[PATCH 1/4] Import upstream version 3.6.1
Julian Wollrath
jwollrath at web.de
Sun May 3 11:51:31 UTC 2015
---
.gitignore | 1 -
AUTHORS | 174 -
COPYING | 41 +-
acinclude.m4 | 124 +-
config.h.in | 21 +-
configure | 3447 ++++++---
configure.ac | 503 +-
debian/changelog | 7 +
extra.mk.in | 13 +
m4/buildsys.m4 | 10 +-
po/Makefile | 3 +
po/POTFILES.in | 305 +-
po/audacious-plugins.pot | 2603 ++++---
po/be.po | 2714 +++----
po/bg.po | 2882 ++++----
po/ca.po | 2702 +++----
po/cmn.po | 2833 ++++----
po/cs.po | 3118 ++++----
po/da.po | 3182 +++++----
po/de.po | 2977 ++++----
po/el.po | 2740 +++----
po/en_GB.po | 2646 +++----
po/es.po | 3756 +++++-----
po/es_AR.po | 2794 ++++----
po/es_MX.po | 2974 ++++----
po/et.po | 2706 +++----
po/eu.po | 2729 +++----
po/fa_IR.po | 2657 +++----
po/fi.po | 3000 ++++----
po/fr.po | 3002 ++++----
po/gl.po | 2964 ++++----
po/hu.po | 3047 ++++----
po/id_ID.po | 2979 ++++----
po/it.po | 2955 ++++----
po/ja.po | 3114 ++++----
po/ko.po | 2858 ++++----
po/ky.po | 2695 +++----
po/lt.po | 2856 ++++----
po/lv.po | 2921 ++++----
po/ml_IN.po | 2736 +++----
po/ms.po | 4352 ++++++++++++
po/nl.po | 4078 +++++++++++
po/pl.po | 3191 +++++----
po/process-transifex-po | 7 +-
po/pt_BR.po | 2915 ++++----
po/pt_PT.po | 3266 +++++----
po/ru.po | 2916 ++++----
po/si.po | 2837 ++++----
po/sk.po | 2836 ++++----
po/sr.po | 2966 ++++----
po/sr_RS.po | 2798 ++++----
po/sv.po | 4012 +++++++++++
po/ta.po | 2739 +++----
po/tr.po | 2736 +++----
po/uk.po | 3081 ++++----
po/update-potfiles.sh | 3 +-
po/zh_CN.po | 2984 ++++----
po/zh_TW.po | 2898 ++++----
src/aac-raw/Makefile | 4 +-
src/aac-raw/aac.c | 482 --
src/aac-raw/aac.cc | 477 ++
src/aac/Makefile | 20 -
src/aac/itunes-cover.c | 92 -
src/aac/libmp4.c | 320 -
src/aac/mp4_utils.c | 31 -
src/aac/mp4ff/mp4atom.c | 676 --
src/aac/mp4ff/mp4ff.c | 480 --
src/aac/mp4ff/mp4ff.h | 138 -
src/aac/mp4ff/mp4ff_int_types.h | 23 -
src/aac/mp4ff/mp4ffint.h | 308 -
src/aac/mp4ff/mp4meta.c | 468 --
src/aac/mp4ff/mp4sample.c | 155 -
src/aac/mp4ff/mp4tagupdate.c | 658 --
src/aac/mp4ff/mp4util.c | 191 -
src/adplug/Makefile | 111 +-
src/adplug/adplug-xmms.cc | 205 +-
src/adplug/adplug-xmms.h | 34 -
src/adplug/core/a2m.cc | 597 ++
src/adplug/core/a2m.cxx | 597 --
src/adplug/core/a2m.h | 3 +-
src/adplug/core/adl.cc | 2874 ++++++++
src/adplug/core/adl.cxx | 2874 --------
src/adplug/core/adl.h | 2 +-
src/adplug/core/adlibemu.c | 600 --
src/adplug/core/adlibemu.cc | 594 ++
src/adplug/core/adplug.cc | 266 +
src/adplug/core/adplug.cxx | 266 -
src/adplug/core/adplug.h | 2 +-
src/adplug/core/adtrack.cc | 238 +
src/adplug/core/adtrack.cxx | 239 -
src/adplug/core/adtrack.h | 2 +-
src/adplug/core/amd.cc | 231 +
src/adplug/core/amd.cxx | 231 -
src/adplug/core/amd.h | 2 +-
src/adplug/core/bam.cc | 244 +
src/adplug/core/bam.cxx | 244 -
src/adplug/core/bam.h | 2 +-
src/adplug/core/binio_virtual.h | 78 +-
src/adplug/core/bmf.cc | 636 ++
src/adplug/core/bmf.cxx | 636 --
src/adplug/core/cff.cc | 531 ++
src/adplug/core/cff.cxx | 541 --
src/adplug/core/cff.h | 2 +-
src/adplug/core/cmf.cc | 788 +++
src/adplug/core/cmf.cxx | 788 ---
src/adplug/core/cmf.h | 4 +-
src/adplug/core/d00.cc | 653 ++
src/adplug/core/d00.cxx | 653 --
src/adplug/core/d00.h | 2 +-
src/adplug/core/database.cc | 520 ++
src/adplug/core/database.cxx | 520 --
src/adplug/core/debug.c | 57 -
src/adplug/core/debug.cc | 57 +
src/adplug/core/debug.h | 13 +-
src/adplug/core/dfm.cc | 137 +
src/adplug/core/dfm.cxx | 137 -
src/adplug/core/dfm.h | 2 +-
src/adplug/core/dmo.cc | 456 ++
src/adplug/core/dmo.cxx | 456 --
src/adplug/core/dmo.h | 2 +-
src/adplug/core/dro.cc | 151 +
src/adplug/core/dro.cxx | 151 -
src/adplug/core/dro.h | 2 +-
src/adplug/core/dro2.cc | 142 +
src/adplug/core/dro2.cxx | 142 -
src/adplug/core/dro2.h | 2 +-
src/adplug/core/dtm.cc | 338 +
src/adplug/core/dtm.cxx | 338 -
src/adplug/core/dtm.h | 2 +-
src/adplug/core/emuopl.cc | 166 +
src/adplug/core/emuopl.cxx | 166 -
src/adplug/core/emuopl.h | 8 +-
src/adplug/core/flash.cc | 259 +
src/adplug/core/flash.cxx | 259 -
src/adplug/core/fmc.cc | 243 +
src/adplug/core/fmc.cxx | 243 -
src/adplug/core/fmc.h | 2 +-
src/adplug/core/fmopl.c | 1389 ----
src/adplug/core/fmopl.cc | 1393 ++++
src/adplug/core/fprovide.cc | 73 +
src/adplug/core/fprovide.cxx | 77 -
src/adplug/core/fprovide.h | 4 +-
src/adplug/core/hsc.cc | 389 +
src/adplug/core/hsc.cxx | 389 -
src/adplug/core/hsc.h | 2 +-
src/adplug/core/hsp.cc | 86 +
src/adplug/core/hsp.cxx | 86 -
src/adplug/core/hsp.h | 2 +-
src/adplug/core/hybrid.cc | 268 +
src/adplug/core/hybrid.cxx | 268 -
src/adplug/core/hyp.cc | 129 +
src/adplug/core/hyp.cxx | 129 -
src/adplug/core/imf.cc | 229 +
src/adplug/core/imf.cxx | 229 -
src/adplug/core/imf.h | 2 +-
src/adplug/core/jbm.cc | 294 +
src/adplug/core/jbm.cxx | 294 -
src/adplug/core/jbm.h | 14 +-
src/adplug/core/kemuopl.h | 8 +-
src/adplug/core/ksm.cc | 419 ++
src/adplug/core/ksm.cxx | 420 --
src/adplug/core/ksm.h | 2 +-
src/adplug/core/lds.cc | 817 +++
src/adplug/core/lds.cxx | 817 ---
src/adplug/core/lds.h | 10 +-
src/adplug/core/mad.cc | 146 +
src/adplug/core/mad.cxx | 146 -
src/adplug/core/mad.h | 2 +-
src/adplug/core/mid.cc | 1101 +++
src/adplug/core/mid.cxx | 1105 ---
src/adplug/core/mid.h | 2 +-
src/adplug/core/mkj.cc | 225 +
src/adplug/core/mkj.cxx | 225 -
src/adplug/core/mkj.h | 2 +-
src/adplug/core/msc.cc | 338 +
src/adplug/core/msc.cxx | 338 -
src/adplug/core/msc.h | 2 +-
src/adplug/core/mtk.cc | 168 +
src/adplug/core/mtk.cxx | 168 -
src/adplug/core/mtk.h | 2 +-
src/adplug/core/player.cc | 73 +
src/adplug/core/player.cxx | 73 -
src/adplug/core/player.h | 2 +-
src/adplug/core/players.cc | 107 +
src/adplug/core/players.cxx | 107 -
src/adplug/core/protrack.cc | 996 +++
src/adplug/core/protrack.cxx | 996 ---
src/adplug/core/protrack.h | 8 +-
src/adplug/core/psi.cc | 187 +
src/adplug/core/psi.cxx | 187 -
src/adplug/core/rad.cc | 155 +
src/adplug/core/rad.cxx | 155 -
src/adplug/core/rad.h | 2 +-
src/adplug/core/rat.cc | 311 +
src/adplug/core/rat.cxx | 311 -
src/adplug/core/raw.cc | 129 +
src/adplug/core/raw.cxx | 129 -
src/adplug/core/raw.h | 2 +-
src/adplug/core/rix.cc | 611 ++
src/adplug/core/rix.cxx | 612 --
src/adplug/core/rix.h | 2 +-
src/adplug/core/rol.cc | 747 ++
src/adplug/core/rol.cxx | 750 --
src/adplug/core/rol.h | 8 +-
src/adplug/core/s3m.cc | 728 ++
src/adplug/core/s3m.cxx | 728 --
src/adplug/core/s3m.h | 4 +-
src/adplug/core/sa2.cc | 314 +
src/adplug/core/sa2.cxx | 314 -
src/adplug/core/sa2.h | 2 +-
src/adplug/core/sng.cc | 113 +
src/adplug/core/sng.cxx | 113 -
src/adplug/core/sng.h | 2 +-
src/adplug/core/temuopl.cc | 85 +
src/adplug/core/temuopl.cxx | 85 -
src/adplug/core/temuopl.h | 8 +-
src/adplug/core/u6m.cc | 1064 +++
src/adplug/core/u6m.cxx | 1064 ---
src/adplug/core/u6m.h | 3 +-
src/adplug/core/xad.cc | 155 +
src/adplug/core/xad.cxx | 155 -
src/adplug/core/xad.h | 2 +-
src/adplug/core/xsm.cc | 136 +
src/adplug/core/xsm.cxx | 136 -
src/adplug/core/xsm.h | 2 +-
src/adplug/plugin.c | 22 -
src/alarm/Makefile | 10 +-
src/alarm/alarm.c | 817 ---
src/alarm/alarm.cc | 822 +++
src/alarm/alarm.h | 2 +-
src/alarm/callbacks.h | 20 +-
src/alarm/interface.c | 457 --
src/alarm/interface.cc | 424 ++
src/alarm/interface.h | 4 +-
src/albumart-qt/Makefile | 13 +
src/albumart-qt/albumart.cc | 89 +
src/albumart/Makefile | 5 +-
src/albumart/albumart.c | 75 -
src/albumart/albumart.cc | 88 +
src/alsa/Makefile | 11 +-
src/alsa/alsa.c | 743 --
src/alsa/alsa.cc | 675 ++
src/alsa/alsa.h | 84 +-
src/alsa/config.c | 525 --
src/alsa/config.cc | 330 +
src/alsa/plugin.c | 59 -
src/amidi-plug/Makefile | 15 +-
src/amidi-plug/amidi-plug.c | 477 --
src/amidi-plug/amidi-plug.cc | 450 ++
src/amidi-plug/amidi-plug.logo.xpm | 743 --
src/amidi-plug/amidi-plug.midiicon.xpm | 2 +-
src/amidi-plug/backend-fluidsynth/Makefile | 12 -
src/amidi-plug/backend-fluidsynth/b-fluidsynth.c | 257 -
src/amidi-plug/backend-fluidsynth/b-fluidsynth.cc | 233 +
src/amidi-plug/i_backend.h | 23 +-
src/amidi-plug/i_configure-fluidsynth.c | 277 -
src/amidi-plug/i_configure-fluidsynth.cc | 275 +
src/amidi-plug/i_configure.c | 148 -
src/amidi-plug/i_configure.cc | 156 +
src/amidi-plug/i_configure.h | 4 +-
src/amidi-plug/i_fileinfo.c | 381 -
src/amidi-plug/i_fileinfo.cc | 340 +
src/amidi-plug/i_fileinfo.h | 4 +-
src/amidi-plug/i_midi.c | 897 ---
src/amidi-plug/i_midi.cc | 803 +++
src/amidi-plug/i_midi.h | 98 +-
src/amidi-plug/i_midievent.h | 22 +-
src/amidi-plug/i_utils.c | 73 -
src/amidi-plug/i_utils.h | 26 -
src/aosd/Makefile | 14 +-
src/aosd/aosd.c | 101 -
src/aosd/aosd.cc | 59 +
src/aosd/aosd.h | 30 +-
src/aosd/aosd_cfg.c | 403 --
src/aosd/aosd_cfg.cc | 174 +
src/aosd/aosd_cfg.h | 79 +-
src/aosd/aosd_common.h | 33 -
src/aosd/aosd_osd.c | 543 --
src/aosd/aosd_osd.cc | 509 ++
src/aosd/aosd_osd.h | 7 +-
src/aosd/aosd_style.c | 391 -
src/aosd/aosd_style.cc | 341 +
src/aosd/aosd_style.h | 20 +-
src/aosd/aosd_style_private.h | 17 +-
src/aosd/aosd_trigger.c | 337 -
src/aosd/aosd_trigger.cc | 284 +
src/aosd/aosd_trigger.h | 16 +-
src/aosd/aosd_trigger_private.h | 13 +-
src/aosd/aosd_ui.c | 977 ---
src/aosd/aosd_ui.cc | 886 +++
src/aosd/aosd_ui.h | 33 -
src/aosd/ghosd.c | 2 -
src/aosd/ghosd.h | 10 +-
src/asx/Makefile | 8 +-
src/asx/asx.c | 87 -
src/asx/asx.cc | 80 +
src/asx3/Makefile | 8 +-
src/asx3/asx3.c | 184 -
src/asx3/asx3.cc | 187 +
src/audpl/Makefile | 4 +-
src/audpl/audpl.c | 191 -
src/audpl/audpl.cc | 170 +
src/blur_scope/Makefile | 3 +-
src/blur_scope/blur_scope.c | 232 -
src/blur_scope/blur_scope.cc | 234 +
src/bs2b/Makefile | 7 +-
src/bs2b/plugin.c | 198 -
src/bs2b/plugin.cc | 145 +
src/cairo-spectrum/Makefile | 3 +-
src/cairo-spectrum/cairo-spectrum.c | 300 -
src/cairo-spectrum/cairo-spectrum.cc | 266 +
src/cd-menu-items/Makefile | 3 +-
src/cd-menu-items/cd-menu-items.c | 61 -
src/cd-menu-items/cd-menu-items.cc | 73 +
src/cdaudio-ng/Makefile | 8 +-
src/cdaudio-ng/cdaudio-ng.c | 873 ---
src/cdaudio-ng/cdaudio-ng.cc | 815 +++
src/compressor/Makefile | 7 +-
src/compressor/compressor.c | 241 -
src/compressor/compressor.cc | 232 +
src/compressor/compressor.h | 28 -
src/compressor/plugin.c | 70 -
src/console/Audacious_Driver.cc | 292 +
src/console/Audacious_Driver.cxx | 302 -
src/console/Ay_Apu.cc | 395 ++
src/console/Ay_Apu.cxx | 395 --
src/console/Ay_Apu.h | 5 +-
src/console/Ay_Cpu.cc | 1661 +++++
src/console/Ay_Cpu.cxx | 1661 -----
src/console/Ay_Emu.cc | 405 ++
src/console/Ay_Emu.cxx | 405 --
src/console/Ay_Emu.h | 1 -
src/console/Blip_Buffer.cc | 460 ++
src/console/Blip_Buffer.cxx | 460 --
src/console/Blip_Buffer.h | 2 +-
src/console/Classic_Emu.cc | 184 +
src/console/Classic_Emu.cxx | 184 -
src/console/Classic_Emu.h | 4 +-
src/console/Data_Reader.cc | 315 +
src/console/Data_Reader.cxx | 315 -
src/console/Dual_Resampler.cc | 129 +
src/console/Dual_Resampler.cxx | 131 -
src/console/Effects_Buffer.cc | 529 ++
src/console/Effects_Buffer.cxx | 529 --
src/console/Fir_Resampler.cc | 199 +
src/console/Fir_Resampler.cxx | 199 -
src/console/Gb_Apu.cc | 306 +
src/console/Gb_Apu.cxx | 306 -
src/console/Gb_Apu.h | 4 +-
src/console/Gb_Cpu.cc | 1052 +++
src/console/Gb_Cpu.cxx | 1052 ---
src/console/Gb_Oscs.cc | 336 +
src/console/Gb_Oscs.cxx | 336 -
src/console/Gb_Oscs.h | 2 +-
src/console/Gbs_Emu.cc | 289 +
src/console/Gbs_Emu.cxx | 289 -
src/console/Gme_File.cc | 215 +
src/console/Gme_File.cxx | 215 -
src/console/Gme_File.h | 4 +-
src/console/Gym_Emu.cc | 380 +
src/console/Gym_Emu.cxx | 380 -
src/console/Gzip_Reader.cc | 108 +
src/console/Gzip_Reader.cxx | 108 -
src/console/Hes_Apu.cc | 315 +
src/console/Hes_Apu.cxx | 315 -
src/console/Hes_Cpu.cc | 1301 ++++
src/console/Hes_Cpu.cxx | 1301 ----
src/console/Hes_Emu.cc | 531 ++
src/console/Hes_Emu.cxx | 531 --
src/console/Kss_Cpu.cc | 1704 +++++
src/console/Kss_Cpu.cxx | 1704 -----
src/console/Kss_Emu.cc | 416 ++
src/console/Kss_Emu.cxx | 416 --
src/console/Kss_Emu.h | 1 -
src/console/Kss_Scc_Apu.cc | 97 +
src/console/Kss_Scc_Apu.cxx | 97 -
src/console/Kss_Scc_Apu.h | 4 +-
src/console/M3u_Playlist.cc | 426 ++
src/console/M3u_Playlist.cxx | 426 --
src/console/Makefile | 106 +-
src/console/Multi_Buffer.cc | 232 +
src/console/Multi_Buffer.cxx | 232 -
src/console/Music_Emu.cc | 411 ++
src/console/Music_Emu.cxx | 411 --
src/console/Nes_Apu.cc | 391 +
src/console/Nes_Apu.cxx | 391 -
src/console/Nes_Apu.h | 14 +-
src/console/Nes_Cpu.cc | 1082 +++
src/console/Nes_Cpu.cxx | 1082 ---
src/console/Nes_Fme7_Apu.cc | 121 +
src/console/Nes_Fme7_Apu.cxx | 121 -
src/console/Nes_Fme7_Apu.h | 2 +-
src/console/Nes_Namco_Apu.cc | 145 +
src/console/Nes_Namco_Apu.cxx | 145 -
src/console/Nes_Oscs.cc | 551 ++
src/console/Nes_Oscs.cxx | 551 --
src/console/Nes_Vrc6_Apu.cc | 215 +
src/console/Nes_Vrc6_Apu.cxx | 215 -
src/console/Nsf_Emu.cc | 559 ++
src/console/Nsf_Emu.cxx | 559 --
src/console/Nsfe_Emu.cc | 332 +
src/console/Nsfe_Emu.cxx | 332 -
src/console/Sap_Apu.cc | 334 +
src/console/Sap_Apu.cxx | 334 -
src/console/Sap_Cpu.cc | 1009 +++
src/console/Sap_Cpu.cxx | 1009 ---
src/console/Sap_Emu.cc | 525 ++
src/console/Sap_Emu.cxx | 444 --
src/console/Sap_Emu.h | 2 +
src/console/Sms_Apu.cc | 330 +
src/console/Sms_Apu.cxx | 330 -
src/console/Sms_Apu.h | 4 +-
src/console/Sms_Oscs.h | 2 +-
src/console/Snes_Spc.cc | 380 +
src/console/Snes_Spc.cxx | 380 -
src/console/Snes_Spc.h | 2 +-
src/console/Spc_Cpu.cc | 565 ++
src/console/Spc_Cpu.cxx | 565 --
src/console/Spc_Dsp.cc | 701 ++
src/console/Spc_Dsp.cxx | 701 --
src/console/Spc_Dsp.h | 2 +-
src/console/Spc_Emu.cc | 352 +
src/console/Spc_Emu.cxx | 352 -
src/console/Spc_Filter.cc | 83 +
src/console/Spc_Filter.cxx | 83 -
src/console/Track_Emu.cc | 186 +
src/console/Track_Emu.cxx | 186 -
src/console/Vfs_File.cc | 57 +
src/console/Vfs_File.cxx | 71 -
src/console/Vfs_File.h | 12 +-
src/console/Vgm_Emu.cc | 416 ++
src/console/Vgm_Emu.cxx | 416 --
src/console/Vgm_Emu_Impl.cc | 314 +
src/console/Vgm_Emu_Impl.cxx | 314 -
src/console/Vgm_Emu_Impl.h | 2 +-
src/console/Ym2413_Emu.cc | 2216 ++++++
src/console/Ym2413_Emu.cxx | 2224 ------
src/console/Ym2612_Emu.cc | 1319 ++++
src/console/Ym2612_Emu.cxx | 1319 ----
src/console/Zlib_Inflater.cc | 175 +
src/console/Zlib_Inflater.cxx | 175 -
src/console/blargg_endian.h | 21 +-
src/console/configure.c | 56 -
src/console/configure.cc | 57 +
src/console/configure.h | 20 +-
src/console/gme.cc | 374 +
src/console/gme.cxx | 374 -
src/console/gme.h | 21 +-
src/console/gme_design.txt | 2 +-
src/console/gme_notes.txt | 10 +-
src/console/gme_type_list.cc | 38 +
src/console/gme_type_list.cxx | 38 -
src/console/plugin.c | 71 -
src/console/plugin.cc | 56 +
src/console/plugin.h | 47 +
src/console/sap_cpu_io.h | 22 +-
src/coreaudio/Makefile | 13 +
src/coreaudio/coreaudio.cc | 470 ++
src/crossfade/Makefile | 6 +-
src/crossfade/crossfade.c | 284 -
src/crossfade/crossfade.cc | 308 +
src/crystalizer/Makefile | 3 +-
src/crystalizer/crystalizer.c | 105 -
src/crystalizer/crystalizer.cc | 105 +
src/cue/Makefile | 8 +-
src/cue/cue.c | 159 -
src/cue/cue.cc | 155 +
src/delete-files/Makefile | 6 +-
src/delete-files/delete-files.c | 177 -
src/delete-files/delete-files.cc | 186 +
src/echo_plugin/Makefile | 6 +-
src/echo_plugin/echo.c | 132 -
src/echo_plugin/echo.cc | 115 +
src/ffaudio/Makefile | 8 +-
src/ffaudio/ffaudio-core.c | 655 --
src/ffaudio/ffaudio-core.cc | 622 ++
src/ffaudio/ffaudio-io.c | 49 -
src/ffaudio/ffaudio-io.cc | 48 +
src/ffaudio/ffaudio-stdinc.h | 26 +-
src/ffaudio/itunes-cover.cc | 91 +
src/filewriter/Makefile | 14 +-
src/filewriter/convert.c | 45 -
src/filewriter/convert.cc | 43 +
src/filewriter/convert.h | 10 +-
src/filewriter/filewriter.c | 542 --
src/filewriter/filewriter.cc | 507 ++
src/filewriter/filewriter.h | 36 +-
src/filewriter/flac.c | 204 -
src/filewriter/flac.cc | 206 +
src/filewriter/mp3.c | 1238 ----
src/filewriter/mp3.cc | 1200 ++++
src/filewriter/plugins.h | 8 +-
src/filewriter/vorbis.c | 263 -
src/filewriter/vorbis.cc | 248 +
src/filewriter/wav.c | 147 -
src/filewriter/wav.cc | 152 +
src/flacng/Makefile | 14 +-
src/flacng/flacng.h | 81 +-
src/flacng/metadata.c | 444 --
src/flacng/metadata.cc | 438 ++
src/flacng/plugin.c | 207 -
src/flacng/plugin.cc | 173 +
src/flacng/seekable_stream_callbacks.c | 170 -
src/flacng/seekable_stream_callbacks.cc | 173 +
src/flacng/tools.c | 79 -
src/flacng/tools.cc | 52 +
src/gio/Makefile | 4 +-
src/gio/gio.c | 319 -
src/gio/gio.cc | 388 +
src/gl-spectrum-qt/Makefile | 13 +
src/gl-spectrum-qt/gl-spectrum.cc | 292 +
src/gl-spectrum/Makefile | 3 +-
src/gl-spectrum/gl-spectrum.c | 416 --
src/gl-spectrum/gl-spectrum.cc | 426 ++
src/gnomeshortcuts/Makefile | 3 +-
src/gnomeshortcuts/gnomeshortcuts.c | 294 -
src/gnomeshortcuts/gnomeshortcuts.cc | 289 +
src/gtkui/Makefile | 24 +-
src/gtkui/columns.c | 332 -
src/gtkui/columns.cc | 350 +
src/gtkui/gtkui.h | 23 +-
src/gtkui/layout.c | 580 --
src/gtkui/layout.cc | 616 ++
src/gtkui/layout.h | 15 +-
src/gtkui/menus.c | 285 -
src/gtkui/menus.cc | 293 +
src/gtkui/playlist_util.c | 125 -
src/gtkui/playlist_util.cc | 150 +
src/gtkui/playlist_util.h | 13 +-
src/gtkui/settings.c | 62 -
src/gtkui/settings.cc | 54 +
src/gtkui/ui_gtk.c | 1022 ---
src/gtkui/ui_gtk.cc | 1120 +++
src/gtkui/ui_infoarea.c | 597 --
src/gtkui/ui_infoarea.cc | 566 ++
src/gtkui/ui_infoarea.h | 4 +-
src/gtkui/ui_playlist_notebook.c | 564 --
src/gtkui/ui_playlist_notebook.cc | 573 ++
src/gtkui/ui_playlist_notebook.h | 15 +-
src/gtkui/ui_playlist_widget.c | 497 --
src/gtkui/ui_playlist_widget.cc | 488 ++
src/gtkui/ui_playlist_widget.h | 38 +-
src/gtkui/ui_statusbar.c | 144 -
src/gtkui/ui_statusbar.cc | 163 +
src/gtkui/ui_statusbar.h | 2 +-
src/hotkey/Makefile | 5 +-
src/hotkey/grab.c | 388 -
src/hotkey/grab.cc | 388 +
src/hotkey/gui.c | 650 --
src/hotkey/gui.cc | 631 ++
src/hotkey/gui.h | 4 +-
src/hotkey/plugin.c | 449 --
src/hotkey/plugin.cc | 446 ++
src/hotkey/plugin.h | 9 +-
src/jack-ng/Makefile | 13 +
src/jack-ng/jack-ng.cc | 402 ++
src/jack/Makefile | 13 -
src/jack/bio2jack.c | 2652 -------
src/jack/bio2jack.h | 145 -
src/jack/jack.c | 453 --
src/jack/jack.h | 16 -
src/ladspa/Makefile | 12 +-
src/ladspa/effect.c | 262 -
src/ladspa/effect.cc | 241 +
src/ladspa/ladspa.h | 20 +-
src/ladspa/loaded-list.c | 135 -
src/ladspa/loaded-list.cc | 125 +
src/ladspa/plugin-list.c | 77 -
src/ladspa/plugin-list.cc | 71 +
src/ladspa/plugin.c | 687 --
src/ladspa/plugin.cc | 560 ++
src/ladspa/plugin.h | 110 +-
src/lirc/Makefile | 3 +-
src/lirc/lirc.c | 409 --
src/lirc/lirc.cc | 401 ++
src/lyricwiki-qt/Makefile | 14 +
src/lyricwiki-qt/lyricwiki.cc | 354 +
src/lyricwiki/Makefile | 4 +-
src/lyricwiki/lyricwiki.c | 416 --
src/lyricwiki/lyricwiki.cc | 386 +
src/m3u/Makefile | 7 +-
src/m3u/m3u.c | 121 -
src/m3u/m3u.cc | 117 +
src/mac-media-keys/MacMediaKeys.h | 40 +
src/mac-media-keys/MacMediaKeys.mm | 103 +
src/mac-media-keys/Makefile | 16 +
src/mac-media-keys/SPInvocationGrabbing.h | 41 +
src/mac-media-keys/SPInvocationGrabbing.m | 138 +
src/mac-media-keys/SPMediaKeyTap.h | 54 +
src/mac-media-keys/SPMediaKeyTap.m | 356 +
src/metronom/Makefile | 4 +-
src/metronom/metronom.c | 234 -
src/metronom/metronom.cc | 242 +
src/mixer/Makefile | 6 +-
src/mixer/mixer.c | 196 -
src/mixer/mixer.cc | 212 +
src/mms/Makefile | 4 +-
src/mms/mms.c | 199 -
src/mms/mms.cc | 196 +
src/modplug/Makefile | 15 +-
src/modplug/archive/arch_raw.cc | 49 +
src/modplug/archive/arch_raw.cxx | 52 -
src/modplug/archive/arch_raw.h | 4 +-
src/modplug/archive/archive.cc | 78 +
src/modplug/archive/archive.cxx | 78 -
src/modplug/archive/open.cc | 15 +
src/modplug/archive/open.cxx | 15 -
src/modplug/modplugbmp.cc | 401 ++
src/modplug/modplugbmp.cxx | 414 --
src/modplug/modplugbmp.h | 52 +-
src/modplug/plugin.cxx | 36 -
src/modplug/plugin.h | 21 -
src/modplug/plugin_main.c | 245 -
src/modplug/plugin_main.cc | 158 +
src/modplug/settings.h | 26 +-
src/mpg123/Makefile | 4 +-
src/mpg123/mpg123.c | 422 --
src/mpg123/mpg123.cc | 426 ++
src/mpris2/Makefile | 4 +-
src/mpris2/plugin.c | 408 --
src/mpris2/plugin.cc | 413 ++
src/neon/Makefile | 11 +-
src/neon/cert_verification.c | 429 --
src/neon/cert_verification.cc | 427 ++
src/neon/debug.h | 31 -
src/neon/neon.c | 1062 ---
src/neon/neon.cc | 1102 +++
src/neon/neon.h | 79 -
src/neon/rb.c | 203 -
src/neon/rb.h | 50 -
src/notify/Makefile | 6 +-
src/notify/event.c | 177 -
src/notify/event.cc | 162 +
src/notify/notify.c | 98 -
src/notify/notify.cc | 118 +
src/notify/osd.c | 110 -
src/notify/osd.cc | 111 +
src/oss4/Makefile | 8 +-
src/oss4/oss.c | 316 -
src/oss4/oss.cc | 365 +
src/oss4/oss.h | 122 +-
src/oss4/plugin.c | 134 -
src/oss4/plugin.cc | 103 +
src/oss4/utils.c | 205 -
src/oss4/utils.cc | 204 +
src/playlist-manager/Makefile | 13 +
src/playlist-manager/playlist-manager.cc | 271 +
src/pls/Makefile | 6 +-
src/pls/pls.c | 107 -
src/pls/pls.cc | 100 +
src/psf/Makefile | 30 +-
src/psf/ao.h | 14 +-
src/psf/corlett.c | 389 -
src/psf/corlett.cc | 390 +
src/psf/cpuintrf.h | 4 +-
src/psf/eng_protos.h | 10 +-
src/psf/eng_psf.c | 398 --
src/psf/eng_psf.cc | 372 +
src/psf/eng_psf2.c | 671 --
src/psf/eng_psf2.cc | 662 ++
src/psf/eng_spx.c | 244 -
src/psf/eng_spx.cc | 243 +
src/psf/peops/License.txt | 3 +-
src/psf/peops/adsr.c | 618 --
src/psf/peops/adsr.cc | 618 ++
src/psf/peops/dma.c | 80 -
src/psf/peops/dma.cc | 80 +
src/psf/peops/registers.c | 499 --
src/psf/peops/registers.cc | 499 ++
src/psf/peops/reverb.c | 383 -
src/psf/peops/reverb.cc | 383 +
src/psf/peops/spu.c | 673 --
src/psf/peops/spu.cc | 671 ++
src/psf/peops/spu.h | 2 +-
src/psf/peops2/License.txt | 3 +-
src/psf/peops2/adsr.c | 656 --
src/psf/peops2/adsr.cc | 656 ++
src/psf/peops2/dma.c | 175 -
src/psf/peops2/dma.cc | 175 +
src/psf/peops2/registers.c | 1343 ----
src/psf/peops2/registers.cc | 1343 ++++
src/psf/peops2/reverb.c | 420 --
src/psf/peops2/reverb.cc | 420 ++
src/psf/peops2/spu.c | 1036 ---
src/psf/peops2/spu.cc | 1034 +++
src/psf/peops2/spu.h | 2 +-
src/psf/peops2/xa.c | 363 -
src/psf/peops2/xa.cc | 363 +
src/psf/plugin.c | 215 -
src/psf/plugin.cc | 215 +
src/psf/psx.c | 3005 --------
src/psf/psx.cc | 3005 ++++++++
src/psf/psx_hw.c | 3543 ----------
src/psf/psx_hw.cc | 3542 ++++++++++
src/pulse_audio/Makefile | 3 +-
src/pulse_audio/pulse_audio.c | 677 --
src/pulse_audio/pulse_audio.cc | 625 ++
src/qtaudio/Makefile | 13 +
src/qtaudio/qtaudio.cc | 302 +
src/qtui/Makefile | 107 +
src/qtui/QtUi/16/audio-volume-high.png | Bin 0 -> 709 bytes
src/qtui/QtUi/16/audio-volume-low.png | Bin 0 -> 577 bytes
src/qtui/QtUi/16/audio-volume-medium.png | Bin 0 -> 632 bytes
src/qtui/QtUi/16/audio-volume-muted.png | Bin 0 -> 527 bytes
src/qtui/QtUi/16/audio-volume-off.png | Bin 0 -> 495 bytes
src/qtui/QtUi/16/document-open.png | Bin 0 -> 585 bytes
src/qtui/QtUi/16/edit-find.png | Bin 0 -> 643 bytes
src/qtui/QtUi/16/list-add.png | Bin 0 -> 463 bytes
src/qtui/QtUi/16/media-playback-pause.png | Bin 0 -> 380 bytes
src/qtui/QtUi/16/media-playback-start.png | Bin 0 -> 437 bytes
src/qtui/QtUi/16/media-playback-stop.png | Bin 0 -> 327 bytes
src/qtui/QtUi/16/media-playlist-repeat.png | Bin 0 -> 555 bytes
src/qtui/QtUi/16/media-playlist-shuffle.png | Bin 0 -> 652 bytes
src/qtui/QtUi/16/media-skip-backward.png | Bin 0 -> 545 bytes
src/qtui/QtUi/16/media-skip-forward.png | Bin 0 -> 543 bytes
src/qtui/QtUi/22/audio-volume-high.png | Bin 0 -> 976 bytes
src/qtui/QtUi/22/audio-volume-low.png | Bin 0 -> 741 bytes
src/qtui/QtUi/22/audio-volume-medium.png | Bin 0 -> 877 bytes
src/qtui/QtUi/22/audio-volume-muted.png | Bin 0 -> 663 bytes
src/qtui/QtUi/22/audio-volume-off.png | Bin 0 -> 604 bytes
src/qtui/QtUi/22/document-open.png | Bin 0 -> 604 bytes
src/qtui/QtUi/22/edit-find.png | Bin 0 -> 887 bytes
src/qtui/QtUi/22/list-add.png | Bin 0 -> 462 bytes
src/qtui/QtUi/22/media-playback-pause.png | Bin 0 -> 279 bytes
src/qtui/QtUi/22/media-playback-start.png | Bin 0 -> 555 bytes
src/qtui/QtUi/22/media-playback-stop.png | Bin 0 -> 252 bytes
src/qtui/QtUi/22/media-playlist-repeat.png | Bin 0 -> 676 bytes
src/qtui/QtUi/22/media-playlist-shuffle.png | Bin 0 -> 793 bytes
src/qtui/QtUi/22/media-skip-backward.png | Bin 0 -> 537 bytes
src/qtui/QtUi/22/media-skip-forward.png | Bin 0 -> 469 bytes
src/qtui/QtUi/32/audio-volume-high.png | Bin 0 -> 1687 bytes
src/qtui/QtUi/32/audio-volume-low.png | Bin 0 -> 1279 bytes
src/qtui/QtUi/32/audio-volume-medium.png | Bin 0 -> 1475 bytes
src/qtui/QtUi/32/audio-volume-muted.png | Bin 0 -> 1093 bytes
src/qtui/QtUi/32/audio-volume-off.png | Bin 0 -> 1036 bytes
src/qtui/QtUi/32/document-open.png | Bin 0 -> 1053 bytes
src/qtui/QtUi/32/edit-find.png | Bin 0 -> 1469 bytes
src/qtui/QtUi/32/list-add.png | Bin 0 -> 581 bytes
src/qtui/QtUi/32/media-playback-pause.png | Bin 0 -> 527 bytes
src/qtui/QtUi/32/media-playback-start.png | Bin 0 -> 805 bytes
src/qtui/QtUi/32/media-playback-stop.png | Bin 0 -> 388 bytes
src/qtui/QtUi/32/media-playlist-repeat.png | Bin 0 -> 1109 bytes
src/qtui/QtUi/32/media-playlist-shuffle.png | Bin 0 -> 1464 bytes
src/qtui/QtUi/32/media-skip-backward.png | Bin 0 -> 1099 bytes
src/qtui/QtUi/32/media-skip-forward.png | Bin 0 -> 1108 bytes
src/qtui/QtUi/44/audio-volume-high.png | Bin 0 -> 2413 bytes
src/qtui/QtUi/44/audio-volume-low.png | Bin 0 -> 1729 bytes
src/qtui/QtUi/44/audio-volume-medium.png | Bin 0 -> 2072 bytes
src/qtui/QtUi/44/audio-volume-muted.png | Bin 0 -> 1412 bytes
src/qtui/QtUi/44/audio-volume-off.png | Bin 0 -> 1318 bytes
src/qtui/QtUi/44/document-open.png | Bin 0 -> 1038 bytes
src/qtui/QtUi/44/edit-find.png | Bin 0 -> 2105 bytes
src/qtui/QtUi/44/list-add.png | Bin 0 -> 696 bytes
src/qtui/QtUi/44/media-playback-pause.png | Bin 0 -> 402 bytes
src/qtui/QtUi/44/media-playback-start.png | Bin 0 -> 1091 bytes
src/qtui/QtUi/44/media-playback-stop.png | Bin 0 -> 350 bytes
src/qtui/QtUi/44/media-playlist-repeat.png | Bin 0 -> 1339 bytes
src/qtui/QtUi/44/media-playlist-shuffle.png | Bin 0 -> 1806 bytes
src/qtui/QtUi/44/media-skip-backward.png | Bin 0 -> 996 bytes
src/qtui/QtUi/44/media-skip-forward.png | Bin 0 -> 940 bytes
src/qtui/QtUi/AUTHORS | 3 +
src/qtui/QtUi/index.theme | 17 +
src/qtui/dialog_windows.cc | 68 +
src/qtui/dialog_windows.h | 53 +
src/qtui/filter_input.cc | 56 +
src/qtui/filter_input.h | 34 +
src/qtui/info_bar.cc | 211 +
src/qtui/info_bar.h | 96 +
src/qtui/main_window.cc | 317 +
src/qtui/main_window.h | 103 +
src/qtui/main_window_actions.cc | 197 +
src/qtui/playlist.cc | 287 +
src/qtui/playlist.h | 63 +
src/qtui/playlist_model.cc | 181 +
src/qtui/playlist_model.h | 54 +
src/qtui/playlist_tabs.cc | 239 +
src/qtui/playlist_tabs.h | 82 +
src/qtui/qtui.cc | 83 +
src/qtui/status_bar.cc | 99 +
src/qtui/status_bar.h | 49 +
src/qtui/time_slider.cc | 121 +
src/qtui/time_slider.h | 61 +
src/qtui/tool_bar.cc | 65 +
src/qtui/tool_bar.h | 63 +
src/resample/Makefile | 8 +-
src/resample/resample.c | 225 -
src/resample/resample.cc | 247 +
src/scrobbler2/Makefile | 10 +-
src/scrobbler2/config_window.c | 234 -
src/scrobbler2/config_window.cc | 224 +
src/scrobbler2/scrobbler.c | 308 -
src/scrobbler2/scrobbler.cc | 291 +
src/scrobbler2/scrobbler.h | 44 +-
src/scrobbler2/scrobbler_communication.c | 789 ---
src/scrobbler2/scrobbler_communication.cc | 703 ++
src/scrobbler2/scrobbler_xml_parsing.c | 322 -
src/scrobbler2/scrobbler_xml_parsing.cc | 300 +
src/sdlout/Makefile | 8 +-
src/sdlout/plugin.c | 48 -
src/sdlout/sdlout.c | 348 -
src/sdlout/sdlout.cc | 335 +
src/sdlout/sdlout.h | 38 -
src/search-tool/Makefile | 6 +-
src/search-tool/search-tool.c | 792 ---
src/search-tool/search-tool.cc | 759 ++
src/sid/Makefile | 13 +-
src/sid/xmms-sid.c | 375 -
src/sid/xmms-sid.cc | 326 +
src/sid/xmms-sid.h | 31 +-
src/sid/xs_config.c | 79 -
src/sid/xs_config.cc | 140 +
src/sid/xs_config.h | 37 +-
src/sid/xs_length.c | 528 --
src/sid/xs_length.h | 39 -
src/sid/xs_md5.c | 25 -
src/sid/xs_md5.h | 21 -
src/sid/xs_player.h | 29 -
src/sid/xs_sidplay2.cc | 372 +-
src/sid/xs_sidplay2.h | 28 +-
src/sid/xs_slsup.c | 273 -
src/sid/xs_slsup.h | 29 -
src/sid/xs_stil.c | 429 --
src/sid/xs_stil.h | 41 -
src/sid/xs_support.c | 116 -
src/sid/xs_support.h | 28 -
src/silence-removal/Makefile | 13 +
src/silence-removal/silence-removal.cc | 192 +
src/skins/Makefile | 67 +-
src/skins/actions-mainwin.h | 2 +
src/skins/actions-playlist.h | 8 +
src/skins/dnd.h | 15 +-
src/skins/drag-handle.c | 105 -
src/skins/drag-handle.cc | 106 +
src/skins/drag-handle.h | 4 +-
src/skins/draw-compat.h | 21 +-
src/skins/menus.c | 322 -
src/skins/menus.cc | 311 +
src/skins/menus.h | 3 +-
src/skins/plugin-window.cc | 175 +
src/skins/plugin-window.h | 33 +
src/skins/plugin.c | 148 -
src/skins/plugin.cc | 202 +
src/skins/plugin.h | 6 +-
src/skins/preset-browser.c | 169 -
src/skins/preset-browser.cc | 158 +
src/skins/preset-list.c | 468 --
src/skins/preset-list.cc | 462 ++
src/skins/skins_cfg.c | 355 -
src/skins/skins_cfg.cc | 342 +
src/skins/skins_cfg.h | 37 +-
src/skins/surface.c | 72 -
src/skins/surface.cc | 74 +
src/skins/surface.h | 12 +-
src/skins/ui_dock.c | 384 -
src/skins/ui_dock.cc | 384 +
src/skins/ui_dock.h | 8 +-
src/skins/ui_equalizer.c | 526 --
src/skins/ui_equalizer.cc | 498 ++
src/skins/ui_equalizer.h | 23 +-
src/skins/ui_main.c | 1297 ----
src/skins/ui_main.cc | 1352 ++++
src/skins/ui_main.h | 32 +-
src/skins/ui_main_evlisteners.c | 345 -
src/skins/ui_main_evlisteners.cc | 346 +
src/skins/ui_playlist.c | 1124 ---
src/skins/ui_playlist.cc | 1163 +++
src/skins/ui_playlist.h | 6 +-
src/skins/ui_skin.c | 821 ---
src/skins/ui_skin.cc | 809 +++
src/skins/ui_skin.h | 166 +-
src/skins/ui_skin_load_ini.c | 440 --
src/skins/ui_skin_load_ini.cc | 315 +
src/skins/ui_skinned_button.c | 263 -
src/skins/ui_skinned_button.cc | 264 +
src/skins/ui_skinned_button.h | 10 +-
src/skins/ui_skinned_equalizer_graph.c | 143 -
src/skins/ui_skinned_equalizer_graph.cc | 147 +
src/skins/ui_skinned_equalizer_slider.c | 191 -
src/skins/ui_skinned_equalizer_slider.cc | 191 +
src/skins/ui_skinned_equalizer_slider.h | 6 +-
src/skins/ui_skinned_horizontal_slider.c | 238 -
src/skins/ui_skinned_horizontal_slider.cc | 241 +
src/skins/ui_skinned_horizontal_slider.h | 12 +-
src/skins/ui_skinned_menurow.c | 149 -
src/skins/ui_skinned_menurow.cc | 147 +
src/skins/ui_skinned_monostereo.c | 65 -
src/skins/ui_skinned_monostereo.cc | 66 +
src/skins/ui_skinned_monostereo.h | 2 +-
src/skins/ui_skinned_number.c | 92 -
src/skins/ui_skinned_number.cc | 93 +
src/skins/ui_skinned_number.h | 4 +-
src/skins/ui_skinned_playlist.c | 948 ---
src/skins/ui_skinned_playlist.cc | 945 +++
src/skins/ui_skinned_playlist.h | 16 +-
src/skins/ui_skinned_playlist_slider.c | 141 -
src/skins/ui_skinned_playlist_slider.cc | 144 +
src/skins/ui_skinned_playlist_slider.h | 4 +-
src/skins/ui_skinned_playstatus.c | 81 -
src/skins/ui_skinned_playstatus.cc | 82 +
src/skins/ui_skinned_playstatus.h | 2 +-
src/skins/ui_skinned_textbox.c | 405 --
src/skins/ui_skinned_textbox.cc | 412 ++
src/skins/ui_skinned_textbox.h | 10 +-
src/skins/ui_skinned_window.c | 196 -
src/skins/ui_skinned_window.cc | 246 +
src/skins/ui_skinned_window.h | 9 +-
src/skins/ui_skinselector.c | 398 --
src/skins/ui_skinselector.cc | 398 ++
src/skins/ui_svis.c | 206 -
src/skins/ui_svis.cc | 215 +
src/skins/ui_vis.c | 316 -
src/skins/ui_vis.cc | 325 +
src/skins/ui_vis.h | 4 +-
src/skins/util.c | 453 --
src/skins/util.cc | 432 ++
src/skins/util.h | 28 +-
src/skins/view.c | 204 -
src/skins/view.cc | 222 +
src/skins/view.h | 23 +-
src/sndfile/Makefile | 8 +-
src/sndfile/plugin.c | 379 -
src/sndfile/plugin.cc | 351 +
src/sndio-ng/Makefile | 13 +
src/sndio-ng/sndio.cc | 376 +
src/sndio/Makefile | 12 -
src/sndio/sndio.c | 432 --
src/song-info-qt/Makefile | 13 +
src/song-info-qt/song-info.cc | 99 +
src/song_change/Makefile | 4 +-
src/song_change/formatter.c | 103 -
src/song_change/formatter.cc | 104 +
src/song_change/formatter.h | 8 +-
src/song_change/song_change.c | 523 --
src/song_change/song_change.cc | 415 ++
src/sox-resampler/Makefile | 7 +-
src/sox-resampler/sox-resampler.c | 175 -
src/sox-resampler/sox-resampler.cc | 166 +
src/speed-pitch/Makefile | 7 +-
src/speed-pitch/speed-pitch.c | 277 -
src/speed-pitch/speed-pitch.cc | 237 +
src/statusicon/Makefile | 8 +-
src/statusicon/statusicon.c | 405 --
src/statusicon/statusicon.cc | 395 ++
src/statusicon/statusicon.h | 34 -
src/statusicon/util.c | 35 -
src/stereo_plugin/Makefile | 3 +-
src/stereo_plugin/stereo.c | 82 -
src/stereo_plugin/stereo.cc | 84 +
src/tonegen/Makefile | 8 +-
src/tonegen/tonegen.c | 190 -
src/tonegen/tonegen.cc | 165 +
src/voice_removal/Makefile | 3 +-
src/voice_removal/voice_removal.c | 59 -
src/voice_removal/voice_removal.cc | 61 +
src/vorbis/Makefile | 8 +-
src/vorbis/vcedit.c | 469 --
src/vorbis/vcedit.cc | 443 ++
src/vorbis/vcedit.h | 30 +-
src/vorbis/vcupdate.c | 219 -
src/vorbis/vcupdate.cc | 210 +
src/vorbis/vorbis.c | 517 --
src/vorbis/vorbis.cc | 481 ++
src/vorbis/vorbis.h | 29 +-
src/vtx/Makefile | 14 +-
src/vtx/ay8912.c | 495 --
src/vtx/ay8912.cc | 494 ++
src/vtx/ayemu.h | 10 +-
src/vtx/ayemu_8912.h | 14 +-
src/vtx/ayemu_vtxfile.h | 60 +-
src/vtx/info.c | 40 -
src/vtx/info.cc | 38 +
src/vtx/lh5dec.c | 300 -
src/vtx/lh5dec.cc | 305 +
src/vtx/vtx.c | 181 -
src/vtx/vtx.cc | 186 +
src/vtx/vtx.h | 12 +-
src/vtx/vtxfile.c | 331 -
src/vtx/vtxfile.cc | 229 +
src/wavpack/Makefile | 8 +-
src/wavpack/wavpack.c | 279 -
src/wavpack/wavpack.cc | 258 +
src/xsf/Makefile | 18 +-
src/xsf/corlett.c | 382 -
src/xsf/corlett.cc | 385 +
src/xsf/desmume/COPYING | 4 +-
src/xsf/desmume/FIFO.c | 65 -
src/xsf/desmume/FIFO.cc | 65 +
src/xsf/desmume/FIFO.h | 10 +-
src/xsf/desmume/GPU.c | 98 -
src/xsf/desmume/GPU.cc | 98 +
src/xsf/desmume/GPU.h | 16 +-
src/xsf/desmume/MMU.c | 3565 ----------
src/xsf/desmume/MMU.cc | 3526 +++++++++
src/xsf/desmume/MMU.h | 41 +-
src/xsf/desmume/NDSSystem.c | 748 --
src/xsf/desmume/NDSSystem.cc | 748 ++
src/xsf/desmume/NDSSystem.h | 55 +-
src/xsf/desmume/SPU.c | 961 ---
src/xsf/desmume/SPU.cc | 963 +++
src/xsf/desmume/SPU.h | 2 +-
src/xsf/desmume/arm_instructions.c | 7857 ---------------------
src/xsf/desmume/arm_instructions.cc | 7857 +++++++++++++++++++++
src/xsf/desmume/arm_instructions.h | 2 +-
src/xsf/desmume/armcpu.c | 487 --
src/xsf/desmume/armcpu.cc | 487 ++
src/xsf/desmume/armcpu.h | 19 +-
src/xsf/desmume/bios.c | 1073 ---
src/xsf/desmume/bios.cc | 1073 +++
src/xsf/desmume/bios.h | 2 +-
src/xsf/desmume/config.h | 2 +-
src/xsf/desmume/cp15.c | 590 --
src/xsf/desmume/cp15.cc | 590 ++
src/xsf/desmume/cp15.h | 2 +-
src/xsf/desmume/dscard.h | 2 +-
src/xsf/desmume/instruction_tabdef.inc | 2 +-
src/xsf/desmume/matrix.c | 257 -
src/xsf/desmume/matrix.cc | 257 +
src/xsf/desmume/matrix.h | 2 +-
src/xsf/desmume/mc.c | 121 -
src/xsf/desmume/mc.cc | 121 +
src/xsf/desmume/mc.h | 14 +-
src/xsf/desmume/mem.h | 2 +-
src/xsf/desmume/registers.h | 2 +-
src/xsf/desmume/thumb_instructions.c | 944 ---
src/xsf/desmume/thumb_instructions.cc | 944 +++
src/xsf/desmume/thumb_instructions.h | 2 +-
src/xsf/desmume/thumb_tabdef.inc | 2 +-
src/xsf/desmume/types.h | 10 +-
src/xsf/plugin.c | 223 -
src/xsf/plugin.cc | 242 +
src/xsf/tagget.h | 2 +-
src/xsf/vio2sf.c | 841 ---
src/xsf/vio2sf.cc | 828 +++
src/xsf/vio2sf.h | 5 +-
src/xsf/xsfdrv.h | 9 -
src/xspf/Makefile | 4 +-
src/xspf/xspf.c | 443 --
src/xspf/xspf.cc | 429 ++
1038 files changed, 218366 insertions(+), 198382 deletions(-)
delete mode 100644 .gitignore
delete mode 100644 AUTHORS
create mode 100644 po/ms.po
create mode 100644 po/nl.po
create mode 100644 po/sv.po
delete mode 100644 src/aac-raw/aac.c
create mode 100644 src/aac-raw/aac.cc
delete mode 100644 src/aac/Makefile
delete mode 100644 src/aac/itunes-cover.c
delete mode 100644 src/aac/libmp4.c
delete mode 100644 src/aac/mp4_utils.c
delete mode 100644 src/aac/mp4ff/mp4atom.c
delete mode 100644 src/aac/mp4ff/mp4ff.c
delete mode 100644 src/aac/mp4ff/mp4ff.h
delete mode 100644 src/aac/mp4ff/mp4ff_int_types.h
delete mode 100644 src/aac/mp4ff/mp4ffint.h
delete mode 100644 src/aac/mp4ff/mp4meta.c
delete mode 100644 src/aac/mp4ff/mp4sample.c
delete mode 100644 src/aac/mp4ff/mp4tagupdate.c
delete mode 100644 src/aac/mp4ff/mp4util.c
delete mode 100644 src/adplug/adplug-xmms.h
create mode 100644 src/adplug/core/a2m.cc
delete mode 100644 src/adplug/core/a2m.cxx
create mode 100644 src/adplug/core/adl.cc
delete mode 100644 src/adplug/core/adl.cxx
delete mode 100644 src/adplug/core/adlibemu.c
create mode 100644 src/adplug/core/adlibemu.cc
create mode 100644 src/adplug/core/adplug.cc
delete mode 100644 src/adplug/core/adplug.cxx
create mode 100644 src/adplug/core/adtrack.cc
delete mode 100644 src/adplug/core/adtrack.cxx
create mode 100644 src/adplug/core/amd.cc
delete mode 100644 src/adplug/core/amd.cxx
create mode 100644 src/adplug/core/bam.cc
delete mode 100644 src/adplug/core/bam.cxx
create mode 100644 src/adplug/core/bmf.cc
delete mode 100644 src/adplug/core/bmf.cxx
create mode 100644 src/adplug/core/cff.cc
delete mode 100644 src/adplug/core/cff.cxx
create mode 100644 src/adplug/core/cmf.cc
delete mode 100644 src/adplug/core/cmf.cxx
create mode 100644 src/adplug/core/d00.cc
delete mode 100644 src/adplug/core/d00.cxx
create mode 100644 src/adplug/core/database.cc
delete mode 100644 src/adplug/core/database.cxx
delete mode 100644 src/adplug/core/debug.c
create mode 100644 src/adplug/core/debug.cc
create mode 100644 src/adplug/core/dfm.cc
delete mode 100644 src/adplug/core/dfm.cxx
create mode 100644 src/adplug/core/dmo.cc
delete mode 100644 src/adplug/core/dmo.cxx
create mode 100644 src/adplug/core/dro.cc
delete mode 100644 src/adplug/core/dro.cxx
create mode 100644 src/adplug/core/dro2.cc
delete mode 100644 src/adplug/core/dro2.cxx
create mode 100644 src/adplug/core/dtm.cc
delete mode 100644 src/adplug/core/dtm.cxx
create mode 100644 src/adplug/core/emuopl.cc
delete mode 100644 src/adplug/core/emuopl.cxx
create mode 100644 src/adplug/core/flash.cc
delete mode 100644 src/adplug/core/flash.cxx
create mode 100644 src/adplug/core/fmc.cc
delete mode 100644 src/adplug/core/fmc.cxx
delete mode 100644 src/adplug/core/fmopl.c
create mode 100644 src/adplug/core/fmopl.cc
create mode 100644 src/adplug/core/fprovide.cc
delete mode 100644 src/adplug/core/fprovide.cxx
create mode 100644 src/adplug/core/hsc.cc
delete mode 100644 src/adplug/core/hsc.cxx
create mode 100644 src/adplug/core/hsp.cc
delete mode 100644 src/adplug/core/hsp.cxx
create mode 100644 src/adplug/core/hybrid.cc
delete mode 100644 src/adplug/core/hybrid.cxx
create mode 100644 src/adplug/core/hyp.cc
delete mode 100644 src/adplug/core/hyp.cxx
create mode 100644 src/adplug/core/imf.cc
delete mode 100644 src/adplug/core/imf.cxx
create mode 100644 src/adplug/core/jbm.cc
delete mode 100644 src/adplug/core/jbm.cxx
create mode 100644 src/adplug/core/ksm.cc
delete mode 100644 src/adplug/core/ksm.cxx
create mode 100644 src/adplug/core/lds.cc
delete mode 100644 src/adplug/core/lds.cxx
create mode 100644 src/adplug/core/mad.cc
delete mode 100644 src/adplug/core/mad.cxx
create mode 100644 src/adplug/core/mid.cc
delete mode 100644 src/adplug/core/mid.cxx
create mode 100644 src/adplug/core/mkj.cc
delete mode 100644 src/adplug/core/mkj.cxx
create mode 100644 src/adplug/core/msc.cc
delete mode 100644 src/adplug/core/msc.cxx
create mode 100644 src/adplug/core/mtk.cc
delete mode 100644 src/adplug/core/mtk.cxx
create mode 100644 src/adplug/core/player.cc
delete mode 100644 src/adplug/core/player.cxx
create mode 100644 src/adplug/core/players.cc
delete mode 100644 src/adplug/core/players.cxx
create mode 100644 src/adplug/core/protrack.cc
delete mode 100644 src/adplug/core/protrack.cxx
create mode 100644 src/adplug/core/psi.cc
delete mode 100644 src/adplug/core/psi.cxx
create mode 100644 src/adplug/core/rad.cc
delete mode 100644 src/adplug/core/rad.cxx
create mode 100644 src/adplug/core/rat.cc
delete mode 100644 src/adplug/core/rat.cxx
create mode 100644 src/adplug/core/raw.cc
delete mode 100644 src/adplug/core/raw.cxx
create mode 100644 src/adplug/core/rix.cc
delete mode 100644 src/adplug/core/rix.cxx
create mode 100644 src/adplug/core/rol.cc
delete mode 100644 src/adplug/core/rol.cxx
create mode 100644 src/adplug/core/s3m.cc
delete mode 100644 src/adplug/core/s3m.cxx
create mode 100644 src/adplug/core/sa2.cc
delete mode 100644 src/adplug/core/sa2.cxx
create mode 100644 src/adplug/core/sng.cc
delete mode 100644 src/adplug/core/sng.cxx
create mode 100644 src/adplug/core/temuopl.cc
delete mode 100644 src/adplug/core/temuopl.cxx
create mode 100644 src/adplug/core/u6m.cc
delete mode 100644 src/adplug/core/u6m.cxx
create mode 100644 src/adplug/core/xad.cc
delete mode 100644 src/adplug/core/xad.cxx
create mode 100644 src/adplug/core/xsm.cc
delete mode 100644 src/adplug/core/xsm.cxx
delete mode 100644 src/adplug/plugin.c
delete mode 100644 src/alarm/alarm.c
create mode 100644 src/alarm/alarm.cc
delete mode 100644 src/alarm/interface.c
create mode 100644 src/alarm/interface.cc
create mode 100644 src/albumart-qt/Makefile
create mode 100644 src/albumart-qt/albumart.cc
delete mode 100644 src/albumart/albumart.c
create mode 100644 src/albumart/albumart.cc
delete mode 100644 src/alsa/alsa.c
create mode 100644 src/alsa/alsa.cc
delete mode 100644 src/alsa/config.c
create mode 100644 src/alsa/config.cc
delete mode 100644 src/alsa/plugin.c
delete mode 100644 src/amidi-plug/amidi-plug.c
create mode 100644 src/amidi-plug/amidi-plug.cc
delete mode 100644 src/amidi-plug/amidi-plug.logo.xpm
delete mode 100644 src/amidi-plug/backend-fluidsynth/Makefile
delete mode 100644 src/amidi-plug/backend-fluidsynth/b-fluidsynth.c
create mode 100644 src/amidi-plug/backend-fluidsynth/b-fluidsynth.cc
delete mode 100644 src/amidi-plug/i_configure-fluidsynth.c
create mode 100644 src/amidi-plug/i_configure-fluidsynth.cc
delete mode 100644 src/amidi-plug/i_configure.c
create mode 100644 src/amidi-plug/i_configure.cc
delete mode 100644 src/amidi-plug/i_fileinfo.c
create mode 100644 src/amidi-plug/i_fileinfo.cc
delete mode 100644 src/amidi-plug/i_midi.c
create mode 100644 src/amidi-plug/i_midi.cc
delete mode 100644 src/amidi-plug/i_utils.c
delete mode 100644 src/amidi-plug/i_utils.h
delete mode 100644 src/aosd/aosd.c
create mode 100644 src/aosd/aosd.cc
delete mode 100644 src/aosd/aosd_cfg.c
create mode 100644 src/aosd/aosd_cfg.cc
delete mode 100644 src/aosd/aosd_common.h
delete mode 100644 src/aosd/aosd_osd.c
create mode 100644 src/aosd/aosd_osd.cc
delete mode 100644 src/aosd/aosd_style.c
create mode 100644 src/aosd/aosd_style.cc
delete mode 100644 src/aosd/aosd_trigger.c
create mode 100644 src/aosd/aosd_trigger.cc
delete mode 100644 src/aosd/aosd_ui.c
create mode 100644 src/aosd/aosd_ui.cc
delete mode 100644 src/aosd/aosd_ui.h
delete mode 100644 src/asx/asx.c
create mode 100644 src/asx/asx.cc
delete mode 100644 src/asx3/asx3.c
create mode 100644 src/asx3/asx3.cc
delete mode 100644 src/audpl/audpl.c
create mode 100644 src/audpl/audpl.cc
delete mode 100644 src/blur_scope/blur_scope.c
create mode 100644 src/blur_scope/blur_scope.cc
delete mode 100644 src/bs2b/plugin.c
create mode 100644 src/bs2b/plugin.cc
delete mode 100644 src/cairo-spectrum/cairo-spectrum.c
create mode 100644 src/cairo-spectrum/cairo-spectrum.cc
delete mode 100644 src/cd-menu-items/cd-menu-items.c
create mode 100644 src/cd-menu-items/cd-menu-items.cc
delete mode 100644 src/cdaudio-ng/cdaudio-ng.c
create mode 100644 src/cdaudio-ng/cdaudio-ng.cc
delete mode 100644 src/compressor/compressor.c
create mode 100644 src/compressor/compressor.cc
delete mode 100644 src/compressor/compressor.h
delete mode 100644 src/compressor/plugin.c
create mode 100644 src/console/Audacious_Driver.cc
delete mode 100644 src/console/Audacious_Driver.cxx
create mode 100644 src/console/Ay_Apu.cc
delete mode 100644 src/console/Ay_Apu.cxx
create mode 100644 src/console/Ay_Cpu.cc
delete mode 100644 src/console/Ay_Cpu.cxx
create mode 100644 src/console/Ay_Emu.cc
delete mode 100644 src/console/Ay_Emu.cxx
create mode 100644 src/console/Blip_Buffer.cc
delete mode 100644 src/console/Blip_Buffer.cxx
create mode 100644 src/console/Classic_Emu.cc
delete mode 100644 src/console/Classic_Emu.cxx
create mode 100644 src/console/Data_Reader.cc
delete mode 100644 src/console/Data_Reader.cxx
create mode 100644 src/console/Dual_Resampler.cc
delete mode 100644 src/console/Dual_Resampler.cxx
create mode 100644 src/console/Effects_Buffer.cc
delete mode 100644 src/console/Effects_Buffer.cxx
create mode 100644 src/console/Fir_Resampler.cc
delete mode 100644 src/console/Fir_Resampler.cxx
create mode 100644 src/console/Gb_Apu.cc
delete mode 100644 src/console/Gb_Apu.cxx
create mode 100644 src/console/Gb_Cpu.cc
delete mode 100644 src/console/Gb_Cpu.cxx
create mode 100644 src/console/Gb_Oscs.cc
delete mode 100644 src/console/Gb_Oscs.cxx
create mode 100644 src/console/Gbs_Emu.cc
delete mode 100644 src/console/Gbs_Emu.cxx
create mode 100644 src/console/Gme_File.cc
delete mode 100644 src/console/Gme_File.cxx
create mode 100644 src/console/Gym_Emu.cc
delete mode 100644 src/console/Gym_Emu.cxx
create mode 100644 src/console/Gzip_Reader.cc
delete mode 100644 src/console/Gzip_Reader.cxx
create mode 100644 src/console/Hes_Apu.cc
delete mode 100644 src/console/Hes_Apu.cxx
create mode 100644 src/console/Hes_Cpu.cc
delete mode 100644 src/console/Hes_Cpu.cxx
create mode 100644 src/console/Hes_Emu.cc
delete mode 100644 src/console/Hes_Emu.cxx
create mode 100644 src/console/Kss_Cpu.cc
delete mode 100644 src/console/Kss_Cpu.cxx
create mode 100644 src/console/Kss_Emu.cc
delete mode 100644 src/console/Kss_Emu.cxx
create mode 100644 src/console/Kss_Scc_Apu.cc
delete mode 100644 src/console/Kss_Scc_Apu.cxx
create mode 100644 src/console/M3u_Playlist.cc
delete mode 100644 src/console/M3u_Playlist.cxx
create mode 100644 src/console/Multi_Buffer.cc
delete mode 100644 src/console/Multi_Buffer.cxx
create mode 100644 src/console/Music_Emu.cc
delete mode 100644 src/console/Music_Emu.cxx
create mode 100644 src/console/Nes_Apu.cc
delete mode 100644 src/console/Nes_Apu.cxx
create mode 100644 src/console/Nes_Cpu.cc
delete mode 100644 src/console/Nes_Cpu.cxx
create mode 100644 src/console/Nes_Fme7_Apu.cc
delete mode 100644 src/console/Nes_Fme7_Apu.cxx
create mode 100644 src/console/Nes_Namco_Apu.cc
delete mode 100644 src/console/Nes_Namco_Apu.cxx
create mode 100644 src/console/Nes_Oscs.cc
delete mode 100644 src/console/Nes_Oscs.cxx
create mode 100644 src/console/Nes_Vrc6_Apu.cc
delete mode 100644 src/console/Nes_Vrc6_Apu.cxx
create mode 100644 src/console/Nsf_Emu.cc
delete mode 100644 src/console/Nsf_Emu.cxx
create mode 100644 src/console/Nsfe_Emu.cc
delete mode 100644 src/console/Nsfe_Emu.cxx
create mode 100644 src/console/Sap_Apu.cc
delete mode 100644 src/console/Sap_Apu.cxx
create mode 100644 src/console/Sap_Cpu.cc
delete mode 100644 src/console/Sap_Cpu.cxx
create mode 100644 src/console/Sap_Emu.cc
delete mode 100644 src/console/Sap_Emu.cxx
create mode 100644 src/console/Sms_Apu.cc
delete mode 100644 src/console/Sms_Apu.cxx
create mode 100644 src/console/Snes_Spc.cc
delete mode 100644 src/console/Snes_Spc.cxx
create mode 100644 src/console/Spc_Cpu.cc
delete mode 100644 src/console/Spc_Cpu.cxx
create mode 100644 src/console/Spc_Dsp.cc
delete mode 100644 src/console/Spc_Dsp.cxx
create mode 100644 src/console/Spc_Emu.cc
delete mode 100644 src/console/Spc_Emu.cxx
create mode 100644 src/console/Spc_Filter.cc
delete mode 100644 src/console/Spc_Filter.cxx
create mode 100644 src/console/Track_Emu.cc
delete mode 100644 src/console/Track_Emu.cxx
create mode 100644 src/console/Vfs_File.cc
delete mode 100644 src/console/Vfs_File.cxx
create mode 100644 src/console/Vgm_Emu.cc
delete mode 100644 src/console/Vgm_Emu.cxx
create mode 100644 src/console/Vgm_Emu_Impl.cc
delete mode 100644 src/console/Vgm_Emu_Impl.cxx
create mode 100644 src/console/Ym2413_Emu.cc
delete mode 100644 src/console/Ym2413_Emu.cxx
create mode 100644 src/console/Ym2612_Emu.cc
delete mode 100644 src/console/Ym2612_Emu.cxx
create mode 100644 src/console/Zlib_Inflater.cc
delete mode 100644 src/console/Zlib_Inflater.cxx
delete mode 100644 src/console/configure.c
create mode 100644 src/console/configure.cc
create mode 100644 src/console/gme.cc
delete mode 100644 src/console/gme.cxx
create mode 100644 src/console/gme_type_list.cc
delete mode 100644 src/console/gme_type_list.cxx
delete mode 100644 src/console/plugin.c
create mode 100644 src/console/plugin.cc
create mode 100644 src/console/plugin.h
create mode 100644 src/coreaudio/Makefile
create mode 100644 src/coreaudio/coreaudio.cc
delete mode 100644 src/crossfade/crossfade.c
create mode 100644 src/crossfade/crossfade.cc
delete mode 100644 src/crystalizer/crystalizer.c
create mode 100644 src/crystalizer/crystalizer.cc
delete mode 100644 src/cue/cue.c
create mode 100644 src/cue/cue.cc
delete mode 100644 src/delete-files/delete-files.c
create mode 100644 src/delete-files/delete-files.cc
delete mode 100644 src/echo_plugin/echo.c
create mode 100644 src/echo_plugin/echo.cc
delete mode 100644 src/ffaudio/ffaudio-core.c
create mode 100644 src/ffaudio/ffaudio-core.cc
delete mode 100644 src/ffaudio/ffaudio-io.c
create mode 100644 src/ffaudio/ffaudio-io.cc
create mode 100644 src/ffaudio/itunes-cover.cc
delete mode 100644 src/filewriter/convert.c
create mode 100644 src/filewriter/convert.cc
delete mode 100644 src/filewriter/filewriter.c
create mode 100644 src/filewriter/filewriter.cc
delete mode 100644 src/filewriter/flac.c
create mode 100644 src/filewriter/flac.cc
delete mode 100644 src/filewriter/mp3.c
create mode 100644 src/filewriter/mp3.cc
delete mode 100644 src/filewriter/vorbis.c
create mode 100644 src/filewriter/vorbis.cc
delete mode 100644 src/filewriter/wav.c
create mode 100644 src/filewriter/wav.cc
delete mode 100644 src/flacng/metadata.c
create mode 100644 src/flacng/metadata.cc
delete mode 100644 src/flacng/plugin.c
create mode 100644 src/flacng/plugin.cc
delete mode 100644 src/flacng/seekable_stream_callbacks.c
create mode 100644 src/flacng/seekable_stream_callbacks.cc
delete mode 100644 src/flacng/tools.c
create mode 100644 src/flacng/tools.cc
delete mode 100644 src/gio/gio.c
create mode 100644 src/gio/gio.cc
create mode 100644 src/gl-spectrum-qt/Makefile
create mode 100644 src/gl-spectrum-qt/gl-spectrum.cc
delete mode 100644 src/gl-spectrum/gl-spectrum.c
create mode 100644 src/gl-spectrum/gl-spectrum.cc
delete mode 100644 src/gnomeshortcuts/gnomeshortcuts.c
create mode 100644 src/gnomeshortcuts/gnomeshortcuts.cc
delete mode 100644 src/gtkui/columns.c
create mode 100644 src/gtkui/columns.cc
delete mode 100644 src/gtkui/layout.c
create mode 100644 src/gtkui/layout.cc
delete mode 100644 src/gtkui/menus.c
create mode 100644 src/gtkui/menus.cc
delete mode 100644 src/gtkui/playlist_util.c
create mode 100644 src/gtkui/playlist_util.cc
delete mode 100644 src/gtkui/settings.c
create mode 100644 src/gtkui/settings.cc
delete mode 100644 src/gtkui/ui_gtk.c
create mode 100644 src/gtkui/ui_gtk.cc
delete mode 100644 src/gtkui/ui_infoarea.c
create mode 100644 src/gtkui/ui_infoarea.cc
delete mode 100644 src/gtkui/ui_playlist_notebook.c
create mode 100644 src/gtkui/ui_playlist_notebook.cc
delete mode 100644 src/gtkui/ui_playlist_widget.c
create mode 100644 src/gtkui/ui_playlist_widget.cc
delete mode 100644 src/gtkui/ui_statusbar.c
create mode 100644 src/gtkui/ui_statusbar.cc
delete mode 100644 src/hotkey/grab.c
create mode 100644 src/hotkey/grab.cc
delete mode 100644 src/hotkey/gui.c
create mode 100644 src/hotkey/gui.cc
delete mode 100644 src/hotkey/plugin.c
create mode 100644 src/hotkey/plugin.cc
create mode 100644 src/jack-ng/Makefile
create mode 100644 src/jack-ng/jack-ng.cc
delete mode 100644 src/jack/Makefile
delete mode 100644 src/jack/bio2jack.c
delete mode 100644 src/jack/bio2jack.h
delete mode 100644 src/jack/jack.c
delete mode 100644 src/jack/jack.h
delete mode 100644 src/ladspa/effect.c
create mode 100644 src/ladspa/effect.cc
delete mode 100644 src/ladspa/loaded-list.c
create mode 100644 src/ladspa/loaded-list.cc
delete mode 100644 src/ladspa/plugin-list.c
create mode 100644 src/ladspa/plugin-list.cc
delete mode 100644 src/ladspa/plugin.c
create mode 100644 src/ladspa/plugin.cc
delete mode 100644 src/lirc/lirc.c
create mode 100644 src/lirc/lirc.cc
create mode 100644 src/lyricwiki-qt/Makefile
create mode 100644 src/lyricwiki-qt/lyricwiki.cc
delete mode 100644 src/lyricwiki/lyricwiki.c
create mode 100644 src/lyricwiki/lyricwiki.cc
delete mode 100644 src/m3u/m3u.c
create mode 100644 src/m3u/m3u.cc
create mode 100644 src/mac-media-keys/MacMediaKeys.h
create mode 100644 src/mac-media-keys/MacMediaKeys.mm
create mode 100644 src/mac-media-keys/Makefile
create mode 100644 src/mac-media-keys/SPInvocationGrabbing.h
create mode 100644 src/mac-media-keys/SPInvocationGrabbing.m
create mode 100644 src/mac-media-keys/SPMediaKeyTap.h
create mode 100644 src/mac-media-keys/SPMediaKeyTap.m
delete mode 100644 src/metronom/metronom.c
create mode 100644 src/metronom/metronom.cc
delete mode 100644 src/mixer/mixer.c
create mode 100644 src/mixer/mixer.cc
delete mode 100644 src/mms/mms.c
create mode 100644 src/mms/mms.cc
create mode 100644 src/modplug/archive/arch_raw.cc
delete mode 100644 src/modplug/archive/arch_raw.cxx
create mode 100644 src/modplug/archive/archive.cc
delete mode 100644 src/modplug/archive/archive.cxx
create mode 100644 src/modplug/archive/open.cc
delete mode 100644 src/modplug/archive/open.cxx
create mode 100644 src/modplug/modplugbmp.cc
delete mode 100644 src/modplug/modplugbmp.cxx
delete mode 100644 src/modplug/plugin.cxx
delete mode 100644 src/modplug/plugin.h
delete mode 100644 src/modplug/plugin_main.c
create mode 100644 src/modplug/plugin_main.cc
delete mode 100644 src/mpg123/mpg123.c
create mode 100644 src/mpg123/mpg123.cc
delete mode 100644 src/mpris2/plugin.c
create mode 100644 src/mpris2/plugin.cc
delete mode 100644 src/neon/cert_verification.c
create mode 100644 src/neon/cert_verification.cc
delete mode 100644 src/neon/debug.h
delete mode 100644 src/neon/neon.c
create mode 100644 src/neon/neon.cc
delete mode 100644 src/neon/neon.h
delete mode 100644 src/neon/rb.c
delete mode 100644 src/neon/rb.h
delete mode 100644 src/notify/event.c
create mode 100644 src/notify/event.cc
delete mode 100644 src/notify/notify.c
create mode 100644 src/notify/notify.cc
delete mode 100644 src/notify/osd.c
create mode 100644 src/notify/osd.cc
delete mode 100644 src/oss4/oss.c
create mode 100644 src/oss4/oss.cc
delete mode 100644 src/oss4/plugin.c
create mode 100644 src/oss4/plugin.cc
delete mode 100644 src/oss4/utils.c
create mode 100644 src/oss4/utils.cc
create mode 100644 src/playlist-manager/Makefile
create mode 100644 src/playlist-manager/playlist-manager.cc
delete mode 100644 src/pls/pls.c
create mode 100644 src/pls/pls.cc
delete mode 100644 src/psf/corlett.c
create mode 100644 src/psf/corlett.cc
delete mode 100644 src/psf/eng_psf.c
create mode 100644 src/psf/eng_psf.cc
delete mode 100644 src/psf/eng_psf2.c
create mode 100644 src/psf/eng_psf2.cc
delete mode 100644 src/psf/eng_spx.c
create mode 100644 src/psf/eng_spx.cc
delete mode 100644 src/psf/peops/adsr.c
create mode 100644 src/psf/peops/adsr.cc
delete mode 100644 src/psf/peops/dma.c
create mode 100644 src/psf/peops/dma.cc
delete mode 100644 src/psf/peops/registers.c
create mode 100644 src/psf/peops/registers.cc
delete mode 100644 src/psf/peops/reverb.c
create mode 100644 src/psf/peops/reverb.cc
delete mode 100644 src/psf/peops/spu.c
create mode 100644 src/psf/peops/spu.cc
delete mode 100644 src/psf/peops2/adsr.c
create mode 100644 src/psf/peops2/adsr.cc
delete mode 100644 src/psf/peops2/dma.c
create mode 100644 src/psf/peops2/dma.cc
delete mode 100644 src/psf/peops2/registers.c
create mode 100644 src/psf/peops2/registers.cc
delete mode 100644 src/psf/peops2/reverb.c
create mode 100644 src/psf/peops2/reverb.cc
delete mode 100644 src/psf/peops2/spu.c
create mode 100644 src/psf/peops2/spu.cc
delete mode 100644 src/psf/peops2/xa.c
create mode 100644 src/psf/peops2/xa.cc
delete mode 100644 src/psf/plugin.c
create mode 100644 src/psf/plugin.cc
delete mode 100644 src/psf/psx.c
create mode 100644 src/psf/psx.cc
delete mode 100644 src/psf/psx_hw.c
create mode 100644 src/psf/psx_hw.cc
delete mode 100644 src/pulse_audio/pulse_audio.c
create mode 100644 src/pulse_audio/pulse_audio.cc
create mode 100644 src/qtaudio/Makefile
create mode 100644 src/qtaudio/qtaudio.cc
create mode 100644 src/qtui/Makefile
create mode 100644 src/qtui/QtUi/16/audio-volume-high.png
create mode 100644 src/qtui/QtUi/16/audio-volume-low.png
create mode 100644 src/qtui/QtUi/16/audio-volume-medium.png
create mode 100644 src/qtui/QtUi/16/audio-volume-muted.png
create mode 100644 src/qtui/QtUi/16/audio-volume-off.png
create mode 100644 src/qtui/QtUi/16/document-open.png
create mode 100644 src/qtui/QtUi/16/edit-find.png
create mode 100644 src/qtui/QtUi/16/list-add.png
create mode 100644 src/qtui/QtUi/16/media-playback-pause.png
create mode 100644 src/qtui/QtUi/16/media-playback-start.png
create mode 100644 src/qtui/QtUi/16/media-playback-stop.png
create mode 100644 src/qtui/QtUi/16/media-playlist-repeat.png
create mode 100644 src/qtui/QtUi/16/media-playlist-shuffle.png
create mode 100644 src/qtui/QtUi/16/media-skip-backward.png
create mode 100644 src/qtui/QtUi/16/media-skip-forward.png
create mode 100644 src/qtui/QtUi/22/audio-volume-high.png
create mode 100644 src/qtui/QtUi/22/audio-volume-low.png
create mode 100644 src/qtui/QtUi/22/audio-volume-medium.png
create mode 100644 src/qtui/QtUi/22/audio-volume-muted.png
create mode 100644 src/qtui/QtUi/22/audio-volume-off.png
create mode 100644 src/qtui/QtUi/22/document-open.png
create mode 100644 src/qtui/QtUi/22/edit-find.png
create mode 100644 src/qtui/QtUi/22/list-add.png
create mode 100644 src/qtui/QtUi/22/media-playback-pause.png
create mode 100644 src/qtui/QtUi/22/media-playback-start.png
create mode 100644 src/qtui/QtUi/22/media-playback-stop.png
create mode 100644 src/qtui/QtUi/22/media-playlist-repeat.png
create mode 100644 src/qtui/QtUi/22/media-playlist-shuffle.png
create mode 100644 src/qtui/QtUi/22/media-skip-backward.png
create mode 100644 src/qtui/QtUi/22/media-skip-forward.png
create mode 100644 src/qtui/QtUi/32/audio-volume-high.png
create mode 100644 src/qtui/QtUi/32/audio-volume-low.png
create mode 100644 src/qtui/QtUi/32/audio-volume-medium.png
create mode 100644 src/qtui/QtUi/32/audio-volume-muted.png
create mode 100644 src/qtui/QtUi/32/audio-volume-off.png
create mode 100644 src/qtui/QtUi/32/document-open.png
create mode 100644 src/qtui/QtUi/32/edit-find.png
create mode 100644 src/qtui/QtUi/32/list-add.png
create mode 100644 src/qtui/QtUi/32/media-playback-pause.png
create mode 100644 src/qtui/QtUi/32/media-playback-start.png
create mode 100644 src/qtui/QtUi/32/media-playback-stop.png
create mode 100644 src/qtui/QtUi/32/media-playlist-repeat.png
create mode 100644 src/qtui/QtUi/32/media-playlist-shuffle.png
create mode 100644 src/qtui/QtUi/32/media-skip-backward.png
create mode 100644 src/qtui/QtUi/32/media-skip-forward.png
create mode 100644 src/qtui/QtUi/44/audio-volume-high.png
create mode 100644 src/qtui/QtUi/44/audio-volume-low.png
create mode 100644 src/qtui/QtUi/44/audio-volume-medium.png
create mode 100644 src/qtui/QtUi/44/audio-volume-muted.png
create mode 100644 src/qtui/QtUi/44/audio-volume-off.png
create mode 100644 src/qtui/QtUi/44/document-open.png
create mode 100644 src/qtui/QtUi/44/edit-find.png
create mode 100644 src/qtui/QtUi/44/list-add.png
create mode 100644 src/qtui/QtUi/44/media-playback-pause.png
create mode 100644 src/qtui/QtUi/44/media-playback-start.png
create mode 100644 src/qtui/QtUi/44/media-playback-stop.png
create mode 100644 src/qtui/QtUi/44/media-playlist-repeat.png
create mode 100644 src/qtui/QtUi/44/media-playlist-shuffle.png
create mode 100644 src/qtui/QtUi/44/media-skip-backward.png
create mode 100644 src/qtui/QtUi/44/media-skip-forward.png
create mode 100644 src/qtui/QtUi/AUTHORS
create mode 100644 src/qtui/QtUi/index.theme
create mode 100644 src/qtui/dialog_windows.cc
create mode 100644 src/qtui/dialog_windows.h
create mode 100644 src/qtui/filter_input.cc
create mode 100644 src/qtui/filter_input.h
create mode 100644 src/qtui/info_bar.cc
create mode 100644 src/qtui/info_bar.h
create mode 100644 src/qtui/main_window.cc
create mode 100644 src/qtui/main_window.h
create mode 100644 src/qtui/main_window_actions.cc
create mode 100644 src/qtui/playlist.cc
create mode 100644 src/qtui/playlist.h
create mode 100644 src/qtui/playlist_model.cc
create mode 100644 src/qtui/playlist_model.h
create mode 100644 src/qtui/playlist_tabs.cc
create mode 100644 src/qtui/playlist_tabs.h
create mode 100644 src/qtui/qtui.cc
create mode 100644 src/qtui/status_bar.cc
create mode 100644 src/qtui/status_bar.h
create mode 100644 src/qtui/time_slider.cc
create mode 100644 src/qtui/time_slider.h
create mode 100644 src/qtui/tool_bar.cc
create mode 100644 src/qtui/tool_bar.h
delete mode 100644 src/resample/resample.c
create mode 100644 src/resample/resample.cc
delete mode 100644 src/scrobbler2/config_window.c
create mode 100644 src/scrobbler2/config_window.cc
delete mode 100644 src/scrobbler2/scrobbler.c
create mode 100644 src/scrobbler2/scrobbler.cc
delete mode 100644 src/scrobbler2/scrobbler_communication.c
create mode 100644 src/scrobbler2/scrobbler_communication.cc
delete mode 100644 src/scrobbler2/scrobbler_xml_parsing.c
create mode 100644 src/scrobbler2/scrobbler_xml_parsing.cc
delete mode 100644 src/sdlout/plugin.c
delete mode 100644 src/sdlout/sdlout.c
create mode 100644 src/sdlout/sdlout.cc
delete mode 100644 src/sdlout/sdlout.h
delete mode 100644 src/search-tool/search-tool.c
create mode 100644 src/search-tool/search-tool.cc
delete mode 100644 src/sid/xmms-sid.c
create mode 100644 src/sid/xmms-sid.cc
delete mode 100644 src/sid/xs_config.c
create mode 100644 src/sid/xs_config.cc
delete mode 100644 src/sid/xs_length.c
delete mode 100644 src/sid/xs_length.h
delete mode 100644 src/sid/xs_md5.c
delete mode 100644 src/sid/xs_md5.h
delete mode 100644 src/sid/xs_player.h
delete mode 100644 src/sid/xs_slsup.c
delete mode 100644 src/sid/xs_slsup.h
delete mode 100644 src/sid/xs_stil.c
delete mode 100644 src/sid/xs_stil.h
delete mode 100644 src/sid/xs_support.c
delete mode 100644 src/sid/xs_support.h
create mode 100644 src/silence-removal/Makefile
create mode 100644 src/silence-removal/silence-removal.cc
delete mode 100644 src/skins/drag-handle.c
create mode 100644 src/skins/drag-handle.cc
delete mode 100644 src/skins/menus.c
create mode 100644 src/skins/menus.cc
create mode 100644 src/skins/plugin-window.cc
create mode 100644 src/skins/plugin-window.h
delete mode 100644 src/skins/plugin.c
create mode 100644 src/skins/plugin.cc
delete mode 100644 src/skins/preset-browser.c
create mode 100644 src/skins/preset-browser.cc
delete mode 100644 src/skins/preset-list.c
create mode 100644 src/skins/preset-list.cc
delete mode 100644 src/skins/skins_cfg.c
create mode 100644 src/skins/skins_cfg.cc
delete mode 100644 src/skins/surface.c
create mode 100644 src/skins/surface.cc
delete mode 100644 src/skins/ui_dock.c
create mode 100644 src/skins/ui_dock.cc
delete mode 100644 src/skins/ui_equalizer.c
create mode 100644 src/skins/ui_equalizer.cc
delete mode 100644 src/skins/ui_main.c
create mode 100644 src/skins/ui_main.cc
delete mode 100644 src/skins/ui_main_evlisteners.c
create mode 100644 src/skins/ui_main_evlisteners.cc
delete mode 100644 src/skins/ui_playlist.c
create mode 100644 src/skins/ui_playlist.cc
delete mode 100644 src/skins/ui_skin.c
create mode 100644 src/skins/ui_skin.cc
delete mode 100644 src/skins/ui_skin_load_ini.c
create mode 100644 src/skins/ui_skin_load_ini.cc
delete mode 100644 src/skins/ui_skinned_button.c
create mode 100644 src/skins/ui_skinned_button.cc
delete mode 100644 src/skins/ui_skinned_equalizer_graph.c
create mode 100644 src/skins/ui_skinned_equalizer_graph.cc
delete mode 100644 src/skins/ui_skinned_equalizer_slider.c
create mode 100644 src/skins/ui_skinned_equalizer_slider.cc
delete mode 100644 src/skins/ui_skinned_horizontal_slider.c
create mode 100644 src/skins/ui_skinned_horizontal_slider.cc
delete mode 100644 src/skins/ui_skinned_menurow.c
create mode 100644 src/skins/ui_skinned_menurow.cc
delete mode 100644 src/skins/ui_skinned_monostereo.c
create mode 100644 src/skins/ui_skinned_monostereo.cc
delete mode 100644 src/skins/ui_skinned_number.c
create mode 100644 src/skins/ui_skinned_number.cc
delete mode 100644 src/skins/ui_skinned_playlist.c
create mode 100644 src/skins/ui_skinned_playlist.cc
delete mode 100644 src/skins/ui_skinned_playlist_slider.c
create mode 100644 src/skins/ui_skinned_playlist_slider.cc
delete mode 100644 src/skins/ui_skinned_playstatus.c
create mode 100644 src/skins/ui_skinned_playstatus.cc
delete mode 100644 src/skins/ui_skinned_textbox.c
create mode 100644 src/skins/ui_skinned_textbox.cc
delete mode 100644 src/skins/ui_skinned_window.c
create mode 100644 src/skins/ui_skinned_window.cc
delete mode 100644 src/skins/ui_skinselector.c
create mode 100644 src/skins/ui_skinselector.cc
delete mode 100644 src/skins/ui_svis.c
create mode 100644 src/skins/ui_svis.cc
delete mode 100644 src/skins/ui_vis.c
create mode 100644 src/skins/ui_vis.cc
delete mode 100644 src/skins/util.c
create mode 100644 src/skins/util.cc
delete mode 100644 src/skins/view.c
create mode 100644 src/skins/view.cc
delete mode 100644 src/sndfile/plugin.c
create mode 100644 src/sndfile/plugin.cc
create mode 100644 src/sndio-ng/Makefile
create mode 100644 src/sndio-ng/sndio.cc
delete mode 100644 src/sndio/Makefile
delete mode 100644 src/sndio/sndio.c
create mode 100644 src/song-info-qt/Makefile
create mode 100644 src/song-info-qt/song-info.cc
delete mode 100644 src/song_change/formatter.c
create mode 100644 src/song_change/formatter.cc
delete mode 100644 src/song_change/song_change.c
create mode 100644 src/song_change/song_change.cc
delete mode 100644 src/sox-resampler/sox-resampler.c
create mode 100644 src/sox-resampler/sox-resampler.cc
delete mode 100644 src/speed-pitch/speed-pitch.c
create mode 100644 src/speed-pitch/speed-pitch.cc
delete mode 100644 src/statusicon/statusicon.c
create mode 100644 src/statusicon/statusicon.cc
delete mode 100644 src/statusicon/statusicon.h
delete mode 100644 src/statusicon/util.c
delete mode 100644 src/stereo_plugin/stereo.c
create mode 100644 src/stereo_plugin/stereo.cc
delete mode 100644 src/tonegen/tonegen.c
create mode 100644 src/tonegen/tonegen.cc
delete mode 100644 src/voice_removal/voice_removal.c
create mode 100644 src/voice_removal/voice_removal.cc
delete mode 100644 src/vorbis/vcedit.c
create mode 100644 src/vorbis/vcedit.cc
delete mode 100644 src/vorbis/vcupdate.c
create mode 100644 src/vorbis/vcupdate.cc
delete mode 100644 src/vorbis/vorbis.c
create mode 100644 src/vorbis/vorbis.cc
delete mode 100644 src/vtx/ay8912.c
create mode 100644 src/vtx/ay8912.cc
delete mode 100644 src/vtx/info.c
create mode 100644 src/vtx/info.cc
delete mode 100644 src/vtx/lh5dec.c
create mode 100644 src/vtx/lh5dec.cc
delete mode 100644 src/vtx/vtx.c
create mode 100644 src/vtx/vtx.cc
delete mode 100644 src/vtx/vtxfile.c
create mode 100644 src/vtx/vtxfile.cc
delete mode 100644 src/wavpack/wavpack.c
create mode 100644 src/wavpack/wavpack.cc
delete mode 100644 src/xsf/corlett.c
create mode 100644 src/xsf/corlett.cc
delete mode 100644 src/xsf/desmume/FIFO.c
create mode 100644 src/xsf/desmume/FIFO.cc
delete mode 100644 src/xsf/desmume/GPU.c
create mode 100644 src/xsf/desmume/GPU.cc
delete mode 100644 src/xsf/desmume/MMU.c
create mode 100644 src/xsf/desmume/MMU.cc
delete mode 100644 src/xsf/desmume/NDSSystem.c
create mode 100644 src/xsf/desmume/NDSSystem.cc
delete mode 100644 src/xsf/desmume/SPU.c
create mode 100644 src/xsf/desmume/SPU.cc
delete mode 100644 src/xsf/desmume/arm_instructions.c
create mode 100644 src/xsf/desmume/arm_instructions.cc
delete mode 100644 src/xsf/desmume/armcpu.c
create mode 100644 src/xsf/desmume/armcpu.cc
delete mode 100644 src/xsf/desmume/bios.c
create mode 100644 src/xsf/desmume/bios.cc
delete mode 100644 src/xsf/desmume/cp15.c
create mode 100644 src/xsf/desmume/cp15.cc
delete mode 100644 src/xsf/desmume/matrix.c
create mode 100644 src/xsf/desmume/matrix.cc
delete mode 100644 src/xsf/desmume/mc.c
create mode 100644 src/xsf/desmume/mc.cc
delete mode 100644 src/xsf/desmume/thumb_instructions.c
create mode 100644 src/xsf/desmume/thumb_instructions.cc
delete mode 100644 src/xsf/plugin.c
create mode 100644 src/xsf/plugin.cc
delete mode 100644 src/xsf/vio2sf.c
create mode 100644 src/xsf/vio2sf.cc
delete mode 100644 src/xspf/xspf.c
create mode 100644 src/xspf/xspf.cc
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 845ca0677527..000000000000
--- a/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-.pc
diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index 9059c8011dcd..000000000000
--- a/AUTHORS
+++ /dev/null
@@ -1,174 +0,0 @@
-Audacious (C) GPL 2005-2009
-
-Authors listed alphabetically, by last name:
---------------------------------------------
-
-George Averill <nhjm449 at gmail.com>
-Kieran Clancy <clancy.kieran+audacious at gmail.com>
-Michael Färber <0102 at gmx.at>
-Matti Hämäläinen <ccr at tnsp.org>
-Giacomo Lozito <james at develia.org>
-Tomasz MoÅ <desowin at gmail.com>
-William Pitcock <nenolod at sacredspiral.co.uk>
-Derek Pomery <nemo at m8y.org>
-Mohammed Sameer <msameer at foolab.org>
-Jonathan Schleifer <js-audacious at webkeks.org>
-Stephen Sokolow <deitarion at gmail.com>
-Ben Tucker <ben at tucker.org>
-Tony Vroon <chainsaw at gentoo.org>
-Yoshiki Yazawa <yaz at cc.or.rim.jp>
-
-Translators
------------
-
-Dutch - Tony Vroon
-Hungarian - Dvornik László
-German - Michael Hanselmann
- Matthias Debus
-Greek - Kouzinopoulos Haris
- Stavros Giannouris
- Stathis Kamperis
-Italian - Diego Petteno
-Japanese - Dai
-Finnish - Pauli Virtanen
- Matti Hämäläinen
-
--
-
-Based on:
-
-BMP - beep media player (C) GPL 2003-2005
-
-Authors alphabetically
-----------------------
-
-Artem Baguinski <artm at v2.nl>
-Edward Brocklesby <ejb at goth.net>
-Chong Kai Xiong <descender at phreaker.net>
-Milosz Derezynski <m.derezynski at arcor.de>
-David Lau <coder_sku at users.sourceforge.net>
-Ole Andre Vadla Ravnaas <oleavr at jblinux.net>
-Michiel Sikkes <michiel at eyesopened.nl>
-
-Patch Authors
--------------
-
-Andrei Badea
-Peter Behroozi
-Bernard Blackham
-Oliver Blin
-David Le Brun
-Tomas Bzatek
-Liviu Danicel
-Jon Dowland
-Artur Frysiak
-Sebastian Kapfer
-Lukas Koberstein
-Dan Korostelev
-Oliver Lehmann
-Jolan Luff
-Mike Lundy
-Michael Marineau
-Tim-Philipp Muller
-Julien Portalier
-Andrew Ruder
-Olivier Samyn
-John Spray
-Takashi Iwai
-Martijn Vernooij
-Thierry Vignaud
-
-Translators
------------
-
-Brazilian Portuguese - Philipi Pinto <philipi at gmx.net>
-Breton - Thierry Vignaud <tvignaud at mandrakesoft.com>
-Czech - Jan Narovec <jnarovec at students.zcu.cz>
-Dutch - Laurens Buhler <masterpe at xs4all.nl>
-German - Matthias Debus <psic4t at netbands.de>
-Georgian - George Machitidze <giomac at global-erty.net>
-Greek - Kouzinopoulos Haris <haris at mpa.gr>
- Stavros Giannouris <stavrosg2002 at freemail.gr>
-Finnish - Pauli Virtanen <pauli.virtanen at hut.fi>
-French - David Le Brun <david at dyn-ns.net>
-Hindi - Dhananjaya Sharma <dysxhi at yahoo.co.in>
-Hungarian - Dvornik László <dvornik at gnome.hu>
-Italian - Alessio D'Ascanio <otaku at fastwebnet.it>
-Japanese - Takeshi Aihana <aihana at gnome.gr.jp>
-Korean - DongCheon Park <dcpark at kaist.ac.kr>
-Lithuanian - Rimas Kudelis <rq at akl.lt>
-Macedonian - Arangel Angov <ufo at linux.net.mk>
-Polish - Jacek Wolszczak <shutdownrunner at o2.pl>
-Romanian - Liviu Danicel <liviu.danicel at spymac.com>
-Russian - Pavlo Bohmat <bohm at ukr.net>
- Dan Korostelev <dan at ats.energo.ru>
- Vitaly Lipatov <lav at altlinux.ru>
- Maxim Musatov <m1kc at yandex.ru>
-Simplified Chinese - Chong Kai Xiong <descender at phreaker.net>
-Traditional Chinese - Chao-Hsiung Liao <pesder.liao at msa.hinet.net>
-Slovak - Pavel Kanzelsberger <kanzels at zmail.sk>
-Spanish - Francisco Javier F. Serrador <serrador at cvs.gnome.org>
-Swedish - Martin Persenius <martin at persenius.net>
-Ukrainian - Mykola Lynnyk<definer at users.sf.net>
-Welsh - Edward Brocklesby <ejb at goth.net>
- (Based on XMMS from Rhoslyn Prys <rhoslyn.prys at meddal.org.uk>)
-
-
-(please tell us if we left your name out)
-
--
-
-Based on:
-
-XMMS - X Multimedia System (C)1998-2003
-
- Main Programming: Peter Alm
-
- Additional Programming: Håvard Kvålen
- Derrik Pates
-
- With Additional Help: Sean Atkinson
- Jorn Baayen
- James M. Cape
- Anders Carlsson (effect plugins)
- Chun-Chung Chen (xfont patch)
- Tim Ferguson (joystick plugin)
- Ben Gertzfield
- Vesa Halttunen
- Logan Hanks
- Eric L. Hernes (FreeBSD patches)
- Ville Herva
- higway (MMX)
- Michael Hipp and others (MPG123 engine)
- Olle Hällnäs (compiling fixes)
- David Jacoby
- Osamu Kayasono (3DNow!)
- Lyle B Kempler
- J. Nick Koston (MikMod plugin)
- Aaron Lehmann
- Johan Levin (echo + stereo plugin)
- Eric Lindvall
- Colin Marquardt
- Willem Monsuwe
- John Riddoch (Solaris plugin)
- Josip Rodin
- Pablo Saratxaga (i18n)
- Carl van Schaik (pro logic plugin)
- Jörg Schuler
- Charles Sielski (irman plugin)
- Espen Skoglund
- Matthieu Sozeau (ALSA plugin)
- Kimura Takuhiro (3DNow!)
- Zinx Verituse
- Ryan Weaver (RPMs among other things)
- Chris Wilson
- Dave Yearke
- Stephan K. Zitz
-
- Default skin: Leonard "Blayde" Tan
- Robin Sylvestre (Equalizer and Playlist)
- Thomas Nilsson (New titles, and cleanups)
-
- Homepage and Graphics: Thomas Nilsson
-
- Support and Docs: Olle Hällnäs
diff --git a/COPYING b/COPYING
index 8dd4e9166445..f634604e545f 100644
--- a/COPYING
+++ b/COPYING
@@ -1,35 +1,22 @@
-The buildsystem and framework for installing and managing plugins is:
+The build system and framework for installing and managing plugins is:
-Copyright (c) 2005-2007 Audacious development team.
+Copyright © 2001-2015 Audacious developers
-All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions, and the following disclaimer in the
+ documentation provided with the distribution.
- Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- Neither the name of the author nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software is provided âas isâ and without any warranty, express or
+ implied. In no event shall the authors be liable for any damages arising
+ from the use of this software.
------------------------------------------------------------------------------
-The plugins themselves are distributed under their own distribution terms,
-read the sourcecode for plugin-specific licensing details.
+The plugins themselves are distributed under their own distribution terms.
+Read the source code for individual copyright holders and licensing details.
diff --git a/acinclude.m4 b/acinclude.m4
index 157258c8586b..cccd41186b06 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1,5 +1,5 @@
dnl Add $1 to CFLAGS and CXXFLAGS if supported
-dnl ------------------------------------------
+dnl ==========================================
AC_DEFUN([AUD_CHECK_CFLAGS],[
AC_MSG_CHECKING([whether the C/C++ compiler supports $1])
@@ -15,25 +15,30 @@ AC_DEFUN([AUD_CHECK_CFLAGS],[
])
])
+dnl Add $1 to CXXFLAGS if supported
+dnl ===============================
+
+AC_DEFUN([AUD_CHECK_CXXFLAGS],[
+ AC_MSG_CHECKING([whether the C++ compiler supports $1])
+ AC_LANG_PUSH([C++])
+ OLDCXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS $1 -Werror"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[return 0;])],[
+ AC_MSG_RESULT(yes)
+ CXXFLAGS="$OLDCXXFLAGS $1"
+ ],[
+ AC_MSG_RESULT(no)
+ CXXFLAGS="$OLDCXXFLAGS"
+ ])
+ AC_LANG_POP([C++])
+])
+
dnl **
dnl ** Common checks
dnl **
AC_DEFUN([AUD_COMMON_PROGS], [
-dnl Check for C and C++ compilers
-dnl =============================
-AC_REQUIRE([AC_PROG_CC])
-AC_REQUIRE([AC_PROG_CXX])
-AC_REQUIRE([AC_C_BIGENDIAN])
-AC_REQUIRE([AC_SYS_LARGEFILE])
-
-if test "x$GCC" = "xyes"; then
- CFLAGS="$CFLAGS -std=gnu99 -ffast-math -Wall -pipe"
- CXXFLAGS="$CXXFLAGS -Wall -pipe"
- AUD_CHECK_CFLAGS(-Wtype-limits)
-fi
-
dnl Check platform
dnl ==============
@@ -44,6 +49,7 @@ AC_MSG_CHECKING([operating system type])
HAVE_LINUX=no
HAVE_MSWINDOWS=no
+HAVE_DARWIN=no
case "$target" in
*linux*)
@@ -54,6 +60,10 @@ case "$target" in
AC_MSG_RESULT(Windows)
HAVE_MSWINDOWS=yes
;;
+ *darwin*)
+ AC_MSG_RESULT(Darwin)
+ HAVE_DARWIN=yes
+ ;;
*)
AC_MSG_RESULT(other UNIX)
;;
@@ -61,6 +71,38 @@ esac
AC_SUBST(HAVE_MSWINDOWS)
AC_SUBST(HAVE_LINUX)
+AC_SUBST(HAVE_DARWIN)
+
+dnl Check for C and C++ compilers
+dnl =============================
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([AC_C_BIGENDIAN])
+AC_REQUIRE([AC_SYS_LARGEFILE])
+
+if test "x$GCC" = "xyes"; then
+ CFLAGS="$CFLAGS -std=gnu99 -ffast-math -Wall -pipe"
+ if test "x$HAVE_DARWIN" = "xyes"; then
+ CXXFLAGS="$CXXFLAGS -stdlib=libc++ -std=gnu++11 -ffast-math -Wall -pipe"
+ LDFLAGS="$LDFLAGS -lc++ -stdlib=libc++"
+ else
+ CXXFLAGS="$CXXFLAGS -std=gnu++11 -ffast-math -Wall -pipe"
+ fi
+ AUD_CHECK_CFLAGS(-Wtype-limits)
+ AUD_CHECK_CXXFLAGS(-Woverloaded-virtual)
+fi
+
+dnl On Mac, check for Objective-C and -C++ compilers
+dnl ================================================
+
+if test "x$HAVE_DARWIN" = "xyes"; then
+ AC_PROG_OBJC
+ AC_PROG_OBJCPP
+ AC_PROG_OBJCXX
+ AC_PROG_OBJCXXCPP
+
+ OBJCXXFLAGS="$OBJCXXFLAGS -stdlib=libc++ -std=c++11"
+fi
dnl Enable "-Wl,-z,defs" only on Linux
dnl ==================================
@@ -74,6 +116,26 @@ if test $HAVE_MSWINDOWS = yes ; then
CFLAGS="$CFLAGS -march=i686"
fi
+dnl Byte order
+dnl ==========
+AC_C_BIGENDIAN([BIGENDIAN=1], [BIGENDIAN=0],
+ [AC_MSG_ERROR([Unknown machine byte order])],
+ [AC_MSG_ERROR([Universal builds are not supported, sorry])])
+AC_SUBST([BIGENDIAN])
+
+dnl Prevent symbol collisions
+dnl =========================
+if test "x$HAVE_MSWINDOWS" = "xyes" ; then
+ EXPORT="__declspec(dllexport)"
+elif test "x$GCC" = "xyes" ; then
+ CFLAGS="$CFLAGS -fvisibility=hidden"
+ CXXFLAGS="$CXXFLAGS -fvisibility=hidden"
+ EXPORT="__attribute__((visibility(\"default\")))"
+else
+ AC_MSG_ERROR([Unknown syntax for EXPORT keyword])
+fi
+AC_DEFINE_UNQUOTED([EXPORT], [$EXPORT], [Define to compiler syntax for public symbols])
+
dnl Checks for various programs
dnl ===========================
AC_PROG_LN_S
@@ -93,7 +155,20 @@ dnl =======================
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.32)
PKG_CHECK_MODULES(GMODULE, gmodule-2.0 >= 2.32)
-PKG_CHECK_MODULES(GTK, gtk+-3.0 >= 3.4)
+
+dnl GTK+ support
+dnl =============
+
+AC_ARG_ENABLE(gtk,
+ AS_HELP_STRING(--disable-gtk, [Disable GTK+ support (default=enabled)]),
+ USE_GTK=$enableval, USE_GTK=yes)
+
+if test $USE_GTK = yes ; then
+ PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.24)
+ AC_DEFINE(USE_GTK, 1, [Define if GTK+ support enabled])
+fi
+
+AC_SUBST(USE_GTK)
if test $HAVE_MSWINDOWS = yes ; then
PKG_CHECK_MODULES(GIO, gio-2.0 >= 2.32)
@@ -110,4 +185,23 @@ AC_SUBST(GMODULE_LIBS)
AC_SUBST(GTK_CFLAGS)
AC_SUBST(GTK_LIBS)
+dnl Qt support
+dnl ==========
+
+AC_ARG_ENABLE(qt,
+ AS_HELP_STRING(--enable-qt, [Enable Qt support (default=disabled)]),
+ USE_QT=$enableval, USE_QT=no)
+
+if test $USE_QT = yes ; then
+ PKG_CHECK_MODULES([QT], [Qt5Core Qt5Gui Qt5Widgets])
+ AC_DEFINE(USE_QT, 1, [Define if Qt support enabled])
+
+ # needed if Qt was built with -reduce-relocations
+ QT_CFLAGS="$QT_CFLAGS -fPIC"
+fi
+
+AC_SUBST(USE_QT)
+AC_SUBST(QT_CFLAGS)
+AC_SUBST(QT_LIBS)
+
])
diff --git a/config.h.in b/config.h.in
index a49878055624..19fddce57eea 100644
--- a/config.h.in
+++ b/config.h.in
@@ -7,6 +7,9 @@
language is requested. */
#undef ENABLE_NLS
+/* Define to compiler syntax for public symbols */
+#undef EXPORT
+
/* Define if FLAC output part should be built */
#undef FILEWRITER_FLAC
@@ -28,6 +31,9 @@
*/
#undef HAVE_DCGETTEXT
+/* Define if using FFmpeg */
+#undef HAVE_FFMPEG
+
/* Define if the GNU gettext() function is already present or preinstalled. */
#undef HAVE_GETTEXT
@@ -37,18 +43,15 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define if using libav */
+#undef HAVE_LIBAV
+
/* Define to 1 if you have the <lirc/lirc_client.h> header file. */
#undef HAVE_LIRC_LIRC_CLIENT_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
-/* Define to 1 if you have the `mkdtemp' function. */
-#undef HAVE_MKDTEMP
-
-/* Whether we have ne_set_connect_timeout */
-#undef HAVE_NE_SET_CONNECT_TIMEOUT
-
/* Define to 1 if you have the <soundcard.h> header file. */
#undef HAVE_SOUNDCARD_H
@@ -109,6 +112,12 @@
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
+/* Define if GTK+ support enabled */
+#undef USE_GTK
+
+/* Define if Qt support enabled */
+#undef USE_QT
+
/* Version number of package */
#undef VERSION
diff --git a/configure b/configure
index 82da64cf60e7..2eb511616727 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for audacious-plugins 3.5.
+# Generated by GNU Autoconf 2.69 for audacious-plugins 3.6.1.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -9,7 +9,7 @@
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
#
-# (C) 2005-2014 Audacious Team
+# Copyright (C) 2001-2015 Audacious developers and others
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##
@@ -579,8 +579,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='audacious-plugins'
PACKAGE_TARNAME='audacious-plugins'
-PACKAGE_VERSION='3.5'
-PACKAGE_STRING='audacious-plugins 3.5'
+PACKAGE_VERSION='3.6.1'
+PACKAGE_STRING='audacious-plugins 3.6.1'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -651,11 +651,15 @@ EFFECT_PLUGIN_DIR
OUTPUT_PLUGIN_DIR
INPUT_PLUGIN_DIR
plugindir
+QTOPENGL_LIBS
+QTOPENGL_CFLAGS
GL_LIBS
GLIB214_LIBS
GLIB214_CFLAGS
SOXR_LIBS
SOXR_CFLAGS
+SAMPLERATE_LIBS
+SAMPLERATE_CFLAGS
BS2B_LIBS
BS2B_CFLAGS
FILEWRITER_LIBS
@@ -684,8 +688,6 @@ ALSA_CFLAGS
OSS_CFLAGS
SIDPLAYFP_LIBS
SIDPLAYFP_CFLAGS
-SAMPLERATE_LIBS
-SAMPLERATE_CFLAGS
JACK_LIBS
JACK_CFLAGS
FFMPEG_LIBS
@@ -719,8 +721,10 @@ MPG123_LIBS
MPG123_CFLAGS
PULSE_LIBS
PULSE_CFLAGS
-XML_LIBS
+QTMULTIMEDIA_LIBS
+QTMULTIMEDIA_CFLAGS
XML_CFLAGS
+XML_LIBS
AUDACIOUS_LIBS
AUDACIOUS_CFLAGS
POSUB
@@ -757,8 +761,12 @@ LIB_SUFFIX
LIB_PREFIX
LIB_LDFLAGS
LIB_CFLAGS
+USE_QT
+QT_LIBS
+QT_CFLAGS
GIO_LIBS
GIO_CFLAGS
+USE_GTK
GTK_LIBS
GTK_CFLAGS
GMODULE_LIBS
@@ -775,6 +783,29 @@ CP
MV
RM
LN_S
+BIGENDIAN
+OBJCXXCPP
+ac_ct_OBJCXX
+OBJCXXFLAGS
+OBJCXX
+OBJCPP
+ac_ct_OBJC
+OBJCFLAGS
+OBJC
+EGREP
+GREP
+CPP
+ac_ct_CXX
+CXXFLAGS
+CXX
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+HAVE_DARWIN
HAVE_LINUX
HAVE_MSWINDOWS
target_os
@@ -789,19 +820,6 @@ build_os
build_vendor
build_cpu
build
-EGREP
-GREP
-CPP
-ac_ct_CXX
-CXXFLAGS
-CXX
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
target_alias
host_alias
build_alias
@@ -844,13 +862,18 @@ ac_subst_files=''
ac_user_opts='
enable_option_checking
enable_largefile
+enable_gtk
+enable_qt
enable_nls
with_gnu_ld
enable_rpath
with_libiconv_prefix
with_libintl_prefix
+with_system_libxml2
enable_console
enable_xsf
+enable_qtaudio
+enable_coreaudio
enable_pulse
enable_psf
enable_mp3
@@ -858,7 +881,6 @@ enable_hotkey
enable_gnomeshortcuts
enable_lirc
enable_songchange
-enable_statusicon
enable_aosd
enable_aosd_xcomp
enable_notify
@@ -870,12 +892,13 @@ enable_wavpack
enable_aac
enable_sndfile
enable_modplug
-enable_ffaudio
+with_ffmpeg
enable_jack
enable_sid
enable_oss4
enable_alsa
enable_sdlout
+with_libsdl
enable_sndio
enable_amidiplug
enable_cdaudio
@@ -890,10 +913,14 @@ enable_bs2b
enable_resample
enable_speedpitch
enable_soxr
-enable_gtkui
-enable_skins
enable_lyricwiki
enable_glspectrum
+enable_qtglspectrum
+enable_vtx
+enable_ladspa
+enable_blur_scope
+enable_cairo_spectrum
+enable_mac_media_keys
'
ac_precious_vars='build_alias
host_alias
@@ -907,6 +934,12 @@ CXX
CXXFLAGS
CCC
CPP
+OBJC
+OBJCFLAGS
+OBJCPP
+OBJCXX
+OBJCXXFLAGS
+OBJCXXCPP
PKG_CONFIG
PKG_CONFIG_PATH
PKG_CONFIG_LIBDIR
@@ -918,10 +951,14 @@ GTK_CFLAGS
GTK_LIBS
GIO_CFLAGS
GIO_LIBS
+QT_CFLAGS
+QT_LIBS
AUDACIOUS_CFLAGS
AUDACIOUS_LIBS
XML_CFLAGS
XML_LIBS
+QTMULTIMEDIA_CFLAGS
+QTMULTIMEDIA_LIBS
PULSE_CFLAGS
PULSE_LIBS
MPG123_CFLAGS
@@ -952,8 +989,6 @@ FFMPEG_CFLAGS
FFMPEG_LIBS
JACK_CFLAGS
JACK_LIBS
-SAMPLERATE_CFLAGS
-SAMPLERATE_LIBS
SIDPLAYFP_CFLAGS
SIDPLAYFP_LIBS
ALSA_CFLAGS
@@ -978,10 +1013,14 @@ FLAC_CFLAGS
FLAC_LIBS
BS2B_CFLAGS
BS2B_LIBS
+SAMPLERATE_CFLAGS
+SAMPLERATE_LIBS
SOXR_CFLAGS
SOXR_LIBS
GLIB214_CFLAGS
-GLIB214_LIBS'
+GLIB214_LIBS
+QTOPENGL_CFLAGS
+QTOPENGL_LIBS'
# Initialize some variables set by options.
@@ -1522,7 +1561,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures audacious-plugins 3.5 to adapt to many kinds of systems.
+\`configure' configures audacious-plugins 3.6.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1589,7 +1628,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of audacious-plugins 3.5:";;
+ short | recursive ) echo "Configuration of audacious-plugins 3.6.1:";;
esac
cat <<\_ACEOF
@@ -1598,32 +1637,34 @@ Optional Features:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-largefile omit support for large files
+ --disable-gtk Disable GTK+ support (default=enabled)
+ --enable-qt Enable Qt support (default=disabled)
--disable-nls do not use Native Language Support
--disable-rpath do not hardcode runtime library paths
--disable-console disable game music decoder (console)
--disable-xsf disable Nintendo DS audio decoder (xsf)
+ --disable-qtaudio disable QtMultimedia output plugin (default=enabled)
+ --disable-coreaudio disable CoreAudio output plugin (default=enabled)
--disable-pulse disable PulseAudio output plugin (default=enabled)
--disable-psf disable PlayStation (psf/psf2) audio decoder
- --disable-mp3 disable MP3 plugin (default=enabled)
+ --disable-mp3 disable MP3 support (default=enabled)
--disable-hotkey disable global hotkey plugin (default=enabled)
--disable-gnomeshortcuts
disable gnome shortcuts (default=enabled)
--disable-lirc disable LIRC support (default=enabled)
--disable-songchange disable song change plugin
- --disable-statusicon disable X11 Status Icon plugin (default=enabled)
--disable-aosd disable Audacious OSD plugin (default=enabled)
--disable-aosd-xcomp disable Audacious OSD X Composite Support
(default=enabled)
--disable-notify disable notify plugin (default=enabled)
--disable-mpris2 disable MPRIS 2 support (default=auto)
--disable-adplug disable AdPlug plugin (default=enabled)
- --disable-vorbis disable Ogg Vorbis decoding and encoding
- --disable-flacng disable flac input plugin (default=enabled)
+ --disable-vorbis disable Ogg Vorbis support (default=enabled)
+ --disable-flacng disable FLAC support (default=enabled)
--disable-wavpack disable WavPack input plugin (default=enabled)
- --disable-aac disable aac plugin (default=enabled)
+ --disable-aac disable AAC support (default=enabled)
--disable-sndfile disable sndfile extensions. [default=enabled]
--disable-modplug disable ModPlug plugin (default=enabled)
- --disable-ffaudio disable ffaudio plugin (default=enabled)
--disable-jack disable JACK output plugin (default=enabled)
--disable-sid disable SID input plugin (default=enabled)
--disable-oss4 disable OSS4 output plugin
@@ -1647,10 +1688,16 @@ Optional Features:
--disable-speedpitch disable Speed and Pitch effect plugin
--disable-soxr disable SoX Resampler effect plugin
(default=enabled)
- --disable-gtkui disable GTK interface (gtkui)
- --disable-skins disable Winamp Classic interface (skins)
--disable-lyricwiki disable LyricWiki plugin (default=enabled)
--enable-glspectrum enable OpenGL Spectrum Analyzer (default=auto)
+ --disable-qtglspectrum disable Qt OpenGL Spectrum Analyzer
+ (default=enabled)
+ --disable-vtx disable VTX Decoder
+ --disable-ladspa disable LADSPA Host
+ --disable-blur-scope disable Blur Scope
+ --disable-cairo-spectrum
+ disable Cairo Spectrum Analyzer
+ --enable-mac-media-keys enable Mac Media Keys
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -1660,6 +1707,13 @@ Optional Packages:
--without-libiconv-prefix don't search for libiconv in includedir and libdir
--with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib
--without-libintl-prefix don't search for libintl in includedir and libdir
+ --with-system-libxml2=yes,no
+ Use system version of libxml2 (default=yes)
+ --with-ffmpeg=ffmpeg,libav,none
+ choose between FFmpeg, libav, or neither
+ (default=ffmpeg)
+ --with-libsdl=VER select which SDL version to use. Set VER to 1 for
+ libsdl1, to 2 for libsdl2. [default=check]
Some influential environment variables:
CC C compiler command
@@ -1672,6 +1726,12 @@ Some influential environment variables:
CXX C++ compiler command
CXXFLAGS C++ compiler flags
CPP C preprocessor
+ OBJC Objective C compiler command
+ OBJCFLAGS Objective C compiler flags
+ OBJCPP Objective C preprocessor
+ OBJCXX Objective C++ compiler command
+ OBJCXXFLAGS Objective C++ compiler flags
+ OBJCXXCPP Objective C++ preprocessor
PKG_CONFIG path to pkg-config utility
PKG_CONFIG_PATH
directories to add to pkg-config's search path
@@ -1687,12 +1747,18 @@ Some influential environment variables:
GTK_LIBS linker flags for GTK, overriding pkg-config
GIO_CFLAGS C compiler flags for GIO, overriding pkg-config
GIO_LIBS linker flags for GIO, overriding pkg-config
+ QT_CFLAGS C compiler flags for QT, overriding pkg-config
+ QT_LIBS linker flags for QT, overriding pkg-config
AUDACIOUS_CFLAGS
C compiler flags for AUDACIOUS, overriding pkg-config
AUDACIOUS_LIBS
linker flags for AUDACIOUS, overriding pkg-config
XML_CFLAGS C compiler flags for XML, overriding pkg-config
XML_LIBS linker flags for XML, overriding pkg-config
+ QTMULTIMEDIA_CFLAGS
+ C compiler flags for QTMULTIMEDIA, overriding pkg-config
+ QTMULTIMEDIA_LIBS
+ linker flags for QTMULTIMEDIA, overriding pkg-config
PULSE_CFLAGS
C compiler flags for PULSE, overriding pkg-config
PULSE_LIBS linker flags for PULSE, overriding pkg-config
@@ -1742,10 +1808,6 @@ Some influential environment variables:
FFMPEG_LIBS linker flags for FFMPEG, overriding pkg-config
JACK_CFLAGS C compiler flags for JACK, overriding pkg-config
JACK_LIBS linker flags for JACK, overriding pkg-config
- SAMPLERATE_CFLAGS
- C compiler flags for SAMPLERATE, overriding pkg-config
- SAMPLERATE_LIBS
- linker flags for SAMPLERATE, overriding pkg-config
SIDPLAYFP_CFLAGS
C compiler flags for SIDPLAYFP, overriding pkg-config
SIDPLAYFP_LIBS
@@ -1774,12 +1836,20 @@ Some influential environment variables:
FLAC_LIBS linker flags for FLAC, overriding pkg-config
BS2B_CFLAGS C compiler flags for BS2B, overriding pkg-config
BS2B_LIBS linker flags for BS2B, overriding pkg-config
+ SAMPLERATE_CFLAGS
+ C compiler flags for SAMPLERATE, overriding pkg-config
+ SAMPLERATE_LIBS
+ linker flags for SAMPLERATE, overriding pkg-config
SOXR_CFLAGS C compiler flags for SOXR, overriding pkg-config
SOXR_LIBS linker flags for SOXR, overriding pkg-config
GLIB214_CFLAGS
C compiler flags for GLIB214, overriding pkg-config
GLIB214_LIBS
linker flags for GLIB214, overriding pkg-config
+ QTOPENGL_CFLAGS
+ C compiler flags for QTOPENGL, overriding pkg-config
+ QTOPENGL_LIBS
+ linker flags for QTOPENGL, 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.
@@ -1847,14 +1917,14 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-audacious-plugins configure 3.5
+audacious-plugins configure 3.6.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
-(C) 2005-2014 Audacious Team
+Copyright (C) 2001-2015 Audacious developers and others
_ACEOF
exit
fi
@@ -2049,6 +2119,156 @@ $as_echo "$ac_res" >&6; }
} # ac_fn_c_check_header_compile
+# ac_fn_objc_try_compile LINENO
+# -----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_objc_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_objc_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_objc_try_compile
+
+# ac_fn_objc_try_cpp LINENO
+# -------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_objc_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_objc_preproc_warn_flag$ac_objc_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_objc_try_cpp
+
+# ac_fn_objcxx_try_compile LINENO
+# -------------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_objcxx_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_objcxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_objcxx_try_compile
+
+# ac_fn_objcxx_try_cpp LINENO
+# ---------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_objcxx_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_objcxx_preproc_warn_flag$ac_objcxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_objcxx_try_cpp
+
# ac_fn_c_try_link LINENO
# -----------------------
# Try to link conftest.$ac_ext, and return whether this succeeded.
@@ -2095,73 +2315,6 @@ fi
} # ac_fn_c_try_link
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $2 (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_func
-
# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists, giving a warning if it cannot be compiled using
@@ -2248,60 +2401,14 @@ fi
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_header_mongrel
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
-# ---------------------------------------------
-# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
-# accordingly.
-ac_fn_c_check_decl ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- as_decl_name=`echo $2|sed 's/ *(.*//'`
- as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
-$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
-if eval \${$3+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-#ifndef $as_decl_name
-#ifdef __cplusplus
- (void) $as_decl_use;
-#else
- (void) $as_decl_name;
-#endif
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_decl
-cat >config.log <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by audacious-plugins $as_me 3.5, which was
-generated by GNU Autoconf 2.69. Invocation command line was
-
- $ $0 $@
+It was created by audacious-plugins $as_me 3.6.1, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
_ACEOF
exec 5>>config.log
@@ -2693,6 +2800,116 @@ ac_config_headers="$ac_config_headers config.h"
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
+$as_echo_n "checking target system type... " >&6; }
+if ${ac_cv_target+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$target_alias" = x; then
+ ac_cv_target=$ac_cv_host
+else
+ ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
+$as_echo "$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -4561,116 +4778,7 @@ rm -rf conftest*
fi
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
- as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
-$as_echo_n "checking build system type... " >&6; }
-if ${ac_cv_build+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
- ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
- as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
-$as_echo "$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
-$as_echo_n "checking host system type... " >&6; }
-if ${ac_cv_host+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "x$host_alias" = x; then
- ac_cv_host=$ac_cv_build
-else
- ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
-$as_echo "$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
-esac
-host=$ac_cv_host
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_host
-shift
-host_cpu=$1
-host_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-host_os=$*
-IFS=$ac_save_IFS
-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
-$as_echo_n "checking target system type... " >&6; }
-if ${ac_cv_target+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "x$target_alias" = x; then
- ac_cv_target=$ac_cv_host
-else
- ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
-$as_echo "$ac_cv_target" >&6; }
-case $ac_cv_target in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
-esac
-target=$ac_cv_target
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_target
-shift
-target_cpu=$1
-target_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-target_os=$*
-IFS=$ac_save_IFS
-case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-test -n "$target_alias" &&
- test "$program_prefix$program_suffix$program_transform_name" = \
- NONENONEs,x,x, &&
- program_prefix=${target_alias}-
@@ -4797,29 +4905,71 @@ fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking operating system type" >&5
+$as_echo_n "checking operating system type... " >&6; }
-if test "x$GCC" = "xyes"; then
- CFLAGS="$CFLAGS -std=gnu99 -ffast-math -Wall -pipe"
- CXXFLAGS="$CXXFLAGS -Wall -pipe"
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C/C++ compiler supports -Wtype-limits" >&5
-$as_echo_n "checking whether the C/C++ compiler supports -Wtype-limits... " >&6; }
- OLDCFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -Wtype-limits -Werror"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+HAVE_LINUX=no
+HAVE_MSWINDOWS=no
+HAVE_DARWIN=no
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+case "$target" in
+ *linux*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Linux" >&5
+$as_echo "Linux" >&6; }
+ HAVE_LINUX=yes
+ ;;
+ *mingw*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Windows" >&5
+$as_echo "Windows" >&6; }
+ HAVE_MSWINDOWS=yes
+ ;;
+ *darwin*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Darwin" >&5
+$as_echo "Darwin" >&6; }
+ HAVE_DARWIN=yes
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: other UNIX" >&5
+$as_echo "other UNIX" >&6; }
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+if test "x$GCC" = "xyes"; then
+ CFLAGS="$CFLAGS -std=gnu99 -ffast-math -Wall -pipe"
+ if test "x$HAVE_DARWIN" = "xyes"; then
+ CXXFLAGS="$CXXFLAGS -stdlib=libc++ -std=gnu++11 -ffast-math -Wall -pipe"
+ LDFLAGS="$LDFLAGS -lc++ -stdlib=libc++"
+ else
+ CXXFLAGS="$CXXFLAGS -std=gnu++11 -ffast-math -Wall -pipe"
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C/C++ compiler supports -Wtype-limits" >&5
+$as_echo_n "checking whether the C/C++ compiler supports -Wtype-limits... " >&6; }
+ OLDCFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wtype-limits -Werror"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
CFLAGS="$OLDCFLAGS -Wtype-limits"
CXXFLAGS="$CXXFLAGS -Wtype-limits"
@@ -4831,47 +4981,1071 @@ $as_echo "no" >&6; }
CFLAGS="$OLDCFLAGS"
fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler supports -Woverloaded-virtual" >&5
+$as_echo_n "checking whether the C++ compiler supports -Woverloaded-virtual... " >&6; }
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ OLDCXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -Woverloaded-virtual -Werror"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CXXFLAGS="$OLDCXXFLAGS -Woverloaded-virtual"
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CXXFLAGS="$OLDCXXFLAGS"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+
+if test "x$HAVE_DARWIN" = "xyes"; then
+ ac_ext=m
+ac_cpp='$OBJCPP $CPPFLAGS'
+ac_compile='$OBJC -c $OBJCFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$OBJC -o conftest$ac_exeext $OBJCFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_objc_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in gcc objcc objc cc CC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJC"; then
+ ac_cv_prog_OBJC="$OBJC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJC=$ac_cv_prog_OBJC
+if test -n "$OBJC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJC" >&5
+$as_echo "$OBJC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$OBJC" && break
+ done
+fi
+if test -z "$OBJC"; then
+ ac_ct_OBJC=$OBJC
+ for ac_prog in gcc objcc objc cc CC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJC"; then
+ ac_cv_prog_ac_ct_OBJC="$ac_ct_OBJC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJC=$ac_cv_prog_ac_ct_OBJC
+if test -n "$ac_ct_OBJC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJC" >&5
+$as_echo "$ac_ct_OBJC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_OBJC" && break
+done
+
+ if test "x$ac_ct_OBJC" = x; then
+ OBJC="gcc"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJC=$ac_ct_OBJC
+ fi
+fi
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for Objective C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C compiler" >&5
+$as_echo_n "checking whether we are using the GNU Objective C compiler... " >&6; }
+if ${ac_cv_objc_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_objc_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_objc_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objc_compiler_gnu" >&5
+$as_echo "$ac_cv_objc_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GOBJC=yes
+else
+ GOBJC=
+fi
+ac_test_OBJCFLAGS=${OBJCFLAGS+set}
+ac_save_OBJCFLAGS=$OBJCFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJC accepts -g" >&5
+$as_echo_n "checking whether $OBJC accepts -g... " >&6; }
+if ${ac_cv_prog_objc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_objc_werror_flag=$ac_objc_werror_flag
+ ac_objc_werror_flag=yes
+ ac_cv_prog_objc_g=no
+ OBJCFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_objc_try_compile "$LINENO"; then :
+ ac_cv_prog_objc_g=yes
+else
+ OBJCFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_objc_try_compile "$LINENO"; then :
+
+else
+ ac_objc_werror_flag=$ac_save_objc_werror_flag
+ OBJCFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_objc_try_compile "$LINENO"; then :
+ ac_cv_prog_objc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_objc_werror_flag=$ac_save_objc_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_objc_g" >&5
+$as_echo "$ac_cv_prog_objc_g" >&6; }
+if test "$ac_test_OBJCFLAGS" = set; then
+ OBJCFLAGS=$ac_save_OBJCFLAGS
+elif test $ac_cv_prog_objc_g = yes; then
+ if test "$GOBJC" = yes; then
+ OBJCFLAGS="-g -O2"
+ else
+ OBJCFLAGS="-g"
+ fi
+else
+ if test "$GOBJC" = yes; then
+ OBJCFLAGS="-O2"
+ else
+ OBJCFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ ac_ext=m
+ac_cpp='$OBJCPP $CPPFLAGS'
+ac_compile='$OBJC -c $OBJCFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$OBJC -o conftest$ac_exeext $OBJCFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_objc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the Objective C preprocessor" >&5
+$as_echo_n "checking how to run the Objective C preprocessor... " >&6; }
+if test -z "$OBJCPP"; then
+ if ${ac_cv_prog_OBJCPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because OBJCPP needs to be expanded
+ for OBJCPP in "$OBJC -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_objc_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_objc_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_objc_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_OBJCPP=$OBJCPP
+
+fi
+ OBJCPP=$ac_cv_prog_OBJCPP
+else
+ ac_cv_prog_OBJCPP=$OBJCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJCPP" >&5
+$as_echo "$OBJCPP" >&6; }
+ac_preproc_ok=false
+for ac_objc_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_objc_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_objc_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Objective C preprocessor \"$OBJCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ ac_ext=mm
+ac_cpp='$OBJCXXCPP $CPPFLAGS'
+ac_compile='$OBJCXX -c $OBJCXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$OBJCXX -o conftest$ac_exeext $OBJCXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_objcxx_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ objc++ objcxx c++ CXX
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJCXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJCXX"; then
+ ac_cv_prog_OBJCXX="$OBJCXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJCXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJCXX=$ac_cv_prog_OBJCXX
+if test -n "$OBJCXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJCXX" >&5
+$as_echo "$OBJCXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$OBJCXX" && break
+ done
+fi
+if test -z "$OBJCXX"; then
+ ac_ct_OBJCXX=$OBJCXX
+ for ac_prog in g++ objc++ objcxx c++ CXX
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJCXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJCXX"; then
+ ac_cv_prog_ac_ct_OBJCXX="$ac_ct_OBJCXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJCXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJCXX=$ac_cv_prog_ac_ct_OBJCXX
+if test -n "$ac_ct_OBJCXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJCXX" >&5
+$as_echo "$ac_ct_OBJCXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_OBJCXX" && break
+done
+
+ if test "x$ac_ct_OBJCXX" = x; then
+ OBJCXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJCXX=$ac_ct_OBJCXX
+ fi
+fi
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for Objective C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU Objective C++ compiler... " >&6; }
+if ${ac_cv_objcxx_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_objcxx_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_objcxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objcxx_compiler_gnu" >&5
+$as_echo "$ac_cv_objcxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GOBJCXX=yes
+else
+ GOBJCXX=
+fi
+ac_test_OBJCXXFLAGS=${OBJCXXFLAGS+set}
+ac_save_OBJCXXFLAGS=$OBJCXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJCXX accepts -g" >&5
+$as_echo_n "checking whether $OBJCXX accepts -g... " >&6; }
+if ${ac_cv_prog_objcxx_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_objcxx_werror_flag=$ac_objcxx_werror_flag
+ ac_objcxx_werror_flag=yes
+ ac_cv_prog_objcxx_g=no
+ OBJCXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_objcxx_try_compile "$LINENO"; then :
+ ac_cv_prog_objcxx_g=yes
+else
+ OBJCXXFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_objcxx_try_compile "$LINENO"; then :
+
+else
+ ac_objcxx_werror_flag=$ac_save_objcxx_werror_flag
+ OBJCXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_objcxx_try_compile "$LINENO"; then :
+ ac_cv_prog_objcxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_objcxx_werror_flag=$ac_save_objcx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_objcxx_g" >&5
+$as_echo "$ac_cv_prog_objcxx_g" >&6; }
+if test "$ac_test_OBJCXXFLAGS" = set; then
+ OBJCXXFLAGS=$ac_save_OBJCXXFLAGS
+elif test $ac_cv_prog_objcxx_g = yes; then
+ if test "$GOBJCXX" = yes; then
+ OBJCXXFLAGS="-g -O2"
+ else
+ OBJCXXFLAGS="-g"
+ fi
+else
+ if test "$GOBJCXX" = yes; then
+ OBJCXXFLAGS="-O2"
+ else
+ OBJCXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ ac_ext=mm
+ac_cpp='$OBJCXXCPP $CPPFLAGS'
+ac_compile='$OBJCXX -c $OBJCXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$OBJCXX -o conftest$ac_exeext $OBJCXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_objcxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the Objective C++ preprocessor" >&5
+$as_echo_n "checking how to run the Objective C++ preprocessor... " >&6; }
+if test -z "$OBJCXXCPP"; then
+ if ${ac_cv_prog_OBJCXXCPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because OBJCXXCPP needs to be expanded
+ for OBJCXXCPP in "$OBJCXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_objcxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_objcxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_objcxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_OBJCXXCPP=$OBJCXXCPP
+
+fi
+ OBJCXXCPP=$ac_cv_prog_OBJCXXCPP
+else
+ ac_cv_prog_OBJCXXCPP=$OBJCXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJCXXCPP" >&5
+$as_echo "$OBJCXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_objcxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_objcxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_objcxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Objective C++ preprocessor \"$OBJCXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ OBJCXXFLAGS="$OBJCXXFLAGS -stdlib=libc++ -std=c++11"
+fi
+
+if test $HAVE_LINUX = yes ; then
+ LDFLAGS="$LDFLAGS -Wl,-z,defs"
+fi
+
+if test $HAVE_MSWINDOWS = yes ; then
+ CFLAGS="$CFLAGS -march=i686"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ BIGENDIAN=1;; #(
+ no)
+ BIGENDIAN=0 ;; #(
+ universal)
+ as_fn_error $? "Universal builds are not supported, sorry" "$LINENO" 5
+ ;; #(
+ *)
+ as_fn_error $? "Unknown machine byte order" "$LINENO" 5 ;;
+ esac
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking operating system type" >&5
-$as_echo_n "checking operating system type... " >&6; }
-
-HAVE_LINUX=no
-HAVE_MSWINDOWS=no
-
-case "$target" in
- *linux*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: Linux" >&5
-$as_echo "Linux" >&6; }
- HAVE_LINUX=yes
- ;;
- *mingw*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: Windows" >&5
-$as_echo "Windows" >&6; }
- HAVE_MSWINDOWS=yes
- ;;
- *)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: other UNIX" >&5
-$as_echo "other UNIX" >&6; }
- ;;
-esac
-
-
-
-
-if test $HAVE_LINUX = yes ; then
- LDFLAGS="$LDFLAGS -Wl,-z,defs"
+if test "x$HAVE_MSWINDOWS" = "xyes" ; then
+ EXPORT="__declspec(dllexport)"
+elif test "x$GCC" = "xyes" ; then
+ CFLAGS="$CFLAGS -fvisibility=hidden"
+ CXXFLAGS="$CXXFLAGS -fvisibility=hidden"
+ EXPORT="__attribute__((visibility(\"default\")))"
+else
+ as_fn_error $? "Unknown syntax for EXPORT keyword" "$LINENO" 5
fi
-if test $HAVE_MSWINDOWS = yes ; then
- CFLAGS="$CFLAGS -march=i686"
-fi
+cat >>confdefs.h <<_ACEOF
+#define EXPORT $EXPORT
+_ACEOF
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
$as_echo_n "checking whether ln -s works... " >&6; }
@@ -5366,6 +6540,17 @@ $as_echo "yes" >&6; }
fi
+
+# Check whether --enable-gtk was given.
+if test "${enable_gtk+set}" = set; then :
+ enableval=$enable_gtk; USE_GTK=$enableval
+else
+ USE_GTK=yes
+fi
+
+
+if test $USE_GTK = yes ; then
+
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK" >&5
$as_echo_n "checking for GTK... " >&6; }
@@ -5374,12 +6559,12 @@ if test -n "$GTK_CFLAGS"; then
pkg_cv_GTK_CFLAGS="$GTK_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-3.0 >= 3.4\""; } >&5
- ($PKG_CONFIG --exists --print-errors "gtk+-3.0 >= 3.4") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.24\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.24") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_GTK_CFLAGS=`$PKG_CONFIG --cflags "gtk+-3.0 >= 3.4" 2>/dev/null`
+ pkg_cv_GTK_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0 >= 2.24" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -5391,12 +6576,12 @@ if test -n "$GTK_LIBS"; then
pkg_cv_GTK_LIBS="$GTK_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-3.0 >= 3.4\""; } >&5
- ($PKG_CONFIG --exists --print-errors "gtk+-3.0 >= 3.4") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.24\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.24") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_GTK_LIBS=`$PKG_CONFIG --libs "gtk+-3.0 >= 3.4" 2>/dev/null`
+ pkg_cv_GTK_LIBS=`$PKG_CONFIG --libs "gtk+-2.0 >= 2.24" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -5417,14 +6602,14 @@ else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
- GTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-3.0 >= 3.4" 2>&1`
+ GTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-2.0 >= 2.24" 2>&1`
else
- GTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-3.0 >= 3.4" 2>&1`
+ GTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-2.0 >= 2.24" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$GTK_PKG_ERRORS" >&5
- as_fn_error $? "Package requirements (gtk+-3.0 >= 3.4) were not met:
+ as_fn_error $? "Package requirements (gtk+-2.0 >= 2.24) were not met:
$GTK_PKG_ERRORS
@@ -5457,6 +6642,12 @@ $as_echo "yes" >&6; }
fi
+$as_echo "#define USE_GTK 1" >>confdefs.h
+
+fi
+
+
+
if test $HAVE_MSWINDOWS = yes ; then
pkg_failed=no
@@ -5653,6 +6844,119 @@ fi
+# Check whether --enable-qt was given.
+if test "${enable_qt+set}" = set; then :
+ enableval=$enable_qt; USE_QT=$enableval
+else
+ USE_QT=no
+fi
+
+
+if test $USE_QT = yes ; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for QT" >&5
+$as_echo_n "checking for QT... " >&6; }
+
+if test -n "$QT_CFLAGS"; then
+ pkg_cv_QT_CFLAGS="$QT_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Core Qt5Gui Qt5Widgets\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "Qt5Core Qt5Gui Qt5Widgets") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_QT_CFLAGS=`$PKG_CONFIG --cflags "Qt5Core Qt5Gui Qt5Widgets" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$QT_LIBS"; then
+ pkg_cv_QT_LIBS="$QT_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Core Qt5Gui Qt5Widgets\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "Qt5Core Qt5Gui Qt5Widgets") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_QT_LIBS=`$PKG_CONFIG --libs "Qt5Core Qt5Gui Qt5Widgets" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ QT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "Qt5Core Qt5Gui Qt5Widgets" 2>&1`
+ else
+ QT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "Qt5Core Qt5Gui Qt5Widgets" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$QT_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (Qt5Core Qt5Gui Qt5Widgets) were not met:
+
+$QT_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables QT_CFLAGS
+and QT_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables QT_CFLAGS
+and QT_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ QT_CFLAGS=$pkg_cv_QT_CFLAGS
+ QT_LIBS=$pkg_cv_QT_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+$as_echo "#define USE_QT 1" >>confdefs.h
+
+
+ # needed if Qt was built with -reduce-relocations
+ QT_CFLAGS="$QT_CFLAGS -fPIC"
+fi
+
+
+
+
+
+
@@ -5662,15 +6966,15 @@ $as_echo_n "checking for shared library system... " >&6; }
darwin*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Darwin" >&5
$as_echo "Darwin" >&6; }
- LIB_CFLAGS='-fPIC -DPIC'
- LIB_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}'
+ LIB_CFLAGS='-fPIC -DPIC -mmacosx-version-min=10.7'
+ LIB_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR} -mmacosx-version-min=10.7 -install_name "${libdir}/$$(i=${SHARED_LIB}; echo $${i%${LIB_SUFFIX}}).${LIB_MAJOR}${LIB_SUFFIX}"'
LIB_PREFIX='lib'
LIB_SUFFIX='.dylib'
LDFLAGS_RPATH='-Wl,-rpath,${libdir}'
- PLUGIN_CFLAGS='-fPIC -DPIC'
- PLUGIN_LDFLAGS='-bundle -undefined dynamic_lookup'
+ PLUGIN_CFLAGS='-fPIC -DPIC -mmacosx-version-min=10.7'
+ PLUGIN_LDFLAGS='-bundle -undefined dynamic_lookup -mmacosx-version-min=10.7'
PLUGIN_SUFFIX='.bundle'
- INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && install_name_tool -id ${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$$i'
+ INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$$i'
UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib'
CLEAN_LIB=''
;;
@@ -5749,18 +7053,6 @@ $as_echo "GNU" >&6; }
-for ac_func in mkdtemp
-do :
- ac_fn_c_check_func "$LINENO" "mkdtemp" "ac_cv_func_mkdtemp"
-if test "x$ac_cv_func_mkdtemp" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_MKDTEMP 1
-_ACEOF
-
-fi
-done
-
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
set x ${MAKE-make}
@@ -6012,7 +7304,7 @@ $as_echo "$USE_NLS" >&6; }
- GETTEXT_MACRO_VERSION=0.18
+ GETTEXT_MACRO_VERSION=0.19
@@ -7263,36 +8555,42 @@ else
if test $am_cv_lib_iconv = yes; then
LIBS="$LIBS $LIBICONV"
fi
- if test "$cross_compiling" = yes; then :
-
- case "$host_os" in
- aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
- *) am_cv_func_iconv_works="guessing yes" ;;
- esac
-
+ am_cv_func_iconv_works=no
+ for ac_iconv_const in '' 'const'; do
+ if test "$cross_compiling" = yes; then :
+ case "$host_os" in
+ aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+ *) am_cv_func_iconv_works="guessing yes" ;;
+ esac
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <iconv.h>
#include <string.h>
-int main ()
+
+#ifndef ICONV_CONST
+# define ICONV_CONST $ac_iconv_const
+#endif
+
+int
+main ()
{
- int result = 0;
+int result = 0;
/* Test against AIX 5.1 bug: Failures are not distinguishable from successful
returns. */
{
iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
if (cd_utf8_to_88591 != (iconv_t)(-1))
{
- static const char input[] = "\342\202\254"; /* EURO SIGN */
+ static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */
char buf[10];
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_utf8_to_88591,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 1;
@@ -7305,14 +8603,14 @@ int main ()
iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
if (cd_ascii_to_88591 != (iconv_t)(-1))
{
- static const char input[] = "\263";
+ static ICONV_CONST char input[] = "\263";
char buf[10];
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_ascii_to_88591,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 2;
@@ -7324,14 +8622,14 @@ int main ()
iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
- static const char input[] = "\304";
+ static ICONV_CONST char input[] = "\304";
static char buf[2] = { (char)0xDE, (char)0xAD };
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = 1;
char *outptr = buf;
size_t outbytesleft = 1;
size_t res = iconv (cd_88591_to_utf8,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
result |= 4;
@@ -7344,14 +8642,14 @@ int main ()
iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
- static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
char buf[50];
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_88591_to_utf8,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if ((int)res > 0)
result |= 8;
@@ -7371,17 +8669,20 @@ int main ()
&& iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
result |= 16;
return result;
+
+ ;
+ return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
am_cv_func_iconv_works=yes
-else
- am_cv_func_iconv_works=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
+ test "$am_cv_func_iconv_works" = no || break
+ done
LIBS="$am_save_LIBS"
fi
@@ -8075,12 +9376,12 @@ if test -n "$AUDACIOUS_CFLAGS"; then
pkg_cv_AUDACIOUS_CFLAGS="$AUDACIOUS_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"audacious >= 3.5\""; } >&5
- ($PKG_CONFIG --exists --print-errors "audacious >= 3.5") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"audacious >= 3.6\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "audacious >= 3.6") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_AUDACIOUS_CFLAGS=`$PKG_CONFIG --cflags "audacious >= 3.5" 2>/dev/null`
+ pkg_cv_AUDACIOUS_CFLAGS=`$PKG_CONFIG --cflags "audacious >= 3.6" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -8092,12 +9393,12 @@ if test -n "$AUDACIOUS_LIBS"; then
pkg_cv_AUDACIOUS_LIBS="$AUDACIOUS_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"audacious >= 3.5\""; } >&5
- ($PKG_CONFIG --exists --print-errors "audacious >= 3.5") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"audacious >= 3.6\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "audacious >= 3.6") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_AUDACIOUS_LIBS=`$PKG_CONFIG --libs "audacious >= 3.5" 2>/dev/null`
+ pkg_cv_AUDACIOUS_LIBS=`$PKG_CONFIG --libs "audacious >= 3.6" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -8118,32 +9419,141 @@ else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
- AUDACIOUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "audacious >= 3.5" 2>&1`
+ AUDACIOUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "audacious >= 3.6" 2>&1`
else
- AUDACIOUS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "audacious >= 3.5" 2>&1`
+ AUDACIOUS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "audacious >= 3.6" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$AUDACIOUS_PKG_ERRORS" >&5
- as_fn_error $? "Cannot find Audacious 3.5; have you installed Audacious yet?" "$LINENO" 5
+ as_fn_error $? "Cannot find Audacious 3.6; have you installed Audacious yet?" "$LINENO" 5
+
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "Cannot find Audacious 3.6; have you installed Audacious yet?" "$LINENO" 5
+
+else
+ AUDACIOUS_CFLAGS=$pkg_cv_AUDACIOUS_CFLAGS
+ AUDACIOUS_LIBS=$pkg_cv_AUDACIOUS_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+CPPFLAGS="$CPPFLAGS $AUDACIOUS_CFLAGS"
+LIBS="$LIBS $AUDACIOUS_LIBS"
+
+
+if test $HAVE_DARWIN = yes ; then
+
+# Check whether --with-system-libxml2 was given.
+if test "${with_system_libxml2+set}" = set; then :
+ withval=$with_system_libxml2; with_system_libxml2=$withval
+else
+ with_system_libxml2=yes
+fi
+
+
+ if test $with_system_libxml2 = yes ; then
+ XML_LIBS="-lxml2"
+ XML_CFLAGS="-I/usr/include/libxml2"
+
+
+ else
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML" >&5
+$as_echo_n "checking for XML... " >&6; }
+
+if test -n "$XML_CFLAGS"; then
+ pkg_cv_XML_CFLAGS="$XML_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxml-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libxml-2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_XML_CFLAGS=`$PKG_CONFIG --cflags "libxml-2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$XML_LIBS"; then
+ pkg_cv_XML_LIBS="$XML_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxml-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libxml-2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_XML_LIBS=`$PKG_CONFIG --libs "libxml-2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ XML_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libxml-2.0" 2>&1`
+ else
+ XML_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libxml-2.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$XML_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (libxml-2.0) were not met:
+
+$XML_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+Alternatively, you may set the environment variables XML_CFLAGS
+and XML_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- as_fn_error $? "Cannot find Audacious 3.5; have you installed Audacious yet?" "$LINENO" 5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables XML_CFLAGS
+and XML_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
else
- AUDACIOUS_CFLAGS=$pkg_cv_AUDACIOUS_CFLAGS
- AUDACIOUS_LIBS=$pkg_cv_AUDACIOUS_LIBS
+ XML_CFLAGS=$pkg_cv_XML_CFLAGS
+ XML_LIBS=$pkg_cv_XML_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
fi
-
-CPPFLAGS="$CPPFLAGS $AUDACIOUS_CFLAGS"
-LIBS="$LIBS $AUDACIOUS_LIBS"
-
-
+ fi
+else
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML" >&5
@@ -8235,16 +9645,27 @@ else
$as_echo "yes" >&6; }
fi
+fi
-INPUT_PLUGINS="tonegen metronom vtx"
+INPUT_PLUGINS="tonegen metronom"
OUTPUT_PLUGINS=""
-EFFECT_PLUGINS="compressor crossfade crystalizer ladspa mixer stereo_plugin voice_removal echo_plugin"
-GENERAL_PLUGINS="alarm albumart delete-files search-tool"
-VISUALIZATION_PLUGINS="blur_scope cairo-spectrum"
+EFFECT_PLUGINS="compressor crossfade crystalizer mixer silence-removal stereo_plugin voice_removal echo_plugin"
+GENERAL_PLUGINS=""
+VISUALIZATION_PLUGINS=""
CONTAINER_PLUGINS="asx asx3 audpl m3u pls xspf"
TRANSPORT_PLUGINS="gio"
+if test "x$USE_GTK" = "xyes" ; then
+ GENERAL_PLUGINS="$GENERAL_PLUGINS alarm albumart delete-files playlist-manager search-tool statusicon"
+ GENERAL_PLUGINS="$GENERAL_PLUGINS gtkui skins"
+fi
+
+if test "x$USE_QT" = "xyes" ; then
+ GENERAL_PLUGINS="$GENERAL_PLUGINS albumart-qt lyricwiki-qt song-info-qt"
+ GENERAL_PLUGINS="$GENERAL_PLUGINS qtui"
+fi
+
# Check whether --enable-console was given.
if test "${enable_console+set}" = set; then :
@@ -8290,6 +9711,116 @@ if test "x$enable_xsf" != "xno"; then
fi
+# Check whether --enable-qtaudio was given.
+if test "${enable_qtaudio+set}" = set; then :
+ enableval=$enable_qtaudio; enable_qtaudio=$enableval
+else
+ enable_qtaudio=auto
+fi
+
+
+have_qtaudio=no
+if test "x$enable_qtaudio" = "xyes" -o \( "x$USE_QT" = "xyes" -a "x$enable_qtaudio" = "xauto" \); then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for QTMULTIMEDIA" >&5
+$as_echo_n "checking for QTMULTIMEDIA... " >&6; }
+
+if test -n "$QTMULTIMEDIA_CFLAGS"; then
+ pkg_cv_QTMULTIMEDIA_CFLAGS="$QTMULTIMEDIA_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Multimedia\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "Qt5Multimedia") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_QTMULTIMEDIA_CFLAGS=`$PKG_CONFIG --cflags "Qt5Multimedia" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$QTMULTIMEDIA_LIBS"; then
+ pkg_cv_QTMULTIMEDIA_LIBS="$QTMULTIMEDIA_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Multimedia\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "Qt5Multimedia") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_QTMULTIMEDIA_LIBS=`$PKG_CONFIG --libs "Qt5Multimedia" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ QTMULTIMEDIA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "Qt5Multimedia" 2>&1`
+ else
+ QTMULTIMEDIA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "Qt5Multimedia" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$QTMULTIMEDIA_PKG_ERRORS" >&5
+
+ have_qtaudio=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_qtaudio=no
+else
+ QTMULTIMEDIA_CFLAGS=$pkg_cv_QTMULTIMEDIA_CFLAGS
+ QTMULTIMEDIA_LIBS=$pkg_cv_QTMULTIMEDIA_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_qtaudio=yes
+fi
+ if test "x$have_qtaudio" = "xyes"; then
+ QTMULTIMEDIA_CFLAGS="$QTMULTIMEDIA_CFLAGS -fPIC"
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS qtaudio"
+ elif test "x$enable_qtaudio" = "xyes"; then
+ as_fn_error $? "QtAudio output plugin requested but QtMultimedia not found!" "$LINENO" 5
+ fi
+fi
+
+
+# Check whether --enable-coreaudio was given.
+if test "${enable_coreaudio+set}" = set; then :
+ enableval=$enable_coreaudio; enable_coreaudio=$enableval
+else
+ enable_coreaudio=auto
+
+fi
+
+
+have_coreaudio=no
+if test "x$enable_coreaudio" != "xno"; then
+ if test "x$HAVE_DARWIN" != "xno"; then
+ have_coreaudio=yes
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS coreaudio"
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: *** CoreAudio output plugin disabled per user request ***" >&5
+$as_echo "*** CoreAudio output plugin disabled per user request ***" >&6; }
+fi
+
# Check whether --enable-pulse was given.
if test "${enable_pulse+set}" = set; then :
@@ -8403,12 +9934,11 @@ fi
if test "${enable_mp3+set}" = set; then :
enableval=$enable_mp3; enable_mp3=$enableval
else
- enable_mp3=auto
+ enable_mp3=yes
fi
-have_mp3=no
-if test "x$enable_mp3" != "xno"; then
+if test $enable_mp3 = yes ; then
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MPG123" >&5
@@ -8468,28 +9998,39 @@ fi
# Put the nasty error message in config.log where it belongs
echo "$MPG123_PKG_ERRORS" >&5
- if test "x$enable_mp3" = "xyes"; then
- as_fn_error $? "Cannot find libmpg123 development files (ver >= 1.12), but compilation of MP3 plugin has been explicitly requested; please install libmpg123 dev files and run configure again" "$LINENO" 5
- fi
+ as_fn_error $? "Package requirements (libmpg123 >= 1.12) were not met:
+
+$MPG123_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+Alternatively, you may set the environment variables MPG123_CFLAGS
+and MPG123_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- if test "x$enable_mp3" = "xyes"; then
- as_fn_error $? "Cannot find libmpg123 development files (ver >= 1.12), but compilation of MP3 plugin has been explicitly requested; please install libmpg123 dev files and run configure again" "$LINENO" 5
- fi
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+Alternatively, you may set the environment variables MPG123_CFLAGS
+and MPG123_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
else
MPG123_CFLAGS=$pkg_cv_MPG123_CFLAGS
MPG123_LIBS=$pkg_cv_MPG123_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- have_mp3=yes
- INPUT_PLUGINS="$INPUT_PLUGINS mpg123"
+
fi
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: *** libmpg123 not found; MP3 plugin disabled" >&5
-$as_echo "*** libmpg123 not found; MP3 plugin disabled" >&6; }
+ INPUT_PLUGINS="$INPUT_PLUGINS mpg123"
fi
@@ -8513,12 +10054,12 @@ if test -n "$GDKX11_CFLAGS"; then
pkg_cv_GDKX11_CFLAGS="$GDKX11_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gdk-x11-3.0\""; } >&5
- ($PKG_CONFIG --exists --print-errors "gdk-x11-3.0") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gdk-x11-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gdk-x11-2.0") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_GDKX11_CFLAGS=`$PKG_CONFIG --cflags "gdk-x11-3.0" 2>/dev/null`
+ pkg_cv_GDKX11_CFLAGS=`$PKG_CONFIG --cflags "gdk-x11-2.0" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -8530,12 +10071,12 @@ if test -n "$GDKX11_LIBS"; then
pkg_cv_GDKX11_LIBS="$GDKX11_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gdk-x11-3.0\""; } >&5
- ($PKG_CONFIG --exists --print-errors "gdk-x11-3.0") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gdk-x11-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gdk-x11-2.0") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_GDKX11_LIBS=`$PKG_CONFIG --libs "gdk-x11-3.0" 2>/dev/null`
+ pkg_cv_GDKX11_LIBS=`$PKG_CONFIG --libs "gdk-x11-2.0" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -8556,22 +10097,22 @@ else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
- GDKX11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gdk-x11-3.0" 2>&1`
+ GDKX11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gdk-x11-2.0" 2>&1`
else
- GDKX11_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gdk-x11-3.0" 2>&1`
+ GDKX11_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gdk-x11-2.0" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$GDKX11_PKG_ERRORS" >&5
if test "x$enable_hotkey" = "xyes"; then
- as_fn_error $? "Cannot find gdk-x11-3.0 development files, but compilation of X11 Global Hotkey plugin has been explicitly requested; please install gdk-x11-3.0 dev files and run configure again" "$LINENO" 5
+ as_fn_error $? "Cannot find gdk-x11-2.0 development files, but compilation of X11 Global Hotkey plugin has been explicitly requested; please install gdk-x11-2.0 dev files and run configure again" "$LINENO" 5
fi
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if test "x$enable_hotkey" = "xyes"; then
- as_fn_error $? "Cannot find gdk-x11-3.0 development files, but compilation of X11 Global Hotkey plugin has been explicitly requested; please install gdk-x11-3.0 dev files and run configure again" "$LINENO" 5
+ as_fn_error $? "Cannot find gdk-x11-2.0 development files, but compilation of X11 Global Hotkey plugin has been explicitly requested; please install gdk-x11-2.0 dev files and run configure again" "$LINENO" 5
fi
else
@@ -8744,19 +10285,6 @@ done
fi
-# Check whether --enable-statusicon was given.
-if test "${enable_statusicon+set}" = set; then :
- enableval=$enable_statusicon; have_statusicon=$enableval
-else
- have_statusicon="yes"
-fi
-
-
-if test "x$have_statusicon" != "xno"; then
- GENERAL_PLUGINS="$GENERAL_PLUGINS statusicon"
-fi
-
-
# Check whether --enable-aosd was given.
if test "${enable_aosd+set}" = set; then :
enableval=$enable_aosd; enable_aosd=$enableval
@@ -9202,16 +10730,16 @@ $as_echo "*** AdPlug plugin disabled per user request ***" >&6; }
fi
+
# Check whether --enable-vorbis was given.
if test "${enable_vorbis+set}" = set; then :
enableval=$enable_vorbis; enable_vorbis=$enableval
else
- enable_vorbis=auto
+ enable_vorbis=yes
fi
-have_vorbis=no
-if test "x$enable_vorbis" != "xno"; then
+if test $enable_vorbis = yes ; then
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VORBIS" >&5
@@ -9271,25 +10799,39 @@ fi
# Put the nasty error message in config.log where it belongs
echo "$VORBIS_PKG_ERRORS" >&5
- if test "x$enable_vorbis" = "xyes"; then
- as_fn_error $? "Cannot find ogg, vorbis, vorbisenc or vorbisfile development files (ver >= 1.0), but compilation of Ogg Vorbis decoding and encoding has been explicitly requested; please install ogg, vorbis, vorbisenc and vorbisfile dev files and run configure again" "$LINENO" 5
- fi
+ as_fn_error $? "Package requirements (ogg >= 1.0 vorbis >= 1.0 vorbisenc >= 1.0 vorbisfile >= 1.0) were not met:
+
+$VORBIS_PKG_ERRORS
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables VORBIS_CFLAGS
+and VORBIS_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- if test "x$enable_vorbis" = "xyes"; then
- as_fn_error $? "Cannot find ogg, vorbis, vorbisenc or vorbisfile development files (ver >= 1.0), but compilation of Ogg Vorbis decoding and encoding has been explicitly requested; please install ogg, vorbis, vorbisenc and vorbisfile dev files and run configure again" "$LINENO" 5
- fi
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables VORBIS_CFLAGS
+and VORBIS_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
else
VORBIS_CFLAGS=$pkg_cv_VORBIS_CFLAGS
VORBIS_LIBS=$pkg_cv_VORBIS_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- have_vorbis=yes
- INPUT_PLUGINS="$INPUT_PLUGINS vorbis"
+
fi
+ INPUT_PLUGINS="$INPUT_PLUGINS vorbis"
fi
@@ -9297,13 +10839,11 @@ fi
if test "${enable_flacng+set}" = set; then :
enableval=$enable_flacng; enable_flacng=$enableval
else
- enable_flacng=auto
-
+ enable_flacng=yes
fi
-have_flacng=no
-if test "x$enable_flacng" != "xno"; then
+if test $enable_flacng = yes ; then
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBFLAC" >&5
@@ -9363,28 +10903,39 @@ fi
# Put the nasty error message in config.log where it belongs
echo "$LIBFLAC_PKG_ERRORS" >&5
- if test "x$enable_flacng" = "xyes"; then
- as_fn_error $? "Cannot find libFLAC development files (ver >= 1.2.1), but compilation of FLACng plugin has been explicitly requested; please install libFLAC dev files and run configure again" "$LINENO" 5
- fi
+ as_fn_error $? "Package requirements (flac >= 1.2.1) were not met:
+
+$LIBFLAC_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+Alternatively, you may set the environment variables LIBFLAC_CFLAGS
+and LIBFLAC_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- if test "x$enable_flacng" = "xyes"; then
- as_fn_error $? "Cannot find libFLAC development files (ver >= 1.2.1), but compilation of FLACng plugin has been explicitly requested; please install libFLAC dev files and run configure again" "$LINENO" 5
- fi
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+Alternatively, you may set the environment variables LIBFLAC_CFLAGS
+and LIBFLAC_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
else
LIBFLAC_CFLAGS=$pkg_cv_LIBFLAC_CFLAGS
LIBFLAC_LIBS=$pkg_cv_LIBFLAC_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- have_flacng=yes
- INPUT_PLUGINS="$INPUT_PLUGINS flacng"
+
fi
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: *** FLACng plugin disabled per user request ***" >&5
-$as_echo "*** FLACng plugin disabled per user request ***" >&6; }
+ INPUT_PLUGINS="$INPUT_PLUGINS flacng"
fi
@@ -9487,25 +11038,20 @@ fi
if test "${enable_aac+set}" = set; then :
enableval=$enable_aac; enable_aac=$enableval
else
- enable_aac=auto
-
+ enable_aac=yes
fi
-have_aac=no
-if test "x$enable_aac" != "xno"; then
- FAAD_LIBS="-lfaad"
- FAAD_CFLAGS=
+if test $enable_aac = yes ; then
+ ac_fn_c_check_header_mongrel "$LINENO" "neaacdec.h" "ac_cv_header_neaacdec_h" "$ac_includes_default"
+if test "x$ac_cv_header_neaacdec_h" = xyes; then :
+ have_aac=yes
+else
+ have_aac=no
+fi
- ac_fn_c_check_header_mongrel "$LINENO" "faad.h" "ac_cv_header_faad_h" "$ac_includes_default"
-if test "x$ac_cv_header_faad_h" = xyes; then :
- ac_fn_c_check_decl "$LINENO" "FAAD2_VERSION" "ac_cv_have_decl_FAAD2_VERSION" "#include <neaacdec.h>
-"
-if test "x$ac_cv_have_decl_FAAD2_VERSION" = xyes; then :
- ac_fn_c_check_decl "$LINENO" "NeAACDecInit2" "ac_cv_have_decl_NeAACDecInit2" "#include <neaacdec.h>
-"
-if test "x$ac_cv_have_decl_NeAACDecInit2" = xyes; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NeAACDecInit2 in -lfaad" >&5
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NeAACDecInit2 in -lfaad" >&5
$as_echo_n "checking for NeAACDecInit2 in -lfaad... " >&6; }
if ${ac_cv_lib_faad_NeAACDecInit2+:} false; then :
$as_echo_n "(cached) " >&6
@@ -9542,24 +11088,22 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_faad_NeAACDecInit2" >&5
$as_echo "$ac_cv_lib_faad_NeAACDecInit2" >&6; }
if test "x$ac_cv_lib_faad_NeAACDecInit2" = xyes; then :
- have_aac=yes
-
-
- INPUT_PLUGINS="$INPUT_PLUGINS aac aac-raw"
-fi
-
+ have_aac=$have_aac
+else
+ have_aac=no
fi
-fi
+ if test $have_aac != yes ; then
+ as_fn_error $? "Please install libfaad, or use --disable-aac to disable AAC support." "$LINENO" 5
+ fi
-fi
+ FAAD_CFLAGS=
+ FAAD_LIBS="-lfaad"
- if test "x$enable_aac" = "xyes" -a "x$have_aac" != "xyes"; then
- as_fn_error $? "Cannot find faad development files, but compilation of aac plugin has been explicitly requested; please install faad dev files and run configure again" "$LINENO" 5
- fi
+ INPUT_PLUGINS="$INPUT_PLUGINS aac-raw"
fi
@@ -9744,23 +11288,97 @@ else
MODPLUG_LIBS=$pkg_cv_MODPLUG_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- INPUT_PLUGINS="$INPUT_PLUGINS modplug"
- have_modplug=yes
-fi
-fi
-
+ INPUT_PLUGINS="$INPUT_PLUGINS modplug"
+ have_modplug=yes
+fi
+fi
+
+
+
+# Check whether --with-ffmpeg was given.
+if test "${with_ffmpeg+set}" = set; then :
+ withval=$with_ffmpeg; ffmpeg_variant=$withval
+else
+ ffmpeg_variant=ffmpeg
+fi
+
+
+if test $ffmpeg_variant = ffmpeg ; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FFMPEG" >&5
+$as_echo_n "checking for FFMPEG... " >&6; }
+
+if test -n "$FFMPEG_CFLAGS"; then
+ pkg_cv_FFMPEG_CFLAGS="$FFMPEG_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libavcodec >= 53.40.0 libavformat >= 53.21.0 libavutil >= 51.27.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libavcodec >= 53.40.0 libavformat >= 53.21.0 libavutil >= 51.27.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_FFMPEG_CFLAGS=`$PKG_CONFIG --cflags "libavcodec >= 53.40.0 libavformat >= 53.21.0 libavutil >= 51.27.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$FFMPEG_LIBS"; then
+ pkg_cv_FFMPEG_LIBS="$FFMPEG_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libavcodec >= 53.40.0 libavformat >= 53.21.0 libavutil >= 51.27.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libavcodec >= 53.40.0 libavformat >= 53.21.0 libavutil >= 51.27.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_FFMPEG_LIBS=`$PKG_CONFIG --libs "libavcodec >= 53.40.0 libavformat >= 53.21.0 libavutil >= 51.27.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ FFMPEG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libavcodec >= 53.40.0 libavformat >= 53.21.0 libavutil >= 51.27.0" 2>&1`
+ else
+ FFMPEG_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libavcodec >= 53.40.0 libavformat >= 53.21.0 libavutil >= 51.27.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$FFMPEG_PKG_ERRORS" >&5
+
+ as_fn_error $? "FFmpeg is not installed or too old (required: libavcodec 53.40.0, libavformat 53.21.0, libavutil 51.27.0). Use --with-ffmpeg=none to disable the ffaudio plugin or --with-ffmpeg=libav to use libav instead." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "FFmpeg is not installed or too old (required: libavcodec 53.40.0, libavformat 53.21.0, libavutil 51.27.0). Use --with-ffmpeg=none to disable the ffaudio plugin or --with-ffmpeg=libav to use libav instead." "$LINENO" 5
+else
+ FFMPEG_CFLAGS=$pkg_cv_FFMPEG_CFLAGS
+ FFMPEG_LIBS=$pkg_cv_FFMPEG_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ INPUT_PLUGINS="$INPUT_PLUGINS ffaudio"
-# Check whether --enable-ffaudio was given.
-if test "${enable_ffaudio+set}" = set; then :
- enableval=$enable_ffaudio; enable_ffaudio=$enableval
-else
- enable_ffaudio=auto
+$as_echo "#define HAVE_FFMPEG 1" >>confdefs.h
fi
-
-
-have_ffaudio=no
-if test "x$enable_ffaudio" != "xno"; then
+elif test $ffmpeg_variant = libav ; then
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FFMPEG" >&5
@@ -9770,12 +11388,12 @@ if test -n "$FFMPEG_CFLAGS"; then
pkg_cv_FFMPEG_CFLAGS="$FFMPEG_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libavcodec >= 53.40.0 libavformat >= 53.5.0 libavutil >= 50.42.0\""; } >&5
- ($PKG_CONFIG --exists --print-errors "libavcodec >= 53.40.0 libavformat >= 53.5.0 libavutil >= 50.42.0") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libavcodec >= 53.25.0 libavformat >= 53.15.0 libavutil >= 51.18.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libavcodec >= 53.25.0 libavformat >= 53.15.0 libavutil >= 51.18.0") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_FFMPEG_CFLAGS=`$PKG_CONFIG --cflags "libavcodec >= 53.40.0 libavformat >= 53.5.0 libavutil >= 50.42.0" 2>/dev/null`
+ pkg_cv_FFMPEG_CFLAGS=`$PKG_CONFIG --cflags "libavcodec >= 53.25.0 libavformat >= 53.15.0 libavutil >= 51.18.0" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -9787,12 +11405,12 @@ if test -n "$FFMPEG_LIBS"; then
pkg_cv_FFMPEG_LIBS="$FFMPEG_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libavcodec >= 53.40.0 libavformat >= 53.5.0 libavutil >= 50.42.0\""; } >&5
- ($PKG_CONFIG --exists --print-errors "libavcodec >= 53.40.0 libavformat >= 53.5.0 libavutil >= 50.42.0") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libavcodec >= 53.25.0 libavformat >= 53.15.0 libavutil >= 51.18.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libavcodec >= 53.25.0 libavformat >= 53.15.0 libavutil >= 51.18.0") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_FFMPEG_LIBS=`$PKG_CONFIG --libs "libavcodec >= 53.40.0 libavformat >= 53.5.0 libavutil >= 50.42.0" 2>/dev/null`
+ pkg_cv_FFMPEG_LIBS=`$PKG_CONFIG --libs "libavcodec >= 53.25.0 libavformat >= 53.15.0 libavutil >= 51.18.0" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -9813,31 +11431,27 @@ else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
- FFMPEG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libavcodec >= 53.40.0 libavformat >= 53.5.0 libavutil >= 50.42.0" 2>&1`
+ FFMPEG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libavcodec >= 53.25.0 libavformat >= 53.15.0 libavutil >= 51.18.0" 2>&1`
else
- FFMPEG_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libavcodec >= 53.40.0 libavformat >= 53.5.0 libavutil >= 50.42.0" 2>&1`
+ FFMPEG_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libavcodec >= 53.25.0 libavformat >= 53.15.0 libavutil >= 51.18.0" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$FFMPEG_PKG_ERRORS" >&5
- if test "x$enable_ffaudio" = "xyes"; then
- as_fn_error $? "Cannot find FFmpeg development files (libavcodec ver >= 53.40.0, libavformat ver >= 53.5.0, libavutil ver >= 50.42.0), but compilation of ffaudio plugin has been explicitly requested; please install FFmpeg dev files and run configure again" "$LINENO" 5
- fi
-
+ as_fn_error $? "libav is not installed or too old (required: libavcodec 53.25.0, libavformat 53.15.0, libavutil 51.18.0)." "$LINENO" 5
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- if test "x$enable_ffaudio" = "xyes"; then
- as_fn_error $? "Cannot find FFmpeg development files (libavcodec ver >= 53.40.0, libavformat ver >= 53.5.0, libavutil ver >= 50.42.0), but compilation of ffaudio plugin has been explicitly requested; please install FFmpeg dev files and run configure again" "$LINENO" 5
- fi
-
+ as_fn_error $? "libav is not installed or too old (required: libavcodec 53.25.0, libavformat 53.15.0, libavutil 51.18.0)." "$LINENO" 5
else
FFMPEG_CFLAGS=$pkg_cv_FFMPEG_CFLAGS
FFMPEG_LIBS=$pkg_cv_FFMPEG_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- have_ffaudio=yes
- INPUT_PLUGINS="$INPUT_PLUGINS ffaudio"
+ INPUT_PLUGINS="$INPUT_PLUGINS ffaudio"
+
+$as_echo "#define HAVE_LIBAV 1" >>confdefs.h
+
fi
fi
@@ -10067,85 +11681,9 @@ $as_echo "yes" >&6; }
fi
if test "x$have_jack" = "xyes"; then
-
-pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SAMPLERATE" >&5
-$as_echo_n "checking for SAMPLERATE... " >&6; }
-
-if test -n "$SAMPLERATE_CFLAGS"; then
- pkg_cv_SAMPLERATE_CFLAGS="$SAMPLERATE_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
- if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"samplerate\""; } >&5
- ($PKG_CONFIG --exists --print-errors "samplerate") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- pkg_cv_SAMPLERATE_CFLAGS=`$PKG_CONFIG --cflags "samplerate" 2>/dev/null`
- test "x$?" != "x0" && pkg_failed=yes
-else
- pkg_failed=yes
-fi
- else
- pkg_failed=untried
-fi
-if test -n "$SAMPLERATE_LIBS"; then
- pkg_cv_SAMPLERATE_LIBS="$SAMPLERATE_LIBS"
- elif test -n "$PKG_CONFIG"; then
- if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"samplerate\""; } >&5
- ($PKG_CONFIG --exists --print-errors "samplerate") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- pkg_cv_SAMPLERATE_LIBS=`$PKG_CONFIG --libs "samplerate" 2>/dev/null`
- test "x$?" != "x0" && pkg_failed=yes
-else
- pkg_failed=yes
-fi
- else
- pkg_failed=untried
-fi
-
-
-
-if test $pkg_failed = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
- _pkg_short_errors_supported=yes
-else
- _pkg_short_errors_supported=no
-fi
- if test $_pkg_short_errors_supported = yes; then
- SAMPLERATE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "samplerate" 2>&1`
- else
- SAMPLERATE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "samplerate" 2>&1`
- fi
- # Put the nasty error message in config.log where it belongs
- echo "$SAMPLERATE_PKG_ERRORS" >&5
-
- have_jack=no
-
-elif test $pkg_failed = untried; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- have_jack=no
-
-else
- SAMPLERATE_CFLAGS=$pkg_cv_SAMPLERATE_CFLAGS
- SAMPLERATE_LIBS=$pkg_cv_SAMPLERATE_LIBS
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-fi
- fi
-
- if test "x$have_jack" = "xyes"; then
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS jack"
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS jack-ng"
elif test "x$enable_jack" = "xyes"; then
- as_fn_error $? "Cannot find JACK (ver >= 0.120.1 but < 1.0 or >= 1.9.7) or libsamplerate development files, but compilation of JACK output plugin has been explicitly requested; please install JACK and libsamplerate dev files and run configure again" "$LINENO" 5
+ as_fn_error $? "Cannot find JACK (ver >= 0.120.1 but < 1.0 or >= 1.9.7) development files, but compilation of JACK output plugin has been explicitly requested; please install JACK dev files and run configure again" "$LINENO" 5
fi
fi
@@ -10269,42 +11807,22 @@ if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
-
+ have_oss4=yes
fi
done
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OSS4" >&5
-$as_echo_n "checking for OSS4... " >&6; }
-
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef HAVE_SYS_SOUNDCARD_H
- #include <sys/soundcard.h>
- #elif defined HAVE_SOUNDCARD_H
- #include <soundcard.h>
- #endif
- #if OSS_VERSION >= 0x40000 || SOUND_VERSION >= 0x40000
- yes
- #endif
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "yes" >/dev/null 2>&1; then :
- have_oss4=yes
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS oss4"
-
-else
- if test "x$enable_oss4" = "xyes"; then
- as_fn_error $? "Cannot find OSS4 development files, but compilation of OSS4 output plugin has been explicitly requested; please install OSS4 dev files and run configure again" "$LINENO" 5
- fi
+ CPPFLAGS="$OLD_CPPFLAGS"
-fi
-rm -f conftest*
+ if test "x$have_oss4" = "xyes" ; then
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS oss4"
+ elif test "x$enable_oss4" = "xyes" ; then
+ as_fn_error $? "OSS4 output was enabled but soundcard.h was not found" "$LINENO" 5
+ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_oss4" >&5
$as_echo "$have_oss4" >&6; }
- CPPFLAGS="$OLD_CPPFLAGS"
fi
@@ -10321,19 +11839,190 @@ have_alsa=no
if test "x$enable_alsa" != "xno"; then
pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ALSA" >&5
-$as_echo_n "checking for ALSA... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ALSA" >&5
+$as_echo_n "checking for ALSA... " >&6; }
+
+if test -n "$ALSA_CFLAGS"; then
+ pkg_cv_ALSA_CFLAGS="$ALSA_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"alsa >= 1.0.16\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "alsa >= 1.0.16") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_ALSA_CFLAGS=`$PKG_CONFIG --cflags "alsa >= 1.0.16" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$ALSA_LIBS"; then
+ pkg_cv_ALSA_LIBS="$ALSA_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"alsa >= 1.0.16\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "alsa >= 1.0.16") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_ALSA_LIBS=`$PKG_CONFIG --libs "alsa >= 1.0.16" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ ALSA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "alsa >= 1.0.16" 2>&1`
+ else
+ ALSA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "alsa >= 1.0.16" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$ALSA_PKG_ERRORS" >&5
+
+ if test "x$enable_alsa" = "xyes"; then
+ as_fn_error $? "Cannot find ALSA development files (ver >= 1.0.16), but compilation of ALSA output plugin has been explicitly requested; please install ALSA dev files and run configure again" "$LINENO" 5
+ fi
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ if test "x$enable_alsa" = "xyes"; then
+ as_fn_error $? "Cannot find ALSA development files (ver >= 1.0.16), but compilation of ALSA output plugin has been explicitly requested; please install ALSA dev files and run configure again" "$LINENO" 5
+ fi
+else
+ ALSA_CFLAGS=$pkg_cv_ALSA_CFLAGS
+ ALSA_LIBS=$pkg_cv_ALSA_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_alsa=yes
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS alsa"
+fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: *** ALSA output plugin disabled per user request ***" >&5
+$as_echo "*** ALSA output plugin disabled per user request ***" >&6; }
+fi
+
+
+# Check whether --enable-sdlout was given.
+if test "${enable_sdlout+set}" = set; then :
+ enableval=$enable_sdlout; enable_sdlout=$enableval
+else
+ enable_sdlout=auto
+fi
+
+
+if test "x$enable_sdlout" != "xno"; then
+
+# Check whether --with-libsdl was given.
+if test "${with_libsdl+set}" = set; then :
+ withval=$with_libsdl; case "x$withval" in
+ x1) ;;
+ x2) ;;
+ x*) withval=check;;
+ esac
+ with_libsdl=$withval
+else
+ with_libsdl=check
+fi
+
+fi
+
+libsdl1_min="1.2.11";
+libsdl2_min="2.0";
+
+have_sdlout=no
+if test "x$enable_sdlout" != "xno"; then
+ if test "x$with_libsdl" = "xcheck"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5
+$as_echo_n "checking for SDL... " >&6; }
+
+if test -n "$SDL_CFLAGS"; then
+ pkg_cv_SDL_CFLAGS="$SDL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= \$libsdl2_min\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "sdl2 >= $libsdl2_min") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl2 >= $libsdl2_min" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$SDL_LIBS"; then
+ pkg_cv_SDL_LIBS="$SDL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= \$libsdl2_min\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "sdl2 >= $libsdl2_min") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl2 >= $libsdl2_min" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl2 >= $libsdl2_min" 2>&1`
+ else
+ SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl2 >= $libsdl2_min" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$SDL_PKG_ERRORS" >&5
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5
+$as_echo_n "checking for SDL... " >&6; }
-if test -n "$ALSA_CFLAGS"; then
- pkg_cv_ALSA_CFLAGS="$ALSA_CFLAGS"
+if test -n "$SDL_CFLAGS"; then
+ pkg_cv_SDL_CFLAGS="$SDL_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"alsa >= 1.0.16\""; } >&5
- ($PKG_CONFIG --exists --print-errors "alsa >= 1.0.16") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl >= \$libsdl1_min\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "sdl >= $libsdl1_min") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_ALSA_CFLAGS=`$PKG_CONFIG --cflags "alsa >= 1.0.16" 2>/dev/null`
+ pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl >= $libsdl1_min" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -10341,16 +12030,16 @@ fi
else
pkg_failed=untried
fi
-if test -n "$ALSA_LIBS"; then
- pkg_cv_ALSA_LIBS="$ALSA_LIBS"
+if test -n "$SDL_LIBS"; then
+ pkg_cv_SDL_LIBS="$SDL_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"alsa >= 1.0.16\""; } >&5
- ($PKG_CONFIG --exists --print-errors "alsa >= 1.0.16") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl >= \$libsdl1_min\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "sdl >= $libsdl1_min") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_ALSA_LIBS=`$PKG_CONFIG --libs "alsa >= 1.0.16" 2>/dev/null`
+ pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl >= $libsdl1_min" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -10371,46 +12060,33 @@ else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
- ALSA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "alsa >= 1.0.16" 2>&1`
+ SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl >= $libsdl1_min" 2>&1`
else
- ALSA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "alsa >= 1.0.16" 2>&1`
+ SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl >= $libsdl1_min" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
- echo "$ALSA_PKG_ERRORS" >&5
+ echo "$SDL_PKG_ERRORS" >&5
- if test "x$enable_alsa" = "xyes"; then
- as_fn_error $? "Cannot find ALSA development files (ver >= 1.0.16), but compilation of ALSA output plugin has been explicitly requested; please install ALSA dev files and run configure again" "$LINENO" 5
- fi
+ if test "x$enable_sdlout" = "xyes"; then
+ as_fn_error $? "Cannot find SDL development files (ver >= $libsdl1_min), but compilation of SDL output plugin has been explicitly requested; please install SDL dev files and run configure again" "$LINENO" 5
+ fi
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- if test "x$enable_alsa" = "xyes"; then
- as_fn_error $? "Cannot find ALSA development files (ver >= 1.0.16), but compilation of ALSA output plugin has been explicitly requested; please install ALSA dev files and run configure again" "$LINENO" 5
- fi
+ if test "x$enable_sdlout" = "xyes"; then
+ as_fn_error $? "Cannot find SDL development files (ver >= $libsdl1_min), but compilation of SDL output plugin has been explicitly requested; please install SDL dev files and run configure again" "$LINENO" 5
+ fi
else
- ALSA_CFLAGS=$pkg_cv_ALSA_CFLAGS
- ALSA_LIBS=$pkg_cv_ALSA_LIBS
+ SDL_CFLAGS=$pkg_cv_SDL_CFLAGS
+ SDL_LIBS=$pkg_cv_SDL_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- have_alsa=yes
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS alsa"
-fi
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: *** ALSA output plugin disabled per user request ***" >&5
-$as_echo "*** ALSA output plugin disabled per user request ***" >&6; }
-fi
-
-
-# Check whether --enable-sdlout was given.
-if test "${enable_sdlout+set}" = set; then :
- enableval=$enable_sdlout; enable_sdlout=$enableval
-else
- enable_sdlout=auto
+ have_sdlout=yes
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"
fi
-
-
-have_sdlout=no
-if test "x$enable_sdlout" != "xno"; then
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5
@@ -10420,12 +12096,12 @@ if test -n "$SDL_CFLAGS"; then
pkg_cv_SDL_CFLAGS="$SDL_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= 2.0\""; } >&5
- ($PKG_CONFIG --exists --print-errors "sdl2 >= 2.0") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl >= \$libsdl1_min\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "sdl >= $libsdl1_min") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl2 >= 2.0" 2>/dev/null`
+ pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl >= $libsdl1_min" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -10437,12 +12113,12 @@ if test -n "$SDL_LIBS"; then
pkg_cv_SDL_LIBS="$SDL_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= 2.0\""; } >&5
- ($PKG_CONFIG --exists --print-errors "sdl2 >= 2.0") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl >= \$libsdl1_min\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "sdl >= $libsdl1_min") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl2 >= 2.0" 2>/dev/null`
+ pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl >= $libsdl1_min" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -10463,13 +12139,39 @@ else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
- SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl2 >= 2.0" 2>&1`
+ SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl >= $libsdl1_min" 2>&1`
else
- SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl2 >= 2.0" 2>&1`
+ SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl >= $libsdl1_min" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$SDL_PKG_ERRORS" >&5
+ if test "x$enable_sdlout" = "xyes"; then
+ as_fn_error $? "Cannot find SDL development files (ver >= $libsdl1_min), but compilation of SDL output plugin has been explicitly requested; please install SDL dev files and run configure again" "$LINENO" 5
+ fi
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ if test "x$enable_sdlout" = "xyes"; then
+ as_fn_error $? "Cannot find SDL development files (ver >= $libsdl1_min), but compilation of SDL output plugin has been explicitly requested; please install SDL dev files and run configure again" "$LINENO" 5
+ fi
+else
+ SDL_CFLAGS=$pkg_cv_SDL_CFLAGS
+ SDL_LIBS=$pkg_cv_SDL_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_sdlout=yes
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"
+fi
+else
+ SDL_CFLAGS=$pkg_cv_SDL_CFLAGS
+ SDL_LIBS=$pkg_cv_SDL_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_sdlout=yes
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"
+fi
+ elif test "x$with_libsdl" = "x1"; then
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5
@@ -10479,12 +12181,12 @@ if test -n "$SDL_CFLAGS"; then
pkg_cv_SDL_CFLAGS="$SDL_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl >= 1.2.11\""; } >&5
- ($PKG_CONFIG --exists --print-errors "sdl >= 1.2.11") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl >= \$libsdl1_min\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "sdl >= $libsdl1_min") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl >= 1.2.11" 2>/dev/null`
+ pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl >= $libsdl1_min" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -10496,12 +12198,12 @@ if test -n "$SDL_LIBS"; then
pkg_cv_SDL_LIBS="$SDL_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl >= 1.2.11\""; } >&5
- ($PKG_CONFIG --exists --print-errors "sdl >= 1.2.11") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl >= \$libsdl1_min\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "sdl >= $libsdl1_min") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl >= 1.2.11" 2>/dev/null`
+ pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl >= $libsdl1_min" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -10522,33 +12224,31 @@ else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
- SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl >= 1.2.11" 2>&1`
+ SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl >= $libsdl1_min" 2>&1`
else
- SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl >= 1.2.11" 2>&1`
+ SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl >= $libsdl1_min" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$SDL_PKG_ERRORS" >&5
if test "x$enable_sdlout" = "xyes"; then
- as_fn_error $? "Cannot find SDL development files (ver >= 1.2.11), but compilation of SDL output plugin has been explicitly requested; please install SDL dev files and run configure again" "$LINENO" 5
- fi
+ as_fn_error $? "Cannot find SDL1 development files (ver >= $libsdl1_min), but compilation of SDL output plugin has been explicitly requested; please install SDL1 dev files and run configure again" "$LINENO" 5
+ fi
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if test "x$enable_sdlout" = "xyes"; then
- as_fn_error $? "Cannot find SDL development files (ver >= 1.2.11), but compilation of SDL output plugin has been explicitly requested; please install SDL dev files and run configure again" "$LINENO" 5
- fi
+ as_fn_error $? "Cannot find SDL1 development files (ver >= $libsdl1_min), but compilation of SDL output plugin has been explicitly requested; please install SDL1 dev files and run configure again" "$LINENO" 5
+ fi
else
SDL_CFLAGS=$pkg_cv_SDL_CFLAGS
SDL_LIBS=$pkg_cv_SDL_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
have_sdlout=yes
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"
fi
-elif test $pkg_failed = untried; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+ elif test "x$with_libsdl" = "x2"; then
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5
@@ -10558,12 +12258,12 @@ if test -n "$SDL_CFLAGS"; then
pkg_cv_SDL_CFLAGS="$SDL_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl >= 1.2.11\""; } >&5
- ($PKG_CONFIG --exists --print-errors "sdl >= 1.2.11") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= \$libsdl2_min\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "sdl2 >= $libsdl2_min") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl >= 1.2.11" 2>/dev/null`
+ pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl2 >= $libsdl2_min" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -10575,12 +12275,12 @@ if test -n "$SDL_LIBS"; then
pkg_cv_SDL_LIBS="$SDL_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl >= 1.2.11\""; } >&5
- ($PKG_CONFIG --exists --print-errors "sdl >= 1.2.11") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= \$libsdl2_min\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "sdl2 >= $libsdl2_min") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl >= 1.2.11" 2>/dev/null`
+ pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl2 >= $libsdl2_min" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -10601,38 +12301,31 @@ else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
- SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl >= 1.2.11" 2>&1`
+ SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl2 >= $libsdl2_min" 2>&1`
else
- SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl >= 1.2.11" 2>&1`
+ SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl2 >= $libsdl2_min" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$SDL_PKG_ERRORS" >&5
if test "x$enable_sdlout" = "xyes"; then
- as_fn_error $? "Cannot find SDL development files (ver >= 1.2.11), but compilation of SDL output plugin has been explicitly requested; please install SDL dev files and run configure again" "$LINENO" 5
- fi
+ as_fn_error $? "Cannot find SDL2 development files (ver >= $libsdl2_min), but compilation of SDL output plugin has been explicitly requested; please install SDL2 dev files and run configure again" "$LINENO" 5
+ fi
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if test "x$enable_sdlout" = "xyes"; then
- as_fn_error $? "Cannot find SDL development files (ver >= 1.2.11), but compilation of SDL output plugin has been explicitly requested; please install SDL dev files and run configure again" "$LINENO" 5
- fi
-else
- SDL_CFLAGS=$pkg_cv_SDL_CFLAGS
- SDL_LIBS=$pkg_cv_SDL_LIBS
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- have_sdlout=yes
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"
-fi
+ as_fn_error $? "Cannot find SDL2 development files (ver >= $libsdl2_min), but compilation of SDL output plugin has been explicitly requested; please install SDL2 dev files and run configure again" "$LINENO" 5
+ fi
else
SDL_CFLAGS=$pkg_cv_SDL_CFLAGS
SDL_LIBS=$pkg_cv_SDL_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
have_sdlout=yes
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"
fi
+ fi
fi
@@ -10687,7 +12380,7 @@ fi
$as_echo "$ac_cv_lib_sndio_sio_open" >&6; }
if test "x$ac_cv_lib_sndio_sio_open" = xyes; then :
have_sndio=yes
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS sndio"
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS sndio-ng"
SNDIO_LIBS="-lsndio"
@@ -10704,6 +12397,11 @@ fi
fi
+if test "x$OUTPUT_PLUGINS" = "x" ; then
+ as_fn_error $? "No output plugin was enabled. Please install the necessary packages for your system and run configure again." "$LINENO" 5
+fi
+
+
# Check whether --enable-amidiplug was given.
if test "${enable_amidiplug+set}" = set; then :
enableval=$enable_amidiplug; enable_amidiplug=$enableval
@@ -10788,7 +12486,7 @@ else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
have_amidiplug=yes
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS amidi-plug"
+ INPUT_PLUGINS="$INPUT_PLUGINS amidi-plug"
fi
fi
@@ -11063,12 +12761,11 @@ fi
if test "${enable_neon+set}" = set; then :
enableval=$enable_neon; enable_neon=$enableval
else
- enable_neon=auto
+ enable_neon=yes
fi
-have_neon=no
-if test "x$enable_neon" != "xno"; then
+if test $enable_neon = yes ; then
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NEON" >&5
@@ -11078,12 +12775,12 @@ if test -n "$NEON_CFLAGS"; then
pkg_cv_NEON_CFLAGS="$NEON_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"neon >= 0.26\""; } >&5
- ($PKG_CONFIG --exists --print-errors "neon >= 0.26") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"neon >= 0.27\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "neon >= 0.27") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_NEON_CFLAGS=`$PKG_CONFIG --cflags "neon >= 0.26" 2>/dev/null`
+ pkg_cv_NEON_CFLAGS=`$PKG_CONFIG --cflags "neon >= 0.27" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -11095,12 +12792,12 @@ if test -n "$NEON_LIBS"; then
pkg_cv_NEON_LIBS="$NEON_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"neon >= 0.26\""; } >&5
- ($PKG_CONFIG --exists --print-errors "neon >= 0.26") 2>&5
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"neon >= 0.27\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "neon >= 0.27") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
- pkg_cv_NEON_LIBS=`$PKG_CONFIG --libs "neon >= 0.26" 2>/dev/null`
+ pkg_cv_NEON_LIBS=`$PKG_CONFIG --libs "neon >= 0.27" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -11121,76 +12818,46 @@ else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
- NEON_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "neon >= 0.26" 2>&1`
+ NEON_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "neon >= 0.27" 2>&1`
else
- NEON_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "neon >= 0.26" 2>&1`
+ NEON_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "neon >= 0.27" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$NEON_PKG_ERRORS" >&5
- if test "x$enable_neon" = "xyes"; then
- as_fn_error $? "Cannot find neon development files (ver >= 0.26), but compilation of neon HTTP support has been explicitly requested; please install neon dev files and run configure again" "$LINENO" 5
- fi
+ as_fn_error $? "Package requirements (neon >= 0.27) were not met:
+
+$NEON_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+Alternatively, you may set the environment variables NEON_CFLAGS
+and NEON_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- if test "x$enable_neon" = "xyes"; then
- as_fn_error $? "Cannot find neon development files (ver >= 0.26), but compilation of neon HTTP support has been explicitly requested; please install neon dev files and run configure again" "$LINENO" 5
- fi
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+Alternatively, you may set the environment variables NEON_CFLAGS
+and NEON_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
else
NEON_CFLAGS=$pkg_cv_NEON_CFLAGS
NEON_LIBS=$pkg_cv_NEON_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- have_neon=yes
- TRANSPORT_PLUGINS="$TRANSPORT_PLUGINS neon"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ne_set_connect_timeout in -lneon" >&5
-$as_echo_n "checking for ne_set_connect_timeout in -lneon... " >&6; }
-if ${ac_cv_lib_neon_ne_set_connect_timeout+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lneon $NEON_LIBS $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char ne_set_connect_timeout ();
-int
-main ()
-{
-return ne_set_connect_timeout ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_neon_ne_set_connect_timeout=yes
-else
- ac_cv_lib_neon_ne_set_connect_timeout=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_neon_ne_set_connect_timeout" >&5
-$as_echo "$ac_cv_lib_neon_ne_set_connect_timeout" >&6; }
-if test "x$ac_cv_lib_neon_ne_set_connect_timeout" = xyes; then :
-
-$as_echo "#define HAVE_NE_SET_CONNECT_TIMEOUT 1" >>confdefs.h
-
-fi
-
-
fi
+ TRANSPORT_PLUGINS="$TRANSPORT_PLUGINS neon"
fi
@@ -11462,7 +13129,7 @@ fi
have_vorbisenc=no
-if test "x$have_filewriter" = "xyes" -a "x$have_vorbis" = "xyes"; then
+if test "x$have_filewriter" = "xyes" -a "x$enable_vorbis" = "xyes"; then
have_vorbisenc=yes
$as_echo "#define FILEWRITER_VORBIS 1" >>confdefs.h
@@ -11940,32 +13607,6 @@ fi
fi
-# Check whether --enable-gtkui was given.
-if test "${enable_gtkui+set}" = set; then :
- enableval=$enable_gtkui; enable_gtkui=$enableval
-else
- enable_gtkui="yes"
-fi
-
-
-if test "x$enable_gtkui" != "xno"; then
- GENERAL_PLUGINS="$GENERAL_PLUGINS gtkui"
-fi
-
-
-# Check whether --enable-skins was given.
-if test "${enable_skins+set}" = set; then :
- enableval=$enable_skins; enable_skins=$enableval
-else
- enable_skins="yes"
-fi
-
-
-if test "x$enable_skins" != "xno"; then
- GENERAL_PLUGINS="$GENERAL_PLUGINS skins"
-fi
-
-
# Check whether --enable-lyricwiki was given.
if test "${enable_lyricwiki+set}" = set; then :
enableval=$enable_lyricwiki; enable_lyricwiki=$enableval
@@ -12131,6 +13772,164 @@ fi
+# Check whether --enable-qtglspectrum was given.
+if test "${enable_qtglspectrum+set}" = set; then :
+ enableval=$enable_qtglspectrum; enable_qtglspectrum=$enableval
+else
+ enable_qtglspectrum=auto
+fi
+
+
+have_qtglspectrum=no
+if test "x$USE_QT" = "xno" -a "x$enable_qtglspectrum" = "xyes"; then
+ as_fn_error $? "--enable-qtglspectrum cannot be used without --enable-qt" "$LINENO" 5
+fi
+if test "x$USE_QT" = "xyes" -a "x$enable_qtglspectrum" != "xno"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for QTOPENGL" >&5
+$as_echo_n "checking for QTOPENGL... " >&6; }
+
+if test -n "$QTOPENGL_CFLAGS"; then
+ pkg_cv_QTOPENGL_CFLAGS="$QTOPENGL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5OpenGL\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "Qt5OpenGL") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_QTOPENGL_CFLAGS=`$PKG_CONFIG --cflags "Qt5OpenGL" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$QTOPENGL_LIBS"; then
+ pkg_cv_QTOPENGL_LIBS="$QTOPENGL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5OpenGL\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "Qt5OpenGL") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_QTOPENGL_LIBS=`$PKG_CONFIG --libs "Qt5OpenGL" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ QTOPENGL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "Qt5OpenGL" 2>&1`
+ else
+ QTOPENGL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "Qt5OpenGL" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$QTOPENGL_PKG_ERRORS" >&5
+
+ have_qtglspectrum=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_qtglspectrum=no
+else
+ QTOPENGL_CFLAGS=$pkg_cv_QTOPENGL_CFLAGS
+ QTOPENGL_LIBS=$pkg_cv_QTOPENGL_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_qtglspectrum=yes
+fi
+ if test "x$have_qtglspectrum" = "xyes"; then
+ QTOPENGL_CFLAGS="$QTOPENGL_CFLAGS -fPIC"
+ VISUALIZATION_PLUGINS="$VISUALIZATION_PLUGINS gl-spectrum-qt"
+ elif test "x$enable_qtglspectrum" = "xyes"; then
+ as_fn_error $? "Qt OpenGL Spectrum Analyzer plugin requested but QtOpenGL not found!" "$LINENO" 5
+ fi
+fi
+
+
+# Check whether --enable-vtx was given.
+if test "${enable_vtx+set}" = set; then :
+ enableval=$enable_vtx; enable_vtx=$enableval
+else
+ enable_vtx="yes"
+fi
+
+
+if test "x$enable_vtx" != "xno"; then
+ INPUT_PLUGINS="$INPUT_PLUGINS vtx"
+fi
+
+
+# Check whether --enable-ladspa was given.
+if test "${enable_ladspa+set}" = set; then :
+ enableval=$enable_ladspa; enable_ladspa=$enableval
+else
+ enable_ladspa="yes"
+fi
+
+
+if test "x$enable_ladspa" != "xno"; then
+ EFFECT_PLUGINS="$EFFECT_PLUGINS ladspa"
+fi
+
+
+# Check whether --enable-blur_scope was given.
+if test "${enable_blur_scope+set}" = set; then :
+ enableval=$enable_blur_scope; enable_blur_scope=$enableval
+else
+ enable_blur_scope="yes"
+fi
+
+
+if test "x$enable_blur_scope" != "xno"; then
+ VISUALIZATION_PLUGINS="$VISUALIZATION_PLUGINS blur_scope"
+fi
+
+
+# Check whether --enable-cairo_spectrum was given.
+if test "${enable_cairo_spectrum+set}" = set; then :
+ enableval=$enable_cairo_spectrum; enable_cairo_spectrum=$enableval
+else
+ enable_cairo_spectrum="yes"
+fi
+
+
+if test "x$enable_cairo_spectrum" != "xno"; then
+ VISUALIZATION_PLUGINS="$VISUALIZATION_PLUGINS cairo-spectrum"
+fi
+
+
+# Check whether --enable-mac_media_keys was given.
+if test "${enable_mac_media_keys+set}" = set; then :
+ enableval=$enable_mac_media_keys; enable_mac_media_keys=$enableval
+else
+ enable_mac_media_keys="no"
+fi
+
+
+if test "x$enable_mac_media_keys" != "xno"; then
+ GENERAL_PLUGINS="$GENERAL_PLUGINS mac-media-keys"
+fi
+
+
plugindir=`pkg-config audacious --variable=plugin_dir`
@@ -12799,7 +14598,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by audacious-plugins $as_me 3.5, which was
+This file was extended by audacious-plugins $as_me 3.6.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12865,7 +14664,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-audacious-plugins config.status 3.5
+audacious-plugins config.status 3.6.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -13737,9 +15536,11 @@ echo " --------------"
echo " Open Sound System (oss4): $have_oss4"
echo " Advanced Linux Sound Arch. (alsa): $have_alsa"
echo " Sndio (sndio): $have_sndio"
+echo " CoreAudio (coreaudio): $have_coreaudio"
echo " PulseAudio (pulse): $have_pulse"
echo " Jack Audio Connection Kit (jack): $have_jack"
echo " Simple DirectMedia Layer (sdlout): $have_sdlout"
+echo " Qt Multimedia (qtaudio): $have_qtaudio"
echo " FileWriter: $have_filewriter"
echo " -> FileWriter MP3 output part: $have_lame"
echo " -> FileWriter Vorbis output part: $have_vorbisenc"
@@ -13747,16 +15548,16 @@ echo " -> FileWriter FLAC output part: $have_writer_flac"
echo
echo " Input Plugins"
echo " -------------"
-echo " MPEG-1 Layer I/II/III (mpg123): $have_mp3"
-echo " MPEG-2/4 AAC (aac): $have_aac"
-echo " FFaudio (ffaudio): $have_ffaudio"
+echo " MPEG-1 Layer I/II/III (mpg123): $enable_mp3"
+echo " MPEG-2/4 AAC (aac): $enable_aac"
+echo " FFaudio (ffaudio): $ffmpeg_variant"
echo " Module decoder (modplug): $have_modplug"
echo " MIDI synthesizer (amidi-plug): $have_amidiplug"
echo " CD Digital Audio (cdaudio_ng): $have_cdaudio_ng"
echo " sndfile extensions: $have_sndfile"
echo " Tone Generator: yes"
-echo " Ogg Vorbis (vorbis): $have_vorbis"
-echo " Free Lossless Audio Codec (flacng): $have_flacng"
+echo " Ogg Vorbis (vorbis): $enable_vorbis"
+echo " Free Lossless Audio Codec (flacng): $enable_flacng"
echo " Commodore 64 audio (SID): $have_sidplay"
echo " Game music (spc, nsf & gbs): $have_console"
echo " PlayStation (psf/psf2) audio: $enable_psf"
@@ -13764,17 +15565,19 @@ echo " Nintendo DS audio (xsf): $enable_xsf"
echo " AdLib synthesizer (adplug): $have_adplug"
echo " WavPack 4.31+ (wavpack): $have_wavpack"
echo " Metronom: yes"
+echo " VTX Decoder: $enable_vtx"
echo
echo " General"
echo " -------"
-echo " Alarm: yes"
-echo " Album Art: yes"
-echo " Delete from Filesystem: yes"
+echo " Alarm: $USE_GTK"
+echo " Album Art: $USE_GTK"
+echo " Delete from Filesystem: $USE_GTK"
echo " Linux Infrared Remote Control (LIRC) $have_lirc"
echo " MPRIS 2 Server: $have_mpris2"
-echo " Search Tool: yes"
+echo " Playlist Manager: $USE_GTK"
+echo " Search Tool: $USE_GTK"
echo " Song Change: $have_songchange"
-echo " Status Icon: $have_statusicon"
+echo " Status Icon: $USE_GTK"
echo " Audacious OSD: $have_aosd"
echo " -> X Composite support: $have_aosd_xcomp"
echo " libnotify OSD: $have_notify"
@@ -13782,6 +15585,7 @@ echo " Global Hotkey Plugin: $have_hotkey"
echo " Gnome Shortcuts Plugin: $have_gnomeshortcuts"
echo " Scrobbler 2.0: $have_scrobbler2"
echo " LyricWiki viewer: $have_lyricwiki"
+echo " Mac Media Keys: $enable_mac_media_keys"
echo
echo " Effect"
echo " ------"
@@ -13790,22 +15594,24 @@ echo " Crystalizer: yes"
echo " Dynamic Range Compressor: yes"
echo " Echo/Surround: yes"
echo " Extra Stereo: yes"
-echo " LADSPA Host: yes"
+echo " LADSPA Host: $enable_ladspa"
echo " Voice Removal: yes"
echo " Bauer stereophonic-to-binaural (bs2b): $have_bs2b"
echo " Sample Rate Converter (resample): $have_resample"
+echo " Silence Removal: yes"
echo " Speed and Pitch: $have_speedpitch"
echo " SoX Resampler: $have_soxr"
echo
echo " Visualization"
echo " -------------"
-echo " Blur Scope: yes"
-echo " Cairo Spectrum Analyzer: yes"
-echo " OpenGL Spectrum Analyzer: $have_glspectrum"
+echo " Blur Scope: $enable_blur_scope"
+echo " Cairo Spectrum Analyzer: $enable_cairo_spectrum"
+echo " GTK+ OpenGL Spectrum Analyzer: $have_glspectrum"
+echo " Qt OpenGL Spectrum Analyzer: $have_qtglspectrum"
echo
echo " Transport"
echo " ---------"
-echo " neon-based http/https: $have_neon"
+echo " neon-based http/https: $enable_neon"
echo " libmms-based mms: $have_mms"
echo " GIO: yes"
echo
@@ -13821,6 +15627,7 @@ echo " CUE playlist format (cue): $have_cue"
echo
echo " Interfaces"
echo " ----------"
-echo " GTK (gtkui): $enable_gtkui"
-echo " Winamp Classic (skins): $enable_skins"
+echo " GTK (gtkui): $USE_GTK"
+echo " Qt (qtui): $USE_QT"
+echo " Winamp Classic (skins): $USE_GTK"
echo
diff --git a/configure.ac b/configure.ac
index e750ca215c72..ce53000f856a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,8 +5,8 @@ dnl ***
dnl Initialize
dnl ==========
AC_PREREQ([2.59])
-AC_INIT([audacious-plugins], [3.5])
-AC_COPYRIGHT([(C) 2005-2014 Audacious Team])
+AC_INIT([audacious-plugins], [3.6.1])
+AC_COPYRIGHT([Copyright (C) 2001-2015 Audacious developers and others])
AC_DEFINE_UNQUOTED([PACKAGE], "$PACKAGE_NAME", [Name of package])
AC_DEFINE_UNQUOTED([VERSION], "$PACKAGE_VERSION", [Version number of package])
@@ -19,10 +19,6 @@ AUD_COMMON_PROGS
BUILDSYS_SHARED_LIB
-dnl Headers and functions
-dnl =====================
-AC_CHECK_FUNCS([mkdtemp])
-
dnl gettext
dnl =======
AM_GNU_GETTEXT([external])
@@ -35,9 +31,9 @@ LIBS="$LIBS $LIBINTL"
dnl Check for Audacious
dnl ===================
-PKG_CHECK_MODULES(AUDACIOUS, [audacious >= 3.5],
+PKG_CHECK_MODULES(AUDACIOUS, [audacious >= 3.6],
[],
- [AC_MSG_ERROR([Cannot find Audacious 3.5; have you installed Audacious yet?])]
+ [AC_MSG_ERROR([Cannot find Audacious 3.6; have you installed Audacious yet?])]
)
CPPFLAGS="$CPPFLAGS $AUDACIOUS_CFLAGS"
@@ -46,19 +42,45 @@ LIBS="$LIBS $AUDACIOUS_LIBS"
dnl Check for libxml2 (required to load XSPF playlists from previous versions)
dnl ==========================================================================
-PKG_CHECK_MODULES([XML], [libxml-2.0])
+if test $HAVE_DARWIN = yes ; then
+ AC_ARG_WITH([system-libxml2],
+ [AS_HELP_STRING([--with-system-libxml2=yes,no], [Use system version of libxml2 (default=yes)])],
+ [with_system_libxml2=$withval],
+ [with_system_libxml2=yes])
+
+ if test $with_system_libxml2 = yes ; then
+ XML_LIBS="-lxml2"
+ XML_CFLAGS="-I/usr/include/libxml2"
+ AC_SUBST(XML_LIBS)
+ AC_SUBST(XML_CFLAGS)
+ else
+ PKG_CHECK_MODULES([XML], [libxml-2.0])
+ fi
+else
+ PKG_CHECK_MODULES([XML], [libxml-2.0])
+fi
dnl Default Set of Plugins
dnl ======================
-INPUT_PLUGINS="tonegen metronom vtx"
+INPUT_PLUGINS="tonegen metronom"
OUTPUT_PLUGINS=""
-EFFECT_PLUGINS="compressor crossfade crystalizer ladspa mixer stereo_plugin voice_removal echo_plugin"
-GENERAL_PLUGINS="alarm albumart delete-files search-tool"
-VISUALIZATION_PLUGINS="blur_scope cairo-spectrum"
+EFFECT_PLUGINS="compressor crossfade crystalizer mixer silence-removal stereo_plugin voice_removal echo_plugin"
+GENERAL_PLUGINS=""
+VISUALIZATION_PLUGINS=""
CONTAINER_PLUGINS="asx asx3 audpl m3u pls xspf"
TRANSPORT_PLUGINS="gio"
+if test "x$USE_GTK" = "xyes" ; then
+ GENERAL_PLUGINS="$GENERAL_PLUGINS alarm albumart delete-files playlist-manager search-tool statusicon"
+ GENERAL_PLUGINS="$GENERAL_PLUGINS gtkui skins"
+fi
+
+if test "x$USE_QT" = "xyes" ; then
+ GENERAL_PLUGINS="$GENERAL_PLUGINS albumart-qt lyricwiki-qt song-info-qt"
+ GENERAL_PLUGINS="$GENERAL_PLUGINS qtui"
+fi
+
dnl Console
dnl =======
@@ -88,6 +110,43 @@ if test "x$enable_xsf" != "xno"; then
INPUT_PLUGINS="$INPUT_PLUGINS xsf"
fi
+dnl QtAudio
+dnl =======
+
+AC_ARG_ENABLE(qtaudio,
+ [AS_HELP_STRING([--disable-qtaudio], [disable QtMultimedia output plugin (default=enabled)])],
+ [enable_qtaudio=$enableval],
+ [enable_qtaudio=auto])
+
+have_qtaudio=no
+if test "x$enable_qtaudio" = "xyes" -o \( "x$USE_QT" = "xyes" -a "x$enable_qtaudio" = "xauto" \); then
+ PKG_CHECK_MODULES(QTMULTIMEDIA, [Qt5Multimedia], [have_qtaudio=yes], [have_qtaudio=no])
+ if test "x$have_qtaudio" = "xyes"; then
+ QTMULTIMEDIA_CFLAGS="$QTMULTIMEDIA_CFLAGS -fPIC"
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS qtaudio"
+ elif test "x$enable_qtaudio" = "xyes"; then
+ AC_MSG_ERROR([QtAudio output plugin requested but QtMultimedia not found!])
+ fi
+fi
+
+dnl CoreAudio
+dnl =========
+
+AC_ARG_ENABLE(coreaudio,
+ [AS_HELP_STRING([--disable-coreaudio], [disable CoreAudio output plugin (default=enabled)])],
+ [enable_coreaudio=$enableval],
+ [enable_coreaudio=auto]
+)
+
+have_coreaudio=no
+if test "x$enable_coreaudio" != "xno"; then
+ if test "x$HAVE_DARWIN" != "xno"; then
+ have_coreaudio=yes
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS coreaudio"
+ fi
+else
+ AC_MSG_RESULT([*** CoreAudio output plugin disabled per user request ***])
+fi
dnl PulseAudio
dnl ==========
@@ -123,23 +182,16 @@ if test "x$enable_psf" != "xno"; then
INPUT_PLUGINS="$INPUT_PLUGINS psf"
fi
-dnl *** MP3
+dnl MP3 (enabled by default)
+dnl ========================
AC_ARG_ENABLE(mp3,
- [AS_HELP_STRING([--disable-mp3], [disable MP3 plugin (default=enabled)])],
- [enable_mp3=$enableval], [enable_mp3=auto])
-
-have_mp3=no
-if test "x$enable_mp3" != "xno"; then
- PKG_CHECK_MODULES(MPG123, [libmpg123 >= 1.12],
- [have_mp3=yes
- INPUT_PLUGINS="$INPUT_PLUGINS mpg123"],
- [if test "x$enable_mp3" = "xyes"; then
- AC_MSG_ERROR([Cannot find libmpg123 development files (ver >= 1.12), but compilation of MP3 plugin has been explicitly requested; please install libmpg123 dev files and run configure again])
- fi]
- )
-else
- AC_MSG_RESULT([*** libmpg123 not found; MP3 plugin disabled])
+ [AS_HELP_STRING([--disable-mp3], [disable MP3 support (default=enabled)])],
+ [enable_mp3=$enableval], [enable_mp3=yes])
+
+if test $enable_mp3 = yes ; then
+ PKG_CHECK_MODULES(MPG123, [libmpg123 >= 1.12])
+ INPUT_PLUGINS="$INPUT_PLUGINS mpg123"
fi
dnl *** Global Hotkey general plugin (only built on X11)
@@ -152,11 +204,11 @@ AC_ARG_ENABLE(hotkey,
have_hotkey=no
if test "x$enable_hotkey" != "xno"; then
- PKG_CHECK_MODULES(GDKX11, [gdk-x11-3.0],
+ PKG_CHECK_MODULES(GDKX11, [gdk-x11-2.0],
[have_hotkey="yes"
GENERAL_PLUGINS="$GENERAL_PLUGINS hotkey"],
[if test "x$enable_hotkey" = "xyes"; then
- AC_MSG_ERROR([Cannot find gdk-x11-3.0 development files, but compilation of X11 Global Hotkey plugin has been explicitly requested; please install gdk-x11-3.0 dev files and run configure again])
+ AC_MSG_ERROR([Cannot find gdk-x11-2.0 development files, but compilation of X11 Global Hotkey plugin has been explicitly requested; please install gdk-x11-2.0 dev files and run configure again])
fi]
)
else
@@ -219,17 +271,6 @@ if test "x$enable_songchange" != "xno"; then
)
fi
-dnl Status Icon
-dnl ===========
-
-AC_ARG_ENABLE(statusicon,
- [AS_HELP_STRING([--disable-statusicon], [disable X11 Status Icon plugin (default=enabled)])],
- [have_statusicon=$enableval], [have_statusicon="yes"])
-
-if test "x$have_statusicon" != "xno"; then
- GENERAL_PLUGINS="$GENERAL_PLUGINS statusicon"
-fi
-
dnl *** Audacious OSD plugin (pangocairo-based)
AC_ARG_ENABLE(aosd,
@@ -338,45 +379,30 @@ else
AC_MSG_RESULT([*** AdPlug plugin disabled per user request ***])
fi
-dnl Ogg Vorbis
-dnl ==========
+dnl Ogg Vorbis (enabled by default)
+dnl ===============================
+
dnl This test is reused later to enable/disable Vorbis support in filewriter.
AC_ARG_ENABLE(vorbis,
- [AS_HELP_STRING([--disable-vorbis], [disable Ogg Vorbis decoding and encoding])],
- [enable_vorbis=$enableval], [enable_vorbis=auto])
-
-have_vorbis=no
-if test "x$enable_vorbis" != "xno"; then
- PKG_CHECK_MODULES(VORBIS, [ogg >= 1.0 vorbis >= 1.0 vorbisenc >= 1.0 vorbisfile >= 1.0],
- [have_vorbis=yes
- INPUT_PLUGINS="$INPUT_PLUGINS vorbis"],
- [if test "x$enable_vorbis" = "xyes"; then
- AC_MSG_ERROR([Cannot find ogg, vorbis, vorbisenc or vorbisfile development files (ver >= 1.0), but compilation of Ogg Vorbis decoding and encoding has been explicitly requested; please install ogg, vorbis, vorbisenc and vorbisfile dev files and run configure again])
- fi]
- )
+ [AS_HELP_STRING([--disable-vorbis], [disable Ogg Vorbis support (default=enabled)])],
+ [enable_vorbis=$enableval], [enable_vorbis=yes])
+
+if test $enable_vorbis = yes ; then
+ PKG_CHECK_MODULES(VORBIS, [ogg >= 1.0 vorbis >= 1.0 vorbisenc >= 1.0 vorbisfile >= 1.0])
+ INPUT_PLUGINS="$INPUT_PLUGINS vorbis"
fi
-dnl FLAC
-dnl ====
+dnl FLAC (enabled by default)
+dnl =========================
AC_ARG_ENABLE(flacng,
- [AS_HELP_STRING([--disable-flacng], [disable flac input plugin (default=enabled)])],
- [enable_flacng=$enableval],
- [enable_flacng=auto]
-)
+ [AS_HELP_STRING([--disable-flacng], [disable FLAC support (default=enabled)])],
+ [enable_flacng=$enableval], [enable_flacng=yes])
-have_flacng=no
-if test "x$enable_flacng" != "xno"; then
- PKG_CHECK_MODULES(LIBFLAC, [flac >= 1.2.1],
- [have_flacng=yes
- INPUT_PLUGINS="$INPUT_PLUGINS flacng"],
- [if test "x$enable_flacng" = "xyes"; then
- AC_MSG_ERROR([Cannot find libFLAC development files (ver >= 1.2.1), but compilation of FLACng plugin has been explicitly requested; please install libFLAC dev files and run configure again])
- fi]
- )
-else
- AC_MSG_RESULT([*** FLACng plugin disabled per user request ***])
+if test $enable_flacng = yes ; then
+ PKG_CHECK_MODULES(LIBFLAC, [flac >= 1.2.1])
+ INPUT_PLUGINS="$INPUT_PLUGINS flacng"
fi
dnl *** WavPack 4.31 support
@@ -400,34 +426,27 @@ else
AC_MSG_RESULT([*** WavPack plugin disabled per user request ***])
fi
-dnl *** AAC
+dnl AAC (enabled by default)
+dnl ========================
AC_ARG_ENABLE(aac,
- [AS_HELP_STRING([--disable-aac], [disable aac plugin (default=enabled)])],
- [enable_aac=$enableval],
- [enable_aac=auto]
-)
+ [AS_HELP_STRING([--disable-aac], [disable AAC support (default=enabled)])],
+ [enable_aac=$enableval], [enable_aac=yes])
-have_aac=no
-if test "x$enable_aac" != "xno"; then
- FAAD_LIBS="-lfaad"
- FAAD_CFLAGS=
-
- AC_CHECK_HEADER([faad.h],
- [AC_CHECK_DECL([FAAD2_VERSION],
- [AC_CHECK_DECL([NeAACDecInit2],
- [AC_CHECK_LIB([faad],[NeAACDecInit2],
- [have_aac=yes
- AC_SUBST(FAAD_CFLAGS)
- AC_SUBST(FAAD_LIBS)
- INPUT_PLUGINS="$INPUT_PLUGINS aac aac-raw"])],
- [], [#include <neaacdec.h>])],
- [], [#include <neaacdec.h>])]
- )
+if test $enable_aac = yes ; then
+ AC_CHECK_HEADER([neaacdec.h], [have_aac=yes], [have_aac=no])
+ AC_CHECK_LIB([faad], [NeAACDecInit2], [have_aac=$have_aac], [have_aac=no])
- if test "x$enable_aac" = "xyes" -a "x$have_aac" != "xyes"; then
- AC_MSG_ERROR([Cannot find faad development files, but compilation of aac plugin has been explicitly requested; please install faad dev files and run configure again])
+ if test $have_aac != yes ; then
+ AC_MSG_ERROR([Please install libfaad, or use --disable-aac to disable AAC support.])
fi
+
+ FAAD_CFLAGS=
+ FAAD_LIBS="-lfaad"
+ AC_SUBST(FAAD_CFLAGS)
+ AC_SUBST(FAAD_LIBS)
+
+ INPUT_PLUGINS="$INPUT_PLUGINS aac-raw"
fi
dnl *** sndfile
@@ -472,21 +491,21 @@ fi
dnl *** FFaudio
-AC_ARG_ENABLE(ffaudio,
- [AS_HELP_STRING([--disable-ffaudio], [disable ffaudio plugin (default=enabled)])],
- [enable_ffaudio=$enableval],
- [enable_ffaudio=auto]
-)
-
-have_ffaudio=no
-if test "x$enable_ffaudio" != "xno"; then
- PKG_CHECK_MODULES([FFMPEG], [libavcodec >= 53.40.0 libavformat >= 53.5.0 libavutil >= 50.42.0],
- [have_ffaudio=yes
- INPUT_PLUGINS="$INPUT_PLUGINS ffaudio"],
- [if test "x$enable_ffaudio" = "xyes"; then
- AC_MSG_ERROR([Cannot find FFmpeg development files (libavcodec ver >= 53.40.0, libavformat ver >= 53.5.0, libavutil ver >= 50.42.0), but compilation of ffaudio plugin has been explicitly requested; please install FFmpeg dev files and run configure again])
- fi]
- )
+AC_ARG_WITH([ffmpeg],
+ AS_HELP_STRING([--with-ffmpeg=ffmpeg,libav,none], [choose between FFmpeg, libav, or neither (default=ffmpeg)]),
+ [ffmpeg_variant=$withval],
+ [ffmpeg_variant=ffmpeg])
+
+if test $ffmpeg_variant = ffmpeg ; then
+ PKG_CHECK_MODULES([FFMPEG], [libavcodec >= 53.40.0 libavformat >= 53.21.0 libavutil >= 51.27.0],
+ [INPUT_PLUGINS="$INPUT_PLUGINS ffaudio"
+ AC_DEFINE([HAVE_FFMPEG], [1], [Define if using FFmpeg])],
+ [AC_MSG_ERROR([FFmpeg is not installed or too old (required: libavcodec 53.40.0, libavformat 53.21.0, libavutil 51.27.0). Use --with-ffmpeg=none to disable the ffaudio plugin or --with-ffmpeg=libav to use libav instead.])])
+elif test $ffmpeg_variant = libav ; then
+ PKG_CHECK_MODULES([FFMPEG], [libavcodec >= 53.25.0 libavformat >= 53.15.0 libavutil >= 51.18.0],
+ [INPUT_PLUGINS="$INPUT_PLUGINS ffaudio"
+ AC_DEFINE([HAVE_LIBAV], [1], [Define if using libav])],
+ [AC_MSG_ERROR([libav is not installed or too old (required: libavcodec 53.25.0, libavformat 53.15.0, libavutil 51.18.0).])])
fi
dnl *** jack output plugin
@@ -505,15 +524,9 @@ if test "x$enable_jack" != "xno"; then
)
if test "x$have_jack" = "xyes"; then
- PKG_CHECK_MODULES([SAMPLERATE], [samplerate],
- [], [have_jack=no]
- )
- fi
-
- if test "x$have_jack" = "xyes"; then
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS jack"
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS jack-ng"
elif test "x$enable_jack" = "xyes"; then
- AC_MSG_ERROR([Cannot find JACK (ver >= 0.120.1 but < 1.0 or >= 1.9.7) or libsamplerate development files, but compilation of JACK output plugin has been explicitly requested; please install JACK and libsamplerate dev files and run configure again])
+ AC_MSG_ERROR([Cannot find JACK (ver >= 0.120.1 but < 1.0 or >= 1.9.7) development files, but compilation of JACK output plugin has been explicitly requested; please install JACK dev files and run configure again])
fi
fi
@@ -539,7 +552,7 @@ dnl OSS output
dnl ==========
AC_ARG_ENABLE(oss4,
- [AS_HELP_STRING([--disable-oss4],[disable OSS4 output plugin])],
+ [AS_HELP_STRING([--disable-oss4], [disable OSS4 output plugin])],
[enable_oss4=$enableval], [enable_oss4=auto])
OSS_CFLAGS=
@@ -552,28 +565,17 @@ if test "x$enable_oss4" != "xno" ; then
OLD_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $OSS_CFLAGS"
- AC_CHECK_HEADERS([sys/soundcard.h soundcard.h])
- AC_MSG_CHECKING(for OSS4)
-
- AC_EGREP_CPP(yes,
- [#ifdef HAVE_SYS_SOUNDCARD_H
- #include <sys/soundcard.h>
- #elif defined HAVE_SOUNDCARD_H
- #include <soundcard.h>
- #endif
- #if OSS_VERSION >= 0x40000 || SOUND_VERSION >= 0x40000
- yes
- #endif],
- [have_oss4=yes
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS oss4"
- AC_SUBST(OSS_CFLAGS)],
- [if test "x$enable_oss4" = "xyes"; then
- AC_MSG_ERROR([Cannot find OSS4 development files, but compilation of OSS4 output plugin has been explicitly requested; please install OSS4 dev files and run configure again])
- fi]
- )
+ AC_CHECK_HEADERS([sys/soundcard.h soundcard.h], [have_oss4=yes])
+ CPPFLAGS="$OLD_CPPFLAGS"
+
+ if test "x$have_oss4" = "xyes" ; then
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS oss4"
+ AC_SUBST(OSS_CFLAGS)
+ elif test "x$enable_oss4" = "xyes" ; then
+ AC_MSG_ERROR([OSS4 output was enabled but soundcard.h was not found])
+ fi
AC_MSG_RESULT([$have_oss4])
- CPPFLAGS="$OLD_CPPFLAGS"
fi
dnl *** ALSA output plugin
@@ -603,17 +605,47 @@ AC_ARG_ENABLE(sdlout,
[AS_HELP_STRING([--disable-sdlout], [disable SDL output plugin])],
[enable_sdlout=$enableval], [enable_sdlout=auto])
+if test "x$enable_sdlout" != "xno"; then
+ AC_ARG_WITH(libsdl,
+ [AS_HELP_STRING([--with-libsdl=VER], [select which SDL version to use. Set VER to 1 for libsdl1, to 2 for libsdl2. @<:@default=check@:>@])],
+ [case "x$withval" in
+ x1) ;;
+ x2) ;;
+ x*) withval=check;;
+ esac
+ with_libsdl=$withval], [with_libsdl=check])
+fi
+
+libsdl1_min="1.2.11";
+libsdl2_min="2.0";
+
have_sdlout=no
if test "x$enable_sdlout" != "xno"; then
- PKG_CHECK_MODULES([SDL], [sdl2 >= 2.0],
- [have_sdlout=yes
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"],
- [PKG_CHECK_MODULES([SDL], [sdl >= 1.2.11],
+ if test "x$with_libsdl" = "xcheck"; then
+ PKG_CHECK_MODULES([SDL], [sdl2 >= $libsdl2_min],
[have_sdlout=yes
OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"],
- [if test "x$enable_sdlout" = "xyes"; then
- AC_MSG_ERROR([Cannot find SDL development files (ver >= 1.2.11), but compilation of SDL output plugin has been explicitly requested; please install SDL dev files and run configure again])
- fi])])
+ [PKG_CHECK_MODULES([SDL], [sdl >= $libsdl1_min],
+ [have_sdlout=yes
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"],
+ [if test "x$enable_sdlout" = "xyes"; then
+ AC_MSG_ERROR([Cannot find SDL development files (ver >= $libsdl1_min), but compilation of SDL output plugin has been explicitly requested; please install SDL dev files and run configure again])
+ fi])])
+ elif test "x$with_libsdl" = "x1"; then
+ PKG_CHECK_MODULES([SDL], [sdl >= $libsdl1_min],
+ [have_sdlout=yes
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"],
+ [if test "x$enable_sdlout" = "xyes"; then
+ AC_MSG_ERROR([Cannot find SDL1 development files (ver >= $libsdl1_min), but compilation of SDL output plugin has been explicitly requested; please install SDL1 dev files and run configure again])
+ fi])
+ elif test "x$with_libsdl" = "x2"; then
+ PKG_CHECK_MODULES([SDL], [sdl2 >= $libsdl2_min],
+ [have_sdlout=yes
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS sdlout"],
+ [if test "x$enable_sdlout" = "xyes"; then
+ AC_MSG_ERROR([Cannot find SDL2 development files (ver >= $libsdl2_min), but compilation of SDL output plugin has been explicitly requested; please install SDL2 dev files and run configure again])
+ fi])
+ fi
fi
dnl *** sndio output
@@ -629,7 +661,7 @@ if test "x$enable_sndio" != "xno"; then
AC_CHECK_HEADER([sndio.h],
[AC_CHECK_LIB([sndio], [sio_open],
[have_sndio=yes
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS sndio"
+ OUTPUT_PLUGINS="$OUTPUT_PLUGINS sndio-ng"
SNDIO_LIBS="-lsndio"
AC_SUBST(SNDIO_LIBS)]
)]
@@ -640,6 +672,13 @@ if test "x$enable_sndio" != "xno"; then
fi
fi
+dnl Check for at least one output plugin (not including filewriter)
+dnl ===============================================================
+
+if test "x$OUTPUT_PLUGINS" = "x" ; then
+ AC_MSG_ERROR([No output plugin was enabled. Please install the necessary packages for your system and run configure again.])
+fi
+
dnl amidi-plug
dnl ==========
@@ -651,7 +690,7 @@ have_amidiplug=no
if test "x$enable_amidiplug" != "xno"; then
PKG_CHECK_MODULES(FLUIDSYNTH, [fluidsynth >= 1.0.6],
[have_amidiplug=yes
- OUTPUT_PLUGINS="$OUTPUT_PLUGINS amidi-plug"],
+ INPUT_PLUGINS="$INPUT_PLUGINS amidi-plug"],
[if test "x$enable_amidiplug" = "xyes"; then
AC_MSG_ERROR([Cannot find FluidSynth development files (ver >= 1.0.6), but compilation of amidi-plug input plugin has been explicitly requested; please install FluidSynth dev files and run configure again])
fi])
@@ -706,25 +745,16 @@ if test "x$enable_scrobbler2" != "xno"; then
)
fi
-dnl *** neon http plugin ***
+dnl neon HTTP support (enabled by default)
+dnl ======================================
AC_ARG_ENABLE(neon,
-[AS_HELP_STRING([--disable-neon], [disable neon HTTP support (default=enabled)])],
-[enable_neon=$enableval],
-[enable_neon=auto])
-
-have_neon=no
-if test "x$enable_neon" != "xno"; then
- PKG_CHECK_MODULES(NEON, [neon >= 0.26],
- [have_neon=yes
- TRANSPORT_PLUGINS="$TRANSPORT_PLUGINS neon"
- AC_CHECK_LIB([neon], [ne_set_connect_timeout], [AC_DEFINE(HAVE_NE_SET_CONNECT_TIMEOUT, 1, [Whether we have ne_set_connect_timeout])], [], [$NEON_LIBS])
- AC_SUBST([NEON_LIBS])
- AC_SUBST([NEON_CFLAGS])],
- [if test "x$enable_neon" = "xyes"; then
- AC_MSG_ERROR([Cannot find neon development files (ver >= 0.26), but compilation of neon HTTP support has been explicitly requested; please install neon dev files and run configure again])
- fi]
- )
+ [AS_HELP_STRING([--disable-neon], [disable neon HTTP support (default=enabled)])],
+ [enable_neon=$enableval], [enable_neon=yes])
+
+if test $enable_neon = yes ; then
+ PKG_CHECK_MODULES(NEON, [neon >= 0.27])
+ TRANSPORT_PLUGINS="$TRANSPORT_PLUGINS neon"
fi
dnl MMS
@@ -806,7 +836,7 @@ fi
dnl Vorbis support reuses test done for Vorbis input plugin.
have_vorbisenc=no
-if test "x$have_filewriter" = "xyes" -a "x$have_vorbis" = "xyes"; then
+if test "x$have_filewriter" = "xyes" -a "x$enable_vorbis" = "xyes"; then
have_vorbisenc=yes
AC_DEFINE(FILEWRITER_VORBIS, 1, [Define if Vorbis output part should be built])
FILEWRITER_CFLAGS="$FILEWRITER_CFLAGS $VORBIS_CFLAGS"
@@ -909,28 +939,6 @@ if test "x$enable_soxr" != "xno"; then
)
fi
-dnl GTK Interface
-dnl =============
-
-AC_ARG_ENABLE(gtkui,
- [AS_HELP_STRING([--disable-gtkui], [disable GTK interface (gtkui)])],
- [enable_gtkui=$enableval], [enable_gtkui="yes"])
-
-if test "x$enable_gtkui" != "xno"; then
- GENERAL_PLUGINS="$GENERAL_PLUGINS gtkui"
-fi
-
-dnl Winamp Classic Interface
-dnl =============
-
-AC_ARG_ENABLE(skins,
- [AS_HELP_STRING([--disable-skins], [disable Winamp Classic interface (skins)])],
- [enable_skins=$enableval], [enable_skins="yes"])
-
-if test "x$enable_skins" != "xno"; then
- GENERAL_PLUGINS="$GENERAL_PLUGINS skins"
-fi
-
dnl LyricWiki
dnl =========
@@ -980,6 +988,83 @@ fi
AC_SUBST(GL_LIBS)
+dnl Qt OpenGL Spectrum Analyzer
+dnl ===========================
+
+AC_ARG_ENABLE(qtglspectrum,
+ [AS_HELP_STRING([--disable-qtglspectrum], [disable Qt OpenGL Spectrum Analyzer (default=enabled)])],
+ [enable_qtglspectrum=$enableval],
+ [enable_qtglspectrum=auto])
+
+have_qtglspectrum=no
+if test "x$USE_QT" = "xno" -a "x$enable_qtglspectrum" = "xyes"; then
+ AC_MSG_ERROR([--enable-qtglspectrum cannot be used without --enable-qt])
+fi
+if test "x$USE_QT" = "xyes" -a "x$enable_qtglspectrum" != "xno"; then
+ PKG_CHECK_MODULES(QTOPENGL, [Qt5OpenGL], [have_qtglspectrum=yes], [have_qtglspectrum=no])
+ if test "x$have_qtglspectrum" = "xyes"; then
+ QTOPENGL_CFLAGS="$QTOPENGL_CFLAGS -fPIC"
+ VISUALIZATION_PLUGINS="$VISUALIZATION_PLUGINS gl-spectrum-qt"
+ elif test "x$enable_qtglspectrum" = "xyes"; then
+ AC_MSG_ERROR([Qt OpenGL Spectrum Analyzer plugin requested but QtOpenGL not found!])
+ fi
+fi
+
+dnl VTX Decoder
+dnl =============
+
+AC_ARG_ENABLE(vtx,
+ [AS_HELP_STRING([--disable-vtx], [disable VTX Decoder])],
+ [enable_vtx=$enableval], [enable_vtx="yes"])
+
+if test "x$enable_vtx" != "xno"; then
+ INPUT_PLUGINS="$INPUT_PLUGINS vtx"
+fi
+
+dnl LADSPA Host
+dnl =============
+
+AC_ARG_ENABLE(ladspa,
+ [AS_HELP_STRING([--disable-ladspa], [disable LADSPA Host])],
+ [enable_ladspa=$enableval], [enable_ladspa="yes"])
+
+if test "x$enable_ladspa" != "xno"; then
+ EFFECT_PLUGINS="$EFFECT_PLUGINS ladspa"
+fi
+
+dnl Blur Scope
+dnl =============
+
+AC_ARG_ENABLE(blur_scope,
+ [AS_HELP_STRING([--disable-blur-scope], [disable Blur Scope])],
+ [enable_blur_scope=$enableval], [enable_blur_scope="yes"])
+
+if test "x$enable_blur_scope" != "xno"; then
+ VISUALIZATION_PLUGINS="$VISUALIZATION_PLUGINS blur_scope"
+fi
+
+dnl Cairo Spectrum Analyzer
+dnl =============
+
+AC_ARG_ENABLE(cairo_spectrum,
+ [AS_HELP_STRING([--disable-cairo-spectrum], [disable Cairo Spectrum Analyzer])],
+ [enable_cairo_spectrum=$enableval], [enable_cairo_spectrum="yes"])
+
+if test "x$enable_cairo_spectrum" != "xno"; then
+ VISUALIZATION_PLUGINS="$VISUALIZATION_PLUGINS cairo-spectrum"
+fi
+
+dnl Mac Media Keys
+dnl ============
+
+AC_ARG_ENABLE(mac_media_keys,
+ [AS_HELP_STRING([--enable-mac-media-keys], [enable Mac Media Keys])],
+ [enable_mac_media_keys=$enableval], [enable_mac_media_keys="no"])
+
+if test "x$enable_mac_media_keys" != "xno"; then
+ GENERAL_PLUGINS="$GENERAL_PLUGINS mac-media-keys"
+fi
+
dnl *** End of all plugin checks ***
plugindir=`pkg-config audacious --variable=plugin_dir`
@@ -1044,9 +1129,11 @@ echo " --------------"
echo " Open Sound System (oss4): $have_oss4"
echo " Advanced Linux Sound Arch. (alsa): $have_alsa"
echo " Sndio (sndio): $have_sndio"
+echo " CoreAudio (coreaudio): $have_coreaudio"
echo " PulseAudio (pulse): $have_pulse"
echo " Jack Audio Connection Kit (jack): $have_jack"
echo " Simple DirectMedia Layer (sdlout): $have_sdlout"
+echo " Qt Multimedia (qtaudio): $have_qtaudio"
echo " FileWriter: $have_filewriter"
echo " -> FileWriter MP3 output part: $have_lame"
echo " -> FileWriter Vorbis output part: $have_vorbisenc"
@@ -1054,16 +1141,16 @@ echo " -> FileWriter FLAC output part: $have_writer_flac"
echo
echo " Input Plugins"
echo " -------------"
-echo " MPEG-1 Layer I/II/III (mpg123): $have_mp3"
-echo " MPEG-2/4 AAC (aac): $have_aac"
-echo " FFaudio (ffaudio): $have_ffaudio"
+echo " MPEG-1 Layer I/II/III (mpg123): $enable_mp3"
+echo " MPEG-2/4 AAC (aac): $enable_aac"
+echo " FFaudio (ffaudio): $ffmpeg_variant"
echo " Module decoder (modplug): $have_modplug"
echo " MIDI synthesizer (amidi-plug): $have_amidiplug"
echo " CD Digital Audio (cdaudio_ng): $have_cdaudio_ng"
echo " sndfile extensions: $have_sndfile"
echo " Tone Generator: yes"
-echo " Ogg Vorbis (vorbis): $have_vorbis"
-echo " Free Lossless Audio Codec (flacng): $have_flacng"
+echo " Ogg Vorbis (vorbis): $enable_vorbis"
+echo " Free Lossless Audio Codec (flacng): $enable_flacng"
echo " Commodore 64 audio (SID): $have_sidplay"
echo " Game music (spc, nsf & gbs): $have_console"
echo " PlayStation (psf/psf2) audio: $enable_psf"
@@ -1071,17 +1158,19 @@ echo " Nintendo DS audio (xsf): $enable_xsf"
echo " AdLib synthesizer (adplug): $have_adplug"
echo " WavPack 4.31+ (wavpack): $have_wavpack"
echo " Metronom: yes"
+echo " VTX Decoder: $enable_vtx"
echo
echo " General"
echo " -------"
-echo " Alarm: yes"
-echo " Album Art: yes"
-echo " Delete from Filesystem: yes"
+echo " Alarm: $USE_GTK"
+echo " Album Art: $USE_GTK"
+echo " Delete from Filesystem: $USE_GTK"
echo " Linux Infrared Remote Control (LIRC) $have_lirc"
echo " MPRIS 2 Server: $have_mpris2"
-echo " Search Tool: yes"
+echo " Playlist Manager: $USE_GTK"
+echo " Search Tool: $USE_GTK"
echo " Song Change: $have_songchange"
-echo " Status Icon: $have_statusicon"
+echo " Status Icon: $USE_GTK"
echo " Audacious OSD: $have_aosd"
echo " -> X Composite support: $have_aosd_xcomp"
echo " libnotify OSD: $have_notify"
@@ -1089,6 +1178,7 @@ echo " Global Hotkey Plugin: $have_hotkey"
echo " Gnome Shortcuts Plugin: $have_gnomeshortcuts"
echo " Scrobbler 2.0: $have_scrobbler2"
echo " LyricWiki viewer: $have_lyricwiki"
+echo " Mac Media Keys: $enable_mac_media_keys"
echo
echo " Effect"
echo " ------"
@@ -1097,22 +1187,24 @@ echo " Crystalizer: yes"
echo " Dynamic Range Compressor: yes"
echo " Echo/Surround: yes"
echo " Extra Stereo: yes"
-echo " LADSPA Host: yes"
+echo " LADSPA Host: $enable_ladspa"
echo " Voice Removal: yes"
echo " Bauer stereophonic-to-binaural (bs2b): $have_bs2b"
echo " Sample Rate Converter (resample): $have_resample"
+echo " Silence Removal: yes"
echo " Speed and Pitch: $have_speedpitch"
echo " SoX Resampler: $have_soxr"
echo
echo " Visualization"
echo " -------------"
-echo " Blur Scope: yes"
-echo " Cairo Spectrum Analyzer: yes"
-echo " OpenGL Spectrum Analyzer: $have_glspectrum"
+echo " Blur Scope: $enable_blur_scope"
+echo " Cairo Spectrum Analyzer: $enable_cairo_spectrum"
+echo " GTK+ OpenGL Spectrum Analyzer: $have_glspectrum"
+echo " Qt OpenGL Spectrum Analyzer: $have_qtglspectrum"
echo
echo " Transport"
echo " ---------"
-echo " neon-based http/https: $have_neon"
+echo " neon-based http/https: $enable_neon"
echo " libmms-based mms: $have_mms"
echo " GIO: yes"
echo
@@ -1128,6 +1220,7 @@ echo " CUE playlist format (cue): $have_cue"
echo
echo " Interfaces"
echo " ----------"
-echo " GTK (gtkui): $enable_gtkui"
-echo " Winamp Classic (skins): $enable_skins"
+echo " GTK (gtkui): $USE_GTK"
+echo " Qt (qtui): $USE_QT"
+echo " Winamp Classic (skins): $USE_GTK"
echo
diff --git a/debian/changelog b/debian/changelog
index f9fc1f5689ef..9d877c7f462b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+audacious-plugins (3.6.1-0.1) UNRELEASED; urgency=medium
+
+ * Non-maintainer upload.
+ * New upstream version.
+
+ -- Julian Wollrath <jwollrath at web.de> Sun, 03 May 2015 13:00:41 +0200
+
audacious-plugins (3.5-1) unstable; urgency=low
[ Alin Andrei ]
diff --git a/extra.mk.in b/extra.mk.in
index 3beebf95be79..7c2ec0cdfe84 100644
--- a/extra.mk.in
+++ b/extra.mk.in
@@ -16,6 +16,9 @@ TRANSPORT_PLUGINS ?= @TRANSPORT_PLUGINS@
VISUALIZATION_PLUGINS ?= @VISUALIZATION_PLUGINS@
VISUALIZATION_PLUGIN_DIR ?= @VISUALIZATION_PLUGIN_DIR@
+USE_GTK ?= @USE_GTK@
+USE_QT ?= @USE_QT@
+
ALSA_CFLAGS ?= @ALSA_CFLAGS@
ALSA_LIBS ?= @ALSA_LIBS@
BINIO_CFLAGS ?= @BINIO_CFLAGS@
@@ -75,6 +78,12 @@ SIDPLAYFP_LIBS ?= @SIDPLAYFP_LIBS@
SNDFILE_CFLAGS ?= @SNDFILE_CFLAGS@
SNDFILE_LIBS ?= @SNDFILE_LIBS@
SNDIO_LIBS ?= @SNDIO_LIBS@
+QT_CFLAGS ?= @QT_CFLAGS@
+QT_LIBS ?= @QT_LIBS@
+QTMULTIMEDIA_CFLAGS ?= @QTMULTIMEDIA_CFLAGS@
+QTMULTIMEDIA_LIBS ?= @QTMULTIMEDIA_LIBS@
+QTOPENGL_CFLAGS ?= @QTOPENGL_CFLAGS@
+QTOPENGL_LIBS ?= @QTOPENGL_LIBS@
VORBIS_CFLAGS ?= @VORBIS_CFLAGS@
VORBIS_LIBS ?= @VORBIS_LIBS@
WAVPACK_CFLAGS ?= @WAVPACK_CFLAGS@
@@ -85,3 +94,7 @@ XML_CFLAGS ?= @XML_CFLAGS@
XML_LIBS ?= @XML_LIBS@
XRENDER_CFLAGS ?= @XRENDER_CFLAGS@
XRENDER_LIBS ?= @XRENDER_LIBS@
+
+HAVE_LINUX ?= @HAVE_LINUX@
+HAVE_MSWINDOWS ?= @HAVE_MSWINDOWS@
+HAVE_DARWIN ?= @HAVE_DARWIN@
diff --git a/m4/buildsys.m4 b/m4/buildsys.m4
index 6afd8c6a0fdb..6a9af41c3b6a 100644
--- a/m4/buildsys.m4
+++ b/m4/buildsys.m4
@@ -108,15 +108,15 @@ AC_DEFUN([BUILDSYS_SHARED_LIB], [
case "$host_os" in
darwin*)
AC_MSG_RESULT(Darwin)
- LIB_CFLAGS='-fPIC -DPIC'
- LIB_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}'
+ LIB_CFLAGS='-fPIC -DPIC -mmacosx-version-min=10.7'
+ LIB_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR} -mmacosx-version-min=10.7 -install_name "${libdir}/$$(i=${SHARED_LIB}; echo $${i%${LIB_SUFFIX}}).${LIB_MAJOR}${LIB_SUFFIX}"'
LIB_PREFIX='lib'
LIB_SUFFIX='.dylib'
LDFLAGS_RPATH='-Wl,-rpath,${libdir}'
- PLUGIN_CFLAGS='-fPIC -DPIC'
- PLUGIN_LDFLAGS='-bundle -undefined dynamic_lookup'
+ PLUGIN_CFLAGS='-fPIC -DPIC -mmacosx-version-min=10.7'
+ PLUGIN_LDFLAGS='-bundle -undefined dynamic_lookup -mmacosx-version-min=10.7'
PLUGIN_SUFFIX='.bundle'
- INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && install_name_tool -id ${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$$i'
+ INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$$i'
UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib'
CLEAN_LIB=''
;;
diff --git a/po/Makefile b/po/Makefile
index 203b04d40a4b..6c827daa4d58 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -34,6 +34,8 @@ LOCALES = be.po \
lt.po \
lv.po \
ml_IN.po \
+ ms.po \
+ nl.po \
pl.po \
pt_BR.po \
pt_PT.po \
@@ -42,6 +44,7 @@ LOCALES = be.po \
sk.po \
sr.po \
sr_RS.po \
+ sv.po \
ta.po \
tr.po \
uk.po \
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 2028d6e614da..65eb00da6c6a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,129 +1,180 @@
# Please don't update this file manually - use ./update-potfiles.sh instead!
-src/aac/libmp4.c
-src/aac-raw/aac.c
+src/aac-raw/aac.cc
src/adplug/adplug-xmms.cc
-src/adplug/plugin.c
-src/alarm/alarm.c
-src/alarm/interface.c
-src/albumart/albumart.c
-src/alsa/config.c
-src/alsa/plugin.c
-src/amidi-plug/amidi-plug.c
-src/amidi-plug/i_configure.c
-src/amidi-plug/i_configure-fluidsynth.c
-src/amidi-plug/i_fileinfo.c
-src/amidi-plug/i_utils.c
-src/aosd/aosd.c
-src/aosd/aosd_style.c
-src/aosd/aosd_trigger.c
-src/aosd/aosd_ui.c
-src/asx3/asx3.c
-src/asx/asx.c
-src/audpl/audpl.c
-src/blur_scope/blur_scope.c
-src/bs2b/plugin.c
-src/cairo-spectrum/cairo-spectrum.c
-src/cdaudio-ng/cdaudio-ng.c
-src/cd-menu-items/cd-menu-items.c
-src/compressor/plugin.c
-src/console/Ay_Apu.cxx
-src/console/Ay_Emu.cxx
-src/console/Blip_Buffer.cxx
-src/console/Classic_Emu.cxx
-src/console/Data_Reader.cxx
-src/console/Dual_Resampler.cxx
-src/console/Fir_Resampler.cxx
-src/console/Gbs_Emu.cxx
-src/console/Gme_File.cxx
-src/console/Gym_Emu.cxx
-src/console/Gzip_Reader.cxx
-src/console/Hes_Emu.cxx
-src/console/Kss_Emu.cxx
-src/console/M3u_Playlist.cxx
-src/console/Multi_Buffer.cxx
-src/console/Music_Emu.cxx
-src/console/Nes_Apu.cxx
-src/console/Nsfe_Emu.cxx
-src/console/Nsf_Emu.cxx
-src/console/plugin.c
-src/console/Sap_Emu.cxx
-src/console/Spc_Cpu.cxx
-src/console/Spc_Dsp.cxx
-src/console/Spc_Emu.cxx
-src/console/Vgm_Emu.cxx
-src/console/Ym2612_Emu.cxx
-src/crossfade/crossfade.c
-src/crystalizer/crystalizer.c
-src/cue/cue.c
-src/delete-files/delete-files.c
-src/echo_plugin/echo.c
-src/ffaudio/ffaudio-core.c
-src/filewriter/filewriter.c
-src/filewriter/mp3.c
-src/filewriter/vorbis.c
-src/flacng/metadata.c
-src/flacng/plugin.c
-src/gio/gio.c
-src/gl-spectrum/gl-spectrum.c
-src/gnomeshortcuts/gnomeshortcuts.c
-src/gtkui/columns.c
-src/gtkui/layout.c
-src/gtkui/menus.c
-src/gtkui/settings.c
-src/gtkui/ui_gtk.c
-src/gtkui/ui_playlist_widget.c
-src/gtkui/ui_statusbar.c
-src/hotkey/gui.c
-src/hotkey/plugin.c
-src/jack/bio2jack.c
-src/jack/jack.c
-src/ladspa/plugin.c
-src/lirc/lirc.c
-src/lyricwiki/lyricwiki.c
-src/m3u/m3u.c
-src/metronom/metronom.c
-src/mixer/mixer.c
-src/mms/mms.c
-src/modplug/modplugbmp.cxx
-src/modplug/plugin_main.c
-src/mpg123/mpg123.c
-src/mpris2/plugin.c
-src/neon/neon.c
-src/notify/event.c
-src/notify/notify.c
-src/notify/osd.c
-src/oss4/plugin.c
-src/pls/pls.c
-src/psf/plugin.c
-src/pulse_audio/pulse_audio.c
-src/resample/resample.c
-src/scrobbler2/config_window.c
-src/scrobbler2/scrobbler.c
-src/scrobbler2/scrobbler_communication.c
-src/sdlout/plugin.c
-src/search-tool/search-tool.c
-src/skins/menus.c
-src/skins/plugin.c
-src/skins/preset-browser.c
-src/skins/preset-list.c
-src/skins/skins_cfg.c
-src/skins/ui_equalizer.c
-src/skins/ui_main.c
-src/skins/ui_main_evlisteners.c
-src/skins/ui_playlist.c
-src/skins/ui_skinselector.c
-src/skins/util.c
-src/sndfile/plugin.c
-src/sndio/sndio.c
-src/song_change/song_change.c
-src/sox-resampler/sox-resampler.c
-src/speed-pitch/speed-pitch.c
-src/statusicon/statusicon.c
-src/stereo_plugin/stereo.c
-src/tonegen/tonegen.c
-src/voice_removal/voice_removal.c
-src/vorbis/vorbis.c
-src/vtx/vtx.c
-src/wavpack/wavpack.c
-src/xsf/plugin.c
-src/xspf/xspf.c
+src/adplug/core/rix.h
+src/alarm/alarm.cc
+src/alarm/interface.cc
+src/albumart/albumart.cc
+src/albumart-qt/albumart.cc
+src/alsa/alsa.h
+src/alsa/config.cc
+src/amidi-plug/amidi-plug.cc
+src/amidi-plug/i_configure.cc
+src/amidi-plug/i_configure-fluidsynth.cc
+src/amidi-plug/i_fileinfo.cc
+src/aosd/aosd.cc
+src/aosd/aosd.h
+src/aosd/aosd_style.cc
+src/aosd/aosd_trigger.cc
+src/aosd/aosd_ui.cc
+src/asx3/asx3.cc
+src/asx/asx.cc
+src/audpl/audpl.cc
+src/blur_scope/blur_scope.cc
+src/bs2b/plugin.cc
+src/cairo-spectrum/cairo-spectrum.cc
+src/cdaudio-ng/cdaudio-ng.cc
+src/cd-menu-items/cd-menu-items.cc
+src/compressor/compressor.cc
+src/console/Ay_Apu.cc
+src/console/Ay_Apu.h
+src/console/Ay_Emu.cc
+src/console/Ay_Emu.h
+src/console/blargg_common.h
+src/console/blargg_source.h
+src/console/Blip_Buffer.cc
+src/console/Blip_Buffer.h
+src/console/Classic_Emu.cc
+src/console/Classic_Emu.h
+src/console/Data_Reader.cc
+src/console/Dual_Resampler.cc
+src/console/Dual_Resampler.h
+src/console/Fir_Resampler.cc
+src/console/Fir_Resampler.h
+src/console/gb_cpu_io.h
+src/console/Gbs_Emu.cc
+src/console/Gbs_Emu.h
+src/console/Gme_File.cc
+src/console/Gme_File.h
+src/console/Gym_Emu.cc
+src/console/Gym_Emu.h
+src/console/Gzip_Reader.cc
+src/console/Gzip_Reader.h
+src/console/hes_cpu_io.h
+src/console/Hes_Emu.cc
+src/console/Hes_Emu.h
+src/console/Kss_Emu.cc
+src/console/Kss_Emu.h
+src/console/M3u_Playlist.cc
+src/console/M3u_Playlist.h
+src/console/Multi_Buffer.cc
+src/console/Music_Emu.cc
+src/console/Music_Emu.h
+src/console/Nes_Apu.cc
+src/console/Nes_Apu.h
+src/console/Nsfe_Emu.cc
+src/console/Nsfe_Emu.h
+src/console/Nsf_Emu.cc
+src/console/Nsf_Emu.h
+src/console/plugin.cc
+src/console/plugin.h
+src/console/sap_cpu_io.h
+src/console/Sap_Emu.cc
+src/console/Sap_Emu.h
+src/console/Snes_Spc.h
+src/console/Spc_Cpu.cc
+src/console/Spc_Cpu.h
+src/console/Spc_Dsp.cc
+src/console/Spc_Emu.cc
+src/console/Spc_Emu.h
+src/console/Vgm_Emu.cc
+src/console/Vgm_Emu.h
+src/console/Ym2612_Emu.cc
+src/coreaudio/coreaudio.cc
+src/crossfade/crossfade.cc
+src/crystalizer/crystalizer.cc
+src/cue/cue.cc
+src/delete-files/delete-files.cc
+src/echo_plugin/echo.cc
+src/ffaudio/ffaudio-core.cc
+src/filewriter/filewriter.cc
+src/filewriter/mp3.cc
+src/filewriter/vorbis.cc
+src/flacng/flacng.h
+src/flacng/metadata.cc
+src/flacng/plugin.cc
+src/gio/gio.cc
+src/gl-spectrum/gl-spectrum.cc
+src/gl-spectrum-qt/gl-spectrum.cc
+src/gnomeshortcuts/gnomeshortcuts.cc
+src/gtkui/columns.cc
+src/gtkui/layout.cc
+src/gtkui/menus.cc
+src/gtkui/settings.cc
+src/gtkui/ui_gtk.cc
+src/gtkui/ui_playlist_widget.cc
+src/gtkui/ui_statusbar.cc
+src/hotkey/gui.cc
+src/hotkey/plugin.cc
+src/jack-ng/jack-ng.cc
+src/ladspa/plugin.cc
+src/ladspa/plugin.h
+src/lirc/lirc.cc
+src/lyricwiki/lyricwiki.cc
+src/lyricwiki-qt/lyricwiki.cc
+src/m3u/m3u.cc
+src/metronom/metronom.cc
+src/mixer/mixer.cc
+src/mms/mms.cc
+src/modplug/modplugbmp.cc
+src/modplug/modplugbmp.h
+src/modplug/plugin_main.cc
+src/mpg123/mpg123.cc
+src/mpris2/plugin.cc
+src/neon/neon.cc
+src/notify/event.cc
+src/notify/notify.cc
+src/notify/osd.cc
+src/oss4/oss.h
+src/oss4/plugin.cc
+src/playlist-manager/playlist-manager.cc
+src/pls/pls.cc
+src/psf/plugin.cc
+src/psf/psx.h
+src/pulse_audio/pulse_audio.cc
+src/qtaudio/qtaudio.cc
+src/qtui/dialog_windows.cc
+src/qtui/filter_input.cc
+src/qtui/main_window_actions.cc
+src/qtui/main_window.cc
+src/qtui/playlist_model.cc
+src/qtui/qtui.cc
+src/qtui/status_bar.cc
+src/resample/resample.cc
+src/scrobbler2/config_window.cc
+src/scrobbler2/scrobbler.cc
+src/scrobbler2/scrobbler_communication.cc
+src/sdlout/sdlout.cc
+src/search-tool/search-tool.cc
+src/sid/xmms-sid.cc
+src/sid/xs_config.cc
+src/silence-removal/silence-removal.cc
+src/skins/menus.cc
+src/skins/plugin.cc
+src/skins/preset-browser.cc
+src/skins/preset-list.cc
+src/skins/skins_cfg.cc
+src/skins/ui_equalizer.cc
+src/skins/ui_main.cc
+src/skins/ui_main_evlisteners.cc
+src/skins/ui_playlist.cc
+src/skins/ui_skinselector.cc
+src/skins/util.cc
+src/sndfile/plugin.cc
+src/sndio-ng/sndio.cc
+src/song_change/song_change.cc
+src/song-info-qt/song-info.cc
+src/sox-resampler/sox-resampler.cc
+src/speed-pitch/speed-pitch.cc
+src/statusicon/statusicon.cc
+src/stereo_plugin/stereo.cc
+src/tonegen/tonegen.cc
+src/voice_removal/voice_removal.cc
+src/vorbis/vorbis.cc
+src/vorbis/vorbis.h
+src/vtx/info.cc
+src/vtx/vtx.cc
+src/wavpack/wavpack.cc
+src/xsf/desmume/types.h
+src/xsf/plugin.cc
+src/xspf/xspf.cc
diff --git a/po/audacious-plugins.pot b/po/audacious-plugins.pot
index ff95c3deb993..f8c64fd52001 100644
--- a/po/audacious-plugins.pot
+++ b/po/audacious-plugins.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:13+0200\n"
+"POT-Creation-Date: 2015-04-03 11:54+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
"Language-Team: LANGUAGE <LL at li.org>\n"
@@ -18,51 +18,35 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr ""
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr ""
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr ""
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
+#: src/aac-raw/aac.cc:18
+msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/aac-raw/aac.c:476
-msgid "AAC (Raw) Decoder"
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr ""
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
msgstr ""
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr ""
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -85,7 +69,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -107,7 +91,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -121,360 +105,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr ""
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr ""
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr ""
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr ""
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr ""
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr ""
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr ""
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr ""
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr ""
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr ""
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr ""
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr ""
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr ""
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr ""
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr ""
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr ""
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr ""
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr ""
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr ""
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr ""
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr ""
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr ""
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr ""
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr ""
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr ""
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr ""
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr ""
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr ""
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr ""
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr ""
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr ""
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr ""
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr ""
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr ""
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr ""
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr ""
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr ""
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr ""
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr ""
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr ""
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
msgstr ""
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr ""
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr ""
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -485,261 +475,258 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr ""
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr ""
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr ""
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr ""
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr ""
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr ""
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr ""
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr ""
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr ""
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr ""
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr ""
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr ""
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr ""
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr ""
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr ""
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr ""
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr ""
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr ""
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr ""
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr ""
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr ""
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr ""
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr ""
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr ""
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr ""
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr ""
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr ""
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr ""
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr ""
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr ""
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr ""
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr ""
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr ""
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
"manager otherwise the OSD won't work properly"
msgstr ""
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr ""
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr ""
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr ""
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr ""
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr ""
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr ""
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr ""
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr ""
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr ""
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr ""
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr ""
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr ""
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr ""
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr ""
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr ""
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr ""
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr ""
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
msgstr ""
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
msgstr ""
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
msgstr ""
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
msgstr ""
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -751,169 +738,156 @@ msgid ""
"This was a Google Summer of Code 2007 project."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr ""
-#: src/cd-menu-items/cd-menu-items.c:31
-msgid "Play CD"
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
msgstr ""
-#: src/cd-menu-items/cd-menu-items.c:31
-msgid "Add CD"
+#: src/cd-menu-items/cd-menu-items.cc:47
+msgid "Play CD"
msgstr ""
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
+#: src/cd-menu-items/cd-menu-items.cc:47
+msgid "Add CD"
msgstr ""
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr ""
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr ""
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr ""
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr ""
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -923,195 +897,220 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr ""
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr ""
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr ""
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr ""
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr ""
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr ""
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr ""
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr ""
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr ""
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr ""
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr ""
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr ""
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr ""
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr ""
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr ""
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr ""
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr ""
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr ""
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr ""
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr ""
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr ""
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr ""
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
+#: src/echo_plugin/echo.cc:39
+msgid "Echo"
msgstr ""
-#: src/echo_plugin/echo.c:122
-msgid "Echo"
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1121,55 +1120,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
msgstr ""
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr ""
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr ""
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr ""
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr ""
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr ""
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr ""
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1187,165 +1186,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr ""
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr ""
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr ""
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr ""
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr ""
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr ""
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr ""
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr ""
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr ""
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr ""
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr ""
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr ""
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr ""
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr ""
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr ""
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr ""
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr ""
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr ""
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr ""
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr ""
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr ""
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr ""
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr ""
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr ""
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr ""
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr ""
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr ""
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr ""
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr ""
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr ""
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr ""
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr ""
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr ""
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1353,21 +1356,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr ""
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1379,530 +1386,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr ""
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr ""
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr ""
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr ""
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr ""
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr ""
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr ""
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr ""
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr ""
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr ""
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr ""
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr ""
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr ""
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr ""
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr ""
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr ""
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr ""
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr ""
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr ""
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr ""
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr ""
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr ""
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr ""
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr ""
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr ""
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr ""
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr ""
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr ""
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr ""
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr ""
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr ""
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr ""
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr ""
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr ""
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr ""
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr ""
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr ""
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr ""
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr ""
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr ""
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr ""
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr ""
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr ""
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr ""
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr ""
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr ""
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr ""
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr ""
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr ""
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr ""
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr ""
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr ""
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr ""
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr ""
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr ""
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr ""
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr ""
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr ""
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr ""
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr ""
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr ""
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr ""
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr ""
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr ""
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr ""
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr ""
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr ""
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr ""
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr ""
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr ""
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr ""
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr ""
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr ""
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr ""
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr ""
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr ""
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr ""
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr ""
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] ""
msgstr[1] ""
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr ""
-#: src/hotkey/gui.c:70
-msgid "Previous track"
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
msgstr ""
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
-msgid "Play"
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
msgstr ""
-#: src/hotkey/gui.c:72
-msgid "Pause/Resume"
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
msgstr ""
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:71
+msgid "Previous track"
+msgstr ""
+
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
+msgid "Play"
+msgstr ""
+
+#: src/hotkey/gui.cc:73
+msgid "Pause/Resume"
+msgstr ""
+
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr ""
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr ""
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr ""
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr ""
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr ""
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr ""
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr ""
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr ""
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1910,37 +1994,37 @@ msgid ""
"Do you want to continue?"
msgstr ""
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr ""
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr ""
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
msgstr ""
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr ""
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr ""
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr ""
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr ""
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1955,124 +2039,90 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
msgstr ""
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
-msgstr ""
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr ""
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr ""
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr ""
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
"After adding new paths, press Enter to scan for new plugins.</small>"
msgstr ""
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr ""
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr ""
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr ""
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr ""
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr ""
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr ""
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr ""
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr ""
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr ""
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
msgstr ""
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2088,73 +2138,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr ""
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr ""
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr ""
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
-#, c-format
-msgid "Unable to fetch %s"
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
+#, c-format
+msgid "Unable to fetch %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr ""
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr ""
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr ""
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr ""
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2163,162 +2221,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
msgstr ""
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr ""
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr ""
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
+#: src/mms/mms.cc:35
+msgid "MMS Plugin"
msgstr ""
-#: src/mms/mms.c:195
-msgid "MMS Plugin"
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
msgstr ""
-#: src/modplug/plugin_main.c:55
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr ""
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr ""
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr ""
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr ""
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr ""
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr ""
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
msgstr ""
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
+#: src/mpg123/mpg123.cc:54
+msgid "MPG123 Plugin"
msgstr ""
-#: src/mpg123/mpg123.c:412
-msgid "MPG123 Plugin"
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
msgstr ""
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr ""
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr ""
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr ""
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr ""
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr ""
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr ""
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2338,55 +2428,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr ""
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr ""
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr ""
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr ""
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr ""
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr ""
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr ""
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2395,19 +2494,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
msgstr ""
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr ""
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr ""
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr ""
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2427,143 +2542,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
msgstr ""
-#: src/resample/resample.c:165
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr ""
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr ""
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr ""
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr ""
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr ""
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr ""
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr ""
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr ""
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr ""
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr ""
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr ""
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr ""
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr ""
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr ""
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr ""
-#: src/resample/resample.c:204
-msgid "192 kHz:"
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
msgstr ""
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
+#: src/resample/resample.cc:241
+msgid "192 kHz:"
msgstr ""
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr ""
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr ""
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2574,765 +2758,840 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr ""
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr ""
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr ""
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr ""
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr ""
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-
-#: src/search-tool/search-tool.c:631
-#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
+msgid "%d result"
+msgid_plural "%d results"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr ""
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr ""
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr ""
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr ""
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr ""
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr ""
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr ""
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr ""
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr ""
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr ""
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr ""
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr ""
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr ""
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr ""
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr ""
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr ""
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr ""
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr ""
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr ""
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr ""
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr ""
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr ""
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr ""
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr ""
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr ""
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr ""
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr ""
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
msgstr ""
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr ""
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr ""
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr ""
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr ""
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr ""
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr ""
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr ""
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr ""
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr ""
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr ""
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr ""
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr ""
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr ""
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr ""
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr ""
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr ""
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr ""
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr ""
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr ""
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr ""
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr ""
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr ""
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr ""
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr ""
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr ""
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr ""
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr ""
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr ""
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr ""
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr ""
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr ""
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr ""
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr ""
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr ""
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr ""
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr ""
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr ""
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr ""
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr ""
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr ""
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr ""
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr ""
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr ""
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr ""
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr ""
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr ""
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr ""
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr ""
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr ""
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr ""
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr ""
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr ""
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr ""
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr ""
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr ""
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr ""
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr ""
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr ""
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr ""
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr ""
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr ""
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr ""
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr ""
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr ""
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3340,57 +3599,61 @@ msgid ""
"for."
msgstr ""
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr ""
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr ""
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr ""
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr ""
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr ""
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr ""
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr ""
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3412,75 +3675,69 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
msgstr ""
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
msgstr ""
-#: src/sndio/sndio.c:384
-msgid "sndio device"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
+#: src/song_change/song_change.cc:33
+msgid "Song Change"
msgstr ""
-#: src/song_change/song_change.c:54
-msgid "Song Change"
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
msgstr ""
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3495,17 +3752,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-#: src/song_change/song_change.c:490
-msgid "Commands"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3514,51 +3769,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
msgstr ""
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3569,63 +3824,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr ""
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr ""
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr ""
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr ""
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr ""
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr ""
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
msgstr ""
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr ""
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
msgstr ""
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr ""
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr ""
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3634,15 +3889,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr ""
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr ""
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3663,44 +3914,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr ""
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr ""
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
msgstr ""
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr ""
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr ""
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
+#: src/xsf/plugin.cc:50
+msgid "2SF Decoder"
msgstr ""
-#: src/xsf/plugin.c:217
-msgid "2SF Decoder"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
msgstr ""
-#: src/xspf/xspf.c:438
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr ""
diff --git a/po/be.po b/po/be.po
index d0302f411432..9e4d60303b6f 100644
--- a/po/be.po
+++ b/po/be.po
@@ -7,11 +7,11 @@
# debconf <prach.by at gmail.com>, 2014
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Belarusian (http://www.transifex.com/projects/p/audacious/"
"language/be/)\n"
"Language: be\n"
@@ -21,51 +21,35 @@ msgstr ""
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "мона"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "ÑÑÑÑÑа"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr ""
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib ÐлÑеÑ)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr ""
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib ÐлÑеÑ)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "ÐлÑÑм"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "ÐлÑÑм"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -88,7 +72,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -110,7 +94,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -124,360 +108,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "ÐÑÑа Ð²Ð°Ñ Ð²ÑклÑк абÑджÑннÑ."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr ""
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "ÐапамÑн"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "ÐанÑдзелак"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "ÐÑÑоÑак"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "СеÑада"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "ЧаÑвеÑ"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "ÐÑÑнÑÑа"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "СÑбоÑа"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "ÐÑдзелÑ"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "ÐÐ°Ð»Ð°Ð´ÐºÑ Ð°Ð»ÑÑмаÑ"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "ЧаÑ"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "ÐлÑÑм Ñ ÑÐ°Ñ (па-змоÑÑваннÑ):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "г"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "СÑÑÑÑÑÑ Ð¿Ð°ÑлÑ:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "гадзÑн"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "Ñ
вÑлÑн"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "ÐбÑÑÑÑе Ð´Ð½Ñ Ð´Ð»Ñ ÑжÑÐ²Ð°Ð½Ð½Ñ Ð°Ð»ÑÑмаÑ"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "ÐзенÑ"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Ðа-змоÑÑваннÑ"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "ÐзÑн"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "ÐгаÑанне"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "ÑекÑнд"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "ÐÑÑнаÑÑÑ"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "ÐаÑаÑÑ Ñ"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "ФÑналÑнÑ"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "ÐÑгÑÑÑ"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "ÐадаÑÐºÐ¾Ð²Ñ Ð·Ð°Ð³Ð°Ð´"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "ÑклÑÑÑÑÑ"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "ÐлÑйлÑÑÑ (апÑÑÑналÑнÑ)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "ÐÑбÑаÑÑ Ð¿Ð»ÑйлÑÑÑ"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "ÐпÑÑÑ"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "ШÑо азнаÑаÑÑÑ Ð³ÑÑÑÑ Ð¾Ð¿ÑÑÑ?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Ðаведка"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "ÐÑаÑмленне алÑбома"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ÐÑвад ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "ТÑÐ¿Ð¾Ð²Ð°Ñ PCM-пÑÑлада"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "ТÑÐ¿Ð¾Ð²Ð°Ñ Ð¿ÑÑлада мÑкÑаÑа"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM пÑÑлада:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "ÐÑÑлада мÑкÑаÑа:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "ÐÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼ÑкÑаÑа:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "ÐпÑаÑоÑваÑÑ Ð±ÑÑÑÑ Ð·Ð°Ð²ÑÑаннÑ"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr ""
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ÐÑвад ALSA"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "ÐÑ"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "Ðазва Ñайла"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "ÐÐ¼Ñ Ñайла"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "ÐÐ°Ð¼ÐµÑ (байÑаÑ)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Ðазва:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> ÐвеÑÑÐºÑ Ð¿Ð° MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "ФаÑмаÑ:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "ÐаÑжÑÐ½Ñ (мÑек):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "ÐÑм. ÑÑÑкаÑ:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "пеÑаменнÑ"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "УÐÐ¥:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "УÐÐ¥ (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI ÐаменÑаÑÑ Ñ ÐÑÑÑка </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr " * Ñ Ð³ÑÑÑм MIDI-Ñайле каменÑаÑÑÑ Ð½ÐµÐ´Ð°ÑÑÑпнÑÑ *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* Ñ Ð³ÑÑÑм MIDI-Ñайле лÑÑÑка недаÑÑÑÐ¿Ð½Ð°Ñ *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "ÐакÑÑ_ÑÑ"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr "(недапÑÑÑалÑÐ½Ñ UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -488,152 +478,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr ""
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ÐÑамавÑголÑнÑк"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "СкÑÑÐ³Ð»ÐµÐ½Ñ ÐÑамавÑголÑнÑк"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "УвагнÑÑÑ ÐÑамавÑголÑнÑк"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "ÐÑма"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "СÑаÑÑ ÐÑайгÑаваннÑ"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "ÐÑводзÑÑÑ OSD ÐºÐ°Ð»Ñ Ð¿ÑÐ½ÐºÑ Ð¿Ð»ÑйлÑÑÑа пÑайгÑаваеÑÑа."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Ðмена ÐазвÑ"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"ÐÑводзÑÑÑ OSD, ÐºÐ°Ð»Ñ Ð¿Ð°Ð´ÑÐ°Ñ Ð¿ÑайгÑÐ°Ð²Ð°Ð½Ð½Ñ Ð·Ð¼ÑнÑеÑÑа назва пеÑнÑ, але ÑÐ¼Ñ Ñайла "
-"заÑÑаеÑÑа ÑанейÑÑм. ÐÑÑа Ñ Ð°ÑноÑнÑм каÑÑÑна Ð´Ð»Ñ Ð²ÑÐ²Ð°Ð´Ñ Ð·Ð¼ÐµÐ½Ð°Ñ Ñ ÑнÑÑÑнÑÑ-"
-"ÑÑанÑлÑÑÑÑÑ
."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "ÐаÑза УÐÐ."
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "ÐÑводзÑÑÑ OSD ÐºÐ°Ð»Ñ Ð¿ÑайгÑаванне на паÑзе."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "ÐаÑза ÐЫÐÐ."
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "ÐÑводзÑÑÑ OSD ÐºÐ°Ð»Ñ Ð¿ÑайÑаванне пÑаÑÑгваеÑÑа з паÑзÑ."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "ÐмÑÑÑÑнне"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "ÐÑÑÑÑнне адноÑна X:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "ÐÑÑÑÑнне адноÑна Y:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "ÐакÑÑмалÑÐ½Ð°Ñ ÑÑÑÑÐ½Ñ OSD:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "ÐпÑÑÑ Ð´Ð»Ñ Ð½ÐµÐºÐ°Ð»ÑкÑÑ
манÑÑоÑаÑ"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "ÐаказваÑÑ OSD пÑаз:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "ÑÑе манÑÑоÑÑ"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "манÑÑÐ¾Ñ %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "ÐаÑÑÑмка (мÑ)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "ÐаказваÑÑ:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Ð'ÑÑленне:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "ÐнÑкненне:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "ШÑÑÑÑÑ"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "ШÑÑÑÑ %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "ЦенÑ"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "СÑÑÐ»Ñ Ð ÑндÑÑÑ"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "ÐолеÑÑ"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "ÐÐ¾Ð»ÐµÑ %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "УклÑÑÑÑÑ ÑÑÑгеÑ"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "ÐадзеÑ"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "ÐÑÑÑÐ»ÐµÐ½Ñ ÐºÐ°Ð¼Ð¿Ð°Ð·ÑÑÐ½Ñ Ð¼ÐµÐ½ÑджаÑ"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -643,112 +627,112 @@ msgstr ""
"ÐºÐ°Ð»Ñ Ð²Ñ Ð½Ðµ ведаÑÑе, ÑÑ Ð·Ð°Ð¿ÑÑÑÐ°Ð½Ñ Ñн, акÑÑвÑйÑе кампазÑÑÐ½Ñ Ð¼ÐµÐ½ÑджаÑ. ÐÐ½Ð°ÐºÑ "
"OSD не бÑдзе пÑаÑаваÑÑ ÐºÐ°ÑÑкÑна"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "ÐампазÑÑÐ½Ñ Ð¼ÐµÐ½ÑÐ´Ð¶Ð°Ñ Ð½Ðµ паÑÑÑÐ±Ð½Ñ Ð´Ð»Ñ ÑмÑÑаÑÑйнай пÑазÑÑÑÑаÑÑÑ"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "ÐÑазÑÑÑÑаÑÑÑ"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "ÐмÑÑаÑÑÐ¹Ð½Ð°Ñ Ð¿ÑазÑÑÑÑаÑÑÑ"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "СапÑаÑÐ´Ð½Ð°Ñ Ð¿ÑазÑÑÑÑаÑÑÑ (паÑÑабÑе X Composite Ext.)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "ÐампазÑÑнÑÑ Ð¿Ð°ÑÑÑÑÐ½Ð½Ñ Ð½Ðµ загÑÑжанÑ"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "ÐампазÑÑнÑÑ Ð¿Ð°ÑÑÑÑÐ½Ð½Ñ Ð½ÐµÐ´Ð°ÑÑÑпнÑÑ"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr ""
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - канÑÑгÑÑаванне"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "ÐазÑÑÑÑ"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "ÐнÑмаÑÑÑ"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "ТÑкÑÑ"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "ÐбÑамленне"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "ÐеÑаклÑÑалÑнÑк"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "ÐнÑае"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ÐлÑйлÑÑÑÑ ASXv1/ASXv2"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "ÐлÑйлÑÑÑÑ Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>ÐолеÑ</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "РазмÑÑÑ Ð°ÑÑÑлогÑаÑ"
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
-msgstr ""
-
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
msgstr ""
-#: src/bs2b/plugin.c:166
+#: src/bs2b/plugin.cc:129
msgid "Presets:"
msgstr "ÐÑÑÑеÑÑ:"
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
+msgstr ""
+
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
msgstr ""
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "СпекÑÑалÑÐ½Ñ Ð°Ð½Ð°Ð»ÑзаÑаÑ"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "ÐлагÑн ÐÑдÑÑ ÐÐ"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -760,169 +744,156 @@ msgid ""
"This was a Google Summer of Code 2007 project."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>ÐÑÑлада</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>ÐеÑазвеÑÑкÑ</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "УжÑваÑÑ CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "УжÑваÑÑ CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "УжÑваÑÑ HTTP замеÑÑ CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "СеÑвеÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "ШлÑÑ
:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "ÐоÑÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "ÐлагÑн ÐÑдÑÑ ÐÐ"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Audio CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "ÐÑÑвад пÑÑÑÑ."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "ТÑп не падÑÑÑмлÑваеÑÑа."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr ""
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "ÐÑайгÑаÑÑ CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "ÐадаÑÑ CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr ""
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>ÐампÑÑÑÑÑ</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "ÐÑÑнаÑÑÑ ÑÑнÑÑÑ:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "ÐÑнамÑÑÐ½Ñ Ð´ÑÑпазон:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr ""
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -932,195 +903,220 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ÐаÑ:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "СапÑана:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "ТÑÐ¿Ð¾Ð²Ð°Ñ Ð¿ÑаÑÑглаÑÑÑ Ð¿ÐµÑнÑ:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "УклÑÑÑÑÑ Ð¿ÐµÑаÑÑмплаванне гÑкÑ"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "ЧаÑÑаÑа пеÑаÑÑмплаваннÑ:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "ÐÑ"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr ""
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "УзмаÑнÑÑÑ ÑÑÑ
а"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr ""
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>ÐеÑаÑ
од</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "ÐеÑакÑÑÑÑÑ:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "ÐеÑаÑ
од"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>ÐÑÑÑÑалайзеÑ</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "ÐнÑÑнÑÑÑнаÑÑÑ:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "ÐÑÑÑÑалайзеÑ"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "СÑеÑÑÑ"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "СкаÑаваÑÑ"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Ð ÑÑ
а</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "ÐаÑÑÑмка:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "мÑ"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "ÐваÑоÑÐ½Ð°Ñ ÑÑвÑзÑ:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "ÐÑÑнаÑÑÑ:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Ð ÑÑ
а"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "ÐлагÑн FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1130,55 +1126,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "ÐлагÑн FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "ÐлагÑн запÑÑÑ ÑайлаÑ"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "ФаÑÐ¼Ð°Ñ Ñайла вÑвадÑ:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "ÐанÑÑгÑÑаваÑÑ"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "ÐапÑÑваÑÑ Ñ Ð²ÑÑоÑÐ½Ñ ÐºÐ°Ñалог"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "ÐапÑÑваÑÑ Ñ Ð°Ð´Ð¼ÑÑÐ»Ð¾Ð²Ñ ÐºÐ°Ñалог"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "ÐаÑалог ÑÐ°Ð¹Ð»Ð°Ñ Ð²ÑвадÑ:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "ÐбÑаÑÑ ÐºÐ°Ñалог"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "ÐÑÑÑмаÑÑ Ð½Ð°Ð·Ð²Ñ Ñайла з:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "аÑÑгÑналÑнÑÑ
ÑÑгаÑ"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "аÑÑгÑналÑнай Ð½Ð°Ð·Ð²Ñ Ñайла"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Ðе адкÑдваÑÑ Ð¿Ð°ÑÑÑÑнне Ð½Ð°Ð·Ð²Ñ Ñайла"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "ÐадаваÑÑ Ð½ÑÐ¼Ð°Ñ ÑÑÑка пеÑад назвай Ñайла"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1196,165 +1192,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "ÐлагÑн запÑÑÑ ÑайлаÑ"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "ÐÑÑа"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Ðб'Ñднанае ÑÑÑÑÑа"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "СÑÑÑÑа"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Ðона"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "ÐанÑÑгÑÑаÑÑÑ MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "ÐлгаÑÑÑмÑÑÐ½Ð°Ñ ÑкаÑÑÑ:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "ЧаÑÑаÑа кванÑÐ°Ð²Ð°Ð½Ð½Ñ Ð²ÑвадÑ:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(ÐÑ)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "СÑадноÑÑÐ½Ñ Bitrate / Compression:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ÐÑÑÑÑÐ¹Ñ (кб/Ñ):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "УзÑÐ¾Ð²ÐµÐ½Ñ ÑÑÑÑкÑ:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Ð ÑжÑм аÑдÑÑ:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "ÐнÑ:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "ÐабÑÑпеÑÑÑÑ ÑÑÑогÑÑ ÑдпаведнаÑÑÑ ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "ÐбаÑона ад памÑлак"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "ЯкаÑÑÑ"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "УклÑÑÑÑÑ VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "ТÑп:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "ÐпÑÑÑ VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "ÐÑнÑмалÑÐ½Ñ Ð±ÑÑÑÑÐ¹Ñ (кб/Ñ):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "ÐакÑÑмалÑÐ½Ñ Ð±ÑÑÑÑÐ¹Ñ (кб/Ñ):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "СÑÑÐ¾Ð³Ð°Ñ Ð°Ð´Ð¿Ð°Ð²ÐµÐ´Ð½Ð°ÑÑÑ Ð¼ÑнÑмалÑÐ½Ð°Ð¼Ñ Ð±ÑÑÑÑйÑÑ"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ÐпÑÑÑ ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "СÑÑÑÐ´Ð½Ñ Ð±ÑÑÑÑÐ¹Ñ (кб/Ñ):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "УзÑÐ¾Ð²ÐµÐ½Ñ ÑкаÑÑÑ VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Ðе запÑÑваÑÑ Ð·Ð°Ð³Ð°Ð»Ð¾Ð²Ð°Ðº Xing VBR"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "ÐазнаÑÑÑÑ copyright"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "ÐазнаÑÑÑÑ Ñк аÑÑгÑнал"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ID3 паÑамеÑÑÑ:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "ÐÑÑмÑÑова дадаваÑÑ ÑÑг веÑÑÑÑ 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "ÐадаваÑÑ ÑолÑÐºÑ ÑÑг v1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "ÐадаваÑÑ ÑолÑÐºÑ ÑÑг v2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "ТÑгÑ"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "ÐанÑÑгÑÑаÑÑÑ ÐнкÑдÑÑа Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "УзÑÐ¾Ð²ÐµÐ½Ñ ÑкаÑÑÑ (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "ÐÑÐºÐ¾Ð´Ð°Ñ FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr ""
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1362,21 +1362,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "ÐÑÐºÐ¾Ð´Ð°Ñ FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "ÐлагÑн GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1388,446 +1392,509 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "ЦÑÑлÑÐºÑ Ðнома"
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "ÐÑÐ¼Ð°Ñ Ð·Ð°Ð¿ÑÑа"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Ðазва"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "ÐÑканаÑÑа"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Ðод"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "ÐлÑбом"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "ТÑÑк"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "ÐанÑ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "ÐазÑÑÑÑ Ñ ÑаÑзе"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "ÐÑаÑÑглаÑÑÑ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "ШлÑÑ
да Ñайла"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "ÐÐ¼Ñ Ñайла"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "ÐдмÑÑÐ»Ð¾Ð²Ñ Ð·Ð°Ð³Ð°Ð»Ð¾Ð²Ð°Ðº"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ÐÑÑÑÑйÑ"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "ÐоÑÑÐºÐ°Ð²Ð°Ñ Ð¿ÑÑлада"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "СÑÑкаваÑÑ Ðлева"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "СÑÑкаваÑÑ Ð¡Ð¿Ñава"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "СÑÑкаваÑÑ Ð£Ð²ÐµÑÑе"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "СÑÑкаваÑÑ ÐолÑ"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr ""
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "ÐÑклÑÑÑÑÑ"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "ÐоÑÑÐºÐ°Ð²Ð°Ñ Ð¿ÑÑлада"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "Ðдк_ÑÑÑÑ ÑÐ°Ð¹Ð»Ñ ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "ÐдкÑÑÑÑ _URL ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "ÐадаÑÑ _ÑÐ°Ð¹Ð»Ñ ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "ÐадаÑÑ U_RL ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "Ðб ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "ÐÑ_йÑÑÑ"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_ÐÑайгÑаÑÑ"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Ðа_Ñза"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "Сп_ÑнÑÑÑ"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "Ðап_ÑÑÑднÑ"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "ÐаÑ_ÑÑпнÑ"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "Ðа_ÑÑоÑ"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "У_Ñазнабой"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "_Ðе пеÑаÑ
одзÑÑÑ Ð´Ð° наÑÑÑпнай"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_ÐвеÑÑÐºÑ Ð¿Ñа пеÑÐ½Ñ ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "ÐеÑайÑÑÑ Ð´Ð° _ÑаÑÑ ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "_ÐеÑайÑÑÑ Ð´Ð° пеÑÐ½Ñ ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Ðа _назве"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Ðа _нÑмаÑÑ ÑÑÑка"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Ðа вÑк_анаÑÑÑ"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Ðа даÑе _вÑданнÑ"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Ðа ÑлÑÑ
Ñ Ð´Ð° Ñайла"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Ðа адмÑ_ÑловÑм загалоÑкÑ"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Ðд_ваÑоÑÐ½Ñ Ð¿Ð°Ñадак"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "ÐÑпад_ÐºÐ¾Ð²Ñ Ð¿Ð°Ñадак"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "ÐÑайгÑаÑÑ Ð¿Ð»ÑйлÑÑÑ"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "Ð_бнавÑÑÑ"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_ÐаÑадкаваÑÑ"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "СÑеÑÑÑ _недаÑÑÑпнÑÑ ÑайлÑ"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_ÐадаÑÑ"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "ÐеÑайменаваÑÑ ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_ÐмпаÑÑ ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "Ð_кÑпаÑÑ ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "ÐÑÑа_ÑнÑк плÑйлÑÑÑÐ¾Ñ ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "ÐÑÑаÑнÑк _ÑаÑÐ³Ñ ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "_ÐÑÑней"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "_ЦÑÑÑй"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "Ð_квалайзеÑ"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "ÐаказваÑÑ ÑÑÑÐ¶ÐºÑ _менÑ"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "ÐаказваÑÑ ÑÑÑÐ¶ÐºÑ Ð·Ð²ÐµÑ_Ñак"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "ÐаказваÑÑ Ð²Ñ_зÑалÑзаÑÑÑ ÑÑÑÐ¶ÐºÑ Ð·Ð²ÐµÑÑак"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "ÐаказваÑÑ ÑÑÑÐ¶ÐºÑ _ÑÑаÑÑÑÑ"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "Ф_айл"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_ÐÑайгÑаванне"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "Ð_лÑйлÑÑÑ"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "СеÑвÑÑ_Ñ"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "ÐÑва_д"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "ÐÑ_глÑд"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "У ÑаÑÐ³Ñ / Ð ÑаÑгÑ"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "_ÐÑÑазаÑÑ"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_ÐапÑÑаваÑÑ"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_УÑÑавÑÑÑ"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "ÐÑлÑÑÑÑÑ ÑÑе"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "Ð_еÑайменаваÑÑ ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "ÐнÑÑÑÑÐµÐ¹Ñ GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ÐазапаÑванне ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "мона"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "ÑÑÑÑÑа"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
@@ -1836,84 +1903,98 @@ msgstr[1] "%d каналÑ"
msgstr[2] "%d каналаÑ"
msgstr[3] "%d каналаÑ"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d кб/Ñ"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr ""
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Ð ÑжÑм плÑйлÑÑÑа."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "СпÑненне паÑÐ»Ñ Ð¿ÐµÑнÑ."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr ""
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "ÐÑаÑÑ"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "ÐаÑза/ÐÑаÑÑгнÑÑÑ"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "СпÑнÑÑÑ"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr ""
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "ЦÑÑÑнÑ"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr ""
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr ""
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr ""
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "ÐаказаÑÑ ÐÑÑплей на ÐкÑане :OSD:"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(нÑма)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1921,37 +2002,37 @@ msgid ""
"Do you want to continue?"
msgstr ""
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr ""
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr ""
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
msgstr ""
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr ""
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>ÐзеÑнне:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr ""
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr ""
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1966,124 +2047,90 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "ÐÑвад JACK"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "ÐÑвад JACK"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s ÐаÑÑаÑленнÑ"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "ÐаÑÑаÑÐ»ÐµÐ½Ð½Ñ Ñ
оÑÑа LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "ШлÑÑ
да модÑлÑ:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
"After adding new paths, press Enter to scan for new plugins.</small>"
msgstr ""
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "ÐаÑÑÑпнÑÑ Ð¿Ð»Ð°Ð³ÑнÑ:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "УклÑÑÑÑÑ"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "УклÑÑанÑÑ Ð¿Ð»Ð°Ð³ÑнÑ:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "ÐаÑÑаÑленнÑ"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr ""
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr ""
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: ÑпÑоба паÑÑоÑнага злÑÑÑннÑ...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: невÑÐ´Ð¾Ð¼Ñ Ð·Ð°Ð³Ð°Ð´ \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: злÑÑÑнне з LIRC ÑÑÑаÑана\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr ""
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "ÐлагÑн LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2099,73 +2146,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>ÐлÑÑÑнне</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "ÐеÑазлÑÑÑнне з ÑеÑвеÑам LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr ""
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "ÐлагÑн LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "ÐлагÑн LyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Ð¡Ð»Ð¾Ð²Ñ Ð½ÐµÐ´Ð°ÑÑÑпнÑÑ"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "ÐамÑлка"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "ÐемагÑÑма аÑÑÑмаÑÑ %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "ÐамÑлка"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "ÐемагÑÑма ÑазабÑаÑÑ %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "ШÑкаÑÑÑа ÑÐ»Ð¾Ð²Ñ ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "ÐдÑÑÑнÑÑаÑÑÑ Ð¼ÐµÑазвеÑÑÐºÑ Ñ Ð¿ÐµÑнÑ"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "ÐлÑÑÑнне з lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "ÐлагÑн LyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "ÐлÑйлÑÑÑÑ M3U"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "ТакÑÐ°Ð²Ñ Ð³ÐµÐ½ÐµÑаÑаÑ"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "ТакÑÐ°Ð²Ñ Ð³ÐµÐ½ÐµÑаÑаÑ: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "ТакÑÐ°Ð²Ñ Ð³ÐµÐ½ÐµÑаÑаÑ: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2174,162 +2229,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "ТакÑÐ°Ð²Ñ Ð³ÐµÐ½ÐµÑаÑаÑ"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "ÐÑкÑÐ°Ñ ÐºÐ°Ð½Ð°Ð»Ð°Ñ"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>ÐÑкÑÐ°Ñ ÐºÐ°Ð½Ð°Ð»Ð°Ñ</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "ÐÐ°Ð½Ð°Ð»Ð°Ñ Ð²ÑвадÑ:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "ÐÑкÑÐ°Ñ ÐºÐ°Ð½Ð°Ð»Ð°Ñ"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "ÐлагÑн MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr ""
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr ""
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr ""
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr ""
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr ""
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr ""
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
msgstr ""
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr ""
-
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "ÐлагÑн MPG123"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr ""
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr ""
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "ÐлагÑн Neon HTTP/HTTPS"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "СпÑнена"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious не ÑгÑае."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr ""
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2349,55 +2436,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr ""
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "ÐаÑза"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "ÐаÑÑÑпнÑ"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. ТÑÐ¿Ð¾Ð²Ð°Ñ Ð¿ÑÑлада"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "ÐÑвад OSS4"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "ÐÑдÑÑ-пÑÑлада:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr ""
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "ÐаÑ
оÑваÑÑ Ð³ÑÑнаÑÑÑ Ð¿Ð°Ð¼Ñж ÑеанÑамÑ."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr ""
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2406,19 +2502,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "ÐÑвад OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "ÐлÑйлÑÑÑÑ PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "ÐÑÐºÐ¾Ð´Ð°Ñ OpenPSF PSF1/PSF2"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "ÐÑвад PulseAudio"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2438,143 +2550,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "ÐÑвад PulseAudio"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ÐапÑÑÑднÑ"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "ÐаÑÑоÑ"
-#: src/resample/resample.c:165
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "УÑазнабой"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr ""
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "ÐÑÐ½ÐµÐ¹Ð½Ð°Ñ ÑнÑÑÑпалÑÑÑÑ"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>ÐанвеÑÑÑÑ</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "ÐеÑад:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr ""
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr ""
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 кÐÑ:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 кÐÑ:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22,05 кÐÑ:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44,1 кÐÑ:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 кÐÑ:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 кÐÑ:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 кÐÑ:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr ""
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr ""
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr ""
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2585,771 +2766,846 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr ""
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr ""
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "ÐÑблÑÑÑÑка"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "ÐевÑÐ´Ð¾Ð¼Ñ Ð²ÑканаÑÑа"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "ÐевÑÐ´Ð¾Ð¼Ñ Ð°Ð»Ñбом"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-
-#: src/search-tool/search-tool.c:631
-#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
+msgid "%d result"
+msgid_plural "%d results"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_СÑваÑÑÑÑ Ð¿Ð»ÑйлÑÑÑ"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_ÐадаÑÑ Ñ Ð¿Ð»ÑйлÑÑÑ"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "ШÑкаÑÑ Ñ Ð±ÑблÑÑÑÑÑÑ"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "ÐаÑакайÑе, ÐºÐ°Ð»Ñ Ð»Ð°Ñка ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "ÐÑбеÑÑÑе каÑалог"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "ÐÑайгÑаванне"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "ÐлÑйлÑÑÑ"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "ÐÑглÑд"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "ÐаÑÑоÑ"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "УÑазнабой"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Ðе пеÑаÑ
одзÑÑÑ Ð´Ð° наÑÑÑпнай"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ÐапÑÑÑднÑ"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "ÐÐ¾Ð²Ñ Ð¿Ð»ÑйлÑÑÑ"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "ÐаказваÑÑ ÑÑдакÑÐ°Ñ ÑпÑÑаÑ"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "ÐаказваÑÑ ÑквалайзеÑ"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "ÐаÑÑÑÐ´Ñ Ð·Ð²ÐµÑÑ
Ñ"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Ðа загалоÑкÑ"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Ðа назве Ñайла"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "СÑеÑÑÑ ÑÑе"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "ÐÑÑÑÑÑÑÑ ÑаÑгÑ"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "СÑеÑÑÑ Ð½ÐµÐ´Ð°ÑÑÑпнÑÑ ÑайлÑ"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "СÑеÑÑÑ Ð´ÑблÑкаÑÑ"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "СÑеÑÑÑ Ð½ÐµÐ²ÑлÑÑанÑÑ"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "СÑеÑÑÑ Ð²ÑлÑÑанÑÑ"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "ÐоÑÑк Ñ Ð²ÑлÑÑÑнне"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "ÐнвеÑÑаваÑÑ Ð²ÑлÑÑÑнне"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "ÐнÑÑÑ Ð²ÑлÑÑÑнне"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "ÐÑлÑÑÑÑÑ ÑÑе"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Ðа алÑбомÑ"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Ðа нÑмаÑÑ ÑÑÑка"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Ðа вÑканаÑÑÑ"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Ðа алÑбомÑ"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Ðа нÑмаÑÑ ÑÑÑка"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "РаÑкÑдаÑÑ ÑпÑÑ"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "СпÑÑ Ð½Ð°Ð°Ð´Ð²Ð°ÑоÑ"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "СаÑÑаваÑÑ Ð²ÑлÑÑанÑÑ"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "СаÑÑаваÑÑ ÑпÑÑ"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "ÐÑÑазаÑÑ"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "ÐапÑÑаваÑÑ"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "УÑÑавÑÑÑ"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "ÐнÑÑÑÑÐµÐ¹Ñ Winamp-клаÑÑк"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "ÐапÑÑаÑÑ"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "ÐагÑÑзÑÑÑ"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "ÐÑÑÑеÑÑ"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "ЧÑÑаÑÑ Ð¿ÑÑÑеÑ"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "ЧÑÑаÑÑ Ð°ÑÑа-пÑÑÑеÑ"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "ÐапÑÑаÑÑ Ð¿ÑÑÑеÑ"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "ÐапÑÑаÑÑ Ð°ÑÑа-пÑÑÑеÑ"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "СÑеÑÑÑ Ð¿ÑÑÑеÑ"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "СÑеÑÑÑ Ð°ÑÑа-пÑÑÑеÑ"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "ÐлÑеÑ:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "ÐÑлÑÑÑÑе ÑÑÑÑÑ Ð´Ð»Ñ Ð³Ð°Ð»Ð¾Ñнага вакна плÑеÑа:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "Ðл_ÑйлÑÑÑ:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "ÐÑбеÑÑÑе ÑÑÑÑÑ Ð´Ð»Ñ Ð¿Ð»ÑйлÑÑÑа:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr ""
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "ÐÑакÑÑÑваÑÑ Ð½Ð°Ð·Ð²Ñ Ð¿ÐµÑÐ½Ñ Ñ Ð°Ð±Ð¾Ð´Ð²ÑÑ
кÑÑÑнкаÑ
"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "ÐналÑзаÑаÑ"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "ÐÑÑÑлогÑаÑ"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "ÐÑкл"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "ÐоÑма"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "ÐолÑмÑ"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "ÐÑнÑÑ"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "СлÑпкÑ"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "ÐаймаÑÑдней"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "ÐаÑÑдна"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "СÑÑÑдне"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Ð¥ÑÑка"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "ÐайÑ
ÑÑÑÑй"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "ÐÑд"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Ðладка"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "ÐгÑлÑнÑÑ"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "ÐÑзÑалÑзаÑÑÑ"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "ÐеÑадÑзмаÑненне"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "2 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 кÐÑ"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "ÐÐºÐ²Ð°Ð»Ð°Ð¹Ð·ÐµÑ Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr ""
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "ÐÑÑнаÑÑÑ: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "ÐаланÑ: %d%% Ñлева"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "ÐаланÑ: ÑÑнÑÑ"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "ÐаланÑ: %d%% ÑпÑава"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "ÐÐµÐ½Ñ Ð¾Ð¿ÑÑй"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "ÐдклÑÑÑÑÑ 'ÐаÑÑÑÐ´Ñ Ð·Ð²ÐµÑÑ
Ñ'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "УклÑÑÑÑÑ 'ÐаÑÑÑÐ´Ñ Ð·Ð²ÐµÑÑ
Ñ'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr ""
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr ""
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Ð ÑжÑм плÑйлÑÑÑа."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "СпÑненне паÑÐ»Ñ Ð¿ÐµÑнÑ."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "ШÑкаÑÑ Ð·Ð°Ð¿ÑÑÑ Ñ Ð±ÑгÑÑÑм плÑйлÑÑÑе"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3357,57 +3613,61 @@ msgid ""
"for."
msgstr ""
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Ðагаловак: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "ÐлÑбом: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "ÐÑканаÑÑа: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Ðазва Ñайла: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "ÐÑÑÑÑÑÑÑ Ð¿Ð°Ð¿ÑÑÑднÑе вÑлÑÑÑнне пеÑад поÑÑкам"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "ÐÑÑамаÑÑÑна пеÑаклÑÑÑÑÑ ÑаÑÐ³Ñ Ð´Ð»Ñ Ð°Ð´Ð¿Ð°Ð²ÐµÐ´Ð½ÑÑ
запÑÑаÑ"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "СÑваÑÑÑÑ Ð½Ð¾Ð²Ñ Ð¿Ð»ÑйлÑÑÑ Ð· адпаведнÑÐ¼Ñ Ð·Ð°Ð¿ÑÑамÑ"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Ð ÑдакÑÐ°Ñ Ð¿Ð»ÑйлÑÑÑÐ¾Ñ Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d з %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "СÑÑÑнÑÑÐ°Ñ Ð°Ð±Ð°Ð»Ð¾Ð½ÐºÐ° Winamp 2.x"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "ÐеÑÑÑÑнÑÑÐ°Ñ Ð°Ð±Ð°Ð»Ð¾Ð½ÐºÐ° Winamp 2.x"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "ÐемагÑÑма ÑÑваÑÑÑÑ ÐºÐ°Ñалог (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "ÐлагÑн Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3429,75 +3689,69 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "ÐлагÑн Sndfile"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "ÐÑа плагÑн вÑÐ²Ð°Ð´Ñ Sndfile"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "ФаÑÐ¼Ð°Ñ Ð½Ðµ падÑÑÑмлÑваеÑÑа"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "пÑÑлада sndio"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "Так"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "ÐеÑаклÑÑÑнне пеÑнÑ"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Ðагад:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Ðагад, ÑÐºÑ Ð²ÑканаÑÑ Ð¿Ð° заканÑÑÐ½Ð½Ñ Ð¿ÐµÑнÑ."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "ÐÑконваÑÑ Ð·Ð°Ð³Ð°Ð´, ÐºÐ°Ð»Ñ Audacious даÑÑгае канÑа плÑйлÑÑÑа."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3512,17 +3766,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "ÐагадÑ"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3531,51 +3783,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Ð¥ÑÑкаÑÑÑ"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr ""
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "ÐнаÑок ÑÑаÑÑÑÑ"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3586,63 +3838,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>ÐзеÑÐ½Ð½Ñ ÐºÐ¾Ð»Ñа мÑÑÑ</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "ÐмÑнÑÑÑ Ð³Ñк"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "ÐмÑнÑÑÑ Ð¿ÐµÑнÑ"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>ÐнÑÑÑ Ð½Ð°ÑÑаÑленнÑ</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "ÐдклÑÑÑÑÑ ÑÑплÑÑное акно"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr ""
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "ÐнаÑок ÑÑаÑÑÑÑ"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "ÐадаÑковае ÑÑÑÑÑа"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>ÐадаÑковае ÑÑÑÑÑа</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "ÐадаÑковае ÑÑÑÑÑа"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr ""
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f ÐÑ"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr ""
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3651,15 +3903,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr ""
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "ÐÑдаленне голаÑÑ"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3680,44 +3928,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "ÐÑÐºÐ¾Ð´Ð°Ñ Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "ÐÑÐºÐ¾Ð´Ð°Ñ VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "ÐÑÐºÐ¾Ð´Ð°Ñ VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "ÐÑÐºÐ¾Ð´Ð°Ñ WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr ""
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr ""
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "ÐÑÐºÐ¾Ð´Ð°Ñ WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "ÐÑÐºÐ¾Ð´Ð°Ñ 2SF"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr ""
diff --git a/po/bg.po b/po/bg.po
index ad7a7a07dc75..c4b5bfe8ff17 100644
--- a/po/bg.po
+++ b/po/bg.po
@@ -3,17 +3,20 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
+# Ivailo Monev <xakepa10 at gmail.com>, 2014
+# Kiril Kirilov <cybercop_montana at abv.bg>, 2014-2015
# Pandi3a <pandi3a at gmail.com>, 2012
# Pandi3a <pandi3a at gmail.com>, 2012
-# РадоÑлав <reckku at gmail.com>, 2013-2014
-# РадоÑлав <reckku at gmail.com>, 2013
+# РадоÑлав Ðванов <reckku at gmail.com>, 2013-2014
+# РадоÑлав Ðванов <reckku at gmail.com>, 2013
+# РадоÑлав Ðванов <reckku at gmail.com>, 2015
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-13 11:48+0000\n"
-"Last-Translator: РадоÑлав <reckku at gmail.com>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-19 22:33+0000\n"
+"Last-Translator: РадоÑлав Ðванов <reckku at gmail.com>\n"
"Language-Team: Bulgarian (http://www.transifex.com/projects/p/audacious/"
"language/bg/)\n"
"Language: bg\n"
@@ -22,40 +25,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "еднозвÑÑие"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "многозвÑÑие"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "обгÑÐ°Ð¶Ð´Ð°Ñ Ð·Ð²Ñк"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "РазкодиÑане на AAC (MP4)"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "РазкодиÑане на AAC (Raw)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib ÐлейÑÑ)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "подÑедени"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib ÐлеÑÑ)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "ÐлаÑма"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "Ðадаване на ÐлаÑма ..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -66,11 +57,7 @@ msgstr ""
"\n"
"ÐÑигинално напиÑана Ð¾Ñ Adam Feakin и Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "ÐлаÑма"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -112,7 +99,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -150,7 +137,7 @@ msgstr ""
"ÐопÑлниÑелна команда:\n"
"СÑаÑÑиÑане на Ñази команда по вÑеме на алаÑмаÑа.\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -174,183 +161,156 @@ msgstr ""
"ÐÑведеÑе извеÑÑиеÑо в кÑÑиÑÑа и вклÑÑеÑе клавиÑа за\n"
"пÑевклÑÑване, ако иÑкаÑе да бÑде извеждано."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Това е ÐаÑиÑÑ Ñигнал за ÑÑбÑждане."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "ÐаÑеÑо напомнÑне за Ð´Ð½ÐµÑ Ðµ..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "ÐапомнÑне"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Ðонеделник"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "ÐÑоÑник"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "СÑÑда"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "ЧеÑвÑÑÑÑк"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "ÐеÑÑк"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "СÑбоÑа"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "ÐеделÑ"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "ÐаÑÑÑойки на алаÑма"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "_ÐобÑе"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "_ÐÑказ"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "ЧаÑ"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "ÐлаÑмиÑане в (по подÑазбиÑане):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "Ñ"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "ÐаÑиÑие Ñлед:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "ÑаÑове"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "минÑÑи"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "ÐÐ·Ð±Ð¾Ñ Ð½Ð° дни, в коиÑо да Ñе акÑивиÑа алаÑмаÑа"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Ðен"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Ðо подÑазбиÑане"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Ðни"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "ÐаÑиÑ
ване"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "ÑекÑнди"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Сила на звÑка"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "ÐаÑало"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "ÐÑай"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "ТекÑÑо"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "ÐопÑлниÑелна команда"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "акÑивиÑане"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "СпиÑÑк за изпÑлнение (по избоÑ)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "ÐÐ·Ð±Ð¾Ñ Ð½Ð° ÑпиÑÑк"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "ÐпÑии"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Ðакво ознаÑÐ°Ð²Ð°Ñ Ñези опÑии?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "ÐомоÑ"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Ðбложка на албÑм"
-#: src/alsa/config.c:210
-msgid "Default PCM device"
-msgstr "PCM ÑÑÑÑойÑÑво по подÑазбиÑане"
-
-#: src/alsa/config.c:239
-msgid "Default mixer device"
-msgstr "ÐикÑÐµÑ ÑÑÑÑойÑÑво по подÑазбиÑане"
-
-#: src/alsa/config.c:428
-msgid "PCM device:"
-msgstr "PCM ÑÑÑÑойÑÑво:"
-
-#: src/alsa/config.c:430
-msgid "Mixer device:"
-msgstr "ÐикÑеÑ:"
-
-#: src/alsa/config.c:432
-msgid "Mixer element:"
-msgstr "ÐÐ»ÐµÐ¼ÐµÐ½Ñ Ð½Ð° микÑеÑа:"
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "ÐлбÑм Ðзп (Qt)"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "ÐзбÑгване на повÑоÑение"
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA ÐзÑ
од"
-#: src/alsa/plugin.c:27
+#: src/alsa/config.cc:28
msgid ""
"ALSA Output Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren\n"
@@ -365,194 +325,208 @@ msgstr ""
"NG, ÑийÑо код ÑлÑжеÑе за ÑпÑавка, когаÑо ÑÑководÑÑвоÑо кÑм ALSA не беÑе "
"доÑÑаÑÑÑно."
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA ÐзÑ
од"
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(нÑма опиÑание)"
+
+#: src/alsa/config.cc:166
+msgid "Default PCM device"
+msgstr "PCM ÑÑÑÑойÑÑво по подÑазбиÑане"
-#: src/amidi-plug/amidi-plug.c:466
+#: src/alsa/config.cc:188
+msgid "Default mixer device"
+msgstr "ÐикÑÐµÑ ÑÑÑÑойÑÑво по подÑазбиÑане"
+
+#: src/alsa/config.cc:296
+msgid "PCM device:"
+msgstr "PCM ÑÑÑÑойÑÑво:"
+
+#: src/alsa/config.cc:299
+msgid "Mixer device:"
+msgstr "ÐикÑеÑ:"
+
+#: src/alsa/config.cc:302
+msgid "Mixer element:"
+msgstr "ÐÐ»ÐµÐ¼ÐµÐ½Ñ Ð½Ð° микÑеÑа:"
+
+#: src/amidi-plug/amidi-plug.cc:41
msgid "AMIDI-Plug (MIDI Player)"
msgstr "AMIDI-Plug (MIDI ÐлеÑÑ)"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/amidi-plug.cc:437
+msgid ""
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
+"\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "ÐÑÐµÐ·Ð°Ð¿Ð¸Ñ Ð½Ð° ÑÑандаÑÑноÑо ÑÑилване:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "ÐÑÐµÐ·Ð°Ð¿Ð¸Ñ Ð½Ð° ÑÑандаÑÑнаÑа полиÑониÑ:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "ÐÑÐµÐ·Ð°Ð¿Ð¸Ñ Ð½Ð° ÑÑандаÑÑноÑо еÑ
о"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "ÐклÑÑено"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "ÐÑÐµÐ·Ð°Ð¿Ð¸Ñ Ð½Ð° ÑÑандаÑÑÐ½Ð¸Ñ Ñ
оÑ:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>ÐÑзпÑоизвеждане</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "ТÑанÑпозиÑии:"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "полÑÑонове"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "ÐÑомÑна на баÑабана:"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>ÐопÑлниÑелни</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "РазаÑÑ
ивиÑане на коменÑаÑи Ð¾Ñ MIDI Ñайл"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "РазаÑÑ
ивиÑане на ÑекÑÑ Ð¾Ñ MIDI Ñайл"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>ШÑиÑÑ Ð½Ð° звÑка</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>СинÑезаÑоÑ</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr "ЧеÑÑоÑа на диÑкÑеÑизаÑиÑ:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Ð¥Ñ"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-ÐонÑÐ°ÐºÑ - Ð¸Ð·Ð±Ð¾Ñ Ð½Ð° Ñайл за звÑково изÑавнÑване"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_ÐÑказ"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "_ÐÑваÑÑне"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "Ðме на Ñайл"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "Ðме на Ñайла"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Ð Ð°Ð·Ð¼ÐµÑ (байÑове)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Ðме:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI инÑоÑмаÑÐ¸Ñ </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "ФоÑмаÑ:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "ÐÑодÑлжиÑелноÑÑ (милиÑекÑнди):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "â на ÐапиÑи:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "пÑоменливоÑÑ"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "УÐÐ:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "УÐÐ (вÑлни):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "ÐÑеме Разд.:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI ÐоменÑаÑи и лиÑика </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* нÑма доÑÑÑпни коменÑаÑи за Ñози MIDI Ñайл *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* нÑма доÑÑÑпна лиÑика за Ñози MIDI Ñайл *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_ÐаÑваÑÑне"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (невалиден UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "ÐÑноÑно AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-ÐÑ
од"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"модÑлен MIDI плеÑÑ\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"ÐапиÑан Ð¾Ñ Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"иÑкÑени благодаÑноÑÑи на...\n"
-"\n"
-"Clemens Ladisch и Jaroslav Kysela\n"
-"за ÑÑÑаÑ
оÑниÑе им пÑогÑами aplaymidi и amixer;\n"
-"Ñе бÑÑ
а наиÑÑина полезни, заедно Ñ Ð´Ð¾ÐºÑменÑаÑиÑÑа за\n"
-"alsa-lib, вÑв вÑÑзка ÑÑÑ Ð·Ð°Ð¿Ð¾Ð·Ð½Ð°Ð²Ð°Ð½ÐµÑо Ñ ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"за Ñ
ÑбавоÑо клавиаÑÑÑно midi лого\n"
-"\n"
-"Tony Vroon\n"
-"за помоÑÑа пÑи алÑа ÑеÑÑовеÑе"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -570,154 +544,148 @@ msgstr ""
"ÐазиÑан оÑÑаÑÑи на Ghosd библиоÑекаÑа на Evan Martin:\n"
"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (пÑозоÑÐµÑ Ð² екÑана)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ÐÑавоÑгÑлник"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "ÐÑавоÑгÑлник ÑÑÑ Ð·Ð°Ð¾Ð±Ð»ÐµÐ½Ð¸ кÑаиÑа"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "ÐдлÑÐ±Ð½Ð°Ñ Ð¿ÑавоÑгÑлник"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Ðез"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "ÐаÑало на вÑзпÑоизвежданеÑо"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "ÐадейÑÑване на OSD, когаÑо запоÑне вÑзпÑоизвежданеÑо"
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "ÐÑомÑна на заглавие"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"ÐадейÑÑване на OSD, когаÑо, по вÑеме на вÑзпÑоизвежданеÑо, Ñе пÑомени имеÑо "
-"на заглавиеÑо, но имеÑо на Ñайла оÑÑане непÑоменено. Това е най-полезно пÑи "
-"извеждане на пÑомениÑе в заглавиеÑо за инÑеÑÐ½ÐµÑ Ð¿Ð¾ÑоÑиÑе."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "ÐÑеменноÑо ÑпиÑане е акÑивиÑано"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr ""
"ÐадейÑÑване на OSD, когаÑо\n"
"вÑзпÑоижзвежданеÑо е в Ñежим на вÑеменна паÑза."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "ÐÑеменноÑо ÑпиÑане е деакÑивиÑано"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "ÐадейÑÑване на OSD, когаÑо вÑзпÑоизвежданеÑо пÑодÑлжи."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "ÐеÑÑоположение"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "ÐÑноÑиÑелен оÑÑÑÑп за X:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "ÐÑноÑиÑелен оÑÑÑÑп за Y:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "ÐакÑимална ÑиÑина на OSD:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "ÐпÑии за много мониÑоÑи"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Ðзвеждай OSD, използвайки:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "вÑиÑки мониÑоÑи"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "мониÑÐ¾Ñ %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "ÐÑемеÑÑаене (мÑ)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "ÐкÑан:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "ÐÑоÑÑнÑване:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "ÐзбледнÑване:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "ШÑиÑÑове"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "ШÑиÑÑ %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "СÑнка"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "СÑздай Ñвой ÑÑил"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "ЦвеÑове"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "ЦвÑÑ %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "ÐкÑивиÑане на акÑиваÑоÑа"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "СÑбиÑие"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "ÐаÑеÑен е ÐомпозиÑен мениджÑÑ"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -727,112 +695,112 @@ msgstr ""
"Ð¼Ð¾Ð»Ñ Ð°ÐºÑивиÑайÑе мениджÑÑа, оÑвен ако веÑе нÑмаÑе ÑÑаÑÑиÑан, в пÑоÑивен "
"ÑлÑÑай OSD нÑма да ÑабоÑи пÑавилно"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Ðе Ñе изиÑква композиÑен мениджÑÑ Ð·Ð° илÑзийна пÑозÑаÑноÑÑ"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "ÐÑозÑаÑноÑÑ"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "ÐлÑзийна пÑозÑаÑноÑÑ"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "ÐÑÑинÑка пÑозÑаÑноÑÑ (изиÑква ÑазÑиÑение за X)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "ÐомпозиÑноÑо ÑазÑиÑение не е заÑедено"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "ÐомпозиÑноÑо ÑазÑиÑение не е налиÑно"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - наÑÑÑойка"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "_ТеÑÑ"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "_Ðадаване"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "ÐозиÑиÑ"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "ÐнимаÑиÑ"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "ТекÑÑ"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "ÐекоÑаÑиÑ"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "ÐкÑиваÑоÑ"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Разни"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "ТеÑÑ"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "ASXv3 ÑпиÑÑÑи за изпÑлнение"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 СпиÑÑÑи"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious СпиÑÑÑи (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>ЦвÑÑ</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Ð Ð°Ð·Ð¼Ð¸Ñ Ð¾ÑÑилоÑкоп"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer ÐногозвÑÑие-кÑм-двÑзвÑÑие (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "ÐÑедложениÑ:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Ðиво на емиÑиÑ:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "ЧеÑÑоÑа на ÑÑез:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "ÐÑедложениÑ:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer ÐногозвÑÑие-кÑм-двÑзвÑÑие (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Ðнализ на ÑпекÑÑÑа"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "ÐÑдио CD ÐÑиÑÑавка"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -855,171 +823,156 @@ msgstr ""
"\n"
"Това беÑе пÑÐ¾ÐµÐºÑ Ð¾Ñ Google Summer of Code 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>УÑÑÑойÑÑво</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "СкоÑоÑÑ Ð½Ð° ÑеÑене:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "ÐÑÐµÐ·Ð°Ð¿Ð¸Ñ Ð½Ð° ÑÑÑÑойÑÑвоÑо:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>ÐеÑаданни</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Ðзползвай CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Ðзползвай CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Ðзползване на HTTP вмеÑÑо CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "СÑÑвÑÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "ÐÑÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "ÐоÑÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "ÐÑдио CD ÐÑиÑÑавка"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "ÐÑÑпеÑ
пÑи оÑкÑиване на cdio подÑиÑÑема."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "Ðевалиден ÐнÑеÑÐ½ÐµÑ Ð°Ð´ÑÐµÑ %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "ÐÐ°Ð¿Ð¸Ñ %d не е намеÑен."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "ÐапиÑÑÑ %d е Ð¾Ñ Ð´Ð°Ð½Ð½Ð¸."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Ðе може да бÑде оÑвоÑен аÑдио изÑ
ода."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "ÐÑеÑка пÑи ÑеÑене на audio CD."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "ÐÑдио ÐиÑк"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "ÐÐ°Ð¿Ð¸Ñ %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Ðе може да бÑде оÑвоÑено CD ÑÑÑÑойÑÑво %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Ðе е намеÑено Audio CD ÑÑÑÑойÑÑво."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "ÐеÑÑпеÑно пÑиклÑÑване на обознаÑаванеÑо на оÑвоÑеноÑо CD ÑÑÑÑойÑÑво."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "ÐеÑÑпеÑ
пÑи извлиÑане на пÑÑвиÑÑ/поÑледниÑÑ Ð½Ð¾Ð¼ÐµÑ Ð½Ð° запиÑ."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Ðе може да пÑоÑеÑе наÑалоÑо/кÑÐ°Ñ Ð½Ð° LSN за Ð·Ð°Ð¿Ð¸Ñ %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "ÐеÑÑпеÑ
пÑи ÑÑздаване на cddb вÑÑзка."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "ÐеÑÑпеÑна заÑвка кÑм CDDB ÑÑÑвÑÑ"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "ÐеÑÑпеÑна заÑвка кÑм CDDB ÑÑÑвÑÑ: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "ÐеÑÑпеÑно пÑоÑиÑане на cddb инÑоÑмаÑиÑ: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "УÑÑÑойÑÑвоÑо е пÑазно."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "ÐеподдÑÑжан диÑк."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "ÐлеменÑи на Ð¼ÐµÐ½Ñ Ñип Audio CD"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "ÐÑзпÑоизвеждане на ÐºÐ¾Ð¼Ð¿Ð°ÐºÑ Ð´Ð¸Ñк"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "ÐобавÑне на ÐºÐ¾Ð¼Ð¿Ð°ÐºÑ Ð´Ð¸Ñк"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "ÐлеменÑи на Ð¼ÐµÐ½Ñ Ñип Audio CD"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Свиване</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "СÑеда на звÑка:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "ÐинамиÑен обÑ
ваÑ:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"ÐÑиÑÑавка за Свиване на динамиÑниÑе ÑеÑÑоÑи за Audacious\n"
-"ÐвÑоÑÑки пÑава 2010-2012 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Свиване на динамиÑÐ½Ð¸Ñ Ð¾Ð±Ñ
ваÑ"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1035,207 +988,226 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ÐиÑки:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "ÐиÑоки:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "ÐÑ
о:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "СÑандаÑÑно вÑемеÑÑаене за пеÑен:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>ÐÑеизÑиÑлÑване</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "ÐкÑивиÑане на пÑеизÑиÑлÑване на звÑка"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "ЧеÑÑоÑа на пÑеизÑиÑлÑване:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Ð¥Ñ"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "ÐезаÑиÑане на пÑодÑлжиÑелноÑÑÑа ÑпоÑед SPC еÑикеÑиÑе"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "УвелиÑаване на еÑ
оÑо"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "ÐвÑково ÑазкодиÑане за игÑална конзола"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-"ÐлавноÑо пÑеминаване неÑполÑÑи, заÑоÑо пеÑниÑе Ð¸Ð¼Ð°Ñ ÑазлиÑен бÑой канали. "
-"ÐожеÑе да използваÑе СмеÑиÑÐµÐ»Ñ Ð½Ð° канали, за да пÑевÑÑнеÑе бÑÐ¾Ñ Ð¸Ð¼ в Ð¾Ð±Ñ Ð·Ð° "
-"вÑиÑки пеÑни."
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"ÐлавноÑо пÑеминаване неÑполÑÑи, заÑоÑо пеÑниÑе Ð¸Ð¼Ð°Ñ ÑазлиÑна ÑеÑÑоÑа. ÐожеÑе "
-"да използваÑе ÐÑеобÑазÑваÑÐµÐ»Ñ Ð½Ð° ÑеÑÑоÑа, за да зададеÑе обÑа ÑеÑÑоÑа за "
-"вÑиÑки пеÑни."
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"ÐÑиÑÑавка за плавно пÑеминаване на Audacious\n"
-"ÐвÑоÑÑки пÑава 2010-2012 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Ðлавно пÑеминаване</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "ÐаÑÑÑпване:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Ðлавно пÑеминаване"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"ÐлавноÑо пÑеминаване неÑполÑÑи, заÑоÑо пеÑниÑе Ð¸Ð¼Ð°Ñ ÑазлиÑен бÑой канали. "
+"ÐожеÑе да използваÑе СмеÑиÑÐµÐ»Ñ Ð½Ð° канали, за да пÑевÑÑнеÑе бÑÐ¾Ñ Ð¸Ð¼ в Ð¾Ð±Ñ Ð·Ð° "
+"вÑиÑки пеÑни."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"ÐлавноÑо пÑеминаване неÑполÑÑи, заÑоÑо пеÑниÑе Ð¸Ð¼Ð°Ñ ÑазлиÑна ÑеÑÑоÑа. ÐожеÑе "
+"да използваÑе ÐÑеобÑазÑваÑÐµÐ»Ñ Ð½Ð° ÑеÑÑоÑа, за да зададеÑе обÑа ÑеÑÑоÑа за "
+"вÑиÑки пеÑни."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>ÐÑиÑÑализиÑане</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "ÐаÑиÑеноÑÑ:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "ÐÑиÑÑализаÑоÑ"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "ÐÑиÑÑавка за ÑÑловноÑÑи"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "ÐзÑÑиване на Ñайлове"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "ÐÑеÑка пÑи пÑемеÑÑванеÑо на %s в коÑа: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "ÐÑеÑка пÑи изÑÑиванеÑо на %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "ÐÑеÑка пÑи изÑÑиванеÑо на %s: не е меÑÑен Ñайл."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "ÐÑкаÑе ли да пÑемеÑÑиÑе избÑаниÑе Ñайлове в коÑа?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "ÐÑемеÑÑване в ÐоÑа"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "ÐÑкаÑе ли оконÑаÑелно да изÑÑиеÑе избÑаниÑе Ñайлове?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "ÐзÑÑиване"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "ÐÑказ"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "ÐзÑÑиване на Ñайлове"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "ÐзÑÑиване на избÑаниÑе Ñайлове"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>ÐаÑин на изÑÑиване</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "ÐÑемеÑÑи в коÑа, вмеÑÑо незабавно изÑÑиване"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>ÐÑ
о</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "ÐабавÑне:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "мÑ"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "ÐÑзиви:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Сила на звÑка:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"ÐÑиÑÑавка за ÐÑ
о\n"
-"ÐÑ Johan Levin, 1999\n"
-"\n"
-"ÐбгÑаждаÑо еÑ
о Ð¾Ñ Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "ÐÑ
о"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "ÐÑиÑÑавка за FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1251,55 +1223,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "ÐÑиÑÑавка за FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "ÐÑиÑÑавка FileWriter"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "ФоÑÐ¼Ð°Ñ Ð½Ð° изÑ
Ð¾Ð´Ð½Ð¸Ñ Ñайл:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "ÐаÑÑÑойване"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "ÐапамеÑи в оÑигиналнаÑа диÑекÑоÑиÑ"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "ÐапамеÑи на избÑано мÑÑÑо"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Ðапка на изÑ
Ð¾Ð´Ð½Ð¸Ñ Ñайл:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "ÐÐ·Ð±Ð¾Ñ Ð½Ð° папка"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "ÐзвлиÑане на име оÑ:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "ÐенеÑиÑай име на Ñайл оÑ:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "маÑкеÑи на оÑÐ¸Ð³Ð¸Ð½Ð°Ð»Ð½Ð¸Ñ Ñайл"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "оÑигинално име"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "ÐÑигинално име на Ñайл"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Ðа не Ñе изÑÑзва ÑазÑиÑениеÑо на Ñайла"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "ÐомеÑÑÑ Ð½Ð° запиÑа да пÑедÑеÑÑва имеÑо мÑ"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1329,165 +1301,169 @@ msgstr ""
"ако не ÑÑе, пиÑеÑе до Free Software Foundation, Inc., 51 Franklin Street,\n"
"Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "ÐÑиÑÑавка FileWriter"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "ÐвÑомаÑиÑно"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "ÐбÑо СÑеÑео"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "СÑеÑео"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Ðоно"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 наÑÑÑойки"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_ÐобÑе"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "ÐлгоÑиÑÑм за каÑеÑÑво:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "ÐзÑ
одна ÑеÑÑоÑа:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr "ÐзÑ
одна ÑеÑÑоÑа на диÑкÑеÑизаÑиÑ:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Ð¥Ñ)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "ЧеÑÑоÑа на ÑгÑÑÑÑване:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ЧеÑÑоÑа за Ð±Ð¸Ñ (кбвÑ):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "ЧеÑÑоÑа на ÑгÑÑÑÑване:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Режим на звÑка:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "Разни:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "ÐÑидÑÑжане кÑм ISO ÑÑвмеÑÑимоÑÑ"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "ÐÑеÑна заÑиÑа"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "ÐаÑеÑÑво"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "ÐкÑивиÑане VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Ðид:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR ÐпÑии:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Ðинимална ÑеÑÑоÑа за Ð±Ð¸Ñ (кбвÑ):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "ÐакÑимална ÑеÑÑоÑа за Ð±Ð¸Ñ (кбвÑ):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "ÐÑидÑÑжане кÑм минимална ÑеÑÑоÑа за биÑ"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR ÐпÑии:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "СÑедна ÑеÑÑоÑа за Ð±Ð¸Ñ (кбвÑ):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "Ðиво на каÑеÑÑвоÑо на VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Ðа не Ñе запиÑва ÑиÑÑл за Xing VBR"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "СÑойноÑÑи на ÑамкаÑа:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "ÐаÑÐºÐµÑ âÐаÑиÑено Ð¾Ñ ÐºÐ¾Ð¿Ð¸Ñанеâ"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "ÐаÑÐºÐµÑ âÐÑигиналâ"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "СÑойноÑÑи на ID3:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "ÐÑинÑдиÑелно добавÑне на маÑÐºÐµÑ Ð¾Ñ 2-Ñа веÑÑиÑ"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Ðобави Ñамо маÑÐºÐµÑ 1-ва веÑÑиÑ"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Ðобави Ñамо маÑÐºÐµÑ 2-Ñа веÑÑиÑ"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "ÐаÑкеÑи"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "ÐаÑÑÑойка на Vorbis кодиÑане"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Ðиво на каÑеÑÑвоÑо (0-10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "РазкодиÑане на FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "по-малко загÑби"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1499,11 +1475,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "РазкодиÑане на FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1511,11 +1483,19 @@ msgstr ""
"ÐÑиÑÑавка GIO за Audacious\n"
"ÐвÑоÑÑки пÑава 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "ÐÑиÑÑавка GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1535,534 +1515,607 @@ msgstr ""
"\n"
"ÐиÑенз: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL оÑÑилоÑкоп"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-msgstr ""
-"ÐÑиÑÑавка ÐÑÑзи клавиÑи на Gnome\n"
-"ÐозволÑва Ðи да конÑÑолиÑаÑе плеÑÑа Ñ Ð±ÑÑзиÑе клавиÑи на Gnome.\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
"\n"
-"ÐвÑоÑÑки пÑава (C) 2007-2008 "
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
msgstr "ÐÑÑзи клавиÑи за Gnome"
-#: src/gtkui/columns.c:34
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "ÐÐ¾Ð¼ÐµÑ Ð½Ð° запиÑ"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Ðаглавие"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "ÐзпÑлниÑел"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Ðодина"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "ÐлбÑм"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "ÐзпÑлниÑел на албÑм"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "ÐапиÑ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "ÐанÑ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "ÐозиÑÐ¸Ñ Ð½Ð° опаÑкаÑа"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "ÐÑемеÑÑаене"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "ÐÑÑ Ð´Ð¾ Ñайла"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Ðме на Ñайла"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "ÐзбÑано заглавие"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ЧеÑÑоÑа за биÑ"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "ÐалиÑни колони"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "Ðоказване колони"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "ÐнÑÑÑÑÐ¼ÐµÐ½Ñ Ð·Ð° ÑÑÑÑене"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Ðанел влÑво"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Ðанел вдÑÑно"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Ðанел оÑгоÑе"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Ðанел оÑдолÑ"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Ðез панел"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "ÐеакÑивиÑане"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "ÐнÑÑÑÑÐ¼ÐµÐ½Ñ Ð·Ð° ÑÑÑÑене"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_ÐÑвоÑÑне на Ñайлове..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "ÐÑ_ваÑÑне на ÐнÑеÑÐ½ÐµÑ Ð°Ð´ÑеÑ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_ÐобавÑне на Ñайлове..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "_ÐобавÑне на ÐнÑеÑÐ½ÐµÑ Ð°Ð´ÑеÑ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "_ÐиблиоÑека за ÑÑÑÑене"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "Ð_ÑноÑно..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "_ÐаÑÑÑойки..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_ÐзÑ
од"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "Ð_зпÑлнение"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Ð_Ñеменно ÑпиÑане"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_СпиÑане"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_ÐÑедиÑен"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_СледваÑ"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "ÐовÑ_оÑение"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "РазбÑÑка_но"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "_Ðез пÑеÑкаÑане кÑм ÑледваÑо изпÑлнение"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "СпÑи Ñ_лед Ñази пеÑен"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_ÐнÑоÑмаÑÐ¸Ñ Ð·Ð° пеÑен..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "ÐÑе_ÑкаÑане до вÑеме..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "ÐÑеÑкаÑане до п_еÑен..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "ÐаÑална ÑоÑка н_а повÑоÑение"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "ÐÑайна ÑоÑка на повÑоÑе_ниe"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "Ðз_ÑиÑÑване на ÑоÑкиÑе на повÑоÑение"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Ðо _Ðаглавие"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "Ðо _име на Ñайл"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "Ðо Ðме на Ñайл"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Ðо _пÑÑ Ð´Ð¾ Ñайл"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Ðо _Ð½Ð¾Ð¼ÐµÑ Ð½Ð° запиÑ"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Ðо _ÐзпÑлниÑел"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Ðо ал_бÑм"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Ðо ÐзпÑлниÑел на ÐлбÑм"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Ðо _ÐаÑа на излизане"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "Ðо _ÐанÑ"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "Ðо в_ÑемеÑÑаене"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Ðо _ÐÑÑ Ð´Ð¾ Ñайл"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Ðо ÐзбÑано _заглавие"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Ð_бÑÑÑане на подÑедбаÑа"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "Сл_ÑÑаен Ñед"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_ÐзпÑлни Ñози ÑпиÑÑк"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_ÐзпÑлнение/ÐодновÑване"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_ÐпÑеÑнÑване"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_СоÑÑиÑане"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "Ðо_дÑеждане на избÑаниÑе"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "ÐÑемаÑ
ване на по_вÑаÑÑÑи Ñе"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "ÐÑемаÑ
ване на _липÑваÑиÑе Ñайлове"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Ðова"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "_ÐÑеименÑване..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "ÐÑемаÑ
_ване"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_ÐнаÑÑне..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_ÐзнаÑÑне..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "_УпÑавление на ÑпиÑÑка..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_УпÑавление на опаÑкаÑа..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "УвелиÑаване на _звÑка"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "ÐамалÑване на з_вÑка"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_ТонкоÑекÑоÑ"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "Ð_ÑекÑи..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Ðоказване на панел Ñ _менÑ"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Ðоказване на ленÑа Ñ _инÑоÑмаÑиÑ"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Ðоказване на пÑедÑÑавÑне в ÑÑÑлба Ñ Ð¸Ð½ÑоÑмаÑиÑ"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Ðоказване на ленÑа на _ÑÑÑÑоÑниеÑо"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Ðока_жи оÑÑаваÑо вÑеме"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "Ðиз_ÑализаÑии..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Файл"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_ÐзпÑлнение"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_СпиÑÑк"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_УÑлÑги"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_ÐзÑ
одÑÑ Ð¿Ð¾Ñок"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Ðзглед"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_ÐÑомÑна на ÑÑÑÑоÑниеÑо в опаÑкаÑа"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "_ÐÑÑÑзване"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_ÐопиÑане"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_ÐоÑÑавÑне"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "ÐÐ·Ð±Ð¾Ñ Ð½Ð° _вÑиÑки"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "Ð_ÑеименÑване..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>ÐодпÑозоÑÑи в ÑпиÑÑка</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "Ðинаги да Ñе Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ñ Ð¿Ð¾Ð´Ð¿ÑозоÑÑиÑе"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "Ðоказване на бÑоÑÑ Ð½Ð° запиÑиÑе"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "Ðоказване на бÑÑони за заÑваÑÑне"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>Ðолони в ÑпиÑÑка</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "Ðоказване на анÑеÑки"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Разни</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr "ÐÑевÑÑÑане ÑÑÑ ÑÑÑелкиÑе:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "ÐÑевÑÑÑане пÑи ÑмÑна на пеÑенÑа"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK Ðзглед"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ÐапÑлване..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "еднозвÑÑие"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "многозвÑÑие"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d канал"
msgstr[1] "%d канали"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d кбвÑ"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Режим âÐдиниÑенâ."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Режим âСпиÑÑкâ."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "СпиÑане Ñлед пеÑенÑа."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "ÐÑедиÑен запиÑ"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "ÐзпÑлнение"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "ÐÑеменно ÑпиÑане/ÐÑзобновÑване"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "СпиÑане"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Ð¡Ð»ÐµÐ´Ð²Ð°Ñ Ð·Ð°Ð¿Ð¸Ñ"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "ÐапÑед Ñ 5 ÑекÑнди"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "Ðазад Ñ 5 ÑекÑнди"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "ÐаглÑÑаване"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "УвелиÑаване на звÑка"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "ÐамалÑване на звÑка"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "ÐÑеÑкаÑане до Ñайл"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "ÐÑевклÑÑване Ð¼ÐµÐ¶Ð´Ñ Ð¿ÑозоÑÑиÑе"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Ðоказване на ÐÑозоÑÐµÑ Ð²ÑÑÑ
Ñ ÐµÐºÑана"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "ÐÑевклÑÑване на повÑоÑение"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "ÐÑевклÑÑване на ÑазбÑÑкване"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "ÐÑевклÑÑване на ÑпиÑане Ñлед ÑекÑÑиÑÑ"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Ðздигане на пÑозоÑÑиÑе"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(без)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2074,15 +2127,11 @@ msgstr ""
"\n"
"ÐÑкаÑе ли да пÑодÑлжиÑе?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "ÐбвÑÑзани бÑÑони на миÑкаÑа"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "ÐаÑÑÑойка на пÑиÑÑавкаÑа за оÑновни бÑÑзи клавиÑи"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2090,23 +2139,27 @@ msgstr ""
"ÐабеÑеÑе комбинаÑÐ¸Ñ Ð¾Ñ ÐºÐ»Ð°Ð²Ð¸Ñи в ÑекÑÑовоÑо поле.\n"
"ÐожеÑе да вклÑÑеÑе и бÑÑони Ð¾Ñ Ð¼Ð¸ÑкаÑа."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "ÐÑÑзи клавиÑи:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>ÐейÑÑвие:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>ÐбвÑÑзване на клавиÑ:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "_ÐобавÑне"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "ÐбÑи бÑÑзи клавиÑи"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2132,60 +2185,51 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "ÐбÑи бÑÑзи клавиÑи"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK ÐзÑ
од"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "СвÑÑзване кÑм вÑиÑки налиÑни поÑÑове на jack"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "СвÑÑзване Ñамо на изÑ
одÑÑиÑе поÑÑове"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "Ðез ÑвÑÑзване кÑм никой поÑÑ"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "Режим на ÑвÑÑзване:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "ÐкÑивиÑай извеждане на дебÑг"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"ÐазиÑан на xmms-jack, Ð¾Ñ Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"ÐÑенапиÑан за Audacious Ð¾Ñ Giacomo Lozito"
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK ÐзÑ
од"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s ÐаÑÑÑойки"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "ÐаÑÑÑойки на LADSPA ÑÑеда"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "ÐÑÑиÑа кÑм модÑл:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2196,25 +2240,25 @@ msgstr ""
"След добавÑне на Ñези пÑÑиÑа, наÑиÑнеÑе ÐнÑÐµÑ Ð·Ð° ÑканиÑане за нови пÑиÑÑавки."
"</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "ÐоÑÑÑпни пÑиÑÑавки:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "ÐкÑивиÑане"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "ÐкÑивиÑани пÑиÑÑавки:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "ÐаÑÑÑойки"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2222,47 +2266,15 @@ msgstr ""
"ÐоÑÑ Ð½Ð° LADSPA за Audacious\n"
"ÐвÑоÑÑки пÑава 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA СÑеда"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: не може да Ñе оÑбележи поддÑÑжка на LIRC\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: не може да Ñе пÑоÑеÑе Ñайла Ñ Ð½Ð°ÑÑÑойка на LIRC\n"
-"%s: Ð¼Ð¾Ð»Ñ Ð¿ÑоÑеÑеÑе докÑменÑаÑиÑÑа на LIRC\n"
-"%s: как да ÑÑздадем подÑ
одÑÑ Ñайл Ñ Ð½Ð°ÑÑÑойки\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: Ð¾Ð¿Ð¸Ñ Ð·Ð° повÑоÑно ÑвÑÑзване...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: неизвеÑÑна команда â%sâ\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: пÑекÑÑнаÑа вÑÑзка Ð¾Ñ LIRC\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: Ð¾Ð¿Ð¸Ñ Ð·Ð° повÑоÑна вÑÑзка на вÑеки %d ÑекÑнди...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "ÐÑиÑÑавка LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2291,73 +2303,81 @@ msgstr ""
"\n"
"Ðа повеÑе инÑоÑмаÑÐ¸Ñ Ð¾ÑноÑно LIRC, вижÑе http://lirc.org"
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>ÐÑÑзка</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "ÐовÑоÑно ÑвÑÑзване кÑм LIRC ÑÑÑвÑÑа"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "ÐзÑакайÑе пÑеди да опиÑаÑе повÑоÑно ÑвÑÑзване:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "ÐÑиÑÑавка LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "ÐÑиÑÑавка LyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "ÐÑма налиÑен ÑекÑÑ"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "ÐÑеÑка"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "ÐеÑÑпеÑ
пÑи извлиÑане на %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "ÐÑеÑка"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "ÐеÑÑпеÑ
пÑи ÑазделÑне на %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "ТÑÑÑене на ÑекÑÑ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "ÐипÑваÑи меÑаданни за пеÑенÑа"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "СвÑÑзване кÑм lyrics.wikia.com..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "ÐÑиÑÑавка LyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "ÐÑиÑÑавка LyricWiki (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "СпиÑÑк M3U"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "ÐенеÑаÑÐ¾Ñ Ð½Ð° ÑдаÑи"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "ÐенеÑаÑÐ¾Ñ Ð½Ð° ÑдаÑи: %d Ñвм"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "ÐенеÑаÑÐ¾Ñ Ð½Ð° ÑдаÑи: %d Ñвм %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2371,11 +2391,11 @@ msgstr ""
"напÑ. tact://77 за изпÑлнÑване на 77 ÑдаÑа в минÑÑа\n"
"или tact://60*3/4 за изпÑлнÑване на 60 Ñвм в ÑÐ°ÐºÑ 3/4"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "ÐенеÑаÑÐ¾Ñ Ð½Ð° ÑдаÑи"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "СмеÑиÑел на канали"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2383,152 +2403,184 @@ msgstr ""
"ÐÑиÑÑавка ÑмеÑиÑел на канали за Audacious\n"
"ÐвÑоÑÑки пÑава 2011-2012 John Lindgren и "
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>СмеÑиÑел на канали</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "ÐзÑ
одни канали:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "СмеÑиÑел на канали"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "ÐÑиÑÑавка MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "ÐÑеÑка пÑи ÑвÑÑзване кÑм MMS ÑÑÑвÑÑ"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (ÐодÑлен плеÑÑ)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>ÐÑлбоÑина</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-биÑов"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-биÑов"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Ðанали</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "Ðай-близкиÑÑ (най-бÑÑз)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Ðинеен (бÑÑз)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Шпонка (добÑÑ)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "ÐногоÑазен (най-добÑÑ)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr "<b>ЧеÑÑоÑа на диÑкÑеÑизаÑиÑ</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 кХÑ"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 кХÑ"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 кХÑ"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 кХÑ"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Ðиво:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "СÑез:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>ÐÑ
о</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>УÑилване на ниÑкиÑе</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>ÐбгÑÐ°Ð¶Ð´Ð°Ñ Ð·Ð²Ñк</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>ÐÑедÑÑилваÑел</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "ÐадÑ
вÑÑлÑне на ÑеÑÑоÑаÑа на диÑкÑеÑизаÑиÑ"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "ÐамалÑване на ÑÑма"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "ÐзпÑлнÑване на Amiga MODs"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>ÐовÑоÑение</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "ÐÑой повÑоÑениÑ:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "Ðа непÑекÑÑнаÑо повÑоÑение, задайÑе ÑÑойноÑÑ -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (ÐодÑлен плеÑÑ)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "ÐбгÑÐ°Ð¶Ð´Ð°Ñ Ð·Ð²Ñк"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "ÐÑиÑÑавка MPG123"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>ÐопÑлниÑелни</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "ÐбгÑÐ°Ð¶Ð´Ð°Ñ Ð·Ð²Ñк"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "УÑлÑга MPRIS 2"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "ÐÑиÑÑавка Neon HTTP/HTTPS"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "ÐÑеÑка пÑи пÑенаÑоÑванеÑо"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "ÐеизвеÑÑна HTTP гÑеÑка"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "ÐÑеÑка пÑи заÑеждане на URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "ТвÑÑде много пÑенаÑоÑваниÑ"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "СпÑÑн"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious не изпÑлнÑва ниÑо."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Ð£Ð²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð½Ð° ÑабоÑÐ½Ð¸Ñ Ð¿Ð»Ð¾Ñ"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2563,55 +2615,64 @@ msgstr ""
"You should have received a copy of the GNU General Public License along with "
"this program. If not, see <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Ðоказване на бÑÑониÑе за ÑпÑавление"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Ðинаги да Ñе показва извеÑÑие"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Ð£Ð²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð½Ð° ÑабоÑÐ½Ð¸Ñ Ð¿Ð»Ð¾Ñ"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "ÐклÑÑи име на албÑм в ÑведомлениÑÑа"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Ðоказване"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "ÐÑеменно ÑпиÑане"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "СледваÑ"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. УÑÑÑойÑÑво по подÑазбиÑане"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "ÐзÑ
од OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "ÐзÑ
од OSS3"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "УÑÑÑойÑÑво по подÑазбиÑане"
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "ÐÑдио ÑÑÑÑойÑÑво:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Ðзползване на алÑеÑнаÑивно ÑÑÑÑойÑÑво:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Ðапази нивоÑона звÑка Ð¼ÐµÐ¶Ð´Ñ ÑеÑииÑе."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "ÐкÑивиÑане на ÑоÑмаÑи, напÑавени Ð¾Ñ OSS ÑоÑÑÑеÑ."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "ÐкÑивиÑане на екÑклÑзивен Ñежим, за пÑедоÑвÑаÑÑване на ÑмеÑване."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2625,19 +2686,35 @@ msgstr ""
"ÐиÑ
иÑкал да благодаÑÑ Ð½Ð° Ñ
оÑаÑа Ð¾Ñ #audacious, оÑобено на Tony Vroon и John "
"Lindgren и, ÑазбиÑа Ñе, на авÑоÑиÑе на пÑедиÑнаÑа веÑÑÐ¸Ñ Ð½Ð° пÑиÑÑавкаÑа."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "ÐзÑ
од OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "ÐениджÑÑ Ð½Ð° плейлиÑÑа"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "ÐлеменÑи"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_ÐÑемаÑ
ване"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "ÐÑеименÑван_е"
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "СпиÑÑÑи PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "РазкодиÑане OpenPSF PSF1/PSF2"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "ÐзÑ
од PulseAudio"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2671,11 +2748,68 @@ msgstr ""
"ако не ÑÑе, пиÑеÑе до Free Software Foundation, Inc., 51 Franklin Street,\n"
"Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "ÐзÑ
од PulseAudio"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "ÐзÑ
од QtMultimedia"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "РабоÑи ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "ТÑÑÑене"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_ÐÑваÑÑне на Ðапка ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_ÐобавÑне на Ðапка ..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "ÐÑовеÑка на лог ..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "ÐÑваÑÑне на Ñайлове"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "ÐобавÑне на Ñайлове"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ÐÑедиÑен"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "ÐовÑоÑение"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "ÐÑеÑкаÑане"
-#: src/resample/resample.c:165
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Qt Ðзглед"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "ÐÑеобÑазÑваÑел на ÑеÑÑоÑи"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2683,99 +2817,107 @@ msgstr ""
"ÐÑиÑÑавка за пÑомÑна на ÑеÑÑоÑаÑа за Audacious\n"
"ÐвÑоÑÑки пÑава 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "ЧеÑÑоÑно пÑеÑкаÑане/повÑаÑÑне"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Ðинейна инÑеÑполаÑиÑ"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "ÐÑÑзоÑинÑ
Ñонна инÑеÑполаÑиÑ"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "СÑедноÑинÑ
Ñонна инÑеÑполаÑиÑ"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Ðай-добÑа ÑинÑ
Ñонна инÑеÑполаÑиÑ"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>ÐбÑÑÑане</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "ÐеÑод:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "ЧеÑÑоÑа:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>ÐланиÑани ÑеÑÑоÑи</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Ðзползване на планиÑани ÑеÑÑоÑи"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 кХÑ:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 кХÑ:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 кХÑ:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 кХÑ:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 кХÑ:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 кХÑ:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 кХÑ:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 кХÑ:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 кХÑ:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 кХÑ:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "ÐÑеобÑазÑваÑел на ÑеÑÑоÑи"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "ÐобÑе. СподелÑне за поÑÑебиÑел: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "ÐÑмаÑе пÑава"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"ÐоÑеÑеÑе вÑÑзкаÑа, за да позволиÑе на Audacious, да ÑÐ¿Ð¾Ð´ÐµÐ»Ñ ÐаÑиÑе "
"изпÑлнениÑ:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"ÐапазеÑе Ñози пÑозоÑÐµÑ Ð¾ÑвоÑен и оÑново избеÑеÑе âÐÑовеÑка на пÑаваâ.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2783,34 +2925,38 @@ msgstr ""
"Ðе Ñе пÑиÑеÑнÑвайÑе. ÐаÑиÑе ÑподелÑÐ½Ð¸Ñ Ñа запамеÑени на компÑÑÑÑа.\n"
"Ще бÑÐ´Ð°Ñ Ð¸Ð·Ð¿ÑаÑени веднага Ñлед каÑо на Audacious Ð¼Ñ Ð±Ñде позволено."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "ÐнÑеÑÐ½ÐµÑ Ð¿Ñоблем."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "ÐÑзникна пÑоблем пÑи ÑвÑÑзване Ñ Last.fm. ÐпиÑайÑе по-кÑÑно."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "ÐÑовеÑка..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "Ð_ÑовеÑка на пÑава"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_ÐÑÑÑане на пÑава"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"ÐÑжно е да позволиÑе на Audacious да ÑÐ¿Ð¾Ð´ÐµÐ»Ñ Ð·Ð°Ð¿Ð¸ÑиÑе вÑв ÐаÑиÑÑ Last.fm "
"пÑоÑил.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "СподелÑне 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2818,7 +2964,7 @@ msgstr ""
"ÐÑиÑÑавкаÑа СподелÑне на пеÑен не може да Ñе ÑÑаÑÑиÑа.\n"
"Ðоже би има пÑоблем Ñ Ð¸Ð½ÑÑалаÑиÑÑа."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2835,11 +2981,7 @@ msgstr ""
"ÐлагодаÑноÑÑи на John Lindgren за оказанаÑа Ð¿Ð¾Ð¼Ð¾Ñ Ð² Ñози пÑоекÑ.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "СподелÑне 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2847,7 +2989,11 @@ msgstr ""
"Audacious използва подобÑена веÑÑÐ¸Ñ Ð½Ð° СподелÑне на пеÑни за Last.fm.\n"
"ÐолÑ, пÑовеÑеÑе наÑÑÑойкиÑе на пÑиÑÑавкаÑа за СподелÑне на пеÑни."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "ÐзÑ
од SDL"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2855,81 +3001,56 @@ msgstr ""
"ÐзÑ
одна пÑиÑÑавка SDL за Audacious\n"
"ÐвÑоÑÑки пÑава 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "ÐзÑ
од SDL"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "ÐиблиоÑека"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "ÐÐµÐ¿Ð¾Ð·Ð½Ð°Ñ Ð¸Ð·Ð¿ÑлниÑел"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "ÐÐµÐ¿Ð¾Ð·Ð½Ð°Ñ Ð°Ð»Ð±Ñм"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" на %s Ð¾Ñ %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d ÑезÑлÑаÑ"
+msgstr[1] "%d ÑезÑлÑаÑи"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d албÑм"
-msgstr[1] "%d албÑми"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d ÑкÑиÑ)"
+msgstr[1] "(%d ÑкÑиÑи)"
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d пеÑен"
-msgstr[1] ""
-"%s\n"
-" %s, %d пеÑни"
-
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d пеÑен Ð¾Ñ %s"
-msgstr[1] ""
-"%s\n"
-" %d пеÑни Ð¾Ñ %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d пеÑен"
+msgstr[1] "%d пеÑни"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "на Ñози жанÑ"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "на"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "оÑ"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_СÑздай ÑпиÑÑк"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_ÐобавÑне в ÑпиÑÑк"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "ТÑÑÑене в библиоÑека"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2937,679 +3058,769 @@ msgstr ""
"Ðа да внеÑеÑе мÑзикална библиоÑека в Audacious, избеÑеÑе папка и кликнеÑе на "
"бÑÑона \"ÐпÑеÑнÑване\"."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "ÐÐ¾Ð»Ñ Ð¸Ð·ÑакайÑе..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "ÐÐ·Ð±Ð¾Ñ Ð½Ð° папка"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "SID ÐлеÑÑ"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>ÐзÑ
од</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Ðанали:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>ÐмÑлаÑиÑ</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "ÐмÑлиÑай MOS 8580 (по подÑазбиÑане: MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "Ðе избиÑай авÑомаÑиÑно модел на Ñип"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "ÐмÑлаÑÐ¸Ñ Ð½Ð° ÑилÑÑÑ"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "СкоÑоÑÑ Ð½Ð° ÑаÑовника:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "Ðе избиÑай авÑомаÑиÑно ÑкоÑоÑÑ Ð½Ð° ÑаÑовника"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>ÐÑеме на вÑзпÑоизвеждане</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "Ðадай макÑимална пÑодÑлжиÑелноÑÑ Ð½Ð° изпÑлнениеÑо:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Уведомление</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Таван:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "дÐ"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "ÐÑваÑÑне на Ñайлове..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "ÐÑваÑÑне на инÑеÑÐ½ÐµÑ Ð°Ð´ÑеÑ..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "ТÑÑÑене в библиоÑекаÑа"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "ÐÑзпÑоизвеждане"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "СпиÑÑк за изпÑлнение"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Ðзглед"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "УÑлÑги"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "ÐÑноÑно..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "ÐаÑÑÑойки..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "ÐзÑ
од"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "ÐнÑоÑмаÑÐ¸Ñ Ð·Ð° пеÑен..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "ÐовÑоÑение"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "ÐÑеÑкаÑане"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Ðез пÑодÑлжаване в ÑпиÑÑка"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "СпиÑане Ñлед Ñази пеÑен"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ÐÑедиÑен"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "Ðадаване на Ð-РповÑоÑение"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "ÐзÑиÑÑване на Ð-РповÑоÑение"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "ÐÑеÑкаÑане до пеÑен..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "ÐÑеÑкаÑане до вÑеме..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "ÐÑзпÑоизвеждане на Ñози ÑпиÑÑк"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Ðов ÑпиÑÑк"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "ÐÑеименÑване на ÑпиÑÑк..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "ÐÑемаÑ
ване на ÑпиÑÑк..."
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "ÐÑедиÑен ÑпиÑÑк"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "Ð¡Ð»ÐµÐ´Ð²Ð°Ñ ÑпиÑÑк"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "ÐнаÑÑне на ÑпиÑÑк..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "ÐзнаÑÑне на ÑпиÑÑк..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "ÐениджÑÑ Ð½Ð° ÑпиÑÑÑи..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "ÐениджÑÑ Ð½Ð° опаÑкиÑе..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "ÐпÑеÑнÑване на ÑпиÑÑк"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Ðоказване на ÑедакÑÐ¾Ñ Ð½Ð° ÑпиÑÑка"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Ðоказване на ÑонкоÑекÑоÑ"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "Ðоказвай оÑÑаваÑо вÑеме"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Ðинаги оÑгоÑе"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "Ðа вÑиÑки ÑабоÑни ÑÑеди"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "Свиване на плеÑÑ"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "Свиване на ÑедакÑоÑа на ÑпиÑÑÑи"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "Свиване на ÑонкоÑекÑоÑ"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Ðвоен РазмеÑ"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "ÐобавÑне на инÑеÑÐ½ÐµÑ Ð°Ð´ÑеÑ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "ÐобавÑне на Ñайлове..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Ðо заглавие"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Ðо име на Ñайла"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr "Ðо Ðме на Ñайл"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "Ðо пÑÑ Ð´Ð¾ Ñайл"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "ÐÑемаÑ
ване на вÑиÑки"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "ÐзÑиÑÑване на опаÑкаÑа"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "ÐÑемаÑ
ване на липÑваÑиÑе Ñайлове"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "ÐÑемаÑ
ване на повÑоÑениÑ"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "ÐÑемаÑ
ване на неизбÑаниÑе"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "ÐÑемаÑ
ване на избÑаниÑе"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "ТÑÑÑене и избиÑане"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "ÐбÑÑÑане на избÑаноÑо"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Ðез избÑани"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "ÐÐ·Ð±Ð¾Ñ Ð½Ð° вÑиÑки"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Ðо ÐлбÑм"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Ðо Ð½Ð¾Ð¼ÐµÑ Ð½Ð° запиÑа"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Ðо ÐзпÑлниÑел"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Ðо ÐлбÑм"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Ðо ÐзпÑлниÑел на ÐлбÑм"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "Ðо даÑа на издаване"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Ðо Ð½Ð¾Ð¼ÐµÑ Ð½Ð° запиÑа"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "СлÑÑаен ÑпиÑÑк"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "ÐбÑÑÑане на ÑпиÑÑка"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "ÐодÑеждане на избÑаниÑе"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "ÐодÑеждане на ÑпиÑÑка"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "ÐзÑÑзване"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "ÐопиÑане"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "ÐоÑÑавÑне"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "Ðа опаÑка/без опаÑка"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "ÐаÑеди подгоÑвени..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "ÐаÑеди авÑомаÑиÑно подгоÑвени..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "ÐаÑеди ÑÑандаÑÑни"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "ÐаÑеди Ñайл Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñвени..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "ÐаÑеди на EQF Ñайл..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "Ðапази подгоÑвено..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "Ðапази авÑомаÑиÑно подгоÑвено..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "Ðапази ÑÑандаÑÑно"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "Ðапази Ñайл Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñвено..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "ÐапамеÑи EQF Ñайл..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "ÐзÑÑий подгоÑвено..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "ÐзÑÑий авÑомаÑиÑно подгоÑвено..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "ÐнаÑÑне на подгоÑвени за Winamp..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "ÐÑÑни до нÑла"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "ÐлаÑиÑеÑки изглед на Winamp"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "ÐапамеÑÑване"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "ÐаÑеждане"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "ÐаÑеди Ñайл Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñвени"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "ÐаÑеди EQF Ñайл"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "Ðапази Ñайл Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñвено"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "ÐапамеÑи EQF Ñайл"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "ÐнаÑÑне на подгоÑвени за Winamp"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Ðададени"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "ÐаÑеждане на пÑедложение"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "ÐаÑеждане на авÑомаÑиÑно пÑедложение"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Ðапазване на пÑедложение"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Ðапазване на авÑомаÑиÑно пÑедложение"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "ÐзÑÑиване на пÑедложение"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "ÐзÑÑиване на авÑомаÑиÑно пÑедложение"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_ÐлеÑÑ:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "ÐлеÑÑ:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "ÐÐ·Ð±Ð¾Ñ Ð½Ð° оÑновен ÑÑиÑÑ Ð·Ð° пÑозоÑеÑа на плеÑÑа:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_СпиÑÑк:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "ÐлейлиÑÑа:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "ÐÐ·Ð±Ð¾Ñ Ð½Ð° ÑÑиÑÑ Ð·Ð° ÑпиÑÑка:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>Ðожа</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>ШÑиÑÑове</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "ÐÐ·Ð±Ð¾Ñ Ð½Ð° ÑаÑÑеÑни ÑÑиÑÑове (поддÑÑжа Ñамо ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "ÐÑевÑÑÑане на заглавиеÑо на пеÑенÑа"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "ÐÑевÑÑÑане на заглавиеÑо на пеÑенÑа в двеÑе поÑоки"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "ÐнализаÑоÑ"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "ÐÑÑилоÑкоп"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "ÐлаÑов оÑпеÑаÑÑк / VU-меÑÑÑ"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "ÐзглÑÑено"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "ÐоÑмално"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "ÐгÑн"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "ÐеÑÑикални линии"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Ðинии"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "СÑÑлбове"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Ðай-бавно"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Ðавно"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "СÑедно"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "ÐÑÑзо"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Ðай-бÑÑзо"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "ТоÑки"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "ÐиниÑ"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "ÐлÑÑно"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Ðед"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "РазмиÑо"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>Ðид</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "Ðид на визÑализаÑиÑ:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>ÐнализаÑоÑ</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "Ðоказвай пикове"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "ÐÑвеÑÑване:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "СÑил:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "Ðадане:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "Ðадане на пиковеÑе:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "ÐÑÑилоÑкопиÑен ÑÑил:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "ЦвÑÑ Ð½Ð° глаÑÐ¾Ð²Ð¸Ñ Ð¾ÑпеÑаÑÑк:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "СÑил на VU-меÑÑÑ:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "ÐбÑи"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "ÐзобÑазÑване"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "ÐÑедÑÑилваÑел"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Ð¥Ñ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Ð¥Ñ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Ð¥Ñ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Ð¥Ñ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Ð¥Ñ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 кХÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 кХÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 кХÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 кХÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 кХÑ"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "ТонкоÑекÑÐ¾Ñ Ð½Ð° Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "ÐÑевÑÑÑане до %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Сила на звÑка: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "ÐаланÑ: %d%% лÑво"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "ÐаланÑ: ÑенÑÑÑ"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "ÐаланÑ: %d%% дÑÑно"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "ÐÐµÐ½Ñ Ñ Ð¾Ð¿Ñии"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "ÐеакÑивиÑане на âÐинаги оÑгоÑеâ"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "ÐкÑивиÑане на âÐинаги оÑгоÑеâ"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "ÐÑÑийка Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð·Ð° Ñайла"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "ÐизÑализаÑии"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "Ðададена е наÑална ÑоÑка на повÑоÑение."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "Ðададена е кÑайна ÑоÑка на повÑоÑение."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "ТоÑкиÑе на повÑоÑение Ñа изÑиÑÑени."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Режим âÐдиниÑенâ."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Режим âСпиÑÑкâ."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "СпиÑане Ñлед пеÑенÑа."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "ТÑÑÑене на запиÑи в акÑÐ¸Ð²Ð½Ð¸Ñ ÑпиÑÑк"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "ТÑÑÑене"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3621,57 +3832,61 @@ msgstr ""
"бÑкваÑа. Ðко не знаеÑе как ÑабоÑи Ñози ÑинÑакÑиÑ, пÑоÑÑо вÑведеÑе ÑаÑÑ Ð¾Ñ "
"Ñова, коеÑо ÑÑÑÑиÑе."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
msgstr "Ðаглавие:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr "ÐлбÑм:"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr "ÐзпÑлниÑел:"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
msgstr "Ðме на Ñайл:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "ÐзÑиÑÑване на пÑедиÑÐ½Ð¸Ñ Ð¸Ð·Ð±Ð¾Ñ Ð¿Ñеди ÑÑÑÑене"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "ÐвÑомаÑиÑно пÑевклÑÑване в опаÑкаÑа за ÑÑвпадаÑиÑе елеменÑи"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "СÑздаване на нов ÑпиÑÑк ÑÑÑ ÑÑвпадаÑиÑе елеменÑи"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audacious РедакÑÐ¾Ñ Ð½Ð° ÑпиÑÑка за изпÑлнение"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d Ð¾Ñ %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "ÐÑÑ
ивиÑана кожа на Winamp 2.x"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "ÐеаÑÑ
ивиÑана кожа на Winamp 2.x"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Ðе може да Ñе ÑÑздаде диÑекÑоÑÐ¸Ñ (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "ÐÑиÑÑавка Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3710,83 +3925,71 @@ msgstr ""
"ако не ÑÑе, пиÑеÑе до Free Software Foundation, Inc., 51 Franklin Street,\n"
"Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "ÐÑиÑÑавка Sndfile"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "ÐÑноÑно изÑ
одна пÑиÑÑавка Sndio"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-"ÐзÑ
одна пÑиÑÑавка Sndio\n"
-"\n"
-"ÐапиÑана Ð¾Ñ Thomas Pfaff <tpfaff at tp76.info>\n"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "ÐеподдÑÑжан ÑоÑмаÑ"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Ðапази и вÑзÑанови звÑка:"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-"Ðе поиÑкан ÑоÑмаÑ, койÑо не Ñе поддÑÑжа Ð¾Ñ ÑÑÑÑойÑÑвоÑо.\n"
-"\n"
-"ÐÐ¾Ð»Ñ Ð¾Ð¿Ð¸ÑайÑе оÑново, но ÑÑÑ ÑÑаÑÑиÑан sndiod(1) ÑÑÑвÑÑ."
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio ÑÑÑÑойÑÑво"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(пÑазно - ознаÑава по подÑазбиÑане)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "ÐобÑе"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "ÐÑомÑна на пеÑен"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Ðоманда за изпÑлнение Ñлед запоÑване на нова пеÑен."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>СÑойноÑÑиÑе, изпÑаÑени до обвивкаÑа, е добÑе да Ñа в "
+"кавиÑки. РпÑоÑивен ÑлÑÑай Ñе кÑие опаÑноÑÑ Ð·Ð° ÑигÑÑноÑÑÑа.</span>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Ðоманда:"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Ðоманди</b>"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Ðоманда за изпÑлнение Ñлед кÑай на пеÑен."
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Ðоманда за изпÑлнение пÑи запоÑване на нова пеÑен:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "Ðоманда за изпÑлнение пÑи доÑÑигане на кÑÐ°Ñ Ð½Ð° ÑпиÑÑка."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Ðоманда за изпÑлнение пÑи кÑай на пеÑен:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Ðоманда за изпÑлнение пÑи кÑай на плейлиÑÑа."
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Ðоманда за изпÑлнение пÑи пÑомÑна на заглавиеÑо на пеÑен (напÑ. пÑи инÑеÑÐ½ÐµÑ "
-"поÑок)"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3800,35 +4003,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"ÐожеÑе да използваÑе ÑледниÑе бÑкви,\n"
-"коиÑо Ñе бÑÐ´Ð°Ñ Ð·Ð°Ð¼ÐµÑÑени, пÑеди изпÑлнениеÑо на командаÑа\n"
-"(не вÑиÑки Ñа полезни за команда пÑи кÑай на ÑпиÑÑка):\n"
-"\n"
-"%F: ЧеÑÑоÑа (Ñ
еÑÑове)\n"
-"%c: ÐÑой канали\n"
-"%f: Ðме на Ñайла (пÑлен пÑÑ)\n"
-"%l: ÐÑемеÑÑаене (милиÑекÑнди)\n"
-"%n или %s: Ðме на пеÑен\n"
-"%r: ЧеÑÑоÑа (биÑове в ÑекÑнда)\n"
-"%t: ÐÑÑÑо в ÑпиÑÑка (%02d)\n"
-"%p: РизпÑлнение (1 или 0)\n"
-"%a: ÐзпÑлниÑел\n"
-"%b: ÐлбÑм\n"
-"%T: Ðаглавие на запиÑ"
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>СÑойноÑÑиÑе, изпÑаÑени до обвивкаÑа, е добÑе да Ñа в "
-"кавиÑки. РпÑоÑивен ÑлÑÑай Ñе кÑие опаÑноÑÑ Ð·Ð° ÑигÑÑноÑÑÑа.</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Ðоманди"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "ÐнÑоÑмаÑÐ¸Ñ Ð·Ð° пеÑен (Qt)"
+
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "ÐÑеизÑиÑлиÑел SoX"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3842,51 +4026,51 @@ msgstr ""
"ÐазиÑан на пÑиÑÑавкаÑа за пÑомÑна на ÑеÑÑоÑаÑа:\n"
"ÐвÑоÑÑки пÑава 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "ÐÑÑзо"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "ÐиÑко"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "ÐиÑоко"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Ðного виÑоко"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "ÐаÑеÑÑво:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "ÐÑеизÑиÑлиÑел SoX"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "СкоÑоÑÑ Ð¸ нива"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>СкоÑоÑÑ Ð¸ нива</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "СкоÑоÑÑ:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Ðива:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "СкоÑоÑÑ Ð¸ нива"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Ðкона на ÑÑÑÑоÑниеÑо"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "ÐаÑÑÑо_йки..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3904,39 +4088,39 @@ msgstr ""
"Тази пÑиÑÑавка пÑедоÑÑÐ°Ð²Ñ Ð¸ÐºÐ¾Ð½Ð° на ÑÑÑÑоÑниеÑо, Ñазположена\n"
"в зонаÑа на ÑиÑÑемниÑе извеÑÑÐ¸Ñ Ð½Ð° мениджÑÑа на пÑозоÑÑиÑе."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>ÐейÑÑвие пÑи пÑевÑÑÑане Ñ Ð¼Ð¸Ñка</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "ÐÑомÑна на ÑилаÑа на звÑка"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "ÐÑомÑна на изпÑлнÑванаÑа пеÑен"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>ÐÑÑги наÑÑÑойки</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "ÐеакÑивиÑане на изÑкаÑÐ°Ñ Ð¿ÑозоÑеÑ"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "ÐаÑваÑÑне в ÑиÑÑемнаÑа Ñабла"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "ÐапÑед в ÑпиÑÑка пÑи пÑивÑÑÑане нагоÑе"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Ðкона на ÑÑÑÑоÑниеÑо"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "ÐопÑлниÑелно ÑÑзвÑÑие"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3946,24 +4130,24 @@ msgstr ""
"\n"
"ÐÑ Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>ÐопÑлниÑелно многозвÑÑие</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "ÐопÑлниÑелно ÑÑзвÑÑие"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "ÐенеÑаÑÐ¾Ñ Ð½Ð° ÑдаÑи"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Ð¥Ñ"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "ÐенеÑаÑÐ¾Ñ Ð½Ð° ÑдаÑи:"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3978,15 +4162,11 @@ msgstr ""
"frequency3;...â\n"
"напÑ. tone://2000;2005 за изпÑлнÑванеÑо на Ñон Ð¾Ñ 2000 Ð¥Ñ Ð¸ Ñон Ð¾Ñ 2005 Ð¥Ñ"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "ÐенеÑаÑÐ¾Ñ Ð½Ð° ÑдаÑи"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "ÐÑемаÑ
ване на глаÑ"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4024,11 +4204,46 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "РазгодиÑане на Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "ÐодÑобноÑÑи за %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"Ðаглавие: %t\n"
+"ÐвÑоÑ: %a\n"
+"ÐÑ: %f\n"
+"ТÑакеÑ: %T\n"
+"ÐоменÑаÑ: %C\n"
+"Тип на Ñипа: %c\n"
+"СÑеÑео: %s\n"
+"ÐонÑÑÑ: %l\n"
+"ЧеÑÑоÑа на Ñипа: %F\n"
+"ЧеÑÑоÑа на плеÑÑа: %P\n"
+"Ðодина: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "РазкодиÑане VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4038,19 +4253,19 @@ msgstr ""
"Ðа оÑноваÑа на in_vtx.dll Ð¾Ñ Roman Sherbakov <v_soft at microfor.ru>\n"
"ÐÑиÑÑавка за Audacious Ð¾Ñ Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "РазкодиÑане VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "РазкодиÑане WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "ÑÑÑ Ð·Ð°Ð³Ñби (ÑмеÑено)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "ÑÑÑ Ð·Ð°Ð³Ñби"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4060,23 +4275,18 @@ msgstr ""
"\n"
"ЧаÑÑ Ð¾Ñ ÐºÐ¾Ð´Ð° е напиÑана Ð¾Ñ Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "РазкодиÑане WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "РазкодиÑане 2SF"
-#: src/xspf/xspf.c:438
-msgid "XML Shareable Playlists (XSPF)"
-msgstr "СподелÑеми ÑпиÑÑÑи XML (XSPF)"
-
-#~ msgid "32.0 kHz:"
-#~ msgstr "32.0 кХÑ:"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>ÐаÑÑÑойки на XSF</b>"
-#~ msgid "88.2 kHz:"
-#~ msgstr "88.2 кХÑ:"
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "ÐгноÑиÑане на дÑлжинаÑа Ð¾Ñ Ñайла"
-#~ msgid "176.4 kHz:"
-#~ msgstr "176.4 кХÑ:"
+#: src/xspf/xspf.cc:89
+msgid "XML Shareable Playlists (XSPF)"
+msgstr "СподелÑеми ÑпиÑÑÑи XML (XSPF)"
diff --git a/po/ca.po b/po/ca.po
index 4cba10c5f79c..402f12b3f666 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -3,16 +3,16 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# Adolfo Jayme Barrientos <fitoschido at ubuntu.com>, 2013
+# Adolfo Jaymeâ¯Barrientos, 2013
# Catalanoic <catalanoic at gmail.com>, 2012
-# frangor <frangor at frangor.info>, 2013
+# Francesc Gordillo i CortÃnez <inactive+frangor at transifex.com>, 2013
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Catalan (http://www.transifex.com/projects/p/audacious/"
"language/ca/)\n"
"Language: ca\n"
@@ -21,51 +21,35 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "estèreo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "envoltant"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
+#: src/aac-raw/aac.cc:18
+msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/aac-raw/aac.c:476
-msgid "AAC (Raw) Decoder"
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "seqüenciat"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr ""
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarma"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarma"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -88,7 +72,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -110,7 +94,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -124,360 +108,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Això és l'avÃs per despertar-se."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr ""
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Recordatori"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Dilluns"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Dimarts"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Dimecres"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Dijous"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Divendres"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Dissabte"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Diumenge"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Parà metres de lâalarma"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Hora"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarma (per defecte) a les:"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Para al cap de:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "hores"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minuts"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Trieu els dies que ha de saltar l'alarma"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Dia"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Per defecte"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Dies"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Fosa"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "segons"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Volum"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Comença a"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Final"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Actual"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Ordre addicional"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "activa"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Llista de reproducció (opcional)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr ""
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Opcions"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Què signifiquen aquestes opcions?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Ajuda"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Art del à lbum"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "Sortida ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Dispositiu PCM per defecte"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Dispositiu de mescla per defecte"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "Dispositiu PCM:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Dispositiu de mescla:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Element de mescla:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Evitar penjar-se per falta de recursos"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr ""
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "Sortida ALSA"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "Connector AMIDI-Plug - Seleccioneu un fitxer SoundFont"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Nom del fitxer"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Mida (octets)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nom:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> Informació MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Format:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Durada (ms):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Num. de pistes:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variable"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Div temps:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> Comentaris MIDI i lletres </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* aquest fitxer MIDI no té comentaris *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* aquest fitxer MIDI no té lletra *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "Tan_car"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (UTF-8 no và lid)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Quant a AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -488,153 +478,147 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr ""
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Rectangle"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Rectangle arrodonit"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Rectangle còncau"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Cap"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Inici de la reproducció"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr ""
"Activa l'OSD quan es reprodueix una entrada de la llista de reproducció"
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Canvi de tÃtol"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Activa l'OSD quan, mentre s'està reproduint, el tÃtol de la cançó canvia "
-"però el nom del fitxer no. Això és útil per a mostrar canvis de tÃtol en "
-"fluxos d'Internet."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Pausa On"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Activa l'OSD quan la reproducció està en pausa."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Pausa Off"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Activa l'OSD quan la reproducció deixa d'estar en pausa."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Posició"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Desplaçament relatiu X:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Desplaçament relatiu Y:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Amplada mà xima de l'OSD:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Opcions multi-monitor"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Mostra l'OSD en:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "tots els monitors"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "el monitor %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Durada (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Visible:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Fosa entrant:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Fosa sortint:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Foses"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Fosa %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Ombra"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Estil de representació"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Colors"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Color %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Habilita activador"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Esdeveniment"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "S'ha detectat un gestor Composite"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -644,112 +628,112 @@ msgstr ""
"tret que sapigueu que ja n'està funcionant un, activeu un gestor Composite o "
"l'OSD no funcionarà correctament"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "La transparència simulada no requereix un gestor Composite"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Transparència"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Transparència simulada"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Transparència real (requereix l'ext. X composite)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "L'extensió Composite no està carregada"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "L'extensió Composite no està disponible"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>OSD de l'Audacious</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - Configuració"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Posició"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animació"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Text"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Decoració"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Llançador"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Misc"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr ""
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr ""
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Color</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr ""
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
-msgstr "Nivell de canal:"
-
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
-msgstr "Tallar freqüència:"
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr ""
-#: src/bs2b/plugin.c:166
+#: src/bs2b/plugin.cc:129
msgid "Presets:"
msgstr "Predefinits:"
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
+msgstr "Nivell de canal:"
+
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
msgstr ""
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr "Tallar freqüència:"
+
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Analitzador d'espectre"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Connector de Ãudio CD"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -761,169 +745,156 @@ msgid ""
"This was a Google Summer of Code 2007 project."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Dispositiu</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Velocitat de lectura:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadades</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Usa CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Usa HTTP en lloc de CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Servidor:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "CamÃ:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Port:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Connector de Ãudio CD"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "LâURI %s no és và lid."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "No sâha trobat la pista %d."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "CD d'audio"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "La unitat està buida."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Tipus de disc no admès."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr ""
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Reprodueix CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Afegeix CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr ""
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Compressió</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Centrar volum"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Marge dinà mic:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr ""
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -933,195 +904,220 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Baixos:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Aguts:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Durada per defecte:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Activa el remostratge d'Ã udio"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Taxa de remostratge:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ignora la durada indicada a les etiquetes SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Incrementa la reverberació"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Descodificador musical de videoconsola"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr ""
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr ""
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr ""
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Cristal·litzador</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intensitat:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr ""
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Elimina"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Cancel·la"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Eco</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Retard:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Retorn:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Volum:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
+#: src/echo_plugin/echo.cc:39
+msgid "Echo"
msgstr ""
-#: src/echo_plugin/echo.c:122
-msgid "Echo"
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1131,55 +1127,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
msgstr ""
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Format del fitxer de sortida:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Configuració"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Desa al directori original"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Desa a un altre directori"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Directori de sortida:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Trieu un directori"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Agafa el nom del fitxer de:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "etiquetes del fitxer originals"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "nom del fitxer original"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Deixa l'extensió del fitxer"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Precedeix el nom del fitxer pel nombre de pista"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1197,165 +1193,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr ""
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Auto"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Estèreo conjunt"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Estèreo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Configuració d'MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Qualitat de l'algoritme:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Freqüència de mostra de sortida:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Flux de bits / Rà tio de compressió:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Flux de bits (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Rà tio de compressió:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Mode d'Ã udio:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Força el compliment estricte de l'està ndard ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Protecció d'errors"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Qualitat"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Activa VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tipus:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Opcions VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Flux de bits mÃnim (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Flux de bits mà xim (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Compliment estricte el flux de bit mÃnim"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Opcions ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Flux de bits mitjà (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "Nivell de qualitat VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Omet escriure la capçalera VBR Xing"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Marca com a copyright"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Marca com a original"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "Etiquetes ID3:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Força l'afegit d'etiquetes ID3 versió 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Només etiquetes v1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Només etiquetes v2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Etiquetes"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Configuració del codificador Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Nivell de qualitat (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr ""
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "sense pèrdues"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1363,21 +1363,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr ""
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "Connector GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1389,530 +1393,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "Analitzador dâespectre OpenGL"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Dreceras del Gnome"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Número d'entrada"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "TÃtol"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Artista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Any"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Ãlbum"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Pista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Gènere"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Posició a la cua"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Durada"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Camà del fitxer"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Nom del fitxer"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "TÃtol personalitzat"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Flux de bits"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Eina de cerca"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Acoblador a l'esquerre"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Acoblador a la dreta"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Acoblador a la part superior"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Acoblador a la part inferior"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Desacoblar"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Desactivar"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Eina de cerca"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Obrir Fitxers..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Obrir _URL..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_Afegir fitxers..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Afegir U_RL..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "_Quant a..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Surt"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "Repro_duir"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "_Pausa"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Atura"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_Anterior"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_Següent"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Repetir"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_Mesclar"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "No ava_nçar la llista de reproducció"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Informació de la cançó..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "_Salta al temps..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "Salta a la _cançó..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Per _tÃtol"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Pel número de _pista"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Per l'_artista"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Per la _data"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Per nom de _fitxer"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Per tÃtol _personalitzat"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Ordre _invers"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "Ordre alea_tori"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "A_ctualitzar"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Ordenar"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Eliminar fitxers _no disponibles"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Nou"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr ""
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importar..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Exportar..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr ""
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Gestor de _cues..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "P_ujar volum"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "_Baixar volum"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Equalitzador"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "_Mostrar barra de menú"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Mostrar barra d'_informació"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr ""
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Mostrar barra d'_estat"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Mostra el temps _restant"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Fitxer"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Reproducció"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Llista de reproducció"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Servei"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "Sorti_da"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Veure"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Enviar/Treure de la cua"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Re_tallar"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Copiar"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Enganxar"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Seleccionar _tot"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr ""
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "InterfÃcie GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Gestió de memòria intermèdia..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "estèreo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d canal"
msgstr[1] "%d canals"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Mode únic"
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Mode de llista de reproducció"
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Parar després de la cançó."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr ""
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Reprodueix"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pausa/Represa"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Para"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr ""
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Silencia"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Puja el volum"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Baixa el volum"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr ""
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Activa l'OSD (sobre-impressió)"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(cap)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1924,15 +2005,11 @@ msgstr ""
"\n"
"Voleu continuar?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Vinculació dels botons del ratolÃ"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Configuració del connector de tecles rà pides globals"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -1940,23 +2017,27 @@ msgstr ""
"Premeu una combinació de tecles dins del camp de text.\n"
"També podeu vincular botons del ratolÃ."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Tecles rà pides:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Acció:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Vinculació de tecles:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr ""
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1971,127 +2052,90 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
msgstr ""
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr ""
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "Parà metres %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Parà metres del servidor LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Camà de mòduls:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
"After adding new paths, press Enter to scan for new plugins.</small>"
msgstr ""
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Connectors disponibles: "
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Activa"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Connectors habilitats:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Configuració"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr ""
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: no s'ha pogut inicialitzar el suport per a LIRC\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
msgstr ""
-"%s: no s'ha pogut llegir el firxer de configuració de LIRC\n"
-"%s: si us plau, llegiu la documentació de LIRC, per a saber\n"
-"%s: com crear un fitxer de configuració adequat\n"
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: tractant de reconnectar...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: ordre desconeguda \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: desconnectat del LIRC\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: s'intentarà reconnectar cada %d segons...\n"
-
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2107,73 +2151,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr ""
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Reconnecta amb el servidor LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr ""
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Error"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Error"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr ""
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr ""
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Generador de compassos: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Generador de compassos: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2182,162 +2234,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
msgstr ""
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr ""
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Canals de sortida:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
+#: src/mms/mms.cc:35
+msgid "MMS Plugin"
msgstr ""
-#: src/mms/mms.c:195
-msgid "MMS Plugin"
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
msgstr ""
-#: src/modplug/plugin_main.c:55
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>Resolució</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8 bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr ""
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr ""
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Nivell:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Reducció de soroll"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Repeteix</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "Comptatge de repeticions:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "Per repetir indefinidament, definiu el nombre a -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
msgstr ""
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "So envolvent"
-
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr ""
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "So envolvent"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr ""
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr ""
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Aturat"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious no està reproduint."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr ""
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2357,55 +2441,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Mostra"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pausa"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Següent"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Dispositiu per defecte"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Dispositiu d'Ã udio:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Usa un dispositiu alternatiu:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr ""
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Activar conversions de format realitzades pel programari OSS."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2414,19 +2507,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
msgstr ""
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr ""
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr ""
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr ""
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2446,143 +2555,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
msgstr ""
-#: src/resample/resample.c:165
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Anterior"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Repeteix"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Barreja"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Convertidor de taxa de mostratge"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Interpolació lineal"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Conversió</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Mètode:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Taxa:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr ""
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22,05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44,1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Convertidor de taxa de mostratge"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "Hi ha un problema de xarxa."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr ""
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2593,93 +2771,72 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr ""
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr ""
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Biblioteca"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Artista desconegut"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Ãlbum desconegut"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" a %s per %s"
-
-#: src/search-tool/search-tool.c:631
-#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d à lbum"
-msgstr[1] "%d à lbums"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-"%s\n"
-" %s, %d cançó"
msgstr[1] ""
-"%s\n"
-" %s, %d cançons"
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Crear llista de reproducció"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Afegir a la llista de reproducció"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Cercar biblioteca"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2687,679 +2844,769 @@ msgstr ""
"Per importar la vostra col·lecció musical en lâAudacious, trieu una carpeta "
"i feu clic a la icona «Actualitza»."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Esperi si us plau..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Seleccioneu un directori"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Reproducció"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Llistes"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Finestres"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Repeteix"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Barreja"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Discontinua la reproducció programada"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Anterior"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Llista de reproducció nova"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Mostra l'editor de llistes"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Mostra l'equalitzador"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Sempre per sobre"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Per tÃtol"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Per nom de fitxer"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Treu tots els elements"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Neteja la cua"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Treu els fitxers no disponibles"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Treu els duplicats"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Treu els no seleccionats"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Treu els seleccionats"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Cerca i selecciona"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Inverteix la selecció"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Selecciona no res"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Selecciona tots els elements"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Per à lbum"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Pel número de pista"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Per l'artista"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Per à lbum"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Pel número de pista"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Barreja la llista"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Inverteix la llista"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Ordena els seleccionats"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Ordena la llista"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Retallar"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Copiar"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Enganxar"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "InterfÃcie del Winamp clà ssic"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Desa"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Carrega"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Perfils"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Carrega un perfil"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Carregar auto-predefinit"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Desa el perfil"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Desar auto-predefinit"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Esborra el perfil"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Suprimir auto-predefinit"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Reproductor:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Trieu la fosa de la finestra principal:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Llista de reproducció:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Trieu la fosa de la llista de reproducció:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Utilitzar tipografies de mapa de bits (nomes suporta ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Desplaçar el tÃtol de la cançó en ambdues direccions "
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analitzador"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Oscil·loscopi"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Apagat"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normal"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Foc"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "LÃnies"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Barres"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "MÃnim"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Lent"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Mitjà "
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "RÃ pid"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Al mà xim"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Gel"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Suau"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "General"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualització"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Preamplificació"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Equalitzador de l'Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Anar a la posició %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Volum: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balanç: %d%% esquerra"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balanç: centrat"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balanç: %d%% dreta"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Menú d'opcions"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Desactiva 'Sempre per sobre'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Activa 'Sempre per sobre'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Informació del fitxer"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Mode únic"
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Mode de llista de reproducció"
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Parar després de la cançó."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Cerca elements en la llista de reproducció activa"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3371,57 +3618,61 @@ msgstr ""
"insensibles a la capitalització. Si no sabeu com funcionen les expressions "
"regulars, podeu escriure literalment el text que busqueu."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "TÃtol: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Ãlbum:"
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Artista: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Nom del fitxer: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Neteja la selecció anterior abans de cercar"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Posa o treu de la cua automà ticament els elements trobats"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Crea una llista de reproducció nova amb els elements trobats"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Editor de llistes de l'Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d de %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Decoració del Winamp 2.x arxivada"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Decoració del Winamp 2.x no arxivada"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "No s'ha pogut crear el directori (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr ""
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3443,78 +3694,72 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
msgstr ""
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
msgstr ""
-#: src/sndio/sndio.c:384
-msgid "sndio device"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "Dâacord"
-
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Canvi de cançó"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Ordre a executar quan l'Audacious comença una nova cançó."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Els parà metres passats a la shell s'han d'encapsular "
+"entre\n"
+"cometes. Altrament seria un risc per a la seguretat.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Ordre:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Ordre a executar cap al final de la cançó."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
msgstr ""
-"Ordre a executar quan l'Audacious arriba al final de la llista de "
-"reproducció."
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Ordre a executar quan canvia el tÃtol d'una cançó (en fluxos de xarxa)."
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3529,20 +3774,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>Els parà metres passats a la shell s'han d'encapsular "
-"entre\n"
-"cometes. Altrament seria un risc per a la seguretat.</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Ordres"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3551,51 +3791,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "RÃ pida"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Baixa"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Alta"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Molt alta"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Qualitat:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Velocitat:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr ""
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Icona dâestat"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3606,63 +3846,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr ""
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Canvia el volum"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Canvia la cançó"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr ""
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Desactiva la finestra emergent"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Tanca a la safata del sistema"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Icona dâestat"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr ""
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr ""
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
msgstr ""
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Generador de tons:"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3671,15 +3911,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr ""
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr ""
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3700,44 +3936,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr ""
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr ""
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
msgstr ""
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "amb pèrdues (hÃbrid)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "amb pèrdues"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
+#: src/xsf/plugin.cc:50
+msgid "2SF Decoder"
msgstr ""
-#: src/xsf/plugin.c:217
-msgid "2SF Decoder"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
msgstr ""
-#: src/xspf/xspf.c:438
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr ""
diff --git a/po/cmn.po b/po/cmn.po
index f1d4192fbb81..6b073935dc15 100644
--- a/po/cmn.po
+++ b/po/cmn.po
@@ -4,14 +4,14 @@
#
# Translators:
# Ruei-Yuan Lu <RueiYuan.Lu at gmail.com>, 2011
-# Wei-Lun Chao <bluebat at member.fsf.org>, 2013
+# è¶æå« <bluebat at member.fsf.org>, 2013
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Chinese (Mandarin) (http://www.transifex.com/projects/p/"
"audacious/language/cmn/)\n"
"Language: cmn\n"
@@ -20,40 +20,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "å®è²é"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "ç«é«è²"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "ç°ç¹"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib ææ¾å¨)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "ç·¨æ²æ©"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib ææ¾å¨)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "鬧é"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -63,11 +51,7 @@ msgstr ""
"\n"
"忬æ¯ç± Adam Feakin è Daniel Stodden 編寫ã"
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "鬧é"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -108,7 +92,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -148,7 +132,7 @@ msgstr ""
" 鬧éè§¸ç¼æå·è¡éåæä»¤ã\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -172,384 +156,371 @@ msgstr ""
" è¥æ¨å¸æå®è¢«é¡¯ç¤ºï¼è«å¾é¸ä¸¦å¨æ¬\n"
" ä½ä¸è¼¸å
¥è¨æ¯ã"
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "鿝æ¨çåéã"
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "æ¨ä»å¤©çæé"
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "æé"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "ææä¸"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "ææäº"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "ææä¸"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "ææå"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "ææäº"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "ææå
"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "æææ¥"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "鬧éè¨å®"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "æé"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "é´é¿æ¼ (é è¨)"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "å¤ä¹
å¾éé³ï¼"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "å°æ"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "åé"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "鏿æ³è¦å¨åªå¹¾å¤©åç¨é¬§é"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "åªå¹¾å¤©"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "é è¨"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "鱿ç¨"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "æ·¡åº"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "ç§"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "é³é"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "åå§é³é"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "æçµé³é"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "ç®åé³é"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "é¡å¤å½ä»¤"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "åç¨"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "ææ¾å表 (é¸ç¨)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "è«é¸æææ¾å表"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "é¸é
"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "éäºé¸é
代表ä»éº¼ææï¼"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "說æ"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "å°è¼¯å°é¢"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA 輸åº"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"Audacious ç ALSA 輸åºå¤æç¨å¼\n"
+"è使¬ 2009-2012 John Lindgren\n"
+"\n"
+"æè¬ William Pitcockï¼ä»æ¯æ°ä¸ä»£ ALSA 輸åºå¤æç¨å¼çä½è
ãç¶ ALSA æåæä¸è¶³"
+"æï¼æä»¥å
¶ç¨å¼ç¢¼åçºåèã"
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "é è¨ PCM è£ç½®"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "é è¨æ··é³å¨è£ç½®"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM è£ç½®ï¼"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "æ··é³å¨è£ç½®ï¼"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "æ··é³å¨å
ä»¶ï¼"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "èçæ¬ è¼éæ»"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI ææ¾å¨)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-"Audacious ç ALSA 輸åºå¤æç¨å¼\n"
-"è使¬ 2009-2012 John Lindgren\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
"\n"
-"æè¬ William Pitcockï¼ä»æ¯æ°ä¸ä»£ ALSA 輸åºå¤æç¨å¼çä½è
ãç¶ ALSA æåæä¸è¶³"
-"æï¼æä»¥å
¶ç¨å¼ç¢¼åçºåèã"
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA 輸åº"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI ææ¾å¨)"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - 鏿 SoundFont æªæ¡"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "æªæ¡å稱"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "å¤§å° (ä½å
çµ)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "å稱ï¼"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI è³è¨ </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "æ ¼å¼ï¼"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "é·åº¦ (毫ç§)ï¼"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "é³è»ç·¨èï¼"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "è®åç"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPMï¼"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg)ï¼"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "æéåå²ï¼"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI å註èæè© </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* éå MIDI æªä¸å
å«åè¨»è³æ *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* éå MIDI æªä¸å
嫿è©è³æ *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "éé(_C)"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (ç¡æç UTF-8 å串)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "éæ¼ AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"模çµå MIDI 鳿¨ææ¾å¨\n"
-"http://www.develia.org/projects.phpï¼p=amidiplug\n"
-"\n"
-"ç± Giacomo Lozito 編寫\n"
-"<james at develia.org>\n"
-"\n"
-"ç¹å¥æè¬â¦\n"
-"\n"
-"Clemens Ladisch è Jaroslav Kysela\n"
-"ææä¾çè»é« aplaymidi è amixerï¼å®å\n"
-"以åæé
ç alsa-lib æä»¶ç¸ç¶æå©æ¼\n"
-"æ´å çè§£ ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"ææä¾ä¸é¯ç midi éµç¤åæ¨\n"
-"\n"
-"Tony Vroon\n"
-"ææä¾æç¨ç測試åå©"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -560,150 +531,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (Audacious OSD)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ç©å½¢"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "åè§ç©å½¢"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "è§è½å¹é·çç©å½¢"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "ç¡"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "éå§ææ¾"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "ç¶ææ¾å表ä¸çé
ç®è¢«ææ¾æè§¸ç¼ OSD"
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "æ¨é¡è®æ´"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"ç¶ææ¾ä¸ææ²æ¨é¡æ¹è®ä½æªåä¸è®æè§¸ç¼ OSDãéå°é¡¯ç¤ºç¶²è·¯ä¸²æµçæ¨é¡å¾æç¨ã"
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "æ«åææ¾"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "ç¶ææ¾æ«åæè§¸ç¼ OSD"
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "è§£é¤æ«å"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "ç¶è§£é¤æ«åæè§¸ç¼ OSD"
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "æ¾ç½®ä½ç½®"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "X 軸ç¸å°ä½ç§»ï¼"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Y 軸ç¸å°ä½ç§»ï¼"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "æå¤§ OSD 寬度ï¼"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "å¤è¢å¹é¸é
"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "顯示 OSDï¼"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "ææè¢å¹"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "è¢å¹ %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "è¨æ (毫ç§)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "顯示ï¼"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "æ·¡å
¥ï¼"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "æ·¡åºï¼"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "åå"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "åå %iï¼"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "é°å½±"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "åç¾æ¨£å¼"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "é¡è²"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "é¡è² %iï¼"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "åç¨è§¸ç¼å¨"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "äºä»¶"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "已嵿¸¬å°åæç¹æç®¡çç¨å¼"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -712,112 +679,112 @@ msgstr ""
"æªåµæ¸¬å°åæç¹æç®¡çç¨å¼ï¼\n"
"é¤éæ¨ç¢ºå®å·²ç¶å·è¡ï¼å¦å OSD å°ç¡æ³æ£ç¢ºåç¨ã"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "åçéæç¹æä¸éè¦ Composite manager"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "éæ"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "åçéæç¹æ"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "ççéæç¹æ (éè¦ X Composite 延伸åè½)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Composite 延伸åè½æªè¼å
¥"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Composite 延伸åè½ä¸åå¨"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - è¨å®"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "ä½ç½®"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "åç«"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "æå"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "è£é£¾"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "觸ç¼"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "éé
"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1ï¼ASXv2 ææ¾å表"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious ææ¾å表 (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>è²å½©</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "æ¨¡ç³æ³¢å½¢"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "樣å¼"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "é¥éçç´ï¼"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "æªæ·é »çï¼"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "樣å¼"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "é »èåæå"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "鳿¨ CD 夿ç¨å¼"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -837,171 +804,156 @@ msgstr ""
"\n"
"鿝 Google Summer of Code 2007 å°æ¡ä¹ä¸ã"
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>è£ç½®</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "è®åé度ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "è¦è¼è£ç½®ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>è©®éè³æ</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "ä½¿ç¨ CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "ä½¿ç¨ CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "ä½¿ç¨ HTTP èé CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "伺æå¨ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "è·¯å¾ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "éè¨å ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "鳿¨ CD 夿ç¨å¼"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "ç¡æ³åå§å cdio å系統ã"
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "ç¡æç URI %sã"
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "æ¾ä¸å°é³è» %dã"
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "è»é %d æ¯è³æè»ã"
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "ç¡æ³éåé³è¨è¼¸åºã"
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "è®å鳿¨ CD æç¼çé¯èª¤ã"
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "鳿¨ CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "ç¡æ³éå CD è£ç½® %sã"
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "æ¾ä¸å°å¯ä»¥ææ¾é³è¨çå
ç¢æ©ã"
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "éåçå
ç¢æ©ç¡æ³å®æåå§åã"
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "ç¡æ³åå¾ç¬¬ä¸åææå¾çé³è»ç·¨èã"
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "ç¡æ³è®åé³è» %d çèµ·å§ï¼çµæé輯ç£åç·¨èã"
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "ç¡æ³å»ºç« cddb çé£ç·ã"
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "ç¡æ³æ¥è©¢ CDDB 伺æå¨"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "ç¡æ³æ¥è©¢ CDDB 伺æå¨ï¼%s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "ç¡æ³è®å cddb è³è¨ï¼%s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "å
ç¢æ©æ¯ç©ºçã"
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "æªæ¯æ´çå
ç¢é¡å"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "鳿¨ CD é¸å®é
ç®"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "ææ¾ CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "å å
¥ CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "鳿¨ CD é¸å®é
ç®"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>å£ç¸®</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "ä¸å¤®é³éï¼"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "åæ
ç¯åï¼"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Audacious çåæ
ç¯åå£ç¸®å¤æç¨å¼\n"
-"è使¬ 2010-2012 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "åæ
ç¯åå£ç¸®"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1017,205 +969,224 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ä½é³"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "é«é³"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "é è¨ææ²é·åº¦ï¼"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>é忍£</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "åç¨è²é³é忍£"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "é忍£ç"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "å¿½ç¥ SPC æ¨ç±¤è£¡è¨éçé·åº¦"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "å¢å åé³"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "鿲䏻æ©é³æ¨è§£ç¢¼å¨"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-"å çºææ²éçè²éæ¸ä¸åï¼ç¡æ³ä½¿ç¨ Crossfadeãæ¨å¯ä»¥ä½¿ç¨è²éæ··åå°ææ²è½æè³ç¸"
-"åçè²éæ¸éã"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-"æ·¡å
¥æ·¡åºå¤±æï¼å çºææ²éç忍£çä¸åãæ¨å¯ä»¥ä½¿ç¨å樣çè½æåè½ä¾åå¾ç¸åçå"
-"樣çã"
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Audacious çæ·¡å
¥æ·¡åºå¤æç¨å¼\n"
-"è使¬ 2010-2012 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>æ·¡å
¥æ·¡åº</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "éçï¼"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "æ·¡å
¥æ·¡åº"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"å çºææ²éçè²éæ¸ä¸åï¼ç¡æ³ä½¿ç¨ Crossfadeãæ¨å¯ä»¥ä½¿ç¨è²éæ··åå°ææ²è½æè³ç¸"
+"åçè²éæ¸éã"
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"æ·¡å
¥æ·¡åºå¤±æï¼å çºææ²éç忍£çä¸åãæ¨å¯ä»¥ä½¿ç¨å樣çè½æåè½ä¾åå¾ç¸åçå"
+"樣çã"
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Crystalizer</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "ææå¼·åº¦ï¼"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Crystalizer"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Cue Sheet 夿ç¨å¼"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "åªé¤"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "åæ¶"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>åé³</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "å»¶é²ï¼"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "毫ç§"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "åé¥ï¼"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "é³éï¼"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"åé³å¤æç¨å¼\n"
-"ç± Johan Levin, 1999\n"
-"\n"
-"ç°ç¹å鳿¯ç± Carl van Schaik, 1999 編寫"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "åé³"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg 夿ç¨å¼"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1231,55 +1202,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg 夿ç¨å¼"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "æªæ¡è¼¸åºå¤æç¨å¼"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "è¼¸åºæªæ¡æ ¼å¼ï¼"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "è¨å®"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "å²åå°åå§è³æå¤¾"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "å²åå°èªè¨è³æå¤¾"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "è¼¸åºæªæ¡è³æå¤¾ï¼"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "鏿ä¸åè³æå¤¾"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "æªå便ºï¼"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "åå§æªæ¡æ¨ç±¤"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "åå§æªå"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "ä¸è¦å»æå¯æªå"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "卿ªååé¢å ä¸é³è»è碼"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1311,165 +1282,169 @@ msgstr ""
"Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA "
"02110-1301, USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "æªæ¡è¼¸åºå¤æç¨å¼"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "èªå"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "è¯åç«é«è²"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "ç«é«è²"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "å®è²é"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 è¨å®"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "æ¼ç®æ³å質ï¼"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "輸åºå樣çï¼"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "ä½å
çï¼å£ç¸®æ¯çï¼"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ä½å
ç (kbps)ï¼"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "å£ç¸®æ¯çï¼"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "é³è¨æ¨¡å¼ï¼"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "éé
ï¼"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "å¼·å¶å´æ ¼ç¸å®¹æ¼ ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "é¯èª¤ä¿è·"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "å質"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "åç¨ VBRï¼ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "é¡åï¼"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR é¸é
ï¼"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "æå°ä½å
ç (kbps)ï¼"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "æå¤§ä½å
ç (kbps)ï¼"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "å¼·å¶ä½¿ç¨æå°ä½å
ç"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR é¸é
ï¼"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "å¹³åä½å
ç (kbps)ï¼"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR å質çç´ï¼"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "ä¸è¦å¯«å
¥ Xing VBR æªé "
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBRï¼ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "鳿¡åæ¸ï¼"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "æ¨ç¤ºçºè使¬"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "æ¨ç¤ºçºååµ"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ID3 忏ï¼"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "å¼·å¶å å
¥ç¬¬äºçæ¨ç±¤"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "åªå å
¥ç¬¬ä¸çæ¨ç±¤"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "åªå å
¥ç¬¬äºçæ¨ç±¤"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "æ¨ç±¤"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis 編碼å¨è¨å®"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "å質çç´ (0 - 10)ï¼"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC 解碼å¨"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "ç¡æ"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1481,11 +1456,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC 解碼å¨"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1493,11 +1464,19 @@ msgstr ""
"Audacious ç GIO 夿ç¨å¼\n"
"è使¬ 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO 夿ç¨å¼"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1509,533 +1488,606 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL é »èåæå"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-msgstr ""
-"Gnome å¿«æ·éµå¤æç¨å¼\n"
-"è®æ¨æ§å¶ææ¾å¨è Gnome çå¿«æ·éµã\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
"\n"
-"è使¬Â©2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"License: GPLv2+"
+msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Gnome å¿«æ·éµ"
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "é
ç®ç·¨è"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "æ¨é¡"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "æ¼åºè
"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "å¹´å"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "å°è¼¯"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "é³è»"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "é¡å"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "ä½åä½ç½®"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "é·åº¦"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "æªæ¡è·¯å¾"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "æªæ¡å稱"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "èªè¨æ¨é¡"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ä½å
ç"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "æå°å·¥å
·"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "åµå
¥å·¦æ¹"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "åµå
¥å³æ¹"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "åµå
¥é 端"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "åµå
¥åºç«¯"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "è§£é¤åµå
¥"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "éé"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "æå°å·¥å
·"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "éåæªæ¡(_O)â¦"
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "éåç¶²å(_U)â¦"
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "å å
¥æªæ¡(_A)⦠"
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "å å
¥ç¶²å(_R)â¦"
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "éæ¼(_B)â¦"
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "é¢é(_Q)"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "ææ¾(_P)"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "æ«å(_E)"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "忢(_S)"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "ä¸ä¸é¦(_V)"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "ä¸ä¸é¦(_N)"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "éè¤"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "鍿©"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "ä¸è¦åæææ¾å表"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "ææ¾å®ç®åææ²å¾åæ¢(_F)"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "ææ²è³è¨(_I)â¦"
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "è·³è³æé(_T)â¦"
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "è·³è³ææ²(_J)â¦"
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "è¨å®éè¤é» _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "è¨å®éè¤é» _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "æ¸
é¤éè¤é»(_C)"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "æ¨é¡(_T)"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "æªæ¡å稱(_F)"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "æªæ¡è·¯å¾(_P)"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "é³è»ç·¨è(_N)"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "æ¼åºè
(_A)"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "å°è¼¯(_B)"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "éåºæ¥æ(_D)"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "é·åº¦(_L)"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "æªæ¡è·¯å¾(_F)"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "èªè¨æ¨é¡(_C)"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "ååé åº(_E)"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "鍿©é åº(_R)"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "ææ¾æ¤å表(_P)"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "éæ°æ´ç(_R)"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "æåº(_S)"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "æåºæé¸(_L)"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "ç§»é¤éè¤çé
ç®(_D)"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "ç§»é¤ä¸åå¨çæªæ¡(_U)"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "æ°å¢(_N)"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "éæ°å½å(_A)â¦"
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "å¯å
¥(_I)â¦"
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "å¯åº(_E)â¦"
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "ææ¾å表管ç(_M)â¦"
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "ä½å管ç(_Q)â¦"
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "æé«é³é(_U)"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "éä½é³é(_D)"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "çåå¨(_E)"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "顯示é¸å®å(_M)"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "顯示è³è¨å(_N)"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "顯示è³è¨åçè¦è¦ºç¹æ(_U)"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "顯示çæ
å(_S)"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "顯示å©é¤æé(_R)"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "æªæ¡(_F)"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "ææ¾(_P)"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "ææ¾å表(_L)"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "æå(_S)"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "輸åº(_O)"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "檢è¦(_V)"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "æå
¥ï¼ç§»åºä½å(_Q)"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "åªä¸(_T)"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "æ·è²(_C)"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "è²¼ä¸(_P)"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "鏿å
¨é¨(_A)"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "éæ°å½å(_R)â¦"
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>å
¶ä»é¸é
</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK ä»é¢"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ç·©è¡ä¸â¦"
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "å®è²é"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "ç«é«è²"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d è²é"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "å®ä¸æ¨¡å¼ã"
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "ææ¾å表模å¼ã"
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "ææ¾å®æå¾åæ¢ã"
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "ä¸ä¸åé³è»"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "ææ¾"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "æ«åï¼å復"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "忢"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "ä¸ä¸åé³è»"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "å¿«è½äºç§"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "åè½äºç§"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "éé³"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "æé«é³é"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "éä½é³é"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "è·³è³æªæ¡"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "åæé¡¯ç¤ºææ¾å¨è¦çª"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "顯示 OSD"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "åæéè¤ææ¾"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "åæé¨æ©ææ¾"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "ææ¾å®ç®åææ²å¾åæ¢"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "å°ææ¾å¨è¦çªæ¾å°æä¸å±¤"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(ç¡)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2046,15 +2098,11 @@ msgstr ""
"\n"
"æ¨æ³è¦ç¹¼çºåï¼"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "ç¶å®æ»é¼ æé"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "å
¨åç±éµå¤æè¨å®"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2062,23 +2110,27 @@ msgstr ""
"è«å¨è¼¸å
¥æ¬ä½ä¸æä¸æ³è¦çæéµçµåã\n"
"æ¨ä¹å¯ä»¥ç¶å®æ»é¼ æéã"
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "ç±éµï¼"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>åä½ï¼</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>æéµç¶å®ï¼</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "å
¨åç±éµ"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2104,60 +2156,51 @@ msgstr ""
" Jonathan A.Davis <davis at jdhouse.org>ï¼\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "å
¨åç±éµ"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK 輸åº"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"åºæ¼ xmms-jackï¼ç± Chris Morgan 編寫ï¼\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"ç± Giacomo Lozito ç§»æ¤å° Audacious"
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK 輸åº"
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s è¨å®"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA 主æ§ç«¯è¨å®"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "模çµè·¯å¾ï¼"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2167,25 +2210,25 @@ msgstr ""
"系統é¤äº LADSPA_PATH ä¹å¤ä¹ææå°éäºè·¯å¾ã\n"
"å å
¥æ°è·¯å¾ä¹å¾è«æ Enter æææ°ç夿ã</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "å¯ç¨ç夿ï¼"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "åç¨"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "åç¨å¤æï¼"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "è¨å®"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2193,47 +2236,15 @@ msgstr ""
"Audacious ç LADSPA 主æ§ç«¯\n"
"è使¬ 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA 主æ§ç«¯"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%sï¼ç¡æ³åå§å LIRC æ¯æ´\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%sï¼ç¡æ³è®å LIRC çµæ
æª\n"
-"%sï¼è«é±è® LIRC çç¸éæä»¶\n"
-"%sï¼å¦ä½å»ºç«ä¸åé©åççµæ
æª\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%sï¼åè©¦éæ°é£ç·ä¸â¦\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%sï¼ä¸æçå½ä»¤ã%sã\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%sï¼å·²å¾ LIRC é¢ç·\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%sï¼å°æ¯ %d ç§åè©¦éæ°é£ç·ä¸æ¬¡â¦\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Linux ç´
å¤ç·éæ§å¨å¤æç¨å¼"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2261,73 +2272,81 @@ msgstr ""
"\n"
"è¦ç²å¾æ´å¤ LIRC çç¸éè³è¨ï¼è«åç http://lirc.orgã"
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>é£ç·</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "éæ°é£ç·è³ LIRC 伺æå¨"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "éæ°é£ç·åççå¾
æéï¼"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Linux ç´
å¤ç·éæ§å¨å¤æç¨å¼"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki æè©å¤æç¨å¼"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "ç¡å¯ç¨çæè©"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "é¯èª¤"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "ç¡æ³åå¾ %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "é¯èª¤"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "ç¡æ³åæ %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "å°æ¾æè©ä¸â¦"
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "æ¾ä¸å°ææ²è©®éè³æ"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "é£ç·è³ lyrics.wikia.com ä¸â¦"
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki æè©å¤æç¨å¼"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U ææ¾å表"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "ç¯æç¢çå¨"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "ç¯æç¢çå¨ï¼%d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "ç¯æç¢çå¨ï¼%d bpm %dï¼%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2341,11 +2360,11 @@ msgstr ""
"ç¯ä¾ï¼tact://77 ææ¾ 77 BPM\n"
"æ tact://60*3/4 以 3/4 æææ¾ 60 BPM"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "ç¯æç¢çå¨"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "è²éæ··å"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2353,152 +2372,184 @@ msgstr ""
"Audacious çé »éæ··é³å¨å¤æç¨å¼\n"
"è使¬ 2011-2012 John Lindgren è MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>è²éæ··å</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "輸åºè²éæ¸ç®ï¼"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "è²éæ··å"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS 夿ç¨å¼"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (MOD ææ¾å¨)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>è§£æåº¦</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>è²é</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "æè¿é»å樣(æå¿«)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "ç·æ§å樣(å¿«)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "æ²ç·å½æ¸(ä½³)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "å¤ç¸ä½å樣(æä½³)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>忍£ç</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "強度ï¼"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "è£åï¼"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>åé³</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>éä½é³å¼·å</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>ç°ç¹é³æ</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>åç½®æ¾å¤§</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "è¶
忍£"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "éåª"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "ææ¾ Amiga MOD æªæ¡"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>éè¤</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "éè¤æ¬¡æ¸ï¼"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "å°éè¤æ¬¡æ¸è¨å®çº -1 表示永é éè¤ææ¾ã"
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (MOD ææ¾å¨)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "ç°ç¹"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 夿ç¨å¼"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "ç°ç¹"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 伺æå¨"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTPï¼HTTPS 夿ç¨å¼"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "已忢"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious éææ¾ä¸ã"
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "æ¡é¢éç¥"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2531,55 +2582,64 @@ msgstr ""
"æ¨æè©²å·²ç¶æ¶å°é¨éæ¼éåç¨å¼ç GNU éç¨å
Œ
±ææ¬æ·è²ã å¦ææ²æï¼è«åç "
"<http://www.gnu.org/licenses/>ã"
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "é¡¯ç¤ºææ¾æ§å¶å
ä»¶"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "æ°¸é 顯示éç¥"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "æ¡é¢éç¥"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "顯示"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "æ«å"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "ä¸ä¸å"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1ãé è¨è£ç½®"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 輸åº"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "é³è¨è£ç½®ï¼"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "ä½¿ç¨æ¿ä»£è£ç½®ï¼"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "å²åä¸åå·¥ä½é段çé³éã"
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "åç¨æ ¼å¼è½æ (ä½¿ç¨ OSS è»é«)ã"
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "åç¨ç¨å 模å¼ä»¥é²æ¢èæ¬æ··é³ã"
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2587,25 +2647,41 @@ msgid ""
"I would like to thank people on #audacious, especially Tony Vroon and John "
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-"Audacious ç OSS4 輸åºå¤æç¨å¼\n"
-"è使¬ 2010-2012 MichaÅ Lipski\n"
-"\n"
-"ææ³è¦è¬è¬ #audacious ä¸ç人åï¼ç¹å¥æ¯ Tony Vroon è John Lindgrenï¼ç¶ç¶éæ"
-"åä¸å OSS 夿ç¨å¼çä½è
ã"
+"Audacious ç OSS4 輸åºå¤æç¨å¼\n"
+"è使¬ 2010-2012 MichaÅ Lipski\n"
+"\n"
+"ææ³è¦è¬è¬ #audacious ä¸ç人åï¼ç¹å¥æ¯ Tony Vroon è John Lindgrenï¼ç¶ç¶éæ"
+"åä¸å OSS 夿ç¨å¼çä½è
ã"
+
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 輸åº"
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS ææ¾å表"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1ï¼PSF2 解碼å¨"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio 輸åº"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2641,11 +2717,68 @@ msgstr ""
"Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA "
"02110-1301, USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio 輸åº"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
-#: src/resample/resample.c:165
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ä¸ä¸å"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "éè¤"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "鍿©"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "忍£çè½æ"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2653,96 +2786,104 @@ msgstr ""
"Audacious ç忍£çè½æå¨å¤æç¨å¼\n"
"è使¬ 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "è·³éï¼éè¤å樣"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "ç·æ§å
§æ"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "å¿«é sinc å
§æ"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "ä¸ç sinc å
§æ"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "æä½³ sinc å
§æ"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>è½æ</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "æ¼ç®æ³ï¼"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "忍£çï¼"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>忍£çæ å°</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "使ç¨åæ¨£çæ å°"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHzï¼"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHzï¼"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHzï¼"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHzï¼"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHzï¼"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHzï¼"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHzï¼"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "忍£çè½æ"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "確èªãä¸å³ä½¿ç¨è
%s çææ¾è³è¨"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "åå被æ"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr "é»é¸ä¸åéçµå
許 Audacious ä¸å³æ¨çææ¾è³è¨ï¼"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr "è«ä¿æéåè¦çªçéå䏦忬¡é»é¸ãæª¢æ¥æ¬éãã\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2750,32 +2891,36 @@ msgstr ""
"奿å¿ãæ¨çè³è¨å·²ç¶å²åå¨é»è
¦ä¸ã\n"
"Audacious æå¨çæ³å
許ä¸ç¡å¿«å°å°å®åä¸å³ã"
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "網路ç¼çåé¡ã"
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "åå Last.fm æç¼çåé¡ãè«ç¨åå試ã"
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "檢æ¥ä¸â¦"
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "æª¢æ¥æ¬é(_H)"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "æ¤é·ææ¬(_R)"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr "æ¨éè¦å
許 Audacious ä¸å³é³è»çææ¾è³è¨è³æ¨ç Last.fm 帳èã\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2783,7 +2928,7 @@ msgstr ""
"ç¡æ³åå Scrobbler 夿ã\n"
"æ¨çå®è£å¯è½æäºåé¡ã"
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2800,11 +2945,7 @@ msgstr ""
"æè¬ John Lindgren å¨éåå°æ¡çéé 婿ä¸èä¹åã\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2812,7 +2953,11 @@ msgstr ""
"Audacious ç¾å¨ä½¿ç¨æ¹è¯çç Last.fm ææ¾è³è¨ä¸å³åè½ã\n"
"è«åé±å好è¨å®ä¸çææ¾è³è¨å¤æã"
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL 輸åº"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2820,753 +2965,822 @@ msgstr ""
"Audacious ç SDL 輸åºå¤æç¨å¼\n"
"è使¬ 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL 輸åº"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "åªé«æ«"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "ä¸æçæ¼åºè
"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "䏿çå°è¼¯"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" æ¼ã%sãç±ã%sãæ¼å±"
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d å¼µå°è¼¯"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-"%s\n"
-" %sï¼%d 馿æ²"
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
-"%s\n"
-" %d 馿æ²ç±ã%sãæ¼å±"
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "å»ºç«ææ¾å表(_C)"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "å å
¥è³ææ¾å表(_A)"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "æå°åªé«æ«"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
"è¦å°æ¨çåªé«æ«å¯å
¥è³ Audaciousï¼è«é¸æç®æ¨è³æå¤¾ä¸¦ä¸æä¸ãéæ°æ´çãå示ã"
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "è«ç¨åâ¦"
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "é¸æè³æå¤¾"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "ææ¾"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "ææ¾å表"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "檢è¦"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "éè¤"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "鍿©"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "ä¸è¦åæææ¾å表"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ä¸ä¸å"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "æ°å¢ææ¾å表"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "é¡¯ç¤ºææ¾å表編輯å¨"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "顯示çåå¨"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "æ°¸é 卿ä¸å±¤"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "æ¨é¡"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "æªæ¡å稱"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "å
¨é¨ç§»é¤"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "æ¸
é¤ä½å"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "ç§»é¤ç¡æ³ä½¿ç¨çæªæ¡"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "ç§»é¤éè¤çé
ç®"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "ç§»é¤æªé¸æçé
ç®"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "ç§»é¤é¸æçé
ç®"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "æå°ä¸¦é¸æ"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "åå鏿"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "忶鏿"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "鏿å
¨é¨"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "å°è¼¯"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "é³è»ç·¨è"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "æ¼åºè
"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "å°è¼¯"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "é³è»ç·¨è"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "åè¡¨é¨æ©æåº"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "å表ååæåº"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "æåºé¸æçé
ç®"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "æåºå表"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "åªä¸"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "æ·è²"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "è²¼ä¸"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winamp å³çµ±ä»é¢"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "å²å"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "è¼å
¥"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "樣å¼"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "è¼å
¥æ¨£å¼"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "è®åèªåè¼å
¥æ¨£å¼"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "å²å樣å¼"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "å²åèªåè¼å
¥æ¨£å¼"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "åªé¤æ¨£å¼"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "åªé¤èªåè¼å
¥æ¨£å¼"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "ææ¾å¨(_P)ï¼"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "é¸æææ¾å¨ä¸»è¦çªååï¼"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "ææ¾å表(_P)ï¼"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "é¸æææ¾å表ååï¼"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "使ç¨é»é£åå (åªæ¯æ´ ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "é忲忿²æ¨é¡"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "åæå"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "示波å¨"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "éé"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "æ¨æº"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "ç«ç°"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "ç·æ¢"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "æ£ç"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "ææ
¢"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "æ
¢"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "ä¸ç"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "å¿«"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "æå¿«"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "å°é"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "å¹³æ»"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "ä¸è¬"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "è¦è¦ºç¹æ"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "åç½®æ¾å¤§"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious çåå¨"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "ç§»åè³ %d:%-2.2dï¼%d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "é³éï¼%dï¼
"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "平衡ï¼%dï¼
åå·¦"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "平衡ï¼ä¸é"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "平衡ï¼%dï¼
åå³"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "é¸å®é¸é
"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "ééç½®é "
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "åç¨ç½®é "
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "æªæ¡è³è¨è¦çª"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "å·²è¨å®éè¤é» Aã"
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "å·²è¨å®éè¤é» Bã"
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "å·²æ¸
é¤éè¤é»ã"
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "å®ä¸æ¨¡å¼ã"
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "ææ¾å表模å¼ã"
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "ææ¾å®æå¾åæ¢ã"
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "å¨ä½¿ç¨ä¸çææ¾å表裡æå°ææ¾é
ç®"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3576,57 +3790,61 @@ msgstr ""
"å¡«å
¥ä¸åæå¤åæ¬ä½ä»¥é¸æææ¾å表ä¸çé
ç®ãæ¬ä½ä½¿ç¨æ£è¦è¡¨ç¤ºæ³ï¼å¤§å°å¯«è¦çºä¸å"
"åå
ãè¥æ¨ä¸ç¥éå¦ä½ä½¿ç¨æ£è¦è¡¨ç¤ºæ³ï¼è«è¼¸å
¥æ¨æ³æå°çé¨åæåã"
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "æ¨é¡ï¼"
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "å°è¼¯ï¼"
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "æ¼åºè
ï¼"
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "æªåï¼"
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "é²è¡æå°åæ¸
ç©ºä¸æ¬¡ç鏿é
ç®"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "èªååæè³ç¬¦åé
ç®çä½å"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "以符åçé
ç®å»ºç«æ°çææ¾å表"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audacious ææ¾å表編輯å¨"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%dï¼%d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "å£ç¸®ç Winamp 2.x 颿¿"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "æªå£ç¸®ç Winamp 2.x skin"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "ç¡æ³å»ºç«è³æå¤¾ (%s)ï¼%s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile 夿ç¨å¼"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3664,81 +3882,71 @@ msgstr ""
"Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA "
"02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile 夿ç¨å¼"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "éæ¼ Sndio 輸åºå¤æç¨å¼"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-"Sndio 輸åºå¤æ\n"
-"\n"
-"ä½è
ï¼Thomas Pfaff <tpfaff at tp76.info>\n"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "æªæ¯æ´çæ ¼å¼"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-"è¦æ±äºæªè¢«é³è¨è£ç½®æ¯æ´çæ ¼å¼ã\n"
-"\n"
-"è«ç¢ºèª sndiod(1) 伺æå¨å·²å·è¡å¾é試ã"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio è£ç½®"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(空ç½è¡¨ç¤ºä½¿ç¨é è¨å¼)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "確èª"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "ææ²åæ"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "ç¶ Audacious éå§ææ¾æ°çææ²æå·è¡çæä»¤ã"
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>å³çµ¦ shell ç忏æè©²ç¨éå¼èå
èµ·ä¾ï¼å¦åææå®å
¨é¢¨éªã</"
+"span>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "å½ä»¤ï¼"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "æ¯ç¶ä¸é¦ææ²ææ¾å®æå·è¡å½ä»¤"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "æ¯ç¶ Audacious ææ¾éå°å表尾端æå·è¡å½ä»¤"
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
-msgstr "ç¶ä¸é¦æçæ¨é¡æ¹è®æå·è¡å½ä»¤ã(網路串æµçæ¨é¡)"
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr ""
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3752,35 +3960,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"æ¨å¯ä»¥å¨å½ä»¤ä¸ä½¿ç¨ä¸åçæ ¼å¼å串ã\n"
-"å®åæå¨å·è¡å½ä»¤å被實éå¼å代ã\n"
-"(䏿¯å
¨é¨é½è½å¨ææ¾åè¡¨çµæå½ä»¤ä¸ä½¿ç¨)\n"
-"\n"
-"%Fï¼é »ç (赫è²)\n"
-"%cï¼è²éæ¸ç®\n"
-"%fï¼æªå (宿´è·¯å¾)\n"
-"%lï¼é·åº¦ (毫ç§)\n"
-"%n æ %sï¼ææ²å稱\n"
-"%rï¼ä½å
ç (bps)\n"
-"%tï¼ææ¾å表ä½ç½® (%02d)\n"
-"%pï¼ææ¾ä¸ (1 æ 0)\n"
-"%aï¼æ¼åºè
\n"
-"%bï¼å°è¼¯\n"
-"%Tï¼é³è»æ¨é¡"
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>å³çµ¦ shell ç忏æè©²ç¨éå¼èå
èµ·ä¾ï¼å¦åææå®å
¨é¢¨éªã</"
-"span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "å½ä»¤"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX é忍£"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3794,51 +3983,51 @@ msgstr ""
"åºæ¼å樣çè½æå¨å¤æç¨å¼ï¼\n"
"è使¬ 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "å¿«é"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "ä½"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "é«"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "é常é«"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "å質ï¼"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX é忍£"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "é度èé³é«"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>é度èé³é«</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "é度ï¼"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "é³é«ï¼"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "é度èé³é«"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "çæ
å示"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3855,39 +4044,39 @@ msgstr ""
"\n"
"éå夿æä¾ä¸åçæ
å示並æ¾å¨ç³»çµ±éç¥åã"
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>æ»é¼ 滾輪åä½</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "調æ´é³é"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "åæææ¾ææ²"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>å
¶ä»è¨å®</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "ééå½åºå¼è¦çª"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "縮å°ç³»çµ±å"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "ä»¥èæ»é¼ æ»¾è¼ªçåæ¹ååæææ²"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "çæ
å示"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "é¡å¤ç«é«è²ææ"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3897,24 +4086,24 @@ msgstr ""
"\n"
"ç± Johan Levinï¼1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>é¡å¤ç«é«è²ææ</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "é¡å¤ç«é«è²ææ"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "é³èª¿ç¢çå¨"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "é³èª¿ç¢çå¨ï¼"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3928,15 +4117,11 @@ msgstr ""
"ç¨æ³ï¼å å
¥ç¶²åï¼tone://frequency1;frequency2;frequency3;â¦\n"
"ç¯ä¾ï¼tone://2000;2005 æææ¾ 2000 HZ å 2005HZ çæ£å¼¦æ³¢"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "é³èª¿ç¢çå¨"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "人è²ç§»é¤"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3974,11 +4159,35 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis 解碼å¨"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX 解碼å¨"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -3988,19 +4197,19 @@ msgstr ""
"åºæ¼ invtx(_V).dll ç·¨å¯«èª Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious 夿ç¨å¼ç·¨å¯«èª Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX 解碼å¨"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack 解碼å¨"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "失ç (æ··å)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "失ç"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4010,14 +4219,18 @@ msgstr ""
"\n"
"å
¶ä¸ä¸äºå¤æç¨å¼ç¢¼æ¯ç± Miles Egan 編寫ã"
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack 解碼å¨"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF 解碼å¨"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "XML å¯åäº«å¼ææ¾å表 (XSPF)"
diff --git a/po/cs.po b/po/cs.po
index 4b635dbd4a9b..a3748995fb45 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -3,21 +3,24 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# jui <appukonrad at gmail.com>, 2012-2013
+# JiÅÃ VÃrava <appukonrad at gmail.com>, 2012-2013
# Based on audacious-1.2.2.cs.po by Jan Nárovec <finn at sendmail.cz>, 2004
# fri, 2012-2013
+# nd76er <nd76er at gmail.com>, 2014
+# nd76er <nd76er at gmail.com>, 2014-2015
+# fri, 2014
# fri, 2012
# Petr Pisar <petr.pisar at atlas.cz>, 2007-2012
-# petr.simacek <petr.simacek at gmail.com>, 2012
-# petr.simacek <petr.simacek at gmail.com>, 2012
-# petr.simacek <petr.simacek at gmail.com>, 2013
+# Petr Å imáÄek <petr.simacek at gmail.com>, 2012
+# Petr Å imáÄek <petr.simacek at gmail.com>, 2012
+# Petr Å imáÄek <petr.simacek at gmail.com>, 2013-2014
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-04-03 11:52+0200\n"
+"PO-Revision-Date: 2015-02-27 10:53+0000\n"
+"Last-Translator: nd76er <nd76er at gmail.com>\n"
"Language-Team: Czech (http://www.transifex.com/projects/p/audacious/language/"
"cs/)\n"
"Language: cs\n"
@@ -26,40 +29,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "prostorový zvuk"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
-msgstr ""
-
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
-msgid "sequenced"
-msgstr "Sekvencován"
+msgstr "AAC (Raw) dekodér"
-#: src/adplug/plugin.c:14
+#: src/adplug/adplug-xmms.cc:42
msgid "AdPlug (AdLib Player)"
msgstr "AdPlug (AdLib pÅehrávaÄ)"
-#: src/alarm/alarm.c:778
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
+msgid "sequenced"
+msgstr "seÅazen"
+
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "BudÃk"
+
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
-msgstr ""
+msgstr "Nastavit budÃk"
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -69,11 +60,7 @@ msgstr ""
"\n"
"PůvodnÄ napsal Adam Feakin a Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "BudÃk"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -95,8 +82,25 @@ msgid ""
"\n"
"\n"
msgstr ""
+"Äas\n"
+"Budit v:\n"
+"Äas pro spuÅ¡tÄnà budÃku.\n"
+"\n"
+"Ticho po:\n"
+"Zastavit budÃk po nastaveném Äase.\n"
+"(jestliže dialog probuzenà nenà zavÅený)\n"
+"\n"
+"\n"
+"Dny\n"
+" Den:\n"
+"Nastavit dny, v kterých se má budÃk spouÅ¡tÄt.\n"
+"\n"
+" Äas:\n"
+"Vybrat Äas budÃku na každý den nebo zaÅ¡krtnout tlaÄÃtko pro použità "
+"standardnÃho Äasu.\n"
+"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -118,7 +122,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -131,366 +135,381 @@ msgid ""
" Type the reminder in the box and turn on the\n"
" toggle button if you want it to be shown."
msgstr ""
+"Seznam skladeb:\n"
+"Nahraj tento seznam skladeb. Jestliže nenÃ\n"
+"žádný dán, bude použit aktuálnÃ.\n"
+"URL mp3/ogg proudu se zde může také vložit.\n"
+"\n"
+"UpomÃnka:\n"
+"Zobraz upomÃnku, když se budÃk vypne.\n"
+"NapiÅ¡ upomÃnku do rámeÄku a zapni pÅepÃnacà tlaÄÃtko, \n"
+"jestli chceš aby se zobrazovala."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Toto je váš budÃcà signál."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "VaÅ¡e pÅipomÃnka pro dneÅ¡ek je..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "UpomÃnánÃ"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "PondÄlÃ"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Ãterý"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "StÅeda"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Ätvrtek"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Pátek"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Sobota"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "NedÄle"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Nastavenà budÃku"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Äas"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Budit v (standardnÃ):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Ticho po:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "h"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "min"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Vyberte dny, kdy má budÃk budit"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Den"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "StandardnÃ"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Dny"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "ZesilovánÃ"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "sekund"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Hlasitost"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "ZaÄÃt na"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "SkonÄit na"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "SouÄasná"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "DodateÄný pÅÃkaz"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "zapnout"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Seznam skladeb (volitelné)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Vybrat seznam skladeb"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "NastavenÃ"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Co tyto volby znamenajÃ?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "NápovÄda"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Album"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Obal alba (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA výstup:"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ALSA výstupnà modul pro Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"Mé dÃky patÅà Williamu Pitcockovy, autoru výstupnÃho ALSA Zásuvného modulu "
+"NG, jehož kód sloužil jako reference, když použità ALSA mauálu nestaÄilo."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Implicitnà PCM zaÅÃzenÃ"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Implicitnà smÄÅ¡ovacà zaÅÃzenÃ"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "ZaÅÃzenà PCM:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "ZaÅÃzenà smÄÅ¡ovaÄe:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Prvek smÄÅ¡ovaÄe:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "ObejÃt zaseknutà pÅi vyprazdÅovanÃ"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI pÅehrávaÄ)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-"ALSA výstupnà modul pro Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
"\n"
-"Mé dÃky patÅà Williamu Pitcockovy, autoru výstupnÃho ALSA Zásuvného modulu "
-"NG, jehož kód sloužil jako reference, když použità ALSA mauálu nestaÄilo."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA výstup:"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI pÅehrávaÄ)"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
-msgstr ""
+msgstr "PotlaÄit výchozà zesÃlenÃ:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
-msgstr ""
+msgstr "PotlaÄit výchozà vÃcehlas:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
-msgstr ""
+msgstr "PotlaÄit výchozà dozvuk:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
-msgstr ""
+msgstr "On"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
-msgstr ""
+msgstr "PotlaÄit výchozà sbor:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
-msgstr ""
+msgstr "<b>Playback</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
-msgstr ""
+msgstr "Transponovat: "
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "půltóny"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
-msgstr ""
+msgstr "Posun bubnu: "
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "ÄÃsla poznámek"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "PÅeskoÄit ticho na zaÄátku"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "PÅeskoÄit ticho na konci"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
-msgstr ""
+msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
-msgstr ""
-
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr ""
+msgstr "<b>Synthesizer</b>"
+
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "Vzorkovacà frekvence:"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug â vyberte soundfontový soubor"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Zrušit"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
-msgstr ""
+msgstr "_OtevÅÃt"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "Jméno souboru"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "Název souboru"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Velikost (v bajtech):"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Jméno:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"small\"> Podrobnosti o MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Formát:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Délka (ms):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Ä. skladby"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "promÄnlivé"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (váž.):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Äas. pom.:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"small\"> KomentáÅe a text MIDI skladby </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* v MIDI souboru se nenacházà žádné komentáÅe *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* v MIDI souboru se nenacházà text skladby *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_ZavÅÃt"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (neplatné UTF8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "O AMIDI-Pluginu"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -501,152 +520,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (On-Screen Display)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ObdélnÃk"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Zaoblený obdélnÃk"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Konkávnà obdélnÃk"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Žádný"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Zahájenà pÅehrávánÃ"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Spustà OSD, když se zaÄne pÅehrávat skladba."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "ZmÄna názvu"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Spustà OSD, když se bÄhem pÅehrávanà zmÄnà název skladby, ale jméno souboru "
-"je stále stejné. To se hodà pÅi pÅehrávánà internetových proudů, v nichž se "
-"stÅÃdajà skladby."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "PozastavenÃ"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Spustà OSD, když je pÅehrávánà pozastaveno."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Obnovenà pÅehrávánÃ"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Spustà OSD, když pÅehrávánà obnoveno."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "UmÃstÄnÃ"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Relativnà odsazenà ve smÄru osy X:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Relativnà odsazenà ve smÄru osy Y"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Maximálnà šÃÅka OSD"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Nastavenà pro vÃce monitorů"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Zobrazit OSD na:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "všech monitorech"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "monitoru %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Äasovánà (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "ZobrazenÃ:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "RozsvÃcenÃ:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "PohasnutÃ:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Fonty"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Font %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "StÃn"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Styl vyobrazenÃ"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Barvy"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Barvy %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Povolit spouÅ¡tÄÄ"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Událost"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Nalezen kompozitnà správce"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -656,112 +669,112 @@ msgstr ""
"Pokud nevÃte, že byste jste již nÄjakého spustili, prosÃm, aktivujte "
"kompozitnÃho správce, jinak OSDâ¯nebude správnÄ fungovat."
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "PÅi faleÅ¡né průhlednosti nenà kompozitnà správce potÅeba"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Průhlednost"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Falešná průhlednost"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "SkuteÄná průhlednostâ¯(vyžaduje kompozitnà rozÅ¡ÃÅenà X)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Kompozitnà rozÅ¡ÃÅenà nenà nahráno"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Kompozitnà rozÅ¡ÃÅenà nenà dostupné"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>OSD Audacious</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "OSD pro Audacious â nastavenÃ"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "UmÃstÄnÃ"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animace"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Text"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Výzdoba"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "SpouÅ¡tÄÄ"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Různé"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Zkouška"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
-msgstr ""
+msgstr "Seznamy skladeb ASXv3"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 seznamy skladeb"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious seszam skladeb (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Barva</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Rozsah rozostÅenÃ"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "PÅedvolby:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "ÃroveÅ pÅeslechu:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "OÅezová frekvence:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "PÅedvolby:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Analyzátor spektra"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Audio CD Plugin"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -772,170 +785,165 @@ msgid ""
"\n"
"This was a Google Summer of Code 2007 project."
msgstr ""
+"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> a dalÅ¡Ã.\n"
+"\n"
+"HodnÄ dÃků patÅà libcdio vývojáÅům <http://www.gnu.org/software/libcdio/>\n"
+"a libcddb vývojáÅům <http://libcddb.sourceforge.net/>.\n"
+"\n"
+"Také dÄkujeme Tony Vroon za mentorovánà a smÄrovánÃ.\n"
+"\n"
+"Toto byl projekt v rámci Google Summer of Code 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>ZaÅÃzenÃ</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Rychlost ÄtenÃ:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "PÅepsat zaÅÃzenÃ:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadata</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Použità CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "PoužÃvat CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "PoužÃt HTTP mÃsto CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Server:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Cesta:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Port:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Audio CD Plugin"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "NepodaÅilo se inicializovat cdio subsystému."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "Neplatná URI %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Stopa %d nebyla nalezena."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "Stopa %d je datová stopa."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Nelze otevÅÃt zvukový výstup"
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Chyba pÅi Ätenà zvukového CD."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Zvukové CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Nelze otevÅÃt CD zaÅÃzenà %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Nebyly nalezeny funkÄnà CD mechaniky"
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "NepodaÅilo se dokonÄit inicializaci otevÅenà CD mechaniky."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "NepodaÅilo se naÄÃst prvnÃ/poslednà ÄÃslo skladby."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "nelze pÅeÄÃst zaÄátek/konec LSN pro skladbu %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "NepodaÅilo se vytvoÅit pÅipojenà k CDDB."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "NepodaÅil se dotaz na server CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "NepodaÅil se dotaz na server CDDB: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "NepodaÅilo se pÅeÄÃst cddb info: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Mechanika je prázdná"
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Nepodporovaný druh disku."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Položky Audio CD menu"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "PÅehrát CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "PÅidat CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Položky Audio CD menu"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Komprese</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Hlasitost stÅedu:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Rozsah dynamiky:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Dynamický rozsah kompresoru"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -945,206 +953,227 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Hloubky:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Výšky:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
-msgstr ""
+msgstr "OzvÄna:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Implicitnà délka skladby:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>PÅevzorkovánÃ</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Povolit pÅevzorkovánà zvuku"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "PÅevzorkovat na:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
-msgstr ""
+msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ignorovat délku z SPC popisků"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Prodloužit dozvuk"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Dekodér hudby pro hernà konzole"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"ProlÃnánà se nezdaÅilo, protože pÃsnÄ mÄly různý poÄet kanálů. Můžete "
-"použÃt MÃchánà kanálů a pÅevést pÃsnÄ na stejný poÄet kanálů."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "CoreAudio výstup"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"ProlÃnánà se nezdaÅilo, protože pÃsniÄky mÄly různé vzorkovacà frekvence. "
-"Můžete použÃt PÅevádÄnà vzorkovacà frekvence pro pÅevod skladeb na stejnou "
-"vzorkovacà frekvenci."
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "Použij exkluzivnà mód"
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"ProlÃnánà zásuvný modul pro Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Crossfade výstupnà modul for Audacious\n"
+"Copyright 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>ProlÃnánÃ</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "PÅi automatické zmÄnÄ skladby"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "PÅesah:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Tip<b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "ProlÃnánÃ"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"ProlÃnánà se nezdaÅilo, protože pÃsnÄ mÄly různý poÄet kanálů. Můžete "
+"použÃt MÃchánà kanálů a pÅevést pÃsnÄ na stejný poÄet kanálů."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"ProlÃnánà se nezdaÅilo, protože pÃsniÄky mÄly různé vzorkovacà frekvence. "
+"Můžete použÃt PÅevádÄnà vzorkovacà frekvence pro pÅevod skladeb na stejnou "
+"vzorkovacà frekvenci."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Crystalizer</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intenzita:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Krystalizér"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Smazat soubory"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
-msgstr ""
+msgstr "Chyba pÅi mazánà %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
-msgstr ""
+msgstr "Chyba pÅi mazánà %s: nenà to lokálnà soubor."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
-msgstr ""
+msgstr "Chcete pÅesunout vybrané soubory do koÅ¡e?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
-msgstr ""
+msgstr "PÅesunout do koÅ¡e"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
-msgstr ""
+msgstr "Opravdu chcete trvale odstranit vybrané soubory?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Smazat"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Zrušit"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
-msgstr ""
+msgstr "Smazat vybrané soubory"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
-msgstr ""
+msgstr "<b>Metoda mazánÃ<b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
+msgstr "PresuÅ do koÅ¡e mÃsto okamžitého smazánÃ"
+
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>OzvÄna</ b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "ZpoždÄnÃ:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "ZpÄtná vazba:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Hlasitost:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"OzvÄna zásuvný modul \n"
-"Od Johna Levina, 1999\n"
-"\n"
-"Prostorová ozvÄna od Carla van Schaika, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "OzvÄna"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg Plugin"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1160,55 +1189,55 @@ msgstr ""
"Williama Pitcocka <nenolod at nenolod.net>\n"
"Matti Hämäläinena <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg Plugin"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "PÅÃdavný modul FileWriter"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Formát výstupnÃho souboru:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Nastavit"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Ukládat do původnÃho adresáÅe"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Ukládat do vlastnÃho adresáÅe"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Složka s výstupnÃmi soubory:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Vybrat složku"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "ZÃskat jméno souboru z:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Generuj jméno souboru z:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "původnÃch znaÄek v souboru"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "jména původnÃho souboru"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Originálnà jméno souboru"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Nezkracovat pÅÃponu jména souboru"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "VÄetnÄ originálnà pÅÃpony jména souboru"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "PÅedÅadit jménu souboru ÄÃslo stopy"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr "PÅedÅadit ÄÃslo stopy k jménu souboru"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1240,165 +1269,169 @@ msgstr ""
"Foundation, Inc, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "PÅÃdavný modul FileWriter"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Auto"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Joint-stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Nastavenà MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_OK"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Kvalita algoritmu:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Výstupnà vzorkovacà kmitoÄet"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr "Výstupnà vzorkovacà frekvence:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Datový tok / Kompresnà pomÄr:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "Bitrate / Kompresnà pomÄr:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Datový tok (kb/s):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Kompresnà pomÄr:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Zvukový režim:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "Různé:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Vynutit pÅÃsnou shodu s ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr "Vynutit pÅÃsnou shodu s ISO"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Ochrana pÅed chybami"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Kvalita"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Povolit VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Druh:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Nastavenà VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Nejmenšà datový tok (kb/s):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "NejvÄtšà datový tok (kb/s):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "PÅÃsnÄ vynucovat nejmenšà datový tok"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Nastavenà ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "PrůmÄrný datový tok (kb/s):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "ÃroveÅ kvality VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Nezapisovat VBRâ¯hlaviÄku Xing"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Vynechat Xing VBR hlaviÄku"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr "Parametry rámců:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "OznaÄit jako podléhajÃcà autorskému právu"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "OznaÄit jako původnÃ"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "Parametry ID3:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr "ID3 Parametry:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Vynutit pÅidánà popisků verze 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "PÅidávat jen popisky verze 1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "PÅidávat jen popisky verze 2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Popisky"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Nastavenà vorbis kodéru"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "ÃroveÅ kvality (0â10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC Dekodér"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "Bezztrátová kvalita"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1410,11 +1443,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC Dekodér"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1422,11 +1451,19 @@ msgstr ""
"GIO zásuvný modul pro Audacious\n"
"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO Plugin"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "Neplatný způsob otvÃránÃ"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1437,451 +1474,522 @@ msgid ""
"\n"
"License: GPLv2+"
msgstr ""
+"OpenGL Analyzátor spektra pro Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren a Carlo Bramini\n"
+"\n"
+"Založeno na XMMS modulu:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson a "
+"4Front Technologies\n"
+"\n"
+"Licence: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL analyzátor spektra"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "OpenGL analyzátor spektra (Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "GNOME Klávesové zkratky"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-"Zásuvný modul pro klávesové zkratky v Gnome\n"
+"GNOME Zásuvný modul pro klávesové zkratky\n"
"UmožÅuje ovládat program pomocà klávesových Gnome\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Klávesové zkratky Gnome"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "ÄÃslo položky"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Název"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "UmÄlec"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Rok"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Album"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "UmÄlec alba"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Stopa"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Žánr"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "UmÃstÄnà ve frontÄ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Délka"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Cesta k souboru"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Název souboru"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Vlastnà název"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Datový tok"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
-msgstr ""
+msgstr "Použitelné sloupce"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
-msgstr ""
+msgstr "Zobrazené sloupce"
+
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Vyhledávacà nástroj"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "UmÃstit vlevo"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "UmÃstit vpravo"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "UmÃstit nahoru"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "UmÃstit dolů"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Neumisťovat"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Zakázat"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Vyhledávacà nástroj"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_OtevÅÃt souboryâ¦"
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "OtevÅÃt _URLâ¦"
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "PÅid_at souboryâ¦"
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "PÅidat U_RLâ¦"
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
-msgstr ""
+msgstr "Prohledej knihovnu"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "_O programuâ¦Â "
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
-msgstr ""
+msgstr "_Nastavenà ..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Konec"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Hrát"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "P_ozastavit"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "Za_stavit"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "PÅed_chozÃ"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_DalÅ¡Ã"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Opakovat"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "Ná_hodné pÅehrávánÃ"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Žádné p_okraÄovánà dle seznamu skladeb"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Zastavit _po této skladbÄ"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Informace o skladbÄâ¦"
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "PÅejÃ_t na Äasâ¦"
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "PÅe_jÃt na skladbuâ¦"
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "Nastavit bod opakovánà _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "Nastavit bod opakovánà _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_Vymazat body opakovánÃ"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Podle ná_zvu"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "Podle _pÅÃpony"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Podle cesty k _souboru"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Podle ÄÃsla _stopy"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Podle _umÄlce"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Podle Al_ba"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Podle data vy_dánÃ"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "Podle _délky"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Podle _cesty k souboru"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "_Vlastnà název"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "_Obrátit poÅadÃ"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "Ná_hodné poÅadÃ"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_PÅehrát tento seznam skladeb"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Obnovit"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_SeÅadit"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "SeÅadit vy_brané"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "Odstranit _duplikáty"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Odstranit nedost_upné soubory"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Nový"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "PÅej_menovat"
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
-msgstr ""
+msgstr "OdstraÅ"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importovatâ¦"
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Exportovatâ¦"
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "Organizace seznamů skladeb"
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Správce _frontyâ¦"
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Ze_sÃlit"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "Z_tišit"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Ekvalizér"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
-msgstr ""
+msgstr "E_fekty ..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Zobrazit h_lavnà nabÃdku"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Zobrazit oblast i_nformacÃ"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Zobrazit znázornÄnà oblasti informacÃ"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Zobrazit _stavový panel"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Ukázat _zbývajÃcà Äas"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
-msgstr ""
+msgstr "_Vizualizace"
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Soubor"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_PÅehrát"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "Seznam sk_ladeb"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Služby"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Výstup"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_ZobrazenÃ"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
-msgstr "Ode_brat/pÅidat z/do fronty"
+msgstr "PÅi_dat/odebrat do/z fronty"
+
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "V_yjmout"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_KopÃrovat"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "V_ložit"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Vybr_at vše"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_PÅejmenovat ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
-msgstr ""
+msgstr "<b>Panely seznamu skladeb</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
-msgstr ""
+msgstr "Vždy zobrazovat panely"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
-msgstr ""
+msgstr "Zobrazovat poÄet skladeb"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
-msgstr ""
+msgstr "Zobrazovat zavÃracà tlaÄÃtko"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
-msgstr ""
+msgstr "<b>Sloupce seznamu skladeb</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
-msgstr ""
+msgstr "Zobrazovat hlaviÄky sloupců"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Různé</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
-msgstr ""
+msgstr "Klávesy šipek posouvajà o:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
-msgstr ""
+msgstr "Posun pÅi zmÄnÄ skladby"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "Rozhranà GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s â Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "PlnÄnà vyrovnávácà pamÄtiâ¦"
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
@@ -1889,84 +1997,98 @@ msgstr[0] "%d kanál"
msgstr[1] "%d kanály"
msgstr[2] "%d kanálů"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%dâ¯kb/s"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Režim jedné skladby."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Režim seznamu skladeb."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Zastavuje po skladbÄ."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "PÅedchozà skladba"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Hrát"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pozastavit/PokraÄovat"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Zastavit"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Dalšà stopa"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "VpÅed o 5 sekund"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "ZpÄt o 5 sekund"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Vypnout zvuk"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Zvýšit hlasitost"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "SnÞit hlasitost"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "PÅejÃt na soubor"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "PÅepnout okno pÅehrávaÄe"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Zobrazit OSD (nápis na obrazovce)"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "PÅepnout opakovánÃ"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "PÅepnout zamÃchánÃ"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "PÅepnout zastavenà po souÄasné skladbÄ"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Vyvolat okno pÅehrávaÄe"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(žádné)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1977,15 +2099,11 @@ msgstr ""
"\n"
"Chcete pokraÄovat?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "PÅiÅazuji tlaÄÃtka myÅ¡i"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Hlavnà nastavenà modulu pro horké klávesy"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -1993,23 +2111,27 @@ msgstr ""
"UvnitÅ textového pole stisknÄte kombinaci kláves.\n"
"Navázat lze také tlaÄÃtka myÅ¡i."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Horké klávesy:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Akce</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Navázánà kláves:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
-msgstr ""
+msgstr "_PÅidat"
+
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Globálnà klávesové zkratky"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2024,60 +2146,56 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Globálnà klávesové zkratky"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK výstup"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "Automaticky pÅipojit k výstupnÃm portům"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
+"Pouze %d JACK výstupnÃch portů bylo nalezeno, ale %d je jich vyžadováno."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "NepodaÅilo se pÅipojit na JACK port %s."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
+"JACK podporuje pouze floating-point audio. MusÃte zmÄnit výstupnà bitovou "
+"hloubku na Plovoucà desetinnou Äárku v nastavenà JACK výstupu."
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "NepodaÅilo se spojit s JACK servrem; bÄžÃ?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Na základÄ xmms-jack, od Chrise Morgana:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Portováno pro Audacious od Giacomo Lozito"
+"JACK server vyžaduje vzorkovacà kmitoÄet %d Hz, ale Audacious pÅehrává na %d "
+"Hz. ProsÃm použijte efekt PÅevodnÃk vzorkovacÃho kmitoÄtu na opravu."
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK výstup"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "Nastavenà %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Nastavenà hostitele LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Cesta k modulům:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2088,25 +2206,25 @@ msgstr ""
"Po té, co pÅidáte novou cestu, je tÅeba stisknout Enter, aby se vyhledaly "
"nové moduly.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Dostupné moduly:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Povolit"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Povolené moduly:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "NastavenÃ"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2114,47 +2232,15 @@ msgstr ""
"LADSPA Host pro Audacious\n"
"Copyright 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA Host"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: nelze inicializovat podporu LIRC\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: nelze ÄÃst z konfiguraÄnÃho souboru LIRC\n"
-"%s: prosÃm, pÅeÄtÄte si dokumentaci k LIRC,\n"
-"%s: jak správnÄ vytvoÅit konfiguraÄnà soubor\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s:â¯pokouÅ¡Ãm se znovu pÅipojitâ¦\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: neznámý pÅÃkaz â%sâ\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: odpojeno od LIRC\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: pokus o pÅipojenà budu opakovat každých %d sekundâ¦\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC Plugin"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2183,73 +2269,81 @@ msgstr ""
"\n"
"Pro vÃce informacà o LIRC, navÅ¡tivte http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>PÅipojenÃ</ b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Znovu se pÅipojit k serveru LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "VyÄkat pÅed opÄtovným pÅipojenÃm:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC Plugin"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki Plugin"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Žádný text k dispozici"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Chyba"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Nelze naÄÃst %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Chyba"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Nelze analyzovat %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Hledám texty ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Chybà metadata skladby"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "PÅipojovánà k lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki Plugin"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "LyricWiki Plugin (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U Playlisty"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Genetátor taktů"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Generátor taktu: %d dob/min"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Generátor taktu: %dâ¯dob/min %dâ%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2263,11 +2357,11 @@ msgstr ""
"napÅ. tact://77 pro pÅehránà 77 beatů za minutu\n"
"nebo tact://60*3/4 pro pÅehránà 60 bpm v 3/4 taktu"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Genetátor taktů"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "MÃchánà kanálů"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2275,152 +2369,184 @@ msgstr ""
"Zásuvný modul kanáloveho mixeru pro Audacious\n"
"Copyright 2011-2012 John Lindgren a MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>MÃchánà kanálů</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Výstupnà kanály:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "MÃchánà kanálů"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS Plugin"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "Chyba pÅi pÅipojenà k MMS servru"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Module Player)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>RozliÅ¡enÃ</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8 bitů"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16 bitů"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Kanály</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "Nejbližšà (nejrychlejÅ¡Ã)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Lineárnà (rychlé)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "KÅivka (dobré)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "VÃcefázové (nejlepÅ¡Ã)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr "<b>Vzorkovacà kmitoÄet</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "ÃroveÅ:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "Bod zkrácenÃ:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Dozvuk</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>ZdůraznÄnà basů</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>Prostorový zvuk</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>PÅedzesÃlenÃ</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "Oblast vzorku"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Zmenšenà šumu"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "PÅehrát Amiga MOD"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Opakovat</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "PoÄet opakovánÃ:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "Pro opakovánà navždy, nastavte poÄet opakovánà na -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "Tyto nastavenà se projevà až po restartu Audacious."
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Prostorový zvuk"
-
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 Plugin"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>PokroÄilé</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Použij pÅesný výpoÄet délky (pomalé)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Prostorový zvuk"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 Server"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS Plugin"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Neznámá HTTP chyba"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Zastaveno"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious nynà nehraje."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Oznámenà na plochu"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2440,55 +2566,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Ukázat ovládánà pÅehrávánÃ"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Vždy ukázat oznámenÃ"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Oznámenà na plochu"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "VÄetnÄ jména alba v oznámenÃ"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Ukázat"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pozastavit"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "DalÅ¡Ã"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Implicitnà zaÅÃzenÃ"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 výstup"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "OSS3 výstup"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Standardnà zaÅÃzenÃ"
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Zvukové zaÅÃzenÃ:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "PoužÃt jiné zaÅÃzenÃ:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Uložit hlasitost mezi relacemi."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Zapnout pÅevody formátu prostÅednictvÃm OSS."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Zabránit virtuálnÃmu smÄÅ¡ovánà použitÃm výluÄného režimu."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2502,19 +2637,35 @@ msgstr ""
"Rád bych podÄkoval lidem z #audacious, zejména Tonymu Vroonnovy a Johnu "
"Lindgrennovy a samozÅejmÄ také autorům pÅedeÅ¡lého OSS zásuvného modulu."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 výstup"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Správce seznamu skladeb"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Položky"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Odstranit"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "PÅejmenovat"
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS seznamy skladeb"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2 Dekodér"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio Výstup"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2534,144 +2685,213 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio Výstup"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Pracuji ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Hledej"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_OtevÅÃt složku ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_PÅidat složku"
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "Inspektor logů."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "OtevÅÃt soubory"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "PÅidat soubory"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "PÅedchozÃ"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Opakovat"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Náhodné pÅehrávánÃ"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Qt rozhranÃ"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "PÅevodnÃk vzorkovacÃho kmitoÄtu"
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "PÅeskoÄit/opakovat vzorky"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Lineárnà interpolace"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Rychlá sinc interpolace"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "StÅednà sinc interpolace"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Nejlepšà sinc interpolace"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>PÅevod</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Metoda:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "HodnocenÃ:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "PoužÃt pÅiÅazenà frekvencÃ"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "PÅevodnÃk vzorkovacÃho kmitoÄtu"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "PÅÃstup odepÅen"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
-msgstr ""
+msgstr "Ponech toto okno otevÅené a klikni znovu na 'Check Permission'.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "Problém se sÃtÃ."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
"Objevil se problém pÅi kontaktovánà Last.fm. Zkuste to prosÃm za chvÃli."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "ProvÄÅuje se..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "Z_kontrolovat oprávnÄnÃ"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_Odvolánà oprávnÄnÃ"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr "MusÃte povolit Audacious scrobblovat skladby do Last.fm úÄtu.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2682,94 +2902,77 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL Výstup"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
+"SDL výstupnà zásuvný modul pro Audacious\n"
+"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL Výstup"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Knihovna"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Neznámý interpret"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Neznámé Album"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr "%sâ na %s od %s"
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d album"
-msgstr[1] "%d alba"
-msgstr[2] "%d alb"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-"%sâ\n"
-" %s, %d skladba"
-msgstr[1] "%sâ %s, %d skladby"
-msgstr[2] "%sâ %s, %d skladeb"
+msgstr[1] ""
+msgstr[2] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
-" %sâ\n"
-" %d skladba od %s"
-msgstr[1] " %sâ %d skladby od %s"
-msgstr[2] " %sâ %d skladeb od %s"
+msgstr[1] ""
+msgstr[2] ""
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_VytvoÅit seznam skladeb"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "PÅid_at do seznamu skladeb"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Prohledat knihovnu"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2777,679 +2980,771 @@ msgstr ""
"Hudebnà knihovnu se do Audacious naimportuje tak, že vyberete složku a pak "
"kliknete na ikonu âobnovitâ."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "ProsÃm, poÄkejteâ¦"
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Vybrat složku"
-#: src/skins/menus.c:56
-msgid "Open Files ..."
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "SID PÅehrávaÄ"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>Výstup</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Kanály:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Emulace</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "Emuluj MOS 8580 (standardnÄ: MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
msgstr ""
-#: src/skins/menus.c:57
-msgid "Open URL ..."
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Emuluj filtr"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>Äas pÅehrávánÃ</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "Nastavit nejdelšà Äas pÅehrávánÃ:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Použij pouze když je délka skladby neznámá"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "Nastavit nejkratšà Äas pÅehrávánÃ:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Poznámka</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "OdstranÄnà ticha"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
msgstr ""
+"Silence Removal zásuvný modul pro Audacious\n"
+"Copyright 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>OdstranÄnà ticha</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Práh:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
+msgid "Open Files ..."
+msgstr "OtevÅi soubory ..."
+
+#: src/skins/menus.cc:65
+msgid "Open URL ..."
+msgstr "OtevÅi URL ..."
+
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Prohledej knihovnu"
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "PÅehrát"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Seznam skladeb"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "ZobrazenÃ"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
-msgstr ""
+msgstr "Služby"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
-msgstr ""
+msgstr "O programu ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
-msgstr ""
+msgstr "Nastavenà ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
-msgstr ""
+msgstr "UkonÄit"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
-msgstr ""
-
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Opakovat"
+msgstr "Informace o skladbÄ ..."
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Náhodné pÅehrávánÃ"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Žádné pokraÄovánà dle seznamu skladeb"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
-msgstr ""
+msgstr "Zastavit po této skladbÄ"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "PÅedchozÃ"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
-msgstr ""
+msgstr "Nastavit A-B opakovánÃ"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
-msgstr ""
+msgstr "Smazat A-B opakovánÃ"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
-msgstr ""
+msgstr "PÅejÃt na skladbu ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
-msgstr ""
+msgstr "PÅejÃt na Äas ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Nový seznam skladeb"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
-msgstr ""
+msgstr "PÅejmenuj seznam skladeb"
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
-msgstr ""
+msgstr "OdstraÅ seznam skladeb"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
-msgstr ""
+msgstr "PÅedchozà seznam skladeb"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
-msgstr ""
+msgstr "Dalšà seznam skladeb"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
-msgstr ""
+msgstr "Importuj seznam skladeb ..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
-msgstr ""
+msgstr "Exportuj seznam skladeb ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
-msgstr ""
+msgstr "Správce seznamu skladeb ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
-msgstr ""
+msgstr "Správce fronty ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
-msgstr ""
+msgstr "Obnov seznam skladeb"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Zobrazit editor seznamu skladeb"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Ukázat ekvalizér"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
-msgstr ""
+msgstr "Ukaž zbývajÃcà Äas"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Vždy na vrchu"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
-msgstr ""
+msgstr "Na vÅ¡ech pracovnÃch plochách"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Dvojitá velikost"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
-msgstr ""
+msgstr "PÅidej URL ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
-msgstr ""
+msgstr "PÅidej soubory ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Podle názvu"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Podle jména souboru"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Odebrat všechny"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Vyprázdnit frontu"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Odstranit nedostupné soubory"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Odebrat duplikáty"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Odebrat neoznaÄené"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Odebrat oznaÄené"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Hledánà a výbÄr"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Invertovat výbÄr"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Nevybrat žádné"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Vybrat vše"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Podle alba"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Podle ÄÃsla stopy"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Podle umÄlce"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Podle alba"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Podle ÄÃsla stopy"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "ZamÃchat poÅadÃ"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "OtoÄit seznam"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "SeÅadit vybrané"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "SeÅadit seznam"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "OÅÃznout"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "KopÃrovat"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Vložit"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
-msgstr ""
+msgstr "PÅidat/odebrat do/z fronty"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
-msgstr ""
+msgstr "Nahraj pÅedvolbu ..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
-msgstr ""
+msgstr "Nahraj standardnÃ"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
-msgstr ""
+msgstr "Nahraj soubor pÅedvoleb ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
-msgstr ""
+msgstr "Nahraj EQF soubor ..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
-msgstr ""
+msgstr "Ulož pÅedvolbu ..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
-msgstr ""
+msgstr "Ulož standardnÃ"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
-msgstr ""
+msgstr "Ulož soubor pÅedvoleb ..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
-msgstr ""
+msgstr "Ulož EQF soubor ..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
-msgstr ""
+msgstr "Smaž pÅedvolbu ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
-msgstr ""
+msgstr "Importuj Winamp pÅedvolbu ..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Rozhranà Winamp Classic "
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Uložit"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "NaÄÃst"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
-msgstr ""
+msgstr "Nahraj soubor pÅedvoleb"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
-msgstr ""
+msgstr "Nahraj EQF soubor"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
-msgstr ""
+msgstr "Ulož soubor pÅedvoleb"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
-msgstr ""
+msgstr "Ulož EQF soubor"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
-msgstr ""
+msgstr "Importovat nastavenà z Winampu"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "PÅedvolby"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "NaÄÃst pÅedvolbu"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "NaÄÃst souborovou pÅedvolbu"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Uložit pÅedvolbu"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Uložit automatickou pÅedvolbu"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Smazat pÅedvolbu"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Smazat souborovou pÅedvolbu"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_PÅehrávaÄ:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "PÅehrávaÄ:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Font v hlavnÃm oknÄ pÅehrávaÄe:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Seznamu skladeb:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Seznam skladeb:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Vyberte font pro seznam skladeb:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
-msgstr ""
+msgstr "<b>PÃsma</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "PoužÃt bitmapové fonty (podporuje pouze ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
-msgstr ""
+msgstr "Posouvánà názvu skladby"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "PÅevÃjet název skladby obÄma smÄry"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analyzátor"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Vlnovka"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Žádný"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "NormálnÃ"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "OheÅ"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Äáry"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Sloupce"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "NejpomalejÅ¡Ã"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Pomalé"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "StÅednÃ"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Rychlé"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "NejrychlejÅ¡Ã"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Led"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Plynulý"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
-msgstr ""
+msgstr "<b>Typ</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
-msgstr ""
+msgstr "Typ vizualizace:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
-msgstr ""
+msgstr "<b>Analyzátor</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
-msgstr ""
+msgstr "Zobrazovat zvukové Å¡piÄky"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
-msgstr ""
+msgstr "Styl:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
-msgstr ""
+msgstr "Styl VU metru."
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Obecné"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
-msgstr "ZnázornÄnÃ"
+msgstr "Vizualizace"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "PÅedzesÃlenÃ"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31â¯Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63â¯Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125â¯Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250â¯Hz "
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500âHz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1â¯kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2â¯kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4â¯kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8â¯kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16â¯kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Ekvalizér"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "PÅejÃt na %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Hlasitost: %dâ¯%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "VyváženÃ: %dâ¯%% vlevo"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "VyváženÃ: stÅed"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "VyváženÃ: %dâ¯%% vpravo"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "NabÃdka nastavenÃ"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Vypnout âVždy na vrchuâ"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Zapnout âVždy na vrchuâ"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Informace o souboru"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "Vizualizace."
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
-msgstr ""
+msgstr "Nastavit bod opakovánà A."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
-msgstr ""
+msgstr "Nastavit bod opakovánà B."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
-msgstr ""
-
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Režim jedné skladby."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Režim seznamu skladeb."
+msgstr "A-B opakovánà smazáno."
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Zastavuje po skladbÄ."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Vyhledat skladby v souÄasném seznamu skladeb"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3461,57 +3756,61 @@ msgstr ""
"regulárnÃm výrazům nerozumÃte, jednoduÅ¡e vložte Äásti textu, které chcete "
"vyhledat."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Název: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr "Název:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr "Album:"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "UmÄlec: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr "UmÄlec:"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Jméno souboru: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Jméno souboru:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "PÅed hledánÃm vymazat pÅedchozà výbÄr"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "ShodujÃcà se položky automaticky zaÅadit/vyÅadit z fronty"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Ze shodujÃcÃch se položek vytvoÅit nový seznam skladeb"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Zobrazit editor seznamu skladeb"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d z %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Zabalený skin Winapmu 2.x"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Nezabalený skin Winampu 2.x"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "AdresáŠ(â%sâ) nebylo možné vytvoÅit: %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile modul"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3532,84 +3831,90 @@ msgid ""
"this program; if not, write to the Free Software Foundation, Inc., 51 "
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile modul"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "O výstupnÃm pluginu Sndio"
-
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
+"Založeno na xmms_sndfile pluginu:\n"
+"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Sndio výstupnà plugin\n"
+"Adaptováno pro Audacious - Tony Vroon <chainsaw at gentoo.org>\n"
+"\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"
-"napsal Thomas Pfaff <tpfaff at tp76.info>\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., 51 "
+"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Nepodporovaný formát"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Sndio Výstup"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"Formát nenà podporován tÃmto zvukovým zaÅÃzenÃm. â â Zkuste to prosÃm znovu "
-"s bÄžÃcÃm sndiod(1) serverem."
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "ZaÅÃzenà (prázdné pro standardnÃ)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio zaÅÃzenÃ"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Ulož a obnov hlasitost:"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(prázdné znamená výchozÃ)"
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Sndio chyba: Nepodporovaný zvukový formát (%d)"
+
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Sndio chyba: sio_open() selhal"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "Budiž"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Sndio chyba: sio_setpar() selhal"
-#: src/song_change/song_change.c:54
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Sndio chyba: sio_start() selhal"
+
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "ZmÄna skladby"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "PÅÃkaz, který se provede, když Audacious zaÄne novou skladbu."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Parametry pÅedávané shellu by mÄly být uzavÅeny do "
+"uvozovek. Nerespektovánà této rady pÅedstavuje bezpeÄnostnà riziko.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>PÅÃkazy</b>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "PÅÃkaz:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "SpusÅ¥ pÅÃkaz pÅi spuÅ¡tÄnà nové skladby:"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "PÅÃkaz, který se provede na konci skladby."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "SpusÅ¥ pÅÃkaz po skonÄenà skladby:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr ""
-"PÅÃkaz, který se provede, když Audacious dosáhne konce seznamu skladeb."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "SpusÅ¥ pÅÃkaz po skonÄenà pÅehrávánà seznamu skladeb:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
-msgstr ""
-"PÅÃkaz, který se provede pÅi zmÄnÄ názvu skladbu (tj. názvy v sÃÅ¥ových "
-"proudech)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr "SpusÅ¥ pÅÃkaz pÅi zmÄnÄ názvu skladby (pro sÃÅ¥ové proudy):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3624,19 +3929,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>Parametry pÅedávané shellu by mÄly být uzavÅeny do "
-"uvozovek. Nerespektovánà této rady pÅedstavuje bezpeÄnostnà riziko.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Informace o skladbÄ (Qt)"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "PÅÃkazy"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "Sox pÅevzorkovánÃ"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3644,52 +3945,57 @@ msgid ""
"Based on Sample Rate Converter Plugin:\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
+"SoX Resampler modul pro Audacious\n"
+"Copyright 2013 MichaÅ Lipski\n"
+"\n"
+"Založeno na Sample Rate Converter Plugin:\n"
+"Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Rychle"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "NÃzká"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Vysoká"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Velmi vysoká"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Kvalita:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "Sox pÅevzorkovánÃ"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Rychlost a výška:"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Rychlost a výška</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
-msgstr "Rachlost:"
+msgstr "Rychlost:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Výška:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Rychlost a výška:"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Stavová ikona"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3700,39 +4006,39 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Reakce na rolovánà myÅ¡Ã</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "ZmÄnit hlasitost"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "ZmÄnit hranou skladbu"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Ostatnà nastavenÃ</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Zakázat vyskakovacà okno"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "ZavÅÃt do systémové oblasti"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "PÅecházet v seznamu skladeb, když se roluje nahoru"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Stavová ikona"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Stereo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3742,24 +4048,24 @@ msgstr ""
"\n"
"Od Johana Levina, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra Stereo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Generátor tónu"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1fâ¯Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Generátor tónů:"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3767,16 +4073,17 @@ msgid ""
"To use it, add a URL: tone://frequency1;frequency2;frequency3;...\n"
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
+"Generátor sinusového tónu Håvard Kvålen <havardk at xmms.org>\n"
+"Upraven Daniel J. Peng <danielpeng at bigfoot.com>\n"
+"\n"
+"Návod: Použij URL: tone://frekvence1;frekvence2;frekvence3;...\n"
+"napÅ. tone://2000;2005 pÅehraje 2000 Hz tón a 2005 Hz tón"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Generátor tónu"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "OdstranÄnà hlasu"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3796,31 +4103,72 @@ msgid ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
+"Audacious Ogg Vorbis dekodér\n"
+"\n"
+"Založeno Xiph.org Foundation's Ogg Vorbis Plugin:\n"
+"http://www.xiph.org/\n"
+"\n"
+"Originálnà kód:\n"
+"Tony Arcieri <bascule at inferno.tusculum.edu>\n"
+"\n"
+"PÅÃspÄvky od:\n"
+"Chris Montgomery <monty at xiph.org>\n"
+"Peter Alm <peter at xmms.org>\n"
+"Michael Smith <msmith at labyrinth.edu.au>\n"
+"Jack Moffitt <jack at icecast.org>\n"
+"Jorn Baayen <jorn at nl.linux.org>\n"
+"Håvard Kvålen <havardk at xmms.org>\n"
+"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
+"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis Dekodér"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Detaily o %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX Dekodér"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX Dekodér"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack Dekodér"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "Ztrátové (hybridnÃ)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "Ztrátové"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -3830,14 +4178,18 @@ msgstr ""
"\n"
"NÄkterý kód pluginů vytvoÅil Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack Dekodér"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF Dekodér"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b> Konfigurace XSF</b>"
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Ignoruj délku ze souboru"
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "XML Shareable Playlists (XSPF)"
diff --git a/po/da.po b/po/da.po
index 1a0e4d06d104..5fadee1ac6f2 100644
--- a/po/da.po
+++ b/po/da.po
@@ -3,14 +3,14 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# Joe Hansen <joedalton2 at yahoo.dk>, 2013
+# Joe Hansen <joedalton2 at yahoo.dk>, 2013-2014
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Danish (http://www.transifex.com/projects/p/audacious/"
"language/da/)\n"
"Language: da\n"
@@ -19,40 +19,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "surround"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
-msgstr ""
-
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
-msgid "sequenced"
-msgstr ""
+msgstr "AAC (Raw)-afkoder"
-#: src/adplug/plugin.c:14
+#: src/adplug/adplug-xmms.cc:42
msgid "AdPlug (AdLib Player)"
msgstr "AdPlug (AdLib-afspiller)"
-#: src/alarm/alarm.c:778
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
+msgid "sequenced"
+msgstr "sekventeret"
+
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarm"
+
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
-msgstr ""
+msgstr "Angiv alarm ..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -63,11 +51,7 @@ msgstr ""
"\n"
"Oprindelig skrevet af Adam Feakin og Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarm"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -89,8 +73,26 @@ msgid ""
"\n"
"\n"
msgstr ""
+"Tidspunkt\n"
+" Alarmtidspunkt:\n"
+" Tidspunktet alarme udløses på.\n"
+"\n"
+" Stille efter:\n"
+" Stop alarmen efter dette tidsforløb.\n"
+" (hvis opvågningsdialogen ikke er lukket)\n"
+"\n"
+"\n"
+"Dage\n"
+" Dag:\n"
+" Vælg dagene for hvor alarmen skal være aktiv.\n"
+"\n"
+" Tidspunkt:\n"
+" Vælg tidspunkt for alarmen på hver dag,\n"
+" eller vælg skift-knappen for at benytte standardtidspunktet.\n"
+"\n"
+"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -111,8 +113,26 @@ msgid ""
" Run this command at the alarm time.\n"
"\n"
msgstr ""
+"Lydstyrke\n"
+" Lydovergang:\n"
+" øg lydstyrken til den valgte lydstyrke\n"
+" via denne mængde tid.\n"
+"\n"
+" Begynd ved:\n"
+" Begynd lydovergang fra denne lydstyrke.\n"
+"\n"
+" Endelig:\n"
+" Lydstyrken hvor lydovergang stopper. Hvis lydovergangens\n"
+" tid er 0 så angiv lydstyrken til dette og start\n"
+" afspilning.\n"
+"\n"
+"\n"
+"Tilvalg:\n"
+" Yderligere kommando:\n"
+" Kør denne kommando på alarm-tidspunktet.\n"
+"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -126,360 +146,371 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "SÃ¥ gik alarmen."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
-msgstr ""
+msgstr "Din huskeseddel for i dag er ..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "PÃ¥mindelse"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Mondag"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Tirsdag"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Onsdag"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Torsdag"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Fredag"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Lørdag"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Søndag"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Alarmindstillinger"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Tid"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarm (standard):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "t"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Stille efter:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "timer"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minutter"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Vælg dagene hvor alarmen skal udløses"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Dag"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Standard"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Dage"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Overgang"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "sekunder"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Lydstyrke"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Start"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Endelig"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Nuværende"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Yderligere kommando"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "aktiver"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Afspilningsliste (valgfri)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Vælg en afspilningsliste"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Indstillinger"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Hvad betyder disse indstillinger?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Hjælp"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Omslag"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Omslagskunst (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA-lydkanal"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ALSA Output Plugin for Audacious\n"
+"Ophavsret 2009-2012 John Lindgren\n"
+"\n"
+"Mange tak til William Pitcock, forfatter til ALSA Output Plugin NG, hvis "
+"kode fungerede som en reference når ALSA-manualen ikke var nok."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Standard-PCM-enhed"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Standardenhed for mikser"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM-enhed:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Mikserenhed:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Mikserelement:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Arbejd uden om tømningsafbrydelse"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI-afspiller)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA-lydkanal"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI-afspiller)"
-
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
-msgstr ""
+msgstr "Tilsidesæt standardforstærkning:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
-msgstr ""
+msgstr "Tilsidesæt standardpolyfoni:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
-msgstr ""
+msgstr "Tilsidesæt standardefterklang:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
-msgstr ""
+msgstr "Tilsidesæt standardomkvæd:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
-msgstr ""
+msgstr "<b>Afspilning</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
-msgid "Drum shift:"
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:132
+msgid "Drum shift:"
+msgstr "Trommeskift:"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Udelad foranstillet tavshed"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Udelad bagvedstillet tavshed"
+
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
-msgstr ""
+msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
-msgstr ""
-
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr ""
+msgstr "<b>Synthesizer</b>"
+
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - vælg SoundFont-fil"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Afbryd"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
-msgstr ""
+msgstr "_Ã
bn"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Filnavn"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Størrelse (byte)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Navn:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI-information </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Format:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Længde (ms):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Antallet af numre:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variabel"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI-kommentarer og sangtekster </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* ingen kommentarer tilgængelig i denne MIDI-fil *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* ingen sangtekster tilgængelige i denne MIDI-fil *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Luk"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr "(Ugyldig UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Om AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -489,153 +520,154 @@ msgid ""
"Based in part on Evan Martin's Ghosd library:\n"
"http://neugierig.org/software/ghosd/"
msgstr ""
+"Audacious OSD\n"
+"http://www.develia.org/projects.php?p=audacious#aosd\n"
+"\n"
+"Skrevet af Giacomo Lozito <james at develia.org>\n"
+"\n"
+"Baseret delvist på Evan Martins Ghosd-bibliotek:\n"
+"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (On-Screen Display)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Rektangel"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Afrundet rektangel"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Konkav rektangel"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Ingen"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Start for afspilning"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Udløser OSD når et afspilningspunkt spilles."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Ãndring af titel"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Udløser OSD når, under afspilning, sangens titel ændres men filnavnet er det "
-"samme. Det er hovedsagelig nyttigt til at vise små ændringer i "
-"internetudsendelser."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Pause aktiveret"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Udløser OSD når afspilning sættes på pause."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Pause deaktiveret"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Udløser OSD når pause fjernes fra afspilning "
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Placering"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Relativ X-forskydning:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Relativ Y-forskydning:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Maks OSD-bredde:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Flerskærmsindstillinger"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Vis OSD med:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "alle skærme"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "skærm %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Timing (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Visning:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Ton ind:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Ton ud:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Skrifttyper"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Skrifttype %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Skygge"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Optegningsstil"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Farver"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Farve %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Aktiver udløser"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Hændelse"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Composite-håndtering detekteret"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -645,112 +677,112 @@ msgstr ""
"med mindre du ved at du har en kørende, så aktiver en composite-håndtering "
"ellers vil OSD'en ikke fungere korrekt"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Composite-håndtering er ikke krævet for falsk gennemsigtighed"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Gennemsigtighed"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Falsk gennemsigtighed"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Reel gennemsigtighed (kræver X Composite Ext.)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Composite-udvidelse er ikke indlæst"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Composite-udvidelse er ikke tilgængelig"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - konfiguration"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Position"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animation"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Tekst"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Dekoration"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Udløser"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Diverse"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Test"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
-msgstr ""
+msgstr "ASXv3-afspilningslister"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2-afspilningslister"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious-afspilningslister (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Farve</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Sløret omfang"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-til-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Forhåndsindstillinger:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Nyhedskildeniveau:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Klip frekvens:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Forhåndsindstillinger:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer Stereophonic-til-Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Spektrumanalyseprogram"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Lyd-cd-udvidelsesmodul"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -761,172 +793,167 @@ msgid ""
"\n"
"This was a Google Summer of Code 2007 project."
msgstr ""
+"Ophavsret 2007-2012 Calin Crisan <ccrisan at gmail.com> og andre.\n"
+"\n"
+"Mange tak til libcdio-udviklerne <http://www.gnu.org/software/libcdio/>\n"
+"og til libcddb-udviklere <http://libcddb.sourceforge.net/>.\n"
+"\n"
+"Også tak til Tony Vroon for vejledning.\n"
+"\n"
+"Dette var et Google Summer of Code 2007-projekt."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Enhed</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Læs hastighed:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Tilsidesæt enhed:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadata</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Brug CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Brug CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Brug HTTP i stedet for CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Server:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Sti:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Port:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Lyd-cd-udvidelsesmodul"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
-msgstr ""
+msgstr "Kunne ikke initialisere cdio-undersystemet."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "Ugyldig URI %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Nummeret %d blev ikke fundet."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Kunne ikke åbne lydudkanal"
+msgstr "Spor %d er et dataspor."
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Kunne ikke læse lyd-cd."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Lyd-cd"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Kunne ikke åbne cd-enhed %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Intet cd-drev med lyd blev fundet."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "Kunne ikke afslutte initialisering af åbnet cd-drev."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Kunne ikke indhente første/sidste nummer."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Kan ikke læse start/slut LSN for spor %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Kunne ikke oprette cddb-forbindelsen."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Kunne ikke forespørge CDDB-serveren"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Kunne ikke forespørge CDDB-serveren: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Kunne ikke læse cddb-informationen: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Drev er tomt."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Disktype er ikke understøttet."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Menupunkter for lyd-cd"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Afspil cd"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Tilføj cd"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Menupunkter for lyd-cd"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Komprimering</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Lydstyrke for centrum:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Dynamisk interval:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Ophavsret 2010-2012 John Lindgren"
+"Ophavsret 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Dynamisk intervalkomprimering"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -943,207 +970,232 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Bas:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Diskant:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
-msgstr ""
+msgstr "Ekko:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Standardlængde for sang:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>Resampling</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Aktiver gensampling af lyd"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Gensamplingsfrekvens"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
-msgstr ""
+msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ignorer længde fra SPC-mærker"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Ãg ekko"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Musikafkoder for spilkonsol"
-#: src/crossfade/crossfade.c:83
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "CoreAudio-udgang"
+
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"Glidende overgang mislykkedes da sangene havde forskellige antal kanaler. Du "
-"kan bruge kanalmikseren til at konvertere sangene til det samme antal "
-"kanaler."
-#: src/crossfade/crossfade.c:90
-msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-"Glidende overgang mislykkedes da sangene havde forskellige "
-"samplingshastigheder. Du kan bruge Konvertering af samplingshastighed til at "
-"konvertere sangene til den samme samplingshastighed."
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Crossfade-udvidelsesmodul for Audacious\n"
-"Ophavsret 2010-2012 John Lindgren"
+"Crossfade Plugin for Audacious\n"
+"Ophavsret 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Glidende overgang</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "Ved automatisk sangændring"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr ""
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "Ved søgning eller manuel sangændring"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Fif</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Glidende overgang"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"Glidende overgang mislykkedes da sangene havde forskellige antal kanaler. Du "
+"kan bruge kanalmikseren til at konvertere sangene til det samme antal "
+"kanaler."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"Glidende overgang mislykkedes da sangene havde forskellige "
+"samplingshastigheder. Du kan bruge Konvertering af samplingshastighed til at "
+"konvertere sangene til den samme samplingshastighed."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Crystalizer</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intensitet:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Crystalizer"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Cue Sheet-udvidelsesmodul"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Slet filer"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
-msgstr ""
+msgstr "Kunne ikke flytte %s til papirkurven: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
-msgstr ""
+msgstr "Kunne ikke slette %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
-msgstr ""
+msgstr "Kunne ikke slette %s: ikke en lokal fil."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
-msgstr ""
+msgstr "Ãnsker du at flytte de valgte filer til papirkurven?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
-msgstr ""
+msgstr "Flyt til papirkurven"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
-msgstr ""
+msgstr "Ãnsker du permanent at slette de valgte filer?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Slet"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Afbryd"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
-msgstr ""
+msgstr "Slet valgte filer"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
-msgstr ""
+msgstr "<b>Slettemetode</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
+msgstr "Flyt til papirkurven i stedet for at slette øjeblikkeligt"
+
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
msgstr ""
+"Echo Plugin\n"
+"Af Johan Levin, 1999\n"
+"Surround-ekko af Carl van Schaik, 1999\n"
+"Opdateret for Audacious af William Pitcock og John Lindgren, 2010-2014"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Ekko</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Forsinkelse:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Tilbagemelding:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Lydstyrke:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Echo-udvidelsesmodul\n"
-"Af Johan Levin, 1999\n"
-"\n"
-"Surround echo af Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Echo"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg-udvidelsesmodul"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1152,56 +1204,62 @@ msgid ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
+"Lydafkodningsmodul til flere formater for Audacious der bruger\n"
+"FFmpeg-multimedierammen (http://www.ffmpeg.org/)\n"
+"\n"
+"Audacious-udvidelsesmodul af:\n"
+"William Pitcock <nenolod at nenolod.net>\n"
+"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg-udvidelsesmodul"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "FileWriter-udvidelsesmodul"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Filformat for lyden:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Konfigurer"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Gem i oprindelig mappe"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Gem i mappe efter eget valg"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Filmappe for lyd:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Vælg en mappe"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Hent filnavn fra"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Opret filnavnet fra:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "oprindelige filmærker"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Original filmærke"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "oprindelig filnavn"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Original filnavn"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Fjern ikke filnavnsendelsen"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "Inkluder original navn på filendelsen"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
msgstr "Foranstil rækkefølge for numrene til filnavnet"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1219,187 +1277,201 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "FileWriter-udvidelsesmodul"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Auto"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Fælles stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3-konfiguration"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_O.k."
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Algoritmekvalitet"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Samplingsfrekvens for lydudgang:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Bithastighed/komprimeringsforhold:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Bithastighed (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Komprimeringsforhold:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Lydtilstand:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "Diverse:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
msgstr "Fremtving streng ISO-overholdelse"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Fejlbeskyttelse"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Kvalitet"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Aktiver VBH/GBH"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Type:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBH-indstillinger:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Minimum for bithastighed (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Maksimum for bithastighed (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Fremtving strengt minimum for bithastighed"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "GBH-indstillinger:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Gennemsnitlig bithastighed (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR-kvalitetsniveau:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Skriv ikke Xing VBH-hoved"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Udelad Xing VBR-teksthoved"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBH/GBH"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr "Billedparametre:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Marker som ophavsret"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Marker som original"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "ID3-parametre:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Fremtving tilføjelse af version 2-mærke"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Tilføj kun v1-mærke"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Tilføj kun v2-mærke"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Mærker"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Konfiguration af Vorbiskoder"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Kvalitetsniveau (0-10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC-afkoder"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "uden kvalitetstab"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
+"Original kode af\n"
+"Ralf Ertzinger <ralf at skytale.net>\n"
+"\n"
+"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC-afkoder"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
+"GIO-udvidelsesmodul for Audacious\n"
+"Ophavsret 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO-udvidelsesmodul"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "Læs og tilføj-tilstand er ikke understøttet"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "Ugyldig åbn-tilstand"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1410,531 +1482,629 @@ msgid ""
"\n"
"License: GPLv2+"
msgstr ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Ophavsret 2013 Christophe Budé, John Lindgren og Carlo Bramini\n"
+"\n"
+"Baseret på XMMS-udvidelsesmodulet:\n"
+"Ophavsret 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson og "
+"4Front Technologies\n"
+"\n"
+"Licens: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
-msgstr ""
+msgstr "OpenGL-spektrumanalyseprogram"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Ophavsret 2013 Christophe Budé, John Lindgren og Carlo Bramini\n"
+"Ophavsret 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Ophavsret 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson og "
+"4Front Technologies\n"
+"\n"
+"Licens: GPLv2+"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "OpenGL-spektrumanalyseprogram (Qt)"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
msgstr "Genvejstaster for GNOME"
-#: src/gtkui/columns.c:34
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+"Udvidelsesmodul til genvejstaster for GNOME\n"
+"Gør at du kan kontrollere din afspiller med GNOME's genvejstaster.\n"
+"\n"
+"Ophavsret 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Postnummer"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Titel"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Kunstner"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Ã
r"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Album"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Kunstner"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Nummer"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Genre"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Køposition"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Længde"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Filsti"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Filnavn"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Tilpasset titel"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Bithastighed"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
-msgstr ""
+msgstr "Tilgængelige kolonner"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
-msgstr ""
+msgstr "Viste kolonner"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Søgeværktøj"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Dok til venstre"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Dok til højre"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Dok øverst"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Dok nederst"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Fjern dok"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Deaktiver"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Søgeværktøj"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Ã
bn filer ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Ã
bn a_dresse ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_Tilføj filer ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "_Tilføj adresse ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
-msgstr ""
+msgstr "Søg _bibliotek"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "_Om ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
-msgstr ""
+msgstr "_Indstillinger ..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Afslut"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Afspil"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "_Pause"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Stop"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_Forrige"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_Næste"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Gentag"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_Bland"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "_Ingen næste afspilningsliste"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Stop _Efter denne sang"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Sanginformation ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "_Hop til tid ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "_Hop til sang ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
-msgstr ""
+msgstr "Angiv gentagelsespunkt _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
-msgstr ""
+msgstr "Angiv gentagelsespunkt _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_Ryd gentagelsespunkter"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Efter _titel"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr "Efter _filnavn"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Efter fil_sti"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Efter _rækkefølge for nummeret"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Efter _kunstner"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Efter al_bum"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Efter _kunstner"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Efter _udgivelsesdato"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "Efter _længde"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Efter _filsti"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Efter _tilpasset titel"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "_Omvendt rækkefølge"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_Vilkårlig rækkefølge"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_Start denne afspilningsliste"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Opdater"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Sorter"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
-msgstr ""
+msgstr "Sorter _valgte"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "Fjern dupletter"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Fjern _utilgængelige filer"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Ny"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "_Omdøb ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
-msgstr ""
+msgstr "_Fjern"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importer ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Eksporter ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "HÃ¥ndtering af _afspilningslister ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_Køhåndtering ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Lydstyrke _op"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "Lydstyrke _ned"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Equalizer"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
-msgstr ""
+msgstr "_Effekter ..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Vis _menubjælke"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Vis _informationsbjælke"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Vis _visualisering for informationsbjælken"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Vis _statusbjælke"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Vis _resterende tid"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
-msgstr ""
+msgstr "_Visualiseringer ..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Fil"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Afspilning"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Afspilningsliste"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Tjenester"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Lydudgang"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Vis"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Sæt i kø/fjern fra kø"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "_Klip"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Kopier"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Indsæt"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Vælg _alle"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_Omdøb ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
-msgstr ""
+msgstr "<b>Afspilningslistefaneblade</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
-msgstr ""
+msgstr "Vis altid faneblade"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
-msgstr ""
+msgstr "<b>Afspilningslistekolonner</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
-msgstr ""
+msgstr "Vis teksthoveder for kolonner"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Diverse</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
-msgstr ""
+msgstr "Rul ved sangændring"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK-grænseflade"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Mellemlagrer ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d kanal"
msgstr[1] "%d kanaler"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Tilstand for én."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Afspilningstilstand."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Stopper efter sang."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Forrige nummer"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Afspil"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pause/genoptag"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Stop"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Næste nummer"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "Fremad 5 sekunder"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "Tilbage 5 sekunder"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Sluk lyden"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Lydstyrke op"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Lydstyrke ned"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Hop til fil"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "Skift afspillervinduer"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Vis On-Screen-Display"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "Skift gentag"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "Skift bland"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "Skift stop efter nuværende"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
-msgstr ""
+msgstr "Hæv vinduer for afspiller"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(ingen)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1945,15 +2115,11 @@ msgstr ""
"\n"
"Ãnsker du at fortsætte?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Binding af museknapper"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Konfiguration af udvid.modul for globale genvejstaster"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -1961,23 +2127,27 @@ msgstr ""
"Tryk på en tastekombination i et tekstfelt.\n"
"Du kan også binde museknapper."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Genvejstaster:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Handling:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Genvejstast:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
-msgstr ""
+msgstr "_Tilføj"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Globale genvejstaster"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1992,56 +2162,51 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Globale genvejstaster"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK-lydkanal"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "Forbind automatisk til udgangsporte"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "Kun %d JACK-udgangsporte blev fundet, men %d var krævet."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Kunen ikke forbinde til JACK-port %s"
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "Kunne ikke forbinde til JACK-serveren; kører den?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK-lydkanal"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s-indstillinger"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Indstillinger for LADSPA-vært"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Modulstier:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2052,68 +2217,41 @@ msgstr ""
"Efter tilføjelse af nye stier, tryk Retur for at skanne for nye "
"udvidelsesmoduler.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Tilgængelige udvidelsesmoduler:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Aktiver"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Aktiverede udvidelsesmoduler:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Indstillinger"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
+"LADSPA-vært for Audacious\n"
+"Ophavsret 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA-vært"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: Kunne ikke initiere LIRC-understøttelse\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: Forsøger at forbinde igen ...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: Ukendt kommando »%s«\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: Frakoblet fra LIRC\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: Vil forsøge at forbinde igen hver %d sekunder ...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC-udvidelsesmodul"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2128,74 +2266,95 @@ msgid ""
"\n"
"For more information about LIRC, see http://lirc.org."
msgstr ""
+"Et simpelt udvidelsesmodul til at kontrollere Audacious med LIRC's eksterne "
+"kontroldæmon\n"
+"\n"
+"Tilpasset Audacious af:\n"
+"Tony Vroon <chainsaw at gentoo.org>\n"
+"Joonas Harjumäki <jharjuma at gmail.com>\n"
+"\n"
+"Baseret på XMMS LIRC-udvidelsesmodulet af:\n"
+"Carl van Schaik <carl at leg.uct.ac.za>\n"
+"Christoph Bartelmus <xmms at bartelmus.de>\n"
+"Andrew O. Shadoura <bugzilla at tut.by>\n"
+"\n"
+"For yderligere information om LIRC, se http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Forbindelse</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Forbind igen til LIRC-serveren"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Vent før du forbinder igen:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC-udvidelsesmodul"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki-udvidelsesmodul"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Ingen sangtekster er tilgængelige"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Fejl"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Kunne ikke hente %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Fejl"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Kunne ikke fortolke %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Kigger efter sangtekster ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Manglende sangmetadata"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Forbinder til lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki-udvidelsesmodul"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "LyricWiki-udvidelsesmodul (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U-afspilningslister"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr ""
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Tact-opretter: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Tact-opretter: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2204,162 +2363,196 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr ""
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Kanalmikser"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
+"Channel Mixer-udvidelsesmodul for Audacious\n"
+"Ophavsret 2011-2012 John Lindgren og MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Kanalmikser</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Kanaler for lydudgang:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Kanalmikser"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS-udvidelsemodul"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "Der opstod en fejl under forbindelse til MMS-server"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Module-afspiller)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>Opløsning</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Kanaler</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
-msgstr ""
+msgstr "Nærmeste (hurtigste)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
-msgstr ""
+msgstr "Lineær (hurtig)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Niveau:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Ekko</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>Surround</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Støjreduktion"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Afspil Amiga MOD'er"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Gentag</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "Antal gentagelser:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "For at gentage for evigt, så sæt antal gentagelser til -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Module-afspiller)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Surround"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "Disse indstillinger vil træde i kraft når Audacious bliver genstartet"
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123-udvidelsesmodul"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Avanceret</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Brug præcis længdeberegning (langsom)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2-server"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS-udvidelsesmodul"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "Der opstod en fejl ved videresendelse af fortolkning"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Ukendt HTTP-fejl"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "Der opstod en fejl ved fortolkning af adresse"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "For mange videresendelser"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Stoppet"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious afspiller ikke."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Skrivebordspåmindelser"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2379,55 +2572,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
-msgstr ""
+msgstr "Vis afspilningskontroller"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Vis altid påmindelse"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Skrivebordspåmindelser"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "Inkluder albumnavn i påmindelse"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Vis"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pause"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Næste"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Standardenhed"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4-lydkanal"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "OSS3-udgang"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Standardenhed"
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Lydenhed:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Brug anden enhed:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Gem lydstyrke mellem sessioner."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Aktiver formatkonvertering lavet af OSS-programmer."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Aktiver eksklusiv tilstand for at forhindre virtuel blanding."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2435,20 +2637,41 @@ msgid ""
"I would like to thank people on #audacious, especially Tony Vroon and John "
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
+"OSS4 Output Plugin for Audacious\n"
+"Ophavsret 2010-2012 MichaÅ Lipski\n"
+"\n"
+"Jeg vil gerne takke folk på #audacious, specielt Tony Vroon og John Lindgren "
+"og selvfølgelig forfatterne af det tidligere OSS-udvidelsesmodul."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4-lydkanal"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Afspilningshåndtering"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Poster"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Fjern"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "_Omdøb"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS-afspilningslister"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2-afkoder"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio-lydkanal"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2467,146 +2690,238 @@ msgid ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
msgstr ""
+"Audacious PulseAudio Output Plugin\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
+"USA."
+
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "QtMultimedia-udgang"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Ophavsret 2014 William Pitcock\n"
+"\n"
+"Baseret på SDL Output Plugin for Audacious\n"
+"Ophavsret 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Arbejder ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Søg"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio-lydkanal"
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "_Loginspektør ..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Ã
bn filer"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Tilføj filer"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Forrige"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Gentag"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Bland"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Qt-grænseflade"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr ""
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "Udelad/gentag samplinger"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Lineær interpolation"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Fast sinc-interpolation"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "Medium sinc-interpolation"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Bedste sinc-interpolation"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
-msgstr ""
+msgstr "<b>Konvertering</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Metode:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Hastighed:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Hastighedsoversættelser</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Brug hastighedsoversættelser"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32,0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88,2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176,4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr ""
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "Tilladelse nægtet"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
-msgstr ""
+msgstr "Hold dette vindue åben og klik så på »Kontroller rettighed« igen.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "Netværksproblem."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
"Der opstod et problem under forsøget på at kontakte Last.fm. Prøv igen "
"senere."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "Kontrollerer ..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "_Kontroller rettighed"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_Tilbagekald rettighed"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
+"Scrobbler-udvidelsesmodulet kunne ikke startes.\n"
+"Der er måske et problem med din installation."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2616,12 +2931,15 @@ msgid ""
"project.\n"
"\n"
msgstr ""
+"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
+"\n"
+"Ophavsret 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com>\n"
+"\n"
+"Tak til John Lindgren for at give mig en hånd i begyndelsen af dette "
+"projekt.\n"
+"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2629,87 +2947,68 @@ msgstr ""
"Audacious bruger nu en forbedret version af Last.fm Scrobbler.\n"
"Kontroller præferencerne for Scrobbler-udvidelsesmodulet."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL-lydkanal"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
+"SDL Output Plugin for Audacious\n"
+"Ophavsret 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL-lydkanal"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Bibliotek"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Ukendt kunstner"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Ukendt album"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" på %s af %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d resultat"
+msgstr[1] "%d resultater"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d album"
-msgstr[1] "%d albummer"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d skjult)"
+msgstr[1] "(%d skjulte)"
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d sang"
-msgstr[1] ""
-"%s\n"
-" %s, %d sang"
-
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d sang af %s"
-msgstr[1] ""
-"%s\n"
-" %d sange af %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d sang"
+msgstr[1] "%d sange"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "i denne genre"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "på"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "af"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Opret afspilningsliste"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Tilføj til afspilningsliste"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Søg bibliotek"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2717,679 +3016,771 @@ msgstr ""
"For at importere dit musikbibliotek til Audacious skal du vælge en mappe og "
"så klikke på ikonet »Opdater«."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Vent venligst ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Vælg mappe"
-#: src/skins/menus.c:56
-msgid "Open Files ..."
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "SID-afspiller"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>Lydudgang</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Kanaler:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Emulering</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "Emuler MOS 8580 (standard: MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "Vælg ikke automatisk chip-model"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Emuler filter"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Ur-hastighed:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "Vælg ikke automatisk ur-hastighed"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>Afspilningstid</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
msgstr ""
-#: src/skins/menus.c:57
-msgid "Open URL ..."
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Brug kun når sanglængden er ukendt"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "Sæt minimum for afspilningstidspunkt:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Fjernelse af stilhed"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
msgstr ""
+"Silence Removal Plugin for Audacious\n"
+"Ophavsret 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Fjernelse af stilhed</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Tærskel:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
+msgid "Open Files ..."
+msgstr "Ã
bn filer ..."
+
+#: src/skins/menus.cc:65
+msgid "Open URL ..."
+msgstr "Ã
bn adresse ..."
+
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Søg i biblioteket"
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Afspilning"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Afspilningsliste"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Vis"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
-msgstr ""
+msgstr "Tjenester"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
-msgstr ""
+msgstr "Om ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
-msgstr ""
+msgstr "Indstillinger ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
-msgstr ""
+msgstr "Afslut"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
-msgstr ""
-
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Gentag"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Bland"
+msgstr "Sanginformation ..."
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Ingen næste afspilningsliste"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
-msgstr ""
-
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Forrige"
+msgstr "Stop efter denne sang"
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
-msgstr ""
+msgstr "GÃ¥ til sang ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
-msgstr ""
+msgstr "GÃ¥ til tidspunkt ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Ny afspilningsliste"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
-msgstr ""
+msgstr "Omdøb afspilningsliste ..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
-msgstr ""
+msgstr "Fjern afspilningsliste"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
-msgstr ""
+msgstr "Forrige afspilningsliste"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
-msgstr ""
+msgstr "Næste afspilningsliste"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
-msgstr ""
+msgstr "Importer afspilningsliste ..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
-msgstr ""
+msgstr "Eksporter afspilningsliste ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
-msgstr ""
+msgstr "HÃ¥ndtering af afspilningslister ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
-msgstr ""
+msgstr "Køhåndtering ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
-msgstr ""
+msgstr "Opdater afspilningsliste"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Vis redigeringsprogram for afspilningslister"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Vis equalizer"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
-msgstr ""
+msgstr "Vis tilbageværende tid"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Altid øverst"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
-msgstr ""
+msgstr "PÃ¥ alle arbejdsrum"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Dobbelt størrelse"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
-msgstr ""
+msgstr "Tilføj adresse ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
-msgstr ""
+msgstr "Tilføj filer ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Efter titel"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Efter filnavn"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
-msgstr ""
+msgstr "Efter filsti"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Fjern alle"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Ryd kø"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Fjern utilgængelige filer"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Fjern duplikater"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Fjern dem som ikke er valgt"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Fjern de valgte"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Søg og vælg"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Vend markering om"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Vælg ingen"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Vælg alle"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Efter album"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Efter rækkefølge"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Efter kunstner"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Efter album"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Efter kunster"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
+msgstr "Efter udgivelsesdato"
+
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Efter rækkefølge"
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Sæt listen i vilkårlig rækkefølge"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Vend listen om"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Sorter valgt"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Sorter listen"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Klip"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Kopier"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Indsæt"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
-msgstr ""
+msgstr "Tilføj/fjern fra kø"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
-msgstr ""
+msgstr "Indlæs forhåndsindstilling ..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
-msgstr ""
+msgstr "Indlæs autoamtisk forhåndsindstilling ..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
-msgstr ""
+msgstr "Indlæs standard"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
-msgstr ""
+msgstr "Indlæs forhåndsindstillingsfil ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
-msgstr ""
+msgstr "Indlæs EQF-fil ..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
-msgstr ""
+msgstr "Gem forhåndsindstilling ..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
-msgstr ""
+msgstr "Gem automatisk forhåndsindstilling ..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
-msgstr ""
+msgstr "Gem standard"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
-msgstr ""
+msgstr "Gem forhåndsindstillingsfil ..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
-msgstr ""
+msgstr "Gem EQF-fil ..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
-msgstr ""
+msgstr "Slet forhåndsindstilling ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
-msgstr ""
+msgstr "Slet automatisk forhåndsindstilling ..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
-msgstr ""
+msgstr "Importer WinAMP-forhåndsindstillinger ..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
-msgstr ""
+msgstr "Nulstil til nul"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winamps klassiske brugerflade"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Gem"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Indlæs"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
-msgstr ""
+msgstr "Indlæs forhåndsindstillingsfil"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
-msgstr ""
+msgstr "Indlæs EQF-fil"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
-msgstr ""
+msgstr "Gem forhåndsindstillingsfil"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
-msgstr ""
+msgstr "Gem EQF-fil"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
-msgstr ""
+msgstr "Importer Winamp-forhåndsindstillinger"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Forhåndsindstillinger"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Indlæs forhåndsindstilling"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Indlæs automatisk forhåndsindstilling"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Gem forhåndsindstilling"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Gem automatisk forhåndsindstilling"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Slet forhåndsindstilling"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Slet automatisk forhåndsindstilling"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Afspiller:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Afspiller:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Vælg skrifttype for hovedafspillerens vindue:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Afspilningsliste:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Afspilningsliste:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Vælg skrifttype for afspilningslisten:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
-msgstr ""
+msgstr "<b>Tema</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
-msgstr ""
+msgstr "<b>Skrifttyper</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Brug bitmap-skrifttyper (understøtter kun ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
-msgstr ""
+msgstr "Rul igennem sangtitel"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Rul sangtitel i begge retninger"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analyseprogram"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Omfang"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Slukket"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normal"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Ild"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
-msgstr ""
+msgstr "Lodrette linjer"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Linjer"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Bjælker"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Langsomst"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Langsom"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Mellem"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Hurtig"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Hurtigst"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
-msgstr ""
+msgstr "Punktummer"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
-msgstr ""
+msgstr "Linje"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
-msgstr ""
+msgstr "Fast"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Is"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Blød"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
-msgstr ""
+msgstr "<b>Type</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
-msgstr ""
+msgstr "Visualiseringstype:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
-msgstr ""
+msgstr "<b>Analyseprogram</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
-msgstr ""
+msgstr "Vis toppunkter"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
-msgstr ""
+msgstr "Farver:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
-msgstr ""
+msgstr "Stil:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Generelt"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualisering"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr ""
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious-equalizer"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Søg til %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Lydstyrke: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balance: %d%% venstre"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balance: centrum"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balance: %d%% højre"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Menu for indstillinger"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Deakiver »Altid øverst«"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Aktiver »Altid øverst«"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Filinformationsboks"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Tilstand for én."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Afspilningstilstand."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Stopper efter sang."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Søg i punkter i aktiv afspilningsliste"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3401,57 +3792,61 @@ msgstr ""
"Hvis du ikke ved hvordan regulære udtryk fungerer, så indsæt bare en lille "
"del af hvad du søger efter."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
msgstr "Titel:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr "Album:"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr "Kunstner:"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
msgstr "Filnavn:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Ryd forrige valg før søgning"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Skift automatisk kø for matchende punkter"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Opret en ny afspilningsliste med matchende punkter"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Redigeringsprogram for Audacious' afspilningslister"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d of %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Arkiveret Winamp 2.x-tema"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Winamp 2.x-tema der ikke er i arkiv"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Kunne ikke oprette mappe (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile-udvidelsesmodul"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3473,84 +3868,72 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile-udvidelsesmodul"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Om Sndio Output-udvidelsesmodulet"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Sndio-lydudgang"
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Sndio Output-udvidelsesmodulet\n"
-"\n"
-"Skrevet af Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "Enhed (tom for standard):"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Format er ikke understøttet"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Gem og gendan lydstyrke:"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"Der blev forespurgt om et format der ikke understøttes af lydenheden.\n"
-"\n"
-"Prøv igen med sndiod(1)-serveren kørende."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Sndio-fejl: Lydformat er ikke understøttet (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio-enhed"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Sndio-fejl: sio_open() mislykkedes"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(tom er standard)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Sndio-fejl: sio_setpar() mislykkedes"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "O.k."
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Sndio-fejl: sio_start() mislykkedes"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Sangændring"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Kommando der skal køres når Audacious starter en ny sang."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Parametre sendt til skallen skal omsluttes af "
+"citationstegn. Alt andet er en sikkerhedsrisiko.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Kommandoer</b>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Kommando:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Kommando til afvikling ved ny sang:"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Kommando der skal køres mod slutningen af en sang."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Kommando til afvikling ved afsluting på sang:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr ""
-"Kommandoen der skal køres når Audacious når slutningen af afspilningslisten."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Kommando til afvikling ved slut på afspilningsliste:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Kommando der skal køres når titlen ændres sig for en sang (dvs. titler for "
-"netværksudsendelser)."
+"Kommando til afvikling når sangtitlen ændrer sig (for netværksudsendelser):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3564,35 +3947,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Du kan bruge de følgende formatsternge som\n"
-"vil blive erstattet før kommandoen kaldes\n"
-"(ikke alle er nyttige til kommandoen for slut på afspilningslisten)\n"
-"\n"
-"%F: Frekvens (i hertz)\n"
-"%c: Antallet af kanaler\n"
-"%f: Filnavn (fuld sti)\n"
-"%l: Længde (i milllisekunder)\n"
-"%n eller %s: Sangnavn\n"
-"%r: Hastighed (i bit per sekund)\n"
-"%t: Afspilningslsitens position (%02d)\n"
-"%p: Afspiller i øjeblikket (1 eller 0)\n"
-"%a: Kunstner\n"
-"%b: Album\n"
-"%T: Nummerets titel"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>Parametre sendt til skallen skal omsluttes af "
-"citationstegn. Alt andet er en sikkerhedsrisiko.</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Kommandoer"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3601,51 +3965,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Lav"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Høj"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Meget høj"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Kvalitet:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr ""
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Hastighed og tonehøjde"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Hastighed og tonehøjde</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Hastighed:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Tonehøjde:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Hastighed og tonehøjde"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Statusikon"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
-msgstr ""
+msgstr "_Indstillinger ..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3655,40 +4019,47 @@ msgid ""
"This plugin provides a status icon, placed in\n"
"the system tray area of the window manager."
msgstr ""
+"Status Icon Plugin\n"
+"\n"
+"Ophavsret 2005-2007 Giacomo Lozito <james at develia.org>\n"
+"Ophavsret 2010 MichaÅ Lipski <tallica at o2.pl>\n"
+"\n"
+"Dette udvidelsesmdoul tilbyder et statusikon, placeret i statusfeltet i "
+"vindueshåndteringen."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<br>Muserul-handling</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Ãndr lydstyrke"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Ãndr sang der afspilles"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Andre indstillinger</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Deaktiver pop op-vinduet"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Luk statusfeltet"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Gå fremad i afspilningslisten når der rulles opad"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Statusikon"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Ekstra stereo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3698,24 +4069,24 @@ msgstr ""
"\n"
"Af Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Ekstra stereo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Ekstra stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Toneopretter"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Tonegenerator:"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3723,16 +4094,18 @@ msgid ""
"To use it, add a URL: tone://frequency1;frequency2;frequency3;...\n"
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
+"Sine-toneopretter af Håvard Kvålen <havardk at xmms.org>\n"
+"Ãndret af Daniel J. Peng <danielpeng at bigfoot.com>\n"
+"\n"
+"For at bruge tilføjes en adresse: tone://frequency1;frequency2;"
+"frequency3;...\n"
+"f.eks. tone://2000;2005 for at spille en 2000 Hz tone og en 2005 Hz tone"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Toneopretter"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Stemmefjernelse"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3753,44 +4126,75 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis-afkoder"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Detaljer om %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX-afkoder"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX-afkoder"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack-afkoder"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "kvalitetstab (hybrid)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "kvalitetstab"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
+"Ophavsret 2006 William Pitcock <nenolod at nenolod.net>\n"
+"\n"
+"Lidt af udvidelsesmodulets kode blev udført af Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack-afkoder"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF-afkoder"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>XSF-konfiguration</b>"
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Ignorer længde fra fil"
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "XML Shareable-afspilningslister (XSPF)"
diff --git a/po/de.po b/po/de.po
index 32b2f0d71dbf..c4ba4fa88853 100644
--- a/po/de.po
+++ b/po/de.po
@@ -3,18 +3,21 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# Cooligan <ppt23 at lkj.hopto.org>, 2012
+# Chris <ppt23 at lkj.hopto.org>, 2012
+# Chris <ppt23 at lkj.hopto.org>, 2012
+# Ettore Atalan <atalanttore at googlemail.com>, 2014
# Maximilian Vesper <maximilian at mail.com>, 2013
# mschwendt <mschwendt at fedoraproject.org>, 2012
# mschwendt <mschwendt at fedoraproject.org>, 2012
-# Cooligan <ppt23 at lkj.hopto.org>, 2012
+# Chris <ppt23 at lkj.hopto.org>, 2012
+# Thomas Lange <thomas-lange2 at gmx.de>, 2014-2015
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:27+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-18 14:41+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: German (http://www.transifex.com/projects/p/audacious/"
"language/de/)\n"
"Language: de\n"
@@ -23,40 +26,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "Mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "Stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "Surround"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "AAC (MP4) Dekodierer"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "AAC (Raw) Dekodierer"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib-Spieler)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "Sequenziell"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib-Spieler)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarm"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "Alarm setzen ..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -67,11 +58,7 @@ msgstr ""
"\n"
"Ursprünglich geschrieben von Adam Feakin und Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarm"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -112,7 +99,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -152,7 +139,7 @@ msgstr ""
" Führe diesen Befehl bei Auslösung des Alarms aus.\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -176,385 +163,391 @@ msgstr ""
" Aktivieren Sie dazu den Checkbutton und schreiben Sie\n"
" die Erinnerungsnachricht in die Textbox."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Dies ist Ihr Aufwachsignal."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "Die Erinnerung für heute lautet..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Erinnerung"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Montag"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Dienstag"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Mittwoch"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Donnerstag"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Freitag"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Samstag"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Sonntag"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Alarm Einstellungen"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "_OK"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "_Abbrechen"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Uhrzeit"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarm um (Standard):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "Uhr"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Still nach:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "Stunden"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "Minuten"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Tage wählen, an denen der Alarm ausgelöst werden soll"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Tag"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Standard"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Tage"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Ãbergang"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "Sekunden"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Lautstärke"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Beginnen bei"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Schluss"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Momentan"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Zusätzlicher Befehl"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "aktivieren"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Wiedergabeliste (optional)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Wiedergabeliste wählen"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Optionen"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Was bedeuten diese Einstellungen?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Hilfe"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Album-Cover"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Album-Cover (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA Ausgabe"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ALSA Ausgabeplugin für Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"Mein Dank geht an William Pitcock, Autor des ALSA Ausgabeplugins NG, dessen "
+"Code als Referenz gedient hat, wenn die ALSA Dokumentation nicht ausreichend "
+"war."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(keine Beschreibung)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Standard-PCM-Gerät"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Standard-Mixer-Gerät"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM-Gerät:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Mixer-Gerät:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Mixer-Element:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Workaround Drain-Hangup"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI-Spieler)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"ALSA Ausgabeplugin für Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"Modularer MIDI Musikspieler\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"Mein Dank geht an William Pitcock, Autor des ALSA Ausgabeplugins NG, dessen "
-"Code als Referenz gedient hat, wenn die ALSA Dokumentation nicht ausreichend "
-"war."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA Ausgabe"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI-Spieler)"
+"geschrieben von Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"besonderen Dank an...\n"
+"\n"
+"Clemens Ladisch und Jaroslav Kysela\n"
+"für ihre coolen Programme aplaymidi und amixer, welche\n"
+"neben der alsa-lib Dokumentation sehr hilfreich waren,\n"
+"um mehr über die ALSA API zu erfahren\n"
+"\n"
+"Alfredo Spadafina\n"
+"für das schöne MIDI Keyboard Logo\n"
+"\n"
+"Tony Vroon\n"
+"für die gute Hilfe beim Testen"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "Standard Verstärkung überschreiben:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "Standard Polyfonie überschreiben:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "Standard Hall überschreiben:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "An"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "Standard Refrain überschreiben:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>Wiedergabe</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "Transponieren:"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "Halbtöne"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "Drum-Shift:"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>Erweitert</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "Notennummern"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "Kommentare aus MIDI-Datei extrahieren"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Stille am Anfang überspringen"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "Liedtexte aus MIDI-Datei extrahieren"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Stille am Ende überspringen"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>Synthesizer</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr "Resampling-Frequenz:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "Abtastrate:"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - SoundFont-Datei wählen"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Abbrechen"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "Ã_ffnen"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Dateiname"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "GröÃe (Bytes)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Name:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI Info </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Format:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Länge (ms):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Anzahl an Titeln:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variabel"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (Wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Zeitmultiplex:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI Kommentare und Liedtexte </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* keine Kommentare in dieser MIDI-Datei verfügbar *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* keine Liedtexte in dieser MIDI-Datei verfügbar *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "S_chlieÃen"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (ungültiges UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Ãber AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"Modularer MIDI Musikspieler\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"geschrieben von Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"besonderen Dank an...\n"
-"\n"
-"Clemens Ladisch und Jaroslav Kysela\n"
-"für ihre coolen Programme aplaymidi und amixer, welche\n"
-"neben der alsa-lib Dokumentation sehr hilfreich waren,\n"
-"um mehr über die ALSA API zu erfahren\n"
-"\n"
-"Alfredo Spadafina\n"
-"für das schöne MIDI Keyboard Logo\n"
-"\n"
-"Tony Vroon\n"
-"für die gute Hilfe beim Testen"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -572,152 +565,146 @@ msgstr ""
"Zum Teil basierend auf der Ghosd Bibliothek von Evan Martin:\n"
"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (On-Screen Display)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Rechteck"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Abgerundetes Rechteck"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Konkaves Rechteck"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Kein"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Wiedergabebeginn"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Löst OSD beim Abspielen eines Wiedergabelisteneintrags aus."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Titeländerung"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
-msgstr ""
-"Löst OSD aus, wenn sich während der Wiedergabe der Liedtitel ändert, aber "
-"der Dateiname gleich bleibt. Das ist hauptsächlich nützlich, um "
-"Titeländerungen bei Internetstreams anzuzeigen."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
+msgstr "Löst OSD aus, wenn sich der Liedtitel ändert (für Internetstreams)."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Pause An"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Löst OSD beim Pausieren der Wiedergabe aus."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Pause Aus"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Löst OSD beim Fortsetzen der Wiedergabe aus."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Platzierung"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Relative X-Verschiebung:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Relative Y-Verschiebung:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Maximale OSD-Breite:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Multi-Head-Optionen"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "OSD anzeigen auf:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "allen Bildschirmen"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "Bildschirm %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Zeitablauf (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Anzeige:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Einblenden:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Ausblenden:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Schriftarten"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Schriftart %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Schatten"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Render-Stil"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Farben"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Farbe %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Auslöser aktivieren"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Ereignis"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Composite-Manager erkannt"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -727,112 +714,112 @@ msgstr ""
"Sofern ein solcher nicht doch aktiv ist, bitte einen solchen aktivieren, "
"ansonsten wird das OSD nicht funktionieren"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Composite-Manager nicht benötigt für vorgetäuschte Transparenz"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Transparenz"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Pseudo-Transparenz"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Echte Transparenz (benötigt X-Composite-Erweiterung)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Composite-Erweiterung nicht geladen"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Composite-Erweiterung nicht verfügbar"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious-OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious-OSD - Konfiguration"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "_Test"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "_Setzen"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Position"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animation"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Text"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Dekoration"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Auslöser"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Verschiedenes"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Test"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "ASXv3 Wiedergabelisten"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 Wiedergabelisten"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious Wiedergabelisten (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Farbe</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Oszilloskop"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereofonisch-zu-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Voreinstellungen:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Eingabepegel:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Grenzfrequenz:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Voreinstellungen:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer Stereofonisch-zu-Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Spektrumanalysator"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Audio-CD Plugin"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -853,171 +840,158 @@ msgstr ""
"\n"
"Dies war ein Google Summer of Code 2007 Projekt."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Gerät</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Lesegeschwindigkeit:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Gerät überschreiben:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadaten</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "CD-Text benutzen"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "CDDB benutzen"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "HTTP anstatt CDDBP benutzen"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Server:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Pfad:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Port:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Audio-CD Plugin"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "Initialisieren des cdio Subsystems fehlgeschlagen."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "Ungültige URI »%s«."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Titel %d nicht gefunden."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "Titel %d ist eine Datenspur."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Ãffnen der Audioausgabe fehlgeschlagen."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Fehler beim Lesen der Audio-CD."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Audio-CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "Titel %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Ãffnen des CD-Laufwerks »%s« fehlgeschlagen."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Kein geeignetes CD-Laufwerk gefunden."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "AbschlieÃen der Initialisierung des CD-Laufwerks fehlgeschlagen."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Abfragen der ersten/letzten Titelnummer fehlgeschlagen."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Kann Start/Ende LSN für Titel %d nicht lesen."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Herstellen der CDDB Verbindung fehlgeschlagen."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Abfragen des CDDB Servers fehlgeschlagen"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Abfragen des CDDB Servers fehlgeschlagen: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Lesen der CDDB Information fehlgeschlagen: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Laufwerk ist leer."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Nicht unterstützter Disk-Typ."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Audio-CD Menueinträge"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "CD wiedergeben"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "CD hinzufügen"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Audio-CD Menueinträge"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Kompression</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Center Lautstärke:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Dynamischer Bereich:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"Kompressor Plugin für Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Kompressor"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1033,207 +1007,239 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Bass:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Höhe:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "Echo:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Standard-Liedlänge:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>Resampling</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Audio-Resampling aktivieren"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Resampling-Frequenz:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Länge von SPC-Tags ignorieren"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Hall verstärken"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Spielekonsolen-Musik Dekodierer"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"Crossfading fehlgeschlagen, weil die Titel eine andere Anzahl an Kanälen "
-"hatten. Sie können den Kanal-Mixer benutzen, um die Lieder auf die selbe "
-"Anzahl an Kanälen zu konvertieren."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "CoreAudio Ausgabe"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"Crossfading fehlgeschlagen, weil die Titel unterschiedliche Abtastraten "
-"hatten. Sie können den Abtastraten-Konverter benutzen, um die Lieder auf die "
-"selbe Abtastrate zu resamplen."
+"CoreAudio Ausgabeplugin für Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Basierend auf dem SDL Ausgabeplugin für Audacious\n"
+"Copyright 2010 John Lindgren"
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "Benutze exklusiven Modus"
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"Crossfade Plugin für Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Crossfade</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "Bei automatischem Titelwechsel"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "Ãberschneiden:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "Beim Suchen oder manuellem Titelwechsel"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Hinweis</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+"Für besseres Crossfading, aktivieren Sie\n"
+"den Effekt »Stille entfernen«."
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Crossfade"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"Crossfading fehlgeschlagen, weil die Titel eine andere Anzahl an Kanälen "
+"hatten. Sie können den Kanal-Mixer benutzen, um die Lieder auf die selbe "
+"Anzahl an Kanälen zu konvertieren."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"Crossfading fehlgeschlagen, weil die Titel unterschiedliche Abtastraten "
+"hatten. Sie können den Abtastraten-Konverter benutzen, um die Lieder auf die "
+"selbe Abtastrate zu resamplen."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Crystalizer</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intensität:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Crystalizer"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Cuesheet Plugin"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Dateien löschen"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "Fehler beim Verschieben von »%s« in den Papierkorb: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "Fehler beim Löschen von »%s«: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "Fehler beim Löschen von »%s«: Datei nicht lokal gespeichert."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "Möchten Sie die ausgewählten Dateien in den Papierkorb verschieben?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "In den Papierkorb verschieben"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "Möchten Sie die ausgewählten Dateien dauerhaft löschen?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Löschen"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Abbrechen"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "Dateien löschen"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "Ausgewählte Dateien löschen"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>Löschmethode</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "In den Papierkorb verschieben anstatt sofort zu löschen"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+"Echo Plugin\n"
+"Von Johan Levin, 1999\n"
+"Surround Echo von Carl van Schaik, 1999\n"
+"Aktualisiert für Audacious von William Pitcock und John Lindgren, 2010-2014"
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Echo</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Verzögerung:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Rückkopplung:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Lautstärke:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Echo Plugin\n"
-"Von Johan Levin, 1999\n"
-"\n"
-"Surround Echo von Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Echo"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg Plugin"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1249,55 +1255,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg Plugin"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "FileWriter Plugin"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Ausgabedateiformat:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Konfigurieren"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "In Ursprungsverzeichnis speichern"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "In benutzerdefiniertem Verzeichnis speichern"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Ausgabedateiverzeichnis:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Verzeichnis wählen"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Dateiname erhalten von:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Dateiname generieren von:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "ursprünglichen Datei-Tags"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Ursprünglichen Datei-Tags"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "ursprünglichen Dateinamen"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Ursprünglichem Dateiname"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Dateiendung nicht entfernen"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "Ursprüngliche Dateiendung einbeziehen"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Titelnummer vor Dateinamen anhängen"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr "Titelnummer an Dateiname voranstellen"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1314,179 +1320,183 @@ msgid ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"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 "
-"veröffentlicht, weitergeben und/oder modifizieren, entweder gemäà Version 2 "
+"Dieses Programm ist freie Software. Sie können es unter den Bedingungen der\n"
+"GNU General Public License, wie von der Free Software Foundation\n"
+"veröffentlicht, weitergeben und/oder modifizieren, entweder gemäà Version 2\n"
"der Lizenz oder (nach Ihrer Option) jeder späteren Version.\n"
"\n"
-"Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daà es Ihnen "
-"von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die "
-"implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÃR EINEN "
+"Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daà es Ihnen\n"
+"von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die\n"
+"implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÃR EINEN\n"
"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 "
+"Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem\n"
+"Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software\n"
"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "FileWriter Plugin"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Automatisch"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Joint-Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3-Konfiguration"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_OK"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Algorithmen-Qualität:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Ausgabe-Abtastfrequenz:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr "Ausgabe-Abtastrate:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
msgstr "Bitrate / Kompressionsverhältnis:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Bitrate (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Kompressionsverhältnis:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Audio-Modus:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Verschiedenes:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr "Sonstiges:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Strikte ISO-Erfüllung erzwingen"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr "Strikte ISO-Konformität erzwingen"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Fehlerschutz"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Qualität"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "VBR/ABR aktivieren"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Typ:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR-Optionen:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Minimale Bitrate (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Maximale Bitrate (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Minimale Bitrate erzwingen"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR-Optionen:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Durchschnittliche Bitrate (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR-Qualitätsstufe:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Xing-VBR-Header nicht schreiben"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Xing-VBR-Header auslassen"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr "Frame-Parameter:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Als Copyright kennzeichnen"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Als Original kennzeichnen"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "ID3-Parameter:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Hinzufügen von Version-2-Tags erzwingen"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Nur v1-Tag hinzufügen"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Nur v2-Tag hinzufügen"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Tags"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis-Encoder-Konfiguration"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Qualitätsstufe (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC Dekodierer"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "Verlustfrei"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1498,11 +1508,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC Dekodierer"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1510,11 +1516,19 @@ msgstr ""
"GIO Plugin für Audacious\n"
"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO Plugin"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "»Lesen-und-Anhängen«-Modus nicht unterstützt"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "Ungültiger Modus zum Ãffnen"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1534,534 +1548,620 @@ msgstr ""
"\n"
"Lizenz: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL Spektrumanalysator"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+"OpenGL Spektrumanalysator für Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren und Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Basierend auf dem XMMS Plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson und "
+"4Front Technologies\n"
+"\n"
+"Lizenz: GPLv2+"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "OpenGL Spektrumanalysator (Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "GNOME-Tastenkürzel"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-"Gnome Tastenkürzel Plugin\n"
-"Ermöglicht die Kontrolle von Audacious mit Gnome Tastenkürzeln.\n"
+"GNOME Tastenkürzel Plugin\n"
+"Ermöglicht die Kontrolle von Audacious mit GNOME Tastenkürzeln.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Gnome Tastenkürzel"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Eintragsnummer"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Titel"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Künstler"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Jahr"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Album"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Album-Künstler"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Titelnummer"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Genre"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Warteschlangenposition"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Länge"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Dateipfad"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Dateiname"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Benutzerdefinierter Titel"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Bitrate"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "Verfügbare Spalten"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "Angezeigte Spalten"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Suchwerkzeug"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Links andocken"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Rechts andocken"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Oben andocken"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Unten andocken"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Abdocken"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Deaktivieren"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Suchwerkzeug"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Dateien öffnen ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "_URL öffnen ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "Dateien _hinzufügen ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "U_RL hinzufügen ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "Durchsuche _Sammlung"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "_Info ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "_Einstellungen ..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Beenden"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Wiedergabe"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "_Pause"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Stopp"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_Vorheriger"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_Nächster"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "Wieder_holen"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_Zufällige Wiedergabe"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Wiedergabeliste ni_cht weiterspielen"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Nach _diesem Titel stoppen"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "Titel_info ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Zu Z_eitangabe springen ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "Zu _Titel springen ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "Wiederholpunkt _A setzen"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "Wiederholpunkt _B setzen"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "Wiederholpunkte _löschen"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Nach _Titel"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr "Nach _Dateinamen"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Nach Datei_pfad"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Nach Titel_nummer"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Nach _Künstler"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Nach _Album"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Nach Albu_m-Künstler"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Nach _Erscheinungsdatum"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "Nach _Genre"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "Nach _Länge"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Nach _Dateipfad"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Nach _benutzerdefiniertem Titel"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "_Vertausche Anordnung"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_Zufällige Anordnung"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_Wiedergabeliste abspielen"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_Abspielen/Fortsetzen"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
-msgstr "_Aktualisieren"
+msgstr "Aktualisie_ren"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Sortieren"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "Auswahl sor_tieren"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "_Duplikate entfernen"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Nicht _verfügbare Dateien entfernen"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Neu"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "_Umbenennen ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "_Löschen"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importieren ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Exportieren ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
-msgstr "Wiedergabe_listen-Manager ..."
+msgstr "_Wiedergabelisten-Manager ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Warteschlangen-_Manager ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Lautstärke er_höhen"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "Lautstärke _verringern"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Equalizer"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "E_ffekte ..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "_Menüleiste anzeigen"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "I_nfobereich anzeigen"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Vis_ualisierungen im Infobereich"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "_Statusleiste anzeigen"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Verbleibende _Zeit anzeigen"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "_Visualisierungen ..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Datei"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Wiedergabe"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
-msgstr "Wiedergabe_liste"
+msgstr "Wiederga_beliste"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
-msgstr "Di_enste"
+msgstr "Die_nste"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Ausgabe"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "An_sicht"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "In/Aus _Warteschlange"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "_Beinhaltenden Ordner öffen"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Aus_schneiden"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Kopieren"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Einfügen"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "_Alles auswählen"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_Umbenennen ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>Wiedergabelistenreiter</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "Wiedergabelistenreiter immer anzeigen"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "Titelanzahl anzeigen"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "SchlieÃen-Buttons anzeigen"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>Wiedergabelistenspalten</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "Spaltenüberschriften anzeigen"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Sonstiges</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr "Zeitspanne für Pfeiltasten:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "Mit Titelwechsel scrollen"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK Interface"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Puffern ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "Mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "Stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d Kanal"
msgstr[1] "%d Kanäle"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Single-Modus."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Wiedergabelistenmodus."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Nach Titel stoppen."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Vorheriger Titel"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Wiedergabe"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pause/Fortsetzen"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Stopp"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Nächster Titel"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "5 Sekunden vorspulen"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "5 Sekunden zurückspulen"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Stumm"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Lautstärke erhöhen"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Lautstärke verringern"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Zu Titel springen"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "Fenster anzeigen/verstecken"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "On-Screen-Display anzeigen"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "Wiederholen ein-/ausschalten"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "Zufällige Wiedergabe ein-/ausschalten"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "Nach diesem Titel stoppen ein-/ausschalten"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Fenster in den Vordergrund holen"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(keine)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2072,15 +2172,11 @@ msgstr ""
"\n"
"Möchten Sie trotzdem fortfahren?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Maustastenkombinationen"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Globale Tastenkürzel Einstellungen"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2088,23 +2184,27 @@ msgstr ""
"Drücken Sie eine Tastenkombination innerhalb eines Textfeldes.\n"
"Sie können auch Maustasten verwenden."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Tastenkürzel:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Aktion:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Tastenkombination:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "_Hinzufügen"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Globale Tastenkürzel"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2130,60 +2230,56 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Globale Tastenkürzel"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK Ausgabe"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "Mit allen verfügbaren Ports verbinden"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "Automatisch mit Ausgabeports verbinden"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "Nur mit Ausgabeports verbinden"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "Nur %d JACK Ausgabeports gefunden, aber %d erforderlich."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "Mit keinem Port verbinden"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Verbinden zu JACK Port %s fehlgeschlagen."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "Verbindungsmodus:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+"JACK unterstützt nur Gleitkomma Audio. Sie müssen die Ausgabe Bittiefe in "
+"den Audacious Einstellungen auf »Gleitkomma« ändern."
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "Debug-Ausgaben aktivieren"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "Verbinden zum JACK Server fehlgeschlagen. Ist er aktiv?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Basierend auf xmms-jack von Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Portiert für Audacious von Giacomo Lozito"
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK Ausgabe"
+"Der JACK Server erfordert eine Abtastrate von %d Hz, aber Audacious spielt "
+"mit %d Hz. Bitte benutzen Sie den Abtastraten-Konverter Effekt, um diese "
+"Diskrepanz zu korrigieren."
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s Einstellungen"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA Einstellungen"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Modulpfade:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2194,25 +2290,25 @@ msgstr ""
"Drücken Sie nach dem Hinzufügen neuer Pfade Enter, um nach neuen Plugins zu "
"suchen.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Verfügbare Plugins:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Aktivieren"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Aktive Plugins:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Einstellungen"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2220,47 +2316,15 @@ msgstr ""
"LADSPA Host für Audacious\n"
"Copyright 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA Host"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: konnte LIRC Unterstützung nicht initialisieren\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: konnte LIRC Konfigurationsdatei nicht lesen\n"
-"%s: lesen Sie bitte in der Dokumentation von LIRC\n"
-"%s: wie man eine korrekte Konfigurationsdatei erstellt\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: versuche neu zu verbinden...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: unbekannter Befehl »%s«\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: von LIRC getrennt\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: versuche jede %d Sekunden neu zu verbinden...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC Plugin"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2288,73 +2352,81 @@ msgstr ""
"\n"
"Besuchen Sie http://lirc.org für weitere Informationen über LIRC."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Verbindung</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Zum LIRC Server wiederverbinden"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Zeitspanne bis zum Wiederverbinden:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC Plugin"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki Plugin"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Keine Liedtexte verfügbar"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Fehler"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Abrufen von »%s« nicht möglich"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Fehler"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Parsen von »%s« nicht möglich"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Suche nach Liedtexten ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Fehlende Titel-Metadaten"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Verbinde zu lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki Plugin"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "LyricWiki-Plugin (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U Wiedergabelisten"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Takt-Generator"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
-msgstr "Takt-Generator: %d bpm"
+msgstr "Takt-Generator: %d BPM"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
-msgstr "Takt-Generator: %d bpm %d/%d"
+msgstr "Takt-Generator: %d BPM %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2365,14 +2437,14 @@ msgstr ""
"Ein Takt-Generator von Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
"Um ihn zu benutzen, fügen Sie eine URL hinzu: tact://Schläge*Zähler/Nenner\n"
-"z.B. tact://77 zum Spielen von 77 Beats per minute\n"
-"oder tact://60*3/4 zum Spielen von 60 bpm im 3/4-Takt"
+"z.B. tact://77 zum Spielen von 77 BPM\n"
+"oder tact://60*3/4 zum Spielen von 60 BPM im 3/4-Takt"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Takt-Generator"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Kanal-Mixer"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2380,152 +2452,184 @@ msgstr ""
"Kanal-Mixer Plugin für Audacious\n"
"Copyright 2011-2012 John Lindgren und MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Kanal-Mixer</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Ausgabekanäle:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Kanal-Mixer"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS Plugin"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "Fehler beim Verbinden zum MMS Server"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Modulspieler)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>Auflösung</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-Bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-Bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Kanäle</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "Nächstliegend (am schnellsten)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Linear (schnell)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Spline (gute Qualität)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "Polyphase (beste Qualität)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>Abtastfrequenz</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr "<b>Abtastrate</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Pegel:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "Grenzfrequenz:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Hall</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>Bassverstärkung</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>Surround</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>Vorverstärkung</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "Oversampling"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Geräuschreduktion"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Amiga MOD abspielen"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Wiederholen</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "Wiederholzahl:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "Für eine endlose Wiederholung, den obigen Wert auf -1 setzen."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Modulspieler)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Surround"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "Diese Einstellungen treten in Kraft, wenn Audacious neugestartet wird."
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 Plugin"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Erweitert</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Nutze exakte Längenberechnung (langsam)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 Server"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS Plugin"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "Fehler beim Parsen der Weiterleitung"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Unbekannter HTTP Fehler"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "Fehler beim Parsen der URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Zu viele Weiterleitungen"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Gestoppt"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious spielt gerade nichts ab."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Desktop-Benachrichtigungen"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2561,55 +2665,64 @@ msgstr ""
"Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem "
"Programm erhalten haben. Falls nicht, siehe <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Bedienelemente für Wiedergabe anzeigen"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Benachrichtigungen immer anzeigen"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Desktop-Benachrichtigungen"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "Albumname in Benachrichtigung einschlieÃen"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Anzeigen"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pause"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Nächster"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Standardgerät"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 Ausgabe"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "OSS3 Ausgabe"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Standardgerät"
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Audiogerät:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Alternatives Gerät benutzen:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Lautstärke zwischen Sitzungen speichern."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Formatkonvertierung durch OSS aktivieren."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Exklusivmodus aktivieren, um virtuelles Mischen zu verhindern."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2623,19 +2736,35 @@ msgstr ""
"Ich möchte den Personen auf #audacious danken, vor allem Tony Vroon und John "
"Lindgren sowie natürlich den Autoren des bisherigen OSS Plugins."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 Ausgabe"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Wiedergabelisten-Manager"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Einträge"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Löschen"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "_Umbenennen"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS Wiedergabelisten"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2 Dekodierer"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio Ausgabe"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2656,25 +2785,87 @@ msgid ""
msgstr ""
"Audacious PulseAudio Ausgabeplugin\n"
"\n"
-"Dieses Programm ist freie Software. Sie können es unter den Bedingungen der "
-"GNU General Public License, wie von der Free Software Foundation "
-"veröffentlicht, weitergeben und/oder modifizieren, entweder gemäà Version 2 "
+"Dieses Programm ist freie Software. Sie können es unter den Bedingungen der\n"
+"GNU General Public License, wie von der Free Software Foundation\n"
+"veröffentlicht, weitergeben und/oder modifizieren, entweder gemäà Version 2\n"
"der Lizenz oder (nach Ihrer Option) jeder späteren Version.\n"
"\n"
-"Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daà es Ihnen "
-"von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die "
-"implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÃR EINEN "
+"Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daà es Ihnen\n"
+"von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die\n"
+"implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÃR EINEN\n"
"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 "
+"Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem\n"
+"Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software\n"
"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio Ausgabe"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "QtMultimedia Ausgabe"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"QtMultimedia Ausgabeplugin für Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Basierend auf dem SDL Ausgabeplugin für Audacious\n"
+"Copyright 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "In Bearbeitung ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Suchen"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_Ordner öffnen ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "Ordner hin_zufügen ..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "Protoko_ll-Inspektor ..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Dateien öffnen"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Dateien hinzufügen"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Vorheriger"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Wiederholen"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Zufällige Wiedergabe"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Qt Interface"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Abtastraten-Konverter"
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2682,100 +2873,108 @@ msgstr ""
"Abtastraten-Konverter Plugin für Audacious\n"
"Copyright 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "Ãberspringen/Wiederholen der Samples"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Lineare Interpolation"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Schnelle Sinc-Interpolation"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "Mittlere Sinc-Interpolation"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Beste Sinc-Interpolation"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Konvertierung</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Methode:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Abtastrate:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Rate-Mappings</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Nutze Rate-Mappings"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Abtastraten-Konverter"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "OK. Scrobbeln für Profil: »%s«"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "Zugriff verweigert"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"Besuchen Sie den folgenden Link, um Audacious das Scrobbeln Ihrer Titel zu "
"erlauben:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"Lassen Sie das Fenster geöffnet und klicken Sie erneut auf »Berechtigung "
"überprüfen«.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2783,36 +2982,40 @@ msgstr ""
"Keine Sorge, Ihre Scrobbels sind auf Ihrem Computer gespeichert.\n"
"Sie werden übermittelt, sobald Audacious die Berechtigung dazu hat."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "Netzwerkproblem."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
"Es gab ein Problem bei der Verbindung zu Last.fm. Bitte versuchen Sie es "
"später noch einmal."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "Ãberprüfen..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "_Berechtigung überprüfen"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "Berechtigung _entziehen"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"Sie müssen Audacious erlauben, Titel zu Ihrem Last.fm Profil scrobbeln zu "
"dürfen.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2820,7 +3023,7 @@ msgstr ""
"Das Scrobbler Plugin konnte nicht gestartet werden.\n"
"Es könnte sich dabei um ein Installationsproblem handeln."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2837,11 +3040,7 @@ msgstr ""
"Danke an John Lindgren für die anfängliche Hilfe bei diesem Projekt.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2849,7 +3048,11 @@ msgstr ""
"Audacious benutzt jetzt die verbesserte Version des Last.fm Scrobblers.\n"
"Bitte prüfen Sie die Einstellungen für das Scrobbler Plugin."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL Ausgabe"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2857,81 +3060,56 @@ msgstr ""
"SDL Ausgabeplugin für Audacious\n"
"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL Ausgabe"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Sammlung"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Unbekannter Künstler"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Unbekannes Album"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" aus %s von %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d Ergebnis"
+msgstr[1] "%d Ergebnisse"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d Album"
-msgstr[1] "%d Alben"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d versteckt)"
+msgstr[1] "(%d versteckt)"
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d Titel"
-msgstr[1] ""
-"%s\n"
-" %s, %d Titel"
-
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d Titel von %s"
-msgstr[1] ""
-"%s\n"
-" %d Titel von %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d Titel"
+msgstr[1] "%d Titel"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "dieses Genres"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "in"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "von"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "Wiedergabeliste _erstellen"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "Zur Wiedergabeliste _hinzufügen"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Durchsuche Sammlung"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2939,679 +3117,771 @@ msgstr ""
"Wählen Sie einen Ordner und klicken Sie auf »Aktualisieren«, um Ihre "
"Musiksammlung in Audacious zu importieren."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Bitte warten ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Ordner auswählen"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "SID-Spieler"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>Ausgabe</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Kanäle:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Emulation</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "MOS 8580 (Standard: MOS 6581) emulieren"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "Chip-Modell nicht automatisch auswählen"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Filter emulieren"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Taktrate:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "Taktrate nicht automatisch auswählen"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>Wiedergabedauer</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "Maximale Wiedergabedauer setzen:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Nur wenn Titellänge unbekannt ist aktivieren"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "Minimale Wiedergabedauer setzen:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Subtunes</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "Subtunes aktivieren"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "Subtunes ignorieren, wenn kürzer als:"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Hinweis</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Stille entfernen"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"Stille entfernen Plugin für Audacious\n"
+"Copyright 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Stille entfernen</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Grenzbereich:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "Dateien öffnen ..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "URL öffnen ..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Durchsuche Sammlung"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Wiedergabe"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Wiedergabeliste"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Ansicht"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "Dienste"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "Info ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "Einstellungen ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "Beenden"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "Titelinfo ..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Wiederholen"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Zufällige Wiedergabe"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Wiedergabeliste nicht weiterspielen"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "Nach diesem Titel stoppen"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Vorheriger"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "A-B Wiederholung setzen"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "A-B Wiederholung leeren"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "Zu Titel springen ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "Zu Zeitangabe springen ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "Diese Wiedergabeliste spielen"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "Abspielen/Fortsetzen"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Neue Wiedergabeliste"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "Wiedergabeliste umbenennen ..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "Wiedergabeliste löschen"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "Vorherige Wiedergabeliste"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "Nächste Wiedergabeliste"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "Wiedergabeliste importieren ..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "Wiedergabeliste exportieren ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "Wiedergabelisten-Manager ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "Warteschlangen-Manager ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "Wiedergabeliste aktualisieren"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Wiedergabeliste anzeigen"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Equalizer anzeigen"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "Verbleibende Zeit anzeigen"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Immer im Vordergrund"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "Auf allen Arbeitsflächen"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "Hauptfenster aufrollen"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "Wiedergabeliste aufrollen"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "Equalizer aufrollen"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Doppelte GröÃe"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "URL hinzufügen ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "Dateien hinzufügen ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Nach Titel"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "Nach Dateinamen"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "Nach Dateipfad"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Alle entfernen"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Warteschlange löschen"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Nicht verfügbare Dateien entfernen"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Duplikate entfernen"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Nicht ausgewählte entfernen"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Auswahl entfernen"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Suchen und Auswählen"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Auswahl invertieren"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Keine auswählen"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Alle auswählen"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Nach Album"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Nach Titelnummer"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Nach Künstler"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Nach Album"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Nach Album-Künstler"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "Nach Erscheinungsdatum"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Nach Titelnummer"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "Nach Genre"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "Nach Länge"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "Nach benutzerdefiniertem Titel"
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Wiedergabeliste zufällig anordnen"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Wiedergabeliste umkehren"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Auswahl sortieren"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Wiedergabeliste sortieren"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Ausschneiden"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Kopieren"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Einfügen"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "In/Aus Warteschlange"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "Lade Voreinstellung ..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "Lade automatische Voreinstellung ..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "Lade Standardwert"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "Lade Voreinstellung aus Datei ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "Lade EQF-Datei ..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "Speichere Voreinstellung ..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "Speichere automatische Voreinstellung ..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "Speichere Standardwert"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "Speichere Voreinstellung in Datei ..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "Speichere EQF-Datei ..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "Lösche Voreinstellung ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "Lösche automatische Voreinstellung ..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "Importiere Winamp Voreinstellungen ..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "Setze Werte auf Null zurück"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winamp Interface"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Speichern"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Laden"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "Lade Voreinstellung aus Datei"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "Lade EQF-Datei"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "Speichere Voreinstellung in Datei"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "Speichere EQF-Datei"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "Importiere Winamp Voreinstellungen"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Voreinstellungen"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Lade Voreinstellung"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Lade automatische Voreinstellung"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Speichere Voreinstellung"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Speichere automatische Voreinstellung"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Lösche Voreinstellung"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Lösche automatische Voreinstellung"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Hauptfenster:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Hauptfenster:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Hauptfenster-Schrift auswählen:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Wiedergabeliste:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Wiedergabeliste:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Wiedergabelisten-Schrift auswählen:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>Skin</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>Schriftarten</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Benutze Bitmap-Schriftarten (nur ASCII-Unterstützung)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "Titel scrollen"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Titel in beide Richtungen scrollen"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analysator"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Oszilloskop"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "Spektrogramm"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Aus"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normal"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Feuer"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "Vertikale Linien"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Linien"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Balken"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Am langsamsten"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Langsam"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Normal"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Schnell"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Am schnellsten"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "Punkte"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "Linie"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "Beständig"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Eis"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Weich"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>Modus</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "Visualisierungsmodus:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>Analysator</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "Spitzen anzeigen"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "Farbgebung:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "Stil:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "Fallgeschwindigkeit:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "Spitzen-Fallgeschwindigkeit:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "Oszilloskop-Stil:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "Spektrogramm-Farbgebung:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "VU-Meter-Stil:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Allgemein"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualisierung"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Vorverstaerkung"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious Equalizer"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Suche nach %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Lautstaerke: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balance: %d%% links"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balance: Mitte"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balance: %d%% rechts"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Optionen"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "'Immer im Vordergrund' aus"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "'Immer im Vordergrund' an"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Dateiinformationen"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "Visualisierungen"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "Wiederholpunkt A gesetzt."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "Wiederholpunkt B gesetzt."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "Wiederholpunkte geloescht."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Single-Modus."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Wiedergabelistenmodus."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Nach Titel stoppen."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Suche Einträge in aktiver Wiedergabeliste"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "Suchen"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3624,57 +3894,61 @@ msgstr ""
"Ausdrücke funktionieren, geben Sie einfach nur einen Teilbegriff für Ihre "
"Suche ein."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Titel: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr "Titel:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr "Album:"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Künstler: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr "Künstler:"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Dateiname: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Dateiname:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Vorherige Auswahl vor dem Suchen löschen"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Automatisch zwischen passenden Einträgen wechseln"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Erstelle neue Wiedergabeliste mit passenden Einträgen"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audacious Wiedergabeliste"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d von %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Archivierter Winamp 2.x-Skin"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Nicht archivierter Winamp 2.x-Skin"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Konnte Ordner nicht erstellen (»%s«): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile Plugin"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3714,83 +3988,73 @@ msgstr ""
"Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software "
"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile Plugin"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Ãber Sndio Ausgabe Plugin"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Sndio-Ausgabe"
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Sndio Ausgabeplugin\n"
-"\n"
-"Geschrieben von Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "Gerät (leer für Standard):"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Nicht unterstütztes Format"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Lautstärke speichern und wiederherstellen:"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"Ein Format, das nicht vom Audiogerät unterstützt wird, wurde angefordert.\n"
-"\n"
-"Bitte versuchen Sie es erneut mit laufenden sndiod(1) Server."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Sndio-Fehler: Nicht unterstütztes Audioformat (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio Gerät"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Sndio-Fehler: sio_open() fehlgeschlagen"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(Leer bedeutet Standard)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Sndio-Fehler: sio_setpar() fehlgeschlagen"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Sndio-Fehler: sio_start() fehlgeschlagen"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Titelwechsel"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Auszuführender Befehl, wenn Audacious einen neuen Titel startet."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Parameter sollten zwischen Anführungszeichen stehen, "
+"ansonsten besteht ein Sicherheitsrisiko.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Befehle</b>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Befehl:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Auszuführender Befehl, wenn Audacious einen neuen Titel startet:"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Auszuführender Befehl am Ende eines Titels."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Auszuführender Befehl am Ende eines Titels:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "Auszuführender Befehl am Ende der Wiedergabeliste."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Auszuführender Befehl am Ende der Wiedergabeliste:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
"Auszuführender Befehl, wenn sich der Titel eines Lieds ändert (z.B. bei "
-"Netzwerkstreams)."
+"Netzwerkstreams):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3806,8 +4070,7 @@ msgid ""
msgstr ""
"Verwendbar sind folgende Zeichenketten, die ersetzt\n"
" werden, bevor ein Befehl aufgerufen wird\n"
-"(es sind jedoch nicht alle nützlich für den »Ende-der-Wiedergabeliste«-"
-"Befehl):\n"
+"(nicht alle sind sinnvoll für den »Ende-der-Wiedergabeliste«-Befehl):\n"
"\n"
"%F: Frequenz (in Hertz)\n"
"%c: Anzahl der Kanäle\n"
@@ -3821,19 +4084,15 @@ msgstr ""
"%b: Album\n"
"%T: Titelname"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>Parameter sollten zwischen Anführungszeichen stehen, "
-"ansonsten besteht ein Sicherheitsrisiko.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Titelinfo (Qt)"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Befehle"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX Resampler"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3847,51 +4106,51 @@ msgstr ""
"Basierend auf dem Abtastraten-Konverter Plugin:\n"
"Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Schnell"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Niedrig"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Hoch"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Sehr hoch"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Qualität:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Geschwindigkeit und Tonhöhe"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Geschwindigkeit und Tonhöhe</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Geschwindigkeit:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Tonhöhe:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Geschwindigkeit und Tonhöhe"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Status-Icon"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "_Einstellungen ..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3909,39 +4168,39 @@ msgstr ""
"Dieses Plugin stellt ein Status-Icon bereit, welches\n"
"in der Taskleiste des Fenstermanagers angezeigt wird."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Maus-Scroll-Aktion</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Lautstärke ändern"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Aktiven Titel ändern"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Andere Einstellungen</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
-msgstr "PopUp-Fenster deaktivieren"
+msgstr "Popup-Fenster deaktivieren"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "In die Taskleiste minimieren"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Durch Hochscrollen in Wiedergabeliste fortschreiten"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Status-Icon"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Stereo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3951,24 +4210,24 @@ msgstr ""
"\n"
"Von Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra Stereo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Ton-Generator"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Ton-Generator: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3983,15 +4242,11 @@ msgstr ""
"tone://frequenz1;frequenz2;frequenz3;...\n"
"z.B. tone://2000;2005 für einen Ton mit 2000 Hz und einen mit 2005 Hz"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Ton-Generator"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Stimmenaufhebung"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4029,11 +4284,46 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis Dekodierer"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Details über %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"Titel: %t\n"
+"Autor: %a\n"
+"Aus: %f\n"
+"Tracker: %T\n"
+"Kommentar: %C\n"
+"Chiptyp: %c\n"
+"Stereo: %s\n"
+"Schleife: %l\n"
+"Chipfrequenz: %F\n"
+"Spielfrequenz: %P\n"
+"Jahr: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX Dekodierer"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4043,19 +4333,19 @@ msgstr ""
"Basierend auf in_vtx.dll von Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious Plugin von Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX Dekodierer"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack Dekodierer"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "Verlustbehaftet (Hybrid)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "Verlustbehaftet"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4065,23 +4355,18 @@ msgstr ""
"\n"
"Ein Teil des Plugin-Quelltextes war von Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack Dekodierer"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF Dekodierer"
-#: src/xspf/xspf.c:438
-msgid "XML Shareable Playlists (XSPF)"
-msgstr "XML Wiedergabelisten (XSPF)"
-
-#~ msgid "32.0 kHz:"
-#~ msgstr "32.0 kHz:"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>XSF Konfiguration</b>"
-#~ msgid "88.2 kHz:"
-#~ msgstr "88.2 kHz:"
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Länge aus Datei ignorieren"
-#~ msgid "176.4 kHz:"
-#~ msgstr "176.4 kHz:"
+#: src/xspf/xspf.cc:89
+msgid "XML Shareable Playlists (XSPF)"
+msgstr "XML Wiedergabelisten (XSPF)"
diff --git a/po/el.po b/po/el.po
index fc0428fb3146..c7b79e004909 100644
--- a/po/el.po
+++ b/po/el.po
@@ -3,16 +3,17 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# noskamaru <jim.thomas.zks at gmail.com>, 2013
-# noskamaru <jim.thomas.zks at gmail.com>, 2013
+# DImitrios Zakas <jim.thomas.zks at gmail.com>, 2013
+# gis mapps <gismapps at gmail.com>, 2014
+# DImitrios Zakas <jim.thomas.zks at gmail.com>, 2013
# ÎÎ¹Î¬Î½Î½Î·Ï ÎνθÏ
Î¼Î¯Î´Î·Ï <yannanth at gmail.com>, 2012-2013
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Greek (http://www.transifex.com/projects/p/audacious/language/"
"el/)\n"
"Language: el\n"
@@ -21,51 +22,35 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "μονοÏÏνικÏ"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "ÏÏεÏεοÏÏνικÏ"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "ÏεÏιÏεÏειακÏ"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (ÎναÏαÏαγÏγή AdLib)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr ""
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (ÎναÏαÏαγÏγή AdLib)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "ÎÏ
ÏνηÏήÏι"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "ÎÏ
ÏνηÏήÏι"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -88,7 +73,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -110,7 +95,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -124,360 +109,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "ÎÏ
Ïή είναι η κλήÏη αÏÏÏνιÏηÏ."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "Î Ï
ÏενθÏμιÏη ÏÎ±Ï Î³Î¹Î± ÏήμεÏα είναι..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Î¥ÏενθÏμιÏη"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "ÎεÏ
ÏÎÏα"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "ΤÏίÏη"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "ΤεÏάÏÏη"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Î ÎμÏÏη"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "ΠαÏαÏκεÏ
ή"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "ΣάββαÏο"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "ÎÏ
Ïιακή"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "ΡÏ
θμίÏÎµÎ¹Ï ÎÏ
ÏνιÏηÏιοÏ"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "ΧÏÏνοÏ"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "ÎÏÏÏα ÏÏÎ¹Ï (ÏÏοεÏιλογή):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "Ï"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "ΣίγαÏη μεÏά αÏÏ"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "ÏÏεÏ"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "λεÏÏά"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "ÎιαλÎξÏε ÏÎ¹Ï Î·Î¼ÎÏÎµÏ ÏοÏ
θα ÏÏÏ
ÏήÏει Ïο ξÏ
ÏνηÏήÏι"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "ÎμÎÏα"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Î ÏοεÏιλογή"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "ÎμÎÏεÏ"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "ÎεθÏÏιάζει"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "δεÏ
ÏεÏÏλεÏÏα"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "ÎνÏαÏη"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Îεκινάει ÏÏιÏ"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "ΤελικÏ"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "ΤÏÏινÏ"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "ÎÏιÏλÎον ÎνÏολή"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "ενεÏγοÏοίηÏη"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "ÎίÏÏα αναÏαÏαγÏÎ³Î®Ï (ÏÏοαιÏεÏική)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "ÎÏιλÎξÏε μια λίÏÏα αναÏαÏαγÏγήÏ"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "ÎÏιλογÎÏ"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Τι ÏημαίνοÏ
ν αÏ
ÏÎÏ Î¿Î¹ εÏιλογÎÏ;"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Îοήθεια"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "ÎξÏÏÏ
λλο ÎλμÏοÏ
μ"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ÎÎ¾Î¿Î´Î¿Ï ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Î ÏοεÏιλεγμÎνη ÏÏ
ÏκεÏ
ή PCM "
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Î ÏοεÏιλεγμÎνη ÏÏ
ÏκεÏ
ή μείκÏη"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "ΣÏ
ÏκεÏ
ή PCM:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "ΣÏ
ÏκεÏ
ή μείκÏη:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "ΣÏοιÏείο μείκÏη:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
msgstr ""
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ÎÎ¾Î¿Î´Î¿Ï ALSA"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - εÏιλÎξÏε αÏÏείο SoundFont"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_ÎκÏ
Ïο"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
-msgstr ""
+msgstr "_Îνοιγμα"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Îνομα αÏÏείοÏ
"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "ÎÎÎ³ÎµÎ¸Î¿Ï (byte)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Îνομα:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> ΠληÏοÏοÏÎ¯ÎµÏ MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "ÎοÏÏή:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "ÎÎ®ÎºÎ¿Ï (ms):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "ÎÏ. ÎομμαÏιÏν"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "μεÏαβληÏή"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> ΣÏÏλια και ΣÏοίÏοι MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* δεν Ï
ÏάÏÏοÏ
ν ÏÏÏλια Ïε αÏ
ÏÏ Ïο αÏÏείο MIDI *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* δεν Ï
ÏάÏÏοÏ
ν ÏÏοίÏοι Ïε αÏ
ÏÏ Ïο αÏÏείο MIDI *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_ÎλείÏιμο"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (μη ÎγκÏ
Ïο UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "ΣÏεÏικά με Ïο AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -488,261 +479,258 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (ÎÏεικÏνιÏη ÏÏην ÎθÏνη)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ÎÏθογÏνιο"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "ΣÏÏογγÏ
λεμÎνο ÎÏθογÏνιο"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Îοίλο ÎÏθογÏνιο"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "ÎανÎνα"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "ÎναÏξη αναÏαÏαγÏγήÏ"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr ""
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Îλλαγή ΤίÏλοÏ
"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "ΠαÏÏη ÎνεÏγή"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr ""
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "ΠαÏÏη ÎνÎνεÏγη"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr ""
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "ΤοÏοθÎÏηÏη"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr ""
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr ""
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr ""
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "ÎÏιλογÎÏ Î³Î¹Î± ÏολλαÏλÎÏ Î¿Î¸ÏνεÏ"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Î Ïοβολή OSD με ÏÏήÏη:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "ÏÎ»ÎµÏ Î¿Î¹ οθÏνεÏ"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "οθÏνη %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "ΣÏ
γÏÏονιÏμÏÏ (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Î Ïοβολή:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Îμαλή είÏοδοÏ:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "ÎεθÏÏιαÏμα:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "ÎÏαμμαÏοÏειÏÎÏ"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "ÎÏαμμαÏοÏειÏά %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Σκιά"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr ""
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "ΧÏÏμαÏα"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "ΧÏÏμα %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr ""
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "ΣÏ
μβάν"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr ""
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
"manager otherwise the OSD won't work properly"
msgstr ""
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr ""
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "ÎιαÏάνεια"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "ΨεÏÏικη διαÏάνεια"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Î ÏαγμαÏική διαÏάνεια (ÏÏειάζεÏαι X Composite Ext.)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr ""
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr ""
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr ""
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "ÎιαμÏÏÏÏÏη OSD ÏοÏ
Audacious"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "ÎÎÏη"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "ÎίνηÏη"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Îείμενο"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "ÎιακοÏμήÏη"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr ""
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "ÎιάÏοÏα"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ÎίÏÏÎµÏ ÎναÏαÏαγÏÎ³Î®Ï ASXv1/ASXv2"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "ÎίÏÏÎµÏ ÎναÏαÏαγÏÎ³Î®Ï Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>ΧÏÏμα</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr ""
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
-msgstr ""
-
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
msgstr ""
-#: src/bs2b/plugin.c:166
+#: src/bs2b/plugin.cc:129
msgid "Presets:"
msgstr "Î ÏοεÏιλογÎÏ:"
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
+msgstr ""
+
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
msgstr ""
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr ""
+
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "ÎναλÏ
ÏÎ®Ï Î¦Î¬ÏμαÏοÏ"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Î ÏÏÏθεÏο ÎοÏ
ÏικÏν CD"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -763,169 +751,156 @@ msgstr ""
"\n"
"ÎÏ
ÏÏ Ïο ÏÏÏÏθεÏο δημιοÏ
Ïγήθηκε καÏά Ïο Google Summer of Code 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>ΣÏ
ÏκεÏ
ή</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "ΤαÏÏÏηÏα ανάγνÏÏηÏ:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "ΠαÏάκαμÏη ÏÏ
ÏκεÏ
ήÏ:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>ÎεÏαδεδομÎνα</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "ΧÏήÏη CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "ΧÏήÏη CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "ΧÏήÏη HTTP ανÏί CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "ÎξÏ
ÏηÏεÏηÏήÏ:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "ÎιαδÏομή:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "ÎÏÏα:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Î ÏÏÏθεÏο ÎοÏ
ÏικÏν CD"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "ÎÏÎÏÏ
Ïε η αÏÏικοÏοίηÏη ÏοÏ
Ï
ÏοÏÏ
ÏÏήμαÏÎ¿Ï cdio."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "Îη ÎγκÏ
Ïο URI %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Το κομμάÏι %d δεν βÏÎθηκε."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "ÎοÏ
ÏÎ¹ÎºÏ CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr ""
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr ""
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "ÎναÏαÏαγÏγή CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Î ÏοÏθήκη CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr ""
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>ΣÏ
μÏίεÏη</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr ""
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr ""
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr ""
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -943,199 +918,220 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ÎÏάÏο:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr ""
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr ""
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "ÎνεÏγοÏοίηÏη αναÏÏεδίαÏÎ·Ï Î®ÏοÏ
"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "ΡÏ
θμÏÏ Î±Î½Î±ÏÏεδίαÏηÏ:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr ""
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "ÎÏξηÏη ανÏίÏηÏηÏ"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "ÎÏοκÏδικοÏοιηÏÎ®Ï ÎοÏ
ÏÎ¹ÎºÎ®Ï ÎονÏÏÎ»Î±Ï Î Î±Î¹ÏνιδιÏν"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr ""
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr ""
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr ""
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr ""
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "ÎνÏαÏη:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr ""
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "ÎιαγÏαÏή ÎÏÏείÏν"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
-msgstr ""
+msgstr "ÎÎλεÏε να μεÏαÏÎÏεÏε Ïα εÏιλεγμÎνα ÏÏον κάδο ανακÏκλÏÏηÏ;"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
-msgstr ""
+msgstr "ÎεÏακίνηÏη ÏÏον κάδο"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "ÎιαγÏαÏή"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "ÎκÏÏÏÏη"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
-msgstr ""
+msgstr "ÎιαγÏαÏή ÎÏιλεγμÎνÏν ÎÏÏείÏν"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>ÎÏÏ</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "ÎαθÏ
ÏÏÎÏηÏη:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "ÎνάδÏαÏη:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "ÎνÏαÏη:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Î ÏÏÏθεÏο ÎÏοÏ\n"
-"ΤοÏ
Johan Levin, 1999\n"
-"\n"
-"ΠεÏιÏεÏειακή ηÏÏ Î±ÏÏ Ïον Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "ÎÏÏ"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Î ÏÏÏθεÏο FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1145,55 +1141,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "Î ÏÏÏθεÏο FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Î ÏÏÏθεÏο FileWriter"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr ""
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "ÎιαμÏÏÏÏÏη"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr ""
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr ""
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr ""
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "ÎÏιλογή ÏακÎλοÏ
"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "αÏÏικÎÏ ÎµÏικÎÏÎµÏ Î±ÏÏείοÏ
"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "αÏÏÎ¹ÎºÏ Ïνομα αÏÏείοÏ
"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1211,165 +1207,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "Î ÏÏÏθεÏο FileWriter"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "ÎÏ
ÏÏμαÏο"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "ΠολÏ
ÏλεγμÎνο ΣÏεÏεοÏÏνικÏ"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "ΣÏεÏεοÏÏνικÏ"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "ÎονοÏÏνικÏ"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "ÎιαμÏÏÏÏÏη MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "ΠοιÏÏηÏα ÎλγÏÏιθμοÏ
:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Îναλογία ÏÏ
Î¸Î¼Î¿Ï Î¼ÎµÏάδοÏÎ·Ï / ÏÏ
μÏίεÏηÏ:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ΡÏ
θμÏÏ Î¼ÎµÏάδοÏÎ·Ï Î´ÎµÎ´Î¿Î¼ÎνÏν (kb/s):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "ÎÏÎ³Î¿Ï ÏÏ
μÏίεÏηÏ:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "ÎειÏοÏ
Ïγία ÎÏοÏ
:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "ÎιάÏοÏα:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "ÎξαναγκαÏμÏÏ Î±Ï
ÏÏηÏÎ®Ï ÏÏ
μμÏÏÏÏÏÎ·Ï Î¼Îµ ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Î ÏοÏÏαÏία ÏÏαλμάÏÏν"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "ΠοιÏÏηÏα"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "ÎνεÏγοÏοίηÏη VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "ΤÏÏοÏ:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "ÎÏιλογÎÏ VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "ÎλάÏιÏÏÎ¿Ï ÏÏ
θμÏÏ Î¼ÎµÏάδοÏÎ·Ï (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "ÎÎγιÏÏÎ¿Ï ÏÏ
θμÏÏ Î¼ÎµÏάδοÏÎ·Ï (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "ÎÏ
ÏÏηÏά εÏάÏμοÏε ελάÏιÏÏο ÏÏ
Î¸Î¼Ï Î¼ÎµÏάδοÏηÏ"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ÎÏιλογÎÏ ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "ÎÎÏÎ¿Ï ÏÏ
θμÏÏ Î¼ÎµÏάδοÏÎ·Ï (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "ÎÏίÏεδο ÏοιÏÏηÏÎ±Ï VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr ""
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr ""
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ΠαÏαμÎÏÏοι ID3:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr ""
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Î ÏÏÏθεÏε μÏνο εÏικÎÏα v1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Î ÏÏÏθεÏε μÏνο εÏικÎÏα v2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "ÎÏικεÌÏεÏ"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "ÎιαμÏÏÏÏÏη ÎÏδικοÏοιηÏή Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "ÎÏίÏεδο ÏοιÏÏηÏÎ±Ï (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "ÎÏοκÏδικοÏοιηÏÎ®Ï FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr ""
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1377,21 +1377,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "ÎÏοκÏδικοÏοιηÏÎ®Ï FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "Î ÏÏÏθεÏο GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1403,530 +1407,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "ΣÏ
νÏομεÏÏÎµÎ¹Ï GNOME"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "ΤίÏλοÏ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "ÎαλλιÏÎÏνηÏ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "ÎÏοÏ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "ÎλμÏοÏ
μ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "ÎομμάÏι"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "ÎίδοÏ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "ÎÎÏη οÏ
ÏάÏ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "ÎιάÏκεια"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "ÎιαδÏομή αÏÏείοÏ
"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Îνομα αÏÏείοÏ
"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Î ÏοÏαÏμοÏμÎÎ½Î¿Ï ÏίÏλοÏ"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ΡÏ
θμÏÏ Î¼ÎµÏάδοÏÎ·Ï (bitrate)"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "ÎÏγαλÎιο ÎναζήÏηÏηÏ"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr ""
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr ""
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr ""
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr ""
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "ÎÏενεÏγοÏοίηÏη"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "ÎÏγαλÎιο ÎναζήÏηÏηÏ"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Îνοιγμα ÎÏÏείÏν..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Îνοιγμα _URL..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_Î ÏοÏθήκη ÎÏÏείÏν..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Î ÏοÏθήκη U_RL..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "Σ_ÏεÏικά ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_ÎξοδοÏ"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_ÎναÏαÏαγÏγή"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "ΠαÏÏ_η"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_ÎιακοÏή"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "Î Ïο_ηγοÏμενο"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_ÎÏÏμενο"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_ÎÏανάληÏη"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "Î_νακάÏεμα"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr ""
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr ""
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr ""
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr ""
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "ÎαÏά _ΤίÏλο"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "ÎαÏά ÎÏιθμÏ_ÎομμαÏιοÏ:"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "ÎαÏά _ÎαλλιÏÎÏνη"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "ÎαÏά ÎμεÏομηνία_ÎκδοÏηÏ"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "ÎαÏά _ÎιαδÏομή ÎÏÏείοÏ
"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "ÎαÏά _Î ÏοÏαÏμοÏμÎνο ΤίÏλο"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Î_νÏίÏÏÏοÏη ΣειÏά"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_ΤÏ
Ïαία ΣειÏά"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_ÎνανÎÏÏη"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_ΤαξινÏμηÏη"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
-msgstr ""
+msgstr "ÎÏαίÏεÏη ÎιÏλÏν"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr ""
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_ÎÎο"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "ÎεÏ_ονομαÏία ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_ÎιÏαγÏγή..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_ÎξαγÏγή..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "ÎιαÏειÏιÏÏÎ®Ï ÎιÏÏÏν _ÎναÏαÏαγÏÎ³Î®Ï ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_ÎιαÏειÏιÏÏÎ®Ï ÎÏ
ÏÎ¬Ï ÎÎ½Î±Î¼Î¿Î½Î®Ï ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "ÎÏξηÏη_ÎνÏαÏηÏ"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "ÎείÏÏη_ÎνÏαÏηÏ"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_ÎÏοÏÏαθμιÏÏήÏ"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "ÎμÏάνιÏη _ÎÏÎ±Î¼Î¼Î®Ï ÎενοÏ"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "ÎμÏάνιÏη Î _λαιÏίοÏ
ΠληÏοÏοÏιÏν"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "ÎμÏάνιÏη ÎÏεικÏνιÏÎ·Ï Î Î»Î±Î¹ÏίοÏ
Πλη_ÏοÏοÏιÏν"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "ÎμÏάνιÏη _ÎÏÎ±Î¼Î¼Î®Ï ÎαÏάÏÏαÏηÏ"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_ÎÏÏείο"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_ÎναÏαÏαγÏγή"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr ""
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Î¥ÏηÏεÏίεÏ"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_ÎξοδοÏ"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Î Ïοβολή"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_ÎιÏαγÏγή/ÎÏαίÏεÏη ÏÏην/αÏÏ Ïην ÎÏ
Ïά"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "ÎÏοκο_Ïή"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_ÎνÏιγÏαÏή"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_ÎÏικÏλληÏη"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "ÎÏιλογή _ÎλÏν"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_ÎεÏονομαÏία..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>ÎιάÏοÏα</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "ÎιεÏαÏή GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ÎÎμιÏμα ενδιάμεÏÎ·Ï Î¼Î½Î®Î¼Î·Ï..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "μονοÏÏνικÏ"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "ÏÏεÏεοÏÏνικÏ"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d κανάλι"
msgstr[1] "%d κανάλια"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kb/s"
-#: src/hotkey/gui.c:70
-msgid "Previous track"
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
msgstr ""
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "ÎειÏοÏ
Ïγία λίÏÏÎ±Ï Î±Î½Î±ÏαÏαγÏγήÏ."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "ÎιακοÏή ÏÏο ÏÎλοÏ
Ï ÏοÏ
κομμαÏιοÏ."
+
+#: src/hotkey/gui.cc:71
+msgid "Previous track"
+msgstr "Î ÏοηγοÏμενο ÎομμάÏι"
+
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "ÎναÏαÏαγÏγή"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "ΠαÏÏη/ΣÏ
νÎÏεια"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "ÎιακοÏή"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
-msgstr ""
+msgstr "ÎÏÏμενο ÎομμάÏι"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "ÎÏÏοÏÏά 5 δεÏ
ÏεÏÏλεÏÏα"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "ΠίÏÏ 5 δεÏ
ÏεÏÏλεÏÏα"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "ΣίγαÏη"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "ÎÏξηÏη ÎνÏαÏηÏ"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "ÎείÏÏη ÎνÏαÏηÏ"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "ÎεÏαÏήδηÏη ÏÏο αÏÏείο"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr ""
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(κανÎνα)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1934,37 +2015,37 @@ msgid ""
"Do you want to continue?"
msgstr ""
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr ""
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr ""
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
msgstr ""
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "ΣÏ
νÏομεÏÏειÏ:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>ÎνÎÏγεια:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr ""
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
+msgstr "_Î ÏοÏθήκη"
+
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1979,124 +2060,90 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "ÎÎ¾Î¿Î´Î¿Ï JACK"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "ÎÎ¾Î¿Î´Î¿Ï JACK"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "ΡÏ
θμίÏÎµÎ¹Ï %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr ""
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr ""
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
"After adding new paths, press Enter to scan for new plugins.</small>"
msgstr ""
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "ÎιαθÎÏιμα ÏÏÏÏθεÏα:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "ÎνεÏγοÏοίηÏη"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "ÎνεÏγοÏοιημÎνα ÏÏÏÏθεÏα:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "ΡÏ
θμίÏειÏ"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr ""
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr ""
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: ÏÏοÏÏαθεί να εÏαναÏÏ
νδεθεί...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: άγνÏÏÏη ενÏολή «%s»\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: αÏοÏÏνδεÏη αÏÏ LIRC\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: θα ÏÏοÏÏαθήÏει να εÏαναÏÏ
νδεθεί κάθε %d δεÏ
ÏεÏÏλεÏÏα...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Î ÏÏÏθεÏο LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2112,73 +2159,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>ΣÏνδεÏη</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "ÎÏαναÏÏνδεÏη με εξÏ
ÏηÏεÏηÏή LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr ""
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Î ÏÏÏθεÏο LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "Î ÏÏÏθεÏο LyricsWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "ΣÏάλμα"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "ΣÏάλμα"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "ÎναζήÏηÏη για ÏÏοίÏοÏ
Ï ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "ΣÏνδεÏη με lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "Î ÏÏÏθεÏο LyricsWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "ÎίÏÏÎµÏ ÎναÏαÏαγÏÎ³Î®Ï M3U"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr ""
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr ""
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr ""
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2187,162 +2242,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr ""
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "ÎείκÏÎ·Ï ÎαναλιÏν"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>ÎείκÏÎ·Ï ÎαναλιÏν:</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Îανάλια εξÏδοÏ
:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "ÎείκÏÎ·Ï ÎαναλιÏν"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "Î ÏÏÏθεÏο MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Îανάλια</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "ÎÏίÏεδο:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>ÎνÏίÏηÏη</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>ΠεÏιÏεÏειακÏ</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "ÎείÏÏη θοÏÏβοÏ
"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "ÎναÏαÏαγÏγή MOD ÏοÏ
Amiga"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>ÎÏανάληÏη</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "ÎÎÏÏηÏη εÏαναλήÏεÏν:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
msgstr ""
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "ΠεÏιÏεÏειακÏ"
-
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "Î ÏÏÏθεÏο MPG123"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "ΠεÏιÏεÏειακÏ"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "ÎξÏ
ÏηÏεÏηÏÎ®Ï MPRIS 2"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Î ÏÏÏθεÏο Neon HTTP/HTTPS"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "ÎιακÏÏηκε"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Το Audacious δεν αναÏαÏάγει."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr ""
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2362,55 +2449,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "ÎμÏάνιÏη"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "ΠαÏÏη"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "ÎÏÏμενο"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Î ÏοεÏιλεγμÎνη ÏÏ
ÏκεÏ
ή"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "ÎÎ¾Î¿Î´Î¿Ï OSS4"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "ΣÏ
ÏκεÏ
ή ήÏοÏ
:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "ΧÏηÏιμοÏοίηÏε εναλλακÏική ÏÏ
ÏκεÏ
ή:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr ""
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr ""
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2419,19 +2515,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "ÎÎ¾Î¿Î´Î¿Ï OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "ÎίÏÏÎµÏ ÎναÏαÏαγÏÎ³Î®Ï PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "ÎÏοκÏδικοÏοιηÏÎ®Ï OpenPSF PSF1/PSF2"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "ÎÎ¾Î¿Î´Î¿Ï PulseAudio"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2451,143 +2563,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "ÎÎ¾Î¿Î´Î¿Ï PulseAudio"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
-#: src/resample/resample.c:165
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "ÎναζήÏηÏη"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Îνοιγμα αÏÏείÏν"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Î ÏοÏθήκη αÏÏείÏν"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Î ÏοηγοÏμενο"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "ÎÏανάληÏη"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "ÎνακάÏεμα"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr ""
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr ""
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>ÎεÏαÏÏοÏή</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "ÎÎθοδοÏ:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "ΡÏ
θμÏÏ:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr ""
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr ""
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "ÎÏνηÏη Î ÏÏÏβαÏηÏ"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr ""
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "ÎίνεÏαι ÎλεγÏοÏ..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2598,17 +2779,17 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "ÎÎ¾Î¿Î´Î¿Ï SDL"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2616,81 +2797,56 @@ msgstr ""
"Î ÏÏÏθεÏο ÎξÏδοÏ
SDL για Ïο Audacious\n"
"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "ÎÎ¾Î¿Î´Î¿Ï SDL"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Îιβλιοθήκη"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "ÎγνÏÏÏÎ¿Ï ÎαλλιÏÎÏνηÏ"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "ÎγνÏÏÏο ÎλμÏοÏ
μ"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" ÏÏο %s ÏοÏ
%s"
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d δίÏκοÏ"
-msgstr[1] "%d δίÏκοι"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-"%s\n"
-" %s, %d ÏÏαγοÏδι"
msgstr[1] ""
-"%s\n"
-" %s, %d ÏÏαγοÏδια"
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
-"%s\n"
-" %d ÏÏαγοÏδι αÏÏ %s"
msgstr[1] ""
-"%s\n"
-" %d ÏÏαγοÏδια αÏÏ %s"
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_ÎημιοÏ
Ïγία ÎίÏÏÎ±Ï ÎναÏαÏαγÏγήÏ"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Î ÏοÏθήκη ÏÏη ÎίÏÏα ÎναÏαÏαγÏγήÏ"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "ÎναζήÏηÏη βιοθήκηÏ"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2698,679 +2854,769 @@ msgstr ""
"Îια να ειÏάγεÏαι Ïη ÏÏ
λλογή μοÏ
ÏÎ¹ÎºÎ®Ï ÏÎ±Ï ÏÏο Audacious, διαλÎξÏε Îναν Ïάκελο "
"και κάνεÏε κλικ ÏÏο εικονίδιο «ανανÎÏÏη»."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "ΠαÏÎ±ÎºÎ±Î»Ï ÏεÏιμÎνεÏε ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "ÎÏιλογή ΦακÎλοÏ
"
-#: src/skins/menus.c:56
-msgid "Open Files ..."
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
msgstr ""
-#: src/skins/menus.c:57
-msgid "Open URL ..."
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
msgstr ""
-#: src/skins/menus.c:59
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
+msgid "Open Files ..."
+msgstr "Îνοιγμα AÏÏείÏν ..."
+
+#: src/skins/menus.cc:65
+msgid "Open URL ..."
+msgstr "Îνοιγμα διεÏθÏ
νÏÎ·Ï URL..."
+
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "ÎναζήÏηÏη ÎιβλιοθήκηÏ"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "ÎναÏαÏαγÏγή"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "ÎίÏÏα ÎναÏαÏαγÏγήÏ"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Î Ïοβολή"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
-msgstr ""
+msgstr "Î¥ÏηÏεÏίεÏ"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
-msgstr ""
+msgstr "ΡÏ
θμίÏÎµÎ¹Ï ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
-msgstr ""
+msgstr "ÎξοδοÏ"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
-msgstr ""
-
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "ÎÏανάληÏη"
+msgstr "ΠληÏοÏοÏÎ¯ÎµÏ ÏÏαγοÏ
διοÏ"
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "ÎνακάÏεμα"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr ""
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Î ÏοηγοÏμενο"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "ÎÎα ÎίÏÏα ÎναÏαÏαγÏγήÏ"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr ""
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr ""
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr ""
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
-msgid "Add URL ..."
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:138
+msgid "Add URL ..."
+msgstr "Î ÏοÏθήκη ÎιεÏθÏ
νÏÎ·Ï URL ..."
+
+#: src/skins/menus.cc:139
msgid "Add Files ..."
-msgstr ""
+msgstr "Î ÏοÏθήκη ÎÏÏείÏν..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "ÎαÏά ΤίÏλο"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "ÎαÏά Îνομα ÎÏÏείοÏ
"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "ÎÏαίÏεÏη ÎλÏν"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "ÎκκαθάÏιÏη ÎÏ
ÏάÏ"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "ÎÏαίÏεÏη Îη ÎιαθÎÏιμÏν ÎÏÏείÏν"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "ÎÏαίÏεÏη ÎιÏλÏν"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "ÎÏαίÏεÏη Îη ÎÏιλεγμÎνÏν"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "ÎÏαίÏεÏη ÎÏιλεγμÎνÏν"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "ÎναζήÏηÏη και ÎÏιλογή"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "ÎνÏιÏÏÏοÏή ÎÏιλογήÏ"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "ÎÏιλογή ÎανενÏÏ"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "ÎÏιλογή ÎλÏν"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "ÎαÏά ÎίÏκο"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "ÎαÏά ÎÏÎ¹Î¸Î¼Ï ÎομμαÏιοÏ:"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "ÎαÏά ÎαλλιÏÎÏνη"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "ÎαÏά ÎίÏκο"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "ÎαÏά ÎÏÎ¹Î¸Î¼Ï ÎομμαÏιοÏ:"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "ΤÏ
ÏαιοÏοίηÏη ÎίÏÏαÏ"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "ÎνÏίÏÏÏοÏη ÎίÏÏαÏ"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "ΤαξινÏμηÏη ÎÏιλεγμÎνÏν"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "ΤαξινÏμηÏη ÎίÏÏαÏ"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "ÎÏοκοÏή"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "ÎνÏιγÏαÏή"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "ÎÏικÏλληÏη"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "ÎλαÏÏική ÎιεÏαÏή Winamp"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "ÎÏοθήκεÏ
Ïη"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "ΦÏÏÏÏÏη"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Î ÏοÏÏ
θμίÏειÏ"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "ΦÏÏÏÏÏη ÏÏοÏÏθμιÏηÏ"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "ΦÏÏÏÏÏη αÏ
ÏÏμαÏÎ·Ï ÏÏοÏÏθμιÏηÏ"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "ÎÏοθήκεÏ
Ïη ÏÏοÏÏθμιÏηÏ"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "ÎÏοθήκεÏ
Ïη αÏ
ÏÏμαÏÎ·Ï ÏÏοÏÏθμιÏηÏ"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "ÎιαγÏαÏή ÏÏοÏÏθμιÏηÏ"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "ÎιαγÏαÏή αÏ
ÏÏμαÏÎ·Ï ÏÏοÏÏθμιÏηÏ"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_ÎναÏαÏαγÏγÎαÏ:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "ÎÏιλÎξÏε Ïη γÏαμμαÏοÏειÏά ÏοÏ
κÏÏιοÏ
ÏαÏαθÏÏοÏ
:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_ÎίÏÏα αναÏαÏαγÏγήÏ:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "ÎÏιλÎξÏε Ïη γÏαμμαÏοÏειÏά ÏÎ·Ï Î»Î¯ÏÏÎ±Ï Î±Î½Î±ÏαÏαγÏγήÏ:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr ""
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr ""
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "ÎναλÏ
ÏήÏ"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "ÎμβÎλεια"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "ÎακÏιά"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr ""
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr ""
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "ÎÏαμμÎÏ"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "ÎÏάÏεÏ"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "ÎÏγÏÏεÏο"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "ÎÏγÏ"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "ÎεÏαίο"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "ÎÏήγοÏο"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "ÎÏηγοÏÏÏεÏο"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr ""
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "ÎμαλÏ"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Îενικά"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "ÎÏÏικοÏοίηÏη"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Î ÏοενίÏÏÏ
Ïη"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "ÎÏοÏÏαθμιÏÎ®Ï Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr ""
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "ÎνÏαÏη: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "ÎÏοÏÏοÏία: %d%% αÏιÏÏεÏά"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "ÎÏοÏÏοÏία: κÎνÏÏο"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "ÎÏοÏÏοÏία: %d%% δεξιά"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "ÎÎµÎ½Î¿Ï ÎÏιλογÏν"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr ""
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr ""
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr ""
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr ""
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "ÎειÏοÏ
Ïγία λίÏÏÎ±Ï Î±Î½Î±ÏαÏαγÏγήÏ."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "ÎιακοÏή ÏÏο ÏÎλοÏ
Ï ÏοÏ
κομμαÏιοÏ."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr ""
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3378,57 +3624,61 @@ msgid ""
"for."
msgstr ""
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
msgstr "ΤίÏλοÏ: "
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr "ÎίÏκοÏ: "
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr "ÎαλλιÏÎÏνηÏ: "
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Îνομα αÏÏείοÏ
: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Îνομα ÎÏÏείοÏ
:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr ""
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr ""
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d αÏÏ %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr ""
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr ""
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr ""
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Î ÏÏÏθεÏο Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3450,77 +3700,69 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Î ÏÏÏθεÏο Sndfile"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Î ÏÏÏÎ¿Ï Î´ÎµÎ½ Ï
ÏοÏÏηÏίζεÏαι"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-#: src/sndio/sndio.c:384
-msgid "sndio device"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "ÎνÏάξει"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Îλλαγή ΤÏαγοÏ
διοÏ"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "ÎνÏολή για εκÏÎλεÏη ÏÏαν Ïο Audacious αÏÏίζει νÎο ÏÏαγοÏδι."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "ÎνÏολή:"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "ÎνÏολή για εκÏÎλεÏη ÏληÏιάζÏνÏÎ±Ï Ïο ÏÎÎ»Î¿Ï ÎµÎ½ÏÏ ÏÏαγοÏ
διοÏ."
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
msgstr ""
-"ÎνÏολή για εκÏÎλεÏη ÏÏαν Ïο Audacious ÏÏάνει Ïο ÏÎÎ»Î¿Ï ÏÎ·Ï Î»Î¯ÏÏÎ±Ï "
-"αναÏαÏαγÏγήÏ."
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3535,17 +3777,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "ÎνÏολÎÏ"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3554,51 +3794,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr ""
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "ΤαÏÏÏηÏα και ΧÏοιά:"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>ΤαÏÏÏηÏα και ΧÏοιά</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "ΤαÏÏÏηÏα:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "ΧÏοιά:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "ΤαÏÏÏηÏα και ΧÏοιά:"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr ""
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3609,63 +3849,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr ""
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Îλλαγή ÎνÏαÏηÏ"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr ""
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>ÎÎ»Î»ÎµÏ Î¡Ï
θμίÏειÏ</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr ""
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr ""
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
msgstr ""
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr ""
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr ""
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "ÎεννήÏÏια ΤÏνÏν"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "ÎεννήÏÏια ΤÏνÏν: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3674,15 +3914,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "ÎεννήÏÏια ΤÏνÏν"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "ÎÏαίÏεÏη ΦÏνήÏ"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3719,11 +3955,35 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "ÎÏοκÏδικοÏοιηÏÎ®Ï Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "ÎÏοκÏδικοÏοιηÏÎ®Ï VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -3733,19 +3993,19 @@ msgstr ""
"ÎαÏιÏμÎνο ÏÏο in_vtx.dll ÏοÏ
Roman Sherbakov <v_soft at microfor.ru>\n"
"Î ÏÏÏθεÏο για Ïο Audacious αÏÏ Ïον Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "ÎÏοκÏδικοÏοιηÏÎ®Ï VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "ÎÏοκÏδικοÏοιηÏÎ®Ï WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "με αÏÏλεια (Ï
βÏιδικÏÏ)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "με αÏÏλεια"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -3755,14 +4015,18 @@ msgstr ""
"\n"
"ÎεÏικÏÏ ÎºÏÎ´Î¹ÎºÎ±Ï ÎµÎ³Î³ÏάÏει αÏÏ Ïον Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "ÎÏοκÏδικοÏοιηÏÎ®Ï WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "ÎÏοκÏδικοÏοιηÏÎ®Ï 2SF"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "ÎιαμοιÏαζÏÎ¼ÎµÎ½ÎµÏ ÎίÏÏÎµÏ ÎναÏαÏαγÏÎ³Î®Ï Î§ÎL (XSPF)"
diff --git a/po/en_GB.po b/po/en_GB.po
index ada5134c7030..8a82d50c0ad2 100644
--- a/po/en_GB.po
+++ b/po/en_GB.po
@@ -6,11 +6,11 @@
# Andi Chandler <andi at gowling.com>, 2013
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: English (United Kingdom) (http://www.transifex.com/projects/p/"
"audacious/language/en_GB/)\n"
"Language: en_GB\n"
@@ -19,51 +19,35 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "surround"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
+#: src/aac-raw/aac.cc:18
+msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/aac-raw/aac.c:476
-msgid "AAC (Raw) Decoder"
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr ""
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr ""
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarm"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarm"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -86,7 +70,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -108,7 +92,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -122,360 +106,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "This is your wakeup call."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr ""
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Reminder"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Monday"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Tuesday"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Wednesday"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Thursday"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Friday"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Saturday"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Sunday"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Alarm Settings"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Time"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarm at (default):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Quiet after:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "hours"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minutes"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Choose the days for the alarm to come on"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Day"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Default"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Days"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Fading"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "seconds"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Volume"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Start at"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Final"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Current"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Additional Command"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "enable"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Playlist (optional)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr ""
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Options"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "What do these options mean?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Help"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr ""
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr ""
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Default PCM device"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Default mixer device"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM device:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Mixer device:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Mixer element:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Work around drain hangup"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr ""
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr ""
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - select SoundFont file"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "File name"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Size (bytes)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Name:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI Info </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Format:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Length (msec):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variable"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Time Div:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* no comments available in this MIDI file *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* no lyrics available in this MIDI file *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Close"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (invalid UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -486,152 +476,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr ""
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Rectangle"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Rounded Rectangle"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Concave Rectangle"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "None"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Playback Start"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Triggers OSD when a playlist entry is played."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Title Change"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in Internet "
-"streams."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Pause On"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Triggers OSD when playback is paused."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Pause Off"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Triggers OSD when playback is unpaused."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Placement"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Relative X offset:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Relative Y offset:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Max OSD width:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Multi-Monitor options"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Display OSD using:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "all monitors"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "monitor %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Timing (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Display:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Fade in:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Fade out:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Fonts"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Font %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Shadow"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Render Style"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Colours"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Colour %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Enable trigger"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Event"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Composite manager detected"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -641,112 +625,112 @@ msgstr ""
"unless you know that you have one running, please activate a composite "
"manager otherwise the OSD will not work properly"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Composite manager not required for fake transparency"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Transparency"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Fake transparency"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Real transparency (requires X Composite Ext.)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Composite extension not loaded"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Composite extension not available"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - configuration"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Position"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animation"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Text"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Decoration"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Trigger"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Misc"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr ""
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr ""
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr ""
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr ""
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
msgstr ""
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
msgstr ""
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
msgstr ""
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
msgstr ""
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr ""
+
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -758,169 +742,156 @@ msgid ""
"This was a Google Summer of Code 2007 project."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Use HTTP instead of CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Audio CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Drive is empty."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Unsupported disk type."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr ""
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Play CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Add CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr ""
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr ""
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Centre volume:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Dynamic range:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr ""
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -930,195 +901,220 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Bass:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Treble:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Default song length:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Enable audio resampling"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Resampling rate:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ignore length from SPC tags"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Increase reverb"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Game Console Music Decoder"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr ""
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr ""
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr ""
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr ""
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr ""
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr ""
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr ""
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Cancel"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr ""
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr ""
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr ""
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr ""
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr ""
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
+#: src/echo_plugin/echo.cc:39
+msgid "Echo"
msgstr ""
-#: src/echo_plugin/echo.c:122
-msgid "Echo"
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1128,55 +1124,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
msgstr ""
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Output file format:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Configure"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Save into original directory"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Save into custom directory"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Output file folder:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Pick a folder"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Get filename from:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "original file tags"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "original filename"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Do not strip file name extension"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Prepend track number to filename"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1194,165 +1190,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr ""
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Auto"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Joint Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 Configuration"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Algorithm Quality:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Output Sample rate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Bitrate / Compression ratio:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Bitrate (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Compression ratio:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Audio Mode:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Enforce strict ISO compliance"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Error protection"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Quality"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Enable VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Type:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR Options:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Minimum bitrate (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Maximum bitrate (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Strictly enforce minimum bitrate"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR Options:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Average bitrate (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR quality level:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Don't write Xing VBR header"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Mark as copyright"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Mark as original"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Force addition of version 2 tag"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Only add v1 tag"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Only add v2 tag"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Tags"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis Encoder Configuration"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Quality level (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr ""
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr ""
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1360,21 +1360,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr ""
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1386,530 +1390,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Entry number"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Title"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Artist"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Year"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Album"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Track"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr ""
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Queue position"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Length"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "File path"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "File name"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Custom title"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Bitrate"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr ""
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Dock at Left"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Dock at Right"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Dock at Top"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Dock at Bottom"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Undock"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Disable"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr ""
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Open Files ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Open _URL ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr ""
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Add U_RL ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "A_bout ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Quit"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Play"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Paus_e"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Stop"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "Pre_vious"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_Next"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Repeat"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "S_huffle"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "N_o Playlist Advance"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "Song _Info ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Jump to _Time ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "_Jump to Song ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "By _Title"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "By Track _Number"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "By _Artist"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "By Release _Date"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "By _File Path"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "By _Custom Title"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "R_everse Order"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_Random Order"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Refresh"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Sort"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr ""
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_New"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr ""
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Import ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Export ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr ""
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_Queue Manager ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Volume _Up"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "Volume _Down"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Equaliser"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Show _Menu Bar"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Show I_nfo Bar"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr ""
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Show _Status Bar"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_File"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Playback"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "P_laylist"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Services"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Output"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_View"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Queue/Unqueue"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Cu_t"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Copy"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Paste"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Select _All"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr ""
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK Interface"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr ""
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
-#, c-format
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
+#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] ""
msgstr[1] ""
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Single mode."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Playlist mode."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Stopping after song."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr ""
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Play"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pause/Resume"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Stop"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr ""
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Mute"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr ""
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr ""
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr ""
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Show On-Screen-Display"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(none)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1921,15 +2002,11 @@ msgstr ""
"\n"
"Do you want to continue?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Binding mouse buttons"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Global Hotkey Plugin Configuration"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -1937,23 +2014,27 @@ msgstr ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Hotkeys:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Action:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Key Binding:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr ""
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1968,56 +2049,51 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
msgstr ""
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
-msgstr ""
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s Settings"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA Host Settings"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Module paths:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2027,68 +2103,39 @@ msgstr ""
"These paths are searched in addition to LADSPA_PATH.\n"
"After adding new paths, press Enter to scan for new plugins.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Available plugins:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Enable"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Enabled plugins:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Settings"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr ""
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr ""
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr ""
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr ""
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr ""
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
msgstr ""
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2104,73 +2151,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr ""
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr ""
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr ""
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Error"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Error"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr ""
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr ""
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Tact generator: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Tact generator: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2179,162 +2234,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
msgstr ""
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr ""
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Output channels:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
+#: src/mms/mms.cc:35
+msgid "MMS Plugin"
msgstr ""
-#: src/mms/mms.c:195
-msgid "MMS Plugin"
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
msgstr ""
-#: src/modplug/plugin_main.c:55
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr ""
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr ""
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr ""
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr ""
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr ""
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr ""
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
msgstr ""
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Surround"
-
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr ""
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr ""
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr ""
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Stopped"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious is not playing."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr ""
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2354,55 +2441,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr ""
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr ""
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr ""
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Default device"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Audio device:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Use alternate device:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr ""
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Enable format conversions made by the OSS software."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2411,19 +2507,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
msgstr ""
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr ""
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr ""
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr ""
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2443,143 +2555,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
msgstr ""
-#: src/resample/resample.c:165
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr ""
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Repeat"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Shuffle"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr ""
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr ""
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr ""
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Method:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr ""
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr ""
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr ""
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr ""
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr ""
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr ""
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr ""
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr ""
-#: src/resample/resample.c:204
-msgid "192 kHz:"
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
msgstr ""
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
+#: src/resample/resample.cc:241
+msgid "192 kHz:"
msgstr ""
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr ""
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr ""
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2590,765 +2771,840 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr ""
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr ""
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr ""
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr ""
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr ""
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
+msgid "%d result"
+msgid_plural "%d results"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr ""
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr ""
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr ""
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr ""
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr ""
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Playback"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr ""
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr ""
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Repeat"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Shuffle"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "No Playlist Advance"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr ""
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr ""
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Show Playlist Editor"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Show Equaliser"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr ""
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr ""
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr ""
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr ""
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr ""
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr ""
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr ""
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr ""
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr ""
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr ""
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr ""
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr ""
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
msgstr ""
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr ""
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr ""
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr ""
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr ""
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr ""
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr ""
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr ""
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr ""
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr ""
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr ""
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr ""
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr ""
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Presets"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr ""
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr ""
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr ""
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr ""
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr ""
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr ""
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Player:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Select main player window font:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Playlist:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Select playlist font:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Use bitmap fonts (supports ASCII only)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Scroll song title in both directions"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr ""
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr ""
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr ""
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr ""
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr ""
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr ""
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr ""
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr ""
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr ""
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr ""
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr ""
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr ""
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr ""
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr ""
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "General"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr ""
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Preamp"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious Equaliser"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Seek to %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Volume: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balance: %d%% left"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balance: centre"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balance: %d%% right"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Options Menu"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Disable 'Always On Top'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Enable 'Always On Top'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "File Info Box"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Single mode."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Playlist mode."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Stopping after song."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr ""
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3356,57 +3612,61 @@ msgid ""
"for."
msgstr ""
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr ""
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr ""
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr ""
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr ""
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr ""
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr ""
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr ""
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3428,75 +3688,69 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
msgstr ""
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
msgstr ""
-#: src/sndio/sndio.c:384
-msgid "sndio device"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
-
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr ""
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3511,17 +3765,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-#: src/song_change/song_change.c:490
-msgid "Commands"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3530,51 +3782,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
msgstr ""
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3585,63 +3837,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr ""
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr ""
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr ""
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr ""
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr ""
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr ""
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
msgstr ""
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr ""
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
msgstr ""
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr ""
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr ""
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3650,15 +3902,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr ""
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr ""
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3679,44 +3927,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr ""
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr ""
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
msgstr ""
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr ""
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr ""
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
+#: src/xsf/plugin.cc:50
+msgid "2SF Decoder"
msgstr ""
-#: src/xsf/plugin.c:217
-msgid "2SF Decoder"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
msgstr ""
-#: src/xspf/xspf.c:438
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr ""
diff --git a/po/es.po b/po/es.po
index 5c30a9d21a27..d2b30fca2661 100644
--- a/po/es.po
+++ b/po/es.po
@@ -3,24 +3,32 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# Adolfo Jayme Barrientos <fitoschido at ubuntu.com>, 2013
+# Adolfo Jaymeâ¯Barrientos, 2013
+# Adolfo Jaymeâ¯Barrientos <fito at libreoffice.org>, 2013-2014
+# Adolfo Jaymeâ¯Barrientos, 2013
+# Adolfo Jaymeâ¯Barrientos, 2015
# Adrián Ramirez Escalante <buried.prophet at gmail.com>, 2012
# Cosme DomÃnguez DÃaz <cosme.ddiaz at gmail.com>, 2010
-# frangor <frangor at frangor.info>, 2013
-# Excelente <dny1020 at aol.com>, 2013
+# enjolras <yo at miguelrevilla.com>, 2012
+# Francesc Gordillo i CortÃnez <inactive+frangor at transifex.com>, 2013
+# Francesc Gordillo i CortÃnez <inactive+frangor at transifex.com>, 2013
+# Jack R. <dny1020 at aol.com>, 2013
# Jorge Andrés <winninglero at gmail.com>, 2011
+# Juan Riquelme González <soulchainer at gmail.com>, 2015
# LucÃa Balsa <lucia.balsa.prados at gmail.com>, 2012
# Marco Antonio Frias Butrón <inactive+smaug at transifex.com>, 2012
+# Marco Antonio Frias Butrón <inactive+smaug at transifex.com>, 2012
# Matias Menich <und34d at gmail.com>, 2012
+# xukosky <xukosky at yahoo.es>, 2011-2012
# xukosky <xukosky at yahoo.es>, 2011, 2012
# enjolras <yo at miguelrevilla.com>, 2012
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-13 07:28+0000\n"
+"Last-Translator: Adolfo Jaymeâ¯Barrientos\n"
"Language-Team: Spanish (http://www.transifex.com/projects/p/audacious/"
"language/es/)\n"
"Language: es\n"
@@ -29,51 +37,38 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "estéreo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "envolvente"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
-msgstr ""
+msgstr "Descodificador ACC (sin procesar)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (Reproductor AdLib)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "secuenciado"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (Reproductor AdLib)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarma"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
-msgstr ""
+msgstr "Establecer alarmaâ¦"
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
+"Un complemento para iniciar la reproducción en un momento dado.\n"
+"\n"
+"Escrito originalmente por Adam Feakin y Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarma"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -95,8 +90,27 @@ msgid ""
"\n"
"\n"
msgstr ""
+"Tiempo\n"
+" Alarma a:\n"
+" Hora a la que saltará la alarma.\n"
+"\n"
+" Silencio tras:\n"
+" La alarma se detendrá una vez pasado este tiempo.\n"
+" (si no se cierra el diálogo de aviso)\n"
+"\n"
+"\n"
+"DÃas\n"
+" DÃa:\n"
+" Selecciona los dÃas en los que saltará la alarma.\n"
+"\n"
+" Tiempo:\n"
+" Escoge cuando sonará la alarma cada dÃa,\n"
+" o marca «Predeterminado» para usar el\n"
+" tiempo por defecto.\n"
+"\n"
+"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -117,8 +131,27 @@ msgid ""
" Run this command at the alarm time.\n"
"\n"
msgstr ""
+"Volumen\n"
+" Transición:\n"
+" Tiempo que se invertirá en establecer,\n"
+" gradualmente, el volumen final indicado.\n"
+"\n"
+" Iniciar a:\n"
+" Inicia la transición desde este volumen.\n"
+"\n"
+" Final:\n"
+" Alcanzado este volumen, se detendrá la\n"
+" transición. Si el tiempo para la transición es 0,\n"
+" se establecerá este volumen y se iniciará la\n"
+" reproducción directamente.\n"
+"\n"
+"\n"
+"Opciones:\n"
+" Comando adicional:\n"
+" Ejecuta este comando cuando salte la alarma.\n"
+"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -131,361 +164,402 @@ msgid ""
" Type the reminder in the box and turn on the\n"
" toggle button if you want it to be shown."
msgstr ""
+" Lista de reproducción:\n"
+" Carga la lista de reproducción dada.\n"
+" Si no se da ninguna, se usará la lista actual.\n"
+" También puede indicarse aquà el URL de un\n"
+" flujo de audio mp3/ogg.\n"
+"\n"
+" Recordatorio:\n"
+" Muestra un aviso cuando suena la alarma.\n"
+" Escriba el recordatorio en el campo de texto y\n"
+" marque «activar» si quiere que se muestre."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
-msgstr "Esta es su llamada para despertar."
+msgstr "Este es el aviso de su alarma."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
-msgstr ""
+msgstr "Tu recordatorio para hoy es..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Recordatorio"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Lunes"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Martes"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Miércoles"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Jueves"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Viernes"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Sábado"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Domingo"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Ajustes de Alarma"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Tiempo"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarma a (predeterminado):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Silencio tras:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "horas"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minutos"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Seleccione los dÃas para que salte la alarma"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "DÃa"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Predeterminado"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "DÃas"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
-msgstr "Desvanecimiento"
+msgstr "Transición"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "segundos"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Volumen"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Iniciar a"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Final"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Actual"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Comando adicional"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "activar"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Lista de reproducción (opcional)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Seleccione una lista de reproducción"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Opciones"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "¿Qué significan estas opciones?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Ayuda"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
-msgstr "Carátula del Ãlbum"
+msgstr "Carátula del álbum"
+
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Carátula del álbum (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "Salida ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"Complemento «Salida ALSA» para Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"Quiero expresar mi agradecimiento a William Pitcock, autor del complemento "
+"«Salida ALSA NG», cuyo código me sirvió de referencia en esos momentos en "
+"los que el manual de ALSA no era suficiente."
-#: src/alsa/config.c:210
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(sin descripción)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Dispositivo PCM predeterminado"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Dispositivo mezclador predeterminado"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "Dispositivo PCM:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Dispositivo mezclador:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Elemento mezclador:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Evitar los cuelgues por falta de recursos"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (reproductor MIDI)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "Salida ALSA"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
+"AMIDI-Plug\n"
+"reproductor de música MIDI\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
+"\n"
+"escrito por Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"agradecimientos especiales...\n"
+"\n"
+"a Clemens Ladisch y Jaroslav Kysela\n"
+"por sus estupendos programas aplaymidi y amixer; \n"
+"me resultaron muy útiles, junto con la documentación\n"
+"de alsa-lib, para comprender mejor la API de ALSA\n"
+"\n"
+"a Alfredo Spadafina\n"
+"por ese logo tan bonito de un teclado midi\n"
+"\n"
+"a Tony Vroon\n"
+"por su inestimable ayuda probando la alfa"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
-msgstr ""
+msgstr "Ignorar ganancia predeterminada:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
-msgstr ""
+msgstr "Ignorar polifonÃa predeterminada:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
-msgstr ""
+msgstr "Ignorar reverberación predeterminada:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
-msgstr ""
+msgstr "Activado"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
-msgstr ""
+msgstr "Ignorar coro predeterminado:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
-msgstr ""
+msgstr "<b>Reproducción</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
-msgstr ""
+msgstr "Transponer:"
+
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "semitonos"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
-msgstr ""
+msgstr "Cambio de baterÃa:"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "números de nota"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Omitir silencio del principio"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Omitir silencio del final"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
-msgstr ""
+msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
-msgstr ""
-
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr ""
+msgstr "<b>Sintetizador</b>"
+
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "Frecuencia de muestreo:"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "Complemento AMIDI - seleccione un archivo SoundFont"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Cancelar"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
-msgstr ""
+msgstr "_Abrir"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Nombre del archivo"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Tamaño (bytes)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nombre:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> Información MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Formato:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Longitud (mseg):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
-msgstr "Num. de Pistas:"
+msgstr "Núm. de pistas:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variable"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Div tiempo:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> Comentarios y letras MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* no hay comentarios disponibles en este archivo MIDI *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* no hay letras disponibles en este archivo MIDI *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Cerrar"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (UTF-8 no válido)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Acerca del AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -495,269 +569,272 @@ msgid ""
"Based in part on Evan Martin's Ghosd library:\n"
"http://neugierig.org/software/ghosd/"
msgstr ""
+"Audacious OSD (información en pantalla)\n"
+"http://www.develia.org/projects.php?p=audacious#aosd\n"
+"\n"
+"Escrito por Giacomo Lozito <james at develia.org>\n"
+"\n"
+"Basado parcialmente en la librerÃa ghosd de Evan Martin:\n"
+"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (información en pantalla)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Rectángulo"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Rectángulo redondeado"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Rectángulo cóncavo"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Ninguno"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
-msgstr "Reproducción iniciada"
+msgstr "Inicio de reproducción"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Avisa cuando se reproduce un elemento de la lista de reproducción."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Cambio de tÃtulo"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Avisa cuando, durante la reproducción, el tÃtulo de la canción cambia pero "
-"el nombre de archivo es el mismo. Esto es principalmente útil para mostrar "
-"cambios de tÃtulo en los flujos de Internet."
+"Avisa cuando el tÃtulo de la canción cambia (para flujos de audio de "
+"Internet)."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
-msgstr "Inicio de pausa"
+msgstr "Pausa"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
-msgstr "Avisa cuando la reproducción es pausada."
+msgstr "Avisa cuando se pausa la reproducción."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
-msgstr "Fin de pausa"
+msgstr "Fin de la pausa"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
-msgstr "Avisa cuando la reproducción se reanuda."
+msgstr "Avisa cuando se reanuda la reproducción."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
-msgstr "Colocación"
+msgstr "Ubicación"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
-msgstr "Desplazamiento X relativo:"
+msgstr "Desplazamiento horizontal relativo:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
-msgstr "Desplazamiento Y relativo:"
+msgstr "Desplazamiento vertical relativo:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
-msgstr "Ancho máximo:"
+msgstr "Anchura máxima:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
-msgstr "Opciones multi-monitor"
+msgstr "Opciones multimonitor"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Mostrar notificaciones utilizando:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "todos los monitores"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "monitor %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
-msgstr "Temporización (ms)"
+msgstr "Tiempo (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Mostrar:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
-msgstr "Desvanecimiento de entrada:"
+msgstr "Aparición suave:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
-msgstr "Desvanecimiento de salida:"
+msgstr "Desvanecimiento suave:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "TipografÃas"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "TipografÃa %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Sombra"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Estilo de renderizado"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Colores"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Color %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Activar disparador"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Evento"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
-msgstr "Administrador de composición detectado"
+msgstr "Gestor de composición detectado"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
"manager otherwise the OSD won't work properly"
msgstr ""
-"Administrador de composición no detectado;\n"
-"a menos que sepa que tiene uno ejecutándose, por favor active un "
-"administrador de composición o las notificaciones no funcionarán "
-"correctamente"
+"Gestor de composición no detectado;\n"
+"por favor, a no ser que esté seguro de que ya hay uno ejecutándose, active "
+"un gestor de composición, o las notificaciones no funcionarán correctamente"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
-msgstr "Administrador de composición no necesario para transparencia falsa"
+msgstr ""
+"No se necesita un gestor de composición para producir seudotransparencias"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Transparencia"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
-msgstr "Transparencia falsa"
+msgstr "Seudotransparencia"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
-msgstr "Transparencia real (requiere composición 3D)"
+msgstr "Transparencia (requiere extensión de composición)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Extensión de composición no cargada"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Extensión de composición no disponible"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Notificaciones de Audacious</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Notificaciones de Audacious - configuración"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Posición"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animación"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Texto"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Decoración"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Disparador"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Varios"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Probar"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
-msgstr ""
+msgstr "Listas de reproducción ASXv3"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "Listas de reproducción ASXv1/ASXv2"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Listas de reproducción de Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Color</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Borroso"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Conversor Bauer de estéreo a binaural(BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Preajustes:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Nivel de alimentación:"
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
-msgstr "Cortar frecuencia:"
-
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Predefinidos:"
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr ""
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr "Frecuencia de corte:"
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Analizador de espectro"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Complemento de Audio CD"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -768,170 +845,168 @@ msgid ""
"\n"
"This was a Google Summer of Code 2007 project."
msgstr ""
+"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> y otros.\n"
+"\n"
+"Muchas gracias a los desarrolladores de libcdio <http://www.gnu.org/software/"
+"libcdio/>\n"
+"y libcddb <http://libcddb.sourceforge.net/>.\n"
+"\n"
+"También quiero dar las gracias a Tony Vroon por ser mi mentor y mi guÃa.\n"
+"\n"
+"Este fue un proyecto del «Google Summer of Code» de 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Dispositivo</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Velocidad de lectura:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Reemplazar dispositivo:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadatos</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Utilizar CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Usar CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Usar HTTP en lugar de CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Servidor"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Dirección:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Puerto:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Plugin de Audio CD"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
-msgstr ""
+msgstr "No se pudo iniciar el subsistema cdio."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
-msgstr ""
+msgstr "URI %s no válido."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Pista %d no encontrada."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "No se puede abrir la salida de audio."
+msgstr "La pista %d es una pista de datos."
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Error al leer el CD de audio."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
-msgstr "CD de música"
+msgstr "CD de audio"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
-msgstr ""
+msgstr "No se pudo abrir el dispositivo de CD %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
-msgstr ""
+msgstr "No se encontró ningún lector compatible con CDs de audio."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
-msgstr ""
+msgstr "Ocurrió un error tratando de iniciar el lector de CDs."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
-msgstr ""
+msgstr "No se pudo recuperar el número de la primera/última pista."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
-msgstr ""
+msgstr "No se puede leer el LSN de inicio/fin de la pista %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
-msgstr ""
+msgstr "Error de establecimiento de conexión con el servidor CDDB."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
-msgstr ""
+msgstr "Error de consulta al servidor CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
-msgstr ""
+msgstr "Error de consulta al servidor CDDB: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
-msgstr ""
+msgstr "Error de lectura de información de la CDDB: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "La unidad está vacÃa."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Tipo de disco no soportado."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Ãtems de menú de CD de audio"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Reproducir CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Añadir CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Elementos del Menú de audio CD"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Compresión</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Centrar volumen:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Rango dinámico:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
+"Complemento «Compresor de rango dinámico» para Audacious\n"
+"Copyright 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Compresor de rango dinámico"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -940,200 +1015,246 @@ msgid ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
msgstr ""
+"Descodificador de música de videoconsola basado en Game_Music_Emu 0.5.2\n"
+"Formatos soportados: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
+"\n"
+"Complemento para Audacious escrito por:\n"
+"William Pitcock <nenolod at dereferenced.org>\n"
+"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Graves:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Agudos:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
-msgstr ""
+msgstr "Eco:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
-msgstr "Longitud de canción predeterminada:"
+msgstr "Duración predeterminada de canción:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
-msgstr ""
+msgstr "<b>Remuestreo</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Activar el remuestreo de sonido"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Tasa de remuestreo:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
-msgstr ""
+msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ignorar longitud de etiquetas SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Aumentar la reverberación"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
-msgstr "Decodificador musical de videoconsola"
+msgstr "Descodificador de música de videoconsola"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "Salida Core Audio"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
+"Complemento «Salida Core Audio» para Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Basado en el complemento «Salida SDL» para Audacious\n"
+"Copyright 2010 John Lindgren"
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "Usar modo exclusivo"
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
+"Complemento «Fundido de audio» para Audacious\n"
+"Copyright 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
-msgstr ""
+msgstr "<b>Fundido de audio</b>"
+
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "En cambio de pista automático"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
+msgstr "Solapar:"
+
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "En búsqueda o cambio de pista manual"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Consejo</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
msgstr ""
+"Para obtener mejores resultados, active\n"
+"el efecto «Eliminación de silencios»."
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
+msgstr "Fundido de audio"
+
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
msgstr ""
+"Fundido de audio fallido: las pistas no tienen el mismo número de canales. "
+"Puede usar el «Mezclador de canales» para igualar el número de canales de "
+"las pistas."
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"Fundido de audio fallido: las pistas tienen distintas frecuencias de "
+"muestreo. Puede usar el «Convertidor de frecuencia de muestreo» para igualar "
+"la frecuencia de muestreo de las pistas."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Cristalizador</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intensidad:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
-msgstr ""
+msgstr "Cristalizador"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
-msgstr ""
+msgstr "Complemento «Hojas cue»"
+
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Borrar archivos"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
-msgstr ""
+msgstr "Error moviendo %s a la papelera: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
-msgstr ""
+msgstr "Error borrando %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
-msgstr ""
+msgstr "Error borrando %s: no es un archivo local."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
-msgstr ""
+msgstr "¿Quiere mover los archivos seleccionados a la papelera?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
-msgstr ""
+msgstr "Mover a la papelera"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
-msgstr ""
+msgstr "¿Quiere borrar de forma permanente los archivos seleccionados?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Borrar"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Cancelar"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
-msgstr ""
+msgstr "Borrar archivos seleccionados"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
-msgstr ""
+msgstr "<b>Método de borrado</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
+msgstr "Mover a la papelera en vez de borrar inmediatamente"
+
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
msgstr ""
+"Complemento «Eco»\n"
+"Creado por Johan Levin, 1999\n"
+"«Eco envolvente» escrito por Carl van Schaik, 1999\n"
+"Actualizado para Audacious por William Pitcock y John Lindgren, 2010-2014"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Eco</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Retraso:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Retorno:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Volumen:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Complemento de Ecoâ\n"
-"Por Johan Levin, 1999â\n"
-"â\n"
-"Eco envolvente por Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Eco"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Complemento de FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1142,56 +1263,62 @@ msgid ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
+"Complemento descodificador de múltiples formatos de audio,\n"
+"usando el framework multimedia FFmpeg (http://www.ffmpeg.org/)\n"
+"\n"
+"Complemento para Audacious creado por:\n"
+"William Pitcock <nenolod at nenolod.net>\n"
+"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "Complemento de FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Escribir archivo"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Formato del archivo de salida:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Configurar"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Guardar dentro del directorio original"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Guardar dentro de directorio personalizado"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Carpeta de archivo de salida:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Elija una carpeta"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Obtener nombre de archivo desde:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Generar nombre a partir de:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "etiquetas del archivo original"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Etiqueta del archivo original"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "nombre del archivo original"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Nombre del archivo original"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "No quitar la extensión del archivo"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "Incluir la extensión del archivo original"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Anteponer el número de pista al nombre de archivo"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr "Anteponer el nº de pista al nombre del archivo"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1208,202 +1335,218 @@ msgid ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
msgstr ""
-"Este programa es software gratis, puede redistribuirlo y/o modificarlo â\n"
-"bajo los términos de la Licencia Pública General GNU publicada por â\n"
-"the Free Software Foundation; sea versión 2 de la Licencia, o â\n"
-"(a su elección) cualquier versión posterior. â\n"
-"â\n"
-"Este programa se distribuye con la esperanza de que sea útil, â\n"
-"pero SIN NINGUNA GARANTÃA; incluso sin la garantÃa implÃcita de â\n"
-"COMERCIALIZACIÃN o IDONEIDAD PARA UN PROPÃSITO PARTICULAR. Consulte la â\n"
-"GNU General Public License para más detalles. â\n"
-"â\n"
-"DeberÃa haber recibido una copia de GNU General Public License â\n"
-"junto con este programa, y si no, escriba a Free Software â\n"
-"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,â\n"
+"Este programa es software libre: usted puede redistribuirlo y/o modificarlo\n"
+"bajo los términos de la Licencia Pública General GNU, publicada por\n"
+"la «Free Software Foundation» (Fundación para el software libre), ya\n"
+"sea la versión 2 de la Licencia, o (a su elección) cualquier versión "
+"posterior. \n"
+"\n"
+"Este programa se distribuye con la esperanza de que sea útil,\n"
+"pero SIN GARANTÃA ALGUNA; ni siquiera la garantÃa implÃcita de\n"
+"COMERCIALIZACIÃN o IDONEIDAD PARA UN PROPÃSITO DETERMINADO. Consulte los\n"
+"detalles de la Licencia Pública General GNU para obtener una información más "
+"detallada.\n"
+"\n"
+"DeberÃa haber recibido una copia de la Licencia Pública General GNU\n"
+"junto a este programa. En caso contrario, escriba a Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr ""
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Auto"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Estéreo conjunto"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
-msgstr "Estereo"
+msgstr "Estéreo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Configuración MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_Aceptar"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Calidad del algoritmo:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Frecuencia de muestreo de salida:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr "Frecuencia de muestreo:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Tasa de bits / Compresión:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "Tasa de bits / Relación de compresión"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Tasa de bits (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
-msgstr "Compresión:"
+msgstr "Ãndice de compresión:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
-msgstr "Modo de sonido:"
+msgstr "Modo de audio:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Varios:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr "Miscelánea:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Cumplir estrictamente la norma ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr "Forzar conformidad con normas ISO"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Error de protección"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Calidad"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Activar VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tipo:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Opciones VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Tasa de bits mÃnima (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Tasa de bits máxima (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
-msgstr "Aplicar estrictamente la tasa de bits mÃnima"
+msgstr "Aplicación estricta de la tasa de bits mÃnima"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Opciones ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
-msgstr "Tasa de bits promedio (kbps):"
+msgstr "Tasa media de bits (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "Nivel de calidad VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "No escribir la cabecera VBR Xing"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Omitir cabecera VBR Xing"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "Parametros de Marco:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr "Parámetros de trama:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
-msgstr "Marcar como derechos de autor"
+msgstr "Protegido por derechos de autor"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
-msgstr "Marcar como original"
+msgstr "Original"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "Parametros ID3:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr "Parámetros ID3"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
-msgstr "Forzar adición de etiqueta de la versión 2"
+msgstr "Forzar uso de etiquetas de la versión 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
-msgstr "Solo agregar etiqueta v1"
+msgstr "Solo usar ID3v1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
-msgstr "Solo agregar etiqueta v2"
+msgstr "Solo usar ID3v2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Etiquetas"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Configuración de codificador Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Nivel de calidad (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "Descodificador FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "sin pérdida"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
+"Código original escrito por\n"
+"Ralf Ertzinger <ralf at skytale.net>\n"
+"\n"
+"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "Decodificador FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
+"Complemento GIO para Audacious\n"
+"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
-msgstr "Plugin GIO"
+msgstr "Complemento GIO"
+
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "Modo leer-y-agregar no soportado"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "Modo de acceso a ficheros no válido"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1414,531 +1557,629 @@ msgid ""
"\n"
"License: GPLv2+"
msgstr ""
+"Analizador de espectro OpenGL para Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, y Carlo Bramini\n"
+"\n"
+"Basado en el complemento para XMMS:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, y "
+"4Front Technologies\n"
+"\n"
+"Licencia: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
+msgstr "Analizador de espectro OpenGL"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
+"Analizador de espectro OpenGL para Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, y Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Basado en el complemento para XMMS:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, y "
+"4Front Technologies\n"
+"\n"
+"Licencia: GPLv2+"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "Analizador de espectro OpenGL (Qt)"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "Atajos de teclado GNOME"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
+"Complemento «Atajos de teclado de GNOME»\n"
+"Le permite controlar el reproductor con atajos de GNOME.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Atajos de Gnome"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Número de entrada"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "TÃtulo"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Artista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Año"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
-msgstr "Album"
+msgstr "Ãlbum"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Artista del álbum"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Pista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Género"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Posición de la cola"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
-msgstr "Longitud"
+msgstr "Duración"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Ruta del archivo"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Nombre del archivo"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "TÃtulo personalizado"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Tasa de bits"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
-msgstr ""
+msgstr "Columnas disponibles"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
-msgstr ""
+msgstr "Columnas mostradas"
+
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Herramienta de búsqueda"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Acoplar a la izquierda"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Acoplar a la derecha"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Acoplar arriba"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Acoplar abajo"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Desacoplar"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Deshabilitar"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Herramienta de búsqueda"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Abrir archivos ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Abrir _URL ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
-msgstr "_Añadir archivos ..."
+msgstr "Aña_dir archivos ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Añadir U_RL ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
-msgstr ""
+msgstr "Explorar _biblioteca"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "A_cerca de ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
-msgstr ""
+msgstr "_Preferencias ..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Salir"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Reproducir"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
-msgstr "Pa_usar"
+msgstr "_Pausar"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Detener"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "An_terior"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
-msgstr "Si_guiente"
+msgstr "_Siguiente"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "R_epetir"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_Orden aleatorio"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "No avan_zar la lista de reproducción"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
-msgstr ""
+msgstr "Dete_ner después de esta canción"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Información de la canción ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
-msgstr "_Saltar en el tiempo ..."
+msgstr "Ir al _momento ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
-msgstr "Saltar a la _canción ..."
+msgstr "Ir a la _canción ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
-msgstr "Establecer Punto de Repetición _A"
+msgstr "Crear bucle (punto _A)"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
-msgstr "Establecer Punto de Repetición _B"
+msgstr "Crear bucle (punto _B)"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
-msgstr "_Borrar Punto de Repetición"
+msgstr "Borrar b_ucle"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Por _tÃtulo"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr ""
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "Por _nombre de archivo"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
-msgstr ""
+msgstr "Por _ruta de archivo"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Por _número de pista"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Por _artista"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
-msgstr ""
+msgstr "Por ál_bum"
+
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Por artista del álbu_m"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
-msgstr "Por _fecha de estreno"
+msgstr "Por _fecha de lanzamiento"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "Por _género"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
-msgstr "Por_Longitud"
+msgstr "Por _duración"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Por _ruta de archivo"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Por tÃtulo _personalizado"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Orden _inverso"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
-msgstr "Orden alea_torio"
+msgstr "_Orden aleatorio"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_Reproducir esta lista"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_Reproducir/Continuar"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
-msgstr "A_ctualizar"
+msgstr "_Actualizar"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Ordenar"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
-msgstr ""
+msgstr "Ordenar _seleccionados"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
-msgstr "Eliminar_Duplicados"
+msgstr "Eliminar _duplicados"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
-msgstr "Eliminar archivos _no disponibles"
+msgstr "_Eliminar archivos no disponibles"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Nuevo"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
-msgstr "Reno_mbrarâ¦"
+msgstr "Reno_mbrar â¦"
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
-msgstr ""
+msgstr "_Borrar"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importar ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
-msgstr "_Exportar ..."
+msgstr "E_xportar ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
-msgstr "_Gestor de listas de reproducciónâ¦"
+msgstr "_Gestor de listas de reproducción â¦"
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
-msgstr "Gestor de _colas ..."
+msgstr "Gestor de _cola ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "_Subir volumen"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "_Bajar volumen"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Ecualizador"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
-msgstr ""
+msgstr "E_fectos ..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "_Mostrar barra de menú"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Mostrar barra de _información"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
-msgstr "Mostrar Barra de Información de Vis_ualización"
+msgstr "Mostrar barra de información de vis_ualización"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Mostrar barra de _estado"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
-msgstr "Mostrar_Tiempo Restante"
+msgstr "Mostrar _tiempo restante"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
-msgstr ""
+msgstr "Visualizaciones ..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Archivo"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Reproducción"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Lista de reproducción"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Servicios"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "Sali_da"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Ver"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
-msgstr "_Encolar/desencolar"
+msgstr "_A_gregar/Quitar de la cola"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "A_brir carpeta contenedora"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
-msgstr "Cor_tar"
+msgstr "C_ortar"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Copiar"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Pegar"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Seleccionar _todo"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_Renombrar ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
-msgstr ""
+msgstr "<b>Pestañas de listas de reproducción</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
-msgstr ""
+msgstr "Mostrar pestañas siempre"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
-msgstr ""
+msgstr "Mostrar número de pista"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
-msgstr ""
+msgstr "Mostrar botón de cierre"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
-msgstr ""
+msgstr "<b>Columnas de lista de reproducción</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
-msgstr ""
+msgstr "Mostrar cabecera de las columnas"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
-msgstr ""
+msgstr "<b>Miscelánea</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
-msgstr ""
+msgstr "Las teclas de dirección (flechas) dan saltos de:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
-msgstr ""
+msgstr "Desplazar al cambiar de canción"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "Interfaz GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Gestión de memoria intermedia ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "estéreo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d canal"
msgstr[1] "%d canales"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Modo único."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Modo de lista de reproducción."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Parar después de la canción."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
-msgstr ""
+msgstr "Pista anterior"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Reproducir"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
-msgstr "Pausa/continuar"
+msgstr "Pausa/Continuar"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Detener"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
-msgstr ""
+msgstr "Pista siguiente"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
-msgstr ""
+msgstr "Adelantar 5 segundos"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
-msgstr ""
+msgstr "Atrasar 5 segundos"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Silenciar"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Subir volumen"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Bajar volumen"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Ir al archivo"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
-msgstr ""
+msgstr "Minimizar/Restaurar ventana(s)"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Mostrar notificaciones"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
-msgstr ""
+msgstr "Alternar repetir"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
-msgstr ""
+msgstr "Alternar modo aleatorio"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
-msgstr ""
+msgstr "Parar/Continuar tras esta canción"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Elevar la(s) ventana(s)"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
-msgstr "(ninguno)"
+msgstr "(ninguna)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1950,15 +2191,11 @@ msgstr ""
"\n"
"¿Quiere continuar?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Asociar botones del ratón"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Configuración de atajos de teclado"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -1966,23 +2203,27 @@ msgstr ""
"Pulse una combinación de teclas dentro del campo de texto.\n"
"También puede asociar botones del ratón."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Atajos de teclado:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Acción:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Teclas asociadas:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
-msgstr ""
+msgstr "_Añadir"
+
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Atajos de teclado globales"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1996,132 +2237,114 @@ msgid ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
+"Complemento «Atajos de teclado globales»\n"
+"Controla el reproductor con combinaciones de teclado globales o teclas "
+"multimedia.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>\n"
+"\n"
+"Contribuidores:\n"
+"Copyright (C) 2006-2007 Vladimir Paskov <vlado.paskov at gmail.com>\n"
+"Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>,\n"
+" Bryn Davies <curious at ihug.com.au>,\n"
+" Jonathan A. Davis <davis at jdhouse.org>,\n"
+" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Hotkeys Globales"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "Salida JACK"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "Conectar automáticamente a los puertos de salida"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "Sólo se encontraron %d puertos de salida JACK, pero se necesitan %d."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Error de conexión al puerto JACK %s."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
+"JACK sólo soporta audio en coma flotante . Debe cambiar a «Coma flotante» la "
+"opción «Profundidad de bits» en los ajustes de salida de sonido."
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "Error de conexión al servidor JACK. ¿Está ejecutándose?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
+"El servidor JACK requiere una frecuencia de muestreo de %d Hz, pero "
+"Audacious está reproduciendo a %d Hz. Por favor, usa el efecto «Convertidor "
+"de frecuencia de muestreo» para corregir este desfase."
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "Salida JACK"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "Ajustes %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Ajustes del servidor LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Rutas de complementos:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
"After adding new paths, press Enter to scan for new plugins.</small>"
msgstr ""
-"<small>Separe múltiples rutas por dos puntos.\n"
-"Estas rutas se utilizan además de LADSPA_PATH.\n"
+"<small>Separe múltiples rutas con dos puntos.\n"
+"El uso de estas rutas se suma al de la variable de entorno LADSPA_PATH.\n"
"Tras añadir nuevas rutas, pulse Intro para buscar complementos nuevos.</"
"small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Complementos disponibles:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Activar"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
-msgstr "Complementos activos:"
+msgstr "Complementos habilitados:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Ajustes"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
+"Host LADSPA para Audacious\n"
+"Copyright 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
-msgstr ""
-
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: No se puede iniciar soporte LIRC\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: no se pudo leer archivo de configuración LIRC\n"
-"%s: Por favor, lee la documentación de LIRC %s: cómo crear un archivo de "
-"configuración LIRC\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: intentando conectar de nuevo... \n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: comando desconocido \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: desconectado de LIRC\n"
+msgstr "Host LADSPA"
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: se intentará reconectar cada %d segundosâ¦\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Complemento LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2136,74 +2359,95 @@ msgid ""
"\n"
"For more information about LIRC, see http://lirc.org."
msgstr ""
+"Un complemento sencillo para controlar Audacious usando el demonio de "
+"control remoto LIRC\n"
+"\n"
+"Portado para Audacious por:\n"
+"Tony Vroon <chainsaw at gentoo.org>\n"
+"Joonas Harjumäki <jharjuma at gmail.com>\n"
+"\n"
+"Basado en el complemento «XMMS LIRC», creado por:\n"
+"Carl van Schaik <carl at leg.uct.ac.za>\n"
+"Christoph Bartelmus <xmms at bartelmus.de>\n"
+"Andrew O. Shadoura <bugzilla at tut.by>\n"
+"\n"
+"Para obtener más información sobre LIRC, visitar http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Conexión</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Volver a conectar con el servidor LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Espera antes de reconectar:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr ""
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "Complemento de LyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "No hay letras disponibles."
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
-#, c-format
-msgid "Unable to fetch %s"
-msgstr "No es posible obtener %s"
-
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Error"
msgstr "Error"
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
+#, c-format
+msgid "Unable to fetch %s"
+msgstr "No se pudo obtener %s"
+
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
-msgstr ""
+msgstr "No se pudo interpretar %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Buscando letras ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
-msgstr ""
+msgstr "Metadatos de canción ausentes"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Conectando con lyrics.wikia.comâ¦"
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "Complemento de LyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "Complemento LyricWiki (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
-msgstr "Listas M3U"
+msgstr "Listas de reproducción M3U"
+
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Marcador de compás"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
-msgstr "Generador de tacto: %d ppm"
+msgstr "Marcador de compás: %d ppm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
-msgstr "Generador de tacto: %d ppm %d/%d"
+msgstr "Marcador de compás: %d ppm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2211,163 +2455,205 @@ msgid ""
"e.g. tact://77 to play 77 beats per minute\n"
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
+"Un marcador de compás, creado por Martin Strauss <mys at faveve.uni-stuttgart."
+"de>\n"
+"\n"
+"Emula un metrónomo. Para usarlo, añada un URL de la forma: tact://"
+"pulsos*numerador/denominador\n"
+"p.ej. tact://77 para generar 77 pulsos por minuto\n"
+"o tact://60*3/4 para generar 60 ppm con un compás de 3/4"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Generador Tact"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Mezclador de canales"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
+"Complemento «Mezclador de canales» para Audacious\n"
+"Copyright 2011-2012 John Lindgren y MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Mezclador de canales</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Canales de salida:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Mezclador de canales"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
-msgstr "Plugin para MMS"
+msgstr "Complemento para MMS"
+
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "Error de conexión al servidor MMS"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (reproductor MOD)"
-#: src/modplug/plugin_main.c:55
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
-msgstr ""
+msgstr "<b>Resolución</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
-msgstr ""
+msgstr "8 bits"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
-msgstr ""
+msgstr "16 bits"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Canales</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "Más cercano (más rápido)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Lineal (rápido)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
-msgstr ""
+msgstr "Spline (bueno)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
-msgstr ""
+msgstr "Polifásico (el mejor)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr ""
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr "<b>Frecuencia de muestreo</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
-msgstr ""
+msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
-msgstr ""
+msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
-msgstr ""
+msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
-msgstr ""
+msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
-msgstr ""
+msgstr "Nivel:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
-msgstr ""
+msgstr "Corte:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
-msgstr ""
+msgstr "<b>Reverberación</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
-msgstr ""
+msgstr "<b>Refuerzo de graves</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
-msgstr ""
+msgstr "<b>Surround</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
-msgstr ""
+msgstr "<b>Preamplificación</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
-msgstr ""
+msgstr "Sobremuestreo"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Reducción de ruido"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
-msgstr ""
+msgstr "Reproducir archivos MOD de Amiga"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Repetir</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
-msgstr "Cuenta de repetición:"
+msgstr "Número de repeticiones:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
-msgstr "Para repetir siempre, establezca el número de repeticiones en -1."
-
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
msgstr ""
+"Para repetir infinitamente, establezca el número de repeticiones en -1."
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Envolvente"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "Estos ajustes tendrán efecto cuando se reinicie Audacious."
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
-msgstr ""
+msgstr "Complemento MPG123"
+
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Avanzado</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Cálculo preciso de duración (lento)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
-#: src/mpris2/plugin.c:403
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
-msgstr ""
+msgstr "Servidor MPRIS 2"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
-msgstr ""
+msgstr "Complemento Neon HTTP/HTTPS"
+
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "Error procesando redirección"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Error HTTP desconocido"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "Error procesando URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Demasiadas redirecciones"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Detenido"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious no está reproduciendo."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Notificaciones de escritorio"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2386,56 +2672,81 @@ msgid ""
"You should have received a copy of the GNU General Public License along with "
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
+"Complemento «Notificaciones de escritorio» para Audacious\n"
+"Copyright (C) 2010 Maximilian Bogner\n"
+"Copyright (C) 2011-2013 John Lindgren y Jean-Alexandre Anglès d'Auriac\n"
+"\n"
+"Este complemento es software libre: usted puede redistribuirlo y/o "
+"modificarlo bajo los términos de la Licencia Pública General GNU, publicada "
+"por la «Free Software Foundation» (Fundación para el software libre), ya sea "
+"la versión 3 de la Licencia, o (a su elección) cualquier versión posterior.\n"
+"\n"
+"Este programa se distribuye con la esperanza de que sea útil, pero SIN "
+"GARANTÃA ALGUNA; ni siquiera la garantÃa implÃcita de COMERCIALIZACIÃN o "
+"IDONEIDAD APTITUD PARA UN PROPÃSITO DETERMINADO. Consulte los detalles de la "
+"Licencia Pública General GNU para obtener una información más detallada.\n"
+"\n"
+"DeberÃa haber recibido una copia de la Licencia Pública General GNU junto a "
+"este programa. En caso contrario, consulte <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Mostrar controles de reproductor"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
-msgstr "Siempre demostrar notificaciónes"
+msgstr "Mantener siempre visible"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr ""
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "Incluir nombre del álbum"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Mostrar"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pausar"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Siguiente"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Dispositivo predeterminado"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "Salida OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "Salida OSS3"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Dispositivo predeterminado"
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Dispositivo de sonido:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Utilizar dispositivo alternativo:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
-msgstr "Guadar la configuración de volumen de una sesión a otra."
+msgstr "Preservar la configuración de volumen entre sesiones."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Activar conversiones de formato realizadas por el software OSS."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Activa el modo exclusivo para evitar la mezcla virtual."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2443,20 +2754,42 @@ msgid ""
"I would like to thank people on #audacious, especially Tony Vroon and John "
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
+"Complemento «Salida OSS4» para Audacious\n"
+"Copyright 2010-2012 MichaÅ Lipski\n"
+"\n"
+"Quiero expresar mi agradecimiento a toda la gente de #audacious, "
+"especialmente a Tony Vroon y John Lindgren, y, por supuesto, a los autores "
+"del anterior complemento OSS."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr ""
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Gestor de listas de reproducción"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Pistas"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Borrar"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "_Renombrar"
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
-msgstr ""
+msgstr "Listas de reproducción PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
-msgstr ""
+msgstr "Descodificador OpenPSF PSF1/PSF2"
+
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "Salida PulseAudio"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2475,149 +2808,247 @@ msgid ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
msgstr ""
+"Complemento «Salida PulseAudio» para Audacious\n"
+"\n"
+"Este programa es software libre: usted puede redistribuirlo y/o modificarlo\n"
+"bajo los términos de la Licencia Pública General GNU, publicada por la\n"
+"«Free Software Foundation» (Fundación para el software libre), ya sea la\n"
+" versión 2 de la Licencia, o (a su elección) cualquier versión posterior.\n"
+"\n"
+"Este programa se distribuye con la esperanza de que sea útil,\n"
+"pero SIN GARANTÃA ALGUNA; ni siquiera la garantÃa implÃcita de\n"
+"COMERCIALIZACIÃN o IDONEIDAD PARA UN PROPÃSITO DETERMINADO.\n"
+"Consulte los detalles de la Licencia Pública General GNU para obtener\n"
+"una información más detallada.\n"
+"\n"
+"DeberÃa haber recibido una copia de la Licencia Pública General GNU\n"
+"junto a este programa. En caso contrario, escriba a Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
+"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "Salida QtMultimedia"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
+"Complemento «Salida de audio QtMultimedia» para Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Basado en el complemento «Salida SDL» para Audacious\n"
+"Copyright 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Trabajando ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Buscar"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "A_brir carpeta"
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "Añadi_r carpeta"
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "_Inspector de registro..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Abrir archivos"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Añadir archivos"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Anterior"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Repetir"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Orden aleatorio"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Interfaz Qt"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Convertidor de frecuencia de muestreo"
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
+"Complemento «Convertidor de frecuencia de muestreo» para Audacious\n"
+"Copyright 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
-msgstr "Saltar/repetir muestras"
+msgstr "Saltar/Repetir muestras"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Interpolación lineal"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
-msgstr ""
+msgstr "Interpolación sinc (rápida)"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
-msgstr ""
+msgstr "Interpolación sinc (media)"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
-msgstr ""
+msgstr "Interpolación sinc (la mejor)"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Conversión</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Método:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
-msgstr "Taza:"
+msgstr "Tasa:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
-msgstr ""
+msgstr "<b>Mapeo de frecuencias</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
-msgstr ""
+msgstr "Usar mapeo de frecuencias"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Muestra de convertidor de frecuencia"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
-msgstr "Aprovado. Scrobbling para usario: %s"
+msgstr "Aprobado. Scrobbling para usario: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
-msgstr "Permiso Denegado"
+msgstr "Permiso denegado"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr "Acceda a esta página para permitir scrobbling en Audacious:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
+"Mantenga esta ventana abierta y haga clic en «Comprobar el permiso» otra "
+"vez.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
+"No se preocupe: sus scrobbles se guardan en su equipo.\n"
+"Se enviarán tan pronto como Audacious reciba la autorización necesaria."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "Problema de la red"
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
"Hubo un problema al contactar con Last.fm. Por favor inténtelo de nuevo más "
"tarde."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "Comprobando..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "C_omprobar el permiso"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
-msgstr "Revocar el Permiso"
+msgstr "Revocar el permiso"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-"Usted necesidad permitir scrobbling a Audacious a su cuenta de Last.fm. â\n"
+"Necesita autorizar a Audacious para hacer scrobbling a su cuenta de Last."
+"fm.\n"
+
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-"El plugin Scrobbler no se pudo iniciar. â\n"
+"No se pudo iniciar el complemento Scrobbler.\n"
"Puede haber un problema con la instalación."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2627,844 +3058,921 @@ msgid ""
"project.\n"
"\n"
msgstr ""
-"Complemento Audacious Scrobbler 2.0 por Pitxyoki, â\n"
-"â\n"
-"Copyright © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com> â\n"
-"â\n"
-"Gracias a John Lindgren por darme una mano en el inicio de este proyecto. â\n"
-"â\n"
-
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
+"Complemento «Scrobbler 2.0» de Audacious, creado por Pitxyoki,\n"
+"\n"
+"Copyright © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com>\n"
+"\n"
+"Muchas gracias a John Lindgren por su ayuda en el comienzo de este "
+"proyecto.\n"
+"\n"
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
+"Audacious usa ahora una versión mejorada del Scrobbler de Last.fm.\n"
+"Busque «Scrobbler» en la sección de «Complementos» de las «Preferencias»."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "Salida SDL"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
+"Complemento «Salida SDL» para Audacious\n"
+"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "Salida SDL"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Biblioteca"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Artista Desconocido"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Ãlbum Desconocido"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr " %sâ en %s de %s "
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d resultado"
+msgstr[1] "%d resultados"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d álbum"
-msgstr[1] "%d álbumes"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d oculto)"
+msgstr[1] "(%d ocultos)"
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%sâ\n"
-"%s, %d cancion"
-msgstr[1] ""
-"%sâ\n"
-"%s, %d canciones"
-
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%sâ\n"
-"%d cancion de %s"
-msgstr[1] ""
-"%sâ\n"
-"%d canciones de %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d canción"
+msgstr[1] "%d canciones"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "de este género"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "en"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "por"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Crear lista de reproducción"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Añadir a la lista de reproducción"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
-msgstr "Buscar biblioteca"
+msgstr "Explorar biblioteca"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
"Para importar su biblioteca musical en Audacious, seleccione una carpeta y "
-"pulse el botón «actualizar»."
+"pulse el botón «Actualizar»."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Espere por favor..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Seleccione un directorio"
-#: src/skins/menus.c:56
-msgid "Open Files ..."
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "Reproductor SID"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>Salida</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Canales:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Emulación</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "Emular MOS 8580 (predeterminado: MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "No seleccionar automáticamente el chip"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Emular filtro"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Frecuencia de reloj:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "No seleccionar automáticamente la frecuencia"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>Tiempo de reproducción</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "Establecer tiempo máximo de reproducción:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Sólo con pistas de duración desconocida"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "Establecer tiempo mÃnimo de reproducción:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Subtonos</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "Habilitar subtonos"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "Ignorar subtonos de menos de:"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Nota</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Eliminación de silencios"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
msgstr ""
+"Complemento «Eliminación de silencios» para Audacious\n"
+"Copyright 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Eliminación de silencios</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Umbral:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:64
+msgid "Open Files ..."
+msgstr "Abrir archivos ..."
+
+#: src/skins/menus.cc:65
msgid "Open URL ..."
-msgstr ""
+msgstr "Abrir URL ..."
+
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Explorar biblioteca"
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Reproducción"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Lista de reproducción"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Ver"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
-msgstr ""
+msgstr "Servicios"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
-msgstr ""
+msgstr "Acerca de ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
-msgstr ""
+msgstr "Preferencias ... "
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
-msgstr ""
+msgstr "Salir"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
-msgstr ""
-
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Repetir"
+msgstr "Información de la canción ..."
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Orden aleatorio"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "No avanzar la lista de reproducción"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
-msgstr ""
+msgstr "Detener después de esta canción"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Anterior"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
-msgstr ""
+msgstr "Crear bucle (puntos A-B)"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
-msgstr ""
+msgstr "Borrar bucle"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
-msgstr ""
+msgstr "Ir a la canción ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
-msgstr ""
+msgstr "Ir al momento ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr ""
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "Reproducir/Continuar"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Nueva lista de reproducción"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
-msgstr ""
+msgstr "Renombrar lista ..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
-msgstr ""
+msgstr "Borrar lista ..."
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
-msgstr ""
+msgstr "Lista anterior"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
-msgstr ""
+msgstr "Lista siguiente"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
-msgstr ""
+msgstr "Importar lista ..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
-msgstr ""
+msgstr "Exportar lista ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
-msgstr ""
+msgstr "Gestor de listas ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
-msgstr ""
+msgstr "Gestor de cola ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
-msgstr ""
+msgstr "Actualizar lista de reproducción"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Mostrar el editor de listas de reproducción"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Mostrar el ecualizador"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
-msgstr ""
+msgstr "Mostrar tiempo restante"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Siempre encima"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
-msgstr ""
+msgstr "En todas las áreas de trabajo "
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
-msgstr ""
+msgstr "Enrollar reproductor"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
-msgstr ""
+msgstr "Enrollar editor de lista de reproducción"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
-msgstr ""
+msgstr "Enrollar ecualizador"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Duplicar tamaño"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
-msgstr ""
+msgstr "Añadir URL ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
-msgstr ""
+msgstr "Añadir archivos ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Por tÃtulo"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "Por nombre de archivo"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
-msgstr ""
+msgstr "Por ruta de archivo"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Eliminar todo"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Limpiar la cola"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Eliminar los archivos no disponibles"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Eliminar duplicados"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Eliminar los no seleccionados"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Eliminar los seleccionados"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Buscar y seleccionar"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Invertir la selección"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "No seleccionar nada"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Seleccionar todo"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Por álbum"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Por número de pista"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Por artista"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Por álbum"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Por artista del álbum"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
-msgstr ""
+msgstr "Por fecha de lanzamiento"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Por número de pista"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "Por género"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "Por duración"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "Por tÃtulo personalizado"
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Ordenar aleatoriamente"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Invertir la lista"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Ordenar los seleccionados"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Ordenar lista"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Cortar"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Copiar"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Pegar"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
-msgstr ""
+msgstr "Agregar/Quitar de la cola"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
-msgstr ""
+msgstr "Cargar preajuste ..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
-msgstr ""
+msgstr "Cargar de Predefinidos ..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
-msgstr ""
+msgstr "Cargar predeterminado"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
-msgstr ""
+msgstr "Cargar de archivo ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
-msgstr ""
+msgstr "Cargar EQF ..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
-msgstr ""
+msgstr "Guardar preajuste ..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
-msgstr ""
+msgstr "Añadir a Predefinidos ..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
-msgstr ""
+msgstr "Guardar como predeterminado ..."
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
-msgstr ""
+msgstr "Guardar a archivo"
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
-msgstr ""
+msgstr "Guardar como EQF ..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
-msgstr ""
+msgstr "Borrar preajuste ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
-msgstr ""
+msgstr "Borrar predefinido ..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
-msgstr ""
+msgstr "Importar de Winamp ..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
-msgstr ""
+msgstr "Reiniciar"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
-msgstr "Interfaz Clásica de Winamp"
+msgstr "Interfaz clásica de Winamp"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Guardar"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Cargar"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
-msgstr ""
+msgstr "Cargar archivo de preajuste"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
-msgstr ""
+msgstr "Cargar archivo EQF"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
-msgstr ""
+msgstr "Guardar como archivo de preajuste"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
-msgstr ""
+msgstr "Guardar como archivo EQF"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
-msgstr ""
+msgstr "Importar preajustes de Winamp"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
-msgstr "Predefinidos"
+msgstr "Preajustes"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
-msgstr "Cargar predefinido"
+msgstr "Cargar preajuste"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
-msgstr "Cargar auto-predefinido"
+msgstr "Cargar preajuste predefinido"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
-msgstr "Guardar predefinido"
+msgstr "Guardar preajuste"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
-msgstr "Guardar auto-predefinido"
+msgstr "Guardar preajuste como predefinido"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
-msgstr "Borrar predefinido"
+msgstr "Borrar preajuste"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
-msgstr "Borrar auto-predefinido"
+msgstr "Borrar preajuste predefinido"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Reproductor:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Reproductor:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Seleccione la tipografÃa para la ventana principal:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "Lista de reproducción:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Lista:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Seleccione la tipografÃa de la lista de reproducción:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
-msgstr ""
+msgstr "<b>Tema</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
-msgstr ""
+msgstr "<b>Fuentes</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
-msgstr "Usar tipografÃas de mapa de bits (solo soporta ASCII)"
+msgstr "Usar fuentes de mapa de bits (sólo soporta ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
-msgstr ""
+msgstr "Desplazar el tÃtulo de la canción"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Desplazar el tÃtulo de la canción en ambas direcciones"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analizador"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Campo"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
-msgstr ""
+msgstr "Impresión vocal / Vúmetro"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Apagado"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normal"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Fuego"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
-msgstr ""
+msgstr "LÃneas verticales"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "LÃneas"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Barras"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Muy lento"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Lento"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Medio"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Rápido"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Muy rápido"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
-msgstr ""
+msgstr "Puntos"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
-msgstr ""
+msgstr "LÃnea"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
-msgstr ""
+msgstr "Sólido"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Hielo"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Suave"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
-msgstr ""
+msgstr "<b>Tipo</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
-msgstr ""
+msgstr "Visualización:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
-msgstr ""
+msgstr "<b>Analizador</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
-msgstr ""
+msgstr "Mostrar picos"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
-msgstr ""
+msgstr "Coloreado:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
-msgstr ""
+msgstr "Estilo:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
-msgstr ""
+msgstr "Descenso:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
-msgstr ""
+msgstr "Descenso de los picos:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
-msgstr ""
+msgstr "Estilo de campo:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
-msgstr ""
+msgstr "Coloreado de impresión vocal:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
-msgstr ""
+msgstr "Estilo de vúmetro:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "General"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualización"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Preamplificador"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Ecualizador de Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Ir a la posición %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Volumen: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balance: %d%% izquierda"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balance: centrado"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balance: %d%% derecha"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Menú de opciones"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Desactivar 'Siempre encima'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Activar 'Siempre encima'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Caja de información de archivo"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "Visualizaciones"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
-msgstr "Repetir punto de establecimiento A."
+msgstr "Punto A del bucle."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
-msgstr "Repetir punto de establecimiento B."
+msgstr "Punto B del bucle."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
-msgstr "Repetir punto de establecimiento borrados."
-
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Modo único."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Modo de lista de reproducción."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Parar después de la canción."
+msgstr "Borrar bucle."
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
-msgstr "Buscar entradas en la lista de reproducción activa"
+msgstr "Buscar en la lista de reproducción activa"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
"expressions work, simply insert a literal portion of what you're searching "
"for."
msgstr ""
-"Seleccione entradas en la lista de reproducción indicando uno o más campos. "
-"Los campos utilizan sintaxis de expresiones regulares, sin distinguir "
-"mayúsculas de minúsculas. Si no sabe como funcionan las expresiones "
-"regulares, tan solo escriba la parte del literal que quiere buscar."
+"Seleccione entradas de la lista de reproducción rellenando uno o más campos. "
+"Estos campos aceptan expresiones regulares. Si no comprende esto, tan sólo "
+"escriba el texto que desea buscar. No se distinguen mayúsculas de minúsculas."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "TÃtulo: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr "TÃtulo:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Ãlbum: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr "Ãlbum:"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Artista: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr "Artista:"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Nombre del archivo: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Nombre de archivo:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Limpiar la selección previa antes de buscar"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
-msgstr "Conmutar automáticamente la cola para las entradas coincidentes"
+msgstr "Reemplazar la cola actual por las entradas coincidentes"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
-msgstr "Crear una nueva lista de reproducción con las entradas coincidentes"
+msgstr "Crear una nueva lista de reproducción con las coincidencias"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Editor de listas de reproducción de Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d de %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Tema para Winamp 2.x archivado"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Tema para Winamp 2.x no archivado"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "No se pudo crear el directorio (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Complemento Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3485,80 +3993,92 @@ msgid ""
"this program; if not, write to the Free Software Foundation, Inc., 51 "
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
+"Basado en el complemento xmms_sndfile:\n"
+"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
+"\n"
+"Adaptado para Audacious por Tony Vroon <chainsaw at gentoo.org>\n"
+"\n"
+"Este programa es software libre: usted puede redistribuirlo y/o modificarlo "
+"bajo los términos de la Licencia Pública General GNU, publicada por la «Free "
+"Software Foundation» (Fundación para el software libre), ya sea la versión 2 "
+"de la Licencia, o (a su elección) cualquier versión posterior.\n"
+"\n"
+"Este programa se distribuye con la esperanza de que sea útil, pero SIN "
+"GARANTÃA ALGUNA; ni siquiera la garantÃa implÃcita de COMERCIALIZACIÃN o "
+"IDONEIDAD PARA UN PROPÃSITO DETERMINADO. Consulte los detalles de la "
+"Licencia Pública General GNU para obtener una información más detallada.\n"
+"\n"
+"DeberÃa haber recibido una copia de la Licencia Pública General GNU junto a "
+"este programa. En caso contrario, escriba a Free Software Foundation, Inc., "
+"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr ""
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Acerca del complemento de salida Sndio"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Salida Sndio"
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "Dispositivo (en blanco por defecto):"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Formato no soportado"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Guardar y restaurar volumen:"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Error de sndio: formato de audio (%d) no soportado"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "dispositivo sndio"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Error de sndio: sio_open() falló"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(Vacio significa por defecto)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Error de sndio: sio_setpar() falló"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "Aceptar"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Error de sndio: sio_start() falló"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Cambio de canción"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Comando a ejecutar cuando Audacious reproduce una canción nueva."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Los parámetros enviados a la consola deberÃan encerrarse "
+"entre comillas. Hacer lo contrario supone un riesgo de seguridad.</span>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Comando:"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Comandos</b>"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Comando para ejecutar al final de una canción."
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Comando a ejecutar al empezar una nueva canción:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr ""
-"Comando para ejecutar cuando Audacious llega al final de una lista de "
-"reproducción."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Comando a ejecutar al acabar una canción:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Comando a ejecutar al concluir la lista de reproducción:"
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Comando para ejecutar cuando el tÃtulo cambia para una canción (es decir, "
-"tÃtulos de flujos en red)"
+"Comando a ejecutar cuando el tÃtulo de la canción cambie (para flujos de "
+"red):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3572,20 +4092,31 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
+"Puede usar las siguientes cadenas de formato, que serán sustituidas antes de "
+"invocar los comandos (algunas no son válidas para el comando de fin de lista "
+"de reproducción):\n"
+"\n"
+"%F: Frecuencia (en hercios)\n"
+"%c: Número de canales\n"
+"%f: Nombre de archivo (ruta completa)\n"
+"%l: Duración (en milisegundos)\n"
+"%n o %s: Nombre de la canción\n"
+"%r: Tasa (en bits por segundo)\n"
+"%t: Posición en la lista de reproducción (%02d)\n"
+"%p: Reproduciendo (1 o 0)\n"
+"%a: Artista\n"
+"%b: Ãlbum\n"
+"%T: TÃtulo de pista"
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Información de la canción (Qt)"
+
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "Remuestreador SoX"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>Los parámetros enviados a la consola se deberÃan "
-"encapsular con comillas. De otra forma existe un riesgo de seguridad.</span>"
-
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Comandos"
-
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3593,52 +4124,57 @@ msgid ""
"Based on Sample Rate Converter Plugin:\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
+"Complemento «Remuestreador SoX» para Audacious\n"
+"Copyright 2013 MichaÅ Lipski\n"
+"\n"
+"Basado en el complemento «Convertidor de frecuencia de muestreo»:\n"
+"Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
-msgstr "Rapido"
+msgstr "Rápido"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Bajo"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Alto"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Muy Alto"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Calidad"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr ""
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Velocidad y tono"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
-msgstr "<b>Velocidad y Tono</b>"
+msgstr "<b>Velocidad y tono</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Velocidad:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Tono:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Velocidad y tono"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Icono de estado"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
-msgstr ""
+msgstr "Pre_ferencias ..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3648,64 +4184,74 @@ msgid ""
"This plugin provides a status icon, placed in\n"
"the system tray area of the window manager."
msgstr ""
+"Complemento «Icono de estado»\n"
+"\n"
+"Copyright 2005-2007 Giacomo Lozito <james at develia.org>\n"
+"Copyright 2010 MichaÅ Lipski <tallica at o2.pl>\n"
+"\n"
+"Este complemento proporciona un icono de estado, que se muestra\n"
+"en la bandeja del sistema del gestor de ventanas."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
-msgstr ""
+msgstr "<b>Acción al deslizar la rueda del ratón</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Cambiar el volumen"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Cambiar la canción en reproducción"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Otros parámetros</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Desactivar la ventana emergente"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Cerrar a la bandeja del sistema"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Avanzar en la lista de reproducción al desplazar arriba"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Icono de estado"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra estéreo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
+"Complemento «Extra estéreo»\n"
+"\n"
+"Escrito por Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
-msgstr "<b>Extra Estéreo</b>"
+msgstr "<b>Extra estéreo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr ""
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Generador de tonos"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Generador de tonos: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3713,16 +4259,18 @@ msgid ""
"To use it, add a URL: tone://frequency1;frequency2;frequency3;...\n"
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
+"Generador de tonos sinusoidales creado por Håvard Kvålen <havardk at xmms.org>\n"
+"Modificado por Daniel J. Peng <danielpeng at bigfoot.com>\n"
+"\n"
+"Para usarlo, añada un URL de la forma: tone://frecuencia1;frecuencia2;"
+"frecuencia3;...\n"
+"p.ej. tone://2000;2005 para reproducir un tono de 2000 Hz y otro de 2005 Hz"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Generador de tonos"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Eliminación de voz"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3742,45 +4290,107 @@ msgid ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
+"Descodificador Ogg Vorbis para Audacious\n"
+"\n"
+"Basado en el complemento «Ogg Vorbis» de la Fundación Xiph.org:\n"
+"http://www.xiph.org/\n"
+"\n"
+"Código original escrito por:\n"
+"Tony Arcieri <bascule at inferno.tusculum.edu>\n"
+"\n"
+"Con contribuciones de:\n"
+"Chris Montgomery <monty at xiph.org>\n"
+"Peter Alm <peter at xmms.org>\n"
+"Michael Smith <msmith at labyrinth.edu.au>\n"
+"Jack Moffitt <jack at icecast.org>\n"
+"Jorn Baayen <jorn at nl.linux.org>\n"
+"Håvard Kvålen <havardk at xmms.org>\n"
+"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
+"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
-msgstr "Decodificador Ogg Vorbis"
+msgstr "Descodificador Ogg Vorbis"
+
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Detalles sobre %s"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"TÃtulo: %t\n"
+"Autor: %a\n"
+"De: %f\n"
+"Secuenciador: %T\n"
+"Comentario: %C\n"
+"Tipo de chip: %c\n"
+"Estéreo: %s\n"
+"Bucle: %l\n"
+"Chip freq: %F\n"
+"Frecuencia de reproducción: %P\n"
+"Año: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "Descodificador VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
+"Reproductor Vortex creado por Sashnov Alexander <sashnov at ngs.ru>\n"
+"Basado en in_vtx.dll, creado por Roman Sherbakov <v_soft at microfor.ru>\n"
+"Complemento para Audacious escrito por Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "Decodificador VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "Descodificador WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "con pérdida (hÃbrido)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "con pérdida"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
+"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
+"\n"
+"Parte del código del complemento escrita por Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "Decodificador WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
-msgstr "Decodificador 2SF"
+msgstr "Descodificador 2SF"
+
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>Configuración XSF</b>"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Ignorar duración del archivo"
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
-msgstr ""
+msgstr "Listas de reproducción XML (XSPF)"
diff --git a/po/es_AR.po b/po/es_AR.po
index 18c98886dda1..73d2df99e58f 100644
--- a/po/es_AR.po
+++ b/po/es_AR.po
@@ -9,11 +9,11 @@
# xukosky <xukosky at yahoo.es>, 2011
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Spanish (Argentina) (http://www.transifex.com/projects/p/"
"audacious/language/es_AR/)\n"
"Language: es_AR\n"
@@ -22,40 +22,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "estéreo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "envolvente"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (Reproductor AdLib)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr ""
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (Reproductor AdLib)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarma"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -66,11 +54,7 @@ msgstr ""
"\n"
"Escrito originalmente por Adam Feakin y Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarma"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -93,7 +77,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -115,7 +99,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -129,183 +113,156 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Esta es su llamada despertador"
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr ""
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Recordatorio"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Lunes"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Martes"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Miércoles"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Jueves"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Viernes"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Sábado"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Domingo"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Configuración de la alarma"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Tiempo"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarma a (predeterminado):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Silencio tras:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "horas"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minutos"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Seleccione los dÃas para que salte la alarma"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "DÃa"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Predeterminado"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "DÃas"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Desvanecimiento"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "segundos"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Volumen"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Iniciar a"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Final"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Actual"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Comando adicional"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "activar"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Lista de reproducción (opcional)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Elegir una lista de reproducción"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Opciones"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "¿Qué significan estas opciones?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Ayuda"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Arte de tapa"
-#: src/alsa/config.c:210
-msgid "Default PCM device"
-msgstr "Dispositivo PCM predeterminado"
-
-#: src/alsa/config.c:239
-msgid "Default mixer device"
-msgstr "Dispositivo mezclador predeterminado"
-
-#: src/alsa/config.c:428
-msgid "PCM device:"
-msgstr "Dispositivo PCM:"
-
-#: src/alsa/config.c:430
-msgid "Mixer device:"
-msgstr "Dispositivo mezclador:"
-
-#: src/alsa/config.c:432
-msgid "Mixer element:"
-msgstr "Elemento mezclador:"
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Evitar los cuelgues por falta de recursos"
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "Salida ALSA"
-#: src/alsa/plugin.c:27
+#: src/alsa/config.cc:28
msgid ""
"ALSA Output Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren\n"
@@ -320,175 +277,208 @@ msgstr ""
"quien se ha asistido con el código y la referencia cuando el manual de ALSA "
"no era suficiente."
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "Salida ALSA"
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
+msgid "Default PCM device"
+msgstr "Dispositivo PCM predeterminado"
-#: src/amidi-plug/amidi-plug.c:466
+#: src/alsa/config.cc:188
+msgid "Default mixer device"
+msgstr "Dispositivo mezclador predeterminado"
+
+#: src/alsa/config.cc:296
+msgid "PCM device:"
+msgstr "Dispositivo PCM:"
+
+#: src/alsa/config.cc:299
+msgid "Mixer device:"
+msgstr "Dispositivo mezclador:"
+
+#: src/alsa/config.cc:302
+msgid "Mixer element:"
+msgstr "Elemento mezclador:"
+
+#: src/amidi-plug/amidi-plug.cc:41
msgid "AMIDI-Plug (MIDI Player)"
msgstr "Plug-AMIDI (Reproductor MIDI)"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/amidi-plug.cc:437
+msgid ""
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
+"\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "Complemento AMIDI - seleccione un archivo SoundFont"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Nombre del archivo"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Tamaño (bytes)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nombre:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> Información MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Formato:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Longitud (mseg):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Nro. de Pistas:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variable"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Div tiempo:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> Comentarios y letras MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* no hay comentarios disponibles en este archivo MIDI *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* no hay letras disponibles en este archivo MIDI *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Cerrar"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (UTF-8 no válido)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Acerca del Plug-MIDI"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -499,152 +489,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (Visualización en pantalla)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Rectángulo"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Rectángulo redondeado"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Rectángulo cóncavo"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Ninguno"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Reproducción iniciada"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Avisa cuando se reproduce un elemento de la lista de reproducción."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Cambio de tÃtulo"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Avisa cuando, durante la reproducción, el tÃtulo de la canción cambia pero "
-"el nombre de archivo es el mismo. Esto es principalmente útil para mostrar "
-"cambios de tÃtulo en los flujos de Internet."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Inicio de pausa"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Avisa cuando la reproducción es pausada."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Fin de pausa"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Avisa cuando la reproducción se reanuda."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Colocación"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Desplazamiento X relativo:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Desplazamiento Y relativo:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Ancho máximo:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Opciones multi-monitor"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Mostrar notificaciones utilizando:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "todos los monitores"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "monitor %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Temporización (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Mostrar:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Desvanecimiento de entrada:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Desvanecimiento de salida:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "TipografÃas"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "TipografÃa %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Sombra"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Estilo de renderizado"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Colores"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Color %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Activar disparador"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Evento"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Administrador de composición detectado"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -655,112 +639,112 @@ msgstr ""
"administrador de composición o las notificaciones no funcionarán "
"correctamente"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Administrador de composición no necesario para transparencia falsa"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Transparencia"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Transparencia falsa"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Transparencia real (requiere composición 3D)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Extensión de composición no cargada"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Extensión de composición no disponible"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Notificaciones de Audacious</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Notificaciones de Audacious - configuración"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Posición"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animación"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Texto"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Decoración"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Disparador"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Varios"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "Listas de reproducciónASXv1/ASXv2"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Listas de reproducción Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Color</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Niebla Borrosa"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Estereofónico-a-Binaural Bauer (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Predefinidos:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Nivel de alimentación:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Cortar frecuencia:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Predefinidos:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Estereofónico-a-Binaural Bauer (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Analizador de Espectro"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Plugin de CD de audio"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -772,171 +756,156 @@ msgid ""
"This was a Google Summer of Code 2007 project."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Dispositivo</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Leer velocidad:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Anular dispositivo:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadatos</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Usar CD-Texto"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Usar CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Usar HTTP en lugar de CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Servidor:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Ruta:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Puerto:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Plugin de CD de audio"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "Error en la inicialización del subsistema cdio."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "URI inválido %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Pista %d no encontrada."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Error al abrir la salida de audio."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "CD de audio"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Error al abrir la lectora de CD %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "No hay audio que se pueda reproducir en la lectora de CD localizada."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "Error al finalizar la lectora de CD inicializada oportunamente."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Error al obtener el primer/último número de pista."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "No se puede leer el LSN del comienzo/final de la pista %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Error al crear la conexión a cddb."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Error al consultar el servidor CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Error al consultar el servidor CDDB: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Error al leer la información cddb: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "La unidad está vacÃa."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Tipo de disco no soportado."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Items de menú del CD de audio"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Reproducir CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Agregar CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Items de menú del CD de audio"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Compresión</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Centrar volumen:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Rango dinámico:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Plugin de Compresión de Rango Dinámico para Audacious\n"
-"Copyright 2010-2012 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Compresor de Rango Dinámico"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -946,200 +915,225 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Graves:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Agudos:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Longitud de canción predeterminada:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Activar el remuestreo de sonido"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Tasa de remuestreo:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ignorar longitud de etiquetas SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Aumentar la reverberación"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Decodificador musical de videoconsola"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-"El fundido de pistas falló porque las canciones tiene distintas cantidades "
-"de canales. Puede usar el Mezclador de Canales para igualarlos."
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"El fundido de pistas falló porque las canciones tiene distintas "
-"velocidades. Puede usar el Convertidor de Muestreo de Velocidad para "
-"igualarlos."
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Fundido de pistas</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "Superposición:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Fundido de pistas:"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"El fundido de pistas falló porque las canciones tiene distintas cantidades "
+"de canales. Puede usar el Mezclador de Canales para igualarlos."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"El fundido de pistas falló porque las canciones tiene distintas "
+"velocidades. Puede usar el Convertidor de Muestreo de Velocidad para "
+"igualarlos."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Cristalizador</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intensidad:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Cristalizador"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Plugin para hoja cue"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Borrar"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Cancelar"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Eco</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Retardo:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Retroalimentación:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Volumen:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Eco"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Plugin FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1149,55 +1143,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "Plugin FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Plugin FileWriter"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Formato del archivo de salida:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Configurar"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Guardar dentro del directorio original"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Guardar dentro de directorio personalizado"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Carpeta de archivo de salida:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Elija una carpeta"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Obtener nombre de archivo desde:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "etiquetas del archivo original"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "nombre del archivo original"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "No quitar la extensión del archivo"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Anteponer el número de pista al nombre de archivo"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1215,165 +1209,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "Plugin FileWriter"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Auto"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Estéreo conjunto"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Estereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Configuración MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Calidad del algoritmo:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Frecuencia de muestreo de salida:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Tasa de bits / Compresión:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Tasa de bits (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Compresión:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Modo de sonido:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Varios:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Cumplir estrictamente la norma ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Error de protección"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Calidad"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Activar VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tipo:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Opciones VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Tasa de bits mÃnima (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Tasa de bits máxima (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Aplicar estrictamente la tasa de bits mÃnima"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Opciones ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Tasa de bits promedio (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "Nivel de calidad VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "No escribir la cabecera VBR Xing"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "Parámetros del marco:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Marcar como derechos de autor"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Marcar como original"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "Parametros ID3:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Forzar adición de etiqueta de la versión 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Solo agregar etiqueta v1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Solo agregar etiqueta v2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Etiquetas"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Configuración de codificador Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Nivel de calidad (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "Decodificador FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr ""
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1381,21 +1379,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "Decodificador FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "Plugin GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1407,530 +1409,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Accesos directos para GNOME"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Número de entrada"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "TÃtulo"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Artista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Año"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Album"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Pista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Género"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Posición de la cola"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Longitud"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Ruta del archivo"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Nombre del archivo"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "TÃtulo personalizado"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Tasa de bits"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Herramienta de búsqueda"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Acoplar a la izquierda"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Acoplar a la derecha"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Acoplar arriba"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Acoplar abajo"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Desacoplar"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Deshabilitar"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Herramienta de búsqueda"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Abrir archivos ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Abrir _URL ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_Añadir archivos ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Añadir U_RL ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "A_cerca de ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Salir"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Reproducir"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Pa_usar"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Detener"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "An_terior"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "Si_guiente"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "R_epetir"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_Orden aleatorio"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "No avan_zar la lista de reproducción"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Información de la canción ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "_Saltar en el tiempo ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "Saltar a la _canción ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Por _tÃtulo"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Por _número de pista"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Por _artista"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Por _fecha de estreno"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Por _ruta de archivo"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Por tÃtulo _personalizado"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Orden _inverso"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "Orden alea_torio"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_Reproducir esta lista de reproducción"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "A_ctualizar"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Ordenar"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Eliminar archivos _no disponibles"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Nuevo"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "Ren_ombrar..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importar ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Exportar ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "Administrador_de listas de reproducción ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Gestor de _colas ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "_Subir volumen"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "_Bajar volumen"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Ecualizador"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "_Mostrar barra de menú"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Mostrar barra de _información"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Mostrar la Barra Informativa de Vis_ualización"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Mostrar barra de _estado"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Archivo"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Reproducción"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Lista de reproducción"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Servicios"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "Sali_da"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Ver"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Encolar/desencolar"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Cor_tar"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Copiar"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Pegar"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Seleccionar _todo"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_Renombrar ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "Interfaz GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Gestión de memoria intermedia ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "estéreo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d canal"
msgstr[1] "%d canales"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Modo único."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Modo de lista de reproducción."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Parar después de la canción."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr ""
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Reproducir"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pausa/continuar"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Detener"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr ""
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Silenciar"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr ""
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr ""
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr ""
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Mostrar notificaciones"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(ninguno)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1941,15 +2020,11 @@ msgstr ""
"\n"
"¿Quiere continuar?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Asociar botones del mouse"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Configuración de atajos de teclado"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -1957,23 +2032,27 @@ msgstr ""
"Pulse una combinación de teclas dentro del campo de texto.\n"
"También puede asociar botones del ratón."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Atajos de teclado:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Acción:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Teclas asociadas:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Teclas abreviadas globales"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1988,56 +2067,51 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Teclas abreviadas globales"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "Salida JACK"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "Salida JACK"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "Ajustes %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Ajustes del servidor LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Rutas de complementos:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2048,71 +2122,39 @@ msgstr ""
"Tras añadir nuevas rutas, pulse Intro para buscar complementos nuevos.</"
"small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Complementos disponibles:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Activar"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Complementos activos:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Ajustes"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "Servidor LADSPA"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: no se puede iniciar soporte LIRC\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: no se puede leer el archivo de configuración de LIRC\n"
-"%s: por favor lea la documentación de LIRC\n"
-"%s: en el tópico \"Cómo crear un archivo de configuración adecuado\"\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: tratando de reconectar...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: comando desconocido \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: desconectando de LIRC\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: se intentará reconectar cada %d segundos...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Plugin LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2128,73 +2170,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Conexión</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Reconectar a servidor LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Espera antes de reconectar:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Plugin LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "Plugin LyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "No se encontraron letras"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Error"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "No se puede obtener %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Error"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "No se puede analizar %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Buscando letras de la canción...."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "No hay metadatos de la canción"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Conectándose con lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "Plugin LyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "Listas de reproducción M3U"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Generador de tacto"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Generador de tacto: %d ppm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Generador de tacto: %d ppm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2203,162 +2253,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Generador de tacto"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Mezclador de canales"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Mezclador de canales</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Canales de salida:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Mezclador de canales"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "Plugin MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Módulo de reproducción)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr ""
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr ""
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr ""
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr ""
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr ""
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr ""
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Módulo de reproducción)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Envolvente"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 Plugin"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Envolvente"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 Server"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS Plugin"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Detenido"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious no está reproduciendo."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Notificaciones de escritorio"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2378,55 +2460,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Notificaciones de escritorio"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr ""
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pausar"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Siguiente"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Dispositivo predeterminado"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "Salida OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Dispositivo de sonido:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Utilizar dispositivo alternativo:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Guardar volumen entre sesiones."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Activar conversiones de formato realizadas por el software OSS."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Activa el modo exclusivo para evitar la mezcla virtual."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2435,19 +2526,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "Salida OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "Listas PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "Abrir el decodificador PSF PSF1/PSF2"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "Salida de PulseAudio"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2467,143 +2574,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "Salida de PulseAudio"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
-#: src/resample/resample.c:165
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Anterior"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Repetir"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Orden aleatorio"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Convertidor de Velocidad de Muestra"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "Saltear/repetir muestras"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Interpolación lineal"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Interpolación de sincronización rápida "
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "Interpolación de sincronización media"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Mejor interpolación de sincronización "
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Conversión</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Método:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Velocidad:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Mapeos de velocidad</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Usar mapeos de velocidad"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Convertidor de Velocidad de Muestra"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr ""
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr ""
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2614,97 +2790,72 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "Salida SDL"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "Salida SDL"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Biblioteca"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Artista Desconocido"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Album Desconocido"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" en %s por %s"
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d álbum"
-msgstr[1] "%d álbumes"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-"%s\n"
-" %s, %d canción"
msgstr[1] ""
-"%s\n"
-" %s, %d canciones"
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
-"%s\n"
-" %d canción por %s"
msgstr[1] ""
-"%s\n"
-" %d canciones por %s"
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Crear lista de reproducción"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Añadir a la lista de reproducción"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Buscar biblioteca"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2712,679 +2863,769 @@ msgstr ""
"Para importar su colección musical en Audacious, elija una carpeta y pulse "
"el botón «actualizar»."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Espere por favor..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Elija una carpeta"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Reproducción"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Lista de reproducción"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Ver"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Repetir"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Orden aleatorio"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "No avanzar la lista de reproducción"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Anterior"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Nueva lista de reproducción"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Mostrar el editor de listas de reproducción"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Mostrar el ecualizador"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Siempre encima"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Por tÃtulo"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Por nombre de archivo"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Eliminar todo"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Limpiar la cola"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Eliminar los archivos no disponibles"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Eliminar duplicados"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Eliminar los no seleccionados"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Eliminar los seleccionados"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Buscar y seleccionar"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Invertir la selección"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "No seleccionar nada"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Seleccionar todo"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Por álbum"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Por número de pista"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Por artista"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Por álbum"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Por número de pista"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Ordenar aleatoriamente"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Invertir la lista"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Ordenar los seleccionados"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Ordenar lista"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Cortar"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Copiar"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Pegar"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Interface del Winamp Clásico"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Guardar"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Cargar"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Predefinidos"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Cargar predefinido"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Cargar auto-predefinido"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Guardar predefinido"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Guardar auto-predefinido"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Borrar predefinido"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Borrar auto-predefinido"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Reproductor:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Seleccione la tipografÃa para la ventana principal:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "Lista de reproducción:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Seleccione la tipografÃa de la lista de reproducción:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Usar tipografÃas de mapa de bits (solo soporta ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Desplazar el tÃtulo de la canción en ambas direcciones"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analizador"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Campo"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Apagado"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normal"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Fuego"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "LÃneas"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Barras"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Muy lento"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Lento"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Medio"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Rápido"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Muy rápido"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Hielo"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Suave"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "General"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualización"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Preamplificador"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Ecualizador de Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Ir a la posición %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Volumen: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balance: %d%% izquierda"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balance: centrado"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balance: %d%% derecha"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Menú de opciones"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Desactivar 'Siempre encima'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Activar 'Siempre encima'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Caja de información de archivo"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Modo único."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Modo de lista de reproducción."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Parar después de la canción."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Buscar entradas en la lista de reproducción activa"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3396,57 +3637,61 @@ msgstr ""
"mayúsculas de minúsculas. Si no sabe como funcionan las expresiones "
"regulares, tan solo escriba la parte del literal que quiere buscar."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "TÃtulo: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Ãlbum: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Artista: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Nombre del archivo: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Limpiar la selección previa antes de buscar"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Conmutar automáticamente la cola para las entradas coincidentes"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Crear una nueva lista de reproducción con las entradas coincidentes"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Editor de listas de reproducción de Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d de %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Tema para Winamp 2.x archivado"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Tema para Winamp 2.x no archivado"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "No se pudo crear el directorio (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Plugin Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3468,85 +3713,71 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Plugin Sndfile"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Acerca del Plugin de Salida Sndio"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-"Plugin de Salida Sndio\n"
-"\n"
-"Escrito por Thomas Pfaff <tpfaff at tp76.info>\n"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "formato no soportado"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-"Un formato no soportado por el dispositivo de audio fue solicitado.\n"
-"\n"
-"Por favor,intente de nuevo con el servidor sndiod(1) ejecutándose."
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "dispositivo sndio"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(el vacÃo significa algo)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "Aceptar"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Cambio de canción"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Comando a ejecutar cuando Audacious reproduce una canción nueva."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Los parámetros enviados a la consola se deberÃan "
+"encapsular con comillas. De otra forma existe un riesgo de seguridad.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Comando:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Comando para ejecutar al final de una canción."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
msgstr ""
-"Comando para ejecutar cuando Audacious llega al final de una lista de "
-"reproducción."
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Comando para ejecutar cuando el tÃtulo cambia para una canción (es decir, "
-"tÃtulos de flujos en red)"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3560,35 +3791,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Puede usar los siguientes cadenas de formatos, las cuales\n"
-"serán reemplazadas antes de invocar al comando\n"
-"(no todos son útiles para el comando finalizar lista de reproducción):\n"
-"\n"
-"%F: Frecuencia (en hertz)\n"
-"%c: Número de canales\n"
-"%f: Nombre de archivo (ruta completa)\n"
-"%l: Duración (en milisegundos)\n"
-"%n o %s: Nombre de la canción\n"
-"%r: Velocidad (en bits por segundo)\n"
-"%t: Posición en la lista de reproducción (%02d)\n"
-"%p: Reproduciendo actualmente (1 or 0)\n"
-"%a: Artista\n"
-"%b: Album\n"
-"%T: TÃtulo de la pista"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>Los parámetros enviados a la consola se deberÃan "
-"encapsular con comillas. De otra forma existe un riesgo de seguridad.</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Comandos"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3597,51 +3809,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr ""
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Velocidad y amplitud"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Velocidad y amplitud</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Velocidad:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Amplitud:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Velocidad y amplitud"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Icono de estado"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3652,63 +3864,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Acción al desplazar rueda del mouse<b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Cambiar el volumen"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Cambiar la canción en reproducción"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Otras Opciones<b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Desactivar la ventana emergente"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Cerrar a la barra tray"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Avanzar en la lista de reproducción al desplazar arriba"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Icono de estado"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Esteréo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra Estéreo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra Esteréo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Generador de Tono"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Generador de tonos: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3717,15 +3929,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Generador de Tono"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Quitar voz"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3746,44 +3954,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Decodificador Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "Decodificador VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "Decodificador VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "Decodificador WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr ""
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr ""
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "Decodificador WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "Decodificador 2SF"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "Listas de reproducción compartidas XML (XSPF)"
diff --git a/po/es_MX.po b/po/es_MX.po
index d7c696e30ea6..f950c6fab813 100644
--- a/po/es_MX.po
+++ b/po/es_MX.po
@@ -3,14 +3,15 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# Jorge A. GarcÃa Sosa <jagsmd at gmail.com>, 2012-2014
+# Jorge A. GarcÃa Sosa <kamesennin555 at icloud.com>, 2012-2014
+# Jorge A. GarcÃa Sosa <kamesennin555 at icloud.com>, 2014-2015
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-13 16:17+0000\n"
-"Last-Translator: Jorge A. GarcÃa Sosa <jagsmd at gmail.com>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-08 19:38+0000\n"
+"Last-Translator: Jorge A. GarcÃa Sosa <kamesennin555 at icloud.com>\n"
"Language-Team: Spanish (Mexico) (http://www.transifex.com/projects/p/"
"audacious/language/es_MX/)\n"
"Language: es_MX\n"
@@ -19,40 +20,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "monoaural"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "estéreo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "envolvente"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "Descodificador AAC (MP4)"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
-msgstr "Descodificador AAC(RAW)"
+msgstr "Decodificador AAC (RAW)"
+
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (Reproductor AdLib)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "secuencializado"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (Reproductor AdLib)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarma"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "Programar Alarma ..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -63,11 +52,7 @@ msgstr ""
"\n"
"Orignalmente escrito por Adam Feakin y Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarma"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -109,7 +94,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -149,7 +134,7 @@ msgstr ""
" Ejecuta este comando a la hora de la alarma.\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -173,384 +158,390 @@ msgstr ""
" Escribe el recordatorio en la caja y enciende el\n"
" botón interruptor si quieres que se muestre."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Esta es tu llamada despertador."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "Tu recordatorio para hoy es..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Recordatorio"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Lunes"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Martes"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Miércoles"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Jueves"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Viernes"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Sábado"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Domingo"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Ajustes de Alarma"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "_OK"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "_Cancelar"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Tiempo"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarma a las (predeterminado):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Silenciar después de:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "horas"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minutos"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Escoge los dÃas para que suene la alarma"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "DÃa"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Predeterminado"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "DÃas"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Desvanecimiento"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "segundos"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Volumen"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Comenzar a"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Finalizar a"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Actual"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Comando Adicional"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "habilitar"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Lista de Reproducción (opcional)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Selecciona una lista de reproducción"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Opciones"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "¿Qué significan estás opciones?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Ayuda"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Portada de Ãlbum"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Arte de Ãlbum (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "Salida ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"Plugin de salida ALSA\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"Mis agradecimientos a William Pitcock, autor del plugin NG de salida ALSA, "
+"cuyo código sirvió como referencia cuando el manual ALSA no era suficiente."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(sin descripción)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Dispositivo PCM predeterminado"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Dispositivo mezclador predeterminado"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "Dispositivo PCM:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Dispositivo mezclador:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Elemento mezclador:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Evitar colapsos por falta de recursos"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (Reproductor MIDI)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"Plugin de salida ALSA\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"Reproductor modular de música MIDI\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"Mis agradecimientos a William Pitcock, autor del plugin NG de salida ALSA, "
-"cuyo código sirvió como referencia cuando el manual ALSA no era suficiente."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "Salida ALSA"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (Reproductor MIDI)"
+"escrito por Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"gracias especiales a...\n"
+"\n"
+"Clemens Ladisch y Jaroslav Kysela\n"
+"por sus chidos programas aplaymidi y amixer; estos\n"
+"fueron realmente útiles, junto con los docs alsa-lib, para\n"
+"aprender más sobre la API ALSA\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "Anular ganancia predeterminada:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "Anular polifonÃa predeterminada:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "Anular reverberación predeterminada:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "Encender"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "Anular coro predeterminado:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>Reproducir</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "Transportar:"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "semitonos"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "Cambio de baterÃa:"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>Avanzado</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "números de nota"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "Extraer comentarios del archivo MIDI"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Saltar silencio inicial"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "Extraer letras del archivo MIDI"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Saltar silencio final"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>SIntetizador</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr "Tasa de muestreo:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "Tasa de bits:"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - seleccionar archivo SoundFont"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Cancelar"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "_Abrir"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Nombre del archivo"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Tamaño (bytes)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nombre:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> Información MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Formato:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Duración (ms):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Núm. de Pistas:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variable"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Div. tiempo:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> Comentarios y Letras de canción MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* no hay comentarios disponibles en este archivo MIDI *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* no hay letras de canción disponibles en este archivo MIDI *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Cerrar"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (UTF-8 inválido)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Acerca de AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"reproductor de música MIDI modular\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"escrito por Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"agradecimientos especiales a...\n"
-"\n"
-"Clemens Ladish y Jaroslav Kysela\n"
-"por sus chidos programas aplaymidi y amixer; fueron\n"
-"realmente útiles, junto con los documentos alsa-lib,\n"
-"para aprender más de la API ALSA\n"
-"\n"
-"Alfredo Spadafina\n"
-"por el bonito logo de teclado midi\n"
-"\n"
-"Tony Vroon\n"
-"por la buena ayuda con las pruebas alfa."
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -568,154 +559,148 @@ msgstr ""
"Basado en parte en la librerÃa Ghosd de Evan Martin:\n"
"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (Mensaje en Pantalla)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Rectángulo"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Rectágulo Redondeado"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Rectángulo Cóncavo"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Ninguno"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Iniciar Reproducción"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr ""
"Muestra Notificación en Pantalla cuando se reproduce un elemento de la lista "
"de reproducción"
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Cambio de TÃtulo"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
-msgstr ""
-"Muestra el Notificación en Pantalla cuando, en la reproducción, el tÃtulo de "
-"la pista cambia pero el nombre del archivo es el mismo. Esto es muy útil "
-"para mostrar cambios de tÃtulo en streams de internet."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
+msgstr "Lanza OSD cuando el tÃtulo de pista cambia (para streams de internet)."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Pausa Encendida"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Muestra Notificación en Pantalla cuando la reproducción está pausada."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Pausa Apagada"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Muestra Notificación en Pantalla cuando la pausa termina."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Colocación"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Compensación relativa en X:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Compensación relativa en Y:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Ancho máximo de OSD:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Opciones de varios monitores"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Mostrar OSD utilizando:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "Todos los monitores"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "monitor %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Tiempo (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Mostrar:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Desvanecimiento al aparecer:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Desvanecimiento al desaparecer:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Fuentes"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Fuente %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Sombra"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Estilo de Renderización"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Colores"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Color %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Activar Aviso"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Evento"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Administrador de composición detectado"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -726,112 +711,112 @@ msgstr ""
"administrador de composición, de otra forma las Notificaciones en Pantalla "
"no funcionarán apropiadamente"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Administrador de composición no requerido para transparencia falsa"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Transparencia"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Transparencia falsa"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Transparencia real (requiere X Composite Ext.)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Extensión de composición no cargada"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Extensión de composición no disponible"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - configuración"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "_Probar"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "E_stablecer"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Posición"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animación"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Texto"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Decoración"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Avisos"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Misc."
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Probar"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "Listas de reproducción ASXv3"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "Listas de reproducción ASXv1/ASXv2"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Lista de reproducción Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Color</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Blur Scope"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Predefinidos:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Nivel de alimentación:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Frecuencia de corte:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Predefinidos:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Analizador de Espectro"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Plugin CD de Audio "
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -852,171 +837,158 @@ msgstr ""
"\n"
"Este fue un proyecto del Google Summer of Code 2007"
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Dispositivo</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Velocidad de lectura:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Reemplazar dispositivo:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadatos</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Usar CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Usar CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Utilizar HTTP en vez de CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Servidor:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Ruta de Acceso:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Puerto:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Plugin CD de Audio "
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "Falla al iniciar el susbsistema cdio."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "URI %s no válido."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Pista %d no encontrada."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "Pista %d es una pista de datos."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Falló al abrir la salida de audio."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Error al leer CD de audio."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "CD de Audio"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "Pista %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Fallo al abrir el dispositivo de CD %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "No se encontró drive de CD capaz de reproducir audio."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "Fallo al terminar de preparar drive de CD abierto."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Fallo al recuperar el primer/último número de pista."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "No se puede leer LSN inicio/final para la pista %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Fallo al crear la conexión cddb."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Fallo al consultar el servidor CDDB."
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Fallo al consultar el servidor CDDB: %s."
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Fallo al leer la nformación cddb: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "La unidad de disco está vacÃa."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Tipo de disco no soportado."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Entradas del Menú del CD de Audio"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Reproducir CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Agregar CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Entradas del Menú del CD de Audio"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Compresión</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Centrar volumen:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Rango dinámico:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Plugin de Compresión de Rango Dinámico para Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Plugin de Compresión de Rango Dinámico para Audacious\n"
+"Copyright 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Compresor de Rango Dinámico"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1025,214 +997,246 @@ msgid ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
msgstr ""
-"Motor de descodificador de música de consola basado en Game_Music_Emu 0.5.2\n"
+"Motor decodificador de música de consola basado en Game_Music_Emu 0.5.2\n"
"Formatos soportados: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM,VGZ\n"
"\n"
"Plugin para Audacious por:\n"
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Bajos: "
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Agudos"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "Eco:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Duración de pista predeterminada:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>Resampling</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Habilitar resampling de audio"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Frecuencia de resampling:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ignorar duración proveniente de las etiquetas SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Aumentar reverberación"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
-msgstr "Descodificador de Música de Consolas de Juego"
+msgstr "Decodificador de Música de Consolas de Juego"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"Los fundidos fallaron porque las pistas tienen un número diferente de "
-"canales. Puedes usar el Mezclador de Canales para convertir las pistas al "
-"mismo número de canales."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "Salida CoreAudio"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"Los fundidos fallaron porque las pistas tienen diferentes tasas de bitis. "
-"Puedes usar el Convertidos de Tasas de Bits para convertir las pistas a la "
-"misma tasa."
+"Plugin CoreAudio Output para Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Basado en el Plugin de Salida SDL para Audacious\n"
+"Copyright 2010 John Lindgren"
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "Usar modo exclusivo"
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Crossfade Plugin para Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Plugin Crossfade para Audacious\n"
+"Copyright 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Fundido</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "Al cambio automático de pista"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "Encimar:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "Al buscar o cambio manual de pista"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Tip</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+"Para mejor desvanecimiento, habilita\n"
+"el efecto Remover Silencio."
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Fundir"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"Los fundidos fallaron porque las pistas tienen un número diferente de "
+"canales. Puedes usar el Mezclador de Canales para convertir las pistas al "
+"mismo número de canales."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"Los fundidos fallaron porque las pistas tienen diferentes tasas de bitis. "
+"Puedes usar el Convertidos de Tasas de Bits para convertir las pistas a la "
+"misma tasa."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Cristalizador</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intensidad:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Cristalizador"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Plugin Cue Sheet"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Borrar Archivos"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "Error al mover %s a la bandeja: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "Error al borrar %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "Error mientras borraba %s: no es un archivo local."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "¿Quieres mover los archivos seleccionados a la bandeja?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "Mover a la bandeja"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "¿Quieres borrar permanentemente los archivos seleccionados?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Borrar"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Cancelar"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "Borrar Archivos"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "Borrar Archivos Seleccionados"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>Borrar Método</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "Mover a la bandeja en vez de borrar inmediatamente"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+"Plugin Echo\n"
+"Por Johan Levin, 1999\n"
+"Surround echo por Carl van Schaik, 1999\n"
+"Actualizado para Audacious por William Pitcock y John Lindgren, 2010-2014"
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Eco</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Retraso:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Retroalimentación:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Volumen:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Plugin Echo \n"
-"Por Johan Levin, 1999\n"
-"\n"
-"Eco envolvente by Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Eco"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Plugin FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1241,62 +1245,62 @@ msgid ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-"Plugin descodificador de audio multi-formato para Audacious usando\n"
+"Plugin decodificador de audio multi-formato para Audacious usando\n"
"el marco multimedia FFmpeg (http://www.ffmpeg.org/)\n"
"\n"
"Plugin para Audacious por:\n"
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "Plugin FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Plugin FileWriter"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Formato del archivo de salida:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Configurar"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Guardar en el directorio original"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Guardar en un directorio personalizado"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Carpeta del archivo de salida:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Escoge una carpeta"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Obtener el nombre del archivo desde:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Generar nombre de archivo de:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "etiquetas del archivo original"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Etiqueta original del archivo"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "nombre del archivo original"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Nombre de archivo original"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "No quitar la extensión del archivo"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "Incluir extensión original del archivo"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Colocar primero el número de pista en el nombre del archivo"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr "Agregar número de pista al nombre de archivo"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1328,165 +1332,169 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA \n"
"02110-1301, USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "Plugin FileWriter"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Auto"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Estéreo Unido"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Estéreo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Monoaural"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Configuración MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_OK"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Calidad del algoritmo:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Frecuencia de muestrei de salida:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr "Tasa de Muestreo de Salida:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Relación de Tasa de bits / Compresión:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "Tasa de Bits / Relación de Compresión:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Tasa de bits (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Tasa de Compresión"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Modo de audio:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Misc.:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr "Otros:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Forzar conformidad ISO estricta"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr "Cumplir normas ISO estrictas"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Error de protección"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Calidad"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Habilitar VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tipo:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Opciones VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Tasa de bits mÃnima (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Tasa de bits máxima (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Forzar estrÃctamente tasa de bits mÃnima"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Opciones ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Promedio de tasa de bits (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "Nivel de calidad VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "No escribir encabezado VBR Xing"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Omitir encabezado VBR Xing"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "Parametros de Marco:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr "Parámetros de Marco:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Marcar como copyright"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Marcar como original"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "Parámetros ID3:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Forzar adición de etiquetas versión 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Sólo agrega etiqueta v1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Sólo agrega etiqueta v2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Etiquetas"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Configuración del codificador Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Nivel de calidad (0-10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "Decodificador FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "sin pérdida"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1498,11 +1506,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "Descodificador FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1510,11 +1514,19 @@ msgstr ""
"Plugin GIO para Audacious\n"
"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "Plugin GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "Modo leer-y-anexar no soportado"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "modo abierto invalido"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1534,534 +1546,620 @@ msgstr ""
"\n"
"Licencia: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "Analizador de Espectro OpenGL"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+"OpenGL Spectrum Analyzer para Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, y Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Basado en el plugin XMMS:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, y "
+"4Front Technologies\n"
+"\n"
+"Licencia: GPLv2+"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "Analizador de Espectro OpenGL (Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "Atajos GNOME"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-"Plugin de Atajos Gnome\n"
-"Te permite controlar el reproductor con los atajos de Gnome.\n"
+"Plugin de Atajos GNOME\n"
+"Te permite controlar el reproductor con atajos de GNOME's.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Atajos Gnome"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Número de entrada"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "TÃtulo"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Artista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Año"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Ãlbum"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Artista de Ãlbum"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Pista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Género"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Posición en cola"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Duración"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Ruta del archivo"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Nombre del archivo"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "TÃtulo personalizado"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Tasa de bits"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "Columnas disponibles"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "Columnas mostradas"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Herramienta de Búsqueda"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Acoplar a la izquierda"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Acoplar a la derecha"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Acoplar arriba"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Acoplar abajo"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Desacoplar"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Dehabilitar"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Herramienta de Búsqueda"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Abrir archivos..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Abrir _URL..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "A_gregar archivos..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Agregar U_RL..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "Buscar en Bib_lioteca"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "A_cerca..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "_Ajustes"
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Salir"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Reproducir"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Pa_usa"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Detener"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_Anterior"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "Siguie_nte"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "Repe_tir"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "A_leatorio"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "_No avanzar Lista de Reprod."
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Detener D_espués de Esta Pista"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Información de pista..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Saltar al _tiempo"
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "Saltar a la _pista"
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "Configura Punto _A de Repetición"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "Configura Punto _B de Repetición"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_Borrar Puntos de Repetición"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Por _TÃtulo"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr "Por _Nombre de Archivo"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Por _Ruta de Archivo"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Por _Núm de pista"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Por_Artista"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Por Al_bum"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Por Artista de Ãlbu_m"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Por _Fecha de Lanzamiento"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "Por _Género"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "Por _Duración"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Por _Ruta del Archivo"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Por TÃtulo _Personalizado"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "_Invertir Orden"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "O_rden Aleatorio"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_Reproducir esta Lista de Reproducción"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_Reproducir/Reanudar"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "A_ctualizar"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Ordenar"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "Ordenar Se_leccionados"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "Remover _Duplicados"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Remover Archivos No _Disponibles"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Nuevo"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "Ren_ombrar ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "Remo_ver"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importar..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Exportar..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "Ad_ministrador de Listas de Reproducción ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Administrador de _Colas ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "_Aumentar Volumen"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "_Disminuir Volumen"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Ecualizador"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "E_fectos ..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Mostrar Barra de _Menú"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Mostrar Barra de I_nformación"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Mostrar Barra de Información de Vis_ualización"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Mostrar Barra de E_stado"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Mostrar Tiempo _Restante"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "_Visualizaciones ..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Archivo"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Reproducción"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Lista de Reproducción"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Servicios"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Salida"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Ver"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Formar/Desformar"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "A_brir Carpeta Contenedora"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Cor_tar"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Copiar"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Pegar"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Seleccion_ar todo"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_Renombrar ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>Pestañas de Listas de Reproducción</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "Siempre mostrar pestañas"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "Mostrar total de entradas"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "Mostrar botones para cerrar"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>Columnas de Listas de Reproducción</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "Mostrar encabezados de columna"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Misceláneo</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr "Teclas de flechas buscan por:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "Desplazar al cambiar de pista"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "Interfaz GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Almacenando en buffer..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "monoaural"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "estéreo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d canal"
msgstr[1] "%d canales"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Modo sencillo."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Modo Lista de Reproducción."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Detener después de la pista."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Pista previa"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Reproducir"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pausa/Continuar"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Detener"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Pista siguiente"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "Avanza 5 segundos"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "Retrocede 5 segundos"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Silenciar"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Aumentar volumen"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Disminuir volumen"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Saltar al archivo"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "Cambiar ventana(s) del reproductor"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Mostrar Notificaciones en Pantalla"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "Repetir"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "Aleatorio"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "Detener después de actual"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Aumentar ventanas(s) del reproductor"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(ninguno)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2072,15 +2170,11 @@ msgstr ""
"\n"
"¿Quieres continuar?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Asociar botones del ratón"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Configuración del Plugin Global Hotkey"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2088,23 +2182,27 @@ msgstr ""
"Presiona una combinación de teclas dentro de un campo de texto.\n"
"También puedes asociar botones del ratón."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Atajos del teclado:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Acción:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Asociación de Teclas:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "_Agregar"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Hotkeys Globales"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2131,60 +2229,57 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Hotkeys Globales"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "Salida JACK"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "Conectar a todos los puertos disponibles"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "Automáticamente conectar a puertos de salida"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "Conectar solo a los puestos de salida"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr ""
+"Solo %d puertos de salida JACK fueron encontrados pero %d son requeridos."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "No conectar a ningún puerto"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Falla al conectar al puerto JACK %s."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "Modo de conexión:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+"JACK solo soporta audio de punto flotante. Debes cambiar la profundidad de "
+"bit de salida a punto flotante en las preferencias de Audacious."
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "Habilitar impresión para depuración"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "Falla al conectar al servidor JACK; ¿Se está ejecutando?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Basado en xmms-jack, por Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Llevado a Audacious por Giacomo Lozito"
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "Salida JACK"
+"El servidor JACK requiere una tasa de muestra de %d Hz, pero audacious está "
+"reproduciendo a %d Hz. Por favor utiliza el efecto de Convertidor de Tasa de "
+"Muestra para corregir la discordancia."
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "Ajustes %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Ajustes del Host LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Rutas de Módulos:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2195,73 +2290,41 @@ msgstr ""
"Después de agregar nuevas rutas, presiona Intro para buscar plugins nuevos.</"
"small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Plugins disponibles:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Habilitar"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Habilitar plugins:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Ajustes"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
-"LADSPA Host for Audacious\n"
-"Copyright 2011 John Lindgren"
-msgstr ""
-"LADSPA Host para Audacious\n"
-"Copyright 2011 John Lindgren"
-
-#: src/ladspa/plugin.c:676
-msgid "LADSPA Host"
-msgstr "Huesped LADSPA"
-
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: No se puede iniciar soporte LIRC\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: no se pudo leer archivo de configuración LIRC\n"
-"%s: Por favor, lee la documentación de LIRC\n"
-"%s: cómo crear un archivo de configuración LIRC adecuado\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: intentando reconectar...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: comando desconocido \"%s\"\n"
+"LADSPA Host for Audacious\n"
+"Copyright 2011 John Lindgren"
+msgstr ""
+"LADSPA Host para Audacious\n"
+"Copyright 2011 John Lindgren"
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: desconectado de LIRC\n"
+#: src/ladspa/plugin.h:78
+msgid "LADSPA Host"
+msgstr "Huesped LADSPA"
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: se intentará reconectar cada %d segundos...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Plugin LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2290,73 +2353,81 @@ msgstr ""
"\n"
"Para más información acerca de LIRC, ve a http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Conexión</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Reconectar a servidor LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Espera entes de reconectar:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Plugin LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "Plugin LyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Letras de canción no disponibles"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Error"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Incapaz de traer %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Error"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Incapaz de analizar %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Buscando letras de canción ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Sin metadatos de pista"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Conectando a lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "Plugin LyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "Plugin LyricWiki (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "Listas de Reproducción M3U"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Generador Tact"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Generador de tact: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Generador de tact: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2370,11 +2441,11 @@ msgstr ""
"por ejemplo, tact://77 to reproducir 77 golpes por minuto\n"
"o tact://60*3/4 para reproducir 60 bpm en ritmo 3/4"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Generador Tact"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Mezclador de Canales"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2382,152 +2453,184 @@ msgstr ""
"Plugin Mezclador de Canales para Audacious.\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Mezclador de Canales</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Canales de salida:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Mezclador de Canales"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "Plugin MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "Error al conectar al servidor MMS"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (reproducor Module)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>Resolución</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Canales</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "Más cercano (más rápido)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Linear (rápido)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Ranura (bueno)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "Polifase (mejor)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>Frecuencia de muestreo</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr "<b>Tasa de Muestreo</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Nivel:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "Corte:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Reverberación</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>Bass Boost</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>Envolvente</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>Preamplificador</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "Sobremuestra"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Reducción de ruido"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Reproducir MODs Amiga"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Repetir</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "Cuenta de repetición:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "Para repetir por siempre, coloca la cuenta de repetición en -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (reproducor Module)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Envolvente"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "Estos ajustes tomarán efecto cuando Audacious reinicie."
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "Plugin MPG123"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Avanzado</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Usar el cálculo preciso de longitud (lento)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Envolvente"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "Servidor MPRIS 2"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Plugin Neon HTTP/HTTPS"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "Error al analizar redirección"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Error HTTP desconocido"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "Error al analizar URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Demasiadas redirecciones"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Detenido"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious no está reproduciendo."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Notificaciones en Escritorio"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2563,55 +2666,64 @@ msgstr ""
"DeberÃas haber recibido una copia de la GNU General Public License junto con "
"este programa. Si no, mira en <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Mostrar los controles de reproducción"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Siempre mostrar la notificación"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Notificaciones en Escritorio"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "Incluir nombre del álbum en la notificación"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Mostrar"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pausa"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Siguiente"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Dispositivo predeterminado"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "Salida OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "Salida OSS3"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Dispositivo por default"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Dispositivo de audio:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Usar dispositivo alterno:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Guardar volumen entre sesiones."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Habilitar las conversiones de formato hechas por el software OSS."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Habilitar modo exclusivo para prevenir mezclado virtual."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2625,19 +2737,35 @@ msgstr ""
"Me gustarÃa agradecer a la ente de #audacious, especialmente a Tony Vroon y "
"John Lindgren y por supuesto a los autores del plugin OSS anterior."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "Salida OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Administrador de Lista de Reproducción"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Entradas"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Remover"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "Ren_ombrar"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "Listas de reproducción PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
-msgstr "Descodificador OpenPSF PSF1/PSF2"
+msgstr "Decodificador OpenPSF PSF1/PSF2"
+
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "Salida PulseAudio"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2673,11 +2801,73 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA \n"
"02110-1301, USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "Salida PulseAudio"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "Salida QtMultimedia"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"Plugin de salida de Audio QtMultimedia para Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Basado en el Plugin de Salida SDL para Audacious\n"
+"Copyright 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Trabajando ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Buscar"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_Abrir Carpeta ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_Agregar Carpeta ..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "_Inspector de Registro ..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Abrir Archivos"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Agregar Archivos"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Anterior"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Repetir"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Aleatorio"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Interface Qt"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Convertidor de tasa de muestra"
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2685,99 +2875,107 @@ msgstr ""
"Plugin Sample Rate Converter para Audacious\n"
"Copyright 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "Saltar/repetir muestras"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Interpolación linear"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Interpolación de sincronización rápida"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "Interpolación de sincronización media"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Mejor Interpolación de sincronización"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Conversión</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Método:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Tasa:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Mapeos de Tasas</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Usar mapeos de tasas"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Convertidor de tasa de muestra"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "OK. Agregando datos -scrobbling- para usuario: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "Permiso Denegado"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"Accede al siguiente vÃnculo para permitir que Audacious agregue datos -"
"scrobble- a tus reproducciones:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"Mantiene esta ventana abierta y da clic en 'Verificar Permiso' otra vez.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2785,34 +2983,38 @@ msgstr ""
"No te preocupes. Tus datos agregados han sido guardados en tu computadora.\n"
"Ellos serán enviados tan pronto como a Audacious le sea permitido hacerlo."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "Problema de Red."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "Hay un problema contactando Last.fm. Por favor, intenta después."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "Verificando..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "V_erificar Permiso"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_Revocar Permiso"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"Necesitas permitir que Audacious transfiera los metadatos de las pistas "
"\"scrobblee\" a tu cuenta Last.fm\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2820,7 +3022,7 @@ msgstr ""
"El plugin Scrobbler no pudo ser iniciado.\n"
"Puede haber un problema con tu instalación."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2837,11 +3039,7 @@ msgstr ""
"Gracias a John Lindgren por echárme una mano al comienzo de este proyecto.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2849,7 +3047,11 @@ msgstr ""
"Audacious está usando ahora una versión mejorada de Last.fm Scrobbler.\n"
"Por favor revisa las Preferencias para el plugin Scrobbler."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "Salida SDL"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2857,81 +3059,56 @@ msgstr ""
"Plugin de salida SDL para Audacious\n"
"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "Salida SDL"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "LibrerÃa"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Artista Desconocido"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Ãlbum Desconocido"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-"en %s de %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d resultado"
+msgstr[1] "%d resultados"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d álbum"
-msgstr[1] "%d álbumes"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d oculto)"
+msgstr[1] "(%d ocultos)"
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-"%s, %d pista"
-msgstr[1] ""
-"%s\n"
-"%s, %d pistas"
-
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-"%d canción de %s"
-msgstr[1] ""
-"%s\n"
-"%d canciones de %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d pista"
+msgstr[1] "%d pistas"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "de este género"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "en"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "por"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Crear Lista de Reproducción"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Agregar a la Lista de Reproducción"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Buscar librerÃa"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2939,679 +3116,771 @@ msgstr ""
"Para importar tu librerÃa de música en Audacious, selecciona una carpeta y "
"luego haz clic en el Ãcono \"actualizar\"."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Por favor espere..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Seleccione Carpeta"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "Reproductor SID"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>Salida</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Canales:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Emulación</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "Emular MOS 8580 (default: MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "No seleccionar automáticamente modelo de chip"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Emular filtro"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Velocidad de reloj:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "No seleccionar automáticamente vel. de reloj"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>Tiempo de reproducción</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "Establecer tiempo máx. de reprod.:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Usar solo cuando la duración de pista es desconocida"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "Establecer tiempo mÃnimo de reprod.:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Subtonos</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "Habilitar subtonos"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "Ignorar subtonos más cortos que:"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Nota</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Remover Silencio"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"Plugin Remover Silencio para Audacious\n"
+"Copyright 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Remover Silence</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Umbral:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "Abrir Archivos ..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "Abrir URL ..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Buscar LibrerÃa"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Reproducción"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Lista de Reproducción"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Ver"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "Servicios"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "Acerca ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "Ajustes ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "Salir"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "Información de Pista ..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Repetir"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Aleatorio"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "No avanzar Lista de Reproducción"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "Detener Al Terminar Esta Pista"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Anterior"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "Establecer Repetición A-B"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "Limpiar Repetición A-B"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "Saltar a la Pista ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "Saltar al Tiempo ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "Reproducir Esta Lista de Reproducción"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "Reproducir/Reanudar"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Nueva Lista de Reproducción"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "Renombrar Lista de Reproducción"
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "Remover Lista de Reproducción"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "Lista de Reproducción Previa"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "Siguiente Lista de Reproducción"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "Importar Lista de Reproducción ..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "Exportar Lista de Reproducción ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "Administrador de Listas de Reproducción ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "Administrador de Fila ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "Refrescar Lista de Reproducción"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Mostrar Editor de Listas de Reproducción"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Mostrar Ecualizador"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "Mostrar Tiempo Restante"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Siempre Encima"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "En Todas Las Ãreas de Trabajo"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "Enrollar Reproductor"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "Enrollar Editor de Listas de Reproducción"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "Enrollar Ecualizador"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Tamaño Doble"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "Agregar URL ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "Agregar Archivos ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Por TÃtulo"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "Por Nombre de Archivo"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "Por Ruta de Archivo"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Quitar Todo"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Limpiar Cola de reproducción"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Remueve los Archivos No Disponibles"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Remover Duplicados"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Remover No Seleccionados"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Remover Seleccionados"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Buscar y Seleccionar"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Invertir Selección"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Selecciona ninguno"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Selecciona Todo"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Por Ãlbum"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Por Número de Pista"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Por Artista"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Por Ãlbum"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Por Artista de Ãlbum"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "Por Fecha de Lanzamiento"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Por Número de Pista"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "Por Género"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "Por Duración"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "Por TÃtulo Personalizado"
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Aleatorizar Lista"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Invertir Lista"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Ordenar Seleccionado"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Ordenar Lista"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Cortar"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Copiar"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Pegar"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "A la Fila/Quitar de la Fila"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "Cargar Preajuste ..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "Cargar Preajuste Automático ..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "Cargar Predeterminado"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "Cargar Archivo de Preajuste ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "Cargar Archivo EQF ..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "Guardar Preajuste ..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "Guardar Preajuste Automático ..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "Guardar Predeterminado"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "Guardar Archivo de Preajuste ..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "Guardar Archivo EQF ..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "Borrar Preajuste ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "Borrar Preajuste Automático ..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "Importar Preajustes de Winamp ..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "Restablecer a Cero"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Interface Clásica de Winamp"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Guardar"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Cargar"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "Cargar Archivo de Preajuste"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "Cargar Archivo EQF"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "Guardar Archivo de Prejuste"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "Guardar Archivo EQF"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "Importar Preajuste de Winamp"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Presets"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Cargar preset"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Cargar auto-preset"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Guardar preset"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Guardar auto-preset"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Borrar preset"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Borrar auto-preset"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "Re_productor"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Reproductor:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Selecciona la fuente de la ventana principal del reproductor:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Lista de Reproducción:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Lista de reproducción:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Selecciona la fuenta de la lista de reproducción:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>Piel</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>Fuentes</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Usar fuentes de mapa de bits (únicamente soporta ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "Desplazar tÃtulo de pista"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Desplaza el tÃtulo de la pista en ambas direcciones"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analizador de Espectro"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Osciloscopio"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "Espectrograma vocal / medidor VU"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Apagado"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normal"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Fuego"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "LÃneas verticales"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "LÃneas"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Barras"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Muy lento"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Lento"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Medio"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Rápido"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Muy rápido"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "Puntos"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "LÃnea"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "Sólido"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Hielo"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Suave"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>Tipo</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "Tipo de visualización:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>Analizador</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "Mostrar picos"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "Colorear:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "Estilo:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "CaÃda:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "CaÃda de pico:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "Estilo del Analizador de Espectro:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "Color del Espectrograma vocal:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "Estilo del medidor VU:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "General"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualización"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Preamplificación"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Ecualizador de Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Saltar a %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Volumen: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balance: %d%% izquierda"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balance: central"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balance: %d%% derecha"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Menú de Opciones"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Deshabilitar 'Siempre Encima'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Habilitar 'Siempre Encima'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Caja de Información del Archivo"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "Visualizaciones"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "Repite punto A configurado."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "Repite punto B configurado."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "Repite puntos borrados."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Modo sencillo."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Modo Lista de Reproducción."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Detener después de la pista."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Buscar entradas en la lista de reproducción activa"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "Buscar"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3623,57 +3892,61 @@ msgstr ""
"minÃsculas indiscriminadas. Si no sabes como trabajan las expresiones "
"regulares, simplemente inserta una porción literal de lo que buscas."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "TÃtulo: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr "TÃtulo:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Ãlbum: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr "Ãlbum:"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Artista: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr "Artista:"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Nombre de Archivo: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Nombre de Archivo:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Limpiar selección previa antes de buscar"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Cambiar automáticamente la cola para las entradas coincidentes"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Crear una nueva lista de reproducción con las entradas coincidentes"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Editor de Listas de Reproducción de Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d de %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Skin de Winamp 2.x comprimida"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Skin de winamp 2.x sin comprimir"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "No se puede crear el directorio (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Plugin Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3714,85 +3987,73 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA \n"
"02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Plugin Sndfile"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Acerca del Plugin de Salida Sndio"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Salida Sndio"
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Plugin de Salida Sndio\n"
-"\n"
-"Escrito por Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "Dispositivo (en blanco para predeterminado):"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Formato no soportado"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Guardar y restaurar volumen:"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"Fue solicitado un formato no soportado por el dispositivo de audio.\n"
-"\n"
-"Por favor, intenta nuevamente con el servidor sndio(1) ejecutándose."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Error Sndio: Formato de audio no soportado (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "dispositivo sndio"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Error Sndio: falló sio_open()"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(vacÃo significa predeterminado)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Error Sndio: falló sio_setpar()"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Error Sndio error: falló sio_start()"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Cambiar Pista"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Comando para ejecutar cuando Audacious comience una nueva pista."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Parámetros enviados al shell deberán ser encapsulados en "
+"apóstrofes. Hacer otra cosa es un riesgo de seguridad.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Comandos</b>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Comando:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Comando para ejecutar cuando inicie una nueva pista:"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Comando para ejecutar al final de una pista."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Comando para ejecutar al finalizar una pista:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr ""
-"Comando para ejecutar cuando Audacious alcance el final de una lista de "
-"reproducción."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Comando para ejecutar al finalizar una lista de reproducción:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Comando para ejecutar cuando el tÃtulo de una pista cambie (por ejemplo, "
-"tÃtulos de flujos de red)."
+"Comando para ejecutar cuando el tÃtulo de pista cambie (para transmisión por "
+"red):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3806,34 +4067,31 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Puedes usar las siguiente cadenas de formato las\n"
-"cuales serán sustituidas antes de llamar al comando\n"
-"(no todas son útiles para el comando end-of-playlist):\n"
+"Puedes usar los siguientes formatos de cadena que serán sustituidos antes de "
+"llamar\n"
+"al comando (no todos son útiles para el comando al finalizar lista de "
+"reproducción):\n"
"%F: Frecuencia (en hertz)\n"
"%c: Número de canales\n"
-"%f: Nombre de archivo (ruta completa)\n"
+"%f: Nombre del archivo (ruta completa)\n"
"%l: Duración (en milisegundos)\n"
-"%n: o %s: Nombre de pista\n"
+"%n o %s: Nombre de pista\n"
"%r: Tasa (en bits por segundo)\n"
-"%t: Posición en la lista de reproducción (%02d)\n"
+"%t: Posición en Lista de Reproducción (%02d)\n"
"%p: Actualmente reproduciendo (1 ó 0)\n"
"%a: Artista\n"
"%b: Ãlbum\n"
"%T: TÃtulo de pista"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>Parámetros enviados al shell deberán ser encapsulados en "
-"apóstrofes. Hacer otra cosa es un riesgo de seguridad.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Info. de Pista (Qt)"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Comandos"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX Resampler"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3847,51 +4105,51 @@ msgstr ""
"Basado en el Plugin Sample Rate Coverter\n"
"Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Rápido"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Bajo"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Alto"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Muy Alto"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Calidad:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Velocidad y Tono"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Velocidad y Tono</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Velocidad:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Tono:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Velocidad y Tono"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Ãcono de Estado"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "Ajus_tes ..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3909,39 +4167,39 @@ msgstr ""
"Este plugin provee un Ãcono de estado, colocado en el área \n"
"de la bandeja del sistema del administrador de la ventana."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Acción de rueda central del mouse</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Cambiar volumen"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Cambiar pista en reproducción"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Otras Configuraciones</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Deshabilitar la ventana emergente"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Cerrar a la bandeja del sistema"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Avanzar en la lista de reproducción cuando se desplace hacia arriba"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Ãcono de Estado"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Estéreo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3951,24 +4209,24 @@ msgstr ""
"\n"
"Por Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra Estéreo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra Estéreo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Generador de Tonos"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Generador de tonos: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3983,15 +4241,11 @@ msgstr ""
"por ejemplo, tone://2000;2005 to reproducir un tono de2000 Hz tone y un tono "
"de 2005 Hz"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Generador de Tonos"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Removedor de Voz"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4011,7 +4265,7 @@ msgid ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-"Descodificador Audacious Ogg Vorbis\n"
+"Decodificador Audacious Ogg Vorbis\n"
"\n"
"Basado en el Plugin Ogg Vorbis de Xiph.org Foundation:\n"
"http://www.xiph.org/\n"
@@ -4029,11 +4283,46 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
-msgstr "Descodificador Ogg Vorbis"
+msgstr "Decodificador Ogg Vorbis"
+
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Detalles sobre %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"TÃtulo: %t\n"
+"Autor: %a\n"
+"De: %f\n"
+"Tracker: %T\n"
+"Comentario: %C\n"
+"Tipo de Chip: %c\n"
+"Estéreo: %s\n"
+"Loop: %l\n"
+"Frec. de Chip: %F\n"
+"Frec. de Reprod: %P\n"
+"Año: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "Decodificador VTX"
-#: src/vtx/vtx.c:167
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4044,19 +4333,19 @@ msgstr ""
"Basado en in_vtx.dll por Roman Sherbakov <v_soft at microfor.ru>\n"
"Plugin para Audacious por Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "Descodificador VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "Decodificador WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "con pérdida (hÃbrido)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "con pérdida"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4066,23 +4355,18 @@ msgstr ""
"\n"
"Algo del código del plugin era de Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "Descodificador WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
-msgstr "Descodificador 2SF"
-
-#: src/xspf/xspf.c:438
-msgid "XML Shareable Playlists (XSPF)"
-msgstr "Listas de Reprod. XML Compartibles (XSPF)"
+msgstr "Decodificador 2SF"
-#~ msgid "32.0 kHz:"
-#~ msgstr "32.0 kHz:"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>Configuración XSF</b>"
-#~ msgid "88.2 kHz:"
-#~ msgstr "88.2 kHz:"
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Ignorar duración del archivo"
-#~ msgid "176.4 kHz:"
-#~ msgstr "176.4 kHz:"
+#: src/xspf/xspf.cc:89
+msgid "XML Shareable Playlists (XSPF)"
+msgstr "Listas de Reprod. XML Compartibles (XSPF)"
diff --git a/po/et.po b/po/et.po
index 942eef4cc8e6..56859149b6e8 100644
--- a/po/et.po
+++ b/po/et.po
@@ -7,11 +7,11 @@
# Ivar Smolin <okul at linux.ee>, 2012
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Estonian (http://www.transifex.com/projects/p/audacious/"
"language/et/)\n"
"Language: et\n"
@@ -20,51 +20,35 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr ""
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
+#: src/aac-raw/aac.cc:18
+msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/aac-raw/aac.c:476
-msgid "AAC (Raw) Decoder"
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr ""
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr ""
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Ãratus"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Ãratus"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -87,7 +71,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -109,7 +93,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -123,360 +107,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "See on sinu äratus."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr ""
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Meeldetuletaja"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Esmaspäev"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Teisipäev"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Kolmapäev"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Neljapäev"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Reede"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Laupäev"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Pühapäev"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Ãratuste sätted"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Aeg"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Vaikimisi äratuskell:"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr " "
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Vaigistamine pärast:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "tundi"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minutit"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Vali päevad, mil äratus tööle hakkab"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Päev"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Vaikimisi"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Päevad"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Sumbumine"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "sekundit"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Valjus"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Alguses"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Lõpuks"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Praegune"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Täiendav käsk"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "lubatud"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Esitusnimekiri (valikuline)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr ""
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Valikud"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Mida need valikud tähendavad?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Abi"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Albumi graafika"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr ""
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Vaikimisi PCM-seade"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Vaikimisi mikserseade"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM-seade:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Miksimisseade:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Miksimiselement:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
msgstr ""
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr ""
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - SoundFont faili valimine"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "Failinimi"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "Faili nimi"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Suurus (baitides)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nimi:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI-andmed </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Vorming:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Kestus (msek):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI kommentaarid ja laulusõnad </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* selles MIDI-failis pole kommentaare *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* selles MIDI-failis pole laulusõnu *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "Sul_ge"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (vigane UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -487,263 +477,258 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr ""
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Ristkülik"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Ãmarnurkne ristkülik"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Nõgus ristkülik"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Puudub"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Esitamise alustamine"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "OSD käivitamine loo esitamisel esitusnimekirjast."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Pealkirja muutumine"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"OSD käivitamine kui esitamise ajal loo pealkiri muutub, kuid esitatav fail "
-"või andmevoog jääb samaks. See on kasulik internetiraadiote puhul."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Pausimine"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "OSD käivitamine loo pausimisel."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Pausi lõpetamine"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "OSD käivitamine pausitud loo jätkamisel."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Paigutus"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Suhteline nihe X-teljel:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Suhteline nihe Y-teljel:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Suurim OSD laius:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Mitme monitori valikud"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "OSD kuvatakse:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "kõigil monitoridel"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "%i. monitoril"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Ajastus (millisekundites)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Kuvamine:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Sujuv näitamine:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Sujuv peitmine:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Kirjatüübid"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Kirjatüüp %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Vari"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Renderdamise laad"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Värvused"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Värvus %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Päästik on lubatud"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Sündmus"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr ""
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
"manager otherwise the OSD won't work properly"
msgstr ""
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr ""
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Läbipaistvus"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Võltsitud läbipaistvus"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Tegelik läbipaistvus (vajab X Composite laiendust)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr ""
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr ""
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audaciouse OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - sätted"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Asukoht"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animatsioon"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Tekst"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Kaunistused"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Päästikud"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Muu"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2-esitusnimekirjad"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audaciouse esitusnimekirjad (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr ""
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr ""
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
-msgstr ""
-
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
msgstr ""
-#: src/bs2b/plugin.c:166
+#: src/bs2b/plugin.cc:129
msgid "Presets:"
msgstr "Valmisseadistused:"
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
msgstr ""
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr ""
+
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -755,169 +740,156 @@ msgid ""
"This was a Google Summer of Code 2007 project."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "CDDBP asemel kasutatakse HTTP-d"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Audio-CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Seade on tühi."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Plaadi liik pole toetatud."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Audioplaadi menüüvalikud"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Esita CD-lt"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Lisa CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Audioplaadi menüüvalikud"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr ""
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr ""
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr ""
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr ""
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -927,195 +899,220 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Madalad:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Kõrged:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Loo vaikimisi kestus:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr ""
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr ""
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "SPC-siltidest pärit pikkust tuleb eirata"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr ""
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Mängukonsooli muusikadekooder"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr ""
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr ""
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr ""
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr ""
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr ""
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr ""
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Kustuta"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Loobu"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Kaja</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Viivitus:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr ""
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr ""
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Kaja"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr ""
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1125,55 +1122,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
msgstr ""
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Väljundfaili vorming:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Seadista..."
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Salvestatakse algkataloogi"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Salvestatakse kohandatud kataloogi"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Väljundkataloog:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Kataloogi valimine"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Failinimi tuletatakse lähtefaili:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "siltidest"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "nimest"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Algse faili laiendit maha ei lõigata"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Failinime ette lisatakse loo number"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1191,165 +1188,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr ""
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Automaatne"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr ""
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 sätted"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Algoritmi kvaliteet:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Väljundi diskreetimissagedus:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Bitikiirus / pakkimistihedus:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Bitikiirus (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Pakkimistihedus"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Audiorežiim:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Muu:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Veakaitse"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Kvaliteet"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr ""
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Liik:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr ""
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Vähim bitikiirus (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Suurim bitikiirus (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr ""
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr ""
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Keskmine bitikiirus (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr ""
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr ""
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr ""
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr ""
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ID3-parameetrid:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr ""
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Lisatakse ainult v1 silt"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Lisatakse ainult v2 silt"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Sildid"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis-kodeerija sätted"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Kvaliteedi tase (0-10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr ""
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr ""
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1357,21 +1358,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr ""
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO-plugin"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1383,530 +1388,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Kirje number"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Pealkiri"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Esitaja"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Aasta"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Album"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Lugu"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Žanr"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Asukoht järjekorras"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Kestus"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Faili rada"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Faili nimi"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Kohandatud pealkiri"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Bitikiirus"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Otsinguvahend"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Doki vasakule"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Doki paremale"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Doki üles"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Doki alla"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr ""
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Keela"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Otsinguvahend"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Ava failid ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Ava _URL ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_Lisa faile ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Lisa U_RL ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "_Programmist lähemalt"
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Välju"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Esita"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "_Peata"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Seiska"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "Ee_lmine"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_Järgmine"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "Ko_rduv"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "Se_gatud"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Esitusnimekirja ei _kasutata"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "L_oo andmed ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "_Hüppa määratud ajale..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "_Vaheta lugu ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Peal_kirja järgi"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Loo _numbri järgi"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "_Esitaja järgi"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "_Väljalaske kuupäeva järgi"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "_Faili raja järgi"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Ko_handatud pealkirja järgi"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "_Pööra järjestus tagurpidi"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_Järjestus juhuslikuks"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "Esita selle _nimekirja lood"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Värskenda"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Sordi"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Ee_malda kättesaamatud failid"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Uus"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "Muu_da nime"
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Impordi ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Ekspordi ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "Esitusnimekirjade _haldur.."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Halda _järjekorda ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "_Valjemaks"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "Va_iksemaks"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Ekvalaiser"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "_Menüüriba on nähtaval"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "_Teaberiba on nähtaval"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr ""
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "_Olekuriba on nähtaval"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Fail"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Esitamine"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "E_situsnimekiri"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Teenused"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "Väl_jund"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Vaade"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Järjekorda/järjekorrast maha"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "_Lõika"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Kopeeri"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Aseta"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Val_i kõik"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_Muuda nime..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK liides"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Puhverdamine ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d kanal"
msgstr[1] "%d kanalit"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Ãhe loo režiim."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Esitusnimekirja režiim."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Seiskamine pärast loo lõppu."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr ""
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Esita"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pausimine/pausi lõpetamine"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Seiska"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr ""
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Heli tummaks"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr ""
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr ""
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr ""
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "OSD sisse-/väljalülitamine"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr ""
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1917,15 +1999,11 @@ msgstr ""
"\n"
"Kas soovid jätkata?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Hiirenuppude sidumine"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Globaalsete kiirklahvide plugina sätted"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -1933,23 +2011,27 @@ msgstr ""
"Vajuta tekstiväljal soovitud klahvikombinatsiooni.\n"
"Samamoodi saab siduda ka hiirenuppe."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Kiirklahvid:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Tegevus:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Kiirklahv:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr ""
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1964,56 +2046,51 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
msgstr ""
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr ""
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s sätted"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA hosti sätted"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Moodulite rajad:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2024,71 +2101,39 @@ msgstr ""
"radadelt.\n"
"Pärast uute radade lisamist vajuta uute pluginate otsimiseks Enterit.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Saadaolevad pluginad:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Luba"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Lubatud pluginad:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Sätted"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr ""
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: LIRC-tuge pole võimalik lähtestada\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: LIRC-seadistusfaili pole võimalik lugeda\n"
-"%s: korrektse seadistusfaili loomiseks\n"
-"%s: loe palun LIRC-dokumentatsiooni\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr ""
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: tundmatu käsk \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr ""
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr ""
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC-plugin"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2104,73 +2149,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Ãhendus</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Taasühendumine LIRC-serveriga"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Enne taasühendumist oodatakse"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC-plugin"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr ""
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Viga"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Viga"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Ãhendumine saidiga lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U-esitusnimekirjad"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr ""
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Taktigeneraator: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Taktigeneraator: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2179,162 +2232,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr ""
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Kanalimikser"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Kanalimikser</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Väljundkanalite arv:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Kanalimikser"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS-plugin"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr ""
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr ""
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr ""
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr ""
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr ""
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr ""
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
msgstr ""
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Ruumiline heli"
-
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr ""
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Ruumiline heli"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr ""
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS-plugin"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr ""
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr ""
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Töölauateavitused"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2354,55 +2439,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Töölauateavitused"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr ""
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pausi"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Järgmine"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Vaikimisi seade"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Audioseade:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Kasutatakse alternatiivset seadet:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr ""
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr ""
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2411,19 +2505,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
msgstr ""
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS-esitusnimekirjad"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr ""
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio väljund"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2443,143 +2553,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio väljund"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Eelmine"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Korduv"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Segatud"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr ""
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr ""
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr ""
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Meetod:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr ""
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr ""
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22,05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44,1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr ""
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr ""
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr ""
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2590,87 +2769,72 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL-väljund"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL-väljund"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Teek"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Tundmatu esitaja"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Tundmatu album"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d album"
-msgstr[1] "%d albumit"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "Loo _esitusnimekiri"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Lisa esitusnimekirja"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Otsing audiokogust"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2678,679 +2842,769 @@ msgstr ""
"Oma audiokogu importimiseks Audaciousesse vali kataloog ja vajuta "
"värskendamise ikoonile."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Palun oota..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Kataloogi valimine"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Esitamine"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Esitusnimekiri"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Vaade"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Korduv"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Segatud"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Esitusnimekirja ei kasutata"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Eelmine"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Uus esitusnimekiri"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Näita esitusnimekirja redaktorit"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Näita ekvalaiserit"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Alati pealmine"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Pealkirja järgi"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Failinime järgi"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Eemalda kõik"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Puhasta järjekord"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Eemalda kättesaamatud failid"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Eemalda korduvad kirjed"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Eemalda valimata kirjed"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Eemalda valik"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Otsi ja vali"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Vaheta valitud ja valimata"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Tühista valik"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Vali kõik"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Albumi järgi"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Loo numbri järgi"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Esitaja järgi"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Albumi järgi"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Loo numbri järgi"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Sega nimekiri"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Pööra järjestus ümber"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Valiku sortimine"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Nimekirja sortimine"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Lõika"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Kopeeri"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Aseta"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr ""
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Salvesta"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Laadi"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Valmisseadistused"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Valmisseadistuste laadimine"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr ""
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Valmisseadistuste salvestamine"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr ""
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Valmisseadistuse kustutamine"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr ""
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Esitaja:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr ""
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Esitusnimekiri:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Esitusnimekirja kirjatüübi valimine:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Kasutatakse rasterkirja (toetab ainult ASCII kooditabelit)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Loo nime keritakse mõlemas suunas"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analüsaator"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Skoop"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Väljas"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Tavaline"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Tuli"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Jooned"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Tulbad"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Väga aeglane"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Aeglane"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Keskmine"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Kiire"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Väga kiire"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Jää"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Pehme"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Ãldine"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualiseerimine"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr ""
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audaciouse ekvalaiser"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr ""
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Valjus: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr ""
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr ""
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr ""
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Valikute menüü"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr ""
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr ""
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr ""
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Ãhe loo režiim."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Esitusnimekirja režiim."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Seiskamine pärast loo lõppu."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Otsimine aktiivsest esitusnimekirjast"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3361,57 +3615,61 @@ msgstr ""
"kasutatakse tõstutundetut regulaaravaldise süntaksit. Kui sa pole "
"regulaaravaldistega tuttav, siis sisesta lihtsalt otsitav sõnaosa."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Pealkiri: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Esitaja: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Failinimi: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Enne otsimist nullitakse eelmine valik"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Otsingule vastavatest kirjetest luuakse uus esitusnimekiri"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audaciouse esitusnimekirja redaktor"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d/%d-st)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Arhiveeritud Winamp 2.x rüü"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Arhiveerimata Winamp 2.x rüü"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Kataloogi (%s) pole võimalik luua: %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr ""
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3433,77 +3691,72 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
msgstr ""
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
msgstr ""
-#: src/sndio/sndio.c:384
-msgid "sndio device"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "Olgu"
-
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Loovahetus"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Uue loo alustamisel käivitatav käsk:"
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Käsureaprogrammile edastatavad parameetrid tuleks "
+"paigutada jutumärkide vahele. Selle tegematajätmine võib olla turvarisk.</"
+"span>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Käsk:"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Loo lõppemisel käivitatav käsk:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "Esitusnimekirja lõppu jõudmisel käivitatav käsk:"
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Loo pealkirja muutumisel käivitatav käsk (näiteks võrguraadio pealkirja "
-"muutumisel)."
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3518,20 +3771,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>Käsureaprogrammile edastatavad parameetrid tuleks "
-"paigutada jutumärkide vahele. Selle tegematajätmine võib olla turvarisk.</"
-"span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Käsud"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3540,51 +3788,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr ""
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Olekuikoon"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3595,63 +3843,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Hiireratta kerimine</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Muudab valjust"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Vahetab esitatavat lugu"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Muud sätted</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Hüpikaken on keelatud"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Sulgemine süsteemisalve"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Olekuikoon"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr ""
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr ""
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr ""
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Toonigeneraator"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Toonigeneraator: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3660,15 +3908,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Toonigeneraator"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Hääle eemaldamine"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3689,44 +3933,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis dekooder"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX-dekooder"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX-dekooder"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack dekooder"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr ""
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr ""
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack dekooder"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF-dekooder"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "Jagatavad XML-esitusnimekirjad (XSPF)"
diff --git a/po/eu.po b/po/eu.po
index a5569c513157..4f20cc7ef02a 100644
--- a/po/eu.po
+++ b/po/eu.po
@@ -3,16 +3,16 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# asier <asier.fernandez.iribar at gmail.com>, 2013
+# asier fernandez iribar <asier.fernandez.iribar at gmail.com>, 2013
# Iñaki Larrañaga Murgoitio <dooteo at euskalgnu.org>, 2009
# Osoitz <oelkoro at gmail.com>, 2012
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Basque (http://www.transifex.com/projects/p/audacious/"
"language/eu/)\n"
"Language: eu\n"
@@ -21,51 +21,35 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "monoa"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "estereoa"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "surround"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
+#: src/aac-raw/aac.cc:18
+msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/aac-raw/aac.c:476
-msgid "AAC (Raw) Decoder"
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr ""
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr ""
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarma"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarma"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -88,7 +72,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -110,7 +94,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -124,360 +108,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Hau da zure esnatzeko deia:"
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr ""
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Gogorarazlea"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Astelehena"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Asteartea"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Asteazkena"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Osteguna"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Ostirala"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Larunbata"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Igandea"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Alarmaren ezarpenak"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Denbora"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarma noiz (lehenetsia):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "o"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Isildu hau eta gero:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "orduak"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minutuak"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Aukeratu alarmak jotzeko egunak"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Eguna"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Lehenetsia"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Egunak"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Progresioa"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "segundo"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Bolumena"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Hasi hemen "
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Bukaeran"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Oraingoa"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Komando gehigarria"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "gaitu"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Erreprodukzio-zerrenda (aukerazkoa)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr ""
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Aukerak"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Zer esan nahi dute aukera hauek?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Laguntza"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Diskoaren azala"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr ""
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Lehenetsitako PCM gailua"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Lehenetsitako nahaslea"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM gailua:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Nahastailearen gailua:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Nahaslea:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
msgstr ""
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr ""
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - hautatu SoundFont fitxategia"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "Fitxategi-Izena"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "Fitxategi izena"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Tamaina (byte)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Izena:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI informazioa </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Formatua:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Luzera (mseg.):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Pista kopurua:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "aldagaia"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Denbora zat:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI iruzkinak eta letrak </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* iruzkinik ez dago erabilgarri MIDI fitxategi honetan *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* letrarik ez dago erabilgarri MIDI fitxategi honetan *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (UTF-8 baliogabea)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -488,153 +478,147 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr ""
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Laukizuzena"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Laukizuzen biribildua"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Laukizuzen ahurra"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Bat ere ez"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Erreprodukzioa hasi"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr ""
"OSDa abiarazten du erreprodukzio-zerrendako sarrera bat erreproduzitzean."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Titulu aldaketa"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"OSDa abiarazten du erreproduzitzean abestiaren titulua aldatzen bada, baina "
-"fitxategi-izena berdina bada. Interneteko korronteetan tituluen izenen "
-"aldaketak bistaratzeko da batizpat erabilgarria."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Pausatuta"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "OSDa abiarazten du erreprodukzioa pausatzean."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Jarraitu"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "OSDa abiarazten du erreprodukzioa jarraitzean."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Kokalekua"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "X desplazamendu erlatiboa:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Y desplazamendu erlatiboa:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "OSDaren gehi. zabalera:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Pantaila anitzen aukerak"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Bistaratu OSDa hau erabiliz:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "pantaila guztiak"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "%i. pantaila"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Tenporizadorea (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Bistaratu:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Pixkanaka agertu:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Iraungitu:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Letra-tipoak"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "%i letra-tipoa:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Itzala"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Errendatze estiloa"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Koloreak"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "%i kolorea:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Gaitu abiarazlea"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Gertaera"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Kudeatzaile konposatua detektatuta"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -644,112 +628,112 @@ msgstr ""
"Bat exekutatzen dagoela jakin ezean, aktibatu konposaketako kudeatzalea "
"bestela OSDak ez du ongi funtzionatuko"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Gardentasun faltsua egiteko ez da konposaketako kudeaketak behar"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Gardentasuna"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Gardentasun faltsua"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Egitako gardentasuna (Xen konposaketa hed. behar da)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Konposaketako hedapena ez da kargatu"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Konposaketako hedapena ez dago erabilgarri"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSDa</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSDa - konfigurazioa"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Posizioa"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animazioa"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Testua"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Dekorazioa"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Abiarazlea"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Hainbat"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr ""
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr ""
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr ""
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr ""
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
msgstr ""
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
msgstr ""
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
msgstr ""
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
msgstr ""
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Audio CD plugina"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -761,169 +745,156 @@ msgid ""
"This was a Google Summer of Code 2007 project."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Gailua</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadatuak</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Erabili CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Erabili CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "HTTP erabili CDDBP ordez"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Zerbitzaria:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Bidea:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Portua:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Audio CD plugina"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Audio CDa"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Unitatea hutsik dago"
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Onartu gabeko disko mota."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr ""
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Jo CDa"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Gehitu CDa"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr ""
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Konpresioa</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Bolumen zentrala:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Bitarte dinamikoa:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr ""
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -933,195 +904,220 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Baxua:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Altua:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Abestiaren luzera lehenetsia:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Gaitu audioa berriro lagintzea"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Birlagintze-tasa:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ezikusi egin SPCko etiketetako luzerari"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Handiagotu reverb-a"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Joko Kontsola Musika Deskodetzailea"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr ""
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr ""
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr ""
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr ""
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intentsitatea:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr ""
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Ezabatu"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Utzi"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Ekoa</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr ""
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Berelikatzea:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Bolumena:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg plugina"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1131,55 +1127,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg plugina"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr ""
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Irteerako fitxategi-formatua:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Konfiguratu"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Gorde jatorrizko direktorioan"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Gorde direktorio pertsonalizatuan"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Irteerako fitxategiaren karpeta:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Hautatu karpeta"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Lortu fitxategi-izena hemendik:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "jatorrizko fitxategi-etiketak"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "jatorrizko fitxategi-izena"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Ez kendu fitxategi-izenaren luzapena"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Jarri pistaren zenbakia fitxategi-izenaren aurretik"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1197,165 +1193,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr ""
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Automatikoa"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr ""
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Estereoa"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Monoa"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 konfigurazioa"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Algoritmoaren kalitatea:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Irteerako lagin-tasa:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Bit-tasa / Konpresio-tasa:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Bit-tasa (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Konpresio-tasa:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Audio modua:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Hainbat:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Derrigortu ISOa betetzen duela"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Erroreen aurkako babesa"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Kalitatea"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Gaitu VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Mota:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR aukerak:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Gutxieneko bit-tasa (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Gehienezko bit-tasa (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Derrigortu gutxieneko bit-tasa"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR aukerak:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Batez besteko bit-tasa (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR kalitate-maila:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Ez idatzi Xing VBR goiburukoa"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Markatu copyright gisa"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Markatu jatorrizko gisa"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ID3 parametroak:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Derrigortu v2 etiketa gehitzea"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Gehitu v1 etiketa soilik"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Gehitu v2 etiketa soilik"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Etiketak"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis kodetzailearen konfigurazioa"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Kalitate maila (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC Deskodetzailea"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr ""
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1363,21 +1363,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC Deskodetzailea"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO plugina"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1389,530 +1393,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Sarera zenbakia"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Titulua"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Artista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Urtea"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Diskoa"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Pista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr ""
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Ilara posizioa"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Iraupena"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Fitxategi bidea"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Fitxategi izena"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr ""
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Bit-tasa:"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr ""
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr ""
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr ""
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr ""
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr ""
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Desgaitu"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr ""
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "Ireki fitxategiak"
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Ireki BKU ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr ""
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr ""
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr ""
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "I_rten"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "Erreproduzitu"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Pausatu"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "Gelditu"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "Aurrekoa"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr ""
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr ""
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr ""
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr ""
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr ""
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr ""
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr ""
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr ""
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Pista zenbakiaren arabera"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr ""
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr ""
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr ""
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr ""
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr ""
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr ""
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr ""
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr ""
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr ""
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr ""
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr ""
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr ""
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr ""
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr ""
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_Ilara Kudeatzailea..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr ""
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr ""
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr ""
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr ""
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr ""
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr ""
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr ""
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr ""
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr ""
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr ""
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr ""
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr ""
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr ""
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Ilararatu/Ilaratik kendu"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr ""
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr ""
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr ""
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr ""
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr ""
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK Interfazea"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr ""
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "monoa"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "estereoa"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "kanal %d"
msgstr[1] "%d kanal"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Single modua."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Erreprodukzio-zerrenda modua."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Kantuaren ostean geldituko da."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr ""
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Erreproduzitu"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pausatu/jarraitu"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Gelditu"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr ""
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Mututu"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr ""
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr ""
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr ""
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Erakutsi pantaila gaineko mezuak (OSD)"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(bat ere ez)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1923,15 +2004,11 @@ msgstr ""
"\n"
"Jarraitzea nahi duzu?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Saguaren botoiak lotzea"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Laster-tekla globalen pluginaren konfigurazioa"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -1939,23 +2016,27 @@ msgstr ""
"Sakatu tekla konbinazioa testu-eremuaren barruan.\n"
"Saguaren botoiak ere lotu ditzakezu."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Laster-teklak"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Ekintza:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Tekla-konbinazioa:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr ""
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1970,56 +2051,51 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
msgstr ""
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr ""
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s Ezarpenak"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA Ostalari Ezarpenak"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Modulo bideak:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2029,68 +2105,39 @@ msgstr ""
"LADSPA_PATH bidean eta bide hauetan bilatuko da.\n"
"Bide berria gehitu eta gero, sakatu Enter Plugin berriak bilatzeko.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Plugin eskuragarriak:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Gaitu"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Gaitutako pluginak:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Ezarpenak"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr ""
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr ""
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr ""
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr ""
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr ""
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr ""
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC plugina"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2106,73 +2153,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr ""
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Berkonektatu LIRC zerbitzarira"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Itxaron berkonektatu aurretik:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC plugina"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki plugina"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Errorea"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Errorea"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki plugina"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U Erreprodukzio-zerrendak"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr ""
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Ukimen sortzailea: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Ukimen sortzailea: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2181,162 +2236,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
msgstr ""
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr ""
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Irteera kanalak:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr ""
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS Plugina"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr ""
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr ""
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr ""
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr ""
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr ""
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr ""
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
msgstr ""
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Surround"
-
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 plugina"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr ""
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS plugina"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Geldituta"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious ez da jotzen ari."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr ""
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2356,55 +2443,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr ""
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pausatu"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Hurrengoa"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr ""
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Soinu-gailua:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Erabili bestelako gailua:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr ""
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr ""
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2413,19 +2509,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
msgstr ""
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr ""
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2 Deskodetzailea"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr ""
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2445,143 +2557,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
msgstr ""
-#: src/resample/resample.c:165
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Aurrekoa"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Errepikatu"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Ausazkoa"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr ""
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr ""
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr ""
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr ""
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr ""
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr ""
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr ""
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr ""
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr ""
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr ""
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr ""
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr ""
-#: src/resample/resample.c:204
-msgid "192 kHz:"
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
msgstr ""
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
+#: src/resample/resample.cc:241
+msgid "192 kHz:"
msgstr ""
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr ""
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr ""
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2592,765 +2773,840 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr ""
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr ""
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr ""
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Artista ezezaguna"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Disko ezezaguna"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d album"
-msgstr[1] "%d albums"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr ""
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr ""
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr ""
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr ""
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr ""
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Erreprodukzioa"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Erreprodukzio-zerrenda"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Ikusi"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Errepikatu"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Ausazkoa"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Erreprodukzio-zerrenda aurreraturik ez"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Aurrekoa"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Erreprodukzio-zerrenda berria"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Erakutsi erreprodukzio-zerrendaren editorea"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Erakutsi ekualizadorea"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Beti gainean"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Tituluaren arabera"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Fitxategi-izenaren arabera"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Kendu guztiak"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Garbitu ilara"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Kendu fitxategi erabilkaitzak"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Kendu bikoiztuak"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Kendu desautatutakoak"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Kendu hautatutakoak"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Bilatu eta hautatu"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Alderantzikatu hautapena"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Ez hautatu ezer"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Hautatu denak"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Diskoaren arabera"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Pista zenbakiaren arabera"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Artistaren arabera"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Diskoaren arabera"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Pista zenbakiaren arabera"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Nahastu ausaz zerrenda"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Alderantzikatu zerrenda"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Ordenatu hautatutakoak"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Ordenatu zerrenda"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Moztu"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Kopiatu"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Itsatsi"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr ""
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Gorde"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Kargatu"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Aurrezarpenak"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Kargatu aurrezarpena"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr ""
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Gorde aurrezarpenak"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr ""
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Ezabatu aurrezarpena"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr ""
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Erreproduzitzailea:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Hautatu erreproduzitzaile nagusiaren leihoko letra-tipoa:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Erreprodukzio-zerrenda:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Hautatu erreprodukzio-zerrendaren letra-tipoa:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr ""
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr ""
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analizatzailea"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Esparrua"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Itzalita"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normala"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Sua"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Marrak"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Barrak"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Motelena"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Motela"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Tartekoa"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Azkarra"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Azkarrena"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Izotza"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Leuna"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Orokorra"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Bisualizazioa"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Aurre-anp"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious-en ekualizadorea"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Bilatu %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Bolumena: %% %d"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balantzea: %% %d ezkerrean"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balantzea: erdian"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balantzea: %% %d eskuinean"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Aukeren menua"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Desgaitu 'Beti gainean'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Gaitu 'Beti gainean'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Fitxategi-informazioaren koadroa"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Single modua."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Erreprodukzio-zerrenda modua."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Kantuaren ostean geldituko da."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Bilatu sarrerak erreprodukzio-zerrenda aktiboan"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3362,57 +3618,61 @@ msgstr ""
"minuskulak ez bereiztuz. Ez badakizu adierazpen erregularrak nola ibiltzen "
"diren, sartu bilatzea nahi duzunaren zati literal bat."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Izenburua: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Diskoa: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Artista: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Fitxategi-izena: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Garbitu aurreko hautapena bilatu aurretik"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Txandakatu automatikoki ilara bat datozen sarrerentzako"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Sortu erreprodukzio-zerrenda berria bat datozen sarrerekin"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audacious erreprodukzio-zerrendaren editorea"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr ""
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Konprimitutako Winamp 2.x azala"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Deskonprimitutako Winamp 2.x azala"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Ezin izan da direktorioa (%s) sortu: %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile plugina"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3434,85 +3694,71 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile plugina"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Sndio irteera pluginari buruz"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-"Sndio irteera plugina\n"
-"\n"
-"Thomas Pfaff-ek idatzia <tpfaff at tp76.info>\n"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Onartu gabeko formatua"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-"Audio gailuak onartzen ez duen formatua eskatu da.\n"
-"\n"
-"Mesedez berriro saiatu sndiod(1) zerbitzaria martxan dela"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio gailua"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(hutsik badago: lehenetsia)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "Ados"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr ""
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Exekutatuko den komandoa audacious-ek abesti berria hastean."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Shell-ari emandako parametroak komatxoen artean kapsulatu "
+"behar dira. Bestela segurtasunezko arriskua izan daiteke.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Komandoa:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Exekutatuko den komandoa abestiaren amaierantz joatean."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
msgstr ""
-"Exekutatuko den komandoa Audacious erreprodukzio-zerrendaren amaierara "
-"iristean."
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Exekutatuko den komandoa abesti baten titulua aldatzean (adib. sareko "
-"korronteen tituluak)."
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3526,35 +3772,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Hurrengo formatu kateak erabili ditzazkezu \n"
-"eta komandoa deitu aurretik ordezaktuko dira\n"
-"(Denak ez dira erabilgarriak erreproduzkio-zerrenda bukaerako komanoan):\n"
-"\n"
-"%F: Frekuentzia (hertziotan)\n"
-"%c: Kanal kopurua\n"
-"%f: Fitxategi izena (bide osoa)\n"
-"%l: Iraupena (milisegunduetan)\n"
-"%n edo %s: Kantuaren izena\n"
-"%r:Bitartea (bit segunduko\n"
-"%t: Erreprodukzio-zerrendan posizioa (%02d)\n"
-"%p: Jotzen ari da (1 edo 0)\n"
-"%a: Artista\n"
-"%b: Diskoa\n"
-"%T: Pista izena"
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>Shell-ari emandako parametroak komatxoen artean kapsulatu "
-"behar dira. Bestela segurtasunezko arriskua izan daiteke.</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Komandoak"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3563,51 +3790,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr ""
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Abiadura eta Tonoa"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Abiadura eta Tonoa</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Abiadura:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Tonoa:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Abiadura eta Tonoa"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr ""
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3618,63 +3845,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr ""
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Aldatu bolumena"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Aldatu erreprodukzioaren abestia"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Bestelako Ezarpenak</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr ""
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr ""
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
msgstr ""
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr ""
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
msgstr ""
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Tonu-sortzailea: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3683,15 +3910,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr ""
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr ""
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3712,44 +3935,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis Deskodetzailea"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX Deskodetzailea"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX Deskodetzailea"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack Deskodetzailea"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr ""
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr ""
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack Deskodetzailea"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF Deskodetzailea"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr ""
diff --git a/po/fa_IR.po b/po/fa_IR.po
index 2aabf72b4095..7ac512602ecb 100644
--- a/po/fa_IR.po
+++ b/po/fa_IR.po
@@ -7,11 +7,11 @@
# vandu <vandusoft at gmail.com>, 2014
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Persian (Iran) (http://www.transifex.com/projects/p/audacious/"
"language/fa_IR/)\n"
"Language: fa_IR\n"
@@ -20,51 +20,35 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "تکâÚ©Ø§ÙØ§ÙÙ"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "دÙÚ©Ø§ÙØ§ÙÙ"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "ÙØ±Ø§Ú¯Ûر"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
+#: src/aac-raw/aac.cc:18
+msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/aac-raw/aac.c:476
-msgid "AAC (Raw) Decoder"
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr ""
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr ""
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "ÙØ´Ø¯Ø§Ø±"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "ÙØ´Ø¯Ø§Ø±"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -87,7 +71,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -109,7 +93,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -123,360 +107,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "اÛ٠تÙ
اس Ø¨ÛØ¯Ø§Ø±Ø¨Ø§Ø´ Ø´Ù
ا است."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr ""
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "ÛØ§Ø¯Ø¢ÙرÛ"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Ø¯ÙØ´ÙبÙ"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "سÙâØ´ÙØ¨Ù"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "ÚÙØ§Ø±Ø´ÙبÙ"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Ù¾ÙØ¬âØ´ÙØ¨Ù"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "جÙ
عÙ"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Ø´ÙØ¨Ù"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "ÛÚ©Ø´ÙØ¨Ù"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "ØªÙØ¸ÛÙ
ات ÙØ´Ø¯Ø§Ø±"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "زÙ
اÙ"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "ÙØ´Ø¯Ø§Ø± در (Ù¾ÛØ´âÙØ±Ø¶):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "س"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "خاÙ
ÙØ´ Ø´ÙØ¯ بعد از:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "ساعت"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "دÙÛÙÙ"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Ø±ÙØ²ÙØ§Û Ù
ÙØ±Ø¯ ÙØ¸Ø± Ø¨Ø±Ø§Û ÙØ´Ø¯Ø§Ø± Ø§ÙØªØ®Ø§Ø¨ Ø´ÙØ¯"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Ø±ÙØ²"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Ù¾ÛØ´âÙØ±Ø¶"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Ø±ÙØ²Ùا"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Ù
ØÙ شدÙ"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "ثاÙÛÙâÙØ§"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "صدا"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Ø´Ø±ÙØ¹ از"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Ù¾Ø§ÛØ§Ù"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "جارÛ"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "ÙØ±Ù
ا٠تکÙ
ÛÙÛ"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "ÙØ¹Ø§ÙâØ³Ø§Ø²Û"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "ÙÛØ³Øª پخش (Ø§Ø®ØªÛØ§Ø±Û)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr ""
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "گزÛÙÙâÙØ§"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Ù
Ø¹ÙØ§Û اÛ٠گزÛÙÙâÙØ§ ÚÛØ³ØªØ"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "راÙÙÙ
اÛÛ"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr ""
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr ""
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "ابزار PCM Ù¾ÛØ´âÙØ±Ø¶"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "ابزار Ù
Ûکسر Ù¾ÛØ´âÙØ±Ø¶"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "ابزار PCM:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "ابزار Ù
Ûکسر:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Ø¹ÙØµØ± Ù
Ûکسر:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "کار ØÙ٠اتÙ
اÙ
تÙ
اس"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr ""
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr ""
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "ÙØ±ØªØ²"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - ÙØ§ÛÙ SoundFont Ø§ÙØªØ®Ø§Ø¨ Ø´ÙØ¯"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "ÙØ§Ù
ÙØ§Ø¨Ù"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "ÙØ§Ù
ÙØ§ÛÙ"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Ø§ÙØ¯Ø§Ø²Ù (Ø¨Ø§ÛØª)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "ÙØ§Ù
:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> âØ§Ø·ÙØ§Ø¹Ø§Øª MIDI â</span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "ÙØ±Ù
ت:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Ù
دت زÙ
ا٠(Ù
ÛÙÛâØ«Ø§ÙÛÙ):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "Ù
ØªØºÛØ±"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "âBPM (wavg)â:"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "ÙØ³Ù
ت زÙ
اÙ:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> ØªÙØ¶ÛØØ§Øª ٠تراÙÙâÙØ§Û MIDIâ </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* ØªÙØ¶ÛØØ§ØªÛ در اÛÙ ÙØ§ÛÙ MIDI ÙØ¬Ùد ÙØ¯Ø§Ø±Ø¯ *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* تراÙÙâØ§Û Ø¯Ø± اÛÙ ÙØ§ÛÙ MIDI ÙØ¬Ùد ÙØ¯Ø§Ø±Ø¯ *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "بستÙ"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr "(UTF-8 ÙØ§Ù
عتبر)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -487,151 +477,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr ""
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Ù
ستطÛÙ"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Ù
ستطÛÙ Ú¯ÙØ´Ùâگرد"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Ù
ستطÛÙ Ù
ÙØ¹Ø±"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "ÙÛÚکداÙ
"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Ø´Ø±ÙØ¹ پخش"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "ÙÙØªÛ ÛÚ©Û Ø§Ø² گزÛÙÙâÙØ§Û ÙÛØ³Øª پخش اجرا شد OSD اجرا Ø´ÙØ¯."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "تغÛÛØ± عÙÙØ§Ù"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"ÙÙگاÙ
Û Ú©Ù Ø¯Ø± ØØ§Ù پخش عÙÙØ§Ù ÙØ§Û٠تغÛÛØ± Ú©Ø±Ø¯Ø Ø§Ù
ا ÙØ§Ù
ÙØ§ÛÙ Ø¹ÙØ¶ ÙØ´Ø¯Ø OSD اجرا "
-"Ø´ÙØ¯. از اÛ٠گزÛÙÙ Ø¨Ø±Ø§Û ÙÙ
Ø§ÛØ´ تغÛÛØ± عÙÙØ§Ù در استرÛÙ
âÙØ§Û اÛÙØªØ±ÙØªÛ Ø§Ø³ØªÙØ§Ø¯Ù Ù
ÛâØ´ÙØ¯."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "تÙÙÙ Ø±ÙØ´Ù"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "ÙÙØªÛ عÙ
ÙÛØ§Øª پخش Ù
تÙÙ٠شد OSD اجرا Ø´ÙØ¯."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "تÙÙ٠خاÙ
ÙØ´"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "ÙÙØªÛ از پخش از ØØ§Ùت تÙÙ٠خارج شد OSD اجرا Ø´ÙØ¯."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Ù
ØÙ ÙØ±Ø§Ø±Ú¯ÛرÛ"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "ÙØ§ØµÙÙ ÙØ³Ø¨Û از عرض:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "ÙØ§ØµÙÙ ÙØ³Ø¨Û از Ø§Ø±ØªÙØ§Ø¹:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "ØØ¯Ø§Ú©Ø«Ø± Ø·ÙÙ OSD:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "گزÛÙÙâÙØ§Û ØØ§Ùت ÚÙØ¯ÙÙ
Ø§ÛØ´Ú¯Ø±Ù"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "ÙÙ
Ø§ÛØ´ OSD Ø¨ÙØ³ÛÙÙ:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "ÙÙ
Ù ÙÙ
Ø§ÛØ´Ú¯Ø±Ùا"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "ÙÙ
Ø§ÛØ´Ú¯Ø± â%i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "زÙ
اÙâØ¨ÙØ¯Û (Ø¨Ø±ØØ³Ø¨ Ù
ÛÙÛâØ«Ø§ÙÛÙ)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "ÙÙ
Ø§ÛØ´:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "ÙÙ
Ø§ÛØ´ ØªØ¯Ø±ÛØ¬Û:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Ø®Ø±ÙØ¬ ØªØ¯Ø±ÛØ¬Û:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "ÙÙÙØªâÙØ§"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "ÙÙÙØª â%i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "ساÛÙ"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Ø´ÛÙÙ Ø±ÙØ¯Ø±"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "رÙÚ¯âÙØ§"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "رÙÚ¯ â%i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "ÙØ¹Ø§ÙâØ³Ø§Ø²Û Ø§Ø¬Ø±Ø§"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "رخداد"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Ù
Ø¯ÛØ±Ú©Ø§Ù
Ù¾ÙØ²Ûت ÛØ§Ùت شد"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -641,112 +626,112 @@ msgstr ""
"اگر Ù
ÛâØ¯Ø§ÙÛØ¯ در ØØ§Ù Ø§Ø¬Ø±Ø§Ø³ØªØ ÙØ·Ùا ÛÚ© Ù
Ø¯ÛØ± کاÙ
Ù¾ÙØ²Ûت را ÙØ¹Ø§Ù Ú©ÙÛØ¯Ø در ØºÛØ±Ø§ÛÙØµÙرت "
"OSDâ Ø¨Ø¯Ø±Ø³Û ÙØ´Ø§Ù داد٠ÙÙ
ÛâØ´ÙØ¯"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Ø¨Ø±Ø§Û Ø´ÙØ§ÙÛØª Ø³Ø§Ø®ØªÚ¯Û ÙÛØ§Ø²Û ب٠Ù
Ø¯ÛØ± کاÙ
Ù¾ÙØ²Ûت ÙÛØ³Øª"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Ø´ÙØ§ÙÛØª"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Ø´ÙØ§ÙÛØª ساختگÛ"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Ø´ÙØ§ÙÛØª ÙØ§ÙØ¹Û (Ø¨Ù Ø§ÙØ²ÙÙ٠کاÙ
Ù¾ÙØ²Ûت X ÙÛØ§Ø² دارد)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Ø§ÙØ²ÙÙ٠کاÙ
Ù¾ÙØ²Ûت Ø¨Ø§Ø±Ú¯Ø°Ø§Ø±Û ÙØ´Ø¯Ù است"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Ø§ÙØ²ÙÙ٠کاÙ
Ù¾ÙØ²Ûت در دسترس ÙÛØ³Øª"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "ØªÙØ¸ÛÙ
ات Audacious OSD"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Ù
کاÙ"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Ù¾ÙÛØ§ÙÙ
اÛÛ"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Ù
تÙ"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "تزÛÛÙØ§Øª"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "ترÛگر"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Ù
ØªÙØ±ÙÙ"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr ""
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr ""
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr ""
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr ""
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
msgstr ""
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
msgstr ""
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
msgstr ""
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
msgstr ""
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -758,169 +743,156 @@ msgid ""
"This was a Google Summer of Code 2007 project."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Ø¨Ø¬Ø§Û CDDBP از HTTP Ø§Ø³ØªÙØ§Ø¯Ù Ú©Ù"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "سÛâØ¯Û ØµÙØªÛ"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "دراÛ٠خاÙÛ Ø§Ø³Øª."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "ÙÙØ¹ Ø¯ÛØ³Ú© Ù¾Ø´ØªÛØ¨Ø§ÙÛ ÙÙ
ÛâØ´ÙØ¯."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr ""
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Ø§Ø¬Ø±Ø§Û Ø³ÛâØ¯Û"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "اضاÙ٠کرد٠سÛâØ¯Û"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr ""
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr ""
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Ù
تÙ
رکز کرد٠صدا:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "باز٠Ù
ØªØºÛØ±:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr ""
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -930,195 +902,220 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "باس:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "ØµØ¯Ø§Û Ø²ÛØ±:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Ø·ÙÙ Ù¾ÛØ´ ÙØ±Ø¶ Ø¢ÙÙÚ¯:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "ÙÙ
ÙÙÙâÚ¯ÛØ±Û Ù
جدد صدا Ø§ÙØ¬Ø§Ù
Ø´ÙØ¯"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "ÙØ±Ø® ÙÙ
ÙÙÙâÚ¯ÛØ±Û Ù
جدد:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "ÙØ±ØªØ²"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ø·ÙÙ Ø¨Ø±ÚØ³Ø¨âÙØ§Û SPC ÙØ§Ø¯ÛØ¯Ù Ú¯Ø±ÙØªÙ Ø´ÙØ¯"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Ø§ÙØ²Ø§ÛØ´ Ø§ÙØ¹Ú©Ø§Ø³"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "دÛکدر Ù
ÙØ³ÛÙÛ Ú©ÙØ³Ù٠بازÛ"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr ""
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr ""
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr ""
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr ""
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr ""
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr ""
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "ØØ°Ù"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Ø§ÙØµØ±Ø§Ù"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr ""
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr ""
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr ""
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr ""
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr ""
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
+#: src/echo_plugin/echo.cc:39
+msgid "Echo"
msgstr ""
-#: src/echo_plugin/echo.c:122
-msgid "Echo"
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1128,55 +1125,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
msgstr ""
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "ÙØ±Ù
ت ÙØ§ÛÙ Ø®Ø±ÙØ¬Û:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Ù¾ÛÚ©Ø±Ø¨ÙØ¯Û"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Ø°Ø®ÛØ±Ù در Ù¾ÙØ´Ù اصÙÛ"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Ø°Ø®ÛØ±Ù در Ù¾ÙØ´Ù شخصÛ"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Ù¾ÙØ´Ù Ø¨Ø±Ø§Û Ø°Ø®ÛØ±ÙâØ³Ø§Ø²Û ÙØ§ÛÙ:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "ÛÚ© Ù¾ÙØ´Ù را Ø§ÙØªØ®Ø§Ø¨ Ú©ÙÛØ¯"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "ÙØ§Ù
âÚ¯Ø°Ø§Ø±Û ÙØ§Û٠از رÙÛ:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "Ø¨Ø±ÚØ³Ø¨âÙØ§Û اصÙÛ ÙØ§ÛÙ"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "ÙØ§Ù
اصÙÛ ÙØ§ÛÙ"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Ø§ÙØ²ÙÙÙ ÙØ§Ù
ÙØ§Û٠از بÛÙ ÙØ±Ùد"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Ø´Ù
ار٠آÙÙÚ¯ را Ø¨Ù ÙØ§Ù
ÙØ§ÛÙ ÙØ³Ø¨Øª بدÙ"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1194,165 +1191,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr ""
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Ø®ÙØ¯Ú©Ø§Ø±"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "ÛÚ©Û Ú©Ø±Ø¯Ù Ø¯Ù Ú©Ø§ÙØ§Ù"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "دÙÚ©Ø§ÙØ§ÙÙ"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "تکâÚ©Ø§ÙØ§ÙÙ"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Ù¾ÛÚ©Ø±Ø¨ÙØ¯Û MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Ú©ÛÙÛØª اÙÚ¯ÙØ±ÛتÙ
:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "ÙØ±Ø® ÙÙ
ÙÙÙâÚ¯ÛØ±Û Ø®Ø±ÙØ¬Û:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(ÙØ±ØªØ²)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "ÙØ³Ø¨Øª ÙØ±Ø® Ø¨ÛØª / ÙØ´Ø±Ø¯ÙâØ³Ø§Ø²Û:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ÙØ±Ø® Ø¨ÛØª (Ú©ÛÙÙØ¨Ûت بر ثاÙÛÙ):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "ÙØ³Ø¨Øª ÙØ´Ø±Ø¯ÙâØ³Ø§Ø²Û:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "ØØ§Ùت صدا:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Ù
ØªÙØ±ÙÙ:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "اجبار در Ø§Ø³ØªÙØ§Ø¯Ù از ÙÙØ§Ø¹Ø¯ ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Ù
ØØ§Ùظت در برابر خطا"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Ú©ÛÙÛØª"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "ÙØ¹Ø§ÙâØ³Ø§Ø²Û VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "ÙÙØ¹:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "گزÛÙÙâÙØ§Û VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "ØØ¯Ø§ÙÙ ÙØ±Ø® Ø¨ÛØª (Ú©ÛÙÙØ¨Ûت بر ثاÙÛÙ):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "ØØ¯Ø§Ú©Ø«Ø± ÙØ±Ø® Ø¨ÛØª (Ú©ÛÙÙØ¨Ûت بر ثاÙÛÙ):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "ØØ¯Ø§ÙÙ ÙØ±Ø® Ø¨ÛØª بشدت اعÙ
Ø§Ù Ø´ÙØ¯"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "گزÛÙÙâÙØ§Û ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "ÙØ±Ø® Ø¨ÛØª Ù
ÛØ§ÙÚ¯ÛÙ (Ú©ÛÙÙØ¨Ûت بر ثاÙÛÙ):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "Ø³Ø·Ø Ú©ÛÙÛØª VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "سرآÛÙØ¯ Xing VBRâ ÙÙØ´ØªÙ ÙØ´Ùد"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR ÙØ±Ø® Ø¨ÛØª Ù
ØªØºÛØ±/ÙØ±Ø® Ø¨ÛØª Ù
ÛØ§ÙÚ¯ÛÙ"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "ÙØ§ÛÙ Ú©Ù¾ÛâØ±Ø§ÛØª دارد"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "ÙØ§ÛÙ ÙØ³Ø®Ù اصÙÛ Ø§Ø³Øª"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "پاراÙ
ØªØ±ÙØ§Û ID3:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Ø¨Ø±ÚØ³Ø¨âÙØ§Û ÙØ³Ø®Ù 2 ØØªÙ
ا اضاÙÙ Ø´ÙØ¯"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "ÙÙØ· Ø¨Ø±ÚØ³Ø¨âÙØ§Û ÙØ³Ø®Ù 1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "ÙÙØ· Ø¨Ø±ÚØ³Ø¨âÙØ§Û ÙØ³Ø®Ù 2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Ø¨Ø±ÚØ³Ø¨âÙØ§"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Ù¾ÛÚ©Ø±Ø¨ÙØ¯Û اÙکدر Vorbis:"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Ø³Ø·Ø Ú©ÛÙÛØª (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr ""
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr ""
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1360,21 +1361,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr ""
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1386,529 +1391,606 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Ø´Ù
ار٠گزÛÙÙ"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "عÙÙØ§Ù"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "ÙÙØ±Ù
ÙØ¯"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Ø³Ø§Ù Ø§ÙØªØ´Ø§Ø±"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Ø¢ÙØ¨ÙÙ
"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Ø¢ÙÙÚ¯"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr ""
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Ù
کا٠در صÙ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Ù
دت زÙ
اÙ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Ù
Ø³ÛØ± ÙØ§ÛÙ"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "ÙØ§Ù
ÙØ§ÛÙ"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "عÙÙØ§Ù شخصÛ"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ÙØ±Ø® Ø¨ÛØª"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr ""
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "ب٠سÙ
ت ÚÙ¾ Ø¨ÚØ³Ø¨Ø§Ù"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "ب٠سÙ
ت راست Ø¨ÚØ³Ø¨Ø§Ù"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Ø¨Ù Ø¨Ø§ÙØ§ Ø¨ÚØ³Ø¨Ø§Ù"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "ب٠پاÛÛÙ Ø¨ÚØ³Ø¨Ø§Ù"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "جدا Ú©Ø±Ø¯Ù Ù¾ÙØ¬Ø±Ù"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "ØºÛØ±ÙعاÙâØ³Ø§Ø²Û"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr ""
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Ø¨Ø§Ø²Ú©Ø±Ø¯Ù ÙØ§ÛÙâÙØ§ ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "بازکرد٠_آدرس اÛÙØªØ±ÙØªÛ ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr ""
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "اضاÙ٠کرد٠آدرس _اÛÙØªØ±ÙØªÛ ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "د_ربار٠..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Ø®Ø±ÙØ¬"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_پخش"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "تÙ_ÙÙ"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "پا_ÛØ§Ù پخش"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_ÙØ¨ÙÛ"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_بعدÛ"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_تکرار"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_بÙÙ
Ø±ÛØ®ØªÙ"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr ""
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "ا_Ø·ÙØ§Ø¹Ø§Øª Ø¢ÙÙÚ¯ ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "پرش ب٠_زÙ
ا٠..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "پرش ب٠_Ø¢ÙÙÚ¯ ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "براساس _عÙÙØ§Ù"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "براساس _Ø´Ù
ار٠آÙÙÚ¯"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "براساس _ÙÙØ±Ù
ÙØ¯"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "بر اساس _ØªØ§Ø±ÛØ® Ø§ÙØªØ´Ø§Ø±"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "براساس _Ù
Ø³ÛØ± ÙØ§ÛÙ"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "براساس عÙÙØ§Ù شخصÛ"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Ù
رتب Ø³Ø§Ø²Û Ù
Ø¹Ú©ÙØ³"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "بÙÙ
Ø±ÛØ®ØªÙ Ù
Ø±ØªØ¨âØ³Ø§Ø²Û"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "تازÙâØ³Ø§Ø²Û ÙÛØ³Øª"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "Ù
رتب کردÙ"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr ""
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "Ø¬Ø¯ÛØ¯"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr ""
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "ÙØ§Ø±Ø¯ کرد٠..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "Ø®Ø±ÙØ¬Û Ú¯Ø±ÙØªÙ ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr ""
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Ù
Ø¯ÛØ± ص٠..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Ø§ÙØ²Ø§ÛØ´ صدا"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "Ú©Ø§ÙØ´ صدا"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "اکÙÙØ§Ûزر"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "ÙÙ
Ø§ÛØ´ ÙÙØ§Ø± Ù
ÙÙ"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "ÙÙ
Ø§ÛØ´ ÙÙØ§Ø± Ø§Ø·ÙØ§Ø¹Ø§Øª"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr ""
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "ÙÙ
Ø§ÛØ´ ÙÙØ§Ø± ÙØ¶Ø¹Ûت"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "ÙØ§ÛÙ"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "پخش"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "ÙÛØ³Øª پخش"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "سرÙÛØ³âÙØ§"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "Ø®Ø±ÙØ¬Û"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "ÙÙ
ا"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "ÙØ§Ø±Ø¯ کرد٠بÙ/خارج کرد٠از صÙ"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "برش"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "Ú©Ù¾Û"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "ÚØ³Ø¨Ø§ÙدÙ"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Ø§ÙØªØ®Ø§Ø¨ ÙÙ
Ù"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr ""
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "رابط GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "â%s - Aduacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr ""
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "تکâÚ©Ø§ÙØ§ÙÙ"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "دÙÚ©Ø§ÙØ§ÙÙ"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "â%d Ú©Ø§ÙØ§Ù"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "â%d Ú©ÛÙÙØ¨Ûت بر ثاÙÛÙ"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "ØØ§Ùت تکâÙØ§ÛÙ."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "ØØ§Ùت ÙÛØ³Øª پخش."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "تÙÙ٠بعد از Ø¢ÙÙÚ¯."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr ""
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "پخش"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "تÙÙÙ/اداÙ
Ù"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "اتÙ
اÙ
پخش"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr ""
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "ÙØ·Ø¹ کرد٠صدا"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr ""
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr ""
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr ""
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "ÙÙ
Ø§ÛØ´ Ø§Ø·ÙØ§Ø¹Ø§Øª بر رÙÛ ØµÙØÙ"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(ÙÛÚکداÙ
)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1919,15 +2001,11 @@ msgstr ""
"\n"
"Ø¢ÛØ§ Ù
ÛâØ®ÙØ§ÙÛØ¯ اداÙ
٠دÙÛØ¯Ø"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "تعرÛ٠گزÛÙÙ Ø¨Ø±Ø§Û Ú©ÙÛØ¯ÙØ§Û Ù
Ø§ÙØ³"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "ØªÙØ¸ÛÙ
ات Ø§ÙØ²ÙÙÙ Ú©ÙÛØ¯ Ù
ÛØ§Ùبر عÙ
ÙÙ
Û"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -1935,23 +2013,27 @@ msgstr ""
"ØªØ±Ú©ÛØ¨ Ù
ÙØ±Ø¯ ÙØ¸Ø± را در جعب٠Ù
ت٠از طرÛÙ ÙØ´Ø±Ø¯Ù Ú©ÙÛØ¯Ùا Ø§ÛØ¬Ø§Ø¯ Ú©ÙÛØ¯.\n"
"Ù
ÛâØªÙØ§Ù از Ú©ÙÛØ¯ÙØ§Û Ù
Ø§ÙØ³ ÙÙ
Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛØ¯."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Ú©ÙÛØ¯ÙØ§Û Ù
ÛØ§Ùبر:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>عÙ
Ù:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Ú©ÙÛØ¯ÙØ§Û ØªØ¹Ø±ÛÙâØ´Ø¯Ù:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr ""
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1966,56 +2048,51 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
msgstr ""
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr ""
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "ØªÙØ¸ÛÙ
ات â%s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "ØªÙØ¸ÛÙ
ات ÙØ§Ø³Øª LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Ù
Ø³ÛØ±ÙØ§Û Ù
اÚÙÙ:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2026,68 +2103,39 @@ msgstr ""
"بعد از ÙØ§Ø±Ø¯ Ú©Ø±Ø¯Ù ÙØ± Ù
Ø³ÛØ± Ú©ÙÛØ¯ اÛÙØªØ± را ÙØ´Ø§Ø± دÙÛØ¯ تا Ø§ÙØ²ÙÙÙâÙØ§Û Ø¬Ø¯ÛØ¯ جستج٠"
"Ø´ÙÙØ¯.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Ø§ÙØ²ÙÙÙâÙØ§Û Ù
ÙØ¬Ùد:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "ÙØ¹Ø§Ù کردÙ"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Ø§ÙØ²ÙÙÙâÙØ§Û ÙØ¹Ø§Ù:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "ØªÙØ¸ÛÙ
ات"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr ""
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr ""
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr ""
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr ""
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr ""
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
msgstr ""
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2103,73 +2151,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr ""
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr ""
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr ""
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "خطا"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "خطا"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr ""
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr ""
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Ù
ÙÙØ¯ تکت: â%d Ø¨ÛØª در دÙÛÙÙ"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Ù
ÙÙØ¯ تکت: â%d Ø¨ÛØª در دÙÛÙÙ â%d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2178,162 +2234,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
msgstr ""
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr ""
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Ú©Ø§ÙØ§ÙâÙØ§Û Ø®Ø±ÙØ¬Û:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
+#: src/mms/mms.cc:35
+msgid "MMS Plugin"
msgstr ""
-#: src/mms/mms.c:195
-msgid "MMS Plugin"
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
msgstr ""
-#: src/modplug/plugin_main.c:55
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr ""
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr ""
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr ""
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr ""
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr ""
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr ""
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
msgstr ""
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "ÙØ±Ø§Ú¯Ûر"
-
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr ""
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "ÙØ±Ø§Ú¯Ûر"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr ""
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr ""
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Ù
تÙÙ٠شدÙ"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious در ØØ§Ù پخش ÙÛØ³Øª."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr ""
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2353,55 +2441,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr ""
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Ù
تÙÙÙ"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "بعدÛ"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. ابزار Ù¾ÛØ´âÙØ±Ø¶"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr ""
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "ابزار ØµÙØªÛ:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "از ابزار جاÛگزÛÙ Ø§Ø³ØªÙØ§Ø¯Ù Ú©Ù:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr ""
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "تغÛÛØ± ÙØ±Ù
ت Ø¨ÙØ³ÛÙÙ ÙØ±Ù
âØ§ÙØ²Ø§Ø± ÙØ±Ù
âØ§ÙØ²Ø§Ø± OSS ÙØ¹Ø§Ù Ø´ÙØ¯."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2410,19 +2507,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
msgstr ""
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr ""
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr ""
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr ""
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2442,143 +2555,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
msgstr ""
-#: src/resample/resample.c:165
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ÙØ¨ÙÛ"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "تکرار"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "بÙÙ
âØ±ÛØ®ØªÙ"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr ""
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr ""
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr ""
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Ø´ÛÙÙ:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr ""
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr ""
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr ""
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr ""
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr ""
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr ""
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr ""
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr ""
-#: src/resample/resample.c:204
-msgid "192 kHz:"
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
msgstr ""
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
+#: src/resample/resample.cc:241
+msgid "192 kHz:"
msgstr ""
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr ""
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr ""
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2589,762 +2771,837 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr ""
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr ""
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr ""
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr ""
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr ""
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
+msgid "%d result"
+msgid_plural "%d results"
msgstr[0] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr ""
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr ""
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr ""
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr ""
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr ""
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "پخش"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "ÙÛØ³Øª پخش"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "ÙÙ
ا"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "تکرار"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "بÙÙ
âØ±ÛØ®ØªÙ"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "ÙÛØ³Øª پخش ب٠جÙÙ ÙØ±Ùد"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ÙØ¨ÙÛ"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "ÙÛØ³Øª پخش Ø¬Ø¯ÛØ¯"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "ÙÙ
Ø§ÛØ´ ÙÛØ±Ø§Ûشگر ÙÛØ³Øª پخش"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "ÙÙ
Ø§ÛØ´ اکÙÙØ§Ûزر"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "ÙÙ
ÛØ´Ù در Ø¨Ø§ÙØ§"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "براساس عÙÙØ§Ù"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "براساس ÙØ§Ù
ÙØ§ÛÙ"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "ØØ°Ù ÙÙ
Ù"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Ù¾Ø§Ú©Ø³Ø§Ø²Û ØµÙ"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "پاک Ú©Ø±Ø¯Ù ÙØ§ÛÙâÙØ§Û خارج از دسترس"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "پاک Ú©Ø±Ø¯Ù ÙØ§ÛÙâÙØ§Û تکرارÛ"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "ØØ°Ù Ø§ÙØªØ®Ø§Ø¨âÙØ´Ø¯ÙâÙØ§"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "ØØ°Ù Ø§ÙØªØ®Ø§Ø¨âشدÙâÙØ§"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Ø¬Ø³ØªØ¬Ù Ù Ø§ÙØªØ®Ø§Ø¨"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "برعکس Ú©Ø±Ø¯Ù Ø§ÙØªØ®Ø§Ø¨âÙØ§"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Ø§ÙØªØ®Ø§Ø¨ ÙÛÚâکداÙ
"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Ø§ÙØªØ®Ø§Ø¨ ÙÙ
Ù"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "براساس Ø¢ÙØ¨ÙÙ
"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "براساس Ø´Ù
ار٠آÙÙÚ¯"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "براساس ÙÙØ±Ù
ÙØ¯"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "براساس Ø¢ÙØ¨ÙÙ
"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "براساس Ø´Ù
ار٠آÙÙÚ¯"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "بÙÙ
âØ±ÛØ®ØªÙ ÙÛØ³Øª"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "برعکس Ú©Ø±Ø¯Ù ØªØ±ØªÛØ¨ ÙÛØ³Øª"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Ù
Ø±ØªØ¨âØ³Ø§Ø²Û Ø§ÙØªØ®Ø§Ø¨âشدÙâÙØ§"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Ù
Ø±ØªØ¨âØ³Ø§Ø²Û ÙÛØ³Øª"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "برش"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Ú©Ù¾Û"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "ÚØ³Ø¨Ø§ÙدÙ"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr ""
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Ø°Ø®ÛØ±Ù"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "بارگذارÛ"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "اÙÚ¯ÙÙØ§"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Ø¨Ø§Ø±Ú¯Ø°Ø§Ø±Û Ø§ÙÚ¯Ù"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr ""
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Ø°Ø®ÛØ±Ù اÙÚ¯Ù"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr ""
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "ØØ°Ù اÙÚ¯Ù"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr ""
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "پخشâÚ©ÙÙØ¯Ù:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "ÙÙÙØª اصÙÛ Ù¾ÙØ¬Ø±Ù پخشâÚ©ÙÙØ¯Ù را Ø§ÙØªØ®Ø§Ø¨ Ú©ÙÛØ¯:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "ÙÛØ³Øª پخش:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "ÙÙÙØª ÙÛØ³Øª پخش را Ø§ÙØªØ®Ø§Ø¨ Ú©ÙÛØ¯:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Ø§ÙØªØ®Ø§Ø¨ ÙÙÙØªâÙØ§Û ÙÙØ´ÙâØ¨ÛØªÛ (ÙÙØ· از Ø§Ø³Ú©Û Ù¾Ø´ØªÛØ¨Ø§ÙÛ Ù
ÛâØ´ÙØ¯)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "عÙÙØ§Ù Ø¢ÙÙÚ¯ در ÙØ± Ø¯Ù Ø¬ÙØª ØØ±Ú©Øª Ú©ÙØ¯"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "تØÙÛÙâÚ©ÙÙØ¯Ù"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Ù
ØØ¯ÙدÙ"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "خاÙ
ÙØ´"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "ÙØ±Ù
اÙ"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "آتش"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "خط ÙØ§"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Ù
ÛÙÙâÙØ§"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Ú©ÙØ¯ØªØ±ÛÙ"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Ú©ÙØ¯"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Ù
ØªÙØ³Ø·"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "ØªÙØ¯"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "ØªÙØ¯ØªØ±ÛÙ"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "ÛØ®"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "ÙØ±Ù
"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "عÙ
ÙÙ
Û"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "جÙÙÙâÙØ§Û تصÙÛØ±Û"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Ù¾ÛØ´âتÙÙÛØªâÚ©ÙÙØ¯Ù"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 ÙØ±ØªØ²"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 ÙØ±ØªØ²"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 ÙØ±ØªØ²"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 ÙØ±ØªØ²"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 ÙØ±ØªØ²"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 Ú©ÛÙÙÙØ±ØªØ²"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 Ú©ÛÙÙÙØ±ØªØ²"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 Ú©ÛÙÙÙØ±ØªØ²"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 Ú©ÛÙÙÙØ±ØªØ²"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 Ú©ÛÙÙÙØ±ØªØ²"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "اکÙÙØ§Ûزر Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Ù¾ÛÙ
Ø§ÛØ´ ب٠â%d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "صدا: â%d%%â"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Ø¨Ø§ÙØ§Ùس: â%d%%â ÚÙ¾"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Ø¨Ø§ÙØ§Ùس: Ù
رکز"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Ø¨Ø§ÙØ§Ùس: â%d%%â Ø±Ø§Ø³Øª"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Ù
ÙÙÛ Ú¯Ø²ÛÙÙâÙØ§"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "ØºÛØ±Ùعا٠کرد٠'ÙÙ
ÛØ´Ù در Ø¨Ø§ÙØ§'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "ÙØ¹Ø§Ù کرد٠'ÙÙ
ÛØ´Ù در Ø¨Ø§ÙØ§'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Ø¬Ø¹Ø¨Ù Ø§Ø·ÙØ§Ø¹Ø§Øª ÙØ§ÛÙ"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "ØØ§Ùت تکâÙØ§ÛÙ."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "ØØ§Ùت ÙÛØ³Øª پخش."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "تÙÙ٠بعد از Ø¢ÙÙÚ¯."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "گزÛÙÙâÙØ§Û Ù
ÙØ¬Ùد در ÙÛØ³Øª پخش ÙØ¹Ø§Ù را جستج٠کÙ"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3355,57 +3612,61 @@ msgstr ""
"Ù¾Ø´ØªÛØ¨Ø§ÙÛ Ú©Ø±Ø¯ÙØ Ø¨Ù Ø¨Ø²Ø±Ú¯Û Ù Ú©ÙÚÚ©Û ØØ±ÙÙ ØØ³Ø§Ø³ ÙØ³ØªÙد. اگر ÙÙ
ÛâØ¯Ø§ÙÛØ¯ عبارات Ù
ÙØ¸Ù
ÚÙ "
"ÙØ³ØªÙØ¯Ø Ø¨Ø®Ø´Û Ø§Ø² عبارت Ù
ÙØ±Ø¯Ùظر Ø®ÙØ¯ را ÙØ§Ø±Ø¯ Ú©ÙÛØ¯."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "عÙÙØ§Ù:"
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Ø¢ÙØ¨ÙÙ
:"
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "ÙÙØ±Ù
ÙØ¯:"
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "ÙØ§Ù
ÙØ§ÛÙ:"
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "ÙØ¨Ù از Ø¬Ø³ØªØ¬Ù Ø§ÙØªØ®Ø§Ø¨ ÙØ¨ÙÛ Ø±Ø§ پاک Ú©Ù"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "گزÛÙÙâÙØ§Û ÛØ§Ùت شد٠را در ØµÙ ÙØ´Ø§Ù بدÙ"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "ÙÛØ³Øª پخش براساس گزÛÙÙâÙØ§Û ÛØ§Ùت Ø´Ø¯Ù Ø§ÛØ¬Ø§Ø¯ Ú©Ù"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "ÙÛØ±Ø§Ûشگر ÙÛØ³Øª پخش Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "â%s (%d of %d)â"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Ù¾ÙØ³ØªÙ ÙØ´Ø±Ø¯Ù Winamp 2.x"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Ù¾ÙØ³ØªÙ ØºÛØ±Ùشرد٠Winamp 2.x"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr ""
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr ""
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3427,75 +3688,69 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
msgstr ""
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
msgstr ""
-#: src/sndio/sndio.c:384
-msgid "sndio device"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "ÙØ¨ÙÙ"
-
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr ""
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3510,17 +3765,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-#: src/song_change/song_change.c:490
-msgid "Commands"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3529,51 +3782,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
msgstr ""
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3584,63 +3837,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr ""
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr ""
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr ""
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr ""
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr ""
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr ""
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
msgstr ""
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr ""
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
msgstr ""
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr ""
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr ""
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3649,15 +3902,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr ""
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr ""
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3678,44 +3927,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr ""
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr ""
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
msgstr ""
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr ""
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr ""
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
+#: src/xsf/plugin.cc:50
+msgid "2SF Decoder"
msgstr ""
-#: src/xsf/plugin.c:217
-msgid "2SF Decoder"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
msgstr ""
-#: src/xspf/xspf.c:438
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr ""
diff --git a/po/fi.po b/po/fi.po
index 1bb1ea0ba7a6..cd81d9abfd62 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -3,15 +3,16 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# Jaergenoth <jstuomisto at gmail.com>, 2013
-# Jaergenoth <jstuomisto at gmail.com>, 2013
+# Jiri Grönroos <jiri.gronroos at iki.fi>, 2014-2015
+# J. S. Tuomisto <jstuomisto at gmail.com>, 2013
+# J. S. Tuomisto <jstuomisto at gmail.com>, 2013
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-05 07:12+0000\n"
+"Last-Translator: Jiri Grönroos <jiri.gronroos at iki.fi>\n"
"Language-Team: Finnish (http://www.transifex.com/projects/p/audacious/"
"language/fi/)\n"
"Language: fi\n"
@@ -20,40 +21,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "surround"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
-msgstr ""
+msgstr "AAC (Raw) -dekooderi"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib-soitin)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "sarjoitettu"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib-soitin)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Herätyskello"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
-msgstr ""
+msgstr "Aseta hälytys..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -63,11 +52,7 @@ msgstr ""
"\n"
"Alkuperäiset kehittäjät Adam Feakin ja Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Herätyskello"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -108,7 +93,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -147,7 +132,7 @@ msgstr ""
" Suoritetaan tämä komento kun hälytys alkaa.\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -171,384 +156,371 @@ msgstr ""
" Kirjoita muistutus laatikkoon ja kytke\n"
" se päälle, jos haluat muistutuksen näkyvän."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Herätys!"
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "Muistutuksesi tälle päivälle on..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Muistutus"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Maanantai"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Tiistai"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Keskiviikko"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Torstai"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Perjantai"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Lauantai"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Sunnuntai"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Herätyskellon asetukset"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Aika"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Kellonaika (oletus):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Hiljennä, kun aikaa kulunut:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "tunnit"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minuutit"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Valitse päivät jolloin herätyskello on aktiivinen"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Päivä"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Oletus"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Päivät"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Häivytys"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "sekuntia"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Ãänenvoimakkuus"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Aloita"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Lopullinen"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Nykyinen"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Lisäkomento"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "käytä"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Soittolista (valinnainen)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Valitse soittolista"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Asetukset"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Mitä nämä asetukset tarkoittavat?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Ohje"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
-msgstr "Levyn kansitaide"
+msgstr "Albumin kansikuvitus"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Albumikuvitus (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA-lähtö"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ALSA-lähdön liitännäinen Audacioukselle.\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"Kiitokseni William Pitcock:lle (ALSA Output Plugin NG:n kehittäjä), jonka "
+"koodi toimi referenssinä silloin, kun ALSA:n manuaali ei riittänyt."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(ei kuvausta)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Oletus PCM-laite"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Oletus miksauslaite"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM-laite:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Miksauslaite:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Miksauskanava:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Korjaa \"drain hangup\""
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-liitännäinen (MIDI-soitin)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-"ALSA-lähdön liitännäinen Audacioukselle.\n"
-"Copyright 2009-2012 John Lindgren\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
"\n"
-"Kiitokseni William Pitcock:lle (ALSA Output Plugin NG:n kehittäjä), jonka "
-"koodi toimi referenssinä silloin, kun ALSA:n manuaali ei riittänyt."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA-lähtö"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-liitännäinen (MIDI-soitin)"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
-msgstr ""
+msgstr "<b>Toisto</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
-msgid "Drum shift:"
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:132
+msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Ohita edeltävä hiljaisuus"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Ohita lopussa oleva hiljaisuus"
+
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-liitännäinen - valitse SoundFont-tiedosto"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Peru"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
-msgstr ""
+msgstr "_Avaa"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Tiedostonimi"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Koko (tavuina)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nimi:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI-tiedot </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Muoto:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Kesto (ms):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Raitojen lukumäärä:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "muuttuja"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Aikajako:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI-kommentit ja -lyriikat </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* MIDI-tiedostossa ei ollut kommentteja *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* MIDI-tiedostossa ei ollut lyriikoita *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Sulje"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (virheellinen UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Tietoja AMIDI-liitännäisestä"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-liitännäinen"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"modulaarinen MIDI-soitin\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"Luonut Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"Erityiskiitokset...\n"
-"\n"
-"Clemens Ladisch ja Jaroslav Kysela\n"
-"aplaymidi ja amixer olivat erittäin hyödyllisiä, \n"
-"alsa-lib dokumentaation ohella. Ne auttoivat\n"
-"oppimaan lisää ALSA:n ohjelmointirajapinnasta.\n"
-"\n"
-"Alfredo Spadafina\n"
-"hienosta MIDI-näppäimistö logosta\n"
-"\n"
-"Tony Vroon\n"
-"avusta alpha-testauksessa"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -559,151 +531,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (On-Screen Display)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Suorakulmio"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Pyöristetty suorakulmio"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Kovera suorakulmio"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Ei mitään"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Toiston aloitus"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Näyttää OSD:n kun kappaleen toisto alkaa."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Nimen muutos"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Näyttää OSD:n kun kappaleen nimi muuttuu toiston aikana, mutta tiedostonimi "
-"pysyy samana. Hyödyllinen lähinnä internet-virroille."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Keskeytys"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Näyttää OSD:n kun toisto keskeytetään."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Toisto jatkuu"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Näyttää OSD:n kun toisto jatkuu."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Sijoitus"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Suhteellinen X:n poikkeama:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Suhteellinen Y:n poikkeama:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "OSD:n maksimileveys:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Monen näytön asetukset"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Näytä OSD käyttäen:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "kaikki näytöt"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "näyttö %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Ajoitus (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Näytä:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Häivytä sisään:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Häivytä ulos:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Kirjasimet"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Kirjasin %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Varjo"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Esitystyyli"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Värit"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Väri %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Käytä liipaisinta"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Tapahtuma"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Komposointimanageri havaittu"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -713,112 +680,112 @@ msgstr ""
"Jos komposointimanageri ei ole vielä päällä, aktivoi se tai muutoin OSD ei "
"toimi kunnolla."
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Komposointimanageria ei tarvita jäljiteltyyn läpinäkyvyyteen"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Läpinäkyvyys"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Jäljitelty läpinäkyvyys"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Oikea läpinäkyvyys (vaatii X:n komposointilaajennuksen)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Komposointilaajennusta ei ole ladattu"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Komposointilaajennus ei ole saatavilla"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - asetukset"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Sijainti"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animaatio"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Teksti"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Koristeet"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Liipaisin"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Muut"
-#: src/asx3/asx3.c:179
-msgid "ASXv3 Playlists"
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx3/asx3.cc:35
+msgid "ASXv3 Playlists"
+msgstr "ASXv3-soittolistat"
+
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 -soittolistat"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious -soittolistat (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Väri</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Blur Scope"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Esiasetukset:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Syöttötaso:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Leikkaustaajuus:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Esiasetukset:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Spektrianalysaattori"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Ãäni CD -liitännäinen"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -838,171 +805,156 @@ msgstr ""
"\n"
"Tämä oli Google Summer of Code 2007 -projekti."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Laite</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Lukunopeus:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Laite:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metatiedot</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Käytä CD-tekstiä"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Käytä CDDB:tä"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Käytä HTTP:tä CDDBP:n sijasta"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Palvelin:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Polku:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Portti:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Ãäni CD -liitännäinen"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "cdio-alijärjestelmää ei voitu alustaa."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "Viallinen URI %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Raitaa %d ei löydetty."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "Raita %d on dataraita."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Ãänilähtöä ei voitu avata."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Virhe luettaessa ääni CD:tä."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Ãäni CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Ei voitu avata CD-asemaa %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Ãäneen kykenevää CD-asemaa ei löydetty."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "Avatun CD-aseman alustaminen epäonnistui."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Ei voitu lukea ensimmäistä/viimeistä raitaa."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Ei voida lukea alku/loppu LSN:ää raidalle %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "CDDB-yhteyden luonti epäonnistui."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "CDDB-palvelimen kysely epäonnistui."
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "CDDB-palvelimen kysely epäonnistui: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Ei voitu lukea cddb-tietoa: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Asema on tyhjä."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Levytyyppiä ei tueta."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Ãäni CD -valikkonimikkeet"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Toista CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Lisää CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Ãäni CD -valikkonimikkeet"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Kompressio</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Keskikanava:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Dynaaminen alue:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Dynaamisen alueen kompressori -liitännäinen Audacioukselle\n"
-"Copyright 2010-2012 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Dynaamisen alueen kompressori"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1018,206 +970,225 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Basso:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Diskantti:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Kappaleen oletuskesto:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>Uudelleennäytteistys</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Käytä äänen uudelleennäytteistystä"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Näytteenottotaajuus:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Sivuuta kesto SPC-tietueista"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Lisää kaikuefektiä"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Pelikonsoli-dekooderi"
-#: src/crossfade/crossfade.c:83
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "CoreAudio-lähtö"
+
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"Ristiinhäivytys epäonnistui koska kappaleilla oli eri määrä kanavia. Voit "
-"käyttää kanavamikseriä muuntaaksesi kappaleiden sisältämien kanavien määrää."
-#: src/crossfade/crossfade.c:90
-msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-"Ristiinhäivytys epäonnistui koska kappaleilla oli eri "
-"näytteenottotaajuudet. Voit käyttää uudelleennäytteistäjää muuntaaksesi "
-"kappaleiden näytteenottotaajuutta."
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Ristiinhäivytys-liitännäinen Audacioukselle\n"
-"Copyright 2010-2012 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Ristiinhäivytys</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "Limittäisyys:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Ristiinhäivytys"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"Ristiinhäivytys epäonnistui koska kappaleilla oli eri määrä kanavia. Voit "
+"käyttää kanavamikseriä muuntaaksesi kappaleiden sisältämien kanavien määrää."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"Ristiinhäivytys epäonnistui koska kappaleilla oli eri "
+"näytteenottotaajuudet. Voit käyttää uudelleennäytteistäjää muuntaaksesi "
+"kappaleiden näytteenottotaajuutta."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Crystalizer</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Vahvuus:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Crystalizer"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Cue Sheet -liitännäinen"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Poista tiedostot"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
-msgstr ""
+msgstr "Virhe siirrettäessä kohdetta %s roskakoriin: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
-msgstr ""
+msgstr "Virhe poistaessa kohdetta %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
-msgstr ""
+msgstr "Virhe poistaessa kohdetta %s: ei paikallinen tiedosto."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
-msgstr ""
+msgstr "Haluatko siirtää valitut tiedostot roskakoriin?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
-msgstr ""
+msgstr "Siirrä roskakoriin"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
-msgstr ""
+msgstr "Haluatko poistaa seuraavat tiedostot pysyvästi?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Poista"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Peruuta"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
-msgstr ""
+msgstr "Poista valitut tiedostot"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
-msgstr ""
+msgstr "<b>Poistamistapa</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
+msgstr "Siirrä roskakoriin pysyvän poistamisen sijaan"
+
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Kaikuefekti</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Viive:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Feedback:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Ãänenvoimakkuus:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Kaikuefekti-liitännäinen\n"
-"Luonut Johan Levin, 1999\n"
-"\n"
-"Surround-kaiun luonut Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Kaikuefekti"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg-liitännäinen"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1233,55 +1204,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg-liitännäinen"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "FileWriter-liitännäinen"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Tiedostoformaatti:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Muuta asetuksia"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Tallenna alkuperäiseen kansioon"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Tallenna muuhun kansioon"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Tiedoston kohdekansio:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Valitse kansio"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Hae tiedostonimi:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "alkuperäiset tiedoston tietueet"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "alkuperäinen tiedostonimi"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Pidä tiedoston pääte"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Lisää raidan numero tiedostonimeen"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1313,165 +1284,169 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "FileWriter-liitännäinen"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Automaattinen"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Joint Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3-asetukset"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_OK"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Algoritmin laatu:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Näytteenottotaajuus:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Bittinopeus / Pakkaussuhde:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Bittinopeus (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Pakkaussuhde:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Ãänitila:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Muut:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Pakota tarkka ISO-yhteensopivuus"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Virhesuojaus"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Laatu"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Käytä VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tyyppi:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR-asetukset:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Minimi bittinopeus (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Maksimi bittinopeus (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Valvo tiukasti minimi bittinopeutta"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR-asetukset:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Bittinopeuden keskiarvo (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR:n laatutaso:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Ãlä kirjoita Xing VBR -otsaketta"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "Kehyksen parametrit:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Merkitse tekijänoikeudeksi"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Merkitse alkuperäiseksi"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "ID3-parametrit:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Pakota v2-tagin lisäys"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Lisää vain v1-tagi"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Lisää vain v2-tagi"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Tagit"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis-enkooderin asetukset"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Laatutaso (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC-dekooderi"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "häviötön"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1483,11 +1458,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC-dekooderi"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1495,11 +1466,19 @@ msgstr ""
"GIO-liitännäinen Audacioukselle\n"
"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO-liitännäinen"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1511,534 +1490,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL Spektrianalysaattori"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
msgstr ""
-"Gnomen oikopolku -liitännäinen\n"
-"Ohjaa soitinta Gnomen oikopoluilla.\n"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "Gnome-pikanäppäimet"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Gnomen oikopolut"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Numero"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Nimi"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Esittäjä"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Vuosi"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Albumi"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Raita"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Tyylilaji"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Sijainti jonossa"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Kesto"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Tiedostopolku"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Tiedostonimi"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Mukautettu nimi"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Bittinopeus"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
-msgstr ""
+msgstr "Käytettävissä olevat sarakkeet"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
-msgstr ""
+msgstr "Näytettävät sarakkeet"
+
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Etsintätyökalu"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Telakoi vasemmalle"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Telakoi oikealle"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Telakoi ylhäälle"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Telakoi alhaalle"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Poista telakointi"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Poista käytöstä"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Etsintätyökalu"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "Avaa tied_ostot..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Avaa _URL..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_Lisää tiedostoja..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Lisää U_RL..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
-msgstr ""
+msgstr "_Etsi kirjastosta"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "_Tietoja..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
-msgstr ""
+msgstr "_Asetukset..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Sulje"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Toista"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "_Keskeytä"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Pysäytä"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_Edellinen"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_Seuraava"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Kertaus"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "S_ekoitus"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Ãlä _etene soittolistalla"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "_Pysäytä tämän kappaleen jälkeen"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "K_appaleen tiedot..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Hyppää _aikaan..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "_Hyppää kappaleeseen..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "Aseta kertauksen alkupiste A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "Aseta kertauksen loppupiste B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_Tyhjennä kertauspisteet"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "_Nimen mukaan"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "_Tiedostonimen mukaan"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Tiedosto_polun mukaan"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Ka_ppalenumeron mukaan"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "_Esittäjän mukaan"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Al_bumin mukaan"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "_Julkaisupäivämäärän mukaan"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "_Keston mukaan"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "_Tiedostopolun mukaan"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "_Mukautetun nimen mukaan"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "_Käänteinen järjestys"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_Satunnainen järjestys"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_Toista tämä soittolista"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_Toista/jatka"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Päivitä"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Lajittele"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "Järjestä _valitut"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "Poista _kopiot"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Poista _ei saatavilla olevat tiedostot"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Uusi"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "Nimeä _uudelleen..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
-msgstr ""
+msgstr "_Poista"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Tuo..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Vie..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "Soittolistojen _hallinta..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_Jonomanageri..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "_Nosta äänenvoimakkuutta"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "_Laske äänenvoimakkuutta"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Taajuuskorjain"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
-msgstr ""
+msgstr "_Tehosteet..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Näytä _valikkopalkki"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Näytä _tietopalkki"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Näytä tietopalkin vis_ualisaatio"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Näytä tila_rivi"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Näytä _jäljellä oleva aika"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
-msgstr ""
+msgstr "_Visualisoinnit..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Tiedosto"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "T_oisto"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Soittolista"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Palvelut"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Ãäni"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Näkymä"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Lisää jonoon/Poista jonosta"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "_Avaa sisältävä kansio"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "L_eikkaa"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Kopioi"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Liitä"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Valitse _kaikki"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_Nimeä uudelleen..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
-msgstr ""
+msgstr "<b>Soittolistan välilehdet</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
-msgstr ""
+msgstr "Näytä aina välilehdet"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
-msgstr ""
+msgstr "Näytä esiintymäkerrat"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
-msgstr ""
+msgstr "Näytä sulkemispainikkeet"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
-msgstr ""
+msgstr "<b>Soittolistan sarakkeet</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
-msgstr ""
+msgstr "Näytä sarakkeiden otsakkeet"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Sekalaiset</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
-msgstr ""
+msgstr "Nuolinäppäimet siirtävät:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
-msgstr ""
+msgstr "Vieritä kappaleen vaihtuessa"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK-käyttöliittymä"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Puskuroidaan..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d kanava"
msgstr[1] "%d kanavaa"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Yksittäinen -tila."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Soittolista -tila."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Pysäytä kappaleen jälkeen."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Edellinen raita"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Toista"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Keskeytä/Jatka"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Pysäytä"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Seuraava raita"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "5 sekuntia eteenpäin"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "5 sekuntia taaksepäin"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Vaimenna"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Nosta äänenvoimakkuutta"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Laske äänenvoimakkuutta"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Hyppää tiedostoon"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "Näytä/Piilota soittimen ikkunat"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Näytä OSD"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "Kertaus"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "Sekoitus"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "Pysäytä nykyisen jälkeen"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Nosta soittimen ikkunat"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(ei mitään)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2049,15 +2101,11 @@ msgstr ""
"\n"
"Haluatko jatkaa?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Kytketään hiiren painalluksia"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Globaalit pikanäppäimet -liitännäisen asetukset"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2065,23 +2113,27 @@ msgstr ""
"Paina näppäinyhdistelmää tekstikentän sisällä.\n"
"Voit käyttää myös hiiren nappeja."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Pikanäppäimet:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Toiminto:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Näppäinsidos:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
-msgstr ""
+msgstr "_Lisää"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Globaalit pikanäppäimet"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2107,60 +2159,51 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Globaalit pikanäppäimet"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK-lähtö"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Yhteys JACK-porttiin %s epäonnistui."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "Yhteys JACK-palvelimeen epäonnistui. Onhan se käynnissä?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Perustuu xmms-jack:iin, luonut Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Portannut Audacioukselle Giacomo Lozito"
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK-lähtö"
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s asetukset"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA-isännän asetukset"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Moduulipolut:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2171,25 +2214,25 @@ msgstr ""
"Uuden polun lisäämisen jälkeen paina entteriä hakeaksesi uusia liitännäisiä."
"</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Saatavilla olevat liitännäiset:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Käytä"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Aktiiviset liitännäiset:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Asetukset"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2197,47 +2240,15 @@ msgstr ""
"LADSPA-isäntä Audacioukselle\n"
"Copyright 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA-isäntä"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: ei voida alustaa LIRC-tukea\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: ei voitu lukea LIRC:n asetustiedostoa\n"
-"%s: lue LIRC:n dokumentaatiosta\n"
-"%s: kuinka luoda kelvollinen asetustiedosto \n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: yritetään yhdistää uudelleen...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: tuntematon komento \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: LIRC-yhteys katkaistu\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: yritetään yhdistää uudelleen joka %d sekunti...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC-liitännäinen"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2265,73 +2276,81 @@ msgstr ""
"\n"
"Lisää tieto LIRC:stä http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Yhteys</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Yhdistä uudelleen LIRC-palvelimelle"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Odota ennen uudelleenyhdistämistä:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC-liitännäinen"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki-liitännäinen"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Lyriikoita ei saatavilla"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Virhe"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Ei voitu hakea %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Virhe"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Ei voida jäsentää %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Etsitään lyriikoita..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Kappaleen metatiedot puuttuvat"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Yhdistetään lyrics.wikia.com..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki-liitännäinen"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "LyricWiki-liitännäinen (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U-soittolistat"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Tahtigeneraattori"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Tahtigeneraattori: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Tahtigeneraattori: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2345,11 +2364,11 @@ msgstr ""
"esim. tact://77 soittaaksesi 77 iskua minuutissa.\n"
"Tai tact://60*3/4 soittaaksesi 60 iskua minuutissa tahdilla 3/4"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Tahtigeneraattori"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Kanavamikseri"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2357,152 +2376,184 @@ msgstr ""
"Kanavamikseri-liitännäinen Audacioukselle\n"
"Copyright 2011-2012 John Lindgren ja MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Kanavamikseri</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Kanavat:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Kanavamikseri"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS-liitännäinen"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "Virhe MMS-palvelimeen yhdistäessä"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Module Player)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>Resoluutio</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bittiä"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bittiä"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Kanavat</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "Nearest (nopein)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Linear (nopea)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Spline (hyvä)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "Polyphase (paras)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>Näytteenottotaajuus</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Taso:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "Alaraja:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Reverb</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>Bass Boost</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>Surround</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>Preamp</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "Ylinäytteistä"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Kohinan vähennys"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Toista Amigan MOD-tiedostoja"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Kertaus</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "Kertojen määrä:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "Jos haluat kerrata ikuisesti, aseta kertojen määräksi -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Module Player)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Surround"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "Nämä asetukset tulevat voimaan, kun Audacious käynnistetään uudelleen."
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123-liitännäinen"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Lisäasetukset</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Käytä tarkkaa keston laskentaa (hidas)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 -palvelin"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS -liitännäinen"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Tuntematon HTTP-virhe"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Liian monta uudelleenohjausta"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Pysäytetty"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious ei tällä hetkellä soita mitään."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Työpöytäilmoitukset"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2538,55 +2589,64 @@ msgstr ""
"You should have received a copy of the GNU General Public License along with "
"this program. If not, see <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Näytä toiston kontrollit"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Näytä ilmoitukset aina"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Työpöytäilmoitukset"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "Sisällytä albumin nimi ilmoitukseen"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Näytä"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Keskeytä"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Seuraava"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Oletuslaite"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4-lähtö"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "OSS3-lähtö"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Oletuslaite"
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Ãänilaite:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Käytä vaihtoehtoista laitetta:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Tallenna äänenvoimakkuus eri sessioiden välillä."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Käytä OSS:n luomia formaatin muutoksia."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Kytke eksklusiivinen tila päälle virtuaalisen miksauksen estämiseksi."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2600,19 +2660,35 @@ msgstr ""
"Haluaisin kiittää ihmisiä kanavalla #audacious, erityisesti Tony Vroonia "
"sekä John Lindgreniä. Kiitokset myös edellisen OSS-liitännäisen kehittäjille."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4-lähtö"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Soittolistan hallinta"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Poista"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "_Nimeä uudelleen"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS-soittolistat"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2 -dekooderi"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio-lähtö"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2648,11 +2724,68 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio-lähtö"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "QtMultimedia-lähtö"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Etsi"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_Avaa kansio..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_Lisää kansio..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Avaa tiedostoja"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Lisää tiedostoja"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Edellinen"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Kertaus"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Sekoitus"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Qt-käyttöliittymä"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Uudelleenäytteistäjä"
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2660,98 +2793,106 @@ msgstr ""
"Uudelleenäytteistys-liitännäinen Audacioukselle\n"
"Copyright 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "Sivuuta/kertaa näytteet"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Lineaarinen interpolaatio"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Nopea sinc-interpolaatio"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "Kohtalainen sinc-interpolaatio"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Paras sinc-interpolaatio"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Muunnos</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Metodi:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Näytteenottotaajuus:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Kartoitus</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Käytä kartoituksia"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Uudelleenäytteistäjä"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "OK. Päivitetään raitoja käyttäjälle: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "Lupa evätty"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"Avaa seuraava linkki salliaksesi Audaciouksen päivittää soitettuja raitojasi:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"Pidä tämä ikkuna auki ja paina \"Tarkista oikeudet\" -painiketta uudelleen.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2759,33 +2900,37 @@ msgstr ""
"Soitettujen kappaleiden tiedot tallennetaan koneellesi.\n"
"Tiedot lähetetään heti kun mahdollista."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "Verkko-ongelma."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "Last.fm -palveluun yhdistettäessä ilmeni ongelmia. Yritä uudelleen."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "Tarkistetaan..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "_Tarkista oikeudet"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_Kumoa oikeudet"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"Sinun pitää sallia Audaciouksen päivittää raitoja Last.fm -tilillesi.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2793,7 +2938,7 @@ msgstr ""
"Scrobbler -liitännäistä ei voitu käynnistää.\n"
"Asennuksessasi saattaa olla jotain vikaa."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2810,11 +2955,7 @@ msgstr ""
"Kiitos John Lindgrenille avusta projektin alussa.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2822,7 +2963,11 @@ msgstr ""
"Audacious käyttää parannettua versiota Last.fm Scrobblerista.\n"
"Scrobbler -liitännäinen löytyy asetuksista."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL-lähtö"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2830,81 +2975,56 @@ msgstr ""
"SDL-lähdön liitännäinen Audacioukselle\n"
"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL-lähtö"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Kirjasto"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Tuntematon esittäjä"
+#: src/search-tool/search-tool.cc:394
+#, c-format
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d tulos"
+msgstr[1] "%d tulosta"
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Tuntematon albumi"
+#: src/search-tool/search-tool.cc:400
+#, c-format
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d piilotettu)"
+msgstr[1] "(%d piilotettua)"
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d kappale"
+msgstr[1] "%d kappaletta"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
msgstr ""
-"%s\n"
-" albumilla %s esittäjältä %s"
-#: src/search-tool/search-tool.c:631
-#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d albumi"
-msgstr[1] "%d albumia"
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d kappale"
-msgstr[1] ""
-"%s\n"
-" %s, %d kappaletta"
-
-#: src/search-tool/search-tool.c:639
-#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d kappale esittäjältä %s"
-msgstr[1] ""
-"%s\n"
-" %d kappaletta esittäjältä %s"
-
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Luo soittolista"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "L_isää soittolistalle"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Etsi kirjastosta"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2912,679 +3032,769 @@ msgstr ""
"Tuodaksesi musiikkikirjastosi Audacioukseen, valitse kansio ja paina sen "
"jälkeen päivitys painiketta."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Odota..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Valitse kansio"
-#: src/skins/menus.c:56
-msgid "Open Files ..."
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
msgstr ""
-#: src/skins/menus.c:57
-msgid "Open URL ..."
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Kanavat:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
msgstr ""
-#: src/skins/menus.c:59
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Hiljaisuuden poisto"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Hiljaisuuden poisto</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Raja-arvo:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
+msgid "Open Files ..."
+msgstr "Avaa tiedostoja..."
+
+#: src/skins/menus.cc:65
+msgid "Open URL ..."
+msgstr "Avaa URL..."
+
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Etsi kirjastosta"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Toisto"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Soittolista"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Näkymä"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
-msgstr ""
+msgstr "Palvelut"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
-msgstr ""
+msgstr "Tietoja..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
-msgstr ""
+msgstr "Asetukset..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
-msgstr ""
+msgstr "Lopeta"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
-msgstr ""
+msgstr "Kappaleen tiedot..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Kertaus"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Sekoitus"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Ãlä etene soittolistalla"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
-msgstr ""
-
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Edellinen"
+msgstr "Lopeta tämän kappaleen jälkeen"
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
-msgstr ""
+msgstr "Siirry kappaleeseen..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
-msgstr ""
+msgstr "Siirry kohtaan..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Uusi soittolista"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
-msgstr ""
+msgstr "Nimeä uudelleen soittolista..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
-msgstr ""
+msgstr "Poista soittolista"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
-msgstr ""
+msgstr "Edellinen soittolista"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
-msgstr ""
+msgstr "Seuraava soittolista"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
-msgstr ""
+msgstr "Tuo soittolista..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
-msgstr ""
+msgstr "Vie soittolista..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
-msgstr ""
+msgstr "Soittolistan hallinta..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
-msgstr ""
+msgstr "Jonohallinta..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
-msgstr ""
+msgstr "Päivitä soittolista"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Näytä soittolistan muokkain"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Näytä taajuuskorjain"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
-msgstr ""
+msgstr "Näytä jäljellä oleva aika"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Aina päällimmäisenä"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
-msgstr ""
+msgstr "Kaikissa työtiloissa"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
-msgid "Add URL ..."
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:138
+msgid "Add URL ..."
+msgstr "Lisää URL..."
+
+#: src/skins/menus.cc:139
msgid "Add Files ..."
-msgstr ""
+msgstr "Lisää tiedostoja..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Nimen mukaan"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Tiedostonimen mukaan"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Poista kaikki"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Tyhjennä jono"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Poista ei saatavilla olevat tiedostot"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Poista kopiot"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Poista ei valitut"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Poista valitut"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Etsi ja valitse"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Käänteinen valinta"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Ei mitään"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Valitse kaikki"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Albumin mukaan"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Raidan mukaan"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Esittäjän mukaan"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Albumin mukaan"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Raidan mukaan"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Sekoita lista"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Käännä lista"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Järjestä valitut"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Lajittele lista"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Leikkaa"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Kopioi"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Liitä"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
-msgstr ""
+msgstr "Lataa esiasetus..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
-msgstr ""
+msgstr "Lataa oletus"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
-msgstr ""
+msgstr "Lataa esiasetustiedosto..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
-msgstr ""
+msgstr "Lataa EQF-tiedosto..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
-msgstr ""
+msgstr "Tallenna esiasetus..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
-msgstr ""
+msgstr "Tallenna oletus"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
-msgstr ""
+msgstr "Tallenna esiasetustiedosto..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
-msgstr ""
+msgstr "Tallenna EQF-tiedosto..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
-msgstr ""
+msgstr "Poista esiasetus..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
-msgstr ""
+msgstr "Tuo Winamp-esiasetukset..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winampin klassinen käyttöliittymä"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Tallenna"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Lataa"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
-msgstr ""
+msgstr "Lataa esiasetustiedosto"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
-msgstr ""
+msgstr "Lataa EQF-tiedosto"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
-msgstr ""
+msgstr "Tallenna esiasetustiedosto"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
-msgstr ""
+msgstr "Tallenna EQF-tiedosto"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
-msgstr ""
+msgstr "Tuo Winamp-esiasetukset"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Esiasetukset"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Lataa esiasetus"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Lataa automaattinen esiasetus"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Tallenna esiasetukset"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Tallenna automaattinen esiasetus"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Poista esiasetus"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Poista automaattisesti ladattava esiasetus"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Soitin:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Soitin:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Valitse pääikkunan kirjasin:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Soittolista:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Soittolista:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Valitse soittolistan kirjasin:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
-msgstr ""
+msgstr "<b>Fontit</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Käytä bittikartta-kirjasimia (vain ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
-msgstr ""
+msgstr "Vieritä kappaleen nimeä"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Vieritä kappaleen nimeä kumpaankin suuntaan"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analyzer"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Scope"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Pois"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normaali"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Tuli"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Viivat"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Palkit"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Hitain"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Hidas"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Keskinkertainen"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Nopea"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Nopein"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Jää"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Tasainen"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
-msgstr ""
+msgstr "<b>Tyyppi</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
-msgstr ""
+msgstr "Visualisoinnin tyyppi:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
-msgstr ""
+msgstr "Näytä piikit"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
-msgstr ""
+msgstr "Väritys:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
-msgstr ""
+msgstr "Tyyli:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Yleiset"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualisaatio"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Esivahvistus"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audaciouksen taajuuskorjain"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Siirry kohtaan %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Ãänenvoimakkuus: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Tasapaino: %d%% vasen"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Tasapaino: keskellä"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Tasapaino: %d%% oikea"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Asetusvalikko"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Poista käytöstä 'Aina päällimmäisenä'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Käytä 'Aina päällimmäisenä'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Tiedoston tietolaatikko"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "Kertauksen alkupiste A asetettu."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "Kertauksen loppupiste B asetettu."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "Kertauspisteet tyhjennetty."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Yksittäinen -tila."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Soittolista -tila."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Pysäytä kappaleen jälkeen."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Etsi kappaleita aktiivisesta soittolistasta"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3596,57 +3806,61 @@ msgstr ""
"merkitystä. Jos et tiedä kuinka säännöllisiä lausekkeita käytetään, kirjoita "
"kenttään suoraan se mitä haluat etsiä."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Nimi:"
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr "Albumi:"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr "Esittäjä:"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
msgstr "Tiedostonimi:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Tyhjennä aiempi valinta ennen hakemista"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Lisää tai poista automaattisesti täsmäävät kappaleet jonosta"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Luo uusi soittolista täsmäävistä kappaleista"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audaciouksen soittolistan muokkain"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d / %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Pakattu Winamp 2.x skini"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Pakkaamaton Winamp 2.x skini"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Ei voitu luoda kansiota (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile-liitännäinen"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3686,82 +3900,74 @@ msgstr ""
"this program; if not, write to the Free Software Foundation, Inc., 51 "
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile-liitännäinen"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Tietoja Sndio Output -liitännäisestä"
-
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
msgstr ""
-"Sndio Output -liitännäinen\n"
-"\n"
-"Luonut Thomas Pfaff <tpfaff at tp76.info>\n"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Formaattia ei tueta"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "Laite (tyhjä oletusta varten):"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
msgstr ""
-"Yritettiin toistaa formaattia jota äänilaite ei tue.\n"
-"\n"
-"Yritä uudelleen kun sndiod(1) palvelin on käynnissä."
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio-laite"
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Sndio-virhe: äänimuoto ei ole tuettu (%d)"
+
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Sndio-virhe: sio_open() epäonnistui"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(tyhjä tarkoittaa oletusta)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Sndio-virhe: sio_setpar() epäonnistui"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Sndio-virhe: sio_start() epäonnistui"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Kappaleen vaihtuminen"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Komento joka ajetaan kun kappaleen toisto alkaa."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Komentoriville syötettävät parametrit tulisi asettaa "
+"lainausmerkkien sisään. Lainausmerkkien käyttämättä jättäminen on "
+"tietoturvariski.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Komennot</b>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Komento:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Kappaleen alussa suoritettava komento:"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Komento joka ajetaan kun kappale lähestyy loppua."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Kappaleen päättyessä suoritettava komento:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "Komento joka ajetaan kun päästään soittolistan loppuun."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Soittolistan päättyessä suoritettava komento:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Komento joka ajetaan kun kappaleen nimi vaihtuu (esim. internet-virrat)."
+"Suoritettava komento, kun kappaleen nimi muuttuu (verkon suoratoistoja "
+"varten):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3775,36 +3981,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Voit käyttää seuraavia merkkijonoja jotka \n"
-"korvataan komentoa kutsuttaessa.\n"
-"(kaikki eivät välttämättä ole hyödyllisiä):\n"
-"\n"
-"%F: taajuus (hertseinä)\n"
-"%c: kanavien lukumäärä\n"
-"%f: tiedostopolku\n"
-"%l: kesto (millisekunteina)\n"
-"%n tai %s: kappaleen nimi\n"
-"%r: nopeus (bittejä/sekunti)\n"
-"%t: sija soittolistassa (%02d)\n"
-"%p: toistetaanko jotain (1 tai 0)\n"
-"%a: esittäjä\n"
-"%b: albumi\n"
-"%T: kappaleen nimi"
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>Komentoriville syötettävät parametrit tulisi asettaa "
-"lainausmerkkien sisään. Lainausmerkkien käyttämättä jättäminen on "
-"tietoturvariski.</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Komennot"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Kappaletiedot (Qt)"
+
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX Resampler"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3818,51 +4004,51 @@ msgstr ""
"Perustuu Sample Rate Converter -liitännäiseen:\n"
"Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Nopea"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Matala"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Korkea"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Erittäin korkea"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Laatu:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Nopeus ja sävelkorkeus"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Nopeus ja sävelkorkeus</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Nopeus:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Sävelkorkeus:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Nopeus ja sävelkorkeus"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Tilaikoni"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
-msgstr ""
+msgstr "Ase_tukset..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3879,39 +4065,39 @@ msgstr ""
"\n"
"Tämä liitännäinen tarjoaa järjestelmäpalkkiin sijoitettavan ikonin."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Hiiren rullan vieritystoiminto</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Muuta äänenvoimakkuutta"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Vaihda kappaletta"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Muut asetukset</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Poista ponnahdusikkuna käytöstä"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Sulje järjestelmäpalkkiin"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Etene soittolistassa kun vieritetään ylöspäin"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Tilaikoni"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Stereo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3921,24 +4107,24 @@ msgstr ""
"\n"
"By Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra Stereo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Sointugeneraattori"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Sointugeneraattori:"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3952,15 +4138,11 @@ msgstr ""
"Käyttääksesi, lisää URL: tone://frequency1;frequency2;frequency3;...\n"
"esim. tone://2000;2005 toistaaksesi 2000 Hz:n ja 2005 Hz:n soinnun"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Sointugeneraattori"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Ãänen poisto"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3998,11 +4180,35 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis -dekooderi"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX-dekooderi"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4012,19 +4218,19 @@ msgstr ""
"Perustuu in_vtx.dll:ään, luonut Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious liitännäisen luonut Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX-dekooderi"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack-dekooderi"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "häviöllinen (hybridi)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "häviöllinen"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4034,14 +4240,18 @@ msgstr ""
"\n"
"Osan liitännäisen koodista kirjoittanut Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack-dekooderi"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF-dekooderi"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>XSF-asetukset</b>"
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Ãlä huomioi tiedoston ilmoittamaa kestoa"
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "XML jaettavat soittolistat (XSPF)"
diff --git a/po/fr.po b/po/fr.po
index 949af2b87aba..7cd058dec7d3 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -3,18 +3,18 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# Alain-Olivier Breysse, 2012-2013
-# Oxayotl <jagw40k at free.fr>, 2013
+# yahoe.001, 2012-2013
+# Oxayotl <jagw40k at free.fr>, 2013-2014
# Oxayotl <jagw40k at free.fr>, 2011-2012
# Jean-Alexandre Anglès d'Auriac <jagw40k at free.fr>, 2011
-# Alain-Olivier Breysse, 2013-2014
+# yahoe.001, 2013-2015
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:41+0000\n"
-"Last-Translator: Alain-Olivier Breysse\n"
+"POT-Creation-Date: 2015-04-03 11:52+0200\n"
+"PO-Revision-Date: 2015-03-15 20:32+0000\n"
+"Last-Translator: yahoe.001\n"
"Language-Team: French (http://www.transifex.com/projects/p/audacious/"
"language/fr/)\n"
"Language: fr\n"
@@ -23,40 +23,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "son ambiophonique"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "Décodeur AAC (MP4)"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "Décodeur AAC (brut)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (Lecteur AdLib)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "séquencé"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (Lecteur AdLib)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarme"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "Définir l'alarme..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -66,11 +54,7 @@ msgstr ""
"\n"
"Développé à l'origine par Adam Feakin et Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarme"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -110,7 +94,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -149,7 +133,7 @@ msgstr ""
" Exécute cette commande à l'heure de l'alarme.\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -173,384 +157,390 @@ msgstr ""
" Saisir le rappel dans le champs de texte et cocher\n"
" la case pour que le rappel soit affiché."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Ceci est votre réveil."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "Votre pense-bête pour aujourd'hui estâ¦"
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Pense-bête"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Lundi"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Mardi"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Mercredi"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Jeudi"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Vendredi"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Samedi"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Dimanche"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Alarm Settings"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "_OK"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "_Annuler"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Heure"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarme à (par défaut) :"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Silencieux après :"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "heures"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minutes"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Choisir les jours où l'alarme se déclenche"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Jour"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Par défaut"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Jours"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Fondu"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "secondes"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Volume"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Commencer à "
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Finir à "
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Actuel"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Commande additionnelle"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "activer"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Liste de lecture (optionnelle)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Choisir une liste de lecture"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Options"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Que signifient ces options ?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Aide"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Illustration"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Illustration (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "Sortie ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"Greffon de sortie ALSA pour Audacious\n"
+"Tous droits réservés © 2009-2012 John Lindgren\n"
+"Mes remerciements à Wiliam Pitcock, auteur du greffon de sortie ALSA NG, "
+"dont le code a servi de référence lorsque la documentation d'ALSA n'était "
+"pas suffisante."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(aucune description)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Périphérique PCM par défaut"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Mélangeur audio par défaut"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "Périphérique PCM :"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Canal de mélange audio :"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Mélangeur :"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Contourner le problème d'interruption du flux"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (Lecteur MIDI)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"Greffon de sortie ALSA pour Audacious\n"
-"Tous droits réservés © 2009-2012 John Lindgren\n"
-"Mes remerciements à Wiliam Pitcock, auteur du greffon de sortie ALSA NG, "
-"dont le code a servi de référence lorsque la documentation d'ALSA n'était "
-"pas suffisante."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "Sortie ALSA"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (Lecteur MIDI)"
+"AMIDI-Plug\n"
+"lecteur musical modulaire MIDI\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
+"\n"
+"écrit par Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"un grand merci à ...\n"
+"\n"
+"Clemens Ladisch et Jaroslav Kysela\n"
+"pour leurs excellents programmes aplaymidi et amixer ;\n"
+"ils furent très utiles, avec les docs alsa-lib, afin d'en apprendre\n"
+"plus sur l'API ALSA\n"
+"\n"
+"Alfredo Spadafina\n"
+"pour le beau logo de clavier MIDI\n"
+"\n"
+"Tony Vroon\n"
+"pour son aide appréciée durant les tests alpha"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "Remplacer le gain par défaut :"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "Remplacer la polyphonie par défaut :"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "Remplacer la réverbération par défaut :"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "Marche"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "Remplacer le refrain par défaut :"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>Lecture</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "Transposer :"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "demi-tons tempérés"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "Décalage des percussions :"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>Avancé</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "numéros de note"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "Extraire les commentaires des fichiers MIDI"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Ignorer le silence d'ouverture"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "Extraire les paroles des fichiers MIDI"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Ignorer le silence de fermeture"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>Synthétiseur</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr "Fréquence d'échantillonnage :"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "Fréquence de l'échantillon :"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - choix du fichier SoundFont"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Annuler"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "_Ouvrir"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "Nom du fichier"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "Nom de fichier"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Taille (octets)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nom :"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> Infos MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Format :"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Durée (ms) :"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Nombre de pistes :"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variable"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM :"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg) :"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Division du temps :"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> Commentaires et paroles MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
-msgstr "* aucun commentaire disponible dans ce fichier MIDI *"
+msgstr "* aucun commentaire proposé dans ce fichier MIDI *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
-msgstr "* aucune parole disponible dans ce fichier MIDI"
+msgstr "* aucune parole proposée dans ce fichier MIDI"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Fermer"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (UTF-8 invalide)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Ã propos d'AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"lecteur musical modulaire MIDI\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"développé par Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"un grand merci à ...\n"
-"\n"
-"Clemens Ladisch et Jaroslav Kysela\n"
-"pour leurs excellents programmes aplaymidi et amixer ;\n"
-"ils furent très utiles, avec les docs alsa-lib, afin d'en apprendre\n"
-"plus à propos de l'interface de programmation ALSA\n"
-"\n"
-"Alfredo Spadafina\n"
-"pour le beau logo de clavier MIDI\n"
-"\n"
-"Tony Vroon\n"
-"pour son aide appréciée durant les tests alpha"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -568,156 +558,151 @@ msgstr ""
"Basé en partie sur la bibliothèque Ghosd de Evan Martin :\n"
"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (Affichage à l'écran)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Rectangle"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Rectangle arrondi"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Rectangle concave"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Aucun"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Début de la lecture"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr ""
"Déclenche l'affichage à l'écran lorsqu'une entrée de la liste de lecture est "
"jouée."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Changement de titre"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Déclenche l'affichage à l'écran si, pendant la lecture, le titre du morceau "
-"change alors que le nom du fichier est identique. Cette option est "
-"particulièrement utile pour afficher le changement de titre des flux "
-"Internet."
+"Déclenche l'affichage à l'écran lorsque le titre du morceau change (pour les "
+"flux Internet) :"
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "En pause"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Déclenche l'affichage à l'écran lorsque la lecture est mise en pause."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Pause désactivée"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr ""
"Déclenche l'affichage à l'écran lorsque la pause de lecture eest désactivée."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Position"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Décalage horizontal X :"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Décalage vertical Y :"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Largeur maximale d'affichage à l'écran :"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Options pour moniteurs multiples"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Affichage à l'écran avec :"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "tous les moniteurs"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "le moniteur %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Durée (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Affichage :"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Fondu d'entrée :"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Fondu de sortie :"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Polices"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Police %i :"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Ombre"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Style du rendu"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Couleurs"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Couleur %i :"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Activer le déclencheur"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Ãvénement"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Gestionnaire composite détecté"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -728,112 +713,112 @@ msgstr ""
"veuillez activer un gestionnaire composite sinon l'affichage à l'écran ne "
"fonctionnera pas correctement."
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "La fausse transparence ne nécessite pas de gestionnaire composite."
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Transparence"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Fausse transparence"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Véritable transparence (nécessite l'extension composite de X)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "L'extension composite n'est pas chargée"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
-msgstr "L'extension composite n'est pas disponible"
+msgstr "L'extension composite n'est pas proposée"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Affichage à l'écran Audacious</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Affichage à l'écran Audacious - configuration"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "_Test"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "_Définir"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Arrangement"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animation"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Texte"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Décoration"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Déclenchement"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Options diverses"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Test"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "Liste de lecture ASXv3"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "Listes de lecture ASXv1 et ASXv2"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Listes de lecture au format Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Couleur</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Oscilloscope flou"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Stéréophonique-vers-binaural Bauer (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Préréglages :"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Niveau d'entrée :"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Fréquence de coupure :"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Préréglages :"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Stéréophonique-vers-binaural Bauer (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Analyseur de spectre"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Greffon CD audio"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -855,173 +840,160 @@ msgstr ""
"\n"
"Ceci était un projet Google « Summer of Code » de 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Lecteur</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Vitesse de lecture :"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Forcer le lecteur :"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Métadonnées</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Utiliser CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Utiliser CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Utiliser HTTP Ã la place de CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Serveur :"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Chemin :"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Port :"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Greffon CD audio"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "Ãchec de l'initialisation du sous-système cdio"
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "URI %s invalide."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Piste %d non trouvée."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "La piste %d en est une de données."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Ãchec de l'ouverture de la sortie audio"
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Erreur de lecture du CD audio."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "CD audio"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "Piste %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Ãchec de l'ouverture du lecteur de CD %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Aucun lecteur de CD audio n'a été trouvé."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "N'a pu finir d'initialiser le lecteur CD ouvert."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Ãchec de la récupération du premier et/ou du dernier numéro de piste"
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
"Impossible de lire le numéro de secteur logique (LSN) de début ou de fin "
"pour la piste %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Ãchec de la connexion à CDDB."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Ãchec de la requête auprès du serveur CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Ãchec de la requête auprès du serveur CDDB : %s ."
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Ãchec de la lecture des informations cddb : %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Le lecteur est vide"
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Type de disque non pris en charge."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Ãléments du menu CD Audio"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Lire le CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Ajouter un CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Ãléments du menu CD Audio"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Compression</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Volume central :"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Plage dynamique :"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"Greffon de compression d'étendue dynamique pour Audacious\n"
-"Tous droits réservés © 2010-2012 John Lindgren"
+"Tous droits réservés © 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Compresseur de gamme dynamique"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1038,206 +1010,238 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Grave :"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Aigu :"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "Ãcho :"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Durée par défaut du morceau :"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>Rééchantillonnage</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Activer le rééchantillonnage"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Fréquence de rééchantillonnage :"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ignorer la durée des balises SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Augmenter la réverbération"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Décodeur « Game Console Music »"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"Le fondu enchaîné a échoué car les morceaux avaient un nombre différents de "
-"canaux. Tu peux utiliser le « Mélangeur de canaux » pour les uniformiser."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "Sortie CoreAudio"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"Le fondu enchaîné a échoué car les morceaux avaient des taux "
-"dâéchantillonnage différents. Tu peux utiliser le « Convertisseur de taux "
-"dâéchantillonnage » pour les uniformiser."
+"Greffon de sortie CoreAudio pour Audacious\n"
+"Tous droits réservés © 2014 William Pitcock\n"
+"\n"
+"Basé sur le greffon de sortie SDL pour Audacious\n"
+"Tous droits réservés © 2010 John Lindgren"
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "Utiliser le mode exclusif"
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Greffon de fondus pour Audacious\n"
-"Tous droits réservés © 2010-2012 John Lindgren"
+"Greffon de fondu enchaîné pour Audacious\n"
+"Tous droits réservés © 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Fondu enchaîné</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "Lors d'un changement automatique de morceau"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "Recouvrement:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "Lors d'un positionnement ou d'un changement manuel de morceau"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Astuce</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+"Pour un meilleur fondu, activer\n"
+"l'effet Suppression des silences."
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Fondu enchaîné"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"Le fondu enchaîné a échoué car les morceaux avaient un nombre différents de "
+"canaux. Tu peux utiliser le « Mélangeur de canaux » pour les uniformiser."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"Le fondu enchaîné a échoué car les morceaux avaient des taux "
+"dâéchantillonnage différents. Tu peux utiliser le « Convertisseur de taux "
+"dâéchantillonnage » pour les uniformiser."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Cristalliseur</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intensité :"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Cristalliseur "
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Greffon des fichiers .cue"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Supprimer les fichiers"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "Erreur lors du déplacement de %s vers la corbeille : %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "Erreur lors de la suppression de %s : %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "Erreur lors de la suppression de %s : n'est pas un fichier local."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "Voulez-vous déplacer les fichiers sélectionnés vers la corbeille ?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "Déplacer vers la corbeille"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "Voulez-vous supprimer définitivement les fichiers sélectionnés ?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Supprimer"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Annuler"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "Supprimer les fichiers"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "Supprimer les fichiers sélectionnés"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>Méthode de suppression</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "Déplacer vers la corbeille au lieu de supprimer immédiatement"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+"Greffon d'écho\n"
+"Par Johan Levin, 1999\n"
+"Ãcho ambiophonique par Carl van Schaik, 1999\n"
+"Mise à niveau pour Audacious par William Pitcock et John Lindgren, 2010-2014"
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Ãcho</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Retard :"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Retour :"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Volume :"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Effet d'écho\n"
-"Par Johan Levin, 1999\n"
-"\n"
-"Effet d'écho ambiophonique par Carl van Schalk, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Ãcho"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Greffon FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1253,55 +1257,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "Greffon FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Greffon FileWriter"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Format du fichier de sortie :"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Configurer"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Enregistrer dans le répertoire d'origine"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Enregistrer dans un répertoire personnalisé"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Dossier de destination :"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Choisir un dossier"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Obtenir le nom du fichier à partir de :"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Générer le nom de fichier à partir de :"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "balises originales du fichier"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Balise originale du fichier"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "nom du fichier original"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Nom original du fichier"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Conserver l'extension du nom de fichier"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "Inclure l'extension originale du nom de fichier"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
msgstr "Ajouter le numéro de la piste au début du nom du fichier"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1332,165 +1336,169 @@ msgstr ""
"temps que ce programme ; si ce nâest pas le cas, écrivez à la Free Software "
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "Greffon FileWriter"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Auto"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Stéréo combinée"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stéréo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Configuration MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_OK"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Qualité de l'algorithme :"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Fréquence d'échantillonnage de sortie :"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr "Fréquence de sortie de l'échantillon :"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Débit binaire / Taux de compression :"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "Rapport débit binaire / compression :"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Débit binaire (kbps)"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Taux de compression :"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Mode audio :"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "Divers :"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Forcer le respect strict des normes ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr "Respecter rigoureusement les normes ISO"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Protection contre les erreurs"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Qualité"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
-msgstr "Activer DBV/DBM (Débit Binaire Variable/Débit Binaire Moyen)"
+msgstr "Activer DBV/DBM (débit binaire variable/débit binaire moyen)"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Type :"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Options DBV :"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Débit binaire minimal (kbps) :"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Débit binaire maximal (kbps) :"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Forcer de manière stricte le débit binaire minimal"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Options DBM :"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Débit binaire moyen (kbps) :"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
-msgstr "Niveau de qualité BDV (Débit Binaire Variable) :"
+msgstr "Niveau de qualité DBV (débit binaire variable) :"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Ne pas écrire l'en-tête BDV Xing"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Omettre l'en-tête DBV (débit binaire variable) Xing"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
-msgstr "DBV/DBM (Débit Binaire Variable/Débit Binaire Moyen)"
+msgstr "DBV/DBM (débit binaire variable/débit binaire moyen)"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr "Paramètres de trame :"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Marquer comme soumis aux droits d'auteur"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Marquer comme originale"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "Paramètres ID3 :"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Forcer l'ajout de la version 2 des balises"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Ajouter uniquement la version 1 des balises"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Ajouter uniquement la version 2 des balises"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Balises"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Configuration de l'encodeur Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Niveau de qualité (0 - 10) :"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "Décodeur FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "sans perte"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1502,11 +1510,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "Décodeur FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1514,11 +1518,19 @@ msgstr ""
"Greffon GIO pour Audacious\n"
"Tous droits réservés © 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "Greffon GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "Le mode lecture-et-ajout n'est pas pris en charge"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "Mode d'ouverture invalide"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1538,534 +1550,620 @@ msgstr ""
"\n"
"Licence : GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "Analyseur de spectre utilisant OpenGL"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+"Analyseur de spectre OpenGL pour Audacious\n"
+"Tous droits réservés © 2013 Christophe Budé, John Lindgren et Carlo Bramini\n"
+"Tous droits réservés © 2014 William Pitcock\n"
+"\n"
+"Basé sur le greffon XMMS :\n"
+"Tous droits réservés © 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas "
+"Nilsson, et 4Front Technologies\n"
+"\n"
+"Licence : GPLv2+"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "Analyseur de spectre OpenGL (Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "Raccourcis de GNOME"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-"Greffon de support des raccourcis de Gnome\n"
-"Permet de contrôler Audacious via les raccourcis de Gnome\n"
+"Greffon de prise en charge des raccourcis de GNOME\n"
+"Vous permet de contrôler le lecteur avec les raccourcis de GNOME\n"
"\n"
"Tous droits réservés © 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Raccourcis de Gnome"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Numéro de l'entrée"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Titre"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Artiste"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Année"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Album"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Artiste de l'album"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Numéro de piste"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Genre"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Position dans la file"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Durée"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Chemin du fichier"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Nom du fichier"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Titre personnalisé"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Débit binaire"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
-msgstr "Colonnes disponibles :"
+msgstr "Colonnes proposées :"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "Colonnes affichées"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Outil de recherche"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Intégrer à gauche"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Intégrer à droite"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Intègrer en haut"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Intègrer en bas"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Séparer"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Désactiver"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Outil de recherche"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Ouvrir des fichiers..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Ouvrir une _URL..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_Ajouter des fichiers..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Ajouter une U_RL..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "Rechercher dans _l'audiothèque"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "Ã propos _de..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "_Paramètres..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Quitter"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Lire"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Paus_e"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Arrêt"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "Pré_cédent"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "S_uivant"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Répéter"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "Lecture _aléatoire"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "_Ne pas avancer dans la liste de lecture"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Arrêter après ce morceau"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Infos sur le morceau..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Sauter à la _position... (temps)"
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "Sauter au _morceau..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "Point de répétition _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "Point de répétition _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_Effacer les points de répétition"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Par _titre"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "Par nom de _fichier"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "Par chemin de _fichier"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Par _chemin de fichier"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Par _numéro de piste"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Par _artiste"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Par al_bum"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Par Artiste de l'albu_m"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Par _date de parution"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "Par _Genre"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "Par _durée"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
-msgstr "Par chemin d'accès de _fichier"
+msgstr "Par chemin de _fichier"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Par _titre personnalisé"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Ordre i_nversé"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "Ordre _aléatoire"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "Lire cette liste de lecture"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_Lire/Reprendre"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Rafraîchir"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Trier"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "Trier la sé_lection"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "Enlever les _doublons"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
-msgstr "Retirer les fichiers _non disponibles"
+msgstr "Retirer les fichiers _absents"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Nouvelle"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
-msgstr "Re_nommer ..."
+msgstr "Re_nommer..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "Enle_ver"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importer"
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Exporter"
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "_Gestionnaire de listes de lecture..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Gestionnaire de file d'_attente..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Augmenter le _volume"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "_Réduire le volume"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "Ãga_liseur"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "E_ffets..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Afficher la barre de _menu"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Afficher la barre d'i_nfos"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Afficher la vis_ualisation « Barre d'infos »"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Afficher la _barre d'état"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Afficher le temps _restant"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "_Visualisations..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Fichier"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Lecture"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "L_iste de lecture"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Services"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Sortie"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Affichage"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Ajouter / retirer de la file d'attente"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "_Ouvrir le dossier conteneur"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Cou_per"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Copier"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Coller"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Sélectionner _tout"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
-msgstr "_Renommer â¦"
+msgstr "_Renommerâ¦"
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>Onglets de la liste de lecture</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "Toujours montrer les onglets"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "Montrer le nombre d'entrées"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "Montrer les boutons de fermeture"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>Colonnes de la liste de lecture</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "Montrer les en-têtes des colonnes"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Divers</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
-msgstr "Avance/retour avec les flèches :"
+msgstr "Positionnement avec les flèches :"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "Déplacer vers le morceau en cours"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "Interface GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Mise en mémoire tampon..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d canal"
msgstr[1] "%d canaux"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Mode « Fichier unique »."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Mode « Liste de lecture »."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Arrêter après le morceau."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Piste précédente"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Lire"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pause/Reprise"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Arrêt"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Piste suivante"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "Avancer de 5 secondes"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "Reculer de 5 secondes"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Muet"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Augmenter le volume"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Réduire le volume"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Sauter au fichier"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "Montrer/cacher les fenêtres du lecteur"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Activer l'affichage à l'écran"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "Activer/désactiver la répétition"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "Activer/désactiver la lecture aléatoire"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "Activer/désactiver l'arrêt après le morceau en cours"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Monter les fenêtres du lecteur au premier plan"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(aucun)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2077,15 +2175,11 @@ msgstr ""
"\n"
"Souhaitez-vous poursuivre ?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Association des boutons de la souris"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Configuration du greffon « Raccourcis universels »"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2094,23 +2188,27 @@ msgstr ""
"Vous pouvez aussi créer des associations avec les boutons de la souris.\n"
" "
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Raccourcis clavier :"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Action : </b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Association de touches :</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "_Ajouter"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Raccourcis universels"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2137,60 +2235,59 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Raccourcis universels"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "Sortie JACK"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "Connecter à tous les ports Jack disponibles"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "Se connecter automatiquement aux ports de sortie"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "Connecter seulement aux ports de sortie"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr ""
+"Seulement %d ports de sortie JACK ont été trouvés mais sont %d sont exigés."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "Ne connecter à aucun port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Erreur lors de la connexion au port JACK %s."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "Mode de connexion :"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+"JACK ne prend en charge que l'audio à virgule flottante. Vous devez changer "
+"la profondeur de sortie binaire pour « virgule flottante » dans les "
+"paramètres d'Audacious."
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "Activer l'impression du débogage"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr ""
+"Ãchec lors de la connexion au serveur JACK ; est-il en cours d'exécution ?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Basé sur xmms-jack, par Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Porté pour Audacious par Giacomo Lozito"
+"Le serveur JACK exige un taux d'échantillonnage de %d Hz, mais Audacious lit "
+"à %d Hz. Veuillez utiliser l'effet Convertisseur de taux dâéchantillonnage "
+"pour corriger cette discordance."
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "Sortie JACK"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "Réglages %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Réglages de l'hôte ADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Chemins de recherche des greffons :"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2201,25 +2298,25 @@ msgstr ""
"Après avoir ajouté de nouveaux chemins, presser sur Entrée pour rechercher "
"des nouveaux greffons.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
-msgstr "Greffons disponibles :"
+msgstr "Greffons proposés :"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Activer"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Greffons activés :"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Paramètres"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2227,47 +2324,15 @@ msgstr ""
"Hôte LADSPA pour Audacious\n"
"Tous droits réservés © 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
-msgstr "Hôte LADSPA"
-
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: n'a pas pu initialiser la prise en charge de LIRC\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: N'a pas pu lire le fichier de configuration de LIRC\n"
-"%s: veuillez lire la documentation de LIRC STP\n"
-"%s: comment créer un fichier de configuration valide\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: essaie de se reconnecterâ¦\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: commande inconnue « %s »\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: déconnecté de LIRC\n"
+msgstr "Hôte LADSPA"
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: essaiera de se reconnecter toutes les %d secondesâ¦\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Greffon LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2296,73 +2361,81 @@ msgstr ""
"\n"
"Pour plus d'information sur LIRC, se référer à http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Connexion</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Se reconnecter automatiquement au serveur LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Attendre avant de se reconnecter :"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Greffon LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "Greffon LyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
-msgstr "Aucune parole disponible"
+msgstr "Aucune parole proposée"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Erreur"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Impossible de récupérer %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Erreur"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Impossible d'analyser %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Recherche de paroles â¦"
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Métadonnées de morceau manquantes"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Connexion à lyrics.wikia.com â¦"
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "Greffon LyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "Greffon LyricWiki (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "Listes de lecture M3U"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Métronome"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Métronome : %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Métronome : %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2376,11 +2449,11 @@ msgstr ""
"Par exemple. tact://77 pour battre 77 temps par minutes\n"
"ou tact://60*3/4 pour battre 60 temps en mesures 3/4"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Métronome"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Mélangeur de canaux"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2388,152 +2461,184 @@ msgstr ""
"Greffon de mélange des canaux pour Audacious\n"
"Tous droits réservés © 2011-2012 John Lindgren et MichaŠLipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Mélangeur de canaux</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Canaux de sortie :"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Mélangeur de canaux"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "Greffon MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "Erreur lors de la connexion au serveur MMS"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Lecteur de module)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>Résolution</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bits"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bits"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Canaux</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "Le plus proche (le plus rapide)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Linéaire (rapide)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Interpolation par segments (bon)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "Polyphasé (le meilleur) "
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>Fréquence dâéchantillonnage</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr "<b>Taux de l'échantillon</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr " Niveau :"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "Coupure :"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Réverbération</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>Amplificateur de basses</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>Ambiophonique </b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>Préampli</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "Suréchantillonnage"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Réduction du bruit"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Jouer les MODs Amiga"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Répéter</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "Comptage des répétitions :"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "Pour répéter à l'infini, mettre le comptage des répétions à -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Lecteur de module)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Son ambiophonique"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "Ces paramètres prendront effet lorsque Audacious sera redémarré."
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "Greffon MPG123"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Avancé</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Utiliser un calcul précis de durée (lent)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Son ambiophonique"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "Serveur MPRIS 2"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Greffon HTTP/HTTPS neon"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "Erreur lors de l'analyse de la redirection"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Erreur HTTP inconnue"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "Erreur lors de l'analyse de l'URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Trop de redirections"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Arrêté"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious est inactif."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Notifications du bureau"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2571,55 +2676,64 @@ msgstr ""
"temps que ce programme ; si ce nâest pas le cas, écrivez à la Free Software "
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Permettre le contrôle d'Audacious depuis les notifications."
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Rendre les notifications persistantes."
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Notifications du bureau"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "Inclure le nom de l'album dans la notification"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Afficher"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pause"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Suivant"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Périphérique par défaut"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "Sortie OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "Sortie OSS3"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Dispositif par défaut"
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Périphérique audio :"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Utiliser un autre périphérique :"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Conserver le volume d'une session à l'autre"
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Activer les conversions de format du logiciel OSS."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Activer le mode exclusif pour empêcher le mixage virtuel."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2634,19 +2748,35 @@ msgstr ""
"Tony Vroon and John Lindgren, et bien entendu les auteurs du précédent "
"greffon OSS."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "Sortie OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Gestionnaire de listes de lecture"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Entrées"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Enlever"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "Ren_ommer"
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "Listes de lecture PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "Décodeur OpenPSF PSF1/PSF2"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "Sortie PulseAudio"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2681,11 +2811,73 @@ msgstr ""
"temps que ce programme ; si ce nâest pas le cas, écrivez à la Free Software "
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "Sortie PulseAudio"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "Sortie QtMultimédia"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"Sortie Audio QtMultimédia pour Audacious\n"
+"Tous droits réservés © 2014 Willian Pitcock\n"
+"\n"
+"Basé sur le greffon de sortie SDL pour Audacious\n"
+"Tous droits réservés © 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Je travaille..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Rechercher"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_Ouvrir un dossier..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_Ajouter un dossier..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "_Inspecteur de journaux..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Fichiers ouverts"
-#: src/resample/resample.c:165
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Ajouter des fichiers"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Précédent"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Répéter"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Lecture aléatoire"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Interface Qt"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Convertisseur de taux dâéchantillonnage"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2693,100 +2885,108 @@ msgstr ""
"Greffon de convertisseur de taux dâéchantillonnage pour Audacious\n"
"Tous droits réservés © 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "Sauter/répéter les échantillons"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Interpolation linéaire"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Interpolation sinus cardinal rapide"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "Interpolation sinus cardinal moyenne"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Interpolation sinus cardinal la meilleure"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Conversion</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Méthode :"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Taux :"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Mappage de taux</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Utiliser les mappages de taux"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz :"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz :"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22,05 kHz :"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32,0 kHz :"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz :"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz :"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88,2 kHz :"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz :"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176,4 kHz :"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz :"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Convertisseur de taux dâéchantillonnage"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "OK. Scrobble pour l'utilisateur : %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "Permission refusée."
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"Accéder au lien suivant pour permettre à Audacious de scrobbler vos "
"lectures :"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"Garder cette fenêtre ouverte et cliquer sur « Vérifier les permissions » de "
"nouveau.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2794,34 +2994,38 @@ msgstr ""
"Pas d'inquiétude. Vos scrobbles sont sauvegardés sur votre ordinateur.\n"
"Ils seront transmis dès qu'Audacious en aura la permission."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "Problème de réseau."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "Il a eu un problème lors du contact de Last.fm. Ressayer plus tard."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
-msgstr "Vérification ..."
+msgstr "Vérification..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "Véri_fier les permissions"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_Révoquer les permissions"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"Vous devez autoriser Audacious à scrobbler vos pistes vers votre compte Last."
"fm.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2829,7 +3033,7 @@ msgstr ""
"Le greffon scrobbler n'a pu être démarré.\n"
"Il y a peut-être un problème avec votre installation."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2848,11 +3052,7 @@ msgstr ""
"ce projet.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2861,7 +3061,11 @@ msgstr ""
"fm. \n"
"Veuillez vérifier les propriétés du greffon Scrobbler 2.0."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "Sortie SDL"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2869,761 +3073,828 @@ msgstr ""
"Greffon de sortie SDL pour Audacious\n"
"Tous droits réservés © 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "Sortie SDL"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Audiothèque"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Artiste inconnu"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Album inconnu"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" dans %s par %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d résultat"
+msgstr[1] "%d résultats"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d album"
-msgstr[1] "%d albums"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d caché)"
+msgstr[1] "(%d cachés)"
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d morceau"
-msgstr[1] ""
-"%s\n"
-" %s, %d morceaux"
-
-#: src/search-tool/search-tool.c:639
-#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d morceau par %s"
-msgstr[1] ""
-"%s\n"
-" %d morceaux par %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d morceau"
+msgstr[1] "%d morceaux"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "de ce genre"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "sur"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "par"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Créer une liste de lecture"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Ajouter à la liste de lecture"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Rechercher dans l'audiothèque"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
-"Pour importer votre audiothèque dans Audacious, choisir un dossier, puis "
-"utiliser l'icône de rafraîchissement."
+"Pour importer votre audiothèque dans Audacious, choisissez un dossier et "
+"cliquez ensuite sur l'icône de rafraîchissement."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Veuillez patienterâ¦"
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Choisir un dossier"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "Lecteur SID"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>Sortie</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Canaux :"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Ãmulation</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "Ãmuler MOS 8580 (par défaut : MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "Ne pas choisir automatiquement le modèle de puce"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Ãmuler le filtre"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Vitesse d'horloge : "
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "Ne pas choisir automatiquement la vitesse d'horloge"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>Durée de lecture</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "Définir une durée maximale de lecture :"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Ã n'utiliser que si la longueur du morceau est inconnue"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "Définir une durée minimum de lecture :"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Sous-morceaux</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "Activer les sous-morceaux"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "Ignorer les sous-morceaux plus courts que :"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Note</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Suppression des silences"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"Greffon de Suppression des silences pour Audacious\n"
+"Tous droits réservés © John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Suppression des silences</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Seuil :"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "Ouvrir les fichiers..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "Ouvrir l'URL..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Rechercher dans l'audiothèque"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Lecture"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Liste de lecture"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Affichage"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "Services"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
-msgstr "Ã propos de..."
+msgstr "Ã propos..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "Paramètres..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "Quitter"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "Infos sur le morceau..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Répéter"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Lecture aléatoire"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Ne pas avancer dans la liste de lecture"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "Arrêter après ce morceau"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Précédent"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "Définir une répétition A-B"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "Effacer la répétition A-B"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "Sauter au morceau..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "Sauter à la positon (temps)â¦"
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "Jouer cette liste de lecture"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "Lire/Reprendre"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Nouvelle liste de lecture"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "Renommer la liste de lecture..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "Enlever la liste de lecture"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "Liste de lecture précédente"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "Liste de lecture suivante"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "Importer la piste de lecture..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "Exporter la liste de lecture..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "Gestionnaire de listes de lecture..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "Gestionnaire de file d'attente..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "Rafraîchir la liste de lecture"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Montrer l'éditeur de liste de lecture"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Montrer l'égaliseur"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "Afficher le temps restant"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Toujours au premier plan"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "Sur tous les espaces de travail"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "Enrouler le lecteur"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "Enrouler l'éditeur de listes de lecture"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "Enrouler l'égaliseur"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Taille double"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "Ajouter une URL..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "Ajouter des fichiers..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Par titre"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "Par nom de fichier"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "Par chemin de fichier"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Tout enlever"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Vider la file d'attente"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
-msgstr "Effacer les fichiers non disponibles"
+msgstr "Effacer les fichiers absents"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Enlever les doublons"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Ne garder que la sélection"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Enlever la sélection"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Chercher et sélectionner"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Inverser la sélection"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Ne rien sélectionner"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Tout sélectionner"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Par album"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Par numéro de piste"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Par artiste"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Par album"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Par artiste de l'album"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "Par date de parution"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Par numéro de piste"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "Par Genre"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "Par durée"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "Par titre personnalisé"
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "MeÌlange aleÌatoirement la liste"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Inverser la liste"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Trier la sélection"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Trier la liste"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Couper"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Copier"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Coller"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "Mettre/enlever de la file d'attente"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "Charger un préréglage..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "Charger un préréglage automatique..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "Charger la valeur par défaut"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "Charger un fichier de préréglage..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "Charger un fichier EQF..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "Enregistrer le préréglage..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "Enregistrer le préréglage automatique..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "Enregistrer la valeur par défaut"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "Enregistrer le fichier de préréglage..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "Enregistrer le fichier EQF..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "Supprimer le préréglage..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "Supprimer le préréglage automatique..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "Importer les préréglages WinAMP..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "Réinitialiser à zéro"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Interface Winamp Classic"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Enregistrer"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Charger"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "Charger un fichier de préréglage"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "Charger un fichier EQF"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "Enregistrer un fichier de préréglage"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "Enregistrer un fichier EQF"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "Importer les préréglages de WinAMP"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Préréglages"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Charger un préréglage"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Charger le réglage automatique"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Enregistrer le préréglage"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Enregistrer le réglage automatique"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Supprimer un préréglage."
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Supprimer le réglage automatique"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Lecteur :"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Lecteur :"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Choisir la police de la fenêtre principale du lecteur :"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Liste de lecture"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Liste de lecture :"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Choisir la police de la liste de lecture :"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>Habillage</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>Polices</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Utiliser des polices bitmap (seul ASCII est pris en charge)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "Faire défiler le titre du morceau"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Faire défiler le titre dans les deux sens"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analyseur"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Oscilloscope"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "Spectrogramme/vumètre"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Arrêt"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normal"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Feu"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "Lignes verticales"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Lignes"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Barres"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "La plus lente"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Lente"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Moyenne"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Rapide"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "La plus rapide"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "Points"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "Lignes"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "Plein"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Glace"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Lissé"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>Type</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "Type de visualisation :"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>Analyseur</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "Afficher les crêtes"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "Coloration :"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "Style :"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "Retombée :"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "Retombée des crêtes :"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "Style oscilloscope :"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "Coloration du spectrogramme :"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "Style vumètre :"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Général"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualisations"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Préampli"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Ãgaliseur d'Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
-msgstr "Aller à %d:%-2.2d/%d:%-2.2d"
+msgstr "Se positionner à %d:%-2.2d/%d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Volume : %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balance : %d%% gauche"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balance : centre"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balance : %d%% droite"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Menu des options"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Désactiver « Toujours au premier plan »"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Activer « Toujours au premier plan »"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Boîte d'Infos sur le fichier"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "Visualisations"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "Point de répétition A activé."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "Point de répétition B activé."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "Points de répétition effacés."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Mode « Fichier unique »."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Mode « Liste de lecture »."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Arrêter après le morceau."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Chercher des entrées dans la liste de lecture active"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "Rechercher"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3637,57 +3908,61 @@ msgstr ""
"Si vous ne savez pas comment fonctionnent les expressions rationnelles, vous "
"pouvez simplement indiquer une expression littérale de ce que vous cherchez."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
msgstr "Titre :"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr "Album :"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr "Artiste :"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Nom du fichier :"
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Nom de fichier :"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Effacer la sélection précédente avant d'effectuer la recherche"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Mettre automatiquement dans la file d'attente les entrées trouvées"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Créer une nouvelle liste de lecture à partir des entrées trouvées"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Ãditeur de liste de lecture d'Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d sur %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Habillage Winamp 2.x archivé"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Habillage Winamp 2.x non archivé"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Impossible de créer le répertoire (%s) : %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Greffon Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3727,84 +4002,73 @@ msgstr ""
"temps que ce programme ; si ce nâest pas le cas, écrivez à la Free Software "
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Greffon Sndfile"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Sortie sndio"
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Ã propos du greffon de sortie Sndio"
-
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Greffon de sortie Sndio\n"
-"\n"
-"Développé par Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "Périphérique (vide pour celui par défaut) :"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Format non pris en charge"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Enregistrer et restaurer le volume :"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"Un format non pris en charge par le périphérique audio a été demandé.\n"
-"\n"
-"Veuillez essayer à nouveau avec le serveur sndiod(1) en fonction."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Erreur sndio : format audio non pris en charge (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "Périphérique sndio"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Erreur sndio : échec de sio_open()"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(vide implique par défaut)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Erreur sndio : échec de sio_setpar()"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Erreur sndio : échec de sio_start()"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Changement de morceau"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Commande à exécuter lorsqu'Audacious commence un nouveau morceau."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Les arguments passés à la ligne de commande doivent être "
+"mis entre \" \". Ne pas le faire entraîne un risque de sécurité.</span>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Commande :"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Commandes</b>"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Commande à exécuter lorsque la lecture d'un morceau se termine."
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Commande à exécuter lorsqu'un nouveau morceau commence :"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr ""
-"Commande à exécuter lorsqu'Audacious atteint la fin de la liste de lecture."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Commande à exécuter lorsqu'un morceau se termine :"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Commande à exécuter à la fin de la liste de lecture :"
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Commande à exécuter lorsque le titre d'un morceau change (par exemple le "
-"titre d'un flux en réseau)."
+"Commande à exécuter lorsque le titre d'un morceau change (pour les flux "
+"réseau) :"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3818,35 +4082,31 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Vous pouvez utiliser les variables suivantes qui seront remplacées avant "
-"l'appel de la commande à exécuter (toutes ne sont pas utiles pour la "
-"fonction « fin de liste de lecture ») :\n"
-"\n"
-"%F : Fréquence (en Hertz)\n"
-"%c : Nombre de canaux\n"
-"%f : Nom du fichier (chemin complet)\n"
-"%l : Durée (en millisecondes)\n"
-"%n ou %s : Nom du morceau\n"
-"%r : Taux d'encodage (en bit par seconde)\n"
-"%t : Position dans la liste de lecture (%02d)\n"
-"%p : Lecture en cours (1 ou 0)\n"
-"%a : Artiste\n"
-"%b : Album\n"
-"%T : Titre de la piste"
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>Les arguments passés à la ligne de commande doivent être "
-"mis entre \" \". Ne pas le faire entraîne un risque de sécurité.</span>"
-
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Commandes"
+"Vous pouvez utiliser les chaînes de formatage suivantes qui seront\n"
+"remplacées avant l'appel de la commande (toutes ne sont pas utiles pour la "
+"commande fin-de-liste-de-lecture) :\n"
+"\n"
+"%F : fréquence (en hertz)\n"
+"%c : nombre de canaux\n"
+"%f : nom de fichier (chemin complet)\n"
+"%l : durée (en millisecondes)\n"
+"%n ou %s : nom du morceau\n"
+"%r : taux (en bits par seconde)\n"
+"%t : position dans la liste de lecture (%02d)\n"
+"%p : lecture en cours (1 ou 0)\n"
+"%a : artiste\n"
+"%b : album\n"
+"%T : titre de la piste"
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Infos sur le morceau (Qt)"
+
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "Ré-échantillonneur SoX"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3860,51 +4120,51 @@ msgstr ""
"Basé sur le greffon de conversion du taux d'échantillonnage :\n"
"Tous droits réservés © 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Rapide"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Bas"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Haut"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Très haut"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Qualité :"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "Ré-échantillonneur SoX"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Vitesse et hauteur"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Vitesse et hauteur</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Vitesse :"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Hauteur :"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Vitesse et hauteur"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Icône d'état"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "Pa_ramètres..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3922,39 +4182,39 @@ msgstr ""
"Ce greffon ajoute une icône de contrôle d'Audacious dans la zone de "
"notification de votre gestionnaire de fenêtre."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Action lors du défilement à la molette</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Changer le volume"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Changer le morceau en cours"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Autres paramètres</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "DeÌsactiver la fenêtre contextuelle"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Réduire dans la zone de notification"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Avancer dans la liste de lecture en roulant la molette vers le haut"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Icône d'état"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Stéréo additionnelle"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3964,24 +4224,24 @@ msgstr ""
"\n"
"Par Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Stéréo additionnelle</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Stéréo additionnelle"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Générateur de fréquences musicales"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Générateur de tonalités : "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3997,15 +4257,11 @@ msgstr ""
"Par exemple. tone://2000;2005 pour jouer une note à 2 000 Hz en même temps "
"qu'une note à 2 005 Hz"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Générateur de fréquences musicales"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Suppression des voix"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4043,11 +4299,46 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Décodeur Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Détails à propos de %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"Titre : %t\n"
+"Auteur : %a\n"
+"De : %f\n"
+"Tracker : %T\n"
+"Commentaire : %C\n"
+"Type de puce : %c\n"
+"Stéréo : %s\n"
+"Boucle : %l\n"
+"Fréq. de la puce : %F\n"
+"Fréq. du lecteur : %P\n"
+"Année : %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "Décodeur VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4057,19 +4348,19 @@ msgstr ""
"Basé sur in_vtx.dll par Roman Sherbakov <v_soft at microfor.ru>\n"
"Greffon Audacious par Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "Décodeur VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "Décodeur WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr " avec perte (hybride)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "avec perte"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4079,23 +4370,18 @@ msgstr ""
"\n"
"Une partie du code du greffon a été développé par Miles Egan"
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "Décodeur WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "Décodeur 2SF"
-#: src/xspf/xspf.c:438
-msgid "XML Shareable Playlists (XSPF)"
-msgstr "Listes de lecture XSPF"
-
-#~ msgid "32.0 kHz:"
-#~ msgstr "32,0 kHz :"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>Configuration XFS</b>"
-#~ msgid "88.2 kHz:"
-#~ msgstr "88,2 kHz :"
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Ignorer la durée donnée par le fichier"
-#~ msgid "176.4 kHz:"
-#~ msgstr "176,4 kHz :"
+#: src/xspf/xspf.cc:89
+msgid "XML Shareable Playlists (XSPF)"
+msgstr "Listes de lecture XSPF"
diff --git a/po/gl.po b/po/gl.po
index a38e454a42cc..2f5839cb757f 100644
--- a/po/gl.po
+++ b/po/gl.po
@@ -3,18 +3,18 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# antiparvos <marcoslansgarza at gmail.com>, 2014
-# mbouzada <mbouzada at gmail.com>, 2012
-# mbouzada <mbouzada at gmail.com>, 2013
-# mbouzada <mbouzada at gmail.com>, 2012
-# mbouzada <mbouzada at gmail.com>, 2012,2014
+# antiparvos <marcoslansgarza at gmail.com>, 2014-2015
+# Miguel Anxo Bouzada <mbouzada at gmail.com>, 2012
+# Miguel Anxo Bouzada <mbouzada at gmail.com>, 2013
+# Miguel Anxo Bouzada <mbouzada at gmail.com>, 2012
+# Miguel Anxo Bouzada <mbouzada at gmail.com>, 2012,2014-2015
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:41+0000\n"
-"Last-Translator: antiparvos <marcoslansgarza at gmail.com>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-05 07:36+0000\n"
+"Last-Translator: Miguel Anxo Bouzada <mbouzada at gmail.com>\n"
"Language-Team: Galician (http://www.transifex.com/projects/p/audacious/"
"language/gl/)\n"
"Language: gl\n"
@@ -23,40 +23,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "estéreo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "son envolvente"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "Decodificador AAC (MP4)"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "Decodificador AAC (en bruto)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (reprodutor AdLib)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "secuenciado"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (reprodutor AdLib)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarma"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "Estabelecer a alarma ..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -67,11 +55,7 @@ msgstr ""
"\n"
"Escrito orixinalmente por Adam Feakin e Stodden Daniel."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarma"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -113,7 +97,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -153,7 +137,7 @@ msgstr ""
" Executar esta orde no momento da alarma.\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -177,384 +161,390 @@ msgstr ""
" escriba a mensaxe na caixa e acenda o\n"
" botón de activación se quere que se amose. "
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Esta é a súa chamada de atención."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "O seu recordatorio para hoxe é..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Lembranza"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "luns"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "martes"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "mércores"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "xoves"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "venres"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "sábado"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "domingo"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Configuración da alarma"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "_Aceptar"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "_Cancelar"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Hora"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarma as (predeterminado):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Silencio despois de:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "horas"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minutos"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Seleccione os dÃas para que salte a alarma"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "DÃa"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Predeterminado"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Dias"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Esvaecemento"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "segundos"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Volume"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Inicial"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Final"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Actual"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Orde adicional"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "activar"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Lista de reprodución (opcional)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Escolla a lista de reprodución"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Opcións"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Que significan estas opcións?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Axuda"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Portada"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Portada (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "SaÃda ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"Engadido de saÃda ALSA para Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"O meu agradecemento para William Pitcock, autor do engadido de saÃda NG de "
+"ALSA, cuxo código serviu de referencia cando o manual de ALSA non foi abondo."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(sen descrición)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Dispositivo PCM predeterminado"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Dispositivo mesturador predeterminado"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "Dispositivo PCM:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Dispositivo mesturador:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Elemento mesturador:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Evitar as crebas por falta de recursos"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "Engadido AMIDI (Reprodutor MIDI)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"Engadido de saÃda ALSA para Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"reprodutor musical MIDI modular\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"O meu agradecemento para William Pitcock, autor do engadido de saÃda NG de "
-"ALSA, cuxo código serviu de referencia cando o manual de ALSA non foi abondo."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "SaÃda ALSA"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "Engadido AMIDI (Reprodutor MIDI)"
+"escrito por Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"agradecementos especiais a...\n"
+"\n"
+"Clemens Ladisch e Jaroslav Kysela\n"
+"polos seus excelentes programas aplaymidi e amixer; ambos\n"
+"realmente útiles, xunto coa documentación de alsa-lib, a fin\n"
+"de aprender máis sobre a API de ALSA\n"
+"\n"
+"Alfredo Spadafina\n"
+"polo fermoso logotipo do teclado mididi\n"
+"\n"
+"Tony Vroon\n"
+"pola gran axuda coas probas da alfa"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "Anular a ganancia predeterminada:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "Anular a polifonÃa predeterminada:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "Anular a reverberación predeterminada:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "Acender"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "Anular o coro predeterminado:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>Reprodución</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "Transposición:"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "semitóns"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "Cambio de baterÃa:"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>Avanzado</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "números de nota"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "Extraer comentarios desde o ficheiro MIDI"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Omitir o silencio principal"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "Extraer letras desde o ficheiro MIDI"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Omitir o silencio posterior"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>Fonte de son</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>Sintetizador</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr "Taxa da mostraxe:"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "Engadido AMIDI - seleccione un ficheiro SoundFont"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Cancelar"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "_Abrir"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Nome de ficheiro"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Tamaño (bytes)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nome:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> Información MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Formato:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Duración (mseg.):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Num. de pistas"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variábel"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Div. tempo:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\\\"smaller\\\"> Comentarios e letras MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* non hai comentarios dispoñÃbeis neste ficheiro MIDI *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* non hai letras dispoñÃbeis neste ficheiro MIDI *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Pechar"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (UTF-8 incorrecto)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Sobre o engadido AMIDI"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "Engadido AMIDI"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"Reprodutor musical modular MIDI\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"Escrito por Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"O noso especial agradecemento a...\n"
-"\n"
-"Clemens Ladisch e Jaroslav Kysela\n"
-"polos magnÃficos programas aplaymidi e amixer; xa\n"
-"que eran moi necesarios xunto coa documentación\n"
-"de alsa-lib, a fin de coñecer mellor a API de ALSA\n"
-"\n"
-"Alfredo Spadafina\n"
-"polo fermoso logotipo do teclado MIDI\n"
-"\n"
-"Tony Vroon\n"
-"pola gran axuda coas probas da alfa"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -572,156 +562,151 @@ msgstr ""
"Baseado parcialmente na biblioteca Ghosd de Evan Marti:\n"
"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (Información en pantalla)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Rectángulo"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Rectángulo arredondado"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Rectángulo cóncavo"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Ningún"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Reprodución iniciada"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr ""
"Activa as notificacións OSD cando se reproduce un elemento da lista de "
"reprodución."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Cambio de tÃtulo"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Activa as notificacións OSD cando, durante a reprodución, o tÃtulo da "
-"canción cambia mais o nome do ficheiro é o mesmo. Isto es útil, "
-"principalmente, para amosar os cambios de tÃtulo nos fluxos da Internet"
+"Disparar OSD cando cambia o tÃtulo da canción (para fluxos da Internet)."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Inicio da pausa"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Activa as notificacións OSD cando a reprodución e posta en pausa"
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Fin da pausa"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr ""
"Activa as notificacións OSD cando a reinicia a reprodución despois dunha "
"pausa"
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Colocación"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Desprazamento X relativo:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Desprazamento Y relativo:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Largura máx. do OSD"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Opcións de múltiple monitor"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Amosar as notificacións OSD utilizando:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "todos os monitores"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "monitor %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Temporización (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Mostrar:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Esvaecemento de entrada:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Esvaecemento de saÃda:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Tipos de letra"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Tipo de letra %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Sombra"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Estilo de debuxado"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Cores"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Cor %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Activar disparador"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Actividade"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Detectouse un administrador de composición"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -731,113 +716,113 @@ msgstr ""
"a non ser que saiba que ten un en execución, active un administrador de "
"composición ou as notificacións OSD non funcionarán correctamente"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr ""
"Para a falsa transparencia non fai falta un administrador de compòsición"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Transparencia"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Transparencia falsa"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Transparencia real (require composición 3D)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "A extensión de composición non está cargada"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "A extensión de composición non está dispoñÃbel"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Notificacións OSD de Audacious</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Notificacións OSD de Audacious - configuración"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "_Proba"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "_Estabelecer"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Posición"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animación"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Texto"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Decoración"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Disparador"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Miscelánea"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Proba"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "Listas de reprodución ASXv3"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "Listas de reprodución ASXv1/ASXv2"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Listas de reprodución do Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Cor</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Alcance do desenfoque"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer estereofónico a Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Predefinicións:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Nivel de alimentación:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Cortar frecuencia:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Predefinicións:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer estereofónico a Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Analizador de espectro"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Engadido de CD de son"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -858,171 +843,158 @@ msgstr ""
"\n"
"Este foi un proxecto do Google Summer of Code 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Dispositivo</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Velocidade de lectura:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Anular o dispositivo:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadatos</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Empregar o CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Empregar a CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Empregar HTTP no canto de CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Servidor:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Ruta:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Porto:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Engadido de CD de son"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "Non foi posÃbel iniciar o subsistema cdio"
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "URI incorrecto %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Non se atopa a pista %d"
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "A pista %d é unha pista de datos"
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Non foi posÃbel abrir a saÃda de son."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Produciuse un erro ao ler o CD de son"
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "CD de son"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "Pista %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Non foi posÃbel abrir o dispositivo do CD %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Non foi posÃbel atopar unha unidade de CD de son."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "Non foi posÃbel rematar a inicialización da unidade de CD aberta."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Non foi posibel obter o primeiro/último número de la pista."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Non é posÃbel ler o inicio/fin LSN para a pista %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Non foi posÃbel crear a conexión coa CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Produciuse un erro ao consultar o servidor CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Produciuse un erro ao consultar o servidor CDDB: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Non foi posÃbel ler a información de CDDB: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "A unidade está baleira."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Tipo de disco non admitido."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Elementos do menú do CD de son"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Reproducir o CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Engadir un CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Elementos do menú do CD de son"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Compresión</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Centrar o volume:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Intervalo dinámico:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Engadido de compresión de rango dinámico para Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Engadido de compresión de intervalo dinámico para Audacious\n"
+"Dereitos de autor 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Compresor de intervalo dinámico"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1038,208 +1010,241 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Graves:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Agudos:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "Eco:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Duración predeterminada da canción:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>Mostraxe múltipla</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Activar a múltipla mostraxe de son"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Taxa de múltipla mostraxe:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
-msgstr "Ignorar a lonxitude das etiquetas SPC"
+msgstr "Ignorar a duración desde as etiquetas SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Aumentar a reverberación"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Descodificador de música dunha consola de xogos"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"Produciuse un fallo na atenuación cruzada xa que existen cancións cun número "
-"diferente de canles. Pode empregar o «Mesturador de canles» para converter "
-"as cancións ao mesmo número de canle."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "SaÃda CoreAudio"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"Produciuse un fallo na atenuación cruzada xa que existen cancións con "
-"diferente taxa de mostraxe. Pode empregar o «Convertedor de taxa de "
-"mostraxe» para converter as cancións á mesma taxa de mostraxe."
+"Engadido de saÃda CoreAudio para Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Baseado no engadido de saÃda SDL para Audacious\n"
+"Copyright 2010 John Lindgren"
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "Usar o modo exclusivo"
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"Engadido Crossfade para Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Atenuación cruzada</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "No cambio automático de canción"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "Sobreposición:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "No cambio manual, ou nas buscas, de canción"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Consello</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+"Para un mellor efecto de fundido, active\n"
+"o efecto de supresión do silencio."
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Atenuación cruzada"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"Produciuse un fallo na atenuación cruzada xa que existen cancións cun número "
+"diferente de canles. Pode empregar o «Mesturador de canles» para converter "
+"as cancións ao mesmo número de canle."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"Produciuse un fallo na atenuación cruzada xa que existen cancións con "
+"diferente taxa de mostraxe. Pode empregar o «Convertedor de taxa de "
+"mostraxe» para converter as cancións á mesma taxa de mostraxe."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Cristalizador</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intensidade:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Cristalizador"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Engadido de plano de referencia"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Eliminar ficheiros"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "Produciuse un erro ao enviar %s ao lixo: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "Produciuse un erro ao eliminar %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "Produciuse un erro ao eliminar %s: non é un ficheiro local."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "Confirma que quere enviar ao lixo os ficheiros seleccionados?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "Enviar ao lixo"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
"Confirma que quere eliminar permanentemente os ficheiros seleccionados?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Eliminar"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Cancelar"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "Eliminar ficheiros"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "Eliminar os ficheiros seleccionados"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>Eliminar o método</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "Enviar ao lixo no canto de eliminar inmediatamente"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+"Engadido Echo\n"
+"Por Johan Levin, 1999\n"
+"\n"
+"Surround echo por Carl van Schaik, 1999\n"
+"Actualizado para Audacious por William Pitcock e John Lindgren, 2010-2014"
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Eco</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Atraso:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Realimentación"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Volume:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Engadido Echo\n"
-"Por Johan Levin, 1999\n"
-"\n"
-"Surround echo por Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Eco"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Engadido FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1255,55 +1260,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "Engadido FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Engadido FileWrite"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Formato do ficheiro de saÃda:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Configurar"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Gardar no directorio orixinal"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Gardar nun directorio personalizado"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Cartafol do ficheiro de saÃda:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Escolla un cartafol"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Obter o nome de ficheiro desde:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Xerar o nome de ficheiro desde:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "etiquetas do ficheiro orixinal"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Etiqueta do ficheiro orixinal"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
msgstr "Nome do ficheiro orixinal"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Non quitar a extensión do ficheiro"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "IncluÃr a extensión do nome do ficheiro orixinañ"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
msgstr "Antepor o número de pista ao nome de ficheiro"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1335,165 +1340,169 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "Engadido FileWrite"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Auto"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Estéreo solapado"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Estéreo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Configuración de MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_Aceptar"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Calidade do algoritmo:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
msgstr "Frecuencia de mostraxe de saÃda:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
msgstr "Taxa de bits / Relación de compresión:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Taxa de bits (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Relación de compresión:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Modo do son:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Miscelánea:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr "Varios:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Forzar a compatibilidade estrita con ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr "Forzar o cumprimento estrito da norma ISO"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Protección contra erros"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Calidade"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Activar VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tipo:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Opcións VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Taxa de bits mÃnima (kbps)"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Taxa de bits máxima (kbps)"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Aplicar estritamente a taxa de bits mÃnima"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Opcións ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Taxa media de bits (kbps)"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "Nivel de calidade VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Non escribir a cabeceira VBR Xing"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Omitir a cabeceira VBR Xing"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr "Parámetros do cadro:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Marcar con Dereitos de autorÃa"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Marcar como orixinal"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "Parámetros ID3:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Forzar o engadido da etiqueta da versión 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Engadir só a etiqueta v1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Engadir só a etiqueta v2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Etiquetas"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Configuración do codificador Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Nivel de calidade (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "Descodificador FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "sen perdas"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1505,11 +1514,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "Descodificador FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1517,11 +1522,19 @@ msgstr ""
"Engadido GIO para Audacious\n"
"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "Engadido GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "O modo ler e engadir non está admitido"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "Modo incorrecto de apertura"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1541,534 +1554,620 @@ msgstr ""
"\n"
"Liceza: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "Analizador de espectro OpenGL"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+"Analizador de espectro OpenGL para Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren e Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Baseado no engadido de XMMS:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, e "
+"4Front Technologies\n"
+"\n"
+"Licencia: GPLv2+"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "Analizador de espectro OpenGL (Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "Atallos do GNOME"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-"Engadido de atallos do Gnome\n"
-"Permite controlar o reproductor cos atallos de GNOME.\n"
+"Engadido de atallos do GNOME\n"
+"Permite controlar o reprodutor cos atallos do GNOME.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Atallos do Gnome"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Número de entrada"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "TÃtulo"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Interprete"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Ano"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Ãlbum"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Interprete do álbum"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Pista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Xénero"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Posición na cola"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Duración"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Ruta ao ficheiro"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Nome de ficheiro"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "TÃtulo personalizado"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Taxa de bits"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "Columnas dispoñÃbeis"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "Columnas amosadas"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Ferramenta de buscas"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Ancorar á esquerda"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Ancorar á dereita"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Ancorar enriba"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Ancorar abaixo"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Desancorar"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Desactivar"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Ferramenta de buscas"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Abrir ficheiros..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Abrir un _URL..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_Engadir ficheiros..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Engadir un U_RL..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "Buscar unha _fonoteca"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "So_bre..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "_Axustes ..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_SaÃr"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Reproducir"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "_Pausa"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Deter"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "A_nterior"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "Se_guinte"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "Repe_tir"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "Ao c_hou"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "N_on avanzar na lista de reprodución"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Parar _despois desta canción"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Información da canción"
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Saltar no _tempo"
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "Saltar á _canción"
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "Estabelecer o punto de repetición _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "Estabelecer o punto de repetición _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_Limpar os puntos de repetición"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Polo _tÃtulo"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "Por_ nome de ficheiro"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "Pola nome do _ficheiro"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Por _ruta do ficheiro"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Polo _número de pista"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Polo _interprete"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Por ál_bum"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Polo interprete do álbu_m"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Pola _data de publicación"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "Por _xénero"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "Por _duración"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Pola _ruta do ficheiro"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Polo tÃtulo _personalizado"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Orden _inversa"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "Ao c_hou"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_Reproducir esta lista"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "Re_producir/Continuar"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Actualizar"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Ordenar"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "Ordenar a s_elección"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "Retirar _duplicados"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Eliminar os ficheiros _non dispoñÃbeis"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Novo"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "Cambiar o _nome..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "Re_tirar"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importar..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Exportar..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "Xestor da _lista de reprodución:"
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Xestor da _cola"
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "_Subir o volume"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "_Baixar o volume"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Ecualizador"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "E_fectos ..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Amosar a barra de _menú"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Amosar a barra de i_nformación"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Amosar a barra de vis_ualización"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Amosar a barra de e_stado"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Amosar o tempo _restante"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "_Visualizacións ..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Ficheiro"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Reproducir"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Lista de reprodución"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Servicios"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "SaÃ_da"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Ver"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Por na cola/retirar da cola"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "Abrir o cartafol _contedor"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "C_ortar"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Copiar"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Pegar"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Seleccionar _todo"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "Cambiar o _nome..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>Lapelas da lista de reprodución</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "Amosar sempre as lapelas"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "Amosar os contadores da entrada"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "Amosar os botóns de peche"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>Columnas da lista de reprodución</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "Amosar as cabeceiras de columna"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Varios</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr "As teclas de frecha buscan a través de:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "Avanzar ao cambiar de canción"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "Interface GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Almacenando no búfer..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "estéreo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d canle"
msgstr[1] "%d canles"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Modo único."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Modo da lista de reprodución"
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Parar despois da canción."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Pista anterior"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Reproducir"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pausar/Reiniciar"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Parar"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Pista seguinte"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "Avanzar 5 segundos"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "Retroceder 5 segundos"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Silenciar"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Subir o volume"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Baixar o volume"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Ir ao ficheiro"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "Cambiar a(s) xanela(s) de reprodución"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Mostrar as notificacións OSD"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
-msgstr "Conmutar a repetición"
+msgstr "Cambiar a repetición"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
-msgstr "Conmutar a reprodución ao chou"
+msgstr "Cambiar a reprodución ao chou"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
-msgstr "Conmutar a parada despois da actual"
+msgstr "Cambiar a parada despois da actual"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Elevar as xanelas do reprodutor"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(ningún)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2079,15 +2178,11 @@ msgstr ""
"\n"
"Quere continuar?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Asociar botóns do rato"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Configuración global de atallos de teclado do engadido"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2095,23 +2190,27 @@ msgstr ""
"Prema unha combinación de teclas dentro do campo de texto.\n"
"Tamén pode asociar botóns do rato."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Teclas rápidas:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Acción</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Teclas asociadas:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "_Engadir"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Teclas rápidas globais"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2138,60 +2237,56 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Teclas rápidas globais"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "SaÃda JACK"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "Conectar todos os portos «jack» dispoñÃbeis"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "Conectar automaticamente os portos de saÃda"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "Conectar só os portos de saÃda"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "Só se atoparon %d portos de saÃda de JACK, son necesarios %d."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "Non conectar ningún porto"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Produciuse un fallo ao conectar co porto JACK %s."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "Modo de conexión:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+"JACK só acepta son en punto flotante. Ten que cambiar o bit de profundidade "
+"da saÃda a punto flotante nos axustes do Audacious."
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "Activar a impresión da depuración"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "Produciuse un fallo ao conectar co servidor JACK; está en execución?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Baseado en xmms-jack, por Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Portado a Audacious por Giacomo Lozito"
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "SaÃda JACK"
+"O servidor JACK precisa dunha taxa de mostraxe de %d Hz, mais o Audacious "
+"está a reproducir cunha taxa de %d Hz. Use o efecto «Convertedor de taxa de "
+"mostraxe» para corrixir esta discordancia."
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "Configuración de %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Configuración do servidor LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Rutas dos módulos:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2201,25 +2296,25 @@ msgstr ""
"Estas rutas empréganse ademais de LADSPA_PATH.\n"
"Tras engadir as novas rutas, prema Intro para buscar novos engadidos.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Engadidos dispoñÃbeis:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Activar"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Engadidos activados:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Configuración"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2227,47 +2322,15 @@ msgstr ""
"LADSPA Host para Audacious\n"
"Copyright 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
-msgid "LADSPA Host"
-msgstr "Servidor LADSPA"
-
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: a compatibilidade de LIRC non foi iniciada\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: non foi posÃbel ler o ficheiro de configuración LIRC\n"
-"%s: consulte a documentación do LIRC\n"
-"%s: como crear un ficheiro de configuración válido\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: tentando volver a conectar...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: orde descoñecida «%s»\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: desconectado de LIRC\n"
+#: src/ladspa/plugin.h:78
+msgid "LADSPA Host"
+msgstr "Servidor LADSPA"
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: tentará volver a conectar cada %d segundos...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Engadido LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2296,73 +2359,81 @@ msgstr ""
"\n"
"Para obter máis información sobre LIRC, consulte http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Conexión</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Volver conectar co servidor LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Agardar antes de volver conectar:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Engadido LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "Engadido LyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Non hai letras dispoñÃbeis"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Erro"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Non é posibel obter %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Erro"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Non é posÃbel analizar %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Buscando letras ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Faltan os metadatos da canción"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Conectando con lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "Engadido LyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "Engadido LyricWiki (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "Listas de reprodución M3U"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Xerador de tacto"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Xerador de tacto: %d ppm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Xerador de tacto: %d ppm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2376,11 +2447,11 @@ msgstr ""
"p.ex. tact://77 para reproducir a 77 pulsos por minuto\n"
"ou tact://60*3/4 to para reproducir a 60 ppm en 3/4 tactos"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Xerador de tacto"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Mesturador de canles"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2388,152 +2459,184 @@ msgstr ""
"Engadido Channel Mixer para Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Mesturador de canles</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Canles de saÃda:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Mesturador de canles"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "Engadido MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "Produciuse un erro ao conectar co servidor MMS"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (modulo reprodutor)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>Resolución</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Canles</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "Máis próximo (o máis rápido)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Lineal (rápido)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Spline (bo)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "Polifase (o mellor)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr "<b>Taxa da mostraxe</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Nivel:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "lÃmite de corte:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Reverberación</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>Ãnfase de graves</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>Son envolvente</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>Preamplificación</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "Sobremostraxe"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Redución de ruÃdo"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Reproducir os MOD de Amiga"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Repetir</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "Contador de repeticións:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "Para repetir sempre, estabelecer o contador de repeticións en -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (modulo reprodutor)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Son envolvente"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "Estes axustes terán efecto após que Audacious sexa reiniciado."
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "Engadido MPG123"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Avanzado</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Utilizar o cálculo de duración exacta (lento)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Son envolvente"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "Servidor MPRIS 2"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Engadido Neon HTTP/HTTPS"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "Erro de análise de redireccionamento"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Erro HTTP descoñecido"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "Erro de análise de URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Demasiadas redireccións"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Parado"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious non está a reproducir nada."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Notificacións de escritorio"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2569,55 +2672,64 @@ msgstr ""
"DeberÃa ter recibido unha copia da Licenza Pública Xeral de GNU xunto\n"
"con este programa, de non ser asÃ, consulte <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Amosar os controis de reprodución"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Amosar sempre a notificación"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Notificacións de escritorio"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "IncluÃr o nome do álbum na notificación"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Amosar"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pausa"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Seguinte"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Dispositivo predeterminado"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "SaÃda OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "SaÃda OSS3"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Dispositivo predeterminado"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Dispositivo de son:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Empregar un dispositivo alternativo:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Gardar o volume entre sesións."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Activar as conversións de formato realizadas plo software OSS."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Activar o modo exclusivo para impedir a mestura virtual."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2631,19 +2743,35 @@ msgstr ""
"GustarÃame darlle as grazas á xente de #audacious, sobre todo a Tony Vroon "
"e a John Lindgren e por suposto aos autores do anterior engadido de OSS."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "SaÃda OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Xestor da lista de reprodución:"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Entradas"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Retirar"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "Re_nomear"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "Listas de reprodución PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "Descodificador OpenPSF PSF1/PSF2"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "SaÃda PulseAudio"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2679,11 +2807,73 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "SaÃda PulseAudio"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "SaÃda QtMultimedia"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"Engadido de saÃda QtMultimedia Audio para Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Baseado no engadido de saÃda SDL para Audacious\n"
+"Copyright 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Traballando..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Busca"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_Abrir o cartafol ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_Engadir un cartafol ..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "Inspector do _rexistro ..."
-#: src/resample/resample.c:165
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Abrir ficheiros"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Engadir ficheiros"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Anterior"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Repetir"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Ao chou"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Interface Qt"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Convertedor de taxa de mostraxe"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2691,99 +2881,107 @@ msgstr ""
"Engadido Sample Rate Converter para Audacious\n"
"Copyright 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "Omitir/repetir as mostraxes"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Interpolación lineal "
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Interpolación de sincronÃa rápida"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "Interpolación de sincronÃa media"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Mellor interpolación de sincronÃa"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Conversión</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Método:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Taxa:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Taxa de asignacións</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Empregar a taxa de asignacións"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Convertedor de taxa de mostraxe"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "Aceptar. Scrobbling para o usuario: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "Permiso denegado"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"Acceda á seguinte ligazón para permitirlle a Audacious enviar o rexistro das "
"súas escoitas:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"Manteña aberta esta xanela e prema outra vez en «Comprobación de permisos».\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2791,34 +2989,38 @@ msgstr ""
"No se preocupe. Os seus rexistros de escoitas gardanse no seu computador.\n"
"Só se enviarán se Audacious llelo permite."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "Problema na rede."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "Houbo un problema ao contactar con Last.fm. Ténteo de novo máis tarde."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "Comprobando..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "C_omprobación de permisos"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_Revogar o permiso"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"Ten que autorizar a súa conta en Last.fm para que poida seguir (scrobble) as "
"súas pistas.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2826,7 +3028,7 @@ msgstr ""
"Non foi posÃbel iniciar o engadido de Scrobbler.\n"
"Semella que hai un problema de instalación."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2843,11 +3045,7 @@ msgstr ""
"Gracias a John Lindgren por botarme unha man no comenzo deste proxecto.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2855,7 +3053,11 @@ msgstr ""
"Audacious está a empregar unha versión mellorada do Scrobbler de Last.fm .\n"
"Comprobe as preferencias para o engadido do Scrobbler."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SaÃda SDL"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2863,81 +3065,56 @@ msgstr ""
"Engadido SDL Output para Audacious\n"
"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SaÃda SDL"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Biblioteca"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Interprete descoñecido"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Ãlbum descoñecido"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" en %s por %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d resultado"
+msgstr[1] "%d resultados"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d álbum"
-msgstr[1] "%d álbumes"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d agochado)"
+msgstr[1] "(%d agochados)"
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d canción"
-msgstr[1] ""
-"%s\n"
-" %s, %d cancións"
-
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d canción por %s"
-msgstr[1] ""
-"%s\n"
-" %d cancións por %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d canción"
+msgstr[1] "%d cancións"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "deste xénero"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "en"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "por"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Crear unha lista de reprodución"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Engadir á lista de reprodución"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Buscar unha fonoteca"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2945,679 +3122,771 @@ msgstr ""
"Para importar a súa fonoteca en Audacious, escolla un cartafol e prema na "
"icona «Actualizar»."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Agarde..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Escolla un cartafol"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "Reprodutor SID"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>SaÃda</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Canles:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Emulación</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "Emular MOS 8580 (predeterminado: MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "Non seleccionar automaticamente o modelo de chip"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Filtro de emulación"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Velocidade do reloxo:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "Non seleccionar automaticamente a velocidade do reloxo"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>Tempo de reprodución</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "Estabelecer o tempo máximo de reprodución:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Usar só cando a duración e descoñecida"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "Estabelecer o tempo mÃnimo de reprodución:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Subtóns</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "Activar subtóns"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "Ignorar os subtóns menores que:"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Nota</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Supresión do silencio"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"Engadido de supresión do silencio para Audacious\n"
+"Copyright 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Supresión do silencio</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Limiar:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "Abrir ficheiros ..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "Abrir un URL ..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Buscar unha fonoteca"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Reprodución"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Lista de reprodución"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Ver"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "Servizos"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "Sobre ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "Axustes ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "SaÃr"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "Información da canción ..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Repetir"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Ao chou"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Non avanzar na lista de reprodución"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "Deter despois desta canción"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Anterior"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "Estabelecer a repetición A-B"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "Limpar a repetición A-B"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "Saltar á canción ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "Saltar no tempo ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "Reproducir esta lista"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "Reproducir/Continuar"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Nova lista de reprodución"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "Renomear a lista de reprodución ..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "Retirar a lista de reprodución"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "Lista de reprodución anterior"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "Seguinte lista de reprodución"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "Importar lista de reprodución ..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "Exportar lista de reprodución ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "Xestor da lista de reprodución ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "Xestor da cola ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "Actualizar a lista"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Amosar o editor de listas de reprodución"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Amosar o ecualizador"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "Amosar o tempo restante"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Sempre enriba"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "En todos os espazos de traballo"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "Enrolar o reprodutor"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "Enrolar o editor de listas de reprodución"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "Enrolar o ecualizador"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Dobre tamaño"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "Engadir un URL ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "Engadir ficheiros ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Polo tÃtulo"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "Polo nome de ficheiro"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "Pola ruta do ficheiro"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Retirar todo"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Limpar a cola"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Retirar os ficheiros non dispoñÃbeis"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Retirar os duplicados"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Retirar os NON seleccionados"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Retirar os seleccionados"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Buscar e seleccionar"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Inverter a selección"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Non seleccionar nada"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Seleccionar todo"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Polo álbum"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Polo número de pista"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Polo interprete"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Polo álbum"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Polo interprete do álbum"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "Pola data de publicación"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Polo número de pista"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "Por xénero"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "Por duración"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "Por tÃtulo personalizado"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Lista ao chou"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Lista inversa"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Ordenar os seleccionados"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Ordenar a lista"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Cortar"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Copiar"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Pegar"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "Poñer na cola/Quitar da cola"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "Cargar o axuste ..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "Cargar o axuste automático ..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "Cargar o predeterminado"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "Cargar o ficheiro de axustes ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "Cargar o ficheiro EQF ..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "Gardar os axustes ..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "Gardar o axuste automático ..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "Gardar o axuste predeterminado"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "Gardar o ficheiro de axustes ..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "Gardar o ficheiro EQF ..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "Eliminar o axuste ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "Eliminar o axuste automático ..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "Importar os axustes do WinAMP ..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "Poñer a cero"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Interface clásica do Winamp"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Gardar"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Cargar"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "Cargar o ficheiro de axustes"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "Cargar o ficheiro EQF"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "Gardar o ficheiro de axustes"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "Gardar o ficheiro EQF"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "Importar os axustes do WinAMP"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Axustes"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Cargar o axustes"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Cargar o axuste automático"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Gardar o axustes"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Gardar o axuste automático"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Eliminar o axuste"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Eliminar o axuste automático"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Reprodutor:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Reprodutor:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Seleccione o tipo de letra da xanela principal do reprodutor:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_lista de reprodución:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Lista de reprodución:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Seleccione o tipo de letra da lista de reprodución:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>Tema</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>Tipos de letra</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Empregar tipos de letra de mapa de bits (só admiten ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "Desprazar o tÃtulo da canción"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Desprazar o tÃtulo da canción en ambas direccións"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analizador"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Campo"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "Impresión vocal / Medidor de unidades de volume"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Apagado"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normal"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Lume"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "Liñas verticais"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Liñas"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Barras"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Máis lento"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Lento"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Medio"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Rápido"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Máis rápido"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "Puntos"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "Liña"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "Sólido"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Xeo"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Suave"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>Tipo</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "Tipo de visualización:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>Analizador</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "Amosar os picos"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "Colorear:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "Estilo:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "CaÃda:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "CaÃda dos picos:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "Estilo de campo:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "Coloreado da impresión vocal"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "Estilo do medidor de UV:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Xeral"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualización"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Preamplificador"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Ecualizador do Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Ir a %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Volume: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balance: %d%% esquerda"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balance: centro"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balance: %d%% dereita"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Menú de opcións"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Desactivar «Sempre enriba»"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Activar «Sempre enriba»"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Caixa de información do ficheiro"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "Vistas"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "Repetir o punto de axuste A."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "Repetir o punto de axuste B."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "Repetir os puntos limpados"
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Modo único."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Modo da lista de reprodución"
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Parar despois da canción."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Buscar entradas na lista de reprodución activa"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "Busca"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3629,57 +3898,61 @@ msgstr ""
"de minúsculas. Se non sabe como funcionan as expresións regulares, escriba "
"só a parte del literal que quere buscar."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
msgstr "TÃtulo: "
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr "Ãlbum: "
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr "Interprete: "
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Nome do ficheiro: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Nome de ficheiro:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Limpar a selección previa antes de buscar"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
-msgstr "Conmutar automaticamente a cola para as entradas coincidentes"
+msgstr "Cambiar automaticamente a cola para as entradas coincidentes"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Crear unha nova lista de reprodución coas entradas coincidentes"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Editor de listas de reprodución do Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d de %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Tema para Winamp 2.x arquivado"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Tema para Winamp 2.x sen arquivar"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Non foi posÃbel crear o directorio (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Engadido Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3720,84 +3993,72 @@ msgstr ""
"Inc.,\n"
"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Engadido Sndfile"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "SaÃda Sndio"
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Sobre o engadido de saÃda Sndio"
-
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Engadido de saÃda Sndio Output\n"
-"\n"
-"Escrito por Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "Dispositivo (baleiro como predeterminado):"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Formato non admitido"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Gardar e restaurar o volume:"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"Foi solicitado un formato non admitido polo dispositivo de son.\n"
-"\n"
-"Tenteo de novo co servidor sndiod(1) en execución."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Produciuse un erro de Sndio: Formato de son non admitido (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "Dispositivo «sndio»"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Produciuse un erro de Sndio: fallou sio_open()"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(como predeterminado medio baleiro)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Produciuse un erro de Sndio: fallou sio_setpar()"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "Aceptar"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Produciuse un erro de Sndio: fallou sio_start()"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Cambio de canción"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Orde que executar cando Audacious reproduce unha canción nova."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Os parámetros enviados á consola deberÃanse delimitar con "
+"comiñas. Doutro xeito existe un risco de seguranza.</span>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Orde:"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Ordes</b>"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Orde que executar na fin dunha canción."
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Orde que executar cando comece unha nova canción:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr ""
-"Orde que executar cando Audacious chega á fin dunha lista de reprodución."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Orde que executar na fin dunha canción:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Orde que executar na fin dunha lista de reprodución:"
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Orde que executar cando o tÃtulo cambia para una canción (é dicir, tÃtulos "
-"de fluxos da rede)"
+"Orde que executar cando cambia o tÃtulo dunha canción (para fluxos da rede):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3811,36 +4072,31 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Pode empregar os formatos descritos embaixo, que\n"
-"serán substituÃdos antes da invocación da orde\n"
-"(non todos poden ser empregados para a orde fin\n"
-"da lista de reprodución):\n"
-"\n"
-"%F: frecuencia (en hertzios)\n"
-"%c: número de canles\n"
-"%f: nome do ficheiro (ruta completa)\n"
-"%l: duración (em ms)\n"
-"%n ou %s: nome da canción\n"
-"%r: taxa (en bits por segundo)\n"
-"%t: posición na lista de reprodución (%02d)\n"
-"%p: reproducÃndose actualmente (1 ou 0)\n"
-"%a: interprete\n"
-"%b: álbum\n"
-"%T: tÃtulo da pista"
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>Os parámetros enviados á consola deberÃanse delimitar con "
-"comiñas. Doutro xeito existe un risco de seguranza.</span>"
-
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Ordes"
+"Pode utilizar as seguintes cadeas de formato que serán substituÃdas antes de "
+"chamar a orde (non todas son útiles para a orde de fin de lista de "
+"reprodución)\n"
+"\n"
+"%F: Frecuencia (en hercios)\n"
+"%c: Número de canles\n"
+"%f: Nome de ficheiro (ruta completa)\n"
+"%l: Duración (en milisegundos)\n"
+"%n ou %s: Nome da canción\n"
+"%r: Taxa (en bits por segundo)\n"
+"%t: Posición da lista de reprodución (%02d)\n"
+"%p: ReproducÃndose actualmente (1 ou 0)\n"
+"%a: Artista\n"
+"%b: Ãlbum\n"
+"%T: TÃtulo da pista"
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Información da canción (Qt)"
+
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX Resampler"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3854,51 +4110,51 @@ msgstr ""
"Baseado no engadido Sample Rate Converter:\n"
"Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Rápido"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Baixa"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Alta"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Moi alta"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Calidade:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Velocidade e ton"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Velocidade e ton</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Velocidade:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Ton:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Velocidade e ton"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Icona de estado"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "A_xustes ..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3916,39 +4172,39 @@ msgstr ""
"Este engadido fornece unha icona de estado, situada na\n"
"área de información do sistema do xestor de xanelas."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Acción coa roda do rato</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Cambiar o volume"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Cambiar a cancion que se está a reproducir"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Outras configuracións</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Desactivar a xanela emerxente"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Pechar na área de notificación"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Avanzar na lista de reprodución ao desprazar cara arriba"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Icona de estado"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra estéreo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3958,24 +4214,24 @@ msgstr ""
"\n"
"Por Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra estéreo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra estéreo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Xerador de tons"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Xerador de tons: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3990,15 +4246,11 @@ msgstr ""
"frecuencia3;...\n"
"p.ex. tone://2000;2005 para reproducir un ton de 2000 Hz e un ton de 2005 Hz"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Xerador de tons"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Supresión de voz"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4036,11 +4288,46 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Descodificador de Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Detalles sobre %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"TÃtulo: %t\n"
+"Autor: %a\n"
+"Desde: %f\n"
+"Localizador: %T\n"
+"Comentario: %C\n"
+"Tipo de chip: %c\n"
+"Estéreo: %s\n"
+"Bucle: %l\n"
+"Frecuencia do chip: %F\n"
+"Frecuencia do reprodutor: %P\n"
+"Ano: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "Descodificador VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4051,19 +4338,19 @@ msgstr ""
"Baseado no in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Engadido de Audacious por Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "Descodificador VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "Descodificador WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "con perdas (hÃbrido)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "con perdas"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4073,23 +4360,18 @@ msgstr ""
"\n"
"Unah parte do código do engadido foi feita por Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "Descodificador WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "Descodificador 2SF"
-#: src/xspf/xspf.c:438
-msgid "XML Shareable Playlists (XSPF)"
-msgstr "Lista de reprodución XML compartÃbel (XSPF)"
-
-#~ msgid "32.0 kHz:"
-#~ msgstr "32.0 kHz:"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>Configuración XSF</b>"
-#~ msgid "88.2 kHz:"
-#~ msgstr "88.2 kHz:"
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Ignorar a duración do ficheiro"
-#~ msgid "176.4 kHz:"
-#~ msgstr "176.4 kHz:"
+#: src/xspf/xspf.cc:89
+msgid "XML Shareable Playlists (XSPF)"
+msgstr "Lista de reprodución XML compartÃbel (XSPF)"
diff --git a/po/hu.po b/po/hu.po
index fb40b63d085f..ca0ac213a52b 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -3,15 +3,17 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
+# Ferenc Szabo <szaboferee at gmail.com>, 2015
+# Gergely Békési <bekesi.gergely at gmail.com>, 2014
# Péter Polonkai <polesz at nedudu.hu>, 2010
-# Péter Polonkai <polesz at nedudu.hu>, 2011-2012
+# Péter Polonkai <polesz at nedudu.hu>, 2011-2012,2014-2015
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-04-03 11:52+0200\n"
+"PO-Revision-Date: 2015-03-04 13:41+0000\n"
+"Last-Translator: Péter Polonkai <polesz at nedudu.hu>\n"
"Language-Team: Hungarian (http://www.transifex.com/projects/p/audacious/"
"language/hu/)\n"
"Language: hu\n"
@@ -20,51 +22,38 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "sztereó"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "térhatású"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
-msgstr ""
-
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
-msgid "sequenced"
-msgstr ""
+msgstr "AAC (Nyers) Dekóder"
-#: src/adplug/plugin.c:14
+#: src/adplug/adplug-xmms.cc:42
msgid "AdPlug (AdLib Player)"
msgstr "AdPlug (AdLib Lejátszó)"
-#: src/alarm/alarm.c:778
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
+msgid "sequenced"
+msgstr "soros"
+
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Riasztás"
+
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
-msgstr ""
+msgstr "Riasztás beállÃtása ..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
+"BÅvÃtmény a lejátszás idÅzÃtett elindÃtásához\n"
+"\n"
+"Eredetileg Adam Feakin és Daniel Stodden Ãrta."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Riasztás"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -87,7 +76,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -109,7 +98,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -123,360 +112,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Ez egy ébresztési hÃvás."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
-msgstr ""
+msgstr "A mai emlékeztetÅ.."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "EmlékeztetÅ"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "HétfÅ"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Kedd"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Szerda"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Csütörtök"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Péntek"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Szombat"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Vasárnap"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Riasztási beállÃtások"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "IdÅ"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Riasztás (alapértelmezett):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Csendes ezután:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "óra"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "perc"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Válassza ki a riasztás napját a következÅekbÅl"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Nap"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Alapértelmezett"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Napok"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Elhalványulás"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "másodperc"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "HangerÅ"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Kezdjük a"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Vége"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Jelenlegi"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "További parancs"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "engedélyez"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Lejátszólista (opcionális)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Lejátszólista választása"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Opciók"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Mit jelentenek ezek a lehetÅségek?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Súgó"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Album borÃtó"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Album borÃtó (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA kimenet"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(nincs leÃrás)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Alapértelmezett PCM eszköz"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Alapértelmezett keverŠeszköz"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM eszköz:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "KeverŠeszköz:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Mixer elem:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr ""
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI Lejátszó)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA kimenet"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI Lejátszó)"
-
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
-msgstr ""
+msgstr "Be"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
-msgstr ""
+msgstr "<b>Lejátszás</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
+msgstr "Transzponálás:"
+
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "Mintavételi frekvencia:"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - SoundFont fájl választás"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Mégsem"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
-msgstr ""
+msgstr "_Megnyitás"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Fájlnév"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Méret (byte)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Név"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI Információ </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Formátum:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Hossz (msec):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Sáv sorszáma:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "változó"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Kezdeti idÅ"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI Megjegyzések és Dalszövegek </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* nem található megjegyzés ehhez a MIDI fájlhoz *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* nem található dalszöveg ehhez a MIDI fájlhoz *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Bezár"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (érvénytelen UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -487,149 +482,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr ""
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Téglalap"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "KerekÃtett téglalap"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Konkáv téglalap"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Nincs"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Lejátszás kezdete"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "OSD használata ha a lejátszólista egy eleme elindul."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "CÃm váltás"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Szünet Be"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "OSD használata ha megállÃtják a lejátszást."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Szünet Ki"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "OSD használata ha elindÃtják a lejátszást."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Elhelyezés"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "RelatÃv X pozÃció:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "RelatÃv Y pozÃció:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Max OSD szélesség:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Több monitoros opciók"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "OSD képernyÅk használata:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "minden monitoron"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "monitor %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "IdÅtartam (mp)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "KépernyÅ:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Ãttűnés be:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Ãttűnés ki:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Betűkészletek"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Betűkészlet %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Ãrnyék"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Renderelési stÃlus"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "SzÃnek"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "SzÃn %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Esemény engedélyezése"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Esemény"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Kompozit kezelŠdetektálva"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -639,112 +631,112 @@ msgstr ""
"ha tudja, hogy van egy futó kompozÃt kezelÅ, kérjük aktiválja, egyébként az "
"OSD nem fog megfelelÅen működni"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "KompozÃt kezelÅ nem szükséges a nem valódi átlátszósághoz"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Ãtlátszóság"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Nem valódi átlátszóság"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Valódi átlászóság (szükséges X Composite Ext.)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Kompozit kiterjesztés nem tölthetŠbe"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Kompozit kiterjesztés nem érhetŠel"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - beállÃtás"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "PozÃció"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animáció"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Szöveg"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Dekoráció"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Esemény"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Egyéb"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Teszt"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
-msgstr ""
+msgstr "ASXv3 Lejátszólisták"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 lejátszólisták"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious lejátszólisták (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>SzÃn</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Szolid szkóp"
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
msgstr ""
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
-msgstr "Vágási frekvencia:"
-
-#: src/bs2b/plugin.c:166
+#: src/bs2b/plugin.cc:129
msgid "Presets:"
msgstr ""
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
msgstr ""
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr "Vágási frekvencia:"
+
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Spektrum analizátor"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Audio CD bÅvÃtmény"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -755,170 +747,168 @@ msgid ""
"\n"
"This was a Google Summer of Code 2007 project."
msgstr ""
+"Copyright (c) 2007, by Calin Crisan <ccrisan at gmail.com> és az Audacious "
+"csapat.\n"
+"\n"
+"Sok köszönet a libcdio fejlesztÅinek <http://www.gnu.org/software/libcdio/>\n"
+"és a libcddb fejlesztÅinek <http://libcddb.sourceforge.net/>.\n"
+"\n"
+"Külön köszönet Tony Vroon részére aki a mentorunk és vezetÅnk.\n"
+"\n"
+"Ez egy Google Summer of Code 2007 projekt.\n"
+"\n"
+"Copyright 2009 John Lindgren"
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Eszköz</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Olvasási sebesség:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Eszköz felülÃrása:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metaadat</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "CD-Text használata"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "CDDB használata"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Hasznájon HTTP helyett CDDBP protokollt"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Szerver:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Elérési út:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Port:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Audio CD bÅvÃtmény"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "A cdio alrendszer inicializálása sikertelen."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "Ãrvénytelen URI: %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "%d sáv nem található."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "Ez adatsáv: %d."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Az audio kimenet megnyitása sikertelen."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Hiba az audio CD olvasásakor."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Audio CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "A CD eszköz %s megnyitása sikertelen."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Sikertelen a cddb kapcsolat létrehozása."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "A meghajtó üres."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Nem támogatott lemez tÃpus."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Audio CD menüelemek"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "CD lejátszása"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "CD Hozzáadása"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Audio CD menüelemek"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>TömörÃtés</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Közép hangerÅ:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Dinamikus tartomány:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
-msgstr ""
+msgstr "Dinamikus tartomány kompresszió"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -928,199 +918,220 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Basszus:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Magas:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
-msgstr ""
+msgstr "Visszhang:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Alapértelmezett szám hossz:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Engedélyezi az audio újra mintavételezést"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Ãjra mintavételezési arány:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr ""
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Visszhang növelése"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Játék Konzol Zene Dekóder"
-#: src/crossfade/crossfade.c:83
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "CoreAudio kimenet"
+
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:90
-msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Ãtfedés</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "Automatikus számváltáskor"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
+msgstr "Ãtfedés:"
+
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "Tekeréskor vagy kézi számváltáskor"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Tipp</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
msgstr ""
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Ãtfedés"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr ""
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intenzitás:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr ""
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Fájlok törlése"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
-msgstr ""
+msgstr "Hiba a törléskor %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
-msgstr ""
+msgstr "Kukába helyez"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
-msgstr ""
+msgstr "Véglegesen törli a kiválasztott fájlokat?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Törlés"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Mégsem"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
-msgstr ""
+msgstr "Kijelölt fájlok törlése"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
-msgstr ""
+msgstr "<b>Törlési mód</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Visszhang</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Késleltetés:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Visszajelzés:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "HangerÅ:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Visszhang bÅvÃtmény\n"
-"Ãrta Johan Levin, 1999\n"
-"\n"
-"Surround visszhang Ãrta Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Visszhang"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg bÅvÃtméyn"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1130,55 +1141,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg bÅvÃtméyn"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "FájlÃró bÅvÃtmény"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Kimeneti fájl formátum:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "BeállÃtás"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Mentés az eredeti könyvtárba"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Mentés egyéb könyvtárba"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Kimeneti fájl könyvtára:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Válasszon egy mappát"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Legyen a fájlnévbÅl:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "eredeti fájl kiterjesztések"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Eredeti fájl kiterjesztés"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "eredeti fájlnév"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Eredeti fájlnév"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Ne vágja le a fájl kiterjesztést"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "Az eredeti fájl kiterjesztés használata"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1196,165 +1207,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "FájlÃró bÅvÃtmény"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Automatikus"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Joint Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Sztereó"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Monó"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 BeállÃtás"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_Rendben"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Algoritmus minÅsége:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
msgstr "Kimenet mintavétele:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
msgstr "Bitráta / TömörÃtési arány:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Bitráta (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "TömörÃtési arány:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Audio mód:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "Egyéb:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Hiba védelem"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "MinÅség"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "VBR/ABR engedélyezése"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "TÃpus:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR beállÃtások:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Minimális bitsebesség (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Maximális bitsebesség (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr ""
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR beállÃtások:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Ãtlagos bitráta (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR minÅségi szint:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Ne Ãrjon Xing VBR fejlécet"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Xing VBR fejléc elhagyása"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Megjelölés jogvédettként"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Megjelölés eredetiként"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "ID3 paraméterek:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Mindig adja hozzá a 2-es verzió cÃmkéit"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Csak v1 cÃmkék hozzáadása"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Csak v2 cÃmkék hozzáadása"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "CÃmkék"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis kódoló beállÃtások"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "MinÅségi szint (0-10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC dekódoló"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
-msgstr ""
+msgstr "veszteségmentes"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1366,11 +1381,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC dekódoló"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1378,11 +1389,19 @@ msgstr ""
"GIO bÅvÃtmény az Audacious-hoz\n"
"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO bÅvÃtmény"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "Olvas-és-hozzáad mód nem támogatott"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "Ãrvénytelen megnyitási mód"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1394,530 +1413,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
-msgstr ""
+msgstr "OpenGL spektrum analizátor"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
msgstr "Gnome rövidÃtések"
-#: src/gtkui/columns.c:34
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Bejegyzés száma"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "CÃm"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "ElÅadó"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Ãv"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Album"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Album elÅadó"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Sáv"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Műfaj"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Várakozási sor pozÃció"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Hossz"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Fájl elérési útja"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Fájlnév"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Egyéni cÃm"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Bitráta"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
-msgstr ""
+msgstr "ElérhetŠoszlopok"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
-msgstr ""
+msgstr "MegjelenÃtett oszlopok"
+
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "KeresŠeszköz"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Balra rögzÃt"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Jobbra rögzÃt"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Felülre rögzÃt"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Alulra rögzÃt"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "RögzÃtés feloldása"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Letiltás"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr ""
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "Fájl_ok megnyitása ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "_URL megnyitása ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "Fájlok hozzá_adása ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "U_RL hozzáadása ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
-msgstr ""
+msgstr "_Keresés a gyűjteményben"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "_Névjegy ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
-msgstr ""
+msgstr "_BeállÃtások ..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Kilépés"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Lejátszás"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "_Szünet"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_MegállÃtás"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "ElÅ_zÅ"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_KövetkezÅ"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Ismétlés"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_Véletlenszerű"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "_Ne legyen léptetés a lejátszólistában"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
-msgstr ""
+msgstr "L_eállÃtás az aktuális dal után"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "Dal _információ ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Ugrás _idÅre ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "Ugrás _dalra ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
-msgstr ""
+msgstr "_Ismétlési pontok törlése"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "CÃm szerin_t"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr ""
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "_Fájlnév szerint"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
-msgstr ""
+msgstr "Fájl _elérési útja szerint"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Sáv szeri_nt"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "ElÅ_adó szerint"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
-msgstr ""
+msgstr "Al_bum szerint"
+
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Albu_m elÅadó szerint"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "_Dátum szerint"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "_Műfaj szerint"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
-msgstr ""
+msgstr "_Hossz szerint"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "_Fájl útvonal szerint"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "_Egyedi cÃm szerint"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Fo_rdÃtott sorrend"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "Véletlensze_rű sorrend"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr ""
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_Lejátszás/Szünet"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_FrissÃtés"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "Rendezé_s"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
-msgstr ""
+msgstr "Kije_löltek rendezése"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
-msgstr ""
+msgstr "KettÅzöttek eltávolÃtása"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "_Nem elérhetŠfájlok törlése"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Ãj"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "Ãt_nevezés ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
-msgstr ""
+msgstr "Tö_rlés"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importálás ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Exportálás ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "_Lejátszólista kezelŠ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_Várakozási sor kezelŠ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "HangerÅ _fel"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "HangerÅ _le"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_HangszÃnszabályzó"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
-msgstr ""
+msgstr "E_ffektusok ..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "_Menü sor mutatása"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "I_nfo sor mutatása"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Inf_ormációs sáv mutatása"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "_Státusz sor mutatása"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
-msgstr ""
+msgstr "Hát_ralévŠidŠmutatása"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
-msgstr ""
+msgstr "_MegjelenÃtés ..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Fájl"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "L_ejátszás"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Lejátszólista"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Szervizek"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Kimenet"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Nézet"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
-msgstr ""
+msgstr "_Várólistára/Várólistáról ki"
+
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "_Tartalmazó mappa megnyitása"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "_Kivágás"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Másolás"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Beillesztés"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Mind kivál_aszt"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "Ãtneve_zés ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
-msgstr ""
+msgstr "<b>Lejátszólista fülek</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
-msgstr ""
+msgstr "Mindig mutassa a füleket"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
-msgstr ""
+msgstr "Elemek számának mutatása"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
-msgstr ""
+msgstr "Bezárás gomb mutatása"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
-msgstr ""
+msgstr "<b>Lejátszólista oszlopok</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
-msgstr ""
+msgstr "Oszlop fejlécek mutatása"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
-msgstr ""
+msgstr "<b>Egyéb</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
-msgstr ""
+msgstr "NyÃl billentyűk a tekeréshez:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
-msgstr ""
+msgstr "Számváltáskor gördül"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK+ felület"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Pufferelés ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "sztereó"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d csatorna"
msgstr[1] "%d csatorna"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Egyszerű mód."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Lejátszólista mód."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "LeállÃtás az aktuális dal után."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
-msgstr ""
+msgstr "ElÅzÅ szám"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Lejátszás"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Szünet/Folytatás"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "LeállÃt"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
-msgstr ""
+msgstr "KövetkezŠszám"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
-msgstr ""
+msgstr "5 mp elÅre"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
-msgstr ""
+msgstr "5 mp vissza"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "NémÃtás"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
-msgstr ""
+msgstr "HangerŠnövelése"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
-msgstr ""
+msgstr "HangerŠcsökkentése"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
-msgstr ""
+msgstr "Ugrás fájlhoz"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
-msgstr ""
+msgstr "Lejátszó ablak(ok) váltása"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "On-Screen-Display mutatása"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
-msgstr ""
+msgstr "Ismétlés bekapcsolása"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
-msgstr ""
+msgstr "Véletlenszerű lejátszás be"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
-msgstr ""
+msgstr "Játszott szám után állj"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
-msgstr ""
+msgstr "Lejátszó ablak(ok) kiemelése"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(nincs)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1925,37 +2021,39 @@ msgid ""
"Do you want to continue?"
msgstr ""
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Egér gombok hozzárendelése"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr ""
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
msgstr ""
+"Adjon meg egy billentyűkombinációt a beviteli mezÅben.\n"
+"Ez fog az egér gombjaihoz kötÅdni."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Gyorsbillentyűk:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Művelet:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Billentyű kötések:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
-msgstr ""
+msgstr "_Hozzáadás"
+
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Ãltalános gyorsbillentyűk"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1970,124 +2068,97 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Ãltalános gyorsbillentyűk"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK kimenet"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "Automatikus csatlakozás a kimeneti portokhoz"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Sikertelen kapcsolódás a JACK porthoz: %s."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
+"A JACK csak a lebegÅpontos audiót támogatja. Kérem állÃtsa át a kimeneti bit "
+"mélységet lebegÅpontosra az Audacious beállÃtásaiban."
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "Sikertelen kapcsolódás a JACK szerverhez; valóban fut?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
+"A JACK szerverhez szükséges mintavételi frekvencia %d Hz, de az Audacious "
+"csa %d Hz-en játszik le. Kérem használja a Mintavételi Frekvencia Konverter "
+"modult a hibák elkerülése érdekében."
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK kimenet"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s BeállÃtások"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr ""
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Modul útvonalak:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
"After adding new paths, press Enter to scan for new plugins.</small>"
msgstr ""
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "ElérhetÅ bÅvÃtmények:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Engedélyez"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Engedélyezett modulok:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "BeállÃtások"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
+"LADSPA Host az Audacious részére\n"
+"Copyright 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA gép"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: nem sikerült a LIRC támogatás inicializálni\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: újracsatlakozás...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: ismeretlen parancs \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr ""
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr ""
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC bÅvÃtmény"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2102,74 +2173,94 @@ msgid ""
"\n"
"For more information about LIRC, see http://lirc.org."
msgstr ""
+"Egyszerű modul az Audacious LIRC távirányÃtón keresztüli vezérléséhez\n"
+"\n"
+"Az Audacious részére adoptálták:\n"
+"Tony Vroon <chainsaw at gentoo.org>\n"
+"Joonas Harjumäki <jharjuma at gmail.com>\n"
+"\n"
+"Az eredeti XMMS LIRC modul Ãrói:\n"
+"Carl van Schaik <carl at leg.uct.ac.za>\n"
+"Christoph Bartelmus <xmms at bartelmus.de>\n"
+"Andrew O. Shadoura <bugzilla at tut.by>\n"
+"\n"
+"További információkért nézze meg a LIRC honlapját, http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Kapcsolat</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Ãjracsatlakozás a LIRC szerverhez"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Várjon az újracsatlakozás elÅtt:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC bÅvÃtmény"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki bÅvÃtmény"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Nincs elérhetŠzeneszöveg"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Hiba"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Nem sikerült letölteni: %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Hiba"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Nem sikerült értelmezni: %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Zeneszöveg keresése ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Ãrvénytelen a dal metaadata"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Kapcsolódás a lyrics.wikia.com helyhez ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki bÅvÃtmény"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U lejátszólisták"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Tact generátor"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Tact generátor: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Tact generátor: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2178,162 +2269,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr ""
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Csatorna keverÅ"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Csatorna keverÅ</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Kimeneti csatornák:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Csatorna keverÅ"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS bÅvÃtmény"
-#: src/modplug/plugin_main.c:55
-msgid "<b>Resolution</b>"
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Modul lejátszó)"
+
+#: src/modplug/plugin_main.cc:53
+msgid "<b>Resolution</b>"
+msgstr "<b>Felbontás</b>"
+
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
-msgstr ""
+msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
-msgstr ""
+msgstr "16 bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
-msgstr ""
+msgstr "<b>Csatornák</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr ""
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr "<b>Mintavételi ráta</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
-msgstr ""
+msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
-msgstr ""
+msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
-msgstr ""
+msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
-msgstr ""
+msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
-msgstr ""
+msgstr "Szint:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
-msgstr ""
+msgstr "<b>Basszus erÅsÃtés</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
-msgstr ""
+msgstr "<b>Surround</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
-msgstr ""
+msgstr "Túlvételezés"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
-msgstr ""
+msgstr "Zajcsökkentés"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
-msgstr ""
+msgstr "AMIGA MOD fájlok lejátszása"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
-msgstr ""
+msgstr "<b>Ismétlés</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
-msgstr ""
+msgstr "Ismétlés száma:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
-msgstr ""
+msgstr "Ismétlés örökké, állÃtsd be az ismétlés számát -1-re"
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Modul lejátszó)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Térhatású"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "A beállÃtások csak az Audacious újraindÃtása után érvényesülnek."
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 bÅvÃtmény"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Haladó</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Térhatású"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 szerver"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS bÅvÃtmény"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Ismeretlen HTTP hiba"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "Hiba az URL elemzésekor"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Túl sok átirányÃtás"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "LeállÃtva"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Az Audacious nem játszik."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Asztali értesÃtések"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2353,55 +2476,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
-msgstr ""
+msgstr "Lejátszó vezérlÅk mutatása"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
-msgstr ""
+msgstr "Mindig mutasson értesÃtést"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Asztali értesÃtések"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "Az album nevének megjelenÃtése az értesÃtésben"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
-msgstr ""
+msgstr "Mutat"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Szünet"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "KövetkezÅ"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Alapértelmezett eszköz"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 kimenet"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "OSS3 kimenet"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Alapértelmezett eszköz"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Audio eszköz:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "AlternatÃv eszköz használata:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
-msgstr ""
+msgstr "HangerŠmentése munkamentek között"
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Formátum konverzió engedélyezése az OSS szoftverben."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2410,19 +2542,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr ""
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Lejátszólista kezelÅ"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Elemek"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_EltávolÃtás"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "Ãt_nevezés"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS lejásztólisták"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr ""
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio kimenet"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2442,143 +2590,214 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio kimenet"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "QtMultimedia Kimenet"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Dolgozom ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Keresés"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_Mappa megnyitása ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "M_appa hozzáadása ..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "_Napló ellenÅr ..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Fájlok megnyitása"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Fájlok hozzáadása"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ElÅzÅ"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Ismétlés"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Véletlenszerű"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Qt felület"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Mintavételi konverter"
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
+"Mintavételi Ráta Konverter modul az Audacioushoz\n"
+" Copyright 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Lineáris interpoláció"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>ÃtalakÃtás</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Módszer: "
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
-msgstr ""
+msgstr "Ráta:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr ""
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
-msgid "192 kHz:"
-msgstr ""
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr ""
+#: src/resample/resample.cc:241
+msgid "192 kHz:"
+msgstr "192 kHz:"
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
-msgstr ""
+msgstr "Hozzáférés megtagadva"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
-msgstr ""
+msgstr "Hálózati probléma."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
-msgstr ""
+msgstr "EllenÅrzés..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
-msgstr ""
+msgstr "_Jogosultságok ellenÅrzése"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2589,769 +2808,842 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL kimenet"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr ""
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Gyűjtemény"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Ismeretlen ElÅadó"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Ismeretlen Album"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d találat"
+msgstr[1] "%d találat"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d album"
-msgstr[1] "%d album"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d rejtett)"
+msgstr[1] "(%d rejtett)"
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-"%s, %d dal"
-msgstr[1] ""
-"%s\n"
-"%s, %d dal"
-
-#: src/search-tool/search-tool.c:639
-#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-msgstr[1] ""
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d zeneszám"
+msgstr[1] "%d zeneszám"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "műfaj szerint"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "be"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "Ãrta"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Lejátszólista létrehozása"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "Lejátszólistához hozzá_ad"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Keresés a gyűjteményben"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
+"Az Audacious zenekönyvtárába importáláshoz válaszd ki a mappát majd kattints "
+"a \"FrissÃtés\" ikonra."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Kérem várjon ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Mappa választás"
-#: src/skins/menus.c:56
-msgid "Open Files ..."
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "SID lejátszó"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>Kimenet</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Csatornák:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Emuláció</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "MOS 8580 emulálása (alapértelmezett: MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
msgstr ""
-#: src/skins/menus.c:57
-msgid "Open URL ..."
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Emuláció szűrÅ"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Ãra sebesség:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "Ne legyen automatikus óra sebesség állÃtás"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>Lejátszási idÅ</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "Maximális lejátszási idÅ beállÃtása:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Csak akkor ha a zeneszám hossza ismeretlen"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "Minimális lejátszási idÅ beállÃtása:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Megjegyzés</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Csend eltávolÃtása"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Csend eltávolÃtása</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
msgstr ""
-#: src/skins/menus.c:59
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
+msgid "Open Files ..."
+msgstr "Fájlok megnyitása ..."
+
+#: src/skins/menus.cc:65
+msgid "Open URL ..."
+msgstr "URL megnyitása ..."
+
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Keresés a gyűjteményben"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Lejátszás"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Lejátszólista"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Nézet"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
-msgstr ""
+msgstr "Szolgáltatások"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
-msgstr ""
+msgstr "Névjegy ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
-msgstr ""
+msgstr "BeállÃtások ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
-msgstr ""
+msgstr "Kilépés"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
-msgstr ""
+msgstr "Dal információ ..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Ismétlés"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Véletlenszerű"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Ne legyen léptetés a lejátszólistában"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
-msgstr ""
+msgstr "LeállÃtás az aktuális dal után"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ElÅzÅ"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
-msgstr ""
+msgstr "Ugrás a dalra ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
-msgstr ""
+msgstr "Ugrás idÅpontra ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Ãj lejátszólista"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
-msgstr ""
+msgstr "Lejátszólista átnevezése ..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
-msgstr ""
+msgstr "Lejátszólista törlése"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
-msgstr ""
+msgstr "ElÅzÅ lejátszólista"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
-msgstr ""
+msgstr "KövetkezŠlejátszólista"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
-msgstr ""
+msgstr "Lejátszólista importálása"
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
-msgstr ""
+msgstr "Lejátszólista exportálása"
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
-msgstr ""
+msgstr "Lejátszólista kezelŠ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
-msgstr ""
+msgstr "Várakozási sor kezelŠ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
-msgstr ""
+msgstr "Lejátszólista frissÃtése"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Lejátszólista szerkesztŠmutatása"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "HangszÃnszabályzó mutatása"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
-msgstr ""
+msgstr "HátralévŠidŠmutatása"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Mindig felül"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
-msgstr ""
+msgstr "Minden munkaterületen"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
-msgstr ""
+msgstr "Lejátszó felgördÃtése"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
-msgstr ""
+msgstr "Lejátszólista szerkesztÅ felgördÃtése"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
-msgstr ""
+msgstr "HangszÃnszabályzó felgördÃtése"
+
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Dupla méret"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:138
msgid "Add URL ..."
-msgstr ""
+msgstr "URL hozzáadása ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
-msgstr ""
+msgstr "Fájlok hozzáadása ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "CÃm szerint"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "Fájlnév szerint"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
-msgstr ""
+msgstr "Fájl útvonal szerint"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Ãsszes törlése"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Várólista törlése"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Elérhetetlen fájlok törlése"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "KettÅzöttek eltávolÃtása"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Nem kiválasztottak törlése"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Kijelölt törlése"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Keresés és választ"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Kijelölés megfordÃtása"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Nincs kijelölés"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Mindet kijelöl"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Album szerint"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "A dal sorszáma szerint"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "ElÅadó szerint"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Album szerint"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Album elÅadó szerint"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
-msgstr ""
+msgstr "Kiadás dátuma szerint"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "A dal sorszáma szerint"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "Műfaj szerint"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "Hossz szerint"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "Egyéb cÃm szerint"
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Véletlenszerű lista"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "FordÃtott lista"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Kijelöltek rendezése"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Lista rendezése"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Kivágás"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Másolás"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Beillesztés"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
-msgstr ""
+msgstr "Várólistára/Várólistáról ki"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
-msgstr ""
+msgstr "ElÅre beállÃtott betöltése"
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
-msgstr ""
+msgstr "Alapértelmezett betöltése"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
-msgstr ""
+msgstr "EQF fájl betöltése ..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
-msgstr ""
+msgstr "ElÅre beállÃtott mentése ..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
-msgstr ""
+msgstr "Alapértelmezettként ment"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
-msgstr ""
+msgstr "Minden érték nulla"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr ""
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Mentés"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Betöltés"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Profilok"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "ElÅre beállÃtott betöltése"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr ""
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr ""
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr ""
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr ""
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr ""
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Lejátszó:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Lejátszó:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "FÅablak betűtÃpus kiválasztás:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Lejátszólista:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Lejátszólista:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Válassza ki a lejátszólista betűkészletét:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
-msgstr ""
+msgstr "<b>Felület</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
-msgstr ""
+msgstr "<b>BetűtÃpusok</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Bitmap fontok használata (csak ASCII támogatása)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "A dal cÃme mindkét irányba mozog"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analizátor"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Szkóp"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Kikapcsolva"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Szokásos"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Tűz"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Vonalak"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "CsÃkok"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Lasabb"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Lassú"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Közepes"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Gyors"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Leggyorsabb"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
-msgstr ""
+msgstr "Pontok"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
-msgstr ""
+msgstr "Vonal"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
-msgstr ""
+msgstr "Szolid"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Jég"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Sima"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
-msgstr ""
+msgstr "<b>TÃpus</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
-msgstr ""
+msgstr "MegjelenÃtés tÃpusa:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
-msgstr ""
+msgstr "<b>Analizátor</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
-msgstr ""
+msgstr "Csúcsok mutatása"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
-msgstr ""
+msgstr "SzÃnezés:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
-msgstr ""
+msgstr "StÃlus:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
-msgstr ""
+msgstr "Szkóp stÃlusa:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Ãltalános"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "MegjelenÃtés"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Preamp"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious Equalizer"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Tekerés %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "HangerÅ: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balansz: %d%% bal"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balansz: közép"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balansz: %d%% jobb"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "BeállÃtások menü"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Tiltja a 'Mindig felül' opciót"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Engedélyezi a 'Mindig felül' opciót"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Fájl Információs doboz"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "MegjelenÃtés"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Egyszerű mód."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Lejátszólista mód."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "LeállÃtás az aktuális dal után."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Elemek keresése az aktÃv lejátszólistában"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3359,57 +3651,61 @@ msgid ""
"for."
msgstr ""
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
msgstr "CÃm:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr "Album:"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr "ElÅadó:"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
msgstr "Fájlnév:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Az elÅzÅ kiválasztások törlése keresés elÅtt"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Automatikusan várólistára kerülnek a talált elemek"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Hozzon létre új lejátszólistát az egyezÅ elemekbÅl"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audacious lejátszólista szerkesztÅ"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d / %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Régi Winamp 2.x bÅr"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Nem régi Winamp 2.x bÅr"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Nem lehet létrehozni a könyvtárat (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile bÅvÃtmény"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3431,75 +3727,69 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr ""
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Sndio kimenet"
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Menti és helyreállÃtja a hangerÅt:"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Nem támogatott formátum"
-
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Sndio hiba: Ismeretlen audió formátum (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio eszköz"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Sndio hiba: sio_open() sikertelen"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr ""
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Sndio hiba: sio_setpart() sikertelen"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Sndio hiba: sio_start() sikertelen"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Szám váltás"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Parancs futtatása ha az Audacious elindÃt egy új számot."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Parancs:"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Parancsok</b>"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Parancs futtatása a dal végén."
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Parancs ami lefut az új zeneszám indÃtásakor:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "Parancs futtatása amikor Audacious elér a lejátszási lista végéhez."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Parancs ami lefut amikor vége a zeneszámnak:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
-msgstr "Parancs futtatása ha a dal cÃm változik (pl. hálózati stream-cÃmek)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Parancs ami lefut ha a lejátszólistának vége:"
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr "Parancs ami lefut a szám cÃmének változásakor (hálózati folyamhoz):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3514,17 +3804,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Parancsok"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3533,51 +3821,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
-msgstr ""
+msgstr "Gyors"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
-msgstr ""
+msgstr "Alacsony"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
-msgstr ""
+msgstr "Magas"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
-msgstr ""
+msgstr "Nagyon magas"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
-msgstr ""
+msgstr "MinÅség:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
-msgstr ""
+msgstr "Sebesség:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
-msgstr ""
+msgstr "Hangmagasság:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr ""
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Státusz ikon"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
-msgstr ""
+msgstr "BeállÃ_tások ...."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3588,63 +3876,66 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr ""
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "HangerŠváltás"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Váltja a lejátszott dalt"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Egyéb beállÃtások</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Felugró ablakok tiltása"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
-msgstr ""
+msgstr "Bezáráskor az értesÃtési területen marad (a tálcán)"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr ""
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra sztereó"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
+"Extra Sztereó bÅvÃtmény\n"
+"\n"
+"Ãrta: Johan Levin 1999."
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra Sztereó</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
msgstr ""
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Hang generátor:"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3653,15 +3944,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr ""
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr ""
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3682,44 +3969,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr ""
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr ""
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
msgstr ""
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr ""
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr ""
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
+#: src/xsf/plugin.cc:50
+msgid "2SF Decoder"
msgstr ""
-#: src/xsf/plugin.c:217
-msgid "2SF Decoder"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
msgstr ""
-#: src/xspf/xspf.c:438
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr ""
diff --git a/po/id_ID.po b/po/id_ID.po
index bb3646bfb161..056470b09ae8 100644
--- a/po/id_ID.po
+++ b/po/id_ID.po
@@ -5,27 +5,28 @@
# Translators:
# Rahman Yusri Aftian <aftian at yahoo.com>, 2012
# Andika Triwidada <andika at gmail.com>, 2012
-# Ardjuna <Asyura.x at gmail.com>, 2013
+# Ardjuna <Asyura.x at gmail.com>, 2013,2015
# Ardjuna <Asyura.x at gmail.com>, 2012
-# mijortsa <astrojim.blankon at gmail.com>, 2012
+# abd azis ws <astrojim.blankon at gmail.com>, 2012
# <bu0ncu3 at yahoo.com>, 2012
-# mascatur <satyafree at gmail.com>, 2013
+# Catur Susetyo <satyafree at gmail.com>, 2013
# <kokabiel9 at gmail.com>, 2012
+# Liffindra Angga Zaaldian <findrakecil at gmail.com>, 2015
# martadinata666 <martadinata666 at gmail.com>, 2012
-# Mohamad Hasan Al Banna, 2012-2013
+# Hasan Al Banna, 2012-2013
# <pri_yess at yahoo.com>, 2012
-# Rahman Yusri Aftian <aftian at yahoo.com>, 2012-2013
-# operamaniac <rizkiaulia.r at gmail.com>, 2013
+# Rahman Yusri Aftian <aftian at yahoo.com>, 2012-2014
+# Rizki Aulia Rachman <rizkiaulia.r at gmail.com>, 2013
# xunilresu <xunilresu at gmail.com>, 2012
# <yudi.al at gmail.com>, 2012
# <yustrizal24 at gmail.com>, 2012
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-04-03 11:52+0200\n"
+"PO-Revision-Date: 2015-03-05 11:08+0000\n"
+"Last-Translator: Ardjuna <Asyura.x at gmail.com>\n"
"Language-Team: Indonesian (Indonesia) (http://www.transifex.com/projects/p/"
"audacious/language/id_ID/)\n"
"Language: id_ID\n"
@@ -34,51 +35,38 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "surround"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
-msgstr ""
+msgstr "Dekoder AAC (orisinal)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
-msgid "sequenced"
-msgstr ""
-
-#: src/adplug/plugin.c:14
+#: src/adplug/adplug-xmms.cc:42
msgid "AdPlug (AdLib Player)"
msgstr "AdPlug (Pemutar AdLib)"
-#: src/alarm/alarm.c:778
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
+msgid "sequenced"
+msgstr "telah diurutkan"
+
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarm"
+
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
-msgstr ""
+msgstr "Setel Alarm..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
+"Sebuah plugin yang dapat digunakan untuk mulai bermain pada waktu tertentu\n"
+"\n"
+"Awalnya ditulis oleh Adam Feakin dan Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarm"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -100,8 +88,28 @@ msgid ""
"\n"
"\n"
msgstr ""
+"Waktu\n"
+" Alarm pada:\n"
+" Waktu saat alarm aktif.\n"
+"\n"
+" Diam saat:\n"
+" Hentikan alarm saat waktu ini tiba.\n"
+" (jika dialog pengingat tidak ditutup)\n"
+"\n"
+"\n"
+"Hari\n"
+" Hari aktif:\n"
+" Pilih hari saat alarm akan aktif.\n"
+"\n"
+" Waktu:\n"
+" Pilih waktu aktif alarm pada hari H,\n"
+" atau tekan tombol untuk menggunakan\n"
+" waktu standar.\n"
+"\n"
+"\n"
+"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -123,7 +131,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -137,360 +145,372 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Ini adalah panggilan bangun Anda."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
-msgstr ""
+msgstr "Pengingat Anda untuk hari ini adalah..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Pengingat"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Senin"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Selasa"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Rabu"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Kamis"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Jumat"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Sabtu"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Minggu"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Pengaturan Alarm "
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Waktu"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Bunyikan alarm pada (bawaan):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "j"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Diam setelah:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "jam"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "menit"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Pilih hari aktivasi alarm"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Hari"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Bawaan"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Hari"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Memudar"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "detik"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Volume"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Dimulai dari"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Paripurna"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Sekarang"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Perintah Tambahan"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "gunakan"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Daftar lagu (pilihan)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Pilih daftar lagu"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Pilihan"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Apa yang dimaksud dengan opsi ini?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Bantuan"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Sampul Album"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Gambar Album (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "Keluaran ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"Pengaya Keluaran ALSA untuk Audacious\n"
+"Hak cipta 2009-2012 John Lindgren\n"
+"\n"
+"Terima kasih dari saya kepada William Pitcock, pencipta dari Pengaya "
+"Keluaran ALSA NG, yang kodenya telah disajikan sebagai sebuah rujukan ketika "
+"panduan ALSA tidak cukup memadai."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(tidak ada deskripsi)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Perangkat PCM standar"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Perangkat mixer standar"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "Perangkat PCM:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Perangkat mixer:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Elemen mixer:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Antisipasi pemutusan saluran"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (Pemutar MIDI)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "Keluaran ALSA"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (Pemutar MIDI)"
-
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
-msgstr ""
+msgstr "Timpa peningkatan bawaan:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
-msgstr ""
+msgstr "Timpa polyphony bawaan:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
-msgstr ""
+msgstr "Timpa gema bawaan:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
-msgstr ""
+msgstr "Nyala"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
-msgstr ""
+msgstr "Timpa paduan suara bawaan:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
-msgstr ""
+msgstr "<b>Putar lagu</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
-msgstr ""
+msgstr "Tukar tempat"
+
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "nada setengah"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
-msgstr ""
+msgstr "Perpindahan drum: "
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "angka not"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Lompati hening di awal"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Lompati hening yang mengikuti"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
-msgstr ""
+msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
-msgstr ""
-
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr ""
+msgstr "<b>Synthesizer</b>"
+
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "Kadar contoh:"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - pilih berkas SoundFont"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Batal"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
-msgstr ""
+msgstr "Bu_ka"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "Namaberkas"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "Nama berkas"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Ukuran (bytes)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nama:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI Info </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Format:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Panjang(milidetik)"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
-msgstr ""
+msgstr "Jumlah trek:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variable"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Waktu Div:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> Info dan Lirik MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* tidak ada komentar yang tersedia di berkas MIDI ini *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* tidak ada lirik yang tersedia di berkas MIDI ini *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Keluar"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (UTF-8 tidak cocok)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Tentang AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -501,152 +521,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
-msgstr ""
+msgstr "AOSD (On-Screen Display)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Persegi panjang"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Persegi Bersudut Bundar"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Persegi Bersudut Cekung"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Tidak ada"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Mulai putar kembali"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Tampilkan OSD saat awalan lagu dimainkan."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Ubah judul"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Tampilkan OSD selama lagu diputar. Judul lagu akan diubah namun tidak dengan "
-"nama berkasnya. Umumnya berguna untuk menampilkan perubahan judul saat "
-"streaming melalui internet."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Jedah hidup"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Tampilkan OSD saat lagu dihentikan."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Jedah mati"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Tampilkan OSD saat lagu diputar kembali."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Penempatan"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Mengimbangi X relatif:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Mengimbangi Y relatif:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Lebar tampilan destop"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Opsi Multi Monitor"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Menggunakan tampilan destop"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "Semua monitor"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "monitor %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "waktu (milidetik)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Tampilan:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Menghilang secara cepat:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Menghilang secara perlahan:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Huruf"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Huruf %i"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Bayangan"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Gaya Penggambaran"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Warna"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Warna %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Aktifkan pemicu"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Peristiwa"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Manajer komposisi terdeteksi"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -656,112 +670,112 @@ msgstr ""
"kecuali kalau kamu tahu bahwa kamu punya satu yang berjalan, harap "
"diaktifkan sebaliknya OSD tidak akan bekerja dengan baik"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Manajer komposisi tidak dibutuhkan untuk transparansi semu"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Transparansi"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Transparansi palsu"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Transparansi penuh (dibutuhkan Kompositor X)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Ekstensi komposisi tidak digunakan"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Ekstensi komposisi tidak tersedia"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>OSD Audacious</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "OSD Audacious - Konfigurasi"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Posisi"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animasi"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "teks"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Dekorasi"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Pemicu"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Misc"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Uji coba"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
-msgstr ""
+msgstr "Daftar putar ASXv3"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
-msgstr ""
+msgstr "Daftar Putar ASXv1/ASXv2 "
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Daftar Putar Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
-msgstr ""
+msgstr "<b>Warna</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
-msgstr ""
-
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
-msgstr ""
+msgstr "Blur Scope"
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
-msgstr ""
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
-#: src/bs2b/plugin.c:166
+#: src/bs2b/plugin.cc:129
msgid "Presets:"
-msgstr ""
+msgstr "Aturan baku:"
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr ""
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
+msgstr "Tingkat suapan:"
+
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr "Frekuensi potong:"
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
-msgstr ""
+msgstr "Penelaah spektrum"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Pengaya Audio CD"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -772,170 +786,167 @@ msgid ""
"\n"
"This was a Google Summer of Code 2007 project."
msgstr ""
+"Hak cipta (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> dan kawan-kawan.\n"
+"\n"
+"Banyak terima kasih kepada para pengembang libcdio <http://www.gnu.org/"
+"software/libcdio/>\n"
+"dan kepada para pengembang libcddb <http://libcddb.sourceforge.net/>.\n"
+"\n"
+"Juga terima kasih kepada Tony Vroon karena telah mengajari dan membimbing "
+"saya.\n"
+"\n"
+"Ini adalah sebuah proyek Google Summer of Code 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
-msgstr ""
+msgstr "<b>Perangkat</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
-msgstr ""
+msgstr "Kecepatan membaca:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
-msgstr ""
+msgstr "Timpa perangkat:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadata</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Gunakan CD-Teks"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
-msgstr ""
+msgstr "Gunakan CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Gunakan HTTP daripada CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Server:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
-msgstr ""
+msgstr "Jalur:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Port:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Pengaya Audio CD"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
-msgstr ""
+msgstr "Gagal memulai subsistem cdio."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
-msgstr ""
+msgstr "URI Tidak Valid %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
-msgstr ""
+msgstr "Tidak menemukan trek %d."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr ""
+msgstr "Trek %d adalah sebuah trek data."
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
-msgstr ""
+msgstr "Galat saat membaca audio CD."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Audio CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
-msgstr ""
+msgstr "Gagal membuka perangkat CD %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Penggerak kosong."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Tipe diska tidak didukung."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr ""
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Putar CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Tambah CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr ""
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr ""
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Volume tengah:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Jangkauan dinamis:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr ""
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -945,195 +956,220 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Bass:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Trebel:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Panjang standar lagu:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Aktifkan fitur sampel ulang"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Tingkat sampel ulang:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
-msgstr ""
+msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Abaikan panjang dari tag SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Tingkatkan reverb"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Dekoder Musik Konsol Game"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr ""
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr ""
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr ""
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr ""
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr ""
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr ""
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Hapus Berkas"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
-msgstr ""
+msgstr "Pindah ke Tong Sampah"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Hapus"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Batal"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
-msgstr ""
+msgstr "Hapus Berkas Dipilih"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Echo</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
-msgstr ""
+msgstr "Penundaan"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr ""
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
-msgstr ""
-
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
+msgstr "Volume"
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Echo"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Pengaya FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1143,55 +1179,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "Pengaya FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr ""
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Format berkas keluaran:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Konfigurasi"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Simpan didalam original direktori"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Simpan dalam direktori tertentu"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Direktori berkas keluaran:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Ambil folder"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Dapatkan nama dari:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "berkas original tag"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "nama berkas original"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Jangan hilangkan ektensi file"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Tambahkan nomor jalur di nama berkas"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1209,165 +1245,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr ""
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Otomatis"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Gabung stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Konfigurasi MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_OK"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Kualitas Algoritma"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Keluaran Samplerate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Bitrate / Rasio kompresi:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Bitrate (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Rasio kompresi:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Mode Otomatis:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Memaksakan dengan ketat pemenuhan ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Pengaman kesalahan"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Kualitas"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Aktifkan VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tipe:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Opsi VBR"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Minimum bitrate (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Maksimal bitrate (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Memaksakan dengan ketat bitrate terendah"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Opsi ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "bitrate rata-rata (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "Tingkat kualitas VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Jangan menulis header Xing VBR"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Tandai sebagai hak cipta"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Tandai sebagai orisinil"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "Parameter ID3"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Memaksa tambahan tag versi 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Hanya tambahkan tag v1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Hanya tambahkan tag v2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Tags"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Pengaturan Enkoder Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Tingkat kualitas (0-10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "Dekoder FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr ""
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1375,21 +1415,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "Dekoder FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "Pengaya GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1401,529 +1445,606 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Masukkan angka"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Judul"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Artis"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Tahun"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Album"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Track"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Aliran"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Posisi antri"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Panjang"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Tempat Berkas"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Nama berkas"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Title pilihan"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Bitrate"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
-msgstr ""
+msgstr "Kolom tersedia"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
-msgstr ""
+msgstr "Tampilan kolom"
+
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Alat Pencari"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Dok dikiri"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Dok dikanan"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Dok diatas"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Dok dibawah"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Tidak didok"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Nonaktifkan"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Alat Pencari"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Buka Berkas..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Buka _URL..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_Tambah Berkas ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Tambah U_RL..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
-msgstr ""
+msgstr "Cari _Pustaka"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "Te_ntang..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
-msgstr ""
+msgstr "_Pengaturan...."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Keluar"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Putar"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Paus_e"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Stop"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "Se_belumnya"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "Sela_njutnya"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Ulangi"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_Acak"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "N_o Kemajuan Playlist"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "Informasi_Lagu..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Loncat ke _Waktu..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "_Loncat ke Lagu..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Oleh_Judul"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Oleh No_Track"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Oleh_Artis"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Oleh _Tanggal Release"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Berdasarkan tempat"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "By _Judul Terkustomisasi"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "B_alik Urutan"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_Acak Urutan"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "Sega_rkan"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "Uru_tkan"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr ""
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Baru"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr ""
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
-msgstr ""
+msgstr "Hap_us"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Import..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Export..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr ""
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_Manajer Antrian ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Volume _Naik"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "Volume _Turun"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Equalizer"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Perlihatkan Bar _Menu"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Perlihatkan _Bar Info"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr ""
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Perlihatkan Bar _Status"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
-msgstr ""
+msgstr "_Visualisasi"
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Berkas"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Pemutaran"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "Daftar P_utar"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Layanan"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Keluaran"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Lihat"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Antre/Tidak Antre"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Potong"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Salin"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Tempel"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Pilih _Semua"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_Ubah nama ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "Tampilan GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr ""
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d kanal"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "mode Single."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "mode Playlist."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Berhenti setelah lagu"
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr ""
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Putar"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Jeda/Mulai Lagi"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Berhenti"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr ""
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Diam"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr ""
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr ""
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
-msgstr ""
+msgstr "Loncat ke berkas"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Tunjukkan On-Screen-Display"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(kosong)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1934,15 +2055,11 @@ msgstr ""
"\n"
"Apakah anda ingin meneruskan?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Mengikat tombol mouse"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Konfigurasi Plugin Global Hotkey"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -1950,23 +2067,27 @@ msgstr ""
"Tekan kombinasi tombol didalam bidang teks.\n"
"Kamu juga dapat mengikat tombol mouse."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Hotkeys:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Aksi:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Kunci Pengikat:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
+msgstr "T_ambah"
+
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1981,56 +2102,51 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "Keluaran Jack"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "Keluaran Jack"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s Pengaturan"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Pengaturan Host LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Modul path:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2041,68 +2157,39 @@ msgstr ""
"Setelah menambahkan path baru, tekan Enter untuk mengamati plugin baru.</"
"small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Pengaya tersedia:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Gunakan"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Pengaya digunakan:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Pengaturan"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr ""
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr ""
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: mencoba menyambung...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: perintah tidak diketahui \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: terputus dari LIRC\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: mencoba menyambung tiap %d detik...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Pengaya LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2118,73 +2205,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Sambungan</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Menyambung kembali ke server LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Tunggu sebelum menyambung kembali:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Pengaya LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr ""
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Tidak ada lirik tersedia"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Kesalahan"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Kesalahan"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Mencari lirik ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Menyambungkan ke lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
+msgstr "Daftar Putar M3U"
+
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
msgstr ""
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Penghasil Tact: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Penghasil Tact: %d bpm %d%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2193,162 +2288,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
msgstr ""
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr ""
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Keluaran kanal:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr ""
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "Pengaya MMS"
-#: src/modplug/plugin_main.c:55
-msgid "<b>Resolution</b>"
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
msgstr ""
-#: src/modplug/plugin_main.c:56
-msgid "8-bit"
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
msgstr ""
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:53
+msgid "<b>Resolution</b>"
+msgstr "<b>Resolusi</b>"
+
+#: src/modplug/plugin_main.cc:54
+msgid "8-bit"
+msgstr "8-bit"
+
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
-msgstr ""
+msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
-msgstr ""
+msgstr "<b>Cennel</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr ""
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr ""
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr ""
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
msgstr ""
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Surround"
-
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "Pengaya MPG123"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "Server MPRIS 2"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Pengaya Neon HTTP/HTTPS"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Berhenti"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious berhenti"
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Pemberitahuan Destop"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2368,55 +2495,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Pemberitahuan Destop"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr ""
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Istirahat"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Selanjutnya"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Alat bawaan"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "Keluaran OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Perangkat suara:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Gunakan alat alternatif"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr ""
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Izinkan pembuatan konversi format oleh perangkat lunak OSS"
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2425,19 +2561,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "Keluaran OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr ""
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr ""
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr ""
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2457,143 +2609,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Cari"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Sebelumnya"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Ulang"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Acak"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
msgstr ""
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr ""
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr ""
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Metode"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr ""
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr ""
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr ""
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr ""
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr ""
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2604,820 +2825,903 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr ""
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr ""
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
-msgstr ""
-
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Artis Tidak Diketahui"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Album Tidak Diketahui"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
+msgstr "Pustaka"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d album"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Buat Daftar Putar"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Tambah ke Daftar Putar"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
-msgstr ""
+msgstr "Cari pustaka"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Mohon tunggu ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Pilih Folder"
-#: src/skins/menus.c:56
-msgid "Open Files ..."
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:64
+msgid "Open Files ..."
+msgstr "Buka Berkas ..."
+
+#: src/skins/menus.cc:65
msgid "Open URL ..."
+msgstr "Buka URL...."
+
+#: src/skins/menus.cc:66
+msgid "Search Library"
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Putar Lagu"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Daftar Putar"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Lihat"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
-msgstr ""
+msgstr "Servis"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
-msgstr ""
+msgstr "Tentang"
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
-msgstr ""
+msgstr "Pengaturan"
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
-msgstr ""
+msgstr "Keluar"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
-msgstr ""
-
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Ulang"
+msgstr "Info Lagu"
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Acak"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Tidak ada kemajuan Playlist"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
-msgstr ""
+msgstr "Stop Setelah Lagu Ini"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Sebelumnya"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
-msgstr ""
+msgstr "Lompat ke Lagu ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
-msgstr ""
+msgstr "Lompat ke Waktu ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Daftar Lagu Baru"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
-msgstr ""
+msgstr "Ganti Nama Daftar Putar ..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
-msgstr ""
+msgstr "Hapus Daftar Putar"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
-msgstr ""
+msgstr "Daftar Putar Sebelumnya"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
-msgstr ""
+msgstr "Daftar Putar Selanjutnya"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
-msgstr ""
+msgstr "Impor Daftar Putar ..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
-msgstr ""
+msgstr "Ekspor Daftar Putar ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
-msgstr ""
+msgstr "Manager Daftar Putar ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
-msgstr ""
+msgstr "Segarkan Daftar Putar"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Munculkan Perubah Daftar Lagu"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Munculkan Equalizer"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Selalu di Atas"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
-msgid "Add URL ..."
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:138
+msgid "Add URL ..."
+msgstr "Tambah URL"
+
+#: src/skins/menus.cc:139
msgid "Add Files ..."
-msgstr ""
+msgstr "Tambah Berkas ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Dari Judul"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Dari Nama berkas"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
-msgstr ""
+msgstr "Oleh Path Berkas"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Hapus Semua"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Bersihkan Antrian"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Hapus File yang Tidak Tersedia"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Hapus Duplikat"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Hapus yang tidak Terpilih"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Hapus Yang Dipilih"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Cari dan Pilih"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Balik Pilihan"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Jangan Pilih Apapun"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Pilih Semua"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Dari Album"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Oleh Nomor Trek"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Dari Artis"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Dari Album"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
+msgstr "Oleh Tanggal Rilis"
+
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Oleh Nomor Trek"
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Acak Daftar"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Balikkan Daftar"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Urutkan yang Terpilih"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Urutkan Daftar"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Potong"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Salin"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Tempel"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
-msgstr ""
+msgstr "Simpan Berkas EQF ..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
-msgstr ""
+msgstr "Impor Preset-preset Winamp ..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Tampilan Winamp Klasik"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Simpan"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Buka"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Presets"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Muat preset"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr ""
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
-msgstr ""
+msgstr "Simpan preset"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr ""
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
-msgstr ""
+msgstr "Hapus preset"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr ""
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "Pemutar:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Pilih font jendela player utama:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Playlist:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Pilih huruf daftar putar"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
-msgstr ""
+msgstr "<b>Kulit</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
-msgstr ""
+msgstr "<b>Fonts</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Gunakan huruf bitmap (hanya dukungan ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Gulir judul lagu dalam kedua arah"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analyzer"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Cakupan"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Mati"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normal"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Api"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Garis"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Batang"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Paling Lambat"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Lambat"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Sedang"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Cepat"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Paling Cepat"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
-msgstr ""
+msgstr "Garis"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Es"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Halus"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
-msgstr ""
+msgstr "<b>Tipe</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
-msgstr ""
+msgstr "Gaya"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Umum"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualisasi"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Preamp"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious Equalizer"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
-msgstr ""
+msgstr "Berusaha untuk %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Volume: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Keseimbangan: %d%% left"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Keseimbangan: tengah"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Keseimbangan: %d%% kanan"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Menu Opsi"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Nonaktifkan 'Always On Top'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Bolehkan 'Always On Top'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Kotak Info Berkas"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "mode Single."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "mode Playlist."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Berhenti setelah lagu"
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
-msgstr ""
-
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
+msgstr "Cari catatan di daftar putar aktif"
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
"expressions work, simply insert a literal portion of what you're searching "
"for."
msgstr ""
+"Pilih entri dalam daftar putar dengan mengisi satu atau lebih bidang. Fields "
+"menggunakan ekspresi reguler sintaks, case-insensitive. Jika Anda tidak tahu "
+"bagaimana ekspresi reguler bekerja, cukup memasukkan sebagian literal dari "
+"apa yang Anda cari."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Judul: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Artis: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Nama berkas: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr ""
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
-msgstr ""
+msgstr "Buat daftar putar baru dengan mencocokan entri"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
-msgstr ""
+msgstr "Audacious Daftar Putar Editor"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d of %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
-msgstr ""
+msgstr "Arsipkan Kulit Winamp 2.x "
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
-msgstr ""
+msgstr "Jangan Arsipkan Kulit Winam 2.x "
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
+msgstr "Tidak dapat membuat folder (%s): %s\n"
+
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
msgstr ""
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3439,75 +3743,69 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
msgstr ""
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Format tidak didukung"
-
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-#: src/sndio/sndio.c:384
-msgid "sndio device"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
+msgstr "Ubah Lagu"
+
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
msgstr ""
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Perintah saat Audacious memainkan lagu baru."
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Perintah:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "Perintah saat Audacious mencapai akhir daftar lagu."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3522,17 +3820,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Perintah"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3541,51 +3837,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
-msgstr ""
+msgstr "Cepat"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
-msgstr ""
+msgstr "Rendah"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
-msgstr ""
+msgstr "Tinggi"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
-msgstr ""
+msgstr "Sangat Tinggi"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
-msgstr ""
+msgstr "Kualitas"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr ""
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Kecepatan dan Nada"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
-msgstr ""
+msgstr "Kecepatan"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
-msgstr ""
+msgstr "Nada"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr ""
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Ikon Status"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
-msgstr ""
+msgstr "Se_ttings ..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3596,63 +3892,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr ""
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
-msgstr ""
+msgstr "Ubah volume"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
-msgstr ""
+msgstr "Ubah lagu yang sedang diputar"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
-msgstr ""
+msgstr "<b>Pengaturan Lain</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr ""
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr ""
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Ikon Status"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Stereo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra Stereo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr ""
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr ""
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3661,15 +3957,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr ""
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr ""
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3690,44 +3982,75 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Dekoder Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "Dekoder VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "Dekoder VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "Dekoder WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
-msgstr ""
+msgstr "yang berkurang (gabungan)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
-msgstr ""
+msgstr "yang berkurang"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
+"Hak cipta 2006 William Pitcock <nenolod at nenolod.net>\n"
+"\n"
+"Beberapa kode pengaya ditulis oleh Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "Dekoder WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "Dekoder 2SF"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>Pengaturan XSF</b>"
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Abaikan panjang dari berkas"
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
-msgstr ""
+msgstr "XML Shareable Playlists (XSPF)"
diff --git a/po/it.po b/po/it.po
index 9da1799df177..e905f5939a68 100644
--- a/po/it.po
+++ b/po/it.po
@@ -3,21 +3,22 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# davros74 <davros74 at gmail.com>, 2012
-# Federico.Torsello <federico421 at hotmail.it>, 2013-2014
+# David Rossi <davros74 at gmail.com>, 2012
+# Federico <federico421 at hotmail.it>, 2013-2014
# minderz <franketti at gmail.com>, 2014
# Jacopo Lorenzetti <jacopo.jl at gmail.com>, 2011-2012
# Jacopo Lorenzetti <jacopol at cyan.xubiq.com>, 2012-2013
-# Marco91, 2013
-# Nicola Manini <nicola.manini at fisica.unimi.it>, 2014
+# Marco Mangiacavalli, 2013
# Nicola Manini <nicola.manini at fisica.unimi.it>, 2014
+# Nicola Manini <nicola.manini at fisica.unimi.it>, 2014-2015
+# Saverio <saverio.brancaccio at gmail.com>, 2014
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-12 21:08+0000\n"
+"Last-Translator: Nicola Manini <nicola.manini at fisica.unimi.it>\n"
"Language-Team: Italian (http://www.transifex.com/projects/p/audacious/"
"language/it/)\n"
"Language: it\n"
@@ -26,40 +27,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "surround"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "Decoder AAC (MP4)"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "Decoder AAC (Raw)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (Riproduttore AdLib)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "sequenziato"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (Riproduttore AdLib)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Allarme"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "Regola la sveglia ..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -70,11 +59,7 @@ msgstr ""
"\n"
"Originariamente scritto da Adam Feakin e Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Allarme"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -116,7 +101,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -155,7 +140,7 @@ msgstr ""
"Comando addizionale:\n"
"Avvia questo comando al tempo di allarme.\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -179,385 +164,389 @@ msgstr ""
"Seleziona l'allarme nella casella e accendi\n"
"l'interruttore se vuoi che venga mostrato."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Questa è la tua sveglia."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "Il tuo promemoria per oggi è..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Promemoria"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Lunedì"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Martedì"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Mercoledì"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Giovedì"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Venerdì"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Sabato"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Domenica"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Impostazioni sveglia"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "_OK"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "_Cancella"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Ora"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Sveglia alle (predefinita):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Ferma dopo:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "ore"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minuti"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Scegliere i giorni in cui attivare la sveglia"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Giorno"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Predefinita"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Giorni"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Dissolvenza"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "secondi"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Volume"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Inizia a"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Finale"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Attuale"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Comando aggiuntivo"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "abilita"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Playlist (opzionale)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Seleziona una lista di riproduzione"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Opzioni"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Cosa significano queste opzioni?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Aiuto"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Copertina Album"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Copertina dell'album (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "Uscita ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"I miei ringraziamenti a William Pitcock, autore dell'ALSA Output Plugin NG, "
+"il cui codice serve come riferimento quando il manuale ALSA non è "
+"sufficiente."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(nessuna descrizione)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Dispositivo PCM predefinito"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Dispositivo mixer predefinito"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "Dispositivo PCM:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Dispositivo mixer:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Elemento mixer:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Aggira interruzione per esaurimento risorse"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "Plug-in AMIDI (Riproduttore MIDI)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"Connettore AMIDI\n"
+"lettore di musica modulare MIDI\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"I miei ringraziamenti a William Pitcock, autore dell'ALSA Output Plugin NG, "
-"il cui codice serve come riferimento quando il manuale ALSA non è "
-"sufficiente."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "Uscita ALSA"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "Plug-in AMIDI (Riproduttore MIDI)"
+"scritto da Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"Si ringraziano in particolare...\n"
+"Clemens Ladisch e Jaroslav Kysela\n"
+"per i loro programmi eccezionali aplaymidi e amixer; e i\n"
+"documenti alsa-lib per usati per approfondire le conoscenze delle API ALSA\n"
+"\n"
+"Alfredo Spadafina\n"
+"per il bel logo della tastiera midi\n"
+"\n"
+"Tony Vroon\n"
+"per l'aiuto fornito durante l'alpha testing"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "Sovrascrivi l'amplificazione di default"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "Sovrascrivi la polifonia di default"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "Sovrascrivi il riverbero di default"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "Acceso"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "Sovrascrivi il chorus di default"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>Playback</b><b>Riproduzione</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "Trasponi:"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "semitoni"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "Trasla la batteria:"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>Opzioni avanzate</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "numeri di note"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "Estrai i commenti da file MIDI"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Salta il silenzio iniziale"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "Estrai i testi da file MIDI"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Salta il silenzio finale"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>Sintetizzatore</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr "Frequenza di campionamento"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "Frequenza di campionamento:"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - seleziona file SoundFont"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Cancella"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "_Apri"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Nome del file"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Dimensioni (byte)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nome:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> Informazioni MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Formato:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Durata (msec):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Numero di tracce: "
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variabile"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Suddivisione temporale:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> Commenti e testi MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* nessun commento disponibile in questo file MIDI *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* nessun testo disponibile in questo file MIDI *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Chiudi"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (UTF-8 non valido)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Informazioni sul plug-in AMIDI"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug "
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"Riproduttore musicale MIDI modulare\n"
-"http://www.develia.org/projects.php?p=amidiplugâ\n"
-"\n"
-"scritto da Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"Ringraziamenti speciali a...\n"
-"\n"
-"Clemens Ladisch e Jaroslav Kyselaâ\n"
-"per i loro bei programmi aplaymidi e amixer; questi\n"
-"erano realmente utili, insieme con alsa-lib docs, allo scopo di\n"
-"imparare di più sull'API ALSA\n"
-"\n"
-"Alfredo Spadafina\n"
-"per il bel logo midi della tastiera\n"
-"\n"
-"Tony Vroon\n"
-"per il buono aiuto nell alfa test"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -575,152 +564,147 @@ msgstr ""
"Parzialmente basato sulla libreria Ghosd scritta da Evan Martin\n"
"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (Informazioni sullo schermo)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Rettangolo"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Rettangolo arrotondato"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Rettangolo concavo"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Nessuno"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Avvio della riproduzione"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Visualizza l'OSD quando viene riprodotto un elemento della playlist."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Cambio titolo"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Visualizza l'OSD quando, durante la riproduzione, il titolo del brano cambia "
-"ma il nome del file è lo stesso. à utile principalmente per visualizzare i "
-"cambi di titolo negli stream su internet."
+"Attiva OSD quando cambia il titolo di una canzone (per gli stream in rete)."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Attivazione pausa"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Visualizza l'OSD quando viene interrotta la riproduzione."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Disattivazione pausa"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Visualizza l'OSD quando viene ripresa la riproduzione."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Posizionamento"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Offset X relativo:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Offset Y relativo:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Larghezza massima OSD:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Opzioni multi-monitor"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Visualizza OSD su:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "tutti i monitor"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "monitor %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Temporizzazione (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Visualizza:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Dissolvi in ingresso:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Dissolvi in uscita:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Caratteri"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Carattere %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Ombra"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Stile di resa grafica"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Colori"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Colore %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Abilita visualizzazione in seguito all'evento"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Evento"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Rilevato compositing manager"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -730,112 +714,112 @@ msgstr ""
"a meno che tu non sappia di averne uno in esecuzione, per favore attiva un "
"compositing manager altrimenti l'OSD non funzionerà correttamente"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Compositing manager non richiesto per la falsa trasparenza"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Trasparenza"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Falsa trasparenza"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Trasparenza reale (richiede est. Composite di X)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Estensione Composite non caricata"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Estensione Composite non disponibile"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - configurazione"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "_Testa"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "_Regola"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Posizione"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animazione"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Testo"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Decorazione"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Eventi"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Varie"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Test"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "Playlists "
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "Liste di riproduzione ASXv1/ASXv2"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Lista di riproduzione Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Colore</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Blur Scope"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer da Stereofinico a Binaurale (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Preimpostazioni:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Livello di alimentazione:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Frequenza di taglio:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Preimpostazioni:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer da Stereofinico a Binaurale (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Analizzatore di spettro"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Plugin CD Audio"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -856,171 +840,158 @@ msgstr ""
"\n"
"Questo era un progetto Google Summer of Code 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Dispositivo</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Velocità di lettura: "
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Ignora dispositivo: "
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadati</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Usa CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Usa CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Usa HTTP invece di CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Server: "
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Percorso: "
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Porta: "
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Plugin CD Audio"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "Errore nell'inizializzazione del sottosistema cdio."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "URI %s non valido."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Traccia %d non trovata."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "La traccia %d è una traccia dati."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Errore nell'apertura dell'output audio."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Errore durante la lettura del CD Audio."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "CD Audio"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "Brano %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Errore nell'apertura del lettore CD %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Nessuna unità CD audio adatta trovata."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "Errore alla fine dell'inizializzazione dell'unità CD aperta."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Errore nella ricerca del primo/ultimo numero della traccia."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Impossibile leggere inizio/fine dell'LNS per la traccia %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Errore nella creazione della connessione al cddb."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Errore nella richiesta al server CDDB."
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Errore nella richiesta al server CDDB: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Errore nella lettura delle informazioni del cddb: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Il drive è vuoto."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Tipo di disco non supportato."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Voci di menu CD Audio"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Riproduci CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Aggiungi CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Voci di menu CD Audio"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Compressione</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Volume centrale:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Gamma dinamica:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Dynamic Range Compression Plugin per Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Plugin Dynamic Range Compression per Audacious\n"
+"Copyright 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Compressione gamma dinamica"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1036,207 +1007,239 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Bassi:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Alti:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "Eco:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Durata brano predefinita:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>Resampling</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Abilita ricampionamento audio"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Frequenza di ricampionamento:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ignora durata specificata nei tag SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Aumenta riverbero"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Decodificatore musica console giochi"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"La dissolvenza incrociata non è riuscita poiché i brani avevano un numero di "
-"canali differente. Puoi usare il Mixer Canale per convertire i brani allo "
-"stesso numero di canali."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "Uscita CoreAudio"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"La dissolvenza incrociata non è riuscita poiché i brani avevano differenti "
-"frequenze di campionamento. Puoi usare il Convertitore frequenza di "
-"campionamento per convertire i brani alla stessa frequenza."
+"Plugin CoreAudio Output per Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Basato sul plugin SDL Output per Audacious\n"
+"Copyright 2010 John Lindgren"
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "Usa la modalità esclusiva"
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Crossfade Plugin per Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Plugin Crossfade per Audacious\n"
+"Copyright 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Dissolvenza incrociata</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "Su cambiamento automatico della canzone"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "Sovrapposizione:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "Sulla ricerca o cambiamento manuale della canzone"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Suggerimento</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+"Per una dissolvenza migliore, abilitare\n"
+"l'effetto Rimozione del Silenzio"
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Dissolvenza incrociata"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"La dissolvenza incrociata non è riuscita poiché i brani avevano un numero di "
+"canali differente. Puoi usare il Mixer Canale per convertire i brani allo "
+"stesso numero di canali."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"La dissolvenza incrociata non è riuscita poiché i brani avevano differenti "
+"frequenze di campionamento. Puoi usare il Convertitore frequenza di "
+"campionamento per convertire i brani alla stessa frequenza."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Crystalizer</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intensità : "
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Crystalizer"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Plugin Cue Sheet"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Cancella files"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "Si è verificato un errore spostando %s nel cestino: %s"
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "Si è verificato un errore eliminando %s: %s"
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "Si è verificato un errore eliminando %s: file non locale"
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "Vuoi spostare i files selezionati nel cestino?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "Sposta nel cestino"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "Vuoi cancellare permanentemente i files selezionati?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Elimina"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Annulla"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "Cancella files"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "Cancella files selezionati"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>Metodo di cancellazione</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "Sposta nel cestino invece di cancellare immediatamente"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+"Plugin Echo\n"
+"di Johan Levin, 1999\n"
+"Surround echo di Carl van Schaik, 1999\n"
+"Aggiornato per Audacious da William Pitcock e John Lindgren, 2010-2014"
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Eco</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Ritardo: "
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Feedback: "
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Volume: "
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Echo Plugin\n"
-"Realizzato da Johan Levin, 1999\n"
-"\n"
-"Echo surround realizzato da Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Echo"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Plugin FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1252,55 +1255,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "Plugin FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Plugin FileWriter"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Formato del file in uscita:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Configura"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Salva nella directory originale"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Salva in directory personalizzata"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Cartella del file in uscita:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Seleziona una cartella"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Ottieni nome file da:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Genera il nome del file da:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "tag del file originale"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Tag del file originale"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "nome del file originale"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Nome del file originale"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Non togliere estensione dal nome del file"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "Tieni l'estensione del nome originale del file"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
msgstr "Anteponi numero di traccia al nome del file"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1333,165 +1336,169 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "Plugin FileWriter"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Auto"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Joint stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Configurazione MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_OK"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Qualità dell'algoritmo:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
msgstr "Frequenza di campionamento in uscita:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Bitrate / fattore di compressione:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "Rapporto bitrate / compressione:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Bitrate (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Fattore di compressione:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Modalità audio:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "Varie:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Rispetta rigorosamente conformità ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr "Imponi rispetto rigoroso conformità ISO"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Protezione dagli errori"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Qualità "
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Abilita VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tipo:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Opzioni VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Bitrate minima (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Bitrate massima (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Rispetta rigorosamente bitrate minima"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Opzioni ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Bitrate media (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "Livello di qualità VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Non scrivere intestazione VBR Xing"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Ometti l'intestazione VBR Xing"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "Parametri del frame: "
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr "Parametri del frame:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Contrassegna come coperto da copyright"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Contrassegna come originale"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "Parametri ID3:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Forza aggiunta del tag versione 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Aggiungi solo tag v1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Aggiungi solo tag v2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Tag"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Configurazione del codificatore Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Livello di qualità (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "Decodificatore FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "senza perdita"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1503,11 +1510,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "Decodificatore FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1515,11 +1518,19 @@ msgstr ""
"GIO Plugin per Audacious\n"
"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "Plugin GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "Modalità Leggi-e-aggiungi non supportata"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "Modalità di apertura non valida"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1539,535 +1550,620 @@ msgstr ""
"\n"
"Licenza: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL Spectrum Analyzer"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+"Analizzatore di Spettro OpenGL per Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Basato sul plugin di XMMS\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, \n"
+"e 4Front Technologies\n"
+"\n"
+"Licenza: GPLv2+"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "Analizzatore di Spettro OpenGL (Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "Scorciatoie di GNOME"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-"Gnome Shortcut Plugin\n"
-"Ti permette di controllare il riproduttore con i tasti di scelta rapida di "
-"Gnome.\n"
+"Plugin GNOME Shortcut\n"
+"Permette di controllare il lettore con le scorciatoie di GNOME.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Scorciatoie Gnome"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Numero elemento"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Titolo"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Artista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Anno"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Album"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Artista"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Traccia"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Genere"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Posizione nella coda"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Durata"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Percorso del file"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Nome del file"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Titolo personalizzato"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Bitrate"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "Colonne disponibili"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "Colonne visualizzate"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Tool di ricerca"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Aggancia a sinistra"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Aggancia a destra"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Aggancia in alto"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Aggancia in basso"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Sgancia"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Disabilita"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Tool di ricerca"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Apri fileâ¦"
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Apri _URLâ¦"
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "A_ggiungi fileâ¦"
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Aggiungi U_RLâ¦"
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "Cerca nella _Libreria"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "I_nformazioni suâ¦"
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "_Configurazione ..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Esci"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Riproduci"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Interro_mpi"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Ferma"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "Pre_cedente"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_Successiva"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "Ripe_ti"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "C_asuale"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "N_on avanzare nella playlist"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Ferma _dopo questo brano"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "Informazioni sul _branoâ¦"
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Salta alla _posizioneâ¦"
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "Sa_lta al branoâ¦"
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "Imposta Punto di Ripetizione _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "Imposta Punto di Ripetizione _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_Cancella Punti di Ripetizione"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Per _titolo"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "Da _Nome del file"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "Per nome _File"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Da _Percorso del File"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Per _numero di traccia"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Per _artista"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Da Al_bum"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Per Albu_m artista"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Per _data di pubblicazione"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "Per _Genere"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "Da _Lunghezza"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Per percorso del _file"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Per titolo _personalizzato"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Ordine in_verso"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "Ordine _casuale"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_Riproduci questa lista"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "Ri_produci/Riparti"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "A_ggiorna"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Ordina"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "Ordina i selezionati"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "Rimuovi _Duplicati"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Ri_muovi file non disponibili"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Nuova"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "Rin_omina ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "Elimina"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importaâ¦"
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Esportaâ¦"
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "Gestione_Liste di riproduzione ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Gestione co_daâ¦"
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "_Alza volume"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "A_bbassa volume"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Equalizzatore"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "Effetti ..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Mostra barra dei _menu"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Mostra barra i_nformazioni"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Mostra barra di vis_ualizzazione informazioni"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Mostra barra di _stato"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Mostra Tempo _Rimasto"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "_Visualizzazioni ..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_File"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Riproduzione"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Playlist"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Servizi"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Uscita"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Visualizza"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "Inserisci/rimuovi dalla _coda"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "Apri cartella"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "T_aglia"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "C_opia"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Incolla"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Seleziona _tutti"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_Rinomina ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>Schede di playlist</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "Mostra sempre le schede"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "Mostra i conteggi"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "Mostra i bottoni di chiusura"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>Colonne di playlist</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "Mostra le intestazioni delle colonne"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Varie</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr "Tasti freccia cercano per:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "Fa avanzare la lista quando cambia brano"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "Interfaccia GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Bufferingâ¦"
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d canale"
msgstr[1] "%d canali"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Modalità singolo."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Modalità playlist."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "La riproduzione si fermerà alla fine del brano."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Traccia precedente"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Riproduci"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Interrompi/riprendi"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Ferma"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Traccia successiva"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "Avanza di 5 secondi"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "Riavvolgi di 5 secondi"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Silenzia"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Alza volume"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Abbassa volume"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Salta al file"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "Mostra/nascondi finestra(e) di riproduzione"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Mostra On-screen-display"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "Attiva/disattiva ripetizione"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "Attiva/disattiva shuffle"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "Attiva/Disattiva lo stop dopo la corrente"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Mostra finestra(e) di riproduzione"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(nessuno)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2079,15 +2175,11 @@ msgstr ""
"\n"
"Vuoi continuare?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Associazione pulsanti del mouse"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Configurazione plugin Tasti di scelta rapida globali"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2095,23 +2187,27 @@ msgstr ""
"Premi una combinazione di tasti all'interno di un campo di testo.\n"
"Puoi anche associare i pulsanti del mouse."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Tasti di scelta rapida:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Azione:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Tasto associato:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "_Aggiungi"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Hotkeys globali"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2138,60 +2234,58 @@ msgstr ""
"Jonathan A. Davis <davis at jdhouse.org>,\n"
"Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Hotkeys globali"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "Uscita JACK"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "Collegati a tutte le porte jack disponibili"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "Connetti automaticamente alle porte di uscita"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "Collega solo le porte in uscita"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr ""
+"Sono state rilevate solo le porte di uscita %d JACK ma sono richieste le %d."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "Non collegare alcuna porta"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Impossibile connettersi alla porta JACK %s"
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "Metodo di connessione:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+"JACK supporta solo audio con profondità di bit in virgola mobile. Si deve "
+"cambiare la codifica di uscita nelle impostazioni di Audacious, alla voce "
+"profondità di bit: virgola mobile."
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "Attiva l'output di debug"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "Impossibile connettersi al server JACK; è in esecuzione?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Basato su xmms-jack, da Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Converito per Audacious da Giacomo Lozito"
+"Il server JACK richiede una frequenza di campionamento pari a %d Hz mentre "
+"Audacious sta riproducendo a %d Hz. Si prega di usare l'effetto convertitore "
+"della frequenza di campionamento per correggere la discrepanza."
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "Uscita JACK"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "Impostazioni %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Impostazioni Host LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Percorsi dei moduli:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2202,73 +2296,41 @@ msgstr ""
"Dopo aver aggiunto nuovi percorsi, premi Invio per ricercare nuovi plugin.</"
"small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Plugin disponibili:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Abilita"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Plugin abilitati:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Impostazioni"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-"LADSPA Host per Audacious\n"
-"Copyright 2011 John Lindgren"
-
-#: src/ladspa/plugin.c:676
-msgid "LADSPA Host"
-msgstr "Host LADSPA"
-
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: non posso inizializzare il supporto LIRC\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: non posso leggere il file di configurazione LIRC\n"
-"%s: fare riferimento alla documentazione di LIRC\n"
-"%s: come creare un file di configurazione appropriato\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: tento la riconnessione...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: comando sconosciuto \"%s\"\n"
+"LADSPA Host per Audacious\n"
+"Copyright 2011 John Lindgren"
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: disconnesso da LIRC\n"
+#: src/ladspa/plugin.h:78
+msgid "LADSPA Host"
+msgstr "Host LADSPA"
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: tento la riconnessione ogni %d secondi...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Plugin LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2297,73 +2359,81 @@ msgstr ""
"\n"
"Per maggiori informazioni su LIRC, vedi http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Connessione</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Riconnetti al server LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Attesa prima della riconnessione:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Plugin LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "Plugin LyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Nessun testo disponibile"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Errore"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Impossibile recuperare %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Errore"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Impossibile analizzare %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Ricerca testi ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Metadata brano mancante"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Connessione a lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "Plugin LyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "Plugin LyricWiki (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "Playlists M3U"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Generatore Tact"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Metronomo: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Metronomo: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2378,11 +2448,11 @@ msgstr ""
"ad esempio tact://77 per avviare 77 battiti al minuto\n"
"o tact://60*3/4 per avviare 60 bpm in 3/4 tact"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Generatore Tact"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Mixer Canale"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2390,152 +2460,184 @@ msgstr ""
"Channel Mixer Plugin per Audaciousâ\n"
"Copyright 2011-2012 John Lindgren e MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Mixer Canale</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Canali in uscita:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Mixer Canale"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "Plugin MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "Impossibile connettersi al server MMS"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Riproduttore del Modulo)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>Risoluzione</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Canali</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "Più vicino (più veloce)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Lineare (veloce)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Spline (buono)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "Polifase (il migliore)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>Frequenza di Sampling</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr "<b>Frequenza di campionamento</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz:"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz:"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Livello:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "Taglio:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Riverbero</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>Aumento del Basso</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>Surround</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>Preamplificatore</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "Sovracampionamento"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Riduzione del rumore"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Avvia MOD Amiga"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Ripeti</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "Contatore di ripetizioni:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "Per ripetere per sempre, imposta il contatore di ripetizioni a -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Riproduttore del Modulo)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Surround"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "Queste impostazioni avranno effetto al prossimo riavvio di Audacious."
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "Plugin MPG123"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Opzioni avanzate</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Utilizza il calcolo della lunghezza accurata (lento)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "Server MPRIS 2"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Plugin Neon HTTP/HTTPS"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "Impossibile elaborare la ridirezione"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Errore HTTP sconosciuto"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "Impossibile elaborare l'URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Troppe ridirezioni"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Fermato"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious non sta riproducendo."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Notifiche Desktop"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2571,55 +2673,64 @@ msgstr ""
"Dovresti aver ricevuto una copia della licenza GNU General Public License "
"insieme al programma; se così non fosse, vedi <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Mostra controlli di riproduzione"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Permette di mostrare le notifiche"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Notifiche Desktop"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "Includi il nome dell'album nella notifica"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Mostra"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Interrompi"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Successivo"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Dispositivo predefinito"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "Uscita OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "Uscita OSS3"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Dispositivo predefinito"
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Dispositivo audio:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Usa dispositivo alternativo:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Mantieni volume tra le sessioni"
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Abilita conversioni di formato effettuate dal software OSS."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Abilita la modalità esclusiva per prevenire il missaggio virtuale."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2633,19 +2744,35 @@ msgstr ""
"Vorrei ringrazire le persone su #audacious, specialmente Tony Vroon e John "
"Lindgren e sicuramente gli autori del precedente OSS plugin."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "Uscita OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Gestore delle playlist"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Voci"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Rimuovi"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "Rin_omina"
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "Playlist PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "Decodificatore OpenPSF PSF1/PSF2"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "Uscita PulseAudio"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2682,11 +2809,73 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "Uscita PulseAudio"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "Uscita QtMultimedia"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"Plugin QtMultimedia Audio per Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Basato sul plugin SDL Output per Audacious\n"
+"Copyright 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "In elaborazione ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Cerca"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "Apri cartella ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_Aggiungi cartella ..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "_Ispettore dei log ..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Apri file"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Aggiungi file"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Precedente"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Ripeti"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Casuale"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Interfaccia Qt"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Convertitore Sample Rate"
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2694,99 +2883,107 @@ msgstr ""
"Sample Rate Converter Plugin per Audaciousâ\n"
"Copyright 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "Salta/ripeti gli esempi"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Interpolazione lineare"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Interpolazione di Shannon veloce"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "Interpolazione di Shannon media"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Interpolazione di Shannon migliore"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Conversione</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Metodo:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Frequenza:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Mappature della frequenza</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Usa le mappature della frequenza"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Convertitore Sample Rate"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "OK. Processo di scrobbling per l'utente: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "Permesso Negato."
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"Accedi al seguente link per permettere ad Audacious di eseguire lo "
"scrobbling dei tuoi avvii:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"Mantieni aperta questa finestra e clicca ancora su 'Controlla Permesso'.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2794,35 +2991,39 @@ msgstr ""
"Non preoccuparti. I tuoi scrobble sono stati salvati sul tuo computer.\n"
"Loro saranno inviati appena Audacious avrà il permesso di farlo."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "Problema di Rete."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
"C'era un problema nel contattare Last.fm. Per favore riprova più tardi."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "In controllo..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "C_ontrolla Permesso"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_Revoca Permesso"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"Hai bisogno di permettere ad Audacious di eseguire lo scrobbling delle "
"tracce al tuo account Last.fm.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2830,7 +3031,7 @@ msgstr ""
"Lo Scrobbler plugin non può essere avviato.\n"
"Ci potrebbe essere un problema con l'installazione."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2846,11 +3047,7 @@ msgstr ""
"\n"
"Grazie a John Lindgren per avermi dato una mano all'inizio del progetto.\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2859,7 +3056,11 @@ msgstr ""
"fm.\n"
"Per favore controlla le impostazioni per il plugin Scrobbler."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "Uscita SDL"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2867,81 +3068,56 @@ msgstr ""
"SDL Output Plugin per Audacious\n"
"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "Uscita SDL"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Libreria"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Artista sconosciuto"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Album sconosciuto"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s \n"
-" su %s di %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d risultato"
+msgstr[1] "%d risultati"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d album"
-msgstr[1] "%d album"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d nascosto)"
+msgstr[1] "(%d nascosti)"
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d canzone"
-msgstr[1] ""
-"%s\n"
-" %s, %d canzoni"
-
-#: src/search-tool/search-tool.c:639
-#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d canzoni di %s"
-msgstr[1] ""
-"%s\n"
-" %d canzoni di %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d canzone"
+msgstr[1] "%d canzoni"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "di questo genere"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "in funzione"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "di"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Crea playlist"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Aggiungi alla playlist"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Cerca nella libreria"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2949,679 +3125,771 @@ msgstr ""
"Per importare la tua musica in Audacious, scegli una cartella e clicca "
"sull'icona \"aggiorna\"."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Attendi per favoreâ¦"
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Scegli una cartella"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "Player SID"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>Uscita</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Canali:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Emulazione</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "Emula MOS 8580 (Predefinito: MOD 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "Non selezionare in automatico il modello del chip"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Emula il filtro"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Velocità del clock:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "Non selezionare in automatico la velocità del clock"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>Tempo di riproduzione</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "Imposta il tempo massimo di riproduzione:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Da usare quando la lunghezza della canzone è sconosciuta"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "Imposta il tempo minimo di riproduzione:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Bassi</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "Abilita i bassi"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "Ignora i bassi pù piccoli di:"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Nota</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Rimozione del silenzio"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"Plugin Silence Removal per Audacious\n"
+"Copyright 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Rimozione del silenzio</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Soglia:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "Apri files ..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "Apri URL ..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Cerca nella libreria"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Riproduzione"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Playlist"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Visualizza"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "Servizi"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "Informazioni ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "Impostazioni ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "Esci"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "Informazioni sul brano"
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Ripeti"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Casuale"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Non avanzare nella playlist"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "Interrompi al termine di questo brano"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Precedente"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "Setta ripetizione A-B"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "Elimina ripetizione A-B"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "Vai a brano ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "Vai a istante di tempo ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "Riproduci questa Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "Riproduci/Riparti"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Nuova playlist"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "Cambia nome a Playlist"
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "Elimina Playlist"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "Playlist precedente"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "Playlist successiva"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "Importazione Playlist ..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "Esportazione Playlist ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "Organizza Playlist ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "Organizza Coda ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "Aggiorna Playlist"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Mostra editor della playlist"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Mostra equalizzatore"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "Mostra tempo rimanente"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Sempre in primo piano"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "Su tutti gli spazi di lavoro"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "Arrotola il Player"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "Arrotola l'editor di Playlist"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "Arrotola l'equalizzatore"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Doppia grandezza"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "Aggiungi URL ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "Aggiungi files ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Per titolo"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Per nome del file"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr "Per nome File"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "Per percorso file"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Rimuovi tutti"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Cancella coda"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Rimuovi i file non disponibili"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Rimuovi i duplicati"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Rimuovi deselezionati"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Rimuovi selezionati"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Cerca e seleziona"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Inverti selezione"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Deseleziona tutti"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Seleziona tutti"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Per album"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Per numero di traccia"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Per artista"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Per album"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Per album artista"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "Per data di pubblicazione"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Per numero di traccia"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "Per Genere"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "Per Durata"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "Per titolo personalizzato"
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Riordina casualmente la lista"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Inverti lista"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Ordina selezionati"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Ordina lista"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Taglia"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Copia"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Incolla"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "Metti in/togli da coda"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "Carica predefiniti ..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "Carica predefiniti automatici ..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "Carica i default"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "Carica un file di predefiniti ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "Carica file EQF"
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "Salva predefiniti"
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "Salva predefiniti automatici"
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "Salva default"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "Salva file di predefiniti"
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "Salva file EQF"
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "Cancella predefiniti"
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "Cancella predefiniti automatici"
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "Importa i predefiniti di Winamp"
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "Resetta a zero"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Interfaccia classica di Winamp"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Salva"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Carica"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "Carica file di predefiniti"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "Carica file EQF"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "Salva file di predefiniti"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "Salva file EQF"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "Importa i predefiniti di Winamp"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Preimpostazioni"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Carica preimpostazione"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Carica preimpostazione a caricamento automatico"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Salva preimpostazione"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Salva preimpostazione a caricamento automatico"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Elimina preimpostazione"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Elimina preimpostazione a caricamento automatico"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Lettore:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Lettore:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Seleziona il carattere della finestra principale del lettore:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Playlist:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Playlist:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Seleziona il carattere della playlist:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>Pelle</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>Caratteri</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Usa caratteri bitmap (supporta solo ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "Fai sfilare il titolo del brano"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Scorri titolo brano in entrambe le direzioni"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analizzatore"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Oscilloscopio"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "Impronta vocale/VU meter"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Spento"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normale"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Fuoco"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "Linee verticali"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Linee"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Barre"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Molto lenta"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Lenta"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Media"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Veloce"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Molto veloce"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "Puntini"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "Linea"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "Solido"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Ghiaccio"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Morbida"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>Scrivi</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "Tipo di visualizzazione:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>Analizzatore</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "Mostra picchi"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "Colori:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "Stile:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "Decadimento:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "Decadimento dei picchi:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "Stile di oscilloscopio:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "Colori dell'impronta vocale:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "Stile del VU meter:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Generale"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualizzazione"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Preamplificazione"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Equalizzatore di Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Vai a %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Volume: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Bilanciamento: sinistra %d%%"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Bilanciamento: centro"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Bilanciamento: destra %d%%"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Menu opzioni"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Disabilita 'Sempre in primo piano'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Abilita 'Sempre in primo piano'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Finestra informazioni file"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "Visualizzazioni"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "Punto di Ripetizione _A impostato"
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "Punto di Ripetizione _B impostato"
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "Punti di Ripetizione Cancellati"
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Modalità singolo."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Modalità playlist."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "La riproduzione si fermerà alla fine del brano."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Cerca elementi nella playlist attiva"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "Cerca"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3633,57 +3901,61 @@ msgstr ""
"maiuscole e minuscole. Se non sai come funzionano le espressioni regolari, "
"inserisci semplicemente una porzione letterale di quello che stai cercando."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Titolo: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr "Titolo:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr "Album:"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Artista: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr "Artista:"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Nome del file: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Nome del file:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Cancella la selezione precedente prima di effettuare la ricerca"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Inserisci automaticamente in coda gli elementi trovati"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Crea una nuova playlist con gli elementi trovati"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Editor della playlist di Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d di %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Skin Winamp 2.x archiviata"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Skin Winamp 2.x non archiviata"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Impossibile creare la directory (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Plugin Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3724,83 +3996,74 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, "
"USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Plugin Sndfile"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Informazioni sul plugin Sndio Output"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Uscita Sndio"
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Plugin Sndio Output\n"
-"\n"
-"Scritto da Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "Dispositivo (lasciare vuoto per usare quello predefinito):"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Formato non supportato"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Salva e ripristina il volume:"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"E' stato richiesto un formato non supportato dal dispositivo audio.\n"
-"\n"
-"Per favore, riprova con il server sndiod(1) attivato."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Errore Sndio: Formato audio non supportato (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "dispositivo sndio"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Errore Sndio: sio_open() fallito"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(vuoto significa default)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Errore Sndio: sio_setpar() fallito"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Errore Sndio: sio_start() fallito"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Cambio brano"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Comando da eseguire quando Audacious inizia un nuovo brano."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>I parametri passati alla shell dovrebbero essere "
+"racchiusi tra virgolette. Fare diversamente costituisce un rischio per la "
+"sicurezza.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Comandi</b>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Comando:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Comando da lanciare quando si avvia una nuova canzone:"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Comando da eseguire alla fine del brano."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Comando da lanciare al termine di una canzone:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "Comando da eseguire quando Audacious raggiunge la fine della playlist."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Comando da lanciare alla fine di una playlist:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Comando da eseguire quando cambia il titolo del brano (titoli degli stream "
-"di rete)."
+"Comando da lanciare quando cambia il titolo di una canzone (per gli stream "
+"in rete):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3814,36 +4077,31 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Puoi usare il seguente formato stringa che\n"
-"sarà sostituito prima di chiamare il comando\n"
-"(non tutti sono utili per il comando fine-playlist):\n"
+"Si possono usare i seguenti formati che verranno sostituiti prima di "
+"chiamare il comando (non tutti sono utili per il comando eseguibile alla "
+"fine della playlist):\n"
"\n"
"%F: Frequenza (in hertz)\n"
"%c: Numero di canali\n"
-"%f: Nome file (full path)\n"
-"%l: Durata (in milliseconds)\n"
-"%n o %s: Nome Brano\n"
-"%r: Rate (in bits per secondi)\n"
-"%t: Posizione playlist (%02d)\n"
-"%p: In riproduzione (1 o 0)\n"
+"%f: Nome del file (path completo)\n"
+"%l: Lunghezza (in millisecondi)\n"
+"%n o %s: Nome della canzone\n"
+"%r: Rapporto (in bits al secondo)\n"
+"%t: Posizione nella playlist (%02d)\n"
+"%p: Attualmente in esecuzione (1 or 0)\n"
"%a: Artista\n"
"%b: Album\n"
-"%T: Nome brano"
+"%T: Titolo del brano"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>I parametri passati alla shell dovrebbero essere "
-"racchiusi tra virgolette. Fare diversamente costituisce un rischio per la "
-"sicurezza.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Informazioni sul brano (Qt)"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Comandi"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX Resampler"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3857,51 +4115,51 @@ msgstr ""
"Basato sul Plugin Sample Rate Converter:\n"
"Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Veloce"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Basso"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Alto"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Molto Alto"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Qualità :"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Velocità e Tono"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Velocità e Tono</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Velocità : "
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Tono:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Velocità e Tono"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Icona di stato"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "Impostazioni ..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3919,39 +4177,39 @@ msgstr ""
"Questo plugin fornisce un'icona di stato, posizionata nell'\n"
"area di notifica del gestore delle finestre di sistema."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "Azione Scroll Mouse"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Cambia volume"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Cambia brano in riproduzione"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Altre impostazioni</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Disabilita la finestra popup"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Chiudi nell'area di notifica (system tray)"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Avanza nella playlist quando si scorre verso l'alto"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Icona di stato"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Stereo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3961,24 +4219,24 @@ msgstr ""
"\n"
"Realizzato da Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra Stereo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Generatore di toni"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Generatore di toni: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3993,15 +4251,11 @@ msgstr ""
"ad esempio tone://2000;2005 per avviare un tono di 2000 Hz e un tono di 2005 "
"Hz"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Generatore di toni"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Rimozione voce"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4039,11 +4293,46 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Decodificatore Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Dettagli su %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"Titolo: %t\n"
+"Autore: %a\n"
+"Da: %f\n"
+"Tracker: %T\n"
+"Commento: %C\n"
+"Tipo di chip: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Freq. del chip: %F\n"
+"Freq. player: %P\n"
+"Anno: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "Decodificatore VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4054,19 +4343,19 @@ msgstr ""
"Basato su in_vtx.dll realizzato da Roman Sherbakov <v_soft at microfor.ru>\n"
"Plugin Audacious realizzato da Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "Decodificatore VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "Decodificatore WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "senza perdita (ibrido)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "con perdita"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4076,14 +4365,18 @@ msgstr ""
"\n"
"Una parte del codice del plugin era di Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "Decodificatore WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "Decodificatore 2SF"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>Configurazione XSF</b>"
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Ignora la lunghezza dal file"
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "Liste di riproduzione condivisibili XML (XSPF)"
diff --git a/po/ja.po b/po/ja.po
index cf3ef9300956..72c4f6682840 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -3,20 +3,21 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# natird <dritan86 at gmail.com>, 2012
-# uÇsıɯoÊ(èªã¿å°) <hallconnen2+transifex at gmail.com>, 2013
-# uÇsıɯoÊ(èªã¿å°) <hallconnen2+transifex at gmail.com>, 2012
-# Shuuji TAKAHASHI <shuuji3 at gmail.com>, 2012-2014
+# natird zoto <dritan86 at gmail.com>, 2012
+# ABE Tsunehiko, 2013
+# ABE Tsunehiko, 2012
+# Mika Kobayashi, 2014-2015
+# Shuuji Takahashi <shuuji3 at gmail.com>, 2012-2014
# Warui-chan <>, 2012
-# uÇsıɯoÊ(èªã¿å°) <hallconnen2+transifex at gmail.com>, 2012
-# uÇsıɯoÊ(èªã¿å°) <hallconnen2+transifex at gmail.com>, 2013
+# ABE Tsunehiko, 2012
+# ABE Tsunehiko, 2013
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-20 17:34+0000\n"
+"Last-Translator: Mika Kobayashi\n"
"Language-Team: Japanese (http://www.transifex.com/projects/p/audacious/"
"language/ja/)\n"
"Language: ja\n"
@@ -25,40 +26,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "ã¢ãã©ã«"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "ã¹ãã¬ãª"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "ãµã©ã¦ã³ã"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "AAC (MP4) ãã³ã¼ã"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "AAC (Raw) ãã³ã¼ã"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib ãã¬ã¤ã¤ã¼)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "ã·ã¼ã±ã³ã¹"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib ãã¬ã¤ã¤ã¼)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "ã¢ã©ã¼ã "
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "ã¢ã©ã¼ã ãã»ãã"
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -66,13 +55,9 @@ msgid ""
msgstr ""
"è¨å®ããæéã«åçãéå§ããããã®ãã©ã°ã¤ã³\n"
"\n"
-"Originally written by Adam Feakin and Daniel Stodden."
-
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "ã¢ã©ã¼ã "
+"å
ã®ä½è
: Adam Feakin ããã³ Daniel Stodden"
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -94,8 +79,25 @@ msgid ""
"\n"
"\n"
msgstr ""
+"æå»\n"
+" ã¢ã©ã¼ã æå»:\n"
+" ã¢ã©ã¼ã ãé³´ãæå»ã\n"
+"\n"
+" éãã«ãªãã¾ã§ã®æé:\n"
+" ãã®æéãéããã¨ã¢ã©ã¼ã ãæ¢ã¾ãã¾ãã\n"
+" (ç®è¦ã¾ããã¤ã¢ãã°ãéããªãã£ãå ´å)\n"
+"\n"
+"ææ¥\n"
+" ææ¥:\n"
+" ã¢ã©ã¼ã ãæå¹ã«ããææ¥ãæå®ãã¾ãã\n"
+"\n"
+" æå»:\n"
+" ãã®ææ¥ã®ã¢ã©ã¼ã ãé³´ããæå»ãæå®ãããã\n"
+" ãã¿ã³ã«ãã§ãã¯ãã¦ããã©ã«ããæå®ãã¾ãã\n"
+"\n"
+"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -133,7 +135,7 @@ msgstr ""
" ã¢ã©ã¼ã ã®æå»ã«ãã®ã³ãã³ããå®è¡ãã¾ãã\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -157,384 +159,390 @@ msgstr ""
" 表示ããå ´åã«ã¯ãããã¹ãããã¯ã¹ã«ãªãã¤ã³ããå
¥åãã\n"
" ãã°ã«ãã¿ã³ããªã³ã«ãã¦ãã ããã"
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "ç®è¦ã¾ãã§ãã"
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "仿¥ã®ãªãã¤ã³ã:"
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "ãªãã¤ã³ã"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "æææ¥"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "ç«ææ¥"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "æ°´ææ¥"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "æ¨ææ¥"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "éææ¥"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "åææ¥"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "æ¥ææ¥"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "ã¢ã©ã¼ã ã®è¨å®"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "OK (_O)"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "ãã£ã³ã»ã« (_C)"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "æå»"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "ã¢ã©ã¼ã æå» (ããã©ã«ã)"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr " "
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "éãã«ãªãã¾ã§ã®æé:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "æé"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "å"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "ã¢ã©ã¼ã ãé³´ãææ¥ãé¸ãã§ãã ãã"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
-msgstr "æ¥"
+msgstr "ææ¥"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "ããã©ã«ã"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
-msgstr "æ¥"
+msgstr "ææ¥"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "ãã§ã¼ã"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "ç§"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "é³é"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "ãã§ã¼ãéå§é³é"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "ãã§ã¼ãçµäºé³é"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "ç¾å¨ã®é³é"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "追å ã³ãã³ã"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "æå¹"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "ãã¬ã¤ãªã¹ã (ãªãã·ã§ã³)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "ãã¬ã¤ãªã¹ãã鏿"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "ãªãã·ã§ã³"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "ãªãã·ã§ã³ã®èª¬æ"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "ãã«ã"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "ã¢ã«ãã ã¢ã¼ã"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "ã¢ã«ãã ã¢ã¼ã (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA åºå"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ALSA åºåãã©ã°ã¤ã³ for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"ALSA åºåãã©ã°ã¤ã³ NG ã®ä½è
William Pitcock ã«æè¬ãã¾ããALSA ã®ããã¥ã¢ã«"
+"ã§ã¯ä¸ååãªæã«åèã«ããã¦ãããã¾ããã"
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(説æãªã)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "ããã©ã«ã PCM ããã¤ã¹"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "ããã©ã«ããããµããã¤ã¹"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM ããã¤ã¹:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "ãããµããã¤ã¹:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "ãããµã¨ã¬ã¡ã³ã"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Work around drain hangup"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI ãã¬ã¤ã¤ã¼)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"ALSA åºåãã©ã°ã¤ã³ for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"ã¢ã¸ã¥ã©ã¼ MIDI 鳿¥½ãã¬ã¤ã¤\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"ALSA åºåãã©ã°ã¤ã³ NG ã®ä½è
William Pitcock ã«æè¬ãã¾ããALSA ã®ããã¥ã¢ã«"
-"ã§ã¯ä¸ååãªæã«åèã«ããã¦ãããã¾ããã"
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA åºå"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI ãã¬ã¤ã¤ã¼)"
+"ä½è
: Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"ã¹ãã·ã£ã«ãµã³ã¯ã¹...\n"
+"\n"
+"Clemens Ladisch ããã³ Jaroslav Kysela\n"
+"ï¼å½¼ãã®åµã£ãç´ æ´ãããããã°ã©ã aplaymidi amixerã«ã¤ãã¦ã\n"
+"å®ã«ä¾¿å©ã§ãalsa-lib ã®ææ¸ã«æ²¿ã£ã¦ããã\n"
+"ALSA API ã®ç¿å¾ã«é©ã£ã¦ããï¼\n"
+"\n"
+"Alfredo Spadafina\n"
+"ï¼å½¼ã®ãç´ æµãª MIDI ãã¼ãã¼ãã®ãã´ã«ã¤ãã¦ï¼\n"
+"\n"
+"Tony Vroon\n"
+"ï¼ã¢ã«ãã¡ãã¹ãæã«ã¨ã¦ãããæä¼ã£ã¦ãããï¼"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "ããã©ã«ãã®ã²ã¤ã³ã䏿¸ã:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "ããã©ã«ãã®ããªãã©ãã¼ã䏿¸ã:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "ããã©ã«ãã®ãªãã¼ãã䏿¸ã:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
-msgstr ""
+msgstr "ãªã³"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "ããã©ã«ãã®ã³ã¼ã©ã¹ã䏿¸ã:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>åç</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "ãã©ã³ã¹ãã¼ãº: "
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "åé³"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "ãã©ã ã·ãã: "
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "ãã¼ããã³ãã¼"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "MIDI ãã¡ã¤ã«ããã³ã¡ã³ããæ½åºãã"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "å
è¡ããç¡é³ãã¹ããã"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "MIDI ãã¡ã¤ã«ããæè©ãæ½åºãã"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "å¾è¡ããç¡é³ãã¹ããã"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>ãµã¦ã³ããã©ã³ã</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>ã·ã³ã»ãµã¤ã¶ã¼</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr "ãªãµã³ããªã³ã°ã¬ã¼ã:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "ãµã³ããªã³ã°ã¬ã¼ã:"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - ãµã¦ã³ããã©ã³ã ãã¡ã¤ã«ã®é¸æ"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "ãã£ã³ã»ã« (_C)"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "éã (_O)"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "ãã¡ã¤ã«å"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "ãµã¤ãº (ãã¤ã)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "åå:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI æ
å ± </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "å½¢å¼:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "é·ã (ããªç§):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "ãã©ãã¯æ°:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "å¯å¤"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "æé軸:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI ã³ã¡ã³ãã¨æè© </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* MIDI ãã¡ã¤ã«ä¸ã«æå¹ãªã³ã¡ã³ããããã¾ãã *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* MIDI ãã¡ã¤ã«ä¸ã«æå¹ãªæè©ãããã¾ãã *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "ãã¬ã¤ãªã¹ããéãã(_C)"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (䏿£ãª UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "AMIDI-Plug ã«ã¤ãã¦"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"modular MIDI 鳿¥½ãã¬ã¤ã¤\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"ã¹ãã·ã£ã«ãµã³ã¯ã¹\n"
-"\n"
-"Clemens Ladisch 㨠Jaroslav Kysela\n"
-"å½¼ãã®ä½ã£ã aplaymidi ã¨amixer ã¨ããç´ æ´ãããããã°ã©ã ã¯ã\n"
-"ALSA API ã«ã¤ãã¦ç¥ãããã«ãalsa-lib ã®ããã¥ã¡ã³ãã¨ã¨ãã«ã大å¤å½¹ã«ç«ã¡ã¾"
-"ããã\n"
-"\n"
-"Alfredo Spadafina\n"
-"ç´ æµãª midi ãã¼ãã¼ãã®ãã´ãä½ã£ã¦ããã¾ããã\n"
-"\n"
-"Tony Vroon\n"
-"ã¢ã«ãã¡ãã¹ãã§å¤§å¤å©ãã¦ãããã¾ããã"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -544,152 +552,155 @@ msgid ""
"Based in part on Evan Martin's Ghosd library:\n"
"http://neugierig.org/software/ghosd/"
msgstr ""
+"Audacious OSD\n"
+"http://www.develia.org/projects.php?p=audacious#aosd\n"
+"\n"
+"ä½è
Giacomo Lozito <james at develia.org>\n"
+"\n"
+"Evan Martin ä½ã® Ghosd ã©ã¤ãã©ãªã«ä¸é¨ãåºã¥ã:\n"
+"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (On-Screen Display)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ç©å½¢"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "è§ä¸¸ç©å½¢"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "å¹ç©å½¢"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "ãªã"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "åçéå§"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "ãã¬ã¤ãªã¹ãã®æ²ãåçãããã¨ãã« OSD ã表示ãã¾ãã"
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "ã¿ã¤ãã«å¤æ´"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"åçä¸ã«ããã¡ã¤ã«åãåãã§ããæ²ã®ã¿ã¤ãã«ã夿´ãããã¨ãã« OSD ã表示ãã¾"
-"ããããã¯ãã¤ã³ã¿ã¼ãããã¹ããªã¼ã ã®ã¿ã¤ãã«å¤æ´ã表示ããã®ã«ä¾¿å©ã§ãã"
+"æ²ã¿ã¤ãã«ãæ¿ãã£ããOSDãçºåããã (ã¤ã³ã¿ã¼ãããã¹ããªã¼ãã³ã°ç¨)ã"
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "䏿忢"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "åçã忢ããã¨ãã« OSD ã表示ãã¾ãã"
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "åçã®åé"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "åçãåéããã¨ãã« OSD ã表示ãã¾ãã"
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "ä½ç½®"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "ç¸å¯¾ X ãªãã»ãã:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "ç¸å¯¾ Y ãªãã»ãã:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "æå¤§ OSD å¹
:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "ãã«ãã¢ãã¿ ãªãã·ã§ã³"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "OSD ã表示ããã¢ãã¿:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "å
¨ã¦ã®ã¢ãã¿"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "ã¢ãã¿ %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "ã¿ã¤ãã³ã° (ããªç§)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "表示:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "ãã§ã¼ãã¤ã³:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "ãã§ã¼ãã¢ã¦ã:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "ãã©ã³ã"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "ãã©ã³ã %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "å½±"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "æç»å½¢å¼"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "è²"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "è² %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "ããªã¬ã¼æå¹"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "ã¤ãã³ã"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Composite ããã¼ã¸ã£ãæ¤åºããã¾ãã"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -699,112 +710,112 @@ msgstr ""
"åä½ããã¦ãããããããªããã°, Composite ããã¼ã¸ã£ãæå¹ã«ãã¦ãã ãã. ã"
"ãããªããã° OSD ã¯æ£å¸¸ã«åä½ããªãã§ããã."
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Composite ããã¼ã¸ã£ã¯å½ã®éæåã«ã¯å¿
è¦ã§ã¯ããã¾ãã"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "éæå"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "å½ã®éæå"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "çã®éæå (X Composite æ¡å¼µãå¿
è¦)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Composite æ¡å¼µãèªã¿è¾¼ã¾ãã¦ãã¾ãã"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Composite æ¡å¼µãæå¹ã§ã¯ããã¾ãã"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - è¨å®"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "ãã¹ã (_T)"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "è¨å® (_S)"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "ä½ç½®"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "ã¢ãã¡ã¼ã·ã§ã³"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "æå"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "è£
飾"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "ããªã¬ã¼"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "ãã®ä»"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "ãã¹ã"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "ASXv3 ãã¬ã¤ãªã¹ã"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 ãã¬ã¤ãªã¹ã"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious ãã¬ã¤ãªã¹ã (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>è²</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "ãã©ã¼ã»ã¹ã³ã¼ã"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "ãã¦ã¢ã¼ ã¹ãã¬ãª-ãã¤ãã¼ã©ã«å¤æ (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "ããªã»ãã:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "ãã§ã¼ãã¬ãã«:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Cut 卿³¢æ°"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "ããªã»ãã:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "ãã¦ã¢ã¼ ã¹ãã¬ãª-ãã¤ãã¼ã©ã«å¤æ (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "ã¹ãã¯ãã©ã ã¢ãã©ã¤ã¶"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "ãªã¼ãã£ãª CD ãã©ã°ã¤ã³"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -825,172 +836,159 @@ msgstr ""
"\n"
"ãã®ãã©ã°ã¤ã³ã¯ãGoogle Summer of Code 2007 ã®ããã¸ã§ã¯ãã§ãã"
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>ããã¤ã¹</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "èªã¿è¾¼ã¿é度:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "䏿¸ãããã¤ã¹"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>ã¡ã¿ãã¼ã¿</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "CD-Text ã使ç¨ãã"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "CDDB ã使ç¨ãã"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "CDDBP ã®ä»£ããã« HTTP ã使ã"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "ãµã¼ãã¼:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "ãã¹:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "ãã¼ã:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "ãªã¼ãã£ãª CD ãã©ã°ã¤ã³"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "cdio ãµãã·ã¹ãã ã®åæåã«å¤±æãã¾ããã"
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "次㮠URI ã¯ç¡å¹ã§ãã%s"
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "ãã©ã㯠%d ãè¦ã¤ããã¾ããã"
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "ãã©ã㯠%d ã¯ãã¼ã¿ãã©ãã¯ã§ãã"
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "ãªã¼ãã£ãªåºåã®ãªã¼ãã³ã«å¤±æãã¾ããã"
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr " ãªã¼ãã£ãªCDã®èªã¿è¾¼ã¿ã§ã¨ã©ã¼ãçºçãã¾ããã"
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "ãªã¼ãã£ãª CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "ãã©ã㯠%d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "CDããã¤ã¹ %s ã®ãªã¼ãã³ã«å¤±æãã¾ããã"
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "ãªã¼ãã£ãªãå©ç¨å¯è½ãªCDãã©ã¤ããè¦ã¤ããã¾ããã"
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "ãªã¼ãã³ãããCDãã©ã¤ãã®åæåãå®äºã§ãã¾ããã§ããã"
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "æåã¾ãã¯æå¾ã®ãã©ãã¯ãã³ããåå¾ã§ãã¾ããã§ããã"
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
"ãã©ã㯠%d ã® LSN(è«çã»ã¯ã¿çªå·) ã®éå§ã¾ãã¯çµäºãèªã¿åãã¾ããã§ããã"
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "cddb ã³ãã¯ã·ã§ã³ã®ä½æã«å¤±æãã¾ããã"
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "CDDB ãµã¼ãã¸ã®ã¯ã¨ãªã«å¤±æãã¾ããã"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "CDDB ãµã¼ãã¸ã®ã¯ã¨ãªã«å¤±æãã¾ãã: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "cddb æ
å ±ã®èªã¿åãã«å¤±æãã¾ãã: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "ãã©ã¤ãã«ãã£ã¹ã¯ãããã¾ããã"
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "é対å¿ã®ãã£ã¹ã¯ã§ãã"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "ãªã¼ãã£ãª CD ã¡ãã¥ã¼é
ç®"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "CD ãåç"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "ãã¬ã¤ãªã¹ãã« CD ã追å "
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "ãªã¼ãã£ãª CD ã¡ãã¥ã¼é
ç®"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>ã³ã³ãã¬ãã·ã§ã³</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "ã»ã³ã¿ã¼é³é:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "ãã¤ãããã¯ã¬ã³ã¸:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"ãã¤ãããã¯ã¬ã³ã¸å§ç¸®ãã©ã°ã¤ã³ for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "ãã¤ãããã¯ã¬ã³ã¸ã³ã³ãã¬ããµ"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1006,207 +1004,239 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ãã¼ã¹:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "ããªãã«:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "ã¨ã³ã¼:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "ããã©ã«ãã®æ²ã®é·ã:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>ãªãµã³ããªã³ã°</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "ãªã¼ãã£ãªãªãµã³ããªã³ã°ãæå¹ã«ãã"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "ãªãµã³ããªã³ã°ã¬ã¼ã:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "SPC ã¿ã°ããã®é·ããç¡è¦ãã"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "ãªãã¼ããå¢ãã"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "ã²ã¼ã ã³ã³ã½ã¼ã«é³æ¥½ãã³ã¼ã"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"æ²ã®ãã£ã³ãã«æ°ãç°ãªããããã¯ãã¹ãã§ã¼ãã失æãã¾ããã\n"
-"æ²ãåããã£ã³ãã«æ°ã«ããããã«ã¯ããã£ã³ãã«ãããµãå©ç¨ã§ãã¾ãã"
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "CoreAudio åºå"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"æ²ã®ãµã³ããªã³ã°å¨æ³¢æ°ãç°ãªããããã¯ãã¹ãã§ã¼ãã失æãã¾ããã\n"
-"æ²ãåããµã³ããªã³ã°å¨æ³¢æ°ã«ããããã«ããµã³ããªã³ã°å¨æ³¢æ°ãããµãå©ç¨ã§ãã¾"
-"ãã"
+"CoreAudio åºåãã©ã°ã¤ã³ for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"æ´¾çå
: SDL åºåãã©ã°ã¤ã³ for Audacious\n"
+"Copyright 2010 John Lindgren"
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "æä»ã¢ã¼ããç¨ãã"
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"ã¯ãã¹ãã§ã¼ããã©ã°ã¤ã³ for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>ã¯ãã¹ãã§ã¼ã</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "æ²ãèªåçã«æ¿ãã£ãã¨ã"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "ãªã¼ãã¼ã©ãã:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "ã·ã¼ã¯ãä»»æã«æ²ãæ¿ããã¨ã"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>åè</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+"ãã广çãªã¯ãã¹ãã§ã¼ããå®ç¾ããã«ã¯\n"
+"ç¡é³é¨ã®é¤å»ãã©ã°ã¤ã³ãæå¹ã«"
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "ã¯ãã¹ãã§ã¼ã"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"æ²ã®ãã£ã³ãã«æ°ãç°ãªããããã¯ãã¹ãã§ã¼ãã失æãã¾ããã\n"
+"æ²ãåããã£ã³ãã«æ°ã«ããããã«ã¯ããã£ã³ãã«ãããµãå©ç¨ã§ãã¾ãã"
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"æ²ã®ãµã³ããªã³ã°å¨æ³¢æ°ãç°ãªããããã¯ãã¹ãã§ã¼ãã失æãã¾ããã\n"
+"æ²ãåããµã³ããªã³ã°å¨æ³¢æ°ã«ããããã«ããµã³ããªã³ã°å¨æ³¢æ°ãããµãå©ç¨ã§ãã¾"
+"ãã"
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>ã¯ãªã¹ã¿ã©ã¤ã¶</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "æãã:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "ã¯ãªã¹ã¿ã©ã¤ã¶"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Cue ã·ã¼ããã©ã°ã¤ã³"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "ãã¡ã¤ã«ã®åé¤"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "%s ãã´ãç®±ã«ç§»åä¸ã«æ¬¡ã®ã¨ã©ã¼ãçºçãã¾ããã%sã"
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "%s ã®åé¤ä¸ã«æ¬¡ã®ã¨ã©ã¼ãçºçãã¾ããã%sã"
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
"%s ã®åé¤ä¸ã«æ¬¡ã®ã¨ã©ã¼ãçºçãã¾ããããã¼ã«ã«ãªãã¡ã¤ã«ã§ã¯ããã¾ããã"
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "鏿ãããã¡ã¤ã«ãã´ãç®±ã«ç§»åãã¾ããï¼"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "ã´ãç®±ã«ç§»åãã"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "鏿ãããã¡ã¤ã«ãå®å
¨ã«åé¤ãã¾ããï¼"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "åé¤"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "ãã£ã³ã»ã«"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "ãã¡ã¤ã«ã®åé¤"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "鏿ãããã¡ã¤ã«ã®åé¤"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>åé¤ã®æ¹æ³</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "䏿çã«åé¤ãããããã«ã´ãç®±ã«ç§»å"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+"ã¨ã³ã¼ãã©ã°ã¤ã³\n"
+"By Johan Levin, 1999\n"
+"ãµã©ã¦ã³ãã¨ã³ã¼ by Carl van Schaik, 1999\n"
+"Audaciousç¨ã«æ´æ° by William Pitcock and John Lindgren, 2010-2014"
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>ã¨ã³ã¼</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "é
å»¶:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "ãã£ã¼ãããã¯:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "é³é:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"ã¨ã³ã¼ãã©ã°ã¤ã³\n"
-"By Johan Levin, 1999\n"
-"\n"
-"ãµã©ã¦ã³ãã¨ã³ã¼ by Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "ã¨ã³ã¼"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg ãã©ã°ã¤ã³"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1222,55 +1252,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg ãã©ã°ã¤ã³"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "ãã¡ã¤ã«åºåãã©ã°ã¤ã³"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "åºåãã¡ã¤ã«ãã©ã¼ããã:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "è¨å®"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "å
ã®ãã£ã¬ã¯ããªã«ä¿åãã"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "æå®ã®ãã£ã¬ã¯ããªã«ä¿åãã"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "ãã¡ã¤ã«åºåå
ãã£ã¬ã¯ããª:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "ãã£ã¬ã¯ããªã®é¸æ"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "ãã¡ã¤ã«åã®åå¾å
:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "ãã¡ã¤ã«ãã¼ã ãæ¬¡ããçæ:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "å
ã®ãã¡ã¤ã«ã®ã¿ã°"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "å
ã®ãã¡ã¤ã«ã¿ã°"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
msgstr "å
ã®ãã¡ã¤ã«å"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "ãã¡ã¤ã«åããæ¡å¼µåãåãé¤ããªã"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "å
ã®ãã¡ã¤ã«æ¡å¼µåãå«ãã"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "ãã¡ã¤ã«åã®å
é ã«ãã©ãã¯çªå·ãä»å ãã"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr "ãã¡ã¤ã«åã®åã«ãã©ãã¯çªå·ãä»ãã"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1287,180 +1317,183 @@ msgid ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
msgstr ""
-"This program is free software; you can redistribute it and/or modify\n"
-"it under the terms of the GNU General Public License as published by\n"
-"the Free Software Foundation; either version 2 of the License, or\n"
-"(at your option) any later version.\n"
-"\n"
-"This program is distributed in the hope that it will be useful,\n"
-"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
-"GNU General Public License for more details.\n"
+"ãã®ããã°ã©ã ã¯ããªã¼ã½ããã¦ã§ã¢ã§ããããªãã¯ãããã\n"
+"ããªã¼ã½ããã¦ã§ã¢è²¡å£ã«ãã£ã¦çºè¡ããã GNU ä¸è¬å
¬è¡å©ç¨è¨±è«¾å¥ç´æ¸\n"
+"(ãã¼ã¸ã§ã³2ãã叿ã«ãã£ã¦ã¯ãã以éã®ãã¼ã¸ã§ã³ã®ãã¡ã©ãã)ã®\n"
+"å®ããæ¡ä»¶ã®ä¸ã§åé å¸ã¾ãã¯æ¹å¤ãããã¨ãã§ãã¾ãã\n"
"\n"
-"You should have received a copy of the GNU General Public License\n"
-"along with this program; if not, write to the Free Software\n"
-"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
-"USA."
-
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "ãã¡ã¤ã«åºåãã©ã°ã¤ã³"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+"ãã®ããã°ã©ã ã¯æç¨ã§ãããã¨ãé¡ã£ã¦é å¸ããã¾ããã*å
¨ãã®ç¡ä¿è¨¼* \n"
+"ã§ãã忥å¯è½æ§ã®ä¿è¨¼ãç¹å®ã®ç®çã¸ã®é©åæ§ã¯ãè¨å¤ã«ç¤ºããããã®ã\n"
+"å«ãå
¨ãåå¨ãã¾ããã詳ããã¯GNU ä¸è¬å
¬è¡å©ç¨è¨±è«¾å¥ç´æ¸ãã覧ãã ããã\n"
+" \n"
+"ããªãã¯ãã®ããã°ã©ã ã¨å
±ã«ãGNU ä¸è¬å
¬è¡å©ç¨è¨±è«¾å¥ç´æ¸ã®è¤è£½ç©ã\n"
+"ï¼é¨åãåã£ãã¯ãã§ããããåãåã£ã¦ããªããã°ãããªã¼ã½ããã¦ã§ã¢è²¡å£\n"
+"ã¾ã§è«æ±ãã¦ãã ãã(å®å
㯠the Free Software Foundation, Inc., \n"
+"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA)ã"
+
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "èªå"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "ã¸ã§ã¤ã³ãã¹ãã¬ãª"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "ã¹ãã¬ãª"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "ã¢ãã©ã«"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 è¨å®"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "OK (_O)"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "ã¢ã«ã´ãªãºã å質:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
msgstr "åºåãµã³ããªã³ã°ã¬ã¼ã:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
msgstr "ãããã¬ã¼ã / å§ç¸®ç:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ãããã¬ã¼ã (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "å§ç¸®ç:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "ãªã¼ãã£ãª ã¢ã¼ã:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "ãã®ä»:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "峿 ¼ãª ISO éµå®ãå¼·å¶ãã"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr "å³å¯ãªISOé©åãå¼·å¶"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "ã¨ã©ã¼ä¿è·"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "é³è³ª"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "VBR/ABR ãæå¹ã«ãã"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "ã¿ã¤ã:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR ãªãã·ã§ã³:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "æå°ãããã¬ã¼ã (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "æå¤§ãããã¬ã¼ã (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "æå°ãããã¬ã¼ãã峿 ¼ã«å¼·å¶ãã"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR ãªãã·ã§ã³:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "å¹³åãããã¬ã¼ã (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR å質ã¬ãã«:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Xing VBR ããããæ¸ãè¾¼ã¾ãªã"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Xing VBR ããããé¤ã"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "ãã¬ã¼ã ãã©ã¡ã¼ã¿"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr "ãã¬ã¼ã ãã©ã¡ã¼ã¿:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "è使¨©ç©ã¨ãã¦ãã¼ã¯"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "ãªãªã¸ãã«ã¨ãã¦ãã¼ã¯"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "ID3 ãã©ã¡ã¼ã¿:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "ãã¼ã¸ã§ã³ 2 ã¿ã°ãå¼·å¶çã«ä»å ãã"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "v1 ã¿ã°ã®ã¿ä»å ãã"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "v2 ã¿ã°ã®ã¿ä»å ãã"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "ã¿ã°"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis ã¨ã³ã³ã¼ãè¨å®"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "å質ã¬ãã« (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC ãã³ã¼ã"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "å¯é"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1472,11 +1505,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC ãã³ã¼ã"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1484,11 +1513,19 @@ msgstr ""
"GIO ãã©ã°ã¤ã³ for Audacious\n"
"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO ãã©ã°ã¤ã³"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "ãªã¼ãã¢ã³ãã¢ãã³ãã¢ã¼ãã«ã¯å¯¾å¿ãã¦ãã¾ãã"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "ç¡å¹ãªãªã¼ãã³ã¢ã¼ã"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1499,542 +1536,628 @@ msgid ""
"\n"
"License: GPLv2+"
msgstr ""
+"OpenGL ã¹ãã¯ãã©ã ã¢ãã©ã¤ã¶ for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"\n"
+"æ´¾çå
: XMMS ãã©ã°ã¤ã³:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"ã©ã¤ã»ã³ã¹: GPLv2+"
+
+#: src/gl-spectrum/gl-spectrum.cc:62
+msgid "OpenGL Spectrum Analyzer"
+msgstr "OpenGL ã¹ãã¯ãã©ã ã¢ãã©ã¤ã¶"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
+msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
"Based on the XMMS plugin:\n"
"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
"4Front Technologies\n"
"\n"
"License: GPLv2+"
+msgstr ""
+"OpenGL ã¹ãã¯ãã©ã ã¢ãã©ã¤ã¶ for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"æ´¾çå
: XMMS ãã©ã°ã¤ã³:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"ã©ã¤ã»ã³ã¹: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
-msgid "OpenGL Spectrum Analyzer"
-msgstr "OpenGL ã¹ãã¯ãã«ã¢ãã©ã¤ã¶"
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "OpenGL ã¹ãã¯ãã©ã ã¢ãã©ã¤ã¶ (Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "GNOME ã·ã§ã¼ãã«ãã"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-"Gnome ã·ã§ã¼ãã«ãããã©ã°ã¤ã³\n"
-"Gnome ã·ã§ã¼ãã«ããã§ãã¬ã¤ã¤ã¼ãã³ã³ããã¼ã«ãã¾ãã\n"
+"GNOME ã·ã§ã¼ãã«ãããã©ã°ã¤ã³\n"
+"GNOME ã·ã§ã¼ãã«ããã§ãã¬ã¤ã¤ã¼ãå¶å¾¡å¯è½ã«ãã¾ãã\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Gnome ã·ã§ã¼ãã«ãã"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "ãªã¹ãçªå·"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "ã¿ã¤ãã«"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "ã¢ã¼ãã£ã¹ã"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "å¹´"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "ã¢ã«ãã "
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "ã¢ã«ãã ã¢ã¼ãã£ã¹ã"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "ãã©ãã¯"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "ã¸ã£ã³ã«"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "ãã¥ã¼çªå·"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "é·ã"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "ãã¡ã¤ã«ãã¹"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "ãã¡ã¤ã«å"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "ã«ã¹ã¿ã ã¿ã¤ãã«"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ãããã¬ã¼ã"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "å©ç¨ã§ããå"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "表示ãããå"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "æ¤ç´¢ãã¼ã«"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "å·¦å´ã«ãããã³ã°"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "å³å´ã«ãããã³ã°"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "ä¸é¨ã«ãããã³ã°"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "ä¸é¨ã«ãããã³ã°"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "ãããã³ã°ãè§£ã"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "ç¡å¹"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "æ¤ç´¢ãã¼ã«"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "ãã¡ã¤ã«ãéã(_O)"
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "URL ãéã(_U)"
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "ãã¡ã¤ã«ã追å (_A)"
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "URL ã追å (_R)"
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "ã©ã¤ãã©ãªãæ¤ç´¢ (_L)"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "ããã°ã©ã ã®æ
å ±(_B)"
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "è¨å® (_S)"
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "çµäº(_Q)"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "åç(_P)"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "䏿忢(_E)"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "忢(_S)"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "åã®æ²ã¸(_V)"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "æ¬¡ã®æ²ã¸(_N)"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "ãªãã¼ã(_R)"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "ã·ã£ããã«(_H)"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "1æ²ãªãã¼ã(_O)"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "æ²ã®åçå¾ã«åæ¢(_A)"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "æ²ã®æ
å ±(_I)"
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "æå®ããæéã«ã¸ã£ã³ã(_T)"
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "æå®ããæ²ã«ã¸ã£ã³ã(_J)"
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "ãªãã¼ããã¤ã³ãAãè¨å®(_A)"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "ãªãã¼ããã¤ã³ãBãè¨å®(_B)"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "ãªãã¼ããã¤ã³ããã¯ãªã¢ãã(_C)"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "ã¿ã¤ãã«(_T)"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr "ãã¡ã¤ã«å(_F)"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "ãã¹(_P)"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "ãã©ãã¯ãã³ãã¼(_N)"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "ã¢ã¼ãã£ã¹ã(_A)"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "ã¢ã«ãã (_L)"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "ã¢ã«ãã ã¢ã¼ãã£ã¹ã(_M)"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "ãªãªã¼ã¹æ¥(_D)"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "ã¸ã£ã³ã«(_G)"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "æ²ã®é·ã(_L)"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "ãã¡ã¤ã«ãã¹(_F)"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "ã«ã¹ã¿ã ã¿ã¤ãã«(_C)"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "éé ã«ãã(_E)"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "ã©ã³ãã ã«ä¸¦ã¹ã(_R)"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "ãã®ãã¬ã¤ãªã¹ããåçãã(_P)"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "åç/åé(_P)"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "åèªã¿è¾¼ã¿(_R)"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "ã½ã¼ã(_S)"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "鏿ãããã©ãã¯ãã½ã¼ããã (_L)"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "éè¤ãã¦ããæ²ãåé¤(_D)"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "åçã§ããªããã¡ã¤ã«ãåé¤ãã(_U)"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "æ°ãããã¬ã¤ãªã¹ã(_N)"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "ååã®å¤æ´(_A)"
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "åé¤ (_V)"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "ã¤ã³ãã¼ã(_I)"
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "ã¨ã¯ã¹ãã¼ã(_E)"
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "ãã¬ã¤ãªã¹ãããã¼ã¸ã£(_M)"
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "ãã¥ã¼ããã¼ã¸ã£(_Q)"
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "é³éãä¸ãã(_U)"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "é³éãä¸ãã(_D)"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "ã¤ã³ã©ã¤ã¶(_E)"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "ã¨ãã§ã¯ã (_E)"
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "ã¡ãã¥ã¼ãã¼ã表示ãã(_M)"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "æ
å ±ãã¼ã表示ãã(_N)"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "æ
å ±ãã¼ã«è¦è¦å¹æã表示"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "ã¹ãã¼ã¿ã¹ãã¼ã表示ãã(_S)"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "æ®ãæéã表示ãã(_R)"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "è¦è¦å (_V)"
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "ãã¡ã¤ã«(_F)"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "åç(_P)"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "ãã¬ã¤ãªã¹ã(_L)"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "ãµã¼ãã¹(_S)"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "åºå(_O)"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "表示(_V)"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "ãã¥ã¼ / ã¢ã³ãã¥ã¼(_Q)"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "ãã®ãã¡ã¤ã«ãå«ããã©ã«ãã追å (_O)"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "åãåã(_T)"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "ã³ãã¼(_C)"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "è²¼ãä»ã(_P)"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "ãã¹ã¦é¸æ(_A)"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "ååã®å¤æ´(_R)"
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>ãã¬ã¤ãªã¹ãã®ã¿ã</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "常ã«ã¿ãã表示ãã"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
-msgstr ""
+msgstr "é
ç®ç·æ°ã表示"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "éãããã¿ã³ã表示ãã"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>ãã¬ã¤ãªã¹ãå</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "åã®ãããã¼ã表示ãã"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>ãã®ä»</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
-msgstr ""
+msgstr "ç¢å°ãã¼ã§ã·ã¼ã¯ããæé:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "æ²ãå¤ãã£ããã¹ã¯ãã¼ã«ãã"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK ã¤ã³ã¿ã¼ãã§ã¤ã¹"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ãããã¡ä¸ ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "ã¢ãã©ã«"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "ã¹ãã¬ãª"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d ãã£ã³ãã«"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "ã·ã³ã°ã«ã¢ã¼ã"
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "ãã¬ã¤ãªã¹ãã¢ã¼ã"
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "æ²ã®åçå¾ã«åæ¢ãã"
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "åã®ãã©ãã¯"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "åç"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "䏿忢/åé"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "忢"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "次ã®ãã©ãã¯"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "5ç§é²ãã"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "5ç§æ»ã"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "ãã¥ã¼ã"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "é³éãä¸ãã"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "é³éãä¸ãã"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "æå®ãããã¡ã¤ã«ã¸ç§»å"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "ãã¬ã¤ã¤ã¦ã£ã³ãã¦ããã°ã«"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "On-Screen-Display ã表示ãã"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "ãªãã¼ãããã°ã«"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "ã·ã£ããã«ããã°ã«"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "ç¾å¨ã®æ²ã®åçå¾ã«åæ¢ãã"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "ãã¬ã¤ã¤ã¦ã£ã³ãã¦ã表示ãã"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(ãªã)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2045,15 +2168,11 @@ msgstr ""
"\n"
"æ¬å½ã«ããããã§ããï¼"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "ãã¦ã¹ãã¿ã³ã®å²ãå½ã¦"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "ã°ãã¼ãã«ããããã¼ãã©ã°ã¤ã³ã®è¨å®"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2061,23 +2180,27 @@ msgstr ""
"ããã¹ããã£ã¼ã«ãå
ã§ãã¼ã³ã³ããã¼ã·ã§ã³ãæ¼ãã¦ãã ããã\n"
"ãã¦ã¹ãã¿ã³ãçµã¿åããããã¨ãã§ãã¾ãã"
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "ããããã¼:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>åä½:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>ãã¼ãã¤ã³ã:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "追å (_A)"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "ã°ãã¼ãã«ããããã¼"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2103,60 +2226,56 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "ã°ãã¼ãã«ããããã¼"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK åºå"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "æå¹ãªãã¹ã¦ã® jack ãã¼ãã«æ¥ç¶ãã"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "åºåãã¼ãã«èªåæ¥ç¶ãã"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "åºåãã¼ãã«ã®ã¿æ¥ç¶ãã"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "%d åã® JACK åºåãã¼ããè¦ã¤ããã¾ãããã %d åãå¿
è¦ã§ãã"
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "ãã¼ãã«æ¥ç¶ããªã"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "JACK ãã¼ã %s ã¸ã®æ¥ç¶ã«å¤±æ"
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "æ¥ç¶ã¢ã¼ã:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+"JACK ã¯ãæµ®åå°æ°ç¹ã®ãªã¼ãã£ãªã«ãã対å¿ãã¦ããªãã®ã§ããAudacious ã®ãªã¼"
+"ãã£ãªåºåã®è¨å®ã§ããããæ·±åº¦ãæµ®åå°æ°ç¹ã«å¤æ´ããå¿
è¦ãããã¾ãã"
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "ãããã°åºåãæå¹ã«ãã"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "JACKãµã¼ãã¸ã®æ¥ç¶ã«å¤±æãã¾ãããJACKãµã¼ãã¯æ¬å½ã«åãã¦ãã¾ãã?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Audacious ã¸ã®ãã¼ã by Giacomo Lozito"
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK åºå"
+"JACK ãµã¼ãã«ã¯%d Hzã®ãµã³ããªã³ã°å¨æ³¢æ°ãå¿
è¦ã§ããã¨ãããã Audacious ãã"
+"ã¾åçãã¦ããã®ã¯ %d Hz ã§ãããµã³ããªã³ã°å¨æ³¢æ°ã³ã³ãã¼ã¿ã®ãã©ã°ã¤ã³ãç¨ã"
+"ã¦ãåºåãã卿³¢æ°ãåãããããã«ãã¦ãã ããã"
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s ã®è¨å®"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA Host ã®è¨å®"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "ã¢ã¸ã¥ã¼ã«ã®ãã¹:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2167,25 +2286,25 @@ msgstr ""
"å ããå¾ã¯ãæ°ãããã©ã°ã¤ã³ãã¹ãã£ã³ããããã«ã\n"
"Enter ãã¼ãæ¼ãã¦ãã ããã</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "å©ç¨å¯è½ãªãã©ã°ã¤ã³:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "æå¹"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "æå¹ãªãã©ã°ã¤ã³:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "è¨å®:"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2193,48 +2312,15 @@ msgstr ""
"LADSPA ãã¹ã for Audacious\n"
"Copyright 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA ãã¹ã"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: LIRC æ©è½ãåæåã§ãã¾ãã\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: LIRC ã®è¨å®ãã¡ã¤ã«ãèªã¿è¾¼ãã¾ãã\n"
-"%s: LIRC ã®ããã¥ã¡ã³ãããèªã¿ãã ãã\n"
-"%s: æ£ããè¨å®ãã¡ã¤ã«ã®æ¸ãæ¹\n"
-"\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: 忥ç¶ã試ã¿ã¦ãã¾ã...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: 䏿ãªã³ãã³ã \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: LIRC ããåæããã¾ãã\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: %d ç§æ¯ã«åæ¥ç¶ã試ã¿ã¾ã...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC ãã©ã°ã¤ã³"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2251,84 +2337,92 @@ msgid ""
msgstr ""
"LIRC ãªã¢ã¼ãã³ã³ããã¼ã«ãã¼ã¢ã³ãç¨ãããã·ã³ãã«ãª Audacious ã³ã³ããã¼ã«"
"ãã©ã°ã¤ã³\n"
-"Adapted for Audacious by:\n"
+"Audacious ç¨ã«ç§»æ¤:\n"
"Tony Vroon <chainsaw at gentoo.org>\n"
"Joonas Harjumäki <jharjuma at gmail.com>\n"
"\n"
-"Based on the XMMS LIRC plugin by:\n"
+"æ´¾çå
: XMMS LIRC ãã©ã°ã¤ã³ãä½è
:\n"
"Carl van Schaik <carl at leg.uct.ac.za>\n"
"Christoph Bartelmus <xmms at bartelmus.de>\n"
"Andrew O. Shadoura <bugzilla at tut.by>\n"
"\n"
-"For more information about LIRC, see http://lirc.org."
+"LIRC ã«ã¤ãã¦ã®è©³ç´°ã¯ http://lirc.org ãåç
§"
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>æ¥ç¶</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "LIRC ãµã¼ãã¼ã¸åæ¥ç¶ãã"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "忥ç¶ã®å¾
æ©æé:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC ãã©ã°ã¤ã³"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki ãã©ã°ã¤ã³"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "æè©ãè¦ã¤ããã¾ãã"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "ã¨ã©ã¼"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "%s ãåå¾ã§ãã¾ãã"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "ã¨ã©ã¼"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "%s ãè§£æã§ãã¾ãã"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "æè©ãæ¤ç´¢ãã¦ãã¾ã ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "æ²ã®ã¡ã¿ãã¼ã¿ãè¦ã¤ããã¾ãã"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "lyrics.wikia.com ã«æ¥ç¶ãã¦ãã¾ã ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki ãã©ã°ã¤ã³"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "LyricWiki ãã©ã°ã¤ã³ (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U ãã©ã°ã¤ã³"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "ã¿ã¯ãã¸ã§ãã¬ã¼ã¿"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "ã¿ã¯ãã¸ã§ãã¬ã¼ã¿: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "ã¿ã¯ãã¸ã§ãã¬ã¼ã¿: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2347,11 +2441,11 @@ msgstr ""
"tact://77 (77bpmã®ãã¼ããä½ã)\n"
"tact://60*3/4 (3/4 æåã§ 60 bpmã®ãã¼ããä½ã)"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "ã¿ã¯ãã¸ã§ãã¬ã¼ã¿"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "ãã£ã³ãã«ãããµ"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2359,152 +2453,184 @@ msgstr ""
"ãã£ã³ãã«ãããµãã©ã°ã¤ã³ for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>ãã£ã³ãã«ãããµ</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "åºåãã£ã³ãã«:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "ãã£ã³ãã«ãããµ"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS ãã©ã°ã¤ã³"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "MMS ãµã¼ãã¸ã®æ¥ç¶ã¨ã©ã¼"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Module Player)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
-msgstr ""
+msgstr "<b>è§£å度</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>ãã£ã³ãã«</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
-msgstr ""
+msgstr "è¿å (æé«é)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
-msgstr ""
+msgstr "ãªã㢠(é«é)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
-msgstr ""
+msgstr "ã¹ãã©ã¤ã³æ²ç· (é«å質)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
-msgstr ""
+msgstr "ããªãã§ã¼ãº (æé«å質)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr "<b>ãµã³ããªã³ã°ã¬ã¼ã</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "ã¬ãã«:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
-msgstr ""
+msgstr "ã«ãããªã:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>ãªãã¼ã</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>ãã¹ãã¼ã¹ã</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>ãµã©ã¦ã³ã</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>ããªã¢ã³ã</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
-msgstr ""
+msgstr "ãªã¼ãã¼ãµã³ããªã³ã°"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "ãã¤ãºãªãã¯ã·ã§ã³"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
-msgstr ""
+msgstr "Amiga MODãåçãã"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>ãªãã¼ã</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "ãªãã¼ãã«ã¦ã³ã:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "ãã£ã¨ãªãã¼ãããã«ã¯ãªãã¼ãåæ°ã-1ã«è¨å®ãã¦ãã ããã"
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "ãããã®è¨å®ã¯ãAudaciousã®åèµ·åå¾ã«åæ ããã¾ãã"
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "ãµã©ã¦ã³ã"
-
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 ãã©ã°ã¤ã³"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>é«åº¦</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "æ£ç¢ºãªé·ããè¨ç®ãã(é
ã)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "ãµã©ã¦ã³ã"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 ãµã¼ã"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS ãã©ã°ã¤ã³"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "ãªãã¤ã¬ã¯ãå¦çã®ã¨ã©ã¼"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "ä¸æãª HTTP ã¨ã©ã¼"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "URLå¦çã®ã¨ã©ã¼"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "ãªãã¤ã¬ã¯ãã®éå°ãªç¹°è¿ã"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "忢ãã¾ãã"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious ã¯æ²ãåçãã¦ãã¾ããã"
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "ãã¹ã¯ãããéç¥"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2523,57 +2649,85 @@ msgid ""
"You should have received a copy of the GNU General Public License along with "
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
+"ãã¹ã¯ãããéç¥ãã©ã°ã¤ã³ for Audacious\n"
+"Copyright (C) 2010 Maximilian Bogner\n"
+"Copyright (C) 2011-2013 John Lindgren and Jean-Alexandre Anglès d'Auriac\n"
+"\n"
+"ãã®ããã°ã©ã ã¯ããªã¼ã½ããã¦ã§ã¢ã§ããããªãã¯ããããããªã¼ã½ã ãã¦ã§ã¢è²¡"
+"å£ã«ãã£ã¦çºè¡ãããGNUä¸è¬å
¬è¡å©ç¨è¨±è«¾æ¸(ãã¼ã¸ã§ã³3ãããã以éã®ãã¼ã¸ã§ã³"
+"ã®ãã¡ã©ãã)ãå®ããæ¡ä»¶ã®ä¸ã§åé å¸ã¾ãã¯æ¹å¤ãããã¨ãã§ãã¾ãã\n"
+"\n"
+"ãã®ããã°ã©ã ã¯æç¨ã§ãããã¨ãé¡ã£ã¦é å¸ããã¾ããã*å
¨ãã®ç¡ä¿è¨¼ *ã§ããå"
+"æ¥å¯è½æ§ã®ä¿è¨¼ãç¹å®ç®çã¸ã®é©åæ§ã¯ãè¨å¤ã«ç¤ºããããã®ãå«ããå
¨ãåå¨ãã¾"
+"ããã詳ããã¯GNUä¸è¬å
¬è¡å©ç¨è¨±è«¾æ¸ãã覧ãã ããã\n"
+"\n"
+"ããªãã¯ãã®ããã°ã©ã ã¨å
±ã«ãGNUä¸è¬å
¬è¡å©ç¨è¨±è«¾æ¸ã®ã³ãã¼ãä¸é¨åãåã£ã¦ã"
+"ãã¯ãã§ããããåãåã£ã¦ããªããã°ã<http://www.gnu.org/licenses/> ãã覧ã"
+"ã ããã\n"
+"\n"
+"ï¼ãã®GPLã®ç¿»è¨³ã¯éå
¬å¼ãªãã®ã§ãããªã¼ã½ããã¦ã§ã¢ãã¡ã¦ã³ãã¼ã·ã§ã³ã«ãã£ã¦"
+"æ³çå¹åãããã¨æ¿èªããããã®ã§ã¯ããã¾ãããä½ã許å¯ããã¦ãããå³å¯ã«ç¢ºèª"
+"ããããã«ã¯ã(è±èªã§æ¸ããã)ãªãªã¸ãã«ã®GPLãåç
§ãã¦ãã ãããï¼"
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "åçã³ã³ããã¼ã«ã表示ãã"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "常ã«éç¥ã表示ãã"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "ãã¹ã¯ãããéç¥"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "ã¢ã«ãã ã®ååãéç¥ã«å«ãã"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "表示ãã"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "䏿忢"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "æ¬¡ã®æ²"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. ããã©ã«ãããã¤ã¹"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 åºå"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "OSS3 åºå"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "ããã©ã«ãããã¤ã¹"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "ãªã¼ãã£ãªããã¤ã¹:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "代æ¿ããã¤ã¹ã使ç¨ãã:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "ã»ãã·ã§ã³éã§é³éãä¿åãã"
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "OSS ã½ããã¦ã§ã¢ã®ãã©ã¼ããã夿ãæå¹ã«ãã"
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
"ãã¼ãã£ã«ããã·ã³ã°ãé²ãããã«æä»çã¢ã¼ã (exclusive mode) ãæå¹ã«ãã"
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2587,19 +2741,35 @@ msgstr ""
"#audacious ã®äººã
ãç¹ã« Tony Vroon ããã³ John Lindgrenãããã¦ãã¡ãããOSS "
"plugin ã®åä½è
ã«æè¬ãã¾ãã"
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 åºå"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "ãã¬ã¤ãªã¹ãããã¼ã¸ã£"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "ã¨ã³ããª"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "åé¤(_R)"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "ååã®å¤æ´(_A)"
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS ãã¬ã¤ãªã¹ã"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2 ãã³ã¼ã"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio åºå"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2635,11 +2805,73 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio åºå"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "QtMultimedia åºå"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"QtMultimedia Audio åºåãã©ã°ã¤ã³ for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"æ´¾çå
: SDL åºåãã©ã°ã¤ã³ for Audacious\n"
+"Copyright 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "å¦çä¸ ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "æ¤ç´¢"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "ãã©ã«ããéã(_O)"
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "ãã©ã«ãã追å (_A)"
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "ãã°æ¤æ» (_L)"
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "ãã¡ã¤ã«ãéã"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "ãã¡ã¤ã«ã追å "
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "åã®æ²"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "ãªãã¼ã"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "ã·ã£ããã«"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Qt ã¤ã³ã¿ã¼ãã§ã¤ã¹"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "ãµã³ããªã³ã°å¨æ³¢æ°ã³ã³ãã¼ã¿"
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2647,100 +2879,107 @@ msgstr ""
"ãµã³ãã«ã¬ã¼ã夿ãã©ã°ã¤ã³ for Audacious\n"
"Copyright 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "ãµã³ãã«ã®ã¹ããã/ç¹°ãè¿ã"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "ç·å½¢è£é"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "é«é sinc è£é"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "sinc è£é"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "é«å質 sinc è£é"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>夿</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "æ¹æ³"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "ã¬ã¼ã:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>ã¬ã¼ããããã³ã°</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "ã¬ã¼ããããã³ã°ã使ç¨ãã"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "ãµã³ããªã³ã°å¨æ³¢æ°ã³ã³ãã¼ã¿"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "ã¦ã¼ã¶ã¼ %s ã® Scrobble ã«æåãã¾ããã"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "ã¢ã¯ã»ã¹è¨±å¯ãããã¾ãã"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"Audacious ã« scrobble ãã許å¯ãä¸ããã«ã¯ã以ä¸ã®ãªã³ã¯ã«ã¢ã¯ã»ã¹ãã¦ãã ã"
"ãã"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-"ãã®ã¦ã£ã³ãã¦ãéããã¾ã¾ãããä¸åº¦ããã¼ããã·ã§ã³ã確èªããããã¯ãªãã¯ã"
-"ã¦ãã ããã\n"
+"ãã®ã¦ã£ã³ãã¦ãéããã¾ã¾ãããä¸åº¦ãèªè¨¼ç¢ºèªããã¯ãªãã¯ãã¦ãã ããã\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2748,34 +2987,38 @@ msgstr ""
"ããªãã® Scrobble ã¯ã³ã³ãã¥ã¼ã¿ã«ä¿åããã¦ãã¾ãã\\n\n"
"Audacious ã¯æç¨¿ãå¯è½ã«ãªã次第ãããã« Scrobble ãæç¨¿ãã¾ãã"
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "ãããã¯ã¼ã¯ã«åé¡ãããã¾ãã"
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "Last.fmã¸ã®æ¥ç¶ã«åé¡ãçºçãã¾ããããã¨ã§ããä¸åº¦è©¦ãã¦ãã ããã"
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "ãã§ãã¯ãã¦ãã¾ã..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
-msgstr "ãã¼ããã·ã§ã³ã確èªãã(_H)"
+msgstr "èªè¨¼ç¢ºèª(_H)"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
-msgstr ""
+msgstr "èªè¨¼åæ¶(_R)"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"Audacious ãããªãã® Last.fm ã¢ã«ã¦ã³ãã«ãã©ãã¯ã scrobble ã§ããããã«è¨å®"
"ããå¿
è¦ãããã¾ãã\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2783,7 +3026,7 @@ msgstr ""
"Scrobbler ãã©ã°ã¤ã³ãèµ·åã§ãã¾ããã§ããã\\n\n"
"ã¤ã³ã¹ãã¼ã«æ¹æ³ã«åé¡ãããå¯è½æ§ãããã¾ãã"
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2797,11 +3040,7 @@ msgstr ""
"Copyright © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com>\\n\\n\n"
"ããã¸ã§ã¯ãéå§æã«æå©ããã¦ããã John Lindgren ã«æè¬ãã¾ãã\\n\\n\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2809,7 +3048,11 @@ msgstr ""
"Audacious 㯠Last.fm Scrobbler ã®ãã¼ã¸ã§ã³ãæ´æ°ãã¾ããã\n"
"Scrobbler ãã©ã°ã¤ã³ã®è¨å®ãã確èªãã ããã"
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL åºå"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2817,74 +3060,53 @@ msgstr ""
"SDL åºåãã©ã°ã¤ã³ for Audacious\n"
"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL åºå"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "ã©ã¤ãã©ãª"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "䏿ãªã¢ã¼ãã£ã¹ã"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "䏿ãªã¢ã«ãã "
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\\n\n"
-"ã¢ã«ãã : %s ã¢ã¼ãã£ã¹ã: %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d ã®çµæ"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d albums"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d ã®é ã)"
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d songs"
-
-#: src/search-tool/search-tool.c:639
-#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d songs by %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d æ²"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "ï¼ãã®ã¸ã£ã³ã«ä¸ã§ï¼"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "ã¢ã«ãã :"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "ã¢ã¼ãã£ã¹ã:"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "ãã¬ã¤ãªã¹ãã使(_C)"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "ãã¬ã¤ãªã¹ãã«è¿½å (_A)"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "ã©ã¤ãã©ãªãæ¤ç´¢"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2892,679 +3114,771 @@ msgstr ""
"鳿¥½ã©ã¤ãã©ãªã Audacious ã¸ã¤ã³ãã¼ãããã«ã¯ããã©ã«ãã鏿ãã\"åèªã¿è¾¼"
"ã¿\" ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã"
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "ãå¾
ã¡ãã ãã..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "ãã©ã«ãã鏿"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "SID "
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>åºå</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "ãã£ã³ãã«:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>ã¨ãã¥ã¬ã¼ã·ã§ã³</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "MOS 8580 ãã¨ãã¥ã¬ã¼ã (ããã©ã«ã㯠MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "ãããåå¼ãèªå鏿ãããªã"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "ã¨ãã¥ã¬ã¼ããã£ã«ã¿"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "ã¯ããã¯é度:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "ã¯ããã¯é度ãèªå鏿ãããªã"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>åçæé</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "åçæéã®æé·ãè¨å®"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "æ²ã®é·ãã䏿ãªã¨ãã®ã¿é©ç¨ãã"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "åçæéã®æçãè¨å®"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Subtunes</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "subtunes ãæå¹ã«ãã"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "æ¬¡ã®æéãããçãsubtunesãç¡è¦ãã"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>注æ</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "ç¡é³é¨ã®é¤å»"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"ç¡é³é¨é¤å»ãã©ã°ã¤ã³ for Audacious\n"
+"Copyright 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>ç¡é³é¨ã®é¤å»</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "ãããå¤:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "ãã¡ã¤ã«ãéã"
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "URLãéã"
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "ã©ã¤ãã©ãªãæ¤ç´¢"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "æ¼å¥"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "ãã¬ã¤ãªã¹ã"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "表示"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "ãµã¼ãã¹"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
-msgstr "Audacious ã«ã¤ãã¦"
+msgstr "æ
å ±"
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "è¨å®"
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "çµäº"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "æ²ã®æ
å ±"
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "ãªãã¼ã"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "ã·ã£ããã«"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "æ¬¡ã®æ²ã«é²ã¾ãªã"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "æ²ã®åçå¾ã«åæ¢"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "åã®æ²"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "A-B ãªãã¼ããã»ãã"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "A-B ãªãã¼ããã¯ãªã¢"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "æå®ããæ²ã«ã¸ã£ã³ã"
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "æå®ããæéã¸ã¸ã£ã³ã"
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "ãã®ãã¬ã¤ãªã¹ããåç"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "åç/åé"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "æ°ãããã¬ã¤ãªã¹ã"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "ãã¬ã¤ãªã¹ãã®ååã夿´"
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "ãã¬ã¤ãªã¹ããåé¤"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "åã®ãã¬ã¤ãªã¹ã"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "次ã®ãã¬ã¤ãªã¹ã"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "ãã¬ã¤ãªã¹ãã®ã¤ã³ãã¼ã"
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "ãã¬ã¤ãªã¹ãã®ã¨ã¯ã¹ãã¼ã"
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "ãã¬ã¤ãªã¹ãããã¼ã¸ã£"
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "ãã¥ã¼ããã¼ã¸ã£"
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "ãã¬ã¤ãªã¹ãã®æ´æ°"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "ãã¬ã¤ãªã¹ãã¨ãã£ã¿ã表示ãã"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "ã¤ã³ã©ã¤ã¶ã表示ãã"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "æ®ãæéã表示ãã"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "å¸¸ã«æåé¢ã«é
ç½®ãã"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "å
¨ã¯ã¼ã¯ã¹ãã¼ã¹ã«é
ç½®ãã"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
-msgstr ""
+msgstr "ãã¬ã¤ã¤ã¼ãããã"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
-msgstr ""
+msgstr "ãã¬ã¤ãªã¹ãã¨ãã£ã¿ã¼ãããã"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
-msgstr ""
+msgstr "ã¤ã³ã©ã¤ã¶ã¼ãããã"
+
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "2åã®å¤§ããã§è¡¨ç¤º"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "URLã追å "
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "ãã¡ã¤ã«ã追å "
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "ã¿ã¤ãã«"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "ãã¡ã¤ã«å"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "ãã¡ã¤ã«ãã¹"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "å
¨ã¦åé¤"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "ãã¥ã¼ã®ã¯ãªã¢"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "å©ç¨ã§ããªããã¡ã¤ã«ã®åé¤"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "éè¤ã¨ã³ããªã®åé¤"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "鏿ãã¦ããªãã¨ã³ããªã®åé¤"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "鏿ããã¨ã³ããªã®åé¤"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "æ¤ç´¢ã¨é¸æ"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "鏿ç¯å²ã®å転"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "æªé¸æã«ãã"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "å
¨ã¦é¸æ"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "ã¢ã«ãã "
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "ãã©ãã¯çªå·"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "ã¢ã¼ãã£ã¹ã"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "ã¢ã«ãã "
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "ã¢ã«ãã ã¢ã¼ãã£ã¹ã"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "ãªãªã¼ã¹æ¥"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "ãã©ãã¯çªå·"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "ã¸ã£ã³ã«"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "é·ã"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "ã«ã¹ã¿ã ã¿ã¤ãã«"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "ãã¬ã¤ãªã¹ããã©ã³ãã ã«ãã"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "ãã¬ã¤ãªã¹ããéé ã«ãã"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "鏿ç¯å²ã®ã½ã¼ã"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "ãã¬ã¤ãªã¹ãã®ã½ã¼ã"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "åãåã"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "ã³ãã¼"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "è²¼ãä»ã"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "ãã¥ã¼/ã¢ã³ãã¥ã¼"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "ããªã»ããã®èªã¿è¾¼ã¿"
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "èªåããªã»ããã®èªã¿è¾¼ã¿"
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "ããã©ã«ãã®èªã¿è¾¼ã¿"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "ããªã»ãããã¡ã¤ã«ã®èªã¿è¾¼ã¿"
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "EQF ãã¡ã¤ã«ã®èªã¿è¾¼ã¿"
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "ããªã»ããã®ä¿å"
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "èªåããªã»ããã®ä¿å"
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "ããã©ã«ããä¿å"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "ããªã»ãããã¡ã¤ã«ãä¿å"
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "EQF ãã¡ã¤ã«ã®ä¿å"
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "ããªã»ãããåé¤"
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "èªåããªã»ãããåé¤"
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "Winamp ããªã»ããã®ã¤ã³ãã¼ã"
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
-msgstr ""
+msgstr "ã¼ãã«ãªã»ãã"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winamp ã¯ã©ã·ãã¯ã¤ã³ã¿ã¼ãã§ã¤ã¹"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "ä¿å"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "èªã¿è¾¼ã¿"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
-msgstr ""
+msgstr "ããªã»ãããã¡ã¤ã«ãèªè¾¼ã"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
-msgstr ""
+msgstr "EQF ãã¡ã¤ã«ããã¼ã"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
-msgstr ""
+msgstr "ããªã»ãããã¡ã¤ã«ãä¿å"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
-msgstr ""
+msgstr "EQF ãã¡ã¤ã«ãä¿å"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
-msgstr ""
+msgstr "Winamp ã®ããªã»ãããã¤ã³ãã¼ã"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "ããªã»ãã"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "ããªã»ããã®èªã¿è¾¼ã¿"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "èªåããªã»ããã®èªã¿è¾¼ã¿"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "ããªã»ããã®ä¿å"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "èªåããªã»ããã®ä¿å"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "ããªã»ããã®åé¤"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "èªåããªã»ããã®åé¤"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "ãã¬ã¤ã¤(_P):"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "ãã¬ã¤ã¤:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "ã¡ã¤ã³ã¦ã£ã³ãã¦ã§ä½¿ç¨ãããã©ã³ãã®é¸æ"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "ãã¬ã¤ãªã¹ã(_P):"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "ãã¬ã¤ãªã¹ã:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "ãã¬ã¤ãªã¹ãã§ä½¿ç¨ãããã©ã³ãã®é¸æ"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>ã¹ãã³</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>ãã©ã³ã</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "ãããããããã©ã³ãã使ç¨ãã (ASCII ã®ã¿å¯¾å¿)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
-msgstr ""
+msgstr "æ²ã®ã¿ã¤ãã«ãã¹ã¯ãã¼ã«"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "æ²ã®ã¿ã¤ãã«ã両æ¹åã«ã¹ã¯ãã¼ã«ãã"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "ã¢ãã©ã¤ã¶"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "ã¹ã³ã¼ã"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
-msgstr ""
+msgstr "å£°ç´ / VU ã¡ã¼ã¿ã¼"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "ãªã"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "æ¨æº"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "ãã¡ã¤ã¢"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
-msgstr ""
+msgstr "åç´ç·"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "ã©ã¤ã³"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "ãã¼"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "æãé
ã"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "é
ã"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "ä¸"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "æ©ã"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "æãæ©ã"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
-msgstr ""
+msgstr "ç¹"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
-msgstr ""
+msgstr "ç·"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
-msgstr ""
+msgstr "ã½ãªãã"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "ã¢ã¤ã¹"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "ã¹ã ã¼ãº"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>ã¿ã¤ã</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
-msgstr ""
+msgstr "è¦è¦åã¿ã¤ã:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>ã¢ãã©ã¤ã¶</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
-msgstr ""
+msgstr "ãã¼ã¯ã表示"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
-msgstr ""
+msgstr "è²ä»ã:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
-msgstr ""
+msgstr "ã¹ã¿ã¤ã«:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
-msgstr ""
+msgstr "éä¸é度:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
-msgstr ""
+msgstr "ãã¼ã¯ã®éä¸é度:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
-msgstr ""
+msgstr "ã¹ã³ã¼ãã®ã¹ã¿ã¤ã«:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
-msgstr ""
+msgstr "声ç´ã®è²ä»ã:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
-msgstr ""
+msgstr "VU ã¡ã¼ã¿ã¼ã®ã¹ã¿ã¤ã«:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "ä¸è¬"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "è¦è¦å"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "ããªã¢ã³ã"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious ã¤ã³ã©ã¤ã¶"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "%d:%-2.2d / %d:%-2.2d ã¸ã·ã¼ã¯ãã"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "é³é: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "ãã©ã³ã¹: %d%% å·¦"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "ãã©ã³ã¹: ä¸å¤®"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "ãã©ã³ã¹: %d%% å³"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "ãªãã·ã§ã³ã¡ãã¥ã¼"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "ãå¸¸ã«æåé¢ã«é
ç½®ãç¡å¹"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "ãå¸¸ã«æåé¢ã«é
ç½®ãæå¹"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "ãã¡ã¤ã«æ
å ±ããã¯ã¹"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "è¦è¦å"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "ãªãã¼ããã¤ã³ãAãè¨å®ãã¾ãã"
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "ãªãã¼ããã¤ã³ãBãè¨å®ãã¾ãã"
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "ãªãã¼ããã¤ã³ããã¯ãªã¢ããã¾ããã"
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "ã·ã³ã°ã«ã¢ã¼ã"
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "ãã¬ã¤ãªã¹ãã¢ã¼ã"
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "æ²ã®åçå¾ã«åæ¢ãã"
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "æå¹ã«ãªã£ã¦ãããã¬ã¤ãªã¹ãã®ã¨ã³ããªãæ¤ç´¢"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "æ¤ç´¢"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3575,57 +3889,61 @@ msgstr ""
"表ç¾ã使ãã大æåã¨å°æåãåºå¥ãã¾ãããæ£è¦è¡¨ç¾ã®åä½ãããããªãå ´åã¯ã"
"æ¤ç´¢ãããæåããã®ã¾ã¾å
¥åãã¦ãã ããã"
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
msgstr "ã¿ã¤ãã«: "
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "ã¢ã«ãã å: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr "ã¢ã«ãã : "
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr "ã¢ã¼ãã£ã¹ã: "
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "ãã¡ã¤ã«å: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "ãã¡ã¤ã«å:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "æ¤ç´¢åã«ååã®é¸æãã¯ãªã¢ãã"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "ãããããã¨ã³ããªã®ãã¥ã¼ãèªåçã«ãã°ã«ãã"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "ãããããã¨ã³ããªã§æ°ãããã¬ã¤ãªã¹ãã使ãã"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audacious ãã¬ã¤ãªã¹ãã¨ãã£ã¿"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d / %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Archived Winamp 2.x ã¹ãã³"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Unarchived Winamp 2.x ã¹ãã³"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "ãã£ã¬ã¯ã㪠(%s) ã使ã§ãã¾ããã§ãã: %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile ãã©ã°ã¤ã³"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3665,83 +3983,72 @@ msgstr ""
"this program; if not, write to the Free Software Foundation, Inc., 51 "
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile ãã©ã°ã¤ã³"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Sndio åºå"
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Sndio åºåãã©ã°ã¤ã³ã«ã¤ãã¦"
-
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Sndio åºåãã©ã°ã¤ã³\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "ããã¤ã¹ (空ç½ã®å ´åã¯ããã©ã«ã)"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "対å¿ãã¦ããªãå½¢å¼"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "é³éãä¿åã復å
:"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"ãªã¼ãã£ãªããã¤ã¹ã§å¯¾å¿ãã¦ããªãå½¢å¼ãè¦æ±ããã¾ããã\n"
-"\n"
-"sndiod(1) ãµã¼ããèµ·åãã¦ãããããä¸åº¦å®è¡ãã¦ãã ããã"
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Sndio ã¨ã©ã¼: ãµãã¼ããã¦ããªããªã¼ãã£ãªå½¢å¼ (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio ããã¤ã¹"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Sndio ã¨ã©ã¼: sio_open() ã«å¤±æ"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(空ã®å ´åãããã©ã«ãã«è¨å®ãã¾ã)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Sndio ã¨ã©ã¼: sio_setpar() ã«å¤±æ"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Sndio ã¨ã©ã¼: sio_start() ã«å¤±æ"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "楽æ²ã®å¤æ´éç¥"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "æ°ããæ²ãåçããã¨ãã«å®è¡ããã³ãã³ã"
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>ã·ã§ã«ã«æ¸¡ããããã©ã¡ã¼ã¿ã¯ã¯ã©ã¼ãã§ããã£ã¦ãã ãããã"
+"ãããªãå ´åãã»ãã¥ãªãã£ä¸ã®å±éºãããã¾ãã</span>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "ã³ãã³ã:"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>ã³ãã³ã</b>"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "æ²ã®åçãçµãã£ãã¨ãã«å®è¡ããã³ãã³ã"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "æ°ããæ²ã®åçæã«å®è¡ããã³ãã³ã:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "ãã¬ã¤ãªã¹ãã®æå¾ã«å°éããã¨ãã«å®è¡ããã³ãã³ã"
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "æ²ã®çµäºæã«å®è¡ããã³ãã³ã:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "ãã¬ã¤ãªã¹ãã®çµäºæã«å®è¡ããã³ãã³ã:"
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"æ²ã®ã¿ã¤ãã«ãå¤ãã£ãã¨ãã«å®è¡ããã³ãã³ã (ãããã¯ã¼ã¯ã¹ããªã¼ã ã®ã¿ã¤ã"
-"ã«ãªã©)"
+"æ²ã¿ã¤ãã«ãæ¿ãã£ãã¨ãã«å®è¡ããã³ãã³ã (ãããã¯ã¼ã¯ã¹ããªã¼ãã³ã°ç¨):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3755,35 +4062,31 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"次ã®ãã©ã¼ãããæååã使ç¨ã§ãã¾ãã\n"
-"ãããã¯ãã³ãã³ããå¼ã°ããåã«ç½®æããã¾ãã\n"
-"ãã ãããã¬ã¤ãªã¹ãã®æå¾ã®æ²ã®å ´åãç¡æå³ãªãã®ãããã¾ã\n"
+"次ã®å½¢å¼ã®æååããã³ãã³ãå®è¡åã«è©ä¾¡ããããã®ã¨ãã¦ä½¿ç¨ãããã¨ãã§ãã¾"
+"ãï¼ãã®å
¨ã¦ããã¬ã¤ãªã¹ãã®æå¾ã®ã³ãã³ãã¨ãã¦æç¨ã§ããã¨ã¯éãã¾ãã"
+"ãï¼:\n"
"\n"
-"%F: ãµã³ããªã³ã°å¨æ³¢æ° (Hz)\n"
-"%c: ãã£ã³ãã«æ°\n"
+"%F: 卿³¢æ° (ãã«ã)\n"
+"%c: ãã£ãã«æ°\n"
"%f: ãã¡ã¤ã«å (ãã«ãã¹)\n"
-"%l: é·ã (ms)\n"
+"%l: é·ã (ããªç§)\n"
"%n ã¾ã㯠%s: æ²å\n"
-"%r: ãããã¬ã¼ã (bps)\n"
+"%r: ã¬ã¼ã (bps)\n"
"%t: ãã¬ã¤ãªã¹ãã®ä½ç½® (%02d)\n"
-"%p: åçä¸ãï¼ (1 or 0)\n"
+"%p: ç¾å¨åçä¸ãã©ãã (1 ã¾ã㯠0)\n"
"%a: ã¢ã¼ãã£ã¹ã\n"
"%b: ã¢ã«ãã \n"
-"%T: ãã©ãã¯å"
+"%T: ãã©ãã¯ã®ã¿ã¤ãã«"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>ã·ã§ã«ã«æ¸¡ããããã©ã¡ã¼ã¿ã¯ã¯ã©ã¼ãã§ããã£ã¦ãã ãããã"
-"ãããªãå ´åãã»ãã¥ãªãã£ä¸ã®å±éºãããã¾ãã</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "æ²ã®æ
å ± (Qt)"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "ã³ãã³ã"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX ãªãµã³ãã©ã¼"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3791,52 +4094,57 @@ msgid ""
"Based on Sample Rate Converter Plugin:\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
+"SoX ãªãµã³ãã©ã¼ãã©ã°ã¤ã³ for Audacious\n"
+"Copyright 2013 MichaÅ Lipski\n"
+"\n"
+"æ´¾çå
: ãµã³ããªã³ã°å¨æ³¢æ°ã³ã³ãã¼ã¿ãã©ã°ã¤ã³\n"
+"Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
-msgstr ""
+msgstr "é«é"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
-msgstr ""
+msgstr "ä½å質"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
-msgstr ""
+msgstr "é«å質"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
-msgstr ""
+msgstr "æé«å質"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
-msgstr ""
+msgstr "å質:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr ""
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "ãã³ãã¨ããã"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>ãã³ãã¨ããã</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "ãã³ã:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "ããã:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "ãã³ãã¨ããã"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "ã¹ãã¼ã¿ã¹ã¢ã¤ã³ã³"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "è¨å® (_T)"
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3851,42 +4159,42 @@ msgstr ""
"Copyright 2005-2007 Giacomo Lozito <james at develia.org>\n"
"Copyright 2010 MichaÅ Lipski <tallica at o2.pl>\n"
"\n"
-"This plugin provides a status icon, placed in\n"
-"the system tray area of the window manager."
+"ãã®ãã©ã°ã¤ã³ã¯ã¹ãã¼ã¿ã¹ã¢ã¤ã³ã³ã\n"
+"ã¦ã¤ã³ãã¦ããã¼ã¸ã£ãå®ããã·ã¹ãã ãã¬ã¤å
ã«è¡¨ç¤ºãã"
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>ãã¦ã¹ã¹ã¯ãã¼ã«ã¢ã¯ã·ã§ã³</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "é³éã®å¤æ´"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "åçæ²ã®å¤æ´"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>ãã®ä»ã®è¨å®</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "ãããã¢ããã¦ã£ã³ãã¦ãç¡å¹ã«ãã"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "ã·ã¹ãã ãã¬ã¤ã«åç´ãã"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "ä¸ã«ã¹ã¯ãã¼ã«ããããã¬ã¤ãªã¹ããé²ãã"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "ã¹ãã¼ã¿ã¹ã¢ã¤ã³ã³"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "ã¨ã¯ã¹ãã©ã¹ãã¬ãª"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3896,24 +4204,24 @@ msgstr ""
"\n"
"By Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>ã¨ã¯ã¹ãã©ã¹ãã¬ãª</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "ã¨ã¯ã¹ãã©ã¹ãã¬ãª"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "ãã¼ã³ã¸ã§ãã¬ã¼ã¿"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "ãã¼ã³ã¸ã§ãã¬ã¼ã¿: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3932,15 +4240,11 @@ msgstr ""
"ä¾:\n"
"tone://2000;2005 (2000Hz 㨠2005Hz ã®ãã¼ã³ãåçãã)"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "ãã¼ã³ã¸ã§ãã¬ã¼ã¿"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "ãã¼ã«ã«ã®é¤å»"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3962,13 +4266,13 @@ msgid ""
msgstr ""
"Audacious Ogg Vorbis ãã³ã¼ã\n"
"\n"
-"Based on the Xiph.org Foundation's Ogg Vorbis Plugin:\n"
+"æ´¾çå
: Xiph.org Foundation ã® Ogg Vorbis ãã©ã°ã¤ã³\n"
"http://www.xiph.org/\n"
"\n"
-"Original code by:\n"
+"å
ã®ã³ã¼ãã®ä½è
:\n"
"Tony Arcieri <bascule at inferno.tusculum.edu>\n"
"\n"
-"Contributions from:\n"
+"è²¢ç®è
:\n"
"Chris Montgomery <monty at xiph.org>\n"
"Peter Alm <peter at xmms.org>\n"
"Michael Smith <msmith at labyrinth.edu.au>\n"
@@ -3978,34 +4282,68 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis ãã³ã¼ã"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "%s ã®è©³ç´°"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"ã¿ã¤ãã«: %t\n"
+"ä½è
: %a\n"
+"ç±æ¥: %f\n"
+"ãã©ãã«ã¼: %T\n"
+"ã³ã¡ã³ã: %C\n"
+"ãããåå¼: %c\n"
+"ã¹ãã¬ãª: %s\n"
+"ã«ã¼ã: %l\n"
+"ããã卿³¢æ°: %F\n"
+"ãã¬ã¤ã¤å¨æ³¢æ°: %P\n"
+"å¹´: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX ãã³ã¼ã"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-"Sashnov Alexander <sashnov at ngs.ru> ã«ãã Vortex ãã¡ã¤ã«å½¢å¼ãã¬ã¤ã¤ã§"
-"ãã\\n\n"
-"Roman Sherbakov <v_soft at microfor.ru> ã® in_vtx.dll ãåºã«ãã¦ãã¾ãã\\n\n"
-"Audacious ã®å®è£
ã¯ãPavel Vymetalek <pvymetalek at seznam.cz> ãè¡ãã¾ããã"
+"Sashnov Alexander <sashnov at ngs.ru> ã«ãã Vortex ãã¡ã¤ã«å½¢å¼ãã¬ã¤ã¤ã§ãã\n"
+"Roman Sherbakov <v_soft at microfor.ru> ã® in_vtx.dll ãåºã«ãã¦ãã¾ãã\n"
+"Audacious ã¸ã®å®è£
ã¯ãPavel Vymetalek <pvymetalek at seznam.cz> ãè¡ãã¾ããã"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX ãã³ã¼ã"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack ãã³ã¼ã"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "éå¯é(ãã¤ããªãã)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "éå¯é"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4013,16 +4351,20 @@ msgid ""
msgstr ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
-"Some of the plugin code was by Miles Egan."
-
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack ãã³ã¼ã"
+"ãã©ã°ã¤ã³ã®ã³ã¼ãã®ä¸é¨ã¯ Miles Egan ãæ¸ãã"
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF ãã³ã¼ã"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>XSF ã®è¨å®</b>"
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "ãã¡ã¤ã«ã«è¨é²ããã¦ããåçæéãç¡è¦"
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "å
±æå¯è½ãª XML ãã¬ã¤ãªã¹ã (XSPF)"
diff --git a/po/ko.po b/po/ko.po
index 37a5a4b92ff0..7d720f2caca6 100644
--- a/po/ko.po
+++ b/po/ko.po
@@ -4,21 +4,21 @@
#
# Translators:
# ChoSeongWoo <syn333 at gmail.com>, 2008
-# Darkcircle <darkcircle.0426 at gmail.com>, 2013
-# Darkcircle <darkcircle.0426 at gmail.com>, 2012-2013
+# Seong-ho Cho <darkcircle.0426 at gmail.com>, 2013
+# Seong-ho Cho <darkcircle.0426 at gmail.com>, 2012-2013
# Jaegeum Choe <baedaron at hananet.net>, 2001
# Man-Yong Lee <yong at linuxkorea.co.kr>, 2000
# Sang-Jin Hwang <accel at accellinux.org>, 1999
-# Darkcircle <darkcircle.0426 at gmail.com>, 2012
-# Darkcircle <darkcircle.0426 at gmail.com>, 2012
-# Darkcircle <darkcircle.0426 at gmail.com>, 2012-2014
+# Seong-ho Cho <darkcircle.0426 at gmail.com>, 2012
+# Seong-ho Cho <darkcircle.0426 at gmail.com>, 2012
+# Seong-ho Cho <darkcircle.0426 at gmail.com>, 2012-2015
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-14 15:07+0000\n"
+"Last-Translator: Seong-ho Cho <darkcircle.0426 at gmail.com>\n"
"Language-Team: Korean (http://www.transifex.com/projects/p/audacious/"
"language/ko/)\n"
"Language: ko\n"
@@ -27,40 +27,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "모ë
¸"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "ì¤í
ë ì¤"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "ìë¼ì´ë"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "AAC (MP4) ëì½ë"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "AAC (Raw) ëì½ë"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib ì¬ì기)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "ìì°¨"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib ì¬ì기)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "ì림"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "ì림 ì¤ì ..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -70,11 +58,7 @@ msgstr ""
"\n"
"ì´ê¸°ì Adam Feakinê³¼ Daniel Stoddenì´ ìì±íìµëë¤."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "ì림"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -116,7 +100,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -156,7 +140,7 @@ msgstr ""
" ìë ìê°ì ì´ ëª
ë ¹ì ì¤íí©ëë¤.\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -180,382 +164,371 @@ msgstr ""
" ììì ì½ìì ì
ë ¥íê³ íìíë ¤ë\n"
" ê²½ì° ì í ë¨ì¶ë¥¼ ë르ììì¤."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "기ì ì림ì
ëë¤."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "ì¤ë ì½ìì..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "ì½ì ì리미"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "ììì¼"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "íìì¼"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "ììì¼"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "목ìì¼"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "ê¸ìì¼"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "í ìì¼"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "ì¼ìì¼"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "ì림 ì¤ì "
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "íì¸(_O)"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "ì·¨ì(_C)"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "ìê³"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "ë¤ì ìê°ì ì림(기본):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "ì"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "ë¤ì ìê°í ì¡°ì©í:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "ìê°"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "ë¶"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "ì림ì ì¸ë¦´ ë ì§ë¥¼ ì íí©ëë¤"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "ìì¼"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "기본ê°"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "ì¼"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "ì ì§ì ìë ë³í ìê°"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "ì´"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "ìë"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "ìì"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "ë"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "íì¬"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "ì¶ê° ëª
ë ¹"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "íì±í"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "ì¬ì 목ë¡(ì í)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "ì¬ì ëª©ë¡ ì íí기"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "ìµì
"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "ì´ ìµì
ì 무ìì ì미íëì?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "ëìë§"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "ì¨ë² íì§"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "ì¨ë² ìí¸(Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA ì¶ë ¥"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ì¤ë°ì´ì
ì¤ì© ALSA ì¶ë ¥ íë¬ê·¸ì¸\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"ALSA ë©ë´ì¼ì´ ì¶©ë¶í ëìì´ ëì§ ììì ë, ì½ë ì°¸ê³ ìê° ëì´ì¤ ALSA ì¶ë ¥ í"
+"ë¬ê·¸ì¸ NGì ì ììì¸ William Pitcockìê² ê°ì¬ë립ëë¤."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "기본 PCM ì¥ì¹"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "기본 ìë ì¡°ì 기 ì¥ì¹"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM ì¥ì¹:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "ìë ì¡°ì 기 ì¥ì¹:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "ìë ì¡°ì 기 ìì:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "ëë ì¸ íì
ì í¼íë©° ìì
"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI ì¬ì기)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-"ì¤ë°ì´ì
ì¤ì© ALSA ì¶ë ¥ íë¬ê·¸ì¸\n"
-"Copyright 2009-2012 John Lindgren\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
"\n"
-"ALSA ë©ë´ì¼ì´ ì¶©ë¶í ëìì´ ëì§ ììì ë, ì½ë ì°¸ê³ ìê° ëì´ì¤ ALSA ì¶ë ¥ í"
-"ë¬ê·¸ì¸ NGì ì ììì¸ William Pitcockìê² ê°ì¬ë립ëë¤."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA ì¶ë ¥"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI ì¬ì기)"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "기본 ê²ì¸ ê° ì¤ë³µ ì ì©:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "기본 íì± ì¤ë³µ ì ì©:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "기본 리ë²ë¸ ì¤ë³µ ì ì©:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "켬"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "기본 ì½ë¬ì¤ ì¤ë³µ ì ì©:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>ì¬ì</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "í¸ëì¤í¬ì¤:"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "ëë¼ ì¬íí¸:"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>ê³ ê¸</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "미ë íì¼ìì 주ì ì¶ì¶"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "미ë íì¼ìì ê°ì¬ ì¶ì¶"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>ì¬ì´ë í°í¸</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>ì ëì¬ì´ì </b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr "ìí 주íì:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - ì¬ì´ë í°í¸ íì¼ ì í"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "ì·¨ì(_C)"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "ì´ê¸°(_O)"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "íì¼ ì´ë¦"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "í¬ê¸°(ë°ì´í¸)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "ì´ë¦:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> 미ë ì ë³´ </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "íì:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "길ì´(ë°ë¦¬ì´):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "í¸ë ë²í¸:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "ê°ë³"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "ë¹ ë¥´ê¸°(BPM):"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "ë¹ ë¥´ê¸°(BPM, wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "ë°ì:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> 미ë 주ìê³¼ ê°ì¬ </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* ì´ ë¯¸ë íì¼ìë 주ìì´ ììµëë¤ *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* ì´ ë¯¸ë íì¼ìë ê°ì¬ê° ììµëë¤ *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "ë«ê¸°(_C)"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (ì못ë UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "AMIDI-Plug ì ë³´"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"모ëí MIDI ìì
ì¬ì기\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"Giacomo Lozito\n"
-"<james at develia.org>ê° ìì±í¨\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"ALSA API를 ì¢ ë ë°°ì°ê¸° ìí alsa-lib 문ìì\n"
-"ì ë§ ì¸ëª¨ìë aplaymidi, amixerë¼ë ì¢ì \n"
-"íë¡ê·¸ë¨ì ë§ë Clemens Ladisch, Jaroslav Kysela\n"
-"\n"
-"ê´ì°®ì 미ë í¤ë³´ë ë¡ê³ 를 ì¬ì©í ì ìê² í´ì¤\n"
-"Alfredo Spadafina\n"
-"\n"
-"ìí í
ì¤í¸ì ë§ì ëìì ì¤ Tony Vroon"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -565,152 +538,154 @@ msgid ""
"Based in part on Evan Martin's Ghosd library:\n"
"http://neugierig.org/software/ghosd/"
msgstr ""
+"ì¤ë°ì´ì
ì¤ OSD\n"
+"http://www.develia.org/projects.php?p=audacious#aosd\n"
+"\n"
+"Giacomo Lozito <james at develia.org>ê° ìì±\n"
+"\n"
+"Evan Martin's Ghosd ë¼ì´ë¸ë¬ë¦¬ ì¼ë¶ë¥¼ 기ë°ì¼ë¡ í¨:\n"
+"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (íë©´ì íì)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ì¬ê°í"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "모ìë¦¬ê° ë¥ê·¼ ì¬ê°í"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "ì¤ëª©í ì¬ê°í"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "ìì"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "ì¬ì ìì"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "ì¬ì 목ë¡ì í목ì ì¬ìí ë OSD를 ììí©ëë¤."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "ì 목 ë°ê¾¸ê¸°"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"ì¬ìí ë OSD를 ììíë©´ 곡 ì 목ì ë°ëì§ë§ íì¼ ì´ë¦ì ê·¸ëë¡ ì
ëë¤. ì¸í°"
-"ë· ì¤í¸ë¦¼ì ì 목ì ë°ê¾¸ì´ì ë³´ì¬ì¤ ëë¶ë¶ì ê²½ì°ì ì ì©í©ëë¤."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "ì¼ì ì ì§ íì±í"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "ì¬ìì ë©ì¶ìì ë OSD를 ììí©ëë¤."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "ì¼ì ì ì§ íì±í"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "ë©ì¶°ì§ ì¬ì ìíìì ë³µê·í ë OSD를 ììí©ëë¤."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "ìì¹"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "ìë X ì¤íì
:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "ìë Y ì¤íì
:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "ìµë OSD í:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "ë¤ì¤ 모ëí° ìµì
"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "OSD ì¬ì©ì¤ íì:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "모ë 모ëí°"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "%ië² ëª¨ëí° "
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "íì´ë°(ë°ë¦¬ì´)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "ëì¤íë ì´:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "ëíë´ê¸° ìê°:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "ì¬ë¼ì§ê¸° ìê°:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "ê¸ê¼´"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "%ië² ê¸ê¼´:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "ìëì°"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "íí ë°©ì"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "ì"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "%ië² ì:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "í¸ë¦¬ê±° íì±í"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "ì´ë²¤ë"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "í©ì± ê´ë¦¬ì를 ìì íìµëë¤"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -720,112 +695,112 @@ msgstr ""
"ì ì´ë íëê° ì¤íì¤ì¸ì§ ìì§ ëª»íë¤ë©´, í©ì± ê´ë¦¬ì를 íì±í í´ ì£¼ììì¤. ê·¸"
"ë ì§ ìì¼ë©´ OSDê° ì ëë¡ ëìíì§ ììµëë¤"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "í¬ëª
ë ìì´ê¸°ì í©ì± ê´ë¦¬ìê° íìíì§ ììµëë¤"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "í¬ëª
ë"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "í¬ëª
ë ìì´ê¸°"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "ì¤ì í¬ëª
ë ( X í©ì± íì¥ì´ íìí©ëë¤ )"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "í©ì± íì¥ì ë¶ë¬ì¤ì§ ìììµëë¤"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "í©ì± íì¥ì ì¬ì©í ì ììµëë¤"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>ì¤ë°ì´ì
ì¤ OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "ì¤ë°ì´ì
ì¤ OSD - ì¤ì "
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "ìí(_T)"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "ì¤ì (_S)"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "ìì¹"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "ì ëë©ì´ì
"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "ê¸ì"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "ì¥ì"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "í¸ë¦¬ê±°"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "기í"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "ASXv3 ì¬ì 목ë¡"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 ì¬ì 목ë¡"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "ì¤ë°ì´ì
ì¤ ì¬ì 목ë¡(audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>ì</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "í림ì²ë¦¬ ì¤ì½í"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "ì¤ì 목ë¡:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "í¼ë ìì¤:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "주íì ìë¼ë´ê¸°:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "ì¤ì 목ë¡:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "ì¤íí¸ë¼ ë¶ì기"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "ì¤ëì¤ CD íë¬ê·¸ì¸"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -845,171 +820,156 @@ msgstr ""
"\n"
"ì´ íë¡ì í¸ë GSoC 2007ìì ë§ë¤ììµëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>ì¥ì¹</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "ì½ê¸° ìë:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "ì¥ì¹ ëì²´:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>ë©íë°ì´í°</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "CD-Text ì¬ì©í기"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "CDDB ì¬ì©í기"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "CDDBP ëì HTTP ì¬ì©í기"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "ìë²:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "ê²½ë¡:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "í¬í¸:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "ì¤ëì¤ CD íë¬ê·¸ì¸"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "cdio íì ìì¤í
ì ì´ê¸°ííëë° ì¤í¨íìµëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "ì못ë %s URI ì
ëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "%d í¸ëì´ ììµëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "%d í¸ëì ë°ì´í° í¸ëì
ëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "ì¤ëì¤ ì¶ë ¥ì ì¬ëë° ì¤í¨íìµëë¤."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "ì¤ëì¤ CD ì½ëì¤ ì¤ë¥ê° ë°ìíìµëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "ì¤ëì¤ CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "í¸ë %dë²"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "%s CD ì¥ì¹ë¥¼ ì¬ëë° ì¤í¨íìµëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "ì¤ëì¤ë¥¼ ì¬ìí ì ìë CD ëë¼ì´ë¸ê° ììµëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "ì´ë ¤ ìë CD ëë¼ì´ë¸ ì´ê¸°í를 ëë´ëë° ì¤í¨íìµëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "첫ë²ì§¸/ë§ì§ë§ í¸ë ë²í¸ë¥¼ ê²ìíëë° ì¤í¨íìµëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "%dë² í¸ëì ëí ìì/ë LSNì ì½ì ì ììµëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "cddb ì°ê²°ì ë§ëëë° ì¤í¨íìµëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "CDDB ìë²ì ìì²íëë° ì¤í¨íìµëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "CDDB ìë²ì ìì²íëë° ì¤í¨íìµëë¤: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "cddb ì 보를 ì½ëë° ì¤í¨íìµëë¤: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "ëë¼ì´ë¸ê° ë¹ì´ ììµëë¤."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "ì§ìíì§ ìë ëì¤í¬ íìì
ëë¤."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "ì¤ëì¤ CD ë©ë´ í목"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "CD ì¬ì"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "CD ì¶ê°"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "ì¤ëì¤ CD ë©ë´ í목"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>ìì¶</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "ì¤ì ìë:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "ëì ë²ì:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"ì¤ë°ì´ì
ì¤ì© ëì ë²ì ìì¶ íë¬ê·¸ì¸\n"
-"Copyright 2010-2012 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "ëì ë²ì ìì¶"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1025,205 +985,224 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ì ì:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "ê³ ì:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "ì¸ë¦¼:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "기본 곡 길ì´:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>리ìíë§</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "ì¤ëì¤ ë¦¬ìíë§ íì±í"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "리ìíë§ ì£¼íì:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "SPC íê·¸ì ê¸¸ì´ ë¬´ì"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "리ë²ë¸ ì¦ê°"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "ê²ì ì½ì ìì
ëì½ë"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-"ê³¡ì´ ë¤ë¥¸ ì±ë ì를 ê°ì§ê³ ìì´ í¬ë¡ì¤íì´ë©ì ì¤í¨íìµëë¤. ì±ë 믹ì를 ì¬ì©"
-"íì¬ ëì¼í ì±ë ì를 ê°ì§ëë¡ ê³¡ì ë³íí ì ììµëë¤."
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-"ê³¡ì´ ë¤ë¥¸ ìí 주íì를 ê°ì§ê³ ìì´ í¬ë¡ì¤íì´ë©ì ì¤í¨íìµëë¤. ìí 주íì "
-"ë³í기를 ì¬ì©íì¬ ëì¼í ìí 주íì를 ê°ì§ëë¡ ê³¡ì ë³í í ì ììµëë¤."
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"ì¤ë°ì´ì
ì¤ì© êµì°¨ íì´ë íë¬ê·¸ì¸\n"
-"Copyright 2010-2012 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>í¬ë¡ì¤íì´ë</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "ì¤ë²ë©:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "í¬ë¡ì¤íì´ë"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"ê³¡ì´ ë¤ë¥¸ ì±ë ì를 ê°ì§ê³ ìì´ í¬ë¡ì¤íì´ë©ì ì¤í¨íìµëë¤. ì±ë 믹ì를 ì¬ì©"
+"íì¬ ëì¼í ì±ë ì를 ê°ì§ëë¡ ê³¡ì ë³íí ì ììµëë¤."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"ê³¡ì´ ë¤ë¥¸ ìí 주íì를 ê°ì§ê³ ìì´ í¬ë¡ì¤íì´ë©ì ì¤í¨íìµëë¤. ìí 주íì "
+"ë³í기를 ì¬ì©íì¬ ëì¼í ìí 주íì를 ê°ì§ëë¡ ê³¡ì ë³í í ì ììµëë¤."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>í¬ë¦¬ì¤í¸ë¼ì´ì </b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "ê°ë:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "í¬ë¦¬ì¤í¸ë¼ì´ì "
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "í ìí¸ íë¬ê·¸ì¸"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "íì¼ ìì "
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "%sì(를) í´ì§íµì¼ë¡ ì´ëíë ì¤ ì¤ë¥: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "%sì(를) ìì íë ì¤ ì¤ë¥: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "%sì(를) ìì íë ì¤ ì¤ë¥: ë¡ì»¬ íì¼ì´ ìëëë¤."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "ì íí íì¼ì í´ì§íµì¼ë¡ ì´ëíìê² ìµëê¹?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "í´ì§íµì¼ë¡ ì´ë"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "ì íí íì¼ì ìì í ìì íìê² ìµëê¹?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "ìì "
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "ì·¨ì"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "íì¼ ìì "
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "ì íí íì¼ ìì "
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>ìì ë°©ì</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "ì¦ì ìì íë ëì í´ì§íµì¼ë¡ ì´ë"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>ì¸ë¦¼</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "ì§ì°:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "ë°í¥:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "ìë:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"ìì½ íë¬ê·¸ì¸\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "ì¸ë¦¼"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg íë¬ê·¸ì¸"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1239,55 +1218,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg íë¬ê·¸ì¸"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "FileWriter íë¬ê·¸ì¸"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "ì¶ë ¥ íì¼ íì:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "ì¤ì í기"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "ì본 ëë í°ë¦¬ì ì ì¥"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "ì¬ì©ì ì ì ëë í°ë¦¬ì ì ì¥"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "ì¶ë ¥ íì¼ í´ë:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "í´ë ì íí기"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "ë¤ìì¼ë¡ë¶í° íì¼ ì´ë¦ ê°ì ¸ì¤ê¸°:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "ì본 íì¼ íê·¸"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "ì본 íì¼ ì´ë¦"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "íì¼ ì´ë¦ íì¥ì를 ë¹¼ì§ ì기"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "í¸ë ë²í¸ë¥¼ íì¼ ì´ë¦ì¼ë¡ ê°ì£¼í기"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1316,165 +1295,169 @@ msgstr ""
"ë§ì½ ì¬ë³¸ì´ ìë¤ë©´ ìì ìíí¸ì¨ì´ ì¬ë¨ì ìì²íììì¤.\n"
"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "FileWriter íë¬ê·¸ì¸"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "ìë"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "íµí© ì¤í
ë ì¤"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "ì¤í
ë ì¤"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "모ë"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 ì¤ì "
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "íì¸(_O)"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "ìê³ ë¦¬ì¦ íì§:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
msgstr "ì¶ë ¥ ìí 주íì:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "ë¹í¸ì ì¡ì¨ / ìì¶ì¨:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "ë¹í¸ ì ì¡ë¥ /ìì¶ì¨:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ë¹í¸ì ì¡ì¨(kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "ìì¶ì¨:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "ì¤ëì¤ ëª¨ë:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "기í:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
msgstr "ì격í ISO ê·ê²© ê°ì "
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "ì¤ë¥ ë°©ì§"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "ìì§"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "VBR/ABR íì±í"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "íì:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR ìµì
:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "ìµì ë¹í¸ë ì´í¸(kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "ìµë ë¹í¸ë ì´í¸(kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "ìµì ë¹í¸ì ì¡ì¨ì ì² ì íê² ê°ì "
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR ìµì
:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "íê· ë¹í¸ì ì¡ì¨(kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR ìì§ ìì¤:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Xing VBR í¤ë 기ë¡íì§ ì기"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "íë ì ì¸ì:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr "íë ì 매ê°ë³ì:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Copyrightë¡ íì"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "ì본ì¼ë¡ íì"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ID3 ì¸ì:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr "ID3 매ê°ë³ì:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "ë²ì 2 íê·¸ ì¶ê°ì¬í ê°ì "
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "v1 íê·¸ë§ ì¶ê°"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "v2 íê·¸ë§ ì¶ê°"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "íê·¸"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis ì¸ì½ë ì¤ì "
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "ìì§ ìì¤(0-10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC ëì½ë"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "무ìì¤"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1486,11 +1469,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC ëì½ë"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1498,11 +1477,19 @@ msgstr ""
"ì¤ë°ì´ì
ì¤ì© GIO íë¬ê·¸ì¸\n"
"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO íë¬ê·¸ì¸"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "ì못ë ì´ê¸° 모ë"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1522,533 +1509,610 @@ msgstr ""
"\n"
"ë¼ì´ì ì¤: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL ì¤íí¸ë¼ ë¶ì기"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "ê·¸ë ë°ë¡ê°ê¸°"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-"ê·¸ë ë°ë¡ ê°ê¸° íë¬ê·¸ì¸\n"
-"ê·¸ë ë°ë¡ ê°ê¸°ë¥¼ íµí´ ì¬ì기를 ì ì´í ì ìê² í´ì¤ëë¤.\n"
+"ê·¸ë ë°ë¡ê°ê¸° íë¬ê·¸ì¸\n"
+"ê·¸ë ë°ë¡ê°ê¸°ë¡ íë ì´ì´ë¥¼ ì ì´í ì ììµëë¤.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "ê·¸ë ë°ë¡ ê°ê¸°"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "í목 ë²í¸"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "ì 목"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "ìì
ê°"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "ì°ë"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "ì¨ë²"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "ì¨ë² ìì
ê°"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "í¸ë"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "ì¥ë¥´"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "ë기 ëª©ë¡ ìì¹"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "길ì´"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "íì¼ ê²½ë¡"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "íì¼ ì´ë¦"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "ì¬ì©ì ì ì ì 목"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ë¹í¸ ì ì¡ì¨"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "ì¡´ì¬íë ë´ì©"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "íìí ë´ì©"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "ê²ì ë구"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "ì¼í¸ì ë¶ì´ê¸°"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "ì¤ë¥¸í¸ì ë¶ì´ê¸°"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "ìë¨ì ë¶ì´ê¸°"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "íë¨ì ë¶ì´ê¸°"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "ë¼ì´ë´ê¸°"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "ë¹íì±í"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "ê²ì ë구"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "íì¼ ì´ê¸°(_O) ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "URL ì´ê¸°(_U) ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "íì¼ ì¶ê°(_A) ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "URL ì¶ê°(_R) ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "ë¼ì´ë¸ë¬ë¦¬ ê²ì(_L)"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "ì ë³´(_B) ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "ì¤ì (_S)..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "ëë´ê¸°(_Q)"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "ì¬ì(_P)"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "ì¼ìì ì§(_E)"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "ì ì§(_S)"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "ì´ì (_V)"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "ë¤ì(_N)"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "ë°ë³µ(_R)"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "ë¤ì기(_H)"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "ì¬ì ëª©ë¡ ë¯¸ë¦¬ ìë¦¬ì§ ìì(_O)"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "ì´ ë
¸ë ë¤ì ë©ì¶¤(_F)"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "곡 ì ë³´(_I) ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "ìê° ê±´ëë°ê¸°(_T) ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "곡 ê±´ëë°ê¸°(_J) ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "ë°ë³µ ìì A ì¤ì (_A)"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "ë°ë³µ ìì B ì¤ì (_B)"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "ë°ë³µ ìì ì§ì°ê¸°(_C)"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "ì 목ì(_T)"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr "íì¼ ì´ë¦ì(_F)"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "íì¼ ê²½ë¡ ì(_P)"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "í¸ë ë²í¸ì(_N)"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "ìì
ê° ì´ë¦ì(_A)"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "ì¨ë² ì´ë¦ì(_B)"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "ì¨ë² ì곡ê°ì(_M)"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "ì¶ì ì¼ìì(_D)"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "ì¥ë¥´ì(_G)"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "길ì´ì(_L)"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "íì¼ ê²½ë¡ì(_F)"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "ì¬ì©ì ì ì ì 목ì(_C)"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "ìì ë¤ì§ê¸°(_E)"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "ìì ìì(_R)"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "ì´ ì¬ì ëª©ë¡ ì¬ì(_P)"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "ì¬ì/ë³µê·(_P)"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "ìë¡ ê³ ì¹¨(_R)"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "ì ë ¬(_S)"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "ì íí í목 ì ë ¬(_L)"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "ì¤ë³µ ì ê±°(_D)"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "ì¬ì©í ì ìë íì¼ ì ê±°(_U)"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "ì íì¼(_N)"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "ì´ë¦ ë°ê¾¸ê¸°(_A)..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "ì ê±°(_V)"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "ê°ì ¸ì¤ê¸°(_I) ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "ë´ë³´ë´ê¸°(_E) ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "ì¬ì ëª©ë¡ ê´ë¦¬ì(_M) ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "ë기 ëª©ë¡ ê´ë¦¬ì(_Q) ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "ìë í¬ê²(_U)"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "ìë ìê²(_D)"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "ì´íë¼ì´ì (_E)"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "í¨ê³¼(_F)..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "ë©ë´ íìì¤ íì(_M)"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "ì ë³´ íìì¤ íì(_N)"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "ì ë³´ íìì¤ ìê°í íì(_U)"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "ìí íìì¤ íì(_S)"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "ë¨ì ìê° íì(_R)"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "ìê°í(_V)..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "íì¼(_F)"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "ì¬ì(_P)"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "ì¬ì 목ë¡(_L)"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "ìë¹ì¤(_S)"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "ì¶ë ¥(_O)"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "보기(_V)"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "ë기 목ë¡ì ë£ê¸°/빼기(_Q)"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "ìì
í¬í¨ í´ë ì´ê¸°(_O)"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "ìë¼ë´ê¸°(_T)"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "ë³µì¬(_C)"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "ë¶ì¬ë£ê¸°(_P)"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "모ë ì í(_A)"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "ì´ë¦ ë°ê¾¸ê¸°(_R) ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>ì¬ì ëª©ë¡ í</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "íì í íì"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "í목 ê°¯ì íì"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "ë«ê¸° ë¨ì¶ íì"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>ì¬ì ëª©ë¡ ë´ì©</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "ë´ì© í¤ë íì"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>기í</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
-msgstr ""
+msgstr "íì´í í¤ë¡ íì:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "곡 ë°ë ë ì¤í¬ë¡¤"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK ì¸í°íì´ì¤"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - ì¤ë°ì´ì
ì¤"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ë²í¼ë§ ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "ì¤ë°ì´ì
ì¤"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "모ë
¸"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "ì¤í
ë ì¤"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "ì±ë %dê°"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "ì±ê¸ 모ëì
ëë¤."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "ì¬ì ëª©ë¡ ëª¨ëì
ëë¤."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "곡 ì¬ì í ë©ì¶ë ì¤ì
ëë¤."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "ì´ì í¸ë"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "ì¬ì"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "ì¼ì ì ì§/ì¬ê°"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "ì ì§"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "ë¤ì í¸ë"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "5ì´ ë¹¨ë¦¬ê°ê¸°"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "5ì´ ëê°ê¸°"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "ììê±°"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "ìë ì¦ê°"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "ìë ê°ì"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "íì¼ë¡ ê±´ëë°ê¸°"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "ì¬ì ì°½ ì í"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "íë©´ì íì ë³´ì´ê¸°"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "ë°ë³µ ì í"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "ììì¬ì ì í"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "íì¬ ê³¡ ì´í ë©ì¶¤ì¬ë¶ ì í"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "ì¬ì ì°½ ë³µê·"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(ìì)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2059,15 +2123,11 @@ msgstr ""
"\n"
"ê³ì ì§ííìê² ìµëê¹?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "ë§ì°ì¤ ë¨ì¶ ë°ì¸ë©í기"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "ì ì ë¨ì¶í¤ íë¬ê·¸ì¸ ì¤ì "
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2075,23 +2135,27 @@ msgstr ""
"í
ì¤í¸ íëìì í¤ ì¡°í©ì ë르ììì¤.\n"
"ë§ì°ì¤ ë¨ì¶ë ë£ì ì ììµëë¤."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "ë¨ì¶í¤:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>ëì:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>í¤ ë°ì¸ë©:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "ì¶ê°(_A)"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "ì ì ë¨ì¶í¤"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2117,60 +2181,51 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "ì ì ë¨ì¶í¤"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK ì¶ë ¥"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "ì¡´ì¬íë 모ë Jack í¬í¸ì ì°ê²°"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "ì¶ë ¥ í¬í¸ë¡ ìë ì°ê²°"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "ì¶ë ¥ í¬í¸ìë§ ì°ê²°"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "ì´ë¤ í¬í¸ìë ì°ê²°íì§ ìì"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "ì°ê²° ë°©ì:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "ëë²ê¹
ì¶ë ¥ íì±í"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"xmms-jack 기ë°. by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK ì¶ë ¥"
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s ì¤ì "
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA í¸ì¤í¸ ì¤ì "
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "모ë ê²½ë¡:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2180,25 +2235,25 @@ msgstr ""
"ì´ ê²½ë¡ë¥¼ LADSPA_PATHììë ì°¾ììµëë¤.\n"
"ì íë¬ê·¸ì¸ì ê²ìíë ¤ë©´ ì ê²½ë¡ë¥¼ ì¶ê°íê³ Enter í¤ë¥¼ ë르ììì¤.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "ì¬ì©í ì ìë íë¬ê·¸ì¸:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "íì±í"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "íì±íí íë¬ê·¸ì¸:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "ì¤ì "
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2206,47 +2261,15 @@ msgstr ""
"ì¤ë°ì´ì
ì¤ì© LADSPA í¸ì¤í¸\n"
"Copyright 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA í¸ì¤í¸"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: LIRC ì§ìì ì´ê¸°í í ì ììµëë¤\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: LIRC ì¤ì íì¼ì ì½ì ì ììµëë¤\n"
-"%s: ì ë¹í ì¤ì íì¼ì ì´ë»ê² ë§ëëì§\n"
-"%s: LIRC 문ì를 ì½ì´ì£¼ììì¤\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: ë¤ì ì°ê²° ìë ì¤...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: ì ì ìë ëª
ë ¹ \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: LIRCë¡ë¶í° ëì´ì¡ìµëë¤\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: 매 %d ì´ í ë¤ì ì°ê²°ì ìëí©ëë¤...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC íë¬ê·¸ì¸"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2273,73 +2296,81 @@ msgstr ""
"\n"
"LIRCì ëí ìì¸í ë´ì©ì, http://lirc.org를 ë³´ììì¤."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>ì°ê²°</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "LIRC ìë²ì ë¤ì ì°ê²°"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "ë¤ì ì°ê²°í기 ì ì ë기ì¤:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC íë¬ê·¸ì¸"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki íë¬ê·¸ì¸"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "ê°ì¬ê° ììµëë¤."
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "ì¤ë¥"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "%sì(를) ê°ì ¸ì¬ ì ììµëë¤"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "ì¤ë¥"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "%sì(를) í´ìí ì ììµëë¤"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "ê°ì¬ ê²ìì¤..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "곡 ë©íë°ì´í°ê° ë¹ ì¡ìµëë¤"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "lyrics.wikia.comì ì°ê²° ì¤..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki íë¬ê·¸ì¸"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U ì¬ì 목ë¡"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Tact ìì±ê¸°"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Tact ìì±ê¸°: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Tact ìì±ê¸°: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2353,11 +2384,11 @@ msgstr ""
"ì¬ì© ì) tact://77ì ë¶ë¹ 77 ë¹í¸\n"
"ëë tact://60*3/4ë 3/4 tactìì ë¶ë¹ 60 bpm"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Tact ìì±ê¸°"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "ì±ë 믹ì"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2365,152 +2396,184 @@ msgstr ""
"ì¤ë°ì´ì
ì¤ì© ì±ë ìë ì¡°ì 기 íë¬ê·¸ì¸\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>ì±ë 믹ì</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "ì¶ë ¥ ì±ë:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "ì±ë 믹ì"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS íë¬ê·¸ì¸"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (모ë ì¬ì기)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>ë 졸루ì
</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8ë¹í¸"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16ë¹í¸"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>ì±ë</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "ê·¼ì (ê°ì¥ ë¹ ë¦)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "ì í(ë¹ ë¦)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "ì¤íë¼ì¸(ì¢ì)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "ë¤ì¤ íì´ì¤(ìµì)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>ìí 주íì</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "ë 벨:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "ì»·-ì¤í:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>리ë²ë¸</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>ì ì ì¦í</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>ìë¼ì´ë</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>í리ì°í</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "ì¤ë²ìíë§"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "ë
¸ì´ì¦ ê°ì"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Amiga MOD ì¬ì"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>ë°ë³µ</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "ë°ë³µ íì:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "ê³ì ë°ë³µíë ¤ë©´ ë°ë³µ íì를 -1ë¡ ì¤ì íììì¤."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (모ë ì¬ì기)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "ìë¼ì´ë"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 íë¬ê·¸ì¸"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>ê³ ê¸</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "ìë¼ì´ë"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 ìë²"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS íë¬ê·¸ì¸"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "ì ì ìë HTTP ì¤ë¥"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "URL í´ì ì¤ë¥"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "ì ì§í¨"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "ì¤ë°ì´ì
ì¤ê° ì¬ìì¤ì´ ìëëë¤."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "ë°ì¤í¬í± ì림"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2544,55 +2607,64 @@ msgstr ""
"ì´ íë¡ê·¸ë¨ê³¼ í¨ê» GNU ì¼ë° ê³µì¤ ì¬ì© íê°ì ì¬ë³¸ì ë°ìì¼ í©ëë¤. ë§ì½ ì¬ë³¸"
"ì´ ìë¤ë©´ <http://www.gnu.org/licenses/> ë§í¬ë¥¼ 참조íììì¤."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "ì¬ì 컨í¸ë¡¤ íì"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "íì ì림 íì"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "ë°ì¤í¬í± ì림"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "ë³´ì´ê¸°"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "ì¼ì ì ì§"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "ë¤ì"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. 기본 ì¥ì¹"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 ì¶ë ¥"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "OSS3 ì¶ë ¥"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "기본 ì¥ì¹"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "ì¤ëì¤ ì¥ì¹:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "ëì²´ ì¥ì¹ ì¬ì©:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "ê° ì¸ì
ì 볼륨ì ì ì¥í©ëë¤."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "OSS ìíí¸ì¨ì´ê° ë§ëë í ë³íì íì±í í©ëë¤."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "ê°ì 믹ì±ì ë§ë ë² íì 모ë를 íì±í í©ëë¤."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2606,19 +2678,35 @@ msgstr ""
"#audacious ì±ë ì¬ë, í¹í Tony Vroon, John Lindgren, ì´ì ì OSS íë¬ê·¸ì¸ì "
"ë§ë ì ììë¶ê» ê°ì¬ëë¦¬ê³ ì¶ìµëë¤."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 ì¶ë ¥"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "ì¬ì ëª©ë¡ ê´ë¦¬ì"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "í목"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "ì ê±°(_R)"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "ì´ë¦ ë°ê¾¸ê¸°(_A)"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS ì¬ì 목ë¡"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2 ëì½ë"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio ì¶ë ¥"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2651,11 +2739,73 @@ msgstr ""
"ë§ì½ ì¬ë³¸ì´ ìë¤ë©´ ìì ìíí¸ì¨ì´ ì¬ë¨ì ìì²íììì¤.\n"
"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio ì¶ë ¥"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "QtMultimedia ì¶ë ¥"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"ì¤ë°ì´ì
ì¤ì© QtMultimedia ìì± ì¶ë ¥ íë¬ê·¸ì¸\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"ì¤ë°ì´ì
ì¤ì© SDL ì¶ë ¥ íë¬ê·¸ì¸ 기ë°ì\n"
+"Copyright 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "ëìì¤ ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "ê²ì"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "í´ë ì´ê¸°(_O)..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "í´ë ì¶ê°(_A)..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "ë¡ê·¸ ê°ì기(_L)..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "íì¼ ì´ê¸°"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "íì¼ ì¶ê°"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ì´ì "
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "ë°ë³µ"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "ë¤ì기"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Qt ì¸í°íì´ì¤"
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "ìí 주íì ë³í기"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2663,97 +2813,105 @@ msgstr ""
"ì¤ë°ì´ì
ì¤ì© ìí 주íì ë³í íë¬ê·¸ì¸\n"
"Copyright 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "ìí ê±´ëë°ê¸°/ë°ë³µí기"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "ì í ë³´ê°"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "ë¹ ë¥¸ sincí¨ì ë³´ê°"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "ì¤ê° sincí¨ì ë³´ê°"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "ìµìì sincí¨ì ë³´ê°"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>ë³í</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "ë°©ì:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "주íì:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>주íì 매í</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "주íì 매í ì¬ì©í기"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "ìí 주íì ë³í기"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "ë¤. %s ì¬ì©ìì ì¤í¬ë¡ë¸ë§ì ì§íí©ëë¤"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "ê¶íì´ ê±°ë¶ëììµëë¤"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"ì¬ì í목ì ì¤ë°ì´ì
ì¤ìì ì¤í¬ë¡¤ íëë¡ íë ¤ë©´ ë¤ì ì°ê²°ì 방문íììì¤:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr "ì´ ì°½ì ì° ìíë¡ ë¤ì 'ê¶í íì¸'ì ë르ììì¤.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2761,32 +2919,36 @@ msgstr ""
"ê±±ì íì§ ë§ììì¤. ì¤í¬ë¡ë¸ì ì»´í¨í°ì ì ì¥íìµëë¤.\n"
"ì¤ë°ì´ì
ì¤ê° ëìí ì ìëëë¡ ë°ë¡ ì ì¶í©ëë¤."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "ë¤í¸ìí¬ì 문ì ê° ììµëë¤."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "Last.fmì ì°ê²°íëë° ë¬¸ì ê° ììµëë¤. ë¤ì ìëí´ ì£¼ììì¤."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "íì¸ì¤..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "ê¶í íì¸(_H)"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "ê¶í ì·¨ì(_R)"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr "ì¤ë°ì´ì
ì¤ê° Last.fm ê³ì ì í¸ëì ì¶ì¶í ì ìê² í´ì¼ í©ëë¤.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "ì¤í¬ë¡ë¸ë¬ 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2794,7 +2956,7 @@ msgstr ""
"ì¤í¬ë¡ë¸ë¬ íë¬ê·¸ì¸ì ììí ì ììµëë¤.\n"
"ì¤ì¹ì 문ì ê° ìë ê² ê°ìµëë¤."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2811,11 +2973,7 @@ msgstr ""
"ì´ íë¡ì í¸ë¥¼ ììíëë° ëìì ì¤ John Lindgrenìê² ê°ì¬ë립ëë¤.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "ì¤í¬ë¡ë¸ë¬ 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2823,7 +2981,11 @@ msgstr ""
"Audaciousê° ì´ì ë¶í° Last.fm ì¤í¬ë¡ë¸ë¬ ê°ì ë²ì ì ì¬ì©ì¤ì
ëë¤.â\n"
"ì¤í¬ë¡ë¸ë¬ íë¬ê·¸ì¸ì 기본 ì¤ì ì íì¸íììì¤."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL ì¶ë ¥"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2831,74 +2993,53 @@ msgstr ""
"ì¤ë°ì´ì
ì¤ì© SDL ì¶ë ¥ íë¬ê·¸ì¸\n"
"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL ì¶ë ¥"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "ë¼ì´ë¸ë¬ë¦¬"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "ì ì ìë ìì
ê°"
+#: src/search-tool/search-tool.cc:394
+#, c-format
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "ê²°ê³¼ %dê°"
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "ì ì ìë ì¨ë²"
+#: src/search-tool/search-tool.cc:400
+#, c-format
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(ì¨ê¸´ í목 %dê°)"
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "ë
¸ë %d곡"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ": ì´ ì¥ë¥´ì í´ë¹"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
msgstr ""
-"%3$sì\n"
-"%2$sì ìë %1$s"
-#: src/search-tool/search-tool.c:631
-#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "ì¨ë² %dê°"
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, 곡 %dê°"
-
-#: src/search-tool/search-tool.c:639
-#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%1$s\n"
-"%3$sì 곡 %2$dê°\t"
-
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "ì¬ì ëª©ë¡ ë§ë¤ê¸°(_C)"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "ì¬ì ëª©ë¡ ì¶ê°í기(_A)"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "ë¼ì´ë¸ë¬ë¦¬ ê²ì"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2906,679 +3047,769 @@ msgstr ""
"ìì
ë¼ì´ë¸ë¬ë¦¬ë¥¼ ì¤ë°ì´ì
ì¤ë¡ ê°ì ¸ì¤ë ¤ë©´ í´ë를 ì ííê³ \"ìë¡ê³ 침\"ìì´ì½"
"ì ë르ììì¤."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "기ë¤ë ¤ 주ììì¤ ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "í´ë ì í"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "SID ì¬ì기"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>ì¶ë ¥</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "ì±ë:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>ì뮬ë ì´ì
</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "MOS 8580 ì뮬ë ì´ì
(기본: MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "칩 ëª¨ë¸ ìëì¼ë¡ ì ííì§ ë§ ê²"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "íí° ì뮬ë ì´ì
"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "í´ë¡ ìë:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "í´ë¡ ìë ìëì¼ë¡ ì ííì§ ë§ ê²"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>ì¬ì ìê°</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "ìµë ì¬ì ìê° ì¤ì :"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "곡 길ì´ë¥¼ ì ì ììëë§ ì¬ì©"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "ìµì ì¬ì ìê° ì¤ì :"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "íì¼ ì´ê¸°..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "URL ì´ê¸°..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "ë¼ì´ë¸ë¬ë¦¬ ê²ì"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "ì¬ì"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "ì¬ì 목ë¡"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "보기"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "ìë¹ì¤"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "ì ë³´..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "ì¤ì ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "ëë´ê¸°"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "곡 ì ë³´..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "ë°ë³µ"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "ë¤ì기"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "ì´ì ì¬ì목ë¡ì´ ììµëë¤"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "ì´ ê³¡ ë¤ì ë©ì¶¤"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ì´ì "
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "A-B ë°ë³µ ì¤ì "
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "A-B ë°ë³µ ì§ì°ê¸°"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "ì§ì 곡ì¼ë¡ ê±´ëë°ê¸°..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "ì§ì ìê°ì¼ë¡ ê±´ëë°ê¸°..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "ì´ ì¬ì ëª©ë¡ ì¬ì"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "ì¬ì/ì¬ê°"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "ì ì¬ì 목ë¡"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "ì¬ì ëª©ë¡ ì ê±°..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "ì¬ì ëª©ë¡ ì ê±°"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "ì´ì ì¬ì 목ë¡"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "ë¤ì ì¬ì 목ë¡"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "ì¬ì ëª©ë¡ ê°ì ¸ì¤ê¸°..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "ì¬ì ëª©ë¡ ë´ë³´ë´ê¸°..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "ì¬ì ëª©ë¡ ê´ë¦¬ì..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "í ê´ë¦¬ì..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "ì¬ì ëª©ë¡ ìë¡ ê³ ì¹¨"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "ì¬ì ëª©ë¡ í¸ì§ê¸° íì"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "ì´íë¼ì´ì íì"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "ë¨ì ìê° íì"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "íì ì"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "모ë ìì
ê³µê°ì íì"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "ì¬ì íë¡ê·¸ë¨ ë§ì ì¬ë¦¬ê¸°"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "ì¬ì ëª©ë¡ í¸ì§ê¸° ë§ì ì¬ë¦¬ê¸°"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "ì´íë¼ì´ì ë§ì ì¬ë¦¬ê¸°"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "ëë°° 길ì´"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "URL ì¶ê°..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "íì¼ ì¶ê°..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "ì 목ë³"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "íì¼ ì´ë¦ë³"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "íì¼ ê²½ë¡ì"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "모ë ì ê±°"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "ë기 ëª©ë¡ ì§ì°ê¸°"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "ì¬ì©í ì ìë íì¼ ì ê±°"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "ë³µì 본 ì ê±°"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "ì ííì§ ìì í목 ì ê±°"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "ì íí í목 ì ê±°"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "ê²ìíê³ ì í"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "ì í ë°ì "
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "ì ííì§ ìì"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "모ë ì í"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "ì¨ë² ì 목ì"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "í¸ë ë²í¸ì"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "ìì
ê°ì"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "ì¨ë² ì 목ì"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "ì¨ë² ìì
ê°ë³"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "ì¶ìì¼ìì"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "í¸ë ë²í¸ì"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "ì¥ë¥´ë³"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "길ì´ë³"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "ì§ì ì 목ë³"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "ëª©ë¡ ìì ë¤ì기"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "ëª©ë¡ ìì ë¤ì§ê¸°"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "ì íí í목 ì ë ¬"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "ëª©ë¡ ì ë ¬"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "ìë¼ë´ê¸°"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "ë³µì¬"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "ë¶ì¬ë£ê¸°"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "íì ë£ê¸°/íìì 빼기"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "ì¤ì ëª©ë¡ ë¶ë¬ì¤ê¸°..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "ìë ì¤ì ëª©ë¡ ë¶ë¬ì¤ê¸°..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "기본 ì¤ì ë¶ë¬ì¤ê¸°"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "ì¤ì ëª©ë¡ íì¼ ë¶ë¬ì¤ê¸°..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "EQF íì¼ ë¶ë¬ì¤ê¸°..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "ì¤ì ëª©ë¡ ì ì¥..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "ìë ì¤ì ëª©ë¡ ì ì¥..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "기본 ì¤ì ì ì¥"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "ì¤ì ëª©ë¡ íì¼ ì ì¥..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "EQF íì¼ ì ì¥..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "ì¤ì ëª©ë¡ ìì ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "ìë ì¤ì ëª©ë¡ ìì ..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "ìì°í ì¤ì ëª©ë¡ ê°ì ¸ì¤ê¸°..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "0 ê°ì¼ë¡ ì´ê¸°í"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winamp í´ëì ì¸í°íì´ì¤"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "ì ì¥"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "ë¶ë¬ì¤ê¸°"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "ì¤ì ëª©ë¡ íì¼ ë¶ë¬ì¤ê¸°"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "EQF íì¼ ë¶ë¬ì¤ê¸°"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "ì¤ì ëª©ë¡ íì¼ ì ì¥"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "EQF íì¼ ì ì¥"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "ìì°í ì¤ì ëª©ë¡ ë¶ë¬ì¤ê¸°"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "ì¤ì 목ë¡"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "ì¤ì ëª©ë¡ ë¶ë¬ì¤ê¸°"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "ìë ì¤ì ëª©ë¡ ë¶ë¬ì¤ê¸°"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "ì¤ì ëª©ë¡ ì ì¥"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "ìë ì¤ì ëª©ë¡ ì ì¥"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "ì¤ì ëª©ë¡ ìì "
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "ìë ì¤ì ëª©ë¡ ìì "
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "ì¬ì기(_P):"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "ì°ì£¼ì:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "주 ì¬ì기 ì°½ ê¸ê¼´ ì í:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "ì¬ì 목ë¡(_P):"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "ì¬ì목ë¡:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "ì¬ì ëª©ë¡ ê¸ê¼´ ì í:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>ì¤í¨</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>ê¸ê¼´</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "ë¹í¸ë§µ ê¸ê¼´ ì¬ì©(ìì¤í¤ ì ì© ì§ì)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "곡 ì 목 ì¤í¬ë¡¤"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "ìë°©í¥ì¼ë¡ 곡 ì 목 ì¤í¬ë¡¤"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "ë¶ì기"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "íì기"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "ë³´ì´ì¤ì¶ë ¥ / VU ë©í°"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "ë기"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "ë³´íµ"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "ë¶"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "ìíì "
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "ì "
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "ë§ë"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "ê°ì¥ ë리ê²"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "ë리ê²"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "ì¤ê°"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "ë¹ ë¥´ê²"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "ê°ì¥ ë¹ ë¥´ê²"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "ì "
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "ì "
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "ë©´"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "ì¼ì"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "ë¶ëë½ê²"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>ë°©ì</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "ìê°í ë°©ì:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>ë¶ì íë¡ê·¸ë¨</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "í¼í¬ íì"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "ìì ì ì©:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "ë°©ì:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "í´ ì¤í:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "ìµë í´ ì¤í:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "ì¤ì½í 모ìì:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "ë³´ì´ì¤ ì¶ë ¥ ìì ì ì©:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "VU ë©í° 모ìì:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "ì¼ë°"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "ìê°í"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "í리ì°í"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "ì¤ë°ì´ì
ì¤ ì´íë¼ì´ì "
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "%d íì:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "ìë: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "ê· í: %d%% ì¼ìª½"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "ê· í: ê°ì´ë°"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "ê· í: %d%% ì¤ë¥¸ìª½"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "ìµì
ë©ë´"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "'íì ì' ë¹íì±í"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "'íì ì' íì±í"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "íì¼ ì ë³´ ìì"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "A ë°ë³µ ìì ì ì¤ì íìµëë¤."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "B ë°ë³µ ìì ì ì¤ì íìµëë¤."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "ë°ë³µ ìì ì ì§ì ìµëë¤."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "ì±ê¸ 모ëì
ëë¤."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "ì¬ì ëª©ë¡ ëª¨ëì
ëë¤."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "곡 ì¬ì í ë©ì¶ë ì¤ì
ëë¤."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "íì± ì¬ì 목ë¡ìì í목 ê²ì"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "ê²ì"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3589,57 +3820,61 @@ msgstr ""
"ê·ííì 문ë²ì ì¬ì©í©ëë¤. ì ê·ííìì´ ì´ë»ê² ëìíëì§ ëª¨ë¥´ì ë¤ë©´ ê²ìí "
"ë¬¸ì¥ ì¼ë¶ë¥¼ ë£ì¼ìë©´ ë©ëë¤."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "ì 목:"
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "ì¨ë²:"
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "ìì
ê°:"
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "íì¼ ì´ë¦:"
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "ê²ìí기 ì ì ì´ì ì íí목 ì§ì°ê¸°"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "ì¼ì¹íë í목ì ëí´ ìëì¼ë¡ ë기 목ë¡ì ì íí기"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "ì¼ì¹íë í목ì ëí´ ì ì¬ì ëª©ë¡ ë§ë¤ê¸°"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "ì¤ë°ì´ì
ì¤ ì¬ì ëª©ë¡ í¸ì§ê¸°"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%1$s (%3$dì¤ %2$d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "ìì¶í Winamp 2.x ì¤í¨"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "ìì¶íì§ ìì Winamp 2.x ì¤í¨"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "(%s) ëë í°ë¦¬ë¥¼ ë§ë¤ ì ììµëë¤: %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile íë¬ê·¸ì¸"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3678,81 +3913,71 @@ msgstr ""
"ì´ ìë¤ë©´ ìì ìíí¸ì¨ì´ ì¬ë¨ì ìì²íììì¤. 51 Franklin Street, Fifth "
"Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile íë¬ê·¸ì¸"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Sndio ì¶ë ¥ íë¬ê·¸ì¸ ì ë³´"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-"Sndio ì¶ë ¥ íë¬ê·¸ì¸\n"
-"\n"
-"Thomas Pfaff <tpfaff at tp76.info>ê° ìì±íììµëë¤\n"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "ì§ìíì§ ìë íì"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-"ì¤ëì¤ ì¥ì¹ê° ì§ìíì§ ìë íìì ìì²íìµëë¤.\n"
-"\n"
-"sndiod(1) ìë²ë¥¼ ì¤ííê³ ë¤ì ìëíììì¤."
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio ì¥ì¹"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(ë¹ ê°ì 기본 ê°ì ì미)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "íì¸"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "곡 ë°ê¾¸ê¸°"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "ì¤ë°ì´ì
ì¤ê° ì 곡 ì¬ìì ììí ë ì¤íí ëª
ë ¹ì
ëë¤."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>ìì ì ë¬íë ì¸ìë ë°ì´íë¡ ê°ì¸ì¼ í©ëë¤. ê·¸ë ê² íì§ "
+"ìì¼ë©´ ë³´ì 문ì ê° ìê¹ëë¤.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "ëª
ë ¹:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "곡ì ë ë¶ë¶ì ë¤ë¤ëìë ì¤íí ëª
ë ¹ì
ëë¤."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "ì¬ì 목ë¡ì ëì ëë¬íì ë ì¤íí ëª
ë ¹ì
ëë¤."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
-msgstr "곡ì ì 목(ì: ë¤í¸ìí¬ ì¤í¸ë¦¼ ì 목)ì ë°ê¿ ë ì¤íí ëª
ë ¹ì
ëë¤."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr ""
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3766,35 +3991,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"ëª
ë ¹ì í¸ì¶í기 ì ì ëì²´í ë¤ìì íì 문ìì´ì\n"
-"ì¬ì©í ì ììµëë¤\n"
-"(ì¬ì ëª©ë¡ ë§ì§ë§ ìì ì ëª
ë ¹ì¼ë¡ ë¤ ì¸ëª¨ ìëê²ì ìëëë¤):\n"
-"\n"
-"%F: 주íì(Hz ë¨ì)\n"
-"%c: ì±ë ë²í¸\n"
-"%f: íì¼ ì´ë¦(ì ì²´ ê²½ë¡)\n"
-"%l: 곡 길ì´(ë°ë¦¬ì´ ë¨ì)\n"
-"%n or %s: 곡 ì´ë¦\n"
-"%r: ë¹í¸ì ì¡ì¨(bps ë¨ì)\n"
-"%t: ì¬ì ëª©ë¡ ìì¹(%02d)\n"
-"%p: íì¬ ì¬ìì¤ ì¬ë¶(1 or 0)\n"
-"%a: ìì
ê°\n"
-"%b: ì¨ë²\n"
-"%T: í¸ë ì 목"
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>ìì ì ë¬íë ì¸ìë ë°ì´íë¡ ê°ì¸ì¼ í©ëë¤. ê·¸ë ê² íì§ "
-"ìì¼ë©´ ë³´ì 문ì ê° ìê¹ëë¤.</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "ëª
ë ¹"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX 리ìíë¬"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3808,51 +4014,51 @@ msgstr ""
"ìí 주íì ë³í íë¬ê·¸ì¸ì 기ë°ì¼ë¡ íììµëë¤:\n"
"Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "ë¹ ë¦"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "ë®ì"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "ëì"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "ë§¤ì° ëì"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "ìì§:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX 리ìíë¬"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "ìëì í¼ì¹"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>ìëì í¼ì¹</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "ìë:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "í¼ì¹:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "ìëì í¼ì¹"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "ìí ìì´ì½"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "ì¤ì (_T)..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3870,39 +4076,39 @@ msgstr ""
"ì´ íë¬ê·¸ì¸ì ì°½ ê´ë¦¬ìì ìì¤í
íìì¤ ììì\n"
"ë¨ë ìí ìì´ì½ì ì ê³µí©ëë¤."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>ë§ì°ì¤ ì¤í¬ë¡¤ ëì</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "ìë ì¡°ì í기"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "ì¬ìì¤ì¸ 곡 ë°ê¾¸ê¸°"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>기í ì¤ì </b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "íì ëìë§ ì°½ ë¹íì±í"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "ìì¤í
í¸ë ì´ë¡ ì í"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "ì¬ì목ë¡ì ìë¡ ì¤í¬ë¡¤ í ë 미리 ì림"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "ìí ìì´ì½"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "ìì¤í¸ë¼ ì¤í
ë ì¤"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3912,24 +4118,24 @@ msgstr ""
"\n"
"By Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>ìì¤í¸ë¼ ì¤í
ë ì¤</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "ìì¤í¸ë¼ ì¤í
ë ì¤"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "í¤ ìì±ê¸°"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "í¤ ìì±ê¸°:"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3944,15 +4150,11 @@ msgstr ""
"frequency3;...\n"
"ì¬ì© ì) tone://2000;2005ë 2000 Hz í¤ê³¼ a 2005 Hz í¤ì¼ë¡ ì¬ìí©ëë¤."
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "í¤ ìì±ê¸°"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "ì¡ì± ì ê±°"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3990,11 +4192,35 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis "
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX ëì½ë"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4004,19 +4230,19 @@ msgstr ""
"Roman Sherbakov <v_soft at microfor.ru>ì in_vtx.dllì 기ë°ì¼ë¡ í¨\n"
"Pavel Vymetalek <pvymetalek at seznam.cz>ì´ ì¤ë°ì´ì
ì¤ íë¬ê·¸ì¸ ì ì"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX ëì½ë"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack ëì½ë"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "ìì¤(í¼ì±)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "ìì¤"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4026,14 +4252,18 @@ msgstr ""
"\n"
"íë¬ê·¸ì¸ ì½ë ì¼ë¶ë Miles Eganì´ ìì±íìµëë¤."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack ëì½ë"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF ëì½ë"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "XML ê³µì ê°ë¥ ì¬ì 목ë¡(XSPF)"
diff --git a/po/ky.po b/po/ky.po
index 276e9a906368..2dd609af38f2 100644
--- a/po/ky.po
+++ b/po/ky.po
@@ -7,11 +7,11 @@
# chingis, 2012
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Kirgyz (http://www.transifex.com/projects/p/audacious/"
"language/ky/)\n"
"Language: ky\n"
@@ -20,51 +20,35 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "моно"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "ÑÑеÑео"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "көлөмдүү ÑÑбÑÑ"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib ойноÑкÑÑÑ)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr ""
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib ойноÑкÑÑÑ)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "ÐйгоÑкÑÑ ÑааÑ"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "ÐйгоÑкÑÑ ÑааÑ"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -87,7 +71,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -109,7 +93,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -123,360 +107,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr ""
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr ""
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "ÐÑке ÑалÑÑ"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "ÐүйÑөмбү"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "ШейÑемби"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "ШаÑÑемби"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "ÐейÑемби"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "ÐÑма"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "ÐÑемби"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "ÐекÑемби"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "ÐйгоÑкÑÑ ÑааÑÑÑн ÑÑаÑÑоолоÑÑ"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "УбакÑÑ"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr ""
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "Ñ"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr ""
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "ÑааÑ"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "мүнөÑ"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr ""
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Ðүн"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "ÐаÑÑÑланбаÑ"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "ÐүндөÑ"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "ÐаÑаңÑалоо"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "ÑекÑнда"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "ÐаÑÑÑлÑк"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr ""
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "ÐÑкÑоо"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "ÐезекÑеги"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "ÐоÑÑмÑа команда"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "күйгүзүү"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr ""
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "ÐйноÑÑÑ ÑизмеÑин ÑандаңÑз"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "ÐпÑиÑлаÑ"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr ""
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "ÐаÑдам"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "ÐлÑбом ÑÑÑÑ"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA ÑÑгÑÑÑ"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "ÐаÑÑÑÐ»Ð°Ð½Ð±Ð°Ñ PCM оÑноÑмоÑÑ"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "ÐаÑÑÑÐ»Ð°Ð½Ð±Ð°Ñ Ð¼Ð¸ÐºÑÐµÑ Ð¾ÑноÑмоÑÑ"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM оÑноÑмоÑÑ:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "ÐикÑÐµÑ Ð¾ÑноÑмоÑÑ:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "ÐикÑÐµÑ ÑлеменÑи:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
msgstr ""
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA ÑÑгÑÑÑ"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "ÐÑ"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Файл аÑÑ"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "ӨлÑөм (байÑ)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "ÐÑÑ:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI маалÑмаÑÑ </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "ФоÑмаÑ:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "УзÑндÑк (мÑ):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "өзгөÑмө"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Time Div:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI комменÑаÑÐ¸Ð¹Ð»ÐµÑ Ð¶Ð°Ð½Ð° ÑөздөÑÒ¯ </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_ÐабÑÑ"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (ÑÑÑÑа ÑÐ¼ÐµÑ UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "AMIDI-Plug жөнүндө"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -487,261 +477,258 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr ""
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Тик бÑÑÑÑÑк"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "ТоголокÑолгон Ñик бÑÑÑÑÑк"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "ЧÑңкÑÑайган Ñик бÑÑÑÑÑк"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Ðок"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "ÐйноÑÑÑнÑн баÑÑ"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr ""
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "ÐÑÑн өзгөÑÑÒ¯Ò¯"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr ""
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr ""
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr ""
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr ""
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "ТÑÑган жеÑи"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr ""
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr ""
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr ""
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr ""
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr ""
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr ""
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr ""
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr ""
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr ""
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr ""
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr ""
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "ШÑиÑÑÑеÑ"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr ""
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Ðөлөкө"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr ""
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "ТүÑÑÓ©Ñ"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr ""
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr ""
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "ÐкÑÑ"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr ""
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
"manager otherwise the OSD won't work properly"
msgstr ""
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr ""
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "ТÑнÑкÑÑк"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr ""
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr ""
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr ""
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr ""
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "ÐÑÑн"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "ÐнимаÑиÑ"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "ТекÑÑ"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "СÑилÑ"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr ""
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr ""
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 ойноÑÑÑ ÑизмелеÑи"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious ойноÑÑÑ ÑизмелеÑи (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>ТүÑ</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "ÐÒ¯Ò£Ò¯ÑÑ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½"
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
-msgstr ""
-
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
msgstr ""
-#: src/bs2b/plugin.c:166
+#: src/bs2b/plugin.cc:129
msgid "Presets:"
msgstr "ÐÑеÑеÑÑеÑ:"
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
msgstr ""
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr ""
+
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "СпекÑÑ ÑалдагÑÑÑ"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "ÐÑдио CD плагини"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -753,169 +740,156 @@ msgid ""
"This was a Google Summer of Code 2007 project."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>ÐÑноÑмо</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "ÐкÑÑ ÑлдамдÑгÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>ÐеÑамаалÑмаÑ</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "CD-Text колдонÑÑ"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "CDDB колдонÑÑ"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "СеÑвеÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Ðол:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "ÐоÑÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "ÐÑдио CD плагини"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "ÐÑдио ÑÑгÑÑÑн аÑÑÑ Ð¾Ò£Ñнан ÑÑккан жок."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "ÐÑдио CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "%s CD оÑноÑмоÑÑн аÑÑÑ Ð¾Ò£Ñнан ÑÑккан жок."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr ""
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr ""
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "CD ойноÑÑÑ"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "CD коÑÑÑ"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr ""
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>ÐÑÑÑлÑÑ</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "ÐоÑÐ±Ð¾Ñ ÐºÐ°ÑÑÑлÑгÑ:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "ÐинамикалÑк диапазон:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr ""
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -925,195 +899,220 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ÐаÑ:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr ""
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "ÐаÑÑÑÐ»Ð°Ð½Ð±Ð°Ñ ÑÑ ÑзÑндÑгÑ:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr ""
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr ""
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "ÐÑ"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr ""
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr ""
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr ""
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr ""
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr ""
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr ""
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>ÐÑиÑÑализаÑоÑ</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "ÐнÑенÑивдүүлүк:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "ÐÑиÑÑализаÑоÑ"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Ó¨ÑÒ¯ÑÒ¯Ò¯"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "ÐйнÑÑ"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>ÐаңÑÑÑк</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "ÐеÑигүү:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "мÑ"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "ÐеÑбайланÑÑ:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "ÐаÑÑÑлÑк:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "ÐÑ
о"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg плагини"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1123,55 +1122,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg плагини"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr ""
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "ЧÑгÑÑ Ñайл ÑоÑмаÑÑ:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "ЫÑаÑÑоо"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr ""
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "ТапÑÑÑÑлма каÑалогго ÑакÑоо"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "ЧÑгÑÑ Ñайл каÑалогÑ:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "ÐаÑÐ°Ð»Ð¾Ð³Ð´Ñ Ñандоо"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1189,165 +1188,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr ""
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "ÐвÑомаÑÑÑÑ"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr ""
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "СÑеÑео"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Ðоно"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr ""
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "ÐлгоÑиÑм ÑапаÑÑ:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "ЧÑгÑÑ Ð¶ÑÑÑÑгÑ:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(ÐÑ)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ÐиÑÑÐµÐ¹Ñ (кбиÑ/Ñ):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr ""
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "ÐÑдио Ñежими:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "ÐаÑалаÑдан коÑгоо"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "СапаÑ"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "VBR/ABR күйгүзүү"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "ТүÑ:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR паÑамеÑÑлеÑи:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "ТөмөнÑек биÑÑейÑи (кбиÑ/Ñ):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "ÐогоÑÑек биÑÑейÑи (кбиÑ/Ñ):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr ""
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR паÑамеÑÑлеÑи:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "ÐÑÑоÑо биÑÑÐµÐ¹Ñ (кбиÑ/Ñ):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR ÑÐ°Ð¿Ð°Ñ Ð´ÐµÒ£Ð³ÑÑли:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "ÐÐ°Ð´Ñ Ð¿Ð°ÑамеÑÑлеÑи:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "ÐвÑоÑдÑк ÑкÑк менен коÑголгон деп белгилөө"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "ÐÑигинал деп белгилөө"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ID3 паÑамеÑÑлеÑи:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr ""
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr ""
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr ""
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "ТегдеÑ"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis кодегин ÑÑаÑÑоо"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Ð¡Ð°Ð¿Ð°Ñ Ð´ÐµÒ£Ð³ÑÑли (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC декодеÑи"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr ""
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1355,21 +1358,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC декодеÑи"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO плагини"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1381,529 +1388,606 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "ÐазÑÑнÑн номеÑи"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "ÐÑ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "ÐÑкаÑÑÑÑÑ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "ÐÑл"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "ÐлÑбом"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Ðол"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "ÐанÑ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "ÐезекÑеги оÑдÑ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "УзÑндÑк"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Файлга жол"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Файл аÑÑ"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "ТапÑÑÑÑлма аÑ"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ÐиÑÑейÑ"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Ðздөө аÑпабÑ"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr ""
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr ""
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr ""
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr ""
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Ó¨ÑÒ¯ÑÒ¯Ò¯"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Ðздөө аÑпабÑ"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "ФайлдаÑÐ´Ñ _аÑÑÑ ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "_URL аÑÑÑ ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "ФайлдаÑÐ´Ñ _коÑÑÑ ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "U_RL коÑÑÑ ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "ÐÑогÑамма _жөнүндө ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_ЧÑгÑÑ"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_ÐйноÑÑÑ"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "_ÐаÑза"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_ТокÑоÑÑÑ"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_ÐÑÑÑнкÑ"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_Ðийинки"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_ÐайÑалоо"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_ÐÑеÑÑиз"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Тизмеден жÑлдÑÑбоо"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "Ð«Ñ _маалÑмаÑÑ ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "_УбакÑÑка Ó©ÑÒ¯Ò¯ ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "_ЫÑга Ó©ÑÒ¯Ò¯ ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "_ÐÑ Ð±Ð¾ÑнÑа"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "ТÑек _номеÑи боÑнÑа"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "_ÐÑкаÑÑÑÑÑ Ð±Ð¾ÑнÑа"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "ЧÑгаÑÑÑ _күнү боÑнÑа"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "_ФайлдÑн ÑÑÑган жеÑи боÑнÑа"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "_ТапÑÑÑÑлма Ð°Ñ Ð±Ð¾ÑнÑа"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "_ТеÑкеÑи ÑаÑÑип менен"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_ÐÑÐ°Ð»Ð°Ñ ÑаÑÑип менен"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "УÑÑл ойноÑÑÑ ÑизмеÑин _ойноÑÑÑ"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_ÐаңÑлоо"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_СоÑÑÑоо"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "_Ðол жеÑÐºÐ¸Ñ ÑайлдаÑÐ´Ñ Ó©ÑÒ¯ÑÒ¯Ò¯"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_ÐаңÑ"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "ÐÑÑн _өзгөÑÑÒ¯Ò¯..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_ÐмпоÑÑ ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_ÐкÑпоÑÑ ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "ÐйноÑÑÑ ÑизмеÑинин _менеджеÑи..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_Ðезек менеджеÑи ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "ÐаÑÑÑлÑкÑÑ _көбөйÑÒ¯Ò¯"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "ÐаÑÑÑлÑкÑÑ _азайÑÑÑ"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_ÐквалайзеÑ"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "_ÐÐµÐ½Ñ Ð¿Ð°Ð½ÐµÐ»Ð¸Ð½ көÑÑÓ©ÑÒ¯Ò¯"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Ð_аалÑÐ¼Ð°Ñ Ð¿Ð°Ð½ÐµÐ»Ð¸Ð½ көÑÑÓ©ÑÒ¯Ò¯"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr ""
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "_Ðбал панелин көÑÑÓ©ÑÒ¯Ò¯"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Файл"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_ÐйноÑÑÑ"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Тизме"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_ÐÑзмаÑÑаÑ"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_ЧÑгÑÑ"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "ÐÓ©_ÑүнүÑ"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Ðезекке коÑÑ/койбоо"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Ðе_ÑÒ¯Ò¯"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_ÐÓ©ÑÒ¯ÑÒ¯Ò¯"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "Ð_оÑÑ"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "_ÐааÑÑн Ñандоо"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_ÐÑÑн өзгөÑÑÒ¯Ò¯ ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK инÑеÑÑейÑ"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ÐÑÑеÑизаÑÐ¸Ñ ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
-#, c-format
-msgid "%d channel"
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "моно"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "ÑÑеÑео"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
+#, c-format
+msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d канал"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d кбиÑ/Ñ"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "ÐиÑиндеген Ñежим."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "ÐйноÑÑÑ ÑизмеÑи Ñежими."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "ЫÑдан кийин ÑокÑоÑÑÑ."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "ÐÑÑÑÐ½ÐºÑ Ð¶Ð¾Ð»Ñо"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "ÐйноÑÑÑ"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "ÐаÑза/УланÑÑÑ"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "ТокÑоÑÑÑ"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Ðийинки жолÑо"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Үнүн баÑÑÑ"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr ""
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr ""
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Файлга Ó©ÑÒ¯Ò¯"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr ""
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(жок)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1911,37 +1995,37 @@ msgid ""
"Do you want to continue?"
msgstr ""
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr ""
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr ""
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
msgstr ""
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "ЫÑÑк клавиÑалаÑ:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>ÐÑакеÑ:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>ÐлавиÑÑик айкалÑÑ:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr ""
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1956,124 +2040,90 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK ÑÑгÑÑÑ"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK ÑÑгÑÑÑ"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s ЫÑаÑÑоолоÑ"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr ""
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr ""
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
"After adding new paths, press Enter to scan for new plugins.</small>"
msgstr ""
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Ðол жеÑеÑдик плагиндеÑ:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Ðүйгүзүү"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Ðүйгүзүлгөн плагиндеÑ:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "ЫÑаÑÑоолоÑ"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA Ñүйүнү"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr ""
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr ""
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr ""
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr ""
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr ""
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC плагини"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2089,73 +2139,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>ТÑÑаÑÑÑÑÑÑ</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr ""
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr ""
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC плагини"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki плагини"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Ð«Ñ ÑекÑÑи кол жеÑкиÑ"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "ÐаÑа"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "ÐаÑа"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Ð«Ñ ÑекÑÑин издөө ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Ð«Ñ Ð¼ÐµÑамаалÑмаÑÑаÑÑ Ð¶Ð¾Ðº болÑÑ"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki плагини"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U ойноÑÑÑ ÑизмелеÑи"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Ð¢Ð°ÐºÑ Ð³ÐµÐ½ÐµÑаÑоÑÑ"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr ""
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr ""
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2164,162 +2222,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Ð¢Ð°ÐºÑ Ð³ÐµÐ½ÐµÑаÑоÑÑ"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Ðанал микÑеÑи"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Ðанал микÑеÑи</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "ЧÑгÑÑ ÐºÐ°Ð½Ð°Ð»Ð´Ð°ÑÑ:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Ðанал микÑеÑи"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS плагини"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (модÑÐ»Ñ Ð¾Ð¹Ð½Ð¾ÑкÑÑÑ)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>ЧеÑим</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-биÑ"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-биÑ"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>ÐаналдаÑ</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 кÐÑ"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 кÐÑ"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 кÐÑ"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 кÐÑ"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "ÐеңгÑÑли:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>ÐайÑалоо</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "ÐайÑалоо ÑанÑ:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (модÑÐ»Ñ Ð¾Ð¹Ð½Ð¾ÑкÑÑÑ)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Ðөлөмдүү ÑÑбÑÑ"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 плагини"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Ðөлөмдүү ÑÑбÑÑ"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 ÑеÑвеÑи"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS плагини"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "ТокÑолгон"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious ойноÑÑп жаÑкан жок."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr ""
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2339,55 +2429,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr ""
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "ÐаÑза"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Ðийинки"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. ÐаÑÑÑÐ»Ð°Ð½Ð±Ð°Ñ Ð¾ÑноÑмоÑÑ"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 ÑÑгÑÑÑ"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Үн оÑноÑмоÑÑ:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr ""
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr ""
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr ""
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2396,19 +2495,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 ÑÑгÑÑÑ"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS ойноÑÑÑ ÑизмелеÑи"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2 ÑÑгÑÑÑ"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio ÑÑгÑÑÑ"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2428,143 +2543,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio ÑÑгÑÑÑ"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
-#: src/resample/resample.c:165
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ÐÑÑÑнкÑ"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "ÐайÑалоо"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "ÐÑеÑÑиз"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr ""
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "СÑзÑкÑÑк инÑеÑполÑÑиÑ"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>ÐонвеÑÑиÑ</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Ыкма:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "ÐÑÑÑÑк:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>ÐÑÑÑÑкÑÐ°Ñ ÐºÐ°ÑÑаÑÑ</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "ÐÑÑÑÑк каÑÑаÑÑн колдонÑÑ"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 кÐÑ:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 кÐÑ:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 кÐÑ:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 кÐÑ:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 кÐÑ:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 кÐÑ:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 кÐÑ:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr ""
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "ТаÑмак көйгөйү."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "ТекÑеÑилүүдө..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2575,84 +2759,69 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL ÑÑгÑÑÑ"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL ÑÑгÑÑÑ"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Ðбазкана"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "ÐелгиÑиз аÑкаÑÑÑÑÑ"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "ÐелгиÑиз алÑбом"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d алÑбом"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "ÐйноÑÑÑ ÑизмеÑин _жаÑаÑÑÑ"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "ÐйноÑÑÑ ÑизмеÑине _коÑÑÑ"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Ðздөө абазканаÑÑ"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2660,679 +2829,769 @@ msgstr ""
"Audacious абазканаÑÑна мÑзÑкаңÑÐ·Ð´Ñ Ð¸Ð¼Ð¿Ð¾ÑÑ ÐºÑлÑÑ Ò¯Ñүн, биÑинÑи каÑÐ°Ð»Ð¾Ð³Ð´Ñ "
"ÑандаңÑз, анан \"жаңÑÑÑÑÑ\" деген Ð¸ÐºÐ¾Ð½ÐºÐ°Ð½Ñ Ð±Ð°ÑÑÒ£Ñз."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr ""
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "ÐаÑÐ°Ð»Ð¾Ð³Ð´Ñ ÑандаңÑз"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "ÐйноÑÑÑ"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "ÐйноÑÑÑ ÑизмеÑи"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "ÐÓ©ÑүнүÑ"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "ÐайÑалоо"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "ÐÑеÑÑиз"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr ""
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ÐÑÑÑнкÑ"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "ÐÐ°Ò£Ñ Ð¾Ð¹Ð½Ð¾ÑÑÑ ÑизмеÑи"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "ÐйноÑÑÑ ÑизмеÑинин ÑедакÑоÑÑн көÑÑÓ©ÑÒ¯Ò¯"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "_ÐквалайзеÑди көÑÑÓ©ÑÒ¯Ò¯"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "ÐайÑма Ò¯ÑÑүндө"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "ÐÑ Ð±Ð¾ÑнÑа"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Файл аÑÑ Ð±Ð¾ÑнÑа"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "ÐааÑÑн Ó©ÑÒ¯ÑÒ¯Ò¯"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "ÐезекÑи Ñазалоо"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Ðол жеÑÐºÐ¸Ñ ÑайлдаÑÐ´Ñ Ó©ÑÒ¯ÑÒ¯Ò¯"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "ÐÑбликаÑÑаÑÐ´Ñ Ó©ÑÒ¯ÑÒ¯Ò¯"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "ТандалбагандаÑÐ´Ñ Ó©ÑÒ¯ÑÒ¯Ò¯"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "ТандалгандаÑÐ´Ñ Ó©ÑÒ¯ÑÒ¯Ò¯"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Ðздеп анан Ñандоо"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Ð¢Ð°Ð½Ð´Ð°Ð»Ð³Ð°Ð½Ð´Ñ ÑеÑкеÑилеÑÒ¯Ò¯"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Ð¢Ð°Ð½Ð´Ð¾Ð¾Ð½Ñ Ð°Ð»ÑÑ"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "ÐааÑÑн Ñандоо"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "ÐлÑбом боÑнÑа"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "ÐолÑо номеÑлеÑи боÑнÑа"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "ÐÑкаÑÑÑÑÑ Ð±Ð¾ÑнÑа"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "ÐлÑбом боÑнÑа"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "ÐолÑо номеÑлеÑи боÑнÑа"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Тизмени аÑалаÑÑÑÑÑÑ"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Тизмени ÑеÑкеÑилеÑÒ¯Ò¯"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "ТандалгандаÑÐ´Ñ ÑоÑÑÑоо"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Тизмени ÑоÑÑÑоо"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "ÐеÑÒ¯Ò¯"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "ÐÓ©ÑÒ¯ÑÒ¯Ò¯"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "ÐоÑÑ"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winamp клаÑÑикалÑк инÑеÑÑейÑи"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "СакÑоо"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "ÐүкÑÓ©Ó©"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr ""
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "ÐÑеÑеÑÑи жүкÑÓ©Ó©"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "ÐвÑо-пÑеÑеÑÑи жүкÑÓ©Ó©"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "ÐÑеÑеÑÑи ÑакÑоо"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "ÐвÑо-пÑеÑеÑÑи ÑакÑоо"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "ÐÑеÑеÑÑи Ó©ÑÒ¯ÑÒ¯Ò¯"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "ÐвÑо-пÑеÑеÑÑи Ó©ÑÒ¯ÑÒ¯Ò¯"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_ÐйноÑкÑÑ:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "ÐйноÑкÑÑÑÑн негизги ÑеÑезеÑинин ÑÑиÑÑин ÑандаңÑз:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_ÐйноÑÑÑ ÑизмеÑи:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "ÐйноÑÑÑ ÑизмеÑинин ÑÑиÑÑин Ñандоо:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr ""
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Ð«Ñ Ð°ÑÑн Ñки багÑÑÑÑ ÐºÐ°ÑаÑа айланÑÑÑ"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "ÐнализаÑоÑ"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "ÐÑÑиллогÑамма"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "."
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Ðөнөкөй"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "ÐÑ"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "СÑзÑкÑаÑ"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "ТилкелеÑ"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "ÐайÑÑаак"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Ðай"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "ÐÑÑоÑо"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "ÐаÑ"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "ÐаÑÑÑаак"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "ÐÑз"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Тегиз"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Ðегизги"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "ÐизÑалдаÑÑÑÑÑÑ"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "ÐÒ¯ÑÓ©ÑÒ¯Ò¯"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 кÐÑ"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious ÑквалайзеÑи"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr ""
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "ÐаÑÑÑлÑк: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "ÐаланÑÑ: %d%% Ñол"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr ""
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "ÐаланÑÑ: %d%% оң"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "ÐаÑамеÑÑÐ»ÐµÑ Ð¼ÐµÐ½ÑÑÑ"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "\"ÐайÑма Ò¯ÑÑүндө\"нү Ó©ÑÒ¯ÑÒ¯Ò¯"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "\"ÐайÑма Ò¯ÑÑүндө\"нү күйгүзүү"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Файл жөнүндө маалÑмаÑ"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "ÐиÑиндеген Ñежим."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "ÐйноÑÑÑ ÑизмеÑи Ñежими."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "ЫÑдан кийин ÑокÑоÑÑÑ."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "ÐкÑивдүү ойноÑÑÑ ÑизмеÑинен жазÑÑлаÑÐ´Ñ Ð¸Ð·Ð´Ó©Ó©"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3340,57 +3599,61 @@ msgid ""
"for."
msgstr ""
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "ÐÑ: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "ÐлÑбом: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "ÐÑкаÑÑÑÑÑ: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Файл аÑÑ: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr ""
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audacious ойноÑÑÑ ÑизмеÑинин ÑедакÑоÑÑ"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d / %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "ÐÑÑ
ивделген Winamp 2.x ÑемаÑÑ"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "ÐÑÑ
ивделбеген Winamp 2.x ÑемаÑÑ"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr ""
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile плагини"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3412,75 +3675,69 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile плагини"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Sndio ÑÑгÑÑ Ð¿Ð»Ð°Ð³Ð¸Ð½Ð¸ жөнүндө"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Ðолдолбогон ÑоÑмаÑ"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio оÑноÑмоÑÑ"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Ð«Ñ ÐºÐ¾ÑоÑÑÑ"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Ðоманда:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3495,17 +3752,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "ÐомандалаÑ"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3514,51 +3769,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "СапаÑÑ:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr ""
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "ЫлдамдÑк жана бийикÑик"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>ЫлдамдÑк жана бийикÑик</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "ЫлдамдÑк:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "ÐийикÑик:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "ЫлдамдÑк жана бийикÑик"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "СÑаÑÑÑ Ð¸ÐºÐ¾Ð½ÐºÐ°ÑÑ"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3569,63 +3824,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>ЧÑÑÐºÐ°Ð½Ð´Ñ Ð°Ð¹Ð»Ð°Ð½ÑÑÑ Ð°ÑакеÑи</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "ÐаÑÑÑлÑкÑÑ Ó©Ð·Ð³Ó©ÑÑÒ¯Ò¯"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "ÐйноÑÑлÑп жаÑкан ÑÑÐ´Ñ Ð°Ð»Ð¼Ð°ÑÑÑÑÑÑ"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>ÐаÑка ÑÑаÑÑоолоÑ</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "ÐалкÑма ÑеÑезени Ó©ÑÒ¯ÑÒ¯Ò¯"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "СиÑÑемалÑк ÑÑейге жабÑÑ"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "СÑаÑÑÑ Ð¸ÐºÐ¾Ð½ÐºÐ°ÑÑ"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "ÐкÑÑÑа ÑÑеÑео"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>ÐкÑÑÑа ÑÑеÑео</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "ÐкÑÑÑа ÑÑеÑео"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Тон генеÑаÑоÑÑ"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f ÐÑ"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Тон генеÑаÑоÑÑ: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3634,15 +3889,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Тон генеÑаÑоÑÑ"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr ""
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3663,44 +3914,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis декодеÑи"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX декодеÑи"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX декодеÑи"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack декодеÑи"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr ""
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr ""
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack декодеÑи"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF декодеÑи"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr ""
diff --git a/po/lt.po b/po/lt.po
index e3033f4df6ed..3270d896587d 100644
--- a/po/lt.po
+++ b/po/lt.po
@@ -10,11 +10,11 @@
# gymka <gymka at mail.ru>, 2011
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Lithuanian (http://www.transifex.com/projects/p/audacious/"
"language/lt/)\n"
"Language: lt\n"
@@ -24,40 +24,28 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n"
"%100<10 || n%100>=20) ? 1 : 2);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "erdvinis"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "AAC (MP4) Dekoderis"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "AAC (Raw) Dekoderis"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib grotuvas)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "nuoseklus"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib grotuvas)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Žadintuvas"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "Nustatyti perspÄjimÄ
..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -67,11 +55,7 @@ msgstr ""
"\n"
"Originaliai paraÅ¡Ä Adam Feakin ir Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Žadintuvas"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -113,7 +97,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -150,7 +134,7 @@ msgstr ""
"atÄjus signalo laikui paleisti Å¡iÄ
komandÄ
.\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -173,381 +157,371 @@ msgstr ""
" Ä®raÅ¡ykite priminimÄ
ir perjunkite mygtukÄ
\n"
" jei norite jog jis būtų rodomas."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Tai pabudimo skambutis."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "Å iandienos priminimas..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Priminimas"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Pirmadienis"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Antradienis"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "TreÄiadienis"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Ketvirtadienis"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Penktadienis"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Šeštadienis"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Sekmadienis"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Žadintuvo nustatymai"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "_Gerai"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "_Atsisakyti"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Laikas"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Žadinti (numatyta):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "v"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Nutildyti po:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "valandos"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minutÄs"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Pasirinkite dienas kuriomis žadinti"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Diena"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Numatytosios"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Dienos"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Išblukimas"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "sekundÄs"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Garsas"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "PradÄti nuo"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Baigti"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Dabartinis"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Papildoma komanda"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "Įjungti"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Grojaraštis (nebūtina)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Pasirinkite grojaraštį"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Pasirinktys"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "KÄ
šios pasirinktys reiškia?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Žinynas"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Albumo apipavadalinimas"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA išvestis"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ALSA išvesties įskiepis skirtas Audacious\n"
+"AutorinÄs teisÄs 2009-2012 John Lindgren\n"
+"\n"
+"DÄkoju William Pitcock, âALSA Output Plugin NGâ autoriui, jo kodas buvo kaip "
+"pagrindas kai ALSA žinynas negelbÄdavo."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Numatytasis PCM įrenginys"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Numatytasis mikšerio įrenginys"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM įrenginys:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Mikšerio įrenginys:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Mikšerio elementas:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Apeiti sausÄ
pakibimÄ
"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI grotuvas)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-"ALSA išvesties įskiepis skirtas Audacious\n"
-"AutorinÄs teisÄs 2009-2012 John Lindgren\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
"\n"
-"DÄkoju William Pitcock, âALSA Output Plugin NGâ autoriui, jo kodas buvo kaip "
-"pagrindas kai ALSA žinynas negelbÄdavo."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA išvestis"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI grotuvas)"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "PerraÅ¡yti numatytÄ
jį garsÄ
:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "PerraÅ¡yti numatytÄ
jÄ
polifonijÄ
:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "PerraÅ¡yti numatytÄ
jį aidÄ
:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "Įjungta"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "PerraÅ¡yti numatytÄ
jį chorÄ
:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>Atkūrimas</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "PerkÄlimas:"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "Būgnų poslinkis:"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>SudÄtingesni</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "Išgauti komentarus iš MIDI failo"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "Gauti žodžius iš MIDI failo"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>Sintezatorius</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr "Diskretizacijos dažnis:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - pasirinkite SoundFont failÄ
"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Atsisakyti"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "_Atverti"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "Failo vardas"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "Bylos vardas"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Dydis (bitais)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Pavadinimas:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI Info </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Formatas:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "TrukmÄ (ms):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Takelių:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "kintamasis"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Laiko div:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI komentarai ir žodžiai</span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* Å iame MIDI faile nÄra komentarų *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* Å iame MIDI faile nÄra žodžių *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Uždaryti"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (neteisingas UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Apie AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"moduliarinis MIDI muzikos grotuvas \n"
-"http://www.develia.org/projects.php?p=amidiplug sukÅ«rÄ \n"
-"Giacomo Lozito <james at develia.org> \n"
-"\n"
-"ypatinga padÄka...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela \n"
-"už jų puikias programas aplaymidi ir amixer; šios programos tikrai naudingos "
-"susipažįstant su ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"už gražų midi klaviatÅ«ros logotipÄ
\n"
-"\n"
-"Tony Vroon\n"
-"už pagalbÄ
testuojan alfa"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -565,152 +539,146 @@ msgstr ""
"Paremta Evan Martin Ghosd biblioteka:\n"
"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (Rodymas ekrane)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "StaÄiakampis"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Apvalus staÄiakampis"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Ä®gaubtas staÄiakampis"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Joks"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Atkūrimo pradžia"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Sužadina OSD kai grojaraÅ¡Äio elementas grojamas."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Pavadinimo keitimas"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Sužadina OSD kai, atkÅ«rimo metu, dainos pavadinimas pasikeiÄia, bet bylos "
-"vardas lieka tas pats. Å ita pasirinktis naudingiausia atvaizduojant "
-"interneto srauto dainos pavadinimo pokyÄius. "
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "PauzÄ"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Sužadina OSD kai atkūrimas sustabdomas"
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "PauzÄ iÅ¡jungiama"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Sužadina OSD kai atkÅ«rimas atkuriamas po pauzÄs."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "PadÄtis"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Reliatyvus X poslinkis:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Reliatyvus Y poslinkis:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Didžiausias OSD plotis:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Kelių vaizduoklių pasirinktys"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Vaizduoklis naudoja OSD:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "visi vaizduokliai"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "vaizduoklis %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Laiko derinimas (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Monitorius:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Nustelbti:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Išblukti:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Å riftai"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Å riftas %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Å eÅ¡Älis"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Atvaizdavimo stilius"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Spalvos"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Spalva %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Sužadinti"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Įvykis"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Kompozicionavimo tvarkyklÄ aptikta"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -719,112 +687,112 @@ msgstr ""
"Kompozicionavimo tvarkyklÄ nerasta;\n"
"įjunkite kompozicionavimo tvarkyklÄ, nes OSD neveiks taip kaip priklauso"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Netikram permatomumui kompozicionavimo tvarkyklÄ nebÅ«tina"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Permatomumas"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Netikras permatomumas"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Tikras permatomumas (reikalinga X kompozicionavimo plÄtinys)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Kompozicionavimo plÄtinys neįkrautas"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Kompozicionavimo plÄtinys neprieinamas"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - konfigūracija"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "_Testas"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "_Nustatyti"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Pozicija"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animacija"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Tekstas"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Dekoracijos"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Sužadintojas"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Kita"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "ASXv3 GrojaraÅ¡Äiai"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 grojaraÅ¡Äiai"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious grojaraÅ¡Äiai (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Spalva</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Išsiliejimo sritis"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Profiliai:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Duoti lygį:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Nukirpti dažnius:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Profiliai:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Spektro analizatorius"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Audio CD įskiepis"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -844,171 +812,156 @@ msgstr ""
"\n"
"Tai buvo Google Summer Code 2007 projektas."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Įrenginys</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Skaitymo greitis:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Perrašyti įrenginį:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Meta duomenys</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Naudoti CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Naudoti CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Naudoti HTTP vietoj CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Serveris:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Kelias:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Prievadas:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Audio CD įskiepis"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "Inicijuoti cdio posistemÄs nepavyko."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "Netinkamas URI %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Takelis %d nerastas."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "Takelis %d yra duomenų takelis."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Atverti audio išvesties nepavyko."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Klaida skaitant audio CD."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Audio CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "Takelis %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Atverti CD įrenginio %s nepavyko."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "CD įrenginio suderinamo su audio nerasta."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "Nepavyko užbaigti inicijuoto atverto CD įrenginio."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Gauti pirmo/paskutinio takelio numerio nepavyko."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Perskaityti LSN takelio %d pradžios/pabaigos nepavyko."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Sukurti cddb sujungimo nepavyko."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Užlausti CDDB serverio nepavyko"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Užlausti CDDB serverio nepavyko: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Perskaityti cddb informacijÄ
nepavyko: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Diskasukis tuÅ¡Äias."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Nepalaikomas disko tipas."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Audio CD Meniu elementai"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Groti CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "PridÄti CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Audio CD Meniu elementai"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Glaudinimas</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Centro garsas:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "DinaminÄ sritis:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Dynamic Range Compression įskiepis skirtas Audacious\n"
-"AutorinÄs teisÄs 2010-2012 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Dynamic Range Compressor"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1024,206 +977,225 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Bosas:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Aukšti:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "Aidas:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Numatyta dainos trukmÄ:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>Perdarymas (resampling)</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Ä®jungti garso diskretizacijÄ
"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Diskretizacijos dažnis:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Nepaisyti trukmÄs iÅ¡ SPC žymų"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Padidinti reverb"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Žaidimų konsolÄs muzikos dekoderis"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-"Garso perÄjimo efektas nepavyko, nes dainos turi skirtingÄ
skaiÄių kanalų. "
-"Galite panaudoti kanalų mikÅ¡erio įrankį ir suvienodinti kanalų skaiÄių."
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"Garso perÄjimo efektas nepavyko, nes dainos turi skirtingus diskretizavimo "
-"dažnius. Galite panaudoti diskretizacijos konvertavimo įrankį ir paversti "
-"dainas į tÄ
patį dažnį."
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Crossfade Plugin skirtas Audacious\n"
-"AutorinÄs teisÄs 2010-2012 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Persidengimas</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "Perdengti:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Perdengimas"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"Garso perÄjimo efektas nepavyko, nes dainos turi skirtingÄ
skaiÄių kanalų. "
+"Galite panaudoti kanalų mikÅ¡erio įrankį ir suvienodinti kanalų skaiÄių."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"Garso perÄjimo efektas nepavyko, nes dainos turi skirtingus diskretizavimo "
+"dažnius. Galite panaudoti diskretizacijos konvertavimo įrankį ir paversti "
+"dainas į tÄ
patį dažnį."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Crystalizer</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intensyvumas:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Crystalizer"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Cue Sheet įskiepis"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Pašalinti failus"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "Klaida perkeliant %s į Å¡iukÅ¡linÄ: %s"
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "Klaida šalinant %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "Klaida šalinant %s: ne vietinis failas."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "Ar tikrai norite perkelti pasirinktus failus į Å¡iukÅ¡liadÄžÄ?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "Perkelti į Å¡iukÅ¡linÄ"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "Ar tikrai norite negrįžtamai ištrinti pasirinktus failus?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Ištrinti"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Atšaukti"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "Pašalinti failus"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "Pašalinti pasirinktus failus"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>Å alinimo metodas</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "Perkelti į Å¡iukÅ¡linÄ, iÅ¡kart nepaÅ¡alinti"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Aidas</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Delsa:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Garsinis atsakas:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Garsumas:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Echo Plugin\n"
-"SukÅ«rÄ Johan Levin, 1999\n"
-"\n"
-"Surround echo sukÅ«rÄ Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Aidas"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg įskiepis"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1239,55 +1211,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg įskiepis"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "FileWriter įskiepis"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Išvesties failo formatas:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Konfigūruoti"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Išsaugoti originalo aplanke"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Išsaugoti pasirinktame aplanke"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Paskirties aplankas:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Pasirinkite aplankÄ
"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Gauti failo vardÄ
iš:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "originalios failo žymÄs"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "originalus failo vardas"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "NeiÅ¡trinti failo plÄtinio"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Ä®dÄti takelio numerį į failo vardÄ
"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1319,165 +1291,169 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "FileWriter įskiepis"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Auto"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Sujungtas stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 konfigūravimas"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_Gerai"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Algoritmo kokybÄ:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Išvesties diskretizavimo dažnis:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Bitų dažnis / Kompresijos santykis:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Bitų dažnis(kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Kompresijos santykis:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Audio režimas:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Kita:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Priversti griežtai laikytis ISO suderinamumo"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Apsauga nuo klaidų"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "KokybÄ"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Įjungti VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tipas:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR pasirinktys:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Minimalus bitų dažnis (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Maksimalus bitų dažnis (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Griežtai laikytis minimalaus bitų dažnio"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR pasirinktys:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Vidutinis bitų dažnis (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR kokybÄs lygis:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "NeraÅ¡yti Xing VBR antraÅ¡tÄs"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "Kadro nustatymai:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "PažymÄti kaip saugomÄ
autorinių teisių"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "PažymÄti kaip originalÄ
"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ID3 parametrai"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Priverstinai pridÄti 2 versijos žymÄ
"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "PridÄti tik v1 žymÄ
"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "PridÄti tik v2 žymÄ
"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Žymos"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis koduotojo konfigūracija"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "KokybÄs lygis (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC dekoderis"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "lossless"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1489,11 +1465,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC dekoderis"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1501,11 +1473,19 @@ msgstr ""
"GIO įskiepis skirtas Audacious\n"
"AutorinÄs teisÄs 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO įskiepis"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1525,450 +1505,509 @@ msgstr ""
"\n"
"License: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL spektro analizatorius"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-msgstr ""
-"Gnome Shortcut įskiepis\n"
-"Suteikia galimybÄ valdyti grotuvÄ
su Gnome susiejimais.\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
"\n"
-"AutorinÄs teisÄs (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Gnome spartieji klavišai"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Įrašo numeris"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Pavadinimas"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "AtlikÄjas"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Metai"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Albumas"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Takelis"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Žanras"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Vieta eilÄje"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "TrukmÄ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Bylos kelias"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Bylos vardas"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Derintas pavadinimas"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Bitų seka"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "Prieinami stulpeliai"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "Rodomų stulpelių sÄ
rašas"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Paieškos įrankis"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Sumažinti į kairÄ"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Sumažinti į deÅ¡inÄ"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Sumažinti į viršų"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Sumažinti apaÄioje"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Padidinti"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Išjungti"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Paieškos įrankis"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Atverti failus ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Atverti _URL ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_PridÄti failus..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "PridÄti U_RL ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "Ieškoti _bibliotekoje"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "A_pie"
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "_Nustatymai..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Išeiti"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Groti"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Pauz_Ä"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Sustabdyti"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "Ankste_snis"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_Sekantis"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Kartoti"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "S_umaišyti"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "N_esislinkti grojaraÅ¡Äiu"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Sustabdyti _po šios dainos"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "Dainos _informacija ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Å okti į _laikÄ
"
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "_Pereiti prie dainos ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "Nustatyti kartojimo taÅ¡kÄ
_A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "Nustatyti kartojimo taÅ¡kÄ
_B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_Išvalyti kartojimo taškus"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Pagal _pavadinimÄ
"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "Pagal failo _vardÄ
"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Pagal failo _keliÄ
"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Pagal takelio _numerį"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Pagal _atlikÄjÄ
"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Pagal _albumÄ
"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Pagal iÅ¡leidimo _datÄ
"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "Pagal _trukmÄ"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Pagal _failo keliÄ
"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Pagal _derintÄ
eilutÄ"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "A_tvirkštine tvarka"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_Atsitiktine tvarka"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_Groti šį grojaraštį"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Atnaujinti"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Rikiuoti"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "Rikuoti _pasirinktus"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "Pašalinti _dubliuotus"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Pašalinti _neprieinamus failus"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Naujas"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "_Pervadinti"
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "_Å alinti"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Įkelti ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Eksportuoti ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "GrojaraÅ¡Äio _redaktorius"
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_EilÄs redaktorius ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Pagarsi_nti"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "Patil_dyti"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Ekvalaizeris"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "E_fektai..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Rodyti _meniu juostÄ
"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Rodyti i_nfo juostÄ
"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Rodyti informacijos juostos _vizualizacijÄ
"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Rodyti _bÅ«senos juostÄ
"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "_Rodyti likusį laikÄ
"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "_Vaizdiniai..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Failas"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Atkūrimas"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "G_rojaraštis"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Tarnybos"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Išvestis"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Rodymas"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Ä® eilÄ/IÅ¡ eilÄs"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Iškirpt_i"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Kopijuoti"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Įklijuoti"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Pasirinkti _viskÄ
"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_Pervadinti..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>GrojaraÅ¡Äio kortelÄs</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "Visada rodyti korteles"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "Rodyti įvesÄių skaiÄių"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "Rodyti uždarymo mygtukus"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>GrojaraÄio stulpeliai</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "Rodyti stulpelio antraštes"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Kita</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr "KrypÄių klaviÅ¡ai persuka:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "KeiÄiantis dainai slinkti"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK naudotojo sÄ
saja"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Įkraunama į atmintį ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
@@ -1976,84 +2015,98 @@ msgstr[0] "%d kanalas"
msgstr[1] "%d kanalai"
msgstr[2] "%d kanalų"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Vieno režimas."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "GrojaraÅ¡Äio režimas."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Sustabdymas po dainos."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Ankstesnis takelis"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Groti"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Sustabdyti/Paleisti"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Stabdyti"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Kitas takelis"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "5 sekundes į priekį"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "5 sekundes atgal"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Nutildyti"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Pagarsinti"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Pritildyti"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "PerÅ¡okti į failÄ
"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "Perjungti grotuvo langÄ
(-us)"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Rodyti On-Screen-Display"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "Perjungti kartojimÄ
"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "Perjungti maiÅ¡ymÄ
"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "Perjungti sustabdymÄ
po dabartinÄs"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Pakelti grotuvÄ
langÄ
(-us)"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(joks)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2064,15 +2117,11 @@ msgstr ""
"\n"
"TÄsti?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Saistyti pelÄs mygtukus"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Global Hotkey įskiepio konfigūravimas"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2080,23 +2129,27 @@ msgstr ""
"Paspauskite klavišų kombinacijÄ
teksto lauke.\n"
"Taip pat galima sieti ir pelÄs mygtukus."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Spartieji klavišai:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Veiksmas:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Klavišo susiejimas:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "_PridÄti"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Bendri karštieji klavišai"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2122,60 +2175,51 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Bendri karštieji klavišai"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK išvestis"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "Prisijungti prie visų prieinamų jack prievadų"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "Prisijungti tik prie išvesties prievadų"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "Nesijungti prie jokio prievado"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "Prisijungimo režimas:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "Įjungti derinimo pranešimus"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Paremta xmms-jack, kÅ«rÄ Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"PritaikÄ Audacious, Giacomo Lozito"
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK išvestis"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s nustatymai:"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA Host nustatymai"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Modulio kelias:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2186,25 +2230,25 @@ msgstr ""
"Kai pridedami nauji keliai, paspauskite ENTER naujų įskiepių paieškai.</"
"small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Prieinami įskiepiai:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Įjungti"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Įjungti įskiepiai:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Nustatymai"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2212,47 +2256,15 @@ msgstr ""
"LADSPA Host skirta Audacious\n"
"AutorinÄs teisÄs 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA Host"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: inicijuoti LIRC palaikymo nepavyko\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: nepavyko perskaityti LIRC konfigūracijos failo\n"
-"%s: paskaitykite LIRC dokumentacijÄ
\n"
-"%s: kaip sukurti tinkamÄ
konfigÅ«racijos failÄ
\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: bandoma prisijungti iš naujo...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: nežinoma komanda â%sâ\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: atsijungta nuo LIRC\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: bus bandoma prisijungti iš naujo kas %d sekundes...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC įskiepis"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2280,73 +2292,81 @@ msgstr ""
"\n"
"Apie LIRC galite sužinoti tinklalapy http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Prisijungimas</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "IÅ¡ naujo prisijungti prie LIRC serverio"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Prieš jungiantis iš naujo palaukti:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC įskiepis"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki įskiepis"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "NÄra prieinamų dainų žodžių"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Klaida"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Gauti %s nepavyko"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Klaida"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Apdoroti %s nepavyko"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Ieškoma dainų žodžių"
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Trūksta dainos metaduomenų"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Jungiamasi prie lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki įskiepis"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U grojaraÅ¡Äiai"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Takto generatorius"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Takto generatorius: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Takto generatorius: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2359,11 +2379,11 @@ msgstr ""
"pvz. tact://77 norint atkurt 77 dūžius per minutÄ\n"
"ar tact://60*3/4 norint atkurti 60 bpm 3/4 taktu"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Takto generatorius"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Kanalų mikšeris"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2371,152 +2391,184 @@ msgstr ""
"Channel Mixer įskiepis skirtas Audacious\n"
"AutorinÄs teisÄs 2011-2012 John Lindgren ir MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Kanalų mikšeris</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Išvesties kanalai:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Kanalų mikšeris"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS įskiepis"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Module grotuvas)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>Raiška</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bitai"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bitų"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Kanalai</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "ArÄiausias (greiÄiausia)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Linijinis (greitas)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Spline (gerai)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "Polifazinis (geriausiai)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>Diskretizacijos dažnis</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Lygis:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "Nukirpimas:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Reverb</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>Boso garsinimas</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>Erdvinis</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>Stiprinimas</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "Oversample"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Triukšmo mažinimas"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Groti Amiga MOD"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Kartoti</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "Kartojimų skaiÄius:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "NorÄdami kartoti amžinai, nustatykite â-1â."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Module grotuvas)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Erdvinis garsas"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 įskiepis"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>SudÄtingesni</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Erdvinis garsas"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 Serveris"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS įskiepis"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Sustabdyta"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious negroja."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Darbastalio pranešimai"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2552,55 +2604,64 @@ msgstr ""
"You should have received a copy of the GNU General Public License along with "
"this program. If not, see <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Rodyti atkÅ«rimo valdymÄ
"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Visada rodyti praneÅ¡imÄ
"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Darbastalio pranešimai"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Rodyti"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "PauzÄ"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Sekantis"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Numatytasis įrenginys"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 išvestis"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Audio įrenginys:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Naudoti alternatyvų įrenginį:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "IÅ¡saugoti garsÄ
tarp sesijų"
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Ä®galinti formato keitimÄ
kurį padarÄ OSS programinÄ Ä¯ranga."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Ä®galinti iÅ¡skirtinį režimÄ
, siekiant išvengti virtualaus maišymosi."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2614,19 +2675,35 @@ msgstr ""
"NorÄÄiau padÄkoti žmonÄms #audacious kanale, ypatingai Tony Vroon ir John "
"Lindgren ir savaime aiÅ¡ku ankstesnÄs OSS įskiepio versijos autoriams."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 išvestis"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS grojaraÅ¡Äiai"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2 dekoderis"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio išvestis"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2662,11 +2739,68 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio išvestis"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Ieškoti"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Ankstesnis"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Kartoti"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Maišyti"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Diskretizavimo dažnio keitÄjas"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2674,98 +2808,106 @@ msgstr ""
"Sample Rate Converter Plugin for Audacious\n"
"AutorinÄs teisÄs 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "Praleisti/kartoti pavyzdžius"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "LinijinÄ interpoliacija"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Greita interpoliacija"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "VidutinÄ interpoliacija"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Geriausia interpoliacija"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Konvertavimas</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Metodas:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Dažnis:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Dažnio nustatymai</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Naudoti dažnio nustatymus"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Diskretizavimo dažnio keitÄjas"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "Gerai. Ieškoma informacijos naudotojui: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "Neleidžiama"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"Nueikite Å¡ia nuoroda ir leiskite Audacious gauti informacijÄ
apie dainas:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"Palikite šį langÄ
atvertÄ
ir paspauskite âTikrinti leidimusâ dar kartÄ
.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2773,33 +2915,37 @@ msgstr ""
"Nesijaudinkite. Jūsų informacija saugoma kompiuteryje.\n"
"Ji bus išsiųsta kai tik Audacious leis tai padaryti."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "Tinklo problema."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "Bandant susisiekti su Last.fm įvyko klaida. Pabandykite vÄliau."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "Tikrinama..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "_Tikrinti leidimus"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_AtÅ¡aukti leidimÄ
"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"Turite leisti Audacious perduoti takelių informacijÄ
jūsų Last.fm paskyrai.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2807,7 +2953,7 @@ msgstr ""
"Scrobbler įskiepio paleisti nepavyko.\n"
"Gali būt jog yra problemų su jūsų įdiegimu."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2824,11 +2970,7 @@ msgstr ""
"DÄkojame John Lindgren už pagalbÄ
.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2836,7 +2978,11 @@ msgstr ""
"Nuo Å¡iol audacious naudoja patobulintÄ
last.fm apdoroklio versijÄ
.\n"
"PažiÅ«rÄkite apdoroklio nustatymuose."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL išvestis"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2844,88 +2990,59 @@ msgstr ""
"SDL Output Plugin skirtas Audacious\n"
"AutorinÄs teisÄs 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL išvestis"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Fonoteka"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Nežinomas atlikÄjas"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Nežinomas albumas"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" ant %s su %s"
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d albumas"
-msgstr[1] "%d albumai"
-msgstr[2] "%d albumų"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-"%s\n"
-" %s, %d daina"
msgstr[1] ""
-"%s\n"
-" %s, %d dainos"
msgstr[2] ""
-"%s\n"
-" %s, %d dainų"
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
-"%s\n"
-" %d daina kuriÄ
sukÅ«rÄ %s"
msgstr[1] ""
-"%s\n"
-" %d dainos kurias sukÅ«rÄ %s"
msgstr[2] ""
-"%s\n"
-" %d dainų kurias sukÅ«rÄ %s"
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Sukurti grojaraštį"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_PridÄti į grojaraÅ¡tį"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Ieškoti fonotekoje"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2933,679 +3050,769 @@ msgstr ""
"NorÄdami importuoti muzikÄ
į Audacious fonotekÄ
, pasirinkite aplankÄ
ir "
"paspauskite âatnaujintiâ piktogramÄ
."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Palaukite..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Pasirinkite aplankÄ
"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "Atverti failus..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "Atverti URL..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Atkūrimas"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Grojaraštis"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Rodymas"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "Tarnybos"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "Apie..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "Nustatymai..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "Baigti"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "Dainos informacija..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Kartoti"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Maišyti"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Nesislinkti grojaraÅ¡Äiu"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "Sustabdyti po šios dainos"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Ankstesnis"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "Nustatyti A-B kartojimÄ
"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "IÅ¡valyti A-B kartojimÄ
"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "Pereiti prie dainos ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "Å okti į laikÄ
..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "Groti šį grojaraštį"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Naujas grojaraštis"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "Pervadinti grojaraštį..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "Pašalinti grojaraštį"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "Ankstesnis grojaraštis"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "Sekantis grojaraštis"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "Įkelti grojaraštį..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "Eksportuoti grojaraštį..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "GrojaraÅ¡Äių redaktorius..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "EilÄs redaktorius ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "Atnaujinti grojaraštį"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Rodyti grojaraÅ¡Äio redaktorių"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Rodyti ekvalaizerį"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "Rodyti likusį laikÄ
"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Visada viršuje"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "Visuose darbalaukiuose"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "Sustumti grotuvÄ
"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "Sustumti grojaraÅ¡Äio redaktorių"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "Sustumti ekvalaizerį"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "PridÄti URL..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "PridÄti failus..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Pagal pavadinimÄ
"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Pagal failo vardÄ
"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "Pagal failo keliÄ
"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Pašalinti visus"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "IÅ¡valyti eilÄ"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Pašalina neprieinamus failus"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Pašalinti dubliuotus"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "PaÅ¡alint nepažymÄtus"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "PaÅ¡alint pažymÄtus"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Ieškoti ir pasirinkti"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Invertuoti pažymÄjimÄ
"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Nieko nepasirinkti"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Pasirinkti viskÄ
"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Pagal albumÄ
"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Pagal takelio numerį"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Pagal atlikÄjÄ
"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Pagal albumÄ
"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "Pagal iÅ¡leidimo datÄ
"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Pagal takelio numerį"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "SumaiÅ¡yti sÄ
raÅ¡Ä
"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Apversti sÄ
raÅ¡Ä
"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Rikuoti pasirinktus"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Rikiuoti sÄ
raÅ¡Ä
"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Iškirpti"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Kopijuoti"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Įklijuoti"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "Ä® eilÄ/IÅ¡ eilÄs"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "Ä®krauti Å¡ablonÄ
..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "Ä®krauti savaime įsikraunantį Å¡ablonÄ
..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "Įkelti numatytus"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "Ä®krauti Å¡ablonÄ
iš failo..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "Ä®kelti EQF failÄ
..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "IÅ¡saugoti Å¡ablonÄ
..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "IÅ¡saugoti savaime įsikraunantį Å¡ablonÄ
..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "Įrašyti numatytuosius"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "IÅ¡saugoti Å¡ablonÄ
į failÄ
..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "IÅ¡saugoti Å¡ablonÄ
į EQF failÄ
..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "PaÅ¡alinti Å¡ablonÄ
..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "IÅ¡trinti savaime įsikraunantį Å¡ablonÄ
..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "Importuoti WinAMP šablonus..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "Atstatyti nulį"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "KlasikinÄ Winamp sÄ
saja"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Išsaugoti"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Įkrauti"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "Ä®krauti Å¡ablonÄ
iš failo"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "Ä®kelti EQF failÄ
"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "IÅ¡saugoti Å¡ablonÄ
į failÄ
"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "IÅ¡saugoti Å¡ablonÄ
į EQF failÄ
"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "Importuoti WinAMP šablonus"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Å ablonai"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Ä®krauti Å¡ablonÄ
"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Įkrauti auto išankstinius nustatymus"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Išsaugoti šablonus"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Išsaugoti auto išankstinius nustatymus"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "IÅ¡trinti Å¡ablonÄ
"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Ištrinti auto išankstinius nustatymus"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Grotuvas:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Pasirinkti pagrindinį lango Å¡riftÄ
:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Grojaraštis:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Pasirinkti grojaraÅ¡Äio Å¡riftÄ
:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>Išvaizda</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>Å riftai</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Naudoti bitmap šriftus (palaiko tik ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "Slinkti pavadinimÄ
"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Slinkti pavadinimÄ
į abi puses"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analizatorius"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Sritis"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "Voiceprint / VU meter"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Išjungta"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normalus"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Ugnis"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "Vertikalios linijos"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Linijos"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Juostos"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "LÄÄiausias"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "LÄtas"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Vidutinis"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Greitas"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "GreiÄiausias"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "Taškai"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "EilutÄ "
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "Vientisa"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Ledas"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Tolygus"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>Tipas</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "Vaizdo efektų tipas:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>Analizatorius</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "Rodyti pikus"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "Spalvinimas:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "Stilius:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "Pikų krytis:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "Pikų krytis:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "Srities stilius:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "Voiceprint spalvojimas:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "VU Meter stilius:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "PagrindinÄs"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Vizualizacija"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Preamp"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious ekvalaizeris"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Eiti į %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Garsumas: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balansas: %d%% kairÄ"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balansas: centras"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balansas: %d%% deÅ¡inÄ"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "PasirinkÄių meniu"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "IÅ¡jungti âVisada virÅ¡ujeâ"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Ä®jungti âVisada virÅ¡ujeâ"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Failo informacijos langas"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "Kartojimo taškas A nustatytas."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "Kartojimo taškas B nustatytas."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "Kartojimo taškai išvalyti."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Vieno režimas."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "GrojaraÅ¡Äio režimas."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Sustabdymas po dainos."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Ieškoti įrašų aktyviame grojaraštyje"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "Ieškoti"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3617,57 +3824,61 @@ msgstr ""
"nesvarbus. Jei nežinai kaip veikia reguliariosios iÅ¡raiÅ¡kos, paprasÄiausiai "
"įrašyk paraidžiui tai ko ieškai."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Pavadinimas:"
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Albumas:"
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "AtlikÄjas:"
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Failo vardas:"
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Prie ieškant, išvalyti buvusius pasirinkimus"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Atitinkantiems įraÅ¡ams automatiÅ¡kai perjungti eilÄ"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "IÅ¡ surastų įrašų sukurti naujÄ
grojaraštį"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audacious grojaraÅ¡Äio redaktorius"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d iš %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Archyvuotas Winamp 2.x skin"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Išarchyvuotas Winamp 2.x skin"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Negaliu sukurti aplanko (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile įskiepis"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3707,83 +3918,71 @@ msgstr ""
"this program; if not, write to the Free Software Foundation, Inc., 51 "
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile įskiepis"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Apie Sndio Output įskiepį"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-"Sndio Output Plugin\n"
-"\n"
-"SukÅ«rÄ Thomas Pfaff <tpfaff at tp76.info>\n"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Nepalaikomas formatas"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-"Garso įrenginys šio formato nepalaiko.\n"
-"\n"
-"Pabandykite dar kartÄ
su paleistu sndiod(1) serveriu."
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio įrenginys"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(tuÅ¡Äia reiÅ¡kia numatytÄ
)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "Gerai"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Dainos keitimas"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Komanda kuriÄ
paleisti kai Audacious paleidžia naujÄ
dainÄ
."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Parametrai pateikti komandų interpretatoriui turi būti "
+"kabutÄse. Darant kitaip rizikuojate savo saugumu.</span>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Komanda:"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Komanda kuriÄ
paleisti prieš pasibaigiant dainai."
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "Komanda kuriÄ
paleisti kai Audacious pasiekia grojaraÅ¡Äio pabaigÄ
."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Komanda kuriÄ
paleisti kai dainos pavadinimas pasikeiÄia (t.y. interneto "
-"srautų pavadinimai)"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3797,35 +3996,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Galite naudoti tokio formato eilutes, kurios\n"
-"prieÅ¡ kvieÄiant komandÄ
bus pakeistos (ne visos\n"
-"tinka end-of-playlist komandai):\n"
-"\n"
-"%F: Dažnis (hercais)\n"
-"%c: Kanalų skaiÄius\n"
-"%f: Failo vardas (pilnas kelias)\n"
-"%l: TrukmÄ (millisekundÄmis)\n"
-"%n ar %s: Dainos vardas\n"
-"%r: Dažnis (bitais per sekundÄ)\n"
-"%t: GrojaraÅ¡Äio vieta (%02d)\n"
-"%p: Å iuo metu grojama (1 arba 0)\n"
-"%a: AtlikÄjas\n"
-"%b: Albumas\n"
-"%T: Takelio pavadinimas"
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>Parametrai pateikti komandų interpretatoriui turi būti "
-"kabutÄse. Darant kitaip rizikuojate savo saugumu.</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Komandos"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX Resampler"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3836,51 +4016,51 @@ msgstr ""
"SoX Resampler įskiepis skirtas Audaciousâ Copyright 2013 MichaÅ Lipskiâ â "
"Paremta Sample Rate Converter įskiepiu:â Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Greita"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Žema"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Aukšta"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Labai aukšta"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "KokybÄ:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Greitis ir žingsnis"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Greitis ir žingsnis</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Greitis:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Žingsnis:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Greitis ir žingsnis"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Būsenos piktograma"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "Nus_tatymai..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3898,39 +4078,39 @@ msgstr ""
"Å is įskiepis suteikia bÅ«senos piktogramÄ
, kuri\n"
"rodoma sistemos dÄkle."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>PelÄs slinkimo veiksmas</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Keisti garsÄ
"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Keisti grojanÄiÄ
dainÄ
"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Kiti nustatymai</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "IÅ¡jungti iššokantį langÄ
"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Užverti į sistemos dÄklÄ
"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Slenkant aukÅ¡tyn, žengti grojaraÅ¡Äiu"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Būsenos piktograma"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Stereo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3940,24 +4120,24 @@ msgstr ""
"\n"
"SukÅ«rÄ Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra Stereo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Tono generatorius"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Tono generatorius: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3971,15 +4151,11 @@ msgstr ""
"NorÄdami naudoti, pridÄkite URL: tone://dažnis1;dažnis2;dažnis3;...\n"
"pvz. tone://2000;2005 norint atkurti 2000 Hz tonÄ
ir 2005 Hz tonÄ
"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Tono generatorius"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Balso pašalinimas"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4017,11 +4193,35 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis dekoderis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX Decoder"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4031,19 +4231,19 @@ msgstr ""
"Paremta in_vtx.dll kurį sukÅ«rÄ Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious įskiepį sukÅ«rÄ Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX Decoder"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack dekoderis"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "lossy (hibridinis)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "lossy"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4053,14 +4253,18 @@ msgstr ""
"\n"
"Dalį kodo paraÅ¡Ä Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack dekoderis"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF dekoderis"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "XML vieÅ¡inami grojaraÅ¡Äiai (XSPF)"
diff --git a/po/lv.po b/po/lv.po
index 9d248c9d960c..85f87fbd75cc 100644
--- a/po/lv.po
+++ b/po/lv.po
@@ -3,14 +3,14 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# hairy_latvian <einars8 at gmail.com>, 2013-2014
+# hairy_latvian <einars8 at gmail.com>, 2013-2015
# hairy_latvian <einars8 at gmail.com>, 2009,2011-2013
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:49+0000\n"
+"POT-Creation-Date: 2015-04-03 11:52+0200\n"
+"PO-Revision-Date: 2015-03-24 10:07+0000\n"
"Last-Translator: hairy_latvian <einars8 at gmail.com>\n"
"Language-Team: Latvian (http://www.transifex.com/projects/p/audacious/"
"language/lv/)\n"
@@ -21,40 +21,28 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : "
"2);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "ieskaušana"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "AAC (MP4) dekodÄtÄjs"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "AAC (jÄldati) dekodÄtÄjs"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib atskaÅotÄjs)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "sekvencÄts"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib atskaÅotÄjs)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "ModinÄtÄjs"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "IestatÄ«t signÄlu ..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -64,11 +52,7 @@ msgstr ""
"\n"
"SÄkotnÄjie autori: Adam Feakin un Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "ModinÄtÄjs"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -109,7 +93,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -148,7 +132,7 @@ msgstr ""
" palaist Å¡o komandu, noskanot modinÄtÄjam.\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -172,384 +156,389 @@ msgstr ""
" pÄrslÄgÅ¡anas pogu, ja vÄlaties, lai atgÄdinÄjums\n"
" tiek parÄdÄ«ts."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Å is ir jÅ«su moÅ¡anÄs zvans."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "JÅ«su atgÄdinÄjums Å¡odienai ir..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "AtgÄdinÄjums"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Pirmdiena"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Otrdiena"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Trešdiena"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Ceturtdiena"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Piektdiena"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Sestdiena"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "SvÄtdiena"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "ModinÄtÄjs iestatÄ«jumi"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "_Labi"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "_Atcelt"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Laiks"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "ModinÄt (noklusÄjums):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Kluss pÄc:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "stundas"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minūtes"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "IzvÄlieties dienas, kurÄs ieslÄgsies modinÄtÄjs"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Diena"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "NoklusÄtais"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Dienas"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Izdzišana"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "sekundes"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Skaļums"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "SÄkumÄ"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "BeigÄs"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "PaÅ¡reizÄjais"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Papildu komanda"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "ieslÄgt"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "RepertuÄrs (neobligÄts)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "IzvÄlieties repertuÄru"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Opcijas"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Ko šīs opcijas nozÄ«mÄ?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Palīdzība"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Albuma vÄks"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Albuma vÄks (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA izvade"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ALSA izvades spraudnis atskaÅotÄjam Audacious\n"
+"Autortiesības 2009-2012 John Lindgren\n"
+"\n"
+"Paldies William Pitcock, ALSA NG izvades spraudÅa autoram, kura kods kalpoja "
+"kÄ paraugs, kad ar ALSA rokasgrÄmatu vien nepietika."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(bez apraksta)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "NoklusÄtÄ PCM ierÄ«ce"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "NoklusÄtÄ miksera ierÄ«ce"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM ierīce:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Miksera ierīce:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Miksera elements:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Apiet 'drain hangup' problÄmai"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI atskaÅotÄjs)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"ALSA izvades spraudnis atskaÅotÄjam Audacious\n"
-"Autortiesības 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modulÄrs MIDI mÅ«zikas atskaÅotÄjs\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"Paldies William Pitcock, ALSA NG izvades spraudÅa autoram, kura kods kalpoja "
-"kÄ paraugs, kad ar ALSA rokasgrÄmatu vien nepietika."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA izvade"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI atskaÅotÄjs)"
+"Autors Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"Īpašs paldies...\n"
+"\n"
+"Clemens Ladisch un Jaroslav Kysela\n"
+"par viÅu programmÄm aplaymidi and amixer; tÄs, lÄ«dz ar alsa-lib dokumentiem, "
+"bija ļoti noderÄ«gas, mÄcoties par ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"par jauku midi klaviatūras logo\n"
+"\n"
+"Tony Vroon\n"
+"par palÄ«dzÄ«bu alfa testÄÅ¡anÄ"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "AizstÄt noklusÄto pastiprinÄjumu:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "AizstÄt noklusÄto polifoniju:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "AizstÄt noklusÄto atbalsi: "
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "IeslÄgts"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "AizstÄt noklusÄto kori:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>AtskaÅoÅ¡ana</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "PÄrlikt:"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "pustoÅi"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "Bungu pÄrbÄ«de:"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>PaplaÅ¡inÄti</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "nošu numuri"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "izvilkt komentÄrus no MIDI faila"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Izlaist klusumu sÄkumÄ"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "izvilkt dziesmu vÄrdu tekstus no MIDI faila"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Izlaist klusumu beigÄs"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>Sintezators</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr "Iztveršanas temps:"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug â izvÄlieties SoundFont failu"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Atcelt"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "_AtvÄrt"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Faila nosaukums"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "IzmÄrs (baitos)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nosaukums:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI informÄcija </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "FormÄts:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Garums (ms):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "CeliÅu skaits:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "mainīgais"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Laika dalÄ«tÄjs:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI KomentÄri un dziesmu vÄrdu teksti </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* komentÄri Å¡ajÄ MIDI failÄ nav pieejami *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* dziesmu vÄrdu teksti Å¡ajÄ MIDI failÄ nav pieejami *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "Ai_zvÄrt"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (nederīgs UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "About AMIDI spraudni"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI spraudnis"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"modulÄrs MIDI mÅ«zikas atskaÅotÄjs\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"autors Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"īpašs paldies...\n"
-"\n"
-"Clemens Ladisch un Jaroslav Kysela\n"
-"par viÅu jaukajÄm programmÄm aplaymidi un amixer;\n"
-"šīs programmas, lÄ«dz ar alsa-lib dokumentÄciju, bija ļoti\n"
-"noderÄ«gas, lai uzzinÄtu vairÄk par ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"par jauku midi klaviatūras logo\n"
-"\n"
-"Tony Vroon\n"
-"par palÄ«dzÄ«bu alfa-testÄÅ¡anÄ"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -567,152 +556,146 @@ msgstr ""
"DaļÄji balstÄ«ts uz Evan Martin Ghosd bibliotÄku:\n"
"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (virsekrÄna displejs)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Taisnstūris"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Noapaļots taisnstrūris"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Ieliekts taisnstrūris"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Neviens"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "AtskaÅoÅ¡anas sÄkums"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Palaiž OSD, kad tiek atskaÅots repertuÄra ieraksts."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Nosaukuma maiÅa"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
-msgstr ""
-"Palaiž OSD, kad, atskaÅoÅ¡anas laikÄ, dziesmas nosaukums mainÄs, bet faila "
-"nosaukums paliek nemainÄ«gs. Tas galvenokÄrt ir noderÄ«gi, lai attÄlotu "
-"interneta straumju nosaukumu maiÅu."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
+msgstr "Palaiž OSD, izmainoties dziesmas nosaukumam (interneta straumÄm)."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Pauze ieslÄgta"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Palaiž OSD, kad tiek nopauzÄta atskaÅoÅ¡ana."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Pauze izslÄgta"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Palaiž OSD, kad tiek atjaunota atskaÅoÅ¡ana pÄc pauzes."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Novietojums"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "RelatÄ«vÄ X nobÄ«de:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "RelatÄ«vÄ Y nobÄ«de:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "MaksimÄlais OSD platums:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Daudzmonitoru opcijas"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "RÄdÄ«t OSD izmantojot:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "visi monitori"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "%i. monitors"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Ilgums (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "RÄdÄ«t:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "ParÄdÄ«ties:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Izgaist:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Fonti"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "%i. fonts:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Äna"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "RenderÄÅ¡anas stils"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "KrÄsas"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "%i. krÄsa:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "IeslÄgt palaidÄju"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Notikums"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "KompozitÄÅ¡anas pÄrvaldnieks atrasts"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -722,112 +705,112 @@ msgstr ""
"ja vien esat pÄrliecinÄts, ka jums tas ir palaists, lÅ«dzu, aktivizÄjiet "
"kompozitÄÅ¡anas pÄrvaldnieku, citÄdi OSD nefunkcionÄs pareizi"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Viltus caurspÄ«dÄ«bai kompozitÄÅ¡anas pÄrvaldnieks nav nepiecieÅ¡ams"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Caurspīdība"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Viltus caurspīdība"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Īsta caurspīdība (nepieciešams X Composite paplašin.)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Composite paplaÅ¡inÄjums nav ielÄdÄts"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Composite paplaÅ¡inÄjums nav pieejams"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - konfigurÄcija"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "_PÄrbaudÄ«t"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "Ie_statīt"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Novietojums"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "AnimÄcija"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Teksts"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "NoformÄjums"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "PalaidÄjs"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "DažÄdi"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "TestÄt"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "ASXv3 repertuÄri"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 repertuÄri"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious repertuÄri (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>KrÄsa</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Blur Scope"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer stereofoniski-uz-binaurÄli (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Gatavie regulÄjumi:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Barošanas līmenis:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Nogriešanas frekvence:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Gatavie regulÄjumi:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer stereofoniski-uz-binaurÄli (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Spektra analizators"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Audio CD spraudnis"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -847,172 +830,159 @@ msgstr ""
"\n"
"Å is bija Google Summer of Code 2007 projekts."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Ierīce</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Lasīšanas Ätrums:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "AizstÄt ierÄ«ci:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadati</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Lietot CD-text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Lietot CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Lietot HTTP nevis CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Serveris:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Ceļš:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Ports:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Audio CD spraudnis"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "NeizdevÄs inicializÄt cdio apakÅ¡sistÄmu."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "Nederīgs URI %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "CeliÅÅ¡ %d netika atrasts."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "CeliÅÅ¡ %d ir datu celiÅÅ¡."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "NeizdevÄs atvÄrt audio izvadi."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Kļūda nolasot audio CD."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Audio CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "CeliÅÅ¡ %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "NeizdevÄs atvÄrt CD ierÄ«ci %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Netika atrasts CD dzinis ar audio atskaÅoÅ¡anas iespÄju."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "NeizdevÄs pabeigt inicializÄt atvÄrtu CD dzini."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "NeizdevÄs saÅemt pirmÄ/pÄdÄjÄ celiÅa numuru."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "NeizdevÄs nolasÄ«t LSN sÄkumu/beigas celiÅam %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "NeizdevÄs izveidot cddb savienojumu."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "NeizdevÄs aptaujÄt CDDB serveri."
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "NeizdevÄs aptaujÄt CDDB serveri: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "NeizdevÄs nolasÄ«t cddb informÄciju: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Dzinis ir tukšs."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Neatbalstīts diska tips."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Audio CD izvÄlnes elementi"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "AtskaÅot CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Pievienot CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Audio CD izvÄlnes elementi"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Kompresija</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Centra skaļums:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Dinamiskais diapazons:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"DinamiskÄ diapozona kompresijas spraudnis atskaÅotÄjam\n"
"Audacious\n"
-"Autortiesības 2010-2012 John Lindgren"
+"Autortiesības 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "DinamiskÄ diapazona kompresors"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1028,206 +998,239 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Bass:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Augstie toÅi:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "Atbalss:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "NoklusÄtais dziesmas garums:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>IztverÅ¡anas tempa pÄrveidoÅ¡ana</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "IeslÄgt audio iztverÅ¡anas tempa pÄrveidoÅ¡anu"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Iztveršanas temps:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "IgnorÄt garums no SPC tagiem"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "PalielinÄt atbalsi"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "SpÄļu konsoles mÅ«zikas dekodÄtÄjs"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"SapludinÄÅ¡ana neizdevÄs, jo dziesmÄm ir dažÄds kanÄlu skaits. Varat izmantot "
-"kanÄlu mikseri, lai pÄrveidotu abas dziesmas uz vienÄdu kanÄlu skaitu."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "CoreAudio izvade"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"SapludinÄÅ¡ana neizdevÄs, jo dziesmÄm ir dažÄdas diskretizÄcijas frekvences. "
-"Varat izmantot diskretizÄcijas frekvenÄu pÄrveidotÄju, lai pÄrveidotu "
-"dziesmas uz vienu diskretizÄcijas frekvenci."
+"CoreAudio izvades spraudnis atskaÅotÄjam Audacious\n"
+"Autortiesības 2014 William Pitcock\n"
+"\n"
+"BÄzÄts uz Audacious SDL izvades spraudÅa\n"
+"Autortiesības 2010 John Lindgren"
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "Izmantot ekskluzīvo režīmu"
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"SapludinÄÅ¡anas spraudnis atskaÅotÄjam Audacious\n"
-"Autortiesības 2010-2012 John Lindgren"
+"Autortiesības 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>SapludinÄÅ¡ana</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "AutomÄtiski mainoties dziesmai"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "PÄrklÄÅ¡anÄs:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "MeklÄjot vai paÅ¡rocÄ«gi mainot dziesmu"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Padoms</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+"LabÄkai sapludinÄÅ¡anai, ieslÄdziet\n"
+"klusuma izÅemÅ¡anas efektu."
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "SapludinÄÅ¡ana"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"SapludinÄÅ¡ana neizdevÄs, jo dziesmÄm ir dažÄds kanÄlu skaits. Varat izmantot "
+"kanÄlu mikseri, lai pÄrveidotu abas dziesmas uz vienÄdu kanÄlu skaitu."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"SapludinÄÅ¡ana neizdevÄs, jo dziesmÄm ir dažÄdas diskretizÄcijas frekvences. "
+"Varat izmantot diskretizÄcijas frekvenÄu pÄrveidotÄju, lai pÄrveidotu "
+"dziesmas uz vienu diskretizÄcijas frekvenci."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Kristalizators</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "IntensitÄte:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Kristalizators"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Cue lapas spraudnis"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "DzÄst failus"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "Kļūda pÄrvietojot %s uz miskasti: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "Kļūda dzÄÅ¡ot %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "Kļūda dzÄÅ¡ot %s: nav vietÄjais fails."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "Vai vÄlaties izvÄlÄtos failus pÄrvietot uz miskasti?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "PÄrvietot uz miskasti"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "Vai vÄlaties izvÄlÄtos failus dzÄst uz visiem laikiem?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "DzÄst"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Atcelt"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "DzÄst failus"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "DzÄst izvÄlÄtos failus"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>DzÄÅ¡anas metode</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "PÄrvietot uz miskasti nevis dzÄst nekavÄjoties"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+"Atbalss spraudnis\n"
+"Autors Johan Levin, 1999\n"
+"IeskaujoÅ¡Äs atbalss autors Carl van Schaik, 1999\n"
+"AtskaÅotÄjam Audacious atjauninÄjuÅ¡i William Pitcock un John Londgren, "
+"2010-2014"
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Atbalss</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Aizture:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Atbilde:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Skaļums:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Atbalss spraudnis\n"
-"Autors Johan Levin, 1999\n"
-"\n"
-"IeskaujoÅ¡Äs atbalss autors Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Atbalss"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg spraudnis"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1243,55 +1246,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg spraudnis"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Failu rakstÄ«tÄja spraudnis"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Izvades faila formÄts:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "KonfigurÄt"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "SaglabÄt oriÄ£inÄlajÄ mapÄ"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "SaglabÄt pielÄgotÄ mapÄ"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Izvades faila mape:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "IzvÄlieties mapi"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Iegūt faila nosaukumu no:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Ä¢enerÄt faila nosaukumu no:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "oriÄ£inÄlajiem faila tagiem"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "OriÄ£inÄlais faila tags"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "oriÄ£inÄlÄ faila nosaukuma"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "OriÄ£inÄlais faila nosaukums"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Neatmest faila paplaÅ¡inÄjumu"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "Iekļaut oriÄ£inÄlo faila nosaukuma paplaÅ¡inÄjumu"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Pievienot celiÅa numuru pirms faila nosaukuma"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr "Pievienot celiÅa numuru faila nosaukumam"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1321,165 +1324,169 @@ msgstr ""
"Ja tÄ nav, rakstiet uz Free Software Foundation, Inc., 51 Franklin Street,\n"
"Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "Failu rakstÄ«tÄja spraudnis"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "AutomÄtiski"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Joint Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 konfigurÄcija"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_Labi"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Algoritma kvalitÄte:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Izvades diskretizÄcijas frekvence:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr "Izvades iztveršanas temps:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "BitÄtrums / Kompresijas attiecÄ«ba:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "BitÄtrums/Kompresijas attiecÄ«ba:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "BitÄtrums (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Kompresijas attiecība:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Audio režīms:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "DažÄdi:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
msgstr "Uzspiest stingru ISO savietojamību"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Kļūdu aizsardzība"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "KvalitÄte"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "IeslÄgt VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tips:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR opcijas:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "MinimÄlais bitÄtrums (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "MaksimÄlais bitÄtrums (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Stingri uzspiest minimÄlo bitÄtrumu"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR opcijas:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "VidÄjais bitÄtrums (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR kvalitÄtes lÄ«menis:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Nerakstīt Xing VBR galveni"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Atmest Xing VBR galveni"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr "Kadra parametri:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "AtzÄ«mÄt kÄ autortiesÄ«bÄm aizsargÄtu"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "AtzÄ«mÄt kÄ oriÄ£inÄlu"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "ID3 parametri:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Uzspiest 2. versijas tagu pievienošanu"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Pievienot tikai 1. versijas tagu"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Pievienot tikai 2. versijas tagu"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Tagi"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis kodÄtÄja konfigurÄcija"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "KvalitÄtes lÄ«menis (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC dekodÄtÄjs"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "bezzudumu"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1491,11 +1498,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC dekodÄtÄjs"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1503,11 +1506,19 @@ msgstr ""
"GIO spraudnis atskaÅotÄjam Audacious\n"
"Autortiesības 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO spraudnis"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "Režīms lasīt-un-pievienot nav atbalstīts"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "Neatļauts atvÄrÅ¡anas režīms"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1527,14 +1538,44 @@ msgstr ""
"\n"
"Licence: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL spektra analizators"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+"OpenGL spektra analizators atskaÅotÄjam Audacious\n"
+"Autortiesības 2013 Christophe Budé, John Lindgren un Carlo Bramini\n"
+"Autortiesības 2014 William Pitcock\n"
+"\n"
+"Balstīts uz XMMS spraudni:\n"
+"Autortiesības 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson "
+"un 4Front Technologies\n"
+"\n"
+"Licence: GPLv2+"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "OpenGL spektra analizators (Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "GNOME īsceļi"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
@@ -1543,434 +1584,476 @@ msgstr ""
"\n"
"Autortiesības (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Gnome īsceļi"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Ieraksta numurs"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Nosaukums"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "IzpildÄ«tÄjs"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Gads"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Albums"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Albuma izpildÄ«tÄjs"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "CeliÅÅ¡"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Žanrs"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Novietojums rindÄ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Ilgums"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Faila ceļš"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Faila nosaukums"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "PielÄgots nosaukums"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "BitÄtrums"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "PieejamÄs kolonnas"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "ParÄdÄ«tÄs kolonnas"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "MeklÄÅ¡anas rÄ«ks"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Pietauvot pa kreisi"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Pietauvot pa labi"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Pietauvot augÅ¡Ä"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Pietauvot apakÅ¡Ä"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Attauvot"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "AtslÄgt"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "MeklÄÅ¡anas rÄ«ks"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "AtvÄrt _failus ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "AtvÄrt _URL ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "Pievienot f_ailus ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Pievienot U_RL ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "MeklÄt _bibliotÄkÄ"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "_Par ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "I_estatījumi ..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "I_ziet"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "A_tskaÅot"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Pauz_e"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Stop"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_IepriekÅ¡Äjais"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_NÄkamais"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_AtkÄrtot"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_Jaukt"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Ne_virzÄ«ties uz priekÅ¡u repertuÄrÄ"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Apt_urÄt pÄc šīs dziesmas"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "Dziesmas _info ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "PÄriet uz _laiku ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "PÄriet uz _dziesmu ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "IestatÄ«t atkÄrtojuma punktu _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "IestatÄ«t atkÄrtojuma punktu _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_NotÄ«rÄ«t atkÄrtojuma punktus"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "PÄc n_osaukuma"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "PÄc _faila nosaukuma"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "PÄc _faila ceļa"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "PÄc faila _ceļa"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "PÄc celiÅa _numura"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "PÄc _izpildÄ«tÄja"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "PÄc a_lbuma"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "PÄc albu_ma izpildÄ«tÄja"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "PÄc izlaiÅ¡anas _datuma"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "PÄ_c žanra"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "PÄc _ilguma"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "PÄc _faila ceļa"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "PÄc _pielÄgota nosaukuma"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Apgri_eztÄ kÄrtÄ«bÄ"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "NejauÅ¡Ä _kÄrtÄ«bÄ"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_AtskaÅot Å¡o repertuÄru"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_AtskaÅot/AtsÄkt"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "A_tsvaidzinÄt"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_KÄrtot"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "KÄrtot izvÄ_lÄtos"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "IzÅemt _dublikÄtus"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "IzÅemt _nepieejamos failus"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Jauns"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "PÄ_rdÄvÄt ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "IzÅe_mt"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_ImportÄt ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_EksportÄt ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "Reper_tuÄru pÄrvaldnieks ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Ri_ndas pÄrvaldnieks ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "_PalielinÄt skaļumu"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "_SamazinÄt skaļumu"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Balansieris"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "E_fekti ..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "RÄdÄ«t _izvÄlnes joslu"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "RÄdÄ«t i_nfoapgabalu"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "RÄdÄ«t infoapgabala viz_ualizÄciju"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "RÄdÄ«t _stÄvokļjoslu"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "RÄdÄ«t a_tlikuÅ¡o laiku"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "_VizualizÄcijas ..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Fails"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_AtskaÅoÅ¡ana"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_RepertuÄrs"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Servisi"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "I_zvade"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "S_kats"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "Ie_rindot/IzÅ. no rindas"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "_AtvÄrt saturoÅ¡o mapi"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "_Izgriezt"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_KopÄt"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "I_elÄ«mÄt"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "IezÄ«mÄt _visu"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "PÄ_rdÄvÄt ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>RepertuÄru cilnes</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "VienmÄr rÄdÄ«t cilnes"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "RÄdÄ«t ierakstu skaitu"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "RÄdÄ«t aizvÄrÅ¡anas pogas"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>RepertuÄru kolonnas</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "RÄdÄ«t kolonnu galvenes"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>DažÄdi</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr "KursortaustiÅi meklÄ pa:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "RitinÄt dziesmÄm mainoties"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK saskarne"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "BuferizÄcija ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
@@ -1978,84 +2061,98 @@ msgstr[0] "%d kanÄls"
msgstr[1] "%d kanÄli"
msgstr[2] "%d kanÄlu"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Vieninstances režīms."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "RepertuÄra režīms."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Aptur pÄc paÅ¡reizÄjÄs dziesmas."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "IepriekÅ¡Äjais celiÅÅ¡"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "AtskaÅot"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pauze/AtsÄkt"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Stop"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "NÄkamais celiÅÅ¡"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "Uz priekÅ¡u par 5 sekundÄm"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "Atpakaļ par 5 sekundÄm"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "ApklusinÄt"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "SkaļÄk"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "KlusÄk"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "PÄriet uz failu"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "PÄrslÄgt atskaÅotÄja logu(s)"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "ParÄdÄ«t virsekrÄna displeju"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "PÄrslÄgt atkÄrtoÅ¡anu"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "PÄrslÄgt jaukÅ¡anu"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "PÄrslÄgt atkÄrtoÅ¡anu pÄc paÅ¡reizÄjÄ"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Pacelt atskaÅotÄja logu(s)"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(nekas)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2066,15 +2163,11 @@ msgstr ""
"\n"
"Vai vÄlaties turpinÄt?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Piesaista peles pogas"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "GlobÄlo Ä«sinÄjumtaustiÅu spraudÅa konfigurÄcija"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2082,23 +2175,27 @@ msgstr ""
"Nospiediet taustiÅu kombinÄciju teksta laukÄ.\n"
"Jūs varat piesaistīt arī peles pogas."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "ĪsinÄjumtaustiÅi:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Darbība:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>TaustiÅa piesaiste:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "Pi_evienot"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "GlobÄlie Ä«sinÄjumtaustiÅi"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2125,60 +2222,56 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "GlobÄlie Ä«sinÄjumtaustiÅi"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK izvade"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "Pievienoties visiem pieejamajiem jack portiem"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "AutomÄtiski pieslÄgties izvades portiem"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "Pievienot tikai izvades portus"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "Tika atrasti tikai %d JACK izvades porti, bet vajadzīgi %d."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "Nepievienoties nevienam portam"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "NeizdevÄs pieslÄgties JACK portam %s."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "Savienojuma režīms:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+"JACK atbalsta tikai peldoÅ¡Ä punkta audio. Jums Audacious iestatÄ«jumos "
+"jÄizmaina izvades dziļums uz 'peldoÅ¡Ä punkta'."
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "IeslÄgt atkļūdoÅ¡anas izvadi"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "NeizdevÄs pieslÄgties JACK serverim, vai tas ir palaists?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Balstīts uz xmms-jack, autors Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Audacious ports â Giacomo Lozito"
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK izvade"
+"JACK serverim vajadzÄ«ga diskretizÄcijas frekvence %d Hz, bet Audacious "
+"atskaÅo %d Hz. LÅ«dzu, izmantojiet diskretizÄcijas frekvences pÄrveidotÄja "
+"efektu, lai izlabotu nesakritību."
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s iestatījumi"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA saimnieka iestatījumi"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Moduļu ceļi:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2189,25 +2282,25 @@ msgstr ""
"PÄc jauno ceļu pievienoÅ¡anas nospiediet 'Enter', lai skenÄtu jaunos "
"spraudÅus.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Pieejamie spraudÅi:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "IeslÄgt"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "IeslÄgtie spraudÅi:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Iestatījumi"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2215,47 +2308,15 @@ msgstr ""
"LADSPA saimnieks atskaÅotÄjam Audacious\n"
"Autortiesības 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
-msgid "LADSPA Host"
-msgstr "LADSPA saimnieks"
-
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: neizdevÄs inicializÄt LIRC atbalstu\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: neizdevÄs nolasÄ«t LIRC konf. failu\n"
-"%s: lÅ«dzu, lasiet LIRC dokumentÄcijÄ\n"
-"%s: kÄ izveidot pareizu konf. failu\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: mÄÄ£ina pieslÄgties vÄlreiz...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: nezinÄma komanda \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: atvienots no LIRC\n"
+#: src/ladspa/plugin.h:78
+msgid "LADSPA Host"
+msgstr "LADSPA saimnieks"
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: tiks mÄÄ£inÄts pieslÄgties vÄlreiz katras %d sekundes...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC spraudnis"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2284,73 +2345,81 @@ msgstr ""
"\n"
"Papildu informÄcijai par LIRC skatiet http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Savienojums</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "PieslÄgties vÄlreiz LIRC serverim"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "GaidÄ«t, pirms atkÄrtoti pieslÄgties:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC spraudnis"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki spraudnis"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Dziesmu vÄrdu teksti nav pieejami"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Kļūda"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "NeizdevÄs saÅemt %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Kļūda"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "NeizdevÄs parsÄt %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "MeklÄ dziesmas vÄrdu tekstu ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Trūkst dziesmas metadatu"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "PieslÄdzas lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki spraudnis"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "LyricWiki spraudnis (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U repertuÄri"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Takts ģenerators"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Takts ģenerators: %d sit./min."
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Takts ģenerators: %d sit./min. %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2364,11 +2433,11 @@ msgstr ""
"piem., tact://77, lai atskaÅotu 77 sitienus minÅ«tÄ\n"
"vai tact://60*3/4, lai atskaÅotu 60 s/min 3/4 taktsmÄrÄ"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Takts ģenerators"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "KanÄlu mikseris"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2376,152 +2445,184 @@ msgstr ""
"KanÄlu miksera spraudnis atskaÅotÄjam Audacious\n"
"Autortiesības 2011-2012 John Lindgren un MichaŠLipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>KanÄlu mikseris</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Izvades kanÄli:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "KanÄlu mikseris"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS spraudnis"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "Kļūda pieslÄdzoties MMS serverim"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (moduļu atskaÅotÄjs)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>IzšķirtspÄja</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>KanÄli</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "TuvÄkais (ÄtrÄkais)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "LineÄrs (Ätrs)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Splaina (labs)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "PolifÄzes (labÄkais)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr "<b>Iztveršanas temps</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Līmenis:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "Nogriešana:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Atbalss</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>Basu pastiprinÄjums</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>Ieskaušana</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>PriekÅ¡pastiprinÄjums</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "PÄrdiskretizÄcija"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "TrokÅ¡Åu samazinÄÅ¡ana"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "AtskaÅot Amiga MOD-us"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>AtkÄrtot</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "AtkÄrtojumu skaits:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "Lai atkÄrtotu bezgalÄ«gi, iestaties skaitu uz -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (moduļu atskaÅotÄjs)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Ieskaušana"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "Å ie iestatÄ«jumi stÄsies spÄkÄ, pÄrstartÄjot Audacious."
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 spraudnis"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>PaplaÅ¡inÄti</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Lietot precÄ«zo ilguma aprÄÄ·inÄÅ¡anu (lÄni)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Ieskaušana"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 serveris"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS spraudnis"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "Kļūda parsÄjot pÄrvirzi"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "NezinÄma HTTP kļūda"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "Kļūda parsÄjot URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "PÄrÄk daudz pÄrviržu"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "ApturÄts"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious paÅ¡reiz neatskaÅo."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Darbvirsmas paziÅojumi"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2556,55 +2657,64 @@ msgstr ""
"GNU VispÄrÄjÄs PubliskÄs licences kopijai vajadzÄtu bÅ«t saÅemtai kopÄ ar Å¡o "
"programmu. Ja tÄ nav, skatiet <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "RÄdÄ«t atskaÅoÅ¡anas vadÄ«klas"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "VienmÄr rÄdÄ«t paziÅojumu"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Darbvirsmas paziÅojumi"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "PaziÅojumÄ iekļaut albuma nosaukumu"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "RÄdÄ«t"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pauze"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "NÄkamais"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. noklusÄtÄ ierÄ«ce"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 izvade"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "OSS3 izvade"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "NoklusÄtÄ ierÄ«ce"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Audio ierīce:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Lietot citu ierīci:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "SaglabÄt skaļumu starp sesijÄm."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "IeslÄgt OSS programmatÅ«ras veiktÄs formÄta pÄrveides."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "IeslÄgt izÅÄmuma režīmu, lai novÄrstu virtuÄlo miksÄÅ¡anu."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2618,19 +2728,35 @@ msgstr ""
"Autors vÄlas pateikties cilvÄkiem kanÄlÄ #audacious, Ä«paÅ¡i Tony Vroon un "
"John Lindgren, un, protams, iepriekÅ¡ÄjÄ OSS spraudÅa autoriem."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 izvade"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "RepertuÄru pÄrvaldnieks"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Ieraksti"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_IzÅemt"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "PÄr_dÄvÄt"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS repertuÄri"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2 dekodÄtÄjs"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio izvade"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2664,11 +2790,73 @@ msgstr ""
"Ja tÄ nav, rakstiet uz Free Software Foundation, Inc., 51 Franklin Street,\n"
"Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio izvade"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "QtMultimedia izvade"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"QtMultimedia Audio izvades spraudnis atskaÅotÄjam Audacious\n"
+"Autortiesības 2014 William Pitcock\n"
+"\n"
+"BÄzÄts uz Audacious SDL izvades spraudÅa\n"
+"Autortiesības 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Darbojas ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "MeklÄt"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_AtvÄrt mapi ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_Pievienot mapi ..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "Ž_urnÄla inspektors ..."
-#: src/resample/resample.c:165
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "AtvÄrt failus"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Pievienot failus"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "IepriekÅ¡Äjais"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "AtkÄrtot"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Jaukt"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Qt saskarne"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "DiskretizÄcijas frekvences pÄrveidotÄjs"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2677,99 +2865,107 @@ msgstr ""
"Audacious\n"
"Autortiesības 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "Izlaist/atkÄrtot paraugus"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "LineÄrÄ interpolÄcija"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "ÄtrÄ sinc interpolÄcija"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "VidÄjÄ sinc interpolÄcija"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "LabÄkÄ sinc interpolÄcija"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>PÄrveidoÅ¡ana</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Metode:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Temps:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Tempu kartÄjumi:</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Lietot tempu kartÄjumus"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "DiskretizÄcijas frekvences pÄrveidotÄjs"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "Labi. NosÅ«ta atskaÅojumu lietotÄjam: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "Pieeja liegta"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"Nospiediet uz sekojoÅ¡Äs saites, lai ļautu Audacious nosÅ«tÄ«t jÅ«su "
"atskaÅojumus:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"Paturiet Å¡o logu atvÄrtu un vÄlreiz noklikšķiniet uz 'PÄrbaudÄ«t pieeju'.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2777,32 +2973,36 @@ msgstr ""
"Neuztraucieties. JÅ«su atskaÅojumi ir saglabÄti jÅ«su datorÄ.\n"
"Tie tiks nosūtīti tiklīdz Audacious tiks dota atļauja."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "TÄ«kla problÄma."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "RadÄs problÄma, sazinoties ar Last.fm. LÅ«dzu, vÄlÄk mÄÄ£iniet vÄlreiz."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "PÄrbauda..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "PÄr_baudÄ«t pieeju"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "At_celt pieeju"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr "Jums jÄatļauj Audacious nosÅ«tÄ«t atskaÅojumu uz savu Last.fm kontu.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "AtskaÅojumu nosÅ«tÄ«tÄjs 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2810,7 +3010,7 @@ msgstr ""
"NeizdevÄs palaist atskaÅojumu nosÅ«tÄ«tÄja spraudni.\n"
"IespÄjams, jÅ«su instalÄcijÄ radusies problÄma."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2827,11 +3027,7 @@ msgstr ""
"Paldies John Lindgren par palÄ«dzÄ«bu projekta sÄkumÄ.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "AtskaÅojumu nosÅ«tÄ«tÄjs 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2839,7 +3035,11 @@ msgstr ""
"Audacious paÅ¡laik izmanto Last.fm atskaÅojumu nosÅ«tÄ«tÄja uzlabotu versiju.\n"
"LÅ«dzu, pÄrbaudiet atskaÅojumu nosÅ«tÄ«tÄja spraudÅa iestatÄ«jumus."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL izvade"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2847,88 +3047,59 @@ msgstr ""
"SDL izvades spraudnis atskaÅotÄjam Audacious\n"
"Autortiesības 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL izvade"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "BibliotÄka"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "NezinÄms izpildÄ«tÄjs"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "NezinÄms albums"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" albumÄ %s, izpilda %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d rezultÄtu"
+msgstr[1] "%d rezultÄts"
+msgstr[2] "%d rezultÄti"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d albums"
-msgstr[1] "%d albumi"
-msgstr[2] "%d albumu"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d paslÄpti)"
+msgstr[1] "(%d paslÄpts)"
+msgstr[2] "(%d paslÄpti)"
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d dziesma"
-msgstr[1] ""
-"%s\n"
-" %s, %d dziesmas"
-msgstr[2] ""
-"%s\n"
-" %s, %d dziesmu"
-
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d dziesma ar izpildÄ«tÄju %s"
-msgstr[1] ""
-"%s\n"
-" %d dziesmas ar izpildÄ«tÄju %s"
-msgstr[2] ""
-"%s\n"
-" %d dziesmu ar izpildÄ«tÄju %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d dziesmu"
+msgstr[1] "%d dziesma"
+msgstr[2] "%d dziesmas"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "Å¡ajÄ Å¾anrÄ"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "uz"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "izpilda"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "Iz_veidot repertuÄru"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "Pi_evienot repertuÄru"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "MeklÄt bibliotÄkÄ"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2936,679 +3107,771 @@ msgstr ""
"Lai importÄtu jÅ«su mÅ«zikas bibleotÄku atskaÅotÄjÄ Audacious, izvÄlieties "
"mapi un nospiediet uz ikonas \"atsvaidzinÄt\"."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Lūdzu, uzgaidiet ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "IzvÄlieties mapi"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "SID atskaÅotÄjs"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>Izvade</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "KanÄli:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>EmulÄcija</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "EmulÄt MOS 8580 (noklusÄjums: MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "NeizdarÄ«t automÄtisku Äipa modeļa izvÄli"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "EmulÄt filtru"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Takts frekvence:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "NeizdarÄ«t automÄtisku takts frekvences izvÄli"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>AtskaÅoÅ¡anas laiks</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "IestatÄ«t maksimÄlo atskaÅoÅ¡anas laiku:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Izmantot tikai, kad dziesmas ilgums nav zinÄms"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "IestatÄ«t minimÄlo atskaÅoÅ¡anas laiku:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Apakšmelodijas</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "IeslÄgt apakÅ¡melodijas"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "IgnorÄt apakÅ¡melodijas, kas Ä«sÄkas par:"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Nots</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Klusuma izÅemÅ¡ana"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"Klusuma izÅemÅ¡anas spraudnis atskaÅotÄjam Audacious\n"
+"Autortiesības 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Klusuma izÅemÅ¡ana</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Slieksnis:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "AtvÄrt failus ..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "AtvÄrt URL ..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "MeklÄt bibliotÄkÄ"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "AtskaÅoÅ¡ana"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "RepertuÄrs"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Skatīt"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "Servisi"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "Par ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "iestatījumi ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "Iziet"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "Dziesmas info ..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "AtkÄrtot"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Jaukt"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "NevirzÄ«ties uz priekÅ¡u repertuÄrÄ"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "ApturÄt pÄc paÅ¡reizÄjÄs dziesmas"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "IepriekÅ¡Äjais"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "UzstÄdÄ«t A-B atkÄrtoÅ¡anu"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "NotÄ«rÄ«t A-B atkÄrtoÅ¡anu"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "PÄriet uz dziesmu ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "PÄriet uz laiku ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "AtskaÅot Å¡o repertuÄru"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "AtskaÅot/AtsÄkt"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Jauns repertuÄrs"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "PÄrdÄvÄt repertuÄru ..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "IzÅemt repertuÄru"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "IepriekÅ¡Äjais repertuÄrs"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "NÄkamais repertuÄrs"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "ImportÄt repertuÄru ..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "EksportÄt repertuÄru ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "RepertuÄru pÄrvaldnieks ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "Rindas pÄrvaldnieks ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "AtsvaidzinÄt repertuÄru"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "RÄdÄ«t repertuÄra redaktoru"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "RÄdÄ«t balansieri"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "RÄdÄ«t atlikuÅ¡o laiku"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "VienmÄr virspusÄ"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "Uz visÄm darbvirsmÄm"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "SaritinÄt atskaÅotÄju"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "SaritinÄt repertuÄra redaktoru"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "SaritinÄt balansieri"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "DubultizmÄrs"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "Pievienot URL ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "Pievienot failus ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "PÄc nosaukuma"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "PÄc faila nosaukuma"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "PÄc faila ceļa"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "IzÅemt visus"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Notīrīt ierindošanu"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "IzÅemt nepieejamos failus"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "IzÅemt dublikÄtus"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "IzÅemt neiezÄ«mÄtos"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "IzÅemt iezÄ«mÄtos"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "MeklÄt un iezÄ«mÄt"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Apgriezt iezÄ«mÄto"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "NotÄ«rÄ«t iezÄ«mÄjumu"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "IezÄ«mÄt visus"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "PÄc albuma"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "PÄc celiÅa numura"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "PÄc izpildÄ«tÄja"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "PÄc albuma"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "PÄc albuma izpildÄ«tÄja"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "PÄc izlaiÅ¡anas datuma"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "PÄc celiÅa numura"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "PÄc žanra"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "PÄc ilguma"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "PÄc pielÄgotÄ nosaukuma"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Sajaukt repertuÄru"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Apgriezt repertuÄru"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "KÄrtot iezÄ«mÄtos"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "KÄrtot repertuÄru"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Izgriezt"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "KopÄt"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "IelÄ«mÄt"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "Ierindot/IzÅemt no rindas"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "IelÄdÄt sÄkumuzstÄdÄ«jumu ..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "IelÄdÄt auto-sÄkumuzstÄdÄ«jumu ..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "IelÄdÄt noklusÄto"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "IelÄdÄt sÄkumuzstÄdÄ«jumu no faila ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "IelÄdÄt EQF failu ..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "SaglabÄt sÄkumuzstÄdÄ«jumu ..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "SaglabÄt auto-sÄkumuzstÄdÄ«jumu ..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "SaglabÄt noklusÄto"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "SaglabÄt sÄkumuzstÄdÄ«jumu failÄ ..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "SaglabÄt EQF failu ..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "DzÄst sÄkumuzstÄdÄ«jumu ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "DzÄst auto-sÄkumuzstÄdÄ«jumu ..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "ImportÄt WinAMP sÄkumuzstÄdÄ«jumus ..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "Atstatīt uz nulli"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winamp klasiskÄ saskarne"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "SaglabÄt"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "IelÄdÄt"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "IelÄdÄt sÄkumuzstÄdÄ«jumu no faila"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "IelÄdÄt EQF failu"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "SaglabÄt sÄkumuzstÄdÄ«jumu failÄ"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "SaglabÄt EQF failu"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "ImportÄt WinAMP sÄkumuzstÄdÄ«jumus"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Gatavie regulÄjumi"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "IelÄdÄt sÄkumuzstÄdÄ«jumu"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "IelÄdÄt auto-sÄkumuzstÄdÄ«jumu"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "SaglabÄt sÄkumuzstÄdÄ«jumu"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "SaglabÄt auto-sÄkumuzstÄdÄ«jumu"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "DzÄst sÄkumuzstÄdÄ«jumu"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "DzÄst auto-sÄkumuzstÄdÄ«jumu"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "A_tskaÅotÄjs:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "AtskaÅotÄjs:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "IzvÄlieties galvenÄ atskaÅotÄja loga fontu:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "Re_pertuÄrs:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "RepertuÄrs:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "IzvÄlieties repertuÄra fontu:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>Apdare</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>Fonti</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Lietot bitmap fontus (atbalsta tikai ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "RitinÄt dziesmas nosaukumu"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "RitinÄt dziesmas nosaukumu abos virzienos"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analizators"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Loks"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "Balss vizualizÄÅ¡ana / VU mÄrÄ«tÄjs"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "IzslÄgts"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "NormÄls"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Uguns"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "VertikÄlas lÄ«nijas"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Līnijas"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Joslas"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "LÄnÄkais"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "LÄni"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "VidÄji"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Ätri"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "ÄtrÄkais"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "Punkti"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "Līnijas"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "Aizpildīts"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Ledus"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Gluds"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>Tips</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "VizualizÄcijas tips:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>Analizators</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "RÄdÄ«t virsotnes"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "KrÄsa:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "Stils:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "Krišana:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "VirsotÅu kriÅ¡ana:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "Loka stils:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "Balss vizualizÄcijas krÄsa:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "VU mÄrÄ«tÄja stils:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "VispÄrÄ«gi"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "VizualizÄÅ¡ana"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "PriekÅ¡pastiprinÄjums"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious balansieris"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "PÄriet uz %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Skaļums: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balanss: %d%% pa kreisi"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balanss: centrs"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balanss: %d%% pa labi"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "IestatÄ«jumu izvÄlne"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "IzslÄgt 'VienmÄr virspusÄ'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "IeslÄgt 'VienmÄr virspusÄ'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Faila info lodziÅÅ¡"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "VizualizÄcijas"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "AtkÄrtoÅ¡anas punkts A iestatÄ«ts."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "AtkÄrtoÅ¡anas punkts B iestatÄ«ts."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "AtkÄrtoÅ¡anas punkti notÄ«rÄ«ti."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Vieninstances režīms."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "RepertuÄra režīms."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Aptur pÄc paÅ¡reizÄjÄs dziesmas."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "MeklÄt ierakstus aktÄ«vajÄ repertuÄrÄ"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "MeklÄt"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3619,57 +3882,61 @@ msgstr ""
"jÄizmanto regulÄro izteiksmju sintakse, reÄ£istrnejutÄ«ga. Ja neziniet, kÄ "
"regulÄrÄs izteiksmes darbojas, vienkÄrÅ¡i nosaukuma daļu tam, ko meklÄjat."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Nosaukums: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr "Nosaukums:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr "Albums: "
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr "IzpildÄ«tÄjs: "
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Faila nosaukums: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Faila nosaukums:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "NotÄ«rÄ«t iepriekÅ¡Äjo iezÄ«mÄjumu pirms meklÄÅ¡anas"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "AutomÄtiski pÄrslÄgt ierindoÅ¡anu atbilstoÅ¡ajiem ierakstiem"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Izveidot jaunu repertuÄru no atbilstoÅ¡ajiem ierakstiem"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audacious repertuÄra redaktors"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d of %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "ArhivÄta Winamp 2.x apdare"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "AtarhivÄta Winamp 2.x apdare"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "NeizdevÄs izveidot mapi (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile spraudnis"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3708,82 +3975,71 @@ msgstr ""
"Ja tÄ nav, rakstiet uz Free Software Foundation, Inc., 51 Franklin Street,\n"
"Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile spraudnis"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Par Sndio izvades spraudni"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Sndio izvade"
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Sndio izvades spraudnis\n"
-"\n"
-"Autors Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "IerÄ«ce (noklusÄtajai atstÄt tukÅ¡u):"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "NeatbalstÄ«ts formÄts"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "SaglabÄt un atjaunot skaļumu:"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"Tika pieprasÄ«ts formÄts, ko neatbalsta audio ierÄ«ce.\n"
-"\n"
-"LÅ«dzu, mÄÄ£iniet vÄlreiz ar palaistu sndiod(1) serveri."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Sndio kļūda: neatbalstÄ«ts audio formÄts (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio ierīce"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Sndio kļūda: sio_open() neizdevÄs"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(tukÅ¡s nozÄ«mÄ noklusÄtais)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Sndio kļūda: sio_setpar() neizdevÄs"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "Labi"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Sndio kļūda: sio_start() neizdevÄs"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Dziesmas maiÅa"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Komanda, ko palaist, kad Audacious sÄk atskaÅot jaunu dziesmu."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Parametrus, kuri tiek padoti Äaulai, vajadzÄtu ietvert "
+"pÄdiÅÄs. PretÄjÄ gadÄ«jumÄ rodas risks drošībai.</span>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Komanda:"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Komandas</b>"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Komanda, ko palaist dziesmas beigÄs."
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Komanda, ko palaist, sÄkot atskaÅot jaunu dziesmu:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "Komanda, ko palaist, kad Audacious sasniedz repertuÄra beigas."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Komanda, ko palaist dziesmas beigÄs:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
-msgstr ""
-"Komanda, ko palaist, kad nomainÄs dziesmas nosaukums (piem., tÄ«kla plÅ«smas)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Komanda, ko palaist repertuÄra beigÄs:"
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr "Komanda, ko palaist, kad nomainÄs dziesmas nosaukums (tÄ«kla plÅ«smÄm):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3797,9 +4053,8 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Varat izmantot sekojoÅ¡a formÄta virknes, kuras\n"
-"pirms komandas izsaukšanas tiks aizvietotas\n"
-"(ne visas ir derÄ«gas repertuÄra-beigas komandai)\n"
+"Varat izmantot sekojoÅ¡a formÄta virknes, kuras pirms komandas izsaukÅ¡anas "
+"tiks aizvietotas (ne visas ir derÄ«gas repertuÄra-beigas komandai):\n"
"\n"
"%F: Frekvence (hercos)\n"
"%c: KanÄlu skaits\n"
@@ -3813,19 +4068,15 @@ msgstr ""
"%b: Albums\n"
"%T: CeliÅa nosaukums"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>Parametrus, kuri tiek padoti Äaulai, vajadzÄtu ietvert "
-"pÄdiÅÄs. PretÄjÄ gadÄ«jumÄ rodas risks drošībai.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Dziesmas info (Qt)"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Komandas"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX diskretizÄcijas frekvences pÄrveidotÄjs"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3839,51 +4090,51 @@ msgstr ""
"BalstÄ«ts uz diskretizÄcijas frekvences pÄrveidoÅ¡anas spraudni:\n"
"autortiesības 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Ätri"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Zema"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Augsta"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Ļoti augsta"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "KvalitÄte:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX diskretizÄcijas frekvences pÄrveidotÄjs"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Ätrums un augstums"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Ätrums un augstums</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Ätrums:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Augstums:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Ätrums un augstums"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Statusa ikona"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "Ies_tatījumi ..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3901,39 +4152,39 @@ msgstr ""
"Šis spraudnis nodrošina ar statusa ikonu, kas novietota\n"
"sistÄmas ikonu joslas apgabalÄ."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Peles rullīša darbība</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Mainīt skaļumu"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "MainÄ«t atskaÅojamo dziesmu"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Citi iestatījumi</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "AtslÄgt izlecoÅ¡o logu"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "AizvÄrt sistÄmas ikonu joslu"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Tinot uz augÅ¡u, pÄriet uz priekÅ¡u repertuÄrÄ"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Statusa ikona"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Papildu stereo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3943,24 +4194,24 @@ msgstr ""
"\n"
"Autors Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Papildu stereo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Papildu stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "ToÅa Ä£enerators"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "ToÅa Ä£enerators: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3975,15 +4226,11 @@ msgstr ""
"frekvence3;...\n"
"piem., tone://2000;2005, lai atskaÅotu 2000 Hz tonu un 2005 Hz toni"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "ToÅa Ä£enerators"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Balss izÅemÅ¡ana"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4020,11 +4267,46 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis dekodÄtÄjs"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Detaļas par %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"Nosaukums: %t\n"
+"Autors: %a\n"
+"No: %f\n"
+"Trakeris: %T\n"
+"KomentÄrs: %C\n"
+"Äipa tips: %c\n"
+"Stereo: %s\n"
+"Cikls: %l\n"
+"Äips frekvence: %F\n"
+"AtskaÅotÄja frekvence: %P\n"
+"Gads: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX dekodÄtÄjs"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4034,19 +4316,19 @@ msgstr ""
"Balstīts uz in_vtx.dll, autors Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious spraudÅa autors Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX dekodÄtÄjs"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack dekodÄtÄjs"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "zudumradošs (hibrīdais)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "zudumradošs"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4056,23 +4338,18 @@ msgstr ""
"\n"
"Daļai koda autors ir Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack dekodÄtÄjs"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF dekodÄtÄjs"
-#: src/xspf/xspf.c:438
-msgid "XML Shareable Playlists (XSPF)"
-msgstr "XML kopÄ«gojamie repertuÄri (XSPF)"
-
-#~ msgid "32.0 kHz:"
-#~ msgstr "32.0 kHz:"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>XSF konfigurÄcija</b>"
-#~ msgid "88.2 kHz:"
-#~ msgstr "88.2 kHz:"
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "IgnorÄt ilgumu no faila"
-#~ msgid "176.4 kHz:"
-#~ msgstr "176.4 kHz:"
+#: src/xspf/xspf.cc:89
+msgid "XML Shareable Playlists (XSPF)"
+msgstr "XML kopÄ«gojamie repertuÄri (XSPF)"
diff --git a/po/ml_IN.po b/po/ml_IN.po
index dcf4940d4566..747b462f566c 100644
--- a/po/ml_IN.po
+++ b/po/ml_IN.po
@@ -3,17 +3,17 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# nandakumar <nandakumar96 at gmail.com>, 2013
-# navaneeths52 <navaneeths52 at gmail.com>, 2013-2014
-# navaneeths52 <navaneeths52 at gmail.com>, 2013
-# STyM Alfaz, 2014
+# Nandakumar <nandakumar96 at gmail.com>, 2013
+# Navaneeth <inactive+navaneeths52 at transifex.com>, 2013-2014
+# Navaneeth <inactive+navaneeths52 at transifex.com>, 2013
+# ST Alfas, 2014
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Malayalam (India) (http://www.transifex.com/projects/p/"
"audacious/language/ml_IN/)\n"
"Language: ml_IN\n"
@@ -22,51 +22,35 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "à´®àµà´£àµ"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "à´¸àµà´±àµà´±àµà´°à´¿à´¯àµ"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "സറàµà´£àµà´àµ"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib à´ªàµà´²àµà´¯à´°àµâ)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "à´¸àµà´àµà´µà´¨àµâà´¸àµà´¡àµ"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib à´ªàµà´²àµà´¯à´°àµâ)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "à´
ലാà´"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "à´
ലാà´"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -89,7 +73,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -111,7 +95,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -125,360 +109,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "à´à´¤àµ നിà´àµà´à´³àµà´àµ à´à´£à´°àµâà´¤àµà´¤àµà´ªà´¾à´àµà´à´¾à´£àµ."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "à´à´¨àµà´¨àµà´¯àµà´àµà´àµà´³àµà´³ നിà´àµà´à´³àµà´àµ à´¸àµà´®à´¾à´°à´à´: "
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "à´¸àµà´®à´¾à´°à´à´"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "തിà´àµà´à´³à´¾à´´àµà´"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "à´àµà´µàµà´µà´¾à´´àµà´"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "à´¬àµà´§à´¨à´¾à´´àµà´"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "à´µàµà´¯à´¾à´´à´¾à´´àµà´"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "à´µàµà´³àµà´³à´¿à´¯à´¾à´´àµà´"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "ശനിയാഴàµà´"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "à´à´¾à´¯à´±à´¾à´´àµà´"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "à´
ലാഠà´àµà´°à´®àµà´à´°à´£à´àµà´à´³àµâ"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "സമയà´"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "à´
ലാഠമàµà´´à´àµà´àµà´£àµà´ സമയഠ(à´¸àµà´µà´¤à´µàµà´¯àµà´³àµà´³à´¤àµ):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "à´¶àµà´·à´ ശാനàµà´¤à´®à´¾à´àµ :"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "മണിà´àµà´àµà´±àµà´à´³àµâ"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "മിനിറàµà´±àµà´à´³àµâ"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "à´
ലാഠമàµà´´à´àµà´àµà´£àµà´ ദിനà´àµà´à´³àµâ à´¤àµà´°àµà´àµà´àµà´àµà´àµà´àµà´"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "ദിവസà´"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "à´¸àµà´µà´¤à´¸àµà´¸à´¿à´¦àµà´§à´"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "ദിവസà´àµà´à´³àµâ"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "മായàµà´¨àµà´¨àµ"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "à´¸àµà´àµà´à´¨àµâà´¡àµà´à´³àµâ"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "à´à´àµà´à´¤"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "à´à´µà´¿à´àµ à´¤àµà´à´àµà´àµà´"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "à´
വസാനതàµà´¤àµà´¤àµ"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "നിലവിലàµà´³àµà´³à´¤àµ"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "à´
à´§à´¿à´à´à´²àµâà´ªàµà´ªà´¨"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "സാദàµà´§àµà´¯à´®à´¾à´àµà´àµà´"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ (നിരàµâബനàµà´§à´®à´¿à´²àµà´²)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "à´à´°àµ à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ തിരà´àµà´àµà´àµà´àµà´àµà´"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "à´à´ªàµà´·à´¨àµà´à´³àµâ"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "à´ à´à´ªàµà´·à´¨àµà´à´³àµâ à´à´¨àµà´¤à´¾à´£àµ à´
à´°àµâà´¤àµà´¥à´®à´¾à´àµà´àµà´¨àµà´¨à´¤àµ?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "സഹായà´"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "à´à´²àµâബഠà´à´°àµâà´àµà´àµ"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "à´
à´²àµâà´¸ à´à´àµà´ªàµà´àµà´àµ"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "à´¸àµà´µà´¤à´µàµà´¯àµà´³àµà´³ PCM à´à´ªà´à´°à´£à´"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "à´¸àµà´µà´¤à´µàµà´¯àµà´³àµà´³ മിà´àµà´¸à´°àµâ à´à´ªà´à´°à´£à´"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM à´à´ªà´à´°à´£à´:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "മിà´àµà´¸à´°àµâ à´à´ªà´à´°à´£à´:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "മിà´àµà´¸à´°àµâ à´à´²à´®àµà´¨àµà´±àµ:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "ââà´¡àµà´°àµà´¨àµâ ഹാà´àµà´à´ªàµà´ªà´¿à´¨àµ à´àµà´±àµà´±àµà´ à´ªàµà´°à´µà´°àµâà´¤àµà´¤à´¿à´àµà´àµà´"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-à´ªàµà´²à´àµà´àµ (MIDI à´ªàµà´²àµà´¯à´°àµâ)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "à´
à´²àµâà´¸ à´à´àµà´ªàµà´àµà´àµ"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-à´ªàµà´²à´àµà´àµ (MIDI à´ªàµà´²àµà´¯à´°àµâ)"
-
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-à´ªàµà´²à´àµà´àµ - à´¸àµà´£àµà´àµ à´«àµà´£àµà´àµ à´¤àµà´°àµà´àµà´àµà´àµà´àµà´àµà´"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "ഫയലàµâà´¨àµà´¯à´¿à´"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "ഫയലàµâ à´¨àµà´¯à´¿à´"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "വലിപàµà´ªà´ (à´¬àµà´±àµà´±àµà´à´³àµâ)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "à´ªàµà´°àµ:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI വിവരà´àµà´à´³àµâ </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "à´«àµà´°àµâമാറàµà´±àµ:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "à´¨àµà´³à´ (മിലàµà´²à´¿ à´¸àµà´àµà´à´¨àµâà´¡à´¿à´²àµâ):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "à´àµà´°à´¾à´àµà´àµà´à´³àµà´àµ à´à´£àµà´£à´:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "à´à´°à´"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI വിവരണà´àµà´à´³àµà´ വരിà´à´³àµà´ </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* à´ MIDI ഫയലിലàµâ നിലവിലàµà´³àµà´³ വിവരണà´àµà´à´³àµâ à´à´¨àµà´¨àµà´®à´¿à´²àµà´² *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* à´ MIDI ഫയലിലàµâ നിലവിലàµà´³àµà´³ വരിà´à´³àµâ à´à´¨àµà´¨àµà´®à´¿à´²àµà´² *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_à´
à´à´¯àµà´àµà´àµà´"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr "(à´ªàµà´°à´¾à´¬à´²àµà´¯à´®à´¿à´²àµà´²à´¾à´¤àµà´¤ UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "AMIDI à´ªàµà´²à´àµà´à´¿à´¨àµà´ªàµà´ªà´±àµà´±à´¿"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI à´ªàµà´²à´àµà´àµ"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -489,149 +479,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr ""
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "à´à´¤àµà´°à´"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "à´µà´àµà´àµà´µà´³à´àµà´ à´à´¤àµà´"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "à´
വതലà´à´¤àµà´°à´"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "à´¶àµà´¨àµà´¯à´"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "à´ªàµà´²àµà´¬à´¾à´àµà´àµ à´¤àµà´à´àµà´àµà´"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr ""
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "തലà´àµà´àµà´àµà´à´¿à´²àµ മാറàµà´±à´"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "à´ªàµà´¸àµ à´à´£àµâ"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr ""
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "à´ªàµà´¸àµ à´à´«àµ"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr ""
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "à´
വസàµà´¥"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "താരതമàµà´¯àµà´¨à´¯àµà´³àµà´³ X à´à´«àµâà´¸àµà´±àµà´±àµ"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "താരതമàµà´¯àµà´¨à´¯àµà´³àµà´³ Y à´à´«àµâà´¸àµà´±àµà´±àµ"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "പരമാവധി OSD à´¨àµà´³à´"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "മളàµâà´àµà´à´¿ à´®àµà´£à´¿à´±àµà´±à´°àµâ à´àµà´°à´®àµà´à´°à´£à´àµà´à´³àµâ"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr ""
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "à´à´²àµà´²à´¾ à´®àµà´£à´¿à´±àµà´±à´±àµà´à´³àµà´"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "à´®àµà´£à´¿à´±àµà´±à´°àµâ %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr ""
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "à´¡à´¿à´¸àµà´ªàµà´²àµ:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "à´«àµà´¯àµà´¡àµ à´à´¨àµâ:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "à´«àµà´¯àµà´¡àµ à´à´àµà´àµ"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "à´«àµà´£àµà´àµà´à´³àµâ"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "à´«àµà´£àµà´àµ %i"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "നിഴലàµâ"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "à´±àµà´¨àµâà´¡à´°àµâ à´¸àµà´±àµà´±àµà´²àµâ"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "നിറà´àµà´à´³àµâ"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "നിറഠ%i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "à´à´¾à´àµà´à´¿ സാദàµà´§àµà´¯à´®à´¾à´àµà´àµà´"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "à´¸à´à´à´µà´"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "à´à´®àµà´ªàµà´¸à´¿à´±àµà´±àµ മാനàµà´à´°àµâ à´¶àµà´°à´¦àµà´§à´¯à´¿à´²àµâ à´ªàµà´àµà´àµ"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -641,112 +628,112 @@ msgstr ""
"മറàµà´±àµà´¨àµà´¨àµ à´ªàµà´°à´µà´°àµâà´¤àµà´¤à´¿à´àµà´àµà´¨àµà´¨à´¤àµ നിà´àµà´à´³àµâà´àµà´à´±à´¿à´¯à´¾à´®àµà´àµà´à´¿à´²àµâ, ദയവൠà´àµà´¯àµà´¤àµ à´à´°àµ à´à´®àµà´ªàµà´¸à´¿à´±àµà´±àµ മാനàµà´à´°àµâ "
"à´ªàµà´°à´¾à´µà´°àµâà´¤àµà´¤à´¿à´à´®à´¾à´àµà´àµà´ à´
à´²àµà´²àµà´àµà´à´¿à´²àµâ OSD à´ªàµà´°à´µà´°àµâà´¤àµà´¤à´¿à´àµà´à´¿à´²àµà´²àµà´¨àµà´¨àµ വരാà´"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "à´µàµà´¯à´¾à´à´®à´¾à´¯ à´¸àµà´¤à´¾à´°àµà´¯à´¤à´¯àµà´àµà´àµ à´à´®àµà´ªàµà´¸à´¿à´±àµà´±àµ മാനàµà´à´°àµâ à´à´µà´¶àµà´¯à´®à´¿à´²àµà´²"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "à´¸àµà´¤à´¾à´°àµà´¯à´¤"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "à´à´ªà´à´¸àµà´¤à´¾à´°àµà´¯à´¤"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "യഥാരàµâà´¤àµà´¥ à´¸àµà´¤à´¾à´°àµà´¯à´¤ (X composite Ext. à´à´µà´¶àµà´¯à´®àµà´£àµà´àµ)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "à´àµà´®àµà´ªàµà´¸à´¿à´±àµà´±àµ à´à´àµà´¸àµà´±àµà´±à´¨àµâà´·à´¨àµâ നിലവിലàµâ വനàµà´¨à´¿à´àµà´à´¿à´²àµà´²"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "à´àµà´®àµà´ªàµà´¸à´¿à´±àµà´±àµ à´à´àµà´¸àµà´±àµà´±à´¨àµâà´·à´¨àµâ നിലവിലിലàµà´²"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>à´à´¡à´¾à´·àµà´¯à´¸àµ OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "à´à´¡à´¾à´·àµà´¯à´¸àµ OSD à´àµà´°à´®àµà´à´°à´£à´"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "à´¸àµà´¥à´¾à´¨à´"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "à´
നിമàµà´·à´¨àµâ"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "à´à´´àµà´¤àµà´¤àµ"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "à´
à´²à´àµà´à´¾à´°à´"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "à´à´¾à´àµà´à´¿"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "പലവà´"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr ""
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr ""
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>നിറà´</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "à´¬àµà´²à´°àµâ à´¸àµà´àµà´ªàµà´ªàµ"
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
-msgstr "à´«àµà´¡àµ à´²àµà´µà´²àµâ:"
-
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
-msgstr "à´à´µàµà´¤àµà´¤à´¿ à´®àµà´±à´¿à´¯àµà´àµà´àµà´:"
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr ""
-#: src/bs2b/plugin.c:166
+#: src/bs2b/plugin.cc:129
msgid "Presets:"
msgstr "à´ªàµà´°àµà´¸àµà´±àµà´±àµà´à´³àµâ:"
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
+msgstr "à´«àµà´¡àµ à´²àµà´µà´²àµâ:"
+
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
msgstr ""
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr "à´à´µàµà´¤àµà´¤à´¿ à´®àµà´±à´¿à´¯àµà´àµà´àµà´:"
+
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "à´¸àµà´ªàµà´àµà´àµà´°à´ à´
നലàµà´¸à´°àµâ"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "à´à´¡à´¿à´¯àµ സി.à´¡à´¿. à´ªàµà´²à´àµà´à´¿à´¨àµâ"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -758,169 +745,156 @@ msgid ""
"This was a Google Summer of Code 2007 project."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>à´à´ªà´à´°à´£à´</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "വായനയàµà´àµ à´µàµà´à´:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>à´®àµà´±àµà´±à´¾à´¡àµà´±àµà´±</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "സി.à´¡à´¿.-à´àµà´àµà´¸àµà´±àµà´±àµ à´à´ªà´¯àµà´à´¿à´¯àµà´àµà´àµà´"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "CDDB à´à´ªà´¯àµà´à´¿à´¯àµà´àµà´àµà´"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "CDDBP à´¯àµà´àµà´àµ à´ªà´à´°à´ HTTP à´à´ªà´¯àµà´à´¿à´àµà´à´¾à´"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "à´¸àµà´°àµâവരàµâ:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "പാതàµà´¤àµ:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "à´ªàµà´°àµâà´àµà´àµ:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "à´à´¡à´¿à´¯àµ സി.à´¡à´¿. à´ªàµà´²à´àµà´à´¿à´¨àµâ"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "à´
സാധàµà´µà´¾à´¯ URI %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "à´àµà´°à´¾à´àµà´àµ %d à´à´£àµà´àµà´à´¿à´àµà´à´¿à´¯à´¿à´²àµà´²."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "à´àµà´°à´¾à´àµà´àµ %d à´à´°àµ à´¡àµà´±àµà´±à´¾ à´àµà´°à´¾à´àµà´àµ à´à´£àµ."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "à´à´¡à´¿à´¯àµ à´à´àµà´ªàµà´àµà´àµ à´¤àµà´±à´àµà´àµà´¨àµà´¨à´¤à´¿à´²àµâ പരാà´à´¯à´ªàµà´ªàµà´àµà´àµ."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "à´à´¡à´¿à´¯àµ സി.à´¡à´¿. വായിയàµà´àµà´àµà´¨àµà´¨à´¤à´¿à´²àµâ പിശà´àµ."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "à´à´¡à´¿à´¯àµ സി.à´¡à´¿."
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "സി.à´¡à´¿. à´à´ªà´à´°à´£à´ %s à´¤àµà´±à´àµà´àµà´¨àµà´¨à´¤à´¿à´²àµâ പരാà´à´¯à´ªàµà´ªàµà´àµà´àµ."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "à´à´¡à´¿à´¯àµ à´¶àµà´·à´¿à´¯àµà´³àµà´³ സി.à´¡à´¿. à´¡àµà´°àµà´µàµ à´à´£àµà´àµà´à´¿à´àµà´à´¿à´¯à´¿à´²àµà´²."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "cddb ബനàµà´§à´ സാദàµà´§àµà´¯à´®à´¾à´àµà´àµà´¨àµà´¨à´¤à´¿à´²àµâ പരാà´à´¯à´ªàµà´ªàµà´àµà´àµ."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "cddb à´à´¨àµâഫൠവായിയàµà´àµà´àµà´¨àµà´¨à´¤à´¿à´²àµâ പരാà´à´¯à´: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "à´¡àµà´°àµà´µàµ à´¶àµà´¨àµà´¯à´®à´¾à´£àµ."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "പിനàµà´¤àµà´£à´¯à´¿à´²àµà´²à´¾à´¤àµà´¤ തരഠഡിസàµà´àµ."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "à´à´¡à´¿à´¯àµ സി.à´¡à´¿. à´®àµà´¨àµ à´
à´à´à´àµà´à´³àµâ"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "സി.à´¡à´¿. പാà´àµà´"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "സി.à´¡à´¿. à´àµà´°àµâà´àµà´àµà´"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "à´à´¡à´¿à´¯àµ സി.à´¡à´¿. à´®àµà´¨àµ à´
à´à´à´àµà´à´³àµâ"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>à´à´à´ªàµà´°à´·à´¨àµâ</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "à´à´±à´µà´¿à´à´¤àµà´¤à´¿à´²àµ à´à´àµà´à´¤:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "à´¡àµà´¨à´¾à´®à´¿à´àµ à´±àµà´¯àµà´àµà´àµ:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr ""
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -930,195 +904,220 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "à´¬àµà´¸àµ:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "à´àµà´°àµà´¬àµà´³àµâ:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "പാà´àµà´à´¿à´¨àµà´±àµ à´¸àµà´µà´¤à´¸àµà´¸à´¿à´¦àµà´§à´®à´¾à´¯ à´¨àµà´³à´"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>à´±àµà´¸à´¾à´à´ªàµà´²à´¿à´àµ</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "à´à´¡à´¿à´¯àµ à´±àµà´¸à´¾à´à´ªàµà´²à´¿à´àµ സാദàµà´§àµà´¯à´®à´¾à´àµà´àµà´"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "à´±àµà´¸à´¾à´à´ªàµà´²à´¿à´àµ നിരà´àµà´àµ:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "SPC à´à´ªà´¨à´¾à´®à´àµà´à´³à´¿à´²àµâ നിനàµà´¨àµà´ à´¨àµà´³à´ à´
à´µà´à´£à´¿à´àµà´àµà´"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "à´ªàµà´°à´¤à´¿à´¦àµà´§àµà´µà´¨à´¿ à´àµà´àµà´àµà´"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "à´àµà´¯à´¿à´ à´à´£àµâà´¸àµà´³àµâ à´®àµà´¯àµà´¸à´¿à´àµ à´¡àµà´àµà´¡à´°àµâ"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>à´àµà´°àµà´¸àµâà´«àµà´¯àµà´¡àµ</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "à´à´µà´°àµâലാപàµà´ªàµ:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "à´àµà´°àµà´¸àµâà´«àµà´¯àµà´¡àµ"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>à´àµà´°à´¿à´¸àµà´±àµà´±à´²àµà´¸à´°àµâ</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "à´¤àµà´µàµà´°à´¤:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "à´àµà´°à´¿à´¸àµà´±àµà´±à´²àµà´¸à´°àµâ"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "à´¨àµà´àµà´à´ à´àµà´¯àµà´¯àµà´"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "റദàµà´¦à´¾à´àµà´àµà´"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>à´ªàµà´°à´¤à´¿à´§àµà´µà´¨à´¿</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "താമസà´:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr ""
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "à´
à´à´¿à´ªàµà´°à´¾à´¯à´:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "à´¶à´¬àµà´¦àµà´àµà´à´¤:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "à´ªàµà´°à´¤à´¿à´§àµà´µà´¨à´¿"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg à´ªàµà´²à´àµà´à´¿à´¨àµâ"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1128,55 +1127,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg à´ªàµà´²à´àµà´à´¿à´¨àµâ"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "FileWriter à´ªàµà´²à´àµà´à´¿à´¨àµâ"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "à´à´àµà´ªàµà´àµà´àµ ഫയലàµâ à´«àµà´°àµâമാറàµà´±àµ:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "à´àµà´°à´®àµà´à´°à´¿à´¯àµà´àµà´àµà´"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "യഥാരàµâà´¤àµà´¥à´¡à´¯à´±à´àµà´±àµà´±à´±à´¿à´¯à´¿à´²àµà´¯àµà´àµà´ à´¸àµà´µàµ à´àµà´¯àµà´¯àµà´"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "à´¸àµà´µàµà´àµà´à´¯à´¾à´²àµà´³àµà´³ ഡയറà´àµà´±àµà´±à´±à´¿à´¯à´¿à´²àµà´¯àµà´àµà´àµ à´¸àµà´µàµ à´àµà´¯àµà´¯àµà´"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "à´à´àµà´ªàµà´àµà´àµ ഫയലàµâ à´«àµà´³àµâà´¡à´°àµâ:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "à´à´°àµ à´«àµà´³àµâà´¡à´°àµâ തിരà´àµà´àµà´àµà´àµà´àµà´"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "ഫയലàµâനാമഠലà´à´¿à´àµà´àµà´¨àµà´¨à´¤àµ:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "യഥാരàµâà´¤àµà´¥ ഫയലàµâ à´à´¾à´àµà´à´³àµâ"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "യഥാരàµâà´¤àµà´¥ ഫയലàµâà´¨àµà´¯à´¿à´"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "ഫയലàµâനാമതàµà´¤à´¿à´¨àµà´±àµ വിപàµà´²àµà´à´°à´£à´ à´à´¾à´à´¿à´àµà´à´°àµà´¤àµ"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "à´àµà´°à´¾à´àµà´àµ à´¸à´à´àµà´¯ ഫയലàµâനാമതàµà´¤à´¿à´¨àµ à´®àµà´¨àµà´¨à´¿à´²à´¾à´¯à´¿ à´àµàµ¼à´àµà´àµà´"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1194,165 +1193,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "FileWriter à´ªàµà´²à´àµà´à´¿à´¨àµâ"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "à´¸àµà´µà´¯à´"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "à´àµà´àµà´à´¿à´àµà´àµà´°àµâà´¤àµà´¤ à´¸àµà´±àµà´±àµà´°à´¿à´¯àµ"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "à´¸àµà´±àµà´±àµà´°à´¿à´¯àµ"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "à´®àµà´£àµ"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 à´àµà´°à´®àµà´à´°à´£à´"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "à´à´²àµâà´àµà´°à´¿à´¤à´ à´àµà´£à´®àµà´¨àµà´®:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "à´à´àµà´ªàµà´àµà´àµ സാà´à´ªà´¿à´³àµâനിരà´àµà´àµ:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "à´¬àµà´àµà´°àµà´±àµà´±àµ / à´à´à´ªàµà´°à´·à´¨àµâ à´
à´¨àµà´ªà´¾à´¤à´"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ബിറàµà´±àµâà´±àµà´±àµà´±àµ (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "à´à´à´ªàµà´°à´·à´¨àµâ നിരà´àµà´àµ:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "à´à´¡à´¿à´¯àµ à´®àµà´¡àµ:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "പലവà´:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "ISO à´à´¤àµà´àµà´à´ à´à´°àµâശനമായി നിരàµâബനàµà´§à´¿à´àµà´àµà´"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "à´¸à´à´°à´àµà´·à´£ പിശà´àµ"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "à´àµà´£à´®àµà´¨àµà´®"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "VBR/ABR സാദàµà´§àµà´¯à´®à´¾à´àµà´àµà´"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "തരà´:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR à´à´ªàµà´·à´¨àµà´à´³àµâ"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "à´àµà´±à´àµà´ ബിറàµà´±àµâà´±àµà´±àµà´±àµ (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "പരമാവധി ബിറàµà´±àµâà´±àµà´±àµà´±àµ (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "à´àµà´°àµà´àµà´à´¿à´¯ à´¬àµà´àµà´°àµà´±àµà´±àµ à´à´°àµâശനമായി നിരàµâബനàµà´§à´¿à´àµà´àµà´"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR à´àµà´°à´®àµà´à´°à´£à´àµà´à´³àµâ:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "ശരാശരി ബിറàµà´±àµà´±àµà´±àµà´±àµ (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR à´àµà´£à´¨à´¿à´²à´µà´¾à´°à´:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Xing VBR തലà´àµà´àµà´àµà´àµ à´à´´àµà´¤àµà´¨àµà´¨à´¤àµ à´à´´à´¿à´µà´¾à´àµà´à´¾à´"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "à´«àµà´°àµà´ പരാമàµà´±àµà´±à´±àµà´à´³àµâ:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "à´àµà´ªàµà´ªà´¿à´±àµà´±àµà´±à´à´¾à´¯à´¿ à´
à´à´¯à´¾à´³à´ªàµà´ªàµà´àµà´¤àµà´¤àµà´"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "à´ªàµà´°à´¥à´®à´®à´¾à´¯à´¿ à´
à´à´¯à´¾à´³à´ªàµà´ªàµà´àµà´¤àµà´¤àµà´"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ID3 പാരà´à´¸àµ"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "à´µàµà´°àµâà´·à´¨àµâ 2 à´à´¾à´à´¿à´¨àµà´±àµ à´¸à´à´¯àµà´à´ നിരàµâബനàµà´§à´¿à´àµà´àµà´"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "v1 à´à´¾à´àµ മാതàµà´°à´ à´¸à´à´¯àµà´à´¿à´àµà´àµà´"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "v2 à´à´¾à´àµ മാതàµà´°à´ à´¸à´à´¯àµà´à´¿à´àµà´àµà´"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "à´à´¾à´àµà´à´³àµâ"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "à´µàµà´°àµâബിസൠà´à´¨àµâà´àµà´¡à´°àµâ à´àµà´°à´®àµà´à´°à´£à´"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "à´àµà´£à´¨à´¿à´²à´µà´¾à´°à´ ( 0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC à´¡àµà´àµà´¡à´°àµâ"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "à´²àµà´¸àµâà´²àµà´¸àµà´¸àµ"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1360,21 +1363,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC à´¡àµà´àµà´¡à´°àµâ"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO à´ªàµà´²à´àµà´à´¿à´¨àµâ"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1386,530 +1393,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL à´¸àµà´ªàµà´àµà´àµà´°à´ à´
നലàµà´¸à´°àµâ"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "à´àµà´¨àµà´ à´à´³àµà´ªàµà´ªà´µà´´à´¿à´à´³àµâ"
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "à´à´¨àµâà´àµà´°à´¿ നമàµà´ªà´°àµâ"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "à´àµà´±àµà´±à´¿à´²àµâ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "à´à´°àµâà´àµà´à´¿à´¸àµà´±àµà´±àµ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "വരàµâà´·à´"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "à´à´²àµâà´¬à´"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "à´àµà´°à´¾à´àµà´àµ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "തരà´"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "വരിയിലàµà´³àµà´³ à´¸àµà´¥à´¾à´¨à´"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "à´¨àµà´³à´"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "ഫയലàµâ പാതàµà´¤àµ"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "ഫയലàµâ à´¨àµà´¯à´¿à´"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "à´¸àµà´µàµà´àµà´à´¯à´¾à´²àµà´³àµà´³ തലà´àµà´àµà´àµà´àµ"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ബിറàµà´±àµâà´±àµà´±àµà´±àµ"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "തിരà´àµà´à´¿à´²àµâ à´àµà´³àµâ"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "à´à´à´¤àµà´µà´¶à´¤àµà´¤àµ à´¡àµà´àµà´àµ à´àµà´¯àµà´¯àµà´"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "വലതàµà´µà´¶à´¤àµà´¤àµ à´¡àµà´àµà´àµ à´àµà´¯àµà´¯àµà´"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "à´®àµà´à´³à´¿à´²àµâ à´¡àµà´àµà´àµ à´àµà´¯àµà´¯àµà´"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "താഴൠഡàµà´àµà´àµ à´àµà´¯àµà´¯àµà´"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "à´¡àµà´àµà´à´¿à´àµ à´à´´à´¿à´µà´¾à´àµà´àµà´"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "à´
സാദàµà´§àµà´¯à´®à´¾à´àµà´àµà´"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "തിരà´àµà´à´¿à´²àµâ à´àµà´³àµâ"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "ഫയലàµà´à´³àµâ _à´¤àµà´±à´àµà´àµà´ ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "_URL à´¤àµà´±à´àµà´àµà´"
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_ഫയലàµà´à´³àµâ à´àµà´°àµâà´àµà´àµà´"
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "U_RL à´àµà´°àµâà´àµà´àµà´"
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "_à´à´¤àµà´ªàµà´ªà´±àµà´±à´¿ ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_à´ªàµà´±à´¤àµà´¤àµà´à´à´àµà´àµà´"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_പാà´àµà´"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "à´ªàµ_സൠà´àµà´¯àµà´¯àµà´"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_നിരàµâà´¤àµà´¤àµà´"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_à´®àµà´®àµà´ªà´¤àµà´¤àµà´¤àµ"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_à´
à´àµà´¤àµà´¤à´¤àµ"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_à´à´µà´°àµâà´¤àµà´¤à´¿à´¯àµà´àµà´àµà´"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_à´à´¶à´àµà´àµà´"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "N_o à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ à´ªàµà´°àµà´à´®à´¨à´"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "_ഠപാà´àµà´àµ à´à´´à´¿à´àµà´à´¾à´²àµâ നിരàµâà´¤àµà´¤àµà´"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "à´¸àµà´àµ à´à´¨àµâഫൠ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "_സമയതàµà´¤à´¿à´²àµà´àµà´àµ à´à´¾à´àµà´ ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "പാà´àµà´à´¿à´²àµà´àµà´àµ _à´à´¾à´àµà´ ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "_à´àµà´±àµà´±à´¿à´²àµâ à´
à´¨àµà´¸à´°à´¿à´àµà´àµ"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "_ഫയലàµâà´¨àµà´¯à´¿à´ à´
à´¨àµà´¸à´°à´¿à´àµà´àµ"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "ഫയലàµâ_പാതàµà´¤àµ à´
à´¨àµà´¸à´°à´¿à´àµà´àµ"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "à´àµà´°à´¾à´àµà´àµ _നമàµà´ªà´°àµâ à´
à´¨àµà´¸à´°à´¿à´àµà´àµ"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "_à´à´°àµâà´àµà´à´¿à´¸àµà´±àµà´±à´¿à´¨à´¨àµà´¸à´°à´¿à´àµà´àµ"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "à´_à´²àµâബമനàµà´¸à´°à´¿à´àµà´àµ"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "റിലàµà´¸àµ à´¡àµà´±àµà´±àµ à´
à´¨àµà´¸à´°à´¿à´àµà´àµ"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "_à´¨àµà´³à´®à´¨àµà´¸à´°à´¿à´àµà´àµ"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "ഫയലàµâ പാതàµà´¤àµ à´
à´¨àµà´¸à´°à´¿à´àµà´àµ"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "à´¸àµà´µàµà´àµà´à´¯à´¾à´²àµà´³àµà´³ തലà´àµà´àµà´àµà´àµ à´
à´¨àµà´¸à´°à´¿à´àµà´àµ"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "à´¨àµ_à´°àµâവിപരàµà´¤ à´°àµà´¤à´¿"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_à´àµà´°à´®à´®à´¿à´²àµà´²à´¾à´¤àµà´¤ à´°àµà´¤à´¿"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "à´ à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ _പാà´àµà´"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "à´ªàµ_à´¤àµà´àµà´àµà´"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_à´àµà´°à´®à´¤àµà´¤à´¿à´²à´¾à´àµà´àµà´"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "_à´ªà´à´°àµâà´ªàµà´ªàµà´à´³àµâ à´¨àµà´àµà´à´ à´àµà´¯àµà´¯àµà´"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "_à´²à´àµà´¯à´®à´²àµà´²à´¾à´¤àµà´¤ ഫയലàµà´à´³àµâ à´¨àµà´àµà´à´ à´àµà´¯àµà´¯àµà´"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_à´ªàµà´¤à´¿à´¯à´¤àµ"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "à´ªàµà´°àµ _മാറàµà´±àµà´"
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_à´à´±à´àµà´àµà´®à´¤à´¿ à´àµà´¯àµà´¯àµà´ ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_à´à´¯à´±àµà´±àµà´®à´¤à´¿ à´àµà´¯àµà´¯àµà´ ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ _മാനàµà´à´°àµâ ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "à´àµà´¯àµ മാനàµà´à´°àµâ ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "à´¶à´¬àµà´¦à´ à´àµà´àµà´àµà´ (_U)"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "à´¶à´¬àµà´¦à´ à´àµà´±à´¯àµà´àµà´àµà´ (_D)"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_à´à´àµà´µà´²àµà´¸à´°àµâ"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "_à´®àµà´¨àµà´¬à´¾à´°àµâ à´à´¾à´£à´¿à´¯àµà´àµà´àµà´"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "_à´à´¨àµâà´«àµà´¬à´¾à´°àµâ à´à´¾à´£à´¿à´¯àµà´àµà´àµà´"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr ""
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "_à´¸àµà´±àµà´±à´¾à´±àµà´±à´¸àµà´¬à´¾à´°àµâ à´à´¾à´£à´¿à´¯àµà´àµà´àµà´"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "_à´
വശàµà´·à´¿à´àµà´àµà´¨àµà´¨ സമയഠà´à´¾à´£à´¿à´àµà´àµà´"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_ഫയലàµâ"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_à´ªàµà´²àµà´¬à´¾à´àµà´àµ"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "à´ªàµà´²àµ_ലിസàµà´±àµà´±àµ"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_à´¸àµà´µà´¨à´àµà´à´³àµâ"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_à´à´àµà´ªàµà´àµà´àµ"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_à´à´¾à´´àµà´"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_à´àµà´¯àµ/à´
à´£àµâà´àµà´¯àµ"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "_à´®àµà´±à´¿à´¯àµà´àµà´àµà´"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_à´ªà´à´°àµâà´¤àµà´¤àµà´"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_à´à´àµà´à´¿à´¯àµà´àµà´àµà´"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "_à´à´²àµà´²à´¾à´ തിരà´àµà´àµà´àµà´àµà´àµà´"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "à´ªàµà´°àµ _മാറàµà´±àµà´ ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>പലവà´</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK à´à´¨àµâà´¡à´°àµâà´«àµà´¸àµ"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - à´à´¡à´¾à´·àµà´¯à´¸àµ"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ബഫരàµâ à´àµà´¯àµà´¯àµà´¨àµà´¨àµ ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "à´à´¡à´¾à´·àµà´¯à´¸àµ"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "à´®àµà´£àµ"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "à´¸àµà´±àµà´±àµà´°à´¿à´¯àµ"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d à´à´¾à´¨à´²àµâ"
msgstr[1] "%d à´à´¾à´¨à´²àµà´à´³àµâ"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "സിà´à´àµà´³àµâ à´®àµà´¡àµ"
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ à´®àµà´¡àµ"
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "പാà´àµà´à´¿à´¨àµ à´¶àµà´·à´ നിരàµâà´¤àµà´¤àµà´¨àµà´¨àµ."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "à´®àµà´®àµà´ªà´¤àµà´¤àµ à´àµà´°à´¾à´àµà´àµ"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "പാà´àµà´"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "à´ªàµà´¸àµ/à´±àµà´¸àµà´¯àµà´"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "നിരàµâà´¤àµà´¤àµà´"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "à´
à´àµà´¤àµà´¤ à´àµà´°à´¾à´àµà´àµ"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "5 à´¸àµà´àµà´à´¨àµâഡൠമàµà´¨àµà´¨àµà´àµà´àµ"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "5 à´¸àµà´àµà´à´¨àµâഡൠപിനàµà´¨àµà´àµà´àµ"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "നിശàµà´¶à´¬àµà´¦à´®à´¾à´àµà´àµà´"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "à´¶à´¬àµà´¦à´ à´àµà´àµà´àµà´"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "à´¶à´¬àµà´¦à´ à´àµà´±à´¯àµà´àµà´àµà´"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "ഫയലിലàµà´¯àµà´àµà´àµ à´à´¾à´àµà´"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "à´à´£àµâ-à´¸àµà´àµà´°àµà´¨àµâ-à´¡à´¿à´¸àµâà´ªàµà´²àµ à´à´¾à´£à´¿à´¯àµà´àµà´àµà´"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(à´¶àµà´¨àµà´¯à´)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1920,15 +2004,11 @@ msgstr ""
"\n"
"നിà´àµà´à´³àµâà´àµà´àµ à´¤àµà´à´°à´¾à´¨àµâ താലàµà´ªà´°àµà´¯à´®àµà´£àµà´àµ ?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "à´®àµà´¸àµ à´¬à´àµà´à´£àµà´à´³àµâ à´¬àµà´¨àµà´±àµ à´àµà´¯àµà´¯àµà´¨àµà´¨àµ"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "à´à´àµà´³ à´¹àµà´àµà´àµ à´àµ à´ªàµà´²à´à´¿à´¨àµâ à´àµà´°à´®àµà´à´°à´£à´"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -1936,23 +2016,27 @@ msgstr ""
"à´àµà´àµà´¸àµà´±àµà´±àµ à´«àµà´²àµâà´¡à´¿à´¨àµà´³àµà´³à´¿à´²àµâ à´à´°àµ à´àµ à´àµà´®àµà´ªà´¿à´¨àµà´·à´¨àµâ à´
മരàµâà´¤àµà´¤àµà´.\n"
"à´®àµà´¸àµ à´¬à´àµà´à´£àµà´à´³àµà´ നിà´àµà´à´³àµâà´àµà´àµ à´¬àµà´¨àµâഡൠà´àµà´¯àµà´¯à´¾à´."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "à´¹àµà´àµà´àµà´à´³àµâ"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>à´ªàµà´°à´µàµà´¤àµà´¤à´¿:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>à´àµ à´¬àµà´¨àµà´±à´¿à´àµ:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr ""
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1967,124 +2051,90 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "à´à´¾à´àµà´àµ à´à´àµà´ªàµà´àµà´àµ"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "à´à´¾à´àµà´àµ à´à´àµà´ªàµà´àµà´àµ"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s à´àµà´°à´®àµà´à´°à´£à´àµà´à´³àµâ"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA à´¹àµà´¸àµà´±àµà´±àµ à´àµà´°à´®àµà´à´°à´£à´àµà´à´³àµâ"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "à´®àµà´¡àµà´¯àµà´³àµâ പാതàµà´¤àµà´à´³àµâ:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
"After adding new paths, press Enter to scan for new plugins.</small>"
msgstr ""
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "à´²à´àµà´¯à´®à´¾à´¯ à´ªàµà´²à´àµà´à´¿à´¨àµà´¨àµà´à´³àµâ:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "സാദàµà´§àµà´¯à´®à´¾à´àµà´àµà´"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "à´ªàµà´²à´àµà´à´¿à´¨àµà´à´³àµâ സാദàµà´§àµà´¯à´®à´¾à´àµà´àµà´:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "à´àµà´°à´®àµà´à´°à´£à´àµà´à´³àµâ"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA à´¹àµà´¸àµà´±àµà´±àµ"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr ""
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: à´ªàµà´¨à´°àµâബനàµà´§à´¨à´¤àµà´¤à´¿à´¨àµ à´¶àµà´°à´®à´¿à´àµà´àµà´¨àµà´¨àµ...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s à´
à´àµà´à´¾à´¤à´®à´¾à´¯ à´à´®à´¾à´¨àµà´±àµ \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: LIRC യിലàµâ നിനàµà´¨àµà´ ബനàµà´§à´ à´µàµà´°àµâà´ªàµà´àµà´¤àµà´¤à´¿\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: à´à´²àµà´²à´¾ %d à´¸àµà´àµà´à´¨àµâà´¡àµà´à´³à´¿à´²àµà´ à´ªàµà´¨à´°àµâബനàµà´§à´¤àµà´¤à´¿à´¨àµ à´¶àµà´°à´®à´¿à´àµà´àµà´...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC à´ªàµà´²à´àµà´à´¿à´¨àµâ"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2100,73 +2150,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>ബനàµà´§à´</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "LIRC à´¸àµà´°àµâവറàµà´®à´¾à´¯à´¿ à´µàµà´£àµà´àµà´ ബനàµà´§à´¿à´ªàµà´ªà´¿à´¯àµà´àµà´àµà´"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "à´ªàµà´¨à´°àµâബനàµà´§à´¤àµà´¤à´¿à´¨àµ à´®àµà´®àµà´ªàµ à´à´¾à´¤àµà´¤à´¿à´°à´¿à´àµà´àµà´:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC à´ªàµà´²à´àµà´à´¿à´¨àµâ"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki à´ªàµà´²à´àµà´à´¿à´¨àµâ"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "വരിà´à´³àµâ à´²à´àµà´¯à´®à´²àµà´²"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "പിശà´àµ"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "പിശà´àµ"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "വരിà´à´³àµâà´àµà´à´¾à´¯à´¿ à´¨àµà´àµà´àµà´¨àµà´¨àµ ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "à´à´¿à´² à´®àµà´±àµà´±à´¾à´¡àµà´±àµà´± à´²à´àµà´¯à´®à´²àµà´²"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki à´ªàµà´²à´àµà´à´¿à´¨àµâ"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµà´à´³àµâ"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "à´à´¾à´àµà´±àµà´±àµ à´à´¨à´±àµà´±àµà´±à´°àµâ"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr ""
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr ""
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2175,162 +2233,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "à´à´¾à´àµà´±àµà´±àµ à´à´¨à´±àµà´±àµà´±à´°àµâ"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "à´à´¾à´¨à´²àµâ മിà´àµà´¸à´°àµâ"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>à´à´¾à´¨à´²àµâ മിà´àµà´¸à´°àµâ</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "à´à´àµà´ªàµà´àµà´àµ à´à´¾à´¨à´²àµà´à´³àµâ:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "à´à´¾à´¨à´²àµâ മിà´àµà´¸à´°àµâ"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS à´ªàµà´²à´àµà´à´¿à´¨àµâ"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>à´±àµà´¸à´²àµà´¯àµà´·à´¨àµâ</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-ബിറàµà´±àµ"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-ബിറàµà´±àµ"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>à´à´¾à´¨à´²àµà´à´³àµâ</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "à´à´±àµà´±à´µàµà´ à´
à´àµà´¤àµà´¤àµà´³àµà´³à´¤àµ (à´à´±àµà´±à´µàµà´ à´µàµà´à´¤à´¯àµà´³àµà´³à´¤àµ)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>സാà´à´ªàµà´²à´¿à´àµ നിരà´àµà´àµ</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "തലà´:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "à´à´àµà´àµà´«àµ:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b> à´ªàµà´°à´¤à´¿à´§àµà´µà´¨à´¿ </b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>à´¬àµà´¸àµ à´¬àµà´¸àµà´±àµà´±àµ</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>സറàµà´£àµà´àµ</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>à´ªàµà´°àµà´à´à´ªàµ</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "à´à´µà´°àµâസാമàµà´ªàµà´³àµâ"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "à´¨àµà´¯àµà´¸àµ റിഡà´àµà´·à´¨àµâ"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>à´à´µà´°àµâà´¤àµà´¤à´¿à´¯àµà´àµà´àµà´</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "à´à´µà´°àµâà´¤àµà´¤à´àµà´à´³àµà´àµ à´à´£àµà´£à´:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
msgstr ""
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "സറàµà´£àµà´àµ"
-
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 à´ªàµà´²à´àµà´à´¿à´¨àµâ"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "സറàµà´£àµà´àµ"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 à´¸àµà´°àµâവരàµâ"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr ""
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "നിരàµâà´¤àµà´¤à´¿"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "à´à´¡à´¾à´·àµà´¯à´¸àµ à´ªàµà´°à´µà´°àµâà´¤àµà´¤à´¿à´àµà´àµà´¨àµà´¨à´¿à´²àµà´²."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "à´¡àµà´¸àµà´àµà´àµà´ªàµà´ªàµ à´
റിയിപàµà´ªàµà´à´³àµâ"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2350,55 +2440,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "à´ªàµà´²àµà´¬à´¾à´àµà´àµ à´àµà´°à´®àµà´à´°à´£à´àµà´à´³àµâ à´à´¾à´£à´¿à´àµà´àµà´"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "à´à´²àµà´²à´¾à´¯àµà´ªàµà´ªàµà´´àµà´ വിà´àµà´à´¾à´ªà´¨à´àµà´à´³àµâ à´à´¾à´£à´¿à´àµà´àµà´"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "à´¡àµà´¸àµà´àµà´àµà´ªàµà´ªàµ à´
റിയിപàµà´ªàµà´à´³àµâ"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "à´à´¾à´£à´¿à´¯àµà´àµà´àµà´"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "à´ªàµà´¸àµ à´àµà´¯àµà´¯àµà´"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "à´
à´àµà´¤àµà´¤à´¤àµ"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. à´¸àµà´µà´¤à´µàµà´¯àµà´³àµà´³ à´à´ªà´à´°à´£à´"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 à´à´àµà´ªàµà´àµà´àµ"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "à´à´¡à´¿à´¯àµ à´à´ªà´à´°à´£à´:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "ബദലàµâ à´à´ªà´à´°à´£à´ à´à´ªà´¯àµà´à´¿à´¯àµà´àµà´àµà´"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "à´¸àµà´·à´¨àµà´à´³àµà´àµ à´à´à´¯à´¿à´²àµà´³àµà´³ à´à´àµà´à´¤ à´¸àµà´µàµ à´àµà´¯àµà´¯àµà´."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "OSS à´¸àµà´«àµà´±àµà´±àµà´µàµà´¯à´°àµâ തയàµà´¯à´¾à´±à´¾à´àµà´à´¿à´¯ à´«àµà´°àµâമാറàµà´±àµ മാറàµà´±à´àµà´à´³àµâ സാധàµà´¯à´®à´¾à´àµà´àµà´."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2407,19 +2506,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 à´à´àµà´ªàµà´àµà´àµ"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµà´à´³àµâ"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr ""
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "പളàµâà´¸àµâà´à´¡à´¿à´¯àµ à´à´àµà´ªàµà´àµà´àµ"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2439,143 +2554,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "പളàµâà´¸àµâà´à´¡à´¿à´¯àµ à´à´àµà´ªàµà´àµà´àµ"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "à´®àµà´®àµà´ªà´¤àµà´¤àµà´¤àµ"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "à´à´µà´°àµâà´¤àµà´¤à´¿à´¯àµà´àµà´àµà´"
-#: src/resample/resample.c:165
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "à´à´¶à´àµà´àµà´"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr ""
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr ""
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>à´à´£àµâà´µàµà´°àµâà´·à´¨àµâ</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "à´°àµà´¤à´¿:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "à´¤àµà´¤àµ:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr ""
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr ""
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "à´
à´¨àµà´µà´¾à´¦à´ à´à´²àµà´²"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "à´¨àµà´±àµà´±àµâവരàµâà´àµà´àµ à´àµà´´à´ªàµà´ªà´."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "പരിശàµà´§à´¿à´àµà´àµà´¨àµà´¨àµ..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "à´¸àµâà´àµà´°àµà´¬àµà´¬àµà´²à´°àµâ 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2586,765 +2770,840 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "à´¸àµâà´àµà´°àµà´¬àµà´¬àµà´²à´°àµâ 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr ""
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr ""
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "à´àµà´°à´¨àµà´¥à´¶à´¾à´²"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "à´
à´àµà´à´¾à´¤à´¨à´¾à´¯ à´à´²à´¾à´à´¾à´°à´¨àµâ"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "à´
à´àµà´à´¾à´¤à´®à´¾à´¯ പാà´àµà´àµ"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d പാà´àµà´àµ"
-msgstr[1] "%d പാà´àµà´àµà´à´³àµâ"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ _നിരàµâമിà´àµà´àµà´"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±à´¿à´²àµà´¯àµà´àµà´àµ _à´àµà´°àµâà´àµà´àµà´"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "à´àµà´°à´¨àµà´¥à´¶à´¾à´² തിരയàµà´"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "ദയവായി à´à´¾à´¤àµà´¤à´¿à´°à´¿à´àµà´àµà´ ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "à´«àµà´³àµâà´¡à´°àµâ à´¤àµà´°àµà´àµà´àµà´àµà´àµà´àµà´"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "à´ªàµà´²àµà´¬à´¾à´àµà´àµ"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "à´à´¾à´£àµà´"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "à´à´µà´°àµâà´¤àµà´¤à´¿à´¯àµà´àµà´àµà´"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "à´à´¶à´àµà´àµà´"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr ""
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "à´®àµà´®àµà´ªà´¤àµà´¤àµà´¤àµ"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "à´ªàµà´¤à´¿à´¯ à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ à´à´¡à´¿à´±àµà´±à´°àµâ à´à´¾à´£à´¿à´àµà´àµà´"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "à´à´àµà´µà´²àµà´°àµâ à´ªàµà´°à´¦à´°àµâà´¶à´¿à´ªàµà´ªà´¿à´¯àµà´àµà´àµà´"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "à´à´ªàµà´ªàµà´´àµà´ à´®àµà´à´³à´¿à´²àµâ"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "à´àµà´±àµà´±à´¿à´²à´¿à´¨à´¨àµà´¸à´°à´¿à´àµà´àµ"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "ഫയലàµâà´¨àµà´¯à´¿à´®à´¨àµà´¸à´°à´¿à´àµà´àµ"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "à´à´²àµà´²à´¾à´ à´¨àµà´àµà´à´ à´àµà´¯àµà´¯àµà´"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "വരി à´µàµà´à´¿à´ªàµà´ªà´¾à´àµà´àµà´"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "à´²à´àµà´¯à´®à´²àµà´²à´¾à´¤àµà´¤ ഫയലàµà´à´³àµâ à´¨àµà´àµà´à´à´àµà´¯àµà´¯àµà´"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "à´ªà´à´°àµâà´ªàµà´ªàµà´à´³àµâ à´à´´à´¿à´µà´¾à´àµà´àµà´"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "തിരà´àµà´àµà´àµà´àµà´à´¾à´¤àµà´¤à´µ à´¨àµà´àµà´à´à´àµà´¯àµà´¯àµà´"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "തിരà´àµà´àµà´àµà´¤àµà´¤à´µ à´¨àµà´àµà´à´à´àµà´¯àµà´¯àµà´"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "തിരയàµà´, തിരà´àµà´àµà´àµà´àµà´àµà´"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "തിരà´àµà´àµà´àµà´ªàµà´ªàµ à´à´¨àµâà´µàµà´°àµâà´àµà´àµ à´àµà´¯àµà´¯àµà´"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "à´à´¨àµà´¨àµà´ തിരà´àµà´àµà´àµà´àµà´àµà´£àµà´"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "à´âà´²àµà´²à´¾à´ തിരà´àµà´àµà´àµà´àµà´àµà´"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "à´à´²àµâബമനàµà´¸à´°à´¿à´àµà´àµ"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "à´àµà´°à´¾à´àµà´àµ നമàµà´ªà´°àµâ à´
à´¨àµà´¸à´°à´¿à´àµà´àµ"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "à´à´°àµâà´àµà´à´¸àµà´±àµà´±à´¿à´¨à´¨àµà´¸à´°à´¿à´àµà´àµ"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "à´à´²àµâബമനàµà´¸à´°à´¿à´àµà´àµ"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "à´àµà´°à´¾à´àµà´àµ നമàµà´ªà´°àµâ à´
à´¨àµà´¸à´°à´¿à´àµà´àµ"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "ലിസàµà´±àµà´±àµ à´àµà´°à´®à´®à´¿à´²àµà´²à´¾à´¤àµà´¯à´¾à´àµà´àµà´"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "à´ªà´àµà´à´¿à´ തലതിരിയàµà´àµà´àµà´"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "തിരà´àµà´àµà´àµà´¤àµà´¤à´µ à´àµà´°à´®àµà´à´°à´¿à´¯àµà´àµà´àµà´"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "à´ªà´àµà´à´¿à´ à´
à´àµà´·à´°à´®à´¾à´²à´¾à´àµà´°à´®à´¤àµà´¤à´¿à´²à´¾à´àµà´àµà´"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "à´®àµà´±à´¿à´¯àµà´àµà´àµà´"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "à´ªà´à´°àµâà´¤àµà´¤àµà´"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "à´à´àµà´à´¿à´¯àµà´àµà´àµà´"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr ""
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "à´¸àµà´µàµ"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "à´²àµà´¡àµ à´àµà´¯àµà´¯àµà´"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "à´ªàµà´°àµà´¸àµà´±àµà´±àµà´à´³àµâ"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "à´ªàµà´°àµà´¸àµà´±àµà´±àµ à´²àµà´¡àµ à´àµà´¯àµà´¯àµà´"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "à´à´àµà´àµ-à´ªàµà´°àµà´¸àµà´±àµà´±àµ à´²àµà´¡àµ à´àµà´¯àµà´¯àµà´"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "à´ªàµà´°àµà´¸àµà´±àµà´±àµ à´¸àµà´µàµ à´àµà´¯àµà´¯àµà´"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "à´à´àµà´àµ à´ªàµà´°àµà´¸àµà´±àµà´±àµ à´¸àµà´µàµ à´àµà´¯àµà´¯àµà´"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "à´ªàµà´°àµà´¸àµà´±àµà´±àµ à´¨àµà´àµà´à´à´àµà´¯àµà´¯àµà´"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "à´à´àµà´àµ à´ªàµà´°àµà´¸àµà´±àµà´±àµ à´¨àµà´àµà´à´ à´àµà´¯àµà´¯àµà´"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_à´ªàµà´²àµà´¯à´°àµâ:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "à´ªàµà´°à´§à´¾à´¨à´ªàµà´ªàµà´àµà´ à´ªàµà´²àµà´¯à´°àµâ വിനàµâà´¡àµà´¯àµà´àµ à´«àµà´£àµà´àµ à´¤àµà´°àµà´àµà´àµà´àµà´àµà´àµà´:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "à´ªàµà´²àµ_ലിസàµà´±àµà´±àµ:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ à´«àµà´£àµà´àµ à´¤àµà´°àµà´àµà´àµà´àµà´àµà´àµà´:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "ബിറàµà´±àµà´®à´¾à´ªàµ à´«àµà´£àµà´àµà´à´³àµâ à´à´ªà´¯àµà´à´¿à´àµà´à´¾à´ (ASCII മാതàµà´°à´ പിനàµâà´¤àµà´£à´¯àµà´àµà´àµà´)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "à´°à´£àµà´àµ ദിശà´à´³à´¿à´²àµà´ പാà´àµà´à´¿à´¨àµà´±àµ à´¶àµà´°àµâà´·à´à´ à´¸àµâà´àµà´°àµà´³àµâ à´àµà´¯àµà´¯àµà´"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "à´
നലàµà´¸à´°àµâ"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "à´¸àµà´àµà´ªàµà´ªàµ"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "à´à´«àµ"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "സാധാരണà´"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "à´¤àµ"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "വരà´à´³àµâ"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "നാà´à´à´³àµâ"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "വളരàµà´ªàµà´ªà´¤àµà´àµà´àµ"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "പതàµà´àµà´àµ"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "പാà´à´"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "à´µàµà´à´"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "à´
തിദàµà´°àµà´¤à´"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "à´à´¸àµ"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "à´®àµà´¦àµà´²à´"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "à´ªàµà´¤àµà´µà´¾à´¯à´µ"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "à´¦àµà´¶àµà´¯à´µà´¤àµà´à´°à´£à´"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "à´ªàµà´°àµà´à´à´ªàµ"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "à´à´¡à´¾à´·àµà´¯à´¸àµ à´à´àµà´µà´²àµà´¸à´°àµâ"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "തിരയàµà´ %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "à´¶à´¬àµà´¦à´: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "à´
വശàµà´·à´¿à´àµà´àµà´¨àµà´¨à´¤àµ: %d%% വലതàµ"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "à´
വശàµà´·à´¿à´àµà´àµà´¨àµà´¨à´¤àµ: à´¨à´àµà´µà´¿à´²àµâ"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "à´
വശàµà´·à´¿à´àµà´àµà´¨àµà´¨à´¤àµ: %d%% à´à´à´¤àµ"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "à´à´ªàµà´·à´¨àµâസൠമàµà´¨àµ"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "'à´à´ªàµà´ªàµà´´àµà´ à´®àµà´à´³à´¿à´²àµâ' à´
സാദàµà´§àµà´¯à´®à´¾à´àµà´àµà´"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "'à´à´ªàµà´ªàµà´´àµà´ à´®àµà´à´³à´¿à´²àµâ' സാദàµà´§àµà´¯à´®à´¾à´àµà´àµà´"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "ഫയലàµâ à´à´¨àµâഫൠà´à´¾à´²à´à´"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "സിà´à´àµà´³àµâ à´®àµà´¡àµ"
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ à´®àµà´¡àµ"
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "പാà´àµà´à´¿à´¨àµ à´¶àµà´·à´ നിരàµâà´¤àµà´¤àµà´¨àµà´¨àµ."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "à´¸à´àµà´µà´®à´¾à´¯ à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±à´¿à´²àµ à´à´¨àµâà´àµà´°à´¿à´à´³àµâ തിരയàµà´"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3352,57 +3611,61 @@ msgid ""
"for."
msgstr ""
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "à´àµà´±àµà´±à´¿à´²àµâ:"
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "à´à´²àµâà´¬à´:"
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "à´à´°àµâà´àµà´à´¿à´¸àµà´±àµà´±àµ:"
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "ഫയലàµâനാമà´:"
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "തിരയàµà´¨àµà´¨à´¤à´¿à´¨àµà´®àµà´®àµà´ªàµ à´®àµà´®àµà´ªàµà´³àµà´³ തിരà´àµà´àµà´àµà´ªàµà´ªàµ à´µàµà´à´¿à´ªàµà´ªà´¾à´àµà´àµà´"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "à´¯àµà´à´¿à´¯àµà´àµà´àµà´¨àµà´¨ à´à´¨àµâà´àµà´°à´¿à´à´³àµâ à´à´ªà´¯àµà´à´¿à´àµà´àµ à´ªàµà´¤à´¿à´¯àµà´°àµ à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ à´à´£àµà´à´¾à´àµà´àµà´"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "à´à´¡à´¾à´·àµà´¯à´¸àµ à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±àµ à´à´¡à´¿à´±àµà´±à´°àµâ"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d / %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "à´¶àµà´à´°à´¿à´àµà´à´ªàµà´ªàµà´àµà´ വിനാമàµà´ªàµ 2.x à´°àµà´ªà´"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "à´¶àµà´à´°à´¿à´àµà´à´¾à´¤àµà´¤ വിനാമàµà´ªàµ 2.x à´°àµà´ªà´"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "à´«àµà´³àµâà´¡à´°àµâ നിരàµâമാണഠസാധàµà´¯à´®à´²àµà´² (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile à´ªàµà´²à´àµà´à´¿à´¨àµâ"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3424,76 +3687,69 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile à´ªàµà´²à´àµà´à´¿à´¨àµâ"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "പിനàµà´¤àµà´£à´¯à´¿à´²àµà´²à´¾à´¤àµà´¤ à´«àµà´°àµâമാറàµà´±àµ"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-#: src/sndio/sndio.c:384
-msgid "sndio device"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(à´¶àµà´¨àµà´¯à´ à´à´¨àµà´¨àµ à´
à´°àµâà´¤àµà´¥à´®à´¾à´àµà´àµà´¨àµà´¨à´¤àµ à´¸àµà´µà´¤à´¸àµà´¸à´¿à´¦àµà´§à´¤àµà´¤àµà´¯à´¾à´£àµ)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "à´¶à´°à´¿"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "പാà´àµà´àµ മാറàµà´±àµà´"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "à´à´¡à´¾à´·àµà´¯à´¸àµ à´ªàµà´¤à´¿à´¯ പാà´àµà´àµ à´à´°à´à´à´¿à´àµà´àµà´®àµà´ªàµà´³àµâ à´ªàµà´°à´µà´°àµâà´¤àµà´¤à´¿à´ªàµà´ªà´¿à´àµà´à´¾à´¨àµà´³àµà´³ à´à´®à´¾à´¨àµà´±àµ."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "à´à´²àµâà´ªàµà´ªà´¨:"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "പാà´àµà´à´¿à´¨àµà´±àµ à´
വസാനതàµà´¤à´¿à´²àµà´àµà´àµ റണàµâ à´àµà´¯àµà´¯à´¾à´¨àµâ à´µàµà´£àµà´ à´à´®à´¾à´¨àµà´±àµ."
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "à´à´¡à´¾à´·àµà´¯à´¸àµ à´ªàµà´²àµà´²à´¿à´¸àµà´±àµà´±à´¿à´¨àµà´±àµ à´
വസാനതàµà´¤à´¿à´²àµà´¯àµà´àµà´àµ à´à´¤àµà´¤àµà´®àµà´ªàµà´³àµâ റണàµâ à´àµà´¯àµà´¯à´¾à´¨àµâ à´µàµà´£àµà´ à´à´®à´¾à´¨àµà´±àµ."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"പാà´àµà´à´¿à´¨àµà´±àµ à´¶àµà´°àµâà´·à´à´ മാറàµà´®àµà´ªàµà´³àµâ റണàµâ à´àµà´¯àµà´¯àµà´¨àµà´¨ à´à´®à´¾à´¨àµà´±àµ (à´
തായതൠനàµà´±àµà´±àµâവരàµâà´àµà´àµ à´¸àµâà´àµà´°àµà´®àµà´à´³àµà´àµ à´¶àµà´°àµâà´·à´à´àµà´à´³àµâ)."
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3508,17 +3764,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "à´à´²àµâà´ªàµà´ªà´¨à´à´³àµâ"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX à´±àµà´¸à´¾à´à´ªàµà´²à´°àµâ"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3527,51 +3781,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "à´¦àµà´°àµà´¤à´"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "താഴàµà´¨àµà´¨à´¤àµ"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "à´à´¯à´°àµâà´¨àµà´¨à´¤àµ"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "വളരൠà´à´¯à´°àµâà´¨àµà´¨à´¤àµ"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "à´àµà´£à´®àµà´¨àµà´®:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX à´±àµà´¸à´¾à´à´ªàµà´²à´°àµâ"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "à´µàµà´à´µàµà´ à´¶àµà´°àµà´¤à´¿à´¯àµà´"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>à´µàµà´à´µàµà´ à´¶àµà´°àµà´¤à´¿à´¯àµà´</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "à´µàµà´à´:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "à´¶àµà´°àµà´¤à´¿:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "à´µàµà´à´µàµà´ à´¶àµà´°àµà´¤à´¿à´¯àµà´"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "à´¸àµà´±àµà´±à´¾à´±àµà´±à´¸àµ à´à´àµà´à´£àµâ"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3582,63 +3836,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr ""
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "à´¶à´¬àµà´¦àµà´àµà´à´¤ മാറàµà´±àµà´"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "പാà´àµà´¨àµà´¨ പാà´àµà´àµ മാറàµà´±àµà´"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>മറàµà´±àµ à´àµà´°à´®àµà´à´°à´£à´àµà´à´³àµâ</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "à´ªàµà´ªàµà´ªà´ªàµà´ªàµ à´à´¾à´²à´à´ à´
സാദàµà´§àµà´¯à´®à´¾à´àµà´àµà´"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "സിസàµà´±àµà´±à´ à´àµà´°àµà´¯à´¿à´²àµà´¯àµà´àµà´àµ à´
à´à´àµà´à´¿à´àµà´"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "à´¸àµà´±àµà´±à´¾à´±àµà´±à´¸àµ à´à´àµà´à´£àµâ"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "à´à´àµà´¸àµà´àµà´°à´¾ à´¸àµà´±àµà´±àµà´°à´¿à´¯àµ"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>à´à´àµà´¸àµà´àµà´°à´¾ à´¸àµà´±àµà´±àµà´°à´¿à´¯àµ</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "à´à´àµà´¸àµà´àµà´°à´¾ à´¸àµà´±àµà´±àµà´°à´¿à´¯àµ"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "à´àµà´£àµâ à´à´¨à´±àµà´±àµà´±à´°àµâ"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "à´àµà´£àµâ à´à´¨à´±àµà´±àµà´±à´°àµâ: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3647,15 +3901,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "à´àµà´£àµâ à´à´¨à´±àµà´±àµà´±à´°àµâ"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "à´µàµà´¯àµà´¸àµ റിമàµà´µà´²àµâ"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3676,44 +3926,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis à´¡àµà´àµà´¡à´°àµâ"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX à´¡àµà´àµà´¡à´°àµâ"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX à´¡àµà´àµà´¡à´°àµâ"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack à´¡àµà´àµà´¡à´°àµâ"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "à´²àµà´¸à´¿ (à´¸à´àµà´à´°à´)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "à´²àµà´¸à´¿"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack à´¡àµà´àµà´¡à´°àµâ"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF à´¡àµà´àµà´¡à´°àµâ"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr ""
diff --git a/po/ms.po b/po/ms.po
new file mode 100644
index 000000000000..9a99a85c84d7
--- /dev/null
+++ b/po/ms.po
@@ -0,0 +1,4352 @@
+# Malay translation for Audacious Plugins
+# Copyright (C) Audacious translators
+# This file is distributed under the same license as the Audacious Plugins package.
+#
+# Translators:
+# abuyop <abuyop at gmail.com>, 2014-2015
+# Mick The KN <f.seedsss at gmail.com>, 2012
+msgid ""
+msgstr ""
+"Project-Id-Version: Audacious Plugins\n"
+"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-09 15:08+0000\n"
+"Last-Translator: abuyop <abuyop at gmail.com>\n"
+"Language-Team: Malay (http://www.transifex.com/projects/p/audacious/language/"
+"ms/)\n"
+"Language: ms\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"
+
+#: src/aac-raw/aac.cc:18
+msgid "AAC (Raw) Decoder"
+msgstr "Penyahkod AAC (Raw)"
+
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (Pemain AdLib)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
+msgid "sequenced"
+msgstr "berjujukan"
+
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Penggera"
+
+#: src/alarm/alarm.cc:782
+msgid "Set Alarm ..."
+msgstr "Tetapkan Penggera ..."
+
+#: src/alarm/alarm.cc:810
+msgid ""
+"A plugin that can be used to start playing at a certain time.\n"
+"\n"
+"Originally written by Adam Feakin and Daniel Stodden."
+msgstr ""
+"Pemalam yang boleh digunakan untuk mula memainkan pada\n"
+"masa tertentu.\n"
+"\n"
+"Asalnya ditulis oleh Adam Feakin dan Daniel Stodden."
+
+#: src/alarm/interface.cc:28
+msgid ""
+"Time\n"
+" Alarm at:\n"
+" The time for the alarm to come on.\n"
+"\n"
+" Quiet after:\n"
+" Stop alarm after this amount of time.\n"
+" (if the wakeup dialog is not closed)\n"
+"\n"
+"\n"
+"Days\n"
+" Day:\n"
+" Select the days for the alarm to activate.\n"
+"\n"
+" Time:\n"
+" Choose the time for the alarm on each day,\n"
+" or select the toggle button to use the default\n"
+" time.\n"
+"\n"
+"\n"
+msgstr ""
+"Masa\n"
+" Penggera pada:\n"
+" Masa untuk penggera bergerak.\n"
+"\n"
+" Senyap selepas:\n"
+" Hentikan penggera selepas amaum masa ini.\n"
+" (jika dialog bangun tidak ditutup)\n"
+"\n"
+"\n"
+"Hari\n"
+" Hari:\n"
+" Pilih hari untuk penggera diaktifkan.\n"
+"\n"
+" Masa:\n"
+" Pilih masa untuk penggera pada setiap hari,\n"
+" atau pilih butang togol untuk guna masa\n"
+" lalai.\n"
+"\n"
+"\n"
+
+#: src/alarm/interface.cc:45
+msgid ""
+"Volume\n"
+" Fading:\n"
+" Fade the volume up to the chosen volume\n"
+" for this amount of time.\n"
+"\n"
+" Start at:\n"
+" Start fading from this volume.\n"
+"\n"
+" Final:\n"
+" The volume to stop fading at. If the fading\n"
+" time is 0 then set volume to this and start\n"
+" playing.\n"
+"\n"
+"\n"
+"Options:\n"
+" Additional Command:\n"
+" Run this command at the alarm time.\n"
+"\n"
+msgstr ""
+"Volum\n"
+" Pelenyapan:\n"
+" Lenyapkan volum mengikut volum pilihan\n"
+" untuk amaun masa ini.\n"
+"\n"
+" Mula pada:\n"
+" Mula melenyap dari volum ini.\n"
+"\n"
+" Akhir:\n"
+" Volum berhenti melenyap. Jika masa melenyap\n"
+" adalah 0 maka tetapkan volum pada ini dan mula\n"
+" main.\n"
+"\n"
+"\n"
+"Pilihan:\n"
+" Perintah Tambahan:\n"
+" Jalankan perintah ini pada masa penggera.\n"
+"\n"
+
+#: src/alarm/interface.cc:62
+msgid ""
+" Playlist:\n"
+" Load this playlist. If no playlist\n"
+" is given, the current one will be used.\n"
+" The URL of an mp3/ogg stream\n"
+" can also be entered here.\n"
+"\n"
+" Reminder:\n"
+" Display a reminder when the alarm goes off.\n"
+" Type the reminder in the box and turn on the\n"
+" toggle button if you want it to be shown."
+msgstr ""
+" Senarai Main:\n"
+" Muatkan senarai main ini. Jika tiada senarai main\n"
+" diberi, yang semasa akan digunakan.\n"
+" URL bagi strim mp3/ogg juga boleh digunakan\n"
+" di sini.\n"
+"\n"
+" Peringatan:\n"
+" Papar peringatan bila penggera dimatikan.\n"
+" Taip peringatan dalam kotak dan hidupkan\n"
+" butang togol jika anda mahu ia ditunjukkan."
+
+#: src/alarm/interface.cc:81
+msgid "This is your wakeup call."
+msgstr "Ini adalah panggilan bangun tidur anda."
+
+#: src/alarm/interface.cc:99
+msgid "Your reminder for today is..."
+msgstr "Peringatan untuk hari ini ialah..."
+
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
+msgid "Reminder"
+msgstr "Peringatan"
+
+#: src/alarm/interface.cc:132
+msgid "Monday"
+msgstr "Isnin"
+
+#: src/alarm/interface.cc:132
+msgid "Tuesday"
+msgstr "Selasa"
+
+#: src/alarm/interface.cc:132
+msgid "Wednesday"
+msgstr "Rabu"
+
+#: src/alarm/interface.cc:133
+msgid "Thursday"
+msgstr "Khamis"
+
+#: src/alarm/interface.cc:133
+msgid "Friday"
+msgstr "Jumaat"
+
+#: src/alarm/interface.cc:133
+msgid "Saturday"
+msgstr "Sabtu"
+
+#: src/alarm/interface.cc:133
+msgid "Sunday"
+msgstr "Ahad"
+
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
+msgid "Time"
+msgstr "Masa"
+
+#: src/alarm/interface.cc:178
+msgid "Alarm at (default):"
+msgstr "Penggera pada (lalai):"
+
+#: src/alarm/interface.cc:200
+msgid "h"
+msgstr "h"
+
+#: src/alarm/interface.cc:203
+msgid "Quiet after:"
+msgstr "Tenang selepas:"
+
+#: src/alarm/interface.cc:215
+msgid "hours"
+msgstr "jam"
+
+#: src/alarm/interface.cc:226
+msgid "minutes"
+msgstr "minit"
+
+#: src/alarm/interface.cc:235
+msgid "Choose the days for the alarm to come on"
+msgstr "Pilih hari bagi penggera beraktif"
+
+#: src/alarm/interface.cc:242
+msgid "Day"
+msgstr "Hari"
+
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
+msgid "Default"
+msgstr "Lalai"
+
+#: src/alarm/interface.cc:288
+msgid "Days"
+msgstr "Hari"
+
+#: src/alarm/interface.cc:297
+msgid "Fading"
+msgstr "Pudar"
+
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
+msgid "seconds"
+msgstr "Saat"
+
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
+msgid "Volume"
+msgstr "Volum"
+
+#: src/alarm/interface.cc:317
+msgid "Start at"
+msgstr "Bermula pada"
+
+#: src/alarm/interface.cc:333
+msgid "Final"
+msgstr "Terakhir"
+
+#: src/alarm/interface.cc:346
+msgid "Current"
+msgstr "Semasa"
+
+#: src/alarm/interface.cc:359
+msgid "Additional Command"
+msgstr "Perintah Tambahan"
+
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
+msgid "enable"
+msgstr "Aktif"
+
+#: src/alarm/interface.cc:372
+msgid "Playlist (optional)"
+msgstr "Senarai Main (pilihan)"
+
+#: src/alarm/interface.cc:379
+msgid "Select a playlist"
+msgstr "Pilih satu senarai main"
+
+#: src/alarm/interface.cc:399
+msgid "Options"
+msgstr "Pilihan"
+
+#: src/alarm/interface.cc:404
+msgid "What do these options mean?"
+msgstr "Apa pilihan ini bermakna?"
+
+#: src/alarm/interface.cc:420
+msgid "Help"
+msgstr "Bantuan"
+
+#: src/albumart/albumart.cc:31
+msgid "Album Art"
+msgstr "Seni Album"
+
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Seni Album (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "Output ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"Pemalam Output ALSA untuk Audacious\n"
+"Hakcipta 2009-2012 John Lindgren\n"
+"\n"
+"Terima kasih buat William Pitcock, pengarang Pemalam Output ALSA NG, yang "
+"mana kodnya dirujuk bila panduan ALSA tidak mencukupi."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(tiada keterangan)"
+
+#: src/alsa/config.cc:166
+msgid "Default PCM device"
+msgstr "Lalai peranti PCM"
+
+#: src/alsa/config.cc:188
+msgid "Default mixer device"
+msgstr "Lalai campuran peranti"
+
+#: src/alsa/config.cc:296
+msgid "PCM device:"
+msgstr "peranti PCM:"
+
+#: src/alsa/config.cc:299
+msgid "Mixer device:"
+msgstr "Peranti campuran:"
+
+#: src/alsa/config.cc:302
+msgid "Mixer element:"
+msgstr "Elemen campuran:"
+
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (Pemain MIDI)"
+
+#: src/amidi-plug/amidi-plug.cc:437
+msgid ""
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
+"\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
+"AMIDI-Plug\n"
+"Pemain muzik MIDI modular\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
+"\n"
+"ditulis oleh Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"terima kasih buat...\n"
+"\n"
+"Clemens Ladisch dan Jaroslav Kysela\n"
+"atas program hebat aplaymidi dan amixer mereka; ia\n"
+"sangat berguna, selain itu alsa-lib docs, untuk ketahui\n"
+"lebih lanjut mengenai API ALSA\n"
+"\n"
+"Alfredo Spadafina\n"
+"atas logo papan kekunci midi yang cantik\n"
+"\n"
+"Tony Vroon\n"
+"atas bantuan pengujian alfa yang diberi"
+
+#: src/amidi-plug/i_configure.cc:94
+msgid "Override default gain:"
+msgstr "Batalkan gandaan lalai:"
+
+#: src/amidi-plug/i_configure.cc:102
+msgid "Override default polyphony:"
+msgstr "Batalkan polifoni lalai:"
+
+#: src/amidi-plug/i_configure.cc:110
+msgid "Override default reverb:"
+msgstr "Batalkan reverb lalai:"
+
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
+msgid "On"
+msgstr "Hidup"
+
+#: src/amidi-plug/i_configure.cc:118
+msgid "Override default chorus:"
+msgstr "Batalkan korus lalai:"
+
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
+msgid "<b>Playback</b>"
+msgstr "<b>Main Balik</b>"
+
+#: src/amidi-plug/i_configure.cc:129
+msgid "Transpose:"
+msgstr "Transsposisi:"
+
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "seminada"
+
+#: src/amidi-plug/i_configure.cc:132
+msgid "Drum shift:"
+msgstr "Anjak dram:"
+
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "nombor nota"
+
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Langkau senyap hadapan"
+
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Langkau senyap belakang"
+
+#: src/amidi-plug/i_configure.cc:141
+msgid "<b>SoundFont</b>"
+msgstr "<b>SoundFont</b>"
+
+#: src/amidi-plug/i_configure.cc:143
+msgid "<b>Synthesizer</b>"
+msgstr "<b>Pensintesis</b>"
+
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "Kadar sampel:"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
+msgid "AMIDI-Plug - select SoundFont file"
+msgstr "AMIDI-Plug - pilih fail SoundFont"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Batal"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
+msgid "_Open"
+msgstr "_Buka"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "Nama fail"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
+msgid "Size (bytes)"
+msgstr "Saiz (bait)"
+
+#: src/amidi-plug/i_fileinfo.cc:163
+msgid "Name:"
+msgstr "Nama:"
+
+#: src/amidi-plug/i_fileinfo.cc:181
+msgid "<span size=\"smaller\"> MIDI Info </span>"
+msgstr "<span size=\"smaller\"> Maklumat MIDI </span>"
+
+#: src/amidi-plug/i_fileinfo.cc:195
+msgid "Format:"
+msgstr "Format:"
+
+#: src/amidi-plug/i_fileinfo.cc:198
+msgid "Length (msec):"
+msgstr "Panjang (msaat):"
+
+#: src/amidi-plug/i_fileinfo.cc:201
+msgid "No. of Tracks:"
+msgstr "Nombor Trek:"
+
+#: src/amidi-plug/i_fileinfo.cc:207
+msgid "variable"
+msgstr "pembolehubah"
+
+#: src/amidi-plug/i_fileinfo.cc:209
+msgid "BPM:"
+msgstr "BPM:"
+
+#: src/amidi-plug/i_fileinfo.cc:217
+msgid "BPM (wavg):"
+msgstr "BPM (wavg):"
+
+#: src/amidi-plug/i_fileinfo.cc:220
+msgid "Time Div:"
+msgstr "Masa Div:"
+
+#: src/amidi-plug/i_fileinfo.cc:231
+msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
+msgstr "<span size=\"smaller\"> Ulasan dan Lirik MIDI </span>"
+
+#: src/amidi-plug/i_fileinfo.cc:278
+msgid "* no comments available in this MIDI file *"
+msgstr "* tiada ulasan tersedi dalam fail MIDI ini *"
+
+#: src/amidi-plug/i_fileinfo.cc:290
+msgid "* no lyrics available in this MIDI file *"
+msgstr "* tiada lirik didapati dalam fail MIDI ini *"
+
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
+msgid "_Close"
+msgstr "T_utup"
+
+#: src/amidi-plug/i_fileinfo.cc:325
+msgid " (invalid UTF-8)"
+msgstr "(UTF-8 tidak sah)"
+
+#: src/aosd/aosd.cc:32
+msgid ""
+"Audacious OSD\n"
+"http://www.develia.org/projects.php?p=audacious#aosd\n"
+"\n"
+"Written by Giacomo Lozito <james at develia.org>\n"
+"\n"
+"Based in part on Evan Martin's Ghosd library:\n"
+"http://neugierig.org/software/ghosd/"
+msgstr ""
+"Audacious OSD\n"
+"http://www.develia.org/projects.php?p=audacious#aosd\n"
+"\n"
+"Ditulis oleh Giacomo Lozito <james at develia.org>\n"
+"\n"
+"Berdasarkan bahagian dalam pustaka Ghosd Evan Martin:\n"
+"http://neugierig.org/software/ghosd/"
+
+#: src/aosd/aosd.h:37
+msgid "AOSD (On-Screen Display)"
+msgstr "AOSD (Paparan Atas-Skrin)"
+
+#: src/aosd/aosd_style.cc:54
+msgid "Rectangle"
+msgstr "Segiempat Tepat"
+
+#: src/aosd/aosd_style.cc:59
+msgid "Rounded Rectangle"
+msgstr "Bulatan Segiempat Tepat"
+
+#: src/aosd/aosd_style.cc:64
+msgid "Concave Rectangle"
+msgstr "Cekung Segiempat Tepat"
+
+#: src/aosd/aosd_style.cc:69
+msgid "None"
+msgstr "Tiada"
+
+#: src/aosd/aosd_trigger.cc:50
+msgid "Playback Start"
+msgstr "Mulakan Main Semula"
+
+#: src/aosd/aosd_trigger.cc:51
+msgid "Triggers OSD when a playlist entry is played."
+msgstr "Mencetus OSD apabila kemasukan senarai main dimainkan."
+
+#: src/aosd/aosd_trigger.cc:56
+msgid "Title Change"
+msgstr "Tukar Tajuk"
+
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
+msgstr "Memicu OSD bila tajuk lagu berubah (untuk strim internet)."
+
+#: src/aosd/aosd_trigger.cc:62
+msgid "Pause On"
+msgstr "Aktifkan Jeda"
+
+#: src/aosd/aosd_trigger.cc:63
+msgid "Triggers OSD when playback is paused."
+msgstr "Mencetus OSD apabila main dijeda."
+
+#: src/aosd/aosd_trigger.cc:68
+msgid "Pause Off"
+msgstr "Matikan Jeda"
+
+#: src/aosd/aosd_trigger.cc:69
+msgid "Triggers OSD when playback is unpaused."
+msgstr "Mencetus OSD apabila main tidak dijeda"
+
+#: src/aosd/aosd_ui.cc:163
+msgid "Placement"
+msgstr "Penempatan"
+
+#: src/aosd/aosd_ui.cc:196
+msgid "Relative X offset:"
+msgstr "X relatif diimbangi:"
+
+#: src/aosd/aosd_ui.cc:203
+msgid "Relative Y offset:"
+msgstr "Y relatif diimbangi:"
+
+#: src/aosd/aosd_ui.cc:210
+msgid "Max OSD width:"
+msgstr "Max lebar OSD:"
+
+#: src/aosd/aosd_ui.cc:221
+msgid "Multi-Monitor options"
+msgstr "pilihan Pelbagai-Monitor"
+
+#: src/aosd/aosd_ui.cc:225
+msgid "Display OSD using:"
+msgstr "Paparkan OSD digunakan:"
+
+#: src/aosd/aosd_ui.cc:227
+msgid "all monitors"
+msgstr "semua monitor"
+
+#: src/aosd/aosd_ui.cc:230
+#, c-format
+msgid "monitor %i"
+msgstr "monitor %i"
+
+#: src/aosd/aosd_ui.cc:282
+msgid "Timing (ms)"
+msgstr "Masa (ms)"
+
+#: src/aosd/aosd_ui.cc:287
+msgid "Display:"
+msgstr "Paparan:"
+
+#: src/aosd/aosd_ui.cc:292
+msgid "Fade in:"
+msgstr "Pudar dalam:"
+
+#: src/aosd/aosd_ui.cc:297
+msgid "Fade out:"
+msgstr "Pudar luar:"
+
+#: src/aosd/aosd_ui.cc:361
+msgid "Fonts"
+msgstr "Font"
+
+#: src/aosd/aosd_ui.cc:368
+#, c-format
+msgid "Font %i:"
+msgstr "Font %i:"
+
+#: src/aosd/aosd_ui.cc:382
+msgid "Shadow"
+msgstr "Bayang"
+
+#: src/aosd/aosd_ui.cc:486
+msgid "Render Style"
+msgstr "Realisasi Gaya"
+
+#: src/aosd/aosd_ui.cc:502
+msgid "Colors"
+msgstr "Warna"
+
+#: src/aosd/aosd_ui.cc:513
+#, c-format
+msgid "Color %i:"
+msgstr "Warna %i:"
+
+#: src/aosd/aosd_ui.cc:600
+msgid "Enable trigger"
+msgstr "Aktifkan pencetus"
+
+#: src/aosd/aosd_ui.cc:627
+msgid "Event"
+msgstr "Acara"
+
+#: src/aosd/aosd_ui.cc:655
+msgid "Composite manager detected"
+msgstr "Pengurus komposit dikesan"
+
+#: src/aosd/aosd_ui.cc:662
+msgid ""
+"Composite manager not detected;\n"
+"unless you know that you have one running, please activate a composite "
+"manager otherwise the OSD won't work properly"
+msgstr ""
+"Pengurus komposit tidak dikesan\n"
+"melainkan anda tahu bahawa anda mempunyai satu berjalan, sila mengaktifkan "
+"pengurus komposit sebaliknya OSD tidak akan berfungsi dengan betul"
+
+#: src/aosd/aosd_ui.cc:670
+msgid "Composite manager not required for fake transparency"
+msgstr "Komposit pengurus tidak diperlukan untuk ketelusan palsu"
+
+#: src/aosd/aosd_ui.cc:706
+msgid "Transparency"
+msgstr "Ketelusan"
+
+#: src/aosd/aosd_ui.cc:712
+msgid "Fake transparency"
+msgstr "Ketelusan palsu"
+
+#: src/aosd/aosd_ui.cc:714
+msgid "Real transparency (requires X Composite Ext.)"
+msgstr "Ketelusan sebenar (minta X Composite Ext.)"
+
+#: src/aosd/aosd_ui.cc:756
+msgid "Composite extension not loaded"
+msgstr "Lanjutan komposit tidak dimuatkan"
+
+#: src/aosd/aosd_ui.cc:764
+msgid "Composite extension not available"
+msgstr "Sambungan komposit tidak tersedia"
+
+#: src/aosd/aosd_ui.cc:781
+#, c-format
+msgid "<span font_desc='%s'>Audacious OSD</span>"
+msgstr "<span font_desc='%s'>Audacious OSD</span>"
+
+#: src/aosd/aosd_ui.cc:844
+msgid "Position"
+msgstr "Kedudukan"
+
+#: src/aosd/aosd_ui.cc:849
+msgid "Animation"
+msgstr "Animasi"
+
+#: src/aosd/aosd_ui.cc:854
+msgid "Text"
+msgstr "Teks"
+
+#: src/aosd/aosd_ui.cc:859
+msgid "Decoration"
+msgstr "Hiasan"
+
+#: src/aosd/aosd_ui.cc:864
+msgid "Trigger"
+msgstr "Pemicu"
+
+#: src/aosd/aosd_ui.cc:869
+msgid "Misc"
+msgstr "Pelbagai"
+
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Uji"
+
+#: src/asx3/asx3.cc:35
+msgid "ASXv3 Playlists"
+msgstr "Senarai Main ASXv3"
+
+#: src/asx/asx.cc:33
+msgid "ASXv1/ASXv2 Playlists"
+msgstr "Senarai Main ASXv1/ASXv2"
+
+#: src/audpl/audpl.cc:33
+msgid "Audacious Playlists (audpl)"
+msgstr "Senarai Main Audacious (audpl)"
+
+#: src/blur_scope/blur_scope.cc:42
+msgid "<b>Color</b>"
+msgstr "<b>Warna</b>"
+
+#: src/blur_scope/blur_scope.cc:58
+msgid "Blur Scope"
+msgstr "Skop Kabur"
+
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Praset:"
+
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
+msgstr "Aras suapan:"
+
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr "Frekuensi kerat:"
+
+#: src/cairo-spectrum/cairo-spectrum.cc:41
+msgid "Spectrum Analyzer"
+msgstr "Penganalisis Spektrum"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Pemalam CD Audio"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
+msgid ""
+"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
+"\n"
+"Many thanks to libcdio developers <http://www.gnu.org/software/libcdio/>\n"
+"and to libcddb developers <http://libcddb.sourceforge.net/>.\n"
+"\n"
+"Also thank you to Tony Vroon for mentoring and guiding me.\n"
+"\n"
+"This was a Google Summer of Code 2007 project."
+msgstr ""
+"Hakcipta (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> dan lain-lain.\n"
+"\n"
+"Terima kasih buat pembangun libcdio <http://www.gnu.org/software/libcdio/>\n"
+"dan pembangun libcddb <http://libcddb.sourceforge.net/>.\n"
+"\n"
+"Dan juga terima kasih kepada Tony Vroon atas pementoran dan panduan.\n"
+"\n"
+"Ini merupakan projek Google Summer of Code 2007."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:137
+msgid "<b>Device</b>"
+msgstr "<b>Peranti</b>"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:138
+msgid "Read speed:"
+msgstr "Kelajuan baca:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:141
+msgid "Override device:"
+msgstr "Batalkan peranti:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:143
+msgid "<b>Metadata</b>"
+msgstr "<b>Data meta</b>"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:144
+msgid "Use CD-Text"
+msgstr "Guna Teks-CD"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:146
+msgid "Use CDDB"
+msgstr "Guna CDDB"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:148
+msgid "Use HTTP instead of CDDBP"
+msgstr "Guna HTTP selain dari CDDBP"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:151
+msgid "Server:"
+msgstr "Pelayan:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:155
+msgid "Path:"
+msgstr "Laluan:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:159
+msgid "Port:"
+msgstr "Port:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:246
+msgid "Failed to initialize cdio subsystem."
+msgstr "Gagal mengawalkan subsistem cdio."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:281
+#, c-format
+msgid "Invalid URI %s."
+msgstr "URI %s tidak sah."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:283
+#, c-format
+msgid "Track %d not found."
+msgstr "Trek %d tidak ditemui."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:285
+#, c-format
+msgid "Track %d is a data track."
+msgstr "Trek %d adalah trek data."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:360
+msgid "Error reading audio CD."
+msgstr "Ralat membaca CD audio."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:429
+msgid "Audio CD"
+msgstr "CD Audio"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
+#, c-format
+msgid "Failed to open CD device %s."
+msgstr "Gagal membuka peranti CD %s."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:472
+msgid "No audio capable CD drive found."
+msgstr "Tiada pemacu CD upaya audio ditemui."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:497
+msgid "Failed to finish initializing opened CD drive."
+msgstr "Gagal menyelesaikan pengawalan pemacu CD dibuka."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:510
+msgid "Failed to retrieve first/last track number."
+msgstr "Gagal mendapatkan nombor trek pertama/terakhir."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:531
+#, c-format
+msgid "Cannot read start/end LSN for track %d."
+msgstr "Tidak dapat baca/tamatkan LSN untuk trek %d."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:613
+msgid "Failed to create the cddb connection."
+msgstr "Gagal mencipta sambungan cddb."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:679
+msgid "Failed to query the CDDB server"
+msgstr "Gagal menanya pelayan CDDB"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:681
+#, c-format
+msgid "Failed to query the CDDB server: %s"
+msgstr "Gagal menanya pelayan CDDB: %s"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:705
+#, c-format
+msgid "Failed to read the cddb info: %s"
+msgstr "Gagal membaca maklumat cddb: %s"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:765
+msgid "Drive is empty."
+msgstr "Pemacu kosong."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:767
+msgid "Unsupported disk type."
+msgstr "Jenis cakera tidak disokong."
+
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Item Menu CD Audio"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
+msgid "Play CD"
+msgstr "Main CD"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
+msgid "Add CD"
+msgstr "Tambah CD"
+
+#: src/compressor/compressor.cc:45
+msgid "<b>Compression</b>"
+msgstr "<b>Pemampatan</b>"
+
+#: src/compressor/compressor.cc:46
+msgid "Center volume:"
+msgstr "Volum tengah:"
+
+#: src/compressor/compressor.cc:49
+msgid "Dynamic range:"
+msgstr "Julat dinamik:"
+
+#: src/compressor/compressor.cc:57
+msgid ""
+"Dynamic Range Compression Plugin for Audacious\n"
+"Copyright 2010-2014 John Lindgren"
+msgstr ""
+"Pemalam Pemampatan Julat dinamik untuk Audacious\n"
+"Hakcipta 2010-2014 John Lindgren"
+
+#: src/compressor/compressor.cc:64
+msgid "Dynamic Range Compressor"
+msgstr "Pemampat Jula Dinamik"
+
+#: src/console/plugin.cc:15
+msgid ""
+"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
+"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
+"\n"
+"Audacious plugin by:\n"
+"William Pitcock <nenolod at dereferenced.org>\n"
+"Shay Green <gblargg at gmail.com>"
+msgstr ""
+"Enjin penyahkod muzik konsol berasaskan pada Game_Music_Emu 0.5.2\n"
+"Format disokong: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
+"\n"
+"Pemalam Audacious oleh:\n"
+"William Pitcock <nenolod at dereferenced.org>\n"
+"Shay Green <gblargg at gmail.com>"
+
+#: src/console/plugin.cc:30
+msgid "Bass:"
+msgstr "Bes:"
+
+#: src/console/plugin.cc:33
+msgid "Treble:"
+msgstr "Trebel:"
+
+#: src/console/plugin.cc:36
+msgid "Echo:"
+msgstr "Gema:"
+
+#: src/console/plugin.cc:39
+msgid "Default song length:"
+msgstr "Panjang lagu lalai:"
+
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
+msgid "<b>Resampling</b>"
+msgstr "<b>Persampelan Semula</b>"
+
+#: src/console/plugin.cc:43
+msgid "Enable audio resampling"
+msgstr "Benarkan persampelan semula audio"
+
+#: src/console/plugin.cc:49
+msgid "<b>SPC</b>"
+msgstr "<b>SPC</b>"
+
+#: src/console/plugin.cc:50
+msgid "Ignore length from SPC tags"
+msgstr "Abai panjang dari tag SPC"
+
+#: src/console/plugin.cc:52
+msgid "Increase reverb"
+msgstr "Tingkatkan reverb"
+
+#: src/console/plugin.h:26
+msgid "Game Console Music Decoder"
+msgstr "Penyahkod Muzik Konsol Permainan"
+
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "Output CoreAudio"
+
+#: src/coreaudio/coreaudio.cc:131
+msgid ""
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"Pemalam Output CoreAudio untuk Audacious\n"
+"Hakcipta 2014 William Pitcock\n"
+"\n"
+"Berdasarkan pada Pemalam Output SDL untukr Audacious\n"
+"Hakcipta 2010 John Lindgren"
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "Guna mod ekslusif"
+
+#: src/crossfade/crossfade.cc:44
+msgid ""
+"Crossfade Plugin for Audacious\n"
+"Copyright 2010-2014 John Lindgren"
+msgstr ""
+"Pemalam Resap Silang untuk Audacious\n"
+"Hakcipta 2010-2014 John Lindgren"
+
+#: src/crossfade/crossfade.cc:48
+msgid "<b>Crossfade</b>"
+msgstr "<b>Resap Silang</b>"
+
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "Bila automatik lagu berubah"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
+msgid "Overlap:"
+msgstr "Tindih:"
+
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "Bila jangkau atau ubah lagu secara manual"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Petua</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+"Untuk resap silang yang lebih baik,\n"
+"benarkan kesan Pembuangan Senyap."
+
+#: src/crossfade/crossfade.cc:72
+msgid "Crossfade"
+msgstr "Resap Silang"
+
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"Peresapan silang gagal kerana lagu mempunyai bilangan saluran berbeza. Anda "
+"boleh guna Pengadun Saluran untuk tukarkan lagu ke bilangan saluran yang "
+"sama."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"Peresapan silang gagal keran lagu mempunyai kadar sampel yang berlainan. "
+"Anda boleh guna Penukar Kadar Sampel untuk tukarkan lagu menjadi kadar "
+"sampel yang sama."
+
+#: src/crystalizer/crystalizer.cc:31
+msgid "<b>Crystalizer</b>"
+msgstr "<b>Crystalizer</b>"
+
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
+msgid "Intensity:"
+msgstr "Keamatan:"
+
+#: src/crystalizer/crystalizer.cc:43
+msgid "Crystalizer"
+msgstr "Crystalizer"
+
+#: src/cue/cue.cc:37
+msgid "Cue Sheet Plugin"
+msgstr "Pemalam Lembaran Isyarat"
+
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Padam Fail"
+
+#: src/delete-files/delete-files.cc:75
+#, c-format
+msgid "Error moving %s to trash: %s."
+msgstr "Ralat mengalih %s ke tong sampah: %s."
+
+#: src/delete-files/delete-files.cc:86
+#, c-format
+msgid "Error deleting %s: %s."
+msgstr "Ralat memadam %s: %s."
+
+#: src/delete-files/delete-files.cc:117
+#, c-format
+msgid "Error deleting %s: not a local file."
+msgstr "Ralat memadam %s: bukan fail setempat."
+
+#: src/delete-files/delete-files.cc:134
+msgid "Do you want to move the selected files to the trash?"
+msgstr "Anda mahu alih fail terpilih ke tong sampah?"
+
+#: src/delete-files/delete-files.cc:135
+msgid "Move to Trash"
+msgstr "Alih ke Tong Sampah"
+
+#: src/delete-files/delete-files.cc:140
+msgid "Do you want to permanently delete the selected files?"
+msgstr "Anda mahu padam fail terpilih secara kekal?"
+
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
+msgid "Delete"
+msgstr "Padam"
+
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
+msgid "Cancel"
+msgstr "Batal"
+
+#: src/delete-files/delete-files.cc:166
+msgid "Delete Selected Files"
+msgstr "Padam Fail Terpilih"
+
+#: src/delete-files/delete-files.cc:181
+msgid "<b>Delete Method</b>"
+msgstr "<b>Kaedah Padam</b>"
+
+#: src/delete-files/delete-files.cc:182
+msgid "Move to trash instead of deleting immediately"
+msgstr "Alih ke tong sampah selain dari memadam serta-merta"
+
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+"Pemalam Gema\n"
+"Oleh Johan Levin, 1999\n"
+"Gema keliling oleh Carl van Schaik, 1999\n"
+"Dikemaskini untuk Audacious oleh William Pitcock dan John Lindgren, 2010-2014"
+
+#: src/echo_plugin/echo.cc:21
+msgid "<b>Echo</b>"
+msgstr "<b>Gema</b>"
+
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
+msgid "Delay:"
+msgstr "Lengah:"
+
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
+msgid "ms"
+msgstr "ms"
+
+#: src/echo_plugin/echo.cc:25
+msgid "Feedback:"
+msgstr "Maklumbalas:"
+
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
+msgid "Volume:"
+msgstr "Volum:"
+
+#: src/echo_plugin/echo.cc:39
+msgid "Echo"
+msgstr "Gema"
+
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Pemalam FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
+msgid ""
+"Multi-format audio decoding plugin for Audacious using\n"
+"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
+"\n"
+"Audacious plugin by:\n"
+"William Pitcock <nenolod at nenolod.net>\n"
+"Matti Hämäläinen <ccr at tnsp.org>"
+msgstr ""
+"Pemalam penyahkodan audio format-berbilang menggunakan\n"
+"bingkai kerja multimedia FFmpeg (http://www.ffmpeg.org/)\n"
+"\n"
+"Pemalam Audacious oleh:\n"
+"William Pitcock <nenolod at nenolod.net>\n"
+"Matti Hämäläinen <ccr at tnsp.org>"
+
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Pemalam FileWriter"
+
+#: src/filewriter/filewriter.cc:386
+msgid "Output file format:"
+msgstr "Format fail output:"
+
+#: src/filewriter/filewriter.cc:403
+msgid "Configure"
+msgstr "Konfigur"
+
+#: src/filewriter/filewriter.cc:413
+msgid "Save into original directory"
+msgstr "Simpan ke dalam direktori asal"
+
+#: src/filewriter/filewriter.cc:417
+msgid "Save into custom directory"
+msgstr "Simpan ke dalam direktori suai"
+
+#: src/filewriter/filewriter.cc:427
+msgid "Output file folder:"
+msgstr "Folder fail output:"
+
+#: src/filewriter/filewriter.cc:431
+msgid "Pick a folder"
+msgstr "Ambil satu folder"
+
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Jana nama fail dari:"
+
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Tag fail asal"
+
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Nama fail asal"
+
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "Sertakan sambungan nama fail asal"
+
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr "Tambah nombor trek ke nama fail"
+
+#: src/filewriter/filewriter.cc:484
+msgid ""
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
+"USA."
+msgstr ""
+"Program adalah perisian bebas; anda boleh mengedarkannya dan/atau "
+"mengubahsuainya dibawah terma Pelesenan Awam Am GNU yang diterbitkan oleh "
+"Free Software Foundation; sama ada versi 2 dari lesen, atau (mengikut "
+"pilihan anda) mana-mana versi terkini.\n"
+"\n"
+"Program ini diedarkan dengan harapan ianya akan berguna, TANPA SEBARANG "
+"JAMINAN; termasuk juga KESESUAIAN UNTUK DIPASARKAN, JAMINAN KUALITI, atau "
+"JAMINAN ATAS APA JUA SEBAB. Sila lihat GNU General Public License untuk "
+"maklumat lanjut.\n"
+"\n"
+"Anda seharusnya menerima satu salinan Lesen Awam Am GNU bersama-sama dengan "
+"Gwibber; jika tidak, laporkannya ke Free Software Foundation, Inc., 51 "
+"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
+
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
+msgid "Auto"
+msgstr "Auto"
+
+#: src/filewriter/mp3.cc:40
+msgid "Joint Stereo"
+msgstr "Stereo Gabung"
+
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
+msgid "Stereo"
+msgstr "Stereo"
+
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
+msgid "Mono"
+msgstr "Mono"
+
+#: src/filewriter/mp3.cc:657
+msgid "MP3 Configuration"
+msgstr "Konfigurasi MP3"
+
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_OK"
+
+#: src/filewriter/mp3.cc:681
+msgid "Algorithm Quality:"
+msgstr "Kualiti Algoritma:"
+
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr "Kadar Sampel Output:"
+
+#: src/filewriter/mp3.cc:733
+msgid "(Hz)"
+msgstr "(Hz)"
+
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "Kadar Bit / Nisbah Pemampatan:"
+
+#: src/filewriter/mp3.cc:764
+msgid "Bitrate (kbps):"
+msgstr "Kadar bit (kbps):"
+
+#: src/filewriter/mp3.cc:796
+msgid "Compression ratio:"
+msgstr "Nisbah pemampatan:"
+
+#: src/filewriter/mp3.cc:820
+msgid "Audio Mode:"
+msgstr "Mod Audio:"
+
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr "Pelbagai:"
+
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr "Paksa turutan ISO ketat"
+
+#: src/filewriter/mp3.cc:867
+msgid "Error protection"
+msgstr "Pelindungan ralat"
+
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
+msgid "Quality"
+msgstr "Kualiti"
+
+#: src/filewriter/mp3.cc:888
+msgid "Enable VBR/ABR"
+msgstr "Benarkan VBR/ABR"
+
+#: src/filewriter/mp3.cc:898
+msgid "Type:"
+msgstr "Jenis:"
+
+#: src/filewriter/mp3.cc:931
+msgid "VBR Options:"
+msgstr "Pilihan VBR:"
+
+#: src/filewriter/mp3.cc:947
+msgid "Minimum bitrate (kbps):"
+msgstr "Kadar bit minimum (kbps):"
+
+#: src/filewriter/mp3.cc:973
+msgid "Maximum bitrate (kbps):"
+msgstr "Kadar bit maksimum (kbps):"
+
+#: src/filewriter/mp3.cc:995
+msgid "Strictly enforce minimum bitrate"
+msgstr "Paksa kadar bit minimum betul-betul"
+
+#: src/filewriter/mp3.cc:1007
+msgid "ABR Options:"
+msgstr "Pilihan ABR:"
+
+#: src/filewriter/mp3.cc:1017
+msgid "Average bitrate (kbps):"
+msgstr "Kadar bit purata (kbps):"
+
+#: src/filewriter/mp3.cc:1044
+msgid "VBR quality level:"
+msgstr "Aras kualiti VBR:"
+
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Buang pengepala VBR Xing"
+
+#: src/filewriter/mp3.cc:1076
+msgid "VBR/ABR"
+msgstr "VBR/ABR"
+
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr "Parameter Bingkai:"
+
+#: src/filewriter/mp3.cc:1097
+msgid "Mark as copyright"
+msgstr "Tanda sebagai hakcipta"
+
+#: src/filewriter/mp3.cc:1108
+msgid "Mark as original"
+msgstr "Tanda sebagai asal"
+
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr "Parameter ID3:"
+
+#: src/filewriter/mp3.cc:1131
+msgid "Force addition of version 2 tag"
+msgstr "Paksa penambahan tag versi 2"
+
+#: src/filewriter/mp3.cc:1141
+msgid "Only add v1 tag"
+msgstr "Hanya tambah tag v1"
+
+#: src/filewriter/mp3.cc:1148
+msgid "Only add v2 tag"
+msgstr "Hanya tambah tag v2"
+
+#: src/filewriter/mp3.cc:1169
+msgid "Tags"
+msgstr "Tag"
+
+#: src/filewriter/vorbis.cc:196
+msgid "Vorbis Encoder Configuration"
+msgstr "Konfigurasi Pengekod Vorbis"
+
+#: src/filewriter/vorbis.cc:219
+msgid "Quality level (0 - 10):"
+msgstr "Aras kualiti (0 - 10):"
+
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "Penyahkod FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
+msgid "lossless"
+msgstr "tak hilang"
+
+#: src/flacng/plugin.cc:169
+msgid ""
+"Original code by\n"
+"Ralf Ertzinger <ralf at skytale.net>\n"
+"\n"
+"http://www.skytale.net/projects/bmp-flac2/"
+msgstr ""
+"Kod asal oleh\n"
+"Ralf Ertzinger <ralf at skytale.net>\n"
+"\n"
+"http://www.skytale.net/projects/bmp-flac2/"
+
+#: src/gio/gio.cc:34
+msgid ""
+"GIO Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren"
+msgstr ""
+"Pemalam GIO untuk Audacious\n"
+"Hakcipta 2009-2012 John Lindgren"
+
+#: src/gio/gio.cc:42
+msgid "GIO Plugin"
+msgstr "Pemalam GIO"
+
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "Mod baca-dan-tambah tidak disokong"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "Mod buka tidak sah"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+"Penganalisis Spektrum OpenGL untuk Audacious\n"
+"Hakcipta 2013 Christophe Budé, John Lindgren, dan Carlo Bramini\n"
+"\n"
+"Berdasarkan pada pemalam XMMS:\n"
+"Hakcipta 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, dan "
+"4Front Technologies\n"
+"\n"
+"Lesen: GPLv2+"
+
+#: src/gl-spectrum/gl-spectrum.cc:62
+msgid "OpenGL Spectrum Analyzer"
+msgstr "Penganalisis Spektrum OpenGL"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+"Penganalisis Spektrum OpenGL untuk Audacious\n"
+"Hakcipta 2013 Christophe Budé, John Lindgren, dan Carlo Bramini\n"
+"Hakcipta 2014 William Pitcock\n"
+"\n"
+"Berdasarkan pada pemalam XMMS:\n"
+"Hakcipta 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, dan "
+"4Front Technologies\n"
+"\n"
+"Lesen: GPLv2+"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "Penganalisis Spektrum OpenGL (Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "Pintasan GNOME"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+"Pemalam Pintasan GNOME\n"
+"Membolehkan anda kawal pemain dengan pintasan GNOME.\n"
+"\n"
+"Hakcipta (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+
+#: src/gtkui/columns.cc:35
+msgid "Entry number"
+msgstr "Nombor masukan"
+
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
+msgid "Title"
+msgstr "Tajuk"
+
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
+msgid "Artist"
+msgstr "Artis"
+
+#: src/gtkui/columns.cc:38
+msgid "Year"
+msgstr "Tahun"
+
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
+msgid "Album"
+msgstr "Album"
+
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Artis album"
+
+#: src/gtkui/columns.cc:41
+msgid "Track"
+msgstr "Trek"
+
+#: src/gtkui/columns.cc:42
+msgid "Genre"
+msgstr "Genre"
+
+#: src/gtkui/columns.cc:43
+msgid "Queue position"
+msgstr "Kedudukan baris gilir"
+
+#: src/gtkui/columns.cc:44
+msgid "Length"
+msgstr "Panjang"
+
+#: src/gtkui/columns.cc:45
+msgid "File path"
+msgstr "Laluan fail"
+
+#: src/gtkui/columns.cc:47
+msgid "Custom title"
+msgstr "Tajuk suai"
+
+#: src/gtkui/columns.cc:48
+msgid "Bitrate"
+msgstr "Kadar bit"
+
+#: src/gtkui/columns.cc:308
+msgid "Available columns"
+msgstr "Lajur tersedia"
+
+#: src/gtkui/columns.cc:334
+msgid "Displayed columns"
+msgstr "Lajur dipapar"
+
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Alat Gelintar"
+
+#: src/gtkui/layout.cc:167
+msgid "Dock at Left"
+msgstr "Labuh di Kiri"
+
+#: src/gtkui/layout.cc:167
+msgid "Dock at Right"
+msgstr "Labuh di Kanan"
+
+#: src/gtkui/layout.cc:168
+msgid "Dock at Top"
+msgstr "Labuh di Atas"
+
+#: src/gtkui/layout.cc:168
+msgid "Dock at Bottom"
+msgstr "Labuh di Bawah"
+
+#: src/gtkui/layout.cc:168
+msgid "Undock"
+msgstr "Tanggalkan"
+
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
+msgid "Disable"
+msgstr "Lumpuhkan"
+
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
+msgid "_Open Files ..."
+msgstr "_Buka Fail ..."
+
+#: src/gtkui/menus.cc:127
+msgid "Open _URL ..."
+msgstr "Buka _URL ..."
+
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
+msgid "_Add Files ..."
+msgstr "T_ambah Fail ..."
+
+#: src/gtkui/menus.cc:129
+msgid "Add U_RL ..."
+msgstr "Tambah U_RL ..."
+
+#: src/gtkui/menus.cc:131
+msgid "Search _Library"
+msgstr "Gelintar _Pustaka"
+
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
+msgid "A_bout ..."
+msgstr "Per_ihal ..."
+
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
+msgid "_Settings ..."
+msgstr "T_etapan ..."
+
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
+msgid "_Quit"
+msgstr "_Keluar"
+
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
+msgid "_Play"
+msgstr "_Main"
+
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
+msgid "Paus_e"
+msgstr "_Jeda"
+
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
+msgid "_Stop"
+msgstr "_Henti"
+
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
+msgid "Pre_vious"
+msgstr "Ter_dahulu"
+
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
+msgid "_Next"
+msgstr "Ber_ikutnya"
+
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
+msgid "_Repeat"
+msgstr "_Ulang"
+
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
+msgid "S_huffle"
+msgstr "K_ocok"
+
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
+msgid "N_o Playlist Advance"
+msgstr "T_iada Senarai Main Pendahuluan"
+
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
+msgid "Stop A_fter This Song"
+msgstr "Henti Se_lepas Lagu Ini"
+
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
+msgid "Song _Info ..."
+msgstr "Mak_lumat Lagu ..."
+
+#: src/gtkui/menus.cc:151
+msgid "Jump to _Time ..."
+msgstr "Lompat ke Ma_sa ..."
+
+#: src/gtkui/menus.cc:152
+msgid "_Jump to Song ..."
+msgstr "L_ompat ke Lagu ..."
+
+#: src/gtkui/menus.cc:154
+msgid "Set Repeat Point _A"
+msgstr "Tetapkan Titik Ulang _A"
+
+#: src/gtkui/menus.cc:155
+msgid "Set Repeat Point _B"
+msgstr "Tetapkan Titik Ulang _B"
+
+#: src/gtkui/menus.cc:156
+msgid "_Clear Repeat Points"
+msgstr "_Kosongkan Titik Ulang"
+
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
+msgid "By _Title"
+msgstr "Mengikut _Tajuk"
+
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "Mengikut Nama _Fail"
+
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
+msgid "By File _Path"
+msgstr "Mengikut _Laluan Fail"
+
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
+msgid "By Track _Number"
+msgstr "Mengikut _Nombor Trek"
+
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
+msgid "By _Artist"
+msgstr "Mengikut _Artis"
+
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
+msgid "By Al_bum"
+msgstr "Mengikut Al_bum"
+
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Mengikut Albu_m Artis"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
+msgid "By Release _Date"
+msgstr "Mengikut Tarik_h Keluaran"
+
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "Mengikut _Genre"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
+msgid "By _Length"
+msgstr "Mengikut Pan_jang"
+
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
+msgid "By _File Path"
+msgstr "Mengikut Laluan _Fail"
+
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
+msgid "By _Custom Title"
+msgstr "Mengikut Tajuk _Suai"
+
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
+msgid "R_everse Order"
+msgstr "Tertib S_ongsang"
+
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
+msgid "_Random Order"
+msgstr "Tertib _Rawak"
+
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_Main/Sambung Semula"
+
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
+msgid "_Refresh"
+msgstr "Se_gar Semula"
+
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
+msgid "_Sort"
+msgstr "_Isih"
+
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
+msgid "Sort Se_lected"
+msgstr "Isih T_erpilih"
+
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
+msgid "Remove _Duplicates"
+msgstr "Buang Pen_dua"
+
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
+msgid "Remove _Unavailable Files"
+msgstr "Buang Fail Yang _Tiada"
+
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
+msgid "_New"
+msgstr "_Baharu"
+
+#: src/gtkui/menus.cc:207
+msgid "Ren_ame ..."
+msgstr "N_ama Semula ..."
+
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
+msgid "Remo_ve"
+msgstr "B_uang"
+
+#: src/gtkui/menus.cc:210
+msgid "_Import ..."
+msgstr "_Import ..."
+
+#: src/gtkui/menus.cc:211
+msgid "_Export ..."
+msgstr "_Eksport ..."
+
+#: src/gtkui/menus.cc:213
+msgid "Playlist _Manager ..."
+msgstr "Pen_gurus Senarai Main ..."
+
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
+msgid "_Queue Manager ..."
+msgstr "Pengurus Baris _Gilir ..."
+
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
+msgid "Volume _Up"
+msgstr "Volum _Naik"
+
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
+msgid "Volume _Down"
+msgstr "Volum _Turun"
+
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
+msgid "_Equalizer"
+msgstr "Pen_yama"
+
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
+msgid "E_ffects ..."
+msgstr "K_esan ..."
+
+#: src/gtkui/menus.cc:227
+msgid "Show _Menu Bar"
+msgstr "Tunjuk Palang _Menu"
+
+#: src/gtkui/menus.cc:228
+msgid "Show I_nfo Bar"
+msgstr "Tunjuk Palang Ma_klumat"
+
+#: src/gtkui/menus.cc:229
+msgid "Show Info Bar Vis_ualization"
+msgstr "Tunjuk Peng_visualan Palang Maklumat"
+
+#: src/gtkui/menus.cc:230
+msgid "Show _Status Bar"
+msgstr "Tunjuk Palang _Status"
+
+#: src/gtkui/menus.cc:232
+msgid "Show _Remaining Time"
+msgstr "Tunjuk Masa _Berbaki"
+
+#: src/gtkui/menus.cc:234
+msgid "_Visualizations ..."
+msgstr "Pe_ngvisualan ..."
+
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
+msgid "_File"
+msgstr "_Fail"
+
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
+msgid "_Playback"
+msgstr "_Main Balik"
+
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
+msgid "P_laylist"
+msgstr "Se_narai Main"
+
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
+msgid "_Services"
+msgstr "Perk_hidmatan"
+
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
+msgid "_Output"
+msgstr "_Output"
+
+#: src/gtkui/menus.cc:243
+msgid "_View"
+msgstr "_Lihat"
+
+#: src/gtkui/menus.cc:248
+msgid "_Queue/Unqueue"
+msgstr "_Baris Gilir/Nyahbaris Gilir"
+
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "_Buka Folder Dikandungi"
+
+#: src/gtkui/menus.cc:253
+msgid "Cu_t"
+msgstr "Po_tong"
+
+#: src/gtkui/menus.cc:254
+msgid "_Copy"
+msgstr "Sa_lin"
+
+#: src/gtkui/menus.cc:255
+msgid "_Paste"
+msgstr "Tam_pal"
+
+#: src/gtkui/menus.cc:256
+msgid "Select _All"
+msgstr "Pilih Semu_a"
+
+#: src/gtkui/menus.cc:263
+msgid "_Rename ..."
+msgstr "_Nama Semula ..."
+
+#: src/gtkui/settings.cc:35
+msgid "<b>Playlist Tabs</b>"
+msgstr "<b>Tab Senarai Main</b>"
+
+#: src/gtkui/settings.cc:36
+msgid "Always show tabs"
+msgstr "Sentiasa tunjuk tab"
+
+#: src/gtkui/settings.cc:38
+msgid "Show entry counts"
+msgstr "Tunjuk kiraan masukan"
+
+#: src/gtkui/settings.cc:40
+msgid "Show close buttons"
+msgstr "Tunjuk butang tutup"
+
+#: src/gtkui/settings.cc:42
+msgid "<b>Playlist Columns</b>"
+msgstr "<b>Lajur Senarai Main</b>"
+
+#: src/gtkui/settings.cc:44
+msgid "Show column headers"
+msgstr "Tunjuk pengepala lajur"
+
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
+msgid "<b>Miscellaneous</b>"
+msgstr "<b>Pelbagai</b>"
+
+#: src/gtkui/settings.cc:47
+msgid "Arrow keys seek by:"
+msgstr "Kekunci anak panah jangkau:"
+
+#: src/gtkui/settings.cc:50
+msgid "Scroll on song change"
+msgstr "Tatal bila lagu berubah"
+
+#: src/gtkui/ui_gtk.cc:71
+msgid "GTK Interface"
+msgstr "Antaramuka GTK"
+
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
+#, c-format
+msgid "%s - Audacious"
+msgstr "%s - Audacious"
+
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
+msgid "Buffering ..."
+msgstr "Menimbal ..."
+
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
+msgid "Audacious"
+msgstr "Audacious"
+
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
+#, c-format
+msgid "%d channel"
+msgid_plural "%d channels"
+msgstr[0] "%d saluran"
+
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
+#, c-format
+msgid "%d kbps"
+msgstr "%d kbps"
+
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Mod tunggal."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Mod senarai main."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Dihentikan selepas lagu."
+
+#: src/hotkey/gui.cc:71
+msgid "Previous track"
+msgstr "Trek terdahulu"
+
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
+msgid "Play"
+msgstr "Main"
+
+#: src/hotkey/gui.cc:73
+msgid "Pause/Resume"
+msgstr "Jeda/Sambung Semula"
+
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
+msgid "Stop"
+msgstr "Henti"
+
+#: src/hotkey/gui.cc:75
+msgid "Next track"
+msgstr "Trek berikutnya"
+
+#: src/hotkey/gui.cc:76
+msgid "Forward 5 seconds"
+msgstr "Maju 5 saat"
+
+#: src/hotkey/gui.cc:77
+msgid "Rewind 5 seconds"
+msgstr "Undur 5 saat"
+
+#: src/hotkey/gui.cc:78
+msgid "Mute"
+msgstr "Senyap"
+
+#: src/hotkey/gui.cc:79
+msgid "Volume up"
+msgstr "Volum naik"
+
+#: src/hotkey/gui.cc:80
+msgid "Volume down"
+msgstr "Volum turun"
+
+#: src/hotkey/gui.cc:81
+msgid "Jump to file"
+msgstr "Lompat ke fail"
+
+#: src/hotkey/gui.cc:82
+msgid "Toggle player window(s)"
+msgstr "Togol tetingkap pemain"
+
+#: src/hotkey/gui.cc:83
+msgid "Show On-Screen-Display"
+msgstr "Tunjuk Paparan-Atas-Skrin"
+
+#: src/hotkey/gui.cc:84
+msgid "Toggle repeat"
+msgstr "Togol ulang"
+
+#: src/hotkey/gui.cc:85
+msgid "Toggle shuffle"
+msgstr "Togol kocok"
+
+#: src/hotkey/gui.cc:86
+msgid "Toggle stop after current"
+msgstr "Togol henti selepas semasa"
+
+#: src/hotkey/gui.cc:87
+msgid "Raise player window(s)"
+msgstr "Naik tetingkap pemain"
+
+#: src/hotkey/gui.cc:97
+msgid "(none)"
+msgstr "(tiada)"
+
+#: src/hotkey/gui.cc:234
+msgid ""
+"It is not recommended to bind the primary mouse buttons without "
+"modificators.\n"
+"\n"
+"Do you want to continue?"
+msgstr ""
+"Anda tidak disarankan mengikat butang tetikus utama dan pengubahsuai.\n"
+"\n"
+"Anda mahu teruskan?"
+
+#: src/hotkey/gui.cc:236
+msgid "Binding mouse buttons"
+msgstr "Pengikatan butang tetikus"
+
+#: src/hotkey/gui.cc:391
+msgid ""
+"Press a key combination inside a text field.\n"
+"You can also bind mouse buttons."
+msgstr ""
+"Tekan gabungan kekunci di dalam medan teks.\n"
+"Anda juga boleh mengikat butang tetikus."
+
+#: src/hotkey/gui.cc:396
+msgid "Hotkeys:"
+msgstr "Kekunci Panas:"
+
+#: src/hotkey/gui.cc:413
+msgid "<b>Action:</b>"
+msgstr "<b>Tindakan:</b>"
+
+#: src/hotkey/gui.cc:420
+msgid "<b>Key Binding:</b>"
+msgstr "<b>Pengikatan Kekunci:</b>"
+
+#: src/hotkey/gui.cc:468
+msgid "_Add"
+msgstr "T_ambah"
+
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Kekunci Panas Sejagat"
+
+#: src/hotkey/plugin.cc:79
+msgid ""
+"Global Hotkey Plugin\n"
+"Control the player with global key combinations or multimedia keys.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>\n"
+"\n"
+"Contributers include:\n"
+"Copyright (C) 2006-2007 Vladimir Paskov <vlado.paskov at gmail.com>\n"
+"Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>,\n"
+" Bryn Davies <curious at ihug.com.au>,\n"
+" Jonathan A. Davis <davis at jdhouse.org>,\n"
+" Jeremy Tan <nsx at nsx.homeip.net>"
+msgstr ""
+"Pemalam Kekunci Panas Sejagat\n"
+"Kawal pemain dengan gabungan kekunci sejagat atau kekunci multimedia.\n"
+"\n"
+"Hakcopta (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>\n"
+"\n"
+"Penyumbang terlibat:\n"
+"Copyright (C) 2006-2007 Vladimir Paskov <vlado.paskov at gmail.com>\n"
+"Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>,\n"
+" Bryn Davies <curious at ihug.com.au>,\n"
+" Jonathan A. Davis <davis at jdhouse.org>,\n"
+" Jeremy Tan <nsx at nsx.homeip.net>"
+
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "Output JEK"
+
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "Sambung ke port output secara automatik"
+
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "Hanya %d port output JACK ditemui tetapi %d yang diperlukan."
+
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Gagal menyambung ke port JACK %s."
+
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+"JACK hanya menyokong audio titik-apung. Anda mesti ubah kedalaman bit output "
+"ke titik-apung di dalam tetapan Audacious."
+
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "Gagal bersambung dengan pelayan JACK; adakah ia berjalan?"
+
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
+msgid ""
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
+msgstr ""
+"Pelayan JACK memerlukan kadar sampel %d Hz, tetapi Audacious dimainkan pada "
+"%d Hz. Sila guna kesan Penukar Kadar Sampel untuk membetulkan ketidakpadanan "
+"ini."
+
+#: src/ladspa/plugin.cc:414
+#, c-format
+msgid "%s Settings"
+msgstr "Tetapan %s"
+
+#: src/ladspa/plugin.cc:478
+msgid "Module paths:"
+msgstr "Laluan Modul:"
+
+#: src/ladspa/plugin.cc:483
+msgid ""
+"<small>Separate multiple paths with a colon.\n"
+"These paths are searched in addition to LADSPA_PATH.\n"
+"After adding new paths, press Enter to scan for new plugins.</small>"
+msgstr ""
+"<small>Pisah laluan berbilang dengan tanda titk bertindih.\n"
+"Laluan ini digelintar sebagai tambahan ke LADSPA_PATH.\n"
+"Selepas menambah laluan baharu, tekan Enter untuk imbas pemalam baharu.</"
+"small>"
+
+#: src/ladspa/plugin.cc:499
+msgid "Available plugins:"
+msgstr "Pemalam tersedia:"
+
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
+msgid "Enable"
+msgstr "Benarkan"
+
+#: src/ladspa/plugin.cc:518
+msgid "Enabled plugins:"
+msgstr "Pemalam dibenarkan:"
+
+#: src/ladspa/plugin.cc:534
+msgid "Settings"
+msgstr "Tetapan"
+
+#: src/ladspa/plugin.cc:551
+msgid ""
+"LADSPA Host for Audacious\n"
+"Copyright 2011 John Lindgren"
+msgstr ""
+"Hos LADSPA untuk Audacious\n"
+"Hakcipta 2011 John Lindgren"
+
+#: src/ladspa/plugin.h:78
+msgid "LADSPA Host"
+msgstr "Hos LADSPA"
+
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Pemalam LIRC"
+
+#: src/lirc/lirc.cc:381
+msgid ""
+"A simple plugin to control Audacious using the LIRC remote control daemon\n"
+"\n"
+"Adapted for Audacious by:\n"
+"Tony Vroon <chainsaw at gentoo.org>\n"
+"Joonas Harjumäki <jharjuma at gmail.com>\n"
+"\n"
+"Based on the XMMS LIRC plugin by:\n"
+"Carl van Schaik <carl at leg.uct.ac.za>\n"
+"Christoph Bartelmus <xmms at bartelmus.de>\n"
+"Andrew O. Shadoura <bugzilla at tut.by>\n"
+"\n"
+"For more information about LIRC, see http://lirc.org."
+msgstr ""
+"Pemalam ringkas untuk mengawal Audacious menggunakan daemon kawalan jauh "
+"LIRC\n"
+"\n"
+"Diadaptasi untuk Audacious oleh:\n"
+"Tony Vroon <chainsaw at gentoo.org>\n"
+"Joonas Harjumäki <jharjuma at gmail.com>\n"
+"\n"
+"Berdasarkan pada pemalam LIRC XMMS oleh:\n"
+"Carl van Schaik <carl at leg.uct.ac.za>\n"
+"Christoph Bartelmus <xmms at bartelmus.de>\n"
+"Andrew O. Shadoura <bugzilla at tut.by>\n"
+"\n"
+"Untuk maklumat lanjut mengenai LIRC, sila rujuk http://lirc.org."
+
+#: src/lirc/lirc.cc:392
+msgid "<b>Connection</b>"
+msgstr "<b>Sambungan</b>"
+
+#: src/lirc/lirc.cc:393
+msgid "Reconnect to LIRC server"
+msgstr "Sambung semula ke pelayan LIRC"
+
+#: src/lirc/lirc.cc:395
+msgid "Wait before reconnecting:"
+msgstr "Tunggu sebelum disambung semula:"
+
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "Pemalam LyricWiki"
+
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
+msgid "No lyrics available"
+msgstr "Tiada lirik tersedia"
+
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Ralat"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
+#, c-format
+msgid "Unable to fetch %s"
+msgstr "Tidak boleh dapatkan %s"
+
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
+#, c-format
+msgid "Unable to parse %s"
+msgstr "Tidak boleh hurai %s"
+
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
+msgid "Looking for lyrics ..."
+msgstr "Mencari lirik ..."
+
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Missing song metadata"
+msgstr "Data meta lagu hilang"
+
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
+msgid "Connecting to lyrics.wikia.com ..."
+msgstr "Menyambung ke lyrics.wikia.com ..."
+
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "Pemalam LyricWiki (Qt)"
+
+#: src/m3u/m3u.cc:32
+msgid "M3U Playlists"
+msgstr "Senarai Main M3U"
+
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Penjana Rentak"
+
+#: src/metronom/metronom.cc:147
+#, c-format
+msgid "Tact generator: %d bpm"
+msgstr "Penjana rentak: %d bpm"
+
+#: src/metronom/metronom.cc:149
+#, c-format
+msgid "Tact generator: %d bpm %d/%d"
+msgstr "Penjana rentak: %d bpm %d/%d"
+
+#: src/metronom/metronom.cc:237
+msgid ""
+"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
+"\n"
+"To use it, add a URL: tact://beats*num/den\n"
+"e.g. tact://77 to play 77 beats per minute\n"
+"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
+msgstr ""
+"Penjana Rentak oleh Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
+"\n"
+"Untuk gunakanya, tambah URL: tact://beats*num/den\n"
+"cth. tact://77 untuk main 77 beat per minit\n"
+"atau tact://60*3/4 untuk main 60 bpm dalam tempo 3/4 rentak"
+
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Pengadun Saluran"
+
+#: src/mixer/mixer.cc:202
+msgid ""
+"Channel Mixer Plugin for Audacious\n"
+"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
+msgstr ""
+"Pemalam Pengadun Saluran untuk Audacious\n"
+"Hakcipta 2011-2012 John Lindgren dan MichaÅ Lipski"
+
+#: src/mixer/mixer.cc:206
+msgid "<b>Channel Mixer</b>"
+msgstr "<b>Pengadun Saluran</b>"
+
+#: src/mixer/mixer.cc:207
+msgid "Output channels:"
+msgstr "Saluran output:"
+
+#: src/mms/mms.cc:35
+msgid "MMS Plugin"
+msgstr "Pemalam MMS"
+
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "Ralat menyambung ke pelayan MMS"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Pemain Modul)"
+
+#: src/modplug/plugin_main.cc:53
+msgid "<b>Resolution</b>"
+msgstr "<b>Resolusi</b>"
+
+#: src/modplug/plugin_main.cc:54
+msgid "8-bit"
+msgstr "8-bit"
+
+#: src/modplug/plugin_main.cc:55
+msgid "16-bit"
+msgstr "16-bit"
+
+#: src/modplug/plugin_main.cc:56
+msgid "<b>Channels</b>"
+msgstr "<b>Saluran</b>"
+
+#: src/modplug/plugin_main.cc:60
+msgid "Nearest (fastest)"
+msgstr "Terdekat (terpantas)"
+
+#: src/modplug/plugin_main.cc:61
+msgid "Linear (fast)"
+msgstr "Linear (pantas)"
+
+#: src/modplug/plugin_main.cc:62
+msgid "Spline (good)"
+msgstr "Spline (baik)"
+
+#: src/modplug/plugin_main.cc:63
+msgid "Polyphase (best)"
+msgstr "Polifasa (terbaik)"
+
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr "<b>Kadar sampel</b>"
+
+#: src/modplug/plugin_main.cc:65
+msgid "22 kHz"
+msgstr "22 kHz"
+
+#: src/modplug/plugin_main.cc:66
+msgid "44 kHz"
+msgstr "44 kHz"
+
+#: src/modplug/plugin_main.cc:67
+msgid "48 kHz"
+msgstr "48 kHz"
+
+#: src/modplug/plugin_main.cc:68
+msgid "96 kHz"
+msgstr "96 kHz"
+
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
+msgid "Level:"
+msgstr "Aras:"
+
+#: src/modplug/plugin_main.cc:78
+msgid "Cutoff:"
+msgstr "Pangkas:"
+
+#: src/modplug/plugin_main.cc:91
+msgid "<b>Reverb</b>"
+msgstr "<b>Reverb</b>"
+
+#: src/modplug/plugin_main.cc:94
+msgid "<b>Bass Boost</b>"
+msgstr "<b>Galak Bes</b>"
+
+#: src/modplug/plugin_main.cc:97
+msgid "<b>Surround</b>"
+msgstr "<b>Keliling</b>"
+
+#: src/modplug/plugin_main.cc:100
+msgid "<b>Preamp</b>"
+msgstr "<b>Praamp</b>"
+
+#: src/modplug/plugin_main.cc:107
+msgid "Oversample"
+msgstr "Oversampel"
+
+#: src/modplug/plugin_main.cc:108
+msgid "Noise reduction"
+msgstr "Pengurangan hingar"
+
+#: src/modplug/plugin_main.cc:109
+msgid "Play Amiga MODs"
+msgstr "Main MOD Amiga"
+
+#: src/modplug/plugin_main.cc:110
+msgid "<b>Repeat</b>"
+msgstr "<b>Ulang</b>"
+
+#: src/modplug/plugin_main.cc:111
+msgid "Repeat count:"
+msgstr "Kiraan ulang:"
+
+#: src/modplug/plugin_main.cc:112
+msgid "To repeat forever, set the repeat count to -1."
+msgstr "Untuk ulang selamanya, tetapkan kiraan ulang menjadi -1."
+
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "Tetapan ini akan berkesan bila Audacious dimulakan semula."
+
+#: src/mpg123/mpg123.cc:54
+msgid "MPG123 Plugin"
+msgstr "Pemalam MPG123"
+
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Lanjutan</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Guna pengiraan lebih tepat (perlahan)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Keliling"
+
+#: src/mpris2/plugin.cc:39
+msgid "MPRIS 2 Server"
+msgstr "Pelayan MPRIS 2"
+
+#: src/neon/neon.cc:97
+msgid "Neon HTTP/HTTPS Plugin"
+msgstr "Pemalam Neon HTTP/HTTPS"
+
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "Ralat menghurai arah semula"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Ralat HTTP tidak diketahui"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "Ralat menghurai URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Terlalu banyak arah semula"
+
+#: src/notify/event.cc:64
+msgid "Stopped"
+msgstr "Dihentikan"
+
+#: src/notify/event.cc:64
+msgid "Audacious is not playing."
+msgstr "Audacioud tidak dimainkan."
+
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Pemberitahuan Desktop"
+
+#: src/notify/notify.cc:60
+msgid ""
+"Desktop Notifications Plugin for Audacious\n"
+"Copyright (C) 2010 Maximilian Bogner\n"
+"Copyright (C) 2011-2013 John Lindgren and Jean-Alexandre Anglès d'Auriac\n"
+"\n"
+"This plugin is free software: you can redistribute it and/or modify it under "
+"the terms of the GNU General Public License as published by the Free "
+"Software Foundation, either version 3 of the License, or (at your option) "
+"any later version.\n"
+"\n"
+"This plugin 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, see <http://www.gnu.org/licenses/>."
+msgstr ""
+"Pemalam Pemberitahuan Desktop untuk Audacious\n"
+"Hakcipta (C) 2010 Maximilian Bogner\n"
+"Hakcipta (C) 2011-2013 John Lindgren dan Jean-Alexandre Anglès d'Auriac\n"
+"\n"
+"Pemalam adalah perisian bebas; anda boleh mengedarkannya dan/atau "
+"mengubahsuainya dibawah terma Pelesenan Awam Am GNU yang diterbitkan oleh "
+"Free Software Foundation, sama ada versi 3 lesen, atau (mengikut pilihan "
+"anda) mana-mana versi terkini.\n"
+"\n"
+"Pemalam ini diedarkan dengan harapan ianya akan berguna, TANPA SEBARANG "
+"JAMINAN; termasuk juga KESESUAIAN UNTUK DIPASARKAN, JAMINAN KUALITI, atau "
+"JAMINAN ATAS APA JUA SEBAB. Sila lihat GNU General Public License untuk "
+"maklumat lanjut.\n"
+"\n"
+"Anda seharusnya menerima satu salinan Lesen Awam Am GNU bersama-sama dengan "
+"pengurus skrip Nautilus; jika tidak, rujuk <http://www.gnu.org/licenses/>."
+
+#: src/notify/notify.cc:110
+msgid "Show playback controls"
+msgstr "Tunjuk kawalan main balik"
+
+#: src/notify/notify.cc:112
+msgid "Always show notification"
+msgstr "Sentiasa tunjuk pemberitahuan"
+
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "Sertakan nama album dalam pemberitahuan"
+
+#: src/notify/osd.cc:58
+msgid "Show"
+msgstr "Tunjuk"
+
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
+msgid "Pause"
+msgstr "Jeda"
+
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
+msgid "Next"
+msgstr "Berikutnya"
+
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "Output OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "Output OSS3"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Peranti lalai"
+
+#: src/oss4/plugin.cc:77
+msgid "Audio device:"
+msgstr "Peranti audio:"
+
+#: src/oss4/plugin.cc:80
+msgid "Use alternate device:"
+msgstr "Guna peranti alternatif:"
+
+#: src/oss4/plugin.cc:84
+msgid "Save volume between sessions."
+msgstr "Simpan volum diantara sesi."
+
+#: src/oss4/plugin.cc:86
+msgid "Enable format conversions made by the OSS software."
+msgstr "Benarkan penukaran format yang dibuat oleh perisian OSS."
+
+#: src/oss4/plugin.cc:88
+msgid "Enable exclusive mode to prevent virtual mixing."
+msgstr "Benarkan mod ekslusif untuk menghindari pengadunan maya."
+
+#: src/oss4/plugin.cc:100
+msgid ""
+"OSS4 Output Plugin for Audacious\n"
+"Copyright 2010-2012 MichaÅ Lipski\n"
+"\n"
+"I would like to thank people on #audacious, especially Tony Vroon and John "
+"Lindgren and of course the authors of the previous OSS plugin."
+msgstr ""
+"Pemalam Output OSS4 untuk Audacious\n"
+"Hakcipta 2010-2012 MichaÅ Lipski\n"
+"\n"
+"Terima kasih buat individu di #audacious, terutamanya Tony Vroon dan John "
+"Lindgren serta bekas pengarang pemalam OSS."
+
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Pengurus Senarai Main"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Masukan"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Buang"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "N_ama Semula"
+
+#: src/pls/pls.cc:35
+msgid "PLS Playlists"
+msgstr "Senarai Main PLS"
+
+#: src/psf/plugin.cc:45
+msgid "OpenPSF PSF1/PSF2 Decoder"
+msgstr "Penyahkod OpenPSF PSF1/PSF2"
+
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "Output PulseAudio"
+
+#: src/pulse_audio/pulse_audio.cc:611
+msgid ""
+"Audacious PulseAudio Output Plugin\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
+"USA."
+msgstr ""
+"Pemalam Output Audacious PulseAudio\n"
+"\n"
+"Program ini adalah perisian bebas; anda boleh mengedarkannya dan/atau\n"
+"mengubahsuainya dibawah terma Pelesenan Awam Am GNU yang\n"
+"diterbitkan oleh Free Software Foundation; sama ada versi 2 dari lesen, \n"
+"atau (mengikut pilihan anda) mana-mana versi terkini\n"
+"\n"
+"Program ini diedarkan dengan harapan ianya akan berguna, TANPA \n"
+"SEBARANG JAMINAN; termasuk juga KESESUAIAN UNTUK DIPASARKAN,\n"
+"JAMINAN KUALITI, atau JAMINAN ATAS APA JUA SEBAB. Sila lihat GNU\n"
+"General Public License untuk maklumat lanjut.\n"
+"\n"
+"Anda seharusnya menerima satu salinan Lesen Awam Am GNU \n"
+"bersama-sama dengan Gwibber; jika tidak, laporkannya ke Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
+"USA."
+
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "Output QtMultimedia"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"Pemalam Output Audio QtMultimedia untuk Audacious\n"
+"Hakcipta 2014 William Pitcock\n"
+"\n"
+"Berdasarkan pada Pemalam Output SDL untuk Audacious\n"
+"Hakcipta 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Berfungsi ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Gelintar"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_Buka Folder ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_Tambah Folder ..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "Pemeriksa _Log ..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Buka Fail"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Tambah Fail"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Terdahulu"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Ulang"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Kocok"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Antaramuka Qt"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Penukar Kadar Sampel"
+
+#: src/resample/resample.cc:183
+msgid ""
+"Sample Rate Converter Plugin for Audacious\n"
+"Copyright 2010-2012 John Lindgren"
+msgstr ""
+"Pemalam Penukar Kadar Sampel untuk Audacious\n"
+"Hakcipta 2010-2012 John Lindgren"
+
+#: src/resample/resample.cc:187
+msgid "Skip/repeat samples"
+msgstr "Langkau/ulang sampel"
+
+#: src/resample/resample.cc:188
+msgid "Linear interpolation"
+msgstr "Interpolasi linear"
+
+#: src/resample/resample.cc:189
+msgid "Fast sinc interpolation"
+msgstr "Interpolasi sinc pantas"
+
+#: src/resample/resample.cc:190
+msgid "Medium sinc interpolation"
+msgstr "Interpolasi sinc sederhana"
+
+#: src/resample/resample.cc:191
+msgid "Best sinc interpolation"
+msgstr "Interpolasi sinc terbaik"
+
+#: src/resample/resample.cc:195
+msgid "<b>Conversion</b>"
+msgstr "<b>Penukaran</b>"
+
+#: src/resample/resample.cc:196
+msgid "Method:"
+msgstr "Kaedah:"
+
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
+msgid "Rate:"
+msgstr "Kadar:"
+
+#: src/resample/resample.cc:202
+msgid "<b>Rate Mappings</b>"
+msgstr "<b>Pemetaan Kadar</b>"
+
+#: src/resample/resample.cc:203
+msgid "Use rate mappings"
+msgstr "Guna pemetaan kadar"
+
+#: src/resample/resample.cc:205
+msgid "8 kHz:"
+msgstr "8 kHz:"
+
+#: src/resample/resample.cc:209
+msgid "16 kHz:"
+msgstr "16 kHz:"
+
+#: src/resample/resample.cc:213
+msgid "22.05 kHz:"
+msgstr "22.05 kHz:"
+
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
+msgid "44.1 kHz:"
+msgstr "44.1 kHz:"
+
+#: src/resample/resample.cc:225
+msgid "48 kHz:"
+msgstr "48 kHz:"
+
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
+msgid "96 kHz:"
+msgstr "96 kHz:"
+
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
+msgid "192 kHz:"
+msgstr "192 kHz:"
+
+#: src/scrobbler2/config_window.cc:41
+#, c-format
+msgid "OK. Scrobbling for user: %s"
+msgstr "OK. Scrobble untuk pengguna: %s"
+
+#: src/scrobbler2/config_window.cc:54
+msgid "Permission Denied"
+msgstr "Keizinan Dinafikan"
+
+#: src/scrobbler2/config_window.cc:56
+msgid "Access the following link to allow Audacious to scrobble your plays:"
+msgstr "Capai pautan berikut untuk membolehkan Audacious scrobble lagu anda:"
+
+#: src/scrobbler2/config_window.cc:66
+msgid "Keep this window open and click 'Check Permission' again.\n"
+msgstr "Kekalkan tetingkap ini dibuka dan klik 'Semak Keizinan' lagi.\n"
+
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
+msgid ""
+"Don't worry. Your scrobbles are saved on your computer.\n"
+"They will be submitted as soon as Audacious is allowed to do so."
+msgstr ""
+"Jangan risau. Scrobble anda disimpan dalam komputer anda.\n"
+"Ia akan diserah sebaik sahaja Audacious dibenarkan membuatnya."
+
+#: src/scrobbler2/config_window.cc:77
+msgid "Network Problem."
+msgstr "Masalah Rangkaian."
+
+#: src/scrobbler2/config_window.cc:78
+msgid "There was a problem contacting Last.fm. Please try again later."
+msgstr "Terdapat masalah menghubungi Last.fm. Sila cuba lagi kemudian."
+
+#: src/scrobbler2/config_window.cc:110
+msgid "Checking..."
+msgstr "Memeriksa..."
+
+#: src/scrobbler2/config_window.cc:176
+msgid "C_heck Permission"
+msgstr "S_emak Keizinan"
+
+#: src/scrobbler2/config_window.cc:177
+msgid "_Revoke Permission"
+msgstr "_Batalkan Keizinan"
+
+#: src/scrobbler2/config_window.cc:220
+msgid ""
+"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
+msgstr "Anda perlu benarkan Audacious scrobble trek ke akaun Last.fm anda.\n"
+
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
+msgid ""
+"The Scrobbler plugin could not be started.\n"
+"There might be a problem with your installation."
+msgstr ""
+"Pemalam Scrobbler tidak dapat dimulakan.\n"
+"Terdapat masalah dengan pemasangan anda."
+
+#: src/scrobbler2/scrobbler.cc:289
+msgid ""
+"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
+"\n"
+"Copyright © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com>\n"
+"\n"
+"Thanks to John Lindgren for giving me a hand at the beginning of this "
+"project.\n"
+"\n"
+msgstr ""
+"Pemalam Audacious Scrobbler 2.0 oleh Pitxyoki,\n"
+"\n"
+"hakcipta © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com>\n"
+"\n"
+"Terima kasih buat John Lindgren kerana membantu saya memulakan projek ini.\n"
+"\n"
+
+#: src/scrobbler2/scrobbler_communication.cc:642
+msgid ""
+"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
+"Please check the Preferences for the Scrobbler plugin."
+msgstr ""
+"Audacious kini menggunakan versi dipertingkat Scrobbler Last.fm.\n"
+"Sila semak Keutamaan untuk pemalam Scrobbler."
+
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "Output SDL"
+
+#: src/sdlout/sdlout.cc:77
+msgid ""
+"SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"Pemalam Output SDL untuk Audacious\n"
+"Hakcipta 2010 John Lindgren"
+
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
+msgid "Library"
+msgstr "Pustaka"
+
+#: src/search-tool/search-tool.cc:394
+#, c-format
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d keputusan"
+
+#: src/search-tool/search-tool.cc:400
+#, c-format
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d tersembunyi)"
+
+#: src/search-tool/search-tool.cc:594
+#, c-format
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d lagu"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "dari genre ini"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "hidup"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "oleh"
+
+#: src/search-tool/search-tool.cc:643
+msgid "_Create Playlist"
+msgstr "_Cipta Senarai Main"
+
+#: src/search-tool/search-tool.cc:645
+msgid "_Add to Playlist"
+msgstr "T_ambah ke Senarai Main"
+
+#: src/search-tool/search-tool.cc:684
+msgid "Search library"
+msgstr "Gelintar pustaka"
+
+#: src/search-tool/search-tool.cc:688
+msgid ""
+"To import your music library into Audacious, choose a folder and then click "
+"the \"refresh\" icon."
+msgstr ""
+"Untuk mengimport pustaka muzik anda ke dalam Audacious, pilih satu folder "
+"dan kemudian klik pada ikon \"segar semula\"."
+
+#: src/search-tool/search-tool.cc:696
+msgid "Please wait ..."
+msgstr "Tunggu sebentar ..."
+
+#: src/search-tool/search-tool.cc:723
+msgid "Choose Folder"
+msgstr "Pilih Folder"
+
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "Pemain SID"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>Output</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Saluran:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Emulasi</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "Emulasi MOS 8580 (lalai: MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "Jangan pilih model cip secara automatik"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Emulasi penapis"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Kelajuan jam:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "Jangan pilih kelajuan jam secara automatik"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>Masa main balik</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "Tetapkan masa main balik maksimum:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Hanya guna bila panjang lagu tidak diketahui"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "Tetapkan masa main balik minimum:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Subnada</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "Benarkan subnada"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "Abai subnada lebih pendek dari:"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Perhatian</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Pembuangan Senyap"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"Pemalam Pembuangan Senyap untuk Audacious\n"
+"Hakcipta 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Pembuangan Senyap</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Ambang:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
+msgid "Open Files ..."
+msgstr "Buka Fail ..."
+
+#: src/skins/menus.cc:65
+msgid "Open URL ..."
+msgstr "Buka URL ..."
+
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Gelintar Pustaka"
+
+#: src/skins/menus.cc:68
+msgid "Playback"
+msgstr "Main Balik"
+
+#: src/skins/menus.cc:69
+msgid "Playlist"
+msgstr "Senarai Main"
+
+#: src/skins/menus.cc:70
+msgid "View"
+msgstr "Lihat"
+
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
+msgid "Services"
+msgstr "Perkhidmatan"
+
+#: src/skins/menus.cc:74
+msgid "About ..."
+msgstr "Perihal ..."
+
+#: src/skins/menus.cc:75
+msgid "Settings ..."
+msgstr "Tetapan ..."
+
+#: src/skins/menus.cc:76
+msgid "Quit"
+msgstr "Keluar"
+
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
+msgid "Song Info ..."
+msgstr "Maklumat Lagu ..."
+
+#: src/skins/menus.cc:84
+msgid "No Playlist Advance"
+msgstr "Tiada Senarai Main Pendahuluan"
+
+#: src/skins/menus.cc:85
+msgid "Stop After This Song"
+msgstr "Henti Selepas Lagu Ini"
+
+#: src/skins/menus.cc:93
+msgid "Set A-B Repeat"
+msgstr "Tetapkan Ulang A-B"
+
+#: src/skins/menus.cc:94
+msgid "Clear A-B Repeat"
+msgstr "Kosongkan Ulang A-B"
+
+#: src/skins/menus.cc:96
+msgid "Jump to Song ..."
+msgstr "Lompat ke Lagu ..."
+
+#: src/skins/menus.cc:97
+msgid "Jump to Time ..."
+msgstr "Lompat ke Masa ..."
+
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "Main/Sambung Semula"
+
+#: src/skins/menus.cc:103
+msgid "New Playlist"
+msgstr "Senarai Main Baharu"
+
+#: src/skins/menus.cc:104
+msgid "Rename Playlist ..."
+msgstr "Nama Semula Senarai Main ..."
+
+#: src/skins/menus.cc:105
+msgid "Remove Playlist"
+msgstr "Buang Senarai Main"
+
+#: src/skins/menus.cc:107
+msgid "Previous Playlist"
+msgstr "Senarai Main Terdahulu"
+
+#: src/skins/menus.cc:108
+msgid "Next Playlist"
+msgstr "Senarai Main Berikutnya"
+
+#: src/skins/menus.cc:110
+msgid "Import Playlist ..."
+msgstr "Import Senarai Main ..."
+
+#: src/skins/menus.cc:111
+msgid "Export Playlist ..."
+msgstr "Eksport Senarai Main ..."
+
+#: src/skins/menus.cc:113
+msgid "Playlist Manager ..."
+msgstr "Pengurus Senarai Main ..."
+
+#: src/skins/menus.cc:114
+msgid "Queue Manager ..."
+msgstr "Pengurus Baris Gilir ..."
+
+#: src/skins/menus.cc:116
+msgid "Refresh Playlist"
+msgstr "Segar Semula Senarai Main"
+
+#: src/skins/menus.cc:120
+msgid "Show Playlist Editor"
+msgstr "Tunjuk Penyunting Senarai Main"
+
+#: src/skins/menus.cc:121
+msgid "Show Equalizer"
+msgstr "Tunjuk Penyama"
+
+#: src/skins/menus.cc:123
+msgid "Show Remaining Time"
+msgstr "Tunjuk Masa Berbaki"
+
+#: src/skins/menus.cc:125
+msgid "Always on Top"
+msgstr "Sentiasa di Atas"
+
+#: src/skins/menus.cc:126
+msgid "On All Workspaces"
+msgstr "Pada Semua Ruang Kerja"
+
+#: src/skins/menus.cc:128
+msgid "Roll Up Player"
+msgstr "Gulung Pemain"
+
+#: src/skins/menus.cc:129
+msgid "Roll Up Playlist Editor"
+msgstr "Gulung Penyunting Senarai Main"
+
+#: src/skins/menus.cc:130
+msgid "Roll Up Equalizer"
+msgstr "Gulung Penyama"
+
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Saiz Dua Kali Ganda"
+
+#: src/skins/menus.cc:138
+msgid "Add URL ..."
+msgstr "Tambah URL ..."
+
+#: src/skins/menus.cc:139
+msgid "Add Files ..."
+msgstr "Tambah Fail ..."
+
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
+msgid "By Title"
+msgstr "Mengikut Tajuk"
+
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr "Mengikut Nama Fail"
+
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
+msgid "By File Path"
+msgstr "Mengikut Laluan Fail"
+
+#: src/skins/menus.cc:151
+msgid "Remove All"
+msgstr "Buang Semua"
+
+#: src/skins/menus.cc:152
+msgid "Clear Queue"
+msgstr "Kosongkan Baris Gilir"
+
+#: src/skins/menus.cc:154
+msgid "Remove Unavailable Files"
+msgstr "Buang Fail Tidak Tersedia"
+
+#: src/skins/menus.cc:155
+msgid "Remove Duplicates"
+msgstr "Buang Pendua"
+
+#: src/skins/menus.cc:157
+msgid "Remove Unselected"
+msgstr "Buang Dinyahpilih"
+
+#: src/skins/menus.cc:158
+msgid "Remove Selected"
+msgstr "Buang Terpilih"
+
+#: src/skins/menus.cc:162
+msgid "Search and Select"
+msgstr "Gelintar dan Pilih"
+
+#: src/skins/menus.cc:164
+msgid "Invert Selection"
+msgstr "Songsangkan Pemilihan"
+
+#: src/skins/menus.cc:165
+msgid "Select None"
+msgstr "Pilih Tiada"
+
+#: src/skins/menus.cc:166
+msgid "Select All"
+msgstr "Pilih Semua"
+
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Mengikut Nombor Trek"
+
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
+msgid "By Artist"
+msgstr "Mengikut Artis"
+
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Mengikut Album"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Mengikut Album Artis"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
+msgid "By Release Date"
+msgstr "Mengikut Tarikh Keluaran"
+
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "Mengikut Genre"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "Mengikut Panjang"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "Mengikut Tajuk Suai"
+
+#: src/skins/menus.cc:198
+msgid "Randomize List"
+msgstr "Rawakkan Senarai"
+
+#: src/skins/menus.cc:199
+msgid "Reverse List"
+msgstr "Songsangkan Senarai"
+
+#: src/skins/menus.cc:201
+msgid "Sort Selected"
+msgstr "Isih Terpilih"
+
+#: src/skins/menus.cc:202
+msgid "Sort List"
+msgstr "Isih Senarai"
+
+#: src/skins/menus.cc:208
+msgid "Cut"
+msgstr "Potong"
+
+#: src/skins/menus.cc:209
+msgid "Copy"
+msgstr "Salin"
+
+#: src/skins/menus.cc:210
+msgid "Paste"
+msgstr "Tampal"
+
+#: src/skins/menus.cc:212
+msgid "Queue/Unqueue"
+msgstr "Baris Gilir/Nyahbaris Gilir"
+
+#: src/skins/menus.cc:218
+msgid "Load Preset ..."
+msgstr "Muat Praset ..."
+
+#: src/skins/menus.cc:219
+msgid "Load Auto Preset ..."
+msgstr "Muat Auto Praset ..."
+
+#: src/skins/menus.cc:220
+msgid "Load Default"
+msgstr "Muat Lalai"
+
+#: src/skins/menus.cc:221
+msgid "Load Preset File ..."
+msgstr "Muat Fail Praset ..."
+
+#: src/skins/menus.cc:222
+msgid "Load EQF File ..."
+msgstr "Muat Fail EQF ..."
+
+#: src/skins/menus.cc:224
+msgid "Save Preset ..."
+msgstr "Simpan Praset ..."
+
+#: src/skins/menus.cc:225
+msgid "Save Auto Preset ..."
+msgstr "Simpan Auto Praset ..."
+
+#: src/skins/menus.cc:226
+msgid "Save Default"
+msgstr "Simpan Lalai"
+
+#: src/skins/menus.cc:227
+msgid "Save Preset File ..."
+msgstr "Simpan Fail Praset ..."
+
+#: src/skins/menus.cc:228
+msgid "Save EQF File ..."
+msgstr "Simpan Fail EQF ..."
+
+#: src/skins/menus.cc:230
+msgid "Delete Preset ..."
+msgstr "Padam Praset ..."
+
+#: src/skins/menus.cc:231
+msgid "Delete Auto Preset ..."
+msgstr "Padam Auto Praset ..."
+
+#: src/skins/menus.cc:233
+msgid "Import Winamp Presets ..."
+msgstr "Import Praset Winamp ..."
+
+#: src/skins/menus.cc:235
+msgid "Reset to Zero"
+msgstr "Tetap Semula ke Sifar"
+
+#: src/skins/plugin.cc:48
+msgid "Winamp Classic Interface"
+msgstr "Antaramuka Klasik Winamp"
+
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
+msgid "Save"
+msgstr "Simpan"
+
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
+msgid "Load"
+msgstr "Muat"
+
+#: src/skins/preset-browser.cc:83
+msgid "Load Preset File"
+msgstr "Muat Fail Praset"
+
+#: src/skins/preset-browser.cc:100
+msgid "Load EQF File"
+msgstr "Muat Fail EQF"
+
+#: src/skins/preset-browser.cc:119
+msgid "Save Preset File"
+msgstr "Simpan Fail Praset"
+
+#: src/skins/preset-browser.cc:137
+msgid "Save EQF File"
+msgstr "Simpan Fail EQF"
+
+#: src/skins/preset-browser.cc:151
+msgid "Import Winamp Presets"
+msgstr "Import Praset Winamp"
+
+#: src/skins/preset-list.cc:285
+msgid "Presets"
+msgstr "Praset"
+
+#: src/skins/preset-list.cc:335
+msgid "Load preset"
+msgstr "Muat praset"
+
+#: src/skins/preset-list.cc:351
+msgid "Load auto-preset"
+msgstr "Muat auto-praset"
+
+#: src/skins/preset-list.cc:367
+msgid "Save preset"
+msgstr "Simpan praset"
+
+#: src/skins/preset-list.cc:382
+msgid "Save auto-preset"
+msgstr "Simpan auto-praset"
+
+#: src/skins/preset-list.cc:408
+msgid "Delete preset"
+msgstr "Padam praset"
+
+#: src/skins/preset-list.cc:424
+msgid "Delete auto-preset"
+msgstr "Padam auto-praset"
+
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Pemain:"
+
+#: src/skins/skins_cfg.cc:178
+msgid "Select main player window font:"
+msgstr "Pilih fon tetingkap pemain utama:"
+
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Senarai Main:"
+
+#: src/skins/skins_cfg.cc:181
+msgid "Select playlist font:"
+msgstr "Pilih fon senarai main:"
+
+#: src/skins/skins_cfg.cc:187
+msgid "<b>Skin</b>"
+msgstr "<b>Kulit</b>"
+
+#: src/skins/skins_cfg.cc:189
+msgid "<b>Fonts</b>"
+msgstr "<b>Fon</b>"
+
+#: src/skins/skins_cfg.cc:192
+msgid "Use bitmap fonts (supports ASCII only)"
+msgstr "Guna fon peta bit (sokong ASCII sahaja)"
+
+#: src/skins/skins_cfg.cc:194
+msgid "Scroll song title"
+msgstr "Tatal tajuk lagu"
+
+#: src/skins/skins_cfg.cc:196
+msgid "Scroll song title in both directions"
+msgstr "Tatal tajuk lagu dalam kedua-dua arah"
+
+#: src/skins/skins_cfg.cc:201
+msgid "Analyzer"
+msgstr "Penganalisis"
+
+#: src/skins/skins_cfg.cc:202
+msgid "Scope"
+msgstr "Skop"
+
+#: src/skins/skins_cfg.cc:203
+msgid "Voiceprint / VU meter"
+msgstr "Voiceprint / VU meter"
+
+#: src/skins/skins_cfg.cc:204
+msgid "Off"
+msgstr "Mati"
+
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
+msgid "Normal"
+msgstr "Biasa"
+
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
+msgid "Fire"
+msgstr "Api"
+
+#: src/skins/skins_cfg.cc:210
+msgid "Vertical lines"
+msgstr "Garis menegak"
+
+#: src/skins/skins_cfg.cc:214
+msgid "Lines"
+msgstr "Garis"
+
+#: src/skins/skins_cfg.cc:215
+msgid "Bars"
+msgstr "Palang"
+
+#: src/skins/skins_cfg.cc:219
+msgid "Slowest"
+msgstr "Paling lambat"
+
+#: src/skins/skins_cfg.cc:220
+msgid "Slow"
+msgstr "Lambat"
+
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
+msgid "Medium"
+msgstr "Sederhana"
+
+#: src/skins/skins_cfg.cc:222
+msgid "Fast"
+msgstr "Pantas"
+
+#: src/skins/skins_cfg.cc:223
+msgid "Fastest"
+msgstr "Paling pantas"
+
+#: src/skins/skins_cfg.cc:227
+msgid "Dots"
+msgstr "Titik"
+
+#: src/skins/skins_cfg.cc:228
+msgid "Line"
+msgstr "Garis"
+
+#: src/skins/skins_cfg.cc:229
+msgid "Solid"
+msgstr "Tegar"
+
+#: src/skins/skins_cfg.cc:235
+msgid "Ice"
+msgstr "Ais"
+
+#: src/skins/skins_cfg.cc:240
+msgid "Smooth"
+msgstr "Licin"
+
+#: src/skins/skins_cfg.cc:244
+msgid "<b>Type</b>"
+msgstr "<b>Jenis</b>"
+
+#: src/skins/skins_cfg.cc:245
+msgid "Visualization type:"
+msgstr "Jenis pengvisualan:"
+
+#: src/skins/skins_cfg.cc:248
+msgid "<b>Analyzer</b>"
+msgstr "<b>Penganalisis</b>"
+
+#: src/skins/skins_cfg.cc:249
+msgid "Show peaks"
+msgstr "Tunjuk puncak"
+
+#: src/skins/skins_cfg.cc:251
+msgid "Coloring:"
+msgstr "Pewarnaan:"
+
+#: src/skins/skins_cfg.cc:254
+msgid "Style:"
+msgstr "Gaya:"
+
+#: src/skins/skins_cfg.cc:257
+msgid "Falloff:"
+msgstr "Jatuhan:"
+
+#: src/skins/skins_cfg.cc:260
+msgid "Peak falloff:"
+msgstr "Jatuhan puncak:"
+
+#: src/skins/skins_cfg.cc:264
+msgid "Scope Style:"
+msgstr "Gaya Skop:"
+
+#: src/skins/skins_cfg.cc:267
+msgid "Voiceprint Coloring:"
+msgstr "Pewarnaan Voiceprint:"
+
+#: src/skins/skins_cfg.cc:270
+msgid "VU Meter Style:"
+msgstr "Gaya Meter VU:"
+
+#: src/skins/skins_cfg.cc:276
+msgid "General"
+msgstr "Am"
+
+#: src/skins/skins_cfg.cc:277
+msgid "Visualization"
+msgstr "Pengvisualan"
+
+#: src/skins/ui_equalizer.cc:282
+msgid "Preamp"
+msgstr "Praamp"
+
+#: src/skins/ui_equalizer.cc:286
+msgid "31 Hz"
+msgstr "31 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "63 Hz"
+msgstr "63 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "125 Hz"
+msgstr "125 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "250 Hz"
+msgstr "250 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "500 Hz"
+msgstr "500 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "1 kHz"
+msgstr "1 kHz"
+
+#: src/skins/ui_equalizer.cc:288
+msgid "2 kHz"
+msgstr "2 kHz"
+
+#: src/skins/ui_equalizer.cc:288
+msgid "4 kHz"
+msgstr "4 kHz"
+
+#: src/skins/ui_equalizer.cc:288
+msgid "8 kHz"
+msgstr "8 kHz"
+
+#: src/skins/ui_equalizer.cc:288
+msgid "16 kHz"
+msgstr "16 kHz"
+
+#: src/skins/ui_equalizer.cc:330
+msgid "Audacious Equalizer"
+msgstr "Penyama Audacious"
+
+#: src/skins/ui_main.cc:688
+#, c-format
+msgid "Seek to %d:%-2.2d / %d:%-2.2d"
+msgstr "Jangkau ke %d:%-2.2d / %d:%-2.2d"
+
+#: src/skins/ui_main.cc:709
+#, c-format
+msgid "Volume: %d%%"
+msgstr "Volum: %d%%"
+
+#: src/skins/ui_main.cc:732
+#, c-format
+msgid "Balance: %d%% left"
+msgstr "Imbangan: %d%% kiri"
+
+#: src/skins/ui_main.cc:734
+msgid "Balance: center"
+msgstr "Imbangan: tengah"
+
+#: src/skins/ui_main.cc:736
+#, c-format
+msgid "Balance: %d%% right"
+msgstr "Imbangan: %d%% kanan"
+
+#: src/skins/ui_main.cc:842
+msgid "Options Menu"
+msgstr "Menu Pilihan"
+
+#: src/skins/ui_main.cc:846
+msgid "Disable 'Always On Top'"
+msgstr "Lumpuhkan 'Sentiasa Di Atas'"
+
+#: src/skins/ui_main.cc:848
+msgid "Enable 'Always On Top'"
+msgstr "Benarkan 'Sentiasa Di Atas'"
+
+#: src/skins/ui_main.cc:851
+msgid "File Info Box"
+msgstr "Kotak Maklumat Fail"
+
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "Pengvisualan"
+
+#: src/skins/ui_main.cc:1336
+msgid "Repeat point A set."
+msgstr "Ulang titik A ditetapkan."
+
+#: src/skins/ui_main.cc:1341
+msgid "Repeat point B set."
+msgstr "Ulang titik B ditetapkan"
+
+#: src/skins/ui_main.cc:1350
+msgid "Repeat points cleared."
+msgstr "Ulang titik dikosongkan."
+
+#: src/skins/ui_playlist.cc:219
+msgid "Search entries in active playlist"
+msgstr "Gelintar masukan dalam senarai main aktif"
+
+#: src/skins/ui_playlist.cc:226
+msgid ""
+"Select entries in playlist by filling one or more fields. Fields use regular "
+"expressions syntax, case-insensitive. If you don't know how regular "
+"expressions work, simply insert a literal portion of what you're searching "
+"for."
+msgstr ""
+"Pilih masukan dalam senarai main dengan mengisi satu atau lebih medan. Medan "
+"guna sintaks ungkapan nalar, tidak-sensitif-kata. Jika anda tidak tahu "
+"bagaimana ungkapan nalar berfungsi, hanya masukkan bahagian harfiah apa yang "
+"anda gelintar."
+
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr "Tajuk:"
+
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr "Album:"
+
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr "Artis:"
+
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Nama Fail:"
+
+#: src/skins/ui_playlist.cc:263
+msgid "Clear previous selection before searching"
+msgstr "Kosongkan pemilihan terdahulu sebelum menggelintar"
+
+#: src/skins/ui_playlist.cc:266
+msgid "Automatically toggle queue for matching entries"
+msgstr "Togol baris gilir secara automatik untuk pemadanan masukan"
+
+#: src/skins/ui_playlist.cc:269
+msgid "Create a new playlist with matching entries"
+msgstr "Cipta senarai main baharu dengan masukan sepadan"
+
+#: src/skins/ui_playlist.cc:717
+msgid "Audacious Playlist Editor"
+msgstr "Penyunting Senarai Main Audacious"
+
+#: src/skins/ui_playlist.cc:752
+#, c-format
+msgid "%s (%d of %d)"
+msgstr "%s (%d dar %d)"
+
+#: src/skins/ui_skinselector.cc:167
+msgid "Archived Winamp 2.x skin"
+msgstr "Kulit Winamp 2.x berarkib"
+
+#: src/skins/ui_skinselector.cc:172
+msgid "Unarchived Winamp 2.x skin"
+msgstr "Kulit Winamp 2.x tidak berarkib"
+
+#: src/skins/util.cc:430
+#, c-format
+msgid "Could not create directory (%s): %s\n"
+msgstr "Tidak dapat mencipta direktori (%s): %s\n"
+
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Pemalam Sndfile"
+
+#: src/sndfile/plugin.cc:336
+msgid ""
+"Based on the xmms_sndfile plugin:\n"
+"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
+"\n"
+"Adapted for Audacious by Tony Vroon <chainsaw at gentoo.org>\n"
+"\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., 51 "
+"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
+msgstr ""
+"Berdasarkan pada pemalam xmms_sndfile:\n"
+"Hakcipta (C) 2000, 2002 Erik de Castro Lopo\n"
+"\n"
+"Diadaptasi untuk Audacious oleh Tony Vroon <chainsaw at gentoo.org>\n"
+"\n"
+"Program ini adalah perisian bebas; anda boleh mengedarkannya dan/atau "
+"mengubahsuainya dibawah terma Pelesenan Awam Am GNU yang diterbitkan oleh "
+"Free Software Foundation; sama ada versi 2 dari lesen, atau (mengikut "
+"pilihan anda) mana-mana versi terkini.\n"
+"\n"
+"Program ini diedarkan dengan harapan ianya akan berguna, TANPA SEBARANG "
+"JAMINAN; termasuk juga KESESUAIAN UNTUK DIPASARKAN, JAMINAN KUALITI, atau "
+"JAMINAN ATAS APA JUA SEBAB. Sila lihat GNU General Public License untuk "
+"maklumat lanjut.\n"
+"\n"
+"Anda seharusnya menerima satu salinan Lesen Awam Am GNU bersama-sama dengan "
+"program; jika tidak, laporkannya ke Free Software Foundation, Inc., 51 "
+"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
+
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Output Sndio"
+
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "Peranti (kosong untuk lalai):"
+
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Simpan dan pulihkan volum:"
+
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Ralat Sndio: Format audio tidak disokong (%d)"
+
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Ralat Sndio: sio_open() gagal"
+
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Ralat Sndio: sio_setpar() gagal"
+
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Ralat Sndio: sio_start() gagal"
+
+#: src/song_change/song_change.cc:33
+msgid "Song Change"
+msgstr "Lagu Berubah"
+
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Parameter dilepasi ke shell seharusnya dikurungkan dalam "
+"petikan. Jika dibuat sebaliknya mengundang risiko keselamatan.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Perintah</b>"
+
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Perintah dijalankan bila memulakan lagu baharu:"
+
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Perintah dijalankan dipenghujung lagu:"
+
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Perintah dijalankan dipenghujung senarai main:"
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr "Perintah dijalankan bila tajuk lagu berubah (untuk strim rangkaian):"
+
+#: src/song_change/song_change.cc:376
+msgid ""
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
+"\n"
+"%F: Frequency (in hertz)\n"
+"%c: Number of channels\n"
+"%f: File name (full path)\n"
+"%l: Length (in milliseconds)\n"
+"%n or %s: Song name\n"
+"%r: Rate (in bits per second)\n"
+"%t: Playlist position (%02d)\n"
+"%p: Currently playing (1 or 0)\n"
+"%a: Artist\n"
+"%b: Album\n"
+"%T: Track title"
+msgstr ""
+"Anda boleh guna rentetan format berikut yang diganti sebelum memanggil "
+"perintah (bukan emua berguna untuk perintah end-of-playlist):\n"
+"\n"
+"%F: Frekuensi (dalam hertz)\n"
+"%c: Bilangan saluran\n"
+"%f: Nama penuh (laluan penuh)\n"
+"%l: Panjang (dalam milisaat)\n"
+"%n atau %s: Nama lagu\n"
+"%r: Kadar (dalam bit per saat)\n"
+"%t: Kedudukan senarai main (%02d)\n"
+"%p: Dimain ketika ini (1 atau 0)\n"
+"%a: Artis\n"
+"%b: Album\n"
+"%T: Tajuk trek"
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Maklumat Lagu (Qt)"
+
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "Pensampel Semula SoX"
+
+#: src/sox-resampler/sox-resampler.cc:144
+msgid ""
+"SoX Resampler Plugin for Audacious\n"
+"Copyright 2013 MichaÅ Lipski\n"
+"\n"
+"Based on Sample Rate Converter Plugin:\n"
+"Copyright 2010-2012 John Lindgren"
+msgstr ""
+"Pemlam Pensampel Semula SoX \n"
+"untuk Audacious\n"
+"Hakcipta 2013 MichaÅ Lipski\n"
+"\n"
+"Berdasarkan pada Pemalam Penukar\n"
+"Kadar Sampel:\n"
+"Hakcipta 2010-2012 John Lindgren"
+
+#: src/sox-resampler/sox-resampler.cc:150
+msgid "Quick"
+msgstr "Pantas"
+
+#: src/sox-resampler/sox-resampler.cc:151
+msgid "Low"
+msgstr "Rendah"
+
+#: src/sox-resampler/sox-resampler.cc:153
+msgid "High"
+msgstr "Tinggi"
+
+#: src/sox-resampler/sox-resampler.cc:154
+msgid "Very High"
+msgstr "Sangat Tinggi"
+
+#: src/sox-resampler/sox-resampler.cc:158
+msgid "Quality:"
+msgstr "Kualiti:"
+
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Kelajuan dan Pic"
+
+#: src/speed-pitch/speed-pitch.cc:210
+msgid "<b>Speed and Pitch</b>"
+msgstr "<b>Kelajuan dan Pic</b>"
+
+#: src/speed-pitch/speed-pitch.cc:211
+msgid "Speed:"
+msgstr "Kelajuan:"
+
+#: src/speed-pitch/speed-pitch.cc:214
+msgid "Pitch:"
+msgstr "Pic:"
+
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Ikon Status"
+
+#: src/statusicon/statusicon.cc:283
+msgid "Se_ttings ..."
+msgstr "_Tetapan ..."
+
+#: src/statusicon/statusicon.cc:372
+msgid ""
+"Status Icon Plugin\n"
+"\n"
+"Copyright 2005-2007 Giacomo Lozito <james at develia.org>\n"
+"Copyright 2010 MichaÅ Lipski <tallica at o2.pl>\n"
+"\n"
+"This plugin provides a status icon, placed in\n"
+"the system tray area of the window manager."
+msgstr ""
+"Pemalam Ikon Status\n"
+"\n"
+"Hakcipta 2005-2007 Giacomo Lozito <james at develia.org>\n"
+"Hakcipta 2010 MichaÅ Lipski <tallica at o2.pl>\n"
+"\n"
+"Pemalam ini menyediakan ikon status, terletak di\n"
+"dalam kawasan talam sistem pengurus tetingkap."
+
+#: src/statusicon/statusicon.cc:379
+msgid "<b>Mouse Scroll Action</b>"
+msgstr "<b>Tindakan Tatal Tetikus</b>"
+
+#: src/statusicon/statusicon.cc:380
+msgid "Change volume"
+msgstr "Ubah volum"
+
+#: src/statusicon/statusicon.cc:383
+msgid "Change playing song"
+msgstr "Ubah lagu dimainkan"
+
+#: src/statusicon/statusicon.cc:386
+msgid "<b>Other Settings</b>"
+msgstr "<b>Tetapan Lain</b>"
+
+#: src/statusicon/statusicon.cc:387
+msgid "Disable the popup window"
+msgstr "Lumpuhkan tetingkap timbul"
+
+#: src/statusicon/statusicon.cc:389
+msgid "Close to the system tray"
+msgstr "Tutup talam sistem"
+
+#: src/statusicon/statusicon.cc:391
+msgid "Advance in playlist when scrolling upward"
+msgstr "Dahulukan dalam senarai main bila menatal ke atas"
+
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Stereo Ekstra"
+
+#: src/stereo_plugin/stereo.cc:36
+msgid ""
+"Extra Stereo Plugin\n"
+"\n"
+"By Johan Levin, 1999"
+msgstr ""
+"Pemalam Stereo Extra\n"
+"\n"
+"Oleh Johan Levin, 1999"
+
+#: src/stereo_plugin/stereo.cc:44
+msgid "<b>Extra Stereo</b>"
+msgstr "<b>Stereo Ekstra</b>"
+
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Penjana Nada"
+
+#: src/tonegen/tonegen.cc:94
+#, c-format
+msgid "%s %.1f Hz"
+msgstr "%s %.1f Hz"
+
+#: src/tonegen/tonegen.cc:94
+msgid "Tone Generator: "
+msgstr "Penjana Nada:"
+
+#: src/tonegen/tonegen.cc:160
+msgid ""
+"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
+"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
+"\n"
+"To use it, add a URL: tone://frequency1;frequency2;frequency3;...\n"
+"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
+msgstr ""
+"Penjana nada sin oleh Håvard Kvålen <havardk at xmms.org>\n"
+"Diubahsuai oleh Daniel J. Peng <danielpeng at bigfoot.com>\n"
+"\n"
+"Untuk guna ia, tambah URL: tone://frequency1;frequency2;frequency3;...\n"
+"cth. tone://2000;2005 untuk mainkan nada 2000 Hz dan nada 2005 Hz"
+
+#: src/voice_removal/voice_removal.cc:28
+msgid "Voice Removal"
+msgstr "Pembuangan Suara"
+
+#: src/vorbis/vorbis.cc:465
+msgid ""
+"Audacious Ogg Vorbis Decoder\n"
+"\n"
+"Based on the Xiph.org Foundation's Ogg Vorbis Plugin:\n"
+"http://www.xiph.org/\n"
+"\n"
+"Original code by:\n"
+"Tony Arcieri <bascule at inferno.tusculum.edu>\n"
+"\n"
+"Contributions from:\n"
+"Chris Montgomery <monty at xiph.org>\n"
+"Peter Alm <peter at xmms.org>\n"
+"Michael Smith <msmith at labyrinth.edu.au>\n"
+"Jack Moffitt <jack at icecast.org>\n"
+"Jorn Baayen <jorn at nl.linux.org>\n"
+"Håvard Kvålen <havardk at xmms.org>\n"
+"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
+"Eugene Zagidullin <e.asphyx at gmail.com>"
+msgstr ""
+"Penyahkod Ogg Vorbis Audacious\n"
+"\n"
+"Berdasarkan pada Pemalam Ogg Vorbis Xiph.org Foundation:\n"
+"http://www.xiph.org/\n"
+"\n"
+"Kod asal oleh:\n"
+"Tony Arcieri <bascule at inferno.tusculum.edu>\n"
+"\n"
+"Penyumbang:\n"
+"Chris Montgomery <monty at xiph.org>\n"
+"Peter Alm <peter at xmms.org>\n"
+"Michael Smith <msmith at labyrinth.edu.au>\n"
+"Jack Moffitt <jack at icecast.org>\n"
+"Jorn Baayen <jorn at nl.linux.org>\n"
+"Håvard Kvålen <havardk at xmms.org>\n"
+"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
+"Eugene Zagidullin <e.asphyx at gmail.com>"
+
+#: src/vorbis/vorbis.h:18
+msgid "Ogg Vorbis Decoder"
+msgstr "Penyahkod Ogg Vorbis"
+
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Perincian mengenai %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"Tajuk: %t\n"
+"Pengarang: %a\n"
+"Daripada: %f\n"
+"Penjejak: %T\n"
+"Ulasan: %C\n"
+"Jenis cip: %c\n"
+"Stereo: %s\n"
+"Gelung: %l\n"
+"Frek. cip: %F\n"
+"Frek. pemain: %P\n"
+"Tahun: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "Penyahkod VTX"
+
+#: src/vtx/vtx.cc:184
+msgid ""
+"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
+"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
+"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
+msgstr ""
+"Pemain format fail Vortex oleh Sashnov Alexander <sashnov at ngs.ru>\n"
+"Berdasarkan pada in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
+"Pemalam Audacious oleh Pavel Vymetalek <pvymetalek at seznam.cz>"
+
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "Penyahkod WavPack"
+
+#: src/wavpack/wavpack.cc:211
+msgid "lossy (hybrid)"
+msgstr "hilang (hidbrid)"
+
+#: src/wavpack/wavpack.cc:213
+msgid "lossy"
+msgstr "hilang"
+
+#: src/wavpack/wavpack.cc:255
+msgid ""
+"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
+"\n"
+"Some of the plugin code was by Miles Egan."
+msgstr ""
+"Hakcipta 2006 William Pitcock <nenolod at nenolod.net>\n"
+"\n"
+"Sebahagian kod pemalam oleh Miles Egan."
+
+#: src/xsf/plugin.cc:50
+msgid "2SF Decoder"
+msgstr "Penyahkod 2SF"
+
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>Konfigurasi XSF</b>"
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Abai panjang dari fail"
+
+#: src/xspf/xspf.cc:89
+msgid "XML Shareable Playlists (XSPF)"
+msgstr "Senarai Main Boleh Kongsi XML (XSPF)"
diff --git a/po/nl.po b/po/nl.po
new file mode 100644
index 000000000000..dff9fa0d01ac
--- /dev/null
+++ b/po/nl.po
@@ -0,0 +1,4078 @@
+# Dutch translation for Audacious Plugins
+# Copyright (C) Audacious translators
+# This file is distributed under the same license as the Audacious Plugins package.
+#
+# Translators:
+# Bjorn Roesbeke <inbox at bjornroesbeke.be>, 2013
+# Dennis Klomp <c_klomp at epu-forum.net>, 2012
+# dragnadh <dragnadh at gmail.com>, 2015
+# Farioko <fabianbakkum at hotmail.com>, 2014
+# Freek1A <fjvluijt at hotmail.com>, 2012
+# shured <shured1 at gmail.com>, 2014
+msgid ""
+msgstr ""
+"Project-Id-Version: Audacious Plugins\n"
+"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-17 17:53+0000\n"
+"Last-Translator: dragnadh <dragnadh at gmail.com>\n"
+"Language-Team: Dutch (http://www.transifex.com/projects/p/audacious/language/"
+"nl/)\n"
+"Language: nl\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"
+
+#: src/aac-raw/aac.cc:18
+msgid "AAC (Raw) Decoder"
+msgstr "AAC (Raw) Decoder"
+
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib Player)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
+msgid "sequenced"
+msgstr "gesequentieerd"
+
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarm"
+
+#: src/alarm/alarm.cc:782
+msgid "Set Alarm ..."
+msgstr "Alarm instellen ..."
+
+#: src/alarm/alarm.cc:810
+msgid ""
+"A plugin that can be used to start playing at a certain time.\n"
+"\n"
+"Originally written by Adam Feakin and Daniel Stodden."
+msgstr ""
+"Een invoegtoepassing die gebruikt kan worden om het afspelen te starten op "
+"een bepaald tijdstip.\n"
+"\n"
+"Origineel geschreven door Adam Feakin en Daniel Stodden."
+
+#: src/alarm/interface.cc:28
+msgid ""
+"Time\n"
+" Alarm at:\n"
+" The time for the alarm to come on.\n"
+"\n"
+" Quiet after:\n"
+" Stop alarm after this amount of time.\n"
+" (if the wakeup dialog is not closed)\n"
+"\n"
+"\n"
+"Days\n"
+" Day:\n"
+" Select the days for the alarm to activate.\n"
+"\n"
+" Time:\n"
+" Choose the time for the alarm on each day,\n"
+" or select the toggle button to use the default\n"
+" time.\n"
+"\n"
+"\n"
+msgstr ""
+"Tijd\n"
+"Alarm op:\n"
+"De tijd voor het alarm start.\n"
+"\n"
+"Stil na:\n"
+"Stop alarm na zolang.\n"
+"(als het opsta venster nog gesloten is)\n"
+"\n"
+"\n"
+"Dagen\n"
+"Dag:\n"
+"Selecteer de dagen voor wanneer het \n"
+"alarm actief moet zijn.\n"
+"\n"
+"Tijd:\n"
+"Kies de tijd voor het alarm elke dag,\n"
+"of klik op de pin knop om de standaardwaarde\n"
+"te gebruiken.\n"
+"\n"
+"\n"
+
+#: src/alarm/interface.cc:45
+msgid ""
+"Volume\n"
+" Fading:\n"
+" Fade the volume up to the chosen volume\n"
+" for this amount of time.\n"
+"\n"
+" Start at:\n"
+" Start fading from this volume.\n"
+"\n"
+" Final:\n"
+" The volume to stop fading at. If the fading\n"
+" time is 0 then set volume to this and start\n"
+" playing.\n"
+"\n"
+"\n"
+"Options:\n"
+" Additional Command:\n"
+" Run this command at the alarm time.\n"
+"\n"
+msgstr ""
+"Volume\n"
+"Vervaging:\n"
+"Vervaag het volume op het gekozen tijdstip.\n"
+"\n"
+"Start op:\n"
+"Start vervaging vanaf dit volume.\n"
+"\n"
+"Uiteindelijk:\n"
+"Stop met het vervagen wanneer,\n"
+"de tijd op 0 staat en start met afspelen.\n"
+"\n"
+"\n"
+"Opties:\n"
+"Overige commando's:\n"
+"Voer dit commando uit wanneer het\n"
+"alarm wordt geactiveerd.\n"
+
+#: src/alarm/interface.cc:62
+msgid ""
+" Playlist:\n"
+" Load this playlist. If no playlist\n"
+" is given, the current one will be used.\n"
+" The URL of an mp3/ogg stream\n"
+" can also be entered here.\n"
+"\n"
+" Reminder:\n"
+" Display a reminder when the alarm goes off.\n"
+" Type the reminder in the box and turn on the\n"
+" toggle button if you want it to be shown."
+msgstr ""
+"Afspeellijst:\n"
+"Laad deze afspeellijst. Als er\n"
+"geen afspeellijst gespecificeerd\n"
+"is, zal de huidige worden gebruikt.\n"
+"De URL van een mp3/ogg stream\n"
+"kan hier ook ingevoerd worden.\n"
+"\n"
+"Herinnering:\n"
+"Laat een herinnering zien wanneer het alarm afgaat.\n"
+"Schrijf een herinnering in dit vakje en activeer de\n"
+"pin knop als je het wilt laten weergeven."
+
+#: src/alarm/interface.cc:81
+msgid "This is your wakeup call."
+msgstr "Dit is uw opstaan melding"
+
+#: src/alarm/interface.cc:99
+msgid "Your reminder for today is..."
+msgstr "Uw herinnering voor vandaag is..."
+
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
+msgid "Reminder"
+msgstr "Herinnering"
+
+#: src/alarm/interface.cc:132
+msgid "Monday"
+msgstr "Maandag"
+
+#: src/alarm/interface.cc:132
+msgid "Tuesday"
+msgstr "Dinsdag"
+
+#: src/alarm/interface.cc:132
+msgid "Wednesday"
+msgstr "Woensdag"
+
+#: src/alarm/interface.cc:133
+msgid "Thursday"
+msgstr "Donderdag"
+
+#: src/alarm/interface.cc:133
+msgid "Friday"
+msgstr "Vrijdag"
+
+#: src/alarm/interface.cc:133
+msgid "Saturday"
+msgstr "Zaterdag"
+
+#: src/alarm/interface.cc:133
+msgid "Sunday"
+msgstr "Zondag"
+
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
+msgid "Time"
+msgstr "Tijd"
+
+#: src/alarm/interface.cc:178
+msgid "Alarm at (default):"
+msgstr "Alarm (op standaard)"
+
+#: src/alarm/interface.cc:200
+msgid "h"
+msgstr "h"
+
+#: src/alarm/interface.cc:203
+msgid "Quiet after:"
+msgstr "Stil na:"
+
+#: src/alarm/interface.cc:215
+msgid "hours"
+msgstr "uren"
+
+#: src/alarm/interface.cc:226
+msgid "minutes"
+msgstr "minuten"
+
+#: src/alarm/interface.cc:235
+msgid "Choose the days for the alarm to come on"
+msgstr "Kies de dag voor het alarm om aan te gaan"
+
+#: src/alarm/interface.cc:242
+msgid "Day"
+msgstr "Dag"
+
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
+msgid "Default"
+msgstr "Standaard"
+
+#: src/alarm/interface.cc:288
+msgid "Days"
+msgstr "Dagen"
+
+#: src/alarm/interface.cc:297
+msgid "Fading"
+msgstr "Vervagen"
+
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
+msgid "seconds"
+msgstr "Seconden"
+
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
+msgid "Volume"
+msgstr "Volume"
+
+#: src/alarm/interface.cc:317
+msgid "Start at"
+msgstr "Start bij"
+
+#: src/alarm/interface.cc:333
+msgid "Final"
+msgstr "Laatste"
+
+#: src/alarm/interface.cc:346
+msgid "Current"
+msgstr "Huidige"
+
+#: src/alarm/interface.cc:359
+msgid "Additional Command"
+msgstr "Extra Opdracht"
+
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
+msgid "enable"
+msgstr "Aan"
+
+#: src/alarm/interface.cc:372
+msgid "Playlist (optional)"
+msgstr "Afspeellijst (Hoeft niet)"
+
+#: src/alarm/interface.cc:379
+msgid "Select a playlist"
+msgstr "Selecteer een afspeellijst"
+
+#: src/alarm/interface.cc:399
+msgid "Options"
+msgstr "Opties"
+
+#: src/alarm/interface.cc:404
+msgid "What do these options mean?"
+msgstr "Wat betekenen deze opties"
+
+#: src/alarm/interface.cc:420
+msgid "Help"
+msgstr "Help"
+
+#: src/albumart/albumart.cc:31
+msgid "Album Art"
+msgstr "Albumhoes"
+
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Albumhoes (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA Uitvoer"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ALSA Uitvoer Invoegtoepassing voor Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"Met dank aan William Pitcock, schrijver van de ALSA Uitvoer Plugin NG,\n"
+"van wie zijn code werd gebruikt als handleiding wanneer de ALSA handleiding "
+"niet genoeg was."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(geen beschrijving)"
+
+#: src/alsa/config.cc:166
+msgid "Default PCM device"
+msgstr "Standaard PCM apparaat"
+
+#: src/alsa/config.cc:188
+msgid "Default mixer device"
+msgstr "Standaard mixer apparaat"
+
+#: src/alsa/config.cc:296
+msgid "PCM device:"
+msgstr "PCM apparaat:"
+
+#: src/alsa/config.cc:299
+msgid "Mixer device:"
+msgstr "Mixer apparaat:"
+
+#: src/alsa/config.cc:302
+msgid "Mixer element:"
+msgstr "Mixer element:"
+
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI Speler)"
+
+#: src/amidi-plug/amidi-plug.cc:437
+msgid ""
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
+"\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:94
+msgid "Override default gain:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:102
+msgid "Override default polyphony:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:110
+msgid "Override default reverb:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
+msgid "On"
+msgstr "Aan"
+
+#: src/amidi-plug/i_configure.cc:118
+msgid "Override default chorus:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
+msgid "<b>Playback</b>"
+msgstr "<b>Afspelen</b>"
+
+#: src/amidi-plug/i_configure.cc:129
+msgid "Transpose:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
+msgid "Drum shift:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "Noteer nummers"
+
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:141
+msgid "<b>SoundFont</b>"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:143
+msgid "<b>Synthesizer</b>"
+msgstr "<b>Synthesizer</b>"
+
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "Sample rate:"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
+msgid "AMIDI-Plug - select SoundFont file"
+msgstr "AMIDI-Plug - SoundFont bestand selecteren"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Sluiten"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
+msgid "_Open"
+msgstr "_Open"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "Bestandsnaam"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
+msgid "Size (bytes)"
+msgstr "Groote (bytes)"
+
+#: src/amidi-plug/i_fileinfo.cc:163
+msgid "Name:"
+msgstr "Naam:"
+
+#: src/amidi-plug/i_fileinfo.cc:181
+msgid "<span size=\"smaller\"> MIDI Info </span>"
+msgstr "<span size=\"smaller\"> MIDI Info <span>"
+
+#: src/amidi-plug/i_fileinfo.cc:195
+msgid "Format:"
+msgstr "A"
+
+#: src/amidi-plug/i_fileinfo.cc:198
+msgid "Length (msec):"
+msgstr "Lengte (msec):"
+
+#: src/amidi-plug/i_fileinfo.cc:201
+msgid "No. of Tracks:"
+msgstr "Aantal Tracks:"
+
+#: src/amidi-plug/i_fileinfo.cc:207
+msgid "variable"
+msgstr "variabel"
+
+#: src/amidi-plug/i_fileinfo.cc:209
+msgid "BPM:"
+msgstr "BPM:"
+
+#: src/amidi-plug/i_fileinfo.cc:217
+msgid "BPM (wavg):"
+msgstr "BPM (wavg):"
+
+#: src/amidi-plug/i_fileinfo.cc:220
+msgid "Time Div:"
+msgstr "Time Div:"
+
+#: src/amidi-plug/i_fileinfo.cc:231
+msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
+msgstr "<span size=\"smaller\"> MIDI Commentaar en songtekst </span>"
+
+#: src/amidi-plug/i_fileinfo.cc:278
+msgid "* no comments available in this MIDI file *"
+msgstr "* geen commentaar beschikbaar in dit MIDI bestand *"
+
+#: src/amidi-plug/i_fileinfo.cc:290
+msgid "* no lyrics available in this MIDI file *"
+msgstr "* geen songtekst beschikbaar in dit MIDI bestand *"
+
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
+msgid "_Close"
+msgstr "_Sluit"
+
+#: src/amidi-plug/i_fileinfo.cc:325
+msgid " (invalid UTF-8)"
+msgstr " (onjuist UTF-8)"
+
+#: src/aosd/aosd.cc:32
+msgid ""
+"Audacious OSD\n"
+"http://www.develia.org/projects.php?p=audacious#aosd\n"
+"\n"
+"Written by Giacomo Lozito <james at develia.org>\n"
+"\n"
+"Based in part on Evan Martin's Ghosd library:\n"
+"http://neugierig.org/software/ghosd/"
+msgstr ""
+
+#: src/aosd/aosd.h:37
+msgid "AOSD (On-Screen Display)"
+msgstr "AOSD (On-Screen Display)"
+
+#: src/aosd/aosd_style.cc:54
+msgid "Rectangle"
+msgstr "Vierkant"
+
+#: src/aosd/aosd_style.cc:59
+msgid "Rounded Rectangle"
+msgstr "Vierkant met afgeronde hoeken"
+
+#: src/aosd/aosd_style.cc:64
+msgid "Concave Rectangle"
+msgstr "Concave vierkant"
+
+#: src/aosd/aosd_style.cc:69
+msgid "None"
+msgstr "Geen"
+
+#: src/aosd/aosd_trigger.cc:50
+msgid "Playback Start"
+msgstr "Start Afspelen"
+
+#: src/aosd/aosd_trigger.cc:51
+msgid "Triggers OSD when a playlist entry is played."
+msgstr "OSD starten wanneer een afspeellijst regel word afgespeeld."
+
+#: src/aosd/aosd_trigger.cc:56
+msgid "Title Change"
+msgstr "Titel verandering"
+
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
+msgstr ""
+"OSD wordt geactiveerd wanneer een liedtitel verandert (voor internet "
+"streams)."
+
+#: src/aosd/aosd_trigger.cc:62
+msgid "Pause On"
+msgstr "Pause Aan"
+
+#: src/aosd/aosd_trigger.cc:63
+msgid "Triggers OSD when playback is paused."
+msgstr "OSD wordt geactiveerd wanneer afspelen wordt gepauzeerd."
+
+#: src/aosd/aosd_trigger.cc:68
+msgid "Pause Off"
+msgstr "Pause Uit"
+
+#: src/aosd/aosd_trigger.cc:69
+msgid "Triggers OSD when playback is unpaused."
+msgstr "OSD wordt geactiveerd wanneer afspelen wordt hervat."
+
+#: src/aosd/aosd_ui.cc:163
+msgid "Placement"
+msgstr "Plaatsing"
+
+#: src/aosd/aosd_ui.cc:196
+msgid "Relative X offset:"
+msgstr "Relatieve X verplaatsing:"
+
+#: src/aosd/aosd_ui.cc:203
+msgid "Relative Y offset:"
+msgstr "Relatieve Y verplaatsing:"
+
+#: src/aosd/aosd_ui.cc:210
+msgid "Max OSD width:"
+msgstr "Max OSD breedte:"
+
+#: src/aosd/aosd_ui.cc:221
+msgid "Multi-Monitor options"
+msgstr "Multi-Monitor opties"
+
+#: src/aosd/aosd_ui.cc:225
+msgid "Display OSD using:"
+msgstr "Toon OSD op:"
+
+#: src/aosd/aosd_ui.cc:227
+msgid "all monitors"
+msgstr "alle monitors"
+
+#: src/aosd/aosd_ui.cc:230
+#, c-format
+msgid "monitor %i"
+msgstr "monitor %i"
+
+#: src/aosd/aosd_ui.cc:282
+msgid "Timing (ms)"
+msgstr "Timing (ms)"
+
+#: src/aosd/aosd_ui.cc:287
+msgid "Display:"
+msgstr "Weergeven:"
+
+#: src/aosd/aosd_ui.cc:292
+msgid "Fade in:"
+msgstr "Fade in:"
+
+#: src/aosd/aosd_ui.cc:297
+msgid "Fade out:"
+msgstr "Fade uit:"
+
+#: src/aosd/aosd_ui.cc:361
+msgid "Fonts"
+msgstr "Lettertypen"
+
+#: src/aosd/aosd_ui.cc:368
+#, c-format
+msgid "Font %i:"
+msgstr "Lettertype %i:"
+
+#: src/aosd/aosd_ui.cc:382
+msgid "Shadow"
+msgstr "Schaduw"
+
+#: src/aosd/aosd_ui.cc:486
+msgid "Render Style"
+msgstr "Weergavestijl"
+
+#: src/aosd/aosd_ui.cc:502
+msgid "Colors"
+msgstr "Kleuren"
+
+#: src/aosd/aosd_ui.cc:513
+#, c-format
+msgid "Color %i:"
+msgstr "Kleur %i:"
+
+#: src/aosd/aosd_ui.cc:600
+msgid "Enable trigger"
+msgstr "Trekker inschakelen"
+
+#: src/aosd/aosd_ui.cc:627
+msgid "Event"
+msgstr "Gebeurtenis"
+
+#: src/aosd/aosd_ui.cc:655
+msgid "Composite manager detected"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:662
+msgid ""
+"Composite manager not detected;\n"
+"unless you know that you have one running, please activate a composite "
+"manager otherwise the OSD won't work properly"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:670
+msgid "Composite manager not required for fake transparency"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:706
+msgid "Transparency"
+msgstr "Doorzichtigheid"
+
+#: src/aosd/aosd_ui.cc:712
+msgid "Fake transparency"
+msgstr "Valse doorzichtigheid"
+
+#: src/aosd/aosd_ui.cc:714
+msgid "Real transparency (requires X Composite Ext.)"
+msgstr "Echte doorzichtigheid (vereist X Composiet uitbreiding)"
+
+#: src/aosd/aosd_ui.cc:756
+msgid "Composite extension not loaded"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:764
+msgid "Composite extension not available"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:781
+#, c-format
+msgid "<span font_desc='%s'>Audacious OSD</span>"
+msgstr "<span font_desc='%s'>Audacious OSD</span>"
+
+#: src/aosd/aosd_ui.cc:844
+msgid "Position"
+msgstr "Positie"
+
+#: src/aosd/aosd_ui.cc:849
+msgid "Animation"
+msgstr "Animatie"
+
+#: src/aosd/aosd_ui.cc:854
+msgid "Text"
+msgstr "Tekst"
+
+#: src/aosd/aosd_ui.cc:859
+msgid "Decoration"
+msgstr "Decoratie"
+
+#: src/aosd/aosd_ui.cc:864
+msgid "Trigger"
+msgstr "Trekker"
+
+#: src/aosd/aosd_ui.cc:869
+msgid "Misc"
+msgstr "Divers"
+
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Test"
+
+#: src/asx3/asx3.cc:35
+msgid "ASXv3 Playlists"
+msgstr "ASXv3 Afspeellijsten"
+
+#: src/asx/asx.cc:33
+msgid "ASXv1/ASXv2 Playlists"
+msgstr "ASXv1/ASXv2 Afspeellijsten"
+
+#: src/audpl/audpl.cc:33
+msgid "Audacious Playlists (audpl)"
+msgstr "Audacious Afspeellijsten (audpl)"
+
+#: src/blur_scope/blur_scope.cc:42
+msgid "<b>Color</b>"
+msgstr "<b>Kleur</b>"
+
+#: src/blur_scope/blur_scope.cc:58
+msgid "Blur Scope"
+msgstr ""
+
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr ""
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Presets:"
+
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
+msgstr ""
+
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr "Knip frequentie:"
+
+#: src/cairo-spectrum/cairo-spectrum.cc:41
+msgid "Spectrum Analyzer"
+msgstr "Spectrum Analyseerder"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Audio CD Plugin"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
+msgid ""
+"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
+"\n"
+"Many thanks to libcdio developers <http://www.gnu.org/software/libcdio/>\n"
+"and to libcddb developers <http://libcddb.sourceforge.net/>.\n"
+"\n"
+"Also thank you to Tony Vroon for mentoring and guiding me.\n"
+"\n"
+"This was a Google Summer of Code 2007 project."
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:137
+msgid "<b>Device</b>"
+msgstr "<b>Apparaat</b>"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:138
+msgid "Read speed:"
+msgstr "Lees snelheid:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:141
+msgid "Override device:"
+msgstr "Override apparaat:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:143
+msgid "<b>Metadata</b>"
+msgstr "<b>Metadata</b>"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:144
+msgid "Use CD-Text"
+msgstr "Gebruik CD-Tekst"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:146
+msgid "Use CDDB"
+msgstr "Gebruik CDDB"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:148
+msgid "Use HTTP instead of CDDBP"
+msgstr "Gebruik HTTP in plaats van CDDBP"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:151
+msgid "Server:"
+msgstr "Server:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:155
+msgid "Path:"
+msgstr "Pad:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:159
+msgid "Port:"
+msgstr "Poort:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:246
+msgid "Failed to initialize cdio subsystem."
+msgstr "Fout bij initialiseren cdio subsysteem."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:281
+#, c-format
+msgid "Invalid URI %s."
+msgstr "Ongeldige URI %s"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:283
+#, c-format
+msgid "Track %d not found."
+msgstr "Track %d niet gevonden."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:285
+#, c-format
+msgid "Track %d is a data track."
+msgstr "Track %d is alleen data."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:360
+msgid "Error reading audio CD."
+msgstr "Fout bij lezen audio CD"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:429
+msgid "Audio CD"
+msgstr "Audio CD"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
+#, c-format
+msgid "Failed to open CD device %s."
+msgstr "Het openen van CD apparaat %s is mislukt."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:472
+msgid "No audio capable CD drive found."
+msgstr "Geen CD speler met audio mogelijkheid gevonden."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:497
+msgid "Failed to finish initializing opened CD drive."
+msgstr "Het Initialiseren van de geopende CD Drive is mislukt."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:510
+msgid "Failed to retrieve first/last track number."
+msgstr "Het herstellen van de eerste/laatste tracknummer is mislukt."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:531
+#, c-format
+msgid "Cannot read start/end LSN for track %d."
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:613
+msgid "Failed to create the cddb connection."
+msgstr "Fout bij verbinden met de cddb"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:679
+msgid "Failed to query the CDDB server"
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:681
+#, c-format
+msgid "Failed to query the CDDB server: %s"
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:705
+#, c-format
+msgid "Failed to read the cddb info: %s"
+msgstr "Fout bij lezen van cddb info: %s"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:765
+msgid "Drive is empty."
+msgstr "Schijfstation is leeg."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:767
+msgid "Unsupported disk type."
+msgstr "Niet-ondersteund schijftype."
+
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Audio CD Menu Items"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
+msgid "Play CD"
+msgstr "CD afspelen"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
+msgid "Add CD"
+msgstr "CD toevoegen"
+
+#: src/compressor/compressor.cc:45
+msgid "<b>Compression</b>"
+msgstr "<b>Compressie</b>"
+
+#: src/compressor/compressor.cc:46
+msgid "Center volume:"
+msgstr "Centrum volume:"
+
+#: src/compressor/compressor.cc:49
+msgid "Dynamic range:"
+msgstr "Dynamisch bereik:"
+
+#: src/compressor/compressor.cc:57
+msgid ""
+"Dynamic Range Compression Plugin for Audacious\n"
+"Copyright 2010-2014 John Lindgren"
+msgstr ""
+
+#: src/compressor/compressor.cc:64
+msgid "Dynamic Range Compressor"
+msgstr ""
+
+#: src/console/plugin.cc:15
+msgid ""
+"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
+"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
+"\n"
+"Audacious plugin by:\n"
+"William Pitcock <nenolod at dereferenced.org>\n"
+"Shay Green <gblargg at gmail.com>"
+msgstr ""
+
+#: src/console/plugin.cc:30
+msgid "Bass:"
+msgstr "Bas:"
+
+#: src/console/plugin.cc:33
+msgid "Treble:"
+msgstr "Treble:"
+
+#: src/console/plugin.cc:36
+msgid "Echo:"
+msgstr "Echo:"
+
+#: src/console/plugin.cc:39
+msgid "Default song length:"
+msgstr "Standaard lied lengte:"
+
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
+msgid "<b>Resampling</b>"
+msgstr ""
+
+#: src/console/plugin.cc:43
+msgid "Enable audio resampling"
+msgstr ""
+
+#: src/console/plugin.cc:49
+msgid "<b>SPC</b>"
+msgstr "<b>SPC</b>"
+
+#: src/console/plugin.cc:50
+msgid "Ignore length from SPC tags"
+msgstr "Negeer lengte van SPC tags"
+
+#: src/console/plugin.cc:52
+msgid "Increase reverb"
+msgstr ""
+
+#: src/console/plugin.h:26
+msgid "Game Console Music Decoder"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:131
+msgid ""
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:44
+msgid ""
+"Crossfade Plugin for Audacious\n"
+"Copyright 2010-2014 John Lindgren"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:48
+msgid "<b>Crossfade</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
+msgid "Overlap:"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Tip</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
+msgid "Crossfade"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
+msgid "<b>Crystalizer</b>"
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
+msgid "Intensity:"
+msgstr "Intensiteit:"
+
+#: src/crystalizer/crystalizer.cc:43
+msgid "Crystalizer"
+msgstr ""
+
+#: src/cue/cue.cc:37
+msgid "Cue Sheet Plugin"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Verwijder Bestanden"
+
+#: src/delete-files/delete-files.cc:75
+#, c-format
+msgid "Error moving %s to trash: %s."
+msgstr "Fout bij verplaatsen %s naar de prullenbak: %s."
+
+#: src/delete-files/delete-files.cc:86
+#, c-format
+msgid "Error deleting %s: %s."
+msgstr "Fout bij verwijderen %s: %s."
+
+#: src/delete-files/delete-files.cc:117
+#, c-format
+msgid "Error deleting %s: not a local file."
+msgstr "Fout bij verwijderen %s: is geen lokaal bestand."
+
+#: src/delete-files/delete-files.cc:134
+msgid "Do you want to move the selected files to the trash?"
+msgstr "Wilt u de geselecteerde bestanden verplaatsen naar de prullenbak?"
+
+#: src/delete-files/delete-files.cc:135
+msgid "Move to Trash"
+msgstr "Verplaats naar Prullenbak"
+
+#: src/delete-files/delete-files.cc:140
+msgid "Do you want to permanently delete the selected files?"
+msgstr "Wilt u de geselecteerde bestanden definitief verwijderen?"
+
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
+msgid "Delete"
+msgstr "Verwijder"
+
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
+msgid "Cancel"
+msgstr "Annuleren"
+
+#: src/delete-files/delete-files.cc:166
+msgid "Delete Selected Files"
+msgstr "Verwijder Geselcteerde Bestanden"
+
+#: src/delete-files/delete-files.cc:181
+msgid "<b>Delete Method</b>"
+msgstr "<b>Verwijder Methode</b>"
+
+#: src/delete-files/delete-files.cc:182
+msgid "Move to trash instead of deleting immediately"
+msgstr "Verplaats naar de prullenbak ipv onmiddellijk verwijderen"
+
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
+msgid "<b>Echo</b>"
+msgstr "<b>Echo</b>"
+
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
+msgid "Delay:"
+msgstr "Vertraging:"
+
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
+msgid "ms"
+msgstr "ms"
+
+#: src/echo_plugin/echo.cc:25
+msgid "Feedback:"
+msgstr "Terugkoppeling:"
+
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
+msgid "Volume:"
+msgstr "Volume:"
+
+#: src/echo_plugin/echo.cc:39
+msgid "Echo"
+msgstr "Echo"
+
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg Plugin"
+
+#: src/ffaudio/ffaudio-core.cc:571
+msgid ""
+"Multi-format audio decoding plugin for Audacious using\n"
+"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
+"\n"
+"Audacious plugin by:\n"
+"William Pitcock <nenolod at nenolod.net>\n"
+"Matti Hämäläinen <ccr at tnsp.org>"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "FileWriter Plugin"
+
+#: src/filewriter/filewriter.cc:386
+msgid "Output file format:"
+msgstr "Uitvoer bestandsformaat:"
+
+#: src/filewriter/filewriter.cc:403
+msgid "Configure"
+msgstr "Configureer"
+
+#: src/filewriter/filewriter.cc:413
+msgid "Save into original directory"
+msgstr "Opslaan in oorspronkelijke map"
+
+#: src/filewriter/filewriter.cc:417
+msgid "Save into custom directory"
+msgstr "Opslaan in aangepaste map"
+
+#: src/filewriter/filewriter.cc:427
+msgid "Output file folder:"
+msgstr "Bestandsuitvoer map:"
+
+#: src/filewriter/filewriter.cc:431
+msgid "Pick a folder"
+msgstr "Kies een map"
+
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Oorspronkelijke bestandslabel"
+
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Oorspronkelijke bestandsnaam"
+
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "Omvat originele bestandsnaam extensie"
+
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:484
+msgid ""
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
+"USA."
+msgstr ""
+
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
+msgid "Auto"
+msgstr "Auto"
+
+#: src/filewriter/mp3.cc:40
+msgid "Joint Stereo"
+msgstr "Samengevoegd stereo"
+
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
+msgid "Stereo"
+msgstr "Stereo"
+
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
+msgid "Mono"
+msgstr "Mono"
+
+#: src/filewriter/mp3.cc:657
+msgid "MP3 Configuration"
+msgstr "MP3 Configuratie"
+
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_Ok"
+
+#: src/filewriter/mp3.cc:681
+msgid "Algorithm Quality:"
+msgstr "Algoritme kwaliteit:"
+
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr "Sample Rate Uitvoer:"
+
+#: src/filewriter/mp3.cc:733
+msgid "(Hz)"
+msgstr "(Hz)"
+
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "Bitrate / Compressie Ratio:"
+
+#: src/filewriter/mp3.cc:764
+msgid "Bitrate (kbps):"
+msgstr "Bitrate (kbps):"
+
+#: src/filewriter/mp3.cc:796
+msgid "Compression ratio:"
+msgstr "Compressie ratio:"
+
+#: src/filewriter/mp3.cc:820
+msgid "Audio Mode:"
+msgstr "Audio Modus:"
+
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr "Diversen:"
+
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
+
+#: src/filewriter/mp3.cc:867
+msgid "Error protection"
+msgstr "Foutbescherming"
+
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
+msgid "Quality"
+msgstr "Kwaliteit"
+
+#: src/filewriter/mp3.cc:888
+msgid "Enable VBR/ABR"
+msgstr "VBR/ABR inschakelen"
+
+#: src/filewriter/mp3.cc:898
+msgid "Type:"
+msgstr "Type:"
+
+#: src/filewriter/mp3.cc:931
+msgid "VBR Options:"
+msgstr "VBR Opties:"
+
+#: src/filewriter/mp3.cc:947
+msgid "Minimum bitrate (kbps):"
+msgstr "Minimale bitrate (kbps):"
+
+#: src/filewriter/mp3.cc:973
+msgid "Maximum bitrate (kbps):"
+msgstr "Maximale bitrate (kbps):"
+
+#: src/filewriter/mp3.cc:995
+msgid "Strictly enforce minimum bitrate"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1007
+msgid "ABR Options:"
+msgstr "ABR Opties:"
+
+#: src/filewriter/mp3.cc:1017
+msgid "Average bitrate (kbps):"
+msgstr "Gemiddelde bitrate (kbps):"
+
+#: src/filewriter/mp3.cc:1044
+msgid "VBR quality level:"
+msgstr "VBR kwaliteitsniveau:"
+
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1076
+msgid "VBR/ABR"
+msgstr "VBR/ABR"
+
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1097
+msgid "Mark as copyright"
+msgstr "Markeer als auteursrecht"
+
+#: src/filewriter/mp3.cc:1108
+msgid "Mark as original"
+msgstr "Markeer als origineel"
+
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr "ID3 Parameters:"
+
+#: src/filewriter/mp3.cc:1131
+msgid "Force addition of version 2 tag"
+msgstr "Forceer het toevoegen van een versie 2 tag"
+
+#: src/filewriter/mp3.cc:1141
+msgid "Only add v1 tag"
+msgstr "Alleen v1 tag toevoegen"
+
+#: src/filewriter/mp3.cc:1148
+msgid "Only add v2 tag"
+msgstr "Alleen v2 tag toevoegen"
+
+#: src/filewriter/mp3.cc:1169
+msgid "Tags"
+msgstr "Tags"
+
+#: src/filewriter/vorbis.cc:196
+msgid "Vorbis Encoder Configuration"
+msgstr "Vorbis Encoder Configuratie"
+
+#: src/filewriter/vorbis.cc:219
+msgid "Quality level (0 - 10):"
+msgstr "Kwaliteitsniveau (0 - 10):"
+
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC Decoder"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
+msgid "lossless"
+msgstr "lossless"
+
+#: src/flacng/plugin.cc:169
+msgid ""
+"Original code by\n"
+"Ralf Ertzinger <ralf at skytale.net>\n"
+"\n"
+"http://www.skytale.net/projects/bmp-flac2/"
+msgstr ""
+"Originele code door\n"
+"Ralf Ertzinger <ralf at skytale.net>\n"
+"\n"
+"http://www.skytale.net/projects/bmp-flac2/"
+
+#: src/gio/gio.cc:34
+msgid ""
+"GIO Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren"
+msgstr ""
+"GIO Plugin voor Audicious\n"
+"Copyright 2009-2012 John Lindgren"
+
+#: src/gio/gio.cc:42
+msgid "GIO Plugin"
+msgstr "GIO Plugin"
+
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:62
+msgid "OpenGL Spectrum Analyzer"
+msgstr "OpenGL Spectrum Analyseerder"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "GNOME Snelkoppeling"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+
+#: src/gtkui/columns.cc:35
+msgid "Entry number"
+msgstr "Invoer nummer"
+
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
+msgid "Title"
+msgstr "Titel"
+
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
+msgid "Artist"
+msgstr "Artiest"
+
+#: src/gtkui/columns.cc:38
+msgid "Year"
+msgstr "Jaar"
+
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
+msgid "Album"
+msgstr "Album"
+
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Album Artiest"
+
+#: src/gtkui/columns.cc:41
+msgid "Track"
+msgstr "Nummer"
+
+#: src/gtkui/columns.cc:42
+msgid "Genre"
+msgstr "Genre"
+
+#: src/gtkui/columns.cc:43
+msgid "Queue position"
+msgstr "Positie in wachtrij"
+
+#: src/gtkui/columns.cc:44
+msgid "Length"
+msgstr "Lengte"
+
+#: src/gtkui/columns.cc:45
+msgid "File path"
+msgstr "Bestandspad"
+
+#: src/gtkui/columns.cc:47
+msgid "Custom title"
+msgstr "Aangepaste titel"
+
+#: src/gtkui/columns.cc:48
+msgid "Bitrate"
+msgstr "Bitrate"
+
+#: src/gtkui/columns.cc:308
+msgid "Available columns"
+msgstr "Beschikbare kolommen"
+
+#: src/gtkui/columns.cc:334
+msgid "Displayed columns"
+msgstr "Weergegeven kolommen"
+
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Zoek hulpmiddel"
+
+#: src/gtkui/layout.cc:167
+msgid "Dock at Left"
+msgstr "Vastkoppelen aan linkerzijde"
+
+#: src/gtkui/layout.cc:167
+msgid "Dock at Right"
+msgstr "Vastkoppelen aan rechterzijde"
+
+#: src/gtkui/layout.cc:168
+msgid "Dock at Top"
+msgstr "Vastkoppelen aan bovenkant"
+
+#: src/gtkui/layout.cc:168
+msgid "Dock at Bottom"
+msgstr "Vastkoppelen aan onderkant"
+
+#: src/gtkui/layout.cc:168
+msgid "Undock"
+msgstr "Loskoppelen"
+
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
+msgid "Disable"
+msgstr "Uitschakelen"
+
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
+msgid "_Open Files ..."
+msgstr "_Open bestanden ..."
+
+#: src/gtkui/menus.cc:127
+msgid "Open _URL ..."
+msgstr "Open _URL ..."
+
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
+msgid "_Add Files ..."
+msgstr "_Bestanden Toevoegen ..."
+
+#: src/gtkui/menus.cc:129
+msgid "Add U_RL ..."
+msgstr "U_RL toevoegen ..."
+
+#: src/gtkui/menus.cc:131
+msgid "Search _Library"
+msgstr "Doorzoek_Bibliotheek"
+
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
+msgid "A_bout ..."
+msgstr ""
+
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
+msgid "_Settings ..."
+msgstr "In_stellingen ..."
+
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
+msgid "_Quit"
+msgstr "_Afsluiten"
+
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
+msgid "_Play"
+msgstr ""
+
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
+msgid "Paus_e"
+msgstr ""
+
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
+msgid "_Stop"
+msgstr "_Stop"
+
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
+msgid "Pre_vious"
+msgstr "Vo_rige"
+
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
+msgid "_Next"
+msgstr "_Volgende"
+
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
+msgid "_Repeat"
+msgstr "_Herhaal"
+
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
+msgid "S_huffle"
+msgstr ""
+
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
+msgid "N_o Playlist Advance"
+msgstr ""
+
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
+msgid "Stop A_fter This Song"
+msgstr ""
+
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
+msgid "Song _Info ..."
+msgstr "Lied_Informatie ..."
+
+#: src/gtkui/menus.cc:151
+msgid "Jump to _Time ..."
+msgstr "Spring naar _Tijd ..."
+
+#: src/gtkui/menus.cc:152
+msgid "_Jump to Song ..."
+msgstr ""
+
+#: src/gtkui/menus.cc:154
+msgid "Set Repeat Point _A"
+msgstr ""
+
+#: src/gtkui/menus.cc:155
+msgid "Set Repeat Point _B"
+msgstr ""
+
+#: src/gtkui/menus.cc:156
+msgid "_Clear Repeat Points"
+msgstr ""
+
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
+msgid "By _Title"
+msgstr "Volgens _Titel"
+
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr ""
+
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
+msgid "By File _Path"
+msgstr ""
+
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
+msgid "By Track _Number"
+msgstr "Volgens _Nummer"
+
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
+msgid "By _Artist"
+msgstr "Volgens _Artiest"
+
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
+msgid "By Al_bum"
+msgstr ""
+
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
+msgid "By Release _Date"
+msgstr "Volgens uitgave_datum"
+
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
+msgid "By _Length"
+msgstr ""
+
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
+msgid "By _File Path"
+msgstr "Volgens _Bestandspad"
+
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
+msgid "By _Custom Title"
+msgstr "Volgens _Aangepaste titel"
+
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
+msgid "R_everse Order"
+msgstr "R_angschikking omkeren"
+
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
+msgid "_Random Order"
+msgstr "_Willekeurige volgorde"
+
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
+
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
+msgid "_Refresh"
+msgstr "_Vernieuw"
+
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
+msgid "_Sort"
+msgstr "_Sorteer"
+
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
+msgid "Sort Se_lected"
+msgstr ""
+
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
+msgid "Remove _Duplicates"
+msgstr ""
+
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
+msgid "Remove _Unavailable Files"
+msgstr ""
+
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
+msgid "_New"
+msgstr "_Nieuw"
+
+#: src/gtkui/menus.cc:207
+msgid "Ren_ame ..."
+msgstr ""
+
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
+msgid "Remo_ve"
+msgstr "_Verwijder"
+
+#: src/gtkui/menus.cc:210
+msgid "_Import ..."
+msgstr "_Importeer ..."
+
+#: src/gtkui/menus.cc:211
+msgid "_Export ..."
+msgstr "_Exporteer ..."
+
+#: src/gtkui/menus.cc:213
+msgid "Playlist _Manager ..."
+msgstr ""
+
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
+msgid "_Queue Manager ..."
+msgstr ""
+
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
+msgid "Volume _Up"
+msgstr "Volume _Hoger"
+
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
+msgid "Volume _Down"
+msgstr "Volume _Lager"
+
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
+msgid "_Equalizer"
+msgstr "_Equalizer"
+
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
+msgid "E_ffects ..."
+msgstr "E_ffecten ..."
+
+#: src/gtkui/menus.cc:227
+msgid "Show _Menu Bar"
+msgstr "Toon _Menubalk"
+
+#: src/gtkui/menus.cc:228
+msgid "Show I_nfo Bar"
+msgstr "Show I_nfobalk"
+
+#: src/gtkui/menus.cc:229
+msgid "Show Info Bar Vis_ualization"
+msgstr ""
+
+#: src/gtkui/menus.cc:230
+msgid "Show _Status Bar"
+msgstr "Toon _Statusbalk"
+
+#: src/gtkui/menus.cc:232
+msgid "Show _Remaining Time"
+msgstr ""
+
+#: src/gtkui/menus.cc:234
+msgid "_Visualizations ..."
+msgstr ""
+
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
+msgid "_File"
+msgstr "_Bestand"
+
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
+msgid "_Playback"
+msgstr ""
+
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
+msgid "P_laylist"
+msgstr "Spee_llijst"
+
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
+msgid "_Services"
+msgstr ""
+
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
+msgid "_Output"
+msgstr "_Uitvoer"
+
+#: src/gtkui/menus.cc:243
+msgid "_View"
+msgstr "_Bekijk"
+
+#: src/gtkui/menus.cc:248
+msgid "_Queue/Unqueue"
+msgstr "In/uit _wachtrij"
+
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
+msgid "Cu_t"
+msgstr ""
+
+#: src/gtkui/menus.cc:254
+msgid "_Copy"
+msgstr "_Kopieer"
+
+#: src/gtkui/menus.cc:255
+msgid "_Paste"
+msgstr "_Plak"
+
+#: src/gtkui/menus.cc:256
+msgid "Select _All"
+msgstr "Selecteer _Alles"
+
+#: src/gtkui/menus.cc:263
+msgid "_Rename ..."
+msgstr "He_rnoem ..."
+
+#: src/gtkui/settings.cc:35
+msgid "<b>Playlist Tabs</b>"
+msgstr ""
+
+#: src/gtkui/settings.cc:36
+msgid "Always show tabs"
+msgstr "Laat tabbladen altijd zien"
+
+#: src/gtkui/settings.cc:38
+msgid "Show entry counts"
+msgstr "Toon entree tellingen"
+
+#: src/gtkui/settings.cc:40
+msgid "Show close buttons"
+msgstr "Toon sluitknoppen"
+
+#: src/gtkui/settings.cc:42
+msgid "<b>Playlist Columns</b>"
+msgstr "<b>Afspeellijst Kolommen</b>"
+
+#: src/gtkui/settings.cc:44
+msgid "Show column headers"
+msgstr "Toon kolomkoppen"
+
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
+msgid "<b>Miscellaneous</b>"
+msgstr "<b>Diversen</b>"
+
+#: src/gtkui/settings.cc:47
+msgid "Arrow keys seek by:"
+msgstr ""
+
+#: src/gtkui/settings.cc:50
+msgid "Scroll on song change"
+msgstr ""
+
+#: src/gtkui/ui_gtk.cc:71
+msgid "GTK Interface"
+msgstr "GTK Interface"
+
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
+#, c-format
+msgid "%s - Audacious"
+msgstr "%s - Audacious"
+
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
+msgid "Buffering ..."
+msgstr ""
+
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
+msgid "Audacious"
+msgstr "Audacious"
+
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
+#, c-format
+msgid "%d channel"
+msgid_plural "%d channels"
+msgstr[0] "%d kanaal"
+msgstr[1] "%d kanalen"
+
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
+#, c-format
+msgid "%d kbps"
+msgstr "%d kbps"
+
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr ""
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Speellijst modus."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr ""
+
+#: src/hotkey/gui.cc:71
+msgid "Previous track"
+msgstr "Vorig liedje"
+
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
+msgid "Play"
+msgstr "Afspelen"
+
+#: src/hotkey/gui.cc:73
+msgid "Pause/Resume"
+msgstr "Pauzeer/Hervat"
+
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
+msgid "Stop"
+msgstr "Stop"
+
+#: src/hotkey/gui.cc:75
+msgid "Next track"
+msgstr "Volgend liedje"
+
+#: src/hotkey/gui.cc:76
+msgid "Forward 5 seconds"
+msgstr "Vijf seconden naar voren"
+
+#: src/hotkey/gui.cc:77
+msgid "Rewind 5 seconds"
+msgstr "Vijf seconden terug"
+
+#: src/hotkey/gui.cc:78
+msgid "Mute"
+msgstr "Dempen"
+
+#: src/hotkey/gui.cc:79
+msgid "Volume up"
+msgstr "Volume Harder"
+
+#: src/hotkey/gui.cc:80
+msgid "Volume down"
+msgstr "Volume zachter"
+
+#: src/hotkey/gui.cc:81
+msgid "Jump to file"
+msgstr "Spring naar bestand"
+
+#: src/hotkey/gui.cc:82
+msgid "Toggle player window(s)"
+msgstr ""
+
+#: src/hotkey/gui.cc:83
+msgid "Show On-Screen-Display"
+msgstr "Show On-Screen-Display"
+
+#: src/hotkey/gui.cc:84
+msgid "Toggle repeat"
+msgstr "Herhaal Aan/Uit"
+
+#: src/hotkey/gui.cc:85
+msgid "Toggle shuffle"
+msgstr "Shuffle Aan/Uit"
+
+#: src/hotkey/gui.cc:86
+msgid "Toggle stop after current"
+msgstr ""
+
+#: src/hotkey/gui.cc:87
+msgid "Raise player window(s)"
+msgstr ""
+
+#: src/hotkey/gui.cc:97
+msgid "(none)"
+msgstr "(geen)"
+
+#: src/hotkey/gui.cc:234
+msgid ""
+"It is not recommended to bind the primary mouse buttons without "
+"modificators.\n"
+"\n"
+"Do you want to continue?"
+msgstr ""
+
+#: src/hotkey/gui.cc:236
+msgid "Binding mouse buttons"
+msgstr ""
+
+#: src/hotkey/gui.cc:391
+msgid ""
+"Press a key combination inside a text field.\n"
+"You can also bind mouse buttons."
+msgstr ""
+
+#: src/hotkey/gui.cc:396
+msgid "Hotkeys:"
+msgstr "Sneltoetsen:"
+
+#: src/hotkey/gui.cc:413
+msgid "<b>Action:</b>"
+msgstr "<b>Actie:</b>"
+
+#: src/hotkey/gui.cc:420
+msgid "<b>Key Binding:</b>"
+msgstr ""
+
+#: src/hotkey/gui.cc:468
+msgid "_Add"
+msgstr "_Toevoegen"
+
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Globale Sneltoetsen"
+
+#: src/hotkey/plugin.cc:79
+msgid ""
+"Global Hotkey Plugin\n"
+"Control the player with global key combinations or multimedia keys.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>\n"
+"\n"
+"Contributers include:\n"
+"Copyright (C) 2006-2007 Vladimir Paskov <vlado.paskov at gmail.com>\n"
+"Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>,\n"
+" Bryn Davies <curious at ihug.com.au>,\n"
+" Jonathan A. Davis <davis at jdhouse.org>,\n"
+" Jeremy Tan <nsx at nsx.homeip.net>"
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK Uitvoer"
+
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
+msgid ""
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
+msgstr ""
+
+#: src/ladspa/plugin.cc:414
+#, c-format
+msgid "%s Settings"
+msgstr "%s Instellingen"
+
+#: src/ladspa/plugin.cc:478
+msgid "Module paths:"
+msgstr "Module paden:"
+
+#: src/ladspa/plugin.cc:483
+msgid ""
+"<small>Separate multiple paths with a colon.\n"
+"These paths are searched in addition to LADSPA_PATH.\n"
+"After adding new paths, press Enter to scan for new plugins.</small>"
+msgstr ""
+
+#: src/ladspa/plugin.cc:499
+msgid "Available plugins:"
+msgstr "Beschikbare plugins:"
+
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
+msgid "Enable"
+msgstr "Inschakelen"
+
+#: src/ladspa/plugin.cc:518
+msgid "Enabled plugins:"
+msgstr "Ingeschakelde plugins:"
+
+#: src/ladspa/plugin.cc:534
+msgid "Settings"
+msgstr "Instellingen"
+
+#: src/ladspa/plugin.cc:551
+msgid ""
+"LADSPA Host for Audacious\n"
+"Copyright 2011 John Lindgren"
+msgstr ""
+"LADSPA Host voor Audacious\n"
+"Copyright 2011 John Lindgren"
+
+#: src/ladspa/plugin.h:78
+msgid "LADSPA Host"
+msgstr "LADSPA Host"
+
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC Plugin"
+
+#: src/lirc/lirc.cc:381
+msgid ""
+"A simple plugin to control Audacious using the LIRC remote control daemon\n"
+"\n"
+"Adapted for Audacious by:\n"
+"Tony Vroon <chainsaw at gentoo.org>\n"
+"Joonas Harjumäki <jharjuma at gmail.com>\n"
+"\n"
+"Based on the XMMS LIRC plugin by:\n"
+"Carl van Schaik <carl at leg.uct.ac.za>\n"
+"Christoph Bartelmus <xmms at bartelmus.de>\n"
+"Andrew O. Shadoura <bugzilla at tut.by>\n"
+"\n"
+"For more information about LIRC, see http://lirc.org."
+msgstr ""
+
+#: src/lirc/lirc.cc:392
+msgid "<b>Connection</b>"
+msgstr "<b>Verbinding</b>"
+
+#: src/lirc/lirc.cc:393
+msgid "Reconnect to LIRC server"
+msgstr ""
+
+#: src/lirc/lirc.cc:395
+msgid "Wait before reconnecting:"
+msgstr ""
+
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki Plugin"
+
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
+msgid "No lyrics available"
+msgstr "Geen song-tekst beschikbaar"
+
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Fout"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
+#, c-format
+msgid "Unable to fetch %s"
+msgstr ""
+
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
+#, c-format
+msgid "Unable to parse %s"
+msgstr ""
+
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
+msgid "Looking for lyrics ..."
+msgstr "Zoeken naar teksten ..."
+
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Missing song metadata"
+msgstr "Ontbrekende metadata"
+
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
+msgid "Connecting to lyrics.wikia.com ..."
+msgstr "Verbinden met lyrics.wikia.com ..."
+
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
+
+#: src/m3u/m3u.cc:32
+msgid "M3U Playlists"
+msgstr "M3U Afspeellijsten"
+
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr ""
+
+#: src/metronom/metronom.cc:147
+#, c-format
+msgid "Tact generator: %d bpm"
+msgstr ""
+
+#: src/metronom/metronom.cc:149
+#, c-format
+msgid "Tact generator: %d bpm %d/%d"
+msgstr ""
+
+#: src/metronom/metronom.cc:237
+msgid ""
+"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
+"\n"
+"To use it, add a URL: tact://beats*num/den\n"
+"e.g. tact://77 to play 77 beats per minute\n"
+"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
+msgstr ""
+
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Kanaal Mixer"
+
+#: src/mixer/mixer.cc:202
+msgid ""
+"Channel Mixer Plugin for Audacious\n"
+"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
+msgstr ""
+
+#: src/mixer/mixer.cc:206
+msgid "<b>Channel Mixer</b>"
+msgstr "<b>Kanalen Mixer</b>"
+
+#: src/mixer/mixer.cc:207
+msgid "Output channels:"
+msgstr "Uitvoerkanalen:"
+
+#: src/mms/mms.cc:35
+msgid "MMS Plugin"
+msgstr "MMS Plugin"
+
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlus (Module Player)"
+
+#: src/modplug/plugin_main.cc:53
+msgid "<b>Resolution</b>"
+msgstr "<b>Resolutie</b>"
+
+#: src/modplug/plugin_main.cc:54
+msgid "8-bit"
+msgstr "8-bit"
+
+#: src/modplug/plugin_main.cc:55
+msgid "16-bit"
+msgstr "16-bit"
+
+#: src/modplug/plugin_main.cc:56
+msgid "<b>Channels</b>"
+msgstr "<b>Kanalen</b>"
+
+#: src/modplug/plugin_main.cc:60
+msgid "Nearest (fastest)"
+msgstr "Dichtstbijzijnd (snelst)"
+
+#: src/modplug/plugin_main.cc:61
+msgid "Linear (fast)"
+msgstr "Lineair (snel)"
+
+#: src/modplug/plugin_main.cc:62
+msgid "Spline (good)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:63
+msgid "Polyphase (best)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:65
+msgid "22 kHz"
+msgstr "22 kHz"
+
+#: src/modplug/plugin_main.cc:66
+msgid "44 kHz"
+msgstr "44 kHz"
+
+#: src/modplug/plugin_main.cc:67
+msgid "48 kHz"
+msgstr "48 kHz"
+
+#: src/modplug/plugin_main.cc:68
+msgid "96 kHz"
+msgstr "96 kHz"
+
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
+msgid "Level:"
+msgstr "Level:"
+
+#: src/modplug/plugin_main.cc:78
+msgid "Cutoff:"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:91
+msgid "<b>Reverb</b>"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:94
+msgid "<b>Bass Boost</b>"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:97
+msgid "<b>Surround</b>"
+msgstr "<b>Surround</b>"
+
+#: src/modplug/plugin_main.cc:100
+msgid "<b>Preamp</b>"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:107
+msgid "Oversample"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:108
+msgid "Noise reduction"
+msgstr "Ruisonderdrukking"
+
+#: src/modplug/plugin_main.cc:109
+msgid "Play Amiga MODs"
+msgstr "Speel Amiga MOD's"
+
+#: src/modplug/plugin_main.cc:110
+msgid "<b>Repeat</b>"
+msgstr "<b>Herhaal</b>"
+
+#: src/modplug/plugin_main.cc:111
+msgid "Repeat count:"
+msgstr "Herhaal teller:"
+
+#: src/modplug/plugin_main.cc:112
+msgid "To repeat forever, set the repeat count to -1."
+msgstr ""
+
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
+
+#: src/mpg123/mpg123.cc:54
+msgid "MPG123 Plugin"
+msgstr "MPG123 Plugin"
+
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Geadvanceerd</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
+
+#: src/mpris2/plugin.cc:39
+msgid "MPRIS 2 Server"
+msgstr "MPRIS 2 Server"
+
+#: src/neon/neon.cc:97
+msgid "Neon HTTP/HTTPS Plugin"
+msgstr "Neon HTTP/HTTPS Plugin"
+
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Onbekende HTTP fout"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Teveel redirects"
+
+#: src/notify/event.cc:64
+msgid "Stopped"
+msgstr "Gestopt"
+
+#: src/notify/event.cc:64
+msgid "Audacious is not playing."
+msgstr "Audacious is niets aan het afspelen."
+
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Desktop Notificaties"
+
+#: src/notify/notify.cc:60
+msgid ""
+"Desktop Notifications Plugin for Audacious\n"
+"Copyright (C) 2010 Maximilian Bogner\n"
+"Copyright (C) 2011-2013 John Lindgren and Jean-Alexandre Anglès d'Auriac\n"
+"\n"
+"This plugin is free software: you can redistribute it and/or modify it under "
+"the terms of the GNU General Public License as published by the Free "
+"Software Foundation, either version 3 of the License, or (at your option) "
+"any later version.\n"
+"\n"
+"This plugin 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, see <http://www.gnu.org/licenses/>."
+msgstr ""
+
+#: src/notify/notify.cc:110
+msgid "Show playback controls"
+msgstr ""
+
+#: src/notify/notify.cc:112
+msgid "Always show notification"
+msgstr "Laat altijd de notificaties zien"
+
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
+
+#: src/notify/osd.cc:58
+msgid "Show"
+msgstr "Laat zien"
+
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
+msgid "Pause"
+msgstr "Pauze"
+
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
+msgid "Next"
+msgstr "Volgende"
+
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 Uitvoer"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "OSS3 Uitvoer"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Standaard Apparaat"
+
+#: src/oss4/plugin.cc:77
+msgid "Audio device:"
+msgstr "Audio apparaat:"
+
+#: src/oss4/plugin.cc:80
+msgid "Use alternate device:"
+msgstr "Gebruik alternatief apparaat:"
+
+#: src/oss4/plugin.cc:84
+msgid "Save volume between sessions."
+msgstr "Bewaar het volume tussen twee sessies."
+
+#: src/oss4/plugin.cc:86
+msgid "Enable format conversions made by the OSS software."
+msgstr ""
+
+#: src/oss4/plugin.cc:88
+msgid "Enable exclusive mode to prevent virtual mixing."
+msgstr ""
+
+#: src/oss4/plugin.cc:100
+msgid ""
+"OSS4 Output Plugin for Audacious\n"
+"Copyright 2010-2012 MichaÅ Lipski\n"
+"\n"
+"I would like to thank people on #audacious, especially Tony Vroon and John "
+"Lindgren and of course the authors of the previous OSS plugin."
+msgstr ""
+"OSS4 Output Plugin voor Audacious\n"
+"Copyright 2010-2012 MichaÅ Lipski\n"
+"\n"
+"Ik wil graag de mensen op #audacious bedanken. Speciaal Tony Vroon en John "
+"Lindgren en natuurlijk de auteurs van de vorige OSS plugin."
+
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Invoer"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Verwijderen"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
+
+#: src/pls/pls.cc:35
+msgid "PLS Playlists"
+msgstr "PLS Afspeellijsten"
+
+#: src/psf/plugin.cc:45
+msgid "OpenPSF PSF1/PSF2 Decoder"
+msgstr "OpenPSF PSF1/PSF2 Decoder"
+
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio Uitvoer"
+
+#: src/pulse_audio/pulse_audio.cc:611
+msgid ""
+"Audacious PulseAudio Output Plugin\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
+"USA."
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "QtMultimedia Uitvoer"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Werken ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Zoeken"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_Map Openen ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_Map Toevoegen ..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Bestanden Openen"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Bestanden Toevoegen"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Vorige"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Herhaal"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Shuffle"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Qt Interface"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr ""
+
+#: src/resample/resample.cc:183
+msgid ""
+"Sample Rate Converter Plugin for Audacious\n"
+"Copyright 2010-2012 John Lindgren"
+msgstr ""
+
+#: src/resample/resample.cc:187
+msgid "Skip/repeat samples"
+msgstr ""
+
+#: src/resample/resample.cc:188
+msgid "Linear interpolation"
+msgstr ""
+
+#: src/resample/resample.cc:189
+msgid "Fast sinc interpolation"
+msgstr ""
+
+#: src/resample/resample.cc:190
+msgid "Medium sinc interpolation"
+msgstr ""
+
+#: src/resample/resample.cc:191
+msgid "Best sinc interpolation"
+msgstr ""
+
+#: src/resample/resample.cc:195
+msgid "<b>Conversion</b>"
+msgstr "<b>Conversie</b>"
+
+#: src/resample/resample.cc:196
+msgid "Method:"
+msgstr "Methode:"
+
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
+msgid "Rate:"
+msgstr "Rate:"
+
+#: src/resample/resample.cc:202
+msgid "<b>Rate Mappings</b>"
+msgstr ""
+
+#: src/resample/resample.cc:203
+msgid "Use rate mappings"
+msgstr ""
+
+#: src/resample/resample.cc:205
+msgid "8 kHz:"
+msgstr "8 kHz:"
+
+#: src/resample/resample.cc:209
+msgid "16 kHz:"
+msgstr "16 kHz:"
+
+#: src/resample/resample.cc:213
+msgid "22.05 kHz:"
+msgstr "22.05 kHz:"
+
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32,0 kHz:"
+
+#: src/resample/resample.cc:221
+msgid "44.1 kHz:"
+msgstr "44.1 kHz:"
+
+#: src/resample/resample.cc:225
+msgid "48 kHz:"
+msgstr "48 kHz:"
+
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
+msgid "96 kHz:"
+msgstr "96 kHz:"
+
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
+msgid "192 kHz:"
+msgstr "192 kHz:"
+
+#: src/scrobbler2/config_window.cc:41
+#, c-format
+msgid "OK. Scrobbling for user: %s"
+msgstr "OK. Scrobbling voor gebruiker: %s"
+
+#: src/scrobbler2/config_window.cc:54
+msgid "Permission Denied"
+msgstr "Toegang Geweigerd"
+
+#: src/scrobbler2/config_window.cc:56
+msgid "Access the following link to allow Audacious to scrobble your plays:"
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:66
+msgid "Keep this window open and click 'Check Permission' again.\n"
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
+msgid ""
+"Don't worry. Your scrobbles are saved on your computer.\n"
+"They will be submitted as soon as Audacious is allowed to do so."
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:77
+msgid "Network Problem."
+msgstr "Netwerk Probleem."
+
+#: src/scrobbler2/config_window.cc:78
+msgid "There was a problem contacting Last.fm. Please try again later."
+msgstr ""
+"Er is een probleem om met Last.fm te verbinden. Probeer het later nog eens."
+
+#: src/scrobbler2/config_window.cc:110
+msgid "Checking..."
+msgstr "Controleren..."
+
+#: src/scrobbler2/config_window.cc:176
+msgid "C_heck Permission"
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:177
+msgid "_Revoke Permission"
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:220
+msgid ""
+"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
+msgid ""
+"The Scrobbler plugin could not be started.\n"
+"There might be a problem with your installation."
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:289
+msgid ""
+"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
+"\n"
+"Copyright © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com>\n"
+"\n"
+"Thanks to John Lindgren for giving me a hand at the beginning of this "
+"project.\n"
+"\n"
+msgstr ""
+
+#: src/scrobbler2/scrobbler_communication.cc:642
+msgid ""
+"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
+"Please check the Preferences for the Scrobbler plugin."
+msgstr ""
+
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL Uitvoer"
+
+#: src/sdlout/sdlout.cc:77
+msgid ""
+"SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"SDL Output Plugin voor Audacious\n"
+"Copyright 2010 John Lindgren"
+
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
+msgid "Library"
+msgstr "Bibliotheek"
+
+#: src/search-tool/search-tool.cc:394
+#, c-format
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d resultaat"
+msgstr[1] "%d resultaten"
+
+#: src/search-tool/search-tool.cc:400
+#, c-format
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d verborgen)"
+msgstr[1] "(%d verborgen)"
+
+#: src/search-tool/search-tool.cc:594
+#, c-format
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d lied"
+msgstr[1] "%d liedjes"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "van deze genre"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "op"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "volgens"
+
+#: src/search-tool/search-tool.cc:643
+msgid "_Create Playlist"
+msgstr "_Creëer Afspeellijst"
+
+#: src/search-tool/search-tool.cc:645
+msgid "_Add to Playlist"
+msgstr "Voeg toe _Aan Afspeellijst"
+
+#: src/search-tool/search-tool.cc:684
+msgid "Search library"
+msgstr "Zoek bibliotheek"
+
+#: src/search-tool/search-tool.cc:688
+msgid ""
+"To import your music library into Audacious, choose a folder and then click "
+"the \"refresh\" icon."
+msgstr ""
+
+#: src/search-tool/search-tool.cc:696
+msgid "Please wait ..."
+msgstr "Aub wachten ..."
+
+#: src/search-tool/search-tool.cc:723
+msgid "Choose Folder"
+msgstr "Kies Map"
+
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "SID Speler"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Kanalen:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Kloksnelheid:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
+msgid "Open Files ..."
+msgstr "Open Bestanden ..."
+
+#: src/skins/menus.cc:65
+msgid "Open URL ..."
+msgstr "Open URL ..."
+
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Doorzoek Bibliotheek"
+
+#: src/skins/menus.cc:68
+msgid "Playback"
+msgstr ""
+
+#: src/skins/menus.cc:69
+msgid "Playlist"
+msgstr "Speellijst"
+
+#: src/skins/menus.cc:70
+msgid "View"
+msgstr ""
+
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
+msgid "Services"
+msgstr ""
+
+#: src/skins/menus.cc:74
+msgid "About ..."
+msgstr "Over ..."
+
+#: src/skins/menus.cc:75
+msgid "Settings ..."
+msgstr "Instellingen ..."
+
+#: src/skins/menus.cc:76
+msgid "Quit"
+msgstr ""
+
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
+msgid "Song Info ..."
+msgstr ""
+
+#: src/skins/menus.cc:84
+msgid "No Playlist Advance"
+msgstr ""
+
+#: src/skins/menus.cc:85
+msgid "Stop After This Song"
+msgstr "Stop Na Dit Liedje"
+
+#: src/skins/menus.cc:93
+msgid "Set A-B Repeat"
+msgstr "Set A-B Herhaling"
+
+#: src/skins/menus.cc:94
+msgid "Clear A-B Repeat"
+msgstr "Wis A-B Herhaling"
+
+#: src/skins/menus.cc:96
+msgid "Jump to Song ..."
+msgstr "Spring naar Liedje ..."
+
+#: src/skins/menus.cc:97
+msgid "Jump to Time ..."
+msgstr "Spring naar Tijd ..."
+
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr ""
+
+#: src/skins/menus.cc:103
+msgid "New Playlist"
+msgstr "Nieuwe afspeellijst"
+
+#: src/skins/menus.cc:104
+msgid "Rename Playlist ..."
+msgstr "Hernoem Afspeellijst ..."
+
+#: src/skins/menus.cc:105
+msgid "Remove Playlist"
+msgstr "Verwijder Afspeellijst"
+
+#: src/skins/menus.cc:107
+msgid "Previous Playlist"
+msgstr "Vorige Afspeellijst"
+
+#: src/skins/menus.cc:108
+msgid "Next Playlist"
+msgstr "Volgende Afspeellijst"
+
+#: src/skins/menus.cc:110
+msgid "Import Playlist ..."
+msgstr "Importeer Afspeellijst ..."
+
+#: src/skins/menus.cc:111
+msgid "Export Playlist ..."
+msgstr "Exporteer Afspeellijst ..."
+
+#: src/skins/menus.cc:113
+msgid "Playlist Manager ..."
+msgstr ""
+
+#: src/skins/menus.cc:114
+msgid "Queue Manager ..."
+msgstr ""
+
+#: src/skins/menus.cc:116
+msgid "Refresh Playlist"
+msgstr ""
+
+#: src/skins/menus.cc:120
+msgid "Show Playlist Editor"
+msgstr ""
+
+#: src/skins/menus.cc:121
+msgid "Show Equalizer"
+msgstr "Toon Equalizer"
+
+#: src/skins/menus.cc:123
+msgid "Show Remaining Time"
+msgstr ""
+
+#: src/skins/menus.cc:125
+msgid "Always on Top"
+msgstr "Altijd bovenaan"
+
+#: src/skins/menus.cc:126
+msgid "On All Workspaces"
+msgstr ""
+
+#: src/skins/menus.cc:128
+msgid "Roll Up Player"
+msgstr ""
+
+#: src/skins/menus.cc:129
+msgid "Roll Up Playlist Editor"
+msgstr ""
+
+#: src/skins/menus.cc:130
+msgid "Roll Up Equalizer"
+msgstr ""
+
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Dubbele Grootte"
+
+#: src/skins/menus.cc:138
+msgid "Add URL ..."
+msgstr "URL Toevoegen ..."
+
+#: src/skins/menus.cc:139
+msgid "Add Files ..."
+msgstr "Bestanden Toevoegen ..."
+
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
+msgid "By Title"
+msgstr "Volgens titel"
+
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr "Volgens Bestandsnaam"
+
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
+msgid "By File Path"
+msgstr "Volgens Bestandspad"
+
+#: src/skins/menus.cc:151
+msgid "Remove All"
+msgstr "Verwijder Alles"
+
+#: src/skins/menus.cc:152
+msgid "Clear Queue"
+msgstr "Wachtrij leegmaken"
+
+#: src/skins/menus.cc:154
+msgid "Remove Unavailable Files"
+msgstr "Verwijder onbeschikbare bestanden"
+
+#: src/skins/menus.cc:155
+msgid "Remove Duplicates"
+msgstr "Verwijder duplicaten"
+
+#: src/skins/menus.cc:157
+msgid "Remove Unselected"
+msgstr "Verwijder niet geselecteerde"
+
+#: src/skins/menus.cc:158
+msgid "Remove Selected"
+msgstr "Verwijder geselecteerde"
+
+#: src/skins/menus.cc:162
+msgid "Search and Select"
+msgstr "Zoek en selecteer"
+
+#: src/skins/menus.cc:164
+msgid "Invert Selection"
+msgstr "Selectie omkeren"
+
+#: src/skins/menus.cc:165
+msgid "Select None"
+msgstr "Selecteer geen enkele"
+
+#: src/skins/menus.cc:166
+msgid "Select All"
+msgstr "Selecteer alles"
+
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Volgens nummer"
+
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
+msgid "By Artist"
+msgstr "Volgens artiest"
+
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Volgens album"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Volgens Album Artiest"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
+msgid "By Release Date"
+msgstr "Volgens Uitgave Datum"
+
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "Volgens Genre"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "Volgens Lengte"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "Volgens Aangepaste Titel"
+
+#: src/skins/menus.cc:198
+msgid "Randomize List"
+msgstr "Herschik lijst in willekeurige volgorde"
+
+#: src/skins/menus.cc:199
+msgid "Reverse List"
+msgstr "Lijst omkeren"
+
+#: src/skins/menus.cc:201
+msgid "Sort Selected"
+msgstr "Sorteer het geselecteerde"
+
+#: src/skins/menus.cc:202
+msgid "Sort List"
+msgstr "Sorteer lijst"
+
+#: src/skins/menus.cc:208
+msgid "Cut"
+msgstr "Knip"
+
+#: src/skins/menus.cc:209
+msgid "Copy"
+msgstr "Kopieer"
+
+#: src/skins/menus.cc:210
+msgid "Paste"
+msgstr "Plak"
+
+#: src/skins/menus.cc:212
+msgid "Queue/Unqueue"
+msgstr "Queue/Unqueue"
+
+#: src/skins/menus.cc:218
+msgid "Load Preset ..."
+msgstr "Laad Presets ..."
+
+#: src/skins/menus.cc:219
+msgid "Load Auto Preset ..."
+msgstr "Laad Auto Preset ..."
+
+#: src/skins/menus.cc:220
+msgid "Load Default"
+msgstr "Laad Standaard"
+
+#: src/skins/menus.cc:221
+msgid "Load Preset File ..."
+msgstr "Laad Presets Bestand"
+
+#: src/skins/menus.cc:222
+msgid "Load EQF File ..."
+msgstr "Laad EQF Bestand"
+
+#: src/skins/menus.cc:224
+msgid "Save Preset ..."
+msgstr "Bewaar Presets ..."
+
+#: src/skins/menus.cc:225
+msgid "Save Auto Preset ..."
+msgstr "Bewaar Auto Preset ..."
+
+#: src/skins/menus.cc:226
+msgid "Save Default"
+msgstr "Bewaar Standaard"
+
+#: src/skins/menus.cc:227
+msgid "Save Preset File ..."
+msgstr "Bewaar Presets Bestand ..."
+
+#: src/skins/menus.cc:228
+msgid "Save EQF File ..."
+msgstr "Bewaar EQF Bestand ..."
+
+#: src/skins/menus.cc:230
+msgid "Delete Preset ..."
+msgstr "Verwijder Preset ..."
+
+#: src/skins/menus.cc:231
+msgid "Delete Auto Preset ..."
+msgstr "Verwijder Auto Preset ..."
+
+#: src/skins/menus.cc:233
+msgid "Import Winamp Presets ..."
+msgstr "Importeer Winaps Presets ..."
+
+#: src/skins/menus.cc:235
+msgid "Reset to Zero"
+msgstr "Terug naar Nul"
+
+#: src/skins/plugin.cc:48
+msgid "Winamp Classic Interface"
+msgstr "Winamp Klassieke Interface"
+
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
+msgid "Save"
+msgstr "Opslaan"
+
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
+msgid "Load"
+msgstr "Laad"
+
+#: src/skins/preset-browser.cc:83
+msgid "Load Preset File"
+msgstr "Laad Presets Bestand"
+
+#: src/skins/preset-browser.cc:100
+msgid "Load EQF File"
+msgstr "Laad EQF Bestand"
+
+#: src/skins/preset-browser.cc:119
+msgid "Save Preset File"
+msgstr "Bewaar Presets Bestand"
+
+#: src/skins/preset-browser.cc:137
+msgid "Save EQF File"
+msgstr "Bewaar EQF Bestand"
+
+#: src/skins/preset-browser.cc:151
+msgid "Import Winamp Presets"
+msgstr "Importeer Winamp Instellingen"
+
+#: src/skins/preset-list.cc:285
+msgid "Presets"
+msgstr "Presets"
+
+#: src/skins/preset-list.cc:335
+msgid "Load preset"
+msgstr "Laad Presets"
+
+#: src/skins/preset-list.cc:351
+msgid "Load auto-preset"
+msgstr "Laad auto-preset"
+
+#: src/skins/preset-list.cc:367
+msgid "Save preset"
+msgstr "Bewaar Presets"
+
+#: src/skins/preset-list.cc:382
+msgid "Save auto-preset"
+msgstr "Bewaar auto-preset"
+
+#: src/skins/preset-list.cc:408
+msgid "Delete preset"
+msgstr "Verwijder preset"
+
+#: src/skins/preset-list.cc:424
+msgid "Delete auto-preset"
+msgstr "Verwijder auto-preset"
+
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Speler:"
+
+#: src/skins/skins_cfg.cc:178
+msgid "Select main player window font:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Afspeellijst:"
+
+#: src/skins/skins_cfg.cc:181
+msgid "Select playlist font:"
+msgstr "Selecteer lettertype van de speellijst:"
+
+#: src/skins/skins_cfg.cc:187
+msgid "<b>Skin</b>"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:189
+msgid "<b>Fonts</b>"
+msgstr "<b>Lettertypes</b>"
+
+#: src/skins/skins_cfg.cc:192
+msgid "Use bitmap fonts (supports ASCII only)"
+msgstr "Gebruik bitmap lettertypen (ondersteunt alleen ASCII)"
+
+#: src/skins/skins_cfg.cc:194
+msgid "Scroll song title"
+msgstr "Scrol titel "
+
+#: src/skins/skins_cfg.cc:196
+msgid "Scroll song title in both directions"
+msgstr "Scrol titel in beide kanten"
+
+#: src/skins/skins_cfg.cc:201
+msgid "Analyzer"
+msgstr "Analyseerder"
+
+#: src/skins/skins_cfg.cc:202
+msgid "Scope"
+msgstr "Scope"
+
+#: src/skins/skins_cfg.cc:203
+msgid "Voiceprint / VU meter"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:204
+msgid "Off"
+msgstr "Uit"
+
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
+msgid "Normal"
+msgstr "Normaal"
+
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
+msgid "Fire"
+msgstr "Vuur"
+
+#: src/skins/skins_cfg.cc:210
+msgid "Vertical lines"
+msgstr "Verticale Strepen"
+
+#: src/skins/skins_cfg.cc:214
+msgid "Lines"
+msgstr "Lijnen"
+
+#: src/skins/skins_cfg.cc:215
+msgid "Bars"
+msgstr "Horizontale Strepen"
+
+#: src/skins/skins_cfg.cc:219
+msgid "Slowest"
+msgstr "Traagst"
+
+#: src/skins/skins_cfg.cc:220
+msgid "Slow"
+msgstr "Traag"
+
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
+msgid "Medium"
+msgstr "Matig"
+
+#: src/skins/skins_cfg.cc:222
+msgid "Fast"
+msgstr "Snel"
+
+#: src/skins/skins_cfg.cc:223
+msgid "Fastest"
+msgstr "Snelst"
+
+#: src/skins/skins_cfg.cc:227
+msgid "Dots"
+msgstr "Punten"
+
+#: src/skins/skins_cfg.cc:228
+msgid "Line"
+msgstr "Lijn"
+
+#: src/skins/skins_cfg.cc:229
+msgid "Solid"
+msgstr "Solide"
+
+#: src/skins/skins_cfg.cc:235
+msgid "Ice"
+msgstr "IJs"
+
+#: src/skins/skins_cfg.cc:240
+msgid "Smooth"
+msgstr "Glad"
+
+#: src/skins/skins_cfg.cc:244
+msgid "<b>Type</b>"
+msgstr "<b>Type</b>"
+
+#: src/skins/skins_cfg.cc:245
+msgid "Visualization type:"
+msgstr "Visualisatie type:"
+
+#: src/skins/skins_cfg.cc:248
+msgid "<b>Analyzer</b>"
+msgstr "<b>Analyseerder</b>"
+
+#: src/skins/skins_cfg.cc:249
+msgid "Show peaks"
+msgstr "Laat pieken zien"
+
+#: src/skins/skins_cfg.cc:251
+msgid "Coloring:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:254
+msgid "Style:"
+msgstr "Stijl:"
+
+#: src/skins/skins_cfg.cc:257
+msgid "Falloff:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:260
+msgid "Peak falloff:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:264
+msgid "Scope Style:"
+msgstr "Scope Stijl:"
+
+#: src/skins/skins_cfg.cc:267
+msgid "Voiceprint Coloring:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:270
+msgid "VU Meter Style:"
+msgstr "VU Meter Stijl:"
+
+#: src/skins/skins_cfg.cc:276
+msgid "General"
+msgstr "Algemeen"
+
+#: src/skins/skins_cfg.cc:277
+msgid "Visualization"
+msgstr "Visualisatie "
+
+#: src/skins/ui_equalizer.cc:282
+msgid "Preamp"
+msgstr "Voorversterker"
+
+#: src/skins/ui_equalizer.cc:286
+msgid "31 Hz"
+msgstr "31 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "63 Hz"
+msgstr "63 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "125 Hz"
+msgstr "125 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "250 Hz"
+msgstr "250 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "500 Hz"
+msgstr "500 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "1 kHz"
+msgstr "1 kHz"
+
+#: src/skins/ui_equalizer.cc:288
+msgid "2 kHz"
+msgstr "2 kHz"
+
+#: src/skins/ui_equalizer.cc:288
+msgid "4 kHz"
+msgstr "4 kHz"
+
+#: src/skins/ui_equalizer.cc:288
+msgid "8 kHz"
+msgstr "8 kHz"
+
+#: src/skins/ui_equalizer.cc:288
+msgid "16 kHz"
+msgstr "16 kHz"
+
+#: src/skins/ui_equalizer.cc:330
+msgid "Audacious Equalizer"
+msgstr "Audacious Equalizer"
+
+#: src/skins/ui_main.cc:688
+#, c-format
+msgid "Seek to %d:%-2.2d / %d:%-2.2d"
+msgstr ""
+
+#: src/skins/ui_main.cc:709
+#, c-format
+msgid "Volume: %d%%"
+msgstr "Volume: %d%%"
+
+#: src/skins/ui_main.cc:732
+#, c-format
+msgid "Balance: %d%% left"
+msgstr "Balans: %d%% links"
+
+#: src/skins/ui_main.cc:734
+msgid "Balance: center"
+msgstr "Balans: gecentreerd"
+
+#: src/skins/ui_main.cc:736
+#, c-format
+msgid "Balance: %d%% right"
+msgstr "Balans: %d%% rechts"
+
+#: src/skins/ui_main.cc:842
+msgid "Options Menu"
+msgstr "Opties menu"
+
+#: src/skins/ui_main.cc:846
+msgid "Disable 'Always On Top'"
+msgstr "'Altijd bovenaan' uitschakelen"
+
+#: src/skins/ui_main.cc:848
+msgid "Enable 'Always On Top'"
+msgstr "'Altijd bovenaan' inschakelen"
+
+#: src/skins/ui_main.cc:851
+msgid "File Info Box"
+msgstr "Bestandsinformatie Box"
+
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "Visualisatie "
+
+#: src/skins/ui_main.cc:1336
+msgid "Repeat point A set."
+msgstr "Herhaal ingesteld punt A."
+
+#: src/skins/ui_main.cc:1341
+msgid "Repeat point B set."
+msgstr "Herhaal ingesteld punt B."
+
+#: src/skins/ui_main.cc:1350
+msgid "Repeat points cleared."
+msgstr ""
+
+#: src/skins/ui_playlist.cc:219
+msgid "Search entries in active playlist"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:226
+msgid ""
+"Select entries in playlist by filling one or more fields. Fields use regular "
+"expressions syntax, case-insensitive. If you don't know how regular "
+"expressions work, simply insert a literal portion of what you're searching "
+"for."
+msgstr ""
+
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr "Titel:"
+
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr "Album:"
+
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr "Artiest:"
+
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Bestadsnaam:"
+
+#: src/skins/ui_playlist.cc:263
+msgid "Clear previous selection before searching"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:266
+msgid "Automatically toggle queue for matching entries"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:269
+msgid "Create a new playlist with matching entries"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:717
+msgid "Audacious Playlist Editor"
+msgstr "Audacious Afspeellijst Bewerker"
+
+#: src/skins/ui_playlist.cc:752
+#, c-format
+msgid "%s (%d of %d)"
+msgstr "%s (%d van %d)"
+
+#: src/skins/ui_skinselector.cc:167
+msgid "Archived Winamp 2.x skin"
+msgstr ""
+
+#: src/skins/ui_skinselector.cc:172
+msgid "Unarchived Winamp 2.x skin"
+msgstr ""
+
+#: src/skins/util.cc:430
+#, c-format
+msgid "Could not create directory (%s): %s\n"
+msgstr "Kon de map (%s) niet aanmaken: %s\n"
+
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile Plugin"
+
+#: src/sndfile/plugin.cc:336
+msgid ""
+"Based on the xmms_sndfile plugin:\n"
+"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
+"\n"
+"Adapted for Audacious by Tony Vroon <chainsaw at gentoo.org>\n"
+"\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., 51 "
+"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
+msgstr ""
+
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Sndio Uitvoer"
+
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "Apparaat (leeg voor standaardwaarde):"
+
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Volume opslaan en herstellen:"
+
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr ""
+
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
+
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
+
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
+
+#: src/song_change/song_change.cc:33
+msgid "Song Change"
+msgstr ""
+
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Opdrachten</b>"
+
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Opdracht uitvoeren wanneer een nieuw lied start:"
+
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Opdracht uitvoeren aan het eind van een lied:"
+
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Opdracht uitvoeren aan het eind van een afspeellijst:"
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr ""
+"Opdracht uitvoeren wanneer de songtitel verandert (voor netwerk streams):"
+
+#: src/song_change/song_change.cc:376
+msgid ""
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
+"\n"
+"%F: Frequency (in hertz)\n"
+"%c: Number of channels\n"
+"%f: File name (full path)\n"
+"%l: Length (in milliseconds)\n"
+"%n or %s: Song name\n"
+"%r: Rate (in bits per second)\n"
+"%t: Playlist position (%02d)\n"
+"%p: Currently playing (1 or 0)\n"
+"%a: Artist\n"
+"%b: Album\n"
+"%T: Track title"
+msgstr ""
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Lied Informatie (Qt)"
+
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX Resampler"
+
+#: src/sox-resampler/sox-resampler.cc:144
+msgid ""
+"SoX Resampler Plugin for Audacious\n"
+"Copyright 2013 MichaÅ Lipski\n"
+"\n"
+"Based on Sample Rate Converter Plugin:\n"
+"Copyright 2010-2012 John Lindgren"
+msgstr ""
+"SoX Resampler Plugin voor Audacious\n"
+"Copyright 2013 MichaÅ Lipski\n"
+"\n"
+"Gebaseerd op de Sample Rate Converter Plugin:\n"
+"Copyright 2010-2012 John Lindgren"
+
+#: src/sox-resampler/sox-resampler.cc:150
+msgid "Quick"
+msgstr "Snel"
+
+#: src/sox-resampler/sox-resampler.cc:151
+msgid "Low"
+msgstr "Laag"
+
+#: src/sox-resampler/sox-resampler.cc:153
+msgid "High"
+msgstr "Hoog"
+
+#: src/sox-resampler/sox-resampler.cc:154
+msgid "Very High"
+msgstr "Erg Hoog"
+
+#: src/sox-resampler/sox-resampler.cc:158
+msgid "Quality:"
+msgstr "Kwaliteit:"
+
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Snelheid en Pitch"
+
+#: src/speed-pitch/speed-pitch.cc:210
+msgid "<b>Speed and Pitch</b>"
+msgstr "<b>Snelheid en Pitch</b>"
+
+#: src/speed-pitch/speed-pitch.cc:211
+msgid "Speed:"
+msgstr "Snelheid:"
+
+#: src/speed-pitch/speed-pitch.cc:214
+msgid "Pitch:"
+msgstr "Pitch:"
+
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Status Icoon"
+
+#: src/statusicon/statusicon.cc:283
+msgid "Se_ttings ..."
+msgstr "Ins_tellingen"
+
+#: src/statusicon/statusicon.cc:372
+msgid ""
+"Status Icon Plugin\n"
+"\n"
+"Copyright 2005-2007 Giacomo Lozito <james at develia.org>\n"
+"Copyright 2010 MichaÅ Lipski <tallica at o2.pl>\n"
+"\n"
+"This plugin provides a status icon, placed in\n"
+"the system tray area of the window manager."
+msgstr ""
+
+#: src/statusicon/statusicon.cc:379
+msgid "<b>Mouse Scroll Action</b>"
+msgstr "<b>Muis Scroll Actie</b>"
+
+#: src/statusicon/statusicon.cc:380
+msgid "Change volume"
+msgstr "Verander Volume"
+
+#: src/statusicon/statusicon.cc:383
+msgid "Change playing song"
+msgstr "Verander het huidige lied dat wordt afgespeeld"
+
+#: src/statusicon/statusicon.cc:386
+msgid "<b>Other Settings</b>"
+msgstr "<b>Ander Instellingen</b>"
+
+#: src/statusicon/statusicon.cc:387
+msgid "Disable the popup window"
+msgstr "Het pop-up venster uitschakelen"
+
+#: src/statusicon/statusicon.cc:389
+msgid "Close to the system tray"
+msgstr "In de buurt van het systeemvak"
+
+#: src/statusicon/statusicon.cc:391
+msgid "Advance in playlist when scrolling upward"
+msgstr ""
+
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Stereo"
+
+#: src/stereo_plugin/stereo.cc:36
+msgid ""
+"Extra Stereo Plugin\n"
+"\n"
+"By Johan Levin, 1999"
+msgstr ""
+"Extra Stereo Plugin\n"
+"\n"
+"Door Johan Levin, 1999"
+
+#: src/stereo_plugin/stereo.cc:44
+msgid "<b>Extra Stereo</b>"
+msgstr "<b>Extra Stereo"
+
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Toon Generator"
+
+#: src/tonegen/tonegen.cc:94
+#, c-format
+msgid "%s %.1f Hz"
+msgstr "%s %.1f Hz"
+
+#: src/tonegen/tonegen.cc:94
+msgid "Tone Generator: "
+msgstr "Toon Generator:"
+
+#: src/tonegen/tonegen.cc:160
+msgid ""
+"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
+"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
+"\n"
+"To use it, add a URL: tone://frequency1;frequency2;frequency3;...\n"
+"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
+msgstr ""
+
+#: src/voice_removal/voice_removal.cc:28
+msgid "Voice Removal"
+msgstr "Stem Opheffing"
+
+#: src/vorbis/vorbis.cc:465
+msgid ""
+"Audacious Ogg Vorbis Decoder\n"
+"\n"
+"Based on the Xiph.org Foundation's Ogg Vorbis Plugin:\n"
+"http://www.xiph.org/\n"
+"\n"
+"Original code by:\n"
+"Tony Arcieri <bascule at inferno.tusculum.edu>\n"
+"\n"
+"Contributions from:\n"
+"Chris Montgomery <monty at xiph.org>\n"
+"Peter Alm <peter at xmms.org>\n"
+"Michael Smith <msmith at labyrinth.edu.au>\n"
+"Jack Moffitt <jack at icecast.org>\n"
+"Jorn Baayen <jorn at nl.linux.org>\n"
+"Håvard Kvålen <havardk at xmms.org>\n"
+"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
+"Eugene Zagidullin <e.asphyx at gmail.com>"
+msgstr ""
+
+#: src/vorbis/vorbis.h:18
+msgid "Ogg Vorbis Decoder"
+msgstr "Ogg Vorbis Decoder"
+
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Details over %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX Decoder"
+
+#: src/vtx/vtx.cc:184
+msgid ""
+"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
+"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
+"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
+msgstr ""
+
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack Decoder"
+
+#: src/wavpack/wavpack.cc:211
+msgid "lossy (hybrid)"
+msgstr ""
+
+#: src/wavpack/wavpack.cc:213
+msgid "lossy"
+msgstr ""
+
+#: src/wavpack/wavpack.cc:255
+msgid ""
+"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
+"\n"
+"Some of the plugin code was by Miles Egan."
+msgstr ""
+"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
+"\n"
+"Enkele regels code van de plugin zijn door Miles Egan."
+
+#: src/xsf/plugin.cc:50
+msgid "2SF Decoder"
+msgstr "2SF Decoder"
+
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>XSF Configuratie</b>"
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Negeer de lengte van het bestand"
+
+#: src/xspf/xspf.cc:89
+msgid "XML Shareable Playlists (XSPF)"
+msgstr ""
diff --git a/po/pl.po b/po/pl.po
index 81bc8383ad7f..bf131d5bba33 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -3,27 +3,29 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# CH <259095+transifex at gmail.com>, 2012
-# CH <259095+transifex at gmail.com>, 2012
+# Chris <259095+transifex at gmail.com>, 2012
+# Chris <259095+transifex at gmail.com>, 2012
+# Chris <259095+transifex at gmail.com>, 2012
# felikstayson <felikstayson at o2.pl>, 2012
# felikstayson <felikstayson at o2.pl>, 2012
# mkkot <marcin2006 at gmail.com>, 2013
-# mgrvnwald <marco at mgrvnwald.com>, 2013
-# mgrvnwald <marco at mgrvnwald.com>, 2013
-# mgrvnwald <marco at mgrvnwald.com>, 2013
+# Marco Oliver Grunwald <m at mgrvnwald.com>, 2013
+# Marco Oliver Grunwald <m at mgrvnwald.com>, 2013
+# Marco Oliver Grunwald <m at mgrvnwald.com>, 2013
# mkkot <marcin2006 at gmail.com>, 2013-2014
# Piotr SokóŠ<psokol at jabster.pl>, 2012
+# Piotr StrÄbski <strebski at o2.pl>, 2014-2015
# Szymon Weihs <sz.weihs at gmail.com>, 2011
# Szymon Weihs <sz.weihs at gmail.com>, 2011-2012
-# vojcek <vojcek at tlen.pl>, 2013
-# vojcek <vojcek at tlen.pl>, 2013
+# Wojciech Myrda <vojcek at tlen.pl>, 2013
+# Wojciech Myrda <vojcek at tlen.pl>, 2013
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-05 12:12+0000\n"
+"Last-Translator: Piotr StrÄbski <strebski at o2.pl>\n"
"Language-Team: Polish (http://www.transifex.com/projects/p/audacious/"
"language/pl/)\n"
"Language: pl\n"
@@ -33,40 +35,28 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "DźwiÄk przestrzenny"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "Dekoder AAC (MP4)"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "Dekoder AAC (surowe dane)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (Odtwarzacz AdLib)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "sekwencjonowane"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (Odtwarzacz AdLib)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarm"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "Ustaw alarm..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -75,11 +65,7 @@ msgstr ""
"Wtyczka do zaplanowania odtwarzania w okreÅlonym czasie.\n"
"Pierwotni autorzy: Adam Feakin i Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarm"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -121,7 +107,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -161,7 +147,7 @@ msgstr ""
" Uruchom tÄ
komendÄ podczas alarmu.\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -185,383 +171,390 @@ msgstr ""
" Wpisz informacjÄ do wyÅwietlenia przy alarmie\n"
" oraz zaznacz przycisk gdy chcesz by siÄ ukazaÅa."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "To jest twój sygnaŠbudzenia."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "Twoje przypomnienie na dzisiaj to..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Przypominacz"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "PoniedziaÅek"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Wtorek"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Åroda"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Czwartek"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "PiÄ
tek"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Sobota"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Niedziela"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Ustawienia alarmu"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "_OK"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "_Anuluj"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Czas"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "DomyÅlnie alarm o:"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "[hh:mm]"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Wyciszenie po:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "godziny"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minuty"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Wybierz dni, w których alarm bÄdzie aktywny"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "DzieÅ"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "DomyÅlny"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Dni"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Czas przejÅcia"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "sekundy"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "GÅoÅnoÅÄ"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "PoczÄ
tkowa"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "KoÅcowa"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "BieżÄ
ca"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Dodatkowe polecenie"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "wÅÄ
cz"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Lista odtwarzania (opcjonalnie)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Wybierz listÄ odtwarzania"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Ustawienia"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Co oznaczajÄ
te ustawienia?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Pomoc"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
-msgstr "OkÅadka Albumu"
+msgstr "OkÅadka albumu"
+
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "OkÅadka albumu (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "WyjÅcie ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"Wtyczka wyjÅcia ALSY dla Audaciousa\n"
+"Prawa autorskie: 2009-2012 John Lindgren\n"
+"\n"
+"PodziÄkowania kierujÄ do Williama Pitcocka, autora ALSA Output Plugin NG, "
+"którego kod sÅużyÅ za odniesienie, gdy podrÄcznik ALSY nie wystarczaÅ."
-#: src/alsa/config.c:210
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(brak opisu)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "DomyÅlne urzÄ
dzenie PCM"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "DomyÅlne urzÄ
dzenie miksera"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "UrzÄ
dzenie PCM:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "UrzÄ
dzenie miksera:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Element miksera:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Obejdź rozÅÄ
czenie"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (Odtwarzacz MIDI)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"moduÅowy odtwarzacz MIDI\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (Odtwarzacz MIDI)"
+"autorstwa Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"szczególne podziÄkowania kierujÄ do:\n"
+"\n"
+"Clemensa Ladischa and Jaroslava Kysela\n"
+"za ich Åwietne programy aplaymidi i amixer; byÅy one\n"
+"naprawdÄ pomocne wraz z alsa-lib docs, które przydaÅy siÄ\n"
+"do nauki ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"za logo klawiatury MIDI\n"
+"\n"
+"Tony'ego Vroona\n"
+"za pomoc w testowaniu wersji alfa"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "ZmieÅ domyÅlnÄ
gÅoÅnoÅÄ:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "ZmieÅ domyÅlnÄ
polifoniÄ:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "ZmieÅ domyÅlne echo:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "WÅÄ
czone"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "ZmieÅ domyÅlny chorus:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>Odtwarzanie</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "PrzesuniÄcie:"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "póÅtony"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "PrzesuniÄcie perkusji:"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>Zaawansowane</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "numery nut"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "WydobÄ
dź komentarze z pliku MIDI"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Przeskocz ciszÄ na wprowadzeniu"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "WydobÄ
dź sÅowa z pliku MIDI"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Przeskocz ciszÄ na zakoÅczeniu"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>Czcionka</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>Syntezator</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr "CzÄstotliwoÅÄ próbkowania:"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - wybierz plik czcionki"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Anuluj"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "_Otwórz"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Nazwa pliku"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "WielkoÅÄ (w bajtach)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nazwa:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
-msgstr "<span size=\"smaller\"> Info MIDI </span>"
+msgstr "<span size=\"smaller\"> Informacje MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Format:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "DÅugoÅÄ (ms):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "Liczba utworów:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "zmienna"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "Uderzenia na minutÄ:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "Uderzenia na minutÄ (Årednia ważona):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "PodziaÅ czasu:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> Komentarze i teksty utworów MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* brak dostÄpnych komentarzy w tym pliku MIDI *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* brak dostÄpnych tekstów utworów w tym pliku MIDI *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Zamknij"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (niepoprawne kodowanie UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "O Pluginie AMIDI"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"odtwarzacz modularny muzyki MIDI\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"napisany przez Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"specjalne podziÄkowania dla...\n"
-"\n"
-"Clemens Ladisch i Jaroslav Kysela\n"
-"za ich wspaniaÅe programy aplaymidi i amixer; byÅy bardzo pomocne wraz "
-"dokumentacjÄ
alsa-lib, która pozwoliÅa dowiedzieÄ siÄ wiÄcej o ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"za loga klawiatur midi\n"
-"\n"
-"Tony Vroon\n"
-"za pomoc przy testowaniu wersji alpha"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -579,152 +572,149 @@ msgstr ""
"Wykorzystano fragmenty kodu biblioteki Ghosd Evana Martina:\n"
"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (informacja ekranowa)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ProstokÄ
t"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "ZaokrÄ
glony prostokÄ
t"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "WklÄsÅy prostokÄ
t"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Brak"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Rozpocznij odtwarzanie"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr ""
"WyÅwietla informacjÄ ekranowÄ
po zmianie pozycji na liÅcie odtwarzania."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Zmiana tytuÅu"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"WyÅwietla informacjÄ ekranowÄ
po zmianie tytuÅu Åcieżki, bez zmiany "
-"odtwarzanego pliku. Użyteczne podczas odtwarzania strumieni internetowych."
+"Wyzwala OSD, gdy nastÄpuje zmiana tytuÅu piosenki (dla strumieniowania "
+"internetowego)"
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Wstrzymaj"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "WyÅwietla informacjÄ ekranowÄ
po wstrzymaniu odtwarzania."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Wznów"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "WyÅwietla informacjÄ ekranowÄ
po wznowieniu odtwarzania."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Rozmieszczenie"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "PrzesuniÄcie wzdÅuż osi X:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "PrzesuniÄcie wzdÅuż osi Y:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Maksymalna szerokoÅÄ informacji:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Wiele ekranów"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "WyÅwietlanie informacji ekranowej na:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "wszystkie ekrany"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "ekran %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Czas (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "WyÅwietlanie:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Pojawianie siÄ:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Zanikanie:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Czcionki"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Czcionka %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "CieÅ"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "KsztaÅt"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Kolory"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Kolor %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "WÅÄ
czenie"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Zdarzenia"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Wykryto menedżer okien obsÅugujÄ
cy kompozycje"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -734,114 +724,114 @@ msgstr ""
"Aby menu ekranowe byÅo wyÅwietlanie prawidÅowo, należy uruchomiÄ menedżer "
"okien obsÅugujÄ
cy kompozycje (np. Compiz)."
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr ""
"Menedżer okien obsÅugujÄ
cy kompozycje nie jest wymagany dla udawanej "
"przezroczystoÅci"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "PrzezroczystoÅÄ"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Udawana przeźroczystoÅÄ"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Prawdziwa przezroczystoÅÄ (wymaga rozszerzenia X Composite)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Nie wczytano rozszerzenia kompozycji"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Rozszerzenie kompozycji jest niedostÄpne"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Ustawienia menu ekranowego Audacious"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "_Przetestuj"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "_Ustaw"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Pozycja"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animacja"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Tekst"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Obramowanie"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Wyzwalanie"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Różne"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Przetestuj"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "Lista odtwarzania ASXv3"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "Listy odtwarzania ASXv1/ASXv2"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Listy odtwarzania Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Kolor</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Rozmyty zakres"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Profile ustawieÅ:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Poziom sygnaÅu wejÅciowego:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "CzÄstotliwoÅÄ obciÄcia:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Profile ustawieÅ:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Analizator spektrum"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Wtyczka Audio CD"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -852,178 +842,168 @@ msgid ""
"\n"
"This was a Google Summer of Code 2007 project."
msgstr ""
-"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
-"Many thanks to libcdio developers <http://www.gnu.org/software/libcdio/> and "
-"to libcddb developers <http://libcddb.sourceforge.net/>.\n"
+"Prawa autorskie: (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> i inni.\n"
+"\n"
+"PodziÄkowania kierujÄ do programistów libcdio <http://www.gnu.org/software/"
+"libcdio/>\n"
+"oraz libcddb <http://libcddb.sourceforge.net/>.\n"
"\n"
-"Also thank you to Tony Vroon for mentoring and guiding me. This was a Google "
-"Summer of Code 2007 project."
+"DziÄkujÄ także Tony'emu Vroonowi za opiekÄ i wskazówki.\n"
+"\n"
+"Zrealizowano w ramach programu Google Summer of Code 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>UrzÄ
dzenie</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "PrÄdkoÅÄ odczytu:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "ZastÄ
p urzÄ
dzenie:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadane</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Użyj CD-Tekstu"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Użyj CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Używanie protokoÅu HTTP zamiast CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Serwer:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Åcieżka:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Port:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Wtyczka Audio CD"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "Nie udaÅo siÄ zainicjalizowaÄ podsystemu cdio."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "NieprawidÅowy URI %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Åcieżka %d nie znaleziona."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "Åcieżka %d jest ÅcieżkÄ
danych."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Nie udaÅo siÄ otworzyÄ wyjÅcia audio."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "WystÄ
piÅ bÅÄ
d przy odczycie pÅyty CD Audio."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Audio CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "Åcieżka %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Nie udaÅo siÄ otworzyÄ urzÄ
dzenia CD %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Nie znaleziono napÄdu CD."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "Nie udaÅo siÄ zainicjalizowaÄ otwarcia napÄdu CD."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Nie udaÅo siÄ odzyskaÄ pierwszego/ostatniego numeru Åcieżki."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Nie mogÄ odczytaÄ LSN poczÄ
tku/koÅca Åcieżki %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Nie udaÅo siÄ poÅÄ
czyÄ z cddb."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Nie udaÅo siÄ uzyskaÄ odpowiedzi z serwera cddb."
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Nie udaÅo siÄ uzyskaÄ odpowiedzi z serwera cddb: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Nie udaÅo siÄ odczytaÄ informacji z cddb: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Brak pÅyty w napÄdzie."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "NieobsÅugiwany rodzaj pÅyty."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Pozycje menu Audio CD"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Odtwórz pÅytÄ CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Dodaj pÅytÄ CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Pozycje menu Audio CD"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Kompresja</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Centralna gÅoÅnoÅÄ:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Zakres dynamiki:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Wtyczka kompresora zakresu dynamicznego dla Audacious\n"
+"Prawa autorskie 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Kompresor zakresu dynamicznego"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1032,216 +1012,249 @@ msgid ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
msgstr ""
-"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
-"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
+"Odtwarzacz muzyki z konsol do gier bazowany na Game_Music_Emu 0.5.2\n"
+"ObsÅugiwane formaty: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
"\n"
-"Audacious plugin by:\n"
+"Wtyczka dla Audaciousa:\n"
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Basy:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Soprany:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "Echo:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "DomyÅlny czas trwania Åcieżki:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
"<b>Konwersja czÄstotliwoÅci\n"
"próbkowania</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "WÅÄ
czenie"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "CzÄstotliwoÅÄ:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ignorowanie czasu trwania w etykietach SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "ZwiÄkszenie pogÅosu"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Dekoder muzyki z konsol gier"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"Przenikanie Åcieżek zawiodÅo, ponieważ piosenki miaÅy różnÄ
liczbÄ kanaÅów. "
-"Możesz użyÄ Miksera kanaÅów, by przekonwertowaÄ piosenki do tej samej liczby "
-"kanaÅów."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "WyjÅcie CoreAudio"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"Wtyczka przenikania Åcieżek zawiodÅa, gdyż utwory posiadajÄ
różnÄ
"
-"czÄstotliwoÅÄ próbkowania. Możesz użyÄ konwertera czÄstotliwoÅci "
-"próbkowania, aby sprowadziÄ utwory do tej samej czÄstotliwoÅci."
+"Wtyczka wyjÅcie CoreAudio dla Audacious\n"
+"Prawa autorskie 2014 William Pitcock\n"
+"\n"
+"Oparta na wtyczce wyjÅcia SDL dla Audacious\n"
+"Prawa autorskie 2010 John Lindgren"
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "Użyj trybu wyÅÄ
cznoÅci"
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Przenikanie Åcieżek dla Audaciousa\n"
-"Prawa autorskie 2010-2012 John Lindgren"
+"Wtyczka przenikania Åcieżek dla Audacious\n"
+"Prawa autorskie 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Przenikanie Åcieżek</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "Przy automatycznej zmianie piosenki"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "NakÅadanie siÄ:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "Przy wyszukiwaniu lub rÄcznej zmianie piosenki"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Podpowiedź</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+"Dla lepszego przenikania Åcieżek, \n"
+"wÅÄ
cz efekt usuwania ciszy."
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Przenikanie Åcieżek"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"Przenikanie Åcieżek zawiodÅo, ponieważ piosenki miaÅy różnÄ
liczbÄ kanaÅów. "
+"Możesz użyÄ Miksera kanaÅów, by przekonwertowaÄ piosenki do tej samej liczby "
+"kanaÅów."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"Wtyczka przenikania Åcieżek zawiodÅa, gdyż utwory posiadajÄ
różnÄ
"
+"czÄstotliwoÅÄ próbkowania. Możesz użyÄ konwertera czÄstotliwoÅci "
+"próbkowania, aby sprowadziÄ utwory do tej samej czÄstotliwoÅci."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>KrystalicznoÅÄ</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "IntensywnoÅÄ:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Krystalizator"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Wtyczka Cue Sheet"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "UsuÅ pliki"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "Nie udaÅo siÄ przenieÅÄ %s do kosza: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "Nie udaÅo siÄ usunÄ
Ä %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "Nie udaÅo siÄ usunÄ
Ä %s: to nie jest plik lokalny."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "Czy chcesz usunÄ
Ä zaznaczone pliki do kosza?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "PrzesuÅ do kosza"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "Czy chcesz caÅkowicie usunÄ
Ä zaznaczone pliki?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "UsuÅ"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Anuluj"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "UsuÅ pliki"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "UsuÅ zaznaczone pliki"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>Sposób usuwania</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "PrzesuÅ do kosza zamiast kasowaÄ"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+"Wtyczka echa\n"
+"Autor: Johan Levin, 1999\n"
+"OtaczajÄ
ce echo autorstwa Carla van Schaika, 1999\n"
+"Zaktualizowano dla potrzeb Audacious przez Williama Pitcocka i Johna "
+"Lindgrena, 2010-2014"
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Echo</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Opóźnienie:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "SprzÄżenie zwrotne:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "GÅoÅnoÅÄ:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Wtyczka echa\n"
-"Autor: Johan Levin, 1999\n"
-"\n"
-"Przestrzenne echo, autor: Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Echo"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Wtyczka FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1257,55 +1270,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "Wtyczka FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Zapis do pliku"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Format pliku wyjÅciowego:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Konfiguruj"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Zapisywanie w pierwotnym poÅożeniu"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Zapisywanie we wÅasnym poÅożeniu"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "PoÅożenie pliku docelowego:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Wybór katalogu"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Uzyskanie nazwy pliku z:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Utwórz nazwÄ pliku z:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "zaÅÄ
czonych etykiet"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Pierwotny znacznik pliku"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "nazwy pliku"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Pierwotna nazwa pliku"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Pozostawienie rozszerzenia nazwy pierwotnego pliku"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "DoÅÄ
czenie rozszerzenia pierwotnej nazwy pliku"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Dodanie do nazwy pliku numer Åcieżki"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr "Dodanie do nazwy pliku numeru Åcieżki"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1322,205 +1335,219 @@ msgid ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"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"
+"Niniejszy program jest wolnym oprogramowaniem; możesz go \n"
+"rozprowadzaÄ dalej i/lub modyfikowaÄ na warunkach Powszechnej\n"
+"Licencji Publicznej GNU, wydanej przez FundacjÄ Wolnego\n"
+"Oprogramowania - wedÅug wersji 2-giej tej Licencji lub którejÅ\n"
+"z późniejszych wersji.\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"
+"Niniejszy program rozpowszechniany jest z nadziejÄ
, iż bÄdzie on \n"
+"użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyÅlnej \n"
+"gwarancji PRZYDATNOÅCI HANDLOWEJ albo PRZYDATNOÅCI DO OKREÅLONYCH \n"
+"ZASTOSOWAÅ. W celu uzyskania bliższych informacji - Powszechna \n"
+"Licencja Publiczna GNU.\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., 51 "
-"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "Wtyczka FileWriter"
+"Z pewnoÅciÄ
wraz z niniejszym programem otrzymaÅeÅ też egzemplarz \n"
+"Powszechnej Licencji Publicznej GNU (GNU General Public License);\n"
+"jeÅli nie - napisz do Free Software Foundation, Inc., 51 Franklin Street, "
+"Fifth Floor, Boston, MA 02110-1301,\n"
+"USA."
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Automatycznie"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "PoÅÄ
czone stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Konfiguracja kodera MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_OK"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "JakoÅÄ algorytmu:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
msgstr "WyjÅciowa czÄstotliwoÅÄ próbkowania:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Tempo transmisji/wspóÅczynnik kompresji:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "Tempo bitowe / wspóÅczynnik kompresji:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Tempo transmisji (kb/s):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "WspóÅczynnik kompresji:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "KanaÅy:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "Różne:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
msgstr "Wymuszenie ÅcisÅej zgodnoÅci z ISO"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Zabezpieczenie przed bÅÄdami"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "JakoÅÄ"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "WÅÄ
czenie"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
-msgstr "Typ:"
+msgstr "Rodzaj:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Zmienne tempo transmisji (VBR):"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Minimalna wartoÅÄ (kb/s):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Maksymalna wartoÅÄ (kb/s):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Wymuszenie wartoÅci minimalnej"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Årednie tempo transmisji (ABR):"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Årednia wartoÅÄ (kb/s):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "JakoÅÄ algorytmu VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "PominiÄcie zapisywania nagÅówka Xing VBR"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "PominiÄcie nagÅówka Xing VBR"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr "Parametry klatek:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Oznaczenie prawem autorskim"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Oznaczenie jako oryginalne"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "Parametry ID3:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "WymuŠdodawanie tagów wersji 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Dodawanie tagów tylko wersji 1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Dodawanie tagów tylko wersji 2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
-msgstr "Tagi"
+msgstr "Znaczniki"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Konfiguracja kodera Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "JakoÅÄ (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "Dekoder FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "bezstratna"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-"Original code by Ralf Ertzinger <ralf at skytale.net>\n"
+"Oryginalny kod autorstwa\n"
+"Ralfa Ertzingera <ralf at skytale.net>\n"
+"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "Dekoder FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-"Wtyczka GIO Audaciousa\n"
-"Copyright 2009-2012 John Lindgren"
+"Wtyczka GIO dla Audaciousa\n"
+"Prawa autorskie 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "Wtyczka GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "Tryb odczytu i doÅÄ
czania nie jest obsÅugiwany"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "NieprawidÅowy tryb otwierania"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1540,448 +1567,522 @@ msgstr ""
"\n"
"Licencja: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "Analizator spektrum OpenGL"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
-"GIO Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren"
+"Analizator spektrum OpenGL dla Audaciousa\n"
+"Prawa autorskie: 2013 Christophe Budé, John Lindgren i Carlo Bramini\n"
+"Prawa autorskie 2014 William Pitcock\n"
+"\n"
+"Na podstawie wtyczki XMMS-a:\n"
+"Prawa autorskie 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas "
+"Nilsson i 4Front Technologies\n"
+"\n"
+"Licencja: GPL wersja 2 i późniejsze"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Skróty Gnome"
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "Analizator spektrum OpenGL (Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "Skróty GNOME"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+"Wtyczka skrótów GNOME\n"
+"Umożliwia obsÅugÄ odtwarzacza za pomocÄ
skrótów GNOME.\n"
+"\n"
+"Prawa autorskie (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Numer porzÄ
dkowy"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "TytuÅ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Wykonawca"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Rok"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Album"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Artysta albumu"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Numer Åcieżki"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Gatunek"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Pozycja w kolejce"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Czas trwania"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "PoÅożenie pliku"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Nazwa pliku"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "WÅasny tytuÅ (z ustawieÅ)"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Tempo transmisji"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "DostÄpne kolumny"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "WyÅwietlane kolumny"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "NarzÄdzie wyszukiwania"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Zaczep po lewej"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Zaczep po prawej"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Zaczep na górze"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Zaczep na dole"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Odczep"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "WyÅÄ
cz"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "NarzÄdzie wyszukiwania"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Otwórz pliki ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Otwórz adres _URL ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_Dodaj pliki ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Dodaj adres U_RL ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "_Wyszukaj w bibliotece"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "O _programie ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "_Ustawienia"
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "Za_koÅcz"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Odtwarzaj"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "_Wstrzymaj"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Zatrzymaj"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "P_oprzednie"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_NastÄpne"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "Powta_rzanie"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_Losowo"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Odtwarzaj _pojedynczo"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Z_atrzymaj odtwarzanie po tym utworze"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Informacje o Åcieżce..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Przejdź do _czasu..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "Przejdź do Åcież_ki..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "Ustaw punkt poczÄ
tkowy pÄtli"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "Ustaw punkt koÅcowy pÄtli"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_Resetuj punkty graniczne pÄtli"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "wedÅug _tytuÅu"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "wedÅug _nazwy pliku"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "WedÅug _nazwy pliku"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "wedÅug Åcieżki _pliku"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "wedÅug _numeru Åcieżki"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "wedÅug _wykonawcy"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "wedÅug al_bumu"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "wedÅug wykonawcy albu_mu"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
-msgstr "wedÅug _daty wydania"
+msgstr "wedÅug daty w_ydania"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "WedÅug _gatunku"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "wedÅug _dÅugoÅci"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "wedÅug p_oÅożenia pliku"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "wedÅug wÅa_snego tytuÅu"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "_OdwrÃ³Ä kolejnoÅÄ"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "Wy_losuj kolejnoÅÄ"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_Odtwórz listÄ odtwarzania"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_Odtwórz/Ponów"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Wczytaj ponownie"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Sortuj"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "Sortuj _wybrane"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "UsuÅ _duplikaty"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "_UsuÅ niedostÄpne pliki"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Nowa"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "Z_mieÅ nazwÄ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "_UsuÅ"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importuj..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Eksportuj..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "Menedżer _listy odtwarzania..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Menedżer _kolejki..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Z_wiÄksz gÅoÅnoÅÄ"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "Z_mniejsz gÅoÅnoÅÄ"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Korektor graficzny"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "E_fekty..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Pasek _menu"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Pasek _informacji"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Pokaż pasek wiz_ualizacji"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Pokaż pasek _stanu"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Pokaż _pozostaÅy czas"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "_Wizualizacje"
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Plik"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "Odt_warzanie"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Lista"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "W_tyczki"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_DźwiÄk"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Widok"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Dodaj/usuÅ kolejkÄ"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "_Otwórz katalog zawierajÄ
cy"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "_Wytnij"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "K_opiuj"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "Wk_lej"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "_Zaznacz wszystko"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "Z_mieÅ nazwÄ ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>Karty listy odtwarzania</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "Zawsze pokazuj karty"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "Pokaż statystykÄ nagraÅ"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "Pokaż przyciski zamykania"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>Kolumny listy odtwarzania</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "Pokaż nagÅówki listy odtwarzania"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Różne</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr "Przyciski strzaÅki przesuwajÄ
o:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "PrzewiÅ przy zmianie piosenki"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "Interfejs GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "Buforowanie ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
@@ -1989,84 +2090,98 @@ msgstr[0] "%d kanaÅ"
msgstr[1] "%d kanaÅy"
msgstr[2] "%d kanaÅów"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kb/s"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Tryb prosty."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Tryb listy odtwarzania."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Zatrzymaj po tym utworze."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Poprzedni utwór"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Odtwarzaj"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Wstrzymaj/wznów"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Zatrzymaj"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "NastÄpny utwór"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "PrzewiÅ o 5 sekund do przodu"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "PrzewiÅ o 5 sekund do tyÅu"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Wyciszenie dźwiÄku"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "ZwiÄksz gÅoÅnoÅÄ"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Zmniejsz gÅoÅnoÅÄ"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Przejdź do pliku"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "PrzeÅÄ
cz okno(a) odtwarzacza"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Pokaż menu ekranowe"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "WÅÄ
cz/WyÅÄ
cz powtarzanie"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "WÅÄ
cz/WyÅÄ
cz odtwaranie losowe"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "Zatrzymanie po bieżÄ
cej Åcieżce"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "PrzesuÅ na wierzch okno(a) odtwarzacza"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(brak)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2078,15 +2193,11 @@ msgstr ""
"\n"
"KontynuowaÄ?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Przyciski dowiÄ
zaÅ myszy"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Ustawienia wtyczki Global Hotkey"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2094,23 +2205,27 @@ msgstr ""
"ProszÄ wcisnÄ
Ä kombinacjÄ klawiszy wewnÄ
trz pola\n"
"tekstowego. Można również użyÄ przycisków myszy."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Skróty klawiszowe:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>CzynnoÅÄ:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Kombinacja klawiszy:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "_Dodaj"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Globalne skróty klawiszowe"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2124,7 +2239,7 @@ msgid ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-"Globalne skróty klawiszowe\n"
+"Wtyczka globalnych skrótów klawiszowych\n"
"Steruj odtwarzaniem przy użyciu globalnych skrótów klawiszowych lub "
"przycisków multimedialnych.\n"
"\n"
@@ -2137,59 +2252,56 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Globalne skróty klawiszowe"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "WyjÅcie JACK"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "PodÅÄ
cz siÄ do wszystkich dostÄpnych portów jacka"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "Automatycznie poÅÄ
cz z portami wyjÅcia"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "PodÅÄ
cz siÄ tylko do portów wyjÅciowych"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "Odnaleziono tylko %d portów wyjÅcia JACK, ale wymaganych jest %d."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "Nie podÅÄ
czaj siÄ do portów"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "WystÄ
piÅ bÅÄ
d przy poÅÄ
czeniu z portem JACK %s."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "Tryb podÅÄ
czenia"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+"JACK obsÅuguje tylko dźwiÄk zmiennoprzecinkowy. Musisz zmieniÄ rozdzielczoÅÄ "
+"bitowÄ
w ustawieniach dźwiÄku Audaciousa na tryb zmiennopozycyjny."
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "WÅÄ
cz wyjÅcie bÅÄdów"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "WystÄ
piÅ bÅÄ
d przy poÅÄ
czeniu z serwerem JACK. Czy jest uruchomiony?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Napisano na podstawie xmms-jack, prawa autorskie Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"Port dla Audaciousa: Giacomo Lozito"
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK"
+"Serwer JACK wymaga czÄstotliwoÅci próbkowania %d HZ, a Audacious odtwarza %d "
+"Hz. Użyj proszÄ Konwertera czÄstotliwoÅci próbkowania (wtyczki) aby usunÄ
Ä "
+"niezgodnoÅÄ."
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "Ustawienia %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Ustawienia wtyczki LADSPA Host"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "PoÅożenia moduÅów:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2200,82 +2312,41 @@ msgstr ""
"Po dodaniu nowych Åcieżek proszÄ wcisnÄ
Ä Enter, aby wyszukaÄ nowe wtyczki.</"
"small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "DostÄpne wtyczki:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "WÅÄ
cz"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "WÅÄ
czone wtyczki:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Ustawienia"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-"LADSPA Host for Audacious\n"
-"Copyright 2011 John Lindgren"
+"Serwer LADSPA dla Audacious\n"
+"Prawa autorskie 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
-msgstr "Host LADSPA"
-
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr ""
-"%s: nie można zainicjowaÄ wsparcia LIRC\n"
-"\n"
-"\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: nie udaÅo siÄ odczytaÄ pliku konfiguracji LIRC\n"
-" %s: proszÄ przeczytaÄ dokumentacjÄ LIRC\n"
-" %s: jak stworzyÄ prawidÅowy plik konfiguracji\n"
-"\n"
-"\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr ""
-"%s: próba ponownego podÅÄ
czenia...\n"
-"\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr ""
-"%s: nienzana komenda \"%s\"\n"
-"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: rozÅÄ
czono z LIRC\n"
+msgstr "Serwer LADSPA"
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: próbuj ponownie poÅÄ
czyÄ co %d sekund...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Wtyczka LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2290,85 +2361,95 @@ msgid ""
"\n"
"For more information about LIRC, see http://lirc.org."
msgstr ""
-"A simple plugin to control Audacious using the LIRC remote control daemon\n"
-"Adapted for Audacious by: \n"
+"Prosta wtyczka do kontroli Audaciousa za pomocÄ
demona zdalnej kontroli "
+"LIRC.\n"
+"\n"
+"Port na Audaciousa:\n"
"Tony Vroon <chainsaw at gentoo.org>\n"
"Joonas Harjumäki <jharjuma at gmail.com>\n"
"\n"
-"Based on the XMMS LIRC plugin by: \n"
+"Stworzono na podstawie wtyczki LIRC dla XMMS-a autorstwa:\n"
"Carl van Schaik <carl at leg.uct.ac.za>\n"
"Christoph Bartelmus <xmms at bartelmus.de>\n"
"Andrew O. Shadoura <bugzilla at tut.by>\n"
"\n"
-"For more information about LIRC, see http://lirc.org."
+"WiÄcej informacji LIRC-u, znajdziesz na stronie: http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>PoÅÄ
cznenie</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "PodÅÄ
cz ponownie do serwera LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Odczekaj przed ponownym poÅÄ
czeniem:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Wtyczka LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "Wtyczka LyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Nie znaleziono tekstu piosenki"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "BÅÄ
d"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Nie można pobraÄ %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "BÅÄ
d"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Nie można odczytaÄ %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Szukanie tekstu piosenk i ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "BrakujÄ
ce metadane utworu"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "ÅÄ
czenie z lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "Wtyczka LyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "Wtyczka LyricWiki (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "Lista odtwarzania M3U"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Generator taktu"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
-msgstr "Generator taktu: %d bpm"
+msgstr "Generator taktu: %d uderzeÅ na minutÄ"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Generator taktu: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2376,169 +2457,204 @@ msgid ""
"e.g. tact://77 to play 77 beats per minute\n"
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
+"Generator taktu autorstwa Martina Straussa <mys at faveve.uni-stuttgart.de>\n"
"\n"
-"To use it, add a URL: tact://beats*num/den e.g. tact://77 to play 77 beats "
-"per minute or tact://60*3/4 to play 60 bpm in 3/4 tacts"
+"Instrukcja: wprowadź adres URL: tact://uderzenia*liczba jednostek "
+"metrycznych/jednostka metryczna\n"
+"na przykÅad tact://77 aby wygenerowaÄ 77 uderzeÅ na minutÄ\n"
+"lub tact://60*3/4 aby wygenerowaÄ 60 uderzeÅ na minutÄ w metrum 3/4."
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Generator taktu"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Mikser kanaÅów"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-"Channel Mixer Plugin for Audacious\n"
-"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
+"Wtyczka miksera kanaÅów dla Audacious\n"
+"Prawa autorskie 2011-2012 John Lindgren i MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Mikser kanaÅów</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "IloÅÄ kanaÅów wyjÅciowych:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Mikser kanaÅów"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "Wtyczka MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "BÅÄ
d poÅÄ
czenia z serwerem MMS"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (odtwarzacz moduÅów)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>RozdzielczoÅÄ bitowa</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8 bitów"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16 bitów"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>KanaÅy</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "Najbliższa (najszybsza)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Liniowa (szybka)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Krzywa (dobra)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "PrzesuniÄcie fazowe (najlepsza)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr "<b>CzÄstotliwoÅÄ próbkowania</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Poziom:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "OdciÄcie:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Echo</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>Podbicie basów</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>DźwiÄk przestrzenny</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>Przedwzmacniacz</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "Próbkowanie nadmiarowe"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Redukcja szumów"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Odtwórz MOD-y Amigi"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Powtórz</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "IloÅÄ powtórzeÅ:"
-#: src/modplug/plugin_main.c:141
-msgid "To repeat forever, set the repeat count to -1."
-msgstr "By powtarzaÄ bez koÅca ustaw -1."
+#: src/modplug/plugin_main.cc:112
+msgid "To repeat forever, set the repeat count to -1."
+msgstr "By powtarzaÄ bez koÅca ustaw -1."
+
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
+"Poniższe ustawienia zostanÄ
wprowadzone w życie po restarcie Audaciousa."
+
+#: src/mpg123/mpg123.cc:54
+msgid "MPG123 Plugin"
+msgstr "Wtyczka MPG123"
+
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Zaawansowane</b>"
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (odtwarzacz moduÅów)"
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Użyj dokÅadnego obliczania dÅugoÅci (wolne)"
-#: src/mpg123/mpg123.c:210
+#: src/mpg123/mpg123.cc:248
msgid "Surround"
msgstr "DźwiÄk przestrzenny"
-#: src/mpg123/mpg123.c:412
-msgid "MPG123 Plugin"
-msgstr "Wtyczka MPG123"
-
-#: src/mpris2/plugin.c:403
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "Serwer MPRIS 2"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Wtyczka Neon HTTP/HTTPS"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "BÅÄ
d przetwarzania przekierowania"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Nieznany bÅÄ
d HTTP"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "BÅÄ
d przetwarzania adresu URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Za dużo przekierowaÅ"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Zatrzymany"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious nie odtwarza."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Powiadomienia na pulpicie"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2557,9 +2673,9 @@ msgid ""
"You should have received a copy of the GNU General Public License along with "
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-"Wtyczka powiadomieÅ pulpitowych Audaciousa\n"
+"Wtyczka powiadomieÅ pulpitowych dla Audaciousa\n"
"Prawa autorskie (C) 2010: Maximilian Bogner\n"
-"Prawa autorskie (C) 2011-2013 John Lindgren and Jean-Alexandre Anglès "
+"Prawa autorskie (C) 2011-2013 John Lindgren i Jean-Alexandre Anglès "
"d'Auriac\n"
"\n"
"Niniejsza wtyczka jest wolnym oprogramowaniem; można jÄ
rozprowadzaÄ dalej i/"
@@ -2576,55 +2692,64 @@ msgstr ""
"Publicznej GNU (GNU General Public License); jeÅli nie, odwiedź <http://www."
"gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Pokaż kontrolki odtwarzania"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Zawsze pokazuj powiadomienia"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Powiadomienia na pulpicie"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "DoÅÄ
cz nazwÄ albumu do powiadomienia"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Pokaż"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Wstrzymaj"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "NastÄpne"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. DomyÅlne urzÄ
dzenie"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "WyjÅcie OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "WyjÅcie OSS3"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "DomyÅlne urzÄ
dzenie"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "UrzÄ
dzenie dźwiÄkowe:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Użyj alternatywnego urzÄ
dzenia:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Zapisz poziom gÅoÅnoÅci."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "WÅÄ
cz konwersje formatu poprzez oprogramowanie OSS"
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "WÅÄ
cz tryb wyÅÄ
cznoÅci, aby wyÅÄ
czyÄ programowe miksowanie."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2632,25 +2757,42 @@ msgid ""
"I would like to thank people on #audacious, especially Tony Vroon and John "
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-"OSS4 Output Plugin for Audacious\n"
-"Copyright 2010-2012 MichaÅ Lipski\n"
+"Wtyczka wyjÅcia OSS4 dla Audaciousa Prawa autorskie: 2010-2012 MichaÅ "
+"Lipski\n"
"\n"
-"I would like to thank people on #audacious, especially Tony Vroon and John "
-"Lindgren and of course the authors of the previous OSS plugin."
+"ChciaÅbym wyraziÄ wdziÄcznoÅÄ bywalcom kanaÅu #audacious, szczególnie "
+"Tony'emu Vroonowi oraz Johnowi Lindgrenowi, a także, naturalnie, autorom "
+"poprzedniej wtyczki OSS."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Menedżer list odtwarzania"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Wpisy"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_UsuÅ"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "_ZmieÅ nazwÄ"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "Listy odtwarzania PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "Dekoder OpenPSF PSF1/PSF2"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "WyjÅcie PulseAudio"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2669,121 +2811,197 @@ msgid ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
msgstr ""
-"Audacious PulseAudio Output Plugin\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"
-"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"
-"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"
+"Wtyczka wyjÅcia PulseAudio dla Audaciousa\n"
+"Niniejszy program jest wolnym oprogramowaniem; możesz go\n"
+"rozprowadzaÄ dalej i/lub modyfikowaÄ na warunkach Powszechnej\n"
+"Licencji Publicznej GNU, wydanej przez FundacjÄ Wolnego\n"
+"Oprogramowania - wedÅug wersji 2-giej tej Licencji lub którejÅ\n"
+"z późniejszych wersji. \n"
+"\n"
+"Niniejszy program rozpowszechniany jest z nadziejÄ
, iż bÄdzie on \n"
+"użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyÅlnej \n"
+"gwarancji PRZYDATNOÅCI HANDLOWEJ albo PRZYDATNOÅCI DO OKREÅLONYCH \n"
+"ZASTOSOWAÅ. W celu uzyskania bliższych informacji - Powszechna \n"
+"Licencja Publiczna GNU. \n"
+"\n"
+"Z pewnoÅciÄ
wraz z niniejszym programem otrzymaÅeÅ też egzemplarz \n"
+"Powszechnej Licencji Publicznej GNU (GNU General Public License);\n"
+"jeÅli nie - napisz do Free Software Foundation, Inc., 51 Franklin Street, "
+"Fifth Floor, Boston, MA 02110-1301,\n"
+"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "WyjÅcie QtMultimedia"
-#: src/resample/resample.c:165
+#: src/qtaudio/qtaudio.cc:77
msgid ""
-"Sample Rate Converter Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
+"Wtyczka wyjÅcia dźwiÄkowego QtMultimedia dla Audacious\n"
+"Prawa autorskie 2014 William Pitcock\n"
+"\n"
+"Oparta na wtyczce wyjÅcia SDL dla Audacious\n"
+"Prawa autorskie 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "DziaÅanie..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Szukaj"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_Otwórz katalog..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_Dodaj katalog..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "_Dziennik programu"
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Otwórz pliki"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Dodaj pliki"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Poprzednie"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Powtarzaj"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Losowa kolejnoÅÄ"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Interfejs Qt"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Konwerter czÄstotliwoÅci próbkowania"
+
+#: src/resample/resample.cc:183
+msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
+msgstr ""
+"Wtyczka konwertera czÄstotliwoÅci próbkowania dla Audacious\n"
+"Prawa autorskie 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "PomiÅ/powtórz próbki"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Liniowa interpolacja"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Szybka interpolacja funkcji sinc"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "PoÅrednia interpolacja funkcji sinc"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Najlepsza interpolacja funkcji sinc"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Konwersja</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Metoda:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Klasa:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Mapowanie klasy</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Użyj klasy mapowania"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Konwerter czÄstotliwoÅci próbkowania"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "OK, Scrobblowanie dla użytkownika: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "Brak zezwolenia"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr "Użyj tego linku by zezwoliÄ Audacious na scrobblowanie twoich utworów."
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr "Pozostaw to okno otwarte i naciÅnij ponownie 'Sprawdź Uprawnienia'.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2792,43 +3010,47 @@ msgstr ""
"BÄdÄ
przekazane do Audacious tak szybko jak tylko bÄdzie miaÅ na to "
"pozwolenie."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
-msgstr "Problem sieciowy."
+msgstr "Problem z sieciÄ
."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
"WystÄ
piÅ problem przy skontaktowaniu siÄ z Last.fm. ProszÄ spróbuj ponownie."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "Sprawdzanie..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "S_prawdź zezwolenia"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "U_nieważnij pozwolenia"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"Musisz zezwoliÄ Audacious na scrobblowanie utworów do twojego konta Last."
"fm.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-"Plugin Scrobbler nie mógÅ zostaÄ uruchomiony.\n"
-"Prawdopodobnie ma miejsce problem z twojÄ
instalacjÄ
."
+"Wtyczka Scrobbler nie mogÅa zostaÄ uruchomiona.\n"
+"Prawdopodobnie wystÄ
piÅ problem z TwojÄ
instalacjÄ
."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2838,18 +3060,14 @@ msgid ""
"project.\n"
"\n"
msgstr ""
-"Plugin Scrobbler dla Audacious 2.0 przez Pitxyoki,\n"
+"Wtyczka Scrobbler dla Audacious 2.0, przez Pitxyoki,\n"
"\n"
-"Copyright © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com>\n"
+"Prawa autorskie © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com>\n"
"\n"
-"PodziÄkowania dla John Lindgren za wsparcie a poczÄ
tku projektu.\n"
+"PodziÄkowania dla John Lindgren za wsparcie na poczÄ
tku projektu.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2857,96 +3075,71 @@ msgstr ""
"Audacious używa obecnie poprawionej wersji Scrobblera Last.fm.\n"
"ProszÄ sprawdź ustawienia dla wtyczki Scrobbler."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "WyjÅcie SDL"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-"SDL Output Plugin for Audacious\n"
-"Copyright 2010 John Lindgren"
-
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL"
+"Wtyczka wyjÅcia SDL dla Audacious\n"
+"Prawa autorskie 2010 John Lindgren"
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Biblioteka"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Nieznany artysta"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Nieznany album"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" na %s przez %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d wynik"
+msgstr[1] "%d wyniki"
+msgstr[2] "%d wyników"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d album"
-msgstr[1] "%d albumy"
-msgstr[2] "%d albumów"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d ukryty)"
+msgstr[1] "(%d ukryte)"
+msgstr[2] "(%d ukrytych)"
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d piosenka"
-msgstr[1] ""
-"%s\n"
-" %s, %d piosenki"
-msgstr[2] ""
-"%s\n"
-" %s, %d piosenek"
-
-#: src/search-tool/search-tool.c:639
-#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d piosenka przez %s"
-msgstr[1] ""
-"%s\n"
-" %d piosenek przez %s"
-msgstr[2] ""
-"%s\n"
-" %d piosenek przez %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d piosenka"
+msgstr[1] "%d piosenki"
+msgstr[2] "%d piosenek"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "tego gatunku"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "na"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "przez"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Utwórz listÄ odtwarzania"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Dodaj do listy odtwarzania"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Przeszukaj bibliotekÄ"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2954,679 +3147,771 @@ msgstr ""
"Aby zaimportowaÄ kolekcjÄ muzycznÄ
, proszÄ wybraÄ katalog i kliknÄ
Ä przycisk "
"ponownego wczytywania."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "ProszÄ czekaÄ ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Wybierz katalog"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "Odtwarzacz SID"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>WyjÅcie</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "KanaÅy:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Emulacja</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "Emuluj MOS 8580 (domyÅlnie: MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "Nie wybieraj automatycznie modela czipu"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Emuluj filtr"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Taktowanie zegara:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "Nie wybieraj automatycznie taktowania zegara"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>Czas odtwarzania</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "Ustaw najdÅuższy czas odtwarzania:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Użyj tylko, jeÅli dÅugoÅÄ piosenki jest nieznana"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "Ustaw najkrótszy czas odtwarzania:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Tony poÅrednie</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "WÅÄ
cz tony poÅrednie"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "Pomijaj tony poÅrednie krótsze niż:"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Uwaga</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Usuwanie ciszy"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"Wtyczka usuwania ciszy dla Audacious\n"
+"Prawa autorskie 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Usuwanie ciszy</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Próg:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "Otwórz pliki..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "Otwórz URL..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Przeszukaj bibliotekÄ"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Odtwarzanie"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Lista odtwarzania"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Widok"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "UsÅugi"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "O..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "Ustawienia..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "ZakoÅcz"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "Informacje o piosence..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Powtarzaj"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Losowa kolejnoÅÄ"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Odtwarzaj pojedynczo"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "Zatrzymaj odtwarzanie po tym utworze"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Poprzednie"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "Ustaw powtarzanie od punktu A do punktu B"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "UsuÅ powtarzanie A-B"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "Przejdź do piosenki..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "Przejdź do czasu..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "Odtwórz tÄ listÄ odtwarzania"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "Odtwórz/Ponów"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Nowa lista odtwarzania"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "ZmieÅ nazwÄ listy odtwarzania..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "UsuÅ listÄ odtwarzania"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "Poprzednia lista odtwarzania"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "NastÄpna lista odtwarzania"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "Importuj listÄ odtwarzania..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "Eksportuj listÄ odtwarzania..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "Menedżer list odtwarzania..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "Menedżer kolejki..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "OdÅwież listÄ odtwarzania"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Okno listy odtwarzania"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Okno korektora graficznego"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "Pokaż pozostaÅy czas"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Zawsze na wierzchu"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "Na wszystkich pulpitach"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "ZwiÅ odtwarzacz"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "ZwiÅ okno listy odtwarzania"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "ZwiÅ okno korektora graficznego"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Podwójny rozmiar"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "Dodaj adres URL..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "Dodaj pliki..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
-msgstr "wedÅug tytuÅu"
+msgstr "WedÅug tytuÅu"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "wedÅug nazwy pliku"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr "WedÅug nazwy pliku"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "WedÅug Åcieżki dostÄpu"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "UsuÅ wszystkie"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "WyczyÅÄ kolejkÄ"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "UsuÅ niedostÄpne"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "UsuÅ duplikaty"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "UsuÅ niezaznaczone"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "UsuÅ zaznaczone"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Szukaj i wybierz"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "OdwrÃ³Ä zaznaczenie"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "WyczyÅÄ zaznaczenie"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Zaznacz wszystko"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "wedÅug albumu"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "wedÅug numeru Åcieżki"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "wedÅug wykonawcy"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "wedÅug albumu"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "wedÅug wykonawcy albumu"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "wedÅug daty wydania"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "wedÅug numeru Åcieżki"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "WedÅug gatunku"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "WedÅug dÅugoÅci"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "WedÅug wÅasnego tytuÅu"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Wymieszaj listÄ odtwarzania"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "OdwrÃ³Ä kolejnoÅÄ listy odtwarzania"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Posortuj zaznaczone"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Sortuj"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Wytnij"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
-msgstr "Skopiuj"
+msgstr "Kopiuj"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Wklej"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "PrzeÅÄ
cz kolejkÄ"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "Wczytaj ustawienia..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "Wczytaj automatyczne ustawienia"
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "Wczytaj domyÅlne"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "Wczytaj plik ustawieÅ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "Wczytaj plik EQF..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "Zapisz ustawienia..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "Zapisz automatyczne ustawienia"
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "Zapisz domyÅlne"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "Zapisz plik ustawieÅ..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "Zapisz plik EQF..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "UsuÅ ustawienia"
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "UsuÅ automatyczne ustawienia..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "Importuj ustawienia Winampa..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "Wyzeruj"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Klasyczny interfejs Winampa"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Zapisz"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Wczytaj"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "Wczytaj plik ustawieÅ"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "Wczytaj plik EQF"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "Zapisz plik ustawieÅ"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "Zapisz plik EQF"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "Importuj ustawienia Winampa"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Profile ustawieÅ"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Wczytaj ustawienia"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Wczytaj automatyczne ustawienia"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Zapisz ustawienia"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Zapisz automatyczne ustawienia"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "UsuÅ ustawienia"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "UsuÅ automatyczne ustawienia"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "Odtwa_rzacz:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Odtwarzacz:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
-msgstr "Wybór czcionki okna odtwarzacza"
+msgstr "Wybór czcionki okna odtwarzacza:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Lista odtwarzania:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Lista odtwarzania:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Wybór czcionki listy odtwarzania"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>Skórka</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>Czcionki</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Czcionki bitmapowe (obsÅuguje tylko kodowanie ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "Przewijaj tytuÅ piosenki"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Przewijanie tytuÅu utworu w obydwu kierunkach"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analizator"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Zakres"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "Spektogram / wskaźnik wysterowania"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "WyÅÄ
czony"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "ZwykÅy"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Ognisty"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "Pionowe linie"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Linie"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Kolumny"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Najwolniejszy"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Wolny"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Åredni"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Szybki"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Najszybszy"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "Kropki"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "Linia"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "ZwykÅy"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Lodowy"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "WygÅadzony"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>Sposób</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "Sposób wizualizacji:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>Analizator</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "Pokaż wartoÅci szczytowe"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "Kolorowanie:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "Styl: "
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "Upadanie:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "Upadanie wartoÅci szczytowych:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "Stylistyka ksztaÅtu:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "Kolor spektogramu:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "Styl wskaźnika wysterowania:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Ogólne"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Wizualizacja"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Przedwzmacniacz"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Korektor graficzny Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Skocz do: %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "GÅoÅnoÅÄ: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Balans: %d%% lewy"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Balans: centralny"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Balans: %d%% prawy"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Menu opcji"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "WyÅÄ
cz 'Zawsze na wierzchu'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "WÅÄ
cz 'Zawsze na wierzchu'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Obszar informacji o pliku"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "Wizualizacje"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "Ustawiono punkt poczÄ
tkowy pÄtli."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "Ustawiono punkt koÅcowy pÄtli."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "Zresetowano punkty graniczne pÄtli."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Tryb prosty."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Tryb listy odtwarzania."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Zatrzymaj po tym utworze."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Wyszukaj wpisy w aktywnej playliÅcie"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "Szukaj"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3638,57 +3923,61 @@ msgstr ""
"nie wiesz, jak dziaÅajÄ
wyrażenia regularne, wpisz po prostu to, czego "
"szukasz."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "TytuÅ: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr "TytuÅ:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr "Album:"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Wykonawca: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr "Artysta:"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Nazwa pliku: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Nazwa pliku:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "WyczyÅÄ poprzednie zaznaczenie przed szukaniem"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Automatycznie przeÅÄ
cz kolejkÄ dla pasujÄ
cych wpisów"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Utwórz nowÄ
playlistÄ z pasujÄ
cymi wpisami"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Edytor listy odtwarzania Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d z %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Zarchiwizowany styl programu Winamp 2.x"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Styl programu Winamp 2.x"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Nie można utworzyÄ katalogu (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Wtyczka Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3709,96 +3998,93 @@ msgid ""
"this program; if not, write to the Free Software Foundation, Inc., 51 "
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-"Based on the xmms_sndfile plugin: Copyright (C) 2000, 2002 Erik de Castro "
-"Lopo\n"
-"Adapted for Audacious by Tony Vroon <chainsaw at gentoo.org>\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"
-"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"
-"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."
-
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Wtyczka Sndfile"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "O wtyczce wyjÅcia Sndio"
-
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
+"Stworzono na podstawie wtyczki xmms_sndfile:\n"
+"Prawa autorskie (C) 2000, 2002 Erik de Castro Lopo\n"
"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Wtyczka wyjÅcia Sndio\n"
+"Port na Audaciousa: Tony Vroon <chainsaw at gentoo.org>\n"
"\n"
-"Autorstwo Thomas Pfaff <tpfaff at tp76.info>\n"
-
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "NieobsÅugiwany format pliku"
-
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
+"Niniejszy program jest wolnym oprogramowaniem; możesz go rozprowadzaÄ dalej "
+"i/lub modyfikowaÄ na warunkach PowszechnejLicencji Publicznej GNU, wydanej "
+"przez FundacjÄ WolnegoOprogramowania - wedÅug wersji 2-giej tej Licencji lub "
+"którejÅz późniejszych wersji.\n"
"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"Format jest nieobsÅugiwany przez urzÄ
dzenie.\n"
+"Niniejszy program rozpowszechniany jest z nadziejÄ
, iż bÄdzie on użyteczny - "
+"jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyÅlnej gwarancji PRZYDATNOÅCI "
+"HANDLOWEJ albo PRZYDATNOÅCI DO OKREÅLONYCH ZASTOSOWAÅ. W celu uzyskania "
+"bliższych informacji - Powszechna Licencja Publiczna GNU.\n"
"\n"
-"Spróbuj ponownie z uruchomionym serwerem sndiod(1)."
+"Z pewnoÅciÄ
wraz z niniejszym programem otrzymaÅeÅ też egzemplarz "
+"Powszechnej Licencji Publicznej GNU (GNU General Public License);jeÅli nie - "
+"napisz do Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, "
+"Boston, MA 02110-1301, USA."
+
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "WyjÅcie Sndio"
+
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "UrzÄ
dzenie (puste oznacza domyÅlne):"
+
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Zapisz i przywrÃ³Ä gÅoÅnoÅÄ:"
+
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "BÅÄ
d Sndio: NieobsÅugiwany format dźwiÄku (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "urzÄ
dzenie sndio"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "BÅÄ
d Sndio: funkcja sio_open() zwróciÅa bÅÄ
d"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(pusty oznacza domyÅlne)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "BÅÄ
d Sndio: funkcja sio_setpar() zwróciÅa bÅÄ
d"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "BÅÄ
d Sndio: funkcja sio_start() zwróciÅa bÅÄ
d"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Polecenie przy zmianie Åcieżki"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Wykonaj polecenie kiedy uruchamiasz odtwarzanie."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Parametry przekazywane do powÅoki powinny byÄ zawarte w "
+"cudzysÅowach. Ich brak jest zagrożeniem dla bezpieczeÅstwa systemu.</span>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Polecenie:"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Polecenia</b>"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "KoÅcz odtwarzanie Åcieżki."
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Polecenie do uruchomienia przy rozpoczÄciu nowej piosenki:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "ZakoÅczenie odtwarzania listy odtwarzania."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Polecenie do uruchomienia przy zakoÅczeniu piosenki:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
-msgstr "ZmieÅ tytuÅu Åcieżki (np. użyteczne dla internetowych strumieni)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Polecenie do uruchomienia przy zakoÅczeniu listy odtwarzania:"
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr ""
+"Polecenie do uruchomienia, gdy zmieni siÄ tytuÅ piosenki (dla "
+"strumieniowania sieciowego):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3812,35 +4098,31 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Możesz użyÄ nastÄpujÄ
cych ciÄ
gów formatowania, które\n"
-"zostanÄ
zastÄ
pione przez wywoÅaniem komendy\n"
-"(nie wszystkie sÄ
użyteczne przy komendach 'koniec playlisty'):\n"
+"Możesz użyÄ poniższych symboli, które zostanÄ
zastÄ
pione przed wywoÅaniem "
+"polecenia (nie wszystkie sÄ
użyteczne jeÅli chodzi o polecenie wywoÅywane po "
+"zakoÅczeniu listy odtwarzania):\n"
"\n"
-"%F: CzÄstotliwoÅÄ (Hz)\n"
+"%F: CzÄstotliwoÅÄ (w hercach)\n"
"%c: Liczba kanaÅów\n"
-"%f: Nazwa pliku (peÅna Åcieżka)\n"
-"%l: DÅugoÅÄ (ms)\n"
-"%n lub %s: Nazwa piosenki\n"
-"%r: SzybkoÅÄ (b/s)\n"
-"%t: Pozycja playlisty (%02d)\n"
-"%p: Aktualnie odtwarzane (1 or 0)\n"
-"%a: Artysta\n"
+"%f: PeÅna nazwa (ze ÅcieżkÄ
dostÄpu)\n"
+"%l: DÅugoÅÄ (w milisekundach)\n"
+"%n lub %s: Nazwa nagrania\n"
+"%r: PrzepÅywnoÅÄ (w bitach na sekundÄ)\n"
+"%t: Pozycja na liÅcie odtwarzania (%02d)\n"
+"%p: Aktualnie odtwarzane (1 lub 0)\n"
+"%a: Wykonawca\n"
"%b: Album\n"
-"%T: TytuÅ utworu"
+"%T: Nazwa Åcieżki"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>Parametry przekazywane do powÅoki powinny byÄ zawarte w "
-"cudzysÅowach. Ich brak jest zagrożeniem dla bezpieczeÅstwa systemu.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Informacje o utworze (Qt)"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Polecenia"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "Konwerter czÄstotliwoÅci SoX"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3848,57 +4130,57 @@ msgid ""
"Based on Sample Rate Converter Plugin:\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-"Plugin SoX Resampler dla Audacious\n"
-"Copyright 2013 MichaÅ Lipski\n"
+"Wtyczka SoX Resampler dla Audacious\n"
+"Prawa autorskie 2013 MichaÅ Lipski\n"
"\n"
-"Bazowany na wtyczce Sample Rate Converter:\n"
-"Copyright 2010-2012 John Lindgren"
+"Oparty na wtyczce Sample Rate Converter:\n"
+"Prawa autorskie 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Szybki"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Wolny"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Wysoki"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Bardzo wysoki"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "JakoÅÄ:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "Konwerter czÄstotliwoÅci SoX"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "SzybkoÅÄ i wysokoÅÄ tonu"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>SzybkoÅÄ i wysokoÅÄ tonu</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "SzybkoÅÄ:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "WysokoÅÄ tonu:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "SzybkoÅÄ i wysokoÅÄ tonu"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Ikona statusu"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "_Ustawienia..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3914,39 +4196,39 @@ msgstr ""
"Wtyczka wyÅwietla ikonÄ statusu, umieszczonÄ
w obszarze ikon powiadomienia "
"menedżera okien."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Akcja dla przewijania kóÅkiem myszy</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Zmiana gÅoÅnoÅci"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Zmiana bieżÄ
cej Åcieżki"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Inne ustawienia</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "WyÅÄ
czenie wyskakujÄ
cych komunikatów"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Zamknij do zasobnika systemowego"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Przejdź do nastÄpnej Åcieżki przewijajÄ
c w górÄ"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Ikona statusu"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Dodatkowe stereo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3955,24 +4237,24 @@ msgstr ""
"Wtyczka generujÄ
ca dodatkowy efekt stereo\n"
"Autor: Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Dodatkowe stereo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Dodatkowe stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Generator sygnaÅów"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Generator sygnaÅów: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3980,21 +4262,19 @@ msgid ""
"To use it, add a URL: tone://frequency1;frequency2;frequency3;...\n"
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-"Sine tone generator by Håvard Kvålen <havardk at xmms.org> \n"
-"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
+"Autor generatora sinusoidalnego: Håvard Kvålen <havardk at xmms.org>\n"
+"Poprawki: Daniel J. Peng <danielpeng at bigfoot.com>\n"
"\n"
-"To use it, add a URL: tone://frequency1;frequency2;frequency3;... e.g. "
-"tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
-
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Generator sygnaÅów"
+"Instrukcja użytkowania: wprowadź URL tone://czÄstotliwoÅÄ1;czÄstotliwoÅÄ2;"
+"czÄstotliwoÅÄ3;...\n"
+"przykÅadowo wprowadzenie: tone://2000;2005 wytworzy dźwiÄk o czÄstotliwoÅci "
+"2000 Hz oraz 2005 Hz."
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Usuwanie gÅosu (karaoke)"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4016,7 +4296,7 @@ msgid ""
msgstr ""
"Dekoder OGG Vorbis dla Audaciousa\n"
"\n"
-"Bazowany na kodzie wtyczki Ogg Vorbis fundacji Xiph.org:\n"
+"Oparty na kodzie wtyczki Ogg Vorbis fundacji Xiph.org:\n"
"http://www.xiph.org/\n"
"\n"
"Autor oryginalnego kodu:\n"
@@ -4032,11 +4312,46 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Dekoder Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "SzczegóÅy o %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"TytuÅ: %t\n"
+"Autor: %a\n"
+"Z: %f\n"
+"Tropiciel: %T\n"
+"Komentarz: %C\n"
+"Rodzaj ukÅadu: %c\n"
+"Stereo: %s\n"
+"PÄtla: %l\n"
+"CzÄstotliwoÅÄ ukÅadu: %F\n"
+"CzÄstotliwoÅÄ odtwarzacza: %P\n"
+"Rok: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "Dekoder VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4047,19 +4362,19 @@ msgstr ""
"ru>\n"
"Wtyczka Audaciousa napisana przez Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "Dekoder VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "Dekoder WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "stratna (hybryda)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "stratna"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4069,14 +4384,18 @@ msgstr ""
"\n"
"CzÄÅÄ kodu napisana przez Milesa Egana."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "Dekoder WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "Dekoder 2SF"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>Konfiguracja XSF</b>"
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Ignorowanie czasu trwania z pliku"
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
-msgstr "WspóÅdzielone playlisty XML (XSPF)"
+msgstr "WspóÅdzielone listy odtwarzania XML (XSPF)"
diff --git a/po/process-transifex-po b/po/process-transifex-po
index afdd1bb46598..4a29c2ff91e9 100755
--- a/po/process-transifex-po
+++ b/po/process-transifex-po
@@ -85,6 +85,9 @@ lt.po)
lv.po)
LANGUAGE="Latvian"
;;
+ms.po)
+ LANGUAGE="Malay"
+ ;;
nl.po)
LANGUAGE="Dutch"
;;
@@ -118,8 +121,8 @@ sr.po)
sr_RS.po)
LANGUAGE="Serbian (Serbia)"
;;
-sr at latin.po)
- LANGUAGE="Serbian (Latin)"
+sv.po)
+ LANGUAGE="Swedish"
;;
ta.po)
LANGUAGE="Tamil"
diff --git a/po/pt_BR.po b/po/pt_BR.po
index c23974aa422f..b459197ec590 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -3,23 +3,25 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# salmora8 <shorterfire at gmail.com>, 2013
+# Alexandro Casanova <shorterfire at gmail.com>, 2013
+# Conservador Ressurge, 2014
+# Eudes Soares <eudes.sp2007 at gmail.com>, 2014
# Fuad Saud <fuadksd at gmail.com>, 2012
# mcnd2 <glauber_gf at hotmail.com>, 2012
# John_Norum <john.norum4 at gmail.com>, 2012
# Bruno Bacelar <mail2buy8 at gmail.com>, 2012
# Rafael Ferreira <rafael.f.f1 at gmail.com>, 2012
# Rodrigo Macedo <rodrigomacedo at rmsolucoeseminformatica.com>, 2012
-# salmora8 <shorterfire at gmail.com>, 2012-2013
+# Alexandro Casanova <shorterfire at gmail.com>, 2012-2013
# vitorgatti <vitorgatti at yahoo.com.br>, 2012
-# salmora8 <shorterfire at gmail.com>, 2012
+# Alexandro Casanova <shorterfire at gmail.com>, 2012
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/"
"audacious/language/pt_BR/)\n"
"Language: pt_BR\n"
@@ -28,40 +30,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "surround"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
-msgstr ""
+msgstr "Decodificador AAC(Bruto)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib Player)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "sequenciado"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib Player)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarme"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
-msgstr ""
+msgstr "Definir Alarme ..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -72,11 +62,7 @@ msgstr ""
"\n"
"Originalmente escrito por Adam Feakin e Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarme"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -117,7 +103,7 @@ msgstr ""
" padrão.\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -156,7 +142,7 @@ msgstr ""
" Comando Adicional:\n"
" Executar esse comando no momento do alarme.\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -181,183 +167,156 @@ msgstr ""
" Digite o lembrete na caixa e ligue-o\n"
" botão habilitar/desabilitar, se você quer que ele seja mostrado."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Este é o seu alerta."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "Seu lembrete para hoje é..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Lembrete"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Segunda-feira"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Terça-feira"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Quarta-feira"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Quinta-feira"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Sexta-feira"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Sábado"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Domingo"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Configurações do Alarme"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Horário"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarme às (padrão):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Silenciar após:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "horas"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minutos"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Escolha os dias para o alarme tocar"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Dia"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Padrão"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Dias"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Enfraquecimento"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "segundos"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Volume"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Começar no"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Final"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Atual"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Comando Adicional"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "habilitar"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Lista de Reprodução (opcional)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Selecionar uma Lista de Reprodução"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Opções"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "O que significam estas opções?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Ajuda"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Imagem do Ãlbum"
-#: src/alsa/config.c:210
-msgid "Default PCM device"
-msgstr "Dispositivo PCM padrão"
-
-#: src/alsa/config.c:239
-msgid "Default mixer device"
-msgstr "Dispositivo mixer padrão"
-
-#: src/alsa/config.c:428
-msgid "PCM device:"
-msgstr "Dispositivo PCM:"
-
-#: src/alsa/config.c:430
-msgid "Mixer device:"
-msgstr "Dispositivo mixer:"
-
-#: src/alsa/config.c:432
-msgid "Mixer element:"
-msgstr "Elemento mixer:"
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Arte do Ãlbum (Qt)"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Solução para impedir a suspensão"
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "SaÃda ALSA"
-#: src/alsa/plugin.c:27
+#: src/alsa/config.cc:28
msgid ""
"ALSA Output Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren\n"
@@ -373,194 +332,208 @@ msgstr ""
"cujo código serviu como referencia quando a documentação ALSA não era o "
"suficiente."
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "SaÃda ALSA"
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
+msgid "Default PCM device"
+msgstr "Dispositivo PCM padrão"
+
+#: src/alsa/config.cc:188
+msgid "Default mixer device"
+msgstr "Dispositivo mixer padrão"
-#: src/amidi-plug/amidi-plug.c:466
+#: src/alsa/config.cc:296
+msgid "PCM device:"
+msgstr "Dispositivo PCM:"
+
+#: src/alsa/config.cc:299
+msgid "Mixer device:"
+msgstr "Dispositivo mixer:"
+
+#: src/alsa/config.cc:302
+msgid "Mixer element:"
+msgstr "Elemento mixer:"
+
+#: src/amidi-plug/amidi-plug.cc:41
msgid "AMIDI-Plug (MIDI Player)"
msgstr "AMIDI-Plug (Player MIDI)"
-#: src/amidi-plug/i_configure.c:96
-msgid "Override default gain:"
+#: src/amidi-plug/amidi-plug.cc:437
+msgid ""
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
+"\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:94
+msgid "Override default gain:"
+msgstr "Sobrescrever ganho padrão:"
+
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
-msgstr ""
+msgstr "Sobrescrever polifonia padrão:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
-msgstr ""
+msgstr "Sobrescrever reverberação padrão:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
-msgstr ""
+msgstr "Ativo"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
-msgstr ""
+msgstr "Sobrescrever coro padrão:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
-msgid "Drum shift:"
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:132
+msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "número de notas"
+
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
-msgstr ""
-
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr ""
+msgstr "<b>Sintetizador</b>"
+
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "Taxa de amostragem:"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - Selecione o arquivo SoundFont"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Cancelar"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
-msgstr ""
+msgstr "_Abrir"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "Nome do arquivo"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "Nome do Arquivo"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Tamanho (bytes)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nome:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\">Informações MIDI</span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Formato:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Duração (msec):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "N.º de Faixas;"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variável"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Div. de tempo:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> Comentários de MIDI e Letras </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* Sem comentários disponÃveis neste arquivo MIDI *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* Sem letras disponÃveis neste arquivo MIDI *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Fechar"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (UTF-8 invalido)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Sobre o AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"Player de música modular MIDI\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"Escrito por Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"Agradecimentos especias para...\n"
-"\n"
-"Clemens Ladisch e Jaroslav Kysela\n"
-"pelos excelentes programas aplaymidi e amixer; foram\n"
-"realmente úteis, juntamente com a documentação alsa-lib, de modo\n"
-"a aprender mais sobre a API ALSA\n"
-"\n"
-"Alfredo Spadafina\n"
-"pelo bonito logotipo do teclado midi\n"
-"\n"
-"Tony Vroon\n"
-"pela boa ajuda como um testador alpha."
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -571,151 +544,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (OSD)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Retângulo"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Retângulo Arredondado"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Retângulo Côncavo"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Nada"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Iniciar Reprodução"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Ativar OSD ao reproduzir uma faixa da lista de reprodução"
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Mudança de TÃtulo"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Ativar OSD quando, durante a reprodução, o tÃtulo da faixa for alterado, mas "
-"o nome do ficheiro permanecer igual. Ãtil nas reproduções de emissões web."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Pausar"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Ativar OSD se a reprodução for colocada em pausa"
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Despausar"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Ativar OSD ao retomar a reprodução"
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Localização"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "X relativo:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Y Relativo:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Largura máxima do OSD:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Opções de múltiplos monitores "
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Exibir uso do OSD:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "todos os monitores"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "monitor %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Duração (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Exibição:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Aparecer gradual:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Desaparecer gradual:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Tipo de letra"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Tipo de letra %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Sombra"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Estilo de renderização"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Cores"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Cor %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Habilitar gatilho"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Evento "
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Gerenciador Composite detectado"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -725,112 +693,112 @@ msgstr ""
"ao menos que você saiba que tenha executado, por favor ative um gerenciador "
"composite, caso contrario o OSD não vai funcionar corretamente "
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Não é necessário o gerenciador Composite para falsa transparência."
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Transparência "
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Falsa transparência "
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Transparência Real (requer a Extensão X Composite.)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Extensão Composite não carregada"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Extensão Composite não disponÃvel"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - configuração"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Posição"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animação"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Texto"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Decoração"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Gatilho"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Vários"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Teste"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "Listas de Reproduções ASXv1/ASXv2"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Listas de Reproduções Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Cor</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Ofuscar Escopo"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Estereofônico Bauer para Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Pré-ajuste:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "NÃvel alimentar:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Frequência de corte:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Pré-ajuste:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Estereofônico Bauer para Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Analisador Espectro"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Plugin de CD de Ãudio"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -851,171 +819,156 @@ msgstr ""
"\n"
"Este foi um projeto do Google Summer of Code 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Dispositivo</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Velocidade de Leitura:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Substituir dispositivo:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadados</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Utilizar CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Usar CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Use HTTP em vez de CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Servidor:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Caminho:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Porta:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Plugin de CD de Ãudio"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "Falha ao iniciar o subsistema cdio."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "URI Inválido %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Faixa %d não encontrada."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "A faixa %d é uma faixa de dados."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Falha ao abrir a saÃda de áudio."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Erro ao ler CD de áudio. "
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Audio CD "
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Falha ao abrir dispositivo de CD %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Não se encontrou drive de CD capaz de reproduzir áudio."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "Falha ao terminar de inicializar drive de CD aberto."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Falha ao recuperar primeiro/ultimo número de faixa."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Não foi possÃvel começar/terminar LSN da faixa %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Falha ao criar a conexão cddb."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Falha ao consultar o servidor CDDB."
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Falha ao consultar o servidor CDDB: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Falha ao ler as informações cddb: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Unidade está vazia."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Tipo de disco não suportado."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Itens do Menu do Ãudio CD"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Reproduzir CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Adicionar CD "
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Itens do Menu do Ãudio CD"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Compressão</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Volume Central:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Latitude de exposição:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Plugin Latitude de Exposição do Compressor para Audacious\n"
-"Copyright 2010-2012 John Lindgren."
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Latitude de Exposição do Compressor"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1031,206 +984,225 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>."
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Graves:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Agudos:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
-msgstr ""
+msgstr "Eco:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Duração da música:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>Reamostragem</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Ativar reamostragem de audio"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Taxa de reamostragem:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ignorar duração de tags SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Acrescentar \"reverb\""
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Decodificador Game Console Music"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-"A sobreposição falhou porque existem faixas com um número de canais "
-"diferente. Pode utilizar o canal mixer para converter o número das faixas."
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-"Crossfading falhou porque as musicas tinham diferentes taxas de amostragem. "
-"Você pode usar o Conversor de Taxa de Amostragem para converter as músicas "
-"para a mesma taxa de amostragem."
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Plugin Crossfade para Audacious\n"
-"Copyright 2010-2012 John Lindgren."
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Crossfade</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "Sobrepor:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Crossfade"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"A sobreposição falhou porque existem faixas com um número de canais "
+"diferente. Pode utilizar o canal mixer para converter o número das faixas."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"Crossfading falhou porque as musicas tinham diferentes taxas de amostragem. "
+"Você pode usar o Conversor de Taxa de Amostragem para converter as músicas "
+"para a mesma taxa de amostragem."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Cristalizar</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intensidade:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Cristalizador"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Plugin Cue Sheet"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Deletar Arquivos"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
-msgstr ""
+msgstr "Erro apagando %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
-msgstr ""
+msgstr "Erro apagando %s: não é um arquivo local."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
-msgstr ""
+msgstr "Deseja mover os arquivos selecionados para a lixeira?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
-msgstr ""
+msgstr "Mover para Lixeira"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
-msgstr ""
+msgstr "Deseja excluir permanentemente os arquivos selecionados?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Apagar"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Cancelar"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
-msgstr ""
+msgstr "Deletar Arquivos Selecionados"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Eco</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Atraso:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Comentários:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Volume:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Plugin Eco\n"
-"Por Johan Levin, 1999\n"
-"\n"
-"Eco evolvente por Carl van Schaik, 1999."
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Eco"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Plugin FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1247,55 +1219,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>."
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "Plugin FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Plugin FileWriter"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Formato de saÃda do arquivo:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Configurar"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Salvar no diretório original"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Salvar em diretório personalizado"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Pasta de destino:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Escolha uma pasta"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Obter nome de arquivo:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Gerar nome de arquivo a partir de:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "Tags originais do arquivo"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Etiqueta do arquivo original"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "nome do arquivo original"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Nome do arquivo original"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Não tirar a extensão do nome do arquivo"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Acrescentar número de faixa ao nome do arquivo"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1326,165 +1298,169 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "Plugin FileWriter"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Automático"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Joint Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Configuração MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_OK"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Qualidade do AlgorÃtimo:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "SaÃda de taxa de amostragem:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr "Taxa de Amostragem de SaÃda:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Taxa de dados /Taxa de compreensão:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "Taxa de compressão:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Taxa de dados (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Taxa de compressão:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Modo de áudio:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "Diversos:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "Assegurar o cumprimento estrito ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Proteção de erros"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Qualidade"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Ativar VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tipo:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Opções VBR"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Taxa mÃnima (kbps)"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Taxa máxima (kbps)"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Cumprir rigorosamente taxa de bits mÃnima"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Opções ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Taxa média (kbps)"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "NÃvel de qualidade VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Não gravar cabeçalho VBR Xing "
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Omitir cabeçalho Xing VBR"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "Parâmetros:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Assinalar como copyright"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Assinalar como original"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "Parâmetros ID3:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Forçar adição de tag, versão 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Somente adicionar tag v1 "
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Somente adicionar tag v2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Tags"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Configuração do codificador Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "NÃvel de Qualidade (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "Decodificador FLAG"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "sem perdas"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1496,11 +1472,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "Decodificador FLAG"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1508,11 +1480,19 @@ msgstr ""
"Plugin GIO para Audacious\n"
"Copyright 2009-2012 John Lindgren."
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "Plugin GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "Modo de abertura inválido"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1524,533 +1504,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "Analisador Spectrum OpenGl"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
-"Plugin Atalhos GNOME\n"
-"Permite controlar o player com atalhos do gnome.\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>."
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Atalhos Gnome"
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "Atalhos do GNOME"
-#: src/gtkui/columns.c:34
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Número de entrada"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "TÃtulo"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Artista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Ano"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Ãlbum"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Faixa"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Gênero"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Posição na fila"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Duração"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Caminho do arquivo"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Nome do Arquivo"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "TÃtulo personalizado"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Taxa de dados"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
-msgstr ""
+msgstr "Colunas disponÃveis"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
-msgstr ""
+msgstr "Colunas visÃveis"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Ferramenta de Busca"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Apontar na esquerda"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Apontar na direita"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Apontar no topo"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Apontar na parte inferior"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Desencaixar"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Desabilitar"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Ferramenta de Busca"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Abrir Arquivo(s) ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Abrir _URL ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_Adicionar Arquivo(s) ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Adicionar U_RL ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
-msgstr ""
+msgstr "Pesquisar _Biblioteca"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "S_obre ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
-msgstr ""
+msgstr "_Configurações ..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Sair"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Reproduzir"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Paus_ar"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_Parar"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "An_terior"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_Próxima"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Repetir"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "E_mbaralhar"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "N_ão avançar faixa"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Parar D_epois Desta Faixa"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Informações da faixa ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Ir para posição _temporal ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "_Ir para a faixa ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "Definir Ponto de Repetição _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "Definir Ponto de Repetição _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_Limpar Pontos de Repetição"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Por _TÃtulo"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "Por _Nome do Arquivo"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "Por _Nome de Arquivo"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Por Arquivo de _Diretório"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Por _Número da Faixa"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Por _Artista"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Por Ãl_bum "
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Por _Artista de Ãlbum"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Por _Data de Lançamento"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "Por _Duração"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Por _Arquivo de Diretório"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Por _TÃtulo Personalizado"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "I_nverter Ordem"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_Aleatório"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_Reproduzir esta Lista de Reprodução"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Atualizar"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Organizar Lista de Reprodução"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "Organizar Se_lecionado"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "Remover _Duplicatas"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Remover _Arquivos IndisponÃveis"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Novo"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "Re_nomear ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importar"
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Exportar"
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "Gerenciador de _Lista de Reprodução ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Gerenciador de _Fila de Reprodução ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Aumentar _Volume"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "Abaixar _Volume"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Equalizador"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
-msgstr ""
+msgstr "E_feitos"
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Mostrar Barra de _Menu"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Mostrar Barra de _Informação"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Mostrar vis_ualização da barra de informaçoes"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Mostrar Barra de _Status"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Mostrar _Tempo Restante"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
-msgstr ""
+msgstr "_Visualizações"
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Arquivo"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Reprodução"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Lista de Reprodução"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Serviços"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_SaÃda"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Visualizar"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "Colocar/Retirar da fila"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Recor_tar"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Copiar"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_Colar"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Selecionar _Tudo"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_Renomear ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
-msgstr ""
+msgstr "Mostrar botão fechar"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
-msgstr ""
+msgstr "Mostrar cabeçalho das colunas"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Diversos</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "Interface GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "A processar ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d canal"
msgstr[1] "%d canais"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Modo simples."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Modo Lista de Reprodução."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Parar após faixa"
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Faixa anterior"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Reproduzir"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pausa/Retornar"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Parar"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Próxima faixa"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "Avançar 5 segundos"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "Retroceder 5 segundos"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Mudo"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Aumentar volume"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Diminuir volume"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Ir para o arquivo"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "Habilitar/Desabilitar janela(s) do player"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Mostrar OSD"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "Habilitar/Desabilitar repetir"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "Habilitar/Desabilitar embaralhar"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "Habilitar/Desabilitar parar depois da atual"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Aumentar janela(s) do player"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(nada)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2062,15 +2116,11 @@ msgstr ""
"\n"
"Continuar?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Associação do botão do mouse"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Configurações Plugin Global Hotkey"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2078,23 +2128,27 @@ msgstr ""
"Pressionar uma combinação de teclas no campo de texto.\n"
"Você também pode associar os botoes do mouse."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Hotkeys:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Ação:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Combinação de Teclas:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
-msgstr ""
+msgstr "_Adicionar"
+
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Global Hotkeys"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2120,60 +2174,51 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>."
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Global Hotkeys"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "SaÃda JACK"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Falha ao conectar a porta JACK %s."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Baseado no xmms-jack, por Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Portado para Audacious por Giacomo Lozito."
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "SaÃda JACK"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "Configurações de %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Configurações LADSPA Host"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Diretório do Modulo:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2184,25 +2229,25 @@ msgstr ""
"Após a adição dos caminhos, pressione Enter para procurar os novos plugins.</"
"small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Plugins disponÃveis:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Habilitar"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Plugins ativos:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Configurações"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2210,55 +2255,15 @@ msgstr ""
"LADSPA Host para Audacious\n"
"Copyright 2011 John Lindgren."
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA Host"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr ""
-"%s: suporte LIRC não iniciado\n"
-"\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: não foi possÃvel ler o arquivo de configuração LIRC\n"
-"%s: consulte a documentação do LIRC\n"
-"%s: como criar um arquivo de configuração válido\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr ""
-"%s: tentando nova reconexão...\n"
-"\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: comando desconhecido %s\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr ""
-"%s: LIRC desconectado\n"
-"\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr ""
-"%s: tentara reconectar %d segundos...\n"
-"\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Plugin LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2288,73 +2293,81 @@ msgstr ""
"\n"
"Para mais informações sobre LIRC, veja http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Conexão</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Reconectar ao servidor LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Espere antes de reconectar:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Plugin LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "Plugin RyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "A letra da faixa não está disponÃvel"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Erro"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Não foi possÃvel obter %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Erro"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Não foi possÃvel analisar %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Procurando a letra da faixa ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Metadados da música faltando"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Conectando no lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "Plugin RyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "Listas de Reproduções M3U"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Gerador Tacto"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Gerador Tacto: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Gerador Tacto: %d bpm %d%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2368,11 +2381,11 @@ msgstr ""
"Exemplo: tact://77 para reproduzir 77 bpm (batidas por minuto)\n"
"ou tact://60*3/4 para reproduzir 60 bpm em 3/4 tactos."
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Gerador Tacto"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Canal Mixer"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2380,152 +2393,184 @@ msgstr ""
"Plugin Canal Mixer para Audacious\n"
"Copyright 2011-2012 John Lindgren e MichaÅ Lipski."
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Canal Mixer</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Canais de saÃda:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Canal Mixer"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "Plugin MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Modulo Player)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>Resolução</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Canais</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "O mais próximo (mais rápido)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Linear (rápido)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Spline (bom)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "Polifásico (melhor)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>Taxa de amostragem</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "NÃvel:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "Atalho:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Reverberação</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>Bass Boost</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>Cercar</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>Pré-amplificador</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "Sobreamostra"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Redução de ruÃdo"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Reproduzir Amiga MODs"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Repetir</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "Contagem de repetição:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "Para repetir para sempre, definir a contagem de repetição para -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Modulo Player)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Surround"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "Plugin MPG 123"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Avançado</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "Servidor MPRIS 2"
-#: src/neon/neon.c:1056
-msgid "Neon HTTP/HTTPS Plugin"
-msgstr "Plugin Neon HTTP/HTTPS"
+#: src/neon/neon.cc:97
+msgid "Neon HTTP/HTTPS Plugin"
+msgstr "Plugin Neon HTTP/HTTPS"
+
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Erro HTTP desconhecido"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "Erro validando URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Muitos redirecionamentos"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Parado"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious não está tocando."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Notificações do Desktop"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2560,55 +2605,64 @@ msgstr ""
"Você poderá receber uma copia de GNU General Public License junto a esse "
"programa, se não, veja <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Mostrar controles de reprodução"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Sempre exibir notificação"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Notificações do Desktop"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Exibir"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pausa"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Próxima"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Dispositivo padrão"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "SaÃda OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "SaÃda OSS3"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Dispositivo padrão"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Dispositivo de áudio:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Usar dispositivo alternativo:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Salve volume entre sessões."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Permitir conversões de formatos com programa OSS"
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Ativar modo exclusivo para evitar mistura virtual."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2622,19 +2676,35 @@ msgstr ""
"Gostaria de agradecer as pessoas em #audacious, especialmente Tony Vroon e "
"John Lindgren e a todos os autores anteriores do plugin OSS."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "SaÃda OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Entradas"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Remover"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "Ren_omear"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "Listas de Reproduções PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "Decodificador OpenPSF PDF1/PSF2"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "SaÃda PulseAudio"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2670,11 +2740,68 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "SaÃda PulseAudio"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Processando ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Pesquisar"
-#: src/resample/resample.c:165
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Abrir arquivos"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Adicionar arquivos"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Anterior"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Repetir"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Embaralhar"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Conversor de Taxa de Amostragem"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2682,99 +2809,107 @@ msgstr ""
"Plugin Conversor de Taxa de Amostragem para Audacious\n"
"Copyright 2010-2012 John Lindgren."
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "Pular/Repetir amostras"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Interpolação linear"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Interpolação sinc rápida"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "Interpolação sinc normal"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Interpolação sinc máxima"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Conversão</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Método:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Taxa:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Mapeamento de Taxa</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Usar mapeamento de taxas"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Conversor de Taxa de Amostragem"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "OK. Scrobbling para o usuário: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "Permissão Negada"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"Acesse o link a seguir para permitir Audacious no scrobble em suas "
"reproduções:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"Mantenha esta janela aberta e clique em \"Verificar permissão' novamente.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2782,36 +2917,40 @@ msgstr ""
"Não se preocupe. Seus scrobbles são salvos no seu computador.\n"
"Eles serão apresentados logo que Audacious é permitido fazê-lo."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "Problema de Rede."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
"Houve um problema ao contactar Last.fm. Por favor, tente novamente mais "
"tarde."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "Verificando..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "V_erificar Permissão"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_Revogar Permissão"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"Você precisa permitir Audacious para a reprodução de faixas scrobble na sua "
"conta Last.fm.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2819,7 +2958,7 @@ msgstr ""
"O plugin Scrobbler não pôde ser iniciado.\n"
"Pode haver um problema com a sua instalação."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2837,11 +2976,7 @@ msgstr ""
"\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2849,7 +2984,11 @@ msgstr ""
"Audacious agora está usando uma versão melhorada do Last.fm Scrobbler.\n"
"Por favor, verifique as Preferências do plugin Scrobbler."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SaÃda SDL"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2857,82 +2996,56 @@ msgstr ""
"Plugin SDL Output para Audacious\n"
"Copyright 2010 John Lindgren."
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SaÃda SDL"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Biblioteca"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Artista Desconhecido"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Album Desconhecido"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-"em\n"
-"%s de %s"
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d álbum"
-msgstr[1] " %d álbuns"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-"%s\n"
-"%s, %d faixa"
msgstr[1] ""
-"%s\n"
-"%s, %d faixas"
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
-"%s\n"
-"%d faixa de %s"
msgstr[1] ""
-"%s\n"
-"%d faixas de %s"
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "por"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Criar Lista de Reprodução"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Adicionar à Lista de Reprodução"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Procurar biblioteca"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2940,679 +3053,769 @@ msgstr ""
"Para importar sua biblioteca de música no Audacious, escolha uma pasta e em "
"seguida no Ãcone \"atualizar\"."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Por favor aguarde ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Escolha pasta"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>SaÃda</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Canais:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Emulação</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Emular filtro"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Reprodução:"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Lista de Reprodução"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Ver"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
-msgstr ""
+msgstr "Sobre ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
-msgstr ""
+msgstr "Sair"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Repetir"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Embaralhar"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Não Avançar a Lista de Reprodução"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Anterior"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Nova Lista de Reprodução"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Mostrar editor do Player"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Mostrar Equalizador"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Sempre no Topo"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Por TÃtulo"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Por Nome do Arquivo"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Remover Todos"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Apagar Fila de Reprodução"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Remover Arquivos IndisponÃveis"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Remover Duplicatas"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Remover Desmarcada"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Remover Selecionados"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Pesquisar e Selecionar"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Inverter Seleção"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Não Selecionar"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Selecionar Tudo"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Por Album"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Por Número da Faixa"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Por Artista"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Por Album"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Por Número da Faixa"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Randomizar Lista"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Reverter Lista"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Organizar Selecionado"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Organizar Lista"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Cortar"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Copiar"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Colar"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Interface Clássica Winamp"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Salvar"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Carregar"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Pré-ajuste"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Carregar pré-ajuste"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Carregar pré-ajuste automático"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Salvar pré-ajuste"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Salvar pré-ajuste automático"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Deletar pré-ajuste"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Deletar pré-ajuste automático"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Player:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Selecionar o tipo de letra do player:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Lista de Reprodução:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Selecionar o tipo de letra da lista de reprodução:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Usar letras bitmap (suporta ASCII somente)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "TÃtulo da musica rola em ambas as direções"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analisador"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Escopo"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Desligado"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normal"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Fogo"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Linhas"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Barras"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Mais Lento"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Lento"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Médio"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Rápido"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Muito Rápido"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
-msgstr ""
+msgstr "Linha"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
-msgstr ""
+msgstr "Solido"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Gelo"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Suave"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Geral"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualização"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Amplificador"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Esqualizador do Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Ir para %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Volume: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "EquilÃbrio: %d%% esquerda"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "EquilÃbrio centro"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "EquilÃbrio: %d%% direita"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Menu de Opções"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Desativar 'Sempre No Topo'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Ativar 'Sempre No Topo'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Caixa de Informações do Arquivo"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "Repetir ponto de definição A."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "Repetir ponto de definição B."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "Repetir pontos apagados."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Modo simples."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Modo Lista de Reprodução."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Parar após faixa"
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Procurar entradas na lista de reprodução ativa"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3624,58 +3827,62 @@ msgstr ""
"minúsculas. Se não sabe o que são expressões regulares, basta inserir uma "
"parte do que pretende procurar."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Titulo:"
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Ãlbum:"
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Artista:"
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Nome do Arquivo:"
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Apagar seleção anterior antes de pesquisar"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr ""
"Automaticamente habilitar/desabilitar fila para as entradas coincidentes"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Criar uma nova lista de reprodução com as entradas correspondentes"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Editor de lista de reprodução do Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d de %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Tema Winamp 2.x arquivado"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Tema Winamp 2.x não arquivado"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Não foi possÃvel criar o diretório (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Plugin Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3716,84 +3923,71 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Plugin Sndfile"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Sobre Sndio Plugin de saÃda"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-"Plugin de SaÃda Sndio\n"
-"\n"
-"Escrito por Thomas Plaff <tpfaff at tp76.info>.\n"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Formato não suportado"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-"Um formato não suportado pelo dispositivo foi solicitado.\n"
-"\n"
-"Por favor tente novamente com o servidor sndiod(1) em execução."
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "dispositivo sndio"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(vazio significa os padrões)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Mudar Faixa"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Comando a executar quando Audacious iniciar uma nova faixa."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Parâmetros enviados ââpara o console devem ser colocados em "
+"aspas. Caso contrário corre risco de segurança.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Comando:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Comando a executar ao terminar uma faixa."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
msgstr ""
-"Comando a executar quando Audacious atinge o fim de uma lista de reprodução."
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Comando a executar quando o titulo da música for modificado (Exemplo: "
-"tÃtulos de redes stream)."
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3807,35 +4001,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Você pode utilizar os formatos descritos em baixo, que\n"
-"serão substituÃdo antes de chamar o comando\n"
-"(nem todos podem ser utilizados para o comando fim da lista de reprodução):\n"
-"\n"
-"%F: Frequência (em hertz)\n"
-"%c: Números de canais\n"
-"%f Nome do arquivo (diretório completo)\n"
-"%l: Duração (em milissegundos)\n"
-"%n ou %s Nome da faixa\n"
-"%r: Taxa (em bits por segundo)\n"
-"%t Posição da lista de reprodução (%02d)\n"
-"%p A reproduzir atualmente (1 ou 0)\n"
-"%a: Artista\n"
-"%b Ãlbum\n"
-"%T: Faixa de titulo"
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>Parâmetros enviados ââpara o console devem ser colocados em "
-"aspas. Caso contrário corre risco de segurança.</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Comandos"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "Reamostrador SoX"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3849,51 +4024,51 @@ msgstr ""
"Baseado no Plugin Conversor de Taxa de Amostragem:\n"
"Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Rápido"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Baixo"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Alto"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Muito Alto"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Qualidade:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "Reamostrador SoX"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Velocidade e Tom"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Velocidade e Tom</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Velocidade:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Tom:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Velocidade e Tom"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Ãcone de Status"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3911,39 +4086,39 @@ msgstr ""
"Esse plugin fornece um Ãcone de status, colocado na\n"
"área de notificação do sistema no gerenciador de janelas."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Ação do Mouse no botão do meio</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Alterar volume"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Mudar de faixa"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Outras Configuraçoes</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Desativar janelas pop-up"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Fechar para a bandeja do sistema"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Avançar lista de reprodução ao rolar para cima"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Ãcone de Status"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Stereo Extra"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3953,24 +4128,24 @@ msgstr ""
"\n"
"Por Johan Levin, 1999."
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Stereo Extra</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Stereo Extra"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Gerador de Tons"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Gerador de Tons:"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3985,15 +4160,11 @@ msgstr ""
"frequência3;...\n"
"Exemplo: tone://2000;2005 para reproduzir um tom 2000 Hz e outro de 2005 Hz."
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Gerador de Tons"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Remoção de voz"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4031,11 +4202,35 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>."
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Decodificador Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "Decodificador VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4046,19 +4241,19 @@ msgstr ""
"Baseado em in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Plugin Audacious por Pavel Vymetalek <pvymetalek at seznam.cz>."
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "Decodificador VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "Decodificador WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "com perdas (hÃbrido)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "com perdas"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4068,14 +4263,18 @@ msgstr ""
"\n"
"Parte do código do plugin foi por Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "Decodificador WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "Decodificador 2SF"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "Lista de Reprodução Compartilhável XML (XSPF)"
diff --git a/po/pt_PT.po b/po/pt_PT.po
index 6d5ab250c511..cfb5da9d20b8 100644
--- a/po/pt_PT.po
+++ b/po/pt_PT.po
@@ -3,17 +3,19 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
+# Alexandro Casanova <shorterfire at gmail.com>, 2012
# Bruno Martins <bmomartins at gmail.com>, 2011
# Pitxyoki <Pitxyoki at gmail.com>, 2013
-# Sérgio Marques <smarquespt at gmail.com>, 2012-2013
-# salmora8 <shorterfire at gmail.com>, 2012
+# Pitxyoki <Pitxyoki at gmail.com>, 2013
+# Sérgio Marques <smarquespt at gmail.com>, 2012-2015
+# Alexandro Casanova <shorterfire at gmail.com>, 2012
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-05 13:02+0000\n"
+"Last-Translator: Sérgio Marques <smarquespt at gmail.com>\n"
"Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/"
"audacious/language/pt_PT/)\n"
"Language: pt_PT\n"
@@ -22,40 +24,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "estéreo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "surround"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
-msgstr ""
+msgstr "Descodificador AAC (RAW)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (Reprodutor AdLib)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "sequencial"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (Reprodutor AdLib)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarme"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
-msgstr ""
+msgstr "Definir alarme..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -65,11 +55,7 @@ msgstr ""
"\n"
"Versão original desenvolvida por Adam Feakin e Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarme"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -111,7 +97,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -151,7 +137,7 @@ msgstr ""
" Executar este comando ao tocar o alarme.\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -175,385 +161,391 @@ msgstr ""
" Escreva o lembrete na caixa e ative o botão\n"
" para alternar se o quiser mostrar."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Este é o seu alerta."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "O seu lembrete de hoje é:"
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Lembrete"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "segunda"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "terça"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "quarta"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "quinta"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "sexta"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "sábado"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "domingo"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Definições do alarme"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Horário"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarme às (pré-definido):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Silenciar após:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "horas"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minutos"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
-msgstr "Escolha os dias para o alarme"
+msgstr "Escolha os dias para o alarme tocar"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Dia"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Pré-definido"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Dias"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Desvanecimento"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "segundos"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Volume"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Ao iniciar"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Ao terminar"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Atual"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Comando adicional"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "ativar"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Lista de reprodução (opcional)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
-msgstr "Escolha uma lista de reprodução"
+msgstr "Escolha a lista de reprodução"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Opções"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "O que significam estas opções?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Ajuda"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Imagem de álbum"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Imagem do álbum (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "Sistema ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"Suplemento ALSA\n"
+"Direitos de autor 2009-2012 John Lindgren\n"
+"\n"
+"Os meus agradecimentos a William Pitcock, autor do suplemento ALSA Output "
+"NG, cujo código serviu de base nas situações em que a documentação ALSA não "
+"cumpria os requisitos."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(sem descrição)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Dispositivo PCM pré-definido"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Dispositivo misturador pré-definido"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "Dispositivo PCM:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Dispositivo misturador:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Elemento misturador:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Solução para impedir a suspensão"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (Reprodutor MIDI)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"Suplemento ALSA\n"
-"Direitos de autor 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"Reprodutor de música MIDI\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"Os meus agradecimentos a William Pitcock, autor do suplemento ALSA Output "
-"NG, cujo código serviu de base nas situações em que a documentação ALSA não "
-"cumpria os requisitos."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "Sistema ALSA"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (Reprodutor MIDI)"
+"desenvolvido por Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"um especial obrigado a...\n"
+"\n"
+"Clemens Ladisch e Jaroslav Kysela\n"
+"pelos programas aplaymidi e amixer uma vez que\n"
+"foram muito úteis, bem como a documentação alsa-lib\n"
+"que disponibiliza as informações da API ALSA\n"
+"\n"
+"Alfredo Spadafina\n"
+"pela imagem do teclado midi\n"
+"\n"
+"Tony Vroon\n"
+"pela ajuda nos testes"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
-msgstr ""
+msgstr "Substituir ganho pré-definido:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
-msgstr ""
+msgstr "Substituir polifonia pré-definido:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
-msgstr ""
+msgstr "Substituir reverb pré-definido:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
-msgstr ""
+msgstr "Ligado"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
-msgstr ""
+msgstr "Substituir coro pré-definido:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
-msgstr ""
+msgstr "<b>Reprodução</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
-msgstr ""
+msgstr "Transposição:"
+
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "semitons"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
-msgstr ""
+msgstr "Drum shift:"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "número da nota"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "Ignorar silêncio inicial"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "Ignorar silêncio final"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
-msgstr ""
+msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
-msgstr ""
+msgstr "<b>Sintetizador</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr ""
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "Frequência:"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
-msgstr "Amidi - selecione o ficheiro SoundFont"
+msgstr "AMIDI-Plug - selecione o ficheiro SoundFont"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Cancelar"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
-msgstr ""
+msgstr "_Abrir"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Nome do ficheiro"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Tamanho (bytes)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Nome:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
-msgstr "<span size=\"smaller\">Informações Midi</span>"
+msgstr "<span size=\"smaller\">Informações MIDI</span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Formato:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Duração (mseg):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "N.º de faixas:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "variável"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Div. de tempo:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
-msgstr "<span size=\"smaller\">Comentários e letras das faixas midi</span>"
+msgstr "<span size=\"smaller\">Comentários e letras das faixas MIDI</span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
-msgstr "* sem comentários para este ficheiro midi *"
+msgstr "* sem comentários para este ficheiro MIDI *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
-msgstr "* sem letra da música para este ficheiro midi *"
+msgstr "* sem letra da música para este ficheiro MIDI *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "Fe_char"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (UTF-8 inválido)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Sobre o AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"Reprodutor de faixas MIDI\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"Desenvolvido por Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"Um especial obrigado a...\n"
-"\n"
-"Clemens Ladisch e Jaroslav Kysela\n"
-"pelas aplicações aplaymidi e amixer e\n"
-"à documentação alsa-lib que me ajudou a\n"
-"descobrir as especificações da API ALSA.\n"
-"\n"
-"Alfredo Spadafina\n"
-"pelo logótipo do teclado midi.\n"
-"\n"
-"Tony Vroon\n"
-"por me ajudar nos testes."
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -563,152 +555,154 @@ msgid ""
"Based in part on Evan Martin's Ghosd library:\n"
"http://neugierig.org/software/ghosd/"
msgstr ""
+"Audacious OSD\n"
+"http://www.develia.org/projects.php?p=audacious#aosd\n"
+"\n"
+"Dsesenvolvido por Giacomo Lozito <james at develia.org>\n"
+"\n"
+"Baseado na biblioteca Ghosd criada por Evan Martin:\n"
+"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (Notificação no ecrã)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Retângulo"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Retângulo arredondado"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Retângulo côncavo"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Nenhum"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Ao iniciar reprodução"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Ativar OSD ao reproduzir uma faixa da lista de reprodução."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
-msgstr "Ao alterar o tÃtulo"
+msgstr "Ao mudar o tÃtulo"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
-msgstr ""
-"Ativar OSD se, durante a reprodução, o tÃtulo da faixa for alterado mas o "
-"nome do ficheiro permanecer igual. Ãtil nas reproduções de emissões web."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
+msgstr "Ativar OSD ao mudar o tÃtulo da faixa (para emissões web)."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
-msgstr "Ao colocar em pausa"
+msgstr "Ao pausar"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Ativar OSD se a reprodução for colocada em pausa."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Ao retirar da pausa"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Ativar OSD ao retomar a reprodução."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Posicionamento"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "X relativo:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Y relativo:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Largura máxima do OSD:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Opções de monitores múltiplos"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Mostrar OSD:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "em todos os monitores"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "no monitor %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Duração (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Exibição:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Aparecer gradual:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Desaparecer gradual:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Tipo de letra"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Tipo de letra %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Sombra"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Estilo"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Cores"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Cor %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Ativar"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Evento"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Detetado um gestor de composição."
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -718,112 +712,112 @@ msgstr ""
"A menos que tenha a certeza que o gestor está ativo, tem que ativar um "
"gestor de composição para mostrar o OSD."
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
-msgstr "O gestor de composição não é necessário para a transparência fictÃcia."
+msgstr "A transparência fictÃcia não precisa de um gestor de composição"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Transparência"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Transparência fictÃcia"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Transparência efetiva (requer a extensão X Composite)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
-msgstr "Extensão Composite não carregada"
+msgstr "Extensão de composição não carregada"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
-msgstr "Extensão Composite não disponÃvel"
+msgstr "Extensão de composição não disponÃvel"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Definições do OSD Audacious"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Posição"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animação"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Texto"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Decoração"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "Ativador"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
-msgstr "Diversos"
+msgstr "Outras"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "Teste"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
-msgstr ""
+msgstr "Listas de reprodução ASXv3"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "Listas de reprodução ASXv1/ASXv2"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Listas de reprodução Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Cor</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Blur Scope"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Pré-ajuste:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "NÃvel:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Frequência de corte:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Pré-ajuste:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Analisador de espetro"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Suplemento Ãudio CD"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -836,179 +830,166 @@ msgid ""
msgstr ""
"Direitos de autor (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> e outros.\n"
"\n"
-"Os meus agradecimentos aos programadores da libcdio <http://www.gnu.org/"
-"software/libcdio/>\n"
+"O meu obrigado aos programadores da libcdio <http://www.gnu.org/software/"
+"libcdio/>\n"
"e da libcddb <http://libcddb.sourceforge.net/>.\n"
"\n"
"Agradeço também a Tony Vroon pelo apoio concedido.\n"
"\n"
"Este foi um projeto do Google Summer of Code 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>Dispositivo</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Velocidade de leitura:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "Sobrepor dispositivo:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Detalhes</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Utilizar CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Utilizar CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Utilizar HTTP em vez de CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Servidor:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Caminho:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Porta:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Suplemento Ãudio CD"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "Ocorreu um erro ao iniciar o sistema cdio."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "URI %s inválido."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Faixa %d não encontrada."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "A faixa %d é uma faixa de dados."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Ocorreu um erro ao abrir o sistema de som."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Ocorreu um erro ao ler o CD."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "CD áudio"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Ocorreu um erro ao abrir o dispositivo %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Não foi encontrada uma unidade de CD."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "Ocorreu um erro ao iniciar a unidade de CD."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Ocorreu um erro ao obter o número da primeira/última faixa."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Não foi possÃvel ler inicio/fim LSN da faixa %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Ocorreu um erro ao criar a ligação à cddb."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Ocorreu um erro ao consultar o servidor cddb."
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Ocorreu um erro ao consultar o servidor cddb: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Ocorreu um erro ao ler as informações cddb: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Unidade vazia."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Tipo de disco não suportado."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Itens de menu do Ãudio CD"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Reproduzir CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Adicionar CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Itens de menu do Ãudio CD"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Compressão</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Centrar volume:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Intervalo dinâmico:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"Suplemento Dynamic Range Compression\n"
-"DIreitos de autor 2010-2012 John Lindgren."
+"Direitos de autor 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Compressor de intervalo dinâmico"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1017,213 +998,245 @@ msgid ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
msgstr ""
-"Suplemento Console music decoder baseado no Game_Music_Emu 0.5.2\n"
+"Suplemento Console Music Decoder baseado no Game_Music_Emu 0.5.2\n"
"Formatos suportados: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
"\n"
-"Adaptação para o Audacious por:\n"
+"Adaptação ao Audacious por:\n"
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Graves:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Agudos:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
-msgstr ""
+msgstr "Eco:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Duração pré-definida da faixa:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
-msgstr "<b>Resampling</b>"
+msgstr "<b>Remistura</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Ativar remistura áudio"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Frequência:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
-msgstr ""
+msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "Ignorar duração das \"tags\" SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Aumentar \"reverb\""
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Descodificador Game Console Music"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"A sobreposição falhou porque existem faixas com um número de canais "
-"diferente. Pode utilizar o gestor de canais para converter o número de "
-"canais das faixas."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "Suplemento CoreAudio"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"A sobreposição falhou porque existem faixas com frequências diferentes. Pode "
-"utilizar o Conversor de frequências para converter a frequência das faixas."
+"Suplemento CoreAudio Output\n"
+"Direitos de autor 2014 William Pitcock\n"
+"\n"
+"Baseado no suplemento SDL Output\n"
+"Direitos de autor 2010 John Lindgren"
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "Usar modo exclusivo"
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"Suplemento Crossfade\n"
-"Direitos de autor 2010-2012 John Lindgren"
+"Direitos de autor 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>Sobreposição</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "Ao mudar automaticamente de faixa"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "Sobreposição:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "Ao procurar ou mudar manualmente a faixa"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>Dica</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+"Para um melhor desempenho, ative\n"
+"o efeito Remoção de silêncio."
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "Sobreposição"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"A sobreposição falhou porque existem faixas com um número de canais "
+"diferente. Pode utilizar o gestor de canais para converter o número de "
+"canais das faixas."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"A sobreposição falhou porque existem faixas com frequências diferentes. Pode "
+"utilizar o Conversor de frequências para converter a frequência das faixas."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Cristalizador</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intensidade:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Cristalizador"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
-msgstr "Suplemento Cue"
+msgstr "Suplemento Cue Sheet"
+
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Eliminar ficheiros"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
-msgstr ""
+msgstr "Erro ao mover %s para o lixo: %s"
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
-msgstr ""
+msgstr "Erro ao eliminar %s: %s"
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
-msgstr ""
+msgstr "Erro ao eliminar %s: não é ficheiro local"
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
-msgstr ""
+msgstr "Pretende mover os ficheiros selecionados para o lixo?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
-msgstr ""
+msgstr "Mover para o lixo"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
-msgstr ""
+msgstr "Pretende eliminar permanentemente os ficheiros selecionados?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Eliminar"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Cancelar"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
-msgstr ""
+msgstr "Eliminar ficheiros selecionados"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
-msgstr ""
+msgstr "<b>Método de eliminação</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
+msgstr "Mover para o lixo em vez de os eliminar"
+
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
msgstr ""
+"Suplemento Echo\n"
+"Por Johan Levin, 1999\n"
+"Surround echo por Carl van Schaik, 1999\n"
+"Atualizado para o Audacious por William Pitcock e John Lindgren, 2010-2014"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Eco</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Atraso:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Retorno:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Volume:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Suplemento Echo\n"
-"Po Johan Levin, 1999\n"
-"\n"
-"Surround echo por Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Eco"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Suplemento FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1232,62 +1245,61 @@ msgid ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-"Suplemento de descodificação através da infraestrutura\n"
-"FFmpeg (http://www.ffmpeg.org/)\n"
+"Suplemento FFmpeg (http://www.ffmpeg.org/)\n"
"\n"
"Adaptação ao Audacious por:\n"
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "Suplemento FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Suplemento FileWriter"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Formato de saÃda:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Configurar"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Gravar no diretório original"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Gravar num diretório personalizado"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Pasta de destino:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Escolha a pasta"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Obter nome do ficheiro:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "Gerar nome de ficheiro de:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "das \"tags\" originais"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "Etiqueta orifinal"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "do nome de ficheiro original"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "Nome de ficheiro original"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Não remover extensão do ficheiro"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "Incluir extensão de ficheiro original"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Prefixar n.º da faixa ao nome do ficheiro"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr "Adicionar número de faixa ao nome do ficheiro"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1304,180 +1316,184 @@ msgid ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
msgstr ""
-"Este suplemento é um programa livre. Pode redistribui-lo e/ou modificá-lo "
-"nos termos da GNU General Public License, tal como publicada pela Free "
-"Software Foundation, tanto na versão 3 ou (por opção) qualquer versão mais "
-"recente.\n"
+"Este suplemento é um programa livre. Pode redistribui-lo e/ou modificá-lo\n"
+"nos termos da GNU General Public License, tal como publicada pela\n"
+"Free Software Foundation, tanto na versão 3 ou (por opção)\n"
+"qualquer versão mais recente.\n"
"\n"
-"Este programa é disponibilizado com o intuito de ser útil mas NÃO POSSUI "
-"QUALQUER GARANTIA. Nem mesmo a garantia implÃcita de comercialização ou "
-"adequação a um propósito concreto. Consulte a GNU General Public License "
-"para mais detalhes.\n"
+"Este programa é disponibilizado com o intuito de ser útil mas\n"
+"NÃO POSSUI QUALQUER GARANTIA. Nem mesmo a garantia implÃcita\n"
+"de comercialização ou adequação a um propósito concreto.\n"
+"Consulte a GNU General Public License para mais detalhes.\n"
"\n"
-"Deve ter recebido uma cópia da GNU General Public License junto com o "
-"programa. Se tal não aconteceu, escreva uma carta para Free Software\n"
-"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
-"USA."
+"Deve ter recebido uma cópia da GNU General Public License\n"
+"com o programa. Se tal não aconteceu, escreva uma carta para\n"
+"Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor\n"
+"Boston, MA 02110-1301, USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "Suplemento FileWriter"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Automático"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Joint estéreo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Estéreo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Definições MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_Aceitar"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Qualidade do algoritmo:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
msgstr "Frequência de saÃda:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
msgstr "Taxa de dados/compressão:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Taxa de dados (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Rácio de compressão:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Modo áudio:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Diversos:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr "Diversos"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
msgstr "Forçar conformidade ISO"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Proteção de erros"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Qualidade"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Ativar VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tipo:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Opções VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Taxa mÃnima (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "Taxa máxima (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "Forçar taxa de dados mÃnima"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Opções ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Taxa média (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "Qualidade VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Não gravar cabeçalho Xing VBR"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "Omitir cabeçalho Xing VBR"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr "Parâmetros:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
-msgstr "Assinalar como copyright"
+msgstr "Marcar como copyright"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
-msgstr "Assinalar como original"
+msgstr "Marcar como original"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "Parâmetros ID3:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "Forçar adição de \"tags\" v2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Apenas \"tags\" v1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Apenas \"tags\" v2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "\"Tags\""
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Definições do codificador Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Qualidade (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "Descodificador FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "sem perda"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1489,11 +1505,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "Descodificador FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1501,11 +1513,19 @@ msgstr ""
"Suplemento GIO\n"
"Direitos de autor 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "Suplemento GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "Modo \"read-and-append\" não suportado"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "Modo inválido de abertura"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1516,535 +1536,629 @@ msgid ""
"\n"
"License: GPLv2+"
msgstr ""
+"Analisador de espetro OpenGL\n"
+"Direitos de autor 2013 Christophe Budé, John Lindgren e Carlo Bramini\n"
+"\n"
+"Baseado no suplemento XMMS:\n"
+"Direitos de autor 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas "
+"Nilsson e 4Front Technologies\n"
+"\n"
+"Licença: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "Analisador de espetro OpenGL"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
-"Suplemento Gnome Shortcut\n"
-"Permite-lhe controlar o Audacious com as teclas de atalho Gnome.\n"
+"Analisador de espetro OpenGL\n"
+"Direitos de autor 2013 Christophe Budé, John Lindgren e Carlo Bramini\n"
+"Direitos de autor 2014 William Pitcock\n"
"\n"
-"Direitos de autor (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Baseado no suplemento XMMS:\n"
+"Direitos de autor 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas "
+"Nilsson e 4Front Technologies\n"
+"\n"
+"Licença: GPLv2+"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "Analisador de espetro OpenGL (Qt)"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Atalhos Gnome"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "GNOME Shortcuts"
-#: src/gtkui/columns.c:34
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+"Suplemento GNOME Shortcut\n"
+"Permite controlar a aplicação através dos atalhos GNOME.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Número da entrada"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "TÃtulo"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Artista"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Ano"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Ãlbum"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "Artista do álbum"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Faixa"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Género"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Posição na fila"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Duração"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Caminho do ficheiro"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Nome do ficheiro"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "TÃtulo personalizado"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Taxa de dados"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
-msgstr ""
+msgstr "Colunas disponÃveis"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
-msgstr ""
+msgstr "Colunas mostradas"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Ferramenta de procura"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Doca à esquerda"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Doca à direita"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Doca em cima"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Doca em baixo"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Desacoplar"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Desativar"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Ferramenta de procura"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "Abrir ficheir_os..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Abrir _URL..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_Adicionar ficheiros..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Adicionar U_RL..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
-msgstr ""
+msgstr "Procurar co_leção"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "So_bre..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
-msgstr ""
+msgstr "Definiçõe_s..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Sair"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "Re_produzir"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Paus_a"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "Pa_rar"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "An_terior"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "Segui_nte"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Repetir"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "Baral_har"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Sem avanç_o na lista de reprodução"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Parar após esta fai_xa"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Informações da faixa..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Ir para posição _temporal..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "I_r para a faixa..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "Definir ponto de repetição _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "Definir ponto de repetição _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "Remover pontos de rep_etição"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Por _tÃtulo"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "Por nome de _ficheiro"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "Por nome do _ficheiro"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Por caminho do fic_heiro"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Por _número de faixa"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Por _artista"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Por ál_bum"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Por artista do álbu_m"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Por _data de disponibilização"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "Por _género"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
-msgstr "Por _duração"
+msgstr "Por d_uração"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Por caminho do _ficheiro"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
-msgstr "Por tÃt_ulo personalizado"
+msgstr "Por tÃtulo personali_zado"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Inv_erter ordem"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "Aleató_rio"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "Re_produzir esta lista de reprodução"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "Re_produzir/Retomar"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Atualizar"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Organização"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
-msgstr ""
+msgstr "Organizar se_leção"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "Remover _duplicados"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Remover ficheiros indisponÃvei_s"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Nova"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "Mud_ar nome..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
-msgstr ""
+msgstr "Remo_ver"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importar..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Exportar..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "_Gestão da lista de reprodução..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
-msgstr "_Gestão da fila de reprodução"
+msgstr "_Gestão da fila de reprodução..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "A_umentar volume"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "_Diminuir volume"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Equalizador"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
-msgstr ""
+msgstr "E_feitos..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "_Mostrar barra de menu"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Mostrar barra de i_nformações"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
-msgstr "Mostrar visualização da barra de informações"
+msgstr "Mostrar vis_ualização da barra de informações"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Mo_strar barra de estado"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "Mostrar tempo _restante"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
-msgstr ""
+msgstr "_Visualizações..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Ficheiro"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "Re_produção"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_Lista de reprodução"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Serviços"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "S_aÃda"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Ver"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_Colocar/retirar da fila"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "_Abrir pasta respetiva"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Cor_tar"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Copiar"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "Co_lar"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Selecion_ar tudo"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "Muda_r nome..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
-msgstr ""
+msgstr "<b>Separadores da lista de reprodução</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
-msgstr ""
+msgstr "Mostrar sempre"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
-msgstr ""
+msgstr "Mostrar número de entradas"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
-msgstr ""
+msgstr "Mostrar botão Fechar"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
-msgstr ""
+msgstr "<b>Colunas da lista de reprodução</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
-msgstr ""
+msgstr "Mostrar tÃtulo das colunas"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Diversos</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
-msgstr ""
+msgstr "Teclas de seta procuram por:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
-msgstr ""
+msgstr "Deslocar ao mudar de faixa"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "Interface GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "A processar..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "estéreo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d canal"
msgstr[1] "%d canais"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Modo simples"
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Modo lista de reprodução"
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Para após a faixa"
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Faixa anterior"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Reproduzir"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Pausa/Retomar"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Parar"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Faixa seguinte"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "Avançar 5 segundos"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "Recuar 5 segundos"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Silenciar"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Aumentar volume"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Diminuir volume"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Ir para ficheiro"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "Ativar/desativar janela(s) do reprodutor"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Mostrar OSD"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "Ativar/desativar repetição"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "Ativar/desativar desorganização"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "Ativar/desativar paragem após a faixa atual"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Mostrar janela(s) do reprodutor"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(nada)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2055,15 +2169,11 @@ msgstr ""
"\n"
"Continuar?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Associação dos botões do rato"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Definições das Teclas globais"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2071,23 +2181,27 @@ msgstr ""
"Prima a combinação de teclas no campo de texto.\n"
"Também pode associar os botões do rato."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Teclas de atalho:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>Ação:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Associação de teclas:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
-msgstr ""
+msgstr "_Adicionar"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Atalhos globais"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2114,60 +2228,57 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Atalhos globais"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "Sistema Jack"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "Ligar automaticamente à s portas de saÃda"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "Apenas foram encontradas %d portas de saÃda JACK e são precisas %d."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Falha ao estabelecer ligação à porta %s."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
+"O JACK apenas tem suporte a áudio de vÃrgula flutuante. Deve alterar a "
+"profundidade para vÃrgula flutuante nas definições."
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
+"Falha ao estabelecer ligação ao servidor JACK. O servidor está em execução?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Baseado no suplemento xmms-jack, de Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Adaptação ao Audacious por Giacomo Lozito"
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "Sistema Jack"
+"O servidor JACK requer uma frequência de %d Hz, mas o Audacious está a "
+"reproduzir a %d Hz. Utilize o efeito Sample Rate Converter para corrigir a "
+"diferença."
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "Definições de %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Definições LADSPA "
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Caminhos do módulo:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2178,25 +2289,25 @@ msgstr ""
"Após a adição dos caminhos, prima Enter para procurar os novos suplementos.</"
"small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Suplemento disponÃveis:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Ativar"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Suplementos ativos:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Definições"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2204,47 +2315,15 @@ msgstr ""
"Suplemento LADSPA Host\n"
"Direitos de autor 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: suporte LIRC não iniciado.\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: não foi possÃvel ler o ficheiro de configuração LIRC.\n"
-"%s: consulte a documentação do LIRC.\n"
-"%s: como criar um ficheiro de configuração válido.\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: a tentar nova ligação...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: comando desconhecido \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: desligado do servidor LIRC\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: nova tentativa de ligação a cada %d segundos...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Suplemento LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2259,8 +2338,7 @@ msgid ""
"\n"
"For more information about LIRC, see http://lirc.org."
msgstr ""
-"Um suplemento para controlar o Audacious através do serviço de controlo "
-"remoto LIRC.\n"
+"Um suplemento para controlar o Audacious através do serviço LIRC.\n"
"\n"
"Adaptação ao Audacious por:\n"
"Tony Vroon <chainsaw at gentoo.org>\n"
@@ -2273,73 +2351,81 @@ msgstr ""
"\n"
"Para mais informações, consulte http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Ligação</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Nova ligação ao servidor LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "Intervalo entre ligações:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Suplemento LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "Suplemento LyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "A letra da faixa não está disponÃvel."
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Erro"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Não foi possÃvel obter %s."
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Erro"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Não foi possÃvel processar %s."
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "A procurar letra da faixa..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Detalhes em falta"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Ligação a lyrics.wikia.com..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "Suplemento LyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "Suplemento LyricWiki (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "Listas de reprodução M3U"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Gerador Tact"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Gerador Tact: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Gerador Tact: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2353,11 +2439,11 @@ msgstr ""
"exemplo: tact://77 para reproduzir 77 batidas por minuto\n"
"ou tact://60*3/4 para reproduzir 60 batidas por minuto em 3/4 tacts"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Gerador Tact"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "Gestor de canais"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2365,152 +2451,184 @@ msgstr ""
"Suplemento Channel Mixer\n"
"Direitos de autor 2011-2012 John Lindgren e MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>Gestor de canais</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Canais de saÃda:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "Gestor de canais"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "Suplemento MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "Erro ao estabelecer ligação ao servidor MMS"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Reprodutor Module)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>Resolução</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Canais</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "Nearest (mais rápido)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Linear (rápido)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Spline (bom)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "Polyphase (melhor)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr "<b>Frequência</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "NÃvel:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "Corte:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>Reverb</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>Amplificação de graves</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>Surround</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>Amplificador</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "Oversample"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "Redução de ruÃdo"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Reproduzir Amiga MODs"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Repetição</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "N.º de repetições:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
-msgstr "Para repetir eternamente, defina o valor para -1."
+msgstr "Para repetir eternamente, defina o valor -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Reprodutor Module)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Surround"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "Estas definições serão aplicadas após reiniciar o Audacious."
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "Suplemento MPG123"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>Avançado</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "Usar cálculo preciso de duração (lento)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "Servidor MPRIS 2"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Suplemento Neon HTTP/HTTPS"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "Erro ao redirecionar"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "Erro HTTP desconhecido"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "Erro ao processar URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "Demasiados redirecionamentos"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Parado"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "O Audacious não está a reproduzir."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Notificações do ambiente de trabalho"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2547,55 +2665,64 @@ msgstr ""
"Deve ter recebido uma cópia da GNU General Public License com esta "
"aplicação. Se tal não ocorreu consulte <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "Mostrar controlos de reprodução"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Mostrar sempre notificação"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Notificações do ambiente de trabalho"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "Incluir nome do álbum na notificação"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Mostrar"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pausa"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Seguinte"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Dispositivo pré-definido"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "Sistema OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "SaÃda OSS3"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "Dispositivo pré-definido"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Dispositivo áudio:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Utilizar dispositivo alternativo:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Memorizar volume entre sessões."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "Ativar conversão de formatos com o programa OSS."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "Ativar modo exclusivo para prevenir mistura virtual."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2609,19 +2736,35 @@ msgstr ""
"Gostaria de agradecer às pessoas em #audacious, especialmente a Tony Vroon, "
"a John Lindgren e a todos os anteriores autores do suplemento OSS."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "Sistema OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Gestor de lista de reprodução"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Entradas"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Remover"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "Mud_ar nome"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "Listas de reprodução PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "Descodificador OpenPSF PSF1/PSF2"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "Sistema PulseAudio"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2652,16 +2795,78 @@ msgstr ""
"adequação a um propósito concreto. Consulte a GNU General Public License "
"para mais detalhes.\n"
"\n"
-"Deve ter recebido uma cópia da GNU General Public License junto com o "
-"programa. Se tal não aconteceu, escreva uma carta para Free Software\n"
-"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
-"USA."
+"Deve ter recebido uma cópia da GNU General Public License junto com o "
+"programa. Se tal não aconteceu, escreva uma carta para Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
+"USA."
+
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "SaÃda QtMultimedia"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"Suplemento QtMultimedia Audio Output\n"
+"Direitos de autor 2014 William Pitcock\n"
+"\n"
+"Baseado no suplemento SDL Output\n"
+"Direitos de autor 2010 John Lindgren"
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "Sistema PulseAudio"
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Execução..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Procura"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "A_brir pasta..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_Adicionar pasta..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "Insp_etor de registos..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "Abrir ficheiros"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "Adicionar ficheiros"
-#: src/resample/resample.c:165
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Anterior"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Repetir"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Baralhar"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Interface Qt"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Conversor de frequências"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2669,99 +2874,107 @@ msgstr ""
"Suplemento Sample Rate Converter\n"
"Direitos de autor 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "Ignorar/repetir frequências"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Interpolação linear"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Interpolação rápida"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "Interpolação normal"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Interpolação máxima"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Conversão</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Método:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Taxa:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Mapeamentos de taxa</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Utilizar mapeamento de taxa"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Conversor de frequências"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "OK. A fazer scrobble para o utilizador: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
-msgstr "Sem Permissão"
+msgstr "Permissão recusada"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"Aceda a esta ligação para permitir que o Audacious faça scrobble das "
"reproduções:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"Mantenha esta janela aberta e clique novamente em \"Verificar permissões\".\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2769,34 +2982,38 @@ msgstr ""
"Não se preocupe. Os seus scrobbles estão gravados no computador.\n"
"Serão enviados assim que o Audacious tiver permissão."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
-msgstr "Erro na Rede."
+msgstr "Erro na rede"
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "Ocorreu um erro ao contactar com a Last.fm. Por favor tente novamente."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
-msgstr "A Verificar..."
+msgstr "A verificar..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
-msgstr "Verific_ar Permissão"
+msgstr "Verific_ar permissão"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
-msgstr "_Revogar Permissão"
+msgstr "_Revogar permissão"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-"Tem de dar permissão ao Audacious para poder fazer scrobble das faixas para "
-"a sua conta Last.fm.\n"
+"Tem de dar permissão ao Audacious para fazer scrobble das faixas para a sua "
+"conta Last.fm.\n"
+
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2804,7 +3021,7 @@ msgstr ""
"O suplemento Scrobbler não foi iniciado.\n"
"Pode haver um problema com a sua instalação."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2814,27 +3031,27 @@ msgid ""
"project.\n"
"\n"
msgstr ""
-"Audacious Scrobbler 2.0 por Pitxyoki,\n"
+"Suplemento Audacious Scrobbler 2.0 por Pitxyoki.\n"
"\n"
-"Direitos de Autor © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail."
+"Direitos de autor © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail."
"com>\n"
"\n"
-"Obrigado ao John Lindgren por me ter ajudado no inÃcio deste projecto.\n"
+"Obrigado ao John Lindgren por me ter ajudado no inÃcio deste projeto.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-"O Audacious passou a usar uma nova versão do Scrobbler para a Last.fm.\n"
-"Por favor verifique as Preferências do suplemento Scrobbler."
+"O Audacious passou a usar uma nova versão do scrobbler Last.fm.\n"
+"Por favor verifique as definições do suplemento Scrobbler."
+
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "Sistema SDL"
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2842,81 +3059,56 @@ msgstr ""
"Suplemento SDL\n"
"Direitos de autor 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "Sistema SDL"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Coleção"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Artista desconhecido"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Ãlbum desconhecido"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-"em %s de %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d resultado"
+msgstr[1] "%d resultados"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d álbum"
-msgstr[1] "%d álbuns"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d oculto)"
+msgstr[1] "(%d ocultos)"
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d faixa"
-msgstr[1] ""
-"%s\n"
-" %s, %d faixas"
-
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d faixa de %s"
-msgstr[1] ""
-"%s\n"
-" %d faixas de %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d faixa"
+msgstr[1] "%d faixas"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "deste género"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "em"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "por"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Criar lista de reprodução"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Adicionar à lista de reprodução"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Procurar coleção"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2924,679 +3116,771 @@ msgstr ""
"Para importar a coleção de músicas para o Audacious, escolha a pasta e "
"clique no Ãcone \"Atualizar\"."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Aguarde..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "Escolha a pasta"
-#: src/skins/menus.c:56
-msgid "Open Files ..."
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "Reprodutor SID"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>SaÃda</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "Canais:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>Emulação</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "Emular MOS 8580 (pré-definição: MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "Não escolher modelo automaticamente"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "Filtro de emulação"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "Velocidade do relógio:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "Não escolher automaticamente a velocidade do relógio"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>Tempo de reprodução</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "Definir tempo máximo de reprodução:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "Apenas se a duração da faixa for desconhecida"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "Definir o tempo mÃnimo de reprodução"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Subtunes</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "Ativar subtunes"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "Ignorar subtunes inferiores a:"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Nota</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "Remoção de silêncio"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
msgstr ""
+"Suplemento Silence Removal\n"
+"Direitos de autor 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>Remoção de silêncio</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "Limite:"
-#: src/skins/menus.c:57
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
+msgid "Open Files ..."
+msgstr "Abrir ficheiros..."
+
+#: src/skins/menus.cc:65
msgid "Open URL ..."
-msgstr ""
+msgstr "Abrir URL..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "Procurar na coleção"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Reprodução"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Lista de reprodução"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Ver"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
-msgstr ""
+msgstr "Serviços"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
-msgstr ""
+msgstr "Sobre..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
-msgstr ""
+msgstr "Definições..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
-msgstr ""
+msgstr "Sair"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
-msgstr ""
-
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Repetir"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Baralhar"
+msgstr "Informações da faixa..."
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Sem avanço na lista de reprodução"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
-msgstr ""
-
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Anterior"
+msgstr "Parar após esta faixa"
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
-msgstr ""
+msgstr "Definir repetição A-B"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
-msgstr ""
+msgstr "Remover repetição A-B"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
-msgstr ""
+msgstr "Ir para a faixa..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
-msgstr ""
+msgstr "Ir para posição temporal..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr ""
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "Reproduzir/Retomar"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Nova lista de reprodução"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
-msgstr ""
+msgstr "Mudar nome da lista de reprodução..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
-msgstr ""
+msgstr "Remover lista de reprodução..."
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
-msgstr ""
+msgstr "Lista de reprodução anterior"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
-msgstr ""
+msgstr "Próxima lista de reprodução"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
-msgstr ""
+msgstr "Importar lista de reprodução..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
-msgstr ""
+msgstr "Exportar lista de reprodução..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
-msgstr ""
+msgstr "Gestão da lista de reprodução..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
-msgstr ""
+msgstr "Gestão da fila de reprodução..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
-msgstr ""
+msgstr "Atualizar lista de reprodução"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Mostrar editor de listas de reprodução"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Mostrar equalizador"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
-msgstr ""
+msgstr "Mostrar tempo restante"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Sempre visÃvel"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
-msgstr ""
+msgstr "Em todas as áreas de trabalho"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
-msgstr ""
+msgstr "Recolher reprodutor"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
-msgstr ""
+msgstr "Recolher editor de listas"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
-msgstr ""
+msgstr "Recolher equalizador"
+
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Tamanho duplo"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:138
msgid "Add URL ..."
-msgstr ""
+msgstr "Adicionar URL..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
-msgstr ""
+msgstr "Adicionar ficheiros..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Por tÃtulo"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "Por nome de ficheiro"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
-msgstr ""
+msgstr "Por caminho"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Remover tudo"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Limpar fila de reprodução"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Remover ficheiros indisponÃveis"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Remover duplicados"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Remover desmarcadas"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Remover seleção"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Procurar e selecionar"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Inverter seleção"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Não selecionar"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Selecionar tudo"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Por álbum"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Por número de faixa"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Por artista"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Por álbum"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Por artista do álbum"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
-msgstr ""
+msgstr "Por data de lançamento"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Por número de faixa"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "Por género"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "Por duração"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "Por tÃtulo personalizado"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Lista aleatória"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Inverter lista"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
-msgstr "Ordenar seleção"
+msgstr "Organizar seleção"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Ordenação"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Cortar"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Copiar"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Colar"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
-msgstr ""
+msgstr "Colocar/retirar da fila"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
-msgstr ""
+msgstr "Carregar pré-ajuste..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
-msgstr ""
+msgstr "Carregar pré-ajuste automático"
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
-msgstr ""
+msgstr "Carregar pré-definido"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
-msgstr ""
+msgstr "Carregar ficheiro de pré-ajuste..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
-msgstr ""
+msgstr "Carregar ficheiro EQF..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
-msgstr ""
+msgstr "Gravar pré-ajuste..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
-msgstr ""
+msgstr "Gravar pré-ajuste automático..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
-msgstr ""
+msgstr "Gravar pré-definido"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
-msgstr ""
+msgstr "Gravar ficheiro de pré-ajuste..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
-msgstr ""
+msgstr "Gravar ficheiro EQF..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
-msgstr ""
+msgstr "Eliminar pré-ajuste..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
-msgstr ""
+msgstr "Eliminar pré-ajuste automático..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
-msgstr ""
+msgstr "Importar pré-ajuste Winamp..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
-msgstr ""
+msgstr "Repor para zero"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Interface clássica Winamp"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Gravar"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Carregar"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
-msgstr ""
+msgstr "Carregar ficheiro de pré-ajuste"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
-msgstr ""
+msgstr "Carregar ficheiro EQF"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
-msgstr ""
+msgstr "Gravar ficheiro de pré-ajuste"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
-msgstr ""
+msgstr "Gravar ficheiro EQF"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
-msgstr ""
+msgstr "Importar pré-ajuste Winamp"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Pré-ajuste"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "Carregar pré-ajuste"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "Carregar pré-ajuste automático"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Gravar pré-ajuste"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Gravar pré-ajuste automático"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Eliminar pré-ajuste"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Eliminar pré-ajuste automático"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "Re_produtor:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "Reprodutor:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Selecione o tipo de letra do reprodutor:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_Lista de reprodução:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "Lista de reprodução:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Escolha o tipo de letra da lista de reprodução:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
-msgstr ""
+msgstr "<b>Tema</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
-msgstr ""
+msgstr "<b>Tipos de letra</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "Utilizar letras bitmap (só para ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
-msgstr ""
+msgstr "Deslocar tÃtulo da faixa"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Deslocar tÃtulo em ambas as direções"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analisador"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Scope"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
-msgstr ""
+msgstr "Voiceprint/Medidor VU"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Desligado"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normal"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "Fogo"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
-msgstr ""
+msgstr "Linhas verticais"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Linhas"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Barras"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Mais lento"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Lento"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Normal"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Rápido"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Mais rápido"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
-msgstr ""
+msgstr "Pontos"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
-msgstr ""
+msgstr "Linha"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
-msgstr ""
+msgstr "Sólido"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Gelo"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Suave"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
-msgstr ""
+msgstr "<b>Tipo</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
-msgstr ""
+msgstr "Tipo de visualização:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
-msgstr ""
+msgstr "<b>Analisador</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
-msgstr ""
+msgstr "Mostrar picos"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
-msgstr ""
+msgstr "Coloração:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
-msgstr ""
+msgstr "Estilo:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
-msgstr ""
+msgstr "Recurso:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
-msgstr ""
+msgstr "Recurso de picos:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
-msgstr ""
+msgstr "Estilo de scope:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
-msgstr ""
+msgstr "Coloração Voiceprint:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
-msgstr ""
+msgstr "Estilo do medidor VU:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Geral"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Visualização"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Amplificador"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Equalizador do Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Ir para %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Volume: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "EquilÃbrio: %d%% Ã esquerda"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "EquilÃbrio: centro"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "EquilÃbrio: %d%% Ã direita"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Menu de opções"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Desativar \"Sempre visÃvel\""
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Ativar \"Sempre visÃvel\""
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Caixa de informações de ficheiro"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "Visualizações"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "Ponto de repetição A definido"
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "Ponto de repetição B definido"
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
-msgstr "Pontos de repetição eliminados"
-
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Modo simples"
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Modo lista de reprodução"
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Para após a faixa"
+msgstr "Pontos de repetição removidos"
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "Procurar entradas na lista de reprodução ativa"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3608,57 +3892,61 @@ msgstr ""
"minúsculas. Se não sabe o que são expressões regulares, basta inserir uma "
"parte do que pretende procurar."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
msgstr "TÃtulo:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr "Ãlbum: "
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr "Artista: "
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Nome do ficheiro:"
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Nome de ficheiro:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Limpar seleção anterior antes de procurar"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Alternar fila automaticamente para as entradas coincidentes"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Criar lista de reprodução com as entradas coincidentes"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Editor de listas de reprodução"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d de %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Tema Winamp 2.x arquivado"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Tema Winamp 2.x não arquivado"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Não foi possÃvel criar o diretório (%s): %s.\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Suplemento Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3699,82 +3987,71 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Suplemento Sndfile"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "SaÃda Sndio"
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Sobre o Sndio"
-
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Suplemento Sndio\n"
-"\n"
-"Desenvolvido por Thomas Pfaff <tpfaff at tp76.info>.\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "Dispositivo (vazio para predefinição):"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Formato não suportado"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "Gravar e restaurar volume:"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"Foi solicitado um formato não suportado pelo dispositivo.\n"
-"\n"
-"Tente novamente com o servidor sndiod(1) em execução."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Erro Sndio: formato áudio não suportado (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "Dispositivo sndio"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Erro Sndio: falha sio_open()"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(vazio significa as predefinições)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Erro Sndio: falha sio_setpar()"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "Aceitar"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Erro Sndio: falha sio_start()"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Alteração de faixa"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Comando a executar ao iniciar uma nova faixa."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Os parâmetros enviados à consola devem ser envolvidos em "
+"aspas. Se não o fizer corre riscos de segurança.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>Comandos</b>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Comando:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Comando a executar ao inicar uma nova faixa:"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Comando a executar ao terminar uma faixa."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Comando a executar ao terminar uma faixa:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "Comando a executar ao atingir o fim de uma lista de reprodução."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Comando a executar no final de uma lista de reprodução:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
-msgstr ""
-"Comando a executar se o tÃtulo da faixa for alterado (para emissões web)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr "Comando a executar ao mudar o tÃtulo da faixa (para emissões web):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3788,9 +4065,9 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Pode utilizar os formatos descritos em baixo, que\n"
-"serão substituÃdos antes da invocação do comando\n"
-"(nem todos podem ser utilizados como comando end-of-playlist).\n"
+"Pode utilizar os formatos descritos em baixo, que serão substituÃdos antes "
+"de invocar o comando (nem todos podem ser utilizados como comando end-of-"
+"playlist).\n"
"\n"
"%F: frequência (em hertz)\n"
"%c: número de canais\n"
@@ -3799,24 +4076,20 @@ msgstr ""
"%n ou %s: nome da faixa\n"
"%r: taxa (em bits por segundo)\n"
"%t: posição na lista de reprodução (%02d)\n"
-"%p: a reproduzir atualmente (1 ou 0)\n"
+"%p: reprodução atual (1 ou 0)\n"
"%a: artista\n"
"%b: álbum\n"
"%T: tÃtulo da faixa"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>Os parâmetros enviados à consola devem ser envolvidos em "
-"aspas. Se não o fizer corre riscos de segurança.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Informações da faixa (Qt)"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Comandos"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX Resampler"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3824,57 +4097,57 @@ msgid ""
"Based on Sample Rate Converter Plugin:\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-"SoX Resampler para o Audacious\n"
+"Suplemento SoX Resampler\n"
"Direitos de autor 2013 MichaÅ Lipski\n"
"\n"
"Baseado no suplemento Sample Rate Converter\n"
"Direitos de autor 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Rápida"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Baixa"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Alta"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Muito alta"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Qualidade:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Velocidade e pitch"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Velocidade e pitch</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Velocidade:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Pitch:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Velocidade e pitch"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Ãcone de estado"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
-msgstr ""
+msgstr "De_finições..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3892,39 +4165,39 @@ msgstr ""
"Este suplemento disponibiliza um Ãcone de estado na área de notificação do "
"seu gestor de janelas."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Ação da roda do rato</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Alterar volume"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Alterar faixa reproduzida"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Outras definições</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Desativar janela emergente"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Fechar para a área de notificação"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "Avançar na lista de reprodução ao rolar para cima"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Ãcone de estado"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra estéreo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3934,24 +4207,24 @@ msgstr ""
"\n"
"Por Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra estéreo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra estéreo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Gerador de tons"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Gerador de tons:"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3967,15 +4240,11 @@ msgstr ""
"exemplo: tone://2000;2005 para reproduzir um tom de 2000 Hz e outro de 2005 "
"Hz"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Gerador de tons"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Remoção de voz"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4014,11 +4283,46 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Descodificador Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Detalhes para %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"TÃtulo: %t\n"
+"Autor: %a\n"
+"De: %f\n"
+"Tracker: %T\n"
+"Comentário: %C\n"
+"Tipo de chip: %c\n"
+"Estéreo: %s\n"
+"Loop: %l\n"
+"Frequência do chip: %F\n"
+"Frequência do reprodutor: %P\n"
+"Ano: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "Descodificador VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4028,19 +4332,19 @@ msgstr ""
"Baseado em in_vtx.dll de Roman Sherbakov <v_soft at microfor.ru>\n"
"Adaptação ao Audacious por Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "Descodificador VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "Descodificador WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "com perda (hÃbrido)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "com perda"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4050,14 +4354,18 @@ msgstr ""
"\n"
"Parte do código foi desenvolvido por Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "Descodificador WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "Descodificador 2SF"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>Configuração XSF</b>"
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Ignorar duração do ficheiro"
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "Listas de reprodução XML Shareable (XSPF)"
diff --git a/po/ru.po b/po/ru.po
index 9bcfc4feb0f0..d5cfc84395d5 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -4,37 +4,39 @@
#
# Translators:
# Alexander Orlov <alxorlov at pochta.ru>, 2007
-# dane <alpi_bel at mail.ru>, 2014
+# ÐÐµÐ½Ð¸Ñ <alpi_bel at mail.ru>, 2014
+# Andrei Stepanov, 2014
# Someonefree <drag-sasha at mail.ru>, 2013-2014
# arinov <i.arinov at iht.kz>, 2014
# iavojd <iavojd at gmail.com>, 2013
# iavojd <iavojd at gmail.com>, 2013
# joshuazzz <joshuazzz at yandex.ru>, 2012
# joshuazzz <joshuazzz at yandex.ru>, 2012
-# StreamThreaedr <kvantarium at gmail.com>, 2012
-# Maxim Musatov <m1kc at yandex.ru>, 2012
-# Maxim Musatov <m1kc at yandex.ru>, 2012
+# Oleg <kvantarium at gmail.com>, 2012
+# Max Musatov <m1kc at yandex.ru>, 2012
+# Max Musatov <m1kc at yandex.ru>, 2012
# NaiLi (aka jamesjames) Rootaerc <theism at mail.ru>, 2012-2013
# NaiLi (aka jamesjames) Rootaerc <theism at mail.ru>, 2012
-# NEKURIM <kvadrocu7 at gmail.com>, 2013
+# ÐлекÑей <kvadrocu7 at gmail.com>, 2013
+# Lowrider <pams at imail.ru>, 2014-2015
# Rax Garfield <admin at dvizho.ks.ua>, 2012
# <sejava at mail.ru>, 2012
-# senyalutyi <senyalutyi at ya.ru>, 2013
-# senyalutyi <senyalutyi at ya.ru>, 2013
+# Senya <senyalutyi at ya.ru>, 2013
+# Senya <senyalutyi at ya.ru>, 2013
# serg0 <sergo at bk.ru>, 2010
# Sergey V. Mironov <serg0 at ulx.ru>, 2009
# serg0 <sergo at bk.ru>, 2010
# Someonefree <drag-sasha at mail.ru>, 2013
-# StreamThreaedr <kvantarium at gmail.com>, 2012
+# Oleg <kvantarium at gmail.com>, 2012
# Victor Ponomarev <victor.a.ponomarev at gmail.com>, 2013
-# NEKURIM <kvadrocu7 at gmail.com>, 2013
+# ÐлекÑей <kvadrocu7 at gmail.com>, 2013
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Russian (http://www.transifex.com/projects/p/audacious/"
"language/ru/)\n"
"Language: ru\n"
@@ -44,40 +46,28 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "моно"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "ÑÑеÑео"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "обÑÑмное звÑÑание"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ AAC(MP4)"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ AAC(Raw)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (пÑоигÑÑваÑÐµÐ»Ñ AdLib)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "поÑледоваÑелÑнÑй"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (пÑоигÑÑваÑÐµÐ»Ñ AdLib)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "ÐÑдилÑник"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "УÑÑановиÑÑ ÐÑдилÑник,,,,"
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -87,11 +77,7 @@ msgstr ""
"опÑеделенное вÑемÑ.\n"
"ÐзнаÑалÑно напиÑан Adam Feakin и Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "ÐÑдилÑник"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -131,7 +117,7 @@ msgstr ""
"или вÑбеÑиÑе пеÑеклÑÑаÑÐµÐ»Ñ Ð´Ð»Ñ Ð²Ñемени по ÑмолÑаниÑ.\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -170,7 +156,7 @@ msgstr ""
"ÐополниÑелÑнÑе командÑ:\n"
"ÐÑполниÑÑ ÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð¿Ñи ÑÑабаÑÑвании Ñигнала.\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -193,385 +179,390 @@ msgstr ""
"ÐведиÑе в поле напоминание и вклÑÑиÑе\n"
"- пеÑеклÑÑаÑелÑ, еÑли Ð²Ñ Ñ
оÑиÑе, ÑÑÐ¾Ð±Ñ ÑÑо бÑло показано."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "ÐÑо Ð²Ð°Ñ Ð·Ð²Ð¾Ð½Ð¾Ðº бÑдилÑника"
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "Ðапоминание на ÑегоднÑÑний денÑ..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Ðапоминание"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "ÐонеделÑник"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "ÐÑоÑник"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "СÑеда"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "ЧеÑвеÑг"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "ÐÑÑниÑа"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "СÑббоÑа"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "ÐоÑкÑеÑенÑе"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "ÐаÑÑÑойки бÑдилÑника"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "_ÐÐ"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "ÐаконÑиÑÑ"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "ÐÑемÑ"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "ÐÑдилÑник в (по ÑмолÑаниÑ):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "Ñ"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "ÐеÑеÑÑаÑÑ Ð·Ð²Ð¾Ð½Ð¸ÑÑ Ð¿Ð¾Ñле:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "ÑаÑÑ"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "минÑÑÑ"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "ÐÑбеÑиÑе дни, в коÑоÑÑе бÑÐ´ÐµÑ ÑÑабаÑÑваÑÑ Ð±ÑдилÑник"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "ÐенÑ"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Ðо ÑмолÑаниÑ"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Ðни"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Ðлавное наÑаÑÑание гÑомкоÑÑи"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "ÑекÑнд"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "ÐÑомкоÑÑÑ"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "ÐаÑаÑÑ c"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "РконÑе"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "ТекÑÑее"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "ÐополниÑелÑÐ½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "вклÑÑиÑÑ"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
-msgstr "СпиÑок воÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ (необÑзаÑелÑно)"
+msgstr "ÐлейлиÑÑ (необÑзаÑелÑно)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "ÐÑбеÑиÑе ÑпиÑок воÑпÑоизведениÑ"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "ÐаÑамеÑÑÑ"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "ЧÑо ознаÑаÑÑ ÑÑи опÑии?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "СпÑавка"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Ðбложка алÑбома"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "ÐллÑÑÑÑаÑÐ¸Ñ Ð°Ð»Ñбома (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ÐÑвод ALSA"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ALSA Ðлагин вÑвода Ð´Ð»Ñ Audacious\n"
+"ÐвÑоÑÑÑво 2009-2012 John Lindgren\n"
+"\n"
+"ÐÐ¾Ñ Ð±Ð»Ð°Ð³Ð¾Ð´Ð°ÑноÑÑÑ Ð£Ð¸Ð»ÑÑÐ¼Ñ Pitcock, авÑÐ¾Ñ ÐÑвода ALSA NG, Ñей код ÑлÑжил "
+"оÑиенÑиÑом, когда ÑÑководÑÑва по ALSA бÑло недоÑÑаÑоÑно."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "УÑÑÑойÑÑво PCM по ÑмолÑаниÑ"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "ÐикÑÐµÑ Ð¿Ð¾ ÑмолÑаниÑ"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "УÑÑÑойÑÑво PCM:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "ÐикÑеÑ:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "ÐÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ Ð¼Ð¸ÐºÑеÑа:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "ÐбÑ
одиÑÑ Ð¾ÑÐ¸Ð±ÐºÑ Ð·Ð°Ð²Ð¸ÑÐ°Ð½Ð¸Ñ \"drain\" в ALSA"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "Ðлагин AMIDI (пÑоигÑÑваÑÐµÐ»Ñ MIDI)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"ALSA Ðлагин вÑвода Ð´Ð»Ñ Audacious\n"
-"ÐвÑоÑÑÑво 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"модÑлÑнÑй мÑзÑкалÑнÑй MIDI пÑоигÑÑваÑелÑ\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"ÐÐ¾Ñ Ð±Ð»Ð°Ð³Ð¾Ð´Ð°ÑноÑÑÑ Ð£Ð¸Ð»ÑÑÐ¼Ñ Pitcock, авÑÐ¾Ñ ÐÑвода ALSA NG, Ñей код ÑлÑжил "
-"оÑиенÑиÑом, когда ÑÑководÑÑва по ALSA бÑло недоÑÑаÑоÑно."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ÐÑвод ALSA"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "Ðлагин AMIDI (пÑоигÑÑваÑÐµÐ»Ñ MIDI)"
+"ÑоздаÑÐµÐ»Ñ Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"оÑобÑе благодаÑноÑÑи...\n"
+"\n"
+"Clemens Ladisch и Jaroslav Kysela\n"
+"за иÑ
пÑиколÑнÑе пÑогÑÐ°Ð¼Ð¼Ñ aplaymidi и amixer; они\n"
+"ÑеалÑно полезнÑ, Ñакже как ÑÑководÑÑва alsa-lib, позволÑÑÑие\n"
+"ÑзнаÑÑ Ð±Ð¾Ð»ÑÑе о ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"за Ñ
оÑоÑо наÑиÑованнÑй логоÑип MIDI клавиаÑÑÑÑ\n"
+"\n"
+"Tony Vroon\n"
+"за помоÑÑ Ð¿Ñи алÑÑа-ÑеÑÑиÑовании"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "ÐамениÑÑ Ð´ÐµÑолÑнÑй ÑÑилиÑÐµÐ»Ñ Ð½Ð°:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "ÐзмениÑÑ Ð¿Ð¾Ð»Ð¸ÑÐ¾Ð½Ð¸Ñ Ð¿Ð¾ ÑмолÑаниÑ:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "ÐамениÑÑ ÑевеÑбаÑÐ¸Ñ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Ð½Ð°:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "Ðа"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "ÐамениÑÑ Ñ
Ð¾Ñ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Ð½Ð°:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>ÐоÑпÑоизведение</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "ТÑанÑпониÑование: "
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "полÑÑона"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "СмеÑение ÑдаÑнÑÑ
: "
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>РаÑÑиÑеннÑе</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "номеÑа ноÑ"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "СÑиÑÑваÑÑ ÐºÐ¾Ð¼Ð¼ÐµÐ½ÑаÑии из MIDI-Ñайлов"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "ÐÑопÑÑкаÑÑ ÑиÑинÑ"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "СÑиÑÑваÑÑ ÑекÑÑÑ Ð¸Ð· MIDI-Ñайлов"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "ÐÑопÑÑкаÑÑ ÑиÑÐ¸Ð½Ñ Ð² конÑе"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>ШÑиÑÑ</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>СинÑезаÑоÑ</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr "ЧаÑÑоÑа диÑкÑеÑизаÑии:"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "ÐÑ"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - вÑÐ±Ð¾Ñ SoundFont Ñайла"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "ÐаконÑиÑÑ"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "_ÐÑкÑÑÑÑ"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "ÐÐ¼Ñ Ñайла"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Ð Ð°Ð·Ð¼ÐµÑ (байÑ)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "ÐмÑ:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\">ÐнÑоÑмаÑÐ¸Ñ MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "ФоÑмаÑ:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "ÐлиÑелÑноÑÑÑ (мÑ):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "ÐолиÑеÑÑво доÑожек:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "пеÑеменнÑй"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Time Div:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\">ÐомменÑаÑии и ÑекÑÑÑ MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* в ÑÑом MIDI-Ñайле Ð½ÐµÑ ÐºÐ¾Ð¼Ð¼ÐµÐ½ÑаÑиев *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* в ÑÑом MIDI-Ñайле Ð½ÐµÑ ÑекÑÑов *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "ÐакÑÑÑÑ"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (невеÑнÑй UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Ðб AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "ÐодÑÐ»Ñ AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"модÑлÑнÑй пÑоигÑÑваÑÐµÐ»Ñ MIDI\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"напиÑан Giacomo Lozito\n"
-"< james at develia.org >\n"
-"\n"
-"\n"
-"оÑделÑнÑе благодаÑноÑÑи...\n"
-"\n"
-"Clemens Ladisch и Jaroslav Kysela\n"
-"за иÑ
оÑлиÑнÑе пÑогÑÐ°Ð¼Ð¼Ñ aplaymidi и amixer; они\n"
-"дейÑÑвиÑелÑно полезнÑе, как и докÑменÑаÑÐ¸Ñ alsa-lib Ð´Ð»Ñ Ñого,\n"
-"ÑÑÐ¾Ð±Ñ ÑзнаÑÑ Ð±Ð¾Ð»ÑÑе об инÑеÑÑейÑе библиоÑеки ALSA\n"
-"\n"
-"Alfredo Spadafina\n"
-"за пÑекÑаÑнÑй логоÑип миди-клавиаÑÑÑÑ\n"
-"\n"
-"Tony Vroon\n"
-"за болÑÑÑÑ Ð¿Ð¾Ð¼Ð¾ÑÑ Ð² алÑÑа-ÑеÑÑиÑовании"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -589,152 +580,148 @@ msgstr ""
"РоÑнове библиоÑека Ghosd Evan Martin'а:\n"
" http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (вÑплÑваÑÑие ÑообÑениÑ)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ÐÑÑмоÑголÑник"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "СкÑÑглÑннÑй пÑÑмоÑголÑник"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "ÐогнÑÑÑй пÑÑмоÑголÑник"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "ÐеÑ"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "ÐаÑало воÑпÑоизведениÑ"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "ÐоказаÑÑ OSD в наÑале воÑпÑоизведениÑ."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Ðзменение названиÑ"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"ÐоказаÑÑ OSD, еÑли в пÑоÑеÑÑе воÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¼ÐµÐ½ÑеÑÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ, но Ð¸Ð¼Ñ "
-"Ñайла оÑÑаÑÑÑÑ Ð¿Ñежним. Ðолезно Ð´Ð»Ñ Ð¾ÑобÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ð¹ пÑи воÑпÑоизведении "
-"из ÑеÑи."
+"ÐеÑеклÑÑÐ°ÐµÑ ÑкÑанное менÑ, когда название композиÑии менÑеÑÑÑ (Ð´Ð»Ñ Ð¸Ð½ÑеÑÐ½ÐµÑ "
+"поÑоков)."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "ÐаÑза вкл."
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "ÐоказаÑÑ OSD, когда воÑпÑоизведение пÑиоÑÑанавливаеÑÑÑ."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "ÐаÑза вÑкл."
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "ÐоказаÑÑ OSD, когда воÑпÑоизведение возобновлÑеÑÑÑ."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "РаÑположение"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "СмеÑение по оÑи X:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "СмеÑение по оÑи Y:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "ÐакÑималÑÐ½Ð°Ñ ÑиÑина OSD:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "ÐаÑамеÑÑÑ Ð´Ð»Ñ ÑиÑÑем Ñ Ð½ÐµÑколÑкими мониÑоÑами"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "ÐоказаÑÑ OSD:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "на вÑеÑ
мониÑоÑаÑ
"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "на мониÑоÑе %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "ÐÑÐµÐ¼Ñ (мÑ)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "оÑобÑажениÑ:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "поÑвлениÑ:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "заÑÑÑ
аниÑ:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "ШÑиÑÑÑ"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "ШÑиÑÑ %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "ТенÑ"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "СÑÐ¸Ð»Ñ Ð¾ÑобÑажениÑ"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "ЦвеÑа"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Ð¦Ð²ÐµÑ %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "ÐклÑÑиÑÑ ÑобÑÑие"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "СобÑÑие"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Ðайден композиÑнÑй менеджеÑ"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -744,113 +731,113 @@ msgstr ""
"ÐожалÑйÑÑа, запÑÑÑиÑе композиÑнÑй менеджеÑ; в пÑоÑивном ÑлÑÑае\n"
"OSD не бÑÐ´ÐµÑ ÑабоÑаÑÑ ÐºÐ¾ÑÑекÑно."
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr ""
"ÐÐ»Ñ Ñежима \"ÐмиÑиÑÐ¾Ð²Ð°Ð½Ð½Ð°Ñ Ð¿ÑозÑаÑноÑÑÑ\" композиÑнÑй Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑ Ð½Ðµ ÑÑебÑеÑÑÑ."
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "ÐÑозÑаÑноÑÑÑ"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "ÐмиÑиÑÐ¾Ð²Ð°Ð½Ð½Ð°Ñ Ð¿ÑозÑаÑноÑÑÑ"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "ÐаÑÑоÑÑÐ°Ñ Ð¿ÑозÑаÑноÑÑÑ (ÑÑебÑеÑÑÑ ÑаÑÑиÑение X Composite)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "РаÑÑиÑение X Composite не загÑÑжено"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "РаÑÑиÑение X Composite недоÑÑÑпно"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "ÐаÑамеÑÑÑ Ð¼Ð¾Ð´ÑÐ»Ñ Audacious OSD"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "_ТеÑÑ"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "_СделаÑÑ"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Ðоложение"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "ÐнимаÑиÑ"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "ТекÑÑ"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "СÑилÑ"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "СобÑÑиÑ"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "ÐÑоÑее"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "ТеÑÑ"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "ASXv3 ÐлейлиÑÑÑ"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "СпиÑки воÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ ASXv1/ASXv2"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "СпиÑки воÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>ЦвеÑ</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "РазмÑваÑÑийÑÑ ÑÑовенÑ"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "СÑеÑеоÑониÑеÑкий в бинаÑÑалÑнÑй по ÐаÑÑÑÑ (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "ÐагоÑовки:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "УÑÐ¾Ð²ÐµÐ½Ñ ÑмеÑÐ¸Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð²:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 дÐ"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "ЧаÑÑоÑа ÑÑеза:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "ÐагоÑовки:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "СÑеÑеоÑониÑеÑкий в бинаÑÑалÑнÑй по ÐаÑÑÑÑ (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "ÐнализаÑÐ¾Ñ ÑпекÑÑа"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Ðлагин Audio CD"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -874,171 +861,158 @@ msgstr ""
"\n"
"Copyright 2009 John Lindgren"
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>УÑÑÑойÑÑво</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "СкоÑоÑÑÑ ÑÑениÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "ÐеÑеопÑеделиÑÑ ÑÑÑÑойÑÑво:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>ÐеÑаданнÑе</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "ÐÑполÑзоваÑÑ CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "ÐÑполÑзоваÑÑ CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "ÐÑполÑзоваÑÑ HTTP вмеÑÑо CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "СеÑвеÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "ÐÑÑÑÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "ÐоÑÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Ðлагин Audio CD"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "ÐÑибка пÑи иниÑиализаÑии CD."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "ÐекоÑÑекÑнÑй URI %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "ТÑек %d не найден."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "ÐоÑожка %d ÑÑо даннÑе доÑожки."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Ðе ÑдалоÑÑ Ð·Ð°Ð´ÐµÐ¹ÑÑвоваÑÑ Ð°Ñдио-вÑвод."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "ÐÑибка ÑÑÐµÐ½Ð¸Ñ ÐÑдио CD"
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Audio CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "ÐоÑожка %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Ðе ÑдалоÑÑ Ð¾ÑкÑÑÑÑ ÑÑÑÑойÑÑво CD %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Ðе найдено ÑовмеÑÑимого CD-ÑÑÑÑойÑÑва."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "ÐÑибка пÑи иниÑиализаÑии CD."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Failed to retrieve first/last track number."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Ðевозможно ÑÑиÑаÑÑ Ð½Ð°Ñало/ÐºÐ¾Ð½ÐµÑ LSN Ð´Ð»Ñ ÑÑека %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ cddb ÑоеденениÑ."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Ðе ÑдалоÑÑ Ð²ÑполниÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ðº базе CDDB ÑеÑвеÑа"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Ðе ÑдалоÑÑ Ð²ÑполниÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ðº базе CDDB ÑеÑвеÑа: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Ðе ÑдалоÑÑ Ð¿ÑоÑиÑаÑÑ cddb инÑоÑмаÑиÑ: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "ÐÑивод пÑÑÑ."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "ÐеподдеÑживаемÑй Ñип диÑка."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "ÐÑнкÑÑ Ð¼ÐµÐ½Ñ Audio CD"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "ÐоÑпÑоизвеÑÑи CD-диÑк"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "ÐобавиÑÑ CD-диÑк"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "ÐÑнкÑÑ Ð¼ÐµÐ½Ñ Audio CD"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>СжаÑие</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "ЦенÑÑ Ð³ÑомкоÑÑи:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "ÐинамиÑеÑкий диапазон:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"СжаÑие динамиÑеÑкого Ðиапазона Ðлагин Ð´Ð»Ñ Audacious\n"
-"ÐвÑоÑÑÑво 2010-2012 Ðжон ÐиндгÑен"
+"ÐадÑÑÑойка ÑжаÑÐ¸Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÑеÑкого диапазона Ð´Ð»Ñ Audacious\n"
+"ÐвÑоÑÑкое пÑаво 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "ÐомпÑеÑÑÐ¾Ñ ÑиÑокого диапозона"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1055,207 +1029,226 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>â\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ÐаÑ:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "ÐÑÑокие:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "ÐÑ
о"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "ÐлиÑелÑноÑÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð·Ð¸Ñии по ÑмолÑаниÑ:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>ÐеÑедиÑкÑеÑизаÑиÑ</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "ÐклÑÑиÑÑ Ð¿ÑеобÑазование"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "ÐÑеобÑазование ÑаÑÑоÑÑ:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "ÐÑ"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "ÐгноÑиÑоваÑÑ Ð´Ð»Ð¸ÑелÑноÑÑÑ Ð¸Ð· Ñегов SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "УвелиÑиÑÑ ÑевеÑбеÑаÑиÑ"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ Ð·Ð²Ñка игÑовой конÑоли"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"ÐÑоÑÑÑÑÐ¹Ð´ÐµÑ ÑÑолкнÑлÑÑ Ñ Ð¾Ñибкой, поÑÐ¾Ð¼Ñ ÑÑо пеÑÐ½Ñ Ð¸Ð¼ÐµÐµÑ Ð´ÑÑгое колиÑеÑÑво "
-"каналов. ÐÑ Ð¼Ð¾Ð¶ÐµÑе иÑполÑзоваÑÑ Ð¼Ð¸ÐºÑÐµÑ ÐºÐ°Ð½Ð°Ð»Ð¾Ð², ÑÑÐ¾Ð±Ñ ÐºÐ¾Ð½Ð²ÐµÑÑиÑоваÑÑ Ð¿ÐµÑÐ½Ñ "
-"в Ñо же колиÑеÑÑво каналов."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "ÐÑÑ
од CoreAudio"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"ÐÑоÑÑÑÑÐ¹Ð´ÐµÑ ÑÑолкнÑлÑÑ Ñ Ð¾Ñибкой, поÑÐ¾Ð¼Ñ ÑÑо пеÑÐ½Ñ Ð¸Ð¼ÐµÐµÑ Ð´ÑÑгÑÑ ÑаÑÑоÑÑ "
-"диÑкÑеÑизаÑии. ÐÑ Ð¼Ð¾Ð¶ÐµÑе иÑполÑзоваÑÑ ÐºÐ¾Ð½Ð²ÐµÑÑÐµÑ ÑаÑÑоÑÑ Ð´Ð¸ÑкÑеÑизаÑии Ð´Ð»Ñ "
-"конвеÑÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÐµÑни в ÑÑ Ð¶Ðµ ÑаÑÑоÑÑ."
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "ÐкÑклÑзивнÑй Ñежим"
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Ðлагин пеÑекÑеÑÑного заÑÑÑ
Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Audaciousâ\n"
-"ÐвÑоÑÑÑво 2010-2012 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>ÐлавнÑй пеÑеÑ
од</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "ÐÑи авÑомаÑиÑеÑкой Ñмене композиÑии"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "ÐеÑекÑÑÑие:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "ÐÑи поиÑке или ÑамоÑÑоÑÑелÑной Ñмене композиÑии"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>СовеÑ</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "ÐлавнÑй пеÑеÑ
од"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"ÐÑоÑÑÑÑÐ¹Ð´ÐµÑ ÑÑолкнÑлÑÑ Ñ Ð¾Ñибкой, поÑÐ¾Ð¼Ñ ÑÑо пеÑÐ½Ñ Ð¸Ð¼ÐµÐµÑ Ð´ÑÑгое колиÑеÑÑво "
+"каналов. ÐÑ Ð¼Ð¾Ð¶ÐµÑе иÑполÑзоваÑÑ Ð¼Ð¸ÐºÑÐµÑ ÐºÐ°Ð½Ð°Ð»Ð¾Ð², ÑÑÐ¾Ð±Ñ ÐºÐ¾Ð½Ð²ÐµÑÑиÑоваÑÑ Ð¿ÐµÑÐ½Ñ "
+"в Ñо же колиÑеÑÑво каналов."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"ÐÑоÑÑÑÑÐ¹Ð´ÐµÑ ÑÑолкнÑлÑÑ Ñ Ð¾Ñибкой, поÑÐ¾Ð¼Ñ ÑÑо пеÑÐ½Ñ Ð¸Ð¼ÐµÐµÑ Ð´ÑÑгÑÑ ÑаÑÑоÑÑ "
+"диÑкÑеÑизаÑии. ÐÑ Ð¼Ð¾Ð¶ÐµÑе иÑполÑзоваÑÑ ÐºÐ¾Ð½Ð²ÐµÑÑÐµÑ ÑаÑÑоÑÑ Ð´Ð¸ÑкÑеÑизаÑии Ð´Ð»Ñ "
+"конвеÑÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÐµÑни в ÑÑ Ð¶Ðµ ÑаÑÑоÑÑ."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>ÐÑиÑÑализаÑоÑ</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "ÐнÑенÑивноÑÑÑ:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "ÐÑиÑÑализаÑоÑ"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Ðлагин Cue лиÑÑов"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "УдалиÑÑ ÑайлÑ"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "ÐÑибка пÑи пеÑемеÑении %s в коÑзинÑ: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "оÑибка ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ %s: %s"
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "ÐÑибка ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ %s: ÑÑо не локалÑнÑй Ñайл."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "ÐÑ Ñ
оÑиÑе ÑдалиÑÑ Ð²ÑбÑаннÑе ÑÐ°Ð¹Ð»Ñ Ð² коÑзинÑ?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "УдалиÑÑ Ð² ÐоÑзинÑ"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "ÐÑ Ñ
оÑиÑе ÑдалиÑÑ Ð±ÐµÐ· воÑÑÑÐ°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð²ÑбÑаннÑе ÑайлÑâ?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "УдалиÑÑ"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "ÐÑмена"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "УдалиÑÑ ÑайлÑ"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "УдалиÑÑ Ð²ÑбÑаннÑй ÑайлÑ"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>ÐеÑод УдалениÑ</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "ÐеÑемеÑаÑÑ Ð² коÑÐ·Ð¸Ð½Ñ Ð²Ð¼ÐµÑÑо немедленного ÑдалениÑ"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>ÐÑ
о</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "ÐадеÑжка:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "мÑ"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "ÐбÑаÑÐ½Ð°Ñ ÑвÑзÑ:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "ÐÑомкоÑÑÑ:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"ÐодÑÐ»Ñ ÐÑ
о\n"
-"ÐвÑÐ¾Ñ Johan Levin, 1999.\n"
-"\n"
-"ÐбÑÑмное ÑÑ
о добавил Carl van Schaik 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "ÐÑ
о"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "Ðлагин FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1271,55 +1264,55 @@ msgstr ""
" William Pitcock <nenolod at nenolod.net>,\n"
" Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "Ðлагин FFmpeg"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Ðлагин запиÑи в Ñайл"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "ФоÑÐ¼Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑваемого Ñайла:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "ÐаÑÑÑойка"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "СоÑ
ÑаниÑÑ Ð² ÑÐ¾Ñ Ð¶Ðµ каÑалог"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "СоÑ
ÑаниÑÑ Ð² дÑÑгой каÑалог"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "ÐаÑалог Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸ÑÑваемÑÑ
Ñайлов:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "ÐÑÐ±Ð¾Ñ ÐºÐ°Ñалога"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "ÐолÑÑиÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ Ñайла из:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "СоздаваÑÑ Ð¸Ð¼Ñ Ñайла из:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "имеÑÑиÑ
ÑÑ Ñегов Ñайла"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "ÐеÑка иÑÑ
одного Ñайла"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "имеÑÑегоÑÑ Ð¸Ð¼ÐµÐ½Ð¸ Ñайла"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "ÐÑÑ
одное Ð¸Ð¼Ñ Ñайла"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Ðе ÑдалÑÑÑ ÑаÑÑиÑение имени Ñайла"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "ÐобавлÑÑÑ ÑаÑÑиÑение к иÑÑ
Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð¸Ð¼ÐµÐ½Ð¸ Ñайла"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "ÐпиÑаÑÑ Ð´Ð¾ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñайла Ð½Ð¾Ð¼ÐµÑ Ð´Ð¾Ñожки"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr "ÐобавиÑÑ Ð² наÑало Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñайла Ð½Ð¾Ð¼ÐµÑ Ð´Ð¾Ñожки"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1352,165 +1345,169 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"СШÐ."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "Ðлагин запиÑи в Ñайл"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "ÐвÑомаÑиÑеÑки"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "ÐбÑединÑнное ÑÑеÑео"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "СÑеÑео"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Ðоно"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "ÐаÑамеÑÑÑ MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_ÐÐ"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "ÐаÑеÑÑво алгоÑиÑма:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "ÐÑÑ
Ð¾Ð´Ð½Ð°Ñ ÑаÑÑоÑа:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr "ЧаÑÑоÑа диÑкÑеÑизаÑии на вÑÑ
оде:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(ÐÑ)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "ÐиÑÑÐµÐ¹Ñ / СÑÐµÐ¿ÐµÐ½Ñ ÑжаÑиÑ:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "ÐаÑеÑÑво звÑка и ÑÑÐµÐ¿ÐµÐ½Ñ ÑжаÑиÑ:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ÐиÑÑÐµÐ¹Ñ (кб/Ñ)"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "СÑÐµÐ¿ÐµÐ½Ñ ÑжаÑиÑ:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "ÐÑдио Ñежим:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "ÐÑоÑее:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
msgstr "СÑÑогое ÑооÑвеÑÑÑвие ISO"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "ÐаÑиÑа Ð¾Ñ Ð¾Ñибок"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "ÐаÑеÑÑво"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "ÐклÑÑиÑÑ VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Тип:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "ÐаÑамеÑÑÑ VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "ÐинималÑнÑй биÑÑÐµÐ¹Ñ (кб/Ñ):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "ÐакÑималÑнÑй биÑÑÐµÐ¹Ñ (кб/Ñ):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "СÑÑогое ÑоблÑдение минималÑного биÑÑейÑа"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ÐаÑамеÑÑÑ ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "СÑедний биÑÑÐµÐ¹Ñ (кбиÑ/Ñ):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "УÑÐ¾Ð²ÐµÐ½Ñ ÐºÐ°ÑеÑÑва VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Ðе запиÑÑваÑÑ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¸ Xing VBR"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "ÐаÑамеÑÑÑ ÐºÐ°Ð¶Ñа:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr "ÐаÑамеÑÑÑ ÐºÐ°Ð´Ñа:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "ÐомеÑиÑÑ ÐºÐ°Ðº заÑиÑÑнное авÑоÑÑким пÑавом"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "ÐомеÑиÑÑ ÐºÐ°Ðº оÑигиналÑное"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "ÐаÑамеÑÑÑ ID3:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "ÐÑинÑдиÑелÑное добавление Ñегов 2-й веÑÑии"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "ТолÑко 1-Ñ Ð²ÐµÑÑÐ¸Ñ Ñегов"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "ТолÑко 2-Ñ Ð²ÐµÑÑÐ¸Ñ Ñегов"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Теги"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "ÐаÑÑÑойка кодека Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "УÑÐ¾Ð²ÐµÐ½Ñ ÐºÐ°ÑеÑÑва (0 â 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "lossless"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1522,11 +1519,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1534,11 +1527,19 @@ msgstr ""
"GIO Ðлагин Ð´Ð»Ñ Audaciousâ\n"
"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "Ðлагин GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "ÐедопÑÑÑимÑй меÑод оÑкÑÑÑиÑ"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1558,451 +1559,509 @@ msgstr ""
"\n"
"ÐиÑензиÑ: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL СпекÑÑалÑнÑй ÐнализаÑоÑ"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
-"ÐодÑÐ»Ñ \"ÐоÑÑÑие клавиÑи\" Ð´Ð»Ñ Gnome\n"
-"УпÑавление пÑоигÑÑваÑелем пÑи помоÑи \"гоÑÑÑиÑ
\n"
-"клавиÑ\", ÑказаннÑÑ
в наÑÑÑойкаÑ
Gnome.\n"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "OpenGL СпекÑÑалÑнÑй ÐнализаÑÐ¾Ñ (Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "ÐоÑÑÑие клавиÑи Gnome"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "ÐÐ¾Ð¼ÐµÑ Ð·Ð°Ð¿Ð¸Ñи"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Ðазвание"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "ÐÑполниÑелÑ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Ðод"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "ÐлÑбом"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "ÐÑполниÑÐµÐ»Ñ Ð°Ð»Ñбома"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "ÐоÑожка"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "ÐанÑ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Ðоложение в оÑеÑеди"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "ÐлиÑелÑноÑÑÑ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "ÐÑÑÑ Ðº ÑайлÑ"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "ÐÐ¼Ñ Ñайла"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "ÐадаÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ÐиÑÑейÑ"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "ÐоÑÑÑпнÑе колонки"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "ÐоказаннÑе колонки"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "ÐоиÑк"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "ÐÑикÑепиÑÑ Ñлева"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "ÐÑикÑепиÑÑ ÑпÑава"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "ÐÑикÑепиÑÑ Ð½Ð°Ð²ÐµÑÑ
Ñ"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "ÐÑикÑепиÑÑ Ð²Ð½Ð¸Ð·Ñ"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "ÐÑкÑепиÑÑ"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "ÐÑклÑÑиÑÑ"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "ÐоиÑк"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_ÐÑкÑÑÑÑ ÑÐ°Ð¹Ð»Ñ ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "ÐÑкÑÑÑÑ _URL ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_ÐобавиÑÑ ÑÐ°Ð¹Ð»Ñ ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "ÐобавиÑÑ U_RL ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "ÐоиÑк в библиоÑеке"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "Ð_ пÑогÑамме ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "_ÐаÑÑÑойки"
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_ÐÑÑ
од"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_ÐоÑпÑоизведение"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "ÐаÑз_а"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_СÑоп"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "ÐÑе_дÑдÑÑий"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_СледÑÑÑий"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_ÐовÑоÑ"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "Ð_ÑазбÑоÑ"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Ð_е пеÑедвигаÑÑÑÑ Ð¿Ð¾ ÑпиÑкÑ"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
-msgstr "ÐÑÑановка поÑле еÑой пеÑни"
+msgstr "ÐÑÑановка поÑле ÑÑой пеÑни"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "ÐнÑоÑмаÑÐ¸Ñ Ð¾ _пеÑне"
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "ÐеÑейÑи ко _вÑемени ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "_ÐеÑейÑи к пеÑне ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "ÐовÑÐ¾Ñ ÑÑÑановки _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "ÐовÑÐ¾Ñ ÑÑÑановки _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_ÐовÑÐ¾Ñ ÑиÑÑÑÑ
пÑнкÑов"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Ðо _названиÑ"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "Ðо _Ðмени"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "Ðо _имени Ñайла"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "ÐÑÑÑ Ðº ÑайлÑ"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Ðо _номеÑÑ ÑÑека"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Ðо _иÑполниÑелÑ"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Ðо ÐлÑбомÑ"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "Ðо иÑполниÑелÑ"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Ðо _даÑе вÑпÑÑка"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "Ðо _жанÑÑ"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "Ðо _Ðлинне"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Ðо ÑаÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ _Ñайла"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Ðо _Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð¼Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñайла"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Ð _обÑаÑном поÑÑдке"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "Ð _ÑлÑÑайном поÑÑдке"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_ÐоÑпÑоизвеÑÑи ÑÑÐ¾Ñ ÑпиÑок"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_ÐоÑпÑоизвеÑÑи/пÑодолжиÑÑ"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "ÐбновиÑÑ"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_СоÑÑиÑоваÑÑ"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "СоÑÑиÑоваÑÑ Ð²ÑбÑаннÑе"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "УдалиÑÑ _ÐÑбликаÑÑ"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "УбÑаÑÑ _недоÑÑÑпнÑе ÑайлÑ"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_ÐовÑй"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "ÐеÑе_именоваÑÑ"
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "УбÑаÑÑ"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_ÐмпоÑÑиÑоваÑÑ ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_ÐкÑпоÑÑиÑоваÑÑ ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "_УпÑавление ÑпиÑками..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_УпÑавление оÑеÑедÑÑ ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "УвелиÑиÑÑ Ð³ÑомкоÑÑÑ"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "УменÑÑиÑÑ Ð³ÑомкоÑÑÑ"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_ÐквалайзеÑ"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "Ð_ÑÑекÑÑ"
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "ÐоказÑваÑÑ _Ð¿Ð°Ð½ÐµÐ»Ñ Ð¼ÐµÐ½Ñ"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "ÐоказÑваÑÑ Ð¿_Ð°Ð½ÐµÐ»Ñ Ð¸Ð½ÑоÑмаÑии"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "ÐоказÑваÑÑ Info Bar Vis_ualization"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "ÐоказÑваÑÑ _ÑÑÑÐ¾ÐºÑ ÑоÑÑоÑниÑ"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "ÐоказаÑÑ _ÐÑÑавÑееÑÑ Ð²ÑемÑ"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "_ÐизÑализаÑиÑ..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Файл"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_ÐоÑпÑоизведение"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "С_пиÑок"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_СлÑжбÑ"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_ÐÑвод"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Ðид"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_ÐÐ»ÐµÐ¼ÐµÐ½Ñ Ð¾ÑеÑеди"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "_ÐÑкÑÑÑÑ ÑаÑположение Ñайла"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "_ÐÑÑезаÑÑ"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_ÐопиÑоваÑÑ"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_ÐÑÑавиÑÑ"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "ÐÑбÑаÑÑ _вÑÑ"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "ÐеÑе_именоваÑÑ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>Ðкладки плейлиÑÑа</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "ÐÑегда показÑваÑÑ Ð²ÐºÐ»Ð°Ð´ÐºÐ¸"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "ÐоказÑваÑÑ ÑÑеÑÑик ÑлеменÑов"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "ÐоказÑваÑÑ ÐºÐ½Ð¾Ð¿ÐºÐ¸ закÑÑÑиÑ"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>Ðолонки плейлиÑÑа</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "ÐоказÑваÑÑ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¸ ÑÑолбÑов"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Разное</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr "ÐоиÑк ÑÑÑелками:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "ÐÑокÑÑÑиваÑÑ Ð¿Ñи Ñмене пеÑни"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "ÐнÑеÑÑÐµÐ¹Ñ GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ÐÑÑеÑизаÑÐ¸Ñ ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "моно"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "ÑÑеÑео"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
@@ -2010,84 +2069,98 @@ msgstr[0] "%d канал"
msgstr[1] "%d канала"
msgstr[2] "%d каналов"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d кбиÑ/Ñ"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "ÐдиноÑнÑй Ñежим"
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Режим ÑпиÑка воÑпÑоизведениÑ"
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "ÐÑÑановиÑÑ Ð¿Ð¾Ñле доÑожки"
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "ÐÑедÑдÑÑÐ°Ñ Ð´Ð¾Ñожка"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "ÐоÑпÑоизвеÑÑи"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "ÐаÑза/ÐÑодолжиÑÑ"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "ÐÑÑановиÑÑ"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "СледÑÑÑÐ°Ñ Ð´Ð¾Ñожка"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "ÐеÑемоÑаÑÑ Ð²Ð¿ÐµÑÑд на 5 Ñек"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "ÐеÑемоÑаÑÑ Ð½Ð°Ð·Ð°Ð´ на 5 Ñек"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "ÐÑиглÑÑиÑÑ"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "УвелиÑиÑÑ Ð³ÑомкоÑÑÑ"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "УменÑÑиÑÑ Ð³ÑомкоÑÑÑ"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "ÐеÑейÑи к ÑайлÑ"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "ÐеÑеклÑÑиÑÑ ÑоÑÑоÑние окон пÑоигÑÑваÑелÑ"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "ÐÑобÑазиÑÑ ÑкÑанное ÑообÑение (OSD)"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "ÐовÑоÑ"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "ÐеÑеÑаÑовка"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "ÐÑÑановиÑÑ Ð¿Ð¾Ñле ÑекÑÑего"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "ÐоднÑÑÑ Ð¾ÐºÐ½Ð¾(а) плееÑа"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(неÑ)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2099,15 +2172,11 @@ msgstr ""
"\n"
"ÐÑодолжиÑÑ?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "ÐÑивÑзки к кнопкам мÑÑи"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "ÐаÑамеÑÑÑ Ð¼Ð¾Ð´ÑÐ»Ñ ÐлобалÑнÑе \"гоÑÑÑие клавиÑи\""
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2115,23 +2184,27 @@ msgstr ""
"ÐажмиÑе комбинаÑÐ¸Ñ ÐºÐ»Ð°Ð²Ð¸Ñ Ð² ÑекÑÑовом поле.\n"
"Ðожно Ñакже ÑделаÑÑ Ð¿ÑивÑзки к кнопкам мÑÑи."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "ÐоÑÑÑие клавиÑи:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>ÐейÑÑвие:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>ÐÑивÑзка клавиÑ:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "ÐобавиÑÑ"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "ÐлобалÑнÑе гоÑÑÑие клавиÑи"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2158,60 +2231,54 @@ msgstr ""
"\t\t\tJonathan A. Davis <davis at jdhouse.org>\n"
"\t\t\tJeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "ÐлобалÑнÑе гоÑÑÑие клавиÑи"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "ÐÑвод JACK"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "ÐодÑоединиÑÑÑÑ Ðº доÑÑÑпнÑм поÑÑам"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "ÐвÑомаÑиÑеÑки подклÑÑаÑÑÑÑ Ðº поÑÑам вÑвода"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "ÐодÑоединиÑÑÑÑ ÑолÑко к поÑÑам вÑвода"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "ÐбнаÑÑÐ¶ÐµÐ½Ñ ÑолÑко вÑÑ
однÑе ÑазÑÑÐ¼Ñ %d JACK, но ÑÑебÑеÑÑÑ %d."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "Ðе подклÑÑаÑÑÑÑ Ð½Ð¸ к каким поÑÑам"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "ÐÑибка подклÑÑÐµÐ½Ð¸Ñ Ðº ÑазÑÑÐ¼Ñ JACK %s."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "Режим ÑоединениÑ:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "ÐÑводиÑÑ Ð¾ÑладоÑнÑÑ Ð¸Ð½ÑоÑмаÑиÑ"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "Сбой подклÑÑÐµÐ½Ð¸Ñ Ðº ÑеÑвеÑÑ JACK; он ÑабоÑаеÑ?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"ÐÑнован на xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"ÐоÑÑиÑован в Audacious Giacomo Lozito"
+"СеÑÐ²ÐµÑ JACK ÑÑебÑÐµÑ ÑаÑÑоÑÑ Ñемплов %d ÐÑ, но Audacious воÑпÑÐ¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ Ð½Ð° %d "
+"ÐÑ. ÐожалÑйÑÑа, иÑполÑзÑйÑе ÑÑÑÐµÐºÑ ÐºÐ¾Ð½Ð²ÐµÑÑеÑа ÑаÑÑоÑÑ Ñемплов Ð´Ð»Ñ ÑÑÑÑÐ°Ð½ÐµÐ½Ð¸Ñ "
+"неÑовпадений."
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "ÐÑвод JACK"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s ÐаÑÑÑойки"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "ÐаÑÑÑойки Ñ
оÑÑа LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "ÐÑÑÑ Ðº модÑлÑм:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2221,25 +2288,25 @@ msgstr ""
"ÐоиÑк оÑÑÑеÑÑвлÑеÑÑÑ Ð¿Ð¾ ÑказаннÑм пÑÑÑм и пеÑеменной LADSPA_PATH.\n"
"Указав пÑÑи, нажмиÑе Enter Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка новÑÑ
плагинов.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "ÐоÑÑÑпнÑе плагинÑ:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "ÐклÑÑиÑÑ"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "ÐклÑÑеннÑе плагинÑ"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "ÐаÑÑÑойки"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2247,47 +2314,15 @@ msgstr ""
"LADSPA ХоÑÑ Ð´Ð»Ñ Audacious\n"
"ÐвÑоÑÑÑво 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "СеÑÐ²ÐµÑ LADSPA"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: не Ð¼Ð¾Ð³Ñ Ð¸Ð½Ð¸ÑиализиÑоваÑÑ Ð¿Ð¾Ð´Ð´ÐµÑÐ¶Ñ LIRC\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: не Ð¼Ð¾Ð³Ñ Ð¿ÑоÑеÑÑÑ ÐºÐ¾Ð½ÑигÑÑаÑионнÑй Ñайл LIRC\n"
-"%s: пожалÑйÑÑа пÑоÑÑиÑе докÑменÑаÑÐ¸Ñ Ðº LIRC\n"
-"%s: как ÑоздаÑÑ Ð¿ÑавилÑнÑй конÑигÑÑаÑионнÑй Ñайл\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: пÑÑаÑÑÑ Ð¿ÐµÑеподклÑÑиÑÑÑÑ...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: неизвеÑÑÐ½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: оÑклÑÑен Ð¾Ñ LIRC\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: пеÑеподклÑÑаÑÑÑÑ ÐºÐ°Ð¶Ð´Ñе %d ÑекÑнд...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Ðлагин LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2316,73 +2351,81 @@ msgstr ""
"\n"
"ÐолÑÑе инÑÑомаÑии пÑо LIRC, ÑмоÑÑиÑе http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>ÐодклÑÑение</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "ÐеÑеподклÑÑиÑÑÑÑ Ðº LIRC ÑеÑвеÑÑ"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "ÐдаÑÑ Ð¿ÐµÑед пеÑеподклÑÑением:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Ðлагин LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "Ðлагин LyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "ТекÑÑ Ð¿ÐµÑни недоÑÑÑпен"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "ÐÑибка"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "ÐÑибка"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Ðе ÑдалоÑÑ Ð¿ÑоанализиÑоваÑÑ %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "ÐоиÑк ÑекÑÑа пеÑни ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "ÐеÑаданнÑе пеÑни оÑÑÑÑÑÑвÑÑÑ"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°Ñ Ñоединение Ñ lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "Ðлагин LyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "ÐадÑÑÑойка LyricWiki (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "СпиÑки воÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ M3U"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑов"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "ТакÑовÑй генеÑаÑоÑ: %d ÑакÑов/Ñ"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "ТакÑовÑй генеÑаÑоÑ: %d Ñд/мин %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2396,11 +2439,11 @@ msgstr ""
"напÑÐ¸Ð¼ÐµÑ tact://77 to play 77 beats per minute\n"
"или tact://60*3/4 to play 60 bpm in 3/4 tacts"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑов"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "ÐикÑÐµÑ ÐºÐ°Ð½Ð°Ð»Ð¾Ð²"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2408,152 +2451,184 @@ msgstr ""
"Ðлагин ÑмеÑÐ¸Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð² Audacious\n"
"ÐвÑоÑÑÑво 2011-2012 John Lindgren and MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>ÐикÑÐµÑ ÐºÐ°Ð½Ð°Ð»Ð¾Ð²</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Ðаналов на вÑÑ
оде:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "ÐикÑÐµÑ ÐºÐ°Ð½Ð°Ð»Ð¾Ð²"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "Ðлагин MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "ÐÑибка подклÑÑÐµÐ½Ð¸Ñ Ðº ÑеÑвеÑÑ MMS"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (модÑлÑнÑй плееÑ)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>РазÑеÑение</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-биÑ"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-биÑ"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>ÐаналÑ</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "ÐлижайÑий (ÑамÑй бÑÑÑÑÑй)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "ÐинейнÑй (бÑÑÑÑÑй)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Сплайн (Ñ
оÑоÑий)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "ÐногоÑазнÑй (лÑÑÑий)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr "<b>ЧаÑÑоÑа диÑкÑеÑизаÑии</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 кÐÑ:"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 кÐÑ:"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 кÐÑ:"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 кÐÑ:"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "УÑовенÑ:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "ÐÑклÑÑение:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>РевеÑбеÑаÑиÑ</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>УÑиление баÑов</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>ÐкÑÑжение</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>ÐÑедÑÑилиÑелÑ</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "ÐеÑекÑÑÑие"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "ШÑмоподавление"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "ÐоÑпÑоизвеÑÑи модиÑикаÑÐ¸Ñ Amiga"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>ÐовÑоÑиÑÑ</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "СÑеÑÑик повÑоÑений:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "ÐовÑоÑÑÑÑ Ð²Ñегда, задаÑÑ ÑиÑло повÑоÑов до -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (модÑлÑнÑй плееÑ)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "ÐбÑÑмное звÑÑание"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "ÐаÑÑÑойки вÑÑÑпÑÑ Ð² ÑÐ¸Ð»Ñ Ð¿Ð¾Ñле пеÑезапÑÑка Audacious."
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "Ðлагин MPG123"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>РаÑÑиÑеннÑе</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "ÐÑполÑзоваÑÑ Ð°ÐºÐºÑÑаÑное вÑÑиÑление Ð´Ð»Ð¸Ð½Ñ (медленно)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "ÐбÑÑмное звÑÑание"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "СеÑÐ²ÐµÑ MPRIS 2"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Ðлагин Neon HTTP/HTTPS"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "ÐÑибка паÑÑинга пеÑенапÑавлений"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "ÐеизвеÑÑÐ½Ð°Ñ Ð¾Ñибка HTTP"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "ÐÑибка паÑÑинга URL"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "СлиÑком много пеÑенапÑавлений"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "ÐÑÑановлен"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious ниÑего не воÑпÑоизводиÑ."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "ÐÑплÑваÑÑие ÑообÑениÑ"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2584,55 +2659,64 @@ msgstr ""
"ÐÑ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±Ñли полÑÑиÑÑ ÐºÐ¾Ð¿Ð¸Ñ ÑÑандаÑÑной ÐбÑеÑÑвенной ÐиÑензии GNU вмеÑÑе Ñ "
"ÑÑой пÑогÑаммой. ÐÑли неÑ,ÑмоÑÑиÑе <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "ÐоказаÑÑ ÐºÐ½Ð¾Ð¿ÐºÐ¸ ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¾ÑпÑоизведением"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "ÐÑегда показÑваÑÑ ÑведомлениÑ"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "ÐÑплÑваÑÑие ÑообÑениÑ"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "ÐклÑÑиÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ алÑбома в Ñведомление"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "ÐоказаÑÑ"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "ÐаÑза"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "СледÑÑÑÐ°Ñ Ð´Ð¾Ñожка"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. УÑÑÑойÑÑво по ÑмолÑаниÑ"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "ÐÑвод OSS4"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "ÐÑÑ
од OSS3"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "УÑÑÑойÑÑво по ÑмолÑаниÑ"
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "ÐвÑковое ÑÑÑÑойÑÑво:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "ÐÑполÑзоваÑÑ Ð´ÑÑгое ÑÑÑÑойÑÑво:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "СоÑ
ÑанÑÑÑ Ð³ÑомкоÑÑÑ Ð¼ÐµÐ¶Ð´Ñ ÑеÑÑиÑми."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "РазÑеÑиÑÑ Ð¿ÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑоÑмаÑа Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ OSS."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "ÐклÑÑиÑÑ Ð¼Ð¾Ð½Ð¾Ð¿Ð¾Ð»ÑнÑй Ñежим, ÑÑÐ¾Ð±Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ Ð²Ð¸ÑÑÑалÑного микÑиÑованиÑ."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2646,19 +2730,35 @@ msgstr ""
"Я Ñ
оÑÑ Ð¿Ð¾Ð±Ð»Ð°Ð³Ð¾Ð´Ð°ÑиÑÑ ÑеÑ
лÑдей #audacious, оÑобенно Тони Vroon и Ðжон "
"ÐиндгÑен и, конеÑно же авÑоÑов пÑедÑдÑÑиÑ
OSS плагин."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "ÐÑвод OSS4"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "СпиÑки воÑпÑоизведениÑ"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "ÐлеменÑÑ"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_УдалиÑÑ"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "ÐеÑе_именоваÑÑ"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "СпиÑки воÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ PLS"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ OpenPSF PSF1/PSF2"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "ÐÑвод PulseAudio"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2696,11 +2796,73 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"СШÐ."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "ÐÑвод PulseAudio"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "ÐÑÑ
од QtMultimedia"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"Ðлагин QtMultimedia Audio Output Ð´Ð»Ñ Audacious\n"
+"ÐÑава заÑиÑÐµÐ½Ñ 2014 Уиллиам ÐиÑкок\n"
+"\n"
+"ÐÑнован на плагине SDL Output Ð´Ð»Ñ Audacious\n"
+"ÐÑава заÑиÑÐµÐ½Ñ 2010 Ðжон ÐиндгÑÑн"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "РабоÑÐ°Ñ ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "ÐоиÑк"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "_OÑкÑÑÑÑ Ð¿Ð°Ð¿ÐºÑ ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_ÐобавиÑÑ Ð¿Ð°Ð¿ÐºÑ ..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "_ÐнÑпекÑÐ¾Ñ Ð¶ÑÑнала ..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "ÐÑкÑÑÑÑ ÑайлÑ"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "ÐобавиÑÑ ÑайлÑ"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ÐÑедÑдÑÑÐ°Ñ Ð´Ð¾Ñожка"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "ÐовÑоÑ"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "СлÑÑайно"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "ÐнÑеÑÑÐµÐ¹Ñ Qt"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "ÐонвеÑÑÐµÑ ÑаÑÑоÑÑ"
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2708,99 +2870,107 @@ msgstr ""
"ÐонвеÑÑÐµÑ ÑаÑÑоÑÑ Ð´Ð¸ÑкÑеÑизаÑии Ðлагин Ð´Ð»Ñ Audacious\n"
"ÐвÑоÑÑÑво 2010-2012 Ðжон ÐиндгÑен"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "ÐÑопÑÑÑиÑÑ/повÑоÑиÑÑ ÑÑмплÑ"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "ÐÐ¸Ð½ÐµÐ¹Ð½Ð°Ñ Ð¸Ð½ÑеÑполÑÑиÑ"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "ÐÑÑÑÑÐ°Ñ sinc инÑеÑполÑÑиÑ"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "СÑеднÑÑ sinc инÑеÑполÑÑиÑ"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "ÐÑÑÑÐ°Ñ sinc инÑеÑполÑÑиÑ"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>ÐÑеобÑазование</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "ÐеÑод:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "ЧаÑÑоÑа:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>ÐаÑÑа ÑаÑÑоÑ</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "ÐÑполÑзваÑÑ ÐºÐ°ÑÑÑ ÑаÑÑоÑ"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 кÐÑ:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 кÐÑ:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 кÐÑ:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 кÐÑ:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 кÐÑ:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 кÐÑ:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 кÐÑ:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 кÐÑ:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 кÐÑ:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 кÐÑ:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "ÐонвеÑÑÐµÑ ÑаÑÑоÑÑ"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "OK. ÐÑоÑлÑÑивание Ð´Ð»Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "ÐÑказано в доÑÑÑпе"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"ÐоÑполÑзÑйÑеÑÑ ÑледÑÑÑей ÑÑÑлкой ÑÑÐ¾Ð±Ñ ÑазÑеÑиÑÑ Audacious оÑпÑавлÑÑÑ "
"пÑоÑлÑÑаннÑе композиÑии на Last.fm:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"ÐÑÑавÑе ÑÑо окно оÑкÑÑÑÑм и нажмиÑе ÐºÐ½Ð¾Ð¿ÐºÑ \" ÐапÑоÑиÑÑ ÑазÑеÑение' Ñнова.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2809,34 +2979,38 @@ msgstr ""
"Ðн бÑÐ´ÐµÑ Ð´Ð¾ÑÑавлен на Last.fm, как ÑолÑко Audacious полÑÑÐ¸Ñ ÑазÑеÑение ÑÑо "
"ÑделаÑÑ."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "ÐÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ñ ÑеÑÑÑ"
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "Ðевозможно подклÑÑиÑÑÑ Ðº Last.fm. ÐопÑобÑйÑе повÑоÑиÑÑ Ð¿Ð¾Ð·Ð¶Ðµ"
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "ÐÑовеÑка..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "Ð_апÑоÑиÑÑ ÑазÑеÑение"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_ÐÑмениÑÑ ÑазÑеÑение"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"ÐÑ Ð´Ð¾Ð»Ð¶Ð½Ñ ÑазÑеÑиÑÑ Audacious оÑпÑавлÑÑÑ Ð¿ÑоÑлÑÑаннÑе доÑожки в Ð²Ð°Ñ Ð°ÐºÐºÐ°ÑÐ½Ñ "
"Last.fm\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "СкÑÐ¾Ð±Ð±Ð»ÐµÑ 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2844,7 +3018,7 @@ msgstr ""
"Ðлагин scrobbler не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð·Ð°Ð¿ÑÑен.\n"
"ÐогÑÑ Ð±ÑÑÑ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ñ ÑÑÑановкой"
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2860,11 +3034,7 @@ msgstr ""
"\n"
"СпаÑибо ÐÐ¶Ð¾Ð½Ñ ÐиндгÑен ÑÑо подал мне ÑÑÐºÑ Ð² наÑале ÑÑого пÑоекÑа.\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "СкÑÐ¾Ð±Ð±Ð»ÐµÑ 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2872,7 +3042,11 @@ msgstr ""
"Audacious ÑепеÑÑ Ð¸ÑполÑзÑÐµÑ ÑÑовеÑÑенÑÑвованнÑÑ Ð²ÐµÑÑÐ¸Ñ Ð¼Ð¾Ð´ÑÐ»Ñ Last.fm "
"Scrobbler"
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "ÐÑвод SDL"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2881,88 +3055,59 @@ msgstr ""
"SDL модÑÐ»Ñ ÐÑвода Ð´Ð»Ñ Audacious\n"
"ÐвÑоÑÑÑво 2010 Ðжон ÐиндгÑен"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "ÐÑвод SDL"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "ÐиблиоÑека"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "ÐеизвеÑÑнÑй иÑполниÑелÑ"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "ÐеизвеÑÑнÑй алÑбом"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-"Ð¾Ñ %s до %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d ÑезÑлÑÑаÑ"
+msgstr[1] "%d ÑезÑлÑÑаÑов"
+msgstr[2] "%d ÑезÑлÑÑаÑов"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d алÑбом"
-msgstr[1] "%d алÑбомÑ"
-msgstr[2] "%d алÑбомÑ"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d ÑкÑÑÑо)"
+msgstr[1] "(%d ÑкÑÑÑо)"
+msgstr[2] "(%d ÑкÑÑÑо)"
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d пеÑнÑ"
-msgstr[1] ""
-"%s\n"
-" %s, %d пеÑни"
-msgstr[2] ""
-"%s\n"
-" %s, %d пеÑни"
-
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d пеÑÐ½Ñ Ð´Ð¾ %s"
-msgstr[1] ""
-"%s\n"
-" %d пеÑни до %s"
-msgstr[2] ""
-"%s\n"
-" %d пеÑни до %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d пеÑнÑ"
+msgstr[1] "%d пеÑен"
+msgstr[2] "%d пеÑен"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "ÑÑого жанÑа"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "на"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "оÑ"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_СоздаÑÑ ÑпиÑок воÑпÑоизведениÑ"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_ÐобавиÑÑ Ð² ÑпиÑок воÑпÑоизведениÑ"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "ÐоиÑк в библиоÑеке"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2970,679 +3115,771 @@ msgstr ""
"ÐÐ»Ñ Ð¸Ð¼Ð¿Ð¾ÑÑа мÑзÑки в библиоÑÐµÐºÑ Audacious вÑбеÑиÑе каÑалог, заÑем нажмиÑе "
"Ð¸ÐºÐ¾Ð½ÐºÑ \"обновиÑÑ\"."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "ÐожалÑйÑÑа, подождиÑе ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "ÐÑбеÑиÑе каÑалог"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "ÐÑоигÑÑваÑÐµÐ»Ñ SID"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>ÐÑвод</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "ÐаналÑ:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>ÐмÑлÑÑиÑ</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "Ðе вÑбиÑаÑÑ Ð¼Ð¾Ð´ÐµÐ»Ñ Ñипа авÑомаÑиÑеÑки"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "ÐмиÑиÑоваÑÑ ÑилÑÑÑ"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>ÐÑÐµÐ¼Ñ Ð²Ð¾ÑпÑоизведениÑ</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "ÐазнаÑиÑÑ Ð¼Ð°ÐºÑималÑное вÑÐµÐ¼Ñ Ð²Ð¾ÑпÑоизведениÑ:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "ÐадейÑÑвоваÑÑ Ð² ÑлÑÑае, когда длина композиÑии неизвеÑÑна"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "ÐазнаÑиÑÑ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»Ñное вÑÐµÐ¼Ñ Ð²Ð¾ÑпÑоизведениÑ:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "ШÑмоподавление"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"Ðлагин ÑÑÐ¼Ð¾Ð¿Ð¾Ð´Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Audacious\n"
+"ÐÑава заÑиÑÐµÐ½Ñ 2014 Ðжон ÐиндгÑÑн"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>ШÑмоподавление</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "ÐÑимеÑÑ:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "дÐ"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "ÐÑкÑÑÑÑ ÑайлÑ..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "ÐÑкÑÑÑÑ URL..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "ÐоиÑк в библиоÑеке"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "ÐоÑпÑоизведение"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
-msgstr "СпиÑок воÑпÑоизведениÑ"
+msgstr "ÐлейлиÑÑ"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Ðид"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "СлÑжбÑ"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "Ð..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "наÑÑÑойки ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "ÐÑÑ
од"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "ÐнÑоÑмаÑÐ¸Ñ Ð¾ пеÑне"
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "ÐовÑоÑ"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "СлÑÑайно"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Ðез Ð´Ð²Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑпиÑÐºÑ Ð²Ð¾ÑпÑоизведениÑ"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "ÐÑÑановиÑÑ Ð¿Ð¾Ñле ÑÑой пеÑни"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ÐÑедÑдÑÑÐ°Ñ Ð´Ð¾Ñожка"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "УÑÑановиÑÑ A-B повÑоÑ"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "УдалиÑÑ A-B повÑоÑ"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "ÐеÑейÑи к пеÑне ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "ÐеÑейÑи ко вÑемени ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "ÐоÑпÑоизвеÑÑи ÑÑÐ¾Ñ ÑпиÑок"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "ÐоÑпÑоизвеÑÑи/пÑодолжиÑÑ"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "ÐовÑй ÑпиÑок воÑпÑоизведениÑ"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
-msgstr "ÐеÑеименоваÑÑ ÑпиÑок воÑпÑоизведениÑ"
+msgstr "ÐеÑеименоваÑÑ ÑпиÑок"
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "УдалиÑÑ Ð¿Ð»ÐµÐ¹Ð»Ð¸ÑÑ"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "ÐÑедÑдÑÑий ÑпиÑок"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "СледÑÑÑий ÑпиÑок"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "ÐмпоÑÑиÑоваÑÑ ÑпиÑок воÑпÑоизведениÑ"
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "ÐкÑпоÑÑиÑоваÑÑ ÑпиÑок воÑпÑоизведениÑ"
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "УпÑавление ÑпиÑками..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "УпÑавление оÑеÑедÑÑ ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "ÐбновиÑÑ ÑпиÑок воÑпÑоизведениÑ"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "ÐÑобÑазиÑÑ ÑедакÑÐ¾Ñ ÑпиÑка воÑпÑоизведениÑ"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "ÐÑобÑазиÑÑ ÑквалайзеÑ"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "ÐоказаÑÑ ÐÑÑавÑееÑÑ Ð²ÑемÑ"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "ÐовеÑÑ
вÑеÑ
окон"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "Ðа вÑеÑ
ÑабоÑиÑ
ÑÑолаÑ
"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "СвеÑнÑÑÑ Ð¿ÑоигÑÑваÑелÑ"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "СвеÑнÑÑÑ ÑедакÑÐ¾Ñ ÑпиÑка воÑпÑоизведениÑ"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "СвеÑнÑÑÑ ÑквалайзеÑ"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "Ðвойной ÑазмеÑ"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "ÐобавиÑÑ URL ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "ÐобавиÑÑ ÑайлÑ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Ðо названиÑ"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "Ðо имени Ñайла"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "Ðо ÑаÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ _Ñайла"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "УдалиÑÑ Ð²Ñе"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "ÐÑиÑÑиÑÑ Ð¾ÑеÑедÑ"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "УдалиÑÑ Ð½ÐµÐ´Ð¾ÑÑÑпнÑе ÑайлÑ"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "УдалиÑÑ Ð´ÑбликаÑÑ"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "УдалиÑÑ Ð½Ðµ оÑмеÑеннÑе"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "УдалиÑÑ Ð²ÑбÑаннÑе"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "ÐайÑи и вÑбÑаÑÑ"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "ÐнвеÑÑиÑоваÑÑ Ð²ÑбоÑ"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "СнÑÑÑ Ð²Ñделение"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "ÐÑбÑаÑÑ Ð²Ñе"
-#: src/skins/menus.c:168 src/skins/menus.c:178
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Ðо номеÑÑ Ð´Ð¾Ñожки"
+
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
+msgid "By Artist"
+msgstr "Ðо иÑполниÑелÑ"
+
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
msgid "By Album"
msgstr "Ðо алÑбомÑ"
-#: src/skins/menus.c:169 src/skins/menus.c:179
-msgid "By Artist"
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
msgstr "Ðо иÑполниÑелÑ"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "Ðо _даÑе вÑпÑÑка"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Ðо номеÑÑ Ð´Ð¾Ñожки"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "Ðо жанÑÑ"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "Ðо длиÑелÑноÑÑи"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "Ðо _Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð¼Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñайла"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "СоÑÑиÑоваÑÑ Ð² ÑлÑÑайном поÑÑдке"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "РобÑаÑном поÑÑдке"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "СоÑÑиÑоваÑÑ Ð²ÑбÑаннÑе"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "СоÑÑиÑоваÑÑ ÑпиÑок"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "ÐÑÑезаÑÑ"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "ÐопиÑоваÑÑ"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "ÐÑÑавиÑÑ"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "РоÑеÑедÑ/Ðз оÑеÑеди"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "ÐагÑÑзиÑÑ ÐÑедÑÑÑановкÑ"
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "ÐагÑÑзиÑÑ ÐвÑо УÑÑановкÑ..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "ÐагÑÑзиÑÑ Ð¿Ð¾ ÑмолÑаниÑ"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "ÐагÑÑзиÑÑ Ñайл пÑедÑÑÑановки"
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "ÐагÑÑзиÑÑ EQF Ñайл ..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "СоÑ
ÑаниÑÑ Ð¿ÑедÑÑÑановки...."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "СоÑ
ÑаниÑÑ Ð°Ð²Ñо ÑÑÑановки..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "СоÑ
ÑаниÑÑ Ð¿Ð¾ ÑмолÑаниÑ"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "ÑоÑ
ÑаниÑÑ Ñайл пÑедÑÑÑановки"
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "СоÑ
ÑаниÑÑ EQF Файл"
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "УдалиÑÑ Ð¿ÑедÑÑÑановкÑ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "УдалиÑÑ Ð°Ð²Ñо ÑÑÑановки..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "ÐмпоÑÑиÑоваÑÑ Ð¿ÑедÑÑÑановки WinAMP'a...."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "СбÑÐ¾Ñ Ð½Ð° ÐолÑ"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "ÐнÑеÑÑÐµÐ¹Ñ ÐºÐ»Ð°ÑÑиÑеÑкого Winamp"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "СоÑ
ÑаниÑÑ"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "ÐагÑÑзиÑÑ"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "ÐагÑÑзиÑÑ Ñайл пÑедÑÑÑановки"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "ÐагÑÑзиÑÑ EQF Ñайл"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "СоÑ
ÑаниÑÑ Ñайл пÑедÑÑÑановки"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "СоÑ
ÑаниÑÑ EQF Ñайл"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "ÐмпоÑÑиÑоваÑÑ Ð¿ÑедÑÑÑановки WinAMP'a"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "ÐÑедÑÑÑановки"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "ÐагÑÑзиÑÑ Ð¿ÑедÑÑÑановкÑ"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "ÐагÑÑзиÑÑ Ð°Ð²Ñо-ÑÑÑановки"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "СоÑ
ÑаниÑÑ Ð¿ÑедÑÑÑановки"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "СоÑ
ÑаниÑÑ Ð°Ð²ÑоÑÑÑановки"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "УдалиÑÑ Ð¿ÑедÑÑÑановкÑ"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "УдалиÑÑ Ð°Ð²ÑоÑÑÑановки"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
msgstr "ÐÑоигÑÑваÑелÑ:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "ÐÑбеÑиÑе ÑÑиÑÑ Ð¾Ñновного окна пÑоигÑÑваÑелÑ:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "СпиÑок воÑпÑоизведениÑ:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "СпиÑок:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
-msgstr "ÐÑбеÑиÑе ÑÑиÑÑ ÑпиÑка воÑпÑоизведениÑ:"
+msgstr "ÐÑбеÑиÑе ÑÑиÑÑ Ð¿Ð»ÐµÐ¹Ð»Ð¸ÑÑа:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>Скин</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>ШÑиÑÑÑ</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "ÐÑполÑзоваÑÑ ÑаÑÑÑовÑе ÑÑиÑÑÑ (поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑолÑко ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "ÐÑокÑÑÑиваÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ пеÑни "
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "ÐÑокÑÑÑиваÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ пеÑни в обоиÑ
напÑавлениÑÑ
"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "ÐнализаÑоÑ"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "ÐÑÑиллогÑамма"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "ÐÑпеÑаÑок голоÑа / VU измеÑиÑелÑ"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "ÐÑкл."
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "ÐбÑÑнÑй"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "ÐгонÑ"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "ÐеÑÑикалÑнÑе линии"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Ðинии"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "ÐолоÑки"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "ÐÑÐµÐ½Ñ Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Ðедленно"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "СÑедне"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "ÐÑÑÑÑо"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "ÐÑÐµÐ½Ñ Ð±ÑÑÑÑо"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "ТоÑки"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "ÐиниÑ"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "СплоÑнаÑ"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "ÐÑд"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "СглаженнÑй"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>Тип</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "Тип визÑализаÑии:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>ÐнализаÑоÑ</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "ÐоказÑваÑÑ Ð¿Ð¸ÐºÐ¸"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "ÐкÑаÑка:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "СÑилÑ:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "Спад:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "Спад пиков:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "СÑÐ¸Ð»Ñ Ð¾ÑÑиллогÑаммÑ:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "ÐкÑаÑка оÑпеÑаÑка голоÑа:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "СÑÐ¸Ð»Ñ VU измеÑиÑелÑ:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "ÐÑновной"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "ÐизÑализаÑиÑ"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "ÐÑедÑÑиление"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 кÐÑ"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "ÐÐºÐ²Ð°Ð»Ð°Ð¹Ð·ÐµÑ Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "ÐеÑеÑ
од к %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "ÐÑомкоÑÑÑ: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "ÐаланÑ: %d%% влево"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "ÐаланÑ: по ÑенÑÑÑ"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "ÐаланÑ: %d%% впÑаво"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "ÐÐµÐ½Ñ Ð¿Ð°ÑамеÑÑов"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "ÐÑклÑÑиÑÑ \"ÐовеÑÑ
вÑеÑ
окон\""
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "ÐклÑÑиÑÑ \"ÐовеÑÑ
вÑеÑ
окон\""
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "ÐнÑоÑмаÑÐ¸Ñ Ð¾ Ñайле"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "ÐÑиÑелÑнÑе обÑазÑ"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "ÐовÑоÑиÑÑ ÑÑÑановки A"
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "ÐовÑоÑиÑÑ ÑÑÑановки B"
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "ÐовÑоÑиÑÑ Ð¾ÑиÑеннÑе пÑнкÑÑ"
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "ÐдиноÑнÑй Ñежим"
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Режим ÑпиÑка воÑпÑоизведениÑ"
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "ÐÑÑановиÑÑ Ð¿Ð¾Ñле доÑожки"
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "ÐоиÑк запиÑей в акÑивном ÑпиÑке воÑпÑоизведениÑ"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "ÐоиÑк"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3654,57 +3891,61 @@ msgstr ""
"ÑегиÑÑÑÑ. ÐÑли Ð²Ñ Ð½Ðµ знаеÑе, как ÑабоÑаÑÑ ÑегÑлÑÑнÑе вÑÑажениÑ, пÑоÑÑо "
"вÑÑавÑÑе ÑаÑÑÑ Ð±Ñкв из Ñлова, коÑоÑÑе Ñ
оÑиÑе найÑи."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Ðазвание: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr "Ðаголовок:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "ÐлÑбом: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr "ÐлÑбом:"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "ÐÑполниÑелÑ: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr "ÐÑÑиÑÑ:"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "ÐÐ¼Ñ Ñайла: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "ÐÐ¼Ñ Ñайла:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "ÐÑиÑÑиÑÑ Ð¿ÑедÑдÑÑий вÑÐ±Ð¾Ñ Ð´Ð¾ наÑала поиÑка"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "ÐвÑомаÑиÑеÑки пеÑеклÑÑаÑÑ Ð¿Ð¾Ð¾ÑеÑÑдно на ÑооÑвеÑÑÑвÑÑÑим запиÑÑм"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "СоздаÑÑ Ð½Ð¾Ð²Ñй ÑпиÑок воÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñ ÑооÑвеÑÑÑвÑÑÑими запиÑÑми"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "РедакÑÐ¾Ñ ÑпиÑков воÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d из %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "ÐÑÑ
ивиÑÐ¾Ð²Ð°Ð½Ð½Ð°Ñ Ñема Winamp 2.x"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Ðе аÑÑ
ивиÑÐ¾Ð²Ð°Ð½Ð½Ð°Ñ Ñема Winamp 2.x"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Ðевозможно ÑоздаÑÑ ÐºÐ°Ñалог (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Ðлагин Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3744,84 +3985,73 @@ msgstr ""
"пÑогÑаммой; еÑли ÑÑого не пÑоизоÑло, напиÑиÑе во Free Software Foundation, "
"Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Ðлагин Sndfile"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "ÐÑÑ
од Sndio"
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Рплагине вÑвода Sndio"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
msgstr ""
-"Ðлагин вÑвода Sndio\n"
-"\n"
-"ÐвÑÐ¾Ñ â Thomas Pfaff <tpfaff at tp76.info>\n"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "ФоÑÐ¼Ð°Ñ Ð½Ðµ поддеÑживаеÑÑÑ"
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "ÐÑибка Sndio: ÐеподдеÑживаемÑй звÑковой ÑоÑÐ¼Ð°Ñ (%d)"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
msgstr ""
-"ФоÑÐ¼Ð°Ñ Ð½Ðµ поддеÑживаеÑÑÑ Ð·Ð°Ð¿ÑоÑеннÑм звÑковÑм ÑÑÑÑойÑÑвом.\n"
-"\n"
-"ÐопÑобÑйÑе еÑÑ Ñаз, запÑÑÑив ÑеÑÐ²ÐµÑ sndiod(1)"
-
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "УÑÑÑойÑÑво sndio"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(пÑÑÑо ознаÑÐ°ÐµÑ Â«Ð¿Ð¾ ÑмолÑаниÑ»)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "ÐÐ"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Смена доÑожки"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Ðоманда, запÑÑÐºÐ°ÐµÐ¼Ð°Ñ Audacious в наÑале воÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð¹ доÑожки"
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>ÐаÑамеÑÑÑ, пеÑедаваемÑе оболоÑке, Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð·Ð°ÐºÐ»ÑÑÐµÐ½Ñ Ð² "
+"кавÑÑки. РпÑоÑивном ÑлÑÑае Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°ÑноÑÑÑÑ</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>ÐомандÑ</b>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Ðоманда:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "Ðоманда Ð´Ð»Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ñле наÑала воÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð¹ композиÑии:"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Ðоманда, запÑÑÐºÐ°ÐµÐ¼Ð°Ñ Ð¿Ð¾Ñле оконÑÐ°Ð½Ð¸Ñ Ð´Ð¾Ñожки"
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "Ðоманда вÑполнÑÐµÐ¼Ð°Ñ Ð¿Ð¾Ñле оконÑÐ°Ð½Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð·Ð¸Ñии:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr ""
-"Ðоманда, запÑÑÐºÐ°ÐµÐ¼Ð°Ñ Audacious пÑи доÑÑижении конÑа ÑпиÑка воÑпÑоизведениÑ"
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "Ðоманда вÑполнÑÐµÐ¼Ð°Ñ Ð¿Ð¾Ñле оконÑÐ°Ð½Ð¸Ñ ÑпиÑка воÑпÑоизведениÑ:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Ðоманда, запÑÑÐºÐ°ÐµÐ¼Ð°Ñ Ð¿Ñи изменении Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ñожки (напÑимеÑ, пÑи "
-"воÑпÑоизведении из ÑеÑи)"
+"Ðоманда Ð´Ð»Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ñи изменении Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð·Ð¸Ñии (Ð´Ð»Ñ "
+"воÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑеÑи):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3835,26 +4065,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"ÐÑ Ð¼Ð¾Ð¶ÐµÑе иÑполÑзоваÑÑ ÑледÑÑÑие ÑоÑмаÑÑ ÑÑÑок, коÑоÑÑе бÑдÑÑ Ð·Ð°Ð¼ÐµÐ½ÐµÐ½Ñ Ð¿ÐµÑед "
-"вÑзовом ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ (не вÑе они Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ Ð´Ð»Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð¾ÐºÐ¾Ð½ÑÐ°Ð½Ð¸Ñ ÑпиÑка ). %F: "
-"Frequency (in hertz) %c: Number of channels %f: filename (full path) %l: "
-"length (in milliseconds) %n or %s: Song name %r: Rate (in bits per second) "
-"%t: Playlist position (%02d) %p: Currently playing (1 or 0) %a: Artist %b: "
-"Album %T: Track title"
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>ÐаÑамеÑÑÑ, пеÑедаваемÑе оболоÑке, Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð·Ð°ÐºÐ»ÑÑÐµÐ½Ñ Ð² "
-"кавÑÑки. РпÑоÑивном ÑлÑÑае Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°ÑноÑÑÑÑ</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "ÐомандÑ"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ композиÑии (Qt)"
+
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX РеÑемплеÑ"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3868,51 +4088,51 @@ msgstr ""
"ÐÑнован на плагине конвеÑÑоÑа ÑаÑÑоÑÑ Ð´Ð¸ÑкÑеÑизаÑии:\n"
"ÐвÑоÑÑÑво 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "ÐÑÑÑÑо"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "Ðизкое"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "ÐÑÑокое"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "ÐÑÐµÐ½Ñ Ð²ÑÑокое"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "ÐаÑеÑÑво:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX РеÑемплеÑ"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "СкоÑоÑÑÑ Ð¸ вÑÑоÑа"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>СкоÑоÑÑÑ Ð¸ вÑÑоÑа</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "СкоÑоÑÑÑ:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "ÐÑÑоÑа:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "СкоÑоÑÑÑ Ð¸ вÑÑоÑа"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Ðконка ÑÑаÑÑÑа"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "ÐаÑÑÑойки ..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3930,39 +4150,39 @@ msgstr ""
"ÐÑÐ¾Ñ Ð¼Ð¾Ð´ÑÐ»Ñ Ð¾ÑобÑÐ°Ð¶Ð°ÐµÑ Ð·Ð½Ð°Ñок пÑогÑаммÑ\n"
"в ÑиÑÑемном лоÑке"
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>ÐейÑÑвие пÑокÑÑÑки мÑÑи</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "ÐзмениÑÑ Ð³ÑомкоÑÑÑ"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "СмениÑÑ ÑекÑÑÑÑ Ð´Ð¾ÑожкÑ"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>ÐÑÑгие наÑÑÑойки</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "ÐÑклÑÑиÑÑ Ð²ÑплÑваÑÑее окно"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "ÐакÑÑÑÑ Ð² ÑиÑÑемнÑй ÑÑей"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "ÐÑодвигаÑÑÑÑ Ð¿Ð¾ ÑпиÑÐºÑ Ð²Ð¾ÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¿Ñи пÑокÑÑÑке колÑÑика"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Ðконка ÑÑаÑÑÑа"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "РаÑÑиÑенное ÑÑеÑео"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3972,24 +4192,24 @@ msgstr ""
"\n"
"Johan Levin 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>РаÑÑиÑенное ÑÑеÑео</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "РаÑÑиÑенное ÑÑеÑео"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "ÐенеÑаÑÐ¾Ñ Ñона"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f ÐÑ"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "ÐенеÑаÑÐ¾Ñ Ñигналов: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -4004,15 +4224,11 @@ msgstr ""
"ÑаÑÑоÑа1;ÑаÑÑоÑа2;ÑаÑÑоÑа3;...\n"
"ÐапÑимеÑ, tone://2000;2005 Ð´Ð»Ñ Ð²Ð¾ÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñигналов 2000 ÐÑ Ð¸ 2005 ÐÑ"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "ÐенеÑаÑÐ¾Ñ Ñона"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Удаление вокала"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4048,11 +4264,35 @@ msgstr ""
"\n"
"ÐоÑеÑиÑе ÑÐ°Ð¹Ñ Xiph.org Foundation по адÑеÑÑ http://www.xiph.org/"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ %s"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4062,19 +4302,19 @@ msgstr ""
"ÐÑнован на коде in_vtx.dll Ð¾Ñ Roman Sherbakov <v_soft at microfor.ru>\n"
"РеализаÑÐ¸Ñ Ð´Ð»Ñ Audacious вÑполнил Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "lossy (hybrid)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "lossy"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4084,14 +4324,18 @@ msgstr ""
"\n"
"ÐекоÑоÑÑй код плагина Miles Egan"
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ 2SF"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>ÐаÑÑÑойки XSF</b>"
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "Ðе пÑидаваÑÑ Ð·Ð½Ð°Ñение длиÑелÑноÑÑи из Ñайла"
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "XSPF"
diff --git a/po/si.po b/po/si.po
index 00dbde9564e5..292486fee293 100644
--- a/po/si.po
+++ b/po/si.po
@@ -3,16 +3,19 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# ashintha89 <ashintha at gmail.com>, 2013
-# D.N.Perera <deen.niro at gmail.com>, 2013
+# Ashintha Rukmal Perera <ashintha at gmail.com>, 2013
+# Ashintha Rukmal Perera <ashintha at gmail.com>, 2013-2014
+# Deenuka Niroshini Perera <deen.niro at gmail.com>, 2013
+# Deenuka Niroshini Perera <deen.niro at gmail.com>, 2013
+# P.I.Balasinghe <pushpika.indrachapa at gmail.com>, 2013
# P.I.Balasinghe <pushpika.indrachapa at gmail.com>, 2013
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Sinhala (http://www.transifex.com/projects/p/audacious/"
"language/si/)\n"
"Language: si\n"
@@ -21,40 +24,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr " à¶à¶±à· "
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "à¶à·âà¶»à·à¶¸à·à¶± "
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "à·à·à·à·à·
"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "Adà¶à·à·à·à¶±à·à¶º (AdLib à¶°à·à·à¶à¶º)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "à¶
à¶±à·à¶´à·à·
à·à·à·à·
"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "Adà¶à·à·à·à¶±à·à¶º (AdLib à¶°à·à·à¶à¶º)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "à·à·à·à· à¶à·à¶³à·à·à¶¸â"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -64,11 +55,7 @@ msgstr ""
"â\n"
"මà·à¶½à·à¶±à· à¶½à·à¶ºà¶± ලදà·à¶¯à· à¶à¶©à¶¸à· à·à·à¶à·à¶±à· à·à· à¶©à·à¶±à·à¶ºà·à¶½à· à·à·à¶§à·à¶©à·à¶©à¶±à· à·à·à·à·à¶±à·."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "à·à·à·à· à¶à·à¶³à·à·à¶¸â"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -110,7 +97,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -147,7 +134,7 @@ msgstr ""
"à·à·à¶©à·à¶´à·à¶» à·à·à¶°à·à¶±:\n"
"මà·à¶¸ à·à·à¶°à·à¶± à·à·à·à·à¶à¶±à·à·à·à¶¸à· à·à·à¶½à·à·à·à¶¯à· à¶°à·à·à¶±à¶º à¶à¶»à¶±à·à¶±.\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -171,382 +158,370 @@ msgstr ""
"à¶à·à¶§à·à· à¶à·à¶½ à·à·à·à· à¶à·à¶¯à·à·à¶¸ ටයà·à¶´à· à¶à¶»à¶±à·à¶± à·à· à¶à¶¶à¶§ à¶à¶º à¶´à·à¶±à·à·à·à¶¸à¶§\n"
"à¶
à·à·à·âය නම෠ටà·à¶à¶½ à¶¶à·à¶à·à¶à¶¸ à·à¶à·âà¶»à·à¶º à¶à¶»à¶±à·à¶± "
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "ම෠à¶à¶¶à¶à· à·à·à·à· à¶à·à¶³à·à·à¶¸à· à¶à¶¸à¶à·à¶¸à¶ºà·."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "à¶à¶¶à¶à· à¶
ද දà·à·à· මà¶à¶à· à¶à·à¶»à·à¶¸ à·à¶±à·à¶±à·..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "මà¶à¶à· à¶à·à¶»à·à¶¸â"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "à·à¶³à·à¶¯à·"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "à¶
à¶à·à¶»à·à·à·à¶¯à·"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "බදà·à¶¯à·"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "à¶¶à·âà¶»à·à·à·à¶´à¶à·à¶±à·à¶¯à·"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "à·à·à¶à·à¶»à·à¶¯à·"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "à·à·à¶±à·à·à¶»à·à¶¯à·"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "à¶à¶»à·à¶¯à·"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "à·à·à·à· à¶à·à¶³à·à·à¶¸à· à·à¶à·à¶±à¶ºà¶±à·"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "à·à·à¶½à·à·â"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "à·à·à·à·à¶à·à¶³à·à·à¶¸â (à¶´à·à¶»à¶±à·à¶¸à·à¶ºâ)"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "à¶´à·"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "à¶´à·à· à¶±à·à·à¶¬à·à¶±à·à¶±:â"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "à¶´à·à¶ºâ"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "මà·à¶±à·à¶à·à¶à·"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "à·à·à·à· à¶à·à¶³à·à·à¶¸à· à¶½à·à¶¶à·à¶º යà·à¶à· දà·à¶±à¶ºà¶±à· à¶à·à¶»à¶±à·à¶±â"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "දà·à·â"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "à¶´à·à¶»à¶±à·à¶¸à·à¶ºâ"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "දà·à·à·"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "à·à·à¶ºà¶±à¶º"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "à¶à¶´à·à¶´à¶»â"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "à·à¶¶à·à¶¯ මටà·à¶§à¶¸â"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "à¶à¶»à¶¸à·à¶· à¶à¶»à¶±à·à¶±â"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "à¶
à·à·à·à¶±à¶ºâ"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "දà·à¶±à·"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "à¶
මà¶à¶» à·à·à¶°à·à¶±â"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "à·à¶à·âà¶»à·à¶ºâ"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "à¶°à·à·à¶±à¶º à·à¶± à¶à·à¶±à·à· (à¶
මà¶à¶»â)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à·à¶à·â à¶à·à¶»à¶±à·à¶±"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "à·à·à¶à¶½à·à¶´â"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "මà·à¶±à·à·à¶¯ ම෠à·à·à¶à¶½à·à¶´à¶ºà¶±à·à¶à·à¶±à· à¶
දà·à·à· à·à¶±à·à¶±à·?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "à¶à¶¯à·à·"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "à¶à¶½à·à¶¶à¶¸à· à¶à¶½à·à·"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA à¶´à·âà¶»à¶à·à¶¯à·à¶±à¶º "
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"à¶à¶©à·à·à·à· à·à¶³à·à· ALSA à¶´à·âà¶»à¶à·à¶¯à·à¶± à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º\n"
+"à¶´à·âà¶»à¶à·à·à¶± à·à·à¶¸à·à¶à¶¸ à¶¢à·à¶±à· à¶½à·à¶±à·à¶©à·à¶à·à¶»à·à¶±à· 2009-2012\n"
+"මà¶à· à·à·à¶à·à¶à·à¶º ALSA à¶´à·âà¶»à¶à·à¶¯à·à¶± à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶ºà· à¶à¶»à·à¶à· à·à·à¶½à·à¶ºà¶¸à· à¶´à·à¶§à·à¶à·à¶à· à·à·à¶ à¶´à·à¶¯à¶± à¶
à¶à¶» à¶à·à·à¶à· à¶à·à¶à¶º "
+"ALSA à¶
à¶à·à¶´à·à¶ à¶´à·âරමà·à¶«à·à¶à· à¶±à·à·à¶± à·à·à¶§ à¶à¶¯à·à·à¶à¶ºà¶à· à¶½à·à· à¶·à·à·à·à¶à· à¶à¶»à¶± ලදà·."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "à¶´à·à¶»à¶±à·à¶¸à· PCM à¶à¶¸à·à¶´à¶±à·à¶±à¶º "
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "à¶´à·à¶»à¶±à·à¶¸à· මà·à·à·âà¶» à¶à·à¶»à·à¶¸à· à¶à¶¸à·à¶´à¶±à·à¶±à¶º "
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM à¶à¶¸à·à¶´à¶±à·à¶±à¶º:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "මà·à·à·âà¶» à¶à·à¶»à·à¶¸à· à¶à¶¸à·à¶´à¶±à·à¶±à¶º:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "මà·à·à·âà¶» à¶à·à¶»à·à¶¸à· මà·à¶½à¶¯à·âà¶»à·à·âය:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "à¶à·âරමයà·à¶±à· à¶
à¶©à· à·à· à¶±à·à·à¶à·à¶¸à¶à· à¶´à·à·
à·à¶¶à¶³ à¶à·âà¶»à·à¶ºà· à¶à·à¶»à·à¶¸â"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-à¶à·à·à·à¶±à·à¶º (MIDI à¶°à·à·à¶à¶º)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"à¶à¶©à·à·à·à· à·à¶³à·à· ALSA à¶´à·âà¶»à¶à·à¶¯à·à¶± à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º\n"
-"à¶´à·âà¶»à¶à·à·à¶± à·à·à¶¸à·à¶à¶¸ à¶¢à·à¶±à· à¶½à·à¶±à·à¶©à·à¶à·à¶»à·à¶±à· 2009-2012\n"
-"මà¶à· à·à·à¶à·à¶à·à¶º ALSA à¶´à·âà¶»à¶à·à¶¯à·à¶± à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶ºà· à¶à¶»à·à¶à· à·à·à¶½à·à¶ºà¶¸à· à¶´à·à¶§à·à¶à·à¶à· à·à·à¶ à¶´à·à¶¯à¶± à¶
à¶à¶» à¶à·à·à¶à· à¶à·à¶à¶º "
-"ALSA à¶
à¶à·à¶´à·à¶ à¶´à·âරමà·à¶«à·à¶à· à¶±à·à·à¶± à·à·à¶§ à¶à¶¯à·à·à¶à¶ºà¶à· à¶½à·à· à¶·à·à·à·à¶à· à¶à¶»à¶± ලදà·."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA à¶´à·âà¶»à¶à·à¶¯à·à¶±à¶º "
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-à¶à·à·à·à¶±à·à¶º (MIDI à¶°à·à·à¶à¶º)"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "à·à¶»à·à¶§à·à·à·"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-à¶´à·à¶±à· - SoundFont à¶à·à¶±à·à· à¶à·à¶»à¶±à·à¶±â"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_à¶
à·à¶½à¶à¶à· à¶à¶»à¶±à·à¶±â"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "à¶à·à¶±à· නමâ"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "à¶´à·âරමà·à¶«à¶º (බයà·à¶§à·à·à·)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "නමâ:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI à¶à·à¶»à¶à·à¶»à· </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "à·à·à¶©à¶à¶½à¶ºâ:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "දà·à¶ (මà·à¶½à· à¶à¶´à·à¶´à¶»â):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "à¶à¶«à·à¶© à¶à¶«à¶±:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "à·à·à¶ à¶½à·âයය"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "à¶à·à¶½à¶ºâ à¶¶à·à¶¯à·à¶¸â:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI à¶
දà·à·à· දà·à¶à·à·à·à¶¸à· à·à· පද රචනයන෠</span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* මà·à¶¸ MIDI à¶à·à¶±à·à·à·à·à· à¶
දà·à·à· දà·à¶à·à·à·à¶¸à· à¶±à·à¶¸à·à¶â *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* මà·à¶¸ MIDI à¶à·à¶±à·à·à·à·à· පද රචන෠නà·à¶¸à·à¶â *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_à·à·à¶±à·à¶±â"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr "(à¶
à·à¶½à¶à¶à· UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "AMIDI-à¶à·à·à·à¶±à·à¶º à¶à·à¶± "
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-à¶´à·à¶±à·à· "
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"මà·à¶©à·à¶ºà·à¶½ MIDI à¶à·à¶ à¶°à·à·à¶à¶º \n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"රචන෠à¶à¶»à¶± ලදà·à¶¯à· Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"à·à·à·à·à· à·à·à¶à·à¶à·à¶º...\n"
-"Clemens Ladisch à·à· Jaroslav Kysela\n"
-"à¶à·à·à¶±à·à¶à· à·à·à¶©à·à¶§à·à¶±à· à·à¶± aplaymidi à·à· amixer; à¶à·à· \n"
-"à¶à¶à· à¶´à·âරයà·à¶¢à¶±à·à¶à· à·à·à¶º. à¶à¶¸à·à¶±à·à¶¸ alsa-lib à¶½à·à¶à¶± \n"
-"ALSA API à·à·à¶©à·à¶¯à·à¶» à¶à¶à·à¶± à¶à·à¶±à·à¶¸à¶§ \n"
-"\n"
-"Alfredo Spadafina\n"
-"à·à¶§ à¶
à¶½à¶à¶à·à¶» midi යà¶à·à¶»à· à¶´à·à·à¶»à· à¶½à·à¶à¶¡à¶±à¶º à·à¶³à·à· \n"
-"\n"
-"Tony Vroon\n"
-"à·à¶§ à¶à¶½à·à·à· à¶´à¶»à·à¶à·à·à¶« à·à¶³à·à· à·à·à¶º දà·à¶à·à·à·à¶¸ à·à·à¶±à·à·à·à¶±à· "
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -557,151 +532,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (à¶à·à¶»à¶º මචà·à¶à¶¯à¶»à·à·à¶±à¶º)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "à¶à¶¢à·à¶à·à¶«à·à·à·âරය"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "à·à¶§à¶à·à¶»à· à¶à·à¶±à· à·à·à·à¶â à¶à¶¢à·à¶à·à¶«à·à·à·âරය"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "à¶
à·à¶à¶½ à¶à¶¢à·à¶à·à¶«à·à·à·âරය"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "à¶à·à·à·à·à¶à· à¶±à·à¶â"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "à¶´à·à·
à·à·à·à¶ºà·à¶¸ à¶à¶»à¶¸à·à¶· à¶à·à¶»à·à¶¸â"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à· à¶
යà·à¶à¶¸à¶ºà¶à· à¶à·âà¶»à·à¶ºà·à¶à·à¶¸à¶ à·à¶±à·à·à¶§ OSD à¶à·à¶ºà·à¶à·à¶¸à¶ à¶à·à¶»à·à¶¸â"
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "මà·à¶à·à¶à·à· à·à·à¶±à·à·à¶à·à¶»à·à¶¸"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"à¶°à·à·à¶±à¶º à¶
à¶à¶»à¶à·à¶»â, à¶à·à¶ මà·à¶à·à¶à·à· à·à·à¶±à·à· à·à·à·à¶¯ à¶à·à¶±à· නම à¶à¶ºà¶¸ නම෠OSD à¶à·âà¶»à·à¶ºà·à¶à·à¶¸à¶ à¶à·à¶»à·à¶¸â. à¶
à¶±à·à¶à¶»à·à¶¢à·à¶½ "
-"à¶à¶½à¶±à¶ºà¶±à·à·à· ද෠මà·à¶à·à¶à·à· à·à·à¶±à·à· à·à·à¶¸à· à¶´à·à¶±à·à·à·à¶¸à¶§ මà·à¶º à¶à¶à· à¶´à·âරයà·à¶¢à¶±à·à¶à· à·à·."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "à·à·à¶»à·à¶¸à¶º à¶à·âà¶»à·à¶ºà·à¶à·à¶¸à¶à¶ºà·"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "à¶´à·à·
à·à·à·à¶ºà·à¶¸à· à·à·à¶»à·à¶¸à¶ºà·à¶¯à· OSD à¶à·âà¶»à·à¶ºà·à¶à·à¶¸à¶ à¶à·à¶»à·à¶¸â"
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "à·à·à¶»à·à¶¸à¶º à¶à·âà¶»à·à¶ºà·à·à·à¶»à·à·à¶à¶ºà·"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "à¶´à·à·
à·à·à·à¶ºà·à¶¸à· à·à·à¶»à·à¶¸à¶º à¶
à·à·à·à¶±à¶ºà·à¶¯à· OSD à¶à·âà¶»à·à¶ºà·à¶à·à¶¸à¶ à¶à·à¶»à·à¶¸â"
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "à·à·à¶®à·à¶´à¶±à¶º"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "à·à·à¶´à·à¶à·à· X à¶
à¶±à·à¶½à¶¸à·à¶¶à¶º:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "à·à·à¶´à·à¶à·à· Y à¶
à¶±à·à¶½à¶¸à·à¶¶à¶º:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "à¶à¶´à¶»à·à¶¸ OSD à¶´à·
à¶½:â"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "à¶¶à·à· මà·à¶±à·à¶§à¶» à·à·à¶à¶½à·à¶´â"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "OSD දරà·à·à¶±à¶ºà¶§â à¶·à·à·à·à¶à· à¶à¶»à¶±à·à¶±â:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "à·à·à¶ºà¶½à·à¶¸ මà·à¶±à·à¶§à¶»â"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "මà·à¶±à·à¶§à¶»âයâ %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "à¶à·à¶½ à¶±à·à¶ºà¶¸à¶º (මà·à¶½à· à¶à¶´à·à¶´à¶»â)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "දරà·à·à¶±à¶ºâ:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "à¶à·âරමà·à¶¯à·à¶¯à·à¶´à¶±à¶º:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "à¶à·âරමà·à·à¶¯à·à¶´à¶±à¶º:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "à¶
à¶à·à¶»à· à·à¶»à·à¶à¶ºâ"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "à¶
à¶à·à¶»à· à·à¶»à·à¶à¶º â%i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "à·à·à·à¶±à·à¶½à·à¶½â"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "à·à·à¶¯à·à·à·à¶¸à· à¶
à¶±à·à¶¯à¶¸"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "à¶´à·à¶§â"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "à¶´à·à¶§â %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "à¶à·âà¶»à·à¶ºà·à¶»à¶¸à·à¶·à¶à¶º à·à¶à·âà¶»à·à¶º à¶à·à¶»à·à¶¸"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "à·à·à¶¯à·à¶°à·à¶ºâ"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "à·à¶à¶ºà·à¶à·à¶ à¶à·
මනà·à¶à·à¶»à¶à¶º à·à¶³à·à¶±à· à¶à¶±à·à¶±à· ලදà·"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -711,112 +681,112 @@ msgstr ""
"දà·à¶±à¶§à¶¸à¶à· à¶à¶à¶à· à¶°à·à·à¶±à¶º à·à·à¶¸à·à¶±à· à¶±à·à¶´à·à¶à· නම෠à¶à¶»à·à¶«à·à¶à¶» à·à¶à¶ºà·à¶à·à¶ à¶à·
මනà·à¶à·à¶»à¶à¶ºà¶à· à·à¶à·âà¶»à·à¶º à¶à¶»à¶±à·à¶±â. à¶à·à· à¶±à·à¶à·à¶±à¶¸à· "
"OSD à¶±à·à·à· à¶½à·à· à¶à·âà¶»à·à¶ºà· à¶±à·à¶à¶»à¶ºà·"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "à·à·âයà·à¶¢ à·à·à¶±à·à·à·à¶¯ à¶´à·à¶±à·à¶¸ à·à¶³à·à· à·à¶à¶ºà·à¶à·à¶ à¶à·
මනà·à¶à·à¶»à¶à¶º à¶
à·à·à·âය à¶±à·à¶â"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "à·à·à¶±à·à·à·à¶¯ à¶´à·à¶±à·à¶¸"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "à·à·âයà·à¶¢ à·à·à¶±à·à·à·à¶¯ à¶´à·à¶±à·à¶¸â"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "à·à¶à·âය à·à·à¶±à·à·à·à¶¯ à¶´à·à¶±à·à¶¸â (X à·à¶à¶ºà·à¶à·à¶ Ext. à¶
à·à·à·âයයයà·)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "à·à¶à¶ºà·à¶à·à¶ දà·à¶à·à·â à¶´à·âà¶»à·à·à·à¶±à¶º à·à· à¶±à·à¶¸à·à¶â"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "à·à¶à¶ºà·à¶à·à¶ දà·à¶à·à·â à¶±à·à¶¸à·à¶â"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - à·à·à¶±à·âයà·à·à¶ºâ"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "à¶´à·à·à·à¶§à·à¶¸â"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "à·à¶¢à·à·à¶±à¶ºâ"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "à¶´à·à·
â"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "à¶
à¶½à¶à¶à¶»à¶«à¶º"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "à¶à·âà¶»à·à¶ºà·à¶»à¶¸à·à¶·à¶à¶º"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "à·à·à·à·à¶°"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à· "
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "à¶à¶©à·à·à·à· à¶°à·à·à¶± à¶½à·à·à·à¶à· (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>à·à¶»à·à¶«</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "à¶±à·à¶´à·à·à·à¶¯à·à¶½à· à·à·à·à¶º පථය"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "à¶à·âà¶»à·à¶¸à·à¶± à¶°à·à·à·à¶±à·à¶ à·à¶à¶ à·à¶½à¶± à·à¶½ à·à·à¶§ දà·à·à·à¶à¶»à·à¶«à·à¶ à·à·à¶ (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "à¶´à·à¶» à·à¶à·à¶± ලද:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "à·à¶à¶à·âර෠මටà·à¶§à¶¸:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "à·à¶à¶à·âයà·à¶à¶º à¶à¶´à¶±à·à¶±:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "à¶´à·à¶» à·à¶à·à¶± ලද:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "à¶à·âà¶»à·à¶¸à·à¶± à¶°à·à·à·à¶±à·à¶ à·à¶à¶ à·à¶½à¶± à·à¶½ à·à·à¶§ දà·à·à·à¶à¶»à·à¶«à·à¶ à·à·à¶ (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "à·à¶»à·à¶«à·à·à¶½à· à·à·à·à·à¶½à·à·à¶à¶º"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "à·à·âà¶»à·à·âය CD à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º "
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -833,171 +803,156 @@ msgstr ""
"à¶à¶´à¶¯à·à·à· දà·à¶¸ à·à· මà¶à¶´à·à¶±à·à·à·à¶¸ à·à·à¶±à·à·à·à¶±à· මà¶à· à·à·à¶à·à¶à·à¶º Tony Vroon à·à·à¶ à¶´à·à¶¯ à¶à¶»à¶¸à·.\n"
"මà·à¶º 2007 à·à·à¶»à· Google Summer of Code à·à·âයà·à¶´à·à¶à·à¶ºà¶à·."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>à¶à¶¸à·à¶´à¶±à·à¶±à¶º</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "à·à·à¶à¶ºà·à¶±à· à¶à·à¶ºà·à¶±à·à¶±:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "à¶´à·âà¶»à¶à·à¶à·à·à·à¶´à·à¶ à¶à¶¸à·à¶´à¶±à·à¶±à¶º:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>à¶´à·à¶»à¶¯à¶à·à¶</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "à¶·à·à·à·à¶à· à¶à¶»à¶±à·à¶± CD-à¶´à·à·
"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "à¶·à·à·à·à¶à· à¶à¶»à¶±à·à¶± CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "CDDBP à·à·à¶±à·à·à¶§ HTTP à¶·à·à·à·à¶à· à¶à¶»à¶±à·à¶±â"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "à·à·à·à·à¶¯à·à¶ºà¶à¶º:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "පථය:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "à¶à·à¶§:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "à·à·âà¶»à·à·âය CD à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º "
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "cdio à¶à¶´ පදà·à¶°à¶à·à¶º à¶à¶»à¶¹à·à¶¸ à¶
à·à·à¶»à·à¶®à¶à¶º."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "à¶
à·à¶½à¶à¶à· URI %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "à¶à¶«à·à¶©à¶º %d à·à·à¶ºà·à¶à¶ à¶±à·à·à·à¶."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "à¶à¶«à·à¶© %d දà¶à·à¶ à¶à¶«à·à¶©à¶ºà¶à·."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "à·à·âà¶»à·à·âය à¶´à·âà¶»à¶à·à¶¯à·à¶±à¶º à·à·à·à·à¶ à¶à·à¶»à·à¶¸ à¶
à·à·à¶»à·à¶®à¶ à·à·à¶º."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "à·à·âà¶»à·à·âය CD à¶à·à¶ºà·à·à¶¸à· දà·à·à¶º"
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "à·à·âà¶»à·à·âය CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "CD à¶
මà·à¶´à¶±à·à¶±à¶º %s à·à·à·à·à¶ à¶à·à¶»à·à¶¸ à¶
à·à·à¶»à·à¶®à¶ à·à·à¶º."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "à·à·âà¶»à·à·âය à¶à·âà¶»à·à¶ºà· à¶à¶½ à·à·à¶à· CD à¶
මà·à¶´à¶±à·à¶±à¶º à·à·à¶ºà·à¶à¶ à¶±à·à·à·à¶."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "à·à·à·à·à¶ à¶à¶»à¶± ලද CD à¶
මà·à¶´à¶±à·à¶±à¶º à¶
à·à·à·à¶±à¶º à¶à·à¶à· à¶à·âà¶»à·à¶ºà·à¶à·à¶¸à¶ à¶à·à¶»à·à¶¸ à¶
à·à·à¶»à·à¶®à¶ à·à·à¶º."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "à¶´à·
මà·/à¶
à·à·à·à¶± à¶à¶«à·à¶© à¶
à¶à¶à¶º à·à·à¶ºà·à¶à·à¶±à·à¶¸ à¶
à·à·à¶»à·à¶®à¶ à·à·à¶º."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "à¶à¶«à·à¶© %d à·à· à¶´à·
මà·/à¶
à·à·à·à¶± LSN à¶à·à¶ºà·à·à¶¸à¶§ à¶±à·à·à·à¶."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "cddb à·à¶¸à·à¶¶à¶±à·à¶°à¶à·à· à¶à·à¶±à·à¶¸ à¶
à·à·à¶»à·à¶®à¶ à·à·à¶º."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "CDDB à·à·à·à·à¶¯à·à¶ºà¶à¶º à·à·à¶¸à·à·à¶¸à¶§ à¶
à¶´à·à·à·à·à¶à· à·à·à¶º."
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "CDDB à·à·à·à·à¶¯à·à¶ºà¶à¶º : %s à·à·à¶¸à·à·à¶¸à¶§ à¶
à¶´à·à·à·à·à¶à· à·à·à¶º."
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "cddb à¶à·à¶»à¶à·à¶»à·: %s à¶à·à¶ºà·à·à¶¸à¶§ à¶
à¶´à·à·à·à·à¶à· à·à·à¶º."
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "à¶°à·à·à¶à¶º à·à·à·à·."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "à·à·à·à¶º à¶±à·à¶¸à·à¶à· à¶à·à¶§à· à·à¶»à·à¶à¶ºà¶à·."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "à·à·âà¶»à·à·âය CD මà·à¶±à· à¶
යà·à¶à¶¸ "
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "à·à¶à¶ºà·à¶à·à¶ à¶à·à¶§à·à¶ºâ à¶°à·à·à¶±à¶º à¶à¶»à¶±à·à¶± "
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "à·à¶à¶ºà·à¶à·à¶ à¶à·à¶§à·à¶º à¶à¶à¶à· à¶à¶»à¶±à·à¶±â"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "à·à·âà¶»à·à·âය CD මà·à¶±à· à¶
යà·à¶à¶¸ "
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>à·à·à¶à·à¶½à·à¶¸</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "මධà·âය à·à¶¶à·à¶¯ මටà·à¶§à¶¸â :"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "à¶à¶à·à¶ à¶´à¶»à·à·à¶º:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"à¶à¶©à·à·à·à· à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º à·à¶³à·à· à¶à¶à·à¶ à¶´à¶»à·à· à·à¶¸à·à¶´à·à¶©à¶±à¶º\n"
-"à¶´à·âà¶»à¶à·à·à¶± à·à·à¶¸à·à¶à¶¸à· 2010-2012 à¶¢à·à¶±à· à¶½à·à¶±à·à¶©à·à¶à·à¶»à·à¶±à·"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "à¶à¶à·à¶ à¶´à¶»à·à· à·à¶¸à·à¶´à·à¶©à¶à¶º"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1013,205 +968,224 @@ msgstr ""
" William Pitcock<nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "මනà·à¶¯à·âà¶»à·à·à·à¶»:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "à¶à¶ à·à¶ à·à·à·à¶±à¶º:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "à¶´à·à¶»à¶±à·à¶¸à· à¶à·à¶ දà·à¶â:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr " <b>à¶±à·à·à¶ à·à·à¶¸à·à¶´à¶½ à¶à·à¶»à·à¶¸</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "à¶±à·à·à¶ à¶±à·à¶ºà·à¶¯à·à¶¸â à·à¶à·âà¶»à·à¶º à¶à¶»à¶±à·à¶±â"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "à¶±à·à·à¶ à¶±à·à¶ºà·à¶¯à·à¶¸à· à¶
à¶±à·à¶´à·à¶à¶ºâ:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "à·à¶»à·à¶§à·à·à·"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "SPC \tà·à¶¸à·à¶¶à¶±à·à¶°à¶à¶ºà·à¶±à· දà·à¶ à¶±à·à·à¶½à¶à· à·à¶»à·à¶±à·à¶±â"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "à¶´à·âà¶»à¶à·à¶»à·à·à¶º à·à·à¶©à· à¶à¶»à¶±à·à¶±â"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "à¶à·âà¶»à·à¶©à· à¶´à·à¶½à¶± à¶´à·à·à¶»à· à·à¶à¶à·à¶ à·à·à¶à·à¶à¶à¶ºâ"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-"à¶à·à¶ à·à¶½à¶§ à·à·à¶±à·à· à¶±à·à¶½à·à¶à· à¶à·à·à·à¶´à¶ºà¶à· à¶à·à¶¶à·à¶¸ à¶±à·à·à· à¶à¶à· à·à¶¶à·à¶¯à¶ºà¶à·à¶±à· à¶à·à¶à· à·à¶¶à·à¶¯à¶ºà¶à¶§ මà·à¶»à· à·à·à¶¸à¶§ à¶
à·à¶¸à¶à· à·à· à¶à¶. "
-"à¶±à·à¶½à·à¶à· මà·à·à·âà¶»à¶à¶º à¶·à·à·à·à¶à¶ºà·à¶±à· à¶à¶¶à¶§ à¶à·à¶ à·à¶¸à·à¶± à¶±à·à¶½à·à¶à· à¶à¶«à¶±à¶à¶§ à·à·à¶±à·à· à¶à¶½ à·à·à¶."
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-"à¶à·à¶ à·à¶½à¶§ à·à·à¶±à·à· à¶±à·à¶ºà·à¶¯à· à¶
à¶±à·à¶´à·à¶ à¶à·à¶¶à·à¶¸ à¶±à·à·à· à¶à¶à· à·à¶¶à·à¶¯à¶ºà¶à·à¶±à· à¶à·à¶à· à·à¶¶à·à¶¯à¶ºà¶à¶§ මà·à¶»à· à·à·à¶¸à¶§ à¶
à·à¶¸à¶à· à·à· à¶à¶. "
-"à¶±à·à¶½à·à¶à· මà·à·à·âà¶»à¶à¶º à¶·à·à·à·à¶à¶ºà·à¶±à· à¶à¶¶à¶§ à¶à·à¶ à¶à¶à· à¶±à·à¶ºà·à¶¯à· à¶
à¶±à·à¶´à·à¶à¶ºà¶à¶§ à·à·à¶±à·à· à¶à¶½ à·à·à¶."
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Audacious à·à¶³à·à· à·à¶± à·à¶»à·à· à¶´à·à·à·à¶¸à· à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶ºâ\n"
-"à¶´à·âà¶»à¶à·à·à¶± à¶
යà·à¶à·à¶º 2010-2012 à¶¢à·à¶±à· à¶½à·à¶±à·à¶©à·à¶à·âà¶»à·à¶±à·"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>à¶à¶à· à·à¶¶à·à¶¯à¶ºà¶à·à¶±à· à¶à·à¶à· à·à¶¶à·à¶¯à¶ºà¶à¶§ මà·à¶»à· à·à·à¶¸</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "à¶
à¶à·à¶ à·à¶¡à·à¶¯à¶±:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "à¶à¶à· à·à¶¶à·à¶¯à¶ºà¶à·à¶±à· à¶à·à¶à· à·à¶¶à·à¶¯à¶ºà¶à¶§ මà·à¶»à· à·à·à¶¸"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"à¶à·à¶ à·à¶½à¶§ à·à·à¶±à·à· à¶±à·à¶½à·à¶à· à¶à·à·à·à¶´à¶ºà¶à· à¶à·à¶¶à·à¶¸ à¶±à·à·à· à¶à¶à· à·à¶¶à·à¶¯à¶ºà¶à·à¶±à· à¶à·à¶à· à·à¶¶à·à¶¯à¶ºà¶à¶§ මà·à¶»à· à·à·à¶¸à¶§ à¶
à·à¶¸à¶à· à·à· à¶à¶. "
+"à¶±à·à¶½à·à¶à· මà·à·à·âà¶»à¶à¶º à¶·à·à·à·à¶à¶ºà·à¶±à· à¶à¶¶à¶§ à¶à·à¶ à·à¶¸à·à¶± à¶±à·à¶½à·à¶à· à¶à¶«à¶±à¶à¶§ à·à·à¶±à·à· à¶à¶½ à·à·à¶."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"à¶à·à¶ à·à¶½à¶§ à·à·à¶±à·à· à¶±à·à¶ºà·à¶¯à· à¶
à¶±à·à¶´à·à¶ à¶à·à¶¶à·à¶¸ à¶±à·à·à· à¶à¶à· à·à¶¶à·à¶¯à¶ºà¶à·à¶±à· à¶à·à¶à· à·à¶¶à·à¶¯à¶ºà¶à¶§ මà·à¶»à· à·à·à¶¸à¶§ à¶
à·à¶¸à¶à· à·à· à¶à¶. "
+"à¶±à·à¶½à·à¶à· මà·à·à·âà¶»à¶à¶º à¶·à·à·à·à¶à¶ºà·à¶±à· à¶à¶¶à¶§ à¶à·à¶ à¶à¶à· à¶±à·à¶ºà·à¶¯à· à¶
à¶±à·à¶´à·à¶à¶ºà¶à¶§ à·à·à¶±à·à· à¶à¶½ à·à·à¶."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>à¶´à·
à·à¶à·à·</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "à¶à·à·à·âà¶»à¶à·à·:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "à¶´à·
à·à¶à·à·"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "à·à¶½à¶à·à¶«à· à¶´à¶à· à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º "
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "මà¶à¶±à·à¶± "
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "à¶
à·à¶½à¶à¶à· à¶à·à¶»à·à¶¸â"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>à¶´à·âà¶»à¶à·à¶»à·à·</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "à¶´à·âරමà·à¶¯à¶º:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "මà·à¶ à·à¶à·à·à¶¯à·âයà¶à·à·"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "à¶´à·âà¶»à¶à·à¶´à·à·à¶«à¶º:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "à·à¶¶à·à¶¯ මටà·à¶§à¶¸â :"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"à¶´à·âà¶»à¶à·à¶°à·à·à¶±à· à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶ºâ\n"
-"à¶¢à·à·à·à¶±à· à¶½à·à·à·à¶±à· à·à·à·à·à¶±à·, 1999â\n"
-"â\n"
-"à·à·à·à·à·
à¶´à·âà¶»à¶à·à¶°à·à·à¶±à· à¶à·à¶»à·à¶½à· à·à·à¶±à· à·à·à¶ à·à¶ºà·à¶à· à·à·à·à·à¶±à·, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "à¶´à·âà¶»à¶à·à¶»à·à·"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º "
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1227,55 +1201,55 @@ msgstr ""
"à·à·à¶½à·à¶ºà¶¸à· à¶´à·à¶§à·à¶à·à¶à· <nenolod at nenolod.net>â\n"
"මà·à¶§à· à·à·à¶¸à¶½à·à¶ºà·à¶±à·à¶±à· <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º "
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "à¶à·à¶±à· රචචපà·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º "
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "à¶´à·âà¶»à¶à·à¶¯à·à¶± à¶à·à¶±à· à¶à¶à·à¶à·à¶º:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "à·à·à¶±à·âයà·à· à¶à¶»à¶±à·à¶±â"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "මà·à¶½à·à¶ à¶±à·à¶¸à·à·à¶½à·à¶ºà¶§ à·à·à¶»à¶à·à¶±à·à¶±â"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "à¶
à¶·à·à¶»à·à¶ à· à¶±à·à¶¸à·à·à¶½à·à¶ºà¶§à¶à¶§â à·à·à¶»à¶à·à¶±à·à¶±â"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "à¶´à·âà¶»à¶à·à¶¯à·à¶± à¶à·à¶±à· à·à·à¶½à·à¶©à¶»à¶ºâ:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "à·à·à¶½à·à¶©à¶»à¶ºà¶à·â à¶à·à¶»à¶±à·à¶±â"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "à·à·à¶à·à¶±à· à¶à·à¶±à· à¶±à·à¶¸à¶ºà¶à· ලබà·à¶à¶±à·à¶±â:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "මà·à¶½à·à¶ à¶à·à¶±à· à·à¶¸à·à¶¶à¶±à·à¶°à¶à¶º"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "මà·à¶½à·à¶ à¶à·à¶±à· නමâ"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "à¶à·à¶±à· නම෠දà·à¶à·à· à¶à·à¶à· à¶±à·à¶à¶»à¶±à·à¶±â"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "à¶´à¶® à¶
à¶à¶à¶º à¶à·à¶±à· නමට à¶à¶à¶à· à¶à¶»à¶±à·à¶±â"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1303,165 +1277,169 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "à¶à·à¶±à· රචචපà·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º "
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "à·à·à·à¶ºà¶à¶à·âà¶»à·à¶ºâ"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "à¶à¶à¶à· à·à· à¶à·âà¶»à·à¶¸à·à¶«â"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "à¶âà·âà¶»âà·âà¶»à·à¶¸à·à¶« "
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "à¶à¶±à· "
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 à·à·à¶±à·âයà·à·à¶º"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "à¶à¶½à·à¶à·à¶»à·à¶à¶¸ à¶à¶à·à¶à·à·à¶º:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "à¶´à·âà¶»à¶à·à¶¯à·à¶± à¶±à·à¶ºà·à¶¯à· à¶
à¶±à·à¶´à·à¶à¶ºâ:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(à·à¶»à·à¶§à·à·à·)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "à¶¶à·à¶§à· à¶»à·à¶§à¶º / à·à¶¸à·à¶´à·à¶©à¶ à¶
à¶±à·à¶´à·à¶à¶ºâ:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "à¶¶à·à¶§à· à¶»à·à¶§à¶º (à¶à¶´à·à¶´à¶»à¶ºà¶§ à¶à·.à¶¶â.)"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "à·à¶¸à·à¶´à·à¶©à¶ à¶
à¶±à·à¶´à·à¶à¶ºâ:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "à·à·âà¶»à·à·âයâ à¶´à·âà¶»à¶à·à¶»à¶ºâ:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "à¶´à·âà¶»à¶à·à¶»à·à¶«:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "à·à·à¶°à·à¶¸à¶à· ISO à¶
à¶±à·à¶à·à¶½à·à·à¶¸à¶à¶§ à¶¶à¶½ à¶à¶»à¶±à·à¶±â"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "දà·à· à¶à¶»à¶à·âà·à·à·â"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "à¶´à·âà¶»à·à·à·à¶à¶à·à·"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "VBR/ABR à·à¶à·âà¶»à·à¶º à¶à¶»à¶±à·à¶±â"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "à·à¶»à·à¶à¶ºâ:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR à·à·à¶à¶½à·à¶´â:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "à¶
à·à¶¸ à¶¶à·à¶§à· à¶»à·à¶§à¶º (à¶à¶´à·à¶´à¶»à¶ºà¶§ à¶à·.à¶¶â.)"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "à¶à¶´à¶»à·à¶¸â à¶¶à·à¶§à· à¶»à·à¶§à¶º (à¶à¶´à·à¶´à¶»à¶ºà¶§ à¶à·.à¶¶â.)"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "à¶
à·à¶¸ à¶¶à·à¶§à· à¶»à·à¶§à¶º à·à¶³à·à· à¶à¶¯à·à¶±à· à¶¶à¶½à¶à¶»à¶±à·à¶±â"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR à·à·à¶à¶½à·à¶´â:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "à·à·à¶¸à·à¶±à·âය à¶¶à·à¶§à· à¶»à·à¶§à¶º (à¶à¶à·à¶´à¶»à¶ºà¶§ à¶à·.à¶¶â.)"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR à¶´à·âà¶»à·à·à·à¶à¶à· මටà·à¶§à¶¸â:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Xing VBR à·à·à¶»à·âà·à¶à¶ºâ à¶±à·à¶½à·à¶ºà¶±à·à¶±â"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "à¶»à·à¶¸à· à¶´à¶»à·à¶¸à·à¶à·à¶º :"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "à¶´à·âà¶»à¶à·à·à¶± à¶
යà·à¶à·à¶º à·à·à·à¶ à¶½à·à· à·à¶½à¶à·à¶«à· à¶à¶»à¶±à·à¶±"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "මà·à¶½à· à¶´à·à¶§à¶´à¶à¶à· à¶½à·à· à·à¶½à¶à·à¶«à· à¶à¶»à¶±à·à¶±â"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "2 à·à¶± à·à¶à·à·à¶à¶»à¶«à¶ºà· à·à¶¸à·à¶¶à¶±à·à¶°à¶à¶ºà¶§â à¶¶à¶½à·à¶±à· à¶à¶à·à¶½à¶à· à¶à·à¶»à·à¶¸â"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "1 à·à¶± à·à¶à·à·à¶à¶»à¶«à¶ºà· à·à¶¸à·à¶¶à¶±à·à¶°à¶à¶º පමණà¶à· à¶à¶à¶à· à¶à¶»à¶±à·à¶±â"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "2 à·à¶± à·à¶à·à·à¶à¶»à¶«à¶ºà· à·à¶¸à·à¶¶à¶±à·à¶°à¶à¶º පමණà¶à· à¶à¶à¶à· à¶à¶»à¶±à·à¶±â"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "à·à¶¸à·à¶¶à¶±à·à¶°à¶"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis à·à·à¶à·à¶à¶à¶ºà· à·à·à¶±à·âයà·à·à¶º"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "à¶´à·âà¶»à·à·à·à¶®à¶à· මටà·à¶§à¶¸â (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC à·à·à¶à·à¶à¶à¶º"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "à·à·à¶±à· à·à· à¶±à·à¶¸à·à¶à· "
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1473,11 +1451,7 @@ msgstr ""
"â\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC à·à·à¶à·à¶à¶à¶º"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1485,14 +1459,22 @@ msgstr ""
"Audacious à·à¶³à·à· à·à¶±â GIO à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶ºâ\n"
"à¶´à·âà¶»à¶à·à·à¶± à¶
යà·à¶à·à¶º 2009-2012 à¶¢à·à¶±à· à¶½à·à¶±à·à¶©à·à¶à·âà¶»à·à¶±à·"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º "
-#: src/gl-spectrum/gl-spectrum.c:400
-msgid ""
-"OpenGL Spectrum Analyzer for Audacious\n"
-"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
"\n"
"Based on the XMMS plugin:\n"
"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
@@ -1501,534 +1483,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL à·à¶»à·à¶«à·à·à¶½à· à·à·à·à·à¶½à·à·à¶à¶º"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
-"à¶à·à¶±à·à¶¸à· à¶à·à¶§à· යà·à¶¯à·à¶¸à· à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶ºâ\n"
-"à¶à·à¶±à·à¶¸à· à¶à·à¶§à· යà·à¶¯à·à¶¸à· මà¶à·à¶±à· à¶à¶¶à¶§ à¶°à·à·à¶à¶º à¶´à·à¶½à¶±à¶ºà¶§ à¶à¶© à·à¶½à·à¶ºà·.â\n"
-"â\n"
-"à¶´à·âà¶»à¶à·à·à¶± à¶
යà·à¶à·à¶ºâ (C) 2007-2008 à·à·à·à¶ à· à·à·à¶½à·à·à·à¶ºà·à¶à· <contact at saschahlusiak.de>"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Gnome à¶à·à¶§à·à¶¸à¶ "
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "à¶à¶à·à¶½à¶à· à¶à·à¶»à·à¶¸à· à¶
à¶à¶à¶ºâ"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "මà·à¶à·à¶à·à·"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "à·à·à¶½à·à¶´à·à¶ºà· "
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "à·à¶»à·à·à¶º "
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "à¶à¶½à·à¶¶à¶¸à¶º "
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "à¶à¶«à·à¶©à¶º "
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "à¶´à·âරභà·à¶¯à¶º"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "à¶´à·à¶½à·à¶ºà·à·à· à¶´à·à·à·à¶§à¶± à·à·à¶®à·à¶±à¶ºâ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "දà·à¶"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "à¶à·à¶±à· පථය"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "à¶à·à¶±à· නමâ"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "à¶
à¶·à·à¶»à·à¶ ෠මà·à¶à·à¶à·à·â"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "à¶¶à·à¶§à· à¶»à·à¶§à¶ºâ"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "à·à·à·à·à¶¸à· මà·à·à¶½à¶¸ "
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "à·à¶¸à¶§ à¶à¶³à¶±à·à¶±â"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "දà¶à·à¶«à¶§ âà¶à¶³à¶±à·à¶±â"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "à¶à·à·
à¶§â à¶à¶³à¶±à·à¶±â"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr " à¶´à·à·
à¶§ à¶à¶³à¶±à·à¶±â"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "à¶à¶³à·à¶¸â à¶
à·à¶½à¶à¶à· à¶à¶»à¶±à·à¶±â"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "à¶
à¶à·âà¶»à·à¶º à¶à¶»à¶±à·à¶±â"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "à·à·à·à·à¶¸à· මà·à·à¶½à¶¸ "
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_à¶à·à¶±à· à·à·à·à·à¶ à¶à¶»à¶±à·à¶± ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "_URL à·à·à·à·à¶ à¶à¶»à¶±à·à¶± ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_à¶à·à¶±à· à¶à¶à¶à· à¶à¶»à¶±à·à¶± ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "U_RL à¶à¶à¶à· à¶à¶»à¶±à·à¶± ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "à¶´à·_à·
à·à¶¶à¶³â ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_à¶´à·à¶§à·à·à¶±à·à¶±â"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_à¶°à·à·à¶±à¶º à¶à¶»à¶±à·à¶±â"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "à·à·à¶»à·à¶¸_යâ"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_à¶±à·à¶à·à·à¶±à·à¶±â"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "à¶_à¶½à·à¶±à·"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_à¶à·
à¶â"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_à¶±à·à·à¶â à¶°à·à·à¶±à¶ºâ"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "à¶_à·
à·à¶¸à· à¶à·à¶»à·à¶¸â"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "à¶°à·à·à¶± à¶½à·à·à·à¶à· à¶±à·_à¶ "
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "මà·à¶¸ à¶à·à¶à¶ºà·à¶±à· à¶´à·à· à¶±à·à¶à·à¶à¶±à·à¶± "
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "à¶à·à¶_à¶à·à¶»à¶à·à¶»à· ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "මà¶à·à·à¶» à·à·à¶½à·à·à¶§_à¶´à·à·à·à·à·à¶±à·à¶± ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "_මà¶à·à·à¶» à¶à·à¶à¶ºà¶§ à¶´à·à·à·à·à·à¶±à·à¶± ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "à¶±à·à·à¶ à·à·à¶¯à·à·à¶± à·à·à¶®à·à¶±_A à¶´à·à·à·à¶§à·à·à¶±à·à¶± "
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "à¶±à·à·à¶ à·à·à¶¯à·à·à¶± à·à·à¶®à·à¶±_B à¶´à·à·à·à¶§à·à·à¶±à·à¶± "
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "à¶±à·à·à¶ à·à·à¶¯à·à·à¶± à·à·à¶®à·à¶± à·à·à·à·à¶à¶»à¶±à·à¶± "
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "මà·à¶à·à¶à·_à·à·à¶±à·"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "à¶à·à¶±à· à¶±à·à¶¸à¶ºà·à¶±à· "
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "à¶à·à¶±à· පථයà·à¶±à· "
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "à¶à¶«à·à¶©_à¶
à¶à¶à¶ºà·à¶±à· "
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "à·à·à¶½à·à¶´à·à¶ºà·_à¶à·à¶±à·"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "à¶à¶½à·à¶¶à¶¸à¶ºà·à¶±à· "
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "à¶´à·à¶§ à¶à¶½ _දà·à¶±à¶ºà·à¶±à·"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "දà·à¶»à·à¶±à· "
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "à¶à·à¶±à·_පථයà·à¶±à·"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "à¶
à¶·à·à¶»à·à¶ à·_මà·à¶à·à¶à·à·à·à¶±à· "
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "à¶
à¶_à·à·à¶§ මà·à¶½à¶§â"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_à·à·à¶¸à·à¶·à·à·à· à¶´à·à·
à·à·à·à¶½â"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à· à¶°à·à·à¶±à¶º à¶à¶»à¶±à·à¶±â"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_à¶±à·à·à·à¶¸à· à¶à¶»à¶±à·à¶±â"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_à¶
à¶±à·à¶´à·à·
à·à·à·à¶½à¶§ à·à¶à·à¶±à·à¶±â"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "à¶
à¶±à·à¶´à·à¶§à¶´à¶à·_à¶à·à¶à· à¶à·à¶»à·à¶¸ "
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "à¶
à¶±à·à¶´à¶ºà·à¶¢à·âය_à¶à·à¶±à· à¶à·à¶à· à¶à¶»à¶±à·à¶±"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_à¶±à·â"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "Ren_ame ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_à¶à¶ºà·à¶ à¶à¶»à¶±à·à¶±â ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_à¶±à·à¶»à·à¶ºà·à¶ à¶à¶»à¶±à·à¶± ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·_à¶à·
මනà·à¶à·à¶»à¶à¶ºâ ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_à¶´à·à·
à¶à·à·à·à¶¸ à¶à·
මනà·à¶à¶»à¶«à¶º ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "à·à¶¶à·à¶¯ මටà·à¶§à¶¸â _à·à·à¶©à· à¶à¶»à¶±à·à¶±"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "à·à¶¶à·à¶¯ මටà·à¶§à¶¸â _à¶
à¶©à· à¶à¶»à¶±à·à¶±"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_à¶à¶à·âයà·à·à¶½à¶ºà·à·à¶»à¶ºâ"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "_මà·à¶±à· à¶à·à¶»à·à· à¶´à·à¶±à·à·à¶±à·à¶±â"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "à¶à·à¶»à¶à·à¶»à· à¶à·_à¶»à·à· à¶´à·à¶±à·à·à¶±à·à¶±â"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "à¶à·à¶»à¶à·à¶»à· à¶à·à¶»à·à·à· දà·à·à·à¶§à· à¶à¶½à·à¶´à¶±à¶º à¶´à·à¶±à·à·à¶±à·à¶± "
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "à¶à¶à·à· _à¶à·à¶»à·à· à¶´à·à¶±à·à·à¶±à·à¶±â"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "à¶à¶à·à¶»à·à·à· à¶à¶à· à¶à·à¶½à¶º à¶´à·à¶±à·à·à¶±à·à¶±."
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_à¶à·à¶±à·à·â"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_à¶´à·à·
à·à·à·à¶ºà·à¶¸â"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "à¶°à·_à·à¶± à¶½à·à¶ºà·à·à·à¶à·à·â"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_à·à·à·à·"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_à¶´à·âà¶»à¶à·à¶¯à·à¶±â"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_දà·à·à¶±â"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_à¶´à·à·
à¶à·à·à·à¶±à·à¶±â/à¶´à·à·
à¶à·à·à·à¶¸ à¶
à·à¶½à¶à¶à· à¶à¶»à¶±à·à¶±â"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "à¶à¶´à¶±à·_à¶±â"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_à¶´à·à¶§à¶´à¶à· à¶à¶»à¶±à·à¶±â"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_à¶
à¶½à·à¶±à·à¶±â"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "à·à·à¶ºà¶½à·à¶½_à¶à·à¶»à¶±à·à¶±"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_à¶±à·à·à¶ නම෠à¶à·à¶»à·à¶¸â ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>à·à·à·à·à¶°</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK à¶
à¶à·à¶»à· මà·à·à·à¶«à¶"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "à¶
à¶±à·à¶à¶»à·à¶ යනය..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "à¶à¶©à·à·à·à· "
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr " à¶à¶±à· "
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "à¶à·âà¶»à·à¶¸à·à¶± "
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d à¶±à·à¶½à·à¶à·à· "
msgstr[1] "%d à¶±à·à¶½à·à¶à· "
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d à¶à¶à·à¶´à¶»à¶ºà¶§ à¶à·à¶½à· බයà·à¶§à· "
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "à¶à¶±à· à¶´à·âà¶»à¶à·à¶»à¶º."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "à¶°à·à·à¶± à¶½à·à·à·à¶à· à¶´à·âà¶»à¶à·à¶»à¶º."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "à¶à·à¶à¶ºà¶à·à¶±à· à¶´à·à· à¶±à·à·à¶à·à¶¸."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "à¶´à·à¶» à¶à¶«à·à¶©à¶º"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "à¶°à·à·à¶±à¶º à¶à¶»à¶±à·à¶± "
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "à¶±à·à·à¶à·à¶¸/à¶±à·à·à¶ à¶à¶»à¶¹à·à¶¸ "
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "à¶±à·à·à¶à·à¶¸ "
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "à¶´à·à· à¶à¶«à·à¶©à¶º "
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "à¶à¶à·.5 à¶°à·à·à¶±à¶º à¶à¶»à¶±à·à¶±"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "à¶à¶à·.5 à¶´à·à· à¶°à·à·à¶±à¶º à¶à¶»à¶±à·à¶±"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "à¶±à·à·à¶¬ à¶à¶»à¶±à·à¶± "
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "à·à¶¶à·à¶¯ මටà·à¶§à¶¸â à·à·à¶©à· à¶à¶»à¶±à·à¶±"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "à·à¶¶à·à¶¯ මටà·à¶§à¶¸â à¶
à¶©à· à¶à¶»à¶±à·à¶±"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "මà¶à·à·à¶» à¶à·à¶±à·à·à¶§ à¶´à·à·à·à·à·à¶±à·à¶± "
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "à¶°à·à·à¶ à¶à·à·à·
à·(à·) à¶´à·à¶»à·à¶à· à¶à¶»à¶±à·à¶±"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "à¶à·à¶»à¶º මචà·à¶à¶¯à¶»à·à·à¶±à¶º à¶à¶» à¶´à·à¶±à·à·à¶±à·à¶± "
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "à¶±à·à·à¶ à¶à·à¶»à·à¶¸ à¶§à·à¶à¶½à· à¶à¶»à¶±à·à¶±"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "à¶à·
à·à¶¸à· à¶à·à¶»à·à¶¸ à¶§à·à¶à¶½à· à¶à¶»à¶±à·à¶±"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "à¶´à·à¶à·à¶± à¶à·à¶à¶ºà·à¶±à· à¶´à·à· à¶±à·à·à¶à·à¶¸ à¶§à·à¶à¶½à· à¶à¶»à¶±à·à¶± "
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "à¶°à·à·à¶ à¶à·à·à·
à·(à·) à¶´à·à¶±à·à·à¶±à·à¶±"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(à¶à·à·à·à·à¶à· à¶±à·à¶)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2038,15 +2093,11 @@ msgstr ""
"à¶´à·âà¶»à·à¶®à¶¸à·à¶ මà·à·à·à¶ à¶¶à·à¶à·à¶à¶¸à· à¶±à·à·à¶à¶»à¶«à¶ºà¶à·à¶±à· à¶à·à¶»à· à¶¶à·à¶³à·à¶¸à¶§ à¶±à·à¶»à·à¶¯à·à· à¶±à·à¶à·à¶»à·.\n"
"à¶à¶¶à¶§ à¶à¶¯à·à¶»à·à¶ºà¶§à¶ºà·à¶¸âà¶§ à¶
à·à·à·âයද ?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "à¶¶à·à¶³à·à¶± මà·à·à·à¶ à¶¶à·à¶à·à¶à¶¸à· "
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "à¶à·à¶½à·à¶º à·à·à·à·à· à¶¶à·à¶à·à¶à¶¸à· à¶´à·à¶±à· මà·à¶¯à·à¶à¶à¶ à·à·à¶±à·âයà·à·à¶º "
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2054,23 +2105,27 @@ msgstr ""
"à¶´à·à·
à¶à·à·à·à¶à·âරය à¶à¶à·à¶½à¶ යà¶à·à¶»à· à¶à¶à¶à·à· à¶à¶¶à¶±à·à¶±.\n"
"à¶à¶¶à¶§ මà·à·à·à¶ à¶¶à·à¶à·à¶à¶¸à¶¯ à¶¶à·à¶³à·à¶º à·à·à¶."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "à·à·à·à·à· à¶¶à·à¶à·à¶à¶¸à·:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>à¶à·âà¶»à·à¶ºà·à·:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>යà¶à·à¶»à· à¶¶à·à¶³à·à¶¸:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "à¶à·à¶½à·à¶º à·à·à·à·à· à¶¶à·à¶à·à¶à¶¸à·:"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2096,60 +2151,51 @@ msgstr ""
"à¶¢à·à¶±à¶à¶±à· à¶. à¶©à·à·à·à·à· <davis at jdhouse.org>,\n"
"à¶¢à·à¶»à¶¸à· à¶§à·à¶±à· <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "à¶à·à¶½à·à¶º à·à·à·à·à· à¶¶à·à¶à·à¶à¶¸à·:"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK à¶´à·âà¶»à¶à·à¶¯à·à¶±à¶º"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"à¶à·âà¶»à·à·à· මà·à¶»à·à¶à¶±à· à¶à· xmms-jack මචපදනම෠à·à· à¶à¶â:â\n"
-"http://xmms-jack.sourceforge.net/â\n"
-"â\n"
-"Audacious à·à·à¶ à¶à¶à·à¶½à¶à· à¶à·
à· à¶¢à·à¶ºà·à¶à·à¶¸à· à¶½à·à·à·à¶§à· à·à·à·à·à¶±à·"
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK à¶´à·âà¶»à¶à·à¶¯à·à¶±à¶º"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s à·à·à¶§à·à·à¶¸ "
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA à·à¶à·à¶à·à¶»à¶ à·à·à¶§à·à·à¶¸ "
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "මà·à¶©à·à¶ºà·à¶½ පථය:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2159,25 +2205,25 @@ msgstr ""
"මà·à¶¸ à¶´à¶® à·à·à¶ºà¶±à·à¶±à· LADSPA_PATH à¶à¶à¶§ à¶
මà¶à¶»à·à¶º.\n"
"න෠පථ à¶à¶à·à¶½à¶à· à¶à·à¶»à·à¶¸à·à¶±à· à¶´à·à·à·, න෠පà·à¶±à· මà·à¶¯à·à¶à·à¶à¶ à·à¶¯à·à· Enter යà¶à·à¶» à¶à¶¶à¶±à·à¶±.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "à¶à¶´à¶ºà·à¶¢à·âය à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "à·à¶à·âà¶»à·à¶º "
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "à·à¶à·âà¶»à·à¶º à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "à·à·à¶§à·à·à¶¸à· "
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2185,47 +2231,15 @@ msgstr ""
"Audacious à·à¶³à·à· à·à¶± LADSPA à·à¶à·à¶à·à¶»à¶à¶ºââ\n"
"à¶´à·âà¶»à¶à·à·à¶± à¶
යà·à¶à·à¶ºâ 2011 à¶¢à·à¶±à· à¶½à·à¶±à·à¶©à·à¶à·âà¶»à·à¶±à·"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA à·à¶à·à¶à·à¶»à¶ "
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: LIRC à·à¶³à·à· à·à·à¶ºà·à·à¶º à¶±à·à·à·à¶\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: LIRC à·à·à¶±à·âයà·à· à¶à·à¶±à·à· à¶à·à¶ºà·à·à¶º à¶±à·à·à·à¶ \n"
-"%s: à¶à¶»à·à¶«à·à¶à¶» LIRC à·à¶½à¶§ à¶
දà·à¶½ à¶½à·à¶à¶± à¶à·à¶ºà·à¶±à·à¶± \n"
-"%s: à¶à·âරමà·à¶±à·à¶à·à¶½ à·à·à¶±à·âයà·à· à¶à·à¶±à·à·à¶à· à·à·à¶¯à¶±à·à¶±à· à¶à·à·à·à¶¯ \n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr " %s: à¶´à·âà¶»à¶à·à·à¶¸à·à¶¶à¶±à·à¶° à·à·à¶¸à¶§ à¶à¶à·à·à·à· à¶à·à¶»à·à¶¸...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: à¶±à·à¶¯à¶±à·à¶±à· à·à·à¶°à·à¶±à¶ºà¶à· \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: LIRC à·à¶½à·à¶±à· à¶à·âà¶»à·à¶ºà·à·à·à¶»à·à·à¶ à¶à¶» à¶à¶ \n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: à·à·à¶¸ à¶à¶à·à¶´à¶» %d à·à¶»à¶à· à¶±à·à·à¶ à·à¶¸à·à¶¶à¶±à·à¶° à·à·à¶¸à¶§ à¶à¶à·à·à·à· à¶à¶»à¶ºà·...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2253,73 +2267,81 @@ msgstr ""
"â\n"
"LIRC à¶´à·à·
à·à¶¶à¶³ à·à·à¶©à· à·à·à·à·à¶à¶» à·à¶³à·à·,http://lirc.org බලනà·à¶±â."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>à·à¶¶à·à¶³à·à¶¸</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "à·à·à·à·à¶¯à·à¶ºà¶à¶ºà¶§ à¶´à·âà¶»à¶à·à·à¶¸à·à¶¶à¶±à·à¶° à¶à¶»à¶±à·à¶± "
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "à¶´à·âà¶»à¶à·à·à¶¸à·à¶¶à¶±à·à¶° à·à·à¶¸à¶§ à¶´à·à¶» මදà¶à· à·à·à¶§à·à¶±à·à¶±:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "à¶½à·à¶»à·à¶à· à·à·à¶à· à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "පද රචන෠නà·à¶¸à·à¶â"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "දà·à·à¶º "
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "à¶à·à¶³à·à·à¶à·à¶± ය෠නà·à·à·à¶â %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "දà·à·à¶º "
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "parse à¶à·
à¶±à·à·à·à¶â %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "පද රචන෠à·à·à¶ºà¶¸à·à¶±à· à¶´à·à¶à· ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "à¶à·à¶à¶ºà· metadata à¶±à·à¶¸à·à¶â"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "lyrics.wikia.com à·à·à¶â à·à¶¸à·à¶¶à¶±à·à¶¯ à·à·à¶¸à·à¶±à· à¶´à·à¶à· ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "à¶½à·à¶»à·à¶à· à·à·à¶à· à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à·â"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "à¶§à·à¶à·à¶§à· ජනà¶à¶º"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "à¶§à·à¶à·à¶§à· ජනà¶à¶º: %d මà·à¶±à·à¶à·à¶à·à·à¶§ බයà·à¶§à·à·à· "
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "à¶§à·à¶à·à¶§à· ජනà¶à¶º: %d මà·à¶±à·à¶à·à¶à·à·à¶§ බයà·à¶§à·à·à· %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2333,11 +2355,11 @@ msgstr ""
"e.g. tact://77 to play 77 beats per minuteâ\n"
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "à¶§à·à¶à·à¶§à· ජනà¶à¶º"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "à¶±à·à¶½à·à¶à· මà·à·à·âà¶»à¶à¶º"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2345,152 +2367,184 @@ msgstr ""
"Audacious à·à¶³à·à· à¶±à·à¶½à·à¶à· මà·à·à·âරනâ à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶ºà¶à·\n"
"à¶´à·âà¶»à¶à·à·à¶± à¶
යà·à¶à·à¶ºâ 2011-2012 John Lindgren and MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>à¶±à·à¶½à·à¶à· මà·à·à·âà¶»à¶à¶º</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "à¶´à·âà¶»à¶à·à¶¯à·à¶± à¶±à·à¶½à·à¶à·:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "à¶±à·à¶½à·à¶à· මà·à·à·âà¶»à¶à¶º"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "මà·à¶©à· à¶à·à·à·à¶±à·à¶º (මà·à¶©à·à¶ºà·à¶½ à¶°à·à·à¶à¶º)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>à·à·à¶·à·à¶¯à¶±à¶º</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "à¶¶à·à¶§à·-8"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "à¶¶à·à¶§à·-16"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>à¶±à·à¶½à·à¶à· </b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "à¶à·à¶§à·à¶§à·à¶à¶¸ (à·à·à¶à·à¶à·à¶¸)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "à¶»à·à¶à·à¶º (à·à·à¶à·à¶à·)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "à·à·à¶» à¶à¶½à·à¶º (යà·à¶´à¶à·)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "à¶¶à·à· à¶
දà·à¶ºà¶» (à¶´à·âà¶»à·à·à·à¶)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>à·à·à¶¸à·à¶´à¶½ à·à·âà¶»à·à¶âà·âà¶»à¶à·à·</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "මටà·à¶§à¶¸:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "à¶à¶´à· à·à·à¶»à·à¶¸:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>à¶´à·âà¶»à¶à·à¶±à·à¶¯à¶à¶º</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "\t<b>මනà·à¶¯à·âà¶»à·à·à·à¶»à¶º à·à·à¶©à·à·à·à¶¸</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>à·à¶§à¶´à·à¶§à·à·</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>à¶´à·âà¶»à·à¶à·à·à¶»à·à¶°à¶à¶º</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "à¶
à¶°à·à¶ à·à·à¶¸à·à¶´à¶½"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "à·à¶¶à·à¶¯à¶º à¶
à¶©à· à¶à·à¶»à·à¶¸"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "Amiga MODs à¶°à·à·à¶±à¶º à¶à¶»à¶±à·à¶± "
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>à¶±à·à·à¶ à¶à·à¶»à·à¶¸</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "à¶±à·à·à¶ à¶à¶«à¶±à· à¶à·à¶»à·à¶¸"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "à·à¶¯à·à¶§à¶¸ à¶±à·à·à¶ à¶±à·à·à¶ à¶à·à¶»à·à¶¸à¶§, à¶±à·à·à¶ à·à¶»à¶à· à¶à¶«à¶±à· à¶à·à¶»à·à¶¸ -1 à·à· à¶´à·à·à·à¶§à·à·à¶±à·à¶±."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "මà·à¶©à· à¶à·à·à·à¶±à·à¶º (මà·à¶©à·à¶ºà·à¶½ à¶°à·à·à¶à¶º)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "à·à·à·à·à·
"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "à·à·à·à·à·
"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 à·à·à·à·à¶¯à·à¶ºà¶à¶º"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "à¶±à·à¶à¶±à· HTTP/HTTPS à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "à¶±à·à·à¶à·à¶± "
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "à¶à¶©à·à·à·à· à¶à·âà¶»à·à¶ºà·à¶à·à¶¸à¶ à¶±à·à·à·."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "à·à·à¶©à¶à¶½à¶º දà·à¶±à·à¶¸à· දà·à¶¸ "
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2524,55 +2578,64 @@ msgstr ""
"à¶à¶¶à¶§ මම මà·à¶¯à·à¶à·à¶à¶à¶º à·à¶¸à¶ GNU à¶´à·à¶¯à· මà·à¶¢à¶± à·à¶»à¶´à¶à· à¶´à·à¶§à¶´à¶à¶à· à¶½à·à¶¶à· à¶à·à¶¶à·à¶º යà·à¶à·à¶º, à¶à·à· à¶±à·à¶¸à·à¶à· නම෠"
"<http://www.gnu.org/licenses/>. බලනà·à¶±."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "යà·
à· à¶°à·à·à¶± à¶´à·à¶½à¶± යà¶à·à¶»à· à¶´à·à¶±à·à¶±à¶±à·à¶± "
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "à¶±à·à¶à¶» à¶±à·à·à·à¶¯à¶± à¶´à·à¶±à·à¶±à¶±à·à¶±"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "à·à·à¶©à¶à¶½à¶º දà·à¶±à·à¶¸à· දà·à¶¸ "
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "à¶´à·à¶±à·à¶±à¶±à·à¶± "
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "à·à·à¶»à·à¶¸à¶º "
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "à¶à·
à¶ "
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1.à¶´à·à¶»à¶±à·à¶¸à· à¶à¶¸à·à¶´à¶±à·à¶±à¶º "
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 à¶´à·âà¶»à¶à·à¶¯à·à¶±à¶º"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "à·à·à·à¶ºà¶à¶à·âà¶»à·à¶º à¶
මà·à¶´à¶±à·à¶±à¶º:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "à·à·à¶à¶½à·à¶´ à¶
මà·à¶´à¶±à·à¶±à¶ºà¶à· à¶·à·à·à·à¶à· à¶à¶»à¶±à·à¶±:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "à·à·à·à· à¶
à¶à¶» à·à¶¶à·à¶¯à¶º à·à·à¶»à¶à·à¶±à·à¶±."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "OSS මà·à¶¯à·à¶à·à¶à¶à¶ºà·à¶±à· à·à·à¶¯à¶± ලද à¶à¶à·à¶à· à¶
à¶±à·à·à¶»à·à¶à¶± à·à¶à·âà¶»à·à¶º à¶à¶»à¶±à·à¶±."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "à¶
à¶à·à¶à·à·à·à¶ à¶à¶§à¶±à·à·à·à¶±à· මà·à¶¯à·à¶¸à¶§ à¶à·à·à¶½ à¶´à·âà¶»à¶à·à¶»à¶º à·à¶à·âà¶»à·à¶º à¶à¶»à¶±à·à¶±."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2586,19 +2649,35 @@ msgstr ""
"#audacious à·à· මà·à¶±à·à·à·à¶±à· à·à·à¶ à·à·à¶à·à¶à· à¶à¶»à¶¸à·, à·à·à·à·à·à¶ºà·à¶±à· Tony Vroon à·à·â John Lindgren මà·à¶±à·à¶¸ à¶´à·à¶» "
"OSS à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶ºà¶ºà·à·à· à¶à¶à·à¶±à· à·à¶§ ."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 à¶´à·âà¶»à¶à·à¶¯à·à¶±à¶º"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à·â"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "PSF PSF1/PSF2 à·à·à¶à·à¶à¶à¶º à·à·à·à·à¶ à¶à¶»à¶±à·à¶± "
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "à·à·âà¶»à·à·âය à·à·à¶´à¶±à·à¶¯ à¶´à·âà¶»à¶à·à¶¯à·à¶±à¶º "
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2632,11 +2711,68 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "à·à·âà¶»à·à·âය à·à·à¶´à¶±à·à¶¯ à¶´à·âà¶»à¶à·à¶¯à·à¶±à¶º "
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
-#: src/resample/resample.c:165
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "à¶´à·à¶» "
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "à¶±à·à·à¶ à¶à¶»à¶±à·à¶± "
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "à¶à¶½à·à¶¸à· à¶à¶»à¶±à·à¶± "
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "à¶±à·à¶ºà·à¶¯à· à¶
à¶±à·à¶´à·à¶ à¶´à¶»à·à·à¶»à·à¶à¶à¶º "
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2644,96 +2780,104 @@ msgstr ""
"à¶à¶©à·à·à·à· à·à¶³à·à· à¶±à·à¶ºà·à¶¯à· à¶
à¶±à·à¶´à·à¶ à¶´à¶»à·à·à¶»à·à¶à¶à¶º \n"
"à¶´à·âà¶»à¶à·à·à¶± à·à·à¶¸à·à¶à¶¸ 2010-2012 à¶¢à·à¶±à· à¶½à·à¶±à·à¶¯à¶©à·à¶à·à¶»à·à¶±à· "
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "à¶±à·à¶ºà·à¶¯à· මà¶à·à·à¶»à·à¶¸/à¶±à·à·à¶ à¶à·à¶»à·à¶¸ "
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "à¶»à·à¶à·à¶º à¶
à¶±à·à¶à¶»à· à¶±à·à·à·à·à¶«à¶º"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "à·à·à¶à·à¶à· à·à·à¶±à·à¶à· à¶
à¶±à·à¶à¶»à· à¶±à·à·à·à·à¶«à¶º"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "මධà·âයම à·à·à¶±à·à¶à· à¶
à¶±à·à¶à¶»à· à¶±à·à·à·à·à¶«à¶º"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "à·à·à¶³à¶¸ à·à·à¶±à·à¶à· à¶
à¶±à·à¶à¶»à· à¶±à·à·à·à·à¶«à¶º"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>à¶´à¶»à·à·à¶»à·à¶à¶±à¶º</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "à¶à·âරමය "
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "à¶
à¶±à·à¶´à·à¶à¶º:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>à¶
à¶±à·à¶´à·à¶à¶º à·à·à¶à·à¶ºà¶¸à·à¶à¶»à¶«à¶º</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "à¶
à¶±à·à¶´à·à¶à¶º à·à·à¶à·à¶ºà¶¸à·à¶à¶»à¶«à¶º à¶·à·à·à·à¶à· à¶à¶»à¶±à·à¶±â"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 à¶à·à¶½à· à·à¶»à¶§à·à·à·:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 à¶à·à¶½à· à·à¶»à¶§à·à·à·:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 à¶à·à¶½à· à·à¶»à¶§à·à·à·:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 à¶à·à¶½à· à·à¶»à¶§à·à·à·:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 à¶à·à¶½à· à·à¶»à¶§à·à·à·:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 à¶à·à¶½à· à·à¶»à¶§à·à·à·:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 à¶à·à¶½à· à·à¶»à¶§à·à·à·:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "à¶±à·à¶ºà·à¶¯à· à¶
à¶±à·à¶´à·à¶ à¶´à¶»à·à·à¶»à·à¶à¶à¶º "
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "à¶à·à·. \tà¶´à¶»à·à·à·âà¶»à·à¶½à¶: %s à·à¶¯à·à· à¶·à·à·à·à¶ දà¶à·à¶ à·à·à¶»à¶à·à¶±à·à¶±"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "à¶
à¶±à·à¶¸à·à¶à·à¶º à¶à·à¶±à¶¸à· à¶à·à¶»à·à¶¸ "
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr "Audacious à·à¶¯à·à· à¶·à·à·à·à¶ දà¶à·à¶ à·à·à¶»à¶à·à¶¸à¶§ මà·à¶¸ à¶
මà·à¶«à¶§ à¶´à·à·à·à·à·à¶±à·à¶± :"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr "මම à¶à·à·à·
à·à· à·à·à·à·à¶âà· à¶à¶¶à· 'à¶
à·à·à¶» à¶´à·à¶»à·à¶à·à·à¶±à·à¶±' à¶±à·à·à¶ à¶à·à¶½à·à¶à· à¶à¶»à¶±à·à¶±\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2741,32 +2885,36 @@ msgstr ""
"à¶à¶«à¶à·à¶§à· à¶±à·à·à¶±à·à¶± à¶à¶¶à¶à· à¶·à·à·à·à¶ දà¶à·à¶ à¶à¶¶à¶à· à¶´à¶»à·à¶à¶«à¶à¶ºà· ම à·à·à¶»à¶à·à·à·à¶ à¶à¶»à¶ºà·.\n"
"à¶à·à· Audacious à·à¶¯à·à· à¶
à·à·à¶» à¶½à·à¶¶à·à¶«à· à·à·à·à¶¸ à·à·à¶»à¶à·à·à·à¶ à·à·"
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "à¶¢à·à¶½ à¶à·à¶§à·
à·."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "à¶
à·à·à·à¶±à¶ºà¶§ à·à¶¸à·à¶¶à¶±à·à¶° à·à·à¶¸à· à¶à·à¶§à·
à·à·à¶à· à·à·à¶º.fm.à¶à¶»à·à¶«à·à¶à¶» à¶´à·à·à· à¶±à·à·à¶ à¶à¶à·à·à· à¶à¶»à¶±à·à¶± "
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "à¶´à·à¶»à·à¶à·à·à¶±..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "C_heck à¶
à¶±à·à¶¸à·à¶à·à¶º "
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_à¶
à¶±à·à¶¸à·à¶à·à¶º à¶
à·à¶½à¶à¶à· à¶à·à¶»à·à¶¸ "
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr "à¶à¶¶ à¶à¶©à·à·à·à· à·à¶§ à¶à¶¶à¶à· à¶
à·à·à·à¶± fm à¶à·à¶«à·à¶¸à·à¶±à· à¶à·à¶ ලබ෠à¶à·à¶±à·à¶¸à¶§ à¶
à·à·à¶» දà·à¶º යà·à¶à·à¶º.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "à·à·à¶à·à¶»à·à¶¶à·à¶½à¶»à· 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2774,7 +2922,7 @@ msgstr ""
"Scrobbler à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º à¶à¶»à¶·à·à¶º à¶±à·à·à·à¶à·à¶º.â\n"
"à·à¶¸à·à¶»à·à·à¶§ à¶à¶¶à¶à· à¶´à·à·à·à¶§à·à·à·à¶¸à·à·à· à¶à·à¶§à¶½à·à·à¶à· à¶à¶."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2788,11 +2936,7 @@ msgstr ""
"\n"
"à¶´à·âà¶»à¶à·à·à¶± à¶
යà·à¶à·à¶º © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com>\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "à·à·à¶à·à¶»à·à¶¶à·à¶½à¶»à· 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2800,7 +2944,11 @@ msgstr ""
"Audacious à¶
à·à·à·à¶±à¶ºà¶§ à·à·à¶©à· දà·à¶ºà·à¶«à·à¶à·
à¶
à¶±à·à·à·à¶¯à¶º à¶·à·à·à·à¶ à¶à¶»à¶ºà·.fm Scrobbler.â \n"
"à¶à¶»à·à¶«à·à¶à¶» Scrobbler à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶ºà· à¶
à¶·à·à¶»à·à¶ à·à¶º à¶´à¶»à·à¶à·à·à· à¶à¶» බලනà·à¶±."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL à¶´à·âà¶»à¶à·à¶¯à·à¶±à¶º"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2808,760 +2956,825 @@ msgstr ""
"Audacious à·à¶³à·à· à·à¶± SDL à¶´à·âà¶»à¶à·à¶¯à·à¶±â à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º\n"
"à¶´à·âà¶»à¶à·à·à¶± à¶
යà·à¶à·à¶º 2010 à¶¢à·à¶±à· à¶½à·à¶±à·à¶©à·à¶à·âà¶»à·à¶±à·"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL à¶´à·âà¶»à¶à·à¶¯à·à¶±à¶º"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "à¶´à·à·à·à¶à¶à·à¶½à¶º "
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "à¶±à·à¶³à·à¶±à¶± à·à·à¶½à·à¶´à·à¶ºà·"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "à¶±à·à¶³à·à¶±à¶± à¶à¶½à·à¶¶à¶¸à¶º "
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-"මà¶à·à¶´à·à¶§ %s à·à·à·à·à¶±à· %s"
-
-#: src/search-tool/search-tool.c:631
-#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d à¶à¶½à·à¶¶à¶¸à¶º "
-msgstr[1] "%d à¶à¶½à·à¶¶à¶¸"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-"%sâ\n"
-"%s, %d à¶à·à¶à¶º "
msgstr[1] ""
-"%s\n"
-"%s, %d à¶à·à¶ "
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
-"%s\n"
-"%d à¶à·à¶à¶ºà·à¶±à· %s"
msgstr[1] ""
-"%sâ\n"
-"%d à¶à·à¶ à·à¶½à·à¶±à· %s"
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à·â à¶à¶±à¶±à·à¶± "
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à·âà¶§ à¶à¶à¶à· à¶à¶»à¶±à·à¶± "
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "à¶´à·à·à·à¶à¶à·à¶½à¶º à·à·à¶ºà¶±à·à¶± "
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
"à¶à¶©à·à·à·à· à¶à·à¶½à¶§ à¶à¶¶à¶à· à¶à·à¶ à¶´à·à·à·à¶à¶à·à¶½à¶º à¶à¶ºà·à¶ à¶à·à¶»à·à¶¸à¶§, à·à·à¶½à·à¶©à¶»à¶ºà¶à· à¶à·à¶»à· \"à¶±à·à·à·à¶¸à· à¶à¶»à¶±à·à¶±\" à¶±à·à¶»à·à¶´à¶à¶º à¶à¶¶à¶±à·à¶±."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "à¶à¶»à·à¶«à·à¶à¶» à¶»à·à¶³à· à·à·à¶§à·à¶±à·à¶± ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "à·à·à¶½à·à¶©à¶»à¶º à¶à·à¶»à¶±à·à¶± "
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "à¶´à·à·
à·à·à·à¶ºà·à¶¸"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à·â"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "දà¶à·à·à¶±à·à¶± "
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "à¶±à·à·à¶ à¶à¶»à¶±à·à¶± "
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "à¶à¶½à·à¶¸à· à¶à¶»à¶±à·à¶± "
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "à¶°à·à·à¶± à¶½à·à·à·à¶à· à¶±à·à¶ "
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "à¶´à·à¶» "
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "න෠ධà·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à·â"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "à¶°à·à·à¶± à¶½à·à·à·à¶à· à·à¶à·à¶±à¶º à¶´à·à¶±à·à·à¶±à·à¶± "
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr " à¶à¶à·à·à¶½à·à·à¶»à¶º à¶´à·à¶±à·à·à¶±à·à¶± "
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "à·à·à¶¸à·à·à¶§à¶¸ à¶à·à·
"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "මà·à¶à·à¶à·à·à·à¶±à· "
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "à¶à·à¶±à· à¶±à·à¶¸à¶ºà·à¶±à· "
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "à·à·à¶ºà¶½à·à¶½ à¶à·à¶à· à¶à¶»à¶±à·à¶± "
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "à¶´à·à·
à¶à·à·à·à¶¸ à·à·à·à· à¶à¶»à¶±à·à¶±"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "à¶
à¶±à·à¶´à¶ºà·à¶¢à·âය à¶à·à¶±à· à¶à·à¶à· à¶à¶»à¶±à·à¶± "
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "දà·à·à·à¶à¶»à¶« à¶à·à¶à· à¶à¶»à¶±à·à¶± "
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "à¶à·à¶»à·à¶±à·à¶à¶à· à¶à·à· à¶à·à¶à· à¶à¶»à¶±à·à¶± "
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "à¶à·à¶»à·à¶à¶à· à¶à·à· à¶à·à¶à· à¶à¶»à¶±à·à¶± "
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "à·à·à¶ºà¶±à·à¶± à·à· à¶à·à¶»à¶±à·à¶± "
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "à·à¶»à¶«à¶º à¶´à·à¶»à¶½à¶±à·à¶± "
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "à¶à·à·à·à·à¶à· à¶à·à¶»à·à¶±à·à¶à¶±à·à¶± "
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "à·à·à¶ºà¶½à·à¶½ à¶à·à¶»à¶±à·à¶±"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "à¶à¶½à·à¶¶à¶¸à¶ºà·à¶±à· "
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "à¶à¶«à·à¶© à¶
à¶à¶à¶ºà·à¶±à· "
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "à·à·à¶½à·à¶´à·à¶ºà·à¶à·à¶±à· "
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "à¶à¶½à·à¶¶à¶¸à¶ºà·à¶±à· "
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "à¶à¶«à·à¶© à¶
à¶à¶à¶ºà·à¶±à· "
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "à·à·à¶¸à·à¶·à·à·à· à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à· "
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "à¶½à·à·à·à¶à·à·à· à¶à¶´à·à·à·à¶§ යනà·à¶± "
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "à¶à·à¶»à·à¶à¶à· à¶
à¶±à·à¶´à·à·
à·à·à¶½à¶§ "
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "à¶½à·à¶ºà·à·à·à¶à·à· à¶
à¶±à·à¶´à·à·
à·à·à¶½à¶§ à·à¶à·à¶±à·à¶± "
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "à¶à¶´à¶±à·à¶± "
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "à¶´à·à¶§à¶´à¶à· à¶à¶»à¶±à·à¶± "
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "à¶
à¶½à·à¶±à·à¶± "
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winamp à·à¶¸à·à¶·à·à·à·âය à¶
à¶à·à¶»à· මà·à·à·à¶«à¶"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "à·à·à¶»à¶à·à¶±à·à¶± "
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "à¶´à·âà¶»à·à·à·à¶±à¶º "
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "à¶´à·à¶» à·à¶à·à¶± ලද "
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "à¶´à·à¶» à·à¶à·à¶±à¶º à¶´à·âà¶»à·à·à·à¶±à¶º à¶à¶»à¶±à·à¶± "
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "à¶´à·à¶» à·à¶à·à¶±-à·à·à·à¶ºà¶à¶à·âà¶»à·à¶º à¶´à·âà¶»à·à·à·à¶±à¶º"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "à¶´à·à¶» à·à¶à·à¶±à¶º à·à·à¶»à¶à·à¶±à·à¶± "
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "à¶´à·à¶» à·à¶à·à¶±à¶º-à·à·à·à¶ºà¶à¶à·âà¶»à·à¶ºà· à·à·à¶»à¶à·à¶±à·à¶±"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "à¶´à·à¶» à·à¶à·à¶±à¶º මà¶à¶±à·à¶±"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "à¶´à·à¶» à·à¶à·à¶±à¶º-à·à·à·à¶ºà¶à¶à·âà¶»à·à¶ºà· මà¶à¶±à·à¶±"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_à¶°à·à·à¶à¶º:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "à¶à·à·à·
à· à·à·à¶±à·à¶§à¶ºà· à¶´à·âරධà·à¶± à¶°à·à·à¶à¶º à¶à·à¶»à¶±à·à¶±:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_à¶°à·à·à¶± à¶½à·à·à·à¶à·à·:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "à¶°à·à·à¶± à¶½à·à·à·à¶à· à·à·à¶±à·à¶§à¶º à¶à·à¶»à¶±à·à¶±:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "à¶¶à·à¶§à·à¶¸à·à¶´à· à·à·à¶±à·à¶§ à¶·à·à·à·à¶à· à¶à¶»à¶±à·à¶± (ASCII පමණà¶à· à·à·à¶º à·à¶± )"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "à¶à·à¶ à¶à·à¶¸à·à· දà·à¶´à·à¶§ චලනය à¶à¶»à¶±à·à¶± "
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "à·à·à·à·à¶½à·à·à¶à¶º "
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "à·à·à·à¶º පථය "
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "à·à·à¶±à·à· "
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "à·à·à¶¸à·à¶±à·âය "
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "දලà·à·à¶±à·à· "
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr " à¶»à·à¶à·"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "à¶à·à¶»à· "
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "මනà·à¶¯à¶à·à¶¸à·à¶¸ "
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "මනà·à¶¯à¶à·à¶¸à·"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "මධà·âයම "
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "à·à·à¶à·à¶à· "
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "à·à·à¶à·à¶à·à¶¸ "
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "à·à·à¶¸ "
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "මà·à¶¯à· "
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "à·à·à¶¸à·à¶±à·âය"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "දà·à·à·à¶§à· à¶à¶½à·à¶´à¶±à¶º "
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "à¶´à·à¶»à·à· à·à¶»à·à¶°à¶à¶º"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 à·à¶»à¶§à·à·à· "
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 à·à¶»à¶§à·à·à· "
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 à·à¶»à¶§à·à·à· "
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 à·à¶»à¶§à·à·à· "
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 à·à¶»à¶§à·à·à· "
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 à·à¶»à¶§à·à·à· "
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 à·à¶»à¶§à·à·à· "
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 à·à¶»à¶§à·à·à· "
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 à·à¶»à¶§à·à·à· "
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 à·à¶»à¶§à·à·à· "
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "à¶à¶©à·à·à·à· à¶à¶à·à·à¶½à·à·à¶»à¶º "
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "à·à·à¶ºà¶±à·à· %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "à·à¶¶à·à¶¯ මටà·à¶§à¶¸â : %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "à¶à·à¶½à¶±à¶º : %d%% à·à¶¸à¶§ "
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "à¶à·à¶½à¶±à¶º: මà·à¶¯à¶§ "
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "à¶à·à¶½à¶±à¶º: %d%% දà¶à·à¶«à¶§ "
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "à·à·à¶à¶½à·à¶´ මà·à¶±à·à· "
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "à¶
à¶à·âà¶»à·à¶º à¶à¶»à¶±à·à¶± 'à·à·à¶¸à·à·à¶§à¶¸ à¶à·à·
'"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "à·à¶à·âà¶»à·à¶º à¶à¶»à¶±à·à¶± 'à·à·à¶¸à·à·à¶§à¶¸ à¶à·à·
'"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "à¶à·à¶±à· à¶à·à¶»à¶à·à¶»à· à¶´à·à¶§à·à¶§à·à¶º "
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "à¶´à·à¶±à¶»à·à·à¶»à·à¶®à¶± à·à·à¶®à·à¶±à¶º A à¶à·à¶½à¶à¶º."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "à¶´à·à¶±à¶»à·à·à¶»à·à¶®à¶± à·à·à¶®à·à¶±à¶º B à¶à·à¶½à¶à¶º."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "à¶´à·à¶±à¶»à·à·à¶»à·à¶®à¶± à·à·à¶®à·à¶± à·à·à·à· à¶à¶»à¶± ලදà·."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "à¶à¶±à· à¶´à·âà¶»à¶à·à¶»à¶º."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "à¶°à·à·à¶± à¶½à·à·à·à¶à· à¶´à·âà¶»à¶à·à¶»à¶º."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "à¶à·à¶à¶ºà¶à·à¶±à· à¶´à·à· à¶±à·à·à¶à·à¶¸."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "à·à¶à·âà¶»à·à¶º à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à·à· à¶´à·à·à·à·à·à¶¸à· à·à·à¶ºà¶±à·à¶± "
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3572,57 +3785,61 @@ msgstr ""
"à·à·à¶à· à¶»à·à¶à·, à¶
à¶à·à¶»à· à¶à¶§à·-à·à¶à·à·à¶¯à· à¶±à·à¶à· à¶·à·à·à·à¶à· à¶à¶»à¶ºà·. à¶à¶¶à¶§ à·à·à¶°à·à¶¸à¶à· à¶´à·âà¶»à¶à·à·à¶± à·à·à¶à· à¶»à·à¶à· à¶à·âà¶»à·à¶ºà·à¶à·à¶¸à¶ à·à¶± à¶à¶à·à¶»à¶º "
"à¶´à·à·
à·à¶¶à¶³ à¶
à·à¶¶à·à¶°à¶ºà¶à· à¶±à·à¶à· නමà·, à¶à¶¶ à·à·à¶ºà¶± à·à¶ à¶± à¶à·à¶§à· à¶à¶à·à¶½à· à¶à¶»à¶±à·à¶±."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "මà·à¶à·à¶à·à·:"
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "à¶à¶½à·à¶¶à¶¸à¶º:"
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "à·à·à¶½à·à¶´à·à¶ºà·:"
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "à¶à·à¶±à· à¶±à·à¶¸à¶º:"
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "à¶´à·à¶» à¶à·à¶»à·à¶¸ à·à·à·à·à¶¸à¶§ à¶´à·à¶» à·à·à·à· à¶à¶»à¶±à·à¶± "
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "à¶à·à¶½à¶´à·à¶± à¶´à·à·à·à·à·à¶¸à· à·à¶³à·à· à·à·à·à¶ºà¶à¶à·âà¶»à·à¶ºà· à¶´à·à·
à¶à·à·à·à¶¸ à¶§à·à¶à¶½ à¶à¶»à¶±à·à¶± "
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "à¶à·à¶½à¶´à·à¶± à¶´à·à·à·à·à·à¶¸à· à·à¶¸à¶ න෠ධà·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à· à¶à¶±à¶±à·à¶± "
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "à¶à¶©à·à·à·à· à¶°à·à·à¶± à¶½à·à·à·à¶à· à·à¶à·à¶±à¶º "
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d à¶à·à¶±à· %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "à·à¶à¶»à¶à·à·à·à¶ Winamp 2.x මà¶à·à¶´à·à¶§ "
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "à·à¶à¶»à¶à·à·à¶«à¶º à¶±à·à¶à¶»à¶± ලද Winamp 2.x මà¶à·à¶´à·à¶§"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "à¶±à·à¶¸à·à·à¶½à·à¶º à¶±à·à¶»à·à¶¸à·à¶«à¶º à¶à·à¶»à·à¶¸à¶§ à¶±à·à·à·à¶à·à¶º (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Snd à¶à·à¶±à· à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3661,81 +3878,71 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Snd à¶à·à¶±à· à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Sndio à¶´à·âà¶»à¶à·à¶¯à·à¶± à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º à¶´à·à·
à·à¶¶à¶³â"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-"Sndio à¶´à·âà¶»à¶à·à¶¯à·à¶± à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶ºâ\n"
-"â\n"
-"à¶½à·à¶ºà¶±à· à¶½à·à¶¶à·à·à· à¶à·à¶¸à·à· à¶´à·à·à·à·à· à·à·à·à·à¶±à· <tpfaff at tp76.info>â\n"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "à·à·à·à¶º à¶±à·à¶¸à·à¶à· à·à·à¶©à¶à¶½à¶ºâà¶à·"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-"à·à·âà¶»à·à·âය à¶à¶¸à·à¶´à¶±à·à¶±à¶ºà¶§ à·à·à¶º à¶±à·à¶¯à¶à·à·à¶± à·à·à¶©à¶à¶½à¶ºà¶à· à¶
යà·à¶¯à·à¶¸à· à¶à¶»à¶± ලදà·.â\n"
-"â\n"
-"sndiod(1) à·à·à·à·à¶¯à·à¶ºà¶à¶ºâ à¶°à·à·à¶±à¶º à·à¶± à¶
à¶à¶»à¶à·à¶» à¶±à·à·à¶ à¶à¶à·à·à·à· à¶à¶»à¶±à·à¶±â."
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio à¶à¶¸à·à¶´à¶±à·à¶±à¶º"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(à·à·à·à· à· à¶à·à¶¶à·à¶¸ යන෠පà·à¶»à¶±à·à¶¸à·à¶ºà¶ºà· )"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "à¶à¶à¶à¶ºà·"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "à¶à·à¶ à·à·à¶±à·à·à¶à·à¶»à·à¶¸ "
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "à¶à¶©à·à·à·à· න෠à¶à·à¶à¶ºà¶à· à¶à¶»à¶¸à·à¶· à¶à·
à·à·à¶§ à¶°à·à·à¶±à¶º à·à¶³à·à· à·à·à¶°à·à¶±à¶º."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>à¶à·à¶ ය à·à·à¶ à·à·à·à¶¸à·à¶»à· à¶à¶»à¶± ලද à¶´à¶»à·à¶¸à·à¶à·à¶ à¶à·à¶§à·à· à¶½à·à· à¶´à·âà¶»à·à·à¶»à·à¶à·à¶ à¶à¶» à¶à¶. à¶à¶º "
+"à¶à·à· à¶±à·à¶à¶»à·à·à¶à· à¶à¶»à¶à·à·à·à· à¶´à·à·
à·à¶¶à¶³ à¶
à·à¶¯à·à¶±à¶¸à¶à· à¶´à·à¶à·.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "à·à·à¶°à·à¶±à¶º:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "à¶à·à¶à¶ºà¶ à¶
à·à·à·à¶±à¶º à¶à·à¶à· à¶°à·à·à¶±à¶º à·à¶³à·à· à·à·à¶°à·à¶±à¶º."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "à¶à¶©à·à·à·à· à¶°à·à·à¶± à¶½à·à·à·à¶à·à·à· à¶
à·à·à·à¶±à¶ºà¶§ à¶´à·à¶¸à·à¶«à·à·à·à¶§ à¶°à·à·à¶±à¶º à·à¶³à·à· à·à·à¶°à·à¶±à¶º."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
-msgstr "à¶à·à¶à¶ºà¶ මà·à¶à·à¶à·à· à·à·à¶±à·à· à·à· à·à·à¶§ à¶°à·à·à¶±à¶º à·à¶³à·à· à·à·à¶°à·à¶±à¶º (à¶¢à·à¶½ à¶´à·âà¶»à·à·à· මà·à¶à·à¶à· )."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr ""
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3749,34 +3956,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"à¶à¶¶à¶§ à¶´à·à¶ දà·à¶à·à·à·à¶± à¶
à¶±à·à¶½à¶à·à¶«à· à·à·à¶½à·à·à· à¶à¶à·à¶à· à·à·à¶°à·à¶±à¶º à¶à·à¶»à·à¶¸à¶§ à¶´à·à¶» à¶à¶¯à·à· à¶à·
à·à·à¶\n"
-"(à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à· à·à·à¶°à·à¶± à¶
à·à·à·à¶±à¶ºà·à¶¯à· à¶à¶à·à¶¸à·à·à·à¶§ à·à·à¶ºà¶½à·à¶¸ à·à·à¶°à·à¶± à¶´à·âරයà·à¶¢à¶±à·à¶à· à¶±à·à·à·à¶º à·à·à¶):\n"
-"\n"
-"%F: à·à¶à¶à·âයà·à¶à¶º (à·à¶»à·à¶§à·à·à· à·à¶½à·à¶±à·)\n"
-"%c: à¶±à·à¶½à·à¶à· à¶à¶«à¶± \n"
-"%f: à¶à·à¶±à· à¶±à·à¶¸à¶º (à·à¶¸à·à¶´à·à¶»à·à¶« පථය)\n"
-"%l: à¶à¶ºà·à¶¸à¶º (මà·à¶½à· à¶à¶à·à¶´à¶» à·à¶½à·à¶±à·)\n"
-"%n à·à· %s: à¶à·à¶à¶ºà· නම \n"
-"%r: à¶
à¶±à·à¶´à·à¶à¶º (à¶à¶à·à¶´à¶»à¶ºà¶§ à¶¶à·à¶§à·à·à· à·à¶½à·à¶±à·)\n"
-"%t: à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à·à· à·à·à¶®à·à¶±à¶º (%02d)\n"
-"%p: දà·à¶±à· à¶°à·à·à¶±à¶º à·à¶± (1 or 0)\n"
-"%a: à·à·à¶½à·à¶´à·à¶ºà· \n"
-"%b: à¶à¶½à·à¶¶à¶¸à¶º \n"
-"%T: à¶à¶«à·à¶©à¶ºà· මà¶à·à¶à·à· "
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>à¶à·à¶ ය à·à·à¶ à·à·à·à¶¸à·à¶»à· à¶à¶»à¶± ලද à¶´à¶»à·à¶¸à·à¶à·à¶ à¶à·à¶§à·à· à¶½à·à· à¶´à·âà¶»à·à·à¶»à·à¶à·à¶ à¶à¶» à¶à¶. à¶à¶º "
-"à¶à·à· à¶±à·à¶à¶»à·à·à¶à· à¶à¶»à¶à·à·à·à· à¶´à·à·
à·à¶¶à¶³ à¶
à·à¶¯à·à¶±à¶¸à¶à· à¶´à·à¶à·.</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "à·à·à¶°à·à¶±:"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "Sox à¶±à·à·à¶ à·à·à¶¸à·à¶´à¶½ à¶à·à¶»à·à¶¸ "
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3790,51 +3979,51 @@ msgstr ""
"à¶±à·à¶ºà·à¶¯à· à¶
à¶±à·à¶´à·à¶ à¶´à¶»à·à·à¶»à·à¶à¶± à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º මචපදනම෠à·à· à¶à¶â:\n"
"à¶´à·âà¶»à¶à·à·à¶± à¶
යà·à¶à·à¶º 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "à¶à¶©à·à¶±à¶¸à·"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "à¶´à·à·
"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "à¶à·à·
"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "à¶
à¶à·- à¶à¶ à·à¶ "
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "à¶´à·âà¶»à·à·à·à¶à¶à·à·:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "Sox à¶±à·à·à¶ à·à·à¶¸à·à¶´à¶½ à¶à·à¶»à·à¶¸ "
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "à·à·à¶à¶º à·à· à·à·à·à¶»à¶¸à·à¶±à¶º"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>à·à·à¶à¶º à·à· à·à·à·à¶»à¶¸à·à¶±à¶º</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "à·à·à¶à¶º:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "à·à·à·à¶»à¶¸à·à¶±à¶º:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "à·à·à¶à¶º à·à· à·à·à·à¶»à¶¸à·à¶±à¶º"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "à¶à¶à·à· à¶±à·à¶»à·à¶´à¶à¶º"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3852,39 +4041,39 @@ msgstr ""
"මà·à¶¸ à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º à¶à¶à·à¶à·à· à·à·à¶»à·à·à¶¸à¶à· à·à¶´à¶ºà¶±à· ලබයà·, à¶à·à·à·
à· à¶à·
මනà·à¶à·à¶»à¶à¶ºà·à·à· පදà·à¶°à¶à· à¶§à·âර෠à¶à·à¶§à·à· රඳà·à· "
"à¶à·à¶¶à·à¶± à¶½à·à·."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>මà·à·à·à¶ à¶
à¶±à·à¶ ලන à¶à·âà¶»à·à¶ºà·à·</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "à·à¶¶à·à¶¯à¶º à·à·à¶±à·à·à¶à·à¶»à·à¶¸ "
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "à·à·à¶¯à¶±à¶º à·à¶± à¶à·à¶à¶º à·à·à¶±à·à·à¶à·à¶»à·à¶¸ "
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>à¶
à¶±à·à¶à·à¶à· à·à·à¶à·à·à¶¸à·</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "à¶à¶à·à¶´à¶à¶± à¶à·à·à·
à·à· à¶
à¶à·âà¶»à·à¶º à¶à¶»à¶±à·à¶± "
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "පදà·à¶°à¶à· à¶à¶§à·à¶§à·à·à¶§ à¶à·à¶±à·à¶±à· "
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "à¶
à¶±à·à¶ ලනය à¶à·à·
à¶§ à·à·à¶¯à·à¶à¶»à¶± à·à·à¶§ à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à· à¶´à·âà¶»à¶à¶¸à¶±à¶º "
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "à¶à¶à·à· à¶±à·à¶»à·à¶´à¶à¶º"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "à¶
à¶à·à¶»à·à¶ à¶âà·âà¶»âà·âà¶»à·à¶¸à·à¶«"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3894,24 +4083,24 @@ msgstr ""
"\n"
"Johan Levin à·à·à·à·à¶±à·, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>à¶
à¶à·à¶»à·à¶ à¶à·âà¶»à·à¶¸à·à¶±</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "à¶
à¶à·à¶»à·à¶ à¶âà·âà¶»âà·âà¶»à·à¶¸à·à¶«"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "à·à·à·à¶» ජනà¶à¶º"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f à·à¶»à·à¶§à·à·à· "
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "à·à·à·à¶» ජනà¶à¶º:"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3925,15 +4114,11 @@ msgstr ""
"à¶·à·à·à·à¶à· à¶à·à¶»à·à¶¸ à·à¶³à·à·, add a URL: tone://frequency1;frequency2;frequency3;...\n"
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "à·à·à·à¶» ජනà¶à¶º"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "à¶à¶§à·à¶¬ à¶à·à¶à· à¶à·à¶»à·à¶¸â"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3971,11 +4156,35 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis à·à·à¶à·à¶à¶à¶º"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX à·à·à¶à·à¶à¶à¶º"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -3985,19 +4194,19 @@ msgstr ""
"Based on in_vtx.dll Roman Sherbakov à·à·à·à·à¶±à· <v_soft at microfor.ru>\n"
"Audacious à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶à¶º Pavel Vymetalek à·à·à·à·à¶±à· <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX à·à·à¶à·à¶à¶à¶º"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack à·à·à¶à·à¶à¶à¶º"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "à·à·à¶±à·à¶¸à¶à· (දà·à¶¸à·à·à·à¶±à·)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "à·à·à¶±à·à¶¸à¶à· "
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4006,14 +4215,18 @@ msgstr ""
"à¶´à·âà¶»à¶à·à·à¶± à·à·à¶¸à·à¶à¶¸ 2006 William Pitcock <nenolod at nenolod.net>\n"
"à¶à¶à·à¶¸à· à¶´à·à¶±à· මà·à¶¯à·à¶à·à¶à¶ à¶à·à¶ Miles Egan à·à·à·à·à¶±à·."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack à·à·à¶à·à¶à¶à¶º"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr " 2SF à·à·à¶à·à¶à¶à¶º"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "XML à·à·à·à¶¸à·à¶»à· à¶à·
à·à·à¶à· à¶°à·à·à¶± à¶½à·à¶ºà·à·à·à¶à·à·â (XSPF)"
diff --git a/po/sk.po b/po/sk.po
index 7f8190638179..2ed74993a28f 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -4,17 +4,17 @@
#
# Translators:
# Andrej Herceg <herceg.andrej at zoznam.sk>, 2007, 2008, 2010, 2011
-# citro <lukas.dobransky at gmail.com>, 2012
+# Lukáš Dobránsky <lukas.dobransky at gmail.com>, 2012
# Tomáš Vadina <tomasvadina+transifex at cryptolab.net>, 2012
# Corduroy <vdcorduroy at gmail.com>, 2013
# Corduroy <vdcorduroy at gmail.com>, 2012
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Slovak (http://www.transifex.com/projects/p/audacious/"
"language/sk/)\n"
"Language: sk\n"
@@ -23,40 +23,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "Priestorový zvuk"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib prehrávaÄ)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "sekvenÄný"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib prehrávaÄ)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarm"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -66,11 +54,7 @@ msgstr ""
"\n"
"NapÃsali Adam Feakin a Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarm"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -93,7 +77,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -115,7 +99,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -129,384 +113,371 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Toto je budiaci signál."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr ""
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Upozornenie"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Pondelok"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Utorok"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "Streda"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "Å tvrtok"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Piatok"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Sobota"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Nedeľa"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Nastavenie Alarmu"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Äas"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Budiť o (predvolené):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Ticho po:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "hodÃn"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "minút"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Vyberte dni, kedy má budÃk budiÅ¥"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "DeÅ"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Štandardné"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Dni"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Zosilovanie"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "sekúnd"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Hlasitosť"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "ZaÄaÅ¥ na"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "SkonÄiÅ¥ na"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Aktuálna"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "DodatoÄný prÃkaz"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "povoliť"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Zoznam skladieb (voliteľné)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "Vyber zoznam skladieb"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Možnosti"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Äo tieto možnosti znamenajú?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "PomocnÃk"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Album"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA výstup"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ALSA výstupný zásuvný modul pre Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"Moja vÄaka patrà Williamovy Pitcockovy, autorovy ALSA výstupného zásuvného "
+"modulu NG, ktorého kód mi poslúžil ako predloha keÄ ALSA manual nestaÄil."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Predvolené PCM zariadenie"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Predvolené zariadenie mixéra"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM zariadenie:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "Zariadenie mixéra:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "Prvok mixéra:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "ObÃsÅ¥ problém so zasekávanÃm pri vyprázdÅovanÃ"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI prehrávaÄ)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-"ALSA výstupný zásuvný modul pre Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
"\n"
-"Moja vÄaka patrà Williamovy Pitcockovy, autorovy ALSA výstupného zásuvného "
-"modulu NG, ktorého kód mi poslúžil ako predloha keÄ ALSA manual nestaÄil."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA výstup"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI prehrávaÄ)"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - vyberte SoundFont súbor"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Názov súboru"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Veľkosť (v bajtoch)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Názov:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> Podrobnosti o MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Formát:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Dĺžka (ms):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "PoÄet stôp:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "premenlivé"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (váž.):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Äas. pomer:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> Komentáre a slová MIDI skladby </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* v MIDI súbore sa nenachádzajú žiadne komentáre *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* v MIDI súbore sa nenachádzajú žiadne texty skladby *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Zatvoriť"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (neplatné UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "O AMIDI zásuvnom module"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"modulárny prehrávaÄ MIDI hudby\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"napÃsal Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"zvláštne poÄakovanie...\n"
-"\n"
-"Clemens Ladisch a Jaroslav Kysela\n"
-"za ich úžasné programy aplaymidi a amixer; boli\n"
-"naozaj užitoÄné, spolu s alsa-lib dokumentáciou\n"
-"som sa nauÄil viac o ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"za pekné logo MIDI klávesnice\n"
-"\n"
-"Tony Vroon\n"
-"za pomoc pri testovanÃ"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -517,152 +488,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (On-Screen Display)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Obdĺžnik"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Zaoblený obdĺžnik"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "Konkávny obdĺžnik"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Žiadne"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "ZaÄiatok prehrávania"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "OSD sa zobrazà pri zahájenà prehrávania položky zo zoznamu skladieb."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "Zmena názvu"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"OSD sa zobrazà poÄas prehrávania ak sa zmenà názov, ale meno súboru ostane "
-"nezmenené. Je to hlavne vhodné na zobrazenie zmien názvov skladieb pri "
-"prehrávanà internetových prúdov."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Pozastavenie prehrávania"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "OSD sa zobrazà pri pozastavenà prehrávania."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Obnovenie prehrávania"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "OSD sa zobrazà keÄ je prehrávanie obnovené."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "Umiestnenie"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "RelatÃvne odsadenie v smere osi X:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "RelatÃvne odsadenie v smere osi Y:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Maximálna Å¡Ãrka OSD:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Nastavenia pre viac monitorov"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "Zobraziť OSD na:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "všetkých monitoroch"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "monitore %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Äasovanie (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Zobrazenie:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Rozsvietenie:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Zhasnutie:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "PÃsma"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "PÃsmo %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "TieÅ"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Štýl zobrazenia"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Farby"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Farba %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "PovoliÅ¥ spúšťaÄ"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Udalosť"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Bol zistený kompozitný správca"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -672,112 +637,112 @@ msgstr ""
"Ak viete, že žiadny nebežÃ, prosÃm, aktivujte kompozitného správcu, inak "
"nebude OSD pracovať správne"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Pri falošnej priehľadnosti nie je potrebný kompozitný správca"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Priehľadnosť"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Falošná priehľadnosť"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "SkutoÄná priehľadnosÅ¥ (vyžaduje kompozitné rozÅ¡Ãrenie X servera)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Kompozitné rozÅ¡Ãrenie nie je naÄÃtané"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Kompozitné rozÅ¡Ãrenie nie je dostupné"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>OSD Audacious</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "OSD pre Audacious - nastavenie"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Umiestnenie"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Animácia"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Text"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Výzdoba"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "SpúšťaÄ"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Rôzne"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 zoznamy skladieb"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious zoznamy skladieb (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>Farba</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Rozsah rozostrenia"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "Predvoľby:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "ÃroveÅ zdroja:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "Frekvencia pre vystrihnutie:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "Predvoľby:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "Analyzér spektra"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Audio CD zásuvný modul"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -797,171 +762,156 @@ msgstr ""
"\n"
"Toto bol Google Summer of Code 2007 projekt."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "Zariadenia"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "Rýchlosť disku:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "PrepÃsaÅ¥ zariadenie:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadáta</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "Použiť CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "Použiť CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "Namiesto CDDBP použiť HTTP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "Server: "
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "Cesta: "
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "Port: "
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "Audio CD zásuvný modul"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "Zlyhala inicializácia cdio podsystému."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "Neplatná URI %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "Stopa %d sa nenašla."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "Stopa %d je dátová stopa."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Zlyhalo otvorenie audio výstupu."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "Chyba pri ÄÃtanà audio CD."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Zvukové CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Zlyhalo CD zariadenie %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Nebolo nájdené žiadne spôsobilé CD zariadenie."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "Zlyhalo dokonÄenie inicializácie otvoreného CD zariadenia."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Zlyhalo naÄÃtanie prvého/posledného ÄÃsla skladby."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Nie je možné preÄÃtaÅ¥ zaÄiatok/koniec LSN pre stopu %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Zlyhalo vytvorenie cddb pripojenia."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Nepodaril sa dotaz na CDDB server"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Nepodaril sa dotaz na CDDB server: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Zlyhalo naÄÃtanie cddb info: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Mechanika je prázdna."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Nepodporovaný typ disku."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "Položky Audio CD menu"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "Prehrať CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "Pridať CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "Položky Audio CD menu"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>Kompresia</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Stredná hlasitosť:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Dynamický rozsah:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Dynamic Range Compression zásuvný modul pre Audacious\n"
-"Copyright 2010-2012 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "Dynamický rozsah kompresora"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -977,207 +927,226 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Hĺbky:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Výšky:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Predvolená dĺžka skladby:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Povoliť prevzorkovanie zvuku"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Prevzorkovať na:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "IgnorovaÅ¥ dĺžku z SPC znaÄiek"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "Predĺžiť dozvuk"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Dekodér konzolovej hudby"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-"PrelÃnanie sa nepodarilo, pretože skladby mali rôzny poÄet kanálov. Môžete\n"
-"použiÅ¥ ZmieÅ¡avaÄ kanálov a previesÅ¥ piesne na rovnaký poÄet kanálov."
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
-msgstr ""
-"PrelÃnanie zlyhalo, pretože skladby majú rozdielnu vzorkovaciu frekvenciu:\n"
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Na prevzorkovanie skladieb na rovnakú frekvenciu môžete použiť efektový "
-"modul âKonvertor vzorkovacej frekvencieâ."
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Crossfade zásuvný modul pre Audacious\n"
-"Copyright 2010-2012 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>PrelÃnanie</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "Prekrývanie:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "PrelÃnanie"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"PrelÃnanie sa nepodarilo, pretože skladby mali rôzny poÄet kanálov. Môžete\n"
+"použiÅ¥ ZmieÅ¡avaÄ kanálov a previesÅ¥ piesne na rovnaký poÄet kanálov."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"PrelÃnanie zlyhalo, pretože skladby majú rozdielnu vzorkovaciu frekvenciu:\n"
+"\n"
+"Na prevzorkovanie skladieb na rovnakú frekvenciu môžete použiť efektový "
+"modul âKonvertor vzorkovacej frekvencieâ."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Kryštalizér</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "Intenzita:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Crystalizer"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Cue Sheet zásuvný modul"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Vymazať"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "Zrušiť"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>Ozvena</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "Oneskorenie:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Spätná väzba:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "Hlasitosť:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Echo zásuvný modul\n"
-"napÃsal Johan Levin, 1999\n"
-"\n"
-"Surround echo napÃsal Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "Ozvena"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg zásuvný modul"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1194,55 +1163,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg zásuvný modul"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "Zápis do súboru zásuvný modul"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Formát výstupného súboru:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Nastaviť"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Ukladať do pôvodného adresára"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Ukladať do vlastného adresára"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "PrieÄinok s výstupnými súbormi:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "VybraÅ¥ prieÄinok"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "ZÃskaÅ¥ názov súboru z:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "pôvodných znaÄiek v súbore"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "názvu pôvodného súboru"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "NeodstraÅovaÅ¥ prÃponu názvu súboru"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Na zaÄiatok názvu súboru pridaÅ¥ ÄÃslo stopy"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1274,165 +1243,169 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "Zápis do súboru zásuvný modul"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Auto"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "Joint Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "Nastavenie MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Kvalita algoritmu:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Výstupná vzorkovacia frekvencia:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Dátový tok / kompresný pomer:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Dátový tok (kb/s):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "Kompresný pomer:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Zvukový režim:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Rôzne:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "VynútiÅ¥ prÃsnu zhodu s ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Ochrana pred chybami"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Kvalita"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "Povoliť VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Typ:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "Nastavenia VBR:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "Najmenšà dátový tok (kb/s):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "NajväÄšà dátový tok (kb/s):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "PrÃsne vynucovaÅ¥ najmenšà dátový tok"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "Nastavenia ABR:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Priemerný dátový tok (kb/s):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "ÃroveÅ kvality VBR:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "NezapisovaÅ¥ hlaviÄku Xing VBR"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "Parametre rámcov:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "PridaÅ¥ oznaÄenie autorských práv"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "PridaÅ¥ oznaÄenie originálu"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "Parametre ID3:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "VynútiÅ¥ pridanie znaÄiek verzie 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "PridávaÅ¥ iba znaÄky verzie 1"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "PridávaÅ¥ iba znaÄky verzie 2"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "ZnaÄky"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Nastavenie kodéra Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "ÃroveÅ kvality (0-10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC dekodér"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "bezstratový"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1444,11 +1417,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC dekodér"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1456,11 +1425,19 @@ msgstr ""
"GIO zásuvný modul pre Audacious\n"
"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO zásuvný modul"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1472,450 +1449,509 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
msgstr ""
-"Zásuvný modul pre klávesové skratky Gnome\n"
-"Ovládajte prehrávaÄ klávesovými skratkami Gnome.\n"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Klávesové skratky GNOME"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "ÄÃslo položky"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Názov"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Umelec"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Rok"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Album"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Stopa"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "Žáner"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Poradie vo fronte"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Dĺžka"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Cesta k súboru"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Názov súboru"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Vlastný názov"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Dátový tok"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Vyhľadávacà nástroj"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Ukotviť vľavo"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "Ukotviť vpravo"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Ukotviť hore"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "Ukotviť dole"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Uvolniť"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Zakázať"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Vyhľadávacà nástroj"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Otvoriť súbory ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "Otvoriť _URL ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "Prid_ať súbory ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "Pridať U_RL ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "_O programe ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Koniec"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Hrať"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "P_ozastaviť"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "Za_staviť"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "Pred_chádzajúca"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_Nasledujúca"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "O_pakovať"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "Ná_hodné prehrávanie"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Nep_okraÄovaÅ¥ podľa zoznamu skladieb"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "Zastaviť po tejto skladbe"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Informácie o skladbe ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "S_koÄiÅ¥ na Äas ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "SkoÄiÅ¥ na sk_ladbu ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Podľa _názvu"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "Podľa ÄÃ_sla stopy"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Podľa _umelca"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Podľa dátumu vy_dania"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Podľa _cesty k súboru"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Podľa vlastného ná_zvu"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "Obrátené poradie"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "Náhodné po_radie"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_Prehrať tento zoznam skladieb"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Obnoviť"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Zoradiť"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Odstrániť nedost_upné súbory"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Nový"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "Pre_menovať ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Importovať ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Exportovať ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "Správca_zoznamu skladieb ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Správca _fronty .."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Zo_silniť"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "S_tÃÅ¡iÅ¥"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Ekvalizér"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Zobraziť _panel s ponukou"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Zobraziť panel s i_nformáciami"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "ZobraziÅ¥ znázornenie oblasti informáciÃ"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Zobraziť panel so _stavom"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Súbor"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Prehrávanie"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "Zoznam sk_ladieb"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_Služby"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Výstup"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Zobrazenie"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "Pridať alebo odobrať z _fronty"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Vys_trihnúť"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_KopÃrovaÅ¥"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "V_ložiť"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Ozn_aÄiÅ¥ vÅ¡etko"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_Premenovať ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "Rozhranie GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "NapĺÅanie vyrovnávajúcej pamäte ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
@@ -1923,84 +1959,98 @@ msgstr[0] "%d kanálov"
msgstr[1] "%d kanál"
msgstr[2] "%d kanály"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "Režim jednej skladby."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Režim zoznamu skladieb."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "ZastaviÅ¥ po skonÄenà skladby."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Predchádzajúca skladba"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Prehrať"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "PozastaviÅ¥/PokraÄovaÅ¥"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Zastaviť"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Nasledujúca skladba"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "Vpred o 5 sekúnd"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "Späť o 5 sekúnd"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Stlmiť"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Zvýšenie hlasitosti"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "ZnÞenie hlasitosti"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Prejsť na súbor"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "Zobraziť OSD"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "Opakovanie"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "Náhodné prehrávanie"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "ZastaviÅ¥ po skonÄenà aktuálnej skladby"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(žiadne)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2011,15 +2061,11 @@ msgstr ""
"\n"
"Chcete pokraÄovaÅ¥?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "Priradenie tlaÄidiel myÅ¡i"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Nastavenie modulu Globálne klávesové skratky"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2027,23 +2073,27 @@ msgstr ""
"V textovom poli stlaÄte kombináciu klávesov.\n"
"Môžete priradiÅ¥ aj tlaÄÃtka na myÅ¡i."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Klávesové skratky:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>ÄinnosÅ¥:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Priradenie klávesu:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "Globálne klávesové skratky"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2069,60 +2119,51 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "Globálne klávesové skratky"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK výstup"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Založené na xmms-jack, ktorý napÃsal Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Port pre Audacious napÃsal Giacomo Lozito"
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK výstup"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "Nastavenia %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "Nastavenia hostiteľa LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "Cesty modulu:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2133,25 +2174,25 @@ msgstr ""
"Po pridanà novej cesty, stlaÄte Enter pre vyhľadanie nových modulov. </ "
"Small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Dostupné moduly:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "Povoliť"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Povolené moduly:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Nastavenie"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2159,49 +2200,15 @@ msgstr ""
"LADSPA Host pre Audacious\n"
"Copyright 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA Host"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr ""
-"%s: nie je možné inicializovať podporu LIRC\n"
-"\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: nie je možné naÄÃtaÅ¥ konfiguraÄný súbor LIRC\n"
-"%s: prosÃm preÄÃtajte si dokumentáciu k LIRC\n"
-"%s: ako správne vytvoriÅ¥ konfiguraÄný súbor\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: pokúšam sa znova pripojiť...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: neznámy prÃkaz \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: odpojené od LIRC\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: skúsim sa znova napojiť každých %d sekúnd...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC zásuvný modul"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2228,73 +2235,81 @@ msgstr ""
"\n"
"Pre viac informácià o LIRC, navÅ¡tÃvte http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Pripojenie</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Znovu sa pripojiť k serveru LIRC"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "PoÄkajte pred opätovným pripojenÃm:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC zásuvný modul"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki zásuvný modul"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Žiadne texty k dispozÃcii"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Chyba"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Nedá sa naÄÃtaÅ¥ %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Chyba"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Nedá sa analyzovať %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "Vyhľadáva sa text skladby..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "Chýba metadata skladby"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "Pripájanie na lyrics.wikia.com..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki zásuvný modul"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U zoznam skladieb"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Generátor taktov"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Generátor taktu: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Generátor taktu: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2308,11 +2323,11 @@ msgstr ""
"napr. tact://77 to play 77 beats per minute\n"
"alebo tact://60*3/4 to play 60 bpm in 3/4 tacts"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Generátor taktov"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "ZmieÅ¡avaÄ kanálov"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2320,152 +2335,184 @@ msgstr ""
"Channel Mixer zásuvný modul pre Audacious\n"
"Copyright 2011-2012 John Lindgren a MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>ZmieÅ¡avaÄ kanálov</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Výstupné kanály:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "ZmieÅ¡avaÄ kanálov"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS zásuvný modul"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Module Player) zásuvný modul"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr ""
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr ""
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr ""
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr ""
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr ""
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr ""
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Module Player) zásuvný modul"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Priestorový zvuk"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 zásuvný modul"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Priestorový zvuk"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 Server"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS zásuvný modul"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Zastavené"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious teraz neprehráva."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "Oznámenia na plochu"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2485,55 +2532,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "Oznámenia na plochu"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr ""
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Pozastaviť"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Nasledujúca"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Štandardné zariadenie"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 výstup"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Zvukové zariadenie:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Použiť iné zariadenie:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "Ulož hlasitosť medzi reláciami"
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "PovoliÅ¥ konverziu formátu prostrednÃctvom OSS."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "PovoliÅ¥ exkluzÃvny režim pre predchádzanie virtuálnemu zmieÅ¡avaniu."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2547,19 +2603,35 @@ msgstr ""
"Chcem poÄakovaÅ¥ ľuÄom z #audacious, najmä Tonymu Vroonovy a Johnovy "
"Lindgrenovy a samozrejme autorom predošlého OSS zásuvného modulu."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 výstup"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS zoznamy skladieb"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2 dekodér"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio výstup"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2595,11 +2667,68 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio výstup"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Predchádzajúca"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Opakovať"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Náhodné poradie"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "Konvertor vzorkovacej frekvencie"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2607,133 +2736,145 @@ msgstr ""
"Sample Rate Converter zásuvný modul pre Audacious\n"
"Copyright 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "PreskoÄ/opakuj vzorky"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Lineárna interpolácia"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Rýchla sinc interpolácia"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "Priemerná sinc interpolácia"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "Najlepšia sinc interpolácia"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Prevod</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Metóda:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Hodnotenie:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>Mapovanie hodnotenia</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "Použiť mapovanie hodnotenia"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "Konvertor vzorkovacej frekvencie"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr ""
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "Vyskytol sa problém s pripojenÃm k Last.fm. ProsÃm, skúste to neskôr."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr ""
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2744,11 +2885,7 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2756,7 +2893,11 @@ msgstr ""
"Audacious odteraz použÃva vylepÅ¡enú verziu doplnku Last.fm Scrobbler.\n"
"ProsÃm, skontrolujte Predvoľby doplnku Scrobbler."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL výstup"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2764,88 +2905,59 @@ msgstr ""
"SDL výstupný zásuvný modul pre Aduacious\n"
"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL výstup"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "Knižnica"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "Neznámy Umelec"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "Neznámy Album"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" na %s od %s"
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d album"
-msgstr[1] "%d álb"
-msgstr[2] "%d albumov"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-"%s\n"
-" %s, %d skladba"
msgstr[1] ""
-"%s\n"
-" %s, %d skladby"
msgstr[2] ""
-"%s\n"
-" %s, %d skladieb"
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
-"%s\n"
-" %d skladba od %s"
msgstr[1] ""
-"%s\n"
-" %d skladby od %s"
msgstr[2] ""
-"%s\n"
-" %d skladieb od %s"
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_Vytvoriť zoznam skladieb"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_Pridať do zoznamu skladieb"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "Vyhľadať knižnicu"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2853,679 +2965,769 @@ msgstr ""
"Pre import hudobnej knižnice do Audacious, vyberte prieÄinok a potom "
"kliknite na ikonu \"obnoviť\"."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Äakajte prosÃm ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "VybraÅ¥ prieÄinok"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Prehrávanie"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Zoznam skladieb"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Zobrazenie"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Opakovať"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Náhodné poradie"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "NeprehrávaÅ¥ ÄalÅ¡iu skladbu zo zoznamu"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Predchádzajúca"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Nový zoznam skladieb"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "Zobraziť editor zoznamu skladieb"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "Zobraziť ekvalizér"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Vždy navrchu"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Podľa názvu"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Podľa názvu súboru"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Odstrániť všetky"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "Vyprázdniť front"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Odstrániť nedostupné súbory"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Odstrániť duplikáty"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "OdstrániÅ¥ neoznaÄené"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "OdstrániÅ¥ oznaÄené"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Hľadanie a výber"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "Invertovať výber"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Zrušiť výber"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "OznaÄiÅ¥ vÅ¡etko"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Podľa albumu"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Podľa ÄÃsla stopy"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Podľa umelca"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Podľa albumu"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Podľa ÄÃsla stopy"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Premiešať poradie"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "Obrátiť poradie"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "Triediť výber"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Triediť zoznam"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Vystrihnúť"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "KopÃrovaÅ¥"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "Vložiť"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winamp Classic Interface"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Uložiť"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "NaÄÃtaÅ¥"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Predvoľby"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "NaÄÃtaÅ¥ predvoľbu"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "NaÄÃtaÅ¥ automatickú predvoľbu"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "Uložiť predvoľbu"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "Uložiť automatickú predvoľbu"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "Vymazať predvoľbu"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "Vymazať automatickú predvoľbu"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "V _okne prehrávaÄa:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Vyberte pÃsmo pre hlavné okno prehrávaÄa:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "V zozname _skladieb:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "Vyberte pÃsmo pre zoznam skladieb:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "PoužiÅ¥ bitmapové pÃsma (podporuje iba ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "Rolovať názov skladby obidvoma smermi"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analyzátor"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "Osciloskop"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Žiadne"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normálny"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "OheÅ"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Äiary"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Obdĺžniky"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "Najpomalšie"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "Pomaly"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Stredne"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Rýchlo"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "Najrýchlejšie"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Ľad"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Plynulý"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Všeobecné"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "Vizualizácia"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Predzosilnenie"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz "
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz "
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Ekvalizér Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "prejsť na %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Hlasitosť: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "Vyváženie: %d%% vľavo"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "Vyváženie: stred"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "Vyváženie: %d%% vpravo"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Ponuka s možnosťami"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Vypnúť âVždy navrchuâ"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "Zapnúť âVždy navrchuâ"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "Informácie o súbore"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "Režim jednej skladby."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Režim zoznamu skladieb."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "ZastaviÅ¥ po skonÄenà skladby."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "VyhľadaÅ¥ skladby v aktÃvnom zozname skladieb"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3537,57 +3739,61 @@ msgstr ""
"regulárnym výrazom nerozumiete, jednoducho zadajte ÄasÅ¥ textu, ktorý chcete "
"vyhľadať."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Názov: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Umelec: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Názov súboru: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Pred hľadanÃm vymazaÅ¥ predchádzajúci výber"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "Zhodujúce sa položky pridať do (odstrániť z) frontu"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "Zo zhodujúcich sa položiek vytvoriť nový zoznam skladieb"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Editor zoznamu skladieb"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d z %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "Zabalený vzhľad pre WinAMP 2.x"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "Nezabalený vzhľad pre WinAMP 2.x"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Nepodarilo sa vytvoriť adresár (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile zásuvný modul"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3627,84 +3833,72 @@ msgstr ""
"this program; if not, write to the Free Software Foundation, Inc., 51 "
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile zásuvný modul"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "O Sndio výstupnom zásuvnom module"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-"Sndio Output zásuvný modul\n"
-"\n"
-"napÃsal Thomas Pfaff <tpfaff at tp76.info>\n"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "Nepodporovaný formát"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-"Formát nie je podporovaný týmto zvukovým zariadenÃm.\n"
-"\n"
-"Skúste to znova prosÃm s bežiacim sndiod(1) serverom."
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio zariadenie"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(prázdne znamená predvolené)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "OK"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Zmena skladby"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "PrÃkaz, ktorý sa vykoná keÄ Audacious zaÄne prehrávaÅ¥ novú skladbu."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>Parametre predávané shellu by mali byť uzatvorené do "
+"úvodzoviek. NereÅ¡pektovanie tejto rady predstavuje bezpeÄnostné riziko.</"
+"span>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "PrÃkaz:"
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "PrÃkaz, ktorý sa vykoná na konci skladby."
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
msgstr ""
-"PrÃkaz, ktorý sa vykoná, keÄ Audacious dosiahne koniec zoznamu skladieb."
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
msgstr ""
-"PrÃkaz, ktorý sa vykoná pri zmene názvu skladby (t.j. pre názvy v sieÅ¥ových "
-"prúdoch)."
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr ""
+
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3718,36 +3912,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Môžete použiť nasledujúce formátovacie reťazce,\n"
-"ktoré budú pri spustenà prÃkazu nahradené (nie vÅ¡etky\n"
-"sú užitoÄné pre prÃkaz spúšťaný na konci zoznamu skladieb).\n"
-"\n"
-"%F: Frekvencia (v hertzoch)\n"
-"%c: PoÄet kanálov\n"
-"%f: Názov súboru (celá cesta)\n"
-"%l: Dĺžka (v milisekundách)\n"
-"%n alebo %s: Názov skladby\n"
-"%r: Dátový tok (v bitoch za sekundu)\n"
-"%t: PozÃcia v zozname skladieb (%02d)\n"
-"%p: Práve sa hrá (1 alebo 0)\n"
-"%a: Umelec\n"
-"%b: Album\n"
-"%T: Názov stopy"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>Parametre predávané shellu by mali byť uzatvorené do "
-"úvodzoviek. NereÅ¡pektovanie tejto rady predstavuje bezpeÄnostné riziko.</"
-"span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "PrÃkazy"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3756,51 +3930,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr ""
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "Rýchlosť a výška"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>Rýchlosť a výška</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Rýchlosť"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "Výška"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "Rýchlosť a výška"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Stavová ikona"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3818,39 +3992,39 @@ msgstr ""
"Tento zásuvný modul poskytuje stavovú ikonu, umiestnenú v\n"
"stavovej oblasti správcu okien."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Rolovanie kolieskom myši</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Zmeniť hlasitosť"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Zmeniť prehrávanú skladbu"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>Ostatné nastavenia</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Zakázať vyskakovacie okno"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Zatvor do systémového zásobnÃka"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "PokraÄovaÅ¥ v zozname skladieb ak sa posúva smerom hore"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Stavová ikona"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Stereo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3860,24 +4034,24 @@ msgstr ""
"\n"
"NapÃsal Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra Stereo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Generátor tónov"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Generátor tónov: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3891,15 +4065,11 @@ msgstr ""
"Pre použitie, pridajte URL: tone://frequency1;frequency2;frequency3;...\n"
"napr.. tone://2000;2005 prehrá 2000 Hz tón a 2005 Hz tón"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Generátor tónov"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Odstránenie hlasu"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3937,11 +4107,35 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis dekodér"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX dekodér"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -3951,19 +4145,19 @@ msgstr ""
"Založené na in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious zásuvný modul napÃsal Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX dekodér"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack dekodér"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "stratový (hybrid)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "stratový"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -3973,14 +4167,18 @@ msgstr ""
"\n"
"ÄasÅ¥ kódu zásuvného modulu napÃsal Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack dekodér"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF dekodér"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "XML Shareable Playlists (XSPF)"
diff --git a/po/sr.po b/po/sr.po
index 94934fc7125e..0b6951523e4f 100644
--- a/po/sr.po
+++ b/po/sr.po
@@ -3,13 +3,14 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
+# ÐиÑоÑлав ÐÐ¸ÐºÐ¾Ð»Ð¸Ñ <miroslavnikolic at rocketmail.com>, 2014-2015
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-05 19:51+0000\n"
+"Last-Translator: ÐиÑоÑлав ÐÐ¸ÐºÐ¾Ð»Ð¸Ñ <miroslavnikolic at rocketmail.com>\n"
"Language-Team: Serbian (http://www.transifex.com/projects/p/audacious/"
"language/sr/)\n"
"Language: sr\n"
@@ -19,40 +20,28 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "моно"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "ÑÑеÑео"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "окÑÑжеÑе"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "ÐÐЦ (ÐÐ4) декодеÑ"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "ÐÐЦ (СиÑови) декодеÑ"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "Ðд пÑикÑÑÑак (ÐдÐибл пÑогÑам)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "низовни"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "Ðд пÑикÑÑÑак (ÐдÐибл пÑогÑам)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "ÐлаÑм"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "ÐодеÑи алаÑм ..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -62,11 +51,7 @@ msgstr ""
"\n"
"ÐÑвобиÑни аÑÑоÑи ÑÑ Ðдам Фикин и ÐаниÑел СÑоден."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "ÐлаÑм"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -107,7 +92,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -147,7 +132,7 @@ msgstr ""
" ÐокÑеÑе Ð¾Ð²Ñ Ð½Ð°ÑÐµÐ´Ð±Ñ Ð·Ð° вÑеме алаÑма.\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -173,385 +158,390 @@ msgstr ""
" ÑпиÑиÑе подÑеÑник Ñ Ð¿Ð¾Ñе и ÑÑиклиÑаÑÑе\n"
" квадÑаÑÐ¸Ñ Ð°ÐºÐ¾ желиÑе да бÑде пÑиказиван."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Ðво Ñе Ð²Ð°Ñ Ð¿Ð¾Ð·Ð¸Ð² за бÑÑеÑе."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "ÐÐ°Ñ Ð¿Ð¾Ð´ÑеÑник за Ð´Ð°Ð½Ð°Ñ Ñе..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "ÐодÑеÑник"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "ÐонедеÑак"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "УÑоÑак"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "СÑеда"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "ЧеÑвÑÑак"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "ÐеÑак"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "СÑбоÑа"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "ÐедеÑа"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "ÐодеÑаваÑа алаÑма"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "У _ÑедÑ"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "_ÐÑкажи"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "ÐÑеме"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "ÐкÑивиÑÐ°Ñ Ð°Ð»Ð°Ñм Ñ (оÑновно):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "ÑаÑова"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "УÑиÑÐ°Ñ Ð½Ð°ÐºÐ¾Ð½:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "ÑаÑ(а)"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "минÑÑа"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "ÐзабеÑиÑе коÑим данима Ñе Ñе акÑивиÑаÑи алаÑм"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Ðан"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "ÐÑновно"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Ðани"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "ÐÑÑезаваÑе"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "ÑекÑнде"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "ÐаÑина"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "ÐапоÑни пÑи"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "ÐавÑÑи пÑи"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "ТÑенÑÑно"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "ÐодаÑна наÑедба"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "ÑкÑÑÑи"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "СпиÑак нÑмеÑа (необавезно)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "ÐзабеÑиÑе ÑпиÑак нÑмеÑа"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "ÐпÑиÑе"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "ШÑа знаÑе ове опÑиÑе?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "ÐомоÑ"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "ÐÐ¼Ð¾Ñ Ð°Ð»Ð±Ñма"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "ÐÐ¼Ð¾Ñ Ð°Ð»Ð±Ñма (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "Ðзлаз ÐÐСÐ-е"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ÐÑикÑÑÑак излаза ÐÐСÐ-е за ÐезоÑника\n"
+"ÐÑÑоÑÑка пÑава 2009-2012 Ðон ÐиндгÑин\n"
+"\n"
+"ÐаÑ
ваÑÑÑем Ñе ÐилиÑÐ°Ð¼Ñ ÐиÑкокÑ, аÑÑоÑÑ ÐРпÑикÑÑÑка излаза ÐÐСÐ-е, ÑиÑи Ñе "
+"код ÑлÑжио као ÑÐ·Ð¾Ñ ÐºÐ°Ð´Ð° ÑпÑÑÑÑво ÐÐСÐ-е ниÑе било довоÑно."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(без опиÑа)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "ÐÑновни ÐЦРÑÑеÑаÑ"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "ÐÑновни ÑÑеÑÐ°Ñ Ð¼ÐµÑаÑа"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "ÐЦРÑÑеÑаÑ:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "УÑеÑÐ°Ñ Ð¼Ð¸ÐºÑеÑа:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "ÐÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼ÐµÑаÑа:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "РеÑиÑе ÑÑви пÑекид"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "ÐÐÐÐÐ-ÐÑикÑÑÑак (ÐÐÐРпÑогÑам)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"ÐÑикÑÑÑак излаза ÐÐСÐ-е за ÐезоÑника\n"
-"ÐÑÑоÑÑка пÑава 2009-2012 Ðон ÐиндгÑин\n"
+"ÐÐÐÐÐ-ÐÑикÑÑÑак\n"
+"ÐодÑлаÑни ÐÐÐРмÑзиÑки пÑогÑам\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"ÐаÑ
ваÑÑÑем Ñе ÐилиÑÐ°Ð¼Ñ ÐиÑкокÑ, аÑÑоÑÑ ÐРпÑикÑÑÑка излаза ÐÐСÐ-е, ÑиÑи Ñе "
-"код ÑлÑжио као ÑÐ·Ð¾Ñ ÐºÐ°Ð´Ð° ÑпÑÑÑÑво ÐÐСÐ-е ниÑе било довоÑно."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "Ðзлаз ÐÐСÐ-е"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "ÐÐÐÐÐ-ÐÑикÑÑÑак (ÐÐÐРпÑогÑам)"
+"ÐапиÑао га Ñе Ðакомо ÐоÑиÑо\n"
+"< james at develia.org >\n"
+"\n"
+"ÐоÑебно ÑÑ Ð·Ð°ÑлÑжни...\n"
+"\n"
+"ÐÐ»ÐµÐ¼ÐµÐ½Ñ ÐÐ°Ð´Ð¸Ñ Ð¸ ÐаÑоÑлав ÐиÑела\n"
+"због ÑиÑ
овиÑ
пÑогÑама âaplaymidiâ и âamixerâ; коÑи\n"
+"ÑÑ Ð²Ñло коÑиÑни, Ñз âalsa-lib docsâ, како биÑмо\n"
+"Ñазнали виÑе о ÐÐСРÐÐÐÑÑ\n"
+"\n"
+"ÐлÑÑедо СпадаÑина\n"
+"коÑи Ñе ÑÑадио леп логоÑип ÐÐÐÐ ÑаÑÑаÑÑÑе \n"
+"\n"
+"Тони ÐÑÑн\n"
+"због одлиÑне помоÑи за алÑа ÑеÑÑиÑаÑе"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "ÐÑепиÑи оÑновно поÑаÑаÑе:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
-msgstr "ÐÑепиÑи оÑÐ½Ð¾Ð²Ð½Ñ Ð¿Ð¾Ð»Ð¸ÑониÑÑ: "
+msgstr "ÐÑепиÑи оÑÐ½Ð¾Ð²Ð½Ñ Ð¿Ð¾Ð»Ð¸ÑониÑÑ:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "ÐÑепиÑи оÑновни одÑек:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "УкÑ."
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "ÐÑепиÑи оÑновни Ñ
оÑ:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>ÐÑÑÑаÑе</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "ÐÑемеÑÑаÑ:"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "полÑÑонови"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "ÐÑомена бÑбÑа:"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>ÐапÑедно</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "бÑоÑеви ноÑе"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "ÐзвÑÑи напомене из ÐÐÐРдаÑоÑеке"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "ÐÑеÑкоÑи водеÑÑ ÑиÑинÑ"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "ÐзвÑÑи ÑекÑÑ Ð¿ÐµÑме из ÐÐÐРдаÑоÑеке"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "ÐÑеÑкоÑи пÑаÑеÑÑ ÑиÑинÑ"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>СаÑндФонÑ</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>СинÑиÑаÑзеÑ</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr "ÐÑоÑок ÑзоÑка:"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "ÐÐÐÐРпÑикÑÑÑак â изабеÑиÑе СаÑÐ½Ð´Ð¤Ð¾Ð½Ñ Ð´Ð°ÑоÑекÑ"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "ÐÑ_кажи"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
-msgstr "_ÐÑвоÑи"
+msgstr "ÐÑ_воÑи"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Ðазив даÑоÑеке"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "ÐелиÑина (баÑÑова)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Ðазив:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
-msgstr "<span size=\"smaller\"> ÐÐÐÐ ÐнÑоÑмаÑиÑе </span>"
+msgstr "<span size=\"smaller\"> ÐÐÐРподаÑи </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "ÐапиÑ:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "ТÑаÑаÑе (msec):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "ÐÑÐ¾Ñ Ð½ÑмеÑа:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "пÑоменÑиво"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "ÐÐÐ:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "ÐÐÐ (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Ðив вÑеме:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> ÐÐÐРкоменÑаÑи и ÑекÑÑови пеÑама </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* нема доÑÑÑпниÑ
коменÑаÑа Ñ Ð¾Ð²Ð¾Ñ ÐÐÐРдаÑоÑеÑи *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* нема доÑÑÑпниÑ
ÑекÑÑова пеÑама Ñ Ð¾Ð²Ð¾Ñ ÐÐÐРдаÑоÑеÑи *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_ÐаÑвоÑи"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (неиÑпÑаван УТФ-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Ð ÐÐÐÐРпÑикÑÑÑкÑ"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "ÐÐÐÐРпÑикÑÑÑак"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"ÐодÑлаÑни ÐÐÐРмÑзиÑки пÑогÑам\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"ÐапиÑао га Ñе Ðакомо ÐоÑиÑо\n"
-"< james at develia.org >\n"
-"\n"
-"\n"
-"ÐоÑебно ÑÑ Ð·Ð°ÑлÑжни...\n"
-"\n"
-"ÐÐ»ÐµÐ¼ÐµÐ½Ñ ÐÐ°Ð´Ð¸Ñ Ð¸ ÐаÑоÑлав ÐиÑела\n"
-"због ÑиÑ
овиÑ
пÑогÑама âaplaymidiâ и âamixerâ; коÑи\n"
-"ÑÑ Ð²Ñло коÑиÑни, Ñз âalsa-lib docsâ, како биÑмо\n"
-"Ñазнали виÑе о ÐÐСРÐÐÐÑÑ\n"
-"\n"
-"ÐлÑÑедо СпадаÑина\n"
-"коÑи Ñе ÑÑадио леп логоÑип ÐÐÐÐ ÑаÑÑаÑÑÑе \n"
-"\n"
-"Тони ÐÑÑн\n"
-"због одлиÑне помоÑи за алÑа ÑеÑÑиÑаÑе"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -561,153 +551,154 @@ msgid ""
"Based in part on Evan Martin's Ghosd library:\n"
"http://neugierig.org/software/ghosd/"
msgstr ""
+"ÐÐÐ ÐезоÑника\n"
+"http://www.develia.org/projects.php?p=audacious#aosd\n"
+"\n"
+"ÐапиÑао га Ñе Ðакомо ÐоÑиÑо < james at develia.org >\n"
+"\n"
+"Ðелом Ñе заÑнован на библиоÑеÑи âGhosdâ коÑÑ Ñе напиÑао Ðван ÐаÑÑин\n"
+"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "ÐÐСР(ÐÑиказ на екÑанÑ)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ÐÑавоÑгаоник"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "ÐаобÑени пÑавоÑгаоник"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "УдÑбÑен пÑавоÑгаоник"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "ÐиÑÑа"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "ÐоÑеÑак ÑепÑодÑкÑиÑе"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "ÐÑиказÑÑе ÐСРкада поÑиÑе ÑепÑодÑкÑиÑа пеÑме."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "ÐÑомена наÑлова"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
-msgstr ""
-"ÐÑиказÑÑе ÐСРкада Ñе, Ñ ÑÐ¾ÐºÑ ÑепÑодÑкÑиÑе, измени наÑлов пеÑме али назив "
-"даÑоÑеке оÑÑане иÑÑи. Ðво Ñе Ñглавном коÑиÑно за пÑиказиваÑе измена Ñ "
-"наÑловима Ñ Ð¸Ð½ÑеÑÐ½ÐµÑ Ñоковима."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
+msgstr "ÐÑебаÑÑÑе ÐСРкада Ñе пÑомени наÑлов пеÑме (за инÑеÑÐ½ÐµÑ Ñокове)."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "ÐаÑзиÑаÑе"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "ÐÑиказÑÑе ÐСРкада Ñе ÑепÑодÑкÑиÑа пÑивÑемено заÑÑÑавÑена."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "ÐÑпаÑзиÑаÑе"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "ÐÑиказÑÑе ÐСРкада Ñе ÑепÑодÑкÑиÑа поново покÑенÑÑа."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "ÐоÑÑавÑаÑе"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "РелаÑиван Ñ
оÑизонÑални помеÑаÑ:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "РелаÑиван веÑÑикални помеÑаÑ:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "ÐаÑвеÑа ÑиÑина пÑиказа:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "ÐпÑиÑа виÑе мониÑоÑа"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "ÐÑикажи ÐСРна:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "Ñвим мониÑоÑима"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "на мониÑоÑÑ Ð±Ñ. %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "ÐÑеме ÑÑаÑаÑа (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "ÐÑиказ:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "ÐоÑавÑиваÑе:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "ÐÑÑезаваÑе:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Словни ликови"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "ÐиÑмо %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Сенка"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "СÑил иÑÑÑÑаваÑа"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "ÐоÑе"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "ÐоÑа %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "ÐмогÑÑи акÑивиÑаÑе"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "ÐогаÑаÑ"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "ÐÑкÑивен Ñе композиÑни ÑпÑавник"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -717,112 +708,112 @@ msgstr ""
"оÑим ако знаÑе да Ñе Ñедан Ð²ÐµÑ Ð¿Ð¾ÐºÑенÑÑ, молим покÑениÑе композиÑног "
"ÑпÑавника ÑÐµÑ Ñ ÑÑпÑоÑном ÐСРнеÑе ÑадиÑи иÑпÑавно"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "ÐомпозиÑни ÑпÑавник ниÑе поÑÑебан за Ð»Ð°Ð¶Ð½Ñ Ð¿ÑовидноÑÑ"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "ÐÑовидноÑÑ"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Ðажна пÑовидноÑÑ"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "СÑваÑна пÑовидноÑÑ (заÑ
Ñева Ð¥ композиÑно пÑоÑиÑеÑе)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "ÐомпозиÑно пÑоÑиÑеÑе ниÑе ÑÑиÑано"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "ÐомпозиÑно пÑоÑиÑеÑе ниÑе доÑÑÑпно"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>ÐезоÑник â ÐСÐ</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "ÐезоÑник ÐСРâ подеÑаваÑа"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "_ÐÑпÑобаÑ"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "_ÐодеÑи"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "ÐоложаÑ"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "ÐнимаÑиÑа"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "ТекÑÑ"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "ÐекоÑаÑиÑа"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "УкÑÑÑиваÑе"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "ÐÑÑало"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "ÐÑпÑобаÑ"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "ÐСÐкÑв3 ÑпиÑак нÑмеÑа"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ÐСÐкÑв1/ÐСÐкÑв2 ÑпиÑкови нÑмеÑа"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "ÐезоÑникови ÑпиÑкови нÑмеÑа (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>ÐоÑе</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Ðбим замÑÑеÑа"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "ÐоÑÐµÑ ÑÑеÑеоÑонÑки-Ñ-бинаÑÑални (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "ÐÑеÑподеÑаваÑа:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Ðиво довода:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "УÑеÑÑаноÑÑ Ð¸ÑеÑаÑа:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "ÐÑеÑподеÑаваÑа:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "ÐоÑÐµÑ ÑÑеÑеоÑонÑки-Ñ-бинаÑÑални (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "ÐнализаÑÐ¾Ñ ÑпекÑÑа"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "ÐÑикÑÑÑак звÑÑног ЦÐ-а"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -842,171 +833,158 @@ msgstr ""
"\n"
"ÐеÑе Ñо ÐÑгл леÑо пÑоÑекÑа Ðôд 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>УÑеÑаÑ</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "ÐÑзина ÑиÑаÑа:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "ÐÑепиÑи ÑÑеÑаÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>ÐеÑаподаÑи</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "ÐоÑиÑÑи ЦÐ-ÑекÑÑ"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "ÐоÑиÑÑи ЦÐÐÐ"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "ÐоÑиÑÑи ХТТРÑмеÑÑо ЦÐÐÐÐ-а"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "СеÑвеÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "ÐÑÑаÑа:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "ÐÑикÑÑÑник:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "ÐÑикÑÑÑак звÑÑног ЦÐ-а"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "ÐиÑам ÑÑпео да запоÑнем ÑдÑи подÑиÑÑем."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "ÐеиÑпÑавна пÑÑаÑа â%sâ."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "ÐиÑам пÑонаÑао нÑмеÑÑ â%dâ."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "ÐÑмеÑа â%dâ Ñе Ð·Ð°Ð¿Ð¸Ñ Ð¿Ð¾Ð´Ð°Ñака."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "ÐиÑам ÑÑпео да оÑвоÑим излаз звÑка."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "ÐÑеÑка ÑиÑаÑа звÑÑног диÑка."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "ÐÑдио ЦÐ"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "ÐÑмеÑа %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "ÐиÑам ÑÑпео да оÑвоÑим ЦРÑÑеÑÐ°Ñ â%sâ."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "ÐиÑам пÑонаÑао ÑÑеÑÐ°Ñ Ð·Ð° ÑиÑаÑе ЦÐ-а."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "ÐиÑам ÑÑпео да завÑÑим покÑеÑаÑе оÑвоÑеног ЦРÑÑеÑаÑа."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "ÐиÑам ÑÑпео да пÑонаÑем бÑÐ¾Ñ Ð¿Ñве/поÑледÑе нÑмеÑе."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Ðе Ð¼Ð¾Ð³Ñ Ð´Ð° пÑоÑиÑам поÑеÑак/кÑÐ°Ñ ÐСÐ-а за нÑмеÑÑ â%dâ."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "ÐиÑам ÑÑпео да напÑавим Ð²ÐµÐ·Ñ Ñа Ñд базом подаÑака."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "ÐиÑам ÑÑпео да пÑопиÑам ÑеÑÐ²ÐµÑ Ð±Ð°Ð·Ðµ подаÑака ЦÐ-а"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "ÐиÑам ÑÑпео да пÑопиÑам ÑеÑÐ²ÐµÑ Ð±Ð°Ð·Ðµ подаÑака ЦÐ-а: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "ÐиÑам ÑÑпео да пÑоÑиÑам обавеÑÑеÑе базе подаÑака Ñд-а: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "УÑеÑÐ°Ñ Ñе пÑазан."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "ÐеподÑжана вÑÑÑа диÑка."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "СÑавке избоÑника звÑÑног ЦÐ-а"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "ÐÑÑÑи ЦÐ"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "ÐÐ¾Ð´Ð°Ñ Ð¦Ð"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "СÑавке избоÑника звÑÑног ЦÐ-а"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>СажимаÑе</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Ðлавна ÑаÑина:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "ÐинамиÑки опÑег:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"ÐÑикÑÑÑак ÑажимаÑа динамиÑког опÑега за ÐезоÑника\n"
-"ÐÑÑоÑÑка пÑава 2010-2012 Ðон ÐиндгÑин"
+"ÐÑÑоÑÑка пÑава 2010-2014 Ðон ÐиндгÑин"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "СажимаÑÐµÑ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñког опÑега"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1021,206 +999,238 @@ msgstr ""
"ÐилиÑам ÐиÑкок <nenolod at dereferenced.org>, \n"
"Ð¨Ð°Ñ ÐÑин <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ÐиÑки Ñонови:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "ÐиÑоки Ñонови:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "ÐдÑек:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "ÐÑновно ÑÑаÑаÑе пеÑме:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>Ðоновно ÑзоÑковаÑе</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "УкÑÑÑи поновно ÑзоÑковаÑе"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "ÐÑоÑок поновног ÑзоÑковаÑа:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>СÐЦ</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "ÐанемаÑи ÑÑаÑаÑе из СÐЦ ознака"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "ÐовеÑÐ°Ñ Ð¾Ð´Ñек"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Ðонзолни мÑзиÑки Ð´ÐµÐºÐ¾Ð´ÐµÑ Ð¸Ð³Ñе"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"ÐоÑÑепени пÑелаз ниÑе ÑÑпео ÑÐµÑ Ñе пеÑма имала ÑазлиÑÐ¸Ñ Ð±ÑÐ¾Ñ ÐºÐ°Ð½Ð°Ð»Ð°. ÐожеÑе "
-"да коÑиÑÑиÑе ÐеÑаÑа канала да пÑеÑвоÑиÑе пеÑме на иÑÑи бÑÐ¾Ñ ÐºÐ°Ð½Ð°Ð»Ð°."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "ÐоÑеâаÑдио излаз"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"ÐоÑÑепени пÑелаз ниÑе ÑÑпео ÑÐµÑ Ñе пеÑма имала ÑазлиÑÐ¸Ñ Ð¿ÑоÑок ÑзоÑка. "
-"ÐожеÑе да коÑиÑÑиÑе ÐÑеÑваÑаÑа пÑоÑока ÑзоÑка да пÑеÑвоÑиÑе пеÑме на иÑÑи "
-"пÑоÑок ÑзоÑка."
+"ÐÑикÑÑÑак ÐоÑе-аÑдио излаза за ÐезоÑника\n"
+"ÐÑÑоÑÑка пÑава 2014 ÐилиÑам ÐиÑкок\n"
+"\n"
+"ÐаÑновано на пÑикÑÑÑÐºÑ Ð¡ÐРизлаза за ÐезоÑника:\n"
+"ÐÑÑоÑÑка пÑава 2010 Ðон ÐиндгÑин"
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "ÐоÑиÑÑи иÑкÑÑÑиви Ñежим"
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"ÐÑикÑÑÑак поÑÑепеног пÑелаза за ÐезоÑника\n"
-"ÐÑÑоÑÑка пÑава 2010-2012 Ðон ÐиндгÑин"
+"ÐÑÑоÑÑка пÑава 2010-2014 Ðон ÐиндгÑин"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>ÐоÑÑепени пÑелаз</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "ÐÑи ÑамоÑÑÐ°Ð»Ð½Ð¾Ñ Ð¿Ñомени пеÑме"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "ÐÑеклапаÑе:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "ÐÑи пÑемоÑаваÑÑ Ð¸Ð»Ð¸ ÑÑÑÐ½Ð¾Ñ Ð¿Ñомени пеÑме"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>СавеÑ</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+"Ðа боÑи поÑÑепени пÑелаз, ÑкÑÑÑиÑе\n"
+"деÑÑÑво ÑклаÑаÑа ÑиÑине."
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "ÐоÑÑепени пÑелаз"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"ÐоÑÑепени пÑелаз ниÑе ÑÑпео ÑÐµÑ Ñе пеÑма имала ÑазлиÑÐ¸Ñ Ð±ÑÐ¾Ñ ÐºÐ°Ð½Ð°Ð»Ð°. ÐожеÑе "
+"да коÑиÑÑиÑе ÐеÑаÑа канала да пÑеÑвоÑиÑе пеÑме на иÑÑи бÑÐ¾Ñ ÐºÐ°Ð½Ð°Ð»Ð°."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"ÐоÑÑепени пÑелаз ниÑе ÑÑпео ÑÐµÑ Ñе пеÑма имала ÑазлиÑÐ¸Ñ Ð¿ÑоÑок ÑзоÑка. "
+"ÐожеÑе да коÑиÑÑиÑе ÐÑеÑваÑаÑа пÑоÑока ÑзоÑка да пÑеÑвоÑиÑе пеÑме на иÑÑи "
+"пÑоÑок ÑзоÑка."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>ÐÑиÑÑализаÑоÑ</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "ÐакоÑÑ:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "ÐÑиÑÑализаÑоÑ"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "ÐÑикÑÑÑак âcueâ Ñабеле"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "ÐбÑиÑи даÑоÑеке"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "ÐÑеÑка пÑемеÑÑаÑа â%sâ Ñ ÑмеÑе: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "ÐÑеÑка бÑиÑаÑа â%sâ: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "ÐÑеÑка бÑиÑаÑа â%sâ: ниÑе меÑна даÑоÑека."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "Ðа ли желиÑе да пÑемеÑÑиÑе изабÑане даÑоÑеке Ñ ÑмеÑе?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "ÐÑемеÑÑи Ñ ÑмеÑе"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "Ðа ли желиÑе ÑÑаÑно да обÑиÑеÑе изабÑане даÑоÑеке?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "ÐбÑиÑи"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "ÐÑкажи"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "ÐбÑиÑи даÑоÑеке"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "ÐбÑиÑиÑе изабÑане даÑоÑеке"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>ÐаÑин бÑиÑаÑа</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "ÐÑемеÑÑиÑе Ñ ÑмеÑе ÑмеÑÑо да одмаÑ
обÑиÑеÑе"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+"ÐÑикÑÑÑак одÑека\n"
+"ÐÑÑÐ¾Ñ ÐоÑ
ан Ðевин 1999\n"
+"ÐдÑек окÑÑжеÑа Ñе напиÑао ÐаÑл ван Шаик, 1999\n"
+"Ðа ÐезоÑника ÑÑ Ð³Ð° оÑвежили ÐилиÑам ÐиÑкок и Ðон ÐиндгÑен, 2010-2014"
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>ÐдÑек</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "ÐаÑÑоÑ:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Ðдзив:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "ÐаÑина звÑка:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"ÐÑикÑÑÑак одÑека\n"
-"ÐÑÑÐ¾Ñ ÐоÑ
ан Ðевин 1999\n"
-"\n"
-"ÐкÑÑжеÑе одÑека Ñе напиÑао ÐаÑл ван Шаик, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "ÐдÑек"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "ÐÑикÑÑÑак ФФмпег-а"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1236,55 +1246,55 @@ msgstr ""
"ÐилиÑам ÐиÑкок <nenolod at nenolod.net>\n"
"ÐаÑи ХамалаÑнен <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "ÐÑикÑÑÑак ФФмпег-а"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "ÐÑикÑÑÑак запиÑиваÑа даÑоÑека"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "ФоÑÐ¼Ð°Ñ Ð¸Ð·Ð»Ð°Ð·Ð½Ðµ даÑоÑеке:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "ÐодеÑи"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "СаÑÑÐ²Ð°Ñ Ñ Ð¾Ñигиналном диÑекÑоÑиÑÑмÑ"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "СаÑÑÐ²Ð°Ñ Ñ Ð¿ÑоизвоÑном диÑекÑоÑиÑÑмÑ"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "ФаÑÑикла излазне даÑоÑеке:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "ÐзабеÑиÑе ÑаÑÑиклÑ"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Ðабави име даÑоÑеке из:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "СÑвоÑи назив даÑоÑеке из:"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "ознаке оÑигиналне даÑоÑеке"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "ÐзвоÑне ознаке даÑоÑеке"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "назива оÑигиналне даÑоÑеке"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "ÐзвоÑног назива даÑоÑеке"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Ðе одÑÐ·Ð¸Ð¼Ð°Ñ Ð¿ÑоÑиÑеÑе назива даÑоÑеке"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "УкÑÑÑи пÑоÑиÑеÑе извоÑног назива даÑоÑеке"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "ÐÑÐ¸Ð´Ð¾Ð´Ð°Ñ Ð±ÑÐ¾Ñ Ð½ÑмеÑе Ð½Ð°Ð·Ð¸Ð²Ñ Ð´Ð°ÑоÑеке"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr "СÑави бÑÐ¾Ñ Ð½ÑмеÑе назива даÑоÑеке"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1316,165 +1326,169 @@ msgstr ""
"âFree Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA "
"02110-1301, USAâ."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "ÐÑикÑÑÑак запиÑиваÑа даÑоÑека"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "СамоÑÑално"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "УдÑÑжени ÑÑеÑео"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "СÑеÑео"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Ðоно"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "ÐÐ3 подеÑаваÑа"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "У _ÑедÑ"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "ÐвалиÑÐµÑ Ð°Ð»Ð³Ð¾ÑиÑма:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "ÐÑоÑок ÑзоÑка излаза:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr "Ðзлазни пÑоÑок ÑзоÑка:"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
msgstr "ÐÑоÑок биÑа / ÐÐ´Ð½Ð¾Ñ ÑажимаÑа:"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ÐÑоÑок биÑа (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "ÐÐ´Ð½Ð¾Ñ ÑажимаÑа:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Режим звÑка:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
msgstr "Разно:"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "ÐÑиÑили ÑÑÑого ÐСРпоÑÑоваÑе"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr "ÐÑимоÑÐ°Ñ Ð¸Ð·ÑиÑиÑÑ ÐСРÑаглаÑноÑÑ"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "ÐÑеÑка заÑÑиÑе"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "ÐвалиÑеÑ"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
-msgstr "УкÑÑÑи ÐÐÐ /ÐÐÐ "
+msgstr "УкÑÑÑи ÐÐÐ/СÐÐ"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "ÐÑÑÑа:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
-msgstr "ÐÐРопÑиÑе:"
+msgstr "ÐпÑиÑе ÐÐÐ-а:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "ÐаÑмаÑи пÑоÑок биÑа (kb/s):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "ÐаÑвеÑи пÑоÑок биÑа (kb/s):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "СÑÑого ÑпÑоведи наÑмаÑи пÑоÑок биÑа"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
-msgstr "ÐÐРопÑиÑе:"
+msgstr "ÐпÑиÑе СÐÐ-а:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
-msgstr "ÐÑоÑеÑни пÑоÑок биÑа (kb/s):"
+msgstr "СÑедÑи пÑоÑок биÑа (kb/s):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
-msgstr "Ðиво ÐÐРквалиÑеÑа:"
+msgstr "Ðиво квалиÑеÑа ÐÐÐ-а:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Ðе запиÑÑÑ Ð¥Ð¸Ð½Ð³ ÐÐРзаглавÑе"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "ÐзоÑÑави ÐкÑинг заглавÑе ÐÐÐ-а"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
-msgstr "ÐÐÐ /ÐÐÐ "
+msgstr "ÐÐÐ/СÐÐ"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr "ÐаÑамеÑÑи кадÑа:"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "ÐзнаÑи као аÑÑоÑÑко пÑаво"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "ÐзнаÑи као оÑигинал"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "ÐÐ3 паÑамеÑÑи:"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "ÐÑиÑили додаваÑе ознаке издаÑа 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "ÐÐ¾Ð´Ð°Ñ Ñамо в1 ознакÑ"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "ÐÐ¾Ð´Ð°Ñ Ñамо в2 ознакÑ"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Ðзнаке"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "ÐодеÑаваÑе ÐоÑÐ±Ð¸Ñ ÑиÑÑеÑа"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Ðиво квалиÑеÑа (0 â 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "ФÐÐЦ декодеÑ"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "без гÑбиÑака"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1486,11 +1500,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "ФÐÐЦ декодеÑ"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1498,11 +1508,19 @@ msgstr ""
"ÐУРпÑикÑÑÑак за ÐезоÑника\n"
"ÐÑÑоÑÑка пÑава 2009-2012 Ðон ÐиндгÑин"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "ÐУРпÑикÑÑÑак"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "Режим ÑиÑаÑ-и-пÑикаÑи ниÑе подÑжан"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "ÐеиÑпÑаван Ñежим оÑваÑаÑа"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1522,450 +1540,522 @@ msgstr ""
"\n"
"Ðозвола: ÐÐÐв2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "ÐпенÐÐ ÐнализаÑÐ¾Ñ ÑпекÑÑа"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
-"ÐÑикÑÑÑак Ðномове пÑеÑиÑе\n"
-"ÐмогÑÑава вам да ÑпÑавÑаÑе пÑогÑамом коÑиÑÑеÑи Ðномове пÑеÑиÑе.\n"
+"ÐпенÐРанализаÑÐ¾Ñ ÑпекÑÑа за ÐезоÑника\n"
+"ÐÑÑоÑÑка пÑава 2013 ÐÑиÑÑÐ¾Ñ ÐÑде, Ðон ÐиндгÑин, и ÐаÑло ÐÑамини\n"
+"ÐÑÑоÑÑка пÑава 2014 ÐилиÑам ÐиÑкок\n"
"\n"
-"ÐÑÑоÑÑка пÑава (C) 2007-2008 СаÑа ХлаÑÑак <contact at saschahlusiak.de>"
+"ÐаÑновано на ÐÐÑÐÐС пÑикÑÑÑкÑ:\n"
+"ÐÑÑоÑÑка пÑава 1998-2000 ÐиÑÐµÑ Ðлм, ÐаÑкол Ðлм, Ðле ХалнаÑ, Ð¢Ð¾Ð¼Ð°Ñ ÐилÑон, и "
+"4ФÑÐ¾Ð½Ñ Ð¢ÐµÑ
нологиÑе\n"
+"\n"
+"Ðозвола: ÐÐÐв2+"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "ÐпенÐÐ ÐнализаÑÐ¾Ñ ÑпекÑÑа (Qt)"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
msgstr "Ðномове пÑеÑиÑе"
-#: src/gtkui/columns.c:34
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+"ÐÑикÑÑÑак ÐномовиÑ
пÑеÑиÑа\n"
+"УпÑавÑаÑÑе пÑÑÑаÑем мÑзике Ðномовим пÑеÑиÑама.\n"
+"\n"
+"ÐÑÑоÑÑка пÑава (C) 2007-2008 СаÑа ХлÑÑÑак <contact at saschahlusiak.de>"
+
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "ÐÑÐ¾Ñ ÑÑавке"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "ÐаÑлов"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "ÐзвоÑаÑ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Ðодина"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "ÐлбÑм"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "ÐзвоÑÐ°Ñ Ð°Ð»Ð±Ñма"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "ÐÑмеÑа"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "ÐанÑ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "ÐÐ¾Ð»Ð¾Ð¶Ð°Ñ ÐºÐ¾Ð»Ð¾Ð½Ðµ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "ТÑаÑаÑе"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "ÐÑÑаÑа даÑоÑеке"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Ðазив даÑоÑеке"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "ÐÑоизвоÑан наÑлов"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ÐиÑÑки пÑоÑок"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "ÐоÑÑÑпни ÑÑÑпÑи"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "ÐÑиказани ÑÑÑпÑи"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "ÐÐ»Ð°Ñ Ð·Ð° пÑеÑÑагÑ"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "УÑидÑи на лево"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "УÑидÑи на деÑно"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "УÑидÑи на вÑÑ
"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "УÑидÑи на дно"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "ÐÑкаÑи"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "ÐÑкÑÑÑи"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "ÐÐ»Ð°Ñ Ð·Ð° пÑеÑÑагÑ"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "ÐÑвоÑи _даÑоÑеке ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "ÐÑвоÑи _адÑеÑÑ ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "ÐÐ¾Ð´Ð°Ñ Ð´Ð°_ÑоÑеке ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "ÐÐ¾Ð´Ð°Ñ Ð°Ð´_ÑеÑÑ ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "ÐÑеÑÑажи _библиоÑекÑ"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "Ð _пÑогÑÐ°Ð¼Ñ ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "_ÐодеÑаваÑа ..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_ÐзаÑи"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "ÐÑ_ÑÑи"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Ðа_ÑзиÑаÑ"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_ÐаÑÑÑави"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_ÐÑеÑÑ
одно"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "С_ледеÑе"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Ðонови"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_ÐаÑÑмиÑно"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Ð_е напÑедÑÑ Ñ ÑпиÑÐºÑ Ð½ÑмеÑа"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "ÐаÑÑÑави _након ове пеÑме"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "ÐодаÑи о _пеÑми ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "ÐÑеÑи на _вÑеме ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "ÐÑеÑи на _пеÑÐ¼Ñ ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "ÐоÑÑави _Ð ÑаÑÐºÑ Ð¿Ð¾Ð½Ð°Ð²ÑаÑа"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "ÐоÑÑави _Ð ÑаÑÐºÑ Ð¿Ð¾Ð½Ð°Ð²ÑаÑа"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_ÐÑиÑÑи ÑаÑке понавÑаÑа"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "ÐÑема _наÑловÑ"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr "ÐÑема Ð½Ð°Ð·Ð¸Ð²Ñ _даÑоÑеке"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "ÐÑема _пÑÑаÑи даÑоÑеке"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "ÐÑема бÑоÑÑ _нÑмеÑе"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "ÐÑема _извоÑаÑÑ"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "ÐÑема _албÑмÑ"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "ÐÑема извоÑаÑÑ Ð°Ð»Ð±Ñ_ма"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "ÐÑема _даÑÑÐ¼Ñ Ð¸Ð·Ð´Ð°Ð²Ð°Ñа"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "ÐÑема _жанÑÑ"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "ÐÑема _ÑÑаÑаÑÑ"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "ÐÑема _пÑÑаÑи даÑоÑеке"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
-msgstr "ÐÑема п_ÑоизвоÑном наÑловÑ"
+msgstr "ÐÑема пÑоизвоÑном _наÑловÑ"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "ÐÑеокÑени п_оÑедак"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_СлÑÑаÑан поÑедак"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_ÐÑÑÑи Ð¾Ð²Ð°Ñ ÑпиÑак нÑмеÑа"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_ÐÑÑÑи/ÐаÑÑави"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_ÐÑвежи"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "ÐоÑ_еÑаÑ"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "ÐоÑеÑÐ°Ñ _ознаÑене"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "Уклони _двоÑÑÑÑке"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Уклони _недоÑÑÑпне даÑоÑеке"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Ðово"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "_ÐÑеименÑÑ ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "_Уклони"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "Ув_ези ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "Ðз_вези ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "УпÑавник ÑпиÑка _нÑмеÑа ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "УпÑавник _ÑедоÑледа ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Ðо_ÑаÑаÑ"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "У_ÑиÑаÑ"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "УÑе_днаÑаваÑ"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "_ÐеÑÑÑва ..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "ÐÑикажи ÑÑÐ°ÐºÑ _избоÑника"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "ÐÑикажи ÑÑÐ°ÐºÑ _подаÑака"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "ÐÑикажи _визÑелизаÑиÑÑ ÑÑаке обавеÑÑеÑа"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "ÐÑикажи ÑÑÐ°ÐºÑ _ÑÑаÑа"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "ÐÑикажи пÑеоÑÑало _вÑеме"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "_ÐизÑелизаÑиÑе ..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_ÐаÑоÑека"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_ÐзвоÑеÑе"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_СпиÑак нÑмеÑа"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_УÑлÑге"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Ðзлаз"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_ÐÑеглед"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_СÑави Ñ Ñед/ÐзбаÑи из Ñеда"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "_ÐÑвоÑи ÑадÑжаваÑÑÑÑ ÑаÑÑиклÑ"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "_ÐÑеÑи"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "У_множи"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "У_баÑи"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "_ÐзабеÑи Ñве"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_ÐÑеименÑÑ ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>ÐезиÑÑи ÑпиÑка нÑмеÑа</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "Увек пÑикажи ÑезиÑке"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "ÐÑикажи бÑÐ¾Ñ ÑноÑа"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "ÐÑикажи дÑгмад заÑваÑаÑа"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>СÑÑпÑи ÑпиÑка нÑмеÑа</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "ÐÑикажи заглавÑа колона"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Разно</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr "СÑÑалиÑе помеÑаÑÑ Ð·Ð°:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "ÐÐ»Ð¸Ð·Ð°Ñ Ð¿Ñи пÑомени пеÑме"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "ÐТРÑÑÑеÑе"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s â ÐезоÑник"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ÐаÑеÑÑÑем ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "ÐезоÑник"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "моно"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "ÑÑеÑео"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
@@ -1973,84 +2063,98 @@ msgstr[0] "%d канал"
msgstr[1] "%d канала"
msgstr[2] "%d канала"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kb/s"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "ÐедноÑÑавни Ñежим."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Режим ÑпиÑка нÑмеÑа."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "ÐаÑÑÑавÑа након пеÑме."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "ÐÑеÑÑ
одна нÑмеÑа"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "ÐÑÑÑи"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "ÐаÑзиÑаÑ/наÑÑави"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "ÐаÑÑÑави"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "СледеÑа нÑмеÑа"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "УнапÑед 5 ÑекÑнде"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "Уназад 5 ÑекÑнде"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "ÐÑкÑÑÑи звÑк"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "ÐоÑаÑаÑ"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "УÑиÑаÑ"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "СкоÑи до даÑоÑеке"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "УкÑÑÑи/иÑкÑÑÑи главни пÑозоÑ"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "ÐÑикажи пÑиказ на екÑанÑ"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "УкÑÑÑи/иÑкÑÑÑи понавÑаÑе"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "УкÑÑÑи/иÑкÑÑÑи пÑемеÑÑаÑе"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "ÐаÑÑÑави поÑле ÑекÑÑе пеÑме"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "Ðздигни главни пÑозоÑ"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(ниÑÑа)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2061,15 +2165,11 @@ msgstr ""
"\n"
"Ðа ли желиÑе да наÑÑавиÑе?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "ÐовезÑÑем дÑгмад миÑа"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "ÐодеÑаваÑа пÑикÑÑÑка опÑÑиÑ
пÑеÑиÑа"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2077,23 +2177,27 @@ msgstr ""
"ÐÑиÑиÑниÑе комбинаÑиÑÑ ÑаÑÑеÑа ÑнÑÑÐ°Ñ Ð¿Ð¾Ñа за ÑекÑÑ.\n"
"ÐожеÑе ÑакоÑе да повежеÑе дÑгмад миÑа."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "ÐÑеÑиÑе:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>РадÑа:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Свезе ÑаÑÑеÑа:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "_ÐодаÑ"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "ÐпÑÑе пÑеÑиÑе"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2120,60 +2224,55 @@ msgstr ""
" ÐонаÑан Ð. ÐÐ°Ð²Ð¸Ñ <davis at jdhouse.org>\n"
" ÐеÑеми Тан <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "ÐпÑÑе пÑеÑиÑе"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "ÐÐРизлаз"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "Ðовежи Ñа Ñвим ÑаÑположивим поÑÑовима ÑÑиÑниÑа"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "СамоÑÑално повезиваÑе на пÑикÑÑÑнике излаза"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "Ðовежи Ñамо излазне поÑÑове"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "ÐаÑао Ñам Ñамо %d излазна пÑикÑÑÑка ÐÐÐ-а али ÑÑ Ð¿Ð¾ÑÑебна %d."
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "Ðе повезÑÑ Ñе на пÑикÑÑÑнике"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "ÐиÑам ÑÑпео да Ñе повежем на пÑикÑÑÑник ÐÐÐ-а â%sâ."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "Режим повезиваÑа:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+"ÐÐРподÑжава Ñамо звÑк покÑеÑног заÑеза. ÐоÑаÑе измениÑи дÑÐ±Ð¸Ð½Ñ Ð¸Ð·Ð»Ð°Ð·Ð½Ð¾Ð³ "
+"биÑа на покÑеÑни заÑез Ñ Ð¿Ð¾Ð´ÐµÑаваÑима ÐезоÑника."
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "УкÑÑÑи ÑÑампаÑе ÑклаÑаÑа гÑеÑака"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "ÐиÑам ÑÑпео да Ñе повежем на ÑеÑÐ²ÐµÑ ÐÐÐ-а; да ли Ñе покÑенÑÑ?"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"ÐаÑновано на икÑммÑ-ÑекÑ, коÑи Ñе пÑиÑедио ÐÑÐ¸Ñ ÐоÑган:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ðакомо ÐоÑиÑо Ñе пÑипÑемио за ÐезоÑника"
+"ÐÐÐ ÑеÑÐ²ÐµÑ Ð·Ð°Ñ
Ñева пÑоÑок ÑзоÑка од %d Hz, али ÐезоÑник пÑÑÑа пÑи %d Hz. "
+"ÐоÑиÑÑиÑе деÑÑÑво пÑеÑваÑаÑа пÑоÑока ÑзоÑка да иÑпÑавиÑе неÑаглаÑноÑÑ."
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "ÐÐРизлаз"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "ÐодеÑаваÑа за %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "ÐодеÑаваÑа ÐÐÐСÐРдомаÑинÑ"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "ÐÑÑаÑе модÑла:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2184,25 +2283,25 @@ msgstr ""
"Ðакон додаваÑа новиÑ
пÑÑаÑа, пÑиÑиÑниÑе УнеÑи да поÑÑажиÑе нове пÑикÑÑÑке.</"
"small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "ÐоÑÑÑпни пÑикÑÑÑÑи:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "УкÑÑÑи"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "УкÑÑÑени пÑикÑÑÑÑи:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "ÐодеÑаваÑа"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2210,47 +2309,15 @@ msgstr ""
"ÐÐÐСÐРдомаÑин за ÐезоÑника\n"
"ÐÑÑоÑÑка пÑава 2011 Ðон ÐиндгÑин"
-#: src/ladspa/plugin.c:676
-msgid "LADSPA Host"
-msgstr "ÐÐÐСÐРдомаÑин"
-
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: не Ð¼Ð¾Ð³Ñ Ð´Ð° запоÑнем ÐÐРЦ подÑÑкÑ\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: не Ð¼Ð¾Ð³Ñ Ð´Ð° пÑоÑиÑам даÑоÑÐµÐºÑ ÐÐРЦ подеÑаваÑа\n"
-"%s: молим пÑоÑиÑаÑÑе ÐÐРЦ докÑменÑаÑиÑÑ\n"
-"%s: како да напÑавиÑе лиÑÐ½Ñ Ð´Ð°ÑоÑÐµÐºÑ Ð¿Ð¾Ð´ÐµÑаваÑа\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: покÑÑавам да Ñе поново повежем...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: непознаÑа наÑедба â%sâ\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: пÑекинÑÑа Ñе веза Ñа ÐÐРЦ-а\n"
+#: src/ladspa/plugin.h:78
+msgid "LADSPA Host"
+msgstr "ÐÐÐСÐРдомаÑин"
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: покÑÑаÑÑ Ð´Ð° Ñе поново повежем Ñваке %d ÑекÑнде...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "ÐÐРЦ пÑикÑÑÑак"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2279,73 +2346,81 @@ msgstr ""
"\n"
"Ðа ÑазнаÑе виÑе о ÐÐРЦ-Ñ, погледаÑÑе âhttp://lirc.orgâ."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Ðеза</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Ðоново Ñе повежи Ñа ÐÐРЦ ÑеÑвеÑом"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "СаÑÐµÐºÐ°Ñ Ð¿Ñе поновног повезиваÑа:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "ÐÐРЦ пÑикÑÑÑак"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "ÐÑикÑÑÑак за ÐиÑик вики"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Ðема доÑÑÑпниÑ
ÑекÑÑова"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "ÐÑеÑка"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Ðе Ð¼Ð¾Ð³Ñ Ð´Ð° довÑÑем â%sâ"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "ÐÑеÑка"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Ðе Ð¼Ð¾Ð³Ñ Ð´Ð° обÑадим â%sâ"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "ТÑажим ÑекÑÑ Ð¿ÐµÑме ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "ÐедоÑÑаÑÑ Ð¼ÐµÑаподаÑи пеÑме"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "ÐовезÑÑем Ñе на âlyrics.wikia.comâ ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "ÐÑикÑÑÑак за ÐиÑик вики"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "ÐÑикÑÑÑак за ÐиÑик вики (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "Ð3У ÑпиÑак нÑмеÑа"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑа"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑа: %d оÑк/мин"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑа: %d оÑк/мин %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2359,11 +2434,11 @@ msgstr ""
"нпÑ.: âtact://77â да добиÑеÑе 77 оÑкÑÑаÑа Ñ Ð¼Ð¸Ð½ÑÑÑ\n"
"или: âtact://60*3/4â да добиÑеÑе 60 оÑк./мин Ñ 3/4 ÑакÑÑ"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑа"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "ÐеÑÐ°Ñ ÐºÐ°Ð½Ð°Ð»Ð°"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2371,152 +2446,185 @@ msgstr ""
"ÐÑикÑÑÑак меÑаÑа канала за ÐезоÑника\n"
"ÐÑÑоÑÑка пÑава 2011-2012 Ðон ÐиндгÑин и ÐиÑ
ал ÐипÑки"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>ÐеÑÐ°Ñ ÐºÐ°Ð½Ð°Ð»Ð°</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Ðзлазни канали:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "ÐеÑÐ°Ñ ÐºÐ°Ð½Ð°Ð»Ð°"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "ÐÐС пÑикÑÑÑак"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "ÐÑеÑка повезиваÑа на ÐÐС ÑеÑвеÑ"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "Ðод пÑикÑÑÑак (ÐÑогÑам за модле)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>РезолÑÑиÑа</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8 биÑа"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16 биÑа"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>ÐÑ. канала</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "ÐаÑближе (наÑбÑже)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "ÐинеаÑно (бÑзо)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Сп-кÑива (добÑо)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "ÐолиÑазни (наÑбоÑе)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>ÐÑоÑок ÑзоÑка</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr "<b>ÐÑоÑок ÑзоÑка:</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Ðиво:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "ÐÑекид:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>ÐдÑек</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>ÐÑиÑаÑÑ Ð±Ð°Ñа</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>ÐкÑÑжеÑе</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>ÐÑеÑпоÑаÑаÑе</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "ÐÑеклапаÑе"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "СмаÑеÑе бÑке"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "ÐÑÑÑÐ°Ñ Ðмига ÐÐÐ-е"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>Ðонови</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "ÐÑÐ¾Ñ Ð¿Ð¾Ð½Ð°Ð²ÑаÑа:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "Ðа непÑекидно понавÑаÑе, поÑÑавиÑе бÑÐ¾Ñ Ð¿Ð¾Ð½Ð°Ð²ÑаÑа на -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "Ðод пÑикÑÑÑак (ÐÑогÑам за модле)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "ÐкÑÑжеÑе"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
+"Ðва подеÑаваÑа Ñе ÑÑÑпиÑи Ñ Ð´ÐµÑÑÑво након поновног покÑеÑаÑа ÐезоÑника."
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "ÐÐÐ123 пÑикÑÑÑак"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>ÐапÑедно</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "ÐоÑиÑÑи ÑаÑан пÑоÑаÑÑн ÑÑаÑаÑа (ÑпоÑо)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "ÐкÑÑжеÑе"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "ÐÐÐ ÐС 2 ÑеÑвеÑ"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Ðеон ХТТÐ/ХХТÐС пÑикÑÑÑак"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "ÐÑеÑка обÑаде пÑеÑÑмеÑеÑа"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "ÐепознаÑа ХТТРгÑеÑка"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "ÐÑеÑка обÑаде адÑеÑе"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "ÐÑевиÑе пÑеÑÑмеÑеÑа"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "ÐаÑÑÑавÑено"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "ÐезоÑник не пÑÑÑа пеÑме."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "ÐбавеÑÑеÑа Ñадне повÑÑи"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2552,55 +2660,64 @@ msgstr ""
"ТÑебали ÑÑе да пÑимиÑе пÑимеÑак ÐнÑове опÑÑе Ñавне лиÑенÑе Ñз оваÑ\n"
"пÑогÑам. Ðко ниÑÑе, погледаÑÑе <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "ÐÑикажи дÑгмад за пÑÑÑаÑе"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Ðвек пÑикажи обавеÑÑеÑа"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "ÐбавеÑÑеÑа Ñадне повÑÑи"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "УкÑÑÑи назив албÑма Ñ Ð¾Ð±Ð°Ð²ÐµÑÑеÑÑ"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "ÐÑикажи"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "ÐаÑзиÑаÑ"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "СледеÑа"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. ÐÑновни ÑÑеÑаÑ"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "ÐСС4 излаз"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "ÐСС3 излаз"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "ÐÑновни ÑÑеÑаÑ"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "ÐвÑÑни ÑÑеÑаÑ:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "ÐоÑиÑÑи алÑеÑнаÑивни ÑÑеÑаÑ:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "СаÑÑваÑÑе ÑаÑÐ¸Ð½Ñ Ð·Ð²Ñка измеÑÑ ÑеÑиÑа."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "УкÑÑÑÑÑе пÑеÑваÑаÑе ÑоÑмаÑа напÑавÑено ÐСС ÑоÑÑвеÑом."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "УкÑÑÑÑÑе иÑкÑÑÑиви Ñежим да ÑпÑеÑи виÑÑÑално меÑаÑе."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2614,19 +2731,35 @@ msgstr ""
"Ðелим да Ñе заÑ
валим ÑÑдима на â#audaciousâ, наÑоÑиÑо Тони ÐÑÑÐ½Ñ Ð¸ ÐÐ¾Ð½Ñ "
"ÐиндгÑÐ¸Ð½Ñ Ð¸ наÑавно аÑÑоÑима пÑеÑÑ
одног ÐСС пÑикÑÑÑка."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "ÐСС4 излаз"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "УпÑавник ÑпиÑка нÑмеÑа"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "УноÑи"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Уклони"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "_ÐÑеименÑÑ"
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "ÐÐС ÑпиÑкови нÑмеÑа"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "ÐпенÐСФ ÐСФ1/ÐСФ2 декодеÑ"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "ÐÑлÑâаÑдио излаз"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2663,11 +2796,73 @@ msgstr ""
"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "ÐÑлÑâаÑдио излаз"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "Ðзлаз ÐÑÑ Ð¼ÑлÑимедиÑа"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"ÐÑикÑÑÑак аÑдио излаза ÐÑÑ Ð¼ÑлÑимедиÑа за ÐезоÑника\n"
+"ÐÑÑоÑÑка пÑава 2014 ÐилиÑам ÐиÑкок\n"
+"\n"
+"ÐаÑновано на пÑикÑÑÑÐºÑ Ð¡ÐРизлаза за ÐезоÑника\n"
+"ÐÑÑоÑÑка пÑава 2010 Ðон ÐиндгÑин"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "Радим ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "ÐоÑÑажи"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "ÐÑвоÑи _ÑаÑÑÐ¸ÐºÐ»Ñ ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "_ÐÐ¾Ð´Ð°Ñ ÑаÑÑÐ¸ÐºÐ»Ñ ..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "ÐадзоÑник _дневника ..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "ÐÑвоÑи даÑоÑеке"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "ÐÐ¾Ð´Ð°Ñ Ð´Ð°ÑоÑеке"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ÐÑеÑÑ
одна"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Ðонови"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "ÐаÑÑмиÑно"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "ÐÑÑ ÑÑÑеÑе"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "ÐÑеÑваÑÐ°Ñ Ð¿ÑоÑока ÑзоÑка"
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2675,98 +2870,106 @@ msgstr ""
"ÐÑикÑÑÑак ÐÑеÑваÑаÑа пÑоÑока ÑзоÑка за ÐезоÑника\n"
"ÐÑÑоÑÑка пÑава 2010-2012 Ðон ÐиндгÑин"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "ÐÑеÑкоÑи/понови ÑзоÑке"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "ÐиниÑÑко ÑмеÑаÑе"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "ÐÑзо ÑмеÑаÑе ÑÑклаÑеÑа"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "СÑедÑе ÑмеÑаÑе ÑÑклаÑеÑа"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "ÐаÑбоÑе ÑмеÑаÑе ÑÑклаÑеÑа"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>ÐÑеÑваÑаÑе</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "ÐеÑод:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "ÐÑоÑок:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>ÐапиÑаÑе пÑоÑока</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "ÐоÑиÑÑи мапиÑаÑе пÑоÑока"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "ÐÑеÑваÑÐ°Ñ Ð¿ÑоÑока ÑзоÑка"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "У ÑедÑ. СкÑоблÑÑем за коÑиÑника: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "ÐвлаÑÑеÑа ÑÑ Ð¾Ð´Ð±Ð¸Ñена"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"ÐÑиÑÑÑпиÑе ÑледеÑÐ¾Ñ Ð²ÐµÐ·Ð¸ да омогÑÑиÑе ÐезоÑÐ½Ð¸ÐºÑ Ð´Ð° ÑкÑоблÑÑе ваÑа пÑÑÑаÑа:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"ÐадÑжиÑе Ð¾Ð²Ð°Ñ Ð¿ÑÐ¾Ð·Ð¾Ñ Ð¾ÑвоÑеним и Ð¾Ð¿ÐµÑ Ð¿ÑиÑиÑниÑе âÐÑовеÑи овлаÑÑеÑаâ.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2774,34 +2977,38 @@ msgstr ""
"Ðе бÑиниÑе. ÐаÑа ÑкÑобловаÑа ÑÑ ÑаÑÑвана на ваÑем ÑаÑÑнаÑÑ.\n"
"ÐиÑе поÑлаÑа Ñим ÐезоÑÐ½Ð¸ÐºÑ Ñо бÑде било омогÑÑено."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "ÐÑоблем Ñа мÑежом."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
"ÐоÑло Ñе до пÑоблема ÑÑÑпаÑа Ñ Ð²ÐµÐ·Ñ Ñа ÐаÑÑ.Ñм-ом. ÐаÑниÑе покÑÑаÑÑе поново."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "ÐÑовеÑавам..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "_ÐÑовеÑи овлаÑÑеÑа"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_Уклони овлаÑÑеÑа"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"ТÑебаÑе да омогÑÑиÑе ÐезоÑÐ½Ð¸ÐºÑ Ð´Ð° ÑкÑоблÑÑе нÑмеÑе до ваÑег ÐаÑÑ.Ñм налога.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "СкÑÐ¾Ð±Ð»ÐµÑ 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2809,7 +3016,7 @@ msgstr ""
"ÐÑикÑÑÑак СкÑоблеÑа не може биÑи покÑенÑÑ.\n"
"Ðожда Ñе пÑоблем Ñа ваÑом инÑÑалаÑиÑом."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2826,11 +3033,7 @@ msgstr ""
"ÐаÑ
ваÑÑÑем Ñе ÐÐ¾Ð½Ñ ÐиндгÑÐ¸Ð½Ñ ÑÑо ми Ñе помогао на поÑеÑÐºÑ Ð¾Ð²Ð¾Ð³ пÑоÑекÑа.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "СкÑÐ¾Ð±Ð»ÐµÑ 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2838,7 +3041,11 @@ msgstr ""
"ÐезоÑник Ñада коÑиÑÑи побоÑÑано издаÑе ÐаÑÑ.Ñм-овог СкÑоблеÑа.\n"
"ÐÑовеÑиÑе Ñ Ð¿Ð¾ÑÑавкама за пÑикÑÑÑком СкÑоблеÑа"
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "СÐРизлаз"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2846,88 +3053,59 @@ msgstr ""
"ÐÑикÑÑÑак СÐРизлаза за ÐезоÑника\n"
"ÐÑÑоÑÑка пÑава 2010 Ðон ÐиндгÑин"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "СÐРизлаз"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "ÐиблиоÑека"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "ÐÐµÐ¿Ð¾Ð·Ð½Ð°Ñ Ð¸Ð·Ð²Ð¾ÑаÑ"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "ÐÐµÐ¿Ð¾Ð·Ð½Ð°Ñ Ð°Ð»Ð±Ñм"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" â%sâ изводи %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d ÑезÑлÑаÑ"
+msgstr[1] "%d ÑезÑлÑаÑа"
+msgstr[2] "%d ÑезÑлÑаÑа"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d албÑм"
-msgstr[1] "%d албÑма"
-msgstr[2] "%d албÑма"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d ÑкÑивена)"
+msgstr[1] "(%d ÑкÑивене)"
+msgstr[2] "(%d ÑкÑивениÑ
)"
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %s, %d пеÑма"
-msgstr[1] ""
-"%s\n"
-" %s, %d пеÑме"
-msgstr[2] ""
-"%s\n"
-" %s, %d пеÑама"
-
-#: src/search-tool/search-tool.c:639
-#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d пеÑма коÑÑ Ð¸Ð·Ð²Ð¾Ð´Ð¸ %s"
-msgstr[1] ""
-"%s\n"
-" %d пеÑме коÑе изводи %s"
-msgstr[2] ""
-"%s\n"
-" %d пеÑама коÑе изводи %s"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d пеÑма"
+msgstr[1] "%d пеÑме"
+msgstr[2] "%d пеÑама"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "овог жанÑа"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr " "
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "изводи"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_ÐапÑави ÑпиÑак нÑмеÑа"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_ÐÐ¾Ð´Ð°Ñ Ñ ÑпиÑак нÑмеÑа"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "ÐÑеÑÑажиÑе библиоÑекÑ"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2935,679 +3113,771 @@ msgstr ""
"Ðа ÑвезеÑе ваÑÑ Ð¼ÑзиÑÐºÑ Ð±Ð¸Ð±Ð»Ð¸Ð¾ÑÐµÐºÑ Ñ ÐезоÑникÑ, изабеÑиÑе ÑаÑÑÐ¸ÐºÐ»Ñ Ð¸ заÑим "
"кликниÑе на икониÑÑ âоÑвежиâ."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Ðолим ÑаÑекаÑÑе ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "ÐзабеÑиÑе ÑаÑÑиклÑ"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "СÐРпÑÑÑаÑ"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>Ðзлаз</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "ÐÑ. канала:"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>ÐпонаÑаÑе</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "ÐпонаÑÐ°Ñ ÐÐС 8580 (оÑновно: ÐÐС 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "Ðе биÑÐ°Ñ Ñам модел Ñипа"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "ÐпонаÑÐ°Ñ Ð¿ÑопÑÑник"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "ÐÑзина ÑаÑа:"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "Ðе биÑÐ°Ñ Ñам бÑÐ·Ð¸Ð½Ñ ÑаÑа"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>ÐÑеме пÑÑÑаÑа</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "ÐодеÑи наÑвеÑе вÑеме пÑÑÑаÑа:"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "ÐоÑиÑÑи Ñамо када Ñе ÑÑаÑаÑе пеÑме непознаÑо"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "ÐодеÑи наÑмаÑе вÑеме пÑÑÑаÑа:"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>СÑбÑÑÑнÑ</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "УкÑÑÑиÑе ÑÑбÑÑÑнÑе"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "ÐанемаÑи ÑÑбÑÑÑнÑе кÑаÑе од:"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>Ðапомена</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "УклаÑаÑе ÑиÑине"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"ÐÑикÑÑÑак ÑклаÑаÑа ÑиÑине за ÐезоÑника\n"
+"ÐÑÑоÑÑка пÑава 2014 Ðон ÐиндгÑин"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>УклаÑаÑе ÑиÑине</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "ÐÑеÑÑивоÑÑ:"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "ÐÑвоÑи даÑоÑеке ..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "ÐÑвоÑи адÑеÑÑ ..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "ÐÑеÑÑажи библиоÑекÑ"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "ÐÑÑÑаÑе"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "СпиÑак нÑмеÑа"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
-msgstr "ÐÑеглед"
+msgstr "Ðоглед"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "УÑлÑге"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "РпÑогÑÐ°Ð¼Ñ ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "ÐодеÑаваÑа ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "ÐзаÑи"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "ÐодаÑи о пеÑми ..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Ðонови"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "ÐаÑÑмиÑно"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Ðе напÑедÑÑ Ñ ÑпиÑÐºÑ Ð½ÑмеÑа"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "ÐаÑÑÑави након ове пеÑме"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ÐÑеÑÑ
одна"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "ÐоÑÑави ÐâРпонавÑаÑа"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "ÐÑиÑÑи ÐâРпонавÑаÑа"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "ÐÑеÑи на пеÑÐ¼Ñ ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "ÐÑеÑи на вÑеме ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "ÐÑÑÑи Ð¾Ð²Ð°Ñ ÑпиÑак нÑмеÑа"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "ÐÑÑÑи/ÐаÑÑави"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Ðови ÑпиÑак нÑмеÑа"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "ÐÑеименÑÑ ÑпиÑак нÑмеÑа ..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "Ðови ÑпиÑак нÑмеÑа"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "ÐÑеÑÑ
одни ÑпиÑак нÑмеÑа"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "СледеÑи ÑпиÑак нÑмеÑа"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "Увези ÑпиÑак нÑмеÑа ..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "Ðзвези ÑпиÑак нÑмеÑа ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "УпÑавник ÑпиÑка нÑмеÑа ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "УпÑавник ÑедоÑледа ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "ÐÑвежи ÑпиÑак нÑмеÑа"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "ÐÑикажи ÑÑеÑÐ¸Ð²Ð°Ñ ÑпиÑка нÑмеÑа"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "ÐÑикажи ÑÑеднаÑаваÑ"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "ÐÑикажи пÑеоÑÑало вÑеме"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Увек Ñ Ð¿Ñвом планÑ"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "Све на Ñадне пÑоÑÑоÑе"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "ÐамоÑÐ°Ñ Ð¿Ð»ÐµÑеÑ"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "ÐамоÑÐ°Ñ ÑÑеÑÐ¸Ð²Ð°Ñ ÑпиÑка нÑмеÑа"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "ÐамоÑÐ°Ñ ÑÑеднаÑаваÑ"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "ÐвоÑÑÑÑка велиÑина"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "ÐÐ¾Ð´Ð°Ñ Ð°Ð´ÑеÑÑ ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "ÐÐ¾Ð´Ð°Ñ Ð´Ð°ÑоÑеке ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "ÐÑема наÑловÑ"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "ÐÑема Ð½Ð°Ð·Ð¸Ð²Ñ Ð´Ð°ÑоÑеке"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "ÐÑема пÑÑаÑи даÑоÑеке"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Уклони Ñве"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "ÐбÑиÑи заказано"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Уклони недоÑÑÑпне даÑоÑеке"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Уклони дÑпликаÑе"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Уклони неознаÑене"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Уклони ознаÑене"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "ÐÑеÑÑажи и ознаÑи"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "ÐбÑни избоÑ"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "ÐзнаÑи ниÑÑа"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "ÐзнаÑи Ñве"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "ÐÑема албÑмÑ"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "ÐÑема бÑоÑÑ Ð½ÑмеÑе"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "ÐÑема извоÑаÑÑ"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "ÐÑема албÑмÑ"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "ÐÑема извоÑаÑÑ Ð°Ð»Ð±Ñма"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "ÐÑема даÑÑÐ¼Ñ Ð¸Ð·Ð´Ð°Ð²Ð°Ñа"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "ÐÑема бÑоÑÑ Ð½ÑмеÑе"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "ÐÑема жанÑÑ"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "ÐÑема ÑÑаÑаÑÑ"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "ÐÑема пÑоизвоÑном наÑловÑ"
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "ÐаÑÑмиÑе иÑпÑемеÑÑÐ°Ñ ÑпиÑак"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "ÐÑеокÑени ÑпиÑак"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "ÐоÑеÑÐ°Ñ Ð¾Ð·Ð½Ð°Ñене"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "ÐоÑеÑÐ°Ñ ÑпиÑак"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "ÐÑеÑи"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Умножи"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "УбаÑи"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "СÑави Ñ Ñед/ÐзбаÑи из Ñеда"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "УÑиÑÐ°Ñ Ð¿ÑеÑподеÑаваÑе ..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "УÑиÑÐ°Ñ ÑамоÑÑално пÑеÑподеÑаваÑе ..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "УÑиÑÐ°Ñ Ð¾Ñновно"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "УÑиÑÐ°Ñ Ð´Ð°ÑоÑÐµÐºÑ Ð¿ÑеÑподеÑаваÑа ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "УÑиÑÐ°Ñ ÐÐÑФ даÑоÑÐµÐºÑ ..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "СаÑÑÐ²Ð°Ñ Ð¿ÑеÑподеÑаваÑе ..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "СаÑÑÐ²Ð°Ñ ÑамоÑÑално пÑеÑподеÑаваÑе ..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "СаÑÑÐ²Ð°Ñ Ð¾Ñновно"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "СаÑÑÐ²Ð°Ñ Ð´Ð°ÑоÑÐµÐºÑ Ð¿ÑеÑподеÑаваÑа ..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "СаÑÑÐ²Ð°Ñ ÐÐÑФ даÑоÑÐµÐºÑ ..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "ÐбÑиÑи пÑеÑподеÑаваÑе ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "ÐбÑиÑи ÑамоÑÑално пÑеÑподеÑаваÑе ..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "Увези Ðинамп пÑеÑподеÑаваÑа ..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "ÐÑаÑи на нÑлÑ"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Ðинампово ÑобиÑаÑено ÑÑÑеÑе"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "СаÑÑваÑ"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "УÑиÑаÑ"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "УÑиÑÐ°Ñ Ð´Ð°ÑоÑÐµÐºÑ Ð¿ÑеÑподеÑаваÑа"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "УÑиÑÐ°Ñ ÐÐÑФ даÑоÑекÑ"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "СаÑÑÐ²Ð°Ñ Ð´Ð°ÑоÑÐµÐºÑ Ð¿ÑеÑподеÑаваÑа"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "СаÑÑÐ²Ð°Ñ ÐÐÑФ даÑоÑекÑ"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "Увези Ðинамп пÑеÑподеÑаваÑа"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "ÐÑеÑподеÑаваÑа"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "УÑиÑава пÑеÑподеÑаваÑе"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "УÑиÑава ÑамоÑÑално пÑеÑподеÑаваÑе"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "ЧÑва пÑеÑподеÑаваÑе"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "ЧÑва ÑамоÑÑално пÑеÑподеÑаваÑе"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "ÐзбÑиÑи пÑеÑподеÑаваÑе"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "ÐÑиÑе ÑамоÑÑално пÑеÑподеÑаваÑе"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_ÐлеÑеÑ:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "ÐÑÑÑаÑ:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
-msgstr "ÐзабеÑиÑе Ñловни лик главног пÑозоÑа плеÑеÑа:"
+msgstr "ÐзабеÑиÑе Ñловни лик главног пÑозоÑа пÑогÑама:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_СпиÑак нÑмеÑа:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "СпиÑак нÑмеÑа:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "ÐзабеÑи Ñловни лик ÑпиÑка нÑмеÑа:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>ÐаÑка</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
-msgstr "<b>Словни ликови</b>"
+msgstr "<b>Слова</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "ÐоÑиÑÑи биÑмап Ñловне ликове (подÑжава Ñамо ÐСÐÐ Ð)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "ÐомеÑÐ°Ñ Ð½Ð°Ñлов пеÑме"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "ÐомеÑÐ°Ñ Ð½Ð°Ñлов пеÑме Ñ Ð¾Ð±Ð° ÑмеÑа"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "ÐнализаÑоÑ"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "ÐоÑег"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "Режим оÑиÑка глаÑа / ÐУ меÑаÑ"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "ÐÑкÑÑÑено"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "ÐоÑмалан"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "ÐаÑÑа"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
-msgstr "ÐеÑÑикалне линиÑе"
+msgstr "УÑпÑавне линиÑе"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "ÐиниÑе"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "ТÑаке"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "ÐаÑÑпоÑиÑе"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "СпоÑо"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "СÑедÑе"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "ÐÑзо"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "ÐаÑбÑже"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "ТаÑке"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "ÐиниÑа"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "ÐÑпÑÑено"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Ðед"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "ÐлаÑко"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>ÐÑÑÑа</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "ÐÑÑÑа пÑиказиваÑа:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>ÐнализаÑоÑ</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "ÐÑикажи вÑÑ
ÑнÑе"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "ÐоÑа:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "Ðзглед:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "ÐпадаÑе:"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "ÐпадаÑе вÑÑ
ова:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "Режим доÑега:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "ÐбоÑаваÑе оÑиÑка глаÑа:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "СÑил ÐУ меÑаÑа:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "ÐпÑÑе"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "ÐÑиказиваÑе"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "ÐÑеÑпоÑаÑаÑе"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "УÑеднаÑÐ°Ð²Ð°Ñ ÐезоÑника"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "ТÑажи до: %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "ÐаÑина звÑка: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "УÑавноÑеженоÑÑ: %d%% леви"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "УÑавноÑеженоÑÑ: ÑенÑÑиÑано"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "УÑавноÑеженоÑÑ: %d%% деÑни"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "ÐзбоÑник опÑиÑа"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "ÐÑкÑÑÑи âУвек Ñ Ð¿Ñвом планÑâ"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "УкÑÑÑи âУвек Ñ Ð¿Ñвом планÑâ"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
-msgstr "ÐоÑе инÑоÑмаÑиÑа о даÑоÑеÑи"
+msgstr "ÐоÑе подаÑака даÑоÑеке"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "ÐизÑализаÑиÑе"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "Ðонови ÑкÑп ÑаÑке Ð."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "Ðонови ÑкÑп ÑаÑке Ð."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "Ðонови оÑиÑÑене ÑаÑке."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "ÐедноÑÑавни Ñежим."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Режим ÑпиÑка нÑмеÑа."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "ÐаÑÑÑавÑа након пеÑме."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "ÐÑеÑÑажи ÑÑавке Ñ Ð°ÐºÑивном ÑпиÑÐºÑ Ð½ÑмеÑа"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "ÐоÑÑажи"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3619,57 +3889,61 @@ msgstr ""
"како обиÑни изÑази ÑÑнкÑиониÑÑ, ÑедноÑÑавно доÑловно ÑнеÑиÑе део онога ÑÑо "
"ÑÑажиÑе."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "ÐаÑлов: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr "ÐаÑлов:"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "ÐлбÑм: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr "ÐлбÑм:"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "ÐзвоÑаÑ: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr "ÐзвоÑаÑ:"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Ðазив даÑоÑеке: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "Ðазив даÑоÑеке:"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "ÐбÑиÑи пÑеÑÑ
одни Ð¸Ð·Ð±Ð¾Ñ Ð¿Ñе пÑеÑÑаге"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "ÐодÑдаÑаÑÑÑе ÑÑавке ÑамоÑÑално пÑебаÑи Ñ Ñед"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "ÐапÑави нови ÑпиÑак нÑмеÑа Ñа подÑдаÑаÑÑÑим ÑÑавкама"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "УÑеÑÐ¸Ð²Ð°Ñ ÑпиÑка нÑмеÑа"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d од %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "ÐÑÑ
ивиÑана Ðинамп 2.x маÑка"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "ÐеаÑÑ
ивиÑана Ðинамп 2.x маÑка"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Ðе Ð¼Ð¾Ð³Ñ Ð´Ð° напÑавим ÑаÑÑÐ¸ÐºÐ»Ñ (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "ÐÑикÑÑÑак звÑÑне даÑоÑеке"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3696,7 +3970,7 @@ msgstr ""
"Ðа ÐезоÑника га Ñе пÑилагодио Тони ÐÑÑн <chainsaw at gentoo.org>\n"
"\n"
"ÐÐ²Ð°Ñ Ð¿ÑогÑам Ñе Ñлободан ÑоÑÑвеÑ; можеÑе га пÑоÑлеÑиваÑи\n"
-"и/или меÑаÑи под ÑÑловима ÐÐУ ÐпÑÑе Ñавне лиÑенÑе коÑÑ Ñе\n"
+"и/или меÑаÑи под ÑÑловима ÐнÑове ÐпÑÑе Ñавне лиÑенÑе коÑÑ Ñе\n"
"обÑавила ÐадÑжбина Ñлободног ÑоÑÑвеÑа; веÑзиÑе 2 лиÑенÑе\n"
"или (по ваÑем избоÑÑ) било коÑе новиÑе веÑзиÑе.\n"
"\n"
@@ -3705,88 +3979,76 @@ msgstr ""
"ТРÐÐШÐÐ ÐÐ ÐÐÐÐСТРили ÐÐ ÐÐÐÐÐÐÐÐÐСТРÐÐÐ ÐÐÐÐÐÐ ÐÐÐÐÐÐ.\n"
"ÐогледаÑÑе ÐÐУ ÐпÑÑÑ ÑÐ°Ð²Ð½Ñ Ð»Ð¸ÑенÑÑ Ð·Ð° виÑе деÑаÑа.\n"
"\n"
-"ТÑебали ÑÑе да пÑимиÑе пÑимеÑак ÐÐУ ÐпÑÑе Ñавне лиÑенÑе\n"
+"ТÑебали ÑÑе да пÑимиÑе пÑимеÑак ÐнÑове ÐпÑÑе Ñавне лиÑенÑе\n"
"Ñз Ð¾Ð²Ð°Ñ Ð¿ÑогÑам; ако ниÑÑе, пиÑиÑе ÐадÑжбини Ñлободног\n"
"ÑоÑÑва на адÑеÑÑ: Free Software Foundation, Inc.,\n"
"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "ÐÑикÑÑÑак звÑÑне даÑоÑеке"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Ðзлаз звкÑи"
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "РпÑикÑÑÑÐºÑ Ð·Ð²ÑÑногÑи излаза"
-
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"ÐÑикÑÑÑак звÑÑногÑи излаза\n"
-"\n"
-"ÐапиÑао га Ñе Ð¢Ð¾Ð¼Ð°Ñ ÐÑÐ°Ñ <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "УÑеÑÐ°Ñ (пÑазно за оÑновно):"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "ÐеподÑжани облик даÑоÑеке"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "СаÑÑÐ²Ð°Ñ Ð¸ вÑаÑи ÑаÑÐ¸Ð½Ñ Ð·Ð²ÐºÐ°:"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"ÐвÑÑни ÑÑеÑÐ°Ñ Ñе заÑÑажио неподÑжани облик даÑоÑеке.\n"
-"\n"
-"Ðолим покÑÑаÑÑе Ð¾Ð¿ÐµÑ Ñа покÑенÑÑим âsndiod(1)â ÑеÑвеÑом."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "ÐвкÑи гÑеÑка: ÐеподÑжан Ð·Ð°Ð¿Ð¸Ñ Ð·Ð²Ñка (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "звÑÑниÑи ÑÑеÑаÑ"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "ÐвкÑи гÑеÑка: ниÑе ÑÑпело âsio_open()â"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(пÑазно знаÑи задаÑо)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "ÐвкÑи гÑеÑка: ниÑе ÑÑпело âsio_setpar()â"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "У ÑедÑ"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "ÐвкÑи гÑеÑка: ниÑе ÑÑпело âsio_start()â"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "ÐÑомена пеÑме"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "ÐаÑедба за покÑеÑаÑе када ÐезоÑник запоÑиÑе Ð½Ð¾Ð²Ñ Ð¿ÐµÑмÑ."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>ÐаÑамеÑÑи пÑоÑлеÑени ÑÑÑÑи би ÑÑебало да бÑÐ´Ñ Ñ "
+"наводниÑима. Све дÑÑгаÑиÑе Ñе безбедноÑни Ñизик.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>ÐаÑедбе</b>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "ÐаÑедба:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "ÐаÑедба за покÑеÑаÑе пÑиликом поÑеÑка нове пеÑме:"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "ÐаÑедба за покÑеÑаÑе пÑи кÑаÑÑ Ð¿ÐµÑме."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "ÐаÑедба за покÑеÑаÑе пÑи кÑаÑÑ Ð¿ÐµÑме:"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "ÐаÑедба за покÑеÑаÑе када ÐезоÑник ÑÑигне на кÑÐ°Ñ ÑпиÑка нÑмеÑа."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "ÐаÑедба за покÑеÑаÑе пÑи кÑаÑÑ ÑпиÑка нÑмеÑа:"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
-msgstr ""
-"ÐаÑедба за покÑеÑаÑе када Ñе пÑомени наÑлов пеÑме (ÑÑ. наÑлови мÑежниÑ
"
-"Ñокова)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr "ÐаÑедба за покÑеÑаÑе када Ñе пÑомени наÑлов пеÑме (за мÑежне Ñокове):"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3800,9 +4062,8 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"ÐожеÑе да коÑиÑÑиÑе ÑледеÑе ниÑке ÑоÑмаÑа коÑе\n"
-"Ñе биÑи замеÑене пÑе позиваÑа наÑедбе\n"
-"(ниÑÑ Ñве коÑиÑне за наÑÐµÐ´Ð±Ñ ÐºÑаÑ-ÑпиÑка-нÑмеÑа):\n"
+"ÐожеÑе да коÑиÑÑиÑе ÑледеÑе ниÑке запиÑа коÑе Ñе биÑи замеÑене пÑе позиваÑа "
+"наÑедбе (ниÑÑ Ñве коÑиÑне за наÑÐµÐ´Ð±Ñ ÐºÑаÑа-ÑпиÑка-нÑмеÑа):\n"
"\n"
"%F: УÑеÑÑалоÑÑ (Ñ Ñ
еÑÑима)\n"
"%c: ÐÑÐ¾Ñ ÐºÐ°Ð½Ð°Ð»Ð°\n"
@@ -3810,25 +4071,21 @@ msgstr ""
"%l: ТÑаÑаÑе (Ñ Ð¼Ð¸Ð»Ð¸ÑекÑндама)\n"
"%n или %s: Ðазив пеÑме\n"
"%r: ÐÑоÑок (Ñ Ð±Ð¸Ñима Ñ ÑекÑнди)\n"
-"%t: ÐозиÑиÑа ÑпиÑка нÑмеÑа (%%02d)\n"
+"%t: ÐозиÑиÑа ÑпиÑка нÑмеÑа (%02d)\n"
"%p: ТÑенÑÑно пÑÑÑена (1 или 0)\n"
"%a: УмеÑник\n"
"%b: ÐлбÑм\n"
"%T: ÐаÑлов нÑмеÑе"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>ÐаÑамеÑÑи пÑоÑлеÑени ÑÑÑÑи би ÑÑебало да бÑÐ´Ñ Ñ "
-"наводниÑима. Све дÑÑгаÑиÑе Ñе безбедноÑни Ñизик.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "ÐодаÑи о пеÑми (ÐÑÑ)"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "ÐаÑедбе"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "СоÐС поновни ÑзоÑковаÑ"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3842,51 +4099,51 @@ msgstr ""
"ÐаÑновано на пÑикÑÑÑÐºÑ Ð¿ÑеÑваÑаÑа пÑоÑока ÑзоÑка:\n"
"ÐÑÑоÑÑка пÑава 2010-2012 Ðон ÐиндгÑин"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "ÐÑзо"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "ÐиÑко"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "ÐиÑоко"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "ÐÑло виÑоко"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "ÐвалиÑеÑ:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "СоÐС поновни ÑзоÑковаÑ"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "ÐÑзина и вÑÑ
ÑнаÑ"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>ÐÑзина и вÑÑ
ÑнаÑ</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "ÐÑзина:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "ÐÑÑ
ÑнаÑ:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "ÐÑзина и вÑÑ
ÑнаÑ"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "ÐкониÑа ÑÑаÑа"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "_ÐодеÑаваÑа ..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3904,39 +4161,39 @@ msgstr ""
"ÐÐ²Ð°Ñ Ð´Ð¾Ð´Ð°Ñак обезбеÑÑÑе икониÑÑ ÑÑаÑа, ÑмеÑÑенÑ\n"
"Ñ Ð¾Ð±Ð»Ð°ÑÑи Ñиоке ÑиÑÑема ÑпÑавника пÑозоÑа."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>РадÑа клизаÑа миÑем</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "ÐÑомени ÑаÑÐ¸Ð½Ñ Ð·Ð²Ñка"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "ÐÑомени пеÑмÑ"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>ÐÑÑала подеÑаваÑа</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "ÐÑкÑÑÑи пÑÐ¾Ð·Ð¾Ñ Ð¾Ð±Ð»Ð°ÑиÑа"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "ÐаÑвоÑи Ñ ÑиÑÑемÑÐºÑ ÐºÐ°ÑеÑÑ"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "ÐапÑедÑÑе Ñ ÑпиÑÐºÑ Ð½ÑмеÑа када клиза ÑнапÑед"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "ÐкониÑа ÑÑаÑа"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "ÐодаÑни ÑÑеÑео"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3946,24 +4203,24 @@ msgstr ""
"\n"
"ÐапиÑао га Ñе Ðон Ðевин, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>ÐодаÑни ÑÑеÑео</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "ÐодаÑни ÑÑеÑео"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "ТонÑки генеÑаÑоÑ"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "ТонÑки генеÑаÑоÑ: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3978,15 +4235,11 @@ msgstr ""
"ÑÑеÑÑалоÑÑ3;...\n"
"нпÑ.: tone://2000;2005 да пÑÑÑиÑе Ñонове 2000 Hz и 2005 Hz"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "ТонÑки генеÑаÑоÑ"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "УклаÑаÑе глаÑа"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4024,11 +4277,46 @@ msgstr ""
"ÐанкаÑло ÐаÑкÑÑо <gcp at sjeng.org>\n"
"ÐÑÑон ÐагидÑлин <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ðгг ÐоÑÐ±Ð¸Ñ Ð´ÐµÐºÐ¾Ð´ÐµÑ"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "ÐоÑединоÑÑи о â%sâ"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"ÐаÑлов: %t\n"
+"ÐзвоÑаÑ: %a\n"
+"Ðд: %f\n"
+"ÐÑаÑилаÑ: %T\n"
+"Ðапомена: %C\n"
+"ÐÑÑÑа Ñипа: %c\n"
+"СÑеÑео: %s\n"
+"ÐонавÑаÑе: %l\n"
+"УÑеÑÑаноÑÑ Ñипа: %F\n"
+"УÑеÑÑаноÑÑ Ð¿ÑÑÑаÑа: %P\n"
+"Ðодина: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "ÐТÐС декодеÑ"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4040,19 +4328,19 @@ msgstr ""
"ru>\n"
"ÐÑикÑÑÑак за ÐезоÑника Ñе напиÑао Ðавел ÐимеÑалек <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "ÐТÐС декодеÑ"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "ÐеÑвпак декодеÑ"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "оÑлабÑено (Ñ
ибÑидно)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "оÑлабÑено"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4062,14 +4350,18 @@ msgstr ""
"\n"
"ÐеÑÑо кода пÑикÑÑÑка Ñе напиÑао ÐаÑÐ»Ñ Ðган."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "ÐеÑвпак декодеÑ"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2СФ декодеÑ"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>ÐкÑСФ подеÑаваÑа</b>"
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "ÐанемаÑи ÑÑаÑаÑе из даÑоÑеке"
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "ÐкÑÐРдеÑиви ÑпиÑкови пÑÑÑаÑа (XSPF)"
diff --git a/po/sr_RS.po b/po/sr_RS.po
index b57770a1f39a..a8006e117659 100644
--- a/po/sr_RS.po
+++ b/po/sr_RS.po
@@ -3,14 +3,14 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# MirosNik <miroslavnikolic at rocketmail.com>, 2011-2012
+# ÐиÑоÑлав ÐÐ¸ÐºÐ¾Ð»Ð¸Ñ <miroslavnikolic at rocketmail.com>, 2011-2012
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Serbian (Serbia) (http://www.transifex.com/projects/p/"
"audacious/language/sr_RS/)\n"
"Language: sr_RS\n"
@@ -20,40 +20,28 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "моно"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "ÑÑеÑео"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "окÑÑжеÑе"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "Ðд пÑикÑÑÑак (ÐдÐибл пÑогÑам)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "низовни"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "Ðд пÑикÑÑÑак (ÐдÐибл пÑогÑам)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "ÐлаÑм"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -63,11 +51,7 @@ msgstr ""
"\n"
"ÐÑвобиÑни аÑÑоÑи ÑÑ Ðдам Фикин и ÐаниÑел СÑоден."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "ÐлаÑм"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -90,7 +74,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -112,7 +96,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -126,365 +110,371 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Ðво Ñе Ð²Ð°Ñ Ð¿Ð¾Ð·Ð¸Ð² за бÑÑеÑе."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr ""
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "ÐодÑеÑник"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "ÐонедеÑак"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "УÑоÑак"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "СÑеда"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "ЧеÑвÑÑак"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "ÐеÑак"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "СÑбоÑа"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "ÐедеÑа"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "ÐодеÑаваÑа алаÑма"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "ÐÑеме"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "ÐкÑивиÑÐ°Ñ Ð°Ð»Ð°Ñм Ñ (оÑновно):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "ÑаÑова"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "УÑиÑÐ°Ñ Ð½Ð°ÐºÐ¾Ð½:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "ÑаÑ(а)"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "минÑÑа"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "ÐзабеÑиÑе коÑим данима Ñе Ñе акÑивиÑаÑи алаÑм"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Ðан"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "ÐÑновно"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Ðани"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "ÐÑÑезаваÑе"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "ÑекÑнде"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "ÐаÑина"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "ÐапоÑни пÑи"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "ÐавÑÑи пÑи"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "ТÑенÑÑно"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "ÐодаÑна наÑедба"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "ÑкÑÑÑи"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "СпиÑак нÑмеÑа (необавезно)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "ÐзабеÑиÑе ÑпиÑак нÑмеÑа"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "ÐпÑиÑе"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "ШÑа знаÑе ове опÑиÑе?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "ÐомоÑ"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "ÐÐ¼Ð¾Ñ Ð°Ð»Ð±Ñма"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "Ðзлаз ÐÐСÐ-е"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ÐÑикÑÑÑак излаза ÐÐСÐ-е за ÐезоÑника\n"
+"ÐÑÑоÑÑка пÑава 2009-2012 Ðон ÐиндгÑин\n"
+"\n"
+"ÐаÑ
ваÑÑÑем Ñе ÐилиÑÐ°Ð¼Ñ ÐиÑкокÑ, аÑÑоÑÑ ÐРпÑикÑÑÑка излаза ÐÐСÐ-е, ÑиÑи Ñе "
+"код ÑлÑжио као ÑÐ·Ð¾Ñ ÐºÐ°Ð´Ð° ÑпÑÑÑÑво ÐÐСÐ-е ниÑе било довоÑно."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "ÐÑновни ÐЦРÑÑеÑаÑ"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "ÐÑновни ÑÑеÑÐ°Ñ Ð¼ÐµÑаÑа"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "ÐЦРÑÑеÑаÑ:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "УÑеÑÐ°Ñ Ð¼Ð¸ÐºÑеÑа:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "ÐÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼ÐµÑаÑа:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "РеÑиÑе ÑÑви пÑекид"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "ÐÐÐÐÐ-ÐÑикÑÑÑак (ÐÐÐРпÑогÑам)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-"ÐÑикÑÑÑак излаза ÐÐСÐ-е за ÐезоÑника\n"
-"ÐÑÑоÑÑка пÑава 2009-2012 Ðон ÐиндгÑин\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
"\n"
-"ÐаÑ
ваÑÑÑем Ñе ÐилиÑÐ°Ð¼Ñ ÐиÑкокÑ, аÑÑоÑÑ ÐРпÑикÑÑÑка излаза ÐÐСÐ-е, ÑиÑи Ñе "
-"код ÑлÑжио као ÑÐ·Ð¾Ñ ÐºÐ°Ð´Ð° ÑпÑÑÑÑво ÐÐСÐ-е ниÑе било довоÑно."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "Ðзлаз ÐÐСÐ-е"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "ÐÐÐÐÐ-ÐÑикÑÑÑак (ÐÐÐРпÑогÑам)"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "ÐÐÐÐРпÑикÑÑÑак â изабеÑиÑе СаÑÐ½Ð´Ð¤Ð¾Ð½Ñ Ð´Ð°ÑоÑекÑ"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Ðазив даÑоÑеке"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "ÐелиÑина (баÑÑова)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Ðазив:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> ÐÐÐÐ ÐнÑоÑмаÑиÑе </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "ФоÑмаÑ:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "ТÑаÑаÑе (msec):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "ÐÑÐ¾Ñ Ð½ÑмеÑа:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "пÑоменÑиво"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "ÐÐÐ:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "ÐÐÐ (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Ðив вÑеме:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> ÐÐÐРкоменÑаÑи и ÑекÑÑови пеÑама </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* нема доÑÑÑпниÑ
коменÑаÑа Ñ Ð¾Ð²Ð¾Ñ ÐÐÐРдаÑоÑеÑи *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* нема доÑÑÑпниÑ
ÑекÑÑова пеÑама Ñ Ð¾Ð²Ð¾Ñ ÐÐÐРдаÑоÑеÑи *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_ÐаÑвоÑи"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (неиÑпÑаван УТФ-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "Ð ÐÐÐÐРпÑикÑÑÑкÑ"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -495,152 +485,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "ÐÐСР(ÐÑиказ на екÑанÑ)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ÐÑавоÑгаоник"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "ÐаобÑени пÑавоÑгаоник"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "УдÑбÑен пÑавоÑгаоник"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "ÐиÑÑа"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "ÐоÑеÑак ÑепÑодÑкÑиÑе"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "ÐÑиказÑÑе ÐСРкада поÑиÑе ÑепÑодÑкÑиÑа пеÑме."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "ÐÑомена наÑлова"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"ÐÑиказÑÑе ÐСРкада Ñе, Ñ ÑÐ¾ÐºÑ ÑепÑодÑкÑиÑе, измени наÑлов пеÑме али назив "
-"даÑоÑеке оÑÑане иÑÑи. Ðво Ñе Ñглавном коÑиÑно за пÑиказиваÑе измена Ñ "
-"наÑловима Ñ Ð¸Ð½ÑеÑÐ½ÐµÑ Ñоковима."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "ÐаÑзиÑаÑе"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "ÐÑиказÑÑе ÐСРкада Ñе ÑепÑодÑкÑиÑа пÑивÑемено заÑÑÑавÑена."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "ÐÑпаÑзиÑаÑе"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "ÐÑиказÑÑе ÐСРкада Ñе ÑепÑодÑкÑиÑа поново покÑенÑÑа."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "ÐоÑÑавÑаÑе"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "РелаÑиван Ñ
оÑизонÑални помеÑаÑ:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "РелаÑиван веÑÑикални помеÑаÑ:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "ÐаÑвеÑа ÑиÑина пÑиказа:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "ÐпÑиÑа виÑе мониÑоÑа"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "ÐÑикажи ÐСРна:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "Ñвим мониÑоÑима"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "на мониÑоÑÑ Ð±Ñ. %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "ÐÑеме ÑÑаÑаÑа (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "ÐÑиказ:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "ÐоÑавÑиваÑе:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "ÐÑÑезаваÑе:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Словни ликови"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "ÐиÑмо %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Сенка"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "СÑил иÑÑÑÑаваÑа"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "ÐоÑе"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "ÐоÑа %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "ÐмогÑÑи акÑивиÑаÑе"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "ÐогаÑаÑ"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "ÐÑкÑивен Ñе композиÑни ÑпÑавник"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -650,112 +634,112 @@ msgstr ""
"оÑим ако знаÑе да Ñе Ñедан Ð²ÐµÑ Ð¿Ð¾ÐºÑенÑÑ, молим покÑениÑе композиÑног "
"ÑпÑавника ÑÐµÑ Ñ ÑÑпÑоÑном ÐСРнеÑе ÑадиÑи иÑпÑавно"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "ÐомпозиÑни ÑпÑавник ниÑе поÑÑебан за Ð»Ð°Ð¶Ð½Ñ Ð¿ÑовидноÑÑ"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "ÐÑовидноÑÑ"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Ðажна пÑовидноÑÑ"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "СÑваÑна пÑовидноÑÑ (заÑ
Ñева Ð¥ композиÑно пÑоÑиÑеÑе)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "ÐомпозиÑно пÑоÑиÑеÑе ниÑе ÑÑиÑано"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "ÐомпозиÑно пÑоÑиÑеÑе ниÑе доÑÑÑпно"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>ÐезоÑник â ÐСÐ</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "ÐезоÑник ÐСРâ подеÑаваÑа"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "ÐоложаÑ"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "ÐнимаÑиÑа"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "ТекÑÑ"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "ÐекоÑаÑиÑа"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "УкÑÑÑиваÑе"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "ÐÑÑало"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ÐСÐкÑв1/ÐСÐкÑв2 ÑпиÑкови нÑмеÑа"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "ÐезоÑникови ÑпиÑкови нÑмеÑа (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>ÐоÑе</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "Ðбим замÑÑеÑа"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "ÐоÑÐµÑ ÑÑеÑеоÑонÑки-Ñ-бинаÑÑални (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "ÐÑеÑподеÑаваÑа:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Ðиво довода:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "УÑеÑÑаноÑÑ Ð¸ÑеÑаÑа:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "ÐÑеÑподеÑаваÑа:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "ÐоÑÐµÑ ÑÑеÑеоÑонÑки-Ñ-бинаÑÑални (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "ÐнализаÑÐ¾Ñ ÑпекÑÑа"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "ÐÑикÑÑÑак звÑÑног ЦÐ-а"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -775,171 +759,156 @@ msgstr ""
"\n"
"ÐеÑе Ñо ÐÑгл леÑо пÑоÑекÑа Ðôд 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>УÑеÑаÑ</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "ÐÑзина ÑиÑаÑа:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "ÐÑепиÑи ÑÑеÑаÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>ÐеÑаподаÑи</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "ÐоÑиÑÑи ЦÐ-ÑекÑÑ"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "ÐоÑиÑÑи ЦÐÐÐ"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "ÐоÑиÑÑи ХТТРÑмеÑÑо ЦÐÐÐÐ-а"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "СеÑвеÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "ÐÑÑаÑа:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "ÐÑикÑÑÑник:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "ÐÑикÑÑÑак звÑÑног ЦÐ-а"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "ÐиÑам ÑÑпео да запоÑнем ÑдÑи подÑиÑÑем."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "ÐеиÑпÑавна пÑÑаÑа â%sâ."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "ÐиÑам пÑонаÑао нÑмеÑÑ â%dâ."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "ÐиÑам ÑÑпео да оÑвоÑим излаз звÑка."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "ÐÑдио ЦÐ"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "ÐиÑам ÑÑпео да оÑвоÑим ЦРÑÑеÑÐ°Ñ â%sâ."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "ÐиÑам пÑонаÑао ÑÑеÑÐ°Ñ Ð·Ð° ÑиÑаÑе ЦÐ-а."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "ÐиÑам ÑÑпео да завÑÑим покÑеÑаÑе оÑвоÑеног ЦРÑÑеÑаÑа."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "ÐиÑам ÑÑпео да пÑонаÑем бÑÐ¾Ñ Ð¿Ñве/поÑледÑе нÑмеÑе."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Ðе Ð¼Ð¾Ð³Ñ Ð´Ð° пÑоÑиÑам поÑеÑак/кÑÐ°Ñ ÐСÐ-а за нÑмеÑÑ â%dâ."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "ÐиÑам ÑÑпео да напÑавим Ð²ÐµÐ·Ñ Ñа Ñд базом подаÑака."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "ÐиÑам ÑÑпео да пÑопиÑам ÑеÑÐ²ÐµÑ Ð±Ð°Ð·Ðµ подаÑака ЦÐ-а"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "ÐиÑам ÑÑпео да пÑопиÑам ÑеÑÐ²ÐµÑ Ð±Ð°Ð·Ðµ подаÑака ЦÐ-а: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "ÐиÑам ÑÑпео да пÑоÑиÑам обавеÑÑеÑе базе подаÑака Ñд-а: %s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "УÑеÑÐ°Ñ Ñе пÑазан."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "ÐеподÑжана вÑÑÑа диÑка."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "СÑавке избоÑника звÑÑног ЦÐ-а"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "ÐÑÑÑи ЦÐ"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "ÐÐ¾Ð´Ð°Ñ Ð¦Ð"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "СÑавке избоÑника звÑÑног ЦÐ-а"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>СажимаÑе</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "Ðлавна ÑаÑина:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "ÐинамиÑки опÑег:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"ÐÑикÑÑÑак ÑажимаÑа динамиÑког опÑега за ÐезоÑника\n"
-"ÐÑÑоÑÑка пÑава 2010-2012 Ðон ÐиндгÑин"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "СажимаÑÐµÑ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñког опÑега"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -954,206 +923,225 @@ msgstr ""
"ÐилиÑам ÐиÑкок <nenolod at dereferenced.org>, \n"
"Ð¨Ð°Ñ ÐÑин <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ÐиÑки Ñонови:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "ÐиÑоки Ñонови:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "ÐÑновно ÑÑаÑаÑе пеÑме:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "УкÑÑÑи поновно ÑзоÑковаÑе"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "ÐÑоÑок поновног ÑзоÑковаÑа:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "ÐанемаÑи ÑÑаÑаÑе из СÐЦ ознака"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "ÐовеÑÐ°Ñ Ð¾Ð´Ñек"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Ðонзолни мÑзиÑки Ð´ÐµÐºÐ¾Ð´ÐµÑ Ð¸Ð³Ñе"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-"ÐоÑÑепени пÑелаз ниÑе ÑÑпео ÑÐµÑ Ñе пеÑма имала ÑазлиÑÐ¸Ñ Ð±ÑÐ¾Ñ ÐºÐ°Ð½Ð°Ð»Ð°. ÐожеÑе "
-"да коÑиÑÑиÑе ÐеÑаÑа канала да пÑеÑвоÑиÑе пеÑме на иÑÑи бÑÐ¾Ñ ÐºÐ°Ð½Ð°Ð»Ð°."
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"ÐоÑÑепени пÑелаз ниÑе ÑÑпео ÑÐµÑ Ñе пеÑма имала ÑазлиÑÐ¸Ñ Ð¿ÑоÑок ÑзоÑка. "
-"ÐожеÑе да коÑиÑÑиÑе ÐÑеÑваÑаÑа пÑоÑока ÑзоÑка да пÑеÑвоÑиÑе пеÑме на иÑÑи "
-"пÑоÑок ÑзоÑка."
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"ÐÑикÑÑÑак поÑÑепеног пÑелаза за ÐезоÑника\n"
-"ÐÑÑоÑÑка пÑава 2010-2012 Ðон ÐиндгÑин"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>ÐоÑÑепени пÑелаз</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "ÐÑеклапаÑе:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "ÐоÑÑепени пÑелаз"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"ÐоÑÑепени пÑелаз ниÑе ÑÑпео ÑÐµÑ Ñе пеÑма имала ÑазлиÑÐ¸Ñ Ð±ÑÐ¾Ñ ÐºÐ°Ð½Ð°Ð»Ð°. ÐожеÑе "
+"да коÑиÑÑиÑе ÐеÑаÑа канала да пÑеÑвоÑиÑе пеÑме на иÑÑи бÑÐ¾Ñ ÐºÐ°Ð½Ð°Ð»Ð°."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"ÐоÑÑепени пÑелаз ниÑе ÑÑпео ÑÐµÑ Ñе пеÑма имала ÑазлиÑÐ¸Ñ Ð¿ÑоÑок ÑзоÑка. "
+"ÐожеÑе да коÑиÑÑиÑе ÐÑеÑваÑаÑа пÑоÑока ÑзоÑка да пÑеÑвоÑиÑе пеÑме на иÑÑи "
+"пÑоÑок ÑзоÑка."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>ÐÑиÑÑализаÑоÑ</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "ÐакоÑÑ:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "ÐÑиÑÑализаÑоÑ"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "ÐÑикÑÑÑак âcueâ Ñабеле"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "ÐбÑиÑи"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "ÐÑкажи"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>ÐдÑек</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "ÐаÑÑоÑ:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Ðдзив:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "ÐаÑина звÑка:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"ÐÑикÑÑÑак одÑека\n"
-"ÐÑÑÐ¾Ñ ÐоÑ
ан Ðевин 1999\n"
-"\n"
-"ÐкÑÑжеÑе одÑека Ñе напиÑао ÐаÑл ван Шаик, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "ÐдÑек"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "ÐÑикÑÑÑак ФФмпег-а"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1169,55 +1157,55 @@ msgstr ""
"ÐилиÑам ÐиÑкок <nenolod at nenolod.net>\n"
"ÐаÑи ХамалаÑнен <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "ÐÑикÑÑÑак ФФмпег-а"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "ÐÑикÑÑÑак запиÑиваÑа даÑоÑека"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "ФоÑÐ¼Ð°Ñ Ð¸Ð·Ð»Ð°Ð·Ð½Ðµ даÑоÑеке:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "ÐодеÑи"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "СаÑÑÐ²Ð°Ñ Ñ Ð¾Ñигиналном диÑекÑоÑиÑÑмÑ"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "СаÑÑÐ²Ð°Ñ Ñ Ð¿ÑоизвоÑном диÑекÑоÑиÑÑмÑ"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "ФаÑÑикла излазне даÑоÑеке:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "ÐзабеÑиÑе ÑаÑÑиклÑ"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Ðабави име даÑоÑеке из:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "ознаке оÑигиналне даÑоÑеке"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "назива оÑигиналне даÑоÑеке"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Ðе одÑÐ·Ð¸Ð¼Ð°Ñ Ð¿ÑоÑиÑеÑе назива даÑоÑеке"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "ÐÑÐ¸Ð´Ð¾Ð´Ð°Ñ Ð±ÑÐ¾Ñ Ð½ÑмеÑе Ð½Ð°Ð·Ð¸Ð²Ñ Ð´Ð°ÑоÑеке"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1249,165 +1237,169 @@ msgstr ""
"âFree Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA "
"02110-1301, USAâ."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "ÐÑикÑÑÑак запиÑиваÑа даÑоÑека"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "СамоÑÑално"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "УдÑÑжени ÑÑеÑео"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "СÑеÑео"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Ðоно"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "ÐÐ3 подеÑаваÑа"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "ÐвалиÑÐµÑ Ð°Ð»Ð³Ð¾ÑиÑма:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "ÐÑоÑок ÑзоÑка излаза:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "ÐÑоÑок биÑа / ÐÐ´Ð½Ð¾Ñ ÑажимаÑа:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ÐÑоÑок биÑа (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "ÐÐ´Ð½Ð¾Ñ ÑажимаÑа:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Режим звÑка:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Разно:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "ÐÑиÑили ÑÑÑого ÐСРпоÑÑоваÑе"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "ÐÑеÑка заÑÑиÑе"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "ÐвалиÑеÑ"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "УкÑÑÑи ÐÐÐ /ÐÐÐ "
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "ÐÑÑÑа:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "ÐÐРопÑиÑе:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "ÐаÑмаÑи пÑоÑок биÑа (kb/s):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "ÐаÑвеÑи пÑоÑок биÑа (kb/s):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "СÑÑого ÑпÑоведи наÑмаÑи пÑоÑок биÑа"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ÐÐРопÑиÑе:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "ÐÑоÑеÑни пÑоÑок биÑа (kb/s):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "Ðиво ÐÐРквалиÑеÑа:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Ðе запиÑÑÑ Ð¥Ð¸Ð½Ð³ ÐÐРзаглавÑе"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "ÐÐÐ /ÐÐÐ "
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "ÐаÑамеÑÑи кадÑа:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "ÐзнаÑи као аÑÑоÑÑко пÑаво"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "ÐзнаÑи као оÑигинал"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ÐÐ3 паÑамеÑÑи:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "ÐÑиÑили додаваÑе ознаке издаÑа 2"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "ÐÐ¾Ð´Ð°Ñ Ñамо в1 ознакÑ"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "ÐÐ¾Ð´Ð°Ñ Ñамо в2 ознакÑ"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Ðзнаке"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "ÐодеÑаваÑе ÐоÑÐ±Ð¸Ñ ÑиÑÑеÑа"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Ðиво квалиÑеÑа (0 â 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "ФÐÐЦ декодеÑ"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "без гÑбиÑака"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1419,11 +1411,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "ФÐÐЦ декодеÑ"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1431,11 +1419,19 @@ msgstr ""
"ÐУРпÑикÑÑÑак за ÐезоÑника\n"
"ÐÑÑоÑÑка пÑава 2009-2012 Ðон ÐиндгÑин"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "ÐУРпÑикÑÑÑак"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1447,450 +1443,509 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-msgstr ""
-"ÐÑикÑÑÑак Ðномове пÑеÑиÑе\n"
-"ÐмогÑÑава вам да ÑпÑавÑаÑе пÑогÑамом коÑиÑÑеÑи Ðномове пÑеÑиÑе.\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
"\n"
-"ÐÑÑоÑÑка пÑава (C) 2007-2008 СаÑа ХлаÑÑак <contact at saschahlusiak.de>"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Ðномове пÑеÑиÑе"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "ÐÑÐ¾Ñ ÑÑавке"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "ÐаÑлов"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "ÐзвоÑаÑ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Ðодина"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "ÐлбÑм"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "ÐÑмеÑа"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "ÐанÑ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "ÐÐ¾Ð»Ð¾Ð¶Ð°Ñ ÐºÐ¾Ð»Ð¾Ð½Ðµ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "ТÑаÑаÑе"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "ÐÑÑаÑа даÑоÑеке"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Ðазив даÑоÑеке"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "ÐÑоизвоÑан наÑлов"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ÐиÑÑки пÑоÑок"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "ÐÐ»Ð°Ñ Ð·Ð° пÑеÑÑагÑ"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "УÑидÑи на лево"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "УÑидÑи на деÑно"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "УÑидÑи на вÑÑ
"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "УÑидÑи на дно"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "ÐÑкаÑи"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "ÐÑкÑÑÑи"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "ÐÐ»Ð°Ñ Ð·Ð° пÑеÑÑагÑ"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "ÐÑвоÑи _даÑоÑеке ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "ÐÑвоÑи _адÑеÑÑ ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "ÐÐ¾Ð´Ð°Ñ Ð´Ð°_ÑоÑеке ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "ÐÐ¾Ð´Ð°Ñ Ð°Ð´_ÑеÑÑ ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "Ð _пÑогÑÐ°Ð¼Ñ ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_ÐзаÑи"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "ÐÑ_ÑÑи"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "Ðа_ÑзиÑаÑ"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_ÐаÑÑÑави"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_ÐÑеÑÑ
одно"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "С_ледеÑе"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Ðонови"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_ÐаÑÑмиÑно"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Ð_е напÑедÑÑ Ñ ÑпиÑÐºÑ Ð½ÑмеÑа"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "ÐодаÑи о _пеÑми ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "ÐÑеÑи на _вÑеме ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "ÐÑеÑи на _пеÑÐ¼Ñ ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "ÐÑема _наÑловÑ"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "ÐÑема бÑоÑÑ _нÑмеÑе"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "ÐÑема _извоÑаÑÑ"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "ÐÑема _даÑÑÐ¼Ñ Ð¸Ð·Ð´Ð°Ð²Ð°Ñа"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "ÐÑема _пÑÑаÑи даÑоÑеке"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "ÐÑема п_ÑоизвоÑном наÑловÑ"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "ÐÑеокÑени п_оÑедак"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_СлÑÑаÑан поÑедак"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "_ÐÑÑÑи Ð¾Ð²Ð°Ñ ÑпиÑак нÑмеÑа"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_ÐÑвежи"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "ÐоÑ_еÑаÑ"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "Уклони _недоÑÑÑпне даÑоÑеке"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Ðово"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "_ÐÑеименÑÑ ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "Ув_ези ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "Ðз_вези ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "УпÑавник ÑпиÑка _нÑмеÑа ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "УпÑавник _ÑедоÑледа ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Ðо_ÑаÑаÑ"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "У_ÑиÑаÑ"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "УÑе_днаÑаваÑ"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "ÐÑикажи ÑÑÐ°ÐºÑ _избоÑника"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "ÐÑикажи ÑÑÐ°ÐºÑ _подаÑака"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "ÐÑикажи _визÑелизаÑиÑÑ ÑÑаке обавÑÑеÑа"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "ÐÑикажи ÑÑÐ°ÐºÑ _ÑÑаÑа"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_ÐаÑоÑека"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_ÐзвоÑеÑе"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_СпиÑак нÑмеÑа"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_УÑлÑге"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_Ðзлаз"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_ÐÑеглед"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_СÑави Ñ Ñед/ÐзбаÑи из Ñеда"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "_ÐÑеÑи"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "У_множи"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "У_баÑи"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "_ÐзабеÑи Ñве"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "_ÐÑеименÑÑ ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "ÐТРÑÑÑеÑе"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s â ÐезоÑник"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ÐаÑеÑÑÑем ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "ÐезоÑник"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "моно"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "ÑÑеÑео"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
@@ -1898,84 +1953,98 @@ msgstr[0] "%d канал"
msgstr[1] "%d канала"
msgstr[2] "%d Ñедан канал"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kb/s"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "ÐедноÑÑавни Ñежим."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Режим ÑпиÑка нÑмеÑа."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "ÐаÑÑÑавÑа након пеÑме."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr ""
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "ÐÑÑÑи"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "ÐаÑзиÑаÑ/наÑÑави"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "ÐаÑÑÑави"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr ""
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr ""
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "ÐÑкÑÑÑи звÑк"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr ""
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr ""
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr ""
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "ÐÑикажи пÑиказ на екÑанÑ"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(ниÑÑа)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1986,15 +2055,11 @@ msgstr ""
"\n"
"Ðа ли желиÑе да наÑÑавиÑе?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "ÐовезÑÑем дÑгмад миÑа"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "ÐодеÑаваÑа пÑикÑÑÑка опÑÑиÑ
пÑеÑиÑа"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2002,23 +2067,27 @@ msgstr ""
"ÐÑиÑиÑниÑе комбинаÑиÑÑ ÑаÑÑеÑа ÑнÑÑÐ°Ñ Ð¿Ð¾Ñа за ÑекÑÑ.\n"
"ÐожеÑе ÑакоÑе да повежеÑе дÑгмад миÑа."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "ÐÑеÑиÑе:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>РадÑа:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>Свезе ÑаÑÑеÑа:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "ÐпÑÑе пÑеÑиÑе"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2045,60 +2114,51 @@ msgstr ""
" ÐонаÑан Ð. ÐÐ°Ð²Ð¸Ñ <davis at jdhouse.org>\n"
" ÐеÑеми Тан <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "ÐпÑÑе пÑеÑиÑе"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "ÐÐРизлаз"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"ÐаÑновано на икÑммÑ-ÑекÑ, коÑи Ñе пÑиÑедио ÐÑÐ¸Ñ ÐоÑган:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ðакомо ÐоÑиÑо Ñе пÑипÑемио за ÐезоÑника"
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "ÐÐРизлаз"
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "ÐодеÑаваÑа за %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "ÐодеÑаваÑа ÐÐÐСÐРдомаÑинÑ"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "ÐÑÑаÑе модÑла:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2109,25 +2169,25 @@ msgstr ""
"Ðакон додаваÑа новиÑ
пÑÑаÑа, пÑиÑиÑниÑе УнеÑи да поÑÑажиÑе нове пÑикÑÑÑке.</"
"small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "ÐоÑÑÑпни пÑикÑÑÑÑи:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "УкÑÑÑи"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "УкÑÑÑени пÑикÑÑÑÑи:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "ÐодеÑаваÑа"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2135,47 +2195,15 @@ msgstr ""
"ÐÐÐСÐРдомаÑин за ÐезоÑника\n"
"ÐÑÑоÑÑка пÑава 2011 Ðон ÐиндгÑин"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "ÐÐÐСÐРдомаÑин"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: не Ð¼Ð¾Ð³Ñ Ð´Ð° запоÑнем ÐÐРЦ подÑÑкÑ\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: не Ð¼Ð¾Ð³Ñ Ð´Ð° пÑоÑиÑам даÑоÑÐµÐºÑ ÐÐРЦ подеÑаваÑа\n"
-"%s: молим пÑоÑиÑаÑÑе ÐÐРЦ докÑменÑаÑиÑÑ\n"
-"%s: како да напÑавиÑе лиÑÐ½Ñ Ð´Ð°ÑоÑÐµÐºÑ Ð¿Ð¾Ð´ÐµÑаваÑа\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: покÑÑавам да Ñе поново повежем...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: непознаÑа наÑедба â%sâ\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: пÑекинÑÑа Ñе веза Ñа ÐÐРЦ-а\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: покÑÑаÑÑ Ð´Ð° Ñе поново повежем Ñваке %d ÑекÑнде...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "ÐÐРЦ пÑикÑÑÑак"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2204,73 +2232,81 @@ msgstr ""
"\n"
"Ðа ÑазнаÑе виÑе о ÐÐРЦ-Ñ, погледаÑÑе âhttp://lirc.orgâ."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>Ðеза</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "Ðоново Ñе повежи Ñа ÐÐРЦ ÑеÑвеÑом"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "СаÑÐµÐºÐ°Ñ Ð¿Ñе поновног повезиваÑа:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "ÐÐРЦ пÑикÑÑÑак"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "ÐÑикÑÑÑак за ÐиÑик вики"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "Ðема доÑÑÑпниÑ
ÑекÑÑова"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "ÐÑеÑка"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Ðе Ð¼Ð¾Ð³Ñ Ð´Ð° довÑÑем â%sâ"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "ÐÑеÑка"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Ðе Ð¼Ð¾Ð³Ñ Ð´Ð° обÑадим â%sâ"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "ТÑажим ÑекÑÑ Ð¿ÐµÑме ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "ÐедоÑÑаÑÑ Ð¼ÐµÑаподаÑи пеÑме"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "ÐовезÑÑем Ñе на âlyrics.wikia.comâ ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "ÐÑикÑÑÑак за ÐиÑик вики"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "Ð3У ÑпиÑак нÑмеÑа"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑа"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑа: %d оÑк/мин"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑа: %d оÑк/мин %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2284,11 +2320,11 @@ msgstr ""
"нпÑ.: âtact://77â да добиÑеÑе 77 оÑкÑÑаÑа Ñ Ð¼Ð¸Ð½ÑÑÑ\n"
"или: âtact://60*3/4â да добиÑеÑе 60 оÑк./мин Ñ 3/4 ÑакÑÑ"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑа"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "ÐеÑÐ°Ñ ÐºÐ°Ð½Ð°Ð»Ð°"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2296,152 +2332,184 @@ msgstr ""
"ÐÑикÑÑÑак меÑаÑа канала за ÐезоÑника\n"
"ÐÑÑоÑÑка пÑава 2011-2012 Ðон ÐиндгÑин и ÐиÑ
ал ÐипÑки"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>ÐеÑÐ°Ñ ÐºÐ°Ð½Ð°Ð»Ð°</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "Ðзлазни канали:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "ÐеÑÐ°Ñ ÐºÐ°Ð½Ð°Ð»Ð°"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "ÐÐС пÑикÑÑÑак"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "Ðод пÑикÑÑÑак (ÐÑогÑам за модле)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr ""
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr ""
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr ""
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr ""
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr ""
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr ""
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "Ðод пÑикÑÑÑак (ÐÑогÑам за модле)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "ÐкÑÑжеÑе"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "ÐÐÐ123 пÑикÑÑÑак"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "ÐкÑÑжеÑе"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "ÐÐÐ ÐС 2 ÑеÑвеÑ"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Ðеон ХТТÐ/ХХТÐС пÑикÑÑÑак"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "ÐаÑÑÑавÑено"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "ÐезоÑник не пÑÑÑа пеÑме."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "ÐбавеÑÑеÑа Ñадне повÑÑи"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2461,55 +2529,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "ÐбавеÑÑеÑа Ñадне повÑÑи"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr ""
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "ÐаÑзиÑаÑ"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "СледеÑа"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. ÐÑновни ÑÑеÑаÑ"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "ÐСС4 излаз"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "ÐвÑÑни ÑÑеÑаÑ:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "ÐоÑиÑÑи алÑеÑнаÑивни ÑÑеÑаÑ:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "СаÑÑваÑÑе ÑаÑÐ¸Ð½Ñ Ð·Ð²Ñка измеÑÑ ÑеÑиÑа."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "УкÑÑÑÑÑе пÑеÑваÑаÑе ÑоÑмаÑа напÑавÑено ÐСС ÑоÑÑвеÑом."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "УкÑÑÑÑÑе иÑкÑÑÑиви Ñежим да ÑпÑеÑи виÑÑÑално меÑаÑе."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2523,19 +2600,35 @@ msgstr ""
"Ðелим да Ñе заÑ
валим ÑÑдима на â#audaciousâ, наÑоÑиÑо Тони ÐÑÑÐ½Ñ Ð¸ ÐÐ¾Ð½Ñ "
"ÐиндгÑÐ¸Ð½Ñ Ð¸ наÑавно аÑÑоÑима пÑеÑÑ
одног ÐСС пÑикÑÑÑка."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "ÐСС4 излаз"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "ÐÐС ÑпиÑкови нÑмеÑа"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "ÐпенÐСФ ÐСФ1/ÐСФ2 декодеÑ"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "ÐÑлÑâаÑдио излаз"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2572,11 +2665,68 @@ msgstr ""
"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "ÐÑлÑâаÑдио излаз"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ÐÑеÑÑ
одна"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Ðонови"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "ÐаÑÑмиÑно"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "ÐÑеÑваÑÐ°Ñ Ð¿ÑоÑока ÑзоÑка"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2584,133 +2734,145 @@ msgstr ""
"ÐÑикÑÑÑак ÐÑеÑваÑаÑа пÑоÑока ÑзоÑка за ÐезоÑника\n"
"ÐÑÑоÑÑка пÑава 2010-2012 Ðон ÐиндгÑин"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "ÐÑеÑкоÑи/понови ÑзоÑке"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "ÐиниÑÑко ÑмеÑаÑе"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "ÐÑзо ÑмеÑаÑе ÑÑклаÑеÑа"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "СÑедÑе ÑмеÑаÑе ÑÑклаÑеÑа"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "ÐаÑбоÑе ÑмеÑаÑе ÑÑклаÑеÑа"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>ÐÑеÑваÑаÑе</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "ÐеÑод:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "ÐÑоÑок:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>ÐапиÑаÑе пÑоÑока</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "ÐоÑиÑÑи мапиÑаÑе пÑоÑока"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "ÐÑеÑваÑÐ°Ñ Ð¿ÑоÑока ÑзоÑка"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr ""
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr ""
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2721,17 +2883,17 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "СÐРизлаз"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2739,76 +2901,59 @@ msgstr ""
"ÐÑикÑÑÑак СÐРизлаза за ÐезоÑника\n"
"ÐÑÑоÑÑка пÑава 2010 Ðон ÐиндгÑин"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "СÐРизлаз"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "ÐиблиоÑека"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "ÐÐµÐ¿Ð¾Ð·Ð½Ð°Ñ Ð¸Ð·Ð²Ð¾ÑаÑ"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "ÐÐµÐ¿Ð¾Ð·Ð½Ð°Ñ Ð°Ð»Ð±Ñм"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" â%sâ изводи %s"
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
+msgid "%d result"
+msgid_plural "%d results"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_ÐапÑави ÑпиÑак нÑмеÑа"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_ÐÐ¾Ð´Ð°Ñ Ñ ÑпиÑак нÑмеÑа"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "ÐÑеÑÑажиÑе библиоÑекÑ"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2816,679 +2961,769 @@ msgstr ""
"Ðа ÑвезеÑе ваÑÑ Ð¼ÑзиÑÐºÑ Ð±Ð¸Ð±Ð»Ð¸Ð¾ÑÐµÐºÑ Ñ ÐезоÑникÑ, изабеÑиÑе ÑаÑÑÐ¸ÐºÐ»Ñ Ð¸ заÑим "
"кликниÑе на икониÑÑ âоÑвежиâ."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "Ðолим ÑаÑекаÑÑе ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "ÐзабеÑиÑе ÑаÑÑиклÑ"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "РепÑодÑкÑиÑа"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "СпиÑак нÑмеÑа"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Ðоглед"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Ðонови"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "ÐаÑÑмиÑно"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Ðе напÑедÑÑ Ñ ÑпиÑÐºÑ Ð½ÑмеÑа"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ÐÑеÑÑ
одна"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Ðови ÑпиÑак нÑмеÑа"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "ÐÑикажи ÑÑеÑÐ¸Ð²Ð°Ñ ÑпиÑка нÑмеÑа"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "ÐÑикажи ÑÑеднаÑаваÑ"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Увек Ñ Ð¿Ñвом планÑ"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "ÐÑема наÑловÑ"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "ÐÑема Ð½Ð°Ð·Ð¸Ð²Ñ Ð´Ð°ÑоÑеке"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Уклони Ñве"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "ÐбÑиÑи заказано"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Уклони недоÑÑÑпне даÑоÑеке"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Уклони дÑпликаÑе"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "Уклони неознаÑене"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Уклони ознаÑене"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "ÐÑеÑÑажи и ознаÑи"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "ÐбÑни избоÑ"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "ÐзнаÑи ниÑÑа"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "ÐзнаÑи Ñве"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "ÐÑема албÑмÑ"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "ÐÑема бÑоÑÑ Ð½ÑмеÑе"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "ÐÑема извоÑаÑÑ"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "ÐÑема албÑмÑ"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "ÐÑема бÑоÑÑ Ð½ÑмеÑе"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "ÐаÑÑмиÑе иÑпÑемеÑÑÐ°Ñ ÑпиÑак"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "ÐÑеокÑени ÑпиÑак"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "ÐоÑеÑÐ°Ñ Ð¾Ð·Ð½Ð°Ñене"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "ÐоÑеÑÐ°Ñ ÑпиÑак"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "ÐÑеÑи"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Умножи"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "УбаÑи"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Ðинампово ÑобиÑаÑено ÑÑÑеÑе"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "СаÑÑваÑ"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "УÑиÑаÑ"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "ÐÑеÑподеÑаваÑа"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "УÑиÑава пÑеÑподеÑаваÑе"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "УÑиÑава ÑамоÑÑално пÑеÑподеÑаваÑе"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "ЧÑва пÑеÑподеÑаваÑе"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "ЧÑва ÑамоÑÑално пÑеÑподеÑаваÑе"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "ÐзбÑиÑи пÑеÑподеÑаваÑе"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "ÐÑиÑе ÑамоÑÑално пÑеÑподеÑаваÑе"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_ÐлеÑеÑ:"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "ÐзабеÑиÑе Ñловни лик главног пÑозоÑа плеÑеÑа:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_СпиÑак нÑмеÑа:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "ÐзабеÑи Ñловни лик ÑпиÑка нÑмеÑа:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "ÐоÑиÑÑи биÑмап Ñловне ликове (подÑжава Ñамо ÐСÐÐ Ð)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "ÐомеÑÐ°Ñ Ð½Ð°Ñлов пеÑме Ñ Ð¾Ð±Ð° ÑмеÑа"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "ÐнализаÑоÑ"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "ÐоÑег"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "ÐÑкÑÑÑено"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "ÐоÑмалан"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "ÐаÑÑа"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "ÐиниÑе"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "ТÑаке"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "ÐаÑÑпоÑиÑе"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "СпоÑо"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "СÑедÑе"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "ÐÑзо"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "ÐаÑбÑже"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "Ðед"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "ÐлаÑко"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "ÐпÑÑе"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "ÐÑиказиваÑе"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "ÐÑеÑпоÑаÑаÑе"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "УÑеднаÑÐ°Ð²Ð°Ñ ÐезоÑника"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "ТÑажи до: %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "ÐаÑина звÑка: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "УÑавноÑеженоÑÑ: %d%% леви"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "УÑавноÑеженоÑÑ: ÑенÑÑиÑано"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "УÑавноÑеженоÑÑ: %d%% деÑни"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "ÐзбоÑник опÑиÑа"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "ÐÑкÑÑÑи âУвек Ñ Ð¿Ñвом планÑâ"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "УкÑÑÑи âУвек Ñ Ð¿Ñвом планÑâ"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "ÐоÑе инÑоÑмаÑиÑа о даÑоÑеÑи"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "ÐедноÑÑавни Ñежим."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Режим ÑпиÑка нÑмеÑа."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "ÐаÑÑÑавÑа након пеÑме."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "ÐÑеÑÑажи ÑÑавке Ñ Ð°ÐºÑивном ÑпиÑÐºÑ Ð½ÑмеÑа"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3500,57 +3735,61 @@ msgstr ""
"како обиÑни изÑази ÑÑнкÑиониÑÑ, ÑедноÑÑавно доÑловно ÑнеÑиÑе део онога ÑÑо "
"ÑÑажиÑе."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "ÐаÑлов: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "ÐлбÑм: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "ÐзвоÑаÑ: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "Ðазив даÑоÑеке: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "ÐбÑиÑи пÑеÑÑ
одни Ð¸Ð·Ð±Ð¾Ñ Ð¿Ñе пÑеÑÑаге"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "ÐодÑдаÑаÑÑÑе ÑÑавке ÑамоÑÑално пÑебаÑи Ñ Ñед"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "ÐапÑави нови ÑпиÑак нÑмеÑа Ñа подÑдаÑаÑÑÑим ÑÑавкама"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "УÑеÑÐ¸Ð²Ð°Ñ ÑпиÑка нÑмеÑа"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d од %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "ÐÑÑ
ивиÑана Ðинамп 2.x маÑка"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "ÐеаÑÑ
ивиÑана Ðинамп 2.x маÑка"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Ðе Ð¼Ð¾Ð³Ñ Ð´Ð° напÑавим ÑаÑÑÐ¸ÐºÐ»Ñ (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "ÐÑикÑÑÑак звÑÑне даÑоÑеке"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3591,83 +3830,71 @@ msgstr ""
"ÑоÑÑва на адÑеÑÑ: Free Software Foundation, Inc.,\n"
"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "ÐÑикÑÑÑак звÑÑне даÑоÑеке"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "РпÑикÑÑÑÐºÑ Ð·Ð²ÑÑногÑи излаза"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-"ÐÑикÑÑÑак звÑÑногÑи излаза\n"
-"\n"
-"ÐапиÑао га Ñе Ð¢Ð¾Ð¼Ð°Ñ ÐÑÐ°Ñ <tpfaff at tp76.info>\n"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "ÐеподÑжани облик даÑоÑеке"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-"ÐвÑÑни ÑÑеÑÐ°Ñ Ñе заÑÑажио неподÑжани облик даÑоÑеке.\n"
-"\n"
-"Ðолим покÑÑаÑÑе Ð¾Ð¿ÐµÑ Ñа покÑенÑÑим âsndiod(1)â ÑеÑвеÑом."
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "звÑÑниÑи ÑÑеÑаÑ"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(пÑазно знаÑи задаÑо)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "У ÑедÑ"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "ÐÑомена пеÑме"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "ÐаÑедба за покÑеÑаÑе када ÐезоÑник запоÑиÑе Ð½Ð¾Ð²Ñ Ð¿ÐµÑмÑ."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>ÐаÑамеÑÑи пÑоÑлеÑени ÑÑÑÑи би ÑÑебало да бÑÐ´Ñ Ñ "
+"наводниÑима. Све дÑÑгаÑиÑе Ñе безбедноÑни Ñизик.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "ÐаÑедба:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "ÐаÑедба за покÑеÑаÑе пÑи кÑаÑÑ Ð¿ÐµÑме."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "ÐаÑедба за покÑеÑаÑе када ÐезоÑник ÑÑигне на кÑÐ°Ñ ÑпиÑка нÑмеÑа."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"ÐаÑедба за покÑеÑаÑе када Ñе пÑомени наÑлов пеÑме (ÑÑ. наÑлови мÑежниÑ
"
-"Ñокова)."
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3681,35 +3908,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"ÐожеÑе да коÑиÑÑиÑе ÑледеÑе ниÑке ÑоÑмаÑа коÑе\n"
-"Ñе биÑи замеÑене пÑе позиваÑа наÑедбе\n"
-"(ниÑÑ Ñве коÑиÑне за наÑÐµÐ´Ð±Ñ ÐºÑаÑ-ÑпиÑка-нÑмеÑа):\n"
-"\n"
-"%F: УÑеÑÑалоÑÑ (Ñ Ñ
еÑÑима)\n"
-"%c: ÐÑÐ¾Ñ ÐºÐ°Ð½Ð°Ð»Ð°\n"
-"%f: Ðазив даÑоÑеке (пÑна пÑÑаÑа)\n"
-"%l: ТÑаÑаÑе (Ñ Ð¼Ð¸Ð»Ð¸ÑекÑндама)\n"
-"%n или %s: Ðазив пеÑме\n"
-"%r: ÐÑоÑок (Ñ Ð±Ð¸Ñима Ñ ÑекÑнди)\n"
-"%t: ÐозиÑиÑа ÑпиÑка нÑмеÑа (%%02d)\n"
-"%p: ТÑенÑÑно пÑÑÑена (1 или 0)\n"
-"%a: УмеÑник\n"
-"%b: ÐлбÑм\n"
-"%T: ÐаÑлов нÑмеÑе"
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>ÐаÑамеÑÑи пÑоÑлеÑени ÑÑÑÑи би ÑÑебало да бÑÐ´Ñ Ñ "
-"наводниÑима. Све дÑÑгаÑиÑе Ñе безбедноÑни Ñизик.</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "ÐаÑедбе"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3718,51 +3926,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr ""
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "ÐÑзина и вÑÑ
ÑнаÑ"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>ÐÑзина и вÑÑ
ÑнаÑ</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "ÐÑзина:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "ÐÑÑ
ÑнаÑ:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "ÐÑзина и вÑÑ
ÑнаÑ"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "ÐкониÑа ÑÑаÑа"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3780,39 +3988,39 @@ msgstr ""
"ÐÐ²Ð°Ñ Ð´Ð¾Ð´Ð°Ñак обезбеÑÑÑе икониÑÑ ÑÑаÑа, ÑмеÑÑенÑ\n"
"Ñ Ð¾Ð±Ð»Ð°ÑÑи Ñиоке ÑиÑÑема ÑпÑавника пÑозоÑа."
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>РадÑа клизаÑа миÑем</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "ÐÑомени ÑаÑÐ¸Ð½Ñ Ð·Ð²Ñка"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "ÐÑомени пеÑмÑ"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>ÐÑÑала подеÑаваÑа</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "ÐÑкÑÑÑи пÑÐ¾Ð·Ð¾Ñ Ð¾Ð±Ð»Ð°ÑиÑа"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "ÐаÑвоÑи Ñ ÑиÑÑемÑÐºÑ ÐºÐ°ÑеÑÑ"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "ÐапÑедÑÑе Ñ ÑпиÑÐºÑ Ð½ÑмеÑа када клиза ÑнапÑед"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "ÐкониÑа ÑÑаÑа"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "ÐодаÑни ÑÑеÑео"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3822,24 +4030,24 @@ msgstr ""
"\n"
"ÐапиÑао га Ñе Ðон Ðевин, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>ÐодаÑни ÑÑеÑео</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "ÐодаÑни ÑÑеÑео"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "ТонÑки генеÑаÑоÑ"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "ТонÑки генеÑаÑоÑ: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3854,15 +4062,11 @@ msgstr ""
"ÑÑеÑÑалоÑÑ3;...\n"
"нпÑ.: tone://2000;2005 да пÑÑÑиÑе Ñонове 2000 Hz и 2005 Hz"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "ТонÑки генеÑаÑоÑ"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "УклаÑаÑе глаÑа"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3900,11 +4104,35 @@ msgstr ""
"ÐанкаÑло ÐаÑкÑÑо <gcp at sjeng.org>\n"
"ÐÑÑон ÐагидÑлин <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ðгг ÐоÑÐ±Ð¸Ñ Ð´ÐµÐºÐ¾Ð´ÐµÑ"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "ÐТÐС декодеÑ"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -3916,19 +4144,19 @@ msgstr ""
"ru>\n"
"ÐÑикÑÑÑак за ÐезоÑника Ñе напиÑао Ðавел ÐимеÑалек <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "ÐТÐС декодеÑ"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "ÐеÑвпак декодеÑ"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "оÑлабÑено (Ñ
ибÑидно)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "оÑлабÑено"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -3938,14 +4166,18 @@ msgstr ""
"\n"
"ÐеÑÑо кода пÑикÑÑÑка Ñе напиÑао ÐаÑÐ»Ñ Ðган."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "ÐеÑвпак декодеÑ"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2СФ декодеÑ"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "ÐкÑÐРдеÑиви ÑпиÑкови пÑÑÑаÑа (XSPF)"
diff --git a/po/sv.po b/po/sv.po
new file mode 100644
index 000000000000..24703d7ffb52
--- /dev/null
+++ b/po/sv.po
@@ -0,0 +1,4012 @@
+# Swedish translation for Audacious Plugins
+# Copyright (C) Audacious translators
+# This file is distributed under the same license as the Audacious Plugins package.
+#
+# Translators:
+# Bo Serrander <bserrander at gmail.com>, 2013
+# Martin Jernberg <bittin at cafe8bitar.se>, 2014
+msgid ""
+msgstr ""
+"Project-Id-Version: Audacious Plugins\n"
+"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
+"Language-Team: Swedish (http://www.transifex.com/projects/p/audacious/"
+"language/sv/)\n"
+"Language: sv\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"
+
+#: src/aac-raw/aac.cc:18
+msgid "AAC (Raw) Decoder"
+msgstr "AAC (Raw) Dekoder"
+
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib Spelare)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
+msgid "sequenced"
+msgstr ""
+
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarm"
+
+#: src/alarm/alarm.cc:782
+msgid "Set Alarm ..."
+msgstr "Ställ in Alarm ..."
+
+#: src/alarm/alarm.cc:810
+msgid ""
+"A plugin that can be used to start playing at a certain time.\n"
+"\n"
+"Originally written by Adam Feakin and Daniel Stodden."
+msgstr ""
+
+#: src/alarm/interface.cc:28
+msgid ""
+"Time\n"
+" Alarm at:\n"
+" The time for the alarm to come on.\n"
+"\n"
+" Quiet after:\n"
+" Stop alarm after this amount of time.\n"
+" (if the wakeup dialog is not closed)\n"
+"\n"
+"\n"
+"Days\n"
+" Day:\n"
+" Select the days for the alarm to activate.\n"
+"\n"
+" Time:\n"
+" Choose the time for the alarm on each day,\n"
+" or select the toggle button to use the default\n"
+" time.\n"
+"\n"
+"\n"
+msgstr ""
+
+#: src/alarm/interface.cc:45
+msgid ""
+"Volume\n"
+" Fading:\n"
+" Fade the volume up to the chosen volume\n"
+" for this amount of time.\n"
+"\n"
+" Start at:\n"
+" Start fading from this volume.\n"
+"\n"
+" Final:\n"
+" The volume to stop fading at. If the fading\n"
+" time is 0 then set volume to this and start\n"
+" playing.\n"
+"\n"
+"\n"
+"Options:\n"
+" Additional Command:\n"
+" Run this command at the alarm time.\n"
+"\n"
+msgstr ""
+
+#: src/alarm/interface.cc:62
+msgid ""
+" Playlist:\n"
+" Load this playlist. If no playlist\n"
+" is given, the current one will be used.\n"
+" The URL of an mp3/ogg stream\n"
+" can also be entered here.\n"
+"\n"
+" Reminder:\n"
+" Display a reminder when the alarm goes off.\n"
+" Type the reminder in the box and turn on the\n"
+" toggle button if you want it to be shown."
+msgstr ""
+
+#: src/alarm/interface.cc:81
+msgid "This is your wakeup call."
+msgstr "Detta är din väckarklocka."
+
+#: src/alarm/interface.cc:99
+msgid "Your reminder for today is..."
+msgstr "Din påminelse idag är ..."
+
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
+msgid "Reminder"
+msgstr "PÃ¥minelse"
+
+#: src/alarm/interface.cc:132
+msgid "Monday"
+msgstr "MÃ¥ndag"
+
+#: src/alarm/interface.cc:132
+msgid "Tuesday"
+msgstr "Tisdag"
+
+#: src/alarm/interface.cc:132
+msgid "Wednesday"
+msgstr "Onsdag"
+
+#: src/alarm/interface.cc:133
+msgid "Thursday"
+msgstr "Torsdag"
+
+#: src/alarm/interface.cc:133
+msgid "Friday"
+msgstr "Fredag"
+
+#: src/alarm/interface.cc:133
+msgid "Saturday"
+msgstr "Lördag"
+
+#: src/alarm/interface.cc:133
+msgid "Sunday"
+msgstr "Söndag"
+
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
+msgid "Time"
+msgstr "Tid"
+
+#: src/alarm/interface.cc:178
+msgid "Alarm at (default):"
+msgstr "Larm på (standard):"
+
+#: src/alarm/interface.cc:200
+msgid "h"
+msgstr "h"
+
+#: src/alarm/interface.cc:203
+msgid "Quiet after:"
+msgstr "Tyst efter:"
+
+#: src/alarm/interface.cc:215
+msgid "hours"
+msgstr "timmar"
+
+#: src/alarm/interface.cc:226
+msgid "minutes"
+msgstr "minuter"
+
+#: src/alarm/interface.cc:235
+msgid "Choose the days for the alarm to come on"
+msgstr ""
+
+#: src/alarm/interface.cc:242
+msgid "Day"
+msgstr "Dag"
+
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
+msgid "Default"
+msgstr "Standard"
+
+#: src/alarm/interface.cc:288
+msgid "Days"
+msgstr "Dagar"
+
+#: src/alarm/interface.cc:297
+msgid "Fading"
+msgstr ""
+
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
+msgid "seconds"
+msgstr "sekunder"
+
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
+msgid "Volume"
+msgstr "Volym"
+
+#: src/alarm/interface.cc:317
+msgid "Start at"
+msgstr "Börja på"
+
+#: src/alarm/interface.cc:333
+msgid "Final"
+msgstr ""
+
+#: src/alarm/interface.cc:346
+msgid "Current"
+msgstr "Nuvarande"
+
+#: src/alarm/interface.cc:359
+msgid "Additional Command"
+msgstr "Ytterligare Kommando"
+
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
+msgid "enable"
+msgstr ""
+
+#: src/alarm/interface.cc:372
+msgid "Playlist (optional)"
+msgstr "Spellista (valfritt)"
+
+#: src/alarm/interface.cc:379
+msgid "Select a playlist"
+msgstr "Välj en spellista"
+
+#: src/alarm/interface.cc:399
+msgid "Options"
+msgstr "Inställningar"
+
+#: src/alarm/interface.cc:404
+msgid "What do these options mean?"
+msgstr "Vad betyder dessa inställningar?"
+
+#: src/alarm/interface.cc:420
+msgid "Help"
+msgstr "Hjälp"
+
+#: src/albumart/albumart.cc:31
+msgid "Album Art"
+msgstr "Skivomslag"
+
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA Utgång"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
+msgid "Default PCM device"
+msgstr ""
+
+#: src/alsa/config.cc:188
+msgid "Default mixer device"
+msgstr ""
+
+#: src/alsa/config.cc:296
+msgid "PCM device:"
+msgstr ""
+
+#: src/alsa/config.cc:299
+msgid "Mixer device:"
+msgstr ""
+
+#: src/alsa/config.cc:302
+msgid "Mixer element:"
+msgstr ""
+
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI Spelare)"
+
+#: src/amidi-plug/amidi-plug.cc:437
+msgid ""
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
+"\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:94
+msgid "Override default gain:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:102
+msgid "Override default polyphony:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:110
+msgid "Override default reverb:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
+msgid "On"
+msgstr "PÃ¥"
+
+#: src/amidi-plug/i_configure.cc:118
+msgid "Override default chorus:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
+msgid "<b>Playback</b>"
+msgstr "<b> Uppspelning </ b>"
+
+#: src/amidi-plug/i_configure.cc:129
+msgid "Transpose:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
+msgid "Drum shift:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:141
+msgid "<b>SoundFont</b>"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:143
+msgid "<b>Synthesizer</b>"
+msgstr "<b>Synthesizer</b>"
+
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
+msgid "AMIDI-Plug - select SoundFont file"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_Avbryt"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
+msgid "_Open"
+msgstr "_Ãppna"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "Filnamn"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
+msgid "Size (bytes)"
+msgstr "Storlek (bytes)"
+
+#: src/amidi-plug/i_fileinfo.cc:163
+msgid "Name:"
+msgstr "Namn:"
+
+#: src/amidi-plug/i_fileinfo.cc:181
+msgid "<span size=\"smaller\"> MIDI Info </span>"
+msgstr "<span size=\"smaller\"> MIDI Info </span>"
+
+#: src/amidi-plug/i_fileinfo.cc:195
+msgid "Format:"
+msgstr "Format:"
+
+#: src/amidi-plug/i_fileinfo.cc:198
+msgid "Length (msec):"
+msgstr "Längd (msec):"
+
+#: src/amidi-plug/i_fileinfo.cc:201
+msgid "No. of Tracks:"
+msgstr "Nummer av Spår:"
+
+#: src/amidi-plug/i_fileinfo.cc:207
+msgid "variable"
+msgstr "variabel"
+
+#: src/amidi-plug/i_fileinfo.cc:209
+msgid "BPM:"
+msgstr "BPM:"
+
+#: src/amidi-plug/i_fileinfo.cc:217
+msgid "BPM (wavg):"
+msgstr "BPM (wavg):"
+
+#: src/amidi-plug/i_fileinfo.cc:220
+msgid "Time Div:"
+msgstr ""
+
+#: src/amidi-plug/i_fileinfo.cc:231
+msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
+msgstr ""
+
+#: src/amidi-plug/i_fileinfo.cc:278
+msgid "* no comments available in this MIDI file *"
+msgstr "* Inga kommentarer finns i denna MIDI-fil *"
+
+#: src/amidi-plug/i_fileinfo.cc:290
+msgid "* no lyrics available in this MIDI file *"
+msgstr "* Inga texter finns i denna MIDI-fil *"
+
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
+msgid "_Close"
+msgstr "_Stäng"
+
+#: src/amidi-plug/i_fileinfo.cc:325
+msgid " (invalid UTF-8)"
+msgstr "(ogiltig UTF-8)"
+
+#: src/aosd/aosd.cc:32
+msgid ""
+"Audacious OSD\n"
+"http://www.develia.org/projects.php?p=audacious#aosd\n"
+"\n"
+"Written by Giacomo Lozito <james at develia.org>\n"
+"\n"
+"Based in part on Evan Martin's Ghosd library:\n"
+"http://neugierig.org/software/ghosd/"
+msgstr ""
+
+#: src/aosd/aosd.h:37
+msgid "AOSD (On-Screen Display)"
+msgstr ""
+
+#: src/aosd/aosd_style.cc:54
+msgid "Rectangle"
+msgstr "Rektangel"
+
+#: src/aosd/aosd_style.cc:59
+msgid "Rounded Rectangle"
+msgstr "Rundad Rektangel"
+
+#: src/aosd/aosd_style.cc:64
+msgid "Concave Rectangle"
+msgstr "Konkav Rektangel"
+
+#: src/aosd/aosd_style.cc:69
+msgid "None"
+msgstr "Ingen"
+
+#: src/aosd/aosd_trigger.cc:50
+msgid "Playback Start"
+msgstr "Starta Uppspelning"
+
+#: src/aosd/aosd_trigger.cc:51
+msgid "Triggers OSD when a playlist entry is played."
+msgstr ""
+
+#: src/aosd/aosd_trigger.cc:56
+msgid "Title Change"
+msgstr ""
+
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
+msgstr ""
+
+#: src/aosd/aosd_trigger.cc:62
+msgid "Pause On"
+msgstr "Pause på"
+
+#: src/aosd/aosd_trigger.cc:63
+msgid "Triggers OSD when playback is paused."
+msgstr ""
+
+#: src/aosd/aosd_trigger.cc:68
+msgid "Pause Off"
+msgstr "Pause Av"
+
+#: src/aosd/aosd_trigger.cc:69
+msgid "Triggers OSD when playback is unpaused."
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:163
+msgid "Placement"
+msgstr "Placering"
+
+#: src/aosd/aosd_ui.cc:196
+msgid "Relative X offset:"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:203
+msgid "Relative Y offset:"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:210
+msgid "Max OSD width:"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:221
+msgid "Multi-Monitor options"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:225
+msgid "Display OSD using:"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:227
+msgid "all monitors"
+msgstr "alla skärmar"
+
+#: src/aosd/aosd_ui.cc:230
+#, c-format
+msgid "monitor %i"
+msgstr "skärm %i"
+
+#: src/aosd/aosd_ui.cc:282
+msgid "Timing (ms)"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:287
+msgid "Display:"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:292
+msgid "Fade in:"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:297
+msgid "Fade out:"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:361
+msgid "Fonts"
+msgstr "Teckensnitt"
+
+#: src/aosd/aosd_ui.cc:368
+#, c-format
+msgid "Font %i:"
+msgstr "Teckensnitt %i:"
+
+#: src/aosd/aosd_ui.cc:382
+msgid "Shadow"
+msgstr "Skugga"
+
+#: src/aosd/aosd_ui.cc:486
+msgid "Render Style"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:502
+msgid "Colors"
+msgstr "Färger"
+
+#: src/aosd/aosd_ui.cc:513
+#, c-format
+msgid "Color %i:"
+msgstr "Färg %i:"
+
+#: src/aosd/aosd_ui.cc:600
+msgid "Enable trigger"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:627
+msgid "Event"
+msgstr "Event"
+
+#: src/aosd/aosd_ui.cc:655
+msgid "Composite manager detected"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:662
+msgid ""
+"Composite manager not detected;\n"
+"unless you know that you have one running, please activate a composite "
+"manager otherwise the OSD won't work properly"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:670
+msgid "Composite manager not required for fake transparency"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:706
+msgid "Transparency"
+msgstr "Genomskinlighet"
+
+#: src/aosd/aosd_ui.cc:712
+msgid "Fake transparency"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:714
+msgid "Real transparency (requires X Composite Ext.)"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:756
+msgid "Composite extension not loaded"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:764
+msgid "Composite extension not available"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:781
+#, c-format
+msgid "<span font_desc='%s'>Audacious OSD</span>"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:844
+msgid "Position"
+msgstr ""
+
+#: src/aosd/aosd_ui.cc:849
+msgid "Animation"
+msgstr "Animation"
+
+#: src/aosd/aosd_ui.cc:854
+msgid "Text"
+msgstr "Text"
+
+#: src/aosd/aosd_ui.cc:859
+msgid "Decoration"
+msgstr "Dekoration"
+
+#: src/aosd/aosd_ui.cc:864
+msgid "Trigger"
+msgstr "Trigger"
+
+#: src/aosd/aosd_ui.cc:869
+msgid "Misc"
+msgstr "Misc"
+
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
+msgid "ASXv3 Playlists"
+msgstr "ASXv3 Spellistor"
+
+#: src/asx/asx.cc:33
+msgid "ASXv1/ASXv2 Playlists"
+msgstr "ASXv1/ASXv2 Spellistor"
+
+#: src/audpl/audpl.cc:33
+msgid "Audacious Playlists (audpl)"
+msgstr "Audacious Spellistor (audpl)"
+
+#: src/blur_scope/blur_scope.cc:42
+msgid "<b>Color</b>"
+msgstr "<b>Färg</b>"
+
+#: src/blur_scope/blur_scope.cc:58
+msgid "Blur Scope"
+msgstr ""
+
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr ""
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr ""
+
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
+msgstr ""
+
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr ""
+
+#: src/cairo-spectrum/cairo-spectrum.cc:41
+msgid "Spectrum Analyzer"
+msgstr "Spektrumanalysator"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "Ljud CD Plugin"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
+msgid ""
+"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
+"\n"
+"Many thanks to libcdio developers <http://www.gnu.org/software/libcdio/>\n"
+"and to libcddb developers <http://libcddb.sourceforge.net/>.\n"
+"\n"
+"Also thank you to Tony Vroon for mentoring and guiding me.\n"
+"\n"
+"This was a Google Summer of Code 2007 project."
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:137
+msgid "<b>Device</b>"
+msgstr "<b>Enhet</b>"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:138
+msgid "Read speed:"
+msgstr "Läshastighet:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:141
+msgid "Override device:"
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:143
+msgid "<b>Metadata</b>"
+msgstr "<b>Metadata</b>"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:144
+msgid "Use CD-Text"
+msgstr "Använd CD-Text"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:146
+msgid "Use CDDB"
+msgstr "Använd CDDB"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:148
+msgid "Use HTTP instead of CDDBP"
+msgstr "Använd HTTP istället för CDDBP"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:151
+msgid "Server:"
+msgstr "Server:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:155
+msgid "Path:"
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:159
+msgid "Port:"
+msgstr "Port:"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:246
+msgid "Failed to initialize cdio subsystem."
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:281
+#, c-format
+msgid "Invalid URI %s."
+msgstr "Ogiltig URI %s"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:283
+#, c-format
+msgid "Track %d not found."
+msgstr "Spår %d kunde inte hittas."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:285
+#, c-format
+msgid "Track %d is a data track."
+msgstr "Spår %d är ett dataspår."
+
+#: src/cdaudio-ng/cdaudio-ng.cc:360
+msgid "Error reading audio CD."
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:429
+msgid "Audio CD"
+msgstr "Ljud CD"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
+#, c-format
+msgid "Failed to open CD device %s."
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:472
+msgid "No audio capable CD drive found."
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:497
+msgid "Failed to finish initializing opened CD drive."
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:510
+msgid "Failed to retrieve first/last track number."
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:531
+#, c-format
+msgid "Cannot read start/end LSN for track %d."
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:613
+msgid "Failed to create the cddb connection."
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:679
+msgid "Failed to query the CDDB server"
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:681
+#, c-format
+msgid "Failed to query the CDDB server: %s"
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:705
+#, c-format
+msgid "Failed to read the cddb info: %s"
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:765
+msgid "Drive is empty."
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:767
+msgid "Unsupported disk type."
+msgstr ""
+
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr ""
+
+#: src/cd-menu-items/cd-menu-items.cc:47
+msgid "Play CD"
+msgstr "Spela CD"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
+msgid "Add CD"
+msgstr ""
+
+#: src/compressor/compressor.cc:45
+msgid "<b>Compression</b>"
+msgstr ""
+
+#: src/compressor/compressor.cc:46
+msgid "Center volume:"
+msgstr ""
+
+#: src/compressor/compressor.cc:49
+msgid "Dynamic range:"
+msgstr ""
+
+#: src/compressor/compressor.cc:57
+msgid ""
+"Dynamic Range Compression Plugin for Audacious\n"
+"Copyright 2010-2014 John Lindgren"
+msgstr ""
+
+#: src/compressor/compressor.cc:64
+msgid "Dynamic Range Compressor"
+msgstr ""
+
+#: src/console/plugin.cc:15
+msgid ""
+"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
+"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
+"\n"
+"Audacious plugin by:\n"
+"William Pitcock <nenolod at dereferenced.org>\n"
+"Shay Green <gblargg at gmail.com>"
+msgstr ""
+
+#: src/console/plugin.cc:30
+msgid "Bass:"
+msgstr "Bass:"
+
+#: src/console/plugin.cc:33
+msgid "Treble:"
+msgstr ""
+
+#: src/console/plugin.cc:36
+msgid "Echo:"
+msgstr "Eko:"
+
+#: src/console/plugin.cc:39
+msgid "Default song length:"
+msgstr "Standard sånglängd:"
+
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
+msgid "<b>Resampling</b>"
+msgstr "<b>Resampling</b>"
+
+#: src/console/plugin.cc:43
+msgid "Enable audio resampling"
+msgstr ""
+
+#: src/console/plugin.cc:49
+msgid "<b>SPC</b>"
+msgstr "<b>SPC</b>"
+
+#: src/console/plugin.cc:50
+msgid "Ignore length from SPC tags"
+msgstr ""
+
+#: src/console/plugin.cc:52
+msgid "Increase reverb"
+msgstr ""
+
+#: src/console/plugin.h:26
+msgid "Game Console Music Decoder"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:131
+msgid ""
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:44
+msgid ""
+"Crossfade Plugin for Audacious\n"
+"Copyright 2010-2014 John Lindgren"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:48
+msgid "<b>Crossfade</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
+msgid "Overlap:"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
+msgid "Crossfade"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
+msgid "<b>Crystalizer</b>"
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
+msgid "Intensity:"
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:43
+msgid "Crystalizer"
+msgstr ""
+
+#: src/cue/cue.cc:37
+msgid "Cue Sheet Plugin"
+msgstr "Cue Sheet Plugin"
+
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Ta bort Filer"
+
+#: src/delete-files/delete-files.cc:75
+#, c-format
+msgid "Error moving %s to trash: %s."
+msgstr ""
+
+#: src/delete-files/delete-files.cc:86
+#, c-format
+msgid "Error deleting %s: %s."
+msgstr ""
+
+#: src/delete-files/delete-files.cc:117
+#, c-format
+msgid "Error deleting %s: not a local file."
+msgstr ""
+
+#: src/delete-files/delete-files.cc:134
+msgid "Do you want to move the selected files to the trash?"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:135
+msgid "Move to Trash"
+msgstr "Flytta till Papperskorgen"
+
+#: src/delete-files/delete-files.cc:140
+msgid "Do you want to permanently delete the selected files?"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
+msgid "Delete"
+msgstr "Ta Bort"
+
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
+msgid "Cancel"
+msgstr "Avsluta"
+
+#: src/delete-files/delete-files.cc:166
+msgid "Delete Selected Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:181
+msgid "<b>Delete Method</b>"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:182
+msgid "Move to trash instead of deleting immediately"
+msgstr "Flytta till papperskorgen istället för att ta bort direkt"
+
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
+msgid "<b>Echo</b>"
+msgstr "<b>Eko</b>"
+
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
+msgid "Delay:"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
+msgid "ms"
+msgstr "ms"
+
+#: src/echo_plugin/echo.cc:25
+msgid "Feedback:"
+msgstr "Feedback:"
+
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
+msgid "Volume:"
+msgstr "Volym:"
+
+#: src/echo_plugin/echo.cc:39
+msgid "Echo"
+msgstr "Eko"
+
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg Plugin"
+
+#: src/ffaudio/ffaudio-core.cc:571
+msgid ""
+"Multi-format audio decoding plugin for Audacious using\n"
+"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
+"\n"
+"Audacious plugin by:\n"
+"William Pitcock <nenolod at nenolod.net>\n"
+"Matti Hämäläinen <ccr at tnsp.org>"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:386
+msgid "Output file format:"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:403
+msgid "Configure"
+msgstr "Konfigurera"
+
+#: src/filewriter/filewriter.cc:413
+msgid "Save into original directory"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:417
+msgid "Save into custom directory"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:427
+msgid "Output file folder:"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:431
+msgid "Pick a folder"
+msgstr "Välj en mapp"
+
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
+
+#: src/filewriter/filewriter.cc:484
+msgid ""
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
+"USA."
+msgstr ""
+
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
+msgid "Auto"
+msgstr "Auto"
+
+#: src/filewriter/mp3.cc:40
+msgid "Joint Stereo"
+msgstr "Joint Stereo"
+
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
+msgid "Stereo"
+msgstr "Stereo"
+
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
+msgid "Mono"
+msgstr "Mono"
+
+#: src/filewriter/mp3.cc:657
+msgid "MP3 Configuration"
+msgstr "MP3 Konfiguration"
+
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_OK"
+
+#: src/filewriter/mp3.cc:681
+msgid "Algorithm Quality:"
+msgstr ""
+
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
+
+#: src/filewriter/mp3.cc:733
+msgid "(Hz)"
+msgstr "(Hz)"
+
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
+
+#: src/filewriter/mp3.cc:764
+msgid "Bitrate (kbps):"
+msgstr "Bitrate (kbps):"
+
+#: src/filewriter/mp3.cc:796
+msgid "Compression ratio:"
+msgstr ""
+
+#: src/filewriter/mp3.cc:820
+msgid "Audio Mode:"
+msgstr ""
+
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
+
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
+
+#: src/filewriter/mp3.cc:867
+msgid "Error protection"
+msgstr ""
+
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
+msgid "Quality"
+msgstr "Kvalite"
+
+#: src/filewriter/mp3.cc:888
+msgid "Enable VBR/ABR"
+msgstr ""
+
+#: src/filewriter/mp3.cc:898
+msgid "Type:"
+msgstr "Typ:"
+
+#: src/filewriter/mp3.cc:931
+msgid "VBR Options:"
+msgstr ""
+
+#: src/filewriter/mp3.cc:947
+msgid "Minimum bitrate (kbps):"
+msgstr ""
+
+#: src/filewriter/mp3.cc:973
+msgid "Maximum bitrate (kbps):"
+msgstr ""
+
+#: src/filewriter/mp3.cc:995
+msgid "Strictly enforce minimum bitrate"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1007
+msgid "ABR Options:"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1017
+msgid "Average bitrate (kbps):"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1044
+msgid "VBR quality level:"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1076
+msgid "VBR/ABR"
+msgstr "VBR/ABR"
+
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1097
+msgid "Mark as copyright"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1108
+msgid "Mark as original"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1131
+msgid "Force addition of version 2 tag"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1141
+msgid "Only add v1 tag"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1148
+msgid "Only add v2 tag"
+msgstr ""
+
+#: src/filewriter/mp3.cc:1169
+msgid "Tags"
+msgstr "Taggar"
+
+#: src/filewriter/vorbis.cc:196
+msgid "Vorbis Encoder Configuration"
+msgstr ""
+
+#: src/filewriter/vorbis.cc:219
+msgid "Quality level (0 - 10):"
+msgstr ""
+
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC Dekoder"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
+msgid "lossless"
+msgstr "lossless"
+
+#: src/flacng/plugin.cc:169
+msgid ""
+"Original code by\n"
+"Ralf Ertzinger <ralf at skytale.net>\n"
+"\n"
+"http://www.skytale.net/projects/bmp-flac2/"
+msgstr ""
+
+#: src/gio/gio.cc:34
+msgid ""
+"GIO Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren"
+msgstr ""
+
+#: src/gio/gio.cc:42
+msgid "GIO Plugin"
+msgstr "GIO Plugin"
+
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:62
+msgid "OpenGL Spectrum Analyzer"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+
+#: src/gtkui/columns.cc:35
+msgid "Entry number"
+msgstr ""
+
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
+msgid "Title"
+msgstr "Titel"
+
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
+msgid "Artist"
+msgstr "Artist"
+
+#: src/gtkui/columns.cc:38
+msgid "Year"
+msgstr "Ã
r"
+
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
+msgid "Album"
+msgstr "Album"
+
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
+msgid "Track"
+msgstr "Spår"
+
+#: src/gtkui/columns.cc:42
+msgid "Genre"
+msgstr "Genre"
+
+#: src/gtkui/columns.cc:43
+msgid "Queue position"
+msgstr ""
+
+#: src/gtkui/columns.cc:44
+msgid "Length"
+msgstr "Längd"
+
+#: src/gtkui/columns.cc:45
+msgid "File path"
+msgstr ""
+
+#: src/gtkui/columns.cc:47
+msgid "Custom title"
+msgstr "Anpassad titel"
+
+#: src/gtkui/columns.cc:48
+msgid "Bitrate"
+msgstr "Bitrate"
+
+#: src/gtkui/columns.cc:308
+msgid "Available columns"
+msgstr ""
+
+#: src/gtkui/columns.cc:334
+msgid "Displayed columns"
+msgstr ""
+
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr ""
+
+#: src/gtkui/layout.cc:167
+msgid "Dock at Left"
+msgstr ""
+
+#: src/gtkui/layout.cc:167
+msgid "Dock at Right"
+msgstr ""
+
+#: src/gtkui/layout.cc:168
+msgid "Dock at Top"
+msgstr ""
+
+#: src/gtkui/layout.cc:168
+msgid "Dock at Bottom"
+msgstr ""
+
+#: src/gtkui/layout.cc:168
+msgid "Undock"
+msgstr ""
+
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
+msgid "Disable"
+msgstr ""
+
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
+msgid "_Open Files ..."
+msgstr "_Ãppna filer..."
+
+#: src/gtkui/menus.cc:127
+msgid "Open _URL ..."
+msgstr "Ãppna _URL ..."
+
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
+msgid "_Add Files ..."
+msgstr "_Lägg till filer ..."
+
+#: src/gtkui/menus.cc:129
+msgid "Add U_RL ..."
+msgstr "Lägg till U_RL ..."
+
+#: src/gtkui/menus.cc:131
+msgid "Search _Library"
+msgstr ""
+
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
+msgid "A_bout ..."
+msgstr "O_m ..."
+
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
+msgid "_Settings ..."
+msgstr "_Inställningar ..."
+
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
+msgid "_Quit"
+msgstr "_Avsluta"
+
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
+msgid "_Play"
+msgstr "_Spela"
+
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
+msgid "Paus_e"
+msgstr "_Paus_a"
+
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
+msgid "_Stop"
+msgstr "_Stoppa"
+
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
+msgid "Pre_vious"
+msgstr "Förra"
+
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
+msgid "_Next"
+msgstr "_Nästa"
+
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
+msgid "_Repeat"
+msgstr ""
+
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
+msgid "S_huffle"
+msgstr ""
+
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
+msgid "N_o Playlist Advance"
+msgstr ""
+
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
+msgid "Stop A_fter This Song"
+msgstr ""
+
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
+msgid "Song _Info ..."
+msgstr "LÃ¥tinformation"
+
+#: src/gtkui/menus.cc:151
+msgid "Jump to _Time ..."
+msgstr ""
+
+#: src/gtkui/menus.cc:152
+msgid "_Jump to Song ..."
+msgstr ""
+
+#: src/gtkui/menus.cc:154
+msgid "Set Repeat Point _A"
+msgstr ""
+
+#: src/gtkui/menus.cc:155
+msgid "Set Repeat Point _B"
+msgstr ""
+
+#: src/gtkui/menus.cc:156
+msgid "_Clear Repeat Points"
+msgstr ""
+
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
+msgid "By _Title"
+msgstr ""
+
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr ""
+
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
+msgid "By File _Path"
+msgstr ""
+
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
+msgid "By Track _Number"
+msgstr ""
+
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
+msgid "By _Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
+msgid "By Al_bum"
+msgstr ""
+
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
+msgid "By Release _Date"
+msgstr ""
+
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
+msgid "By _Length"
+msgstr ""
+
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
+msgid "By _File Path"
+msgstr ""
+
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
+msgid "By _Custom Title"
+msgstr ""
+
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
+msgid "R_everse Order"
+msgstr ""
+
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
+msgid "_Random Order"
+msgstr ""
+
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr ""
+
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
+msgid "_Refresh"
+msgstr ""
+
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
+msgid "_Sort"
+msgstr "_Sortera"
+
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
+msgid "Sort Se_lected"
+msgstr ""
+
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
+msgid "Remove _Duplicates"
+msgstr ""
+
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
+msgid "Remove _Unavailable Files"
+msgstr ""
+
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
+msgid "_New"
+msgstr "_Ny"
+
+#: src/gtkui/menus.cc:207
+msgid "Ren_ame ..."
+msgstr ""
+
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
+msgid "Remo_ve"
+msgstr ""
+
+#: src/gtkui/menus.cc:210
+msgid "_Import ..."
+msgstr "_Importera"
+
+#: src/gtkui/menus.cc:211
+msgid "_Export ..."
+msgstr "_Exportera"
+
+#: src/gtkui/menus.cc:213
+msgid "Playlist _Manager ..."
+msgstr ""
+
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
+msgid "_Queue Manager ..."
+msgstr ""
+
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
+msgid "Volume _Up"
+msgstr "Volym _Upp"
+
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
+msgid "Volume _Down"
+msgstr "Volym _Ner"
+
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
+msgid "_Equalizer"
+msgstr "_Equalizer"
+
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
+msgid "E_ffects ..."
+msgstr "Effekter ..."
+
+#: src/gtkui/menus.cc:227
+msgid "Show _Menu Bar"
+msgstr ""
+
+#: src/gtkui/menus.cc:228
+msgid "Show I_nfo Bar"
+msgstr ""
+
+#: src/gtkui/menus.cc:229
+msgid "Show Info Bar Vis_ualization"
+msgstr ""
+
+#: src/gtkui/menus.cc:230
+msgid "Show _Status Bar"
+msgstr ""
+
+#: src/gtkui/menus.cc:232
+msgid "Show _Remaining Time"
+msgstr ""
+
+#: src/gtkui/menus.cc:234
+msgid "_Visualizations ..."
+msgstr ""
+
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
+msgid "_File"
+msgstr "_Fil"
+
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
+msgid "_Playback"
+msgstr ""
+
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
+msgid "P_laylist"
+msgstr "Spellista"
+
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
+msgid "_Services"
+msgstr "_Services"
+
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
+msgid "_Output"
+msgstr ""
+
+#: src/gtkui/menus.cc:243
+msgid "_View"
+msgstr "_Visa"
+
+#: src/gtkui/menus.cc:248
+msgid "_Queue/Unqueue"
+msgstr ""
+
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
+msgid "Cu_t"
+msgstr ""
+
+#: src/gtkui/menus.cc:254
+msgid "_Copy"
+msgstr "_Kopiera"
+
+#: src/gtkui/menus.cc:255
+msgid "_Paste"
+msgstr "_Klistra in"
+
+#: src/gtkui/menus.cc:256
+msgid "Select _All"
+msgstr "Välj _Alla"
+
+#: src/gtkui/menus.cc:263
+msgid "_Rename ..."
+msgstr "_Döp om ..."
+
+#: src/gtkui/settings.cc:35
+msgid "<b>Playlist Tabs</b>"
+msgstr ""
+
+#: src/gtkui/settings.cc:36
+msgid "Always show tabs"
+msgstr ""
+
+#: src/gtkui/settings.cc:38
+msgid "Show entry counts"
+msgstr ""
+
+#: src/gtkui/settings.cc:40
+msgid "Show close buttons"
+msgstr ""
+
+#: src/gtkui/settings.cc:42
+msgid "<b>Playlist Columns</b>"
+msgstr ""
+
+#: src/gtkui/settings.cc:44
+msgid "Show column headers"
+msgstr ""
+
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
+msgid "<b>Miscellaneous</b>"
+msgstr ""
+
+#: src/gtkui/settings.cc:47
+msgid "Arrow keys seek by:"
+msgstr ""
+
+#: src/gtkui/settings.cc:50
+msgid "Scroll on song change"
+msgstr ""
+
+#: src/gtkui/ui_gtk.cc:71
+msgid "GTK Interface"
+msgstr "GTK Interface"
+
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
+#, c-format
+msgid "%s - Audacious"
+msgstr "%s - Audacious"
+
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
+msgid "Buffering ..."
+msgstr "Buffrar ..."
+
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
+msgid "Audacious"
+msgstr "Audacious"
+
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "Stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
+#, c-format
+msgid "%d channel"
+msgid_plural "%d channels"
+msgstr[0] "%d kanal "
+msgstr[1] "%d kanaler"
+
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
+#, c-format
+msgid "%d kbps"
+msgstr "%d kbps"
+
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr ""
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr ""
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr ""
+
+#: src/hotkey/gui.cc:71
+msgid "Previous track"
+msgstr "Förra låten"
+
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
+msgid "Play"
+msgstr "Spela"
+
+#: src/hotkey/gui.cc:73
+msgid "Pause/Resume"
+msgstr "Pausa/Fortsätta"
+
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
+msgid "Stop"
+msgstr "Stoppa"
+
+#: src/hotkey/gui.cc:75
+msgid "Next track"
+msgstr "Nästa låt"
+
+#: src/hotkey/gui.cc:76
+msgid "Forward 5 seconds"
+msgstr "Spola fram 5 sekunder"
+
+#: src/hotkey/gui.cc:77
+msgid "Rewind 5 seconds"
+msgstr "Spola bakåt 5 sekunder"
+
+#: src/hotkey/gui.cc:78
+msgid "Mute"
+msgstr ""
+
+#: src/hotkey/gui.cc:79
+msgid "Volume up"
+msgstr "Volym Upp"
+
+#: src/hotkey/gui.cc:80
+msgid "Volume down"
+msgstr "Volym Ner"
+
+#: src/hotkey/gui.cc:81
+msgid "Jump to file"
+msgstr "Hoppa till fil"
+
+#: src/hotkey/gui.cc:82
+msgid "Toggle player window(s)"
+msgstr ""
+
+#: src/hotkey/gui.cc:83
+msgid "Show On-Screen-Display"
+msgstr ""
+
+#: src/hotkey/gui.cc:84
+msgid "Toggle repeat"
+msgstr ""
+
+#: src/hotkey/gui.cc:85
+msgid "Toggle shuffle"
+msgstr ""
+
+#: src/hotkey/gui.cc:86
+msgid "Toggle stop after current"
+msgstr ""
+
+#: src/hotkey/gui.cc:87
+msgid "Raise player window(s)"
+msgstr ""
+
+#: src/hotkey/gui.cc:97
+msgid "(none)"
+msgstr "(ingen)"
+
+#: src/hotkey/gui.cc:234
+msgid ""
+"It is not recommended to bind the primary mouse buttons without "
+"modificators.\n"
+"\n"
+"Do you want to continue?"
+msgstr ""
+
+#: src/hotkey/gui.cc:236
+msgid "Binding mouse buttons"
+msgstr ""
+
+#: src/hotkey/gui.cc:391
+msgid ""
+"Press a key combination inside a text field.\n"
+"You can also bind mouse buttons."
+msgstr ""
+
+#: src/hotkey/gui.cc:396
+msgid "Hotkeys:"
+msgstr ""
+
+#: src/hotkey/gui.cc:413
+msgid "<b>Action:</b>"
+msgstr ""
+
+#: src/hotkey/gui.cc:420
+msgid "<b>Key Binding:</b>"
+msgstr ""
+
+#: src/hotkey/gui.cc:468
+msgid "_Add"
+msgstr "_Lägg till"
+
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr ""
+
+#: src/hotkey/plugin.cc:79
+msgid ""
+"Global Hotkey Plugin\n"
+"Control the player with global key combinations or multimedia keys.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>\n"
+"\n"
+"Contributers include:\n"
+"Copyright (C) 2006-2007 Vladimir Paskov <vlado.paskov at gmail.com>\n"
+"Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>,\n"
+" Bryn Davies <curious at ihug.com.au>,\n"
+" Jonathan A. Davis <davis at jdhouse.org>,\n"
+" Jeremy Tan <nsx at nsx.homeip.net>"
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr ""
+
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
+msgid ""
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
+msgstr ""
+
+#: src/ladspa/plugin.cc:414
+#, c-format
+msgid "%s Settings"
+msgstr ""
+
+#: src/ladspa/plugin.cc:478
+msgid "Module paths:"
+msgstr ""
+
+#: src/ladspa/plugin.cc:483
+msgid ""
+"<small>Separate multiple paths with a colon.\n"
+"These paths are searched in addition to LADSPA_PATH.\n"
+"After adding new paths, press Enter to scan for new plugins.</small>"
+msgstr ""
+
+#: src/ladspa/plugin.cc:499
+msgid "Available plugins:"
+msgstr ""
+
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
+msgid "Enable"
+msgstr ""
+
+#: src/ladspa/plugin.cc:518
+msgid "Enabled plugins:"
+msgstr ""
+
+#: src/ladspa/plugin.cc:534
+msgid "Settings"
+msgstr "Inställningar"
+
+#: src/ladspa/plugin.cc:551
+msgid ""
+"LADSPA Host for Audacious\n"
+"Copyright 2011 John Lindgren"
+msgstr ""
+
+#: src/ladspa/plugin.h:78
+msgid "LADSPA Host"
+msgstr ""
+
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr ""
+
+#: src/lirc/lirc.cc:381
+msgid ""
+"A simple plugin to control Audacious using the LIRC remote control daemon\n"
+"\n"
+"Adapted for Audacious by:\n"
+"Tony Vroon <chainsaw at gentoo.org>\n"
+"Joonas Harjumäki <jharjuma at gmail.com>\n"
+"\n"
+"Based on the XMMS LIRC plugin by:\n"
+"Carl van Schaik <carl at leg.uct.ac.za>\n"
+"Christoph Bartelmus <xmms at bartelmus.de>\n"
+"Andrew O. Shadoura <bugzilla at tut.by>\n"
+"\n"
+"For more information about LIRC, see http://lirc.org."
+msgstr ""
+
+#: src/lirc/lirc.cc:392
+msgid "<b>Connection</b>"
+msgstr ""
+
+#: src/lirc/lirc.cc:393
+msgid "Reconnect to LIRC server"
+msgstr ""
+
+#: src/lirc/lirc.cc:395
+msgid "Wait before reconnecting:"
+msgstr ""
+
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr ""
+
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
+msgid "No lyrics available"
+msgstr ""
+
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Fel"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
+#, c-format
+msgid "Unable to fetch %s"
+msgstr ""
+
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
+#, c-format
+msgid "Unable to parse %s"
+msgstr ""
+
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
+msgid "Looking for lyrics ..."
+msgstr ""
+
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Missing song metadata"
+msgstr ""
+
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
+msgid "Connecting to lyrics.wikia.com ..."
+msgstr ""
+
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
+
+#: src/m3u/m3u.cc:32
+msgid "M3U Playlists"
+msgstr ""
+
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr ""
+
+#: src/metronom/metronom.cc:147
+#, c-format
+msgid "Tact generator: %d bpm"
+msgstr ""
+
+#: src/metronom/metronom.cc:149
+#, c-format
+msgid "Tact generator: %d bpm %d/%d"
+msgstr ""
+
+#: src/metronom/metronom.cc:237
+msgid ""
+"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
+"\n"
+"To use it, add a URL: tact://beats*num/den\n"
+"e.g. tact://77 to play 77 beats per minute\n"
+"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
+msgstr ""
+
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr ""
+
+#: src/mixer/mixer.cc:202
+msgid ""
+"Channel Mixer Plugin for Audacious\n"
+"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
+msgstr ""
+
+#: src/mixer/mixer.cc:206
+msgid "<b>Channel Mixer</b>"
+msgstr ""
+
+#: src/mixer/mixer.cc:207
+msgid "Output channels:"
+msgstr ""
+
+#: src/mms/mms.cc:35
+msgid "MMS Plugin"
+msgstr ""
+
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:53
+msgid "<b>Resolution</b>"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:54
+msgid "8-bit"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:55
+msgid "16-bit"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:56
+msgid "<b>Channels</b>"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:60
+msgid "Nearest (fastest)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:61
+msgid "Linear (fast)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:62
+msgid "Spline (good)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:63
+msgid "Polyphase (best)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:65
+msgid "22 kHz"
+msgstr "22 kHz"
+
+#: src/modplug/plugin_main.cc:66
+msgid "44 kHz"
+msgstr "44 kHz"
+
+#: src/modplug/plugin_main.cc:67
+msgid "48 kHz"
+msgstr "48 kHz"
+
+#: src/modplug/plugin_main.cc:68
+msgid "96 kHz"
+msgstr "96 kHz"
+
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
+msgid "Level:"
+msgstr "Nivå:"
+
+#: src/modplug/plugin_main.cc:78
+msgid "Cutoff:"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:91
+msgid "<b>Reverb</b>"
+msgstr "<b>Reverb</b>"
+
+#: src/modplug/plugin_main.cc:94
+msgid "<b>Bass Boost</b>"
+msgstr "<b>Bass Boost</b>"
+
+#: src/modplug/plugin_main.cc:97
+msgid "<b>Surround</b>"
+msgstr "<b>Surround</b>"
+
+#: src/modplug/plugin_main.cc:100
+msgid "<b>Preamp</b>"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:107
+msgid "Oversample"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:108
+msgid "Noise reduction"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:109
+msgid "Play Amiga MODs"
+msgstr "Spela Amiga Moduler"
+
+#: src/modplug/plugin_main.cc:110
+msgid "<b>Repeat</b>"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:111
+msgid "Repeat count:"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:112
+msgid "To repeat forever, set the repeat count to -1."
+msgstr ""
+
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
+
+#: src/mpg123/mpg123.cc:54
+msgid "MPG123 Plugin"
+msgstr "MPG123 Plugin"
+
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b> Avancerat </ b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
+
+#: src/mpris2/plugin.cc:39
+msgid "MPRIS 2 Server"
+msgstr "MPRIS 2 Server"
+
+#: src/neon/neon.cc:97
+msgid "Neon HTTP/HTTPS Plugin"
+msgstr "Neon HTTP/HTTPS Plugin"
+
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
+msgid "Stopped"
+msgstr "Stoppad"
+
+#: src/notify/event.cc:64
+msgid "Audacious is not playing."
+msgstr ""
+
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr ""
+
+#: src/notify/notify.cc:60
+msgid ""
+"Desktop Notifications Plugin for Audacious\n"
+"Copyright (C) 2010 Maximilian Bogner\n"
+"Copyright (C) 2011-2013 John Lindgren and Jean-Alexandre Anglès d'Auriac\n"
+"\n"
+"This plugin is free software: you can redistribute it and/or modify it under "
+"the terms of the GNU General Public License as published by the Free "
+"Software Foundation, either version 3 of the License, or (at your option) "
+"any later version.\n"
+"\n"
+"This plugin 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, see <http://www.gnu.org/licenses/>."
+msgstr ""
+
+#: src/notify/notify.cc:110
+msgid "Show playback controls"
+msgstr ""
+
+#: src/notify/notify.cc:112
+msgid "Always show notification"
+msgstr ""
+
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
+
+#: src/notify/osd.cc:58
+msgid "Show"
+msgstr "Visa"
+
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
+msgid "Pause"
+msgstr "Pause"
+
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
+msgid "Next"
+msgstr "Nästa"
+
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr ""
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
+
+#: src/oss4/plugin.cc:77
+msgid "Audio device:"
+msgstr ""
+
+#: src/oss4/plugin.cc:80
+msgid "Use alternate device:"
+msgstr ""
+
+#: src/oss4/plugin.cc:84
+msgid "Save volume between sessions."
+msgstr ""
+
+#: src/oss4/plugin.cc:86
+msgid "Enable format conversions made by the OSS software."
+msgstr ""
+
+#: src/oss4/plugin.cc:88
+msgid "Enable exclusive mode to prevent virtual mixing."
+msgstr ""
+
+#: src/oss4/plugin.cc:100
+msgid ""
+"OSS4 Output Plugin for Audacious\n"
+"Copyright 2010-2012 MichaÅ Lipski\n"
+"\n"
+"I would like to thank people on #audacious, especially Tony Vroon and John "
+"Lindgren and of course the authors of the previous OSS plugin."
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
+
+#: src/pls/pls.cc:35
+msgid "PLS Playlists"
+msgstr "PLS Spellistor"
+
+#: src/psf/plugin.cc:45
+msgid "OpenPSF PSF1/PSF2 Decoder"
+msgstr ""
+
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr ""
+
+#: src/pulse_audio/pulse_audio.cc:611
+msgid ""
+"Audacious PulseAudio Output Plugin\n"
+"\n"
+"This program is free software; you can redistribute it and/or modify\n"
+"it under the terms of the GNU General Public License as published by\n"
+"the Free Software Foundation; either version 2 of the License, or\n"
+"(at your option) any later version.\n"
+"\n"
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License for more details.\n"
+"\n"
+"You should have received a copy of the GNU General Public License\n"
+"along with this program; if not, write to the Free Software\n"
+"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
+"USA."
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "Sök"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Förra"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr ""
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr ""
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr ""
+
+#: src/resample/resample.cc:183
+msgid ""
+"Sample Rate Converter Plugin for Audacious\n"
+"Copyright 2010-2012 John Lindgren"
+msgstr ""
+
+#: src/resample/resample.cc:187
+msgid "Skip/repeat samples"
+msgstr ""
+
+#: src/resample/resample.cc:188
+msgid "Linear interpolation"
+msgstr ""
+
+#: src/resample/resample.cc:189
+msgid "Fast sinc interpolation"
+msgstr ""
+
+#: src/resample/resample.cc:190
+msgid "Medium sinc interpolation"
+msgstr ""
+
+#: src/resample/resample.cc:191
+msgid "Best sinc interpolation"
+msgstr ""
+
+#: src/resample/resample.cc:195
+msgid "<b>Conversion</b>"
+msgstr ""
+
+#: src/resample/resample.cc:196
+msgid "Method:"
+msgstr ""
+
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
+msgid "Rate:"
+msgstr ""
+
+#: src/resample/resample.cc:202
+msgid "<b>Rate Mappings</b>"
+msgstr ""
+
+#: src/resample/resample.cc:203
+msgid "Use rate mappings"
+msgstr ""
+
+#: src/resample/resample.cc:205
+msgid "8 kHz:"
+msgstr "8 kHz:"
+
+#: src/resample/resample.cc:209
+msgid "16 kHz:"
+msgstr "16 kHz:"
+
+#: src/resample/resample.cc:213
+msgid "22.05 kHz:"
+msgstr "22.05 kHz:"
+
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
+msgid "44.1 kHz:"
+msgstr "44.1 kHz:"
+
+#: src/resample/resample.cc:225
+msgid "48 kHz:"
+msgstr "48 kHz:"
+
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
+msgid "96 kHz:"
+msgstr "96 kHz:"
+
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
+msgid "192 kHz:"
+msgstr "192 kHz:"
+
+#: src/scrobbler2/config_window.cc:41
+#, c-format
+msgid "OK. Scrobbling for user: %s"
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:54
+msgid "Permission Denied"
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:56
+msgid "Access the following link to allow Audacious to scrobble your plays:"
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:66
+msgid "Keep this window open and click 'Check Permission' again.\n"
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
+msgid ""
+"Don't worry. Your scrobbles are saved on your computer.\n"
+"They will be submitted as soon as Audacious is allowed to do so."
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:77
+msgid "Network Problem."
+msgstr "Nätverksproblem"
+
+#: src/scrobbler2/config_window.cc:78
+msgid "There was a problem contacting Last.fm. Please try again later."
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:110
+msgid "Checking..."
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:176
+msgid "C_heck Permission"
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:177
+msgid "_Revoke Permission"
+msgstr ""
+
+#: src/scrobbler2/config_window.cc:220
+msgid ""
+"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
+msgid ""
+"The Scrobbler plugin could not be started.\n"
+"There might be a problem with your installation."
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:289
+msgid ""
+"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
+"\n"
+"Copyright © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com>\n"
+"\n"
+"Thanks to John Lindgren for giving me a hand at the beginning of this "
+"project.\n"
+"\n"
+msgstr ""
+
+#: src/scrobbler2/scrobbler_communication.cc:642
+msgid ""
+"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
+"Please check the Preferences for the Scrobbler plugin."
+msgstr ""
+
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr ""
+
+#: src/sdlout/sdlout.cc:77
+msgid ""
+"SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
+msgid "Library"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:394
+#, c-format
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/search-tool/search-tool.cc:400
+#, c-format
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/search-tool/search-tool.cc:594
+#, c-format
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
+msgid "_Create Playlist"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:645
+msgid "_Add to Playlist"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:684
+msgid "Search library"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:688
+msgid ""
+"To import your music library into Audacious, choose a folder and then click "
+"the \"refresh\" icon."
+msgstr ""
+
+#: src/search-tool/search-tool.cc:696
+msgid "Please wait ..."
+msgstr ""
+
+#: src/search-tool/search-tool.cc:723
+msgid "Choose Folder"
+msgstr "Välj Mapp"
+
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
+msgid "Open Files ..."
+msgstr "Ãppna filer..."
+
+#: src/skins/menus.cc:65
+msgid "Open URL ..."
+msgstr "Ãppna URL ..."
+
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
+msgid "Playback"
+msgstr "Uppspelning"
+
+#: src/skins/menus.cc:69
+msgid "Playlist"
+msgstr "Spellista"
+
+#: src/skins/menus.cc:70
+msgid "View"
+msgstr "Visa"
+
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
+msgid "Services"
+msgstr ""
+
+#: src/skins/menus.cc:74
+msgid "About ..."
+msgstr "Om ..."
+
+#: src/skins/menus.cc:75
+msgid "Settings ..."
+msgstr "Inställningar..."
+
+#: src/skins/menus.cc:76
+msgid "Quit"
+msgstr "Avsluta"
+
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
+msgid "Song Info ..."
+msgstr "LÃ¥tinformation ..."
+
+#: src/skins/menus.cc:84
+msgid "No Playlist Advance"
+msgstr ""
+
+#: src/skins/menus.cc:85
+msgid "Stop After This Song"
+msgstr ""
+
+#: src/skins/menus.cc:93
+msgid "Set A-B Repeat"
+msgstr ""
+
+#: src/skins/menus.cc:94
+msgid "Clear A-B Repeat"
+msgstr ""
+
+#: src/skins/menus.cc:96
+msgid "Jump to Song ..."
+msgstr "Hoppa till låt ..."
+
+#: src/skins/menus.cc:97
+msgid "Jump to Time ..."
+msgstr "Hoppa till tid ..."
+
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr ""
+
+#: src/skins/menus.cc:103
+msgid "New Playlist"
+msgstr "Ny spellista"
+
+#: src/skins/menus.cc:104
+msgid "Rename Playlist ..."
+msgstr "Döp om spellista"
+
+#: src/skins/menus.cc:105
+msgid "Remove Playlist"
+msgstr "Ta Bort Spellista"
+
+#: src/skins/menus.cc:107
+msgid "Previous Playlist"
+msgstr "Förra Spellista"
+
+#: src/skins/menus.cc:108
+msgid "Next Playlist"
+msgstr "Nästa Spellista"
+
+#: src/skins/menus.cc:110
+msgid "Import Playlist ..."
+msgstr "Importera spellista"
+
+#: src/skins/menus.cc:111
+msgid "Export Playlist ..."
+msgstr "Exportera spellista"
+
+#: src/skins/menus.cc:113
+msgid "Playlist Manager ..."
+msgstr ""
+
+#: src/skins/menus.cc:114
+msgid "Queue Manager ..."
+msgstr ""
+
+#: src/skins/menus.cc:116
+msgid "Refresh Playlist"
+msgstr ""
+
+#: src/skins/menus.cc:120
+msgid "Show Playlist Editor"
+msgstr ""
+
+#: src/skins/menus.cc:121
+msgid "Show Equalizer"
+msgstr "Visa Equalizer"
+
+#: src/skins/menus.cc:123
+msgid "Show Remaining Time"
+msgstr ""
+
+#: src/skins/menus.cc:125
+msgid "Always on Top"
+msgstr ""
+
+#: src/skins/menus.cc:126
+msgid "On All Workspaces"
+msgstr ""
+
+#: src/skins/menus.cc:128
+msgid "Roll Up Player"
+msgstr ""
+
+#: src/skins/menus.cc:129
+msgid "Roll Up Playlist Editor"
+msgstr ""
+
+#: src/skins/menus.cc:130
+msgid "Roll Up Equalizer"
+msgstr ""
+
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
+msgid "Add URL ..."
+msgstr "Lägg till URL ..."
+
+#: src/skins/menus.cc:139
+msgid "Add Files ..."
+msgstr "Lägg till filer ..."
+
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
+msgid "By Title"
+msgstr ""
+
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
+
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
+msgid "By File Path"
+msgstr ""
+
+#: src/skins/menus.cc:151
+msgid "Remove All"
+msgstr "Ta Bort Alla"
+
+#: src/skins/menus.cc:152
+msgid "Clear Queue"
+msgstr ""
+
+#: src/skins/menus.cc:154
+msgid "Remove Unavailable Files"
+msgstr ""
+
+#: src/skins/menus.cc:155
+msgid "Remove Duplicates"
+msgstr ""
+
+#: src/skins/menus.cc:157
+msgid "Remove Unselected"
+msgstr ""
+
+#: src/skins/menus.cc:158
+msgid "Remove Selected"
+msgstr ""
+
+#: src/skins/menus.cc:162
+msgid "Search and Select"
+msgstr ""
+
+#: src/skins/menus.cc:164
+msgid "Invert Selection"
+msgstr ""
+
+#: src/skins/menus.cc:165
+msgid "Select None"
+msgstr ""
+
+#: src/skins/menus.cc:166
+msgid "Select All"
+msgstr ""
+
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr ""
+
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
+msgid "By Artist"
+msgstr ""
+
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr ""
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
+msgid "By Release Date"
+msgstr ""
+
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
+msgid "Randomize List"
+msgstr ""
+
+#: src/skins/menus.cc:199
+msgid "Reverse List"
+msgstr ""
+
+#: src/skins/menus.cc:201
+msgid "Sort Selected"
+msgstr "Sortera vald"
+
+#: src/skins/menus.cc:202
+msgid "Sort List"
+msgstr "Sortera Lista"
+
+#: src/skins/menus.cc:208
+msgid "Cut"
+msgstr "Klipp"
+
+#: src/skins/menus.cc:209
+msgid "Copy"
+msgstr "Kopiera"
+
+#: src/skins/menus.cc:210
+msgid "Paste"
+msgstr "Klistra in"
+
+#: src/skins/menus.cc:212
+msgid "Queue/Unqueue"
+msgstr ""
+
+#: src/skins/menus.cc:218
+msgid "Load Preset ..."
+msgstr ""
+
+#: src/skins/menus.cc:219
+msgid "Load Auto Preset ..."
+msgstr ""
+
+#: src/skins/menus.cc:220
+msgid "Load Default"
+msgstr ""
+
+#: src/skins/menus.cc:221
+msgid "Load Preset File ..."
+msgstr ""
+
+#: src/skins/menus.cc:222
+msgid "Load EQF File ..."
+msgstr ""
+
+#: src/skins/menus.cc:224
+msgid "Save Preset ..."
+msgstr ""
+
+#: src/skins/menus.cc:225
+msgid "Save Auto Preset ..."
+msgstr ""
+
+#: src/skins/menus.cc:226
+msgid "Save Default"
+msgstr ""
+
+#: src/skins/menus.cc:227
+msgid "Save Preset File ..."
+msgstr ""
+
+#: src/skins/menus.cc:228
+msgid "Save EQF File ..."
+msgstr ""
+
+#: src/skins/menus.cc:230
+msgid "Delete Preset ..."
+msgstr ""
+
+#: src/skins/menus.cc:231
+msgid "Delete Auto Preset ..."
+msgstr ""
+
+#: src/skins/menus.cc:233
+msgid "Import Winamp Presets ..."
+msgstr ""
+
+#: src/skins/menus.cc:235
+msgid "Reset to Zero"
+msgstr ""
+
+#: src/skins/plugin.cc:48
+msgid "Winamp Classic Interface"
+msgstr ""
+
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
+msgid "Save"
+msgstr ""
+
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
+msgid "Load"
+msgstr ""
+
+#: src/skins/preset-browser.cc:83
+msgid "Load Preset File"
+msgstr ""
+
+#: src/skins/preset-browser.cc:100
+msgid "Load EQF File"
+msgstr ""
+
+#: src/skins/preset-browser.cc:119
+msgid "Save Preset File"
+msgstr ""
+
+#: src/skins/preset-browser.cc:137
+msgid "Save EQF File"
+msgstr ""
+
+#: src/skins/preset-browser.cc:151
+msgid "Import Winamp Presets"
+msgstr ""
+
+#: src/skins/preset-list.cc:285
+msgid "Presets"
+msgstr ""
+
+#: src/skins/preset-list.cc:335
+msgid "Load preset"
+msgstr ""
+
+#: src/skins/preset-list.cc:351
+msgid "Load auto-preset"
+msgstr ""
+
+#: src/skins/preset-list.cc:367
+msgid "Save preset"
+msgstr ""
+
+#: src/skins/preset-list.cc:382
+msgid "Save auto-preset"
+msgstr ""
+
+#: src/skins/preset-list.cc:408
+msgid "Delete preset"
+msgstr ""
+
+#: src/skins/preset-list.cc:424
+msgid "Delete auto-preset"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:178
+msgid "Select main player window font:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:181
+msgid "Select playlist font:"
+msgstr "Välj spelliste teckensnitt:"
+
+#: src/skins/skins_cfg.cc:187
+msgid "<b>Skin</b>"
+msgstr "<b>Skin</b>"
+
+#: src/skins/skins_cfg.cc:189
+msgid "<b>Fonts</b>"
+msgstr "<b>Teckensnitt</b>"
+
+#: src/skins/skins_cfg.cc:192
+msgid "Use bitmap fonts (supports ASCII only)"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:194
+msgid "Scroll song title"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:196
+msgid "Scroll song title in both directions"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:201
+msgid "Analyzer"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:202
+msgid "Scope"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:203
+msgid "Voiceprint / VU meter"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:204
+msgid "Off"
+msgstr "Av"
+
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
+msgid "Normal"
+msgstr "Normal"
+
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
+msgid "Fire"
+msgstr "Eld"
+
+#: src/skins/skins_cfg.cc:210
+msgid "Vertical lines"
+msgstr "Vertikala linjer"
+
+#: src/skins/skins_cfg.cc:214
+msgid "Lines"
+msgstr "Linjer"
+
+#: src/skins/skins_cfg.cc:215
+msgid "Bars"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:219
+msgid "Slowest"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:220
+msgid "Slow"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
+msgid "Medium"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:222
+msgid "Fast"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:223
+msgid "Fastest"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:227
+msgid "Dots"
+msgstr "Punkter"
+
+#: src/skins/skins_cfg.cc:228
+msgid "Line"
+msgstr "Linje"
+
+#: src/skins/skins_cfg.cc:229
+msgid "Solid"
+msgstr "Solid"
+
+#: src/skins/skins_cfg.cc:235
+msgid "Ice"
+msgstr "Is"
+
+#: src/skins/skins_cfg.cc:240
+msgid "Smooth"
+msgstr "Smooth"
+
+#: src/skins/skins_cfg.cc:244
+msgid "<b>Type</b>"
+msgstr "<b> Typ</b>"
+
+#: src/skins/skins_cfg.cc:245
+msgid "Visualization type:"
+msgstr "Visualiserings typ:"
+
+#: src/skins/skins_cfg.cc:248
+msgid "<b>Analyzer</b>"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:249
+msgid "Show peaks"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:251
+msgid "Coloring:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:254
+msgid "Style:"
+msgstr "Stil:"
+
+#: src/skins/skins_cfg.cc:257
+msgid "Falloff:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:260
+msgid "Peak falloff:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:264
+msgid "Scope Style:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:267
+msgid "Voiceprint Coloring:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:270
+msgid "VU Meter Style:"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:276
+msgid "General"
+msgstr ""
+
+#: src/skins/skins_cfg.cc:277
+msgid "Visualization"
+msgstr "Visualisering"
+
+#: src/skins/ui_equalizer.cc:282
+msgid "Preamp"
+msgstr ""
+
+#: src/skins/ui_equalizer.cc:286
+msgid "31 Hz"
+msgstr "31 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "63 Hz"
+msgstr "63 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "125 Hz"
+msgstr "125 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "250 Hz"
+msgstr "250 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "500 Hz"
+msgstr "500 Hz"
+
+#: src/skins/ui_equalizer.cc:287
+msgid "1 kHz"
+msgstr "1 kHz"
+
+#: src/skins/ui_equalizer.cc:288
+msgid "2 kHz"
+msgstr "2 kHz"
+
+#: src/skins/ui_equalizer.cc:288
+msgid "4 kHz"
+msgstr "4 kHz"
+
+#: src/skins/ui_equalizer.cc:288
+msgid "8 kHz"
+msgstr "8 kHz"
+
+#: src/skins/ui_equalizer.cc:288
+msgid "16 kHz"
+msgstr "16 kHz"
+
+#: src/skins/ui_equalizer.cc:330
+msgid "Audacious Equalizer"
+msgstr "Audacious Equalizer"
+
+#: src/skins/ui_main.cc:688
+#, c-format
+msgid "Seek to %d:%-2.2d / %d:%-2.2d"
+msgstr ""
+
+#: src/skins/ui_main.cc:709
+#, c-format
+msgid "Volume: %d%%"
+msgstr ""
+
+#: src/skins/ui_main.cc:732
+#, c-format
+msgid "Balance: %d%% left"
+msgstr ""
+
+#: src/skins/ui_main.cc:734
+msgid "Balance: center"
+msgstr ""
+
+#: src/skins/ui_main.cc:736
+#, c-format
+msgid "Balance: %d%% right"
+msgstr ""
+
+#: src/skins/ui_main.cc:842
+msgid "Options Menu"
+msgstr ""
+
+#: src/skins/ui_main.cc:846
+msgid "Disable 'Always On Top'"
+msgstr ""
+
+#: src/skins/ui_main.cc:848
+msgid "Enable 'Always On Top'"
+msgstr ""
+
+#: src/skins/ui_main.cc:851
+msgid "File Info Box"
+msgstr ""
+
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
+msgid "Repeat point A set."
+msgstr ""
+
+#: src/skins/ui_main.cc:1341
+msgid "Repeat point B set."
+msgstr ""
+
+#: src/skins/ui_main.cc:1350
+msgid "Repeat points cleared."
+msgstr ""
+
+#: src/skins/ui_playlist.cc:219
+msgid "Search entries in active playlist"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:226
+msgid ""
+"Select entries in playlist by filling one or more fields. Fields use regular "
+"expressions syntax, case-insensitive. If you don't know how regular "
+"expressions work, simply insert a literal portion of what you're searching "
+"for."
+msgstr ""
+
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:263
+msgid "Clear previous selection before searching"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:266
+msgid "Automatically toggle queue for matching entries"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:269
+msgid "Create a new playlist with matching entries"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:717
+msgid "Audacious Playlist Editor"
+msgstr ""
+
+#: src/skins/ui_playlist.cc:752
+#, c-format
+msgid "%s (%d of %d)"
+msgstr ""
+
+#: src/skins/ui_skinselector.cc:167
+msgid "Archived Winamp 2.x skin"
+msgstr ""
+
+#: src/skins/ui_skinselector.cc:172
+msgid "Unarchived Winamp 2.x skin"
+msgstr ""
+
+#: src/skins/util.cc:430
+#, c-format
+msgid "Could not create directory (%s): %s\n"
+msgstr ""
+
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr ""
+
+#: src/sndfile/plugin.cc:336
+msgid ""
+"Based on the xmms_sndfile plugin:\n"
+"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
+"\n"
+"Adapted for Audacious by Tony Vroon <chainsaw at gentoo.org>\n"
+"\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., 51 "
+"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
+msgstr ""
+
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
+
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr ""
+
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
+
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr ""
+
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
+
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
+
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
+
+#: src/song_change/song_change.cc:33
+msgid "Song Change"
+msgstr ""
+
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
+
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
+
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
+
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
+
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr ""
+
+#: src/song_change/song_change.cc:376
+msgid ""
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
+"\n"
+"%F: Frequency (in hertz)\n"
+"%c: Number of channels\n"
+"%f: File name (full path)\n"
+"%l: Length (in milliseconds)\n"
+"%n or %s: Song name\n"
+"%r: Rate (in bits per second)\n"
+"%t: Playlist position (%02d)\n"
+"%p: Currently playing (1 or 0)\n"
+"%a: Artist\n"
+"%b: Album\n"
+"%T: Track title"
+msgstr ""
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr ""
+
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
+
+#: src/sox-resampler/sox-resampler.cc:144
+msgid ""
+"SoX Resampler Plugin for Audacious\n"
+"Copyright 2013 MichaÅ Lipski\n"
+"\n"
+"Based on Sample Rate Converter Plugin:\n"
+"Copyright 2010-2012 John Lindgren"
+msgstr ""
+
+#: src/sox-resampler/sox-resampler.cc:150
+msgid "Quick"
+msgstr ""
+
+#: src/sox-resampler/sox-resampler.cc:151
+msgid "Low"
+msgstr ""
+
+#: src/sox-resampler/sox-resampler.cc:153
+msgid "High"
+msgstr ""
+
+#: src/sox-resampler/sox-resampler.cc:154
+msgid "Very High"
+msgstr ""
+
+#: src/sox-resampler/sox-resampler.cc:158
+msgid "Quality:"
+msgstr ""
+
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr ""
+
+#: src/speed-pitch/speed-pitch.cc:210
+msgid "<b>Speed and Pitch</b>"
+msgstr ""
+
+#: src/speed-pitch/speed-pitch.cc:211
+msgid "Speed:"
+msgstr ""
+
+#: src/speed-pitch/speed-pitch.cc:214
+msgid "Pitch:"
+msgstr ""
+
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Status ikon"
+
+#: src/statusicon/statusicon.cc:283
+msgid "Se_ttings ..."
+msgstr ""
+
+#: src/statusicon/statusicon.cc:372
+msgid ""
+"Status Icon Plugin\n"
+"\n"
+"Copyright 2005-2007 Giacomo Lozito <james at develia.org>\n"
+"Copyright 2010 MichaÅ Lipski <tallica at o2.pl>\n"
+"\n"
+"This plugin provides a status icon, placed in\n"
+"the system tray area of the window manager."
+msgstr ""
+
+#: src/statusicon/statusicon.cc:379
+msgid "<b>Mouse Scroll Action</b>"
+msgstr ""
+
+#: src/statusicon/statusicon.cc:380
+msgid "Change volume"
+msgstr ""
+
+#: src/statusicon/statusicon.cc:383
+msgid "Change playing song"
+msgstr ""
+
+#: src/statusicon/statusicon.cc:386
+msgid "<b>Other Settings</b>"
+msgstr ""
+
+#: src/statusicon/statusicon.cc:387
+msgid "Disable the popup window"
+msgstr ""
+
+#: src/statusicon/statusicon.cc:389
+msgid "Close to the system tray"
+msgstr ""
+
+#: src/statusicon/statusicon.cc:391
+msgid "Advance in playlist when scrolling upward"
+msgstr ""
+
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Stereo"
+
+#: src/stereo_plugin/stereo.cc:36
+msgid ""
+"Extra Stereo Plugin\n"
+"\n"
+"By Johan Levin, 1999"
+msgstr ""
+"Extra Stereo Plugin\n"
+"\n"
+"Av Johan Levin, 1999"
+
+#: src/stereo_plugin/stereo.cc:44
+msgid "<b>Extra Stereo</b>"
+msgstr "<b>Extra Stereo</b>"
+
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr ""
+
+#: src/tonegen/tonegen.cc:94
+#, c-format
+msgid "%s %.1f Hz"
+msgstr "%s %.1f Hz"
+
+#: src/tonegen/tonegen.cc:94
+msgid "Tone Generator: "
+msgstr ""
+
+#: src/tonegen/tonegen.cc:160
+msgid ""
+"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
+"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
+"\n"
+"To use it, add a URL: tone://frequency1;frequency2;frequency3;...\n"
+"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
+msgstr ""
+
+#: src/voice_removal/voice_removal.cc:28
+msgid "Voice Removal"
+msgstr ""
+
+#: src/vorbis/vorbis.cc:465
+msgid ""
+"Audacious Ogg Vorbis Decoder\n"
+"\n"
+"Based on the Xiph.org Foundation's Ogg Vorbis Plugin:\n"
+"http://www.xiph.org/\n"
+"\n"
+"Original code by:\n"
+"Tony Arcieri <bascule at inferno.tusculum.edu>\n"
+"\n"
+"Contributions from:\n"
+"Chris Montgomery <monty at xiph.org>\n"
+"Peter Alm <peter at xmms.org>\n"
+"Michael Smith <msmith at labyrinth.edu.au>\n"
+"Jack Moffitt <jack at icecast.org>\n"
+"Jorn Baayen <jorn at nl.linux.org>\n"
+"Håvard Kvålen <havardk at xmms.org>\n"
+"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
+"Eugene Zagidullin <e.asphyx at gmail.com>"
+msgstr ""
+"Audacious Ogg Vorbis Decoder\n"
+"\n"
+"Baserat på Xiph.org stiftelsens Ogg Vorbis Plugin: \n"
+"http://www.xiph.org/\n"
+"\n"
+"Original kod av: \n"
+"Tony Arcieri <bascule at inferno.tusculum.edu> \n"
+"\n"
+"Bidrag från: \n"
+"Chris Montgomery <monty at xiph.org> \n"
+"Peter Alm <peter at xmms.org> \n"
+"Michael Smith <msmith at labyrinth.edu.au> \n"
+"Jack Moffitt <jack at icecast.org> \n"
+"Jorn Baayen <jorn at nl.linux.org> \n"
+"Håvard Kvålen <havardk at xmms.org> \n"
+"Gian-Carlo Pascutto <gcp at sjeng.org> \n"
+"Eugene Zagidullin <e.asphyx at gmail.com>"
+
+#: src/vorbis/vorbis.h:18
+msgid "Ogg Vorbis Decoder"
+msgstr "Ogg Vorbis Dekoder"
+
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX Dekoder"
+
+#: src/vtx/vtx.cc:184
+msgid ""
+"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
+"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
+"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
+msgstr ""
+"Vortex filformat spelaren genom Sashnov Alexander <sashnov at ngs.ru> \n"
+"Baserat på in_vtx.dll av Roman Sherbakov <v_soft at microfor.ru> \n"
+"Audacious plugin av Pavel Vymetalek <pvymetalek at seznam.cz>"
+
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack Dekoder"
+
+#: src/wavpack/wavpack.cc:211
+msgid "lossy (hybrid)"
+msgstr "lossy (hybrid)"
+
+#: src/wavpack/wavpack.cc:213
+msgid "lossy"
+msgstr "lossy"
+
+#: src/wavpack/wavpack.cc:255
+msgid ""
+"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
+"\n"
+"Some of the plugin code was by Miles Egan."
+msgstr ""
+"Copyright 2006 William Pitcock <nenolod at nenolod.net> \n"
+"En del av plugin-koden var av Miles Egan."
+
+#: src/xsf/plugin.cc:50
+msgid "2SF Decoder"
+msgstr "2SF Dekoder"
+
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
+msgid "XML Shareable Playlists (XSPF)"
+msgstr "XML Delbara Spellistor (XSPF)"
diff --git a/po/ta.po b/po/ta.po
index f12f846cc441..cb9a8a9555bc 100644
--- a/po/ta.po
+++ b/po/ta.po
@@ -3,15 +3,17 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# Gobi <gobikrishnant at gmail.com>, 2013
-# nar7esh <rajnareshwar at gmail.com>, 2013
+# Gobikrishnan <gobikrishnant at gmail.com>, 2013
+# Gobikrishnan <gobikrishnant at gmail.com>, 2013
+# Nareshwar Raju Vaneshwar <rajnareshwar at gmail.com>, 2013
+# Nareshwar Raju Vaneshwar <rajnareshwar at gmail.com>, 2013
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-04 21:21+0000\n"
+"Last-Translator: Thomas Lange <thomas-lange2 at gmx.de>\n"
"Language-Team: Tamil (http://www.transifex.com/projects/p/audacious/language/"
"ta/)\n"
"Language: ta\n"
@@ -20,51 +22,35 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "தனிதà¯à®¤ "
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "à®à®²à®¿à®ªà¯à®ªà®¿à®°à®¿à®ªà¯à®ªà¯"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "à®à¯à®´à¯à®¨à¯à®¤"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr ""
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib Player)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr ""
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib Player)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "à®
லாரமà¯"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr ""
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "à®
லாரமà¯"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -87,7 +73,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -109,7 +95,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -123,360 +109,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "à®à®¤à¯ à®à®à¯à®à®³à¯ à®à®´à¯à®ªà¯à®ªà¯à®µà®¤à®±à¯à®à®¾à®© à®
à®´à¯à®ªà¯à®ªà¯"
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr ""
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "நினà¯à®µà¯à®à¯à®à®¿"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "திà®à¯à®à®à¯à®à®¿à®´à®®à¯ "
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "à®à¯à®µà¯à®µà®¾à®¯à¯à®à®¿à®´à®®à¯ "
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "பà¯à®¤à®©à¯à®à®¿à®´à®®à¯ "
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "வியாழà®à¯à®à®¿à®´à®®à¯ "
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "வà¯à®³à¯à®³à®¿à®à¯à®à®¿à®´à®®à¯ "
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "à®à®©à®¿à®à¯à®à®¿à®´à®®à¯ "
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "à®à®¾à®¯à®¿à®±à¯à®±à¯à®à®¿à®´à®®à¯ "
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "à®
லாரம௠à®
à®®à¯à®ªà¯à®ªà¯à®à®³à¯"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "நà¯à®°à®®à¯ "
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "à®
லாரம௠à®
à®à®¿à®à¯à®à¯à®®à¯ நà¯à®°à®®à¯ (à®à®¯à®²à¯à®ªà¯à®¨à®¿à®²à¯) :"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "பின௠நிà®à®ªà¯à®¤à®®à®¾à®à¯à®à¯à®: "
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "மணிதà¯à®¤à®¿à®¯à®¾à®²à®à¯à®à®³à¯ "
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "நிமிà®à®à¯à®à®³à¯ "
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "à®
லாரம௠வà¯à®£à¯à®à®¿à®¯ நாà®à¯à®à®³à¯ தà¯à®°à®¿à®µà¯ à®à¯à®¯à¯à® "
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "நாள௠"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "à®à®¯à®²à¯à®ªà¯à®¨à®¿à®²à¯"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "நாà®à¯à®à®³à¯ "
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "à®®à®à¯à®à¯à®¤à®²à¯ "
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "வினாà®à®¿à®à®³à¯ "
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "à®à®²à®¿ à®
ளவ௠"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "à®à®à¯à®à¯ à®à®°à®®à¯à®ªà®¿à®à¯à®à¯à® "
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "à®à®±à¯à®¤à®¿ "
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "தறà¯à®ªà¯à®¤à¯à®¯ "
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "à®®à¯à®²à®¤à®¿à® பினà¯à®©à¯à®à¯à®à¯"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "à®à¯à®¯à®²à¯à®ªà®à¯à®¤à¯à®¤à¯à® "
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯ (விரà¯à®®à¯à®ªà®¿à®©à®¾à®²à¯ à®®à®à¯à®à¯à®®à¯)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à®¿à®©à¯ தà¯à®°à®¿à®µà¯ à®à¯à®¯à¯à®"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "விரà¯à®ªà¯à®ªà®¤à¯à®¤à¯à®°à¯à®µà¯à®à®³à¯ "
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "à®à®µà¯à®µà®¿à®°à¯à®ªà¯à®ª தà¯à®°à¯à®µà¯à®à®³à¯ à®à®¤à®©à¯ à®à®£à®°à¯à®¤à¯à®¤à¯à®à®¿à®©à¯à®±à®©?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "à®à®¤à®µà®¿ "
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "à®à¯à®±à¯à®µà®à¯à®à¯ வரà¯à®µà¯ "
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA வà¯à®³à®¿à®¯à¯à®à¯"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "à®à®¯à®²à¯à®ªà¯à®¨à®¿à®²à¯ தà¯à®à®¿à®ªà¯à®ªà¯ à®à¯à®±à®¿à®¯à¯à®à¯ பணà¯à®ªà¯à®±à¯à®± à®à®¾à®¤à®©à®®à¯ "
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "à®à®¯à®²à¯à®ªà¯à®¨à®¿à®²à¯ à®à®²à®µà¯ à®à®¾à®¤à®©à®®à¯"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "தà¯à®à®¿à®ªà¯à®ªà¯ à®à¯à®±à®¿à®¯à¯à®à¯ பணà¯à®ªà¯à®±à¯à®± à®à®¾à®¤à®©à®®à¯:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "à®à®²à®µà¯ à®à®¾à®¤à®©à®®à¯:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "à®à®²à®µà¯ à®à®±à¯à®ªà¯à®ªà¯:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "தà¯à®à¯à®à¯à®®à¯ தனà¯à®®à¯à®¯à¯ à®à¯à®±à¯à®à¯à®à¯à® "
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-à®à¯à®°à¯à®à®¿ (MIDI à®à®¯à®à¯à®à®¿ )"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA வà¯à®³à®¿à®¯à¯à®à¯"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-à®à¯à®°à¯à®à®¿ (MIDI à®à®¯à®à¯à®à®¿ )"
-
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-à®à¯à®°à¯à®à®¿ - à®à®²à®¿ à®à®´à¯à®¤à¯à®¤à¯à®°à¯ à®à¯à®ªà¯à®ªà®¿à®©à¯ தà¯à®°à®¿à®µà¯ à®à¯à®¯à¯à® "
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr ""
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "à®à¯à®ªà¯à®ªà®¿à®©à¯ பà¯à®¯à®°à¯ "
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "à®
ளவ௠(பயிà®à¯à®¸à¯)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "பà¯à®¯à®°à¯: "
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI தà®à®µà®²à¯ </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "வà®à®¿à®µà®®à¯à®ªà¯à®ªà¯: "
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "நà¯à®³à®®à¯ (மிலà¯à®²à®¿ வினாà®à®¿à®à®³à¯): "
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "பாà®à®²à¯à®à®³à®¿à®©à¯ à®à®²à®à¯à®à®à¯à®à®³à¯:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "மாறி "
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "தà¯à®à®¿à®ªà¯à®ªà¯à®à®³à¯ à®à®°à¯ நிமிà®à®¤à¯à®¤à®¿à®±à¯à®à¯: "
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "தà¯à®à®¿à®ªà¯à®ªà¯à®à®³à¯ à®à®°à¯ நிமிà®à®¤à¯à®¤à®¿à®±à¯à®à¯ (wavg): "
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "நà¯à®°à®ªà¯ பிரிவà¯:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI பினà¯à®©à¯à®à¯à®à¯à®à®³à¯ மறà¯à®±à¯à®®à¯ பாà®à®²à¯ வரிà®à®³à¯ </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "*à®à®¨à¯à®¤ MIDI à®à¯à®ªà¯à®ªà®¿à®±à¯à®à®¾à®© à®à®¨à¯à®¤à®µà¯à®°à¯ பினà¯à®©à¯à®à¯à®à¯à®®à¯ à®à®¿à®à¯à®à¯à®à®ªà¯à®ªà®à®µà®¿à®²à¯à®²à¯ * "
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "*à®à®¨à¯à®¤ MIDI à®à¯à®ªà¯à®ªà®¿à®±à¯à®à®¾à®© à®à®¨à¯à®¤à®µà¯à®°à¯ பாà®à®²à¯à®µà®°à®¿à®à®³à¯à®®à¯ à®à®¿à®à¯à®à¯à®à®ªà¯à®ªà®à®µà®¿à®²à¯à®²à¯ * "
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_à®®à¯à®à®µà¯à®®à¯"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr "(à®à¯à®²à¯à®²à¯à®ªà®à®¿à®¯à®±à¯à®± UTF-8 )"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "AMIDI-à®à¯à®°à¯à®à®¿ பறà¯à®±à®¿ "
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -487,152 +479,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr " AOSD ( திரà¯à®¯à®¿à®²à¯ தà¯à®¾à®©à¯à®±à¯à®®à¯ à®à®¾à®à¯à®à®¿)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "à®à¯à®µà¯à®µà®à®®à¯ "
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "வà®à¯à® வà®à®¿à®µà®¿à®²à®¾à®© à®à¯à®µà¯à®µà®à®®à¯ "
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "à®à¯à®´à®¿à®µà®¾à®© à®à¯à®µà¯à®µà®à®®à¯ "
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "à®à®¤à¯à®®à®¿à®²à¯à®²à¯ "
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "à®®à¯à®³à¯ à®à®¯à®à¯à®à®¿à®©à¯ à®à®°à®®à¯à®ªà®¿à®à¯à®à¯à® "
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯ à®à®à¯à®à¯ à®à®¯à®à¯à®à®ªà¯à®ªà®à¯à®à¯à®¯à®¿à®²à¯ திரà¯à®¯à®¿à®²à¯ தà¯à®¾à®©à¯à®±à¯à®®à¯ à®à®¾à®à¯à®à®¿ தà¯à®£à¯à®à®ªà¯à®ªà®à¯à®à®¿à®±à®¤à¯. "
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "தலà¯à®ªà¯à®ªà¯ மாறà¯à®±à®®à¯ "
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"à®®à¯à®³à¯ à®à®¯à®à¯à®à®¤à¯à®¤à®¿à®©à¯ பà¯à®¤à¯ திரà¯à®¯à®¿à®²à¯ தà¯à®¾à®©à¯à®±à¯à®®à¯ à®à®¾à®à¯à®à®¿ தà¯à®£à¯à®à®ªà¯à®ªà®à¯à®à®¿à®±à®¤à¯, பாà®à®²à¯ தலà¯à®ªà¯à®ªà¯ "
-"மாறà¯à®±à®ªà¯à®ªà®à¯à®à®¿à®±à®¤à¯, à®à®©à®¾à®²à¯ à®à¯à®ªà¯à®ªà®¿à®©à¯ பà¯à®¯à®°à¯ மாறà¯à®±à®®à®à¯à®¯à®¾à®¤à¯. à®à®£à¯à®¯ நà¯à®°à¯à®¾à®à¯à®à®³à®¿à®©à¯ பà¯à®¤à¯ à®à®®à¯à®®à¯à®±à¯ "
-"மிà®à®µà¯à®®à¯ பிரயà¯à®à®©à®®à®¾à®©à®¤à¯. "
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "à®à®à¯à®¨à®¿à®±à¯à®¤à¯à®¤à®¤à¯à®¤à¯ à®à®°à®®à¯à®ªà®¿à®à¯à® "
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "à®®à¯à®³à®¿à®¯à®à¯à®à®®à¯ à®à®à¯à®¨à®¿à®±à¯à®¤à¯à®¤à®ªà¯à®ªà®à¯à®®à¯ பà¯à®¤à¯ திரà¯à®¯à®¿à®²à¯ தà¯à®¾à®©à¯à®±à¯à®®à¯ à®à®¾à®à¯à®à®¿ தà¯à®£à¯à®à®ªà¯à®ªà®à¯à®à®¿à®±à®¤à¯."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "à®à®à¯à®¨à®¿à®±à¯à®¤à¯à®¤à®¤à¯à®¤à¯ நிறà¯à®¤à¯à®¤à¯à®"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "à®®à¯à®³à®¿à®¯à®à¯à®à®®à¯ நிறà¯à®¤à¯à®¤à®ªà¯à®ªà®à¯à®à¯à®¯à®¿à®²à¯ திரà¯à®¯à®¿à®²à¯ தà¯à®¾à®©à¯à®±à¯à®®à¯ à®à®¾à®à¯à®à®¿ தà¯à®£à¯à®à®ªà¯à®ªà®à¯à®à®¿à®±à®¤à¯. "
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "à®à®©à¯à®±à®¿à®©à¯ நிறà¯à®¤à¯à®¤à®ªà¯à®ªà®à¯à® நில௠"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "à®à®ªà¯à®ªà¯à®à¯à®à¯ X விலà®à¯à®à®®à¯:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "à®à®ªà¯à®ªà¯à®à¯à®à¯ Y விலà®à¯à®à®®à¯: "
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "à®
திà®à¯à®à®¿à®¯ திரà¯à®¯à®¿à®²à¯ தà¯à®¾à®©à¯à®±à¯à®®à¯ à®à®¾à®à¯à®à®¿à®¯à®¿à®©à¯ à®
à®à®²à®®à¯:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "பலà¯-à®à®£à®¿à®©à®¿à®¤à¯à®¤à®¿à®°à¯ தà¯à®°à¯à®µà¯à®à®³à¯ "
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "திரà¯à®¯à®¿à®²à¯ தà¯à®¾à®©à¯à®±à¯à®®à¯ à®à®¾à®à¯à®à®¿à®¯à®¿à®©à¯ à®à®¾à®à¯à®à¯à® à®à®¤à®©à¯ பயனà¯à®ªà®à¯à®¤à¯à®¤à®¿: "
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "à®
னà¯à®¤à¯à®¤à¯ à®à®£à®¿à®©à®¿à®¤à¯à®¤à®¿à®°à¯à®à®³à¯ "
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "à®à®£à®¿à®©à®¿à®¤à¯à®¤à®¿à®°à¯ %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "நà¯à®°à®®à¯ (மிலà¯à®²à®¿ வினாà®à®¿à®à®³à®¿à®²à¯) "
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "à®à®¾à®à¯à®à®¿à®ªà¯à®ªà®à¯à®¤à¯à®¤à¯à®:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "à®à®£à¯à®®à®à¯à®à®¿à®¯à®à¯à®¤à®²à¯:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "வà¯à®³à®¿à®®à®à¯à®à¯à®¤à®²à¯:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "à®à®´à¯à®¤à¯à®¤à¯à®°à¯à®à¯à®à®³à¯ "
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "à®à®´à¯à®¤à¯à®¤à¯à®°à¯ %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "நிழல௠"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "வழà®à¯à®à¯à®®à¯ பாà®à¯à®à¯ "
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "நிறà®à¯à®à®³à¯ "
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "நிறம௠%i "
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "தà¯à®£à¯à®à¯à®¤à®²à®¿à®©à¯ à®à¯à®¯à®²à¯à®ªà®à¯à®¤à¯à®¤à¯à® "
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "நிà®à®´à¯à®µà¯ "
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "தà¯à®¾à®à¯à®ªà¯à®ªà¯ நிரà¯à®µà®¾à®à®¿ à®à®£à¯à®à®±à®¿à®¯à®ªà¯à®ªà®à¯à®à®¤à¯"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -643,112 +629,112 @@ msgstr ""
"à®à®à¯à®à®¾à®¯à®®à®¾à® தà¯à®¾à®à¯à®ªà¯à®ªà¯ நிரà¯à®µà®¾à®à®¿à®¯à¯à®©à¯à®±à¯ à®à¯à®¯à®±à¯à®ªà®à¯à®¤à¯à®¤à®ªà¯à®ªà® வà¯à®£à¯à®à¯à®®à¯. à®à®²à¯à®²à¯à®¯à¯à®©à®¿à®²à¯ திரà¯à®¯à®¿à®²à¯ "
"தà¯à®¾à®©à¯à®±à¯à®®à¯ à®à®¾à®à¯à®à®¿ à®à®´à¯à®à¯à®à®¾à® à®à®¯à®à¯à®à®¾à®¤à¯. "
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "பà¯à®¾à®²à®¿ வà¯à®³à®¿à®ªà¯à®ªà®à¯à®¤à¯à®¤à®©à¯à®®à¯à®¯à®¿à®±à¯à®à¯ தà¯à®¾à®à¯à®ªà¯à®ªà¯ நிரà¯à®µà®¾à®à®¿à®¯à¯à®©à¯à®±à¯ தà¯à®µà¯à®¯à®¿à®²à¯à®²à¯ "
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "வà¯à®³à®¿à®ªà¯à®ªà®à¯à®¤à¯à®¤à®©à¯à®®à¯ "
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "பà¯à®¾à®²à®¿ வà¯à®³à®¿à®ªà¯à®ªà®à¯à®¤à¯à®¤à®©à¯à®®à¯ "
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "à®à®£à¯à®®à¯à®¯à®¾à®© வà¯à®³à®¿à®ªà¯à®ªà®à¯à®¤à¯à®¤à®©à¯à®®à¯ ( X தà¯à®¾à®à¯à®ªà¯à®ªà¯ நà¯à®à®¿à®ªà¯à®ªà¯ தà¯à®µà¯à®ªà¯à®ªà®à¯à®à®¿à®±à®¤à¯.)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "தà¯à®¾à®à¯à®ªà¯à®ªà¯ நà¯à®à¯à®à®¿à®ªà¯à®ªà¯ à®à®±à¯à®±à®ªà¯à®ªà®à®µà®¿à®²à¯à®²à¯ "
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "தà¯à®¾à®à¯à®ªà¯à®ªà¯ நà¯à®à¯à®à®¿à®ªà¯à®ªà¯ à®à®¾à®£à®ªà¯à®ªà®à®µà®¿à®²à¯à®²à¯ "
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>à®à®à®à®¿à®µà®¸à¯ திரà¯à®¯à®¿à®²à¯ தà¯à®¾à®©à¯à®±à¯à®®à¯ à®à®¾à®à¯à®à®¿ </span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "à®à®à®à®¿à®µà®¸à¯ திரà¯à®¯à®¿à®²à¯ தà¯à®¾à®©à¯à®±à¯à®®à¯ à®à®¾à®à¯à®à®¿ - à®à®³à¯à®³à®®à¯à®µà¯"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "à®à®à®®à¯ "
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "à®à®¯à®¿à®°à¯à®à¯à®à¯à®¤à®²à¯ "
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "à®à®´à¯à®¤à¯à®¤à¯ "
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "à®
லà®à¯à®à®¾à®°à®®à¯ "
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "தà¯à®£à¯à®à¯à®¤à®²à¯ "
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "மறà¯à®±à®µà¯"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr ""
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯ "
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "à®à®à®à®¿à®µà®¸à¯ பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯à®à®³à¯ "
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>நிறமà¯</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "à®®à®à¯à®à®²à®¾à®© à®à¯à®±à®¿à®¯à®¿à®²à®à¯à®à®®à¯"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "பார௠à®à®à¯à®ªà¯à®ªà®¿à®°à®¿à®ªà¯à®ªà¯ à®®à¯à®¤à®²à¯ à®à®°à¯à®à¯à®µà®¿à®à¯à®à¯à®°à®¿à®¯à®¤à¯ (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "à®®à¯à®©à¯à®©à®®à¯à®ªà¯à®ªà¯à®à®³à¯:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "நில௠à®à®à¯à®à®²à¯:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "à®à¯à®±à¯ à®
திரà¯à®µà¯à®£à¯:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "à®®à¯à®©à¯à®©à®®à¯à®ªà¯à®ªà¯à®à®³à¯:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "பார௠à®à®à¯à®ªà¯à®ªà®¿à®°à®¿à®ªà¯à®ªà¯ à®®à¯à®¤à®²à¯ à®à®°à¯à®à¯à®µà®¿à®à¯à®à¯à®°à®¿à®¯à®¤à¯ (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "நிறமால௠பà®à¯à®ªà¯à®ªà®¾à®¯à¯à®µà®¿ "
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "à®à®²à®¿ à®à®±à¯à®µà®à¯à®à¯ à®à¯à®¾à®°à¯à®à®¿"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -760,169 +746,156 @@ msgid ""
"This was a Google Summer of Code 2007 project."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>à®à®¾à®¤à®©à®®à¯</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "வாà®à®¿à®à¯à®à¯à®®à¯ வà¯à®à®®à¯ :"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "à®à®¾à®¤à®©à®®à¯ à®®à¯à®²à¯à®´à¯à®¤à¯:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>à®®à¯à®¤à¯à®¤à®°à®µà¯ </b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "à®à®±à¯à®µà®à¯à®à¯ à®à®´à¯à®¤à¯à®¤à¯à®à®³à¯ à®à®ªà®¯à¯à®à®¿à®à¯à®"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "CDDB à®à®©à¯ à®à®ªà®¯à¯à®à®¿à®à¯à®"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "CDDBP à®à®±à¯à®à¯ பதிலா஠HTTP à®à®©à¯ பயனà¯à®ªà®à¯à®¤à¯à®¤à¯à® "
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "à®à¯à®µà¯à®¯à®à®®à¯:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "வழி :"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "பà¯à®°à¯à®à¯ :"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "à®à®²à®¿ à®à®±à¯à®µà®à¯à®à¯ à®à¯à®¾à®°à¯à®à®¿"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "à®à®²à®¿ à®à®±à¯à®µà®à¯à®à¯"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "வà®à¯à®à¯ வà¯à®±à¯à®®à¯à®¯à®¾à® à®à®³à¯à®³à®¤à¯."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "à®à®¤à®°à®µà®±à¯à®± வà®à¯à®à¯ வà®à¯."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "à®à®²à®¿ à®à®±à¯à®µà®à¯à®à¯ பà®à¯à®à®¿à®¯à®²à¯ à®à®°à¯à®ªà¯à®ªà®à®¿à®à®³à¯"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "à®à®±à¯à®µà®à¯à®à®¿à®©à¯ à®à®¯à®à¯à®à¯à® "
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "à®à®±à¯à®µà®à¯à®à®¿à®©à¯ à®à¯à®°à¯à®à¯à®à¯à® "
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "à®à®²à®¿ à®à®±à¯à®µà®à¯à®à¯ பà®à¯à®à®¿à®¯à®²à¯ à®à®°à¯à®ªà¯à®ªà®à®¿à®à®³à¯"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>à®à¯à®°à¯à®à¯à®à®®à¯</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "à®®à¯à®¯ à®à®¤à¯à®¤à®®à¯: "
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "நிலà¯à®®à®¾à®±à¯à®®à¯ வரமà¯à®ªà®¾à®: "
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "நிலà¯à®®à®¾à®±à¯à®®à¯ வரமà¯à®ªà¯ à®à¯à®°à¯à®à¯à®à®¿ "
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -932,199 +905,224 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "à®
à®à®¿à®¤à¯à®¤à¯à®¾à®©à®¿:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "à®à®¯à®°à¯ à®à®±à¯à®¤à®¿ à®
திரà¯à®µà¯à®£à¯:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr ""
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "à®à®¯à®²à¯à®ªà¯à®¨à®¿à®²à¯ பாà®à®²à¯ நà¯à®³à®®à¯:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "à®à®²à®¿ பà¯à®¤à¯à®ªà¯à®ªà®¿à®¤à¯à®¤à®²à¯ à®à¯à®¯à®²à¯à®ªà®à¯à®¤à¯à®¤à® "
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "பà¯à®¤à¯à®ªà¯à®ªà®¿à®¤à¯à®¤à®²à¯ வà¯à®¤à®®à¯: "
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "SPC à®à¯à®±à®¿à®à¯à®à¯à®¾à®±à¯à®à®³à®¿à®©à¯ நà¯à®³à®¤à¯à®¤à¯ பà¯à®±à®à¯à®à®£à®¿à®à¯à®à®à¯à® "
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "à®à®¤à®¿à®°à¯à®®à¯à®´à®à¯à®à®¤à¯à®¤à¯ à®
திà®à®°à®¿à®à¯à®à¯à® "
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "விளà¯à®¯à®¾à®à¯à®à¯ பணிய஠à®à®à¯ à®à¯à®±à®¿à®µà®¿à®²à®à¯à®à®¿"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-"பாà®à®²à¯à®à®³à¯ விதà¯à®¤à®¿à®¯à®¾à®à®®à®¾à®© தல à®à®²à®à¯à®à®à¯à®à®³à¯ à®à¯à®£à¯à®à®¤à®¾à®²à¯ à®à¯à®±à¯à®à¯à®à¯à®®à®à¯à®à¯à®¤à®²à¯ à®à¯à®¯à®²à®¿à®´à®¨à¯à®¤à®¤à¯. à®à¯à®¯à®²à¯à®ªà¯à®ªà®à¯à®¤à¯à®¤ "
-"à®à®°à¯ த஠à®à®²à®µà¯à®¯à®¿à®©à¯ à®à®ªà®¯à¯à®à®¿à®¤à¯à®¤à¯ à®re த஠à®à®²à®à¯à®à®à¯à®à®³à¯à®à¯à®à¯ மாறà¯à®±à®µà¯à®®à¯."
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-"பாà®à®²à¯à®à®³à¯ விதà¯à®¤à®¿à®¯à®¾à®à®®à®¾à®© மாதிரி வà¯à®¤à®à¯à®à®³à¯ à®à¯à®£à¯à®à®¤à®¾à®²à¯ à®à¯à®±à¯à®à¯à®à¯à®®à®à¯à®à¯à®¤à®²à¯ à®à¯à®¯à®²à®¿à®´à®¨à¯à®¤à®¤à¯. "
-"à®à¯à®¯à®²à¯à®ªà¯à®ªà®à¯à®¤à¯à®¤ à®à®°à¯ மாதிரி வà¯à®¤ à®à®²à®µà¯à®¯à®¿à®©à¯ à®à®ªà®¯à¯à®à®¿à®¤à¯à®¤à¯ à®à®°à¯ மாதிரி வà¯à®¤à®à¯à®à®³à¯à®à¯à®à¯ மாறà¯à®±à®µà¯à®®à¯."
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>à®à¯à®±à¯à®à¯à®à¯ à®®à®à¯à®à®²à¯</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "à®®à¯à®±à¯à®ªà¯à®¾à®°à¯à®¨à¯à®¤à®²à¯:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "à®à¯à®±à¯à®à¯à®à¯ à®®à®à¯à®à®²à¯"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"பாà®à®²à¯à®à®³à¯ விதà¯à®¤à®¿à®¯à®¾à®à®®à®¾à®© தல à®à®²à®à¯à®à®à¯à®à®³à¯ à®à¯à®£à¯à®à®¤à®¾à®²à¯ à®à¯à®±à¯à®à¯à®à¯à®®à®à¯à®à¯à®¤à®²à¯ à®à¯à®¯à®²à®¿à®´à®¨à¯à®¤à®¤à¯. à®à¯à®¯à®²à¯à®ªà¯à®ªà®à¯à®¤à¯à®¤ "
+"à®à®°à¯ த஠à®à®²à®µà¯à®¯à®¿à®©à¯ à®à®ªà®¯à¯à®à®¿à®¤à¯à®¤à¯ à®re த஠à®à®²à®à¯à®à®à¯à®à®³à¯à®à¯à®à¯ மாறà¯à®±à®µà¯à®®à¯."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"பாà®à®²à¯à®à®³à¯ விதà¯à®¤à®¿à®¯à®¾à®à®®à®¾à®© மாதிரி வà¯à®¤à®à¯à®à®³à¯ à®à¯à®£à¯à®à®¤à®¾à®²à¯ à®à¯à®±à¯à®à¯à®à¯à®®à®à¯à®à¯à®¤à®²à¯ à®à¯à®¯à®²à®¿à®´à®¨à¯à®¤à®¤à¯. "
+"à®à¯à®¯à®²à¯à®ªà¯à®ªà®à¯à®¤à¯à®¤ à®à®°à¯ மாதிரி வà¯à®¤ à®à®²à®µà¯à®¯à®¿à®©à¯ à®à®ªà®¯à¯à®à®¿à®¤à¯à®¤à¯ à®à®°à¯ மாதிரி வà¯à®¤à®à¯à®à®³à¯à®à¯à®à¯ மாறà¯à®±à®µà¯à®®à¯."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>பளிà®à¯à®à¯à®°à¯à®µà®¾à®à¯à®l</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "à®
à®à®°à¯à®¤à¯à®¤à®¿:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "palinguruvaathal"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "à®à¯à®¾à®²à¯ தாள௠à®à¯à®°à¯à®à¯à®¨à®¿à®°à®²à¯"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr ""
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr ""
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr ""
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "à®
ழிà®à¯à®à¯à® "
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "ரதà¯à®¤à¯ à®à¯à®¯à¯à® "
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr ""
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>ethiroli</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "தாமதம௠:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "ms"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "பினà¯à®©à¯à®à¯à®à¯ :"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "à®à®²à®¿ à®
ளவ௠"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "à®à®¤à®¿à®°à¯à®²à®¿ "
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg நà¯à®à¯à®à®¿"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1134,55 +1132,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg நà¯à®à¯à®à®¿"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "FileWriter நà¯à®à¯à®à®¿ "
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "வà¯à®³à®¿à®¯à¯à®à¯à®à¯ à®à¯à®¾à®ªà¯à®ªà¯ வà®à®¿à®µà®®à¯:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "à®à®à¯à®à®®à¯à®à¯à®à¯à® "
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "à®
à®à®²à¯ à®à¯à®¾à®ªà¯à®ªà®à®¤à¯à®¤à®¿à®²à¯ à®à¯à®®à®¿à®à¯à®à®µà¯à®®à¯"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "விரà¯à®ªà¯à®ª à®à¯à®¾à®ªà¯à®ªà®à®¤à¯à®¤à®¿à®²à¯ à®à¯à®®à®¿à®à¯à®à®µà¯à®®à¯"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "வà¯à®³à®¿à®¯à¯à®à¯à®à¯ à®à¯à®¾à®ªà¯à®ªà¯ à®à¯à®ªà¯à®ªà®à®®à¯: "
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "à®à®°à¯ à®à¯à®¾à®ªà¯à®ªà¯à®±à¯à®¯à¯ தà¯à®°à¯à®¨à¯à®¤à¯à®à¯à®à¯à®à®µà¯à®®à¯"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "à®à®°à¯à®¨à¯à®¤à¯ à®à¯à®¾à®ªà¯à®ªà¯ à®à®¿à®à¯à®à¯à®à¯à®®à¯:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "à®
à®à®²à¯ à®à¯à®¾à®ªà¯à®ªà¯ à®à¯à®±à®¿à®à¯à®à¯à®¾à®±à¯à®l"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "à®
à®à®²à¯ à®à¯à®ªà¯à®ªà¯à®±à¯ "
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "à®à¯à®¾à®ªà¯à®ªà¯ நà¯à®à¯à®à®¿à®ªà¯à®ªà®¿à®©à¯ à®
à®à®±à¯à®± வà¯à®£à¯à®à®¾à®®à¯"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "à®à¯à®ªà¯à®ªà¯ பà¯à®¯à®°à¯à®¯à¯à®®à¯ பாà®à®²à¯ à®à®£à¯à®£à¯à®¯à¯à®®à¯ வரà¯à®"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1200,165 +1198,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "FileWriter நà¯à®à¯à®à®¿ "
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "தானியà®à¯à®à¯"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "à®à¯à®à¯à®à¯ பà¯à®°à¯à®¾à®²à®¿"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "பà¯à®°à¯à®¾à®²à®¿"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "à®à®±à¯à®±à¯"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 à®à®à¯à®à®®à¯à®ªà¯à®ªà¯ "
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "பà®à®¿à®®à¯à®±à¯ தரமà¯:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "வà¯à®³à®¿à®¯à¯tà®à¯ மாதிரி வà¯à®¤à®®à¯:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "பிà®à¯à®µà¯à®¤m / à®
à®´à¯à®¤à¯à®¤ விà®à®¿à®¤à®®à¯:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "பிà®à¯à®µà¯à®¤à®®à¯ (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "à®
à®´à¯à®¤à¯à®¤ விà®à®¿à®¤à®®à¯:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "à®à®²à®¿ à®®à¯à®±à¯à®®à¯:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "மறà¯à®±à®µà¯"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "à®à®à¯à®®à¯à®¯à®¾à®© ISO à®à®£à®à¯à®à®¤à¯à®¤à¯ à®à¯à®¯à®²à¯à®ªà®à¯à®¤à¯à®¤à® "
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "தவற௠பாதà¯à®à®¾à®ªà¯à®ªà¯"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "தரம௠"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "VBR/ABR à®à®©à¯ à®à¯à®¯à®²à¯à®ªà®à¯à®¤à¯à®¤à¯à® "
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "வà®à¯:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR தà¯à®°à¯à®µà¯à®à®³à¯:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "à®
திà®à¯à®±à¯à®¨à¯à®¤ பிà®à¯à®µà¯à®¤à®®à¯ (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "à®
திà®à¯à®à®¿à®¯ பிà®à¯à®µà¯à®¤à®®à¯ (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "à®à®£à¯à®à®¿à®ªà¯à®ªà®¾à® à®à¯à®±à¯à®¨à¯à®¤ பிà®à¯à®µà¯à®¤à®¤à¯à®¤à¯ à®à¯à®¯à®²à¯à®ªà®à¯à®¤à¯à®¤à¯à® "
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR தà¯à®°à¯à®µà¯à®à®³à¯:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "à®à®°à®¾à®à®°à®¿ பிà®à¯à®µà¯à®¤à®®à¯ (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR தர நிலà¯:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Xing VBR தலà¯à®ªà¯à®ªà¯ à®à®´à¯à®¤ வà¯à®£à¯à®à®¾à®®à¯ "
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "à®
ளவà¯à®°à¯à®à¯à®à®³à¯ à®à®à¯à®à®ªà¯à®ªà®à¯à®¤à¯à®¤à¯à® :"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "பதிபà¯à®ªà¯à®°à®¿à®®à¯ à®à®© à®à¯à®±à®¿à®à¯à®à¯à® "
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "à®
à®à®²à¯à®© à®à¯rià®à¯à®à¯à®"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ID3 à®
ளபà¯à®°à¯:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "பதிபà¯à®ªà¯ 2 à®à¯à®±à®¿à®¯à¯ பலமா஠à®à®³à¯à®³à®à®à¯à®à¯à® "
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "பதிபà¯à®ªà¯ 1 à®à¯à®±à®¿à®¯à¯ மாதà¯à®¤à®¿à®°à®®à¯ à®à®³à¯à®³à®à®à¯à®à¯à® "
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "பதிபà¯à®ªà¯ 2 à®à¯à®±à®¿à®¯à¯ மாதà¯à®¤à®¿à®°à®®à¯ à®à®³à¯à®³à®à®à¯à®à¯à® "
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "à®à¯à®±à®¿ "
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis à®à¯à®±à®¿à®®à¯à®±à¯à®¯à®¾à®à¯à®à®¿ à®à®à¯à®à®®à¯à®ªà¯à®ªà¯"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "தரம௠(0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC à®à¯à®±à®¿à®µà®¿à®²à®à¯à®à®¿ "
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr ""
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1366,21 +1368,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC à®à¯à®±à®¿à®µà®¿à®²à®à¯à®à®¿ "
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO நà¯à®à¯à®à®¿"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1392,530 +1398,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL நிறமால௠பà®à¯à®ªà¯à®ªà®¾à®¯à¯à®µà®¿"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Gnome à®à¯à®±à¯à®à¯à®à¯à®µà®´à®¿à®à®³à¯ "
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "பதிவ௠à®à®£à¯"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "தலà¯à®ªà¯à®ªà¯"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "பாà®à®à®°à¯"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "வரà¯à®à®®à¯"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "à®à¯à®±à¯à®µà®à¯à®à¯"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "பாà®à®²à¯ "
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "à®à®²à®à¯à®à®¿à®¯à®¨à®à¯"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "வரிà®à¯à®¯à®¿à®²à¯ à®à®à®®à¯ "
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "நà¯à®³à®®à¯"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "à®à¯à®ªà¯à®ªà¯ vali"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "à®à¯à®ªà¯à®ªà®¿à®©à¯ பà¯à®¯à®°à¯ "
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "விரà¯à®ªà¯à®ª தலà¯à®ªà¯à®ªà¯ "
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "பிà®à¯à®µà¯à®¤à®®à¯"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "தà¯à®à®²à¯ à®à®°à¯à®µà®¿"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "à®à®à®¤à¯ பà®à¯à®à®®à¯ தரà¯à®¯à®¿à®±à®à¯à®à¯à® "
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "வலத௠பà®à¯à®à®®à¯ தரà¯à®¯à®¿à®±à®à¯à®à¯à®"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "à®®à¯à®²à¯ பà®à¯à®à®®à¯ தரà¯à®¯à®¿à®±à®à¯à®à¯à®"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "à®à¯à®´à¯ பà®à¯à®à®®à¯ தரà¯à®¯à®¿à®±à®à¯à®à¯à®"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "தரà¯à®¯à®¿à®±à®à¯à® வà¯à®£à¯à®à®¾à®®à¯ "
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "à®®à¯à®à®à¯à®à¯à® "
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "தà¯à®à®²à¯ à®à®°à¯à®µà®¿"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_à®à¯à®ªà¯à®ªà¯à®à¯à®à®³à¯à®¤à¯ திற ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "à®®à¯à®à®µà®°à®¿à®¯à¯_திற ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "à®à¯à®ªà¯à®ªà¯à®à¯à®à®³à¯ _à®à¯à®°à¯ ..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "à®®à¯à®à®µà®°à®¿à®¯à¯ à®à¯à®°à¯ ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "பறà¯à®±à®¿ ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_விலà®à¯ "
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_à®à®¯à®à¯à®à¯à® "
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "_à®à®à¯à®¨à®¿à®±à¯à®¤à¯à®¤à¯"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_நிறà¯à®¤à¯à®¤à¯ga"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_à®®à¯à®¨à¯à®¤à¯à®¯"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_à®
à®à¯à®¤à¯à®¤à¯ "
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_மறà¯à®ªà®à®¿à®¯à¯à®®à¯"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "à®à¯à®²à¯à®à¯à®à¯à® "
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "à®®à¯à®©à¯à®©à¯à®à¯à®à®¿à®¯ பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯ alla"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "பாà®à®²à¯ தà®à®µà®²à¯ "
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "_நà¯à®°à®¤à¯à®¤à®¿à®±à¯à®à¯ தாவவà¯à®®à¯ "
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "பாà®à®²à¯à®à¯à®à¯ _தாவவà¯à®®à¯"
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr ""
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr ""
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr ""
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "_தலà¯à®ªà¯à®ªà¯ à®
à®à®¿à®ªà¯à®ªà®à¯à®¯à®¿à®²à¯"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr ""
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "பாà®à®²à¯ _à®à®²à®à¯à® à®
à®à®¿à®ªà¯à®ªà®à¯à®¯à®¿à®²à¯ "
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "_பாà®à®à®°à¯ à®
à®à®¿à®ªà¯à®ªà®à¯à®¯à®¿à®²à¯"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "வà¯à®³à®¿à®¯à®¿à®à¯à® திà®à®¤à®¿ à®
à®à®¿à®ªà¯à®ªà®à¯à®¯à®¿à®²à¯"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "_à®à¯à®ªà¯à®ªà¯ வழி à®
à®à®¿à®ªà¯à®ªà®à¯à®¯à®¿à®²à¯"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "_விரà¯à®ªà¯à®ª தலà¯à®ªà¯à®ªà¯ à®
à®à®¿à®ªà¯à®ªà®à¯à®¯à®¿à®²à¯"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "தலà¯à®à¯à®´à¯ à®à®´à¯à®à¯à®à¯"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_தறà¯à®ªà¯à®¾à®à¯à®à¯ à®à®´à¯à®à¯à®à¯"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_பà¯à®¤à¯à®ªà¯à®ªà®¿à®à¯à®à¯à® "
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_வரிà®à¯à®ªà¯à®ªà®à¯à®¤à¯à®¤à¯à® "
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "_à®à®¿à®à¯à®à¯à®à®ªà¯à®ªà¯à®±à®¾à®¤ à®à¯à®ªà¯à®ªà¯à®à®³à¯ à®
à®à®±à¯à®±à¯à®"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_பà¯à®¤à®¿à®¯ "
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr ""
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_à®à®±à®à¯à®à¯à®®à®¤à®¿ ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_à®à®±à¯à®±à¯à®®à®¤à®¿ ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr ""
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "_வரிà®à¯ நிரà¯à®µà®¾à®à®¿ ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "à®à®²à®¿à®à®°à®ªà¯à®ªà®¾à®©à¯ _à®
திà®à®°à®¿à®à¯à®à¯à® "
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "à®à®²à®¿à®à®°à®ªà¯à®ªà®¾à®©à¯ _à®à¯à®±à¯à®à¯à®à¯à® "
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_à®à®®à®®à®¾à®à¯à®à®¿"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "_பà®à¯à®à®¿à®¯à®²à¯ பà®à¯à®à®¿à®¯à¯ à®à®¾à®£à¯à®ªà®¿à®à¯à®à¯à® "
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "தà®à®µà®²à¯ பà®à¯à®à®¿à®¯à¯ à®à®¾à®£à¯à®ªà®¿à®à¯à®à¯à® "
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "தà®à®µà®²à¯ பà®à¯à®à®¿ à®à®¾à®à¯à®à®¿à®¯à®¾à®à¯à®à®¤à¯à®¤à¯ à®à®¾à®£à¯à®ªà®¿à®à¯à®à¯à® "
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "_நிலà¯à®®à¯ பà®à¯à®à®¿à®¯à¯ à®à®¾à®£à¯à®ªà®¿à®à¯à®à¯à®"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "à®à¯à®ªà¯à®ªà¯ "
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_à®®à¯à®³à¯à®à®¯à®à¯à®à¯à® "
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯ "
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "_à®à¯à®µà¯à®à®³à¯ "
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "_வà¯à®³à®¿à®¯à¯à®à¯"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_paarvayiduga"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_வரிà®à¯à®ªà¯à®ªà®à¯à®¤à¯à®¤à¯à®/வரிà®à¯à®ªà¯à®ªà®à¯à®¤à¯à®¤à®²à¯ à®
à®à®±à¯à®±à¯à® "
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "வà¯à®à¯à®à¯à® "
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "நà®à®²à¯à®à¯à®à¯à® "
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_à®à®à¯à®à®µà¯à®®à¯"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "_à®
னà¯à®¤à¯à®¤à¯à®¯à¯à®®à¯ தà¯à®°à¯à®¨à¯à®¤à¯à®à¯à®à¯à®à¯à® "
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "மறà¯à®ªà¯à®¯à®°à¯"
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr ""
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK à®à®à¯à®®à¯à®à®®à¯ "
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - à®à®à®à®¿à®µà®¸à¯"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "à®à®à¯à®¨à®¿à®²à¯à®ªà¯à®ªà®à¯à®¤à¯à®¤à¯à®à®¿à®±à®¤à¯ ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "à®à®à®à®¿à®µà®¸à¯"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "தனிதà¯à®¤ "
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "à®à®²à®¿à®ªà¯à®ªà®¿à®°à®¿à®ªà¯à®ªà¯"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] ""
msgstr[1] ""
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "à®à®±à¯à®±à¯ à®®à¯à®±à¯."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯ murai"
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "பாà®à®²à®¿à®©à¯ பினà¯à®©à®°à¯ நிறà¯à®¤à¯à®¤à¯à®."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr ""
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "à®à®¯à®à¯à®à¯à® "
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "à®à®à¯à®¨à®¿à®±à¯à®¤à¯à®¤à¯ / à®®à¯à®£à¯à®à¯à®®à¯ à®à®¯à®à¯à®à¯ "
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "நிறà¯à®¤à¯à®¤à¯à® "
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr ""
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "5 விநாà®à®¿à®à®³à¯ à®®à¯à®©à¯à®©à®¾à®³à¯ à®à¯à®²à¯à® "
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "5 விநாà®à®¿à®à®³à¯ பினà¯à®©à®¾à®²à¯ à®à¯à®²à¯à® "
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "à®à®²à®¿à®¯à®à®à¯à®à®µà¯à®®à¯"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "à®à®²à®¿à®à®°à®ªà¯à®ªà®¾à®©à¯ à®
திà®à®°à®¿à®à¯à®à¯à®"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "à®à®²à®¿à®à®°à®ªà¯à®ªà®¾à®©à¯ à®à¯à®±à¯à®à¯à®à¯à®"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "à®à¯à®ªà¯à®ªà®¿à®±à¯à®à¯ தாவவà¯à®®à¯."
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr " திரà¯à®¯à®¿à®²à¯ தà¯à®¾à®©à¯à®±à¯à®®à¯ à®à®¾à®à¯à®à®¿à®¯à®¿à®©à¯ kaattuga"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(à®à®¤à¯à®µà¯à®®à®²à¯à®²)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1926,15 +2009,11 @@ msgstr ""
"â\n"
"நà¯à®à¯à®à®³à¯ தà¯à®¾à®à®° விரà¯à®®à¯à®ªà¯à®à®¿à®±à¯à®°à¯à®à®³à®¾?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "à®à¯à®à¯à®à®¿ பà¯à®¾à®¤à¯à®¤à®¾à®©à¯à®à®³à¯ பிணà¯à®¤à¯à®¤à®²à¯"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "à®à®²à®à®³à®¾à®µà®¿à®¯ à®®à¯à®à¯à®à®¿à®¯à®à®¾à®µà®¿ நà¯à®à¯à®à®¿ à®à®à¯à®à®®à¯à®ªà¯à®ªà¯"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -1942,23 +2021,27 @@ msgstr ""
"à®à®´à¯à®¤à¯à®¤à¯ பà¯à®²à®¤à¯à®¤à®¿à®²à¯ à®à®°à¯ விà®à¯ à®à¯à®°à¯à®à¯à®à¯à®¯à¯ à®
à®´à¯à®¤à¯à®¤à®µà¯à®®à¯.â\n"
"à®à®à¯à®à®³à¯à®à¯à®à¯ à®à¯à®à¯à®à®¿ பà¯à®¾à®¤à¯à®¤à®¾à®©à¯à®à®³à¯ பிணà¯à®à¯à®à®µà¯à®®à¯ à®®à¯à®à®¿à®¯à¯à®®à¯."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "à®à¯à®±à¯à®à¯à®à¯à®µà®¿à®à¯à®à®³à¯:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>நà®à®µà®à®¿à®à¯à®à¯: </b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>à®à®¾à®µà®¿ பிணà¯à®¤à¯à®¤à®²à¯:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr ""
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "à®à®²à®à®³à®¾à®µà®¿à®¯ à®à¯à®±à¯à®à¯à®à¯à®µà®¿à®à¯à®à®³à¯:"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1973,56 +2056,51 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "à®à®²à®à®³à®¾à®µà®¿à®¯ à®à¯à®±à¯à®à¯à®à¯à®µà®¿à®à¯à®à®³à¯:"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK வà¯à®³à®¿à®¯à¯à®à¯ "
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK வà¯à®³à®¿à®¯à¯à®à¯ "
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s à®
à®®à¯à®ªà¯à®ªà¯à®à®³à¯"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA பà¯à®°à®µà®²à®©à¯ à®
à®®à¯à®ªà¯à®ªà¯à®à®³à¯"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "தà¯à®¾à®à¯à®¤à®¿à®à¯à®à¯à®±à¯ பாதà¯à®à®³à¯:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2033,73 +2111,39 @@ msgstr ""
"பà¯à®¤à®¿à®¯ பாதà¯à®à®³à¯ à®à¯à®°à¯à®¤à¯à®¤à®¤à®©à¯ பினà¯à®©à®°à¯, பà¯à®¤à®¿à®¯ à®à¯à®°à¯à®à¯à®¨à®¿à®°à®²à¯à®à®³à¯ வரà¯à® à®à®³à¯à®³à®¿à®à¯à®à®µà®¿à®©à¯ à®
à®´à¯à®¤à¯à®¤à®.</"
"small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "à®à®°à¯à®ªà¯à®ªà®¿à®²à¯à®³à¯à®³ à®à¯à®°à¯à®à¯à®¨à®¿à®°à®²à¯à®à®³à¯:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "à®à¯à®¯à®²à¯à®ªà®à¯à®¤à¯à®¤à¯à® "
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "à®à¯à®°à¯à®à¯à®¨à®¿à®°à®²à¯à®à®³à®¿à®©à¯ à®à¯à®¯à®²à¯à®ªà¯à®ªà®à¯à®¤à¯à®¤à¯à®:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "à®
à®®à¯à®ªà¯à®ªà¯à®à¯à®à®³à¯"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA "
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: LIRC à®à®¤à®µà®¿à®¯à¯ à®à®°à®®à¯à®ªà®¿à®à¯à® mudiyavillaiâ\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: LIRC à®à®©à¯ à®à®à¯à®à®®à¯à®ªà¯à®ªà¯ à®à¯à®¾à®ªà¯à®ªà®¿à®©à¯ வாà®à®¿à®à¯à® à®®à¯à®à®¿à®¯à®µà®¿à®²à¯à®²à¯â\n"
-"\n"
-"%s: LIRC à®à®©à¯ à®à®µà®£à®à¯à®à®³à¯ பà®à®¿à®à¯à®à®µà¯à®®à¯â\n"
-"\n"
-"%s: à®à®ªà¯à®ªà®à®¿ à®à®°à¯ à®à®°à®¿à®¯à®¾à®© à®à®à¯à®à®®à¯à®ªà¯à®ªà¯ à®à¯à®¾à®ªà¯à®ªà®¿à®©à¯ à®à®°à¯à®µà®¾à®à¯à®à¯à®µà®¤à¯â\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: à®®à¯à®³à¯ à®à®£à¯à®ªà¯à®ªà®¿à®±à¯à®à¯ à®®à¯à®©à¯à®à®¿à®±à®¤à¯ ...â\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: à®
றியபà¯à®ªà®à®¾à®¤ à®à®à¯à®à®³à¯ \"%s\"â\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: LIRC à®à®²à¯ à®à®°à¯à®¨à¯à®¤à¯ தà¯à®£à¯à®à®¿à®à¯à®à®ªà¯à®ªà®à¯à®à¯ விà®à¯à®à®¤à¯ â\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: à®à®µà¯à®µà¯à®°à¯ %d வினாà®à®¿à®à¯à®à¯à®®à¯ à®®à¯à®³à¯ à®à®£à¯à®ªà¯à®ªà¯ பà¯à®± à®®à¯à®¯à®²à¯à®®à¯ ...â\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC "
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2115,73 +2159,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b> à®à®£à¯à®ªà¯à®ªà¯ </b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "LIRC à®à¯à®µà¯à®à®¯à®¤à¯à®¤à¯à®à¯à®à¯ à®®à¯à®³à¯ à®à®£à¯à®à¯à®à¯à® "
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "à®®à¯à®³à¯ à®à®£à¯à®à¯à® à®®à¯à®©à¯ பà¯à®±à¯à®à¯à® :"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC "
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki நà¯à®à¯à®à®¿ "
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "à®à®¨à¯à®¤à®µà¯à®°à¯ பாà®à®²à¯à®µà®°à®¿à®à®³à¯à®®à¯ à®à®¿à®à¯à®à¯à®à®ªà¯à®ªà®à®µà®¿à®²à¯à®²à¯ "
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "thavaruthal"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "thavaruthal"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki நà¯à®à¯à®à®¿ "
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "திறம௠பிறபà¯à®ªà®¾à®à¯à®à®¿"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "திறம௠பிறபà¯à®ªà®¾à®à¯à®à®¿:% d நிமிà®à®¤à¯à®¤à®¿à®±à¯à®à®¾à®© தà¯à®à®¿à®ªà¯à®ªà¯à®à®³à¯ "
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "திறம௠பிறபà¯à®ªà®¾à®à¯à®à®¿:%d நிமிà®à®¤à¯à®¤à®¿à®±à¯à®à®¾à®© தà¯à®à®¿à®ªà¯à®ªà¯à®à®³à¯ %d %d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2190,162 +2242,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "திறம௠பிறபà¯à®ªà®¾à®à¯à®à®¿"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "த஠à®à®²à®µà¯à®ªà¯à®ªà®¾à®©à¯ "
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>த஠à®à®²à®µà¯</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "வà¯à®³à®¿à®¯à¯à®à¯à®à¯ thadangal"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "த஠à®à®²à®µà¯à®ªà¯à®ªà®¾à®©à¯ "
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS நà¯à®à¯à®à®¿"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (தà¯à®¾à®à¯à®¤à®¿ à®à®¯à®à¯à®à®¿ )"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr ""
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr ""
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr ""
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr ""
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr ""
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr ""
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr ""
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr ""
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (தà¯à®¾à®à¯à®¤à®¿ à®à®¯à®à¯à®à®¿ )"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
+
+#: src/mpg123/mpg123.cc:54
+msgid "MPG123 Plugin"
+msgstr "MPG123 நà¯à®à¯à®à®¿"
+
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
-#: src/mpg123/mpg123.c:210
+#: src/mpg123/mpg123.cc:248
msgid "Surround"
msgstr "à®à¯à®´à¯à®¨à¯à®¤"
-#: src/mpg123/mpg123.c:412
-msgid "MPG123 Plugin"
-msgstr "MPG123 நà¯à®à¯à®à®¿"
+#: src/mpris2/plugin.cc:39
+msgid "MPRIS 2 Server"
+msgstr "MPRIS 2 à®à¯à®µà¯à®¯à®à®®à¯ "
+
+#: src/neon/neon.cc:97
+msgid "Neon HTTP/HTTPS Plugin"
+msgstr "Neon HTTP/HTTPS நà¯à®à¯à®à®¿ "
+
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
-#: src/mpris2/plugin.c:403
-msgid "MPRIS 2 Server"
-msgstr "MPRIS 2 à®à¯à®µà¯à®¯à®à®®à¯ "
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
-#: src/neon/neon.c:1056
-msgid "Neon HTTP/HTTPS Plugin"
-msgstr "Neon HTTP/HTTPS நà¯à®à¯à®à®¿ "
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "நிறà¯à®¤à¯à®¤à¯à®ªà¯à®ªà®à¯à®à®¤à¯ "
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "à®à®à®à®¿à®µà®¸à¯ à®à®¯à®à¯à®à®µà®¿à®²à¯à®²à¯ "
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "பணிமà¯à®à¯ à®
றிவிபà¯à®ªà¯à®à®³à¯"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2365,55 +2449,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr ""
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "பணிமà¯à®à¯ à®
றிவிபà¯à®ªà¯à®à®³à¯"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "à®à®¾à®£à¯à®ªà®¿à®à¯à®à¯à® "
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "à®à®à¯à®¨à®¿à®±à¯à®¤à¯à®¤à¯à® "
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "à®
à®à¯à®¤à¯à®¤à®¤à¯ "
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. à®à®¯à®²à¯à®ªà¯à®¨à®¿à®²à¯ à®à®¾à®¤à®©à®®à¯"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 வà¯à®³à®¿à®¯à¯à®à¯ "
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "à®à®²à®¿ à®à®¾à®¤à®©à®®à¯:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "மாறà¯à®±à¯ à®à®¾à®¤à®©à®®à¯ பயனà¯à®ªà®à¯à®¤à¯à®¤à¯à®:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "à®
மரà¯à®µà¯à®à®³à¯ à®à®à¯à®¯à¯ à®à®²à®¿ à®
ளவ௠à®à¯à®®à®¿à®à¯à®à¯à®."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "OSS à®®à¯à®©à¯à®ªà¯à®¾à®°à¯à®³à¯ à®®à¯à®²à®®à¯ வà®à®¿à®µà®®à¯à®ªà¯à®ªà¯ மாறà¯à®±à®¤à¯à®¤à¯ à®à¯à®¯à®²à¯à®ªà®à¯à®¤à¯à®¤à¯à®."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "à®®à¯à®¯à¯à®¨à®¿à®à®°à¯ à®à®²à®ªà¯à®ªà®¿à®©à¯ தà®à¯à®à¯à® பிரதà¯à®¯à¯à® à®®à¯à®±à¯à®¯à®¿à®©à¯ à®à¯à®¯à®²à¯à®ªà®à¯à®¤à¯à®¤à¯à®."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2422,19 +2515,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 வà¯à®³à®¿à®¯à¯à®à¯ "
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2 à®à¯à®±à®¿à®µà®¿à®²à®à¯à®à®¿ "
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio வà¯à®³à®¿à®¯à¯à®à¯ "
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2454,143 +2563,212 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio வà¯à®³à®¿à®¯à¯à®à¯ "
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "à®®à¯à®¨à¯à®¤à¯à®¯"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "மறà¯à®®à¯à®±à¯"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "à®à¯à®²à¯à®à¯à®à¯à® "
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "மாதிரி விà®à®¿à®¤à®®à¯ பரிமாறà¯à®±à®¿ "
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "மாதிரிà®à®³à¯ தவிரà¯à®à¯à®à®µà¯à®®à¯ / à®®à¯lavum"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "நà¯à®°à¯à®à¯à®¾à®à¯à®à¯ à®à®à¯à®à¯à®à®£à®¿à®ªà¯à®ªà¯"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "வà¯à®à®®à®¾à® sinc à®à®à¯à®à¯à®à¯à®°à¯à®à®²à¯"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "மதà¯à®¤à®¿à®®à®®à®¾à®© sinc à®à®à¯à®à¯à®à¯à®°à¯à®à®²à¯"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "à®à®¿à®±à®¨à¯à®¤ sinc à®à®à¯à®à¯à®à¯à®°à¯à®à®²à¯"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b> பரிமாறà¯à®±à®®à¯ </b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "à®®à¯à®±à¯à®®à¯ "
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "வà¯à®¤à®®à¯:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>வà¯à®¤ வரà¯à®ªà®à®à¯à®à®³à¯ </b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "வà¯à®¤ வரà¯à®ªà®à®à¯à®à®³à®¿à®©à¯ à®à®ªà®¯à¯à®à®¿à®à¯à®à¯à® "
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz: "
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz: "
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz: "
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz: "
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz: "
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz: "
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "மாதிரி விà®à®¿à®¤à®®à¯ பரிமாறà¯à®±à®¿ "
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "வலà¯à®¯à®®à¯à®ªà¯à®ªà¯ à®à®¿à®à¯à®à®²à¯ "
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "à®à®°à®¿à®ªà®¾à®°à¯à®à¯à®à®ªà¯à®ªà®à¯à®à®¿à®±à®¤à¯ "
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2601,86 +2779,72 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL வà¯à®³à®¿à®¯à¯à®à¯ "
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL வà¯à®³à®¿à®¯à¯à®à¯ "
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "நà¯à®²à®à®®à¯"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "தà¯à®°à®¿à®¯à®¾à®¤ பாà®à®à®°à¯"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "தà¯à®°à®¿à®¯à®¾à®¤ à®à¯à®±à¯à®µà®à¯à®à¯"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
+msgid "%d result"
+msgid_plural "%d results"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
+msgstr[1] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯à®©à¯à®±à¯ _à®à®°à¯à®µà®¾à®à¯à®à¯à® "
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à®¿à®±à¯à®à¯ _à®à¯à®°à¯à®à¯à® "
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "நà¯à®²à®à®¤à¯à®¤à®¿à®²à¯ தà¯à®à¯à® "
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2688,679 +2852,769 @@ msgstr ""
"à®à®à®à®¿à®µà®¸à¯ à®à®²à¯ à®à®à¯ நà¯à®à®²à®®à¯à®©à¯à®±à¯ à®à®±à®à¯à®à¯à®®à®¤à®¿ à®à¯à®¯à¯à®¯ à®à¯à®ªà¯à®ªà®à®®à¯à®©à¯à®±à¯ தà¯à®°à®¿à®µà¯ à®à¯à®¯à¯à®¤à¯ பà¯à®¤à¯à®ªà¯à®ªà®¿à®ªà¯à®ªà¯ "
"பà¯à®¤à¯à®¤à®¾à®©à¯ à®
à®´à¯à®¤à¯à®¤à¯à®. "
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "தயவ௠à®à¯à®¯à¯à®¤à¯ பà¯à®°à¯à®¤à¯à®¤à®¿à®°à¯à®à¯à®à¯à® ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "à®à¯à®ªà¯à®ªà®à®®à¯à®©à¯à®±à¯ தà¯à®°à¯à® "
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "à®®à¯à®³à¯ à®à®¯à®à¯à®à¯"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "பாரà¯à®µà¯à®¯à®¿à®à¯à® "
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr ""
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr ""
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr ""
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr ""
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr ""
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "மறà¯à®®à¯à®±à¯"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "à®à¯à®²à¯à®à¯à®à¯à® "
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "à®®à¯à®©à¯à®©à¯à®à¯à®à®¿à®¯ பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯à®à¯à®à¯ à®à¯à®²à¯à®² வà¯à®£à¯à®à®¾à®®à¯"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr ""
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "à®®à¯à®¨à¯à®¤à¯à®¯"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "பà¯à®¤à®¿à®¯ பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr ""
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr ""
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr ""
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr ""
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr ""
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr ""
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr ""
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr ""
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr ""
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯ திரà¯à®¤à¯à®¤à®¿à®¯à¯ à®à®¾à®£à¯à®ªà®¿à®à¯à® "
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "à®à®®à®®à®¾à®à¯à®à®¿à®¯à¯ à®à®¾à®£à¯à®ªà®¿à®à¯à® "
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "à®à®ªà¯à®ªà¯à®´à¯à®¤à¯à®®à¯ à®®à¯à®²à¯ "
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "தலà¯à®ªà¯à®ªà®¿à®©à¯ பà®à®¿ "
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "à®à¯à®ªà¯à®ªà¯ பà¯à®¯à®°à®¿à®©à¯ பà®à®¿ "
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "à®
னà¯à®¤à¯à®¤à¯à®¯à¯à®®à¯ à®
à®à®±à¯à®±à¯à®. "
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "வரிà®à¯à®¯à®¿à®©à¯ à®
ழிà®à¯à®à¯à®. "
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "à®à®¿à®à¯à®à¯à®à®ªà¯à®ªà¯à®±à®¾à®¤ à®à¯à®ªà¯à®ªà¯à®à®³à¯ à®
à®à®±à¯à®±à¯à®. "
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "பà¯à®²à®¿à®à®³à¯ à®
à®à®±à¯à®±à¯à® "
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "தà¯à®°à®¿à®µà¯à®à¯à®¯à¯à®¯à®¾à®¤à®µà®±à¯à®±à¯ à®
à®à®±à¯à®±à¯à®. "
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "தà¯à®°à®¿à®µà¯à®à¯à®¯à¯à®¤à®µà®±à¯à®±à¯ à®
à®à®±à¯à®±à¯à®"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "தà¯à®à®¿ தà¯à®°à¯à®¨à¯à®¤à¯à®à¯à®à¯à®à®µà¯à®®à¯"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "தலà¯à®à¯à®´à¯ தà¯à®°à¯à®¨à¯à®¤à¯à®à¯à®ªà¯à®ªà¯"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "à®à®¤à®©à¯à®¯à¯à®®à¯ தà¯à®°à¯à®¨à¯à®¤à¯à®à¯à®à¯à® வà¯à®£à¯à®à®¾à®®à¯."
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "à®
னà¯à®¤à¯à®¤à¯à®¯à¯à®®à¯ தà¯à®°à¯à®¨à¯à®¤à¯à®à¯à®à¯à®à¯à® "
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "à®à¯à®±à¯à®µà®à¯à®à®¿à®©à¯ பà®à®¿ "
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "பாà®à®²à¯ à®à®²à®à¯à® à®
à®à®¿à®ªà¯à®ªà®à¯à®¯à®¿à®²à¯ "
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "பாà®à®à®°à¯à®à®³à®¿à®©à¯ பà®à®¿ "
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "à®à¯à®±à¯à®µà®à¯à®à®¿à®©à¯ பà®à®¿ "
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "பாà®à®²à¯ à®à®²à®à¯à® à®
à®à®¿à®ªà¯à®ªà®à¯à®¯à®¿à®²à¯ "
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
+
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "பà®à¯à®à®¿à®¯à®²à®¿à®©à¯ தறà¯à®ªà¯à®¾à®à¯à®à®¾à® தà¯à®¾à®©à¯à®±à®à¯à®à¯à®¯à¯à® "
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "பà®à¯à®à®¿à®¯à®²à®¿à®©à¯ தலà¯à®à¯à®´à®¾à®à¯à®à¯à®"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "வரிà®à¯à®¯à®¾à®©à®µà®±à¯à®±à¯ தà¯à®°à®¿à®."
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "பà®à¯à®à®¿à®¯à®²à¯ வரிà®à¯à®¯à®¾à®à¯à®à¯à® "
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "வà¯à®à¯à®à¯à® "
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "நà®leà®à¯à®à¯à®à¯à®"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "à®à®à¯à®à¯à® "
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winamp பாரமà¯à®ªà®°à®¿à®¯ à®à®à¯à®®à¯à®à®®à¯"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "à®à¯à®®à®¿à®à¯à®à¯à® "
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "à®à®±à¯à®±à¯à® "
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "à®®à¯à®©à¯à®©à®®à¯à®ªà¯à®ªà¯à®à®³à¯"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "à®®à¯à®©à¯à®©à®®à¯à®ªà¯à®ªà¯à®à®³à®¿à®©à¯ à®à®±à¯à®±à¯à® "
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "தானியà®à¯à®à¯ à®®à¯à®©à¯à®©à®®à¯à®ªà¯à®ªà¯à®à®³à¯ à®à®±à¯à®±à¯à® "
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "à®®à¯à®©à¯à®©à®®à¯à®ªà¯à®ªà¯à®à®³à¯ à®à¯à®®à®¿à®à¯à®"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "தானியà®à¯à®à¯ à®®à¯à®©à¯à®©à®®à¯à®ªà¯à®ªà¯à®à®³à¯ à®à¯à®®à®¿à®à¯à®à¯à®"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "à®®à¯à®©à¯à®©à®®à¯à®ªà¯à®ªà®¿à®©à¯ à®
ழிà®à¯à®à¯à® "
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "தானியà®à¯à®à¯ à®®à¯à®©à¯à®©à®®à¯à®ªà¯à®ªà¯à®à®³à¯ à®
ழிà®à¯à®à¯à®"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_iyakkai"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "பிரதான à®à®¯à®à¯à®à®¿ à®à®¾à®³à®°à®¤à¯à®¤à®¿à®©à¯ à®à®´à¯à®¤à¯à®¤à¯à®°à¯à®µà¯ தà¯à®°à®¿à®µà¯ à®à¯à®¯à¯à® :"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à®¿à®©à¯ à®à®´à¯à®¤à¯à®¤à¯à®°à¯à®µà¯ தà¯à®°à®¿à®µà¯ à®à¯à®¯à¯à® :"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "பிà®à¯à®®à®¾à®ªà¯ ப஠à®à®´à¯à®¤à¯à®¤à¯à®°à¯à®à¯à®à®³à¯ à®à®ªà®¯à¯à®à®¿à®à¯à® (ASCII à®à®£à¯ à®®à®à¯à®à¯à®®à¯ à®à®¤à®°à®¿à®à¯à®à®¿à®±à®¤à¯)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "à®à®°à¯ திà®à¯à®à®³à®¿à®²à¯à®®à¯ பாà®à®²à¯ தலà¯à®ªà¯à®ªà¯ ururavaikkuga "
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "பà®à¯à®ªà¯à®ªà®¾à®¯à¯à®µà®¿ "
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "à®à¯à®±à®¿à®¯à®¿à®²à®à¯à®à®®à¯"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "à®
ணà¯à®à¯à®à¯à® "
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "à®à®¯à®²à¯à®ªà®¾à®©"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "நà¯à®°à¯à®ªà¯à®ªà¯ "
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "à®à¯à®à¯à®à®³à¯ "
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "பà®à¯à®à¯à®à®³à¯"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "à®®à¯à®¤à¯à®µà®¾à®© "
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "à®®à¯à®¤à¯à®µà®¾à®¯à¯ "
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "நà®à¯à®¤à¯à®¤à®°à®®à¯ "
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "விரà¯à®µà¯ "
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "மி஠விரà¯à®µà®¾à® "
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "பனி "
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "மிரà¯à®¤à¯à®µà®¾à®© "
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "பà¯à®¾à®¤à¯à®µà®¾à®©"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "à®à®°à¯à®µà® à®à®¾à®à¯à®à®¿à®ªà¯à®ªà®à¯à®¤à¯à®¤à®²à¯ "
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "à®®à¯à®©à¯ விரிவாà®à¯à®à®¿ "
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr ""
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "à®à®à®à®¿à®µà®¸à¯ à®à®®à®®à®¾à®à¯à®à®¿ "
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "%d:%-2.2d / %d:%-2.2d à®à®©à¯ நாà®à¯à®"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "à®à®²à®¿ à®
ளவà¯: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "à®à®®à®¨à®¿à®²à¯:% d%% à®à®à®¤à¯"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "à®à®®à®¨à®¿à®²à¯:மதà¯à®¤à®¿ "
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "à®à®®à®¨à®¿à®²à¯:% d%% வலத௠"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "தà¯à®°à¯à®µà¯ பà®à¯à®à®¿à®¯à®²à¯"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "'à®à®ªà¯à®ªà¯à®¾à®¤à¯à®®à¯ à®®à¯à®²à¯' à®à®©à¯à®ªà®¤à¯ à®®à¯à®à®à¯à®à¯à® "
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "'à®à®ªà¯à®ªà¯à®¾à®¤à¯à®®à¯ à®®à¯à®²à¯' à®à®©à¯à®ªà®¤à¯ à®à¯à®¯à®±à¯à®ªà®à¯à®¤à¯à®¤à¯à® "
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "à®à¯à®¾à®ªà¯à®ªà¯ தà®à®µà®²à¯ பà¯à®à¯à®à®¿"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "à®à®±à¯à®±à¯ à®®à¯à®±à¯."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯ murai"
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "பாà®à®²à®¿à®©à¯ பினà¯à®©à®°à¯ நிறà¯à®¤à¯à®¤à¯à®."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "à®à¯à®¯à¯à®µà®¿à®©à¯ பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à®¿à®²à¯à®³à¯à®³ பதிவà¯à®à®³à¯ தà¯à®à¯à® "
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3371,57 +3625,61 @@ msgstr ""
"வழà®à¯à®à®®à®¾à®© வà¯à®³à®¿à®ªà¯à®ªà®¾à®à¯à®à®³à¯ தà¯à®¾à®à®°à®¿à®¯à®²à¯ à®à¯à®£à¯à®à®µà¯. வழà®à¯à®à®®à®¾à®© வà¯à®³à®¿à®ªà¯à®ªà®¾à®à¯à®à®³à¯ à®à®µà¯à®µà®¾à®±à¯ à®à®¯à®à¯à®à¯à®®à¯ à®à®© "
"தà¯à®°à®¿à®¯à®¾à®µà®¿à®à®¿à®©à¯ நà¯à®à¯à®à®³à¯ தà¯à®à¯à®µà®¤à®¿à®©à¯ தà¯à®²à¯à®²à®¿à®¯à®®à®¾à®© பà®à¯à®¤à®¿à®¯à®¿à®©à¯ à®à®³à¯à®³à®¿à®à¯à®. "
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "தலà¯à®ªà¯à®ªà¯:"
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "à®à¯à®±à¯à®µà®à¯à®à¯:"
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "பாà®à®à®°à¯:"
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "à®à¯à®ªà¯à®ªà®¿à®©à¯ பà¯à®¯à®°à¯:"
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "தà¯à® à®®à¯à®©à¯ à®®à¯à®©à¯à®©à¯à®¯ தà¯à®°à®¿à®µà¯à®à®³à¯ தà¯à®à¯à®¤à¯à®¤à®´à®¿à®à¯à®à¯à® "
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "தà¯à®°à¯à®µà®à¯à®¯à¯à®®à¯ பதிவà¯à®à®³à¯ தானா஠நிலà¯à®®à®¾à®±à¯à®±à¯ வரிà®à¯à®¯à®¾à®à¯à®à¯à®"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "தà¯à®°à¯à®µà®à¯à®¯à¯à®®à¯ பதிவà¯à®à®³à¯à®à¯à®à¯ பà¯à®¤à®¿à®¯ பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯à®©à¯à®±à¯ à®à®°à¯à®µà®¾à®à¯à®à¯à®."
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "à®à®à®à®¿à®µà®¸à¯ பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯ திரà¯à®¤à¯à®¤à®¿"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d à®à®©à¯ %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "à®à®µà®£à®ªà¯à®ªà®à¯à®¤à¯à®¤à®ªà¯à®ªà®à¯à® Winamp 2.x தà¯à®²à¯ "
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "à®à®µà®£à®ªà¯à®ªà®à¯à®¤à¯à®¤à®ªà¯à®ªà®à®¾à®¤ Winamp 2.x தà¯à®²à¯ "
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "à®à¯à®¾à®ªà¯à®ªà®à®®à¯à®©à¯à®±à¯ à®à®°à¯à®µà®¾à®à¯à® à®®à¯à®à®¿à®¯à®µà®¿à®²à¯à®²à¯ (%s): %sâ\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr ""
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3443,76 +3701,71 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
msgstr ""
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "Sndio வà¯à®³à®¿à®¯à¯à®à¯à®à¯ நà¯à®à¯à®à®¿à®à®³à¯ பறà¯à®±à®¿"
-
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "à®à®¤à®°à®¿à®à¯à®à®ªà¯à®ªà®à®¾à®¤ வà®à®¿à®µà®®à¯à®ªà¯à®ªà¯ "
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-#: src/sndio/sndio.c:384
-msgid "sndio device"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "à®à®°à®¿ "
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "பாà®à®²à¯ மாறà¯à®±à®®à¯ "
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "à®à®à®à®¿à®µà®¸à¯ பà¯à®¤à®¿à®¯ பாà®à®²à¯à®©à¯à®±à¯ à®à®¯à®à¯à® à®à®à¯à®à®³à¯à®¯à®¿à®à¯à®. "
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>à®
ளவà¯à®°à¯à®à¯à®à®³à¯ à®à®à¯à®à¯à®à¯à®à¯à®³à¯ à®®à¯à®±à¯à®à¯à®¾à®³à¯ à®à¯à®±à®¿à®à®³à®¾à®²à¯ à®à®à¯à®ªà¯à®¾à®¤à®¿à®¨à¯à®¤à®¿à®°à¯à®à¯à® வà¯à®£à¯à®à¯à®®à¯."
+"à®à®²à¯à®²à¯à®¯à¯à®©à®¿à®²à¯ பாதà¯à®à®¾à®ªà¯à®ªà¯ à®à®ªà®¤à¯à®¤à¯ à®à®°à¯à®à¯à®à®¿à®±à®¤à¯</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "à®à®à¯à®à®³à¯:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "à®à®à®à®¿à®µà®¸à¯ பாà®à®²à¯à®©à¯à®±à¯ நிறà¯à®¤à¯à®¤ à®à®à¯à®à®³à¯à®¯à®¿à®à¯à®. "
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "à®à®à®à®¿à®µà®¸à¯ பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à¯à®©à¯à®±à¯ à®®à¯à®à®¿à®µà®à¯à®¯à¯à®®à¯ பà¯à®¤à¯ à®à®¯à®à¯à® à®à®à¯à®à®³à¯à®¯à®¿à®à¯à®. "
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"பாà®à®²à¯à®©à¯à®±à®¿à®©à¯ தலà¯à®ªà¯à®ªà¯ மாறà¯à®®à¯ பà¯à®¤à¯ à®à®¯à®à¯à® à®à®à¯à®à®³à¯à®¯à®¿à®à¯à®. (à®
தாவத௠பிணà¯à®¯ நà¯à®°à¯à®¾à®à¯à®à®³à®¿à®©à¯ பà¯à®¤à¯ )"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3527,19 +3780,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>à®
ளவà¯à®°à¯à®à¯à®à®³à¯ à®à®à¯à®à¯à®à¯à®à¯à®³à¯ à®®à¯à®±à¯à®à¯à®¾à®³à¯ à®à¯à®±à®¿à®à®³à®¾à®²à¯ à®à®à¯à®ªà¯à®¾à®¤à®¿à®¨à¯à®¤à®¿à®°à¯à®à¯à® வà¯à®£à¯à®à¯à®®à¯."
-"à®à®²à¯à®²à¯à®¯à¯à®©à®¿à®²à¯ பாதà¯à®à®¾à®ªà¯à®ªà¯ à®à®ªà®¤à¯à®¤à¯ à®à®°à¯à®à¯à®à®¿à®±à®¤à¯</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "à®à®à¯à®à®³à¯à®à®³à¯ "
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3548,51 +3797,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "விரà¯à®µà¯ "
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "à®à¯à®±à¯à®µà¯ "
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "à®à®¯à®°à¯"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "மி஠à®à®¯à®°à¯ "
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "தரமà¯:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "வà¯à®à®®à¯:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "à®à¯à®°à¯à®¤à®¿:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
msgstr ""
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3603,63 +3852,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr ""
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "à®à®ªà¯à®¤ à®
ளவ௠மாறà¯à®±à¯à® "
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "à®à®¯à®à¯à®à¯à®®à¯ பாà®à®²à¯ மாறà¯à®±à¯à® "
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr ""
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "திà®à¯à®°à¯ à®à®¾à®³à®°à®¤à¯à®¤à¯ à®à¯à®¯à®²à®¿à®´à®à¯à® à®à¯à®¯à¯à®."
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr ""
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "பாà®à®²à¯ பà®à¯à®à®¿à®¯à®²à®¿à®©à¯ à®à®°à¯à®à¯à®à¯à®®à¯ பà¯à®¤à¯ à®®à¯à®©à¯à®©à¯à®à¯à®à®¿ à®à¯à®²à¯à®²à®µà¯à®®à¯ "
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
msgstr ""
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>à®à¯à®à¯à®¤à®²à¯ பà¯à®°à¯à®¾à®²à®¿ </b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr ""
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "à®à®²à®¿ à®à®°à¯à®µà®¾à®à¯à®à®¿ "
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "தà¯à®¾à®©à®¿ பிறபà¯à®ªà®¾à®à¯à®à®¿:"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3668,15 +3917,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "à®à®²à®¿ à®à®°à¯à®µà®¾à®à¯à®à®¿ "
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "à®à¯à®°à®²à¯ நà¯à®à¯à®à®®à¯"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3697,44 +3942,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr ""
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr ""
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
msgstr ""
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr ""
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr ""
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
+#: src/xsf/plugin.cc:50
+msgid "2SF Decoder"
msgstr ""
-#: src/xsf/plugin.c:217
-msgid "2SF Decoder"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
msgstr ""
-#: src/xspf/xspf.c:438
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr ""
diff --git a/po/tr.po b/po/tr.po
index 47c1885e8b2f..5311488d4834 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -5,28 +5,29 @@
# Translators:
# aamet <aaydin159 at gmail.com>, 2012
# aamet <aaydin159 at gmail.com>, 2012
-# elma sevmem <drmxmyt at gmail.com>, 2013
-# elma sevmem <drmxmyt at gmail.com>, 2013
-# emfi <emrefirat93 at gmail.com>, 2013
-# etc <etcetin at gmail.com>, 2014
-# emfi <emrefirat93 at gmail.com>, 2013
-# ferhatelmas <elmas.ferhat at gmail.com>, 2013
-# ferhatelmas <elmas.ferhat at gmail.com>, 2013
+# elmasevmem <drmxmyt at gmail.com>, 2013
+# elmasevmem <drmxmyt at gmail.com>, 2013
+# Emre FIRAT <emrefirat93 at gmail.com>, 2013
+# Emin Tufan <etcetin at gmail.com>, 2014
+# Emre FIRAT <emrefirat93 at gmail.com>, 2013
+# ferhat elmas <elmas.ferhat at gmail.com>, 2013
+# ferhat elmas <elmas.ferhat at gmail.com>, 2013
# Murat Senel <muratasenel at gmail.com>, 2007
# Murat Åenel <muratasenel at gmail.com>, 2007
# Onur Küçük <onur at pardus.org.tr>, 2007
-# seckyn <seckyn at windowslive.com>, 2013
-# seckyn <seckyn at windowslive.com>, 2013
+# seckin Yılmaz <seckyn at windowslive.com>, 2013
+# seckin Yılmaz <seckyn at windowslive.com>, 2013
# tarkan255 <t.oguzman at hotmail.com>, 2012
# tarkan255 <t.oguzman at hotmail.com>, 2012
-# volkangezer <volkangezer at gmail.com>, 2013
+# Tolga <tolsen92 at outlook.com>, 2014
+# Volkan Gezer <volkangezer at gmail.com>, 2013,2015
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-13 00:59+0000\n"
+"Last-Translator: Volkan Gezer <volkangezer at gmail.com>\n"
"Language-Team: Turkish (http://www.transifex.com/projects/p/audacious/"
"language/tr/)\n"
"Language: tr\n"
@@ -35,51 +36,35 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "mono"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "stereo"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr ""
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
-msgstr ""
+msgstr "AAC(Raw) Ãözücü"
+
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug(AdLib Oynatıcı)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr ""
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr ""
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "Alarm"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
-msgstr ""
+msgstr "Alarm ayarla..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
msgstr ""
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "Alarm"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -102,7 +87,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -124,7 +109,7 @@ msgid ""
"\n"
msgstr ""
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -138,360 +123,366 @@ msgid ""
" toggle button if you want it to be shown."
msgstr ""
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "Bu uyandırma çaÄrısıdır."
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
-msgstr ""
+msgstr "Bugünkü hatırlatıcınız..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "Hatırlatıcı"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "Pazartesi"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "Salı"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "ÃarÅamba"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "PerÅembe"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "Cuma"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "Cumartesi"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "Pazar"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "Alarm Ayarları"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "Zaman"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "Alarm (Varsayılan)"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "Sonra sessiz:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "saat"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "dakika"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "Sonraki alarm için günleri seçiniz"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "Gün"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Ãntanımlı"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "Günler"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "Bozulma"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "saniye"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "Ses"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "İle baÅla"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Son"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Åu anda"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "Ek Komut"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "izin ver"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "Ãalma Listesi(isteÄe baÄlı)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
-msgstr ""
+msgstr "Ãalma listesi Seç"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "Seçenekler"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Bu ayarlar ne anlama geliyor?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Yardım"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
+msgstr "Albüm kapaÄı"
+
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "Albüm KapaÄı (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA Ãıktısı"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
msgstr ""
-#: src/alsa/config.c:210
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(açıklama yok)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Varsayılan PCM aygıtı"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Varsayılan karıÅtırma aygıtı"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM aygıtı:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "KarıÅtırıcı aygıt:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "KarıÅtırıcı öÄesi:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
msgstr ""
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr ""
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr ""
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr ""
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr ""
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr ""
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr ""
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr ""
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>GeliÅmiÅ</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr ""
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr ""
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - SoundFont dosyası seç"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_İptal"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "_Aç"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "Dosya adı"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "Boyut (bayt)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "İsim:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI Bilgisi </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Biçim:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "Uzunluk (ms):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr ""
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "deÄiÅken"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPM:"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "Zamanı Böl:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI Yorumları ve Sözleri </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* bu midi dosyasında yorum bulunamadı *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* bu midi dosyasında Åarkı sözü bulunamadı *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_Kapat"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (geçersiz UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr ""
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -502,152 +493,146 @@ msgid ""
"http://neugierig.org/software/ghosd/"
msgstr ""
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr ""
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "Dikdörtgen"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "Dairesel Dikdörtgen"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "İçbükey Dikdörtgen"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "Hiçbiri"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "Ãalmayı BaÅlat"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "Parça listesindeki girdi oynatıldıÄında OSD'yi baÅlatır."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "BaÅlık DeÄiÅtirme"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"Åarkı baÅladıÄında görünen Åarkı baÅlıÄı deÄiÅir, fakat dosya adı aynı kalır "
-"ise OSD'yi tetikler. Bu yetenek özellikle İnternet üzerinden dinlenen "
-"yayınlarda baÅlık deÄiÅikliÄi olduÄunda bu ayar faydalı oluyor."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "Bekletme Açık"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "Ãalma bekletildiÄinde OSD'yi baÅlatır."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "Bekletme Kapalı"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "Ãalmaya yeniden baÅladıÄında OSD'yi baÅlatır."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "YerleÅtirme"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "DeÄiÅken X deÄeri:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "DeÄiÅken Y deÄeri:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "Maksimum OSD geniÅliÄi:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "Ãoklu Ekran seçenekleri"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "OSD kullanımını göster:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "tüm ekranlar"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "ekran %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "Zamanlama (ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Görüntü:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "Gecikme:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "Kaybolma:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "Yazı Tipleri"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "Yazı tipi %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "Gölge"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "Tarama Biçemi"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "Renkler"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "Renkler %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "Tetikleyiciyi etkinleÅtir"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "Olay"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "Composite yöneticisi tespit edildi"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -657,112 +642,112 @@ msgstr ""
"ÃalıÅan bir Composite yöneticisinin olduÄundan emin deÄilseniz lütfen "
"OSD'nin düzgün çalıÅması için bir Composite yöneticisi çalıÅtırınız"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "Sahte Åeffaflık için composite yöneticisi gerekli deÄil"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "Åeffaflık"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "Sahte Åeffaflık"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "Gerçek Åeffaflık (X Composite Eklentisi gerekli)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Composite eklentisi yüklü deÄil"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Composite eklentisi eriÅilebilir deÄil"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - yapılandırması"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "_Sına"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "_Ayarla"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "Konum"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "Canlandırma"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "Metin"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "Dekorasyon"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "BaÅlat"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "ÃeÅitli"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr ""
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "ASXv3 Parça listesi"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr ""
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr ""
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
-msgstr ""
+msgstr "<b>Renk</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr ""
-#: src/bs2b/plugin.c:142
-msgid "Feed level:"
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
msgstr ""
-#: src/bs2b/plugin.c:154
-msgid "Cut frequency:"
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
msgstr ""
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
+#: src/bs2b/plugin.cc:136
+msgid "Feed level:"
msgstr ""
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
msgstr ""
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/bs2b/plugin.cc:139
+msgid "Cut frequency:"
+msgstr ""
+
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr ""
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -774,169 +759,156 @@ msgid ""
"This was a Google Summer of Code 2007 project."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "CDDBP yerine HTTP kullan"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "BaÄlantı Noktası:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "Ses CD'si"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "Parça %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr ""
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "Sürücü boÅ."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "Desteklenmeyen disk türü."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr ""
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "CD çal"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "CD Ekle"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr ""
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr ""
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr ""
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "Dinamik alan:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr ""
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -946,195 +918,220 @@ msgid ""
"Shay Green <gblargg at gmail.com>"
msgstr ""
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "Bas:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "Tiz:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
-msgstr ""
+msgstr "Yankı:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Varsayılan Åarkı uzunluÄu:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr ""
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "Ses örneklemesini etkinleÅtir"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "Ãrnekleme oranı:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr ""
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "SPC etiketlerindeki uzunluÄu gözardı et"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "DerinliÄi artır"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "Oyun Konsolu Müzik Ãözümleyicisi"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr ""
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr ""
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr ""
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr ""
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr ""
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr ""
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr ""
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "Dosyaları Sil"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr ""
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr ""
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr ""
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr ""
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "Ãöp kutusuna taÅı"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "Seçilen dosyaları kalıcı olarak silmek istiyor musunuz?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "Sil"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "İptal"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "Dosyaları Sil"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "Seçilen Dosyaları Sil"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr ""
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr ""
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr ""
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr ""
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr ""
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr ""
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
+#: src/echo_plugin/echo.cc:39
+msgid "Echo"
msgstr ""
-#: src/echo_plugin/echo.c:122
-msgid "Echo"
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1144,55 +1141,55 @@ msgid ""
"Matti Hämäläinen <ccr at tnsp.org>"
msgstr ""
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
msgstr ""
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Ãıktı dosya biçimi:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "Yapılandır"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "Orjinal dizine kaydet"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "Ãzel dizine kaydet"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "Ãıktı dosya klasörü:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "Dizin seçimi"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Dosya adı kaynaÄı:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "orijinal dosya iÅaretleri"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "özgün dosya adı"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Dosya ismi uzantılarını daraltma"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "Parça numarısını dosya adına ekle"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1210,165 +1207,169 @@ msgid ""
"USA."
msgstr ""
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr ""
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "Otomatik"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "BirleÅik Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "Stereo"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Mono"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 Yapılandırması"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr ""
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "Algoritma Kalitesi:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "Ãıktı Ãrnekleme Oranı:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Bit oranı / SıkıÅtırma oranı:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "Bit oranı (kbps):"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "SıkıÅtırma oranı:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Ses Kipi:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "ÃeÅitli"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "ISO standartlarına mutlak uyum gözetmeye zorla"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr ""
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "Hata koruması"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "Kalite"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "VBR/ABR etkinleÅtir"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Tür:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR Seçenekleri:"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "En düÅük bit oranı (kbps):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "En yüksek bit oranı (kbps):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "En düÅük bit oranını tam olarak zorla"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR Seçenekleri:"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "Ortalama bit oranı (kbps):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR kalite seviyesi:"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Xing VBR baÅlıÄını yazma"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "Telif hakkı olarak iÅaretle"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "Orijinal olarak iÅaretle"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ID3 parametreleri:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "sürüm 2 etkiketin eklenmesini zorla"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "Sadece v1 etiketini ekle"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "Sadece v2 etiketini ekle"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "Etiketler:"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis Kodlayıcı Ayarları"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Kalite seviyesi (0 - 10):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr ""
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "kayıpsız"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1376,21 +1377,25 @@ msgid ""
"http://www.skytale.net/projects/bmp-flac2/"
msgstr ""
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr ""
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
msgstr ""
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1402,530 +1407,607 @@ msgid ""
"License: GPLv2+"
msgstr ""
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "Sayı girin"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "BaÅlık"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "Sanatçı"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Yıl"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "Albüm"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr ""
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "Parça"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr ""
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "Liste sırası"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "Uzunluk"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "Dosya yolu"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Dosya adı"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Ãzel baÅlık"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "Bit oranı"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr ""
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr ""
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "Arama Aracı"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "Sola kenetle"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "SaÄa kenetle"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "Ãste kenetle"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "AÅaÄıya kenetle"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "Ãıkar"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "Devre DıÅı"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "Arama Aracı"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "_Dosya Aç ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "URL _Aç ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr ""
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "U_RL Ekle ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr ""
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "H_akkında"
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr ""
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_Ãık"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_Oynat"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "_Duraklat"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "D_urdur"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "_Ãnceki"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_Sonraki"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "_Tekrarla"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "_KarıÅtır"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr ""
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr ""
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_Åarkı Bilgisi ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "Süre Atla"
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "Åarkı Atla"
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
-msgstr ""
+msgstr "Tekrarlama BaÅlancıÄı _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
-msgstr ""
+msgstr "Tekrarlama Sonu _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
-msgstr ""
+msgstr "_Tekrarlama Noktalarını Sil"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "_BaÅlıÄa Göre"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
-msgstr ""
+msgstr "_Dosya Yoluna Göre"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
-msgstr "Parça Numarası"
+msgstr "Parça_Numarasına Göre"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
-msgstr "Sanatçı"
+msgstr "_Sanatçıya Göre"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr ""
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
-msgid "By Release _Date"
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
+msgid "By Release _Date"
msgstr "Yayın Tarihi"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr ""
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr ""
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Ãzel BaÅlık"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr ""
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "_Rastgele SipariÅ"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
msgstr ""
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_Yenile"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_Tür"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr ""
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr ""
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr ""
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Yeni"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr ""
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr ""
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_Yükle ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_Ãıkart ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr ""
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "Sıra Yöneticisi ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Sesi_Arttır"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "Sesi_Azalt"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_Ekolayzır"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr ""
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "Menü_ÃubuÄunu Göster"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "Bilgi ÃubuÄunu Göster"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr ""
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "Durum ÃubuÄunu Göster"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr ""
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr ""
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Dosya"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_Oynatma"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "Ãalma Listesi"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "Servisler"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "Ãıktı"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "_Görünüm"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr ""
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "Ke_s"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_Kopyala"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "_YapıÅtır"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "Tümünü_Seç"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr ""
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr ""
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr ""
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr ""
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
-msgstr ""
+msgstr "Kapatma Butonu Göster"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr ""
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr ""
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr ""
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr ""
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr ""
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK Arayüzü"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr ""
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "mono"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "stereo"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] ""
msgstr[1] ""
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr ""
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Ãalma Listesi modu"
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "Åarkıdan sonra duruyor."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "Ãnceki parça"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "Ãal"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "Ara ver/Devam et"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "Dur"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "Sonraki parça"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "5 saniye sonrası"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "5 saniye öncesi"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "Sessiz"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "Sesi aç"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "Sesi kıs"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "Dosyaya Atla"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr ""
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr ""
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr ""
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr ""
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr ""
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr ""
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(hiçbiri)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -1933,37 +2015,37 @@ msgid ""
"Do you want to continue?"
msgstr ""
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr ""
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "Genel Kısayol Eklentisi Ayarları"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
msgstr ""
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "Kısayollar:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr ""
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr ""
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "_Ekle"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr ""
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -1978,127 +2060,90 @@ msgid ""
" Jeremy Tan <nsx at nsx.homeip.net>"
msgstr ""
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "Jack ÃıkıŠbaglantısı"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr ""
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "Jack giriÅine baglantı saglanamadı %s.."
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
-msgstr ""
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s Ayarlar"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA Makine Ayarlari"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
-msgstr ""
+msgstr "Modül Yolu:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
"After adding new paths, press Enter to scan for new plugins.</small>"
msgstr ""
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "Kullanılabilir Eklentiler:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "İzin ver"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "Eklentilere İzin ver:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "Ayarlar"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
msgstr ""
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr ""
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: LIRC desteÄi baÅlatılamıyor\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: LIRC config dosyası okunamıyor\n"
-"%s: Lütfen LIRC dökümanlarını okuyunuz\n"
-"%s: uygun bir config dosyası nasıl yaratılır\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr ""
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: bilinmeyen komut \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: LIRC baÄlantısını kes\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
msgstr ""
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2114,73 +2159,81 @@ msgid ""
"For more information about LIRC, see http://lirc.org."
msgstr ""
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr ""
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr ""
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr ""
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Hata"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Hata"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr ""
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr ""
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr ""
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr ""
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "Takt oluÅturucu: %d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "Takt oluÅturucu: %d bpm %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2189,162 +2242,194 @@ msgid ""
"or tact://60*3/4 to play 60 bpm in 3/4 tacts"
msgstr ""
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
msgstr ""
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
msgstr ""
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr ""
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "ÃıkıŠkanalları:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
+#: src/mms/mms.cc:35
+msgid "MMS Plugin"
msgstr ""
-#: src/mms/mms.c:195
-msgid "MMS Plugin"
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
msgstr ""
-#: src/modplug/plugin_main.c:55
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr ""
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr ""
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr ""
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "En Yakın (en hızlı)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "Lineer (hızlı)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr ""
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr ""
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr ""
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Seviye:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr ""
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr ""
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr ""
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr ""
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr ""
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr ""
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr ""
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr ""
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr ""
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr ""
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr ""
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
msgstr ""
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "Surround"
-
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr ""
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>GeliÅmiÅ</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "Surround"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr ""
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr ""
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "Durdu"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious oynatmıyor."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr ""
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2364,55 +2449,64 @@ msgid ""
"this program. If not, see <http://www.gnu.org/licenses/>."
msgstr ""
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr ""
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Her zaman bildirim göster"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "Göster"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "Duraklat"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "Sonraki Parça"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Varsayılan cihaz"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr ""
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "Ses aygıtı:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "Farklı aygıt kullan:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr ""
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr ""
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr ""
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2421,19 +2515,35 @@ msgid ""
"Lindgren and of course the authors of the previous OSS plugin."
msgstr ""
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "Ãalma Listesi Düzenleyici"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "Girdiler"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "_Sil"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
msgstr ""
-#: src/pls/pls.c:102
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr ""
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr ""
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr ""
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2453,144 +2563,213 @@ msgid ""
"USA."
msgstr ""
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "Ãnceki Parça"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "Tekrar et"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "KarıÅtır"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
msgstr ""
-#: src/resample/resample.c:165
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr ""
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "Lineer interpolasyon"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr ""
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr ""
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr ""
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>Ãeviri</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "Metot:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "Derece:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr ""
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr ""
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr ""
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr ""
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr ""
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr ""
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr ""
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr ""
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr ""
-#: src/resample/resample.c:204
-msgid "192 kHz:"
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
msgstr ""
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
+#: src/resample/resample.cc:241
+msgid "192 kHz:"
msgstr ""
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr ""
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr ""
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
msgstr ""
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "AÄ Sorunu."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
"Last.fm ile iletiÅimde bir sorun var. Lütfen daha sonra tekrar deneyin."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr ""
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr ""
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr ""
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
msgstr ""
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2601,765 +2780,840 @@ msgid ""
"\n"
msgstr ""
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr ""
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
msgstr ""
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr ""
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
msgstr ""
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr ""
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr ""
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr ""
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr ""
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
+msgid "%d result"
+msgid_plural "%d results"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
msgstr[1] ""
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr ""
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr ""
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr ""
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr ""
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr ""
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr ""
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr ""
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "Dosya Aç ..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "URL Aç ..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr ""
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "Ãal"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "Parça Listesi"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "Görünüm"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "Hizmetler"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "Hakkında ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "Ayarlar ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "ÃıkıÅ"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "Åarkı Bilgisi ..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "Tekrar et"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "KarıÅtır"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr ""
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "Åarkıdan Sonra Durdur"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "Ãnceki Parça"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr ""
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr ""
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr ""
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr ""
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "Ãalma Listesini Oynat"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr ""
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "Yeni Ãalma Listesi"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "Ãalma Listesini Yeniden Adlandır"
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "Ãalma Listesini Kaldır"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "Ãnceki Ãalma Listesi"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "Sonraki Ãalma Listesi"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "Ãalma Listesi İçe Aktar"
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "Ãalma Listesi DıÅa Aktar"
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "Ãalma Listesi Yöneticisi"
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "Kuyruk Yöneticisi"
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "Ãalma Listesini Yenile"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr ""
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr ""
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr ""
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Her Zaman Ãstte"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr ""
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr ""
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr ""
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr ""
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr ""
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr ""
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr ""
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr ""
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "Tümünü Sil"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr ""
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "Bulunamayan Dosyaları Sil"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "Birden Fazla Olanı Sil"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr ""
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "Seçilenleri Kaldır"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "Ara ve Seç"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr ""
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "Hiçbiri Seçilmedi"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "Tümünü_Seç"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
msgstr ""
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr ""
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr ""
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr ""
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr ""
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "Rastgele Listele"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr ""
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr ""
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "Kısa Liste"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "Kes"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "Kopyala"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "YapıÅtır"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr ""
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr ""
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr ""
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr ""
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr ""
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr ""
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr ""
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr ""
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr ""
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr ""
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr ""
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr ""
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr ""
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr ""
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "Kaydet"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "Yükle"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr ""
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr ""
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr ""
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr ""
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr ""
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr ""
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr ""
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr ""
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr ""
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr ""
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr ""
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr ""
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_Oynatıcı"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr ""
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "Arayüz yazı tipini seçiniz:"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
msgstr ""
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr ""
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr ""
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr ""
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr ""
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr ""
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr ""
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "Analiz Et"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr ""
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr ""
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Kapalı"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "Normal"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "AteÅ"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr ""
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "Ãizgiler"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "Ãubuk"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr ""
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "YavaÅ"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "Orta"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Hızlı"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr ""
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr ""
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr ""
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr ""
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr ""
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr ""
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr ""
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr ""
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr ""
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr ""
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr ""
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr ""
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr ""
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr ""
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr ""
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "Genel"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "GörselleÅtirme"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "Preamp"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr ""
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr ""
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr ""
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr ""
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr ""
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr ""
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious Ekolayzır"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "Zıpla %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "Ses: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr ""
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr ""
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr ""
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "Seçenekler Menüsü"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "Devre dıÅı bırak 'Her Zaman Görünür' "
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "EtkinleÅtir 'Her Zaman Görünür' "
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr ""
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr ""
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr ""
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr ""
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr ""
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Ãalma Listesi modu"
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "Åarkıdan sonra duruyor."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr ""
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3367,57 +3621,61 @@ msgid ""
"for."
msgstr ""
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "BaÅlık: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "Albüm: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "DosyaAdı:"
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "Ãnceki aramaları temizle"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr ""
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr ""
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr ""
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr ""
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr ""
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr ""
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr ""
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3439,77 +3697,71 @@ msgid ""
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
msgstr ""
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
msgstr ""
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
msgstr ""
-#: src/sndio/sndio.c:384
-msgid "sndio device"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "Tamam"
-
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "Åarkıyı deÄiÅtir"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "Audacious yeni bir Åarkı baÅlattıÄında çalıÅacak komut."
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>KabuÄa yollanan parametreler tırnak içinde belirtilmeli. "
+"Aksi takdirde güvenlik sorunu yaratır. </span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "Komut:"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "Bir Åarkının sonuna doÄru çalıÅacak komut."
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "Audacious parça listesinin sonuna ulaÅtıÄında çalıÅtırılacak komut."
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
msgstr ""
-"Bir Åarkı için baÅlık deÄiÅtiÄinde çalıÅtırılacak komut (örneÄin aÄ yayını "
-"baÅlıkları)."
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3524,19 +3776,15 @@ msgid ""
"%T: Track title"
msgstr ""
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>KabuÄa yollanan parametreler tırnak içinde belirtilmeli. "
-"Aksi takdirde güvenlik sorunu yaratır. </span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Komutlar"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr ""
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3545,51 +3793,51 @@ msgid ""
"Copyright 2010-2012 John Lindgren"
msgstr ""
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Hızlı"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "DüÅük"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "Yüksek"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "Daha Yüksek"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "Kalite:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "Hız:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr ""
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr ""
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "Durum iconu"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr ""
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3600,63 +3848,63 @@ msgid ""
"the system tray area of the window manager."
msgstr ""
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>Mouse kaydırma hareketi</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "Ses seviyesini deÄiÅtir"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "Ãalan Åarkıyı deÄiÅtir"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>DiÄer Ayarlar</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "Açılır pencereleri engelle"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "Sistem tepsisinden çıkar"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr ""
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "Durum iconu"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Stereo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
"By Johan Levin, 1999"
msgstr ""
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra Stereo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr ""
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "Ton OluÅturucu: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3665,15 +3913,11 @@ msgid ""
"e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone"
msgstr ""
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr ""
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "Ses yok etme"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3694,44 +3938,72 @@ msgid ""
"Eugene Zagidullin <e.asphyx at gmail.com>"
msgstr ""
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis Ãözücü"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTC Ãözücü"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
msgstr ""
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTC Ãözücü"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "Wav Ãözücü"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr ""
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr ""
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
"Some of the plugin code was by Miles Egan."
msgstr ""
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "Wav Ãözücü"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF Ãözücü"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "XML PaylaÅılabilir müzik listesi (XSPF)"
diff --git a/po/uk.po b/po/uk.po
index c9ce8cadf790..14fe61ad5a73 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -3,26 +3,27 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
+# Dennis <tymbood at gmail.com>, 2014-2015
# Kostyantyn Fedenko <fedenko at ukr.net>, 2011
# Kostyantyn Fedenko <fedenko at ukr.net>, 2011
-# StreamThreaedr <kvantarium at gmail.com>, 2012
+# Oleg <kvantarium at gmail.com>, 2012
# NaiLi (aka jamesjames) Rootaerc <theism at mail.ru>, 2012
# NaiLi (aka jamesjames) Rootaerc <theism at mail.ru>, 2012
# Rax Garfield <admin at dvizho.ks.ua>, 2012
# Rax Garfield (http://biokillaz.com/), 2012
# Rax Garfield (http://biokillaz.com)/, 2012
# Rax Garfield <admin at dvizho.ks.ua>, 2012
-# rustam <rustam.tsurik at gmail.com>, 2013
-# rustam <rustam.tsurik at gmail.com>, 2013
-# StreamThreaedr <kvantarium at gmail.com>, 2012
+# Rustam Tsurik <rustam.tsurik at gmail.com>, 2013
+# Rustam Tsurik <rustam.tsurik at gmail.com>, 2013
+# Oleg <kvantarium at gmail.com>, 2012
# Yuri Chornoivan <yurchor at ukr.net>, 2012
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-11 16:24+0000\n"
-"Last-Translator: Radioactiveman <thomas-lange2 at gmx.de>\n"
+"POT-Creation-Date: 2015-04-03 11:52+0200\n"
+"PO-Revision-Date: 2015-03-07 09:36+0000\n"
+"Last-Translator: Dennis <tymbood at gmail.com>\n"
"Language-Team: Ukrainian (http://www.transifex.com/projects/p/audacious/"
"language/uk/)\n"
"Language: uk\n"
@@ -32,40 +33,28 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "моно"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "ÑÑеÑео"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "об'Ñмний"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr ""
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
-msgstr ""
+msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ AAC (Raw)"
+
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (пÑогÑÐ°Ð²Ð°Ñ AdLib)"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "поÑлÑдовний"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (пÑогÑÐ°Ð²Ð°Ñ AdLib)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "ÐÑдилÑник"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
-msgstr ""
+msgstr "ÐÑÑановиÑи ÐÑдилÑник..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -75,11 +64,7 @@ msgstr ""
"\n"
"ÐвÑоÑи плаÒÑнÑ-оÑигÑналÑ: Adam Feakin, Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "ÐÑдилÑник"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -121,7 +106,7 @@ msgstr ""
"â\n"
"â\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -161,7 +146,7 @@ msgstr ""
"ÐапÑÑкаÑи ÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð¿Ñи ÑÑаÑÑÑ Ð±ÑдилÑника.\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -185,383 +170,371 @@ msgstr ""
"ÐведÑÑÑ Ð½Ð°Ð³Ð°Ð´ÑÐ²Ð°Ð½Ð½Ñ Ñ Ð¿Ð¾Ð»Ñ Ñа ÑвÑмкнÑÑÑâ\n"
"кнопкÑ-пÑапоÑеÑÑ, ÑкÑо ви Ñ
оÑеÑе, Ñоб його бÑло показано."
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "ÐÑÑавай, УкÑаÑно! ÐÑÑавай, ÑÑдна ненÑко! ÐоÑÐºÐ°Ð»Ñ Ð²Ð¶Ðµ Ð³Ð¾Ð´Ð¸Ð½Ñ Ð½Ðµ ÑпиÑÑ!"
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "ÐагадÑÐ²Ð°Ð½Ð½Ñ Ð½Ð° ÑÑогоднÑ..."
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "ÐовÑдомленнÑ"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "ÐонедÑлок"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "ÐÑвÑоÑок"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "СеÑеда"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "ЧеÑвеÑ"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "ÐâÑÑниÑÑ"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "СÑбоÑа"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "ÐедÑлÑ"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ Ð±ÑдилÑника"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr ""
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr ""
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "ЧаÑ"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "ÐоÑинаÑи о (Ñипово):"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
-msgstr " "
+msgstr " г"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "ÐакÑнÑиÑи ÑеÑез:"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "год"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "Ñ
в"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "ÐалаÑÑÑйÑе Ð´Ð½Ñ ÑижнÑ, в ÑÐºÑ Ð¿ÑаÑÑваÑиме бÑдилÑник."
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "ÐенÑ"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "Як Ñипово"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "ÐнÑ"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "ÐаÑоÑÑаннÑ"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "Ñек"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "ÐÑÑнÑÑÑÑ"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "Ðа поÑаÑкÑ:"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "Ðо закÑнÑеннÑ:"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "Як заÑаз"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "ÐиконÑваÑи командÑ"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "ÑвÑмкнÑÑи"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "СпиÑок вÑдÑвоÑÐµÐ½Ð½Ñ (необовâÑзково)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "ÐбÑаÑи ÑпиÑок вÑдÑвоÑеннÑ"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "ÐпÑÑÑ"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "Як Ñе вÑе налаÑÑÑваÑи?"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "Як налаÑÑÑваÑи?"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "Ðбкладинка алÑбомÑ"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr ""
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA-вивÑд"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ÐлаÒÑн Ð²Ð¸Ð²Ð¾Ð´Ñ ALSA,\n"
+"напиÑаний Ðжоном ÐÑндÒÑеном Ñ 2010â2012 ÑокаÑ
.\n"
+"\n"
+"ÐÑкÑÑ Ð°Ð²ÑоÑÐ¾Ð²Ñ ALSA Output Plugin NG (William Pitcock), Ñий код допомагав, "
+"коли докÑменÑаÑÑÑ Ð´Ð¾ ALSA бÑло недоÑÑаÑнÑо."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr ""
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "Типовий PCM-пÑилад"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "Типовий мÑкÑеÑ"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM-пÑиÑÑÑÑй:"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "ÐÑкÑеÑ:"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "ÐÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼ÑкÑеÑа:"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "Ðе завиÑаÑи ÑеÑез «drain»-Ð²Ð°Ð´Ñ ALSA"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI-пÑогÑаваÑ)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-msgstr ""
-"ÐлаÒÑн Ð²Ð¸Ð²Ð¾Ð´Ñ ALSA,\n"
-"напиÑаний Ðжоном ÐÑндÒÑеном Ñ 2010â2012 ÑокаÑ
.\n"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
"\n"
-"ÐÑкÑÑ Ð°Ð²ÑоÑÐ¾Ð²Ñ ALSA Output Plugin NG (William Pitcock), Ñий код допомагав, "
-"коли докÑменÑаÑÑÑ Ð´Ð¾ ALSA бÑло недоÑÑаÑнÑо."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA-вивÑд"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI-пÑогÑаваÑ)"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
+msgstr ""
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
-msgstr ""
+msgstr "ÐмÑниÑи Ñиповий пÑдÑилÑÐ²Ð°Ñ Ð½Ð°:"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
-msgstr ""
+msgstr "ÐмÑниÑи ÑÐ¸Ð¿Ð¾Ð²Ñ Ð¿Ð¾Ð»ÑÑонÑÑ Ð½Ð°:"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
-msgstr ""
+msgstr "ÐмÑниÑи ÑÐ¸Ð¿Ð¾Ð²Ñ ÑевеÑбеÑаÑÑÑ:"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
-msgstr ""
+msgstr "УвÑмк."
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
-msgstr ""
+msgstr "ÐмÑниÑи Ñиповий Ñ
оÑ:"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
-msgstr ""
+msgstr "<b>ÐÑдÑвоÑеннÑ</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
+msgstr "ТÑанÑпозиÑÑÑ: "
+
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
msgstr ""
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
-msgstr ""
+msgstr "ÐÑÑв ÑдаÑниÑ
: "
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
msgstr ""
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
msgstr ""
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
-msgstr ""
+msgstr "<b>ШÑиÑÑ</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
-msgstr ""
-
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr ""
+msgstr "<b>СинÑезаÑоÑ</b>"
+
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr ""
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "ÐÑ"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - вибÑÑ ÑÐ°Ð¹Ð»Ñ SoundFont"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "_СкаÑÑваÑи"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
-msgstr ""
+msgstr "_ÐÑдкÑиÑи"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
-msgstr "ÐмâÑ ÑайлÑ"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
+msgstr "Ðазва ÑайлÑ"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "РозмÑÑ (Ñ Ð±Ð°Ð¹ÑаÑ
)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "Ðазва:"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> ÐнÑоÑмаÑÑÑ MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "Ðазва:"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "ТÑивалÑÑÑÑ (мÑ):"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "ÐÑлÑкÑÑÑÑ Ð´Ð¾ÑÑжок:"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "змÑнна"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "Темп (BMP):"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg):"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "ЧаÑовий код MIDI:"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> ÐоменÑаÑÑ Ð¹ Ñлова пÑÑÐ½Ñ Ð² MIDI </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* Ñ ÑÑÐ¾Ð¼Ñ MIDI-ÑÐ°Ð¹Ð»Ñ Ð½ÐµÐ¼Ð°Ñ ÐºÐ¾Ð¼ÐµÐ½ÑаÑÑв *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* Ñ ÑÑÐ¾Ð¼Ñ MIDI-ÑÐ°Ð¹Ð»Ñ Ð½ÐµÐ¼Ð°Ñ ÑлÑв пÑÑÐ½Ñ *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "_ÐакÑиÑи"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (недÑйÑний UTF-8)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "ÐÑо плаÒÑн AMIDI"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "ÐлагÑн AMIDI"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"ÐÑогÑÐ°Ð²Ð°Ñ Ð¼Ñзики в ÑоÑмаÑÑ MIDI\n"
-"напиÑаний Ðжакомо ÐоÑÑÑо.\n"
-"\n"
-"<james at develia.org>\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"ÐÐ»ÐµÐ¼ÐµÐ½Ñ ÐадÑÑ Ñа ЯÑоÑлав ÐиÑела\n"
-"напиÑали клаÑÐ½Ñ Ð¿ÑогÑами «aplaymidi» Ñа «amixer»,\n"
-"Ñо виÑвилиÑÑ Ð½Ð°Ð´Ð·Ð²Ð¸Ñайно коÑиÑними\n"
-"пÑи вивÑÐµÐ½Ð½Ñ ALSA API,\n"
-"Ñк Ñ Ð´Ð¾ÐºÑменÑаÑÑÑ Ð´Ð¾ alsa-lib.\n"
-"\n"
-"ÐлÑÑÑедо СпадаÑÑна\n"
-"ÑÑвоÑив гаÑненÑкий логоÑип MIDI-клавÑаÑÑÑи.\n"
-"\n"
-"Ð¢Ð¾Ð½Ñ ÐÑÑн\n"
-"надав Ð²Ð°Ð³Ð¾Ð¼Ñ Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ñ Ð· алÑÑа-ÑеÑÑÑваннÑм."
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -571,152 +544,154 @@ msgid ""
"Based in part on Evan Martin's Ghosd library:\n"
"http://neugierig.org/software/ghosd/"
msgstr ""
+"Audacious OSD\n"
+"http://www.develia.org/projects.php?p=audacious#aosd\n"
+"\n"
+"ÐвÑÐ¾Ñ Giacomo Lozito <james at develia.org>\n"
+"\n"
+"ЧаÑÑково заÑнована на бÑблÑоÑеÑÑ Ghosd вÑд Evan Martin:\n"
+"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD-ÑповÑÑеннÑ"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ÐÑÑмокÑÑник"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "ÐаокÑÑглений пÑÑмокÑÑник"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "УвÑгнÑÑий пÑÑмокÑÑник"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "ТÑлÑки ÑекÑÑ"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "ÐÑдÑвоÑеннÑ"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "ÐоказÑÑ Ð¿Ð¾Ð²ÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð½Ð° поÑаÑÐºÑ Ð²ÑдÑвоÑеннÑ."
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "ÐмÑна назви"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
msgstr ""
-"ÐоказÑÑ Ð¿Ð¾Ð²ÑдомленнÑ, коли пÑд ÑÐ°Ñ Ð²ÑдÑвоÑÐµÐ½Ð½Ñ Ð·Ð¼ÑнÑÑÑÑÑÑ Ð½Ð°Ð·Ð²Ð° доÑÑжки, а "
-"ÑмâÑ ÑÐ°Ð¹Ð»Ñ Ð·Ð°Ð»Ð¸ÑаÑÑÑÑÑ ÑÑаÑим. Це коÑиÑно пÑи вÑдÑвоÑÐµÐ½Ð½Ñ Ð¿Ð¾ÑокÑв."
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "ÐаÑза"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "ÐоказÑÑ Ð¿Ð¾Ð²ÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñи пÑизÑÐ¿Ð¸Ð½ÐµÐ½Ð½Ñ Ð²ÑдÑвоÑеннÑ."
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "ÐÑодовженнÑ"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "ÐоказÑÑ Ð¿Ð¾Ð²ÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñи пÑÐ¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ Ð²ÑдÑвоÑеннÑ."
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "РозÑаÑÑваннÑ"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "ÐÑдноÑний гоÑизонÑалÑний зÑÑв:"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "ÐÑдноÑний веÑÑикалÑний зÑÑв:"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "ÐакÑималÑна ÑиÑина повÑдомленнÑ:"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "ÐпÑÑÑ Ð´Ð»Ñ ÐºÑлÑкоÑ
монÑÑоÑÑв"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "ÐоказÑваÑи на:"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "вÑÑÑ
монÑÑоÑаÑ
"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "монÑÑоÑÑ %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "ЧаÑова виÑÑимка (мÑ)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "Ðоказ:"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "ÐоÑва:"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "ÐникненнÑ:"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "ШÑиÑÑи"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "ШÑиÑÑ %i:"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "ТÑнÑ"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "ÐоказаÑи ÑÑилÑ"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "ÐолÑоÑи"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "ÐолÑÑ %i:"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "ÐадÑÑÑи ÑпÑÑковий гаÑок"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "ÐодÑÑ"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "ÐомпозиÑний "
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -726,112 +701,112 @@ msgstr ""
"ЯкÑо вÑн не запÑÑений, ÑвÑмкнÑÑÑ Ð¹Ð¾Ð³Ð¾, ÑнакÑе екÑанне Ð¼ÐµÐ½Ñ Ð¿ÑаÑÑваÑиме "
"непÑавилÑно."
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "ÐомпозиÑний Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑ Ð½Ðµ поÑÑÑбен Ð´Ð»Ñ ÑалÑÑÐ¸Ð²Ð¾Ñ Ð¿ÑозоÑоÑÑÑ"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "ÐÑозоÑÑÑÑÑ"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "ФалÑÑива пÑозоÑÑÑÑÑ"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "СпÑÐ°Ð²Ð¶Ð½Ñ Ð¿ÑозоÑÑÑÑÑ (поÑÑебÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð·Ð¸ÑÐ½Ñ ÑозÑиÑÐµÐ½Ð½Ñ X)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "ÐомпозиÑне ÑозÑиÑÐµÐ½Ð½Ñ Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ðµ"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "ÐомпозиÑне ÑозÑиÑÐµÐ½Ð½Ñ Ð½ÐµÐ´Ð¾ÑÑÑпне"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>OSD-повÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Audacious</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²ÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ñ Ð½Ð° екÑанÑ"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr ""
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "РозÑаÑÑваннÑ"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "ÐнÑмаÑÑÑ"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "ТекÑÑ"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "ÐздобленнÑ"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "СпÑÑковий гаÑок"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "Ð Ñзне"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "ТеÑÑ"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
-msgstr ""
+msgstr "ASXv3 ÐлейлÑÑÑи"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2-ÑпиÑки вÑдÑвоÑеннÑ"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "СпиÑки вÑдÑвоÑÐµÐ½Ð½Ñ Audacious (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>ÐолÑÑ</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "ÐÑÑилоÑкоп"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "ÐеÑеÑвоÑÐµÐ½Ð½Ñ ÑÑеÑеозвÑÐºÑ Ð² бÑнаÑÑалÑний за ÐаÑеÑом (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "ÐÑеÑеÑи:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "Ð ÑÐ²ÐµÐ½Ñ Ð·Ð¼ÑÑÑÐ²Ð°Ð½Ð½Ñ ÐºÐ°Ð½Ð°Ð»Ñв:"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr ""
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "ЧаÑÑоÑа зÑÑзÑ:"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "ÐÑеÑеÑи:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "ÐеÑеÑвоÑÐµÐ½Ð½Ñ ÑÑеÑеозвÑÐºÑ Ð² бÑнаÑÑалÑний за ÐаÑеÑом (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "СÑовпÑÑ (аналÑзаÑÐ¾Ñ ÑпекÑÑÑ)"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "ÐлаÒÑн аÑдÑодиÑкÑв"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -851,171 +826,156 @@ msgstr ""
"\n"
"Цей пÑÐ¾ÐµÐºÑ Ð±Ñав ÑÑаÑÑÑ Ñ Google Summer of Code 2007."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>ÐÑиÑÑÑÑй</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "ШвидкÑÑÑÑ ÑиÑаннÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "ÐеÑевизнаÑÐµÐ½Ð½Ñ Ð¿ÑиÑÑÑоÑв:"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>ÐеÑаданÑ</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "ÐикоÑиÑÑовÑваÑи CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "ÐикоÑиÑÑовÑваÑи CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "ÐикоÑиÑÑовÑваÑи HTTP замÑÑÑÑ CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "СеÑвеÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "ШлÑÑ
:"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "ÐоÑÑ:"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "ÐлаÒÑн аÑдÑодиÑкÑв"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "Ðе вдалоÑÑ Ð·Ð°Ð´ÑÑÑи пÑдÑиÑÑÐµÐ¼Ñ cdio."
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "Хибне поÑиланнÑ: %s."
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "ÐоÑÑжки %d не знайдено."
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "ÐоÑÑжка %d â не мÑзиÑÐ½Ñ Ð´Ð°Ð½Ñ."
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "Ðе вдалоÑÑ Ð²ÑдкÑиÑи аÑдÑовивÑд."
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "СÑавÑÑ Ð·Ð±Ñй пÑи ÑиÑÐ°Ð½Ð½Ñ Ð°ÑдÑодиÑкÑ."
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "ÐÑдÑодиÑк"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr ""
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "Ðе вдалоÑÑ Ð²ÑдкÑиÑи CD-пÑиÑÑÑÑй %s."
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "Ðе знайдено CD-пÑиÑÑÑÐ¾Ñ Ð· пÑдÑÑÐ¸Ð¼ÐºÐ¾Ñ Ð°ÑдÑо."
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "Ðе вдалоÑÑ Ð·Ð°Ð´ÑÑÑи вÑдкÑиÑий CD-пÑивÑд."
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "Ðе вдалоÑÑ Ð¾ÑÑимаÑи Ð½Ð¾Ð¼ÐµÑ Ð¿ÐµÑÑоÑ/оÑÑаннÑÐ¾Ñ Ð´Ð¾ÑÑжки."
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "Ðе вдалоÑÑ Ð¿ÑоÑиÑаÑи LSN поÑаÑкÑ/кÑнÑÑ Ð´Ð¾ÑÑжки %d."
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "Ðе вдалоÑÑ Ð·âÑднаÑиÑÑ Ð· cddb."
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸ÑаÑи ÑеÑÐ²ÐµÑ CDDB."
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸ÑаÑи ÑеÑÐ²ÐµÑ CDDB: %s."
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "Ðе вдалоÑÑ Ð¿ÑоÑиÑаÑи ÑнÑоÑмаÑÑÑ CDDB: %s."
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "ÐÑивÑд поÑожнÑй."
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "ÐепÑдÑÑимÑваний Ñип диÑкÑ."
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "ÐÑнкÑи Ð¼ÐµÐ½Ñ Ð´Ð»Ñ Ð°ÑдÑодиÑкÑв"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "ÐÑдÑвоÑиÑи диÑк"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "ÐодаÑи диÑк"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "ÐÑнкÑи Ð¼ÐµÐ½Ñ Ð´Ð»Ñ Ð°ÑдÑодиÑкÑв"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>СÑиÑненнÑ</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "ÐÑÑнÑÑÑÑ ÑенÑÑÑ:"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "ÐинамÑÑний дÑапазон:"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"ÐомпÑеÑÐ¾Ñ Ð·Ð²Ñкового дÑапазонÑ,\n"
-"напиÑаний Ðжоном ÐÑндÒÑеном Ñ 2010â2012 ÑокаÑ
."
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "ÐомпÑеÑÐ¾Ñ Ð·Ð²Ñкового дÑапазонÑ"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1031,204 +991,225 @@ msgstr ""
"ÐвÑоÑи â William Pitcock <nenolod at dereferenced.org>,\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ÐЧ:"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "ÐЧ:"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
-msgstr ""
+msgstr "ÐÑ
о:"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "Типова ÑÑивалÑÑÑÑ Ð¿ÑÑнÑ:"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>РеÑемплÑнг</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "ÐÑимÑÑова пеÑедиÑкÑеÑизаÑÑÑ"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "ЧаÑÑоÑа диÑкÑеÑизаÑÑÑ:"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "ÐÑ"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
-msgstr ""
+msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "ÐгноÑÑваÑи ÑÑивалÑÑÑÑ Ñз ÑеÒÑв SPC"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "ÐоÑилиÑи ÑевеÑбеÑаÑÑÑ"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ ÑгÑоконÑолÑÐ½Ð¾Ñ Ð¼Ñзики"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
msgstr ""
-"ÐбÑй пÑи пеÑеÑ
ÑеÑÐ½Ð¾Ð¼Ñ Ð·Ð°ÑиÑ
аннÑ: композиÑÑÑ Ð¼Ð°ÑÑÑ ÑÑÐ·Ð½Ñ ÐºÑлÑкÑÑÑÑ ÐºÐ°Ð½Ð°Ð»Ñв.\n"
-"ÐипÑавÑе Ñе плаÒÑном-мÑкÑеÑом каналÑв."
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
msgstr ""
-"ÐбÑй пÑи пеÑеÑ
ÑеÑÐ½Ð¾Ð¼Ñ Ð·Ð°ÑиÑ
аннÑ: композиÑÑÑ Ð¼Ð°ÑÑÑ ÑÑÐ·Ð½Ñ ÑаÑÑоÑÑ "
-"диÑкÑеÑизаÑÑÑ.\n"
-"ÐипÑавÑе Ñе плаÒÑном-конвеÑÑоÑом ÑаÑÑоÑи диÑкÑеÑизаÑÑÑ."
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"ÐеÑеÑ
ÑеÑне заÑиÑ
аннÑ,\n"
-"напиÑаний Ðжоном ÐÑндÒÑеном Ñ 2010â2012 ÑокаÑ
."
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>ÐеÑеÑ
ÑеÑне заÑиÑ
аннÑ</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "ÐеÑекÑиÑÑÑ:"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr ""
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr ""
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "ÐеÑеÑ
ÑеÑне заÑиÑ
аннÑ"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"ÐбÑй пÑи пеÑеÑ
ÑеÑÐ½Ð¾Ð¼Ñ Ð·Ð°ÑиÑ
аннÑ: композиÑÑÑ Ð¼Ð°ÑÑÑ ÑÑÐ·Ð½Ñ ÐºÑлÑкÑÑÑÑ ÐºÐ°Ð½Ð°Ð»Ñв.\n"
+"ÐипÑавÑе Ñе плаÒÑном-мÑкÑеÑом каналÑв."
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"ÐбÑй пÑи пеÑеÑ
ÑеÑÐ½Ð¾Ð¼Ñ Ð·Ð°ÑиÑ
аннÑ: композиÑÑÑ Ð¼Ð°ÑÑÑ ÑÑÐ·Ð½Ñ ÑаÑÑоÑÑ "
+"диÑкÑеÑизаÑÑÑ.\n"
+"ÐипÑавÑе Ñе плаÒÑном-конвеÑÑоÑом ÑаÑÑоÑи диÑкÑеÑизаÑÑÑ."
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>ÐÑиÑÑалÑзаÑоÑ</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "ÐнÑенÑивнÑÑÑÑ:"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "ÐÑиÑÑалÑзаÑоÑ"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "ÐлаÒÑн cue-лиÑÑÑв"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "ÐÐ¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÑайлÑв"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
-msgstr ""
+msgstr "Ðомилка пÑи пеÑемÑÑÐµÐ½Ð½Ñ %s в ÑмÑÑник: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
-msgstr ""
+msgstr "Ðомилка пÑи Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ %s: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
-msgstr ""
+msgstr "Ðомилка пÑи Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ %s: Ñе не локалÑний Ñайл."
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
-msgstr ""
+msgstr "Ðи Ñ
оÑеÑе пеÑемÑÑÑиÑи вибÑÐ°Ð½Ñ Ñайли до ÑмÑÑника?"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
-msgstr ""
+msgstr "ÐеÑемÑÑÑиÑи до ÑмÑÑника"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
-msgstr ""
+msgstr "Ðи Ñ
оÑеÑе безповоÑоÑно видалиÑи вибÑÐ°Ð½Ñ Ñайли?"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "ÐилÑÑиÑи"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "СкаÑÑваÑи"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr ""
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
-msgstr ""
+msgstr "ÐидалиÑи вибÑÐ°Ð½Ñ Ñайли"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
-msgstr ""
+msgstr "<b>ÐеÑод ÐидаленнÑ</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
+msgstr "ÐеÑемÑÑÑиÑи до ÑмÑÑника замÑÑÑÑ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð²ÑдÑазÑ"
+
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
msgstr ""
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>ÐÑдлÑннÑ</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "ÐаÑÑимка:"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "мÑ"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "Сила:"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "ÐÑÑнÑÑÑÑ:"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"ÐÑна,\n"
-"плаÒÑн напиÑаний Ñ 1999 ÑоÑÑ (авÑÐ¾Ñ â Johan Levin)."
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "ÐÑдлÑннÑ"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "ÐлаÒÑн FFmpeg"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1246,55 +1227,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "ÐлаÒÑн FFmpeg"
-
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "ÐлаÒÑн запиÑÑ Ñ Ñайл"
+
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "Тип ÑÐ°Ð¹Ð»Ñ Ð²Ð¸Ð²Ð¾Ð´Ñ:"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "ÐалаÑÑÑваннÑ..."
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "ÐбеÑÑгаÑи в ÑÐµÐºÑ Ð¾ÑигÑналÑ"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "ÐбÑаÑи ÑÐµÐºÑ ÑамоÑÑÑйно"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "ÐбеÑÑгаÑи вивÑд до:"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "ÐибÑÑ Ñеки виводÑ"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "Ðазва Ñайла:"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr ""
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "за Ñегами доÑÑжки"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr ""
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "за Ð½Ð°Ð·Ð²Ð¾Ñ ÑÐ°Ð¹Ð»Ñ Ð¾ÑигÑналÑ"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr ""
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "Ðе виÑÑзаÑи ÑозÑиÑÐµÐ½Ð½Ñ Ð¾ÑигÑналÑ"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr ""
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "ÐÐ¾Ð¼ÐµÑ Ð´Ð¾ÑÑжки на поÑаÑÐºÑ Ð½Ð°Ð·Ð²Ð¸ ÑайлÑ"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr ""
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1328,166 +1309,169 @@ msgstr ""
"Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA "
"02110-1301, USA"
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "ÐлаÒÑн запиÑÑ Ñ Ñайл"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "ÐвÑо"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "ÐбâÑднане ÑÑеÑео"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "СÑеÑео"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "Ðоно"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ MP3"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "_ÐаÑазд"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "ШвидкÑÑÑÑ ÑÑиÑненнÑ:"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
-msgstr "ЧаÑÑоÑа диÑкÑеÑизаÑÑÑ Ð²Ð¸Ð²Ð¾Ð´Ñ:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
+msgstr ""
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
-msgstr "ÐÑ"
+msgstr "(ÐÑ)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "Сила ÑÑиÑканнÑ"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr ""
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ÐÑÑÑÐµÐ¹Ñ (ÐбÑÑ/Ñ)"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "ÐоеÑÑÑÑÑÐ½Ñ ÑÑиÑненнÑ:"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "Тип звÑкÑ:"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "Ð Ñзне:"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr ""
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
msgstr ""
-"ÐÑимÑÑова вÑдповÑднÑÑÑÑ Ð´Ð¾ ISO (Ð´Ð»Ñ Ð°Ð¿Ð°ÑаÑниÑ
пÑогÑаваÑÑв, бÑлÑÑий ÑозмÑÑ)"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "CRC-заÑ
иÑÑ Ð²Ñд збоÑв (деÑо менÑа ÑкÑÑÑÑ)"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "ЯкÑÑÑÑ"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "УвÑмкнÑÑи змÑнний Ñи ÑÑеÑеднений бÑÑÑейÑ"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "Тип бÑÑÑейÑÑ:"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "ÐпÑÑÑ VBR (змÑнний бÑÑÑейÑ):"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "ÐÑнÑмалÑний бÑÑÑÐµÐ¹Ñ (ÐбÑÑ/c):"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "ÐакÑималÑний бÑÑÑÐµÐ¹Ñ (ÐбÑÑ/c):"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "ÐÑимÑÑово вÑÑановиÑи мÑнÑмалÑний бÑÑÑейÑ"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ÐпÑÑÑ ABR (ÑÑеÑеднений бÑÑÑейÑ):"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "СеÑеднÑй бÑÑÑÐµÐ¹Ñ (ÐбÑÑ/Ñ):"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "Ð ÑÐ²ÐµÐ½Ñ ÑкоÑÑÑ VBR (менÑе - кÑаÑе):"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "Ðе пиÑаÑи VBR-заголовок («Xing»)"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr ""
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
-msgstr "ÐопÑÑаÑÑÑÑ:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "«ÐÑд авÑоÑÑÑкими пÑавами»"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "«РоÑигÑналом»"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
-msgstr "ÐаÑамеÑÑи ID3:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
+msgstr ""
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "ÐÑимÑÑово додаваÑи ÑÐµÒ Ð´ÑÑÐ³Ð¾Ñ Ð²ÐµÑÑÑÑ"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "ÐодаваÑи лиÑе v1-ÑеÒ"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "ÐодаваÑи лиÑе v2-ÑеÒ"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "ТеÒи"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð´ÑвалÑника Vorbis"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "Ð ÑÐ²ÐµÐ½Ñ ÑкоÑÑÑ (0-10, менÑе - кÑаÑе):"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ FLAC"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "без вÑÑаÑ"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1499,11 +1483,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ FLAC"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1511,11 +1491,19 @@ msgstr ""
"ÐлаÒÑн GIO,\n"
"напиÑаний Ðжоном ÐÑндÒÑеном Ñ 2010â2012 ÑокаÑ
."
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "ÐлаÒÑн GIO"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr ""
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr ""
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1526,450 +1514,518 @@ msgid ""
"\n"
"License: GPLv2+"
msgstr ""
+"OpenGL ÐналÑзаÑÐ¾Ñ Ð¡Ð¿ÐµÐºÑÑÑ Ð´Ð»Ñ Audacious\n"
+"ÐвÑоÑÑÑке пÑаво 2013 Christophe Budé, John Lindgren, Ñа Carlo Bramini\n"
+"\n"
+"Ðа оÑÐ½Ð¾Ð²Ñ Ð¿Ð»Ð°ÒÑÐ½Ñ Ð´Ð»Ñ XMMS:\n"
+"ÐвÑоÑÑÑке пÑаво 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas "
+"Nilsson, Ñа 4Front Technologies\n"
+"\n"
+"ÐÑÑензÑÑ: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL аналÑзаÑÐ¾Ñ ÑпекÑÑÑ"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr ""
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
msgstr ""
-"ÐлаÒÑн Ð½Ð°Ð´Ð°Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²ÑÑÑÑ ÐºÐµÑÑваÑи вÑдÑвоÑеннÑм\n"
-"за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ ÐºÐ»Ð°Ð²ÑаÑÑÑниÑ
ÑкоÑоÑÐµÐ½Ñ GNOME.\n"
-"ÐвÑÐ¾Ñ Ñ 2007â2008 ÑокаÑ
â Sascha Hlusiak <contact at saschahlusiak.de>."
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "ЯÑлики Gnome"
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "ÐÐ¾Ð¼ÐµÑ Ñ ÑпиÑкÑ"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "Ðазва"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "ÐиконавеÑÑ"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "Ð Ñк"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "ÐлÑбом"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "ÐиконавеÑÑ Ð°Ð»ÑбомÑ"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "ÐоÑÑжка"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "ÐанÑ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "ÐозиÑÑÑ Ñ ÑеÑзÑ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "ТÑивалÑÑÑÑ"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "ШлÑÑ
до ÑайлÑ"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "Ðазва ÑайлÑ"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "Ðазва ÑайлÑ"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ÐÑÑова ÑвидкÑÑÑÑ"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
-msgstr ""
+msgstr "ÐоÑÑÑÐ¿Ð½Ñ ÐºÐ¾Ð»Ð¾Ð½ÐºÐ¸"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
-msgstr ""
+msgstr "ÐÑдобÑÐ°Ð¶ÐµÐ½Ñ ÐºÐ¾Ð»Ð¾Ð½ÐºÐ¸"
+
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "ÐоÑÑковий ÑнÑÑÑÑменÑ"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "ÐÑикÑÑпиÑи злÑва"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "ÐÑикÑÑпиÑи ÑпÑава"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "ÐÑикÑÑпиÑи вгоÑÑ"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "ÐÑикÑÑпиÑи внизÑ"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "ÐÑдкÑÑпиÑи"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "ÐимкнÑÑи"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "ÐоÑÑковий ÑнÑÑÑÑменÑ"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "ÐÑдÑвоÑиÑи _ÑаиÌли..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "ÐÑдÑвоÑиÑи Ñайли за _поÑиланнÑм..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "_ÐодаÑи ÑаиÌли..."
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "ÐодаÑи Ñайли _за поÑиланнÑм..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
-msgstr ""
+msgstr "ШÑкаÑи в _бÑблÑоÑеÑÑ"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "Ð_Ñо Audacious..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
-msgstr ""
+msgstr "_ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ ..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "_ÐиÑ
Ñд"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "_ÐÑдÑвоÑиÑи"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "_ÐÑизÑпиниÑи"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "_ÐÑпиниÑи"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "Ð_опеÑеднÑ"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "_ÐаÑÑÑпна"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "ÐовÑо_ÑÑваÑи"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "Ð_ипадково"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "Ð_е пÑоÑÑваÑиÑÑ ÑпиÑком"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "ÐÑпиниÑи пÑÑÐ»Ñ _ÑÑÑÑ Ð¿ÑÑнÑ"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "_ÐнÑоÑмаÑÑÑ Ð¿Ñо доÑÑжкÑ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "ÐеÑеиÌÑи до _ÑаÑÑ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "ÐеÑеиÌÑи до _доÑÑжки..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "ÐÑÑановиÑи ÑоÑÐºÑ Ð¿Ð¾Ð²ÑоÑÑ _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "ÐÑÑановиÑи ÑоÑÐºÑ Ð¿Ð¾Ð²ÑоÑÑ _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "_СкинÑÑи ÑоÑки повÑоÑÑ"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "Ðа _назвоÑ"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "Ðа _Ð½Ð°Ð·Ð²Ð¾Ñ ÑайлÑ"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr ""
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "Ðа _ÑлÑÑ
ом до ÑайлÑ"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "_Ðа номеÑом доÑÑжки"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "Ðа _виконавÑем"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "Ðа а_лÑбомом"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr ""
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "Ðа _даÑÐ¾Ñ Ð²Ð¸Ð´Ð°Ð½Ð½Ñ"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr ""
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "Ðа _ÑÑивалÑÑÑÑ"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "Ðа _ÑлÑÑ
ом до ÑайлÑ"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "Ðа Ð½Ð°Ð·Ð²Ð¾Ñ _ÑайлÑ"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "_У звоÑоÑнÑÐ¾Ð¼Ñ Ð¿Ð¾ÑÑдкÑ"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "У Ð²Ð¸Ð¿Ð°Ð´ÐºÐ¾Ð²Ð¾Ð¼Ñ Ð¿Ð¾_ÑÑдкÑ"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "ÐÑдÑвоÑиÑи _Ñей ÑпиÑок"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "_ÐÑдÑвоÑиÑи/пÑодовжиÑи"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "_ÐновиÑи"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "_СоÑÑÑваÑи"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
-msgstr ""
+msgstr "СоÑÑÑваÑи ви_бÑане"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "ÐидалиÑи _дÑблÑкаÑи"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "ÐÑибÑаÑи _недоÑÑÑÐ¿Ð½Ñ Ñайли"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "_Ðовий"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "ÐеÑе_йменÑваÑи..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
-msgstr ""
+msgstr "Ðидали_Ñи"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "_ÐмпоÑÑÑваÑи..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "_ÐкÑпоÑÑÑваÑи..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "ÐеÑÑÐ²Ð°Ð½Ð½Ñ ÑпиÑками _вÑдÑвоÑеннÑ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "ÐеÑÑÐ²Ð°Ð½Ð½Ñ _ÑеÑгоÑ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "Ð_бÑлÑÑиÑи гÑÑнÑÑÑÑ"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "Ð_менÑиÑи гÑÑнÑÑÑÑ"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "_ÐквалайзеÑ"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
-msgstr ""
+msgstr "Ð_ÑекÑи..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "ÐоказÑваÑи Ð¿Ð°Ð½ÐµÐ»Ñ _менÑ"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "ÐоказÑваÑи Ð¿Ð°Ð½ÐµÐ»Ñ Ñ_нÑоÑмаÑÑÑ"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "Ð_оказÑваÑи вÑзÑалÑзаÑÑÑ"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "ÐоказÑваÑи ÑÑдок _ÑÑанÑ"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "ÐоказаÑи ÑÐ°Ñ Ð´Ð¾ _завеÑÑеннÑ"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
-msgstr ""
+msgstr "_ÐÑзÑалÑзаÑÑÑ ..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "_Файл"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "_ÐÑдÑвоÑеннÑ"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "_СпиÑок вÑдÑвоÑеннÑ"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "С_лÑжби"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "Ð_ивÑд"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "Ðи_глÑд"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "_ÐÐ»ÐµÐ¼ÐµÐ½Ñ ÑеÑги"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr ""
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "_ÐиÑÑзаÑи"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "_ÐопÑÑваÑи"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "ÐÑÑ_авиÑи"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "ÐидÑ_лиÑи вÑе"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "ÐеÑе_йменÑваÑи..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
-msgstr ""
+msgstr "<b>Ðкладки плейлиÑÑÑ</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
-msgstr ""
+msgstr "Ðавжди показÑваÑи вкладки"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
-msgstr ""
+msgstr "ÐоказÑваÑи лÑÑилÑник ÑайлÑв"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
-msgstr ""
+msgstr "ÐоказÑваÑи ÐºÐ½Ð¾Ð¿ÐºÑ Ð·Ð°ÐºÑиÑÑÑ"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
-msgstr ""
+msgstr "<b>Ðолонки плейлиÑÑÑ</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
-msgstr ""
+msgstr "ÐоказÑваÑи заголовки колонок"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>Ð Ñзне</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
-msgstr ""
+msgstr "ÐÑок пеÑемоÑÑÐ²Ð°Ð½Ð½Ñ ÑÑÑÑлками:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
-msgstr ""
+msgstr "ÐÑокÑÑÑÑваÑи плейлиÑÑ Ð¿Ñи змÑÐ½Ñ Ð´Ð¾ÑÑжки"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "ÐнÑеÑÑÐµÐ¹Ñ GTK"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ÐÑÑеÑÑÑ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "моно"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "ÑÑеÑео"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
@@ -1977,84 +2033,98 @@ msgstr[0] "%d канал"
msgstr[1] "%d канали"
msgstr[2] "%d каналÑв"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d кб/Ñ"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "ÐднодоÑÑжковий Ñежим."
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "Режим ÑпиÑка вÑдÑвоÑеннÑ."
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "ÐÑпиниÑи пÑÑÐ»Ñ ÑÑÑÑ Ð´Ð¾ÑÑжки."
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "ÐопеÑÐµÐ´Ð½Ñ Ð´Ð¾ÑÑжка"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "ÐÑдÑвоÑиÑи"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "ÐÑизÑпиниÑи/пÑодовжиÑи"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "ÐÑпиниÑи"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "ÐаÑÑÑпна доÑÑжка"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "Ðа 5 ÑекÑнд впеÑед"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "Ðа 5 ÑекÑнд назад"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "ÐимкнÑÑи звÑк"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "ÐбÑлÑÑиÑи гÑÑнÑÑÑÑ"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "ÐменÑиÑи гÑÑнÑÑÑÑ"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "ÐеÑейÑи до ÑайлÑ"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "ÐеÑемкнÑÑи ÑÑан вÑкон пÑогÑаваÑа"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "ÐоказаÑи OSD-повÑдомленнÑ"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "ÐеÑемкнÑÑи повÑоÑ"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "ÐеÑемкнÑÑи ÑаÑÑваннÑ"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "ÐеÑемкнÑÑи зÑÐ¿Ð¸Ð½ÐºÑ Ð¿ÑÑÐ»Ñ Ð¿Ð¾ÑоÑноÑ"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "ÐÑднÑÑи вÑкна пÑогÑаваÑа"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(немаÑ)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2065,15 +2135,11 @@ msgstr ""
"\n"
"ÐÑодовжÑваÑи попÑи Ñе?"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "ÐовâÑзÑÐ²Ð°Ð½Ð½Ñ ÐºÐ½Ð¾Ð¿Ð¾Ðº миÑÑ"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ Ð³Ð°ÑÑÑиÑ
клавÑÑ"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2082,23 +2148,27 @@ msgstr ""
"полÑ.\n"
"Ðожна Ñакож пÑивâÑзÑваÑи кнопки миÑÑ."
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "ÐаÑÑÑÑ ÐºÐ»Ð°Ð²ÑÑÑ:"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>ÐÑÑ:</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>ÐÑивâÑзка до клавÑÑ:</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
-msgstr ""
+msgstr "_ÐодаÑи"
+
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "ÐаÑÑÑÑ ÐºÐ»Ð°Ð²ÑÑÑ"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2125,60 +2195,51 @@ msgstr ""
"Jeremy Tan <nsx at nsx.homeip.net>\n"
"Ñакож бÑали ÑÑаÑÑÑ Ñ ÑозÑобÑÑ."
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "ÐаÑÑÑÑ ÐºÐ»Ð°Ð²ÑÑÑ"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK-вивÑд"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
msgstr ""
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
msgstr ""
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
msgstr ""
-#: src/jack/jack.c:202
-msgid "Connection mode:"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
msgstr ""
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
msgstr ""
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Ðа оÑÐ½Ð¾Ð²Ñ xmms-jack вÑд Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"ÐвÑÐ¾Ñ Ð¿Ð¾ÑÑÑÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ Audacious â Giacomo Lozito."
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK-вивÑд"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ %s"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ Ñ
оÑÑÑ LADSPA"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "ШлÑÑ
и до модÑлÑв:"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2188,25 +2249,25 @@ msgstr ""
"ÐоÑÑк вÑдбÑваÑÑÑÑÑ Ð·Ð° вказаними ÑлÑÑ
ами Ñа змÑÐ½Ð½Ð¾Ñ LADSPA_PATH.\n"
"ÐказавÑи ÑлÑÑ
и, наÑиÑнÑÑÑ Enter Ð´Ð»Ñ Ð¿Ð¾ÑÑÐºÑ Ð¿Ð»Ð°ÒÑнÑв.</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "ÐаÑÐ²Ð½Ñ Ð¿Ð»Ð°ÒÑни:"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "УвÑмкнÑÑи"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "УвÑÐ¼ÐºÐ½ÐµÐ½Ñ Ð¿Ð»Ð°ÒÑни:"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "ÐалаÑÑÑваннÑ"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2214,47 +2275,15 @@ msgstr ""
"ХоÑÑ LADSPA,\n"
"напиÑаний Ðжоном ÐÑндÒÑеном Ñ 2011 ÑоÑÑ."
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "ХоÑÑ LADSPA"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: не Ð¼Ð¾Ð¶Ñ ÑнÑÑÑалÑзÑваÑи пÑдÑÑÐ¸Ð¼ÐºÑ LIRC\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: не Ð¼Ð¾Ð¶Ñ Ð¿ÑоÑиÑаÑи конÑÑгÑÑаÑÑйний Ñайл LIRC\n"
-"%s: пÑоÑиÑайÑе докÑменÑаÑÑÑ Ð´Ð¾ LIRC\n"
-"%s: Ñк ÑÑвоÑиÑи пÑавилÑний конÑигÑÑаÑÑйний Ñайл\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: намагаÑÑÑ Ð¿ÐµÑезâÑднаÑиÑÑ...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: невÑдома команда «%s»\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: зâÑÐ´Ð½Ð°Ð½Ð½Ñ Ð· LIRC ÑозÑÑвано\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: намагаÑÑÑ Ð¿ÐµÑезâÑднаÑиÑÑ ÐºÐ¾Ð¶Ð½Ñ %d ÑекÑнд...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "ÐлаÒÑн LIRC"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2283,73 +2312,81 @@ msgstr ""
"\n"
"http://lirc.org/"
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>ÐâеднаннÑ</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "ÐеÑепÑиÑднаÑиÑÑ Ð´Ð¾ LIRC ÑеÑвеÑÑ"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "ЧекаÑи пеÑед пеÑезâÑднаннÑм:"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "ÐлаÒÑн LIRC"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "ÐлаÒÑн LyricWiki"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "ТекÑÑÑ Ð¿ÑÑÐ½Ñ Ð½Ðµ знайдено"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "Ðомилка"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "Ðе вдалоÑÑ Ð¾ÑÑимаÑи %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "Ðомилка"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "Ðе вдалоÑÑ Ð¿ÑоаналÑзÑваÑи %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "ШÑÐºÐ°Ñ ÑекÑÑ Ð¿ÑÑнÑ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "ÐÑдÑÑÑÐ½Ñ Ð¼ÐµÑÐ°Ð´Ð°Ð½Ñ Ð¿ÑÑнÑ"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "ÐâÑднÑÑÑÑ Ð· lyrics.wikia.com..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "ÐлаÒÑн LyricWiki"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr ""
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U-ÑпиÑки вÑдÑвоÑеннÑ"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑÑ"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑÑ: %d BPM"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑÑ: %d BPM, %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2366,11 +2403,11 @@ msgstr ""
"ÐапÑиклад, tact://77 â 77 ÑдаÑÑв за Ñ
вилинÑ,\n"
"tact://60*3/4 â 60 ÑдаÑÑв за Ñ
Ð²Ð¸Ð»Ð¸Ð½Ñ Ð· ÑакÑом 3/4."
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "ÐенеÑаÑÐ¾Ñ ÑакÑÑ"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "ÐÑкÑÐµÑ ÐºÐ°Ð½Ð°Ð»Ñв"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2378,152 +2415,184 @@ msgstr ""
"ÐÑкÑÐµÑ ÐºÐ°Ð½Ð°Ð»Ñв,\n"
"напиÑаний Ñ 2011â2012 ÑокаÑ
Ðжоном ÐÑндÒÑеном Ñа MichaÅ Lipski."
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>ÐÑкÑÐµÑ ÐºÐ°Ð½Ð°Ð»Ñв</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "ÐаналÑв на виÑ
одÑ:"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "ÐÑкÑÐµÑ ÐºÐ°Ð½Ð°Ð»Ñв"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "ÐлаÒÑн MMS"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr ""
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (пÑогÑÐ°Ð²Ð°Ñ Ð¼Ð¾Ð´ÑлÑв)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>РоздÑлÑна здаÑнÑÑÑÑ</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-бÑÑ"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-бÑÑ"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>Ðанали</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "ÐайближÑий (найÑвидÑий)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "ÐÑнÑйний (Ñвидкий)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "Сплайн (ÑкÑÑний)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "ÐолÑÑазний (найкÑаÑий)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
-msgstr "<b>ЧаÑÑоÑа диÑкÑеÑизаÑÑÑ</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
+msgstr ""
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 кÐÑ"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 кÐÑ"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 кÐÑ"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 кÐÑ"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "Ð ÑвенÑ:"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "ÐÑаниÑÑ:"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>РевеÑбеÑаÑÑÑ</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>ÐодаÑковий баÑ</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>ÐбâÑмне звÑÑаннÑ</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>ÐопеÑÐµÐ´Ð½Ñ Ð¿ÑдÑиленнÑ</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "ÐеÑедиÑкÑеÑизаÑÑÑ"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "ÐменÑÐµÐ½Ð½Ñ ÑÑмÑ"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "ÐÑаÑи Amiga MOD-Ñайли"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>ÐовÑоÑеннÑ</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "ÐÑлÑкÑÑÑÑ Ð¿Ð¾Ð²ÑоÑенÑ:"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "ÐÐ»Ñ Ð±ÐµÐ·ÐºÑнеÑного повÑоÑеннÑ, вÑÑановÑÑÑ ÐºÑлÑкÑÑÑÑ Ð¿Ð¾Ð²ÑоÑÐµÐ½Ñ Ð² -1."
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (пÑогÑÐ°Ð²Ð°Ñ Ð¼Ð¾Ð´ÑлÑв)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "ÐбâÑмний звÑк"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr ""
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "ÐлаÒÑн MPG123"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>ÐодаÑковÑ</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr ""
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "ÐбâÑмний звÑк"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "СеÑÐ²ÐµÑ MPRIS 2"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "ÐлаÒÑн Neon HTTP/HTTPS"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr ""
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr ""
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr ""
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr ""
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "ÐÑпинено"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious нÑÑого не вÑдÑвоÑÑÑ."
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "СповÑÑеннÑ"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2560,55 +2629,64 @@ msgstr ""
"Ðи мали оÑÑимаÑи копÑÑ ÐагалÑÐ½Ð¾Ñ Ð¿ÑблÑÑÐ½Ð¾Ñ Ð»ÑÑензÑÑ GNU Ñазом Ñз ÑÑÑÑ "
"пÑогÑамоÑ. Ð ÑнÑÐ¾Ð¼Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑ, дивÑÑÑÑÑ <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "ÐоказаÑи елеменÑи кеÑÑÐ²Ð°Ð½Ð½Ñ Ð²ÑдÑвоÑеннÑм"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "Ðавжди показÑваÑи повÑдомленнÑ"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "СповÑÑеннÑ"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr ""
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "ÐоказаÑи"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "ÐÑизÑпиниÑи вÑдÑвоÑеннÑ"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "ÐаÑÑÑпна доÑÑжка"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. Типовий пÑилад"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4-вивÑд"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr ""
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr ""
+
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "ÐÑдÑопÑилад:"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "ÐикоÑиÑÑаÑи ÑнÑий пÑилад:"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "ÐбеÑÑгаÑи гÑÑнÑÑÑÑ Ð¼Ñж ÑеанÑами."
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "ÐадÑÑÑи змÑни ÑоÑмаÑÑ, здÑйÑÐ½ÐµÐ½Ñ Ð¿ÑогÑамами OSS."
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "ÐÑÑÑи в екÑклÑÐ·Ð¸Ð²Ð½Ð¾Ð¼Ñ ÑежимÑ, ÑникаÑÑи вÑÑÑÑалÑного мÑкÑÑваннÑ."
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2623,19 +2701,35 @@ msgstr ""
"ÐÑкÑÑмо #audacious, оÑобливо Ð¢Ð¾Ð½Ñ ÐÑÑновÑ, ÐÐ¶Ð¾Ð½Ð¾Ð²Ñ ÐÑндÒÑÐµÐ½Ñ Ð¹, звÑÑно, "
"авÑоÑам попеÑеднÑого плаÒÑÐ½Ñ OSS."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4-вивÑд"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr ""
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr ""
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr ""
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS-ÑпиÑки вÑдÑвоÑеннÑ"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ OpenPSF PSF1/PSF2"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio-вивÑд"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2673,11 +2767,68 @@ msgstr ""
"Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA "
"02110-1301, USA"
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio-вивÑд"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr ""
-#: src/resample/resample.c:165
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr ""
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "ÐоÑÑк"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr ""
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr ""
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr ""
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ÐопеÑÐµÐ´Ð½Ñ Ð´Ð¾ÑÑжка"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "ÐовÑоÑÑваÑи"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "Ðипадково"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr ""
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "ÐонвеÑÑÐ¾Ñ ÑаÑÑоÑи диÑкÑеÑизаÑÑÑ"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2685,99 +2836,107 @@ msgstr ""
"ÐонвеÑÑÐ¾Ñ ÑаÑÑоÑи диÑкÑеÑизаÑÑÑ,\n"
"напиÑаний Ðжоном ÐÑндÒÑеном Ñ 2010â2012 ÑокаÑ
."
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "ÐÑопÑÑк/повÑÐ¾Ñ ÑÑагменÑÑв"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "ÐÑнÑйна ÑнÑеÑполÑÑÑÑ"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "Швидка sinc-ÑнÑеÑполÑÑÑÑ"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "ÐвиÑайна sinc-ÑнÑеÑполÑÑÑÑ"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "ÐайкÑаÑа sinc-ÑнÑеÑполÑÑÑÑ"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>ÐонвеÑÑÑваннÑ</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "ÐеÑод:"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "ЧаÑÑоÑа:"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>СÑ
ема конвеÑÑÑваннÑ</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "ÐонвеÑÑÑваÑи за ÑÑ
емоÑ:"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 кÐÑ:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 кÐÑ:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 кÐÑ:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 кÐÑ:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 кÐÑ:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 кÐÑ:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 кÐÑ:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 кÐÑ:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 кÐÑ:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 кÐÑ:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "ÐонвеÑÑÐ¾Ñ ÑаÑÑоÑи диÑкÑеÑизаÑÑÑ"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "Ðк. СкÑоблÑнг Ð´Ð»Ñ ÐºÐ¾ÑиÑÑÑваÑа: %s"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "ÐÑдмовлено Ñ Ð´Ð¾ÑÑÑпÑ"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr ""
"ÐÑдвÑдайÑе наÑÑÑпне поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñоб дозволиÑи Audacious ÑкÑоблÑнг ваÑиÑ
"
"доÑÑжок:"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr ""
"ÐиÑÑÑÑ Ñе вÑкно вÑдкÑиÑим Ñа Ñе Ñаз наÑиÑнÑÑÑ 'ÐеÑевÑÑиÑи пÑава доÑÑÑпÑ'.\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2785,34 +2944,38 @@ msgstr ""
"Ðе Ñ
вилÑйÑеÑÑ. ÐÐ°Ð½Ñ Ð´Ð»Ñ ÑкÑоблÑÐ½Ð³Ñ Ð·Ð±ÐµÑÐµÐ¶ÐµÐ½Ñ Ð½Ð° компâÑÑеÑÑ.\n"
"Ðони бÑдÑÑÑ Ð²ÑдпÑавленÑ, Ñк ÑÑлÑки Audacious'Ñ Ð±Ñде дозволено Ñе зÑобиÑи."
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "ÐÑоблема меÑежÑ."
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr ""
"Ðиникла пÑоблема Ð·Ñ Ð·âÑднаннÑм до Last.fm. ÐÑÐ´Ñ Ð»Ð°Ñка ÑпÑобÑйÑе пÑзнÑÑе."
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "ÐеÑевÑÑка..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "Ð_еÑевÑÑиÑи пÑава доÑÑÑпÑ"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "_ÐидалиÑи пÑава доÑÑÑпÑ"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr ""
"Ðам поÑÑÑбно дозволиÑи Audacious ÑкÑоблиÑи доÑÑжки Ñ Ð²Ð°Ñ Ð°ÐºÐ°ÑÐ½Ñ Ð½Ð° Last.fm.\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "СкÑÐ¾Ð±Ð»ÐµÑ 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2820,7 +2983,7 @@ msgstr ""
"ÐодÑÐ»Ñ ÑкÑоблеÑа не може бÑÑи запÑÑений.\n"
"Ðожливо Ñе пÑоблема з вÑÑÐ°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾Ñ Ð¿ÑогÑамоÑ."
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2838,11 +3001,7 @@ msgstr ""
"ÑÑого пÑоекÑÑ.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "СкÑÐ¾Ð±Ð»ÐµÑ 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2850,7 +3009,11 @@ msgstr ""
"Ðа даний ÑÐ°Ñ Audacious викоÑиÑÑовÑÑ Ð¿Ð¾ÐºÑаÑÐµÐ½Ñ Ð²ÐµÑÑÑÑ ÑкÑобблеÑа Last.fm.â\n"
"ÐÑдÑ-лаÑка пеÑевÑÑÑе ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð¿Ð»Ð°ÒÑна Scrobbler."
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL-вивÑд"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2858,88 +3021,59 @@ msgstr ""
"ÐлаÒÑн Ð²Ð¸Ð²Ð¾Ð´Ñ Ð² SDL,\n"
"напиÑаний Ðжоном ÐÑндÒÑеном Ñ 2010 ÑоÑÑ."
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL-вивÑд"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "ÐÑблÑоÑека"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "ÐевÑдомий виконавеÑÑ"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "ÐевÑдомий алÑбом"
-
-#: src/search-tool/search-tool.c:625
-#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-"вÑд %s по %s"
-
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d алÑбом"
-msgstr[1] "%d алÑбоми"
-msgstr[2] "%d алÑбомÑв"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
-#: src/search-tool/search-tool.c:633
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
msgstr[0] ""
-"%s\n"
-" %s, %d пÑÑнÑ"
msgstr[1] ""
-"%s\n"
-" %s, %d пÑÑнÑ"
msgstr[2] ""
-"%s\n"
-" %s, %d пÑÑенÑ"
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
+msgid "%d song"
+msgid_plural "%d songs"
msgstr[0] ""
-"%s\n"
-" %d пÑÑÐ½Ñ Ð¿Ð¾ %s"
msgstr[1] ""
-"%s\n"
-" %d пÑÑÐ½Ñ Ð¿Ð¾ %s"
msgstr[2] ""
-"%s\n"
-" %d пÑÑÐµÐ½Ñ Ð¿Ð¾ %s"
-#: src/search-tool/search-tool.c:675
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr ""
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "_СÑвоÑиÑи ÑпиÑок вÑдÑвоÑеннÑ"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "_ÐодаÑи до ÑпиÑÐºÑ Ð²ÑдÑвоÑеннÑ"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "ШÑкаÑи в бÑблÑоÑеÑÑ"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
@@ -2947,679 +3081,769 @@ msgstr ""
"Щоб ÑмпоÑÑÑваÑи ÑÐ²Ð¾Ñ Ð¼ÑзиÑÐ½Ñ Ð±ÑблÑоÑÐµÐºÑ Ð´Ð¾ Audacious, вибеÑÑÑÑ ÑÐµÐºÑ Ð¹ "
"наÑиÑнÑÑÑ Ð½Ð° знаÑок оновленнÑ."
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "ÐаÑекайÑе..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "ÐибÑаÑи ÑекÑ"
-#: src/skins/menus.c:56
-msgid "Open Files ..."
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "ÐÑогÑÐ°Ð²Ð°Ñ SID"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr ""
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr ""
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr ""
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr ""
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr ""
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr ""
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr ""
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr ""
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr ""
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr ""
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr ""
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr ""
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
msgstr ""
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:64
+msgid "Open Files ..."
+msgstr "ÐÑдкÑиÑи ÑаиÌли..."
+
+#: src/skins/menus.cc:65
msgid "Open URL ..."
+msgstr "ÐÑдкÑиÑи адÑеÑÑ..."
+
+#: src/skins/menus.cc:66
+msgid "Search Library"
msgstr ""
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "ÐÑдÑвоÑеннÑ"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "СпиÑок вÑдÑвоÑеннÑ"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "ÐеÑеглÑд"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
-msgstr ""
+msgstr "СлÑжби"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
-msgstr ""
+msgstr "ÐÑо ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
-msgstr ""
+msgstr "ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
-msgstr ""
+msgstr "ÐиÑ
Ñд"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
-msgstr ""
+msgstr "ÐнÑоÑмаÑÑÑ Ð¿Ñо доÑÑжкÑ..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "ÐовÑоÑÑваÑи"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "Ðипадково"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "Ðе пÑоÑÑваÑиÑÑ Ñ ÑпиÑÐºÑ Ð²ÑдÑвоÑеннÑ"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
-msgstr ""
-
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ÐопеÑÐµÐ´Ð½Ñ Ð´Ð¾ÑÑжка"
+msgstr "ÐÑпиниÑи пÑÑÐ»Ñ ÑÑÑÑ Ð´Ð¾ÑÑжки"
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
-msgstr ""
+msgstr "ÐÑÑановиÑи A-B повÑоÑ"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
-msgstr ""
+msgstr "СкинÑÑи A-B повÑоÑ"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
-msgstr ""
+msgstr "ÐеÑеиÌÑи до доÑÑжки..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
-msgstr ""
+msgstr "ÐеÑеиÌÑи до ÑаÑÑ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr ""
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "ÐÑдÑвоÑиÑи/пÑодовжиÑи"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "ÐÐ¾Ð²Ð¸Ð¸Ì ÑпиÑок вÑдÑвоÑеннÑ"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
-msgstr ""
+msgstr "ÐеÑейменÑваÑи ÑпиÑок..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
-msgstr ""
+msgstr "ÐидалиÑи ÑпиÑок"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
-msgstr ""
+msgstr "ÐопеÑеднÑй ÑпиÑок"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
-msgstr ""
+msgstr "ÐаÑÑÑпний ÑпиÑок"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
-msgstr ""
+msgstr "ÐмпоÑÑÑваÑи ÑпиÑок вÑдÑвоÑеннÑ..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
-msgstr ""
+msgstr "ÐкÑпоÑÑÑваÑи ÑпиÑок вÑдÑвоÑеннÑ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
-msgstr ""
+msgstr "ÐеÑÑÐ²Ð°Ð½Ð½Ñ ÑпиÑками вÑдÑвоÑеннÑ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
-msgstr ""
+msgstr "ÐеÑÑÐ²Ð°Ð½Ð½Ñ ÑеÑгоÑ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
-msgstr ""
+msgstr "ÐновиÑи ÑпиÑок вÑдÑвоÑеннÑ"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "ÐоказаÑи ÑедакÑÐ¾Ñ ÑпиÑкÑв вÑдÑвоÑеннÑ"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "ÐоказаÑи еквалайзеÑ"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
-msgstr ""
+msgstr "ÐоказаÑи ÑÐ°Ñ Ð´Ð¾ завеÑÑеннÑ"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "Ðавжди згоÑи"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
-msgstr ""
+msgstr "Ðа вÑÑÑ
ÑобоÑиÑ
ÑÑолаÑ
"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
-msgstr ""
+msgstr "ÐгоÑнÑÑи плеÑÑ"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
-msgstr ""
+msgstr "ÐгоÑнÑÑи ÑедакÑÐ¾Ñ ÑпиÑÐºÑ Ð²ÑдÑвоÑеннÑ"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
+msgstr "ÐгоÑнÑÑи еквалайзеÑ"
+
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
msgstr ""
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:138
msgid "Add URL ..."
-msgstr ""
+msgstr "ÐодаÑи адÑеÑÑ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
-msgstr ""
+msgstr "ÐодаÑи Ñайли..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "Ðа назвоÑ"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "Ðа ÑмâÑм ÑайлÑ"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr ""
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
-msgstr ""
+msgstr "Ðа ÑлÑÑ
ом до ÑайлÑ"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "ÐилÑÑиÑи вÑÑ"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "ÐÑиÑÑиÑи ÑеÑгÑ"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "ÐÑибÑаÑи недоÑÑÑÐ¿Ð½Ñ Ñайли."
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "ÐидалиÑи дÑблÑкаÑи"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "ÐилÑÑиÑи невÑдмÑÑÐµÐ½Ñ "
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "ÐилÑÑиÑи видÑленÑ"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "ÐоÑÑк Ñ Ð²Ð¸Ð´ÑленнÑ"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "ÐнвеÑÑÑваÑи видÑленнÑ"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "ÐнÑÑи видÑленнÑ"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "ÐидÑлиÑи вÑе"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "Ðа алÑбомом"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "Ðа номеÑом доÑÑжки"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "Ðа виконавÑем"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "Ðа алÑбомом"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "Ðа виконавÑем алÑбомÑ"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
+msgstr "Ðа даÑÐ¾Ñ Ð²Ð¸Ð´Ð°Ð½Ð½Ñ"
+
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
msgstr ""
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "Ðа номеÑом доÑÑжки"
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr ""
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr ""
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "ÐоÑÑÑиÑи поÑÑдок"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "ÐбеÑнÑÑи ÑпиÑок"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "СоÑÑÑваÑи видÑлене"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "СоÑÑÑваÑи ÑпиÑок..."
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "ÐиÑÑзаÑи"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "ÐопÑÑваÑи"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "ÐÑÑавиÑи"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
-msgstr ""
+msgstr "Ð ÑеÑгÑ/Ð ÑеÑги"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
-msgstr ""
+msgstr "ÐаванÑажиÑи пÑеÑеÑ..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
-msgstr ""
+msgstr "ÐаванÑажиÑи авÑо-пÑеÑеÑ..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
-msgstr ""
+msgstr "ÐаванÑажиÑи за замовÑÑваннÑм"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
-msgstr ""
+msgstr "ÐаванÑажиÑи пÑеÑÐµÑ Ñз ÑайлÑ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
-msgstr ""
+msgstr "ÐаванÑажиÑи EQF Ñайл.."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
-msgstr ""
+msgstr "ÐбеÑегÑи пÑеÑеÑ..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
-msgstr ""
+msgstr "ÐбеÑегÑи авÑо-пÑеÑеÑ..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
-msgstr ""
+msgstr "ÐбеÑегÑи за замовÑÑваннÑм"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
-msgstr ""
+msgstr "ÐбеÑегÑи пÑеÑÐµÑ Ð´Ð¾ ÑайлÑ..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
-msgstr ""
+msgstr "ÐбеÑегÑи EQF Ñайл..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
-msgstr ""
+msgstr "ÐидалиÑи пÑеÑеÑ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
-msgstr ""
+msgstr "ÐидалиÑи авÑо-пÑеÑеÑ..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
-msgstr ""
+msgstr "ÐмпоÑÑÑваÑи пÑеÑеÑи WinAMP..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
-msgstr ""
+msgstr "СкинÑÑи на нÑлÑ"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "ÐлаÑиÑний ÑнÑеÑÑÐµÐ¹Ñ Winamp"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "ÐбеÑегÑи"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "ÐаванÑажиÑи"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
-msgstr ""
+msgstr "ÐаванÑажиÑи пÑеÑÐµÑ Ñз ÑайлÑ"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
-msgstr ""
+msgstr "ÐаванÑажиÑи EQF Ñайл"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
-msgstr ""
+msgstr "ÐбеÑегÑи пÑеÑÐµÑ Ð´Ð¾ ÑайлÑ"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
-msgstr ""
+msgstr "ÐбеÑегÑи EQF Ñайл"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
-msgstr ""
+msgstr "ÐмпоÑÑÑваÑи пÑеÑеÑи WinAMP"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "Ð¢Ð¸Ð¿Ð¾Ð²Ñ Ð½Ð°Ð»Ð°ÑÑÑваннÑ"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "ÐибÑÑ Ð¿ÑеÑеÑÑ"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "ÐаванÑажиÑи вÑдповÑдний доÑÑжÑÑ Ð¿ÑеÑеÑ"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "ÐбеÑÐµÐ¶ÐµÐ½Ð½Ñ Ð¿ÑеÑеÑÑ"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "ÐбеÑегÑи пÑеÑÐµÑ Ñк вÑдповÑдний доÑÑжÑÑ"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "ÐÐ¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð¿ÑеÑеÑÑ"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "ÐидалиÑи вÑдповÑдний доÑÑжÑÑ Ð¿ÑеÑеÑ"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "_ÐÑогÑаваÑ"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "ÐÑогÑаваÑ:"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "ШÑиÑÑ Ð¾Ñновного вÑкна пÑогÑаваÑа"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "_СпиÑок вÑдÑвоÑеннÑ"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "ÐлейлиÑÑ:"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "ШÑиÑÑ ÑпиÑÐºÑ Ð²ÑдÑвоÑеннÑ:"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
-msgstr ""
+msgstr "<b>Ðболонка</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
-msgstr ""
+msgstr "<b>ШÑиÑÑи</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "ÐикоÑиÑÑовÑваÑи ÑаÑÑÑÐ¾Ð²Ñ ÑÑиÑÑи (пÑдÑÑимÑÑÑÑÑÑ ÑÑлÑки ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
-msgstr ""
+msgstr "ÐÑокÑÑÑÑваÑи Ð½Ð°Ð·Ð²Ñ Ð¿ÑÑнÑ"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "ÐÑокÑÑÑÑваÑи Ð½Ð°Ð·Ð²Ñ Ð¿ÑÑÐ½Ñ Ð² обоÑ
напÑÑмкаÑ
"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "ÐналÑзаÑоÑ"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "ÐÑÑилогÑаÑ"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
-msgstr ""
+msgstr "СпекÑÑогÑама / VU-вимÑÑÑваÑ"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "Ðимкнено"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "ÐвиÑайний"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "ÐогонÑ"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
-msgstr ""
+msgstr "ÐеÑÑикалÑÐ½Ñ Ð»ÑнÑÑ"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "ÐÑнÑÑ"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "СÑовпÑики"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "ÐÑже повÑлÑне"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "ÐовÑлÑне"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "ÐомÑÑне"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "Швидке"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "ÐÑже Ñвидке"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
-msgstr ""
+msgstr "ТоÑки"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
-msgstr ""
+msgstr "ÐÑнÑÑ"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
-msgstr ""
+msgstr "СÑÑÑлÑна"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "ÐÑд"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "Ðлавний"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
-msgstr ""
+msgstr "<b>Тип</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
-msgstr ""
+msgstr "Тип вÑзÑалÑзаÑÑÑ:"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
-msgstr ""
+msgstr "<b>ÐналÑзаÑоÑ</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
-msgstr ""
+msgstr "ÐоказÑваÑи пÑки"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
-msgstr ""
+msgstr "ÐабаÑвленнÑ:"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
-msgstr ""
+msgstr "СÑилÑ:"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
-msgstr ""
+msgstr "Спад"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
-msgstr ""
+msgstr "Спад пÑкÑ:"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
-msgstr ""
+msgstr "СÑÐ¸Ð»Ñ Ð¾ÑÑилогÑами:"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
-msgstr ""
+msgstr "ÐабаÑÐ²Ð»ÐµÐ½Ð½Ñ ÑпекÑÑогÑами:"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
-msgstr ""
+msgstr "СÑÐ¸Ð»Ñ VU-вимÑÑÑваÑа:"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "ÐагалÑне"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "ÐÑзÑалÑзаÑÑÑ"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "ÐопеÑеднÑй пÑдÑилÑваÑ"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 ÐÑ"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 кÐÑ"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 кÐÑ"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "ÐÐºÐ²Ð°Ð»Ð°Ð¹Ð·ÐµÑ Audacious"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "ÐеÑеÑ
Ñд до %d:%-2.2d / %d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "ÐÑÑнÑÑÑÑ: %d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "ÐаланÑ: %d%% влÑво"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "ÐаланÑ: ÑенÑÑ"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "ÐаланÑ: %d%% впÑаво"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "ÐÐµÐ½Ñ Ð¾Ð¿ÑÑй"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "ÐимкнÑÑи вÑдобÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð½Ð°Ð´ ÑнÑими вÑкнами"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "ÐÑдобÑажаÑи над ÑнÑими вÑкнами"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "РедакÑÐ¾Ñ ÑнÑоÑмаÑÑÑ Ð¿Ñо доÑÑжкÑ"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr ""
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "ТоÑÐºÑ Ð¿Ð¾Ð²ÑоÑÑ A вÑÑановлено."
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "ТоÑÐºÑ Ð¿Ð¾Ð²ÑоÑÑ B вÑÑановлено."
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "ТоÑки повÑоÑÑ ÑкинÑÑÑ."
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "ÐднодоÑÑжковий Ñежим."
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "Режим ÑпиÑка вÑдÑвоÑеннÑ."
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "ÐÑпиниÑи пÑÑÐ»Ñ ÑÑÑÑ Ð´Ð¾ÑÑжки."
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "ÐоÑÑк в акÑÐ¸Ð²Ð½Ð¾Ð¼Ñ ÑпиÑÐºÑ Ð²ÑдÑвоÑеннÑ"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr ""
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3630,57 +3854,61 @@ msgstr ""
"Ðожна викоÑиÑÑовÑваÑи лÑÑеÑи, ÑиÑÑи, ÑнÑÑ Ð·Ð½Ð°ÐºÐ¸, ÑегÑлÑÑÐ½Ñ Ð²Ð¸Ñази. ÐÐ¾Ð»Ñ "
"неÑÑÑÐ»Ð¸Ð²Ñ Ð´Ð¾ ÑегÑÑÑÑÑ."
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
-msgstr "Ðазва: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
+msgstr ""
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
-msgstr "ÐлÑбом: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
+msgstr ""
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
-msgstr "ÐиконавеÑÑ: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
+msgstr ""
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "ÐмâÑ ÑайлÑ: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr ""
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "ÐнÑÑи попеÑÐµÐ´Ð½Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð¿ÐµÑед поÑÑком"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "ÐвÑомаÑиÑно пеÑемикаÑи ÑÑан ÑеÑги знайдениÑ
елеменÑÑв"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "ÐидÑлиÑи знайдене в новий ÑпиÑок вÑдÑвоÑеннÑ"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "РедакÑÐ¾Ñ ÑпиÑкÑв вÑдÑвоÑÐµÐ½Ð½Ñ Audacious"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d Ñз %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "ÐааÑÑ
Ñвований жÑпан Winamp 2.x"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "ÐеаÑÑ
Ñвований жÑпан Winamp 2.x"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "Ðеможливо ÑÑвоÑиÑи ÑÐµÐºÑ (%s): %s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "ÐлаÒÑн Sndfile"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3723,78 +3951,71 @@ msgstr ""
"Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA "
"02110-1301, USA"
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "ÐлаÒÑн Sndfile"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "ÐÑо плаÒÑн Ð²Ð¸Ð²Ð¾Ð´Ñ Sndio"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr ""
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr "ÐлаÒÑн Ð²Ð¸Ð²Ð¾Ð´Ñ Sndio, за авÑоÑÑÑвом Thomas Pfaff <tpfaff at tp76.info>.\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr ""
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "ÐепÑдÑÑимÑваний ÑоÑмаÑ"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr ""
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
msgstr ""
-"ФоÑÐ¼Ð°Ñ Ð½Ðµ пÑдÑÑимÑÑÑÑÑÑ Ð°ÑдÑопÑиÑÑÑоÑм.\n"
-"\n"
-"СпÑобÑйÑе Ñе Ñаз, запÑÑÑивÑи ÑеÑÐ²ÐµÑ sndiod(1)."
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "ÐÑиÑÑÑÑй Sndio"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr ""
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(поÑÐ¾Ð¶Ð½Ñ â Ñипове)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr ""
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "ÐаÑазд"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr ""
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "ÐмÑна доÑÑжки"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "ÐиконÑваÑи на поÑаÑÐºÑ Ð²ÑдÑвоÑÐµÐ½Ð½Ñ Ð´Ð¾ÑÑжки:"
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>ÐаÑамеÑÑи подаваÑи ÑлÑд Ñ Ð»Ð°Ð¿ÐºÐ°Ñ
. РобиÑи ÑнакÑе "
+"небезпеÑно Ð´Ð»Ñ ÑиÑÑеми.</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr ""
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr " "
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr ""
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "ÐиконÑваÑи напÑикÑнÑÑ Ð²ÑдÑвоÑÐµÐ½Ð½Ñ Ð´Ð¾ÑÑжки:"
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr ""
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "ÐиконÑваÑи пÑи доÑÑÐ³Ð½ÐµÐ½Ð½Ñ ÐºÑнÑÑ ÑпиÑка вÑдÑвоÑеннÑ:"
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr ""
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
-msgstr "ÐиконÑваÑи пÑи змÑÐ½Ñ Ð½Ð°Ð·Ð²Ð¸ доÑÑжки (онлайн-поÑоки ÑоÑо):"
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr ""
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3808,34 +4029,16 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"Ðи можеÑе викоÑиÑÑовÑваÑи наÑÑÑÐ¿Ð½Ñ Ñаблони\n"
-"(Ð´Ð»Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸ на кÑнеÑÑ ÑпиÑÐºÑ Ð¿ÑдÑ
одÑÑÑ Ð½Ðµ вÑÑ)\n"
-"\n"
-"%F: ЧаÑÑоÑа (ÐÑ)\n"
-"%c: ÐÑлÑкÑÑÑÑ ÐºÐ°Ð½Ð°Ð»Ñв\n"
-"%f: ÐмâÑ Ñайла (повний ÑлÑÑ
)\n"
-"%l: Ðовжина (мÑ)\n"
-"%n Ñи %s: Ðазва композиÑÑÑ\n"
-"%r: ШвидкÑÑÑÑ (бÑÑ/Ñ)\n"
-"%t: ÐозиÑÑÑ Ð² ÑпиÑÐºÑ Ð²ÑдÑвоÑÐµÐ½Ð½Ñ (%02d)\n"
-"%p: ÐаÑаз гÑÐ°Ñ (1 or 0)\n"
-"%a: ÐиконавеÑÑ\n"
-"%b: ÐлÑбом\n"
-"%T: Ðазва доÑÑжки"
-
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
+
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
msgstr ""
-"<span size='small'>ÐаÑамеÑÑи подаваÑи ÑлÑд Ñ Ð»Ð°Ð¿ÐºÐ°Ñ
. РобиÑи ÑнакÑе "
-"небезпеÑно Ð´Ð»Ñ ÑиÑÑеми.</span>"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "Ðоманди"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "РеÑÐµÐ¼Ð¿Ð»ÐµÑ SoX"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3849,51 +4052,51 @@ msgstr ""
"ÐазÑÑÑÑÑÑ Ð½Ð° ÐºÐ¾Ð´Ñ Ð¼Ð¾Ð´ÑÐ»Ñ Sample Rate Converter:\n"
"ÐвÑоÑÑÑке пÑаво 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "Швидка"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "ÐизÑка"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "ÐиÑока"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "ÐÑже виÑока"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "ЯкÑÑÑÑ:"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "РеÑÐµÐ¼Ð¿Ð»ÐµÑ SoX"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "ШвидкÑÑÑÑ Ñа виÑоÑа"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>ШвидкÑÑÑÑ Ñа виÑоÑа</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "ШвидкÑÑÑÑ:"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "ÐиÑоÑа:"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "ШвидкÑÑÑÑ Ñа виÑоÑа"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "ÐнаÑок Ñ Ð»Ð¾ÑкÑ"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
-msgstr ""
+msgstr "Ð_алаÑÑÑÐ²Ð°Ð½Ð½Ñ ..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3908,39 +4111,39 @@ msgstr ""
"2005â2007 â Ðжакомо ÐоÑÑÑо <james at develia.org>\n"
"2010 â MichaÅ Lipski <tallica at o2.pl>"
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>ÐÑÑ ÐºÐ¾Ð»ÑÑаÑка миÑÑ</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "ÐмÑна гÑÑноÑÑÑ"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "ÐмÑна поÑоÑÐ½Ð¾Ñ Ð´Ð¾ÑÑжки"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>ÐнÑÑ Ð½Ð°Ð»Ð°ÑÑÑваннÑ</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "ÐимкнÑÑи Ñпливне вÑкно"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "ÐамÑÑÑÑ Ð·Ð°ÐºÑиÑÑÑ Ð·Ð³Ð¾ÑÑаÑи до лоÑка"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "ÐÑоÑÑваÑиÑÑ ÑпиÑком вÑдÑвоÑÐµÐ½Ð½Ñ Ð¿Ñи пÑокÑÑÑÑÐ²Ð°Ð½Ð½Ñ Ð´Ð¾Ð³Ð¾Ñи"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "ÐнаÑок Ñ Ð»Ð¾ÑкÑ"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "РозÑиÑене ÑÑеÑео"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3949,24 +4152,24 @@ msgstr ""
"РозÑиÑене ÑÑеÑео,\n"
"плаÒÑн напиÑаний Ñ 1999 ÑоÑÑ (авÑÐ¾Ñ â Johan Levin)."
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>РозÑиÑене ÑÑеÑео</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "РозÑиÑене ÑÑеÑео"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "ÐенеÑаÑÐ¾Ñ ÑонÑ"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f ÐÑ"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "ÐенеÑаÑÐ¾Ñ ÑонÑ: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3984,15 +4187,11 @@ msgstr ""
"ÐапÑиклад, tone://2000;2005 â поÑлÑдовне вÑдÑвоÑÐµÐ½Ð½Ñ ÑонÑв з ÑаÑÑоÑÐ¾Ñ 2000 "
"ÐÑ Ñ 2005 ÐÑ."
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "ÐенеÑаÑÐ¾Ñ ÑонÑ"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "ÐÐ¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð³Ð¾Ð»Ð¾ÑÑ"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -4030,11 +4229,35 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ Ogg Vorbis"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr ""
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ VTX"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4045,19 +4268,19 @@ msgstr ""
"\n"
"ÐлаÒÑн Ð´Ð»Ñ Audacious ÑÑвоÑив Ðавел ÐимеÑалек <pvymetalek at seznam.cz>."
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ VTX"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ WavPack"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "Ð·Ñ Ð²ÑÑаÑами (гÑбÑид)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "Ð·Ñ Ð²ÑÑаÑами"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4067,14 +4290,18 @@ msgstr ""
"\n"
"ÐеÑкий код напиÑав ÐÐ°Ð¹Ð»Ñ ÐÒан."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ WavPack"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "ÐÐµÐºÐ¾Ð´ÐµÑ 2SF"
-#: src/xspf/xspf.c:438
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr ""
+
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr ""
+
+#: src/xspf/xspf.cc:89
msgid "XML Shareable Playlists (XSPF)"
msgstr "XML-ÑпиÑки вÑдÑвоÑÐµÐ½Ð½Ñ (XSPF)"
diff --git a/po/update-potfiles.sh b/po/update-potfiles.sh
index ace2d5c30339..437cd13e8f9b 100755
--- a/po/update-potfiles.sh
+++ b/po/update-potfiles.sh
@@ -2,4 +2,5 @@
rm POTFILES*
echo "# Please don't update this file manually - use ./update-potfiles.sh instead!" > POTFILES.in
cd ..
-find src/ \( -name "*.c" -o -name "*.cxx" -o -name "*.cc" -o -name "*.glade" \) -exec grep -lE "translatable|_\(" \{\} \; | sort | uniq >> po/POTFILES.in
+find src/ \( -name "*.c" -o -name "*.h" -o -name "*.cxx" -o -name "*.cc" -o -name "*.glade" \) \
+ -exec grep -lE "translatable|_\(" \{\} \; | sort | uniq >> po/POTFILES.in
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 0979900f8b93..2a76fefcb142 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -3,22 +3,30 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
+# å¨åé¡ <btchina at live.com>, 2013
# Chasye <chasye at gmail.com>, 2010
# yinsigan <ganweiliang886 at gmail.com>, 2012
-# JeffBai <jeffbaichina at members.fsf.org>, 2014
-# michaeljayt <michaeljayt at gmail.com>, 2013
+# ç½é骢 <jeffbaichina at members.fsf.org>, 2014
+# ç½é骢 <jeffbaichina at members.fsf.org>, 2014
# Luke <runningwaterpro at gmail.com>, 2012
-# sd542927172 <sd542927172 at live.cn>, 2013
-# min zhang <zm1990s at gmail.com>, 2014
-# min zhang <zm1990s at gmail.com>, 2013
-# 4679kun <btchina at live.com>, 2013
+# Michael Jay Tong <michaeljayt at gmail.com>, 2013
+# Michael Jay Tong <michaeljayt at gmail.com>, 2013-2014
+# zhangmin <zm1990s at gmail.com>, 2013-2014
+# Luke <runningwaterpro at gmail.com>, 2012
+# shan dong <sd542927172 at live.cn>, 2013
+# shan dong <sd542927172 at live.cn>, 2013
+# yinsigan <ganweiliang886 at gmail.com>, 2012
+# zhangmin <zm1990s at gmail.com>, 2013-2015
+# zhangmin <zm1990s at gmail.com>, 2013
+# å¨åé¡ <btchina at live.com>, 2013
+# èæµ©æµ· <jhaohai at foxmail.com>, 2014
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-12 08:18+0000\n"
-"Last-Translator: min zhang <zm1990s at gmail.com>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-05 10:15+0000\n"
+"Last-Translator: zhangmin <zm1990s at gmail.com>\n"
"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/"
"audacious/language/zh_CN/)\n"
"Language: zh_CN\n"
@@ -27,40 +35,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "å声é"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "ç«ä½å£°"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "ç¯ç»å£°"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "AAC (MP4) è§£ç å¨"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "AAC (Raw) è§£ç å¨"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib ææ¾å¨)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "è¿ç»ç"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib ææ¾å¨)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "é¹é"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "设置é¹é"
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -70,11 +66,7 @@ msgstr ""
"\n"
"æåç± Adam Feakin å Daniel Stodden ç¼åã"
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "é¹é"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -112,7 +104,7 @@ msgstr ""
"éæ©é¹éæ¶é´ï¼æè
ç¹æå¼å
³æé®ä»¥ä½¿ç¨é»è®¤æ¶é´ã\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -149,7 +141,7 @@ msgstr ""
"å¨è®¾å®çæ¶é´è¿è¡å½ä»¤ã\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -170,383 +162,390 @@ msgstr ""
"å¨é¹éååæ¾ç¤ºä¸ä¸ªå¤å¿å½ã\n"
"卿¤è¾å
¥æ¡è¾å
¥å¤å¿å½å¹¶æå¼å¼å
³æé®ã"
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "æ¤ä¸ºèµ·åºé¹é"
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "ä½ ä»æ¥çå¤å¿å½æ¯â¦â¦"
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "æéå¨"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "ææä¸"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "ææäº"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "ææä¸"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "ææå"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "ææäº"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "ææå
"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "æææ¥"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "é¹é设置"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "好ç (&O)"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "åæ¶ (&C)"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "æ¶é´"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "åé¹é (é»è®¤) : "
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "ç¹"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "é鳿¶é´ï¼"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "å°æ¶"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "å"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "éæ©åé¹éçæ¥æ"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "æ¥æ"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "é»è®¤"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "æ¥æ"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "æ¸é"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "ç§"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "é³é"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "å¼å§äº"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "宿äº"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "å½å"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "éå å½ä»¤"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "å¯ç¨"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "ææ¾å表(å¯é)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "éæ©ä¸ä¸ªææ¾å表"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "é项"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "è¿äºé项代表ä»ä¹ï¼"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "帮å©"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "ä¸è¾å°é¢"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "ä¸è¾å°é¢(Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA è¾åº"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"Audacious ç ALSA Output æä»¶\n"
+"çæææ 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(æ æè¿°)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "é»è®¤ PCM 设å¤"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "é»è®¤æ··é³è®¾å¤"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM 设å¤ï¼"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "æ··é³è®¾å¤"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "æ··é³åå
ï¼"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "å°è¯è§£å³é³é¢è¾åºä¸ç
"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI ææ¾å¨)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"Audacious ç ALSA Output æä»¶\n"
-"çæææ 2009-2012 John Lindgren\n"
+"AMIDI-æä»¶\n"
+"模åå MIDI é³ä¹ææ¾å¨\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA è¾åº"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI ææ¾å¨)"
+"ä½è
ï¼ Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"ç¹å«æè°¢...\n"
+"\n"
+"Clemens Ladisch ï¼ Jaroslav Kysela\n"
+"ç¼åçè¶
å¸
ç aplaymidi å amixerï¼è¿ä¸¤ä¸ª\n"
+"以å alsa-lib docs 对æä»¬å¦ä¹ ALSA API æå¾å¤§å¸®å©\n"
+"\n"
+"\n"
+"Alfredo Spadafina\n"
+"è´¡ç®äºå¾æ¼äº®ç midi é®çæ å¿\n"
+"\n"
+"Tony Vroon\n"
+"叮婿们è¿è¡æµè¯"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "è¦çé»è®¤å¢ç: "
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "è¦çé»è®¤å¤è°: "
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "è¦çé»è®¤åå: "
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "å¼å¯"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "è¦çé»è®¤å声: "
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>åæ¾</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "转置: "
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "åé³"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "é¼ç§»: "
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>é«çº§è®¾ç½®</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "é³ç¬¦æ°å"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "ä» MIDI æä»¶éæ¾å¤æ³¨"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "è·³è¿å¼å¤´çéé³"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "ä» MIDI æä»¶éæ¾æè¯"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "è·³è¿å°¾é¨éé³"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>åæå¨</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
-msgstr "åæ ·ç:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
+msgstr "éæ ·çï¼"
+
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "赫å
¹"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - éæ©SoundFontæä»¶"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "åæ¶ (_C)"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
-msgstr "æå¼ (&O)"
+msgstr "æå¼ (_O)"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "æä»¶å"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "大å°(bytes)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "åç§°ï¼"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI ä¿¡æ¯ </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "æ ¼å¼ï¼"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "é¿åº¦(毫ç§)ï¼"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "é³è½¨æ°ï¼"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "åä½"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "æ¯åéèæ: "
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "æ¯åéèæ (wavg): "
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "æ¶é´æ ¼: "
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI夿³¨ä¸æè¯</span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* MIDIæä»¶ä¸å
å«å¤æ³¨ *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* MIDIæä»¶ä¸å
å«æè¯ *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "å
³é(_C)"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (éæ³çUTF-8ç¼ç )"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "å
³äºAMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"模ååç MIDI é³ä¹ææ¾å¨\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"ç± Giacomo Lozito ç¼å\n"
-"<james at develia.org>\n"
-"\n"
-"ç¹å«é¸£è°¢â¦â¦\n"
-"\n"
-"Clemens Ladisch å Jaroslav Kysela\n"
-"为ä»ä»¬ç«é
·çç¨åºå¦ aplaymidi 以å amixerl; è¿äºè½¯ä»¶ç¸å½æç¨ï¼ä¸ alsa-lib çæ"
-"æ¡£é
å以便深å
¥å¦ä¹ ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"为 Ta æ¼äº®ç MIDI é®ç徿 \n"
-"\n"
-"Tony Vroon\n"
-"为ä»å¨ Alpha æµè¯é¶æ®µæä¾ç帮å©"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -564,151 +563,146 @@ msgstr ""
"é¨ååºäº Evan Martin ç Ghosd åº:\n"
"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (On-Screen Display)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "æ¹è§ç©å½¢"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "åè§ç©å½¢"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "å¹è§ç©å½¢"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "æ "
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "ææ¾å¼å§"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "å¼å§ææ¾æ¶è§¦åOSD"
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "æ 颿¹å"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
-msgstr ""
-"ææ¾å䏿件æ¶ï¼æ é¢åçæ¹åæ¶è§¦åOSDã\n"
-"ææ¾ç½ç»åªä½æ¶ä¼ç»å¸¸ç¢°å°ã"
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
+msgstr "卿²ç®æ 颿¹åæ¶è§¦å OSDï¼ç¨äºäºèç½æµåªä½ï¼ã"
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "æåææ¾"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "æåææ¾æ¶è§¦åOSD"
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "æ¢å¤ææ¾"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "æ¢å¤ææ¾æ¶è§¦åOSD"
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "ä½ç½®"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "Xç¸å¯¹ä½ç§»ï¼"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Yç¸å¯¹ä½ç§»ï¼"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "æå¤§OSD宽度ï¼"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "å¤å±é项"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "OSDæ¾ç¤ºäºï¼"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "æææ¾ç¤ºå¨"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "æ¾ç¤ºå¨%i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "å»¶æ¶(ms)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "æ¾ç¤ºï¼"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "æ·¡å
¥ï¼"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "æ·¡åºï¼"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "åä½"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "åä½ %iï¼"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "é´å½±"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "渲æé£æ ¼"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "é¢è²"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "é¢è² %iï¼"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "å¯ç¨è§¦åå¨"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "äºä»¶"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "æ£æµå°æ··å管çå¨"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -717,112 +711,112 @@ msgstr ""
"æªæ£æµå°æ··å管çå¨ï¼\n"
"OSDæ æ³æ£å¸¸å·¥ä½ï¼é¤éä½ æ¿æ´»æ··å管çå¨ã"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "åéææ éæ··åç®¡çæ¯æ"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "éæ"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "åéæ"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "çéæ(éè¦X Compositeæ©å±)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "X Compositeæ©å±æªå è½½"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "X Compositeæ©å±ä¸å¯ç¨"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - 设置"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "æµè¯ (&T)"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "设置 (&S)"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "ä½ç½®"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "å¨ç»"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "åä½"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "è£
饰å¨"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "触åå¨"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "å
¶å®"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "æµè¯"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "ASXv3 ææ¾å表"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1/ASXv2 ææ¾å表"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious ææ¾å表 (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>é¢è²</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "模ç³èå´"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer ç«ä½å声(BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "é¢ç½®:"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "è¯çº§: "
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "æªæ¢é¢ç: "
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "é¢ç½®:"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer ç«ä½å声(BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "é¢è°±åæå¨"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "é³é¢ CD æä»¶"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -842,171 +836,158 @@ msgstr ""
"\n"
"This was a Google Summer of Code 2007 project."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>设å¤</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "读åé度ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "è¦ç设å¤ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>Metadata</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "ä½¿ç¨ CD ææ¬"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "ä½¿ç¨ CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "使ç¨HTTP代æ¿CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "æå¡å¨ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "è·¯å¾ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "端å£ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "é³é¢ CD æä»¶"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "åå§å cdio åç³»ç»å¤±è´¥ã"
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "æ æç URI %sã"
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "æªæ¾å°é³è½¨ %dã"
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "ç£é %d æ¯ä¸ä¸ªæ°æ®ç£é"
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "æå¼é³é¢è¾åºå¤±è´¥ã"
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "读åé³é¢ CD æ¶åºéã"
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "é³é¢CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "é³è½¨ %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "æå¼ CD è®¾å¤ %s 失败ã"
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "æ²¡ææ¾å°åéç CD é³é¢é©±å¨å¨ã"
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "宿æå¼ç CD 驱å¨å¨åå§å失败ã"
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "åå¾ç¬¬ä¸é¦/æåä¸é¦é³é¢é³è½¨å·å¤±è´¥ã"
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "ä¸è½è¯»åé³é¢ %d å¼å§/ç»æç LSN ä¿¡æ¯ã"
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "å建 CDDB è¿æ¥å¤±è´¥ã"
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "æ¥è¯¢ CDDB æå¡å¨å¤±è´¥"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "æ¥è¯¢ CDDB æå¡å¨å¤±è´¥ï¼%s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "读å CDDB ä¿¡æ¯å¤±è´¥ï¼%s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "设å¤ä¸ºç©º"
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "æªæ¯æå
çç±»å"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "é³é¢ CD ç®å½é¡¹"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "ææ¾CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "æ·»å CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "é³é¢ CD ç®å½é¡¹"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>å缩</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "ä¸é´é³éï¼"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "卿èå´ï¼"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Audacious ç Dynamic Range Compression æä»¶\n"
-"çæææ 2010-2012 John Lindgren"
+"Audacious 卿èå´å缩æä»¶\n"
+"John Lindgren 2010-2014 çæææ"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "卿èå´å缩"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1023,207 +1004,237 @@ msgstr ""
"Shay Green <gblargg at gmail.com>\n"
"ç¼å"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ä½é³ï¼"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "é«é³ï¼"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "åå: "
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "é»è®¤ææ²é¿åº¦ï¼"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>éåæ ·</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "å¯ç¨é³é¢ééæ ·"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "éæ ·çï¼"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "赫å
¹"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "忽ç¥SPCæ ç¾æ¾ç¤ºçé¿åº¦"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "å»¶é¿ä½å"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "æ¸¸ææºé³ä¹è§£ç å¨"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"æ·¡åºå¤±è´¥ï¼ åå ï¼ææ²çééæ°ä¸ä¸è´ã\n"
-"\n"
-"ä½ å¯ä»¥å°è¯ä½¿ç¨â声鿷·é³å¨âä½¿ææ²çééæ°ä¿æä¸è´ã"
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "CoreAudio è¾åº"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"æ·¡åºå¤±è´¥ï¼ åå ï¼ææ²çéæ ·çä¸ä¸è´ã\n"
+"Audacious CoreAudio è¾åºæä»¶\n"
+"William Pitcock 2014 çæææ\n"
"\n"
-"ä½ å¯ä»¥å°è¯ä½¿ç¨âéæ ·ç转æ¢å¨âä½¿ææ²çéæ ·ä¿æä¸è´ã"
+"åºäº Audacious SDL è¾åºæä»¶\n"
+"John Lindgren 2010 çæææ"
-#: src/crossfade/crossfade.c:256
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "ä½¿ç¨æé¤æ¨¡å¼"
+
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
-"Audacious çæ·¡åºæä»¶\n"
-"çæææ 2010-2012 John Lindgren"
+"Audacious Crossfade æä»¶\n"
+"John Lindgren 2010-2014 çæææ"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>æ·¡åº</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "å¨èªå¨åæ¢ææ²æ¶"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "éå ï¼"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "å¨å®ä½æè
æå¨æ¹åææ²æ¶"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>æç¤º</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr "为äºè®©æ·¡åºæ´å¥½å°å·¥ä½ï¼å¯ç¨éé³ç§»é¤ç¹æ"
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "æ·¡åº"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"æ·¡åºå¤±è´¥ï¼ åå ï¼ææ²çééæ°ä¸ä¸è´ã\n"
+"\n"
+"ä½ å¯ä»¥å°è¯ä½¿ç¨â声鿷·é³å¨âä½¿ææ²çééæ°ä¿æä¸è´ã"
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"æ·¡åºå¤±è´¥ï¼ åå ï¼ææ²çéæ ·çä¸ä¸è´ã\n"
+"\n"
+"ä½ å¯ä»¥å°è¯ä½¿ç¨âéæ ·ç转æ¢å¨âä½¿ææ²çéæ ·ä¿æä¸è´ã"
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>ä¿ç鳿</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "强度ï¼"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Crystalizer"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Cue 表æä»¶"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "å 餿件"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "å° %s ç§»å¨è³åå¾ç®±æ¶åºé: %s."
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "å é¤ %s æ¶åºé: %s."
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "å é¤ %s æ¶åºé: 䏿¯ä¸ä¸ªæ¬å°æä»¶ã"
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "ä½ å¸æå°éä¸çæä»¶ç§»è³åå¾ç®±åï¼"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "ç§»è³åå¾ç®±"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "ä½ å¸ææ°¸ä¹
å é¤éä¸çæä»¶åï¼"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "å é¤"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "åæ¶"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "å 餿件"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "å é¤éä¸çæä»¶"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>å 餿¹å¼</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "ç§»å¨å°åå¾ç®±è䏿¯ç´æ¥å é¤"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+"å鳿件\n"
+"ä½è
ï¼ Johan Levin, 1999\n"
+"ç¯ç»å声ï¼ä½è
ï¼ Carl van Schaik, 1999\n"
+"ç± William Pitcock å John Lindgren ä¿®æ¹åç¨äº Audacious, 2010-2014"
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>åå</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "å»¶è¿ï¼"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "毫ç§"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "åé¦ï¼"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "é³éï¼"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"ååæä»¶\n"
-"ä½è
Johan Levin 1999.\n"
-"\n"
-"åé³ç¯ç» ä½è
Carl van Schaik 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "åå"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg æä»¶"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1240,55 +1251,55 @@ msgstr ""
"Matti Hämäläinen <ccr at tnsp.org>\n"
"ç¼å"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg æä»¶"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "FileWriter æä»¶"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "è¾åºæä»¶æ ¼å¼ï¼"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "设置"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "ä¿åå°åæ¥çç®å½"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "ä¿åå°èªå®ä¹ç®å½"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "è¾åºæä»¶ç®å½ï¼"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "éæ©ç®å½"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "æä»¶åæ¥èªï¼"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "æä»¶åçææ¥æºï¼"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
msgstr "åå§æä»¶æ ç¾"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
msgstr "åå§æä»¶å"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "ä¿çæä»¶åç¼"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "å
å«åå§æä»¶çæ©å±å"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
msgstr "æä»¶ååå ä¸é³è½¨å·"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1320,165 +1331,169 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "FileWriter æä»¶"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "èªå¨"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "èåç«ä½å£°"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "ç«ä½å£°"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "å声é"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3设置"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "好ç (_O)"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "é³è´¨"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
msgstr "è¾åºåæ ·ï¼"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "ï¼èµ«å
¹ï¼"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
msgstr "ç ç/å缩çï¼"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ç ç(kbps)ï¼"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "å缩çï¼"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "é³é¢æ¨¡å¼ï¼"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "å
¶å®ï¼"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr "æé¡¹ï¼"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
msgstr "强å¶ä¸¥æ ¼éµä»ISO"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "éè¯¯ä¿æ¤"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "è´¨é"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "å¯ç¨VBR/ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "ç±»åï¼"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBRé项ï¼"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "æå°ç ç(kbps)ï¼"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "æå¤§ç ç(kbps)ï¼"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "ä¸¥æ ¼æ§è¡æå°ç ç"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABRé项ï¼"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "å¹³åç ç(kbps)ï¼"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBRè´¨éç级ï¼"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "ä¸è¦åå
¥Xing VBR头"
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "忽ç¥Xing VBR头"
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBR/ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr "叧忰ï¼"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "æ 记为çæ"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "æ 记为åå§æä»¶"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "ID3åæ°ï¼"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "å¼ºå¶æ·»å V2æ ç¾"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "ä»
æ·»å v1æ ç¾"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "ä»
æ·»å v2æ ç¾"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "æ ç¾"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbisç¼ç å¨è®¾ç½®"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "è´¨éç级(0-10)ï¼"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC è§£ç å¨"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "æ æç"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1490,11 +1505,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC è§£ç å¨"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1502,11 +1513,19 @@ msgstr ""
"Audacious ç GIO æä»¶\n"
"çæææ 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO æä»¶"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "读å-è¿½å æ¨¡å¼ä¸åæ¯æ"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "æå¼æ¨¡å¼ä¸å¯ç¨"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1526,533 +1545,619 @@ msgstr ""
"\n"
"许å¯: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL é¢è°±åæå¨"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
+msgid ""
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
+msgstr ""
+"Audacious OpenGL é¢è°±å¾åæå¨\n"
+"Christophe Budé, John Lindgren, Carlo Bramini. 2013 çæææ\n"
+"William Pitcock. 2014 çæææ\n"
+"\n"
+"åºäº XMMS æä»¶ï¼\n"
+"Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilssonï¼4Front Technologies. "
+"1998-2000 çæææ\n"
+"\n"
+"许å¯: GPLv2+"
+
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "OpenGL é¢è°±åæå¨(Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
+msgstr "GNOME å¿«æ·é®"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
msgstr ""
-"GNOME å¿«æ·æ¹å¼æä»¶\n"
+"GNOME å¿«æ·é®æä»¶\n"
"è®©ä½ ä½¿ç¨ GNOME å¿«æ·é®æ¥æ§å¶ææ¾å¨ã\n"
"\n"
"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
-msgstr "Gnome å¿«æ·é®"
-
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "åºå·"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "æ é¢"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "èºæ¯å®¶"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "年份"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "ä¸è¾"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "ä¸è¾èºæ¯å®¶"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "é³è½¨"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "æµæ´¾"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "éåä½ç½®"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "é¿åº¦"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "æä»¶è·¯å¾"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "æä»¶å"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "èªå®æ é¢"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "æ¯ç"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "å¯ç¨å"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "æ¾ç¤ºå"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "æç´¢å·¥å
·"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "颿¿å¨å·¦"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "颿¿å¨å³"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "颿¿å¨ä¸"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "颿¿å¨ä¸"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "æ 颿¿"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "ç¦ç¨"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "æç´¢å·¥å
·"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
-msgstr "æå¼æä»¶(_O) ..."
+msgstr "æå¼æä»¶...(_O)"
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
-msgstr "æå¼URL(_U)..."
+msgstr "æå¼URL...(_U)"
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
-msgstr "æ·»å æä»¶"
+msgstr "æ·»å æä»¶(_A)"
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
-msgstr "æ·»å URL(_R)..."
+msgstr "æ·»å URL...(_R)"
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
-msgstr "æç´¢åº (&L)"
+msgstr "æç´¢åº (_L)"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "å
³äº(_b)"
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
-msgstr "设置 ... (&S)"
+msgstr "设置 ... (_S)"
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "éåº(_Q)"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "ææ¾(_P)"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "æå(_e)"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "忢(_S)"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "ä¸ä¸é¦(_v)"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "ä¸ä¸é¦(_N)"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "éå¤(_R)"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "éæº(_h)"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "ç¦æ¢èªå¨ææ¾ä¸ä¸é¦(_o)"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "å¨è¿é¦æå忢"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
-msgstr "ææ²ä¿¡æ¯(_I)..."
+msgstr "ææ²ä¿¡æ¯...(_I)"
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
-msgstr "è·³å°æ¶é´(_T)..."
+msgstr "è·³å°æ¶é´...(_T)"
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
-msgstr "è·³å°ææ²(_J)..."
+msgstr "è·³å°ææ²...(_J)"
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "设置éå¤ç¹ _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "设置éå¤ç¹ _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
-msgstr "æ¸
é¤éå¤ç¹"
+msgstr "æ¸
é¤éå¤ç¹(_C)"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "ææ é¢(_T)"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
-msgstr "ä½¿ç¨æä»¶åæåº"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
+msgstr "ææä»¶å(_F)"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
-msgstr "ä½¿ç¨æä»¶è·¯å¾æåº"
+msgstr "ææä»¶è·¯å¾(_P)"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "æé³è½¨åºå·(_N)"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "æèºæ¯å®¶(_A)"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
-msgstr "使ç¨ä¸è¾æåº"
+msgstr "æä¸è¾(_b)"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "æä¸è¾èºæ¯å®¶(_m)"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "æåè¡¨æ¥æ(_D)"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "æç
§ç±»å (_G)"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
-msgstr "使ç¨é¿åº¦æåº"
+msgstr "æé¿åº¦(_L)"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "ææä»¶è·¯å¾(_F)"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "æèªå®ä¹æ é¢(_C)"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
-msgstr "å转(_e)"
+msgstr "éåº(_e)"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "éæº(_R)"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "ææ¾æ¤å表ï¼_Pï¼"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "ææ¾/ç»§ç» (_P)"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "å·æ°(_R)"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "æåº(_S)"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
-msgstr "æåºéä¸é¡¹"
+msgstr "æåºéä¸é¡¹(_l)"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
-msgstr "å é¤éå¤"
+msgstr "å é¤éå¤(_D)"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
-msgstr "ç§»é¤æ ææä»¶"
+msgstr "ç§»é¤æ ææä»¶(_U)"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "æ°å»º(_N)"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
-msgstr "éå½åï¼_Aï¼ ..."
+msgstr "éå½å(_a) ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
-msgstr "ç§»é¤ (&V)"
+msgstr "ç§»é¤ (_v)"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
-msgstr "导å
¥(_I)..."
+msgstr "导å
¥...(_I)"
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
-msgstr "导åº(_E)..."
+msgstr "导åº...(_E)"
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "ææ¾å表管çå¨ï¼_Mï¼..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "éå管çå¨(_Q)..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "è°é«é³é(_U)"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "è°ä½é³é(_D)"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "åè¡¡å¨(_E)"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
-msgstr "鳿 ... (&E)"
+msgstr "鳿 ... (_E)"
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "æ¾ç¤ºèå(_M)"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "æ¾ç¤ºä¿¡æ¯åºå(_n)"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "æ¾ç¤ºå¯è§åä¿¡æ¯æ ï¼_Uï¼"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "æ¾ç¤ºç¶ææ (_S)"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
-msgstr "æ¾ç¤ºå©ä½æ¶é´"
+msgstr "æ¾ç¤ºå©ä½æ¶é´(_R)"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
-msgstr "å¯è§å ... (&V)"
+msgstr "å¯è§å ... (_V)"
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "æä»¶(_F)"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "åæ¾(_P)"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "ææ¾å表(_l)"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "æå¡(_S)"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "è¾åº(_O)"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "å¤è§(_V)"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "å
¥éï¼åºå(_Q)"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "æå¼æå±æä»¶å¤¹ (_O)"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "åªå(_t)"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "å¤å¶(_C)"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "ç²è´´(_P)"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "éä¸å
¨é¨(_A)"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
-msgstr "éå½åï¼_Rï¼ ..."
+msgstr "éå½å...(_R)"
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>ææ¾å表æ ç¾é¡µ</b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "æ»æ¯æ¾ç¤ºæ ç¾é¡µ"
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "æ¾ç¤ºæ¡ç®æ°é"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "æ¾ç¤ºå
³éæé®"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>ææ¾å表å</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "æ¾ç¤ºå头"
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>æé¡¹</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr "ç®å¤´é®æåº:"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "ææ²æ¹åæ¶æ»å¨"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTKçé¢"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ç¼å²ä¸..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "å声é"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "ç«ä½å£°"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d声é"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "åä¸çªå£æ¨¡å¼"
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "ææ¾å表模å¼"
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "宿å忢"
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "ä¸ä¸é¦"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "ææ¾"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "æå/ç»§ç»"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "忢"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "ä¸ä¸é¦"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "å¿«è¿ 5 ç§"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "å¿«é 5 ç§"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "éé³"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "æé«é³é"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "éä½é³é"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "è·³å°æä»¶"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "ææ¾çªå£åæ¢"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "æ¾ç¤ºOn-Screen-Display"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "æå¼éå¤"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "æå¼éæºææ¾"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "æå¼å½åæ²ç®å忢"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "æåºææ¾å¨çªå£"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(æ )"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2060,37 +2165,37 @@ msgid ""
"Do you want to continue?"
msgstr "å¹¶ä¸å»ºè®®ç»å®é¼ æ 主é®ãè¦ç»§ç»åï¼"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "ç»å®é¼ æ æé®"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "å
¨å±çé®æä»¶è®¾ç½®"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
msgstr "è¯·å¨ææ¬åºæä¸è¦ç»å®çç»åé®ï¼ä½ 亦å¯ä»¥ç»å®é¼ æ é®"
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "çé®ï¼"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>å¨ä½ï¼</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>é®ä½ç»å®ï¼</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
-msgstr "æ·»å (&A)"
+msgstr "æ·»å (_A)"
+
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "å
¨å±çé®"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2116,60 +2221,53 @@ msgstr ""
"Jonathan A. Davis <davis at jdhouse.org>,\n"
"Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "å
¨å±çé®"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK è¾åº"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "è¿æ¥å°ææå¯ç¨ç Jack æ¥å£"
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "èªå¨è¿æ¥å°è¾åºç«¯å£"
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "ä»
è¿æ¥å°è¾åºç«¯å£"
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "ä»
åç° %d 个 JACK 端å£ï¼ä½æ¯éè¦ %d 个ã"
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "ä¸è¿æ¥å°ä»»ä½ç«¯å£"
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "è¿æ¥å° JACK ç«¯å£ %s 失败ã"
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "è¿æ¥æ¨¡å¼: "
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr "JACK ä»
æ¯ææµ®ç¹é³é¢ãä½ å¿
é¡»å¨ Audacious 设置ä¸å°è¾åºä½æ·±æ¹ä¸ºæµ®ç¹ã"
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "å¯ç¨è°è¯è¾åº"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "è¿æ¥å° JACK æå¡å¨å¤±è´¥ï¼æå¡æ¯å¦å¨è¿è¡ï¼"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"åºäº xmms-jack, ç± Chris Morgan å¶ä½: \n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"ç± Giacomo Lozito ç§»æ¤å° Audacious"
-
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK è¾åº"
+"JACK æå¡è¦æ±éæ ·ç为 %d Hzï¼ä½æ¯ Audacious 以 %d Hz ææ¾ã请使ç¨éæ ·ç转æ¢ç¹"
+"ææä»¶çº æ£æ¤é误"
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s 设置"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA主æºè®¾ç½®"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "模åè·¯å¾ï¼"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2179,25 +2277,25 @@ msgstr ""
"è¿äºè·¯å¾å°éå äº LADSPA_PATH è¿è¡æç´¢ã\n"
"卿·»å è¿äºæ°çè·¯å¾åï¼æä¸ Enter ä»¥æ«ææ°æä»¶ã</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "å¯ç¨æä»¶ï¼"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "å¯ç¨"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "å·²å¯ç¨æä»¶ï¼"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "设置"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2205,47 +2303,15 @@ msgstr ""
"Audacious ç LADSPA Host\n"
"Copyright 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
-msgid "LADSPA Host"
-msgstr "LADSPA 主æº"
-
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%s: æ æ³åå§å LIRC æ¯æ\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%s: æ æ³è¯»å LIRC é
ç½®æä»¶\n"
-"%s: 请é
读 LIRC ææ¡£\n"
-"%s: å¦ä½å»ºç«åéçé
ç½®æä»¶\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%s: å°è¯éæ°è¿æ¥ä¸...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%s: æªç¥å½ä»¤ \"%s\"\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%s: ä» LIRC æå¼\n"
+#: src/ladspa/plugin.h:78
+msgid "LADSPA Host"
+msgstr "LADSPA 主æº"
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%s: å°ä¼å¨ %d ç§åéè¯è¿æ¥...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "LIRC æä»¶"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2273,73 +2339,81 @@ msgstr ""
"\n"
"欲è·ç¥æ´å¤å
³äº LIRC çä¿¡æ¯ï¼è¯·è®¿é® http://lirc.org ."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>è¿æ¥</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "éæ°è¿æ¥ LIRC æå¡å¨"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "éè¿åçå¾
ï¼"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "LIRC æä»¶"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki æä»¶"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "没æç¸ç¬¦æè¯"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "é误"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "æ æ³åå %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "é误"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "æ æ³è§£æ %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "æ£å¨æç´¢æè¯..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "ç¼ºå°ææ²å
ä¿¡æ¯"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "æ£å¨è¿æ¥å° lyrics.wikia.com ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki æä»¶"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "LyricWiki æä»¶(Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U ææ¾å表"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "Tact çæå¨"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "èæçæå¨: æ¯åéèæä¸º %d"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "èæçæå¨: æ¯åéèæä¸º %d %d/%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2353,11 +2427,11 @@ msgstr ""
"ä¾å¦ tact://77 忝åéææ¾ 77 个èæ\n"
"æ tact://60*3/4 æ¯åéææ¾ 60 个èæäº 3/4 æ"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "Tact çæå¨"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "ééæ··åå¨"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2365,152 +2439,184 @@ msgstr ""
"Audacious ç声鿷·å卿件\n"
"Copyright 2011-2012 John Lindgren å MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>ééæ··é³å¨</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "è¾åºééï¼"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "ééæ··åå¨"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS æä»¶"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "è¿æ¥å° MMS æå¡é误"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (Module ææ¾å¨)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>å辨ç</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8 ä½"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16 ä½"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>声é</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "æè¿ç (æå¿«ç)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "çº¿æ§ (å¿«é)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "ä»¿æ · (è¾å¥½)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "å¤ç¸ (æå¥½ç)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr "<b>éæ ·ç</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "å±çº§: "
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "æªæ: "
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>åé³</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>éä½é³å¢å¼º</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>ç¯ç»</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>åç½®æ¾å¤§å¨</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "è¿åº¦éæ ·"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "åå°åªå£°"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "ææ¾ Amiga MOD æä»¶"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>éå¤</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "éå¤è®¡æ°: "
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "è¦æ°¸è¿éå¤ï¼å°éå¤è®¡æ°è°æ´ä¸º -1"
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (Module ææ¾å¨)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "ç¯ç»é³"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "è¿äºè®¾ç½®ä¼å¨éå¯ Audacious åçæã"
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 æä»¶"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>é«çº§è®¾ç½®</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "使ç¨ç²¾ç¡®é¿åº¦è®¡ç®ï¼æ
¢ï¼"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "ç¯ç»é³"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 æå¡å¨"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTP/HTTPS æä»¶"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "éå®åè§£æé误"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "æªç¥ HTTP é误"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "è§£æç½åé误"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "太å¤éå®å"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "已忢"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audaciousæªå¼å§ææ¾"
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "æ¡é¢æé"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2546,55 +2652,64 @@ msgstr ""
"You should have received a copy of the GNU General Public License along with "
"this program. If not, see <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "æ¾ç¤ºåæ¾æ§å¶"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "æ»æ¯æ¾ç¤ºæ¶æ¯æé"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "æ¡é¢æé"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "å¨éç¥ä¸æ¾ç¤ºä¸è¾å"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "æ¾ç¤º"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "æå"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "ä¸ä¸é¦"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. é»è®¤è®¾å¤"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 è¾åº"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "OSS3 è¾åº"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "é»è®¤è®¾å¤"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "é³é¢è®¾å¤ï¼"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "使ç¨å
¶å®è®¾å¤"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "ä¼è¯ä¸ä¿åé³é"
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "使ç¨OSSçæ ¼å¼è½¬æ¢ã"
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "å¼å¯ç¬å 模å¼ä»¥é¿å
èææ··åã"
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2608,19 +2723,35 @@ msgstr ""
"æå¸ææè°¢ #audacious ä¸ç人们ï¼å°¤å
¶ Tony Vroon å John Lindgrenï¼å½ç¶ï¼è¿æ"
"ä¹å OSS æä»¶çä½è
们ã"
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 è¾åº"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "ææ¾å表管çå¨"
+
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "æ¡ç®"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "ç§»é¤(_R)"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "éå½å(_a)"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS ææ¾å表"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1/PSF2 è§£ç å¨"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio è¾åº"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2656,11 +2787,73 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio è¾åº"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "QtMultimedia è¾åº"
+
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"Audacious QtMultimedia é³é¢è¾åºæä»¶\n"
+"William Pitcock 2014 çæææ\n"
+"\n"
+"åºäºAudacious SDL è¾åºæä»¶\n"
+"John Lindgren 2010 çæææ"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "å·¥ä½ä¸ ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "æç´¢"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "æå¼æä»¶å¤¹ ... (&O)"
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "æ·»å æä»¶å¤¹ ... (Add)"
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "æ¥å¿çè§(_L) ..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "æå¼æä»¶"
-#: src/resample/resample.c:165
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "æ·»å æä»¶"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ä¸ä¸é¦"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "éå¤"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "éæº"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Qt çé¢"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "éæ ·ç转æ¢å¨"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2668,96 +2861,104 @@ msgstr ""
"Audacious çæ½æ ·ç转æ¢å¨æä»¶\n"
"Copyright 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "è·³è¿/é夿 ·æ¬"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "çº¿æ§æå¼"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "å¿«é sinc æå¼"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "ä¸ç sinc æå¼"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "æä½³ sinc æå¼"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>转æ¢</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "æ¹æ³ï¼"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "æ¯çï¼"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>æ¯çæ å°</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "æ¯çæ å°ï¼"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHz:"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHz:"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHz:"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHz:"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHz:"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHz:"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHz:"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHz:"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHz:"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHz:"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "éæ ·ç转æ¢å¨"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "æå®ãæ£å¨ä¸ºç¨æ· %s Scrobble"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "æé黿¢"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr "请访é®å¦ä¸é¾æ¥ä»¥å
许 Audacious Scrobble ä½ çææ¾å表: "
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr "ä¿ææ¤çªå£å¹¶å次ç¹å» 'æ£æ¥æé'ã\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2765,32 +2966,36 @@ msgstr ""
"ä¸è¦æ
å¿ãä½ ç Scrobble å·²ä¿åå°äºè®¡ç®æºä¸ã\n"
"ä»ä»¬å°å¨ Audacious 被å
è®¸æ¶æäº¤ã"
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "ç½ç»é®é¢ã"
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "å¨è®¿é® Last.fm æ¶éå°é®é¢ã请ç¨åéè¯ã"
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "æ£å¨æ£ç´¢â¦â¦"
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
-msgstr "æ£æ¥æé"
+msgstr "æ£æ¥æé(_C)"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
-msgstr "åéæé"
+msgstr "åéæé(_R)"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr "ä½ éè¦å
许 Audacious 以 Scrobble ä½ Last.fm 叿·ä¸çé³ä¹ã\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2798,7 +3003,7 @@ msgstr ""
"Scrobbler æä»¶æ æ³å¯å¨ã\n"
"ä½ çå®è£
å¯è½åå¨é®é¢ã"
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2815,11 +3020,7 @@ msgstr ""
"æè°¢ John Lindgren å¨é¡¹ç®åå§é¶æ®µæä¾ç帮å©\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2827,7 +3028,11 @@ msgstr ""
"Audacious ç®åæ£å¨ä½¿ç¨ä¸ä¸ªå¢å¼ºçç Last.fm Scrobbler.\n"
"è¯·æ£æ¥ Scrobbler æä»¶çé¦é项ã"
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL è¾åº"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2835,750 +3040,823 @@ msgstr ""
"Audacious ç SDL è¾åºæä»¶\n"
"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL è¾åº"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "åº"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "æªç¥èºæ¯å®¶"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "æªç¥ä¸è¾"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-"ä½äº %s ä¸ç %s"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d ä¸ªç»æ"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d å¼ ä¸è¾"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d 个éèç)"
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-"%s, %d 馿æ²"
-
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d 馿"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "å±äºæ¤é£æ ¼"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "å¨"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "-"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
-msgstr "åå»ºææ¾å表"
+msgstr "åå»ºææ¾å表(_C)"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
-msgstr "æ·»å å°ææ¾å表"
+msgstr "æ·»å å°ææ¾å表(_A)"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "æç´¢åº"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr "è¦å°æ¨çé³ä¹åºå¯¼å
¥Audaciousï¼éæ©ä¸ä¸ªæä»¶å¤¹ï¼ç¶åç¹å»âå·æ°â徿 ã"
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "请ç¨ç...."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "éæ©æä»¶å¤¹"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "SID ææ¾å¨"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>è¾åº</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "声鿰ï¼"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>仿ç</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "仿ç MOS 8580 (é»è®¤ä¸ºï¼MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "ä¸è¦èªå¨éæ©è¯ç模æ¿"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "仿çè¿æ»¤å¨"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "æ¶ééçï¼"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "ä¸è¦èªå¨éæ©æ¶ééç"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>ææ¾æ¶é´</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "ä½¿ç¨æå¤§ææ¾æ¶é´ï¼"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "ä»
彿æ²é¿åº¦æªç¥æ¶ä½¿ç¨"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "设置æå¤§ææ¾æ¶é´ï¼"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Subtunes</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "å¯ç¨subtunes"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "忽ç¥çsubtunesçäºï¼"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>é³ç¬¦</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "éé³ç§»é¤"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"Audacious éé³ç§»é¤æä»¶\n"
+"John Lindgren 2014 çæææ"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>éé³ç§»é¤</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "éå¼ï¼"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "æå¼æä»¶ ..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "æå¼ URL ..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "æç´¢åº"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "åæ¾"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "ææ¾å表"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "å¤è§"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "æå¡"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "å
³äº ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "设置 ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "éåº"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "ææ²ä¿¡æ¯ ..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "éå¤"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "éæº"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "ç¦æ¢èªå¨ææ¾ä¸ä¸é¦"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "å¨è¿é¦æå忢"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ä¸ä¸é¦"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "设置 A-B ç¹éå¤"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "æ¸
é¤ A-B ç¹éå¤"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "è·³è³æ²ç® ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "è·³è³æ¶é´ ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "ææ¾æ¤ææ¾å表"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "ææ¾/ç»§ç»"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "æ°å»ºææ¾å表"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "éå½åææ¾å表 ..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "ç§»é¤ææ¾å表"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "ä¸ä¸ä¸ªææ¾å表"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "ä¸ä¸ä¸ªææ¾å表"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "导å
¥ææ¾å表"
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "å¯¼åºææ¾å表 ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "ææ¾å表管çå¨ ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "éå管çå¨ ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "å·æ°ææ¾å表"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "æ¾ç¤ºææ¾å表ç¼è¾å¨"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "æ¾ç¤ºåè¡¡å¨"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "æ¾ç¤ºéå½åæ¶é´"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "é¡¶ç½®çªå£"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "ææå·¥ä½åºå¯è§"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "æ¶èµ·ææ¾å¨"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "æ¶èµ·ææ¾å表ç¼è¾å¨"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "æ¶èµ·åè¡¡å¨"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "åå大å°"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "æ·»å URL ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "æ·»å æä»¶ ..."
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "ææ é¢"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
-msgstr "æ ¹æ®æä»¶å"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
+msgstr "ææä»¶å"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "ææä»¶è·¯å¾"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "æ¸
空"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "æ¸
空éå"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "å é¤ä¸å¯ç¨æä»¶"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "å é¤éå¤çæ¡ç®"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "å 餿ªè¢«éä¸ç"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "å é¤å·²éä¸ç"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "æç´¢/éæ©"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "åé"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "åæ¶éä¸"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "éä¸å
¨é¨"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "æä¸è¾"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "æé³è½¨å·ç "
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "æèºæ¯å®¶"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "æä¸è¾"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "æä¸è¾èºæ¯å®¶"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "æåè¡¨æ¥æ"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "æé³è½¨å·ç "
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "æç
§ç±»å"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "æç
§é¿åº¦"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "æç
§èªå®ä¹æ é¢"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "æä¹±å表"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "å转å表"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "æåºå·²éä¸ç"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "æåºå表"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "åªå"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "å¤å¶"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "ç²è´´"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "å å
¥/ç§»åºå表"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "è½½å
¥é¢è®¾ ..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "è½½å
¥èªå¨è½½å
¥é¢è®¾ ..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "è½½å
¥é¢è®¾å¼"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "è½½å
¥é¢è®¾æä»¶ ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "è½½å
¥ EQF æä»¶ ..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "ä¿åé¢è®¾ ..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "ä¿åèªå¨å è½½é¢è®¾ ..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "ä¿å为é»è®¤å¼"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "ä¿åé¢è®¾æä»¶ ..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "ä¿å EQF æä»¶ ..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "å é¤é¢è®¾ ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "å é¤èªå¨é¢è®¾ ..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "导å
¥ WinAMP é¢è®¾ ..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "å½é¶"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winamp ç»å
¸çé¢"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "ä¿å"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "è½½å
¥"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "è½½å
¥é¢è®¾æä»¶"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "è½½å
¥ EQF æä»¶"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "ä¿åé¢è®¾æä»¶"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "ä¿å EQF æä»¶"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "导å
¥ WinAMP é¢è®¾"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "é¢è®¾"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "è½½å
¥é¢è®¾"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "è½½å
¥èªå¨è½½å
¥é¢è®¾"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "ä¿åé¢è®¾"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "ä¿åèªå¨å è½½é¢è®¾"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "å é¤é¢è®¾"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "å é¤èªå¨å è½½é¢è®¾"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "ææ¾å¨(_P)ï¼"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "ææ¾å¨ï¼"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "鿩䏻çé¢åä½"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "ææ¾å表(_P)ï¼"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "ææ¾å表ï¼"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "éæ©ææ¾å表åä½ï¼"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>ç®è¤</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>åä½</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "使ç¨ç¹éµåä½ï¼ä»
æ¯æASCIIå符ï¼"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "æ»å¨æ²ç®æ é¢"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "æ¥åæ»å¨ææ²æ é¢"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "åæå¨"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "示波å¨"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "声纹 / VU 表"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "å
³é"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "ä¸è¬"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "ç«ç"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "ç«çº¿"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "ç»çº¿"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "æ±ç¶"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "ææ
¢"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "æ
¢"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "ä¸é"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "å¿«"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "æå¿«"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "ç¹"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "线"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "è²å"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "å·è"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "å¹³æ»"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>ç±»å</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "å¯è§åç±»å: "
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>åæå¨</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "æ¾ç¤ºå³°å¼"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "ä¸è²: "
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "飿 ¼: "
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "åé: "
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "å³°å¼åéé度: "
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "示波å¨é£æ ¼: "
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "声纹ä¸è²: "
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "VU è¡¨é£æ ¼: "
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "常è§"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "å¯è§åææ"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "åç½®æ¾å¤§"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 赫å
¹"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 赫å
¹"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 赫å
¹"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 赫å
¹"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "200 赫å
¹"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1000 赫å
¹"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2000 赫å
¹"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4000 赫å
¹"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8000 赫å
¹"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16000 赫å
¹"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audaciousåè¡¡å¨"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "æ¥æ¾ï¼ %d:%-2.2d/%d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "é³éï¼%d%%"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "平衡ï¼%d%% å·¦"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "平衡ï¼ä¸é´"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "平衡ï¼%d%% å³"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "é项èå"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "ç¦ç¨âé¡¶ç½®çªå£â"
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "å¯ç¨âé¡¶ç½®çªå£â"
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "æä»¶ä¿¡æ¯"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "å¯è§åææ"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "éå¤ç¹ A 已设置ã"
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "éå¤ç¹ B 已设置ã"
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "éå¤ç¹å·²æ¸
é¤ã"
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "åä¸çªå£æ¨¡å¼"
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "ææ¾å表模å¼"
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "宿å忢"
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "ä»å½åææ¾åè¡¨ä¸æç´¢æ¡ç®"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "æç´¢"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3588,57 +3866,61 @@ msgstr ""
"æé¨ååæ®µæç´¢ææ¾å表ä¸çæ¡ç®ãåä¸ªåæ®µé½å¯ä»¥ä½¿ç¨æ£å表达å¼ï¼è䏿¯ä¸å大å°"
"åçãå¦æä½ ä¸ç¥éä½ä¸ºæ£å表达å¼ï¼ç®åçè¾å
¥é¨åä½ æ³æç´¢çæå亦å¯ã"
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
msgstr "æ é¢ï¼"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr "ä¸è¾ï¼"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr "èºæ¯å®¶ï¼"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
-msgstr "æä»¶å"
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
+msgstr "æä»¶åï¼"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "æç´¢åæ¸
空ä¹åçç»æ"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "èªå¨ä¸ºåºé
æ¡ç®åæ¢éå"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "ç¨å¹é
çæ¡ç®å建æ°çææ¾å表"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audaciousææ¾å表ç¼è¾å¨"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%d of %d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "å·²æå
çWinamp 2.x主é¢"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "æªæå
çWinamp 2.x主é¢"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "æ æ³å建ç®å½(%s)ï¼%s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile æä»¶"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3678,81 +3960,71 @@ msgstr ""
"this program; if not, write to the Free Software Foundation, Inc., 51 "
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile æä»¶"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "å
³äº Sndio è¾åºæä»¶"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Sndio è¾åº"
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Sndio Output æä»¶\n"
-"\n"
-"ä½è
Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "设å¤(é»è®¤ä¸ºç©º)ï¼"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "䏿¯æçæ ¼å¼"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "ä¿åå¹¶æ¢å¤é³éï¼"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"æè¯·æ±ç声é³è®¾å¤ä¸æ¯æè¿ç§æ ¼å¼ã\n"
-"\n"
-"请éè¯ï¼å¹¶ä¸ä¿æ sndiod(1) æå¡å¨çè¿è¡ã"
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Sndio é误ï¼ä¸æ¯æé³é¢æ ¼å¼(%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio 设å¤ï¼"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Sndio éè¯¯ï¼ sio_open() failed"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(空代表é»è®¤)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Sndio éè¯¯ï¼ sio_setpar() failed"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "ç¡®å®"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Sndio éè¯¯ï¼ sio_start() failed"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "ææ²æ¹å"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "ææ²å¼å§ææ¾æ¶æ§è¡æä»¤ã"
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>ä¼ éå°Shellçåæ°ä¸å®è¦ç¨å¼å·å
å´ï¼å¦å伿¯ä¸ä»¶ç¸å½å±é©ç"
+"äºã</span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>å½ä»¤</b>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "æä»¤ï¼"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "å¼å§ææ¾æ°ææ²æ¶è¿è¡å½ä»¤ï¼"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "ææ²å³å°å®ææ¶æ§è¡æä»¤ã"
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "ææ²ç»æææ¾æ¶è¿è¡å½ä»¤ï¼"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "å½Audaciousææ¾å°å表ç»å°¾æ¶æ§è¡æä»¤ã"
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "ææ¾åè¡¨ç»ææ¶è¿è¡å½ä»¤ï¼"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
-msgstr "ææ²çæ é¢æ¹åæ¶æ§è¡æä»¤(å¦ï¼ç½ç»åªä½çæ é¢)ã"
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr "ææ²æ 颿¹åæ¶è¿è¡å½ä»¤(ç¨äºç½ç»æµåªä½)ï¼"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3766,35 +4038,29 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"ä½ å¯ä»¥ä½¿ç¨ä»¥ä¸çæ ¼å¼åå符串ï¼å½ä»¤è°ç¨åï¼\n"
-"å®ä»¬ä¼è¢«è½¬æ¢ä¸ºç¸åºçå¼ã\n"
-"(é¨åå符串å¨end-of-playlistå½ä»¤ä¸æ æ)\n"
+"ä½ å¯ä»¥ä½¿ç¨ä¸åæ ¼å¼çæ¿ä»£ç¬¦ (å¹¶éææé½éç¨äºâææ¾åè¡¨ç»æåæ§è¡å½ä»¤â):\n"
"\n"
-"%F: é¢ç (åä½ï¼Hz)\n"
+"%F: é¢ç (Hz)\n"
"%c: 声鿰\n"
"%f: æä»¶å (宿´è·¯å¾)\n"
-"%l: é¿åº¦ (åä½ï¼æ¯«ç§)\n"
+"%l: é¿åº¦ (毫ç§)\n"
"%n æ %s: ææ²å\n"
-"%r: æ¯ç (åä½ï¼ bit/ç§)\n"
+"%r: æ¯ç¹ç (æ¯ç§æ¯ç¹æ°)\n"
"%t: ææ¾å表ä½ç½® (%02d)\n"
-"%p: å½åææ¾æ²ç® (1 or 0)\n"
+"%p: å½åæ£å¨ææ¾(1 æ 0)\n"
"%a: èºæ¯å®¶\n"
"%b: ä¸è¾\n"
-"%T: é³è½¨æ é¢"
+"%T: æ²ç®æ é¢"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>ä¼ éå°Shellçåæ°ä¸å®è¦ç¨å¼å·å
å´ï¼å¦å伿¯ä¸ä»¶ç¸å½å±é©ç"
-"äºã</span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "ææ²ä¿¡æ¯ (Qt)"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "æä»¤"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX ééæ ·å¨"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3808,51 +4074,51 @@ msgstr ""
"åºäºåæ ·ç转æ¢å¨æä»¶:\n"
"Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "å¿«é"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "ä½"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "é«"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "é常é«"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "é³è´¨: "
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX ééæ ·å¨"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "é度åé³è°"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>é度åé³è°</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "é度ï¼"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "é³è°ï¼"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "é度åé³è°"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "ç¶æå¾æ "
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
-msgstr "设置 (&T)"
+msgstr "设置... (_t)"
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3869,39 +4135,39 @@ msgstr ""
"\n"
"æ¤æä»¶æä¾ä¸ä¸ªç¶æå¾æ ï¼æ¾ç½®äºç³»ç»æçä½ç½®ã"
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>é¼ æ æ»è½®å¨ä½</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "è°æ´é³é"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "æ¹åææ²"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>å
¶ä»è®¾ç½®</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "ç¦ç¨å¼¹åºçªå£"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "å
³éç³»ç»æç"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "åä¸å·å¨æ¶æ¾ç¤ºå¨ææ¾å表顶é¨"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "ç¶æå¾æ "
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "Extra Stereo"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3911,24 +4177,24 @@ msgstr ""
"\n"
"ä½è
: Johan Levin 1999."
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>Extra Stereo</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "Extra Stereo"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "Tone Generator"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "é³è°çæå¨: "
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3942,15 +4208,11 @@ msgstr ""
"è¦ä½¿ç¨è¿ä¸ªçæå¨ï¼æ·»å ä¸ä¸ª URLï¼tone://frequency1;frequency2;frequency3;...\n"
"å®ä¾ tone://2000;2005 ä»¥ææ¾ä¸ä¸ª 2000 Hz 以å 2005 Hz çé³è°"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "Tone Generator"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "人声æ¶é¤"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3988,11 +4250,46 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis è§£ç å¨"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "%s çç»è"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"æ é¢: %t\n"
+"ä½è
: %a\n"
+"æ¥èª: %f\n"
+"tracker: %T\n"
+"注é: %C\n"
+"è¯çç±»å: %c\n"
+"ç«ä½å£°: %s\n"
+"循ç¯: %l\n"
+"è¯çé¢ç: %F\n"
+"ææ¾å¨é¢ç: %P\n"
+"年代: %y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX è§£ç å¨"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4002,19 +4299,19 @@ msgstr ""
"åºäº Roman Sherbakov <v_soft at microfor.ru> å¶ä½ç in_vtx.dll\n"
"Audacious æä»¶ä½è
为 Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX è§£ç å¨"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack è§£ç å¨"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "ææç (æ··å)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "ææç"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4024,23 +4321,18 @@ msgstr ""
"\n"
"ä¸é¨åæä»¶ä»£ç ç± Miles Egan ç¼åã"
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack è§£ç å¨"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF è§£ç å¨"
-#: src/xspf/xspf.c:438
-msgid "XML Shareable Playlists (XSPF)"
-msgstr "å¯å享ç XML ææ¾å表 (XSPF)"
-
-#~ msgid "32.0 kHz:"
-#~ msgstr "32.0 kHz:"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>XSF 设置</b>"
-#~ msgid "88.2 kHz:"
-#~ msgstr "88.2 kHz:"
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "å¿½ç¥æä»¶é¿åº¦"
-#~ msgid "176.4 kHz:"
-#~ msgstr "176.4 kHz:"
+#: src/xspf/xspf.cc:89
+msgid "XML Shareable Playlists (XSPF)"
+msgstr "å¯å享ç XML ææ¾å表 (XSPF)"
diff --git a/po/zh_TW.po b/po/zh_TW.po
index 402941083caf..3c3ec134f8fb 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -3,15 +3,15 @@
# This file is distributed under the same license as the Audacious Plugins package.
#
# Translators:
-# çå
ç§ <rueiyuan.lu at gmail.com>, 2014
+# Ruei-Yuan Lu <rueiyuan.lu at gmail.com>, 2014
# Ruei-Yuan Lu <RueiYuan.Lu at gmail.com>, 2011
msgid ""
msgstr ""
-"Project-Id-Version: Audacious Plugins Plugins\n"
+"Project-Id-Version: Audacious Plugins\n"
"Report-Msgid-Bugs-To: http://redmine.audacious-media-player.org/\n"
-"POT-Creation-Date: 2014-04-21 23:02+0200\n"
-"PO-Revision-Date: 2014-04-17 08:21+0000\n"
-"Last-Translator: çå
ç§ <rueiyuan.lu at gmail.com>\n"
+"POT-Creation-Date: 2015-02-28 19:18+0100\n"
+"PO-Revision-Date: 2015-02-25 03:48+0000\n"
+"Last-Translator: Ruei-Yuan Lu <rueiyuan.lu at gmail.com>\n"
"Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/"
"audacious/language/zh_TW/)\n"
"Language: zh_TW\n"
@@ -20,40 +20,28 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:82
-msgid "mono"
-msgstr "å®è²é"
-
-#: src/aac/libmp4.c:98 src/gtkui/ui_statusbar.c:84
-msgid "stereo"
-msgstr "ç«é«è²"
-
-#: src/aac/libmp4.c:98
-msgid "surround"
-msgstr "ç°ç¹"
-
-#: src/aac/libmp4.c:313
-msgid "AAC (MP4) Decoder"
-msgstr "AAC (MP4) 解碼å¨"
-
-#: src/aac-raw/aac.c:476
+#: src/aac-raw/aac.cc:18
msgid "AAC (Raw) Decoder"
msgstr "AAC (Raw) 解碼å¨"
-#: src/adplug/adplug-xmms.cc:137 src/modplug/modplugbmp.cxx:348
-#: src/psf/plugin.c:122 src/vtx/vtx.c:62 src/xsf/plugin.c:80
+#: src/adplug/adplug-xmms.cc:42
+msgid "AdPlug (AdLib Player)"
+msgstr "AdPlug (AdLib ææ¾å¨)"
+
+#: src/adplug/adplug-xmms.cc:156 src/modplug/modplugbmp.cc:335
+#: src/psf/plugin.cc:138 src/vtx/vtx.cc:87 src/xsf/plugin.cc:113
msgid "sequenced"
msgstr "ç·¨æ²æ©"
-#: src/adplug/plugin.c:14
-msgid "AdPlug (AdLib Player)"
-msgstr "AdPlug (AdLib ææ¾å¨)"
+#: src/alarm/alarm.cc:55 src/alarm/interface.cc:82
+msgid "Alarm"
+msgstr "鬧é"
-#: src/alarm/alarm.c:778
+#: src/alarm/alarm.cc:782
msgid "Set Alarm ..."
msgstr "è¨å®é¬§é ..."
-#: src/alarm/alarm.c:806
+#: src/alarm/alarm.cc:810
msgid ""
"A plugin that can be used to start playing at a certain time.\n"
"\n"
@@ -63,11 +51,7 @@ msgstr ""
"\n"
"Originally written by Adam Feakin and Daniel Stodden."
-#: src/alarm/alarm.c:811 src/alarm/interface.c:86
-msgid "Alarm"
-msgstr "鬧é"
-
-#: src/alarm/interface.c:32
+#: src/alarm/interface.cc:28
msgid ""
"Time\n"
" Alarm at:\n"
@@ -108,7 +92,7 @@ msgstr ""
"\n"
"\n"
-#: src/alarm/interface.c:49
+#: src/alarm/interface.cc:45
msgid ""
"Volume\n"
" Fading:\n"
@@ -148,7 +132,7 @@ msgstr ""
" 鬧éè§¸ç¼æå·è¡éåæä»¤ã\n"
"\n"
-#: src/alarm/interface.c:66
+#: src/alarm/interface.cc:62
msgid ""
" Playlist:\n"
" Load this playlist. If no playlist\n"
@@ -172,384 +156,390 @@ msgstr ""
" è¥æ¨å¸æå®è¢«é¡¯ç¤ºï¼è«å¾é¸ä¸¦å¨æ¬\n"
" ä½ä¸è¼¸å
¥è¨æ¯ã"
-#: src/alarm/interface.c:85
+#: src/alarm/interface.cc:81
msgid "This is your wakeup call."
msgstr "鿝æ¨çåéã"
-#: src/alarm/interface.c:103
+#: src/alarm/interface.cc:99
msgid "Your reminder for today is..."
msgstr "æ¨ä»å¤©çæé"
-#: src/alarm/interface.c:105 src/alarm/interface.c:417
+#: src/alarm/interface.cc:101 src/alarm/interface.cc:386
msgid "Reminder"
msgstr "æé"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Monday"
msgstr "ææä¸"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Tuesday"
msgstr "ææäº"
-#: src/alarm/interface.c:144
+#: src/alarm/interface.cc:132
msgid "Wednesday"
msgstr "ææä¸"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Thursday"
msgstr "ææå"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Friday"
msgstr "ææäº"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Saturday"
msgstr "ææå
"
-#: src/alarm/interface.c:145
+#: src/alarm/interface.cc:133
msgid "Sunday"
msgstr "æææ¥"
-#: src/alarm/interface.c:179
-msgid "Alarm Settings"
-msgstr "鬧éè¨å®"
-
-#: src/alarm/interface.c:180 src/filewriter/mp3.c:690
-msgid "_OK"
-msgstr "確èª(_O)"
-
-#: src/alarm/interface.c:180 src/amidi-plug/i_configure-fluidsynth.c:55
-#: src/aosd/aosd_ui.c:930 src/filewriter/mp3.c:690 src/hotkey/gui.c:486
-msgid "_Cancel"
-msgstr "åæ¶(_C)"
-
-#: src/alarm/interface.c:188 src/alarm/interface.c:252
-#: src/alarm/interface.c:267
+#: src/alarm/interface.cc:171 src/alarm/interface.cc:230
+#: src/alarm/interface.cc:245
msgid "Time"
msgstr "æé"
-#: src/alarm/interface.c:195
+#: src/alarm/interface.cc:178
msgid "Alarm at (default):"
msgstr "é´é¿æ¼ (é è¨)"
-#: src/alarm/interface.c:218
+#: src/alarm/interface.cc:200
msgid "h"
msgstr "h"
-#: src/alarm/interface.c:222
+#: src/alarm/interface.cc:203
msgid "Quiet after:"
msgstr "å¤ä¹
å¾éé³ï¼"
-#: src/alarm/interface.c:236
+#: src/alarm/interface.cc:215
msgid "hours"
msgstr "å°æ"
-#: src/alarm/interface.c:248
+#: src/alarm/interface.cc:226
msgid "minutes"
msgstr "åé"
-#: src/alarm/interface.c:257
+#: src/alarm/interface.cc:235
msgid "Choose the days for the alarm to come on"
msgstr "鏿æ³è¦å¨åªå¹¾å¤©åç¨é¬§é"
-#: src/alarm/interface.c:264
+#: src/alarm/interface.cc:242
msgid "Day"
msgstr "åªå¹¾å¤©"
-#: src/alarm/interface.c:282 src/bs2b/plugin.c:168 src/skins/preset-list.c:439
-#: src/skins/preset-list.c:445
+#: src/alarm/interface.cc:259 src/bs2b/plugin.cc:130
+#: src/skins/preset-list.cc:434 src/skins/preset-list.cc:440
msgid "Default"
msgstr "é è¨"
-#: src/alarm/interface.c:312
+#: src/alarm/interface.cc:288
msgid "Days"
msgstr "鱿ç¨"
-#: src/alarm/interface.c:321
+#: src/alarm/interface.cc:297
msgid "Fading"
msgstr "æ·¡åº"
-#: src/alarm/interface.c:329 src/console/plugin.c:41
-#: src/crossfade/crossfade.c:263 src/gtkui/settings.c:53 src/lirc/lirc.c:395
+#: src/alarm/interface.cc:305 src/console/plugin.cc:41
+#: src/crossfade/crossfade.cc:53 src/crossfade/crossfade.cc:59
+#: src/gtkui/settings.cc:49 src/lirc/lirc.cc:397 src/sid/xs_config.cc:85
+#: src/sid/xs_config.cc:94 src/sid/xs_config.cc:103
msgid "seconds"
msgstr "ç§"
-#: src/alarm/interface.c:336 src/alarm/interface.c:383
+#: src/alarm/interface.cc:312 src/alarm/interface.cc:353
msgid "Volume"
msgstr "é³é"
-#: src/alarm/interface.c:341
+#: src/alarm/interface.cc:317
msgid "Start at"
msgstr "åå§é³é"
-#: src/alarm/interface.c:359
+#: src/alarm/interface.cc:333
msgid "Final"
msgstr "æçµé³é"
-#: src/alarm/interface.c:374
+#: src/alarm/interface.cc:346
msgid "Current"
msgstr "ç®åé³é"
-#: src/alarm/interface.c:389
+#: src/alarm/interface.cc:359
msgid "Additional Command"
msgstr "é¡å¤å½ä»¤"
-#: src/alarm/interface.c:395 src/alarm/interface.c:422
+#: src/alarm/interface.cc:365 src/alarm/interface.cc:391
msgid "enable"
msgstr "åç¨"
-#: src/alarm/interface.c:402
+#: src/alarm/interface.cc:372
msgid "Playlist (optional)"
msgstr "ææ¾æ¸
å® (é¸ç¨)"
-#: src/alarm/interface.c:409
+#: src/alarm/interface.cc:379
msgid "Select a playlist"
msgstr "è«é¸æææ¾æ¸
å®"
-#: src/alarm/interface.c:430
+#: src/alarm/interface.cc:399
msgid "Options"
msgstr "é¸é
"
-#: src/alarm/interface.c:435
+#: src/alarm/interface.cc:404
msgid "What do these options mean?"
msgstr "éäºé¸é
代表ä»éº¼ææï¼"
-#: src/alarm/interface.c:449
+#: src/alarm/interface.cc:420
msgid "Help"
msgstr "說æ"
-#: src/albumart/albumart.c:72
+#: src/albumart/albumart.cc:31
msgid "Album Art"
msgstr "å°è¼¯å°é¢"
-#: src/alsa/config.c:210
+#: src/albumart-qt/albumart.cc:33
+msgid "Album Art (Qt)"
+msgstr "å°è¼¯å°é¢ (Qt)"
+
+#: src/alsa/alsa.h:70
+msgid "ALSA Output"
+msgstr "ALSA 輸åº"
+
+#: src/alsa/config.cc:28
+msgid ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+msgstr ""
+"ALSA Output Plugin for Audacious\n"
+"Copyright 2009-2012 John Lindgren\n"
+"\n"
+"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+"code served as a reference when the ALSA manual was not enough."
+
+#: src/alsa/config.cc:61
+msgid "(no description)"
+msgstr "(ç¡æè¿°è¨æ¯)"
+
+#: src/alsa/config.cc:166
msgid "Default PCM device"
msgstr "é è¨ PCM è£ç½®"
-#: src/alsa/config.c:239
+#: src/alsa/config.cc:188
msgid "Default mixer device"
msgstr "é è¨æ··é³å¨è£ç½®"
-#: src/alsa/config.c:428
+#: src/alsa/config.cc:296
msgid "PCM device:"
msgstr "PCM è£ç½®ï¼"
-#: src/alsa/config.c:430
+#: src/alsa/config.cc:299
msgid "Mixer device:"
msgstr "æ··é³å¨è£ç½®ï¼"
-#: src/alsa/config.c:432
+#: src/alsa/config.cc:302
msgid "Mixer element:"
msgstr "æ··é³å¨å
ä»¶ï¼"
-#: src/alsa/config.c:435
-msgid "Work around drain hangup"
-msgstr "èçæ¬ è¼éæ»"
+#: src/amidi-plug/amidi-plug.cc:41
+msgid "AMIDI-Plug (MIDI Player)"
+msgstr "AMIDI-Plug (MIDI ææ¾å¨)"
-#: src/alsa/plugin.c:27
+#: src/amidi-plug/amidi-plug.cc:437
msgid ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
msgstr ""
-"ALSA Output Plugin for Audacious\n"
-"Copyright 2009-2012 John Lindgren\n"
+"AMIDI-Plug\n"
+"modular MIDI music player\n"
+"http://www.develia.org/projects.php?p=amidiplug\n"
"\n"
-"My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
-"code served as a reference when the ALSA manual was not enough."
-
-#: src/alsa/plugin.c:41
-msgid "ALSA Output"
-msgstr "ALSA 輸åº"
-
-#: src/amidi-plug/amidi-plug.c:466
-msgid "AMIDI-Plug (MIDI Player)"
-msgstr "AMIDI-Plug (MIDI ææ¾å¨)"
+"written by Giacomo Lozito\n"
+"<james at develia.org>\n"
+"\n"
+"special thanks to...\n"
+"\n"
+"Clemens Ladisch and Jaroslav Kysela\n"
+"for their cool programs aplaymidi and amixer; those\n"
+"were really useful, along with alsa-lib docs, in order\n"
+"to learn more about the ALSA API\n"
+"\n"
+"Alfredo Spadafina\n"
+"for the nice midi keyboard logo\n"
+"\n"
+"Tony Vroon\n"
+"for the good help with alpha testing"
-#: src/amidi-plug/i_configure.c:96
+#: src/amidi-plug/i_configure.cc:94
msgid "Override default gain:"
msgstr "è¦è¼é è¨çå¢çå¼ï¼"
-#: src/amidi-plug/i_configure.c:102
+#: src/amidi-plug/i_configure.cc:102
msgid "Override default polyphony:"
msgstr "è¦è¼é è¨çåæç¼é³æ¸ï¼"
-#: src/amidi-plug/i_configure.c:108
+#: src/amidi-plug/i_configure.cc:110
msgid "Override default reverb:"
msgstr "è¦è¼é è¨çæ®é¿å¼·åº¦ï¼"
-#: src/amidi-plug/i_configure.c:110 src/amidi-plug/i_configure.c:116
+#: src/amidi-plug/i_configure.cc:112 src/amidi-plug/i_configure.cc:120
msgid "On"
msgstr "åç¨"
-#: src/amidi-plug/i_configure.c:114
+#: src/amidi-plug/i_configure.cc:118
msgid "Override default chorus:"
msgstr "è¦è¼é è¨åè²å¼·åº¦ï¼"
-#: src/amidi-plug/i_configure.c:122 src/console/plugin.c:33
+#: src/amidi-plug/i_configure.cc:128 src/console/plugin.cc:29
msgid "<b>Playback</b>"
msgstr "<b>ææ¾</b>"
-#: src/amidi-plug/i_configure.c:123
+#: src/amidi-plug/i_configure.cc:129
msgid "Transpose:"
msgstr "移調ï¼"
-#: src/amidi-plug/i_configure.c:125
+#: src/amidi-plug/i_configure.cc:131
+msgid "semitones"
+msgstr "åé³"
+
+#: src/amidi-plug/i_configure.cc:132
msgid "Drum shift:"
msgstr "é¼ç§»ï¼"
-#: src/amidi-plug/i_configure.c:127
-msgid "<b>Advanced</b>"
-msgstr "<b>é²é</b>"
+#: src/amidi-plug/i_configure.cc:134
+msgid "note numbers"
+msgstr "é³ç¬¦æ¸é"
-#: src/amidi-plug/i_configure.c:128
-msgid "Extract comments from MIDI file"
-msgstr "æ½å MIDI æªçåè¨»è³æ"
+#: src/amidi-plug/i_configure.cc:135
+msgid "Skip leading silence"
+msgstr "è·³ééé çéé³"
-#: src/amidi-plug/i_configure.c:130
-msgid "Extract lyrics from MIDI file"
-msgstr "æ½å MIDI æªçæè©è³æ"
+#: src/amidi-plug/i_configure.cc:137
+msgid "Skip trailing silence"
+msgstr "è·³éçµå°¾çéé³"
-#: src/amidi-plug/i_configure.c:134
+#: src/amidi-plug/i_configure.cc:141
msgid "<b>SoundFont</b>"
msgstr "<b>SoundFont</b>"
-#: src/amidi-plug/i_configure.c:136
+#: src/amidi-plug/i_configure.cc:143
msgid "<b>Synthesizer</b>"
msgstr "<b>åæå¨</b>"
-#: src/amidi-plug/i_configure.c:141
-msgid "Sampling rate:"
+#: src/amidi-plug/i_configure.cc:148 src/console/plugin.cc:45
+#: src/sid/xs_config.cc:65
+msgid "Sample rate:"
msgstr "忍£çï¼"
-#: src/amidi-plug/i_configure-fluidsynth.c:52
+#: src/amidi-plug/i_configure.cc:150 src/bs2b/plugin.cc:141
+#: src/console/plugin.cc:47 src/modplug/plugin_main.cc:78
+#: src/resample/resample.cc:201 src/resample/resample.cc:207
+#: src/resample/resample.cc:211 src/resample/resample.cc:215
+#: src/resample/resample.cc:219 src/resample/resample.cc:223
+#: src/resample/resample.cc:227 src/resample/resample.cc:231
+#: src/resample/resample.cc:235 src/resample/resample.cc:239
+#: src/resample/resample.cc:243 src/sid/xs_config.cc:67
+#: src/sox-resampler/sox-resampler.cc:163
+msgid "Hz"
+msgstr "Hz"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:52
msgid "AMIDI-Plug - select SoundFont file"
msgstr "AMIDI-Plug - 鏿 SoundFont æªæ¡"
-#: src/amidi-plug/i_configure-fluidsynth.c:56
+#: src/amidi-plug/i_configure-fluidsynth.cc:55 src/filewriter/mp3.cc:658
+msgid "_Cancel"
+msgstr "åæ¶(_C)"
+
+#: src/amidi-plug/i_configure-fluidsynth.cc:56
msgid "_Open"
msgstr "éå(_O)"
-#: src/amidi-plug/i_configure-fluidsynth.c:227
-msgid "Filename"
+#: src/amidi-plug/i_configure-fluidsynth.cc:225 src/gtkui/columns.cc:46
+msgid "File name"
msgstr "æªæ¡å稱"
-#: src/amidi-plug/i_configure-fluidsynth.c:231
+#: src/amidi-plug/i_configure-fluidsynth.cc:229
msgid "Size (bytes)"
msgstr "å¤§å° (ä½å
çµ)"
-#: src/amidi-plug/i_fileinfo.c:176
+#: src/amidi-plug/i_fileinfo.cc:163
msgid "Name:"
msgstr "å稱ï¼"
-#: src/amidi-plug/i_fileinfo.c:203
+#: src/amidi-plug/i_fileinfo.cc:181
msgid "<span size=\"smaller\"> MIDI Info </span>"
msgstr "<span size=\"smaller\"> MIDI è³è¨ </span>"
-#: src/amidi-plug/i_fileinfo.c:217
+#: src/amidi-plug/i_fileinfo.cc:195
msgid "Format:"
msgstr "æ ¼å¼ï¼"
-#: src/amidi-plug/i_fileinfo.c:220
+#: src/amidi-plug/i_fileinfo.cc:198
msgid "Length (msec):"
msgstr "é·åº¦ (毫ç§)ï¼"
-#: src/amidi-plug/i_fileinfo.c:223
+#: src/amidi-plug/i_fileinfo.cc:201
msgid "No. of Tracks:"
msgstr "é³è»ç·¨èï¼"
-#: src/amidi-plug/i_fileinfo.c:229
+#: src/amidi-plug/i_fileinfo.cc:207
msgid "variable"
msgstr "è®åç"
-#: src/amidi-plug/i_fileinfo.c:231
+#: src/amidi-plug/i_fileinfo.cc:209
msgid "BPM:"
msgstr "BPMï¼"
-#: src/amidi-plug/i_fileinfo.c:239
+#: src/amidi-plug/i_fileinfo.cc:217
msgid "BPM (wavg):"
msgstr "BPM (wavg)ï¼"
-#: src/amidi-plug/i_fileinfo.c:242
+#: src/amidi-plug/i_fileinfo.cc:220
msgid "Time Div:"
msgstr "æéåå²ï¼"
-#: src/amidi-plug/i_fileinfo.c:253
+#: src/amidi-plug/i_fileinfo.cc:231
msgid "<span size=\"smaller\"> MIDI Comments and Lyrics </span>"
msgstr "<span size=\"smaller\"> MIDI å註èæè© </span>"
-#: src/amidi-plug/i_fileinfo.c:302
+#: src/amidi-plug/i_fileinfo.cc:278
msgid "* no comments available in this MIDI file *"
msgstr "* éå MIDI æªä¸å
å«åè¨»è³æ *"
-#: src/amidi-plug/i_fileinfo.c:314
+#: src/amidi-plug/i_fileinfo.cc:290
msgid "* no lyrics available in this MIDI file *"
msgstr "* éå MIDI æªä¸å
嫿è©è³æ *"
-#: src/amidi-plug/i_fileinfo.c:341 src/amidi-plug/i_utils.c:40
-#: src/filewriter/vorbis.c:210 src/ladspa/plugin.c:521 src/ladspa/plugin.c:588
+#: src/amidi-plug/i_fileinfo.cc:300 src/filewriter/vorbis.cc:197
+#: src/ladspa/plugin.cc:416
msgid "_Close"
msgstr "éé(_C)"
-#: src/amidi-plug/i_fileinfo.c:366
+#: src/amidi-plug/i_fileinfo.cc:325
msgid " (invalid UTF-8)"
msgstr " (ç¡æç UTF-8 å串)"
-#: src/amidi-plug/i_utils.c:39
-msgid "About AMIDI-Plug"
-msgstr "éæ¼ AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:53
-msgid "AMIDI-Plug"
-msgstr "AMIDI-Plug"
-
-#: src/amidi-plug/i_utils.c:54
-msgid ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-msgstr ""
-"\n"
-"modular MIDI music player\n"
-"http://www.develia.org/projects.php?p=amidiplug\n"
-"\n"
-"written by Giacomo Lozito\n"
-"<james at develia.org>\n"
-"\n"
-"special thanks to...\n"
-"\n"
-"Clemens Ladisch and Jaroslav Kysela\n"
-"for their cool programs aplaymidi and amixer; those\n"
-"were really useful, along with alsa-lib docs, in order\n"
-"to learn more about the ALSA API\n"
-"\n"
-"Alfredo Spadafina\n"
-"for the nice midi keyboard logo\n"
-"\n"
-"Tony Vroon\n"
-"for the good help with alpha testing"
-
-#: src/aosd/aosd.c:30
+#: src/aosd/aosd.cc:32
msgid ""
"Audacious OSD\n"
"http://www.develia.org/projects.php?p=audacious#aosd\n"
@@ -567,150 +557,146 @@ msgstr ""
"Based in part on Evan Martin's Ghosd library:\n"
"http://neugierig.org/software/ghosd/"
-#: src/aosd/aosd.c:38
+#: src/aosd/aosd.h:37
msgid "AOSD (On-Screen Display)"
msgstr "AOSD (Audacious OSD)"
-#: src/aosd/aosd_style.c:75
+#: src/aosd/aosd_style.cc:54
msgid "Rectangle"
msgstr "ç©å½¢"
-#: src/aosd/aosd_style.c:79
+#: src/aosd/aosd_style.cc:59
msgid "Rounded Rectangle"
msgstr "åè§ç©å½¢"
-#: src/aosd/aosd_style.c:83
+#: src/aosd/aosd_style.cc:64
msgid "Concave Rectangle"
msgstr "è§è½å¹é·çç©å½¢"
-#: src/aosd/aosd_style.c:87
+#: src/aosd/aosd_style.cc:69
msgid "None"
msgstr "ç¡"
-#: src/aosd/aosd_trigger.c:74
+#: src/aosd/aosd_trigger.cc:50
msgid "Playback Start"
msgstr "éå§ææ¾"
-#: src/aosd/aosd_trigger.c:75
+#: src/aosd/aosd_trigger.cc:51
msgid "Triggers OSD when a playlist entry is played."
msgstr "ç¶ææ¾æ¸
å®ä¸çé
ç®è¢«ææ¾æè§¸ç¼ OSD"
-#: src/aosd/aosd_trigger.c:79
+#: src/aosd/aosd_trigger.cc:56
msgid "Title Change"
msgstr "æ¨é¡è®æ´"
-#: src/aosd/aosd_trigger.c:80
-msgid ""
-"Triggers OSD when, during playback, the song title changes but the filename "
-"is the same. This is mostly useful to display title changes in internet "
-"streams."
-msgstr ""
-"ç¶ææ¾ä¸ææ²æ¨é¡æ¹è®ä½æªåä¸è®æè§¸ç¼ OSDãéå°é¡¯ç¤ºç¶²è·¯ä¸²æµçæ¨é¡å¾æç¨ã"
+#: src/aosd/aosd_trigger.cc:57
+msgid "Triggers OSD when the song title changes (for internet streams)."
+msgstr "ææ²æ¨é¡æ¹è®æé¡¯ç¤º OSD (網路串æµç¨)ã"
-#: src/aosd/aosd_trigger.c:86
+#: src/aosd/aosd_trigger.cc:62
msgid "Pause On"
msgstr "æ«åææ¾"
-#: src/aosd/aosd_trigger.c:87
+#: src/aosd/aosd_trigger.cc:63
msgid "Triggers OSD when playback is paused."
msgstr "ç¶ææ¾æ«åæè§¸ç¼ OSD"
-#: src/aosd/aosd_trigger.c:91
+#: src/aosd/aosd_trigger.cc:68
msgid "Pause Off"
msgstr "è§£é¤æ«å"
-#: src/aosd/aosd_trigger.c:92
+#: src/aosd/aosd_trigger.cc:69
msgid "Triggers OSD when playback is unpaused."
msgstr "ç¶è§£é¤æ«åæè§¸ç¼ OSD"
-#: src/aosd/aosd_ui.c:192
+#: src/aosd/aosd_ui.cc:163
msgid "Placement"
msgstr "æ¾ç½®ä½ç½®"
-#: src/aosd/aosd_ui.c:224
+#: src/aosd/aosd_ui.cc:196
msgid "Relative X offset:"
msgstr "X 軸ç¸å°ä½ç§»ï¼"
-#: src/aosd/aosd_ui.c:231
+#: src/aosd/aosd_ui.cc:203
msgid "Relative Y offset:"
msgstr "Y 軸ç¸å°ä½ç§»ï¼"
-#: src/aosd/aosd_ui.c:238
+#: src/aosd/aosd_ui.cc:210
msgid "Max OSD width:"
msgstr "æå¤§ OSD 寬度ï¼"
-#: src/aosd/aosd_ui.c:249
+#: src/aosd/aosd_ui.cc:221
msgid "Multi-Monitor options"
msgstr "å¤è¢å¹é¸é
"
-#: src/aosd/aosd_ui.c:253
+#: src/aosd/aosd_ui.cc:225
msgid "Display OSD using:"
msgstr "顯示 OSDï¼"
-#: src/aosd/aosd_ui.c:255
+#: src/aosd/aosd_ui.cc:227
msgid "all monitors"
msgstr "ææè¢å¹"
-#: src/aosd/aosd_ui.c:258
+#: src/aosd/aosd_ui.cc:230
#, c-format
msgid "monitor %i"
msgstr "è¢å¹ %i"
-#: src/aosd/aosd_ui.c:310
+#: src/aosd/aosd_ui.cc:282
msgid "Timing (ms)"
msgstr "è¨æ (毫ç§)"
-#: src/aosd/aosd_ui.c:315
+#: src/aosd/aosd_ui.cc:287
msgid "Display:"
msgstr "顯示ï¼"
-#: src/aosd/aosd_ui.c:320
+#: src/aosd/aosd_ui.cc:292
msgid "Fade in:"
msgstr "æ·¡å
¥ï¼"
-#: src/aosd/aosd_ui.c:325
+#: src/aosd/aosd_ui.cc:297
msgid "Fade out:"
msgstr "æ·¡åºï¼"
-#: src/aosd/aosd_ui.c:390
+#: src/aosd/aosd_ui.cc:361
msgid "Fonts"
msgstr "åå"
-#: src/aosd/aosd_ui.c:397
+#: src/aosd/aosd_ui.cc:368
#, c-format
msgid "Font %i:"
msgstr "åå %iï¼"
-#: src/aosd/aosd_ui.c:412
+#: src/aosd/aosd_ui.cc:382
msgid "Shadow"
msgstr "é°å½±"
-#: src/aosd/aosd_ui.c:518
+#: src/aosd/aosd_ui.cc:486
msgid "Render Style"
msgstr "åç¾æ¨£å¼"
-#: src/aosd/aosd_ui.c:534
+#: src/aosd/aosd_ui.cc:502
msgid "Colors"
msgstr "é¡è²"
-#: src/aosd/aosd_ui.c:545
+#: src/aosd/aosd_ui.cc:513
#, c-format
msgid "Color %i:"
msgstr "é¡è² %iï¼"
-#: src/aosd/aosd_ui.c:648
+#: src/aosd/aosd_ui.cc:600
msgid "Enable trigger"
msgstr "åç¨è§¸ç¼å¨"
-#: src/aosd/aosd_ui.c:675
+#: src/aosd/aosd_ui.cc:627
msgid "Event"
msgstr "äºä»¶"
-#: src/aosd/aosd_ui.c:703
+#: src/aosd/aosd_ui.cc:655
msgid "Composite manager detected"
msgstr "已嵿¸¬å°åæç¹æç®¡çç¨å¼"
-#: src/aosd/aosd_ui.c:710
+#: src/aosd/aosd_ui.cc:662
msgid ""
"Composite manager not detected;\n"
"unless you know that you have one running, please activate a composite "
@@ -719,112 +705,112 @@ msgstr ""
"æªåµæ¸¬å°åæç¹æç®¡çç¨å¼ï¼\n"
"é¤éæ¨ç¢ºå®å·²ç¶å·è¡ï¼å¦å OSD å°ç¡æ³æ£ç¢ºåç¨ã"
-#: src/aosd/aosd_ui.c:718
+#: src/aosd/aosd_ui.cc:670
msgid "Composite manager not required for fake transparency"
msgstr "åçéæç¹æä¸éè¦ Composite manager"
-#: src/aosd/aosd_ui.c:754
+#: src/aosd/aosd_ui.cc:706
msgid "Transparency"
msgstr "éæ"
-#: src/aosd/aosd_ui.c:760
+#: src/aosd/aosd_ui.cc:712
msgid "Fake transparency"
msgstr "åçéæç¹æ"
-#: src/aosd/aosd_ui.c:762
+#: src/aosd/aosd_ui.cc:714
msgid "Real transparency (requires X Composite Ext.)"
msgstr "ççéæç¹æ (éè¦ X Composite 延伸åè½)"
-#: src/aosd/aosd_ui.c:804
+#: src/aosd/aosd_ui.cc:756
msgid "Composite extension not loaded"
msgstr "Composite 延伸åè½æªè¼å
¥"
-#: src/aosd/aosd_ui.c:812
+#: src/aosd/aosd_ui.cc:764
msgid "Composite extension not available"
msgstr "Composite 延伸åè½ä¸åå¨"
-#: src/aosd/aosd_ui.c:831
+#: src/aosd/aosd_ui.cc:781
#, c-format
msgid "<span font_desc='%s'>Audacious OSD</span>"
msgstr "<span font_desc='%s'>Audacious OSD</span>"
-#: src/aosd/aosd_ui.c:906
-msgid "Audacious OSD - configuration"
-msgstr "Audacious OSD - è¨å®"
-
-#: src/aosd/aosd_ui.c:927
-msgid "_Test"
-msgstr "測試(_T)"
-
-#: src/aosd/aosd_ui.c:933 src/hotkey/gui.c:491
-msgid "_Set"
-msgstr "å¥ç¨(_S)"
-
-#: src/aosd/aosd_ui.c:940
+#: src/aosd/aosd_ui.cc:844
msgid "Position"
msgstr "ä½ç½®"
-#: src/aosd/aosd_ui.c:945
+#: src/aosd/aosd_ui.cc:849
msgid "Animation"
msgstr "åç«"
-#: src/aosd/aosd_ui.c:950
+#: src/aosd/aosd_ui.cc:854
msgid "Text"
msgstr "æå"
-#: src/aosd/aosd_ui.c:955
+#: src/aosd/aosd_ui.cc:859
msgid "Decoration"
msgstr "è£é£¾"
-#: src/aosd/aosd_ui.c:960
+#: src/aosd/aosd_ui.cc:864
msgid "Trigger"
msgstr "觸ç¼"
-#: src/aosd/aosd_ui.c:965
+#: src/aosd/aosd_ui.cc:869
msgid "Misc"
msgstr "éé
"
-#: src/asx3/asx3.c:179
+#: src/aosd/aosd_ui.cc:878
+msgid "Test"
+msgstr "測試"
+
+#: src/asx3/asx3.cc:35
msgid "ASXv3 Playlists"
msgstr "ASXv3 ææ¾æ¸
å®"
-#: src/asx/asx.c:83
+#: src/asx/asx.cc:33
msgid "ASXv1/ASXv2 Playlists"
msgstr "ASXv1ï¼ASXv2 ææ¾æ¸
å®"
-#: src/audpl/audpl.c:186
+#: src/audpl/audpl.cc:33
msgid "Audacious Playlists (audpl)"
msgstr "Audacious ææ¾æ¸
å® (audpl)"
-#: src/blur_scope/blur_scope.c:47
+#: src/blur_scope/blur_scope.cc:42
msgid "<b>Color</b>"
msgstr "<b>è²å½©</b>"
-#: src/blur_scope/blur_scope.c:56
+#: src/blur_scope/blur_scope.cc:58
msgid "Blur Scope"
msgstr "æ¨¡ç³æ³¢å½¢"
-#: src/bs2b/plugin.c:142
+#: src/bs2b/plugin.cc:38
+msgid "Bauer Stereophonic-to-Binaural (BS2B)"
+msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
+
+#: src/bs2b/plugin.cc:129
+msgid "Presets:"
+msgstr "樣å¼"
+
+#: src/bs2b/plugin.cc:136
msgid "Feed level:"
msgstr "é¥éçç´ï¼"
-#: src/bs2b/plugin.c:154
+#: src/bs2b/plugin.cc:138
+msgid "x1/10 dB"
+msgstr "x1/10 dB"
+
+#: src/bs2b/plugin.cc:139
msgid "Cut frequency:"
msgstr "æªæ·é »çï¼"
-#: src/bs2b/plugin.c:166
-msgid "Presets:"
-msgstr "樣å¼"
-
-#: src/bs2b/plugin.c:189
-msgid "Bauer Stereophonic-to-Binaural (BS2B)"
-msgstr "Bauer Stereophonic-to-Binaural (BS2B)"
-
-#: src/cairo-spectrum/cairo-spectrum.c:297
+#: src/cairo-spectrum/cairo-spectrum.cc:41
msgid "Spectrum Analyzer"
msgstr "é »èåæå"
-#: src/cdaudio-ng/cdaudio-ng.c:101
+#: src/cdaudio-ng/cdaudio-ng.cc:72
+msgid "Audio CD Plugin"
+msgstr "鳿¨ CD 夿"
+
+#: src/cdaudio-ng/cdaudio-ng.cc:121
msgid ""
"Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n"
"\n"
@@ -844,171 +830,158 @@ msgstr ""
"\n"
"This was a Google Summer of Code 2007 project."
-#: src/cdaudio-ng/cdaudio-ng.c:119
+#: src/cdaudio-ng/cdaudio-ng.cc:137
msgid "<b>Device</b>"
msgstr "<b>è£ç½®</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:120
+#: src/cdaudio-ng/cdaudio-ng.cc:138
msgid "Read speed:"
msgstr "è®åé度ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:123
+#: src/cdaudio-ng/cdaudio-ng.cc:141
msgid "Override device:"
msgstr "è¦è¼è£ç½®ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:125
+#: src/cdaudio-ng/cdaudio-ng.cc:143
msgid "<b>Metadata</b>"
msgstr "<b>è©®éè³æ</b>"
-#: src/cdaudio-ng/cdaudio-ng.c:126
+#: src/cdaudio-ng/cdaudio-ng.cc:144
msgid "Use CD-Text"
msgstr "ä½¿ç¨ CD-Text"
-#: src/cdaudio-ng/cdaudio-ng.c:128
+#: src/cdaudio-ng/cdaudio-ng.cc:146
msgid "Use CDDB"
msgstr "ä½¿ç¨ CDDB"
-#: src/cdaudio-ng/cdaudio-ng.c:130
+#: src/cdaudio-ng/cdaudio-ng.cc:148
msgid "Use HTTP instead of CDDBP"
msgstr "ä½¿ç¨ HTTP èé CDDBP"
-#: src/cdaudio-ng/cdaudio-ng.c:132
+#: src/cdaudio-ng/cdaudio-ng.cc:151
msgid "Server:"
msgstr "伺æå¨ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:134
+#: src/cdaudio-ng/cdaudio-ng.cc:155
msgid "Path:"
msgstr "è·¯å¾ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:136
+#: src/cdaudio-ng/cdaudio-ng.cc:159
msgid "Port:"
msgstr "飿¥å ï¼"
-#: src/cdaudio-ng/cdaudio-ng.c:146
-msgid "Audio CD Plugin"
-msgstr "鳿¨ CD 夿"
-
-#: src/cdaudio-ng/cdaudio-ng.c:244
+#: src/cdaudio-ng/cdaudio-ng.cc:246
msgid "Failed to initialize cdio subsystem."
msgstr "ç¡æ³åå§å cdio å系統ã"
-#: src/cdaudio-ng/cdaudio-ng.c:300
+#: src/cdaudio-ng/cdaudio-ng.cc:281
#, c-format
msgid "Invalid URI %s."
msgstr "ç¡æç URI %sã"
-#: src/cdaudio-ng/cdaudio-ng.c:302
+#: src/cdaudio-ng/cdaudio-ng.cc:283
#, c-format
msgid "Track %d not found."
msgstr "æ¾ä¸å°é³è» %dã"
-#: src/cdaudio-ng/cdaudio-ng.c:304
+#: src/cdaudio-ng/cdaudio-ng.cc:285
#, c-format
msgid "Track %d is a data track."
msgstr "è»é %d æ¯è³æè»ã"
-#: src/cdaudio-ng/cdaudio-ng.c:306
-msgid "Failed to open audio output."
-msgstr "ç¡æ³éåé³è¨è¼¸åºã"
-
-#: src/cdaudio-ng/cdaudio-ng.c:378
+#: src/cdaudio-ng/cdaudio-ng.cc:360
msgid "Error reading audio CD."
msgstr "è®å鳿¨ CD æç¼çé¯èª¤ã"
-#: src/cdaudio-ng/cdaudio-ng.c:449
+#: src/cdaudio-ng/cdaudio-ng.cc:429
msgid "Audio CD"
msgstr "鳿¨ CD"
-#: src/cdaudio-ng/cdaudio-ng.c:458
-#, c-format
-msgid "Track %d"
-msgstr "é³è» %d"
-
-#: src/cdaudio-ng/cdaudio-ng.c:485 src/cdaudio-ng/cdaudio-ng.c:494
+#: src/cdaudio-ng/cdaudio-ng.cc:460 src/cdaudio-ng/cdaudio-ng.cc:469
#, c-format
msgid "Failed to open CD device %s."
msgstr "ç¡æ³éå CD è£ç½® %sã"
-#: src/cdaudio-ng/cdaudio-ng.c:497
+#: src/cdaudio-ng/cdaudio-ng.cc:472
msgid "No audio capable CD drive found."
msgstr "æ¾ä¸å°å¯ä»¥ææ¾é³è¨çå
ç¢æ©ã"
-#: src/cdaudio-ng/cdaudio-ng.c:524
+#: src/cdaudio-ng/cdaudio-ng.cc:497
msgid "Failed to finish initializing opened CD drive."
msgstr "éåçå
ç¢æ©ç¡æ³å®æåå§åã"
-#: src/cdaudio-ng/cdaudio-ng.c:537
+#: src/cdaudio-ng/cdaudio-ng.cc:510
msgid "Failed to retrieve first/last track number."
msgstr "ç¡æ³åå¾ç¬¬ä¸åææå¾çé³è»ç·¨èã"
-#: src/cdaudio-ng/cdaudio-ng.c:562
+#: src/cdaudio-ng/cdaudio-ng.cc:531
#, c-format
msgid "Cannot read start/end LSN for track %d."
msgstr "ç¡æ³è®åé³è» %d çèµ·å§ï¼çµæé輯ç£åç·¨èã"
-#: src/cdaudio-ng/cdaudio-ng.c:646
+#: src/cdaudio-ng/cdaudio-ng.cc:613
msgid "Failed to create the cddb connection."
msgstr "ç¡æ³å»ºç« cddb çé£ç·ã"
-#: src/cdaudio-ng/cdaudio-ng.c:721
+#: src/cdaudio-ng/cdaudio-ng.cc:679
msgid "Failed to query the CDDB server"
msgstr "ç¡æ³æ¥è©¢ CDDB 伺æå¨"
-#: src/cdaudio-ng/cdaudio-ng.c:723
+#: src/cdaudio-ng/cdaudio-ng.cc:681
#, c-format
msgid "Failed to query the CDDB server: %s"
msgstr "ç¡æ³æ¥è©¢ CDDB 伺æå¨ï¼%s"
-#: src/cdaudio-ng/cdaudio-ng.c:747
+#: src/cdaudio-ng/cdaudio-ng.cc:705
#, c-format
msgid "Failed to read the cddb info: %s"
msgstr "ç¡æ³è®å cddb è³è¨ï¼%s"
-#: src/cdaudio-ng/cdaudio-ng.c:818
+#: src/cdaudio-ng/cdaudio-ng.cc:765
msgid "Drive is empty."
msgstr "å
ç¢æ©æ¯ç©ºçã"
-#: src/cdaudio-ng/cdaudio-ng.c:820
+#: src/cdaudio-ng/cdaudio-ng.cc:767
msgid "Unsupported disk type."
msgstr "æªæ¯æ´çå
ç¢é¡å"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:35
+msgid "Audio CD Menu Items"
+msgstr "鳿¨ CD é¸å®é
ç®"
+
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Play CD"
msgstr "ææ¾ CD"
-#: src/cd-menu-items/cd-menu-items.c:31
+#: src/cd-menu-items/cd-menu-items.cc:47
msgid "Add CD"
msgstr "å å
¥ CD"
-#: src/cd-menu-items/cd-menu-items.c:56
-msgid "Audio CD Menu Items"
-msgstr "鳿¨ CD é¸å®é
ç®"
-
-#: src/compressor/plugin.c:35
+#: src/compressor/compressor.cc:45
msgid "<b>Compression</b>"
msgstr "<b>å£ç¸®</b>"
-#: src/compressor/plugin.c:36
+#: src/compressor/compressor.cc:46
msgid "Center volume:"
msgstr "ä¸å¤®é³éï¼"
-#: src/compressor/plugin.c:39
+#: src/compressor/compressor.cc:49
msgid "Dynamic range:"
msgstr "åæ
ç¯åï¼"
-#: src/compressor/plugin.c:53
+#: src/compressor/compressor.cc:57
msgid ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"Dynamic Range Compression Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
-#: src/compressor/plugin.c:58
+#: src/compressor/compressor.cc:64
msgid "Dynamic Range Compressor"
msgstr "åæ
ç¯åå£ç¸®"
-#: src/console/plugin.c:19
+#: src/console/plugin.cc:15
msgid ""
"Console music decoder engine based on Game_Music_Emu 0.5.2\n"
"Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n"
@@ -1024,205 +997,235 @@ msgstr ""
"William Pitcock <nenolod at dereferenced.org>\n"
"Shay Green <gblargg at gmail.com>"
-#: src/console/plugin.c:34
+#: src/console/plugin.cc:30
msgid "Bass:"
msgstr "ä½é³"
-#: src/console/plugin.c:36
+#: src/console/plugin.cc:33
msgid "Treble:"
msgstr "é«é³"
-#: src/console/plugin.c:38
+#: src/console/plugin.cc:36
msgid "Echo:"
msgstr "åé³ï¼"
-#: src/console/plugin.c:40
+#: src/console/plugin.cc:39
msgid "Default song length:"
msgstr "é è¨ææ²é·åº¦ï¼"
-#: src/console/plugin.c:43 src/modplug/plugin_main.c:65
+#: src/console/plugin.cc:42 src/modplug/plugin_main.cc:59
msgid "<b>Resampling</b>"
msgstr "<b>é忍£</b>"
-#: src/console/plugin.c:44
+#: src/console/plugin.cc:43
msgid "Enable audio resampling"
msgstr "åç¨è²é³é忍£"
-#: src/console/plugin.c:46
-msgid "Resampling rate:"
-msgstr "é忍£ç"
-
-#: src/console/plugin.c:47 src/modplug/plugin_main.c:96
-#: src/resample/resample.c:182 src/resample/resample.c:188
-#: src/resample/resample.c:191 src/resample/resample.c:194
-#: src/resample/resample.c:197 src/resample/resample.c:200
-#: src/resample/resample.c:203 src/resample/resample.c:206
-#: src/sox-resampler/sox-resampler.c:155
-msgid "Hz"
-msgstr "Hz"
-
-#: src/console/plugin.c:49
+#: src/console/plugin.cc:49
msgid "<b>SPC</b>"
msgstr "<b>SPC</b>"
-#: src/console/plugin.c:50
+#: src/console/plugin.cc:50
msgid "Ignore length from SPC tags"
msgstr "å¿½ç¥ SPC æ¨ç±¤è£¡è¨éçé·åº¦"
-#: src/console/plugin.c:52
+#: src/console/plugin.cc:52
msgid "Increase reverb"
msgstr "å¢å æ®é¿å¼·åº¦"
-#: src/console/plugin.c:61
+#: src/console/plugin.h:26
msgid "Game Console Music Decoder"
msgstr "鿲䏻æ©é³æ¨è§£ç¢¼å¨"
-#: src/crossfade/crossfade.c:83
-msgid ""
-"Crossfading failed because the songs had a different number of channels. "
-"You can use the Channel Mixer to convert the songs to the same number of "
-"channels."
-msgstr ""
-"å çºææ²éçè²éæ¸ä¸åï¼ç¡æ³ä½¿ç¨ Crossfadeãæ¨å¯ä»¥ä½¿ç¨è²éæ··åå°ææ²è½ææç¸"
-"åçè²éæ¸éã"
+#: src/coreaudio/coreaudio.cc:50
+msgid "CoreAudio output"
+msgstr "CoreAudio 輸åº"
-#: src/crossfade/crossfade.c:90
+#: src/coreaudio/coreaudio.cc:131
msgid ""
-"Crossfading failed because the songs had different sample rates. You can "
-"use the Sample Rate Converter to convert the songs to the same sample rate."
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
msgstr ""
-"æ·¡å
¥æ·¡åºå¤±æï¼å çºææ²éç忍£çä¸åãæ¨å¯ä»¥ä½¿ç¨å樣çè½æåè½ä¾åå¾ç¸åçå"
-"樣çã"
+"CoreAudio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+
+#: src/coreaudio/coreaudio.cc:143
+msgid "Use exclusive mode"
+msgstr "使ç¨ç¨å 模å¼"
-#: src/crossfade/crossfade.c:256
+#: src/crossfade/crossfade.cc:44
msgid ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
msgstr ""
"Crossfade Plugin for Audacious\n"
-"Copyright 2010-2012 John Lindgren"
+"Copyright 2010-2014 John Lindgren"
-#: src/crossfade/crossfade.c:260
+#: src/crossfade/crossfade.cc:48
msgid "<b>Crossfade</b>"
msgstr "<b>æ·¡å
¥æ·¡åº</b>"
-#: src/crossfade/crossfade.c:261
+#: src/crossfade/crossfade.cc:49
+msgid "On automatic song change"
+msgstr "èªååæææ²æ"
+
+#: src/crossfade/crossfade.cc:51 src/crossfade/crossfade.cc:57
msgid "Overlap:"
msgstr "éçï¼"
-#: src/crossfade/crossfade.c:271
+#: src/crossfade/crossfade.cc:55
+msgid "On seek or manual song change"
+msgstr "è·³è½ææååæææ²æ"
+
+#: src/crossfade/crossfade.cc:61
+msgid "<b>Tip</b>"
+msgstr "<b>æç¤º</b>"
+
+#: src/crossfade/crossfade.cc:62
+msgid ""
+"For better crossfading, enable\n"
+"the Silence Removal effect."
+msgstr "çºäºæè¼ä½³çææï¼è«ä¸ä½µåç¨ç§»é¤éé³ã"
+
+#: src/crossfade/crossfade.cc:72
msgid "Crossfade"
msgstr "æ·¡å
¥æ·¡åº"
-#: src/crystalizer/crystalizer.c:40
+#: src/crossfade/crossfade.cc:161
+msgid ""
+"Crossfading failed because the songs had a different number of channels. "
+"You can use the Channel Mixer to convert the songs to the same number of "
+"channels."
+msgstr ""
+"å çºææ²éçè²éæ¸ä¸åï¼ç¡æ³ä½¿ç¨ Crossfadeãæ¨å¯ä»¥ä½¿ç¨è²éæ··åå°ææ²è½ææç¸"
+"åçè²éæ¸éã"
+
+#: src/crossfade/crossfade.cc:168
+msgid ""
+"Crossfading failed because the songs had different sample rates. You can "
+"use the Sample Rate Converter to convert the songs to the same sample rate."
+msgstr ""
+"æ·¡å
¥æ·¡åºå¤±æï¼å çºææ²éç忍£çä¸åãæ¨å¯ä»¥ä½¿ç¨å樣çè½æåè½ä¾åå¾ç¸åçå"
+"樣çã"
+
+#: src/crystalizer/crystalizer.cc:31
msgid "<b>Crystalizer</b>"
msgstr "<b>Crystalizer</b>"
-#: src/crystalizer/crystalizer.c:41 src/stereo_plugin/stereo.c:26
+#: src/crystalizer/crystalizer.cc:32 src/stereo_plugin/stereo.cc:45
msgid "Intensity:"
msgstr "ææå¼·åº¦ï¼"
-#: src/crystalizer/crystalizer.c:51
+#: src/crystalizer/crystalizer.cc:43
msgid "Crystalizer"
msgstr "Crystalizer"
-#: src/cue/cue.c:155
+#: src/cue/cue.cc:37
msgid "Cue Sheet Plugin"
msgstr "Cue Sheet 夿"
-#: src/delete-files/delete-files.c:48
+#: src/delete-files/delete-files.cc:46 src/delete-files/delete-files.cc:146
+msgid "Delete Files"
+msgstr "åªé¤æªæ¡"
+
+#: src/delete-files/delete-files.cc:75
#, c-format
msgid "Error moving %s to trash: %s."
msgstr "ç§»åã%sãå°å徿¡¶æç¼çé¯èª¤ï¼%sã"
-#: src/delete-files/delete-files.c:60
+#: src/delete-files/delete-files.cc:86
#, c-format
msgid "Error deleting %s: %s."
msgstr "åªé¤ã%sãæç¼çé¯èª¤ï¼%sã"
-#: src/delete-files/delete-files.c:98
+#: src/delete-files/delete-files.cc:117
#, c-format
msgid "Error deleting %s: not a local file."
msgstr "åªé¤ã%sãæç¼çé¯èª¤ï¼é䏿¯æ¬æ©æªæ¡ã"
-#: src/delete-files/delete-files.c:119
+#: src/delete-files/delete-files.cc:134
msgid "Do you want to move the selected files to the trash?"
msgstr "æ¨ç¢ºå®è¦å°é¸æçæªæ¡ç§»åå°å徿¡¶åï¼"
-#: src/delete-files/delete-files.c:120
+#: src/delete-files/delete-files.cc:135
msgid "Move to Trash"
msgstr "ç§»åå°å徿¡¶"
-#: src/delete-files/delete-files.c:125
+#: src/delete-files/delete-files.cc:140
msgid "Do you want to permanently delete the selected files?"
msgstr "æ¨ç¢ºå®è¦æ°¸ä¹
å°åªé¤é¸æçæªæ¡åï¼"
-#: src/delete-files/delete-files.c:126 src/skins/preset-list.c:416
-#: src/skins/preset-list.c:432
+#: src/delete-files/delete-files.cc:141 src/skins/preset-list.cc:411
+#: src/skins/preset-list.cc:427
msgid "Delete"
msgstr "åªé¤"
-#: src/delete-files/delete-files.c:130 src/skins/preset-browser.c:56
-#: src/skins/preset-list.c:311 src/skins/ui_playlist.c:224
-#: src/sndio/sndio.c:424
+#: src/delete-files/delete-files.cc:145 src/skins/preset-browser.cc:56
+#: src/skins/preset-list.cc:307 src/skins/ui_playlist.cc:221
msgid "Cancel"
msgstr "åæ¶"
-#: src/delete-files/delete-files.c:131 src/delete-files/delete-files.c:172
-msgid "Delete Files"
-msgstr "åªé¤æªæ¡"
-
-#: src/delete-files/delete-files.c:147
+#: src/delete-files/delete-files.cc:166
msgid "Delete Selected Files"
msgstr "åªé¤é¸æçæªæ¡"
-#: src/delete-files/delete-files.c:162
+#: src/delete-files/delete-files.cc:181
msgid "<b>Delete Method</b>"
msgstr "<b>åªé¤æ¹å¼</b>"
-#: src/delete-files/delete-files.c:163
+#: src/delete-files/delete-files.cc:182
msgid "Move to trash instead of deleting immediately"
msgstr "ç§»åå°å徿¡¶è䏿¯ç´æ¥åªé¤"
-#: src/echo_plugin/echo.c:26
+#: src/echo_plugin/echo.cc:9
+msgid ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+msgstr ""
+"Echo Plugin\n"
+"By Johan Levin, 1999\n"
+"Surround echo by Carl van Schaik, 1999\n"
+"Updated for Audacious by William Pitcock and John Lindgren, 2010-2014"
+
+#: src/echo_plugin/echo.cc:21
msgid "<b>Echo</b>"
msgstr "<b>åé³</b>"
-#: src/echo_plugin/echo.c:27 src/modplug/plugin_main.c:88
-#: src/modplug/plugin_main.c:102
+#: src/echo_plugin/echo.cc:22 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "Delay:"
msgstr "å»¶é²ï¼"
-#: src/echo_plugin/echo.c:29 src/modplug/plugin_main.c:89
-#: src/modplug/plugin_main.c:103
+#: src/echo_plugin/echo.cc:24 src/modplug/plugin_main.cc:73
+#: src/modplug/plugin_main.cc:83
msgid "ms"
msgstr "毫ç§"
-#: src/echo_plugin/echo.c:30
+#: src/echo_plugin/echo.cc:25
msgid "Feedback:"
msgstr "åé¥ï¼"
-#: src/echo_plugin/echo.c:33 src/modplug/plugin_main.c:107
+#: src/echo_plugin/echo.cc:28 src/modplug/plugin_main.cc:87
msgid "Volume:"
msgstr "é³éï¼"
-#: src/echo_plugin/echo.c:116
-msgid ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-msgstr ""
-"Echo Plugin\n"
-"By Johan Levin, 1999\n"
-"\n"
-"Surround echo by Carl van Schaik, 1999"
-
-#: src/echo_plugin/echo.c:122
+#: src/echo_plugin/echo.cc:39
msgid "Echo"
msgstr "åé³"
-#: src/ffaudio/ffaudio-core.c:589
+#: src/ffaudio/ffaudio-core.cc:41
+msgid "FFmpeg Plugin"
+msgstr "FFmpeg 夿"
+
+#: src/ffaudio/ffaudio-core.cc:571
msgid ""
"Multi-format audio decoding plugin for Audacious using\n"
"FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
@@ -1238,55 +1241,55 @@ msgstr ""
"William Pitcock <nenolod at nenolod.net>\n"
"Matti Hämäläinen <ccr at tnsp.org>"
-#: src/ffaudio/ffaudio-core.c:641
-msgid "FFmpeg Plugin"
-msgstr "FFmpeg 夿"
+#: src/filewriter/filewriter.cc:45
+msgid "FileWriter Plugin"
+msgstr "æªæ¡è¼¸åºå¤æ"
-#: src/filewriter/filewriter.c:404
+#: src/filewriter/filewriter.cc:386
msgid "Output file format:"
msgstr "è¼¸åºæªæ¡æ ¼å¼ï¼"
-#: src/filewriter/filewriter.c:421
+#: src/filewriter/filewriter.cc:403
msgid "Configure"
msgstr "è¨å®"
-#: src/filewriter/filewriter.c:431
+#: src/filewriter/filewriter.cc:413
msgid "Save into original directory"
msgstr "å²åå°åå§è³æå¤¾"
-#: src/filewriter/filewriter.c:435
+#: src/filewriter/filewriter.cc:417
msgid "Save into custom directory"
msgstr "å²åå°èªè¨è³æå¤¾"
-#: src/filewriter/filewriter.c:445
+#: src/filewriter/filewriter.cc:427
msgid "Output file folder:"
msgstr "è¼¸åºæªæ¡è³æå¤¾ï¼"
-#: src/filewriter/filewriter.c:449
+#: src/filewriter/filewriter.cc:431
msgid "Pick a folder"
msgstr "鏿ä¸åè³æå¤¾"
-#: src/filewriter/filewriter.c:462
-msgid "Get filename from:"
-msgstr "æªå便ºï¼"
+#: src/filewriter/filewriter.cc:444
+msgid "Generate file name from:"
+msgstr "ç¢çæªåèªï¼"
-#: src/filewriter/filewriter.c:466
-msgid "original file tags"
-msgstr "åå§æªæ¡æ¨ç±¤"
+#: src/filewriter/filewriter.cc:448
+msgid "Original file tag"
+msgstr "åå§æªæ¡çæ¨ç±¤"
-#: src/filewriter/filewriter.c:471
-msgid "original filename"
-msgstr "åå§æªå"
+#: src/filewriter/filewriter.cc:453
+msgid "Original file name"
+msgstr "åå§æªæ¡çæªå"
-#: src/filewriter/filewriter.c:477
-msgid "Don't strip file name extension"
-msgstr "ä¸è¦å»æå¯æªå"
+#: src/filewriter/filewriter.cc:459
+msgid "Include original file name extension"
+msgstr "å
å«åå§æªæ¡ç坿ªå"
-#: src/filewriter/filewriter.c:486
-msgid "Prepend track number to filename"
-msgstr "卿ªååé¢å ä¸é³è»è碼"
+#: src/filewriter/filewriter.cc:468
+msgid "Prepend track number to file name"
+msgstr "卿ªæ¡å稱åå å
¥é³è»ç·¨è"
-#: src/filewriter/filewriter.c:502
+#: src/filewriter/filewriter.cc:484
msgid ""
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1318,165 +1321,169 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/filewriter/filewriter.c:527
-msgid "FileWriter Plugin"
-msgstr "æªæ¡è¼¸åºå¤æ"
-
-#: src/filewriter/mp3.c:38 src/filewriter/mp3.c:749
+#: src/filewriter/mp3.cc:40 src/filewriter/mp3.cc:717
msgid "Auto"
msgstr "èªå"
-#: src/filewriter/mp3.c:38
+#: src/filewriter/mp3.cc:40
msgid "Joint Stereo"
msgstr "è¯åç«é«è²"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:63
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:58
+#: src/mpg123/mpg123.cc:248
msgid "Stereo"
msgstr "ç«é«è²"
-#: src/filewriter/mp3.c:39 src/modplug/plugin_main.c:61
-#: src/mpg123/mpg123.c:210
+#: src/filewriter/mp3.cc:41 src/modplug/plugin_main.cc:57
+#: src/mpg123/mpg123.cc:248
msgid "Mono"
msgstr "å®è²é"
-#: src/filewriter/mp3.c:689
+#: src/filewriter/mp3.cc:657
msgid "MP3 Configuration"
msgstr "MP3 è¨å®"
-#: src/filewriter/mp3.c:713
+#: src/filewriter/mp3.cc:658
+msgid "_OK"
+msgstr "確èª(_O)"
+
+#: src/filewriter/mp3.cc:681
msgid "Algorithm Quality:"
msgstr "æ¼ç®æ³å質ï¼"
-#: src/filewriter/mp3.c:738
-msgid "Output Samplerate:"
+#: src/filewriter/mp3.cc:706
+msgid "Output Sample Rate:"
msgstr "輸åºå樣çï¼"
-#: src/filewriter/mp3.c:766
+#: src/filewriter/mp3.cc:733
msgid "(Hz)"
msgstr "(Hz)"
-#: src/filewriter/mp3.c:773
-msgid "Bitrate / Compression ratio:"
-msgstr "ä½å
çï¼å£ç¸®æ¯çï¼"
+#: src/filewriter/mp3.cc:740
+msgid "Bitrate / Compression Ratio:"
+msgstr "ä½å
çï¼å£ç¸®æ¯ï¼"
-#: src/filewriter/mp3.c:797
+#: src/filewriter/mp3.cc:764
msgid "Bitrate (kbps):"
msgstr "ä½å
ç (kbps)ï¼"
-#: src/filewriter/mp3.c:830
+#: src/filewriter/mp3.cc:796
msgid "Compression ratio:"
msgstr "å£ç¸®æ¯çï¼"
-#: src/filewriter/mp3.c:854
+#: src/filewriter/mp3.cc:820
msgid "Audio Mode:"
msgstr "é³è¨æ¨¡å¼ï¼"
-#: src/filewriter/mp3.c:879
-msgid "Misc:"
-msgstr "éé
ï¼"
+#: src/filewriter/mp3.cc:845
+msgid "Miscellaneous:"
+msgstr "å
¶ä»é¸é
ï¼"
-#: src/filewriter/mp3.c:890
-msgid "Enforce strict ISO complience"
-msgstr "å¼·å¶å´æ ¼ç¸å®¹æ¼ ISO"
+#: src/filewriter/mp3.cc:856
+msgid "Enforce strict ISO compliance"
+msgstr "å¼·å¶è¦æ± ISO ç¸å®¹"
-#: src/filewriter/mp3.c:901
+#: src/filewriter/mp3.cc:867
msgid "Error protection"
msgstr "é¯èª¤ä¿è·"
-#: src/filewriter/mp3.c:913 src/filewriter/vorbis.c:220
+#: src/filewriter/mp3.cc:879 src/filewriter/vorbis.cc:206
msgid "Quality"
msgstr "å質"
-#: src/filewriter/mp3.c:922
+#: src/filewriter/mp3.cc:888
msgid "Enable VBR/ABR"
msgstr "åç¨ VBRï¼ABR"
-#: src/filewriter/mp3.c:932
+#: src/filewriter/mp3.cc:898
msgid "Type:"
msgstr "é¡åï¼"
-#: src/filewriter/mp3.c:965
+#: src/filewriter/mp3.cc:931
msgid "VBR Options:"
msgstr "VBR é¸é
ï¼"
-#: src/filewriter/mp3.c:981
+#: src/filewriter/mp3.cc:947
msgid "Minimum bitrate (kbps):"
msgstr "æå°ä½å
ç (kbps)ï¼"
-#: src/filewriter/mp3.c:1008
+#: src/filewriter/mp3.cc:973
msgid "Maximum bitrate (kbps):"
msgstr "æå¤§ä½å
ç (kbps)ï¼"
-#: src/filewriter/mp3.c:1031
+#: src/filewriter/mp3.cc:995
msgid "Strictly enforce minimum bitrate"
msgstr "å¼·å¶ä½¿ç¨æå°ä½å
ç"
-#: src/filewriter/mp3.c:1043
+#: src/filewriter/mp3.cc:1007
msgid "ABR Options:"
msgstr "ABR é¸é
ï¼"
-#: src/filewriter/mp3.c:1053
+#: src/filewriter/mp3.cc:1017
msgid "Average bitrate (kbps):"
msgstr "å¹³åä½å
ç (kbps)ï¼"
-#: src/filewriter/mp3.c:1081
+#: src/filewriter/mp3.cc:1044
msgid "VBR quality level:"
msgstr "VBR å質çç´ï¼"
-#: src/filewriter/mp3.c:1100
-msgid "Don't write Xing VBR header"
-msgstr "ä¸è¦å¯«å
¥ Xing VBR æªé "
+#: src/filewriter/mp3.cc:1063
+msgid "Omit Xing VBR header"
+msgstr "çç¥ Xing VBR æªé "
-#: src/filewriter/mp3.c:1113
+#: src/filewriter/mp3.cc:1076
msgid "VBR/ABR"
msgstr "VBRï¼ABR"
-#: src/filewriter/mp3.c:1122
-msgid "Frame parameters:"
+#: src/filewriter/mp3.cc:1085
+msgid "Frame Parameters:"
msgstr "鳿¡åæ¸ï¼"
-#: src/filewriter/mp3.c:1134
+#: src/filewriter/mp3.cc:1097
msgid "Mark as copyright"
msgstr "æ¨ç¤ºçºçæ¬"
-#: src/filewriter/mp3.c:1145
+#: src/filewriter/mp3.cc:1108
msgid "Mark as original"
msgstr "æ¨ç¤ºçºååµ"
-#: src/filewriter/mp3.c:1157
-msgid "ID3 params:"
+#: src/filewriter/mp3.cc:1120
+msgid "ID3 Parameters:"
msgstr "ID3 忏ï¼"
-#: src/filewriter/mp3.c:1168
+#: src/filewriter/mp3.cc:1131
msgid "Force addition of version 2 tag"
msgstr "å¼·å¶å å
¥ç¬¬äºçæ¨ç±¤"
-#: src/filewriter/mp3.c:1178
+#: src/filewriter/mp3.cc:1141
msgid "Only add v1 tag"
msgstr "åªå å
¥ç¬¬ä¸çæ¨ç±¤"
-#: src/filewriter/mp3.c:1185
+#: src/filewriter/mp3.cc:1148
msgid "Only add v2 tag"
msgstr "åªå å
¥ç¬¬äºçæ¨ç±¤"
-#: src/filewriter/mp3.c:1206
+#: src/filewriter/mp3.cc:1169
msgid "Tags"
msgstr "æ¨ç±¤"
-#: src/filewriter/vorbis.c:210
+#: src/filewriter/vorbis.cc:196
msgid "Vorbis Encoder Configuration"
msgstr "Vorbis 編碼å¨è¨å®"
-#: src/filewriter/vorbis.c:233
+#: src/filewriter/vorbis.cc:219
msgid "Quality level (0 - 10):"
msgstr "å質çç´ (0 - 10)ï¼"
-#: src/flacng/metadata.c:359 src/wavpack/wavpack.c:212
+#: src/flacng/flacng.h:35
+msgid "FLAC Decoder"
+msgstr "FLAC 解碼å¨"
+
+#: src/flacng/metadata.cc:351 src/wavpack/wavpack.cc:209
msgid "lossless"
msgstr "ç¡æ"
-#: src/flacng/plugin.c:187
+#: src/flacng/plugin.cc:169
msgid ""
"Original code by\n"
"Ralf Ertzinger <ralf at skytale.net>\n"
@@ -1488,11 +1495,7 @@ msgstr ""
"\n"
"http://www.skytale.net/projects/bmp-flac2/"
-#: src/flacng/plugin.c:195
-msgid "FLAC Decoder"
-msgstr "FLAC 解碼å¨"
-
-#: src/gio/gio.c:295
+#: src/gio/gio.cc:34
msgid ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
@@ -1500,11 +1503,19 @@ msgstr ""
"GIO Plugin for Audacious\n"
"Copyright 2009-2012 John Lindgren"
-#: src/gio/gio.c:314
+#: src/gio/gio.cc:42
msgid "GIO Plugin"
msgstr "GIO 夿"
-#: src/gl-spectrum/gl-spectrum.c:400
+#: src/gio/gio.cc:153
+msgid "Read-and-append mode not supported"
+msgstr "䏿¯æ´è®å並éå çå忍¡å¼"
+
+#: src/gio/gio.cc:166
+msgid "Invalid open mode"
+msgstr "ç¡æçé忍¡å¼"
+
+#: src/gl-spectrum/gl-spectrum.cc:51
msgid ""
"OpenGL Spectrum Analyzer for Audacious\n"
"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
@@ -1524,533 +1535,619 @@ msgstr ""
"\n"
"License: GPLv2+"
-#: src/gl-spectrum/gl-spectrum.c:409
+#: src/gl-spectrum/gl-spectrum.cc:62
msgid "OpenGL Spectrum Analyzer"
msgstr "OpenGL é »èåæå"
-#: src/gnomeshortcuts/gnomeshortcuts.c:41
+#: src/gl-spectrum-qt/gl-spectrum.cc:41
msgid ""
-"Gnome Shortcut Plugin\n"
-"Lets you control the player with Gnome's shortcuts.\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
msgstr ""
-"Gnome Shortcut Plugin\n"
-"è®æ¨ä½¿ç¨ Gnome çå¿«é鵿§å¶ææ¾å¨ã\n"
+"OpenGL Spectrum Analyzer for Audacious\n"
+"Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+"Copyright 2014 William Pitcock\n"
"\n"
-"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+"Based on the XMMS plugin:\n"
+"Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and "
+"4Front Technologies\n"
+"\n"
+"License: GPLv2+"
-#: src/gnomeshortcuts/gnomeshortcuts.c:47
-msgid "Gnome Shortcuts"
+#: src/gl-spectrum-qt/gl-spectrum.cc:53
+msgid "OpenGL Spectrum Analyzer (Qt)"
+msgstr "OpenGL é »èåæå (Qt)"
+
+#: src/gnomeshortcuts/gnomeshortcuts.cc:38
+msgid "GNOME Shortcuts"
msgstr "Gnome å¿«ééµ"
-#: src/gtkui/columns.c:34
+#: src/gnomeshortcuts/gnomeshortcuts.cc:54
+msgid ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+msgstr ""
+"GNOME Shortcut Plugin\n"
+"Lets you control the player with GNOME's shortcuts.\n"
+"\n"
+"Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>"
+
+#: src/gtkui/columns.cc:35
msgid "Entry number"
msgstr "é
ç®ç·¨è"
-#: src/gtkui/columns.c:34
+#: src/gtkui/columns.cc:36 src/playlist-manager/playlist-manager.cc:225
+#: src/qtui/playlist_model.cc:123
msgid "Title"
msgstr "æ¨é¡"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:37 src/qtui/playlist_model.cc:125
msgid "Artist"
msgstr "è人"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:38
msgid "Year"
msgstr "年份"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:39 src/qtui/playlist_model.cc:127
msgid "Album"
msgstr "å°è¼¯"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:40
+msgid "Album artist"
+msgstr "å°è¼¯è人"
+
+#: src/gtkui/columns.cc:41
msgid "Track"
msgstr "é³è»"
-#: src/gtkui/columns.c:35
+#: src/gtkui/columns.cc:42
msgid "Genre"
msgstr "é¡å"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:43
msgid "Queue position"
msgstr "ä½åä½ç½®"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:44
msgid "Length"
msgstr "é·åº¦"
-#: src/gtkui/columns.c:36
+#: src/gtkui/columns.cc:45
msgid "File path"
msgstr "æªæ¡è·¯å¾"
-#: src/gtkui/columns.c:36
-msgid "File name"
-msgstr "æªæ¡å稱"
-
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:47
msgid "Custom title"
msgstr "èªè¨æ¨é¡"
-#: src/gtkui/columns.c:37
+#: src/gtkui/columns.cc:48
msgid "Bitrate"
msgstr "ä½å
ç"
-#: src/gtkui/columns.c:286
+#: src/gtkui/columns.cc:308
msgid "Available columns"
msgstr "å¯ç¨çæ¬ä½"
-#: src/gtkui/columns.c:312
+#: src/gtkui/columns.cc:334
msgid "Displayed columns"
msgstr "é¡¯ç¤ºçæ¬ä½"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:72 src/search-tool/search-tool.cc:40
+msgid "Search Tool"
+msgstr "æå°å·¥å
·"
+
+#: src/gtkui/layout.cc:167
msgid "Dock at Left"
msgstr "åµå
¥å·¦æ¹"
-#: src/gtkui/layout.c:119
+#: src/gtkui/layout.cc:167
msgid "Dock at Right"
msgstr "åµå
¥å³æ¹"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Top"
msgstr "åµå
¥é 端"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Dock at Bottom"
msgstr "åµå
¥åºç«¯"
-#: src/gtkui/layout.c:120
+#: src/gtkui/layout.cc:168
msgid "Undock"
msgstr "è§£é¤åµå
¥"
-#: src/gtkui/layout.c:120 src/ladspa/plugin.c:649
+#: src/gtkui/layout.cc:168 src/ladspa/plugin.cc:531
msgid "Disable"
msgstr "éé"
-#: src/gtkui/layout.c:226 src/search-tool/search-tool.c:786
-msgid "Search Tool"
-msgstr "æå°å·¥å
·"
-
-#: src/gtkui/menus.c:127 src/statusicon/statusicon.c:262
+#: src/gtkui/menus.cc:126 src/qtui/main_window_actions.cc:93
+#: src/statusicon/statusicon.cc:276
msgid "_Open Files ..."
msgstr "éåæªæ¡(_O) ..."
-#: src/gtkui/menus.c:128
+#: src/gtkui/menus.cc:127
msgid "Open _URL ..."
msgstr "éåç¶²å(_U) ..."
-#: src/gtkui/menus.c:129
+#: src/gtkui/menus.cc:128 src/qtui/main_window_actions.cc:95
msgid "_Add Files ..."
msgstr "å å
¥æªæ¡(_A) ... "
-#: src/gtkui/menus.c:130
+#: src/gtkui/menus.cc:129
msgid "Add U_RL ..."
msgstr "å å
¥ç¶²å(_R) ..."
-#: src/gtkui/menus.c:132
+#: src/gtkui/menus.cc:131
msgid "Search _Library"
msgstr "æå°åªé«æ«(_L)"
-#: src/gtkui/menus.c:134
+#: src/gtkui/menus.cc:133 src/qtui/main_window_actions.cc:98
msgid "A_bout ..."
msgstr "éæ¼(_B) ..."
-#: src/gtkui/menus.c:135
+#: src/gtkui/menus.cc:134 src/qtui/main_window_actions.cc:99
msgid "_Settings ..."
msgstr "è¨å®(_S) ..."
-#: src/gtkui/menus.c:136 src/statusicon/statusicon.c:270
+#: src/gtkui/menus.cc:135 src/qtui/main_window_actions.cc:103
+#: src/statusicon/statusicon.cc:284
msgid "_Quit"
msgstr "é¢é(_Q)"
-#: src/gtkui/menus.c:139 src/gtkui/menus.c:254
-#: src/search-tool/search-tool.c:674 src/statusicon/statusicon.c:264
+#: src/gtkui/menus.cc:139 src/gtkui/menus.cc:262
+#: src/qtui/main_window_actions.cc:107 src/search-tool/search-tool.cc:641
+#: src/statusicon/statusicon.cc:278
msgid "_Play"
msgstr "ææ¾(_P)"
-#: src/gtkui/menus.c:140 src/statusicon/statusicon.c:265
+#: src/gtkui/menus.cc:140 src/qtui/main_window_actions.cc:108
+#: src/statusicon/statusicon.cc:279
msgid "Paus_e"
msgstr "æ«å(_E)"
-#: src/gtkui/menus.c:141 src/statusicon/statusicon.c:266
+#: src/gtkui/menus.cc:141 src/qtui/main_window_actions.cc:109
+#: src/statusicon/statusicon.cc:280
msgid "_Stop"
msgstr "忢(_S)"
-#: src/gtkui/menus.c:142 src/statusicon/statusicon.c:263
+#: src/gtkui/menus.cc:142 src/qtui/main_window_actions.cc:110
+#: src/statusicon/statusicon.cc:277
msgid "Pre_vious"
msgstr "ä¸ä¸å(_V)"
-#: src/gtkui/menus.c:143 src/statusicon/statusicon.c:267
+#: src/gtkui/menus.cc:143 src/qtui/main_window_actions.cc:111
+#: src/statusicon/statusicon.cc:281
msgid "_Next"
msgstr "ä¸ä¸å(_N)"
-#: src/gtkui/menus.c:145
+#: src/gtkui/menus.cc:145 src/qtui/main_window_actions.cc:113
msgid "_Repeat"
msgstr "éè¤"
-#: src/gtkui/menus.c:146
+#: src/gtkui/menus.cc:146 src/qtui/main_window_actions.cc:114
msgid "S_huffle"
msgstr "鍿©"
-#: src/gtkui/menus.c:147
+#: src/gtkui/menus.cc:147 src/qtui/main_window_actions.cc:115
msgid "N_o Playlist Advance"
msgstr "ä¸è¦åæææ¾æ¸
å®"
-#: src/gtkui/menus.c:149
+#: src/gtkui/menus.cc:148 src/qtui/main_window_actions.cc:116
msgid "Stop A_fter This Song"
msgstr "ææ¾å®ç®åææ²å¾åæ¢(_F)"
-#: src/gtkui/menus.c:152 src/gtkui/menus.c:242
+#: src/gtkui/menus.cc:150 src/gtkui/menus.cc:247
+#: src/qtui/main_window_actions.cc:118
msgid "Song _Info ..."
msgstr "ææ²è³è¨(_I) ..."
-#: src/gtkui/menus.c:153
+#: src/gtkui/menus.cc:151
msgid "Jump to _Time ..."
msgstr "è·³è½å°æå®æé(_T) ..."
-#: src/gtkui/menus.c:154
+#: src/gtkui/menus.cc:152
msgid "_Jump to Song ..."
msgstr "è·³è½å°æå®ææ²(_J) ..."
-#: src/gtkui/menus.c:156
+#: src/gtkui/menus.cc:154
msgid "Set Repeat Point _A"
msgstr "è¨å®éè¤é» _A"
-#: src/gtkui/menus.c:157
+#: src/gtkui/menus.cc:155
msgid "Set Repeat Point _B"
msgstr "è¨å®éè¤é» _B"
-#: src/gtkui/menus.c:158
+#: src/gtkui/menus.cc:156
msgid "_Clear Repeat Points"
msgstr "æ¸
é¤éè¤é»(_C)"
-#: src/gtkui/menus.c:161 src/gtkui/menus.c:167 src/gtkui/menus.c:180
+#: src/gtkui/menus.cc:160 src/gtkui/menus.cc:167 src/gtkui/menus.cc:183
+#: src/qtui/main_window_actions.cc:122 src/qtui/main_window_actions.cc:129
+#: src/qtui/main_window_actions.cc:145
msgid "By _Title"
msgstr "æ¨é¡(_T)"
-#: src/gtkui/menus.c:162
-msgid "By _Filename"
+#: src/gtkui/menus.cc:161 src/qtui/main_window_actions.cc:123
+msgid "By _File Name"
msgstr "æªæ¡å稱(_F)"
-#: src/gtkui/menus.c:163
+#: src/gtkui/menus.cc:162 src/qtui/main_window_actions.cc:124
msgid "By File _Path"
msgstr "æªæ¡è·¯å¾(_P)"
-#: src/gtkui/menus.c:166 src/gtkui/menus.c:179
+#: src/gtkui/menus.cc:166 src/gtkui/menus.cc:182
+#: src/qtui/main_window_actions.cc:128 src/qtui/main_window_actions.cc:144
msgid "By Track _Number"
msgstr "é³è»ç·¨è(_N)"
-#: src/gtkui/menus.c:168 src/gtkui/menus.c:181
+#: src/gtkui/menus.cc:168 src/gtkui/menus.cc:184
+#: src/qtui/main_window_actions.cc:130 src/qtui/main_window_actions.cc:146
msgid "By _Artist"
msgstr "è人(_A)"
-#: src/gtkui/menus.c:169 src/gtkui/menus.c:182
+#: src/gtkui/menus.cc:169 src/gtkui/menus.cc:185
+#: src/qtui/main_window_actions.cc:131 src/qtui/main_window_actions.cc:147
msgid "By Al_bum"
msgstr "å°è¼¯(_B)"
-#: src/gtkui/menus.c:170 src/gtkui/menus.c:183
+#: src/gtkui/menus.cc:170 src/gtkui/menus.cc:186
+#: src/qtui/main_window_actions.cc:132 src/qtui/main_window_actions.cc:148
+msgid "By Albu_m Artist"
+msgstr "å°è¼¯è人(_M)"
+
+#: src/gtkui/menus.cc:171 src/gtkui/menus.cc:187
+#: src/qtui/main_window_actions.cc:133 src/qtui/main_window_actions.cc:149
msgid "By Release _Date"
msgstr "ç¼è¡æ¥æ(_D)"
-#: src/gtkui/menus.c:171 src/gtkui/menus.c:184
+#: src/gtkui/menus.cc:172 src/gtkui/menus.cc:188
+#: src/qtui/main_window_actions.cc:134 src/qtui/main_window_actions.cc:150
+msgid "By _Genre"
+msgstr "é¡å(_G)"
+
+#: src/gtkui/menus.cc:173 src/gtkui/menus.cc:189
+#: src/qtui/main_window_actions.cc:135 src/qtui/main_window_actions.cc:151
msgid "By _Length"
msgstr "é·åº¦(_L)"
-#: src/gtkui/menus.c:172 src/gtkui/menus.c:185
+#: src/gtkui/menus.cc:174 src/gtkui/menus.cc:190
+#: src/qtui/main_window_actions.cc:136 src/qtui/main_window_actions.cc:152
msgid "By _File Path"
msgstr "æªæ¡è·¯å¾(_F)"
-#: src/gtkui/menus.c:173 src/gtkui/menus.c:186
+#: src/gtkui/menus.cc:175 src/gtkui/menus.cc:191
+#: src/qtui/main_window_actions.cc:137 src/qtui/main_window_actions.cc:153
msgid "By _Custom Title"
msgstr "èªè¨æ¨é¡(_C)"
-#: src/gtkui/menus.c:175 src/gtkui/menus.c:188
+#: src/gtkui/menus.cc:177 src/gtkui/menus.cc:193
+#: src/qtui/main_window_actions.cc:139 src/qtui/main_window_actions.cc:155
msgid "R_everse Order"
msgstr "ååé åº(_E)"
-#: src/gtkui/menus.c:176 src/gtkui/menus.c:189
+#: src/gtkui/menus.cc:178 src/gtkui/menus.cc:194
+#: src/qtui/main_window_actions.cc:140 src/qtui/main_window_actions.cc:156
msgid "_Random Order"
msgstr "鍿©é åº(_R)"
-#: src/gtkui/menus.c:192
-msgid "_Play This Playlist"
-msgstr "ææ¾æ¤æ¸
å®(_P)"
+#: src/gtkui/menus.cc:198 src/qtui/main_window_actions.cc:160
+msgid "_Play/Resume"
+msgstr "ææ¾ï¼å復(_P)"
-#: src/gtkui/menus.c:193 src/gtkui/menus.c:244
+#: src/gtkui/menus.cc:199 src/gtkui/menus.cc:251
+#: src/qtui/main_window_actions.cc:161
msgid "_Refresh"
msgstr "éæ°æ´ç(_R)"
-#: src/gtkui/menus.c:195
+#: src/gtkui/menus.cc:201 src/qtui/main_window_actions.cc:163
msgid "_Sort"
msgstr "æåº(_S)"
-#: src/gtkui/menus.c:196
+#: src/gtkui/menus.cc:202 src/qtui/main_window_actions.cc:164
msgid "Sort Se_lected"
msgstr "æåºé¸æçé
ç®(_L)"
-#: src/gtkui/menus.c:197
+#: src/gtkui/menus.cc:203 src/qtui/main_window_actions.cc:165
msgid "Remove _Duplicates"
msgstr "ç§»é¤éè¤çé
ç®(_D)"
-#: src/gtkui/menus.c:198
+#: src/gtkui/menus.cc:204 src/qtui/main_window_actions.cc:166
msgid "Remove _Unavailable Files"
msgstr "ç§»é¤ä¸åå¨çæªæ¡(_U)"
-#: src/gtkui/menus.c:200
+#: src/gtkui/menus.cc:206 src/playlist-manager/playlist-manager.cc:244
+#: src/qtui/main_window_actions.cc:168
msgid "_New"
msgstr "æ°å¢(_N)"
-#: src/gtkui/menus.c:201
+#: src/gtkui/menus.cc:207
msgid "Ren_ame ..."
msgstr "éæ°å½å(_A) ..."
-#: src/gtkui/menus.c:202 src/gtkui/menus.c:256
+#: src/gtkui/menus.cc:208 src/gtkui/menus.cc:264
+#: src/qtui/main_window_actions.cc:170
msgid "Remo_ve"
msgstr "ç§»é¤(_V)"
-#: src/gtkui/menus.c:204
+#: src/gtkui/menus.cc:210
msgid "_Import ..."
msgstr "å¯å
¥(_I) ..."
-#: src/gtkui/menus.c:205
+#: src/gtkui/menus.cc:211
msgid "_Export ..."
msgstr "å¯åº(_E) ..."
-#: src/gtkui/menus.c:207
+#: src/gtkui/menus.cc:213
msgid "Playlist _Manager ..."
msgstr "ææ¾æ¸
å®ç®¡ç(_M) ..."
-#: src/gtkui/menus.c:208
+#: src/gtkui/menus.cc:214 src/qtui/main_window_actions.cc:176
msgid "_Queue Manager ..."
msgstr "ä½å管ç(_Q) ..."
-#: src/gtkui/menus.c:211
+#: src/gtkui/menus.cc:218 src/qtui/main_window_actions.cc:180
msgid "Volume _Up"
msgstr "æé«é³é(_U)"
-#: src/gtkui/menus.c:212
+#: src/gtkui/menus.cc:219 src/qtui/main_window_actions.cc:181
msgid "Volume _Down"
msgstr "éä½é³é(_D)"
-#: src/gtkui/menus.c:214
+#: src/gtkui/menus.cc:221 src/qtui/main_window_actions.cc:183
msgid "_Equalizer"
msgstr "çåå¨(_E)"
-#: src/gtkui/menus.c:216
+#: src/gtkui/menus.cc:223 src/qtui/main_window_actions.cc:185
msgid "E_ffects ..."
msgstr "ç¹æ(_F) ..."
-#: src/gtkui/menus.c:219
+#: src/gtkui/menus.cc:227
msgid "Show _Menu Bar"
msgstr "顯示é¸å®å(_M)"
-#: src/gtkui/menus.c:221
+#: src/gtkui/menus.cc:228
msgid "Show I_nfo Bar"
msgstr "顯示è³è¨å(_N)"
-#: src/gtkui/menus.c:223
+#: src/gtkui/menus.cc:229
msgid "Show Info Bar Vis_ualization"
msgstr "顯示è³è¨åçè¦è¦ºç¹æ(_U)"
-#: src/gtkui/menus.c:225
+#: src/gtkui/menus.cc:230
msgid "Show _Status Bar"
msgstr "顯示çæ
å(_S)"
-#: src/gtkui/menus.c:228
+#: src/gtkui/menus.cc:232
msgid "Show _Remaining Time"
msgstr "顯示å©é¤æé(_R)"
-#: src/gtkui/menus.c:231
+#: src/gtkui/menus.cc:234
msgid "_Visualizations ..."
msgstr "è¦è¦ºç¹æ(_V) ..."
-#: src/gtkui/menus.c:234
+#: src/gtkui/menus.cc:238 src/qtui/main_window_actions.cc:189
msgid "_File"
msgstr "æªæ¡(_F)"
-#: src/gtkui/menus.c:235
+#: src/gtkui/menus.cc:239 src/qtui/main_window_actions.cc:190
msgid "_Playback"
msgstr "ææ¾(_P)"
-#: src/gtkui/menus.c:236
+#: src/gtkui/menus.cc:240 src/qtui/main_window_actions.cc:191
msgid "P_laylist"
msgstr "ææ¾æ¸
å®(_L)"
-#: src/gtkui/menus.c:237 src/gtkui/menus.c:251
+#: src/gtkui/menus.cc:241 src/gtkui/menus.cc:258
+#: src/qtui/main_window_actions.cc:192
msgid "_Services"
msgstr "æå(_S)"
-#: src/gtkui/menus.c:238
+#: src/gtkui/menus.cc:242 src/qtui/main_window_actions.cc:193
msgid "_Output"
msgstr "輸åº(_O)"
-#: src/gtkui/menus.c:239
+#: src/gtkui/menus.cc:243
msgid "_View"
msgstr "檢è¦(_V)"
-#: src/gtkui/menus.c:243
+#: src/gtkui/menus.cc:248
msgid "_Queue/Unqueue"
msgstr "æå
¥ï¼ç§»åºä½å(_Q)"
-#: src/gtkui/menus.c:246
+#: src/gtkui/menus.cc:250
+msgid "_Open Containing Folder"
+msgstr "éåè©²è³æå¤¾(_O)"
+
+#: src/gtkui/menus.cc:253
msgid "Cu_t"
msgstr "åªä¸(_T)"
-#: src/gtkui/menus.c:247
+#: src/gtkui/menus.cc:254
msgid "_Copy"
msgstr "è¤è£½(_C)"
-#: src/gtkui/menus.c:248
+#: src/gtkui/menus.cc:255
msgid "_Paste"
msgstr "è²¼ä¸(_P)"
-#: src/gtkui/menus.c:249
+#: src/gtkui/menus.cc:256
msgid "Select _All"
msgstr "鏿å
¨é¨(_A)"
-#: src/gtkui/menus.c:255
+#: src/gtkui/menus.cc:263
msgid "_Rename ..."
msgstr "éæ°å½å(_R) ..."
-#: src/gtkui/settings.c:35
+#: src/gtkui/settings.cc:35
msgid "<b>Playlist Tabs</b>"
msgstr "<b>ææ¾æ¸
å®åé </b>"
-#: src/gtkui/settings.c:36
+#: src/gtkui/settings.cc:36
msgid "Always show tabs"
msgstr "æ°¸é 顯示åé "
-#: src/gtkui/settings.c:39
+#: src/gtkui/settings.cc:38
msgid "Show entry counts"
msgstr "顯示é
ç®æ¸é"
-#: src/gtkui/settings.c:42
+#: src/gtkui/settings.cc:40
msgid "Show close buttons"
msgstr "顯示ééæé"
-#: src/gtkui/settings.c:45
+#: src/gtkui/settings.cc:42
msgid "<b>Playlist Columns</b>"
msgstr "<b>ææ¾æ¸
宿¬ä½</b>"
-#: src/gtkui/settings.c:47
+#: src/gtkui/settings.cc:44
msgid "Show column headers"
msgstr "顯示æ¬ä½æ¨é "
-#: src/gtkui/settings.c:50 src/modplug/plugin_main.c:131
-#: src/skins/skins_cfg.c:267
+#: src/gtkui/settings.cc:46 src/modplug/plugin_main.cc:106
+#: src/skins/skins_cfg.cc:263
msgid "<b>Miscellaneous</b>"
msgstr "<b>å
¶ä»é¸é
</b>"
-#: src/gtkui/settings.c:51
+#: src/gtkui/settings.cc:47
msgid "Arrow keys seek by:"
msgstr "æä¸æ¹åéµæè·³è½çæéé·åº¦ï¼"
-#: src/gtkui/settings.c:54
+#: src/gtkui/settings.cc:50
msgid "Scroll on song change"
msgstr "åæææ²ææ²åæ¸
å®"
-#: src/gtkui/ui_gtk.c:94
+#: src/gtkui/ui_gtk.cc:71
msgid "GTK Interface"
msgstr "GTK ä»é¢"
-#: src/gtkui/ui_gtk.c:192 src/skins/ui_main.c:233
+#: src/gtkui/ui_gtk.cc:222 src/skins/ui_main.cc:232
#, c-format
msgid "%s - Audacious"
msgstr "%s - Audacious"
-#: src/gtkui/ui_gtk.c:197
+#: src/gtkui/ui_gtk.cc:225 src/qtui/main_window.cc:186
msgid "Buffering ..."
msgstr "ç·©è¡ä¸ ..."
-#: src/gtkui/ui_gtk.c:200 src/skins/ui_main.c:235 src/skins/ui_main.c:1143
+#: src/gtkui/ui_gtk.cc:228 src/skins/ui_main.cc:234 src/skins/ui_main.cc:1164
msgid "Audacious"
msgstr "Audacious"
-#: src/gtkui/ui_statusbar.c:86
+#: src/gtkui/ui_statusbar.cc:63 src/qtui/status_bar.cc:67
+msgid "mono"
+msgstr "å®è²é"
+
+#: src/gtkui/ui_statusbar.cc:65 src/qtui/status_bar.cc:69
+msgid "stereo"
+msgstr "ç«é«è²"
+
+#: src/gtkui/ui_statusbar.cc:67 src/qtui/status_bar.cc:71
#, c-format
msgid "%d channel"
msgid_plural "%d channels"
msgstr[0] "%d è²é"
-#: src/gtkui/ui_statusbar.c:101
+#: src/gtkui/ui_statusbar.cc:81 src/qtui/status_bar.cc:85
#, c-format
msgid "%d kbps"
msgstr "%d kbps"
-#: src/hotkey/gui.c:70
+#: src/gtkui/ui_statusbar.cc:107 src/skins/ui_main_evlisteners.cc:103
+msgid "Single mode."
+msgstr "å®ä¸æ¨¡å¼ã"
+
+#: src/gtkui/ui_statusbar.cc:109 src/skins/ui_main_evlisteners.cc:105
+msgid "Playlist mode."
+msgstr "ææ¾æ¸
宿¨¡å¼ã"
+
+#: src/gtkui/ui_statusbar.cc:117 src/skins/ui_main_evlisteners.cc:111
+msgid "Stopping after song."
+msgstr "ææ¾å®æå¾åæ¢ã"
+
+#: src/hotkey/gui.cc:71
msgid "Previous track"
msgstr "ä¸ä¸åé³è»"
-#: src/hotkey/gui.c:71 src/notify/osd.c:68 src/skins/menus.c:78
+#: src/hotkey/gui.cc:72 src/notify/osd.cc:69 src/qtui/main_window.cc:69
+#: src/qtui/main_window.cc:172 src/qtui/main_window.cc:173
+#: src/skins/menus.cc:87
msgid "Play"
msgstr "ææ¾"
-#: src/hotkey/gui.c:72
+#: src/hotkey/gui.cc:73
msgid "Pause/Resume"
msgstr "æ«åï¼å復"
-#: src/hotkey/gui.c:73 src/skins/menus.c:80
+#: src/hotkey/gui.cc:74 src/qtui/main_window.cc:70 src/skins/menus.cc:89
msgid "Stop"
msgstr "忢"
-#: src/hotkey/gui.c:74
+#: src/hotkey/gui.cc:75
msgid "Next track"
msgstr "ä¸ä¸åé³è»"
-#: src/hotkey/gui.c:75
+#: src/hotkey/gui.cc:76
msgid "Forward 5 seconds"
msgstr "å¿«è½äºç§"
-#: src/hotkey/gui.c:76
+#: src/hotkey/gui.cc:77
msgid "Rewind 5 seconds"
msgstr "åè½äºç§"
-#: src/hotkey/gui.c:77
+#: src/hotkey/gui.cc:78
msgid "Mute"
msgstr "éé³"
-#: src/hotkey/gui.c:78
+#: src/hotkey/gui.cc:79
msgid "Volume up"
msgstr "æé«é³é"
-#: src/hotkey/gui.c:79
+#: src/hotkey/gui.cc:80
msgid "Volume down"
msgstr "éä½é³é"
-#: src/hotkey/gui.c:80
+#: src/hotkey/gui.cc:81
msgid "Jump to file"
msgstr "è·³è½å°æå®æªæ¡"
-#: src/hotkey/gui.c:81
+#: src/hotkey/gui.cc:82
msgid "Toggle player window(s)"
msgstr "åæé¡¯ç¤ºææ¾å¨è¦çª"
-#: src/hotkey/gui.c:82
+#: src/hotkey/gui.cc:83
msgid "Show On-Screen-Display"
msgstr "顯示 OSD"
-#: src/hotkey/gui.c:83
+#: src/hotkey/gui.cc:84
msgid "Toggle repeat"
msgstr "åæéè¤ææ¾"
-#: src/hotkey/gui.c:84
+#: src/hotkey/gui.cc:85
msgid "Toggle shuffle"
msgstr "åæé¨æ©ææ¾"
-#: src/hotkey/gui.c:85
+#: src/hotkey/gui.cc:86
msgid "Toggle stop after current"
msgstr "ææ¾å®ç®åææ²å¾åæ¢"
-#: src/hotkey/gui.c:86
+#: src/hotkey/gui.cc:87
msgid "Raise player window(s)"
msgstr "å°ææ¾å¨è¦çªæ¾å°æä¸å±¤"
-#: src/hotkey/gui.c:96
+#: src/hotkey/gui.cc:97
msgid "(none)"
msgstr "(ç¡)"
-#: src/hotkey/gui.c:233
+#: src/hotkey/gui.cc:234
msgid ""
"It is not recommended to bind the primary mouse buttons without "
"modificators.\n"
@@ -2061,15 +2158,11 @@ msgstr ""
"\n"
"æ¨æ³è¦ç¹¼çºåï¼"
-#: src/hotkey/gui.c:235
+#: src/hotkey/gui.cc:236
msgid "Binding mouse buttons"
msgstr "ç¶å®æ»é¼ æé"
-#: src/hotkey/gui.c:385
-msgid "Global Hotkey Plugin Configuration"
-msgstr "å
¨åç±éµå¤æè¨å®"
-
-#: src/hotkey/gui.c:400
+#: src/hotkey/gui.cc:391
msgid ""
"Press a key combination inside a text field.\n"
"You can also bind mouse buttons."
@@ -2077,23 +2170,27 @@ msgstr ""
"è«å¨è¼¸å
¥æ¬ä½ä¸æä¸æ³è¦çæéµçµåã\n"
"æ¨ä¹å¯ä»¥ç¶å®æ»é¼ æéã"
-#: src/hotkey/gui.c:405
+#: src/hotkey/gui.cc:396
msgid "Hotkeys:"
msgstr "ç±éµï¼"
-#: src/hotkey/gui.c:422
+#: src/hotkey/gui.cc:413
msgid "<b>Action:</b>"
msgstr "<b>åä½ï¼</b>"
-#: src/hotkey/gui.c:429
+#: src/hotkey/gui.cc:420
msgid "<b>Key Binding:</b>"
msgstr "<b>æéµç¶å®ï¼</b>"
-#: src/hotkey/gui.c:476
+#: src/hotkey/gui.cc:468
msgid "_Add"
msgstr "å å
¥(_A)"
-#: src/hotkey/plugin.c:67
+#: src/hotkey/plugin.cc:61
+msgid "Global Hotkeys"
+msgstr "å
¨åç±éµ"
+
+#: src/hotkey/plugin.cc:79
msgid ""
"Global Hotkey Plugin\n"
"Control the player with global key combinations or multimedia keys.\n"
@@ -2119,60 +2216,54 @@ msgstr ""
" Jonathan A. Davis <davis at jdhouse.org>,\n"
" Jeremy Tan <nsx at nsx.homeip.net>"
-#: src/hotkey/plugin.c:79
-msgid "Global Hotkeys"
-msgstr "å
¨åç±éµ"
+#: src/jack-ng/jack-ng.cc:49
+msgid "JACK Output"
+msgstr "JACK 輸åº"
-#: src/jack/jack.c:196
-msgid "Connect to all available jack ports"
-msgstr "飿¥å°ææå¯ç¨ç jack 飿¥å "
+#: src/jack-ng/jack-ng.cc:114
+msgid "Automatically connect to output ports"
+msgstr "èªå飿¥å°è¼¸åºå "
-#: src/jack/jack.c:197
-msgid "Connect only the output ports"
-msgstr "å
飿¥å°è¼¸åºå "
+#: src/jack-ng/jack-ng.cc:155
+#, c-format
+msgid "Only %d JACK output ports were found but %d are required."
+msgstr "åªæ¾å° %d å JACK 輸åºå ï¼ä½ç³»çµ±éè¦ %d åã"
-#: src/jack/jack.c:198
-msgid "Don't connect to any port"
-msgstr "ä¸è¦é£æ¥å°ä»»ä½é£æ¥å "
+#: src/jack-ng/jack-ng.cc:164
+#, c-format
+msgid "Failed to connect to JACK port %s."
+msgstr "ç¡æ³é£æ¥å° JACK å %s ã"
-#: src/jack/jack.c:202
-msgid "Connection mode:"
-msgstr "é£ç·æ¨¡å¼ï¼"
+#: src/jack-ng/jack-ng.cc:184
+msgid ""
+"JACK supports only floating-point audio. You must change the output bit "
+"depth to floating-point in Audacious settings."
+msgstr ""
+"JACK åªæ¯æ´æµ®é»æ¸é³è¨ãæ¨å¿
é å¨ Audacious è¨å®ä¸å°è¼¸åºç忍£æ ¼å¼æ¹çºæµ®é»æ¸ã"
-#: src/jack/jack.c:205
-msgid "Enable debug printing"
-msgstr "åç¨é¤é¯è¼¸åº"
+#: src/jack-ng/jack-ng.cc:197
+msgid "Failed to connect to the JACK server; is it running?"
+msgstr "ç¡æ³é£æ¥å° JACK 伺æå¨ãè«ç¢ºèªå®æ¯å¦æ£å¸¸éä½ã"
-#: src/jack/jack.c:432
+#: src/jack-ng/jack-ng.cc:273
+#, c-format
msgid ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"The JACK server requires a sample rate of %d Hz, but Audacious is playing at "
+"%d Hz. Please use the Sample Rate Converter effect to correct the mismatch."
msgstr ""
-"Based on xmms-jack, by Chris Morgan:\n"
-"http://xmms-jack.sourceforge.net/\n"
-"\n"
-"Ported to Audacious by Giacomo Lozito"
+"JACK 伺æå¨éè¦ä½¿ç¨ %d Hz ç忍£çï¼ä½ Audacious ç®åæ£ä»¥ %d Hz ææ¾ä¸ãè«ä½¿"
+"ç¨ã忍£çè½æãç¹æä¿®æ£éååé¡ã"
-#: src/jack/jack.c:438
-msgid "JACK Output"
-msgstr "JACK 輸åº"
-
-#: src/ladspa/plugin.c:519
+#: src/ladspa/plugin.cc:414
#, c-format
msgid "%s Settings"
msgstr "%s è¨å®"
-#: src/ladspa/plugin.c:587
-msgid "LADSPA Host Settings"
-msgstr "LADSPA 主æ§ç«¯è¨å®"
-
-#: src/ladspa/plugin.c:596
+#: src/ladspa/plugin.cc:478
msgid "Module paths:"
msgstr "模çµè·¯å¾ï¼"
-#: src/ladspa/plugin.c:601
+#: src/ladspa/plugin.cc:483
msgid ""
"<small>Separate multiple paths with a colon.\n"
"These paths are searched in addition to LADSPA_PATH.\n"
@@ -2182,25 +2273,25 @@ msgstr ""
"系統é¤äº LADSPA_PATH ä¹å¤ä¹ææå°éäºè·¯å¾ã\n"
"å å
¥æ°è·¯å¾ä¹å¾è«æ Enter æææ°ç夿ã</small>"
-#: src/ladspa/plugin.c:617
+#: src/ladspa/plugin.cc:499
msgid "Available plugins:"
msgstr "å¯ç¨ç夿ï¼"
-#: src/ladspa/plugin.c:630 src/modplug/plugin_main.c:113
-#: src/modplug/plugin_main.c:117 src/modplug/plugin_main.c:121
-#: src/modplug/plugin_main.c:125
+#: src/ladspa/plugin.cc:512 src/modplug/plugin_main.cc:92
+#: src/modplug/plugin_main.cc:95 src/modplug/plugin_main.cc:98
+#: src/modplug/plugin_main.cc:101
msgid "Enable"
msgstr "åç¨"
-#: src/ladspa/plugin.c:636
+#: src/ladspa/plugin.cc:518
msgid "Enabled plugins:"
msgstr "åç¨å¤æï¼"
-#: src/ladspa/plugin.c:652
+#: src/ladspa/plugin.cc:534
msgid "Settings"
msgstr "è¨å®"
-#: src/ladspa/plugin.c:671
+#: src/ladspa/plugin.cc:551
msgid ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
@@ -2208,47 +2299,15 @@ msgstr ""
"LADSPA Host for Audacious\n"
"Copyright 2011 John Lindgren"
-#: src/ladspa/plugin.c:676
+#: src/ladspa/plugin.h:78
msgid "LADSPA Host"
msgstr "LADSPA 主æ§ç«¯"
-#: src/lirc/lirc.c:74
-#, c-format
-msgid "%s: could not init LIRC support\n"
-msgstr "%sï¼ç¡æ³åå§å LIRC æ¯æ´\n"
-
-#: src/lirc/lirc.c:81
-#, c-format
-msgid ""
-"%s: could not read LIRC config file\n"
-"%s: please read the documentation of LIRC\n"
-"%s: how to create a proper config file\n"
-msgstr ""
-"%sï¼ç¡æ³è®å LIRC çµæ
æª\n"
-"%sï¼è«é±è® LIRC çç¸éæä»¶\n"
-"%sï¼å¦ä½å»ºç«ä¸åé©åççµæ
æª\n"
-
-#: src/lirc/lirc.c:112
-#, c-format
-msgid "%s: trying to reconnect...\n"
-msgstr "%sï¼åè©¦éæ°é£ç·ä¸...\n"
-
-#: src/lirc/lirc.c:352
-#, c-format
-msgid "%s: unknown command \"%s\"\n"
-msgstr "%sï¼æªç¥çå½ä»¤ã%sã\n"
-
-#: src/lirc/lirc.c:363
-#, c-format
-msgid "%s: disconnected from LIRC\n"
-msgstr "%sï¼å·²å¾ LIRC é¢ç·\n"
-
-#: src/lirc/lirc.c:369
-#, c-format
-msgid "%s: will try reconnect every %d seconds...\n"
-msgstr "%sï¼å°æ¯ %d ç§åè©¦éæ°é£ç·ä¸æ¬¡...\n"
+#: src/lirc/lirc.cc:55
+msgid "LIRC Plugin"
+msgstr "Linux ç´
å¤ç·éæ§å¨å¤æ"
-#: src/lirc/lirc.c:379
+#: src/lirc/lirc.cc:381
msgid ""
"A simple plugin to control Audacious using the LIRC remote control daemon\n"
"\n"
@@ -2276,73 +2335,81 @@ msgstr ""
"\n"
"For more information about LIRC, see http://lirc.org."
-#: src/lirc/lirc.c:390
+#: src/lirc/lirc.cc:392
msgid "<b>Connection</b>"
msgstr "<b>é£ç·</b>"
-#: src/lirc/lirc.c:391
+#: src/lirc/lirc.cc:393
msgid "Reconnect to LIRC server"
msgstr "éæ°é£ç·å° LIRC 伺æå¨"
-#: src/lirc/lirc.c:393
+#: src/lirc/lirc.cc:395
msgid "Wait before reconnecting:"
msgstr "éæ°é£ç·åççå¾
æéï¼"
-#: src/lirc/lirc.c:403
-msgid "LIRC Plugin"
-msgstr "Linux ç´
å¤ç·éæ§å¨å¤æ"
+#: src/lyricwiki/lyricwiki.cc:41
+msgid "LyricWiki Plugin"
+msgstr "LyricWiki æè©å¤æ"
-#: src/lyricwiki/lyricwiki.c:117
+#: src/lyricwiki/lyricwiki.cc:131 src/lyricwiki-qt/lyricwiki.cc:136
msgid "No lyrics available"
msgstr "ç¡å¯ç¨çæè©"
-#: src/lyricwiki/lyricwiki.c:207 src/lyricwiki/lyricwiki.c:241
+#: src/lyricwiki/lyricwiki.cc:217 src/lyricwiki/lyricwiki.cc:226
+#: src/lyricwiki/lyricwiki.cc:243 src/lyricwiki/lyricwiki.cc:252
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:222
+#: src/lyricwiki-qt/lyricwiki.cc:231 src/lyricwiki-qt/lyricwiki.cc:248
+#: src/lyricwiki-qt/lyricwiki.cc:257 src/lyricwiki-qt/lyricwiki.cc:272
+msgid "Error"
+msgstr "é¯èª¤"
+
+#: src/lyricwiki/lyricwiki.cc:218 src/lyricwiki/lyricwiki.cc:244
+#: src/lyricwiki-qt/lyricwiki.cc:223 src/lyricwiki-qt/lyricwiki.cc:249
#, c-format
msgid "Unable to fetch %s"
msgstr "ç¡æ³åå¾ %s"
-#: src/lyricwiki/lyricwiki.c:208 src/lyricwiki/lyricwiki.c:218
-#: src/lyricwiki/lyricwiki.c:242 src/lyricwiki/lyricwiki.c:252
-#: src/lyricwiki/lyricwiki.c:271
-msgid "Error"
-msgstr "é¯èª¤"
-
-#: src/lyricwiki/lyricwiki.c:217 src/lyricwiki/lyricwiki.c:251
+#: src/lyricwiki/lyricwiki.cc:227 src/lyricwiki/lyricwiki.cc:253
+#: src/lyricwiki-qt/lyricwiki.cc:232 src/lyricwiki-qt/lyricwiki.cc:258
#, c-format
msgid "Unable to parse %s"
msgstr "ç¡æ³åæ %s"
-#: src/lyricwiki/lyricwiki.c:260
+#: src/lyricwiki/lyricwiki.cc:259 src/lyricwiki-qt/lyricwiki.cc:264
msgid "Looking for lyrics ..."
msgstr "å°æ¾æè©ä¸ ..."
-#: src/lyricwiki/lyricwiki.c:271
+#: src/lyricwiki/lyricwiki.cc:267 src/lyricwiki-qt/lyricwiki.cc:272
msgid "Missing song metadata"
msgstr "æ¾ä¸å°ææ²è©®éè³æ"
-#: src/lyricwiki/lyricwiki.c:284
+#: src/lyricwiki/lyricwiki.cc:278 src/lyricwiki-qt/lyricwiki.cc:283
msgid "Connecting to lyrics.wikia.com ..."
msgstr "é£ç·å° lyrics.wikia.com ä¸ ..."
-#: src/lyricwiki/lyricwiki.c:411
-msgid "LyricWiki Plugin"
-msgstr "LyricWiki æè©å¤æ"
+#: src/lyricwiki-qt/lyricwiki.cc:55
+msgid "LyricWiki Plugin (Qt)"
+msgstr "LyricWiki æè©å¤æ (Qt)"
-#: src/m3u/m3u.c:116
+#: src/m3u/m3u.cc:32
msgid "M3U Playlists"
msgstr "M3U ææ¾æ¸
å®"
-#: src/metronom/metronom.c:127
+#: src/metronom/metronom.cc:44
+msgid "Tact Generator"
+msgstr "ç¯æç¢çå¨"
+
+#: src/metronom/metronom.cc:147
#, c-format
msgid "Tact generator: %d bpm"
msgstr "ç¯æç¢çå¨ï¼%d bpm"
-#: src/metronom/metronom.c:129
+#: src/metronom/metronom.cc:149
#, c-format
msgid "Tact generator: %d bpm %d/%d"
msgstr "ç¯æç¢çå¨ï¼%d bpm %dï¼%d"
-#: src/metronom/metronom.c:218
+#: src/metronom/metronom.cc:237
msgid ""
"A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n"
"\n"
@@ -2356,11 +2423,11 @@ msgstr ""
"ç¯ä¾ï¼tact://77 ææ¾ 77 BPM\n"
"æ tact://60*3/4 以 3/4 æææ¾ 60 BPM"
-#: src/metronom/metronom.c:227
-msgid "Tact Generator"
-msgstr "ç¯æç¢çå¨"
+#: src/mixer/mixer.cc:38
+msgid "Channel Mixer"
+msgstr "è²éæ··å"
-#: src/mixer/mixer.c:171
+#: src/mixer/mixer.cc:202
msgid ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
@@ -2368,152 +2435,184 @@ msgstr ""
"Channel Mixer Plugin for Audacious\n"
"Copyright 2011-2012 John Lindgren and MichaÅ Lipski"
-#: src/mixer/mixer.c:175
+#: src/mixer/mixer.cc:206
msgid "<b>Channel Mixer</b>"
msgstr "<b>è²éæ··å</b>"
-#: src/mixer/mixer.c:176
+#: src/mixer/mixer.cc:207
msgid "Output channels:"
msgstr "輸åºè²éæ¸ç®ï¼"
-#: src/mixer/mixer.c:186
-msgid "Channel Mixer"
-msgstr "è²éæ··å"
-
-#: src/mms/mms.c:195
+#: src/mms/mms.cc:35
msgid "MMS Plugin"
msgstr "MMS 夿"
-#: src/modplug/plugin_main.c:55
+#: src/mms/mms.cc:82
+msgid "Error connecting to MMS server"
+msgstr "é£ç·å° MMS 伺æå¨æç¼çé¯èª¤"
+
+#: src/modplug/modplugbmp.h:53
+msgid "ModPlug (Module Player)"
+msgstr "ModPlug (MOD ææ¾å¨)"
+
+#: src/modplug/plugin_main.cc:53
msgid "<b>Resolution</b>"
msgstr "<b>è§£æåº¦</b>"
-#: src/modplug/plugin_main.c:56
+#: src/modplug/plugin_main.cc:54
msgid "8-bit"
msgstr "8-bit"
-#: src/modplug/plugin_main.c:58
+#: src/modplug/plugin_main.cc:55
msgid "16-bit"
msgstr "16-bit"
-#: src/modplug/plugin_main.c:60
+#: src/modplug/plugin_main.cc:56
msgid "<b>Channels</b>"
msgstr "<b>è²é</b>"
-#: src/modplug/plugin_main.c:66
+#: src/modplug/plugin_main.cc:60
msgid "Nearest (fastest)"
msgstr "æè¿é»å樣(æå¿«)"
-#: src/modplug/plugin_main.c:68
+#: src/modplug/plugin_main.cc:61
msgid "Linear (fast)"
msgstr "ç·æ§å樣(å¿«)"
-#: src/modplug/plugin_main.c:70
+#: src/modplug/plugin_main.cc:62
msgid "Spline (good)"
msgstr "æ²ç·å½æ¸(ä½³)"
-#: src/modplug/plugin_main.c:72
+#: src/modplug/plugin_main.cc:63
msgid "Polyphase (best)"
msgstr "å¤ç¸ä½å樣(æä½³)"
-#: src/modplug/plugin_main.c:74
-msgid "<b>Sampling rate</b>"
+#: src/modplug/plugin_main.cc:64
+msgid "<b>Sample rate</b>"
msgstr "<b>忍£ç</b>"
-#: src/modplug/plugin_main.c:75
+#: src/modplug/plugin_main.cc:65
msgid "22 kHz"
msgstr "22 kHz"
-#: src/modplug/plugin_main.c:77
+#: src/modplug/plugin_main.cc:66
msgid "44 kHz"
msgstr "44 kHz"
-#: src/modplug/plugin_main.c:79
+#: src/modplug/plugin_main.cc:67
msgid "48 kHz"
msgstr "48 kHz"
-#: src/modplug/plugin_main.c:81
+#: src/modplug/plugin_main.cc:68
msgid "96 kHz"
msgstr "96 kHz"
-#: src/modplug/plugin_main.c:86 src/modplug/plugin_main.c:93
-#: src/modplug/plugin_main.c:100
+#: src/modplug/plugin_main.cc:72 src/modplug/plugin_main.cc:77
+#: src/modplug/plugin_main.cc:82
msgid "Level:"
msgstr "強度ï¼"
-#: src/modplug/plugin_main.c:95
+#: src/modplug/plugin_main.cc:78
msgid "Cutoff:"
msgstr "è£åï¼"
-#: src/modplug/plugin_main.c:112
+#: src/modplug/plugin_main.cc:91
msgid "<b>Reverb</b>"
msgstr "<b>æ®é¿</b>"
-#: src/modplug/plugin_main.c:116
+#: src/modplug/plugin_main.cc:94
msgid "<b>Bass Boost</b>"
msgstr "<b>éä½é³å¼·å</b>"
-#: src/modplug/plugin_main.c:120
+#: src/modplug/plugin_main.cc:97
msgid "<b>Surround</b>"
msgstr "<b>ç°ç¹é³æ</b>"
-#: src/modplug/plugin_main.c:124
+#: src/modplug/plugin_main.cc:100
msgid "<b>Preamp</b>"
msgstr "<b>åç½®æ¾å¤§</b>"
-#: src/modplug/plugin_main.c:132
+#: src/modplug/plugin_main.cc:107
msgid "Oversample"
msgstr "è¶
忍£"
-#: src/modplug/plugin_main.c:134
+#: src/modplug/plugin_main.cc:108
msgid "Noise reduction"
msgstr "éåª"
-#: src/modplug/plugin_main.c:136
+#: src/modplug/plugin_main.cc:109
msgid "Play Amiga MODs"
msgstr "ææ¾ Amiga MOD æªæ¡"
-#: src/modplug/plugin_main.c:138
+#: src/modplug/plugin_main.cc:110
msgid "<b>Repeat</b>"
msgstr "<b>éè¤</b>"
-#: src/modplug/plugin_main.c:139
+#: src/modplug/plugin_main.cc:111
msgid "Repeat count:"
msgstr "éè¤æ¬¡æ¸ï¼"
-#: src/modplug/plugin_main.c:141
+#: src/modplug/plugin_main.cc:112
msgid "To repeat forever, set the repeat count to -1."
msgstr "å°éè¤æ¬¡æ¸è¨å®çº -1 表示永é éè¤ææ¾ã"
-#: src/modplug/plugin_main.c:236
-msgid "ModPlug (Module Player)"
-msgstr "ModPlug (MOD ææ¾å¨)"
-
-#: src/mpg123/mpg123.c:210
-msgid "Surround"
-msgstr "ç°ç¹"
+#: src/modplug/plugin_main.cc:125 src/sid/xs_config.cc:106
+msgid "These settings will take effect when Audacious is restarted."
+msgstr "éäºè¨å®å¼å°å¨ Audacious éæ°ååå¾çæã"
-#: src/mpg123/mpg123.c:412
+#: src/mpg123/mpg123.cc:54
msgid "MPG123 Plugin"
msgstr "MPG123 夿"
-#: src/mpris2/plugin.c:403
+#: src/mpg123/mpg123.cc:83
+msgid "<b>Advanced</b>"
+msgstr "<b>é²é</b>"
+
+#: src/mpg123/mpg123.cc:84
+msgid "Use accurate length calculation (slow)"
+msgstr "åç¨ç²¾ç¢ºé·åº¦è¨ç®(æ
¢)"
+
+#: src/mpg123/mpg123.cc:248
+msgid "Surround"
+msgstr "ç°ç¹"
+
+#: src/mpris2/plugin.cc:39
msgid "MPRIS 2 Server"
msgstr "MPRIS 2 伺æå¨"
-#: src/neon/neon.c:1056
+#: src/neon/neon.cc:97
msgid "Neon HTTP/HTTPS Plugin"
msgstr "Neon HTTPï¼HTTPS 夿"
-#: src/notify/event.c:65
+#: src/neon/neon.cc:521
+msgid "Error parsing redirect"
+msgstr "è§£æéæ°å°åæç¼çé¯èª¤"
+
+#: src/neon/neon.cc:535
+msgid "Unknown HTTP error"
+msgstr "ç¼çæªç¥ç HTTP é¯èª¤"
+
+#: src/neon/neon.cc:569
+msgid "Error parsing URL"
+msgstr "è§£æç¶²åæç¼çé¯èª¤"
+
+#: src/neon/neon.cc:632
+msgid "Too many redirects"
+msgstr "éå¤çéæ°å°å"
+
+#: src/notify/event.cc:64
msgid "Stopped"
msgstr "已忢"
-#: src/notify/event.c:65
+#: src/notify/event.cc:64
msgid "Audacious is not playing."
msgstr "Audacious éææ¾ä¸ã"
-#: src/notify/notify.c:33
+#: src/notify/notify.cc:42
+msgid "Desktop Notifications"
+msgstr "æ¡é¢éç¥"
+
+#: src/notify/notify.cc:60
msgid ""
"Desktop Notifications Plugin for Audacious\n"
"Copyright (C) 2010 Maximilian Bogner\n"
@@ -2549,55 +2648,64 @@ msgstr ""
"You should have received a copy of the GNU General Public License along with "
"this program. If not, see <http://www.gnu.org/licenses/>."
-#: src/notify/notify.c:77
+#: src/notify/notify.cc:110
msgid "Show playback controls"
msgstr "é¡¯ç¤ºææ¾æ§å¶å
ä»¶"
-#: src/notify/notify.c:80
+#: src/notify/notify.cc:112
msgid "Always show notification"
msgstr "æ°¸é 顯示éç¥"
-#: src/notify/notify.c:92
-msgid "Desktop Notifications"
-msgstr "æ¡é¢éç¥"
+#: src/notify/notify.cc:114
+msgid "Include album name in notification"
+msgstr "å¨éç¥è¨æ¯ä¸é¡¯ç¤ºå°è¼¯å稱"
-#: src/notify/osd.c:57
+#: src/notify/osd.cc:58
msgid "Show"
msgstr "顯示"
-#: src/notify/osd.c:65 src/skins/menus.c:79
+#: src/notify/osd.cc:66 src/qtui/main_window.cc:178
+#: src/qtui/main_window.cc:179 src/skins/menus.cc:88
msgid "Pause"
msgstr "æ«å"
-#: src/notify/osd.c:72 src/skins/menus.c:82
+#: src/notify/osd.cc:73 src/qtui/main_window.cc:72 src/skins/menus.cc:91
msgid "Next"
msgstr "ä¸ä¸å"
-#: src/oss4/plugin.c:38
-msgid "1. Default device"
-msgstr "1. é è¨è£ç½®"
+#: src/oss4/oss.h:93
+msgid "OSS4 Output"
+msgstr "OSS4 輸åº"
+
+#: src/oss4/oss.h:95
+msgid "OSS3 Output"
+msgstr "OSS3 輸åº"
+
+#: src/oss4/plugin.cc:35
+msgid "Default device"
+msgstr "é è¨è£ç½®"
-#: src/oss4/plugin.c:77 src/sndio/sndio.c:393
+#: src/oss4/plugin.cc:77
msgid "Audio device:"
msgstr "é³è¨è£ç½®ï¼"
-#: src/oss4/plugin.c:79
+#: src/oss4/plugin.cc:80
msgid "Use alternate device:"
msgstr "ä½¿ç¨æ¿ä»£è£ç½®ï¼"
-#: src/oss4/plugin.c:83
+#: src/oss4/plugin.cc:84
msgid "Save volume between sessions."
msgstr "å²åä¸åå·¥ä½é段çé³éã"
-#: src/oss4/plugin.c:85
+#: src/oss4/plugin.cc:86
msgid "Enable format conversions made by the OSS software."
msgstr "åç¨æ ¼å¼è½æ (ä½¿ç¨ OSS è»é«)ã"
-#: src/oss4/plugin.c:87
+#: src/oss4/plugin.cc:88
msgid "Enable exclusive mode to prevent virtual mixing."
msgstr "åç¨ç¨å 模å¼ä»¥é²æ¢èæ¬æ··é³ã"
-#: src/oss4/plugin.c:110
+#: src/oss4/plugin.cc:100
msgid ""
"OSS4 Output Plugin for Audacious\n"
"Copyright 2010-2012 MichaÅ Lipski\n"
@@ -2611,19 +2719,35 @@ msgstr ""
"I would like to thank people on #audacious, especially Tony Vroon and John "
"Lindgren and of course the authors of the previous OSS plugin."
-#: src/oss4/plugin.c:117
-msgid "OSS4 Output"
-msgstr "OSS4 輸åº"
+#: src/playlist-manager/playlist-manager.cc:37
+msgid "Playlist Manager"
+msgstr "ææ¾æ¸
å®ç®¡ç"
-#: src/pls/pls.c:102
+#: src/playlist-manager/playlist-manager.cc:226
+msgid "Entries"
+msgstr "é
ç®æ¸"
+
+#: src/playlist-manager/playlist-manager.cc:245
+msgid "_Remove"
+msgstr "ç§»é¤(_R)"
+
+#: src/playlist-manager/playlist-manager.cc:246
+msgid "Ren_ame"
+msgstr "éæ°å½å(_A)"
+
+#: src/pls/pls.cc:35
msgid "PLS Playlists"
msgstr "PLS ææ¾æ¸
å®"
-#: src/psf/plugin.c:209
+#: src/psf/plugin.cc:45
msgid "OpenPSF PSF1/PSF2 Decoder"
msgstr "OpenPSF PSF1ï¼PSF2 解碼å¨"
-#: src/pulse_audio/pulse_audio.c:644
+#: src/pulse_audio/pulse_audio.cc:38
+msgid "PulseAudio Output"
+msgstr "PulseAudio 輸åº"
+
+#: src/pulse_audio/pulse_audio.cc:611
msgid ""
"Audacious PulseAudio Output Plugin\n"
"\n"
@@ -2659,11 +2783,73 @@ msgstr ""
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
"USA."
-#: src/pulse_audio/pulse_audio.c:662
-msgid "PulseAudio Output"
-msgstr "PulseAudio 輸åº"
+#: src/qtaudio/qtaudio.cc:49
+msgid "QtMultimedia Output"
+msgstr "QtMultimedia 輸åº"
-#: src/resample/resample.c:165
+#: src/qtaudio/qtaudio.cc:77
+msgid ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+msgstr ""
+"QtMultimedia Audio Output Plugin for Audacious\n"
+"Copyright 2014 William Pitcock\n"
+"\n"
+"Based on SDL Output Plugin for Audacious\n"
+"Copyright 2010 John Lindgren"
+
+#: src/qtui/dialog_windows.cc:31
+msgid "Working ..."
+msgstr "èçä¸ ..."
+
+#: src/qtui/filter_input.cc:44 src/skins/ui_playlist.cc:221
+msgid "Search"
+msgstr "æå°"
+
+#: src/qtui/main_window_actions.cc:94
+msgid "_Open Folder ..."
+msgstr "éåè³æå¤¾(_O) ..."
+
+#: src/qtui/main_window_actions.cc:96
+msgid "_Add Folder ..."
+msgstr "å å
¥è³æå¤¾(_A) ..."
+
+#: src/qtui/main_window_actions.cc:101
+msgid "_Log Inspector ..."
+msgstr "ç£æ§è¨é(_L) ..."
+
+#: src/qtui/main_window.cc:64
+msgid "Open Files"
+msgstr "éåæªæ¡"
+
+#: src/qtui/main_window.cc:66
+msgid "Add Files"
+msgstr "å å
¥æªæ¡"
+
+#: src/qtui/main_window.cc:71 src/skins/menus.cc:90
+msgid "Previous"
+msgstr "ä¸ä¸å"
+
+#: src/qtui/main_window.cc:77 src/skins/menus.cc:82
+msgid "Repeat"
+msgstr "éè¤"
+
+#: src/qtui/main_window.cc:79 src/skins/menus.cc:83
+msgid "Shuffle"
+msgstr "鍿©"
+
+#: src/qtui/qtui.cc:42
+msgid "Qt Interface"
+msgstr "Qt ä»é¢"
+
+#: src/resample/resample.cc:43
+msgid "Sample Rate Converter"
+msgstr "忍£çè½æ"
+
+#: src/resample/resample.cc:183
msgid ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
@@ -2671,96 +2857,104 @@ msgstr ""
"Sample Rate Converter Plugin for Audacious\n"
"Copyright 2010-2012 John Lindgren"
-#: src/resample/resample.c:169
+#: src/resample/resample.cc:187
msgid "Skip/repeat samples"
msgstr "è·³éï¼éè¤å樣"
-#: src/resample/resample.c:170
+#: src/resample/resample.cc:188
msgid "Linear interpolation"
msgstr "ç·æ§å
§æ"
-#: src/resample/resample.c:171
+#: src/resample/resample.cc:189
msgid "Fast sinc interpolation"
msgstr "å¿«é sinc å
§æ"
-#: src/resample/resample.c:172
+#: src/resample/resample.cc:190
msgid "Medium sinc interpolation"
msgstr "ä¸ç sinc å
§æ"
-#: src/resample/resample.c:173
+#: src/resample/resample.cc:191
msgid "Best sinc interpolation"
msgstr "æä½³ sinc å
§æ"
-#: src/resample/resample.c:176
+#: src/resample/resample.cc:195
msgid "<b>Conversion</b>"
msgstr "<b>è½æ</b>"
-#: src/resample/resample.c:177
+#: src/resample/resample.cc:196
msgid "Method:"
msgstr "æ¼ç®æ³ï¼"
-#: src/resample/resample.c:180 src/sox-resampler/sox-resampler.c:153
+#: src/resample/resample.cc:199 src/sox-resampler/sox-resampler.cc:161
msgid "Rate:"
msgstr "忍£çï¼"
-#: src/resample/resample.c:183
+#: src/resample/resample.cc:202
msgid "<b>Rate Mappings</b>"
msgstr "<b>忍£çæ å°</b>"
-#: src/resample/resample.c:184
+#: src/resample/resample.cc:203
msgid "Use rate mappings"
msgstr "使ç¨åæ¨£çæ å°"
-#: src/resample/resample.c:186
+#: src/resample/resample.cc:205
msgid "8 kHz:"
msgstr "8 kHzï¼"
-#: src/resample/resample.c:189
+#: src/resample/resample.cc:209
msgid "16 kHz:"
msgstr "16 kHzï¼"
-#: src/resample/resample.c:192
+#: src/resample/resample.cc:213
msgid "22.05 kHz:"
msgstr "22.05 kHzï¼"
-#: src/resample/resample.c:195
+#: src/resample/resample.cc:217
+msgid "32.0 kHz:"
+msgstr "32.0 kHzï¼"
+
+#: src/resample/resample.cc:221
msgid "44.1 kHz:"
msgstr "44.1 kHzï¼"
-#: src/resample/resample.c:198
+#: src/resample/resample.cc:225
msgid "48 kHz:"
msgstr "48 kHzï¼"
-#: src/resample/resample.c:201
+#: src/resample/resample.cc:229
+msgid "88.2 kHz:"
+msgstr "88.2 kHzï¼"
+
+#: src/resample/resample.cc:233
msgid "96 kHz:"
msgstr "96 kHzï¼"
-#: src/resample/resample.c:204
+#: src/resample/resample.cc:237
+msgid "176.4 kHz:"
+msgstr "176.4 kHzï¼"
+
+#: src/resample/resample.cc:241
msgid "192 kHz:"
msgstr "192 kHzï¼"
-#: src/resample/resample.c:214
-msgid "Sample Rate Converter"
-msgstr "忍£çè½æ"
-
-#: src/scrobbler2/config_window.c:41
+#: src/scrobbler2/config_window.cc:41
#, c-format
msgid "OK. Scrobbling for user: %s"
msgstr "確èªãä¸å³ä½¿ç¨è
%s çææ¾è³è¨"
-#: src/scrobbler2/config_window.c:53
+#: src/scrobbler2/config_window.cc:54
msgid "Permission Denied"
msgstr "åå被æ"
-#: src/scrobbler2/config_window.c:55
+#: src/scrobbler2/config_window.cc:56
msgid "Access the following link to allow Audacious to scrobble your plays:"
msgstr "é»é¸ä¸åé£çµå
許 Audacious ä¸å³æ¨çææ¾è³è¨ï¼"
-#: src/scrobbler2/config_window.c:64
+#: src/scrobbler2/config_window.cc:66
msgid "Keep this window open and click 'Check Permission' again.\n"
msgstr "è«ä¿æéåè¦çªçéå䏦忬¡é»é¸ãæª¢æ¥æ¬éãã\n"
-#: src/scrobbler2/config_window.c:67 src/scrobbler2/config_window.c:78
+#: src/scrobbler2/config_window.cc:69 src/scrobbler2/config_window.cc:80
msgid ""
"Don't worry. Your scrobbles are saved on your computer.\n"
"They will be submitted as soon as Audacious is allowed to do so."
@@ -2768,32 +2962,36 @@ msgstr ""
"奿å¿ãæ¨çè³è¨å·²ç¶å²åå¨é»è
¦ä¸ã\n"
"Audacious æå¨çæ³å
許ä¸ç¡å¿«å°å°å®åä¸å³ã"
-#: src/scrobbler2/config_window.c:75
+#: src/scrobbler2/config_window.cc:77
msgid "Network Problem."
msgstr "網路ç¼çåé¡ã"
-#: src/scrobbler2/config_window.c:76
+#: src/scrobbler2/config_window.cc:78
msgid "There was a problem contacting Last.fm. Please try again later."
msgstr "åå Last.fm æç¼çåé¡ãè«ç¨åå試ã"
-#: src/scrobbler2/config_window.c:108
+#: src/scrobbler2/config_window.cc:110
msgid "Checking..."
msgstr "檢æ¥ä¸..."
-#: src/scrobbler2/config_window.c:174
+#: src/scrobbler2/config_window.cc:176
msgid "C_heck Permission"
msgstr "æª¢æ¥æ¬é(_H)"
-#: src/scrobbler2/config_window.c:175
+#: src/scrobbler2/config_window.cc:177
msgid "_Revoke Permission"
msgstr "æ¤é·ææ¬(_R)"
-#: src/scrobbler2/config_window.c:222
+#: src/scrobbler2/config_window.cc:220
msgid ""
"You need to allow Audacious to scrobble tracks to your Last.fm account.\n"
msgstr "æ¨éè¦å
許 Audacious ä¸å³é³è»çææ¾è³è¨å°æ¨ç Last.fm 帳èã\n"
-#: src/scrobbler2/scrobbler.c:220
+#: src/scrobbler2/scrobbler.cc:29
+msgid "Scrobbler 2.0"
+msgstr "Scrobbler 2.0"
+
+#: src/scrobbler2/scrobbler.cc:224
msgid ""
"The Scrobbler plugin could not be started.\n"
"There might be a problem with your installation."
@@ -2801,7 +2999,7 @@ msgstr ""
"ç¡æ³åå Scrobbler 夿ã\n"
"æ¨çå®è£å¯è½æäºåé¡ã"
-#: src/scrobbler2/scrobbler.c:296
+#: src/scrobbler2/scrobbler.cc:289
msgid ""
"Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n"
"\n"
@@ -2819,11 +3017,7 @@ msgstr ""
"project.\n"
"\n"
-#: src/scrobbler2/scrobbler.c:302
-msgid "Scrobbler 2.0"
-msgstr "Scrobbler 2.0"
-
-#: src/scrobbler2/scrobbler_communication.c:727
+#: src/scrobbler2/scrobbler_communication.cc:642
msgid ""
"Audacious is now using an improved version of the Last.fm Scrobbler.\n"
"Please check the Preferences for the Scrobbler plugin."
@@ -2831,7 +3025,11 @@ msgstr ""
"Audacious ç¾å¨ä½¿ç¨æ¹è¯çç Last.fm ææ¾è³è¨ä¸å³åè½ã\n"
"è«åé±å好è¨å®ä¸çææ¾è³è¨å¤æã"
-#: src/sdlout/plugin.c:26
+#: src/sdlout/sdlout.cc:48
+msgid "SDL Output"
+msgstr "SDL 輸åº"
+
+#: src/sdlout/sdlout.cc:77
msgid ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
@@ -2839,753 +3037,824 @@ msgstr ""
"SDL Output Plugin for Audacious\n"
"Copyright 2010 John Lindgren"
-#: src/sdlout/plugin.c:31
-msgid "SDL Output"
-msgstr "SDL 輸åº"
-
-#: src/search-tool/search-tool.c:104 src/search-tool/search-tool.c:114
+#: src/search-tool/search-tool.cc:116 src/search-tool/search-tool.cc:124
msgid "Library"
msgstr "åªé«æ«"
-#: src/search-tool/search-tool.c:211
-msgid "Unknown Artist"
-msgstr "æªç¥çè人"
-
-#: src/search-tool/search-tool.c:213
-msgid "Unknown Album"
-msgstr "æªç¥çå°è¼¯"
-
-#: src/search-tool/search-tool.c:625
+#: src/search-tool/search-tool.cc:394
#, c-format
-msgid ""
-"%s\n"
-" on %s by %s"
-msgstr ""
-"%s\n"
-" æ¼ã%sãç±ã%sãæ¼å±"
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] "%d é
çµæ"
-#: src/search-tool/search-tool.c:631
+#: src/search-tool/search-tool.cc:400
#, c-format
-msgid "%d album"
-msgid_plural "%d albums"
-msgstr[0] "%d å¼µå°è¼¯"
+msgid "(%d hidden)"
+msgid_plural "(%d hidden)"
+msgstr[0] "(%d é
é±è)"
-#: src/search-tool/search-tool.c:633
-#, c-format
-msgid ""
-"%s\n"
-" %s, %d song"
-msgid_plural ""
-"%s\n"
-" %s, %d songs"
-msgstr[0] ""
-"%s\n"
-" %sï¼%d 馿æ²"
-
-#: src/search-tool/search-tool.c:639
+#: src/search-tool/search-tool.cc:594
#, c-format
-msgid ""
-"%s\n"
-" %d song by %s"
-msgid_plural ""
-"%s\n"
-" %d songs by %s"
-msgstr[0] ""
-"%s\n"
-" %d 馿æ²ç±ã%sãæ¼å±"
-
-#: src/search-tool/search-tool.c:675
+msgid "%d song"
+msgid_plural "%d songs"
+msgstr[0] "%d 馿æ²"
+
+#: src/search-tool/search-tool.cc:601
+msgid "of this genre"
+msgstr "ç¬¦åæ¤åé¡"
+
+#: src/search-tool/search-tool.cc:607
+msgid "on"
+msgstr "æ¶éæ¼"
+
+#: src/search-tool/search-tool.cc:607
+msgid "by"
+msgstr "-"
+
+#: src/search-tool/search-tool.cc:643
msgid "_Create Playlist"
msgstr "å»ºç«ææ¾æ¸
å®(_C)"
-#: src/search-tool/search-tool.c:676
+#: src/search-tool/search-tool.cc:645
msgid "_Add to Playlist"
msgstr "å å°ææ¾æ¸
å®(_A)"
-#: src/search-tool/search-tool.c:713
+#: src/search-tool/search-tool.cc:684
msgid "Search library"
msgstr "æå°åªé«æ«"
-#: src/search-tool/search-tool.c:717
+#: src/search-tool/search-tool.cc:688
msgid ""
"To import your music library into Audacious, choose a folder and then click "
"the \"refresh\" icon."
msgstr ""
"è¦å°æ¨çåªé«æ«å¯å
¥ Audaciousï¼è«é¸æç®æ¨è³æå¤¾ä¸¦ä¸æä¸ \"éæ°æ´ç\" å示ã"
-#: src/search-tool/search-tool.c:725
+#: src/search-tool/search-tool.cc:696
msgid "Please wait ..."
msgstr "è«ç¨å ..."
-#: src/search-tool/search-tool.c:747
+#: src/search-tool/search-tool.cc:723
msgid "Choose Folder"
msgstr "é¸æè³æå¤¾"
-#: src/skins/menus.c:56
+#: src/sid/xmms-sid.cc:43
+msgid "SID Player"
+msgstr "SID ææ¾å¨"
+
+#: src/sid/xs_config.cc:61
+msgid "<b>Output</b>"
+msgstr "<b>輸åº</b>"
+
+#: src/sid/xs_config.cc:62
+msgid "Channels:"
+msgstr "è²éæ¸ï¼"
+
+#: src/sid/xs_config.cc:68
+msgid "<b>Emulation</b>"
+msgstr "<b>模æ¬</b>"
+
+#: src/sid/xs_config.cc:69
+msgid "Emulate MOS 8580 (default: MOS 6581)"
+msgstr "æ¨¡æ¬ MOS 8580 (é è¨å¼ï¼MOS 6581)"
+
+#: src/sid/xs_config.cc:71
+msgid "Do not automatically select chip model"
+msgstr "ä¸è¦èªå鏿æ¶çåè"
+
+#: src/sid/xs_config.cc:73
+msgid "Emulate filter"
+msgstr "æ¨¡æ¬æ¿¾æ³¢å¨"
+
+#: src/sid/xs_config.cc:75
+msgid "Clock speed:"
+msgstr "æèï¼"
+
+#: src/sid/xs_config.cc:78
+msgid "Do not automatically select clock speed"
+msgstr "ä¸è¦èªå鏿æè"
+
+#: src/sid/xs_config.cc:80
+msgid "<b>Playback time</b>"
+msgstr "<b>ææ¾æé</b>"
+
+#: src/sid/xs_config.cc:81
+msgid "Set maximum playback time:"
+msgstr "è¨å®æå¤§çææ¾æéï¼"
+
+#: src/sid/xs_config.cc:87
+msgid "Use only when song length is unknown"
+msgstr "å
卿æ²é·åº¦æªç¥æä½¿ç¨"
+
+#: src/sid/xs_config.cc:90
+msgid "Set minimum playback time:"
+msgstr "è¨å®æå°çææ¾æéï¼"
+
+#: src/sid/xs_config.cc:96
+msgid "<b>Subtunes</b>"
+msgstr "<b>Subtunes</b>"
+
+#: src/sid/xs_config.cc:97
+msgid "Enable subtunes"
+msgstr "åç¨ Subtunes"
+
+#: src/sid/xs_config.cc:99
+msgid "Ignore subtunes shorter than:"
+msgstr "忽ç¥éçç Subtunesï¼"
+
+#: src/sid/xs_config.cc:105
+msgid "<b>Note</b>"
+msgstr "<b>注æ</b>"
+
+#: src/silence-removal/silence-removal.cc:39
+msgid "Silence Removal"
+msgstr "ç§»é¤éé³"
+
+#: src/silence-removal/silence-removal.cc:58
+msgid ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+msgstr ""
+"Silence Removal Plugin for Audacious\n"
+"Copyright 2014 John Lindgren"
+
+#: src/silence-removal/silence-removal.cc:67
+msgid "<b>Silence Removal</b>"
+msgstr "<b>ç§»é¤éé³</b>"
+
+#: src/silence-removal/silence-removal.cc:68
+msgid "Threshold:"
+msgstr "é¥å¼ï¼"
+
+#: src/silence-removal/silence-removal.cc:70
+msgid "dB"
+msgstr "dB"
+
+#: src/skins/menus.cc:64
msgid "Open Files ..."
msgstr "éåæªæ¡ ..."
-#: src/skins/menus.c:57
+#: src/skins/menus.cc:65
msgid "Open URL ..."
msgstr "éåç¶²å ..."
-#: src/skins/menus.c:59
+#: src/skins/menus.cc:66
+msgid "Search Library"
+msgstr "æå°åªé«æ«"
+
+#: src/skins/menus.cc:68
msgid "Playback"
msgstr "ææ¾"
-#: src/skins/menus.c:60
+#: src/skins/menus.cc:69
msgid "Playlist"
msgstr "ææ¾æ¸
å®"
-#: src/skins/menus.c:61
+#: src/skins/menus.cc:70
msgid "View"
msgstr "檢è¦"
-#: src/skins/menus.c:63 src/skins/menus.c:133 src/skins/menus.c:146
-#: src/skins/menus.c:203
+#: src/skins/menus.cc:72 src/skins/menus.cc:136 src/skins/menus.cc:149
+#: src/skins/menus.cc:214
msgid "Services"
msgstr "æå"
-#: src/skins/menus.c:65
+#: src/skins/menus.cc:74
msgid "About ..."
msgstr "éæ¼ ..."
-#: src/skins/menus.c:66
+#: src/skins/menus.cc:75
msgid "Settings ..."
msgstr "è¨å® ..."
-#: src/skins/menus.c:67
+#: src/skins/menus.cc:76
msgid "Quit"
msgstr "é¢é"
-#: src/skins/menus.c:71 src/skins/menus.c:195
+#: src/skins/menus.cc:80 src/skins/menus.cc:206
msgid "Song Info ..."
msgstr "ææ²è³è¨ ..."
-#: src/skins/menus.c:73
-msgid "Repeat"
-msgstr "éè¤"
-
-#: src/skins/menus.c:74
-msgid "Shuffle"
-msgstr "鍿©"
-
-#: src/skins/menus.c:75
+#: src/skins/menus.cc:84
msgid "No Playlist Advance"
msgstr "ä¸è¦åæææ¾æ¸
å®"
-#: src/skins/menus.c:76
+#: src/skins/menus.cc:85
msgid "Stop After This Song"
msgstr "ææ¾å®ç®åææ²å¾åæ¢"
-#: src/skins/menus.c:81
-msgid "Previous"
-msgstr "ä¸ä¸å"
-
-#: src/skins/menus.c:84
+#: src/skins/menus.cc:93
msgid "Set A-B Repeat"
msgstr "è¨å® A-B 循ç°"
-#: src/skins/menus.c:85
+#: src/skins/menus.cc:94
msgid "Clear A-B Repeat"
msgstr "æ¸
é¤ A-B 循ç°"
-#: src/skins/menus.c:87
+#: src/skins/menus.cc:96
msgid "Jump to Song ..."
msgstr "è·³è½å°æå®ææ² ..."
-#: src/skins/menus.c:88
+#: src/skins/menus.cc:97
msgid "Jump to Time ..."
msgstr "è·³è½å°æå®æé ..."
-#: src/skins/menus.c:92
-msgid "Play This Playlist"
-msgstr "ææ¾æ¤æ¸
å®"
+#: src/skins/menus.cc:101
+msgid "Play/Resume"
+msgstr "ææ¾ï¼å復"
-#: src/skins/menus.c:94
+#: src/skins/menus.cc:103
msgid "New Playlist"
msgstr "æ°å¢ææ¾æ¸
å®"
-#: src/skins/menus.c:95
+#: src/skins/menus.cc:104
msgid "Rename Playlist ..."
msgstr "éæ°å½åææ¾æ¸
å® ..."
-#: src/skins/menus.c:96
+#: src/skins/menus.cc:105
msgid "Remove Playlist"
msgstr "ç§»é¤ææ¾æ¸
å®"
-#: src/skins/menus.c:98
+#: src/skins/menus.cc:107
msgid "Previous Playlist"
msgstr "ä¸ä¸åææ¾æ¸
å®"
-#: src/skins/menus.c:99
+#: src/skins/menus.cc:108
msgid "Next Playlist"
msgstr "ä¸ä¸åææ¾æ¸
å®"
-#: src/skins/menus.c:101
+#: src/skins/menus.cc:110
msgid "Import Playlist ..."
msgstr "å¯å
¥ææ¾æ¸
å® ..."
-#: src/skins/menus.c:102
+#: src/skins/menus.cc:111
msgid "Export Playlist ..."
msgstr "å¯åºææ¾æ¸
å® ..."
-#: src/skins/menus.c:104
+#: src/skins/menus.cc:113
msgid "Playlist Manager ..."
msgstr "ææ¾æ¸
å®ç®¡ç ..."
-#: src/skins/menus.c:105
+#: src/skins/menus.cc:114
msgid "Queue Manager ..."
msgstr "ä½å管ç ..."
-#: src/skins/menus.c:107
+#: src/skins/menus.cc:116
msgid "Refresh Playlist"
msgstr "éæ´ææ¾æ¸
å®"
-#: src/skins/menus.c:111
+#: src/skins/menus.cc:120
msgid "Show Playlist Editor"
msgstr "é¡¯ç¤ºææ¾æ¸
å®ç·¨è¼¯å¨"
-#: src/skins/menus.c:113
+#: src/skins/menus.cc:121
msgid "Show Equalizer"
msgstr "顯示çåå¨"
-#: src/skins/menus.c:116
+#: src/skins/menus.cc:123
msgid "Show Remaining Time"
msgstr "顯示å©é¤æé"
-#: src/skins/menus.c:119
+#: src/skins/menus.cc:125
msgid "Always on Top"
msgstr "æ°¸é 卿ä¸å±¤"
-#: src/skins/menus.c:121
+#: src/skins/menus.cc:126
msgid "On All Workspaces"
msgstr "卿æå·¥ä½å顯示"
-#: src/skins/menus.c:124
+#: src/skins/menus.cc:128
msgid "Roll Up Player"
msgstr "æ²èµ·ææ¾å¨"
-#: src/skins/menus.c:126
+#: src/skins/menus.cc:129
msgid "Roll Up Playlist Editor"
msgstr "æ²èµ·ææ¾æ¸
å®ç·¨è¼¯å¨"
-#: src/skins/menus.c:128
+#: src/skins/menus.cc:130
msgid "Roll Up Equalizer"
msgstr "æ²èµ·çåå¨"
-#: src/skins/menus.c:135
+#: src/skins/menus.cc:132 src/skins/ui_main.cc:854
+msgid "Double Size"
+msgstr "å
©å大å°"
+
+#: src/skins/menus.cc:138
msgid "Add URL ..."
msgstr "å å
¥ç¶²å ..."
-#: src/skins/menus.c:136
+#: src/skins/menus.cc:139
msgid "Add Files ..."
msgstr "å å
¥æªæ¡ ... "
-#: src/skins/menus.c:140 src/skins/menus.c:167 src/skins/menus.c:177
+#: src/skins/menus.cc:143 src/skins/menus.cc:171 src/skins/menus.cc:185
msgid "By Title"
msgstr "æ¨é¡"
-#: src/skins/menus.c:141 src/skins/menus.c:170 src/skins/menus.c:180
-msgid "By Filename"
+#: src/skins/menus.cc:144 src/skins/menus.cc:178 src/skins/menus.cc:192
+msgid "By File Name"
msgstr "æªæ¡å稱"
-#: src/skins/menus.c:142 src/skins/menus.c:171 src/skins/menus.c:181
+#: src/skins/menus.cc:145 src/skins/menus.cc:179 src/skins/menus.cc:193
msgid "By File Path"
msgstr "æªæ¡è·¯å¾"
-#: src/skins/menus.c:148
+#: src/skins/menus.cc:151
msgid "Remove All"
msgstr "å
¨é¨ç§»é¤"
-#: src/skins/menus.c:149
+#: src/skins/menus.cc:152
msgid "Clear Queue"
msgstr "æ¸
é¤ä½å"
-#: src/skins/menus.c:151
+#: src/skins/menus.cc:154
msgid "Remove Unavailable Files"
msgstr "ç§»é¤ç¡æ³ä½¿ç¨çæªæ¡"
-#: src/skins/menus.c:152
+#: src/skins/menus.cc:155
msgid "Remove Duplicates"
msgstr "ç§»é¤éè¤çé
ç®"
-#: src/skins/menus.c:154
+#: src/skins/menus.cc:157
msgid "Remove Unselected"
msgstr "ç§»é¤æªé¸æçé
ç®"
-#: src/skins/menus.c:155
+#: src/skins/menus.cc:158
msgid "Remove Selected"
msgstr "ç§»é¤é¸æçé
ç®"
-#: src/skins/menus.c:159
+#: src/skins/menus.cc:162
msgid "Search and Select"
msgstr "æå°ä¸¦é¸æ"
-#: src/skins/menus.c:161
+#: src/skins/menus.cc:164
msgid "Invert Selection"
msgstr "åå鏿"
-#: src/skins/menus.c:162
+#: src/skins/menus.cc:165
msgid "Select None"
msgstr "忶鏿"
-#: src/skins/menus.c:163
+#: src/skins/menus.cc:166
msgid "Select All"
msgstr "鏿å
¨é¨"
-#: src/skins/menus.c:168 src/skins/menus.c:178
-msgid "By Album"
-msgstr "å°è¼¯"
+#: src/skins/menus.cc:170 src/skins/menus.cc:184
+msgid "By Track Number"
+msgstr "é³è»ç·¨è"
-#: src/skins/menus.c:169 src/skins/menus.c:179
+#: src/skins/menus.cc:172 src/skins/menus.cc:186
msgid "By Artist"
msgstr "è人"
-#: src/skins/menus.c:172 src/skins/menus.c:182
+#: src/skins/menus.cc:173 src/skins/menus.cc:187
+msgid "By Album"
+msgstr "å°è¼¯"
+
+#: src/skins/menus.cc:174 src/skins/menus.cc:188
+msgid "By Album Artist"
+msgstr "å°è¼¯è人"
+
+#: src/skins/menus.cc:175 src/skins/menus.cc:190
msgid "By Release Date"
msgstr "ç¼è¡æ¥æ"
-#: src/skins/menus.c:173 src/skins/menus.c:183
-msgid "By Track Number"
-msgstr "é³è»ç·¨è"
+#: src/skins/menus.cc:176 src/skins/menus.cc:189
+msgid "By Genre"
+msgstr "é¡å"
+
+#: src/skins/menus.cc:177 src/skins/menus.cc:191
+msgid "By Length"
+msgstr "é·åº¦"
+
+#: src/skins/menus.cc:180 src/skins/menus.cc:194
+msgid "By Custom Title"
+msgstr "èªè¨æ¨é¡"
-#: src/skins/menus.c:187
+#: src/skins/menus.cc:198
msgid "Randomize List"
msgstr "æ¸
å®é¨æ©æåº"
-#: src/skins/menus.c:188
+#: src/skins/menus.cc:199
msgid "Reverse List"
msgstr "æ¸
å®ååæåº"
-#: src/skins/menus.c:190
+#: src/skins/menus.cc:201
msgid "Sort Selected"
msgstr "æåºé¸æçé
ç®"
-#: src/skins/menus.c:191
+#: src/skins/menus.cc:202
msgid "Sort List"
msgstr "æåºæ¸
å®"
-#: src/skins/menus.c:197
+#: src/skins/menus.cc:208
msgid "Cut"
msgstr "åªä¸"
-#: src/skins/menus.c:198
+#: src/skins/menus.cc:209
msgid "Copy"
msgstr "è¤è£½"
-#: src/skins/menus.c:199
+#: src/skins/menus.cc:210
msgid "Paste"
msgstr "è²¼ä¸"
-#: src/skins/menus.c:201
+#: src/skins/menus.cc:212
msgid "Queue/Unqueue"
msgstr "æå
¥ï¼ç§»åºä½å"
-#: src/skins/menus.c:207
+#: src/skins/menus.cc:218
msgid "Load Preset ..."
msgstr "è¼å
¥æ¨£å¼ ..."
-#: src/skins/menus.c:208
+#: src/skins/menus.cc:219
msgid "Load Auto Preset ..."
msgstr "è®åèªåè¼å
¥æ¨£å¼ ..."
-#: src/skins/menus.c:209
+#: src/skins/menus.cc:220
msgid "Load Default"
msgstr "è¼å
¥é è¨å¼"
-#: src/skins/menus.c:210
+#: src/skins/menus.cc:221
msgid "Load Preset File ..."
msgstr "徿ªæ¡è¼å
¥æ¨£å¼ ..."
-#: src/skins/menus.c:211
+#: src/skins/menus.cc:222
msgid "Load EQF File ..."
msgstr "è¼å
¥ EQF æª ..."
-#: src/skins/menus.c:213
+#: src/skins/menus.cc:224
msgid "Save Preset ..."
msgstr "å²åæ¨£å¼ ..."
-#: src/skins/menus.c:214
+#: src/skins/menus.cc:225
msgid "Save Auto Preset ..."
msgstr "å²åèªåè¼å
¥æ¨£å¼ ..."
-#: src/skins/menus.c:215
+#: src/skins/menus.cc:226
msgid "Save Default"
msgstr "å²åé è¨å¼"
-#: src/skins/menus.c:216
+#: src/skins/menus.cc:227
msgid "Save Preset File ..."
msgstr "å²å樣å¼å°æªæ¡ ..."
-#: src/skins/menus.c:217
+#: src/skins/menus.cc:228
msgid "Save EQF File ..."
msgstr "å²å EQF æª ..."
-#: src/skins/menus.c:219
+#: src/skins/menus.cc:230
msgid "Delete Preset ..."
msgstr "åªé¤æ¨£å¼ ..."
-#: src/skins/menus.c:220
+#: src/skins/menus.cc:231
msgid "Delete Auto Preset ..."
msgstr "åªé¤èªåè¼å
¥æ¨£å¼ ..."
-#: src/skins/menus.c:222
+#: src/skins/menus.cc:233
msgid "Import Winamp Presets ..."
msgstr "å¯å
¥ Winamp æ¨£å¼ ..."
-#: src/skins/menus.c:224
+#: src/skins/menus.cc:235
msgid "Reset to Zero"
msgstr "éç½®çºé¶"
-#: src/skins/plugin.c:49
+#: src/skins/plugin.cc:48
msgid "Winamp Classic Interface"
msgstr "Winamp å³çµ±ä»é¢"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:375
-#: src/skins/preset-list.c:390
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:371
+#: src/skins/preset-list.cc:386
msgid "Save"
msgstr "å²å"
-#: src/skins/preset-browser.c:57 src/skins/preset-list.c:342
-#: src/skins/preset-list.c:358
+#: src/skins/preset-browser.cc:57 src/skins/preset-list.cc:338
+#: src/skins/preset-list.cc:354
msgid "Load"
msgstr "è¼å
¥"
-#: src/skins/preset-browser.c:82
+#: src/skins/preset-browser.cc:83
msgid "Load Preset File"
msgstr "徿ªæ¡è¼å
¥æ¨£å¼"
-#: src/skins/preset-browser.c:106
+#: src/skins/preset-browser.cc:100
msgid "Load EQF File"
msgstr "è¼å
¥ EQF æª"
-#: src/skins/preset-browser.c:122
+#: src/skins/preset-browser.cc:119
msgid "Save Preset File"
msgstr "å²å樣å¼å°æªæ¡"
-#: src/skins/preset-browser.c:144
+#: src/skins/preset-browser.cc:137
msgid "Save EQF File"
msgstr "å²å EQF æª"
-#: src/skins/preset-browser.c:162
+#: src/skins/preset-browser.cc:151
msgid "Import Winamp Presets"
msgstr "å¯å
¥ Winamp 樣å¼"
-#: src/skins/preset-list.c:289
+#: src/skins/preset-list.cc:285
msgid "Presets"
msgstr "樣å¼"
-#: src/skins/preset-list.c:339
+#: src/skins/preset-list.cc:335
msgid "Load preset"
msgstr "è¼å
¥æ¨£å¼"
-#: src/skins/preset-list.c:355
+#: src/skins/preset-list.cc:351
msgid "Load auto-preset"
msgstr "è®åèªåè¼å
¥æ¨£å¼"
-#: src/skins/preset-list.c:371
+#: src/skins/preset-list.cc:367
msgid "Save preset"
msgstr "å²å樣å¼"
-#: src/skins/preset-list.c:386
+#: src/skins/preset-list.cc:382
msgid "Save auto-preset"
msgstr "å²åèªåè¼å
¥æ¨£å¼"
-#: src/skins/preset-list.c:413
+#: src/skins/preset-list.cc:408
msgid "Delete preset"
msgstr "åªé¤æ¨£å¼"
-#: src/skins/preset-list.c:429
+#: src/skins/preset-list.cc:424
msgid "Delete auto-preset"
msgstr "åªé¤èªåè¼å
¥æ¨£å¼"
-#: src/skins/skins_cfg.c:181
-msgid "_Player:"
-msgstr "ææ¾å¨(_P)ï¼"
+#: src/skins/skins_cfg.cc:176
+msgid "Player:"
+msgstr "ææ¾å¨ï¼"
-#: src/skins/skins_cfg.c:183
+#: src/skins/skins_cfg.cc:178
msgid "Select main player window font:"
msgstr "é¸æææ¾å¨ä¸»è¦çªååï¼"
-#: src/skins/skins_cfg.c:184
-msgid "_Playlist:"
-msgstr "ææ¾æ¸
å®(_P)ï¼"
+#: src/skins/skins_cfg.cc:179
+msgid "Playlist:"
+msgstr "ææ¾æ¸
å®ï¼"
-#: src/skins/skins_cfg.c:186
+#: src/skins/skins_cfg.cc:181
msgid "Select playlist font:"
msgstr "é¸æææ¾æ¸
å®ååï¼"
-#: src/skins/skins_cfg.c:191
+#: src/skins/skins_cfg.cc:187
msgid "<b>Skin</b>"
msgstr "<b>颿¿</b>"
-#: src/skins/skins_cfg.c:193
+#: src/skins/skins_cfg.cc:189
msgid "<b>Fonts</b>"
msgstr "<b>åå</b>"
-#: src/skins/skins_cfg.c:196
+#: src/skins/skins_cfg.cc:192
msgid "Use bitmap fonts (supports ASCII only)"
msgstr "使ç¨é»é£åå (åªæ¯æ´ ASCII)"
-#: src/skins/skins_cfg.c:198
+#: src/skins/skins_cfg.cc:194
msgid "Scroll song title"
msgstr "æ²åææ²æ¨é¡"
-#: src/skins/skins_cfg.c:200
+#: src/skins/skins_cfg.cc:196
msgid "Scroll song title in both directions"
msgstr "é忲忿²æ¨é¡"
-#: src/skins/skins_cfg.c:205
+#: src/skins/skins_cfg.cc:201
msgid "Analyzer"
msgstr "åæå"
-#: src/skins/skins_cfg.c:206
+#: src/skins/skins_cfg.cc:202
msgid "Scope"
msgstr "示波å¨"
-#: src/skins/skins_cfg.c:207
+#: src/skins/skins_cfg.cc:203
msgid "Voiceprint / VU meter"
msgstr "è²ç´ï¼VU è¨"
-#: src/skins/skins_cfg.c:208
+#: src/skins/skins_cfg.cc:204
msgid "Off"
msgstr "éé"
-#: src/skins/skins_cfg.c:212 src/skins/skins_cfg.c:237
-#: src/skins/skins_cfg.c:243
+#: src/skins/skins_cfg.cc:208 src/skins/skins_cfg.cc:233
+#: src/skins/skins_cfg.cc:239
msgid "Normal"
msgstr "æ¨æº"
-#: src/skins/skins_cfg.c:213 src/skins/skins_cfg.c:238
+#: src/skins/skins_cfg.cc:209 src/skins/skins_cfg.cc:234
msgid "Fire"
msgstr "ç«ç°"
-#: src/skins/skins_cfg.c:214
+#: src/skins/skins_cfg.cc:210
msgid "Vertical lines"
msgstr "åç´ç·æ¢"
-#: src/skins/skins_cfg.c:218
+#: src/skins/skins_cfg.cc:214
msgid "Lines"
msgstr "ç·æ¢"
-#: src/skins/skins_cfg.c:219
+#: src/skins/skins_cfg.cc:215
msgid "Bars"
msgstr "æ£ç"
-#: src/skins/skins_cfg.c:223
+#: src/skins/skins_cfg.cc:219
msgid "Slowest"
msgstr "ææ
¢"
-#: src/skins/skins_cfg.c:224
+#: src/skins/skins_cfg.cc:220
msgid "Slow"
msgstr "æ
¢"
-#: src/skins/skins_cfg.c:225 src/sox-resampler/sox-resampler.c:145
+#: src/skins/skins_cfg.cc:221 src/sox-resampler/sox-resampler.cc:152
msgid "Medium"
msgstr "ä¸ç"
-#: src/skins/skins_cfg.c:226
+#: src/skins/skins_cfg.cc:222
msgid "Fast"
msgstr "å¿«"
-#: src/skins/skins_cfg.c:227
+#: src/skins/skins_cfg.cc:223
msgid "Fastest"
msgstr "æå¿«"
-#: src/skins/skins_cfg.c:231
+#: src/skins/skins_cfg.cc:227
msgid "Dots"
msgstr "é»ç"
-#: src/skins/skins_cfg.c:232
+#: src/skins/skins_cfg.cc:228
msgid "Line"
msgstr "ç·æ¢"
-#: src/skins/skins_cfg.c:233
+#: src/skins/skins_cfg.cc:229
msgid "Solid"
msgstr "實å¿"
-#: src/skins/skins_cfg.c:239
+#: src/skins/skins_cfg.cc:235
msgid "Ice"
msgstr "å°é"
-#: src/skins/skins_cfg.c:244
+#: src/skins/skins_cfg.cc:240
msgid "Smooth"
msgstr "å¹³æ»"
-#: src/skins/skins_cfg.c:248
+#: src/skins/skins_cfg.cc:244
msgid "<b>Type</b>"
msgstr "<b>é¡å</b>"
-#: src/skins/skins_cfg.c:249
+#: src/skins/skins_cfg.cc:245
msgid "Visualization type:"
msgstr "è¦è¦ºç¹æé¡åï¼"
-#: src/skins/skins_cfg.c:252
+#: src/skins/skins_cfg.cc:248
msgid "<b>Analyzer</b>"
msgstr "<b>åæå</b>"
-#: src/skins/skins_cfg.c:253
+#: src/skins/skins_cfg.cc:249
msgid "Show peaks"
msgstr "é¡¯ç¤ºå³°å¼æ¨è¨"
-#: src/skins/skins_cfg.c:255
+#: src/skins/skins_cfg.cc:251
msgid "Coloring:"
msgstr "é¡è²ï¼"
-#: src/skins/skins_cfg.c:258
+#: src/skins/skins_cfg.cc:254
msgid "Style:"
msgstr "樣å¼ï¼"
-#: src/skins/skins_cfg.c:261
+#: src/skins/skins_cfg.cc:257
msgid "Falloff:"
msgstr "é·è½ï¼"
-#: src/skins/skins_cfg.c:264
+#: src/skins/skins_cfg.cc:260
msgid "Peak falloff:"
msgstr "å³°å¼é·è½ï¼"
-#: src/skins/skins_cfg.c:268
+#: src/skins/skins_cfg.cc:264
msgid "Scope Style:"
msgstr "ç¤ºæ³¢å¨æ¨£å¼ï¼"
-#: src/skins/skins_cfg.c:271
+#: src/skins/skins_cfg.cc:267
msgid "Voiceprint Coloring:"
msgstr "è²ç´é¡è²ï¼"
-#: src/skins/skins_cfg.c:274
+#: src/skins/skins_cfg.cc:270
msgid "VU Meter Style:"
msgstr "VU è¨æ¨£å¼ï¼"
-#: src/skins/skins_cfg.c:280
+#: src/skins/skins_cfg.cc:276
msgid "General"
msgstr "ä¸è¬"
-#: src/skins/skins_cfg.c:281
+#: src/skins/skins_cfg.cc:277
msgid "Visualization"
msgstr "è¦è¦ºç¹æ"
-#: src/skins/ui_equalizer.c:289
+#: src/skins/ui_equalizer.cc:282
msgid "Preamp"
msgstr "åç½®æ¾å¤§"
-#: src/skins/ui_equalizer.c:293
+#: src/skins/ui_equalizer.cc:286
msgid "31 Hz"
msgstr "31 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "63 Hz"
msgstr "63 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "125 Hz"
msgstr "125 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "250 Hz"
msgstr "250 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "500 Hz"
msgstr "500 Hz"
-#: src/skins/ui_equalizer.c:294
+#: src/skins/ui_equalizer.cc:287
msgid "1 kHz"
msgstr "1 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "2 kHz"
msgstr "2 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "4 kHz"
msgstr "4 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "8 kHz"
msgstr "8 kHz"
-#: src/skins/ui_equalizer.c:295
+#: src/skins/ui_equalizer.cc:288
msgid "16 kHz"
msgstr "16 kHz"
-#: src/skins/ui_equalizer.c:337
+#: src/skins/ui_equalizer.cc:330
msgid "Audacious Equalizer"
msgstr "Audacious çåå¨"
-#: src/skins/ui_main.c:686
+#: src/skins/ui_main.cc:688
#, c-format
msgid "Seek to %d:%-2.2d / %d:%-2.2d"
msgstr "ç§»åå° %d:%-2.2dï¼%d:%-2.2d"
-#: src/skins/ui_main.c:707
+#: src/skins/ui_main.cc:709
#, c-format
msgid "Volume: %d%%"
msgstr "é³éï¼%dï¼
"
-#: src/skins/ui_main.c:730
+#: src/skins/ui_main.cc:732
#, c-format
msgid "Balance: %d%% left"
msgstr "平衡ï¼%dï¼
åå·¦"
-#: src/skins/ui_main.c:732
+#: src/skins/ui_main.cc:734
msgid "Balance: center"
msgstr "平衡ï¼ä¸é"
-#: src/skins/ui_main.c:734
+#: src/skins/ui_main.cc:736
#, c-format
msgid "Balance: %d%% right"
msgstr "平衡ï¼%dï¼
åå³"
-#: src/skins/ui_main.c:833
+#: src/skins/ui_main.cc:842
msgid "Options Menu"
msgstr "é¸å®é¸é
"
-#: src/skins/ui_main.c:837
+#: src/skins/ui_main.cc:846
msgid "Disable 'Always On Top'"
msgstr "ééç½®é "
-#: src/skins/ui_main.c:839
+#: src/skins/ui_main.cc:848
msgid "Enable 'Always On Top'"
msgstr "åç¨ç½®é "
-#: src/skins/ui_main.c:842
+#: src/skins/ui_main.cc:851
msgid "File Info Box"
msgstr "æªæ¡è³è¨è¦çª"
-#: src/skins/ui_main.c:1281
+#: src/skins/ui_main.cc:857
+msgid "Visualizations"
+msgstr "è¦è¦ºç¹æ"
+
+#: src/skins/ui_main.cc:1336
msgid "Repeat point A set."
msgstr "å·²è¨å®éè¤é» Aã"
-#: src/skins/ui_main.c:1286
+#: src/skins/ui_main.cc:1341
msgid "Repeat point B set."
msgstr "å·²è¨å®éè¤é» Bã"
-#: src/skins/ui_main.c:1295
+#: src/skins/ui_main.cc:1350
msgid "Repeat points cleared."
msgstr "å·²æ¸
é¤éè¤é»ã"
-#: src/skins/ui_main_evlisteners.c:109
-msgid "Single mode."
-msgstr "å®ä¸æ¨¡å¼ã"
-
-#: src/skins/ui_main_evlisteners.c:111
-msgid "Playlist mode."
-msgstr "ææ¾æ¸
宿¨¡å¼ã"
-
-#: src/skins/ui_main_evlisteners.c:117
-msgid "Stopping after song."
-msgstr "ææ¾å®æå¾åæ¢ã"
-
-#: src/skins/ui_playlist.c:222
+#: src/skins/ui_playlist.cc:219
msgid "Search entries in active playlist"
msgstr "å¨ä½¿ç¨ä¸çææ¾æ¸
å®è£¡æå°ææ¾é
ç®"
-#: src/skins/ui_playlist.c:224
-msgid "Search"
-msgstr "æå°"
-
-#: src/skins/ui_playlist.c:229
+#: src/skins/ui_playlist.cc:226
msgid ""
"Select entries in playlist by filling one or more fields. Fields use regular "
"expressions syntax, case-insensitive. If you don't know how regular "
@@ -3595,57 +3864,61 @@ msgstr ""
"å¡«å
¥ä¸åæå¤åæ¬ä½ä»¥é¸æææ¾æ¸
å®ä¸çé
ç®ãæ¬ä½ä½¿ç¨æ£è¦è¡¨ç¤ºæ³ï¼å¤§å°å¯«è¦çºä¸å"
"åå
ãè¥æ¨ä¸ç¥éå¦ä½ä½¿ç¨æ£è¦è¡¨ç¤ºæ³ï¼è«è¼¸å
¥æ¨æ³æå°çé¨åæåã"
-#: src/skins/ui_playlist.c:237
-msgid "Title: "
+#: src/skins/ui_playlist.cc:234
+msgid "Title:"
msgstr "æ¨é¡ï¼"
-#: src/skins/ui_playlist.c:245
-msgid "Album: "
+#: src/skins/ui_playlist.cc:241
+msgid "Album:"
msgstr "å°è¼¯ï¼"
-#: src/skins/ui_playlist.c:253
-msgid "Artist: "
+#: src/skins/ui_playlist.cc:248
+msgid "Artist:"
msgstr "è人ï¼"
-#: src/skins/ui_playlist.c:261
-msgid "Filename: "
+#: src/skins/ui_playlist.cc:255
+msgid "File Name:"
msgstr "æªåï¼"
-#: src/skins/ui_playlist.c:270
+#: src/skins/ui_playlist.cc:263
msgid "Clear previous selection before searching"
msgstr "é²è¡æå°åæ¸
ç©ºä¸æ¬¡ç鏿é
ç®"
-#: src/skins/ui_playlist.c:273
+#: src/skins/ui_playlist.cc:266
msgid "Automatically toggle queue for matching entries"
msgstr "èªååæå°ç¬¦åé
ç®çä½å"
-#: src/skins/ui_playlist.c:276
+#: src/skins/ui_playlist.cc:269
msgid "Create a new playlist with matching entries"
msgstr "以符åçé
ç®å»ºç«æ°çææ¾æ¸
å®"
-#: src/skins/ui_playlist.c:721
+#: src/skins/ui_playlist.cc:717
msgid "Audacious Playlist Editor"
msgstr "Audacious ææ¾æ¸
å®ç·¨è¼¯å¨"
-#: src/skins/ui_playlist.c:755
+#: src/skins/ui_playlist.cc:752
#, c-format
msgid "%s (%d of %d)"
msgstr "%s (%dï¼%d)"
-#: src/skins/ui_skinselector.c:163
+#: src/skins/ui_skinselector.cc:167
msgid "Archived Winamp 2.x skin"
msgstr "å£ç¸®ç Winamp 2.x 颿¿"
-#: src/skins/ui_skinselector.c:168
+#: src/skins/ui_skinselector.cc:172
msgid "Unarchived Winamp 2.x skin"
msgstr "æªå£ç¸®ç Winamp 2.x skin"
-#: src/skins/util.c:450
+#: src/skins/util.cc:430
#, c-format
msgid "Could not create directory (%s): %s\n"
msgstr "ç¡æ³å»ºç«è³æå¤¾ (%s)ï¼%s\n"
-#: src/sndfile/plugin.c:350
+#: src/sndfile/plugin.cc:39
+msgid "Sndfile Plugin"
+msgstr "Sndfile 夿"
+
+#: src/sndfile/plugin.cc:336
msgid ""
"Based on the xmms_sndfile plugin:\n"
"Copyright (C) 2000, 2002 Erik de Castro Lopo\n"
@@ -3685,81 +3958,71 @@ msgstr ""
"this program; if not, write to the Free Software Foundation, Inc., 51 "
"Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."
-#: src/sndfile/plugin.c:369
-msgid "Sndfile Plugin"
-msgstr "Sndfile 夿"
-
-#: src/sndio/sndio.c:172
-msgid "About Sndio Output Plugin"
-msgstr "éæ¼ Sndio 輸åºå¤æ"
+#: src/sndio-ng/sndio.cc:44
+msgid "Sndio Output"
+msgstr "Sndio 輸åº"
-#: src/sndio/sndio.c:173
-msgid ""
-"Sndio Output Plugin\n"
-"\n"
-"Written by Thomas Pfaff <tpfaff at tp76.info>\n"
-msgstr ""
-"Sndio 輸åºå¤æ\n"
-"\n"
-"ä½è
ï¼Thomas Pfaff <tpfaff at tp76.info>\n"
+#: src/sndio-ng/sndio.cc:98
+msgid "Device (blank for default):"
+msgstr "è£ç½® (空ç½è¡¨ç¤ºé è¨)ï¼"
-#: src/sndio/sndio.c:248
-msgid "Unsupported format"
-msgstr "æªæ¯æ´çæ ¼å¼"
+#: src/sndio-ng/sndio.cc:100
+msgid "Save and restore volume:"
+msgstr "å²åèéåé³éï¼"
-#: src/sndio/sndio.c:249
-msgid ""
-"A format not supported by the audio device was requested.\n"
-"\n"
-"Please try again with the sndiod(1) server running."
-msgstr ""
-"è¦æ±äºæªè¢«é³è¨è£ç½®æ¯æ´çæ ¼å¼ã\n"
-"\n"
-"è«ç¢ºèª sndiod(1) 伺æå¨å·²å·è¡å¾é試ã"
+#: src/sndio-ng/sndio.cc:181
+#, c-format
+msgid "Sndio error: Unsupported audio format (%d)"
+msgstr "Sndio é¯èª¤ï¼æªæ¯æ´çé³è¨æ ¼å¼ (%d)"
-#: src/sndio/sndio.c:384
-msgid "sndio device"
-msgstr "sndio è£ç½®"
+#: src/sndio-ng/sndio.cc:192
+msgid "Sndio error: sio_open() failed"
+msgstr "Sndio é¯èª¤ï¼sio_open() 失æ"
-#: src/sndio/sndio.c:400
-msgid "(empty means default)"
-msgstr "(空ç½è¡¨ç¤ºä½¿ç¨é è¨å¼)"
+#: src/sndio-ng/sndio.cc:222
+msgid "Sndio error: sio_setpar() failed"
+msgstr "Sndio é¯èª¤ï¼sio_setpar() 失æ"
-#: src/sndio/sndio.c:416
-msgid "OK"
-msgstr "確èª"
+#: src/sndio-ng/sndio.cc:234
+msgid "Sndio error: sio_start() failed"
+msgstr "Sndio é¯èª¤ï¼sio_start() 失æ"
-#: src/song_change/song_change.c:54
+#: src/song_change/song_change.cc:33
msgid "Song Change"
msgstr "ææ²åæ"
-#: src/song_change/song_change.c:428
-msgid "Command to run when Audacious starts a new song."
-msgstr "ç¶ Audacious éå§ææ¾æ°çææ²æå·è¡çæä»¤ã"
+#: src/song_change/song_change.cc:342
+msgid ""
+"<span size='small'>Parameters passed to the shell should be encapsulated in "
+"quotes. Doing otherwise is a security risk.</span>"
+msgstr ""
+"<span size='small'>å³çµ¦ shell ç忏æè©²ç¨éå¼èå
èµ·ä¾ï¼å¦åææå®å
¨é¢¨éªã</"
+"span>"
+
+#: src/song_change/song_change.cc:358
+msgid "<b>Commands</b>"
+msgstr "<b>å½ä»¤</b>"
-#: src/song_change/song_change.c:430 src/song_change/song_change.c:436
-#: src/song_change/song_change.c:442 src/song_change/song_change.c:448
-msgid "Command:"
-msgstr "å½ä»¤ï¼"
+#: src/song_change/song_change.cc:360
+msgid "Command to run when starting a new song:"
+msgstr "éå§ææ¾æ°ææ²æå·è¡æ¤å½ä»¤ï¼"
-#: src/song_change/song_change.c:434
-msgid "Command to run toward the end of a song."
-msgstr "æ¯ç¶ä¸é¦ææ²ææ¾å®æå·è¡å½ä»¤"
+#: src/song_change/song_change.cc:364
+msgid "Command to run at the end of a song:"
+msgstr "ç¶æé¦åææ¾å®æå·è¡æ¤å½ä»¤ï¼"
-#: src/song_change/song_change.c:440
-msgid "Command to run when Audacious reaches the end of the playlist."
-msgstr "æ¯ç¶ Audacious ææ¾éå°æ¸
å®å°¾ç«¯æå·è¡å½ä»¤"
+#: src/song_change/song_change.cc:368
+msgid "Command to run at the end of the playlist:"
+msgstr "ææ¾è³ææ¾æ¸
å®ççµå°¾æå·è¡æ¤å½ä»¤ï¼"
-#: src/song_change/song_change.c:446
-msgid ""
-"Command to run when title changes for a song (i.e. network streams titles)."
-msgstr "ç¶ä¸é¦æçæ¨é¡æ¹è®æå·è¡å½ä»¤ã(網路串æµçæ¨é¡)"
+#: src/song_change/song_change.cc:372
+msgid "Command to run when song title changes (for network streams):"
+msgstr "ç¶ææ²æ¨é¡æ¹è®æå·è¡æ¤å½ä»¤ (網路串æµç¨)ï¼"
-#: src/song_change/song_change.c:452
+#: src/song_change/song_change.cc:376
msgid ""
-"You can use the following format strings which\n"
-"will be substituted before calling the command\n"
-"(not all are useful for the end-of-playlist command):\n"
+"You can use the following format strings which will be substituted before "
+"calling the command (not all are useful for the end-of-playlist command):\n"
"\n"
"%F: Frequency (in hertz)\n"
"%c: Number of channels\n"
@@ -3773,35 +4036,30 @@ msgid ""
"%b: Album\n"
"%T: Track title"
msgstr ""
-"æ¨å¯ä»¥å¨å½ä»¤ä¸ä½¿ç¨ä¸åçæ ¼å¼å串ã\n"
-"å®åæå¨å·è¡å½ä»¤å被實éå¼å代ã\n"
-"(䏿¯å
¨é¨é½è½å¨ææ¾æ¸
å®çµæå½ä»¤ä¸ä½¿ç¨)\n"
+"æ¨å¯ä»¥ä½¿ç¨ä»¥ä¸çæ ¼å¼å串ä¾è¡¨ç¤ºç¹æ®æ¬ä½ï¼ä¸æ¯å
¨é¨é½è½å¨ææ¾æ¸
å®çµæå½ä»¤ä¸ä½¿"
+"ç¨ï¼ï¼\n"
"\n"
-"%Fï¼é »ç (赫è²)\n"
-"%cï¼è²éæ¸ç®\n"
-"%fï¼æªå (宿´è·¯å¾)\n"
+"%Fï¼é »ç (HZ)\n"
+"%cï¼è²éæ¸\n"
+"%fï¼æªæ¡å稱 (宿´è·¯å¾)\n"
"%lï¼é·åº¦ (毫ç§)\n"
"%n æ %sï¼ææ²å稱\n"
"%rï¼ä½å
ç (bps)\n"
-"%tï¼ææ¾æ¸
å®ä½ç½® (%02d)\n"
+"%tï¼ææ¾æ¸
å®çä½ç½® (%02d)\n"
"%pï¼ææ¾ä¸ (1 æ 0)\n"
"%aï¼è人\n"
"%bï¼å°è¼¯\n"
"%Tï¼é³è»æ¨é¡"
-#: src/song_change/song_change.c:479
-msgid ""
-"<span size='small'>Parameters passed to the shell should be encapsulated in "
-"quotes. Doing otherwise is a security risk.</span>"
-msgstr ""
-"<span size='small'>å³çµ¦ shell ç忏æè©²ç¨éå¼èå
èµ·ä¾ï¼å¦åææå®å
¨é¢¨éªã</"
-"span>"
+#: src/song-info-qt/song-info.cc:32
+msgid "Song Info (Qt)"
+msgstr "ææ²è³è¨ (Qt)"
-#: src/song_change/song_change.c:490
-msgid "Commands"
-msgstr "å½ä»¤"
+#: src/sox-resampler/sox-resampler.cc:44
+msgid "SoX Resampler"
+msgstr "SoX é忍£"
-#: src/sox-resampler/sox-resampler.c:137
+#: src/sox-resampler/sox-resampler.cc:144
msgid ""
"SoX Resampler Plugin for Audacious\n"
"Copyright 2013 MichaÅ Lipski\n"
@@ -3815,51 +4073,51 @@ msgstr ""
"Based on Sample Rate Converter Plugin:\n"
"Copyright 2010-2012 John Lindgren"
-#: src/sox-resampler/sox-resampler.c:143
+#: src/sox-resampler/sox-resampler.cc:150
msgid "Quick"
msgstr "å¿«é"
-#: src/sox-resampler/sox-resampler.c:144
+#: src/sox-resampler/sox-resampler.cc:151
msgid "Low"
msgstr "ä½"
-#: src/sox-resampler/sox-resampler.c:146
+#: src/sox-resampler/sox-resampler.cc:153
msgid "High"
msgstr "é«"
-#: src/sox-resampler/sox-resampler.c:147
+#: src/sox-resampler/sox-resampler.cc:154
msgid "Very High"
msgstr "é常é«"
-#: src/sox-resampler/sox-resampler.c:150
+#: src/sox-resampler/sox-resampler.cc:158
msgid "Quality:"
msgstr "å質ï¼"
-#: src/sox-resampler/sox-resampler.c:164
-msgid "SoX Resampler"
-msgstr "SoX é忍£"
+#: src/speed-pitch/speed-pitch.cc:51
+msgid "Speed and Pitch"
+msgstr "é度èé³é«"
-#: src/speed-pitch/speed-pitch.c:227
+#: src/speed-pitch/speed-pitch.cc:210
msgid "<b>Speed and Pitch</b>"
msgstr "<b>é度èé³é«</b>"
-#: src/speed-pitch/speed-pitch.c:228
+#: src/speed-pitch/speed-pitch.cc:211
msgid "Speed:"
msgstr "é度ï¼"
-#: src/speed-pitch/speed-pitch.c:231
+#: src/speed-pitch/speed-pitch.cc:214
msgid "Pitch:"
msgstr "é³é«ï¼"
-#: src/speed-pitch/speed-pitch.c:266
-msgid "Speed and Pitch"
-msgstr "é度èé³é«"
+#: src/statusicon/statusicon.cc:47
+msgid "Status Icon"
+msgstr "çæ
å示"
-#: src/statusicon/statusicon.c:269
+#: src/statusicon/statusicon.cc:283
msgid "Se_ttings ..."
msgstr "è¨å®(_T) ..."
-#: src/statusicon/statusicon.c:371
+#: src/statusicon/statusicon.cc:372
msgid ""
"Status Icon Plugin\n"
"\n"
@@ -3876,39 +4134,39 @@ msgstr ""
"\n"
"éå夿æä¾ä¸åçæ
å示並æ¾å¨ç³»çµ±éç¥åã"
-#: src/statusicon/statusicon.c:378
+#: src/statusicon/statusicon.cc:379
msgid "<b>Mouse Scroll Action</b>"
msgstr "<b>æ»é¼ 滾輪åä½</b>"
-#: src/statusicon/statusicon.c:379
+#: src/statusicon/statusicon.cc:380
msgid "Change volume"
msgstr "調æ´é³é"
-#: src/statusicon/statusicon.c:382
+#: src/statusicon/statusicon.cc:383
msgid "Change playing song"
msgstr "åæææ¾ææ²"
-#: src/statusicon/statusicon.c:385
+#: src/statusicon/statusicon.cc:386
msgid "<b>Other Settings</b>"
msgstr "<b>å
¶ä»è¨å®</b>"
-#: src/statusicon/statusicon.c:386
+#: src/statusicon/statusicon.cc:387
msgid "Disable the popup window"
msgstr "ééå½åºå¼è¦çª"
-#: src/statusicon/statusicon.c:388
+#: src/statusicon/statusicon.cc:389
msgid "Close to the system tray"
msgstr "縮å°ç³»çµ±å"
-#: src/statusicon/statusicon.c:390
+#: src/statusicon/statusicon.cc:391
msgid "Advance in playlist when scrolling upward"
msgstr "ä»¥èæ»é¼ æ»¾è¼ªçåæ¹ååæææ²"
-#: src/statusicon/statusicon.c:399
-msgid "Status Icon"
-msgstr "çæ
å示"
+#: src/stereo_plugin/stereo.cc:19
+msgid "Extra Stereo"
+msgstr "é¡å¤ç«é«è²ææ"
-#: src/stereo_plugin/stereo.c:17
+#: src/stereo_plugin/stereo.cc:36
msgid ""
"Extra Stereo Plugin\n"
"\n"
@@ -3918,24 +4176,24 @@ msgstr ""
"\n"
"By Johan Levin, 1999"
-#: src/stereo_plugin/stereo.c:25
+#: src/stereo_plugin/stereo.cc:44
msgid "<b>Extra Stereo</b>"
msgstr "<b>é¡å¤ç«é«è²ææ</b>"
-#: src/stereo_plugin/stereo.c:36
-msgid "Extra Stereo"
-msgstr "é¡å¤ç«é«è²ææ"
+#: src/tonegen/tonegen.cc:45
+msgid "Tone Generator"
+msgstr "é³èª¿ç¢çå¨"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
#, c-format
msgid "%s %.1f Hz"
msgstr "%s %.1f Hz"
-#: src/tonegen/tonegen.c:83
+#: src/tonegen/tonegen.cc:94
msgid "Tone Generator: "
msgstr "é³èª¿ç¢çå¨ï¼"
-#: src/tonegen/tonegen.c:174
+#: src/tonegen/tonegen.cc:160
msgid ""
"Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
"Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n"
@@ -3949,15 +4207,11 @@ msgstr ""
"ç¨æ³ï¼å å
¥ç¶²åï¼tone://frequency1;frequency2;frequency3;...\n"
"ç¯ä¾ï¼tone://2000;2005 æææ¾ 2000 HZ å 2005HZ çæ£å¼¦æ³¢"
-#: src/tonegen/tonegen.c:183
-msgid "Tone Generator"
-msgstr "é³èª¿ç¢çå¨"
-
-#: src/voice_removal/voice_removal.c:53
+#: src/voice_removal/voice_removal.cc:28
msgid "Voice Removal"
msgstr "人è²ç§»é¤"
-#: src/vorbis/vorbis.c:484
+#: src/vorbis/vorbis.cc:465
msgid ""
"Audacious Ogg Vorbis Decoder\n"
"\n"
@@ -3995,11 +4249,46 @@ msgstr ""
"Gian-Carlo Pascutto <gcp at sjeng.org>\n"
"Eugene Zagidullin <e.asphyx at gmail.com>"
-#: src/vorbis/vorbis.c:504
+#: src/vorbis/vorbis.h:18
msgid "Ogg Vorbis Decoder"
msgstr "Ogg Vorbis 解碼å¨"
-#: src/vtx/vtx.c:167
+#: src/vtx/info.cc:22
+#, c-format
+msgid "Details about %s"
+msgstr "éæ¼ %s ç詳細è³è¨"
+
+#: src/vtx/info.cc:24
+msgid ""
+"Title: %t\n"
+"Author: %a\n"
+"From: %f\n"
+"Tracker: %T\n"
+"Comment: %C\n"
+"Chip type: %c\n"
+"Stereo: %s\n"
+"Loop: %l\n"
+"Chip freq: %F\n"
+"Player Freq: %P\n"
+"Year: %y"
+msgstr ""
+"æ¨é¡ï¼%t\n"
+"ä½è
ï¼%a\n"
+"ä¾èªï¼%f\n"
+"Tracker: %T\n"
+"å註ï¼%C\n"
+"æ¶çé¡åï¼%c\n"
+"ç«é«è²ï¼%s\n"
+"循ç°ï¼%l\n"
+"æ¶çé »çï¼%F\n"
+"ææ¾å¨é »çï¼%P\n"
+"年份ï¼%y"
+
+#: src/vtx/vtx.cc:38
+msgid "VTX Decoder"
+msgstr "VTX 解碼å¨"
+
+#: src/vtx/vtx.cc:184
msgid ""
"Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
@@ -4009,19 +4298,19 @@ msgstr ""
"Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
"Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>"
-#: src/vtx/vtx.c:173
-msgid "VTX Decoder"
-msgstr "VTX 解碼å¨"
+#: src/wavpack/wavpack.cc:24
+msgid "WavPack Decoder"
+msgstr "WavPack 解碼å¨"
-#: src/wavpack/wavpack.c:214
+#: src/wavpack/wavpack.cc:211
msgid "lossy (hybrid)"
msgstr "失ç (æ··å)"
-#: src/wavpack/wavpack.c:216
+#: src/wavpack/wavpack.cc:213
msgid "lossy"
msgstr "失ç"
-#: src/wavpack/wavpack.c:265
+#: src/wavpack/wavpack.cc:255
msgid ""
"Copyright 2006 William Pitcock <nenolod at nenolod.net>\n"
"\n"
@@ -4031,23 +4320,18 @@ msgstr ""
"\n"
"Some of the plugin code was by Miles Egan."
-#: src/wavpack/wavpack.c:272
-msgid "WavPack Decoder"
-msgstr "WavPack 解碼å¨"
-
-#: src/xsf/plugin.c:217
+#: src/xsf/plugin.cc:50
msgid "2SF Decoder"
msgstr "2SF 解碼å¨"
-#: src/xspf/xspf.c:438
-msgid "XML Shareable Playlists (XSPF)"
-msgstr "XML å¯åäº«å¼ææ¾æ¸
å® (XSPF)"
-
-#~ msgid "32.0 kHz:"
-#~ msgstr "32.0 kHzï¼"
+#: src/xsf/plugin.cc:238
+msgid "<b>XSF Configuration</b>"
+msgstr "<b>XSF çµæ
</b>"
-#~ msgid "88.2 kHz:"
-#~ msgstr "88.2 kHzï¼"
+#: src/xsf/plugin.cc:239
+msgid "Ignore length from file"
+msgstr "忽ç¥ä¾èªæªæ¡çé·åº¦è³è¨"
-#~ msgid "176.4 kHz:"
-#~ msgstr "176.4 kHzï¼"
+#: src/xspf/xspf.cc:89
+msgid "XML Shareable Playlists (XSPF)"
+msgstr "XML å¯åäº«å¼ææ¾æ¸
å® (XSPF)"
diff --git a/src/aac-raw/Makefile b/src/aac-raw/Makefile
index f44471f3d6e9..c3c9ee2bf06c 100644
--- a/src/aac-raw/Makefile
+++ b/src/aac-raw/Makefile
@@ -1,12 +1,14 @@
PLUGIN = aac-raw${PLUGIN_SUFFIX}
-SRCS = aac.c
+SRCS = aac.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${FAAD_CFLAGS} -I../..
LIBS += ${FAAD_LIBS} -lm -laudtag
diff --git a/src/aac-raw/aac.c b/src/aac-raw/aac.c
deleted file mode 100644
index f5dd85a4c8c5..000000000000
--- a/src/aac-raw/aac.c
+++ /dev/null
@@ -1,482 +0,0 @@
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <neaacdec.h>
-
-#include <audacious/audtag.h>
-#include <audacious/input.h>
-#include <audacious/plugin.h>
-#include <audacious/i18n.h>
-
-/*
- * BUFFER_SIZE is the highest amount of memory that can be pulled.
- * We use this for sanity checks, among other things, as mp4ff needs
- * a labotomy sometimes.
- */
-#define BUFFER_SIZE (FAAD_MIN_STREAMSIZE * 16)
-
-static const char *fmts[] = { "aac", NULL };
-
-/*
- * These routines are derived from MPlayer.
- */
-
-/// \param srate (out) sample rate
-/// \param num (out) number of audio frames in this ADTS frame
-/// \return size of the ADTS frame in bytes
-/// aac_parse_frames needs a buffer at least 8 bytes long
-int aac_parse_frame (unsigned char * buf, int *srate, int *num)
-{
- int i = 0, sr, fl = 0;
- static int srates[] =
- { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000,
- 11025, 8000, 0, 0, 0 };
-
- if ((buf[i] != 0xFF) || ((buf[i + 1] & 0xF6) != 0xF0))
- return 0;
-
-/* We currently have no use for the id below.
- id = (buf[i+1] >> 3) & 0x01; //id=1 mpeg2, 0: mpeg4
-*/
- sr = (buf[i + 2] >> 2) & 0x0F;
- if (sr > 11)
- return 0;
- *srate = srates[sr];
-
- fl =
- ((buf[i + 3] & 0x03) << 11) | (buf[i + 4] << 3) | ((buf[i +
- 5] >> 5) & 0x07);
- *num = (buf[i + 6] & 0x02) + 1;
-
- return fl;
-}
-
-#define PROBE_DEBUG(...)
-
-/* Searches <length> bytes of data for an ADTS header. Returns the offset of
- * the first header or -1 if none is found. Sets <size> to the length of the
- * frame. */
-static int find_aac_header (unsigned char * data, int length, int * size)
-{
- int offset, a, b;
-
- for (offset = 0; offset <= length - 8; offset++)
- {
- if (data[offset] != 255)
- continue;
-
- *size = aac_parse_frame (data + offset, &a, &b);
-
- if (*size < 8)
- continue;
-
- return offset;
- }
-
- return -1;
-}
-
-static bool_t parse_aac_stream (const char * filename, VFSFile * stream)
-{
- unsigned char data[8192];
- int offset, found, inner, size;
-
- size = 0; /* avoid bogus uninitialized variable warning */
-
- if (vfs_fread (data, 1, sizeof data, stream) != sizeof data)
- {
- PROBE_DEBUG ("Read failed.\n");
- return FALSE;
- }
-
- offset = 0;
-
- for (found = 0; found < 3; found++)
- {
- inner = find_aac_header (data + offset, sizeof data - offset, &size);
-
- if (!(inner == 0 || (found == 0 && inner > 0)))
- {
- PROBE_DEBUG ("Only %d ADTS headers.\n", found);
- return FALSE;
- }
-
- offset += inner + size;
- }
-
- PROBE_DEBUG ("Accepted.\n");
- return TRUE;
-}
-
-/* Quick search for an ADTS or ADIF header in the first <len> bytes of <buf>.
- * Returns the byte offset of the header or <len> if none is found. */
-
-static int aac_probe (unsigned char * buf, int len)
-{
- for (int i = 0; i <= len - 4; i ++)
- {
- if ((buf[i] == 0xff && (buf[i + 1] & 0xf6) == 0xf0) || ! strncmp
- ((char *) buf + i, "ADIF", 4))
- return i;
- }
-
- return len;
-}
-
-/* Gets info (some approximated) from an AAC/ADTS file. <length> is
- * milliseconds, <bitrate> is kilobits per second. Any parameters that cannot
- * be read are set to -1. */
-static void calc_aac_info (VFSFile * handle, int * length, int * bitrate,
- int * samplerate, int * channels)
-{
- NeAACDecHandle decoder;
- NeAACDecFrameInfo frame;
- bool_t initted = FALSE;
- int size = vfs_fsize (handle);
- unsigned char buffer[BUFFER_SIZE];
- int offset = 0, filled = 0;
- int found, bytes_used = 0, time_used = 0;
-
- decoder = NULL; /* avoid bogus uninitialized variable warning */
-
- *length = -1;
- *bitrate = -1;
- *samplerate = -1;
- *channels = -1;
-
- /* look for a representative bitrate in the middle of the file */
- if (size > 0 && vfs_fseek (handle, size / 2, SEEK_SET))
- goto DONE;
-
- for (found = 0; found < 32; found++)
- {
- if (filled < BUFFER_SIZE / 2)
- {
- memmove (buffer, buffer + offset, filled);
- offset = 0;
-
- if (vfs_fread (buffer + filled, 1, BUFFER_SIZE - filled, handle)
- != BUFFER_SIZE - filled)
- {
- PROBE_DEBUG ("Read failed.\n");
- goto DONE;
- }
-
- filled = BUFFER_SIZE;
- }
-
- if (!initted)
- {
- int inner, a;
- unsigned long r;
- unsigned char ch;
-
- inner = find_aac_header (buffer + offset, filled, &a);
-
- if (inner < 0)
- {
- PROBE_DEBUG ("No ADTS header.\n");
- goto DONE;
- }
-
- offset += inner;
- filled -= inner;
-
- decoder = NeAACDecOpen ();
- inner = NeAACDecInit (decoder, buffer + offset, filled, &r, &ch);
-
- if (inner < 0)
- {
- PROBE_DEBUG ("Decoder init failed.\n");
- NeAACDecClose (decoder);
- goto DONE;
- }
-
- offset += inner;
- filled -= inner;
- bytes_used += inner;
-
- *samplerate = r;
- *channels = ch;
- initted = TRUE;
- }
-
- if (NeAACDecDecode (decoder, &frame, buffer + offset, filled) == NULL)
- {
- PROBE_DEBUG ("Decode failed.\n");
- goto DONE;
- }
-
- if (frame.samplerate != *samplerate || frame.channels != *channels)
- {
- PROBE_DEBUG ("Parameter mismatch.\n");
- goto DONE;
- }
-
- offset += frame.bytesconsumed;
- filled -= frame.bytesconsumed;
- bytes_used += frame.bytesconsumed;
- time_used += frame.samples / frame.channels * (int64_t) 1000 /
- frame.samplerate;
- }
-
- /* bits per millisecond = kilobits per second */
- *bitrate = bytes_used * 8 / time_used;
-
- if (size > 0)
- *length = size * (int64_t) time_used / bytes_used;
-
- DONE:
- if (initted)
- NeAACDecClose (decoder);
-}
-
-static Tuple *aac_get_tuple (const char * filename, VFSFile * handle)
-{
- Tuple *tuple = tuple_new_from_filename (filename);
- int length, bitrate, samplerate, channels;
-
- tuple_set_str (tuple, FIELD_CODEC, "MPEG-2/4 AAC");
-
- if (!vfs_is_remote (filename))
- {
- calc_aac_info (handle, &length, &bitrate, &samplerate, &channels);
-
- if (length > 0)
- tuple_set_int (tuple, FIELD_LENGTH, length);
-
- if (bitrate > 0)
- tuple_set_int (tuple, FIELD_BITRATE, bitrate);
- }
-
- tag_update_stream_metadata (tuple, handle);
-
- return tuple;
-}
-
-static void aac_seek (VFSFile * file, NeAACDecHandle dec, int time, int len,
- void * buf, int size, int * buflen)
-{
- /* == ESTIMATE BYTE OFFSET == */
-
- int64_t total = vfs_fsize (file);
- if (total < 0)
- {
- fprintf (stderr, "aac: File is not seekable.\n");
- return;
- }
-
- /* == SEEK == */
-
- if (vfs_fseek (file, total * time / len, SEEK_SET))
- return;
-
- * buflen = vfs_fread (buf, 1, size, file);
-
- /* == FIND FRAME HEADER == */
-
- int used = aac_probe (buf, * buflen);
-
- if (used == * buflen)
- {
- fprintf (stderr, "aac: No valid frame header found.\n");
- * buflen = 0;
- return;
- }
-
- if (used)
- {
- * buflen -= used;
- memmove (buf, (char *) buf + used, * buflen);
- * buflen += vfs_fread ((char *) buf + * buflen, 1, size - * buflen, file);
- }
-
- /* == START DECODING == */
-
- unsigned char chan;
- unsigned long rate;
-
- if ((used = NeAACDecInit (dec, buf, * buflen, & rate, & chan)))
- {
- * buflen -= used;
- memmove (buf, (char *) buf + used, * buflen);
- * buflen += vfs_fread ((char *) buf + * buflen, 1, size - * buflen, file);
- }
-}
-
-static bool_t my_decode_aac (const char * filename, VFSFile * file)
-{
- NeAACDecHandle decoder = 0;
- NeAACDecConfigurationPtr decoder_config;
- unsigned long samplerate = 0;
- unsigned char channels = 0;
- int bitrate = 0;
-
- Tuple * tuple = aud_input_get_tuple ();
-
- if (tuple != NULL)
- {
- bitrate = tuple_get_int (tuple, FIELD_BITRATE);
- bitrate = 1000 * MAX (0, bitrate);
- }
-
- if ((decoder = NeAACDecOpen ()) == NULL)
- {
- fprintf (stderr, "AAC: Open Decoder Error\n");
- goto ERR;
- }
-
- decoder_config = NeAACDecGetCurrentConfiguration (decoder);
- decoder_config->outputFormat = FAAD_FMT_FLOAT;
- NeAACDecSetConfiguration (decoder, decoder_config);
-
- /* == FILL BUFFER == */
-
- unsigned char buf[BUFFER_SIZE];
- int buflen = vfs_fread (buf, 1, sizeof buf, file);
-
- /* == SKIP ID3 TAG == */
-
- if (buflen >= 10 && ! strncmp ((char *) buf, "ID3", 3))
- {
- if (vfs_fseek (file, 10 + (buf[6] << 21) + (buf[7] << 14) + (buf[8] <<
- 7) + buf[9], SEEK_SET))
- {
- fprintf (stderr, "aac: Failed to seek past ID3v2 tag.\n");
- goto ERR_CLOSE_DECODER;
- }
-
- buflen = vfs_fread (buf, 1, sizeof buf, file);
- }
-
- /* == FIND FRAME HEADER == */
-
- int used = aac_probe (buf, buflen);
-
- if (used == buflen)
- {
- fprintf (stderr, "aac: No valid frame header found.\n");
- goto ERR_CLOSE_DECODER;
- }
-
- if (used)
- {
- buflen -= used;
- memmove (buf, buf + used, buflen);
- buflen += vfs_fread (buf + buflen, 1, sizeof buf - buflen, file);
- }
-
- /* == START DECODING == */
-
- if ((used = NeAACDecInit (decoder, buf, buflen, & samplerate, & channels)))
- {
- buflen -= used;
- memmove (buf, buf + used, buflen);
- buflen += vfs_fread (buf + buflen, 1, sizeof buf - buflen, file);
- }
-
- /* == CHECK FOR METADATA == */
-
- if (tuple && tag_update_stream_metadata (tuple, file))
- {
- tuple_ref (tuple);
- aud_input_set_tuple (tuple);
- }
-
- /* == START PLAYBACK == */
-
- if (! aud_input_open_audio (FMT_FLOAT, samplerate, channels))
- goto ERR_CLOSE_DECODER;
-
- aud_input_set_bitrate (bitrate);
-
- /* == MAIN LOOP == */
-
- while (! aud_input_check_stop ())
- {
- /* == HANDLE SEEK REQUESTS == */
-
- int seek_value = aud_input_check_seek ();
-
- if (seek_value >= 0)
- {
- int length = tuple ? tuple_get_int (tuple, FIELD_LENGTH) : 0;
-
- if (length > 0)
- aac_seek (file, decoder, seek_value, length, buf, sizeof buf, & buflen);
- }
-
- /* == CHECK FOR END OF FILE == */
-
- if (! buflen)
- break;
-
- /* == CHECK FOR METADATA == */
-
- if (tuple && tag_update_stream_metadata (tuple, file))
- {
- tuple_ref (tuple);
- aud_input_set_tuple (tuple);
- }
-
- /* == DECODE A FRAME == */
-
- NeAACDecFrameInfo info;
- void * audio = NeAACDecDecode (decoder, & info, buf, buflen);
-
- if (info.error)
- {
- fprintf (stderr, "aac: %s.\n", NeAACDecGetErrorMessage (info.error));
-
- if (buflen)
- {
- used = 1 + aac_probe (buf + 1, buflen - 1);
- buflen -= used;
- memmove (buf, buf + used, buflen);
- buflen += vfs_fread (buf + buflen, 1, sizeof buf - buflen, file);
- }
-
- continue;
- }
-
- if ((used = info.bytesconsumed))
- {
- buflen -= used;
- memmove (buf, buf + used, buflen);
- buflen += vfs_fread (buf + buflen, 1, sizeof buf - buflen, file);
- }
-
- /* == PLAY THE SOUND == */
-
- if (audio && info.samples)
- aud_input_write_audio (audio, sizeof (float) * info.samples);
- }
-
- NeAACDecClose (decoder);
-
- if (tuple)
- tuple_unref (tuple);
-
- return TRUE;
-
-ERR_CLOSE_DECODER:
- NeAACDecClose (decoder);
-
-ERR:
- if (tuple)
- tuple_unref (tuple);
-
- return FALSE;
-}
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("AAC (Raw) Decoder"),
- .domain = PACKAGE,
- .play = my_decode_aac,
- .is_our_file_from_vfs = parse_aac_stream,
- .probe_for_tuple = aac_get_tuple,
- .extensions = fmts,
-)
diff --git a/src/aac-raw/aac.cc b/src/aac-raw/aac.cc
new file mode 100644
index 000000000000..1a6d2515cf11
--- /dev/null
+++ b/src/aac-raw/aac.cc
@@ -0,0 +1,477 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <neaacdec.h>
+
+#include <audacious/audtag.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+class AACDecoder : public InputPlugin
+{
+public:
+ static const char * const exts[];
+
+ static constexpr PluginInfo info = {
+ N_("AAC (Raw) Decoder"),
+ PACKAGE
+ };
+
+ static constexpr auto iinfo = InputInfo ()
+ .with_exts (exts);
+
+ constexpr AACDecoder () : InputPlugin (info, iinfo) {}
+
+ bool is_our_file (const char * filename, VFSFile & file);
+ Tuple read_tuple (const char * filename, VFSFile & file);
+ bool play (const char * filename, VFSFile & file);
+};
+
+EXPORT AACDecoder aud_plugin_instance;
+
+const char * const AACDecoder::exts[] = {"aac", nullptr};
+
+/*
+ * BUFFER_SIZE is the highest amount of memory that can be pulled.
+ * We use this for sanity checks, among other things, as mp4ff needs
+ * a labotomy sometimes.
+ */
+#define BUFFER_SIZE (FAAD_MIN_STREAMSIZE * 16)
+
+/*
+ * These routines are derived from MPlayer.
+ */
+
+/// \param srate (out) sample rate
+/// \param num (out) number of audio frames in this ADTS frame
+/// \return size of the ADTS frame in bytes
+/// aac_parse_frames needs a buffer at least 8 bytes long
+int aac_parse_frame (unsigned char * buf, int *srate, int *num)
+{
+ int i = 0, sr, fl = 0;
+ static int srates[] =
+ { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000,
+ 11025, 8000, 0, 0, 0 };
+
+ if ((buf[i] != 0xFF) || ((buf[i + 1] & 0xF6) != 0xF0))
+ return 0;
+
+/* We currently have no use for the id below.
+ id = (buf[i+1] >> 3) & 0x01; //id=1 mpeg2, 0: mpeg4
+*/
+ sr = (buf[i + 2] >> 2) & 0x0F;
+ if (sr > 11)
+ return 0;
+ *srate = srates[sr];
+
+ fl =
+ ((buf[i + 3] & 0x03) << 11) | (buf[i + 4] << 3) | ((buf[i +
+ 5] >> 5) & 0x07);
+ *num = (buf[i + 6] & 0x02) + 1;
+
+ return fl;
+}
+
+#define PROBE_DEBUG(...)
+
+/* Searches <length> bytes of data for an ADTS header. Returns the offset of
+ * the first header or -1 if none is found. Sets <size> to the length of the
+ * frame. */
+static int find_aac_header (unsigned char * data, int length, int * size)
+{
+ int offset, a, b;
+
+ for (offset = 0; offset <= length - 8; offset++)
+ {
+ if (data[offset] != 255)
+ continue;
+
+ *size = aac_parse_frame (data + offset, &a, &b);
+
+ if (*size < 8)
+ continue;
+
+ return offset;
+ }
+
+ return -1;
+}
+
+bool AACDecoder::is_our_file (const char * filename, VFSFile & stream)
+{
+ unsigned char data[8192];
+ int offset, found, inner, size;
+
+ size = 0; /* avoid bogus uninitialized variable warning */
+
+ if (stream.fread (data, 1, sizeof data) != sizeof data)
+ {
+ PROBE_DEBUG ("Read failed.\n");
+ return false;
+ }
+
+ offset = 0;
+
+ for (found = 0; found < 3; found++)
+ {
+ inner = find_aac_header (data + offset, sizeof data - offset, &size);
+
+ if (!(inner == 0 || (found == 0 && inner > 0)))
+ {
+ PROBE_DEBUG ("Only %d ADTS headers.\n", found);
+ return false;
+ }
+
+ offset += inner + size;
+ }
+
+ PROBE_DEBUG ("Accepted.\n");
+ return true;
+}
+
+/* Quick search for an ADTS or ADIF header in the first <len> bytes of <buf>.
+ * Returns the byte offset of the header or <len> if none is found. */
+
+static int aac_probe (unsigned char * buf, int len)
+{
+ for (int i = 0; i <= len - 4; i ++)
+ {
+ if ((buf[i] == 0xff && (buf[i + 1] & 0xf6) == 0xf0) || ! strncmp
+ ((char *) buf + i, "ADIF", 4))
+ return i;
+ }
+
+ return len;
+}
+
+/* Gets info (some approximated) from an AAC/ADTS file. <length> is
+ * milliseconds, <bitrate> is kilobits per second. Any parameters that cannot
+ * be read are set to -1. */
+static void calc_aac_info (VFSFile & handle, int * length, int * bitrate,
+ int * samplerate, int * channels)
+{
+ NeAACDecHandle decoder;
+ NeAACDecFrameInfo frame;
+ bool initted = false;
+ int size = handle.fsize ();
+ unsigned char buffer[BUFFER_SIZE];
+ int offset = 0, filled = 0;
+ int found, bytes_used = 0, time_used = 0;
+
+ decoder = nullptr; /* avoid bogus uninitialized variable warning */
+
+ *length = -1;
+ *bitrate = -1;
+ *samplerate = -1;
+ *channels = -1;
+
+ /* look for a representative bitrate in the middle of the file */
+ if (size < 0 || handle.fseek (size / 2, VFS_SEEK_SET) < 0)
+ goto DONE;
+
+ for (found = 0; found < 32; found++)
+ {
+ if (filled < BUFFER_SIZE / 2)
+ {
+ memmove (buffer, buffer + offset, filled);
+ offset = 0;
+
+ if (handle.fread (buffer + filled, 1, BUFFER_SIZE - filled)
+ != BUFFER_SIZE - filled)
+ {
+ PROBE_DEBUG ("Read failed.\n");
+ goto DONE;
+ }
+
+ filled = BUFFER_SIZE;
+ }
+
+ if (!initted)
+ {
+ int inner, a;
+ unsigned long r;
+ unsigned char ch;
+
+ inner = find_aac_header (buffer + offset, filled, &a);
+
+ if (inner < 0)
+ {
+ PROBE_DEBUG ("No ADTS header.\n");
+ goto DONE;
+ }
+
+ offset += inner;
+ filled -= inner;
+
+ decoder = NeAACDecOpen ();
+ inner = NeAACDecInit (decoder, buffer + offset, filled, &r, &ch);
+
+ if (inner < 0)
+ {
+ PROBE_DEBUG ("Decoder init failed.\n");
+ NeAACDecClose (decoder);
+ goto DONE;
+ }
+
+ offset += inner;
+ filled -= inner;
+ bytes_used += inner;
+
+ *samplerate = r;
+ *channels = ch;
+ initted = true;
+ }
+
+ if (NeAACDecDecode (decoder, &frame, buffer + offset, filled) == nullptr)
+ {
+ PROBE_DEBUG ("Decode failed.\n");
+ goto DONE;
+ }
+
+ if ((int)frame.samplerate != *samplerate || (int)frame.channels != *channels)
+ {
+ PROBE_DEBUG ("Parameter mismatch.\n");
+ goto DONE;
+ }
+
+ offset += frame.bytesconsumed;
+ filled -= frame.bytesconsumed;
+ bytes_used += frame.bytesconsumed;
+ time_used += frame.samples / frame.channels * (int64_t) 1000 /
+ frame.samplerate;
+ }
+
+ /* bits per millisecond = kilobits per second */
+ *bitrate = bytes_used * 8 / time_used;
+
+ if (size > 0)
+ *length = size * (int64_t) time_used / bytes_used;
+
+ DONE:
+ if (initted)
+ NeAACDecClose (decoder);
+}
+
+Tuple AACDecoder::read_tuple (const char * filename, VFSFile & handle)
+{
+ Tuple tuple;
+ int length, bitrate, samplerate, channels;
+
+ tuple.set_filename (filename);
+ tuple.set_str (Tuple::Codec, "MPEG-2/4 AAC");
+
+ calc_aac_info (handle, &length, &bitrate, &samplerate, &channels);
+
+ if (length > 0)
+ tuple.set_int (Tuple::Length, length);
+ if (bitrate > 0)
+ tuple.set_int (Tuple::Bitrate, bitrate);
+
+ tuple.fetch_stream_info (handle);
+
+ return tuple;
+}
+
+static void aac_seek (VFSFile & file, NeAACDecHandle dec, int time, int len,
+ void * buf, int size, int * buflen)
+{
+ /* == ESTIMATE BYTE OFFSET == */
+
+ int64_t total = file.fsize ();
+ if (total < 0)
+ {
+ AUDERR ("File is not seekable.\n");
+ return;
+ }
+
+ /* == SEEK == */
+
+ if (file.fseek (total * time / len, VFS_SEEK_SET))
+ return;
+
+ * buflen = file.fread (buf, 1, size);
+
+ /* == FIND FRAME HEADER == */
+
+ int used = aac_probe ((unsigned char *) buf, * buflen);
+
+ if (used == * buflen)
+ {
+ AUDERR ("No valid frame header found.\n");
+ * buflen = 0;
+ return;
+ }
+
+ if (used)
+ {
+ * buflen -= used;
+ memmove (buf, (char *) buf + used, * buflen);
+ * buflen += file.fread ((char *) buf + * buflen, 1, size - * buflen);
+ }
+
+ /* == START DECODING == */
+
+ unsigned char chan;
+ unsigned long rate;
+
+ if ((used = NeAACDecInit (dec, (unsigned char *) buf, * buflen, & rate, & chan)))
+ {
+ * buflen -= used;
+ memmove (buf, (char *) buf + used, * buflen);
+ * buflen += file.fread ((char *) buf + * buflen, 1, size - * buflen);
+ }
+}
+
+bool AACDecoder::play (const char * filename, VFSFile & file)
+{
+ NeAACDecHandle decoder = 0;
+ NeAACDecConfigurationPtr decoder_config;
+ unsigned long samplerate = 0;
+ unsigned char channels = 0;
+ int bitrate = 0;
+
+ Tuple tuple = get_playback_tuple ();
+
+ if (tuple)
+ {
+ bitrate = tuple.get_int (Tuple::Bitrate);
+ bitrate = 1000 * aud::max (0, bitrate);
+ }
+
+ if ((decoder = NeAACDecOpen ()) == nullptr)
+ {
+ AUDERR ("Open Decoder Error\n");
+ return false;
+ }
+
+ decoder_config = NeAACDecGetCurrentConfiguration (decoder);
+ decoder_config->outputFormat = FAAD_FMT_FLOAT;
+ NeAACDecSetConfiguration (decoder, decoder_config);
+
+ /* == FILL BUFFER == */
+
+ unsigned char buf[BUFFER_SIZE];
+ int buflen;
+ buflen = file.fread (buf, 1, sizeof buf);
+
+ /* == SKIP ID3 TAG == */
+
+ if (buflen >= 10 && ! strncmp ((char *) buf, "ID3", 3))
+ {
+ int tagsize = 10 + (buf[6] << 21) + (buf[7] << 14) + (buf[8] << 7) + buf[9];
+
+ if (file.fseek (tagsize, VFS_SEEK_SET))
+ {
+ AUDERR ("Failed to seek past ID3v2 tag.\n");
+ goto ERR_CLOSE_DECODER;
+ }
+
+ buflen = file.fread (buf, 1, sizeof buf);
+ }
+
+ /* == FIND FRAME HEADER == */
+
+ int used;
+ used = aac_probe (buf, buflen);
+
+ if (used == buflen)
+ {
+ AUDERR ("No valid frame header found.\n");
+ goto ERR_CLOSE_DECODER;
+ }
+
+ if (used)
+ {
+ buflen -= used;
+ memmove (buf, buf + used, buflen);
+ buflen += file.fread (buf + buflen, 1, sizeof buf - buflen);
+ }
+
+ /* == START DECODING == */
+
+ if ((used = NeAACDecInit (decoder, buf, buflen, & samplerate, & channels)))
+ {
+ buflen -= used;
+ memmove (buf, buf + used, buflen);
+ buflen += file.fread (buf + buflen, 1, sizeof buf - buflen);
+ }
+
+ /* == CHECK FOR METADATA == */
+
+ if (tuple && tuple.fetch_stream_info (file))
+ set_playback_tuple (tuple.ref ());
+
+ set_stream_bitrate (bitrate);
+
+ /* == START PLAYBACK == */
+
+ open_audio (FMT_FLOAT, samplerate, channels);
+
+ /* == MAIN LOOP == */
+
+ while (! check_stop ())
+ {
+ /* == HANDLE SEEK REQUESTS == */
+
+ int seek_value = check_seek ();
+
+ if (seek_value >= 0)
+ {
+ int length = tuple ? tuple.get_int (Tuple::Length) : 0;
+
+ if (length > 0)
+ aac_seek (file, decoder, seek_value, length, buf, sizeof buf, & buflen);
+ }
+
+ /* == CHECK FOR END OF FILE == */
+
+ if (! buflen)
+ break;
+
+ /* == CHECK FOR METADATA == */
+
+ if (tuple && tuple.fetch_stream_info (file))
+ set_playback_tuple (tuple.ref ());
+
+ /* == DECODE A FRAME == */
+
+ NeAACDecFrameInfo info;
+ void * audio = NeAACDecDecode (decoder, & info, buf, buflen);
+
+ if (info.error)
+ {
+ AUDERR ("%s.\n", NeAACDecGetErrorMessage (info.error));
+
+ if (buflen)
+ {
+ used = 1 + aac_probe (buf + 1, buflen - 1);
+ buflen -= used;
+ memmove (buf, buf + used, buflen);
+ buflen += file.fread (buf + buflen, 1, sizeof buf - buflen);
+ }
+
+ continue;
+ }
+
+ if ((used = info.bytesconsumed))
+ {
+ buflen -= used;
+ memmove (buf, buf + used, buflen);
+ buflen += file.fread (buf + buflen, 1, sizeof buf - buflen);
+ }
+
+ /* == PLAY THE SOUND == */
+
+ if (audio && info.samples)
+ write_audio (audio, sizeof (float) * info.samples);
+ }
+
+ NeAACDecClose (decoder);
+ return true;
+
+ERR_CLOSE_DECODER:
+ NeAACDecClose (decoder);
+ return false;
+}
diff --git a/src/aac/Makefile b/src/aac/Makefile
deleted file mode 100644
index 48e09e0716ed..000000000000
--- a/src/aac/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-PLUGIN = aac${PLUGIN_SUFFIX}
-
-SRCS = itunes-cover.c \
- libmp4.c \
- mp4_utils.c \
- mp4ff/mp4ff.c \
- mp4ff/mp4atom.c \
- mp4ff/mp4meta.c \
- mp4ff/mp4sample.c \
- mp4ff/mp4util.c \
- mp4ff/mp4tagupdate.c
-
-include ../../buildsys.mk
-include ../../extra.mk
-
-plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
-
-CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${FAAD_CFLAGS} -I../.. -I. -Imp4ff -DUSE_TAGGING=1
-LIBS += ${GLIB_LIBS} ${FAAD_LIBS} -lm
diff --git a/src/aac/itunes-cover.c b/src/aac/itunes-cover.c
deleted file mode 100644
index ac8ad962e5c3..000000000000
--- a/src/aac/itunes-cover.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * itunes-cover.c
- * John Lindgren, 2010
- *
- * The author hereby releases this code into the public domain.
- *
- * Reference:
- * http://atomicparsley.sourceforge.net/mpeg-4files.html
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <glib.h>
-
-#include <libaudcore/vfs.h>
-
-static const char * const hier[] = {"moov", "udta", "meta", "ilst", "covr", "data"};
-static const int skip[] = {0, 0, 4, 0, 0, 8};
-
-bool_t read_itunes_cover (const char * filename, VFSFile * file, void * *
- data, int64_t * size)
-{
- unsigned char b[8];
- int bsize;
-
- * data = NULL;
- * size = 0;
-
- /* Check for ftyp frame. */
-
- if (vfs_fread (b, 1, 8, file) != 8)
- return FALSE;
- if ((bsize = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]) < 8)
- return FALSE;
- if (strncmp ((char *) b + 4, "ftyp", 4))
- return FALSE;
- if (vfs_fseek (file, bsize - 8, SEEK_CUR))
- return FALSE;
-
- int64_t stop = INT64_MAX;
- int64_t at = bsize;
-
- /* Descend into frame hierarchy. */
-
- for (int h = 0; h < ARRAY_LEN (hier); h ++)
- {
- while (1)
- {
- if (vfs_fread (b, 1, 8, file) != 8)
- return FALSE;
- if ((bsize = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]) < 8
- || at + bsize > stop)
- return FALSE;
- if (! strncmp ((char *) b + 4, hier[h], 4))
- break;
- if (vfs_fseek (file, bsize - 8, SEEK_CUR))
- return FALSE;
-
- at += bsize;
- }
-
- stop = at + bsize;
- at += 8;
-
- /* Skip leading bytes in some frames. */
-
- if (skip[h])
- {
- if (vfs_fseek (file, skip[h], SEEK_CUR))
- return FALSE;
- at += skip[h];
- }
- }
-
- /* We're there. */
-
- * data = g_malloc (stop - at);
- * size = stop - at;
-
- if (vfs_fread (* data, 1, stop - at, file) != stop - at)
- {
- g_free (* data);
- * data = NULL;
- * size = 0;
- return FALSE;
- }
-
- return TRUE;
-}
diff --git a/src/aac/libmp4.c b/src/aac/libmp4.c
deleted file mode 100644
index 5ad655cc09a7..000000000000
--- a/src/aac/libmp4.c
+++ /dev/null
@@ -1,320 +0,0 @@
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <neaacdec.h>
-
-#include "mp4ff.h"
-
-#include <audacious/input.h>
-#include <audacious/plugin.h>
-#include <audacious/i18n.h>
-
-/*
- * BUFFER_SIZE is the highest amount of memory that can be pulled.
- * We use this for sanity checks, among other things, as mp4ff needs
- * a labotomy sometimes.
- */
-#define BUFFER_SIZE (FAAD_MIN_STREAMSIZE * 16)
-
-static const char *fmts[] = { "m4a", "mp4", NULL };
-
-int getAACTrack (mp4ff_t *);
-
-static uint32_t mp4_read_callback (void *data, void *buffer, uint32_t len)
-{
- if (data == NULL || buffer == NULL)
- return -1;
-
- return vfs_fread (buffer, 1, len, (VFSFile *) data);
-}
-
-static uint32_t mp4_seek_callback (void *data, uint64_t pos)
-{
- if (! data || pos > INT64_MAX)
- return -1;
-
- return vfs_fseek ((VFSFile *) data, pos, SEEK_SET);
-}
-
-static bool_t is_mp4_aac_file (const char * filename, VFSFile * handle)
-{
- mp4ff_callback_t mp4_data = {
- .read = mp4_read_callback,
- .seek = mp4_seek_callback,
- .user_data = handle
- };
-
- mp4ff_t *mp4_handle = mp4ff_open_read (&mp4_data);
- bool_t success;
-
- if (mp4_handle == NULL)
- return FALSE;
-
- success = (getAACTrack (mp4_handle) != -1);
-
- mp4ff_close (mp4_handle);
- return success;
-}
-
-static void read_and_set_string (mp4ff_t * mp4, int (*func) (const mp4ff_t *
- mp4, char * *string), Tuple * tuple, int field)
-{
- char *string = NULL;
-
- func (mp4, &string);
-
- if (string != NULL)
- tuple_set_str (tuple, field, string);
-
- g_free (string);
-}
-
-static Tuple *generate_tuple (const char * filename, mp4ff_t * mp4, int track)
-{
- Tuple *tuple = tuple_new_from_filename (filename);
- int64_t length;
- int scale, rate, channels, bitrate;
- char *year = NULL, *cd_track = NULL;
- char scratch[32];
-
- tuple_set_str (tuple, FIELD_CODEC, "MPEG-2/4 AAC");
-
- length = mp4ff_get_track_duration (mp4, track);
- scale = mp4ff_time_scale (mp4, track);
-
- if (length > 0 && scale > 0)
- tuple_set_int (tuple, FIELD_LENGTH, length * 1000 / scale);
-
- rate = mp4ff_get_sample_rate (mp4, track);
- channels = mp4ff_get_channel_count (mp4, track);
-
- if (rate > 0 && channels > 0)
- {
- snprintf (scratch, sizeof scratch, "%d kHz, %s", rate / 1000, channels
- == 1 ? _("mono") : channels == 2 ? _("stereo") : _("surround"));
- tuple_set_str (tuple, FIELD_QUALITY, scratch);
- }
-
- bitrate = mp4ff_get_avg_bitrate (mp4, track);
-
- if (bitrate > 0)
- tuple_set_int (tuple, FIELD_BITRATE, bitrate / 1000);
-
- read_and_set_string (mp4, mp4ff_meta_get_title, tuple, FIELD_TITLE);
- read_and_set_string (mp4, mp4ff_meta_get_album, tuple, FIELD_ALBUM);
- read_and_set_string (mp4, mp4ff_meta_get_artist, tuple, FIELD_ARTIST);
- read_and_set_string (mp4, mp4ff_meta_get_comment, tuple, FIELD_COMMENT);
- read_and_set_string (mp4, mp4ff_meta_get_genre, tuple, FIELD_GENRE);
-
- mp4ff_meta_get_date (mp4, &year);
-
- if (year != NULL)
- tuple_set_int (tuple, FIELD_YEAR, atoi (year));
-
- g_free (year);
-
- mp4ff_meta_get_track (mp4, &cd_track);
-
- if (cd_track != NULL)
- tuple_set_int (tuple, FIELD_TRACK_NUMBER, atoi (cd_track));
-
- g_free (cd_track);
-
- return tuple;
-}
-
-static Tuple *mp4_get_tuple (const char * filename, VFSFile * handle)
-{
- mp4ff_callback_t mp4cb;
- mp4ff_t *mp4;
- int track;
- Tuple *tuple;
-
- mp4cb.read = mp4_read_callback;
- mp4cb.seek = mp4_seek_callback;
- mp4cb.user_data = handle;
-
- mp4 = mp4ff_open_read (&mp4cb);
-
- if (mp4 == NULL)
- return NULL;
-
- track = getAACTrack (mp4);
-
- if (track < 0)
- {
- mp4ff_close (mp4);
- return NULL;
- }
-
- tuple = generate_tuple (filename, mp4, track);
- mp4ff_close (mp4);
- return tuple;
-}
-
-static bool_t my_decode_mp4 (const char * filename, mp4ff_t * mp4file)
-{
- // We are reading an MP4 file
- int mp4track = getAACTrack (mp4file);
- NeAACDecHandle decoder;
- NeAACDecConfigurationPtr decoder_config;
- unsigned char *buffer = NULL;
- unsigned bufferSize = 0;
- unsigned long samplerate = 0;
- unsigned char channels = 0;
- unsigned numSamples;
- unsigned long sampleID = 1;
- unsigned framesize = 0;
-
- if (mp4track < 0)
- {
- fprintf (stderr, "Unsupported Audio track type\n");
- return TRUE;
- }
-
- // Open decoder
- decoder = NeAACDecOpen ();
-
- // Configure for floating point output
- decoder_config = NeAACDecGetCurrentConfiguration (decoder);
- decoder_config->outputFormat = FAAD_FMT_FLOAT;
- NeAACDecSetConfiguration (decoder, decoder_config);
-
- mp4ff_get_decoder_config (mp4file, mp4track, &buffer, &bufferSize);
- if (!buffer)
- {
- NeAACDecClose (decoder);
- return FALSE;
- }
- if (NeAACDecInit2 (decoder, buffer, bufferSize, &samplerate, &channels) < 0)
- {
- NeAACDecClose (decoder);
-
- return FALSE;
- }
-
- g_free (buffer);
- if (!channels)
- {
- NeAACDecClose (decoder);
-
- return FALSE;
- }
- numSamples = mp4ff_num_samples (mp4file, mp4track);
-
- if (!aud_input_open_audio (FMT_FLOAT, samplerate, channels))
- {
- NeAACDecClose (decoder);
- return FALSE;
- }
-
- aud_input_set_tuple (generate_tuple (filename, mp4file, mp4track));
- aud_input_set_bitrate (mp4ff_get_avg_bitrate (mp4file, mp4track));
-
- while (! aud_input_check_stop ())
- {
- void *sampleBuffer;
- NeAACDecFrameInfo frameInfo;
- int rc;
-
- buffer = NULL;
- bufferSize = 0;
-
- /* If we've run to the end of the file, we're done. */
- if (sampleID >= numSamples)
- break;
-
- rc = mp4ff_read_sample (mp4file, mp4track,
- sampleID++, &buffer, &bufferSize);
-
- /* If we can't read the file, we're done. */
- if ((rc == 0) || (buffer == NULL) || (bufferSize == 0)
- || (bufferSize > BUFFER_SIZE))
- {
- fprintf (stderr, "MP4: read error\n");
- sampleBuffer = NULL;
-
- NeAACDecClose (decoder);
-
- return FALSE;
- }
-
- sampleBuffer = NeAACDecDecode (decoder, &frameInfo, buffer, bufferSize);
-
- /* If there was an error decoding, we're done. */
- if (frameInfo.error > 0)
- {
- fprintf (stderr, "MP4: %s\n", NeAACDecGetErrorMessage (frameInfo.error));
- NeAACDecClose (decoder);
-
- return FALSE;
- }
- if (buffer)
- {
- g_free (buffer);
- buffer = NULL;
- bufferSize = 0;
- }
-
- /* Calculate frame size from the first (non-blank) frame. This needs to
- * be done before we try to seek. */
- if (!framesize)
- {
- framesize = frameInfo.samples / frameInfo.channels;
-
- if (!framesize)
- continue;
- }
-
- /* Respond to seek/stop requests. This needs to be done after we
- * calculate frame size but of course before we write any audio. */
- int seek_value = aud_input_check_seek ();
-
- if (seek_value >= 0)
- {
- sampleID = (int64_t) seek_value * samplerate / 1000 / framesize;
- continue;
- }
-
- aud_input_write_audio (sampleBuffer, sizeof (float) * frameInfo.samples);
- }
-
- NeAACDecClose (decoder);
-
- return TRUE;
-}
-
-static bool_t mp4_play (const char * filename, VFSFile * file)
-{
- bool_t result;
-
- mp4ff_callback_t mp4cb = {
- .read = mp4_read_callback,
- .seek = mp4_seek_callback,
- .user_data = file
- };
-
- mp4ff_t * mp4file = mp4ff_open_read (& mp4cb);
- result = my_decode_mp4 (filename, mp4file);
- mp4ff_close (mp4file);
-
- return result;
-}
-
-bool_t read_itunes_cover (const char * filename, VFSFile * file, void * *
- data, int64_t * size);
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("AAC (MP4) Decoder"),
- .domain = PACKAGE,
- .play = mp4_play,
- .is_our_file_from_vfs = is_mp4_aac_file,
- .probe_for_tuple = mp4_get_tuple,
- .get_song_image = read_itunes_cover,
- .extensions = fmts,
-)
diff --git a/src/aac/mp4_utils.c b/src/aac/mp4_utils.c
deleted file mode 100644
index 7f83cf6d9f6f..000000000000
--- a/src/aac/mp4_utils.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * some functions for MP4 files
-*/
-
-#include <stdlib.h>
-#include <glib.h>
-
-#include "mp4ff.h"
-#include "neaacdec.h"
-
-int getAACTrack (mp4ff_t * infile)
-{
- int i, rc, numTracks = mp4ff_total_tracks (infile);
- for (i = 0; i < numTracks; i++)
- {
- unsigned char *buff = NULL;
- unsigned buff_size = 0;
- mp4AudioSpecificConfig mp4ASC;
-
- mp4ff_get_decoder_config (infile, i, &buff, &buff_size);
- if (buff != NULL)
- {
- rc = AudioSpecificConfig (buff, buff_size, &mp4ASC);
- g_free (buff);
- if (rc < 0)
- continue;
- return i;
- }
- }
- return -1;
-}
diff --git a/src/aac/mp4ff/mp4atom.c b/src/aac/mp4ff/mp4atom.c
deleted file mode 100644
index 23712dd1b06d..000000000000
--- a/src/aac/mp4ff/mp4atom.c
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
-**
-** 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.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** The "appropriate copyright message" mentioned in section 2c of the GPLv2
-** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Nero AG through Mpeg4AAClicense at nero.com.
-**
-** $Id: mp4atom.c,v 1.29 2009/01/19 23:56:30 menno Exp $
-**/
-
-#include <stdlib.h>
-#include "mp4ffint.h"
-
-#define COPYRIGHT_SYMBOL ((int8_t)0xA9)
-
-/* parse atom header size */
-static uint32_t mp4ff_atom_get_size(const uint8_t *data)
-{
- uint32_t result;
- uint32_t a, b, c, d;
-
- a = data[0];
- b = data[1];
- c = data[2];
- d = data[3];
-
- result = (a<<24) | (b<<16) | (c<<8) | d;
- //if (result > 0 && result < 8) result = 8;
-
- return result;
-}
-
-/* comnapre 2 atom names, returns 1 for equal, 0 for unequal */
-static int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1,
- const int8_t a2, const int8_t b2, const int8_t c2, const int8_t d2)
-{
- if (a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2)
- return 1;
- else
- return 0;
-}
-
-static uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b,
- const int8_t c, const int8_t d)
-{
- if (a == 'm')
- {
- if (mp4ff_atom_compare(a,b,c,d, 'm','o','o','v'))
- return ATOM_MOOV;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','i','n','f'))
- return ATOM_MINF;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','d','i','a'))
- return ATOM_MDIA;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','d','a','t'))
- return ATOM_MDAT;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','d','h','d'))
- return ATOM_MDHD;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','v','h','d'))
- return ATOM_MVHD;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','a'))
- return ATOM_MP4A;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','v'))
- return ATOM_MP4V;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','s'))
- return ATOM_MP4S;
- else if (mp4ff_atom_compare(a,b,c,d, 'm','e','t','a'))
- return ATOM_META;
- } else if (a == 't') {
- if (mp4ff_atom_compare(a,b,c,d, 't','r','a','k'))
- return ATOM_TRAK;
- else if (mp4ff_atom_compare(a,b,c,d, 't','k','h','d'))
- return ATOM_TKHD;
- else if (mp4ff_atom_compare(a,b,c,d, 't','r','e','f'))
- return ATOM_TREF;
- else if (mp4ff_atom_compare(a,b,c,d, 't','r','k','n'))
- return ATOM_TRACK;
- else if (mp4ff_atom_compare(a,b,c,d, 't','m','p','o'))
- return ATOM_TEMPO;
- else if (mp4ff_atom_compare(a,b,c,d, 't','v','n','n'))
- return ATOM_NETWORK;
- else if (mp4ff_atom_compare(a,b,c,d, 't','v','s','h'))
- return ATOM_SHOW;
- else if (mp4ff_atom_compare(a,b,c,d, 't','v','e','n'))
- return ATOM_EPISODENAME;
- else if (mp4ff_atom_compare(a,b,c,d, 't','v','s','n'))
- return ATOM_SEASON;
- else if (mp4ff_atom_compare(a,b,c,d, 't','v','e','s'))
- return ATOM_EPISODE;
- } else if (a == 's') {
- if (mp4ff_atom_compare(a,b,c,d, 's','t','b','l'))
- return ATOM_STBL;
- else if (mp4ff_atom_compare(a,b,c,d, 's','m','h','d'))
- return ATOM_SMHD;
- else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','d'))
- return ATOM_STSD;
- else if (mp4ff_atom_compare(a,b,c,d, 's','t','t','s'))
- return ATOM_STTS;
- else if (mp4ff_atom_compare(a,b,c,d, 's','t','c','o'))
- return ATOM_STCO;
- else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','c'))
- return ATOM_STSC;
- else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','z'))
- return ATOM_STSZ;
- else if (mp4ff_atom_compare(a,b,c,d, 's','t','z','2'))
- return ATOM_STZ2;
- else if (mp4ff_atom_compare(a,b,c,d, 's','k','i','p'))
- return ATOM_SKIP;
- else if (mp4ff_atom_compare(a,b,c,d, 's','i','n','f'))
- return ATOM_SINF;
- else if (mp4ff_atom_compare(a,b,c,d, 's','c','h','i'))
- return ATOM_SCHI;
- else if (mp4ff_atom_compare(a,b,c,d, 's','o','n','m'))
- return ATOM_SORTTITLE;
- else if (mp4ff_atom_compare(a,b,c,d, 's','o','a','l'))
- return ATOM_SORTALBUM;
- else if (mp4ff_atom_compare(a,b,c,d, 's','o','a','r'))
- return ATOM_SORTARTIST;
- else if (mp4ff_atom_compare(a,b,c,d, 's','o','a','a'))
- return ATOM_SORTALBUMARTIST;
- else if (mp4ff_atom_compare(a,b,c,d, 's','o','c','o'))
- return ATOM_SORTWRITER;
- else if (mp4ff_atom_compare(a,b,c,d, 's','o','s','n'))
- return ATOM_SORTSHOW;
- } else if (a == COPYRIGHT_SYMBOL) {
- if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'n','a','m'))
- return ATOM_TITLE;
- else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'A','R','T'))
- return ATOM_ARTIST;
- else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'w','r','t'))
- return ATOM_WRITER;
- else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'a','l','b'))
- return ATOM_ALBUM;
- else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'d','a','y'))
- return ATOM_DATE;
- else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'t','o','o'))
- return ATOM_TOOL;
- else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'c','m','t'))
- return ATOM_COMMENT;
- else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'g','e','n'))
- return ATOM_GENRE1;
- else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'g','r','p'))
- return ATOM_CONTENTGROUP;
- else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'l','y','r'))
- return ATOM_LYRICS;
- }
-
- if (mp4ff_atom_compare(a,b,c,d, 'e','d','t','s'))
- return ATOM_EDTS;
- else if (mp4ff_atom_compare(a,b,c,d, 'e','s','d','s'))
- return ATOM_ESDS;
- else if (mp4ff_atom_compare(a,b,c,d, 'f','t','y','p'))
- return ATOM_FTYP;
- else if (mp4ff_atom_compare(a,b,c,d, 'f','r','e','e'))
- return ATOM_FREE;
- else if (mp4ff_atom_compare(a,b,c,d, 'h','m','h','d'))
- return ATOM_HMHD;
- else if (mp4ff_atom_compare(a,b,c,d, 'v','m','h','d'))
- return ATOM_VMHD;
- else if (mp4ff_atom_compare(a,b,c,d, 'u','d','t','a'))
- return ATOM_UDTA;
- else if (mp4ff_atom_compare(a,b,c,d, 'i','l','s','t'))
- return ATOM_ILST;
- else if (mp4ff_atom_compare(a,b,c,d, 'n','a','m','e'))
- return ATOM_NAME;
- else if (mp4ff_atom_compare(a,b,c,d, 'd','a','t','a'))
- return ATOM_DATA;
- else if (mp4ff_atom_compare(a,b,c,d, 'd','i','s','k'))
- return ATOM_DISC;
- else if (mp4ff_atom_compare(a,b,c,d, 'g','n','r','e'))
- return ATOM_GENRE2;
- else if (mp4ff_atom_compare(a,b,c,d, 'c','o','v','r'))
- return ATOM_COVER;
- else if (mp4ff_atom_compare(a,b,c,d, 'c','p','i','l'))
- return ATOM_COMPILATION;
- else if (mp4ff_atom_compare(a,b,c,d, 'c','t','t','s'))
- return ATOM_CTTS;
- else if (mp4ff_atom_compare(a,b,c,d, 'd','r','m','s'))
- return ATOM_DRMS;
- else if (mp4ff_atom_compare(a,b,c,d, 'f','r','m','a'))
- return ATOM_FRMA;
- else if (mp4ff_atom_compare(a,b,c,d, 'p','r','i','v'))
- return ATOM_PRIV;
- else if (mp4ff_atom_compare(a,b,c,d, 'i','v','i','v'))
- return ATOM_IVIV;
- else if (mp4ff_atom_compare(a,b,c,d, 'u','s','e','r'))
- return ATOM_USER;
- else if (mp4ff_atom_compare(a,b,c,d, 'k','e','y',' '))
- return ATOM_KEY;
- else if (mp4ff_atom_compare(a,b,c,d, 'a','A','R','T'))
- return ATOM_ALBUM_ARTIST;
- else if (mp4ff_atom_compare(a,b,c,d, 'd','e','s','c'))
- return ATOM_DESCRIPTION;
- else if (mp4ff_atom_compare(a,b,c,d, 'p','c','s','t'))
- return ATOM_PODCAST;
- else
- return ATOM_UNKNOWN;
-}
-
-/* read atom header, return atom size, atom size is with header included */
-uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_size)
-{
- uint64_t size;
- int32_t ret;
- uint8_t atom_header[8];
-
- ret = mp4ff_read_data(f, atom_header, 8);
- if (ret != 8)
- return 0;
-
- size = mp4ff_atom_get_size(atom_header);
- *header_size = 8;
-
- /* check for 64 bit atom size */
- if (size == 1)
- {
- *header_size = 16;
- size = mp4ff_read_int64(f);
- }
-
- //printf("%c%c%c%c\n", atom_header[4], atom_header[5], atom_header[6], atom_header[7]);
-
- *atom_type = mp4ff_atom_name_to_type(atom_header[4], atom_header[5], atom_header[6], atom_header[7]);
-
- return size;
-}
-
-static int32_t mp4ff_read_stsz(mp4ff_t *f)
-{
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- f->track[f->total_tracks - 1]->stsz_sample_size = mp4ff_read_int32(f);
- f->track[f->total_tracks - 1]->stsz_sample_count = mp4ff_read_int32(f);
-
- if (f->track[f->total_tracks - 1]->stsz_sample_size == 0)
- {
- int32_t i;
- f->track[f->total_tracks - 1]->stsz_table =
- (int32_t*)malloc(f->track[f->total_tracks - 1]->stsz_sample_count*sizeof(int32_t));
-
- for (i = 0; i < f->track[f->total_tracks - 1]->stsz_sample_count; i++)
- {
- f->track[f->total_tracks - 1]->stsz_table[i] = mp4ff_read_int32(f);
- }
- }
-
- return 0;
-}
-
-static int32_t mp4ff_read_esds(mp4ff_t *f)
-{
- uint8_t tag;
- uint32_t temp;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
-
- /* get and verify ES_DescrTag */
- tag = mp4ff_read_char(f);
- if (tag == 0x03)
- {
- /* read length */
- if (mp4ff_read_mp4_descr_length(f) < 5 + 15)
- {
- return 1;
- }
- /* skip 3 bytes */
- mp4ff_read_int24(f);
- } else {
- /* skip 2 bytes */
- mp4ff_read_int16(f);
- }
-
- /* get and verify DecoderConfigDescrTab */
- if (mp4ff_read_char(f) != 0x04)
- {
- return 1;
- }
-
- /* read length */
- temp = mp4ff_read_mp4_descr_length(f);
- if (temp < 13) return 1;
-
- f->track[f->total_tracks - 1]->audioType = mp4ff_read_char(f);
- mp4ff_read_int32(f);//0x15000414 ????
- f->track[f->total_tracks - 1]->maxBitrate = mp4ff_read_int32(f);
- f->track[f->total_tracks - 1]->avgBitrate = mp4ff_read_int32(f);
-
- /* get and verify DecSpecificInfoTag */
- if (mp4ff_read_char(f) != 0x05)
- {
- return 1;
- }
-
- /* read length */
- f->track[f->total_tracks - 1]->decoderConfigLen = mp4ff_read_mp4_descr_length(f);
-
- if (f->track[f->total_tracks - 1]->decoderConfig)
- free(f->track[f->total_tracks - 1]->decoderConfig);
- f->track[f->total_tracks - 1]->decoderConfig = malloc(f->track[f->total_tracks - 1]->decoderConfigLen);
- if (f->track[f->total_tracks - 1]->decoderConfig)
- {
- mp4ff_read_data(f, f->track[f->total_tracks - 1]->decoderConfig, f->track[f->total_tracks - 1]->decoderConfigLen);
- } else {
- f->track[f->total_tracks - 1]->decoderConfigLen = 0;
- }
-
- /* will skip the remainder of the atom */
- return 0;
-}
-
-static int32_t mp4ff_read_mp4a(mp4ff_t *f)
-{
- int32_t i;
- uint8_t atom_type = 0;
- uint8_t header_size = 0;
-
- for (i = 0; i < 6; i++)
- {
- mp4ff_read_char(f); /* reserved */
- }
- /* data_reference_index */ mp4ff_read_int16(f);
-
- mp4ff_read_int32(f); /* reserved */
- mp4ff_read_int32(f); /* reserved */
-
- f->track[f->total_tracks - 1]->channelCount = mp4ff_read_int16(f);
- f->track[f->total_tracks - 1]->sampleSize = mp4ff_read_int16(f);
-
- mp4ff_read_int16(f);
- mp4ff_read_int16(f);
-
- f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);
-
- mp4ff_read_int16(f);
-
- mp4ff_atom_read_header(f, &atom_type, &header_size);
- if (atom_type == ATOM_ESDS)
- {
- mp4ff_read_esds(f);
- }
-
- return 0;
-}
-
-static int32_t mp4ff_read_stsd(mp4ff_t *f)
-{
- int32_t i;
- uint8_t header_size = 0;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
-
- f->track[f->total_tracks - 1]->stsd_entry_count = mp4ff_read_int32(f);
-
- for (i = 0; i < f->track[f->total_tracks - 1]->stsd_entry_count; i++)
- {
- uint64_t skip = mp4ff_position(f);
- uint64_t size;
- uint8_t atom_type = 0;
- size = mp4ff_atom_read_header(f, &atom_type, &header_size);
- skip += size;
-
- if (atom_type == ATOM_MP4A)
- {
- f->track[f->total_tracks - 1]->type = TRACK_AUDIO;
- mp4ff_read_mp4a(f);
- } else if (atom_type == ATOM_MP4V) {
- f->track[f->total_tracks - 1]->type = TRACK_VIDEO;
- } else if (atom_type == ATOM_MP4S) {
- f->track[f->total_tracks - 1]->type = TRACK_SYSTEM;
- } else {
- f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
- }
-
- mp4ff_set_position(f, skip);
- }
-
- return 0;
-}
-
-static int32_t mp4ff_read_stsc(mp4ff_t *f)
-{
- int32_t i;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- f->track[f->total_tracks - 1]->stsc_entry_count = mp4ff_read_int32(f);
-
- f->track[f->total_tracks - 1]->stsc_first_chunk =
- (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
- f->track[f->total_tracks - 1]->stsc_samples_per_chunk =
- (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
- f->track[f->total_tracks - 1]->stsc_sample_desc_index =
- (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
-
- for (i = 0; i < f->track[f->total_tracks - 1]->stsc_entry_count; i++)
- {
- f->track[f->total_tracks - 1]->stsc_first_chunk[i] = mp4ff_read_int32(f);
- f->track[f->total_tracks - 1]->stsc_samples_per_chunk[i] = mp4ff_read_int32(f);
- f->track[f->total_tracks - 1]->stsc_sample_desc_index[i] = mp4ff_read_int32(f);
- }
-
- return 0;
-}
-
-static int32_t mp4ff_read_stco(mp4ff_t *f)
-{
- int32_t i;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- f->track[f->total_tracks - 1]->stco_entry_count = mp4ff_read_int32(f);
-
- f->track[f->total_tracks - 1]->stco_chunk_offset =
- (int32_t*)malloc(f->track[f->total_tracks - 1]->stco_entry_count*sizeof(int32_t));
-
- for (i = 0; i < f->track[f->total_tracks - 1]->stco_entry_count; i++)
- {
- f->track[f->total_tracks - 1]->stco_chunk_offset[i] = mp4ff_read_int32(f);
- }
-
- return 0;
-}
-
-static int32_t mp4ff_read_ctts(mp4ff_t *f)
-{
- int32_t i;
- mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
-
- if (p_track->ctts_entry_count) return 0;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- p_track->ctts_entry_count = mp4ff_read_int32(f);
-
- p_track->ctts_sample_count = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
- p_track->ctts_sample_offset = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
-
- if (p_track->ctts_sample_count == 0 || p_track->ctts_sample_offset == 0)
- {
- if (p_track->ctts_sample_count) {free(p_track->ctts_sample_count);p_track->ctts_sample_count=0;}
- if (p_track->ctts_sample_offset) {free(p_track->ctts_sample_offset);p_track->ctts_sample_offset=0;}
- p_track->ctts_entry_count = 0;
- return 0;
- }
- else
- {
- for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count; i++)
- {
- p_track->ctts_sample_count[i] = mp4ff_read_int32(f);
- p_track->ctts_sample_offset[i] = mp4ff_read_int32(f);
- }
- return 1;
- }
-}
-
-static int32_t mp4ff_read_stts(mp4ff_t *f)
-{
- int32_t i;
- mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
-
- if (p_track->stts_entry_count) return 0;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- p_track->stts_entry_count = mp4ff_read_int32(f);
-
- p_track->stts_sample_count = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
- p_track->stts_sample_delta = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
-
- if (p_track->stts_sample_count == 0 || p_track->stts_sample_delta == 0)
- {
- if (p_track->stts_sample_count) {free(p_track->stts_sample_count);p_track->stts_sample_count=0;}
- if (p_track->stts_sample_delta) {free(p_track->stts_sample_delta);p_track->stts_sample_delta=0;}
- p_track->stts_entry_count = 0;
- return 0;
- }
- else
- {
- for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count; i++)
- {
- p_track->stts_sample_count[i] = mp4ff_read_int32(f);
- p_track->stts_sample_delta[i] = mp4ff_read_int32(f);
- }
- return 1;
- }
-}
-
-static int32_t mp4ff_read_mvhd(mp4ff_t *f)
-{
- int32_t i;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- /* creation_time */ mp4ff_read_int32(f);
- /* modification_time */ mp4ff_read_int32(f);
- f->time_scale = mp4ff_read_int32(f);
- f->duration = mp4ff_read_int32(f);
- /* preferred_rate */ mp4ff_read_int32(f); /*mp4ff_read_fixed32(f);*/
- /* preferred_volume */ mp4ff_read_int16(f); /*mp4ff_read_fixed16(f);*/
- for (i = 0; i < 10; i++)
- {
- /* reserved */ mp4ff_read_char(f);
- }
- for (i = 0; i < 9; i++)
- {
- mp4ff_read_int32(f); /* matrix */
- }
- /* preview_time */ mp4ff_read_int32(f);
- /* preview_duration */ mp4ff_read_int32(f);
- /* poster_time */ mp4ff_read_int32(f);
- /* selection_time */ mp4ff_read_int32(f);
- /* selection_duration */ mp4ff_read_int32(f);
- /* current_time */ mp4ff_read_int32(f);
- /* next_track_id */ mp4ff_read_int32(f);
-
- return 0;
-}
-
-#if 0
-static int32_t mp4ff_read_tkhd(mp4ff_t *f)
-{
- uint8_t version;
- uint32_t flags;
- version = mp4ff_read_char(f); /* version */
- flags = mp4ff_read_int24(f); /* flags */
- if (version==1)
- {
- mp4ff_read_int64(f);//creation-time
- mp4ff_read_int64(f);//modification-time
- mp4ff_read_int32(f);//track-id
- mp4ff_read_int32(f);//reserved
- f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f);//duration
- }
- else //version == 0
- {
- mp4ff_read_int32(f);//creation-time
- mp4ff_read_int32(f);//modification-time
- mp4ff_read_int32(f);//track-id
- mp4ff_read_int32(f);//reserved
- f->track[f->total_tracks - 1]->duration = mp4ff_read_int32(f);//duration
- if (f->track[f->total_tracks - 1]->duration == 0xFFFFFFFF)
- f->track[f->total_tracks - 1]->duration = 0xFFFFFFFFFFFFFFFF;
-
- }
- mp4ff_read_int32(f);//reserved
- mp4ff_read_int32(f);//reserved
- mp4ff_read_int16(f);//layer
- mp4ff_read_int16(f);//pre-defined
- mp4ff_read_int16(f);//volume
- mp4ff_read_int16(f);//reserved
-
- //matrix
- mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
- mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
- mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
- mp4ff_read_int32(f);//width
- mp4ff_read_int32(f);//height
- return 1;
-}
-#endif
-
-static int32_t mp4ff_read_mdhd(mp4ff_t *f)
-{
- uint32_t version;
-
- version = mp4ff_read_int32(f);
- if (version==1)
- {
- mp4ff_read_int64(f);//creation-time
- mp4ff_read_int64(f);//modification-time
- f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f);//timescale
- f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f);//duration
- }
- else //version == 0
- {
- uint32_t temp;
-
- mp4ff_read_int32(f);//creation-time
- mp4ff_read_int32(f);//modification-time
- f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f);//timescale
- temp = mp4ff_read_int32(f);
- f->track[f->total_tracks - 1]->duration = (temp == (uint32_t)(-1)) ? (uint64_t)(-1) : (uint64_t)(temp);
- }
- mp4ff_read_int16(f);
- mp4ff_read_int16(f);
- return 1;
-}
-#ifdef USE_TAGGING
-static int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size)
-{
- uint64_t subsize, sumsize = 0;
- uint8_t atom_type;
- uint8_t header_size = 0;
-
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
-
- while (sumsize < (size-(header_size+4)))
- {
- subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
- if (subsize <= header_size+4)
- return 1;
- if (atom_type == ATOM_ILST)
- {
- mp4ff_parse_metadata(f, (uint32_t)(subsize-(header_size+4)));
- } else {
- mp4ff_set_position(f, mp4ff_position(f)+subsize-header_size);
- }
- sumsize += subsize;
- }
-
- return 0;
-}
-#endif
-
-int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type)
-{
- uint64_t dest_position = mp4ff_position(f)+size-8;
- if (atom_type == ATOM_STSZ)
- {
- /* sample size box */
- mp4ff_read_stsz(f);
- } else if (atom_type == ATOM_STTS) {
- /* time to sample box */
- mp4ff_read_stts(f);
- } else if (atom_type == ATOM_CTTS) {
- /* composition offset box */
- mp4ff_read_ctts(f);
- } else if (atom_type == ATOM_STSC) {
- /* sample to chunk box */
- mp4ff_read_stsc(f);
- } else if (atom_type == ATOM_STCO) {
- /* chunk offset box */
- mp4ff_read_stco(f);
- } else if (atom_type == ATOM_STSD) {
- /* sample description box */
- mp4ff_read_stsd(f);
- } else if (atom_type == ATOM_MVHD) {
- /* movie header box */
- mp4ff_read_mvhd(f);
- } else if (atom_type == ATOM_MDHD) {
- /* track header */
- mp4ff_read_mdhd(f);
-#ifdef USE_TAGGING
- } else if (atom_type == ATOM_META) {
- /* iTunes Metadata box */
- mp4ff_read_meta(f, size);
-#endif
- }
-
- mp4ff_set_position(f, dest_position);
-
-
- return 0;
-}
diff --git a/src/aac/mp4ff/mp4ff.c b/src/aac/mp4ff/mp4ff.c
deleted file mode 100644
index d8458faa0ffd..000000000000
--- a/src/aac/mp4ff/mp4ff.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
-**
-** 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.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** The "appropriate copyright message" mentioned in section 2c of the GPLv2
-** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Nero AG through Mpeg4AAClicense at nero.com.
-**
-** $Id: mp4ff.c,v 1.22 2009/01/26 23:01:40 menno Exp $
-**/
-
-#include <stdlib.h>
-#include <string.h>
-#include "mp4ffint.h"
-
-mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f)
-{
- mp4ff_t *ff = malloc(sizeof(mp4ff_t));
-
- memset(ff, 0, sizeof(mp4ff_t));
-
- ff->stream = f;
-
- parse_atoms(ff,0);
-
- return ff;
-}
-
-mp4ff_t *mp4ff_open_read_metaonly(mp4ff_callback_t *f)
-{
- mp4ff_t *ff = malloc(sizeof(mp4ff_t));
-
- memset(ff, 0, sizeof(mp4ff_t));
-
- ff->stream = f;
-
- parse_atoms(ff,1);
-
- return ff;
-}
-
-void mp4ff_close(mp4ff_t *ff)
-{
- int32_t i;
-
- for (i = 0; i < ff->total_tracks; i++)
- {
- if (ff->track[i])
- {
- if (ff->track[i]->stsz_table)
- free(ff->track[i]->stsz_table);
- if (ff->track[i]->stts_sample_count)
- free(ff->track[i]->stts_sample_count);
- if (ff->track[i]->stts_sample_delta)
- free(ff->track[i]->stts_sample_delta);
- if (ff->track[i]->stsc_first_chunk)
- free(ff->track[i]->stsc_first_chunk);
- if (ff->track[i]->stsc_samples_per_chunk)
- free(ff->track[i]->stsc_samples_per_chunk);
- if (ff->track[i]->stsc_sample_desc_index)
- free(ff->track[i]->stsc_sample_desc_index);
- if (ff->track[i]->stco_chunk_offset)
- free(ff->track[i]->stco_chunk_offset);
- if (ff->track[i]->decoderConfig)
- free(ff->track[i]->decoderConfig);
- if (ff->track[i]->ctts_sample_count)
- free(ff->track[i]->ctts_sample_count);
- if (ff->track[i]->ctts_sample_offset)
- free(ff->track[i]->ctts_sample_offset);
-#ifdef ITUNES_DRM
- if (ff->track[i]->p_drms)
- drms_free(ff->track[i]->p_drms);
-#endif
- free(ff->track[i]);
- }
- }
-
-#ifdef USE_TAGGING
- mp4ff_tag_delete(&(ff->tags));
-#endif
-
- free(ff);
-}
-
-void mp4ff_track_add(mp4ff_t *f)
-{
- f->total_tracks++;
-
- f->track[f->total_tracks - 1] = malloc(sizeof(mp4ff_track_t));
-
- memset(f->track[f->total_tracks - 1], 0, sizeof(mp4ff_track_t));
-}
-
-static int need_parse_when_meta_only(uint8_t atom_type)
-{
- switch(atom_type)
- {
- case ATOM_EDTS:
-// case ATOM_MDIA:
-// case ATOM_MINF:
- case ATOM_DRMS:
- case ATOM_SINF:
- case ATOM_SCHI:
-// case ATOM_STBL:
-// case ATOM_STSD:
- case ATOM_STTS:
- case ATOM_STSZ:
- case ATOM_STZ2:
- case ATOM_STCO:
- case ATOM_STSC:
-// case ATOM_CTTS:
- case ATOM_FRMA:
- case ATOM_IVIV:
- case ATOM_PRIV:
- return 0;
- default:
- return 1;
- }
-}
-
-/* parse atoms that are sub atoms of other atoms */
-int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size,int meta_only)
-{
- uint64_t size;
- uint8_t atom_type = 0;
- uint64_t counted_size = 0;
- uint8_t header_size = 0;
-
- while (counted_size < total_size)
- {
- size = mp4ff_atom_read_header(f, &atom_type, &header_size);
- counted_size += size;
-
- /* check for end of file */
- if (size == 0)
- break;
-
- /* we're starting to read a new track, update index,
- * so that all data and tables get written in the right place
- */
- if (atom_type == ATOM_TRAK)
- {
- mp4ff_track_add(f);
- }
-
- /* parse subatoms */
- if (meta_only && !need_parse_when_meta_only(atom_type))
- {
- mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
- } else if (atom_type < SUBATOMIC)
- {
- parse_sub_atoms(f, size-header_size,meta_only);
- } else {
- mp4ff_atom_read(f, (uint32_t)size, atom_type);
- }
- }
-
- return 0;
-}
-
-/* parse root atoms */
-int32_t parse_atoms(mp4ff_t *f,int meta_only)
-{
- uint64_t size;
- uint8_t atom_type = 0;
- uint8_t header_size = 0;
-
- f->file_size = 0;
-
- while ((size = mp4ff_atom_read_header(f, &atom_type, &header_size)) != 0)
- {
- f->file_size += size;
- f->last_atom = atom_type;
-
- if (atom_type == ATOM_MDAT && f->moov_read)
- {
- /* moov atom is before mdat, we can stop reading when mdat is encountered */
- /* file position will stay at beginning of mdat data */
-// break;
- }
-
- if (atom_type == ATOM_MOOV && size > header_size)
- {
- f->moov_read = 1;
- f->moov_offset = mp4ff_position(f)-header_size;
- f->moov_size = size;
- }
-
- /* parse subatoms */
- if (meta_only && !need_parse_when_meta_only(atom_type))
- {
- if(mp4ff_set_position(f, mp4ff_position(f) + size - header_size) != 0)
- break;
- }
- else if (atom_type < SUBATOMIC)
- {
- parse_sub_atoms(f, size-header_size,meta_only);
- }
- else
- {
- /* skip this atom */
- if(mp4ff_set_position(f, mp4ff_position(f) + size - header_size) != 0)
- break;
- }
- }
-
- return 0;
-}
-
-int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
- uint8_t** ppBuf, uint32_t* pBufSize)
-{
- if (track >= f->total_tracks)
- {
- *ppBuf = NULL;
- *pBufSize = 0;
- return 1;
- }
-
- if (f->track[track]->decoderConfig == NULL || f->track[track]->decoderConfigLen == 0)
- {
- *ppBuf = NULL;
- *pBufSize = 0;
- } else {
- *ppBuf = malloc(f->track[track]->decoderConfigLen);
- if (*ppBuf == NULL)
- {
- *pBufSize = 0;
- return 1;
- }
- memcpy(*ppBuf, f->track[track]->decoderConfig, f->track[track]->decoderConfigLen);
- *pBufSize = f->track[track]->decoderConfigLen;
- }
-
- return 0;
-}
-
-int32_t mp4ff_get_track_type(const mp4ff_t *f, const int track)
-{
- return f->track[track]->type;
-}
-
-int32_t mp4ff_total_tracks(const mp4ff_t *f)
-{
- return f->total_tracks;
-}
-
-int32_t mp4ff_time_scale(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->timeScale;
-}
-
-uint32_t mp4ff_get_avg_bitrate(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->avgBitrate;
-}
-
-uint32_t mp4ff_get_max_bitrate(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->maxBitrate;
-}
-
-int64_t mp4ff_get_track_duration(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->duration;
-}
-
-int64_t mp4ff_get_track_duration_use_offsets(const mp4ff_t *f, const int32_t track)
-{
- int64_t duration = mp4ff_get_track_duration(f,track);
- if (duration!=-1)
- {
- int64_t offset = mp4ff_get_sample_offset(f,track,0);
- if (offset > duration) duration = 0;
- else duration -= offset;
- }
- return duration;
-}
-
-int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track)
-{
- int32_t i;
- int32_t total = 0;
-
- if (track < 0)
- return -1;
-
- for (i = 0; i < f->track[track]->stts_entry_count; i++)
- {
- total += f->track[track]->stts_sample_count[i];
- }
-
- return total;
-}
-
-uint32_t mp4ff_get_sample_rate(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->sampleRate;
-}
-
-uint32_t mp4ff_get_channel_count(const mp4ff_t * f,const int32_t track)
-{
- return f->track[track]->channelCount;
-}
-
-uint32_t mp4ff_get_audio_type(const mp4ff_t * f,const int32_t track)
-{
- return f->track[track]->audioType;
-}
-
-int32_t mp4ff_get_sample_duration_use_offsets(const mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t d,o;
- d = mp4ff_get_sample_duration(f,track,sample);
- if (d!=-1)
- {
- o = mp4ff_get_sample_offset(f,track,sample);
- if (o>d) d = 0;
- else d -= o;
- }
- return d;
-}
-
-int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t i, co = 0;
-
- for (i = 0; i < f->track[track]->stts_entry_count; i++)
- {
- int32_t delta = f->track[track]->stts_sample_count[i];
- if (sample < co + delta)
- return f->track[track]->stts_sample_delta[i];
- co += delta;
- }
- return (int32_t)(-1);
-}
-
-int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t i, co = 0;
- int64_t acc = 0;
-
- for (i = 0; i < f->track[track]->stts_entry_count; i++)
- {
- int32_t delta = f->track[track]->stts_sample_count[i];
- if (sample < co + delta)
- {
- acc += f->track[track]->stts_sample_delta[i] * (sample - co);
- return acc;
- }
- else
- {
- acc += f->track[track]->stts_sample_delta[i] * delta;
- }
- co += delta;
- }
- return (int64_t)(-1);
-}
-
-int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t i, co = 0;
-
- for (i = 0; i < f->track[track]->ctts_entry_count; i++)
- {
- int32_t delta = f->track[track]->ctts_sample_count[i];
- if (sample < co + delta)
- return f->track[track]->ctts_sample_offset[i];
- co += delta;
- }
- return 0;
-}
-
-int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip)
-{
- int32_t i, co = 0;
- int64_t offset_total = 0;
- mp4ff_track_t * p_track = f->track[track];
-
- for (i = 0; i < p_track->stts_entry_count; i++)
- {
- int32_t sample_count = p_track->stts_sample_count[i];
- int32_t sample_delta = p_track->stts_sample_delta[i];
- int64_t offset_delta = (int64_t)sample_delta * (int64_t)sample_count;
- if (offset < offset_total + offset_delta)
- {
- int64_t offset_fromstts = offset - offset_total;
- if (toskip) *toskip = (int32_t)(offset_fromstts % sample_delta);
- return co + (int32_t)(offset_fromstts / sample_delta);
- }
- else
- {
- offset_total += offset_delta;
- }
- co += sample_count;
- }
- return (int32_t)(-1);
-}
-
-int32_t mp4ff_find_sample_use_offsets(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip)
-{
- return mp4ff_find_sample(f,track,offset + mp4ff_get_sample_offset(f,track,0),toskip);
-}
-
-int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
- uint8_t **audio_buffer, uint32_t *bytes)
-{
- int32_t result = 0;
-
- *bytes = mp4ff_audio_frame_size(f, track, sample);
-
- if (*bytes==0) return 0;
-
- *audio_buffer = (uint8_t*)malloc(*bytes);
-
- mp4ff_set_sample_position(f, track, sample);
-
- result = mp4ff_read_data(f, *audio_buffer, *bytes);
-
- if (!result)
- {
- free(*audio_buffer);
- *audio_buffer = 0;
- return 0;
- }
-
-#ifdef ITUNES_DRM
- if (f->track[track]->p_drms != NULL)
- {
- drms_decrypt(f->track[track]->p_drms, (uint32_t*)*audio_buffer, *bytes);
- }
-#endif
-
- return *bytes;
-}
-
-
-int32_t mp4ff_read_sample_v2(mp4ff_t *f, const int track, const int sample,unsigned char *buffer)
-{
- int32_t result = 0;
- int32_t size = mp4ff_audio_frame_size(f,track,sample);
- if (size<=0) return 0;
- mp4ff_set_sample_position(f, track, sample);
- result = mp4ff_read_data(f,buffer,size);
-
-#ifdef ITUNES_DRM
- if (f->track[track]->p_drms != NULL)
- {
- drms_decrypt(f->track[track]->p_drms, (uint32_t*)buffer, size);
- }
-#endif
-
- return result;
-}
-
-int32_t mp4ff_read_sample_getsize(mp4ff_t *f, const int track, const int sample)
-{
- int32_t temp = mp4ff_audio_frame_size(f, track, sample);
- if (temp<0) temp = 0;
- return temp;
-}
diff --git a/src/aac/mp4ff/mp4ff.h b/src/aac/mp4ff/mp4ff.h
deleted file mode 100644
index 5851b0c7b257..000000000000
--- a/src/aac/mp4ff/mp4ff.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
-**
-** 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.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** The "appropriate copyright message" mentioned in section 2c of the GPLv2
-** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Nero AG through Mpeg4AAClicense at nero.com.
-**
-** $Id: mp4ff.h,v 1.27 2009/01/29 00:41:08 menno Exp $
-**/
-
-#ifndef MP4FF_H
-#define MP4FF_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#else
-#include "mp4ff_int_types.h"
-#endif
-
-/* file callback structure */
-typedef struct
-{
- uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
- uint32_t (*write)(void *udata, void *buffer, uint32_t length);
- uint32_t (*seek)(void *user_data, uint64_t position);
- uint32_t (*truncate)(void *user_data);
- void *user_data;
-} mp4ff_callback_t;
-
-/* mp4 main file structure */
-typedef void* mp4ff_t;
-
-
-/* API */
-
-mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f);
-mp4ff_t *mp4ff_open_read_metaonly(mp4ff_callback_t *f);
-void mp4ff_close(mp4ff_t *f);
-int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_get_sample_duration_use_offsets(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
-int32_t mp4ff_find_sample_use_offsets(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
-
-int32_t mp4ff_read_sample(mp4ff_t *f, const int track, const int sample,
- unsigned char **audio_buffer, unsigned int *bytes);
-
-int32_t mp4ff_read_sample_v2(mp4ff_t *f, const int track, const int sample,unsigned char *buffer);//returns 0 on error, number of bytes read on success, use mp4ff_read_sample_getsize() to check buffer size needed
-int32_t mp4ff_read_sample_getsize(mp4ff_t *f, const int track, const int sample);//returns 0 on error, buffer size needed for mp4ff_read_sample_v2() on success
-
-
-
-int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int track,
- unsigned char** ppBuf, unsigned int* pBufSize);
-int32_t mp4ff_get_track_type(const mp4ff_t *f, const int track);
-int32_t mp4ff_total_tracks(const mp4ff_t *f);
-int32_t mp4ff_num_samples(const mp4ff_t *f, const int track);
-int32_t mp4ff_time_scale(const mp4ff_t *f, const int track);
-
-uint32_t mp4ff_get_avg_bitrate(const mp4ff_t *f, const int32_t track);
-uint32_t mp4ff_get_max_bitrate(const mp4ff_t *f, const int32_t track);
-int64_t mp4ff_get_track_duration(const mp4ff_t *f, const int32_t track); //returns (-1) if unknown
-int64_t mp4ff_get_track_duration_use_offsets(const mp4ff_t *f, const int32_t track); //returns (-1) if unknown
-uint32_t mp4ff_get_sample_rate(const mp4ff_t *f, const int32_t track);
-uint32_t mp4ff_get_channel_count(const mp4ff_t * f,const int32_t track);
-uint32_t mp4ff_get_audio_type(const mp4ff_t * f,const int32_t track);
-
-
-/* metadata */
-int mp4ff_meta_get_num_items(const mp4ff_t *f);
-int mp4ff_meta_get_by_index(const mp4ff_t *f, unsigned int index,
- char **item, char **value);
-int mp4ff_meta_get_title(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_artist(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_writer(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_album(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_date(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_tool(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_comment(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_genre(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_track(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_disc(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_totaltracks(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_totaldiscs(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_compilation(const mp4ff_t *f, char **value);
-int mp4ff_meta_get_tempo(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value);
-#ifdef USE_TAGGING
-
-/* metadata tag structure */
-typedef struct
-{
- char *item;
- char *value;
-} mp4ff_tag_t;
-
-/* metadata list structure */
-typedef struct
-{
- mp4ff_tag_t *tags;
- uint32_t count;
-} mp4ff_metadata_t;
-
-int32_t mp4ff_meta_update(mp4ff_callback_t *f,const mp4ff_metadata_t * data);
-
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif
diff --git a/src/aac/mp4ff/mp4ff_int_types.h b/src/aac/mp4ff/mp4ff_int_types.h
deleted file mode 100644
index 7c5d27b697c2..000000000000
--- a/src/aac/mp4ff/mp4ff_int_types.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _MP4FF_INT_TYPES_H_
-#define _MP4FF_INT_TYPES_H_
-
-#if defined _WIN32 && ! defined __MINGW32__
-
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
-typedef signed short int16_t;
-typedef unsigned short uint16_t;
-typedef signed long int32_t;
-typedef unsigned long uint32_t;
-
-typedef signed __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-
-#else
-
-#include <stdint.h>
-
-#endif
-
-
-#endif
diff --git a/src/aac/mp4ff/mp4ffint.h b/src/aac/mp4ff/mp4ffint.h
deleted file mode 100644
index 83bd0c1ace41..000000000000
--- a/src/aac/mp4ff/mp4ffint.h
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
-**
-** 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.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** The "appropriate copyright message" mentioned in section 2c of the GPLv2
-** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Nero AG through Mpeg4AAClicense at nero.com.
-**
-** $Id: mp4ffint.h,v 1.26 2009/01/25 20:14:34 menno Exp $
-**/
-
-#ifndef MP4FF_INTERNAL_H
-#define MP4FF_INTERNAL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include "mp4ff_int_types.h"
-#include <stdlib.h>
-
-#define MAX_TRACKS 1024
-#define TRACK_UNKNOWN 0
-#define TRACK_AUDIO 1
-#define TRACK_VIDEO 2
-#define TRACK_SYSTEM 3
-
-
-#define SUBATOMIC 128
-
-/* atoms without subatoms */
-#define ATOM_FTYP 129
-#define ATOM_MDAT 130
-#define ATOM_MVHD 131
-#define ATOM_TKHD 132
-#define ATOM_TREF 133
-#define ATOM_MDHD 134
-#define ATOM_VMHD 135
-#define ATOM_SMHD 136
-#define ATOM_HMHD 137
-#define ATOM_STSD 138
-#define ATOM_STTS 139
-#define ATOM_STSZ 140
-#define ATOM_STZ2 141
-#define ATOM_STCO 142
-#define ATOM_STSC 143
-#define ATOM_MP4A 144
-#define ATOM_MP4V 145
-#define ATOM_MP4S 146
-#define ATOM_ESDS 147
-#define ATOM_META 148 /* iTunes Metadata box */
-#define ATOM_NAME 149 /* iTunes Metadata name box */
-#define ATOM_DATA 150 /* iTunes Metadata data box */
-#define ATOM_CTTS 151
-#define ATOM_FRMA 152
-#define ATOM_IVIV 153
-#define ATOM_PRIV 154
-#define ATOM_USER 155
-#define ATOM_KEY 156
-
-#define ATOM_ALBUM_ARTIST 157
-#define ATOM_CONTENTGROUP 158
-#define ATOM_LYRICS 159
-#define ATOM_DESCRIPTION 160
-#define ATOM_NETWORK 161
-#define ATOM_SHOW 162
-#define ATOM_EPISODENAME 163
-#define ATOM_SORTTITLE 164
-#define ATOM_SORTALBUM 165
-#define ATOM_SORTARTIST 166
-#define ATOM_SORTALBUMARTIST 167
-#define ATOM_SORTWRITER 168
-#define ATOM_SORTSHOW 169
-#define ATOM_SEASON 170
-#define ATOM_EPISODE 171
-#define ATOM_PODCAST 172
-
-#define ATOM_UNKNOWN 255
-#define ATOM_FREE ATOM_UNKNOWN
-#define ATOM_SKIP ATOM_UNKNOWN
-
-/* atoms with subatoms */
-#define ATOM_MOOV 1
-#define ATOM_TRAK 2
-#define ATOM_EDTS 3
-#define ATOM_MDIA 4
-#define ATOM_MINF 5
-#define ATOM_STBL 6
-#define ATOM_UDTA 7
-#define ATOM_ILST 8 /* iTunes Metadata list */
-#define ATOM_TITLE 9
-#define ATOM_ARTIST 10
-#define ATOM_WRITER 11
-#define ATOM_ALBUM 12
-#define ATOM_DATE 13
-#define ATOM_TOOL 14
-#define ATOM_COMMENT 15
-#define ATOM_GENRE1 16
-#define ATOM_TRACK 17
-#define ATOM_DISC 18
-#define ATOM_COMPILATION 19
-#define ATOM_GENRE2 20
-#define ATOM_TEMPO 21
-#define ATOM_COVER 22
-#define ATOM_DRMS 23
-#define ATOM_SINF 24
-#define ATOM_SCHI 25
-
-/* file callback structure */
-typedef struct
-{
- uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
- uint32_t (*write)(void *udata, void *buffer, uint32_t length);
- uint32_t (*seek)(void *user_data, uint64_t position);
- uint32_t (*truncate)(void *user_data);
- void *user_data;
-} mp4ff_callback_t;
-
-
-/* metadata tag structure */
-typedef struct
-{
- char *item;
- char *value;
-} mp4ff_tag_t;
-
-/* metadata list structure */
-typedef struct
-{
- mp4ff_tag_t *tags;
- uint32_t count;
-} mp4ff_metadata_t;
-
-
-typedef struct
-{
- int32_t type;
- int32_t channelCount;
- int32_t sampleSize;
- uint16_t sampleRate;
- int32_t audioType;
-
- /* stsd */
- int32_t stsd_entry_count;
-
- /* stsz */
- int32_t stsz_sample_size;
- int32_t stsz_sample_count;
- int32_t *stsz_table;
-
- /* stts */
- int32_t stts_entry_count;
- int32_t *stts_sample_count;
- int32_t *stts_sample_delta;
-
- /* stsc */
- int32_t stsc_entry_count;
- int32_t *stsc_first_chunk;
- int32_t *stsc_samples_per_chunk;
- int32_t *stsc_sample_desc_index;
-
- /* stsc */
- int32_t stco_entry_count;
- int32_t *stco_chunk_offset;
-
- /* ctts */
- int32_t ctts_entry_count;
- int32_t *ctts_sample_count;
- int32_t *ctts_sample_offset;
-
- /* esde */
- uint8_t *decoderConfig;
- int32_t decoderConfigLen;
-
- uint32_t maxBitrate;
- uint32_t avgBitrate;
-
- uint32_t timeScale;
- uint64_t duration;
-
-} mp4ff_track_t;
-
-/* mp4 main file structure */
-typedef struct
-{
- /* stream to read from */
- mp4ff_callback_t *stream;
- int64_t current_position;
-
- int32_t moov_read;
- uint64_t moov_offset;
- uint64_t moov_size;
- uint8_t last_atom;
- uint64_t file_size;
-
- /* mvhd */
- int32_t time_scale;
- int32_t duration;
-
- /* incremental track index while reading the file */
- int32_t total_tracks;
-
- /* track data */
- mp4ff_track_t *track[MAX_TRACKS];
-
- /* metadata */
- mp4ff_metadata_t tags;
-} mp4ff_t;
-
-
-
-
-/* mp4util.c */
-int32_t mp4ff_read_data(mp4ff_t *f, void *data, uint32_t size);
-int32_t mp4ff_write_data(mp4ff_t *f, void *data, uint32_t size);
-uint64_t mp4ff_read_int64(mp4ff_t *f);
-uint32_t mp4ff_read_int32(mp4ff_t *f);
-uint32_t mp4ff_read_int24(mp4ff_t *f);
-uint16_t mp4ff_read_int16(mp4ff_t *f);
-uint8_t mp4ff_read_char(mp4ff_t *f);
-int32_t mp4ff_write_int32(mp4ff_t *f,const uint32_t data);
-uint32_t mp4ff_read_mp4_descr_length(mp4ff_t *f);
-int64_t mp4ff_position(const mp4ff_t *f);
-int32_t mp4ff_set_position(mp4ff_t *f, const int64_t position);
-int32_t mp4ff_truncate(mp4ff_t * f);
-char * mp4ff_read_string(mp4ff_t * f,uint32_t length);
-
-/* mp4atom.c */
-uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_size);
-int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type);
-
-/* mp4sample.c */
-int32_t mp4ff_audio_frame_size(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_set_sample_position(mp4ff_t *f, const int32_t track, const int32_t sample);
-
-#ifdef USE_TAGGING
-/* mp4meta.c */
-int32_t mp4ff_parse_metadata(mp4ff_t *f, const int32_t size);
-int32_t mp4ff_tag_delete(mp4ff_metadata_t *tags);
-int32_t mp4ff_meta_get_num_items(const mp4ff_t *f);
-int32_t mp4ff_meta_get_by_index(const mp4ff_t *f, uint32_t index,
- char **item, char **value);
-int32_t mp4ff_meta_get_title(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_artist(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_writer(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_album(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_date(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_tool(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_comment(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_genre(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_track(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_disc(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_compilation(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_tempo(const mp4ff_t *f, char **value);
-int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value);
-#endif
-
-/* mp4ff.c */
-mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f);
-#ifdef USE_TAGGING
-mp4ff_t *mp4ff_open_edit(mp4ff_callback_t *f);
-#endif
-void mp4ff_close(mp4ff_t *ff);
-//void mp4ff_track_add(mp4ff_t *f);
-int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size,int meta_only);
-int32_t parse_atoms(mp4ff_t *f,int meta_only);
-
-int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
-
-int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
- uint8_t **audio_buffer, uint32_t *bytes);
-int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
- uint8_t** ppBuf, uint32_t* pBufSize);
-int32_t mp4ff_total_tracks(const mp4ff_t *f);
-int32_t mp4ff_time_scale(const mp4ff_t *f, const int32_t track);
-int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track);
-
-uint32_t mp4ff_meta_genre_to_index(const char * genrestr);//returns 1-based index, 0 if not found
-const char * mp4ff_meta_index_to_genre(uint32_t idx);//returns pointer to static string
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif
diff --git a/src/aac/mp4ff/mp4meta.c b/src/aac/mp4ff/mp4meta.c
deleted file mode 100644
index f1d8270e8dce..000000000000
--- a/src/aac/mp4ff/mp4meta.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
-**
-** 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.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** The "appropriate copyright message" mentioned in section 2c of the GPLv2
-** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Nero AG through Mpeg4AAClicense at nero.com.
-**
-** $Id: mp4meta.c,v 1.21 2009/01/19 23:56:30 menno Exp $
-**/
-
-#ifdef USE_TAGGING
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <glib.h>
-#include "mp4ffint.h"
-
-
-
-static int32_t mp4ff_tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value)
-{
- void *backup = (void *)tags->tags;
-
- if (!item || (item && !*item) || !value) return 0;
-
- tags->tags = (mp4ff_tag_t*)realloc(tags->tags, (tags->count+1) * sizeof(mp4ff_tag_t));
- if (!tags->tags)
- {
- if (backup) free(backup);
- return 0;
- } else {
- tags->tags[tags->count].item = strdup(item);
- tags->tags[tags->count].value = strdup(value);
-
- if (!tags->tags[tags->count].item || !tags->tags[tags->count].value)
- {
- if (!tags->tags[tags->count].item) free (tags->tags[tags->count].item);
- if (!tags->tags[tags->count].value) free (tags->tags[tags->count].value);
- tags->tags[tags->count].item = NULL;
- tags->tags[tags->count].value = NULL;
- return 0;
- }
-
- tags->count++;
- return 1;
- }
-}
-
-/* GCC 4 says: unused!
-static int32_t mp4ff_tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value)
-{
- unsigned int i;
-
- if (!item || (item && !*item) || !value) return 0;
-
- for (i = 0; i < tags->count; i++)
- {
- if (!g_ascii_strcasecmp(tags->tags[i].item, item))
- {
- free(tags->tags[i].value);
- tags->tags[i].value = strdup(value);
- return 1;
- }
- }
-
- return mp4ff_tag_add_field(tags, item, value);
-}
-*/
-
-int32_t mp4ff_tag_delete(mp4ff_metadata_t *tags)
-{
- uint32_t i;
-
- for (i = 0; i < tags->count; i++)
- {
- if (tags->tags[i].item) free(tags->tags[i].item);
- if (tags->tags[i].value) free(tags->tags[i].value);
- }
-
- if (tags->tags) free(tags->tags);
-
- tags->tags = NULL;
- tags->count = 0;
-
- return 0;
-}
-
-static const char* ID3v1GenreList[] = {
- "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk",
- "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies",
- "Other", "Pop", "R&B", "Rap", "Reggae", "Rock",
- "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks",
- "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk",
- "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House",
- "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass",
- "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock",
- "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk",
- "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta",
- "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret",
- "New Wave", "Psychedelic", "Rave", "Showtunes", "Trailer", "Lo-Fi",
- "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical",
- "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing",
- "Fast-Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde",
- "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band",
- "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson",
- "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus",
- "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba",
- "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet",
- "Punk Rock", "Drum Solo", "A capella", "Euro-House", "Dance Hall",
- "Goa", "Drum & Bass", "Club House", "Hardcore", "Terror",
- "Indie", "BritPop", "NegerPunk", "Polsk Punk", "Beat",
- "Christian Gangsta", "Heavy Metal", "Black Metal", "Crossover", "Contemporary C",
- "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop",
- "SynthPop",
-};
-
-uint32_t mp4ff_meta_genre_to_index(const char * genrestr)
-{
- unsigned n;
- for(n=0;n<sizeof(ID3v1GenreList)/sizeof(ID3v1GenreList[0]);n++)
- {
- if (!g_ascii_strcasecmp(genrestr,ID3v1GenreList[n])) return n+1;
- }
- return 0;
-}
-
-const char * mp4ff_meta_index_to_genre(uint32_t idx)
-{
- if (idx>0 && idx<=sizeof(ID3v1GenreList)/sizeof(ID3v1GenreList[0]))
- {
- return ID3v1GenreList[idx-1];
- }
- else
- {
- return 0;
- }
-}
-
-/* GCC4 says: unused!
-static int32_t TrackToString(char** str, const uint16_t track, const uint16_t totalTracks)
-{
- char temp[32];
- sprintf(temp, "%.5u of %.5u", track, totalTracks);
- *str = strdup(temp);
- return 0;
-}
-*/
-
-static int32_t mp4ff_set_metadata_name(mp4ff_t *f, const uint8_t atom_type, char **name)
-{
- static char *tag_names[] = {
- "unknown", "title", "artist", "writer", "album",
- "date", "tool", "comment", "genre", "track",
- "disc", "compilation", "genre", "tempo", "cover",
- "album_artist", "contentgroup", "lyrics", "description",
- "network", "show", "episodename",
- "sorttitle", "sortalbum", "sortartist", "sortalbumartist",
- "sortwriter", "sortshow",
- "season", "episode", "podcast"
-
- };
- uint8_t tag_idx = 0;
-
- switch (atom_type)
- {
- case ATOM_TITLE: tag_idx = 1; break;
- case ATOM_ARTIST: tag_idx = 2; break;
- case ATOM_WRITER: tag_idx = 3; break;
- case ATOM_ALBUM: tag_idx = 4; break;
- case ATOM_DATE: tag_idx = 5; break;
- case ATOM_TOOL: tag_idx = 6; break;
- case ATOM_COMMENT: tag_idx = 7; break;
- case ATOM_GENRE1: tag_idx = 8; break;
- case ATOM_TRACK: tag_idx = 9; break;
- case ATOM_DISC: tag_idx = 10; break;
- case ATOM_COMPILATION: tag_idx = 11; break;
- case ATOM_GENRE2: tag_idx = 12; break;
- case ATOM_TEMPO: tag_idx = 13; break;
- case ATOM_COVER: tag_idx = 14; break;
- case ATOM_ALBUM_ARTIST: tag_idx = 15; break;
- case ATOM_CONTENTGROUP: tag_idx = 16; break;
- case ATOM_LYRICS: tag_idx = 17; break;
- case ATOM_DESCRIPTION: tag_idx = 18; break;
- case ATOM_NETWORK: tag_idx = 19; break;
- case ATOM_SHOW: tag_idx = 20; break;
- case ATOM_EPISODENAME: tag_idx = 21; break;
- case ATOM_SORTTITLE: tag_idx = 22; break;
- case ATOM_SORTALBUM: tag_idx = 23; break;
- case ATOM_SORTARTIST: tag_idx = 24; break;
- case ATOM_SORTALBUMARTIST: tag_idx = 25; break;
- case ATOM_SORTWRITER: tag_idx = 26; break;
- case ATOM_SORTSHOW: tag_idx = 27; break;
- case ATOM_SEASON: tag_idx = 28; break;
- case ATOM_EPISODE: tag_idx = 29; break;
- case ATOM_PODCAST: tag_idx = 30; break;
- default: tag_idx = 0; break;
- }
-
- *name = strdup(tag_names[tag_idx]);
-
- return 0;
-}
-
-static int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size)
-{
- uint8_t atom_type;
- uint8_t header_size = 0;
- uint64_t subsize, sumsize = 0;
- char * name = NULL;
- char * data = NULL;
- uint32_t done = 0;
-
-
- while (sumsize < size)
- {
- uint64_t destpos;
- subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
- if (!subsize)
- break;
-
- destpos = mp4ff_position(f)+subsize-header_size;
- if (!done)
- {
- if (atom_type == ATOM_DATA)
- {
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- mp4ff_read_int32(f); /* reserved */
-
- /* some need special attention */
- if (parent_atom_type == ATOM_GENRE2 || parent_atom_type == ATOM_TEMPO)
- {
- if (subsize - header_size >= 8 + 2)
- {
- uint16_t val = mp4ff_read_int16(f);
-
- if (parent_atom_type == ATOM_TEMPO)
- {
- char temp[16];
- sprintf(temp, "%.5u BPM", val);
- mp4ff_tag_add_field(&(f->tags), "tempo", temp);
- }
- else
- {
- const char * temp = mp4ff_meta_index_to_genre(val);
- if (temp)
- {
- mp4ff_tag_add_field(&(f->tags), "genre", temp);
- }
- }
- done = 1;
- }
- } else if (parent_atom_type == ATOM_TRACK || parent_atom_type == ATOM_DISC) {
- /* if (!done && subsize - header_size >= 8 + 8) */
- /* modified by AJS */
- if ( !done && (subsize - header_size) >=
- (sizeof(char) + sizeof(uint8_t)*3 + sizeof(uint32_t) + /* version + flags + reserved */
- + sizeof(uint16_t) /* leading uint16_t */
- + sizeof(uint16_t) /* track / disc */
- + sizeof(uint16_t)) /* totaltracks / totaldiscs */
- )
- {
- uint16_t index,total;
- char temp[32];
- mp4ff_read_int16(f);
- index = mp4ff_read_int16(f);
- total = mp4ff_read_int16(f);
- /* modified by AJS */
- /* mp4ff_read_int16(f); */
-
- sprintf(temp,"%d",index);
- mp4ff_tag_add_field(&(f->tags), parent_atom_type == ATOM_TRACK ? "track" : "disc", temp);
- if (total>0)
- {
- sprintf(temp,"%d",total);
- mp4ff_tag_add_field(&(f->tags), parent_atom_type == ATOM_TRACK ? "totaltracks" : "totaldiscs", temp);
- }
- done = 1;
- }
- } else
- {
- if (data) {free(data);data = NULL;}
- data = mp4ff_read_string(f,(uint32_t)(subsize-(header_size+8)));
- }
- } else if (atom_type == ATOM_NAME) {
- if (!done)
- {
- mp4ff_read_char(f); /* version */
- mp4ff_read_int24(f); /* flags */
- if (name) free(name);
- name = mp4ff_read_string(f,(uint32_t)(subsize-(header_size+4)));
- }
- }
- mp4ff_set_position(f, destpos);
- sumsize += subsize;
- }
- }
-
- if (data)
- {
- if (!done)
- {
- if (name == NULL) mp4ff_set_metadata_name(f, parent_atom_type, &name);
- if (name) mp4ff_tag_add_field(&(f->tags), name, data);
- }
-
- free(data);
- }
- if (name) free(name);
- return 1;
-}
-
-int32_t mp4ff_parse_metadata(mp4ff_t *f, const int32_t size)
-{
- uint64_t subsize, sumsize = 0;
- uint8_t atom_type;
- uint8_t header_size = 0;
-
- while (sumsize < size)
- {
- subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
- if (subsize == 0)
- break;
- mp4ff_parse_tag(f, atom_type, (uint32_t)(subsize-header_size));
- sumsize += subsize;
- }
-
- return 0;
-}
-
-/* find a metadata item by name */
-/* returns 0 if item found, 1 if no such item */
-static int32_t mp4ff_meta_find_by_name(const mp4ff_t *f, const char *item, char **value)
-{
- uint32_t i;
-
- for (i = 0; i < f->tags.count; i++)
- {
- if (!g_ascii_strcasecmp(f->tags.tags[i].item, item))
- {
- *value = strdup(f->tags.tags[i].value);
- return 1;
- }
- }
-
- *value = NULL;
-
- /* not found */
- return 0;
-}
-
-int32_t mp4ff_meta_get_num_items(const mp4ff_t *f)
-{
- return f->tags.count;
-}
-
-int32_t mp4ff_meta_get_by_index(const mp4ff_t *f, uint32_t index,
- char **item, char **value)
-{
- if (index >= f->tags.count)
- {
- *item = NULL;
- *value = NULL;
- return 0;
- } else {
- *item = strdup(f->tags.tags[index].item);
- *value = strdup(f->tags.tags[index].value);
- return 1;
- }
-}
-
-int32_t mp4ff_meta_get_title(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "title", value);
-}
-
-int32_t mp4ff_meta_get_artist(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "artist", value);
-}
-
-int32_t mp4ff_meta_get_writer(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "writer", value);
-}
-
-int32_t mp4ff_meta_get_album(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "album", value);
-}
-
-int32_t mp4ff_meta_get_date(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "date", value);
-}
-
-int32_t mp4ff_meta_get_tool(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "tool", value);
-}
-
-int32_t mp4ff_meta_get_comment(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "comment", value);
-}
-
-int32_t mp4ff_meta_get_genre(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "genre", value);
-}
-
-int32_t mp4ff_meta_get_track(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "track", value);
-}
-
-int32_t mp4ff_meta_get_totaltracks(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "totaltracks", value);
-}
-
-int32_t mp4ff_meta_get_disc(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "disc", value);
-}
-
-int32_t mp4ff_meta_get_totaldiscs(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "totaldiscs", value);
-}
-
-int32_t mp4ff_meta_get_compilation(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "compilation", value);
-}
-
-int32_t mp4ff_meta_get_tempo(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "tempo", value);
-}
-
-int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value)
-{
- return mp4ff_meta_find_by_name(f, "cover", value);
-}
-
-#endif
diff --git a/src/aac/mp4ff/mp4sample.c b/src/aac/mp4ff/mp4sample.c
deleted file mode 100644
index cb22264f7782..000000000000
--- a/src/aac/mp4ff/mp4sample.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
-**
-** 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.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** The "appropriate copyright message" mentioned in section 2c of the GPLv2
-** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Nero AG through Mpeg4AAClicense at nero.com.
-**
-** $Id: mp4sample.c,v 1.20 2007/11/01 12:33:29 menno Exp $
-**/
-
-#include <stdlib.h>
-#include "mp4ffint.h"
-
-
-static int32_t mp4ff_chunk_of_sample(const mp4ff_t *f, const int32_t track, const int32_t sample,
- int32_t *chunk_sample, int32_t *chunk)
-{
- int32_t total_entries = 0;
- int32_t chunk2entry;
- int32_t chunk1, chunk2, chunk1samples, range_samples, total = 0;
-
- if (f->track[track] == NULL)
- {
- return -1;
- }
-
- total_entries = f->track[track]->stsc_entry_count;
-
- chunk1 = 1;
- chunk1samples = 0;
- chunk2entry = 0;
-
- do
- {
- chunk2 = f->track[track]->stsc_first_chunk[chunk2entry];
- *chunk = chunk2 - chunk1;
- range_samples = *chunk * chunk1samples;
-
- if (sample < total + range_samples) break;
-
- chunk1samples = f->track[track]->stsc_samples_per_chunk[chunk2entry];
- chunk1 = chunk2;
-
- if(chunk2entry < total_entries)
- {
- chunk2entry++;
- total += range_samples;
- }
- } while (chunk2entry < total_entries);
-
- if (chunk1samples)
- *chunk = (sample - total) / chunk1samples + chunk1;
- else
- *chunk = 1;
-
- *chunk_sample = total + (*chunk - chunk1) * chunk1samples;
-
- return 0;
-}
-
-static int32_t mp4ff_chunk_to_offset(const mp4ff_t *f, const int32_t track, const int32_t chunk)
-{
- const mp4ff_track_t * p_track = f->track[track];
-
- if (p_track->stco_entry_count && (chunk > p_track->stco_entry_count))
- {
- return p_track->stco_chunk_offset[p_track->stco_entry_count - 1];
- } else if (p_track->stco_entry_count) {
- return p_track->stco_chunk_offset[chunk - 1];
- } else {
- return 8;
- }
-
- return 0;
-}
-
-static int32_t mp4ff_sample_range_size(const mp4ff_t *f, const int32_t track,
- const int32_t chunk_sample, const int32_t sample)
-{
- int32_t i, total;
- const mp4ff_track_t * p_track = f->track[track];
-
- if (p_track->stsz_sample_size)
- {
- return (sample - chunk_sample) * p_track->stsz_sample_size;
- }
- else
- {
- if (sample>=p_track->stsz_sample_count) return 0;//error
-
- for(i = chunk_sample, total = 0; i < sample; i++)
- {
- total += p_track->stsz_table[i];
- }
- }
-
- return total;
-}
-
-static int32_t mp4ff_sample_to_offset(const mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t chunk=0, chunk_sample=0, chunk_offset1, chunk_offset2;
-
- mp4ff_chunk_of_sample(f, track, sample, &chunk_sample, &chunk);
-
- chunk_offset1 = mp4ff_chunk_to_offset(f, track, chunk);
- chunk_offset2 = chunk_offset1 + mp4ff_sample_range_size(f, track, chunk_sample, sample);
-
- return chunk_offset2;
-}
-
-int32_t mp4ff_audio_frame_size(const mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t bytes;
- const mp4ff_track_t * p_track = f->track[track];
-
- if (p_track->stsz_sample_size)
- {
- bytes = p_track->stsz_sample_size;
- } else {
- bytes = p_track->stsz_table[sample];
- }
-
- return bytes;
-}
-
-int32_t mp4ff_set_sample_position(mp4ff_t *f, const int32_t track, const int32_t sample)
-{
- int32_t offset;
-
- offset = mp4ff_sample_to_offset(f, track, sample);
- mp4ff_set_position(f, offset);
-
- return 0;
-}
diff --git a/src/aac/mp4ff/mp4tagupdate.c b/src/aac/mp4ff/mp4tagupdate.c
deleted file mode 100644
index 4b6d79fbffc8..000000000000
--- a/src/aac/mp4ff/mp4tagupdate.c
+++ /dev/null
@@ -1,658 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include "mp4ffint.h"
-
-#ifdef USE_TAGGING
-
-static uint32_t fix_byte_order_32(uint32_t src)
-{
- uint32_t result;
- uint32_t a, b, c, d;
- int8_t data[4];
-
- memcpy(data,&src,sizeof(src));
- a = (uint8_t)data[0];
- b = (uint8_t)data[1];
- c = (uint8_t)data[2];
- d = (uint8_t)data[3];
-
- result = (a<<24) | (b<<16) | (c<<8) | d;
- return (uint32_t)result;
-}
-
-/* GCC4 says: unused!
-static uint16_t fix_byte_order_16(uint16_t src)
-{
- uint16_t result;
- uint16_t a, b;
- int8_t data[2];
-
- memcpy(data,&src,sizeof(src));
- a = (uint8_t)data[0];
- b = (uint8_t)data[1];
-
- result = (a<<8) | b;
- return (uint16_t)result;
-}
-*/
-
-typedef struct
-{
- void * data;
- unsigned written;
- unsigned allocated;
- unsigned error;
-} membuffer;
-
-unsigned membuffer_write(membuffer * buf,const void * ptr,unsigned bytes)
-{
- unsigned dest_size = buf->written + bytes;
-
- if (buf->error) return 0;
- if (dest_size > buf->allocated)
- {
- do
- {
- buf->allocated <<= 1;
- } while(dest_size > buf->allocated);
-
- {
- void * newptr = realloc(buf->data,buf->allocated);
- if (newptr==0)
- {
- free(buf->data);
- buf->data = 0;
- buf->error = 1;
- return 0;
- }
- buf->data = newptr;
- }
- }
-
- if (ptr) memcpy((char*)buf->data + buf->written,ptr,bytes);
- buf->written += bytes;
- return bytes;
-}
-
-#define membuffer_write_data membuffer_write
-
-unsigned membuffer_write_int32(membuffer * buf,uint32_t data)
-{
- uint8_t temp[4] = {(uint8_t)(data>>24),(uint8_t)(data>>16),(uint8_t)(data>>8),(uint8_t)data};
- return membuffer_write_data(buf,temp,4);
-}
-
-unsigned membuffer_write_int24(membuffer * buf,uint32_t data)
-{
- uint8_t temp[3] = {(uint8_t)(data>>16),(uint8_t)(data>>8),(uint8_t)data};
- return membuffer_write_data(buf,temp,3);
-}
-
-unsigned membuffer_write_int16(membuffer * buf,uint16_t data)
-{
- uint8_t temp[2] = {(uint8_t)(data>>8),(uint8_t)data};
- return membuffer_write_data(buf,temp,2);
-}
-
-unsigned membuffer_write_atom_name(membuffer * buf,const char * data)
-{
- return membuffer_write_data(buf,data,4)==4 ? 1 : 0;
-}
-
-void membuffer_write_atom(membuffer * buf,const char * name,unsigned size,const void * data)
-{
- membuffer_write_int32(buf,size + 8);
- membuffer_write_atom_name(buf,name);
- membuffer_write_data(buf,data,size);
-}
-
-unsigned membuffer_write_string(membuffer * buf,const char * data)
-{
- return membuffer_write_data(buf,data,strlen(data));
-}
-
-unsigned membuffer_write_int8(membuffer * buf,uint8_t data)
-{
- return membuffer_write_data(buf,&data,1);
-}
-
-void * membuffer_get_ptr(const membuffer * buf)
-{
- return buf->data;
-}
-
-unsigned membuffer_get_size(const membuffer * buf)
-{
- return buf->written;
-}
-
-unsigned membuffer_error(const membuffer * buf)
-{
- return buf->error;
-}
-
-void membuffer_set_error(membuffer * buf) {buf->error = 1;}
-
-unsigned membuffer_transfer_from_file(membuffer * buf,mp4ff_t * src,unsigned bytes)
-{
- unsigned oldsize;
- void * bufptr;
-
- oldsize = membuffer_get_size(buf);
- if (membuffer_write_data(buf,0,bytes) != bytes) return 0;
-
- bufptr = membuffer_get_ptr(buf);
- if (bufptr==0) return 0;
-
- if ((unsigned)mp4ff_read_data(src,(unsigned char*)bufptr + oldsize,bytes)!=bytes)
- {
- membuffer_set_error(buf);
- return 0;
- }
-
- return bytes;
-}
-
-
-membuffer * membuffer_create()
-{
- const unsigned initial_size = 256;
-
- membuffer * buf = (membuffer *) malloc(sizeof(membuffer));
- buf->data = malloc(initial_size);
- buf->written = 0;
- buf->allocated = initial_size;
- buf->error = buf->data == 0 ? 1 : 0;
-
- return buf;
-}
-
-void membuffer_free(membuffer * buf)
-{
- if (buf->data) free(buf->data);
- free(buf);
-}
-
-void * membuffer_detach(membuffer * buf)
-{
- void * ret;
-
- if (buf->error) return 0;
-
- ret = realloc(buf->data,buf->written);
-
- if (ret == 0) free(buf->data);
-
- buf->data = 0;
- buf->error = 1;
-
- return ret;
-}
-
-#if 0
-/* metadata tag structure */
-typedef struct
-{
- char *item;
- char *value;
-} mp4ff_tag_t;
-
-/* metadata list structure */
-typedef struct
-{
- mp4ff_tag_t *tags;
- uint32_t count;
-} mp4ff_metadata_t;
-#endif
-
-typedef struct
-{
- const char * atom;
- const char * name;
-} stdmeta_entry;
-
-static stdmeta_entry stdmetas[] =
-{
- {"\xA9" "nam","title"},
- {"\xA9" "ART","artist"},
- {"\xA9" "wrt","writer"},
- {"\xA9" "alb","album"},
- {"\xA9" "day","date"},
- {"\xA9" "too","tool"},
- {"\xA9" "cmt","comment"},
-// {"\xA9" "gen","genre"},
- {"cpil","compilation"},
-// {"trkn","track"},
-// {"disk","disc"},
-// {"gnre","genre"},
- {"covr","cover"},
- /* added by AJS */
- {"aART","album_artist"},
-};
-
-
-static const char* find_standard_meta(const char * name) //returns atom name if found, 0 if not
-{
- unsigned n;
- for(n=0;n<sizeof(stdmetas)/sizeof(stdmetas[0]);n++)
- {
- if (!g_ascii_strcasecmp(name,stdmetas[n].name)) return stdmetas[n].atom;
- }
- return 0;
-}
-
-static void membuffer_write_track_tag(membuffer * buf,const char * name,uint32_t index,uint32_t total)
-{
- membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + 8 /*actual data*/ );
- membuffer_write_atom_name(buf,name);
- membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + 8 /*actual data*/ );
- membuffer_write_atom_name(buf,"data");
- membuffer_write_int32(buf,0);//flags
- membuffer_write_int32(buf,0);//reserved
- membuffer_write_int16(buf,0);
- membuffer_write_int16(buf,(uint16_t)index);//track number
- membuffer_write_int16(buf,(uint16_t)total);//total tracks
- membuffer_write_int16(buf,0);
-}
-
-static void membuffer_write_int16_tag(membuffer * buf,const char * name,uint16_t value)
-{
- membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + 2 /*actual data*/ );
- membuffer_write_atom_name(buf,name);
- membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + 2 /*actual data*/ );
- membuffer_write_atom_name(buf,"data");
- membuffer_write_int32(buf,0);//flags
- membuffer_write_int32(buf,0);//reserved
- membuffer_write_int16(buf,value);//value
-}
-
-static void membuffer_write_std_tag(membuffer * buf,const char * name,const char * value)
-{
- /* added by AJS */
- uint32_t flags = 1;
-
- /* special check for compilation flag */
- if ( strcmp(name, "cpil") == 0)
- {
- flags = 21;
- }
-
- membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value) );
- membuffer_write_atom_name(buf,name);
- membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value));
- membuffer_write_atom_name(buf,"data");
- membuffer_write_int32(buf,flags);//flags
- membuffer_write_int32(buf,0);//reserved
- membuffer_write_data(buf,value,strlen(value));
-}
-
-static void membuffer_write_custom_tag(membuffer * buf,const char * name,const char * value)
-{
- membuffer_write_int32(buf,8 /*atom header*/ + 0x1C /*weirdo itunes atom*/ + 12 /*name atom header*/ + strlen(name) + 16 /*data atom header + flags*/ + strlen(value) );
- membuffer_write_atom_name(buf,"----");
- membuffer_write_int32(buf,0x1C);//weirdo itunes atom
- membuffer_write_atom_name(buf,"mean");
- membuffer_write_int32(buf,0);
- membuffer_write_data(buf,"com.apple.iTunes",16);
- membuffer_write_int32(buf,12 + strlen(name));
- membuffer_write_atom_name(buf,"name");
- membuffer_write_int32(buf,0);
- membuffer_write_data(buf,name,strlen(name));
- membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value));
- membuffer_write_atom_name(buf,"data");
- membuffer_write_int32(buf,1);//flags
- membuffer_write_int32(buf,0);//reserved
- membuffer_write_data(buf,value,strlen(value));
-
-}
-
-static uint32_t myatoi(const char * param)
-{
- return param ? atoi(param) : 0;
-}
-
-static uint32_t create_ilst(const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
-{
- membuffer * buf = membuffer_create();
- unsigned metaptr;
- char * mask = (char*)malloc(data->count);
- memset(mask,0,data->count);
-
- {
- const char * tracknumber_ptr = 0, * totaltracks_ptr = 0;
- const char * discnumber_ptr = 0, * totaldiscs_ptr = 0;
- const char * genre_ptr = 0, * tempo_ptr = 0;
- for(metaptr = 0; metaptr < data->count; metaptr++)
- {
- mp4ff_tag_t * tag = &data->tags[metaptr];
- if (!g_ascii_strcasecmp(tag->item,"tracknumber") || !g_ascii_strcasecmp(tag->item,"track"))
- {
- if (tracknumber_ptr==0) tracknumber_ptr = tag->value;
- mask[metaptr] = 1;
- }
- else if (!g_ascii_strcasecmp(tag->item,"totaltracks"))
- {
- if (totaltracks_ptr==0) totaltracks_ptr = tag->value;
- mask[metaptr] = 1;
- }
- else if (!g_ascii_strcasecmp(tag->item,"discnumber") || !g_ascii_strcasecmp(tag->item,"disc"))
- {
- if (discnumber_ptr==0) discnumber_ptr = tag->value;
- mask[metaptr] = 1;
- }
- else if (!g_ascii_strcasecmp(tag->item,"totaldiscs"))
- {
- if (totaldiscs_ptr==0) totaldiscs_ptr = tag->value;
- mask[metaptr] = 1;
- }
- else if (!g_ascii_strcasecmp(tag->item,"genre"))
- {
- if (genre_ptr==0) genre_ptr = tag->value;
- mask[metaptr] = 1;
- }
- else if (!g_ascii_strcasecmp(tag->item,"tempo"))
- {
- if (tempo_ptr==0) tempo_ptr = tag->value;
- mask[metaptr] = 1;
- }
-
- }
-
- if (tracknumber_ptr) membuffer_write_track_tag(buf,"trkn",myatoi(tracknumber_ptr),myatoi(totaltracks_ptr));
- if (discnumber_ptr) membuffer_write_track_tag(buf,"disk",myatoi(discnumber_ptr),myatoi(totaldiscs_ptr));
- if (tempo_ptr) membuffer_write_int16_tag(buf,"tmpo",(uint16_t)myatoi(tempo_ptr));
-
- if (genre_ptr)
- {
- uint32_t index = mp4ff_meta_genre_to_index(genre_ptr);
- if (index==0)
- membuffer_write_std_tag(buf,"\xa9""gen",genre_ptr);
- else
- membuffer_write_int16_tag(buf,"gnre",(uint16_t)index);
- }
- }
-
- for(metaptr = 0; metaptr < data->count; metaptr++)
- {
- if (!mask[metaptr])
- {
- mp4ff_tag_t * tag = &data->tags[metaptr];
- const char * std_meta_atom = find_standard_meta(tag->item);
- if (std_meta_atom)
- {
- membuffer_write_std_tag(buf,std_meta_atom,tag->value);
- }
- else
- {
- membuffer_write_custom_tag(buf,tag->item,tag->value);
- }
- }
- }
-
- free(mask);
-
- if (membuffer_error(buf))
- {
- membuffer_free(buf);
- return 0;
- }
-
- *out_size = membuffer_get_size(buf);
- *out_buffer = membuffer_detach(buf);
- membuffer_free(buf);
-
- return 1;
-}
-
-static uint32_t find_atom(mp4ff_t * f,uint64_t base,uint32_t size,const char * name)
-{
- uint32_t remaining = size;
- uint64_t atom_offset = base;
- for(;;)
- {
- unsigned char atom_name[4];
- uint32_t atom_size;
-
- mp4ff_set_position(f,atom_offset);
-
- if (remaining < 8) break;
- atom_size = mp4ff_read_int32(f);
- if (atom_size > remaining || atom_size < 8) break;
- mp4ff_read_data(f,atom_name,4);
-
- if (!memcmp(atom_name,name,4))
- {
- mp4ff_set_position(f,atom_offset);
- return 1;
- }
-
- remaining -= atom_size;
- atom_offset += atom_size;
- }
- return 0;
-}
-
-static uint32_t find_atom_v2(mp4ff_t * f,uint64_t base,uint32_t size,const char * name,uint32_t extraheaders,const char * name_inside)
-{
- uint64_t first_base = (uint64_t)(-1);
- while(find_atom(f,base,size,name))//try to find atom <name> with atom <name_inside> in it
- {
- uint64_t mybase = mp4ff_position(f);
- uint32_t mysize = mp4ff_read_int32(f);
-
- if (first_base == (uint64_t)(-1)) first_base = mybase;
-
- if (mysize < 8 + extraheaders) break;
-
- if (find_atom(f,mybase+(8+extraheaders),mysize-(8+extraheaders),name_inside))
- {
- mp4ff_set_position(f,mybase);
- return 2;
- }
- base += mysize;
- if (size<=mysize) {size=0;break;}
- size -= mysize;
- }
-
- if (first_base != (uint64_t)(-1))//wanted atom inside not found
- {
- mp4ff_set_position(f,first_base);
- return 1;
- }
- else return 0;
-}
-
-static uint32_t create_meta(const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
-{
- membuffer * buf;
- uint32_t ilst_size;
- void * ilst_buffer;
-
- if (!create_ilst(data,&ilst_buffer,&ilst_size)) return 0;
-
- buf = membuffer_create();
-
- membuffer_write_int32(buf,0);
- membuffer_write_atom(buf,"ilst",ilst_size,ilst_buffer);
- free(ilst_buffer);
-
- *out_size = membuffer_get_size(buf);
- *out_buffer = membuffer_detach(buf);
- membuffer_free(buf);
- return 1;
-}
-
-static uint32_t create_udta(const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
-{
- membuffer * buf;
- uint32_t meta_size;
- void * meta_buffer;
-
- if (!create_meta(data,&meta_buffer,&meta_size)) return 0;
-
- buf = membuffer_create();
-
- membuffer_write_atom(buf,"meta",meta_size,meta_buffer);
-
- free(meta_buffer);
-
- *out_size = membuffer_get_size(buf);
- *out_buffer = membuffer_detach(buf);
- membuffer_free(buf);
- return 1;
-}
-
-static uint32_t modify_moov(mp4ff_t * f,const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
-{
- uint64_t total_base = f->moov_offset + 8;
- uint32_t total_size = (uint32_t)(f->moov_size - 8);
-
- uint64_t udta_offset,meta_offset,ilst_offset;
- uint32_t udta_size, meta_size, ilst_size;
-
- uint32_t new_ilst_size;
- void * new_ilst_buffer;
-
- uint8_t * p_out;
- int32_t size_delta;
-
-
- if (!find_atom_v2(f,total_base,total_size,"udta",0,"meta"))
- {
- membuffer * buf;
- void * new_udta_buffer;
- uint32_t new_udta_size;
- if (!create_udta(data,&new_udta_buffer,&new_udta_size)) return 0;
-
- buf = membuffer_create();
- mp4ff_set_position(f,total_base);
- membuffer_transfer_from_file(buf,f,total_size);
-
- membuffer_write_atom(buf,"udta",new_udta_size,new_udta_buffer);
-
- free(new_udta_buffer);
-
- *out_size = membuffer_get_size(buf);
- *out_buffer = membuffer_detach(buf);
- membuffer_free(buf);
- return 1;
- }
- else
- {
- udta_offset = mp4ff_position(f);
- udta_size = mp4ff_read_int32(f);
- if (!find_atom_v2(f,udta_offset+8,udta_size-8,"meta",4,"ilst"))
- {
- membuffer * buf;
- void * new_meta_buffer;
- uint32_t new_meta_size;
- if (!create_meta(data,&new_meta_buffer,&new_meta_size)) return 0;
-
- buf = membuffer_create();
- mp4ff_set_position(f,total_base);
- membuffer_transfer_from_file(buf,f,(uint32_t)(udta_offset - total_base));
-
- membuffer_write_int32(buf,udta_size + 8 + new_meta_size);
- membuffer_write_atom_name(buf,"udta");
- membuffer_transfer_from_file(buf,f,udta_size);
-
- membuffer_write_atom(buf,"meta",new_meta_size,new_meta_buffer);
- free(new_meta_buffer);
-
- *out_size = membuffer_get_size(buf);
- *out_buffer = membuffer_detach(buf);
- membuffer_free(buf);
- return 1;
- }
- meta_offset = mp4ff_position(f);
- meta_size = mp4ff_read_int32(f);
- if (!find_atom(f,meta_offset+12,meta_size-12,"ilst")) return 0;//shouldn't happen, find_atom_v2 above takes care of it
- ilst_offset = mp4ff_position(f);
- ilst_size = mp4ff_read_int32(f);
-
- if (!create_ilst(data,&new_ilst_buffer,&new_ilst_size)) return 0;
-
- size_delta = new_ilst_size - (ilst_size - 8);
-
- *out_size = total_size + size_delta;
- *out_buffer = malloc(*out_size);
- if (*out_buffer == 0)
- {
- free(new_ilst_buffer);
- return 0;
- }
-
- p_out = (uint8_t*)*out_buffer;
-
- mp4ff_set_position(f,total_base);
- mp4ff_read_data(f,p_out,(uint32_t)(udta_offset - total_base )); p_out += (uint32_t)(udta_offset - total_base );
- *(uint32_t*)p_out = fix_byte_order_32(mp4ff_read_int32(f) + size_delta); p_out += 4;
- mp4ff_read_data(f,p_out,4); p_out += 4;
- mp4ff_read_data(f,p_out,(uint32_t)(meta_offset - udta_offset - 8)); p_out += (uint32_t)(meta_offset - udta_offset - 8);
- *(uint32_t*)p_out = fix_byte_order_32(mp4ff_read_int32(f) + size_delta); p_out += 4;
- mp4ff_read_data(f,p_out,4); p_out += 4;
- mp4ff_read_data(f,p_out,(uint32_t)(ilst_offset - meta_offset - 8)); p_out += (uint32_t)(ilst_offset - meta_offset - 8);
- *(uint32_t*)p_out = fix_byte_order_32(mp4ff_read_int32(f) + size_delta); p_out += 4;
- mp4ff_read_data(f,p_out,4); p_out += 4;
-
- memcpy(p_out,new_ilst_buffer,new_ilst_size);
- p_out += new_ilst_size;
-
- mp4ff_set_position(f,ilst_offset + ilst_size);
- mp4ff_read_data(f,p_out,(uint32_t)(total_size - (ilst_offset - total_base) - ilst_size));
-
- free(new_ilst_buffer);
- }
- return 1;
-
-}
-
-int32_t mp4ff_meta_update(mp4ff_callback_t *f,const mp4ff_metadata_t * data)
-{
- void * new_moov_data;
- uint32_t new_moov_size;
-
- mp4ff_t *ff = malloc(sizeof(mp4ff_t));
-
- memset(ff, 0, sizeof(mp4ff_t));
- ff->stream = f;
- mp4ff_set_position(ff,0);
-
- parse_atoms(ff,1);
-
-
- if (!modify_moov(ff,data,&new_moov_data,&new_moov_size))
- {
- mp4ff_close(ff);
- return 0;
- }
-
- /* copy moov atom to end of the file */
- if (ff->last_atom != ATOM_MOOV)
- {
- char *free_data = "free";
-
- /* rename old moov to free */
- mp4ff_set_position(ff, ff->moov_offset + 4);
- mp4ff_write_data(ff, free_data, 4);
-
- mp4ff_set_position(ff, ff->file_size);
- mp4ff_write_int32(ff,new_moov_size + 8);
- mp4ff_write_data(ff,"moov",4);
- mp4ff_write_data(ff, new_moov_data, new_moov_size);
- }
- else
- {
- mp4ff_set_position(ff, ff->moov_offset);
- mp4ff_write_int32(ff,new_moov_size + 8);
- mp4ff_write_data(ff,"moov",4);
- mp4ff_write_data(ff, new_moov_data, new_moov_size);
- }
-
- mp4ff_truncate(ff);
-
- mp4ff_close(ff);
- return 1;
-}
-#endif
diff --git a/src/aac/mp4ff/mp4util.c b/src/aac/mp4ff/mp4util.c
deleted file mode 100644
index 6e784ad2cc57..000000000000
--- a/src/aac/mp4ff/mp4util.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
-**
-** 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.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** The "appropriate copyright message" mentioned in section 2c of the GPLv2
-** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Nero AG through Mpeg4AAClicense at nero.com.
-**
-** $Id: mp4util.c,v 1.20 2007/11/01 12:33:29 menno Exp $
-**/
-
-#include "mp4ffint.h"
-#include <stdlib.h>
-
-int32_t mp4ff_read_data(mp4ff_t *f, void *data, uint32_t size)
-{
- int32_t result = 1;
-
- result = f->stream->read(f->stream->user_data, data, size);
-
- f->current_position += size;
-
- return result;
-}
-
-int32_t mp4ff_truncate(mp4ff_t * f)
-{
- return f->stream->truncate(f->stream->user_data);
-}
-
-int32_t mp4ff_write_data(mp4ff_t *f, void *data, uint32_t size)
-{
- int32_t result = 1;
-
- result = f->stream->write(f->stream->user_data, data, size);
-
- f->current_position += size;
-
- return result;
-}
-
-int32_t mp4ff_write_int32(mp4ff_t *f,const uint32_t data)
-{
- union {uint32_t dword; uint8_t bytes[4];} temp;
- uint32_t a, b, c, d, result;
-
- temp.dword = data;
- a = temp.bytes[0];
- b = temp.bytes[1];
- c = temp.bytes[2];
- d = temp.bytes[3];
-
- result = (a<<24) | (b<<16) | (c<<8) | d;
-
- return mp4ff_write_data(f,(uint8_t*)&result,sizeof(result));
-}
-
-int32_t mp4ff_set_position(mp4ff_t *f, const int64_t position)
-{
- if (f->stream->seek(f->stream->user_data, position) != 0)
- return -1;
-
- f->current_position = position;
- return 0;
-}
-
-int64_t mp4ff_position(const mp4ff_t *f)
-{
- return f->current_position;
-}
-
-uint64_t mp4ff_read_int64(mp4ff_t *f)
-{
- uint8_t data[8];
- uint64_t result = 0;
- int8_t i;
-
- mp4ff_read_data(f, data, 8);
-
- for (i = 0; i < 8; i++)
- {
- result |= ((uint64_t)data[i]) << ((7 - i) * 8);
- }
-
- return result;
-}
-
-uint32_t mp4ff_read_int32(mp4ff_t *f)
-{
- uint32_t result;
- uint32_t a, b, c, d;
- uint8_t data[4];
-
- mp4ff_read_data(f, data, 4);
- a = data[0];
- b = data[1];
- c = data[2];
- d = data[3];
-
- result = (a<<24) | (b<<16) | (c<<8) | d;
- return (uint32_t)result;
-}
-
-uint32_t mp4ff_read_int24(mp4ff_t *f)
-{
- uint32_t result;
- uint32_t a, b, c;
- uint8_t data[4];
-
- mp4ff_read_data(f, data, 3);
- a = data[0];
- b = data[1];
- c = data[2];
-
- result = (a<<16) | (b<<8) | c;
- return (uint32_t)result;
-}
-
-uint16_t mp4ff_read_int16(mp4ff_t *f)
-{
- uint32_t result;
- uint32_t a, b;
- uint8_t data[2];
-
- mp4ff_read_data(f, data, 2);
- a = data[0];
- b = data[1];
-
- result = (a<<8) | b;
- return (uint16_t)result;
-}
-
-char * mp4ff_read_string(mp4ff_t * f,uint32_t length)
-{
- char * str = (char*)malloc(length + 1);
- if (str!=0)
- {
- if ((uint32_t)mp4ff_read_data(f,str,length)!=length)
- {
- free(str);
- str = 0;
- }
- else
- {
- str[length] = 0;
- }
- }
- return str;
-}
-
-uint8_t mp4ff_read_char(mp4ff_t *f)
-{
- uint8_t output;
- mp4ff_read_data(f, &output, 1);
- return output;
-}
-
-uint32_t mp4ff_read_mp4_descr_length(mp4ff_t *f)
-{
- uint8_t b;
- uint8_t numBytes = 0;
- uint32_t length = 0;
-
- do
- {
- b = mp4ff_read_char(f);
- numBytes++;
- length = (length << 7) | (b & 0x7F);
- } while ((b & 0x80) && numBytes < 4);
-
- return length;
-}
diff --git a/src/adplug/Makefile b/src/adplug/Makefile
index 5c66ae0f1138..7ee162d39297 100644
--- a/src/adplug/Makefile
+++ b/src/adplug/Makefile
@@ -1,59 +1,58 @@
PLUGIN = adplug${PLUGIN_SUFFIX}
SRCS = adplug-xmms.cc \
- core/fmopl.c \
- core/debug.c \
- core/adlibemu.c \
- core/adplug.cxx \
- core/emuopl.cxx \
- core/fprovide.cxx \
- core/player.cxx \
- core/database.cxx \
- core/hsc.cxx \
- core/sng.cxx \
- core/imf.cxx \
- core/players.cxx \
- core/protrack.cxx \
- core/a2m.cxx \
- core/adtrack.cxx \
- core/amd.cxx \
- core/bam.cxx \
- core/cmf.cxx \
- core/d00.cxx \
- core/dfm.cxx \
- core/dmo.cxx \
- core/hsp.cxx \
- core/ksm.cxx \
- core/mad.cxx \
- core/mid.cxx \
- core/mkj.cxx \
- core/cff.cxx \
- core/dtm.cxx \
- core/fmc.cxx \
- core/mtk.cxx \
- core/rad.cxx \
- core/raw.cxx \
- core/sa2.cxx \
- core/s3m.cxx \
- core/xad.cxx \
- core/flash.cxx \
- core/bmf.cxx \
- core/hybrid.cxx \
- core/hyp.cxx \
- core/psi.cxx \
- core/rat.cxx \
- core/u6m.cxx \
- core/rol.cxx \
- core/xsm.cxx \
- core/dro.cxx \
- core/dro2.cxx \
- core/lds.cxx \
- core/temuopl.cxx \
- core/msc.cxx \
- core/rix.cxx \
- core/adl.cxx \
- core/jbm.cxx \
- plugin.c
+ core/fmopl.cc \
+ core/debug.cc \
+ core/adlibemu.cc \
+ core/adplug.cc \
+ core/emuopl.cc \
+ core/fprovide.cc \
+ core/player.cc \
+ core/database.cc \
+ core/hsc.cc \
+ core/sng.cc \
+ core/imf.cc \
+ core/players.cc \
+ core/protrack.cc \
+ core/a2m.cc \
+ core/adtrack.cc \
+ core/amd.cc \
+ core/bam.cc \
+ core/cmf.cc \
+ core/d00.cc \
+ core/dfm.cc \
+ core/dmo.cc \
+ core/hsp.cc \
+ core/ksm.cc \
+ core/mad.cc \
+ core/mid.cc \
+ core/mkj.cc \
+ core/cff.cc \
+ core/dtm.cc \
+ core/fmc.cc \
+ core/mtk.cc \
+ core/rad.cc \
+ core/raw.cc \
+ core/sa2.cc \
+ core/s3m.cc \
+ core/xad.cc \
+ core/flash.cc \
+ core/bmf.cc \
+ core/hybrid.cc \
+ core/hyp.cc \
+ core/psi.cc \
+ core/rat.cc \
+ core/u6m.cc \
+ core/rol.cc \
+ core/xsm.cc \
+ core/dro.cc \
+ core/dro2.cc \
+ core/lds.cc \
+ core/temuopl.cc \
+ core/msc.cc \
+ core/rix.cc \
+ core/adl.cc \
+ core/jbm.cc
include ../../buildsys.mk
include ../../extra.mk
@@ -62,6 +61,6 @@ plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
-CXXFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${BINIO_CFLAGS} -I../.. -I./core
-LIBS += ${GLIB_LIBS} ${BINIO_LIBS}
+CXXFLAGS += ${PLUGIN_CFLAGS} -Wno-sign-compare
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${BINIO_CFLAGS} -I../.. -I./core
+LIBS += ${BINIO_LIBS}
diff --git a/src/adplug/adplug-xmms.cc b/src/adplug/adplug-xmms.cc
index b65bad034da5..89696cd11873 100644
--- a/src/adplug/adplug-xmms.cc
+++ b/src/adplug/adplug-xmms.cc
@@ -28,19 +28,44 @@
#include "silentopl.h"
#include "players.h"
-extern "C" {
-#include <audacious/input.h>
-#include <audacious/misc.h>
-#include <audacious/i18n.h>
#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
-#include "adplug-xmms.h"
-}
+class AdPlugXMMS : public InputPlugin
+{
+public:
+ static const char * const exts[];
-/***** Defines *****/
+ static constexpr PluginInfo info = {
+ N_("AdPlug (AdLib Player)"),
+ PACKAGE
+ };
+
+ static constexpr auto iinfo = InputInfo ()
+ .with_exts (exts);
+
+ constexpr AdPlugXMMS () : InputPlugin (info, iinfo) {}
+
+ bool init ();
+ void cleanup ();
-// Version string
-#define ADPLUG_NAME "AdPlug (AdLib Sound Player)"
+ bool is_our_file (const char * filename, VFSFile & file);
+ Tuple read_tuple (const char * filename, VFSFile & file);
+ bool play (const char * filename, VFSFile & file);
+};
+
+EXPORT AdPlugXMMS aud_plugin_instance;
+
+const char * const AdPlugXMMS::exts[] = {
+ "a2m", "adl", "amd", "bam", "cff", "cmf", "d00", "dfm", "dmo", "dro",
+ "dtm", "hsc", "hsp", "ins", "jbm", "ksm", "laa", "lds", "m", "mad",
+ "mkj", "msc", "rad", "raw", "rix", "rol", "s3m", "sa2", "sat", "sci",
+ "sng", "wlf", "xad", "xsm", nullptr
+};
+
+/***** Defines *****/
// Sound buffer size in samples
#define SNDBUFSIZE 512
@@ -57,26 +82,20 @@ extern "C" {
/***** Global variables *****/
-static bool_t audio_error = FALSE;
-
// Configuration (and defaults)
-static struct
-{
- int freq;
- bool_t bit16, stereo, endless;
- CPlayers players;
-} conf =
-{
-44100l, true, false, false, CAdPlug::getPlayers()};
+static struct {
+ int freq = 44100l;
+ bool bit16 = true, stereo = false, endless = false;
+ CPlayers players = CAdPlug::getPlayers();
+} conf;
// Player variables
-static struct
-{
- CPlayer *p;
- CAdPlugDatabase *db;
- unsigned int subsong, songlength;
- char * filename;
-} plr = {0, 0, 0, 0, NULL};
+static struct {
+ CPlayer *p = nullptr;
+ CAdPlugDatabase *db = nullptr;
+ unsigned int subsong = 0, songlength = 0;
+ String filename;
+} plr;
/***** Debugging *****/
@@ -104,61 +123,62 @@ dbg_printf (const char *fmt, ...)
#endif
static CPlayer *
-factory (VFSFile * fd, Copl * newopl)
+factory (VFSFile & fd, Copl * newopl)
{
return CAdPlug::factory (fd, newopl, conf.players);
}
/***** Main player (!! threaded !!) *****/
-extern "C" Tuple * adplug_get_tuple (const char * filename, VFSFile * fd)
+Tuple AdPlugXMMS::read_tuple (const char * filename, VFSFile & fd)
{
- Tuple * ti = NULL;
+ Tuple tuple;
CSilentopl tmpopl;
if (!fd)
- return NULL;
+ return tuple;
CPlayer *p = factory (fd, &tmpopl);
if (p)
{
- ti = tuple_new_from_filename (filename);
+ tuple.set_filename (filename);
if (! p->getauthor().empty())
- tuple_set_str(ti, FIELD_ARTIST, p->getauthor().c_str());
+ tuple.set_str (Tuple::Artist, p->getauthor().c_str());
if (! p->gettitle().empty())
- tuple_set_str(ti, FIELD_TITLE, p->gettitle().c_str());
+ tuple.set_str (Tuple::Title, p->gettitle().c_str());
else if (! p->getdesc().empty())
- tuple_set_str(ti, FIELD_TITLE, p->getdesc().c_str());
+ tuple.set_str (Tuple::Title, p->getdesc().c_str());
- tuple_set_str(ti, FIELD_CODEC, p->gettype().c_str());
- tuple_set_str(ti, FIELD_QUALITY, _("sequenced"));
- tuple_set_int(ti, FIELD_LENGTH, p->songlength (plr.subsong));
+ tuple.set_str (Tuple::Codec, p->gettype().c_str());
+ tuple.set_str (Tuple::Quality, _("sequenced"));
+ tuple.set_int (Tuple::Length, p->songlength (plr.subsong));
delete p;
}
- return ti;
+ return tuple;
}
-// Define sampsize macro (only usable inside play_loop()!)
-#define sampsize ((bit16 ? 2 : 1) * (stereo ? 2 : 1))
-
-static bool_t play_loop (const char * filename, VFSFile * fd)
/* Main playback thread. Takes the filename to play as argument. */
+bool AdPlugXMMS::play (const char * filename, VFSFile & fd)
{
- dbg_printf ("play_loop(\"%s\"): ", filename);
+ dbg_printf ("adplug_play(\"%s\"): ", filename);
+
+ // Set XMMS main window information
+ dbg_printf ("xmms, ");
+ int sampsize = (conf.bit16 ? 2 : 1) * (conf.stereo ? 2 : 1);
+ set_stream_bitrate (conf.freq * sampsize * 8);
+
+ // open output plugin
+ dbg_printf ("open, ");
+ open_audio (conf.bit16 ? FORMAT_16 : FORMAT_8, conf.freq, conf.stereo ? 2 : 1);
+
CEmuopl opl (conf.freq, conf.bit16, conf.stereo);
long toadd = 0, i, towrite;
char *sndbuf, *sndbufpos;
- bool playing = true, // Song self-end indicator.
- bit16 = conf.bit16, // Duplicate config, so it doesn't affect us if
- stereo = conf.stereo; // the user changes it while we're playing.
- unsigned long freq = conf.freq;
-
- if (!fd)
- return FALSE;
+ bool playing = true; // Song self-end indicator.
// Try to load module
dbg_printf ("factory, ");
@@ -166,15 +186,14 @@ static bool_t play_loop (const char * filename, VFSFile * fd)
{
dbg_printf ("error!\n");
// MessageBox("AdPlug :: Error", "File could not be opened!", "Ok");
- return FALSE;
+ return false;
}
// reset to first subsong on new file
dbg_printf ("subsong, ");
if (! plr.filename || strcmp (filename, plr.filename))
{
- free (plr.filename);
- plr.filename = strdup (filename);
+ plr.filename = String (filename);
plr.subsong = 0;
}
@@ -182,28 +201,24 @@ static bool_t play_loop (const char * filename, VFSFile * fd)
dbg_printf ("buffer, ");
sndbuf = (char *) malloc (SNDBUFSIZE * sampsize);
- // Set XMMS main window information
- dbg_printf ("xmms, ");
- aud_input_set_bitrate (freq * sampsize * 8);
-
// Rewind player to right subsong
dbg_printf ("rewind, ");
plr.p->rewind (plr.subsong);
+ int time = 0;
+
// main playback loop
dbg_printf ("loop.\n");
while ((playing || conf.endless))
{
- if (aud_input_check_stop ())
+ if (check_stop ())
break;
- int seek = aud_input_check_seek ();
+ int seek = check_seek ();
// seek requested ?
if (seek != -1)
{
- int time = aud_input_written_time ();
-
// backward seek ?
if (seek < time)
{
@@ -223,17 +238,19 @@ static bool_t play_loop (const char * filename, VFSFile * fd)
{
while (toadd < 0)
{
- toadd += freq;
+ toadd += conf.freq;
playing = plr.p->update ();
+ if (playing)
+ time += (int) (1000 / plr.p->getrefresh ());
}
- i = MIN (towrite, (long) (toadd / plr.p->getrefresh () + 4) & ~3);
+ i = std::min (towrite, (long) (toadd / plr.p->getrefresh () + 4) & ~3);
opl.update ((short *) sndbufpos, i);
sndbufpos += i * sampsize;
towrite -= i;
toadd -= (long) (plr.p->getrefresh () * i);
}
- aud_input_write_audio (sndbuf, SNDBUFSIZE * sampsize);
+ write_audio (sndbuf, SNDBUFSIZE * sampsize);
}
// free everything and exit
@@ -242,7 +259,7 @@ static bool_t play_loop (const char * filename, VFSFile * fd)
plr.p = 0;
free (sndbuf);
dbg_printf (".\n");
- return TRUE;
+ return true;
}
// sampsize macro not useful anymore.
@@ -250,8 +267,7 @@ static bool_t play_loop (const char * filename, VFSFile * fd)
/***** Informational *****/
-extern "C" int
-adplug_is_our_fd (const char * filename, VFSFile * fd)
+bool AdPlugXMMS::is_our_file (const char * filename, VFSFile & fd)
{
CSilentopl tmpopl;
@@ -262,32 +278,12 @@ adplug_is_our_fd (const char * filename, VFSFile * fd)
if (p)
{
delete p;
- dbg_printf ("TRUE\n");
- return TRUE;
+ dbg_printf ("true\n");
+ return true;
}
- dbg_printf ("FALSE\n");
- return FALSE;
-}
-
-/***** Player control *****/
-
-extern "C" bool_t
-adplug_play (const char * filename, VFSFile * file)
-{
- dbg_printf ("adplug_play(\"%s\"): ", filename);
- audio_error = FALSE;
-
- // open output plugin
- dbg_printf ("open, ");
- if (!aud_input_open_audio (conf.bit16 ? FORMAT_16 : FORMAT_8, conf.freq, conf.stereo ? 2 : 1))
- {
- audio_error = TRUE;
- return TRUE;
- }
-
- play_loop (filename, file);
- return FALSE;
+ dbg_printf ("false\n");
+ return false;
}
/***** Configuration file handling *****/
@@ -299,9 +295,9 @@ static const char * const adplug_defaults[] = {
"Stereo", "FALSE",
"Frequency", "44100",
"Endless", "FALSE",
- NULL};
+ nullptr};
-extern "C" bool_t adplug_init (void)
+bool AdPlugXMMS::init ()
{
aud_config_set_defaults (CFG_VERSION, adplug_defaults);
@@ -313,26 +309,20 @@ extern "C" bool_t adplug_init (void)
// Read file type exclusion list
dbg_printf ("exclusion, ");
{
- char * cfgstr = aud_get_str (CFG_VERSION, "Exclude");
+ String cfgstr = aud_get_str (CFG_VERSION, "Exclude");
if (cfgstr[0])
{
- char exclude[strlen (cfgstr) + 2];
- memcpy (exclude, cfgstr, sizeof exclude - 1);
- exclude[sizeof exclude - 1] = 0;
+ StringBuf exclude = str_concat ({cfgstr, ":"});
str_replace_char (exclude, ':', 0);
for (char * p = exclude; * p; p += strlen (p) + 1)
conf.players.remove (conf.players.lookup_filetype (p));
}
-
- str_unref (cfgstr);
}
// Load database from disk and hand it to AdPlug
dbg_printf ("database");
- plr.db = new CAdPlugDatabase;
-
{
const char *homedir = getenv ("HOME");
@@ -341,29 +331,28 @@ extern "C" bool_t adplug_init (void)
std::string userdb;
userdb = std::string ("file://") + homedir + "/" ADPLUG_CONFDIR "/" + ADPLUGDB_FILE;
- if (vfs_file_test (userdb.c_str (), VFS_EXISTS))
+ if (VFSFile::test_file (userdb.c_str (), VFS_EXISTS))
{
+ plr.db = new CAdPlugDatabase;
plr.db->load (userdb); // load user's database
dbg_printf (" (userdb=\"%s\")", userdb.c_str());
+ CAdPlug::set_database (plr.db);
}
}
}
- CAdPlug::set_database (plr.db);
dbg_printf (".\n");
- return TRUE;
+ return true;
}
-extern "C" void
-adplug_quit (void)
+void AdPlugXMMS::cleanup ()
{
// Close database
dbg_printf ("db, ");
if (plr.db)
delete plr.db;
- free (plr.filename);
- plr.filename = NULL;
+ plr.filename = String ();
aud_set_bool (CFG_VERSION, "16bit", conf.bit16);
aud_set_bool (CFG_VERSION, "Stereo", conf.stereo);
diff --git a/src/adplug/adplug-xmms.h b/src/adplug/adplug-xmms.h
deleted file mode 100644
index 7941d7ccb53a..000000000000
--- a/src/adplug/adplug-xmms.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * AdPlug/XMMS - AdPlug XMMS Plugin
- * Copyright (C) 2002, 2003 Simon Peter <dn.tlp at gmx.net>
- *
- * AdPlug/XMMS 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 plugin 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 plugin; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef ADPLUG_XMMS_H
-#define ADPLUG_XMMS_H
-
-#include <audacious/plugin.h>
-
-bool_t adplug_init (void);
-void adplug_quit (void);
-void adplug_about (void);
-void adplug_config (void);
-bool_t adplug_play (const char * filename, VFSFile * file);
-void adplug_info_box (const char * filename);
-Tuple * adplug_get_tuple (const char * filename, VFSFile * file);
-bool_t adplug_is_our_fd (const char * filename, VFSFile * file);
-
-#endif
diff --git a/src/adplug/core/a2m.cc b/src/adplug/core/a2m.cc
new file mode 100644
index 000000000000..4c446c257c20
--- /dev/null
+++ b/src/adplug/core/a2m.cc
@@ -0,0 +1,597 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * a2m.cpp - A2M Loader by Simon Peter <dn.tlp at gmx.net>
+ *
+ * NOTES:
+ * This loader detects and loads version 1, 4, 5 & 8 files.
+ *
+ * version 1-4 files:
+ * Following commands are ignored: FF1 - FF9, FAx - FEx
+ *
+ * version 5-8 files:
+ * Instrument panning is ignored. Flags byte is ignored.
+ * Following commands are ignored: Gxy, Hxy, Kxy - &xy
+ */
+
+#include <string.h>
+
+#include "a2m.h"
+
+const unsigned int
+ Ca2mLoader::MAXFREQ = 2000,
+ Ca2mLoader::MINCOPY = ADPLUG_A2M_MINCOPY,
+ Ca2mLoader::MAXCOPY = ADPLUG_A2M_MAXCOPY,
+ Ca2mLoader::COPYRANGES = ADPLUG_A2M_COPYRANGES,
+ Ca2mLoader::CODESPERRANGE = ADPLUG_A2M_CODESPERRANGE,
+ Ca2mLoader::TERMINATE = 256,
+ Ca2mLoader::FIRSTCODE = ADPLUG_A2M_FIRSTCODE,
+ Ca2mLoader::MAXCODE = FIRSTCODE + COPYRANGES * CODESPERRANGE - 1,
+ Ca2mLoader::SUCCMAX = MAXCODE + 1,
+ Ca2mLoader::TWICEMAX = ADPLUG_A2M_TWICEMAX,
+ Ca2mLoader::ROOT = 1, Ca2mLoader::MAXBUF = 42 * 1024,
+ Ca2mLoader::MAXDISTANCE = 21389, Ca2mLoader::MAXSIZE = 21389 + MAXCOPY;
+
+const unsigned short
+Ca2mLoader::bitvalue[14] =
+ { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
+
+const signed short
+Ca2mLoader::copybits[COPYRANGES] = { 4, 6, 8, 10, 12, 14 };
+
+const signed short
+Ca2mLoader::copymin[COPYRANGES] = { 0, 16, 80, 336, 1360, 5456 };
+
+CPlayer *
+Ca2mLoader::factory (Copl * newopl)
+{
+ return new Ca2mLoader (newopl);
+}
+
+bool
+Ca2mLoader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ char id[10];
+ int i, j, k, t;
+ unsigned int l;
+ unsigned char *org = nullptr, *orgptr, flags = 0, numpats, version;
+ unsigned long alength;
+ unsigned short len[9], *secdata, *secptr;
+ const unsigned char convfx[16] =
+ { 0, 1, 2, 23, 24, 3, 5, 4, 6, 9, 17, 13, 11, 19, 7, 14 };
+ const unsigned char convinf1[16] =
+ { 0, 1, 2, 6, 7, 8, 9, 4, 5, 3, 10, 11, 12, 13, 14, 15 };
+ const unsigned char newconvfx[] =
+ { 0, 1, 2, 3, 4, 5, 6, 23, 24, 21, 10, 11, 17, 13, 7, 19,
+ 255, 255, 22, 25, 255, 15, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 14, 255
+ };
+
+ // read header
+ f->readString (id, 10);
+ f->readInt (4);
+ version = f->readInt (1);
+ numpats = f->readInt (1);
+
+ // file validation section
+ if (strncmp (id, "_A2module_", 10) || (version != 1 && version != 5 &&
+ version != 4 && version != 8))
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // load, depack & convert section
+ nop = numpats;
+ length = 128;
+ restartpos = 0;
+ if (version < 5)
+ {
+ for (i = 0; i < 5; i++)
+ len[i] = f->readInt (2);
+ t = 9;
+ }
+ else
+ { // version >= 5
+ for (i = 0; i < 9; i++)
+ len[i] = f->readInt (2);
+ t = 18;
+ }
+
+ // block 0
+ secdata = new unsigned short[len[0] / 2];
+ if (version == 1 || version == 5)
+ {
+ for (i = 0; i < len[0] / 2; i++)
+ secdata[i] = f->readInt (2);
+ org = new unsigned char[MAXBUF];
+ orgptr = org;
+ sixdepak (secdata, org, len[0]);
+ }
+ else
+ {
+ orgptr = (unsigned char *) secdata;
+ for (i = 0; i < len[0]; i++)
+ orgptr[i] = f->readInt (1);
+ }
+ memcpy (songname, orgptr, 43);
+ orgptr += 43;
+ memcpy (author, orgptr, 43);
+ orgptr += 43;
+ memcpy (instname, orgptr, 250 * 33);
+ orgptr += 250 * 33;
+
+ for (i = 0; i < 250; i++)
+ { // instruments
+ inst[i].data[0] = *(orgptr + i * 13 + 10);
+ inst[i].data[1] = *(orgptr + i * 13);
+ inst[i].data[2] = *(orgptr + i * 13 + 1);
+ inst[i].data[3] = *(orgptr + i * 13 + 4);
+ inst[i].data[4] = *(orgptr + i * 13 + 5);
+ inst[i].data[5] = *(orgptr + i * 13 + 6);
+ inst[i].data[6] = *(orgptr + i * 13 + 7);
+ inst[i].data[7] = *(orgptr + i * 13 + 8);
+ inst[i].data[8] = *(orgptr + i * 13 + 9);
+ inst[i].data[9] = *(orgptr + i * 13 + 2);
+ inst[i].data[10] = *(orgptr + i * 13 + 3);
+ if (version < 5)
+ inst[i].misc = *(orgptr + i * 13 + 11);
+ else
+ { // version >= 5 -> OPL3 format
+ int pan = *(orgptr + i * 13 + 11);
+
+ if (pan)
+ inst[i].data[0] |= (pan & 3) << 4; // set pan
+ else
+ inst[i].data[0] |= 48; // enable both speakers
+ }
+
+ inst[i].slide = *(orgptr + i * 13 + 12);
+ }
+
+ orgptr += 250 * 13;
+ memcpy (order, orgptr, 128);
+ orgptr += 128;
+ bpm = *orgptr;
+ orgptr++;
+ initspeed = *orgptr;
+ orgptr++;
+ if (version >= 5)
+ flags = *orgptr;
+ if (version == 1 || version == 5)
+ delete[]org;
+ delete[]secdata;
+
+ // blocks 1-4 or 1-8
+ alength = len[1];
+ for (i = 0; i < (version < 5 ? numpats / 16 : numpats / 8); i++)
+ alength += len[i + 2];
+
+ secdata = new unsigned short[alength / 2];
+ if (version == 1 || version == 5)
+ {
+ for (l = 0; l < alength / 2; l++)
+ secdata[l] = f->readInt (2);
+ org = new unsigned char[MAXBUF * (numpats / (version == 1 ? 16 : 8) + 1)];
+ orgptr = org;
+ secptr = secdata;
+ orgptr += sixdepak (secptr, orgptr, len[1]);
+ secptr += len[1] / 2;
+ if (version == 1)
+ {
+ if (numpats > 16)
+ orgptr += sixdepak (secptr, orgptr, len[2]);
+ secptr += len[2] / 2;
+ if (numpats > 32)
+ orgptr += sixdepak (secptr, orgptr, len[3]);
+ secptr += len[3] / 2;
+ if (numpats > 48)
+ sixdepak (secptr, orgptr, len[4]);
+ }
+ else
+ {
+ if (numpats > 8)
+ orgptr += sixdepak (secptr, orgptr, len[2]);
+ secptr += len[2] / 2;
+ if (numpats > 16)
+ orgptr += sixdepak (secptr, orgptr, len[3]);
+ secptr += len[3] / 2;
+ if (numpats > 24)
+ orgptr += sixdepak (secptr, orgptr, len[4]);
+ secptr += len[4] / 2;
+ if (numpats > 32)
+ orgptr += sixdepak (secptr, orgptr, len[5]);
+ secptr += len[5] / 2;
+ if (numpats > 40)
+ orgptr += sixdepak (secptr, orgptr, len[6]);
+ secptr += len[6] / 2;
+ if (numpats > 48)
+ orgptr += sixdepak (secptr, orgptr, len[7]);
+ secptr += len[7] / 2;
+ if (numpats > 56)
+ sixdepak (secptr, orgptr, len[8]);
+ }
+ delete[]secdata;
+ secdata = 0;
+ }
+ else
+ {
+ org = (unsigned char *) secdata;
+ for (l = 0; l < alength; l++)
+ org[l] = f->readInt (1);
+ }
+
+ if (version < 5)
+ {
+ for (i = 0; i < numpats; i++)
+ for (j = 0; j < 64; j++)
+ for (k = 0; k < 9; k++)
+ {
+ struct Tracks *track = &tracks[i * 9 + k][j];
+ unsigned char *o = &org[i * 64 * t * 4 + j * t * 4 + k * 4];
+
+ track->note = o[0] == 255 ? 127 : o[0];
+ track->inst = o[1];
+ track->command = convfx[o[2]];
+ track->param2 = o[3] & 0x0f;
+ if (track->command != 14)
+ track->param1 = o[3] >> 4;
+ else
+ {
+ track->param1 = convinf1[o[3] >> 4];
+ if (track->param1 == 15 && !track->param2)
+ { // convert key-off
+ track->command = 8;
+ track->param1 = 0;
+ track->param2 = 0;
+ }
+ }
+ if (track->command == 14)
+ {
+ switch (track->param1)
+ {
+ case 2: // convert define waveform
+ track->command = 25;
+ track->param1 = track->param2;
+ track->param2 = 0xf;
+ break;
+ case 8: // convert volume slide up
+ track->command = 26;
+ track->param1 = track->param2;
+ track->param2 = 0;
+ break;
+ case 9: // convert volume slide down
+ track->command = 26;
+ track->param1 = 0;
+ break;
+ }
+ }
+ }
+ }
+ else
+ { // version >= 5
+ realloc_patterns (64, 64, 18);
+
+ for (i = 0; i < numpats; i++)
+ for (j = 0; j < 18; j++)
+ for (k = 0; k < 64; k++)
+ {
+ struct Tracks *track = &tracks[i * 18 + j][k];
+ unsigned char *o = &org[i * 64 * t * 4 + j * 64 * 4 + k * 4];
+
+ track->note = o[0] == 255 ? 127 : o[0];
+ track->inst = o[1];
+ track->command = newconvfx[o[2]];
+ track->param1 = o[3] >> 4;
+ track->param2 = o[3] & 0x0f;
+
+ // Convert '&' command
+ if (o[2] == 36)
+ switch (track->param1)
+ {
+ case 0: // pattern delay (frames)
+ track->command = 29;
+ track->param1 = 0;
+ // param2 already set correctly
+ break;
+
+ case 1: // pattern delay (rows)
+ track->command = 14;
+ track->param1 = 8;
+ // param2 already set correctly
+ break;
+ }
+ }
+ }
+
+ init_trackord ();
+
+ if (version == 1 || version == 5)
+ {
+ delete[]org;
+ }
+ else
+ {
+ delete[]secdata;
+ }
+
+ // Process flags
+ if (version >= 5)
+ {
+ CmodPlayer::flags |= Opl3; // All versions >= 5 are OPL3
+ if (flags & 8)
+ CmodPlayer::flags |= Tremolo; // Tremolo depth
+ if (flags & 16)
+ CmodPlayer::flags |= Vibrato; // Vibrato depth
+ }
+
+ fp.close (f);
+ rewind (0);
+ return true;
+}
+
+float
+Ca2mLoader::getrefresh ()
+{
+ if (tempo != 18)
+ return (float) (tempo);
+ else
+ return 18.2f;
+}
+
+/*** private methods *************************************/
+
+void
+Ca2mLoader::inittree ()
+{
+ unsigned short i;
+
+ for (i = 2; i <= TWICEMAX; i++)
+ {
+ dad[i] = i / 2;
+ freq[i] = 1;
+ }
+
+ for (i = 1; i <= MAXCODE; i++)
+ {
+ leftc[i] = 2 * i;
+ rghtc[i] = 2 * i + 1;
+ }
+}
+
+void
+Ca2mLoader::updatefreq (unsigned short a, unsigned short b)
+{
+ do
+ {
+ freq[dad[a]] = freq[a] + freq[b];
+ a = dad[a];
+ if (a != ROOT)
+ {
+ if (leftc[dad[a]] == a)
+ b = rghtc[dad[a]];
+ else
+ b = leftc[dad[a]];
+ }
+ } while (a != ROOT);
+
+ if (freq[ROOT] == MAXFREQ)
+ for (a = 1; a <= TWICEMAX; a++)
+ freq[a] >>= 1;
+}
+
+void
+Ca2mLoader::updatemodel (unsigned short code)
+{
+ unsigned short a = code + SUCCMAX, b, c, code1, code2;
+
+ freq[a]++;
+ if (dad[a] != ROOT)
+ {
+ code1 = dad[a];
+ if (leftc[code1] == a)
+ updatefreq (a, rghtc[code1]);
+ else
+ updatefreq (a, leftc[code1]);
+
+ do
+ {
+ code2 = dad[code1];
+ if (leftc[code2] == code1)
+ b = rghtc[code2];
+ else
+ b = leftc[code2];
+
+ if (freq[a] > freq[b])
+ {
+ if (leftc[code2] == code1)
+ rghtc[code2] = a;
+ else
+ leftc[code2] = a;
+
+ if (leftc[code1] == a)
+ {
+ leftc[code1] = b;
+ c = rghtc[code1];
+ }
+ else
+ {
+ rghtc[code1] = b;
+ c = leftc[code1];
+ }
+
+ dad[b] = code1;
+ dad[a] = code2;
+ updatefreq (b, c);
+ a = b;
+ }
+
+ a = dad[a];
+ code1 = dad[a];
+ } while (code1 != ROOT);
+ }
+}
+
+unsigned short
+Ca2mLoader::inputcode (unsigned short bits)
+{
+ unsigned short i, code = 0;
+
+ for (i = 1; i <= bits; i++)
+ {
+ if (!ibitcount)
+ {
+ if (ibitcount == MAXBUF)
+ ibufcount = 0;
+ ibitbuffer = wdbuf[ibufcount];
+ ibufcount++;
+ ibitcount = 15;
+ }
+ else
+ ibitcount--;
+
+ if (ibitbuffer > 0x7fff)
+ code |= bitvalue[i - 1];
+ ibitbuffer <<= 1;
+ }
+
+ return code;
+}
+
+unsigned short
+Ca2mLoader::uncompress ()
+{
+ unsigned short a = 1;
+
+ do
+ {
+ if (!ibitcount)
+ {
+ if (ibufcount == MAXBUF)
+ ibufcount = 0;
+ ibitbuffer = wdbuf[ibufcount];
+ ibufcount++;
+ ibitcount = 15;
+ }
+ else
+ ibitcount--;
+
+ if (ibitbuffer > 0x7fff)
+ a = rghtc[a];
+ else
+ a = leftc[a];
+ ibitbuffer <<= 1;
+ } while (a <= MAXCODE);
+
+ a -= SUCCMAX;
+ updatemodel (a);
+ return a;
+}
+
+void
+Ca2mLoader::decode ()
+{
+ unsigned short i, j, k, t, c, count = 0, dist, len, index;
+
+ inittree ();
+ c = uncompress ();
+
+ while (c != TERMINATE)
+ {
+ if (c < 256)
+ {
+ obuf[obufcount] = (unsigned char) c;
+ obufcount++;
+ if (obufcount == MAXBUF)
+ {
+ output_size = MAXBUF;
+ obufcount = 0;
+ }
+
+ buf[count] = (unsigned char) c;
+ count++;
+ if (count == MAXSIZE)
+ count = 0;
+ }
+ else
+ {
+ t = c - FIRSTCODE;
+ index = t / CODESPERRANGE;
+ len = t + MINCOPY - index * CODESPERRANGE;
+ dist = inputcode (copybits[index]) + len + copymin[index];
+
+ j = count;
+ k = count - dist;
+ if (count < dist)
+ k += MAXSIZE;
+
+ for (i = 0; i <= len - 1; i++)
+ {
+ obuf[obufcount] = buf[k];
+ obufcount++;
+ if (obufcount == MAXBUF)
+ {
+ output_size = MAXBUF;
+ obufcount = 0;
+ }
+
+ buf[j] = buf[k];
+ j++;
+ k++;
+ if (j == MAXSIZE)
+ j = 0;
+ if (k == MAXSIZE)
+ k = 0;
+ }
+
+ count += len;
+ if (count >= MAXSIZE)
+ count -= MAXSIZE;
+ }
+ c = uncompress ();
+ }
+ output_size = obufcount;
+}
+
+unsigned short
+Ca2mLoader::sixdepak (unsigned short *source, unsigned char *dest,
+ unsigned short size)
+{
+ if ((unsigned int) size + 4096 > MAXBUF)
+ return 0;
+
+ buf = new unsigned char[MAXSIZE];
+ input_size = size;
+ ibitcount = 0;
+ ibitbuffer = 0;
+ obufcount = 0;
+ ibufcount = 0;
+ wdbuf = source;
+ obuf = dest;
+
+ decode ();
+ if (buf)
+ {
+ delete[]buf;
+ buf = 0;
+ }
+ return output_size;
+}
diff --git a/src/adplug/core/a2m.cxx b/src/adplug/core/a2m.cxx
deleted file mode 100644
index b1ce8cb3657b..000000000000
--- a/src/adplug/core/a2m.cxx
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * a2m.cpp - A2M Loader by Simon Peter <dn.tlp at gmx.net>
- *
- * NOTES:
- * This loader detects and loads version 1, 4, 5 & 8 files.
- *
- * version 1-4 files:
- * Following commands are ignored: FF1 - FF9, FAx - FEx
- *
- * version 5-8 files:
- * Instrument panning is ignored. Flags byte is ignored.
- * Following commands are ignored: Gxy, Hxy, Kxy - &xy
- */
-
-#include <string.h>
-
-#include "a2m.h"
-
-const unsigned int
- Ca2mLoader::MAXFREQ = 2000,
- Ca2mLoader::MINCOPY = ADPLUG_A2M_MINCOPY,
- Ca2mLoader::MAXCOPY = ADPLUG_A2M_MAXCOPY,
- Ca2mLoader::COPYRANGES = ADPLUG_A2M_COPYRANGES,
- Ca2mLoader::CODESPERRANGE = ADPLUG_A2M_CODESPERRANGE,
- Ca2mLoader::TERMINATE = 256,
- Ca2mLoader::FIRSTCODE = ADPLUG_A2M_FIRSTCODE,
- Ca2mLoader::MAXCODE = FIRSTCODE + COPYRANGES * CODESPERRANGE - 1,
- Ca2mLoader::SUCCMAX = MAXCODE + 1,
- Ca2mLoader::TWICEMAX = ADPLUG_A2M_TWICEMAX,
- Ca2mLoader::ROOT = 1, Ca2mLoader::MAXBUF = 42 * 1024,
- Ca2mLoader::MAXDISTANCE = 21389, Ca2mLoader::MAXSIZE = 21389 + MAXCOPY;
-
-const unsigned short
-Ca2mLoader::bitvalue[14] =
- { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
-
-const signed short
-Ca2mLoader::copybits[COPYRANGES] = { 4, 6, 8, 10, 12, 14 };
-
-const signed short
-Ca2mLoader::copymin[COPYRANGES] = { 0, 16, 80, 336, 1360, 5456 };
-
-CPlayer *
-Ca2mLoader::factory (Copl * newopl)
-{
- return new Ca2mLoader (newopl);
-}
-
-bool
-Ca2mLoader::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- char id[10];
- int i, j, k, t;
- unsigned int l;
- unsigned char *org = NULL, *orgptr, flags = 0, numpats, version;
- unsigned long alength;
- unsigned short len[9], *secdata, *secptr;
- const unsigned char convfx[16] =
- { 0, 1, 2, 23, 24, 3, 5, 4, 6, 9, 17, 13, 11, 19, 7, 14 };
- const unsigned char convinf1[16] =
- { 0, 1, 2, 6, 7, 8, 9, 4, 5, 3, 10, 11, 12, 13, 14, 15 };
- const unsigned char newconvfx[] =
- { 0, 1, 2, 3, 4, 5, 6, 23, 24, 21, 10, 11, 17, 13, 7, 19,
- 255, 255, 22, 25, 255, 15, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 14, 255
- };
-
- // read header
- f->readString (id, 10);
- f->readInt (4);
- version = f->readInt (1);
- numpats = f->readInt (1);
-
- // file validation section
- if (strncmp (id, "_A2module_", 10) || (version != 1 && version != 5 &&
- version != 4 && version != 8))
- {
- fp.close (f);
- return false;
- }
-
- // load, depack & convert section
- nop = numpats;
- length = 128;
- restartpos = 0;
- if (version < 5)
- {
- for (i = 0; i < 5; i++)
- len[i] = f->readInt (2);
- t = 9;
- }
- else
- { // version >= 5
- for (i = 0; i < 9; i++)
- len[i] = f->readInt (2);
- t = 18;
- }
-
- // block 0
- secdata = new unsigned short[len[0] / 2];
- if (version == 1 || version == 5)
- {
- for (i = 0; i < len[0] / 2; i++)
- secdata[i] = f->readInt (2);
- org = new unsigned char[MAXBUF];
- orgptr = org;
- sixdepak (secdata, org, len[0]);
- }
- else
- {
- orgptr = (unsigned char *) secdata;
- for (i = 0; i < len[0]; i++)
- orgptr[i] = f->readInt (1);
- }
- memcpy (songname, orgptr, 43);
- orgptr += 43;
- memcpy (author, orgptr, 43);
- orgptr += 43;
- memcpy (instname, orgptr, 250 * 33);
- orgptr += 250 * 33;
-
- for (i = 0; i < 250; i++)
- { // instruments
- inst[i].data[0] = *(orgptr + i * 13 + 10);
- inst[i].data[1] = *(orgptr + i * 13);
- inst[i].data[2] = *(orgptr + i * 13 + 1);
- inst[i].data[3] = *(orgptr + i * 13 + 4);
- inst[i].data[4] = *(orgptr + i * 13 + 5);
- inst[i].data[5] = *(orgptr + i * 13 + 6);
- inst[i].data[6] = *(orgptr + i * 13 + 7);
- inst[i].data[7] = *(orgptr + i * 13 + 8);
- inst[i].data[8] = *(orgptr + i * 13 + 9);
- inst[i].data[9] = *(orgptr + i * 13 + 2);
- inst[i].data[10] = *(orgptr + i * 13 + 3);
- if (version < 5)
- inst[i].misc = *(orgptr + i * 13 + 11);
- else
- { // version >= 5 -> OPL3 format
- int pan = *(orgptr + i * 13 + 11);
-
- if (pan)
- inst[i].data[0] |= (pan & 3) << 4; // set pan
- else
- inst[i].data[0] |= 48; // enable both speakers
- }
-
- inst[i].slide = *(orgptr + i * 13 + 12);
- }
-
- orgptr += 250 * 13;
- memcpy (order, orgptr, 128);
- orgptr += 128;
- bpm = *orgptr;
- orgptr++;
- initspeed = *orgptr;
- orgptr++;
- if (version >= 5)
- flags = *orgptr;
- if (version == 1 || version == 5)
- delete[]org;
- delete[]secdata;
-
- // blocks 1-4 or 1-8
- alength = len[1];
- for (i = 0; i < (version < 5 ? numpats / 16 : numpats / 8); i++)
- alength += len[i + 2];
-
- secdata = new unsigned short[alength / 2];
- if (version == 1 || version == 5)
- {
- for (l = 0; l < alength / 2; l++)
- secdata[l] = f->readInt (2);
- org = new unsigned char[MAXBUF * (numpats / (version == 1 ? 16 : 8) + 1)];
- orgptr = org;
- secptr = secdata;
- orgptr += sixdepak (secptr, orgptr, len[1]);
- secptr += len[1] / 2;
- if (version == 1)
- {
- if (numpats > 16)
- orgptr += sixdepak (secptr, orgptr, len[2]);
- secptr += len[2] / 2;
- if (numpats > 32)
- orgptr += sixdepak (secptr, orgptr, len[3]);
- secptr += len[3] / 2;
- if (numpats > 48)
- sixdepak (secptr, orgptr, len[4]);
- }
- else
- {
- if (numpats > 8)
- orgptr += sixdepak (secptr, orgptr, len[2]);
- secptr += len[2] / 2;
- if (numpats > 16)
- orgptr += sixdepak (secptr, orgptr, len[3]);
- secptr += len[3] / 2;
- if (numpats > 24)
- orgptr += sixdepak (secptr, orgptr, len[4]);
- secptr += len[4] / 2;
- if (numpats > 32)
- orgptr += sixdepak (secptr, orgptr, len[5]);
- secptr += len[5] / 2;
- if (numpats > 40)
- orgptr += sixdepak (secptr, orgptr, len[6]);
- secptr += len[6] / 2;
- if (numpats > 48)
- orgptr += sixdepak (secptr, orgptr, len[7]);
- secptr += len[7] / 2;
- if (numpats > 56)
- sixdepak (secptr, orgptr, len[8]);
- }
- delete[]secdata;
- secdata = 0;
- }
- else
- {
- org = (unsigned char *) secdata;
- for (l = 0; l < alength; l++)
- org[l] = f->readInt (1);
- }
-
- if (version < 5)
- {
- for (i = 0; i < numpats; i++)
- for (j = 0; j < 64; j++)
- for (k = 0; k < 9; k++)
- {
- struct Tracks *track = &tracks[i * 9 + k][j];
- unsigned char *o = &org[i * 64 * t * 4 + j * t * 4 + k * 4];
-
- track->note = o[0] == 255 ? 127 : o[0];
- track->inst = o[1];
- track->command = convfx[o[2]];
- track->param2 = o[3] & 0x0f;
- if (track->command != 14)
- track->param1 = o[3] >> 4;
- else
- {
- track->param1 = convinf1[o[3] >> 4];
- if (track->param1 == 15 && !track->param2)
- { // convert key-off
- track->command = 8;
- track->param1 = 0;
- track->param2 = 0;
- }
- }
- if (track->command == 14)
- {
- switch (track->param1)
- {
- case 2: // convert define waveform
- track->command = 25;
- track->param1 = track->param2;
- track->param2 = 0xf;
- break;
- case 8: // convert volume slide up
- track->command = 26;
- track->param1 = track->param2;
- track->param2 = 0;
- break;
- case 9: // convert volume slide down
- track->command = 26;
- track->param1 = 0;
- break;
- }
- }
- }
- }
- else
- { // version >= 5
- realloc_patterns (64, 64, 18);
-
- for (i = 0; i < numpats; i++)
- for (j = 0; j < 18; j++)
- for (k = 0; k < 64; k++)
- {
- struct Tracks *track = &tracks[i * 18 + j][k];
- unsigned char *o = &org[i * 64 * t * 4 + j * 64 * 4 + k * 4];
-
- track->note = o[0] == 255 ? 127 : o[0];
- track->inst = o[1];
- track->command = newconvfx[o[2]];
- track->param1 = o[3] >> 4;
- track->param2 = o[3] & 0x0f;
-
- // Convert '&' command
- if (o[2] == 36)
- switch (track->param1)
- {
- case 0: // pattern delay (frames)
- track->command = 29;
- track->param1 = 0;
- // param2 already set correctly
- break;
-
- case 1: // pattern delay (rows)
- track->command = 14;
- track->param1 = 8;
- // param2 already set correctly
- break;
- }
- }
- }
-
- init_trackord ();
-
- if (version == 1 || version == 5)
- {
- delete[]org;
- }
- else
- {
- delete[]secdata;
- }
-
- // Process flags
- if (version >= 5)
- {
- CmodPlayer::flags |= Opl3; // All versions >= 5 are OPL3
- if (flags & 8)
- CmodPlayer::flags |= Tremolo; // Tremolo depth
- if (flags & 16)
- CmodPlayer::flags |= Vibrato; // Vibrato depth
- }
-
- fp.close (f);
- rewind (0);
- return true;
-}
-
-float
-Ca2mLoader::getrefresh ()
-{
- if (tempo != 18)
- return (float) (tempo);
- else
- return 18.2f;
-}
-
-/*** private methods *************************************/
-
-void
-Ca2mLoader::inittree ()
-{
- unsigned short i;
-
- for (i = 2; i <= TWICEMAX; i++)
- {
- dad[i] = i / 2;
- freq[i] = 1;
- }
-
- for (i = 1; i <= MAXCODE; i++)
- {
- leftc[i] = 2 * i;
- rghtc[i] = 2 * i + 1;
- }
-}
-
-void
-Ca2mLoader::updatefreq (unsigned short a, unsigned short b)
-{
- do
- {
- freq[dad[a]] = freq[a] + freq[b];
- a = dad[a];
- if (a != ROOT)
- {
- if (leftc[dad[a]] == a)
- b = rghtc[dad[a]];
- else
- b = leftc[dad[a]];
- }
- } while (a != ROOT);
-
- if (freq[ROOT] == MAXFREQ)
- for (a = 1; a <= TWICEMAX; a++)
- freq[a] >>= 1;
-}
-
-void
-Ca2mLoader::updatemodel (unsigned short code)
-{
- unsigned short a = code + SUCCMAX, b, c, code1, code2;
-
- freq[a]++;
- if (dad[a] != ROOT)
- {
- code1 = dad[a];
- if (leftc[code1] == a)
- updatefreq (a, rghtc[code1]);
- else
- updatefreq (a, leftc[code1]);
-
- do
- {
- code2 = dad[code1];
- if (leftc[code2] == code1)
- b = rghtc[code2];
- else
- b = leftc[code2];
-
- if (freq[a] > freq[b])
- {
- if (leftc[code2] == code1)
- rghtc[code2] = a;
- else
- leftc[code2] = a;
-
- if (leftc[code1] == a)
- {
- leftc[code1] = b;
- c = rghtc[code1];
- }
- else
- {
- rghtc[code1] = b;
- c = leftc[code1];
- }
-
- dad[b] = code1;
- dad[a] = code2;
- updatefreq (b, c);
- a = b;
- }
-
- a = dad[a];
- code1 = dad[a];
- } while (code1 != ROOT);
- }
-}
-
-unsigned short
-Ca2mLoader::inputcode (unsigned short bits)
-{
- unsigned short i, code = 0;
-
- for (i = 1; i <= bits; i++)
- {
- if (!ibitcount)
- {
- if (ibitcount == MAXBUF)
- ibufcount = 0;
- ibitbuffer = wdbuf[ibufcount];
- ibufcount++;
- ibitcount = 15;
- }
- else
- ibitcount--;
-
- if (ibitbuffer > 0x7fff)
- code |= bitvalue[i - 1];
- ibitbuffer <<= 1;
- }
-
- return code;
-}
-
-unsigned short
-Ca2mLoader::uncompress ()
-{
- unsigned short a = 1;
-
- do
- {
- if (!ibitcount)
- {
- if (ibufcount == MAXBUF)
- ibufcount = 0;
- ibitbuffer = wdbuf[ibufcount];
- ibufcount++;
- ibitcount = 15;
- }
- else
- ibitcount--;
-
- if (ibitbuffer > 0x7fff)
- a = rghtc[a];
- else
- a = leftc[a];
- ibitbuffer <<= 1;
- } while (a <= MAXCODE);
-
- a -= SUCCMAX;
- updatemodel (a);
- return a;
-}
-
-void
-Ca2mLoader::decode ()
-{
- unsigned short i, j, k, t, c, count = 0, dist, len, index;
-
- inittree ();
- c = uncompress ();
-
- while (c != TERMINATE)
- {
- if (c < 256)
- {
- obuf[obufcount] = (unsigned char) c;
- obufcount++;
- if (obufcount == MAXBUF)
- {
- output_size = MAXBUF;
- obufcount = 0;
- }
-
- buf[count] = (unsigned char) c;
- count++;
- if (count == MAXSIZE)
- count = 0;
- }
- else
- {
- t = c - FIRSTCODE;
- index = t / CODESPERRANGE;
- len = t + MINCOPY - index * CODESPERRANGE;
- dist = inputcode (copybits[index]) + len + copymin[index];
-
- j = count;
- k = count - dist;
- if (count < dist)
- k += MAXSIZE;
-
- for (i = 0; i <= len - 1; i++)
- {
- obuf[obufcount] = buf[k];
- obufcount++;
- if (obufcount == MAXBUF)
- {
- output_size = MAXBUF;
- obufcount = 0;
- }
-
- buf[j] = buf[k];
- j++;
- k++;
- if (j == MAXSIZE)
- j = 0;
- if (k == MAXSIZE)
- k = 0;
- }
-
- count += len;
- if (count >= MAXSIZE)
- count -= MAXSIZE;
- }
- c = uncompress ();
- }
- output_size = obufcount;
-}
-
-unsigned short
-Ca2mLoader::sixdepak (unsigned short *source, unsigned char *dest,
- unsigned short size)
-{
- if ((unsigned int) size + 4096 > MAXBUF)
- return 0;
-
- buf = new unsigned char[MAXSIZE];
- input_size = size;
- ibitcount = 0;
- ibitbuffer = 0;
- obufcount = 0;
- ibufcount = 0;
- wdbuf = source;
- obuf = dest;
-
- decode ();
- if (buf)
- {
- delete[]buf;
- buf = 0;
- }
- return output_size;
-}
diff --git a/src/adplug/core/a2m.h b/src/adplug/core/a2m.h
index f1a20c736c3f..d55ae13074dc 100644
--- a/src/adplug/core/a2m.h
+++ b/src/adplug/core/a2m.h
@@ -33,7 +33,7 @@ public:
: CmodPlayer(newopl)
{ };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
float getrefresh();
std::string gettype()
@@ -82,4 +82,3 @@ private:
unsigned char *obuf, *buf;
};
#endif
-
diff --git a/src/adplug/core/adl.cc b/src/adplug/core/adl.cc
new file mode 100644
index 000000000000..281c3b18e0b6
--- /dev/null
+++ b/src/adplug/core/adl.cc
@@ -0,0 +1,2874 @@
+/*
+ * adl.cpp - ADL player adaption by Simon Peter <dn.tlp at gmx.net>
+ *
+ * Original ADL player by Torbjorn Andersson and Johannes Schickel
+ * 'lordhoto' <lordhoto at scummvm dot org> of the ScummVM project.
+ */
+
+/* ScummVM - Scumm Interpreter
+ *
+ * This file is licensed under both GPL and LGPL
+ * Copyright (C) 2006 The ScummVM project
+ * Copyright (C) 2006 Torbjorn Andersson and Johannes Schickel
+ *
+ * GPL License
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * LPGL License
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "adl.h"
+#include "debug.h"
+
+#ifdef ADL_DEBUG
+# define warning(...) AdPlug_LogWrite(__VA_ARGS__); \
+AdPlug_LogWrite("\n")
+
+# define debugC(i1, i2, ...) AdPlug_LogWrite(__VA_ARGS__); \
+AdPlug_LogWrite("\n")
+#else
+# define kDebugLevelSound 1
+
+static inline void
+warning (const char *str, ...)
+{
+}
+
+static inline void
+debugC (int i1, int i2, const char *str, ...)
+{
+}
+#endif
+
+// #define warning(...)
+// #define debugC(i1, i2, ...)
+
+#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
+
+// Basic Adlib Programming:
+// http://www.gamedev.net/reference/articles/article446.asp
+
+#define CALLBACKS_PER_SECOND 72
+
+typedef uint8_t uint8;
+typedef int8_t int8;
+typedef uint16_t uint16;
+typedef int16_t int16;
+typedef uint32_t uint32;
+typedef int32_t int32;
+typedef uint8_t byte;
+
+static inline uint16
+READ_LE_UINT16 (const void *ptr)
+{
+ const byte *b = (const byte *) ptr;
+ return (b[1] << 8) + b[0];
+}
+
+static inline uint16
+READ_BE_UINT16 (const void *ptr)
+{
+ const byte *b = (const byte *) ptr;
+ return (b[0] << 8) + b[1];
+}
+
+class AdlibDriver
+{
+public:
+ AdlibDriver (Copl * opl);
+ ~AdlibDriver ();
+
+ int callback (int opcode, ...);
+ void callback ();
+
+ // AudioStream API
+ // int readBuffer(int16 *buffer, const int numSamples) {
+ // int32 samplesLeft = numSamples;
+ // memset(buffer, 0, sizeof(int16) * numSamples);
+ // while (samplesLeft) {
+ // if (!_samplesTillCallback) {
+ // callback();
+ // _samplesTillCallback = _samplesPerCallback;
+ // _samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
+ // if (_samplesTillCallbackRemainder >= CALLBACKS_PER_SECOND) {
+ // _samplesTillCallback++;
+ // _samplesTillCallbackRemainder -= CALLBACKS_PER_SECOND;
+ // }
+ // }
+
+ // int32 render = MIN(samplesLeft, _samplesTillCallback);
+ // samplesLeft -= render;
+ // _samplesTillCallback -= render;
+ // YM3812UpdateOne(_adlib, buffer, render);
+ // buffer += render;
+ // }
+ // return numSamples;
+ // }
+
+ bool isStereo () const
+ {
+ return false;
+ }
+ bool endOfData () const
+ {
+ return false;
+ }
+ // int getRate() const { return _mixer->getOutputRate(); }
+
+ struct OpcodeEntry
+ {
+ typedef int (AdlibDriver::*DriverOpcode) (va_list & list);
+ DriverOpcode function;
+ const char *name;
+ };
+
+ void setupOpcodeList ();
+ const OpcodeEntry *_opcodeList;
+ int _opcodesEntries;
+
+ int snd_ret0x100 (va_list & list);
+ int snd_ret0x1983 (va_list & list);
+ int snd_initDriver (va_list & list);
+ int snd_deinitDriver (va_list & list);
+ int snd_setSoundData (va_list & list);
+ int snd_unkOpcode1 (va_list & list);
+ int snd_startSong (va_list & list);
+ int snd_unkOpcode2 (va_list & list);
+ int snd_unkOpcode3 (va_list & list);
+ int snd_readByte (va_list & list);
+ int snd_writeByte (va_list & list);
+ int snd_getSoundTrigger (va_list & list);
+ int snd_unkOpcode4 (va_list & list);
+ int snd_dummy (va_list & list);
+ int snd_getNullvar4 (va_list & list);
+ int snd_setNullvar3 (va_list & list);
+ int snd_setFlag (va_list & list);
+ int snd_clearFlag (va_list & list);
+
+ // These variables have not yet been named, but some of them are partly
+ // known nevertheless:
+ //
+ // unk16 - Sound-related. Possibly some sort of pitch bend.
+ // unk18 - Sound-effect. Used for secondaryEffect1()
+ // unk19 - Sound-effect. Used for secondaryEffect1()
+ // unk20 - Sound-effect. Used for secondaryEffect1()
+ // unk21 - Sound-effect. Used for secondaryEffect1()
+ // unk22 - Sound-effect. Used for secondaryEffect1()
+ // unk29 - Sound-effect. Used for primaryEffect1()
+ // unk30 - Sound-effect. Used for primaryEffect1()
+ // unk31 - Sound-effect. Used for primaryEffect1()
+ // unk32 - Sound-effect. Used for primaryEffect2()
+ // unk33 - Sound-effect. Used for primaryEffect2()
+ // unk34 - Sound-effect. Used for primaryEffect2()
+ // unk35 - Sound-effect. Used for primaryEffect2()
+ // unk36 - Sound-effect. Used for primaryEffect2()
+ // unk37 - Sound-effect. Used for primaryEffect2()
+ // unk38 - Sound-effect. Used for primaryEffect2()
+ // unk39 - Currently unused, except for updateCallback56()
+ // unk40 - Currently unused, except for updateCallback56()
+ // unk41 - Sound-effect. Used for primaryEffect2()
+
+ struct Channel
+ {
+ uint8 opExtraLevel2;
+ uint8 *dataptr;
+ uint8 duration;
+ uint8 repeatCounter;
+ int8 baseOctave;
+ uint8 priority;
+ uint8 dataptrStackPos;
+ uint8 *dataptrStack[4];
+ int8 baseNote;
+ uint8 unk29;
+ uint8 unk31;
+ uint16 unk30;
+ uint16 unk37;
+ uint8 unk33;
+ uint8 unk34;
+ uint8 unk35;
+ uint8 unk36;
+ uint8 unk32;
+ uint8 unk41;
+ uint8 unk38;
+ uint8 opExtraLevel1;
+ uint8 spacing2;
+ uint8 baseFreq;
+ uint8 tempo;
+ uint8 position;
+ uint8 regAx;
+ uint8 regBx;
+ typedef void (AdlibDriver::*Callback) (Channel &);
+ Callback primaryEffect;
+ Callback secondaryEffect;
+ uint8 fractionalSpacing;
+ uint8 opLevel1;
+ uint8 opLevel2;
+ uint8 opExtraLevel3;
+ uint8 twoChan;
+ uint8 unk39;
+ uint8 unk40;
+ uint8 spacing1;
+ uint8 durationRandomness;
+ uint8 unk19;
+ uint8 unk18;
+ int8 unk20;
+ int8 unk21;
+ uint8 unk22;
+ uint16 offset;
+ uint8 tempoReset;
+ uint8 rawNote;
+ int8 unk16;
+ };
+
+ void primaryEffect1 (Channel & channel);
+ void primaryEffect2 (Channel & channel);
+ void secondaryEffect1 (Channel & channel);
+
+ void resetAdlibState ();
+ void writeOPL (byte reg, byte val);
+ void initChannel (Channel & channel);
+ void noteOff (Channel & channel);
+ void unkOutput2 (uint8 num);
+
+ uint16 getRandomNr ();
+ void setupDuration (uint8 duration, Channel & channel);
+
+ void setupNote (uint8 rawNote, Channel & channel, bool flag = false);
+ void setupInstrument (uint8 regOffset, uint8 * dataptr, Channel & channel);
+ void noteOn (Channel & channel);
+
+ void adjustVolume (Channel & channel);
+
+ uint8 calculateOpLevel1 (Channel & channel);
+ uint8 calculateOpLevel2 (Channel & channel);
+
+ uint16 checkValue (int16 val)
+ {
+ if (val < 0)
+ val = 0;
+ else if (val > 0x3F)
+ val = 0x3F;
+ return val;
+ }
+
+ // The sound data has at least two lookup tables:
+ //
+ // * One for programs, starting at offset 0.
+ // * One for instruments, starting at offset 500.
+
+ uint8 *getProgram (int progId)
+ {
+ return _soundData + READ_LE_UINT16 (_soundData + 2 * progId);
+ }
+
+ uint8 *getInstrument (int instrumentId)
+ {
+ return _soundData + READ_LE_UINT16 (_soundData + 500 + 2 * instrumentId);
+ }
+
+ void setupPrograms ();
+ void executePrograms ();
+
+ struct ParserOpcode
+ {
+ typedef int (AdlibDriver::*POpcode) (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ POpcode function;
+ const char *name;
+ };
+
+ void setupParserOpcodeTable ();
+ const ParserOpcode *_parserOpcodeTable;
+ int _parserOpcodeTableSize;
+
+ int update_setRepeat (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_checkRepeat (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_setupProgram (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_setNoteSpacing (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_jump (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_jumpToSubroutine (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_returnFromSubroutine (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setBaseOctave (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_stopChannel (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_playRest (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_writeAdlib (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_setupNoteAndDuration (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setBaseNote (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_setupSecondaryEffect1 (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_stopOtherChannel (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_waitForEndOfProgram (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setupInstrument (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setupPrimaryEffect1 (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_removePrimaryEffect1 (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setBaseFreq (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_setupPrimaryEffect2 (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setPriority (uint8 * &dataptr, Channel & channel, uint8 value);
+ int updateCallback23 (uint8 * &dataptr, Channel & channel, uint8 value);
+ int updateCallback24 (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_setExtraLevel1 (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setupDuration (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_playNote (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_setFractionalNoteSpacing (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setTempo (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_removeSecondaryEffect1 (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setChannelTempo (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setExtraLevel3 (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setExtraLevel2 (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_changeExtraLevel2 (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setAMDepth (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_setVibratoDepth (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_changeExtraLevel1 (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int updateCallback38 (uint8 * &dataptr, Channel & channel, uint8 value);
+ int updateCallback39 (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_removePrimaryEffect2 (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int updateCallback41 (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_resetToGlobalTempo (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_nop1 (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_setDurationRandomness (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_changeChannelTempo (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int updateCallback46 (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_nop2 (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_setupRhythmSection (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_playRhythmSection (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_removeRhythmSection (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int updateCallback51 (uint8 * &dataptr, Channel & channel, uint8 value);
+ int updateCallback52 (uint8 * &dataptr, Channel & channel, uint8 value);
+ int updateCallback53 (uint8 * &dataptr, Channel & channel, uint8 value);
+ int update_setSoundTrigger (uint8 * &dataptr, Channel & channel,
+ uint8 value);
+ int update_setTempoReset (uint8 * &dataptr, Channel & channel, uint8 value);
+ int updateCallback56 (uint8 * &dataptr, Channel & channel, uint8 value);
+
+ // These variables have not yet been named, but some of them are partly
+ // known nevertheless:
+ //
+ // _unkValue1 - Unknown. Used for updating _unkValue2
+ // _unkValue2 - Unknown. Used for updating _unkValue4
+ // _unkValue3 - Unknown. Used for updating _unkValue2
+ // _unkValue4 - Unknown. Used for updating _unkValue5
+ // _unkValue5 - Unknown. Used for controlling updateCallback24().
+ // _unkValue6 - Unknown. Rhythm section volume?
+ // _unkValue7 - Unknown. Rhythm section volume?
+ // _unkValue8 - Unknown. Rhythm section volume?
+ // _unkValue9 - Unknown. Rhythm section volume?
+ // _unkValue10 - Unknown. Rhythm section volume?
+ // _unkValue11 - Unknown. Rhythm section volume?
+ // _unkValue12 - Unknown. Rhythm section volume?
+ // _unkValue13 - Unknown. Rhythm section volume?
+ // _unkValue14 - Unknown. Rhythm section volume?
+ // _unkValue15 - Unknown. Rhythm section volume?
+ // _unkValue16 - Unknown. Rhythm section volume?
+ // _unkValue17 - Unknown. Rhythm section volume?
+ // _unkValue18 - Unknown. Rhythm section volume?
+ // _unkValue19 - Unknown. Rhythm section volume?
+ // _unkValue20 - Unknown. Rhythm section volume?
+ // _unkTable[] - Probably frequences for the 12-tone scale.
+ // _unkTable2[] - Unknown. Currently only used by updateCallback46()
+ // _unkTable2_1[] - One of the tables in _unkTable2[]
+ // _unkTable2_2[] - One of the tables in _unkTable2[]
+ // _unkTable2_3[] - One of the tables in _unkTable2[]
+
+ int32 _samplesPerCallback;
+ int32 _samplesPerCallbackRemainder;
+ int32 _samplesTillCallback;
+ int32 _samplesTillCallbackRemainder;
+
+ int _lastProcessed;
+ int8 _flagTrigger;
+ int _curChannel;
+ uint8 _soundTrigger;
+ int _soundsPlaying;
+
+ uint16 _rnd;
+
+ uint8 _unkValue1;
+ uint8 _unkValue2;
+ uint8 _unkValue3;
+ uint8 _unkValue4;
+ uint8 _unkValue5;
+ uint8 _unkValue6;
+ uint8 _unkValue7;
+ uint8 _unkValue8;
+ uint8 _unkValue9;
+ uint8 _unkValue10;
+ uint8 _unkValue11;
+ uint8 _unkValue12;
+ uint8 _unkValue13;
+ uint8 _unkValue14;
+ uint8 _unkValue15;
+ uint8 _unkValue16;
+ uint8 _unkValue17;
+ uint8 _unkValue18;
+ uint8 _unkValue19;
+ uint8 _unkValue20;
+
+ int _flags;
+
+ uint8 *_soundData;
+
+ uint8 _soundIdTable[0x10];
+ Channel _channels[10];
+
+ uint8 _vibratoAndAMDepthBits;
+ uint8 _rhythmSectionBits;
+
+ uint8 _curRegOffset;
+ uint8 _tempo;
+
+ const uint8 *_tablePtr1;
+ const uint8 *_tablePtr2;
+
+ static const uint8 _regOffset[];
+ static const uint16 _unkTable[];
+ static const uint8 *_unkTable2[];
+ static const uint8 _unkTable2_1[];
+ static const uint8 _unkTable2_2[];
+ static const uint8 _unkTable2_3[];
+ static const uint8 _unkTables[][32];
+
+ Copl *opl;
+};
+
+AdlibDriver::AdlibDriver (Copl * newopl):opl (newopl)
+{
+ setupOpcodeList ();
+ setupParserOpcodeTable ();
+
+ // _mixer = mixer;
+
+ _flags = 0;
+ // _adlib = makeAdlibOPL(getRate());
+ // assert(_adlib);
+
+ memset (_channels, 0, sizeof (_channels));
+ _soundData = 0;
+
+ _vibratoAndAMDepthBits = _curRegOffset = 0;
+
+ _lastProcessed = _flagTrigger = _curChannel = _rhythmSectionBits = 0;
+ _soundsPlaying = 0;
+ _rnd = 0x1234;
+
+ _tempo = 0;
+ _soundTrigger = 0;
+
+ _unkValue3 = 0xFF;
+ _unkValue1 = _unkValue2 = _unkValue4 = _unkValue5 = 0;
+ _unkValue6 = _unkValue7 = _unkValue8 = _unkValue9 = _unkValue10 = 0;
+ _unkValue11 = _unkValue12 = _unkValue13 = _unkValue14 = _unkValue15 =
+ _unkValue16 = _unkValue17 = _unkValue18 = _unkValue19 = _unkValue20 = 0;
+
+ _tablePtr1 = _tablePtr2 = 0;
+
+ // _mixer->setupPremix(this);
+
+ // _samplesPerCallback = getRate() / CALLBACKS_PER_SECOND;
+ // _samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND;
+ _samplesTillCallback = 0;
+ _samplesTillCallbackRemainder = 0;
+}
+
+AdlibDriver::~AdlibDriver ()
+{
+ // _mixer->setupPremix(0);
+ // OPLDestroy(_adlib);
+ // _adlib = 0;
+}
+
+int
+AdlibDriver::callback (int opcode, ...)
+{
+ // lock();
+ if (opcode >= _opcodesEntries || opcode < 0)
+ {
+ warning ("AdlibDriver: calling unknown opcode '%d'", opcode);
+ return 0;
+ }
+
+ debugC (9, kDebugLevelSound, "Calling opcode '%s' (%d)",
+ _opcodeList[opcode].name, opcode);
+
+ va_list args;
+ va_start (args, opcode);
+ int returnValue = (this->*(_opcodeList[opcode].function)) (args);
+ va_end (args);
+ // unlock();
+ return returnValue;
+}
+
+// Opcodes
+
+int
+AdlibDriver::snd_ret0x100 (va_list & list)
+{
+ return 0x100;
+}
+
+int
+AdlibDriver::snd_ret0x1983 (va_list & list)
+{
+ return 0x1983;
+}
+
+int
+AdlibDriver::snd_initDriver (va_list & list)
+{
+ _lastProcessed = _soundsPlaying = 0;
+ resetAdlibState ();
+ return 0;
+}
+
+int
+AdlibDriver::snd_deinitDriver (va_list & list)
+{
+ resetAdlibState ();
+ return 0;
+}
+
+int
+AdlibDriver::snd_setSoundData (va_list & list)
+{
+ if (_soundData)
+ {
+ delete[]_soundData;
+ _soundData = 0;
+ }
+ _soundData = va_arg (list, uint8 *);
+ return 0;
+}
+
+int
+AdlibDriver::snd_unkOpcode1 (va_list & list)
+{
+ warning ("unimplemented snd_unkOpcode1");
+ return 0;
+}
+
+int
+AdlibDriver::snd_startSong (va_list & list)
+{
+ int songId = va_arg (list, int);
+ _flags |= 8;
+ _flagTrigger = 1;
+
+ uint8 *ptr = getProgram (songId);
+ uint8 chan = *ptr;
+
+ if ((songId << 1) != 0)
+ {
+ if (chan == 9)
+ {
+ if (_flags & 2)
+ return 0;
+ }
+ else
+ {
+ if (_flags & 1)
+ return 0;
+ }
+ }
+
+ _soundIdTable[_soundsPlaying++] = songId;
+ _soundsPlaying &= 0x0F;
+
+ return 0;
+}
+
+int
+AdlibDriver::snd_unkOpcode2 (va_list & list)
+{
+ warning ("unimplemented snd_unkOpcode2");
+ return 0;
+}
+
+int
+AdlibDriver::snd_unkOpcode3 (va_list & list)
+{
+ int value = va_arg (list, int);
+ int loop = value;
+ if (value < 0)
+ {
+ value = 0;
+ loop = 9;
+ }
+ loop -= value;
+ ++loop;
+
+ while (loop--)
+ {
+ _curChannel = value;
+ Channel & channel = _channels[_curChannel];
+ channel.priority = 0;
+ channel.dataptr = 0;
+ if (value != 9)
+ {
+ noteOff (channel);
+ }
+ ++value;
+ }
+
+ return 0;
+}
+
+int
+AdlibDriver::snd_readByte (va_list & list)
+{
+ int a = va_arg (list, int);
+ int b = va_arg (list, int);
+ uint8 *ptr = getProgram (a) + b;
+ return *ptr;
+}
+
+int
+AdlibDriver::snd_writeByte (va_list & list)
+{
+ int a = va_arg (list, int);
+ int b = va_arg (list, int);
+ int c = va_arg (list, int);
+ uint8 *ptr = getProgram (a) + b;
+ uint8 oldValue = *ptr;
+ *ptr = (uint8) c;
+ return oldValue;
+}
+
+int
+AdlibDriver::snd_getSoundTrigger (va_list & list)
+{
+ return _soundTrigger;
+}
+
+int
+AdlibDriver::snd_unkOpcode4 (va_list & list)
+{
+ warning ("unimplemented snd_unkOpcode4");
+ return 0;
+}
+
+int
+AdlibDriver::snd_dummy (va_list & list)
+{
+ return 0;
+}
+
+int
+AdlibDriver::snd_getNullvar4 (va_list & list)
+{
+ warning ("unimplemented snd_getNullvar4");
+ return 0;
+}
+
+int
+AdlibDriver::snd_setNullvar3 (va_list & list)
+{
+ warning ("unimplemented snd_setNullvar3");
+ return 0;
+}
+
+int
+AdlibDriver::snd_setFlag (va_list & list)
+{
+ int oldFlags = _flags;
+ _flags |= va_arg (list, int);
+ return oldFlags;
+}
+
+int
+AdlibDriver::snd_clearFlag (va_list & list)
+{
+ int oldFlags = _flags;
+ _flags &= ~(va_arg (list, int));
+ return oldFlags;
+}
+
+// timer callback
+
+void
+AdlibDriver::callback ()
+{
+ // lock();
+ --_flagTrigger;
+ if (_flagTrigger < 0)
+ _flags &= ~8;
+ setupPrograms ();
+ executePrograms ();
+
+ uint8 temp = _unkValue3;
+ _unkValue3 += _tempo;
+ if (_unkValue3 < temp)
+ {
+ if (!(--_unkValue2))
+ {
+ _unkValue2 = _unkValue1;
+ ++_unkValue4;
+ }
+ }
+ // unlock();
+}
+
+void
+AdlibDriver::setupPrograms ()
+{
+ while (_lastProcessed != _soundsPlaying)
+ {
+ uint8 *ptr = getProgram (_soundIdTable[_lastProcessed]);
+ uint8 chan = *ptr++;
+ uint8 priority = *ptr++;
+
+ // Only start this sound if its priority is higher than the one
+ // already playing.
+
+ Channel & channel = _channels[chan];
+
+ if (priority >= channel.priority)
+ {
+ initChannel (channel);
+ channel.priority = priority;
+ channel.dataptr = ptr;
+ channel.tempo = 0xFF;
+ channel.position = 0xFF;
+ channel.duration = 1;
+ unkOutput2 (chan);
+ }
+
+ ++_lastProcessed;
+ _lastProcessed &= 0x0F;
+ }
+}
+
+// A few words on opcode parsing and timing:
+//
+// First of all, We simulate a timer callback 72 times per second. Each timeout
+// we update each channel that has something to play.
+//
+// Each channel has its own individual tempo, which is added to its position.
+// This will frequently cause the position to "wrap around" but that is
+// intentional. In fact, it's the signal to go ahead and do more stuff with
+// that channel.
+//
+// Each channel also has a duration, indicating how much time is left on the
+// its current task. This duration is decreased by one. As long as it still has
+// not reached zero, the only thing that can happen is that the note is turned
+// off depending on manual or automatic note spacing. Once the duration reaches
+// zero, a new set of musical opcodes are executed.
+//
+// An opcode is one byte, followed by a variable number of parameters. Since
+// most opcodes have at least one one-byte parameter, we read that as well. Any
+// opcode that doesn't have that one parameter is responsible for moving the
+// data pointer back again.
+//
+// If the most significant bit of the opcode is 1, it's a function; call it.
+// The opcode functions return either 0 (continue), 1 (stop) or 2 (stop, and do
+// not run the effects callbacks).
+//
+// If the most significant bit of the opcode is 0, it's a note, and the first
+// parameter is its duration. (There are cases where the duration is modified
+// but that's an exception.) The note opcode is assumed to return 1, and is the
+// last opcode unless its duration is zero.
+//
+// Finally, most of the times that the callback is called, it will invoke the
+// effects callbacks. The final opcode in a set can prevent this, if it's a
+// function and it returns anything other than 1.
+
+void
+AdlibDriver::executePrograms ()
+{
+ // Each channel runs its own program. There are ten channels: One for
+ // each Adlib channel (0-8), plus one "control channel" (9) which is
+ // the one that tells the other channels what to do.
+
+ for (_curChannel = 9; _curChannel >= 0; --_curChannel)
+ {
+ int result = 1;
+
+ if (!_channels[_curChannel].dataptr)
+ {
+ continue;
+ }
+
+ Channel & channel = _channels[_curChannel];
+ _curRegOffset = _regOffset[_curChannel];
+
+ if (channel.tempoReset)
+ {
+ channel.tempo = _tempo;
+ }
+
+ uint8 backup = channel.position;
+ channel.position += channel.tempo;
+ if (channel.position < backup)
+ {
+ if (--channel.duration)
+ {
+ if (channel.duration == channel.spacing2)
+ noteOff (channel);
+ if (channel.duration == channel.spacing1 && _curChannel != 9)
+ noteOff (channel);
+ }
+ else
+ {
+ // An opcode is not allowed to modify its own
+ // data pointer except through the 'dataptr'
+ // parameter. To enforce that, we have to work
+ // on a copy of the data pointer.
+ //
+ // This fixes a subtle music bug where the
+ // wrong music would play when getting the
+ // quill in Kyra 1.
+ uint8 *dataptr = channel.dataptr;
+ while (dataptr)
+ {
+ uint8 opcode = *dataptr++;
+ uint8 param = *dataptr++;
+
+ if (opcode & 0x80)
+ {
+ opcode &= 0x7F;
+ if (opcode >= _parserOpcodeTableSize)
+ opcode = _parserOpcodeTableSize - 1;
+ debugC (9, kDebugLevelSound,
+ "Calling opcode '%s' (%d) (channel: %d)",
+ _parserOpcodeTable[opcode].name, opcode, _curChannel);
+ result =
+ (this->*(_parserOpcodeTable[opcode].function)) (dataptr,
+ channel, param);
+ channel.dataptr = dataptr;
+ if (result)
+ break;
+ }
+ else
+ {
+ debugC (9, kDebugLevelSound,
+ "Note on opcode 0x%02X (duration: %d) (channel: %d)",
+ opcode, param, _curChannel);
+ setupNote (opcode, channel);
+ noteOn (channel);
+ setupDuration (param, channel);
+ if (param)
+ {
+ channel.dataptr = dataptr;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (result == 1)
+ {
+ if (channel.primaryEffect)
+ (this->*(channel.primaryEffect)) (channel);
+ if (channel.secondaryEffect)
+ (this->*(channel.secondaryEffect)) (channel);
+ }
+ }
+}
+
+//
+
+void
+AdlibDriver::resetAdlibState ()
+{
+ debugC (9, kDebugLevelSound, "resetAdlibState()");
+ _rnd = 0x1234;
+
+ // Authorize the control of the waveforms
+ writeOPL (0x01, 0x20);
+
+ // Select FM music mode
+ writeOPL (0x08, 0x00);
+
+ // I would guess the main purpose of this is to turn off the rhythm,
+ // thus allowing us to use 9 melodic voices instead of 6.
+ writeOPL (0xBD, 0x00);
+
+ int loop = 10;
+ while (loop--)
+ {
+ if (loop != 9)
+ {
+ // Silence the channel
+ writeOPL (0x40 + _regOffset[loop], 0x3F);
+ writeOPL (0x43 + _regOffset[loop], 0x3F);
+ }
+ initChannel (_channels[loop]);
+ }
+}
+
+// Old calling style: output0x388(0xABCD)
+// New calling style: writeOPL(0xAB, 0xCD)
+
+void
+AdlibDriver::writeOPL (byte reg, byte val)
+{
+ opl->write (reg, val);
+}
+
+void
+AdlibDriver::initChannel (Channel & channel)
+{
+ debugC (9, kDebugLevelSound, "initChannel(%lu)",
+ (long) (&channel - _channels));
+ memset (&channel.dataptr, 0,
+ sizeof (Channel) - ((char *) &channel.dataptr - (char *) &channel));
+
+ channel.tempo = 0xFF;
+ channel.priority = 0;
+ // normally here are nullfuncs but we set 0 for now
+ channel.primaryEffect = 0;
+ channel.secondaryEffect = 0;
+ channel.spacing1 = 1;
+}
+
+void
+AdlibDriver::noteOff (Channel & channel)
+{
+ debugC (9, kDebugLevelSound, "noteOff(%lu)", (long) (&channel - _channels));
+
+ // The control channel has no corresponding Adlib channel
+
+ if (_curChannel >= 9)
+ return;
+
+ // When the rhythm section is enabled, channels 6, 7 and 8 are special.
+
+ if (_rhythmSectionBits && _curChannel >= 6)
+ return;
+
+ // This means the "Key On" bit will always be 0
+ channel.regBx &= 0xDF;
+
+ // Octave / F-Number / Key-On
+ writeOPL (0xB0 + _curChannel, channel.regBx);
+}
+
+void
+AdlibDriver::unkOutput2 (uint8 chan)
+{
+ debugC (9, kDebugLevelSound, "unkOutput2(%d)", chan);
+
+ // The control channel has no corresponding Adlib channel
+
+ if (chan >= 9)
+ return;
+
+ // I believe this has to do with channels 6, 7, and 8 being special
+ // when Adlib's rhythm section is enabled.
+
+ if (_rhythmSectionBits && chan >= 6)
+ return;
+
+ uint8 offset = _regOffset[chan];
+
+ // The channel is cleared: First the attack/delay rate, then the
+ // sustain level/release rate, and finally the note is turned off.
+
+ writeOPL (0x60 + offset, 0xFF);
+ writeOPL (0x63 + offset, 0xFF);
+
+ writeOPL (0x80 + offset, 0xFF);
+ writeOPL (0x83 + offset, 0xFF);
+
+ writeOPL (0xB0 + chan, 0x00);
+
+ // ...and then the note is turned on again, with whatever value is
+ // still lurking in the A0 + chan register, but everything else -
+ // including the two most significant frequency bit, and the octave -
+ // set to zero.
+ //
+ // This is very strange behaviour, and causes problems with the ancient
+ // FMOPL code we borrowed from AdPlug. I've added a workaround. See
+ // fmopl.cpp for more details.
+ //
+ // More recent versions of the MAME FMOPL don't seem to have this
+ // problem, but cannot currently be used because of licensing and
+ // performance issues.
+ //
+ // Ken Silverman's Adlib emulator (which can be found on his Web page -
+ // http://www.advsys.net/ken - and as part of AdPlug) also seems to be
+ // immune, but is apparently not as feature complete as MAME's.
+
+ writeOPL (0xB0 + chan, 0x20);
+}
+
+// I believe this is a random number generator. It actually does seem to
+// generate an even distribution of almost all numbers from 0 through 65535,
+// though in my tests some numbers were never generated.
+
+uint16
+AdlibDriver::getRandomNr ()
+{
+ _rnd += 0x9248;
+ uint16 lowBits = _rnd & 7;
+ _rnd >>= 3;
+ _rnd |= (lowBits << 13);
+ return _rnd;
+}
+
+void
+AdlibDriver::setupDuration (uint8 duration, Channel & channel)
+{
+ debugC (9, kDebugLevelSound, "setupDuration(%d, %lu)", duration,
+ (long) (&channel - _channels));
+ if (channel.durationRandomness)
+ {
+ channel.duration =
+ duration + (getRandomNr () & channel.durationRandomness);
+ return;
+ }
+ if (channel.fractionalSpacing)
+ {
+ channel.spacing2 = (duration >> 3) * channel.fractionalSpacing;
+ }
+ channel.duration = duration;
+}
+
+// This function may or may not play the note. It's usually followed by a call
+// to noteOn(), which will always play the current note.
+
+void
+AdlibDriver::setupNote (uint8 rawNote, Channel & channel, bool flag)
+{
+ debugC (9, kDebugLevelSound, "setupNote(%d, %lu)", rawNote,
+ (long) (&channel - _channels));
+
+ channel.rawNote = rawNote;
+
+ int8 note = (rawNote & 0x0F) + channel.baseNote;
+ int8 octave = ((rawNote + channel.baseOctave) >> 4) & 0x0F;
+
+ // There are only twelve notes. If we go outside that, we have to
+ // adjust the note and octave.
+
+ if (note >= 12)
+ {
+ note -= 12;
+ octave++;
+ }
+ else if (note < 0)
+ {
+ note += 12;
+ octave--;
+ }
+
+ // The calculation of frequency looks quite different from the original
+ // disassembly at a first glance, but when you consider that the
+ // largest possible value would be 0x0246 + 0xFF + 0x47 (and that's if
+ // baseFreq is unsigned), freq is still a 10-bit value, just as it
+ // should be to fit in the Ax and Bx registers.
+ //
+ // If it were larger than that, it could have overflowed into the
+ // octave bits, and that could possibly have been used in some sound.
+ // But as it is now, I can't see any way it would happen.
+
+ uint16 freq = _unkTable[note] + channel.baseFreq;
+
+ // When called from callback 41, the behaviour is slightly different:
+ // We adjust the frequency, even when channel.unk16 is 0.
+
+ if (channel.unk16 || flag)
+ {
+ const uint8 *table;
+
+ if (channel.unk16 >= 0)
+ {
+ table = _unkTables[(channel.rawNote & 0x0F) + 2];
+ freq += table[channel.unk16];
+ }
+ else
+ {
+ table = _unkTables[channel.rawNote & 0x0F];
+ freq -= table[-channel.unk16];
+ }
+ }
+
+ channel.regAx = freq & 0xFF;
+ channel.regBx =
+ (channel.regBx & 0x20) | (octave << 2) | ((freq >> 8) & 0x03);
+
+ // Keep the note on or off
+ writeOPL (0xA0 + _curChannel, channel.regAx);
+ writeOPL (0xB0 + _curChannel, channel.regBx);
+}
+
+void
+AdlibDriver::setupInstrument (uint8 regOffset, uint8 * dataptr,
+ Channel & channel)
+{
+ debugC (9, kDebugLevelSound, "setupInstrument(%d, %p, %lu)", regOffset,
+ (const void *) dataptr, (long) (&channel - _channels));
+ // Amplitude Modulation / Vibrato / Envelope Generator Type /
+ // Keyboard Scaling Rate / Modulator Frequency Multiple
+ writeOPL (0x20 + regOffset, *dataptr++);
+ writeOPL (0x23 + regOffset, *dataptr++);
+
+ uint8 temp = *dataptr++;
+
+ // Feedback / Algorithm
+
+ // It is very likely that _curChannel really does refer to the same
+ // channel as regOffset, but there's only one Cx register per channel.
+
+ writeOPL (0xC0 + _curChannel, temp);
+
+ // The algorithm bit. I don't pretend to understand this fully, but
+ // "If set to 0, operator 1 modulates operator 2. In this case,
+ // operator 2 is the only one producing sound. If set to 1, both
+ // operators produce sound directly. Complex sounds are more easily
+ // created if the algorithm is set to 0."
+
+ channel.twoChan = temp & 1;
+
+ // Waveform Select
+ writeOPL (0xE0 + regOffset, *dataptr++);
+ writeOPL (0xE3 + regOffset, *dataptr++);
+
+ channel.opLevel1 = *dataptr++;
+ channel.opLevel2 = *dataptr++;
+
+ // Level Key Scaling / Total Level
+ writeOPL (0x40 + regOffset, calculateOpLevel1 (channel));
+ writeOPL (0x43 + regOffset, calculateOpLevel2 (channel));
+
+ // Attack Rate / Decay Rate
+ writeOPL (0x60 + regOffset, *dataptr++);
+ writeOPL (0x63 + regOffset, *dataptr++);
+
+ // Sustain Level / Release Rate
+ writeOPL (0x80 + regOffset, *dataptr++);
+ writeOPL (0x83 + regOffset, *dataptr++);
+}
+
+// Apart from playing the note, this function also updates the variables for
+// primary effect 2.
+
+void
+AdlibDriver::noteOn (Channel & channel)
+{
+ debugC (9, kDebugLevelSound, "noteOn(%lu)", (long) (&channel - _channels));
+
+ // The "note on" bit is set, and the current note is played.
+
+ channel.regBx |= 0x20;
+ writeOPL (0xB0 + _curChannel, channel.regBx);
+
+ int8 shift = 9 - channel.unk33;
+ uint16 temp = channel.regAx | (channel.regBx << 8);
+ channel.unk37 = ((temp & 0x3FF) >> shift) & 0xFF;
+ channel.unk38 = channel.unk36;
+}
+
+void
+AdlibDriver::adjustVolume (Channel & channel)
+{
+ debugC (9, kDebugLevelSound, "adjustVolume(%lu)",
+ (long) (&channel - _channels));
+ // Level Key Scaling / Total Level
+
+ writeOPL (0x43 + _regOffset[_curChannel], calculateOpLevel2 (channel));
+ if (channel.twoChan)
+ writeOPL (0x40 + _regOffset[_curChannel], calculateOpLevel1 (channel));
+}
+
+// This is presumably only used for some sound effects, e.g. Malcolm blowing up
+// the trees in the intro (but not the effect where he "booby-traps" the big
+// tree) and turning Kallak to stone. Related functions and variables:
+//
+// update_setupPrimaryEffect1()
+// - Initialises unk29, unk30 and unk31
+// - unk29 is not further modified
+// - unk30 is not further modified, except by update_removePrimaryEffect1()
+//
+// update_removePrimaryEffect1()
+// - Deinitialises unk30
+//
+// unk29 - determines how often the notes are played
+// unk30 - modifies the frequency
+// unk31 - determines how often the notes are played
+
+void
+AdlibDriver::primaryEffect1 (Channel & channel)
+{
+ debugC (9, kDebugLevelSound, "Calling primaryEffect1 (channel: %d)",
+ _curChannel);
+ uint8 temp = channel.unk31;
+ channel.unk31 += channel.unk29;
+ if (channel.unk31 >= temp)
+ return;
+
+ // Initialise unk1 to the current frequency
+ uint16 unk1 = ((channel.regBx & 3) << 8) | channel.regAx;
+
+ // This is presumably to shift the "note on" bit so far to the left
+ // that it won't be affected by any of the calculations below.
+ uint16 unk2 = ((channel.regBx & 0x20) << 8) | (channel.regBx & 0x1C);
+
+ int16 unk3 = (int16) channel.unk30;
+
+ if (unk3 >= 0)
+ {
+ unk1 += unk3;
+ if (unk1 >= 734)
+ {
+ // The new frequency is too high. Shift it down and go
+ // up one octave.
+ unk1 >>= 1;
+ if (!(unk1 & 0x3FF))
+ ++unk1;
+ unk2 = (unk2 & 0xFF00) | ((unk2 + 4) & 0xFF);
+ unk2 &= 0xFF1C;
+ }
+ }
+ else
+ {
+ unk1 += unk3;
+ if (unk1 < 388)
+ {
+ // The new frequency is too low. Shift it up and go
+ // down one octave.
+ unk1 <<= 1;
+ if (!(unk1 & 0x3FF))
+ --unk1;
+ unk2 = (unk2 & 0xFF00) | ((unk2 - 4) & 0xFF);
+ unk2 &= 0xFF1C;
+ }
+ }
+
+ // Make sure that the new frequency is still a 10-bit value.
+ unk1 &= 0x3FF;
+
+ writeOPL (0xA0 + _curChannel, unk1 & 0xFF);
+ channel.regAx = unk1 & 0xFF;
+
+ // Shift down the "note on" bit again.
+ uint8 value = unk1 >> 8;
+ value |= (unk2 >> 8) & 0xFF;
+ value |= unk2 & 0xFF;
+
+ writeOPL (0xB0 + _curChannel, value);
+ channel.regBx = value;
+}
+
+// This is presumably only used for some sound effects, e.g. Malcolm entering
+// and leaving Kallak's hut. Related functions and variables:
+//
+// update_setupPrimaryEffect2()
+// - Initialises unk32, unk33, unk34, unk35 and unk36
+// - unk32 is not further modified
+// - unk33 is not further modified
+// - unk34 is a countdown that gets reinitialised to unk35 on zero
+// - unk35 is based on unk34 and not further modified
+// - unk36 is not further modified
+//
+// noteOn()
+// - Plays the current note
+// - Updates unk37 with a new (lower?) frequency
+// - Copies unk36 to unk38. The unk38 variable is a countdown.
+//
+// unk32 - determines how often the notes are played
+// unk33 - modifies the frequency
+// unk34 - countdown, updates frequency on zero
+// unk35 - initialiser for unk34 countdown
+// unk36 - initialiser for unk38 countdown
+// unk37 - frequency
+// unk38 - countdown, begins playing on zero
+// unk41 - determines how often the notes are played
+//
+// Note that unk41 is never initialised. Not that it should matter much, but it
+// is a bit sloppy.
+
+void
+AdlibDriver::primaryEffect2 (Channel & channel)
+{
+ debugC (9, kDebugLevelSound, "Calling primaryEffect2 (channel: %d)",
+ _curChannel);
+ if (channel.unk38)
+ {
+ --channel.unk38;
+ return;
+ }
+
+ uint8 temp = channel.unk41;
+ channel.unk41 += channel.unk32;
+ if (channel.unk41 < temp)
+ {
+ uint16 unk1 = channel.unk37;
+ if (!(--channel.unk34))
+ {
+ unk1 ^= 0xFFFF;
+ ++unk1;
+ channel.unk37 = unk1;
+ channel.unk34 = channel.unk35;
+ }
+
+ uint16 unk2 = (channel.regAx | (channel.regBx << 8)) & 0x3FF;
+ unk2 += unk1;
+
+ channel.regAx = unk2 & 0xFF;
+ channel.regBx = (channel.regBx & 0xFC) | (unk2 >> 8);
+
+ // Octave / F-Number / Key-On
+ writeOPL (0xA0 + _curChannel, channel.regAx);
+ writeOPL (0xB0 + _curChannel, channel.regBx);
+ }
+}
+
+// I don't know where this is used. The same operation is performed several
+// times on the current channel, using a chunk of the _soundData[] buffer for
+// parameters. The parameters are used starting at the end of the chunk.
+//
+// Since we use _curRegOffset to specify the final register, it's quite
+// unlikely that this function is ever used to play notes. It's probably only
+// used to modify the sound. Another thing that supports this idea is that it
+// can be combined with any of the effects callbacks above.
+//
+// Related functions and variables:
+//
+// update_setupSecondaryEffect1()
+// - Initialies unk18, unk19, unk20, unk21, unk22 and offset
+// - unk19 is not further modified
+// - unk20 is not further modified
+// - unk22 is not further modified
+// - offset is not further modified
+//
+// unk18 - determines how often the operation is performed
+// unk19 - determines how often the operation is performed
+// unk20 - the start index into the data chunk
+// unk21 - the current index into the data chunk
+// unk22 - the operation to perform
+// offset - the offset to the data chunk
+
+void
+AdlibDriver::secondaryEffect1 (Channel & channel)
+{
+ debugC (9, kDebugLevelSound, "Calling secondaryEffect1 (channel: %d)",
+ _curChannel);
+ uint8 temp = channel.unk18;
+ channel.unk18 += channel.unk19;
+ if (channel.unk18 < temp)
+ {
+ if (--channel.unk21 < 0)
+ {
+ channel.unk21 = channel.unk20;
+ }
+ writeOPL (channel.unk22 + _curRegOffset,
+ _soundData[channel.offset + channel.unk21]);
+ }
+}
+
+uint8
+AdlibDriver::calculateOpLevel1 (Channel & channel)
+{
+ int8 value = channel.opLevel1 & 0x3F;
+
+ if (channel.twoChan)
+ {
+ value += channel.opExtraLevel1;
+ value += channel.opExtraLevel2;
+ value += channel.opExtraLevel3;
+ }
+
+ // Preserve the scaling level bits from opLevel1
+
+ return checkValue (value) | (channel.opLevel1 & 0xC0);
+}
+
+uint8
+AdlibDriver::calculateOpLevel2 (Channel & channel)
+{
+ int8 value = channel.opLevel2 & 0x3F;
+
+ value += channel.opExtraLevel1;
+ value += channel.opExtraLevel2;
+ value += channel.opExtraLevel3;
+
+ // Preserve the scaling level bits from opLevel2
+
+ return checkValue (value) | (channel.opLevel2 & 0xC0);
+}
+
+// parser opcodes
+
+int
+AdlibDriver::update_setRepeat (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.repeatCounter = value;
+ return 0;
+}
+
+int
+AdlibDriver::update_checkRepeat (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ ++dataptr;
+ if (--channel.repeatCounter)
+ {
+ int16 add = READ_LE_UINT16 (dataptr - 2);
+ dataptr += add;
+ }
+ return 0;
+}
+
+int
+AdlibDriver::update_setupProgram (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ if (value == 0xFF)
+ return 0;
+
+ uint8 *ptr = getProgram (value);
+ uint8 chan = *ptr++;
+ uint8 priority = *ptr++;
+
+ Channel & channel2 = _channels[chan];
+
+ if (priority >= channel2.priority)
+ {
+ _flagTrigger = 1;
+ _flags |= 8;
+ initChannel (channel2);
+ channel2.priority = priority;
+ channel2.dataptr = ptr;
+ channel2.tempo = 0xFF;
+ channel2.position = 0xFF;
+ channel2.duration = 1;
+ unkOutput2 (chan);
+ }
+
+ return 0;
+}
+
+int
+AdlibDriver::update_setNoteSpacing (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.spacing1 = value;
+ return 0;
+}
+
+int
+AdlibDriver::update_jump (uint8 * &dataptr, Channel & channel, uint8 value)
+{
+ --dataptr;
+ int16 add = READ_LE_UINT16 (dataptr);
+ dataptr += 2;
+ dataptr += add;
+ return 0;
+}
+
+int
+AdlibDriver::update_jumpToSubroutine (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ --dataptr;
+ int16 add = READ_LE_UINT16 (dataptr);
+ dataptr += 2;
+ channel.dataptrStack[channel.dataptrStackPos++] = dataptr;
+ dataptr += add;
+ return 0;
+}
+
+int
+AdlibDriver::update_returnFromSubroutine (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ dataptr = channel.dataptrStack[--channel.dataptrStackPos];
+ return 0;
+}
+
+int
+AdlibDriver::update_setBaseOctave (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.baseOctave = value;
+ return 0;
+}
+
+int
+AdlibDriver::update_stopChannel (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.priority = 0;
+ if (_curChannel != 9)
+ {
+ noteOff (channel);
+ }
+ dataptr = 0;
+ return 2;
+}
+
+int
+AdlibDriver::update_playRest (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ setupDuration (value, channel);
+ noteOff (channel);
+ return (value != 0);
+}
+
+int
+AdlibDriver::update_writeAdlib (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ writeOPL (value, *dataptr++);
+ return 0;
+}
+
+int
+AdlibDriver::update_setupNoteAndDuration (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ setupNote (value, channel);
+ value = *dataptr++;
+ setupDuration (value, channel);
+ return (value != 0);
+}
+
+int
+AdlibDriver::update_setBaseNote (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.baseNote = value;
+ return 0;
+}
+
+int
+AdlibDriver::update_setupSecondaryEffect1 (uint8 * &dataptr,
+ Channel & channel, uint8 value)
+{
+ channel.unk18 = value;
+ channel.unk19 = value;
+ channel.unk20 = channel.unk21 = *dataptr++;
+ channel.unk22 = *dataptr++;
+ channel.offset = READ_LE_UINT16 (dataptr);
+ dataptr += 2;
+ channel.secondaryEffect = &AdlibDriver::secondaryEffect1;
+ return 0;
+}
+
+int
+AdlibDriver::update_stopOtherChannel (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ Channel & channel2 = _channels[value];
+ channel2.duration = 0;
+ channel2.priority = 0;
+ channel2.dataptr = 0;
+ return 0;
+}
+
+int
+AdlibDriver::update_waitForEndOfProgram (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ uint8 *ptr = getProgram (value);
+ uint8 chan = *ptr;
+
+ if (!_channels[chan].dataptr)
+ {
+ return 0;
+ }
+
+ dataptr -= 2;
+ return 2;
+}
+
+int
+AdlibDriver::update_setupInstrument (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ setupInstrument (_curRegOffset, getInstrument (value), channel);
+ return 0;
+}
+
+int
+AdlibDriver::update_setupPrimaryEffect1 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.unk29 = value;
+ channel.unk30 = READ_BE_UINT16 (dataptr);
+ dataptr += 2;
+ channel.primaryEffect = &AdlibDriver::primaryEffect1;
+ channel.unk31 = 0xFF;
+ return 0;
+}
+
+int
+AdlibDriver::update_removePrimaryEffect1 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ --dataptr;
+ channel.primaryEffect = 0;
+ channel.unk30 = 0;
+ return 0;
+}
+
+int
+AdlibDriver::update_setBaseFreq (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.baseFreq = value;
+ return 0;
+}
+
+int
+AdlibDriver::update_setupPrimaryEffect2 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.unk32 = value;
+ channel.unk33 = *dataptr++;
+ uint8 temp = *dataptr++;
+ channel.unk34 = temp + 1;
+ channel.unk35 = temp << 1;
+ channel.unk36 = *dataptr++;
+ channel.primaryEffect = &AdlibDriver::primaryEffect2;
+ return 0;
+}
+
+int
+AdlibDriver::update_setPriority (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.priority = value;
+ return 0;
+}
+
+int
+AdlibDriver::updateCallback23 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ value >>= 1;
+ _unkValue1 = _unkValue2 = value;
+ _unkValue3 = 0xFF;
+ _unkValue4 = _unkValue5 = 0;
+ return 0;
+}
+
+int
+AdlibDriver::updateCallback24 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ if (_unkValue5)
+ {
+ if (_unkValue4 & value)
+ {
+ _unkValue5 = 0;
+ return 0;
+ }
+ }
+
+ if (!(value & _unkValue4))
+ {
+ ++_unkValue5;
+ }
+
+ dataptr -= 2;
+ channel.duration = 1;
+ return 2;
+}
+
+int
+AdlibDriver::update_setExtraLevel1 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.opExtraLevel1 = value;
+ adjustVolume (channel);
+ return 0;
+}
+
+int
+AdlibDriver::update_setupDuration (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ setupDuration (value, channel);
+ return (value != 0);
+}
+
+int
+AdlibDriver::update_playNote (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ setupDuration (value, channel);
+ noteOn (channel);
+ return (value != 0);
+}
+
+int
+AdlibDriver::update_setFractionalNoteSpacing (uint8 * &dataptr,
+ Channel & channel, uint8 value)
+{
+ channel.fractionalSpacing = value & 7;
+ return 0;
+}
+
+int
+AdlibDriver::update_setTempo (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ _tempo = value;
+ return 0;
+}
+
+int
+AdlibDriver::update_removeSecondaryEffect1 (uint8 * &dataptr,
+ Channel & channel, uint8 value)
+{
+ --dataptr;
+ channel.secondaryEffect = 0;
+ return 0;
+}
+
+int
+AdlibDriver::update_setChannelTempo (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.tempo = value;
+ return 0;
+}
+
+int
+AdlibDriver::update_setExtraLevel3 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.opExtraLevel3 = value;
+ return 0;
+}
+
+int
+AdlibDriver::update_setExtraLevel2 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ int channelBackUp = _curChannel;
+
+ _curChannel = value;
+ Channel & channel2 = _channels[value];
+ channel2.opExtraLevel2 = *dataptr++;
+ adjustVolume (channel2);
+
+ _curChannel = channelBackUp;
+ return 0;
+}
+
+int
+AdlibDriver::update_changeExtraLevel2 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ int channelBackUp = _curChannel;
+
+ _curChannel = value;
+ Channel & channel2 = _channels[value];
+ channel2.opExtraLevel2 += *dataptr++;
+ adjustVolume (channel2);
+
+ _curChannel = channelBackUp;
+ return 0;
+}
+
+// Apart from initialising to zero, these two functions are the only ones that
+// modify _vibratoAndAMDepthBits.
+
+int
+AdlibDriver::update_setAMDepth (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ if (value & 1)
+ _vibratoAndAMDepthBits |= 0x80;
+ else
+ _vibratoAndAMDepthBits &= 0x7F;
+
+ writeOPL (0xBD, _vibratoAndAMDepthBits);
+ return 0;
+}
+
+int
+AdlibDriver::update_setVibratoDepth (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ if (value & 1)
+ _vibratoAndAMDepthBits |= 0x40;
+ else
+ _vibratoAndAMDepthBits &= 0xBF;
+
+ writeOPL (0xBD, _vibratoAndAMDepthBits);
+ return 0;
+}
+
+int
+AdlibDriver::update_changeExtraLevel1 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.opExtraLevel1 += value;
+ adjustVolume (channel);
+ return 0;
+}
+
+int
+AdlibDriver::updateCallback38 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ int channelBackUp = _curChannel;
+
+ _curChannel = value;
+ Channel & channel2 = _channels[value];
+ channel2.duration = channel2.priority = 0;
+ channel2.dataptr = 0;
+ channel2.opExtraLevel2 = 0;
+
+ if (value != 9)
+ {
+ uint8 outValue = _regOffset[value];
+
+ // Feedback strength / Connection type
+ writeOPL (0xC0 + _curChannel, 0x00);
+
+ // Key scaling level / Operator output level
+ writeOPL (0x43 + outValue, 0x3F);
+
+ // Sustain Level / Release Rate
+ writeOPL (0x83 + outValue, 0xFF);
+
+ // Key On / Octave / Frequency
+ writeOPL (0xB0 + _curChannel, 0x00);
+ }
+
+ _curChannel = channelBackUp;
+ return 0;
+}
+
+int
+AdlibDriver::updateCallback39 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ uint16 unk = *dataptr++;
+ unk |= value << 8;
+ unk &= getRandomNr ();
+
+ uint16 unk2 = ((channel.regBx & 0x1F) << 8) | channel.regAx;
+ unk2 += unk;
+ unk2 |= ((channel.regBx & 0x20) << 8);
+
+ // Frequency
+ writeOPL (0xA0 + _curChannel, unk2 & 0xFF);
+
+ // Key On / Octave / Frequency
+ writeOPL (0xB0 + _curChannel, (unk2 & 0xFF00) >> 8);
+
+ return 0;
+}
+
+int
+AdlibDriver::update_removePrimaryEffect2 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ --dataptr;
+ channel.primaryEffect = 0;
+ return 0;
+}
+
+int
+AdlibDriver::updateCallback41 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.unk16 = value;
+ setupNote (channel.rawNote, channel, true);
+ return 0;
+}
+
+int
+AdlibDriver::update_resetToGlobalTempo (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ --dataptr;
+ channel.tempo = _tempo;
+ return 0;
+}
+
+int
+AdlibDriver::update_nop1 (uint8 * &dataptr, Channel & channel, uint8 value)
+{
+ --dataptr;
+ return 0;
+}
+
+int
+AdlibDriver::update_setDurationRandomness (uint8 * &dataptr,
+ Channel & channel, uint8 value)
+{
+ channel.durationRandomness = value;
+ return 0;
+}
+
+int
+AdlibDriver::update_changeChannelTempo (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ int tempo = channel.tempo + (int8) value;
+
+ if (tempo <= 0)
+ tempo = 1;
+ else if (tempo > 255)
+ tempo = 255;
+
+ channel.tempo = tempo;
+ return 0;
+}
+
+int
+AdlibDriver::updateCallback46 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ uint8 entry = *dataptr++;
+ _tablePtr1 = _unkTable2[entry++];
+ _tablePtr2 = _unkTable2[entry];
+ if (value == 2)
+ {
+ // Frequency
+ writeOPL (0xA0, _tablePtr2[0]);
+ }
+ return 0;
+}
+
+// TODO: This is really the same as update_nop1(), so they should be combined
+// into one single update_nop().
+
+int
+AdlibDriver::update_nop2 (uint8 * &dataptr, Channel & channel, uint8 value)
+{
+ --dataptr;
+ return 0;
+}
+
+int
+AdlibDriver::update_setupRhythmSection (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ int channelBackUp = _curChannel;
+ int regOffsetBackUp = _curRegOffset;
+
+ _curChannel = 6;
+ _curRegOffset = _regOffset[6];
+
+ setupInstrument (_curRegOffset, getInstrument (value), channel);
+ _unkValue6 = channel.opLevel2;
+
+ _curChannel = 7;
+ _curRegOffset = _regOffset[7];
+
+ setupInstrument (_curRegOffset, getInstrument (*dataptr++), channel);
+ _unkValue7 = channel.opLevel1;
+ _unkValue8 = channel.opLevel2;
+
+ _curChannel = 8;
+ _curRegOffset = _regOffset[8];
+
+ setupInstrument (_curRegOffset, getInstrument (*dataptr++), channel);
+ _unkValue9 = channel.opLevel1;
+ _unkValue10 = channel.opLevel2;
+
+ // Octave / F-Number / Key-On for channels 6, 7 and 8
+
+ _channels[6].regBx = *dataptr++ & 0x2F;
+ writeOPL (0xB6, _channels[6].regBx);
+ writeOPL (0xA6, *dataptr++);
+
+ _channels[7].regBx = *dataptr++ & 0x2F;
+ writeOPL (0xB7, _channels[7].regBx);
+ writeOPL (0xA7, *dataptr++);
+
+ _channels[8].regBx = *dataptr++ & 0x2F;
+ writeOPL (0xB8, _channels[8].regBx);
+ writeOPL (0xA8, *dataptr++);
+
+ _rhythmSectionBits = 0x20;
+
+ _curRegOffset = regOffsetBackUp;
+ _curChannel = channelBackUp;
+ return 0;
+}
+
+int
+AdlibDriver::update_playRhythmSection (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ // Any instrument that we want to play, and which was already playing,
+ // is temporarily keyed off. Instruments that were off already, or
+ // which we don't want to play, retain their old on/off status. This is
+ // probably so that the instrument's envelope is played from its
+ // beginning again...
+
+ writeOPL (0xBD, (_rhythmSectionBits & ~(value & 0x1F)) | 0x20);
+
+ // ...but since we only set the rhythm instrument bits, and never clear
+ // them (until the entire rhythm section is disabled), I'm not sure how
+ // useful the cleverness above is. We could perhaps simply turn off all
+ // the rhythm instruments instead.
+
+ _rhythmSectionBits |= value;
+
+ writeOPL (0xBD, _vibratoAndAMDepthBits | 0x20 | _rhythmSectionBits);
+ return 0;
+}
+
+int
+AdlibDriver::update_removeRhythmSection (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ --dataptr;
+ _rhythmSectionBits = 0;
+
+ // All the rhythm bits are cleared. The AM and Vibrato depth bits
+ // remain unchanged.
+
+ writeOPL (0xBD, _vibratoAndAMDepthBits);
+ return 0;
+}
+
+int
+AdlibDriver::updateCallback51 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ uint8 value2 = *dataptr++;
+
+ if (value & 1)
+ {
+ _unkValue12 = value2;
+
+ // Channel 7, op1: Level Key Scaling / Total Level
+ writeOPL (0x51,
+ checkValue (value2 + _unkValue7 + _unkValue11 + _unkValue12));
+ }
+
+ if (value & 2)
+ {
+ _unkValue14 = value2;
+
+ // Channel 8, op2: Level Key Scaling / Total Level
+ writeOPL (0x55,
+ checkValue (value2 + _unkValue10 + _unkValue13 + _unkValue14));
+ }
+
+ if (value & 4)
+ {
+ _unkValue15 = value2;
+
+ // Channel 8, op1: Level Key Scaling / Total Level
+ writeOPL (0x52,
+ checkValue (value2 + _unkValue9 + _unkValue16 + _unkValue15));
+ }
+
+ if (value & 8)
+ {
+ _unkValue18 = value2;
+
+ // Channel 7, op2: Level Key Scaling / Total Level
+ writeOPL (0x54,
+ checkValue (value2 + _unkValue8 + _unkValue17 + _unkValue18));
+ }
+
+ if (value & 16)
+ {
+ _unkValue20 = value2;
+
+ // Channel 6, op2: Level Key Scaling / Total Level
+ writeOPL (0x53,
+ checkValue (value2 + _unkValue6 + _unkValue19 + _unkValue20));
+ }
+
+ return 0;
+}
+
+int
+AdlibDriver::updateCallback52 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ uint8 value2 = *dataptr++;
+
+ if (value & 1)
+ {
+ _unkValue11 =
+ checkValue (value2 + _unkValue7 + _unkValue11 + _unkValue12);
+
+ // Channel 7, op1: Level Key Scaling / Total Level
+ writeOPL (0x51, _unkValue11);
+ }
+
+ if (value & 2)
+ {
+ _unkValue13 =
+ checkValue (value2 + _unkValue10 + _unkValue13 + _unkValue14);
+
+ // Channel 8, op2: Level Key Scaling / Total Level
+ writeOPL (0x55, _unkValue13);
+ }
+
+ if (value & 4)
+ {
+ _unkValue16 =
+ checkValue (value2 + _unkValue9 + _unkValue16 + _unkValue15);
+
+ // Channel 8, op1: Level Key Scaling / Total Level
+ writeOPL (0x52, _unkValue16);
+ }
+
+ if (value & 8)
+ {
+ _unkValue17 =
+ checkValue (value2 + _unkValue8 + _unkValue17 + _unkValue18);
+
+ // Channel 7, op2: Level Key Scaling / Total Level
+ writeOPL (0x54, _unkValue17);
+ }
+
+ if (value & 16)
+ {
+ _unkValue19 =
+ checkValue (value2 + _unkValue6 + _unkValue19 + _unkValue20);
+
+ // Channel 6, op2: Level Key Scaling / Total Level
+ writeOPL (0x53, _unkValue19);
+ }
+
+ return 0;
+}
+
+int
+AdlibDriver::updateCallback53 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ uint8 value2 = *dataptr++;
+
+ if (value & 1)
+ {
+ _unkValue11 = value2;
+
+ // Channel 7, op1: Level Key Scaling / Total Level
+ writeOPL (0x51, checkValue (value2 + _unkValue7 + _unkValue12));
+ }
+
+ if (value & 2)
+ {
+ _unkValue13 = value2;
+
+ // Channel 8, op2: Level Key Scaling / Total Level
+ writeOPL (0x55, checkValue (value2 + _unkValue10 + _unkValue14));
+ }
+
+ if (value & 4)
+ {
+ _unkValue16 = value2;
+
+ // Channel 8, op1: Level Key Scaling / Total Level
+ writeOPL (0x52, checkValue (value2 + _unkValue9 + _unkValue15));
+ }
+
+ if (value & 8)
+ {
+ _unkValue17 = value2;
+
+ // Channel 7, op2: Level Key Scaling / Total Level
+ writeOPL (0x54, checkValue (value2 + _unkValue8 + _unkValue18));
+ }
+
+ if (value & 16)
+ {
+ _unkValue19 = value2;
+
+ // Channel 6, op2: Level Key Scaling / Total Level
+ writeOPL (0x53, checkValue (value2 + _unkValue6 + _unkValue20));
+ }
+
+ return 0;
+}
+
+int
+AdlibDriver::update_setSoundTrigger (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ _soundTrigger = value;
+ return 0;
+}
+
+int
+AdlibDriver::update_setTempoReset (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.tempoReset = value;
+ return 0;
+}
+
+int
+AdlibDriver::updateCallback56 (uint8 * &dataptr, Channel & channel,
+ uint8 value)
+{
+ channel.unk39 = value;
+ channel.unk40 = *dataptr++;
+ return 0;
+}
+
+// static res
+
+#define COMMAND(x) { &AdlibDriver::x, #x }
+
+void
+AdlibDriver::setupOpcodeList ()
+{
+ static const OpcodeEntry opcodeList[] = {
+ COMMAND (snd_ret0x100),
+ COMMAND (snd_ret0x1983),
+ COMMAND (snd_initDriver),
+ COMMAND (snd_deinitDriver),
+ COMMAND (snd_setSoundData),
+ COMMAND (snd_unkOpcode1),
+ COMMAND (snd_startSong),
+ COMMAND (snd_unkOpcode2),
+ COMMAND (snd_unkOpcode3),
+ COMMAND (snd_readByte),
+ COMMAND (snd_writeByte),
+ COMMAND (snd_getSoundTrigger),
+ COMMAND (snd_unkOpcode4),
+ COMMAND (snd_dummy),
+ COMMAND (snd_getNullvar4),
+ COMMAND (snd_setNullvar3),
+ COMMAND (snd_setFlag),
+ COMMAND (snd_clearFlag)
+ };
+
+ _opcodeList = opcodeList;
+ _opcodesEntries = ARRAYSIZE (opcodeList);
+}
+
+void
+AdlibDriver::setupParserOpcodeTable ()
+{
+ static const ParserOpcode parserOpcodeTable[] = {
+ // 0
+ COMMAND (update_setRepeat),
+ COMMAND (update_checkRepeat),
+ COMMAND (update_setupProgram),
+ COMMAND (update_setNoteSpacing),
+
+ // 4
+ COMMAND (update_jump),
+ COMMAND (update_jumpToSubroutine),
+ COMMAND (update_returnFromSubroutine),
+ COMMAND (update_setBaseOctave),
+
+ // 8
+ COMMAND (update_stopChannel),
+ COMMAND (update_playRest),
+ COMMAND (update_writeAdlib),
+ COMMAND (update_setupNoteAndDuration),
+
+ // 12
+ COMMAND (update_setBaseNote),
+ COMMAND (update_setupSecondaryEffect1),
+ COMMAND (update_stopOtherChannel),
+ COMMAND (update_waitForEndOfProgram),
+
+ // 16
+ COMMAND (update_setupInstrument),
+ COMMAND (update_setupPrimaryEffect1),
+ COMMAND (update_removePrimaryEffect1),
+ COMMAND (update_setBaseFreq),
+
+ // 20
+ COMMAND (update_stopChannel),
+ COMMAND (update_setupPrimaryEffect2),
+ COMMAND (update_stopChannel),
+ COMMAND (update_stopChannel),
+
+ // 24
+ COMMAND (update_stopChannel),
+ COMMAND (update_stopChannel),
+ COMMAND (update_setPriority),
+ COMMAND (update_stopChannel),
+
+ // 28
+ COMMAND (updateCallback23),
+ COMMAND (updateCallback24),
+ COMMAND (update_setExtraLevel1),
+ COMMAND (update_stopChannel),
+
+ // 32
+ COMMAND (update_setupDuration),
+ COMMAND (update_playNote),
+ COMMAND (update_stopChannel),
+ COMMAND (update_stopChannel),
+
+ // 36
+ COMMAND (update_setFractionalNoteSpacing),
+ COMMAND (update_stopChannel),
+ COMMAND (update_setTempo),
+ COMMAND (update_removeSecondaryEffect1),
+
+ // 40
+ COMMAND (update_stopChannel),
+ COMMAND (update_setChannelTempo),
+ COMMAND (update_stopChannel),
+ COMMAND (update_setExtraLevel3),
+
+ // 44
+ COMMAND (update_setExtraLevel2),
+ COMMAND (update_changeExtraLevel2),
+ COMMAND (update_setAMDepth),
+ COMMAND (update_setVibratoDepth),
+
+ // 48
+ COMMAND (update_changeExtraLevel1),
+ COMMAND (update_stopChannel),
+ COMMAND (update_stopChannel),
+ COMMAND (updateCallback38),
+
+ // 52
+ COMMAND (update_stopChannel),
+ COMMAND (updateCallback39),
+ COMMAND (update_removePrimaryEffect2),
+ COMMAND (update_stopChannel),
+
+ // 56
+ COMMAND (update_stopChannel),
+ COMMAND (updateCallback41),
+ COMMAND (update_resetToGlobalTempo),
+ COMMAND (update_nop1),
+
+ // 60
+ COMMAND (update_setDurationRandomness),
+ COMMAND (update_changeChannelTempo),
+ COMMAND (update_stopChannel),
+ COMMAND (updateCallback46),
+
+ // 64
+ COMMAND (update_nop2),
+ COMMAND (update_setupRhythmSection),
+ COMMAND (update_playRhythmSection),
+ COMMAND (update_removeRhythmSection),
+
+ // 68
+ COMMAND (updateCallback51),
+ COMMAND (updateCallback52),
+ COMMAND (updateCallback53),
+ COMMAND (update_setSoundTrigger),
+
+ // 72
+ COMMAND (update_setTempoReset),
+ COMMAND (updateCallback56),
+ COMMAND (update_stopChannel)
+ };
+
+ _parserOpcodeTable = parserOpcodeTable;
+ _parserOpcodeTableSize = ARRAYSIZE (parserOpcodeTable);
+}
+
+#undef COMMAND
+
+// This table holds the register offset for operator 1 for each of the nine
+// channels. To get the register offset for operator 2, simply add 3.
+
+const uint8
+ AdlibDriver::_regOffset[] = {
+ 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11,
+ 0x12
+};
+
+// Given the size of this table, and the range of its values, it's probably the
+// F-Numbers (10 bits) for the notes of the 12-tone scale. However, it does not
+// match the table in the Adlib documentation I've seen.
+
+const uint16
+ AdlibDriver::_unkTable[] = {
+ 0x0134, 0x0147, 0x015A, 0x016F, 0x0184, 0x019C, 0x01B4, 0x01CE, 0x01E9,
+ 0x0207, 0x0225, 0x0246
+};
+
+// These tables are currently only used by updateCallback46(), which only ever
+// uses the first element of one of the sub-tables.
+
+const uint8 *
+ AdlibDriver::_unkTable2[] = {
+ AdlibDriver::_unkTable2_1,
+ AdlibDriver::_unkTable2_2,
+ AdlibDriver::_unkTable2_1,
+ AdlibDriver::_unkTable2_2,
+ AdlibDriver::_unkTable2_3,
+ AdlibDriver::_unkTable2_2
+};
+
+const uint8
+ AdlibDriver::_unkTable2_1[] = {
+ 0x50, 0x50, 0x4F, 0x4F, 0x4E, 0x4E, 0x4D, 0x4D,
+ 0x4C, 0x4C, 0x4B, 0x4B, 0x4A, 0x4A, 0x49, 0x49,
+ 0x48, 0x48, 0x47, 0x47, 0x46, 0x46, 0x45, 0x45,
+ 0x44, 0x44, 0x43, 0x43, 0x42, 0x42, 0x41, 0x41,
+ 0x40, 0x40, 0x3F, 0x3F, 0x3E, 0x3E, 0x3D, 0x3D,
+ 0x3C, 0x3C, 0x3B, 0x3B, 0x3A, 0x3A, 0x39, 0x39,
+ 0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35, 0x35,
+ 0x34, 0x34, 0x33, 0x33, 0x32, 0x32, 0x31, 0x31,
+ 0x30, 0x30, 0x2F, 0x2F, 0x2E, 0x2E, 0x2D, 0x2D,
+ 0x2C, 0x2C, 0x2B, 0x2B, 0x2A, 0x2A, 0x29, 0x29,
+ 0x28, 0x28, 0x27, 0x27, 0x26, 0x26, 0x25, 0x25,
+ 0x24, 0x24, 0x23, 0x23, 0x22, 0x22, 0x21, 0x21,
+ 0x20, 0x20, 0x1F, 0x1F, 0x1E, 0x1E, 0x1D, 0x1D,
+ 0x1C, 0x1C, 0x1B, 0x1B, 0x1A, 0x1A, 0x19, 0x19,
+ 0x18, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15,
+ 0x14, 0x14, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11,
+ 0x10, 0x10
+};
+
+// no don't ask me WHY this table exsits!
+const uint8
+ AdlibDriver::_unkTable2_2[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x6F,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F
+};
+
+const uint8
+ AdlibDriver::_unkTable2_3[] = {
+ 0x40, 0x40, 0x40, 0x3F, 0x3F, 0x3F, 0x3E, 0x3E,
+ 0x3E, 0x3D, 0x3D, 0x3D, 0x3C, 0x3C, 0x3C, 0x3B,
+ 0x3B, 0x3B, 0x3A, 0x3A, 0x3A, 0x39, 0x39, 0x39,
+ 0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36,
+ 0x36, 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x33,
+ 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31,
+ 0x30, 0x30, 0x30, 0x2F, 0x2F, 0x2F, 0x2E, 0x2E,
+ 0x2E, 0x2D, 0x2D, 0x2D, 0x2C, 0x2C, 0x2C, 0x2B,
+ 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, 0x29, 0x29, 0x29,
+ 0x28, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26,
+ 0x26, 0x25, 0x25, 0x25, 0x24, 0x24, 0x24, 0x23,
+ 0x23, 0x23, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21,
+ 0x20, 0x20, 0x20, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E,
+ 0x1E, 0x1D, 0x1D, 0x1D, 0x1C, 0x1C, 0x1C, 0x1B,
+ 0x1B, 0x1B, 0x1A, 0x1A, 0x1A, 0x19, 0x19, 0x19,
+ 0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16, 0x16,
+ 0x16, 0x15
+};
+
+// This table is used to modify the frequency of the notes, depending on the
+// note value and unk16. In theory, we could very well try to access memory
+// outside this table, but in reality that probably won't happen.
+//
+// This could be some sort of pitch bend, but I have yet to see it used for
+// anything so it's hard to say.
+
+const uint8
+ AdlibDriver::_unkTables[][32] = {
+ // 0
+ {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
+ 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x19,
+ 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21},
+ // 1
+ {0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x09,
+ 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11,
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x1A,
+ 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x22, 0x24},
+ // 2
+ {0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x09,
+ 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x19, 0x1A, 0x1C, 0x1D,
+ 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26},
+ // 3
+ {0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0A,
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x1A, 0x1C, 0x1D,
+ 0x1E, 0x1F, 0x20, 0x21, 0x23, 0x25, 0x27, 0x28},
+ // 4
+ {0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0A,
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x13, 0x15,
+ 0x16, 0x17, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x28, 0x2A},
+ // 5
+ {0x00, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15,
+ 0x16, 0x17, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x20,
+ 0x21, 0x22, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D},
+ // 6
+ {0x00, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15,
+ 0x16, 0x17, 0x18, 0x1A, 0x1C, 0x1E, 0x21, 0x24,
+ 0x25, 0x26, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x30},
+ // 7
+ {0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C,
+ 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x18,
+ 0x19, 0x1A, 0x1C, 0x1D, 0x1F, 0x21, 0x23, 0x25,
+ 0x26, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x30, 0x32},
+ // 8
+ {0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0D,
+ 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x14, 0x17, 0x1A,
+ 0x19, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x25, 0x28,
+ 0x29, 0x2A, 0x2B, 0x2D, 0x2F, 0x31, 0x33, 0x35},
+ // 9
+ {0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0E,
+ 0x0F, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1B,
+ 0x1C, 0x1D, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x29,
+ 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x39},
+ // 10
+ {0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0E,
+ 0x0F, 0x10, 0x12, 0x14, 0x16, 0x19, 0x1B, 0x1E,
+ 0x1F, 0x21, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D,
+ 0x2E, 0x2F, 0x31, 0x32, 0x34, 0x36, 0x39, 0x3C},
+ // 11
+ {0x00, 0x01, 0x03, 0x05, 0x07, 0x0A, 0x0C, 0x0F,
+ 0x10, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1E,
+ 0x1F, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2B, 0x2E,
+ 0x2F, 0x30, 0x32, 0x34, 0x36, 0x39, 0x3C, 0x3F},
+ // 12
+ {0x00, 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x10,
+ 0x11, 0x12, 0x14, 0x16, 0x18, 0x1B, 0x1E, 0x21,
+ 0x22, 0x23, 0x25, 0x27, 0x29, 0x2C, 0x2F, 0x32,
+ 0x33, 0x34, 0x36, 0x38, 0x3B, 0x34, 0x41, 0x44},
+ // 13
+ {0x00, 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x11,
+ 0x12, 0x13, 0x15, 0x17, 0x1A, 0x1D, 0x20, 0x23,
+ 0x24, 0x25, 0x27, 0x29, 0x2C, 0x2F, 0x32, 0x35,
+ 0x36, 0x37, 0x39, 0x3B, 0x3E, 0x41, 0x44, 0x47}
+};
+
+// #pragma mark -
+
+// At the time of writing, the only known case where Kyra 1 uses sound triggers
+// is in the castle, to cycle between three different songs.
+
+const int
+ CadlPlayer::_kyra1SoundTriggers[] = {
+ 0, 4, 5, 3
+};
+
+const int
+ CadlPlayer::_kyra1NumSoundTriggers =
+ARRAYSIZE (CadlPlayer::_kyra1SoundTriggers);
+
+CadlPlayer::CadlPlayer (Copl * newopl):CPlayer (newopl), numsubsongs (0), _trackEntries (),
+_soundDataPtr (0)
+{
+ memset (_trackEntries, 0, sizeof (_trackEntries));
+ _driver = new AdlibDriver (newopl);
+ assert (_driver);
+
+ _sfxPlayingSound = -1;
+ // _soundFileLoaded = "";
+
+ _soundTriggers = _kyra1SoundTriggers;
+ _numSoundTriggers = _kyra1NumSoundTriggers;
+
+ init ();
+}
+
+CadlPlayer::~CadlPlayer ()
+{
+ delete[]_soundDataPtr;
+ _soundDataPtr = 0;
+ delete _driver;
+ _driver = 0;
+}
+
+bool
+CadlPlayer::init ()
+{
+ _driver->callback (2);
+ _driver->callback (16, int (4));
+ return true;
+}
+
+void
+CadlPlayer::process ()
+{
+ uint8 trigger = _driver->callback (11);
+
+ if (trigger < _numSoundTriggers)
+ {
+ int soundId = _soundTriggers[trigger];
+
+ if (soundId)
+ {
+ playTrack (soundId);
+ }
+ }
+ else
+ {
+ warning ("Unknown sound trigger %d", trigger);
+ // TODO: At this point, we really want to clear the trigger...
+ }
+}
+
+// void CadlPlayer::setVolume(int volume) {
+// }
+
+// int CadlPlayer::getVolume() {
+// return 0;
+// }
+
+// void CadlPlayer::loadMusicFile(const char *file) {
+// loadSoundFile(file);
+// }
+
+void
+CadlPlayer::playTrack (uint8 track)
+{
+ play (track);
+}
+
+// void CadlPlayer::haltTrack() {
+// unk1();
+// unk2();
+// //_engine->_system->delayMillis(3 * 60);
+// }
+
+void
+CadlPlayer::playSoundEffect (uint8_t track)
+{
+ play (track);
+}
+
+void
+CadlPlayer::play (uint8_t track)
+{
+ uint8 soundId = _trackEntries[track];
+ if ((int8) soundId == -1 || !_soundDataPtr)
+ return;
+ soundId &= 0xFF;
+ _driver->callback (16, 0);
+ // while ((_driver->callback(16, 0) & 8)) {
+ // We call the system delay and not the game delay to avoid concurrency issues.
+ // _engine->_system->delayMillis(10);
+ // }
+ if (_sfxPlayingSound != -1)
+ {
+ // Restore the sounds's normal values.
+ _driver->callback (10, _sfxPlayingSound, int (1), int (_sfxPriority));
+ _driver->callback (10, _sfxPlayingSound, int (3),
+ int (_sfxFourthByteOfSong));
+ _sfxPlayingSound = -1;
+ }
+
+ int chan = _driver->callback (9, soundId, int (0));
+
+ if (chan != 9)
+ {
+ _sfxPlayingSound = soundId;
+ _sfxPriority = _driver->callback (9, soundId, int (1));
+ _sfxFourthByteOfSong = _driver->callback (9, soundId, int (3));
+
+ // In the cases I've seen, the mysterious fourth byte has been
+ // the parameter for the update_setExtraLevel3() callback.
+ //
+ // The extra level is part of the channels "total level", which
+ // is a six-bit value where larger values means softer volume.
+ //
+ // So what seems to be happening here is that sounds which are
+ // started by this function are given a slightly lower priority
+ // and a slightly higher (i.e. softer) extra level 3 than they
+ // would have if they were started from anywhere else. Strange.
+
+ int newVal = ((((-_sfxFourthByteOfSong) + 63) * 0xFF) >> 8) & 0xFF;
+ newVal = -newVal + 63;
+ _driver->callback (10, soundId, int (3), newVal);
+ newVal = ((_sfxPriority * 0xFF) >> 8) & 0xFF;
+ _driver->callback (10, soundId, int (1), newVal);
+ }
+
+ _driver->callback (6, soundId);
+}
+
+// void CadlPlayer::beginFadeOut() {
+// playSoundEffect(1);
+// }
+
+bool
+CadlPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ std::string filename (fd.filename ());
+
+ // file validation section
+ if (!f || !fp.extension (filename, ".adl"))
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // if (_soundFileLoaded == file)
+ // return;
+
+ // if (_soundDataPtr) {
+ // haltTrack();
+ // }
+
+ uint8 *file_data = 0;
+ uint32 file_size = 0;
+
+ // char filename[25];
+ // sprintf(filename, "%s.ADL", file);
+
+ // file_data = _engine->resource()->fileData(filename, &file_size);
+ // if (!file_data) {
+ // warning("Couldn't find music file: '%s'", filename);
+ // return;
+ // }
+
+ unk2 ();
+ unk1 ();
+
+ file_size = fp.filesize (f);
+ file_data = new uint8[file_size];
+ f->readString ((char *) file_data, file_size);
+
+ _driver->callback (8, int (-1));
+ _soundDataPtr = 0;
+
+ uint8 *p = file_data;
+ memcpy (_trackEntries, p, 120 * sizeof (uint8));
+ p += 120;
+
+ int soundDataSize = file_size - 120;
+
+ _soundDataPtr = new uint8[soundDataSize];
+ assert (_soundDataPtr);
+
+ memcpy (_soundDataPtr, p, soundDataSize * sizeof (uint8));
+
+ delete[]file_data;
+ file_data = p = 0;
+ file_size = 0;
+
+ _driver->callback (4, _soundDataPtr);
+
+ // _soundFileLoaded = file;
+
+ // find last subsong
+ for(int i = 119; i >= 0; i--)
+ if(_trackEntries[i] != 0xff) {
+ numsubsongs = i + 1;
+ break;
+ }
+ fp.close (f);
+ cursubsong = 2;
+ rewind();
+ return true;
+}
+
+void
+CadlPlayer::rewind (int subsong)
+{
+ if(subsong == -1) subsong = cursubsong;
+ opl->init ();
+ opl->write (1, 32);
+ playSoundEffect (subsong);
+ cursubsong = subsong;
+ update ();
+}
+
+unsigned int
+CadlPlayer::getsubsongs ()
+{
+ return numsubsongs;
+}
+
+bool
+CadlPlayer::update ()
+{
+ bool songend = true;
+
+// if(_trackEntries[cursubsong] == 0xff)
+// return false;
+
+ _driver->callback ();
+
+ for (int i = 0; i < 10; i++)
+ if (_driver->_channels[i].dataptr != nullptr)
+ songend = false;
+
+ return !songend;
+}
+
+void
+CadlPlayer::unk1 ()
+{
+ playSoundEffect (0);
+ //_engine->_system->delayMillis(5 * 60);
+}
+
+void
+CadlPlayer::unk2 ()
+{
+ playSoundEffect (0);
+}
+
+CPlayer *
+CadlPlayer::factory (Copl * newopl)
+{
+ return new CadlPlayer (newopl);
+}
diff --git a/src/adplug/core/adl.cxx b/src/adplug/core/adl.cxx
deleted file mode 100644
index e3506b595b21..000000000000
--- a/src/adplug/core/adl.cxx
+++ /dev/null
@@ -1,2874 +0,0 @@
-/*
- * adl.cpp - ADL player adaption by Simon Peter <dn.tlp at gmx.net>
- *
- * Original ADL player by Torbjorn Andersson and Johannes Schickel
- * 'lordhoto' <lordhoto at scummvm dot org> of the ScummVM project.
- */
-
-/* ScummVM - Scumm Interpreter
- *
- * This file is licensed under both GPL and LGPL
- * Copyright (C) 2006 The ScummVM project
- * Copyright (C) 2006 Torbjorn Andersson and Johannes Schickel
- *
- * GPL License
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * LPGL License
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <assert.h>
-#include <inttypes.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include "adl.h"
-#include "debug.h"
-
-#ifdef ADL_DEBUG
-# define warning(...) AdPlug_LogWrite(__VA_ARGS__); \
-AdPlug_LogWrite("\n")
-
-# define debugC(i1, i2, ...) AdPlug_LogWrite(__VA_ARGS__); \
-AdPlug_LogWrite("\n")
-#else
-# define kDebugLevelSound 1
-
-static inline void
-warning (const char *str, ...)
-{
-}
-
-static inline void
-debugC (int i1, int i2, const char *str, ...)
-{
-}
-#endif
-
-// #define warning(...)
-// #define debugC(i1, i2, ...)
-
-#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
-
-// Basic Adlib Programming:
-// http://www.gamedev.net/reference/articles/article446.asp
-
-#define CALLBACKS_PER_SECOND 72
-
-typedef uint8_t uint8;
-typedef int8_t int8;
-typedef uint16_t uint16;
-typedef int16_t int16;
-typedef uint32_t uint32;
-typedef int32_t int32;
-typedef uint8_t byte;
-
-static inline uint16
-READ_LE_UINT16 (const void *ptr)
-{
- const byte *b = (const byte *) ptr;
- return (b[1] << 8) + b[0];
-}
-
-static inline uint16
-READ_BE_UINT16 (const void *ptr)
-{
- const byte *b = (const byte *) ptr;
- return (b[0] << 8) + b[1];
-}
-
-class AdlibDriver
-{
-public:
- AdlibDriver (Copl * opl);
- ~AdlibDriver ();
-
- int callback (int opcode, ...);
- void callback ();
-
- // AudioStream API
- // int readBuffer(int16 *buffer, const int numSamples) {
- // int32 samplesLeft = numSamples;
- // memset(buffer, 0, sizeof(int16) * numSamples);
- // while (samplesLeft) {
- // if (!_samplesTillCallback) {
- // callback();
- // _samplesTillCallback = _samplesPerCallback;
- // _samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
- // if (_samplesTillCallbackRemainder >= CALLBACKS_PER_SECOND) {
- // _samplesTillCallback++;
- // _samplesTillCallbackRemainder -= CALLBACKS_PER_SECOND;
- // }
- // }
-
- // int32 render = MIN(samplesLeft, _samplesTillCallback);
- // samplesLeft -= render;
- // _samplesTillCallback -= render;
- // YM3812UpdateOne(_adlib, buffer, render);
- // buffer += render;
- // }
- // return numSamples;
- // }
-
- bool isStereo () const
- {
- return false;
- }
- bool endOfData () const
- {
- return false;
- }
- // int getRate() const { return _mixer->getOutputRate(); }
-
- struct OpcodeEntry
- {
- typedef int (AdlibDriver::*DriverOpcode) (va_list & list);
- DriverOpcode function;
- const char *name;
- };
-
- void setupOpcodeList ();
- const OpcodeEntry *_opcodeList;
- int _opcodesEntries;
-
- int snd_ret0x100 (va_list & list);
- int snd_ret0x1983 (va_list & list);
- int snd_initDriver (va_list & list);
- int snd_deinitDriver (va_list & list);
- int snd_setSoundData (va_list & list);
- int snd_unkOpcode1 (va_list & list);
- int snd_startSong (va_list & list);
- int snd_unkOpcode2 (va_list & list);
- int snd_unkOpcode3 (va_list & list);
- int snd_readByte (va_list & list);
- int snd_writeByte (va_list & list);
- int snd_getSoundTrigger (va_list & list);
- int snd_unkOpcode4 (va_list & list);
- int snd_dummy (va_list & list);
- int snd_getNullvar4 (va_list & list);
- int snd_setNullvar3 (va_list & list);
- int snd_setFlag (va_list & list);
- int snd_clearFlag (va_list & list);
-
- // These variables have not yet been named, but some of them are partly
- // known nevertheless:
- //
- // unk16 - Sound-related. Possibly some sort of pitch bend.
- // unk18 - Sound-effect. Used for secondaryEffect1()
- // unk19 - Sound-effect. Used for secondaryEffect1()
- // unk20 - Sound-effect. Used for secondaryEffect1()
- // unk21 - Sound-effect. Used for secondaryEffect1()
- // unk22 - Sound-effect. Used for secondaryEffect1()
- // unk29 - Sound-effect. Used for primaryEffect1()
- // unk30 - Sound-effect. Used for primaryEffect1()
- // unk31 - Sound-effect. Used for primaryEffect1()
- // unk32 - Sound-effect. Used for primaryEffect2()
- // unk33 - Sound-effect. Used for primaryEffect2()
- // unk34 - Sound-effect. Used for primaryEffect2()
- // unk35 - Sound-effect. Used for primaryEffect2()
- // unk36 - Sound-effect. Used for primaryEffect2()
- // unk37 - Sound-effect. Used for primaryEffect2()
- // unk38 - Sound-effect. Used for primaryEffect2()
- // unk39 - Currently unused, except for updateCallback56()
- // unk40 - Currently unused, except for updateCallback56()
- // unk41 - Sound-effect. Used for primaryEffect2()
-
- struct Channel
- {
- uint8 opExtraLevel2;
- uint8 *dataptr;
- uint8 duration;
- uint8 repeatCounter;
- int8 baseOctave;
- uint8 priority;
- uint8 dataptrStackPos;
- uint8 *dataptrStack[4];
- int8 baseNote;
- uint8 unk29;
- uint8 unk31;
- uint16 unk30;
- uint16 unk37;
- uint8 unk33;
- uint8 unk34;
- uint8 unk35;
- uint8 unk36;
- uint8 unk32;
- uint8 unk41;
- uint8 unk38;
- uint8 opExtraLevel1;
- uint8 spacing2;
- uint8 baseFreq;
- uint8 tempo;
- uint8 position;
- uint8 regAx;
- uint8 regBx;
- typedef void (AdlibDriver::*Callback) (Channel &);
- Callback primaryEffect;
- Callback secondaryEffect;
- uint8 fractionalSpacing;
- uint8 opLevel1;
- uint8 opLevel2;
- uint8 opExtraLevel3;
- uint8 twoChan;
- uint8 unk39;
- uint8 unk40;
- uint8 spacing1;
- uint8 durationRandomness;
- uint8 unk19;
- uint8 unk18;
- int8 unk20;
- int8 unk21;
- uint8 unk22;
- uint16 offset;
- uint8 tempoReset;
- uint8 rawNote;
- int8 unk16;
- };
-
- void primaryEffect1 (Channel & channel);
- void primaryEffect2 (Channel & channel);
- void secondaryEffect1 (Channel & channel);
-
- void resetAdlibState ();
- void writeOPL (byte reg, byte val);
- void initChannel (Channel & channel);
- void noteOff (Channel & channel);
- void unkOutput2 (uint8 num);
-
- uint16 getRandomNr ();
- void setupDuration (uint8 duration, Channel & channel);
-
- void setupNote (uint8 rawNote, Channel & channel, bool flag = false);
- void setupInstrument (uint8 regOffset, uint8 * dataptr, Channel & channel);
- void noteOn (Channel & channel);
-
- void adjustVolume (Channel & channel);
-
- uint8 calculateOpLevel1 (Channel & channel);
- uint8 calculateOpLevel2 (Channel & channel);
-
- uint16 checkValue (int16 val)
- {
- if (val < 0)
- val = 0;
- else if (val > 0x3F)
- val = 0x3F;
- return val;
- }
-
- // The sound data has at least two lookup tables:
- //
- // * One for programs, starting at offset 0.
- // * One for instruments, starting at offset 500.
-
- uint8 *getProgram (int progId)
- {
- return _soundData + READ_LE_UINT16 (_soundData + 2 * progId);
- }
-
- uint8 *getInstrument (int instrumentId)
- {
- return _soundData + READ_LE_UINT16 (_soundData + 500 + 2 * instrumentId);
- }
-
- void setupPrograms ();
- void executePrograms ();
-
- struct ParserOpcode
- {
- typedef int (AdlibDriver::*POpcode) (uint8 * &dataptr, Channel & channel,
- uint8 value);
- POpcode function;
- const char *name;
- };
-
- void setupParserOpcodeTable ();
- const ParserOpcode *_parserOpcodeTable;
- int _parserOpcodeTableSize;
-
- int update_setRepeat (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_checkRepeat (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_setupProgram (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_setNoteSpacing (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_jump (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_jumpToSubroutine (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_returnFromSubroutine (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setBaseOctave (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_stopChannel (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_playRest (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_writeAdlib (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_setupNoteAndDuration (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setBaseNote (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_setupSecondaryEffect1 (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_stopOtherChannel (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_waitForEndOfProgram (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setupInstrument (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setupPrimaryEffect1 (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_removePrimaryEffect1 (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setBaseFreq (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_setupPrimaryEffect2 (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setPriority (uint8 * &dataptr, Channel & channel, uint8 value);
- int updateCallback23 (uint8 * &dataptr, Channel & channel, uint8 value);
- int updateCallback24 (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_setExtraLevel1 (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setupDuration (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_playNote (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_setFractionalNoteSpacing (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setTempo (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_removeSecondaryEffect1 (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setChannelTempo (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setExtraLevel3 (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setExtraLevel2 (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_changeExtraLevel2 (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setAMDepth (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_setVibratoDepth (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_changeExtraLevel1 (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int updateCallback38 (uint8 * &dataptr, Channel & channel, uint8 value);
- int updateCallback39 (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_removePrimaryEffect2 (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int updateCallback41 (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_resetToGlobalTempo (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_nop1 (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_setDurationRandomness (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_changeChannelTempo (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int updateCallback46 (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_nop2 (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_setupRhythmSection (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_playRhythmSection (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_removeRhythmSection (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int updateCallback51 (uint8 * &dataptr, Channel & channel, uint8 value);
- int updateCallback52 (uint8 * &dataptr, Channel & channel, uint8 value);
- int updateCallback53 (uint8 * &dataptr, Channel & channel, uint8 value);
- int update_setSoundTrigger (uint8 * &dataptr, Channel & channel,
- uint8 value);
- int update_setTempoReset (uint8 * &dataptr, Channel & channel, uint8 value);
- int updateCallback56 (uint8 * &dataptr, Channel & channel, uint8 value);
-
- // These variables have not yet been named, but some of them are partly
- // known nevertheless:
- //
- // _unkValue1 - Unknown. Used for updating _unkValue2
- // _unkValue2 - Unknown. Used for updating _unkValue4
- // _unkValue3 - Unknown. Used for updating _unkValue2
- // _unkValue4 - Unknown. Used for updating _unkValue5
- // _unkValue5 - Unknown. Used for controlling updateCallback24().
- // _unkValue6 - Unknown. Rhythm section volume?
- // _unkValue7 - Unknown. Rhythm section volume?
- // _unkValue8 - Unknown. Rhythm section volume?
- // _unkValue9 - Unknown. Rhythm section volume?
- // _unkValue10 - Unknown. Rhythm section volume?
- // _unkValue11 - Unknown. Rhythm section volume?
- // _unkValue12 - Unknown. Rhythm section volume?
- // _unkValue13 - Unknown. Rhythm section volume?
- // _unkValue14 - Unknown. Rhythm section volume?
- // _unkValue15 - Unknown. Rhythm section volume?
- // _unkValue16 - Unknown. Rhythm section volume?
- // _unkValue17 - Unknown. Rhythm section volume?
- // _unkValue18 - Unknown. Rhythm section volume?
- // _unkValue19 - Unknown. Rhythm section volume?
- // _unkValue20 - Unknown. Rhythm section volume?
- // _unkTable[] - Probably frequences for the 12-tone scale.
- // _unkTable2[] - Unknown. Currently only used by updateCallback46()
- // _unkTable2_1[] - One of the tables in _unkTable2[]
- // _unkTable2_2[] - One of the tables in _unkTable2[]
- // _unkTable2_3[] - One of the tables in _unkTable2[]
-
- int32 _samplesPerCallback;
- int32 _samplesPerCallbackRemainder;
- int32 _samplesTillCallback;
- int32 _samplesTillCallbackRemainder;
-
- int _lastProcessed;
- int8 _flagTrigger;
- int _curChannel;
- uint8 _soundTrigger;
- int _soundsPlaying;
-
- uint16 _rnd;
-
- uint8 _unkValue1;
- uint8 _unkValue2;
- uint8 _unkValue3;
- uint8 _unkValue4;
- uint8 _unkValue5;
- uint8 _unkValue6;
- uint8 _unkValue7;
- uint8 _unkValue8;
- uint8 _unkValue9;
- uint8 _unkValue10;
- uint8 _unkValue11;
- uint8 _unkValue12;
- uint8 _unkValue13;
- uint8 _unkValue14;
- uint8 _unkValue15;
- uint8 _unkValue16;
- uint8 _unkValue17;
- uint8 _unkValue18;
- uint8 _unkValue19;
- uint8 _unkValue20;
-
- int _flags;
-
- uint8 *_soundData;
-
- uint8 _soundIdTable[0x10];
- Channel _channels[10];
-
- uint8 _vibratoAndAMDepthBits;
- uint8 _rhythmSectionBits;
-
- uint8 _curRegOffset;
- uint8 _tempo;
-
- const uint8 *_tablePtr1;
- const uint8 *_tablePtr2;
-
- static const uint8 _regOffset[];
- static const uint16 _unkTable[];
- static const uint8 *_unkTable2[];
- static const uint8 _unkTable2_1[];
- static const uint8 _unkTable2_2[];
- static const uint8 _unkTable2_3[];
- static const uint8 _unkTables[][32];
-
- Copl *opl;
-};
-
-AdlibDriver::AdlibDriver (Copl * newopl):opl (newopl)
-{
- setupOpcodeList ();
- setupParserOpcodeTable ();
-
- // _mixer = mixer;
-
- _flags = 0;
- // _adlib = makeAdlibOPL(getRate());
- // assert(_adlib);
-
- memset (_channels, 0, sizeof (_channels));
- _soundData = 0;
-
- _vibratoAndAMDepthBits = _curRegOffset = 0;
-
- _lastProcessed = _flagTrigger = _curChannel = _rhythmSectionBits = 0;
- _soundsPlaying = 0;
- _rnd = 0x1234;
-
- _tempo = 0;
- _soundTrigger = 0;
-
- _unkValue3 = 0xFF;
- _unkValue1 = _unkValue2 = _unkValue4 = _unkValue5 = 0;
- _unkValue6 = _unkValue7 = _unkValue8 = _unkValue9 = _unkValue10 = 0;
- _unkValue11 = _unkValue12 = _unkValue13 = _unkValue14 = _unkValue15 =
- _unkValue16 = _unkValue17 = _unkValue18 = _unkValue19 = _unkValue20 = 0;
-
- _tablePtr1 = _tablePtr2 = 0;
-
- // _mixer->setupPremix(this);
-
- // _samplesPerCallback = getRate() / CALLBACKS_PER_SECOND;
- // _samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND;
- _samplesTillCallback = 0;
- _samplesTillCallbackRemainder = 0;
-}
-
-AdlibDriver::~AdlibDriver ()
-{
- // _mixer->setupPremix(0);
- // OPLDestroy(_adlib);
- // _adlib = 0;
-}
-
-int
-AdlibDriver::callback (int opcode, ...)
-{
- // lock();
- if (opcode >= _opcodesEntries || opcode < 0)
- {
- warning ("AdlibDriver: calling unknown opcode '%d'", opcode);
- return 0;
- }
-
- debugC (9, kDebugLevelSound, "Calling opcode '%s' (%d)",
- _opcodeList[opcode].name, opcode);
-
- va_list args;
- va_start (args, opcode);
- int returnValue = (this->*(_opcodeList[opcode].function)) (args);
- va_end (args);
- // unlock();
- return returnValue;
-}
-
-// Opcodes
-
-int
-AdlibDriver::snd_ret0x100 (va_list & list)
-{
- return 0x100;
-}
-
-int
-AdlibDriver::snd_ret0x1983 (va_list & list)
-{
- return 0x1983;
-}
-
-int
-AdlibDriver::snd_initDriver (va_list & list)
-{
- _lastProcessed = _soundsPlaying = 0;
- resetAdlibState ();
- return 0;
-}
-
-int
-AdlibDriver::snd_deinitDriver (va_list & list)
-{
- resetAdlibState ();
- return 0;
-}
-
-int
-AdlibDriver::snd_setSoundData (va_list & list)
-{
- if (_soundData)
- {
- delete[]_soundData;
- _soundData = 0;
- }
- _soundData = va_arg (list, uint8 *);
- return 0;
-}
-
-int
-AdlibDriver::snd_unkOpcode1 (va_list & list)
-{
- warning ("unimplemented snd_unkOpcode1");
- return 0;
-}
-
-int
-AdlibDriver::snd_startSong (va_list & list)
-{
- int songId = va_arg (list, int);
- _flags |= 8;
- _flagTrigger = 1;
-
- uint8 *ptr = getProgram (songId);
- uint8 chan = *ptr;
-
- if ((songId << 1) != 0)
- {
- if (chan == 9)
- {
- if (_flags & 2)
- return 0;
- }
- else
- {
- if (_flags & 1)
- return 0;
- }
- }
-
- _soundIdTable[_soundsPlaying++] = songId;
- _soundsPlaying &= 0x0F;
-
- return 0;
-}
-
-int
-AdlibDriver::snd_unkOpcode2 (va_list & list)
-{
- warning ("unimplemented snd_unkOpcode2");
- return 0;
-}
-
-int
-AdlibDriver::snd_unkOpcode3 (va_list & list)
-{
- int value = va_arg (list, int);
- int loop = value;
- if (value < 0)
- {
- value = 0;
- loop = 9;
- }
- loop -= value;
- ++loop;
-
- while (loop--)
- {
- _curChannel = value;
- Channel & channel = _channels[_curChannel];
- channel.priority = 0;
- channel.dataptr = 0;
- if (value != 9)
- {
- noteOff (channel);
- }
- ++value;
- }
-
- return 0;
-}
-
-int
-AdlibDriver::snd_readByte (va_list & list)
-{
- int a = va_arg (list, int);
- int b = va_arg (list, int);
- uint8 *ptr = getProgram (a) + b;
- return *ptr;
-}
-
-int
-AdlibDriver::snd_writeByte (va_list & list)
-{
- int a = va_arg (list, int);
- int b = va_arg (list, int);
- int c = va_arg (list, int);
- uint8 *ptr = getProgram (a) + b;
- uint8 oldValue = *ptr;
- *ptr = (uint8) c;
- return oldValue;
-}
-
-int
-AdlibDriver::snd_getSoundTrigger (va_list & list)
-{
- return _soundTrigger;
-}
-
-int
-AdlibDriver::snd_unkOpcode4 (va_list & list)
-{
- warning ("unimplemented snd_unkOpcode4");
- return 0;
-}
-
-int
-AdlibDriver::snd_dummy (va_list & list)
-{
- return 0;
-}
-
-int
-AdlibDriver::snd_getNullvar4 (va_list & list)
-{
- warning ("unimplemented snd_getNullvar4");
- return 0;
-}
-
-int
-AdlibDriver::snd_setNullvar3 (va_list & list)
-{
- warning ("unimplemented snd_setNullvar3");
- return 0;
-}
-
-int
-AdlibDriver::snd_setFlag (va_list & list)
-{
- int oldFlags = _flags;
- _flags |= va_arg (list, int);
- return oldFlags;
-}
-
-int
-AdlibDriver::snd_clearFlag (va_list & list)
-{
- int oldFlags = _flags;
- _flags &= ~(va_arg (list, int));
- return oldFlags;
-}
-
-// timer callback
-
-void
-AdlibDriver::callback ()
-{
- // lock();
- --_flagTrigger;
- if (_flagTrigger < 0)
- _flags &= ~8;
- setupPrograms ();
- executePrograms ();
-
- uint8 temp = _unkValue3;
- _unkValue3 += _tempo;
- if (_unkValue3 < temp)
- {
- if (!(--_unkValue2))
- {
- _unkValue2 = _unkValue1;
- ++_unkValue4;
- }
- }
- // unlock();
-}
-
-void
-AdlibDriver::setupPrograms ()
-{
- while (_lastProcessed != _soundsPlaying)
- {
- uint8 *ptr = getProgram (_soundIdTable[_lastProcessed]);
- uint8 chan = *ptr++;
- uint8 priority = *ptr++;
-
- // Only start this sound if its priority is higher than the one
- // already playing.
-
- Channel & channel = _channels[chan];
-
- if (priority >= channel.priority)
- {
- initChannel (channel);
- channel.priority = priority;
- channel.dataptr = ptr;
- channel.tempo = 0xFF;
- channel.position = 0xFF;
- channel.duration = 1;
- unkOutput2 (chan);
- }
-
- ++_lastProcessed;
- _lastProcessed &= 0x0F;
- }
-}
-
-// A few words on opcode parsing and timing:
-//
-// First of all, We simulate a timer callback 72 times per second. Each timeout
-// we update each channel that has something to play.
-//
-// Each channel has its own individual tempo, which is added to its position.
-// This will frequently cause the position to "wrap around" but that is
-// intentional. In fact, it's the signal to go ahead and do more stuff with
-// that channel.
-//
-// Each channel also has a duration, indicating how much time is left on the
-// its current task. This duration is decreased by one. As long as it still has
-// not reached zero, the only thing that can happen is that the note is turned
-// off depending on manual or automatic note spacing. Once the duration reaches
-// zero, a new set of musical opcodes are executed.
-//
-// An opcode is one byte, followed by a variable number of parameters. Since
-// most opcodes have at least one one-byte parameter, we read that as well. Any
-// opcode that doesn't have that one parameter is responsible for moving the
-// data pointer back again.
-//
-// If the most significant bit of the opcode is 1, it's a function; call it.
-// The opcode functions return either 0 (continue), 1 (stop) or 2 (stop, and do
-// not run the effects callbacks).
-//
-// If the most significant bit of the opcode is 0, it's a note, and the first
-// parameter is its duration. (There are cases where the duration is modified
-// but that's an exception.) The note opcode is assumed to return 1, and is the
-// last opcode unless its duration is zero.
-//
-// Finally, most of the times that the callback is called, it will invoke the
-// effects callbacks. The final opcode in a set can prevent this, if it's a
-// function and it returns anything other than 1.
-
-void
-AdlibDriver::executePrograms ()
-{
- // Each channel runs its own program. There are ten channels: One for
- // each Adlib channel (0-8), plus one "control channel" (9) which is
- // the one that tells the other channels what to do.
-
- for (_curChannel = 9; _curChannel >= 0; --_curChannel)
- {
- int result = 1;
-
- if (!_channels[_curChannel].dataptr)
- {
- continue;
- }
-
- Channel & channel = _channels[_curChannel];
- _curRegOffset = _regOffset[_curChannel];
-
- if (channel.tempoReset)
- {
- channel.tempo = _tempo;
- }
-
- uint8 backup = channel.position;
- channel.position += channel.tempo;
- if (channel.position < backup)
- {
- if (--channel.duration)
- {
- if (channel.duration == channel.spacing2)
- noteOff (channel);
- if (channel.duration == channel.spacing1 && _curChannel != 9)
- noteOff (channel);
- }
- else
- {
- // An opcode is not allowed to modify its own
- // data pointer except through the 'dataptr'
- // parameter. To enforce that, we have to work
- // on a copy of the data pointer.
- //
- // This fixes a subtle music bug where the
- // wrong music would play when getting the
- // quill in Kyra 1.
- uint8 *dataptr = channel.dataptr;
- while (dataptr)
- {
- uint8 opcode = *dataptr++;
- uint8 param = *dataptr++;
-
- if (opcode & 0x80)
- {
- opcode &= 0x7F;
- if (opcode >= _parserOpcodeTableSize)
- opcode = _parserOpcodeTableSize - 1;
- debugC (9, kDebugLevelSound,
- "Calling opcode '%s' (%d) (channel: %d)",
- _parserOpcodeTable[opcode].name, opcode, _curChannel);
- result =
- (this->*(_parserOpcodeTable[opcode].function)) (dataptr,
- channel, param);
- channel.dataptr = dataptr;
- if (result)
- break;
- }
- else
- {
- debugC (9, kDebugLevelSound,
- "Note on opcode 0x%02X (duration: %d) (channel: %d)",
- opcode, param, _curChannel);
- setupNote (opcode, channel);
- noteOn (channel);
- setupDuration (param, channel);
- if (param)
- {
- channel.dataptr = dataptr;
- break;
- }
- }
- }
- }
- }
-
- if (result == 1)
- {
- if (channel.primaryEffect)
- (this->*(channel.primaryEffect)) (channel);
- if (channel.secondaryEffect)
- (this->*(channel.secondaryEffect)) (channel);
- }
- }
-}
-
-//
-
-void
-AdlibDriver::resetAdlibState ()
-{
- debugC (9, kDebugLevelSound, "resetAdlibState()");
- _rnd = 0x1234;
-
- // Authorize the control of the waveforms
- writeOPL (0x01, 0x20);
-
- // Select FM music mode
- writeOPL (0x08, 0x00);
-
- // I would guess the main purpose of this is to turn off the rhythm,
- // thus allowing us to use 9 melodic voices instead of 6.
- writeOPL (0xBD, 0x00);
-
- int loop = 10;
- while (loop--)
- {
- if (loop != 9)
- {
- // Silence the channel
- writeOPL (0x40 + _regOffset[loop], 0x3F);
- writeOPL (0x43 + _regOffset[loop], 0x3F);
- }
- initChannel (_channels[loop]);
- }
-}
-
-// Old calling style: output0x388(0xABCD)
-// New calling style: writeOPL(0xAB, 0xCD)
-
-void
-AdlibDriver::writeOPL (byte reg, byte val)
-{
- opl->write (reg, val);
-}
-
-void
-AdlibDriver::initChannel (Channel & channel)
-{
- debugC (9, kDebugLevelSound, "initChannel(%lu)",
- (long) (&channel - _channels));
- memset (&channel.dataptr, 0,
- sizeof (Channel) - ((char *) &channel.dataptr - (char *) &channel));
-
- channel.tempo = 0xFF;
- channel.priority = 0;
- // normally here are nullfuncs but we set 0 for now
- channel.primaryEffect = 0;
- channel.secondaryEffect = 0;
- channel.spacing1 = 1;
-}
-
-void
-AdlibDriver::noteOff (Channel & channel)
-{
- debugC (9, kDebugLevelSound, "noteOff(%lu)", (long) (&channel - _channels));
-
- // The control channel has no corresponding Adlib channel
-
- if (_curChannel >= 9)
- return;
-
- // When the rhythm section is enabled, channels 6, 7 and 8 are special.
-
- if (_rhythmSectionBits && _curChannel >= 6)
- return;
-
- // This means the "Key On" bit will always be 0
- channel.regBx &= 0xDF;
-
- // Octave / F-Number / Key-On
- writeOPL (0xB0 + _curChannel, channel.regBx);
-}
-
-void
-AdlibDriver::unkOutput2 (uint8 chan)
-{
- debugC (9, kDebugLevelSound, "unkOutput2(%d)", chan);
-
- // The control channel has no corresponding Adlib channel
-
- if (chan >= 9)
- return;
-
- // I believe this has to do with channels 6, 7, and 8 being special
- // when Adlib's rhythm section is enabled.
-
- if (_rhythmSectionBits && chan >= 6)
- return;
-
- uint8 offset = _regOffset[chan];
-
- // The channel is cleared: First the attack/delay rate, then the
- // sustain level/release rate, and finally the note is turned off.
-
- writeOPL (0x60 + offset, 0xFF);
- writeOPL (0x63 + offset, 0xFF);
-
- writeOPL (0x80 + offset, 0xFF);
- writeOPL (0x83 + offset, 0xFF);
-
- writeOPL (0xB0 + chan, 0x00);
-
- // ...and then the note is turned on again, with whatever value is
- // still lurking in the A0 + chan register, but everything else -
- // including the two most significant frequency bit, and the octave -
- // set to zero.
- //
- // This is very strange behaviour, and causes problems with the ancient
- // FMOPL code we borrowed from AdPlug. I've added a workaround. See
- // fmopl.cpp for more details.
- //
- // More recent versions of the MAME FMOPL don't seem to have this
- // problem, but cannot currently be used because of licensing and
- // performance issues.
- //
- // Ken Silverman's Adlib emulator (which can be found on his Web page -
- // http://www.advsys.net/ken - and as part of AdPlug) also seems to be
- // immune, but is apparently not as feature complete as MAME's.
-
- writeOPL (0xB0 + chan, 0x20);
-}
-
-// I believe this is a random number generator. It actually does seem to
-// generate an even distribution of almost all numbers from 0 through 65535,
-// though in my tests some numbers were never generated.
-
-uint16
-AdlibDriver::getRandomNr ()
-{
- _rnd += 0x9248;
- uint16 lowBits = _rnd & 7;
- _rnd >>= 3;
- _rnd |= (lowBits << 13);
- return _rnd;
-}
-
-void
-AdlibDriver::setupDuration (uint8 duration, Channel & channel)
-{
- debugC (9, kDebugLevelSound, "setupDuration(%d, %lu)", duration,
- (long) (&channel - _channels));
- if (channel.durationRandomness)
- {
- channel.duration =
- duration + (getRandomNr () & channel.durationRandomness);
- return;
- }
- if (channel.fractionalSpacing)
- {
- channel.spacing2 = (duration >> 3) * channel.fractionalSpacing;
- }
- channel.duration = duration;
-}
-
-// This function may or may not play the note. It's usually followed by a call
-// to noteOn(), which will always play the current note.
-
-void
-AdlibDriver::setupNote (uint8 rawNote, Channel & channel, bool flag)
-{
- debugC (9, kDebugLevelSound, "setupNote(%d, %lu)", rawNote,
- (long) (&channel - _channels));
-
- channel.rawNote = rawNote;
-
- int8 note = (rawNote & 0x0F) + channel.baseNote;
- int8 octave = ((rawNote + channel.baseOctave) >> 4) & 0x0F;
-
- // There are only twelve notes. If we go outside that, we have to
- // adjust the note and octave.
-
- if (note >= 12)
- {
- note -= 12;
- octave++;
- }
- else if (note < 0)
- {
- note += 12;
- octave--;
- }
-
- // The calculation of frequency looks quite different from the original
- // disassembly at a first glance, but when you consider that the
- // largest possible value would be 0x0246 + 0xFF + 0x47 (and that's if
- // baseFreq is unsigned), freq is still a 10-bit value, just as it
- // should be to fit in the Ax and Bx registers.
- //
- // If it were larger than that, it could have overflowed into the
- // octave bits, and that could possibly have been used in some sound.
- // But as it is now, I can't see any way it would happen.
-
- uint16 freq = _unkTable[note] + channel.baseFreq;
-
- // When called from callback 41, the behaviour is slightly different:
- // We adjust the frequency, even when channel.unk16 is 0.
-
- if (channel.unk16 || flag)
- {
- const uint8 *table;
-
- if (channel.unk16 >= 0)
- {
- table = _unkTables[(channel.rawNote & 0x0F) + 2];
- freq += table[channel.unk16];
- }
- else
- {
- table = _unkTables[channel.rawNote & 0x0F];
- freq -= table[-channel.unk16];
- }
- }
-
- channel.regAx = freq & 0xFF;
- channel.regBx =
- (channel.regBx & 0x20) | (octave << 2) | ((freq >> 8) & 0x03);
-
- // Keep the note on or off
- writeOPL (0xA0 + _curChannel, channel.regAx);
- writeOPL (0xB0 + _curChannel, channel.regBx);
-}
-
-void
-AdlibDriver::setupInstrument (uint8 regOffset, uint8 * dataptr,
- Channel & channel)
-{
- debugC (9, kDebugLevelSound, "setupInstrument(%d, %p, %lu)", regOffset,
- (const void *) dataptr, (long) (&channel - _channels));
- // Amplitude Modulation / Vibrato / Envelope Generator Type /
- // Keyboard Scaling Rate / Modulator Frequency Multiple
- writeOPL (0x20 + regOffset, *dataptr++);
- writeOPL (0x23 + regOffset, *dataptr++);
-
- uint8 temp = *dataptr++;
-
- // Feedback / Algorithm
-
- // It is very likely that _curChannel really does refer to the same
- // channel as regOffset, but there's only one Cx register per channel.
-
- writeOPL (0xC0 + _curChannel, temp);
-
- // The algorithm bit. I don't pretend to understand this fully, but
- // "If set to 0, operator 1 modulates operator 2. In this case,
- // operator 2 is the only one producing sound. If set to 1, both
- // operators produce sound directly. Complex sounds are more easily
- // created if the algorithm is set to 0."
-
- channel.twoChan = temp & 1;
-
- // Waveform Select
- writeOPL (0xE0 + regOffset, *dataptr++);
- writeOPL (0xE3 + regOffset, *dataptr++);
-
- channel.opLevel1 = *dataptr++;
- channel.opLevel2 = *dataptr++;
-
- // Level Key Scaling / Total Level
- writeOPL (0x40 + regOffset, calculateOpLevel1 (channel));
- writeOPL (0x43 + regOffset, calculateOpLevel2 (channel));
-
- // Attack Rate / Decay Rate
- writeOPL (0x60 + regOffset, *dataptr++);
- writeOPL (0x63 + regOffset, *dataptr++);
-
- // Sustain Level / Release Rate
- writeOPL (0x80 + regOffset, *dataptr++);
- writeOPL (0x83 + regOffset, *dataptr++);
-}
-
-// Apart from playing the note, this function also updates the variables for
-// primary effect 2.
-
-void
-AdlibDriver::noteOn (Channel & channel)
-{
- debugC (9, kDebugLevelSound, "noteOn(%lu)", (long) (&channel - _channels));
-
- // The "note on" bit is set, and the current note is played.
-
- channel.regBx |= 0x20;
- writeOPL (0xB0 + _curChannel, channel.regBx);
-
- int8 shift = 9 - channel.unk33;
- uint16 temp = channel.regAx | (channel.regBx << 8);
- channel.unk37 = ((temp & 0x3FF) >> shift) & 0xFF;
- channel.unk38 = channel.unk36;
-}
-
-void
-AdlibDriver::adjustVolume (Channel & channel)
-{
- debugC (9, kDebugLevelSound, "adjustVolume(%lu)",
- (long) (&channel - _channels));
- // Level Key Scaling / Total Level
-
- writeOPL (0x43 + _regOffset[_curChannel], calculateOpLevel2 (channel));
- if (channel.twoChan)
- writeOPL (0x40 + _regOffset[_curChannel], calculateOpLevel1 (channel));
-}
-
-// This is presumably only used for some sound effects, e.g. Malcolm blowing up
-// the trees in the intro (but not the effect where he "booby-traps" the big
-// tree) and turning Kallak to stone. Related functions and variables:
-//
-// update_setupPrimaryEffect1()
-// - Initialises unk29, unk30 and unk31
-// - unk29 is not further modified
-// - unk30 is not further modified, except by update_removePrimaryEffect1()
-//
-// update_removePrimaryEffect1()
-// - Deinitialises unk30
-//
-// unk29 - determines how often the notes are played
-// unk30 - modifies the frequency
-// unk31 - determines how often the notes are played
-
-void
-AdlibDriver::primaryEffect1 (Channel & channel)
-{
- debugC (9, kDebugLevelSound, "Calling primaryEffect1 (channel: %d)",
- _curChannel);
- uint8 temp = channel.unk31;
- channel.unk31 += channel.unk29;
- if (channel.unk31 >= temp)
- return;
-
- // Initialise unk1 to the current frequency
- uint16 unk1 = ((channel.regBx & 3) << 8) | channel.regAx;
-
- // This is presumably to shift the "note on" bit so far to the left
- // that it won't be affected by any of the calculations below.
- uint16 unk2 = ((channel.regBx & 0x20) << 8) | (channel.regBx & 0x1C);
-
- int16 unk3 = (int16) channel.unk30;
-
- if (unk3 >= 0)
- {
- unk1 += unk3;
- if (unk1 >= 734)
- {
- // The new frequency is too high. Shift it down and go
- // up one octave.
- unk1 >>= 1;
- if (!(unk1 & 0x3FF))
- ++unk1;
- unk2 = (unk2 & 0xFF00) | ((unk2 + 4) & 0xFF);
- unk2 &= 0xFF1C;
- }
- }
- else
- {
- unk1 += unk3;
- if (unk1 < 388)
- {
- // The new frequency is too low. Shift it up and go
- // down one octave.
- unk1 <<= 1;
- if (!(unk1 & 0x3FF))
- --unk1;
- unk2 = (unk2 & 0xFF00) | ((unk2 - 4) & 0xFF);
- unk2 &= 0xFF1C;
- }
- }
-
- // Make sure that the new frequency is still a 10-bit value.
- unk1 &= 0x3FF;
-
- writeOPL (0xA0 + _curChannel, unk1 & 0xFF);
- channel.regAx = unk1 & 0xFF;
-
- // Shift down the "note on" bit again.
- uint8 value = unk1 >> 8;
- value |= (unk2 >> 8) & 0xFF;
- value |= unk2 & 0xFF;
-
- writeOPL (0xB0 + _curChannel, value);
- channel.regBx = value;
-}
-
-// This is presumably only used for some sound effects, e.g. Malcolm entering
-// and leaving Kallak's hut. Related functions and variables:
-//
-// update_setupPrimaryEffect2()
-// - Initialises unk32, unk33, unk34, unk35 and unk36
-// - unk32 is not further modified
-// - unk33 is not further modified
-// - unk34 is a countdown that gets reinitialised to unk35 on zero
-// - unk35 is based on unk34 and not further modified
-// - unk36 is not further modified
-//
-// noteOn()
-// - Plays the current note
-// - Updates unk37 with a new (lower?) frequency
-// - Copies unk36 to unk38. The unk38 variable is a countdown.
-//
-// unk32 - determines how often the notes are played
-// unk33 - modifies the frequency
-// unk34 - countdown, updates frequency on zero
-// unk35 - initialiser for unk34 countdown
-// unk36 - initialiser for unk38 countdown
-// unk37 - frequency
-// unk38 - countdown, begins playing on zero
-// unk41 - determines how often the notes are played
-//
-// Note that unk41 is never initialised. Not that it should matter much, but it
-// is a bit sloppy.
-
-void
-AdlibDriver::primaryEffect2 (Channel & channel)
-{
- debugC (9, kDebugLevelSound, "Calling primaryEffect2 (channel: %d)",
- _curChannel);
- if (channel.unk38)
- {
- --channel.unk38;
- return;
- }
-
- uint8 temp = channel.unk41;
- channel.unk41 += channel.unk32;
- if (channel.unk41 < temp)
- {
- uint16 unk1 = channel.unk37;
- if (!(--channel.unk34))
- {
- unk1 ^= 0xFFFF;
- ++unk1;
- channel.unk37 = unk1;
- channel.unk34 = channel.unk35;
- }
-
- uint16 unk2 = (channel.regAx | (channel.regBx << 8)) & 0x3FF;
- unk2 += unk1;
-
- channel.regAx = unk2 & 0xFF;
- channel.regBx = (channel.regBx & 0xFC) | (unk2 >> 8);
-
- // Octave / F-Number / Key-On
- writeOPL (0xA0 + _curChannel, channel.regAx);
- writeOPL (0xB0 + _curChannel, channel.regBx);
- }
-}
-
-// I don't know where this is used. The same operation is performed several
-// times on the current channel, using a chunk of the _soundData[] buffer for
-// parameters. The parameters are used starting at the end of the chunk.
-//
-// Since we use _curRegOffset to specify the final register, it's quite
-// unlikely that this function is ever used to play notes. It's probably only
-// used to modify the sound. Another thing that supports this idea is that it
-// can be combined with any of the effects callbacks above.
-//
-// Related functions and variables:
-//
-// update_setupSecondaryEffect1()
-// - Initialies unk18, unk19, unk20, unk21, unk22 and offset
-// - unk19 is not further modified
-// - unk20 is not further modified
-// - unk22 is not further modified
-// - offset is not further modified
-//
-// unk18 - determines how often the operation is performed
-// unk19 - determines how often the operation is performed
-// unk20 - the start index into the data chunk
-// unk21 - the current index into the data chunk
-// unk22 - the operation to perform
-// offset - the offset to the data chunk
-
-void
-AdlibDriver::secondaryEffect1 (Channel & channel)
-{
- debugC (9, kDebugLevelSound, "Calling secondaryEffect1 (channel: %d)",
- _curChannel);
- uint8 temp = channel.unk18;
- channel.unk18 += channel.unk19;
- if (channel.unk18 < temp)
- {
- if (--channel.unk21 < 0)
- {
- channel.unk21 = channel.unk20;
- }
- writeOPL (channel.unk22 + _curRegOffset,
- _soundData[channel.offset + channel.unk21]);
- }
-}
-
-uint8
-AdlibDriver::calculateOpLevel1 (Channel & channel)
-{
- int8 value = channel.opLevel1 & 0x3F;
-
- if (channel.twoChan)
- {
- value += channel.opExtraLevel1;
- value += channel.opExtraLevel2;
- value += channel.opExtraLevel3;
- }
-
- // Preserve the scaling level bits from opLevel1
-
- return checkValue (value) | (channel.opLevel1 & 0xC0);
-}
-
-uint8
-AdlibDriver::calculateOpLevel2 (Channel & channel)
-{
- int8 value = channel.opLevel2 & 0x3F;
-
- value += channel.opExtraLevel1;
- value += channel.opExtraLevel2;
- value += channel.opExtraLevel3;
-
- // Preserve the scaling level bits from opLevel2
-
- return checkValue (value) | (channel.opLevel2 & 0xC0);
-}
-
-// parser opcodes
-
-int
-AdlibDriver::update_setRepeat (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.repeatCounter = value;
- return 0;
-}
-
-int
-AdlibDriver::update_checkRepeat (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- ++dataptr;
- if (--channel.repeatCounter)
- {
- int16 add = READ_LE_UINT16 (dataptr - 2);
- dataptr += add;
- }
- return 0;
-}
-
-int
-AdlibDriver::update_setupProgram (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- if (value == 0xFF)
- return 0;
-
- uint8 *ptr = getProgram (value);
- uint8 chan = *ptr++;
- uint8 priority = *ptr++;
-
- Channel & channel2 = _channels[chan];
-
- if (priority >= channel2.priority)
- {
- _flagTrigger = 1;
- _flags |= 8;
- initChannel (channel2);
- channel2.priority = priority;
- channel2.dataptr = ptr;
- channel2.tempo = 0xFF;
- channel2.position = 0xFF;
- channel2.duration = 1;
- unkOutput2 (chan);
- }
-
- return 0;
-}
-
-int
-AdlibDriver::update_setNoteSpacing (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.spacing1 = value;
- return 0;
-}
-
-int
-AdlibDriver::update_jump (uint8 * &dataptr, Channel & channel, uint8 value)
-{
- --dataptr;
- int16 add = READ_LE_UINT16 (dataptr);
- dataptr += 2;
- dataptr += add;
- return 0;
-}
-
-int
-AdlibDriver::update_jumpToSubroutine (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- --dataptr;
- int16 add = READ_LE_UINT16 (dataptr);
- dataptr += 2;
- channel.dataptrStack[channel.dataptrStackPos++] = dataptr;
- dataptr += add;
- return 0;
-}
-
-int
-AdlibDriver::update_returnFromSubroutine (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- dataptr = channel.dataptrStack[--channel.dataptrStackPos];
- return 0;
-}
-
-int
-AdlibDriver::update_setBaseOctave (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.baseOctave = value;
- return 0;
-}
-
-int
-AdlibDriver::update_stopChannel (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.priority = 0;
- if (_curChannel != 9)
- {
- noteOff (channel);
- }
- dataptr = 0;
- return 2;
-}
-
-int
-AdlibDriver::update_playRest (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- setupDuration (value, channel);
- noteOff (channel);
- return (value != 0);
-}
-
-int
-AdlibDriver::update_writeAdlib (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- writeOPL (value, *dataptr++);
- return 0;
-}
-
-int
-AdlibDriver::update_setupNoteAndDuration (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- setupNote (value, channel);
- value = *dataptr++;
- setupDuration (value, channel);
- return (value != 0);
-}
-
-int
-AdlibDriver::update_setBaseNote (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.baseNote = value;
- return 0;
-}
-
-int
-AdlibDriver::update_setupSecondaryEffect1 (uint8 * &dataptr,
- Channel & channel, uint8 value)
-{
- channel.unk18 = value;
- channel.unk19 = value;
- channel.unk20 = channel.unk21 = *dataptr++;
- channel.unk22 = *dataptr++;
- channel.offset = READ_LE_UINT16 (dataptr);
- dataptr += 2;
- channel.secondaryEffect = &AdlibDriver::secondaryEffect1;
- return 0;
-}
-
-int
-AdlibDriver::update_stopOtherChannel (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- Channel & channel2 = _channels[value];
- channel2.duration = 0;
- channel2.priority = 0;
- channel2.dataptr = 0;
- return 0;
-}
-
-int
-AdlibDriver::update_waitForEndOfProgram (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- uint8 *ptr = getProgram (value);
- uint8 chan = *ptr;
-
- if (!_channels[chan].dataptr)
- {
- return 0;
- }
-
- dataptr -= 2;
- return 2;
-}
-
-int
-AdlibDriver::update_setupInstrument (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- setupInstrument (_curRegOffset, getInstrument (value), channel);
- return 0;
-}
-
-int
-AdlibDriver::update_setupPrimaryEffect1 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.unk29 = value;
- channel.unk30 = READ_BE_UINT16 (dataptr);
- dataptr += 2;
- channel.primaryEffect = &AdlibDriver::primaryEffect1;
- channel.unk31 = 0xFF;
- return 0;
-}
-
-int
-AdlibDriver::update_removePrimaryEffect1 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- --dataptr;
- channel.primaryEffect = 0;
- channel.unk30 = 0;
- return 0;
-}
-
-int
-AdlibDriver::update_setBaseFreq (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.baseFreq = value;
- return 0;
-}
-
-int
-AdlibDriver::update_setupPrimaryEffect2 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.unk32 = value;
- channel.unk33 = *dataptr++;
- uint8 temp = *dataptr++;
- channel.unk34 = temp + 1;
- channel.unk35 = temp << 1;
- channel.unk36 = *dataptr++;
- channel.primaryEffect = &AdlibDriver::primaryEffect2;
- return 0;
-}
-
-int
-AdlibDriver::update_setPriority (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.priority = value;
- return 0;
-}
-
-int
-AdlibDriver::updateCallback23 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- value >>= 1;
- _unkValue1 = _unkValue2 = value;
- _unkValue3 = 0xFF;
- _unkValue4 = _unkValue5 = 0;
- return 0;
-}
-
-int
-AdlibDriver::updateCallback24 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- if (_unkValue5)
- {
- if (_unkValue4 & value)
- {
- _unkValue5 = 0;
- return 0;
- }
- }
-
- if (!(value & _unkValue4))
- {
- ++_unkValue5;
- }
-
- dataptr -= 2;
- channel.duration = 1;
- return 2;
-}
-
-int
-AdlibDriver::update_setExtraLevel1 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.opExtraLevel1 = value;
- adjustVolume (channel);
- return 0;
-}
-
-int
-AdlibDriver::update_setupDuration (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- setupDuration (value, channel);
- return (value != 0);
-}
-
-int
-AdlibDriver::update_playNote (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- setupDuration (value, channel);
- noteOn (channel);
- return (value != 0);
-}
-
-int
-AdlibDriver::update_setFractionalNoteSpacing (uint8 * &dataptr,
- Channel & channel, uint8 value)
-{
- channel.fractionalSpacing = value & 7;
- return 0;
-}
-
-int
-AdlibDriver::update_setTempo (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- _tempo = value;
- return 0;
-}
-
-int
-AdlibDriver::update_removeSecondaryEffect1 (uint8 * &dataptr,
- Channel & channel, uint8 value)
-{
- --dataptr;
- channel.secondaryEffect = 0;
- return 0;
-}
-
-int
-AdlibDriver::update_setChannelTempo (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.tempo = value;
- return 0;
-}
-
-int
-AdlibDriver::update_setExtraLevel3 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.opExtraLevel3 = value;
- return 0;
-}
-
-int
-AdlibDriver::update_setExtraLevel2 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- int channelBackUp = _curChannel;
-
- _curChannel = value;
- Channel & channel2 = _channels[value];
- channel2.opExtraLevel2 = *dataptr++;
- adjustVolume (channel2);
-
- _curChannel = channelBackUp;
- return 0;
-}
-
-int
-AdlibDriver::update_changeExtraLevel2 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- int channelBackUp = _curChannel;
-
- _curChannel = value;
- Channel & channel2 = _channels[value];
- channel2.opExtraLevel2 += *dataptr++;
- adjustVolume (channel2);
-
- _curChannel = channelBackUp;
- return 0;
-}
-
-// Apart from initialising to zero, these two functions are the only ones that
-// modify _vibratoAndAMDepthBits.
-
-int
-AdlibDriver::update_setAMDepth (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- if (value & 1)
- _vibratoAndAMDepthBits |= 0x80;
- else
- _vibratoAndAMDepthBits &= 0x7F;
-
- writeOPL (0xBD, _vibratoAndAMDepthBits);
- return 0;
-}
-
-int
-AdlibDriver::update_setVibratoDepth (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- if (value & 1)
- _vibratoAndAMDepthBits |= 0x40;
- else
- _vibratoAndAMDepthBits &= 0xBF;
-
- writeOPL (0xBD, _vibratoAndAMDepthBits);
- return 0;
-}
-
-int
-AdlibDriver::update_changeExtraLevel1 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.opExtraLevel1 += value;
- adjustVolume (channel);
- return 0;
-}
-
-int
-AdlibDriver::updateCallback38 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- int channelBackUp = _curChannel;
-
- _curChannel = value;
- Channel & channel2 = _channels[value];
- channel2.duration = channel2.priority = 0;
- channel2.dataptr = 0;
- channel2.opExtraLevel2 = 0;
-
- if (value != 9)
- {
- uint8 outValue = _regOffset[value];
-
- // Feedback strength / Connection type
- writeOPL (0xC0 + _curChannel, 0x00);
-
- // Key scaling level / Operator output level
- writeOPL (0x43 + outValue, 0x3F);
-
- // Sustain Level / Release Rate
- writeOPL (0x83 + outValue, 0xFF);
-
- // Key On / Octave / Frequency
- writeOPL (0xB0 + _curChannel, 0x00);
- }
-
- _curChannel = channelBackUp;
- return 0;
-}
-
-int
-AdlibDriver::updateCallback39 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- uint16 unk = *dataptr++;
- unk |= value << 8;
- unk &= getRandomNr ();
-
- uint16 unk2 = ((channel.regBx & 0x1F) << 8) | channel.regAx;
- unk2 += unk;
- unk2 |= ((channel.regBx & 0x20) << 8);
-
- // Frequency
- writeOPL (0xA0 + _curChannel, unk2 & 0xFF);
-
- // Key On / Octave / Frequency
- writeOPL (0xB0 + _curChannel, (unk2 & 0xFF00) >> 8);
-
- return 0;
-}
-
-int
-AdlibDriver::update_removePrimaryEffect2 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- --dataptr;
- channel.primaryEffect = 0;
- return 0;
-}
-
-int
-AdlibDriver::updateCallback41 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.unk16 = value;
- setupNote (channel.rawNote, channel, true);
- return 0;
-}
-
-int
-AdlibDriver::update_resetToGlobalTempo (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- --dataptr;
- channel.tempo = _tempo;
- return 0;
-}
-
-int
-AdlibDriver::update_nop1 (uint8 * &dataptr, Channel & channel, uint8 value)
-{
- --dataptr;
- return 0;
-}
-
-int
-AdlibDriver::update_setDurationRandomness (uint8 * &dataptr,
- Channel & channel, uint8 value)
-{
- channel.durationRandomness = value;
- return 0;
-}
-
-int
-AdlibDriver::update_changeChannelTempo (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- int tempo = channel.tempo + (int8) value;
-
- if (tempo <= 0)
- tempo = 1;
- else if (tempo > 255)
- tempo = 255;
-
- channel.tempo = tempo;
- return 0;
-}
-
-int
-AdlibDriver::updateCallback46 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- uint8 entry = *dataptr++;
- _tablePtr1 = _unkTable2[entry++];
- _tablePtr2 = _unkTable2[entry];
- if (value == 2)
- {
- // Frequency
- writeOPL (0xA0, _tablePtr2[0]);
- }
- return 0;
-}
-
-// TODO: This is really the same as update_nop1(), so they should be combined
-// into one single update_nop().
-
-int
-AdlibDriver::update_nop2 (uint8 * &dataptr, Channel & channel, uint8 value)
-{
- --dataptr;
- return 0;
-}
-
-int
-AdlibDriver::update_setupRhythmSection (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- int channelBackUp = _curChannel;
- int regOffsetBackUp = _curRegOffset;
-
- _curChannel = 6;
- _curRegOffset = _regOffset[6];
-
- setupInstrument (_curRegOffset, getInstrument (value), channel);
- _unkValue6 = channel.opLevel2;
-
- _curChannel = 7;
- _curRegOffset = _regOffset[7];
-
- setupInstrument (_curRegOffset, getInstrument (*dataptr++), channel);
- _unkValue7 = channel.opLevel1;
- _unkValue8 = channel.opLevel2;
-
- _curChannel = 8;
- _curRegOffset = _regOffset[8];
-
- setupInstrument (_curRegOffset, getInstrument (*dataptr++), channel);
- _unkValue9 = channel.opLevel1;
- _unkValue10 = channel.opLevel2;
-
- // Octave / F-Number / Key-On for channels 6, 7 and 8
-
- _channels[6].regBx = *dataptr++ & 0x2F;
- writeOPL (0xB6, _channels[6].regBx);
- writeOPL (0xA6, *dataptr++);
-
- _channels[7].regBx = *dataptr++ & 0x2F;
- writeOPL (0xB7, _channels[7].regBx);
- writeOPL (0xA7, *dataptr++);
-
- _channels[8].regBx = *dataptr++ & 0x2F;
- writeOPL (0xB8, _channels[8].regBx);
- writeOPL (0xA8, *dataptr++);
-
- _rhythmSectionBits = 0x20;
-
- _curRegOffset = regOffsetBackUp;
- _curChannel = channelBackUp;
- return 0;
-}
-
-int
-AdlibDriver::update_playRhythmSection (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- // Any instrument that we want to play, and which was already playing,
- // is temporarily keyed off. Instruments that were off already, or
- // which we don't want to play, retain their old on/off status. This is
- // probably so that the instrument's envelope is played from its
- // beginning again...
-
- writeOPL (0xBD, (_rhythmSectionBits & ~(value & 0x1F)) | 0x20);
-
- // ...but since we only set the rhythm instrument bits, and never clear
- // them (until the entire rhythm section is disabled), I'm not sure how
- // useful the cleverness above is. We could perhaps simply turn off all
- // the rhythm instruments instead.
-
- _rhythmSectionBits |= value;
-
- writeOPL (0xBD, _vibratoAndAMDepthBits | 0x20 | _rhythmSectionBits);
- return 0;
-}
-
-int
-AdlibDriver::update_removeRhythmSection (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- --dataptr;
- _rhythmSectionBits = 0;
-
- // All the rhythm bits are cleared. The AM and Vibrato depth bits
- // remain unchanged.
-
- writeOPL (0xBD, _vibratoAndAMDepthBits);
- return 0;
-}
-
-int
-AdlibDriver::updateCallback51 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- uint8 value2 = *dataptr++;
-
- if (value & 1)
- {
- _unkValue12 = value2;
-
- // Channel 7, op1: Level Key Scaling / Total Level
- writeOPL (0x51,
- checkValue (value2 + _unkValue7 + _unkValue11 + _unkValue12));
- }
-
- if (value & 2)
- {
- _unkValue14 = value2;
-
- // Channel 8, op2: Level Key Scaling / Total Level
- writeOPL (0x55,
- checkValue (value2 + _unkValue10 + _unkValue13 + _unkValue14));
- }
-
- if (value & 4)
- {
- _unkValue15 = value2;
-
- // Channel 8, op1: Level Key Scaling / Total Level
- writeOPL (0x52,
- checkValue (value2 + _unkValue9 + _unkValue16 + _unkValue15));
- }
-
- if (value & 8)
- {
- _unkValue18 = value2;
-
- // Channel 7, op2: Level Key Scaling / Total Level
- writeOPL (0x54,
- checkValue (value2 + _unkValue8 + _unkValue17 + _unkValue18));
- }
-
- if (value & 16)
- {
- _unkValue20 = value2;
-
- // Channel 6, op2: Level Key Scaling / Total Level
- writeOPL (0x53,
- checkValue (value2 + _unkValue6 + _unkValue19 + _unkValue20));
- }
-
- return 0;
-}
-
-int
-AdlibDriver::updateCallback52 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- uint8 value2 = *dataptr++;
-
- if (value & 1)
- {
- _unkValue11 =
- checkValue (value2 + _unkValue7 + _unkValue11 + _unkValue12);
-
- // Channel 7, op1: Level Key Scaling / Total Level
- writeOPL (0x51, _unkValue11);
- }
-
- if (value & 2)
- {
- _unkValue13 =
- checkValue (value2 + _unkValue10 + _unkValue13 + _unkValue14);
-
- // Channel 8, op2: Level Key Scaling / Total Level
- writeOPL (0x55, _unkValue13);
- }
-
- if (value & 4)
- {
- _unkValue16 =
- checkValue (value2 + _unkValue9 + _unkValue16 + _unkValue15);
-
- // Channel 8, op1: Level Key Scaling / Total Level
- writeOPL (0x52, _unkValue16);
- }
-
- if (value & 8)
- {
- _unkValue17 =
- checkValue (value2 + _unkValue8 + _unkValue17 + _unkValue18);
-
- // Channel 7, op2: Level Key Scaling / Total Level
- writeOPL (0x54, _unkValue17);
- }
-
- if (value & 16)
- {
- _unkValue19 =
- checkValue (value2 + _unkValue6 + _unkValue19 + _unkValue20);
-
- // Channel 6, op2: Level Key Scaling / Total Level
- writeOPL (0x53, _unkValue19);
- }
-
- return 0;
-}
-
-int
-AdlibDriver::updateCallback53 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- uint8 value2 = *dataptr++;
-
- if (value & 1)
- {
- _unkValue11 = value2;
-
- // Channel 7, op1: Level Key Scaling / Total Level
- writeOPL (0x51, checkValue (value2 + _unkValue7 + _unkValue12));
- }
-
- if (value & 2)
- {
- _unkValue13 = value2;
-
- // Channel 8, op2: Level Key Scaling / Total Level
- writeOPL (0x55, checkValue (value2 + _unkValue10 + _unkValue14));
- }
-
- if (value & 4)
- {
- _unkValue16 = value2;
-
- // Channel 8, op1: Level Key Scaling / Total Level
- writeOPL (0x52, checkValue (value2 + _unkValue9 + _unkValue15));
- }
-
- if (value & 8)
- {
- _unkValue17 = value2;
-
- // Channel 7, op2: Level Key Scaling / Total Level
- writeOPL (0x54, checkValue (value2 + _unkValue8 + _unkValue18));
- }
-
- if (value & 16)
- {
- _unkValue19 = value2;
-
- // Channel 6, op2: Level Key Scaling / Total Level
- writeOPL (0x53, checkValue (value2 + _unkValue6 + _unkValue20));
- }
-
- return 0;
-}
-
-int
-AdlibDriver::update_setSoundTrigger (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- _soundTrigger = value;
- return 0;
-}
-
-int
-AdlibDriver::update_setTempoReset (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.tempoReset = value;
- return 0;
-}
-
-int
-AdlibDriver::updateCallback56 (uint8 * &dataptr, Channel & channel,
- uint8 value)
-{
- channel.unk39 = value;
- channel.unk40 = *dataptr++;
- return 0;
-}
-
-// static res
-
-#define COMMAND(x) { &AdlibDriver::x, #x }
-
-void
-AdlibDriver::setupOpcodeList ()
-{
- static const OpcodeEntry opcodeList[] = {
- COMMAND (snd_ret0x100),
- COMMAND (snd_ret0x1983),
- COMMAND (snd_initDriver),
- COMMAND (snd_deinitDriver),
- COMMAND (snd_setSoundData),
- COMMAND (snd_unkOpcode1),
- COMMAND (snd_startSong),
- COMMAND (snd_unkOpcode2),
- COMMAND (snd_unkOpcode3),
- COMMAND (snd_readByte),
- COMMAND (snd_writeByte),
- COMMAND (snd_getSoundTrigger),
- COMMAND (snd_unkOpcode4),
- COMMAND (snd_dummy),
- COMMAND (snd_getNullvar4),
- COMMAND (snd_setNullvar3),
- COMMAND (snd_setFlag),
- COMMAND (snd_clearFlag)
- };
-
- _opcodeList = opcodeList;
- _opcodesEntries = ARRAYSIZE (opcodeList);
-}
-
-void
-AdlibDriver::setupParserOpcodeTable ()
-{
- static const ParserOpcode parserOpcodeTable[] = {
- // 0
- COMMAND (update_setRepeat),
- COMMAND (update_checkRepeat),
- COMMAND (update_setupProgram),
- COMMAND (update_setNoteSpacing),
-
- // 4
- COMMAND (update_jump),
- COMMAND (update_jumpToSubroutine),
- COMMAND (update_returnFromSubroutine),
- COMMAND (update_setBaseOctave),
-
- // 8
- COMMAND (update_stopChannel),
- COMMAND (update_playRest),
- COMMAND (update_writeAdlib),
- COMMAND (update_setupNoteAndDuration),
-
- // 12
- COMMAND (update_setBaseNote),
- COMMAND (update_setupSecondaryEffect1),
- COMMAND (update_stopOtherChannel),
- COMMAND (update_waitForEndOfProgram),
-
- // 16
- COMMAND (update_setupInstrument),
- COMMAND (update_setupPrimaryEffect1),
- COMMAND (update_removePrimaryEffect1),
- COMMAND (update_setBaseFreq),
-
- // 20
- COMMAND (update_stopChannel),
- COMMAND (update_setupPrimaryEffect2),
- COMMAND (update_stopChannel),
- COMMAND (update_stopChannel),
-
- // 24
- COMMAND (update_stopChannel),
- COMMAND (update_stopChannel),
- COMMAND (update_setPriority),
- COMMAND (update_stopChannel),
-
- // 28
- COMMAND (updateCallback23),
- COMMAND (updateCallback24),
- COMMAND (update_setExtraLevel1),
- COMMAND (update_stopChannel),
-
- // 32
- COMMAND (update_setupDuration),
- COMMAND (update_playNote),
- COMMAND (update_stopChannel),
- COMMAND (update_stopChannel),
-
- // 36
- COMMAND (update_setFractionalNoteSpacing),
- COMMAND (update_stopChannel),
- COMMAND (update_setTempo),
- COMMAND (update_removeSecondaryEffect1),
-
- // 40
- COMMAND (update_stopChannel),
- COMMAND (update_setChannelTempo),
- COMMAND (update_stopChannel),
- COMMAND (update_setExtraLevel3),
-
- // 44
- COMMAND (update_setExtraLevel2),
- COMMAND (update_changeExtraLevel2),
- COMMAND (update_setAMDepth),
- COMMAND (update_setVibratoDepth),
-
- // 48
- COMMAND (update_changeExtraLevel1),
- COMMAND (update_stopChannel),
- COMMAND (update_stopChannel),
- COMMAND (updateCallback38),
-
- // 52
- COMMAND (update_stopChannel),
- COMMAND (updateCallback39),
- COMMAND (update_removePrimaryEffect2),
- COMMAND (update_stopChannel),
-
- // 56
- COMMAND (update_stopChannel),
- COMMAND (updateCallback41),
- COMMAND (update_resetToGlobalTempo),
- COMMAND (update_nop1),
-
- // 60
- COMMAND (update_setDurationRandomness),
- COMMAND (update_changeChannelTempo),
- COMMAND (update_stopChannel),
- COMMAND (updateCallback46),
-
- // 64
- COMMAND (update_nop2),
- COMMAND (update_setupRhythmSection),
- COMMAND (update_playRhythmSection),
- COMMAND (update_removeRhythmSection),
-
- // 68
- COMMAND (updateCallback51),
- COMMAND (updateCallback52),
- COMMAND (updateCallback53),
- COMMAND (update_setSoundTrigger),
-
- // 72
- COMMAND (update_setTempoReset),
- COMMAND (updateCallback56),
- COMMAND (update_stopChannel)
- };
-
- _parserOpcodeTable = parserOpcodeTable;
- _parserOpcodeTableSize = ARRAYSIZE (parserOpcodeTable);
-}
-
-#undef COMMAND
-
-// This table holds the register offset for operator 1 for each of the nine
-// channels. To get the register offset for operator 2, simply add 3.
-
-const uint8
- AdlibDriver::_regOffset[] = {
- 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11,
- 0x12
-};
-
-// Given the size of this table, and the range of its values, it's probably the
-// F-Numbers (10 bits) for the notes of the 12-tone scale. However, it does not
-// match the table in the Adlib documentation I've seen.
-
-const uint16
- AdlibDriver::_unkTable[] = {
- 0x0134, 0x0147, 0x015A, 0x016F, 0x0184, 0x019C, 0x01B4, 0x01CE, 0x01E9,
- 0x0207, 0x0225, 0x0246
-};
-
-// These tables are currently only used by updateCallback46(), which only ever
-// uses the first element of one of the sub-tables.
-
-const uint8 *
- AdlibDriver::_unkTable2[] = {
- AdlibDriver::_unkTable2_1,
- AdlibDriver::_unkTable2_2,
- AdlibDriver::_unkTable2_1,
- AdlibDriver::_unkTable2_2,
- AdlibDriver::_unkTable2_3,
- AdlibDriver::_unkTable2_2
-};
-
-const uint8
- AdlibDriver::_unkTable2_1[] = {
- 0x50, 0x50, 0x4F, 0x4F, 0x4E, 0x4E, 0x4D, 0x4D,
- 0x4C, 0x4C, 0x4B, 0x4B, 0x4A, 0x4A, 0x49, 0x49,
- 0x48, 0x48, 0x47, 0x47, 0x46, 0x46, 0x45, 0x45,
- 0x44, 0x44, 0x43, 0x43, 0x42, 0x42, 0x41, 0x41,
- 0x40, 0x40, 0x3F, 0x3F, 0x3E, 0x3E, 0x3D, 0x3D,
- 0x3C, 0x3C, 0x3B, 0x3B, 0x3A, 0x3A, 0x39, 0x39,
- 0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35, 0x35,
- 0x34, 0x34, 0x33, 0x33, 0x32, 0x32, 0x31, 0x31,
- 0x30, 0x30, 0x2F, 0x2F, 0x2E, 0x2E, 0x2D, 0x2D,
- 0x2C, 0x2C, 0x2B, 0x2B, 0x2A, 0x2A, 0x29, 0x29,
- 0x28, 0x28, 0x27, 0x27, 0x26, 0x26, 0x25, 0x25,
- 0x24, 0x24, 0x23, 0x23, 0x22, 0x22, 0x21, 0x21,
- 0x20, 0x20, 0x1F, 0x1F, 0x1E, 0x1E, 0x1D, 0x1D,
- 0x1C, 0x1C, 0x1B, 0x1B, 0x1A, 0x1A, 0x19, 0x19,
- 0x18, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15,
- 0x14, 0x14, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11,
- 0x10, 0x10
-};
-
-// no don't ask me WHY this table exsits!
-const uint8
- AdlibDriver::_unkTable2_2[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x6F,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F
-};
-
-const uint8
- AdlibDriver::_unkTable2_3[] = {
- 0x40, 0x40, 0x40, 0x3F, 0x3F, 0x3F, 0x3E, 0x3E,
- 0x3E, 0x3D, 0x3D, 0x3D, 0x3C, 0x3C, 0x3C, 0x3B,
- 0x3B, 0x3B, 0x3A, 0x3A, 0x3A, 0x39, 0x39, 0x39,
- 0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36,
- 0x36, 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x33,
- 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31,
- 0x30, 0x30, 0x30, 0x2F, 0x2F, 0x2F, 0x2E, 0x2E,
- 0x2E, 0x2D, 0x2D, 0x2D, 0x2C, 0x2C, 0x2C, 0x2B,
- 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, 0x29, 0x29, 0x29,
- 0x28, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26,
- 0x26, 0x25, 0x25, 0x25, 0x24, 0x24, 0x24, 0x23,
- 0x23, 0x23, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21,
- 0x20, 0x20, 0x20, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E,
- 0x1E, 0x1D, 0x1D, 0x1D, 0x1C, 0x1C, 0x1C, 0x1B,
- 0x1B, 0x1B, 0x1A, 0x1A, 0x1A, 0x19, 0x19, 0x19,
- 0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16, 0x16,
- 0x16, 0x15
-};
-
-// This table is used to modify the frequency of the notes, depending on the
-// note value and unk16. In theory, we could very well try to access memory
-// outside this table, but in reality that probably won't happen.
-//
-// This could be some sort of pitch bend, but I have yet to see it used for
-// anything so it's hard to say.
-
-const uint8
- AdlibDriver::_unkTables[][32] = {
- // 0
- {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
- 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
- 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x19,
- 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21},
- // 1
- {0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x09,
- 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11,
- 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x1A,
- 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x22, 0x24},
- // 2
- {0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x09,
- 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13,
- 0x14, 0x15, 0x16, 0x17, 0x19, 0x1A, 0x1C, 0x1D,
- 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26},
- // 3
- {0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0A,
- 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13,
- 0x14, 0x15, 0x16, 0x17, 0x18, 0x1A, 0x1C, 0x1D,
- 0x1E, 0x1F, 0x20, 0x21, 0x23, 0x25, 0x27, 0x28},
- // 4
- {0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0A,
- 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x13, 0x15,
- 0x16, 0x17, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x20,
- 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x28, 0x2A},
- // 5
- {0x00, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B,
- 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15,
- 0x16, 0x17, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x20,
- 0x21, 0x22, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D},
- // 6
- {0x00, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B,
- 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15,
- 0x16, 0x17, 0x18, 0x1A, 0x1C, 0x1E, 0x21, 0x24,
- 0x25, 0x26, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x30},
- // 7
- {0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C,
- 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x18,
- 0x19, 0x1A, 0x1C, 0x1D, 0x1F, 0x21, 0x23, 0x25,
- 0x26, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x30, 0x32},
- // 8
- {0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0D,
- 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x14, 0x17, 0x1A,
- 0x19, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x25, 0x28,
- 0x29, 0x2A, 0x2B, 0x2D, 0x2F, 0x31, 0x33, 0x35},
- // 9
- {0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0E,
- 0x0F, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1B,
- 0x1C, 0x1D, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x29,
- 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x39},
- // 10
- {0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0E,
- 0x0F, 0x10, 0x12, 0x14, 0x16, 0x19, 0x1B, 0x1E,
- 0x1F, 0x21, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D,
- 0x2E, 0x2F, 0x31, 0x32, 0x34, 0x36, 0x39, 0x3C},
- // 11
- {0x00, 0x01, 0x03, 0x05, 0x07, 0x0A, 0x0C, 0x0F,
- 0x10, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1E,
- 0x1F, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2B, 0x2E,
- 0x2F, 0x30, 0x32, 0x34, 0x36, 0x39, 0x3C, 0x3F},
- // 12
- {0x00, 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x10,
- 0x11, 0x12, 0x14, 0x16, 0x18, 0x1B, 0x1E, 0x21,
- 0x22, 0x23, 0x25, 0x27, 0x29, 0x2C, 0x2F, 0x32,
- 0x33, 0x34, 0x36, 0x38, 0x3B, 0x34, 0x41, 0x44},
- // 13
- {0x00, 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x11,
- 0x12, 0x13, 0x15, 0x17, 0x1A, 0x1D, 0x20, 0x23,
- 0x24, 0x25, 0x27, 0x29, 0x2C, 0x2F, 0x32, 0x35,
- 0x36, 0x37, 0x39, 0x3B, 0x3E, 0x41, 0x44, 0x47}
-};
-
-// #pragma mark -
-
-// At the time of writing, the only known case where Kyra 1 uses sound triggers
-// is in the castle, to cycle between three different songs.
-
-const int
- CadlPlayer::_kyra1SoundTriggers[] = {
- 0, 4, 5, 3
-};
-
-const int
- CadlPlayer::_kyra1NumSoundTriggers =
-ARRAYSIZE (CadlPlayer::_kyra1SoundTriggers);
-
-CadlPlayer::CadlPlayer (Copl * newopl):CPlayer (newopl), numsubsongs (0), _trackEntries (),
-_soundDataPtr (0)
-{
- memset (_trackEntries, 0, sizeof (_trackEntries));
- _driver = new AdlibDriver (newopl);
- assert (_driver);
-
- _sfxPlayingSound = -1;
- // _soundFileLoaded = "";
-
- _soundTriggers = _kyra1SoundTriggers;
- _numSoundTriggers = _kyra1NumSoundTriggers;
-
- init ();
-}
-
-CadlPlayer::~CadlPlayer ()
-{
- delete[]_soundDataPtr;
- _soundDataPtr = 0;
- delete _driver;
- _driver = 0;
-}
-
-bool
-CadlPlayer::init ()
-{
- _driver->callback (2);
- _driver->callback (16, int (4));
- return true;
-}
-
-void
-CadlPlayer::process ()
-{
- uint8 trigger = _driver->callback (11);
-
- if (trigger < _numSoundTriggers)
- {
- int soundId = _soundTriggers[trigger];
-
- if (soundId)
- {
- playTrack (soundId);
- }
- }
- else
- {
- warning ("Unknown sound trigger %d", trigger);
- // TODO: At this point, we really want to clear the trigger...
- }
-}
-
-// void CadlPlayer::setVolume(int volume) {
-// }
-
-// int CadlPlayer::getVolume() {
-// return 0;
-// }
-
-// void CadlPlayer::loadMusicFile(const char *file) {
-// loadSoundFile(file);
-// }
-
-void
-CadlPlayer::playTrack (uint8 track)
-{
- play (track);
-}
-
-// void CadlPlayer::haltTrack() {
-// unk1();
-// unk2();
-// //_engine->_system->delayMillis(3 * 60);
-// }
-
-void
-CadlPlayer::playSoundEffect (uint8_t track)
-{
- play (track);
-}
-
-void
-CadlPlayer::play (uint8_t track)
-{
- uint8 soundId = _trackEntries[track];
- if ((int8) soundId == -1 || !_soundDataPtr)
- return;
- soundId &= 0xFF;
- _driver->callback (16, 0);
- // while ((_driver->callback(16, 0) & 8)) {
- // We call the system delay and not the game delay to avoid concurrency issues.
- // _engine->_system->delayMillis(10);
- // }
- if (_sfxPlayingSound != -1)
- {
- // Restore the sounds's normal values.
- _driver->callback (10, _sfxPlayingSound, int (1), int (_sfxPriority));
- _driver->callback (10, _sfxPlayingSound, int (3),
- int (_sfxFourthByteOfSong));
- _sfxPlayingSound = -1;
- }
-
- int chan = _driver->callback (9, soundId, int (0));
-
- if (chan != 9)
- {
- _sfxPlayingSound = soundId;
- _sfxPriority = _driver->callback (9, soundId, int (1));
- _sfxFourthByteOfSong = _driver->callback (9, soundId, int (3));
-
- // In the cases I've seen, the mysterious fourth byte has been
- // the parameter for the update_setExtraLevel3() callback.
- //
- // The extra level is part of the channels "total level", which
- // is a six-bit value where larger values means softer volume.
- //
- // So what seems to be happening here is that sounds which are
- // started by this function are given a slightly lower priority
- // and a slightly higher (i.e. softer) extra level 3 than they
- // would have if they were started from anywhere else. Strange.
-
- int newVal = ((((-_sfxFourthByteOfSong) + 63) * 0xFF) >> 8) & 0xFF;
- newVal = -newVal + 63;
- _driver->callback (10, soundId, int (3), newVal);
- newVal = ((_sfxPriority * 0xFF) >> 8) & 0xFF;
- _driver->callback (10, soundId, int (1), newVal);
- }
-
- _driver->callback (6, soundId);
-}
-
-// void CadlPlayer::beginFadeOut() {
-// playSoundEffect(1);
-// }
-
-bool
-CadlPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- std::string filename (vfs_get_filename (fd));
-
- // file validation section
- if (!f || !fp.extension (filename, ".adl"))
- {
- fp.close (f);
- return false;
- }
-
- // if (_soundFileLoaded == file)
- // return;
-
- // if (_soundDataPtr) {
- // haltTrack();
- // }
-
- uint8 *file_data = 0;
- uint32 file_size = 0;
-
- // char filename[25];
- // sprintf(filename, "%s.ADL", file);
-
- // file_data = _engine->resource()->fileData(filename, &file_size);
- // if (!file_data) {
- // warning("Couldn't find music file: '%s'", filename);
- // return;
- // }
-
- unk2 ();
- unk1 ();
-
- file_size = fp.filesize (f);
- file_data = new uint8[file_size];
- f->readString ((char *) file_data, file_size);
-
- _driver->callback (8, int (-1));
- _soundDataPtr = 0;
-
- uint8 *p = file_data;
- memcpy (_trackEntries, p, 120 * sizeof (uint8));
- p += 120;
-
- int soundDataSize = file_size - 120;
-
- _soundDataPtr = new uint8[soundDataSize];
- assert (_soundDataPtr);
-
- memcpy (_soundDataPtr, p, soundDataSize * sizeof (uint8));
-
- delete[]file_data;
- file_data = p = 0;
- file_size = 0;
-
- _driver->callback (4, _soundDataPtr);
-
- // _soundFileLoaded = file;
-
- // find last subsong
- for(int i = 199; i >= 0; i--)
- if(_trackEntries[i] != 0xff) {
- numsubsongs = i + 1;
- break;
- }
- fp.close (f);
- cursubsong = 2;
- rewind();
- return true;
-}
-
-void
-CadlPlayer::rewind (int subsong)
-{
- if(subsong == -1) subsong = cursubsong;
- opl->init ();
- opl->write (1, 32);
- playSoundEffect (subsong);
- cursubsong = subsong;
- update ();
-}
-
-unsigned int
-CadlPlayer::getsubsongs ()
-{
- return numsubsongs;
-}
-
-bool
-CadlPlayer::update ()
-{
- bool songend = true;
-
-// if(_trackEntries[cursubsong] == 0xff)
-// return false;
-
- _driver->callback ();
-
- for (int i = 0; i < 10; i++)
- if (_driver->_channels[i].dataptr != NULL)
- songend = false;
-
- return !songend;
-}
-
-void
-CadlPlayer::unk1 ()
-{
- playSoundEffect (0);
- //_engine->_system->delayMillis(5 * 60);
-}
-
-void
-CadlPlayer::unk2 ()
-{
- playSoundEffect (0);
-}
-
-CPlayer *
-CadlPlayer::factory (Copl * newopl)
-{
- return new CadlPlayer (newopl);
-}
diff --git a/src/adplug/core/adl.h b/src/adplug/core/adl.h
index 083093814523..fc3b1f2dc54f 100644
--- a/src/adplug/core/adl.h
+++ b/src/adplug/core/adl.h
@@ -36,7 +36,7 @@ class CadlPlayer: public CPlayer
CadlPlayer(Copl *newopl);
~CadlPlayer();
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong = -1);
diff --git a/src/adplug/core/adlibemu.c b/src/adplug/core/adlibemu.c
deleted file mode 100644
index 2b7d56196e06..000000000000
--- a/src/adplug/core/adlibemu.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * ADLIBEMU.C
- * Copyright (C) 1998-2001 Ken Silverman
- * Ken Silverman's official web site: "http://www.advsys.net/ken"
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
-This file is a digital Adlib emulator for OPL2 and possibly OPL3
-
-Features that could be added in a future version:
-- Amplitude and Frequency Vibrato Bits (not hard, but a big speed hit)
-- Global Keyboard Split Number Bit (need to research this one some more)
-- 2nd Adlib chip for OPL3 (simply need to make my cell array bigger)
-- Advanced connection modes of OPL3 (Just need to add more "docell" cases)
-- L/R Stereo bits of OPL3 (Need adlibgetsample to return stereo)
-
-Features that aren't worth supporting:
-- Anything related to adlib timers&interrupts (Sorry - I always used IRQ0)
-- Composite sine wave mode (CSM) (Supported only on ancient cards)
-
-I'm not sure about a few things in my code:
-- Attack curve. What function is this anyway? I chose to use an order-3
- polynomial to approximate but this doesn't seem right.
-- Attack/Decay/Release constants - my constants may not be exact
-- What should ADJUSTSPEED be?
-- Haven't verified that Global Keyboard Split Number Bit works yet
-- Some of the drums don't always sound right. It's pretty hard to guess
- the exact waveform of drums when you look at random data which is
- slightly randomized due to digital ADC recording.
-- Adlib seems to have a lot more treble than my emulator does. I'm not
- sure if this is simply unfixable due to the sound blaster's different
- filtering on FM and digital playback or if it's a serious bug in my
- code.
-*/
-
-#include <math.h>
-#include <string.h>
-
-#if !defined(max) && !defined(__cplusplus)
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-#endif
-#if !defined(min) && !defined(__cplusplus)
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-
-#define PI 3.141592653589793
-#define MAXCELLS 18
-#define WAVPREC 2048
-
-static float AMPSCALE=(8192.0);
-#define FRQSCALE (49716/512.0)
-
-//Constants for Ken's Awe32, on a PII-266 (Ken says: Use these for KSM's!)
-#define MODFACTOR 4.0 //How much of modulator cell goes into carrier
-#define MFBFACTOR 1.0 //How much feedback goes back into modulator
-#define ADJUSTSPEED 0.75 //0<=x<=1 Simulate finite rate of change of state
-
-//Constants for Ken's Awe64G, on a P-133
-//#define MODFACTOR 4.25 //How much of modulator cell goes into carrier
-//#define MFBFACTOR 0.5 //How much feedback goes back into modulator
-//#define ADJUSTSPEED 0.85 //0<=x<=1 Simulate finite rate of change of state
-
-typedef struct
-{
- float val, t, tinc, vol, sustain, amp, mfb;
- float a0, a1, a2, a3, decaymul, releasemul;
- short *waveform;
- long wavemask;
- void (*cellfunc)(void *, float);
- unsigned char flags, dum0, dum1, dum2;
-} celltype;
-
-static long numspeakers, bytespersample;
-static float recipsamp;
-static celltype cell[MAXCELLS];
-static signed short wavtable[WAVPREC*3];
-static float kslmul[4] = {0.0,0.5,0.25,1.0};
-static float frqmul[16] = {.5,1,2,3,4,5,6,7,8,9,10,10,12,12,15,15}, nfrqmul[16];
-static unsigned char adlibreg[256], ksl[8][16];
-static unsigned char modulatorbase[9] = {0,1,2,8,9,10,16,17,18};
-static unsigned char odrumstat = 0;
-static unsigned char base2cell[22] = {0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8};
-
-float lvol[9] = {1,1,1,1,1,1,1,1,1}; //Volume multiplier on left speaker
-float rvol[9] = {1,1,1,1,1,1,1,1,1}; //Volume multiplier on right speaker
-long lplc[9] = {0,0,0,0,0,0,0,0,0}; //Samples to delay on left speaker
-long rplc[9] = {0,0,0,0,0,0,0,0,0}; //Samples to delay on right speaker
-
-long nlvol[9], nrvol[9];
-long nlplc[9], nrplc[9];
-long rend = 0;
-#define FIFOSIZ 256
-static float *rptr[9], *nrptr[9];
-static float rbuf[9][FIFOSIZ*2];
-static float snd[FIFOSIZ*2];
-
-#ifndef USING_ASM
-#define _inline
-#endif
-
-#ifdef USING_ASM
-static _inline void ftol (float f, long *a)
-{
- _asm
- {
- mov eax, a
- fld f
- fistp dword ptr [eax]
- }
-}
-#else
-static void ftol(float f, long *a) {
- *a=f;
-}
-#endif
-
-#define ctc ((celltype *)c) //A rare attempt to make code easier to read!
-void docell4 (void *c, float modulator) { }
-void docell3 (void *c, float modulator)
-{
- long i;
-
- ftol(ctc->t+modulator,&i);
- ctc->t += ctc->tinc;
- ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
-}
-void docell2 (void *c, float modulator)
-{
- long i;
-
- ftol(ctc->t+modulator,&i);
-
- if ((long)ctc->amp <= 0x37800000)
- {
- ctc->amp = 0;
- ctc->cellfunc = docell4;
- }
- ctc->amp *= ctc->releasemul;
-
- ctc->t += ctc->tinc;
- ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
-}
-void docell1 (void *c, float modulator)
-{
- long i;
-
- ftol(ctc->t+modulator,&i);
-
- if ((long)ctc->amp <= (long)ctc->sustain)
- {
- if (ctc->flags&32)
- {
- ctc->amp = ctc->sustain;
- ctc->cellfunc = docell3;
- }
- else
- ctc->cellfunc = docell2;
- }
- else
- ctc->amp *= ctc->decaymul;
-
- ctc->t += ctc->tinc;
- ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
-}
-void docell0 (void *c, float modulator)
-{
- long i;
-
- ftol(ctc->t+modulator,&i);
-
- ctc->amp = ((ctc->a3*ctc->amp + ctc->a2)*ctc->amp + ctc->a1)*ctc->amp + ctc->a0;
- if ((long)ctc->amp > 0x3f800000)
- {
- ctc->amp = 1;
- ctc->cellfunc = docell1;
- }
-
- ctc->t += ctc->tinc;
- ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
-}
-
-
-static long waveform[8] = {WAVPREC,WAVPREC>>1,WAVPREC,(WAVPREC*3)>>2,0,0,(WAVPREC*5)>>2,WAVPREC<<1};
-static long wavemask[8] = {WAVPREC-1,WAVPREC-1,(WAVPREC>>1)-1,(WAVPREC>>1)-1,WAVPREC-1,((WAVPREC*3)>>2)-1,WAVPREC>>1,WAVPREC-1};
-static long wavestart[8] = {0,WAVPREC>>1,0,WAVPREC>>2,0,0,0,WAVPREC>>3};
-static float attackconst[4] = {1/2.82624,1/2.25280,1/1.88416,1/1.59744};
-static float decrelconst[4] = {1/39.28064,1/31.41608,1/26.17344,1/22.44608};
-void cellon (long i, long j, celltype *c, unsigned char iscarrier)
-{
- long frn, oct, toff;
- float f;
-
- frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0];
- oct = ((((long)adlibreg[i+0xb0])>>2)&7);
- toff = (oct<<1) + ((frn>>9)&((frn>>8)|(((adlibreg[8]>>6)&1)^1)));
- if (!(adlibreg[j+0x20]&16)) toff >>= 2;
-
- f = pow(2.0,(adlibreg[j+0x60]>>4)+(toff>>2)-1)*attackconst[toff&3]*recipsamp;
- c->a0 = .0377*f; c->a1 = 10.73*f+1; c->a2 = -17.57*f; c->a3 = 7.42*f;
- f = -7.4493*decrelconst[toff&3]*recipsamp;
- c->decaymul = pow(2.0,f*pow(2.0,(adlibreg[j+0x60]&15)+(toff>>2)));
- c->releasemul = pow(2.0,f*pow(2.0,(adlibreg[j+0x80]&15)+(toff>>2)));
- c->wavemask = wavemask[adlibreg[j+0xe0]&7];
- c->waveform = &wavtable[waveform[adlibreg[j+0xe0]&7]];
- if (!(adlibreg[1]&0x20)) c->waveform = &wavtable[WAVPREC];
- c->t = wavestart[adlibreg[j+0xe0]&7];
- c->flags = adlibreg[j+0x20];
- c->cellfunc = docell0;
- c->tinc = (float)(frn<<oct)*nfrqmul[adlibreg[j+0x20]&15];
- c->vol = pow(2.0,((float)(adlibreg[j+0x40]&63) +
- (float)kslmul[adlibreg[j+0x40]>>6]*ksl[oct][frn>>6]) * -.125 - 14);
- c->sustain = pow(2.0,(float)(adlibreg[j+0x80]>>4) * -.5);
- if (!iscarrier) c->amp = 0;
- c->mfb = pow(2.0,((adlibreg[i+0xc0]>>1)&7)+5)*(WAVPREC/2048.0)*MFBFACTOR;
- if (!(adlibreg[i+0xc0]&14)) c->mfb = 0;
- c->val = 0;
-}
-
-//This function (and bug fix) written by Chris Moeller
-void cellfreq (signed long i, signed long j, celltype *c)
-{
- long frn, oct;
-
- frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0];
- oct = ((((long)adlibreg[i+0xb0])>>2)&7);
-
- c->tinc = (float)(frn<<oct)*nfrqmul[adlibreg[j+0x20]&15];
- c->vol = pow(2.0,((float)(adlibreg[j+0x40]&63) +
- (float)kslmul[adlibreg[j+0x40]>>6]*ksl[oct][frn>>6]) * -.125 - 14);
-}
-
-static long initfirstime = 0;
-void adlibinit (long dasamplerate, long danumspeakers, long dabytespersample)
-{
- long i, j, frn, oct;
-
- memset((void *)adlibreg,0,sizeof(adlibreg));
- memset((void *)cell,0,sizeof(celltype)*MAXCELLS);
- memset((void *)rbuf,0,sizeof(rbuf));
- rend = 0; odrumstat = 0;
-
- for(i=0;i<MAXCELLS;i++)
- {
- cell[i].cellfunc = docell4;
- cell[i].amp = 0;
- cell[i].vol = 0;
- cell[i].t = 0;
- cell[i].tinc = 0;
- cell[i].wavemask = 0;
- cell[i].waveform = &wavtable[WAVPREC];
- }
-
- numspeakers = danumspeakers;
- bytespersample = dabytespersample;
-
- recipsamp = 1.0 / (float)dasamplerate;
- for(i=15;i>=0;i--) nfrqmul[i] = frqmul[i]*recipsamp*FRQSCALE*(WAVPREC/2048.0);
-
- if (!initfirstime)
- {
- initfirstime = 1;
-
- for(i=0;i<(WAVPREC>>1);i++)
- {
- wavtable[i] =
- wavtable[(i<<1) +WAVPREC] = (signed short)(16384*sin((float)((i<<1) )*PI*2/WAVPREC));
- wavtable[(i<<1)+1+WAVPREC] = (signed short)(16384*sin((float)((i<<1)+1)*PI*2/WAVPREC));
- }
- for(i=0;i<(WAVPREC>>3);i++)
- {
- wavtable[i+(WAVPREC<<1)] = wavtable[i+(WAVPREC>>3)]-16384;
- wavtable[i+((WAVPREC*17)>>3)] = wavtable[i+(WAVPREC>>2)]+16384;
- }
-
- //[table in book]*8/3
- ksl[7][0] = 0; ksl[7][1] = 24; ksl[7][2] = 32; ksl[7][3] = 37;
- ksl[7][4] = 40; ksl[7][5] = 43; ksl[7][6] = 45; ksl[7][7] = 47;
- ksl[7][8] = 48; for(i=9;i<16;i++) ksl[7][i] = i+41;
- for(j=6;j>=0;j--)
- for(i=0;i<16;i++)
- {
- oct = (long)ksl[j+1][i]-8; if (oct < 0) oct = 0;
- ksl[j][i] = (unsigned char)oct;
- }
- }
- else
- {
- for(i=0;i<9;i++)
- {
- frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0];
- oct = ((((long)adlibreg[i+0xb0])>>2)&7);
- cell[i].tinc = (float)(frn<<oct)*nfrqmul[adlibreg[modulatorbase[i]+0x20]&15];
- }
- }
-}
-
-void adlib0 (long i, long v)
-{
- unsigned char tmp = adlibreg[i];
- adlibreg[i] = v;
-
- if (i == 0xbd)
- {
- if ((v&16) > (odrumstat&16)) //BassDrum
- {
- cellon(6,16,&cell[6],0);
- cellon(6,19,&cell[15],1);
- cell[15].vol *= 2;
- }
- if ((v&8) > (odrumstat&8)) //Snare
- {
- cellon(16,20,&cell[16],0);
- cell[16].tinc *= 2*(nfrqmul[adlibreg[17+0x20]&15] / nfrqmul[adlibreg[20+0x20]&15]);
- if (((adlibreg[20+0xe0]&7) >= 3) && ((adlibreg[20+0xe0]&7) <= 5)) cell[16].vol = 0;
- cell[16].vol *= 2;
- }
- if ((v&4) > (odrumstat&4)) //TomTom
- {
- cellon(8,18,&cell[8],0);
- cell[8].vol *= 2;
- }
- if ((v&2) > (odrumstat&2)) //Cymbal
- {
- cellon(17,21,&cell[17],0);
-
- cell[17].wavemask = wavemask[5];
- cell[17].waveform = &wavtable[waveform[5]];
- cell[17].tinc *= 16; cell[17].vol *= 2;
-
- //cell[17].waveform = &wavtable[WAVPREC]; cell[17].wavemask = 0;
- //if (((adlibreg[21+0xe0]&7) == 0) || ((adlibreg[21+0xe0]&7) == 6))
- // cell[17].waveform = &wavtable[(WAVPREC*7)>>2];
- //if (((adlibreg[21+0xe0]&7) == 2) || ((adlibreg[21+0xe0]&7) == 3))
- // cell[17].waveform = &wavtable[(WAVPREC*5)>>2];
- }
- if ((v&1) > (odrumstat&1)) //Hihat
- {
- cellon(7,17,&cell[7],0);
- if (((adlibreg[17+0xe0]&7) == 1) || ((adlibreg[17+0xe0]&7) == 4) ||
- ((adlibreg[17+0xe0]&7) == 5) || ((adlibreg[17+0xe0]&7) == 7)) cell[7].vol = 0;
- if ((adlibreg[17+0xe0]&7) == 6) { cell[7].wavemask = 0; cell[7].waveform = &wavtable[(WAVPREC*7)>>2]; }
- }
-
- odrumstat = v;
- }
- else if (((unsigned)(i-0x40) < (unsigned)22) && ((i&7) < 6))
- {
- if ((i&7) < 3) // Modulator
- cellfreq(base2cell[i-0x40],i-0x40,&cell[base2cell[i-0x40]]);
- else // Carrier
- cellfreq(base2cell[i-0x40],i-0x40,&cell[base2cell[i-0x40]+9]);
- }
- else if ((unsigned)(i-0xa0) < (unsigned)9)
- {
- cellfreq(i-0xa0,modulatorbase[i-0xa0],&cell[i-0xa0]);
- cellfreq(i-0xa0,modulatorbase[i-0xa0]+3,&cell[i-0xa0+9]);
- }
- else if ((unsigned)(i-0xb0) < (unsigned)9)
- {
- if ((v&32) > (tmp&32))
- {
- cellon(i-0xb0,modulatorbase[i-0xb0],&cell[i-0xb0],0);
- cellon(i-0xb0,modulatorbase[i-0xb0]+3,&cell[i-0xb0+9],1);
- }
- else if ((v&32) < (tmp&32))
- cell[i-0xb0].cellfunc = cell[i-0xb0+9].cellfunc = docell2;
- cellfreq(i-0xb0,modulatorbase[i-0xb0],&cell[i-0xb0]);
- cellfreq(i-0xb0,modulatorbase[i-0xb0]+3,&cell[i-0xb0+9]);
- }
-
- //outdata(i,v);
-}
-
-#ifdef USING_ASM
-static long fpuasm;
-static float fakeadd = 8388608.0+128.0;
-static _inline void clipit8 (float f, long a)
-{
- _asm
- {
- mov edi, a
- fld dword ptr f
- fadd dword ptr fakeadd
- fstp dword ptr fpuasm
- mov eax, fpuasm
- test eax, 0x007fff00
- jz short skipit
- shr eax, 16
- xor eax, -1
- skipit: mov byte ptr [edi], al
- }
-}
-
-static _inline void clipit16 (float f, long a)
-{
- _asm
- {
- mov eax, a
- fld dword ptr f
- fist word ptr [eax]
- cmp word ptr [eax], 0x8000
- jne short skipit2
- fst dword ptr [fpuasm]
- cmp fpuasm, 0x80000000
- sbb word ptr [eax], 0
- skipit2: fstp st
- }
-}
-#else
-static void clipit8(float f,unsigned char *a) {
- f/=256.0;
- f+=128.0;
- if (f>254.5) *a=255;
- else if (f<0.5) *a=0;
- else *a=f;
-}
-
-static void clipit16(float f,short *a) {
- if (f>32766.5) *a=32767;
- else if (f<-32767.5) *a=-32768;
- else *a=f;
-}
-#endif
-
-void adlibsetvolume(int i) {
- AMPSCALE=i;
-}
-
-void adlibgetsample (unsigned char *sndptr, long numbytes)
-{
- long i, j, k=0, ns, endsamples, rptrs, numsamples;
- celltype *cptr;
- float f;
- short *sndptr2=(short *)sndptr;
-
- numsamples = (numbytes>>(numspeakers+bytespersample-2));
-
- if (bytespersample == 1) f = AMPSCALE/256.0; else f = AMPSCALE;
- if (numspeakers == 1)
- {
- nlvol[0] = lvol[0]*f;
- for(i=0;i<9;i++) rptr[i] = &rbuf[0][0];
- rptrs = 1;
- }
- else
- {
- rptrs = 0;
- for(i=0;i<9;i++)
- {
- if ((!i) || (lvol[i] != lvol[i-1]) || (rvol[i] != rvol[i-1]) ||
- (lplc[i] != lplc[i-1]) || (rplc[i] != rplc[i-1]))
- {
- nlvol[rptrs] = lvol[i]*f;
- nrvol[rptrs] = rvol[i]*f;
- nlplc[rptrs] = rend-min(max(lplc[i],0),FIFOSIZ);
- nrplc[rptrs] = rend-min(max(rplc[i],0),FIFOSIZ);
- rptrs++;
- }
- rptr[i] = &rbuf[rptrs-1][0];
- }
- }
-
-
- //CPU time used to be somewhat less when emulator was only mono!
- // Because of no delay fifos!
-
- for(ns=0;ns<numsamples;ns+=endsamples)
- {
- endsamples = min(FIFOSIZ*2-rend,FIFOSIZ);
- endsamples = min(endsamples,numsamples-ns);
-
- for(i=0;i<9;i++)
- nrptr[i] = &rptr[i][rend];
- for(i=0;i<rptrs;i++)
- memset((void *)&rbuf[i][rend],0,endsamples*sizeof(float));
-
- if (adlibreg[0xbd]&0x20)
- {
- //BassDrum (j=6)
- if (cell[15].cellfunc != docell4)
- {
- if (adlibreg[0xc6]&1)
- {
- for(i=0;i<endsamples;i++)
- {
- (cell[15].cellfunc)((void *)&cell[15],0.0);
- nrptr[6][i] += cell[15].val;
- }
- }
- else
- {
- for(i=0;i<endsamples;i++)
- {
- (cell[6].cellfunc)((void *)&cell[6],cell[6].val*cell[6].mfb);
- (cell[15].cellfunc)((void *)&cell[15],cell[6].val*WAVPREC*MODFACTOR);
- nrptr[6][i] += cell[15].val;
- }
- }
- }
-
- //Snare/Hihat (j=7), Cymbal/TomTom (j=8)
- if ((cell[7].cellfunc != docell4) || (cell[8].cellfunc != docell4) || (cell[16].cellfunc != docell4) || (cell[17].cellfunc != docell4))
- {
- for(i=0;i<endsamples;i++)
- {
- k = k*1664525+1013904223;
- (cell[16].cellfunc)((void *)&cell[16],k&((WAVPREC>>1)-1)); //Snare
- (cell[7].cellfunc)((void *)&cell[7],k&(WAVPREC-1)); //Hihat
- (cell[17].cellfunc)((void *)&cell[17],k&((WAVPREC>>3)-1)); //Cymbal
- (cell[8].cellfunc)((void *)&cell[8],0.0); //TomTom
- nrptr[7][i] += cell[7].val + cell[16].val;
- nrptr[8][i] += cell[8].val + cell[17].val;
- }
- }
- }
- for(j=9-1;j>=0;j--)
- {
- if ((adlibreg[0xbd]&0x20) && (j >= 6) && (j < 9)) continue;
-
- cptr = &cell[j]; k = j;
- if (adlibreg[0xc0+k]&1)
- {
- if ((cptr[9].cellfunc == docell4) && (cptr->cellfunc == docell4)) continue;
- for(i=0;i<endsamples;i++)
- {
- (cptr->cellfunc)((void *)cptr,cptr->val*cptr->mfb);
- (cptr->cellfunc)((void *)&cptr[9],0);
- nrptr[j][i] += cptr[9].val + cptr->val;
- }
- }
- else
- {
- if (cptr[9].cellfunc == docell4) continue;
- for(i=0;i<endsamples;i++)
- {
- (cptr->cellfunc)((void *)cptr,cptr->val*cptr->mfb);
- (cptr[9].cellfunc)((void *)&cptr[9],cptr->val*WAVPREC*MODFACTOR);
- nrptr[j][i] += cptr[9].val;
- }
- }
- }
-
- if (numspeakers == 1)
- {
- if (bytespersample == 1)
- {
- for(i=endsamples-1;i>=0;i--)
- clipit8(nrptr[0][i]*nlvol[0],sndptr+1);
- }
- else
- {
- for(i=endsamples-1;i>=0;i--)
- clipit16(nrptr[0][i]*nlvol[0],sndptr2+i);
- }
- }
- else
- {
- memset((void *)snd,0,endsamples*sizeof(float)*2);
- for(j=0;j<rptrs;j++)
- {
- for(i=0;i<endsamples;i++)
- {
- snd[(i<<1) ] += rbuf[j][(nlplc[j]+i)&(FIFOSIZ*2-1)]*nlvol[j];
- snd[(i<<1)+1] += rbuf[j][(nrplc[j]+i)&(FIFOSIZ*2-1)]*nrvol[j];
- }
- nlplc[j] += endsamples;
- nrplc[j] += endsamples;
- }
-
- if (bytespersample == 1)
- {
- for(i=(endsamples<<1)-1;i>=0;i--)
- clipit8(snd[i],sndptr+i);
- }
- else
- {
- for(i=(endsamples<<1)-1;i>=0;i--)
- clipit16(snd[i],sndptr2+i);
- }
- }
-
- sndptr = sndptr+(numspeakers*endsamples);
- sndptr2 = sndptr2+(numspeakers*endsamples);
- rend = ((rend+endsamples)&(FIFOSIZ*2-1));
- }
-}
diff --git a/src/adplug/core/adlibemu.cc b/src/adplug/core/adlibemu.cc
new file mode 100644
index 000000000000..ee3ad93d016d
--- /dev/null
+++ b/src/adplug/core/adlibemu.cc
@@ -0,0 +1,594 @@
+/*
+ * ADLIBEMU.C
+ * Copyright (C) 1998-2001 Ken Silverman
+ * Ken Silverman's official web site: "http://www.advsys.net/ken"
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+This file is a digital Adlib emulator for OPL2 and possibly OPL3
+
+Features that could be added in a future version:
+- Amplitude and Frequency Vibrato Bits (not hard, but a big speed hit)
+- Global Keyboard Split Number Bit (need to research this one some more)
+- 2nd Adlib chip for OPL3 (simply need to make my cell array bigger)
+- Advanced connection modes of OPL3 (Just need to add more "docell" cases)
+- L/R Stereo bits of OPL3 (Need adlibgetsample to return stereo)
+
+Features that aren't worth supporting:
+- Anything related to adlib timers&interrupts (Sorry - I always used IRQ0)
+- Composite sine wave mode (CSM) (Supported only on ancient cards)
+
+I'm not sure about a few things in my code:
+- Attack curve. What function is this anyway? I chose to use an order-3
+ polynomial to approximate but this doesn't seem right.
+- Attack/Decay/Release constants - my constants may not be exact
+- What should ADJUSTSPEED be?
+- Haven't verified that Global Keyboard Split Number Bit works yet
+- Some of the drums don't always sound right. It's pretty hard to guess
+ the exact waveform of drums when you look at random data which is
+ slightly randomized due to digital ADC recording.
+- Adlib seems to have a lot more treble than my emulator does. I'm not
+ sure if this is simply unfixable due to the sound blaster's different
+ filtering on FM and digital playback or if it's a serious bug in my
+ code.
+*/
+
+#include <math.h>
+#include <string.h>
+#include <algorithm>
+
+#define PI 3.141592653589793
+#define MAXCELLS 18
+#define WAVPREC 2048
+
+static float AMPSCALE=(8192.0);
+#define FRQSCALE (49716/512.0)
+
+//Constants for Ken's Awe32, on a PII-266 (Ken says: Use these for KSM's!)
+#define MODFACTOR 4.0 //How much of modulator cell goes into carrier
+#define MFBFACTOR 1.0 //How much feedback goes back into modulator
+#define ADJUSTSPEED 0.75 //0<=x<=1 Simulate finite rate of change of state
+
+//Constants for Ken's Awe64G, on a P-133
+//#define MODFACTOR 4.25 //How much of modulator cell goes into carrier
+//#define MFBFACTOR 0.5 //How much feedback goes back into modulator
+//#define ADJUSTSPEED 0.85 //0<=x<=1 Simulate finite rate of change of state
+
+typedef struct
+{
+ float val, t, tinc, vol, sustain, amp, mfb;
+ float a0, a1, a2, a3, decaymul, releasemul;
+ short *waveform;
+ long wavemask;
+ void (*cellfunc)(void *, float);
+ unsigned char flags, dum0, dum1, dum2;
+} celltype;
+
+static long numspeakers, bytespersample;
+static float recipsamp;
+static celltype cell[MAXCELLS];
+static signed short wavtable[WAVPREC*3];
+static float kslmul[4] = {0.0,0.5,0.25,1.0};
+static float frqmul[16] = {.5,1,2,3,4,5,6,7,8,9,10,10,12,12,15,15}, nfrqmul[16];
+static unsigned char adlibreg[256], ksl[8][16];
+static unsigned char modulatorbase[9] = {0,1,2,8,9,10,16,17,18};
+static unsigned char odrumstat = 0;
+static unsigned char base2cell[22] = {0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8};
+
+float lvol[9] = {1,1,1,1,1,1,1,1,1}; //Volume multiplier on left speaker
+float rvol[9] = {1,1,1,1,1,1,1,1,1}; //Volume multiplier on right speaker
+long lplc[9] = {0,0,0,0,0,0,0,0,0}; //Samples to delay on left speaker
+long rplc[9] = {0,0,0,0,0,0,0,0,0}; //Samples to delay on right speaker
+
+long nlvol[9], nrvol[9];
+long nlplc[9], nrplc[9];
+long rend = 0;
+#define FIFOSIZ 256
+static float *rptr[9], *nrptr[9];
+static float rbuf[9][FIFOSIZ*2];
+static float snd[FIFOSIZ*2];
+
+#ifndef USING_ASM
+#define _inline
+#endif
+
+#ifdef USING_ASM
+static _inline void ftol (float f, long *a)
+{
+ _asm
+ {
+ mov eax, a
+ fld f
+ fistp dword ptr [eax]
+ }
+}
+#else
+static void ftol(float f, long *a) {
+ *a=f;
+}
+#endif
+
+#define ctc ((celltype *)c) //A rare attempt to make code easier to read!
+void docell4 (void *c, float modulator) { }
+void docell3 (void *c, float modulator)
+{
+ long i;
+
+ ftol(ctc->t+modulator,&i);
+ ctc->t += ctc->tinc;
+ ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
+}
+void docell2 (void *c, float modulator)
+{
+ long i;
+
+ ftol(ctc->t+modulator,&i);
+
+ if ((long)ctc->amp <= 0x37800000)
+ {
+ ctc->amp = 0;
+ ctc->cellfunc = docell4;
+ }
+ ctc->amp *= ctc->releasemul;
+
+ ctc->t += ctc->tinc;
+ ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
+}
+void docell1 (void *c, float modulator)
+{
+ long i;
+
+ ftol(ctc->t+modulator,&i);
+
+ if ((long)ctc->amp <= (long)ctc->sustain)
+ {
+ if (ctc->flags&32)
+ {
+ ctc->amp = ctc->sustain;
+ ctc->cellfunc = docell3;
+ }
+ else
+ ctc->cellfunc = docell2;
+ }
+ else
+ ctc->amp *= ctc->decaymul;
+
+ ctc->t += ctc->tinc;
+ ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
+}
+void docell0 (void *c, float modulator)
+{
+ long i;
+
+ ftol(ctc->t+modulator,&i);
+
+ ctc->amp = ((ctc->a3*ctc->amp + ctc->a2)*ctc->amp + ctc->a1)*ctc->amp + ctc->a0;
+ if ((long)ctc->amp > 0x3f800000)
+ {
+ ctc->amp = 1;
+ ctc->cellfunc = docell1;
+ }
+
+ ctc->t += ctc->tinc;
+ ctc->val += (ctc->amp*ctc->vol*((float)ctc->waveform[i&ctc->wavemask])-ctc->val)*ADJUSTSPEED;
+}
+
+
+static long waveform[8] = {WAVPREC,WAVPREC>>1,WAVPREC,(WAVPREC*3)>>2,0,0,(WAVPREC*5)>>2,WAVPREC<<1};
+static long wavemask[8] = {WAVPREC-1,WAVPREC-1,(WAVPREC>>1)-1,(WAVPREC>>1)-1,WAVPREC-1,((WAVPREC*3)>>2)-1,WAVPREC>>1,WAVPREC-1};
+static long wavestart[8] = {0,WAVPREC>>1,0,WAVPREC>>2,0,0,0,WAVPREC>>3};
+static float attackconst[4] = {1/2.82624,1/2.25280,1/1.88416,1/1.59744};
+static float decrelconst[4] = {1/39.28064,1/31.41608,1/26.17344,1/22.44608};
+void cellon (long i, long j, celltype *c, unsigned char iscarrier)
+{
+ long frn, oct, toff;
+ float f;
+
+ frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0];
+ oct = ((((long)adlibreg[i+0xb0])>>2)&7);
+ toff = (oct<<1) + ((frn>>9)&((frn>>8)|(((adlibreg[8]>>6)&1)^1)));
+ if (!(adlibreg[j+0x20]&16)) toff >>= 2;
+
+ f = pow(2.0,(adlibreg[j+0x60]>>4)+(toff>>2)-1)*attackconst[toff&3]*recipsamp;
+ c->a0 = .0377*f; c->a1 = 10.73*f+1; c->a2 = -17.57*f; c->a3 = 7.42*f;
+ f = -7.4493*decrelconst[toff&3]*recipsamp;
+ c->decaymul = pow(2.0,f*pow(2.0,(adlibreg[j+0x60]&15)+(toff>>2)));
+ c->releasemul = pow(2.0,f*pow(2.0,(adlibreg[j+0x80]&15)+(toff>>2)));
+ c->wavemask = wavemask[adlibreg[j+0xe0]&7];
+ c->waveform = &wavtable[waveform[adlibreg[j+0xe0]&7]];
+ if (!(adlibreg[1]&0x20)) c->waveform = &wavtable[WAVPREC];
+ c->t = wavestart[adlibreg[j+0xe0]&7];
+ c->flags = adlibreg[j+0x20];
+ c->cellfunc = docell0;
+ c->tinc = (float)(frn<<oct)*nfrqmul[adlibreg[j+0x20]&15];
+ c->vol = pow(2.0,((float)(adlibreg[j+0x40]&63) +
+ (float)kslmul[adlibreg[j+0x40]>>6]*ksl[oct][frn>>6]) * -.125 - 14);
+ c->sustain = pow(2.0,(float)(adlibreg[j+0x80]>>4) * -.5);
+ if (!iscarrier) c->amp = 0;
+ c->mfb = pow(2.0,((adlibreg[i+0xc0]>>1)&7)+5)*(WAVPREC/2048.0)*MFBFACTOR;
+ if (!(adlibreg[i+0xc0]&14)) c->mfb = 0;
+ c->val = 0;
+}
+
+//This function (and bug fix) written by Chris Moeller
+void cellfreq (signed long i, signed long j, celltype *c)
+{
+ long frn, oct;
+
+ frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0];
+ oct = ((((long)adlibreg[i+0xb0])>>2)&7);
+
+ c->tinc = (float)(frn<<oct)*nfrqmul[adlibreg[j+0x20]&15];
+ c->vol = pow(2.0,((float)(adlibreg[j+0x40]&63) +
+ (float)kslmul[adlibreg[j+0x40]>>6]*ksl[oct][frn>>6]) * -.125 - 14);
+}
+
+static long initfirstime = 0;
+void adlibinit (long dasamplerate, long danumspeakers, long dabytespersample)
+{
+ long i, j, frn, oct;
+
+ memset((void *)adlibreg,0,sizeof(adlibreg));
+ memset((void *)cell,0,sizeof(celltype)*MAXCELLS);
+ memset((void *)rbuf,0,sizeof(rbuf));
+ rend = 0; odrumstat = 0;
+
+ for(i=0;i<MAXCELLS;i++)
+ {
+ cell[i].cellfunc = docell4;
+ cell[i].amp = 0;
+ cell[i].vol = 0;
+ cell[i].t = 0;
+ cell[i].tinc = 0;
+ cell[i].wavemask = 0;
+ cell[i].waveform = &wavtable[WAVPREC];
+ }
+
+ numspeakers = danumspeakers;
+ bytespersample = dabytespersample;
+
+ recipsamp = 1.0 / (float)dasamplerate;
+ for(i=15;i>=0;i--) nfrqmul[i] = frqmul[i]*recipsamp*FRQSCALE*(WAVPREC/2048.0);
+
+ if (!initfirstime)
+ {
+ initfirstime = 1;
+
+ for(i=0;i<(WAVPREC>>1);i++)
+ {
+ wavtable[i] =
+ wavtable[(i<<1) +WAVPREC] = (signed short)(16384*sin((float)((i<<1) )*PI*2/WAVPREC));
+ wavtable[(i<<1)+1+WAVPREC] = (signed short)(16384*sin((float)((i<<1)+1)*PI*2/WAVPREC));
+ }
+ for(i=0;i<(WAVPREC>>3);i++)
+ {
+ wavtable[i+(WAVPREC<<1)] = wavtable[i+(WAVPREC>>3)]-16384;
+ wavtable[i+((WAVPREC*17)>>3)] = wavtable[i+(WAVPREC>>2)]+16384;
+ }
+
+ //[table in book]*8/3
+ ksl[7][0] = 0; ksl[7][1] = 24; ksl[7][2] = 32; ksl[7][3] = 37;
+ ksl[7][4] = 40; ksl[7][5] = 43; ksl[7][6] = 45; ksl[7][7] = 47;
+ ksl[7][8] = 48; for(i=9;i<16;i++) ksl[7][i] = i+41;
+ for(j=6;j>=0;j--)
+ for(i=0;i<16;i++)
+ {
+ oct = (long)ksl[j+1][i]-8; if (oct < 0) oct = 0;
+ ksl[j][i] = (unsigned char)oct;
+ }
+ }
+ else
+ {
+ for(i=0;i<9;i++)
+ {
+ frn = ((((long)adlibreg[i+0xb0])&3)<<8) + (long)adlibreg[i+0xa0];
+ oct = ((((long)adlibreg[i+0xb0])>>2)&7);
+ cell[i].tinc = (float)(frn<<oct)*nfrqmul[adlibreg[modulatorbase[i]+0x20]&15];
+ }
+ }
+}
+
+void adlib0 (long i, long v)
+{
+ unsigned char tmp = adlibreg[i];
+ adlibreg[i] = v;
+
+ if (i == 0xbd)
+ {
+ if ((v&16) > (odrumstat&16)) //BassDrum
+ {
+ cellon(6,16,&cell[6],0);
+ cellon(6,19,&cell[15],1);
+ cell[15].vol *= 2;
+ }
+ if ((v&8) > (odrumstat&8)) //Snare
+ {
+ cellon(16,20,&cell[16],0);
+ cell[16].tinc *= 2*(nfrqmul[adlibreg[17+0x20]&15] / nfrqmul[adlibreg[20+0x20]&15]);
+ if (((adlibreg[20+0xe0]&7) >= 3) && ((adlibreg[20+0xe0]&7) <= 5)) cell[16].vol = 0;
+ cell[16].vol *= 2;
+ }
+ if ((v&4) > (odrumstat&4)) //TomTom
+ {
+ cellon(8,18,&cell[8],0);
+ cell[8].vol *= 2;
+ }
+ if ((v&2) > (odrumstat&2)) //Cymbal
+ {
+ cellon(17,21,&cell[17],0);
+
+ cell[17].wavemask = wavemask[5];
+ cell[17].waveform = &wavtable[waveform[5]];
+ cell[17].tinc *= 16; cell[17].vol *= 2;
+
+ //cell[17].waveform = &wavtable[WAVPREC]; cell[17].wavemask = 0;
+ //if (((adlibreg[21+0xe0]&7) == 0) || ((adlibreg[21+0xe0]&7) == 6))
+ // cell[17].waveform = &wavtable[(WAVPREC*7)>>2];
+ //if (((adlibreg[21+0xe0]&7) == 2) || ((adlibreg[21+0xe0]&7) == 3))
+ // cell[17].waveform = &wavtable[(WAVPREC*5)>>2];
+ }
+ if ((v&1) > (odrumstat&1)) //Hihat
+ {
+ cellon(7,17,&cell[7],0);
+ if (((adlibreg[17+0xe0]&7) == 1) || ((adlibreg[17+0xe0]&7) == 4) ||
+ ((adlibreg[17+0xe0]&7) == 5) || ((adlibreg[17+0xe0]&7) == 7)) cell[7].vol = 0;
+ if ((adlibreg[17+0xe0]&7) == 6) { cell[7].wavemask = 0; cell[7].waveform = &wavtable[(WAVPREC*7)>>2]; }
+ }
+
+ odrumstat = v;
+ }
+ else if (((unsigned)(i-0x40) < (unsigned)22) && ((i&7) < 6))
+ {
+ if ((i&7) < 3) // Modulator
+ cellfreq(base2cell[i-0x40],i-0x40,&cell[base2cell[i-0x40]]);
+ else // Carrier
+ cellfreq(base2cell[i-0x40],i-0x40,&cell[base2cell[i-0x40]+9]);
+ }
+ else if ((unsigned)(i-0xa0) < (unsigned)9)
+ {
+ cellfreq(i-0xa0,modulatorbase[i-0xa0],&cell[i-0xa0]);
+ cellfreq(i-0xa0,modulatorbase[i-0xa0]+3,&cell[i-0xa0+9]);
+ }
+ else if ((unsigned)(i-0xb0) < (unsigned)9)
+ {
+ if ((v&32) > (tmp&32))
+ {
+ cellon(i-0xb0,modulatorbase[i-0xb0],&cell[i-0xb0],0);
+ cellon(i-0xb0,modulatorbase[i-0xb0]+3,&cell[i-0xb0+9],1);
+ }
+ else if ((v&32) < (tmp&32))
+ cell[i-0xb0].cellfunc = cell[i-0xb0+9].cellfunc = docell2;
+ cellfreq(i-0xb0,modulatorbase[i-0xb0],&cell[i-0xb0]);
+ cellfreq(i-0xb0,modulatorbase[i-0xb0]+3,&cell[i-0xb0+9]);
+ }
+
+ //outdata(i,v);
+}
+
+#ifdef USING_ASM
+static long fpuasm;
+static float fakeadd = 8388608.0+128.0;
+static _inline void clipit8 (float f, long a)
+{
+ _asm
+ {
+ mov edi, a
+ fld dword ptr f
+ fadd dword ptr fakeadd
+ fstp dword ptr fpuasm
+ mov eax, fpuasm
+ test eax, 0x007fff00
+ jz short skipit
+ shr eax, 16
+ xor eax, -1
+ skipit: mov byte ptr [edi], al
+ }
+}
+
+static _inline void clipit16 (float f, long a)
+{
+ _asm
+ {
+ mov eax, a
+ fld dword ptr f
+ fist word ptr [eax]
+ cmp word ptr [eax], 0x8000
+ jne short skipit2
+ fst dword ptr [fpuasm]
+ cmp fpuasm, 0x80000000
+ sbb word ptr [eax], 0
+ skipit2: fstp st
+ }
+}
+#else
+static void clipit8(float f,unsigned char *a) {
+ f/=256.0;
+ f+=128.0;
+ if (f>254.5) *a=255;
+ else if (f<0.5) *a=0;
+ else *a=f;
+}
+
+static void clipit16(float f,short *a) {
+ if (f>32766.5) *a=32767;
+ else if (f<-32767.5) *a=-32768;
+ else *a=f;
+}
+#endif
+
+void adlibsetvolume(int i) {
+ AMPSCALE=i;
+}
+
+void adlibgetsample (unsigned char *sndptr, long numbytes)
+{
+ long i, j, k=0, ns, endsamples, rptrs, numsamples;
+ celltype *cptr;
+ float f;
+ short *sndptr2=(short *)sndptr;
+
+ numsamples = (numbytes>>(numspeakers+bytespersample-2));
+
+ if (bytespersample == 1) f = AMPSCALE/256.0; else f = AMPSCALE;
+ if (numspeakers == 1)
+ {
+ nlvol[0] = lvol[0]*f;
+ for(i=0;i<9;i++) rptr[i] = &rbuf[0][0];
+ rptrs = 1;
+ }
+ else
+ {
+ rptrs = 0;
+ for(i=0;i<9;i++)
+ {
+ if ((!i) || (lvol[i] != lvol[i-1]) || (rvol[i] != rvol[i-1]) ||
+ (lplc[i] != lplc[i-1]) || (rplc[i] != rplc[i-1]))
+ {
+ nlvol[rptrs] = lvol[i]*f;
+ nrvol[rptrs] = rvol[i]*f;
+ nlplc[rptrs] = rend-std::min(std::max(lplc[i],0L),(long)FIFOSIZ);
+ nrplc[rptrs] = rend-std::min(std::max(rplc[i],0L),(long)FIFOSIZ);
+ rptrs++;
+ }
+ rptr[i] = &rbuf[rptrs-1][0];
+ }
+ }
+
+
+ //CPU time used to be somewhat less when emulator was only mono!
+ // Because of no delay fifos!
+
+ for(ns=0;ns<numsamples;ns+=endsamples)
+ {
+ endsamples = std::min(FIFOSIZ*2-rend,(long)FIFOSIZ);
+ endsamples = std::min(endsamples,numsamples-ns);
+
+ for(i=0;i<9;i++)
+ nrptr[i] = &rptr[i][rend];
+ for(i=0;i<rptrs;i++)
+ memset((void *)&rbuf[i][rend],0,endsamples*sizeof(float));
+
+ if (adlibreg[0xbd]&0x20)
+ {
+ //BassDrum (j=6)
+ if (cell[15].cellfunc != docell4)
+ {
+ if (adlibreg[0xc6]&1)
+ {
+ for(i=0;i<endsamples;i++)
+ {
+ (cell[15].cellfunc)((void *)&cell[15],0.0);
+ nrptr[6][i] += cell[15].val;
+ }
+ }
+ else
+ {
+ for(i=0;i<endsamples;i++)
+ {
+ (cell[6].cellfunc)((void *)&cell[6],cell[6].val*cell[6].mfb);
+ (cell[15].cellfunc)((void *)&cell[15],cell[6].val*WAVPREC*MODFACTOR);
+ nrptr[6][i] += cell[15].val;
+ }
+ }
+ }
+
+ //Snare/Hihat (j=7), Cymbal/TomTom (j=8)
+ if ((cell[7].cellfunc != docell4) || (cell[8].cellfunc != docell4) || (cell[16].cellfunc != docell4) || (cell[17].cellfunc != docell4))
+ {
+ for(i=0;i<endsamples;i++)
+ {
+ k = k*1664525+1013904223;
+ (cell[16].cellfunc)((void *)&cell[16],k&((WAVPREC>>1)-1)); //Snare
+ (cell[7].cellfunc)((void *)&cell[7],k&(WAVPREC-1)); //Hihat
+ (cell[17].cellfunc)((void *)&cell[17],k&((WAVPREC>>3)-1)); //Cymbal
+ (cell[8].cellfunc)((void *)&cell[8],0.0); //TomTom
+ nrptr[7][i] += cell[7].val + cell[16].val;
+ nrptr[8][i] += cell[8].val + cell[17].val;
+ }
+ }
+ }
+ for(j=9-1;j>=0;j--)
+ {
+ if ((adlibreg[0xbd]&0x20) && (j >= 6) && (j < 9)) continue;
+
+ cptr = &cell[j]; k = j;
+ if (adlibreg[0xc0+k]&1)
+ {
+ if ((cptr[9].cellfunc == docell4) && (cptr->cellfunc == docell4)) continue;
+ for(i=0;i<endsamples;i++)
+ {
+ (cptr->cellfunc)((void *)cptr,cptr->val*cptr->mfb);
+ (cptr->cellfunc)((void *)&cptr[9],0);
+ nrptr[j][i] += cptr[9].val + cptr->val;
+ }
+ }
+ else
+ {
+ if (cptr[9].cellfunc == docell4) continue;
+ for(i=0;i<endsamples;i++)
+ {
+ (cptr->cellfunc)((void *)cptr,cptr->val*cptr->mfb);
+ (cptr[9].cellfunc)((void *)&cptr[9],cptr->val*WAVPREC*MODFACTOR);
+ nrptr[j][i] += cptr[9].val;
+ }
+ }
+ }
+
+ if (numspeakers == 1)
+ {
+ if (bytespersample == 1)
+ {
+ for(i=endsamples-1;i>=0;i--)
+ clipit8(nrptr[0][i]*nlvol[0],sndptr+1);
+ }
+ else
+ {
+ for(i=endsamples-1;i>=0;i--)
+ clipit16(nrptr[0][i]*nlvol[0],sndptr2+i);
+ }
+ }
+ else
+ {
+ memset((void *)snd,0,endsamples*sizeof(float)*2);
+ for(j=0;j<rptrs;j++)
+ {
+ for(i=0;i<endsamples;i++)
+ {
+ snd[(i<<1) ] += rbuf[j][(nlplc[j]+i)&(FIFOSIZ*2-1)]*nlvol[j];
+ snd[(i<<1)+1] += rbuf[j][(nrplc[j]+i)&(FIFOSIZ*2-1)]*nrvol[j];
+ }
+ nlplc[j] += endsamples;
+ nrplc[j] += endsamples;
+ }
+
+ if (bytespersample == 1)
+ {
+ for(i=(endsamples<<1)-1;i>=0;i--)
+ clipit8(snd[i],sndptr+i);
+ }
+ else
+ {
+ for(i=(endsamples<<1)-1;i>=0;i--)
+ clipit16(snd[i],sndptr2+i);
+ }
+ }
+
+ sndptr = sndptr+(numspeakers*endsamples);
+ sndptr2 = sndptr2+(numspeakers*endsamples);
+ rend = ((rend+endsamples)&(FIFOSIZ*2-1));
+ }
+}
diff --git a/src/adplug/core/adplug.cc b/src/adplug/core/adplug.cc
new file mode 100644
index 000000000000..b2eedc4a89af
--- /dev/null
+++ b/src/adplug/core/adplug.cc
@@ -0,0 +1,266 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2008 Simon Peter <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * adplug.cpp - CAdPlug utility class, by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <cstring>
+#include <string>
+#include <binfile.h>
+
+#include "adplug.h"
+#include "debug.h"
+
+/***** Replayer includes *****/
+
+#include "hsc.h"
+#include "amd.h"
+#include "a2m.h"
+#include "imf.h"
+#include "sng.h"
+#include "adtrack.h"
+#include "bam.h"
+#include "cmf.h"
+#include "d00.h"
+#include "dfm.h"
+#include "hsp.h"
+#include "ksm.h"
+#include "mad.h"
+#include "mid.h"
+#include "mkj.h"
+#include "cff.h"
+#include "dmo.h"
+#include "s3m.h"
+#include "dtm.h"
+#include "fmc.h"
+#include "mtk.h"
+#include "rad.h"
+#include "raw.h"
+#include "sa2.h"
+#include "bmf.h"
+#include "flash.h"
+#include "hybrid.h"
+#include "hyp.h"
+#include "psi.h"
+#include "rat.h"
+#include "lds.h"
+#include "u6m.h"
+#include "rol.h"
+#include "xsm.h"
+#include "dro.h"
+#include "dro2.h"
+#include "msc.h"
+#include "rix.h"
+#include "adl.h"
+#include "jbm.h"
+
+/***** Defines *****/
+
+#define ADPLUG_VERSION "1.6"
+
+/***** CAdPlug *****/
+
+// List of all players that come with the standard AdPlug distribution
+/*const CPlayerDesc
+ CAdPlug::allplayers[] = {
+ CPlayerDesc (ChscPlayer::factory, "HSC-Tracker", ".hsc\0"),
+ CPlayerDesc (CsngPlayer::factory, "SNGPlay", ".sng\0"),
+ CPlayerDesc (CimfPlayer::factory, "Apogee IMF", ".imf\0.wlf\0.adlib\0"),
+ CPlayerDesc (Ca2mLoader::factory, "Adlib Tracker 2", ".a2m\0"),
+ CPlayerDesc (CadtrackLoader::factory, "Adlib Tracker", ".sng\0"),
+ CPlayerDesc (CamdLoader::factory, "AMUSIC", ".amd\0"),
+ CPlayerDesc (CbamPlayer::factory, "Bob's Adlib Music", ".bam\0"),
+ CPlayerDesc (CcmfPlayer::factory, "Creative Music File", ".cmf\0"),
+ CPlayerDesc (Cd00Player::factory, "Packed EdLib", ".d00\0"),
+ CPlayerDesc (CdfmLoader::factory, "Digital-FM", ".dfm\0"),
+ CPlayerDesc (ChspLoader::factory, "HSC Packed", ".hsp\0"),
+ CPlayerDesc (CksmPlayer::factory, "Ken Silverman Music", ".ksm\0"),
+ CPlayerDesc (CmadLoader::factory, "Mlat Adlib Tracker", ".mad\0"),
+ CPlayerDesc (CmidPlayer::factory, "MIDI", ".sci\0.laa\0"),
+ CPlayerDesc (CmkjPlayer::factory, "MKJamz", ".mkj\0"),
+ CPlayerDesc (CcffLoader::factory, "Boomtracker", ".cff\0"),
+ CPlayerDesc (CdmoLoader::factory, "TwinTeam", ".dmo\0"),
+ CPlayerDesc (Cs3mPlayer::factory, "Scream Tracker 3", ".s3m\0"),
+ CPlayerDesc (CdtmLoader::factory, "DeFy Adlib Tracker", ".dtm\0"),
+ CPlayerDesc (CfmcLoader::factory, "Faust Music Creator", ".sng\0"),
+ CPlayerDesc (CmtkLoader::factory, "MPU-401 Trakker", ".mtk\0"),
+ CPlayerDesc (CradLoader::factory, "Reality Adlib Tracker", ".rad\0"),
+ CPlayerDesc (CrawPlayer::factory, "RdosPlay RAW", ".raw\0"),
+ CPlayerDesc (Csa2Loader::factory, "Surprise! Adlib Tracker",
+ ".sat\0.sa2\0"),
+ CPlayerDesc (CxadbmfPlayer::factory, "BMF Adlib Tracker", ".xad\0"),
+ CPlayerDesc (CxadflashPlayer::factory, "Flash", ".xad\0"),
+ CPlayerDesc (CxadhybridPlayer::factory, "Hybrid", ".xad\0"),
+ CPlayerDesc (CxadhypPlayer::factory, "Hypnosis", ".xad\0"),
+ CPlayerDesc (CxadpsiPlayer::factory, "PSI", ".xad\0"),
+ CPlayerDesc (CxadratPlayer::factory, "rat", ".xad\0"),
+ CPlayerDesc (CldsPlayer::factory, "LOUDNESS Sound System", ".lds\0"),
+ CPlayerDesc (Cu6mPlayer::factory, "Ultima 6 Music", ".m\0"),
+ CPlayerDesc (CrolPlayer::factory, "Adlib Visual Composer", ".rol\0"),
+ CPlayerDesc (CxsmPlayer::factory, "eXtra Simple Music", ".xsm\0"),
+ CPlayerDesc (CdroPlayer::factory, "DOSBox Raw OPL v0.1", ".dro\0"),
+ CPlayerDesc (Cdro2Player::factory, "DOSBox Raw OPL v2.0", ".dro\0"),
+ CPlayerDesc (CmscPlayer::factory, "Adlib MSC Player", ".msc\0"),
+ CPlayerDesc (CrixPlayer::factory, "Softstar RIX OPL Music", ".rix\0"),
+ CPlayerDesc (CadlPlayer::factory, "Westwood ADL", ".adl\0"),
+ CPlayerDesc (CjbmPlayer::factory, "Johannes Bjerregaard", ".jbm\0"),
+ CPlayerDesc ()
+};
+*/
+const
+ CPlayers &
+CAdPlug::init_players (const CPlayerDesc pd[])
+{
+ static CPlayers initplayers;
+ unsigned int i;
+
+ for (i = 0; pd[i].factory; i++)
+ initplayers.push_back (&pd[i]);
+
+ return initplayers;
+}
+
+const CPlayers& CAdPlug::getPlayers() {
+ static const CPlayerDesc
+ _allplayers[] = {
+ CPlayerDesc (ChscPlayer::factory, "HSC-Tracker", ".hsc\0"),
+ CPlayerDesc (CsngPlayer::factory, "SNGPlay", ".sng\0"),
+ CPlayerDesc (CimfPlayer::factory, "Apogee IMF", ".imf\0.wlf\0.adlib\0"),
+ CPlayerDesc (Ca2mLoader::factory, "Adlib Tracker 2", ".a2m\0"),
+ CPlayerDesc (CadtrackLoader::factory, "Adlib Tracker", ".sng\0"),
+ CPlayerDesc (CamdLoader::factory, "AMUSIC", ".amd\0"),
+ CPlayerDesc (CbamPlayer::factory, "Bob's Adlib Music", ".bam\0"),
+ CPlayerDesc (CcmfPlayer::factory, "Creative Music File", ".cmf\0"),
+ CPlayerDesc (Cd00Player::factory, "Packed EdLib", ".d00\0"),
+ CPlayerDesc (CdfmLoader::factory, "Digital-FM", ".dfm\0"),
+ CPlayerDesc (ChspLoader::factory, "HSC Packed", ".hsp\0"),
+ CPlayerDesc (CksmPlayer::factory, "Ken Silverman Music", ".ksm\0"),
+ CPlayerDesc (CmadLoader::factory, "Mlat Adlib Tracker", ".mad\0"),
+ CPlayerDesc (CmidPlayer::factory, "MIDI", ".sci\0.laa\0"),
+ CPlayerDesc (CmkjPlayer::factory, "MKJamz", ".mkj\0"),
+ CPlayerDesc (CcffLoader::factory, "Boomtracker", ".cff\0"),
+ CPlayerDesc (CdmoLoader::factory, "TwinTeam", ".dmo\0"),
+ CPlayerDesc (Cs3mPlayer::factory, "Scream Tracker 3", ".s3m\0"),
+ CPlayerDesc (CdtmLoader::factory, "DeFy Adlib Tracker", ".dtm\0"),
+ CPlayerDesc (CfmcLoader::factory, "Faust Music Creator", ".sng\0"),
+ CPlayerDesc (CmtkLoader::factory, "MPU-401 Trakker", ".mtk\0"),
+ CPlayerDesc (CradLoader::factory, "Reality Adlib Tracker", ".rad\0"),
+ CPlayerDesc (CrawPlayer::factory, "RdosPlay RAW", ".raw\0"),
+ CPlayerDesc (Csa2Loader::factory, "Surprise! Adlib Tracker",
+ ".sat\0.sa2\0"),
+ CPlayerDesc (CxadbmfPlayer::factory, "BMF Adlib Tracker", ".xad\0"),
+ CPlayerDesc (CxadflashPlayer::factory, "Flash", ".xad\0"),
+ CPlayerDesc (CxadhybridPlayer::factory, "Hybrid", ".xad\0"),
+ CPlayerDesc (CxadhypPlayer::factory, "Hypnosis", ".xad\0"),
+ CPlayerDesc (CxadpsiPlayer::factory, "PSI", ".xad\0"),
+ CPlayerDesc (CxadratPlayer::factory, "rat", ".xad\0"),
+ CPlayerDesc (CldsPlayer::factory, "LOUDNESS Sound System", ".lds\0"),
+ CPlayerDesc (Cu6mPlayer::factory, "Ultima 6 Music", ".m\0"),
+ CPlayerDesc (CrolPlayer::factory, "Adlib Visual Composer", ".rol\0"),
+ CPlayerDesc (CxsmPlayer::factory, "eXtra Simple Music", ".xsm\0"),
+ CPlayerDesc (CdroPlayer::factory, "DOSBox Raw OPL v0.1", ".dro\0"),
+ CPlayerDesc (Cdro2Player::factory, "DOSBox Raw OPL v2.0", ".dro\0"),
+ CPlayerDesc (CmscPlayer::factory, "Adlib MSC Player", ".msc\0"),
+ CPlayerDesc (CrixPlayer::factory, "Softstar RIX OPL Music", ".rix\0"),
+ CPlayerDesc (CadlPlayer::factory, "Westwood ADL", ".adl\0"),
+ CPlayerDesc (CjbmPlayer::factory, "Johannes Bjerregaard", ".jbm\0"),
+ CPlayerDesc ()
+ };
+ static CPlayers players = CAdPlug::init_players(_allplayers);
+ return players;
+}
+
+CAdPlugDatabase *
+ CAdPlug::database = 0;
+
+CPlayer *
+CAdPlug::factory (VFSFile & fd, Copl * opl, const CPlayers & pl,
+ const CFileProvider & fp)
+{
+ CPlayer *p;
+ CPlayers::const_iterator i;
+ unsigned int j;
+
+ // Try a direct hit by file extension
+ for (i = pl.begin (); i != pl.end (); i++)
+ {
+ for (j = 0; (*i)->get_extension (j); j++)
+ {
+ if (fp.extension (fd.filename (), (*i)->get_extension (j)))
+ {
+ AdPlug_LogWrite ("Trying direct hit: %s\n", (*i)->filetype.c_str ());
+
+ if ((p = (*i)->factory (opl)))
+ {
+ if (p->load (fd, fp))
+ {
+ AdPlug_LogWrite ("got it!\n");
+ AdPlug_LogWrite ("--- CAdPlug::factory ---\n");
+ return p;
+ }
+
+ delete p;
+
+ if (fd.fseek (0, VFS_SEEK_SET) < 0)
+ return 0;
+ }
+ }
+ }
+ }
+
+#if 0
+ // Try all players, one by one
+ for (i = pl.begin (); i != pl.end (); i++)
+ {
+ AdPlug_LogWrite ("Trying: %s\n", (*i)->filetype.c_str ());
+ if ((p = (*i)->factory (opl)))
+ if (p->load (fd, fp))
+ {
+ AdPlug_LogWrite ("got it!\n");
+ AdPlug_LogWrite ("--- CAdPlug::factory ---\n");
+ return p;
+ }
+ else
+ delete p;
+ }
+#endif
+
+ // Unknown file
+ AdPlug_LogWrite ("End of list!\n");
+ AdPlug_LogWrite ("--- CAdPlug::factory ---\n");
+ return 0;
+}
+
+void
+CAdPlug::set_database (CAdPlugDatabase * db)
+{
+ database = db;
+}
+
+std::string CAdPlug::get_version ()
+{
+ return std::string (ADPLUG_VERSION);
+}
+
+void
+CAdPlug::debug_output (const std::string & filename)
+{
+ AdPlug_LogFile (filename.c_str ());
+ AdPlug_LogWrite ("CAdPlug::debug_output(\"%s\"): Redirected.\n",
+ filename.c_str ());
+}
diff --git a/src/adplug/core/adplug.cxx b/src/adplug/core/adplug.cxx
deleted file mode 100644
index 8415a21b7e55..000000000000
--- a/src/adplug/core/adplug.cxx
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2008 Simon Peter <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * adplug.cpp - CAdPlug utility class, by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <cstring>
-#include <string>
-#include <binfile.h>
-
-#include "adplug.h"
-#include "debug.h"
-
-/***** Replayer includes *****/
-
-#include "hsc.h"
-#include "amd.h"
-#include "a2m.h"
-#include "imf.h"
-#include "sng.h"
-#include "adtrack.h"
-#include "bam.h"
-#include "cmf.h"
-#include "d00.h"
-#include "dfm.h"
-#include "hsp.h"
-#include "ksm.h"
-#include "mad.h"
-#include "mid.h"
-#include "mkj.h"
-#include "cff.h"
-#include "dmo.h"
-#include "s3m.h"
-#include "dtm.h"
-#include "fmc.h"
-#include "mtk.h"
-#include "rad.h"
-#include "raw.h"
-#include "sa2.h"
-#include "bmf.h"
-#include "flash.h"
-#include "hybrid.h"
-#include "hyp.h"
-#include "psi.h"
-#include "rat.h"
-#include "lds.h"
-#include "u6m.h"
-#include "rol.h"
-#include "xsm.h"
-#include "dro.h"
-#include "dro2.h"
-#include "msc.h"
-#include "rix.h"
-#include "adl.h"
-#include "jbm.h"
-
-/***** Defines *****/
-
-#define ADPLUG_VERSION "1.6"
-
-/***** CAdPlug *****/
-
-// List of all players that come with the standard AdPlug distribution
-/*const CPlayerDesc
- CAdPlug::allplayers[] = {
- CPlayerDesc (ChscPlayer::factory, "HSC-Tracker", ".hsc\0"),
- CPlayerDesc (CsngPlayer::factory, "SNGPlay", ".sng\0"),
- CPlayerDesc (CimfPlayer::factory, "Apogee IMF", ".imf\0.wlf\0.adlib\0"),
- CPlayerDesc (Ca2mLoader::factory, "Adlib Tracker 2", ".a2m\0"),
- CPlayerDesc (CadtrackLoader::factory, "Adlib Tracker", ".sng\0"),
- CPlayerDesc (CamdLoader::factory, "AMUSIC", ".amd\0"),
- CPlayerDesc (CbamPlayer::factory, "Bob's Adlib Music", ".bam\0"),
- CPlayerDesc (CcmfPlayer::factory, "Creative Music File", ".cmf\0"),
- CPlayerDesc (Cd00Player::factory, "Packed EdLib", ".d00\0"),
- CPlayerDesc (CdfmLoader::factory, "Digital-FM", ".dfm\0"),
- CPlayerDesc (ChspLoader::factory, "HSC Packed", ".hsp\0"),
- CPlayerDesc (CksmPlayer::factory, "Ken Silverman Music", ".ksm\0"),
- CPlayerDesc (CmadLoader::factory, "Mlat Adlib Tracker", ".mad\0"),
- CPlayerDesc (CmidPlayer::factory, "MIDI", ".sci\0.laa\0"),
- CPlayerDesc (CmkjPlayer::factory, "MKJamz", ".mkj\0"),
- CPlayerDesc (CcffLoader::factory, "Boomtracker", ".cff\0"),
- CPlayerDesc (CdmoLoader::factory, "TwinTeam", ".dmo\0"),
- CPlayerDesc (Cs3mPlayer::factory, "Scream Tracker 3", ".s3m\0"),
- CPlayerDesc (CdtmLoader::factory, "DeFy Adlib Tracker", ".dtm\0"),
- CPlayerDesc (CfmcLoader::factory, "Faust Music Creator", ".sng\0"),
- CPlayerDesc (CmtkLoader::factory, "MPU-401 Trakker", ".mtk\0"),
- CPlayerDesc (CradLoader::factory, "Reality Adlib Tracker", ".rad\0"),
- CPlayerDesc (CrawPlayer::factory, "RdosPlay RAW", ".raw\0"),
- CPlayerDesc (Csa2Loader::factory, "Surprise! Adlib Tracker",
- ".sat\0.sa2\0"),
- CPlayerDesc (CxadbmfPlayer::factory, "BMF Adlib Tracker", ".xad\0"),
- CPlayerDesc (CxadflashPlayer::factory, "Flash", ".xad\0"),
- CPlayerDesc (CxadhybridPlayer::factory, "Hybrid", ".xad\0"),
- CPlayerDesc (CxadhypPlayer::factory, "Hypnosis", ".xad\0"),
- CPlayerDesc (CxadpsiPlayer::factory, "PSI", ".xad\0"),
- CPlayerDesc (CxadratPlayer::factory, "rat", ".xad\0"),
- CPlayerDesc (CldsPlayer::factory, "LOUDNESS Sound System", ".lds\0"),
- CPlayerDesc (Cu6mPlayer::factory, "Ultima 6 Music", ".m\0"),
- CPlayerDesc (CrolPlayer::factory, "Adlib Visual Composer", ".rol\0"),
- CPlayerDesc (CxsmPlayer::factory, "eXtra Simple Music", ".xsm\0"),
- CPlayerDesc (CdroPlayer::factory, "DOSBox Raw OPL v0.1", ".dro\0"),
- CPlayerDesc (Cdro2Player::factory, "DOSBox Raw OPL v2.0", ".dro\0"),
- CPlayerDesc (CmscPlayer::factory, "Adlib MSC Player", ".msc\0"),
- CPlayerDesc (CrixPlayer::factory, "Softstar RIX OPL Music", ".rix\0"),
- CPlayerDesc (CadlPlayer::factory, "Westwood ADL", ".adl\0"),
- CPlayerDesc (CjbmPlayer::factory, "Johannes Bjerregaard", ".jbm\0"),
- CPlayerDesc ()
-};
-*/
-const
- CPlayers &
-CAdPlug::init_players (const CPlayerDesc pd[])
-{
- static CPlayers initplayers;
- unsigned int i;
-
- for (i = 0; pd[i].factory; i++)
- initplayers.push_back (&pd[i]);
-
- return initplayers;
-}
-
-const CPlayers& CAdPlug::getPlayers() {
- static const CPlayerDesc
- _allplayers[] = {
- CPlayerDesc (ChscPlayer::factory, "HSC-Tracker", ".hsc\0"),
- CPlayerDesc (CsngPlayer::factory, "SNGPlay", ".sng\0"),
- CPlayerDesc (CimfPlayer::factory, "Apogee IMF", ".imf\0.wlf\0.adlib\0"),
- CPlayerDesc (Ca2mLoader::factory, "Adlib Tracker 2", ".a2m\0"),
- CPlayerDesc (CadtrackLoader::factory, "Adlib Tracker", ".sng\0"),
- CPlayerDesc (CamdLoader::factory, "AMUSIC", ".amd\0"),
- CPlayerDesc (CbamPlayer::factory, "Bob's Adlib Music", ".bam\0"),
- CPlayerDesc (CcmfPlayer::factory, "Creative Music File", ".cmf\0"),
- CPlayerDesc (Cd00Player::factory, "Packed EdLib", ".d00\0"),
- CPlayerDesc (CdfmLoader::factory, "Digital-FM", ".dfm\0"),
- CPlayerDesc (ChspLoader::factory, "HSC Packed", ".hsp\0"),
- CPlayerDesc (CksmPlayer::factory, "Ken Silverman Music", ".ksm\0"),
- CPlayerDesc (CmadLoader::factory, "Mlat Adlib Tracker", ".mad\0"),
- CPlayerDesc (CmidPlayer::factory, "MIDI", ".sci\0.laa\0"),
- CPlayerDesc (CmkjPlayer::factory, "MKJamz", ".mkj\0"),
- CPlayerDesc (CcffLoader::factory, "Boomtracker", ".cff\0"),
- CPlayerDesc (CdmoLoader::factory, "TwinTeam", ".dmo\0"),
- CPlayerDesc (Cs3mPlayer::factory, "Scream Tracker 3", ".s3m\0"),
- CPlayerDesc (CdtmLoader::factory, "DeFy Adlib Tracker", ".dtm\0"),
- CPlayerDesc (CfmcLoader::factory, "Faust Music Creator", ".sng\0"),
- CPlayerDesc (CmtkLoader::factory, "MPU-401 Trakker", ".mtk\0"),
- CPlayerDesc (CradLoader::factory, "Reality Adlib Tracker", ".rad\0"),
- CPlayerDesc (CrawPlayer::factory, "RdosPlay RAW", ".raw\0"),
- CPlayerDesc (Csa2Loader::factory, "Surprise! Adlib Tracker",
- ".sat\0.sa2\0"),
- CPlayerDesc (CxadbmfPlayer::factory, "BMF Adlib Tracker", ".xad\0"),
- CPlayerDesc (CxadflashPlayer::factory, "Flash", ".xad\0"),
- CPlayerDesc (CxadhybridPlayer::factory, "Hybrid", ".xad\0"),
- CPlayerDesc (CxadhypPlayer::factory, "Hypnosis", ".xad\0"),
- CPlayerDesc (CxadpsiPlayer::factory, "PSI", ".xad\0"),
- CPlayerDesc (CxadratPlayer::factory, "rat", ".xad\0"),
- CPlayerDesc (CldsPlayer::factory, "LOUDNESS Sound System", ".lds\0"),
- CPlayerDesc (Cu6mPlayer::factory, "Ultima 6 Music", ".m\0"),
- CPlayerDesc (CrolPlayer::factory, "Adlib Visual Composer", ".rol\0"),
- CPlayerDesc (CxsmPlayer::factory, "eXtra Simple Music", ".xsm\0"),
- CPlayerDesc (CdroPlayer::factory, "DOSBox Raw OPL v0.1", ".dro\0"),
- CPlayerDesc (Cdro2Player::factory, "DOSBox Raw OPL v2.0", ".dro\0"),
- CPlayerDesc (CmscPlayer::factory, "Adlib MSC Player", ".msc\0"),
- CPlayerDesc (CrixPlayer::factory, "Softstar RIX OPL Music", ".rix\0"),
- CPlayerDesc (CadlPlayer::factory, "Westwood ADL", ".adl\0"),
- CPlayerDesc (CjbmPlayer::factory, "Johannes Bjerregaard", ".jbm\0"),
- CPlayerDesc ()
- };
- static CPlayers players = CAdPlug::init_players(_allplayers);
- return players;
-}
-
-CAdPlugDatabase *
- CAdPlug::database = 0;
-
-CPlayer *
-CAdPlug::factory (VFSFile * fd, Copl * opl, const CPlayers & pl,
- const CFileProvider & fp)
-{
- CPlayer *p;
- CPlayers::const_iterator i;
- unsigned int j;
-
- // Try a direct hit by file extension
- for (i = pl.begin (); i != pl.end (); i++)
- {
- for (j = 0; (*i)->get_extension (j); j++)
- {
- if (fp.extension (vfs_get_filename (fd), (*i)->get_extension (j)))
- {
- AdPlug_LogWrite ("Trying direct hit: %s\n", (*i)->filetype.c_str ());
-
- if ((p = (*i)->factory (opl)))
- {
- if (p->load (fd, fp))
- {
- AdPlug_LogWrite ("got it!\n");
- AdPlug_LogWrite ("--- CAdPlug::factory ---\n");
- return p;
- }
-
- delete p;
-
- if (vfs_fseek (fd, 0, SEEK_SET) < 0)
- return 0;
- }
- }
- }
- }
-
-#if 0
- // Try all players, one by one
- for (i = pl.begin (); i != pl.end (); i++)
- {
- AdPlug_LogWrite ("Trying: %s\n", (*i)->filetype.c_str ());
- if ((p = (*i)->factory (opl)))
- if (p->load (fd, fp))
- {
- AdPlug_LogWrite ("got it!\n");
- AdPlug_LogWrite ("--- CAdPlug::factory ---\n");
- return p;
- }
- else
- delete p;
- }
-#endif
-
- // Unknown file
- AdPlug_LogWrite ("End of list!\n");
- AdPlug_LogWrite ("--- CAdPlug::factory ---\n");
- return 0;
-}
-
-void
-CAdPlug::set_database (CAdPlugDatabase * db)
-{
- database = db;
-}
-
-std::string CAdPlug::get_version ()
-{
- return std::string (ADPLUG_VERSION);
-}
-
-void
-CAdPlug::debug_output (const std::string & filename)
-{
- AdPlug_LogFile (filename.c_str ());
- AdPlug_LogWrite ("CAdPlug::debug_output(\"%s\"): Redirected.\n",
- filename.c_str ());
-}
diff --git a/src/adplug/core/adplug.h b/src/adplug/core/adplug.h
index 15b676da6c7e..1283ea792846 100644
--- a/src/adplug/core/adplug.h
+++ b/src/adplug/core/adplug.h
@@ -37,7 +37,7 @@ class CAdPlug
public:
static const CPlayers& getPlayers();
- static CPlayer *factory(VFSFile *fd, Copl *opl,
+ static CPlayer *factory(VFSFile &fd, Copl *opl,
const CPlayers &pl = getPlayers(),
const CFileProvider &fp = CProvider_Filesystem());
diff --git a/src/adplug/core/adtrack.cc b/src/adplug/core/adtrack.cc
new file mode 100644
index 000000000000..b4101802afe5
--- /dev/null
+++ b/src/adplug/core/adtrack.cc
@@ -0,0 +1,238 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 Simon Peter <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * adtrack.cpp - Adlib Tracker 1.0 Loader by Simon Peter <dn.tlp at gmx.net>
+ *
+ * NOTES:
+ * The original Adlib Tracker 1.0 is behaving a little different from the
+ * official spec: The 'octave' integer from the instrument file is stored
+ * "minus 1" from the actual value, underflowing from 0 to 0xffff.
+ *
+ * I also noticed that my player is playing everything transposed a few tones
+ * higher than the original tracker. As far as i can see, my player perfectly
+ * follows the official spec, so it "must" be the tracker that does something
+ * wrong here...
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "adtrack.h"
+#include "debug.h"
+
+/*** Public methods ***/
+
+CPlayer *
+CadtrackLoader::factory (Copl * newopl)
+{
+ return new CadtrackLoader (newopl);
+}
+
+bool
+CadtrackLoader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ binistream *instf;
+ char note[2];
+ unsigned short rwp;
+ unsigned char chp, octave, pnote = 0;
+ int i, j;
+ AdTrackInst myinst;
+ std::string filename (fd.filename ());
+
+ // file validation
+ if (!fp.extension (filename, ".sng") || fp.filesize (f) != 36000)
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // check for instruments file
+ std::string instfilename (filename, 0, filename.find_last_of ('.'));
+ instfilename += ".ins";
+ AdPlug_LogWrite ("CadtrackLoader::load(,\"%s\"): Checking for \"%s\"...\n",
+ filename.c_str (), instfilename.c_str ());
+
+ VFSFile instfd (instfilename.c_str (), "rb");
+ instf = fp.open (instfd);
+ if (!instf || fp.filesize (instf) != 468)
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // give CmodPlayer a hint on what we're up to
+ realloc_patterns (1, 1000, 9);
+ realloc_instruments (9);
+ realloc_order (1);
+ init_trackord ();
+ flags = NoKeyOn;
+ (*order) = 0;
+ length = 1;
+ restartpos = 0;
+ bpm = 120;
+ initspeed = 3;
+
+ // load instruments from instruments file
+ for (i = 0; i < 9; i++)
+ {
+ for (j = 0; j < 2; j++)
+ {
+ myinst.op[j].appampmod = instf->readInt (2);
+ myinst.op[j].appvib = instf->readInt (2);
+ myinst.op[j].maintsuslvl = instf->readInt (2);
+ myinst.op[j].keybscale = instf->readInt (2);
+ myinst.op[j].octave = instf->readInt (2);
+ myinst.op[j].freqrisevollvldn = instf->readInt (2);
+ myinst.op[j].softness = instf->readInt (2);
+ myinst.op[j].attack = instf->readInt (2);
+ myinst.op[j].decay = instf->readInt (2);
+ myinst.op[j].release = instf->readInt (2);
+ myinst.op[j].sustain = instf->readInt (2);
+ myinst.op[j].feedback = instf->readInt (2);
+ myinst.op[j].waveform = instf->readInt (2);
+ }
+ convert_instrument (i, &myinst);
+ }
+ fp.close (instf);
+
+ // load file
+ for (rwp = 0; rwp < 1000; rwp++)
+ for (chp = 0; chp < 9; chp++)
+ {
+ // read next record
+ f->readString (note, 2);
+ octave = f->readInt (1);
+ f->ignore ();
+ switch (*note)
+ {
+ case 'C':
+ if (note[1] == '#')
+ pnote = 2;
+ else
+ pnote = 1;
+ break;
+ case 'D':
+ if (note[1] == '#')
+ pnote = 4;
+ else
+ pnote = 3;
+ break;
+ case 'E':
+ pnote = 5;
+ break;
+ case 'F':
+ if (note[1] == '#')
+ pnote = 7;
+ else
+ pnote = 6;
+ break;
+ case 'G':
+ if (note[1] == '#')
+ pnote = 9;
+ else
+ pnote = 8;
+ break;
+ case 'A':
+ if (note[1] == '#')
+ pnote = 11;
+ else
+ pnote = 10;
+ break;
+ case 'B':
+ pnote = 12;
+ break;
+ case '\0':
+ if (note[1] == '\0')
+ tracks[chp][rwp].note = 127;
+ else
+ {
+ fp.close (f);
+ return false;
+ }
+ break;
+ default:
+ fp.close (f);
+ return false;
+ }
+ if ((*note) != '\0')
+ {
+ tracks[chp][rwp].note = pnote + (octave * 12);
+ tracks[chp][rwp].inst = chp + 1;
+ }
+ }
+
+ fp.close (f);
+ rewind (0);
+ return true;
+}
+
+float
+CadtrackLoader::getrefresh ()
+{
+ return 18.2f;
+}
+
+/*** Private methods ***/
+
+void
+CadtrackLoader::convert_instrument (unsigned int n, AdTrackInst * i)
+{
+ // Carrier "Amp Mod / Vib / Env Type / KSR / Multiple" register
+ inst[n].data[2] = i->op[Carrier].appampmod ? 1 << 7 : 0;
+ inst[n].data[2] += i->op[Carrier].appvib ? 1 << 6 : 0;
+ inst[n].data[2] += i->op[Carrier].maintsuslvl ? 1 << 5 : 0;
+ inst[n].data[2] += i->op[Carrier].keybscale ? 1 << 4 : 0;
+ inst[n].data[2] += (i->op[Carrier].octave + 1) & 0xffff; // Bug in original tracker
+ // Modulator...
+ inst[n].data[1] = i->op[Modulator].appampmod ? 1 << 7 : 0;
+ inst[n].data[1] += i->op[Modulator].appvib ? 1 << 6 : 0;
+ inst[n].data[1] += i->op[Modulator].maintsuslvl ? 1 << 5 : 0;
+ inst[n].data[1] += i->op[Modulator].keybscale ? 1 << 4 : 0;
+ inst[n].data[1] += (i->op[Modulator].octave + 1) & 0xffff; // Bug in original tracker
+
+ // Carrier "Key Scaling / Level" register
+ inst[n].data[10] = (i->op[Carrier].freqrisevollvldn & 3) << 6;
+ inst[n].data[10] += i->op[Carrier].softness & 63;
+ // Modulator...
+ inst[n].data[9] = (i->op[Modulator].freqrisevollvldn & 3) << 6;
+ inst[n].data[9] += i->op[Modulator].softness & 63;
+
+ // Carrier "Attack / Decay" register
+ inst[n].data[4] = (i->op[Carrier].attack & 0x0f) << 4;
+ inst[n].data[4] += i->op[Carrier].decay & 0x0f;
+ // Modulator...
+ inst[n].data[3] = (i->op[Modulator].attack & 0x0f) << 4;
+ inst[n].data[3] += i->op[Modulator].decay & 0x0f;
+
+ // Carrier "Release / Sustain" register
+ inst[n].data[6] = (i->op[Carrier].release & 0x0f) << 4;
+ inst[n].data[6] += i->op[Carrier].sustain & 0x0f;
+ // Modulator...
+ inst[n].data[5] = (i->op[Modulator].release & 0x0f) << 4;
+ inst[n].data[5] += i->op[Modulator].sustain & 0x0f;
+
+ // Channel "Feedback / Connection" register
+ inst[n].data[0] = (i->op[Carrier].feedback & 7) << 1;
+
+ // Carrier/Modulator "Wave Select" registers
+ inst[n].data[8] = i->op[Carrier].waveform & 3;
+ inst[n].data[7] = i->op[Modulator].waveform & 3;
+}
diff --git a/src/adplug/core/adtrack.cxx b/src/adplug/core/adtrack.cxx
deleted file mode 100644
index 214d59268aaf..000000000000
--- a/src/adplug/core/adtrack.cxx
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * adtrack.cpp - Adlib Tracker 1.0 Loader by Simon Peter <dn.tlp at gmx.net>
- *
- * NOTES:
- * The original Adlib Tracker 1.0 is behaving a little different from the
- * official spec: The 'octave' integer from the instrument file is stored
- * "minus 1" from the actual value, underflowing from 0 to 0xffff.
- *
- * I also noticed that my player is playing everything transposed a few tones
- * higher than the original tracker. As far as i can see, my player perfectly
- * follows the official spec, so it "must" be the tracker that does something
- * wrong here...
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "adtrack.h"
-#include "debug.h"
-
-/*** Public methods ***/
-
-CPlayer *
-CadtrackLoader::factory (Copl * newopl)
-{
- return new CadtrackLoader (newopl);
-}
-
-bool
-CadtrackLoader::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- binistream *instf;
- char note[2];
- unsigned short rwp;
- unsigned char chp, octave, pnote = 0;
- int i, j;
- AdTrackInst myinst;
- std::string filename (vfs_get_filename (fd));
-
- // file validation
- if (!fp.extension (filename, ".sng") || fp.filesize (f) != 36000)
- {
- fp.close (f);
- return false;
- }
-
- // check for instruments file
- std::string instfilename (filename, 0, filename.find_last_of ('.'));
- instfilename += ".ins";
- AdPlug_LogWrite ("CadtrackLoader::load(,\"%s\"): Checking for \"%s\"...\n",
- filename.c_str (), instfilename.c_str ());
-
- VFSFile *instfd = vfs_fopen (instfilename.c_str (), "rb");
- instf = fp.open (instfd);
- if (!instf || fp.filesize (instf) != 468)
- {
- fp.close (f);
- vfs_fclose (instfd);
- return false;
- }
-
- // give CmodPlayer a hint on what we're up to
- realloc_patterns (1, 1000, 9);
- realloc_instruments (9);
- realloc_order (1);
- init_trackord ();
- flags = NoKeyOn;
- (*order) = 0;
- length = 1;
- restartpos = 0;
- bpm = 120;
- initspeed = 3;
-
- // load instruments from instruments file
- for (i = 0; i < 9; i++)
- {
- for (j = 0; j < 2; j++)
- {
- myinst.op[j].appampmod = instf->readInt (2);
- myinst.op[j].appvib = instf->readInt (2);
- myinst.op[j].maintsuslvl = instf->readInt (2);
- myinst.op[j].keybscale = instf->readInt (2);
- myinst.op[j].octave = instf->readInt (2);
- myinst.op[j].freqrisevollvldn = instf->readInt (2);
- myinst.op[j].softness = instf->readInt (2);
- myinst.op[j].attack = instf->readInt (2);
- myinst.op[j].decay = instf->readInt (2);
- myinst.op[j].release = instf->readInt (2);
- myinst.op[j].sustain = instf->readInt (2);
- myinst.op[j].feedback = instf->readInt (2);
- myinst.op[j].waveform = instf->readInt (2);
- }
- convert_instrument (i, &myinst);
- }
- fp.close (instf);
-
- // load file
- for (rwp = 0; rwp < 1000; rwp++)
- for (chp = 0; chp < 9; chp++)
- {
- // read next record
- f->readString (note, 2);
- octave = f->readInt (1);
- f->ignore ();
- switch (*note)
- {
- case 'C':
- if (note[1] == '#')
- pnote = 2;
- else
- pnote = 1;
- break;
- case 'D':
- if (note[1] == '#')
- pnote = 4;
- else
- pnote = 3;
- break;
- case 'E':
- pnote = 5;
- break;
- case 'F':
- if (note[1] == '#')
- pnote = 7;
- else
- pnote = 6;
- break;
- case 'G':
- if (note[1] == '#')
- pnote = 9;
- else
- pnote = 8;
- break;
- case 'A':
- if (note[1] == '#')
- pnote = 11;
- else
- pnote = 10;
- break;
- case 'B':
- pnote = 12;
- break;
- case '\0':
- if (note[1] == '\0')
- tracks[chp][rwp].note = 127;
- else
- {
- fp.close (f);
- return false;
- }
- break;
- default:
- fp.close (f);
- return false;
- }
- if ((*note) != '\0')
- {
- tracks[chp][rwp].note = pnote + (octave * 12);
- tracks[chp][rwp].inst = chp + 1;
- }
- }
-
- fp.close (f);
- rewind (0);
- return true;
-}
-
-float
-CadtrackLoader::getrefresh ()
-{
- return 18.2f;
-}
-
-/*** Private methods ***/
-
-void
-CadtrackLoader::convert_instrument (unsigned int n, AdTrackInst * i)
-{
- // Carrier "Amp Mod / Vib / Env Type / KSR / Multiple" register
- inst[n].data[2] = i->op[Carrier].appampmod ? 1 << 7 : 0;
- inst[n].data[2] += i->op[Carrier].appvib ? 1 << 6 : 0;
- inst[n].data[2] += i->op[Carrier].maintsuslvl ? 1 << 5 : 0;
- inst[n].data[2] += i->op[Carrier].keybscale ? 1 << 4 : 0;
- inst[n].data[2] += (i->op[Carrier].octave + 1) & 0xffff; // Bug in original tracker
- // Modulator...
- inst[n].data[1] = i->op[Modulator].appampmod ? 1 << 7 : 0;
- inst[n].data[1] += i->op[Modulator].appvib ? 1 << 6 : 0;
- inst[n].data[1] += i->op[Modulator].maintsuslvl ? 1 << 5 : 0;
- inst[n].data[1] += i->op[Modulator].keybscale ? 1 << 4 : 0;
- inst[n].data[1] += (i->op[Modulator].octave + 1) & 0xffff; // Bug in original tracker
-
- // Carrier "Key Scaling / Level" register
- inst[n].data[10] = (i->op[Carrier].freqrisevollvldn & 3) << 6;
- inst[n].data[10] += i->op[Carrier].softness & 63;
- // Modulator...
- inst[n].data[9] = (i->op[Modulator].freqrisevollvldn & 3) << 6;
- inst[n].data[9] += i->op[Modulator].softness & 63;
-
- // Carrier "Attack / Decay" register
- inst[n].data[4] = (i->op[Carrier].attack & 0x0f) << 4;
- inst[n].data[4] += i->op[Carrier].decay & 0x0f;
- // Modulator...
- inst[n].data[3] = (i->op[Modulator].attack & 0x0f) << 4;
- inst[n].data[3] += i->op[Modulator].decay & 0x0f;
-
- // Carrier "Release / Sustain" register
- inst[n].data[6] = (i->op[Carrier].release & 0x0f) << 4;
- inst[n].data[6] += i->op[Carrier].sustain & 0x0f;
- // Modulator...
- inst[n].data[5] = (i->op[Modulator].release & 0x0f) << 4;
- inst[n].data[5] += i->op[Modulator].sustain & 0x0f;
-
- // Channel "Feedback / Connection" register
- inst[n].data[0] = (i->op[Carrier].feedback & 7) << 1;
-
- // Carrier/Modulator "Wave Select" registers
- inst[n].data[8] = i->op[Carrier].waveform & 3;
- inst[n].data[7] = i->op[Modulator].waveform & 3;
-}
diff --git a/src/adplug/core/adtrack.h b/src/adplug/core/adtrack.h
index 6cf1e1a55398..c4df63381da4 100644
--- a/src/adplug/core/adtrack.h
+++ b/src/adplug/core/adtrack.h
@@ -30,7 +30,7 @@ public:
: CmodPlayer(newopl)
{ };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
float getrefresh();
std::string gettype()
diff --git a/src/adplug/core/amd.cc b/src/adplug/core/amd.cc
new file mode 100644
index 000000000000..215a485cb57b
--- /dev/null
+++ b/src/adplug/core/amd.cc
@@ -0,0 +1,231 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * amd.cpp - AMD Loader by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <string.h>
+
+#include "amd.h"
+#include "debug.h"
+
+CPlayer *
+CamdLoader::factory (Copl * newopl)
+{
+ return new CamdLoader (newopl);
+}
+
+bool
+CamdLoader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ struct
+ {
+ char id[9];
+ unsigned char version;
+ } header;
+ int i, j, k, t, numtrax, maxi = 0;
+ unsigned char buf, buf2, buf3;
+ const unsigned char convfx[10] = { 0, 1, 2, 9, 17, 11, 13, 18, 3, 14 };
+ const unsigned char convvol[64] = {
+ 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 0xa, 0xa, 0xb,
+ 0xc, 0xc, 0xd, 0xe, 0xe, 0xf, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21,
+ 0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2b, 0x2d, 0x2e, 0x30, 0x32, 0x35,
+ 0x37, 0x3a, 0x3c, 0x3f
+ };
+
+ // file validation section
+ if (fp.filesize (f) < 1072)
+ {
+ fp.close (f);
+ return false;
+ }
+ f->seek (1062);
+ f->readString (header.id, 9);
+ header.version = f->readInt (1);
+ if (strncmp (header.id, "<o\xefQU\xeeRoR", 9) &&
+ strncmp (header.id, "MaDoKaN96", 9))
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // load section
+ memset (inst, 0, 26 * sizeof (inst[0])); // memset (inst, 0, sizeof (inst));
+ f->seek (0);
+ f->readString (songname, sizeof (songname));
+ f->readString (author, sizeof (author));
+ for (i = 0; i < 26; i++)
+ {
+ f->readString (instname[i], 23);
+ for (j = 0; j < 11; j++)
+ inst[i].data[j] = f->readInt (1);
+ }
+ length = f->readInt (1);
+ nop = f->readInt (1) + 1;
+ for (i = 0; i < 128; i++)
+ order[i] = f->readInt (1);
+ f->seek (10, binio::Add);
+ if (header.version == 0x10)
+ { // unpacked module
+ maxi = nop * 9;
+ for (i = 0; i < 64 * 9; i++)
+ trackord[i / 9][i % 9] = i + 1;
+ t = 0;
+ while (!f->ateof ())
+ {
+ for (j = 0; j < 64; j++)
+ for (i = t; i < t + 9; i++)
+ {
+ buf = f->readInt (1);
+ tracks[i][j].param2 = (buf & 127) % 10;
+ tracks[i][j].param1 = (buf & 127) / 10;
+ buf = f->readInt (1);
+ tracks[i][j].inst = buf >> 4;
+ tracks[i][j].command = buf & 0x0f;
+ buf = f->readInt (1);
+ if (buf >> 4) // fix bug in AMD save routine
+ tracks[i][j].note = ((buf & 14) >> 1) * 12 + (buf >> 4);
+ else
+ tracks[i][j].note = 0;
+ tracks[i][j].inst += (buf & 1) << 4;
+ }
+ t += 9;
+ }
+ }
+ else
+ { // packed module
+ for (i = 0; i < nop; i++)
+ for (j = 0; j < 9; j++)
+ trackord[i][j] = f->readInt (2) + 1;
+ numtrax = f->readInt (2);
+ for (k = 0; k < numtrax; k++)
+ {
+ i = f->readInt (2);
+ if (i > 575)
+ i = 575; // fix corrupted modules
+ maxi = (i + 1 > maxi ? i + 1 : maxi);
+ j = 0;
+ do
+ {
+ buf = f->readInt (1);
+ if (buf & 128)
+ {
+ for (t = j; t < j + (buf & 127) && t < 64; t++)
+ {
+ tracks[i][t].command = 0;
+ tracks[i][t].inst = 0;
+ tracks[i][t].note = 0;
+ tracks[i][t].param1 = 0;
+ tracks[i][t].param2 = 0;
+ }
+ j += buf & 127;
+ continue;
+ }
+ tracks[i][j].param2 = buf % 10;
+ tracks[i][j].param1 = buf / 10;
+ buf = f->readInt (1);
+ tracks[i][j].inst = buf >> 4;
+ tracks[i][j].command = buf & 0x0f;
+ buf = f->readInt (1);
+ if (buf >> 4) // fix bug in AMD save routine
+ tracks[i][j].note = ((buf & 14) >> 1) * 12 + (buf >> 4);
+ else
+ tracks[i][j].note = 0;
+ tracks[i][j].inst += (buf & 1) << 4;
+ j++;
+ } while (j < 64);
+ }
+ }
+ fp.close (f);
+
+ // convert to protracker replay data
+ bpm = 50;
+ restartpos = 0;
+ flags = Decimal;
+ for (i = 0; i < 26; i++)
+ { // convert instruments
+ buf = inst[i].data[0];
+ buf2 = inst[i].data[1];
+ inst[i].data[0] = inst[i].data[10];
+ inst[i].data[1] = buf;
+ buf = inst[i].data[2];
+ inst[i].data[2] = inst[i].data[5];
+ buf3 = inst[i].data[3];
+ inst[i].data[3] = buf;
+ buf = inst[i].data[4];
+ inst[i].data[4] = inst[i].data[7];
+ inst[i].data[5] = buf3;
+ buf3 = inst[i].data[6];
+ inst[i].data[6] = inst[i].data[8];
+ inst[i].data[7] = buf;
+ inst[i].data[8] = inst[i].data[9];
+ inst[i].data[9] = buf2;
+ inst[i].data[10] = buf3;
+ for (j = 0; j < 23; j++) // convert names
+ if (instname[i][j] == '\xff')
+ instname[i][j] = '\x20';
+ }
+ for (i = 0; i < maxi; i++) // convert patterns
+ for (j = 0; j < 64; j++)
+ {
+ tracks[i][j].command = convfx[tracks[i][j].command];
+ // extended command
+ if (tracks[i][j].command == 14)
+ {
+ if (tracks[i][j].param1 == 2)
+ {
+ tracks[i][j].command = 10;
+ tracks[i][j].param1 = tracks[i][j].param2;
+ tracks[i][j].param2 = 0;
+ }
+
+ if (tracks[i][j].param1 == 3)
+ {
+ tracks[i][j].command = 10;
+ tracks[i][j].param1 = 0;
+ }
+ }
+
+ // fix volume
+ if (tracks[i][j].command == 17)
+ {
+ int vol = convvol[tracks[i][j].param1 * 10 + tracks[i][j].param2];
+
+ if (vol > 63)
+ vol = 63;
+ tracks[i][j].param1 = vol / 10;
+ tracks[i][j].param2 = vol % 10;
+ }
+ }
+
+ rewind (0);
+ return true;
+}
+
+float
+CamdLoader::getrefresh ()
+{
+ if (tempo)
+ return (float) (tempo);
+ else
+ return 18.2f;
+}
diff --git a/src/adplug/core/amd.cxx b/src/adplug/core/amd.cxx
deleted file mode 100644
index 1eb49fa28345..000000000000
--- a/src/adplug/core/amd.cxx
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * amd.cpp - AMD Loader by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <string.h>
-
-#include "amd.h"
-#include "debug.h"
-
-CPlayer *
-CamdLoader::factory (Copl * newopl)
-{
- return new CamdLoader (newopl);
-}
-
-bool
-CamdLoader::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- struct
- {
- char id[9];
- unsigned char version;
- } header;
- int i, j, k, t, numtrax, maxi = 0;
- unsigned char buf, buf2, buf3;
- const unsigned char convfx[10] = { 0, 1, 2, 9, 17, 11, 13, 18, 3, 14 };
- const unsigned char convvol[64] = {
- 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 0xa, 0xa, 0xb,
- 0xc, 0xc, 0xd, 0xe, 0xe, 0xf, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x14,
- 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21,
- 0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2b, 0x2d, 0x2e, 0x30, 0x32, 0x35,
- 0x37, 0x3a, 0x3c, 0x3f
- };
-
- // file validation section
- if (fp.filesize (f) < 1072)
- {
- fp.close (f);
- return false;
- }
- f->seek (1062);
- f->readString (header.id, 9);
- header.version = f->readInt (1);
- if (strncmp (header.id, "<o\xefQU\xeeRoR", 9) &&
- strncmp (header.id, "MaDoKaN96", 9))
- {
- fp.close (f);
- return false;
- }
-
- // load section
- memset (inst, 0, 26 * sizeof (inst[0])); // memset (inst, 0, sizeof (inst));
- f->seek (0);
- f->readString (songname, sizeof (songname));
- f->readString (author, sizeof (author));
- for (i = 0; i < 26; i++)
- {
- f->readString (instname[i], 23);
- for (j = 0; j < 11; j++)
- inst[i].data[j] = f->readInt (1);
- }
- length = f->readInt (1);
- nop = f->readInt (1) + 1;
- for (i = 0; i < 128; i++)
- order[i] = f->readInt (1);
- f->seek (10, binio::Add);
- if (header.version == 0x10)
- { // unpacked module
- maxi = nop * 9;
- for (i = 0; i < 64 * 9; i++)
- trackord[i / 9][i % 9] = i + 1;
- t = 0;
- while (!f->ateof ())
- {
- for (j = 0; j < 64; j++)
- for (i = t; i < t + 9; i++)
- {
- buf = f->readInt (1);
- tracks[i][j].param2 = (buf & 127) % 10;
- tracks[i][j].param1 = (buf & 127) / 10;
- buf = f->readInt (1);
- tracks[i][j].inst = buf >> 4;
- tracks[i][j].command = buf & 0x0f;
- buf = f->readInt (1);
- if (buf >> 4) // fix bug in AMD save routine
- tracks[i][j].note = ((buf & 14) >> 1) * 12 + (buf >> 4);
- else
- tracks[i][j].note = 0;
- tracks[i][j].inst += (buf & 1) << 4;
- }
- t += 9;
- }
- }
- else
- { // packed module
- for (i = 0; i < nop; i++)
- for (j = 0; j < 9; j++)
- trackord[i][j] = f->readInt (2) + 1;
- numtrax = f->readInt (2);
- for (k = 0; k < numtrax; k++)
- {
- i = f->readInt (2);
- if (i > 575)
- i = 575; // fix corrupted modules
- maxi = (i + 1 > maxi ? i + 1 : maxi);
- j = 0;
- do
- {
- buf = f->readInt (1);
- if (buf & 128)
- {
- for (t = j; t < j + (buf & 127) && t < 64; t++)
- {
- tracks[i][t].command = 0;
- tracks[i][t].inst = 0;
- tracks[i][t].note = 0;
- tracks[i][t].param1 = 0;
- tracks[i][t].param2 = 0;
- }
- j += buf & 127;
- continue;
- }
- tracks[i][j].param2 = buf % 10;
- tracks[i][j].param1 = buf / 10;
- buf = f->readInt (1);
- tracks[i][j].inst = buf >> 4;
- tracks[i][j].command = buf & 0x0f;
- buf = f->readInt (1);
- if (buf >> 4) // fix bug in AMD save routine
- tracks[i][j].note = ((buf & 14) >> 1) * 12 + (buf >> 4);
- else
- tracks[i][j].note = 0;
- tracks[i][j].inst += (buf & 1) << 4;
- j++;
- } while (j < 64);
- }
- }
- fp.close (f);
-
- // convert to protracker replay data
- bpm = 50;
- restartpos = 0;
- flags = Decimal;
- for (i = 0; i < 26; i++)
- { // convert instruments
- buf = inst[i].data[0];
- buf2 = inst[i].data[1];
- inst[i].data[0] = inst[i].data[10];
- inst[i].data[1] = buf;
- buf = inst[i].data[2];
- inst[i].data[2] = inst[i].data[5];
- buf3 = inst[i].data[3];
- inst[i].data[3] = buf;
- buf = inst[i].data[4];
- inst[i].data[4] = inst[i].data[7];
- inst[i].data[5] = buf3;
- buf3 = inst[i].data[6];
- inst[i].data[6] = inst[i].data[8];
- inst[i].data[7] = buf;
- inst[i].data[8] = inst[i].data[9];
- inst[i].data[9] = buf2;
- inst[i].data[10] = buf3;
- for (j = 0; j < 23; j++) // convert names
- if (instname[i][j] == '\xff')
- instname[i][j] = '\x20';
- }
- for (i = 0; i < maxi; i++) // convert patterns
- for (j = 0; j < 64; j++)
- {
- tracks[i][j].command = convfx[tracks[i][j].command];
- // extended command
- if (tracks[i][j].command == 14)
- {
- if (tracks[i][j].param1 == 2)
- {
- tracks[i][j].command = 10;
- tracks[i][j].param1 = tracks[i][j].param2;
- tracks[i][j].param2 = 0;
- }
-
- if (tracks[i][j].param1 == 3)
- {
- tracks[i][j].command = 10;
- tracks[i][j].param1 = 0;
- }
- }
-
- // fix volume
- if (tracks[i][j].command == 17)
- {
- int vol = convvol[tracks[i][j].param1 * 10 + tracks[i][j].param2];
-
- if (vol > 63)
- vol = 63;
- tracks[i][j].param1 = vol / 10;
- tracks[i][j].param2 = vol % 10;
- }
- }
-
- rewind (0);
- return true;
-}
-
-float
-CamdLoader::getrefresh ()
-{
- if (tempo)
- return (float) (tempo);
- else
- return 18.2f;
-}
diff --git a/src/adplug/core/amd.h b/src/adplug/core/amd.h
index d1bd17d50d5a..ba93d7bf1f52 100644
--- a/src/adplug/core/amd.h
+++ b/src/adplug/core/amd.h
@@ -30,7 +30,7 @@ public:
: CmodPlayer(newopl)
{ };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
float getrefresh();
std::string gettype()
diff --git a/src/adplug/core/bam.cc b/src/adplug/core/bam.cc
new file mode 100644
index 000000000000..d542942e895e
--- /dev/null
+++ b/src/adplug/core/bam.cc
@@ -0,0 +1,244 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * bam.cpp - Bob's Adlib Music Player, by Simon Peter <dn.tlp at gmx.net>
+ *
+ * NOTES:
+ * In my player, the loop counter is stored with the label. This can be
+ * dangerous for some situations (see below), but there shouldn't be any BAM
+ * files triggering this situation.
+ *
+ * From SourceForge Bug #476088:
+ * -----------------------------
+ * Using just one loop counter for each label, my player can't
+ * handle files that loop twice to the same label (if that's at
+ * all possible with BAM). Imagine the following situation:
+ *
+ * ... [*] ---- [<- *] ---- [<- *] ...
+ * ^ ^ ^ ^ ^ ^ ^
+ * | | | | | | |
+ * +---|----+-----|-----+-----|----+--- normal song data
+ * +----------|-----------|-------- label 1
+ * +-----------+-------- loop points to label 1
+ *
+ * both loop points loop to the same label. Storing the loop
+ * count with the label would cause chaos with the counter,
+ * when the player executes the inner jump.
+ * ------------------
+ * Not to worry. my reference implementation of BAM does not
+ * support the multiple loop situation you describe, and
+ * neither do any BAM-creation programs. Then both loops point
+ * to the same label, the inner loop's counter is just allowed
+ * to clobber the outer loop's counter. No stack is neccisary.
+ */
+
+#include <string.h>
+#include "bam.h"
+
+const unsigned short
+ CbamPlayer::freq[] = { 172, 182, 193, 205, 217, 230, 243, 258, 274,
+ 290, 307, 326, 345, 365, 387, 410, 435, 460, 489, 517, 547, 580, 614, 651,
+ 1369, 1389, 1411,
+ 1434, 1459, 1484, 1513, 1541, 1571, 1604, 1638, 1675, 2393, 2413, 2435,
+ 2458, 2483, 2508,
+ 2537, 2565, 2595, 2628, 2662, 2699, 3417, 3437, 3459, 3482, 3507, 3532,
+ 3561, 3589, 3619,
+ 3652, 3686, 3723, 4441, 4461, 4483, 4506, 4531, 4556, 4585, 4613, 4643,
+ 4676, 4710, 4747,
+ 5465, 5485, 5507, 5530, 5555, 5580, 5609, 5637, 5667, 5700, 5734, 5771,
+ 6489, 6509, 6531,
+ 6554, 6579, 6604, 6633, 6661, 6691, 6724, 6758, 6795, 7513, 7533, 7555,
+ 7578, 7603, 7628,
+ 7657, 7685, 7715, 7748, 7782, 7819, 7858, 7898, 7942, 7988, 8037, 8089,
+ 8143, 8191, 8191,
+ 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191
+};
+
+CPlayer *
+CbamPlayer::factory (Copl * newopl)
+{
+ return new CbamPlayer (newopl);
+}
+
+bool
+CbamPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ char id[4];
+ unsigned int i;
+
+ size = fp.filesize (f) - 4; // filesize minus header
+ f->readString (id, 4);
+ if (strncmp (id, "CBMF", 4))
+ {
+ fp.close (f);
+ return false;
+ }
+
+ song = new unsigned char[size];
+ for (i = 0; i < size; i++)
+ song[i] = f->readInt (1);
+
+ fp.close (f);
+ rewind (0);
+ return true;
+}
+
+bool
+CbamPlayer::update ()
+{
+ unsigned char cmd, c;
+
+ if (del)
+ {
+ del--;
+ return !songend;
+ }
+
+ if (pos >= size)
+ { // EOF detection
+ pos = 0;
+ songend = true;
+ }
+
+ while (song[pos] < 128)
+ {
+ cmd = song[pos] & 240;
+ c = song[pos] & 15;
+ switch (cmd)
+ {
+ case 0: // stop song
+ pos = 0;
+ songend = true;
+ break;
+ case 16: // start note
+ if (c < 9)
+ {
+ opl->write (0xa0 + c, freq[song[++pos]] & 255);
+ opl->write (0xb0 + c, (freq[song[pos]] >> 8) + 32);
+ }
+ else
+ pos++;
+ pos++;
+ break;
+ case 32: // stop note
+ if (c < 9)
+ opl->write (0xb0 + c, 0);
+ pos++;
+ break;
+ case 48: // define instrument
+ if (c < 9)
+ {
+ opl->write (0x20 + op_table[c], song[pos + 1]);
+ opl->write (0x23 + op_table[c], song[pos + 2]);
+ opl->write (0x40 + op_table[c], song[pos + 3]);
+ opl->write (0x43 + op_table[c], song[pos + 4]);
+ opl->write (0x60 + op_table[c], song[pos + 5]);
+ opl->write (0x63 + op_table[c], song[pos + 6]);
+ opl->write (0x80 + op_table[c], song[pos + 7]);
+ opl->write (0x83 + op_table[c], song[pos + 8]);
+ opl->write (0xe0 + op_table[c], song[pos + 9]);
+ opl->write (0xe3 + op_table[c], song[pos + 10]);
+ opl->write (0xc0 + c, song[pos + 11]);
+ }
+ pos += 12;
+ break;
+ case 80: // set label
+ label[c].target = ++pos;
+ label[c].defined = true;
+ break;
+ case 96: // jump
+ if (label[c].defined)
+ switch (song[pos + 1])
+ {
+ case 254: // infinite loop
+ if (label[c].defined)
+ {
+ pos = label[c].target;
+ songend = true;
+ break;
+ }
+ // fall through...
+ case 255: // chorus
+ if (!chorus && label[c].defined)
+ {
+ chorus = true;
+ gosub = pos + 2;
+ pos = label[c].target;
+ break;
+ }
+ // fall through...
+ case 0: // end of loop
+ pos += 2;
+ break;
+ default: // finite loop
+ if (!label[c].count)
+ { // loop elapsed
+ label[c].count = 255;
+ pos += 2;
+ break;
+ }
+ if (label[c].count < 255) // loop defined
+ label[c].count--;
+ else // loop undefined
+ label[c].count = song[pos + 1] - 1;
+ pos = label[c].target;
+ break;
+ }
+ break;
+ case 112: // end of chorus
+ if (chorus)
+ {
+ pos = gosub;
+ chorus = false;
+ }
+ else
+ pos++;
+ break;
+ default: // reserved command (skip)
+ pos++;
+ break;
+ }
+ }
+ if (song[pos] >= 128)
+ { // wait
+ del = song[pos] - 127;
+ pos++;
+ }
+ return !songend;
+}
+
+void
+CbamPlayer::rewind (int subsong)
+{
+ int i;
+
+ pos = 0;
+ songend = false;
+ del = 0;
+ gosub = 0;
+ chorus = false;
+ memset (label, 0, sizeof (label));
+ label[0].defined = true;
+ for (i = 0; i < 16; i++)
+ label[i].count = 255; // 255 = undefined
+ opl->init ();
+ opl->write (1, 32);
+}
diff --git a/src/adplug/core/bam.cxx b/src/adplug/core/bam.cxx
deleted file mode 100644
index 8a50b2ccacd9..000000000000
--- a/src/adplug/core/bam.cxx
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * bam.cpp - Bob's Adlib Music Player, by Simon Peter <dn.tlp at gmx.net>
- *
- * NOTES:
- * In my player, the loop counter is stored with the label. This can be
- * dangerous for some situations (see below), but there shouldn't be any BAM
- * files triggering this situation.
- *
- * From SourceForge Bug #476088:
- * -----------------------------
- * Using just one loop counter for each label, my player can't
- * handle files that loop twice to the same label (if that's at
- * all possible with BAM). Imagine the following situation:
- *
- * ... [*] ---- [<- *] ---- [<- *] ...
- * ^ ^ ^ ^ ^ ^ ^
- * | | | | | | |
- * +---|----+-----|-----+-----|----+--- normal song data
- * +----------|-----------|-------- label 1
- * +-----------+-------- loop points to label 1
- *
- * both loop points loop to the same label. Storing the loop
- * count with the label would cause chaos with the counter,
- * when the player executes the inner jump.
- * ------------------
- * Not to worry. my reference implementation of BAM does not
- * support the multiple loop situation you describe, and
- * neither do any BAM-creation programs. Then both loops point
- * to the same label, the inner loop's counter is just allowed
- * to clobber the outer loop's counter. No stack is neccisary.
- */
-
-#include <string.h>
-#include "bam.h"
-
-const unsigned short
- CbamPlayer::freq[] = { 172, 182, 193, 205, 217, 230, 243, 258, 274,
- 290, 307, 326, 345, 365, 387, 410, 435, 460, 489, 517, 547, 580, 614, 651,
- 1369, 1389, 1411,
- 1434, 1459, 1484, 1513, 1541, 1571, 1604, 1638, 1675, 2393, 2413, 2435,
- 2458, 2483, 2508,
- 2537, 2565, 2595, 2628, 2662, 2699, 3417, 3437, 3459, 3482, 3507, 3532,
- 3561, 3589, 3619,
- 3652, 3686, 3723, 4441, 4461, 4483, 4506, 4531, 4556, 4585, 4613, 4643,
- 4676, 4710, 4747,
- 5465, 5485, 5507, 5530, 5555, 5580, 5609, 5637, 5667, 5700, 5734, 5771,
- 6489, 6509, 6531,
- 6554, 6579, 6604, 6633, 6661, 6691, 6724, 6758, 6795, 7513, 7533, 7555,
- 7578, 7603, 7628,
- 7657, 7685, 7715, 7748, 7782, 7819, 7858, 7898, 7942, 7988, 8037, 8089,
- 8143, 8191, 8191,
- 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191
-};
-
-CPlayer *
-CbamPlayer::factory (Copl * newopl)
-{
- return new CbamPlayer (newopl);
-}
-
-bool
-CbamPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- char id[4];
- unsigned int i;
-
- size = fp.filesize (f) - 4; // filesize minus header
- f->readString (id, 4);
- if (strncmp (id, "CBMF", 4))
- {
- fp.close (f);
- return false;
- }
-
- song = new unsigned char[size];
- for (i = 0; i < size; i++)
- song[i] = f->readInt (1);
-
- fp.close (f);
- rewind (0);
- return true;
-}
-
-bool
-CbamPlayer::update ()
-{
- unsigned char cmd, c;
-
- if (del)
- {
- del--;
- return !songend;
- }
-
- if (pos >= size)
- { // EOF detection
- pos = 0;
- songend = true;
- }
-
- while (song[pos] < 128)
- {
- cmd = song[pos] & 240;
- c = song[pos] & 15;
- switch (cmd)
- {
- case 0: // stop song
- pos = 0;
- songend = true;
- break;
- case 16: // start note
- if (c < 9)
- {
- opl->write (0xa0 + c, freq[song[++pos]] & 255);
- opl->write (0xb0 + c, (freq[song[pos]] >> 8) + 32);
- }
- else
- pos++;
- pos++;
- break;
- case 32: // stop note
- if (c < 9)
- opl->write (0xb0 + c, 0);
- pos++;
- break;
- case 48: // define instrument
- if (c < 9)
- {
- opl->write (0x20 + op_table[c], song[pos + 1]);
- opl->write (0x23 + op_table[c], song[pos + 2]);
- opl->write (0x40 + op_table[c], song[pos + 3]);
- opl->write (0x43 + op_table[c], song[pos + 4]);
- opl->write (0x60 + op_table[c], song[pos + 5]);
- opl->write (0x63 + op_table[c], song[pos + 6]);
- opl->write (0x80 + op_table[c], song[pos + 7]);
- opl->write (0x83 + op_table[c], song[pos + 8]);
- opl->write (0xe0 + op_table[c], song[pos + 9]);
- opl->write (0xe3 + op_table[c], song[pos + 10]);
- opl->write (0xc0 + c, song[pos + 11]);
- }
- pos += 12;
- break;
- case 80: // set label
- label[c].target = ++pos;
- label[c].defined = true;
- break;
- case 96: // jump
- if (label[c].defined)
- switch (song[pos + 1])
- {
- case 254: // infinite loop
- if (label[c].defined)
- {
- pos = label[c].target;
- songend = true;
- break;
- }
- // fall through...
- case 255: // chorus
- if (!chorus && label[c].defined)
- {
- chorus = true;
- gosub = pos + 2;
- pos = label[c].target;
- break;
- }
- // fall through...
- case 0: // end of loop
- pos += 2;
- break;
- default: // finite loop
- if (!label[c].count)
- { // loop elapsed
- label[c].count = 255;
- pos += 2;
- break;
- }
- if (label[c].count < 255) // loop defined
- label[c].count--;
- else // loop undefined
- label[c].count = song[pos + 1] - 1;
- pos = label[c].target;
- break;
- }
- break;
- case 112: // end of chorus
- if (chorus)
- {
- pos = gosub;
- chorus = false;
- }
- else
- pos++;
- break;
- default: // reserved command (skip)
- pos++;
- break;
- }
- }
- if (song[pos] >= 128)
- { // wait
- del = song[pos] - 127;
- pos++;
- }
- return !songend;
-}
-
-void
-CbamPlayer::rewind (int subsong)
-{
- int i;
-
- pos = 0;
- songend = false;
- del = 0;
- gosub = 0;
- chorus = false;
- memset (label, 0, sizeof (label));
- label[0].defined = true;
- for (i = 0; i < 16; i++)
- label[i].count = 255; // 255 = undefined
- opl->init ();
- opl->write (1, 32);
-}
diff --git a/src/adplug/core/bam.h b/src/adplug/core/bam.h
index a3b919460060..cf38707720b8 100644
--- a/src/adplug/core/bam.h
+++ b/src/adplug/core/bam.h
@@ -32,7 +32,7 @@ public:
~CbamPlayer()
{ if(song) delete [] song; };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh()
diff --git a/src/adplug/core/binio_virtual.h b/src/adplug/core/binio_virtual.h
index b51a93f632f4..5d7f9ada18b2 100644
--- a/src/adplug/core/binio_virtual.h
+++ b/src/adplug/core/binio_virtual.h
@@ -9,91 +9,81 @@
#include <binio.h>
#include <stdio.h>
-extern "C" {
#include <libaudcore/vfs.h>
-};
class vfsistream : public binistream {
private:
- VFSFile *fd; bool own;
+ VFSFile *fd = nullptr;
+ VFSFile own;
public:
- vfsistream(VFSFile *fd = 0) { this->fd = fd; this->own = false; };
+ vfsistream(VFSFile *fd = nullptr) :
+ fd(fd) {}
void open(const char *file) {
- if ((this->fd = vfs_fopen(file, "r")))
- this->own = true;
+ if ((own = VFSFile(file, "r")))
+ fd = &own;
else
err |= NotFound;
- };
-
- void open(std::string &file) { open(file.c_str()); };
+ }
- vfsistream(const char *file) { this->fd = 0; this->own = false; open(file); };
- vfsistream(std::string &file) { this->fd = 0; this->own = false; open(file); };
+ void open(std::string &file) { open(file.c_str()); }
- ~vfsistream() {
- if (this->own)
- vfs_fclose(this->fd);
- this->fd = 0; this->own = false;
- };
+ vfsistream(const char *file) { open(file); }
+ vfsistream(std::string &file) { open(file); }
- Byte getByte(void) {
- int c = vfs_getc(this->fd);
- if (c < 0)
+ Byte getByte() {
+ Byte b = (Byte)-1;
+ if (fd->fread(&b, 1, 1) != 1)
err |= Eof;
- return (Byte) c;
- };
+ return b;
+ }
void seek(long pos, Offset offs = Set) {
- int wh = (offs == Add) ? SEEK_CUR : (offs == End) ? SEEK_END : SEEK_SET;
- if (vfs_fseek(this->fd, pos, wh))
+ VFSSeekType wh = (offs == Add) ? VFS_SEEK_CUR : (offs == End) ? VFS_SEEK_END : VFS_SEEK_SET;
+ if (fd->fseek (pos, wh))
err |= Eof;
}
- long pos(void) {
- return vfs_ftell(this->fd);
+ long pos() {
+ return fd->ftell ();
}
};
class vfsostream : public binostream {
private:
- VFSFile *fd; bool own;
+ VFSFile *fd = nullptr;
+ VFSFile own;
public:
- vfsostream(VFSFile *fd = 0) { this->fd = fd; this->own = false; };
+ vfsostream(VFSFile *fd = nullptr) :
+ fd(fd) {}
void open(const char *file) {
- if ((this->fd = vfs_fopen(file, "w")))
- this->own = true;
+ if ((own = VFSFile(file, "w")))
+ fd = &own;
else
err |= Denied;
- };
-
- void open(std::string &file) { open(file.c_str()); };
+ }
- vfsostream(const char *file) { this->fd = 0; this->own = false; open(file); };
- vfsostream(std::string &file) { this->fd = 0; this->own = false; open(file); };
+ void open(std::string &file) { open(file.c_str()); }
- ~vfsostream() {
- if (this->own)
- vfs_fclose(this->fd);
- this->fd = 0; this->own = false;
- };
+ vfsostream(const char *file) { open(file); }
+ vfsostream(std::string &file) { open(file); }
void putByte(Byte b) {
- if (vfs_fwrite(&b, 1, 1, this->fd) != 1)
+ if (fd->fwrite (&b, 1, 1) != 1)
err |= Fatal;
- };
+ }
void seek(long pos, Offset offs = Set) {
- int wh = (offs == Add) ? SEEK_CUR : (offs == End) ? SEEK_END : SEEK_SET;
- if (vfs_fseek(this->fd, pos, wh))
+ VFSSeekType wh = (offs == Add) ? VFS_SEEK_CUR : (offs == End) ? VFS_SEEK_END : VFS_SEEK_SET;
+ if (fd->fseek (pos, wh))
err |= Fatal;
}
long pos(void) {
- return vfs_ftell(this->fd);
+ return fd->ftell ();
}
};
diff --git a/src/adplug/core/bmf.cc b/src/adplug/core/bmf.cc
new file mode 100644
index 000000000000..ff546c269e29
--- /dev/null
+++ b/src/adplug/core/bmf.cc
@@ -0,0 +1,636 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003, 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * [xad] BMF player, by Riven the Mage <riven at ok.ru>
+ */
+
+/*
+ - discovery -
+
+ file(s) : GAMESNET.COM
+ type : GamesNet advertising intro
+ tune : by (?)The Brain [Razor 1911]
+ player : ver.0.9b by Hammer
+
+ file(s) : 2FAST4U.COM
+ type : Ford Knox BBStro
+ tune : by The Brain [Razor 1911]
+ player : ver.1.1 by ?
+ comment : in original player at 9th channel the feedback adlib register is not C8 but C6.
+
+ file(s) : DATURA.COM
+ type : Datura BBStro
+ tune : by The Brain [Razor 1911]
+ player : ver.1.2 by ?
+ comment : inaccurate replaying, because constant outport; in original player it can be 380 or 382.
+*/
+
+#include <string.h>
+
+#include "bmf.h"
+#include "debug.h"
+
+const unsigned char
+ CxadbmfPlayer::bmf_adlib_registers[117] = {
+ 0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xA0, 0xB0, 0xC0, 0xE0,
+ 0xE3,
+ 0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xA1, 0xB1, 0xC1, 0xE1,
+ 0xE4,
+ 0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xA2, 0xB2, 0xC2, 0xE2,
+ 0xE5,
+ 0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xA3, 0xB3, 0xC3, 0xE8,
+ 0xEB,
+ 0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xA4, 0xB4, 0xC4, 0xE9,
+ 0xEC,
+ 0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xA5, 0xB5, 0xC5, 0xEA,
+ 0xED,
+ 0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xA6, 0xB6, 0xC6, 0xF0,
+ 0xF3,
+ 0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xA7, 0xB7, 0xC7, 0xF1,
+ 0xF4,
+ 0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xA8, 0xB8, 0xC8, 0xF2, 0xF5
+};
+
+const unsigned short
+ CxadbmfPlayer::bmf_notes[12] = {
+ 0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263,
+ 0x287
+};
+
+/* for 1.1 */
+const unsigned short
+ CxadbmfPlayer::bmf_notes_2[12] = {
+ 0x159, 0x16D, 0x183, 0x19A, 0x1B2, 0x1CC, 0x1E8, 0x205, 0x223, 0x244, 0x267,
+ 0x28B
+};
+
+const unsigned char
+ CxadbmfPlayer::bmf_default_instrument[13] = {
+ 0x01, 0x01, 0x3F, 0x3F, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+CPlayer *
+CxadbmfPlayer::factory (Copl * newopl)
+{
+ return new CxadbmfPlayer (newopl);
+}
+
+bool
+CxadbmfPlayer::xadplayer_load ()
+{
+ unsigned short ptr = 0;
+ int i;
+
+ if (xad.fmt != BMF)
+ return false;
+
+#ifdef DEBUG
+ AdPlug_LogWrite ("\nbmf_load():\n\n");
+#endif
+ if (!strncmp ((char *) &tune[0], "BMF1.2", 6))
+ {
+ bmf.version = BMF1_2;
+ bmf.timer = 70.0f;
+ }
+ else if (!strncmp ((char *) &tune[0], "BMF1.1", 6))
+ {
+ bmf.version = BMF1_1;
+ bmf.timer = 60.0f;
+ }
+ else
+ {
+ bmf.version = BMF0_9B;
+ bmf.timer = 18.2f;
+ }
+
+ // copy title & author
+ if (bmf.version > BMF0_9B)
+ {
+ ptr = 6;
+
+ strncpy (bmf.title, (char *) &tune[ptr], 36);
+
+ while (tune[ptr])
+ {
+ ptr++;
+ }
+ ptr++;
+
+ strncpy (bmf.author, (char *) &tune[ptr], 36);
+
+ while (tune[ptr])
+ {
+ ptr++;
+ }
+ ptr++;
+ }
+ else
+ {
+ strncpy (bmf.title, xad.title, 36);
+ strncpy (bmf.author, xad.author, 36);
+ }
+
+ // speed
+ if (bmf.version > BMF0_9B)
+ bmf.speed = tune[ptr++];
+ else
+ bmf.speed = ((tune[ptr++] << 8) / 3) >> 8; // strange, yeh ?
+
+ // load instruments
+ if (bmf.version > BMF0_9B)
+ {
+ unsigned long iflags =
+ (tune[ptr] << 24) | (tune[ptr + 1] << 16) | (tune[ptr + 2] << 8) |
+ tune[ptr + 3];
+ ptr += 4;
+
+ for (i = 0; i < 32; i++)
+ if (iflags & (1 << (31 - i)))
+ {
+ strcpy (bmf.instruments[i].name, (char *) &tune[ptr]);
+ memcpy (bmf.instruments[i].data, &tune[ptr + 11], 13);
+ ptr += 24;
+ }
+ else
+ {
+ bmf.instruments[i].name[0] = 0;
+
+ if (bmf.version == BMF1_1)
+ for (int j = 0; j < 13; j++)
+ bmf.instruments[i].data[j] = bmf_default_instrument[j];
+ else
+ for (int j = 0; j < 13; j++)
+ bmf.instruments[i].data[j] = 0;
+ }
+ }
+ else
+ {
+ ptr = 6;
+
+ for (i = 0; i < 32; i++)
+ {
+ bmf.instruments[i].name[0] = 0;
+ memcpy (bmf.instruments[tune[ptr]].data, &tune[ptr + 2], 13); // bug no.1 (no instrument-table-end detection)
+ ptr += 15;
+ }
+ }
+
+ // load streams
+ if (bmf.version > BMF0_9B)
+ {
+ unsigned long sflags =
+ (tune[ptr] << 24) | (tune[ptr + 1] << 16) | (tune[ptr + 2] << 8) |
+ tune[ptr + 3];
+ ptr += 4;
+
+ for (i = 0; i < 9; i++)
+ if (sflags & (1 << (31 - i)))
+ ptr += __bmf_convert_stream (&tune[ptr], i);
+ else
+ bmf.streams[i][0].cmd = 0xFF;
+ }
+ else
+ {
+ for (i = 0; i < tune[5]; i++)
+ ptr += __bmf_convert_stream (&tune[ptr], i);
+
+ for (i = tune[5]; i < 9; i++)
+ bmf.streams[i][0].cmd = 0xFF;
+ }
+
+ return true;
+}
+
+void
+CxadbmfPlayer::xadplayer_rewind (int subsong)
+{
+ int i, j;
+
+ for (i = 0; i < 9; i++)
+ {
+ bmf.channel[i].stream_position = 0;
+ bmf.channel[i].delay = 0;
+ bmf.channel[i].loop_position = 0;
+ bmf.channel[i].loop_counter = 0;
+ }
+
+ plr.speed = bmf.speed;
+#ifdef DEBUG
+ AdPlug_LogWrite ("speed: %x\n", plr.speed);
+#endif
+
+ bmf.active_streams = 9;
+
+ // OPL initialization
+ if (bmf.version > BMF0_9B)
+ {
+ opl_write (0x01, 0x20);
+
+ /* 1.1 */
+ if (bmf.version == BMF1_1)
+ for (i = 0; i < 9; i++)
+ for (j = 0; j < 13; j++)
+ opl_write (bmf_adlib_registers[13 * i + j],
+ bmf_default_instrument[j]);
+ /* 1.2 */
+ else if (bmf.version == BMF1_2)
+ for (i = 0x20; i < 0x100; i++)
+ opl_write (i, 0xFF); // very interesting, really!
+ }
+
+ /* ALL */
+
+ opl_write (0x08, 0x00);
+ opl_write (0xBD, 0xC0);
+}
+
+void
+CxadbmfPlayer::xadplayer_update ()
+{
+ for (int i = 0; i < 9; i++)
+ if (bmf.channel[i].stream_position != 0xFFFF)
+ {
+ if (bmf.channel[i].delay)
+ bmf.channel[i].delay--;
+ else
+ {
+#ifdef DEBUG
+ AdPlug_LogWrite ("channel %02X:\n", i);
+#endif
+ bmf_event event;
+
+ // process so-called cross-events
+ while (true)
+ {
+ memcpy (&event, &bmf.streams[i][bmf.channel[i].stream_position],
+ sizeof (bmf_event));
+#ifdef DEBUG
+ AdPlug_LogWrite ("%02X %02X %02X %02X %02X %02X\n",
+ event.note, event.delay, event.volume,
+ event.instrument, event.cmd, event.cmd_data);
+#endif
+
+ if (event.cmd == 0xFF)
+ {
+ bmf.channel[i].stream_position = 0xFFFF;
+ bmf.active_streams--;
+ break;
+ }
+ else if (event.cmd == 0xFE)
+ {
+ bmf.channel[i].loop_position = bmf.channel[i].stream_position + 1;
+ bmf.channel[i].loop_counter = event.cmd_data;
+ }
+ else if (event.cmd == 0xFD)
+ {
+ if (bmf.channel[i].loop_counter)
+ {
+ bmf.channel[i].stream_position =
+ bmf.channel[i].loop_position - 1;
+ bmf.channel[i].loop_counter--;
+ }
+ }
+ else
+ break;
+
+ bmf.channel[i].stream_position++;
+ } // while (true)
+
+ // process normal event
+ unsigned short pos = bmf.channel[i].stream_position;
+
+ if (pos != 0xFFFF)
+ {
+ bmf.channel[i].delay = bmf.streams[i][pos].delay;
+
+ // command ?
+ if (bmf.streams[i][pos].cmd)
+ {
+ unsigned char cmd = bmf.streams[i][pos].cmd;
+
+ // 0x01: Set Modulator Volume
+ if (cmd == 0x01)
+ {
+ unsigned char reg = bmf_adlib_registers[13 * i + 2];
+
+ opl_write (reg,
+ (adlib[reg] | 0x3F) - bmf.streams[i][pos].cmd_data);
+ }
+ // 0x10: Set Speed
+ else if (cmd == 0x10)
+ {
+ plr.speed = bmf.streams[i][pos].cmd_data;
+ plr.speed_counter = plr.speed;
+ }
+ } // if (bmf.streams[i][pos].cmd)
+
+ // instrument ?
+ if (bmf.streams[i][pos].instrument)
+ {
+ unsigned char ins = bmf.streams[i][pos].instrument - 1;
+
+ if (bmf.version != BMF1_1)
+ opl_write (0xB0 + i, adlib[0xB0 + i] & 0xDF);
+
+ for (int j = 0; j < 13; j++)
+ opl_write (bmf_adlib_registers[i * 13 + j],
+ bmf.instruments[ins].data[j]);
+ } // if (bmf.streams[i][pos].instrument)
+
+ // volume ?
+ if (bmf.streams[i][pos].volume)
+ {
+ unsigned char vol = bmf.streams[i][pos].volume - 1;
+ unsigned char reg = bmf_adlib_registers[13 * i + 3];
+
+ opl_write (reg, (adlib[reg] | 0x3F) - vol);
+ } // if (bmf.streams[i][pos].volume)
+
+ // note ?
+ if (bmf.streams[i][pos].note)
+ {
+ unsigned short note = bmf.streams[i][pos].note;
+ unsigned short freq = 0;
+
+ // mute channel
+ opl_write (0xB0 + i, adlib[0xB0 + i] & 0xDF);
+
+ // get frequency
+ if (bmf.version == BMF1_1)
+ {
+ if (note <= 0x60)
+ freq = bmf_notes_2[--note % 12];
+ }
+ else
+ {
+ if (note != 0x7F)
+ freq = bmf_notes[--note % 12];
+ }
+
+ // play note
+ if (freq)
+ {
+ opl_write (0xB0 + i, (freq >> 8) | ((note / 12) << 2) | 0x20);
+ opl_write (0xA0 + i, freq & 0xFF);
+ }
+ } // if (bmf.streams[i][pos].note)
+
+ bmf.channel[i].stream_position++;
+ } // if (pos != 0xFFFF)
+
+ } // if (!bmf.channel[i].delay)
+ } // if (bmf.channel[i].stream_position != 0xFFFF)
+
+ // is module loop ?
+ if (!bmf.active_streams)
+ {
+ for (int j = 0; j < 9; j++)
+ bmf.channel[j].stream_position = 0;
+
+ bmf.active_streams = 9;
+
+ plr.looping = 1;
+ }
+}
+
+float
+CxadbmfPlayer::xadplayer_getrefresh ()
+{
+ return bmf.timer;
+}
+
+std::string CxadbmfPlayer::xadplayer_gettype ()
+{
+ return std::string ("xad: BMF Adlib Tracker");
+}
+
+std::string CxadbmfPlayer::xadplayer_gettitle ()
+{
+ return std::string (bmf.title);
+}
+
+std::string CxadbmfPlayer::xadplayer_getauthor ()
+{
+ return std::string (bmf.author);
+}
+
+unsigned int
+CxadbmfPlayer::xadplayer_getinstruments ()
+{
+ return 32;
+}
+
+std::string CxadbmfPlayer::xadplayer_getinstrument (unsigned int i)
+{
+ return std::string (bmf.instruments[i].name);
+}
+
+/* -------- Internal Functions ---------------------------- */
+
+int
+CxadbmfPlayer::__bmf_convert_stream (unsigned char *stream, int channel)
+{
+#ifdef DEBUG
+ AdPlug_LogWrite
+ ("channel %02X (note,delay,volume,instrument,command,command_data):\n",
+ channel);
+ unsigned char *last = stream;
+#endif
+ unsigned char *stream_start = stream;
+
+ int pos = 0;
+
+ while (true)
+ {
+ memset (&bmf.streams[channel][pos], 0, sizeof (bmf_event));
+
+ bool is_cmd = false;
+
+ if (*stream == 0xFE)
+ {
+ // 0xFE -> 0xFF: End of Stream
+ bmf.streams[channel][pos].cmd = 0xFF;
+
+ stream++;
+
+ break;
+ }
+ else if (*stream == 0xFC)
+ {
+ // 0xFC -> 0xFE xx: Save Loop Position
+ bmf.streams[channel][pos].cmd = 0xFE;
+ bmf.streams[channel][pos].cmd_data =
+ (*(stream + 1) & ((bmf.version == BMF0_9B) ? 0x7F : 0x3F)) - 1;
+
+ stream += 2;
+ }
+ else if (*stream == 0x7D)
+ {
+ // 0x7D -> 0xFD: Loop Saved Position
+ bmf.streams[channel][pos].cmd = 0xFD;
+
+ stream++;
+ }
+ else
+ {
+ if (*stream & 0x80)
+ {
+ if (*(stream + 1) & 0x80)
+ {
+ if (*(stream + 1) & 0x40)
+ {
+ // byte0: 1aaaaaaa = NOTE
+ bmf.streams[channel][pos].note = *stream & 0x7F;
+ // byte1: 11bbbbbb = DELAY
+ bmf.streams[channel][pos].delay = *(stream + 1) & 0x3F;
+ // byte2: cccccccc = COMMAND
+
+ stream += 2;
+
+ is_cmd = true;
+ }
+ else
+ {
+ // byte0: 1aaaaaaa = NOTE
+ bmf.streams[channel][pos].note = *stream & 0x7F;
+ // byte1: 11bbbbbb = DELAY
+ bmf.streams[channel][pos].delay = *(stream + 1) & 0x3F;
+
+ stream += 2;
+ } // if (*(stream+1) & 0x40)
+ }
+ else
+ {
+ // byte0: 1aaaaaaa = NOTE
+ bmf.streams[channel][pos].note = *stream & 0x7F;
+ // byte1: 0bbbbbbb = COMMAND
+
+ stream++;
+
+ is_cmd = true;
+ } // if (*(stream+1) & 0x80)
+ }
+ else
+ {
+ // byte0: 0aaaaaaa = NOTE
+ bmf.streams[channel][pos].note = *stream & 0x7F;
+
+ stream++;
+ } // if (*stream & 0x80)
+ } // if (*stream == 0xFE)
+
+ // is command ?
+ if (is_cmd)
+ {
+
+ /* ALL */
+
+ if ((0x20 <= *stream) && (*stream <= 0x3F))
+ {
+ // 0x20 or higher; 0x3F or lower: Set Instrument
+ bmf.streams[channel][pos].instrument = *stream - 0x20 + 1;
+
+ stream++;
+ }
+ else if (0x40 <= *stream)
+ {
+ // 0x40 or higher: Set Volume
+ bmf.streams[channel][pos].volume = *stream - 0x40 + 1;
+
+ stream++;
+ }
+ else
+ {
+
+ /* 0.9b */
+
+ if (bmf.version == BMF0_9B)
+ if (*stream < 0x20)
+ {
+ // 0x1F or lower: ?
+ stream++;
+ }
+
+ /* 1.2 */
+
+ if (bmf.version == BMF1_2)
+ {
+ if (*stream == 0x01)
+ {
+ // 0x01: Set Modulator Volume -> 0x01
+ bmf.streams[channel][pos].cmd = 0x01;
+ bmf.streams[channel][pos].cmd_data = *(stream + 1);
+
+ stream += 2;
+ }
+ else if (*stream == 0x02)
+ {
+ // 0x02: ?
+ stream += 2;
+ }
+ else if (*stream == 0x03)
+ {
+ // 0x03: ?
+ stream += 2;
+ }
+ else if (*stream == 0x04)
+ {
+ // 0x04: Set Speed -> 0x10
+ bmf.streams[channel][pos].cmd = 0x10;
+ bmf.streams[channel][pos].cmd_data = *(stream + 1);
+
+ stream += 2;
+ }
+ else if (*stream == 0x05)
+ {
+ // 0x05: Set Carrier Volume (port 380)
+ bmf.streams[channel][pos].volume = *(stream + 1) + 1;
+
+ stream += 2;
+ }
+ else if (*stream == 0x06)
+ {
+ // 0x06: Set Carrier Volume (port 382)
+ bmf.streams[channel][pos].volume = *(stream + 1) + 1;
+
+ stream += 2;
+ }
+ } // if (bmf.version == BMF1_2)
+
+ } // if ((0x20 <= *stream) && (*stream <= 0x3F))
+
+ } // if (is_cmd)
+
+#ifdef DEBUG
+ AdPlug_LogWrite ("%02X %02X %02X %02X %02X %02X <---- ",
+ bmf.streams[channel][pos].note,
+ bmf.streams[channel][pos].delay,
+ bmf.streams[channel][pos].volume,
+ bmf.streams[channel][pos].instrument,
+ bmf.streams[channel][pos].cmd,
+ bmf.streams[channel][pos].cmd_data);
+ for (int zz = 0; zz < (stream - last); zz++)
+ AdPlug_LogWrite ("%02X ", last[zz]);
+ AdPlug_LogWrite ("\n");
+ last = stream;
+#endif
+ pos++;
+ } // while (true)
+
+ return (stream - stream_start);
+}
diff --git a/src/adplug/core/bmf.cxx b/src/adplug/core/bmf.cxx
deleted file mode 100644
index ff546c269e29..000000000000
--- a/src/adplug/core/bmf.cxx
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003, 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * [xad] BMF player, by Riven the Mage <riven at ok.ru>
- */
-
-/*
- - discovery -
-
- file(s) : GAMESNET.COM
- type : GamesNet advertising intro
- tune : by (?)The Brain [Razor 1911]
- player : ver.0.9b by Hammer
-
- file(s) : 2FAST4U.COM
- type : Ford Knox BBStro
- tune : by The Brain [Razor 1911]
- player : ver.1.1 by ?
- comment : in original player at 9th channel the feedback adlib register is not C8 but C6.
-
- file(s) : DATURA.COM
- type : Datura BBStro
- tune : by The Brain [Razor 1911]
- player : ver.1.2 by ?
- comment : inaccurate replaying, because constant outport; in original player it can be 380 or 382.
-*/
-
-#include <string.h>
-
-#include "bmf.h"
-#include "debug.h"
-
-const unsigned char
- CxadbmfPlayer::bmf_adlib_registers[117] = {
- 0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xA0, 0xB0, 0xC0, 0xE0,
- 0xE3,
- 0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xA1, 0xB1, 0xC1, 0xE1,
- 0xE4,
- 0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xA2, 0xB2, 0xC2, 0xE2,
- 0xE5,
- 0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xA3, 0xB3, 0xC3, 0xE8,
- 0xEB,
- 0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xA4, 0xB4, 0xC4, 0xE9,
- 0xEC,
- 0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xA5, 0xB5, 0xC5, 0xEA,
- 0xED,
- 0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xA6, 0xB6, 0xC6, 0xF0,
- 0xF3,
- 0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xA7, 0xB7, 0xC7, 0xF1,
- 0xF4,
- 0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xA8, 0xB8, 0xC8, 0xF2, 0xF5
-};
-
-const unsigned short
- CxadbmfPlayer::bmf_notes[12] = {
- 0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263,
- 0x287
-};
-
-/* for 1.1 */
-const unsigned short
- CxadbmfPlayer::bmf_notes_2[12] = {
- 0x159, 0x16D, 0x183, 0x19A, 0x1B2, 0x1CC, 0x1E8, 0x205, 0x223, 0x244, 0x267,
- 0x28B
-};
-
-const unsigned char
- CxadbmfPlayer::bmf_default_instrument[13] = {
- 0x01, 0x01, 0x3F, 0x3F, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-CPlayer *
-CxadbmfPlayer::factory (Copl * newopl)
-{
- return new CxadbmfPlayer (newopl);
-}
-
-bool
-CxadbmfPlayer::xadplayer_load ()
-{
- unsigned short ptr = 0;
- int i;
-
- if (xad.fmt != BMF)
- return false;
-
-#ifdef DEBUG
- AdPlug_LogWrite ("\nbmf_load():\n\n");
-#endif
- if (!strncmp ((char *) &tune[0], "BMF1.2", 6))
- {
- bmf.version = BMF1_2;
- bmf.timer = 70.0f;
- }
- else if (!strncmp ((char *) &tune[0], "BMF1.1", 6))
- {
- bmf.version = BMF1_1;
- bmf.timer = 60.0f;
- }
- else
- {
- bmf.version = BMF0_9B;
- bmf.timer = 18.2f;
- }
-
- // copy title & author
- if (bmf.version > BMF0_9B)
- {
- ptr = 6;
-
- strncpy (bmf.title, (char *) &tune[ptr], 36);
-
- while (tune[ptr])
- {
- ptr++;
- }
- ptr++;
-
- strncpy (bmf.author, (char *) &tune[ptr], 36);
-
- while (tune[ptr])
- {
- ptr++;
- }
- ptr++;
- }
- else
- {
- strncpy (bmf.title, xad.title, 36);
- strncpy (bmf.author, xad.author, 36);
- }
-
- // speed
- if (bmf.version > BMF0_9B)
- bmf.speed = tune[ptr++];
- else
- bmf.speed = ((tune[ptr++] << 8) / 3) >> 8; // strange, yeh ?
-
- // load instruments
- if (bmf.version > BMF0_9B)
- {
- unsigned long iflags =
- (tune[ptr] << 24) | (tune[ptr + 1] << 16) | (tune[ptr + 2] << 8) |
- tune[ptr + 3];
- ptr += 4;
-
- for (i = 0; i < 32; i++)
- if (iflags & (1 << (31 - i)))
- {
- strcpy (bmf.instruments[i].name, (char *) &tune[ptr]);
- memcpy (bmf.instruments[i].data, &tune[ptr + 11], 13);
- ptr += 24;
- }
- else
- {
- bmf.instruments[i].name[0] = 0;
-
- if (bmf.version == BMF1_1)
- for (int j = 0; j < 13; j++)
- bmf.instruments[i].data[j] = bmf_default_instrument[j];
- else
- for (int j = 0; j < 13; j++)
- bmf.instruments[i].data[j] = 0;
- }
- }
- else
- {
- ptr = 6;
-
- for (i = 0; i < 32; i++)
- {
- bmf.instruments[i].name[0] = 0;
- memcpy (bmf.instruments[tune[ptr]].data, &tune[ptr + 2], 13); // bug no.1 (no instrument-table-end detection)
- ptr += 15;
- }
- }
-
- // load streams
- if (bmf.version > BMF0_9B)
- {
- unsigned long sflags =
- (tune[ptr] << 24) | (tune[ptr + 1] << 16) | (tune[ptr + 2] << 8) |
- tune[ptr + 3];
- ptr += 4;
-
- for (i = 0; i < 9; i++)
- if (sflags & (1 << (31 - i)))
- ptr += __bmf_convert_stream (&tune[ptr], i);
- else
- bmf.streams[i][0].cmd = 0xFF;
- }
- else
- {
- for (i = 0; i < tune[5]; i++)
- ptr += __bmf_convert_stream (&tune[ptr], i);
-
- for (i = tune[5]; i < 9; i++)
- bmf.streams[i][0].cmd = 0xFF;
- }
-
- return true;
-}
-
-void
-CxadbmfPlayer::xadplayer_rewind (int subsong)
-{
- int i, j;
-
- for (i = 0; i < 9; i++)
- {
- bmf.channel[i].stream_position = 0;
- bmf.channel[i].delay = 0;
- bmf.channel[i].loop_position = 0;
- bmf.channel[i].loop_counter = 0;
- }
-
- plr.speed = bmf.speed;
-#ifdef DEBUG
- AdPlug_LogWrite ("speed: %x\n", plr.speed);
-#endif
-
- bmf.active_streams = 9;
-
- // OPL initialization
- if (bmf.version > BMF0_9B)
- {
- opl_write (0x01, 0x20);
-
- /* 1.1 */
- if (bmf.version == BMF1_1)
- for (i = 0; i < 9; i++)
- for (j = 0; j < 13; j++)
- opl_write (bmf_adlib_registers[13 * i + j],
- bmf_default_instrument[j]);
- /* 1.2 */
- else if (bmf.version == BMF1_2)
- for (i = 0x20; i < 0x100; i++)
- opl_write (i, 0xFF); // very interesting, really!
- }
-
- /* ALL */
-
- opl_write (0x08, 0x00);
- opl_write (0xBD, 0xC0);
-}
-
-void
-CxadbmfPlayer::xadplayer_update ()
-{
- for (int i = 0; i < 9; i++)
- if (bmf.channel[i].stream_position != 0xFFFF)
- {
- if (bmf.channel[i].delay)
- bmf.channel[i].delay--;
- else
- {
-#ifdef DEBUG
- AdPlug_LogWrite ("channel %02X:\n", i);
-#endif
- bmf_event event;
-
- // process so-called cross-events
- while (true)
- {
- memcpy (&event, &bmf.streams[i][bmf.channel[i].stream_position],
- sizeof (bmf_event));
-#ifdef DEBUG
- AdPlug_LogWrite ("%02X %02X %02X %02X %02X %02X\n",
- event.note, event.delay, event.volume,
- event.instrument, event.cmd, event.cmd_data);
-#endif
-
- if (event.cmd == 0xFF)
- {
- bmf.channel[i].stream_position = 0xFFFF;
- bmf.active_streams--;
- break;
- }
- else if (event.cmd == 0xFE)
- {
- bmf.channel[i].loop_position = bmf.channel[i].stream_position + 1;
- bmf.channel[i].loop_counter = event.cmd_data;
- }
- else if (event.cmd == 0xFD)
- {
- if (bmf.channel[i].loop_counter)
- {
- bmf.channel[i].stream_position =
- bmf.channel[i].loop_position - 1;
- bmf.channel[i].loop_counter--;
- }
- }
- else
- break;
-
- bmf.channel[i].stream_position++;
- } // while (true)
-
- // process normal event
- unsigned short pos = bmf.channel[i].stream_position;
-
- if (pos != 0xFFFF)
- {
- bmf.channel[i].delay = bmf.streams[i][pos].delay;
-
- // command ?
- if (bmf.streams[i][pos].cmd)
- {
- unsigned char cmd = bmf.streams[i][pos].cmd;
-
- // 0x01: Set Modulator Volume
- if (cmd == 0x01)
- {
- unsigned char reg = bmf_adlib_registers[13 * i + 2];
-
- opl_write (reg,
- (adlib[reg] | 0x3F) - bmf.streams[i][pos].cmd_data);
- }
- // 0x10: Set Speed
- else if (cmd == 0x10)
- {
- plr.speed = bmf.streams[i][pos].cmd_data;
- plr.speed_counter = plr.speed;
- }
- } // if (bmf.streams[i][pos].cmd)
-
- // instrument ?
- if (bmf.streams[i][pos].instrument)
- {
- unsigned char ins = bmf.streams[i][pos].instrument - 1;
-
- if (bmf.version != BMF1_1)
- opl_write (0xB0 + i, adlib[0xB0 + i] & 0xDF);
-
- for (int j = 0; j < 13; j++)
- opl_write (bmf_adlib_registers[i * 13 + j],
- bmf.instruments[ins].data[j]);
- } // if (bmf.streams[i][pos].instrument)
-
- // volume ?
- if (bmf.streams[i][pos].volume)
- {
- unsigned char vol = bmf.streams[i][pos].volume - 1;
- unsigned char reg = bmf_adlib_registers[13 * i + 3];
-
- opl_write (reg, (adlib[reg] | 0x3F) - vol);
- } // if (bmf.streams[i][pos].volume)
-
- // note ?
- if (bmf.streams[i][pos].note)
- {
- unsigned short note = bmf.streams[i][pos].note;
- unsigned short freq = 0;
-
- // mute channel
- opl_write (0xB0 + i, adlib[0xB0 + i] & 0xDF);
-
- // get frequency
- if (bmf.version == BMF1_1)
- {
- if (note <= 0x60)
- freq = bmf_notes_2[--note % 12];
- }
- else
- {
- if (note != 0x7F)
- freq = bmf_notes[--note % 12];
- }
-
- // play note
- if (freq)
- {
- opl_write (0xB0 + i, (freq >> 8) | ((note / 12) << 2) | 0x20);
- opl_write (0xA0 + i, freq & 0xFF);
- }
- } // if (bmf.streams[i][pos].note)
-
- bmf.channel[i].stream_position++;
- } // if (pos != 0xFFFF)
-
- } // if (!bmf.channel[i].delay)
- } // if (bmf.channel[i].stream_position != 0xFFFF)
-
- // is module loop ?
- if (!bmf.active_streams)
- {
- for (int j = 0; j < 9; j++)
- bmf.channel[j].stream_position = 0;
-
- bmf.active_streams = 9;
-
- plr.looping = 1;
- }
-}
-
-float
-CxadbmfPlayer::xadplayer_getrefresh ()
-{
- return bmf.timer;
-}
-
-std::string CxadbmfPlayer::xadplayer_gettype ()
-{
- return std::string ("xad: BMF Adlib Tracker");
-}
-
-std::string CxadbmfPlayer::xadplayer_gettitle ()
-{
- return std::string (bmf.title);
-}
-
-std::string CxadbmfPlayer::xadplayer_getauthor ()
-{
- return std::string (bmf.author);
-}
-
-unsigned int
-CxadbmfPlayer::xadplayer_getinstruments ()
-{
- return 32;
-}
-
-std::string CxadbmfPlayer::xadplayer_getinstrument (unsigned int i)
-{
- return std::string (bmf.instruments[i].name);
-}
-
-/* -------- Internal Functions ---------------------------- */
-
-int
-CxadbmfPlayer::__bmf_convert_stream (unsigned char *stream, int channel)
-{
-#ifdef DEBUG
- AdPlug_LogWrite
- ("channel %02X (note,delay,volume,instrument,command,command_data):\n",
- channel);
- unsigned char *last = stream;
-#endif
- unsigned char *stream_start = stream;
-
- int pos = 0;
-
- while (true)
- {
- memset (&bmf.streams[channel][pos], 0, sizeof (bmf_event));
-
- bool is_cmd = false;
-
- if (*stream == 0xFE)
- {
- // 0xFE -> 0xFF: End of Stream
- bmf.streams[channel][pos].cmd = 0xFF;
-
- stream++;
-
- break;
- }
- else if (*stream == 0xFC)
- {
- // 0xFC -> 0xFE xx: Save Loop Position
- bmf.streams[channel][pos].cmd = 0xFE;
- bmf.streams[channel][pos].cmd_data =
- (*(stream + 1) & ((bmf.version == BMF0_9B) ? 0x7F : 0x3F)) - 1;
-
- stream += 2;
- }
- else if (*stream == 0x7D)
- {
- // 0x7D -> 0xFD: Loop Saved Position
- bmf.streams[channel][pos].cmd = 0xFD;
-
- stream++;
- }
- else
- {
- if (*stream & 0x80)
- {
- if (*(stream + 1) & 0x80)
- {
- if (*(stream + 1) & 0x40)
- {
- // byte0: 1aaaaaaa = NOTE
- bmf.streams[channel][pos].note = *stream & 0x7F;
- // byte1: 11bbbbbb = DELAY
- bmf.streams[channel][pos].delay = *(stream + 1) & 0x3F;
- // byte2: cccccccc = COMMAND
-
- stream += 2;
-
- is_cmd = true;
- }
- else
- {
- // byte0: 1aaaaaaa = NOTE
- bmf.streams[channel][pos].note = *stream & 0x7F;
- // byte1: 11bbbbbb = DELAY
- bmf.streams[channel][pos].delay = *(stream + 1) & 0x3F;
-
- stream += 2;
- } // if (*(stream+1) & 0x40)
- }
- else
- {
- // byte0: 1aaaaaaa = NOTE
- bmf.streams[channel][pos].note = *stream & 0x7F;
- // byte1: 0bbbbbbb = COMMAND
-
- stream++;
-
- is_cmd = true;
- } // if (*(stream+1) & 0x80)
- }
- else
- {
- // byte0: 0aaaaaaa = NOTE
- bmf.streams[channel][pos].note = *stream & 0x7F;
-
- stream++;
- } // if (*stream & 0x80)
- } // if (*stream == 0xFE)
-
- // is command ?
- if (is_cmd)
- {
-
- /* ALL */
-
- if ((0x20 <= *stream) && (*stream <= 0x3F))
- {
- // 0x20 or higher; 0x3F or lower: Set Instrument
- bmf.streams[channel][pos].instrument = *stream - 0x20 + 1;
-
- stream++;
- }
- else if (0x40 <= *stream)
- {
- // 0x40 or higher: Set Volume
- bmf.streams[channel][pos].volume = *stream - 0x40 + 1;
-
- stream++;
- }
- else
- {
-
- /* 0.9b */
-
- if (bmf.version == BMF0_9B)
- if (*stream < 0x20)
- {
- // 0x1F or lower: ?
- stream++;
- }
-
- /* 1.2 */
-
- if (bmf.version == BMF1_2)
- {
- if (*stream == 0x01)
- {
- // 0x01: Set Modulator Volume -> 0x01
- bmf.streams[channel][pos].cmd = 0x01;
- bmf.streams[channel][pos].cmd_data = *(stream + 1);
-
- stream += 2;
- }
- else if (*stream == 0x02)
- {
- // 0x02: ?
- stream += 2;
- }
- else if (*stream == 0x03)
- {
- // 0x03: ?
- stream += 2;
- }
- else if (*stream == 0x04)
- {
- // 0x04: Set Speed -> 0x10
- bmf.streams[channel][pos].cmd = 0x10;
- bmf.streams[channel][pos].cmd_data = *(stream + 1);
-
- stream += 2;
- }
- else if (*stream == 0x05)
- {
- // 0x05: Set Carrier Volume (port 380)
- bmf.streams[channel][pos].volume = *(stream + 1) + 1;
-
- stream += 2;
- }
- else if (*stream == 0x06)
- {
- // 0x06: Set Carrier Volume (port 382)
- bmf.streams[channel][pos].volume = *(stream + 1) + 1;
-
- stream += 2;
- }
- } // if (bmf.version == BMF1_2)
-
- } // if ((0x20 <= *stream) && (*stream <= 0x3F))
-
- } // if (is_cmd)
-
-#ifdef DEBUG
- AdPlug_LogWrite ("%02X %02X %02X %02X %02X %02X <---- ",
- bmf.streams[channel][pos].note,
- bmf.streams[channel][pos].delay,
- bmf.streams[channel][pos].volume,
- bmf.streams[channel][pos].instrument,
- bmf.streams[channel][pos].cmd,
- bmf.streams[channel][pos].cmd_data);
- for (int zz = 0; zz < (stream - last); zz++)
- AdPlug_LogWrite ("%02X ", last[zz]);
- AdPlug_LogWrite ("\n");
- last = stream;
-#endif
- pos++;
- } // while (true)
-
- return (stream - stream_start);
-}
diff --git a/src/adplug/core/cff.cc b/src/adplug/core/cff.cc
new file mode 100644
index 000000000000..7bffae5d195f
--- /dev/null
+++ b/src/adplug/core/cff.cc
@@ -0,0 +1,531 @@
+/*
+ AdPlug - Replayer for many OPL2/OPL3 audio file formats.
+ Copyright (C) 1999 - 2006 Simon Peter <dn.tlp at gmx.net>, et al.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ cff.cpp - BoomTracker loader by Riven the Mage <riven at ok.ru>
+*/
+/*
+ NOTE: Conversion of slides is not 100% accurate. Original volume slides
+ have effect on carrier volume only. Also, original arpeggio, frequency & volume
+ slides use previous effect data instead of current.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cff.h"
+
+/* -------- Public Methods -------------------------------- */
+
+CPlayer *
+CcffLoader::factory (Copl * newopl)
+{
+ return new CcffLoader (newopl);
+}
+
+bool
+CcffLoader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ const unsigned char conv_inst[11] = { 2, 1, 10, 9, 4, 3, 6, 5, 0, 8, 7 };
+ const unsigned short conv_note[12] =
+ { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263,
+0x287, 0x2AE };
+
+ int i, j, k, t = 0;
+
+ // '<CUD-FM-File>' - signed ?
+ f->readString (header.id, 16);
+ header.version = f->readInt (1);
+ header.size = f->readInt (2);
+ header.packed = f->readInt (1);
+ f->readString ((char *) header.reserved, 12);
+ if (memcmp (header.id, "<CUD-FM-File>" "\x1A\xDE\xE0", 16))
+ {
+ fp.close (f);
+ return false;
+ }
+
+ unsigned char *module = new unsigned char[0x10000];
+
+ // packed ?
+ if (header.packed)
+ {
+ cff_unpacker *unpacker = new cff_unpacker;
+
+ unsigned char *packed_module = new unsigned char[header.size + 4];
+
+ memset (packed_module, 0, header.size + 4);
+
+ f->readString ((char *) packed_module, header.size);
+ fp.close (f);
+
+ if (!unpacker->unpack (packed_module, module))
+ {
+ delete unpacker;
+ delete[] packed_module;
+ delete[] module;
+ return false;
+ }
+
+ delete unpacker;
+ delete[] packed_module;
+
+ if (memcmp (&module[0x5E1], "CUD-FM-File - SEND A POSTCARD -", 31))
+ {
+ delete[] module;
+ return false;
+ }
+ }
+ else
+ {
+ f->readString ((char *) module, header.size);
+ fp.close (f);
+ }
+
+ // init CmodPlayer
+ realloc_instruments (47);
+ realloc_order (64);
+ realloc_patterns (36, 64, 9);
+ init_notetable (conv_note);
+ init_trackord ();
+
+ // load instruments
+ for (i = 0; i < 47; i++)
+ {
+ memcpy (&instruments[i], &module[i * 32], sizeof (cff_instrument));
+
+ for (j = 0; j < 11; j++)
+ inst[i].data[conv_inst[j]] = instruments[i].data[j];
+
+ instruments[i].name[20] = 0;
+ }
+
+ // number of patterns
+ nop = module[0x5E0];
+
+ // load title & author
+ memcpy (song_title, &module[0x614], 20);
+ memcpy (song_author, &module[0x600], 20);
+
+ // load order
+ memcpy (order, &module[0x628], 64);
+
+ // load tracks
+ for (i = 0; i < nop; i++)
+ {
+ unsigned char old_event_byte2[9];
+
+ memset (old_event_byte2, 0, 9);
+
+ for (j = 0; j < 9; j++)
+ {
+ for (k = 0; k < 64; k++)
+ {
+ cff_event *event =
+ (cff_event *) & module[0x669 + ((i * 64 + k) * 9 + j) * 3];
+
+ // convert note
+ if (event->byte0 == 0x6D)
+ tracks[t][k].note = 127;
+ else if (event->byte0)
+ tracks[t][k].note = event->byte0;
+
+ if (event->byte2)
+ old_event_byte2[j] = event->byte2;
+
+ // convert effect
+ switch (event->byte1)
+ {
+ case 'I': // set instrument
+ tracks[t][k].inst = event->byte2 + 1;
+ tracks[t][k].param1 = tracks[t][k].param2 = 0;
+ break;
+
+ case 'H': // set tempo
+ tracks[t][k].command = 7;
+ if (event->byte2 < 16)
+ {
+ tracks[t][k].param1 = 0x07;
+ tracks[t][k].param2 = 0x0D;
+ }
+ break;
+
+ case 'A': // set speed
+ tracks[t][k].command = 19;
+ tracks[t][k].param1 = event->byte2 >> 4;
+ tracks[t][k].param2 = event->byte2 & 15;
+ break;
+
+ case 'L': // pattern break
+ tracks[t][k].command = 13;
+ tracks[t][k].param1 = event->byte2 >> 4;
+ tracks[t][k].param2 = event->byte2 & 15;
+ break;
+
+ case 'K': // order jump
+ tracks[t][k].command = 11;
+ tracks[t][k].param1 = event->byte2 >> 4;
+ tracks[t][k].param2 = event->byte2 & 15;
+ break;
+
+ case 'M': // set vibrato/tremolo
+ tracks[t][k].command = 27;
+ tracks[t][k].param1 = event->byte2 >> 4;
+ tracks[t][k].param2 = event->byte2 & 15;
+ break;
+
+ case 'C': // set modulator volume
+ tracks[t][k].command = 21;
+ tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
+ tracks[t][k].param2 = (0x3F - event->byte2) & 15;
+ break;
+
+ case 'G': // set carrier volume
+ tracks[t][k].command = 22;
+ tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
+ tracks[t][k].param2 = (0x3F - event->byte2) & 15;
+ break;
+
+ case 'B': // set carrier waveform
+ tracks[t][k].command = 25;
+ tracks[t][k].param1 = event->byte2;
+ tracks[t][k].param2 = 0x0F;
+ break;
+
+ case 'E': // fine frequency slide down
+ tracks[t][k].command = 24;
+ tracks[t][k].param1 = old_event_byte2[j] >> 4;
+ tracks[t][k].param2 = old_event_byte2[j] & 15;
+ break;
+
+ case 'F': // fine frequency slide up
+ tracks[t][k].command = 23;
+ tracks[t][k].param1 = old_event_byte2[j] >> 4;
+ tracks[t][k].param2 = old_event_byte2[j] & 15;
+ break;
+
+ case 'D': // fine volume slide
+ tracks[t][k].command = 14;
+ if (old_event_byte2[j] & 15)
+ {
+ // slide down
+ tracks[t][k].param1 = 5;
+ tracks[t][k].param2 = old_event_byte2[j] & 15;
+ }
+ else
+ {
+ // slide up
+ tracks[t][k].param1 = 4;
+ tracks[t][k].param2 = old_event_byte2[j] >> 4;
+ }
+ break;
+
+ case 'J': // arpeggio
+ tracks[t][k].param1 = old_event_byte2[j] >> 4;
+ tracks[t][k].param2 = old_event_byte2[j] & 15;
+ break;
+ }
+ }
+
+ t++;
+ }
+ }
+
+ delete[]module;
+
+ // order loop
+ restartpos = 0;
+
+ // order length
+ for (i = 0; i < 64; i++)
+ {
+ if (order[i] >= 0x80)
+ {
+ length = i;
+ break;
+ }
+ }
+
+ // default tempo
+ bpm = 0x7D;
+
+ rewind (0);
+
+ return true;
+}
+
+void
+CcffLoader::rewind (int subsong)
+{
+ CmodPlayer::rewind (subsong);
+
+ // default instruments
+ for (int i = 0; i < 9; i++)
+ {
+ channel[i].inst = i;
+
+ channel[i].vol1 = 63 - (inst[i].data[10] & 63);
+ channel[i].vol2 = 63 - (inst[i].data[9] & 63);
+ }
+}
+
+std::string CcffLoader::gettype ()
+{
+ if (header.packed)
+ return std::string ("BoomTracker 4, packed");
+ else
+ return std::string ("BoomTracker 4");
+}
+
+std::string CcffLoader::gettitle ()
+{
+ return std::string (song_title, 20);
+}
+
+std::string CcffLoader::getauthor ()
+{
+ return std::string (song_author, 20);
+}
+
+std::string CcffLoader::getinstrument (unsigned int n)
+{
+ return std::string (instruments[n].name);
+}
+
+unsigned int
+CcffLoader::getinstruments ()
+{
+ return 47;
+}
+
+/* -------- Private Methods ------------------------------- */
+
+/*
+ Lempel-Ziv-Tyr ;-)
+*/
+long
+CcffLoader::cff_unpacker::unpack (unsigned char *ibuf, unsigned char *obuf)
+{
+ if (memcmp (ibuf, "YsComp" "\x07" "CUD1997" "\x1A\x04", 16))
+ return 0;
+
+ input = ibuf + 16;
+ output = obuf;
+
+ output_length = 0;
+
+ heap = (unsigned char *) malloc (0x10000);
+ dictionary = (unsigned char **) malloc (sizeof (unsigned char *) * 0x8000);
+
+ memset (heap, 0, 0x10000);
+ memset (dictionary, 0, 0x8000);
+
+ cleanup ();
+ if (!startup ())
+ goto out;
+
+ // LZW
+ while (1)
+ {
+ new_code = get_code ();
+
+ // 0x00: end of data
+ if (new_code == 0)
+ break;
+
+ // 0x01: end of block
+ if (new_code == 1)
+ {
+ cleanup ();
+ if (!startup ())
+ goto out;
+
+ continue;
+ }
+
+ // 0x02: expand code length
+ if (new_code == 2)
+ {
+ code_length++;
+
+ continue;
+ }
+
+ // 0x03: RLE
+ if (new_code == 3)
+ {
+ unsigned char
+ old_code_length = code_length;
+
+ code_length = 2;
+
+ unsigned char
+ repeat_length = get_code () + 1;
+
+ code_length = 4 << get_code ();
+
+ unsigned long
+ repeat_counter = get_code ();
+
+ if (output_length + repeat_counter * repeat_length > 0x10000)
+ {
+ output_length = 0;
+ goto out;
+ }
+
+ for (unsigned int i = 0; i < repeat_counter * repeat_length; i++)
+ {
+ output[output_length] = output[output_length - repeat_length];
+ output_length++;
+ }
+
+ code_length = old_code_length;
+
+ if (!startup ())
+ goto out;
+
+ continue;
+ }
+
+ if (new_code >= (0x104 + dictionary_length))
+ {
+ // dictionary <- old.code.string + old.code.char
+ the_string[++the_string[0]] = the_string[1];
+ }
+ else
+ {
+ // dictionary <- old.code.string + new.code.char
+ unsigned char
+ temp_string[256];
+
+ translate_code (new_code, temp_string);
+
+ the_string[++the_string[0]] = temp_string[1];
+ }
+
+ expand_dictionary (the_string);
+
+ // output <- new.code.string
+ translate_code (new_code, the_string);
+
+ if (output_length + the_string[0] > 0x10000)
+ {
+ output_length = 0;
+ goto out;
+ }
+
+ for (int i = 0; i < the_string[0]; i++)
+ output[output_length++] = the_string[i + 1];
+
+ old_code = new_code;
+ }
+
+out:
+ free (heap);
+ free (dictionary);
+ return output_length;
+}
+
+unsigned long
+CcffLoader::cff_unpacker::get_code ()
+{
+ unsigned long
+ code;
+
+ while (bits_left < code_length)
+ {
+ bits_buffer |= ((*input++) << bits_left);
+ bits_left += 8;
+ }
+
+ code = bits_buffer & ((1 << code_length) - 1);
+
+ bits_buffer >>= code_length;
+ bits_left -= code_length;
+
+ return code;
+}
+
+void
+CcffLoader::cff_unpacker::translate_code (unsigned long code,
+ unsigned char *string)
+{
+ unsigned char
+ translated_string[256];
+
+ if (code >= 0x104)
+ {
+ memcpy (translated_string, dictionary[code - 0x104],
+ (*(dictionary[code - 0x104])) + 1);
+ }
+ else
+ {
+ translated_string[0] = 1;
+ translated_string[1] = (code - 4) & 0xFF;
+ }
+
+ memcpy (string, translated_string, 256);
+}
+
+void
+CcffLoader::cff_unpacker::cleanup ()
+{
+ code_length = 9;
+
+ bits_buffer = 0;
+ bits_left = 0;
+
+ heap_length = 0;
+ dictionary_length = 0;
+}
+
+int
+CcffLoader::cff_unpacker::startup ()
+{
+ old_code = get_code ();
+
+ translate_code (old_code, the_string);
+
+ if (output_length + the_string[0] > 0x10000)
+ {
+ output_length = 0;
+ return 0;
+ }
+
+ for (int i = 0; i < the_string[0]; i++)
+ output[output_length++] = the_string[i + 1];
+
+ return 1;
+}
+
+void
+CcffLoader::cff_unpacker::expand_dictionary (unsigned char *string)
+{
+ if (string[0] >= 0xF0)
+ return;
+
+ memcpy (&heap[heap_length], string, string[0] + 1);
+
+ dictionary[dictionary_length] = &heap[heap_length];
+
+ dictionary_length++;
+
+ heap_length += (string[0] + 1);
+}
diff --git a/src/adplug/core/cff.cxx b/src/adplug/core/cff.cxx
deleted file mode 100644
index 7403cc492ee1..000000000000
--- a/src/adplug/core/cff.cxx
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- AdPlug - Replayer for many OPL2/OPL3 audio file formats.
- Copyright (C) 1999 - 2006 Simon Peter <dn.tlp at gmx.net>, et al.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- cff.cpp - BoomTracker loader by Riven the Mage <riven at ok.ru>
-*/
-/*
- NOTE: Conversion of slides is not 100% accurate. Original volume slides
- have effect on carrier volume only. Also, original arpeggio, frequency & volume
- slides use previous effect data instead of current.
-*/
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "cff.h"
-
-/* -------- Public Methods -------------------------------- */
-
-CPlayer *
-CcffLoader::factory (Copl * newopl)
-{
- return new CcffLoader (newopl);
-}
-
-bool
-CcffLoader::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- const unsigned char conv_inst[11] = { 2, 1, 10, 9, 4, 3, 6, 5, 0, 8, 7 };
- const unsigned short conv_note[12] =
- { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263,
-0x287, 0x2AE };
-
- int i, j, k, t = 0;
-
- // '<CUD-FM-File>' - signed ?
- f->readString (header.id, 16);
- header.version = f->readInt (1);
- header.size = f->readInt (2);
- header.packed = f->readInt (1);
- f->readString ((char *) header.reserved, 12);
- if (memcmp (header.id, "<CUD-FM-File>" "\x1A\xDE\xE0", 16))
- {
- fp.close (f);
- return false;
- }
-
- unsigned char *module = new unsigned char[0x10000];
-
- // packed ?
- if (header.packed)
- {
- cff_unpacker *unpacker = new cff_unpacker;
-
- unsigned char *packed_module = new unsigned char[header.size + 4];
-
- memset (packed_module, 0, header.size + 4);
-
- f->readString ((char *) packed_module, header.size);
- fp.close (f);
-
- if (!unpacker->unpack (packed_module, module))
- {
- delete unpacker;
- delete[] packed_module;
- delete[] module;
- return false;
- }
-
- delete unpacker;
- delete[] packed_module;
-
- if (memcmp (&module[0x5E1], "CUD-FM-File - SEND A POSTCARD -", 31))
- {
- delete[] module;
- return false;
- }
- }
- else
- {
- f->readString ((char *) module, header.size);
- fp.close (f);
- }
-
- // init CmodPlayer
- realloc_instruments (47);
- realloc_order (64);
- realloc_patterns (36, 64, 9);
- init_notetable (conv_note);
- init_trackord ();
-
- // load instruments
- for (i = 0; i < 47; i++)
- {
- memcpy (&instruments[i], &module[i * 32], sizeof (cff_instrument));
-
- for (j = 0; j < 11; j++)
- inst[i].data[conv_inst[j]] = instruments[i].data[j];
-
- instruments[i].name[20] = 0;
- }
-
- // number of patterns
- nop = module[0x5E0];
-
- // load title & author
- memcpy (song_title, &module[0x614], 20);
- memcpy (song_author, &module[0x600], 20);
-
- // load order
- memcpy (order, &module[0x628], 64);
-
- // load tracks
- for (i = 0; i < nop; i++)
- {
- unsigned char old_event_byte2[9];
-
- memset (old_event_byte2, 0, 9);
-
- for (j = 0; j < 9; j++)
- {
- for (k = 0; k < 64; k++)
- {
- cff_event *event =
- (cff_event *) & module[0x669 + ((i * 64 + k) * 9 + j) * 3];
-
- // convert note
- if (event->byte0 == 0x6D)
- tracks[t][k].note = 127;
- else if (event->byte0)
- tracks[t][k].note = event->byte0;
-
- if (event->byte2)
- old_event_byte2[j] = event->byte2;
-
- // convert effect
- switch (event->byte1)
- {
- case 'I': // set instrument
- tracks[t][k].inst = event->byte2 + 1;
- tracks[t][k].param1 = tracks[t][k].param2 = 0;
- break;
-
- case 'H': // set tempo
- tracks[t][k].command = 7;
- if (event->byte2 < 16)
- {
- tracks[t][k].param1 = 0x07;
- tracks[t][k].param2 = 0x0D;
- }
- break;
-
- case 'A': // set speed
- tracks[t][k].command = 19;
- tracks[t][k].param1 = event->byte2 >> 4;
- tracks[t][k].param2 = event->byte2 & 15;
- break;
-
- case 'L': // pattern break
- tracks[t][k].command = 13;
- tracks[t][k].param1 = event->byte2 >> 4;
- tracks[t][k].param2 = event->byte2 & 15;
- break;
-
- case 'K': // order jump
- tracks[t][k].command = 11;
- tracks[t][k].param1 = event->byte2 >> 4;
- tracks[t][k].param2 = event->byte2 & 15;
- break;
-
- case 'M': // set vibrato/tremolo
- tracks[t][k].command = 27;
- tracks[t][k].param1 = event->byte2 >> 4;
- tracks[t][k].param2 = event->byte2 & 15;
- break;
-
- case 'C': // set modulator volume
- tracks[t][k].command = 21;
- tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
- tracks[t][k].param2 = (0x3F - event->byte2) & 15;
- break;
-
- case 'G': // set carrier volume
- tracks[t][k].command = 22;
- tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
- tracks[t][k].param2 = (0x3F - event->byte2) & 15;
- break;
-
- case 'B': // set carrier waveform
- tracks[t][k].command = 25;
- tracks[t][k].param1 = event->byte2;
- tracks[t][k].param2 = 0x0F;
- break;
-
- case 'E': // fine frequency slide down
- tracks[t][k].command = 24;
- tracks[t][k].param1 = old_event_byte2[j] >> 4;
- tracks[t][k].param2 = old_event_byte2[j] & 15;
- break;
-
- case 'F': // fine frequency slide up
- tracks[t][k].command = 23;
- tracks[t][k].param1 = old_event_byte2[j] >> 4;
- tracks[t][k].param2 = old_event_byte2[j] & 15;
- break;
-
- case 'D': // fine volume slide
- tracks[t][k].command = 14;
- if (old_event_byte2[j] & 15)
- {
- // slide down
- tracks[t][k].param1 = 5;
- tracks[t][k].param2 = old_event_byte2[j] & 15;
- }
- else
- {
- // slide up
- tracks[t][k].param1 = 4;
- tracks[t][k].param2 = old_event_byte2[j] >> 4;
- }
- break;
-
- case 'J': // arpeggio
- tracks[t][k].param1 = old_event_byte2[j] >> 4;
- tracks[t][k].param2 = old_event_byte2[j] & 15;
- break;
- }
- }
-
- t++;
- }
- }
-
- delete[]module;
-
- // order loop
- restartpos = 0;
-
- // order length
- for (i = 0; i < 64; i++)
- {
- if (order[i] >= 0x80)
- {
- length = i;
- break;
- }
- }
-
- // default tempo
- bpm = 0x7D;
-
- rewind (0);
-
- return true;
-}
-
-void
-CcffLoader::rewind (int subsong)
-{
- CmodPlayer::rewind (subsong);
-
- // default instruments
- for (int i = 0; i < 9; i++)
- {
- channel[i].inst = i;
-
- channel[i].vol1 = 63 - (inst[i].data[10] & 63);
- channel[i].vol2 = 63 - (inst[i].data[9] & 63);
- }
-}
-
-std::string CcffLoader::gettype ()
-{
- if (header.packed)
- return std::string ("BoomTracker 4, packed");
- else
- return std::string ("BoomTracker 4");
-}
-
-std::string CcffLoader::gettitle ()
-{
- return std::string (song_title, 20);
-}
-
-std::string CcffLoader::getauthor ()
-{
- return std::string (song_author, 20);
-}
-
-std::string CcffLoader::getinstrument (unsigned int n)
-{
- return std::string (instruments[n].name);
-}
-
-unsigned int
-CcffLoader::getinstruments ()
-{
- return 47;
-}
-
-/* -------- Private Methods ------------------------------- */
-
-#ifdef _WIN32
-#pragma warning(disable:4244)
-#pragma warning(disable:4018)
-#endif
-
-/*
- Lempel-Ziv-Tyr ;-)
-*/
-long
-CcffLoader::cff_unpacker::unpack (unsigned char *ibuf, unsigned char *obuf)
-{
- if (memcmp (ibuf, "YsComp" "\x07" "CUD1997" "\x1A\x04", 16))
- return 0;
-
- input = ibuf + 16;
- output = obuf;
-
- output_length = 0;
-
- heap = (unsigned char *) malloc (0x10000);
- dictionary = (unsigned char **) malloc (sizeof (unsigned char *) * 0x8000);
-
- memset (heap, 0, 0x10000);
- memset (dictionary, 0, 0x8000);
-
- cleanup ();
- if (!startup ())
- goto out;
-
- // LZW
- while (1)
- {
- new_code = get_code ();
-
- // 0x00: end of data
- if (new_code == 0)
- break;
-
- // 0x01: end of block
- if (new_code == 1)
- {
- cleanup ();
- if (!startup ())
- goto out;
-
- continue;
- }
-
- // 0x02: expand code length
- if (new_code == 2)
- {
- code_length++;
-
- continue;
- }
-
- // 0x03: RLE
- if (new_code == 3)
- {
- unsigned char
- old_code_length = code_length;
-
- code_length = 2;
-
- unsigned char
- repeat_length = get_code () + 1;
-
- code_length = 4 << get_code ();
-
- unsigned long
- repeat_counter = get_code ();
-
- if (output_length + repeat_counter * repeat_length > 0x10000)
- {
- output_length = 0;
- goto out;
- }
-
- for (unsigned int i = 0; i < repeat_counter * repeat_length; i++)
- {
- output[output_length] = output[output_length - repeat_length];
- output_length++;
- }
-
- code_length = old_code_length;
-
- if (!startup ())
- goto out;
-
- continue;
- }
-
- if (new_code >= (0x104 + dictionary_length))
- {
- // dictionary <- old.code.string + old.code.char
- the_string[++the_string[0]] = the_string[1];
- }
- else
- {
- // dictionary <- old.code.string + new.code.char
- unsigned char
- temp_string[256];
-
- translate_code (new_code, temp_string);
-
- the_string[++the_string[0]] = temp_string[1];
- }
-
- expand_dictionary (the_string);
-
- // output <- new.code.string
- translate_code (new_code, the_string);
-
- if (output_length + the_string[0] > 0x10000)
- {
- output_length = 0;
- goto out;
- }
-
- for (int i = 0; i < the_string[0]; i++)
- output[output_length++] = the_string[i + 1];
-
- old_code = new_code;
- }
-
-out:
- free (heap);
- free (dictionary);
- return output_length;
-}
-
-unsigned long
-CcffLoader::cff_unpacker::get_code ()
-{
- unsigned long
- code;
-
- while (bits_left < code_length)
- {
- bits_buffer |= ((*input++) << bits_left);
- bits_left += 8;
- }
-
- code = bits_buffer & ((1 << code_length) - 1);
-
- bits_buffer >>= code_length;
- bits_left -= code_length;
-
- return code;
-}
-
-void
-CcffLoader::cff_unpacker::translate_code (unsigned long code,
- unsigned char *string)
-{
- unsigned char
- translated_string[256];
-
- if (code >= 0x104)
- {
- memcpy (translated_string, dictionary[code - 0x104],
- (*(dictionary[code - 0x104])) + 1);
- }
- else
- {
- translated_string[0] = 1;
- translated_string[1] = (code - 4) & 0xFF;
- }
-
- memcpy (string, translated_string, 256);
-}
-
-void
-CcffLoader::cff_unpacker::cleanup ()
-{
- code_length = 9;
-
- bits_buffer = 0;
- bits_left = 0;
-
- heap_length = 0;
- dictionary_length = 0;
-}
-
-int
-CcffLoader::cff_unpacker::startup ()
-{
- old_code = get_code ();
-
- translate_code (old_code, the_string);
-
- if (output_length + the_string[0] > 0x10000)
- {
- output_length = 0;
- return 0;
- }
-
- for (int i = 0; i < the_string[0]; i++)
- output[output_length++] = the_string[i + 1];
-
- return 1;
-}
-
-void
-CcffLoader::cff_unpacker::expand_dictionary (unsigned char *string)
-{
- if (string[0] >= 0xF0)
- return;
-
- memcpy (&heap[heap_length], string, string[0] + 1);
-
- dictionary[dictionary_length] = &heap[heap_length];
-
- dictionary_length++;
-
- heap_length += (string[0] + 1);
-}
-
-#ifdef _WIN32
-#pragma warning(default:4244)
-#pragma warning(default:4018)
-#endif
diff --git a/src/adplug/core/cff.h b/src/adplug/core/cff.h
index 73b2c10a562d..3cdff6ea8f2e 100644
--- a/src/adplug/core/cff.h
+++ b/src/adplug/core/cff.h
@@ -28,7 +28,7 @@ class CcffLoader: public CmodPlayer
CcffLoader(Copl *newopl) : CmodPlayer(newopl) { };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
void rewind(int subsong);
std::string gettype();
diff --git a/src/adplug/core/cmf.cc b/src/adplug/core/cmf.cc
new file mode 100644
index 000000000000..21f3490bb2c5
--- /dev/null
+++ b/src/adplug/core/cmf.cc
@@ -0,0 +1,788 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2009 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * cmf.cpp - CMF player by Adam Nielsen <malvineous at shikadi.net>
+ * Subset of CMF reader in MOPL code (Malvineous' OPL player), no seeking etc.
+ */
+
+#include <stdint.h> // for uintxx_t
+#include <cassert>
+#include <math.h> // for pow() etc.
+#include <string.h> // for memset
+#include "debug.h"
+#include "cmf.h"
+
+// ------------------------------
+// OPTIONS
+// ------------------------------
+
+// The official Creative Labs CMF player seems to ignore the note velocity
+// (playing every note at the same volume), but you can uncomment this to
+// allow the note velocity to affect the volume (as presumably the composer
+// originally intended.)
+//
+//#define USE_VELOCITY
+//
+// The Xargon demo song is a good example of a song that uses note velocity.
+
+// OPL register offsets
+#define BASE_CHAR_MULT 0x20
+#define BASE_SCAL_LEVL 0x40
+#define BASE_ATCK_DCAY 0x60
+#define BASE_SUST_RLSE 0x80
+#define BASE_FNUM_L 0xA0
+#define BASE_KEYON_FREQ 0xB0
+#define BASE_RHYTHM 0xBD
+#define BASE_WAVE 0xE0
+#define BASE_FEED_CONN 0xC0
+
+#define OPLBIT_KEYON 0x20 // Bit in BASE_KEYON_FREQ register for turning a note on
+
+// Supplied with a channel, return the offset from a base OPL register for the
+// Modulator cell (e.g. channel 4's modulator is at offset 0x09. Since 0x60 is
+// the attack/decay function, register 0x69 will thus set the attack/decay for
+// channel 4's modulator.) (channels go from 0 to 8 inclusive)
+#define OPLOFFSET(channel) (((channel) / 3) * 8 + ((channel) % 3))
+
+// These 16 instruments are repeated to fill up the 128 available slots. A CMF
+// file can override none/some/all of the 128 slots with custom instruments,
+// so any that aren't overridden are still available for use with these default
+// patches. The Word Rescue CMFs are good examples of songs that rely on these
+// default patches.
+uint8_t cDefaultPatches[] =
+"\x01\x11\x4F\x00\xF1\xD2\x53\x74\x00\x00\x06"
+"\x07\x12\x4F\x00\xF2\xF2\x60\x72\x00\x00\x08"
+"\x31\xA1\x1C\x80\x51\x54\x03\x67\x00\x00\x0E"
+"\x31\xA1\x1C\x80\x41\x92\x0B\x3B\x00\x00\x0E"
+"\x31\x16\x87\x80\xA1\x7D\x11\x43\x00\x00\x08"
+"\x30\xB1\xC8\x80\xD5\x61\x19\x1B\x00\x00\x0C"
+"\xF1\x21\x01\x00\x97\xF1\x17\x18\x00\x00\x08"
+"\x32\x16\x87\x80\xA1\x7D\x10\x33\x00\x00\x08"
+"\x01\x12\x4F\x00\x71\x52\x53\x7C\x00\x00\x0A"
+"\x02\x03\x8D\x00\xD7\xF5\x37\x18\x00\x00\x04"
+"\x21\x21\xD1\x00\xA3\xA4\x46\x25\x00\x00\x0A"
+"\x22\x22\x0F\x00\xF6\xF6\x95\x36\x00\x00\x0A"
+"\xE1\xE1\x00\x00\x44\x54\x24\x34\x02\x02\x07"
+"\xA5\xB1\xD2\x80\x81\xF1\x03\x05\x00\x00\x02"
+"\x71\x22\xC5\x00\x6E\x8B\x17\x0E\x00\x00\x02"
+"\x32\x21\x16\x80\x73\x75\x24\x57\x00\x00\x0E";
+
+
+CPlayer *CcmfPlayer::factory(Copl *newopl)
+{
+ return new CcmfPlayer(newopl);
+}
+
+CcmfPlayer::CcmfPlayer(Copl *newopl) :
+ CPlayer(newopl),
+ data(nullptr),
+ pInstruments(nullptr),
+ bPercussive(false),
+ iTranspose(0),
+ iPrevCommand(0)
+{
+ assert(OPLOFFSET(1-1) == 0x00);
+ assert(OPLOFFSET(5-1) == 0x09);
+ assert(OPLOFFSET(9-1) == 0x12);
+}
+
+CcmfPlayer::~CcmfPlayer()
+{
+ if (this->data) delete[] data;
+ if (this->pInstruments) delete[] pInstruments;
+}
+
+bool CcmfPlayer::load(VFSFile & fd, const CFileProvider &fp)
+{
+ binistream *f = fp.open(fd);
+ if(!f) return false;
+
+ char cSig[4];
+ f->readString(cSig, 4);
+ if (
+ (cSig[0] != 'C') ||
+ (cSig[1] != 'T') ||
+ (cSig[2] != 'M') ||
+ (cSig[3] != 'F')
+ ) {
+ // Not a CMF file
+ fp.close(f);
+ return false;
+ }
+ uint16_t iVer = f->readInt(2);
+ if ((iVer != 0x0101) && (iVer != 0x0100)) {
+ AdPlug_LogWrite("CMF file is not v1.0 or v1.1 (reports %d.%d)\n", iVer >> 8 , iVer & 0xFF);
+ fp.close(f);
+ return false;
+ }
+
+ this->cmfHeader.iInstrumentBlockOffset = f->readInt(2);
+ this->cmfHeader.iMusicOffset = f->readInt(2);
+ this->cmfHeader.iTicksPerQuarterNote = f->readInt(2);
+ this->cmfHeader.iTicksPerSecond = f->readInt(2);
+ this->cmfHeader.iTagOffsetTitle = f->readInt(2);
+ this->cmfHeader.iTagOffsetComposer = f->readInt(2);
+ this->cmfHeader.iTagOffsetRemarks = f->readInt(2);
+ f->readString((char *)this->cmfHeader.iChannelsInUse, 16);
+ if (iVer == 0x0100) {
+ this->cmfHeader.iNumInstruments = f->readInt(1);
+ this->cmfHeader.iTempo = 0;
+ } else { // 0x0101
+ this->cmfHeader.iNumInstruments = f->readInt(2);
+ this->cmfHeader.iTempo = f->readInt(2);
+ }
+
+ // Load the instruments
+
+ f->seek(this->cmfHeader.iInstrumentBlockOffset);
+ this->pInstruments = new SBI[
+ (this->cmfHeader.iNumInstruments < 128) ? 128 : this->cmfHeader.iNumInstruments
+ ]; // Always at least 128 available for use
+
+ for (int i = 0; i < this->cmfHeader.iNumInstruments; i++) {
+ this->pInstruments[i].op[0].iCharMult = f->readInt(1);
+ this->pInstruments[i].op[1].iCharMult = f->readInt(1);
+ this->pInstruments[i].op[0].iScalingOutput = f->readInt(1);
+ this->pInstruments[i].op[1].iScalingOutput = f->readInt(1);
+ this->pInstruments[i].op[0].iAttackDecay = f->readInt(1);
+ this->pInstruments[i].op[1].iAttackDecay = f->readInt(1);
+ this->pInstruments[i].op[0].iSustainRelease = f->readInt(1);
+ this->pInstruments[i].op[1].iSustainRelease = f->readInt(1);
+ this->pInstruments[i].op[0].iWaveSel = f->readInt(1);
+ this->pInstruments[i].op[1].iWaveSel = f->readInt(1);
+ this->pInstruments[i].iConnection = f->readInt(1);
+ f->seek(5, binio::Add); // skip over the padding bytes
+ }
+
+ // Set the rest of the instruments to the CMF defaults
+ for (int i = this->cmfHeader.iNumInstruments; i < 128; i++) {
+ this->pInstruments[i].op[0].iCharMult = cDefaultPatches[(i % 16) * 11 + 0];
+ this->pInstruments[i].op[1].iCharMult = cDefaultPatches[(i % 16) * 11 + 1];
+ this->pInstruments[i].op[0].iScalingOutput = cDefaultPatches[(i % 16) * 11 + 2];
+ this->pInstruments[i].op[1].iScalingOutput = cDefaultPatches[(i % 16) * 11 + 3];
+ this->pInstruments[i].op[0].iAttackDecay = cDefaultPatches[(i % 16) * 11 + 4];
+ this->pInstruments[i].op[1].iAttackDecay = cDefaultPatches[(i % 16) * 11 + 5];
+ this->pInstruments[i].op[0].iSustainRelease = cDefaultPatches[(i % 16) * 11 + 6];
+ this->pInstruments[i].op[1].iSustainRelease = cDefaultPatches[(i % 16) * 11 + 7];
+ this->pInstruments[i].op[0].iWaveSel = cDefaultPatches[(i % 16) * 11 + 8];
+ this->pInstruments[i].op[1].iWaveSel = cDefaultPatches[(i % 16) * 11 + 9];
+ this->pInstruments[i].iConnection = cDefaultPatches[(i % 16) * 11 + 10];
+ }
+
+ if (this->cmfHeader.iTagOffsetTitle) {
+ f->seek(this->cmfHeader.iTagOffsetTitle);
+ this->strTitle = f->readString('\0');
+ }
+ if (this->cmfHeader.iTagOffsetComposer) {
+ f->seek(this->cmfHeader.iTagOffsetComposer);
+ this->strComposer = f->readString('\0');
+ }
+ if (this->cmfHeader.iTagOffsetRemarks) {
+ f->seek(this->cmfHeader.iTagOffsetRemarks);
+ this->strRemarks = f->readString('\0');
+ }
+
+ // Load the MIDI data into memory
+ f->seek(this->cmfHeader.iMusicOffset);
+ this->iSongLen = fp.filesize(f) - this->cmfHeader.iMusicOffset;
+ this->data = new unsigned char[this->iSongLen];
+ f->readString((char *)data, this->iSongLen);
+
+ fp.close(f);
+ rewind(0);
+
+ return true;
+}
+
+bool CcmfPlayer::update()
+{
+ // This has to be here and not in getrefresh() for some reason.
+ this->iDelayRemaining = 0;
+
+ // Read in the next event
+ while (!this->iDelayRemaining) {
+ uint8_t iCommand = this->data[this->iPlayPointer++];
+ if ((iCommand & 0x80) == 0) {
+ // Running status, use previous command
+ this->iPlayPointer--;
+ iCommand = this->iPrevCommand;
+ } else {
+ this->iPrevCommand = iCommand;
+ }
+ uint8_t iChannel = iCommand & 0x0F;
+ switch (iCommand & 0xF0) {
+ case 0x80: { // Note off (two data bytes)
+ uint8_t iNote = this->data[this->iPlayPointer++];
+ uint8_t iVelocity = this->data[this->iPlayPointer++]; // release velocity
+ this->cmfNoteOff(iChannel, iNote, iVelocity);
+ break;
+ }
+ case 0x90: { // Note on (two data bytes)
+ uint8_t iNote = this->data[this->iPlayPointer++];
+ uint8_t iVelocity = this->data[this->iPlayPointer++]; // attack velocity
+ if (iVelocity) {
+ this->cmfNoteOn(iChannel, iNote, iVelocity);
+ } else {
+ // This is a note-off instead (velocity == 0)
+ this->cmfNoteOff(iChannel, iNote, iVelocity); // 64 is the MIDI default note-off velocity
+ break;
+ }
+ break;
+ }
+ case 0xA0: { // Polyphonic key pressure (two data bytes)
+ uint8_t iNote = this->data[this->iPlayPointer++];
+ uint8_t iPressure = this->data[this->iPlayPointer++];
+ AdPlug_LogWrite("CMF: Key pressure not yet implemented! (wanted ch%d/note %d set to %d)\n", iChannel, iNote, iPressure);
+ break;
+ }
+ case 0xB0: { // Controller (two data bytes)
+ uint8_t iController = this->data[this->iPlayPointer++];
+ uint8_t iValue = this->data[this->iPlayPointer++];
+ this->MIDIcontroller(iChannel, iController, iValue);
+ break;
+ }
+ case 0xC0: { // Instrument change (one data byte)
+ uint8_t iNewInstrument = this->data[this->iPlayPointer++];
+ this->chMIDI[iChannel].iPatch = iNewInstrument;
+ AdPlug_LogWrite("CMF: Remembering MIDI channel %d now uses patch %d\n", iChannel, iNewInstrument);
+ break;
+ }
+ case 0xD0: { // Channel pressure (one data byte)
+ uint8_t iPressure = this->data[this->iPlayPointer++];
+ AdPlug_LogWrite("CMF: Channel pressure not yet implemented! (wanted ch%d set to %d)\n", iChannel, iPressure);
+ break;
+ }
+ case 0xE0: { // Pitch bend (two data bytes)
+ uint8_t iLSB = this->data[this->iPlayPointer++];
+ uint8_t iMSB = this->data[this->iPlayPointer++];
+ uint16_t iValue = (iMSB << 7) | iLSB;
+ // 8192 is middle/off, 0 is -2 semitones, 16384 is +2 semitones
+ this->chMIDI[iChannel].iPitchbend = iValue;
+ AdPlug_LogWrite("CMF: Channel %d pitchbent to %d (%+.2f)\n", iChannel + 1, iValue, (float)(iValue - 8192) / 8192);
+ break;
+ }
+ case 0xF0: // System message (arbitrary data bytes)
+ switch (iCommand) {
+ case 0xF0: { // Sysex
+ uint8_t iNextByte;
+ AdPlug_LogWrite("Sysex message: ");
+ do {
+ iNextByte = this->data[this->iPlayPointer++];
+ AdPlug_LogWrite("%02X", iNextByte);
+ } while ((iNextByte & 0x80) == 0);
+ AdPlug_LogWrite("\n");
+ // This will have read in the terminating EOX (0xF7) message too
+ break;
+ }
+ case 0xF1: // MIDI Time Code Quarter Frame
+ this->iPlayPointer++; // message data (ignored)
+ break;
+ case 0xF2: // Song position pointer
+ this->iPlayPointer++; // message data (ignored)
+ this->iPlayPointer++;
+ break;
+ case 0xF3: // Song select
+ this->iPlayPointer++; // message data (ignored)
+ AdPlug_LogWrite("CMF: MIDI Song Select is not implemented.\n");
+ break;
+ case 0xF6: // Tune request
+ break;
+ case 0xF7: // End of System Exclusive (EOX) - should never be read, should be absorbed by Sysex handling code
+ break;
+
+ // These messages are "real time", meaning they can be sent between
+ // the bytes of other messages - but we're lazy and don't handle these
+ // here (hopefully they're not necessary in a MIDI file, and even less
+ // likely to occur in a CMF.)
+ case 0xF8: // Timing clock (sent 24 times per quarter note, only when playing)
+ case 0xFA: // Start
+ case 0xFB: // Continue
+ case 0xFE: // Active sensing (sent every 300ms or MIDI connection assumed lost)
+ break;
+ case 0xFC: // Stop
+ AdPlug_LogWrite("CMF: Received Real Time Stop message (0xFC)\n");
+ this->bSongEnd = true;
+ this->iPlayPointer = 0; // for repeat in endless-play mode
+ break;
+ case 0xFF: { // System reset, used as meta-events in a MIDI file
+ uint8_t iEvent = this->data[this->iPlayPointer++];
+ switch (iEvent) {
+ case 0x2F: // end of track
+ AdPlug_LogWrite("CMF: End-of-track, stopping playback\n");
+ this->bSongEnd = true;
+ this->iPlayPointer = 0; // for repeat in endless-play mode
+ break;
+ default:
+ AdPlug_LogWrite("CMF: Unknown MIDI meta-event 0xFF 0x%02X\n", iEvent);
+ break;
+ }
+ break;
+ }
+ default:
+ AdPlug_LogWrite("CMF: Unknown MIDI system command 0x%02X\n", iCommand);
+ break;
+ }
+ break;
+ default:
+ AdPlug_LogWrite("CMF: Unknown MIDI command 0x%02X\n", iCommand);
+ break;
+ }
+
+ if (this->iPlayPointer >= this->iSongLen) {
+ this->bSongEnd = true;
+ this->iPlayPointer = 0; // for repeat in endless-play mode
+ }
+
+ // Read in the number of ticks until the next event
+ this->iDelayRemaining = this->readMIDINumber();
+ }
+
+ return !this->bSongEnd;
+}
+
+void CcmfPlayer::rewind(int subsong)
+{
+ this->opl->init();
+
+ // Initialise
+
+ // Enable use of WaveSel register on OPL3 (even though we're only an OPL2!)
+ // Apparently this enables nine-channel mode?
+ this->writeOPL(0x01, 0x20);
+
+ // Disable OPL3 mode (can be left enabled by a previous non-CMF song)
+ this->writeOPL(0x05, 0x00);
+
+ // Really make sure CSM+SEL are off (again, Creative's player...)
+ this->writeOPL(0x08, 0x00);
+
+ // This freq setting is required for the hihat to sound correct at the start
+ // of funky.cmf, even though it's for an unrelated channel.
+ // If it's here however, it makes the hihat in Word Rescue's theme.cmf
+ // sound really bad.
+ // TODO: How do we figure out whether we need it or not???
+ this->writeOPL(BASE_FNUM_L + 8, 514 & 0xFF);
+ this->writeOPL(BASE_KEYON_FREQ + 8, (1 << 2) | (514 >> 8));
+
+ // default freqs?
+ this->writeOPL(BASE_FNUM_L + 7, 509 & 0xFF);
+ this->writeOPL(BASE_KEYON_FREQ + 7, (2 << 2) | (509 >> 8));
+ this->writeOPL(BASE_FNUM_L + 6, 432 & 0xFF);
+ this->writeOPL(BASE_KEYON_FREQ + 6, (2 << 2) | (432 >> 8));
+
+ // Amplify AM + VIB depth. Creative's CMF player does this, and there
+ // doesn't seem to be any way to stop it from doing so - except for the
+ // non-standard controller 0x63 I added :-)
+ this->writeOPL(0xBD, 0xC0);
+
+ this->bSongEnd = false;
+ this->iPlayPointer = 0;
+ this->iPrevCommand = 0; // just in case
+
+ // Read in the number of ticks until the first event
+ this->iDelayRemaining = this->readMIDINumber();
+
+ // Reset song state. This used to be in the constructor, but the XMMS2
+ // plugin sets the song length before starting playback. AdPlug plays the
+ // song in its entirety (with no synth) to determine the song length, which
+ // results in the state variables below matching the end of the song. When
+ // the real OPL synth is activated for playback, it no longer matches the
+ // state variables and the instruments are not set correctly!
+ for (int i = 0; i < 9; i++) {
+ this->chOPL[i].iNoteStart = 0; // no note playing atm
+ this->chOPL[i].iMIDINote = -1;
+ this->chOPL[i].iMIDIChannel = -1;
+ this->chOPL[i].iMIDIPatch = -1;
+
+ this->chMIDI[i].iPatch = -2;
+ this->chMIDI[i].iPitchbend = 8192;
+ }
+ for (int i = 9; i < 16; i++) {
+ this->chMIDI[i].iPatch = -2;
+ this->chMIDI[i].iPitchbend = 8192;
+ }
+
+ memset(this->iCurrentRegs, 0, 256);
+
+ return;
+}
+
+// Return value: 1 == 1 second, 2 == 0.5 seconds
+float CcmfPlayer::getrefresh()
+{
+ if (this->iDelayRemaining) {
+ return (float)this->cmfHeader.iTicksPerSecond / (float)this->iDelayRemaining;
+ } else {
+ // Delay-remaining is zero (e.g. start of song) so use a tiny delay
+ return this->cmfHeader.iTicksPerSecond; // wait for one tick
+ }
+}
+
+std::string CcmfPlayer::gettitle()
+{
+ return this->strTitle;
+}
+std::string CcmfPlayer::getauthor()
+{
+ return this->strComposer;
+}
+std::string CcmfPlayer::getdesc()
+{
+ return this->strRemarks;
+}
+
+
+//
+// PROTECTED
+//
+
+// Read a variable-length integer from MIDI data
+uint32_t CcmfPlayer::readMIDINumber()
+{
+ uint32_t iValue = 0;
+ for (int i = 0; i < 4; i++) {
+ uint8_t iNext = this->data[this->iPlayPointer++];
+ iValue <<= 7;
+ iValue |= (iNext & 0x7F); // ignore the MSB
+ if ((iNext & 0x80) == 0) break; // last byte has the MSB unset
+ }
+ return iValue;
+}
+
+// iChannel: OPL channel (0-8)
+// iOperator: 0 == Modulator, 1 == Carrier
+// Source - source operator to read from instrument definition
+// Dest - destination operator on OPL chip
+// iInstrument: Index into this->pInstruments array of CMF instruments
+void CcmfPlayer::writeInstrumentSettings(uint8_t iChannel, uint8_t iOperatorSource, uint8_t iOperatorDest, uint8_t iInstrument)
+{
+ assert(iChannel <= 8);
+
+ uint8_t iOPLOffset = OPLOFFSET(iChannel);
+ if (iOperatorDest) iOPLOffset += 3; // Carrier if iOperator == 1 (else Modulator)
+
+ this->writeOPL(BASE_CHAR_MULT + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iCharMult);
+ this->writeOPL(BASE_SCAL_LEVL + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iScalingOutput);
+ this->writeOPL(BASE_ATCK_DCAY + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iAttackDecay);
+ this->writeOPL(BASE_SUST_RLSE + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iSustainRelease);
+ this->writeOPL(BASE_WAVE + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iWaveSel);
+
+ // TODO: Check to see whether we should only be loading this for one or both operators
+ this->writeOPL(BASE_FEED_CONN + iChannel, this->pInstruments[iInstrument].iConnection);
+ return;
+}
+
+// Write a byte to the OPL "chip" and update the current record of register states
+void CcmfPlayer::writeOPL(uint8_t iRegister, uint8_t iValue)
+{
+ this->opl->write(iRegister, iValue);
+ this->iCurrentRegs[iRegister] = iValue;
+ return;
+}
+
+void CcmfPlayer::cmfNoteOn(uint8_t iChannel, uint8_t iNote, uint8_t iVelocity)
+{
+ uint8_t iBlock = iNote / 12;
+ if (iBlock > 1) iBlock--; // keep in the same range as the Creative player
+ //if (iBlock > 7) iBlock = 7; // don't want to go out of range
+
+ double d = pow(2, (
+ (double)iNote + (
+ (this->chMIDI[iChannel].iPitchbend - 8192) / 8192.0
+ ) + (
+ this->iTranspose / 128
+ ) - 9) / 12.0 - (iBlock - 20))
+ * 440.0 / 32.0 / 50000.0;
+ uint16_t iOPLFNum = (uint16_t)(d+0.5);
+ if (iOPLFNum > 1023) AdPlug_LogWrite("CMF: This note is out of range! (send this song to malvineous at shikadi.net!)\n");
+
+ // See if we're playing a rhythm mode percussive instrument
+ if ((iChannel > 10) && (this->bPercussive)) {
+ uint8_t iPercChannel = this->getPercChannel(iChannel);
+
+ // Will have to set every time (easier) than figuring out whether the mod
+ // or car needs to be changed.
+ //if (this->chOPL[iPercChannel].iMIDIPatch != this->chMIDI[iChannel].iPatch) {
+ this->MIDIchangeInstrument(iPercChannel, iChannel, this->chMIDI[iChannel].iPatch);
+ //}
+
+ /* Velocity calculations - TODO: Work out the proper formula
+
+ iVelocity -> iLevel (values generated by Creative's player)
+ 7f -> 00
+ 7c -> 00
+
+ 7b -> 09
+ 73 -> 0a
+ 6b -> 0b
+ 63 -> 0c
+ 5b -> 0d
+ 53 -> 0e
+ 4b -> 0f
+ 43 -> 10
+ 3b -> 11
+ 33 -> 13
+ 2b -> 15
+ 23 -> 19
+ 1b -> 1b
+ 13 -> 1d
+ 0b -> 1f
+ 03 -> 21
+
+ 02 -> 21
+ 00 -> N/A (note off)
+ */
+ // Approximate formula, need to figure out more accurate one (my maths isn't so good...)
+ int iLevel = 0x25 - (int) sqrt(iVelocity * 16 /* 6 */); // (127 - iVelocity) * 0x20 / 127;
+ if (iVelocity > 0x7b) iLevel = 0; // full volume
+ if (iLevel < 0) iLevel = 0;
+ if (iLevel > 0x3F) iLevel = 0x3F;
+ //if (iVelocity < 0x40) iLevel = 0x10;
+
+ int iOPLOffset = BASE_SCAL_LEVL + OPLOFFSET(iPercChannel);
+ //if ((iChannel == 11) || (iChannel == 12) || (iChannel == 14)) {
+ if (iChannel == 11) iOPLOffset += 3; // only do bassdrum carrier for volume control
+ //iOPLOffset += 3; // carrier
+ this->writeOPL(iOPLOffset, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | iLevel);//(iVelocity * 0x3F / 127));
+ //}
+ // Bass drum (ch11) uses both operators
+ //if (iChannel == 11) this->writeOPL(iOPLOffset + 3, (this->iCurrentRegs[iOPLOffset + 3] & ~0x3F) | iLevel);
+
+/* #ifdef USE_VELOCITY // Official CMF player seems to ignore velocity levels
+ uint16_t iLevel = 0x2F - (iVelocity * 0x2F / 127); // 0x2F should be 0x3F but it's too quiet then
+ AdPlug_LogWrite("%02X + vel %d (lev %02X) == %02X\n", this->iCurrentRegs[iOPLOffset], iVelocity, iLevel, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | iLevel);
+ //this->writeOPL(iOPLOffset, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | (0x3F - (iVelocity >> 1)));//(iVelocity * 0x3F / 127));
+ this->writeOPL(iOPLOffset, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | iLevel);//(iVelocity * 0x3F / 127));
+ #endif*/
+
+ // Apparently you can't set the frequency for the cymbal or hihat?
+ // Vinyl requires you don't set it, Kiloblaster requires you do!
+ this->writeOPL(BASE_FNUM_L + iPercChannel, iOPLFNum & 0xFF);
+ this->writeOPL(BASE_KEYON_FREQ + iPercChannel, (iBlock << 2) | ((iOPLFNum >> 8) & 0x03));
+
+ uint8_t iBit = 1 << (15 - iChannel);
+
+ // Turn the perc instrument off if it's already playing (OPL can't do
+ // polyphonic notes w/ percussion)
+ if (this->iCurrentRegs[BASE_RHYTHM] & iBit) this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] & ~iBit);
+
+ // I wonder whether we need to delay or anything here?
+
+ // Turn the note on
+ //if (iChannel == 15) {
+ this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] | iBit);
+ //AdPlug_LogWrite("CMF: Note %d on MIDI channel %d (mapped to OPL channel %d-1) - vel %02X, fnum %d/%d\n", iNote, iChannel, iPercChannel+1, iVelocity, iOPLFNum, iBlock);
+ //}
+
+ this->chOPL[iPercChannel].iNoteStart = ++this->iNoteCount;
+ this->chOPL[iPercChannel].iMIDIChannel = iChannel;
+ this->chOPL[iPercChannel].iMIDINote = iNote;
+
+ } else { // Non rhythm-mode or a normal instrument channel
+
+ // Figure out which OPL channel to play this note on
+ int iOPLChannel = -1;
+ int iNumChannels = this->bPercussive ? 6 : 9;
+ for (int i = iNumChannels - 1; i >= 0; i--) {
+ // If there's no note playing on this OPL channel, use that
+ if (this->chOPL[i].iNoteStart == 0) {
+ iOPLChannel = i;
+ // See if this channel is already set to the instrument we want.
+ if (this->chOPL[i].iMIDIPatch == this->chMIDI[iChannel].iPatch) {
+ // It is, so stop searching
+ break;
+ } // else keep searching just in case there's a better match
+ }
+ }
+ if (iOPLChannel == -1) {
+ // All channels were in use, find the one with the longest note
+ iOPLChannel = 0;
+ int iEarliest = this->chOPL[0].iNoteStart;
+ for (int i = 1; i < iNumChannels; i++) {
+ if (this->chOPL[i].iNoteStart < iEarliest) {
+ // Found a channel with a note being played for longer
+ iOPLChannel = i;
+ iEarliest = this->chOPL[i].iNoteStart;
+ }
+ }
+ AdPlug_LogWrite("CMF: Too many polyphonic notes, cutting note on channel %d\n", iOPLChannel);
+ }
+
+ // Run through all the channels with negative notestart values - these
+ // channels have had notes recently stop - and increment the counter
+ // to slowly move the channel closer to being reused for a future note.
+ //for (int i = 0; i < iNumChannels; i++) {
+ // if (this->chOPL[i].iNoteStart < 0) this->chOPL[i].iNoteStart++;
+ //}
+
+ // Now the new note should be played on iOPLChannel, but see if the instrument
+ // is right first.
+ if (this->chOPL[iOPLChannel].iMIDIPatch != this->chMIDI[iChannel].iPatch) {
+ this->MIDIchangeInstrument(iOPLChannel, iChannel, this->chMIDI[iChannel].iPatch);
+ }
+
+ this->chOPL[iOPLChannel].iNoteStart = ++this->iNoteCount;
+ this->chOPL[iOPLChannel].iMIDIChannel = iChannel;
+ this->chOPL[iOPLChannel].iMIDINote = iNote;
+
+ #ifdef USE_VELOCITY // Official CMF player seems to ignore velocity levels
+ // Adjust the channel volume to match the note velocity
+ uint8_t iOPLOffset = BASE_SCAL_LEVL + OPLOFFSET(iChannel) + 3; // +3 == Carrier
+ uint16_t iLevel = 0x2F - (iVelocity * 0x2F / 127); // 0x2F should be 0x3F but it's too quiet then
+ this->writeOPL(iOPLOffset, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | iLevel);
+ #endif
+
+ // Set the frequency and play the note
+ this->writeOPL(BASE_FNUM_L + iOPLChannel, iOPLFNum & 0xFF);
+ this->writeOPL(BASE_KEYON_FREQ + iOPLChannel, OPLBIT_KEYON | (iBlock << 2) | ((iOPLFNum & 0x300) >> 8));
+ }
+ return;
+}
+
+void CcmfPlayer::cmfNoteOff(uint8_t iChannel, uint8_t iNote, uint8_t iVelocity)
+{
+ if ((iChannel > 10) && (this->bPercussive)) {
+ int iOPLChannel = this->getPercChannel(iChannel);
+ if (this->chOPL[iOPLChannel].iMIDINote != iNote) return; // there's a different note playing now
+ this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] & ~(1 << (15 - iChannel)));
+ this->chOPL[iOPLChannel].iNoteStart = 0; // channel free
+ } else { // Non rhythm-mode or a normal instrument channel
+ int iOPLChannel = -1;
+ int iNumChannels = this->bPercussive ? 6 : 9;
+ for (int i = 0; i < iNumChannels; i++) {
+ if (
+ (this->chOPL[i].iMIDIChannel == iChannel) &&
+ (this->chOPL[i].iMIDINote == iNote) &&
+ (this->chOPL[i].iNoteStart != 0)
+ ) {
+ // Found the note, switch it off
+ this->chOPL[i].iNoteStart = 0;
+ iOPLChannel = i;
+ break;
+ }
+ }
+ if (iOPLChannel == -1) return;
+
+ this->writeOPL(BASE_KEYON_FREQ + iOPLChannel, this->iCurrentRegs[BASE_KEYON_FREQ + iOPLChannel] & ~OPLBIT_KEYON);
+ }
+ return;
+}
+
+uint8_t CcmfPlayer::getPercChannel(uint8_t iChannel)
+{
+ switch (iChannel) {
+ case 11: return 7-1; // Bass drum
+ case 12: return 8-1; // Snare drum
+ case 13: return 9-1; // Tom tom
+ case 14: return 9-1; // Top cymbal
+ case 15: return 8-1; // Hihat
+ }
+ AdPlug_LogWrite("CMF ERR: Tried to get the percussion channel from MIDI channel %d - this shouldn't happen!\n", iChannel);
+ return 0;
+}
+
+
+void CcmfPlayer::MIDIchangeInstrument(uint8_t iOPLChannel, uint8_t iMIDIChannel, uint8_t iNewInstrument)
+{
+ if ((iMIDIChannel > 10) && (this->bPercussive)) {
+ switch (iMIDIChannel) {
+ case 11: // Bass drum (operator 13+16 == channel 7 modulator+carrier)
+ this->writeInstrumentSettings(7-1, 0, 0, iNewInstrument);
+ this->writeInstrumentSettings(7-1, 1, 1, iNewInstrument);
+ break;
+ case 12: // Snare drum (operator 17 == channel 8 carrier)
+ //case 15:
+ this->writeInstrumentSettings(8-1, 0, 1, iNewInstrument);
+
+ //
+ //this->writeInstrumentSettings(8-1, 0, 0, iNewInstrument);
+ break;
+ case 13: // Tom tom (operator 15 == channel 9 modulator)
+ //case 14:
+ this->writeInstrumentSettings(9-1, 0, 0, iNewInstrument);
+
+ //
+ //this->writeInstrumentSettings(9-1, 0, 1, iNewInstrument);
+ break;
+ case 14: // Top cymbal (operator 18 == channel 9 carrier)
+ this->writeInstrumentSettings(9-1, 0, 1, iNewInstrument);
+ break;
+ case 15: // Hi-hat (operator 14 == channel 8 modulator)
+ this->writeInstrumentSettings(8-1, 0, 0, iNewInstrument);
+ break;
+ default:
+ AdPlug_LogWrite("CMF: Invalid MIDI channel %d (not melodic and not percussive!)\n", iMIDIChannel + 1);
+ break;
+ }
+ this->chOPL[iOPLChannel].iMIDIPatch = iNewInstrument;
+ } else {
+ // Standard nine OPL channels
+ this->writeInstrumentSettings(iOPLChannel, 0, 0, iNewInstrument);
+ this->writeInstrumentSettings(iOPLChannel, 1, 1, iNewInstrument);
+ this->chOPL[iOPLChannel].iMIDIPatch = iNewInstrument;
+ }
+ return;
+}
+
+void CcmfPlayer::MIDIcontroller(uint8_t iChannel, uint8_t iController, uint8_t iValue)
+{
+ switch (iController) {
+ case 0x63:
+ // Custom extension to allow CMF files to switch the AM+VIB depth on and
+ // off (officially both are on, and there's no way to switch them off.)
+ // Controller values:
+ // 0 == AM+VIB off
+ // 1 == VIB on
+ // 2 == AM on
+ // 3 == AM+VIB on
+ if (iValue) {
+ this->writeOPL(BASE_RHYTHM, (this->iCurrentRegs[BASE_RHYTHM] & ~0xC0) | (iValue << 6)); // switch AM+VIB extension on
+ } else {
+ this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] & ~0xC0); // switch AM+VIB extension off
+ }
+ AdPlug_LogWrite("CMF: AM+VIB depth change - AM %s, VIB %s\n",
+ (this->iCurrentRegs[BASE_RHYTHM] & 0x80) ? "on" : "off",
+ (this->iCurrentRegs[BASE_RHYTHM] & 0x40) ? "on" : "off");
+ break;
+ case 0x66:
+ AdPlug_LogWrite("CMF: Song set marker to 0x%02X\n", iValue);
+ break;
+ case 0x67:
+ this->bPercussive = (iValue != 0);
+ if (this->bPercussive) {
+ this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] | 0x20); // switch rhythm-mode on
+ } else {
+ this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] & ~0x20); // switch rhythm-mode off
+ }
+ AdPlug_LogWrite("CMF: Percussive/rhythm mode %s\n", this->bPercussive ? "enabled" : "disabled");
+ break;
+ case 0x68:
+ // TODO: Shouldn't this just affect the one channel, not the whole song? -- have pitchbends for that
+ this->iTranspose = iValue;
+ AdPlug_LogWrite("CMF: Transposing all notes up by %d * 1/128ths of a semitone.\n", iValue);
+ break;
+ case 0x69:
+ this->iTranspose = -iValue;
+ AdPlug_LogWrite("CMF: Transposing all notes down by %d * 1/128ths of a semitone.\n", iValue);
+ break;
+ default:
+ AdPlug_LogWrite("CMF: Unsupported MIDI controller 0x%02X, ignoring.\n", iController);
+ break;
+ }
+ return;
+}
diff --git a/src/adplug/core/cmf.cxx b/src/adplug/core/cmf.cxx
deleted file mode 100644
index bca87a48a294..000000000000
--- a/src/adplug/core/cmf.cxx
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2009 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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
- *
- * cmf.cpp - CMF player by Adam Nielsen <malvineous at shikadi.net>
- * Subset of CMF reader in MOPL code (Malvineous' OPL player), no seeking etc.
- */
-
-#include <stdint.h> // for uintxx_t
-#include <cassert>
-#include <math.h> // for pow() etc.
-#include <string.h> // for memset
-#include "debug.h"
-#include "cmf.h"
-
-// ------------------------------
-// OPTIONS
-// ------------------------------
-
-// The official Creative Labs CMF player seems to ignore the note velocity
-// (playing every note at the same volume), but you can uncomment this to
-// allow the note velocity to affect the volume (as presumably the composer
-// originally intended.)
-//
-//#define USE_VELOCITY
-//
-// The Xargon demo song is a good example of a song that uses note velocity.
-
-// OPL register offsets
-#define BASE_CHAR_MULT 0x20
-#define BASE_SCAL_LEVL 0x40
-#define BASE_ATCK_DCAY 0x60
-#define BASE_SUST_RLSE 0x80
-#define BASE_FNUM_L 0xA0
-#define BASE_KEYON_FREQ 0xB0
-#define BASE_RHYTHM 0xBD
-#define BASE_WAVE 0xE0
-#define BASE_FEED_CONN 0xC0
-
-#define OPLBIT_KEYON 0x20 // Bit in BASE_KEYON_FREQ register for turning a note on
-
-// Supplied with a channel, return the offset from a base OPL register for the
-// Modulator cell (e.g. channel 4's modulator is at offset 0x09. Since 0x60 is
-// the attack/decay function, register 0x69 will thus set the attack/decay for
-// channel 4's modulator.) (channels go from 0 to 8 inclusive)
-#define OPLOFFSET(channel) (((channel) / 3) * 8 + ((channel) % 3))
-
-// These 16 instruments are repeated to fill up the 128 available slots. A CMF
-// file can override none/some/all of the 128 slots with custom instruments,
-// so any that aren't overridden are still available for use with these default
-// patches. The Word Rescue CMFs are good examples of songs that rely on these
-// default patches.
-uint8_t cDefaultPatches[] =
-"\x01\x11\x4F\x00\xF1\xD2\x53\x74\x00\x00\x06"
-"\x07\x12\x4F\x00\xF2\xF2\x60\x72\x00\x00\x08"
-"\x31\xA1\x1C\x80\x51\x54\x03\x67\x00\x00\x0E"
-"\x31\xA1\x1C\x80\x41\x92\x0B\x3B\x00\x00\x0E"
-"\x31\x16\x87\x80\xA1\x7D\x11\x43\x00\x00\x08"
-"\x30\xB1\xC8\x80\xD5\x61\x19\x1B\x00\x00\x0C"
-"\xF1\x21\x01\x00\x97\xF1\x17\x18\x00\x00\x08"
-"\x32\x16\x87\x80\xA1\x7D\x10\x33\x00\x00\x08"
-"\x01\x12\x4F\x00\x71\x52\x53\x7C\x00\x00\x0A"
-"\x02\x03\x8D\x00\xD7\xF5\x37\x18\x00\x00\x04"
-"\x21\x21\xD1\x00\xA3\xA4\x46\x25\x00\x00\x0A"
-"\x22\x22\x0F\x00\xF6\xF6\x95\x36\x00\x00\x0A"
-"\xE1\xE1\x00\x00\x44\x54\x24\x34\x02\x02\x07"
-"\xA5\xB1\xD2\x80\x81\xF1\x03\x05\x00\x00\x02"
-"\x71\x22\xC5\x00\x6E\x8B\x17\x0E\x00\x00\x02"
-"\x32\x21\x16\x80\x73\x75\x24\x57\x00\x00\x0E";
-
-
-CPlayer *CcmfPlayer::factory(Copl *newopl)
-{
- return new CcmfPlayer(newopl);
-}
-
-CcmfPlayer::CcmfPlayer(Copl *newopl) :
- CPlayer(newopl),
- data(NULL),
- pInstruments(NULL),
- bPercussive(false),
- iTranspose(0),
- iPrevCommand(0)
-{
- assert(OPLOFFSET(1-1) == 0x00);
- assert(OPLOFFSET(5-1) == 0x09);
- assert(OPLOFFSET(9-1) == 0x12);
-}
-
-CcmfPlayer::~CcmfPlayer()
-{
- if (this->data) delete[] data;
- if (this->pInstruments) delete[] pInstruments;
-}
-
-bool CcmfPlayer::load(VFSFile * fd, const CFileProvider &fp)
-{
- binistream *f = fp.open(fd);
- if(!f) return false;
-
- char cSig[4];
- f->readString(cSig, 4);
- if (
- (cSig[0] != 'C') ||
- (cSig[1] != 'T') ||
- (cSig[2] != 'M') ||
- (cSig[3] != 'F')
- ) {
- // Not a CMF file
- fp.close(f);
- return false;
- }
- uint16_t iVer = f->readInt(2);
- if ((iVer != 0x0101) && (iVer != 0x0100)) {
- AdPlug_LogWrite("CMF file is not v1.0 or v1.1 (reports %d.%d)\n", iVer >> 8 , iVer & 0xFF);
- fp.close(f);
- return false;
- }
-
- this->cmfHeader.iInstrumentBlockOffset = f->readInt(2);
- this->cmfHeader.iMusicOffset = f->readInt(2);
- this->cmfHeader.iTicksPerQuarterNote = f->readInt(2);
- this->cmfHeader.iTicksPerSecond = f->readInt(2);
- this->cmfHeader.iTagOffsetTitle = f->readInt(2);
- this->cmfHeader.iTagOffsetComposer = f->readInt(2);
- this->cmfHeader.iTagOffsetRemarks = f->readInt(2);
- f->readString((char *)this->cmfHeader.iChannelsInUse, 16);
- if (iVer == 0x0100) {
- this->cmfHeader.iNumInstruments = f->readInt(1);
- this->cmfHeader.iTempo = 0;
- } else { // 0x0101
- this->cmfHeader.iNumInstruments = f->readInt(2);
- this->cmfHeader.iTempo = f->readInt(2);
- }
-
- // Load the instruments
-
- f->seek(this->cmfHeader.iInstrumentBlockOffset);
- this->pInstruments = new SBI[
- (this->cmfHeader.iNumInstruments < 128) ? 128 : this->cmfHeader.iNumInstruments
- ]; // Always at least 128 available for use
-
- for (int i = 0; i < this->cmfHeader.iNumInstruments; i++) {
- this->pInstruments[i].op[0].iCharMult = f->readInt(1);
- this->pInstruments[i].op[1].iCharMult = f->readInt(1);
- this->pInstruments[i].op[0].iScalingOutput = f->readInt(1);
- this->pInstruments[i].op[1].iScalingOutput = f->readInt(1);
- this->pInstruments[i].op[0].iAttackDecay = f->readInt(1);
- this->pInstruments[i].op[1].iAttackDecay = f->readInt(1);
- this->pInstruments[i].op[0].iSustainRelease = f->readInt(1);
- this->pInstruments[i].op[1].iSustainRelease = f->readInt(1);
- this->pInstruments[i].op[0].iWaveSel = f->readInt(1);
- this->pInstruments[i].op[1].iWaveSel = f->readInt(1);
- this->pInstruments[i].iConnection = f->readInt(1);
- f->seek(5, binio::Add); // skip over the padding bytes
- }
-
- // Set the rest of the instruments to the CMF defaults
- for (int i = this->cmfHeader.iNumInstruments; i < 128; i++) {
- this->pInstruments[i].op[0].iCharMult = cDefaultPatches[(i % 16) * 11 + 0];
- this->pInstruments[i].op[1].iCharMult = cDefaultPatches[(i % 16) * 11 + 1];
- this->pInstruments[i].op[0].iScalingOutput = cDefaultPatches[(i % 16) * 11 + 2];
- this->pInstruments[i].op[1].iScalingOutput = cDefaultPatches[(i % 16) * 11 + 3];
- this->pInstruments[i].op[0].iAttackDecay = cDefaultPatches[(i % 16) * 11 + 4];
- this->pInstruments[i].op[1].iAttackDecay = cDefaultPatches[(i % 16) * 11 + 5];
- this->pInstruments[i].op[0].iSustainRelease = cDefaultPatches[(i % 16) * 11 + 6];
- this->pInstruments[i].op[1].iSustainRelease = cDefaultPatches[(i % 16) * 11 + 7];
- this->pInstruments[i].op[0].iWaveSel = cDefaultPatches[(i % 16) * 11 + 8];
- this->pInstruments[i].op[1].iWaveSel = cDefaultPatches[(i % 16) * 11 + 9];
- this->pInstruments[i].iConnection = cDefaultPatches[(i % 16) * 11 + 10];
- }
-
- if (this->cmfHeader.iTagOffsetTitle) {
- f->seek(this->cmfHeader.iTagOffsetTitle);
- this->strTitle = f->readString('\0');
- }
- if (this->cmfHeader.iTagOffsetComposer) {
- f->seek(this->cmfHeader.iTagOffsetComposer);
- this->strComposer = f->readString('\0');
- }
- if (this->cmfHeader.iTagOffsetRemarks) {
- f->seek(this->cmfHeader.iTagOffsetRemarks);
- this->strRemarks = f->readString('\0');
- }
-
- // Load the MIDI data into memory
- f->seek(this->cmfHeader.iMusicOffset);
- this->iSongLen = fp.filesize(f) - this->cmfHeader.iMusicOffset;
- this->data = new unsigned char[this->iSongLen];
- f->readString((char *)data, this->iSongLen);
-
- fp.close(f);
- rewind(0);
-
- return true;
-}
-
-bool CcmfPlayer::update()
-{
- // This has to be here and not in getrefresh() for some reason.
- this->iDelayRemaining = 0;
-
- // Read in the next event
- while (!this->iDelayRemaining) {
- uint8_t iCommand = this->data[this->iPlayPointer++];
- if ((iCommand & 0x80) == 0) {
- // Running status, use previous command
- this->iPlayPointer--;
- iCommand = this->iPrevCommand;
- } else {
- this->iPrevCommand = iCommand;
- }
- uint8_t iChannel = iCommand & 0x0F;
- switch (iCommand & 0xF0) {
- case 0x80: { // Note off (two data bytes)
- uint8_t iNote = this->data[this->iPlayPointer++];
- uint8_t iVelocity = this->data[this->iPlayPointer++]; // release velocity
- this->cmfNoteOff(iChannel, iNote, iVelocity);
- break;
- }
- case 0x90: { // Note on (two data bytes)
- uint8_t iNote = this->data[this->iPlayPointer++];
- uint8_t iVelocity = this->data[this->iPlayPointer++]; // attack velocity
- if (iVelocity) {
- this->cmfNoteOn(iChannel, iNote, iVelocity);
- } else {
- // This is a note-off instead (velocity == 0)
- this->cmfNoteOff(iChannel, iNote, iVelocity); // 64 is the MIDI default note-off velocity
- break;
- }
- break;
- }
- case 0xA0: { // Polyphonic key pressure (two data bytes)
- uint8_t iNote = this->data[this->iPlayPointer++];
- uint8_t iPressure = this->data[this->iPlayPointer++];
- AdPlug_LogWrite("CMF: Key pressure not yet implemented! (wanted ch%d/note %d set to %d)\n", iChannel, iNote, iPressure);
- break;
- }
- case 0xB0: { // Controller (two data bytes)
- uint8_t iController = this->data[this->iPlayPointer++];
- uint8_t iValue = this->data[this->iPlayPointer++];
- this->MIDIcontroller(iChannel, iController, iValue);
- break;
- }
- case 0xC0: { // Instrument change (one data byte)
- uint8_t iNewInstrument = this->data[this->iPlayPointer++];
- this->chMIDI[iChannel].iPatch = iNewInstrument;
- AdPlug_LogWrite("CMF: Remembering MIDI channel %d now uses patch %d\n", iChannel, iNewInstrument);
- break;
- }
- case 0xD0: { // Channel pressure (one data byte)
- uint8_t iPressure = this->data[this->iPlayPointer++];
- AdPlug_LogWrite("CMF: Channel pressure not yet implemented! (wanted ch%d set to %d)\n", iChannel, iPressure);
- break;
- }
- case 0xE0: { // Pitch bend (two data bytes)
- uint8_t iLSB = this->data[this->iPlayPointer++];
- uint8_t iMSB = this->data[this->iPlayPointer++];
- uint16_t iValue = (iMSB << 7) | iLSB;
- // 8192 is middle/off, 0 is -2 semitones, 16384 is +2 semitones
- this->chMIDI[iChannel].iPitchbend = iValue;
- AdPlug_LogWrite("CMF: Channel %d pitchbent to %d (%+.2f)\n", iChannel + 1, iValue, (float)(iValue - 8192) / 8192);
- break;
- }
- case 0xF0: // System message (arbitrary data bytes)
- switch (iCommand) {
- case 0xF0: { // Sysex
- uint8_t iNextByte;
- AdPlug_LogWrite("Sysex message: ");
- do {
- iNextByte = this->data[this->iPlayPointer++];
- AdPlug_LogWrite("%02X", iNextByte);
- } while ((iNextByte & 0x80) == 0);
- AdPlug_LogWrite("\n");
- // This will have read in the terminating EOX (0xF7) message too
- break;
- }
- case 0xF1: // MIDI Time Code Quarter Frame
- this->iPlayPointer++; // message data (ignored)
- break;
- case 0xF2: // Song position pointer
- this->iPlayPointer++; // message data (ignored)
- this->iPlayPointer++;
- break;
- case 0xF3: // Song select
- this->iPlayPointer++; // message data (ignored)
- AdPlug_LogWrite("CMF: MIDI Song Select is not implemented.\n");
- break;
- case 0xF6: // Tune request
- break;
- case 0xF7: // End of System Exclusive (EOX) - should never be read, should be absorbed by Sysex handling code
- break;
-
- // These messages are "real time", meaning they can be sent between
- // the bytes of other messages - but we're lazy and don't handle these
- // here (hopefully they're not necessary in a MIDI file, and even less
- // likely to occur in a CMF.)
- case 0xF8: // Timing clock (sent 24 times per quarter note, only when playing)
- case 0xFA: // Start
- case 0xFB: // Continue
- case 0xFE: // Active sensing (sent every 300ms or MIDI connection assumed lost)
- break;
- case 0xFC: // Stop
- AdPlug_LogWrite("CMF: Received Real Time Stop message (0xFC)\n");
- this->bSongEnd = true;
- this->iPlayPointer = 0; // for repeat in endless-play mode
- break;
- case 0xFF: { // System reset, used as meta-events in a MIDI file
- uint8_t iEvent = this->data[this->iPlayPointer++];
- switch (iEvent) {
- case 0x2F: // end of track
- AdPlug_LogWrite("CMF: End-of-track, stopping playback\n");
- this->bSongEnd = true;
- this->iPlayPointer = 0; // for repeat in endless-play mode
- break;
- default:
- AdPlug_LogWrite("CMF: Unknown MIDI meta-event 0xFF 0x%02X\n", iEvent);
- break;
- }
- break;
- }
- default:
- AdPlug_LogWrite("CMF: Unknown MIDI system command 0x%02X\n", iCommand);
- break;
- }
- break;
- default:
- AdPlug_LogWrite("CMF: Unknown MIDI command 0x%02X\n", iCommand);
- break;
- }
-
- if (this->iPlayPointer >= this->iSongLen) {
- this->bSongEnd = true;
- this->iPlayPointer = 0; // for repeat in endless-play mode
- }
-
- // Read in the number of ticks until the next event
- this->iDelayRemaining = this->readMIDINumber();
- }
-
- return !this->bSongEnd;
-}
-
-void CcmfPlayer::rewind(int subsong)
-{
- this->opl->init();
-
- // Initialise
-
- // Enable use of WaveSel register on OPL3 (even though we're only an OPL2!)
- // Apparently this enables nine-channel mode?
- this->writeOPL(0x01, 0x20);
-
- // Disable OPL3 mode (can be left enabled by a previous non-CMF song)
- this->writeOPL(0x05, 0x00);
-
- // Really make sure CSM+SEL are off (again, Creative's player...)
- this->writeOPL(0x08, 0x00);
-
- // This freq setting is required for the hihat to sound correct at the start
- // of funky.cmf, even though it's for an unrelated channel.
- // If it's here however, it makes the hihat in Word Rescue's theme.cmf
- // sound really bad.
- // TODO: How do we figure out whether we need it or not???
- this->writeOPL(BASE_FNUM_L + 8, 514 & 0xFF);
- this->writeOPL(BASE_KEYON_FREQ + 8, (1 << 2) | (514 >> 8));
-
- // default freqs?
- this->writeOPL(BASE_FNUM_L + 7, 509 & 0xFF);
- this->writeOPL(BASE_KEYON_FREQ + 7, (2 << 2) | (509 >> 8));
- this->writeOPL(BASE_FNUM_L + 6, 432 & 0xFF);
- this->writeOPL(BASE_KEYON_FREQ + 6, (2 << 2) | (432 >> 8));
-
- // Amplify AM + VIB depth. Creative's CMF player does this, and there
- // doesn't seem to be any way to stop it from doing so - except for the
- // non-standard controller 0x63 I added :-)
- this->writeOPL(0xBD, 0xC0);
-
- this->bSongEnd = false;
- this->iPlayPointer = 0;
- this->iPrevCommand = 0; // just in case
-
- // Read in the number of ticks until the first event
- this->iDelayRemaining = this->readMIDINumber();
-
- // Reset song state. This used to be in the constructor, but the XMMS2
- // plugin sets the song length before starting playback. AdPlug plays the
- // song in its entirety (with no synth) to determine the song length, which
- // results in the state variables below matching the end of the song. When
- // the real OPL synth is activated for playback, it no longer matches the
- // state variables and the instruments are not set correctly!
- for (int i = 0; i < 9; i++) {
- this->chOPL[i].iNoteStart = 0; // no note playing atm
- this->chOPL[i].iMIDINote = -1;
- this->chOPL[i].iMIDIChannel = -1;
- this->chOPL[i].iMIDIPatch = -1;
-
- this->chMIDI[i].iPatch = -2;
- this->chMIDI[i].iPitchbend = 8192;
- }
- for (int i = 9; i < 16; i++) {
- this->chMIDI[i].iPatch = -2;
- this->chMIDI[i].iPitchbend = 8192;
- }
-
- memset(this->iCurrentRegs, 0, 256);
-
- return;
-}
-
-// Return value: 1 == 1 second, 2 == 0.5 seconds
-float CcmfPlayer::getrefresh()
-{
- if (this->iDelayRemaining) {
- return (float)this->cmfHeader.iTicksPerSecond / (float)this->iDelayRemaining;
- } else {
- // Delay-remaining is zero (e.g. start of song) so use a tiny delay
- return this->cmfHeader.iTicksPerSecond; // wait for one tick
- }
-}
-
-std::string CcmfPlayer::gettitle()
-{
- return this->strTitle;
-}
-std::string CcmfPlayer::getauthor()
-{
- return this->strComposer;
-}
-std::string CcmfPlayer::getdesc()
-{
- return this->strRemarks;
-}
-
-
-//
-// PROTECTED
-//
-
-// Read a variable-length integer from MIDI data
-uint32_t CcmfPlayer::readMIDINumber()
-{
- uint32_t iValue = 0;
- for (int i = 0; i < 4; i++) {
- uint8_t iNext = this->data[this->iPlayPointer++];
- iValue <<= 7;
- iValue |= (iNext & 0x7F); // ignore the MSB
- if ((iNext & 0x80) == 0) break; // last byte has the MSB unset
- }
- return iValue;
-}
-
-// iChannel: OPL channel (0-8)
-// iOperator: 0 == Modulator, 1 == Carrier
-// Source - source operator to read from instrument definition
-// Dest - destination operator on OPL chip
-// iInstrument: Index into this->pInstruments array of CMF instruments
-void CcmfPlayer::writeInstrumentSettings(uint8_t iChannel, uint8_t iOperatorSource, uint8_t iOperatorDest, uint8_t iInstrument)
-{
- assert(iChannel <= 8);
-
- uint8_t iOPLOffset = OPLOFFSET(iChannel);
- if (iOperatorDest) iOPLOffset += 3; // Carrier if iOperator == 1 (else Modulator)
-
- this->writeOPL(BASE_CHAR_MULT + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iCharMult);
- this->writeOPL(BASE_SCAL_LEVL + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iScalingOutput);
- this->writeOPL(BASE_ATCK_DCAY + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iAttackDecay);
- this->writeOPL(BASE_SUST_RLSE + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iSustainRelease);
- this->writeOPL(BASE_WAVE + iOPLOffset, this->pInstruments[iInstrument].op[iOperatorSource].iWaveSel);
-
- // TODO: Check to see whether we should only be loading this for one or both operators
- this->writeOPL(BASE_FEED_CONN + iChannel, this->pInstruments[iInstrument].iConnection);
- return;
-}
-
-// Write a byte to the OPL "chip" and update the current record of register states
-void CcmfPlayer::writeOPL(uint8_t iRegister, uint8_t iValue)
-{
- this->opl->write(iRegister, iValue);
- this->iCurrentRegs[iRegister] = iValue;
- return;
-}
-
-void CcmfPlayer::cmfNoteOn(uint8_t iChannel, uint8_t iNote, uint8_t iVelocity)
-{
- uint8_t iBlock = iNote / 12;
- if (iBlock > 1) iBlock--; // keep in the same range as the Creative player
- //if (iBlock > 7) iBlock = 7; // don't want to go out of range
-
- double d = pow(2, (
- (double)iNote + (
- (this->chMIDI[iChannel].iPitchbend - 8192) / 8192.0
- ) + (
- this->iTranspose / 128
- ) - 9) / 12.0 - (iBlock - 20))
- * 440.0 / 32.0 / 50000.0;
- uint16_t iOPLFNum = (uint16_t)(d+0.5);
- if (iOPLFNum > 1023) AdPlug_LogWrite("CMF: This note is out of range! (send this song to malvineous at shikadi.net!)\n");
-
- // See if we're playing a rhythm mode percussive instrument
- if ((iChannel > 10) && (this->bPercussive)) {
- uint8_t iPercChannel = this->getPercChannel(iChannel);
-
- // Will have to set every time (easier) than figuring out whether the mod
- // or car needs to be changed.
- //if (this->chOPL[iPercChannel].iMIDIPatch != this->chMIDI[iChannel].iPatch) {
- this->MIDIchangeInstrument(iPercChannel, iChannel, this->chMIDI[iChannel].iPatch);
- //}
-
- /* Velocity calculations - TODO: Work out the proper formula
-
- iVelocity -> iLevel (values generated by Creative's player)
- 7f -> 00
- 7c -> 00
-
- 7b -> 09
- 73 -> 0a
- 6b -> 0b
- 63 -> 0c
- 5b -> 0d
- 53 -> 0e
- 4b -> 0f
- 43 -> 10
- 3b -> 11
- 33 -> 13
- 2b -> 15
- 23 -> 19
- 1b -> 1b
- 13 -> 1d
- 0b -> 1f
- 03 -> 21
-
- 02 -> 21
- 00 -> N/A (note off)
- */
- // Approximate formula, need to figure out more accurate one (my maths isn't so good...)
- int iLevel = 0x25 - (int) sqrt(iVelocity * 16 /* 6 */); // (127 - iVelocity) * 0x20 / 127;
- if (iVelocity > 0x7b) iLevel = 0; // full volume
- if (iLevel < 0) iLevel = 0;
- if (iLevel > 0x3F) iLevel = 0x3F;
- //if (iVelocity < 0x40) iLevel = 0x10;
-
- int iOPLOffset = BASE_SCAL_LEVL + OPLOFFSET(iPercChannel);
- //if ((iChannel == 11) || (iChannel == 12) || (iChannel == 14)) {
- if (iChannel == 11) iOPLOffset += 3; // only do bassdrum carrier for volume control
- //iOPLOffset += 3; // carrier
- this->writeOPL(iOPLOffset, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | iLevel);//(iVelocity * 0x3F / 127));
- //}
- // Bass drum (ch11) uses both operators
- //if (iChannel == 11) this->writeOPL(iOPLOffset + 3, (this->iCurrentRegs[iOPLOffset + 3] & ~0x3F) | iLevel);
-
-/* #ifdef USE_VELOCITY // Official CMF player seems to ignore velocity levels
- uint16_t iLevel = 0x2F - (iVelocity * 0x2F / 127); // 0x2F should be 0x3F but it's too quiet then
- AdPlug_LogWrite("%02X + vel %d (lev %02X) == %02X\n", this->iCurrentRegs[iOPLOffset], iVelocity, iLevel, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | iLevel);
- //this->writeOPL(iOPLOffset, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | (0x3F - (iVelocity >> 1)));//(iVelocity * 0x3F / 127));
- this->writeOPL(iOPLOffset, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | iLevel);//(iVelocity * 0x3F / 127));
- #endif*/
-
- // Apparently you can't set the frequency for the cymbal or hihat?
- // Vinyl requires you don't set it, Kiloblaster requires you do!
- this->writeOPL(BASE_FNUM_L + iPercChannel, iOPLFNum & 0xFF);
- this->writeOPL(BASE_KEYON_FREQ + iPercChannel, (iBlock << 2) | ((iOPLFNum >> 8) & 0x03));
-
- uint8_t iBit = 1 << (15 - iChannel);
-
- // Turn the perc instrument off if it's already playing (OPL can't do
- // polyphonic notes w/ percussion)
- if (this->iCurrentRegs[BASE_RHYTHM] & iBit) this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] & ~iBit);
-
- // I wonder whether we need to delay or anything here?
-
- // Turn the note on
- //if (iChannel == 15) {
- this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] | iBit);
- //AdPlug_LogWrite("CMF: Note %d on MIDI channel %d (mapped to OPL channel %d-1) - vel %02X, fnum %d/%d\n", iNote, iChannel, iPercChannel+1, iVelocity, iOPLFNum, iBlock);
- //}
-
- this->chOPL[iPercChannel].iNoteStart = ++this->iNoteCount;
- this->chOPL[iPercChannel].iMIDIChannel = iChannel;
- this->chOPL[iPercChannel].iMIDINote = iNote;
-
- } else { // Non rhythm-mode or a normal instrument channel
-
- // Figure out which OPL channel to play this note on
- int iOPLChannel = -1;
- int iNumChannels = this->bPercussive ? 6 : 9;
- for (int i = iNumChannels - 1; i >= 0; i--) {
- // If there's no note playing on this OPL channel, use that
- if (this->chOPL[i].iNoteStart == 0) {
- iOPLChannel = i;
- // See if this channel is already set to the instrument we want.
- if (this->chOPL[i].iMIDIPatch == this->chMIDI[iChannel].iPatch) {
- // It is, so stop searching
- break;
- } // else keep searching just in case there's a better match
- }
- }
- if (iOPLChannel == -1) {
- // All channels were in use, find the one with the longest note
- iOPLChannel = 0;
- int iEarliest = this->chOPL[0].iNoteStart;
- for (int i = 1; i < iNumChannels; i++) {
- if (this->chOPL[i].iNoteStart < iEarliest) {
- // Found a channel with a note being played for longer
- iOPLChannel = i;
- iEarliest = this->chOPL[i].iNoteStart;
- }
- }
- AdPlug_LogWrite("CMF: Too many polyphonic notes, cutting note on channel %d\n", iOPLChannel);
- }
-
- // Run through all the channels with negative notestart values - these
- // channels have had notes recently stop - and increment the counter
- // to slowly move the channel closer to being reused for a future note.
- //for (int i = 0; i < iNumChannels; i++) {
- // if (this->chOPL[i].iNoteStart < 0) this->chOPL[i].iNoteStart++;
- //}
-
- // Now the new note should be played on iOPLChannel, but see if the instrument
- // is right first.
- if (this->chOPL[iOPLChannel].iMIDIPatch != this->chMIDI[iChannel].iPatch) {
- this->MIDIchangeInstrument(iOPLChannel, iChannel, this->chMIDI[iChannel].iPatch);
- }
-
- this->chOPL[iOPLChannel].iNoteStart = ++this->iNoteCount;
- this->chOPL[iOPLChannel].iMIDIChannel = iChannel;
- this->chOPL[iOPLChannel].iMIDINote = iNote;
-
- #ifdef USE_VELOCITY // Official CMF player seems to ignore velocity levels
- // Adjust the channel volume to match the note velocity
- uint8_t iOPLOffset = BASE_SCAL_LEVL + OPLOFFSET(iChannel) + 3; // +3 == Carrier
- uint16_t iLevel = 0x2F - (iVelocity * 0x2F / 127); // 0x2F should be 0x3F but it's too quiet then
- this->writeOPL(iOPLOffset, (this->iCurrentRegs[iOPLOffset] & ~0x3F) | iLevel);
- #endif
-
- // Set the frequency and play the note
- this->writeOPL(BASE_FNUM_L + iOPLChannel, iOPLFNum & 0xFF);
- this->writeOPL(BASE_KEYON_FREQ + iOPLChannel, OPLBIT_KEYON | (iBlock << 2) | ((iOPLFNum & 0x300) >> 8));
- }
- return;
-}
-
-void CcmfPlayer::cmfNoteOff(uint8_t iChannel, uint8_t iNote, uint8_t iVelocity)
-{
- if ((iChannel > 10) && (this->bPercussive)) {
- int iOPLChannel = this->getPercChannel(iChannel);
- if (this->chOPL[iOPLChannel].iMIDINote != iNote) return; // there's a different note playing now
- this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] & ~(1 << (15 - iChannel)));
- this->chOPL[iOPLChannel].iNoteStart = 0; // channel free
- } else { // Non rhythm-mode or a normal instrument channel
- int iOPLChannel = -1;
- int iNumChannels = this->bPercussive ? 6 : 9;
- for (int i = 0; i < iNumChannels; i++) {
- if (
- (this->chOPL[i].iMIDIChannel == iChannel) &&
- (this->chOPL[i].iMIDINote == iNote) &&
- (this->chOPL[i].iNoteStart != 0)
- ) {
- // Found the note, switch it off
- this->chOPL[i].iNoteStart = 0;
- iOPLChannel = i;
- break;
- }
- }
- if (iOPLChannel == -1) return;
-
- this->writeOPL(BASE_KEYON_FREQ + iOPLChannel, this->iCurrentRegs[BASE_KEYON_FREQ + iOPLChannel] & ~OPLBIT_KEYON);
- }
- return;
-}
-
-uint8_t CcmfPlayer::getPercChannel(uint8_t iChannel)
-{
- switch (iChannel) {
- case 11: return 7-1; // Bass drum
- case 12: return 8-1; // Snare drum
- case 13: return 9-1; // Tom tom
- case 14: return 9-1; // Top cymbal
- case 15: return 8-1; // Hihat
- }
- AdPlug_LogWrite("CMF ERR: Tried to get the percussion channel from MIDI channel %d - this shouldn't happen!\n", iChannel);
- return 0;
-}
-
-
-void CcmfPlayer::MIDIchangeInstrument(uint8_t iOPLChannel, uint8_t iMIDIChannel, uint8_t iNewInstrument)
-{
- if ((iMIDIChannel > 10) && (this->bPercussive)) {
- switch (iMIDIChannel) {
- case 11: // Bass drum (operator 13+16 == channel 7 modulator+carrier)
- this->writeInstrumentSettings(7-1, 0, 0, iNewInstrument);
- this->writeInstrumentSettings(7-1, 1, 1, iNewInstrument);
- break;
- case 12: // Snare drum (operator 17 == channel 8 carrier)
- //case 15:
- this->writeInstrumentSettings(8-1, 0, 1, iNewInstrument);
-
- //
- //this->writeInstrumentSettings(8-1, 0, 0, iNewInstrument);
- break;
- case 13: // Tom tom (operator 15 == channel 9 modulator)
- //case 14:
- this->writeInstrumentSettings(9-1, 0, 0, iNewInstrument);
-
- //
- //this->writeInstrumentSettings(9-1, 0, 1, iNewInstrument);
- break;
- case 14: // Top cymbal (operator 18 == channel 9 carrier)
- this->writeInstrumentSettings(9-1, 0, 1, iNewInstrument);
- break;
- case 15: // Hi-hat (operator 14 == channel 8 modulator)
- this->writeInstrumentSettings(8-1, 0, 0, iNewInstrument);
- break;
- default:
- AdPlug_LogWrite("CMF: Invalid MIDI channel %d (not melodic and not percussive!)\n", iMIDIChannel + 1);
- break;
- }
- this->chOPL[iOPLChannel].iMIDIPatch = iNewInstrument;
- } else {
- // Standard nine OPL channels
- this->writeInstrumentSettings(iOPLChannel, 0, 0, iNewInstrument);
- this->writeInstrumentSettings(iOPLChannel, 1, 1, iNewInstrument);
- this->chOPL[iOPLChannel].iMIDIPatch = iNewInstrument;
- }
- return;
-}
-
-void CcmfPlayer::MIDIcontroller(uint8_t iChannel, uint8_t iController, uint8_t iValue)
-{
- switch (iController) {
- case 0x63:
- // Custom extension to allow CMF files to switch the AM+VIB depth on and
- // off (officially both are on, and there's no way to switch them off.)
- // Controller values:
- // 0 == AM+VIB off
- // 1 == VIB on
- // 2 == AM on
- // 3 == AM+VIB on
- if (iValue) {
- this->writeOPL(BASE_RHYTHM, (this->iCurrentRegs[BASE_RHYTHM] & ~0xC0) | (iValue << 6)); // switch AM+VIB extension on
- } else {
- this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] & ~0xC0); // switch AM+VIB extension off
- }
- AdPlug_LogWrite("CMF: AM+VIB depth change - AM %s, VIB %s\n",
- (this->iCurrentRegs[BASE_RHYTHM] & 0x80) ? "on" : "off",
- (this->iCurrentRegs[BASE_RHYTHM] & 0x40) ? "on" : "off");
- break;
- case 0x66:
- AdPlug_LogWrite("CMF: Song set marker to 0x%02X\n", iValue);
- break;
- case 0x67:
- this->bPercussive = (iValue != 0);
- if (this->bPercussive) {
- this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] | 0x20); // switch rhythm-mode on
- } else {
- this->writeOPL(BASE_RHYTHM, this->iCurrentRegs[BASE_RHYTHM] & ~0x20); // switch rhythm-mode off
- }
- AdPlug_LogWrite("CMF: Percussive/rhythm mode %s\n", this->bPercussive ? "enabled" : "disabled");
- break;
- case 0x68:
- // TODO: Shouldn't this just affect the one channel, not the whole song? -- have pitchbends for that
- this->iTranspose = iValue;
- AdPlug_LogWrite("CMF: Transposing all notes up by %d * 1/128ths of a semitone.\n", iValue);
- break;
- case 0x69:
- this->iTranspose = -iValue;
- AdPlug_LogWrite("CMF: Transposing all notes down by %d * 1/128ths of a semitone.\n", iValue);
- break;
- default:
- AdPlug_LogWrite("CMF: Unsupported MIDI controller 0x%02X, ignoring.\n", iController);
- break;
- }
- return;
-}
diff --git a/src/adplug/core/cmf.h b/src/adplug/core/cmf.h
index 26e69f17447b..3e9bb0a28169 100644
--- a/src/adplug/core/cmf.h
+++ b/src/adplug/core/cmf.h
@@ -14,7 +14,7 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* cmf.h - CMF player by Adam Nielsen <malvineous at shikadi.net>
*/
@@ -88,7 +88,7 @@ class CcmfPlayer: public CPlayer
CcmfPlayer(Copl *newopl);
~CcmfPlayer();
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
diff --git a/src/adplug/core/d00.cc b/src/adplug/core/d00.cc
new file mode 100644
index 000000000000..0b53ea04aeb8
--- /dev/null
+++ b/src/adplug/core/d00.cc
@@ -0,0 +1,653 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * d00.c - D00 Player by Simon Peter <dn.tlp at gmx.net>
+ *
+ * NOTES:
+ * Sorry for the goto's, but the code looks so much nicer now.
+ * I tried it with while loops but it was just a mess. If you
+ * can come up with a nicer solution, just tell me.
+ *
+ * BUGS:
+ * Hard restart SR is sometimes wrong
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "debug.h"
+#include "d00.h"
+
+#define HIBYTE(val) (val >> 8)
+#define LOBYTE(val) (val & 0xff)
+
+static const unsigned short notetable[12] = // D00 note table
+{ 340, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647 };
+
+static inline uint16_t
+LE_WORD (const uint16_t * val)
+{
+ const uint8_t *b = (const uint8_t *) val;
+ return (b[1] << 8) + b[0];
+}
+
+/*** public methods *************************************/
+
+CPlayer *
+Cd00Player::factory (Copl * newopl)
+{
+ return new Cd00Player (newopl);
+}
+
+bool
+Cd00Player::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ d00header *checkhead;
+ d00header1 *ch;
+ unsigned long filesize;
+ int i, ver1 = 0;
+ char *str;
+ std::string filename (fd.filename ());
+
+ // file validation section
+ checkhead = new d00header;
+ f->readString ((char *) checkhead, sizeof (d00header));
+
+ // Check for version 2-4 header
+ if (strncmp (checkhead->id, "JCH\x26\x02\x66", 6) || checkhead->type ||
+ !checkhead->subsongs || checkhead->soundcard)
+ {
+ // Check for version 0 or 1 header (and .d00 file extension)
+ delete checkhead;
+ if (!fp.extension (filename, ".d00"))
+ {
+ fp.close (f);
+ return false;
+ }
+ ch = new d00header1;
+ f->seek (0);
+ f->readString ((char *) ch, sizeof (d00header1));
+ if (ch->version > 1 || !ch->subsongs)
+ {
+ delete ch;
+ fp.close (f);
+ return false;
+ }
+ delete ch;
+ ver1 = 1;
+ }
+ else
+ delete checkhead;
+
+ AdPlug_LogWrite
+ ("Cd00Player::load(f,\"%s\"): %s format D00 file detected!\n",
+ filename.c_str (), ver1 ? "Old" : "New");
+
+ // load section
+ filesize = fp.filesize (f);
+ f->seek (0);
+ filedata = new char[filesize + 1]; // 1 byte is needed for old-style DataInfo block
+ f->readString ((char *) filedata, filesize);
+ fp.close (f);
+ if (!ver1)
+ { // version 2 and above
+ header = (struct d00header *) filedata;
+ version = header->version;
+ datainfo = (char *) filedata + LE_WORD (&header->infoptr);
+ inst = (struct Sinsts *) ((char *) filedata + LE_WORD (&header->instptr));
+ seqptr =
+ (unsigned short *) ((char *) filedata + LE_WORD (&header->seqptr));
+ for (i = 31; i >= 0; i--) // erase whitespace
+ if (header->songname[i] == ' ')
+ header->songname[i] = '\0';
+ else
+ break;
+ for (i = 31; i >= 0; i--)
+ if (header->author[i] == ' ')
+ header->author[i] = '\0';
+ else
+ break;
+ }
+ else
+ { // version 1
+ header1 = (struct d00header1 *) filedata;
+ version = header1->version;
+ datainfo = (char *) filedata + LE_WORD (&header1->infoptr);
+ inst =
+ (struct Sinsts *) ((char *) filedata + LE_WORD (&header1->instptr));
+ seqptr =
+ (unsigned short *) ((char *) filedata + LE_WORD (&header1->seqptr));
+ }
+ switch (version)
+ {
+ case 0:
+ levpuls = 0;
+ spfx = 0;
+ header1->speed = 70; // v0 files default to 70Hz
+ break;
+ case 1:
+ levpuls =
+ (struct Slevpuls *) ((char *) filedata + LE_WORD (&header1->lpulptr));
+ spfx = 0;
+ break;
+ case 2:
+ levpuls =
+ (struct Slevpuls *) ((char *) filedata + LE_WORD (&header->spfxptr));
+ spfx = 0;
+ break;
+ case 3:
+ spfx = 0;
+ levpuls = 0;
+ break;
+ case 4:
+ spfx = (struct Sspfx *) ((char *) filedata + LE_WORD (&header->spfxptr));
+ levpuls = 0;
+ break;
+ }
+ if ((str = strstr (datainfo, "\xff\xff")))
+ while ((*str == '\xff' || *str == ' ') && str >= datainfo)
+ {
+ *str = '\0';
+ str--;
+ }
+ else // old-style block
+ memset ((char *) filedata + filesize, 0, 1);
+
+ rewind (0);
+ return true;
+}
+
+bool
+Cd00Player::update ()
+{
+ unsigned char c, cnt, trackend = 0, fx, note;
+ unsigned short ord, *patt, buf, fxop, pattpos;
+
+ // effect handling (timer dependant)
+ for (c = 0; c < 9; c++)
+ {
+ channel[c].slideval += channel[c].slide;
+ setfreq (c); // sliding
+ vibrato (c); // vibrato
+
+ if (channel[c].spfx != 0xffff)
+ { // SpFX
+ if (channel[c].fxdel)
+ channel[c].fxdel--;
+ else
+ {
+ channel[c].spfx = LE_WORD (&spfx[channel[c].spfx].ptr);
+ channel[c].fxdel = spfx[channel[c].spfx].duration;
+ channel[c].inst = LE_WORD (&spfx[channel[c].spfx].instnr) & 0xfff;
+ if (spfx[channel[c].spfx].modlev != 0xff)
+ channel[c].modvol = spfx[channel[c].spfx].modlev;
+ setinst (c);
+ if (LE_WORD (&spfx[channel[c].spfx].instnr) & 0x8000) // locked frequency
+ note = spfx[channel[c].spfx].halfnote;
+ else // unlocked frequency
+ note = spfx[channel[c].spfx].halfnote + channel[c].note;
+ channel[c].freq = notetable[note % 12] + ((note / 12) << 10);
+ setfreq (c);
+ }
+ channel[c].modvol += spfx[channel[c].spfx].modlevadd;
+ channel[c].modvol &= 63;
+ setvolume (c);
+ }
+
+ if (channel[c].levpuls != 0xff) // Levelpuls
+ {
+ if (channel[c].frameskip)
+ channel[c].frameskip--;
+ else
+ {
+ channel[c].frameskip = inst[channel[c].inst].timer;
+ if (channel[c].fxdel)
+ channel[c].fxdel--;
+ else
+ {
+ channel[c].levpuls = levpuls[channel[c].levpuls].ptr - 1;
+ channel[c].fxdel = levpuls[channel[c].levpuls].duration;
+ if (levpuls[channel[c].levpuls].level != 0xff)
+ channel[c].modvol = levpuls[channel[c].levpuls].level;
+ }
+ channel[c].modvol += levpuls[channel[c].levpuls].voladd;
+ channel[c].modvol &= 63;
+ setvolume (c);
+ }
+ }
+ }
+
+ // song handling
+ for (c = 0; c < 9; c++)
+ if (version < 3 ? channel[c].del : channel[c].del <= 0x7f)
+ {
+ if (version == 4) // v4: hard restart SR
+ if (channel[c].del == inst[channel[c].inst].timer)
+ if (channel[c].nextnote)
+ opl->write (0x83 + op_table[c], inst[channel[c].inst].sr);
+ if (version < 3)
+ channel[c].del--;
+ else if (channel[c].speed)
+ channel[c].del += channel[c].speed;
+ else
+ {
+ channel[c].seqend = 1;
+ continue;
+ }
+ }
+ else
+ {
+ if (channel[c].speed)
+ {
+ if (version < 3)
+ channel[c].del = channel[c].speed;
+ else
+ {
+ channel[c].del &= 0x7f;
+ channel[c].del += channel[c].speed;
+ }
+ }
+ else
+ {
+ channel[c].seqend = 1;
+ continue;
+ }
+ if (channel[c].rhcnt)
+ { // process pending REST/HOLD events
+ channel[c].rhcnt--;
+ continue;
+ }
+ readorder: // process arrangement (orderlist)
+ ord = LE_WORD (&channel[c].order[channel[c].ordpos]);
+ switch (ord)
+ {
+ case 0xfffe:
+ channel[c].seqend = 1;
+ continue; // end of arrangement stream
+ case 0xffff: // jump to order
+ channel[c].ordpos =
+ LE_WORD (&channel[c].order[channel[c].ordpos + 1]);
+ channel[c].seqend = 1;
+ goto readorder;
+ default:
+ if (ord >= 0x9000)
+ { // set speed
+ channel[c].speed = ord & 0xff;
+ ord = LE_WORD (&channel[c].order[channel[c].ordpos - 1]);
+ channel[c].ordpos++;
+ }
+ else if (ord >= 0x8000)
+ { // transpose track
+ channel[c].transpose = ord & 0xff;
+ if (ord & 0x100)
+ channel[c].transpose = -channel[c].transpose;
+ ord = LE_WORD (&channel[c].order[++channel[c].ordpos]);
+ }
+ patt =
+ (unsigned short *) ((char *) filedata + LE_WORD (&seqptr[ord]));
+ break;
+ }
+ channel[c].fxflag = 0;
+ readseq: // process sequence (pattern)
+ if (!version) // v0: always initialize rhcnt
+ channel[c].rhcnt = channel[c].irhcnt;
+ pattpos = LE_WORD (&patt[channel[c].pattpos]);
+ if (pattpos == 0xffff)
+ { // pattern ended?
+ channel[c].pattpos = 0;
+ channel[c].ordpos++;
+ goto readorder;
+ }
+ cnt = HIBYTE (pattpos);
+ note = LOBYTE (pattpos);
+ fx = pattpos >> 12;
+ fxop = pattpos & 0x0fff;
+ channel[c].pattpos++;
+ pattpos = LE_WORD (&patt[channel[c].pattpos]);
+ channel[c].nextnote = LOBYTE (pattpos) & 0x7f;
+ if (version ? cnt < 0x40 : !fx)
+ { // note event
+ switch (note)
+ {
+ case 0: // REST event
+ case 0x80:
+ if (!note || version)
+ {
+ channel[c].key = 0;
+ setfreq (c);
+ }
+ // fall through...
+ case 0x7e: // HOLD event
+ if (version)
+ channel[c].rhcnt = cnt;
+ channel[c].nextnote = 0;
+ break;
+ default: // play note
+ // restart fx
+ if (!(channel[c].fxflag & 1))
+ channel[c].vibdepth = 0;
+ if (!(channel[c].fxflag & 2))
+ channel[c].slideval = channel[c].slide = 0;
+
+ if (version)
+ { // note handling for v1 and above
+ if (note > 0x80) // locked note (no channel transpose)
+ note -= 0x80;
+ else // unlocked note
+ note += channel[c].transpose;
+ channel[c].note = note; // remember note for SpFX
+
+ if (channel[c].ispfx != 0xffff && cnt < 0x20)
+ { // reset SpFX
+ channel[c].spfx = channel[c].ispfx;
+ if (LE_WORD (&spfx[channel[c].spfx].instnr) & 0x8000) // locked frequency
+ note = spfx[channel[c].spfx].halfnote;
+ else // unlocked frequency
+ note += spfx[channel[c].spfx].halfnote;
+ channel[c].inst =
+ LE_WORD (&spfx[channel[c].spfx].instnr) & 0xfff;
+ channel[c].fxdel = spfx[channel[c].spfx].duration;
+ if (spfx[channel[c].spfx].modlev != 0xff)
+ channel[c].modvol = spfx[channel[c].spfx].modlev;
+ else
+ channel[c].modvol = inst[channel[c].inst].data[7] & 63;
+ }
+
+ if (channel[c].ilevpuls != 0xff && cnt < 0x20)
+ { // reset LevelPuls
+ channel[c].levpuls = channel[c].ilevpuls;
+ channel[c].fxdel = levpuls[channel[c].levpuls].duration;
+ channel[c].frameskip = inst[channel[c].inst].timer;
+ if (levpuls[channel[c].levpuls].level != 0xff)
+ channel[c].modvol = levpuls[channel[c].levpuls].level;
+ else
+ channel[c].modvol = inst[channel[c].inst].data[7] & 63;
+ }
+
+ channel[c].freq = notetable[note % 12] + ((note / 12) << 10);
+ if (cnt < 0x20) // normal note
+ playnote (c);
+ else
+ { // tienote
+ setfreq (c);
+ cnt -= 0x20; // make count proper
+ }
+ channel[c].rhcnt = cnt;
+ }
+ else
+ { // note handling for v0
+ if (cnt < 2) // unlocked note
+ note += channel[c].transpose;
+ channel[c].note = note;
+
+ channel[c].freq = notetable[note % 12] + ((note / 12) << 10);
+ if (cnt == 1) // tienote
+ setfreq (c);
+ else // normal note
+ playnote (c);
+ }
+ break;
+ }
+ continue; // event is complete
+ }
+ else
+ { // effect event
+ switch (fx)
+ {
+ case 6: // Cut/Stop Voice
+ buf = channel[c].inst;
+ channel[c].inst = 0;
+ playnote (c);
+ channel[c].inst = buf;
+ channel[c].rhcnt = fxop;
+ continue; // no note follows this event
+ case 7: // Vibrato
+ channel[c].vibspeed = fxop & 0xff;
+ channel[c].vibdepth = fxop >> 8;
+ channel[c].trigger = fxop >> 9;
+ channel[c].fxflag |= 1;
+ break;
+ case 8: // v0: Duration
+ if (!version)
+ channel[c].irhcnt = fxop;
+ break;
+ case 9: // New Level
+ channel[c].vol = fxop & 63;
+ if (channel[c].vol + channel[c].cvol < 63) // apply channel volume
+ channel[c].vol += channel[c].cvol;
+ else
+ channel[c].vol = 63;
+ setvolume (c);
+ break;
+ case 0xb: // v4: Set SpFX
+ if (version == 4)
+ channel[c].ispfx = fxop;
+ break;
+ case 0xc: // Set Instrument
+ channel[c].ispfx = 0xffff;
+ channel[c].spfx = 0xffff;
+ channel[c].inst = fxop;
+ channel[c].modvol = inst[fxop].data[7] & 63;
+ if (version < 3 && version && inst[fxop].tunelev) // Set LevelPuls
+ channel[c].ilevpuls = inst[fxop].tunelev - 1;
+ else
+ {
+ channel[c].ilevpuls = 0xff;
+ channel[c].levpuls = 0xff;
+ }
+ break;
+ case 0xd: // Slide up
+ channel[c].slide = fxop;
+ channel[c].fxflag |= 2;
+ break;
+ case 0xe: // Slide down
+ channel[c].slide = -fxop;
+ channel[c].fxflag |= 2;
+ break;
+ }
+ goto readseq; // event is incomplete, note follows
+ }
+ }
+
+ for (c = 0; c < 9; c++)
+ if (channel[c].seqend)
+ trackend++;
+ if (trackend == 9)
+ songend = 1;
+
+ return !songend;
+}
+
+void
+Cd00Player::rewind (int subsong)
+{
+ struct Stpoin
+ {
+ unsigned short ptr[9];
+ unsigned char volume[9], dummy[5];
+ } *tpoin;
+ int i;
+
+ if(subsong == -1) subsong = cursubsong;
+
+ if (version > 1)
+ { // do nothing if subsong > number of subsongs
+ if (subsong >= header->subsongs)
+ return;
+ }
+ else if (subsong >= header1->subsongs)
+ return;
+
+ memset (channel, 0, sizeof (channel));
+ if (version > 1)
+ tpoin = (struct Stpoin *) ((char *) filedata + LE_WORD (&header->tpoin));
+ else
+ tpoin = (struct Stpoin *) ((char *) filedata + LE_WORD (&header1->tpoin));
+ for (i = 0; i < 9; i++)
+ {
+ if (LE_WORD (&tpoin[subsong].ptr[i]))
+ { // track enabled
+ channel[i].speed = LE_WORD ((unsigned short *)
+ ((char *) filedata +
+ LE_WORD (&tpoin[subsong].ptr[i])));
+ channel[i].order =
+ (unsigned short *) ((char *) filedata +
+ LE_WORD (&tpoin[subsong].ptr[i]) + 2);
+ }
+ else
+ { // track disabled
+ channel[i].speed = 0;
+ channel[i].order = 0;
+ }
+ channel[i].ispfx = 0xffff;
+ channel[i].spfx = 0xffff; // no SpFX
+ channel[i].ilevpuls = 0xff;
+ channel[i].levpuls = 0xff; // no LevelPuls
+ channel[i].cvol = tpoin[subsong].volume[i] & 0x7f; // our player may savely ignore bit 7
+ channel[i].vol = channel[i].cvol; // initialize volume
+ }
+ songend = 0;
+ opl->init ();
+ opl->write (1, 32); // reset OPL chip
+ cursubsong = subsong;
+}
+
+std::string Cd00Player::gettype ()
+{
+ char
+ tmpstr[40];
+
+ sprintf (tmpstr, "EdLib packed (version %d)",
+ version > 1 ? header->version : header1->version);
+ return std::string (tmpstr);
+}
+
+float
+Cd00Player::getrefresh ()
+{
+ if (version > 1)
+ return header->speed;
+ else
+ return header1->speed;
+}
+
+unsigned int
+Cd00Player::getsubsongs ()
+{
+ if (version <= 1) // return number of subsongs
+ return header1->subsongs;
+ else
+ return header->subsongs;
+}
+
+/*** private methods *************************************/
+
+void
+Cd00Player::setvolume (unsigned char chan)
+{
+ unsigned char op = op_table[chan];
+ unsigned short insnr = channel[chan].inst;
+
+ opl->write (0x43 + op,
+ (int) (63 -
+ ((63 - (inst[insnr].data[2] & 63)) / 63.0) * (63 -
+ channel
+ [chan].
+ vol)) +
+ (inst[insnr].data[2] & 192));
+ if (inst[insnr].data[10] & 1)
+ opl->write (0x40 + op,
+ (int) (63 -
+ ((63 - channel[chan].modvol) / 63.0) * (63 -
+ channel[chan].
+ vol)) +
+ (inst[insnr].data[7] & 192));
+ else
+ opl->write (0x40 + op,
+ channel[chan].modvol + (inst[insnr].data[7] & 192));
+}
+
+void
+Cd00Player::setfreq (unsigned char chan)
+{
+ unsigned short freq = channel[chan].freq;
+
+ if (version == 4) // v4: apply instrument finetune
+ freq += inst[channel[chan].inst].tunelev;
+
+ freq += channel[chan].slideval;
+ opl->write (0xa0 + chan, freq & 255);
+ if (channel[chan].key)
+ opl->write (0xb0 + chan, ((freq >> 8) & 31) | 32);
+ else
+ opl->write (0xb0 + chan, (freq >> 8) & 31);
+}
+
+void
+Cd00Player::setinst (unsigned char chan)
+{
+ unsigned char op = op_table[chan];
+ unsigned short insnr = channel[chan].inst;
+
+ // set instrument data
+ opl->write (0x63 + op, inst[insnr].data[0]);
+ opl->write (0x83 + op, inst[insnr].data[1]);
+ opl->write (0x23 + op, inst[insnr].data[3]);
+ opl->write (0xe3 + op, inst[insnr].data[4]);
+ opl->write (0x60 + op, inst[insnr].data[5]);
+ opl->write (0x80 + op, inst[insnr].data[6]);
+ opl->write (0x20 + op, inst[insnr].data[8]);
+ opl->write (0xe0 + op, inst[insnr].data[9]);
+ if (version)
+ opl->write (0xc0 + chan, inst[insnr].data[10]);
+ else
+ opl->write (0xc0 + chan,
+ (inst[insnr].data[10] << 1) + (inst[insnr].tunelev & 1));
+}
+
+void
+Cd00Player::playnote (unsigned char chan)
+{
+ // set misc vars & play
+ opl->write (0xb0 + chan, 0); // stop old note
+ setinst (chan);
+ channel[chan].key = 1;
+ setfreq (chan);
+ setvolume (chan);
+}
+
+void
+Cd00Player::vibrato (unsigned char chan)
+{
+ if (!channel[chan].vibdepth)
+ return;
+
+ if (channel[chan].trigger)
+ channel[chan].trigger--;
+ else
+ {
+ channel[chan].trigger = channel[chan].vibdepth;
+ channel[chan].vibspeed = -channel[chan].vibspeed;
+ }
+ channel[chan].freq += channel[chan].vibspeed;
+ setfreq (chan);
+}
diff --git a/src/adplug/core/d00.cxx b/src/adplug/core/d00.cxx
deleted file mode 100644
index d084f484edc0..000000000000
--- a/src/adplug/core/d00.cxx
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * d00.c - D00 Player by Simon Peter <dn.tlp at gmx.net>
- *
- * NOTES:
- * Sorry for the goto's, but the code looks so much nicer now.
- * I tried it with while loops but it was just a mess. If you
- * can come up with a nicer solution, just tell me.
- *
- * BUGS:
- * Hard restart SR is sometimes wrong
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <inttypes.h>
-
-#include "debug.h"
-#include "d00.h"
-
-#define HIBYTE(val) (val >> 8)
-#define LOBYTE(val) (val & 0xff)
-
-static const unsigned short notetable[12] = // D00 note table
-{ 340, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647 };
-
-static inline uint16_t
-LE_WORD (const uint16_t * val)
-{
- const uint8_t *b = (const uint8_t *) val;
- return (b[1] << 8) + b[0];
-}
-
-/*** public methods *************************************/
-
-CPlayer *
-Cd00Player::factory (Copl * newopl)
-{
- return new Cd00Player (newopl);
-}
-
-bool
-Cd00Player::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- d00header *checkhead;
- d00header1 *ch;
- unsigned long filesize;
- int i, ver1 = 0;
- char *str;
- std::string filename (vfs_get_filename (fd));
-
- // file validation section
- checkhead = new d00header;
- f->readString ((char *) checkhead, sizeof (d00header));
-
- // Check for version 2-4 header
- if (strncmp (checkhead->id, "JCH\x26\x02\x66", 6) || checkhead->type ||
- !checkhead->subsongs || checkhead->soundcard)
- {
- // Check for version 0 or 1 header (and .d00 file extension)
- delete checkhead;
- if (!fp.extension (filename, ".d00"))
- {
- fp.close (f);
- return false;
- }
- ch = new d00header1;
- f->seek (0);
- f->readString ((char *) ch, sizeof (d00header1));
- if (ch->version > 1 || !ch->subsongs)
- {
- delete ch;
- fp.close (f);
- return false;
- }
- delete ch;
- ver1 = 1;
- }
- else
- delete checkhead;
-
- AdPlug_LogWrite
- ("Cd00Player::load(f,\"%s\"): %s format D00 file detected!\n",
- filename.c_str (), ver1 ? "Old" : "New");
-
- // load section
- filesize = fp.filesize (f);
- f->seek (0);
- filedata = new char[filesize + 1]; // 1 byte is needed for old-style DataInfo block
- f->readString ((char *) filedata, filesize);
- fp.close (f);
- if (!ver1)
- { // version 2 and above
- header = (struct d00header *) filedata;
- version = header->version;
- datainfo = (char *) filedata + LE_WORD (&header->infoptr);
- inst = (struct Sinsts *) ((char *) filedata + LE_WORD (&header->instptr));
- seqptr =
- (unsigned short *) ((char *) filedata + LE_WORD (&header->seqptr));
- for (i = 31; i >= 0; i--) // erase whitespace
- if (header->songname[i] == ' ')
- header->songname[i] = '\0';
- else
- break;
- for (i = 31; i >= 0; i--)
- if (header->author[i] == ' ')
- header->author[i] = '\0';
- else
- break;
- }
- else
- { // version 1
- header1 = (struct d00header1 *) filedata;
- version = header1->version;
- datainfo = (char *) filedata + LE_WORD (&header1->infoptr);
- inst =
- (struct Sinsts *) ((char *) filedata + LE_WORD (&header1->instptr));
- seqptr =
- (unsigned short *) ((char *) filedata + LE_WORD (&header1->seqptr));
- }
- switch (version)
- {
- case 0:
- levpuls = 0;
- spfx = 0;
- header1->speed = 70; // v0 files default to 70Hz
- break;
- case 1:
- levpuls =
- (struct Slevpuls *) ((char *) filedata + LE_WORD (&header1->lpulptr));
- spfx = 0;
- break;
- case 2:
- levpuls =
- (struct Slevpuls *) ((char *) filedata + LE_WORD (&header->spfxptr));
- spfx = 0;
- break;
- case 3:
- spfx = 0;
- levpuls = 0;
- break;
- case 4:
- spfx = (struct Sspfx *) ((char *) filedata + LE_WORD (&header->spfxptr));
- levpuls = 0;
- break;
- }
- if ((str = strstr (datainfo, "\xff\xff")))
- while ((*str == '\xff' || *str == ' ') && str >= datainfo)
- {
- *str = '\0';
- str--;
- }
- else // old-style block
- memset ((char *) filedata + filesize, 0, 1);
-
- rewind (0);
- return true;
-}
-
-bool
-Cd00Player::update ()
-{
- unsigned char c, cnt, trackend = 0, fx, note;
- unsigned short ord, *patt, buf, fxop, pattpos;
-
- // effect handling (timer dependant)
- for (c = 0; c < 9; c++)
- {
- channel[c].slideval += channel[c].slide;
- setfreq (c); // sliding
- vibrato (c); // vibrato
-
- if (channel[c].spfx != 0xffff)
- { // SpFX
- if (channel[c].fxdel)
- channel[c].fxdel--;
- else
- {
- channel[c].spfx = LE_WORD (&spfx[channel[c].spfx].ptr);
- channel[c].fxdel = spfx[channel[c].spfx].duration;
- channel[c].inst = LE_WORD (&spfx[channel[c].spfx].instnr) & 0xfff;
- if (spfx[channel[c].spfx].modlev != 0xff)
- channel[c].modvol = spfx[channel[c].spfx].modlev;
- setinst (c);
- if (LE_WORD (&spfx[channel[c].spfx].instnr) & 0x8000) // locked frequency
- note = spfx[channel[c].spfx].halfnote;
- else // unlocked frequency
- note = spfx[channel[c].spfx].halfnote + channel[c].note;
- channel[c].freq = notetable[note % 12] + ((note / 12) << 10);
- setfreq (c);
- }
- channel[c].modvol += spfx[channel[c].spfx].modlevadd;
- channel[c].modvol &= 63;
- setvolume (c);
- }
-
- if (channel[c].levpuls != 0xff) // Levelpuls
- {
- if (channel[c].frameskip)
- channel[c].frameskip--;
- else
- {
- channel[c].frameskip = inst[channel[c].inst].timer;
- if (channel[c].fxdel)
- channel[c].fxdel--;
- else
- {
- channel[c].levpuls = levpuls[channel[c].levpuls].ptr - 1;
- channel[c].fxdel = levpuls[channel[c].levpuls].duration;
- if (levpuls[channel[c].levpuls].level != 0xff)
- channel[c].modvol = levpuls[channel[c].levpuls].level;
- }
- channel[c].modvol += levpuls[channel[c].levpuls].voladd;
- channel[c].modvol &= 63;
- setvolume (c);
- }
- }
- }
-
- // song handling
- for (c = 0; c < 9; c++)
- if (version < 3 ? channel[c].del : channel[c].del <= 0x7f)
- {
- if (version == 4) // v4: hard restart SR
- if (channel[c].del == inst[channel[c].inst].timer)
- if (channel[c].nextnote)
- opl->write (0x83 + op_table[c], inst[channel[c].inst].sr);
- if (version < 3)
- channel[c].del--;
- else if (channel[c].speed)
- channel[c].del += channel[c].speed;
- else
- {
- channel[c].seqend = 1;
- continue;
- }
- }
- else
- {
- if (channel[c].speed)
- {
- if (version < 3)
- channel[c].del = channel[c].speed;
- else
- {
- channel[c].del &= 0x7f;
- channel[c].del += channel[c].speed;
- }
- }
- else
- {
- channel[c].seqend = 1;
- continue;
- }
- if (channel[c].rhcnt)
- { // process pending REST/HOLD events
- channel[c].rhcnt--;
- continue;
- }
- readorder: // process arrangement (orderlist)
- ord = LE_WORD (&channel[c].order[channel[c].ordpos]);
- switch (ord)
- {
- case 0xfffe:
- channel[c].seqend = 1;
- continue; // end of arrangement stream
- case 0xffff: // jump to order
- channel[c].ordpos =
- LE_WORD (&channel[c].order[channel[c].ordpos + 1]);
- channel[c].seqend = 1;
- goto readorder;
- default:
- if (ord >= 0x9000)
- { // set speed
- channel[c].speed = ord & 0xff;
- ord = LE_WORD (&channel[c].order[channel[c].ordpos - 1]);
- channel[c].ordpos++;
- }
- else if (ord >= 0x8000)
- { // transpose track
- channel[c].transpose = ord & 0xff;
- if (ord & 0x100)
- channel[c].transpose = -channel[c].transpose;
- ord = LE_WORD (&channel[c].order[++channel[c].ordpos]);
- }
- patt =
- (unsigned short *) ((char *) filedata + LE_WORD (&seqptr[ord]));
- break;
- }
- channel[c].fxflag = 0;
- readseq: // process sequence (pattern)
- if (!version) // v0: always initialize rhcnt
- channel[c].rhcnt = channel[c].irhcnt;
- pattpos = LE_WORD (&patt[channel[c].pattpos]);
- if (pattpos == 0xffff)
- { // pattern ended?
- channel[c].pattpos = 0;
- channel[c].ordpos++;
- goto readorder;
- }
- cnt = HIBYTE (pattpos);
- note = LOBYTE (pattpos);
- fx = pattpos >> 12;
- fxop = pattpos & 0x0fff;
- channel[c].pattpos++;
- pattpos = LE_WORD (&patt[channel[c].pattpos]);
- channel[c].nextnote = LOBYTE (pattpos) & 0x7f;
- if (version ? cnt < 0x40 : !fx)
- { // note event
- switch (note)
- {
- case 0: // REST event
- case 0x80:
- if (!note || version)
- {
- channel[c].key = 0;
- setfreq (c);
- }
- // fall through...
- case 0x7e: // HOLD event
- if (version)
- channel[c].rhcnt = cnt;
- channel[c].nextnote = 0;
- break;
- default: // play note
- // restart fx
- if (!(channel[c].fxflag & 1))
- channel[c].vibdepth = 0;
- if (!(channel[c].fxflag & 2))
- channel[c].slideval = channel[c].slide = 0;
-
- if (version)
- { // note handling for v1 and above
- if (note > 0x80) // locked note (no channel transpose)
- note -= 0x80;
- else // unlocked note
- note += channel[c].transpose;
- channel[c].note = note; // remember note for SpFX
-
- if (channel[c].ispfx != 0xffff && cnt < 0x20)
- { // reset SpFX
- channel[c].spfx = channel[c].ispfx;
- if (LE_WORD (&spfx[channel[c].spfx].instnr) & 0x8000) // locked frequency
- note = spfx[channel[c].spfx].halfnote;
- else // unlocked frequency
- note += spfx[channel[c].spfx].halfnote;
- channel[c].inst =
- LE_WORD (&spfx[channel[c].spfx].instnr) & 0xfff;
- channel[c].fxdel = spfx[channel[c].spfx].duration;
- if (spfx[channel[c].spfx].modlev != 0xff)
- channel[c].modvol = spfx[channel[c].spfx].modlev;
- else
- channel[c].modvol = inst[channel[c].inst].data[7] & 63;
- }
-
- if (channel[c].ilevpuls != 0xff && cnt < 0x20)
- { // reset LevelPuls
- channel[c].levpuls = channel[c].ilevpuls;
- channel[c].fxdel = levpuls[channel[c].levpuls].duration;
- channel[c].frameskip = inst[channel[c].inst].timer;
- if (levpuls[channel[c].levpuls].level != 0xff)
- channel[c].modvol = levpuls[channel[c].levpuls].level;
- else
- channel[c].modvol = inst[channel[c].inst].data[7] & 63;
- }
-
- channel[c].freq = notetable[note % 12] + ((note / 12) << 10);
- if (cnt < 0x20) // normal note
- playnote (c);
- else
- { // tienote
- setfreq (c);
- cnt -= 0x20; // make count proper
- }
- channel[c].rhcnt = cnt;
- }
- else
- { // note handling for v0
- if (cnt < 2) // unlocked note
- note += channel[c].transpose;
- channel[c].note = note;
-
- channel[c].freq = notetable[note % 12] + ((note / 12) << 10);
- if (cnt == 1) // tienote
- setfreq (c);
- else // normal note
- playnote (c);
- }
- break;
- }
- continue; // event is complete
- }
- else
- { // effect event
- switch (fx)
- {
- case 6: // Cut/Stop Voice
- buf = channel[c].inst;
- channel[c].inst = 0;
- playnote (c);
- channel[c].inst = buf;
- channel[c].rhcnt = fxop;
- continue; // no note follows this event
- case 7: // Vibrato
- channel[c].vibspeed = fxop & 0xff;
- channel[c].vibdepth = fxop >> 8;
- channel[c].trigger = fxop >> 9;
- channel[c].fxflag |= 1;
- break;
- case 8: // v0: Duration
- if (!version)
- channel[c].irhcnt = fxop;
- break;
- case 9: // New Level
- channel[c].vol = fxop & 63;
- if (channel[c].vol + channel[c].cvol < 63) // apply channel volume
- channel[c].vol += channel[c].cvol;
- else
- channel[c].vol = 63;
- setvolume (c);
- break;
- case 0xb: // v4: Set SpFX
- if (version == 4)
- channel[c].ispfx = fxop;
- break;
- case 0xc: // Set Instrument
- channel[c].ispfx = 0xffff;
- channel[c].spfx = 0xffff;
- channel[c].inst = fxop;
- channel[c].modvol = inst[fxop].data[7] & 63;
- if (version < 3 && version && inst[fxop].tunelev) // Set LevelPuls
- channel[c].ilevpuls = inst[fxop].tunelev - 1;
- else
- {
- channel[c].ilevpuls = 0xff;
- channel[c].levpuls = 0xff;
- }
- break;
- case 0xd: // Slide up
- channel[c].slide = fxop;
- channel[c].fxflag |= 2;
- break;
- case 0xe: // Slide down
- channel[c].slide = -fxop;
- channel[c].fxflag |= 2;
- break;
- }
- goto readseq; // event is incomplete, note follows
- }
- }
-
- for (c = 0; c < 9; c++)
- if (channel[c].seqend)
- trackend++;
- if (trackend == 9)
- songend = 1;
-
- return !songend;
-}
-
-void
-Cd00Player::rewind (int subsong)
-{
- struct Stpoin
- {
- unsigned short ptr[9];
- unsigned char volume[9], dummy[5];
- } *tpoin;
- int i;
-
- if(subsong == -1) subsong = cursubsong;
-
- if (version > 1)
- { // do nothing if subsong > number of subsongs
- if (subsong >= header->subsongs)
- return;
- }
- else if (subsong >= header1->subsongs)
- return;
-
- memset (channel, 0, sizeof (channel));
- if (version > 1)
- tpoin = (struct Stpoin *) ((char *) filedata + LE_WORD (&header->tpoin));
- else
- tpoin = (struct Stpoin *) ((char *) filedata + LE_WORD (&header1->tpoin));
- for (i = 0; i < 9; i++)
- {
- if (LE_WORD (&tpoin[subsong].ptr[i]))
- { // track enabled
- channel[i].speed = LE_WORD ((unsigned short *)
- ((char *) filedata +
- LE_WORD (&tpoin[subsong].ptr[i])));
- channel[i].order =
- (unsigned short *) ((char *) filedata +
- LE_WORD (&tpoin[subsong].ptr[i]) + 2);
- }
- else
- { // track disabled
- channel[i].speed = 0;
- channel[i].order = 0;
- }
- channel[i].ispfx = 0xffff;
- channel[i].spfx = 0xffff; // no SpFX
- channel[i].ilevpuls = 0xff;
- channel[i].levpuls = 0xff; // no LevelPuls
- channel[i].cvol = tpoin[subsong].volume[i] & 0x7f; // our player may savely ignore bit 7
- channel[i].vol = channel[i].cvol; // initialize volume
- }
- songend = 0;
- opl->init ();
- opl->write (1, 32); // reset OPL chip
- cursubsong = subsong;
-}
-
-std::string Cd00Player::gettype ()
-{
- char
- tmpstr[40];
-
- sprintf (tmpstr, "EdLib packed (version %d)",
- version > 1 ? header->version : header1->version);
- return std::string (tmpstr);
-}
-
-float
-Cd00Player::getrefresh ()
-{
- if (version > 1)
- return header->speed;
- else
- return header1->speed;
-}
-
-unsigned int
-Cd00Player::getsubsongs ()
-{
- if (version <= 1) // return number of subsongs
- return header1->subsongs;
- else
- return header->subsongs;
-}
-
-/*** private methods *************************************/
-
-void
-Cd00Player::setvolume (unsigned char chan)
-{
- unsigned char op = op_table[chan];
- unsigned short insnr = channel[chan].inst;
-
- opl->write (0x43 + op,
- (int) (63 -
- ((63 - (inst[insnr].data[2] & 63)) / 63.0) * (63 -
- channel
- [chan].
- vol)) +
- (inst[insnr].data[2] & 192));
- if (inst[insnr].data[10] & 1)
- opl->write (0x40 + op,
- (int) (63 -
- ((63 - channel[chan].modvol) / 63.0) * (63 -
- channel[chan].
- vol)) +
- (inst[insnr].data[7] & 192));
- else
- opl->write (0x40 + op,
- channel[chan].modvol + (inst[insnr].data[7] & 192));
-}
-
-void
-Cd00Player::setfreq (unsigned char chan)
-{
- unsigned short freq = channel[chan].freq;
-
- if (version == 4) // v4: apply instrument finetune
- freq += inst[channel[chan].inst].tunelev;
-
- freq += channel[chan].slideval;
- opl->write (0xa0 + chan, freq & 255);
- if (channel[chan].key)
- opl->write (0xb0 + chan, ((freq >> 8) & 31) | 32);
- else
- opl->write (0xb0 + chan, (freq >> 8) & 31);
-}
-
-void
-Cd00Player::setinst (unsigned char chan)
-{
- unsigned char op = op_table[chan];
- unsigned short insnr = channel[chan].inst;
-
- // set instrument data
- opl->write (0x63 + op, inst[insnr].data[0]);
- opl->write (0x83 + op, inst[insnr].data[1]);
- opl->write (0x23 + op, inst[insnr].data[3]);
- opl->write (0xe3 + op, inst[insnr].data[4]);
- opl->write (0x60 + op, inst[insnr].data[5]);
- opl->write (0x80 + op, inst[insnr].data[6]);
- opl->write (0x20 + op, inst[insnr].data[8]);
- opl->write (0xe0 + op, inst[insnr].data[9]);
- if (version)
- opl->write (0xc0 + chan, inst[insnr].data[10]);
- else
- opl->write (0xc0 + chan,
- (inst[insnr].data[10] << 1) + (inst[insnr].tunelev & 1));
-}
-
-void
-Cd00Player::playnote (unsigned char chan)
-{
- // set misc vars & play
- opl->write (0xb0 + chan, 0); // stop old note
- setinst (chan);
- channel[chan].key = 1;
- setfreq (chan);
- setvolume (chan);
-}
-
-void
-Cd00Player::vibrato (unsigned char chan)
-{
- if (!channel[chan].vibdepth)
- return;
-
- if (channel[chan].trigger)
- channel[chan].trigger--;
- else
- {
- channel[chan].trigger = channel[chan].vibdepth;
- channel[chan].vibspeed = -channel[chan].vibspeed;
- }
- channel[chan].freq += channel[chan].vibspeed;
- setfreq (chan);
-}
diff --git a/src/adplug/core/d00.h b/src/adplug/core/d00.h
index 05fcc46eb7a9..2071c2ff9e68 100644
--- a/src/adplug/core/d00.h
+++ b/src/adplug/core/d00.h
@@ -35,7 +35,7 @@ class Cd00Player: public CPlayer
~Cd00Player()
{ if(filedata) delete [] filedata; };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
diff --git a/src/adplug/core/database.cc b/src/adplug/core/database.cc
new file mode 100644
index 000000000000..035c284ed205
--- /dev/null
+++ b/src/adplug/core/database.cc
@@ -0,0 +1,520 @@
+/*
+ * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (c) 1999 - 2006 Simon Peter <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * database.cpp - AdPlug database class
+ * Copyright (c) 2002 Riven the Mage <riven at ok.ru>
+ * Copyright (c) 2002, 2003, 2006 Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include "binio_virtual.h"
+#include <string.h>
+
+#include "database.h"
+
+#define DB_FILEID_V10 "AdPlug Module Information Database 1.0\x10"
+
+/***** CAdPlugDatabase *****/
+
+const unsigned short
+ CAdPlugDatabase::hash_radix = 0xfff1; // should be prime
+
+CAdPlugDatabase::CAdPlugDatabase ():linear_index (0), linear_logic_length (0),
+linear_length (0)
+{
+ db_linear = new DB_Bucket *[hash_radix];
+ db_hashed = new DB_Bucket *[hash_radix];
+ memset (db_linear, 0, sizeof (DB_Bucket *) * hash_radix);
+ memset (db_hashed, 0, sizeof (DB_Bucket *) * hash_radix);
+}
+
+CAdPlugDatabase::~CAdPlugDatabase ()
+{
+ unsigned long i;
+
+ for (i = 0; i < linear_length; i++)
+ delete db_linear[i];
+
+ delete[]db_linear;
+ delete[]db_hashed;
+}
+
+bool
+CAdPlugDatabase::load (std::string db_name)
+{
+ vfsistream f (db_name);
+ if (f.error ())
+ return false;
+ return load (f);
+}
+
+bool
+CAdPlugDatabase::load (binistream & f)
+{
+ unsigned int idlen = strlen (DB_FILEID_V10);
+ char *id = new char[idlen];
+ unsigned long length;
+
+ // Open database as little endian with IEEE floats
+ f.setFlag (binio::BigEndian, false);
+ f.setFlag (binio::FloatIEEE);
+
+ f.readString (id, idlen);
+ if (memcmp (id, DB_FILEID_V10, idlen))
+ {
+ delete[]id;
+ return false;
+ }
+ delete[]id;
+ length = f.readInt (4);
+
+ // read records
+ for (unsigned long i = 0; i < length; i++)
+ insert (CRecord::factory (f));
+
+ return true;
+}
+
+bool
+CAdPlugDatabase::save (std::string db_name)
+{
+ vfsostream f (db_name);
+ if (f.error ())
+ return false;
+ return save (f);
+}
+
+bool
+CAdPlugDatabase::save (binostream & f)
+{
+ unsigned long i;
+
+ // Save database as little endian with IEEE floats
+ f.setFlag (binio::BigEndian, false);
+ f.setFlag (binio::FloatIEEE);
+
+ f.writeString (DB_FILEID_V10);
+ f.writeInt (linear_logic_length, 4);
+
+ // write records
+ for (i = 0; i < linear_length; i++)
+ if (!db_linear[i]->deleted)
+ db_linear[i]->record->write (f);
+
+ return true;
+}
+
+CAdPlugDatabase::CRecord * CAdPlugDatabase::search (CKey const &key)
+{
+ if (lookup (key))
+ return get_record ();
+ else
+ return 0;
+}
+
+bool
+CAdPlugDatabase::lookup (CKey const &key)
+{
+ unsigned long index = make_hash (key);
+ if (!db_hashed[index])
+ return false;
+
+ // immediate hit ?
+ DB_Bucket *bucket = db_hashed[index];
+
+ if (!bucket->deleted && bucket->record->key == key)
+ {
+ linear_index = bucket->index;
+ return true;
+ }
+
+ // in-chain hit ?
+ bucket = db_hashed[index]->chain;
+
+ while (bucket)
+ {
+ if (!bucket->deleted && bucket->record->key == key)
+ {
+ linear_index = bucket->index;
+ return true;
+ }
+
+ bucket = bucket->chain;
+ }
+
+ return false;
+}
+
+bool
+CAdPlugDatabase::insert (CRecord * record)
+{
+ long index;
+
+ // sanity checks
+ if (!record)
+ return false; // null-pointer given
+ if (linear_length == hash_radix)
+ return false; // max. db size exceeded
+ if (lookup (record->key))
+ return false; // record already in db
+
+ // make bucket
+ DB_Bucket *bucket = new DB_Bucket (linear_length, record);
+ if (!bucket)
+ return false;
+
+ // add to linear list
+ db_linear[linear_length] = bucket;
+ linear_logic_length++;
+ linear_length++;
+
+ // add to hashed list
+ index = make_hash (record->key);
+
+ if (!db_hashed[index]) // First entry in hashtable
+ db_hashed[index] = bucket;
+ else
+ { // Add entry in chained list
+ DB_Bucket *chain = db_hashed[index];
+
+ while (chain->chain)
+ chain = chain->chain;
+ chain->chain = bucket;
+ }
+
+ return true;
+}
+
+void
+CAdPlugDatabase::wipe (CRecord * record)
+{
+ if (!lookup (record->key))
+ return;
+ wipe ();
+}
+
+void
+CAdPlugDatabase::wipe ()
+{
+ if (!linear_length)
+ return;
+
+ DB_Bucket *bucket = db_linear[linear_index];
+
+ if (!bucket->deleted)
+ {
+ delete bucket->record;
+ linear_logic_length--;
+ bucket->deleted = true;
+ }
+}
+
+CAdPlugDatabase::CRecord * CAdPlugDatabase::get_record ()
+{
+ if (!linear_length)
+ return 0;
+ return db_linear[linear_index]->record;
+}
+
+bool
+CAdPlugDatabase::go_forward ()
+{
+ if (linear_index + 1 < linear_length)
+ {
+ linear_index++;
+ return true;
+ }
+ else
+ return false;
+}
+
+bool
+CAdPlugDatabase::go_backward ()
+{
+ if (!linear_index)
+ return false;
+ linear_index--;
+ return true;
+}
+
+void
+CAdPlugDatabase::goto_begin ()
+{
+ if (linear_length)
+ linear_index = 0;
+}
+
+void
+CAdPlugDatabase::goto_end ()
+{
+ if (linear_length)
+ linear_index = linear_length - 1;
+}
+
+inline unsigned long
+CAdPlugDatabase::make_hash (CKey const &key)
+{
+ return (key.crc32 + key.crc16) % hash_radix;
+}
+
+/***** CAdPlugDatabase::DB_Bucket *****/
+
+CAdPlugDatabase::DB_Bucket::DB_Bucket (unsigned long nindex, CRecord * newrecord, DB_Bucket * newchain):index (nindex), deleted (false), chain (newchain),
+record
+(newrecord)
+{
+}
+
+CAdPlugDatabase::DB_Bucket::~DB_Bucket ()
+{
+ if (!deleted)
+ delete
+ record;
+}
+
+/***** CAdPlugDatabase::CRecord *****/
+
+CAdPlugDatabase::CRecord * CAdPlugDatabase::CRecord::factory (RecordType type)
+{
+ switch (type)
+ {
+ case Plain:
+ return new CPlainRecord;
+ case SongInfo:
+ return new CInfoRecord;
+ case ClockSpeed:
+ return new CClockRecord;
+ default:
+ return 0;
+ }
+}
+
+CAdPlugDatabase::CRecord * CAdPlugDatabase::CRecord::factory (binistream & in)
+{
+ RecordType
+ type;
+ unsigned long
+ size;
+ CRecord *
+ rec;
+
+ type = (RecordType) in.readInt (1);
+ size = in.readInt (4);
+ rec = factory (type);
+
+ if (rec)
+ {
+ rec->key.crc16 = in.readInt (2);
+ rec->key.crc32 = in.readInt (4);
+ rec->filetype = in.readString ('\0');
+ rec->comment = in.readString ('\0');
+ rec->read_own (in);
+ return rec;
+ }
+ else
+ {
+ // skip this record, cause we don't know about it
+ in.seek (size, binio::Add);
+ return 0;
+ }
+}
+
+void
+CAdPlugDatabase::CRecord::write (binostream & out)
+{
+ out.writeInt (type, 1);
+ out.writeInt (get_size () + filetype.length () + comment.length () + 8, 4);
+ out.writeInt (key.crc16, 2);
+ out.writeInt (key.crc32, 4);
+ out.writeString (filetype);
+ out.writeInt ('\0', 1);
+ out.writeString (comment);
+ out.writeInt ('\0', 1);
+
+ write_own (out);
+}
+
+bool
+CAdPlugDatabase::CRecord::user_read (std::istream & in, std::ostream & out)
+{
+ return user_read_own (in, out);
+}
+
+bool
+CAdPlugDatabase::CRecord::user_write (std::ostream & out)
+{
+ out << "Record type: ";
+ switch (type)
+ {
+ case Plain:
+ out << "Plain";
+ break;
+ case SongInfo:
+ out << "SongInfo";
+ break;
+ case ClockSpeed:
+ out << "ClockSpeed";
+ break;
+ default:
+ out << "*** Unknown ***";
+ break;
+ }
+ out << std::endl;
+ out << "Key: " << std::hex << key.crc16 << ":" << key.
+ crc32 << std::dec << std::endl;
+ out << "File type: " << filetype << std::endl;
+ out << "Comment: " << comment << std::endl;
+
+ return user_write_own (out);
+}
+
+/***** CAdPlugDatabase::CRecord::CKey *****/
+
+CAdPlugDatabase::CKey::CKey (binistream & buf)
+{
+ make (buf);
+}
+
+bool
+CAdPlugDatabase::CKey::operator== (const CKey & key)
+{
+ return ((crc16 == key.crc16) && (crc32 == key.crc32));
+}
+
+void
+CAdPlugDatabase::CKey::make (binistream & buf)
+// Key is CRC16:CRC32 pair. CRC16 and CRC32 calculation routines (c) Zhengxi
+{
+ static const unsigned short
+ magic16 = 0xa001;
+ static const unsigned long
+ magic32 = 0xedb88320;
+
+ crc16 = 0;
+ crc32 = ~0;
+
+ while (!buf.eof ())
+ {
+ unsigned char
+ byte = buf.readInt (1);
+
+ for (int j = 0; j < 8; j++)
+ {
+ if ((crc16 ^ byte) & 1)
+ crc16 = (crc16 >> 1) ^ magic16;
+ else
+ crc16 >>= 1;
+
+ if ((crc32 ^ byte) & 1)
+ crc32 = (crc32 >> 1) ^ magic32;
+ else
+ crc32 >>= 1;
+
+ byte >>= 1;
+ }
+ }
+
+ crc16 &= 0xffff;
+ crc32 = ~crc32;
+}
+
+/***** CInfoRecord *****/
+
+CInfoRecord::CInfoRecord ()
+{
+ type = SongInfo;
+}
+
+void
+CInfoRecord::read_own (binistream & in)
+{
+ title = in.readString ('\0');
+ author = in.readString ('\0');
+}
+
+void
+CInfoRecord::write_own (binostream & out)
+{
+ out.writeString (title);
+ out.writeInt ('\0', 1);
+ out.writeString (author);
+ out.writeInt ('\0', 1);
+}
+
+unsigned long
+CInfoRecord::get_size ()
+{
+ return title.length () + author.length () + 2;
+}
+
+bool
+CInfoRecord::user_read_own (std::istream & in, std::ostream & out)
+{
+ out << "Title: ";
+ in >> title;
+ out << "Author: ";
+ in >> author;
+ return true;
+}
+
+bool
+CInfoRecord::user_write_own (std::ostream & out)
+{
+ out << "Title: " << title << std::endl;
+ out << "Author: " << author << std::endl;
+ return true;
+}
+
+/***** CClockRecord *****/
+
+CClockRecord::CClockRecord ():clock (0.0f)
+{
+ type = ClockSpeed;
+}
+
+void
+CClockRecord::read_own (binistream & in)
+{
+ clock = in.readFloat (binio::Single);
+}
+
+void
+CClockRecord::write_own (binostream & out)
+{
+ out.writeFloat (clock, binio::Single);
+}
+
+unsigned long
+CClockRecord::get_size ()
+{
+ return 4;
+}
+
+bool
+CClockRecord::user_read_own (std::istream & in, std::ostream & out)
+{
+ out << "Clockspeed: ";
+ in >> clock;
+ return true;
+}
+
+bool
+CClockRecord::user_write_own (std::ostream & out)
+{
+ out << "Clock speed: " << clock << " Hz" << std::endl;
+ return true;
+}
diff --git a/src/adplug/core/database.cxx b/src/adplug/core/database.cxx
deleted file mode 100644
index 035c284ed205..000000000000
--- a/src/adplug/core/database.cxx
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (c) 1999 - 2006 Simon Peter <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * database.cpp - AdPlug database class
- * Copyright (c) 2002 Riven the Mage <riven at ok.ru>
- * Copyright (c) 2002, 2003, 2006 Simon Peter <dn.tlp at gmx.net>
- */
-
-#include "binio_virtual.h"
-#include <string.h>
-
-#include "database.h"
-
-#define DB_FILEID_V10 "AdPlug Module Information Database 1.0\x10"
-
-/***** CAdPlugDatabase *****/
-
-const unsigned short
- CAdPlugDatabase::hash_radix = 0xfff1; // should be prime
-
-CAdPlugDatabase::CAdPlugDatabase ():linear_index (0), linear_logic_length (0),
-linear_length (0)
-{
- db_linear = new DB_Bucket *[hash_radix];
- db_hashed = new DB_Bucket *[hash_radix];
- memset (db_linear, 0, sizeof (DB_Bucket *) * hash_radix);
- memset (db_hashed, 0, sizeof (DB_Bucket *) * hash_radix);
-}
-
-CAdPlugDatabase::~CAdPlugDatabase ()
-{
- unsigned long i;
-
- for (i = 0; i < linear_length; i++)
- delete db_linear[i];
-
- delete[]db_linear;
- delete[]db_hashed;
-}
-
-bool
-CAdPlugDatabase::load (std::string db_name)
-{
- vfsistream f (db_name);
- if (f.error ())
- return false;
- return load (f);
-}
-
-bool
-CAdPlugDatabase::load (binistream & f)
-{
- unsigned int idlen = strlen (DB_FILEID_V10);
- char *id = new char[idlen];
- unsigned long length;
-
- // Open database as little endian with IEEE floats
- f.setFlag (binio::BigEndian, false);
- f.setFlag (binio::FloatIEEE);
-
- f.readString (id, idlen);
- if (memcmp (id, DB_FILEID_V10, idlen))
- {
- delete[]id;
- return false;
- }
- delete[]id;
- length = f.readInt (4);
-
- // read records
- for (unsigned long i = 0; i < length; i++)
- insert (CRecord::factory (f));
-
- return true;
-}
-
-bool
-CAdPlugDatabase::save (std::string db_name)
-{
- vfsostream f (db_name);
- if (f.error ())
- return false;
- return save (f);
-}
-
-bool
-CAdPlugDatabase::save (binostream & f)
-{
- unsigned long i;
-
- // Save database as little endian with IEEE floats
- f.setFlag (binio::BigEndian, false);
- f.setFlag (binio::FloatIEEE);
-
- f.writeString (DB_FILEID_V10);
- f.writeInt (linear_logic_length, 4);
-
- // write records
- for (i = 0; i < linear_length; i++)
- if (!db_linear[i]->deleted)
- db_linear[i]->record->write (f);
-
- return true;
-}
-
-CAdPlugDatabase::CRecord * CAdPlugDatabase::search (CKey const &key)
-{
- if (lookup (key))
- return get_record ();
- else
- return 0;
-}
-
-bool
-CAdPlugDatabase::lookup (CKey const &key)
-{
- unsigned long index = make_hash (key);
- if (!db_hashed[index])
- return false;
-
- // immediate hit ?
- DB_Bucket *bucket = db_hashed[index];
-
- if (!bucket->deleted && bucket->record->key == key)
- {
- linear_index = bucket->index;
- return true;
- }
-
- // in-chain hit ?
- bucket = db_hashed[index]->chain;
-
- while (bucket)
- {
- if (!bucket->deleted && bucket->record->key == key)
- {
- linear_index = bucket->index;
- return true;
- }
-
- bucket = bucket->chain;
- }
-
- return false;
-}
-
-bool
-CAdPlugDatabase::insert (CRecord * record)
-{
- long index;
-
- // sanity checks
- if (!record)
- return false; // null-pointer given
- if (linear_length == hash_radix)
- return false; // max. db size exceeded
- if (lookup (record->key))
- return false; // record already in db
-
- // make bucket
- DB_Bucket *bucket = new DB_Bucket (linear_length, record);
- if (!bucket)
- return false;
-
- // add to linear list
- db_linear[linear_length] = bucket;
- linear_logic_length++;
- linear_length++;
-
- // add to hashed list
- index = make_hash (record->key);
-
- if (!db_hashed[index]) // First entry in hashtable
- db_hashed[index] = bucket;
- else
- { // Add entry in chained list
- DB_Bucket *chain = db_hashed[index];
-
- while (chain->chain)
- chain = chain->chain;
- chain->chain = bucket;
- }
-
- return true;
-}
-
-void
-CAdPlugDatabase::wipe (CRecord * record)
-{
- if (!lookup (record->key))
- return;
- wipe ();
-}
-
-void
-CAdPlugDatabase::wipe ()
-{
- if (!linear_length)
- return;
-
- DB_Bucket *bucket = db_linear[linear_index];
-
- if (!bucket->deleted)
- {
- delete bucket->record;
- linear_logic_length--;
- bucket->deleted = true;
- }
-}
-
-CAdPlugDatabase::CRecord * CAdPlugDatabase::get_record ()
-{
- if (!linear_length)
- return 0;
- return db_linear[linear_index]->record;
-}
-
-bool
-CAdPlugDatabase::go_forward ()
-{
- if (linear_index + 1 < linear_length)
- {
- linear_index++;
- return true;
- }
- else
- return false;
-}
-
-bool
-CAdPlugDatabase::go_backward ()
-{
- if (!linear_index)
- return false;
- linear_index--;
- return true;
-}
-
-void
-CAdPlugDatabase::goto_begin ()
-{
- if (linear_length)
- linear_index = 0;
-}
-
-void
-CAdPlugDatabase::goto_end ()
-{
- if (linear_length)
- linear_index = linear_length - 1;
-}
-
-inline unsigned long
-CAdPlugDatabase::make_hash (CKey const &key)
-{
- return (key.crc32 + key.crc16) % hash_radix;
-}
-
-/***** CAdPlugDatabase::DB_Bucket *****/
-
-CAdPlugDatabase::DB_Bucket::DB_Bucket (unsigned long nindex, CRecord * newrecord, DB_Bucket * newchain):index (nindex), deleted (false), chain (newchain),
-record
-(newrecord)
-{
-}
-
-CAdPlugDatabase::DB_Bucket::~DB_Bucket ()
-{
- if (!deleted)
- delete
- record;
-}
-
-/***** CAdPlugDatabase::CRecord *****/
-
-CAdPlugDatabase::CRecord * CAdPlugDatabase::CRecord::factory (RecordType type)
-{
- switch (type)
- {
- case Plain:
- return new CPlainRecord;
- case SongInfo:
- return new CInfoRecord;
- case ClockSpeed:
- return new CClockRecord;
- default:
- return 0;
- }
-}
-
-CAdPlugDatabase::CRecord * CAdPlugDatabase::CRecord::factory (binistream & in)
-{
- RecordType
- type;
- unsigned long
- size;
- CRecord *
- rec;
-
- type = (RecordType) in.readInt (1);
- size = in.readInt (4);
- rec = factory (type);
-
- if (rec)
- {
- rec->key.crc16 = in.readInt (2);
- rec->key.crc32 = in.readInt (4);
- rec->filetype = in.readString ('\0');
- rec->comment = in.readString ('\0');
- rec->read_own (in);
- return rec;
- }
- else
- {
- // skip this record, cause we don't know about it
- in.seek (size, binio::Add);
- return 0;
- }
-}
-
-void
-CAdPlugDatabase::CRecord::write (binostream & out)
-{
- out.writeInt (type, 1);
- out.writeInt (get_size () + filetype.length () + comment.length () + 8, 4);
- out.writeInt (key.crc16, 2);
- out.writeInt (key.crc32, 4);
- out.writeString (filetype);
- out.writeInt ('\0', 1);
- out.writeString (comment);
- out.writeInt ('\0', 1);
-
- write_own (out);
-}
-
-bool
-CAdPlugDatabase::CRecord::user_read (std::istream & in, std::ostream & out)
-{
- return user_read_own (in, out);
-}
-
-bool
-CAdPlugDatabase::CRecord::user_write (std::ostream & out)
-{
- out << "Record type: ";
- switch (type)
- {
- case Plain:
- out << "Plain";
- break;
- case SongInfo:
- out << "SongInfo";
- break;
- case ClockSpeed:
- out << "ClockSpeed";
- break;
- default:
- out << "*** Unknown ***";
- break;
- }
- out << std::endl;
- out << "Key: " << std::hex << key.crc16 << ":" << key.
- crc32 << std::dec << std::endl;
- out << "File type: " << filetype << std::endl;
- out << "Comment: " << comment << std::endl;
-
- return user_write_own (out);
-}
-
-/***** CAdPlugDatabase::CRecord::CKey *****/
-
-CAdPlugDatabase::CKey::CKey (binistream & buf)
-{
- make (buf);
-}
-
-bool
-CAdPlugDatabase::CKey::operator== (const CKey & key)
-{
- return ((crc16 == key.crc16) && (crc32 == key.crc32));
-}
-
-void
-CAdPlugDatabase::CKey::make (binistream & buf)
-// Key is CRC16:CRC32 pair. CRC16 and CRC32 calculation routines (c) Zhengxi
-{
- static const unsigned short
- magic16 = 0xa001;
- static const unsigned long
- magic32 = 0xedb88320;
-
- crc16 = 0;
- crc32 = ~0;
-
- while (!buf.eof ())
- {
- unsigned char
- byte = buf.readInt (1);
-
- for (int j = 0; j < 8; j++)
- {
- if ((crc16 ^ byte) & 1)
- crc16 = (crc16 >> 1) ^ magic16;
- else
- crc16 >>= 1;
-
- if ((crc32 ^ byte) & 1)
- crc32 = (crc32 >> 1) ^ magic32;
- else
- crc32 >>= 1;
-
- byte >>= 1;
- }
- }
-
- crc16 &= 0xffff;
- crc32 = ~crc32;
-}
-
-/***** CInfoRecord *****/
-
-CInfoRecord::CInfoRecord ()
-{
- type = SongInfo;
-}
-
-void
-CInfoRecord::read_own (binistream & in)
-{
- title = in.readString ('\0');
- author = in.readString ('\0');
-}
-
-void
-CInfoRecord::write_own (binostream & out)
-{
- out.writeString (title);
- out.writeInt ('\0', 1);
- out.writeString (author);
- out.writeInt ('\0', 1);
-}
-
-unsigned long
-CInfoRecord::get_size ()
-{
- return title.length () + author.length () + 2;
-}
-
-bool
-CInfoRecord::user_read_own (std::istream & in, std::ostream & out)
-{
- out << "Title: ";
- in >> title;
- out << "Author: ";
- in >> author;
- return true;
-}
-
-bool
-CInfoRecord::user_write_own (std::ostream & out)
-{
- out << "Title: " << title << std::endl;
- out << "Author: " << author << std::endl;
- return true;
-}
-
-/***** CClockRecord *****/
-
-CClockRecord::CClockRecord ():clock (0.0f)
-{
- type = ClockSpeed;
-}
-
-void
-CClockRecord::read_own (binistream & in)
-{
- clock = in.readFloat (binio::Single);
-}
-
-void
-CClockRecord::write_own (binostream & out)
-{
- out.writeFloat (clock, binio::Single);
-}
-
-unsigned long
-CClockRecord::get_size ()
-{
- return 4;
-}
-
-bool
-CClockRecord::user_read_own (std::istream & in, std::ostream & out)
-{
- out << "Clockspeed: ";
- in >> clock;
- return true;
-}
-
-bool
-CClockRecord::user_write_own (std::ostream & out)
-{
- out << "Clock speed: " << clock << " Hz" << std::endl;
- return true;
-}
diff --git a/src/adplug/core/debug.c b/src/adplug/core/debug.c
deleted file mode 100644
index aa028a86a1f8..000000000000
--- a/src/adplug/core/debug.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2002 Simon Peter <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * debug.h - AdPlug Debug Logger
- * Copyright (c) 2002 Riven the Mage <riven at ok.ru>
- * Copyright (c) 2002 Simon Peter <dn.tlp at gmx.net>
- */
-
-#ifdef DEBUG
-
-#include <stdio.h>
-#include <stdarg.h>
-
-static FILE *log = NULL;
-
-void AdPlug_LogFile(const char *filename)
-{
- if(log) fclose(log);
- log = fopen(filename,"wt");
-}
-
-void AdPlug_LogWrite(const char *fmt, ...)
-{
- va_list argptr;
-
- va_start(argptr, fmt);
-
- if(log) {
- vfprintf(log, fmt, argptr);
- fflush(log);
- } else
- vfprintf(stderr, fmt, argptr);
-
- va_end(argptr);
-}
-
-#else
-
-void AdPlug_LogFile(char *filename) { }
-void AdPlug_LogWrite(char *fmt, ...) { }
-
-#endif
diff --git a/src/adplug/core/debug.cc b/src/adplug/core/debug.cc
new file mode 100644
index 000000000000..e49b1373d300
--- /dev/null
+++ b/src/adplug/core/debug.cc
@@ -0,0 +1,57 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2002 Simon Peter <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * debug.h - AdPlug Debug Logger
+ * Copyright (c) 2002 Riven the Mage <riven at ok.ru>
+ * Copyright (c) 2002 Simon Peter <dn.tlp at gmx.net>
+ */
+
+#ifdef DEBUG
+
+#include <stdio.h>
+#include <stdarg.h>
+
+static FILE *log = nullptr;
+
+void AdPlug_LogFile(const char *filename)
+{
+ if(log) fclose(log);
+ log = fopen(filename,"wt");
+}
+
+void AdPlug_LogWrite(const char *fmt, ...)
+{
+ va_list argptr;
+
+ va_start(argptr, fmt);
+
+ if(log) {
+ vfprintf(log, fmt, argptr);
+ fflush(log);
+ } else
+ vfprintf(stderr, fmt, argptr);
+
+ va_end(argptr);
+}
+
+#else
+
+void AdPlug_LogFile(const char *filename) { }
+void AdPlug_LogWrite(const char *fmt, ...) { }
+
+#endif
diff --git a/src/adplug/core/debug.h b/src/adplug/core/debug.h
index 2c3fc6b18963..0abd9337aa58 100644
--- a/src/adplug/core/debug.h
+++ b/src/adplug/core/debug.h
@@ -1,17 +1,17 @@
/*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2002 Simon Peter <dn.tlp at gmx.net>, et al.
- *
+ *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -34,10 +34,7 @@
#define ADL_DEBUG
-extern "C"
-{
- void AdPlug_LogFile(const char *filename);
- void AdPlug_LogWrite(const char *fmt, ...);
-}
+void AdPlug_LogFile(const char *filename);
+void AdPlug_LogWrite(const char *fmt, ...);
#endif
diff --git a/src/adplug/core/dfm.cc b/src/adplug/core/dfm.cc
new file mode 100644
index 000000000000..cb00aa563474
--- /dev/null
+++ b/src/adplug/core/dfm.cc
@@ -0,0 +1,137 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * dfm.cpp - Digital-FM Loader by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "dfm.h"
+#include "debug.h"
+
+CPlayer *
+CdfmLoader::factory (Copl * newopl)
+{
+ return new CdfmLoader (newopl);
+}
+
+bool
+CdfmLoader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ unsigned char npats, n, note, fx, c, r, param;
+ unsigned int i;
+ const unsigned char convfx[8] = { 255, 255, 17, 19, 23, 24, 255, 13 };
+
+ // file validation
+ f->readString (header.id, 4);
+ header.hiver = f->readInt (1);
+ header.lover = f->readInt (1);
+ if (strncmp (header.id, "DFM\x1a", 4) || header.hiver > 1)
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // load
+ restartpos = 0;
+ flags = Standard;
+ bpm = 0;
+ init_trackord ();
+ f->readString (songinfo, 33);
+ initspeed = f->readInt (1);
+ for (i = 0; i < 32; i++)
+ f->readString (instname[i], 12);
+ for (i = 0; i < 32; i++)
+ {
+ inst[i].data[1] = f->readInt (1);
+ inst[i].data[2] = f->readInt (1);
+ inst[i].data[9] = f->readInt (1);
+ inst[i].data[10] = f->readInt (1);
+ inst[i].data[3] = f->readInt (1);
+ inst[i].data[4] = f->readInt (1);
+ inst[i].data[5] = f->readInt (1);
+ inst[i].data[6] = f->readInt (1);
+ inst[i].data[7] = f->readInt (1);
+ inst[i].data[8] = f->readInt (1);
+ inst[i].data[0] = f->readInt (1);
+ }
+ for (i = 0; i < 128; i++)
+ order[i] = f->readInt (1);
+ for (i = 0; i < 128 && order[i] != 128; i++);
+ length = i;
+ npats = f->readInt (1);
+ for (i = 0; i < npats; i++)
+ {
+ n = f->readInt (1);
+ for (r = 0; r < 64; r++)
+ for (c = 0; c < 9; c++)
+ {
+ note = f->readInt (1);
+ if ((note & 15) == 15)
+ tracks[n * 9 + c][r].note = 127; // key off
+ else
+ tracks[n * 9 + c][r].note = ((note & 127) >> 4) * 12 + (note & 15);
+ if (note & 128)
+ { // additional effect byte
+ fx = f->readInt (1);
+ if (fx >> 5 == 1)
+ tracks[n * 9 + c][r].inst = (fx & 31) + 1;
+ else
+ {
+ tracks[n * 9 + c][r].command = convfx[fx >> 5];
+ if (tracks[n * 9 + c][r].command == 17)
+ { // set volume
+ param = fx & 31;
+ param = 63 - param * 2;
+ tracks[n * 9 + c][r].param1 = param >> 4;
+ tracks[n * 9 + c][r].param2 = param & 15;
+ }
+ else
+ {
+ tracks[n * 9 + c][r].param1 = (fx & 31) >> 4;
+ tracks[n * 9 + c][r].param2 = fx & 15;
+ }
+ }
+ }
+
+ }
+ }
+
+ fp.close (f);
+ rewind (0);
+ return true;
+}
+
+std::string CdfmLoader::gettype ()
+{
+ char
+ tmpstr[20];
+
+ sprintf (tmpstr, "Digital-FM %d.%d", header.hiver, header.lover);
+ return std::string (tmpstr);
+}
+
+float
+CdfmLoader::getrefresh ()
+{
+ return 125.0f;
+}
diff --git a/src/adplug/core/dfm.cxx b/src/adplug/core/dfm.cxx
deleted file mode 100644
index c8edc03b59c7..000000000000
--- a/src/adplug/core/dfm.cxx
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * dfm.cpp - Digital-FM Loader by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "dfm.h"
-#include "debug.h"
-
-CPlayer *
-CdfmLoader::factory (Copl * newopl)
-{
- return new CdfmLoader (newopl);
-}
-
-bool
-CdfmLoader::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- unsigned char npats, n, note, fx, c, r, param;
- unsigned int i;
- const unsigned char convfx[8] = { 255, 255, 17, 19, 23, 24, 255, 13 };
-
- // file validation
- f->readString (header.id, 4);
- header.hiver = f->readInt (1);
- header.lover = f->readInt (1);
- if (strncmp (header.id, "DFM\x1a", 4) || header.hiver > 1)
- {
- fp.close (f);
- return false;
- }
-
- // load
- restartpos = 0;
- flags = Standard;
- bpm = 0;
- init_trackord ();
- f->readString (songinfo, 33);
- initspeed = f->readInt (1);
- for (i = 0; i < 32; i++)
- f->readString (instname[i], 12);
- for (i = 0; i < 32; i++)
- {
- inst[i].data[1] = f->readInt (1);
- inst[i].data[2] = f->readInt (1);
- inst[i].data[9] = f->readInt (1);
- inst[i].data[10] = f->readInt (1);
- inst[i].data[3] = f->readInt (1);
- inst[i].data[4] = f->readInt (1);
- inst[i].data[5] = f->readInt (1);
- inst[i].data[6] = f->readInt (1);
- inst[i].data[7] = f->readInt (1);
- inst[i].data[8] = f->readInt (1);
- inst[i].data[0] = f->readInt (1);
- }
- for (i = 0; i < 128; i++)
- order[i] = f->readInt (1);
- for (i = 0; i < 128 && order[i] != 128; i++);
- length = i;
- npats = f->readInt (1);
- for (i = 0; i < npats; i++)
- {
- n = f->readInt (1);
- for (r = 0; r < 64; r++)
- for (c = 0; c < 9; c++)
- {
- note = f->readInt (1);
- if ((note & 15) == 15)
- tracks[n * 9 + c][r].note = 127; // key off
- else
- tracks[n * 9 + c][r].note = ((note & 127) >> 4) * 12 + (note & 15);
- if (note & 128)
- { // additional effect byte
- fx = f->readInt (1);
- if (fx >> 5 == 1)
- tracks[n * 9 + c][r].inst = (fx & 31) + 1;
- else
- {
- tracks[n * 9 + c][r].command = convfx[fx >> 5];
- if (tracks[n * 9 + c][r].command == 17)
- { // set volume
- param = fx & 31;
- param = 63 - param * 2;
- tracks[n * 9 + c][r].param1 = param >> 4;
- tracks[n * 9 + c][r].param2 = param & 15;
- }
- else
- {
- tracks[n * 9 + c][r].param1 = (fx & 31) >> 4;
- tracks[n * 9 + c][r].param2 = fx & 15;
- }
- }
- }
-
- }
- }
-
- fp.close (f);
- rewind (0);
- return true;
-}
-
-std::string CdfmLoader::gettype ()
-{
- char
- tmpstr[20];
-
- sprintf (tmpstr, "Digital-FM %d.%d", header.hiver, header.lover);
- return std::string (tmpstr);
-}
-
-float
-CdfmLoader::getrefresh ()
-{
- return 125.0f;
-}
diff --git a/src/adplug/core/dfm.h b/src/adplug/core/dfm.h
index 8cbe47d7489b..0d7770e0cf97 100644
--- a/src/adplug/core/dfm.h
+++ b/src/adplug/core/dfm.h
@@ -30,7 +30,7 @@ public:
: CmodPlayer(newopl)
{ };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
float getrefresh();
std::string gettype();
diff --git a/src/adplug/core/dmo.cc b/src/adplug/core/dmo.cc
new file mode 100644
index 000000000000..bf9d22243284
--- /dev/null
+++ b/src/adplug/core/dmo.cc
@@ -0,0 +1,456 @@
+/*
+ Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ Copyright (C) 1999 - 2004, 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ dmo.cpp - TwinTeam loader by Riven the Mage <riven at ok.ru>
+*/
+/*
+ NOTES:
+ Panning is ignored.
+
+ A WORD ist 16 bits, a DWORD is 32 bits and a BYTE is 8 bits in this context.
+*/
+
+#include <string.h>
+#include <binstr.h>
+
+#include "dmo.h"
+#include "debug.h"
+
+#define LOWORD(l) ((l) & 0xffff)
+#define HIWORD(l) ((l) >> 16)
+#define LOBYTE(w) ((w) & 0xff)
+#define HIBYTE(w) ((w) >> 8)
+
+#define ARRAY_AS_DWORD(a, i) \
+((a[i + 3] << 24) + (a[i + 2] << 16) + (a[i + 1] << 8) + a[i])
+#define ARRAY_AS_WORD(a, i) ((a[i + 1] << 8) + a[i])
+
+#define CHARP_AS_WORD(p) (((*(p + 1)) << 8) + (*p))
+
+/* -------- Public Methods -------------------------------- */
+
+CPlayer *
+CdmoLoader::factory (Copl * newopl)
+{
+ return new CdmoLoader (newopl);
+}
+
+bool
+CdmoLoader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ int i, j;
+ binistream *f;
+ std::string filename (fd.filename ());
+
+ // check header
+ dmo_unpacker *unpacker = new dmo_unpacker;
+ unsigned char chkhdr[16];
+
+ f = fp.open (fd);
+ if (!f)
+ {
+ delete unpacker;
+ return false;
+ }
+ if (!fp.extension (filename, ".dmo"))
+ {
+ delete unpacker;
+ return false;
+ }
+
+ f->readString ((char *) chkhdr, 16);
+
+ if (!unpacker->decrypt (chkhdr, 16))
+ {
+ delete unpacker;
+ fp.close (f);
+ return false;
+ }
+
+ // get file size
+ long packed_length = fp.filesize (f);
+ f->seek (0);
+
+ unsigned char *packed_module = new unsigned char[packed_length];
+
+ // load file
+ f->readString ((char *) packed_module, packed_length);
+ fp.close (f);
+
+ // decrypt
+ unpacker->decrypt (packed_module, packed_length);
+
+ long unpacked_length = 0x2000 * ARRAY_AS_WORD (packed_module, 12);
+ unsigned char *module = new unsigned char[unpacked_length];
+
+ // unpack
+ if (!unpacker->unpack (packed_module + 12, module, unpacked_length))
+ {
+ delete unpacker;
+ delete[]packed_module;
+ delete[]module;
+ return false;
+ }
+
+ delete unpacker;
+ delete[]packed_module;
+
+ // "TwinTeam" - signed ?
+ if (memcmp (module, "TwinTeam Module File" "\x0D\x0A", 22))
+ {
+ delete module;
+ return false;
+ }
+
+ // load header
+ binisstream uf (module, unpacked_length);
+ uf.setFlag (binio::BigEndian, false);
+ uf.setFlag (binio::FloatIEEE);
+
+ memset (&header, 0, sizeof (s3mheader));
+
+ uf.ignore (22); // ignore DMO header ID string
+ uf.readString (header.name, 28);
+
+ uf.ignore (2); // _unk_1
+ header.ordnum = uf.readInt (2);
+ header.insnum = uf.readInt (2);
+ header.patnum = uf.readInt (2);
+ uf.ignore (2); // _unk_2
+ header.is = uf.readInt (2);
+ header.it = uf.readInt (2);
+
+ memset (header.chanset, 0xFF, 32);
+
+ for (i = 0; i < 9; i++)
+ header.chanset[i] = 0x10 + i;
+
+ uf.ignore (32); // ignore panning settings for all 32 channels
+
+ // load orders
+ for (i = 0; i < 256; i++)
+ orders[i] = uf.readInt (1);
+
+ orders[header.ordnum] = 0xFF;
+
+ // load pattern lengths
+ unsigned short my_patlen[100];
+ for (i = 0; i < 100; i++)
+ my_patlen[i] = uf.readInt (2);
+
+ // load instruments
+ for (i = 0; i < header.insnum; i++)
+ {
+ memset (&inst[i], 0, sizeof (s3minst));
+
+ uf.readString (inst[i].name, 28);
+
+ inst[i].volume = uf.readInt (1);
+ inst[i].dsk = uf.readInt (1);
+ inst[i].c2spd = uf.readInt (4);
+ inst[i].type = uf.readInt (1);
+ inst[i].d00 = uf.readInt (1);
+ inst[i].d01 = uf.readInt (1);
+ inst[i].d02 = uf.readInt (1);
+ inst[i].d03 = uf.readInt (1);
+ inst[i].d04 = uf.readInt (1);
+ inst[i].d05 = uf.readInt (1);
+ inst[i].d06 = uf.readInt (1);
+ inst[i].d07 = uf.readInt (1);
+ inst[i].d08 = uf.readInt (1);
+ inst[i].d09 = uf.readInt (1);
+ inst[i].d0a = uf.readInt (1);
+ /*
+ * Originally, riven sets d0b = d0a and ignores 1 byte in the
+ * stream, but i guess this was a typo, so i read it here.
+ */
+ inst[i].d0b = uf.readInt (1);
+ }
+
+ // load patterns
+ for (i = 0; i < header.patnum; i++)
+ {
+ long cur_pos = uf.pos ();
+
+ for (j = 0; j < 64; j++)
+ {
+ while (1)
+ {
+ unsigned char token = uf.readInt (1);
+
+ if (!token)
+ break;
+
+ unsigned char chan = token & 31;
+
+ // note + instrument ?
+ if (token & 32)
+ {
+ unsigned char bufbyte = uf.readInt (1);
+
+ pattern[i][j][chan].note = bufbyte & 15;
+ pattern[i][j][chan].oct = bufbyte >> 4;
+ pattern[i][j][chan].instrument = uf.readInt (1);
+ }
+
+ // volume ?
+ if (token & 64)
+ pattern[i][j][chan].volume = uf.readInt (1);
+
+ // command ?
+ if (token & 128)
+ {
+ pattern[i][j][chan].command = uf.readInt (1);
+ pattern[i][j][chan].info = uf.readInt (1);
+ }
+ }
+ }
+
+ uf.seek (cur_pos + my_patlen[i]);
+ }
+
+ delete[]module;
+ rewind (0);
+ return true;
+}
+
+std::string CdmoLoader::gettype ()
+{
+ return std::string ("TwinTeam (packed S3M)");
+}
+
+std::string CdmoLoader::getauthor ()
+{
+ /*
+ All available .DMO modules written by one composer. And because all .DMO
+ stuff was lost due to hd crash (TwinTeam guys said this), there are
+ never(?) be another.
+ */
+ return std::string ("Benjamin GERARDIN");
+}
+
+/* -------- Private Methods ------------------------------- */
+
+unsigned short
+CdmoLoader::dmo_unpacker::brand (unsigned short range)
+{
+ unsigned short
+ ax,
+ bx,
+ cx,
+ dx;
+
+ ax = LOWORD (bseed);
+ bx = HIWORD (bseed);
+ cx = ax;
+ ax = LOWORD (cx * 0x8405);
+ dx = HIWORD (cx * 0x8405);
+ cx <<= 3;
+ cx = (((HIBYTE (cx) + LOBYTE (cx)) & 0xFF) << 8) + LOBYTE (cx);
+ dx += cx;
+ dx += bx;
+ bx <<= 2;
+ dx += bx;
+ dx = (((HIBYTE (dx) + LOBYTE (bx)) & 0xFF) << 8) + LOBYTE (dx);
+ bx <<= 5;
+ dx = (((HIBYTE (dx) + LOBYTE (bx)) & 0xFF) << 8) + LOBYTE (dx);
+ ax += 1;
+ if (!ax)
+ dx += 1;
+
+ // leave it that way or amd64 might get it wrong
+ bseed = dx;
+ bseed <<= 16;
+ bseed += ax;
+
+ return HIWORD (HIWORD (LOWORD (bseed) * range) + HIWORD (bseed) * range);
+}
+
+bool
+CdmoLoader::dmo_unpacker::decrypt (unsigned char *buf, long len)
+{
+ unsigned long
+ seed = 0;
+ int
+ i;
+
+ bseed = ARRAY_AS_DWORD (buf, 0);
+
+ for (i = 0; i < ARRAY_AS_WORD (buf, 4) + 1; i++)
+ seed += brand (0xffff);
+
+ bseed = seed ^ ARRAY_AS_DWORD (buf, 6);
+
+ if (ARRAY_AS_WORD (buf, 10) != brand (0xffff))
+ return false;
+
+ for (i = 0; i < (len - 12); i++)
+ buf[12 + i] ^= brand (0x100);
+
+ buf[len - 2] = buf[len - 1] = 0;
+
+ return true;
+}
+
+short
+CdmoLoader::dmo_unpacker::unpack_block (unsigned char *ibuf, long ilen,
+ unsigned char *obuf)
+{
+ unsigned char
+ code,
+ par1,
+ par2;
+ unsigned short
+ ax,
+ bx,
+ cx;
+
+ unsigned char *
+ ipos = ibuf;
+ unsigned char *
+ opos = obuf;
+
+ // LZ77 child
+ while (ipos - ibuf < ilen)
+ {
+ code = *ipos++;
+
+ // 00xxxxxx: copy (xxxxxx + 1) bytes
+ if ((code >> 6) == 0)
+ {
+ cx = (code & 0x3F) + 1;
+
+ if (opos + cx >= oend)
+ return -1;
+
+ for (int i = 0; i < cx; i++)
+ *opos++ = *ipos++;
+
+ continue;
+ }
+
+ // 01xxxxxx xxxyyyyy: copy (Y + 3) bytes from (X + 1)
+ if ((code >> 6) == 1)
+ {
+ par1 = *ipos++;
+
+ ax = ((code & 0x3F) << 3) + ((par1 & 0xE0) >> 5) + 1;
+ cx = (par1 & 0x1F) + 3;
+
+ if (opos + cx >= oend)
+ return -1;
+
+ for (int i = 0; i < cx; i++) {
+ *opos = *(opos - ax);
+ opos++;
+ }
+
+ continue;
+ }
+
+ // 10xxxxxx xyyyzzzz: copy (Y + 3) bytes from (X + 1); copy Z bytes
+ if ((code >> 6) == 2)
+ {
+ int
+ i;
+
+ par1 = *ipos++;
+
+ ax = ((code & 0x3F) << 1) + (par1 >> 7) + 1;
+ cx = ((par1 & 0x70) >> 4) + 3;
+ bx = par1 & 0x0F;
+
+ if (opos + bx + cx >= oend)
+ return -1;
+
+ for (i = 0; i < cx; i++) {
+ *opos = *(opos - ax);
+ opos++;
+ }
+
+ for (i = 0; i < bx; i++)
+ *opos++ = *ipos++;
+
+ continue;
+ }
+
+ // 11xxxxxx xxxxxxxy yyyyzzzz: copy (Y + 4) from X; copy Z bytes
+ if ((code >> 6) == 3)
+ {
+ int
+ i;
+
+ par1 = *ipos++;
+ par2 = *ipos++;
+
+ bx = ((code & 0x3F) << 7) + (par1 >> 1);
+ cx = ((par1 & 0x01) << 4) + (par2 >> 4) + 4;
+ ax = par2 & 0x0F;
+
+ if (opos + ax + cx >= oend)
+ return -1;
+
+ for (i = 0; i < cx; i++) {
+ *opos = *(opos - bx);
+ opos++;
+ }
+
+ for (i = 0; i < ax; i++)
+ *opos++ = *ipos++;
+
+ continue;
+ }
+ }
+
+ return opos - obuf;
+}
+
+long
+CdmoLoader::dmo_unpacker::unpack (unsigned char *ibuf, unsigned char *obuf,
+ unsigned long outputsize)
+{
+ long
+ olen = 0;
+ unsigned short
+ block_count = CHARP_AS_WORD (ibuf);
+
+ ibuf += 2;
+ unsigned char *
+ block_length = ibuf;
+ ibuf += 2 * block_count;
+
+ oend = obuf + outputsize;
+
+ for (int i = 0; i < block_count; i++)
+ {
+ unsigned short
+ bul = CHARP_AS_WORD (ibuf);
+
+ if (unpack_block (ibuf + 2, CHARP_AS_WORD (block_length) - 2, obuf) !=
+ bul)
+ return 0;
+
+ obuf += bul;
+ olen += bul;
+
+ ibuf += CHARP_AS_WORD (block_length);
+ block_length += 2;
+ }
+
+ return olen;
+}
diff --git a/src/adplug/core/dmo.cxx b/src/adplug/core/dmo.cxx
deleted file mode 100644
index 9d39d38841fe..000000000000
--- a/src/adplug/core/dmo.cxx
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- Adplug - Replayer for many OPL2/OPL3 audio file formats.
- Copyright (C) 1999 - 2004, 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- dmo.cpp - TwinTeam loader by Riven the Mage <riven at ok.ru>
-*/
-/*
- NOTES:
- Panning is ignored.
-
- A WORD ist 16 bits, a DWORD is 32 bits and a BYTE is 8 bits in this context.
-*/
-
-#include <string.h>
-#include <binstr.h>
-
-#include "dmo.h"
-#include "debug.h"
-
-#define LOWORD(l) ((l) & 0xffff)
-#define HIWORD(l) ((l) >> 16)
-#define LOBYTE(w) ((w) & 0xff)
-#define HIBYTE(w) ((w) >> 8)
-
-#define ARRAY_AS_DWORD(a, i) \
-((a[i + 3] << 24) + (a[i + 2] << 16) + (a[i + 1] << 8) + a[i])
-#define ARRAY_AS_WORD(a, i) ((a[i + 1] << 8) + a[i])
-
-#define CHARP_AS_WORD(p) (((*(p + 1)) << 8) + (*p))
-
-/* -------- Public Methods -------------------------------- */
-
-CPlayer *
-CdmoLoader::factory (Copl * newopl)
-{
- return new CdmoLoader (newopl);
-}
-
-bool
-CdmoLoader::load (VFSFile * fd, const CFileProvider & fp)
-{
- int i, j;
- binistream *f;
- std::string filename (vfs_get_filename (fd));
-
- // check header
- dmo_unpacker *unpacker = new dmo_unpacker;
- unsigned char chkhdr[16];
-
- f = fp.open (fd);
- if (!f)
- {
- delete unpacker;
- return false;
- }
- if (!fp.extension (filename, ".dmo"))
- {
- delete unpacker;
- return false;
- }
-
- f->readString ((char *) chkhdr, 16);
-
- if (!unpacker->decrypt (chkhdr, 16))
- {
- delete unpacker;
- fp.close (f);
- return false;
- }
-
- // get file size
- long packed_length = fp.filesize (f);
- f->seek (0);
-
- unsigned char *packed_module = new unsigned char[packed_length];
-
- // load file
- f->readString ((char *) packed_module, packed_length);
- fp.close (f);
-
- // decrypt
- unpacker->decrypt (packed_module, packed_length);
-
- long unpacked_length = 0x2000 * ARRAY_AS_WORD (packed_module, 12);
- unsigned char *module = new unsigned char[unpacked_length];
-
- // unpack
- if (!unpacker->unpack (packed_module + 12, module, unpacked_length))
- {
- delete unpacker;
- delete[]packed_module;
- delete[]module;
- return false;
- }
-
- delete unpacker;
- delete[]packed_module;
-
- // "TwinTeam" - signed ?
- if (memcmp (module, "TwinTeam Module File" "\x0D\x0A", 22))
- {
- delete module;
- return false;
- }
-
- // load header
- binisstream uf (module, unpacked_length);
- uf.setFlag (binio::BigEndian, false);
- uf.setFlag (binio::FloatIEEE);
-
- memset (&header, 0, sizeof (s3mheader));
-
- uf.ignore (22); // ignore DMO header ID string
- uf.readString (header.name, 28);
-
- uf.ignore (2); // _unk_1
- header.ordnum = uf.readInt (2);
- header.insnum = uf.readInt (2);
- header.patnum = uf.readInt (2);
- uf.ignore (2); // _unk_2
- header.is = uf.readInt (2);
- header.it = uf.readInt (2);
-
- memset (header.chanset, 0xFF, 32);
-
- for (i = 0; i < 9; i++)
- header.chanset[i] = 0x10 + i;
-
- uf.ignore (32); // ignore panning settings for all 32 channels
-
- // load orders
- for (i = 0; i < 256; i++)
- orders[i] = uf.readInt (1);
-
- orders[header.ordnum] = 0xFF;
-
- // load pattern lengths
- unsigned short my_patlen[100];
- for (i = 0; i < 100; i++)
- my_patlen[i] = uf.readInt (2);
-
- // load instruments
- for (i = 0; i < header.insnum; i++)
- {
- memset (&inst[i], 0, sizeof (s3minst));
-
- uf.readString (inst[i].name, 28);
-
- inst[i].volume = uf.readInt (1);
- inst[i].dsk = uf.readInt (1);
- inst[i].c2spd = uf.readInt (4);
- inst[i].type = uf.readInt (1);
- inst[i].d00 = uf.readInt (1);
- inst[i].d01 = uf.readInt (1);
- inst[i].d02 = uf.readInt (1);
- inst[i].d03 = uf.readInt (1);
- inst[i].d04 = uf.readInt (1);
- inst[i].d05 = uf.readInt (1);
- inst[i].d06 = uf.readInt (1);
- inst[i].d07 = uf.readInt (1);
- inst[i].d08 = uf.readInt (1);
- inst[i].d09 = uf.readInt (1);
- inst[i].d0a = uf.readInt (1);
- /*
- * Originally, riven sets d0b = d0a and ignores 1 byte in the
- * stream, but i guess this was a typo, so i read it here.
- */
- inst[i].d0b = uf.readInt (1);
- }
-
- // load patterns
- for (i = 0; i < header.patnum; i++)
- {
- long cur_pos = uf.pos ();
-
- for (j = 0; j < 64; j++)
- {
- while (1)
- {
- unsigned char token = uf.readInt (1);
-
- if (!token)
- break;
-
- unsigned char chan = token & 31;
-
- // note + instrument ?
- if (token & 32)
- {
- unsigned char bufbyte = uf.readInt (1);
-
- pattern[i][j][chan].note = bufbyte & 15;
- pattern[i][j][chan].oct = bufbyte >> 4;
- pattern[i][j][chan].instrument = uf.readInt (1);
- }
-
- // volume ?
- if (token & 64)
- pattern[i][j][chan].volume = uf.readInt (1);
-
- // command ?
- if (token & 128)
- {
- pattern[i][j][chan].command = uf.readInt (1);
- pattern[i][j][chan].info = uf.readInt (1);
- }
- }
- }
-
- uf.seek (cur_pos + my_patlen[i]);
- }
-
- delete[]module;
- rewind (0);
- return true;
-}
-
-std::string CdmoLoader::gettype ()
-{
- return std::string ("TwinTeam (packed S3M)");
-}
-
-std::string CdmoLoader::getauthor ()
-{
- /*
- All available .DMO modules written by one composer. And because all .DMO
- stuff was lost due to hd crash (TwinTeam guys said this), there are
- never(?) be another.
- */
- return std::string ("Benjamin GERARDIN");
-}
-
-/* -------- Private Methods ------------------------------- */
-
-unsigned short
-CdmoLoader::dmo_unpacker::brand (unsigned short range)
-{
- unsigned short
- ax,
- bx,
- cx,
- dx;
-
- ax = LOWORD (bseed);
- bx = HIWORD (bseed);
- cx = ax;
- ax = LOWORD (cx * 0x8405);
- dx = HIWORD (cx * 0x8405);
- cx <<= 3;
- cx = (((HIBYTE (cx) + LOBYTE (cx)) & 0xFF) << 8) + LOBYTE (cx);
- dx += cx;
- dx += bx;
- bx <<= 2;
- dx += bx;
- dx = (((HIBYTE (dx) + LOBYTE (bx)) & 0xFF) << 8) + LOBYTE (dx);
- bx <<= 5;
- dx = (((HIBYTE (dx) + LOBYTE (bx)) & 0xFF) << 8) + LOBYTE (dx);
- ax += 1;
- if (!ax)
- dx += 1;
-
- // leave it that way or amd64 might get it wrong
- bseed = dx;
- bseed <<= 16;
- bseed += ax;
-
- return HIWORD (HIWORD (LOWORD (bseed) * range) + HIWORD (bseed) * range);
-}
-
-bool
-CdmoLoader::dmo_unpacker::decrypt (unsigned char *buf, long len)
-{
- unsigned long
- seed = 0;
- int
- i;
-
- bseed = ARRAY_AS_DWORD (buf, 0);
-
- for (i = 0; i < ARRAY_AS_WORD (buf, 4) + 1; i++)
- seed += brand (0xffff);
-
- bseed = seed ^ ARRAY_AS_DWORD (buf, 6);
-
- if (ARRAY_AS_WORD (buf, 10) != brand (0xffff))
- return false;
-
- for (i = 0; i < (len - 12); i++)
- buf[12 + i] ^= brand (0x100);
-
- buf[len - 2] = buf[len - 1] = 0;
-
- return true;
-}
-
-short
-CdmoLoader::dmo_unpacker::unpack_block (unsigned char *ibuf, long ilen,
- unsigned char *obuf)
-{
- unsigned char
- code,
- par1,
- par2;
- unsigned short
- ax,
- bx,
- cx;
-
- unsigned char *
- ipos = ibuf;
- unsigned char *
- opos = obuf;
-
- // LZ77 child
- while (ipos - ibuf < ilen)
- {
- code = *ipos++;
-
- // 00xxxxxx: copy (xxxxxx + 1) bytes
- if ((code >> 6) == 0)
- {
- cx = (code & 0x3F) + 1;
-
- if (opos + cx >= oend)
- return -1;
-
- for (int i = 0; i < cx; i++)
- *opos++ = *ipos++;
-
- continue;
- }
-
- // 01xxxxxx xxxyyyyy: copy (Y + 3) bytes from (X + 1)
- if ((code >> 6) == 1)
- {
- par1 = *ipos++;
-
- ax = ((code & 0x3F) << 3) + ((par1 & 0xE0) >> 5) + 1;
- cx = (par1 & 0x1F) + 3;
-
- if (opos + cx >= oend)
- return -1;
-
- for (int i = 0; i < cx; i++) {
- *opos = *(opos - ax);
- opos++;
- }
-
- continue;
- }
-
- // 10xxxxxx xyyyzzzz: copy (Y + 3) bytes from (X + 1); copy Z bytes
- if ((code >> 6) == 2)
- {
- int
- i;
-
- par1 = *ipos++;
-
- ax = ((code & 0x3F) << 1) + (par1 >> 7) + 1;
- cx = ((par1 & 0x70) >> 4) + 3;
- bx = par1 & 0x0F;
-
- if (opos + bx + cx >= oend)
- return -1;
-
- for (i = 0; i < cx; i++) {
- *opos = *(opos - ax);
- opos++;
- }
-
- for (i = 0; i < bx; i++)
- *opos++ = *ipos++;
-
- continue;
- }
-
- // 11xxxxxx xxxxxxxy yyyyzzzz: copy (Y + 4) from X; copy Z bytes
- if ((code >> 6) == 3)
- {
- int
- i;
-
- par1 = *ipos++;
- par2 = *ipos++;
-
- bx = ((code & 0x3F) << 7) + (par1 >> 1);
- cx = ((par1 & 0x01) << 4) + (par2 >> 4) + 4;
- ax = par2 & 0x0F;
-
- if (opos + ax + cx >= oend)
- return -1;
-
- for (i = 0; i < cx; i++) {
- *opos = *(opos - bx);
- opos++;
- }
-
- for (i = 0; i < ax; i++)
- *opos++ = *ipos++;
-
- continue;
- }
- }
-
- return opos - obuf;
-}
-
-long
-CdmoLoader::dmo_unpacker::unpack (unsigned char *ibuf, unsigned char *obuf,
- unsigned long outputsize)
-{
- long
- olen = 0;
- unsigned short
- block_count = CHARP_AS_WORD (ibuf);
-
- ibuf += 2;
- unsigned char *
- block_length = ibuf;
- ibuf += 2 * block_count;
-
- oend = obuf + outputsize;
-
- for (int i = 0; i < block_count; i++)
- {
- unsigned short
- bul = CHARP_AS_WORD (ibuf);
-
- if (unpack_block (ibuf + 2, CHARP_AS_WORD (block_length) - 2, obuf) !=
- bul)
- return 0;
-
- obuf += bul;
- olen += bul;
-
- ibuf += CHARP_AS_WORD (block_length);
- block_length += 2;
- }
-
- return olen;
-}
diff --git a/src/adplug/core/dmo.h b/src/adplug/core/dmo.h
index 38962a1711bb..2ae068fcda61 100644
--- a/src/adplug/core/dmo.h
+++ b/src/adplug/core/dmo.h
@@ -28,7 +28,7 @@ class CdmoLoader: public Cs3mPlayer
CdmoLoader(Copl *newopl) : Cs3mPlayer(newopl) { };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
std::string gettype();
std::string getauthor();
diff --git a/src/adplug/core/dro.cc b/src/adplug/core/dro.cc
new file mode 100644
index 000000000000..f93bb2c4004d
--- /dev/null
+++ b/src/adplug/core/dro.cc
@@ -0,0 +1,151 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * dro.c - DOSBox Raw OPL Player by Sjoerd van der Berg <harekiet at zophar.net>
+ *
+ * upgraded by matthew gambrell <zeromus at zeromus.org>
+ *
+ * NOTES: 3-oct-04: the DRO format is not yet finalized. beware.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "dro.h"
+
+/*** public methods *************************************/
+
+CPlayer *
+CdroPlayer::factory (Copl * newopl)
+{
+ return new CdroPlayer (newopl);
+}
+
+CdroPlayer::CdroPlayer (Copl * newopl):CPlayer (newopl), data (0)
+{
+ if (opl->gettype () == Copl::TYPE_OPL2)
+ opl3_mode = 0;
+ else
+ opl3_mode = 1;
+}
+
+bool
+CdroPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ char id[8];
+ unsigned long i;
+
+ // file validation section
+ f->readString (id, 8);
+ if (strncmp (id, "DBRAWOPL", 8))
+ {
+ fp.close (f);
+ return false;
+ }
+ int version = f->readInt (4); // not very useful just yet
+ if (version != 0x10000)
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // load section
+ mstotal = f->readInt (4); // Total milliseconds in file
+ length = f->readInt (4); // Total data bytes in file
+ f->ignore (4); // Type of opl data this can contain - ignored
+ data = new unsigned char[length];
+ for (i = 0; i < length; i++)
+ data[i] = f->readInt (1);
+ fp.close (f);
+ rewind (0);
+ return true;
+}
+
+bool
+CdroPlayer::update ()
+{
+ if (delay > 500)
+ {
+ delay -= 500;
+ return true;
+ }
+ else
+ delay = 0;
+
+ while (pos < length)
+ {
+ unsigned char cmd = data[pos++];
+ switch (cmd)
+ {
+ case 0:
+ delay = 1 + data[pos++];
+ return true;
+ case 1:
+ delay = 1 + data[pos] + (data[pos + 1] << 8);
+ pos += 2;
+ return true;
+ case 2:
+ index = 0;
+ opl->setchip (0);
+ break;
+ case 3:
+ index = 1;
+ opl->setchip (1);
+ break;
+ default:
+ if (cmd == 4)
+ cmd = data[pos++]; //data override
+ if (index == 0 || opl3_mode)
+ opl->write (cmd, data[pos++]);
+ break;
+ }
+ }
+
+ return pos < length;
+}
+
+void
+CdroPlayer::rewind (int subsong)
+{
+ delay = 1;
+ pos = index = 0;
+ opl->init ();
+
+ //dro assumes all registers are initialized to 0
+ //registers not initialized to 0 will be corrected
+ //in the data stream
+ for (int i = 0; i < 256; i++)
+ opl->write (i, 0);
+
+ opl->setchip (1);
+ for (int i = 0; i < 256; i++)
+ opl->write (i, 0);
+ opl->setchip (0);
+}
+
+float
+CdroPlayer::getrefresh ()
+{
+ if (delay > 500)
+ return 1000 / 500;
+ else
+ return 1000 / (double) delay;
+}
diff --git a/src/adplug/core/dro.cxx b/src/adplug/core/dro.cxx
deleted file mode 100644
index a45ac741b492..000000000000
--- a/src/adplug/core/dro.cxx
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * dro.c - DOSBox Raw OPL Player by Sjoerd van der Berg <harekiet at zophar.net>
- *
- * upgraded by matthew gambrell <zeromus at zeromus.org>
- *
- * NOTES: 3-oct-04: the DRO format is not yet finalized. beware.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "dro.h"
-
-/*** public methods *************************************/
-
-CPlayer *
-CdroPlayer::factory (Copl * newopl)
-{
- return new CdroPlayer (newopl);
-}
-
-CdroPlayer::CdroPlayer (Copl * newopl):CPlayer (newopl), data (0)
-{
- if (opl->gettype () == Copl::TYPE_OPL2)
- opl3_mode = 0;
- else
- opl3_mode = 1;
-}
-
-bool
-CdroPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- char id[8];
- unsigned long i;
-
- // file validation section
- f->readString (id, 8);
- if (strncmp (id, "DBRAWOPL", 8))
- {
- fp.close (f);
- return false;
- }
- int version = f->readInt (4); // not very useful just yet
- if (version != 0x10000)
- {
- fp.close (f);
- return false;
- }
-
- // load section
- mstotal = f->readInt (4); // Total milliseconds in file
- length = f->readInt (4); // Total data bytes in file
- f->ignore (4); // Type of opl data this can contain - ignored
- data = new unsigned char[length];
- for (i = 0; i < length; i++)
- data[i] = f->readInt (1);
- fp.close (f);
- rewind (0);
- return true;
-}
-
-bool
-CdroPlayer::update ()
-{
- if (delay > 500)
- {
- delay -= 500;
- return true;
- }
- else
- delay = 0;
-
- while (pos < length)
- {
- unsigned char cmd = data[pos++];
- switch (cmd)
- {
- case 0:
- delay = 1 + data[pos++];
- return true;
- case 1:
- delay = 1 + data[pos] + (data[pos + 1] << 8);
- pos += 2;
- return true;
- case 2:
- index = 0;
- opl->setchip (0);
- break;
- case 3:
- index = 1;
- opl->setchip (1);
- break;
- default:
- if (cmd == 4)
- cmd = data[pos++]; //data override
- if (index == 0 || opl3_mode)
- opl->write (cmd, data[pos++]);
- break;
- }
- }
-
- return pos < length;
-}
-
-void
-CdroPlayer::rewind (int subsong)
-{
- delay = 1;
- pos = index = 0;
- opl->init ();
-
- //dro assumes all registers are initialized to 0
- //registers not initialized to 0 will be corrected
- //in the data stream
- for (int i = 0; i < 256; i++)
- opl->write (i, 0);
-
- opl->setchip (1);
- for (int i = 0; i < 256; i++)
- opl->write (i, 0);
- opl->setchip (0);
-}
-
-float
-CdroPlayer::getrefresh ()
-{
- if (delay > 500)
- return 1000 / 500;
- else
- return 1000 / (double) delay;
-}
diff --git a/src/adplug/core/dro.h b/src/adplug/core/dro.h
index af7337e6e226..e1c2bc0f42e3 100644
--- a/src/adplug/core/dro.h
+++ b/src/adplug/core/dro.h
@@ -33,7 +33,7 @@ class CdroPlayer: public CPlayer
delete [] data;
}
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
diff --git a/src/adplug/core/dro2.cc b/src/adplug/core/dro2.cc
new file mode 100644
index 000000000000..a3aab339d22d
--- /dev/null
+++ b/src/adplug/core/dro2.cc
@@ -0,0 +1,142 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * dro2.cpp - DOSBox Raw OPL v2.0 player by Adam Nielsen <malvineous at shikadi.net>
+ */
+
+#include <cstring>
+#include <stdio.h>
+
+#include "dro2.h"
+
+CPlayer *Cdro2Player::factory(Copl *newopl)
+{
+ return new Cdro2Player(newopl);
+}
+
+Cdro2Player::Cdro2Player(Copl *newopl) :
+ CPlayer(newopl),
+ piConvTable(nullptr),
+ data(0)
+{
+}
+
+Cdro2Player::~Cdro2Player()
+{
+ if (this->data) delete[] this->data;
+ if (this->piConvTable) delete[] this->piConvTable;
+}
+
+bool Cdro2Player::load(VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open(fd);
+ if (!f) return false;
+
+ char id[8];
+ f->readString(id, 8);
+ if (strncmp(id, "DBRAWOPL", 8)) {
+ fp.close(f);
+ return false;
+ }
+ int version = f->readInt(4);
+ if (version != 0x2) {
+ fp.close(f);
+ return false;
+ }
+
+ this->iLength = f->readInt(4) * 2; // stored in file as number of byte pairs
+ f->ignore(4); // Length in milliseconds
+ f->ignore(1); /// OPL type (0 == OPL2, 1 == Dual OPL2, 2 == OPL3)
+ int iFormat = f->readInt(1);
+ if (iFormat != 0) {
+ fp.close(f);
+ return false;
+ }
+ int iCompression = f->readInt(1);
+ if (iCompression != 0) {
+ fp.close(f);
+ return false;
+ }
+ this->iCmdDelayS = f->readInt(1);
+ this->iCmdDelayL = f->readInt(1);
+ this->iConvTableLen = f->readInt(1);
+
+ this->piConvTable = new uint8_t[this->iConvTableLen];
+ f->readString((char *)this->piConvTable, this->iConvTableLen);
+
+ this->data = new uint8_t[this->iLength];
+ f->readString((char *)this->data, this->iLength);
+
+ fp.close(f);
+ rewind(0);
+
+ return true;
+}
+
+bool Cdro2Player::update()
+{
+ while (this->iPos < this->iLength) {
+ int iIndex = this->data[this->iPos++];
+ int iValue = this->data[this->iPos++];
+
+ // Short delay
+ if (iIndex == this->iCmdDelayS) {
+ this->iDelay = iValue + 1;
+ return true;
+
+ // Long delay
+ } else if (iIndex == this->iCmdDelayL) {
+ this->iDelay = (iValue + 1) << 8;
+ return true;
+
+ // Normal write
+ } else {
+ if (iIndex & 0x80) {
+ // High bit means use second chip in dual-OPL2 config
+ this->opl->setchip(1);
+ iIndex &= 0x7F;
+ } else {
+ this->opl->setchip(0);
+ }
+ if (iIndex > this->iConvTableLen) {
+ printf("DRO2: Error - index beyond end of codemap table! Corrupted .dro?\n");
+ return false; // EOF
+ }
+ int iReg = this->piConvTable[iIndex];
+ this->opl->write(iReg, iValue);
+ }
+
+ }
+
+ // This won't result in endless-play using Adplay, but IMHO that code belongs
+ // in Adplay itself, not here.
+ return this->iPos < this->iLength;
+}
+
+void Cdro2Player::rewind(int subsong)
+{
+ this->iDelay = 0;
+ this->iPos = 0;
+ opl->init();
+}
+
+float Cdro2Player::getrefresh()
+{
+ if (this->iDelay > 0) return 1000.0 / this->iDelay;
+ else return 1000.0;
+}
diff --git a/src/adplug/core/dro2.cxx b/src/adplug/core/dro2.cxx
deleted file mode 100644
index 8fe27ff0b68b..000000000000
--- a/src/adplug/core/dro2.cxx
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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
- *
- * dro2.cpp - DOSBox Raw OPL v2.0 player by Adam Nielsen <malvineous at shikadi.net>
- */
-
-#include <cstring>
-#include <stdio.h>
-
-#include "dro2.h"
-
-CPlayer *Cdro2Player::factory(Copl *newopl)
-{
- return new Cdro2Player(newopl);
-}
-
-Cdro2Player::Cdro2Player(Copl *newopl) :
- CPlayer(newopl),
- piConvTable(NULL),
- data(0)
-{
-}
-
-Cdro2Player::~Cdro2Player()
-{
- if (this->data) delete[] this->data;
- if (this->piConvTable) delete[] this->piConvTable;
-}
-
-bool Cdro2Player::load(VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open(fd);
- if (!f) return false;
-
- char id[8];
- f->readString(id, 8);
- if (strncmp(id, "DBRAWOPL", 8)) {
- fp.close(f);
- return false;
- }
- int version = f->readInt(4);
- if (version != 0x2) {
- fp.close(f);
- return false;
- }
-
- this->iLength = f->readInt(4) * 2; // stored in file as number of byte pairs
- f->ignore(4); // Length in milliseconds
- f->ignore(1); /// OPL type (0 == OPL2, 1 == Dual OPL2, 2 == OPL3)
- int iFormat = f->readInt(1);
- if (iFormat != 0) {
- fp.close(f);
- return false;
- }
- int iCompression = f->readInt(1);
- if (iCompression != 0) {
- fp.close(f);
- return false;
- }
- this->iCmdDelayS = f->readInt(1);
- this->iCmdDelayL = f->readInt(1);
- this->iConvTableLen = f->readInt(1);
-
- this->piConvTable = new uint8_t[this->iConvTableLen];
- f->readString((char *)this->piConvTable, this->iConvTableLen);
-
- this->data = new uint8_t[this->iLength];
- f->readString((char *)this->data, this->iLength);
-
- fp.close(f);
- rewind(0);
-
- return true;
-}
-
-bool Cdro2Player::update()
-{
- while (this->iPos < this->iLength) {
- int iIndex = this->data[this->iPos++];
- int iValue = this->data[this->iPos++];
-
- // Short delay
- if (iIndex == this->iCmdDelayS) {
- this->iDelay = iValue + 1;
- return true;
-
- // Long delay
- } else if (iIndex == this->iCmdDelayL) {
- this->iDelay = (iValue + 1) << 8;
- return true;
-
- // Normal write
- } else {
- if (iIndex & 0x80) {
- // High bit means use second chip in dual-OPL2 config
- this->opl->setchip(1);
- iIndex &= 0x7F;
- } else {
- this->opl->setchip(0);
- }
- if (iIndex > this->iConvTableLen) {
- printf("DRO2: Error - index beyond end of codemap table! Corrupted .dro?\n");
- return false; // EOF
- }
- int iReg = this->piConvTable[iIndex];
- this->opl->write(iReg, iValue);
- }
-
- }
-
- // This won't result in endless-play using Adplay, but IMHO that code belongs
- // in Adplay itself, not here.
- return this->iPos < this->iLength;
-}
-
-void Cdro2Player::rewind(int subsong)
-{
- this->iDelay = 0;
- this->iPos = 0;
- opl->init();
-}
-
-float Cdro2Player::getrefresh()
-{
- if (this->iDelay > 0) return 1000.0 / this->iDelay;
- else return 1000.0;
-}
diff --git a/src/adplug/core/dro2.h b/src/adplug/core/dro2.h
index c2bd793342ba..1a893108ccd0 100644
--- a/src/adplug/core/dro2.h
+++ b/src/adplug/core/dro2.h
@@ -41,7 +41,7 @@ class Cdro2Player: public CPlayer
Cdro2Player(Copl *newopl);
~Cdro2Player();
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
diff --git a/src/adplug/core/dtm.cc b/src/adplug/core/dtm.cc
new file mode 100644
index 000000000000..9b8bcc58eb6c
--- /dev/null
+++ b/src/adplug/core/dtm.cc
@@ -0,0 +1,338 @@
+/*
+ Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ dtm.cpp - DTM loader by Riven the Mage <riven at ok.ru>
+*/
+/*
+ NOTE: Panning (Ex) effect is ignored.
+*/
+
+#include <string.h>
+
+#include "dtm.h"
+
+/* -------- Public Methods -------------------------------- */
+
+CPlayer *
+CdtmLoader::factory (Copl * newopl)
+{
+ return new CdtmLoader (newopl);
+}
+
+bool
+CdtmLoader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ const unsigned char conv_inst[11] = { 2, 1, 10, 9, 4, 3, 6, 5, 0, 8, 7 };
+ const unsigned short conv_note[12] =
+ { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263,
+0x287, 0x2AE };
+
+ int i, j, k, t = 0;
+
+ // read header
+ f->readString (header.id, 12);
+ header.version = f->readInt (1);
+ f->readString (header.title, 20);
+ f->readString (header.author, 20);
+ header.numpat = f->readInt (1);
+ header.numinst = f->readInt (1);
+
+ // signature exists ? good version ?
+ if (memcmp (header.id, "DeFy DTM ", 9) || header.version != 0x10)
+ {
+ fp.close (f);
+ return false;
+ }
+
+ header.numinst++;
+
+ // load description
+ memset (desc, 0, 80 * 16);
+
+ char bufstr[80];
+
+ for (i = 0; i < 16; i++)
+ {
+ // get line length
+ unsigned char bufstr_length = f->readInt (1);
+
+ if (bufstr_length > 80)
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // read line
+ if (bufstr_length)
+ {
+ f->readString (bufstr, bufstr_length);
+
+ for (j = 0; j < bufstr_length; j++)
+ if (!bufstr[j])
+ bufstr[j] = 0x20;
+
+ bufstr[bufstr_length] = 0;
+
+ strcat (desc, bufstr);
+ }
+
+ strcat (desc, "\n");
+ }
+
+ // init CmodPlayer
+ realloc_instruments (header.numinst);
+ realloc_order (100);
+ realloc_patterns (header.numpat, 64, 9);
+ init_notetable (conv_note);
+ init_trackord ();
+
+ // load instruments
+ for (i = 0; i < header.numinst; i++)
+ {
+ unsigned char name_length = f->readInt (1);
+
+ if (name_length)
+ f->readString (instruments[i].name, name_length);
+
+ instruments[i].name[name_length] = 0;
+
+ for (j = 0; j < 12; j++)
+ instruments[i].data[j] = f->readInt (1);
+
+ for (j = 0; j < 11; j++)
+ inst[i].data[conv_inst[j]] = instruments[i].data[j];
+ }
+
+ // load order
+ for (i = 0; i < 100; i++)
+ order[i] = f->readInt (1);
+
+ nop = header.numpat;
+
+ unsigned char *pattern = new unsigned char[0x480];
+
+ // load tracks
+ for (i = 0; i < nop; i++)
+ {
+ unsigned short packed_length;
+
+ packed_length = f->readInt (2);
+
+ unsigned char *packed_pattern = new unsigned char[packed_length];
+
+ for (j = 0; j < packed_length; j++)
+ packed_pattern[j] = f->readInt (1);
+
+ long unpacked_length =
+ unpack_pattern (packed_pattern, packed_length, pattern, 0x480);
+
+ delete[]packed_pattern;
+
+ if (!unpacked_length)
+ {
+ delete[] pattern;
+ fp.close (f);
+ return false;
+ }
+
+ // convert pattern
+ for (j = 0; j < 9; j++)
+ {
+ for (k = 0; k < 64; k++)
+ {
+ dtm_event *event = (dtm_event *) & pattern[(k * 9 + j) * 2];
+
+ // instrument
+ if (event->byte0 == 0x80)
+ {
+ if (event->byte1 <= 0x80)
+ tracks[t][k].inst = event->byte1 + 1;
+ }
+
+ // note + effect
+ else
+ {
+ tracks[t][k].note = event->byte0;
+
+ if ((event->byte0 != 0) && (event->byte0 != 127))
+ tracks[t][k].note++;
+
+ // convert effects
+ switch (event->byte1 >> 4)
+ {
+ case 0x0: // pattern break
+ if ((event->byte1 & 15) == 1)
+ tracks[t][k].command = 13;
+ break;
+
+ case 0x1: // freq. slide up
+ tracks[t][k].command = 28;
+ tracks[t][k].param1 = event->byte1 & 15;
+ break;
+
+ case 0x2: // freq. slide down
+ tracks[t][k].command = 28;
+ tracks[t][k].param2 = event->byte1 & 15;
+ break;
+
+ case 0xA: // set carrier volume
+ case 0xC: // set instrument volume
+ tracks[t][k].command = 22;
+ tracks[t][k].param1 = (0x3F - (event->byte1 & 15)) >> 4;
+ tracks[t][k].param2 = (0x3F - (event->byte1 & 15)) & 15;
+ break;
+
+ case 0xB: // set modulator volume
+ tracks[t][k].command = 21;
+ tracks[t][k].param1 = (0x3F - (event->byte1 & 15)) >> 4;
+ tracks[t][k].param2 = (0x3F - (event->byte1 & 15)) & 15;
+ break;
+
+ case 0xE: // set panning
+ break;
+
+ case 0xF: // set speed
+ tracks[t][k].command = 13;
+ tracks[t][k].param2 = event->byte1 & 15;
+ break;
+ }
+ }
+ }
+
+ t++;
+ }
+ }
+
+ delete[]pattern;
+ fp.close (f);
+
+ // order length
+ for (i = 0; i < 100; i++)
+ {
+ if (order[i] >= 0x80)
+ {
+ length = i;
+
+ if (order[i] == 0xFF)
+ restartpos = 0;
+ else
+ restartpos = order[i] - 0x80;
+
+ break;
+ }
+ }
+
+ // initial speed
+ initspeed = 2;
+
+ rewind (0);
+
+ return true;
+}
+
+void
+CdtmLoader::rewind (int subsong)
+{
+ CmodPlayer::rewind (subsong);
+
+ // default instruments
+ for (int i = 0; i < 9; i++)
+ {
+ channel[i].inst = i;
+
+ channel[i].vol1 = 63 - (inst[i].data[10] & 63);
+ channel[i].vol2 = 63 - (inst[i].data[9] & 63);
+ }
+}
+
+float
+CdtmLoader::getrefresh ()
+{
+ return 18.2f;
+}
+
+std::string CdtmLoader::gettype ()
+{
+ return std::string ("DeFy Adlib Tracker");
+}
+
+std::string CdtmLoader::gettitle ()
+{
+ return std::string (header.title);
+}
+
+std::string CdtmLoader::getauthor ()
+{
+ return std::string (header.author);
+}
+
+std::string CdtmLoader::getdesc ()
+{
+ return std::string (desc);
+}
+
+std::string CdtmLoader::getinstrument (unsigned int n)
+{
+ return std::string (instruments[n].name);
+}
+
+unsigned int
+CdtmLoader::getinstruments ()
+{
+ return header.numinst;
+}
+
+/* -------- Private Methods ------------------------------- */
+
+long
+CdtmLoader::unpack_pattern (unsigned char *ibuf, long ilen,
+ unsigned char *obuf, long olen)
+{
+ unsigned char *input = ibuf;
+ unsigned char *output = obuf;
+
+ long input_length = 0;
+ long output_length = 0;
+
+ unsigned char repeat_byte, repeat_counter;
+
+ // RLE
+ while (input_length < ilen)
+ {
+ repeat_byte = input[input_length++];
+
+ if ((repeat_byte & 0xF0) == 0xD0)
+ {
+ repeat_counter = repeat_byte & 15;
+ repeat_byte = input[input_length++];
+ }
+ else
+ repeat_counter = 1;
+
+ for (int i = 0; i < repeat_counter; i++)
+ {
+ if (output_length < olen)
+ output[output_length++] = repeat_byte;
+ }
+ }
+
+ return output_length;
+}
diff --git a/src/adplug/core/dtm.cxx b/src/adplug/core/dtm.cxx
deleted file mode 100644
index f91b3a64a452..000000000000
--- a/src/adplug/core/dtm.cxx
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- Adplug - Replayer for many OPL2/OPL3 audio file formats.
- Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- dtm.cpp - DTM loader by Riven the Mage <riven at ok.ru>
-*/
-/*
- NOTE: Panning (Ex) effect is ignored.
-*/
-
-#include <string.h>
-
-#include "dtm.h"
-
-/* -------- Public Methods -------------------------------- */
-
-CPlayer *
-CdtmLoader::factory (Copl * newopl)
-{
- return new CdtmLoader (newopl);
-}
-
-bool
-CdtmLoader::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- const unsigned char conv_inst[11] = { 2, 1, 10, 9, 4, 3, 6, 5, 0, 8, 7 };
- const unsigned short conv_note[12] =
- { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263,
-0x287, 0x2AE };
-
- int i, j, k, t = 0;
-
- // read header
- f->readString (header.id, 12);
- header.version = f->readInt (1);
- f->readString (header.title, 20);
- f->readString (header.author, 20);
- header.numpat = f->readInt (1);
- header.numinst = f->readInt (1);
-
- // signature exists ? good version ?
- if (memcmp (header.id, "DeFy DTM ", 9) || header.version != 0x10)
- {
- fp.close (f);
- return false;
- }
-
- header.numinst++;
-
- // load description
- memset (desc, 0, 80 * 16);
-
- char bufstr[80];
-
- for (i = 0; i < 16; i++)
- {
- // get line length
- unsigned char bufstr_length = f->readInt (1);
-
- if (bufstr_length > 80)
- {
- fp.close (f);
- return false;
- }
-
- // read line
- if (bufstr_length)
- {
- f->readString (bufstr, bufstr_length);
-
- for (j = 0; j < bufstr_length; j++)
- if (!bufstr[j])
- bufstr[j] = 0x20;
-
- bufstr[bufstr_length] = 0;
-
- strcat (desc, bufstr);
- }
-
- strcat (desc, "\n");
- }
-
- // init CmodPlayer
- realloc_instruments (header.numinst);
- realloc_order (100);
- realloc_patterns (header.numpat, 64, 9);
- init_notetable (conv_note);
- init_trackord ();
-
- // load instruments
- for (i = 0; i < header.numinst; i++)
- {
- unsigned char name_length = f->readInt (1);
-
- if (name_length)
- f->readString (instruments[i].name, name_length);
-
- instruments[i].name[name_length] = 0;
-
- for (j = 0; j < 12; j++)
- instruments[i].data[j] = f->readInt (1);
-
- for (j = 0; j < 11; j++)
- inst[i].data[conv_inst[j]] = instruments[i].data[j];
- }
-
- // load order
- for (i = 0; i < 100; i++)
- order[i] = f->readInt (1);
-
- nop = header.numpat;
-
- unsigned char *pattern = new unsigned char[0x480];
-
- // load tracks
- for (i = 0; i < nop; i++)
- {
- unsigned short packed_length;
-
- packed_length = f->readInt (2);
-
- unsigned char *packed_pattern = new unsigned char[packed_length];
-
- for (j = 0; j < packed_length; j++)
- packed_pattern[j] = f->readInt (1);
-
- long unpacked_length =
- unpack_pattern (packed_pattern, packed_length, pattern, 0x480);
-
- delete[]packed_pattern;
-
- if (!unpacked_length)
- {
- delete[] pattern;
- fp.close (f);
- return false;
- }
-
- // convert pattern
- for (j = 0; j < 9; j++)
- {
- for (k = 0; k < 64; k++)
- {
- dtm_event *event = (dtm_event *) & pattern[(k * 9 + j) * 2];
-
- // instrument
- if (event->byte0 == 0x80)
- {
- if (event->byte1 <= 0x80)
- tracks[t][k].inst = event->byte1 + 1;
- }
-
- // note + effect
- else
- {
- tracks[t][k].note = event->byte0;
-
- if ((event->byte0 != 0) && (event->byte0 != 127))
- tracks[t][k].note++;
-
- // convert effects
- switch (event->byte1 >> 4)
- {
- case 0x0: // pattern break
- if ((event->byte1 & 15) == 1)
- tracks[t][k].command = 13;
- break;
-
- case 0x1: // freq. slide up
- tracks[t][k].command = 28;
- tracks[t][k].param1 = event->byte1 & 15;
- break;
-
- case 0x2: // freq. slide down
- tracks[t][k].command = 28;
- tracks[t][k].param2 = event->byte1 & 15;
- break;
-
- case 0xA: // set carrier volume
- case 0xC: // set instrument volume
- tracks[t][k].command = 22;
- tracks[t][k].param1 = (0x3F - (event->byte1 & 15)) >> 4;
- tracks[t][k].param2 = (0x3F - (event->byte1 & 15)) & 15;
- break;
-
- case 0xB: // set modulator volume
- tracks[t][k].command = 21;
- tracks[t][k].param1 = (0x3F - (event->byte1 & 15)) >> 4;
- tracks[t][k].param2 = (0x3F - (event->byte1 & 15)) & 15;
- break;
-
- case 0xE: // set panning
- break;
-
- case 0xF: // set speed
- tracks[t][k].command = 13;
- tracks[t][k].param2 = event->byte1 & 15;
- break;
- }
- }
- }
-
- t++;
- }
- }
-
- delete[]pattern;
- fp.close (f);
-
- // order length
- for (i = 0; i < 100; i++)
- {
- if (order[i] >= 0x80)
- {
- length = i;
-
- if (order[i] == 0xFF)
- restartpos = 0;
- else
- restartpos = order[i] - 0x80;
-
- break;
- }
- }
-
- // initial speed
- initspeed = 2;
-
- rewind (0);
-
- return true;
-}
-
-void
-CdtmLoader::rewind (int subsong)
-{
- CmodPlayer::rewind (subsong);
-
- // default instruments
- for (int i = 0; i < 9; i++)
- {
- channel[i].inst = i;
-
- channel[i].vol1 = 63 - (inst[i].data[10] & 63);
- channel[i].vol2 = 63 - (inst[i].data[9] & 63);
- }
-}
-
-float
-CdtmLoader::getrefresh ()
-{
- return 18.2f;
-}
-
-std::string CdtmLoader::gettype ()
-{
- return std::string ("DeFy Adlib Tracker");
-}
-
-std::string CdtmLoader::gettitle ()
-{
- return std::string (header.title);
-}
-
-std::string CdtmLoader::getauthor ()
-{
- return std::string (header.author);
-}
-
-std::string CdtmLoader::getdesc ()
-{
- return std::string (desc);
-}
-
-std::string CdtmLoader::getinstrument (unsigned int n)
-{
- return std::string (instruments[n].name);
-}
-
-unsigned int
-CdtmLoader::getinstruments ()
-{
- return header.numinst;
-}
-
-/* -------- Private Methods ------------------------------- */
-
-long
-CdtmLoader::unpack_pattern (unsigned char *ibuf, long ilen,
- unsigned char *obuf, long olen)
-{
- unsigned char *input = ibuf;
- unsigned char *output = obuf;
-
- long input_length = 0;
- long output_length = 0;
-
- unsigned char repeat_byte, repeat_counter;
-
- // RLE
- while (input_length < ilen)
- {
- repeat_byte = input[input_length++];
-
- if ((repeat_byte & 0xF0) == 0xD0)
- {
- repeat_counter = repeat_byte & 15;
- repeat_byte = input[input_length++];
- }
- else
- repeat_counter = 1;
-
- for (int i = 0; i < repeat_counter; i++)
- {
- if (output_length < olen)
- output[output_length++] = repeat_byte;
- }
- }
-
- return output_length;
-}
diff --git a/src/adplug/core/dtm.h b/src/adplug/core/dtm.h
index 1aa31541586a..de33dfea735c 100644
--- a/src/adplug/core/dtm.h
+++ b/src/adplug/core/dtm.h
@@ -28,7 +28,7 @@ class CdtmLoader: public CmodPlayer
CdtmLoader(Copl *newopl) : CmodPlayer(newopl) { };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
void rewind(int subsong);
float getrefresh();
diff --git a/src/adplug/core/emuopl.cc b/src/adplug/core/emuopl.cc
new file mode 100644
index 000000000000..c3284c7d3d3a
--- /dev/null
+++ b/src/adplug/core/emuopl.cc
@@ -0,0 +1,166 @@
+/*
+ * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2005 Simon Peter <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * emuopl.cpp - Emulated OPL, by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include "emuopl.h"
+
+CEmuopl::CEmuopl (int rate, bool bit16, bool usestereo):use16bit (bit16), stereo (usestereo),
+mixbufSamples (0)
+{
+ opl[0] = OPLCreate (OPL_TYPE_YM3812, 3579545, rate);
+ opl[1] = OPLCreate (OPL_TYPE_YM3812, 3579545, rate);
+
+ currType = TYPE_DUAL_OPL2;
+
+ init ();
+}
+
+CEmuopl::~CEmuopl ()
+{
+ OPLDestroy (opl[0]);
+ OPLDestroy (opl[1]);
+
+ if (mixbufSamples)
+ {
+ delete[]mixbuf0;
+ delete[]mixbuf1;
+ }
+}
+
+void
+CEmuopl::update (short *buf, int samples)
+{
+ int i;
+
+ //ensure that our mix buffers are adequately sized
+ if (mixbufSamples < samples)
+ {
+ if (mixbufSamples)
+ {
+ delete[]mixbuf0;
+ delete[]mixbuf1;
+ }
+ mixbufSamples = samples;
+
+ //*2 = make room for stereo, if we need it
+ mixbuf0 = new short[samples * 2];
+ mixbuf1 = new short[samples * 2];
+ }
+
+ //data should be rendered to outbuf
+ //tempbuf should be used as a temporary buffer
+ //if we are supposed to generate 16bit output,
+ //then outbuf may point directly to the actual waveform output "buf"
+ //if we are supposed to generate 8bit output,
+ //then outbuf cannot point to "buf" (because there will not be enough room)
+ //and so it must point to a mixbuf instead--
+ //it will be reduced to 8bit and put in "buf" later
+ short *outbuf;
+ short *tempbuf = mixbuf0;
+ short *tempbuf2 = mixbuf1;
+ if (use16bit)
+ outbuf = buf;
+ else
+ outbuf = mixbuf1;
+ //...there is a potentially confusing situation where mixbuf1 can be aliased.
+ //beware. it is a little loony.
+
+ //all of the following rendering code produces 16bit output
+
+ switch (currType)
+ {
+ case TYPE_OPL2:
+ //for opl2 mode:
+ //render chip0 to the output buffer
+ YM3812UpdateOne (opl[0], outbuf, samples);
+
+ //if we are supposed to output stereo,
+ //then we need to dup the mono channel
+ if (stereo)
+ for (i = samples - 1; i >= 0; i--)
+ {
+ outbuf[i * 2] = outbuf[i];
+ outbuf[i * 2 + 1] = outbuf[i];
+ }
+ break;
+
+ case TYPE_OPL3: // unsupported
+ break;
+
+ case TYPE_DUAL_OPL2:
+ //for dual opl2 mode:
+ //render each chip to a different tempbuffer
+ YM3812UpdateOne (opl[0], tempbuf2, samples);
+ YM3812UpdateOne (opl[1], tempbuf, samples);
+
+ //output stereo:
+ //then we need to interleave the two buffers
+ if (stereo)
+ {
+ //first, spread tempbuf's samples across left channel
+ //left channel
+ for (i = 0; i < samples; i++)
+ outbuf[i * 2] = tempbuf2[i];
+ //next, insert the samples from tempbuf2 into right channel
+ for (i = 0; i < samples; i++)
+ outbuf[i * 2 + 1] = tempbuf[i];
+ }
+ else
+ //output mono:
+ //then we need to mix the two buffers into buf
+ for (i = 0; i < samples; i++)
+ outbuf[i] = (tempbuf[i] >> 1) + (tempbuf2[i] >> 1);
+ break;
+ }
+
+ //now reduce to 8bit if we need to
+ if (!use16bit)
+ for (i = 0; i < (stereo ? samples * 2 : samples); i++)
+ ((char *) buf)[i] = (outbuf[i] >> 8) ^ 0x80;
+}
+
+void
+CEmuopl::write (int reg, int val)
+{
+ switch (currType)
+ {
+ case TYPE_OPL2:
+ case TYPE_DUAL_OPL2:
+ OPLWrite (opl[currChip], 0, reg);
+ OPLWrite (opl[currChip], 1, val);
+ break;
+ case TYPE_OPL3: // unsupported
+ break;
+ }
+}
+
+void
+CEmuopl::init ()
+{
+ OPLResetChip (opl[0]);
+ OPLResetChip (opl[1]);
+ currChip = 0;
+}
+
+void
+CEmuopl::settype (ChipType type)
+{
+ currType = type;
+}
diff --git a/src/adplug/core/emuopl.cxx b/src/adplug/core/emuopl.cxx
deleted file mode 100644
index c3284c7d3d3a..000000000000
--- a/src/adplug/core/emuopl.cxx
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2005 Simon Peter <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * emuopl.cpp - Emulated OPL, by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include "emuopl.h"
-
-CEmuopl::CEmuopl (int rate, bool bit16, bool usestereo):use16bit (bit16), stereo (usestereo),
-mixbufSamples (0)
-{
- opl[0] = OPLCreate (OPL_TYPE_YM3812, 3579545, rate);
- opl[1] = OPLCreate (OPL_TYPE_YM3812, 3579545, rate);
-
- currType = TYPE_DUAL_OPL2;
-
- init ();
-}
-
-CEmuopl::~CEmuopl ()
-{
- OPLDestroy (opl[0]);
- OPLDestroy (opl[1]);
-
- if (mixbufSamples)
- {
- delete[]mixbuf0;
- delete[]mixbuf1;
- }
-}
-
-void
-CEmuopl::update (short *buf, int samples)
-{
- int i;
-
- //ensure that our mix buffers are adequately sized
- if (mixbufSamples < samples)
- {
- if (mixbufSamples)
- {
- delete[]mixbuf0;
- delete[]mixbuf1;
- }
- mixbufSamples = samples;
-
- //*2 = make room for stereo, if we need it
- mixbuf0 = new short[samples * 2];
- mixbuf1 = new short[samples * 2];
- }
-
- //data should be rendered to outbuf
- //tempbuf should be used as a temporary buffer
- //if we are supposed to generate 16bit output,
- //then outbuf may point directly to the actual waveform output "buf"
- //if we are supposed to generate 8bit output,
- //then outbuf cannot point to "buf" (because there will not be enough room)
- //and so it must point to a mixbuf instead--
- //it will be reduced to 8bit and put in "buf" later
- short *outbuf;
- short *tempbuf = mixbuf0;
- short *tempbuf2 = mixbuf1;
- if (use16bit)
- outbuf = buf;
- else
- outbuf = mixbuf1;
- //...there is a potentially confusing situation where mixbuf1 can be aliased.
- //beware. it is a little loony.
-
- //all of the following rendering code produces 16bit output
-
- switch (currType)
- {
- case TYPE_OPL2:
- //for opl2 mode:
- //render chip0 to the output buffer
- YM3812UpdateOne (opl[0], outbuf, samples);
-
- //if we are supposed to output stereo,
- //then we need to dup the mono channel
- if (stereo)
- for (i = samples - 1; i >= 0; i--)
- {
- outbuf[i * 2] = outbuf[i];
- outbuf[i * 2 + 1] = outbuf[i];
- }
- break;
-
- case TYPE_OPL3: // unsupported
- break;
-
- case TYPE_DUAL_OPL2:
- //for dual opl2 mode:
- //render each chip to a different tempbuffer
- YM3812UpdateOne (opl[0], tempbuf2, samples);
- YM3812UpdateOne (opl[1], tempbuf, samples);
-
- //output stereo:
- //then we need to interleave the two buffers
- if (stereo)
- {
- //first, spread tempbuf's samples across left channel
- //left channel
- for (i = 0; i < samples; i++)
- outbuf[i * 2] = tempbuf2[i];
- //next, insert the samples from tempbuf2 into right channel
- for (i = 0; i < samples; i++)
- outbuf[i * 2 + 1] = tempbuf[i];
- }
- else
- //output mono:
- //then we need to mix the two buffers into buf
- for (i = 0; i < samples; i++)
- outbuf[i] = (tempbuf[i] >> 1) + (tempbuf2[i] >> 1);
- break;
- }
-
- //now reduce to 8bit if we need to
- if (!use16bit)
- for (i = 0; i < (stereo ? samples * 2 : samples); i++)
- ((char *) buf)[i] = (outbuf[i] >> 8) ^ 0x80;
-}
-
-void
-CEmuopl::write (int reg, int val)
-{
- switch (currType)
- {
- case TYPE_OPL2:
- case TYPE_DUAL_OPL2:
- OPLWrite (opl[currChip], 0, reg);
- OPLWrite (opl[currChip], 1, val);
- break;
- case TYPE_OPL3: // unsupported
- break;
- }
-}
-
-void
-CEmuopl::init ()
-{
- OPLResetChip (opl[0]);
- OPLResetChip (opl[1]);
- currChip = 0;
-}
-
-void
-CEmuopl::settype (ChipType type)
-{
- currType = type;
-}
diff --git a/src/adplug/core/emuopl.h b/src/adplug/core/emuopl.h
index dd2f29e4b9e5..51ea06e3fd19 100644
--- a/src/adplug/core/emuopl.h
+++ b/src/adplug/core/emuopl.h
@@ -1,17 +1,17 @@
/*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
+ *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -23,9 +23,7 @@
#define H_ADPLUG_EMUOPL
#include "opl.h"
-extern "C" {
#include "fmopl.h"
-}
class CEmuopl: public Copl
{
diff --git a/src/adplug/core/flash.cc b/src/adplug/core/flash.cc
new file mode 100644
index 000000000000..30df8b0c3774
--- /dev/null
+++ b/src/adplug/core/flash.cc
@@ -0,0 +1,259 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * [xad] FLASH player, by Riven the Mage <riven at ok.ru>
+ */
+
+/*
+ - discovery -
+
+ file(s) : LA-INTRO.EXE
+ type : Lunatic Asylum BBStro
+ tune : by Rogue [Logic Design]
+ player : by Flash [Logic Design]
+*/
+
+#include "flash.h"
+#include "debug.h"
+
+const unsigned char
+ CxadflashPlayer::flash_adlib_registers[99] = {
+ 0x23, 0x20, 0x43, 0x40, 0x63, 0x60, 0x83, 0x80, 0xC0, 0xE3, 0xE0,
+ 0x24, 0x21, 0x44, 0x41, 0x64, 0x61, 0x84, 0x81, 0xC1, 0xE4, 0xE1,
+ 0x25, 0x22, 0x45, 0x42, 0x65, 0x62, 0x85, 0x82, 0xC2, 0xE5, 0xE2,
+ 0x2B, 0x28, 0x4B, 0x48, 0x6B, 0x68, 0x8B, 0x88, 0xC3, 0xEB, 0xE8,
+ 0x2C, 0x29, 0x4C, 0x49, 0x6C, 0x69, 0x8C, 0x89, 0xC4, 0xEC, 0xE9,
+ 0x2D, 0x2A, 0x4D, 0x4A, 0x6D, 0x6A, 0x8D, 0x8A, 0xC5, 0xED, 0xEA,
+ 0x33, 0x30, 0x53, 0x50, 0x73, 0x70, 0x93, 0x90, 0xC6, 0xF3, 0xF0,
+ 0x34, 0x31, 0x54, 0x51, 0x74, 0x71, 0x94, 0x91, 0xC7, 0xF4, 0xF1,
+ 0x35, 0x32, 0x55, 0x52, 0x75, 0x72, 0x95, 0x92, 0xC8, 0xF5, 0xF2
+};
+
+const unsigned short
+ CxadflashPlayer::flash_notes_encoded[268] = {
+ 0x000,
+ 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800, 0x900, 0xA00, 0xB00,
+ 0xC00,
+ 0x101, 0x201, 0x301, 0x401, 0x501, 0x601, 0x701, 0x801, 0x901, 0xA01, 0xB01,
+ 0xC01,
+ 0x102, 0x202, 0x302, 0x402, 0x502, 0x602, 0x702, 0x802, 0x902, 0xA02, 0xB02,
+ 0xC02,
+ 0x103, 0x203, 0x303, 0x403, 0x503, 0x603, 0x703, 0x803, 0x903, 0xA03, 0xB03,
+ 0xC03,
+ 0x104, 0x204, 0x304, 0x404, 0x504, 0x604, 0x704, 0x804, 0x904, 0xA04, 0xB04,
+ 0xC04,
+ 0x105, 0x205, 0x305, 0x405, 0x505, 0x605, 0x705, 0x805, 0x905, 0xA05, 0xB05,
+ 0xC05,
+ 0x106, 0x206, 0x306, 0x406, 0x506, 0x606, 0x706, 0x806, 0x906, 0xA06, 0xB06,
+ 0xC06,
+ 0x107, 0x207, 0x307, 0x407, 0x507, 0x607, 0x707, 0x807, 0x907, 0xA07, 0xB07,
+ 0xC07,
+ 0x108, 0x208, 0x308, 0x408, 0x508, 0x608, 0x708, 0x808, 0x908, 0xA08, 0xB08,
+ 0xC08,
+ 0x109, 0x209, 0x309, 0x409, 0x509, 0x609, 0x709, 0x809, 0x909, 0xA09, 0xB09,
+ 0xC09,
+ 0x10A, 0x20A, 0x30A, 0x40A, 0x50A, 0x60A, 0x70A, 0x80A, 0x90A, 0xA0A, 0xB0A,
+ 0xC0A,
+ 0x10B, 0x20B, 0x30B, 0x40B, 0x50B, 0x60B, 0x70B, 0x80B, 0x90B, 0xA0B, 0xB0B,
+ 0xC0B,
+ 0x10C, 0x20C, 0x30C, 0x40C, 0x50C, 0x60C, 0x70C, 0x80C, 0x90C, 0xA0C, 0xB0C,
+ 0xC0C,
+ 0x10D, 0x20D, 0x30D, 0x40D, 0x50D, 0x60D, 0x70D, 0x80D, 0x90D, 0xA0D, 0xB0D,
+ 0xC0D,
+ 0x10E, 0x20E, 0x30E, 0x40E, 0x50E, 0x60E, 0x70E, 0x80E, 0x90E, 0xA0E, 0xB0E,
+ 0xC0E,
+ 0x10F, 0x20F, 0x30F, 0x40F, 0x50F, 0x60F, 0x70F, 0x80F, 0x90F, 0xA0F, 0xB0F,
+ 0xC0F,
+ 0x110, 0x210, 0x310, 0x410, 0x510, 0x610, 0x710, 0x810, 0x910, 0xA10, 0xB10,
+ 0xC10,
+ 0x111, 0x211, 0x311, 0x411, 0x511, 0x611, 0x711, 0x811, 0x911, 0xA11, 0xB11,
+ 0xC11,
+ 0x112, 0x212, 0x312, 0x412, 0x512, 0x612, 0x712, 0x812, 0x912, 0xA12, 0xB12,
+ 0xC12,
+ 0x113, 0x213, 0x313, 0x413, 0x513, 0x613, 0x713, 0x813, 0x913, 0xA13, 0xB13,
+ 0xC13,
+ 0x114, 0x214, 0x314, 0x414, 0x514, 0x614, 0x714, 0x814, 0x914, 0xA14, 0xB14,
+ 0xC14,
+ 0x115, 0x215, 0x315
+};
+
+const unsigned short
+ CxadflashPlayer::flash_notes[12] = {
+ 0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263,
+ 0x287
+};
+
+const unsigned char
+ CxadflashPlayer::flash_default_instrument[8] = {
+ 0x00, 0x00, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+CPlayer *
+CxadflashPlayer::factory (Copl * newopl)
+{
+ return new CxadflashPlayer (newopl);
+}
+
+void
+CxadflashPlayer::xadplayer_rewind (int subsong)
+{
+ int i;
+
+ plr.speed = xad.speed;
+
+ flash.order_pos = 0;
+ flash.pattern_pos = 0;
+
+ opl_write (0x08, 0x00);
+ opl_write (0xBD, 0x00);
+
+ // assign default instrument
+ for (i = 0; i < 9; i++)
+ {
+ opl_write (0xA0 + i, 0x00);
+ opl_write (0xB0 + i, 0x00);
+ }
+
+ // assign instruments
+ for (i = 0; i < 9; i++)
+ for (int j = 0; j < 11; j++)
+ opl_write (flash_adlib_registers[i * 11 + j], tune[i * 12 + j]);
+}
+
+void
+CxadflashPlayer::xadplayer_update ()
+{
+ unsigned short event_pos = (tune[0x600 + flash.order_pos] * 1152) +
+ (flash.pattern_pos * 18) + 0x633;
+
+ for (int i = 0; i < 9; i++)
+ {
+ unsigned short flash_channel_freq =
+ (adlib[0xB0 + i] << 8) + adlib[0xA0 + i];
+
+ unsigned char event_b0 = tune[event_pos++];
+ unsigned char event_b1 = tune[event_pos++];
+#ifdef DEBUG
+ AdPlug_LogWrite ("channel %02X, event %02X %02X:\n", i + 1, event_b0,
+ event_b1);
+#endif
+
+ if (event_b0 == 0x80) // 0.0x80: Set Instrument
+ {
+ for (int j = 0; j < 11; j++)
+ opl_write (flash_adlib_registers[i * 11 + j],
+ tune[event_b1 * 12 + j]);
+ }
+ else
+ {
+ if (event_b1 == 0x01)
+ flash.pattern_pos = 0x3F; // 1.0x01: Pattern Break
+
+ unsigned char fx = (event_b1 >> 4);
+ unsigned char fx_p = (event_b1 & 0x0F);
+
+ switch (fx)
+ {
+ case 0x0A: // 1.0xAy: Set Carrier volume
+ opl_write (flash_adlib_registers[11 * i + 2], fx_p << 2);
+ break;
+ case 0x0B: // 1.0xBy: Set Modulator volume
+ opl_write (flash_adlib_registers[11 * i + 3], fx_p << 2);
+ break;
+ case 0x0C: // 1.0xCy: Set both operators volume
+ opl_write (flash_adlib_registers[11 * i + 2], fx_p << 2);
+ opl_write (flash_adlib_registers[11 * i + 3], fx_p << 2);
+ break;
+// case 0x0E: // 1.0xEy: ? (increase some value)
+ case 0x0F: // 1.0xFy: Set Speed
+ plr.speed = (fx_p + 1);
+ break;
+ }
+
+ if (event_b0)
+ {
+ // mute channel
+ opl_write (0xA0 + i, adlib[0xA0 + i]);
+ opl_write (0xB0 + i, adlib[0xB0 + i] & 0xDF);
+
+ // is note ?
+ if (event_b0 != 0x7F)
+ {
+ unsigned short note_encoded = flash_notes_encoded[event_b0];
+ unsigned short freq = flash_notes[(note_encoded >> 8) - 1];
+
+ flash_channel_freq = freq | ((note_encoded & 0xFF) << 10) | 0x2000;
+
+ opl_write (0xA0 + i, flash_channel_freq & 0xFF);
+ opl_write (0xB0 + i, flash_channel_freq >> 8);
+ }
+ }
+
+ if (fx == 0x01) // 1.0x1y: Fine Frequency Slide Up
+ {
+ flash_channel_freq += (fx_p << 1);
+
+ opl_write (0xA0 + i, flash_channel_freq & 0xFF);
+ opl_write (0xB0 + i, flash_channel_freq >> 8);
+ }
+ else if (fx == 0x02) // 1.0x2y: Fine Frequency Slide Down
+ {
+ flash_channel_freq -= (fx_p << 1);
+
+ opl_write (0xA0 + i, flash_channel_freq & 0xFF);
+ opl_write (0xB0 + i, flash_channel_freq >> 8);
+ }
+ }
+ }
+
+ // next row
+ flash.pattern_pos++;
+
+ // end of pattern ?
+ if (flash.pattern_pos >= 0x40)
+ {
+ flash.pattern_pos = 0;
+
+ flash.order_pos++;
+
+ // end of module ?
+ if (tune[0x600 + flash.order_pos] == 0xFF)
+ {
+ flash.order_pos = 0;
+
+ plr.looping = 1;
+ }
+ }
+}
+
+float
+CxadflashPlayer::xadplayer_getrefresh ()
+{
+ return 17.5f;
+}
+
+std::string CxadflashPlayer::xadplayer_gettype ()
+{
+ return std::string ("xad: flash player");
+}
+
+unsigned int
+CxadflashPlayer::xadplayer_getinstruments ()
+{
+ return 32;
+}
diff --git a/src/adplug/core/flash.cxx b/src/adplug/core/flash.cxx
deleted file mode 100644
index 30df8b0c3774..000000000000
--- a/src/adplug/core/flash.cxx
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * [xad] FLASH player, by Riven the Mage <riven at ok.ru>
- */
-
-/*
- - discovery -
-
- file(s) : LA-INTRO.EXE
- type : Lunatic Asylum BBStro
- tune : by Rogue [Logic Design]
- player : by Flash [Logic Design]
-*/
-
-#include "flash.h"
-#include "debug.h"
-
-const unsigned char
- CxadflashPlayer::flash_adlib_registers[99] = {
- 0x23, 0x20, 0x43, 0x40, 0x63, 0x60, 0x83, 0x80, 0xC0, 0xE3, 0xE0,
- 0x24, 0x21, 0x44, 0x41, 0x64, 0x61, 0x84, 0x81, 0xC1, 0xE4, 0xE1,
- 0x25, 0x22, 0x45, 0x42, 0x65, 0x62, 0x85, 0x82, 0xC2, 0xE5, 0xE2,
- 0x2B, 0x28, 0x4B, 0x48, 0x6B, 0x68, 0x8B, 0x88, 0xC3, 0xEB, 0xE8,
- 0x2C, 0x29, 0x4C, 0x49, 0x6C, 0x69, 0x8C, 0x89, 0xC4, 0xEC, 0xE9,
- 0x2D, 0x2A, 0x4D, 0x4A, 0x6D, 0x6A, 0x8D, 0x8A, 0xC5, 0xED, 0xEA,
- 0x33, 0x30, 0x53, 0x50, 0x73, 0x70, 0x93, 0x90, 0xC6, 0xF3, 0xF0,
- 0x34, 0x31, 0x54, 0x51, 0x74, 0x71, 0x94, 0x91, 0xC7, 0xF4, 0xF1,
- 0x35, 0x32, 0x55, 0x52, 0x75, 0x72, 0x95, 0x92, 0xC8, 0xF5, 0xF2
-};
-
-const unsigned short
- CxadflashPlayer::flash_notes_encoded[268] = {
- 0x000,
- 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800, 0x900, 0xA00, 0xB00,
- 0xC00,
- 0x101, 0x201, 0x301, 0x401, 0x501, 0x601, 0x701, 0x801, 0x901, 0xA01, 0xB01,
- 0xC01,
- 0x102, 0x202, 0x302, 0x402, 0x502, 0x602, 0x702, 0x802, 0x902, 0xA02, 0xB02,
- 0xC02,
- 0x103, 0x203, 0x303, 0x403, 0x503, 0x603, 0x703, 0x803, 0x903, 0xA03, 0xB03,
- 0xC03,
- 0x104, 0x204, 0x304, 0x404, 0x504, 0x604, 0x704, 0x804, 0x904, 0xA04, 0xB04,
- 0xC04,
- 0x105, 0x205, 0x305, 0x405, 0x505, 0x605, 0x705, 0x805, 0x905, 0xA05, 0xB05,
- 0xC05,
- 0x106, 0x206, 0x306, 0x406, 0x506, 0x606, 0x706, 0x806, 0x906, 0xA06, 0xB06,
- 0xC06,
- 0x107, 0x207, 0x307, 0x407, 0x507, 0x607, 0x707, 0x807, 0x907, 0xA07, 0xB07,
- 0xC07,
- 0x108, 0x208, 0x308, 0x408, 0x508, 0x608, 0x708, 0x808, 0x908, 0xA08, 0xB08,
- 0xC08,
- 0x109, 0x209, 0x309, 0x409, 0x509, 0x609, 0x709, 0x809, 0x909, 0xA09, 0xB09,
- 0xC09,
- 0x10A, 0x20A, 0x30A, 0x40A, 0x50A, 0x60A, 0x70A, 0x80A, 0x90A, 0xA0A, 0xB0A,
- 0xC0A,
- 0x10B, 0x20B, 0x30B, 0x40B, 0x50B, 0x60B, 0x70B, 0x80B, 0x90B, 0xA0B, 0xB0B,
- 0xC0B,
- 0x10C, 0x20C, 0x30C, 0x40C, 0x50C, 0x60C, 0x70C, 0x80C, 0x90C, 0xA0C, 0xB0C,
- 0xC0C,
- 0x10D, 0x20D, 0x30D, 0x40D, 0x50D, 0x60D, 0x70D, 0x80D, 0x90D, 0xA0D, 0xB0D,
- 0xC0D,
- 0x10E, 0x20E, 0x30E, 0x40E, 0x50E, 0x60E, 0x70E, 0x80E, 0x90E, 0xA0E, 0xB0E,
- 0xC0E,
- 0x10F, 0x20F, 0x30F, 0x40F, 0x50F, 0x60F, 0x70F, 0x80F, 0x90F, 0xA0F, 0xB0F,
- 0xC0F,
- 0x110, 0x210, 0x310, 0x410, 0x510, 0x610, 0x710, 0x810, 0x910, 0xA10, 0xB10,
- 0xC10,
- 0x111, 0x211, 0x311, 0x411, 0x511, 0x611, 0x711, 0x811, 0x911, 0xA11, 0xB11,
- 0xC11,
- 0x112, 0x212, 0x312, 0x412, 0x512, 0x612, 0x712, 0x812, 0x912, 0xA12, 0xB12,
- 0xC12,
- 0x113, 0x213, 0x313, 0x413, 0x513, 0x613, 0x713, 0x813, 0x913, 0xA13, 0xB13,
- 0xC13,
- 0x114, 0x214, 0x314, 0x414, 0x514, 0x614, 0x714, 0x814, 0x914, 0xA14, 0xB14,
- 0xC14,
- 0x115, 0x215, 0x315
-};
-
-const unsigned short
- CxadflashPlayer::flash_notes[12] = {
- 0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263,
- 0x287
-};
-
-const unsigned char
- CxadflashPlayer::flash_default_instrument[8] = {
- 0x00, 0x00, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF
-};
-
-CPlayer *
-CxadflashPlayer::factory (Copl * newopl)
-{
- return new CxadflashPlayer (newopl);
-}
-
-void
-CxadflashPlayer::xadplayer_rewind (int subsong)
-{
- int i;
-
- plr.speed = xad.speed;
-
- flash.order_pos = 0;
- flash.pattern_pos = 0;
-
- opl_write (0x08, 0x00);
- opl_write (0xBD, 0x00);
-
- // assign default instrument
- for (i = 0; i < 9; i++)
- {
- opl_write (0xA0 + i, 0x00);
- opl_write (0xB0 + i, 0x00);
- }
-
- // assign instruments
- for (i = 0; i < 9; i++)
- for (int j = 0; j < 11; j++)
- opl_write (flash_adlib_registers[i * 11 + j], tune[i * 12 + j]);
-}
-
-void
-CxadflashPlayer::xadplayer_update ()
-{
- unsigned short event_pos = (tune[0x600 + flash.order_pos] * 1152) +
- (flash.pattern_pos * 18) + 0x633;
-
- for (int i = 0; i < 9; i++)
- {
- unsigned short flash_channel_freq =
- (adlib[0xB0 + i] << 8) + adlib[0xA0 + i];
-
- unsigned char event_b0 = tune[event_pos++];
- unsigned char event_b1 = tune[event_pos++];
-#ifdef DEBUG
- AdPlug_LogWrite ("channel %02X, event %02X %02X:\n", i + 1, event_b0,
- event_b1);
-#endif
-
- if (event_b0 == 0x80) // 0.0x80: Set Instrument
- {
- for (int j = 0; j < 11; j++)
- opl_write (flash_adlib_registers[i * 11 + j],
- tune[event_b1 * 12 + j]);
- }
- else
- {
- if (event_b1 == 0x01)
- flash.pattern_pos = 0x3F; // 1.0x01: Pattern Break
-
- unsigned char fx = (event_b1 >> 4);
- unsigned char fx_p = (event_b1 & 0x0F);
-
- switch (fx)
- {
- case 0x0A: // 1.0xAy: Set Carrier volume
- opl_write (flash_adlib_registers[11 * i + 2], fx_p << 2);
- break;
- case 0x0B: // 1.0xBy: Set Modulator volume
- opl_write (flash_adlib_registers[11 * i + 3], fx_p << 2);
- break;
- case 0x0C: // 1.0xCy: Set both operators volume
- opl_write (flash_adlib_registers[11 * i + 2], fx_p << 2);
- opl_write (flash_adlib_registers[11 * i + 3], fx_p << 2);
- break;
-// case 0x0E: // 1.0xEy: ? (increase some value)
- case 0x0F: // 1.0xFy: Set Speed
- plr.speed = (fx_p + 1);
- break;
- }
-
- if (event_b0)
- {
- // mute channel
- opl_write (0xA0 + i, adlib[0xA0 + i]);
- opl_write (0xB0 + i, adlib[0xB0 + i] & 0xDF);
-
- // is note ?
- if (event_b0 != 0x7F)
- {
- unsigned short note_encoded = flash_notes_encoded[event_b0];
- unsigned short freq = flash_notes[(note_encoded >> 8) - 1];
-
- flash_channel_freq = freq | ((note_encoded & 0xFF) << 10) | 0x2000;
-
- opl_write (0xA0 + i, flash_channel_freq & 0xFF);
- opl_write (0xB0 + i, flash_channel_freq >> 8);
- }
- }
-
- if (fx == 0x01) // 1.0x1y: Fine Frequency Slide Up
- {
- flash_channel_freq += (fx_p << 1);
-
- opl_write (0xA0 + i, flash_channel_freq & 0xFF);
- opl_write (0xB0 + i, flash_channel_freq >> 8);
- }
- else if (fx == 0x02) // 1.0x2y: Fine Frequency Slide Down
- {
- flash_channel_freq -= (fx_p << 1);
-
- opl_write (0xA0 + i, flash_channel_freq & 0xFF);
- opl_write (0xB0 + i, flash_channel_freq >> 8);
- }
- }
- }
-
- // next row
- flash.pattern_pos++;
-
- // end of pattern ?
- if (flash.pattern_pos >= 0x40)
- {
- flash.pattern_pos = 0;
-
- flash.order_pos++;
-
- // end of module ?
- if (tune[0x600 + flash.order_pos] == 0xFF)
- {
- flash.order_pos = 0;
-
- plr.looping = 1;
- }
- }
-}
-
-float
-CxadflashPlayer::xadplayer_getrefresh ()
-{
- return 17.5f;
-}
-
-std::string CxadflashPlayer::xadplayer_gettype ()
-{
- return std::string ("xad: flash player");
-}
-
-unsigned int
-CxadflashPlayer::xadplayer_getinstruments ()
-{
- return 32;
-}
diff --git a/src/adplug/core/fmc.cc b/src/adplug/core/fmc.cc
new file mode 100644
index 000000000000..c92bfba897c7
--- /dev/null
+++ b/src/adplug/core/fmc.cc
@@ -0,0 +1,243 @@
+/*
+ Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ Copyright (C) 1999 - 2007 Simon Peter <dn.tlp at gmx.net>, et al.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ fmc.cpp - FMC Loader by Riven the Mage <riven at ok.ru>
+*/
+
+#include <string.h>
+
+#include "fmc.h"
+
+/* -------- Public Methods -------------------------------- */
+
+CPlayer *
+CfmcLoader::factory (Copl * newopl)
+{
+ return new CfmcLoader (newopl);
+}
+
+bool
+CfmcLoader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ const unsigned char conv_fx[16] =
+ { 0, 1, 2, 3, 4, 8, 255, 255, 255, 255, 26, 11, 12, 13, 14, 15 };
+
+ int i, j, k, t = 0;
+
+ // read header
+ f->readString (header.id, 4);
+ f->readString (header.title, 21);
+ header.numchan = f->readInt (1);
+
+ // 'FMC!' - signed ?
+ if (strncmp (header.id, "FMC!", 4))
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // init CmodPlayer
+ realloc_instruments (32);
+ realloc_order (256);
+ realloc_patterns (64, 64, header.numchan);
+ init_trackord ();
+
+ // load order
+ for (i = 0; i < 256; i++)
+ order[i] = f->readInt (1);
+
+ f->ignore (2);
+
+ // load instruments
+ for (i = 0; i < 32; i++)
+ {
+ instruments[i].synthesis = f->readInt (1);
+ instruments[i].feedback = f->readInt (1);
+
+ instruments[i].mod_attack = f->readInt (1);
+ instruments[i].mod_decay = f->readInt (1);
+ instruments[i].mod_sustain = f->readInt (1);
+ instruments[i].mod_release = f->readInt (1);
+ instruments[i].mod_volume = f->readInt (1);
+ instruments[i].mod_ksl = f->readInt (1);
+ instruments[i].mod_freq_multi = f->readInt (1);
+ instruments[i].mod_waveform = f->readInt (1);
+ instruments[i].mod_sustain_sound = f->readInt (1);
+ instruments[i].mod_ksr = f->readInt (1);
+ instruments[i].mod_vibrato = f->readInt (1);
+ instruments[i].mod_tremolo = f->readInt (1);
+
+ instruments[i].car_attack = f->readInt (1);
+ instruments[i].car_decay = f->readInt (1);
+ instruments[i].car_sustain = f->readInt (1);
+ instruments[i].car_release = f->readInt (1);
+ instruments[i].car_volume = f->readInt (1);
+ instruments[i].car_ksl = f->readInt (1);
+ instruments[i].car_freq_multi = f->readInt (1);
+ instruments[i].car_waveform = f->readInt (1);
+ instruments[i].car_sustain_sound = f->readInt (1);
+ instruments[i].car_ksr = f->readInt (1);
+ instruments[i].car_vibrato = f->readInt (1);
+ instruments[i].car_tremolo = f->readInt (1);
+
+ instruments[i].pitch_shift = f->readInt (1);
+
+ f->readString (instruments[i].name, 21);
+ }
+
+ // load tracks
+ for (i = 0; i < 64; i++)
+ {
+ if (f->ateof ())
+ break;
+
+ for (j = 0; j < header.numchan; j++)
+ {
+ for (k = 0; k < 64; k++)
+ {
+ fmc_event event;
+
+ // read event
+ event.byte0 = f->readInt (1);
+ event.byte1 = f->readInt (1);
+ event.byte2 = f->readInt (1);
+
+ // convert event
+ tracks[t][k].note = event.byte0 & 0x7F;
+ tracks[t][k].inst =
+ ((event.byte0 & 0x80) >> 3) + (event.byte1 >> 4) + 1;
+ tracks[t][k].command = conv_fx[event.byte1 & 0x0F];
+ tracks[t][k].param1 = event.byte2 >> 4;
+ tracks[t][k].param2 = event.byte2 & 0x0F;
+
+ // fix effects
+ if (tracks[t][k].command == 0x0E) // 0x0E (14): Retrig
+ tracks[t][k].param1 = 3;
+ if (tracks[t][k].command == 0x1A) // 0x1A (26): Volume Slide
+ {
+ if (tracks[t][k].param1 > tracks[t][k].param2)
+ {
+ tracks[t][k].param1 -= tracks[t][k].param2;
+ tracks[t][k].param2 = 0;
+ }
+ else
+ {
+ tracks[t][k].param2 -= tracks[t][k].param1;
+ tracks[t][k].param1 = 0;
+ }
+ }
+ }
+
+ t++;
+ }
+ }
+ fp.close (f);
+
+ // convert instruments
+ for (i = 0; i < 31; i++)
+ buildinst (i);
+
+ // order length
+ for (i = 0; i < 256; i++)
+ {
+ if (order[i] >= 0xFE)
+ {
+ length = i;
+ break;
+ }
+ }
+
+ // data for Protracker
+ activechan = (0xffffffff >> (32 - header.numchan)) << (32 - header.numchan);
+ nop = t / header.numchan;
+ restartpos = 0;
+
+ // flags
+ flags = Faust;
+
+ rewind (0);
+
+ return true;
+}
+
+float
+CfmcLoader::getrefresh ()
+{
+ return 50.0f;
+}
+
+std::string CfmcLoader::gettype ()
+{
+ return std::string ("Faust Music Creator");
+}
+
+std::string CfmcLoader::gettitle ()
+{
+ return std::string (header.title);
+}
+
+std::string CfmcLoader::getinstrument (unsigned int n)
+{
+ return std::string (instruments[n].name);
+}
+
+unsigned int
+CfmcLoader::getinstruments ()
+{
+ return 32;
+}
+
+/* -------- Private Methods ------------------------------- */
+
+void
+CfmcLoader::buildinst (unsigned char i)
+{
+ inst[i].data[0] = ((instruments[i].synthesis & 1) ^ 1);
+ inst[i].data[0] |= ((instruments[i].feedback & 7) << 1);
+
+ inst[i].data[3] = ((instruments[i].mod_attack & 15) << 4);
+ inst[i].data[3] |= (instruments[i].mod_decay & 15);
+ inst[i].data[5] = ((15 - (instruments[i].mod_sustain & 15)) << 4);
+ inst[i].data[5] |= (instruments[i].mod_release & 15);
+ inst[i].data[9] = (63 - (instruments[i].mod_volume & 63));
+ inst[i].data[9] |= ((instruments[i].mod_ksl & 3) << 6);
+ inst[i].data[1] = (instruments[i].mod_freq_multi & 15);
+ inst[i].data[7] = (instruments[i].mod_waveform & 3);
+ inst[i].data[1] |= ((instruments[i].mod_sustain_sound & 1) << 5);
+ inst[i].data[1] |= ((instruments[i].mod_ksr & 1) << 4);
+ inst[i].data[1] |= ((instruments[i].mod_vibrato & 1) << 6);
+ inst[i].data[1] |= ((instruments[i].mod_tremolo & 1) << 7);
+
+ inst[i].data[4] = ((instruments[i].car_attack & 15) << 4);
+ inst[i].data[4] |= (instruments[i].car_decay & 15);
+ inst[i].data[6] = ((15 - (instruments[i].car_sustain & 15)) << 4);
+ inst[i].data[6] |= (instruments[i].car_release & 15);
+ inst[i].data[10] = (63 - (instruments[i].car_volume & 63));
+ inst[i].data[10] |= ((instruments[i].car_ksl & 3) << 6);
+ inst[i].data[2] = (instruments[i].car_freq_multi & 15);
+ inst[i].data[8] = (instruments[i].car_waveform & 3);
+ inst[i].data[2] |= ((instruments[i].car_sustain_sound & 1) << 5);
+ inst[i].data[2] |= ((instruments[i].car_ksr & 1) << 4);
+ inst[i].data[2] |= ((instruments[i].car_vibrato & 1) << 6);
+ inst[i].data[2] |= ((instruments[i].car_tremolo & 1) << 7);
+
+ inst[i].slide = instruments[i].pitch_shift;
+}
diff --git a/src/adplug/core/fmc.cxx b/src/adplug/core/fmc.cxx
deleted file mode 100644
index d853e9332499..000000000000
--- a/src/adplug/core/fmc.cxx
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- Adplug - Replayer for many OPL2/OPL3 audio file formats.
- Copyright (C) 1999 - 2007 Simon Peter <dn.tlp at gmx.net>, et al.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- fmc.cpp - FMC Loader by Riven the Mage <riven at ok.ru>
-*/
-
-#include <string.h>
-
-#include "fmc.h"
-
-/* -------- Public Methods -------------------------------- */
-
-CPlayer *
-CfmcLoader::factory (Copl * newopl)
-{
- return new CfmcLoader (newopl);
-}
-
-bool
-CfmcLoader::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- const unsigned char conv_fx[16] =
- { 0, 1, 2, 3, 4, 8, 255, 255, 255, 255, 26, 11, 12, 13, 14, 15 };
-
- int i, j, k, t = 0;
-
- // read header
- f->readString (header.id, 4);
- f->readString (header.title, 21);
- header.numchan = f->readInt (1);
-
- // 'FMC!' - signed ?
- if (strncmp (header.id, "FMC!", 4))
- {
- fp.close (f);
- return false;
- }
-
- // init CmodPlayer
- realloc_instruments (32);
- realloc_order (256);
- realloc_patterns (64, 64, header.numchan);
- init_trackord ();
-
- // load order
- for (i = 0; i < 256; i++)
- order[i] = f->readInt (1);
-
- f->ignore (2);
-
- // load instruments
- for (i = 0; i < 32; i++)
- {
- instruments[i].synthesis = f->readInt (1);
- instruments[i].feedback = f->readInt (1);
-
- instruments[i].mod_attack = f->readInt (1);
- instruments[i].mod_decay = f->readInt (1);
- instruments[i].mod_sustain = f->readInt (1);
- instruments[i].mod_release = f->readInt (1);
- instruments[i].mod_volume = f->readInt (1);
- instruments[i].mod_ksl = f->readInt (1);
- instruments[i].mod_freq_multi = f->readInt (1);
- instruments[i].mod_waveform = f->readInt (1);
- instruments[i].mod_sustain_sound = f->readInt (1);
- instruments[i].mod_ksr = f->readInt (1);
- instruments[i].mod_vibrato = f->readInt (1);
- instruments[i].mod_tremolo = f->readInt (1);
-
- instruments[i].car_attack = f->readInt (1);
- instruments[i].car_decay = f->readInt (1);
- instruments[i].car_sustain = f->readInt (1);
- instruments[i].car_release = f->readInt (1);
- instruments[i].car_volume = f->readInt (1);
- instruments[i].car_ksl = f->readInt (1);
- instruments[i].car_freq_multi = f->readInt (1);
- instruments[i].car_waveform = f->readInt (1);
- instruments[i].car_sustain_sound = f->readInt (1);
- instruments[i].car_ksr = f->readInt (1);
- instruments[i].car_vibrato = f->readInt (1);
- instruments[i].car_tremolo = f->readInt (1);
-
- instruments[i].pitch_shift = f->readInt (1);
-
- f->readString (instruments[i].name, 21);
- }
-
- // load tracks
- for (i = 0; i < 64; i++)
- {
- if (f->ateof ())
- break;
-
- for (j = 0; j < header.numchan; j++)
- {
- for (k = 0; k < 64; k++)
- {
- fmc_event event;
-
- // read event
- event.byte0 = f->readInt (1);
- event.byte1 = f->readInt (1);
- event.byte2 = f->readInt (1);
-
- // convert event
- tracks[t][k].note = event.byte0 & 0x7F;
- tracks[t][k].inst =
- ((event.byte0 & 0x80) >> 3) + (event.byte1 >> 4) + 1;
- tracks[t][k].command = conv_fx[event.byte1 & 0x0F];
- tracks[t][k].param1 = event.byte2 >> 4;
- tracks[t][k].param2 = event.byte2 & 0x0F;
-
- // fix effects
- if (tracks[t][k].command == 0x0E) // 0x0E (14): Retrig
- tracks[t][k].param1 = 3;
- if (tracks[t][k].command == 0x1A) // 0x1A (26): Volume Slide
- {
- if (tracks[t][k].param1 > tracks[t][k].param2)
- {
- tracks[t][k].param1 -= tracks[t][k].param2;
- tracks[t][k].param2 = 0;
- }
- else
- {
- tracks[t][k].param2 -= tracks[t][k].param1;
- tracks[t][k].param1 = 0;
- }
- }
- }
-
- t++;
- }
- }
- fp.close (f);
-
- // convert instruments
- for (i = 0; i < 31; i++)
- buildinst (i);
-
- // order length
- for (i = 0; i < 256; i++)
- {
- if (order[i] >= 0xFE)
- {
- length = i;
- break;
- }
- }
-
- // data for Protracker
- activechan = (0xffffffff >> (32 - header.numchan)) << (32 - header.numchan);
- nop = t / header.numchan;
- restartpos = 0;
-
- // flags
- flags = Faust;
-
- rewind (0);
-
- return true;
-}
-
-float
-CfmcLoader::getrefresh ()
-{
- return 50.0f;
-}
-
-std::string CfmcLoader::gettype ()
-{
- return std::string ("Faust Music Creator");
-}
-
-std::string CfmcLoader::gettitle ()
-{
- return std::string (header.title);
-}
-
-std::string CfmcLoader::getinstrument (unsigned int n)
-{
- return std::string (instruments[n].name);
-}
-
-unsigned int
-CfmcLoader::getinstruments ()
-{
- return 32;
-}
-
-/* -------- Private Methods ------------------------------- */
-
-void
-CfmcLoader::buildinst (unsigned char i)
-{
- inst[i].data[0] = ((instruments[i].synthesis & 1) ^ 1);
- inst[i].data[0] |= ((instruments[i].feedback & 7) << 1);
-
- inst[i].data[3] = ((instruments[i].mod_attack & 15) << 4);
- inst[i].data[3] |= (instruments[i].mod_decay & 15);
- inst[i].data[5] = ((15 - (instruments[i].mod_sustain & 15)) << 4);
- inst[i].data[5] |= (instruments[i].mod_release & 15);
- inst[i].data[9] = (63 - (instruments[i].mod_volume & 63));
- inst[i].data[9] |= ((instruments[i].mod_ksl & 3) << 6);
- inst[i].data[1] = (instruments[i].mod_freq_multi & 15);
- inst[i].data[7] = (instruments[i].mod_waveform & 3);
- inst[i].data[1] |= ((instruments[i].mod_sustain_sound & 1) << 5);
- inst[i].data[1] |= ((instruments[i].mod_ksr & 1) << 4);
- inst[i].data[1] |= ((instruments[i].mod_vibrato & 1) << 6);
- inst[i].data[1] |= ((instruments[i].mod_tremolo & 1) << 7);
-
- inst[i].data[4] = ((instruments[i].car_attack & 15) << 4);
- inst[i].data[4] |= (instruments[i].car_decay & 15);
- inst[i].data[6] = ((15 - (instruments[i].car_sustain & 15)) << 4);
- inst[i].data[6] |= (instruments[i].car_release & 15);
- inst[i].data[10] = (63 - (instruments[i].car_volume & 63));
- inst[i].data[10] |= ((instruments[i].car_ksl & 3) << 6);
- inst[i].data[2] = (instruments[i].car_freq_multi & 15);
- inst[i].data[8] = (instruments[i].car_waveform & 3);
- inst[i].data[2] |= ((instruments[i].car_sustain_sound & 1) << 5);
- inst[i].data[2] |= ((instruments[i].car_ksr & 1) << 4);
- inst[i].data[2] |= ((instruments[i].car_vibrato & 1) << 6);
- inst[i].data[2] |= ((instruments[i].car_tremolo & 1) << 7);
-
- inst[i].slide = instruments[i].pitch_shift;
-}
diff --git a/src/adplug/core/fmc.h b/src/adplug/core/fmc.h
index 95ef0f4ca366..3f4eab68ec1f 100644
--- a/src/adplug/core/fmc.h
+++ b/src/adplug/core/fmc.h
@@ -28,7 +28,7 @@ class CfmcLoader: public CmodPlayer
CfmcLoader(Copl *newopl) : CmodPlayer(newopl) { };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
float getrefresh();
std::string gettype();
diff --git a/src/adplug/core/fmopl.c b/src/adplug/core/fmopl.c
deleted file mode 100644
index 81d645981b9a..000000000000
--- a/src/adplug/core/fmopl.c
+++ /dev/null
@@ -1,1389 +0,0 @@
-/*
-**
-** File: fmopl.c -- software implementation of FM sound generator
-**
-** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
-**
-** Version 0.37a
-**
-*/
-
-/*
- preliminary :
- Problem :
- note:
-*/
-
-/* This version of fmopl.c is a fork of the MAME one, relicensed under the LGPL.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#define HAS_YM3812 1
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <math.h>
-//#include "driver.h" /* use M.A.M.E. */
-#include "fmopl.h"
-
-#ifndef PI
-#define PI 3.14159265358979323846
-#endif
-
-/* -------------------- for debug --------------------- */
-/* #define OPL_OUTPUT_LOG */
-#ifdef OPL_OUTPUT_LOG
-static FILE *opl_dbg_fp = NULL;
-static FM_OPL *opl_dbg_opl[16];
-static int opl_dbg_maxchip,opl_dbg_chip;
-#endif
-
-/* -------------------- preliminary define section --------------------- */
-/* attack/decay rate time rate */
-#define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */
-#define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */
-
-#define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */
-
-#define FREQ_BITS 24 /* frequency turn */
-
-/* counter bits = 20 , octerve 7 */
-#define FREQ_RATE (1<<(FREQ_BITS-20))
-#define TL_BITS (FREQ_BITS+2)
-
-/* final output shift , limit minimum and maximum */
-#define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */
-#define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
-#define OPL_MINOUT (-0x8000<<OPL_OUTSB)
-
-/* -------------------- quality selection --------------------- */
-
-/* sinwave entries */
-/* used static memory = SIN_ENT * 4 (byte) */
-#define SIN_ENT 2048
-
-/* output level entries (envelope,sinwave) */
-/* envelope counter lower bits */
-#define ENV_BITS 16
-/* envelope output entries */
-#define EG_ENT 4096
-/* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
-/* used static memory = EG_ENT*4 (byte) */
-
-#define EG_OFF ((2*EG_ENT)<<ENV_BITS) /* OFF */
-#define EG_DED EG_OFF
-#define EG_DST (EG_ENT<<ENV_BITS) /* DECAY START */
-#define EG_AED EG_DST
-#define EG_AST 0 /* ATTACK START */
-
-#define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */
-
-/* LFO table entries */
-#define VIB_ENT 512
-#define VIB_SHIFT (32-9)
-#define AMS_ENT 512
-#define AMS_SHIFT (32-9)
-
-#define VIB_RATE 256
-
-/* -------------------- local defines , macros --------------------- */
-
-/* register number to channel number , slot offset */
-#define SLOT1 0
-#define SLOT2 1
-
-/* envelope phase */
-#define ENV_MOD_RR 0x00
-#define ENV_MOD_DR 0x01
-#define ENV_MOD_AR 0x02
-
-/* -------------------- tables --------------------- */
-static const int slot_array[32]=
-{
- 0, 2, 4, 1, 3, 5,-1,-1,
- 6, 8,10, 7, 9,11,-1,-1,
- 12,14,16,13,15,17,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1
-};
-
-/* key scale level */
-/* table is 3dB/OCT , DV converts this in TL step at 6dB/OCT */
-#define DV (EG_STEP/2)
-static const UINT32 KSL_TABLE[8*16]=
-{
- /* OCT 0 */
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- /* OCT 1 */
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV,
- 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV,
- /* OCT 2 */
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV,
- 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV,
- 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV,
- /* OCT 3 */
- 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV,
- 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV,
- 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV,
- 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV,
- /* OCT 4 */
- 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV,
- 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV,
- 9.000/DV, 9.750/DV,10.125/DV,10.500/DV,
- 10.875/DV,11.250/DV,11.625/DV,12.000/DV,
- /* OCT 5 */
- 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV,
- 9.000/DV,10.125/DV,10.875/DV,11.625/DV,
- 12.000/DV,12.750/DV,13.125/DV,13.500/DV,
- 13.875/DV,14.250/DV,14.625/DV,15.000/DV,
- /* OCT 6 */
- 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV,
- 12.000/DV,13.125/DV,13.875/DV,14.625/DV,
- 15.000/DV,15.750/DV,16.125/DV,16.500/DV,
- 16.875/DV,17.250/DV,17.625/DV,18.000/DV,
- /* OCT 7 */
- 0.000/DV, 9.000/DV,12.000/DV,13.875/DV,
- 15.000/DV,16.125/DV,16.875/DV,17.625/DV,
- 18.000/DV,18.750/DV,19.125/DV,19.500/DV,
- 19.875/DV,20.250/DV,20.625/DV,21.000/DV
-};
-#undef DV
-
-/* sustain lebel table (3db per step) */
-/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
-#define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
-static const INT32 SL_TABLE[16]={
- SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
- SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
-};
-#undef SC
-
-#define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */
-/* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */
-/* TL_TABLE[ 0 to TL_MAX ] : plus section */
-/* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
-static INT32 *TL_TABLE;
-
-/* pointers to TL_TABLE with sinwave output offset */
-static INT32 **SIN_TABLE;
-
-/* LFO table */
-static INT32 *AMS_TABLE;
-static INT32 *VIB_TABLE;
-
-/* envelope output curve table */
-/* attack + decay + OFF */
-static INT32 ENV_CURVE[2*EG_ENT+1];
-
-/* multiple table */
-#define ML 2
-static const UINT32 MUL_TABLE[16]= {
-/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
- 0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
- 8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML
-};
-#undef ML
-
-/* dummy attack / decay rate ( when rate == 0 ) */
-static INT32 RATE_0[16]=
-{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
-/* -------------------- static state --------------------- */
-
-/* lock level of common table */
-static int num_lock = 0;
-
-/* work table */
-static void *cur_chip = NULL; /* current chip point */
-/* currenct chip state */
-/* static OPLSAMPLE *bufL,*bufR; */
-static OPL_CH *S_CH;
-static OPL_CH *E_CH;
-OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
-
-static INT32 outd[1];
-static INT32 ams;
-static INT32 vib;
-INT32 *ams_table;
-INT32 *vib_table;
-static INT32 amsIncr;
-static INT32 vibIncr;
-static INT32 feedback2; /* connect for SLOT 2 */
-
-/* log output level */
-#define LOG_ERR 3 /* ERROR */
-#define LOG_WAR 2 /* WARNING */
-#define LOG_INF 1 /* INFORMATION */
-
-//#define LOG_LEVEL LOG_INF
-#define LOG_LEVEL LOG_ERR
-
-//#define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x
-#define LOG(n,x)
-
-/* --------------------- subroutines --------------------- */
-
-static inline int Limit( int val, int max, int min ) {
- if ( val > max )
- val = max;
- else if ( val < min )
- val = min;
-
- return val;
-}
-
-/* status set and IRQ handling */
-static inline void OPL_STATUS_SET(FM_OPL *OPL,int flag)
-{
- /* set status flag */
- OPL->status |= flag;
- if(!(OPL->status & 0x80))
- {
- if(OPL->status & OPL->statusmask)
- { /* IRQ on */
- OPL->status |= 0x80;
- /* callback user interrupt handler (IRQ is OFF to ON) */
- if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1);
- }
- }
-}
-
-/* status reset and IRQ handling */
-static inline void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
-{
- /* reset status flag */
- OPL->status &=~flag;
- if((OPL->status & 0x80))
- {
- if (!(OPL->status & OPL->statusmask) )
- {
- OPL->status &= 0x7f;
- /* callback user interrupt handler (IRQ is ON to OFF) */
- if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
- }
- }
-}
-
-/* IRQ mask set */
-static inline void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag)
-{
- OPL->statusmask = flag;
- /* IRQ handling check */
- OPL_STATUS_SET(OPL,0);
- OPL_STATUS_RESET(OPL,0);
-}
-
-/* ----- key on ----- */
-static inline void OPL_KEYON(OPL_SLOT *SLOT)
-{
- /* sin wave restart */
- SLOT->Cnt = 0;
- /* set attack */
- SLOT->evm = ENV_MOD_AR;
- SLOT->evs = SLOT->evsa;
- SLOT->evc = EG_AST;
- SLOT->eve = EG_AED;
-}
-/* ----- key off ----- */
-static inline void OPL_KEYOFF(OPL_SLOT *SLOT)
-{
- if( SLOT->evm > ENV_MOD_RR)
- {
- /* set envelope counter from envleope output */
- SLOT->evm = ENV_MOD_RR;
- if( !(SLOT->evc&EG_DST) )
- //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
- SLOT->evc = EG_DST;
- SLOT->eve = EG_DED;
- SLOT->evs = SLOT->evsr;
- }
-}
-
-/* ---------- calcrate Envelope Generator & Phase Generator ---------- */
-/* return : envelope output */
-static inline UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
-{
- /* calcrate envelope generator */
- if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
- {
- switch( SLOT->evm ){
- case ENV_MOD_AR: /* ATTACK -> DECAY1 */
- /* next DR */
- SLOT->evm = ENV_MOD_DR;
- SLOT->evc = EG_DST;
- SLOT->eve = SLOT->SL;
- SLOT->evs = SLOT->evsd;
- break;
- case ENV_MOD_DR: /* DECAY -> SL or RR */
- SLOT->evc = SLOT->SL;
- SLOT->eve = EG_DED;
- if(SLOT->eg_typ)
- {
- SLOT->evs = 0;
- }
- else
- {
- SLOT->evm = ENV_MOD_RR;
- SLOT->evs = SLOT->evsr;
- }
- break;
- case ENV_MOD_RR: /* RR -> OFF */
- SLOT->evc = EG_OFF;
- SLOT->eve = EG_OFF+1;
- SLOT->evs = 0;
- break;
- }
- }
- /* calcrate envelope */
- return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0);
-}
-
-/* set algorythm connection */
-static void set_algorythm( OPL_CH *CH)
-{
- INT32 *carrier = &outd[0];
- CH->connect1 = CH->CON ? carrier : &feedback2;
- CH->connect2 = carrier;
-}
-
-/* ---------- frequency counter for operater update ---------- */
-static inline void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
-{
- int ksr;
-
- /* frequency step counter */
- SLOT->Incr = CH->fc * SLOT->mul;
- ksr = CH->kcode >> SLOT->KSR;
-
- if( SLOT->ksr != ksr )
- {
- SLOT->ksr = ksr;
- /* attack , decay rate recalcration */
- SLOT->evsa = SLOT->AR[ksr];
- SLOT->evsd = SLOT->DR[ksr];
- SLOT->evsr = SLOT->RR[ksr];
- }
- SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
-}
-
-/* set multi,am,vib,EG-TYP,KSR,mul */
-static inline void set_mul(FM_OPL *OPL,int slot,int v)
-{
- OPL_CH *CH = &OPL->P_CH[slot/2];
- OPL_SLOT *SLOT = &CH->SLOT[slot&1];
-
- SLOT->mul = MUL_TABLE[v&0x0f];
- SLOT->KSR = (v&0x10) ? 0 : 2;
- SLOT->eg_typ = (v&0x20)>>5;
- SLOT->vib = (v&0x40);
- SLOT->ams = (v&0x80);
- CALC_FCSLOT(CH,SLOT);
-}
-
-/* set ksl & tl */
-static inline void set_ksl_tl(FM_OPL *OPL,int slot,int v)
-{
- OPL_CH *CH = &OPL->P_CH[slot/2];
- OPL_SLOT *SLOT = &CH->SLOT[slot&1];
- int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */
-
- SLOT->ksl = ksl ? 3-ksl : 31;
- SLOT->TL = (v&0x3f)*(0.75/EG_STEP); /* 0.75db step */
-
- if( !(OPL->mode&0x80) )
- { /* not CSM latch total level */
- SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
- }
-}
-
-/* set attack rate & decay rate */
-static inline void set_ar_dr(FM_OPL *OPL,int slot,int v)
-{
- OPL_CH *CH = &OPL->P_CH[slot/2];
- OPL_SLOT *SLOT = &CH->SLOT[slot&1];
- int ar = v>>4;
- int dr = v&0x0f;
-
- SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0;
- SLOT->evsa = SLOT->AR[SLOT->ksr];
- if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa;
-
- SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
- SLOT->evsd = SLOT->DR[SLOT->ksr];
- if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd;
-}
-
-/* set sustain level & release rate */
-static inline void set_sl_rr(FM_OPL *OPL,int slot,int v)
-{
- OPL_CH *CH = &OPL->P_CH[slot/2];
- OPL_SLOT *SLOT = &CH->SLOT[slot&1];
- int sl = v>>4;
- int rr = v & 0x0f;
-
- SLOT->SL = SL_TABLE[sl];
- if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL;
- SLOT->RR = &OPL->DR_TABLE[rr<<2];
- SLOT->evsr = SLOT->RR[SLOT->ksr];
- if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr;
-}
-
-/* operator output calcrator */
-#define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
-/* ---------- calcrate one of channel ---------- */
-static inline void OPL_CALC_CH( OPL_CH *CH )
-{
- UINT32 env_out;
- OPL_SLOT *SLOT;
-
- feedback2 = 0;
- /* SLOT 1 */
- SLOT = &CH->SLOT[SLOT1];
- env_out=OPL_CALC_SLOT(SLOT);
- if( env_out < EG_ENT-1 )
- {
- /* PG */
- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
- else SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- if(CH->FB)
- {
- int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
- CH->op1_out[1] = CH->op1_out[0];
- *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
- }
- else
- {
- *CH->connect1 += OP_OUT(SLOT,env_out,0);
- }
- }else
- {
- CH->op1_out[1] = CH->op1_out[0];
- CH->op1_out[0] = 0;
- }
- /* SLOT 2 */
- SLOT = &CH->SLOT[SLOT2];
- env_out=OPL_CALC_SLOT(SLOT);
- if( env_out < EG_ENT-1 )
- {
- /* PG */
- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
- else SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- outd[0] += OP_OUT(SLOT,env_out, feedback2);
- }
-}
-
-/* ---------- calcrate rythm block ---------- */
-#define WHITE_NOISE_db 6.0
-static inline void OPL_CALC_RH( OPL_CH *CH )
-{
- UINT32 env_tam,env_sd,env_top,env_hh;
- int whitenoise = (rand()&1)*(WHITE_NOISE_db/EG_STEP);
- INT32 tone8;
-
- OPL_SLOT *SLOT;
- int env_out;
-
- /* BD : same as FM serial mode and output level is large */
- feedback2 = 0;
- /* SLOT 1 */
- SLOT = &CH[6].SLOT[SLOT1];
- env_out=OPL_CALC_SLOT(SLOT);
- if( env_out < EG_ENT-1 )
- {
- /* PG */
- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
- else SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- if(CH[6].FB)
- {
- int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB;
- CH[6].op1_out[1] = CH[6].op1_out[0];
- feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
- }
- else
- {
- feedback2 = OP_OUT(SLOT,env_out,0);
- }
- }else
- {
- feedback2 = 0;
- CH[6].op1_out[1] = CH[6].op1_out[0];
- CH[6].op1_out[0] = 0;
- }
- /* SLOT 2 */
- SLOT = &CH[6].SLOT[SLOT2];
- env_out=OPL_CALC_SLOT(SLOT);
- if( env_out < EG_ENT-1 )
- {
- /* PG */
- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
- else SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- outd[0] += OP_OUT(SLOT,env_out, feedback2)*2;
- }
-
- // SD (17) = mul14[fnum7] + white noise
- // TAM (15) = mul15[fnum8]
- // TOP (18) = fnum6(mul18[fnum8]+whitenoise)
- // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
- env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise;
- env_tam=OPL_CALC_SLOT(SLOT8_1);
- env_top=OPL_CALC_SLOT(SLOT8_2);
- env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise;
-
- /* PG */
- if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE);
- else SLOT7_1->Cnt += 2*SLOT7_1->Incr;
- if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE);
- else SLOT7_2->Cnt += (CH[7].fc*8);
- if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE);
- else SLOT8_1->Cnt += SLOT8_1->Incr;
- if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE);
- else SLOT8_2->Cnt += (CH[8].fc*48);
-
- tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
-
- /* SD */
- if( env_sd < EG_ENT-1 )
- outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8;
- /* TAM */
- if( env_tam < EG_ENT-1 )
- outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2;
- /* TOP-CY */
- if( env_top < EG_ENT-1 )
- outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2;
- /* HH */
- if( env_hh < EG_ENT-1 )
- outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2;
-}
-
-/* ----------- initialize time tabls ----------- */
-static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
-{
- int i;
- double rate;
-
- /* make attack rate & decay rate tables */
- for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
- for (i = 4;i <= 60;i++){
- rate = OPL->freqbase; /* frequency rate */
- if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
- rate *= 1<<((i>>2)-1); /* b2-5 : shift bit */
- rate *= (double)(EG_ENT<<ENV_BITS);
- OPL->AR_TABLE[i] = rate / ARRATE;
- OPL->DR_TABLE[i] = rate / DRRATE;
- }
- for (i = 60;i < 76;i++)
- {
- OPL->AR_TABLE[i] = EG_AED-1;
- OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
- }
-#if 0
- for (i = 0;i < 64 ;i++){ /* make for overflow area */
- LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i,
- ((double)(EG_ENT<<ENV_BITS) / OPL->AR_TABLE[i]) * (1000.0 / OPL->rate),
- ((double)(EG_ENT<<ENV_BITS) / OPL->DR_TABLE[i]) * (1000.0 / OPL->rate) ));
- }
-#endif
-}
-
-/* ---------- generic table initialize ---------- */
-static int OPLOpenTable( void )
-{
- int s,t;
- double rate;
- int i,j;
- double pom;
-
- /* allocate dynamic tables */
- if( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL)
- return 0;
- if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL)
- {
- free(TL_TABLE);
- return 0;
- }
- if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL)
- {
- free(TL_TABLE);
- free(SIN_TABLE);
- return 0;
- }
- if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL)
- {
- free(TL_TABLE);
- free(SIN_TABLE);
- free(AMS_TABLE);
- return 0;
- }
- /* make total level table */
- for (t = 0;t < EG_ENT-1 ;t++){
- rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20); /* dB -> voltage */
- TL_TABLE[ t] = (int)rate;
- TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
-/* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/
- }
- /* fill volume off area */
- for ( t = EG_ENT-1; t < TL_MAX ;t++){
- TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
- }
-
- /* make sinwave table (total level offet) */
- /* degree 0 = degree 180 = off */
- SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2] = &TL_TABLE[EG_ENT-1];
- for (s = 1;s <= SIN_ENT/4;s++){
- pom = sin(2*PI*s/SIN_ENT); /* sin */
- pom = 20*log10(1/pom); /* decibel */
- j = pom / EG_STEP; /* TL_TABLE steps */
-
- /* degree 0 - 90 , degree 180 - 90 : plus section */
- SIN_TABLE[ s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
- /* degree 180 - 270 , degree 360 - 270 : minus section */
- SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT -s] = &TL_TABLE[TL_MAX+j];
-/* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/
- }
- for (s = 0;s < SIN_ENT;s++)
- {
- SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
- SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)];
- SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s];
- }
-
- /* envelope counter -> envelope output table */
- for (i=0; i<EG_ENT; i++)
- {
- /* ATTACK curve */
- pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
- /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
- ENV_CURVE[i] = (int)pom;
- /* DECAY ,RELEASE curve */
- ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
- }
- /* off */
- ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
- /* make LFO ams table */
- for (i=0; i<AMS_ENT; i++)
- {
- pom = (1.0+sin(2*PI*i/AMS_ENT))/2; /* sin */
- AMS_TABLE[i] = (1.0/EG_STEP)*pom; /* 1dB */
- AMS_TABLE[AMS_ENT+i] = (4.8/EG_STEP)*pom; /* 4.8dB */
- }
- /* make LFO vibrate table */
- for (i=0; i<VIB_ENT; i++)
- {
- /* 100cent = 1seminote = 6% ?? */
- pom = (double)VIB_RATE*0.06*sin(2*PI*i/VIB_ENT); /* +-100sect step */
- VIB_TABLE[i] = VIB_RATE + (pom*0.07); /* +- 7cent */
- VIB_TABLE[VIB_ENT+i] = VIB_RATE + (pom*0.14); /* +-14cent */
- /* LOG(LOG_INF,("vib %d=%d\n",i,VIB_TABLE[VIB_ENT+i])); */
- }
- return 1;
-}
-
-
-static void OPLCloseTable( void )
-{
- free(TL_TABLE);
- free(SIN_TABLE);
- free(AMS_TABLE);
- free(VIB_TABLE);
-}
-
-/* CSM Key Controll */
-static inline void CSMKeyControll(OPL_CH *CH)
-{
- OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
- OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
- /* all key off */
- OPL_KEYOFF(slot1);
- OPL_KEYOFF(slot2);
- /* total level latch */
- slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
- slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
- /* key on */
- CH->op1_out[0] = CH->op1_out[1] = 0;
- OPL_KEYON(slot1);
- OPL_KEYON(slot2);
-}
-
-/* ---------- opl initialize ---------- */
-static void OPL_initalize(FM_OPL *OPL)
-{
- int fn;
-
- /* frequency base */
- OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0;
- /* Timer base time */
- OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
- /* make time tables */
- init_timetables( OPL , OPL_ARRATE , OPL_DRRATE );
- /* make fnumber -> increment counter table */
- for( fn=0 ; fn < 1024 ; fn++ )
- {
- OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2;
- }
- /* LFO freq.table */
- OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0;
- OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0;
-}
-
-/* ---------- write a OPL registers ---------- */
-static void OPLWriteReg(FM_OPL *OPL, int r, int v)
-{
- OPL_CH *CH;
- int slot;
- int block_fnum;
-
- switch(r&0xe0)
- {
- case 0x00: /* 00-1f:controll */
- switch(r&0x1f)
- {
- case 0x01:
- /* wave selector enable */
- if(OPL->type&OPL_TYPE_WAVESEL)
- {
- OPL->wavesel = v&0x20;
- if(!OPL->wavesel)
- {
- /* preset compatible mode */
- int c;
- for(c=0;c<OPL->max_ch;c++)
- {
- OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
- OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
- }
- }
- }
- return;
- case 0x02: /* Timer 1 */
- OPL->T[0] = (256-v)*4;
- break;
- case 0x03: /* Timer 2 */
- OPL->T[1] = (256-v)*16;
- return;
- case 0x04: /* IRQ clear / mask and Timer enable */
- if(v&0x80)
- { /* IRQ flag clear */
- OPL_STATUS_RESET(OPL,0x7f);
- }
- else
- { /* set IRQ mask ,timer enable*/
- UINT8 st1 = v&1;
- UINT8 st2 = (v>>1)&1;
- /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
- OPL_STATUS_RESET(OPL,v&0x78);
- OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01);
- /* timer 2 */
- if(OPL->st[1] != st2)
- {
- double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0;
- OPL->st[1] = st2;
- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval);
- }
- /* timer 1 */
- if(OPL->st[0] != st1)
- {
- double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0;
- OPL->st[0] = st1;
- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval);
- }
- }
- return;
-#if BUILD_Y8950
- case 0x06: /* Key Board OUT */
- if(OPL->type&OPL_TYPE_KEYBOARD)
- {
- if(OPL->keyboardhandler_w)
- OPL->keyboardhandler_w(OPL->keyboard_param,v);
- else
- LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n"));
- }
- return;
- case 0x07: /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
- if(OPL->type&OPL_TYPE_ADPCM)
- YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
- return;
- case 0x08: /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
- OPL->mode = v;
- v&=0x1f; /* for DELTA-T unit */
- case 0x09: /* START ADD */
- case 0x0a:
- case 0x0b: /* STOP ADD */
- case 0x0c:
- case 0x0d: /* PRESCALE */
- case 0x0e:
- case 0x0f: /* ADPCM data */
- case 0x10: /* DELTA-N */
- case 0x11: /* DELTA-N */
- case 0x12: /* EG-CTRL */
- if(OPL->type&OPL_TYPE_ADPCM)
- YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
- return;
-#if 0
- case 0x15: /* DAC data */
- case 0x16:
- case 0x17: /* SHIFT */
- return;
- case 0x18: /* I/O CTRL (Direction) */
- if(OPL->type&OPL_TYPE_IO)
- OPL->portDirection = v&0x0f;
- return;
- case 0x19: /* I/O DATA */
- if(OPL->type&OPL_TYPE_IO)
- {
- OPL->portLatch = v;
- if(OPL->porthandler_w)
- OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
- }
- return;
- case 0x1a: /* PCM data */
- return;
-#endif
-#endif
- }
- break;
- case 0x20: /* am,vib,ksr,eg type,mul */
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- set_mul(OPL,slot,v);
- return;
- case 0x40:
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- set_ksl_tl(OPL,slot,v);
- return;
- case 0x60:
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- set_ar_dr(OPL,slot,v);
- return;
- case 0x80:
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- set_sl_rr(OPL,slot,v);
- return;
- case 0xa0:
- switch(r)
- {
- case 0xbd:
- /* amsep,vibdep,r,bd,sd,tom,tc,hh */
- {
- UINT8 rkey = OPL->rythm^v;
- OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
- OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
- OPL->rythm = v&0x3f;
- if(OPL->rythm&0x20)
- {
-#if 0
- usrintf_showmessage("OPL Rythm mode select");
-#endif
- /* BD key on/off */
- if(rkey&0x10)
- {
- if(v&0x10)
- {
- OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
- OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
- OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
- }
- else
- {
- OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
- OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
- }
- }
- /* SD key on/off */
- if(rkey&0x08)
- {
- if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
- else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
- }/* TAM key on/off */
- if(rkey&0x04)
- {
- if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
- else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
- }
- /* TOP-CY key on/off */
- if(rkey&0x02)
- {
- if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
- else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
- }
- /* HH key on/off */
- if(rkey&0x01)
- {
- if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
- else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
- }
- }
- }
- return;
- }
- /* keyon,block,fnum */
- if( (r&0x0f) > 8) return;
- CH = &OPL->P_CH[r&0x0f];
- if(!(r&0x10))
- { /* a0-a8 */
- block_fnum = (CH->block_fnum&0x1f00) | v;
- }
- else
- { /* b0-b8 */
- int keyon = (v>>5)&1;
- block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
- if(CH->keyon != keyon)
- {
- if( (CH->keyon=keyon) )
- {
- CH->op1_out[0] = CH->op1_out[1] = 0;
- OPL_KEYON(&CH->SLOT[SLOT1]);
- OPL_KEYON(&CH->SLOT[SLOT2]);
- }
- else
- {
- OPL_KEYOFF(&CH->SLOT[SLOT1]);
- OPL_KEYOFF(&CH->SLOT[SLOT2]);
- }
- }
- }
- /* update */
- if(CH->block_fnum != block_fnum)
- {
- int blockRv = 7-(block_fnum>>10);
- int fnum = block_fnum&0x3ff;
- CH->block_fnum = block_fnum;
-
- CH->ksl_base = KSL_TABLE[block_fnum>>6];
- CH->fc = OPL->FN_TABLE[fnum]>>blockRv;
- CH->kcode = CH->block_fnum>>9;
- if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1;
- CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
- CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
- }
- return;
- case 0xc0:
- /* FB,C */
- if( (r&0x0f) > 8) return;
- CH = &OPL->P_CH[r&0x0f];
- {
- int feedback = (v>>1)&7;
- CH->FB = feedback ? (8+1) - feedback : 0;
- CH->CON = v&1;
- set_algorythm(CH);
- }
- return;
- case 0xe0: /* wave type */
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- CH = &OPL->P_CH[slot/2];
- if(OPL->wavesel)
- {
- /* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */
- CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT];
- }
- return;
- }
-}
-
-/* lock/unlock for common table */
-static int OPL_LockTable(void)
-{
- num_lock++;
- if(num_lock>1) return 0;
- /* first time */
- cur_chip = NULL;
- /* allocate total level table (128kb space) */
- if( !OPLOpenTable() )
- {
- num_lock--;
- return -1;
- }
- return 0;
-}
-
-static void OPL_UnLockTable(void)
-{
- if(num_lock) num_lock--;
- if(num_lock) return;
- /* last time */
- cur_chip = NULL;
- OPLCloseTable();
-}
-
-#if (BUILD_YM3812 || BUILD_YM3526)
-/*******************************************************************************/
-/* YM3812 local section */
-/*******************************************************************************/
-
-/* ---------- update one of chip ----------- */
-void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
-{
- int i;
- int data;
- OPLSAMPLE *buf = buffer;
- UINT32 amsCnt = OPL->amsCnt;
- UINT32 vibCnt = OPL->vibCnt;
- UINT8 rythm = OPL->rythm&0x20;
- OPL_CH *CH,*R_CH;
-
- if( (void *)OPL != cur_chip ){
- cur_chip = (void *)OPL;
- /* channel pointers */
- S_CH = OPL->P_CH;
- E_CH = &S_CH[9];
- /* rythm slot */
- SLOT7_1 = &S_CH[7].SLOT[SLOT1];
- SLOT7_2 = &S_CH[7].SLOT[SLOT2];
- SLOT8_1 = &S_CH[8].SLOT[SLOT1];
- SLOT8_2 = &S_CH[8].SLOT[SLOT2];
- /* LFO state */
- amsIncr = OPL->amsIncr;
- vibIncr = OPL->vibIncr;
- ams_table = OPL->ams_table;
- vib_table = OPL->vib_table;
- }
- R_CH = rythm ? &S_CH[6] : E_CH;
- for( i=0; i < length ; i++ )
- {
- /* channel A channel B channel C */
- /* LFO */
- ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
- vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
- outd[0] = 0;
- /* FM part */
- for(CH=S_CH ; CH < R_CH ; CH++)
- OPL_CALC_CH(CH);
- /* Rythn part */
- if(rythm)
- OPL_CALC_RH(S_CH);
- /* limit check */
- data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
- /* store to sound buffer */
- buf[i] = data >> OPL_OUTSB;
- }
-
- OPL->amsCnt = amsCnt;
- OPL->vibCnt = vibCnt;
-#ifdef OPL_OUTPUT_LOG
- if(opl_dbg_fp)
- {
- for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
- if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
- fprintf(opl_dbg_fp,"%c%c%c",0x20+opl_dbg_chip,length&0xff,length/256);
- }
-#endif
-}
-#endif /* (BUILD_YM3812 || BUILD_YM3526) */
-
-#if BUILD_Y8950
-
-void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
-{
- int i;
- int data;
- OPLSAMPLE *buf = buffer;
- UINT32 amsCnt = OPL->amsCnt;
- UINT32 vibCnt = OPL->vibCnt;
- UINT8 rythm = OPL->rythm&0x20;
- OPL_CH *CH,*R_CH;
- YM_DELTAT *DELTAT = OPL->deltat;
-
- /* setup DELTA-T unit */
- YM_DELTAT_DECODE_PRESET(DELTAT);
-
- if( (void *)OPL != cur_chip ){
- cur_chip = (void *)OPL;
- /* channel pointers */
- S_CH = OPL->P_CH;
- E_CH = &S_CH[9];
- /* rythm slot */
- SLOT7_1 = &S_CH[7].SLOT[SLOT1];
- SLOT7_2 = &S_CH[7].SLOT[SLOT2];
- SLOT8_1 = &S_CH[8].SLOT[SLOT1];
- SLOT8_2 = &S_CH[8].SLOT[SLOT2];
- /* LFO state */
- amsIncr = OPL->amsIncr;
- vibIncr = OPL->vibIncr;
- ams_table = OPL->ams_table;
- vib_table = OPL->vib_table;
- }
- R_CH = rythm ? &S_CH[6] : E_CH;
- for( i=0; i < length ; i++ )
- {
- /* channel A channel B channel C */
- /* LFO */
- ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
- vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
- outd[0] = 0;
- /* deltaT ADPCM */
- if( DELTAT->portstate )
- YM_DELTAT_ADPCM_CALC(DELTAT);
- /* FM part */
- for(CH=S_CH ; CH < R_CH ; CH++)
- OPL_CALC_CH(CH);
- /* Rythn part */
- if(rythm)
- OPL_CALC_RH(S_CH);
- /* limit check */
- data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
- /* store to sound buffer */
- buf[i] = data >> OPL_OUTSB;
- }
- OPL->amsCnt = amsCnt;
- OPL->vibCnt = vibCnt;
- /* deltaT START flag */
- if( !DELTAT->portstate )
- OPL->status &= 0xfe;
-}
-#endif
-
-/* ---------- reset one of chip ---------- */
-void OPLResetChip(FM_OPL *OPL)
-{
- int c,s;
- int i;
-
- /* reset chip */
- OPL->mode = 0; /* normal mode */
- OPL_STATUS_RESET(OPL,0x7f);
- /* reset with register write */
- OPLWriteReg(OPL,0x01,0); /* wabesel disable */
- OPLWriteReg(OPL,0x02,0); /* Timer1 */
- OPLWriteReg(OPL,0x03,0); /* Timer2 */
- OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
- for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
- /* reset OPerator paramater */
- for( c = 0 ; c < OPL->max_ch ; c++ )
- {
- OPL_CH *CH = &OPL->P_CH[c];
- /* OPL->P_CH[c].PAN = OPN_CENTER; */
- for(s = 0 ; s < 2 ; s++ )
- {
- /* wave table */
- CH->SLOT[s].wavetable = &SIN_TABLE[0];
- /* CH->SLOT[s].evm = ENV_MOD_RR; */
- CH->SLOT[s].evc = EG_OFF;
- CH->SLOT[s].eve = EG_OFF+1;
- CH->SLOT[s].evs = 0;
- }
- }
-#if BUILD_Y8950
- if(OPL->type&OPL_TYPE_ADPCM)
- {
- YM_DELTAT *DELTAT = OPL->deltat;
-
- DELTAT->freqbase = OPL->freqbase;
- DELTAT->output_pointer = outd;
- DELTAT->portshift = 5;
- DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
- YM_DELTAT_ADPCM_Reset(DELTAT,0);
- }
-#endif
-}
-
-/* ---------- Create one of vietual YM3812 ---------- */
-/* 'rate' is sampling rate and 'bufsiz' is the size of the */
-FM_OPL *OPLCreate(int type, int clock, int rate)
-{
- char *ptr;
- FM_OPL *OPL;
- int state_size;
- int max_ch = 9; /* normaly 9 channels */
-
- if( OPL_LockTable() ==-1) return NULL;
- /* allocate OPL state space */
- state_size = sizeof(FM_OPL);
- state_size += sizeof(OPL_CH)*max_ch;
-#if BUILD_Y8950
- if(type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT);
-#endif
- /* allocate memory block */
- ptr = malloc(state_size);
- if(ptr==NULL) return NULL;
- /* clear */
- memset(ptr,0,state_size);
- OPL = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL);
- OPL->P_CH = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
-#if BUILD_Y8950
- if(type&OPL_TYPE_ADPCM) OPL->deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT);
-#endif
- /* set channel state pointer */
- OPL->type = type;
- OPL->clock = clock;
- OPL->rate = rate;
- OPL->max_ch = max_ch;
- /* init grobal tables */
- OPL_initalize(OPL);
- /* reset chip */
- OPLResetChip(OPL);
-#ifdef OPL_OUTPUT_LOG
- if(!opl_dbg_fp)
- {
- opl_dbg_fp = fopen("opllog.opl","wb");
- opl_dbg_maxchip = 0;
- }
- if(opl_dbg_fp)
- {
- opl_dbg_opl[opl_dbg_maxchip] = OPL;
- fprintf(opl_dbg_fp,"%c%c%c%c%c%c",0x00+opl_dbg_maxchip,
- type,
- clock&0xff,
- (clock/0x100)&0xff,
- (clock/0x10000)&0xff,
- (clock/0x1000000)&0xff);
- opl_dbg_maxchip++;
- }
-#endif
- return OPL;
-}
-
-/* ---------- Destroy one of vietual YM3812 ---------- */
-void OPLDestroy(FM_OPL *OPL)
-{
-#ifdef OPL_OUTPUT_LOG
- if(opl_dbg_fp)
- {
- fclose(opl_dbg_fp);
- opl_dbg_fp = NULL;
- }
-#endif
- OPL_UnLockTable();
- free(OPL);
-}
-
-/* ---------- Option handlers ---------- */
-
-void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)
-{
- OPL->TimerHandler = TimerHandler;
- OPL->TimerParam = channelOffset;
-}
-void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param)
-{
- OPL->IRQHandler = IRQHandler;
- OPL->IRQParam = param;
-}
-void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param)
-{
- OPL->UpdateHandler = UpdateHandler;
- OPL->UpdateParam = param;
-}
-#if BUILD_Y8950
-void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param)
-{
- OPL->porthandler_w = PortHandler_w;
- OPL->porthandler_r = PortHandler_r;
- OPL->port_param = param;
-}
-
-void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param)
-{
- OPL->keyboardhandler_w = KeyboardHandler_w;
- OPL->keyboardhandler_r = KeyboardHandler_r;
- OPL->keyboard_param = param;
-}
-#endif
-/* ---------- YM3812 I/O interface ---------- */
-int OPLWrite(FM_OPL *OPL,int a,int v)
-{
- if( !(a&1) )
- { /* address port */
- OPL->address = v & 0xff;
- }
- else
- { /* data port */
- if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
-#ifdef OPL_OUTPUT_LOG
- if(opl_dbg_fp)
- {
- for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
- if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
- fprintf(opl_dbg_fp,"%c%c%c",0x10+opl_dbg_chip,OPL->address,v);
- }
-#endif
- OPLWriteReg(OPL,OPL->address,v);
- }
- return OPL->status>>7;
-}
-
-unsigned char OPLRead(FM_OPL *OPL,int a)
-{
- if( !(a&1) )
- { /* status port */
- return OPL->status & (OPL->statusmask|0x80);
- }
- /* data port */
- switch(OPL->address)
- {
- case 0x05: /* KeyBoard IN */
- if(OPL->type&OPL_TYPE_KEYBOARD)
- {
- if(OPL->keyboardhandler_r)
- return OPL->keyboardhandler_r(OPL->keyboard_param);
- else
- LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n"));
- }
- return 0;
-#if 0
- case 0x0f: /* ADPCM-DATA */
- return 0;
-#endif
- case 0x19: /* I/O DATA */
- if(OPL->type&OPL_TYPE_IO)
- {
- if(OPL->porthandler_r)
- return OPL->porthandler_r(OPL->port_param);
- else
- LOG(LOG_WAR,("OPL:read unmapped I/O port\n"));
- }
- return 0;
- case 0x1a: /* PCM-DATA */
- return 0;
- }
- return 0;
-}
-
-int OPLTimerOver(FM_OPL *OPL,int c)
-{
- if( c )
- { /* Timer B */
- OPL_STATUS_SET(OPL,0x20);
- }
- else
- { /* Timer A */
- OPL_STATUS_SET(OPL,0x40);
- /* CSM mode key,TL controll */
- if( OPL->mode & 0x80 )
- { /* CSM mode total level latch and auto key on */
- int ch;
- if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
- for(ch=0;ch<9;ch++)
- CSMKeyControll( &OPL->P_CH[ch] );
- }
- }
- /* reload timer */
- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase);
- return OPL->status>>7;
-}
diff --git a/src/adplug/core/fmopl.cc b/src/adplug/core/fmopl.cc
new file mode 100644
index 000000000000..348e51c36659
--- /dev/null
+++ b/src/adplug/core/fmopl.cc
@@ -0,0 +1,1393 @@
+/*
+**
+** File: fmopl.c -- software implementation of FM sound generator
+**
+** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
+**
+** Version 0.37a
+**
+*/
+
+/*
+ preliminary :
+ Problem :
+ note:
+*/
+
+/* This version of fmopl.c is a fork of the MAME one, relicensed under the LGPL.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define HAS_YM3812 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <math.h>
+//#include "driver.h" /* use M.A.M.E. */
+#include "fmopl.h"
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+
+/* -------------------- for debug --------------------- */
+/* #define OPL_OUTPUT_LOG */
+#ifdef OPL_OUTPUT_LOG
+static FILE *opl_dbg_fp = nullptr;
+static FM_OPL *opl_dbg_opl[16];
+static int opl_dbg_maxchip,opl_dbg_chip;
+#endif
+
+/* -------------------- preliminary define section --------------------- */
+/* attack/decay rate time rate */
+#define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */
+#define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */
+
+#define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */
+
+#define FREQ_BITS 24 /* frequency turn */
+
+/* counter bits = 20 , octerve 7 */
+#define FREQ_RATE (1<<(FREQ_BITS-20))
+#define TL_BITS (FREQ_BITS+2)
+
+/* final output shift , limit minimum and maximum */
+#define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */
+#define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
+#define OPL_MINOUT (-0x8000<<OPL_OUTSB)
+
+/* -------------------- quality selection --------------------- */
+
+/* sinwave entries */
+/* used static memory = SIN_ENT * 4 (byte) */
+#define SIN_ENT 2048
+
+/* output level entries (envelope,sinwave) */
+/* envelope counter lower bits */
+#define ENV_BITS 16
+/* envelope output entries */
+#define EG_ENT 4096
+/* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
+/* used static memory = EG_ENT*4 (byte) */
+
+#define EG_OFF ((2*EG_ENT)<<ENV_BITS) /* OFF */
+#define EG_DED EG_OFF
+#define EG_DST (EG_ENT<<ENV_BITS) /* DECAY START */
+#define EG_AED EG_DST
+#define EG_AST 0 /* ATTACK START */
+
+#define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */
+
+/* LFO table entries */
+#define VIB_ENT 512
+#define VIB_SHIFT (32-9)
+#define AMS_ENT 512
+#define AMS_SHIFT (32-9)
+
+#define VIB_RATE 256
+
+/* -------------------- local defines , macros --------------------- */
+
+/* register number to channel number , slot offset */
+#define SLOT1 0
+#define SLOT2 1
+
+/* envelope phase */
+#define ENV_MOD_RR 0x00
+#define ENV_MOD_DR 0x01
+#define ENV_MOD_AR 0x02
+
+/* -------------------- tables --------------------- */
+static const int slot_array[32]=
+{
+ 0, 2, 4, 1, 3, 5,-1,-1,
+ 6, 8,10, 7, 9,11,-1,-1,
+ 12,14,16,13,15,17,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1
+};
+
+/* key scale level */
+/* table is 3dB/OCT , DV converts this in TL step at 6dB/OCT */
+#define DV (EG_STEP/2)
+#define U(x) ((UINT32)(x))
+static const UINT32 KSL_TABLE[8*16]=
+{
+ /* OCT 0 */
+ U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),
+ U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),
+ U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),
+ U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),
+ /* OCT 1 */
+ U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),
+ U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),
+ U( 0.000/DV),U( 0.750/DV),U( 1.125/DV),U( 1.500/DV),
+ U( 1.875/DV),U( 2.250/DV),U( 2.625/DV),U( 3.000/DV),
+ /* OCT 2 */
+ U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),
+ U( 0.000/DV),U( 1.125/DV),U( 1.875/DV),U( 2.625/DV),
+ U( 3.000/DV),U( 3.750/DV),U( 4.125/DV),U( 4.500/DV),
+ U( 4.875/DV),U( 5.250/DV),U( 5.625/DV),U( 6.000/DV),
+ /* OCT 3 */
+ U( 0.000/DV),U( 0.000/DV),U( 0.000/DV),U( 1.875/DV),
+ U( 3.000/DV),U( 4.125/DV),U( 4.875/DV),U( 5.625/DV),
+ U( 6.000/DV),U( 6.750/DV),U( 7.125/DV),U( 7.500/DV),
+ U( 7.875/DV),U( 8.250/DV),U( 8.625/DV),U( 9.000/DV),
+ /* OCT 4 */
+ U( 0.000/DV),U( 0.000/DV),U( 3.000/DV),U( 4.875/DV),
+ U( 6.000/DV),U( 7.125/DV),U( 7.875/DV),U( 8.625/DV),
+ U( 9.000/DV),U( 9.750/DV),U(10.125/DV),U(10.500/DV),
+ U(10.875/DV),U(11.250/DV),U(11.625/DV),U(12.000/DV),
+ /* OCT 5 */
+ U( 0.000/DV),U( 3.000/DV),U( 6.000/DV),U( 7.875/DV),
+ U( 9.000/DV),U(10.125/DV),U(10.875/DV),U(11.625/DV),
+ U(12.000/DV),U(12.750/DV),U(13.125/DV),U(13.500/DV),
+ U(13.875/DV),U(14.250/DV),U(14.625/DV),U(15.000/DV),
+ /* OCT 6 */
+ U( 0.000/DV),U( 6.000/DV),U( 9.000/DV),U(10.875/DV),
+ U(12.000/DV),U(13.125/DV),U(13.875/DV),U(14.625/DV),
+ U(15.000/DV),U(15.750/DV),U(16.125/DV),U(16.500/DV),
+ U(16.875/DV),U(17.250/DV),U(17.625/DV),U(18.000/DV),
+ /* OCT 7 */
+ U( 0.000/DV),U( 9.000/DV),U(12.000/DV),U(13.875/DV),
+ U(15.000/DV),U(16.125/DV),U(16.875/DV),U(17.625/DV),
+ U(18.000/DV),U(18.750/DV),U(19.125/DV),U(19.500/DV),
+ U(19.875/DV),U(20.250/DV),U(20.625/DV),U(21.000/DV)
+};
+#undef U
+#undef DV
+
+/* sustain lebel table (3db per step) */
+/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
+#define SC(db) (INT32)((db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST)
+static const INT32 SL_TABLE[16]={
+ SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
+ SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
+};
+#undef SC
+
+#define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */
+/* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */
+/* TL_TABLE[ 0 to TL_MAX ] : plus section */
+/* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
+static INT32 *TL_TABLE;
+
+/* pointers to TL_TABLE with sinwave output offset */
+static INT32 **SIN_TABLE;
+
+/* LFO table */
+static INT32 *AMS_TABLE;
+static INT32 *VIB_TABLE;
+
+/* envelope output curve table */
+/* attack + decay + OFF */
+static INT32 ENV_CURVE[2*EG_ENT+1];
+
+/* multiple table */
+#define ML 2
+static const UINT32 MUL_TABLE[16]= {
+/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
+ ML/2, 1*ML, 2*ML, 3*ML, 4*ML, 5*ML, 6*ML, 7*ML,
+ 8*ML, 9*ML,10*ML,10*ML,12*ML,12*ML,15*ML,15*ML
+};
+#undef ML
+
+/* dummy attack / decay rate ( when rate == 0 ) */
+static INT32 RATE_0[16]=
+{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+/* -------------------- static state --------------------- */
+
+/* lock level of common table */
+static int num_lock = 0;
+
+/* work table */
+static void *cur_chip = nullptr; /* current chip point */
+/* currenct chip state */
+/* static OPLSAMPLE *bufL,*bufR; */
+static OPL_CH *S_CH;
+static OPL_CH *E_CH;
+OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
+
+static INT32 outd[1];
+static INT32 ams;
+static INT32 vib;
+INT32 *ams_table;
+INT32 *vib_table;
+static INT32 amsIncr;
+static INT32 vibIncr;
+static INT32 feedback2; /* connect for SLOT 2 */
+
+/* log output level */
+#define LOG_ERR 3 /* ERROR */
+#define LOG_WAR 2 /* WARNING */
+#define LOG_INF 1 /* INFORMATION */
+
+//#define LOG_LEVEL LOG_INF
+#define LOG_LEVEL LOG_ERR
+
+//#define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x
+#define LOG(n,x)
+
+/* --------------------- subroutines --------------------- */
+
+static inline int Limit( int val, int max, int min ) {
+ if ( val > max )
+ val = max;
+ else if ( val < min )
+ val = min;
+
+ return val;
+}
+
+/* status set and IRQ handling */
+static inline void OPL_STATUS_SET(FM_OPL *OPL,int flag)
+{
+ /* set status flag */
+ OPL->status |= flag;
+ if(!(OPL->status & 0x80))
+ {
+ if(OPL->status & OPL->statusmask)
+ { /* IRQ on */
+ OPL->status |= 0x80;
+ /* callback user interrupt handler (IRQ is OFF to ON) */
+ if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1);
+ }
+ }
+}
+
+/* status reset and IRQ handling */
+static inline void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
+{
+ /* reset status flag */
+ OPL->status &=~flag;
+ if((OPL->status & 0x80))
+ {
+ if (!(OPL->status & OPL->statusmask) )
+ {
+ OPL->status &= 0x7f;
+ /* callback user interrupt handler (IRQ is ON to OFF) */
+ if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
+ }
+ }
+}
+
+/* IRQ mask set */
+static inline void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag)
+{
+ OPL->statusmask = flag;
+ /* IRQ handling check */
+ OPL_STATUS_SET(OPL,0);
+ OPL_STATUS_RESET(OPL,0);
+}
+
+/* ----- key on ----- */
+static inline void OPL_KEYON(OPL_SLOT *SLOT)
+{
+ /* sin wave restart */
+ SLOT->Cnt = 0;
+ /* set attack */
+ SLOT->evm = ENV_MOD_AR;
+ SLOT->evs = SLOT->evsa;
+ SLOT->evc = EG_AST;
+ SLOT->eve = EG_AED;
+}
+/* ----- key off ----- */
+static inline void OPL_KEYOFF(OPL_SLOT *SLOT)
+{
+ if( SLOT->evm > ENV_MOD_RR)
+ {
+ /* set envelope counter from envleope output */
+ SLOT->evm = ENV_MOD_RR;
+ if( !(SLOT->evc&EG_DST) )
+ //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
+ SLOT->evc = EG_DST;
+ SLOT->eve = EG_DED;
+ SLOT->evs = SLOT->evsr;
+ }
+}
+
+/* ---------- calcrate Envelope Generator & Phase Generator ---------- */
+/* return : envelope output */
+static inline UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
+{
+ /* calcrate envelope generator */
+ if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
+ {
+ switch( SLOT->evm ){
+ case ENV_MOD_AR: /* ATTACK -> DECAY1 */
+ /* next DR */
+ SLOT->evm = ENV_MOD_DR;
+ SLOT->evc = EG_DST;
+ SLOT->eve = SLOT->SL;
+ SLOT->evs = SLOT->evsd;
+ break;
+ case ENV_MOD_DR: /* DECAY -> SL or RR */
+ SLOT->evc = SLOT->SL;
+ SLOT->eve = EG_DED;
+ if(SLOT->eg_typ)
+ {
+ SLOT->evs = 0;
+ }
+ else
+ {
+ SLOT->evm = ENV_MOD_RR;
+ SLOT->evs = SLOT->evsr;
+ }
+ break;
+ case ENV_MOD_RR: /* RR -> OFF */
+ SLOT->evc = EG_OFF;
+ SLOT->eve = EG_OFF+1;
+ SLOT->evs = 0;
+ break;
+ }
+ }
+ /* calcrate envelope */
+ return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0);
+}
+
+/* set algorythm connection */
+static void set_algorythm( OPL_CH *CH)
+{
+ INT32 *carrier = &outd[0];
+ CH->connect1 = CH->CON ? carrier : &feedback2;
+ CH->connect2 = carrier;
+}
+
+/* ---------- frequency counter for operater update ---------- */
+static inline void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
+{
+ int ksr;
+
+ /* frequency step counter */
+ SLOT->Incr = CH->fc * SLOT->mul;
+ ksr = CH->kcode >> SLOT->KSR;
+
+ if( SLOT->ksr != ksr )
+ {
+ SLOT->ksr = ksr;
+ /* attack , decay rate recalcration */
+ SLOT->evsa = SLOT->AR[ksr];
+ SLOT->evsd = SLOT->DR[ksr];
+ SLOT->evsr = SLOT->RR[ksr];
+ }
+ SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
+}
+
+/* set multi,am,vib,EG-TYP,KSR,mul */
+static inline void set_mul(FM_OPL *OPL,int slot,int v)
+{
+ OPL_CH *CH = &OPL->P_CH[slot/2];
+ OPL_SLOT *SLOT = &CH->SLOT[slot&1];
+
+ SLOT->mul = MUL_TABLE[v&0x0f];
+ SLOT->KSR = (v&0x10) ? 0 : 2;
+ SLOT->eg_typ = (v&0x20)>>5;
+ SLOT->vib = (v&0x40);
+ SLOT->ams = (v&0x80);
+ CALC_FCSLOT(CH,SLOT);
+}
+
+/* set ksl & tl */
+static inline void set_ksl_tl(FM_OPL *OPL,int slot,int v)
+{
+ OPL_CH *CH = &OPL->P_CH[slot/2];
+ OPL_SLOT *SLOT = &CH->SLOT[slot&1];
+ int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */
+
+ SLOT->ksl = ksl ? 3-ksl : 31;
+ SLOT->TL = (v&0x3f)*(0.75/EG_STEP); /* 0.75db step */
+
+ if( !(OPL->mode&0x80) )
+ { /* not CSM latch total level */
+ SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
+ }
+}
+
+/* set attack rate & decay rate */
+static inline void set_ar_dr(FM_OPL *OPL,int slot,int v)
+{
+ OPL_CH *CH = &OPL->P_CH[slot/2];
+ OPL_SLOT *SLOT = &CH->SLOT[slot&1];
+ int ar = v>>4;
+ int dr = v&0x0f;
+
+ SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0;
+ SLOT->evsa = SLOT->AR[SLOT->ksr];
+ if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa;
+
+ SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
+ SLOT->evsd = SLOT->DR[SLOT->ksr];
+ if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd;
+}
+
+/* set sustain level & release rate */
+static inline void set_sl_rr(FM_OPL *OPL,int slot,int v)
+{
+ OPL_CH *CH = &OPL->P_CH[slot/2];
+ OPL_SLOT *SLOT = &CH->SLOT[slot&1];
+ int sl = v>>4;
+ int rr = v & 0x0f;
+
+ SLOT->SL = SL_TABLE[sl];
+ if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL;
+ SLOT->RR = &OPL->DR_TABLE[rr<<2];
+ SLOT->evsr = SLOT->RR[SLOT->ksr];
+ if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr;
+}
+
+/* operator output calcrator */
+#define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
+/* ---------- calcrate one of channel ---------- */
+static inline void OPL_CALC_CH( OPL_CH *CH )
+{
+ UINT32 env_out;
+ OPL_SLOT *SLOT;
+
+ feedback2 = 0;
+ /* SLOT 1 */
+ SLOT = &CH->SLOT[SLOT1];
+ env_out=OPL_CALC_SLOT(SLOT);
+ if( env_out < EG_ENT-1 )
+ {
+ /* PG */
+ if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
+ else SLOT->Cnt += SLOT->Incr;
+ /* connectoion */
+ if(CH->FB)
+ {
+ int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
+ CH->op1_out[1] = CH->op1_out[0];
+ *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
+ }
+ else
+ {
+ *CH->connect1 += OP_OUT(SLOT,env_out,0);
+ }
+ }else
+ {
+ CH->op1_out[1] = CH->op1_out[0];
+ CH->op1_out[0] = 0;
+ }
+ /* SLOT 2 */
+ SLOT = &CH->SLOT[SLOT2];
+ env_out=OPL_CALC_SLOT(SLOT);
+ if( env_out < EG_ENT-1 )
+ {
+ /* PG */
+ if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
+ else SLOT->Cnt += SLOT->Incr;
+ /* connectoion */
+ outd[0] += OP_OUT(SLOT,env_out, feedback2);
+ }
+}
+
+/* ---------- calcrate rythm block ---------- */
+#define WHITE_NOISE_db 6.0
+static inline void OPL_CALC_RH( OPL_CH *CH )
+{
+ UINT32 env_tam,env_sd,env_top,env_hh;
+ int whitenoise = (rand()&1)*(WHITE_NOISE_db/EG_STEP);
+ INT32 tone8;
+
+ OPL_SLOT *SLOT;
+ int env_out;
+
+ /* BD : same as FM serial mode and output level is large */
+ feedback2 = 0;
+ /* SLOT 1 */
+ SLOT = &CH[6].SLOT[SLOT1];
+ env_out=OPL_CALC_SLOT(SLOT);
+ if( env_out < EG_ENT-1 )
+ {
+ /* PG */
+ if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
+ else SLOT->Cnt += SLOT->Incr;
+ /* connectoion */
+ if(CH[6].FB)
+ {
+ int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB;
+ CH[6].op1_out[1] = CH[6].op1_out[0];
+ feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
+ }
+ else
+ {
+ feedback2 = OP_OUT(SLOT,env_out,0);
+ }
+ }else
+ {
+ feedback2 = 0;
+ CH[6].op1_out[1] = CH[6].op1_out[0];
+ CH[6].op1_out[0] = 0;
+ }
+ /* SLOT 2 */
+ SLOT = &CH[6].SLOT[SLOT2];
+ env_out=OPL_CALC_SLOT(SLOT);
+ if( env_out < EG_ENT-1 )
+ {
+ /* PG */
+ if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
+ else SLOT->Cnt += SLOT->Incr;
+ /* connectoion */
+ outd[0] += OP_OUT(SLOT,env_out, feedback2)*2;
+ }
+
+ // SD (17) = mul14[fnum7] + white noise
+ // TAM (15) = mul15[fnum8]
+ // TOP (18) = fnum6(mul18[fnum8]+whitenoise)
+ // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
+ env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise;
+ env_tam=OPL_CALC_SLOT(SLOT8_1);
+ env_top=OPL_CALC_SLOT(SLOT8_2);
+ env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise;
+
+ /* PG */
+ if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE);
+ else SLOT7_1->Cnt += 2*SLOT7_1->Incr;
+ if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE);
+ else SLOT7_2->Cnt += (CH[7].fc*8);
+ if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE);
+ else SLOT8_1->Cnt += SLOT8_1->Incr;
+ if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE);
+ else SLOT8_2->Cnt += (CH[8].fc*48);
+
+ tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
+
+ /* SD */
+ if( env_sd < EG_ENT-1 )
+ outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8;
+ /* TAM */
+ if( env_tam < EG_ENT-1 )
+ outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2;
+ /* TOP-CY */
+ if( env_top < EG_ENT-1 )
+ outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2;
+ /* HH */
+ if( env_hh < EG_ENT-1 )
+ outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2;
+}
+
+/* ----------- initialize time tabls ----------- */
+static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
+{
+ int i;
+ double rate;
+
+ /* make attack rate & decay rate tables */
+ for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
+ for (i = 4;i <= 60;i++){
+ rate = OPL->freqbase; /* frequency rate */
+ if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
+ rate *= 1<<((i>>2)-1); /* b2-5 : shift bit */
+ rate *= (double)(EG_ENT<<ENV_BITS);
+ OPL->AR_TABLE[i] = rate / ARRATE;
+ OPL->DR_TABLE[i] = rate / DRRATE;
+ }
+ // FIXME: warning: iteration 15u invokes undefined behavior
+ // for (i = 60; i < 76; i++)
+ for (i = 60; i < 75; i++)
+ {
+ OPL->AR_TABLE[i] = EG_AED-1;
+ OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
+ }
+#if 0
+ for (i = 0;i < 64 ;i++){ /* make for overflow area */
+ LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i,
+ ((double)(EG_ENT<<ENV_BITS) / OPL->AR_TABLE[i]) * (1000.0 / OPL->rate),
+ ((double)(EG_ENT<<ENV_BITS) / OPL->DR_TABLE[i]) * (1000.0 / OPL->rate) ));
+ }
+#endif
+}
+
+/* ---------- generic table initialize ---------- */
+static int OPLOpenTable( void )
+{
+ int s,t;
+ double rate;
+ int i,j;
+ double pom;
+
+ /* allocate dynamic tables */
+ if( (TL_TABLE = (INT32*)malloc(TL_MAX*2*sizeof(INT32))) == nullptr)
+ return 0;
+ if( (SIN_TABLE = (INT32**)malloc(SIN_ENT*4 *sizeof(INT32 *))) == nullptr)
+ {
+ free(TL_TABLE);
+ return 0;
+ }
+ if( (AMS_TABLE = (INT32*)malloc(AMS_ENT*2 *sizeof(INT32))) == nullptr)
+ {
+ free(TL_TABLE);
+ free(SIN_TABLE);
+ return 0;
+ }
+ if( (VIB_TABLE = (INT32*)malloc(VIB_ENT*2 *sizeof(INT32))) == nullptr)
+ {
+ free(TL_TABLE);
+ free(SIN_TABLE);
+ free(AMS_TABLE);
+ return 0;
+ }
+ /* make total level table */
+ for (t = 0;t < EG_ENT-1 ;t++){
+ rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20); /* dB -> voltage */
+ TL_TABLE[ t] = (int)rate;
+ TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
+/* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/
+ }
+ /* fill volume off area */
+ for ( t = EG_ENT-1; t < TL_MAX ;t++){
+ TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
+ }
+
+ /* make sinwave table (total level offet) */
+ /* degree 0 = degree 180 = off */
+ SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2] = &TL_TABLE[EG_ENT-1];
+ for (s = 1;s <= SIN_ENT/4;s++){
+ pom = sin(2*PI*s/SIN_ENT); /* sin */
+ pom = 20*log10(1/pom); /* decibel */
+ j = pom / EG_STEP; /* TL_TABLE steps */
+
+ /* degree 0 - 90 , degree 180 - 90 : plus section */
+ SIN_TABLE[ s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
+ /* degree 180 - 270 , degree 360 - 270 : minus section */
+ SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT -s] = &TL_TABLE[TL_MAX+j];
+/* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/
+ }
+ for (s = 0;s < SIN_ENT;s++)
+ {
+ SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
+ SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)];
+ SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s];
+ }
+
+ /* envelope counter -> envelope output table */
+ for (i=0; i<EG_ENT; i++)
+ {
+ /* ATTACK curve */
+ pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
+ /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
+ ENV_CURVE[i] = (int)pom;
+ /* DECAY ,RELEASE curve */
+ ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
+ }
+ /* off */
+ ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
+ /* make LFO ams table */
+ for (i=0; i<AMS_ENT; i++)
+ {
+ pom = (1.0+sin(2*PI*i/AMS_ENT))/2; /* sin */
+ AMS_TABLE[i] = (1.0/EG_STEP)*pom; /* 1dB */
+ AMS_TABLE[AMS_ENT+i] = (4.8/EG_STEP)*pom; /* 4.8dB */
+ }
+ /* make LFO vibrate table */
+ for (i=0; i<VIB_ENT; i++)
+ {
+ /* 100cent = 1seminote = 6% ?? */
+ pom = (double)VIB_RATE*0.06*sin(2*PI*i/VIB_ENT); /* +-100sect step */
+ VIB_TABLE[i] = VIB_RATE + (pom*0.07); /* +- 7cent */
+ VIB_TABLE[VIB_ENT+i] = VIB_RATE + (pom*0.14); /* +-14cent */
+ /* LOG(LOG_INF,("vib %d=%d\n",i,VIB_TABLE[VIB_ENT+i])); */
+ }
+ return 1;
+}
+
+
+static void OPLCloseTable( void )
+{
+ free(TL_TABLE);
+ free(SIN_TABLE);
+ free(AMS_TABLE);
+ free(VIB_TABLE);
+}
+
+/* CSM Key Controll */
+static inline void CSMKeyControll(OPL_CH *CH)
+{
+ OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
+ OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
+ /* all key off */
+ OPL_KEYOFF(slot1);
+ OPL_KEYOFF(slot2);
+ /* total level latch */
+ slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
+ slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
+ /* key on */
+ CH->op1_out[0] = CH->op1_out[1] = 0;
+ OPL_KEYON(slot1);
+ OPL_KEYON(slot2);
+}
+
+/* ---------- opl initialize ---------- */
+static void OPL_initalize(FM_OPL *OPL)
+{
+ int fn;
+
+ /* frequency base */
+ OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0;
+ /* Timer base time */
+ OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
+ /* make time tables */
+ init_timetables( OPL , OPL_ARRATE , OPL_DRRATE );
+ /* make fnumber -> increment counter table */
+ for( fn=0 ; fn < 1024 ; fn++ )
+ {
+ OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2;
+ }
+ /* LFO freq.table */
+ OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0;
+ OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0;
+}
+
+/* ---------- write a OPL registers ---------- */
+static void OPLWriteReg(FM_OPL *OPL, int r, int v)
+{
+ OPL_CH *CH;
+ int slot;
+ int block_fnum;
+
+ switch(r&0xe0)
+ {
+ case 0x00: /* 00-1f:controll */
+ switch(r&0x1f)
+ {
+ case 0x01:
+ /* wave selector enable */
+ if(OPL->type&OPL_TYPE_WAVESEL)
+ {
+ OPL->wavesel = v&0x20;
+ if(!OPL->wavesel)
+ {
+ /* preset compatible mode */
+ int c;
+ for(c=0;c<OPL->max_ch;c++)
+ {
+ OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
+ OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
+ }
+ }
+ }
+ return;
+ case 0x02: /* Timer 1 */
+ OPL->T[0] = (256-v)*4;
+ break;
+ case 0x03: /* Timer 2 */
+ OPL->T[1] = (256-v)*16;
+ return;
+ case 0x04: /* IRQ clear / mask and Timer enable */
+ if(v&0x80)
+ { /* IRQ flag clear */
+ OPL_STATUS_RESET(OPL,0x7f);
+ }
+ else
+ { /* set IRQ mask ,timer enable*/
+ UINT8 st1 = v&1;
+ UINT8 st2 = (v>>1)&1;
+ /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
+ OPL_STATUS_RESET(OPL,v&0x78);
+ OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01);
+ /* timer 2 */
+ if(OPL->st[1] != st2)
+ {
+ double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0;
+ OPL->st[1] = st2;
+ if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval);
+ }
+ /* timer 1 */
+ if(OPL->st[0] != st1)
+ {
+ double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0;
+ OPL->st[0] = st1;
+ if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval);
+ }
+ }
+ return;
+#if BUILD_Y8950
+ case 0x06: /* Key Board OUT */
+ if(OPL->type&OPL_TYPE_KEYBOARD)
+ {
+ if(OPL->keyboardhandler_w)
+ OPL->keyboardhandler_w(OPL->keyboard_param,v);
+ else
+ LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n"));
+ }
+ return;
+ case 0x07: /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
+ if(OPL->type&OPL_TYPE_ADPCM)
+ YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
+ return;
+ case 0x08: /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
+ OPL->mode = v;
+ v&=0x1f; /* for DELTA-T unit */
+ case 0x09: /* START ADD */
+ case 0x0a:
+ case 0x0b: /* STOP ADD */
+ case 0x0c:
+ case 0x0d: /* PRESCALE */
+ case 0x0e:
+ case 0x0f: /* ADPCM data */
+ case 0x10: /* DELTA-N */
+ case 0x11: /* DELTA-N */
+ case 0x12: /* EG-CTRL */
+ if(OPL->type&OPL_TYPE_ADPCM)
+ YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
+ return;
+#if 0
+ case 0x15: /* DAC data */
+ case 0x16:
+ case 0x17: /* SHIFT */
+ return;
+ case 0x18: /* I/O CTRL (Direction) */
+ if(OPL->type&OPL_TYPE_IO)
+ OPL->portDirection = v&0x0f;
+ return;
+ case 0x19: /* I/O DATA */
+ if(OPL->type&OPL_TYPE_IO)
+ {
+ OPL->portLatch = v;
+ if(OPL->porthandler_w)
+ OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
+ }
+ return;
+ case 0x1a: /* PCM data */
+ return;
+#endif
+#endif
+ }
+ break;
+ case 0x20: /* am,vib,ksr,eg type,mul */
+ slot = slot_array[r&0x1f];
+ if(slot == -1) return;
+ set_mul(OPL,slot,v);
+ return;
+ case 0x40:
+ slot = slot_array[r&0x1f];
+ if(slot == -1) return;
+ set_ksl_tl(OPL,slot,v);
+ return;
+ case 0x60:
+ slot = slot_array[r&0x1f];
+ if(slot == -1) return;
+ set_ar_dr(OPL,slot,v);
+ return;
+ case 0x80:
+ slot = slot_array[r&0x1f];
+ if(slot == -1) return;
+ set_sl_rr(OPL,slot,v);
+ return;
+ case 0xa0:
+ switch(r)
+ {
+ case 0xbd:
+ /* amsep,vibdep,r,bd,sd,tom,tc,hh */
+ {
+ UINT8 rkey = OPL->rythm^v;
+ OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
+ OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
+ OPL->rythm = v&0x3f;
+ if(OPL->rythm&0x20)
+ {
+#if 0
+ usrintf_showmessage("OPL Rythm mode select");
+#endif
+ /* BD key on/off */
+ if(rkey&0x10)
+ {
+ if(v&0x10)
+ {
+ OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
+ OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
+ OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
+ }
+ else
+ {
+ OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
+ OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
+ }
+ }
+ /* SD key on/off */
+ if(rkey&0x08)
+ {
+ if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
+ else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
+ }/* TAM key on/off */
+ if(rkey&0x04)
+ {
+ if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
+ else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
+ }
+ /* TOP-CY key on/off */
+ if(rkey&0x02)
+ {
+ if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
+ else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
+ }
+ /* HH key on/off */
+ if(rkey&0x01)
+ {
+ if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
+ else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
+ }
+ }
+ }
+ return;
+ }
+ /* keyon,block,fnum */
+ if( (r&0x0f) > 8) return;
+ CH = &OPL->P_CH[r&0x0f];
+ if(!(r&0x10))
+ { /* a0-a8 */
+ block_fnum = (CH->block_fnum&0x1f00) | v;
+ }
+ else
+ { /* b0-b8 */
+ int keyon = (v>>5)&1;
+ block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
+ if(CH->keyon != keyon)
+ {
+ if( (CH->keyon=keyon) )
+ {
+ CH->op1_out[0] = CH->op1_out[1] = 0;
+ OPL_KEYON(&CH->SLOT[SLOT1]);
+ OPL_KEYON(&CH->SLOT[SLOT2]);
+ }
+ else
+ {
+ OPL_KEYOFF(&CH->SLOT[SLOT1]);
+ OPL_KEYOFF(&CH->SLOT[SLOT2]);
+ }
+ }
+ }
+ /* update */
+ if(CH->block_fnum != block_fnum)
+ {
+ int blockRv = 7-(block_fnum>>10);
+ int fnum = block_fnum&0x3ff;
+ CH->block_fnum = block_fnum;
+
+ CH->ksl_base = KSL_TABLE[block_fnum>>6];
+ CH->fc = OPL->FN_TABLE[fnum]>>blockRv;
+ CH->kcode = CH->block_fnum>>9;
+ if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1;
+ CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
+ CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
+ }
+ return;
+ case 0xc0:
+ /* FB,C */
+ if( (r&0x0f) > 8) return;
+ CH = &OPL->P_CH[r&0x0f];
+ {
+ int feedback = (v>>1)&7;
+ CH->FB = feedback ? (8+1) - feedback : 0;
+ CH->CON = v&1;
+ set_algorythm(CH);
+ }
+ return;
+ case 0xe0: /* wave type */
+ slot = slot_array[r&0x1f];
+ if(slot == -1) return;
+ CH = &OPL->P_CH[slot/2];
+ if(OPL->wavesel)
+ {
+ /* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */
+ CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT];
+ }
+ return;
+ }
+}
+
+/* lock/unlock for common table */
+static int OPL_LockTable(void)
+{
+ num_lock++;
+ if(num_lock>1) return 0;
+ /* first time */
+ cur_chip = nullptr;
+ /* allocate total level table (128kb space) */
+ if( !OPLOpenTable() )
+ {
+ num_lock--;
+ return -1;
+ }
+ return 0;
+}
+
+static void OPL_UnLockTable(void)
+{
+ if(num_lock) num_lock--;
+ if(num_lock) return;
+ /* last time */
+ cur_chip = nullptr;
+ OPLCloseTable();
+}
+
+#if (BUILD_YM3812 || BUILD_YM3526)
+/*******************************************************************************/
+/* YM3812 local section */
+/*******************************************************************************/
+
+/* ---------- update one of chip ----------- */
+void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
+{
+ int i;
+ int data;
+ OPLSAMPLE *buf = buffer;
+ UINT32 amsCnt = OPL->amsCnt;
+ UINT32 vibCnt = OPL->vibCnt;
+ UINT8 rythm = OPL->rythm&0x20;
+ OPL_CH *CH,*R_CH;
+
+ if( (void *)OPL != cur_chip ){
+ cur_chip = (void *)OPL;
+ /* channel pointers */
+ S_CH = OPL->P_CH;
+ E_CH = &S_CH[9];
+ /* rythm slot */
+ SLOT7_1 = &S_CH[7].SLOT[SLOT1];
+ SLOT7_2 = &S_CH[7].SLOT[SLOT2];
+ SLOT8_1 = &S_CH[8].SLOT[SLOT1];
+ SLOT8_2 = &S_CH[8].SLOT[SLOT2];
+ /* LFO state */
+ amsIncr = OPL->amsIncr;
+ vibIncr = OPL->vibIncr;
+ ams_table = OPL->ams_table;
+ vib_table = OPL->vib_table;
+ }
+ R_CH = rythm ? &S_CH[6] : E_CH;
+ for( i=0; i < length ; i++ )
+ {
+ /* channel A channel B channel C */
+ /* LFO */
+ ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
+ vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
+ outd[0] = 0;
+ /* FM part */
+ for(CH=S_CH ; CH < R_CH ; CH++)
+ OPL_CALC_CH(CH);
+ /* Rythn part */
+ if(rythm)
+ OPL_CALC_RH(S_CH);
+ /* limit check */
+ data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
+ /* store to sound buffer */
+ buf[i] = data >> OPL_OUTSB;
+ }
+
+ OPL->amsCnt = amsCnt;
+ OPL->vibCnt = vibCnt;
+#ifdef OPL_OUTPUT_LOG
+ if(opl_dbg_fp)
+ {
+ for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
+ if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
+ fprintf(opl_dbg_fp,"%c%c%c",0x20+opl_dbg_chip,length&0xff,length/256);
+ }
+#endif
+}
+#endif /* (BUILD_YM3812 || BUILD_YM3526) */
+
+#if BUILD_Y8950
+
+void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
+{
+ int i;
+ int data;
+ OPLSAMPLE *buf = buffer;
+ UINT32 amsCnt = OPL->amsCnt;
+ UINT32 vibCnt = OPL->vibCnt;
+ UINT8 rythm = OPL->rythm&0x20;
+ OPL_CH *CH,*R_CH;
+ YM_DELTAT *DELTAT = OPL->deltat;
+
+ /* setup DELTA-T unit */
+ YM_DELTAT_DECODE_PRESET(DELTAT);
+
+ if( (void *)OPL != cur_chip ){
+ cur_chip = (void *)OPL;
+ /* channel pointers */
+ S_CH = OPL->P_CH;
+ E_CH = &S_CH[9];
+ /* rythm slot */
+ SLOT7_1 = &S_CH[7].SLOT[SLOT1];
+ SLOT7_2 = &S_CH[7].SLOT[SLOT2];
+ SLOT8_1 = &S_CH[8].SLOT[SLOT1];
+ SLOT8_2 = &S_CH[8].SLOT[SLOT2];
+ /* LFO state */
+ amsIncr = OPL->amsIncr;
+ vibIncr = OPL->vibIncr;
+ ams_table = OPL->ams_table;
+ vib_table = OPL->vib_table;
+ }
+ R_CH = rythm ? &S_CH[6] : E_CH;
+ for( i=0; i < length ; i++ )
+ {
+ /* channel A channel B channel C */
+ /* LFO */
+ ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
+ vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
+ outd[0] = 0;
+ /* deltaT ADPCM */
+ if( DELTAT->portstate )
+ YM_DELTAT_ADPCM_CALC(DELTAT);
+ /* FM part */
+ for(CH=S_CH ; CH < R_CH ; CH++)
+ OPL_CALC_CH(CH);
+ /* Rythn part */
+ if(rythm)
+ OPL_CALC_RH(S_CH);
+ /* limit check */
+ data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
+ /* store to sound buffer */
+ buf[i] = data >> OPL_OUTSB;
+ }
+ OPL->amsCnt = amsCnt;
+ OPL->vibCnt = vibCnt;
+ /* deltaT START flag */
+ if( !DELTAT->portstate )
+ OPL->status &= 0xfe;
+}
+#endif
+
+/* ---------- reset one of chip ---------- */
+void OPLResetChip(FM_OPL *OPL)
+{
+ int c,s;
+ int i;
+
+ /* reset chip */
+ OPL->mode = 0; /* normal mode */
+ OPL_STATUS_RESET(OPL,0x7f);
+ /* reset with register write */
+ OPLWriteReg(OPL,0x01,0); /* wabesel disable */
+ OPLWriteReg(OPL,0x02,0); /* Timer1 */
+ OPLWriteReg(OPL,0x03,0); /* Timer2 */
+ OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
+ for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
+ /* reset OPerator paramater */
+ for( c = 0 ; c < OPL->max_ch ; c++ )
+ {
+ OPL_CH *CH = &OPL->P_CH[c];
+ /* OPL->P_CH[c].PAN = OPN_CENTER; */
+ for(s = 0 ; s < 2 ; s++ )
+ {
+ /* wave table */
+ CH->SLOT[s].wavetable = &SIN_TABLE[0];
+ /* CH->SLOT[s].evm = ENV_MOD_RR; */
+ CH->SLOT[s].evc = EG_OFF;
+ CH->SLOT[s].eve = EG_OFF+1;
+ CH->SLOT[s].evs = 0;
+ }
+ }
+#if BUILD_Y8950
+ if(OPL->type&OPL_TYPE_ADPCM)
+ {
+ YM_DELTAT *DELTAT = OPL->deltat;
+
+ DELTAT->freqbase = OPL->freqbase;
+ DELTAT->output_pointer = outd;
+ DELTAT->portshift = 5;
+ DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
+ YM_DELTAT_ADPCM_Reset(DELTAT,0);
+ }
+#endif
+}
+
+/* ---------- Create one of vietual YM3812 ---------- */
+/* 'rate' is sampling rate and 'bufsiz' is the size of the */
+FM_OPL *OPLCreate(int type, int clock, int rate)
+{
+ char *ptr;
+ FM_OPL *OPL;
+ int state_size;
+ int max_ch = 9; /* normaly 9 channels */
+
+ if( OPL_LockTable() ==-1) return nullptr;
+ /* allocate OPL state space */
+ state_size = sizeof(FM_OPL);
+ state_size += sizeof(OPL_CH)*max_ch;
+#if BUILD_Y8950
+ if(type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT);
+#endif
+ /* allocate memory block */
+ ptr = (char*)malloc(state_size);
+ if(ptr==nullptr) return nullptr;
+ /* clear */
+ memset(ptr,0,state_size);
+ OPL = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL);
+ OPL->P_CH = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
+#if BUILD_Y8950
+ if(type&OPL_TYPE_ADPCM) OPL->deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT);
+#endif
+ /* set channel state pointer */
+ OPL->type = type;
+ OPL->clock = clock;
+ OPL->rate = rate;
+ OPL->max_ch = max_ch;
+ /* init grobal tables */
+ OPL_initalize(OPL);
+ /* reset chip */
+ OPLResetChip(OPL);
+#ifdef OPL_OUTPUT_LOG
+ if(!opl_dbg_fp)
+ {
+ opl_dbg_fp = fopen("opllog.opl","wb");
+ opl_dbg_maxchip = 0;
+ }
+ if(opl_dbg_fp)
+ {
+ opl_dbg_opl[opl_dbg_maxchip] = OPL;
+ fprintf(opl_dbg_fp,"%c%c%c%c%c%c",0x00+opl_dbg_maxchip,
+ type,
+ clock&0xff,
+ (clock/0x100)&0xff,
+ (clock/0x10000)&0xff,
+ (clock/0x1000000)&0xff);
+ opl_dbg_maxchip++;
+ }
+#endif
+ return OPL;
+}
+
+/* ---------- Destroy one of vietual YM3812 ---------- */
+void OPLDestroy(FM_OPL *OPL)
+{
+#ifdef OPL_OUTPUT_LOG
+ if(opl_dbg_fp)
+ {
+ fclose(opl_dbg_fp);
+ opl_dbg_fp = nullptr;
+ }
+#endif
+ OPL_UnLockTable();
+ free(OPL);
+}
+
+/* ---------- Option handlers ---------- */
+
+void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)
+{
+ OPL->TimerHandler = TimerHandler;
+ OPL->TimerParam = channelOffset;
+}
+void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param)
+{
+ OPL->IRQHandler = IRQHandler;
+ OPL->IRQParam = param;
+}
+void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param)
+{
+ OPL->UpdateHandler = UpdateHandler;
+ OPL->UpdateParam = param;
+}
+#if BUILD_Y8950
+void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param)
+{
+ OPL->porthandler_w = PortHandler_w;
+ OPL->porthandler_r = PortHandler_r;
+ OPL->port_param = param;
+}
+
+void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param)
+{
+ OPL->keyboardhandler_w = KeyboardHandler_w;
+ OPL->keyboardhandler_r = KeyboardHandler_r;
+ OPL->keyboard_param = param;
+}
+#endif
+/* ---------- YM3812 I/O interface ---------- */
+int OPLWrite(FM_OPL *OPL,int a,int v)
+{
+ if( !(a&1) )
+ { /* address port */
+ OPL->address = v & 0xff;
+ }
+ else
+ { /* data port */
+ if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
+#ifdef OPL_OUTPUT_LOG
+ if(opl_dbg_fp)
+ {
+ for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
+ if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
+ fprintf(opl_dbg_fp,"%c%c%c",0x10+opl_dbg_chip,OPL->address,v);
+ }
+#endif
+ OPLWriteReg(OPL,OPL->address,v);
+ }
+ return OPL->status>>7;
+}
+
+unsigned char OPLRead(FM_OPL *OPL,int a)
+{
+ if( !(a&1) )
+ { /* status port */
+ return OPL->status & (OPL->statusmask|0x80);
+ }
+ /* data port */
+ switch(OPL->address)
+ {
+ case 0x05: /* KeyBoard IN */
+ if(OPL->type&OPL_TYPE_KEYBOARD)
+ {
+ if(OPL->keyboardhandler_r)
+ return OPL->keyboardhandler_r(OPL->keyboard_param);
+ else
+ LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n"));
+ }
+ return 0;
+#if 0
+ case 0x0f: /* ADPCM-DATA */
+ return 0;
+#endif
+ case 0x19: /* I/O DATA */
+ if(OPL->type&OPL_TYPE_IO)
+ {
+ if(OPL->porthandler_r)
+ return OPL->porthandler_r(OPL->port_param);
+ else
+ LOG(LOG_WAR,("OPL:read unmapped I/O port\n"));
+ }
+ return 0;
+ case 0x1a: /* PCM-DATA */
+ return 0;
+ }
+ return 0;
+}
+
+int OPLTimerOver(FM_OPL *OPL,int c)
+{
+ if( c )
+ { /* Timer B */
+ OPL_STATUS_SET(OPL,0x20);
+ }
+ else
+ { /* Timer A */
+ OPL_STATUS_SET(OPL,0x40);
+ /* CSM mode key,TL controll */
+ if( OPL->mode & 0x80 )
+ { /* CSM mode total level latch and auto key on */
+ int ch;
+ if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
+ for(ch=0;ch<9;ch++)
+ CSMKeyControll( &OPL->P_CH[ch] );
+ }
+ }
+ /* reload timer */
+ if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase);
+ return OPL->status>>7;
+}
diff --git a/src/adplug/core/fprovide.cc b/src/adplug/core/fprovide.cc
new file mode 100644
index 000000000000..7b6c66507722
--- /dev/null
+++ b/src/adplug/core/fprovide.cc
@@ -0,0 +1,73 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2002 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * fprovide.cpp - File provider class framework, by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <string.h>
+#include <binio.h>
+#include <binfile.h>
+
+#include "fprovide.h"
+
+#include <libaudcore/audstrings.h>
+
+/***** CFileProvider *****/
+
+bool CFileProvider::extension(const std::string &filename,
+ const std::string &extension)
+{
+ return str_has_suffix_nocase(filename.c_str(), extension.c_str());
+}
+
+unsigned long CFileProvider::filesize(binistream *f)
+{
+ unsigned long oldpos = f->pos(), size;
+
+ f->seek(0, binio::End);
+ size = f->pos();
+ f->seek(oldpos, binio::Set);
+
+ return size;
+}
+
+/***** CProvider_Filesystem *****/
+
+binistream *CProvider_Filesystem::open(VFSFile &fd) const
+{
+ if(!fd) return 0;
+
+ vfsistream *f = new vfsistream(&fd);
+
+ if(!f) return 0;
+ if(f->error()) { delete f; return 0; }
+
+ // Open all files as little endian with IEEE floats by default
+ f->setFlag(binio::BigEndian, false); f->setFlag(binio::FloatIEEE);
+
+ return f;
+}
+
+void CProvider_Filesystem::close(binistream *f) const
+{
+ vfsistream *ff = (vfsistream *)f;
+
+ if(f) {
+ delete ff;
+ }
+}
diff --git a/src/adplug/core/fprovide.cxx b/src/adplug/core/fprovide.cxx
deleted file mode 100644
index 0d6b57b7ad3a..000000000000
--- a/src/adplug/core/fprovide.cxx
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2002 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * fprovide.cpp - File provider class framework, by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <string.h>
-#include <binio.h>
-#include <binfile.h>
-
-#include <glib.h>
-
-#include "fprovide.h"
-
-/***** CFileProvider *****/
-
-bool CFileProvider::extension(const std::string &filename,
- const std::string &extension)
-{
- const char *fname = filename.c_str(), *ext = extension.c_str();
-
- if(strlen(fname) < strlen(ext) ||
- g_ascii_strcasecmp(fname + strlen(fname) - strlen(ext), ext))
- return false;
- else
- return true;
-}
-
-unsigned long CFileProvider::filesize(binistream *f)
-{
- unsigned long oldpos = f->pos(), size;
-
- f->seek(0, binio::End);
- size = f->pos();
- f->seek(oldpos, binio::Set);
-
- return size;
-}
-
-/***** CProvider_Filesystem *****/
-
-binistream *CProvider_Filesystem::open(VFSFile *fd) const
-{
- vfsistream *f = new vfsistream(fd);
-
- if(!f) return 0;
- if(f->error()) { delete f; return 0; }
-
- // Open all files as little endian with IEEE floats by default
- f->setFlag(binio::BigEndian, false); f->setFlag(binio::FloatIEEE);
-
- return f;
-}
-
-void CProvider_Filesystem::close(binistream *f) const
-{
- vfsistream *ff = (vfsistream *)f;
-
- if(f) {
- delete ff;
- }
-}
diff --git a/src/adplug/core/fprovide.h b/src/adplug/core/fprovide.h
index ec4d9b5f4784..6755ee9b86f9 100644
--- a/src/adplug/core/fprovide.h
+++ b/src/adplug/core/fprovide.h
@@ -32,7 +32,7 @@ public:
{
}
- virtual binistream *open(VFSFile *) const = 0;
+ virtual binistream *open(VFSFile &) const = 0;
virtual void close(binistream *) const = 0;
static bool extension(const std::string &filename,
@@ -43,7 +43,7 @@ public:
class CProvider_Filesystem: public CFileProvider
{
public:
- virtual binistream *open(VFSFile *) const;
+ virtual binistream *open(VFSFile &) const;
virtual void close(binistream *f) const;
};
diff --git a/src/adplug/core/hsc.cc b/src/adplug/core/hsc.cc
new file mode 100644
index 000000000000..121d2d2bf321
--- /dev/null
+++ b/src/adplug/core/hsc.cc
@@ -0,0 +1,389 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * hsc.cpp - HSC Player by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <string.h>
+
+#include "hsc.h"
+#include "debug.h"
+
+/*** public methods **************************************/
+
+CPlayer *
+ChscPlayer::factory (Copl * newopl)
+{
+ return new ChscPlayer (newopl);
+}
+
+bool
+ChscPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ int i;
+
+ // file validation section
+ if (!f || !fp.extension (fd.filename (), ".hsc") || fp.filesize (f) > 59187)
+ {
+ AdPlug_LogWrite ("ChscPlayer::load(\"%s\"): Not a HSC file!\n",
+ fd.filename ());
+ fp.close (f);
+ return false;
+ }
+
+ // load section
+ for (i = 0; i < 128 * 12; i++) // load instruments
+ *((unsigned char *) instr + i) = f->readInt (1);
+ for (i = 0; i < 128; i++)
+ { // correct instruments
+ instr[i][2] ^= (instr[i][2] & 0x40) << 1;
+ instr[i][3] ^= (instr[i][3] & 0x40) << 1;
+ instr[i][11] >>= 4; // slide
+ }
+ for (i = 0; i < 51; i++)
+ song[i] = f->readInt (1); // load tracklist
+ for (i = 0; i < 50 * 64 * 9; i++) // load patterns
+ *((char *) patterns + i) = f->readInt (1);
+
+ fp.close (f);
+ rewind (0); // rewind module
+ return true;
+}
+
+bool
+ChscPlayer::update ()
+{
+ // general vars
+ unsigned char chan, pattnr, note, effect, eff_op, inst, vol, Okt, db;
+ unsigned short Fnr;
+ unsigned long pattoff;
+
+ del--; // player speed handling
+ if (del)
+ return !songend; // nothing done
+
+ if (fadein) // fade-in handling
+ fadein--;
+
+ pattnr = song[songpos];
+ if (pattnr == 0xff)
+ { // arrangement handling
+ songend = 1; // set end-flag
+ songpos = 0;
+ pattnr = song[songpos];
+ }
+ else if ((pattnr & 128) && (pattnr <= 0xb1))
+ { // goto pattern "nr"
+ songpos = song[songpos] & 127;
+ pattpos = 0;
+ pattnr = song[songpos];
+ songend = 1;
+ }
+
+ if (pattnr >= 50 || pattpos >= 64)
+ {
+ fprintf (stderr, "hsc: Invalid pattnr (%d) or pattpos (%d)!\n", (int) pattnr, (int) pattpos);
+ return false;
+ }
+
+ pattoff = pattpos * 9;
+ for (chan = 0; chan < 9; chan++)
+ { // handle all channels
+ note = patterns[pattnr][pattoff].note;
+ effect = patterns[pattnr][pattoff].effect;
+ pattoff++;
+
+ if (note & 128)
+ { // set instrument
+ setinstr (chan, effect);
+ continue;
+ }
+ eff_op = effect & 0x0f;
+ inst = channel[chan].inst;
+ if (note)
+ channel[chan].slide = 0;
+
+ switch (effect & 0xf0)
+ { // effect handling
+ case 0: // global effect
+ /* The following fx are unimplemented on purpose:
+ * 02 - Slide Mainvolume up
+ * 03 - Slide Mainvolume down (here: fade in)
+ * 04 - Set Mainvolume to 0
+ *
+ * This is because i've never seen any HSC modules using the fx this way.
+ * All modules use the fx the way, i've implemented it.
+ */
+ switch (eff_op)
+ {
+ case 1:
+ pattbreak++;
+ break; // jump to next pattern
+ case 3:
+ fadein = 31;
+ break; // fade in (divided by 2)
+ case 5:
+ mode6 = 1;
+ break; // 6 voice mode on
+ case 6:
+ mode6 = 0;
+ break; // 6 voice mode off
+ }
+ break;
+ case 0x20:
+ case 0x10: // manual slides
+ if (effect & 0x10)
+ {
+ channel[chan].freq += eff_op;
+ channel[chan].slide += eff_op;
+ }
+ else
+ {
+ channel[chan].freq -= eff_op;
+ channel[chan].slide -= eff_op;
+ }
+ if (!note)
+ setfreq (chan, channel[chan].freq);
+ break;
+ case 0x50: // set percussion instrument (unimplemented)
+ break;
+ case 0x60: // set feedback
+ opl->write (0xc0 + chan,
+ (instr[channel[chan].inst][8] & 1) + (eff_op << 1));
+ break;
+ case 0xa0: // set carrier volume
+ vol = eff_op << 2;
+ opl->write (0x43 + op_table[chan],
+ vol | (instr[channel[chan].inst][2] & ~63));
+ break;
+ case 0xb0: // set modulator volume
+ vol = eff_op << 2;
+ if (instr[inst][8] & 1)
+ opl->write (0x40 + op_table[chan],
+ vol | (instr[channel[chan].inst][3] & ~63));
+ else
+ opl->write (0x40 + op_table[chan], vol | (instr[inst][3] & ~63));
+ break;
+ case 0xc0: // set instrument volume
+ db = eff_op << 2;
+ opl->write (0x43 + op_table[chan],
+ db | (instr[channel[chan].inst][2] & ~63));
+ if (instr[inst][8] & 1)
+ opl->write (0x40 + op_table[chan],
+ db | (instr[channel[chan].inst][3] & ~63));
+ break;
+ case 0xd0:
+ pattbreak++;
+ songpos = eff_op;
+ songend = 1;
+ break; // position jump
+ case 0xf0: // set speed
+ speed = eff_op;
+ del = ++speed;
+ break;
+ }
+
+ if (fadein) // fade-in volume setting
+ setvolume (chan, fadein * 2, fadein * 2);
+
+ if (!note) // note handling
+ continue;
+ note--;
+
+ if ((note == 0x7f - 1) || ((note / 12) & ~7))
+ { // pause (7fh)
+ adl_freq[chan] &= ~32;
+ opl->write (0xb0 + chan, adl_freq[chan]);
+ continue;
+ }
+
+ // play the note
+ if (mtkmode) // imitate MPU-401 Trakker bug
+ note--;
+ Okt = ((note / 12) & 7) << 2;
+ Fnr = note_table[(note % 12)] + instr[inst][11] + channel[chan].slide;
+ channel[chan].freq = Fnr;
+ if (!mode6 || chan < 6)
+ adl_freq[chan] = Okt | 32;
+ else
+ adl_freq[chan] = Okt; // never set key for drums
+ opl->write (0xb0 + chan, 0);
+ setfreq (chan, Fnr);
+ if (mode6)
+ {
+ switch (chan)
+ { // play drums
+ case 6:
+ opl->write (0xbd, bd & ~16);
+ bd |= 48;
+ break; // bass drum
+ case 7:
+ opl->write (0xbd, bd & ~1);
+ bd |= 33;
+ break; // hihat
+ case 8:
+ opl->write (0xbd, bd & ~2);
+ bd |= 34;
+ break; // cymbal
+ }
+ opl->write (0xbd, bd);
+ }
+ }
+
+ del = speed; // player speed-timing
+ if (pattbreak)
+ { // do post-effect handling
+ pattpos = 0; // pattern break!
+ pattbreak = 0;
+ songpos++;
+ songpos %= 50;
+ if (!songpos)
+ songend = 1;
+ }
+ else
+ {
+ pattpos++;
+ pattpos &= 63; // advance in pattern data
+ if (!pattpos)
+ {
+ songpos++;
+ songpos %= 50;
+ if (!songpos)
+ songend = 1;
+ }
+ }
+ return !songend; // still playing
+}
+
+void
+ChscPlayer::rewind (int subsong)
+{
+ int i; // counter
+
+ // rewind HSC player
+ pattpos = 0;
+ songpos = 0;
+ pattbreak = 0;
+ speed = 2;
+ del = 1;
+ songend = 0;
+ mode6 = 0;
+ bd = 0;
+ fadein = 0;
+
+ opl->init (); // reset OPL chip
+ opl->write (1, 32);
+ opl->write (8, 128);
+ opl->write (0xbd, 0);
+
+ for (i = 0; i < 9; i++)
+ setinstr ((char) i, (char) i); // init channels
+}
+
+unsigned int
+ChscPlayer::getpatterns ()
+{
+ unsigned char poscnt, pattcnt = 0;
+
+ // count patterns
+ for (poscnt = 0; poscnt < 51 && song[poscnt] != 0xff; poscnt++)
+ if (song[poscnt] > pattcnt)
+ pattcnt = song[poscnt];
+
+ return (pattcnt + 1);
+}
+
+unsigned int
+ChscPlayer::getorders ()
+{
+ unsigned char poscnt;
+
+ // count positions
+ for (poscnt = 0; poscnt < 51; poscnt++)
+ if (song[poscnt] == 0xff)
+ break;
+
+ return poscnt;
+}
+
+unsigned int
+ChscPlayer::getinstruments ()
+{
+ unsigned char instcnt, instnum = 0, i;
+ bool isinst;
+
+ // count instruments
+ for (instcnt = 0; instcnt < 128; instcnt++)
+ {
+ isinst = false;
+ for (i = 0; i < 12; i++)
+ if (instr[instcnt][i])
+ isinst = true;
+ if (isinst)
+ instnum++;
+ }
+
+ return instnum;
+}
+
+/*** private methods *************************************/
+
+void
+ChscPlayer::setfreq (unsigned char chan, unsigned short freq)
+{
+ adl_freq[chan] = (adl_freq[chan] & ~3) | (freq >> 8);
+
+ opl->write (0xa0 + chan, freq & 0xff);
+ opl->write (0xb0 + chan, adl_freq[chan]);
+}
+
+void
+ChscPlayer::setvolume (unsigned char chan, int volc, int volm)
+{
+ unsigned char *ins = instr[channel[chan].inst];
+ char op = op_table[chan];
+
+ opl->write (0x43 + op, volc | (ins[2] & ~63));
+ if (ins[8] & 1) // carrier
+ opl->write (0x40 + op, volm | (ins[3] & ~63));
+ else
+ opl->write (0x40 + op, ins[3]); // modulator
+}
+
+void
+ChscPlayer::setinstr (unsigned char chan, unsigned char insnr)
+{
+ unsigned char *ins = instr[insnr];
+ char op = op_table[chan];
+
+ channel[chan].inst = insnr; // set internal instrument
+ opl->write (0xb0 + chan, 0); // stop old note
+
+ // set instrument
+ opl->write (0xc0 + chan, ins[8]);
+ opl->write (0x23 + op, ins[0]); // carrier
+ opl->write (0x20 + op, ins[1]); // modulator
+ opl->write (0x63 + op, ins[4]); // bits 0..3 = decay; 4..7 = attack
+ opl->write (0x60 + op, ins[5]);
+ opl->write (0x83 + op, ins[6]); // 0..3 = release; 4..7 = sustain
+ opl->write (0x80 + op, ins[7]);
+ opl->write (0xe3 + op, ins[9]); // bits 0..1 = Wellenform
+ opl->write (0xe0 + op, ins[10]);
+ setvolume (chan, ins[2] & 63, ins[3] & 63);
+}
diff --git a/src/adplug/core/hsc.cxx b/src/adplug/core/hsc.cxx
deleted file mode 100644
index e3e01123ed07..000000000000
--- a/src/adplug/core/hsc.cxx
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * hsc.cpp - HSC Player by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <string.h>
-
-#include "hsc.h"
-#include "debug.h"
-
-/*** public methods **************************************/
-
-CPlayer *
-ChscPlayer::factory (Copl * newopl)
-{
- return new ChscPlayer (newopl);
-}
-
-bool
-ChscPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- int i;
-
- // file validation section
- if (!f || !fp.extension (vfs_get_filename (fd), ".hsc") || fp.filesize (f) > 59187)
- {
- AdPlug_LogWrite ("ChscPlayer::load(\"%s\"): Not a HSC file!\n",
- vfs_get_filename (fd));
- fp.close (f);
- return false;
- }
-
- // load section
- for (i = 0; i < 128 * 12; i++) // load instruments
- *((unsigned char *) instr + i) = f->readInt (1);
- for (i = 0; i < 128; i++)
- { // correct instruments
- instr[i][2] ^= (instr[i][2] & 0x40) << 1;
- instr[i][3] ^= (instr[i][3] & 0x40) << 1;
- instr[i][11] >>= 4; // slide
- }
- for (i = 0; i < 51; i++)
- song[i] = f->readInt (1); // load tracklist
- for (i = 0; i < 50 * 64 * 9; i++) // load patterns
- *((char *) patterns + i) = f->readInt (1);
-
- fp.close (f);
- rewind (0); // rewind module
- return true;
-}
-
-bool
-ChscPlayer::update ()
-{
- // general vars
- unsigned char chan, pattnr, note, effect, eff_op, inst, vol, Okt, db;
- unsigned short Fnr;
- unsigned long pattoff;
-
- del--; // player speed handling
- if (del)
- return !songend; // nothing done
-
- if (fadein) // fade-in handling
- fadein--;
-
- pattnr = song[songpos];
- if (pattnr == 0xff)
- { // arrangement handling
- songend = 1; // set end-flag
- songpos = 0;
- pattnr = song[songpos];
- }
- else if ((pattnr & 128) && (pattnr <= 0xb1))
- { // goto pattern "nr"
- songpos = song[songpos] & 127;
- pattpos = 0;
- pattnr = song[songpos];
- songend = 1;
- }
-
- if (pattnr >= 50 || pattpos >= 64)
- {
- fprintf (stderr, "hsc: Invalid pattnr (%d) or pattpos (%d)!\n", (int) pattnr, (int) pattpos);
- return false;
- }
-
- pattoff = pattpos * 9;
- for (chan = 0; chan < 9; chan++)
- { // handle all channels
- note = patterns[pattnr][pattoff].note;
- effect = patterns[pattnr][pattoff].effect;
- pattoff++;
-
- if (note & 128)
- { // set instrument
- setinstr (chan, effect);
- continue;
- }
- eff_op = effect & 0x0f;
- inst = channel[chan].inst;
- if (note)
- channel[chan].slide = 0;
-
- switch (effect & 0xf0)
- { // effect handling
- case 0: // global effect
- /* The following fx are unimplemented on purpose:
- * 02 - Slide Mainvolume up
- * 03 - Slide Mainvolume down (here: fade in)
- * 04 - Set Mainvolume to 0
- *
- * This is because i've never seen any HSC modules using the fx this way.
- * All modules use the fx the way, i've implemented it.
- */
- switch (eff_op)
- {
- case 1:
- pattbreak++;
- break; // jump to next pattern
- case 3:
- fadein = 31;
- break; // fade in (divided by 2)
- case 5:
- mode6 = 1;
- break; // 6 voice mode on
- case 6:
- mode6 = 0;
- break; // 6 voice mode off
- }
- break;
- case 0x20:
- case 0x10: // manual slides
- if (effect & 0x10)
- {
- channel[chan].freq += eff_op;
- channel[chan].slide += eff_op;
- }
- else
- {
- channel[chan].freq -= eff_op;
- channel[chan].slide -= eff_op;
- }
- if (!note)
- setfreq (chan, channel[chan].freq);
- break;
- case 0x50: // set percussion instrument (unimplemented)
- break;
- case 0x60: // set feedback
- opl->write (0xc0 + chan,
- (instr[channel[chan].inst][8] & 1) + (eff_op << 1));
- break;
- case 0xa0: // set carrier volume
- vol = eff_op << 2;
- opl->write (0x43 + op_table[chan],
- vol | (instr[channel[chan].inst][2] & ~63));
- break;
- case 0xb0: // set modulator volume
- vol = eff_op << 2;
- if (instr[inst][8] & 1)
- opl->write (0x40 + op_table[chan],
- vol | (instr[channel[chan].inst][3] & ~63));
- else
- opl->write (0x40 + op_table[chan], vol | (instr[inst][3] & ~63));
- break;
- case 0xc0: // set instrument volume
- db = eff_op << 2;
- opl->write (0x43 + op_table[chan],
- db | (instr[channel[chan].inst][2] & ~63));
- if (instr[inst][8] & 1)
- opl->write (0x40 + op_table[chan],
- db | (instr[channel[chan].inst][3] & ~63));
- break;
- case 0xd0:
- pattbreak++;
- songpos = eff_op;
- songend = 1;
- break; // position jump
- case 0xf0: // set speed
- speed = eff_op;
- del = ++speed;
- break;
- }
-
- if (fadein) // fade-in volume setting
- setvolume (chan, fadein * 2, fadein * 2);
-
- if (!note) // note handling
- continue;
- note--;
-
- if ((note == 0x7f - 1) || ((note / 12) & ~7))
- { // pause (7fh)
- adl_freq[chan] &= ~32;
- opl->write (0xb0 + chan, adl_freq[chan]);
- continue;
- }
-
- // play the note
- if (mtkmode) // imitate MPU-401 Trakker bug
- note--;
- Okt = ((note / 12) & 7) << 2;
- Fnr = note_table[(note % 12)] + instr[inst][11] + channel[chan].slide;
- channel[chan].freq = Fnr;
- if (!mode6 || chan < 6)
- adl_freq[chan] = Okt | 32;
- else
- adl_freq[chan] = Okt; // never set key for drums
- opl->write (0xb0 + chan, 0);
- setfreq (chan, Fnr);
- if (mode6)
- {
- switch (chan)
- { // play drums
- case 6:
- opl->write (0xbd, bd & ~16);
- bd |= 48;
- break; // bass drum
- case 7:
- opl->write (0xbd, bd & ~1);
- bd |= 33;
- break; // hihat
- case 8:
- opl->write (0xbd, bd & ~2);
- bd |= 34;
- break; // cymbal
- }
- opl->write (0xbd, bd);
- }
- }
-
- del = speed; // player speed-timing
- if (pattbreak)
- { // do post-effect handling
- pattpos = 0; // pattern break!
- pattbreak = 0;
- songpos++;
- songpos %= 50;
- if (!songpos)
- songend = 1;
- }
- else
- {
- pattpos++;
- pattpos &= 63; // advance in pattern data
- if (!pattpos)
- {
- songpos++;
- songpos %= 50;
- if (!songpos)
- songend = 1;
- }
- }
- return !songend; // still playing
-}
-
-void
-ChscPlayer::rewind (int subsong)
-{
- int i; // counter
-
- // rewind HSC player
- pattpos = 0;
- songpos = 0;
- pattbreak = 0;
- speed = 2;
- del = 1;
- songend = 0;
- mode6 = 0;
- bd = 0;
- fadein = 0;
-
- opl->init (); // reset OPL chip
- opl->write (1, 32);
- opl->write (8, 128);
- opl->write (0xbd, 0);
-
- for (i = 0; i < 9; i++)
- setinstr ((char) i, (char) i); // init channels
-}
-
-unsigned int
-ChscPlayer::getpatterns ()
-{
- unsigned char poscnt, pattcnt = 0;
-
- // count patterns
- for (poscnt = 0; poscnt < 51 && song[poscnt] != 0xff; poscnt++)
- if (song[poscnt] > pattcnt)
- pattcnt = song[poscnt];
-
- return (pattcnt + 1);
-}
-
-unsigned int
-ChscPlayer::getorders ()
-{
- unsigned char poscnt;
-
- // count positions
- for (poscnt = 0; poscnt < 51; poscnt++)
- if (song[poscnt] == 0xff)
- break;
-
- return poscnt;
-}
-
-unsigned int
-ChscPlayer::getinstruments ()
-{
- unsigned char instcnt, instnum = 0, i;
- bool isinst;
-
- // count instruments
- for (instcnt = 0; instcnt < 128; instcnt++)
- {
- isinst = false;
- for (i = 0; i < 12; i++)
- if (instr[instcnt][i])
- isinst = true;
- if (isinst)
- instnum++;
- }
-
- return instnum;
-}
-
-/*** private methods *************************************/
-
-void
-ChscPlayer::setfreq (unsigned char chan, unsigned short freq)
-{
- adl_freq[chan] = (adl_freq[chan] & ~3) | (freq >> 8);
-
- opl->write (0xa0 + chan, freq & 0xff);
- opl->write (0xb0 + chan, adl_freq[chan]);
-}
-
-void
-ChscPlayer::setvolume (unsigned char chan, int volc, int volm)
-{
- unsigned char *ins = instr[channel[chan].inst];
- char op = op_table[chan];
-
- opl->write (0x43 + op, volc | (ins[2] & ~63));
- if (ins[8] & 1) // carrier
- opl->write (0x40 + op, volm | (ins[3] & ~63));
- else
- opl->write (0x40 + op, ins[3]); // modulator
-}
-
-void
-ChscPlayer::setinstr (unsigned char chan, unsigned char insnr)
-{
- unsigned char *ins = instr[insnr];
- char op = op_table[chan];
-
- channel[chan].inst = insnr; // set internal instrument
- opl->write (0xb0 + chan, 0); // stop old note
-
- // set instrument
- opl->write (0xc0 + chan, ins[8]);
- opl->write (0x23 + op, ins[0]); // carrier
- opl->write (0x20 + op, ins[1]); // modulator
- opl->write (0x63 + op, ins[4]); // bits 0..3 = decay; 4..7 = attack
- opl->write (0x60 + op, ins[5]);
- opl->write (0x83 + op, ins[6]); // 0..3 = release; 4..7 = sustain
- opl->write (0x80 + op, ins[7]);
- opl->write (0xe3 + op, ins[9]); // bits 0..1 = Wellenform
- opl->write (0xe0 + op, ins[10]);
- setvolume (chan, ins[2] & 63, ins[3] & 63);
-}
diff --git a/src/adplug/core/hsc.h b/src/adplug/core/hsc.h
index 80b88c3b50f8..b5a2ae7b6d6a 100644
--- a/src/adplug/core/hsc.h
+++ b/src/adplug/core/hsc.h
@@ -31,7 +31,7 @@ class ChscPlayer: public CPlayer
ChscPlayer(Copl *newopl): CPlayer(newopl), mtkmode(0) {}
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh() { return 18.2f; }; // refresh rate is fixed at 18.2Hz
diff --git a/src/adplug/core/hsp.cc b/src/adplug/core/hsp.cc
new file mode 100644
index 000000000000..e2eaf7a5d9cc
--- /dev/null
+++ b/src/adplug/core/hsp.cc
@@ -0,0 +1,86 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * hsp.cpp - HSP Loader by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <string.h>
+
+#include "hsp.h"
+
+CPlayer *
+ChspLoader::factory (Copl * newopl)
+{
+ return new ChspLoader (newopl);
+}
+
+bool
+ChspLoader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ unsigned long i, j, orgsize, filesize;
+ unsigned char *cmp, *org;
+ std::string filename (fd.filename ());
+
+ // file validation section
+ if (!fp.extension (filename, ".hsp"))
+ {
+ fp.close (f);
+ return false;
+ }
+
+ filesize = fp.filesize (f);
+ orgsize = f->readInt (2);
+ if (orgsize > 59187)
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // load section
+ cmp = new unsigned char[filesize];
+ for (i = 0; i < filesize; i++)
+ cmp[i] = f->readInt (1);
+ fp.close (f);
+
+ org = new unsigned char[orgsize];
+ for (i = 0, j = 0; i < filesize; j += cmp[i], i += 2)
+ { // RLE decompress
+ if (j >= orgsize)
+ break; // memory boundary check
+ memset (org + j, cmp[i + 1],
+ j + cmp[i] < orgsize ? cmp[i] : orgsize - j - 1);
+ }
+ delete[]cmp;
+
+ memcpy (instr, org, 128 * 12); // instruments
+ for (i = 0; i < 128; i++)
+ { // correct instruments
+ instr[i][2] ^= (instr[i][2] & 0x40) << 1;
+ instr[i][3] ^= (instr[i][3] & 0x40) << 1;
+ instr[i][11] >>= 4; // slide
+ }
+ memcpy (song, org + 128 * 12, 51); // tracklist
+ memcpy (patterns, org + 128 * 12 + 51, orgsize - 128 * 12 - 51); // patterns
+ delete[]org;
+
+ rewind (0);
+ return true;
+}
diff --git a/src/adplug/core/hsp.cxx b/src/adplug/core/hsp.cxx
deleted file mode 100644
index 81b983c00703..000000000000
--- a/src/adplug/core/hsp.cxx
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * hsp.cpp - HSP Loader by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <string.h>
-
-#include "hsp.h"
-
-CPlayer *
-ChspLoader::factory (Copl * newopl)
-{
- return new ChspLoader (newopl);
-}
-
-bool
-ChspLoader::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- unsigned long i, j, orgsize, filesize;
- unsigned char *cmp, *org;
- std::string filename (vfs_get_filename (fd));
-
- // file validation section
- if (!fp.extension (filename, ".hsp"))
- {
- fp.close (f);
- return false;
- }
-
- filesize = fp.filesize (f);
- orgsize = f->readInt (2);
- if (orgsize > 59187)
- {
- fp.close (f);
- return false;
- }
-
- // load section
- cmp = new unsigned char[filesize];
- for (i = 0; i < filesize; i++)
- cmp[i] = f->readInt (1);
- fp.close (f);
-
- org = new unsigned char[orgsize];
- for (i = 0, j = 0; i < filesize; j += cmp[i], i += 2)
- { // RLE decompress
- if (j >= orgsize)
- break; // memory boundary check
- memset (org + j, cmp[i + 1],
- j + cmp[i] < orgsize ? cmp[i] : orgsize - j - 1);
- }
- delete[]cmp;
-
- memcpy (instr, org, 128 * 12); // instruments
- for (i = 0; i < 128; i++)
- { // correct instruments
- instr[i][2] ^= (instr[i][2] & 0x40) << 1;
- instr[i][3] ^= (instr[i][3] & 0x40) << 1;
- instr[i][11] >>= 4; // slide
- }
- memcpy (song, org + 128 * 12, 51); // tracklist
- memcpy (patterns, org + 128 * 12 + 51, orgsize - 128 * 12 - 51); // patterns
- delete[]org;
-
- rewind (0);
- return true;
-}
diff --git a/src/adplug/core/hsp.h b/src/adplug/core/hsp.h
index caeb5ba8792c..691220d0e09c 100644
--- a/src/adplug/core/hsp.h
+++ b/src/adplug/core/hsp.h
@@ -33,7 +33,7 @@ public:
: ChscPlayer(newopl)
{};
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
};
#endif
diff --git a/src/adplug/core/hybrid.cc b/src/adplug/core/hybrid.cc
new file mode 100644
index 000000000000..7333c4edfd45
--- /dev/null
+++ b/src/adplug/core/hybrid.cc
@@ -0,0 +1,268 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * [xad] HYBRID player, by Riven the Mage <riven at ok.ru>
+ */
+
+/*
+ - discovery -
+
+ file(s) : HYBRID.EXE
+ type : Hybrid cracktro for Apache Longbow CD-RIP
+ tune : from 'Mig-29 Super Fulcrum' game by Domark
+ player : from 'Mig-29 Super Fulcrum' game by Domark
+*/
+
+#include "hybrid.h"
+#include "debug.h"
+
+const unsigned char
+ CxadhybridPlayer::hyb_adlib_registers[99] = {
+ 0xE0, 0x60, 0x80, 0x20, 0x40, 0xE3, 0x63, 0x83, 0x23, 0x43, 0xC0,
+ 0xE1, 0x61, 0x81, 0x21, 0x41, 0xE4, 0x64, 0x84, 0x24, 0x44, 0xC1,
+ 0xE2, 0x62, 0x82, 0x22, 0x42, 0xE5, 0x65, 0x85, 0x25, 0x45, 0xC2,
+ 0xE8, 0x68, 0x88, 0x28, 0x48, 0xEB, 0x6B, 0x8B, 0x2B, 0x4B, 0xC3,
+ 0xE9, 0x69, 0x89, 0x29, 0x49, 0xEC, 0x6C, 0x8C, 0x2C, 0x4C, 0xC4,
+ 0xEA, 0x6A, 0x8A, 0x2A, 0x4A, 0xED, 0x6D, 0x8D, 0x2D, 0x4D, 0xC5,
+ 0xF0, 0x70, 0x90, 0x30, 0x50, 0xF3, 0x73, 0x93, 0x33, 0x53, 0xC6,
+ 0xF1, 0x71, 0x91, 0x31, 0x51, 0xF4, 0x74, 0x94, 0x34, 0x54, 0xC7,
+ 0xF2, 0x72, 0x92, 0x32, 0x52, 0xF5, 0x75, 0x95, 0x35, 0x55, 0xC8
+};
+
+const unsigned short
+ CxadhybridPlayer::hyb_notes[98] = {
+ 0x0000, 0x0000,
+ 0x016B, 0x0181, 0x0198, 0x01B0, 0x01CA, 0x01E5, 0x0202, 0x0220, 0x0241,
+ 0x0263, 0x0287, 0x02AE,
+ 0x056B, 0x0581, 0x0598, 0x05B0, 0x05CA, 0x05E5, 0x0602, 0x0620, 0x0641,
+ 0x0663, 0x0687, 0x06AE,
+ 0x096B, 0x0981, 0x0998, 0x09B0, 0x09CA, 0x09E5, 0x0A02, 0x0A20, 0x0A41,
+ 0x0A63, 0x0A87, 0x0AAE,
+ 0x0D6B, 0x0D81, 0x0D98, 0x0DB0, 0x0DCA, 0x0DE5, 0x0E02, 0x0E20, 0x0E41,
+ 0x0E63, 0x0E87, 0x0EAE,
+ 0x116B, 0x1181, 0x1198, 0x11B0, 0x11CA, 0x11E5, 0x1202, 0x1220, 0x1241,
+ 0x1263, 0x1287, 0x12AE,
+ 0x156B, 0x1581, 0x1598, 0x15B0, 0x15CA, 0x15E5, 0x1602, 0x1620, 0x1641,
+ 0x1663, 0x1687, 0x16AE,
+ 0x196B, 0x1981, 0x1998, 0x19B0, 0x19CA, 0x19E5, 0x1A02, 0x1A20, 0x1A41,
+ 0x1A63, 0x1A87, 0x1AAE,
+ 0x1D6B, 0x1D81, 0x1D98, 0x1DB0, 0x1DCA, 0x1DE5, 0x1E02, 0x1E20, 0x1E41,
+ 0x1E63, 0x1E87, 0x1EAE
+};
+
+const unsigned char
+ CxadhybridPlayer::hyb_default_instrument[11] = {
+ 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00
+};
+
+CPlayer *
+CxadhybridPlayer::factory (Copl * newopl)
+{
+ return new CxadhybridPlayer (newopl);
+}
+
+bool
+CxadhybridPlayer::xadplayer_load ()
+{
+ if (xad.fmt != HYBRID)
+ return false;
+
+ // load instruments
+ hyb.inst = (hyb_instrument *) & tune[0];
+
+ // load order
+ hyb.order = &tune[0x1D4];
+
+ return true;
+}
+
+void
+CxadhybridPlayer::xadplayer_rewind (int subsong)
+{
+ int i;
+
+ hyb.order_pos = 0;
+ hyb.pattern_pos = 0;
+
+ hyb.speed = 6;
+ hyb.speed_counter = 1;
+
+ plr.speed = 1;
+
+ // init channel data
+ for (i = 0; i < 9; i++)
+ {
+ hyb.channel[i].freq = 0x2000;
+ hyb.channel[i].freq_slide = 0x0000;
+ }
+
+ // basic OPL init
+ opl_write (0x01, 0x20);
+ opl_write (0xBD, 0x40);
+ opl_write (0x08, 0x00);
+
+ // init OPL channels
+ for (i = 0; i < 9; i++)
+ {
+ for (int j = 0; j < 11; j++)
+ opl_write (hyb_adlib_registers[i * 11 + j],
+ 0x00 /* hyb_default_instrument[j] */ );
+
+ opl_write (0xA0 + i, 0x00);
+ opl_write (0xB0 + i, 0x20);
+ }
+}
+
+void
+CxadhybridPlayer::xadplayer_update ()
+{
+ int i, j;
+ unsigned char patpos, ordpos;
+
+ if (--hyb.speed_counter)
+ goto update_slides;
+
+ hyb.speed_counter = hyb.speed;
+
+ patpos = hyb.pattern_pos;
+ ordpos = hyb.order_pos;
+
+ // process channels
+ for (i = 0; i < 9; i++)
+ {
+ unsigned char *pos =
+ &tune[0xADE + (hyb.order[hyb.order_pos * 9 + i] * 64 * 2) +
+ (patpos * 2)];
+ // read event
+ unsigned short event = (pos[1] << 8) + pos[0];
+
+#ifdef DEBUG
+ AdPlug_LogWrite ("track %02X, channel %02X, event %04X:\n",
+ hyb.order[hyb.order_pos * 9 + i], i, event);
+#endif
+
+ // calculate variables
+ unsigned char note = event >> 9;
+ unsigned char ins = ((event & 0x01F0) >> 4);
+ unsigned char slide = event & 0x000F;
+
+ // play event
+ switch (note)
+ {
+ case 0x7D: // 0x7D: Set Speed
+ hyb.speed = event & 0xFF;
+ break;
+ case 0x7E: // 0x7E: Jump Position
+ hyb.order_pos = event & 0xFF;
+ hyb.pattern_pos = 0x3F;
+
+ // jumpback ?
+ if (hyb.order_pos <= ordpos)
+ plr.looping = 1;
+
+ break;
+ case 0x7F: // 0x7F: Pattern Break
+ hyb.pattern_pos = 0x3F;
+ break;
+ default:
+
+ // is instrument ?
+ if (ins)
+ for (j = 0; j < 11; j++)
+ opl_write (hyb_adlib_registers[i * 11 + j], *((unsigned char *) &hyb.inst[ins - 1] + 7 + j)); // +7 = skip name...
+
+ // is note ?
+ if (note)
+ {
+ hyb.channel[i].freq = hyb_notes[note];
+ hyb.channel[i].freq_slide = 0;
+ }
+
+ // is slide ?
+ if (slide)
+ {
+ hyb.channel[i].freq_slide = (((slide >> 3) * -1) * (slide & 7)) << 1;
+
+ if (slide & 0x80)
+ slide = -(slide & 7);
+ }
+
+ // set frequency
+ if (!(hyb.channel[i].freq & 0x2000))
+ {
+ opl_write (0xA0 + i, hyb.channel[i].freq & 0xFF);
+ opl_write (0xB0 + i, hyb.channel[i].freq >> 8);
+
+ hyb.channel[i].freq |= 0x2000;
+
+ opl_write (0xA0 + i, hyb.channel[i].freq & 0xFF);
+ opl_write (0xB0 + i, hyb.channel[i].freq >> 8);
+ }
+
+ break;
+ }
+ }
+
+ hyb.pattern_pos++;
+
+ // end of pattern ?
+ if (hyb.pattern_pos >= 0x40)
+ {
+ hyb.pattern_pos = 0;
+
+ hyb.order_pos++;
+ }
+
+update_slides:
+#ifdef DEBUG
+ AdPlug_LogWrite ("slides:\n");
+#endif
+ // update fine frequency slides
+ for (i = 0; i < 9; i++)
+ if (hyb.channel[i].freq_slide)
+ {
+ hyb.channel[i].freq =
+ (((hyb.channel[i].freq & 0x1FFF) +
+ hyb.channel[i].freq_slide) & 0x1FFF) | 0x2000;
+
+ opl_write (0xA0 + i, hyb.channel[i].freq & 0xFF);
+ opl_write (0xB0 + i, hyb.channel[i].freq >> 8);
+ }
+}
+
+float
+CxadhybridPlayer::xadplayer_getrefresh ()
+{
+ return 50.0f;
+}
+
+std::string CxadhybridPlayer::xadplayer_gettype ()
+{
+ return (std::string ("xad: hybrid player"));
+}
+
+std::string CxadhybridPlayer::xadplayer_getinstrument (unsigned int i)
+{
+ return (std::string (hyb.inst[i].name, 7));
+}
+
+unsigned int
+CxadhybridPlayer::xadplayer_getinstruments ()
+{
+ return 26;
+}
diff --git a/src/adplug/core/hybrid.cxx b/src/adplug/core/hybrid.cxx
deleted file mode 100644
index 7333c4edfd45..000000000000
--- a/src/adplug/core/hybrid.cxx
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * [xad] HYBRID player, by Riven the Mage <riven at ok.ru>
- */
-
-/*
- - discovery -
-
- file(s) : HYBRID.EXE
- type : Hybrid cracktro for Apache Longbow CD-RIP
- tune : from 'Mig-29 Super Fulcrum' game by Domark
- player : from 'Mig-29 Super Fulcrum' game by Domark
-*/
-
-#include "hybrid.h"
-#include "debug.h"
-
-const unsigned char
- CxadhybridPlayer::hyb_adlib_registers[99] = {
- 0xE0, 0x60, 0x80, 0x20, 0x40, 0xE3, 0x63, 0x83, 0x23, 0x43, 0xC0,
- 0xE1, 0x61, 0x81, 0x21, 0x41, 0xE4, 0x64, 0x84, 0x24, 0x44, 0xC1,
- 0xE2, 0x62, 0x82, 0x22, 0x42, 0xE5, 0x65, 0x85, 0x25, 0x45, 0xC2,
- 0xE8, 0x68, 0x88, 0x28, 0x48, 0xEB, 0x6B, 0x8B, 0x2B, 0x4B, 0xC3,
- 0xE9, 0x69, 0x89, 0x29, 0x49, 0xEC, 0x6C, 0x8C, 0x2C, 0x4C, 0xC4,
- 0xEA, 0x6A, 0x8A, 0x2A, 0x4A, 0xED, 0x6D, 0x8D, 0x2D, 0x4D, 0xC5,
- 0xF0, 0x70, 0x90, 0x30, 0x50, 0xF3, 0x73, 0x93, 0x33, 0x53, 0xC6,
- 0xF1, 0x71, 0x91, 0x31, 0x51, 0xF4, 0x74, 0x94, 0x34, 0x54, 0xC7,
- 0xF2, 0x72, 0x92, 0x32, 0x52, 0xF5, 0x75, 0x95, 0x35, 0x55, 0xC8
-};
-
-const unsigned short
- CxadhybridPlayer::hyb_notes[98] = {
- 0x0000, 0x0000,
- 0x016B, 0x0181, 0x0198, 0x01B0, 0x01CA, 0x01E5, 0x0202, 0x0220, 0x0241,
- 0x0263, 0x0287, 0x02AE,
- 0x056B, 0x0581, 0x0598, 0x05B0, 0x05CA, 0x05E5, 0x0602, 0x0620, 0x0641,
- 0x0663, 0x0687, 0x06AE,
- 0x096B, 0x0981, 0x0998, 0x09B0, 0x09CA, 0x09E5, 0x0A02, 0x0A20, 0x0A41,
- 0x0A63, 0x0A87, 0x0AAE,
- 0x0D6B, 0x0D81, 0x0D98, 0x0DB0, 0x0DCA, 0x0DE5, 0x0E02, 0x0E20, 0x0E41,
- 0x0E63, 0x0E87, 0x0EAE,
- 0x116B, 0x1181, 0x1198, 0x11B0, 0x11CA, 0x11E5, 0x1202, 0x1220, 0x1241,
- 0x1263, 0x1287, 0x12AE,
- 0x156B, 0x1581, 0x1598, 0x15B0, 0x15CA, 0x15E5, 0x1602, 0x1620, 0x1641,
- 0x1663, 0x1687, 0x16AE,
- 0x196B, 0x1981, 0x1998, 0x19B0, 0x19CA, 0x19E5, 0x1A02, 0x1A20, 0x1A41,
- 0x1A63, 0x1A87, 0x1AAE,
- 0x1D6B, 0x1D81, 0x1D98, 0x1DB0, 0x1DCA, 0x1DE5, 0x1E02, 0x1E20, 0x1E41,
- 0x1E63, 0x1E87, 0x1EAE
-};
-
-const unsigned char
- CxadhybridPlayer::hyb_default_instrument[11] = {
- 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00
-};
-
-CPlayer *
-CxadhybridPlayer::factory (Copl * newopl)
-{
- return new CxadhybridPlayer (newopl);
-}
-
-bool
-CxadhybridPlayer::xadplayer_load ()
-{
- if (xad.fmt != HYBRID)
- return false;
-
- // load instruments
- hyb.inst = (hyb_instrument *) & tune[0];
-
- // load order
- hyb.order = &tune[0x1D4];
-
- return true;
-}
-
-void
-CxadhybridPlayer::xadplayer_rewind (int subsong)
-{
- int i;
-
- hyb.order_pos = 0;
- hyb.pattern_pos = 0;
-
- hyb.speed = 6;
- hyb.speed_counter = 1;
-
- plr.speed = 1;
-
- // init channel data
- for (i = 0; i < 9; i++)
- {
- hyb.channel[i].freq = 0x2000;
- hyb.channel[i].freq_slide = 0x0000;
- }
-
- // basic OPL init
- opl_write (0x01, 0x20);
- opl_write (0xBD, 0x40);
- opl_write (0x08, 0x00);
-
- // init OPL channels
- for (i = 0; i < 9; i++)
- {
- for (int j = 0; j < 11; j++)
- opl_write (hyb_adlib_registers[i * 11 + j],
- 0x00 /* hyb_default_instrument[j] */ );
-
- opl_write (0xA0 + i, 0x00);
- opl_write (0xB0 + i, 0x20);
- }
-}
-
-void
-CxadhybridPlayer::xadplayer_update ()
-{
- int i, j;
- unsigned char patpos, ordpos;
-
- if (--hyb.speed_counter)
- goto update_slides;
-
- hyb.speed_counter = hyb.speed;
-
- patpos = hyb.pattern_pos;
- ordpos = hyb.order_pos;
-
- // process channels
- for (i = 0; i < 9; i++)
- {
- unsigned char *pos =
- &tune[0xADE + (hyb.order[hyb.order_pos * 9 + i] * 64 * 2) +
- (patpos * 2)];
- // read event
- unsigned short event = (pos[1] << 8) + pos[0];
-
-#ifdef DEBUG
- AdPlug_LogWrite ("track %02X, channel %02X, event %04X:\n",
- hyb.order[hyb.order_pos * 9 + i], i, event);
-#endif
-
- // calculate variables
- unsigned char note = event >> 9;
- unsigned char ins = ((event & 0x01F0) >> 4);
- unsigned char slide = event & 0x000F;
-
- // play event
- switch (note)
- {
- case 0x7D: // 0x7D: Set Speed
- hyb.speed = event & 0xFF;
- break;
- case 0x7E: // 0x7E: Jump Position
- hyb.order_pos = event & 0xFF;
- hyb.pattern_pos = 0x3F;
-
- // jumpback ?
- if (hyb.order_pos <= ordpos)
- plr.looping = 1;
-
- break;
- case 0x7F: // 0x7F: Pattern Break
- hyb.pattern_pos = 0x3F;
- break;
- default:
-
- // is instrument ?
- if (ins)
- for (j = 0; j < 11; j++)
- opl_write (hyb_adlib_registers[i * 11 + j], *((unsigned char *) &hyb.inst[ins - 1] + 7 + j)); // +7 = skip name...
-
- // is note ?
- if (note)
- {
- hyb.channel[i].freq = hyb_notes[note];
- hyb.channel[i].freq_slide = 0;
- }
-
- // is slide ?
- if (slide)
- {
- hyb.channel[i].freq_slide = (((slide >> 3) * -1) * (slide & 7)) << 1;
-
- if (slide & 0x80)
- slide = -(slide & 7);
- }
-
- // set frequency
- if (!(hyb.channel[i].freq & 0x2000))
- {
- opl_write (0xA0 + i, hyb.channel[i].freq & 0xFF);
- opl_write (0xB0 + i, hyb.channel[i].freq >> 8);
-
- hyb.channel[i].freq |= 0x2000;
-
- opl_write (0xA0 + i, hyb.channel[i].freq & 0xFF);
- opl_write (0xB0 + i, hyb.channel[i].freq >> 8);
- }
-
- break;
- }
- }
-
- hyb.pattern_pos++;
-
- // end of pattern ?
- if (hyb.pattern_pos >= 0x40)
- {
- hyb.pattern_pos = 0;
-
- hyb.order_pos++;
- }
-
-update_slides:
-#ifdef DEBUG
- AdPlug_LogWrite ("slides:\n");
-#endif
- // update fine frequency slides
- for (i = 0; i < 9; i++)
- if (hyb.channel[i].freq_slide)
- {
- hyb.channel[i].freq =
- (((hyb.channel[i].freq & 0x1FFF) +
- hyb.channel[i].freq_slide) & 0x1FFF) | 0x2000;
-
- opl_write (0xA0 + i, hyb.channel[i].freq & 0xFF);
- opl_write (0xB0 + i, hyb.channel[i].freq >> 8);
- }
-}
-
-float
-CxadhybridPlayer::xadplayer_getrefresh ()
-{
- return 50.0f;
-}
-
-std::string CxadhybridPlayer::xadplayer_gettype ()
-{
- return (std::string ("xad: hybrid player"));
-}
-
-std::string CxadhybridPlayer::xadplayer_getinstrument (unsigned int i)
-{
- return (std::string (hyb.inst[i].name, 7));
-}
-
-unsigned int
-CxadhybridPlayer::xadplayer_getinstruments ()
-{
- return 26;
-}
diff --git a/src/adplug/core/hyp.cc b/src/adplug/core/hyp.cc
new file mode 100644
index 000000000000..5358a65beb98
--- /dev/null
+++ b/src/adplug/core/hyp.cc
@@ -0,0 +1,129 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * [xad] HYP player, by Riven the Mage <riven at ok.ru>
+ */
+
+/*
+ - discovery -
+
+ file(s) : HT-EF2.COM, HT-EF3.COM
+ type : Eiserne Front BBStro
+ tune : by Shadowdancer [Hypnosis]
+ player : by (?)Hetero [LKCC/SAC]
+*/
+
+#include "hyp.h"
+#include "debug.h"
+
+const unsigned char
+ CxadhypPlayer::hyp_adlib_registers[99] = {
+ 0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xA0, 0xB0, 0xC0,
+ 0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xA1, 0xB1, 0xC1,
+ 0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xA2, 0xB2, 0xC2,
+ 0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xA3, 0xB3, 0xC3,
+ 0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xA4, 0xB4, 0xC4,
+ 0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xA5, 0xB5, 0xC5,
+ 0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xA6, 0xB6, 0xC6,
+ 0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xA7, 0xB7, 0xC7,
+ 0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xA8, 0xB8, 0xC8
+};
+
+const unsigned short
+ CxadhypPlayer::hyp_notes[73] = {
+ 0x0000, // by riven
+ 0x0956, 0x096B, 0x0980, 0x0998, 0x09B1, 0x09C9, 0x09E5, 0x0A03, 0x0A21,
+ 0x0A41, 0x0A63, 0x0A86, 0x0D56, 0x0D6B, 0x0D80, 0x0D98, 0x0DB1, 0x0DC9,
+ 0x0DE5, 0x0E03, 0x0E21, 0x0E41, 0x0E63, 0x0E86, 0x1156, 0x116B, 0x1180,
+ 0x1198, 0x11B1, 0x11C9, 0x11E5, 0x1203, 0x1221, 0x1241, 0x1263, 0x1286,
+ 0x1556, 0x156B, 0x1580, 0x1598, 0x15B1, 0x15C9, 0x15E5, 0x1603, 0x1621,
+ 0x1641, 0x1663, 0x1686, 0x1956, 0x196B, 0x1980, 0x1998, 0x19B1, 0x19C9,
+ 0x19E5, 0x1A03, 0x1A21, 0x1A41, 0x1A63, 0x1A86, 0x1D56, 0x1D6B, 0x1D80,
+ 0x1D98, 0x1DB1, 0x1DC9, 0x1DE5, 0x1E03, 0x1E21, 0x1E41, 0x1E63, 0x1E86
+};
+
+CPlayer *
+CxadhypPlayer::factory (Copl * newopl)
+{
+ return new CxadhypPlayer (newopl);
+}
+
+void
+CxadhypPlayer::xadplayer_rewind (int subsong)
+{
+ int i;
+
+ plr.speed = tune[5];
+
+ opl_write (0xBD, 0xC0);
+
+ for (i = 0; i < 9; i++)
+ adlib[0xB0 + i] = 0;
+
+ // define instruments
+ for (i = 0; i < 99; i++)
+ opl_write (hyp_adlib_registers[i], tune[6 + i]);
+
+ hyp.pointer = 0x69;
+}
+
+void
+CxadhypPlayer::xadplayer_update ()
+{
+ for (int i = 0; i < 9; i++)
+ {
+ unsigned char event = tune[hyp.pointer++];
+
+ if (event)
+ {
+ unsigned short freq = hyp_notes[event & 0x3F];
+
+ unsigned char lofreq = (freq & 0xFF);
+ unsigned char hifreq = (freq >> 8);
+
+ opl_write (0xB0 + i, adlib[0xB0 + i]);
+
+ if (!(event & 0x40))
+ {
+ opl_write (0xA0 + i, lofreq);
+ opl_write (0xB0 + i, hifreq | 0x20);
+ }
+
+ adlib[0xB0 + i] &= 0xDF;
+ }
+ }
+
+ hyp.pointer += 3;
+
+ if (hyp.pointer >= tune_size)
+ {
+ hyp.pointer = 0x69;
+ plr.looping = 1;
+ }
+}
+
+float
+CxadhypPlayer::xadplayer_getrefresh ()
+{
+ return 60.0f;
+}
+
+std::string CxadhypPlayer::xadplayer_gettype ()
+{
+ return std::string ("xad: hypnosis player");
+}
diff --git a/src/adplug/core/hyp.cxx b/src/adplug/core/hyp.cxx
deleted file mode 100644
index 5358a65beb98..000000000000
--- a/src/adplug/core/hyp.cxx
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * [xad] HYP player, by Riven the Mage <riven at ok.ru>
- */
-
-/*
- - discovery -
-
- file(s) : HT-EF2.COM, HT-EF3.COM
- type : Eiserne Front BBStro
- tune : by Shadowdancer [Hypnosis]
- player : by (?)Hetero [LKCC/SAC]
-*/
-
-#include "hyp.h"
-#include "debug.h"
-
-const unsigned char
- CxadhypPlayer::hyp_adlib_registers[99] = {
- 0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xA0, 0xB0, 0xC0,
- 0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xA1, 0xB1, 0xC1,
- 0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xA2, 0xB2, 0xC2,
- 0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xA3, 0xB3, 0xC3,
- 0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xA4, 0xB4, 0xC4,
- 0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xA5, 0xB5, 0xC5,
- 0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xA6, 0xB6, 0xC6,
- 0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xA7, 0xB7, 0xC7,
- 0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xA8, 0xB8, 0xC8
-};
-
-const unsigned short
- CxadhypPlayer::hyp_notes[73] = {
- 0x0000, // by riven
- 0x0956, 0x096B, 0x0980, 0x0998, 0x09B1, 0x09C9, 0x09E5, 0x0A03, 0x0A21,
- 0x0A41, 0x0A63, 0x0A86, 0x0D56, 0x0D6B, 0x0D80, 0x0D98, 0x0DB1, 0x0DC9,
- 0x0DE5, 0x0E03, 0x0E21, 0x0E41, 0x0E63, 0x0E86, 0x1156, 0x116B, 0x1180,
- 0x1198, 0x11B1, 0x11C9, 0x11E5, 0x1203, 0x1221, 0x1241, 0x1263, 0x1286,
- 0x1556, 0x156B, 0x1580, 0x1598, 0x15B1, 0x15C9, 0x15E5, 0x1603, 0x1621,
- 0x1641, 0x1663, 0x1686, 0x1956, 0x196B, 0x1980, 0x1998, 0x19B1, 0x19C9,
- 0x19E5, 0x1A03, 0x1A21, 0x1A41, 0x1A63, 0x1A86, 0x1D56, 0x1D6B, 0x1D80,
- 0x1D98, 0x1DB1, 0x1DC9, 0x1DE5, 0x1E03, 0x1E21, 0x1E41, 0x1E63, 0x1E86
-};
-
-CPlayer *
-CxadhypPlayer::factory (Copl * newopl)
-{
- return new CxadhypPlayer (newopl);
-}
-
-void
-CxadhypPlayer::xadplayer_rewind (int subsong)
-{
- int i;
-
- plr.speed = tune[5];
-
- opl_write (0xBD, 0xC0);
-
- for (i = 0; i < 9; i++)
- adlib[0xB0 + i] = 0;
-
- // define instruments
- for (i = 0; i < 99; i++)
- opl_write (hyp_adlib_registers[i], tune[6 + i]);
-
- hyp.pointer = 0x69;
-}
-
-void
-CxadhypPlayer::xadplayer_update ()
-{
- for (int i = 0; i < 9; i++)
- {
- unsigned char event = tune[hyp.pointer++];
-
- if (event)
- {
- unsigned short freq = hyp_notes[event & 0x3F];
-
- unsigned char lofreq = (freq & 0xFF);
- unsigned char hifreq = (freq >> 8);
-
- opl_write (0xB0 + i, adlib[0xB0 + i]);
-
- if (!(event & 0x40))
- {
- opl_write (0xA0 + i, lofreq);
- opl_write (0xB0 + i, hifreq | 0x20);
- }
-
- adlib[0xB0 + i] &= 0xDF;
- }
- }
-
- hyp.pointer += 3;
-
- if (hyp.pointer >= tune_size)
- {
- hyp.pointer = 0x69;
- plr.looping = 1;
- }
-}
-
-float
-CxadhypPlayer::xadplayer_getrefresh ()
-{
- return 60.0f;
-}
-
-std::string CxadhypPlayer::xadplayer_gettype ()
-{
- return std::string ("xad: hypnosis player");
-}
diff --git a/src/adplug/core/imf.cc b/src/adplug/core/imf.cc
new file mode 100644
index 000000000000..109d6cd6d0c3
--- /dev/null
+++ b/src/adplug/core/imf.cc
@@ -0,0 +1,229 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 Simon Peter <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * imf.cpp - IMF Player by Simon Peter <dn.tlp at gmx.net>
+ *
+ * FILE FORMAT:
+ * There seem to be 2 different flavors of IMF formats out there. One version
+ * contains just the raw IMF music data. In this case, the first word of the
+ * file is always 0 (because the music data starts this way). This is already
+ * the music data! So read in the entire file and play it.
+ *
+ * If this word is greater than 0, it specifies the size of the following
+ * song data in bytes. In this case, the file has a footer that contains
+ * arbitrary infos about it. Mostly, this is plain ASCII text with some words
+ * of the author. Read and play the specified amount of song data and display
+ * the remaining data as ASCII text.
+ *
+ * NOTES:
+ * This player handles the two above mentioned formats, as well as a third
+ * type, invented by Martin Fernandez <mfernan at cnba.uba.ar>, that's got a
+ * proper header to add title/game name information. After the header starts
+ * the normal IMF file in one of the two above mentioned formats.
+ *
+ * This player also handles a special footer format by Adam Nielsen,
+ * which has defined fields of information about the song, the author
+ * and more.
+ */
+
+#include <string.h>
+
+#include "imf.h"
+#include "database.h"
+
+/*** public methods *************************************/
+
+CPlayer *
+CimfPlayer::factory (Copl * newopl)
+{
+ return new CimfPlayer (newopl);
+}
+
+bool
+CimfPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ unsigned long fsize, flsize, mfsize = 0;
+ unsigned int i;
+
+ // file validation section
+ {
+ char header[5];
+ int version;
+
+ f->readString (header, 5);
+ version = f->readInt (1);
+
+ if (strncmp (header, "ADLIB", 5) || version != 1)
+ {
+ if (!fp.extension (fd.filename (), ".imf") && !fp.extension (fd.filename (), ".wlf"))
+ {
+ // It's no IMF file at all
+ fp.close (f);
+ return false;
+ }
+ else
+ f->seek (0); // It's a normal IMF file
+ }
+ else
+ {
+ // It's a IMF file with header
+ track_name = f->readString ('\0');
+ game_name = f->readString ('\0');
+ f->ignore (1);
+ mfsize = f->pos () + 2;
+ }
+ }
+
+ // load section
+ if (mfsize)
+ fsize = f->readInt (4);
+ else
+ fsize = f->readInt (2);
+ flsize = fp.filesize (f);
+ if (!fsize)
+ { // footerless file (raw music data)
+ if (mfsize)
+ f->seek (-4, binio::Add);
+ else
+ f->seek (-2, binio::Add);
+ size = (flsize - mfsize) / 4;
+ }
+ else // file has got a footer
+ size = fsize / 4;
+
+ data = new Sdata[size];
+ for (i = 0; i < size; i++)
+ {
+ data[i].reg = f->readInt (1);
+ data[i].val = f->readInt (1);
+ data[i].time = f->readInt (2);
+ }
+
+ // read footer, if any
+ if (fsize && (fsize < flsize - 2 - mfsize))
+ {
+ if (f->readInt (1) == 0x1a)
+ {
+ // Adam Nielsen's footer format
+ track_name = f->readString ();
+ author_name = f->readString ();
+ remarks = f->readString ();
+ }
+ else
+ {
+ // Generic footer
+ unsigned long footerlen = flsize - fsize - 2 - mfsize;
+
+ footer = new char[footerlen + 1];
+ f->readString (footer, footerlen);
+ footer[footerlen] = '\0'; // Make ASCIIZ string
+ }
+ }
+
+ rate = getrate (fd.filename (), fp, f);
+ fp.close (f);
+ rewind (0);
+ return true;
+}
+
+bool
+CimfPlayer::update ()
+{
+ do
+ {
+ opl->write (data[pos].reg, data[pos].val);
+ del = data[pos].time;
+ pos++;
+ } while (!del && pos < size);
+
+ if (pos >= size)
+ {
+ pos = 0;
+ songend = true;
+ }
+ else
+ timer = rate / (float) del;
+
+ return !songend;
+}
+
+void
+CimfPlayer::rewind (int subsong)
+{
+ pos = 0;
+ del = 0;
+ timer = rate;
+ songend = false;
+ opl->init ();
+ opl->write (1, 32); // go to OPL2 mode
+}
+
+std::string CimfPlayer::gettitle ()
+{
+ std::string title;
+
+ title = track_name;
+
+ if (!track_name.empty () && !game_name.empty ())
+ title += " - ";
+
+ title += game_name;
+
+ return title;
+}
+
+std::string CimfPlayer::getdesc ()
+{
+ std::string desc;
+
+ if (footer)
+ desc = std::string (footer);
+
+ if (!remarks.empty () && footer)
+ desc += "\n\n";
+
+ desc += remarks;
+
+ return desc;
+}
+
+/*** private methods *************************************/
+
+float
+CimfPlayer::getrate (const std::string & filename, const CFileProvider & fp,
+ binistream * f)
+{
+ if (db)
+ { // Database available
+ f->seek (0, binio::Set);
+ CClockRecord *record =
+ (CClockRecord *) db->search (CAdPlugDatabase::CKey (*f));
+ if (record && record->type == CAdPlugDatabase::CRecord::ClockSpeed)
+ return record->clock;
+ }
+
+ // Otherwise the database is either unavailable, or there's no entry for this file
+ if (fp.extension (filename, ".imf"))
+ return 560.0f;
+ if (fp.extension (filename, ".wlf"))
+ return 700.0f;
+ return 700.0f; // default speed for unknown files that aren't .IMF or .WLF
+}
diff --git a/src/adplug/core/imf.cxx b/src/adplug/core/imf.cxx
deleted file mode 100644
index 863512e43b19..000000000000
--- a/src/adplug/core/imf.cxx
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 Simon Peter <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * imf.cpp - IMF Player by Simon Peter <dn.tlp at gmx.net>
- *
- * FILE FORMAT:
- * There seem to be 2 different flavors of IMF formats out there. One version
- * contains just the raw IMF music data. In this case, the first word of the
- * file is always 0 (because the music data starts this way). This is already
- * the music data! So read in the entire file and play it.
- *
- * If this word is greater than 0, it specifies the size of the following
- * song data in bytes. In this case, the file has a footer that contains
- * arbitrary infos about it. Mostly, this is plain ASCII text with some words
- * of the author. Read and play the specified amount of song data and display
- * the remaining data as ASCII text.
- *
- * NOTES:
- * This player handles the two above mentioned formats, as well as a third
- * type, invented by Martin Fernandez <mfernan at cnba.uba.ar>, that's got a
- * proper header to add title/game name information. After the header starts
- * the normal IMF file in one of the two above mentioned formats.
- *
- * This player also handles a special footer format by Adam Nielsen,
- * which has defined fields of information about the song, the author
- * and more.
- */
-
-#include <string.h>
-
-#include "imf.h"
-#include "database.h"
-
-/*** public methods *************************************/
-
-CPlayer *
-CimfPlayer::factory (Copl * newopl)
-{
- return new CimfPlayer (newopl);
-}
-
-bool
-CimfPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- unsigned long fsize, flsize, mfsize = 0;
- unsigned int i;
-
- // file validation section
- {
- char header[5];
- int version;
-
- f->readString (header, 5);
- version = f->readInt (1);
-
- if (strncmp (header, "ADLIB", 5) || version != 1)
- {
- if (!fp.extension (vfs_get_filename (fd), ".imf") && !fp.extension (vfs_get_filename (fd), ".wlf"))
- {
- // It's no IMF file at all
- fp.close (f);
- return false;
- }
- else
- f->seek (0); // It's a normal IMF file
- }
- else
- {
- // It's a IMF file with header
- track_name = f->readString ('\0');
- game_name = f->readString ('\0');
- f->ignore (1);
- mfsize = f->pos () + 2;
- }
- }
-
- // load section
- if (mfsize)
- fsize = f->readInt (4);
- else
- fsize = f->readInt (2);
- flsize = fp.filesize (f);
- if (!fsize)
- { // footerless file (raw music data)
- if (mfsize)
- f->seek (-4, binio::Add);
- else
- f->seek (-2, binio::Add);
- size = (flsize - mfsize) / 4;
- }
- else // file has got a footer
- size = fsize / 4;
-
- data = new Sdata[size];
- for (i = 0; i < size; i++)
- {
- data[i].reg = f->readInt (1);
- data[i].val = f->readInt (1);
- data[i].time = f->readInt (2);
- }
-
- // read footer, if any
- if (fsize && (fsize < flsize - 2 - mfsize))
- {
- if (f->readInt (1) == 0x1a)
- {
- // Adam Nielsen's footer format
- track_name = f->readString ();
- author_name = f->readString ();
- remarks = f->readString ();
- }
- else
- {
- // Generic footer
- unsigned long footerlen = flsize - fsize - 2 - mfsize;
-
- footer = new char[footerlen + 1];
- f->readString (footer, footerlen);
- footer[footerlen] = '\0'; // Make ASCIIZ string
- }
- }
-
- rate = getrate (vfs_get_filename (fd), fp, f);
- fp.close (f);
- rewind (0);
- return true;
-}
-
-bool
-CimfPlayer::update ()
-{
- do
- {
- opl->write (data[pos].reg, data[pos].val);
- del = data[pos].time;
- pos++;
- } while (!del && pos < size);
-
- if (pos >= size)
- {
- pos = 0;
- songend = true;
- }
- else
- timer = rate / (float) del;
-
- return !songend;
-}
-
-void
-CimfPlayer::rewind (int subsong)
-{
- pos = 0;
- del = 0;
- timer = rate;
- songend = false;
- opl->init ();
- opl->write (1, 32); // go to OPL2 mode
-}
-
-std::string CimfPlayer::gettitle ()
-{
- std::string title;
-
- title = track_name;
-
- if (!track_name.empty () && !game_name.empty ())
- title += " - ";
-
- title += game_name;
-
- return title;
-}
-
-std::string CimfPlayer::getdesc ()
-{
- std::string desc;
-
- if (footer)
- desc = std::string (footer);
-
- if (!remarks.empty () && footer)
- desc += "\n\n";
-
- desc += remarks;
-
- return desc;
-}
-
-/*** private methods *************************************/
-
-float
-CimfPlayer::getrate (const std::string & filename, const CFileProvider & fp,
- binistream * f)
-{
- if (db)
- { // Database available
- f->seek (0, binio::Set);
- CClockRecord *record =
- (CClockRecord *) db->search (CAdPlugDatabase::CKey (*f));
- if (record && record->type == CAdPlugDatabase::CRecord::ClockSpeed)
- return record->clock;
- }
-
- // Otherwise the database is either unavailable, or there's no entry for this file
- if (fp.extension (filename, ".imf"))
- return 560.0f;
- if (fp.extension (filename, ".wlf"))
- return 700.0f;
- return 700.0f; // default speed for unknown files that aren't .IMF or .WLF
-}
diff --git a/src/adplug/core/imf.h b/src/adplug/core/imf.h
index 17063dc7acec..9eb3a6edf3ab 100644
--- a/src/adplug/core/imf.h
+++ b/src/adplug/core/imf.h
@@ -35,7 +35,7 @@ public:
~CimfPlayer()
{ if(data) delete [] data; if(footer) delete [] footer; };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh()
diff --git a/src/adplug/core/jbm.cc b/src/adplug/core/jbm.cc
new file mode 100644
index 000000000000..c9658049f839
--- /dev/null
+++ b/src/adplug/core/jbm.cc
@@ -0,0 +1,294 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Johannes Bjerregaard's JBM Adlib Music Format player for AdPlug
+ * Written by Dennis Lindroos <lindroos at nls.fi>, February-March 2007
+ * - Designed and coded from scratch (only frequency-table taken from MUSIC.BIN)
+ * - The percussion mode is buggy (?) but i'm not good enough to find them
+ * and honestly i think the melodic-mode tunes are much better ;)
+ *
+ * This version doesn't use the binstr.h functions (coded with custom func.)
+ * This is my first attempt on writing a musicplayer for AdPlug, and i'm not
+ * coding C++ very often..
+ *
+ * Released under the terms of the GNU General Public License.
+ */
+
+#include "jbm.h"
+
+static const unsigned short notetable[96] = {
+ 0x0158, 0x016d, 0x0183, 0x019a, 0x01b2, 0x01cc, 0x01e7, 0x0204,
+ 0x0223, 0x0244, 0x0266, 0x028b, 0x0558, 0x056d, 0x0583, 0x059a,
+ 0x05b2, 0x05cc, 0x05e7, 0x0604, 0x0623, 0x0644, 0x0666, 0x068b,
+ 0x0958, 0x096d, 0x0983, 0x099a, 0x09b2, 0x09cc, 0x09e7, 0x0a04,
+ 0x0a23, 0x0a44, 0x0a66, 0x0a8b, 0x0d58, 0x0d6d, 0x0d83, 0x0d9a,
+ 0x0db2, 0x0dcc, 0x0de7, 0x0e04, 0x0e23, 0x0e44, 0x0e66, 0x0e8b,
+ 0x1158, 0x116d, 0x1183, 0x119a, 0x11b2, 0x11cc, 0x11e7, 0x1204,
+ 0x1223, 0x1244, 0x1266, 0x128b, 0x1558, 0x156d, 0x1583, 0x159a,
+ 0x15b2, 0x15cc, 0x15e7, 0x1604, 0x1623, 0x1644, 0x1666, 0x168b,
+ 0x1958, 0x196d, 0x1983, 0x199a, 0x19b2, 0x19cc, 0x19e7, 0x1a04,
+ 0x1a23, 0x1a44, 0x1a66, 0x1a8b, 0x1d58, 0x1d6d, 0x1d83, 0x1d9a,
+ 0x1db2, 0x1dcc, 0x1de7, 0x1e04, 0x1e23, 0x1e44, 0x1e66, 0x1e8b
+};
+
+static const unsigned char percmx_tab[4] = { 0x14, 0x12, 0x15, 0x11 };
+static const unsigned char perchn_tab[5] = { 6, 7, 8, 8, 7 };
+static unsigned char percmaskoff[5] = { 0xef, 0xf7, 0xfb, 0xfd, 0xfe };
+static unsigned char percmaskon[5] = { 0x10, 0x08, 0x04, 0x02, 0x01 };
+
+static inline unsigned short GET_WORD(unsigned char *b, int x)
+{
+ return ((unsigned short)(b[x+1] << 8) | b[x]);
+}
+
+/*** public methods *************************************/
+
+CPlayer *CjbmPlayer::factory(Copl *newopl)
+{
+ return new CjbmPlayer(newopl);
+}
+
+bool CjbmPlayer::load(VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ std::string filename (fd.filename ());
+ int filelen = fp.filesize(f);
+ int i;
+
+ if (!filelen || !fp.extension(filename, ".jbm")) goto loaderr;
+
+ // Allocate memory buffer m[] and read entire file into it
+
+ m = new unsigned char[filelen];
+ if (f->readString((char *)m, filelen) != (unsigned int)filelen) goto loaderr;
+
+ fp.close(f);
+
+ // The known .jbm files always seem to start with the number 0x0002
+
+ if (GET_WORD(m, 0) != 0x0002)
+ return false;
+
+ // Song tempo
+
+ i = GET_WORD(m, 2);
+ timer = 1193810.0 / (i ? i : 0xffff);
+
+ seqtable = GET_WORD(m, 4);
+ instable = GET_WORD(m, 6);
+
+ // The flags word has atleast 1 bit, the Adlib's rhythm mode, but
+ // currently we don't support that :(
+
+ flags = GET_WORD(m, 8);
+
+ // Instrument datas are directly addressed with m[]
+
+ inscount = (filelen - instable) >> 4;
+
+ // Voice' and sequence pointers
+
+ seqcount = 0xffff;
+ for (i = 0; i < 11; i++) {
+ voice[i].trkpos = voice[i].trkstart = GET_WORD(m, 10 + (i<<1));
+ if (voice[i].trkpos && voice[i].trkpos < seqcount)
+ seqcount = voice[i].trkpos;
+ }
+ seqcount = (seqcount - seqtable) >> 1;
+ sequences = new unsigned short[seqcount];
+ for (i = 0; i < seqcount; i++)
+ sequences[i] = GET_WORD(m, seqtable + (i<<1));
+
+ rewind(0);
+ return true;
+ loaderr:
+ fp.close(f);
+ return false;
+}
+
+bool CjbmPlayer::update()
+{
+ short c, spos, frq;
+
+ for (c = 0; c < 11; c++) {
+ if (!voice[c].trkpos) // Unused channel
+ continue;
+
+ if (--voice[c].delay)
+ continue;
+
+ // Turn current note/percussion off
+
+ if (voice[c].note&0x7f)
+ opl_noteonoff(c, &voice[c], 0);
+
+ // Process events until we have a note
+
+ spos = voice[c].seqpos;
+ while(!voice[c].delay) {
+ switch(m[spos]) {
+ case 0xFD: // Set Instrument
+ voice[c].instr = m[spos+1];
+ set_opl_instrument(c, &voice[c]);
+ spos+=2;
+ break;
+ case 0xFF: // End of Sequence
+ voice[c].seqno = m[++voice[c].trkpos];
+ if (voice[c].seqno == 0xff) {
+ voice[c].trkpos = voice[c].trkstart;
+ voice[c].seqno = m[voice[c].trkpos];
+ //voicemask &= 0x7ff-(1<<c);
+ voicemask &= ~(1<<c);
+ }
+ spos = voice[c].seqpos = sequences[voice[c].seqno];
+ break;
+ default: // Note Event
+ if ((m[spos] & 127) > 95)
+ return 0;
+
+ voice[c].note = m[spos];
+ voice[c].vol = m[spos+1];
+ voice[c].delay =
+ (m[spos+2] + (m[spos+3]<<8)) + 1;
+
+ frq = notetable[voice[c].note&127];
+ voice[c].frq[0] = (unsigned char)frq;
+ voice[c].frq[1] = frq >> 8;
+ spos+=4;
+ }
+ }
+ voice[c].seqpos = spos;
+
+ // Write new volume to the carrier operator, or percussion
+
+ if (flags&1 && c > 6)
+ opl->write(0x40 + percmx_tab[c-7], voice[c].vol ^ 0x3f);
+ else
+ opl->write(0x43 + op_table[c], voice[c].vol ^ 0x3f);
+
+ // Write new frequencies and Gate bit
+
+ opl_noteonoff(c, &voice[c], !(voice[c].note & 0x80));
+ }
+ return (voicemask);
+}
+
+void CjbmPlayer::rewind(int subsong)
+{
+ int c;
+
+ voicemask = 0;
+
+ for (c = 0; c < 11; c++) {
+ voice[c].trkpos = voice[c].trkstart;
+
+ if (!voice[c].trkpos) continue;
+
+ voicemask |= (1<<c);
+
+ voice[c].seqno = m[voice[c].trkpos];
+ voice[c].seqpos = sequences[voice[c].seqno];
+
+ voice[c].note = 0;
+ voice[c].delay = 1;
+ }
+
+ opl->init();
+ opl->write(0x01, 32);
+
+ // Set rhythm mode if flags bit #0 is set
+ // AM and Vibrato are full depths (taken from DosBox RAW output)
+ bdreg = 0xC0 | (flags&1)<<5;
+
+ opl->write(0xbd, bdreg);
+
+#if 0
+ if (flags&1) {
+ voice[7].frq[0] = 0x58; voice[7].frq[1] = 0x09; // XXX
+ voice[8].frq[0] = 0x04; voice[8].frq[1] = 0x0a; // XXX
+ opl_noteonoff(7, &voice[7], 0);
+ opl_noteonoff(8, &voice[8], 0);
+ }
+#endif
+
+ return;
+}
+
+/*** private methods ************************************/
+
+void CjbmPlayer::opl_noteonoff(int channel, JBMVoice *v, bool state)
+{
+ if (flags&1 && channel > 5) {
+ // Percussion
+ opl->write(0xa0 + perchn_tab[channel-6], voice[channel].frq[0]);
+ opl->write(0xb0 + perchn_tab[channel-6], voice[channel].frq[1]);
+ opl->write(0xbd,
+ state ? bdreg | percmaskon[channel-6] :
+ bdreg & percmaskoff[channel-6]);
+ } else {
+ // Melodic mode or Rhythm mode melodic channels
+ opl->write(0xa0 + channel, voice[channel].frq[0]);
+ opl->write(0xb0 + channel,
+ state ? voice[channel].frq[1] | 0x20 :
+ voice[channel].frq[1] & 0x1f);
+ }
+ return;
+}
+
+
+void CjbmPlayer::set_opl_instrument(int channel, JBMVoice *v)
+{
+ short i = instable + (v->instr << 4);
+
+ // Sanity check on instr number - or we'll be reading outside m[] !
+
+ if (v->instr >= inscount)
+ return;
+
+ // For rhythm mode, multiplexed drums. I don't care about waveforms!
+ if ((flags&1) & (channel > 6)) {
+ opl->write(0x20 + percmx_tab[channel-7], m[i+0]);
+ opl->write(0x40 + percmx_tab[channel-7], m[i+1] ^ 0x3f);
+ opl->write(0x60 + percmx_tab[channel-7], m[i+2]);
+ opl->write(0x80 + percmx_tab[channel-7], m[i+3]);
+
+ opl->write(0xc0 + perchn_tab[channel-6], m[i+8]&15);
+ return;
+ }
+
+ // AM/VIB/EG/KSR/FRQMUL, KSL/OUTPUT, ADSR for 1st operator
+ opl->write(0x20 + op_table[channel], m[i+0]);
+ opl->write(0x40 + op_table[channel], m[i+1] ^ 0x3f);
+ opl->write(0x60 + op_table[channel], m[i+2]);
+ opl->write(0x80 + op_table[channel], m[i+3]);
+
+ // AM/VIB/EG/KSR/FRQMUL, KSL/OUTPUT, ADSR for 2nd operator
+ opl->write(0x23 + op_table[channel], m[i+4]);
+ opl->write(0x43 + op_table[channel], m[i+5] ^ 0x3f);
+ opl->write(0x63 + op_table[channel], m[i+6]);
+ opl->write(0x83 + op_table[channel], m[i+7]);
+
+ // WAVEFORM for operators
+ opl->write(0xe0 + op_table[channel], (m[i+8]>>4)&3);
+ opl->write(0xe3 + op_table[channel], (m[i+8]>>6)&3);
+
+ // FEEDBACK/FM mode
+ opl->write(0xc0 + channel, m[i+8]&15);
+
+ return;
+}
diff --git a/src/adplug/core/jbm.cxx b/src/adplug/core/jbm.cxx
deleted file mode 100644
index dc920d906545..000000000000
--- a/src/adplug/core/jbm.cxx
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Johannes Bjerregaard's JBM Adlib Music Format player for AdPlug
- * Written by Dennis Lindroos <lindroos at nls.fi>, February-March 2007
- * - Designed and coded from scratch (only frequency-table taken from MUSIC.BIN)
- * - The percussion mode is buggy (?) but i'm not good enough to find them
- * and honestly i think the melodic-mode tunes are much better ;)
- *
- * This version doesn't use the binstr.h functions (coded with custom func.)
- * This is my first attempt on writing a musicplayer for AdPlug, and i'm not
- * coding C++ very often..
- *
- * Released under the terms of the GNU General Public License.
- */
-
-#include "jbm.h"
-
-static const unsigned short notetable[96] = {
- 0x0158, 0x016d, 0x0183, 0x019a, 0x01b2, 0x01cc, 0x01e7, 0x0204,
- 0x0223, 0x0244, 0x0266, 0x028b, 0x0558, 0x056d, 0x0583, 0x059a,
- 0x05b2, 0x05cc, 0x05e7, 0x0604, 0x0623, 0x0644, 0x0666, 0x068b,
- 0x0958, 0x096d, 0x0983, 0x099a, 0x09b2, 0x09cc, 0x09e7, 0x0a04,
- 0x0a23, 0x0a44, 0x0a66, 0x0a8b, 0x0d58, 0x0d6d, 0x0d83, 0x0d9a,
- 0x0db2, 0x0dcc, 0x0de7, 0x0e04, 0x0e23, 0x0e44, 0x0e66, 0x0e8b,
- 0x1158, 0x116d, 0x1183, 0x119a, 0x11b2, 0x11cc, 0x11e7, 0x1204,
- 0x1223, 0x1244, 0x1266, 0x128b, 0x1558, 0x156d, 0x1583, 0x159a,
- 0x15b2, 0x15cc, 0x15e7, 0x1604, 0x1623, 0x1644, 0x1666, 0x168b,
- 0x1958, 0x196d, 0x1983, 0x199a, 0x19b2, 0x19cc, 0x19e7, 0x1a04,
- 0x1a23, 0x1a44, 0x1a66, 0x1a8b, 0x1d58, 0x1d6d, 0x1d83, 0x1d9a,
- 0x1db2, 0x1dcc, 0x1de7, 0x1e04, 0x1e23, 0x1e44, 0x1e66, 0x1e8b
-};
-
-static const unsigned char percmx_tab[4] = { 0x14, 0x12, 0x15, 0x11 };
-static const unsigned char perchn_tab[5] = { 6, 7, 8, 8, 7 };
-static unsigned char percmaskoff[5] = { 0xef, 0xf7, 0xfb, 0xfd, 0xfe };
-static unsigned char percmaskon[5] = { 0x10, 0x08, 0x04, 0x02, 0x01 };
-
-static inline unsigned short GET_WORD(unsigned char *b, int x)
-{
- return ((unsigned short)(b[x+1] << 8) | b[x]);
-}
-
-/*** public methods *************************************/
-
-CPlayer *CjbmPlayer::factory(Copl *newopl)
-{
- return new CjbmPlayer(newopl);
-}
-
-bool CjbmPlayer::load(VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- std::string filename (vfs_get_filename (fd));
- int filelen = fp.filesize(f);
- int i;
-
- if (!filelen || !fp.extension(filename, ".jbm")) goto loaderr;
-
- // Allocate memory buffer m[] and read entire file into it
-
- m = new unsigned char[filelen];
- if (f->readString((char *)m, filelen) != (unsigned int)filelen) goto loaderr;
-
- fp.close(f);
-
- // The known .jbm files always seem to start with the number 0x0002
-
- if (GET_WORD(m, 0) != 0x0002)
- return false;
-
- // Song tempo
-
- i = GET_WORD(m, 2);
- timer = 1193810.0 / (i ? i : 0xffff);
-
- seqtable = GET_WORD(m, 4);
- instable = GET_WORD(m, 6);
-
- // The flags word has atleast 1 bit, the Adlib's rhythm mode, but
- // currently we don't support that :(
-
- flags = GET_WORD(m, 8);
-
- // Instrument datas are directly addressed with m[]
-
- inscount = (filelen - instable) >> 4;
-
- // Voice' and sequence pointers
-
- seqcount = 0xffff;
- for (i = 0; i < 11; i++) {
- voice[i].trkpos = voice[i].trkstart = GET_WORD(m, 10 + (i<<1));
- if (voice[i].trkpos && voice[i].trkpos < seqcount)
- seqcount = voice[i].trkpos;
- }
- seqcount = (seqcount - seqtable) >> 1;
- sequences = new unsigned short[seqcount];
- for (i = 0; i < seqcount; i++)
- sequences[i] = GET_WORD(m, seqtable + (i<<1));
-
- rewind(0);
- return true;
- loaderr:
- fp.close(f);
- return false;
-}
-
-bool CjbmPlayer::update()
-{
- short c, spos, frq;
-
- for (c = 0; c < 11; c++) {
- if (!voice[c].trkpos) // Unused channel
- continue;
-
- if (--voice[c].delay)
- continue;
-
- // Turn current note/percussion off
-
- if (voice[c].note&0x7f)
- opl_noteonoff(c, &voice[c], 0);
-
- // Process events until we have a note
-
- spos = voice[c].seqpos;
- while(!voice[c].delay) {
- switch(m[spos]) {
- case 0xFD: // Set Instrument
- voice[c].instr = m[spos+1];
- set_opl_instrument(c, &voice[c]);
- spos+=2;
- break;
- case 0xFF: // End of Sequence
- voice[c].seqno = m[++voice[c].trkpos];
- if (voice[c].seqno == 0xff) {
- voice[c].trkpos = voice[c].trkstart;
- voice[c].seqno = m[voice[c].trkpos];
- //voicemask &= 0x7ff-(1<<c);
- voicemask &= ~(1<<c);
- }
- spos = voice[c].seqpos = sequences[voice[c].seqno];
- break;
- default: // Note Event
- if ((m[spos] & 127) > 95)
- return 0;
-
- voice[c].note = m[spos];
- voice[c].vol = m[spos+1];
- voice[c].delay =
- (m[spos+2] + (m[spos+3]<<8)) + 1;
-
- frq = notetable[voice[c].note&127];
- voice[c].frq[0] = (unsigned char)frq;
- voice[c].frq[1] = frq >> 8;
- spos+=4;
- }
- }
- voice[c].seqpos = spos;
-
- // Write new volume to the carrier operator, or percussion
-
- if (flags&1 && c > 6)
- opl->write(0x40 + percmx_tab[c-7], voice[c].vol ^ 0x3f);
- else
- opl->write(0x43 + op_table[c], voice[c].vol ^ 0x3f);
-
- // Write new frequencies and Gate bit
-
- opl_noteonoff(c, &voice[c], !(voice[c].note & 0x80));
- }
- return (voicemask);
-}
-
-void CjbmPlayer::rewind(int subsong)
-{
- int c;
-
- voicemask = 0;
-
- for (c = 0; c < 11; c++) {
- voice[c].trkpos = voice[c].trkstart;
-
- if (!voice[c].trkpos) continue;
-
- voicemask |= (1<<c);
-
- voice[c].seqno = m[voice[c].trkpos];
- voice[c].seqpos = sequences[voice[c].seqno];
-
- voice[c].note = 0;
- voice[c].delay = 1;
- }
-
- opl->init();
- opl->write(0x01, 32);
-
- // Set rhythm mode if flags bit #0 is set
- // AM and Vibrato are full depths (taken from DosBox RAW output)
- bdreg = 0xC0 | (flags&1)<<5;
-
- opl->write(0xbd, bdreg);
-
-#if 0
- if (flags&1) {
- voice[7].frq[0] = 0x58; voice[7].frq[1] = 0x09; // XXX
- voice[8].frq[0] = 0x04; voice[8].frq[1] = 0x0a; // XXX
- opl_noteonoff(7, &voice[7], 0);
- opl_noteonoff(8, &voice[8], 0);
- }
-#endif
-
- return;
-}
-
-/*** private methods ************************************/
-
-void CjbmPlayer::opl_noteonoff(int channel, JBMVoice *v, bool state)
-{
- if (flags&1 && channel > 5) {
- // Percussion
- opl->write(0xa0 + perchn_tab[channel-6], voice[channel].frq[0]);
- opl->write(0xb0 + perchn_tab[channel-6], voice[channel].frq[1]);
- opl->write(0xbd,
- state ? bdreg | percmaskon[channel-6] :
- bdreg & percmaskoff[channel-6]);
- } else {
- // Melodic mode or Rhythm mode melodic channels
- opl->write(0xa0 + channel, voice[channel].frq[0]);
- opl->write(0xb0 + channel,
- state ? voice[channel].frq[1] | 0x20 :
- voice[channel].frq[1] & 0x1f);
- }
- return;
-}
-
-
-void CjbmPlayer::set_opl_instrument(int channel, JBMVoice *v)
-{
- short i = instable + (v->instr << 4);
-
- // Sanity check on instr number - or we'll be reading outside m[] !
-
- if (v->instr >= inscount)
- return;
-
- // For rhythm mode, multiplexed drums. I don't care about waveforms!
- if ((flags&1) & (channel > 6)) {
- opl->write(0x20 + percmx_tab[channel-7], m[i+0]);
- opl->write(0x40 + percmx_tab[channel-7], m[i+1] ^ 0x3f);
- opl->write(0x60 + percmx_tab[channel-7], m[i+2]);
- opl->write(0x80 + percmx_tab[channel-7], m[i+3]);
-
- opl->write(0xc0 + perchn_tab[channel-6], m[i+8]&15);
- return;
- }
-
- // AM/VIB/EG/KSR/FRQMUL, KSL/OUTPUT, ADSR for 1st operator
- opl->write(0x20 + op_table[channel], m[i+0]);
- opl->write(0x40 + op_table[channel], m[i+1] ^ 0x3f);
- opl->write(0x60 + op_table[channel], m[i+2]);
- opl->write(0x80 + op_table[channel], m[i+3]);
-
- // AM/VIB/EG/KSR/FRQMUL, KSL/OUTPUT, ADSR for 2nd operator
- opl->write(0x23 + op_table[channel], m[i+4]);
- opl->write(0x43 + op_table[channel], m[i+5] ^ 0x3f);
- opl->write(0x63 + op_table[channel], m[i+6]);
- opl->write(0x83 + op_table[channel], m[i+7]);
-
- // WAVEFORM for operators
- opl->write(0xe0 + op_table[channel], (m[i+8]>>4)&3);
- opl->write(0xe3 + op_table[channel], (m[i+8]>>6)&3);
-
- // FEEDBACK/FM mode
- opl->write(0xc0 + channel, m[i+8]&15);
-
- return;
-}
diff --git a/src/adplug/core/jbm.h b/src/adplug/core/jbm.h
index 11191257a4d0..cb9e4cb634a1 100644
--- a/src/adplug/core/jbm.h
+++ b/src/adplug/core/jbm.h
@@ -1,17 +1,17 @@
/*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2007 Simon Peter <dn.tlp at gmx.net>, et al.
- *
+ *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -32,9 +32,9 @@ class CjbmPlayer: public CPlayer
CjbmPlayer(Copl *newopl) : CPlayer(newopl), m(0)
{ }
~CjbmPlayer()
- { if(m != NULL) delete [] m; }
+ { if(m != nullptr) delete [] m; }
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
@@ -57,7 +57,7 @@ class CjbmPlayer: public CPlayer
unsigned short seqtable, seqcount;
unsigned short instable, inscount;
unsigned short *sequences;
- unsigned char bdreg;
+ unsigned char bdreg;
typedef struct {
unsigned short trkpos, trkstart, seqpos;
@@ -73,7 +73,7 @@ class CjbmPlayer: public CPlayer
private:
//void calc_opl_frequency(JBMVoice *);
- void set_opl_instrument(int, JBMVoice *);
+ void set_opl_instrument(int, JBMVoice *);
void opl_noteonoff(int, JBMVoice *, bool);
};
diff --git a/src/adplug/core/kemuopl.h b/src/adplug/core/kemuopl.h
index d68785fa9256..bdee9d78029a 100644
--- a/src/adplug/core/kemuopl.h
+++ b/src/adplug/core/kemuopl.h
@@ -1,17 +1,17 @@
/*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
+ *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -24,9 +24,7 @@
#define H_ADPLUG_KEMUOPL
#include "opl.h"
-extern "C" {
#include "adlibemu.h"
-}
class CKemuopl: public Copl
{
diff --git a/src/adplug/core/ksm.cc b/src/adplug/core/ksm.cc
new file mode 100644
index 000000000000..9b9bea5d6bea
--- /dev/null
+++ b/src/adplug/core/ksm.cc
@@ -0,0 +1,419 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * ksm.cpp - KSM Player for AdPlug by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <string.h>
+
+#include "ksm.h"
+#include "debug.h"
+
+const unsigned int
+ CksmPlayer::adlibfreq[63] = {
+ 0,
+ 2390, 2411, 2434, 2456, 2480, 2506, 2533, 2562, 2592, 2625, 2659, 2695,
+ 3414, 3435, 3458, 3480, 3504, 3530, 3557, 3586, 3616, 3649, 3683, 3719,
+ 4438, 4459, 4482, 4504, 4528, 4554, 4581, 4610, 4640, 4673, 4707, 4743,
+ 5462, 5483, 5506, 5528, 5552, 5578, 5605, 5634, 5664, 5697, 5731, 5767,
+ 6486, 6507, 6530, 6552, 6576, 6602, 6629, 6658, 6688, 6721, 6755, 6791,
+ 7510
+};
+
+/*** public methods **************************************/
+
+CPlayer *
+CksmPlayer::factory (Copl * newopl)
+{
+ return new CksmPlayer (newopl);
+}
+
+bool
+CksmPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f;
+ int i;
+ std::string filename (fd.filename ());
+ char *fn = new char[filename.length () + 9];
+
+ // file validation section
+ if (!fp.extension (filename, ".ksm"))
+ {
+ AdPlug_LogWrite ("CksmPlayer::load(,\"%s\"): File doesn't have '.ksm' "
+ "extension! Rejected!\n", filename.c_str ());
+ delete[]fn;
+ return false;
+ }
+ AdPlug_LogWrite ("*** CksmPlayer::load(,\"%s\") ***\n", filename.c_str ());
+
+ // Load instruments from 'insts.dat'
+ strcpy (fn, filename.c_str ());
+ for (i = strlen (fn) - 1; i >= 0; i--)
+ if (fn[i] == '/' || fn[i] == '\\')
+ break;
+ strcpy (fn + i + 1, "insts.dat");
+ AdPlug_LogWrite ("Instruments file: \"%s\"\n", fn);
+ VFSFile instfd (fn, "rb");
+ f = fp.open (instfd);
+ delete[]fn;
+ if (!f)
+ {
+ AdPlug_LogWrite ("Couldn't open instruments file! Aborting!\n");
+ AdPlug_LogWrite ("--- CksmPlayer::load ---\n");
+ return false;
+ }
+ loadinsts (f);
+ fp.close (f);
+
+ f = fp.open (fd);
+ if (!f)
+ return false;
+ for (i = 0; i < 16; i++)
+ trinst[i] = f->readInt (1);
+ for (i = 0; i < 16; i++)
+ trquant[i] = f->readInt (1);
+ for (i = 0; i < 16; i++)
+ trchan[i] = f->readInt (1);
+ f->ignore (16);
+ for (i = 0; i < 16; i++)
+ trvol[i] = f->readInt (1);
+ numnotes = f->readInt (2);
+ note = new unsigned long[numnotes];
+ for (i = 0; i < numnotes; i++)
+ note[i] = f->readInt (4);
+ fp.close (f);
+
+ if (!trchan[11])
+ {
+ drumstat = 0;
+ numchans = 9;
+ }
+ else
+ {
+ drumstat = 32;
+ numchans = 6;
+ }
+
+ rewind (0);
+ AdPlug_LogWrite ("--- CksmPlayer::load ---\n");
+ return true;
+}
+
+bool
+CksmPlayer::update ()
+{
+ int quanter, chan = 0, drumnum = 0, freq, track, volevel, volval;
+ unsigned int i, j, bufnum;
+ unsigned long temp, templong;
+
+ count++;
+ if (count >= countstop)
+ {
+ bufnum = 0;
+ while (count >= countstop)
+ {
+ templong = note[nownote];
+ track = (int) ((templong >> 8) & 15);
+ if ((templong & 192) == 0)
+ {
+ i = 0;
+
+ while ((i < numchans) &&
+ ((chanfreq[i] != (templong & 63)) ||
+ (chantrack[i] != ((templong >> 8) & 15))))
+ i++;
+ if (i < numchans)
+ {
+ databuf[bufnum] = (char) 0;
+ bufnum++;
+ databuf[bufnum] = (unsigned char) (0xb0 + i);
+ bufnum++;
+ databuf[bufnum] =
+ (unsigned char) ((adlibfreq[templong & 63] >> 8) & 223);
+ bufnum++;
+ chanfreq[i] = 0;
+ chanage[i] = 0;
+ }
+ }
+ else
+ {
+ volevel = trvol[track];
+ if ((templong & 192) == 128)
+ {
+ volevel -= 4;
+ if (volevel < 0)
+ volevel = 0;
+ }
+ if ((templong & 192) == 192)
+ {
+ volevel += 4;
+ if (volevel > 63)
+ volevel = 63;
+ }
+ if (track < 11)
+ {
+ temp = 0;
+ i = numchans;
+ for (j = 0; j < numchans; j++)
+ if ((countstop - chanage[j] >= temp) && (chantrack[j] == track))
+ {
+ temp = countstop - chanage[j];
+ i = j;
+ }
+ if (i < numchans)
+ {
+ databuf[bufnum] = (char) 0, bufnum++;
+ databuf[bufnum] = (unsigned char) (0xb0 + i);
+ bufnum++;
+ databuf[bufnum] = (unsigned char) 0;
+ bufnum++;
+ volval = (inst[trinst[track]][1] & 192) + (volevel ^ 63);
+ databuf[bufnum] = (char) 0, bufnum++;
+ databuf[bufnum] = (unsigned char) (0x40 + op_table[i] + 3);
+ bufnum++;
+ databuf[bufnum] = (unsigned char) volval;
+ bufnum++;
+ databuf[bufnum] = (char) 0, bufnum++;
+ databuf[bufnum] = (unsigned char) (0xa0 + i);
+ bufnum++;
+ databuf[bufnum] =
+ (unsigned char) (adlibfreq[templong & 63] & 255);
+ bufnum++;
+ databuf[bufnum] = (char) 0, bufnum++;
+ databuf[bufnum] = (unsigned char) (0xb0 + i);
+ bufnum++;
+ databuf[bufnum] =
+ (unsigned char) ((adlibfreq[templong & 63] >> 8) | 32);
+ bufnum++;
+ chanfreq[i] = templong & 63;
+ chanage[i] = countstop;
+ }
+ }
+ else if ((drumstat & 32) > 0)
+ {
+ freq = adlibfreq[templong & 63];
+ switch (track)
+ {
+ case 11:
+ drumnum = 16;
+ chan = 6;
+ freq -= 2048;
+ break;
+ case 12:
+ drumnum = 8;
+ chan = 7;
+ freq -= 2048;
+ break;
+ case 13:
+ drumnum = 4;
+ chan = 8;
+ break;
+ case 14:
+ drumnum = 2;
+ chan = 8;
+ break;
+ case 15:
+ drumnum = 1;
+ chan = 7;
+ freq -= 2048;
+ break;
+ }
+ databuf[bufnum] = (char) 0, bufnum++;
+ databuf[bufnum] = (unsigned char) (0xa0 + chan);
+ bufnum++;
+ databuf[bufnum] = (unsigned char) (freq & 255);
+ bufnum++;
+ databuf[bufnum] = (char) 0, bufnum++;
+ databuf[bufnum] = (unsigned char) (0xb0 + chan);
+ bufnum++;
+ databuf[bufnum] = (unsigned char) ((freq >> 8) & 223);
+ bufnum++;
+ databuf[bufnum] = (char) 0, bufnum++;
+ databuf[bufnum] = (unsigned char) (0xbd);
+ bufnum++;
+ databuf[bufnum] = (unsigned char) (drumstat & (255 - drumnum));
+ bufnum++;
+ drumstat |= drumnum;
+ if ((track == 11) || (track == 12) || (track == 14))
+ {
+ volval = (inst[trinst[track]][1] & 192) + (volevel ^ 63);
+ databuf[bufnum] = (char) 0, bufnum++;
+ databuf[bufnum] = (unsigned char) (0x40 + op_table[chan] + 3);
+ bufnum++;
+ databuf[bufnum] = (unsigned char) (volval);
+ bufnum++;
+ }
+ else
+ {
+ volval = (inst[trinst[track]][6] & 192) + (volevel ^ 63);
+ databuf[bufnum] = (char) 0, bufnum++;
+ databuf[bufnum] = (unsigned char) (0x40 + op_table[chan]);
+ bufnum++;
+ databuf[bufnum] = (unsigned char) (volval);
+ bufnum++;
+ }
+ databuf[bufnum] = (char) 0, bufnum++;
+ databuf[bufnum] = (unsigned char) (0xbd);
+ bufnum++;
+ databuf[bufnum] = (unsigned char) (drumstat);
+ bufnum++;
+ }
+ }
+ nownote++;
+ if (nownote >= numnotes)
+ {
+ nownote = 0;
+ songend = true;
+ }
+ templong = note[nownote];
+ if (nownote == 0)
+ count = (templong >> 12) - 1;
+ quanter = (240 / trquant[(templong >> 8) & 15]);
+ countstop = (((templong >> 12) + (quanter >> 1)) / quanter) * quanter;
+ }
+ for (i = 0; i < bufnum; i += 3)
+ opl->write (databuf[i + 1], databuf[i + 2]);
+ }
+ return !songend;
+}
+
+void
+CksmPlayer::rewind (int subsong)
+{
+ unsigned int i, j, k;
+ unsigned char instbuf[11];
+ unsigned long templong;
+
+ songend = false;
+ opl->init ();
+ opl->write (1, 32);
+ opl->write (4, 0);
+ opl->write (8, 0);
+ opl->write (0xbd, drumstat);
+
+ if (trchan[11] == 1)
+ {
+ for (i = 0; i < 11; i++)
+ instbuf[i] = inst[trinst[11]][i];
+ instbuf[1] = ((instbuf[1] & 192) | ((trvol[11]) ^ 63));
+ setinst (6, instbuf[0], instbuf[1], instbuf[2], instbuf[3], instbuf[4],
+ instbuf[5], instbuf[6], instbuf[7], instbuf[8], instbuf[9],
+ instbuf[10]);
+ for (i = 0; i < 5; i++)
+ instbuf[i] = inst[trinst[12]][i];
+ for (i = 5; i < 11; i++)
+ instbuf[i] = inst[trinst[15]][i];
+ instbuf[1] = ((instbuf[1] & 192) | ((trvol[12]) ^ 63));
+ instbuf[6] = ((instbuf[6] & 192) | ((trvol[15]) ^ 63));
+ setinst (7, instbuf[0], instbuf[1], instbuf[2], instbuf[3], instbuf[4],
+ instbuf[5], instbuf[6], instbuf[7], instbuf[8], instbuf[9],
+ instbuf[10]);
+ for (i = 0; i < 5; i++)
+ instbuf[i] = inst[trinst[14]][i];
+ for (i = 5; i < 11; i++)
+ instbuf[i] = inst[trinst[13]][i];
+ instbuf[1] = ((instbuf[1] & 192) | ((trvol[14]) ^ 63));
+ instbuf[6] = ((instbuf[6] & 192) | ((trvol[13]) ^ 63));
+ setinst (8, instbuf[0], instbuf[1], instbuf[2], instbuf[3], instbuf[4],
+ instbuf[5], instbuf[6], instbuf[7], instbuf[8], instbuf[9],
+ instbuf[10]);
+ }
+
+ for (i = 0; i < numchans; i++)
+ {
+ chantrack[i] = 0;
+ chanage[i] = 0;
+ }
+ j = 0;
+ for (i = 0; i < 16; i++)
+ if ((trchan[i] > 0) && (j < numchans))
+ {
+ k = trchan[i];
+ while ((j < numchans) && (k > 0))
+ {
+ chantrack[j] = i;
+ k--;
+ j++;
+ }
+ }
+ for (i = 0; i < numchans; i++)
+ {
+ for (j = 0; j < 11; j++)
+ instbuf[j] = inst[trinst[chantrack[i]]][j];
+ instbuf[1] = ((instbuf[1] & 192) | (63 - trvol[chantrack[i]]));
+ setinst (i, instbuf[0], instbuf[1], instbuf[2], instbuf[3], instbuf[4],
+ instbuf[5], instbuf[6], instbuf[7], instbuf[8], instbuf[9],
+ instbuf[10]);
+ chanfreq[i] = 0;
+ }
+ k = 0;
+ templong = *note;
+ count = (templong >> 12) - 1;
+ countstop = (templong >> 12) - 1;
+ nownote = 0;
+}
+
+std::string CksmPlayer::getinstrument (unsigned int n)
+{
+ if (trchan[n])
+ return std::string (instname[trinst[n]]);
+ else
+ return std::string ();
+}
+
+/*** private methods *************************************/
+
+void
+CksmPlayer::loadinsts (binistream * f)
+{
+ int i, j;
+
+ for (i = 0; i < 256; i++)
+ {
+ f->readString (instname[i], 20);
+ for (j = 0; j < 11; j++)
+ inst[i][j] = f->readInt (1);
+ f->ignore (2);
+ }
+}
+
+void
+CksmPlayer::setinst (int chan,
+ unsigned char v0, unsigned char v1, unsigned char v2,
+ unsigned char v3, unsigned char v4, unsigned char v5,
+ unsigned char v6, unsigned char v7, unsigned char v8,
+ unsigned char v9, unsigned char v10)
+{
+ int offs;
+
+ opl->write (0xa0 + chan, 0);
+ opl->write (0xb0 + chan, 0);
+ opl->write (0xc0 + chan, v10);
+ offs = op_table[chan];
+ opl->write (0x20 + offs, v5);
+ opl->write (0x40 + offs, v6);
+ opl->write (0x60 + offs, v7);
+ opl->write (0x80 + offs, v8);
+ opl->write (0xe0 + offs, v9);
+ offs += 3;
+ opl->write (0x20 + offs, v0);
+ opl->write (0x40 + offs, v1);
+ opl->write (0x60 + offs, v2);
+ opl->write (0x80 + offs, v3);
+ opl->write (0xe0 + offs, v4);
+}
diff --git a/src/adplug/core/ksm.cxx b/src/adplug/core/ksm.cxx
deleted file mode 100644
index 4346fbeb757e..000000000000
--- a/src/adplug/core/ksm.cxx
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * ksm.cpp - KSM Player for AdPlug by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <string.h>
-
-#include "ksm.h"
-#include "debug.h"
-
-const unsigned int
- CksmPlayer::adlibfreq[63] = {
- 0,
- 2390, 2411, 2434, 2456, 2480, 2506, 2533, 2562, 2592, 2625, 2659, 2695,
- 3414, 3435, 3458, 3480, 3504, 3530, 3557, 3586, 3616, 3649, 3683, 3719,
- 4438, 4459, 4482, 4504, 4528, 4554, 4581, 4610, 4640, 4673, 4707, 4743,
- 5462, 5483, 5506, 5528, 5552, 5578, 5605, 5634, 5664, 5697, 5731, 5767,
- 6486, 6507, 6530, 6552, 6576, 6602, 6629, 6658, 6688, 6721, 6755, 6791,
- 7510
-};
-
-/*** public methods **************************************/
-
-CPlayer *
-CksmPlayer::factory (Copl * newopl)
-{
- return new CksmPlayer (newopl);
-}
-
-bool
-CksmPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f;
- int i;
- std::string filename (vfs_get_filename (fd));
- char *fn = new char[filename.length () + 9];
-
- // file validation section
- if (!fp.extension (filename, ".ksm"))
- {
- AdPlug_LogWrite ("CksmPlayer::load(,\"%s\"): File doesn't have '.ksm' "
- "extension! Rejected!\n", filename.c_str ());
- delete[]fn;
- return false;
- }
- AdPlug_LogWrite ("*** CksmPlayer::load(,\"%s\") ***\n", filename.c_str ());
-
- // Load instruments from 'insts.dat'
- strcpy (fn, filename.c_str ());
- for (i = strlen (fn) - 1; i >= 0; i--)
- if (fn[i] == '/' || fn[i] == '\\')
- break;
- strcpy (fn + i + 1, "insts.dat");
- AdPlug_LogWrite ("Instruments file: \"%s\"\n", fn);
- VFSFile *instfd = vfs_fopen (fn, "rb");
- f = fp.open (instfd);
- delete[]fn;
- if (!f)
- {
- AdPlug_LogWrite ("Couldn't open instruments file! Aborting!\n");
- AdPlug_LogWrite ("--- CksmPlayer::load ---\n");
- return false;
- }
- loadinsts (f);
- fp.close (f);
- vfs_fclose (instfd);
-
- f = fp.open (fd);
- if (!f)
- return false;
- for (i = 0; i < 16; i++)
- trinst[i] = f->readInt (1);
- for (i = 0; i < 16; i++)
- trquant[i] = f->readInt (1);
- for (i = 0; i < 16; i++)
- trchan[i] = f->readInt (1);
- f->ignore (16);
- for (i = 0; i < 16; i++)
- trvol[i] = f->readInt (1);
- numnotes = f->readInt (2);
- note = new unsigned long[numnotes];
- for (i = 0; i < numnotes; i++)
- note[i] = f->readInt (4);
- fp.close (f);
-
- if (!trchan[11])
- {
- drumstat = 0;
- numchans = 9;
- }
- else
- {
- drumstat = 32;
- numchans = 6;
- }
-
- rewind (0);
- AdPlug_LogWrite ("--- CksmPlayer::load ---\n");
- return true;
-}
-
-bool
-CksmPlayer::update ()
-{
- int quanter, chan = 0, drumnum = 0, freq, track, volevel, volval;
- unsigned int i, j, bufnum;
- unsigned long temp, templong;
-
- count++;
- if (count >= countstop)
- {
- bufnum = 0;
- while (count >= countstop)
- {
- templong = note[nownote];
- track = (int) ((templong >> 8) & 15);
- if ((templong & 192) == 0)
- {
- i = 0;
-
- while ((i < numchans) &&
- ((chanfreq[i] != (templong & 63)) ||
- (chantrack[i] != ((templong >> 8) & 15))))
- i++;
- if (i < numchans)
- {
- databuf[bufnum] = (char) 0;
- bufnum++;
- databuf[bufnum] = (unsigned char) (0xb0 + i);
- bufnum++;
- databuf[bufnum] =
- (unsigned char) ((adlibfreq[templong & 63] >> 8) & 223);
- bufnum++;
- chanfreq[i] = 0;
- chanage[i] = 0;
- }
- }
- else
- {
- volevel = trvol[track];
- if ((templong & 192) == 128)
- {
- volevel -= 4;
- if (volevel < 0)
- volevel = 0;
- }
- if ((templong & 192) == 192)
- {
- volevel += 4;
- if (volevel > 63)
- volevel = 63;
- }
- if (track < 11)
- {
- temp = 0;
- i = numchans;
- for (j = 0; j < numchans; j++)
- if ((countstop - chanage[j] >= temp) && (chantrack[j] == track))
- {
- temp = countstop - chanage[j];
- i = j;
- }
- if (i < numchans)
- {
- databuf[bufnum] = (char) 0, bufnum++;
- databuf[bufnum] = (unsigned char) (0xb0 + i);
- bufnum++;
- databuf[bufnum] = (unsigned char) 0;
- bufnum++;
- volval = (inst[trinst[track]][1] & 192) + (volevel ^ 63);
- databuf[bufnum] = (char) 0, bufnum++;
- databuf[bufnum] = (unsigned char) (0x40 + op_table[i] + 3);
- bufnum++;
- databuf[bufnum] = (unsigned char) volval;
- bufnum++;
- databuf[bufnum] = (char) 0, bufnum++;
- databuf[bufnum] = (unsigned char) (0xa0 + i);
- bufnum++;
- databuf[bufnum] =
- (unsigned char) (adlibfreq[templong & 63] & 255);
- bufnum++;
- databuf[bufnum] = (char) 0, bufnum++;
- databuf[bufnum] = (unsigned char) (0xb0 + i);
- bufnum++;
- databuf[bufnum] =
- (unsigned char) ((adlibfreq[templong & 63] >> 8) | 32);
- bufnum++;
- chanfreq[i] = templong & 63;
- chanage[i] = countstop;
- }
- }
- else if ((drumstat & 32) > 0)
- {
- freq = adlibfreq[templong & 63];
- switch (track)
- {
- case 11:
- drumnum = 16;
- chan = 6;
- freq -= 2048;
- break;
- case 12:
- drumnum = 8;
- chan = 7;
- freq -= 2048;
- break;
- case 13:
- drumnum = 4;
- chan = 8;
- break;
- case 14:
- drumnum = 2;
- chan = 8;
- break;
- case 15:
- drumnum = 1;
- chan = 7;
- freq -= 2048;
- break;
- }
- databuf[bufnum] = (char) 0, bufnum++;
- databuf[bufnum] = (unsigned char) (0xa0 + chan);
- bufnum++;
- databuf[bufnum] = (unsigned char) (freq & 255);
- bufnum++;
- databuf[bufnum] = (char) 0, bufnum++;
- databuf[bufnum] = (unsigned char) (0xb0 + chan);
- bufnum++;
- databuf[bufnum] = (unsigned char) ((freq >> 8) & 223);
- bufnum++;
- databuf[bufnum] = (char) 0, bufnum++;
- databuf[bufnum] = (unsigned char) (0xbd);
- bufnum++;
- databuf[bufnum] = (unsigned char) (drumstat & (255 - drumnum));
- bufnum++;
- drumstat |= drumnum;
- if ((track == 11) || (track == 12) || (track == 14))
- {
- volval = (inst[trinst[track]][1] & 192) + (volevel ^ 63);
- databuf[bufnum] = (char) 0, bufnum++;
- databuf[bufnum] = (unsigned char) (0x40 + op_table[chan] + 3);
- bufnum++;
- databuf[bufnum] = (unsigned char) (volval);
- bufnum++;
- }
- else
- {
- volval = (inst[trinst[track]][6] & 192) + (volevel ^ 63);
- databuf[bufnum] = (char) 0, bufnum++;
- databuf[bufnum] = (unsigned char) (0x40 + op_table[chan]);
- bufnum++;
- databuf[bufnum] = (unsigned char) (volval);
- bufnum++;
- }
- databuf[bufnum] = (char) 0, bufnum++;
- databuf[bufnum] = (unsigned char) (0xbd);
- bufnum++;
- databuf[bufnum] = (unsigned char) (drumstat);
- bufnum++;
- }
- }
- nownote++;
- if (nownote >= numnotes)
- {
- nownote = 0;
- songend = true;
- }
- templong = note[nownote];
- if (nownote == 0)
- count = (templong >> 12) - 1;
- quanter = (240 / trquant[(templong >> 8) & 15]);
- countstop = (((templong >> 12) + (quanter >> 1)) / quanter) * quanter;
- }
- for (i = 0; i < bufnum; i += 3)
- opl->write (databuf[i + 1], databuf[i + 2]);
- }
- return !songend;
-}
-
-void
-CksmPlayer::rewind (int subsong)
-{
- unsigned int i, j, k;
- unsigned char instbuf[11];
- unsigned long templong;
-
- songend = false;
- opl->init ();
- opl->write (1, 32);
- opl->write (4, 0);
- opl->write (8, 0);
- opl->write (0xbd, drumstat);
-
- if (trchan[11] == 1)
- {
- for (i = 0; i < 11; i++)
- instbuf[i] = inst[trinst[11]][i];
- instbuf[1] = ((instbuf[1] & 192) | ((trvol[11]) ^ 63));
- setinst (6, instbuf[0], instbuf[1], instbuf[2], instbuf[3], instbuf[4],
- instbuf[5], instbuf[6], instbuf[7], instbuf[8], instbuf[9],
- instbuf[10]);
- for (i = 0; i < 5; i++)
- instbuf[i] = inst[trinst[12]][i];
- for (i = 5; i < 11; i++)
- instbuf[i] = inst[trinst[15]][i];
- instbuf[1] = ((instbuf[1] & 192) | ((trvol[12]) ^ 63));
- instbuf[6] = ((instbuf[6] & 192) | ((trvol[15]) ^ 63));
- setinst (7, instbuf[0], instbuf[1], instbuf[2], instbuf[3], instbuf[4],
- instbuf[5], instbuf[6], instbuf[7], instbuf[8], instbuf[9],
- instbuf[10]);
- for (i = 0; i < 5; i++)
- instbuf[i] = inst[trinst[14]][i];
- for (i = 5; i < 11; i++)
- instbuf[i] = inst[trinst[13]][i];
- instbuf[1] = ((instbuf[1] & 192) | ((trvol[14]) ^ 63));
- instbuf[6] = ((instbuf[6] & 192) | ((trvol[13]) ^ 63));
- setinst (8, instbuf[0], instbuf[1], instbuf[2], instbuf[3], instbuf[4],
- instbuf[5], instbuf[6], instbuf[7], instbuf[8], instbuf[9],
- instbuf[10]);
- }
-
- for (i = 0; i < numchans; i++)
- {
- chantrack[i] = 0;
- chanage[i] = 0;
- }
- j = 0;
- for (i = 0; i < 16; i++)
- if ((trchan[i] > 0) && (j < numchans))
- {
- k = trchan[i];
- while ((j < numchans) && (k > 0))
- {
- chantrack[j] = i;
- k--;
- j++;
- }
- }
- for (i = 0; i < numchans; i++)
- {
- for (j = 0; j < 11; j++)
- instbuf[j] = inst[trinst[chantrack[i]]][j];
- instbuf[1] = ((instbuf[1] & 192) | (63 - trvol[chantrack[i]]));
- setinst (i, instbuf[0], instbuf[1], instbuf[2], instbuf[3], instbuf[4],
- instbuf[5], instbuf[6], instbuf[7], instbuf[8], instbuf[9],
- instbuf[10]);
- chanfreq[i] = 0;
- }
- k = 0;
- templong = *note;
- count = (templong >> 12) - 1;
- countstop = (templong >> 12) - 1;
- nownote = 0;
-}
-
-std::string CksmPlayer::getinstrument (unsigned int n)
-{
- if (trchan[n])
- return std::string (instname[trinst[n]]);
- else
- return std::string ();
-}
-
-/*** private methods *************************************/
-
-void
-CksmPlayer::loadinsts (binistream * f)
-{
- int i, j;
-
- for (i = 0; i < 256; i++)
- {
- f->readString (instname[i], 20);
- for (j = 0; j < 11; j++)
- inst[i][j] = f->readInt (1);
- f->ignore (2);
- }
-}
-
-void
-CksmPlayer::setinst (int chan,
- unsigned char v0, unsigned char v1, unsigned char v2,
- unsigned char v3, unsigned char v4, unsigned char v5,
- unsigned char v6, unsigned char v7, unsigned char v8,
- unsigned char v9, unsigned char v10)
-{
- int offs;
-
- opl->write (0xa0 + chan, 0);
- opl->write (0xb0 + chan, 0);
- opl->write (0xc0 + chan, v10);
- offs = op_table[chan];
- opl->write (0x20 + offs, v5);
- opl->write (0x40 + offs, v6);
- opl->write (0x60 + offs, v7);
- opl->write (0x80 + offs, v8);
- opl->write (0xe0 + offs, v9);
- offs += 3;
- opl->write (0x20 + offs, v0);
- opl->write (0x40 + offs, v1);
- opl->write (0x60 + offs, v2);
- opl->write (0x80 + offs, v3);
- opl->write (0xe0 + offs, v4);
-}
diff --git a/src/adplug/core/ksm.h b/src/adplug/core/ksm.h
index 5cd424604dc8..3137df9dee07 100644
--- a/src/adplug/core/ksm.h
+++ b/src/adplug/core/ksm.h
@@ -32,7 +32,7 @@ public:
~CksmPlayer()
{ if(note) delete [] note; };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh()
diff --git a/src/adplug/core/lds.cc b/src/adplug/core/lds.cc
new file mode 100644
index 000000000000..93789a25595b
--- /dev/null
+++ b/src/adplug/core/lds.cc
@@ -0,0 +1,817 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * lds.cpp - LOUDNESS Player by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <string.h>
+
+#include "lds.h"
+#include "debug.h"
+
+// Note frequency table (16 notes / octave)
+const unsigned short
+ CldsPlayer::frequency[] = {
+ 343, 344, 345, 347, 348, 349, 350, 352, 353, 354, 356, 357, 358,
+ 359, 361, 362, 363, 365, 366, 367, 369, 370, 371, 373, 374, 375,
+ 377, 378, 379, 381, 382, 384, 385, 386, 388, 389, 391, 392, 393,
+ 395, 396, 398, 399, 401, 402, 403, 405, 406, 408, 409, 411, 412,
+ 414, 415, 417, 418, 420, 421, 423, 424, 426, 427, 429, 430, 432,
+ 434, 435, 437, 438, 440, 442, 443, 445, 446, 448, 450, 451, 453,
+ 454, 456, 458, 459, 461, 463, 464, 466, 468, 469, 471, 473, 475,
+ 476, 478, 480, 481, 483, 485, 487, 488, 490, 492, 494, 496, 497,
+ 499, 501, 503, 505, 506, 508, 510, 512, 514, 516, 518, 519, 521,
+ 523, 525, 527, 529, 531, 533, 535, 537, 538, 540, 542, 544, 546,
+ 548, 550, 552, 554, 556, 558, 560, 562, 564, 566, 568, 571, 573,
+ 575, 577, 579, 581, 583, 585, 587, 589, 591, 594, 596, 598, 600,
+ 602, 604, 607, 609, 611, 613, 615, 618, 620, 622, 624, 627, 629,
+ 631, 633, 636, 638, 640, 643, 645, 647, 650, 652, 654, 657, 659,
+ 662, 664, 666, 669, 671, 674, 676, 678, 681, 683
+};
+
+// Vibrato (sine) table
+const unsigned char
+ CldsPlayer::vibtab[] = {
+ 0, 13, 25, 37, 50, 62, 74, 86, 98, 109, 120, 131, 142, 152, 162,
+ 171, 180, 189, 197, 205, 212, 219, 225, 231, 236, 240, 244, 247,
+ 250, 252, 254, 255, 255, 255, 254, 252, 250, 247, 244, 240, 236,
+ 231, 225, 219, 212, 205, 197, 189, 180, 171, 162, 152, 142, 131,
+ 120, 109, 98, 86, 74, 62, 50, 37, 25, 13
+};
+
+// Tremolo (sine * sine) table
+const unsigned char
+ CldsPlayer::tremtab[] = {
+ 0, 0, 1, 1, 2, 4, 5, 7, 10, 12, 15, 18, 21, 25, 29, 33, 37, 42, 47,
+ 52, 57, 62, 67, 73, 79, 85, 90, 97, 103, 109, 115, 121, 128, 134,
+ 140, 146, 152, 158, 165, 170, 176, 182, 188, 193, 198, 203, 208,
+ 213, 218, 222, 226, 230, 234, 237, 240, 243, 245, 248, 250, 251,
+ 253, 254, 254, 255, 255, 255, 254, 254, 253, 251, 250, 248, 245,
+ 243, 240, 237, 234, 230, 226, 222, 218, 213, 208, 203, 198, 193,
+ 188, 182, 176, 170, 165, 158, 152, 146, 140, 134, 127, 121, 115,
+ 109, 103, 97, 90, 85, 79, 73, 67, 62, 57, 52, 47, 42, 37, 33, 29,
+ 25, 21, 18, 15, 12, 10, 7, 5, 4, 2, 1, 1, 0
+};
+
+// 'maxsound' is maximum number of patches (instruments)
+// 'maxpos' is maximum number of entries in position list (orderlist)
+const unsigned short
+ CldsPlayer::maxsound = 0x3f, CldsPlayer::maxpos = 0xff;
+
+/*** public methods *************************************/
+
+CldsPlayer::CldsPlayer (Copl * newopl):CPlayer (newopl), soundbank (0), positions (0),
+patterns (0)
+{
+}
+
+CldsPlayer::~CldsPlayer ()
+{
+ if (soundbank)
+ delete[]soundbank;
+ if (positions)
+ delete[]positions;
+ if (patterns)
+ delete[]patterns;
+}
+
+bool
+CldsPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f;
+ unsigned int i, j;
+ SoundBank *sb;
+ std::string filename (fd.filename ());
+
+ // file validation section (actually just an extension check)
+ f = fp.open (fd);
+ if (!f)
+ return false;
+ if (!fp.extension (filename, ".lds"))
+ return false;
+
+ // file load section (header)
+ mode = f->readInt (1);
+ if (mode > 2)
+ {
+ fp.close (f);
+ return false;
+ }
+ speed = f->readInt (2);
+ tempo = f->readInt (1);
+ pattlen = f->readInt (1);
+ for (i = 0; i < 9; i++)
+ chandelay[i] = f->readInt (1);
+ regbd = f->readInt (1);
+
+ // load patches
+ numpatch = f->readInt (2);
+ soundbank = new SoundBank[numpatch];
+ for (i = 0; i < numpatch; i++)
+ {
+ sb = &soundbank[i];
+ sb->mod_misc = f->readInt (1);
+ sb->mod_vol = f->readInt (1);
+ sb->mod_ad = f->readInt (1);
+ sb->mod_sr = f->readInt (1);
+ sb->mod_wave = f->readInt (1);
+ sb->car_misc = f->readInt (1);
+ sb->car_vol = f->readInt (1);
+ sb->car_ad = f->readInt (1);
+ sb->car_sr = f->readInt (1);
+ sb->car_wave = f->readInt (1);
+ sb->feedback = f->readInt (1);
+ sb->keyoff = f->readInt (1);
+ sb->portamento = f->readInt (1);
+ sb->glide = f->readInt (1);
+ sb->finetune = f->readInt (1);
+ sb->vibrato = f->readInt (1);
+ sb->vibdelay = f->readInt (1);
+ sb->mod_trem = f->readInt (1);
+ sb->car_trem = f->readInt (1);
+ sb->tremwait = f->readInt (1);
+ sb->arpeggio = f->readInt (1);
+ for (j = 0; j < 12; j++)
+ sb->arp_tab[j] = f->readInt (1);
+ sb->start = f->readInt (2);
+ sb->size = f->readInt (2);
+ sb->fms = f->readInt (1);
+ sb->transp = f->readInt (2);
+ sb->midinst = f->readInt (1);
+ sb->midvelo = f->readInt (1);
+ sb->midkey = f->readInt (1);
+ sb->midtrans = f->readInt (1);
+ sb->middum1 = f->readInt (1);
+ sb->middum2 = f->readInt (1);
+ }
+
+ // load positions
+ numposi = f->readInt (2);
+ positions = new Position[9 * numposi];
+ for (i = 0; i < numposi; i++)
+ for (j = 0; j < 9; j++)
+ {
+ /*
+ * patnum is a pointer inside the pattern space, but patterns are 16bit
+ * word fields anyway, so it ought to be an even number (hopefully) and
+ * we can just divide it by 2 to get our array index of 16bit words.
+ */
+ positions[i * 9 + j].patnum = f->readInt (2) / 2;
+ positions[i * 9 + j].transpose = f->readInt (1);
+ }
+
+ AdPlug_LogWrite
+ ("CldsPlayer::load(\"%s\",fp): loading LOUDNESS file: mode = "
+ "%d, pattlen = %d, numpatch = %d, numposi = %d\n", filename.c_str (),
+ mode, pattlen, numpatch, numposi);
+
+ // load patterns
+ f->ignore (2); // ignore # of digital sounds (not played by this player)
+ patterns = new unsigned short[(fp.filesize (f) - f->pos ()) / 2 + 1];
+ for (i = 0; !f->eof (); i++)
+ patterns[i] = f->readInt (2);
+
+ fp.close (f);
+ rewind (0);
+ return true;
+}
+
+bool
+CldsPlayer::update ()
+{
+ unsigned short comword, freq, octave, chan, tune, wibc, tremc, arpreg;
+ bool vbreak;
+ unsigned char level, regnum, comhi, comlo;
+ int i;
+ Channel *c;
+
+ if (!playing)
+ return false;
+
+ // handle fading
+ if (fadeonoff)
+ {
+ if (fadeonoff <= 128)
+ {
+ if (allvolume > fadeonoff || allvolume == 0)
+ allvolume -= fadeonoff;
+ else
+ {
+ allvolume = 1;
+ fadeonoff = 0;
+ if (hardfade != 0)
+ {
+ playing = false;
+ hardfade = 0;
+ for (i = 0; i < 9; i++)
+ channel[i].keycount = 1;
+ }
+ }
+ }
+ else
+ if ((unsigned int) ((allvolume + (0x100 - fadeonoff)) & 0xff) <=
+ mainvolume)
+ allvolume += 0x100 - fadeonoff;
+ else
+ {
+ allvolume = mainvolume;
+ fadeonoff = 0;
+ }
+ }
+
+ // handle channel delay
+ for (chan = 0; chan < 9; chan++)
+ {
+ c = &channel[chan];
+ if (c->chancheat.chandelay)
+ if (!(--c->chancheat.chandelay))
+ playsound (c->chancheat.sound, chan, c->chancheat.high);
+ }
+
+ // handle notes
+ if (!tempo_now)
+ {
+ vbreak = false;
+ for (chan = 0; chan < 9; chan++)
+ {
+ c = &channel[chan];
+ if (!c->packwait)
+ {
+ unsigned short patnum = positions[posplay * 9 + chan].patnum;
+ unsigned char transpose = positions[posplay * 9 + chan].transpose;
+
+ comword = patterns[patnum + c->packpos];
+ comhi = comword >> 8;
+ comlo = comword & 0xff;
+ if (comword)
+ {
+ if (comhi == 0x80)
+ {
+ c->packwait = comlo;
+ }
+ else if (comhi >= 0x80)
+ {
+ switch (comhi)
+ {
+ case 0xff:
+ c->volcar = (((c->volcar & 0x3f) * comlo) >> 6) & 0x3f;
+ if (fmchip[0xc0 + chan] & 1)
+ c->volmod = (((c->volmod & 0x3f) * comlo) >> 6) & 0x3f;
+ break;
+ case 0xfe:
+ tempo = comword & 0x3f;
+ break;
+ case 0xfd:
+ c->nextvol = comlo;
+ break;
+ case 0xfc:
+ playing = false;
+ // in real player there's also full keyoff here, but we don't need it
+ break;
+ case 0xfb:
+ c->keycount = 1;
+ break;
+ case 0xfa:
+ vbreak = true;
+ jumppos = (posplay + 1) & maxpos;
+ break;
+ case 0xf9:
+ vbreak = true;
+ jumppos = comlo & maxpos;
+ jumping = 1;
+ if (jumppos < posplay)
+ songlooped = true;
+ break;
+ case 0xf8:
+ c->lasttune = 0;
+ break;
+ case 0xf7:
+ c->vibwait = 0;
+ // PASCAL: c->vibspeed = ((comlo >> 4) & 15) + 2;
+ c->vibspeed = (comlo >> 4) + 2;
+ c->vibrate = (comlo & 15) + 1;
+ break;
+ case 0xf6:
+ c->glideto = comlo;
+ break;
+ case 0xf5:
+ c->finetune = comlo;
+ break;
+ case 0xf4:
+ if (!hardfade)
+ {
+ allvolume = mainvolume = comlo;
+ fadeonoff = 0;
+ }
+ break;
+ case 0xf3:
+ if (!hardfade)
+ fadeonoff = comlo;
+ break;
+ case 0xf2:
+ c->trmstay = comlo;
+ break;
+ case 0xf1: // panorama
+ case 0xf0: // progch
+ // MIDI commands (unhandled)
+ AdPlug_LogWrite
+ ("CldsPlayer(): not handling MIDI command 0x%x, "
+ "value = 0x%x\n", comhi);
+ break;
+ default:
+ if (comhi < 0xa0)
+ c->glideto = comhi & 0x1f;
+ else
+ AdPlug_LogWrite
+ ("CldsPlayer(): unknown command 0x%x encountered!"
+ " value = 0x%x\n", comhi, comlo);
+ break;
+ }
+ }
+ else
+ {
+ unsigned char sound;
+ unsigned short high;
+ signed char transp = transpose & 127;
+
+ /*
+ * Originally, in assembler code, the player first shifted
+ * logically left the transpose byte by 1 and then shifted
+ * arithmetically right the same byte to achieve the final,
+ * signed transpose value. Since we can't do arithmetic shifts
+ * in C, we just duplicate the 7th bit into the 8th one and
+ * discard the 8th one completely.
+ */
+
+ if (transpose & 64)
+ transp |= 128;
+
+ if (transpose & 128)
+ {
+ sound = (comlo + transp) & maxsound;
+ high = comhi << 4;
+ }
+ else
+ {
+ sound = comlo & maxsound;
+ high = (comhi + transp) << 4;
+ }
+
+ /*
+ PASCAL:
+ sound = comlo & maxsound;
+ high = (comhi + (((transpose + 0x24) & 0xff) - 0x24)) << 4;
+ */
+
+ if (!chandelay[chan])
+ playsound (sound, chan, high);
+ else
+ {
+ c->chancheat.chandelay = chandelay[chan];
+ c->chancheat.sound = sound;
+ c->chancheat.high = high;
+ }
+ }
+ }
+
+ c->packpos++;
+ }
+ else
+ c->packwait--;
+ }
+
+ tempo_now = tempo;
+ /*
+ The continue table is updated here, but this is only used in the
+ original player, which can be paused in the middle of a song and then
+ unpaused. Since AdPlug does all this for us automatically, we don't
+ have a continue table here. The continue table update code is noted
+ here for reference only.
+
+ if(!pattplay) {
+ conttab[speed & maxcont].position = posplay & 0xff;
+ conttab[speed & maxcont].tempo = tempo;
+ }
+ */
+ pattplay++;
+ if (vbreak)
+ {
+ pattplay = 0;
+ for (i = 0; i < 9; i++)
+ channel[i].packpos = channel[i].packwait = 0;
+ posplay = jumppos;
+ }
+ else if (pattplay >= pattlen)
+ {
+ pattplay = 0;
+ for (i = 0; i < 9; i++)
+ channel[i].packpos = channel[i].packwait = 0;
+ posplay = (posplay + 1) & maxpos;
+ }
+ }
+ else
+ tempo_now--;
+
+ // make effects
+ for (chan = 0; chan < 9; chan++)
+ {
+ c = &channel[chan];
+ regnum = op_table[chan];
+ if (c->keycount > 0)
+ {
+ if (c->keycount == 1)
+ setregs_adv (0xb0 + chan, 0xdf, 0);
+ c->keycount--;
+ }
+
+ // arpeggio
+ if (c->arp_size == 0)
+ arpreg = 0;
+ else
+ {
+ arpreg = c->arp_tab[c->arp_pos] << 4;
+ if (arpreg == 0x800)
+ {
+ if (c->arp_pos > 0)
+ c->arp_tab[0] = c->arp_tab[c->arp_pos - 1];
+ c->arp_size = 1;
+ c->arp_pos = 0;
+ arpreg = c->arp_tab[0] << 4;
+ }
+
+ if (c->arp_count == c->arp_speed)
+ {
+ c->arp_pos++;
+ if (c->arp_pos >= c->arp_size)
+ c->arp_pos = 0;
+ c->arp_count = 0;
+ }
+ else
+ c->arp_count++;
+ }
+
+ // glide & portamento
+ if (c->lasttune && (c->lasttune != c->gototune))
+ {
+ if (c->lasttune > c->gototune)
+ {
+ if (c->lasttune - c->gototune < c->portspeed)
+ c->lasttune = c->gototune;
+ else
+ c->lasttune -= c->portspeed;
+ }
+ else
+ {
+ if (c->gototune - c->lasttune < c->portspeed)
+ c->lasttune = c->gototune;
+ else
+ c->lasttune += c->portspeed;
+ }
+
+ if (arpreg >= 0x800)
+ arpreg = c->lasttune - (arpreg ^ 0xff0) - 16;
+ else
+ arpreg += c->lasttune;
+
+ freq = frequency[arpreg % (12 * 16)];
+ octave = arpreg / (12 * 16) - 1;
+ setregs (0xa0 + chan, freq & 0xff);
+ setregs_adv (0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
+ }
+ else
+ {
+ // vibrato
+ if (!c->vibwait)
+ {
+ if (c->vibrate)
+ {
+ wibc = vibtab[c->vibcount & 0x3f] * c->vibrate;
+
+ if ((c->vibcount & 0x40) == 0)
+ tune = c->lasttune + (wibc >> 8);
+ else
+ tune = c->lasttune - (wibc >> 8);
+
+ if (arpreg >= 0x800)
+ tune = tune - (arpreg ^ 0xff0) - 16;
+ else
+ tune += arpreg;
+
+ freq = frequency[tune % (12 * 16)];
+ octave = tune / (12 * 16) - 1;
+ setregs (0xa0 + chan, freq & 0xff);
+ setregs_adv (0xb0 + chan, 0x20,
+ ((octave << 2) + (freq >> 8)) & 0xdf);
+ c->vibcount += c->vibspeed;
+ }
+ else if (c->arp_size != 0)
+ { // no vibrato, just arpeggio
+ if (arpreg >= 0x800)
+ tune = c->lasttune - (arpreg ^ 0xff0) - 16;
+ else
+ tune = c->lasttune + arpreg;
+
+ freq = frequency[tune % (12 * 16)];
+ octave = tune / (12 * 16) - 1;
+ setregs (0xa0 + chan, freq & 0xff);
+ setregs_adv (0xb0 + chan, 0x20,
+ ((octave << 2) + (freq >> 8)) & 0xdf);
+ }
+ }
+ else
+ { // no vibrato, just arpeggio
+ c->vibwait--;
+
+ if (c->arp_size != 0)
+ {
+ if (arpreg >= 0x800)
+ tune = c->lasttune - (arpreg ^ 0xff0) - 16;
+ else
+ tune = c->lasttune + arpreg;
+
+ freq = frequency[tune % (12 * 16)];
+ octave = tune / (12 * 16) - 1;
+ setregs (0xa0 + chan, freq & 0xff);
+ setregs_adv (0xb0 + chan, 0x20,
+ ((octave << 2) + (freq >> 8)) & 0xdf);
+ }
+ }
+ }
+
+ // tremolo (modulator)
+ if (!c->trmwait)
+ {
+ if (c->trmrate)
+ {
+ tremc = tremtab[c->trmcount & 0x7f] * c->trmrate;
+ if ((tremc >> 8) <= (c->volmod & 0x3f))
+ level = (c->volmod & 0x3f) - (tremc >> 8);
+ else
+ level = 0;
+
+ if (allvolume != 0 && (fmchip[0xc0 + chan] & 1))
+ setregs_adv (0x40 + regnum, 0xc0,
+ ((level * allvolume) >> 8) ^ 0x3f);
+ else
+ setregs_adv (0x40 + regnum, 0xc0, level ^ 0x3f);
+
+ c->trmcount += c->trmspeed;
+ }
+ else if (allvolume != 0 && (fmchip[0xc0 + chan] & 1))
+ setregs_adv (0x40 + regnum, 0xc0,
+ ((((c->volmod & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
+ else
+ setregs_adv (0x40 + regnum, 0xc0, (c->volmod ^ 0x3f) & 0x3f);
+ }
+ else
+ {
+ c->trmwait--;
+ if (allvolume != 0 && (fmchip[0xc0 + chan] & 1))
+ setregs_adv (0x40 + regnum, 0xc0,
+ ((((c->volmod & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
+ }
+
+ // tremolo (carrier)
+ if (!c->trcwait)
+ {
+ if (c->trcrate)
+ {
+ tremc = tremtab[c->trccount & 0x7f] * c->trcrate;
+ if ((tremc >> 8) <= (c->volcar & 0x3f))
+ level = (c->volcar & 0x3f) - (tremc >> 8);
+ else
+ level = 0;
+
+ if (allvolume != 0)
+ setregs_adv (0x43 + regnum, 0xc0,
+ ((level * allvolume) >> 8) ^ 0x3f);
+ else
+ setregs_adv (0x43 + regnum, 0xc0, level ^ 0x3f);
+ c->trccount += c->trcspeed;
+ }
+ else if (allvolume != 0)
+ setregs_adv (0x43 + regnum, 0xc0,
+ ((((c->volcar & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
+ else
+ setregs_adv (0x43 + regnum, 0xc0, (c->volcar ^ 0x3f) & 0x3f);
+ }
+ else
+ {
+ c->trcwait--;
+ if (allvolume != 0)
+ setregs_adv (0x43 + regnum, 0xc0,
+ ((((c->volcar & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
+ }
+ }
+
+ return (!playing || songlooped) ? false : true;
+}
+
+void
+CldsPlayer::rewind (int subsong)
+{
+ int i;
+
+ // init all with 0
+ tempo_now = 3;
+ playing = true;
+ songlooped = false;
+ jumping = fadeonoff = allvolume = hardfade = pattplay = posplay = jumppos =
+ mainvolume = 0;
+ memset (channel, 0, sizeof (channel));
+ memset (fmchip, 0, sizeof (fmchip));
+
+ // OPL2 init
+ opl->init (); // Reset OPL chip
+ opl->write (1, 0x20);
+ opl->write (8, 0);
+ opl->write (0xbd, regbd);
+
+ for (i = 0; i < 9; i++)
+ {
+ opl->write (0x20 + op_table[i], 0);
+ opl->write (0x23 + op_table[i], 0);
+ opl->write (0x40 + op_table[i], 0x3f);
+ opl->write (0x43 + op_table[i], 0x3f);
+ opl->write (0x60 + op_table[i], 0xff);
+ opl->write (0x63 + op_table[i], 0xff);
+ opl->write (0x80 + op_table[i], 0xff);
+ opl->write (0x83 + op_table[i], 0xff);
+ opl->write (0xe0 + op_table[i], 0);
+ opl->write (0xe3 + op_table[i], 0);
+ opl->write (0xa0 + i, 0);
+ opl->write (0xb0 + i, 0);
+ opl->write (0xc0 + i, 0);
+ }
+}
+
+/*** private methods *************************************/
+
+void
+CldsPlayer::playsound (int inst_number, int channel_number, int tunehigh)
+{
+ if ((unsigned int)inst_number > numpatch-1) {
+ return;
+ }
+ Channel *c = &channel[channel_number]; // current channel
+ SoundBank *i = &soundbank[inst_number]; // current instrument
+ unsigned int regnum = op_table[channel_number]; // channel's OPL2 register
+ unsigned char volcalc, octave;
+ unsigned short freq;
+
+ // set fine tune
+ tunehigh += ((i->finetune + c->finetune + 0x80) & 0xff) - 0x80;
+
+ // arpeggio handling
+ if (!i->arpeggio)
+ {
+ unsigned short arpcalc = i->arp_tab[0] << 4;
+
+ if (arpcalc > 0x800)
+ tunehigh = tunehigh - (arpcalc ^ 0xff0) - 16;
+ else
+ tunehigh += arpcalc;
+ }
+
+ // glide handling
+ if (c->glideto != 0)
+ {
+ c->gototune = tunehigh;
+ c->portspeed = c->glideto;
+ c->glideto = c->finetune = 0;
+ return;
+ }
+
+ // set modulator registers
+ setregs (0x20 + regnum, i->mod_misc);
+ volcalc = i->mod_vol;
+ if (!c->nextvol || !(i->feedback & 1))
+ c->volmod = volcalc;
+ else
+ c->volmod = (volcalc & 0xc0) | ((((volcalc & 0x3f) * c->nextvol) >> 6));
+
+ if ((i->feedback & 1) == 1 && allvolume != 0)
+ setregs (0x40 + regnum,
+ ((c->
+ volmod & 0xc0) | (((c->volmod & 0x3f) *
+ allvolume) >> 8)) ^ 0x3f);
+ else
+ setregs (0x40 + regnum, c->volmod ^ 0x3f);
+ setregs (0x60 + regnum, i->mod_ad);
+ setregs (0x80 + regnum, i->mod_sr);
+ setregs (0xe0 + regnum, i->mod_wave);
+
+ // Set carrier registers
+ setregs (0x23 + regnum, i->car_misc);
+ volcalc = i->car_vol;
+ if (!c->nextvol)
+ c->volcar = volcalc;
+ else
+ c->volcar = (volcalc & 0xc0) | ((((volcalc & 0x3f) * c->nextvol) >> 6));
+
+ if (allvolume)
+ setregs (0x43 + regnum,
+ ((c->
+ volcar & 0xc0) | (((c->volcar & 0x3f) *
+ allvolume) >> 8)) ^ 0x3f);
+ else
+ setregs (0x43 + regnum, c->volcar ^ 0x3f);
+ setregs (0x63 + regnum, i->car_ad);
+ setregs (0x83 + regnum, i->car_sr);
+ setregs (0xe3 + regnum, i->car_wave);
+ setregs (0xc0 + channel_number, i->feedback);
+ setregs_adv (0xb0 + channel_number, 0xdf, 0); // key off
+
+ freq = frequency[tunehigh % (12 * 16)];
+ octave = tunehigh / (12 * 16) - 1;
+ if (!i->glide)
+ {
+ if (!i->portamento || !c->lasttune)
+ {
+ setregs (0xa0 + channel_number, freq & 0xff);
+ setregs (0xb0 + channel_number, (octave << 2) + 0x20 + (freq >> 8));
+ c->lasttune = c->gototune = tunehigh;
+ }
+ else
+ {
+ c->gototune = tunehigh;
+ c->portspeed = i->portamento;
+ setregs_adv (0xb0 + channel_number, 0xdf, 0x20); // key on
+ }
+ }
+ else
+ {
+ setregs (0xa0 + channel_number, freq & 0xff);
+ setregs (0xb0 + channel_number, (octave << 2) + 0x20 + (freq >> 8));
+ c->lasttune = tunehigh;
+ c->gototune = tunehigh + ((i->glide + 0x80) & 0xff) - 0x80; // set destination
+ c->portspeed = i->portamento;
+ }
+
+ if (!i->vibrato)
+ c->vibwait = c->vibspeed = c->vibrate = 0;
+ else
+ {
+ c->vibwait = i->vibdelay;
+ // PASCAL: c->vibspeed = ((i->vibrato >> 4) & 15) + 1;
+ c->vibspeed = (i->vibrato >> 4) + 2;
+ c->vibrate = (i->vibrato & 15) + 1;
+ }
+
+ if (!(c->trmstay & 0xf0))
+ {
+ c->trmwait = (i->tremwait & 0xf0) >> 3;
+ // PASCAL: c->trmspeed = (i->mod_trem >> 4) & 15;
+ c->trmspeed = i->mod_trem >> 4;
+ c->trmrate = i->mod_trem & 15;
+ c->trmcount = 0;
+ }
+
+ if (!(c->trmstay & 0x0f))
+ {
+ c->trcwait = (i->tremwait & 15) << 1;
+ // PASCAL: c->trcspeed = (i->car_trem >> 4) & 15;
+ c->trcspeed = i->car_trem >> 4;
+ c->trcrate = i->car_trem & 15;
+ c->trccount = 0;
+ }
+
+ c->arp_size = i->arpeggio & 15;
+ c->arp_speed = i->arpeggio >> 4;
+ memcpy (c->arp_tab, i->arp_tab, 12);
+ c->keycount = i->keyoff;
+ c->nextvol = c->glideto = c->finetune = c->vibcount = c->arp_pos =
+ c->arp_count = 0;
+}
+
+inline void
+CldsPlayer::setregs (unsigned char reg, unsigned char val)
+{
+ if (fmchip[reg] == val)
+ return;
+
+ fmchip[reg] = val;
+ opl->write (reg, val);
+}
+
+inline void
+CldsPlayer::setregs_adv (unsigned char reg, unsigned char mask,
+ unsigned char val)
+{
+ setregs (reg, (fmchip[reg] & mask) | val);
+}
diff --git a/src/adplug/core/lds.cxx b/src/adplug/core/lds.cxx
deleted file mode 100644
index 1580c51e986f..000000000000
--- a/src/adplug/core/lds.cxx
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * lds.cpp - LOUDNESS Player by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <string.h>
-
-#include "lds.h"
-#include "debug.h"
-
-// Note frequency table (16 notes / octave)
-const unsigned short
- CldsPlayer::frequency[] = {
- 343, 344, 345, 347, 348, 349, 350, 352, 353, 354, 356, 357, 358,
- 359, 361, 362, 363, 365, 366, 367, 369, 370, 371, 373, 374, 375,
- 377, 378, 379, 381, 382, 384, 385, 386, 388, 389, 391, 392, 393,
- 395, 396, 398, 399, 401, 402, 403, 405, 406, 408, 409, 411, 412,
- 414, 415, 417, 418, 420, 421, 423, 424, 426, 427, 429, 430, 432,
- 434, 435, 437, 438, 440, 442, 443, 445, 446, 448, 450, 451, 453,
- 454, 456, 458, 459, 461, 463, 464, 466, 468, 469, 471, 473, 475,
- 476, 478, 480, 481, 483, 485, 487, 488, 490, 492, 494, 496, 497,
- 499, 501, 503, 505, 506, 508, 510, 512, 514, 516, 518, 519, 521,
- 523, 525, 527, 529, 531, 533, 535, 537, 538, 540, 542, 544, 546,
- 548, 550, 552, 554, 556, 558, 560, 562, 564, 566, 568, 571, 573,
- 575, 577, 579, 581, 583, 585, 587, 589, 591, 594, 596, 598, 600,
- 602, 604, 607, 609, 611, 613, 615, 618, 620, 622, 624, 627, 629,
- 631, 633, 636, 638, 640, 643, 645, 647, 650, 652, 654, 657, 659,
- 662, 664, 666, 669, 671, 674, 676, 678, 681, 683
-};
-
-// Vibrato (sine) table
-const unsigned char
- CldsPlayer::vibtab[] = {
- 0, 13, 25, 37, 50, 62, 74, 86, 98, 109, 120, 131, 142, 152, 162,
- 171, 180, 189, 197, 205, 212, 219, 225, 231, 236, 240, 244, 247,
- 250, 252, 254, 255, 255, 255, 254, 252, 250, 247, 244, 240, 236,
- 231, 225, 219, 212, 205, 197, 189, 180, 171, 162, 152, 142, 131,
- 120, 109, 98, 86, 74, 62, 50, 37, 25, 13
-};
-
-// Tremolo (sine * sine) table
-const unsigned char
- CldsPlayer::tremtab[] = {
- 0, 0, 1, 1, 2, 4, 5, 7, 10, 12, 15, 18, 21, 25, 29, 33, 37, 42, 47,
- 52, 57, 62, 67, 73, 79, 85, 90, 97, 103, 109, 115, 121, 128, 134,
- 140, 146, 152, 158, 165, 170, 176, 182, 188, 193, 198, 203, 208,
- 213, 218, 222, 226, 230, 234, 237, 240, 243, 245, 248, 250, 251,
- 253, 254, 254, 255, 255, 255, 254, 254, 253, 251, 250, 248, 245,
- 243, 240, 237, 234, 230, 226, 222, 218, 213, 208, 203, 198, 193,
- 188, 182, 176, 170, 165, 158, 152, 146, 140, 134, 127, 121, 115,
- 109, 103, 97, 90, 85, 79, 73, 67, 62, 57, 52, 47, 42, 37, 33, 29,
- 25, 21, 18, 15, 12, 10, 7, 5, 4, 2, 1, 1, 0
-};
-
-// 'maxsound' is maximum number of patches (instruments)
-// 'maxpos' is maximum number of entries in position list (orderlist)
-const unsigned short
- CldsPlayer::maxsound = 0x3f, CldsPlayer::maxpos = 0xff;
-
-/*** public methods *************************************/
-
-CldsPlayer::CldsPlayer (Copl * newopl):CPlayer (newopl), soundbank (0), positions (0),
-patterns (0)
-{
-}
-
-CldsPlayer::~CldsPlayer ()
-{
- if (soundbank)
- delete[]soundbank;
- if (positions)
- delete[]positions;
- if (patterns)
- delete[]patterns;
-}
-
-bool
-CldsPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f;
- unsigned int i, j;
- SoundBank *sb;
- std::string filename (vfs_get_filename (fd));
-
- // file validation section (actually just an extension check)
- f = fp.open (fd);
- if (!f)
- return false;
- if (!fp.extension (filename, ".lds"))
- return false;
-
- // file load section (header)
- mode = f->readInt (1);
- if (mode > 2)
- {
- fp.close (f);
- return false;
- }
- speed = f->readInt (2);
- tempo = f->readInt (1);
- pattlen = f->readInt (1);
- for (i = 0; i < 9; i++)
- chandelay[i] = f->readInt (1);
- regbd = f->readInt (1);
-
- // load patches
- numpatch = f->readInt (2);
- soundbank = new SoundBank[numpatch];
- for (i = 0; i < numpatch; i++)
- {
- sb = &soundbank[i];
- sb->mod_misc = f->readInt (1);
- sb->mod_vol = f->readInt (1);
- sb->mod_ad = f->readInt (1);
- sb->mod_sr = f->readInt (1);
- sb->mod_wave = f->readInt (1);
- sb->car_misc = f->readInt (1);
- sb->car_vol = f->readInt (1);
- sb->car_ad = f->readInt (1);
- sb->car_sr = f->readInt (1);
- sb->car_wave = f->readInt (1);
- sb->feedback = f->readInt (1);
- sb->keyoff = f->readInt (1);
- sb->portamento = f->readInt (1);
- sb->glide = f->readInt (1);
- sb->finetune = f->readInt (1);
- sb->vibrato = f->readInt (1);
- sb->vibdelay = f->readInt (1);
- sb->mod_trem = f->readInt (1);
- sb->car_trem = f->readInt (1);
- sb->tremwait = f->readInt (1);
- sb->arpeggio = f->readInt (1);
- for (j = 0; j < 12; j++)
- sb->arp_tab[j] = f->readInt (1);
- sb->start = f->readInt (2);
- sb->size = f->readInt (2);
- sb->fms = f->readInt (1);
- sb->transp = f->readInt (2);
- sb->midinst = f->readInt (1);
- sb->midvelo = f->readInt (1);
- sb->midkey = f->readInt (1);
- sb->midtrans = f->readInt (1);
- sb->middum1 = f->readInt (1);
- sb->middum2 = f->readInt (1);
- }
-
- // load positions
- numposi = f->readInt (2);
- positions = new Position[9 * numposi];
- for (i = 0; i < numposi; i++)
- for (j = 0; j < 9; j++)
- {
- /*
- * patnum is a pointer inside the pattern space, but patterns are 16bit
- * word fields anyway, so it ought to be an even number (hopefully) and
- * we can just divide it by 2 to get our array index of 16bit words.
- */
- positions[i * 9 + j].patnum = f->readInt (2) / 2;
- positions[i * 9 + j].transpose = f->readInt (1);
- }
-
- AdPlug_LogWrite
- ("CldsPlayer::load(\"%s\",fp): loading LOUDNESS file: mode = "
- "%d, pattlen = %d, numpatch = %d, numposi = %d\n", filename.c_str (),
- mode, pattlen, numpatch, numposi);
-
- // load patterns
- f->ignore (2); // ignore # of digital sounds (not played by this player)
- patterns = new unsigned short[(fp.filesize (f) - f->pos ()) / 2 + 1];
- for (i = 0; !f->eof (); i++)
- patterns[i] = f->readInt (2);
-
- fp.close (f);
- rewind (0);
- return true;
-}
-
-bool
-CldsPlayer::update ()
-{
- unsigned short comword, freq, octave, chan, tune, wibc, tremc, arpreg;
- bool vbreak;
- unsigned char level, regnum, comhi, comlo;
- int i;
- Channel *c;
-
- if (!playing)
- return false;
-
- // handle fading
- if (fadeonoff)
- {
- if (fadeonoff <= 128)
- {
- if (allvolume > fadeonoff || allvolume == 0)
- allvolume -= fadeonoff;
- else
- {
- allvolume = 1;
- fadeonoff = 0;
- if (hardfade != 0)
- {
- playing = false;
- hardfade = 0;
- for (i = 0; i < 9; i++)
- channel[i].keycount = 1;
- }
- }
- }
- else
- if ((unsigned int) ((allvolume + (0x100 - fadeonoff)) & 0xff) <=
- mainvolume)
- allvolume += 0x100 - fadeonoff;
- else
- {
- allvolume = mainvolume;
- fadeonoff = 0;
- }
- }
-
- // handle channel delay
- for (chan = 0; chan < 9; chan++)
- {
- c = &channel[chan];
- if (c->chancheat.chandelay)
- if (!(--c->chancheat.chandelay))
- playsound (c->chancheat.sound, chan, c->chancheat.high);
- }
-
- // handle notes
- if (!tempo_now)
- {
- vbreak = false;
- for (chan = 0; chan < 9; chan++)
- {
- c = &channel[chan];
- if (!c->packwait)
- {
- unsigned short patnum = positions[posplay * 9 + chan].patnum;
- unsigned char transpose = positions[posplay * 9 + chan].transpose;
-
- comword = patterns[patnum + c->packpos];
- comhi = comword >> 8;
- comlo = comword & 0xff;
- if (comword)
- {
- if (comhi == 0x80)
- {
- c->packwait = comlo;
- }
- else if (comhi >= 0x80)
- {
- switch (comhi)
- {
- case 0xff:
- c->volcar = (((c->volcar & 0x3f) * comlo) >> 6) & 0x3f;
- if (fmchip[0xc0 + chan] & 1)
- c->volmod = (((c->volmod & 0x3f) * comlo) >> 6) & 0x3f;
- break;
- case 0xfe:
- tempo = comword & 0x3f;
- break;
- case 0xfd:
- c->nextvol = comlo;
- break;
- case 0xfc:
- playing = false;
- // in real player there's also full keyoff here, but we don't need it
- break;
- case 0xfb:
- c->keycount = 1;
- break;
- case 0xfa:
- vbreak = true;
- jumppos = (posplay + 1) & maxpos;
- break;
- case 0xf9:
- vbreak = true;
- jumppos = comlo & maxpos;
- jumping = 1;
- if (jumppos < posplay)
- songlooped = true;
- break;
- case 0xf8:
- c->lasttune = 0;
- break;
- case 0xf7:
- c->vibwait = 0;
- // PASCAL: c->vibspeed = ((comlo >> 4) & 15) + 2;
- c->vibspeed = (comlo >> 4) + 2;
- c->vibrate = (comlo & 15) + 1;
- break;
- case 0xf6:
- c->glideto = comlo;
- break;
- case 0xf5:
- c->finetune = comlo;
- break;
- case 0xf4:
- if (!hardfade)
- {
- allvolume = mainvolume = comlo;
- fadeonoff = 0;
- }
- break;
- case 0xf3:
- if (!hardfade)
- fadeonoff = comlo;
- break;
- case 0xf2:
- c->trmstay = comlo;
- break;
- case 0xf1: // panorama
- case 0xf0: // progch
- // MIDI commands (unhandled)
- AdPlug_LogWrite
- ("CldsPlayer(): not handling MIDI command 0x%x, "
- "value = 0x%x\n", comhi);
- break;
- default:
- if (comhi < 0xa0)
- c->glideto = comhi & 0x1f;
- else
- AdPlug_LogWrite
- ("CldsPlayer(): unknown command 0x%x encountered!"
- " value = 0x%x\n", comhi, comlo);
- break;
- }
- }
- else
- {
- unsigned char sound;
- unsigned short high;
- signed char transp = transpose & 127;
-
- /*
- * Originally, in assembler code, the player first shifted
- * logically left the transpose byte by 1 and then shifted
- * arithmetically right the same byte to achieve the final,
- * signed transpose value. Since we can't do arithmetic shifts
- * in C, we just duplicate the 7th bit into the 8th one and
- * discard the 8th one completely.
- */
-
- if (transpose & 64)
- transp |= 128;
-
- if (transpose & 128)
- {
- sound = (comlo + transp) & maxsound;
- high = comhi << 4;
- }
- else
- {
- sound = comlo & maxsound;
- high = (comhi + transp) << 4;
- }
-
- /*
- PASCAL:
- sound = comlo & maxsound;
- high = (comhi + (((transpose + 0x24) & 0xff) - 0x24)) << 4;
- */
-
- if (!chandelay[chan])
- playsound (sound, chan, high);
- else
- {
- c->chancheat.chandelay = chandelay[chan];
- c->chancheat.sound = sound;
- c->chancheat.high = high;
- }
- }
- }
-
- c->packpos++;
- }
- else
- c->packwait--;
- }
-
- tempo_now = tempo;
- /*
- The continue table is updated here, but this is only used in the
- original player, which can be paused in the middle of a song and then
- unpaused. Since AdPlug does all this for us automatically, we don't
- have a continue table here. The continue table update code is noted
- here for reference only.
-
- if(!pattplay) {
- conttab[speed & maxcont].position = posplay & 0xff;
- conttab[speed & maxcont].tempo = tempo;
- }
- */
- pattplay++;
- if (vbreak)
- {
- pattplay = 0;
- for (i = 0; i < 9; i++)
- channel[i].packpos = channel[i].packwait = 0;
- posplay = jumppos;
- }
- else if (pattplay >= pattlen)
- {
- pattplay = 0;
- for (i = 0; i < 9; i++)
- channel[i].packpos = channel[i].packwait = 0;
- posplay = (posplay + 1) & maxpos;
- }
- }
- else
- tempo_now--;
-
- // make effects
- for (chan = 0; chan < 9; chan++)
- {
- c = &channel[chan];
- regnum = op_table[chan];
- if (c->keycount > 0)
- {
- if (c->keycount == 1)
- setregs_adv (0xb0 + chan, 0xdf, 0);
- c->keycount--;
- }
-
- // arpeggio
- if (c->arp_size == 0)
- arpreg = 0;
- else
- {
- arpreg = c->arp_tab[c->arp_pos] << 4;
- if (arpreg == 0x800)
- {
- if (c->arp_pos > 0)
- c->arp_tab[0] = c->arp_tab[c->arp_pos - 1];
- c->arp_size = 1;
- c->arp_pos = 0;
- arpreg = c->arp_tab[0] << 4;
- }
-
- if (c->arp_count == c->arp_speed)
- {
- c->arp_pos++;
- if (c->arp_pos >= c->arp_size)
- c->arp_pos = 0;
- c->arp_count = 0;
- }
- else
- c->arp_count++;
- }
-
- // glide & portamento
- if (c->lasttune && (c->lasttune != c->gototune))
- {
- if (c->lasttune > c->gototune)
- {
- if (c->lasttune - c->gototune < c->portspeed)
- c->lasttune = c->gototune;
- else
- c->lasttune -= c->portspeed;
- }
- else
- {
- if (c->gototune - c->lasttune < c->portspeed)
- c->lasttune = c->gototune;
- else
- c->lasttune += c->portspeed;
- }
-
- if (arpreg >= 0x800)
- arpreg = c->lasttune - (arpreg ^ 0xff0) - 16;
- else
- arpreg += c->lasttune;
-
- freq = frequency[arpreg % (12 * 16)];
- octave = arpreg / (12 * 16) - 1;
- setregs (0xa0 + chan, freq & 0xff);
- setregs_adv (0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
- }
- else
- {
- // vibrato
- if (!c->vibwait)
- {
- if (c->vibrate)
- {
- wibc = vibtab[c->vibcount & 0x3f] * c->vibrate;
-
- if ((c->vibcount & 0x40) == 0)
- tune = c->lasttune + (wibc >> 8);
- else
- tune = c->lasttune - (wibc >> 8);
-
- if (arpreg >= 0x800)
- tune = tune - (arpreg ^ 0xff0) - 16;
- else
- tune += arpreg;
-
- freq = frequency[tune % (12 * 16)];
- octave = tune / (12 * 16) - 1;
- setregs (0xa0 + chan, freq & 0xff);
- setregs_adv (0xb0 + chan, 0x20,
- ((octave << 2) + (freq >> 8)) & 0xdf);
- c->vibcount += c->vibspeed;
- }
- else if (c->arp_size != 0)
- { // no vibrato, just arpeggio
- if (arpreg >= 0x800)
- tune = c->lasttune - (arpreg ^ 0xff0) - 16;
- else
- tune = c->lasttune + arpreg;
-
- freq = frequency[tune % (12 * 16)];
- octave = tune / (12 * 16) - 1;
- setregs (0xa0 + chan, freq & 0xff);
- setregs_adv (0xb0 + chan, 0x20,
- ((octave << 2) + (freq >> 8)) & 0xdf);
- }
- }
- else
- { // no vibrato, just arpeggio
- c->vibwait--;
-
- if (c->arp_size != 0)
- {
- if (arpreg >= 0x800)
- tune = c->lasttune - (arpreg ^ 0xff0) - 16;
- else
- tune = c->lasttune + arpreg;
-
- freq = frequency[tune % (12 * 16)];
- octave = tune / (12 * 16) - 1;
- setregs (0xa0 + chan, freq & 0xff);
- setregs_adv (0xb0 + chan, 0x20,
- ((octave << 2) + (freq >> 8)) & 0xdf);
- }
- }
- }
-
- // tremolo (modulator)
- if (!c->trmwait)
- {
- if (c->trmrate)
- {
- tremc = tremtab[c->trmcount & 0x7f] * c->trmrate;
- if ((tremc >> 8) <= (c->volmod & 0x3f))
- level = (c->volmod & 0x3f) - (tremc >> 8);
- else
- level = 0;
-
- if (allvolume != 0 && (fmchip[0xc0 + chan] & 1))
- setregs_adv (0x40 + regnum, 0xc0,
- ((level * allvolume) >> 8) ^ 0x3f);
- else
- setregs_adv (0x40 + regnum, 0xc0, level ^ 0x3f);
-
- c->trmcount += c->trmspeed;
- }
- else if (allvolume != 0 && (fmchip[0xc0 + chan] & 1))
- setregs_adv (0x40 + regnum, 0xc0,
- ((((c->volmod & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
- else
- setregs_adv (0x40 + regnum, 0xc0, (c->volmod ^ 0x3f) & 0x3f);
- }
- else
- {
- c->trmwait--;
- if (allvolume != 0 && (fmchip[0xc0 + chan] & 1))
- setregs_adv (0x40 + regnum, 0xc0,
- ((((c->volmod & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
- }
-
- // tremolo (carrier)
- if (!c->trcwait)
- {
- if (c->trcrate)
- {
- tremc = tremtab[c->trccount & 0x7f] * c->trcrate;
- if ((tremc >> 8) <= (c->volcar & 0x3f))
- level = (c->volcar & 0x3f) - (tremc >> 8);
- else
- level = 0;
-
- if (allvolume != 0)
- setregs_adv (0x43 + regnum, 0xc0,
- ((level * allvolume) >> 8) ^ 0x3f);
- else
- setregs_adv (0x43 + regnum, 0xc0, level ^ 0x3f);
- c->trccount += c->trcspeed;
- }
- else if (allvolume != 0)
- setregs_adv (0x43 + regnum, 0xc0,
- ((((c->volcar & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
- else
- setregs_adv (0x43 + regnum, 0xc0, (c->volcar ^ 0x3f) & 0x3f);
- }
- else
- {
- c->trcwait--;
- if (allvolume != 0)
- setregs_adv (0x43 + regnum, 0xc0,
- ((((c->volcar & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
- }
- }
-
- return (!playing || songlooped) ? false : true;
-}
-
-void
-CldsPlayer::rewind (int subsong)
-{
- int i;
-
- // init all with 0
- tempo_now = 3;
- playing = true;
- songlooped = false;
- jumping = fadeonoff = allvolume = hardfade = pattplay = posplay = jumppos =
- mainvolume = 0;
- memset (channel, 0, sizeof (channel));
- memset (fmchip, 0, sizeof (fmchip));
-
- // OPL2 init
- opl->init (); // Reset OPL chip
- opl->write (1, 0x20);
- opl->write (8, 0);
- opl->write (0xbd, regbd);
-
- for (i = 0; i < 9; i++)
- {
- opl->write (0x20 + op_table[i], 0);
- opl->write (0x23 + op_table[i], 0);
- opl->write (0x40 + op_table[i], 0x3f);
- opl->write (0x43 + op_table[i], 0x3f);
- opl->write (0x60 + op_table[i], 0xff);
- opl->write (0x63 + op_table[i], 0xff);
- opl->write (0x80 + op_table[i], 0xff);
- opl->write (0x83 + op_table[i], 0xff);
- opl->write (0xe0 + op_table[i], 0);
- opl->write (0xe3 + op_table[i], 0);
- opl->write (0xa0 + i, 0);
- opl->write (0xb0 + i, 0);
- opl->write (0xc0 + i, 0);
- }
-}
-
-/*** private methods *************************************/
-
-void
-CldsPlayer::playsound (int inst_number, int channel_number, int tunehigh)
-{
- if ((unsigned int)inst_number > numpatch-1) {
- return;
- }
- Channel *c = &channel[channel_number]; // current channel
- SoundBank *i = &soundbank[inst_number]; // current instrument
- unsigned int regnum = op_table[channel_number]; // channel's OPL2 register
- unsigned char volcalc, octave;
- unsigned short freq;
-
- // set fine tune
- tunehigh += ((i->finetune + c->finetune + 0x80) & 0xff) - 0x80;
-
- // arpeggio handling
- if (!i->arpeggio)
- {
- unsigned short arpcalc = i->arp_tab[0] << 4;
-
- if (arpcalc > 0x800)
- tunehigh = tunehigh - (arpcalc ^ 0xff0) - 16;
- else
- tunehigh += arpcalc;
- }
-
- // glide handling
- if (c->glideto != 0)
- {
- c->gototune = tunehigh;
- c->portspeed = c->glideto;
- c->glideto = c->finetune = 0;
- return;
- }
-
- // set modulator registers
- setregs (0x20 + regnum, i->mod_misc);
- volcalc = i->mod_vol;
- if (!c->nextvol || !(i->feedback & 1))
- c->volmod = volcalc;
- else
- c->volmod = (volcalc & 0xc0) | ((((volcalc & 0x3f) * c->nextvol) >> 6));
-
- if ((i->feedback & 1) == 1 && allvolume != 0)
- setregs (0x40 + regnum,
- ((c->
- volmod & 0xc0) | (((c->volmod & 0x3f) *
- allvolume) >> 8)) ^ 0x3f);
- else
- setregs (0x40 + regnum, c->volmod ^ 0x3f);
- setregs (0x60 + regnum, i->mod_ad);
- setregs (0x80 + regnum, i->mod_sr);
- setregs (0xe0 + regnum, i->mod_wave);
-
- // Set carrier registers
- setregs (0x23 + regnum, i->car_misc);
- volcalc = i->car_vol;
- if (!c->nextvol)
- c->volcar = volcalc;
- else
- c->volcar = (volcalc & 0xc0) | ((((volcalc & 0x3f) * c->nextvol) >> 6));
-
- if (allvolume)
- setregs (0x43 + regnum,
- ((c->
- volcar & 0xc0) | (((c->volcar & 0x3f) *
- allvolume) >> 8)) ^ 0x3f);
- else
- setregs (0x43 + regnum, c->volcar ^ 0x3f);
- setregs (0x63 + regnum, i->car_ad);
- setregs (0x83 + regnum, i->car_sr);
- setregs (0xe3 + regnum, i->car_wave);
- setregs (0xc0 + channel_number, i->feedback);
- setregs_adv (0xb0 + channel_number, 0xdf, 0); // key off
-
- freq = frequency[tunehigh % (12 * 16)];
- octave = tunehigh / (12 * 16) - 1;
- if (!i->glide)
- {
- if (!i->portamento || !c->lasttune)
- {
- setregs (0xa0 + channel_number, freq & 0xff);
- setregs (0xb0 + channel_number, (octave << 2) + 0x20 + (freq >> 8));
- c->lasttune = c->gototune = tunehigh;
- }
- else
- {
- c->gototune = tunehigh;
- c->portspeed = i->portamento;
- setregs_adv (0xb0 + channel_number, 0xdf, 0x20); // key on
- }
- }
- else
- {
- setregs (0xa0 + channel_number, freq & 0xff);
- setregs (0xb0 + channel_number, (octave << 2) + 0x20 + (freq >> 8));
- c->lasttune = tunehigh;
- c->gototune = tunehigh + ((i->glide + 0x80) & 0xff) - 0x80; // set destination
- c->portspeed = i->portamento;
- }
-
- if (!i->vibrato)
- c->vibwait = c->vibspeed = c->vibrate = 0;
- else
- {
- c->vibwait = i->vibdelay;
- // PASCAL: c->vibspeed = ((i->vibrato >> 4) & 15) + 1;
- c->vibspeed = (i->vibrato >> 4) + 2;
- c->vibrate = (i->vibrato & 15) + 1;
- }
-
- if (!(c->trmstay & 0xf0))
- {
- c->trmwait = (i->tremwait & 0xf0) >> 3;
- // PASCAL: c->trmspeed = (i->mod_trem >> 4) & 15;
- c->trmspeed = i->mod_trem >> 4;
- c->trmrate = i->mod_trem & 15;
- c->trmcount = 0;
- }
-
- if (!(c->trmstay & 0x0f))
- {
- c->trcwait = (i->tremwait & 15) << 1;
- // PASCAL: c->trcspeed = (i->car_trem >> 4) & 15;
- c->trcspeed = i->car_trem >> 4;
- c->trcrate = i->car_trem & 15;
- c->trccount = 0;
- }
-
- c->arp_size = i->arpeggio & 15;
- c->arp_speed = i->arpeggio >> 4;
- memcpy (c->arp_tab, i->arp_tab, 12);
- c->keycount = i->keyoff;
- c->nextvol = c->glideto = c->finetune = c->vibcount = c->arp_pos =
- c->arp_count = 0;
-}
-
-inline void
-CldsPlayer::setregs (unsigned char reg, unsigned char val)
-{
- if (fmchip[reg] == val)
- return;
-
- fmchip[reg] = val;
- opl->write (reg, val);
-}
-
-inline void
-CldsPlayer::setregs_adv (unsigned char reg, unsigned char mask,
- unsigned char val)
-{
- setregs (reg, (fmchip[reg] & mask) | val);
-}
diff --git a/src/adplug/core/lds.h b/src/adplug/core/lds.h
index aac36e3a30d1..5e421298b62d 100644
--- a/src/adplug/core/lds.h
+++ b/src/adplug/core/lds.h
@@ -1,17 +1,17 @@
/*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
+ *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -29,7 +29,7 @@ class CldsPlayer: public CPlayer
CldsPlayer(Copl *newopl);
virtual ~CldsPlayer();
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
virtual bool update();
virtual void rewind(int subsong = -1);
float getrefresh() { return 70.0f; }
@@ -82,7 +82,7 @@ class CldsPlayer: public CPlayer
tempo_now, pattplay, tempo, regbd, chandelay[9], mode, pattlen;
unsigned short posplay, jumppos, *patterns, speed;
bool playing, songlooped;
- unsigned int numpatch, numposi, patterns_size, mainvolume;
+ unsigned int numpatch, numposi, mainvolume;
void playsound(int inst_number, int channel_number, int tunehigh);
inline void setregs(unsigned char reg, unsigned char val);
diff --git a/src/adplug/core/mad.cc b/src/adplug/core/mad.cc
new file mode 100644
index 000000000000..f87b3b469e46
--- /dev/null
+++ b/src/adplug/core/mad.cc
@@ -0,0 +1,146 @@
+/*
+ Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ mad.cpp - MAD loader by Riven the Mage <riven at ok.ru>
+*/
+
+#include <string.h>
+
+#include "mad.h"
+
+/* -------- Public Methods -------------------------------- */
+
+CPlayer *
+CmadLoader::factory (Copl * newopl)
+{
+ return new CmadLoader (newopl);
+}
+
+bool
+CmadLoader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ const unsigned char conv_inst[10] = { 2, 1, 10, 9, 4, 3, 6, 5, 8, 7 };
+ unsigned int i, j, k, t = 0;
+
+ // 'MAD+' - signed ?
+ char id[4];
+ f->readString (id, 4);
+ if (strncmp (id, "MAD+", 4))
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // load instruments
+ for (i = 0; i < 9; i++)
+ {
+ f->readString (instruments[i].name, 8);
+ for (j = 0; j < 12; j++)
+ instruments[i].data[j] = f->readInt (1);
+ }
+
+ f->ignore (1);
+
+ // data for Protracker
+ length = f->readInt (1);
+ nop = f->readInt (1);
+ timer = f->readInt (1);
+
+ // init CmodPlayer
+ realloc_instruments (9);
+ realloc_order (length);
+ realloc_patterns (nop, 32, 9);
+ init_trackord ();
+
+ // load tracks
+ for (i = 0; i < nop; i++)
+ for (k = 0; k < 32; k++)
+ for (j = 0; j < 9; j++)
+ {
+ t = i * 9 + j;
+
+ // read event
+ unsigned char event = f->readInt (1);
+
+ // convert event
+ if (event < 0x61)
+ tracks[t][k].note = event;
+ if (event == 0xFF) // 0xFF: Release note
+ tracks[t][k].command = 8;
+ if (event == 0xFE) // 0xFE: Pattern Break
+ tracks[t][k].command = 13;
+ }
+
+ // load order
+ for (i = 0; i < length; i++)
+ order[i] = f->readInt (1) - 1;
+
+ fp.close (f);
+
+ // convert instruments
+ for (i = 0; i < 9; i++)
+ for (j = 0; j < 10; j++)
+ inst[i].data[conv_inst[j]] = instruments[i].data[j];
+
+ // data for Protracker
+ restartpos = 0;
+ initspeed = 1;
+
+ rewind (0);
+ return true;
+}
+
+void
+CmadLoader::rewind (int subsong)
+{
+ CmodPlayer::rewind (subsong);
+
+ // default instruments
+ for (int i = 0; i < 9; i++)
+ {
+ channel[i].inst = i;
+
+ channel[i].vol1 = 63 - (inst[i].data[10] & 63);
+ channel[i].vol2 = 63 - (inst[i].data[9] & 63);
+ }
+}
+
+float
+CmadLoader::getrefresh ()
+{
+ return (float) timer;
+}
+
+std::string CmadLoader::gettype ()
+{
+ return std::string ("Mlat Adlib Tracker");
+}
+
+std::string CmadLoader::getinstrument (unsigned int n)
+{
+ return std::string (instruments[n].name, 8);
+}
+
+unsigned int
+CmadLoader::getinstruments ()
+{
+ return 9;
+}
diff --git a/src/adplug/core/mad.cxx b/src/adplug/core/mad.cxx
deleted file mode 100644
index 5ce37b94a8a2..000000000000
--- a/src/adplug/core/mad.cxx
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- Adplug - Replayer for many OPL2/OPL3 audio file formats.
- Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- mad.cpp - MAD loader by Riven the Mage <riven at ok.ru>
-*/
-
-#include <string.h>
-
-#include "mad.h"
-
-/* -------- Public Methods -------------------------------- */
-
-CPlayer *
-CmadLoader::factory (Copl * newopl)
-{
- return new CmadLoader (newopl);
-}
-
-bool
-CmadLoader::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- const unsigned char conv_inst[10] = { 2, 1, 10, 9, 4, 3, 6, 5, 8, 7 };
- unsigned int i, j, k, t = 0;
-
- // 'MAD+' - signed ?
- char id[4];
- f->readString (id, 4);
- if (strncmp (id, "MAD+", 4))
- {
- fp.close (f);
- return false;
- }
-
- // load instruments
- for (i = 0; i < 9; i++)
- {
- f->readString (instruments[i].name, 8);
- for (j = 0; j < 12; j++)
- instruments[i].data[j] = f->readInt (1);
- }
-
- f->ignore (1);
-
- // data for Protracker
- length = f->readInt (1);
- nop = f->readInt (1);
- timer = f->readInt (1);
-
- // init CmodPlayer
- realloc_instruments (9);
- realloc_order (length);
- realloc_patterns (nop, 32, 9);
- init_trackord ();
-
- // load tracks
- for (i = 0; i < nop; i++)
- for (k = 0; k < 32; k++)
- for (j = 0; j < 9; j++)
- {
- t = i * 9 + j;
-
- // read event
- unsigned char event = f->readInt (1);
-
- // convert event
- if (event < 0x61)
- tracks[t][k].note = event;
- if (event == 0xFF) // 0xFF: Release note
- tracks[t][k].command = 8;
- if (event == 0xFE) // 0xFE: Pattern Break
- tracks[t][k].command = 13;
- }
-
- // load order
- for (i = 0; i < length; i++)
- order[i] = f->readInt (1) - 1;
-
- fp.close (f);
-
- // convert instruments
- for (i = 0; i < 9; i++)
- for (j = 0; j < 10; j++)
- inst[i].data[conv_inst[j]] = instruments[i].data[j];
-
- // data for Protracker
- restartpos = 0;
- initspeed = 1;
-
- rewind (0);
- return true;
-}
-
-void
-CmadLoader::rewind (int subsong)
-{
- CmodPlayer::rewind (subsong);
-
- // default instruments
- for (int i = 0; i < 9; i++)
- {
- channel[i].inst = i;
-
- channel[i].vol1 = 63 - (inst[i].data[10] & 63);
- channel[i].vol2 = 63 - (inst[i].data[9] & 63);
- }
-}
-
-float
-CmadLoader::getrefresh ()
-{
- return (float) timer;
-}
-
-std::string CmadLoader::gettype ()
-{
- return std::string ("Mlat Adlib Tracker");
-}
-
-std::string CmadLoader::getinstrument (unsigned int n)
-{
- return std::string (instruments[n].name, 8);
-}
-
-unsigned int
-CmadLoader::getinstruments ()
-{
- return 9;
-}
diff --git a/src/adplug/core/mad.h b/src/adplug/core/mad.h
index 836d8c006eb0..7631de9cd819 100644
--- a/src/adplug/core/mad.h
+++ b/src/adplug/core/mad.h
@@ -28,7 +28,7 @@ public:
CmadLoader(Copl *newopl) : CmodPlayer(newopl) { };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
void rewind(int subsong);
float getrefresh();
diff --git a/src/adplug/core/mid.cc b/src/adplug/core/mid.cc
new file mode 100644
index 000000000000..3f78c31bb342
--- /dev/null
+++ b/src/adplug/core/mid.cc
@@ -0,0 +1,1101 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *
+ * MIDI & MIDI-like file player - Last Update: 10/15/2005
+ * by Phil Hassey - www.imitationpickles.org
+ * philhassey at hotmail.com
+ *
+ * Can play the following
+ * .LAA - a raw save of a Lucas Arts Adlib music
+ * or
+ * a raw save of a LucasFilm Adlib music
+ * .SCI - the sierra "midi" format.
+ * Files must be in the form
+ * xxxNAME.sci
+ * So that the loader can load the right patch file:
+ * xxxPATCH.003 (patch.003 must be saved from the
+ * sierra resource from each game.)
+ *
+ * Other acknowledgements:
+ * Allegro - for the midi instruments and the midi volume table
+ * SCUMM Revisited - for getting the .LAA / .MIDs out of those
+ * LucasArts files.
+ * FreeSCI - for some information on the sci music files
+ * SD - the SCI Decoder (to get all .sci out of the Sierra files)
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include "mid.h"
+#include "mididata.h"
+
+/*#define TESTING*/
+#ifdef TESTING
+#define midiprintf printf
+#else
+void
+CmidPlayer::midiprintf (const char *format, ...)
+{
+}
+#endif
+
+#define LUCAS_STYLE 1
+#define CMF_STYLE 2
+#define MIDI_STYLE 4
+#define SIERRA_STYLE 8
+
+// AdLib melodic and rhythm mode defines
+#define ADLIB_MELODIC 0
+#define ADLIB_RYTHM 1
+
+// File types
+#define FILE_LUCAS 1
+#define FILE_MIDI 2
+#define FILE_CMF 3
+#define FILE_SIERRA 4
+#define FILE_ADVSIERRA 5
+#define FILE_OLDLUCAS 6
+
+// AdLib standard operator table
+const unsigned char
+CmidPlayer::adlib_opadd[] =
+ { 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12 };
+
+// dunno
+const int
+CmidPlayer::ops[] =
+ { 0x20, 0x20, 0x40, 0x40, 0x60, 0x60, 0x80, 0x80, 0xe0, 0xe0, 0xc0 };
+
+// map CMF drum channels 12 - 15 to corresponding AdLib drum operators
+// bass drum (channel 11) not mapped, cause it's handled like a normal instrument
+const int
+CmidPlayer::map_chan[] = { 0x14, 0x12, 0x15, 0x11 };
+
+// Standard AdLib frequency table
+const int
+CmidPlayer::fnums[] =
+ { 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x241, 0x263,
+0x287, 0x2ae };
+
+// Map CMF drum channels 11 - 15 to corresponding AdLib drum channels
+const int
+CmidPlayer::percussion_map[] = { 6, 7, 8, 8, 7 };
+
+CPlayer *
+CmidPlayer::factory (Copl * newopl)
+{
+ return new CmidPlayer (newopl);
+}
+
+CmidPlayer::CmidPlayer (Copl * newopl):CPlayer (newopl), author (&emptystr), title (&emptystr), remarks (&emptystr),
+emptystr ('\0'), flen (0), data (0)
+{
+}
+
+unsigned char
+CmidPlayer::datalook (long pos)
+{
+ if (pos < 0 || pos >= flen)
+ return (0);
+ return (data[pos]);
+}
+
+unsigned long
+CmidPlayer::getnexti (unsigned long num)
+{
+ unsigned long v = 0;
+ unsigned long i;
+
+ for (i = 0; i < num; i++)
+ {
+ v += (datalook (pos) << (8 * i));
+ pos++;
+ }
+ return (v);
+}
+
+unsigned long
+CmidPlayer::getnext (unsigned long num)
+{
+ unsigned long v = 0;
+ unsigned long i;
+
+ for (i = 0; i < num; i++)
+ {
+ v <<= 8;
+ v += datalook (pos);
+ pos++;
+ }
+ return (v);
+}
+
+unsigned long
+CmidPlayer::getval ()
+{
+ int v = 0;
+ unsigned char b;
+
+ b = (unsigned char) getnext (1);
+ v = b & 0x7f;
+ while ((b & 0x80) != 0)
+ {
+ b = (unsigned char) getnext (1);
+ v = (v << 7) + (b & 0x7F);
+ }
+ return (v);
+}
+
+bool
+CmidPlayer::load_sierra_ins (const std::string & fname,
+ const CFileProvider & fp)
+{
+ long i, j, k, l;
+ unsigned char ins[28];
+ char *pfilename;
+ binistream *f;
+
+ pfilename = (char *) malloc (fname.length () + 9);
+ strcpy (pfilename, fname.c_str ());
+ j = 0;
+ for (i = strlen (pfilename) - 1; i >= 0; i--)
+ if (pfilename[i] == '/' || pfilename[i] == '\\')
+ {
+ j = i + 1;
+ break;
+ }
+ sprintf (pfilename + j + 3, "patch.003");
+
+ VFSFile instfd (pfilename, "rb");
+ f = fp.open (instfd);
+ free (pfilename);
+ if (!f)
+ return false;
+
+ f->ignore (2);
+ stins = 0;
+ for (i = 0; i < 2; i++)
+ {
+ for (k = 0; k < 48; k++)
+ {
+ l = i * 48 + k;
+ midiprintf ("\n%2ld: ", l);
+ for (j = 0; j < 28; j++)
+ ins[j] = f->readInt (1);
+
+ myinsbank[l][0] = (ins[9] * 0x80) + (ins[10] * 0x40) + (ins[5] * 0x20) + (ins[11] * 0x10) + ins[1]; //1=ins5
+ myinsbank[l][1] = (ins[22] * 0x80) + (ins[23] * 0x40) + (ins[18] * 0x20) + (ins[24] * 0x10) + ins[14]; //1=ins18
+
+ myinsbank[l][2] = (ins[0] << 6) + ins[8];
+ myinsbank[l][3] = (ins[13] << 6) + ins[21];
+
+ myinsbank[l][4] = (ins[3] << 4) + ins[6];
+ myinsbank[l][5] = (ins[16] << 4) + ins[19];
+ myinsbank[l][6] = (ins[4] << 4) + ins[7];
+ myinsbank[l][7] = (ins[17] << 4) + ins[20];
+
+ myinsbank[l][8] = ins[26];
+ myinsbank[l][9] = ins[27];
+
+ myinsbank[l][10] = ((ins[2] << 1)) + (1 - (ins[12] & 1));
+ //(ins[12] ? 0:1)+((ins[2]<<1));
+
+ for (j = 0; j < 11; j++)
+ midiprintf ("%02X ", myinsbank[l][j]);
+ stins++;
+ }
+ f->ignore (2);
+ }
+
+ fp.close (f);
+ memcpy (smyinsbank, myinsbank, 128 * 16);
+ return true;
+}
+
+void
+CmidPlayer::sierra_next_section ()
+{
+ int i, j;
+
+ for (i = 0; i < 16; i++)
+ track[i].on = 0;
+
+ midiprintf ("\n\nnext adv sierra section:\n");
+
+ pos = sierra_pos;
+ i = 0;
+ j = 0;
+ while (i != 0xff)
+ {
+ getnext (1);
+ curtrack = j;
+ j++;
+ track[curtrack].on = 1;
+ track[curtrack].spos = getnext (1);
+ track[curtrack].spos += (getnext (1) << 8) + 4; //4 best usually +3? not 0,1,2 or 5
+// track[curtrack].spos=getnext(1)+(getnext(1)<<8)+4; // dynamite!: doesn't optimize correctly!!
+ track[curtrack].tend = flen; //0xFC will kill it
+ track[curtrack].iwait = 0;
+ track[curtrack].pv = 0;
+ midiprintf ("track %u starts at %lx\n", curtrack, track[curtrack].spos);
+
+ getnext (2);
+ i = getnext (1);
+ }
+ getnext (2);
+ deltas = 0x20;
+ sierra_pos = pos;
+ //getch();
+
+ fwait = 0;
+ doing = 1;
+}
+
+bool
+CmidPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ int good;
+ unsigned char s[6];
+ std::string filename (fd.filename ());
+
+ f->readString ((char *) s, 6);
+ good = 0;
+ subsongs = 0;
+ switch (s[0])
+ {
+ case 'A':
+ if (s[1] == 'D' && s[2] == 'L')
+ good = FILE_LUCAS;
+ break;
+ case 0x84:
+ if (s[1] == 0x00 && load_sierra_ins (filename, fp))
+ {
+ if (s[2] == 0xf0)
+ good = FILE_ADVSIERRA;
+ else
+ good = FILE_SIERRA;
+ break;
+ }
+ default:
+ if (s[4] == 'A' && s[5] == 'D')
+ good = FILE_OLDLUCAS;
+ break;
+ }
+
+ if (good != 0)
+ subsongs = 1;
+ else
+ {
+ fp.close (f);
+ return false;
+ }
+
+ type = good;
+ f->seek (0);
+ flen = fp.filesize (f);
+ data = new unsigned char[flen];
+ f->readString ((char *) data, flen);
+
+ fp.close (f);
+ rewind (0);
+ return true;
+}
+
+void
+CmidPlayer::midi_write_adlib (unsigned int r, unsigned char v)
+{
+ opl->write (r, v);
+ adlib_data[r] = v;
+}
+
+void
+CmidPlayer::midi_fm_instrument (int voice, unsigned char *inst)
+{
+ if ((adlib_style & SIERRA_STYLE) != 0)
+ midi_write_adlib (0xbd, 0); //just gotta make sure this happens..
+ //'cause who knows when it'll be
+ //reset otherwise.
+
+
+ midi_write_adlib (0x20 + adlib_opadd[voice], inst[0]);
+ midi_write_adlib (0x23 + adlib_opadd[voice], inst[1]);
+
+ if ((adlib_style & LUCAS_STYLE) != 0)
+ {
+ midi_write_adlib (0x43 + adlib_opadd[voice], 0x3f);
+ if ((inst[10] & 1) == 0)
+ midi_write_adlib (0x40 + adlib_opadd[voice], inst[2]);
+ else
+ midi_write_adlib (0x40 + adlib_opadd[voice], 0x3f);
+ }
+ else
+ {
+ if ((adlib_style & SIERRA_STYLE) != 0)
+ {
+ midi_write_adlib (0x40 + adlib_opadd[voice], inst[2]);
+ midi_write_adlib (0x43 + adlib_opadd[voice], inst[3]);
+ }
+ else
+ {
+ midi_write_adlib (0x40 + adlib_opadd[voice], inst[2]);
+ if ((inst[10] & 1) == 0)
+ midi_write_adlib (0x43 + adlib_opadd[voice], inst[3]);
+ else
+ midi_write_adlib (0x43 + adlib_opadd[voice], 0);
+ }
+ }
+
+ midi_write_adlib (0x60 + adlib_opadd[voice], inst[4]);
+ midi_write_adlib (0x63 + adlib_opadd[voice], inst[5]);
+ midi_write_adlib (0x80 + adlib_opadd[voice], inst[6]);
+ midi_write_adlib (0x83 + adlib_opadd[voice], inst[7]);
+ midi_write_adlib (0xe0 + adlib_opadd[voice], inst[8]);
+ midi_write_adlib (0xe3 + adlib_opadd[voice], inst[9]);
+
+ midi_write_adlib (0xc0 + voice, inst[10]);
+}
+
+void
+CmidPlayer::midi_fm_percussion (int ch, unsigned char *inst)
+{
+ int opadd = map_chan[ch - 12];
+
+ midi_write_adlib (0x20 + opadd, inst[0]);
+ midi_write_adlib (0x40 + opadd, inst[2]);
+ midi_write_adlib (0x60 + opadd, inst[4]);
+ midi_write_adlib (0x80 + opadd, inst[6]);
+ midi_write_adlib (0xe0 + opadd, inst[8]);
+ midi_write_adlib (0xc0 + opadd, inst[10]);
+}
+
+void
+CmidPlayer::midi_fm_volume (int voice, int volume)
+{
+ int vol;
+
+ if ((adlib_style & SIERRA_STYLE) == 0) //sierra likes it loud!
+ {
+ vol = volume >> 2;
+
+ if ((adlib_style & LUCAS_STYLE) != 0)
+ {
+ if ((adlib_data[0xc0 + voice] & 1) == 1)
+ midi_write_adlib (0x40 + adlib_opadd[voice],
+ (unsigned char) ((63 - vol) |
+ (adlib_data
+ [0x40 +
+ adlib_opadd[voice]] & 0xc0)));
+ midi_write_adlib (0x43 + adlib_opadd[voice],
+ (unsigned char) ((63 - vol) |
+ (adlib_data
+ [0x43 +
+ adlib_opadd[voice]] & 0xc0)));
+ }
+ else
+ {
+ if ((adlib_data[0xc0 + voice] & 1) == 1)
+ midi_write_adlib (0x40 + adlib_opadd[voice],
+ (unsigned char) ((63 - vol) |
+ (adlib_data
+ [0x40 +
+ adlib_opadd[voice]] & 0xc0)));
+ midi_write_adlib (0x43 + adlib_opadd[voice],
+ (unsigned char) ((63 - vol) |
+ (adlib_data
+ [0x43 +
+ adlib_opadd[voice]] & 0xc0)));
+ }
+ }
+}
+
+void
+CmidPlayer::midi_fm_playnote (int voice, int note, int volume)
+{
+ int freq = fnums[note % 12];
+ int oct = note / 12;
+ int c;
+
+ midi_fm_volume (voice, volume);
+ midi_write_adlib (0xa0 + voice, (unsigned char) (freq & 0xff));
+
+ c = ((freq & 0x300) >> 8) + (oct << 2) + (adlib_mode == ADLIB_MELODIC
+ || voice < 6 ? (1 << 5) : 0);
+ midi_write_adlib (0xb0 + voice, (unsigned char) c);
+}
+
+void
+CmidPlayer::midi_fm_endnote (int voice)
+{
+ //midi_fm_volume(voice,0);
+ //midi_write_adlib(0xb0+voice,0);
+
+ midi_write_adlib (0xb0 + voice,
+ (unsigned char) (adlib_data[0xb0 + voice] & (255 - 32)));
+}
+
+void
+CmidPlayer::midi_fm_reset ()
+{
+ int i;
+
+ opl->init ();
+
+ for (i = 0; i < 256; i++)
+ midi_write_adlib (i, 0);
+
+ midi_write_adlib (0x01, 0x20);
+ midi_write_adlib (0xBD, 0xc0);
+}
+
+bool
+CmidPlayer::update ()
+{
+ long w, v, note, vel, ctrl, nv, x, l, lnum;
+ int i = 0, j, c;
+ int on, onl, numchan;
+ int ret;
+
+ if (doing == 1)
+ {
+ // just get the first wait and ignore it :>
+ for (curtrack = 0; curtrack < 16; curtrack++)
+ if (track[curtrack].on)
+ {
+ pos = track[curtrack].pos;
+ if (type != FILE_SIERRA && type != FILE_ADVSIERRA)
+ track[curtrack].iwait += getval ();
+ else
+ track[curtrack].iwait += getnext (1);
+ track[curtrack].pos = pos;
+ }
+ doing = 0;
+ }
+
+ iwait = 0;
+ ret = 1;
+
+ while (iwait == 0 && ret == 1)
+ {
+ for (curtrack = 0; curtrack < 16; curtrack++)
+ if (track[curtrack].on && track[curtrack].iwait == 0 &&
+ track[curtrack].pos < track[curtrack].tend)
+ {
+ pos = track[curtrack].pos;
+
+ v = getnext (1);
+
+ // This is to do implied MIDI events.
+ if (v < 0x80)
+ {
+ v = track[curtrack].pv;
+ pos--;
+ }
+ track[curtrack].pv = (unsigned char) v;
+
+ c = v & 0x0f;
+ midiprintf ("[%2lX]", v);
+ switch (v & 0xf0)
+ {
+ case 0x80: /*note off */
+ note = getnext (1);
+ vel = getnext (1);
+ for (i = 0; i < 9; i++)
+ if (chp[i][0] == c && chp[i][1] == note)
+ {
+ midi_fm_endnote (i);
+ chp[i][0] = -1;
+ }
+ break;
+ case 0x90: /*note on */
+ // doing=0;
+ note = getnext (1);
+ vel = getnext (1);
+
+ if (adlib_mode == ADLIB_RYTHM)
+ numchan = 6;
+ else
+ numchan = 9;
+
+ if (ch[c].on != 0)
+ {
+ for (i = 0; i < 18; i++)
+ chp[i][2]++;
+
+ if (c < 11 || adlib_mode == ADLIB_MELODIC)
+ {
+ j = 0;
+ on = -1;
+ onl = 0;
+ for (i = 0; i < numchan; i++)
+ if (chp[i][0] == -1 && chp[i][2] > onl)
+ {
+ onl = chp[i][2];
+ on = i;
+ j = 1;
+ }
+
+ if (on == -1)
+ {
+ onl = 0;
+ for (i = 0; i < numchan; i++)
+ if (chp[i][2] > onl)
+ {
+ onl = chp[i][2];
+ on = i;
+ }
+ }
+
+ if (j == 0)
+ midi_fm_endnote (on);
+ }
+ else
+ on = percussion_map[c - 11];
+
+ if (vel != 0 && ch[c].inum >= 0 && ch[c].inum < 128)
+ {
+ if (adlib_mode == ADLIB_MELODIC || c < 12)
+ midi_fm_instrument (on, ch[c].ins);
+ else
+ midi_fm_percussion (c, ch[c].ins);
+
+ if ((adlib_style & MIDI_STYLE) != 0)
+ {
+ nv = ((ch[c].vol * vel) / 128);
+ if ((adlib_style & LUCAS_STYLE) != 0)
+ nv *= 2;
+ if (nv > 127)
+ nv = 127;
+ nv = my_midi_fm_vol_table[nv];
+ if ((adlib_style & LUCAS_STYLE) != 0)
+ nv = (int) ((float) sqrt ((float) nv) * 11);
+ }
+ else
+ {
+ nv = vel;
+ }
+
+ midi_fm_playnote (on, note + ch[c].nshift, nv * 2);
+ chp[on][0] = c;
+ chp[on][1] = note;
+ chp[on][2] = 0;
+
+ if (adlib_mode == ADLIB_RYTHM && c >= 11)
+ {
+ midi_write_adlib (0xbd,
+ adlib_data[0xbd] & ~(0x10 >> (c - 11)));
+ midi_write_adlib (0xbd,
+ adlib_data[0xbd] | (0x10 >> (c - 11)));
+ }
+
+ }
+ else
+ {
+ if (vel == 0) //same code as end note
+ {
+ for (i = 0; i < 9; i++)
+ if (chp[i][0] == c && chp[i][1] == note)
+ {
+ // midi_fm_volume(i,0); // really end the note
+ midi_fm_endnote (i);
+ chp[i][0] = -1;
+ }
+ }
+ else
+ { // i forget what this is for.
+ chp[on][0] = -1;
+ chp[on][2] = 0;
+ }
+ }
+ midiprintf (" [%d:%d:%ld:%ld]\n", c, ch[c].inum, note, vel);
+ }
+ else
+ midiprintf ("off");
+ break;
+ case 0xa0: /*key after touch */
+ note = getnext (1);
+ vel = getnext (1);
+ /* //this might all be good
+ for (i=0; i<9; i++)
+ if (chp[i][0]==c & chp[i][1]==note)
+
+ midi_fm_playnote(i,note+cnote[c],my_midi_fm_vol_table[(cvols[c]*vel)/128]*2);
+ */
+ break;
+ case 0xb0: /*control change .. pitch bend? */
+ ctrl = getnext (1);
+ vel = getnext (1);
+
+ switch (ctrl)
+ {
+ case 0x07:
+ midiprintf ("(pb:%d: %ld %ld)", c, ctrl, vel);
+ ch[c].vol = vel;
+ midiprintf ("vol");
+ break;
+ case 0x67:
+ midiprintf ("\n\nhere:%ld\n\n", vel);
+ if ((adlib_style & CMF_STYLE) != 0)
+ {
+ adlib_mode = vel;
+ if (adlib_mode == ADLIB_RYTHM)
+ midi_write_adlib (0xbd, adlib_data[0xbd] | (1 << 5));
+ else
+ midi_write_adlib (0xbd, adlib_data[0xbd] & ~(1 << 5));
+ }
+ break;
+ }
+ break;
+ case 0xc0: /*patch change */
+ x = getnext (1);
+ ch[c].inum = x;
+ for (j = 0; j < 11; j++)
+ ch[c].ins[j] = myinsbank[ch[c].inum][j];
+ break;
+ case 0xd0: /*chanel touch */
+ x = getnext (1);
+ break;
+ case 0xe0: /*pitch wheel */
+ x = getnext (1);
+ x = getnext (1);
+ break;
+ case 0xf0:
+ switch (v)
+ {
+ case 0xf0:
+ case 0xf7: /*sysex */
+ l = getval ();
+ if (datalook (pos + l) == 0xf7)
+ i = 1;
+ midiprintf ("{%ld}", l);
+ midiprintf ("\n");
+
+ if (datalook (pos) == 0x7d &&
+ datalook (pos + 1) == 0x10 && datalook (pos + 2) < 16)
+ {
+ adlib_style = LUCAS_STYLE | MIDI_STYLE;
+ for (i = 0; i < l; i++)
+ {
+ midiprintf ("%x ", datalook (pos + i));
+ if ((i - 3) % 10 == 0)
+ midiprintf ("\n");
+ }
+ midiprintf ("\n");
+ getnext (1);
+ getnext (1);
+ c = getnext (1);
+ getnext (1);
+
+ // getnext(22); //temp
+ ch[c].ins[0] =
+ (unsigned char) ((getnext (1) << 4) + getnext (1));
+ ch[c].ins[2] =
+ (unsigned char) (0xff -
+ (((getnext (1) << 4) + getnext (1)) & 0x3f));
+ ch[c].ins[4] =
+ (unsigned char) (0xff - ((getnext (1) << 4) + getnext (1)));
+ ch[c].ins[6] =
+ (unsigned char) (0xff - ((getnext (1) << 4) + getnext (1)));
+ ch[c].ins[8] =
+ (unsigned char) ((getnext (1) << 4) + getnext (1));
+
+ ch[c].ins[1] =
+ (unsigned char) ((getnext (1) << 4) + getnext (1));
+ ch[c].ins[3] =
+ (unsigned char) (0xff -
+ (((getnext (1) << 4) + getnext (1)) & 0x3f));
+ ch[c].ins[5] =
+ (unsigned char) (0xff - ((getnext (1) << 4) + getnext (1)));
+ ch[c].ins[7] =
+ (unsigned char) (0xff - ((getnext (1) << 4) + getnext (1)));
+ ch[c].ins[9] =
+ (unsigned char) ((getnext (1) << 4) + getnext (1));
+
+ i = (getnext (1) << 4) + getnext (1);
+ ch[c].ins[10] = i;
+
+ //if ((i&1)==1) ch[c].ins[10]=1;
+
+ midiprintf ("\n%d: ", c);
+ for (i = 0; i < 11; i++)
+ midiprintf ("%2X ", ch[c].ins[i]);
+ getnext (l - 26);
+ }
+ else
+ {
+ midiprintf ("\n");
+ for (j = 0; j < l; j++)
+ midiprintf ("%2lX ", getnext (1));
+ }
+
+ midiprintf ("\n");
+ if (i == 1)
+ getnext (1);
+ break;
+ case 0xf1:
+ break;
+ case 0xf2:
+ getnext (2);
+ break;
+ case 0xf3:
+ getnext (1);
+ break;
+ case 0xf4:
+ break;
+ case 0xf5:
+ break;
+ case 0xf6: /*something */
+ case 0xf8:
+ case 0xfa:
+ case 0xfb:
+ case 0xfc:
+ //this ends the track for sierra.
+ if (type == FILE_SIERRA || type == FILE_ADVSIERRA)
+ {
+ track[curtrack].tend = pos;
+ midiprintf ("endmark: %lu -- %lx\n", pos, pos);
+ }
+ break;
+ case 0xfe:
+ break;
+ case 0xfd:
+ break;
+ case 0xff:
+ v = getnext (1);
+ l = getval ();
+ midiprintf ("\n");
+ midiprintf ("{%lX_%lX}", v, l);
+ if (v == 0x51)
+ {
+ lnum = getnext (l);
+ msqtr = lnum; /*set tempo */
+ midiprintf ("(qtr=%ld)", msqtr);
+ }
+ else
+ {
+ for (i = 0; i < l; i++)
+ midiprintf ("%2lX ", getnext (1));
+ }
+ break;
+ }
+ break;
+ default:
+ midiprintf ("%lX!", v); /* if we get down here, a error occurred */
+ break;
+ }
+
+ if (pos < track[curtrack].tend)
+ {
+ if (type != FILE_SIERRA && type != FILE_ADVSIERRA)
+ w = getval ();
+ else
+ w = getnext (1);
+ track[curtrack].iwait = w;
+ /*
+ if (w!=0)
+ {
+ midiprintf("\n<%d>",w);
+ f =
+ ((float)w/(float)deltas)*((float)msqtr/(float)1000000);
+ if (doing==1) f=0; //not playing yet. don't wait yet
+ }
+ */
+ }
+ else
+ track[curtrack].iwait = 0;
+
+ track[curtrack].pos = pos;
+ }
+
+
+ ret = 0; //end of song.
+ iwait = 0;
+ for (curtrack = 0; curtrack < 16; curtrack++)
+ if (track[curtrack].on == 1 &&
+ track[curtrack].pos < track[curtrack].tend)
+ ret = 1; //not yet..
+
+ if (ret == 1)
+ {
+ iwait = 0xffffff; // bigger than any wait can be!
+ for (curtrack = 0; curtrack < 16; curtrack++)
+ if (track[curtrack].on == 1 &&
+ track[curtrack].pos < track[curtrack].tend &&
+ track[curtrack].iwait < iwait)
+ iwait = track[curtrack].iwait;
+ }
+ }
+
+
+ if (iwait != 0 && ret == 1)
+ {
+ for (curtrack = 0; curtrack < 16; curtrack++)
+ if (track[curtrack].on)
+ track[curtrack].iwait -= iwait;
+
+
+ fwait =
+ 1.0f / (((float) iwait / (float) deltas) *
+ ((float) msqtr / (float) 1000000));
+ }
+ else
+ fwait = 50; // 1/50th of a second
+
+ midiprintf ("\n");
+ for (i = 0; i < 16; i++)
+ if (track[i].on)
+ {
+ if (track[i].pos < track[i].tend)
+ midiprintf ("<%lu>", track[i].iwait);
+ else
+ midiprintf ("stop");
+ }
+
+ /*
+ if (ret==0 && type==FILE_ADVSIERRA)
+ if (datalook(sierra_pos-2)!=0xff)
+ {
+ midiprintf ("next sectoin!");
+ sierra_next_section(p);
+ fwait=50;
+ ret=1;
+ }
+ */
+
+ if (ret)
+ return true;
+ else
+ return false;
+}
+
+float
+CmidPlayer::getrefresh ()
+{
+ return (fwait > 0.01f ? fwait : 0.01f);
+}
+
+void
+CmidPlayer::rewind (int subsong)
+{
+ long i, j, l;
+ long o_sierra_pos;
+ unsigned char ins[16];
+
+ pos = 0;
+ tins = 0;
+ adlib_style = MIDI_STYLE | CMF_STYLE;
+ adlib_mode = ADLIB_MELODIC;
+ for (i = 0; i < 128; i++)
+ for (j = 0; j < 14; j++) // for (j = 0; j < 16; j++)
+ myinsbank[i][j] = midi_fm_instruments[i][j];
+ for (i = 0; i < 16; i++)
+ {
+ ch[i].inum = 0;
+ for (j = 0; j < 11; j++)
+ ch[i].ins[j] = myinsbank[ch[i].inum][j];
+ ch[i].vol = 127;
+ ch[i].nshift = -25;
+ ch[i].on = 1;
+ }
+
+ /* General init */
+ for (i = 0; i < 9; i++)
+ {
+ chp[i][0] = -1;
+ chp[i][2] = 0;
+ }
+
+ deltas = 250; // just a number, not a standard
+ msqtr = 500000;
+ fwait = 123; // gotta be a small thing.. sorta like nothing
+ iwait = 0;
+
+ subsongs = 1;
+
+ for (i = 0; i < 16; i++)
+ {
+ track[i].tend = 0;
+ track[i].spos = 0;
+ track[i].pos = 0;
+ track[i].iwait = 0;
+ track[i].on = 0;
+ track[i].pv = 0;
+ }
+ curtrack = 0;
+
+ /* specific to file-type init */
+
+ pos = 0;
+ i = getnext (1);
+ switch (type)
+ {
+ case FILE_LUCAS:
+ getnext (24); //skip junk and get to the midi.
+ adlib_style = LUCAS_STYLE | MIDI_STYLE;
+ //note: no break, we go right into midi headers...
+ case FILE_MIDI:
+ if (type != FILE_LUCAS)
+ tins = 128;
+ getnext (11); /*skip header */
+ deltas = getnext (2);
+ midiprintf ("deltas:%ld\n", deltas);
+ getnext (4);
+
+ curtrack = 0;
+ track[curtrack].on = 1;
+ track[curtrack].tend = getnext (4);
+ track[curtrack].spos = pos;
+ midiprintf ("tracklen:%lu\n", track[curtrack].tend);
+ break;
+ case FILE_OLDLUCAS:
+ msqtr = 250000;
+ pos = 9;
+ deltas = getnext (1);
+
+ i = 8;
+ pos = 0x19; // jump to instruments
+ tins = i;
+ for (j = 0; j < i; j++)
+ {
+ midiprintf ("\n%ld: ", j);
+ for (l = 0; l < 16; l++)
+ ins[l] = (unsigned char) getnext (1);
+
+ myinsbank[j][10] = ins[2];
+ myinsbank[j][0] = ins[3];
+ myinsbank[j][2] = ins[4];
+ myinsbank[j][4] = ins[5];
+ myinsbank[j][6] = ins[6];
+ myinsbank[j][8] = ins[7];
+ myinsbank[j][1] = ins[8];
+ myinsbank[j][3] = ins[9];
+ myinsbank[j][5] = ins[10];
+ myinsbank[j][7] = ins[11];
+ myinsbank[j][9] = ins[12];
+
+ for (l = 0; l < 11; l++)
+ midiprintf ("%2X ", myinsbank[j][l]);
+ }
+
+ for (i = 0; i < 16; i++)
+ {
+ if (i < tins)
+ {
+ ch[i].inum = i;
+ for (j = 0; j < 11; j++)
+ ch[i].ins[j] = myinsbank[ch[i].inum][j];
+ }
+ }
+
+ adlib_style = LUCAS_STYLE | MIDI_STYLE;
+
+ curtrack = 0;
+ track[curtrack].on = 1;
+ track[curtrack].tend = flen; // music until the end of the file
+ track[curtrack].spos = 0x98; //jump to midi music
+ break;
+ case FILE_ADVSIERRA:
+ memcpy (myinsbank, smyinsbank, 128 * 16);
+ tins = stins;
+ deltas = 0x20;
+ getnext (11); //worthless empty space and "stuff" :)
+
+ o_sierra_pos = sierra_pos = pos;
+ sierra_next_section ();
+ while (datalook (sierra_pos - 2) != 0xff)
+ {
+ sierra_next_section ();
+ subsongs++;
+ }
+
+ if (subsong < 0 || subsong >= subsongs)
+ subsong = 0;
+
+ sierra_pos = o_sierra_pos;
+ sierra_next_section ();
+ i = 0;
+ while (i != subsong)
+ {
+ sierra_next_section ();
+ i++;
+ }
+
+ adlib_style = SIERRA_STYLE | MIDI_STYLE; //advanced sierra tunes use volume
+ break;
+ case FILE_SIERRA:
+ memcpy (myinsbank, smyinsbank, 128 * 16);
+ tins = stins;
+ getnext (2);
+ deltas = 0x20;
+
+ curtrack = 0;
+ track[curtrack].on = 1;
+ track[curtrack].tend = flen; // music until the end of the file
+
+ for (i = 0; i < 16; i++)
+ {
+ ch[i].nshift = -13;
+ ch[i].on = getnext (1);
+ ch[i].inum = getnext (1);
+ for (j = 0; j < 11; j++)
+ ch[i].ins[j] = myinsbank[ch[i].inum][j];
+ }
+
+ track[curtrack].spos = pos;
+ adlib_style = SIERRA_STYLE | MIDI_STYLE;
+ break;
+ }
+
+
+/* sprintf(info,"%s\r\nTicks/Quarter Note: %ld\r\n",info,deltas);
+ sprintf(info,"%sms/Quarter Note: %ld",info,msqtr); */
+
+ for (i = 0; i < 16; i++)
+ if (track[i].on)
+ {
+ track[i].pos = track[i].spos;
+ track[i].pv = 0;
+ track[i].iwait = 0;
+ }
+
+ doing = 1;
+ midi_fm_reset ();
+}
+
+std::string CmidPlayer::gettype ()
+{
+ switch (type)
+ {
+ case FILE_LUCAS:
+ return std::string ("LucasArts AdLib MIDI");
+ case FILE_MIDI:
+ return std::string ("General MIDI");
+ case FILE_OLDLUCAS:
+ return std::string ("Lucasfilm Adlib MIDI");
+ case FILE_ADVSIERRA:
+ return std::string ("Sierra On-Line VGA MIDI");
+ case FILE_SIERRA:
+ return std::string ("Sierra On-Line EGA MIDI");
+ default:
+ return std::string ("MIDI unknown");
+ }
+}
diff --git a/src/adplug/core/mid.cxx b/src/adplug/core/mid.cxx
deleted file mode 100644
index f12305fc29bc..000000000000
--- a/src/adplug/core/mid.cxx
+++ /dev/null
@@ -1,1105 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *
- * MIDI & MIDI-like file player - Last Update: 10/15/2005
- * by Phil Hassey - www.imitationpickles.org
- * philhassey at hotmail.com
- *
- * Can play the following
- * .LAA - a raw save of a Lucas Arts Adlib music
- * or
- * a raw save of a LucasFilm Adlib music
- * .SCI - the sierra "midi" format.
- * Files must be in the form
- * xxxNAME.sci
- * So that the loader can load the right patch file:
- * xxxPATCH.003 (patch.003 must be saved from the
- * sierra resource from each game.)
- *
- * Other acknowledgements:
- * Allegro - for the midi instruments and the midi volume table
- * SCUMM Revisited - for getting the .LAA / .MIDs out of those
- * LucasArts files.
- * FreeSCI - for some information on the sci music files
- * SD - the SCI Decoder (to get all .sci out of the Sierra files)
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include <string.h>
-#include "mid.h"
-#include "mididata.h"
-
-/*#define TESTING*/
-#ifdef TESTING
-#define midiprintf printf
-#else
-void
-CmidPlayer::midiprintf (const char *format, ...)
-{
-}
-#endif
-
-#define LUCAS_STYLE 1
-#define CMF_STYLE 2
-#define MIDI_STYLE 4
-#define SIERRA_STYLE 8
-
-// AdLib melodic and rhythm mode defines
-#define ADLIB_MELODIC 0
-#define ADLIB_RYTHM 1
-
-// File types
-#define FILE_LUCAS 1
-#define FILE_MIDI 2
-#define FILE_CMF 3
-#define FILE_SIERRA 4
-#define FILE_ADVSIERRA 5
-#define FILE_OLDLUCAS 6
-
-// AdLib standard operator table
-const unsigned char
-CmidPlayer::adlib_opadd[] =
- { 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12 };
-
-// dunno
-const int
-CmidPlayer::ops[] =
- { 0x20, 0x20, 0x40, 0x40, 0x60, 0x60, 0x80, 0x80, 0xe0, 0xe0, 0xc0 };
-
-// map CMF drum channels 12 - 15 to corresponding AdLib drum operators
-// bass drum (channel 11) not mapped, cause it's handled like a normal instrument
-const int
-CmidPlayer::map_chan[] = { 0x14, 0x12, 0x15, 0x11 };
-
-// Standard AdLib frequency table
-const int
-CmidPlayer::fnums[] =
- { 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x241, 0x263,
-0x287, 0x2ae };
-
-// Map CMF drum channels 11 - 15 to corresponding AdLib drum channels
-const int
-CmidPlayer::percussion_map[] = { 6, 7, 8, 8, 7 };
-
-CPlayer *
-CmidPlayer::factory (Copl * newopl)
-{
- return new CmidPlayer (newopl);
-}
-
-CmidPlayer::CmidPlayer (Copl * newopl):CPlayer (newopl), author (&emptystr), title (&emptystr), remarks (&emptystr),
-emptystr ('\0'), flen (0), data (0)
-{
-}
-
-unsigned char
-CmidPlayer::datalook (long pos)
-{
- if (pos < 0 || pos >= flen)
- return (0);
- return (data[pos]);
-}
-
-unsigned long
-CmidPlayer::getnexti (unsigned long num)
-{
- unsigned long v = 0;
- unsigned long i;
-
- for (i = 0; i < num; i++)
- {
- v += (datalook (pos) << (8 * i));
- pos++;
- }
- return (v);
-}
-
-unsigned long
-CmidPlayer::getnext (unsigned long num)
-{
- unsigned long v = 0;
- unsigned long i;
-
- for (i = 0; i < num; i++)
- {
- v <<= 8;
- v += datalook (pos);
- pos++;
- }
- return (v);
-}
-
-unsigned long
-CmidPlayer::getval ()
-{
- int v = 0;
- unsigned char b;
-
- b = (unsigned char) getnext (1);
- v = b & 0x7f;
- while ((b & 0x80) != 0)
- {
- b = (unsigned char) getnext (1);
- v = (v << 7) + (b & 0x7F);
- }
- return (v);
-}
-
-bool
-CmidPlayer::load_sierra_ins (const std::string & fname,
- const CFileProvider & fp)
-{
- long i, j, k, l;
- unsigned char ins[28];
- char *pfilename;
- binistream *f;
-
- pfilename = (char *) malloc (fname.length () + 9);
- strcpy (pfilename, fname.c_str ());
- j = 0;
- for (i = strlen (pfilename) - 1; i >= 0; i--)
- if (pfilename[i] == '/' || pfilename[i] == '\\')
- {
- j = i + 1;
- break;
- }
- sprintf (pfilename + j + 3, "patch.003");
-
- VFSFile *instfd = vfs_fopen (pfilename, "rb");
- f = fp.open (instfd);
- free (pfilename);
- if (!f)
- {
- vfs_fclose (instfd);
- return false;
- }
-
- f->ignore (2);
- stins = 0;
- for (i = 0; i < 2; i++)
- {
- for (k = 0; k < 48; k++)
- {
- l = i * 48 + k;
- midiprintf ("\n%2ld: ", l);
- for (j = 0; j < 28; j++)
- ins[j] = f->readInt (1);
-
- myinsbank[l][0] = (ins[9] * 0x80) + (ins[10] * 0x40) + (ins[5] * 0x20) + (ins[11] * 0x10) + ins[1]; //1=ins5
- myinsbank[l][1] = (ins[22] * 0x80) + (ins[23] * 0x40) + (ins[18] * 0x20) + (ins[24] * 0x10) + ins[14]; //1=ins18
-
- myinsbank[l][2] = (ins[0] << 6) + ins[8];
- myinsbank[l][3] = (ins[13] << 6) + ins[21];
-
- myinsbank[l][4] = (ins[3] << 4) + ins[6];
- myinsbank[l][5] = (ins[16] << 4) + ins[19];
- myinsbank[l][6] = (ins[4] << 4) + ins[7];
- myinsbank[l][7] = (ins[17] << 4) + ins[20];
-
- myinsbank[l][8] = ins[26];
- myinsbank[l][9] = ins[27];
-
- myinsbank[l][10] = ((ins[2] << 1)) + (1 - (ins[12] & 1));
- //(ins[12] ? 0:1)+((ins[2]<<1));
-
- for (j = 0; j < 11; j++)
- midiprintf ("%02X ", myinsbank[l][j]);
- stins++;
- }
- f->ignore (2);
- }
-
- fp.close (f);
- vfs_fclose (instfd);
- memcpy (smyinsbank, myinsbank, 128 * 16);
- return true;
-}
-
-void
-CmidPlayer::sierra_next_section ()
-{
- int i, j;
-
- for (i = 0; i < 16; i++)
- track[i].on = 0;
-
- midiprintf ("\n\nnext adv sierra section:\n");
-
- pos = sierra_pos;
- i = 0;
- j = 0;
- while (i != 0xff)
- {
- getnext (1);
- curtrack = j;
- j++;
- track[curtrack].on = 1;
- track[curtrack].spos = getnext (1);
- track[curtrack].spos += (getnext (1) << 8) + 4; //4 best usually +3? not 0,1,2 or 5
-// track[curtrack].spos=getnext(1)+(getnext(1)<<8)+4; // dynamite!: doesn't optimize correctly!!
- track[curtrack].tend = flen; //0xFC will kill it
- track[curtrack].iwait = 0;
- track[curtrack].pv = 0;
- midiprintf ("track %u starts at %lx\n", curtrack, track[curtrack].spos);
-
- getnext (2);
- i = getnext (1);
- }
- getnext (2);
- deltas = 0x20;
- sierra_pos = pos;
- //getch();
-
- fwait = 0;
- doing = 1;
-}
-
-bool
-CmidPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- int good;
- unsigned char s[6];
- std::string filename (vfs_get_filename (fd));
-
- f->readString ((char *) s, 6);
- good = 0;
- subsongs = 0;
- switch (s[0])
- {
- case 'A':
- if (s[1] == 'D' && s[2] == 'L')
- good = FILE_LUCAS;
- break;
- case 0x84:
- if (s[1] == 0x00 && load_sierra_ins (filename, fp))
- {
- if (s[2] == 0xf0)
- good = FILE_ADVSIERRA;
- else
- good = FILE_SIERRA;
- break;
- }
- default:
- if (s[4] == 'A' && s[5] == 'D')
- good = FILE_OLDLUCAS;
- break;
- }
-
- if (good != 0)
- subsongs = 1;
- else
- {
- fp.close (f);
- return false;
- }
-
- type = good;
- f->seek (0);
- flen = fp.filesize (f);
- data = new unsigned char[flen];
- f->readString ((char *) data, flen);
-
- fp.close (f);
- rewind (0);
- return true;
-}
-
-void
-CmidPlayer::midi_write_adlib (unsigned int r, unsigned char v)
-{
- opl->write (r, v);
- adlib_data[r] = v;
-}
-
-void
-CmidPlayer::midi_fm_instrument (int voice, unsigned char *inst)
-{
- if ((adlib_style & SIERRA_STYLE) != 0)
- midi_write_adlib (0xbd, 0); //just gotta make sure this happens..
- //'cause who knows when it'll be
- //reset otherwise.
-
-
- midi_write_adlib (0x20 + adlib_opadd[voice], inst[0]);
- midi_write_adlib (0x23 + adlib_opadd[voice], inst[1]);
-
- if ((adlib_style & LUCAS_STYLE) != 0)
- {
- midi_write_adlib (0x43 + adlib_opadd[voice], 0x3f);
- if ((inst[10] & 1) == 0)
- midi_write_adlib (0x40 + adlib_opadd[voice], inst[2]);
- else
- midi_write_adlib (0x40 + adlib_opadd[voice], 0x3f);
- }
- else
- {
- if ((adlib_style & SIERRA_STYLE) != 0)
- {
- midi_write_adlib (0x40 + adlib_opadd[voice], inst[2]);
- midi_write_adlib (0x43 + adlib_opadd[voice], inst[3]);
- }
- else
- {
- midi_write_adlib (0x40 + adlib_opadd[voice], inst[2]);
- if ((inst[10] & 1) == 0)
- midi_write_adlib (0x43 + adlib_opadd[voice], inst[3]);
- else
- midi_write_adlib (0x43 + adlib_opadd[voice], 0);
- }
- }
-
- midi_write_adlib (0x60 + adlib_opadd[voice], inst[4]);
- midi_write_adlib (0x63 + adlib_opadd[voice], inst[5]);
- midi_write_adlib (0x80 + adlib_opadd[voice], inst[6]);
- midi_write_adlib (0x83 + adlib_opadd[voice], inst[7]);
- midi_write_adlib (0xe0 + adlib_opadd[voice], inst[8]);
- midi_write_adlib (0xe3 + adlib_opadd[voice], inst[9]);
-
- midi_write_adlib (0xc0 + voice, inst[10]);
-}
-
-void
-CmidPlayer::midi_fm_percussion (int ch, unsigned char *inst)
-{
- int opadd = map_chan[ch - 12];
-
- midi_write_adlib (0x20 + opadd, inst[0]);
- midi_write_adlib (0x40 + opadd, inst[2]);
- midi_write_adlib (0x60 + opadd, inst[4]);
- midi_write_adlib (0x80 + opadd, inst[6]);
- midi_write_adlib (0xe0 + opadd, inst[8]);
- midi_write_adlib (0xc0 + opadd, inst[10]);
-}
-
-void
-CmidPlayer::midi_fm_volume (int voice, int volume)
-{
- int vol;
-
- if ((adlib_style & SIERRA_STYLE) == 0) //sierra likes it loud!
- {
- vol = volume >> 2;
-
- if ((adlib_style & LUCAS_STYLE) != 0)
- {
- if ((adlib_data[0xc0 + voice] & 1) == 1)
- midi_write_adlib (0x40 + adlib_opadd[voice],
- (unsigned char) ((63 - vol) |
- (adlib_data
- [0x40 +
- adlib_opadd[voice]] & 0xc0)));
- midi_write_adlib (0x43 + adlib_opadd[voice],
- (unsigned char) ((63 - vol) |
- (adlib_data
- [0x43 +
- adlib_opadd[voice]] & 0xc0)));
- }
- else
- {
- if ((adlib_data[0xc0 + voice] & 1) == 1)
- midi_write_adlib (0x40 + adlib_opadd[voice],
- (unsigned char) ((63 - vol) |
- (adlib_data
- [0x40 +
- adlib_opadd[voice]] & 0xc0)));
- midi_write_adlib (0x43 + adlib_opadd[voice],
- (unsigned char) ((63 - vol) |
- (adlib_data
- [0x43 +
- adlib_opadd[voice]] & 0xc0)));
- }
- }
-}
-
-void
-CmidPlayer::midi_fm_playnote (int voice, int note, int volume)
-{
- int freq = fnums[note % 12];
- int oct = note / 12;
- int c;
-
- midi_fm_volume (voice, volume);
- midi_write_adlib (0xa0 + voice, (unsigned char) (freq & 0xff));
-
- c = ((freq & 0x300) >> 8) + (oct << 2) + (adlib_mode == ADLIB_MELODIC
- || voice < 6 ? (1 << 5) : 0);
- midi_write_adlib (0xb0 + voice, (unsigned char) c);
-}
-
-void
-CmidPlayer::midi_fm_endnote (int voice)
-{
- //midi_fm_volume(voice,0);
- //midi_write_adlib(0xb0+voice,0);
-
- midi_write_adlib (0xb0 + voice,
- (unsigned char) (adlib_data[0xb0 + voice] & (255 - 32)));
-}
-
-void
-CmidPlayer::midi_fm_reset ()
-{
- int i;
-
- opl->init ();
-
- for (i = 0; i < 256; i++)
- midi_write_adlib (i, 0);
-
- midi_write_adlib (0x01, 0x20);
- midi_write_adlib (0xBD, 0xc0);
-}
-
-bool
-CmidPlayer::update ()
-{
- long w, v, note, vel, ctrl, nv, x, l, lnum;
- int i = 0, j, c;
- int on, onl, numchan;
- int ret;
-
- if (doing == 1)
- {
- // just get the first wait and ignore it :>
- for (curtrack = 0; curtrack < 16; curtrack++)
- if (track[curtrack].on)
- {
- pos = track[curtrack].pos;
- if (type != FILE_SIERRA && type != FILE_ADVSIERRA)
- track[curtrack].iwait += getval ();
- else
- track[curtrack].iwait += getnext (1);
- track[curtrack].pos = pos;
- }
- doing = 0;
- }
-
- iwait = 0;
- ret = 1;
-
- while (iwait == 0 && ret == 1)
- {
- for (curtrack = 0; curtrack < 16; curtrack++)
- if (track[curtrack].on && track[curtrack].iwait == 0 &&
- track[curtrack].pos < track[curtrack].tend)
- {
- pos = track[curtrack].pos;
-
- v = getnext (1);
-
- // This is to do implied MIDI events.
- if (v < 0x80)
- {
- v = track[curtrack].pv;
- pos--;
- }
- track[curtrack].pv = (unsigned char) v;
-
- c = v & 0x0f;
- midiprintf ("[%2lX]", v);
- switch (v & 0xf0)
- {
- case 0x80: /*note off */
- note = getnext (1);
- vel = getnext (1);
- for (i = 0; i < 9; i++)
- if (chp[i][0] == c && chp[i][1] == note)
- {
- midi_fm_endnote (i);
- chp[i][0] = -1;
- }
- break;
- case 0x90: /*note on */
- // doing=0;
- note = getnext (1);
- vel = getnext (1);
-
- if (adlib_mode == ADLIB_RYTHM)
- numchan = 6;
- else
- numchan = 9;
-
- if (ch[c].on != 0)
- {
- for (i = 0; i < 18; i++)
- chp[i][2]++;
-
- if (c < 11 || adlib_mode == ADLIB_MELODIC)
- {
- j = 0;
- on = -1;
- onl = 0;
- for (i = 0; i < numchan; i++)
- if (chp[i][0] == -1 && chp[i][2] > onl)
- {
- onl = chp[i][2];
- on = i;
- j = 1;
- }
-
- if (on == -1)
- {
- onl = 0;
- for (i = 0; i < numchan; i++)
- if (chp[i][2] > onl)
- {
- onl = chp[i][2];
- on = i;
- }
- }
-
- if (j == 0)
- midi_fm_endnote (on);
- }
- else
- on = percussion_map[c - 11];
-
- if (vel != 0 && ch[c].inum >= 0 && ch[c].inum < 128)
- {
- if (adlib_mode == ADLIB_MELODIC || c < 12)
- midi_fm_instrument (on, ch[c].ins);
- else
- midi_fm_percussion (c, ch[c].ins);
-
- if ((adlib_style & MIDI_STYLE) != 0)
- {
- nv = ((ch[c].vol * vel) / 128);
- if ((adlib_style & LUCAS_STYLE) != 0)
- nv *= 2;
- if (nv > 127)
- nv = 127;
- nv = my_midi_fm_vol_table[nv];
- if ((adlib_style & LUCAS_STYLE) != 0)
- nv = (int) ((float) sqrt ((float) nv) * 11);
- }
- else
- {
- nv = vel;
- }
-
- midi_fm_playnote (on, note + ch[c].nshift, nv * 2);
- chp[on][0] = c;
- chp[on][1] = note;
- chp[on][2] = 0;
-
- if (adlib_mode == ADLIB_RYTHM && c >= 11)
- {
- midi_write_adlib (0xbd,
- adlib_data[0xbd] & ~(0x10 >> (c - 11)));
- midi_write_adlib (0xbd,
- adlib_data[0xbd] | (0x10 >> (c - 11)));
- }
-
- }
- else
- {
- if (vel == 0) //same code as end note
- {
- for (i = 0; i < 9; i++)
- if (chp[i][0] == c && chp[i][1] == note)
- {
- // midi_fm_volume(i,0); // really end the note
- midi_fm_endnote (i);
- chp[i][0] = -1;
- }
- }
- else
- { // i forget what this is for.
- chp[on][0] = -1;
- chp[on][2] = 0;
- }
- }
- midiprintf (" [%d:%d:%ld:%ld]\n", c, ch[c].inum, note, vel);
- }
- else
- midiprintf ("off");
- break;
- case 0xa0: /*key after touch */
- note = getnext (1);
- vel = getnext (1);
- /* //this might all be good
- for (i=0; i<9; i++)
- if (chp[i][0]==c & chp[i][1]==note)
-
- midi_fm_playnote(i,note+cnote[c],my_midi_fm_vol_table[(cvols[c]*vel)/128]*2);
- */
- break;
- case 0xb0: /*control change .. pitch bend? */
- ctrl = getnext (1);
- vel = getnext (1);
-
- switch (ctrl)
- {
- case 0x07:
- midiprintf ("(pb:%d: %ld %ld)", c, ctrl, vel);
- ch[c].vol = vel;
- midiprintf ("vol");
- break;
- case 0x67:
- midiprintf ("\n\nhere:%ld\n\n", vel);
- if ((adlib_style & CMF_STYLE) != 0)
- {
- adlib_mode = vel;
- if (adlib_mode == ADLIB_RYTHM)
- midi_write_adlib (0xbd, adlib_data[0xbd] | (1 << 5));
- else
- midi_write_adlib (0xbd, adlib_data[0xbd] & ~(1 << 5));
- }
- break;
- }
- break;
- case 0xc0: /*patch change */
- x = getnext (1);
- ch[c].inum = x;
- for (j = 0; j < 11; j++)
- ch[c].ins[j] = myinsbank[ch[c].inum][j];
- break;
- case 0xd0: /*chanel touch */
- x = getnext (1);
- break;
- case 0xe0: /*pitch wheel */
- x = getnext (1);
- x = getnext (1);
- break;
- case 0xf0:
- switch (v)
- {
- case 0xf0:
- case 0xf7: /*sysex */
- l = getval ();
- if (datalook (pos + l) == 0xf7)
- i = 1;
- midiprintf ("{%ld}", l);
- midiprintf ("\n");
-
- if (datalook (pos) == 0x7d &&
- datalook (pos + 1) == 0x10 && datalook (pos + 2) < 16)
- {
- adlib_style = LUCAS_STYLE | MIDI_STYLE;
- for (i = 0; i < l; i++)
- {
- midiprintf ("%x ", datalook (pos + i));
- if ((i - 3) % 10 == 0)
- midiprintf ("\n");
- }
- midiprintf ("\n");
- getnext (1);
- getnext (1);
- c = getnext (1);
- getnext (1);
-
- // getnext(22); //temp
- ch[c].ins[0] =
- (unsigned char) ((getnext (1) << 4) + getnext (1));
- ch[c].ins[2] =
- (unsigned char) (0xff -
- (((getnext (1) << 4) + getnext (1)) & 0x3f));
- ch[c].ins[4] =
- (unsigned char) (0xff - ((getnext (1) << 4) + getnext (1)));
- ch[c].ins[6] =
- (unsigned char) (0xff - ((getnext (1) << 4) + getnext (1)));
- ch[c].ins[8] =
- (unsigned char) ((getnext (1) << 4) + getnext (1));
-
- ch[c].ins[1] =
- (unsigned char) ((getnext (1) << 4) + getnext (1));
- ch[c].ins[3] =
- (unsigned char) (0xff -
- (((getnext (1) << 4) + getnext (1)) & 0x3f));
- ch[c].ins[5] =
- (unsigned char) (0xff - ((getnext (1) << 4) + getnext (1)));
- ch[c].ins[7] =
- (unsigned char) (0xff - ((getnext (1) << 4) + getnext (1)));
- ch[c].ins[9] =
- (unsigned char) ((getnext (1) << 4) + getnext (1));
-
- i = (getnext (1) << 4) + getnext (1);
- ch[c].ins[10] = i;
-
- //if ((i&1)==1) ch[c].ins[10]=1;
-
- midiprintf ("\n%d: ", c);
- for (i = 0; i < 11; i++)
- midiprintf ("%2X ", ch[c].ins[i]);
- getnext (l - 26);
- }
- else
- {
- midiprintf ("\n");
- for (j = 0; j < l; j++)
- midiprintf ("%2lX ", getnext (1));
- }
-
- midiprintf ("\n");
- if (i == 1)
- getnext (1);
- break;
- case 0xf1:
- break;
- case 0xf2:
- getnext (2);
- break;
- case 0xf3:
- getnext (1);
- break;
- case 0xf4:
- break;
- case 0xf5:
- break;
- case 0xf6: /*something */
- case 0xf8:
- case 0xfa:
- case 0xfb:
- case 0xfc:
- //this ends the track for sierra.
- if (type == FILE_SIERRA || type == FILE_ADVSIERRA)
- {
- track[curtrack].tend = pos;
- midiprintf ("endmark: %lu -- %lx\n", pos, pos);
- }
- break;
- case 0xfe:
- break;
- case 0xfd:
- break;
- case 0xff:
- v = getnext (1);
- l = getval ();
- midiprintf ("\n");
- midiprintf ("{%lX_%lX}", v, l);
- if (v == 0x51)
- {
- lnum = getnext (l);
- msqtr = lnum; /*set tempo */
- midiprintf ("(qtr=%ld)", msqtr);
- }
- else
- {
- for (i = 0; i < l; i++)
- midiprintf ("%2lX ", getnext (1));
- }
- break;
- }
- break;
- default:
- midiprintf ("%lX!", v); /* if we get down here, a error occurred */
- break;
- }
-
- if (pos < track[curtrack].tend)
- {
- if (type != FILE_SIERRA && type != FILE_ADVSIERRA)
- w = getval ();
- else
- w = getnext (1);
- track[curtrack].iwait = w;
- /*
- if (w!=0)
- {
- midiprintf("\n<%d>",w);
- f =
- ((float)w/(float)deltas)*((float)msqtr/(float)1000000);
- if (doing==1) f=0; //not playing yet. don't wait yet
- }
- */
- }
- else
- track[curtrack].iwait = 0;
-
- track[curtrack].pos = pos;
- }
-
-
- ret = 0; //end of song.
- iwait = 0;
- for (curtrack = 0; curtrack < 16; curtrack++)
- if (track[curtrack].on == 1 &&
- track[curtrack].pos < track[curtrack].tend)
- ret = 1; //not yet..
-
- if (ret == 1)
- {
- iwait = 0xffffff; // bigger than any wait can be!
- for (curtrack = 0; curtrack < 16; curtrack++)
- if (track[curtrack].on == 1 &&
- track[curtrack].pos < track[curtrack].tend &&
- track[curtrack].iwait < iwait)
- iwait = track[curtrack].iwait;
- }
- }
-
-
- if (iwait != 0 && ret == 1)
- {
- for (curtrack = 0; curtrack < 16; curtrack++)
- if (track[curtrack].on)
- track[curtrack].iwait -= iwait;
-
-
- fwait =
- 1.0f / (((float) iwait / (float) deltas) *
- ((float) msqtr / (float) 1000000));
- }
- else
- fwait = 50; // 1/50th of a second
-
- midiprintf ("\n");
- for (i = 0; i < 16; i++)
- if (track[i].on)
- {
- if (track[i].pos < track[i].tend)
- midiprintf ("<%lu>", track[i].iwait);
- else
- midiprintf ("stop");
- }
-
- /*
- if (ret==0 && type==FILE_ADVSIERRA)
- if (datalook(sierra_pos-2)!=0xff)
- {
- midiprintf ("next sectoin!");
- sierra_next_section(p);
- fwait=50;
- ret=1;
- }
- */
-
- if (ret)
- return true;
- else
- return false;
-}
-
-float
-CmidPlayer::getrefresh ()
-{
- return (fwait > 0.01f ? fwait : 0.01f);
-}
-
-void
-CmidPlayer::rewind (int subsong)
-{
- long i, j, l;
- long o_sierra_pos;
- unsigned char ins[16];
-
- pos = 0;
- tins = 0;
- adlib_style = MIDI_STYLE | CMF_STYLE;
- adlib_mode = ADLIB_MELODIC;
- for (i = 0; i < 128; i++)
- for (j = 0; j < 14; j++) // for (j = 0; j < 16; j++)
- myinsbank[i][j] = midi_fm_instruments[i][j];
- for (i = 0; i < 16; i++)
- {
- ch[i].inum = 0;
- for (j = 0; j < 11; j++)
- ch[i].ins[j] = myinsbank[ch[i].inum][j];
- ch[i].vol = 127;
- ch[i].nshift = -25;
- ch[i].on = 1;
- }
-
- /* General init */
- for (i = 0; i < 9; i++)
- {
- chp[i][0] = -1;
- chp[i][2] = 0;
- }
-
- deltas = 250; // just a number, not a standard
- msqtr = 500000;
- fwait = 123; // gotta be a small thing.. sorta like nothing
- iwait = 0;
-
- subsongs = 1;
-
- for (i = 0; i < 16; i++)
- {
- track[i].tend = 0;
- track[i].spos = 0;
- track[i].pos = 0;
- track[i].iwait = 0;
- track[i].on = 0;
- track[i].pv = 0;
- }
- curtrack = 0;
-
- /* specific to file-type init */
-
- pos = 0;
- i = getnext (1);
- switch (type)
- {
- case FILE_LUCAS:
- getnext (24); //skip junk and get to the midi.
- adlib_style = LUCAS_STYLE | MIDI_STYLE;
- //note: no break, we go right into midi headers...
- case FILE_MIDI:
- if (type != FILE_LUCAS)
- tins = 128;
- getnext (11); /*skip header */
- deltas = getnext (2);
- midiprintf ("deltas:%ld\n", deltas);
- getnext (4);
-
- curtrack = 0;
- track[curtrack].on = 1;
- track[curtrack].tend = getnext (4);
- track[curtrack].spos = pos;
- midiprintf ("tracklen:%lu\n", track[curtrack].tend);
- break;
- case FILE_OLDLUCAS:
- msqtr = 250000;
- pos = 9;
- deltas = getnext (1);
-
- i = 8;
- pos = 0x19; // jump to instruments
- tins = i;
- for (j = 0; j < i; j++)
- {
- midiprintf ("\n%ld: ", j);
- for (l = 0; l < 16; l++)
- ins[l] = (unsigned char) getnext (1);
-
- myinsbank[j][10] = ins[2];
- myinsbank[j][0] = ins[3];
- myinsbank[j][2] = ins[4];
- myinsbank[j][4] = ins[5];
- myinsbank[j][6] = ins[6];
- myinsbank[j][8] = ins[7];
- myinsbank[j][1] = ins[8];
- myinsbank[j][3] = ins[9];
- myinsbank[j][5] = ins[10];
- myinsbank[j][7] = ins[11];
- myinsbank[j][9] = ins[12];
-
- for (l = 0; l < 11; l++)
- midiprintf ("%2X ", myinsbank[j][l]);
- }
-
- for (i = 0; i < 16; i++)
- {
- if (i < tins)
- {
- ch[i].inum = i;
- for (j = 0; j < 11; j++)
- ch[i].ins[j] = myinsbank[ch[i].inum][j];
- }
- }
-
- adlib_style = LUCAS_STYLE | MIDI_STYLE;
-
- curtrack = 0;
- track[curtrack].on = 1;
- track[curtrack].tend = flen; // music until the end of the file
- track[curtrack].spos = 0x98; //jump to midi music
- break;
- case FILE_ADVSIERRA:
- memcpy (myinsbank, smyinsbank, 128 * 16);
- tins = stins;
- deltas = 0x20;
- getnext (11); //worthless empty space and "stuff" :)
-
- o_sierra_pos = sierra_pos = pos;
- sierra_next_section ();
- while (datalook (sierra_pos - 2) != 0xff)
- {
- sierra_next_section ();
- subsongs++;
- }
-
- if (subsong < 0 || subsong >= subsongs)
- subsong = 0;
-
- sierra_pos = o_sierra_pos;
- sierra_next_section ();
- i = 0;
- while (i != subsong)
- {
- sierra_next_section ();
- i++;
- }
-
- adlib_style = SIERRA_STYLE | MIDI_STYLE; //advanced sierra tunes use volume
- break;
- case FILE_SIERRA:
- memcpy (myinsbank, smyinsbank, 128 * 16);
- tins = stins;
- getnext (2);
- deltas = 0x20;
-
- curtrack = 0;
- track[curtrack].on = 1;
- track[curtrack].tend = flen; // music until the end of the file
-
- for (i = 0; i < 16; i++)
- {
- ch[i].nshift = -13;
- ch[i].on = getnext (1);
- ch[i].inum = getnext (1);
- for (j = 0; j < 11; j++)
- ch[i].ins[j] = myinsbank[ch[i].inum][j];
- }
-
- track[curtrack].spos = pos;
- adlib_style = SIERRA_STYLE | MIDI_STYLE;
- break;
- }
-
-
-/* sprintf(info,"%s\r\nTicks/Quarter Note: %ld\r\n",info,deltas);
- sprintf(info,"%sms/Quarter Note: %ld",info,msqtr); */
-
- for (i = 0; i < 16; i++)
- if (track[i].on)
- {
- track[i].pos = track[i].spos;
- track[i].pv = 0;
- track[i].iwait = 0;
- }
-
- doing = 1;
- midi_fm_reset ();
-}
-
-std::string CmidPlayer::gettype ()
-{
- switch (type)
- {
- case FILE_LUCAS:
- return std::string ("LucasArts AdLib MIDI");
- case FILE_MIDI:
- return std::string ("General MIDI");
- case FILE_OLDLUCAS:
- return std::string ("Lucasfilm Adlib MIDI");
- case FILE_ADVSIERRA:
- return std::string ("Sierra On-Line VGA MIDI");
- case FILE_SIERRA:
- return std::string ("Sierra On-Line EGA MIDI");
- default:
- return std::string ("MIDI unknown");
- }
-}
diff --git a/src/adplug/core/mid.h b/src/adplug/core/mid.h
index f1b36dc69ebb..737bd70b2928 100644
--- a/src/adplug/core/mid.h
+++ b/src/adplug/core/mid.h
@@ -30,7 +30,7 @@ public:
~CmidPlayer()
{ if(data) delete [] data; }
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
diff --git a/src/adplug/core/mkj.cc b/src/adplug/core/mkj.cc
new file mode 100644
index 000000000000..de4bf2d285f0
--- /dev/null
+++ b/src/adplug/core/mkj.cc
@@ -0,0 +1,225 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * mkj.cpp - MKJamz Player, by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "mkj.h"
+#include "debug.h"
+
+CPlayer *
+CmkjPlayer::factory (Copl * newopl)
+{
+ return new CmkjPlayer (newopl);
+}
+
+bool
+CmkjPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ char id[6];
+ float ver;
+ int i, j;
+ short inst[8];
+
+ // file validation
+ f->readString (id, 6);
+ if (strncmp (id, "MKJamz", 6))
+ {
+ fp.close (f);
+ return false;
+ }
+ ver = f->readFloat (binio::Single);
+ if (ver > 1.12)
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // load
+ maxchannel = f->readInt (2);
+ opl->init ();
+ opl->write (1, 32);
+ for (i = 0; i < maxchannel; i++)
+ {
+ for (j = 0; j < 8; j++)
+ inst[j] = f->readInt (2);
+ opl->write (0x20 + op_table[i], inst[4]);
+ opl->write (0x23 + op_table[i], inst[0]);
+ opl->write (0x40 + op_table[i], inst[5]);
+ opl->write (0x43 + op_table[i], inst[1]);
+ opl->write (0x60 + op_table[i], inst[6]);
+ opl->write (0x63 + op_table[i], inst[2]);
+ opl->write (0x80 + op_table[i], inst[7]);
+ opl->write (0x83 + op_table[i], inst[3]);
+ }
+ maxnotes = f->readInt (2);
+ songbuf = new short[(maxchannel + 1) * maxnotes];
+ for (i = 0; i < maxchannel; i++)
+ channel[i].defined = f->readInt (2);
+ for (i = 0; i < (maxchannel + 1) * maxnotes; i++)
+ songbuf[i] = f->readInt (2);
+
+ AdPlug_LogWrite
+ ("CmkjPlayer::load(\"%s\"): loaded file ver %.2f, %d channels,"
+ " %d notes/channel.\n", fd.filename (), ver, maxchannel, maxnotes);
+ fp.close (f);
+ rewind (0);
+ return true;
+}
+
+bool
+CmkjPlayer::update ()
+{
+ int c, i;
+ short note;
+
+ for (c = 0; c < maxchannel; c++)
+ {
+ if (!channel[c].defined) // skip if channel is disabled
+ continue;
+
+ if (channel[c].pstat)
+ {
+ channel[c].pstat--;
+ continue;
+ }
+
+ opl->write (0xb0 + c, 0); // key off
+ do
+ {
+ assert (channel[c].songptr < (maxchannel + 1) * maxnotes);
+ note = songbuf[channel[c].songptr];
+ if (channel[c].songptr - c > maxchannel)
+ if (note && note < 250)
+ channel[c].pstat = channel[c].speed;
+ switch (note)
+ {
+ // normal notes
+ case 68:
+ opl->write (0xa0 + c, 0x81);
+ opl->write (0xb0 + c, 0x21 + 4 * channel[c].octave);
+ break;
+ case 69:
+ opl->write (0xa0 + c, 0xb0);
+ opl->write (0xb0 + c, 0x21 + 4 * channel[c].octave);
+ break;
+ case 70:
+ opl->write (0xa0 + c, 0xca);
+ opl->write (0xb0 + c, 0x21 + 4 * channel[c].octave);
+ break;
+ case 71:
+ opl->write (0xa0 + c, 0x2);
+ opl->write (0xb0 + c, 0x22 + 4 * channel[c].octave);
+ break;
+ case 65:
+ opl->write (0xa0 + c, 0x41);
+ opl->write (0xb0 + c, 0x22 + 4 * channel[c].octave);
+ break;
+ case 66:
+ opl->write (0xa0 + c, 0x87);
+ opl->write (0xb0 + c, 0x22 + 4 * channel[c].octave);
+ break;
+ case 67:
+ opl->write (0xa0 + c, 0xae);
+ opl->write (0xb0 + c, 0x22 + 4 * channel[c].octave);
+ break;
+ case 17:
+ opl->write (0xa0 + c, 0x6b);
+ opl->write (0xb0 + c, 0x21 + 4 * channel[c].octave);
+ break;
+ case 18:
+ opl->write (0xa0 + c, 0x98);
+ opl->write (0xb0 + c, 0x21 + 4 * channel[c].octave);
+ break;
+ case 20:
+ opl->write (0xa0 + c, 0xe5);
+ opl->write (0xb0 + c, 0x21 + 4 * channel[c].octave);
+ break;
+ case 21:
+ opl->write (0xa0 + c, 0x20);
+ opl->write (0xb0 + c, 0x22 + 4 * channel[c].octave);
+ break;
+ case 15:
+ opl->write (0xa0 + c, 0x63);
+ opl->write (0xb0 + c, 0x22 + 4 * channel[c].octave);
+ break;
+ case 255: // delay
+ channel[c].songptr += maxchannel;
+ channel[c].pstat = songbuf[channel[c].songptr];
+ break;
+ case 254: // set octave
+ channel[c].songptr += maxchannel;
+ channel[c].octave = songbuf[channel[c].songptr];
+ break;
+ case 253: // set speed
+ channel[c].songptr += maxchannel;
+ channel[c].speed = songbuf[channel[c].songptr];
+ break;
+ case 252: // set waveform
+ channel[c].songptr += maxchannel;
+ channel[c].waveform = songbuf[channel[c].songptr] - 300;
+ if (c > 2)
+ opl->write (0xe0 + c + (c + 6), channel[c].waveform);
+ else
+ opl->write (0xe0 + c, channel[c].waveform);
+ break;
+ case 251: // song end
+ for (i = 0; i < maxchannel; i++)
+ channel[i].songptr = i;
+ songend = true;
+ return false;
+ }
+
+ if (channel[c].songptr - c < maxnotes)
+ channel[c].songptr += maxchannel;
+ else
+ channel[c].songptr = c;
+ } while (!channel[c].pstat);
+ }
+
+ return !songend;
+}
+
+void
+CmkjPlayer::rewind (int subsong)
+{
+ int i;
+
+ for (i = 0; i < maxchannel; i++)
+ {
+ channel[i].pstat = 0;
+ channel[i].speed = 0;
+ channel[i].waveform = 0;
+ channel[i].songptr = i;
+ channel[i].octave = 4;
+ }
+
+ songend = false;
+}
+
+float
+CmkjPlayer::getrefresh ()
+{
+ return 100.0f;
+}
diff --git a/src/adplug/core/mkj.cxx b/src/adplug/core/mkj.cxx
deleted file mode 100644
index 6f7087e69b76..000000000000
--- a/src/adplug/core/mkj.cxx
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * mkj.cpp - MKJamz Player, by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include "mkj.h"
-#include "debug.h"
-
-CPlayer *
-CmkjPlayer::factory (Copl * newopl)
-{
- return new CmkjPlayer (newopl);
-}
-
-bool
-CmkjPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- char id[6];
- float ver;
- int i, j;
- short inst[8];
-
- // file validation
- f->readString (id, 6);
- if (strncmp (id, "MKJamz", 6))
- {
- fp.close (f);
- return false;
- }
- ver = f->readFloat (binio::Single);
- if (ver > 1.12)
- {
- fp.close (f);
- return false;
- }
-
- // load
- maxchannel = f->readInt (2);
- opl->init ();
- opl->write (1, 32);
- for (i = 0; i < maxchannel; i++)
- {
- for (j = 0; j < 8; j++)
- inst[j] = f->readInt (2);
- opl->write (0x20 + op_table[i], inst[4]);
- opl->write (0x23 + op_table[i], inst[0]);
- opl->write (0x40 + op_table[i], inst[5]);
- opl->write (0x43 + op_table[i], inst[1]);
- opl->write (0x60 + op_table[i], inst[6]);
- opl->write (0x63 + op_table[i], inst[2]);
- opl->write (0x80 + op_table[i], inst[7]);
- opl->write (0x83 + op_table[i], inst[3]);
- }
- maxnotes = f->readInt (2);
- songbuf = new short[(maxchannel + 1) * maxnotes];
- for (i = 0; i < maxchannel; i++)
- channel[i].defined = f->readInt (2);
- for (i = 0; i < (maxchannel + 1) * maxnotes; i++)
- songbuf[i] = f->readInt (2);
-
- AdPlug_LogWrite
- ("CmkjPlayer::load(\"%s\"): loaded file ver %.2f, %d channels,"
- " %d notes/channel.\n", vfs_get_filename (fd), ver, maxchannel, maxnotes);
- fp.close (f);
- rewind (0);
- return true;
-}
-
-bool
-CmkjPlayer::update ()
-{
- int c, i;
- short note;
-
- for (c = 0; c < maxchannel; c++)
- {
- if (!channel[c].defined) // skip if channel is disabled
- continue;
-
- if (channel[c].pstat)
- {
- channel[c].pstat--;
- continue;
- }
-
- opl->write (0xb0 + c, 0); // key off
- do
- {
- assert (channel[c].songptr < (maxchannel + 1) * maxnotes);
- note = songbuf[channel[c].songptr];
- if (channel[c].songptr - c > maxchannel)
- if (note && note < 250)
- channel[c].pstat = channel[c].speed;
- switch (note)
- {
- // normal notes
- case 68:
- opl->write (0xa0 + c, 0x81);
- opl->write (0xb0 + c, 0x21 + 4 * channel[c].octave);
- break;
- case 69:
- opl->write (0xa0 + c, 0xb0);
- opl->write (0xb0 + c, 0x21 + 4 * channel[c].octave);
- break;
- case 70:
- opl->write (0xa0 + c, 0xca);
- opl->write (0xb0 + c, 0x21 + 4 * channel[c].octave);
- break;
- case 71:
- opl->write (0xa0 + c, 0x2);
- opl->write (0xb0 + c, 0x22 + 4 * channel[c].octave);
- break;
- case 65:
- opl->write (0xa0 + c, 0x41);
- opl->write (0xb0 + c, 0x22 + 4 * channel[c].octave);
- break;
- case 66:
- opl->write (0xa0 + c, 0x87);
- opl->write (0xb0 + c, 0x22 + 4 * channel[c].octave);
- break;
- case 67:
- opl->write (0xa0 + c, 0xae);
- opl->write (0xb0 + c, 0x22 + 4 * channel[c].octave);
- break;
- case 17:
- opl->write (0xa0 + c, 0x6b);
- opl->write (0xb0 + c, 0x21 + 4 * channel[c].octave);
- break;
- case 18:
- opl->write (0xa0 + c, 0x98);
- opl->write (0xb0 + c, 0x21 + 4 * channel[c].octave);
- break;
- case 20:
- opl->write (0xa0 + c, 0xe5);
- opl->write (0xb0 + c, 0x21 + 4 * channel[c].octave);
- break;
- case 21:
- opl->write (0xa0 + c, 0x20);
- opl->write (0xb0 + c, 0x22 + 4 * channel[c].octave);
- break;
- case 15:
- opl->write (0xa0 + c, 0x63);
- opl->write (0xb0 + c, 0x22 + 4 * channel[c].octave);
- break;
- case 255: // delay
- channel[c].songptr += maxchannel;
- channel[c].pstat = songbuf[channel[c].songptr];
- break;
- case 254: // set octave
- channel[c].songptr += maxchannel;
- channel[c].octave = songbuf[channel[c].songptr];
- break;
- case 253: // set speed
- channel[c].songptr += maxchannel;
- channel[c].speed = songbuf[channel[c].songptr];
- break;
- case 252: // set waveform
- channel[c].songptr += maxchannel;
- channel[c].waveform = songbuf[channel[c].songptr] - 300;
- if (c > 2)
- opl->write (0xe0 + c + (c + 6), channel[c].waveform);
- else
- opl->write (0xe0 + c, channel[c].waveform);
- break;
- case 251: // song end
- for (i = 0; i < maxchannel; i++)
- channel[i].songptr = i;
- songend = true;
- return false;
- }
-
- if (channel[c].songptr - c < maxnotes)
- channel[c].songptr += maxchannel;
- else
- channel[c].songptr = c;
- } while (!channel[c].pstat);
- }
-
- return !songend;
-}
-
-void
-CmkjPlayer::rewind (int subsong)
-{
- int i;
-
- for (i = 0; i < maxchannel; i++)
- {
- channel[i].pstat = 0;
- channel[i].speed = 0;
- channel[i].waveform = 0;
- channel[i].songptr = i;
- channel[i].octave = 4;
- }
-
- songend = false;
-}
-
-float
-CmkjPlayer::getrefresh ()
-{
- return 100.0f;
-}
diff --git a/src/adplug/core/mkj.h b/src/adplug/core/mkj.h
index 0979489f79b7..748012835bc0 100644
--- a/src/adplug/core/mkj.h
+++ b/src/adplug/core/mkj.h
@@ -32,7 +32,7 @@ public:
~CmkjPlayer()
{ if(songbuf) delete [] songbuf; }
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
diff --git a/src/adplug/core/msc.cc b/src/adplug/core/msc.cc
new file mode 100644
index 000000000000..7b04a97e70b7
--- /dev/null
+++ b/src/adplug/core/msc.cc
@@ -0,0 +1,338 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * msc.c - MSC Player by Lubomir Bulej (pallas at kadan.cz)
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "msc.h"
+#include "debug.h"
+
+const unsigned char
+ CmscPlayer::msc_signature[MSC_SIGN_LEN] = {
+ 'C', 'e', 'r', 'e', 's', ' ', '\x13', ' ',
+ 'M', 'S', 'C', 'p', 'l', 'a', 'y', ' '
+};
+
+/*** public methods *************************************/
+
+CPlayer *
+CmscPlayer::factory (Copl * newopl)
+{
+ return new CmscPlayer (newopl);
+}
+
+CmscPlayer::CmscPlayer (Copl * newopl):CPlayer (newopl)
+{
+ desc = nullptr;
+ msc_data = nullptr;
+ raw_data = nullptr;
+ nr_blocks = 0;
+}
+
+CmscPlayer::~CmscPlayer ()
+{
+ if (raw_data != nullptr)
+ delete[]raw_data;
+
+ if (msc_data != nullptr)
+ {
+ // free compressed blocks
+ for (int blk_num = 0; blk_num < nr_blocks; blk_num++)
+ {
+ if (msc_data[blk_num].mb_data != nullptr)
+ delete[]msc_data[blk_num].mb_data;
+ }
+
+ delete[]msc_data;
+ }
+
+ if (desc != nullptr)
+ delete[]desc;
+}
+
+bool
+CmscPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *bf;
+ msc_header hdr;
+
+ // open and validate the file
+ bf = fp.open (fd);
+ if (!bf)
+ return false;
+
+ if (!load_header (bf, &hdr))
+ {
+ fp.close (bf);
+ return false;
+ }
+
+ // get stuff from the header
+ version = hdr.mh_ver;
+ timer_div = hdr.mh_timer;
+ nr_blocks = hdr.mh_nr_blocks;
+ block_len = hdr.mh_block_len;
+
+ if (!nr_blocks)
+ {
+ fp.close (bf);
+ return false;
+ }
+
+ // load compressed data blocks
+ msc_data = new msc_block[nr_blocks];
+ raw_data = new u8[block_len];
+
+ for (int blk_num = 0; blk_num < nr_blocks; blk_num++)
+ {
+ msc_block blk;
+
+ blk.mb_length = bf->readInt (2);
+ blk.mb_data = new u8[blk.mb_length];
+ for (int oct_num = 0; oct_num < blk.mb_length; oct_num++)
+ {
+ blk.mb_data[oct_num] = bf->readInt (1);
+ }
+
+ msc_data[blk_num] = blk;
+ }
+
+ // clean up & initialize
+ fp.close (bf);
+ rewind (0);
+
+ return true;
+}
+
+bool
+CmscPlayer::update ()
+{
+ // output data
+ while (!delay)
+ {
+ u8 cmnd;
+ u8 data;
+
+ // decode data
+ if (!decode_octet (&cmnd))
+ return false;
+
+ if (!decode_octet (&data))
+ return false;
+
+ // check for special commands
+ switch (cmnd)
+ {
+
+ // delay
+ case 0xff:
+ delay = 1 + (u8) (data - 1);
+ break;
+
+ // play command & data
+ default:
+ opl->write (cmnd, data);
+
+ } // command switch
+ } // play pass
+
+
+ // count delays
+ if (delay)
+ delay--;
+
+ // advance player position
+ play_pos++;
+ return true;
+}
+
+void
+CmscPlayer::rewind (int subsong)
+{
+ // reset state
+ dec_prefix = 0;
+ block_num = 0;
+ block_pos = 0;
+ play_pos = 0;
+ raw_pos = 0;
+ delay = 0;
+
+ // init the OPL chip and go to OPL2 mode
+ opl->init ();
+ opl->write (1, 32);
+}
+
+float
+CmscPlayer::getrefresh ()
+{
+ // PC timer oscillator frequency / wait register
+ return 1193180 / (float) (timer_div ? timer_div : 0xffff);
+}
+
+std::string CmscPlayer::gettype ()
+{
+ char
+ vstr[40];
+
+ sprintf (vstr, "AdLib MSCplay (version %d)", version);
+ return std::string (vstr);
+}
+
+/*** private methods *************************************/
+
+bool
+CmscPlayer::load_header (binistream * bf, msc_header * hdr)
+{
+ // check signature
+ bf->readString ((char *) hdr->mh_sign, sizeof (hdr->mh_sign));
+ if (memcmp (msc_signature, hdr->mh_sign, MSC_SIGN_LEN) != 0)
+ return false;
+
+ // check version
+ hdr->mh_ver = bf->readInt (2);
+ if (hdr->mh_ver != 0)
+ return false;
+
+ bf->readString ((char *) hdr->mh_desc, sizeof (hdr->mh_desc));
+ hdr->mh_timer = bf->readInt (2);
+ hdr->mh_nr_blocks = bf->readInt (2);
+ hdr->mh_block_len = bf->readInt (2);
+ return true;
+}
+
+bool
+CmscPlayer::decode_octet (u8 * output)
+{
+ msc_block blk; // compressed data block
+
+ if (block_num >= nr_blocks)
+ return false;
+
+ blk = msc_data[block_num];
+ while (1)
+ {
+ u8 octet; // decoded octet
+ u8 len_corr = 0; // length correction
+
+ // advance to next block if necessary
+ if (block_pos >= blk.mb_length && dec_len == 0)
+ {
+ block_num++;
+ if (block_num >= nr_blocks)
+ return false;
+
+ blk = msc_data[block_num];
+ block_pos = 0;
+ raw_pos = 0;
+ }
+
+ // decode the compressed music data
+ switch (dec_prefix)
+ {
+
+ // decode prefix
+ case 155:
+ case 175:
+ octet = blk.mb_data[block_pos++];
+ if (octet == 0)
+ {
+ // invalid prefix, output original
+ octet = dec_prefix;
+ dec_prefix = 0;
+ break;
+ }
+
+ // isolate length and distance
+ dec_len = (octet & 0x0F);
+ len_corr = 2;
+
+ dec_dist = (octet & 0xF0) >> 4;
+ if (dec_prefix == 155)
+ dec_dist++;
+
+ // next decode step for respective prefix type
+ dec_prefix++;
+ continue;
+
+
+ // check for extended length
+ case 156:
+ if (dec_len == 15)
+ dec_len += blk.mb_data[block_pos++];
+
+ // add length correction and go for copy mode
+ dec_len += len_corr;
+ dec_prefix = 255;
+ continue;
+
+
+ // get extended distance
+ case 176:
+ dec_dist += 17 + 16 * blk.mb_data[block_pos++];
+ len_corr = 3;
+
+ // check for extended length
+ dec_prefix = 156;
+ continue;
+
+
+ // prefix copy mode
+ case 255:
+ if ((int) raw_pos >= dec_dist)
+ octet = raw_data[raw_pos - dec_dist];
+ else
+ {
+ AdPlug_LogWrite ("error! read before raw_data buffer.\n");
+ octet = 0;
+ }
+
+ dec_len--;
+ if (dec_len == 0)
+ {
+ // back to normal mode
+ dec_prefix = 0;
+ }
+
+ break;
+
+
+ // normal mode
+ default:
+ octet = blk.mb_data[block_pos++];
+ if (octet == 155 || octet == 175)
+ {
+ // it's a prefix, restart
+ dec_prefix = octet;
+ continue;
+ }
+ } // prefix switch
+
+
+ // output the octet
+ if (output != nullptr)
+ *output = octet;
+
+ raw_data[raw_pos++] = octet;
+ break;
+ }; // decode pass
+
+ return true;
+}
diff --git a/src/adplug/core/msc.cxx b/src/adplug/core/msc.cxx
deleted file mode 100644
index 2fe4c72220c8..000000000000
--- a/src/adplug/core/msc.cxx
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * msc.c - MSC Player by Lubomir Bulej (pallas at kadan.cz)
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "msc.h"
-#include "debug.h"
-
-const unsigned char
- CmscPlayer::msc_signature[MSC_SIGN_LEN] = {
- 'C', 'e', 'r', 'e', 's', ' ', '\x13', ' ',
- 'M', 'S', 'C', 'p', 'l', 'a', 'y', ' '
-};
-
-/*** public methods *************************************/
-
-CPlayer *
-CmscPlayer::factory (Copl * newopl)
-{
- return new CmscPlayer (newopl);
-}
-
-CmscPlayer::CmscPlayer (Copl * newopl):CPlayer (newopl)
-{
- desc = NULL;
- msc_data = NULL;
- raw_data = NULL;
- nr_blocks = 0;
-}
-
-CmscPlayer::~CmscPlayer ()
-{
- if (raw_data != NULL)
- delete[]raw_data;
-
- if (msc_data != NULL)
- {
- // free compressed blocks
- for (int blk_num = 0; blk_num < nr_blocks; blk_num++)
- {
- if (msc_data[blk_num].mb_data != NULL)
- delete[]msc_data[blk_num].mb_data;
- }
-
- delete[]msc_data;
- }
-
- if (desc != NULL)
- delete[]desc;
-}
-
-bool
-CmscPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *bf;
- msc_header hdr;
-
- // open and validate the file
- bf = fp.open (fd);
- if (!bf)
- return false;
-
- if (!load_header (bf, &hdr))
- {
- fp.close (bf);
- return false;
- }
-
- // get stuff from the header
- version = hdr.mh_ver;
- timer_div = hdr.mh_timer;
- nr_blocks = hdr.mh_nr_blocks;
- block_len = hdr.mh_block_len;
-
- if (!nr_blocks)
- {
- fp.close (bf);
- return false;
- }
-
- // load compressed data blocks
- msc_data = new msc_block[nr_blocks];
- raw_data = new u8[block_len];
-
- for (int blk_num = 0; blk_num < nr_blocks; blk_num++)
- {
- msc_block blk;
-
- blk.mb_length = bf->readInt (2);
- blk.mb_data = new u8[blk.mb_length];
- for (int oct_num = 0; oct_num < blk.mb_length; oct_num++)
- {
- blk.mb_data[oct_num] = bf->readInt (1);
- }
-
- msc_data[blk_num] = blk;
- }
-
- // clean up & initialize
- fp.close (bf);
- rewind (0);
-
- return true;
-}
-
-bool
-CmscPlayer::update ()
-{
- // output data
- while (!delay)
- {
- u8 cmnd;
- u8 data;
-
- // decode data
- if (!decode_octet (&cmnd))
- return false;
-
- if (!decode_octet (&data))
- return false;
-
- // check for special commands
- switch (cmnd)
- {
-
- // delay
- case 0xff:
- delay = 1 + (u8) (data - 1);
- break;
-
- // play command & data
- default:
- opl->write (cmnd, data);
-
- } // command switch
- } // play pass
-
-
- // count delays
- if (delay)
- delay--;
-
- // advance player position
- play_pos++;
- return true;
-}
-
-void
-CmscPlayer::rewind (int subsong)
-{
- // reset state
- dec_prefix = 0;
- block_num = 0;
- block_pos = 0;
- play_pos = 0;
- raw_pos = 0;
- delay = 0;
-
- // init the OPL chip and go to OPL2 mode
- opl->init ();
- opl->write (1, 32);
-}
-
-float
-CmscPlayer::getrefresh ()
-{
- // PC timer oscillator frequency / wait register
- return 1193180 / (float) (timer_div ? timer_div : 0xffff);
-}
-
-std::string CmscPlayer::gettype ()
-{
- char
- vstr[40];
-
- sprintf (vstr, "AdLib MSCplay (version %d)", version);
- return std::string (vstr);
-}
-
-/*** private methods *************************************/
-
-bool
-CmscPlayer::load_header (binistream * bf, msc_header * hdr)
-{
- // check signature
- bf->readString ((char *) hdr->mh_sign, sizeof (hdr->mh_sign));
- if (memcmp (msc_signature, hdr->mh_sign, MSC_SIGN_LEN) != 0)
- return false;
-
- // check version
- hdr->mh_ver = bf->readInt (2);
- if (hdr->mh_ver != 0)
- return false;
-
- bf->readString ((char *) hdr->mh_desc, sizeof (hdr->mh_desc));
- hdr->mh_timer = bf->readInt (2);
- hdr->mh_nr_blocks = bf->readInt (2);
- hdr->mh_block_len = bf->readInt (2);
- return true;
-}
-
-bool
-CmscPlayer::decode_octet (u8 * output)
-{
- msc_block blk; // compressed data block
-
- if (block_num >= nr_blocks)
- return false;
-
- blk = msc_data[block_num];
- while (1)
- {
- u8 octet; // decoded octet
- u8 len_corr = 0; // length correction
-
- // advance to next block if necessary
- if (block_pos >= blk.mb_length && dec_len == 0)
- {
- block_num++;
- if (block_num >= nr_blocks)
- return false;
-
- blk = msc_data[block_num];
- block_pos = 0;
- raw_pos = 0;
- }
-
- // decode the compressed music data
- switch (dec_prefix)
- {
-
- // decode prefix
- case 155:
- case 175:
- octet = blk.mb_data[block_pos++];
- if (octet == 0)
- {
- // invalid prefix, output original
- octet = dec_prefix;
- dec_prefix = 0;
- break;
- }
-
- // isolate length and distance
- dec_len = (octet & 0x0F);
- len_corr = 2;
-
- dec_dist = (octet & 0xF0) >> 4;
- if (dec_prefix == 155)
- dec_dist++;
-
- // next decode step for respective prefix type
- dec_prefix++;
- continue;
-
-
- // check for extended length
- case 156:
- if (dec_len == 15)
- dec_len += blk.mb_data[block_pos++];
-
- // add length correction and go for copy mode
- dec_len += len_corr;
- dec_prefix = 255;
- continue;
-
-
- // get extended distance
- case 176:
- dec_dist += 17 + 16 * blk.mb_data[block_pos++];
- len_corr = 3;
-
- // check for extended length
- dec_prefix = 156;
- continue;
-
-
- // prefix copy mode
- case 255:
- if ((int) raw_pos >= dec_dist)
- octet = raw_data[raw_pos - dec_dist];
- else
- {
- AdPlug_LogWrite ("error! read before raw_data buffer.\n");
- octet = 0;
- }
-
- dec_len--;
- if (dec_len == 0)
- {
- // back to normal mode
- dec_prefix = 0;
- }
-
- break;
-
-
- // normal mode
- default:
- octet = blk.mb_data[block_pos++];
- if (octet == 155 || octet == 175)
- {
- // it's a prefix, restart
- dec_prefix = octet;
- continue;
- }
- } // prefix switch
-
-
- // output the octet
- if (output != NULL)
- *output = octet;
-
- raw_data[raw_pos++] = octet;
- break;
- }; // decode pass
-
- return true;
-}
diff --git a/src/adplug/core/msc.h b/src/adplug/core/msc.h
index fbdf3a97c881..67b3fb594e77 100644
--- a/src/adplug/core/msc.h
+++ b/src/adplug/core/msc.h
@@ -32,7 +32,7 @@ public:
CmscPlayer (Copl * newopl);
~CmscPlayer ();
- bool load (VFSFile *fd, const CFileProvider &fp);
+ bool load (VFSFile &fd, const CFileProvider &fp);
bool update ();
void rewind (int subsong);
float getrefresh ();
diff --git a/src/adplug/core/mtk.cc b/src/adplug/core/mtk.cc
new file mode 100644
index 000000000000..dc7c321689e1
--- /dev/null
+++ b/src/adplug/core/mtk.cc
@@ -0,0 +1,168 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * mtk.cpp - MPU-401 Trakker Loader by Simon Peter (dn.tlp at gmx.net)
+ */
+
+#include <string.h>
+
+#include "mtk.h"
+
+/*** public methods **************************************/
+
+CPlayer *
+CmtkLoader::factory (Copl * newopl)
+{
+ return new CmtkLoader (newopl);
+}
+
+bool
+CmtkLoader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ struct
+ {
+ char id[18];
+ unsigned short crc, size;
+ } header;
+ struct mtkdata
+ {
+ char songname[34], composername[34], instname[0x80][34];
+ unsigned char insts[0x80][12], order[0x80], dummy,
+ patterns[0x32][0x40][9];
+ } *data;
+ unsigned char *cmp, *org;
+ unsigned int i;
+ unsigned long cmpsize, cmpptr = 0, orgptr = 0;
+ unsigned short ctrlbits = 0, ctrlmask = 0, cmd, cnt, offs;
+
+ // read header
+ f->readString (header.id, 18);
+ header.crc = f->readInt (2);
+ header.size = f->readInt (2);
+
+ // file validation section
+ if (strncmp (header.id, "mpu401tr\x92kk\xeer at data", 18))
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // load section
+ cmpsize = fp.filesize (f) - 22;
+ cmp = new unsigned char[cmpsize];
+ org = new unsigned char[header.size];
+ for (i = 0; i < cmpsize; i++)
+ cmp[i] = f->readInt (1);
+ fp.close (f);
+
+ while (cmpptr < cmpsize)
+ { // decompress
+ ctrlmask >>= 1;
+ if (!ctrlmask)
+ {
+ ctrlbits = cmp[cmpptr] + (cmp[cmpptr + 1] << 8);
+ cmpptr += 2;
+ ctrlmask = 0x8000;
+ }
+ if (!(ctrlbits & ctrlmask))
+ { // uncompressed data
+ if (orgptr >= header.size)
+ goto err;
+
+ org[orgptr] = cmp[cmpptr];
+ orgptr++;
+ cmpptr++;
+ continue;
+ }
+
+ // compressed data
+ cmd = (cmp[cmpptr] >> 4) & 0x0f;
+ cnt = cmp[cmpptr] & 0x0f;
+ cmpptr++;
+ switch (cmd)
+ {
+ case 0:
+ if (orgptr + cnt > header.size)
+ goto err;
+ cnt += 3;
+ memset (&org[orgptr], cmp[cmpptr], cnt);
+ cmpptr++;
+ orgptr += cnt;
+ break;
+
+ case 1:
+ if (orgptr + cnt > header.size)
+ goto err;
+ cnt += (cmp[cmpptr] << 4) + 19;
+ memset (&org[orgptr], cmp[++cmpptr], cnt);
+ cmpptr++;
+ orgptr += cnt;
+ break;
+
+ case 2:
+ if (orgptr + cnt > header.size)
+ goto err;
+ offs = (cnt + 3) + (cmp[cmpptr] << 4);
+ cnt = cmp[++cmpptr] + 16;
+ cmpptr++;
+ memcpy (&org[orgptr], &org[orgptr - offs], cnt);
+ orgptr += cnt;
+ break;
+
+ default:
+ if (orgptr + cmd > header.size)
+ goto err;
+ offs = (cnt + 3) + (cmp[cmpptr++] << 4);
+ memcpy (&org[orgptr], &org[orgptr - offs], cmd);
+ orgptr += cmd;
+ break;
+ }
+ }
+ delete[]cmp;
+ data = (struct mtkdata *) org;
+
+ // convert to HSC replay data
+ memset (title, 0, 34);
+ strncpy (title, data->songname + 1, 33);
+ memset (composer, 0, 34);
+ strncpy (composer, data->composername + 1, 33);
+ memset (instname, 0, 0x80 * 34);
+ for (i = 0; i < 0x80; i++)
+ strncpy (instname[i], data->instname[i] + 1, 33);
+ memcpy (instr, data->insts, 0x80 * 12);
+ memcpy (song, data->order, 0x80);
+ memcpy (patterns, data->patterns, header.size - 6084);
+ for (i = 0; i < 128; i++)
+ { // correct instruments
+ instr[i][2] ^= (instr[i][2] & 0x40) << 1;
+ instr[i][3] ^= (instr[i][3] & 0x40) << 1;
+ instr[i][11] >>= 4; // make unsigned
+ }
+
+ delete[]org;
+ rewind (0);
+ return true;
+
+err:
+ delete[]cmp;
+ delete[]org;
+ return false;
+}
diff --git a/src/adplug/core/mtk.cxx b/src/adplug/core/mtk.cxx
deleted file mode 100644
index f404b14f3ea5..000000000000
--- a/src/adplug/core/mtk.cxx
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * mtk.cpp - MPU-401 Trakker Loader by Simon Peter (dn.tlp at gmx.net)
- */
-
-#include <string.h>
-
-#include "mtk.h"
-
-/*** public methods **************************************/
-
-CPlayer *
-CmtkLoader::factory (Copl * newopl)
-{
- return new CmtkLoader (newopl);
-}
-
-bool
-CmtkLoader::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- struct
- {
- char id[18];
- unsigned short crc, size;
- } header;
- struct mtkdata
- {
- char songname[34], composername[34], instname[0x80][34];
- unsigned char insts[0x80][12], order[0x80], dummy,
- patterns[0x32][0x40][9];
- } *data;
- unsigned char *cmp, *org;
- unsigned int i;
- unsigned long cmpsize, cmpptr = 0, orgptr = 0;
- unsigned short ctrlbits = 0, ctrlmask = 0, cmd, cnt, offs;
-
- // read header
- f->readString (header.id, 18);
- header.crc = f->readInt (2);
- header.size = f->readInt (2);
-
- // file validation section
- if (strncmp (header.id, "mpu401tr\x92kk\xeer at data", 18))
- {
- fp.close (f);
- return false;
- }
-
- // load section
- cmpsize = fp.filesize (f) - 22;
- cmp = new unsigned char[cmpsize];
- org = new unsigned char[header.size];
- for (i = 0; i < cmpsize; i++)
- cmp[i] = f->readInt (1);
- fp.close (f);
-
- while (cmpptr < cmpsize)
- { // decompress
- ctrlmask >>= 1;
- if (!ctrlmask)
- {
- ctrlbits = cmp[cmpptr] + (cmp[cmpptr + 1] << 8);
- cmpptr += 2;
- ctrlmask = 0x8000;
- }
- if (!(ctrlbits & ctrlmask))
- { // uncompressed data
- if (orgptr >= header.size)
- goto err;
-
- org[orgptr] = cmp[cmpptr];
- orgptr++;
- cmpptr++;
- continue;
- }
-
- // compressed data
- cmd = (cmp[cmpptr] >> 4) & 0x0f;
- cnt = cmp[cmpptr] & 0x0f;
- cmpptr++;
- switch (cmd)
- {
- case 0:
- if (orgptr + cnt > header.size)
- goto err;
- cnt += 3;
- memset (&org[orgptr], cmp[cmpptr], cnt);
- cmpptr++;
- orgptr += cnt;
- break;
-
- case 1:
- if (orgptr + cnt > header.size)
- goto err;
- cnt += (cmp[cmpptr] << 4) + 19;
- memset (&org[orgptr], cmp[++cmpptr], cnt);
- cmpptr++;
- orgptr += cnt;
- break;
-
- case 2:
- if (orgptr + cnt > header.size)
- goto err;
- offs = (cnt + 3) + (cmp[cmpptr] << 4);
- cnt = cmp[++cmpptr] + 16;
- cmpptr++;
- memcpy (&org[orgptr], &org[orgptr - offs], cnt);
- orgptr += cnt;
- break;
-
- default:
- if (orgptr + cmd > header.size)
- goto err;
- offs = (cnt + 3) + (cmp[cmpptr++] << 4);
- memcpy (&org[orgptr], &org[orgptr - offs], cmd);
- orgptr += cmd;
- break;
- }
- }
- delete[]cmp;
- data = (struct mtkdata *) org;
-
- // convert to HSC replay data
- memset (title, 0, 34);
- strncpy (title, data->songname + 1, 33);
- memset (composer, 0, 34);
- strncpy (composer, data->composername + 1, 33);
- memset (instname, 0, 0x80 * 34);
- for (i = 0; i < 0x80; i++)
- strncpy (instname[i], data->instname[i] + 1, 33);
- memcpy (instr, data->insts, 0x80 * 12);
- memcpy (song, data->order, 0x80);
- memcpy (patterns, data->patterns, header.size - 6084);
- for (i = 0; i < 128; i++)
- { // correct instruments
- instr[i][2] ^= (instr[i][2] & 0x40) << 1;
- instr[i][3] ^= (instr[i][3] & 0x40) << 1;
- instr[i][11] >>= 4; // make unsigned
- }
-
- delete[]org;
- rewind (0);
- return true;
-
-err:
- delete[]cmp;
- delete[]org;
- return false;
-}
diff --git a/src/adplug/core/mtk.h b/src/adplug/core/mtk.h
index 30d12e94a845..4d68ac7f96f6 100644
--- a/src/adplug/core/mtk.h
+++ b/src/adplug/core/mtk.h
@@ -32,7 +32,7 @@ class CmtkLoader: public ChscPlayer
mtkmode = 1;
};
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
std::string gettype()
{ return std::string("MPU-401 Trakker"); };
diff --git a/src/adplug/core/player.cc b/src/adplug/core/player.cc
new file mode 100644
index 000000000000..a70d435bbbd7
--- /dev/null
+++ b/src/adplug/core/player.cc
@@ -0,0 +1,73 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * player.cpp - Replayer base class, by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include "player.h"
+#include "adplug.h"
+#include "silentopl.h"
+
+/***** CPlayer *****/
+
+const unsigned short
+CPlayer::note_table[12] =
+ { 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647, 686 };
+
+const unsigned char
+CPlayer::op_table[9] =
+ { 0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12 };
+
+CPlayer::CPlayer (Copl * newopl):opl (newopl), db (CAdPlug::database)
+{
+}
+
+CPlayer::~CPlayer ()
+{
+}
+
+unsigned long
+CPlayer::songlength (int subsong)
+{
+ CSilentopl tempopl;
+ Copl *saveopl = opl;
+ float slength = 0.0f;
+
+ // save original OPL from being overwritten
+ opl = &tempopl;
+
+ // get song length
+ rewind (subsong);
+ while (update () && slength < 600000) // song length limit: 10 minutes
+ slength += 1000.0f / getrefresh ();
+ rewind (subsong);
+
+ // restore original OPL and return
+ opl = saveopl;
+ return (unsigned long) slength;
+}
+
+void
+CPlayer::seek (unsigned long ms)
+{
+ float pos = 0.0f;
+
+ rewind ();
+ while (pos < ms && update ()) // seek to new position
+ pos += 1000 / getrefresh ();
+}
diff --git a/src/adplug/core/player.cxx b/src/adplug/core/player.cxx
deleted file mode 100644
index a70d435bbbd7..000000000000
--- a/src/adplug/core/player.cxx
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * player.cpp - Replayer base class, by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include "player.h"
-#include "adplug.h"
-#include "silentopl.h"
-
-/***** CPlayer *****/
-
-const unsigned short
-CPlayer::note_table[12] =
- { 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647, 686 };
-
-const unsigned char
-CPlayer::op_table[9] =
- { 0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12 };
-
-CPlayer::CPlayer (Copl * newopl):opl (newopl), db (CAdPlug::database)
-{
-}
-
-CPlayer::~CPlayer ()
-{
-}
-
-unsigned long
-CPlayer::songlength (int subsong)
-{
- CSilentopl tempopl;
- Copl *saveopl = opl;
- float slength = 0.0f;
-
- // save original OPL from being overwritten
- opl = &tempopl;
-
- // get song length
- rewind (subsong);
- while (update () && slength < 600000) // song length limit: 10 minutes
- slength += 1000.0f / getrefresh ();
- rewind (subsong);
-
- // restore original OPL and return
- opl = saveopl;
- return (unsigned long) slength;
-}
-
-void
-CPlayer::seek (unsigned long ms)
-{
- float pos = 0.0f;
-
- rewind ();
- while (pos < ms && update ()) // seek to new position
- pos += 1000 / getrefresh ();
-}
diff --git a/src/adplug/core/player.h b/src/adplug/core/player.h
index 0231f2f3e555..55472e38389b 100644
--- a/src/adplug/core/player.h
+++ b/src/adplug/core/player.h
@@ -37,7 +37,7 @@ public:
/***** Operational methods *****/
void seek(unsigned long ms);
- virtual bool load(VFSFile *fd, // loads file
+ virtual bool load(VFSFile &fd, // loads file
const CFileProvider &fp = CProvider_Filesystem()) = 0;
virtual bool update() = 0; // executes replay code for 1 tick
virtual void rewind(int subsong = -1) = 0; // rewinds to specified subsong
diff --git a/src/adplug/core/players.cc b/src/adplug/core/players.cc
new file mode 100644
index 000000000000..5553b77eb333
--- /dev/null
+++ b/src/adplug/core/players.cc
@@ -0,0 +1,107 @@
+/*
+ * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 Simon Peter <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * players.h - Players enumeration, by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "players.h"
+
+#include <libaudcore/audstrings.h>
+
+/***** CPlayerDesc *****/
+
+CPlayerDesc::CPlayerDesc()
+ : factory(0), extensions(0), extlength(0)
+{
+}
+
+CPlayerDesc::CPlayerDesc(const CPlayerDesc &pd)
+ : factory(pd.factory), filetype(pd.filetype), extlength(pd.extlength)
+{
+ if(pd.extensions) {
+ extensions = (char *)malloc(extlength);
+ memcpy(extensions, pd.extensions, extlength);
+ } else
+ extensions = 0;
+}
+
+CPlayerDesc::CPlayerDesc(Factory f, const std::string &type, const char *ext)
+ : factory(f), filetype(type), extensions(0)
+{
+ const char *i = ext;
+
+ // Determine length of passed extensions list
+ while(*i) i += strlen(i) + 1;
+ extlength = i - ext + 1; // length = difference between last and first char + 1
+
+ extensions = (char *)malloc(extlength);
+ memcpy(extensions, ext, extlength);
+}
+
+CPlayerDesc::~CPlayerDesc()
+{
+ if(extensions) free(extensions);
+}
+
+void CPlayerDesc::add_extension(const char *ext)
+{
+ unsigned long newlength = extlength + strlen(ext) + 1;
+
+ extensions = (char *)realloc(extensions, newlength);
+ strcpy(extensions + extlength - 1, ext);
+ extensions[newlength - 1] = '\0';
+ extlength = newlength;
+}
+
+const char *CPlayerDesc::get_extension(unsigned int n) const
+{
+ const char *i = extensions;
+ unsigned int j;
+
+ for(j = 0; j < n && (*i); j++, i += strlen(i) + 1) ;
+ return (*i != '\0' ? i : 0);
+}
+
+/***** CPlayers *****/
+
+const CPlayerDesc *CPlayers::lookup_filetype(const std::string &ftype) const
+{
+ const_iterator i;
+
+ for(i = begin(); i != end(); i++)
+ if((*i)->filetype == ftype)
+ return *i;
+
+ return 0;
+}
+
+const CPlayerDesc *CPlayers::lookup_extension(const std::string &extension) const
+{
+ const_iterator i;
+ unsigned int j;
+
+ for(i = begin(); i != end(); i++)
+ for(j = 0; (*i)->get_extension(j); j++)
+ if(!strcmp_nocase(extension.c_str(), (*i)->get_extension(j)))
+ return *i;
+
+ return 0;
+}
diff --git a/src/adplug/core/players.cxx b/src/adplug/core/players.cxx
deleted file mode 100644
index cf04e28cfcfb..000000000000
--- a/src/adplug/core/players.cxx
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * players.h - Players enumeration, by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "players.h"
-
-/***** CPlayerDesc *****/
-
-CPlayerDesc::CPlayerDesc()
- : factory(0), extensions(0), extlength(0)
-{
-}
-
-CPlayerDesc::CPlayerDesc(const CPlayerDesc &pd)
- : factory(pd.factory), filetype(pd.filetype), extlength(pd.extlength)
-{
- if(pd.extensions) {
- extensions = (char *)malloc(extlength);
- memcpy(extensions, pd.extensions, extlength);
- } else
- extensions = 0;
-}
-
-CPlayerDesc::CPlayerDesc(Factory f, const std::string &type, const char *ext)
- : factory(f), filetype(type), extensions(0)
-{
- const char *i = ext;
-
- // Determine length of passed extensions list
- while(*i) i += strlen(i) + 1;
- extlength = i - ext + 1; // length = difference between last and first char + 1
-
- extensions = (char *)malloc(extlength);
- memcpy(extensions, ext, extlength);
-}
-
-CPlayerDesc::~CPlayerDesc()
-{
- if(extensions) free(extensions);
-}
-
-void CPlayerDesc::add_extension(const char *ext)
-{
- unsigned long newlength = extlength + strlen(ext) + 1;
-
- extensions = (char *)realloc(extensions, newlength);
- strcpy(extensions + extlength - 1, ext);
- extensions[newlength - 1] = '\0';
- extlength = newlength;
-}
-
-const char *CPlayerDesc::get_extension(unsigned int n) const
-{
- const char *i = extensions;
- unsigned int j;
-
- for(j = 0; j < n && (*i); j++, i += strlen(i) + 1) ;
- return (*i != '\0' ? i : 0);
-}
-
-/***** CPlayers *****/
-
-const CPlayerDesc *CPlayers::lookup_filetype(const std::string &ftype) const
-{
- const_iterator i;
-
- for(i = begin(); i != end(); i++)
- if((*i)->filetype == ftype)
- return *i;
-
- return 0;
-}
-
-const CPlayerDesc *CPlayers::lookup_extension(const std::string &extension) const
-{
- const_iterator i;
- unsigned int j;
-
- for(i = begin(); i != end(); i++)
- for(j = 0; (*i)->get_extension(j); j++)
- if(!g_ascii_strcasecmp(extension.c_str(), (*i)->get_extension(j)))
- return *i;
-
- return 0;
-}
diff --git a/src/adplug/core/protrack.cc b/src/adplug/core/protrack.cc
new file mode 100644
index 000000000000..ba43cae143f3
--- /dev/null
+++ b/src/adplug/core/protrack.cc
@@ -0,0 +1,996 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * protrack.cpp - Generic Protracker Player
+ *
+ * NOTES:
+ * This is a generic Protracker-based formats player. It offers all Protracker
+ * features, plus a good set of extensions to be compatible to other Protracker
+ * derivatives. It is derived from the former SA2 player. If you got a
+ * Protracker-like format, this is most certainly the player you want to use.
+ */
+
+#include <string.h>
+
+#include "protrack.h"
+#include "debug.h"
+
+#define SPECIALARPLEN 256 // Standard length of special arpeggio lists
+#define JUMPMARKER 0x80 // Orderlist jump marker
+
+// SA2 compatible adlib note table
+const unsigned short
+CmodPlayer::sa2_notetable[12] =
+ { 340, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647 };
+
+// SA2 compatible vibrato rate table
+const unsigned char
+CmodPlayer::vibratotab[32] =
+ { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 15, 14, 13,
+12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
+
+/*** public methods *************************************/
+
+CmodPlayer::CmodPlayer (Copl * newopl):CPlayer (newopl), inst (0), order (0), arplist (0), arpcmd (0), initspeed (6),
+nop (0), activechan (0xffffffff), flags (Standard), curchip (opl->getchip ()),
+nrows (0), npats (0), nchans (0)
+{
+ realloc_order (128);
+ realloc_patterns (64, 64, 9);
+ realloc_instruments (250);
+ init_notetable (sa2_notetable);
+}
+
+CmodPlayer::~CmodPlayer ()
+{
+ dealloc ();
+}
+
+bool
+CmodPlayer::update ()
+{
+ unsigned char pattbreak = 0, donote, pattnr, chan, oplchan, info1,
+ info2, info, pattern_delay;
+ unsigned short track;
+ unsigned long row;
+
+ if (!speed) // song full stop
+ return !songend;
+
+ // effect handling (timer dependant)
+ for (chan = 0; chan < nchans; chan++)
+ {
+ oplchan = set_opl_chip (chan);
+
+ if (arplist && arpcmd && inst[channel[chan].inst].arpstart) // special arpeggio
+ {
+ if (channel[chan].arpspdcnt)
+ channel[chan].arpspdcnt--;
+ else if (arpcmd[channel[chan].arppos] != 255)
+ {
+ switch (arpcmd[channel[chan].arppos])
+ {
+ case 252:
+ channel[chan].vol1 = arplist[channel[chan].arppos]; // set volume
+ if (channel[chan].vol1 > 63) // ?????
+ channel[chan].vol1 = 63;
+ channel[chan].vol2 = channel[chan].vol1;
+ setvolume (chan);
+ break;
+ case 253:
+ channel[chan].key = 0;
+ setfreq (chan);
+ break; // release sustaining note
+ case 254:
+ channel[chan].arppos = arplist[channel[chan].arppos];
+ break; // arpeggio loop
+ default:
+ if (arpcmd[channel[chan].arppos])
+ {
+ if (arpcmd[channel[chan].arppos] / 10)
+ opl->write (0xe3 + op_table[oplchan],
+ arpcmd[channel[chan].arppos] / 10 - 1);
+ if (arpcmd[channel[chan].arppos] % 10)
+ opl->write (0xe0 + op_table[oplchan],
+ (arpcmd[channel[chan].arppos] % 10) - 1);
+ if (arpcmd[channel[chan].arppos] < 10) // ?????
+ opl->write (0xe0 + op_table[oplchan],
+ arpcmd[channel[chan].arppos] - 1);
+ }
+ }
+ if (arpcmd[channel[chan].arppos] != 252)
+ {
+ if (arplist[channel[chan].arppos] <= 96)
+ setnote (chan,
+ channel[chan].note + arplist[channel[chan].arppos]);
+ if (arplist[channel[chan].arppos] >= 100)
+ setnote (chan, arplist[channel[chan].arppos] - 100);
+ }
+ else
+ setnote (chan, channel[chan].note);
+ setfreq (chan);
+ if (arpcmd[channel[chan].arppos] != 255)
+ channel[chan].arppos++;
+ channel[chan].arpspdcnt = inst[channel[chan].inst].arpspeed - 1;
+ }
+ }
+
+ info1 = channel[chan].info1;
+ info2 = channel[chan].info2;
+ if (flags & Decimal)
+ info = channel[chan].info1 * 10 + channel[chan].info2;
+ else
+ info = (channel[chan].info1 << 4) + channel[chan].info2;
+ switch (channel[chan].fx)
+ {
+ case 0:
+ if (info)
+ { // arpeggio
+ if (channel[chan].trigger < 2)
+ channel[chan].trigger++;
+ else
+ channel[chan].trigger = 0;
+ switch (channel[chan].trigger)
+ {
+ case 0:
+ setnote (chan, channel[chan].note);
+ break;
+ case 1:
+ setnote (chan, channel[chan].note + info1);
+ break;
+ case 2:
+ setnote (chan, channel[chan].note + info2);
+ }
+ setfreq (chan);
+ }
+ break;
+ case 1:
+ slide_up (chan, info);
+ setfreq (chan);
+ break; // slide up
+ case 2:
+ slide_down (chan, info);
+ setfreq (chan);
+ break; // slide down
+ case 3:
+ tone_portamento (chan, channel[chan].portainfo);
+ break; // tone portamento
+ case 4:
+ vibrato (chan, channel[chan].vibinfo1, channel[chan].vibinfo2);
+ break; // vibrato
+ case 5: // tone portamento & volume slide
+ case 6:
+ if (channel[chan].fx == 5) // vibrato & volume slide
+ tone_portamento (chan, channel[chan].portainfo);
+ else
+ vibrato (chan, channel[chan].vibinfo1, channel[chan].vibinfo2);
+ case 10:
+ if (del % 4) // SA2 volume slide
+ break;
+ if (info1)
+ vol_up (chan, info1);
+ else
+ vol_down (chan, info2);
+ setvolume (chan);
+ break;
+ case 14:
+ if (info1 == 3) // retrig note
+ if (!(del % (info2 + 1)))
+ playnote (chan);
+ break;
+ case 16:
+ if (del % 4) // AMD volume slide
+ break;
+ if (info1)
+ vol_up_alt (chan, info1);
+ else
+ vol_down_alt (chan, info2);
+ setvolume (chan);
+ break;
+ case 20: // RAD volume slide
+ if (info < 50)
+ vol_down_alt (chan, info);
+ else
+ vol_up_alt (chan, info - 50);
+ setvolume (chan);
+ break;
+ case 26: // volume slide
+ if (info1)
+ vol_up (chan, info1);
+ else
+ vol_down (chan, info2);
+ setvolume (chan);
+ break;
+ case 28:
+ if (info1)
+ {
+ slide_up (chan, 1);
+ channel[chan].info1--;
+ }
+ if (info2)
+ {
+ slide_down (chan, 1);
+ channel[chan].info2--;
+ }
+ setfreq (chan);
+ break;
+ }
+ }
+
+ if (del)
+ { // speed compensation
+ del--;
+ return !songend;
+ }
+
+ // arrangement handling
+ if (!resolve_order ())
+ return !songend;
+ pattnr = order[ord];
+
+ if (!rw)
+ AdPlug_LogWrite ("\nCmodPlayer::update(): Pattern: %d, Order: %d\n",
+ pattnr, ord);
+ AdPlug_LogWrite ("CmodPlayer::update():%3d|", rw);
+
+ // play row
+ pattern_delay = 0;
+ row = rw;
+ for (chan = 0; chan < nchans; chan++)
+ {
+ oplchan = set_opl_chip (chan);
+
+ if (!(activechan >> (31 - chan)) & 1)
+ { // channel active?
+ AdPlug_LogWrite ("N/A|");
+ continue;
+ }
+ if (!(track = trackord[pattnr][chan]))
+ { // resolve track
+ AdPlug_LogWrite ("------------|");
+ continue;
+ }
+ else
+ track--;
+
+ if (track >= npats*nchans) { // prevent overflow
+ songend = 1;
+ return !songend;
+ }
+ AdPlug_LogWrite ("%3d%3d%2X%2X%2X|", tracks[track][row].note,
+ tracks[track][row].inst, tracks[track][row].command,
+ tracks[track][row].param1, tracks[track][row].param2);
+
+ donote = 0;
+ if (tracks[track][row].inst)
+ {
+ channel[chan].inst = tracks[track][row].inst - 1;
+ if (!(flags & Faust))
+ {
+ channel[chan].vol1 = 63 - (inst[channel[chan].inst].data[10] & 63);
+ channel[chan].vol2 = 63 - (inst[channel[chan].inst].data[9] & 63);
+ setvolume (chan);
+ }
+ }
+
+ if (tracks[track][row].note && tracks[track][row].command != 3)
+ { // no tone portamento
+ channel[chan].note = tracks[track][row].note;
+ setnote (chan, tracks[track][row].note);
+ channel[chan].nextfreq = channel[chan].freq;
+ channel[chan].nextoct = channel[chan].oct;
+ channel[chan].arppos = inst[channel[chan].inst].arpstart;
+ channel[chan].arpspdcnt = 0;
+ if (tracks[track][row].note != 127) // handle key off
+ donote = 1;
+ }
+ channel[chan].fx = tracks[track][row].command;
+ channel[chan].info1 = tracks[track][row].param1;
+ channel[chan].info2 = tracks[track][row].param2;
+
+ if (donote)
+ playnote (chan);
+
+ // command handling (row dependant)
+ info1 = channel[chan].info1;
+ info2 = channel[chan].info2;
+ if (flags & Decimal)
+ info = channel[chan].info1 * 10 + channel[chan].info2;
+ else
+ info = (channel[chan].info1 << 4) + channel[chan].info2;
+ switch (channel[chan].fx)
+ {
+ case 3: // tone portamento
+ if (tracks[track][row].note)
+ {
+ if (tracks[track][row].note < 13)
+ channel[chan].nextfreq = notetable[tracks[track][row].note - 1];
+ else if (tracks[track][row].note % 12 > 0)
+ channel[chan].nextfreq =
+ notetable[(tracks[track][row].note % 12) - 1];
+ else
+ channel[chan].nextfreq = notetable[11];
+ channel[chan].nextoct = (tracks[track][row].note - 1) / 12;
+ if (tracks[track][row].note == 127)
+ { // handle key off
+ channel[chan].nextfreq = channel[chan].freq;
+ channel[chan].nextoct = channel[chan].oct;
+ }
+ }
+ if (info) // remember vars
+ channel[chan].portainfo = info;
+ break;
+
+ case 4: // vibrato (remember vars)
+ if (info)
+ {
+ channel[chan].vibinfo1 = info1;
+ channel[chan].vibinfo2 = info2;
+ }
+ break;
+
+ case 7:
+ tempo = info;
+ break; // set tempo
+
+ case 8:
+ channel[chan].key = 0;
+ setfreq (chan);
+ break; // release sustaining note
+
+ case 9: // set carrier/modulator volume
+ if (info1)
+ channel[chan].vol1 = info1 * 7;
+ else
+ channel[chan].vol2 = info2 * 7;
+ setvolume (chan);
+ break;
+
+ case 11: // position jump
+ pattbreak = 1;
+ rw = 0;
+ if (info < ord)
+ songend = 1;
+ ord = info;
+ break;
+
+ case 12: // set volume
+ channel[chan].vol1 = info;
+ channel[chan].vol2 = info;
+ if (channel[chan].vol1 > 63)
+ channel[chan].vol1 = 63;
+ if (channel[chan].vol2 > 63)
+ channel[chan].vol2 = 63;
+ setvolume (chan);
+ break;
+
+ case 13: // pattern break
+ if (!pattbreak)
+ {
+ pattbreak = 1;
+ rw = info;
+ ord++;
+ }
+ break;
+
+ case 14: // extended command
+ switch (info1)
+ {
+ case 0: // define cell-tremolo
+ if (info2)
+ regbd |= 128;
+ else
+ regbd &= 127;
+ opl->write (0xbd, regbd);
+ break;
+
+ case 1: // define cell-vibrato
+ if (info2)
+ regbd |= 64;
+ else
+ regbd &= 191;
+ opl->write (0xbd, regbd);
+ break;
+
+ case 4: // increase volume fine
+ vol_up_alt (chan, info2);
+ setvolume (chan);
+ break;
+
+ case 5: // decrease volume fine
+ vol_down_alt (chan, info2);
+ setvolume (chan);
+ break;
+
+ case 6: // manual slide up
+ slide_up (chan, info2);
+ setfreq (chan);
+ break;
+
+ case 7: // manual slide down
+ slide_down (chan, info2);
+ setfreq (chan);
+ break;
+
+ case 8: // pattern delay (rows)
+ pattern_delay = info2 * speed;
+ break;
+ }
+ break;
+
+ case 15: // SA2 set speed
+ if (info <= 0x1f)
+ speed = info;
+ if (info >= 0x32)
+ tempo = info;
+ if (!info)
+ songend = 1;
+ break;
+
+ case 17: // alternate set volume
+ channel[chan].vol1 = info;
+ if (channel[chan].vol1 > 63)
+ channel[chan].vol1 = 63;
+ if (inst[channel[chan].inst].data[0] & 1)
+ {
+ channel[chan].vol2 = info;
+ if (channel[chan].vol2 > 63)
+ channel[chan].vol2 = 63;
+ }
+
+ setvolume (chan);
+ break;
+
+ case 18: // AMD set speed
+ if (info <= 31 && info > 0)
+ speed = info;
+ if (info > 31 || !info)
+ tempo = info;
+ break;
+
+ case 19: // RAD/A2M set speed
+ speed = (info ? info : info + 1);
+ break;
+
+ case 21: // set modulator volume
+ if (info <= 63)
+ channel[chan].vol2 = info;
+ else
+ channel[chan].vol2 = 63;
+ setvolume (chan);
+ break;
+
+ case 22: // set carrier volume
+ if (info <= 63)
+ channel[chan].vol1 = info;
+ else
+ channel[chan].vol1 = 63;
+ setvolume (chan);
+ break;
+
+ case 23: // fine frequency slide up
+ slide_up (chan, info);
+ setfreq (chan);
+ break;
+
+ case 24: // fine frequency slide down
+ slide_down (chan, info);
+ setfreq (chan);
+ break;
+
+ case 25: // set carrier/modulator waveform
+ if (info1 != 0x0f)
+ opl->write (0xe3 + op_table[oplchan], info1);
+ if (info2 != 0x0f)
+ opl->write (0xe0 + op_table[oplchan], info2);
+ break;
+
+ case 27: // set chip tremolo/vibrato
+ if (info1)
+ regbd |= 128;
+ else
+ regbd &= 127;
+ if (info2)
+ regbd |= 64;
+ else
+ regbd &= 191;
+ opl->write (0xbd, regbd);
+ break;
+
+ case 29: // pattern delay (frames)
+ pattern_delay = info;
+ break;
+ }
+ }
+
+ // speed compensation
+ del = speed - 1 + pattern_delay;
+
+ if (!pattbreak)
+ { // next row (only if no manual advance)
+ rw++;
+ if (rw >= nrows)
+ {
+ rw = 0;
+ ord++;
+ }
+ }
+
+ resolve_order (); // so we can report songend right away
+ AdPlug_LogWrite ("\n");
+ return !songend;
+}
+
+unsigned char
+CmodPlayer::set_opl_chip (unsigned char chan)
+ /*
+ * Sets OPL chip according to channel number. Channels 0-8 are on first chip,
+ * channels 9-17 are on second chip. Returns corresponding OPL channel
+ * number.
+ */
+{
+ int newchip = chan < 9 ? 0 : 1;
+
+ if (newchip != curchip)
+ {
+ opl->setchip (newchip);
+ curchip = newchip;
+ }
+
+ return chan % 9;
+}
+
+bool
+CmodPlayer::resolve_order ()
+ /*
+ * Resolves current orderlist entry, checking for jumps and loops.
+ *
+ * Returns true on correct processing, false if immediate recursive loop
+ * has been detected.
+ */
+{
+ if (ord < length)
+ {
+ while (order[ord] >= JUMPMARKER)
+ { // jump to order
+ unsigned long neword = order[ord] - JUMPMARKER;
+
+ if (neword <= ord)
+ songend = 1;
+ if (neword == ord)
+ return false;
+ ord = neword;
+ }
+ }
+ else
+ {
+ songend = 1;
+ ord = restartpos;
+ }
+
+ return true;
+}
+
+void
+CmodPlayer::rewind (int subsong)
+{
+ unsigned long i;
+
+ // Reset playing variables
+ songend = del = ord = rw = regbd = 0;
+ tempo = bpm;
+ speed = initspeed;
+
+ // Reset channel data
+ memset (channel, 0, sizeof (Channel) * nchans);
+
+ // Compute number of patterns, if needed
+ if (!nop)
+ for (i = 0; i < length; i++)
+ nop = (order[i] > nop ? order[i] : nop);
+
+ opl->init (); // Reset OPL chip
+ opl->write (1, 32); // Go to ym3812 mode
+
+ // Enable OPL3 extensions if flagged
+ if (flags & Opl3)
+ {
+ opl->setchip (1);
+ opl->write (1, 32);
+ opl->write (5, 1);
+ opl->setchip (0);
+ }
+
+ // Enable tremolo/vibrato depth if flagged
+ if (flags & Tremolo)
+ regbd |= 128;
+ if (flags & Vibrato)
+ regbd |= 64;
+ if (regbd)
+ opl->write (0xbd, regbd);
+}
+
+float
+CmodPlayer::getrefresh ()
+{
+ return (float) (tempo / 2.5);
+}
+
+void
+CmodPlayer::init_trackord ()
+{
+ unsigned long i;
+
+ for (i = 0; i < npats * nchans; i++)
+ trackord[i / nchans][i % nchans] = i + 1;
+}
+
+bool
+CmodPlayer::init_specialarp ()
+{
+ arplist = new unsigned char[SPECIALARPLEN];
+ arpcmd = new unsigned char[SPECIALARPLEN];
+
+ return true;
+}
+
+void
+CmodPlayer::init_notetable (const unsigned short *newnotetable)
+{
+ memcpy (notetable, newnotetable, 12 * 2);
+}
+
+bool
+CmodPlayer::realloc_order (unsigned long len)
+{
+ if (order)
+ delete[]order;
+ order = new unsigned char[len];
+ return true;
+}
+
+bool
+CmodPlayer::realloc_patterns (unsigned long pats, unsigned long rows,
+ unsigned long chans)
+{
+ unsigned long i;
+
+ dealloc_patterns ();
+
+ // set new number of tracks, rows and channels
+ npats = pats;
+ nrows = rows;
+ nchans = chans;
+
+ // alloc new patterns
+ tracks = new Tracks *[pats * chans];
+ for (i = 0; i < pats * chans; i++)
+ tracks[i] = new Tracks[rows];
+ trackord = new unsigned short *[pats];
+ for (i = 0; i < pats; i++)
+ trackord[i] = new unsigned short[chans];
+ channel = new Channel[chans];
+
+ // initialize new patterns
+ for (i = 0; i < pats * chans; i++)
+ memset (tracks[i], 0, sizeof (Tracks) * rows);
+ for (i = 0; i < pats; i++)
+ memset (trackord[i], 0, chans * 2);
+
+ return true;
+}
+
+void
+CmodPlayer::dealloc_patterns ()
+{
+ unsigned long i;
+
+ // dealloc everything previously allocated
+ if (npats && nrows && nchans)
+ {
+ for (i = 0; i < npats * nchans; i++)
+ delete[]tracks[i];
+ delete[]tracks;
+ for (i = 0; i < npats; i++)
+ delete[]trackord[i];
+ delete[]trackord;
+ delete[]channel;
+ }
+}
+
+bool
+CmodPlayer::realloc_instruments (unsigned long len)
+{
+ // dealloc previous instance, if any
+ if (inst)
+ delete[]inst;
+
+ inst = new Instrument[len];
+ memset (inst, 0, sizeof (Instrument) * len); // reset instruments
+ return true;
+}
+
+void
+CmodPlayer::dealloc ()
+{
+ if (inst)
+ delete[]inst;
+ if (order)
+ delete[]order;
+ if (arplist)
+ delete[]arplist;
+ if (arpcmd)
+ delete[]arpcmd;
+ dealloc_patterns ();
+}
+
+/*** private methods *************************************/
+
+void
+CmodPlayer::setvolume (unsigned char chan)
+{
+ unsigned char oplchan = set_opl_chip (chan);
+
+ if (flags & Faust)
+ setvolume_alt (chan);
+ else
+ {
+ opl->write (0x40 + op_table[oplchan],
+ 63 - channel[chan].vol2 +
+ (inst[channel[chan].inst].data[9] & 192));
+ opl->write (0x43 + op_table[oplchan],
+ 63 - channel[chan].vol1 +
+ (inst[channel[chan].inst].data[10] & 192));
+ }
+}
+
+void
+CmodPlayer::setvolume_alt (unsigned char chan)
+{
+ unsigned char oplchan = set_opl_chip (chan);
+ unsigned char ivol2 = inst[channel[chan].inst].data[9] & 63;
+ unsigned char ivol1 = inst[channel[chan].inst].data[10] & 63;
+
+ opl->write (0x40 + op_table[oplchan],
+ (((63 - (channel[chan].vol2 & 63)) + ivol2) >> 1) +
+ (inst[channel[chan].inst].data[9] & 192));
+ opl->write (0x43 + op_table[oplchan],
+ (((63 - (channel[chan].vol1 & 63)) + ivol1) >> 1) +
+ (inst[channel[chan].inst].data[10] & 192));
+}
+
+void
+CmodPlayer::setfreq (unsigned char chan)
+{
+ unsigned char oplchan = set_opl_chip (chan);
+
+ opl->write (0xa0 + oplchan, channel[chan].freq & 255);
+ if (channel[chan].key)
+ opl->write (0xb0 + oplchan,
+ ((channel[chan].freq & 768) >> 8) +
+ ((channel[chan].oct << 2) | 32));
+ else
+ opl->write (0xb0 + oplchan,
+ ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2));
+}
+
+void
+CmodPlayer::playnote (unsigned char chan)
+{
+ unsigned char oplchan = set_opl_chip (chan);
+ unsigned char op = op_table[oplchan], insnr = channel[chan].inst;
+
+ if (!(flags & NoKeyOn))
+ opl->write (0xb0 + oplchan, 0); // stop old note
+
+ // set instrument data
+ opl->write (0x20 + op, inst[insnr].data[1]);
+ opl->write (0x23 + op, inst[insnr].data[2]);
+ opl->write (0x60 + op, inst[insnr].data[3]);
+ opl->write (0x63 + op, inst[insnr].data[4]);
+ opl->write (0x80 + op, inst[insnr].data[5]);
+ opl->write (0x83 + op, inst[insnr].data[6]);
+ opl->write (0xe0 + op, inst[insnr].data[7]);
+ opl->write (0xe3 + op, inst[insnr].data[8]);
+ opl->write (0xc0 + oplchan, inst[insnr].data[0]);
+ opl->write (0xbd, inst[insnr].misc); // set misc. register
+
+ // set frequency, volume & play
+ channel[chan].key = 1;
+ setfreq (chan);
+
+ if (flags & Faust)
+ {
+ channel[chan].vol2 = 63;
+ channel[chan].vol1 = 63;
+ }
+ setvolume (chan);
+}
+
+void
+CmodPlayer::setnote (unsigned char chan, int note)
+{
+ if (note > 96)
+ {
+ if (note == 127)
+ { // key off
+ channel[chan].key = 0;
+ setfreq (chan);
+ return;
+ }
+ else
+ note = 96;
+ }
+
+ if (note < 13)
+ channel[chan].freq = notetable[note - 1];
+ else if (note % 12 > 0)
+ channel[chan].freq = notetable[(note % 12) - 1];
+ else
+ channel[chan].freq = notetable[11];
+ channel[chan].oct = (note - 1) / 12;
+ channel[chan].freq += inst[channel[chan].inst].slide; // apply pre-slide
+}
+
+void
+CmodPlayer::slide_down (unsigned char chan, int amount)
+{
+ channel[chan].freq -= amount;
+ if (channel[chan].freq <= 342)
+ {
+ if (channel[chan].oct)
+ {
+ channel[chan].oct--;
+ channel[chan].freq <<= 1;
+ }
+ else
+ channel[chan].freq = 342;
+ }
+}
+
+void
+CmodPlayer::slide_up (unsigned char chan, int amount)
+{
+ channel[chan].freq += amount;
+ if (channel[chan].freq >= 686)
+ {
+ if (channel[chan].oct < 7)
+ {
+ channel[chan].oct++;
+ channel[chan].freq >>= 1;
+ }
+ else
+ channel[chan].freq = 686;
+ }
+}
+
+void
+CmodPlayer::tone_portamento (unsigned char chan, unsigned char info)
+{
+ if (channel[chan].freq + (channel[chan].oct << 10) <
+ channel[chan].nextfreq + (channel[chan].nextoct << 10))
+ {
+ slide_up (chan, info);
+ if (channel[chan].freq + (channel[chan].oct << 10) >
+ channel[chan].nextfreq + (channel[chan].nextoct << 10))
+ {
+ channel[chan].freq = channel[chan].nextfreq;
+ channel[chan].oct = channel[chan].nextoct;
+ }
+ }
+ if (channel[chan].freq + (channel[chan].oct << 10) >
+ channel[chan].nextfreq + (channel[chan].nextoct << 10))
+ {
+ slide_down (chan, info);
+ if (channel[chan].freq + (channel[chan].oct << 10) <
+ channel[chan].nextfreq + (channel[chan].nextoct << 10))
+ {
+ channel[chan].freq = channel[chan].nextfreq;
+ channel[chan].oct = channel[chan].nextoct;
+ }
+ }
+ setfreq (chan);
+}
+
+void
+CmodPlayer::vibrato (unsigned char chan, unsigned char speed,
+ unsigned char depth)
+{
+ int i;
+
+ if (!speed || !depth)
+ return;
+
+ if (depth > 14)
+ depth = 14;
+
+ for (i = 0; i < speed; i++)
+ {
+ channel[chan].trigger++;
+ while (channel[chan].trigger >= 64)
+ channel[chan].trigger -= 64;
+ if (channel[chan].trigger >= 16 && channel[chan].trigger < 48)
+ slide_down (chan,
+ vibratotab[channel[chan].trigger - 16] / (16 - depth));
+ if (channel[chan].trigger < 16)
+ slide_up (chan, vibratotab[channel[chan].trigger + 16] / (16 - depth));
+ if (channel[chan].trigger >= 48)
+ slide_up (chan, vibratotab[channel[chan].trigger - 48] / (16 - depth));
+ }
+ setfreq (chan);
+}
+
+void
+CmodPlayer::vol_up (unsigned char chan, int amount)
+{
+ if (channel[chan].vol1 + amount < 63)
+ channel[chan].vol1 += amount;
+ else
+ channel[chan].vol1 = 63;
+
+ if (channel[chan].vol2 + amount < 63)
+ channel[chan].vol2 += amount;
+ else
+ channel[chan].vol2 = 63;
+}
+
+void
+CmodPlayer::vol_down (unsigned char chan, int amount)
+{
+ if (channel[chan].vol1 - amount > 0)
+ channel[chan].vol1 -= amount;
+ else
+ channel[chan].vol1 = 0;
+
+ if (channel[chan].vol2 - amount > 0)
+ channel[chan].vol2 -= amount;
+ else
+ channel[chan].vol2 = 0;
+}
+
+void
+CmodPlayer::vol_up_alt (unsigned char chan, int amount)
+{
+ if (channel[chan].vol1 + amount < 63)
+ channel[chan].vol1 += amount;
+ else
+ channel[chan].vol1 = 63;
+ if (inst[channel[chan].inst].data[0] & 1)
+ {
+ if (channel[chan].vol2 + amount < 63)
+ channel[chan].vol2 += amount;
+ else
+ channel[chan].vol2 = 63;
+ }
+}
+
+void
+CmodPlayer::vol_down_alt (unsigned char chan, int amount)
+{
+ if (channel[chan].vol1 - amount > 0)
+ channel[chan].vol1 -= amount;
+ else
+ channel[chan].vol1 = 0;
+ if (inst[channel[chan].inst].data[0] & 1)
+ {
+ if (channel[chan].vol2 - amount > 0)
+ channel[chan].vol2 -= amount;
+ else
+ channel[chan].vol2 = 0;
+ }
+}
diff --git a/src/adplug/core/protrack.cxx b/src/adplug/core/protrack.cxx
deleted file mode 100644
index ba43cae143f3..000000000000
--- a/src/adplug/core/protrack.cxx
+++ /dev/null
@@ -1,996 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * protrack.cpp - Generic Protracker Player
- *
- * NOTES:
- * This is a generic Protracker-based formats player. It offers all Protracker
- * features, plus a good set of extensions to be compatible to other Protracker
- * derivatives. It is derived from the former SA2 player. If you got a
- * Protracker-like format, this is most certainly the player you want to use.
- */
-
-#include <string.h>
-
-#include "protrack.h"
-#include "debug.h"
-
-#define SPECIALARPLEN 256 // Standard length of special arpeggio lists
-#define JUMPMARKER 0x80 // Orderlist jump marker
-
-// SA2 compatible adlib note table
-const unsigned short
-CmodPlayer::sa2_notetable[12] =
- { 340, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647 };
-
-// SA2 compatible vibrato rate table
-const unsigned char
-CmodPlayer::vibratotab[32] =
- { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 15, 14, 13,
-12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
-
-/*** public methods *************************************/
-
-CmodPlayer::CmodPlayer (Copl * newopl):CPlayer (newopl), inst (0), order (0), arplist (0), arpcmd (0), initspeed (6),
-nop (0), activechan (0xffffffff), flags (Standard), curchip (opl->getchip ()),
-nrows (0), npats (0), nchans (0)
-{
- realloc_order (128);
- realloc_patterns (64, 64, 9);
- realloc_instruments (250);
- init_notetable (sa2_notetable);
-}
-
-CmodPlayer::~CmodPlayer ()
-{
- dealloc ();
-}
-
-bool
-CmodPlayer::update ()
-{
- unsigned char pattbreak = 0, donote, pattnr, chan, oplchan, info1,
- info2, info, pattern_delay;
- unsigned short track;
- unsigned long row;
-
- if (!speed) // song full stop
- return !songend;
-
- // effect handling (timer dependant)
- for (chan = 0; chan < nchans; chan++)
- {
- oplchan = set_opl_chip (chan);
-
- if (arplist && arpcmd && inst[channel[chan].inst].arpstart) // special arpeggio
- {
- if (channel[chan].arpspdcnt)
- channel[chan].arpspdcnt--;
- else if (arpcmd[channel[chan].arppos] != 255)
- {
- switch (arpcmd[channel[chan].arppos])
- {
- case 252:
- channel[chan].vol1 = arplist[channel[chan].arppos]; // set volume
- if (channel[chan].vol1 > 63) // ?????
- channel[chan].vol1 = 63;
- channel[chan].vol2 = channel[chan].vol1;
- setvolume (chan);
- break;
- case 253:
- channel[chan].key = 0;
- setfreq (chan);
- break; // release sustaining note
- case 254:
- channel[chan].arppos = arplist[channel[chan].arppos];
- break; // arpeggio loop
- default:
- if (arpcmd[channel[chan].arppos])
- {
- if (arpcmd[channel[chan].arppos] / 10)
- opl->write (0xe3 + op_table[oplchan],
- arpcmd[channel[chan].arppos] / 10 - 1);
- if (arpcmd[channel[chan].arppos] % 10)
- opl->write (0xe0 + op_table[oplchan],
- (arpcmd[channel[chan].arppos] % 10) - 1);
- if (arpcmd[channel[chan].arppos] < 10) // ?????
- opl->write (0xe0 + op_table[oplchan],
- arpcmd[channel[chan].arppos] - 1);
- }
- }
- if (arpcmd[channel[chan].arppos] != 252)
- {
- if (arplist[channel[chan].arppos] <= 96)
- setnote (chan,
- channel[chan].note + arplist[channel[chan].arppos]);
- if (arplist[channel[chan].arppos] >= 100)
- setnote (chan, arplist[channel[chan].arppos] - 100);
- }
- else
- setnote (chan, channel[chan].note);
- setfreq (chan);
- if (arpcmd[channel[chan].arppos] != 255)
- channel[chan].arppos++;
- channel[chan].arpspdcnt = inst[channel[chan].inst].arpspeed - 1;
- }
- }
-
- info1 = channel[chan].info1;
- info2 = channel[chan].info2;
- if (flags & Decimal)
- info = channel[chan].info1 * 10 + channel[chan].info2;
- else
- info = (channel[chan].info1 << 4) + channel[chan].info2;
- switch (channel[chan].fx)
- {
- case 0:
- if (info)
- { // arpeggio
- if (channel[chan].trigger < 2)
- channel[chan].trigger++;
- else
- channel[chan].trigger = 0;
- switch (channel[chan].trigger)
- {
- case 0:
- setnote (chan, channel[chan].note);
- break;
- case 1:
- setnote (chan, channel[chan].note + info1);
- break;
- case 2:
- setnote (chan, channel[chan].note + info2);
- }
- setfreq (chan);
- }
- break;
- case 1:
- slide_up (chan, info);
- setfreq (chan);
- break; // slide up
- case 2:
- slide_down (chan, info);
- setfreq (chan);
- break; // slide down
- case 3:
- tone_portamento (chan, channel[chan].portainfo);
- break; // tone portamento
- case 4:
- vibrato (chan, channel[chan].vibinfo1, channel[chan].vibinfo2);
- break; // vibrato
- case 5: // tone portamento & volume slide
- case 6:
- if (channel[chan].fx == 5) // vibrato & volume slide
- tone_portamento (chan, channel[chan].portainfo);
- else
- vibrato (chan, channel[chan].vibinfo1, channel[chan].vibinfo2);
- case 10:
- if (del % 4) // SA2 volume slide
- break;
- if (info1)
- vol_up (chan, info1);
- else
- vol_down (chan, info2);
- setvolume (chan);
- break;
- case 14:
- if (info1 == 3) // retrig note
- if (!(del % (info2 + 1)))
- playnote (chan);
- break;
- case 16:
- if (del % 4) // AMD volume slide
- break;
- if (info1)
- vol_up_alt (chan, info1);
- else
- vol_down_alt (chan, info2);
- setvolume (chan);
- break;
- case 20: // RAD volume slide
- if (info < 50)
- vol_down_alt (chan, info);
- else
- vol_up_alt (chan, info - 50);
- setvolume (chan);
- break;
- case 26: // volume slide
- if (info1)
- vol_up (chan, info1);
- else
- vol_down (chan, info2);
- setvolume (chan);
- break;
- case 28:
- if (info1)
- {
- slide_up (chan, 1);
- channel[chan].info1--;
- }
- if (info2)
- {
- slide_down (chan, 1);
- channel[chan].info2--;
- }
- setfreq (chan);
- break;
- }
- }
-
- if (del)
- { // speed compensation
- del--;
- return !songend;
- }
-
- // arrangement handling
- if (!resolve_order ())
- return !songend;
- pattnr = order[ord];
-
- if (!rw)
- AdPlug_LogWrite ("\nCmodPlayer::update(): Pattern: %d, Order: %d\n",
- pattnr, ord);
- AdPlug_LogWrite ("CmodPlayer::update():%3d|", rw);
-
- // play row
- pattern_delay = 0;
- row = rw;
- for (chan = 0; chan < nchans; chan++)
- {
- oplchan = set_opl_chip (chan);
-
- if (!(activechan >> (31 - chan)) & 1)
- { // channel active?
- AdPlug_LogWrite ("N/A|");
- continue;
- }
- if (!(track = trackord[pattnr][chan]))
- { // resolve track
- AdPlug_LogWrite ("------------|");
- continue;
- }
- else
- track--;
-
- if (track >= npats*nchans) { // prevent overflow
- songend = 1;
- return !songend;
- }
- AdPlug_LogWrite ("%3d%3d%2X%2X%2X|", tracks[track][row].note,
- tracks[track][row].inst, tracks[track][row].command,
- tracks[track][row].param1, tracks[track][row].param2);
-
- donote = 0;
- if (tracks[track][row].inst)
- {
- channel[chan].inst = tracks[track][row].inst - 1;
- if (!(flags & Faust))
- {
- channel[chan].vol1 = 63 - (inst[channel[chan].inst].data[10] & 63);
- channel[chan].vol2 = 63 - (inst[channel[chan].inst].data[9] & 63);
- setvolume (chan);
- }
- }
-
- if (tracks[track][row].note && tracks[track][row].command != 3)
- { // no tone portamento
- channel[chan].note = tracks[track][row].note;
- setnote (chan, tracks[track][row].note);
- channel[chan].nextfreq = channel[chan].freq;
- channel[chan].nextoct = channel[chan].oct;
- channel[chan].arppos = inst[channel[chan].inst].arpstart;
- channel[chan].arpspdcnt = 0;
- if (tracks[track][row].note != 127) // handle key off
- donote = 1;
- }
- channel[chan].fx = tracks[track][row].command;
- channel[chan].info1 = tracks[track][row].param1;
- channel[chan].info2 = tracks[track][row].param2;
-
- if (donote)
- playnote (chan);
-
- // command handling (row dependant)
- info1 = channel[chan].info1;
- info2 = channel[chan].info2;
- if (flags & Decimal)
- info = channel[chan].info1 * 10 + channel[chan].info2;
- else
- info = (channel[chan].info1 << 4) + channel[chan].info2;
- switch (channel[chan].fx)
- {
- case 3: // tone portamento
- if (tracks[track][row].note)
- {
- if (tracks[track][row].note < 13)
- channel[chan].nextfreq = notetable[tracks[track][row].note - 1];
- else if (tracks[track][row].note % 12 > 0)
- channel[chan].nextfreq =
- notetable[(tracks[track][row].note % 12) - 1];
- else
- channel[chan].nextfreq = notetable[11];
- channel[chan].nextoct = (tracks[track][row].note - 1) / 12;
- if (tracks[track][row].note == 127)
- { // handle key off
- channel[chan].nextfreq = channel[chan].freq;
- channel[chan].nextoct = channel[chan].oct;
- }
- }
- if (info) // remember vars
- channel[chan].portainfo = info;
- break;
-
- case 4: // vibrato (remember vars)
- if (info)
- {
- channel[chan].vibinfo1 = info1;
- channel[chan].vibinfo2 = info2;
- }
- break;
-
- case 7:
- tempo = info;
- break; // set tempo
-
- case 8:
- channel[chan].key = 0;
- setfreq (chan);
- break; // release sustaining note
-
- case 9: // set carrier/modulator volume
- if (info1)
- channel[chan].vol1 = info1 * 7;
- else
- channel[chan].vol2 = info2 * 7;
- setvolume (chan);
- break;
-
- case 11: // position jump
- pattbreak = 1;
- rw = 0;
- if (info < ord)
- songend = 1;
- ord = info;
- break;
-
- case 12: // set volume
- channel[chan].vol1 = info;
- channel[chan].vol2 = info;
- if (channel[chan].vol1 > 63)
- channel[chan].vol1 = 63;
- if (channel[chan].vol2 > 63)
- channel[chan].vol2 = 63;
- setvolume (chan);
- break;
-
- case 13: // pattern break
- if (!pattbreak)
- {
- pattbreak = 1;
- rw = info;
- ord++;
- }
- break;
-
- case 14: // extended command
- switch (info1)
- {
- case 0: // define cell-tremolo
- if (info2)
- regbd |= 128;
- else
- regbd &= 127;
- opl->write (0xbd, regbd);
- break;
-
- case 1: // define cell-vibrato
- if (info2)
- regbd |= 64;
- else
- regbd &= 191;
- opl->write (0xbd, regbd);
- break;
-
- case 4: // increase volume fine
- vol_up_alt (chan, info2);
- setvolume (chan);
- break;
-
- case 5: // decrease volume fine
- vol_down_alt (chan, info2);
- setvolume (chan);
- break;
-
- case 6: // manual slide up
- slide_up (chan, info2);
- setfreq (chan);
- break;
-
- case 7: // manual slide down
- slide_down (chan, info2);
- setfreq (chan);
- break;
-
- case 8: // pattern delay (rows)
- pattern_delay = info2 * speed;
- break;
- }
- break;
-
- case 15: // SA2 set speed
- if (info <= 0x1f)
- speed = info;
- if (info >= 0x32)
- tempo = info;
- if (!info)
- songend = 1;
- break;
-
- case 17: // alternate set volume
- channel[chan].vol1 = info;
- if (channel[chan].vol1 > 63)
- channel[chan].vol1 = 63;
- if (inst[channel[chan].inst].data[0] & 1)
- {
- channel[chan].vol2 = info;
- if (channel[chan].vol2 > 63)
- channel[chan].vol2 = 63;
- }
-
- setvolume (chan);
- break;
-
- case 18: // AMD set speed
- if (info <= 31 && info > 0)
- speed = info;
- if (info > 31 || !info)
- tempo = info;
- break;
-
- case 19: // RAD/A2M set speed
- speed = (info ? info : info + 1);
- break;
-
- case 21: // set modulator volume
- if (info <= 63)
- channel[chan].vol2 = info;
- else
- channel[chan].vol2 = 63;
- setvolume (chan);
- break;
-
- case 22: // set carrier volume
- if (info <= 63)
- channel[chan].vol1 = info;
- else
- channel[chan].vol1 = 63;
- setvolume (chan);
- break;
-
- case 23: // fine frequency slide up
- slide_up (chan, info);
- setfreq (chan);
- break;
-
- case 24: // fine frequency slide down
- slide_down (chan, info);
- setfreq (chan);
- break;
-
- case 25: // set carrier/modulator waveform
- if (info1 != 0x0f)
- opl->write (0xe3 + op_table[oplchan], info1);
- if (info2 != 0x0f)
- opl->write (0xe0 + op_table[oplchan], info2);
- break;
-
- case 27: // set chip tremolo/vibrato
- if (info1)
- regbd |= 128;
- else
- regbd &= 127;
- if (info2)
- regbd |= 64;
- else
- regbd &= 191;
- opl->write (0xbd, regbd);
- break;
-
- case 29: // pattern delay (frames)
- pattern_delay = info;
- break;
- }
- }
-
- // speed compensation
- del = speed - 1 + pattern_delay;
-
- if (!pattbreak)
- { // next row (only if no manual advance)
- rw++;
- if (rw >= nrows)
- {
- rw = 0;
- ord++;
- }
- }
-
- resolve_order (); // so we can report songend right away
- AdPlug_LogWrite ("\n");
- return !songend;
-}
-
-unsigned char
-CmodPlayer::set_opl_chip (unsigned char chan)
- /*
- * Sets OPL chip according to channel number. Channels 0-8 are on first chip,
- * channels 9-17 are on second chip. Returns corresponding OPL channel
- * number.
- */
-{
- int newchip = chan < 9 ? 0 : 1;
-
- if (newchip != curchip)
- {
- opl->setchip (newchip);
- curchip = newchip;
- }
-
- return chan % 9;
-}
-
-bool
-CmodPlayer::resolve_order ()
- /*
- * Resolves current orderlist entry, checking for jumps and loops.
- *
- * Returns true on correct processing, false if immediate recursive loop
- * has been detected.
- */
-{
- if (ord < length)
- {
- while (order[ord] >= JUMPMARKER)
- { // jump to order
- unsigned long neword = order[ord] - JUMPMARKER;
-
- if (neword <= ord)
- songend = 1;
- if (neword == ord)
- return false;
- ord = neword;
- }
- }
- else
- {
- songend = 1;
- ord = restartpos;
- }
-
- return true;
-}
-
-void
-CmodPlayer::rewind (int subsong)
-{
- unsigned long i;
-
- // Reset playing variables
- songend = del = ord = rw = regbd = 0;
- tempo = bpm;
- speed = initspeed;
-
- // Reset channel data
- memset (channel, 0, sizeof (Channel) * nchans);
-
- // Compute number of patterns, if needed
- if (!nop)
- for (i = 0; i < length; i++)
- nop = (order[i] > nop ? order[i] : nop);
-
- opl->init (); // Reset OPL chip
- opl->write (1, 32); // Go to ym3812 mode
-
- // Enable OPL3 extensions if flagged
- if (flags & Opl3)
- {
- opl->setchip (1);
- opl->write (1, 32);
- opl->write (5, 1);
- opl->setchip (0);
- }
-
- // Enable tremolo/vibrato depth if flagged
- if (flags & Tremolo)
- regbd |= 128;
- if (flags & Vibrato)
- regbd |= 64;
- if (regbd)
- opl->write (0xbd, regbd);
-}
-
-float
-CmodPlayer::getrefresh ()
-{
- return (float) (tempo / 2.5);
-}
-
-void
-CmodPlayer::init_trackord ()
-{
- unsigned long i;
-
- for (i = 0; i < npats * nchans; i++)
- trackord[i / nchans][i % nchans] = i + 1;
-}
-
-bool
-CmodPlayer::init_specialarp ()
-{
- arplist = new unsigned char[SPECIALARPLEN];
- arpcmd = new unsigned char[SPECIALARPLEN];
-
- return true;
-}
-
-void
-CmodPlayer::init_notetable (const unsigned short *newnotetable)
-{
- memcpy (notetable, newnotetable, 12 * 2);
-}
-
-bool
-CmodPlayer::realloc_order (unsigned long len)
-{
- if (order)
- delete[]order;
- order = new unsigned char[len];
- return true;
-}
-
-bool
-CmodPlayer::realloc_patterns (unsigned long pats, unsigned long rows,
- unsigned long chans)
-{
- unsigned long i;
-
- dealloc_patterns ();
-
- // set new number of tracks, rows and channels
- npats = pats;
- nrows = rows;
- nchans = chans;
-
- // alloc new patterns
- tracks = new Tracks *[pats * chans];
- for (i = 0; i < pats * chans; i++)
- tracks[i] = new Tracks[rows];
- trackord = new unsigned short *[pats];
- for (i = 0; i < pats; i++)
- trackord[i] = new unsigned short[chans];
- channel = new Channel[chans];
-
- // initialize new patterns
- for (i = 0; i < pats * chans; i++)
- memset (tracks[i], 0, sizeof (Tracks) * rows);
- for (i = 0; i < pats; i++)
- memset (trackord[i], 0, chans * 2);
-
- return true;
-}
-
-void
-CmodPlayer::dealloc_patterns ()
-{
- unsigned long i;
-
- // dealloc everything previously allocated
- if (npats && nrows && nchans)
- {
- for (i = 0; i < npats * nchans; i++)
- delete[]tracks[i];
- delete[]tracks;
- for (i = 0; i < npats; i++)
- delete[]trackord[i];
- delete[]trackord;
- delete[]channel;
- }
-}
-
-bool
-CmodPlayer::realloc_instruments (unsigned long len)
-{
- // dealloc previous instance, if any
- if (inst)
- delete[]inst;
-
- inst = new Instrument[len];
- memset (inst, 0, sizeof (Instrument) * len); // reset instruments
- return true;
-}
-
-void
-CmodPlayer::dealloc ()
-{
- if (inst)
- delete[]inst;
- if (order)
- delete[]order;
- if (arplist)
- delete[]arplist;
- if (arpcmd)
- delete[]arpcmd;
- dealloc_patterns ();
-}
-
-/*** private methods *************************************/
-
-void
-CmodPlayer::setvolume (unsigned char chan)
-{
- unsigned char oplchan = set_opl_chip (chan);
-
- if (flags & Faust)
- setvolume_alt (chan);
- else
- {
- opl->write (0x40 + op_table[oplchan],
- 63 - channel[chan].vol2 +
- (inst[channel[chan].inst].data[9] & 192));
- opl->write (0x43 + op_table[oplchan],
- 63 - channel[chan].vol1 +
- (inst[channel[chan].inst].data[10] & 192));
- }
-}
-
-void
-CmodPlayer::setvolume_alt (unsigned char chan)
-{
- unsigned char oplchan = set_opl_chip (chan);
- unsigned char ivol2 = inst[channel[chan].inst].data[9] & 63;
- unsigned char ivol1 = inst[channel[chan].inst].data[10] & 63;
-
- opl->write (0x40 + op_table[oplchan],
- (((63 - (channel[chan].vol2 & 63)) + ivol2) >> 1) +
- (inst[channel[chan].inst].data[9] & 192));
- opl->write (0x43 + op_table[oplchan],
- (((63 - (channel[chan].vol1 & 63)) + ivol1) >> 1) +
- (inst[channel[chan].inst].data[10] & 192));
-}
-
-void
-CmodPlayer::setfreq (unsigned char chan)
-{
- unsigned char oplchan = set_opl_chip (chan);
-
- opl->write (0xa0 + oplchan, channel[chan].freq & 255);
- if (channel[chan].key)
- opl->write (0xb0 + oplchan,
- ((channel[chan].freq & 768) >> 8) +
- ((channel[chan].oct << 2) | 32));
- else
- opl->write (0xb0 + oplchan,
- ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2));
-}
-
-void
-CmodPlayer::playnote (unsigned char chan)
-{
- unsigned char oplchan = set_opl_chip (chan);
- unsigned char op = op_table[oplchan], insnr = channel[chan].inst;
-
- if (!(flags & NoKeyOn))
- opl->write (0xb0 + oplchan, 0); // stop old note
-
- // set instrument data
- opl->write (0x20 + op, inst[insnr].data[1]);
- opl->write (0x23 + op, inst[insnr].data[2]);
- opl->write (0x60 + op, inst[insnr].data[3]);
- opl->write (0x63 + op, inst[insnr].data[4]);
- opl->write (0x80 + op, inst[insnr].data[5]);
- opl->write (0x83 + op, inst[insnr].data[6]);
- opl->write (0xe0 + op, inst[insnr].data[7]);
- opl->write (0xe3 + op, inst[insnr].data[8]);
- opl->write (0xc0 + oplchan, inst[insnr].data[0]);
- opl->write (0xbd, inst[insnr].misc); // set misc. register
-
- // set frequency, volume & play
- channel[chan].key = 1;
- setfreq (chan);
-
- if (flags & Faust)
- {
- channel[chan].vol2 = 63;
- channel[chan].vol1 = 63;
- }
- setvolume (chan);
-}
-
-void
-CmodPlayer::setnote (unsigned char chan, int note)
-{
- if (note > 96)
- {
- if (note == 127)
- { // key off
- channel[chan].key = 0;
- setfreq (chan);
- return;
- }
- else
- note = 96;
- }
-
- if (note < 13)
- channel[chan].freq = notetable[note - 1];
- else if (note % 12 > 0)
- channel[chan].freq = notetable[(note % 12) - 1];
- else
- channel[chan].freq = notetable[11];
- channel[chan].oct = (note - 1) / 12;
- channel[chan].freq += inst[channel[chan].inst].slide; // apply pre-slide
-}
-
-void
-CmodPlayer::slide_down (unsigned char chan, int amount)
-{
- channel[chan].freq -= amount;
- if (channel[chan].freq <= 342)
- {
- if (channel[chan].oct)
- {
- channel[chan].oct--;
- channel[chan].freq <<= 1;
- }
- else
- channel[chan].freq = 342;
- }
-}
-
-void
-CmodPlayer::slide_up (unsigned char chan, int amount)
-{
- channel[chan].freq += amount;
- if (channel[chan].freq >= 686)
- {
- if (channel[chan].oct < 7)
- {
- channel[chan].oct++;
- channel[chan].freq >>= 1;
- }
- else
- channel[chan].freq = 686;
- }
-}
-
-void
-CmodPlayer::tone_portamento (unsigned char chan, unsigned char info)
-{
- if (channel[chan].freq + (channel[chan].oct << 10) <
- channel[chan].nextfreq + (channel[chan].nextoct << 10))
- {
- slide_up (chan, info);
- if (channel[chan].freq + (channel[chan].oct << 10) >
- channel[chan].nextfreq + (channel[chan].nextoct << 10))
- {
- channel[chan].freq = channel[chan].nextfreq;
- channel[chan].oct = channel[chan].nextoct;
- }
- }
- if (channel[chan].freq + (channel[chan].oct << 10) >
- channel[chan].nextfreq + (channel[chan].nextoct << 10))
- {
- slide_down (chan, info);
- if (channel[chan].freq + (channel[chan].oct << 10) <
- channel[chan].nextfreq + (channel[chan].nextoct << 10))
- {
- channel[chan].freq = channel[chan].nextfreq;
- channel[chan].oct = channel[chan].nextoct;
- }
- }
- setfreq (chan);
-}
-
-void
-CmodPlayer::vibrato (unsigned char chan, unsigned char speed,
- unsigned char depth)
-{
- int i;
-
- if (!speed || !depth)
- return;
-
- if (depth > 14)
- depth = 14;
-
- for (i = 0; i < speed; i++)
- {
- channel[chan].trigger++;
- while (channel[chan].trigger >= 64)
- channel[chan].trigger -= 64;
- if (channel[chan].trigger >= 16 && channel[chan].trigger < 48)
- slide_down (chan,
- vibratotab[channel[chan].trigger - 16] / (16 - depth));
- if (channel[chan].trigger < 16)
- slide_up (chan, vibratotab[channel[chan].trigger + 16] / (16 - depth));
- if (channel[chan].trigger >= 48)
- slide_up (chan, vibratotab[channel[chan].trigger - 48] / (16 - depth));
- }
- setfreq (chan);
-}
-
-void
-CmodPlayer::vol_up (unsigned char chan, int amount)
-{
- if (channel[chan].vol1 + amount < 63)
- channel[chan].vol1 += amount;
- else
- channel[chan].vol1 = 63;
-
- if (channel[chan].vol2 + amount < 63)
- channel[chan].vol2 += amount;
- else
- channel[chan].vol2 = 63;
-}
-
-void
-CmodPlayer::vol_down (unsigned char chan, int amount)
-{
- if (channel[chan].vol1 - amount > 0)
- channel[chan].vol1 -= amount;
- else
- channel[chan].vol1 = 0;
-
- if (channel[chan].vol2 - amount > 0)
- channel[chan].vol2 -= amount;
- else
- channel[chan].vol2 = 0;
-}
-
-void
-CmodPlayer::vol_up_alt (unsigned char chan, int amount)
-{
- if (channel[chan].vol1 + amount < 63)
- channel[chan].vol1 += amount;
- else
- channel[chan].vol1 = 63;
- if (inst[channel[chan].inst].data[0] & 1)
- {
- if (channel[chan].vol2 + amount < 63)
- channel[chan].vol2 += amount;
- else
- channel[chan].vol2 = 63;
- }
-}
-
-void
-CmodPlayer::vol_down_alt (unsigned char chan, int amount)
-{
- if (channel[chan].vol1 - amount > 0)
- channel[chan].vol1 -= amount;
- else
- channel[chan].vol1 = 0;
- if (inst[channel[chan].inst].data[0] & 1)
- {
- if (channel[chan].vol2 - amount > 0)
- channel[chan].vol2 -= amount;
- else
- channel[chan].vol2 = 0;
- }
-}
diff --git a/src/adplug/core/protrack.h b/src/adplug/core/protrack.h
index c399c6ff3061..7cd8c77309b2 100644
--- a/src/adplug/core/protrack.h
+++ b/src/adplug/core/protrack.h
@@ -1,17 +1,17 @@
/*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
+ *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -94,7 +94,7 @@ public:
static const unsigned char vibratotab[32];
unsigned char speed, del, songend, regbd;
- unsigned short rows, notetable[12];
+ unsigned short notetable[12];
unsigned long rw, ord, nrows, npats, nchans;
void setvolume(unsigned char chan);
diff --git a/src/adplug/core/psi.cc b/src/adplug/core/psi.cc
new file mode 100644
index 000000000000..3835ecf6c02b
--- /dev/null
+++ b/src/adplug/core/psi.cc
@@ -0,0 +1,187 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * [xad] PSI player, by Riven the Mage <riven at ok.ru>
+ */
+
+/*
+ - discovery -
+
+ file(s) : 4BIDDEN.COM, PGRID.EXE
+ type : Forbidden Dreams BBStro
+ Power Grid BBStro
+ tune : by Friar Tuck [Shadow Faction/ICE]
+ player : by Psi [Future Crew]
+ comment : seems to me what 4bidden tune & player was ripped from pgrid
+
+ file(s) : MYSTRUNE.COM
+ type : Mystical Runes BBStro
+ tune : by ?
+ player : by Psi [Future Crew]
+*/
+
+#include "psi.h"
+#include "debug.h"
+
+const unsigned char
+ CxadpsiPlayer::psi_adlib_registers[99] = {
+ 0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xE0, 0xE3, 0xC0,
+ 0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xE1, 0xE4, 0xC1,
+ 0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xE2, 0xE5, 0xC2,
+ 0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xE8, 0xEB, 0xC3,
+ 0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xE9, 0xEC, 0xC4,
+ 0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xEA, 0xED, 0xC5,
+ 0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xF0, 0xF3, 0xC6,
+ 0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xF1, 0xF4, 0xC7,
+ 0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xF2, 0xF5, 0xC8
+};
+
+const unsigned short
+ CxadpsiPlayer::psi_notes[16] = {
+ 0x216B, 0x2181, 0x2198, 0x21B0, 0x21CA, 0x21E5, 0x2202, 0x2220,
+ 0x2241, 0x2263, 0x2287, 0x2364,
+ 0x0000, 0x0000, 0x0000, 0x0000 // by riven
+};
+
+CPlayer *
+CxadpsiPlayer::factory (Copl * newopl)
+{
+ return new CxadpsiPlayer (newopl);
+}
+
+void
+CxadpsiPlayer::xadplayer_rewind (int subsong)
+{
+ opl_write (0x01, 0x20);
+ opl_write (0x08, 0x00);
+ opl_write (0xBD, 0x00);
+
+ // get header
+ header.instr_ptr = (tune[1] << 8) + tune[0];
+ header.seq_ptr = (tune[3] << 8) + tune[2];
+
+ // define instruments
+ psi.instr_table = &tune[header.instr_ptr];
+
+ for (int i = 0; i < 8; i++)
+ {
+ for (int j = 0; j < 11; j++)
+ {
+ unsigned short inspos =
+ (psi.instr_table[i * 2 + 1] << 8) + psi.instr_table[i * 2];
+
+ opl_write (psi_adlib_registers[i * 11 + j], tune[inspos + j]);
+ }
+
+ opl_write (0xA0 + i, 0x00);
+ opl_write (0xB0 + i, 0x00);
+
+ psi.note_delay[i] = 1;
+ psi.note_curdelay[i] = 1;
+ psi.looping[i] = 0;
+ }
+
+ // calculate sequence pointer
+ psi.seq_table = &tune[header.seq_ptr];
+}
+
+void
+CxadpsiPlayer::xadplayer_update ()
+{
+ unsigned short ptr;
+
+ for (int i = 0; i < 8; i++)
+ {
+ ptr =
+ (psi.seq_table[(i << 1) * 2 + 1] << 8) + psi.seq_table[(i << 1) * 2];
+
+ psi.note_curdelay[i]--;
+
+ if (!psi.note_curdelay[i])
+ {
+ opl_write (0xA0 + i, 0x00);
+ opl_write (0xB0 + i, 0x00);
+
+ unsigned char event = tune[ptr++];
+#ifdef DEBUG
+ AdPlug_LogWrite ("channel %02X, event %02X:\n", i + 1, event);
+#endif
+
+ // end of sequence ?
+ if (!event)
+ {
+ ptr =
+ (psi.seq_table[(i << 1) * 2 + 3] << 8) +
+ psi.seq_table[(i << 1) * 2 + 2];
+
+ event = tune[ptr++];
+#ifdef DEBUG
+ AdPlug_LogWrite (" channel %02X, event %02X:\n", i + 1, event);
+#endif
+
+ // set sequence loop flag
+ psi.looping[i] = 1;
+
+ // module loop ?
+ plr.looping = 1;
+ for (int j = 0; j < 8; j++)
+ plr.looping &= psi.looping[j];
+ }
+
+ // new note delay ?
+ if (event & 0x80)
+ {
+ psi.note_delay[i] = (event & 0x7F);
+
+ event = tune[ptr++];
+#ifdef DEBUG
+ AdPlug_LogWrite (" channel %02X, event %02X:\n", i + 1, event);
+#endif
+ }
+
+ psi.note_curdelay[i] = psi.note_delay[i];
+
+ // play note
+ unsigned short note = psi_notes[event & 0x0F];
+
+ opl_write (0xA0 + i, note & 0xFF);
+ opl_write (0xB0 + i, (note >> 8) + ((event >> 2) & 0xFC));
+
+ // save position
+ psi.seq_table[(i << 1) * 2] = ptr & 0xff;
+ psi.seq_table[(i << 1) * 2 + 1] = ptr >> 8;
+ }
+ }
+}
+
+float
+CxadpsiPlayer::xadplayer_getrefresh ()
+{
+ return 70.0f;
+}
+
+std::string CxadpsiPlayer::xadplayer_gettype ()
+{
+ return std::string ("xad: psi player");
+}
+
+unsigned int
+CxadpsiPlayer::xadplayer_getinstruments ()
+{
+ return 8;
+}
diff --git a/src/adplug/core/psi.cxx b/src/adplug/core/psi.cxx
deleted file mode 100644
index 3835ecf6c02b..000000000000
--- a/src/adplug/core/psi.cxx
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * [xad] PSI player, by Riven the Mage <riven at ok.ru>
- */
-
-/*
- - discovery -
-
- file(s) : 4BIDDEN.COM, PGRID.EXE
- type : Forbidden Dreams BBStro
- Power Grid BBStro
- tune : by Friar Tuck [Shadow Faction/ICE]
- player : by Psi [Future Crew]
- comment : seems to me what 4bidden tune & player was ripped from pgrid
-
- file(s) : MYSTRUNE.COM
- type : Mystical Runes BBStro
- tune : by ?
- player : by Psi [Future Crew]
-*/
-
-#include "psi.h"
-#include "debug.h"
-
-const unsigned char
- CxadpsiPlayer::psi_adlib_registers[99] = {
- 0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xE0, 0xE3, 0xC0,
- 0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xE1, 0xE4, 0xC1,
- 0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xE2, 0xE5, 0xC2,
- 0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xE8, 0xEB, 0xC3,
- 0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xE9, 0xEC, 0xC4,
- 0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xEA, 0xED, 0xC5,
- 0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xF0, 0xF3, 0xC6,
- 0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xF1, 0xF4, 0xC7,
- 0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xF2, 0xF5, 0xC8
-};
-
-const unsigned short
- CxadpsiPlayer::psi_notes[16] = {
- 0x216B, 0x2181, 0x2198, 0x21B0, 0x21CA, 0x21E5, 0x2202, 0x2220,
- 0x2241, 0x2263, 0x2287, 0x2364,
- 0x0000, 0x0000, 0x0000, 0x0000 // by riven
-};
-
-CPlayer *
-CxadpsiPlayer::factory (Copl * newopl)
-{
- return new CxadpsiPlayer (newopl);
-}
-
-void
-CxadpsiPlayer::xadplayer_rewind (int subsong)
-{
- opl_write (0x01, 0x20);
- opl_write (0x08, 0x00);
- opl_write (0xBD, 0x00);
-
- // get header
- header.instr_ptr = (tune[1] << 8) + tune[0];
- header.seq_ptr = (tune[3] << 8) + tune[2];
-
- // define instruments
- psi.instr_table = &tune[header.instr_ptr];
-
- for (int i = 0; i < 8; i++)
- {
- for (int j = 0; j < 11; j++)
- {
- unsigned short inspos =
- (psi.instr_table[i * 2 + 1] << 8) + psi.instr_table[i * 2];
-
- opl_write (psi_adlib_registers[i * 11 + j], tune[inspos + j]);
- }
-
- opl_write (0xA0 + i, 0x00);
- opl_write (0xB0 + i, 0x00);
-
- psi.note_delay[i] = 1;
- psi.note_curdelay[i] = 1;
- psi.looping[i] = 0;
- }
-
- // calculate sequence pointer
- psi.seq_table = &tune[header.seq_ptr];
-}
-
-void
-CxadpsiPlayer::xadplayer_update ()
-{
- unsigned short ptr;
-
- for (int i = 0; i < 8; i++)
- {
- ptr =
- (psi.seq_table[(i << 1) * 2 + 1] << 8) + psi.seq_table[(i << 1) * 2];
-
- psi.note_curdelay[i]--;
-
- if (!psi.note_curdelay[i])
- {
- opl_write (0xA0 + i, 0x00);
- opl_write (0xB0 + i, 0x00);
-
- unsigned char event = tune[ptr++];
-#ifdef DEBUG
- AdPlug_LogWrite ("channel %02X, event %02X:\n", i + 1, event);
-#endif
-
- // end of sequence ?
- if (!event)
- {
- ptr =
- (psi.seq_table[(i << 1) * 2 + 3] << 8) +
- psi.seq_table[(i << 1) * 2 + 2];
-
- event = tune[ptr++];
-#ifdef DEBUG
- AdPlug_LogWrite (" channel %02X, event %02X:\n", i + 1, event);
-#endif
-
- // set sequence loop flag
- psi.looping[i] = 1;
-
- // module loop ?
- plr.looping = 1;
- for (int j = 0; j < 8; j++)
- plr.looping &= psi.looping[j];
- }
-
- // new note delay ?
- if (event & 0x80)
- {
- psi.note_delay[i] = (event & 0x7F);
-
- event = tune[ptr++];
-#ifdef DEBUG
- AdPlug_LogWrite (" channel %02X, event %02X:\n", i + 1, event);
-#endif
- }
-
- psi.note_curdelay[i] = psi.note_delay[i];
-
- // play note
- unsigned short note = psi_notes[event & 0x0F];
-
- opl_write (0xA0 + i, note & 0xFF);
- opl_write (0xB0 + i, (note >> 8) + ((event >> 2) & 0xFC));
-
- // save position
- psi.seq_table[(i << 1) * 2] = ptr & 0xff;
- psi.seq_table[(i << 1) * 2 + 1] = ptr >> 8;
- }
- }
-}
-
-float
-CxadpsiPlayer::xadplayer_getrefresh ()
-{
- return 70.0f;
-}
-
-std::string CxadpsiPlayer::xadplayer_gettype ()
-{
- return std::string ("xad: psi player");
-}
-
-unsigned int
-CxadpsiPlayer::xadplayer_getinstruments ()
-{
- return 8;
-}
diff --git a/src/adplug/core/rad.cc b/src/adplug/core/rad.cc
new file mode 100644
index 000000000000..d9ae560f673b
--- /dev/null
+++ b/src/adplug/core/rad.cc
@@ -0,0 +1,155 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * rad.cpp - RAD Loader by Simon Peter <dn.tlp at gmx.net>
+ *
+ * BUGS:
+ * some volumes are dropped out
+ */
+
+#include <string.h>
+
+#include "rad.h"
+
+CPlayer *
+CradLoader::factory (Copl * newopl)
+{
+ return new CradLoader (newopl);
+}
+
+bool
+CradLoader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ char id[16];
+ unsigned char buf, ch, c, b, inp;
+ char bufstr[2] = "\0";
+ unsigned int i, j;
+ unsigned short patofs[32];
+ const unsigned char convfx[16] =
+ { 255, 1, 2, 3, 255, 5, 255, 255, 255, 255, 20, 255, 17, 0xd, 255, 19 };
+
+ // file validation section
+ f->readString (id, 16);
+ version = f->readInt (1);
+ if (strncmp (id, "RAD by REALiTY!!", 16) || version != 0x10)
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // load section
+ radflags = f->readInt (1);
+ if (radflags & 128)
+ { // description
+ memset (desc, 0, 80 * 22);
+ while ((buf = f->readInt (1)))
+ if (buf == 1)
+ strcat (desc, "\n");
+ else if (buf >= 2 && buf <= 0x1f)
+ for (i = 0; i < buf; i++)
+ strcat (desc, " ");
+ else
+ {
+ *bufstr = buf;
+ strcat (desc, bufstr);
+ }
+ }
+ while ((buf = f->readInt (1)))
+ { // instruments
+ buf--;
+ inst[buf].data[2] = f->readInt (1);
+ inst[buf].data[1] = f->readInt (1);
+ inst[buf].data[10] = f->readInt (1);
+ inst[buf].data[9] = f->readInt (1);
+ inst[buf].data[4] = f->readInt (1);
+ inst[buf].data[3] = f->readInt (1);
+ inst[buf].data[6] = f->readInt (1);
+ inst[buf].data[5] = f->readInt (1);
+ inst[buf].data[0] = f->readInt (1);
+ inst[buf].data[8] = f->readInt (1);
+ inst[buf].data[7] = f->readInt (1);
+ }
+ length = f->readInt (1);
+ for (i = 0; i < length; i++)
+ order[i] = f->readInt (1); // orderlist
+ for (i = 0; i < 32; i++)
+ patofs[i] = f->readInt (2); // pattern offset table
+ init_trackord (); // patterns
+ for (i = 0; i < 32; i++)
+ if (patofs[i])
+ {
+ f->seek (patofs[i]);
+ do
+ {
+ buf = f->readInt (1);
+ b = buf & 127;
+ do
+ {
+ ch = f->readInt (1);
+ c = ch & 127;
+ inp = f->readInt (1);
+ tracks[i * 9 + c][b].note = inp & 127;
+ tracks[i * 9 + c][b].inst = (inp & 128) >> 3;
+ inp = f->readInt (1);
+ tracks[i * 9 + c][b].inst += inp >> 4;
+ tracks[i * 9 + c][b].command = inp & 15;
+ if (inp & 15)
+ {
+ inp = f->readInt (1);
+ tracks[i * 9 + c][b].param1 = inp / 10;
+ tracks[i * 9 + c][b].param2 = inp % 10;
+ }
+ } while (!(ch & 128));
+ } while (!(buf & 128));
+ }
+ else
+ memset (trackord[i], 0, 9 * 2);
+ fp.close (f);
+
+ // convert replay data
+ for (i = 0; i < 32 * 9; i++) // convert patterns
+ for (j = 0; j < 64; j++)
+ {
+ if (tracks[i][j].note == 15)
+ tracks[i][j].note = 127;
+ if (tracks[i][j].note > 16 && tracks[i][j].note < 127)
+ tracks[i][j].note -= 4 * (tracks[i][j].note >> 4);
+ if (tracks[i][j].note && tracks[i][j].note < 126)
+ tracks[i][j].note++;
+ tracks[i][j].command = convfx[tracks[i][j].command];
+ }
+ restartpos = 0;
+ initspeed = radflags & 31;
+ bpm = radflags & 64 ? 0 : 50;
+ flags = Decimal;
+
+ rewind (0);
+ return true;
+}
+
+float
+CradLoader::getrefresh ()
+{
+ if (tempo)
+ return (float) (tempo);
+ else
+ return 18.2f;
+}
diff --git a/src/adplug/core/rad.cxx b/src/adplug/core/rad.cxx
deleted file mode 100644
index d02d0f07c95e..000000000000
--- a/src/adplug/core/rad.cxx
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * rad.cpp - RAD Loader by Simon Peter <dn.tlp at gmx.net>
- *
- * BUGS:
- * some volumes are dropped out
- */
-
-#include <string.h>
-
-#include "rad.h"
-
-CPlayer *
-CradLoader::factory (Copl * newopl)
-{
- return new CradLoader (newopl);
-}
-
-bool
-CradLoader::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- char id[16];
- unsigned char buf, ch, c, b, inp;
- char bufstr[2] = "\0";
- unsigned int i, j;
- unsigned short patofs[32];
- const unsigned char convfx[16] =
- { 255, 1, 2, 3, 255, 5, 255, 255, 255, 255, 20, 255, 17, 0xd, 255, 19 };
-
- // file validation section
- f->readString (id, 16);
- version = f->readInt (1);
- if (strncmp (id, "RAD by REALiTY!!", 16) || version != 0x10)
- {
- fp.close (f);
- return false;
- }
-
- // load section
- radflags = f->readInt (1);
- if (radflags & 128)
- { // description
- memset (desc, 0, 80 * 22);
- while ((buf = f->readInt (1)))
- if (buf == 1)
- strcat (desc, "\n");
- else if (buf >= 2 && buf <= 0x1f)
- for (i = 0; i < buf; i++)
- strcat (desc, " ");
- else
- {
- *bufstr = buf;
- strcat (desc, bufstr);
- }
- }
- while ((buf = f->readInt (1)))
- { // instruments
- buf--;
- inst[buf].data[2] = f->readInt (1);
- inst[buf].data[1] = f->readInt (1);
- inst[buf].data[10] = f->readInt (1);
- inst[buf].data[9] = f->readInt (1);
- inst[buf].data[4] = f->readInt (1);
- inst[buf].data[3] = f->readInt (1);
- inst[buf].data[6] = f->readInt (1);
- inst[buf].data[5] = f->readInt (1);
- inst[buf].data[0] = f->readInt (1);
- inst[buf].data[8] = f->readInt (1);
- inst[buf].data[7] = f->readInt (1);
- }
- length = f->readInt (1);
- for (i = 0; i < length; i++)
- order[i] = f->readInt (1); // orderlist
- for (i = 0; i < 32; i++)
- patofs[i] = f->readInt (2); // pattern offset table
- init_trackord (); // patterns
- for (i = 0; i < 32; i++)
- if (patofs[i])
- {
- f->seek (patofs[i]);
- do
- {
- buf = f->readInt (1);
- b = buf & 127;
- do
- {
- ch = f->readInt (1);
- c = ch & 127;
- inp = f->readInt (1);
- tracks[i * 9 + c][b].note = inp & 127;
- tracks[i * 9 + c][b].inst = (inp & 128) >> 3;
- inp = f->readInt (1);
- tracks[i * 9 + c][b].inst += inp >> 4;
- tracks[i * 9 + c][b].command = inp & 15;
- if (inp & 15)
- {
- inp = f->readInt (1);
- tracks[i * 9 + c][b].param1 = inp / 10;
- tracks[i * 9 + c][b].param2 = inp % 10;
- }
- } while (!(ch & 128));
- } while (!(buf & 128));
- }
- else
- memset (trackord[i], 0, 9 * 2);
- fp.close (f);
-
- // convert replay data
- for (i = 0; i < 32 * 9; i++) // convert patterns
- for (j = 0; j < 64; j++)
- {
- if (tracks[i][j].note == 15)
- tracks[i][j].note = 127;
- if (tracks[i][j].note > 16 && tracks[i][j].note < 127)
- tracks[i][j].note -= 4 * (tracks[i][j].note >> 4);
- if (tracks[i][j].note && tracks[i][j].note < 126)
- tracks[i][j].note++;
- tracks[i][j].command = convfx[tracks[i][j].command];
- }
- restartpos = 0;
- initspeed = radflags & 31;
- bpm = radflags & 64 ? 0 : 50;
- flags = Decimal;
-
- rewind (0);
- return true;
-}
-
-float
-CradLoader::getrefresh ()
-{
- if (tempo)
- return (float) (tempo);
- else
- return 18.2f;
-}
diff --git a/src/adplug/core/rad.h b/src/adplug/core/rad.h
index 6bf8ac76f099..693bb33629b2 100644
--- a/src/adplug/core/rad.h
+++ b/src/adplug/core/rad.h
@@ -30,7 +30,7 @@ public:
: CmodPlayer(newopl)
{ *desc = '\0'; };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
float getrefresh();
std::string gettype()
diff --git a/src/adplug/core/rat.cc b/src/adplug/core/rat.cc
new file mode 100644
index 000000000000..ee26b20031b2
--- /dev/null
+++ b/src/adplug/core/rat.cc
@@ -0,0 +1,311 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * [xad] RAT player, by Riven the Mage <riven at ok.ru>
+ */
+
+/*
+ - discovery -
+
+ file(s) : PINA.EXE
+ type : Experimental Connection BBStro tune
+ tune : by (?)Ratt/GRIF
+ player : by (?)Ratt/GRIF
+ comment : there are bug in original replayer's adlib_init(): wrong frequency registers.
+*/
+
+#include <string.h>
+
+#include "rat.h"
+#include "debug.h"
+
+const unsigned char
+ CxadratPlayer::rat_adlib_bases[18] = {
+ 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12,
+ 0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15
+};
+
+const unsigned short
+ CxadratPlayer::rat_notes[16] = {
+ 0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263,
+ 0x287,
+ 0x000, 0x000, 0x000, 0x000 // by riven
+};
+
+CPlayer *
+CxadratPlayer::factory (Copl * newopl)
+{
+ return new CxadratPlayer (newopl);
+}
+
+bool
+CxadratPlayer::xadplayer_load ()
+{
+ if (xad.fmt != RAT)
+ return false;
+
+ // load header
+ memcpy (&rat.hdr, &tune[0], sizeof (rat_header));
+
+ // is 'RAT'-signed ?
+ if (strncmp (rat.hdr.id, "RAT", 3))
+ return false;
+
+ // is version 1.0 ?
+ if (rat.hdr.version != 0x10)
+ return false;
+
+ // load order
+ rat.order = &tune[0x40];
+
+ // load instruments
+ rat.inst = (rat_instrument *) & tune[0x140];
+
+ // load pattern data
+ unsigned short patseg = (rat.hdr.patseg[1] << 8) + rat.hdr.patseg[0];
+ unsigned char *event_ptr = &tune[patseg << 4];
+
+ for (int i = 0; i < rat.hdr.numpat; i++)
+ for (int j = 0; j < 64; j++)
+ for (int k = 0; k < rat.hdr.numchan; k++)
+ {
+ memcpy (&rat.tracks[i][j][k], event_ptr, sizeof (rat_event));
+
+ event_ptr += sizeof (rat_event);
+ }
+
+ return true;
+}
+
+void
+CxadratPlayer::xadplayer_rewind (int subsong)
+{
+ int i;
+
+ rat.order_pos = rat.hdr.order_start;
+ rat.pattern_pos = 0;
+ rat.volume = rat.hdr.volume;
+
+ plr.speed = rat.hdr.speed;
+
+ // clear channel data
+ memset (&rat.channel, 0, sizeof (rat.channel[0]) * 9);
+
+ // init OPL
+ opl_write (0x01, 0x20);
+ opl_write (0x08, 0x00);
+ opl_write (0xBD, 0x00);
+
+ // set default frequencies
+ for (i = 0; i < 9; i++)
+ {
+ opl_write (0xA0 + i, 0x00);
+ opl_write (0xA3 + i, 0x00);
+ opl_write (0xB0 + i, 0x00);
+ opl_write (0xB3 + i, 0x00);
+ }
+
+ // set default volumes
+ for (i = 0; i < 0x1F; i++)
+ opl_write (0x40 + i, 0x3F);
+}
+
+void
+CxadratPlayer::xadplayer_update ()
+{
+ int i;
+
+ rat_event event;
+
+ // process events
+ for (i = 0; i < rat.hdr.numchan; i++)
+ {
+ memcpy (&event, &rat.tracks[rat.order[rat.order_pos]][rat.pattern_pos][i],
+ sizeof (rat_event));
+#ifdef DEBUG
+ AdPlug_LogWrite
+ ("order %02X, pattern %02X, row %02X, channel %02X, event %02X %02X %02X %02X %02X:\n",
+ rat.order_pos, rat.order[rat.order_pos], rat.pattern_pos, i,
+ event.note, event.instrument, event.volume, event.fx, event.fxp);
+#endif
+
+ // is instrument ?
+ if (event.instrument != 0xFF)
+ {
+ rat.channel[i].instrument = event.instrument - 1;
+ rat.channel[i].volume = rat.inst[event.instrument - 1].volume;
+ }
+
+ // is volume ?
+ if (event.volume != 0xFF)
+ rat.channel[i].volume = event.volume;
+
+ // is note ?
+ if (event.note != 0xFF)
+ {
+ // mute channel
+ opl_write (0xB0 + i, 0x00);
+ opl_write (0xA0 + i, 0x00);
+
+ // if note != 0xFE then play
+ if (event.note != 0xFE)
+ {
+ unsigned char ins = rat.channel[i].instrument;
+
+ // synthesis/feedback
+ opl_write (0xC0 + i, rat.inst[ins].connect);
+
+ // controls
+ opl_write (0x20 + rat_adlib_bases[i], rat.inst[ins].mod_ctrl);
+ opl_write (0x20 + rat_adlib_bases[i + 9], rat.inst[ins].car_ctrl);
+
+ // volumes
+ opl_write (0x40 + rat_adlib_bases[i],
+ __rat_calc_volume (rat.inst[ins].mod_volume,
+ rat.channel[i].volume, rat.volume));
+ opl_write (0x40 + rat_adlib_bases[i + 9],
+ __rat_calc_volume (rat.inst[ins].car_volume,
+ rat.channel[i].volume, rat.volume));
+
+ // attack/decay
+ opl_write (0x60 + rat_adlib_bases[i], rat.inst[ins].mod_AD);
+ opl_write (0x60 + rat_adlib_bases[i + 9], rat.inst[ins].car_AD);
+
+ // sustain/release
+ opl_write (0x80 + rat_adlib_bases[i], rat.inst[ins].mod_SR);
+ opl_write (0x80 + rat_adlib_bases[i + 9], rat.inst[ins].car_SR);
+
+ // waveforms
+ opl_write (0xE0 + rat_adlib_bases[i], rat.inst[ins].mod_wave);
+ opl_write (0xE0 + rat_adlib_bases[i + 9], rat.inst[ins].car_wave);
+
+ // octave/frequency
+ unsigned short insfreq =
+ (rat.inst[ins].freq[1] << 8) + rat.inst[ins].freq[0];
+ unsigned short freq = insfreq * rat_notes[event.note & 0x0F] / 0x20AB;
+
+ opl_write (0xA0 + i, freq & 0xFF);
+ opl_write (0xB0 + i, (freq >> 8) | ((event.note & 0xF0) >> 2) | 0x20);
+ }
+ }
+
+ // is effect ?
+ if (event.fx != 0xFF)
+ {
+ rat.channel[i].fx = event.fx;
+ rat.channel[i].fxp = event.fxp;
+ }
+ }
+
+ // next row
+ rat.pattern_pos++;
+
+ // process effects
+ for (i = 0; i < rat.hdr.numchan; i++)
+ {
+ unsigned char old_order_pos = rat.order_pos;
+
+ switch (rat.channel[i].fx)
+ {
+ case 0x01: // 0x01: Set Speed
+ plr.speed = rat.channel[i].fxp;
+ break;
+ case 0x02: // 0x02: Position Jump
+ if (rat.channel[i].fxp < rat.hdr.order_end)
+ rat.order_pos = rat.channel[i].fxp;
+ else
+ rat.order_pos = 0;
+
+ // jumpback ?
+ if (rat.order_pos <= old_order_pos)
+ plr.looping = 1;
+
+ rat.pattern_pos = 0;
+ break;
+ case 0x03: // 0x03: Pattern Break (?)
+ rat.pattern_pos = 0x40;
+ break;
+ }
+
+ rat.channel[i].fx = 0;
+ }
+
+ // end of pattern ?
+ if (rat.pattern_pos >= 0x40)
+ {
+ rat.pattern_pos = 0;
+
+ rat.order_pos++;
+
+ // end of module ?
+ if (rat.order_pos == rat.hdr.order_end)
+ {
+ rat.order_pos = rat.hdr.order_loop;
+
+ plr.looping = 1;
+ }
+ }
+}
+
+float
+CxadratPlayer::xadplayer_getrefresh ()
+{
+ return 60.0f;
+}
+
+std::string CxadratPlayer::xadplayer_gettype ()
+{
+ return (std::string ("xad: rat player"));
+}
+
+std::string CxadratPlayer::xadplayer_gettitle ()
+{
+ return (std::string (rat.hdr.title, 32));
+}
+
+unsigned int
+CxadratPlayer::xadplayer_getinstruments ()
+{
+ return rat.hdr.numinst;
+}
+
+/* -------- Internal Functions ---------------------------- */
+
+unsigned char
+CxadratPlayer::__rat_calc_volume (unsigned char ivol, unsigned char cvol,
+ unsigned char gvol)
+{
+#ifdef DEBUG
+ AdPlug_LogWrite ("volumes: instrument %02X, channel %02X, global %02X:\n",
+ ivol, cvol, gvol);
+#endif
+ unsigned short vol;
+
+ vol = ivol;
+ vol &= 0x3F;
+ vol ^= 0x3F;
+ vol *= cvol;
+ vol >>= 6;
+ vol *= gvol;
+ vol >>= 6;
+ vol ^= 0x3F;
+
+ vol |= ivol & 0xC0;
+
+ return vol;
+}
diff --git a/src/adplug/core/rat.cxx b/src/adplug/core/rat.cxx
deleted file mode 100644
index ee26b20031b2..000000000000
--- a/src/adplug/core/rat.cxx
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * [xad] RAT player, by Riven the Mage <riven at ok.ru>
- */
-
-/*
- - discovery -
-
- file(s) : PINA.EXE
- type : Experimental Connection BBStro tune
- tune : by (?)Ratt/GRIF
- player : by (?)Ratt/GRIF
- comment : there are bug in original replayer's adlib_init(): wrong frequency registers.
-*/
-
-#include <string.h>
-
-#include "rat.h"
-#include "debug.h"
-
-const unsigned char
- CxadratPlayer::rat_adlib_bases[18] = {
- 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12,
- 0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15
-};
-
-const unsigned short
- CxadratPlayer::rat_notes[16] = {
- 0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263,
- 0x287,
- 0x000, 0x000, 0x000, 0x000 // by riven
-};
-
-CPlayer *
-CxadratPlayer::factory (Copl * newopl)
-{
- return new CxadratPlayer (newopl);
-}
-
-bool
-CxadratPlayer::xadplayer_load ()
-{
- if (xad.fmt != RAT)
- return false;
-
- // load header
- memcpy (&rat.hdr, &tune[0], sizeof (rat_header));
-
- // is 'RAT'-signed ?
- if (strncmp (rat.hdr.id, "RAT", 3))
- return false;
-
- // is version 1.0 ?
- if (rat.hdr.version != 0x10)
- return false;
-
- // load order
- rat.order = &tune[0x40];
-
- // load instruments
- rat.inst = (rat_instrument *) & tune[0x140];
-
- // load pattern data
- unsigned short patseg = (rat.hdr.patseg[1] << 8) + rat.hdr.patseg[0];
- unsigned char *event_ptr = &tune[patseg << 4];
-
- for (int i = 0; i < rat.hdr.numpat; i++)
- for (int j = 0; j < 64; j++)
- for (int k = 0; k < rat.hdr.numchan; k++)
- {
- memcpy (&rat.tracks[i][j][k], event_ptr, sizeof (rat_event));
-
- event_ptr += sizeof (rat_event);
- }
-
- return true;
-}
-
-void
-CxadratPlayer::xadplayer_rewind (int subsong)
-{
- int i;
-
- rat.order_pos = rat.hdr.order_start;
- rat.pattern_pos = 0;
- rat.volume = rat.hdr.volume;
-
- plr.speed = rat.hdr.speed;
-
- // clear channel data
- memset (&rat.channel, 0, sizeof (rat.channel[0]) * 9);
-
- // init OPL
- opl_write (0x01, 0x20);
- opl_write (0x08, 0x00);
- opl_write (0xBD, 0x00);
-
- // set default frequencies
- for (i = 0; i < 9; i++)
- {
- opl_write (0xA0 + i, 0x00);
- opl_write (0xA3 + i, 0x00);
- opl_write (0xB0 + i, 0x00);
- opl_write (0xB3 + i, 0x00);
- }
-
- // set default volumes
- for (i = 0; i < 0x1F; i++)
- opl_write (0x40 + i, 0x3F);
-}
-
-void
-CxadratPlayer::xadplayer_update ()
-{
- int i;
-
- rat_event event;
-
- // process events
- for (i = 0; i < rat.hdr.numchan; i++)
- {
- memcpy (&event, &rat.tracks[rat.order[rat.order_pos]][rat.pattern_pos][i],
- sizeof (rat_event));
-#ifdef DEBUG
- AdPlug_LogWrite
- ("order %02X, pattern %02X, row %02X, channel %02X, event %02X %02X %02X %02X %02X:\n",
- rat.order_pos, rat.order[rat.order_pos], rat.pattern_pos, i,
- event.note, event.instrument, event.volume, event.fx, event.fxp);
-#endif
-
- // is instrument ?
- if (event.instrument != 0xFF)
- {
- rat.channel[i].instrument = event.instrument - 1;
- rat.channel[i].volume = rat.inst[event.instrument - 1].volume;
- }
-
- // is volume ?
- if (event.volume != 0xFF)
- rat.channel[i].volume = event.volume;
-
- // is note ?
- if (event.note != 0xFF)
- {
- // mute channel
- opl_write (0xB0 + i, 0x00);
- opl_write (0xA0 + i, 0x00);
-
- // if note != 0xFE then play
- if (event.note != 0xFE)
- {
- unsigned char ins = rat.channel[i].instrument;
-
- // synthesis/feedback
- opl_write (0xC0 + i, rat.inst[ins].connect);
-
- // controls
- opl_write (0x20 + rat_adlib_bases[i], rat.inst[ins].mod_ctrl);
- opl_write (0x20 + rat_adlib_bases[i + 9], rat.inst[ins].car_ctrl);
-
- // volumes
- opl_write (0x40 + rat_adlib_bases[i],
- __rat_calc_volume (rat.inst[ins].mod_volume,
- rat.channel[i].volume, rat.volume));
- opl_write (0x40 + rat_adlib_bases[i + 9],
- __rat_calc_volume (rat.inst[ins].car_volume,
- rat.channel[i].volume, rat.volume));
-
- // attack/decay
- opl_write (0x60 + rat_adlib_bases[i], rat.inst[ins].mod_AD);
- opl_write (0x60 + rat_adlib_bases[i + 9], rat.inst[ins].car_AD);
-
- // sustain/release
- opl_write (0x80 + rat_adlib_bases[i], rat.inst[ins].mod_SR);
- opl_write (0x80 + rat_adlib_bases[i + 9], rat.inst[ins].car_SR);
-
- // waveforms
- opl_write (0xE0 + rat_adlib_bases[i], rat.inst[ins].mod_wave);
- opl_write (0xE0 + rat_adlib_bases[i + 9], rat.inst[ins].car_wave);
-
- // octave/frequency
- unsigned short insfreq =
- (rat.inst[ins].freq[1] << 8) + rat.inst[ins].freq[0];
- unsigned short freq = insfreq * rat_notes[event.note & 0x0F] / 0x20AB;
-
- opl_write (0xA0 + i, freq & 0xFF);
- opl_write (0xB0 + i, (freq >> 8) | ((event.note & 0xF0) >> 2) | 0x20);
- }
- }
-
- // is effect ?
- if (event.fx != 0xFF)
- {
- rat.channel[i].fx = event.fx;
- rat.channel[i].fxp = event.fxp;
- }
- }
-
- // next row
- rat.pattern_pos++;
-
- // process effects
- for (i = 0; i < rat.hdr.numchan; i++)
- {
- unsigned char old_order_pos = rat.order_pos;
-
- switch (rat.channel[i].fx)
- {
- case 0x01: // 0x01: Set Speed
- plr.speed = rat.channel[i].fxp;
- break;
- case 0x02: // 0x02: Position Jump
- if (rat.channel[i].fxp < rat.hdr.order_end)
- rat.order_pos = rat.channel[i].fxp;
- else
- rat.order_pos = 0;
-
- // jumpback ?
- if (rat.order_pos <= old_order_pos)
- plr.looping = 1;
-
- rat.pattern_pos = 0;
- break;
- case 0x03: // 0x03: Pattern Break (?)
- rat.pattern_pos = 0x40;
- break;
- }
-
- rat.channel[i].fx = 0;
- }
-
- // end of pattern ?
- if (rat.pattern_pos >= 0x40)
- {
- rat.pattern_pos = 0;
-
- rat.order_pos++;
-
- // end of module ?
- if (rat.order_pos == rat.hdr.order_end)
- {
- rat.order_pos = rat.hdr.order_loop;
-
- plr.looping = 1;
- }
- }
-}
-
-float
-CxadratPlayer::xadplayer_getrefresh ()
-{
- return 60.0f;
-}
-
-std::string CxadratPlayer::xadplayer_gettype ()
-{
- return (std::string ("xad: rat player"));
-}
-
-std::string CxadratPlayer::xadplayer_gettitle ()
-{
- return (std::string (rat.hdr.title, 32));
-}
-
-unsigned int
-CxadratPlayer::xadplayer_getinstruments ()
-{
- return rat.hdr.numinst;
-}
-
-/* -------- Internal Functions ---------------------------- */
-
-unsigned char
-CxadratPlayer::__rat_calc_volume (unsigned char ivol, unsigned char cvol,
- unsigned char gvol)
-{
-#ifdef DEBUG
- AdPlug_LogWrite ("volumes: instrument %02X, channel %02X, global %02X:\n",
- ivol, cvol, gvol);
-#endif
- unsigned short vol;
-
- vol = ivol;
- vol &= 0x3F;
- vol ^= 0x3F;
- vol *= cvol;
- vol >>= 6;
- vol *= gvol;
- vol >>= 6;
- vol ^= 0x3F;
-
- vol |= ivol & 0xC0;
-
- return vol;
-}
diff --git a/src/adplug/core/raw.cc b/src/adplug/core/raw.cc
new file mode 100644
index 000000000000..4dfc8f3645b2
--- /dev/null
+++ b/src/adplug/core/raw.cc
@@ -0,0 +1,129 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * raw.c - RAW Player by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <string.h>
+
+#include "raw.h"
+
+/*** public methods *************************************/
+
+CPlayer *
+CrawPlayer::factory (Copl * newopl)
+{
+ return new CrawPlayer (newopl);
+}
+
+bool
+CrawPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ char id[8];
+ unsigned long i;
+
+ // file validation section
+ f->readString (id, 8);
+ if (strncmp (id, "RAWADATA", 8))
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // load section
+ clock = f->readInt (2); // clock speed
+ length = (fp.filesize (f) - 10) / 2;
+ data = new Tdata[length];
+ for (i = 0; i < length; i++)
+ {
+ data[i].param = f->readInt (1);
+ data[i].command = f->readInt (1);
+ }
+
+ fp.close (f);
+ rewind (0);
+ return true;
+}
+
+bool
+CrawPlayer::update ()
+{
+ bool setspeed;
+
+ if (pos >= length)
+ return false;
+
+ if (del)
+ {
+ del--;
+ return !songend;
+ }
+
+ do
+ {
+ setspeed = false;
+ switch (data[pos].command)
+ {
+ case 0:
+ del = data[pos].param - 1;
+ break;
+ case 2:
+ if (!data[pos].param)
+ {
+ pos++;
+ speed = data[pos].param + (data[pos].command << 8);
+ setspeed = true;
+ }
+ else
+ opl->setchip (data[pos].param - 1);
+ break;
+ case 0xff:
+ if (data[pos].param == 0xff)
+ {
+ rewind (0); // auto-rewind song
+ songend = true;
+ return !songend;
+ }
+ break;
+ default:
+ opl->write (data[pos].command, data[pos].param);
+ break;
+ }
+ } while (data[pos++].command || setspeed);
+
+ return !songend;
+}
+
+void
+CrawPlayer::rewind (int subsong)
+{
+ pos = del = 0;
+ speed = clock;
+ songend = false;
+ opl->init ();
+ opl->write (1, 32); // go to 9 channel mode
+}
+
+float
+CrawPlayer::getrefresh ()
+{
+ return 1193180.0 / (speed ? speed : 0xffff); // timer oscillator speed / wait register = clock frequency
+}
diff --git a/src/adplug/core/raw.cxx b/src/adplug/core/raw.cxx
deleted file mode 100644
index fe0a3dcc4103..000000000000
--- a/src/adplug/core/raw.cxx
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * raw.c - RAW Player by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <string.h>
-
-#include "raw.h"
-
-/*** public methods *************************************/
-
-CPlayer *
-CrawPlayer::factory (Copl * newopl)
-{
- return new CrawPlayer (newopl);
-}
-
-bool
-CrawPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- char id[8];
- unsigned long i;
-
- // file validation section
- f->readString (id, 8);
- if (strncmp (id, "RAWADATA", 8))
- {
- fp.close (f);
- return false;
- }
-
- // load section
- clock = f->readInt (2); // clock speed
- length = (fp.filesize (f) - 10) / 2;
- data = new Tdata[length];
- for (i = 0; i < length; i++)
- {
- data[i].param = f->readInt (1);
- data[i].command = f->readInt (1);
- }
-
- fp.close (f);
- rewind (0);
- return true;
-}
-
-bool
-CrawPlayer::update ()
-{
- bool setspeed;
-
- if (pos >= length)
- return false;
-
- if (del)
- {
- del--;
- return !songend;
- }
-
- do
- {
- setspeed = false;
- switch (data[pos].command)
- {
- case 0:
- del = data[pos].param - 1;
- break;
- case 2:
- if (!data[pos].param)
- {
- pos++;
- speed = data[pos].param + (data[pos].command << 8);
- setspeed = true;
- }
- else
- opl->setchip (data[pos].param - 1);
- break;
- case 0xff:
- if (data[pos].param == 0xff)
- {
- rewind (0); // auto-rewind song
- songend = true;
- return !songend;
- }
- break;
- default:
- opl->write (data[pos].command, data[pos].param);
- break;
- }
- } while (data[pos++].command || setspeed);
-
- return !songend;
-}
-
-void
-CrawPlayer::rewind (int subsong)
-{
- pos = del = 0;
- speed = clock;
- songend = false;
- opl->init ();
- opl->write (1, 32); // go to 9 channel mode
-}
-
-float
-CrawPlayer::getrefresh ()
-{
- return 1193180.0 / (speed ? speed : 0xffff); // timer oscillator speed / wait register = clock frequency
-}
diff --git a/src/adplug/core/raw.h b/src/adplug/core/raw.h
index b3920015b16a..113b84378c08 100644
--- a/src/adplug/core/raw.h
+++ b/src/adplug/core/raw.h
@@ -32,7 +32,7 @@ public:
~CrawPlayer()
{ if(data) delete [] data; };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
diff --git a/src/adplug/core/rix.cc b/src/adplug/core/rix.cc
new file mode 100644
index 000000000000..7ac365e74bf4
--- /dev/null
+++ b/src/adplug/core/rix.cc
@@ -0,0 +1,611 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * rix.cpp - Softstar RIX OPL Format Player by palxex <palxex.ys168.com>
+ * BSPAL <BSPAL.ys168.com>
+ */
+
+#include <cstdlib>
+#include <string.h>
+
+#include "rix.h"
+#include "debug.h"
+
+#include <libaudcore/audstrings.h>
+
+const unsigned char
+CrixPlayer::adflag[] =
+ { 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1 };
+const unsigned char
+CrixPlayer::reg_data[] =
+ { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21 };
+const unsigned char
+CrixPlayer::ad_C0_offs[] =
+ { 0, 1, 2, 0, 1, 2, 3, 4, 5, 3, 4, 5, 6, 7, 8, 6, 7, 8 };
+const unsigned char
+ CrixPlayer::modify[] =
+ { 0, 3, 1, 4, 2, 5, 6, 9, 7, 10, 8, 11, 12, 15, 13, 16, 14, 17, 12,
+ 15, 16, 0, 14, 0, 17, 0, 13, 0
+};
+const unsigned char
+ CrixPlayer::bd_reg_data[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x04, 0x02, 0x01,
+ 0x00, 0x01, 0x01, 0x03, 0x0F, 0x05, 0x00, 0x01, 0x03, 0x0F, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x0F, 0x07, 0x00, 0x02,
+ 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
+ 0x04, 0x00, 0x08, 0x0C, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x0D, 0x04, 0x00, 0x06, 0x0F, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x0C, 0x00, 0x0F, 0x0B, 0x00, 0x08, 0x05, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0F, 0x0B, 0x00,
+ 0x07, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x0F, 0x0B, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x0F, 0x0B, 0x00, 0x07, 0x05, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00
+};
+unsigned char
+ CrixPlayer::for40reg[] =
+ { 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F
+};
+unsigned short
+ CrixPlayer::mus_time = 0x4268;
+
+/*** public methods *************************************/
+
+CPlayer *
+CrixPlayer::factory (Copl * newopl)
+{
+ return new CrixPlayer (newopl);
+}
+
+CrixPlayer::CrixPlayer (Copl * newopl):CPlayer (newopl), flag_mkf (0), file_buffer (0),
+buf_addr (0)
+{
+}
+
+CrixPlayer::~CrixPlayer ()
+{
+ if (file_buffer)
+ delete[]file_buffer;
+}
+
+bool
+CrixPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ unsigned long i = 0;
+ std::string filename (fd.filename ());
+
+ if (str_has_suffix_nocase (filename.c_str (), ".mkf"))
+ {
+ flag_mkf = 1;
+ f->seek (0);
+ int offset = f->readInt (4);
+ f->seek (offset);
+ }
+ if (f->readInt (2) != 0x55aa)
+ {
+ fp.close (f);
+ return false;
+ }
+ file_buffer = new unsigned char[fp.filesize (f) + 1];
+ f->seek (0);
+ while (!f->eof ())
+ file_buffer[i++] = f->readInt (1);
+ length = i;
+ fp.close (f);
+ if (!flag_mkf)
+ buf_addr = file_buffer;
+ rewind (0);
+ return true;
+}
+
+bool
+CrixPlayer::update ()
+{
+ int_08h_entry ();
+ return !play_end;
+}
+
+void
+CrixPlayer::rewind (int subsong)
+{
+ I = 0;
+ T = 0;
+ mus_block = 0;
+ ins_block = 0;
+ rhythm = 0;
+ music_on = 0;
+ pause_flag = 0;
+ band = 0;
+ band_low = 0;
+ e0_reg_flag = 0;
+ bd_modify = 0;
+ sustain = 0;
+ play_end = 0;
+ pos = index = 0;
+
+ memset (f_buffer, 0, sizeof (unsigned short) * 300);
+ memset (a0b0_data2, 0, sizeof (unsigned short) * 11);
+ memset (a0b0_data3, 0, 18);
+ memset (a0b0_data4, 0, 18);
+ memset (a0b0_data5, 0, 96);
+ memset (addrs_head, 0, 96);
+ memset (insbuf, 0, 28 * sizeof (unsigned short));
+ memset (displace, 0, 11 * sizeof (unsigned short));
+ memset (reg_bufs, 0, 18 * sizeof (ADDT));
+
+ if (flag_mkf)
+ {
+ unsigned int *buf_index = (unsigned int *) file_buffer;
+ int offset1 = buf_index[subsong], offset2;
+ while ((offset2 = buf_index[++subsong]) == offset1);
+ length = offset2 - offset1 + 1;
+ buf_addr = file_buffer + offset1;
+ }
+ opl->init ();
+ opl->write (1, 32); // go to OPL2 mode
+ set_new_int ();
+ data_initial ();
+}
+
+unsigned int
+CrixPlayer::getsubsongs ()
+{
+ if (flag_mkf)
+ {
+ unsigned int *buf_index = (unsigned int *) file_buffer;
+ int songs = buf_index[0] / 4, i = 0;
+ for (i = 0; i < songs; i++)
+ if (buf_index[i + 1] == buf_index[i])
+ songs--;
+ return songs;
+ }
+ else
+ return 1;
+}
+
+float
+CrixPlayer::getrefresh ()
+{
+ return 70.0f;
+}
+
+/*------------------Implemention----------------------------*/
+inline void
+CrixPlayer::set_new_int ()
+{
+// if(!ad_initial()) exit(1);
+ ad_initial ();
+}
+
+/*----------------------------------------------------------*/
+inline void
+CrixPlayer::Pause ()
+{
+ unsigned short i;
+ pause_flag = 1;
+ for (i = 0; i < 11; i++)
+ switch_ad_bd (i);
+}
+
+/*----------------------------------------------------------*/
+inline void
+CrixPlayer::ad_a0b0l_reg_ (unsigned short index, unsigned short p2,
+ unsigned short p3)
+{
+// unsigned short i = p2+a0b0_data2[index];
+ a0b0_data4[index] = p3;
+ a0b0_data3[index] = p2;
+}
+inline void
+CrixPlayer::data_initial ()
+{
+ rhythm = buf_addr[2];
+ mus_block = (buf_addr[0x0D] << 8) + buf_addr[0x0C];
+ ins_block = (buf_addr[0x09] << 8) + buf_addr[0x08];
+ I = mus_block + 1;
+ if (rhythm != 0)
+ {
+ // ad_a0b0_reg(6);
+ // ad_a0b0_reg(7);
+ // ad_a0b0_reg(8);
+ ad_a0b0l_reg_ (8, 0x18, 0);
+ ad_a0b0l_reg_ (7, 0x1F, 0);
+ }
+ bd_modify = 0;
+ // ad_bd_reg();
+ band = 0;
+ music_on = 1;
+}
+
+/*----------------------------------------------------------*/
+inline unsigned short
+CrixPlayer::ad_initial ()
+{
+ unsigned short i, j, k = 0;
+ for (i = 0; i < 25; i++)
+ {
+ f_buffer[i * 12] =
+ (unsigned int) ((i * 24 + 10000) * 0.27461678223 + 4) >> 3;
+ for (int t = 1; t < 12; t++)
+ f_buffer[i * 12 + t] =
+ (unsigned int) ((double) f_buffer[i * 12 + t - 1] * 1.06);
+ }
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 12; j++)
+ {
+ a0b0_data5[k] = i;
+ addrs_head[k] = j;
+ k++;
+ }
+ //ad_bd_reg();
+ //ad_08_reg();
+ //for(i=0;i<9;i++) ad_a0b0_reg(i);
+ e0_reg_flag = 0x20;
+ //for(i=0;i<18;i++) ad_bop(0xE0+reg_data[i],0);
+ //ad_bop(1,e0_reg_flag);
+ return 1; //ad_test();
+}
+
+/*----------------------------------------------------------*/
+inline void
+CrixPlayer::ad_bop (unsigned short reg, unsigned short value)
+{
+ if (reg == 2 || reg == 3)
+ AdPlug_LogWrite ("switch OPL2/3 mode!\n");
+ opl->write (reg & 0xff, value & 0xff);
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::int_08h_entry ()
+{
+ unsigned short band_sus = 1;
+ while (band_sus)
+ {
+ if (sustain <= 0)
+ {
+ band_sus = rix_proc ();
+ if (band_sus)
+ sustain += band_sus;
+ else
+ {
+ play_end = 1;
+ break;
+ }
+ }
+ else
+ {
+ if (band_sus)
+ sustain -= 14; /* aging */
+ break;
+ }
+ }
+}
+
+/*--------------------------------------------------------------*/
+inline unsigned short
+CrixPlayer::rix_proc ()
+{
+ unsigned char ctrl = 0;
+ if (music_on == 0 || pause_flag == 1)
+ return 0;
+ band = 0;
+ while (buf_addr[I] != 0x80 && I < length - 1)
+ {
+ band_low = buf_addr[I - 1];
+ ctrl = buf_addr[I];
+ I += 2;
+ switch (ctrl & 0xF0)
+ {
+ case 0x90:
+ rix_get_ins ();
+ rix_90_pro (ctrl & 0x0F);
+ break;
+ case 0xA0:
+ rix_A0_pro (ctrl & 0x0F, ((unsigned short) band_low) << 6);
+ break;
+ case 0xB0:
+ rix_B0_pro (ctrl & 0x0F, band_low);
+ break;
+ case 0xC0:
+ switch_ad_bd (ctrl & 0x0F);
+ if (band_low != 0)
+ rix_C0_pro (ctrl & 0x0F, band_low);
+ break;
+ default:
+ band = (ctrl << 8) + band_low;
+ break;
+ }
+ if (band != 0)
+ return band;
+ }
+ music_ctrl ();
+ I = mus_block + 1;
+ band = 0;
+ music_on = 1;
+ return 0;
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::rix_get_ins ()
+{
+ int i;
+ unsigned char *baddr = (&buf_addr[ins_block]) + (band_low << 6);
+
+ for (i = 0; i < 28; i++)
+ insbuf[i] = (baddr[i * 2 + 1] << 8) + baddr[i * 2];
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::rix_90_pro (unsigned short ctrl_l)
+{
+ if (rhythm == 0 || ctrl_l < 6)
+ {
+ ins_to_reg (modify[ctrl_l * 2], insbuf, insbuf[26]);
+ ins_to_reg (modify[ctrl_l * 2 + 1], insbuf + 13, insbuf[27]);
+ return;
+ }
+ else if (ctrl_l > 6)
+ {
+ ins_to_reg (modify[ctrl_l * 2 + 6], insbuf, insbuf[26]);
+ return;
+ }
+ else
+ {
+ ins_to_reg (12, insbuf, insbuf[26]);
+ ins_to_reg (15, insbuf + 13, insbuf[27]);
+ return;
+ }
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::rix_A0_pro (unsigned short ctrl_l, unsigned short index)
+{
+ if (rhythm == 0 || ctrl_l <= 6)
+ {
+ prepare_a0b0 (ctrl_l, index > 0x3FFF ? 0x3FFF : index);
+ ad_a0b0l_reg (ctrl_l, a0b0_data3[ctrl_l], a0b0_data4[ctrl_l]);
+ }
+ else
+ return;
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::prepare_a0b0 (unsigned short index, unsigned short v) /* important ! */
+{
+ short high = 0, low = 0;
+ unsigned int res;
+ int res1 = (v - 0x2000) * 0x19;
+ if (res1 == (int) 0xff)
+ return;
+ low = res1 / 0x2000;
+ if (low < 0)
+ {
+ low = 0x18 - low;
+ high = (signed short) low < 0 ? 0xFFFF : 0;
+ res = high;
+ res <<= 16;
+ res += low;
+ low = ((signed short) res) / (signed short) 0xFFE7;
+ a0b0_data2[index] = low;
+ low = res;
+ res = low - 0x18;
+ high = (signed short) res % 0x19;
+ low = (signed short) res / 0x19;
+ if (high != 0)
+ {
+ low = 0x19;
+ low = low - high;
+ }
+ }
+ else
+ {
+ res = high = low;
+ low = (signed short) res / (signed short) 0x19;
+ a0b0_data2[index] = low;
+ res = high;
+ low = (signed short) res % (signed short) 0x19;
+ }
+ low = (signed short) low *(signed short) 0x18;
+ displace[index] = low;
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::ad_a0b0l_reg (unsigned short index, unsigned short p2,
+ unsigned short p3)
+{
+ unsigned short data;
+ unsigned short i = p2 + a0b0_data2[index];
+ a0b0_data4[index] = p3;
+ a0b0_data3[index] = p2;
+ i = ((signed short) i <= 0x5F ? i : 0x5F);
+ i = ((signed short) i >= 0 ? i : 0);
+ data = f_buffer[addrs_head[i] + displace[index] / 2];
+ ad_bop (0xA0 + index, data);
+ data = a0b0_data5[i] * 4 + (p3 < 1 ? 0 : 0x20) + ((data >> 8) & 3);
+ ad_bop (0xB0 + index, data);
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::rix_B0_pro (unsigned short ctrl_l, unsigned short index)
+{
+ int temp = 0;
+ if (rhythm == 0 || ctrl_l < 6)
+ temp = modify[ctrl_l * 2 + 1];
+ else
+ {
+ temp = ctrl_l > 6 ? ctrl_l * 2 : ctrl_l * 2 + 1;
+ temp = modify[temp + 6];
+ }
+ for40reg[temp] = index > 0x7F ? 0x7F : index;
+ ad_40_reg (temp);
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::rix_C0_pro (unsigned short ctrl_l, unsigned short index)
+{
+ unsigned short i = index >= 12 ? index - 12 : 0;
+ if (ctrl_l < 6 || rhythm == 0)
+ {
+ ad_a0b0l_reg (ctrl_l, i, 1);
+ return;
+ }
+ else
+ {
+ if (ctrl_l != 6)
+ {
+ if (ctrl_l == 8)
+ {
+ ad_a0b0l_reg (ctrl_l, i, 0);
+ ad_a0b0l_reg (7, i + 7, 0);
+ }
+ }
+ else
+ ad_a0b0l_reg (ctrl_l, i, 0);
+ bd_modify |= bd_reg_data[ctrl_l];
+ ad_bd_reg ();
+ return;
+ }
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::switch_ad_bd (unsigned short index)
+{
+
+ if (rhythm == 0 || index < 6)
+ ad_a0b0l_reg (index, a0b0_data3[index], 0);
+ else
+ {
+ bd_modify &= (~bd_reg_data[index]), ad_bd_reg ();
+ }
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::ins_to_reg (unsigned short index, unsigned short *insb,
+ unsigned short value)
+{
+ unsigned short i;
+ for (i = 0; i < 13; i++)
+ reg_bufs[index].v[i] = insb[i];
+ reg_bufs[index].v[13] = value & 3;
+ ad_bd_reg (), ad_08_reg (),
+ ad_40_reg (index), ad_C0_reg (index), ad_60_reg (index),
+ ad_80_reg (index), ad_20_reg (index), ad_E0_reg (index);
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::ad_E0_reg (unsigned short index)
+{
+ unsigned short data = e0_reg_flag == 0 ? 0 : (reg_bufs[index].v[13] & 3);
+ ad_bop (0xE0 + reg_data[index], data);
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::ad_20_reg (unsigned short index)
+{
+ unsigned short data = (reg_bufs[index].v[9] < 1 ? 0 : 0x80);
+ data += (reg_bufs[index].v[10] < 1 ? 0 : 0x40);
+ data += (reg_bufs[index].v[5] < 1 ? 0 : 0x20);
+ data += (reg_bufs[index].v[11] < 1 ? 0 : 0x10);
+ data += (reg_bufs[index].v[1] & 0x0F);
+ ad_bop (0x20 + reg_data[index], data);
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::ad_80_reg (unsigned short index)
+{
+ unsigned short data = (reg_bufs[index].v[7] & 0x0F), temp =
+ reg_bufs[index].v[4];
+ data |= (temp << 4);
+ ad_bop (0x80 + reg_data[index], data);
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::ad_60_reg (unsigned short index)
+{
+ unsigned short data = reg_bufs[index].v[6] & 0x0F, temp =
+ reg_bufs[index].v[3];
+ data |= (temp << 4);
+ ad_bop (0x60 + reg_data[index], data);
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::ad_C0_reg (unsigned short index)
+{
+ unsigned short data = reg_bufs[index].v[2];
+ if (adflag[index] == 1)
+ return;
+ data *= 2, data |= (reg_bufs[index].v[12] < 1 ? 1 : 0);
+ ad_bop (0xC0 + ad_C0_offs[index], data);
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::ad_40_reg (unsigned short index)
+{
+ unsigned int res = 0;
+ unsigned short data = 0, temp = reg_bufs[index].v[0];
+ data = 0x3F - (0x3F & reg_bufs[index].v[8]),
+ data *= for40reg[index], data *= 2, data += 0x7F, res = data;
+ data = res / 0xFE, data -= 0x3F, data = -data, data |= temp << 6;
+ ad_bop (0x40 + reg_data[index], data);
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::ad_bd_reg ()
+{
+ unsigned short data = rhythm < 1 ? 0 : 0x20;
+ data |= bd_modify;
+ ad_bop (0xBD, data);
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::ad_a0b0_reg (unsigned short index)
+{
+ ad_bop (0xA0 + index, 0);
+ ad_bop (0xB0 + index, 0);
+}
+
+/*--------------------------------------------------------------*/
+inline void
+CrixPlayer::music_ctrl ()
+{
+ int i;
+ for (i = 0; i < 11; i++)
+ switch_ad_bd (i);
+}
diff --git a/src/adplug/core/rix.cxx b/src/adplug/core/rix.cxx
deleted file mode 100644
index ccafac592826..000000000000
--- a/src/adplug/core/rix.cxx
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * rix.cpp - Softstar RIX OPL Format Player by palxex <palxex.ys168.com>
- * BSPAL <BSPAL.ys168.com>
- */
-
-#include <cstdlib>
-#include <string.h>
-
-#include <glib.h>
-
-#include "rix.h"
-#include "debug.h"
-
-const unsigned char
-CrixPlayer::adflag[] =
- { 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1 };
-const unsigned char
-CrixPlayer::reg_data[] =
- { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21 };
-const unsigned char
-CrixPlayer::ad_C0_offs[] =
- { 0, 1, 2, 0, 1, 2, 3, 4, 5, 3, 4, 5, 6, 7, 8, 6, 7, 8 };
-const unsigned char
- CrixPlayer::modify[] =
- { 0, 3, 1, 4, 2, 5, 6, 9, 7, 10, 8, 11, 12, 15, 13, 16, 14, 17, 12,
- 15, 16, 0, 14, 0, 17, 0, 13, 0
-};
-const unsigned char
- CrixPlayer::bd_reg_data[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x04, 0x02, 0x01,
- 0x00, 0x01, 0x01, 0x03, 0x0F, 0x05, 0x00, 0x01, 0x03, 0x0F, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x0F, 0x07, 0x00, 0x02,
- 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
- 0x04, 0x00, 0x08, 0x0C, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x0D, 0x04, 0x00, 0x06, 0x0F, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x0C, 0x00, 0x0F, 0x0B, 0x00, 0x08, 0x05, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0F, 0x0B, 0x00,
- 0x07, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x0F, 0x0B, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x0F, 0x0B, 0x00, 0x07, 0x05, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00
-};
-unsigned char
- CrixPlayer::for40reg[] =
- { 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
- 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F
-};
-unsigned short
- CrixPlayer::mus_time = 0x4268;
-
-/*** public methods *************************************/
-
-CPlayer *
-CrixPlayer::factory (Copl * newopl)
-{
- return new CrixPlayer (newopl);
-}
-
-CrixPlayer::CrixPlayer (Copl * newopl):CPlayer (newopl), flag_mkf (0), file_buffer (0),
-buf_addr (0)
-{
-}
-
-CrixPlayer::~CrixPlayer ()
-{
- if (file_buffer)
- delete[]file_buffer;
-}
-
-bool
-CrixPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- unsigned long i = 0;
- std::string filename (vfs_get_filename (fd));
-
- if (g_ascii_strcasecmp (filename.substr (filename.length () - 4, 4).c_str (), ".mkf")
- == 0)
- {
- flag_mkf = 1;
- f->seek (0);
- int offset = f->readInt (4);
- f->seek (offset);
- }
- if (f->readInt (2) != 0x55aa)
- {
- fp.close (f);
- return false;
- }
- file_buffer = new unsigned char[fp.filesize (f) + 1];
- f->seek (0);
- while (!f->eof ())
- file_buffer[i++] = f->readInt (1);
- length = i;
- fp.close (f);
- if (!flag_mkf)
- buf_addr = file_buffer;
- rewind (0);
- return true;
-}
-
-bool
-CrixPlayer::update ()
-{
- int_08h_entry ();
- return !play_end;
-}
-
-void
-CrixPlayer::rewind (int subsong)
-{
- I = 0;
- T = 0;
- mus_block = 0;
- ins_block = 0;
- rhythm = 0;
- music_on = 0;
- pause_flag = 0;
- band = 0;
- band_low = 0;
- e0_reg_flag = 0;
- bd_modify = 0;
- sustain = 0;
- play_end = 0;
- pos = index = 0;
-
- memset (f_buffer, 0, sizeof (unsigned short) * 300);
- memset (a0b0_data2, 0, sizeof (unsigned short) * 11);
- memset (a0b0_data3, 0, 18);
- memset (a0b0_data4, 0, 18);
- memset (a0b0_data5, 0, 96);
- memset (addrs_head, 0, 96);
- memset (insbuf, 0, 28 * sizeof (unsigned short));
- memset (displace, 0, 11 * sizeof (unsigned short));
- memset (reg_bufs, 0, 18 * sizeof (ADDT));
-
- if (flag_mkf)
- {
- unsigned int *buf_index = (unsigned int *) file_buffer;
- int offset1 = buf_index[subsong], offset2;
- while ((offset2 = buf_index[++subsong]) == offset1);
- length = offset2 - offset1 + 1;
- buf_addr = file_buffer + offset1;
- }
- opl->init ();
- opl->write (1, 32); // go to OPL2 mode
- set_new_int ();
- data_initial ();
-}
-
-unsigned int
-CrixPlayer::getsubsongs ()
-{
- if (flag_mkf)
- {
- unsigned int *buf_index = (unsigned int *) file_buffer;
- int songs = buf_index[0] / 4, i = 0;
- for (i = 0; i < songs; i++)
- if (buf_index[i + 1] == buf_index[i])
- songs--;
- return songs;
- }
- else
- return 1;
-}
-
-float
-CrixPlayer::getrefresh ()
-{
- return 70.0f;
-}
-
-/*------------------Implemention----------------------------*/
-inline void
-CrixPlayer::set_new_int ()
-{
-// if(!ad_initial()) exit(1);
- ad_initial ();
-}
-
-/*----------------------------------------------------------*/
-inline void
-CrixPlayer::Pause ()
-{
- register unsigned short i;
- pause_flag = 1;
- for (i = 0; i < 11; i++)
- switch_ad_bd (i);
-}
-
-/*----------------------------------------------------------*/
-inline void
-CrixPlayer::ad_a0b0l_reg_ (unsigned short index, unsigned short p2,
- unsigned short p3)
-{
-// unsigned short i = p2+a0b0_data2[index];
- a0b0_data4[index] = p3;
- a0b0_data3[index] = p2;
-}
-inline void
-CrixPlayer::data_initial ()
-{
- rhythm = buf_addr[2];
- mus_block = (buf_addr[0x0D] << 8) + buf_addr[0x0C];
- ins_block = (buf_addr[0x09] << 8) + buf_addr[0x08];
- I = mus_block + 1;
- if (rhythm != 0)
- {
- // ad_a0b0_reg(6);
- // ad_a0b0_reg(7);
- // ad_a0b0_reg(8);
- ad_a0b0l_reg_ (8, 0x18, 0);
- ad_a0b0l_reg_ (7, 0x1F, 0);
- }
- bd_modify = 0;
- // ad_bd_reg();
- band = 0;
- music_on = 1;
-}
-
-/*----------------------------------------------------------*/
-inline unsigned short
-CrixPlayer::ad_initial ()
-{
- register unsigned short i, j, k = 0;
- for (i = 0; i < 25; i++)
- {
- f_buffer[i * 12] =
- (unsigned int) ((i * 24 + 10000) * 0.27461678223 + 4) >> 3;
- for (int t = 1; t < 12; t++)
- f_buffer[i * 12 + t] =
- (unsigned int) ((double) f_buffer[i * 12 + t - 1] * 1.06);
- }
- for (i = 0; i < 8; i++)
- for (j = 0; j < 12; j++)
- {
- a0b0_data5[k] = i;
- addrs_head[k] = j;
- k++;
- }
- //ad_bd_reg();
- //ad_08_reg();
- //for(i=0;i<9;i++) ad_a0b0_reg(i);
- e0_reg_flag = 0x20;
- //for(i=0;i<18;i++) ad_bop(0xE0+reg_data[i],0);
- //ad_bop(1,e0_reg_flag);
- return 1; //ad_test();
-}
-
-/*----------------------------------------------------------*/
-inline void
-CrixPlayer::ad_bop (unsigned short reg, unsigned short value)
-{
- if (reg == 2 || reg == 3)
- AdPlug_LogWrite ("switch OPL2/3 mode!\n");
- opl->write (reg & 0xff, value & 0xff);
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::int_08h_entry ()
-{
- unsigned short band_sus = 1;
- while (band_sus)
- {
- if (sustain <= 0)
- {
- band_sus = rix_proc ();
- if (band_sus)
- sustain += band_sus;
- else
- {
- play_end = 1;
- break;
- }
- }
- else
- {
- if (band_sus)
- sustain -= 14; /* aging */
- break;
- }
- }
-}
-
-/*--------------------------------------------------------------*/
-inline unsigned short
-CrixPlayer::rix_proc ()
-{
- unsigned char ctrl = 0;
- if (music_on == 0 || pause_flag == 1)
- return 0;
- band = 0;
- while (buf_addr[I] != 0x80 && I < length - 1)
- {
- band_low = buf_addr[I - 1];
- ctrl = buf_addr[I];
- I += 2;
- switch (ctrl & 0xF0)
- {
- case 0x90:
- rix_get_ins ();
- rix_90_pro (ctrl & 0x0F);
- break;
- case 0xA0:
- rix_A0_pro (ctrl & 0x0F, ((unsigned short) band_low) << 6);
- break;
- case 0xB0:
- rix_B0_pro (ctrl & 0x0F, band_low);
- break;
- case 0xC0:
- switch_ad_bd (ctrl & 0x0F);
- if (band_low != 0)
- rix_C0_pro (ctrl & 0x0F, band_low);
- break;
- default:
- band = (ctrl << 8) + band_low;
- break;
- }
- if (band != 0)
- return band;
- }
- music_ctrl ();
- I = mus_block + 1;
- band = 0;
- music_on = 1;
- return 0;
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::rix_get_ins ()
-{
- int i;
- unsigned char *baddr = (&buf_addr[ins_block]) + (band_low << 6);
-
- for (i = 0; i < 28; i++)
- insbuf[i] = (baddr[i * 2 + 1] << 8) + baddr[i * 2];
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::rix_90_pro (unsigned short ctrl_l)
-{
- if (rhythm == 0 || ctrl_l < 6)
- {
- ins_to_reg (modify[ctrl_l * 2], insbuf, insbuf[26]);
- ins_to_reg (modify[ctrl_l * 2 + 1], insbuf + 13, insbuf[27]);
- return;
- }
- else if (ctrl_l > 6)
- {
- ins_to_reg (modify[ctrl_l * 2 + 6], insbuf, insbuf[26]);
- return;
- }
- else
- {
- ins_to_reg (12, insbuf, insbuf[26]);
- ins_to_reg (15, insbuf + 13, insbuf[27]);
- return;
- }
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::rix_A0_pro (unsigned short ctrl_l, unsigned short index)
-{
- if (rhythm == 0 || ctrl_l <= 6)
- {
- prepare_a0b0 (ctrl_l, index > 0x3FFF ? 0x3FFF : index);
- ad_a0b0l_reg (ctrl_l, a0b0_data3[ctrl_l], a0b0_data4[ctrl_l]);
- }
- else
- return;
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::prepare_a0b0 (unsigned short index, unsigned short v) /* important ! */
-{
- short high = 0, low = 0;
- unsigned int res;
- int res1 = (v - 0x2000) * 0x19;
- if (res1 == (int) 0xff)
- return;
- low = res1 / 0x2000;
- if (low < 0)
- {
- low = 0x18 - low;
- high = (signed short) low < 0 ? 0xFFFF : 0;
- res = high;
- res <<= 16;
- res += low;
- low = ((signed short) res) / (signed short) 0xFFE7;
- a0b0_data2[index] = low;
- low = res;
- res = low - 0x18;
- high = (signed short) res % 0x19;
- low = (signed short) res / 0x19;
- if (high != 0)
- {
- low = 0x19;
- low = low - high;
- }
- }
- else
- {
- res = high = low;
- low = (signed short) res / (signed short) 0x19;
- a0b0_data2[index] = low;
- res = high;
- low = (signed short) res % (signed short) 0x19;
- }
- low = (signed short) low *(signed short) 0x18;
- displace[index] = low;
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::ad_a0b0l_reg (unsigned short index, unsigned short p2,
- unsigned short p3)
-{
- unsigned short data;
- unsigned short i = p2 + a0b0_data2[index];
- a0b0_data4[index] = p3;
- a0b0_data3[index] = p2;
- i = ((signed short) i <= 0x5F ? i : 0x5F);
- i = ((signed short) i >= 0 ? i : 0);
- data = f_buffer[addrs_head[i] + displace[index] / 2];
- ad_bop (0xA0 + index, data);
- data = a0b0_data5[i] * 4 + (p3 < 1 ? 0 : 0x20) + ((data >> 8) & 3);
- ad_bop (0xB0 + index, data);
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::rix_B0_pro (unsigned short ctrl_l, unsigned short index)
-{
- register int temp = 0;
- if (rhythm == 0 || ctrl_l < 6)
- temp = modify[ctrl_l * 2 + 1];
- else
- {
- temp = ctrl_l > 6 ? ctrl_l * 2 : ctrl_l * 2 + 1;
- temp = modify[temp + 6];
- }
- for40reg[temp] = index > 0x7F ? 0x7F : index;
- ad_40_reg (temp);
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::rix_C0_pro (unsigned short ctrl_l, unsigned short index)
-{
- register unsigned short i = index >= 12 ? index - 12 : 0;
- if (ctrl_l < 6 || rhythm == 0)
- {
- ad_a0b0l_reg (ctrl_l, i, 1);
- return;
- }
- else
- {
- if (ctrl_l != 6)
- {
- if (ctrl_l == 8)
- {
- ad_a0b0l_reg (ctrl_l, i, 0);
- ad_a0b0l_reg (7, i + 7, 0);
- }
- }
- else
- ad_a0b0l_reg (ctrl_l, i, 0);
- bd_modify |= bd_reg_data[ctrl_l];
- ad_bd_reg ();
- return;
- }
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::switch_ad_bd (unsigned short index)
-{
-
- if (rhythm == 0 || index < 6)
- ad_a0b0l_reg (index, a0b0_data3[index], 0);
- else
- {
- bd_modify &= (~bd_reg_data[index]), ad_bd_reg ();
- }
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::ins_to_reg (unsigned short index, unsigned short *insb,
- unsigned short value)
-{
- register unsigned short i;
- for (i = 0; i < 13; i++)
- reg_bufs[index].v[i] = insb[i];
- reg_bufs[index].v[13] = value & 3;
- ad_bd_reg (), ad_08_reg (),
- ad_40_reg (index), ad_C0_reg (index), ad_60_reg (index),
- ad_80_reg (index), ad_20_reg (index), ad_E0_reg (index);
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::ad_E0_reg (unsigned short index)
-{
- unsigned short data = e0_reg_flag == 0 ? 0 : (reg_bufs[index].v[13] & 3);
- ad_bop (0xE0 + reg_data[index], data);
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::ad_20_reg (unsigned short index)
-{
- unsigned short data = (reg_bufs[index].v[9] < 1 ? 0 : 0x80);
- data += (reg_bufs[index].v[10] < 1 ? 0 : 0x40);
- data += (reg_bufs[index].v[5] < 1 ? 0 : 0x20);
- data += (reg_bufs[index].v[11] < 1 ? 0 : 0x10);
- data += (reg_bufs[index].v[1] & 0x0F);
- ad_bop (0x20 + reg_data[index], data);
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::ad_80_reg (unsigned short index)
-{
- unsigned short data = (reg_bufs[index].v[7] & 0x0F), temp =
- reg_bufs[index].v[4];
- data |= (temp << 4);
- ad_bop (0x80 + reg_data[index], data);
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::ad_60_reg (unsigned short index)
-{
- unsigned short data = reg_bufs[index].v[6] & 0x0F, temp =
- reg_bufs[index].v[3];
- data |= (temp << 4);
- ad_bop (0x60 + reg_data[index], data);
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::ad_C0_reg (unsigned short index)
-{
- unsigned short data = reg_bufs[index].v[2];
- if (adflag[index] == 1)
- return;
- data *= 2, data |= (reg_bufs[index].v[12] < 1 ? 1 : 0);
- ad_bop (0xC0 + ad_C0_offs[index], data);
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::ad_40_reg (unsigned short index)
-{
- unsigned int res = 0;
- unsigned short data = 0, temp = reg_bufs[index].v[0];
- data = 0x3F - (0x3F & reg_bufs[index].v[8]),
- data *= for40reg[index], data *= 2, data += 0x7F, res = data;
- data = res / 0xFE, data -= 0x3F, data = -data, data |= temp << 6;
- ad_bop (0x40 + reg_data[index], data);
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::ad_bd_reg ()
-{
- unsigned short data = rhythm < 1 ? 0 : 0x20;
- data |= bd_modify;
- ad_bop (0xBD, data);
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::ad_a0b0_reg (unsigned short index)
-{
- ad_bop (0xA0 + index, 0);
- ad_bop (0xB0 + index, 0);
-}
-
-/*--------------------------------------------------------------*/
-inline void
-CrixPlayer::music_ctrl ()
-{
- register int i;
- for (i = 0; i < 11; i++)
- switch_ad_bd (i);
-}
diff --git a/src/adplug/core/rix.h b/src/adplug/core/rix.h
index 1e349226cdb5..5c83ac4cb101 100644
--- a/src/adplug/core/rix.h
+++ b/src/adplug/core/rix.h
@@ -30,7 +30,7 @@ class CrixPlayer: public CPlayer
CrixPlayer(Copl *newopl);
~CrixPlayer();
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
diff --git a/src/adplug/core/rol.cc b/src/adplug/core/rol.cc
new file mode 100644
index 000000000000..a910218acc45
--- /dev/null
+++ b/src/adplug/core/rol.cc
@@ -0,0 +1,747 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * rol.h - ROL Player by OPLx <oplx at yahoo.com>
+ *
+ * Visit: http://tenacity.hispeed.com/aomit/oplx/
+ */
+#include <algorithm>
+#include <string.h>
+
+#include "rol.h"
+#include "debug.h"
+
+int const CrolPlayer::kSizeofDataRecord = 30;
+int const CrolPlayer::kMaxTickBeat = 60;
+int const CrolPlayer::kSilenceNote = -12;
+int const CrolPlayer::kNumMelodicVoices = 9;
+int const CrolPlayer::kNumPercussiveVoices = 11;
+int const CrolPlayer::kBassDrumChannel = 6;
+int const CrolPlayer::kSnareDrumChannel = 7;
+int const CrolPlayer::kTomtomChannel = 8;
+int const CrolPlayer::kTomtomFreq = 2;//4;
+int const CrolPlayer::kSnareDrumFreq = 2;//kTomtomFreq + 7;
+float const CrolPlayer::kDefaultUpdateTme = 18.2f;
+float const CrolPlayer::kPitchFactor = 400.0f;
+
+static const unsigned char drum_table[4] = {0x14, 0x12, 0x15, 0x11};
+
+CrolPlayer::uint16 const CrolPlayer::kNoteTable[12] =
+{
+ 340, // C
+ 363, // C#
+ 385, // D
+ 408, // D#
+ 432, // E
+ 458, // F
+ 485, // F#
+ 514, // G
+ 544, // G#
+ 577, // A
+ 611, // A#
+ 647 // B
+};
+
+/*** public methods **************************************/
+
+CPlayer *CrolPlayer::factory(Copl *newopl)
+{
+ return new CrolPlayer(newopl);
+}
+//---------------------------------------------------------
+CrolPlayer::CrolPlayer(Copl *newopl)
+: CPlayer ( newopl )
+ ,rol_header ( nullptr )
+ ,mNextTempoEvent ( 0 )
+ ,mCurrTick ( 0 )
+ ,mTimeOfLastNote ( 0 )
+ ,mRefresh ( kDefaultUpdateTme )
+ ,bdRegister ( 0 )
+{
+ int n;
+
+ memset(bxRegister, 0, sizeof(bxRegister) );
+ memset(volumeCache, 0, sizeof(volumeCache) );
+ memset(freqCache, 0, sizeof(freqCache) );
+
+ for(n=0; n<11; n++)
+ pitchCache[n]=1.0f;
+}
+//---------------------------------------------------------
+CrolPlayer::~CrolPlayer()
+{
+ if(rol_header)
+ {
+ delete rol_header;
+ rol_header = 0;
+ }
+}
+//---------------------------------------------------------
+bool CrolPlayer::load(VFSFile &fd, const CFileProvider &fp)
+{
+ binistream *f = fp.open(fd); if(!f) return false;
+ std::string filename(fd.filename ());
+
+ char *fn = new char[filename.length()+12];
+ int i;
+ std::string bnk_filename;
+
+ AdPlug_LogWrite("*** CrolPlayer::load(f, \"%s\") ***\n", filename.c_str());
+ strcpy(fn,filename.data());
+ for (i=strlen(fn)-1; i>=0; i--)
+ if (fn[i] == '/' || fn[i] == '\\')
+ break;
+ strcpy(fn+i+1,"standard.bnk");
+ bnk_filename = fn;
+ delete [] fn; fn = 0;
+ AdPlug_LogWrite("bnk_filename = \"%s\"\n",bnk_filename.c_str());
+
+ rol_header = new SRolHeader;
+ memset( rol_header, 0, sizeof(SRolHeader) );
+
+ rol_header->version_major = f->readInt( 2 );
+ rol_header->version_minor = f->readInt( 2 );
+
+ // Version check
+ if(rol_header->version_major != 0 || rol_header->version_minor != 4) {
+ AdPlug_LogWrite("Unsupported file version %d.%d or not a ROL file!\n",
+ rol_header->version_major, rol_header->version_minor);
+ AdPlug_LogWrite("--- CrolPlayer::load ---\n");
+ fp.close(f);
+ return false;
+ }
+
+ f->seek( 40, binio::Add );
+
+ rol_header->ticks_per_beat = f->readInt( 2 );
+ rol_header->beats_per_measure = f->readInt( 2 );
+ rol_header->edit_scale_y = f->readInt( 2 );
+ rol_header->edit_scale_x = f->readInt( 2 );
+
+ f->seek( 1, binio::Add );
+
+ rol_header->mode = f->readInt(1);
+
+ f->seek( 90+38+15, binio::Add );
+
+ rol_header->basic_tempo = f->readFloat( binio::Single );
+
+ load_tempo_events( f );
+
+ mTimeOfLastNote = 0;
+
+ if( load_voice_data( f, bnk_filename, fp ) != true )
+ {
+ AdPlug_LogWrite("CrolPlayer::load_voice_data(f) failed!\n");
+ AdPlug_LogWrite("--- CrolPlayer::load ---\n");
+
+ fp.close( f );
+ return false;
+ }
+
+ fp.close( f );
+
+ rewind( 0 );
+ AdPlug_LogWrite("--- CrolPlayer::load ---\n");
+ return true;
+}
+//---------------------------------------------------------
+bool CrolPlayer::update()
+{
+ if( mNextTempoEvent < mTempoEvents.size() &&
+ mTempoEvents[mNextTempoEvent].time == mCurrTick )
+ {
+ SetRefresh( mTempoEvents[mNextTempoEvent].multiplier );
+ ++mNextTempoEvent;
+ }
+
+ TVoiceData::iterator curr = voice_data.begin();
+ TVoiceData::iterator end = voice_data.end();
+ int voice = 0;
+
+ while( curr != end )
+ {
+ UpdateVoice( voice, *curr );
+ ++curr;
+ ++voice;
+ }
+
+ ++mCurrTick;
+
+ if( mCurrTick > mTimeOfLastNote )
+ {
+ return false;
+ }
+
+ return true;
+ //return ( mCurrTick > mTimeOfLastNote ) ? false : true;
+}
+//---------------------------------------------------------
+void CrolPlayer::rewind( int subsong )
+{
+ TVoiceData::iterator curr = voice_data.begin();
+ TVoiceData::iterator end = voice_data.end();
+
+ while( curr != end )
+ {
+ CVoiceData &voice = *curr;
+
+ voice.Reset();
+ ++curr;
+ }
+
+ memset(bxRegister, 0, sizeof(bxRegister) );
+ memset(volumeCache, 0, sizeof(volumeCache) );
+
+ bdRegister = 0;
+
+ opl->init(); // initialize to melodic by default
+ opl->write(1,0x20); // Enable waveform select (bit 5)
+
+ if( rol_header->mode == 0 )
+ {
+ opl->write( 0xbd, 0x20 ); // select rhythm mode (bit 5)
+ bdRegister = 0x20;
+
+ SetFreq( kTomtomChannel, 24 );
+ SetFreq( kSnareDrumChannel, 31 );
+ }
+
+ mNextTempoEvent = 0;
+ mCurrTick = 0;
+
+ SetRefresh(1.0f);
+}
+//---------------------------------------------------------
+inline float fmin( int const a, int const b )
+{
+ return static_cast<float>( a < b ? a : b );
+}
+//---------------------------------------------------------
+void CrolPlayer::SetRefresh( float const multiplier )
+{
+ float const tickBeat = fmin(kMaxTickBeat, rol_header->ticks_per_beat);
+
+ mRefresh = (tickBeat*rol_header->basic_tempo*multiplier) / 60.0f;
+}
+//---------------------------------------------------------
+float CrolPlayer::getrefresh()
+{
+ return mRefresh;
+}
+//---------------------------------------------------------
+void CrolPlayer::UpdateVoice( int const voice, CVoiceData &voiceData )
+{
+ TNoteEvents const &nEvents = voiceData.note_events;
+
+ if( nEvents.empty() || voiceData.mEventStatus & CVoiceData::kES_NoteEnd )
+ {
+ return; // no note data to process, don't bother doing anything.
+ }
+
+ TInstrumentEvents &iEvents = voiceData.instrument_events;
+ TVolumeEvents &vEvents = voiceData.volume_events;
+ TPitchEvents &pEvents = voiceData.pitch_events;
+
+ if (iEvents.empty()) {
+ return; // prevent out-of-bounds access
+ }
+ if( !(voiceData.mEventStatus & CVoiceData::kES_InstrEnd ) &&
+ iEvents[voiceData.next_instrument_event].time == mCurrTick )
+ {
+ if( voiceData.next_instrument_event < iEvents.size() )
+ {
+ send_ins_data_to_chip( voice, iEvents[voiceData.next_instrument_event].ins_index );
+ ++voiceData.next_instrument_event;
+ }
+ else
+ {
+ voiceData.mEventStatus |= CVoiceData::kES_InstrEnd;
+ }
+ }
+
+ if (vEvents.empty()) {
+ return; // prevent out-of-bounds access
+ }
+ if( !(voiceData.mEventStatus & CVoiceData::kES_VolumeEnd ) &&
+ vEvents[voiceData.next_volume_event].time == mCurrTick )
+ {
+ SVolumeEvent const &volumeEvent = vEvents[voiceData.next_volume_event];
+
+ if( voiceData.next_volume_event < vEvents.size() )
+ {
+ int const volume = (int)(63.0f*(1.0f - volumeEvent.multiplier));
+
+ SetVolume( voice, volume );
+
+ ++voiceData.next_volume_event; // move to next volume event
+ }
+ else
+ {
+ voiceData.mEventStatus |= CVoiceData::kES_VolumeEnd;
+ }
+ }
+
+ if( voiceData.mForceNote || voiceData.current_note_duration > voiceData.mNoteDuration-1 )
+ {
+ if( mCurrTick != 0 )
+ {
+ ++voiceData.current_note;
+ }
+
+ if( voiceData.current_note < nEvents.size() )
+ {
+ SNoteEvent const ¬eEvent = nEvents[voiceData.current_note];
+
+ SetNote( voice, noteEvent.number );
+ voiceData.current_note_duration = 0;
+ voiceData.mNoteDuration = noteEvent.duration;
+ voiceData.mForceNote = false;
+ }
+ else
+ {
+ SetNote( voice, kSilenceNote );
+ voiceData.mEventStatus |= CVoiceData::kES_NoteEnd;
+ return;
+ }
+ }
+
+ if (pEvents.empty()) {
+ return; // prevent out-of-bounds access
+ }
+ if( !(voiceData.mEventStatus & CVoiceData::kES_PitchEnd ) &&
+ pEvents[voiceData.next_pitch_event].time == mCurrTick )
+ {
+ if( voiceData.next_pitch_event < pEvents.size() )
+ {
+ SetPitch(voice,pEvents[voiceData.next_pitch_event].variation);
+ ++voiceData.next_pitch_event;
+ }
+ else
+ {
+ voiceData.mEventStatus |= CVoiceData::kES_PitchEnd;
+ }
+ }
+
+ ++voiceData.current_note_duration;
+}
+//---------------------------------------------------------
+void CrolPlayer::SetNote( int const voice, int const note )
+{
+ if( voice < kBassDrumChannel || rol_header->mode )
+ {
+ SetNoteMelodic( voice, note );
+ }
+ else
+ {
+ SetNotePercussive( voice, note );
+ }
+}
+//---------------------------------------------------------
+void CrolPlayer::SetNotePercussive( int const voice, int const note )
+{
+ int const bit_pos = 4-voice+kBassDrumChannel;
+
+ bdRegister &= ~( 1<<bit_pos );
+ opl->write( 0xbd, bdRegister );
+
+ if( note != kSilenceNote )
+ {
+ switch( voice )
+ {
+ case kTomtomChannel:
+ SetFreq( kSnareDrumChannel, note+7 );
+ case kBassDrumChannel:
+ SetFreq( voice, note );
+ break;
+ }
+
+ bdRegister |= 1<<bit_pos;
+ opl->write( 0xbd, bdRegister );
+ }
+}
+//---------------------------------------------------------
+void CrolPlayer::SetNoteMelodic( int const voice, int const note )
+{
+ opl->write( 0xb0+voice, bxRegister[voice] & ~0x20 );
+
+ if( note != kSilenceNote )
+ {
+ SetFreq( voice, note, true );
+ }
+}
+//---------------------------------------------------------
+void CrolPlayer::SetPitch(int const voice, real32 const variation)
+{
+ pitchCache[voice] = variation;
+ freqCache[voice] += (uint16)((((float)freqCache[voice])*(variation-1.0f)) / kPitchFactor);
+
+ opl->write(0xa0+voice,freqCache[voice] & 0xff);
+}
+//---------------------------------------------------------
+void CrolPlayer::SetFreq( int const voice, int const note, bool const keyOn )
+{
+ uint16 freq = kNoteTable[note%12] + ((note/12) << 10);
+ freq += (uint16)((((float)freq)*(pitchCache[voice]-1.0f))/kPitchFactor);
+
+ freqCache[voice] = freq;
+ bxRegister[voice] = ((freq >> 8) & 0x1f);
+
+ opl->write( 0xa0+voice, freq & 0xff );
+ opl->write( 0xb0+voice, bxRegister[voice] | (keyOn ? 0x20 : 0x0) );
+}
+//---------------------------------------------------------
+void CrolPlayer::SetVolume( int const voice, int const volume )
+{
+ volumeCache[voice] = (volumeCache[voice] &0xc0) | volume;
+
+ int const op_offset = ( voice < kSnareDrumChannel || rol_header->mode ) ?
+ op_table[voice]+3 : drum_table[voice-kSnareDrumChannel];
+
+ opl->write( 0x40+op_offset, volumeCache[voice] );
+}
+//---------------------------------------------------------
+void CrolPlayer::send_ins_data_to_chip( int const voice, int const ins_index )
+{
+ SRolInstrument &instrument = ins_list[ins_index].instrument;
+
+ send_operator( voice, instrument.modulator, instrument.carrier );
+}
+//---------------------------------------------------------
+void CrolPlayer::send_operator( int const voice, SOPL2Op const &modulator, SOPL2Op const &carrier )
+{
+ if( voice < kSnareDrumChannel || rol_header->mode )
+ {
+ int const op_offset = op_table[voice];
+
+ opl->write( 0x20+op_offset, modulator.ammulti );
+ opl->write( 0x40+op_offset, modulator.ksltl );
+ opl->write( 0x60+op_offset, modulator.ardr );
+ opl->write( 0x80+op_offset, modulator.slrr );
+ opl->write( 0xc0+voice , modulator.fbc );
+ opl->write( 0xe0+op_offset, modulator.waveform );
+
+ volumeCache[voice] = (carrier.ksltl & 0xc0) | (volumeCache[voice] & 0x3f);
+
+ opl->write( 0x23+op_offset, carrier.ammulti );
+ opl->write( 0x43+op_offset, volumeCache[voice] );
+ opl->write( 0x63+op_offset, carrier.ardr );
+ opl->write( 0x83+op_offset, carrier.slrr );
+// opl->write( 0xc3+voice , carrier.fbc ); <- don't bother writing this.
+ opl->write( 0xe3+op_offset, carrier.waveform );
+ }
+ else
+ {
+ int const op_offset = drum_table[voice-kSnareDrumChannel];
+
+ volumeCache[voice] = (modulator.ksltl & 0xc0) | (volumeCache[voice] & 0x3f);
+
+ opl->write( 0x20+op_offset, modulator.ammulti );
+ opl->write( 0x40+op_offset, volumeCache[voice] );
+ opl->write( 0x60+op_offset, modulator.ardr );
+ opl->write( 0x80+op_offset, modulator.slrr );
+ opl->write( 0xc0+voice , modulator.fbc );
+ opl->write( 0xe0+op_offset, modulator.waveform );
+ }
+}
+//---------------------------------------------------------
+void CrolPlayer::load_tempo_events( binistream *f )
+{
+ int16 const num_tempo_events = f->readInt( 2 );
+
+ if (num_tempo_events<0) {
+ return;
+ }
+ mTempoEvents.reserve( num_tempo_events );
+
+ for(int i=0; i<num_tempo_events; ++i)
+ {
+ STempoEvent event;
+
+ event.time = f->readInt( 2 );
+ event.multiplier = f->readFloat( binio::Single );
+ mTempoEvents.push_back( event );
+ }
+}
+//---------------------------------------------------------
+bool CrolPlayer::load_voice_data( binistream *f, std::string const &bnk_filename, const CFileProvider &fp )
+{
+ SBnkHeader bnk_header;
+ VFSFile fd(bnk_filename.c_str(), "rb");
+ binistream *bnk_file = fp.open(fd);
+
+ if( bnk_file )
+ {
+ load_bnk_info( bnk_file, bnk_header );
+
+ int const numVoices = rol_header->mode ? kNumMelodicVoices : kNumPercussiveVoices;
+
+ voice_data.reserve( numVoices );
+ for(int i=0; i<numVoices; ++i)
+ {
+ CVoiceData voice;
+
+ load_note_events( f, voice );
+ load_instrument_events( f, voice, bnk_file, bnk_header );
+ load_volume_events( f, voice );
+ load_pitch_events( f, voice );
+
+ voice_data.push_back( voice );
+ }
+
+ fp.close(bnk_file);
+
+ return true;
+ }
+
+ return false;
+}
+//---------------------------------------------------------
+void CrolPlayer::load_note_events( binistream *f, CVoiceData &voice )
+{
+ f->seek( 15, binio::Add );
+
+ int16 const time_of_last_note = f->readInt( 2 );
+
+ if( time_of_last_note != 0 )
+ {
+ TNoteEvents ¬e_events = voice.note_events;
+ int16 total_duration = 0;
+
+ do
+ {
+ SNoteEvent event;
+
+ event.number = f->readInt( 2 );
+ event.duration = f->readInt( 2 );
+
+ event.number += kSilenceNote; // adding -12
+
+ note_events.push_back( event );
+
+ total_duration += event.duration;
+ } while( total_duration < time_of_last_note );
+
+ if( time_of_last_note > mTimeOfLastNote )
+ {
+ mTimeOfLastNote = time_of_last_note;
+ }
+ }
+
+ f->seek( 15, binio::Add );
+}
+//---------------------------------------------------------
+void CrolPlayer::load_instrument_events( binistream *f, CVoiceData &voice,
+ binistream *bnk_file, SBnkHeader const &bnk_header )
+{
+ int16 const number_of_instrument_events = f->readInt( 2 );
+ if (number_of_instrument_events<0) {
+ return;
+ }
+
+ TInstrumentEvents &instrument_events = voice.instrument_events;
+
+ instrument_events.reserve( number_of_instrument_events );
+
+ for(int i=0; i<number_of_instrument_events; ++i)
+ {
+ SInstrumentEvent event;
+ event.time = f->readInt( 2 );
+ f->readString( event.name, 9 );
+
+ std::string event_name = event.name;
+ event.ins_index = load_rol_instrument( bnk_file, bnk_header, event_name );
+
+ instrument_events.push_back( event );
+
+ f->seek( 1+2, binio::Add );
+ }
+
+ f->seek( 15, binio::Add );
+}
+//---------------------------------------------------------
+void CrolPlayer::load_volume_events( binistream *f, CVoiceData &voice )
+{
+ int16 const number_of_volume_events = f->readInt( 2 );
+ if (number_of_volume_events<0) {
+ return;
+ }
+
+ TVolumeEvents &volume_events = voice.volume_events;
+
+ volume_events.reserve( number_of_volume_events );
+
+ for(int i=0; i<number_of_volume_events; ++i)
+ {
+ SVolumeEvent event;
+ event.time = f->readInt( 2 );
+ event.multiplier = f->readFloat( binio::Single );
+
+ volume_events.push_back( event );
+ }
+
+ f->seek( 15, binio::Add );
+}
+//---------------------------------------------------------
+void CrolPlayer::load_pitch_events( binistream *f, CVoiceData &voice )
+{
+ int16 const number_of_pitch_events = f->readInt( 2 );
+ if (number_of_pitch_events<0) {
+ return;
+ }
+
+ TPitchEvents &pitch_events = voice.pitch_events;
+
+ pitch_events.reserve( number_of_pitch_events );
+
+ for(int i=0; i<number_of_pitch_events; ++i)
+ {
+ SPitchEvent event;
+ event.time = f->readInt( 2 );
+ event.variation = f->readFloat( binio::Single );
+
+ pitch_events.push_back( event );
+ }
+}
+//---------------------------------------------------------
+bool CrolPlayer::load_bnk_info( binistream *f, SBnkHeader &header )
+{
+ header.version_major = f->readInt(1);
+ header.version_minor = f->readInt(1);
+ f->readString( header.signature, 6 );
+
+ header.number_of_list_entries_used = f->readInt( 2 );
+ header.total_number_of_list_entries = f->readInt( 2 );
+
+ header.abs_offset_of_name_list = f->readInt( 4 );
+ header.abs_offset_of_data = f->readInt( 4 );
+
+ f->seek( header.abs_offset_of_name_list, binio::Set );
+
+ TInstrumentNames &ins_name_list = header.ins_name_list;
+ ins_name_list.reserve( header.number_of_list_entries_used );
+
+ for(int i=0; i<header.number_of_list_entries_used; ++i)
+ {
+ SInstrumentName instrument;
+
+ instrument.index = f->readInt( 2 );
+ instrument.record_used = f->readInt(1);
+ f->readString( instrument.name, 9 );
+
+ // printf("%s = #%d\n", instrument.name, i );
+
+ ins_name_list.push_back( instrument );
+ }
+
+ //std::sort( ins_name_list.begin(), ins_name_list.end(), StringCompare() );
+
+ return true;
+}
+//---------------------------------------------------------
+int CrolPlayer::load_rol_instrument( binistream *f, SBnkHeader const &header, std::string &name )
+{
+ TInstrumentNames const &ins_name_list = header.ins_name_list;
+
+ int const ins_index = get_ins_index( name );
+
+ if( ins_index != -1 )
+ {
+ return ins_index;
+ }
+
+ typedef TInstrumentNames::const_iterator TInsIter;
+ typedef std::pair<TInsIter, TInsIter> TInsIterPair;
+
+ TInsIterPair range = std::equal_range( ins_name_list.begin(),
+ ins_name_list.end(),
+ name,
+ StringCompare() );
+
+ if( range.first != range.second )
+ {
+ int const seekOffs = header.abs_offset_of_data + (range.first->index*kSizeofDataRecord);
+ f->seek( seekOffs, binio::Set );
+ }
+
+ SUsedList usedIns;
+ usedIns.name = name;
+
+ if( range.first != range.second )
+ {
+ read_rol_instrument( f, usedIns.instrument );
+ }
+ else
+ {
+ // set up default instrument data here
+ memset( &usedIns.instrument, 0, sizeof(usedIns.instrument) );
+ }
+ ins_list.push_back( usedIns );
+
+ return ins_list.size()-1;
+}
+//---------------------------------------------------------
+int CrolPlayer::get_ins_index( std::string const &name ) const
+{
+ for(unsigned int i=0; i<ins_list.size(); ++i)
+ {
+ if( strcmp_nocase(ins_list[i].name.c_str(), name.c_str()) == 0 )
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+//---------------------------------------------------------
+void CrolPlayer::read_rol_instrument( binistream *f, SRolInstrument &ins )
+{
+ ins.mode = f->readInt(1);
+ ins.voice_number = f->readInt(1);
+
+ read_fm_operator( f, ins.modulator );
+ read_fm_operator( f, ins.carrier );
+
+ ins.modulator.waveform = f->readInt(1);
+ ins.carrier.waveform = f->readInt(1);
+}
+//---------------------------------------------------------
+void CrolPlayer::read_fm_operator( binistream *f, SOPL2Op &opl2_op )
+{
+ SFMOperator fm_op;
+
+ fm_op.key_scale_level = f->readInt(1);
+ fm_op.freq_multiplier = f->readInt(1);
+ fm_op.feed_back = f->readInt(1);
+ fm_op.attack_rate = f->readInt(1);
+ fm_op.sustain_level = f->readInt(1);
+ fm_op.sustaining_sound = f->readInt(1);
+ fm_op.decay_rate = f->readInt(1);
+ fm_op.release_rate = f->readInt(1);
+ fm_op.output_level = f->readInt(1);
+ fm_op.amplitude_vibrato = f->readInt(1);
+ fm_op.frequency_vibrato = f->readInt(1);
+ fm_op.envelope_scaling = f->readInt(1);
+ fm_op.fm_type = f->readInt(1);
+
+ opl2_op.ammulti = fm_op.amplitude_vibrato << 7 | fm_op.frequency_vibrato << 6 | fm_op.sustaining_sound << 5 | fm_op.envelope_scaling << 4 | fm_op.freq_multiplier;
+ opl2_op.ksltl = fm_op.key_scale_level << 6 | fm_op.output_level;
+ opl2_op.ardr = fm_op.attack_rate << 4 | fm_op.decay_rate;
+ opl2_op.slrr = fm_op.sustain_level << 4 | fm_op.release_rate;
+ opl2_op.fbc = fm_op.feed_back << 1 | (fm_op.fm_type ^ 1);
+}
diff --git a/src/adplug/core/rol.cxx b/src/adplug/core/rol.cxx
deleted file mode 100644
index c7d06746f14c..000000000000
--- a/src/adplug/core/rol.cxx
+++ /dev/null
@@ -1,750 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * rol.h - ROL Player by OPLx <oplx at yahoo.com>
- *
- * Visit: http://tenacity.hispeed.com/aomit/oplx/
- */
-#include <algorithm>
-#include <string.h>
-
-#include <glib.h>
-
-#include "rol.h"
-#include "debug.h"
-
-int const CrolPlayer::kSizeofDataRecord = 30;
-int const CrolPlayer::kMaxTickBeat = 60;
-int const CrolPlayer::kSilenceNote = -12;
-int const CrolPlayer::kNumMelodicVoices = 9;
-int const CrolPlayer::kNumPercussiveVoices = 11;
-int const CrolPlayer::kBassDrumChannel = 6;
-int const CrolPlayer::kSnareDrumChannel = 7;
-int const CrolPlayer::kTomtomChannel = 8;
-int const CrolPlayer::kTomtomFreq = 2;//4;
-int const CrolPlayer::kSnareDrumFreq = 2;//kTomtomFreq + 7;
-float const CrolPlayer::kDefaultUpdateTme = 18.2f;
-float const CrolPlayer::kPitchFactor = 400.0f;
-
-static const unsigned char drum_table[4] = {0x14, 0x12, 0x15, 0x11};
-
-CrolPlayer::uint16 const CrolPlayer::kNoteTable[12] =
-{
- 340, // C
- 363, // C#
- 385, // D
- 408, // D#
- 432, // E
- 458, // F
- 485, // F#
- 514, // G
- 544, // G#
- 577, // A
- 611, // A#
- 647 // B
-};
-
-/*** public methods **************************************/
-
-CPlayer *CrolPlayer::factory(Copl *newopl)
-{
- return new CrolPlayer(newopl);
-}
-//---------------------------------------------------------
-CrolPlayer::CrolPlayer(Copl *newopl)
-: CPlayer ( newopl )
- ,rol_header ( NULL )
- ,mNextTempoEvent ( 0 )
- ,mCurrTick ( 0 )
- ,mTimeOfLastNote ( 0 )
- ,mRefresh ( kDefaultUpdateTme )
- ,bdRegister ( 0 )
-{
- int n;
-
- memset(bxRegister, 0, sizeof(bxRegister) );
- memset(volumeCache, 0, sizeof(volumeCache) );
- memset(freqCache, 0, sizeof(freqCache) );
-
- for(n=0; n<11; n++)
- pitchCache[n]=1.0f;
-}
-//---------------------------------------------------------
-CrolPlayer::~CrolPlayer()
-{
- if(rol_header)
- {
- delete rol_header;
- rol_header = 0;
- }
-}
-//---------------------------------------------------------
-bool CrolPlayer::load(VFSFile *fd, const CFileProvider &fp)
-{
- binistream *f = fp.open(fd); if(!f) return false;
- std::string filename(vfs_get_filename (fd));
-
- char *fn = new char[filename.length()+12];
- int i;
- std::string bnk_filename;
-
- AdPlug_LogWrite("*** CrolPlayer::load(f, \"%s\") ***\n", filename.c_str());
- strcpy(fn,filename.data());
- for (i=strlen(fn)-1; i>=0; i--)
- if (fn[i] == '/' || fn[i] == '\\')
- break;
- strcpy(fn+i+1,"standard.bnk");
- bnk_filename = fn;
- delete [] fn; fn = 0;
- AdPlug_LogWrite("bnk_filename = \"%s\"\n",bnk_filename.c_str());
-
- rol_header = new SRolHeader;
- memset( rol_header, 0, sizeof(SRolHeader) );
-
- rol_header->version_major = f->readInt( 2 );
- rol_header->version_minor = f->readInt( 2 );
-
- // Version check
- if(rol_header->version_major != 0 || rol_header->version_minor != 4) {
- AdPlug_LogWrite("Unsupported file version %d.%d or not a ROL file!\n",
- rol_header->version_major, rol_header->version_minor);
- AdPlug_LogWrite("--- CrolPlayer::load ---\n");
- fp.close(f);
- return false;
- }
-
- f->seek( 40, binio::Add );
-
- rol_header->ticks_per_beat = f->readInt( 2 );
- rol_header->beats_per_measure = f->readInt( 2 );
- rol_header->edit_scale_y = f->readInt( 2 );
- rol_header->edit_scale_x = f->readInt( 2 );
-
- f->seek( 1, binio::Add );
-
- rol_header->mode = f->readInt(1);
-
- f->seek( 90+38+15, binio::Add );
-
- rol_header->basic_tempo = f->readFloat( binio::Single );
-
- load_tempo_events( f );
-
- mTimeOfLastNote = 0;
-
- if( load_voice_data( f, bnk_filename, fp ) != true )
- {
- AdPlug_LogWrite("CrolPlayer::load_voice_data(f) failed!\n");
- AdPlug_LogWrite("--- CrolPlayer::load ---\n");
-
- fp.close( f );
- return false;
- }
-
- fp.close( f );
-
- rewind( 0 );
- AdPlug_LogWrite("--- CrolPlayer::load ---\n");
- return true;
-}
-//---------------------------------------------------------
-bool CrolPlayer::update()
-{
- if( mNextTempoEvent < mTempoEvents.size() &&
- mTempoEvents[mNextTempoEvent].time == mCurrTick )
- {
- SetRefresh( mTempoEvents[mNextTempoEvent].multiplier );
- ++mNextTempoEvent;
- }
-
- TVoiceData::iterator curr = voice_data.begin();
- TVoiceData::iterator end = voice_data.end();
- int voice = 0;
-
- while( curr != end )
- {
- UpdateVoice( voice, *curr );
- ++curr;
- ++voice;
- }
-
- ++mCurrTick;
-
- if( mCurrTick > mTimeOfLastNote )
- {
- return false;
- }
-
- return true;
- //return ( mCurrTick > mTimeOfLastNote ) ? false : true;
-}
-//---------------------------------------------------------
-void CrolPlayer::rewind( int subsong )
-{
- TVoiceData::iterator curr = voice_data.begin();
- TVoiceData::iterator end = voice_data.end();
-
- while( curr != end )
- {
- CVoiceData &voice = *curr;
-
- voice.Reset();
- ++curr;
- }
-
- memset(bxRegister, 0, sizeof(bxRegister) );
- memset(volumeCache, 0, sizeof(volumeCache) );
-
- bdRegister = 0;
-
- opl->init(); // initialize to melodic by default
- opl->write(1,0x20); // Enable waveform select (bit 5)
-
- if( rol_header->mode == 0 )
- {
- opl->write( 0xbd, 0x20 ); // select rhythm mode (bit 5)
- bdRegister = 0x20;
-
- SetFreq( kTomtomChannel, 24 );
- SetFreq( kSnareDrumChannel, 31 );
- }
-
- mNextTempoEvent = 0;
- mCurrTick = 0;
-
- SetRefresh(1.0f);
-}
-//---------------------------------------------------------
-inline float fmin( int const a, int const b )
-{
- return static_cast<float>( a < b ? a : b );
-}
-//---------------------------------------------------------
-void CrolPlayer::SetRefresh( float const multiplier )
-{
- float const tickBeat = fmin(kMaxTickBeat, rol_header->ticks_per_beat);
-
- mRefresh = (tickBeat*rol_header->basic_tempo*multiplier) / 60.0f;
-}
-//---------------------------------------------------------
-float CrolPlayer::getrefresh()
-{
- return mRefresh;
-}
-//---------------------------------------------------------
-void CrolPlayer::UpdateVoice( int const voice, CVoiceData &voiceData )
-{
- TNoteEvents const &nEvents = voiceData.note_events;
-
- if( nEvents.empty() || voiceData.mEventStatus & CVoiceData::kES_NoteEnd )
- {
- return; // no note data to process, don't bother doing anything.
- }
-
- TInstrumentEvents &iEvents = voiceData.instrument_events;
- TVolumeEvents &vEvents = voiceData.volume_events;
- TPitchEvents &pEvents = voiceData.pitch_events;
-
- if (iEvents.empty()) {
- return; // prevent out-of-bounds access
- }
- if( !(voiceData.mEventStatus & CVoiceData::kES_InstrEnd ) &&
- iEvents[voiceData.next_instrument_event].time == mCurrTick )
- {
- if( voiceData.next_instrument_event < iEvents.size() )
- {
- send_ins_data_to_chip( voice, iEvents[voiceData.next_instrument_event].ins_index );
- ++voiceData.next_instrument_event;
- }
- else
- {
- voiceData.mEventStatus |= CVoiceData::kES_InstrEnd;
- }
- }
-
- if (vEvents.empty()) {
- return; // prevent out-of-bounds access
- }
- if( !(voiceData.mEventStatus & CVoiceData::kES_VolumeEnd ) &&
- vEvents[voiceData.next_volume_event].time == mCurrTick )
- {
- SVolumeEvent const &volumeEvent = vEvents[voiceData.next_volume_event];
-
- if( voiceData.next_volume_event < vEvents.size() )
- {
- int const volume = (int)(63.0f*(1.0f - volumeEvent.multiplier));
-
- SetVolume( voice, volume );
-
- ++voiceData.next_volume_event; // move to next volume event
- }
- else
- {
- voiceData.mEventStatus |= CVoiceData::kES_VolumeEnd;
- }
- }
-
- if( voiceData.mForceNote || voiceData.current_note_duration > voiceData.mNoteDuration-1 )
- {
- if( mCurrTick != 0 )
- {
- ++voiceData.current_note;
- }
-
- if( voiceData.current_note < nEvents.size() )
- {
- SNoteEvent const ¬eEvent = nEvents[voiceData.current_note];
-
- SetNote( voice, noteEvent.number );
- voiceData.current_note_duration = 0;
- voiceData.mNoteDuration = noteEvent.duration;
- voiceData.mForceNote = false;
- }
- else
- {
- SetNote( voice, kSilenceNote );
- voiceData.mEventStatus |= CVoiceData::kES_NoteEnd;
- return;
- }
- }
-
- if (pEvents.empty()) {
- return; // prevent out-of-bounds access
- }
- if( !(voiceData.mEventStatus & CVoiceData::kES_PitchEnd ) &&
- pEvents[voiceData.next_pitch_event].time == mCurrTick )
- {
- if( voiceData.next_pitch_event < pEvents.size() )
- {
- SetPitch(voice,pEvents[voiceData.next_pitch_event].variation);
- ++voiceData.next_pitch_event;
- }
- else
- {
- voiceData.mEventStatus |= CVoiceData::kES_PitchEnd;
- }
- }
-
- ++voiceData.current_note_duration;
-}
-//---------------------------------------------------------
-void CrolPlayer::SetNote( int const voice, int const note )
-{
- if( voice < kBassDrumChannel || rol_header->mode )
- {
- SetNoteMelodic( voice, note );
- }
- else
- {
- SetNotePercussive( voice, note );
- }
-}
-//---------------------------------------------------------
-void CrolPlayer::SetNotePercussive( int const voice, int const note )
-{
- int const bit_pos = 4-voice+kBassDrumChannel;
-
- bdRegister &= ~( 1<<bit_pos );
- opl->write( 0xbd, bdRegister );
-
- if( note != kSilenceNote )
- {
- switch( voice )
- {
- case kTomtomChannel:
- SetFreq( kSnareDrumChannel, note+7 );
- case kBassDrumChannel:
- SetFreq( voice, note );
- break;
- }
-
- bdRegister |= 1<<bit_pos;
- opl->write( 0xbd, bdRegister );
- }
-}
-//---------------------------------------------------------
-void CrolPlayer::SetNoteMelodic( int const voice, int const note )
-{
- opl->write( 0xb0+voice, bxRegister[voice] & ~0x20 );
-
- if( note != kSilenceNote )
- {
- SetFreq( voice, note, true );
- }
-}
-//---------------------------------------------------------
-void CrolPlayer::SetPitch(int const voice, real32 const variation)
-{
- pitchCache[voice] = variation;
- freqCache[voice] += (uint16)((((float)freqCache[voice])*(variation-1.0f)) / kPitchFactor);
-
- opl->write(0xa0+voice,freqCache[voice] & 0xff);
-}
-//---------------------------------------------------------
-void CrolPlayer::SetFreq( int const voice, int const note, bool const keyOn )
-{
- uint16 freq = kNoteTable[note%12] + ((note/12) << 10);
- freq += (uint16)((((float)freq)*(pitchCache[voice]-1.0f))/kPitchFactor);
-
- freqCache[voice] = freq;
- bxRegister[voice] = ((freq >> 8) & 0x1f);
-
- opl->write( 0xa0+voice, freq & 0xff );
- opl->write( 0xb0+voice, bxRegister[voice] | (keyOn ? 0x20 : 0x0) );
-}
-//---------------------------------------------------------
-void CrolPlayer::SetVolume( int const voice, int const volume )
-{
- volumeCache[voice] = (volumeCache[voice] &0xc0) | volume;
-
- int const op_offset = ( voice < kSnareDrumChannel || rol_header->mode ) ?
- op_table[voice]+3 : drum_table[voice-kSnareDrumChannel];
-
- opl->write( 0x40+op_offset, volumeCache[voice] );
-}
-//---------------------------------------------------------
-void CrolPlayer::send_ins_data_to_chip( int const voice, int const ins_index )
-{
- SRolInstrument &instrument = ins_list[ins_index].instrument;
-
- send_operator( voice, instrument.modulator, instrument.carrier );
-}
-//---------------------------------------------------------
-void CrolPlayer::send_operator( int const voice, SOPL2Op const &modulator, SOPL2Op const &carrier )
-{
- if( voice < kSnareDrumChannel || rol_header->mode )
- {
- int const op_offset = op_table[voice];
-
- opl->write( 0x20+op_offset, modulator.ammulti );
- opl->write( 0x40+op_offset, modulator.ksltl );
- opl->write( 0x60+op_offset, modulator.ardr );
- opl->write( 0x80+op_offset, modulator.slrr );
- opl->write( 0xc0+voice , modulator.fbc );
- opl->write( 0xe0+op_offset, modulator.waveform );
-
- volumeCache[voice] = (carrier.ksltl & 0xc0) | (volumeCache[voice] & 0x3f);
-
- opl->write( 0x23+op_offset, carrier.ammulti );
- opl->write( 0x43+op_offset, volumeCache[voice] );
- opl->write( 0x63+op_offset, carrier.ardr );
- opl->write( 0x83+op_offset, carrier.slrr );
-// opl->write( 0xc3+voice , carrier.fbc ); <- don't bother writing this.
- opl->write( 0xe3+op_offset, carrier.waveform );
- }
- else
- {
- int const op_offset = drum_table[voice-kSnareDrumChannel];
-
- volumeCache[voice] = (modulator.ksltl & 0xc0) | (volumeCache[voice] & 0x3f);
-
- opl->write( 0x20+op_offset, modulator.ammulti );
- opl->write( 0x40+op_offset, volumeCache[voice] );
- opl->write( 0x60+op_offset, modulator.ardr );
- opl->write( 0x80+op_offset, modulator.slrr );
- opl->write( 0xc0+voice , modulator.fbc );
- opl->write( 0xe0+op_offset, modulator.waveform );
- }
-}
-//---------------------------------------------------------
-void CrolPlayer::load_tempo_events( binistream *f )
-{
- int16 const num_tempo_events = f->readInt( 2 );
-
- if (num_tempo_events<0) {
- return;
- }
- mTempoEvents.reserve( num_tempo_events );
-
- for(int i=0; i<num_tempo_events; ++i)
- {
- STempoEvent event;
-
- event.time = f->readInt( 2 );
- event.multiplier = f->readFloat( binio::Single );
- mTempoEvents.push_back( event );
- }
-}
-//---------------------------------------------------------
-bool CrolPlayer::load_voice_data( binistream *f, std::string const &bnk_filename, const CFileProvider &fp )
-{
- SBnkHeader bnk_header;
- VFSFile *fd = vfs_fopen(bnk_filename.c_str(), "rb");
- binistream *bnk_file = fp.open(fd);
-
- if( bnk_file )
- {
- load_bnk_info( bnk_file, bnk_header );
-
- int const numVoices = rol_header->mode ? kNumMelodicVoices : kNumPercussiveVoices;
-
- voice_data.reserve( numVoices );
- for(int i=0; i<numVoices; ++i)
- {
- CVoiceData voice;
-
- load_note_events( f, voice );
- load_instrument_events( f, voice, bnk_file, bnk_header );
- load_volume_events( f, voice );
- load_pitch_events( f, voice );
-
- voice_data.push_back( voice );
- }
-
- fp.close(bnk_file);
- vfs_fclose(fd);
-
- return true;
- }
-
- return false;
-}
-//---------------------------------------------------------
-void CrolPlayer::load_note_events( binistream *f, CVoiceData &voice )
-{
- f->seek( 15, binio::Add );
-
- int16 const time_of_last_note = f->readInt( 2 );
-
- if( time_of_last_note != 0 )
- {
- TNoteEvents ¬e_events = voice.note_events;
- int16 total_duration = 0;
-
- do
- {
- SNoteEvent event;
-
- event.number = f->readInt( 2 );
- event.duration = f->readInt( 2 );
-
- event.number += kSilenceNote; // adding -12
-
- note_events.push_back( event );
-
- total_duration += event.duration;
- } while( total_duration < time_of_last_note );
-
- if( time_of_last_note > mTimeOfLastNote )
- {
- mTimeOfLastNote = time_of_last_note;
- }
- }
-
- f->seek( 15, binio::Add );
-}
-//---------------------------------------------------------
-void CrolPlayer::load_instrument_events( binistream *f, CVoiceData &voice,
- binistream *bnk_file, SBnkHeader const &bnk_header )
-{
- int16 const number_of_instrument_events = f->readInt( 2 );
- if (number_of_instrument_events<0) {
- return;
- }
-
- TInstrumentEvents &instrument_events = voice.instrument_events;
-
- instrument_events.reserve( number_of_instrument_events );
-
- for(int i=0; i<number_of_instrument_events; ++i)
- {
- SInstrumentEvent event;
- event.time = f->readInt( 2 );
- f->readString( event.name, 9 );
-
- std::string event_name = event.name;
- event.ins_index = load_rol_instrument( bnk_file, bnk_header, event_name );
-
- instrument_events.push_back( event );
-
- f->seek( 1+2, binio::Add );
- }
-
- f->seek( 15, binio::Add );
-}
-//---------------------------------------------------------
-void CrolPlayer::load_volume_events( binistream *f, CVoiceData &voice )
-{
- int16 const number_of_volume_events = f->readInt( 2 );
- if (number_of_volume_events<0) {
- return;
- }
-
- TVolumeEvents &volume_events = voice.volume_events;
-
- volume_events.reserve( number_of_volume_events );
-
- for(int i=0; i<number_of_volume_events; ++i)
- {
- SVolumeEvent event;
- event.time = f->readInt( 2 );
- event.multiplier = f->readFloat( binio::Single );
-
- volume_events.push_back( event );
- }
-
- f->seek( 15, binio::Add );
-}
-//---------------------------------------------------------
-void CrolPlayer::load_pitch_events( binistream *f, CVoiceData &voice )
-{
- int16 const number_of_pitch_events = f->readInt( 2 );
- if (number_of_pitch_events<0) {
- return;
- }
-
- TPitchEvents &pitch_events = voice.pitch_events;
-
- pitch_events.reserve( number_of_pitch_events );
-
- for(int i=0; i<number_of_pitch_events; ++i)
- {
- SPitchEvent event;
- event.time = f->readInt( 2 );
- event.variation = f->readFloat( binio::Single );
-
- pitch_events.push_back( event );
- }
-}
-//---------------------------------------------------------
-bool CrolPlayer::load_bnk_info( binistream *f, SBnkHeader &header )
-{
- header.version_major = f->readInt(1);
- header.version_minor = f->readInt(1);
- f->readString( header.signature, 6 );
-
- header.number_of_list_entries_used = f->readInt( 2 );
- header.total_number_of_list_entries = f->readInt( 2 );
-
- header.abs_offset_of_name_list = f->readInt( 4 );
- header.abs_offset_of_data = f->readInt( 4 );
-
- f->seek( header.abs_offset_of_name_list, binio::Set );
-
- TInstrumentNames &ins_name_list = header.ins_name_list;
- ins_name_list.reserve( header.number_of_list_entries_used );
-
- for(int i=0; i<header.number_of_list_entries_used; ++i)
- {
- SInstrumentName instrument;
-
- instrument.index = f->readInt( 2 );
- instrument.record_used = f->readInt(1);
- f->readString( instrument.name, 9 );
-
- // printf("%s = #%d\n", instrument.name, i );
-
- ins_name_list.push_back( instrument );
- }
-
- //std::sort( ins_name_list.begin(), ins_name_list.end(), StringCompare() );
-
- return true;
-}
-//---------------------------------------------------------
-int CrolPlayer::load_rol_instrument( binistream *f, SBnkHeader const &header, std::string &name )
-{
- TInstrumentNames const &ins_name_list = header.ins_name_list;
-
- int const ins_index = get_ins_index( name );
-
- if( ins_index != -1 )
- {
- return ins_index;
- }
-
- typedef TInstrumentNames::const_iterator TInsIter;
- typedef std::pair<TInsIter, TInsIter> TInsIterPair;
-
- TInsIterPair range = std::equal_range( ins_name_list.begin(),
- ins_name_list.end(),
- name,
- StringCompare() );
-
- if( range.first != range.second )
- {
- int const seekOffs = header.abs_offset_of_data + (range.first->index*kSizeofDataRecord);
- f->seek( seekOffs, binio::Set );
- }
-
- SUsedList usedIns;
- usedIns.name = name;
-
- if( range.first != range.second )
- {
- read_rol_instrument( f, usedIns.instrument );
- }
- else
- {
- // set up default instrument data here
- memset( &usedIns.instrument, 0, sizeof(usedIns.instrument) );
- }
- ins_list.push_back( usedIns );
-
- return ins_list.size()-1;
-}
-//---------------------------------------------------------
-int CrolPlayer::get_ins_index( std::string const &name ) const
-{
- for(unsigned int i=0; i<ins_list.size(); ++i)
- {
- if( g_ascii_strcasecmp(ins_list[i].name.c_str(), name.c_str()) == 0 )
- {
- return i;
- }
- }
-
- return -1;
-}
-//---------------------------------------------------------
-void CrolPlayer::read_rol_instrument( binistream *f, SRolInstrument &ins )
-{
- ins.mode = f->readInt(1);
- ins.voice_number = f->readInt(1);
-
- read_fm_operator( f, ins.modulator );
- read_fm_operator( f, ins.carrier );
-
- ins.modulator.waveform = f->readInt(1);
- ins.carrier.waveform = f->readInt(1);
-}
-//---------------------------------------------------------
-void CrolPlayer::read_fm_operator( binistream *f, SOPL2Op &opl2_op )
-{
- SFMOperator fm_op;
-
- fm_op.key_scale_level = f->readInt(1);
- fm_op.freq_multiplier = f->readInt(1);
- fm_op.feed_back = f->readInt(1);
- fm_op.attack_rate = f->readInt(1);
- fm_op.sustain_level = f->readInt(1);
- fm_op.sustaining_sound = f->readInt(1);
- fm_op.decay_rate = f->readInt(1);
- fm_op.release_rate = f->readInt(1);
- fm_op.output_level = f->readInt(1);
- fm_op.amplitude_vibrato = f->readInt(1);
- fm_op.frequency_vibrato = f->readInt(1);
- fm_op.envelope_scaling = f->readInt(1);
- fm_op.fm_type = f->readInt(1);
-
- opl2_op.ammulti = fm_op.amplitude_vibrato << 7 | fm_op.frequency_vibrato << 6 | fm_op.sustaining_sound << 5 | fm_op.envelope_scaling << 4 | fm_op.freq_multiplier;
- opl2_op.ksltl = fm_op.key_scale_level << 6 | fm_op.output_level;
- opl2_op.ardr = fm_op.attack_rate << 4 | fm_op.decay_rate;
- opl2_op.slrr = fm_op.sustain_level << 4 | fm_op.release_rate;
- opl2_op.fbc = fm_op.feed_back << 1 | (fm_op.fm_type ^ 1);
-}
diff --git a/src/adplug/core/rol.h b/src/adplug/core/rol.h
index 6b3b7d4c5052..510efeea5e80 100644
--- a/src/adplug/core/rol.h
+++ b/src/adplug/core/rol.h
@@ -26,10 +26,10 @@
#include <vector>
#include <string>
-#include <glib.h>
-
#include "player.h"
+#include <libaudcore/audstrings.h>
+
class CrolPlayer: public CPlayer
{
public:
@@ -39,7 +39,7 @@ public:
~CrolPlayer();
- bool load (VFSFile *fd, const CFileProvider &fp);
+ bool load (VFSFile &fd, const CFileProvider &fp);
bool update ();
void rewind (int subsong); // rewinds to specified subsong
float getrefresh(); // returns needed timer refresh rate
@@ -271,7 +271,7 @@ private:
private:
bool keyLess( const char *const lhs, const char *const rhs ) const
{
- return g_ascii_strcasecmp(lhs, rhs) < 0;
+ return strcmp_nocase(lhs, rhs) < 0;
}
};
diff --git a/src/adplug/core/s3m.cc b/src/adplug/core/s3m.cc
new file mode 100644
index 000000000000..b8cc94c5e408
--- /dev/null
+++ b/src/adplug/core/s3m.cc
@@ -0,0 +1,728 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * s3m.c - S3M Player by Simon Peter <dn.tlp at gmx.net>
+ *
+ * BUGS:
+ * Extra Fine Slides (EEx, FEx) & Fine Vibrato (Uxy) are inaccurate
+ */
+
+#include <string.h>
+
+#include "s3m.h"
+
+const signed char
+ Cs3mPlayer::chnresolv[] = // S3M -> adlib channel conversion
+{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3,
+ 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, -1 };
+
+const unsigned short
+ Cs3mPlayer::notetable[12] = // S3M adlib note table
+{ 340, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647 };
+
+const unsigned char
+ Cs3mPlayer::vibratotab[32] = // vibrato rate table
+{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 15, 14, 13, 12,
+ 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
+
+/*** public methods *************************************/
+
+CPlayer *
+Cs3mPlayer::factory (Copl * newopl)
+{
+ return new Cs3mPlayer (newopl);
+}
+
+Cs3mPlayer::Cs3mPlayer (Copl * newopl):CPlayer (newopl)
+{
+ int
+ i,
+ j,
+ k;
+
+ memset (pattern, 255, sizeof (pattern));
+ memset (orders, 255, sizeof (orders));
+
+ for (i = 0; i < 99; i++) // setup pattern
+ for (j = 0; j < 64; j++)
+ for (k = 0; k < 32; k++)
+ {
+ pattern[i][j][k].instrument = 0;
+ pattern[i][j][k].info = 0;
+ }
+}
+
+bool
+Cs3mPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ unsigned short insptr[99], pattptr[99];
+ int i, row;
+ unsigned char bufval, bufval2;
+ unsigned short ppatlen;
+ s3mheader *checkhead;
+ bool adlibins = false;
+
+ // file validation section
+ checkhead = new s3mheader;
+ load_header (f, checkhead);
+ if (checkhead->kennung != 0x1a || checkhead->typ != 16
+ || checkhead->insnum > 99)
+ {
+ delete checkhead;
+ fp.close (f);
+ return false;
+ }
+ else if (strncmp (checkhead->scrm, "SCRM", 4))
+ {
+ delete checkhead;
+ fp.close (f);
+ return false;
+ }
+ else
+ { // is an adlib module?
+ f->seek (checkhead->ordnum, binio::Add);
+ for (i = 0; i < checkhead->insnum; i++)
+ insptr[i] = f->readInt (2);
+ for (i = 0; i < checkhead->insnum; i++)
+ {
+ f->seek (insptr[i] * 16);
+ if (f->readInt (1) >= 2)
+ {
+ adlibins = true;
+ break;
+ }
+ }
+ delete checkhead;
+ if (!adlibins)
+ {
+ fp.close (f);
+ return false;
+ }
+ }
+
+ // load section
+ f->seek (0); // rewind for load
+ load_header (f, &header); // read header
+
+ // security check
+ if (header.ordnum > 256 || header.insnum > 99 || header.patnum > 99)
+ {
+ fp.close (f);
+ return false;
+ }
+
+ for (i = 0; i < header.ordnum; i++)
+ orders[i] = f->readInt (1); // read orders
+ for (i = 0; i < header.insnum; i++)
+ insptr[i] = f->readInt (2); // instrument parapointers
+ for (i = 0; i < header.patnum; i++)
+ pattptr[i] = f->readInt (2); // pattern parapointers
+
+ for (i = 0; i < header.insnum; i++)
+ { // load instruments
+ f->seek (insptr[i] * 16);
+ inst[i].type = f->readInt (1);
+ f->readString (inst[i].filename, 15);
+ inst[i].d00 = f->readInt (1);
+ inst[i].d01 = f->readInt (1);
+ inst[i].d02 = f->readInt (1);
+ inst[i].d03 = f->readInt (1);
+ inst[i].d04 = f->readInt (1);
+ inst[i].d05 = f->readInt (1);
+ inst[i].d06 = f->readInt (1);
+ inst[i].d07 = f->readInt (1);
+ inst[i].d08 = f->readInt (1);
+ inst[i].d09 = f->readInt (1);
+ inst[i].d0a = f->readInt (1);
+ inst[i].d0b = f->readInt (1);
+ inst[i].volume = f->readInt (1);
+ inst[i].dsk = f->readInt (1);
+ f->ignore (2);
+ inst[i].c2spd = f->readInt (4);
+ f->ignore (12);
+ f->readString (inst[i].name, 28);
+ f->readString (inst[i].scri, 4);
+ }
+
+ for (i = 0; i < header.patnum; i++)
+ { // depack patterns
+ f->seek (pattptr[i] * 16);
+ ppatlen = f->readInt (2);
+ unsigned long pattpos = f->pos ();
+ for (row = 0; (row < 64) && (pattpos - pattptr[i] * 16 <= ppatlen); row++)
+ do
+ {
+ bufval = f->readInt (1);
+ if (bufval & 32)
+ {
+ bufval2 = f->readInt (1);
+ pattern[i][row][bufval & 31].note = bufval2 & 15;
+ pattern[i][row][bufval & 31].oct = (bufval2 & 240) >> 4;
+ pattern[i][row][bufval & 31].instrument = f->readInt (1);
+ }
+ if (bufval & 64)
+ pattern[i][row][bufval & 31].volume = f->readInt (1);
+ if (bufval & 128)
+ {
+ pattern[i][row][bufval & 31].command = f->readInt (1);
+ pattern[i][row][bufval & 31].info = f->readInt (1);
+ }
+ } while (bufval);
+ }
+
+ fp.close (f);
+ rewind (0);
+ return true; // done
+}
+
+bool
+Cs3mPlayer::update ()
+{
+ unsigned char pattbreak = 0, donote; // remember vars
+ unsigned char pattnr, chan, row, info; // cache vars
+ signed char realchan;
+
+ // effect handling (timer dependant)
+ for (realchan = 0; realchan < 9; realchan++)
+ {
+ info = channel[realchan].info; // fill infobyte cache
+ switch (channel[realchan].fx)
+ {
+ case 11:
+ case 12:
+ if (channel[realchan].fx == 11) // dual command: H00 and Dxy
+ vibrato (realchan, channel[realchan].dualinfo);
+ else // dual command: G00 and Dxy
+ tone_portamento (realchan, channel[realchan].dualinfo);
+ case 4:
+ if (info <= 0x0f) // volume slide down
+ {
+ if (channel[realchan].vol - info >= 0)
+ channel[realchan].vol -= info;
+ else
+ channel[realchan].vol = 0;
+ }
+ if ((info & 0x0f) == 0) // volume slide up
+ {
+ if (channel[realchan].vol + (info >> 4) <= 63)
+ channel[realchan].vol += info >> 4;
+ else
+ channel[realchan].vol = 63;
+ }
+ setvolume (realchan);
+ break;
+ case 5:
+ if (info == 0xf0 || info <= 0xe0)
+ { // slide down
+ slide_down (realchan, info);
+ setfreq (realchan);
+ }
+ break;
+ case 6:
+ if (info == 0xf0 || info <= 0xe0)
+ { // slide up
+ slide_up (realchan, info);
+ setfreq (realchan);
+ }
+ break;
+ case 7:
+ tone_portamento (realchan, channel[realchan].dualinfo);
+ break; // tone portamento
+ case 8:
+ vibrato (realchan, channel[realchan].dualinfo);
+ break; // vibrato
+ case 10:
+ channel[realchan].nextfreq = channel[realchan].freq; // arpeggio
+ channel[realchan].nextoct = channel[realchan].oct;
+ switch (channel[realchan].trigger)
+ {
+ case 0:
+ channel[realchan].freq = notetable[channel[realchan].note];
+ break;
+ case 1:
+ if (channel[realchan].note + ((info & 0xf0) >> 4) < 12)
+ channel[realchan].freq =
+ notetable[channel[realchan].note + ((info & 0xf0) >> 4)];
+ else
+ {
+ channel[realchan].freq =
+ notetable[channel[realchan].note + ((info & 0xf0) >> 4) - 12];
+ channel[realchan].oct++;
+ }
+ break;
+ case 2:
+ if (channel[realchan].note + (info & 0x0f) < 12)
+ channel[realchan].freq =
+ notetable[channel[realchan].note + (info & 0x0f)];
+ else
+ {
+ channel[realchan].freq =
+ notetable[channel[realchan].note + (info & 0x0f) - 12];
+ channel[realchan].oct++;
+ }
+ break;
+ }
+ if (channel[realchan].trigger < 2)
+ channel[realchan].trigger++;
+ else
+ channel[realchan].trigger = 0;
+ setfreq (realchan);
+ channel[realchan].freq = channel[realchan].nextfreq;
+ channel[realchan].oct = channel[realchan].nextoct;
+ break;
+ case 21:
+ vibrato (realchan, (unsigned char) (info / 4));
+ break; // fine vibrato
+ }
+ }
+
+ if (del)
+ { // speed compensation
+ del--;
+ return !songend;
+ }
+
+ // arrangement handling
+ pattnr = orders[ord];
+ if (pattnr == 0xff || ord > header.ordnum)
+ { // "--" end of song
+ songend = 1; // set end-flag
+ ord = 0;
+ pattnr = orders[ord];
+ if (pattnr == 0xff)
+ return !songend;
+ }
+ if (pattnr == 0xfe)
+ { // "++" skip marker
+ ord++;
+ pattnr = orders[ord];
+ }
+
+ // play row
+ row = crow; // fill row cache
+ for (chan = 0; chan < 32; chan++)
+ {
+ if (!(header.chanset[chan] & 128)) // resolve S3M -> AdLib channels
+ realchan = chnresolv[header.chanset[chan] & 127];
+ else
+ realchan = -1; // channel disabled
+ if (realchan != -1)
+ { // channel playable?
+ // set channel values
+ donote = 0;
+ if (pattern[pattnr][row][chan].note < 14)
+ {
+ // tone portamento
+ if (pattern[pattnr][row][chan].command == 7
+ || pattern[pattnr][row][chan].command == 12)
+ {
+ channel[realchan].nextfreq =
+ notetable[pattern[pattnr][row][chan].note];
+ channel[realchan].nextoct = pattern[pattnr][row][chan].oct;
+ }
+ else
+ { // normal note
+ channel[realchan].note = pattern[pattnr][row][chan].note;
+ channel[realchan].freq = notetable[pattern[pattnr][row][chan].note];
+ channel[realchan].oct = pattern[pattnr][row][chan].oct;
+ channel[realchan].key = 1;
+ donote = 1;
+ }
+ }
+ if (pattern[pattnr][row][chan].note == 14)
+ { // key off (is 14 here, cause note is only first 4 bits)
+ channel[realchan].key = 0;
+ setfreq (realchan);
+ }
+ if ((channel[realchan].fx != 8 && channel[realchan].fx != 11) && // vibrato begins
+ (pattern[pattnr][row][chan].command == 8
+ || pattern[pattnr][row][chan].command == 11))
+ {
+ channel[realchan].nextfreq = channel[realchan].freq;
+ channel[realchan].nextoct = channel[realchan].oct;
+ }
+ if (pattern[pattnr][row][chan].note >= 14)
+ if ((channel[realchan].fx == 8 || channel[realchan].fx == 11) && // vibrato ends
+ (pattern[pattnr][row][chan].command != 8
+ && pattern[pattnr][row][chan].command != 11))
+ {
+ channel[realchan].freq = channel[realchan].nextfreq;
+ channel[realchan].oct = channel[realchan].nextoct;
+ setfreq (realchan);
+ }
+ if (pattern[pattnr][row][chan].instrument)
+ { // set instrument
+ channel[realchan].inst = pattern[pattnr][row][chan].instrument - 1;
+ if (inst[channel[realchan].inst].volume < 64)
+ channel[realchan].vol = inst[channel[realchan].inst].volume;
+ else
+ channel[realchan].vol = 63;
+ if (pattern[pattnr][row][chan].command != 7)
+ donote = 1;
+ }
+ if (pattern[pattnr][row][chan].volume != 255)
+ {
+ if (pattern[pattnr][row][chan].volume < 64) // set volume
+ channel[realchan].vol = pattern[pattnr][row][chan].volume;
+ else
+ channel[realchan].vol = 63;
+ }
+ channel[realchan].fx = pattern[pattnr][row][chan].command; // set command
+ if (pattern[pattnr][row][chan].info) // set infobyte
+ channel[realchan].info = pattern[pattnr][row][chan].info;
+
+ // some commands reset the infobyte memory
+ switch (channel[realchan].fx)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 20:
+ channel[realchan].info = pattern[pattnr][row][chan].info;
+ break;
+ }
+
+ // play note
+ if (donote)
+ playnote (realchan);
+ if (pattern[pattnr][row][chan].volume != 255) // set volume
+ setvolume (realchan);
+
+ // command handling (row dependant)
+ info = channel[realchan].info; // fill infobyte cache
+ switch (channel[realchan].fx)
+ {
+ case 1:
+ speed = info;
+ break; // set speed
+ case 2:
+ if (info <= ord)
+ songend = 1;
+ ord = info;
+ crow = 0;
+ pattbreak = 1;
+ break; // jump to order
+ case 3:
+ if (!pattbreak)
+ {
+ crow = info;
+ ord++;
+ pattbreak = 1;
+ }
+ break; // pattern break
+ case 4:
+ if (info > 0xf0) // fine volume down
+ {
+ if (channel[realchan].vol - (info & 0x0f) >= 0)
+ channel[realchan].vol -= info & 0x0f;
+ else
+ channel[realchan].vol = 0;
+ }
+ if ((info & 0x0f) == 0x0f && info >= 0x1f) // fine volume up
+ {
+ if (channel[realchan].vol + ((info & 0xf0) >> 4) <= 63)
+ channel[realchan].vol += (info & 0xf0) >> 4;
+ else
+ channel[realchan].vol = 63;
+ }
+ setvolume (realchan);
+ break;
+ case 5:
+ if (info > 0xf0)
+ { // fine slide down
+ slide_down (realchan, (unsigned char) (info & 0x0f));
+ setfreq (realchan);
+ }
+ if (info > 0xe0 && info < 0xf0)
+ { // extra fine slide down
+ slide_down (realchan, (unsigned char) ((info & 0x0f) / 4));
+ setfreq (realchan);
+ }
+ break;
+ case 6:
+ if (info > 0xf0)
+ { // fine slide up
+ slide_up (realchan, (unsigned char) (info & 0x0f));
+ setfreq (realchan);
+ }
+ if (info > 0xe0 && info < 0xf0)
+ { // extra fine slide up
+ slide_up (realchan, (unsigned char) ((info & 0x0f) / 4));
+ setfreq (realchan);
+ }
+ break;
+ case 7: // tone portamento
+ case 8:
+ if ((channel[realchan].fx == 7 || // vibrato (remember info for dual commands)
+ channel[realchan].fx == 8) && pattern[pattnr][row][chan].info)
+ channel[realchan].dualinfo = info;
+ break;
+ case 10:
+ channel[realchan].trigger = 0;
+ break; // arpeggio (set trigger)
+ case 19:
+ if (info == 0xb0) // set loop start
+ loopstart = row;
+ if (info > 0xb0 && info <= 0xbf) // pattern loop
+ {
+ if (!loopcnt)
+ {
+ loopcnt = info & 0x0f;
+ crow = loopstart;
+ pattbreak = 1;
+ }
+ else if (--loopcnt > 0)
+ {
+ crow = loopstart;
+ pattbreak = 1;
+ }
+ }
+ if ((info & 0xf0) == 0xe0) // patterndelay
+ del = speed * (info & 0x0f) - 1;
+ break;
+ case 20:
+ tempo = info;
+ break; // set tempo
+ }
+ }
+ }
+
+ if (!del)
+ del = speed - 1; // speed compensation
+ if (!pattbreak)
+ { // next row (only if no manual advance)
+ crow++;
+ if (crow > 63)
+ {
+ crow = 0;
+ ord++;
+ loopstart = 0;
+ }
+ }
+
+ return !songend; // still playing
+}
+
+void
+Cs3mPlayer::rewind (int subsong)
+{
+ // set basic variables
+ songend = 0;
+ ord = 0;
+ crow = 0;
+ tempo = header.it;
+ speed = header.is;
+ del = 0;
+ loopstart = 0;
+ loopcnt = 0;
+
+ memset (channel, 0, sizeof (channel));
+
+ opl->init (); // reset OPL chip
+ opl->write (1, 32); // Go to ym3812 mode
+}
+
+std::string Cs3mPlayer::gettype ()
+{
+ char
+ filever[5];
+
+ switch (header.cwtv)
+ { // determine version number
+ case 0x1300:
+ strcpy (filever, "3.00");
+ break;
+ case 0x1301:
+ strcpy (filever, "3.01");
+ break;
+ case 0x1303:
+ strcpy (filever, "3.03");
+ break;
+ case 0x1320:
+ strcpy (filever, "3.20");
+ break;
+ default:
+ strcpy (filever, "3.??");
+ }
+
+ return (std::string ("Scream Tracker ") + filever);
+}
+
+float
+Cs3mPlayer::getrefresh ()
+{
+ return (float) (tempo / 2.5);
+}
+
+/*** private methods *************************************/
+
+void
+Cs3mPlayer::load_header (binistream * f, s3mheader * h)
+{
+ int i;
+
+ f->readString (h->name, 28);
+ h->kennung = f->readInt (1);
+ h->typ = f->readInt (1);
+ f->ignore (2);
+ h->ordnum = f->readInt (2);
+ h->insnum = f->readInt (2);
+ h->patnum = f->readInt (2);
+ h->flags = f->readInt (2);
+ h->cwtv = f->readInt (2);
+ h->ffi = f->readInt (2);
+ f->readString (h->scrm, 4);
+ h->gv = f->readInt (1);
+ h->is = f->readInt (1);
+ h->it = f->readInt (1);
+ h->mv = f->readInt (1);
+ h->uc = f->readInt (1);
+ h->dp = f->readInt (1);
+ f->ignore (8);
+ h->special = f->readInt (2);
+ for (i = 0; i < 32; i++)
+ h->chanset[i] = f->readInt (1);
+}
+
+void
+Cs3mPlayer::setvolume (unsigned char chan)
+{
+ unsigned char op = op_table[chan], insnr = channel[chan].inst;
+
+ opl->write (0x43 + op,
+ (int) (63 -
+ ((63 -
+ (inst[insnr].d03 & 63)) / 63.0) * channel[chan].vol) +
+ (inst[insnr].d03 & 192));
+ if (inst[insnr].d0a & 1)
+ opl->write (0x40 + op,
+ (int) (63 -
+ ((63 -
+ (inst[insnr].d02 & 63)) / 63.0) *
+ channel[chan].vol) + (inst[insnr].d02 & 192));
+}
+
+void
+Cs3mPlayer::setfreq (unsigned char chan)
+{
+ opl->write (0xa0 + chan, channel[chan].freq & 255);
+ if (channel[chan].key)
+ opl->write (0xb0 + chan,
+ (((channel[chan].freq & 768) >> 8) +
+ (channel[chan].oct << 2)) | 32);
+ else
+ opl->write (0xb0 + chan,
+ ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2));
+}
+
+void
+Cs3mPlayer::playnote (unsigned char chan)
+{
+ unsigned char op = op_table[chan], insnr = channel[chan].inst;
+
+ opl->write (0xb0 + chan, 0); // stop old note
+
+ // set instrument data
+ opl->write (0x20 + op, inst[insnr].d00);
+ opl->write (0x23 + op, inst[insnr].d01);
+ opl->write (0x40 + op, inst[insnr].d02);
+ opl->write (0x43 + op, inst[insnr].d03);
+ opl->write (0x60 + op, inst[insnr].d04);
+ opl->write (0x63 + op, inst[insnr].d05);
+ opl->write (0x80 + op, inst[insnr].d06);
+ opl->write (0x83 + op, inst[insnr].d07);
+ opl->write (0xe0 + op, inst[insnr].d08);
+ opl->write (0xe3 + op, inst[insnr].d09);
+ opl->write (0xc0 + chan, inst[insnr].d0a);
+
+ // set frequency & play
+ channel[chan].key = 1;
+ setfreq (chan);
+}
+
+void
+Cs3mPlayer::slide_down (unsigned char chan, unsigned char amount)
+{
+ if (channel[chan].freq - amount > 340)
+ channel[chan].freq -= amount;
+ else if (channel[chan].oct > 0)
+ {
+ channel[chan].oct--;
+ channel[chan].freq = 684;
+ }
+ else
+ channel[chan].freq = 340;
+}
+
+void
+Cs3mPlayer::slide_up (unsigned char chan, unsigned char amount)
+{
+ if (channel[chan].freq + amount < 686)
+ channel[chan].freq += amount;
+ else if (channel[chan].oct < 7)
+ {
+ channel[chan].oct++;
+ channel[chan].freq = 341;
+ }
+ else
+ channel[chan].freq = 686;
+}
+
+void
+Cs3mPlayer::vibrato (unsigned char chan, unsigned char info)
+{
+ unsigned char i, speed, depth;
+
+ speed = info >> 4;
+ depth = (info & 0x0f) / 2;
+
+ for (i = 0; i < speed; i++)
+ {
+ channel[chan].trigger++;
+ while (channel[chan].trigger >= 64)
+ channel[chan].trigger -= 64;
+ if (channel[chan].trigger >= 16 && channel[chan].trigger < 48)
+ slide_down (chan,
+ (unsigned char) (vibratotab[channel[chan].trigger - 16] /
+ (16 - depth)));
+ if (channel[chan].trigger < 16)
+ slide_up (chan,
+ (unsigned char) (vibratotab[channel[chan].trigger + 16] /
+ (16 - depth)));
+ if (channel[chan].trigger >= 48)
+ slide_up (chan,
+ (unsigned char) (vibratotab[channel[chan].trigger - 48] /
+ (16 - depth)));
+ }
+ setfreq (chan);
+}
+
+void
+Cs3mPlayer::tone_portamento (unsigned char chan, unsigned char info)
+{
+ if (channel[chan].freq + (channel[chan].oct << 10) <
+ channel[chan].nextfreq + (channel[chan].nextoct << 10))
+ slide_up (chan, info);
+ if (channel[chan].freq + (channel[chan].oct << 10) >
+ channel[chan].nextfreq + (channel[chan].nextoct << 10))
+ slide_down (chan, info);
+ setfreq (chan);
+}
diff --git a/src/adplug/core/s3m.cxx b/src/adplug/core/s3m.cxx
deleted file mode 100644
index 141383a4ef3d..000000000000
--- a/src/adplug/core/s3m.cxx
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * s3m.c - S3M Player by Simon Peter <dn.tlp at gmx.net>
- *
- * BUGS:
- * Extra Fine Slides (EEx, FEx) & Fine Vibrato (Uxy) are inaccurate
- */
-
-#include <string.h>
-
-#include "s3m.h"
-
-const char
- Cs3mPlayer::chnresolv[] = // S3M -> adlib channel conversion
-{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3,
- 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, -1 };
-
-const unsigned short
- Cs3mPlayer::notetable[12] = // S3M adlib note table
-{ 340, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647 };
-
-const unsigned char
- Cs3mPlayer::vibratotab[32] = // vibrato rate table
-{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 15, 14, 13, 12,
- 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
-
-/*** public methods *************************************/
-
-CPlayer *
-Cs3mPlayer::factory (Copl * newopl)
-{
- return new Cs3mPlayer (newopl);
-}
-
-Cs3mPlayer::Cs3mPlayer (Copl * newopl):CPlayer (newopl)
-{
- int
- i,
- j,
- k;
-
- memset (pattern, 255, sizeof (pattern));
- memset (orders, 255, sizeof (orders));
-
- for (i = 0; i < 99; i++) // setup pattern
- for (j = 0; j < 64; j++)
- for (k = 0; k < 32; k++)
- {
- pattern[i][j][k].instrument = 0;
- pattern[i][j][k].info = 0;
- }
-}
-
-bool
-Cs3mPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- unsigned short insptr[99], pattptr[99];
- int i, row;
- unsigned char bufval, bufval2;
- unsigned short ppatlen;
- s3mheader *checkhead;
- bool adlibins = false;
-
- // file validation section
- checkhead = new s3mheader;
- load_header (f, checkhead);
- if (checkhead->kennung != 0x1a || checkhead->typ != 16
- || checkhead->insnum > 99)
- {
- delete checkhead;
- fp.close (f);
- return false;
- }
- else if (strncmp (checkhead->scrm, "SCRM", 4))
- {
- delete checkhead;
- fp.close (f);
- return false;
- }
- else
- { // is an adlib module?
- f->seek (checkhead->ordnum, binio::Add);
- for (i = 0; i < checkhead->insnum; i++)
- insptr[i] = f->readInt (2);
- for (i = 0; i < checkhead->insnum; i++)
- {
- f->seek (insptr[i] * 16);
- if (f->readInt (1) >= 2)
- {
- adlibins = true;
- break;
- }
- }
- delete checkhead;
- if (!adlibins)
- {
- fp.close (f);
- return false;
- }
- }
-
- // load section
- f->seek (0); // rewind for load
- load_header (f, &header); // read header
-
- // security check
- if (header.ordnum > 256 || header.insnum > 99 || header.patnum > 99)
- {
- fp.close (f);
- return false;
- }
-
- for (i = 0; i < header.ordnum; i++)
- orders[i] = f->readInt (1); // read orders
- for (i = 0; i < header.insnum; i++)
- insptr[i] = f->readInt (2); // instrument parapointers
- for (i = 0; i < header.patnum; i++)
- pattptr[i] = f->readInt (2); // pattern parapointers
-
- for (i = 0; i < header.insnum; i++)
- { // load instruments
- f->seek (insptr[i] * 16);
- inst[i].type = f->readInt (1);
- f->readString (inst[i].filename, 15);
- inst[i].d00 = f->readInt (1);
- inst[i].d01 = f->readInt (1);
- inst[i].d02 = f->readInt (1);
- inst[i].d03 = f->readInt (1);
- inst[i].d04 = f->readInt (1);
- inst[i].d05 = f->readInt (1);
- inst[i].d06 = f->readInt (1);
- inst[i].d07 = f->readInt (1);
- inst[i].d08 = f->readInt (1);
- inst[i].d09 = f->readInt (1);
- inst[i].d0a = f->readInt (1);
- inst[i].d0b = f->readInt (1);
- inst[i].volume = f->readInt (1);
- inst[i].dsk = f->readInt (1);
- f->ignore (2);
- inst[i].c2spd = f->readInt (4);
- f->ignore (12);
- f->readString (inst[i].name, 28);
- f->readString (inst[i].scri, 4);
- }
-
- for (i = 0; i < header.patnum; i++)
- { // depack patterns
- f->seek (pattptr[i] * 16);
- ppatlen = f->readInt (2);
- unsigned long pattpos = f->pos ();
- for (row = 0; (row < 64) && (pattpos - pattptr[i] * 16 <= ppatlen); row++)
- do
- {
- bufval = f->readInt (1);
- if (bufval & 32)
- {
- bufval2 = f->readInt (1);
- pattern[i][row][bufval & 31].note = bufval2 & 15;
- pattern[i][row][bufval & 31].oct = (bufval2 & 240) >> 4;
- pattern[i][row][bufval & 31].instrument = f->readInt (1);
- }
- if (bufval & 64)
- pattern[i][row][bufval & 31].volume = f->readInt (1);
- if (bufval & 128)
- {
- pattern[i][row][bufval & 31].command = f->readInt (1);
- pattern[i][row][bufval & 31].info = f->readInt (1);
- }
- } while (bufval);
- }
-
- fp.close (f);
- rewind (0);
- return true; // done
-}
-
-bool
-Cs3mPlayer::update ()
-{
- unsigned char pattbreak = 0, donote; // remember vars
- unsigned char pattnr, chan, row, info; // cache vars
- signed char realchan;
-
- // effect handling (timer dependant)
- for (realchan = 0; realchan < 9; realchan++)
- {
- info = channel[realchan].info; // fill infobyte cache
- switch (channel[realchan].fx)
- {
- case 11:
- case 12:
- if (channel[realchan].fx == 11) // dual command: H00 and Dxy
- vibrato (realchan, channel[realchan].dualinfo);
- else // dual command: G00 and Dxy
- tone_portamento (realchan, channel[realchan].dualinfo);
- case 4:
- if (info <= 0x0f) // volume slide down
- {
- if (channel[realchan].vol - info >= 0)
- channel[realchan].vol -= info;
- else
- channel[realchan].vol = 0;
- }
- if ((info & 0x0f) == 0) // volume slide up
- {
- if (channel[realchan].vol + (info >> 4) <= 63)
- channel[realchan].vol += info >> 4;
- else
- channel[realchan].vol = 63;
- }
- setvolume (realchan);
- break;
- case 5:
- if (info == 0xf0 || info <= 0xe0)
- { // slide down
- slide_down (realchan, info);
- setfreq (realchan);
- }
- break;
- case 6:
- if (info == 0xf0 || info <= 0xe0)
- { // slide up
- slide_up (realchan, info);
- setfreq (realchan);
- }
- break;
- case 7:
- tone_portamento (realchan, channel[realchan].dualinfo);
- break; // tone portamento
- case 8:
- vibrato (realchan, channel[realchan].dualinfo);
- break; // vibrato
- case 10:
- channel[realchan].nextfreq = channel[realchan].freq; // arpeggio
- channel[realchan].nextoct = channel[realchan].oct;
- switch (channel[realchan].trigger)
- {
- case 0:
- channel[realchan].freq = notetable[channel[realchan].note];
- break;
- case 1:
- if (channel[realchan].note + ((info & 0xf0) >> 4) < 12)
- channel[realchan].freq =
- notetable[channel[realchan].note + ((info & 0xf0) >> 4)];
- else
- {
- channel[realchan].freq =
- notetable[channel[realchan].note + ((info & 0xf0) >> 4) - 12];
- channel[realchan].oct++;
- }
- break;
- case 2:
- if (channel[realchan].note + (info & 0x0f) < 12)
- channel[realchan].freq =
- notetable[channel[realchan].note + (info & 0x0f)];
- else
- {
- channel[realchan].freq =
- notetable[channel[realchan].note + (info & 0x0f) - 12];
- channel[realchan].oct++;
- }
- break;
- }
- if (channel[realchan].trigger < 2)
- channel[realchan].trigger++;
- else
- channel[realchan].trigger = 0;
- setfreq (realchan);
- channel[realchan].freq = channel[realchan].nextfreq;
- channel[realchan].oct = channel[realchan].nextoct;
- break;
- case 21:
- vibrato (realchan, (unsigned char) (info / 4));
- break; // fine vibrato
- }
- }
-
- if (del)
- { // speed compensation
- del--;
- return !songend;
- }
-
- // arrangement handling
- pattnr = orders[ord];
- if (pattnr == 0xff || ord > header.ordnum)
- { // "--" end of song
- songend = 1; // set end-flag
- ord = 0;
- pattnr = orders[ord];
- if (pattnr == 0xff)
- return !songend;
- }
- if (pattnr == 0xfe)
- { // "++" skip marker
- ord++;
- pattnr = orders[ord];
- }
-
- // play row
- row = crow; // fill row cache
- for (chan = 0; chan < 32; chan++)
- {
- if (!(header.chanset[chan] & 128)) // resolve S3M -> AdLib channels
- realchan = chnresolv[header.chanset[chan] & 127];
- else
- realchan = -1; // channel disabled
- if (realchan != -1)
- { // channel playable?
- // set channel values
- donote = 0;
- if (pattern[pattnr][row][chan].note < 14)
- {
- // tone portamento
- if (pattern[pattnr][row][chan].command == 7
- || pattern[pattnr][row][chan].command == 12)
- {
- channel[realchan].nextfreq =
- notetable[pattern[pattnr][row][chan].note];
- channel[realchan].nextoct = pattern[pattnr][row][chan].oct;
- }
- else
- { // normal note
- channel[realchan].note = pattern[pattnr][row][chan].note;
- channel[realchan].freq = notetable[pattern[pattnr][row][chan].note];
- channel[realchan].oct = pattern[pattnr][row][chan].oct;
- channel[realchan].key = 1;
- donote = 1;
- }
- }
- if (pattern[pattnr][row][chan].note == 14)
- { // key off (is 14 here, cause note is only first 4 bits)
- channel[realchan].key = 0;
- setfreq (realchan);
- }
- if ((channel[realchan].fx != 8 && channel[realchan].fx != 11) && // vibrato begins
- (pattern[pattnr][row][chan].command == 8
- || pattern[pattnr][row][chan].command == 11))
- {
- channel[realchan].nextfreq = channel[realchan].freq;
- channel[realchan].nextoct = channel[realchan].oct;
- }
- if (pattern[pattnr][row][chan].note >= 14)
- if ((channel[realchan].fx == 8 || channel[realchan].fx == 11) && // vibrato ends
- (pattern[pattnr][row][chan].command != 8
- && pattern[pattnr][row][chan].command != 11))
- {
- channel[realchan].freq = channel[realchan].nextfreq;
- channel[realchan].oct = channel[realchan].nextoct;
- setfreq (realchan);
- }
- if (pattern[pattnr][row][chan].instrument)
- { // set instrument
- channel[realchan].inst = pattern[pattnr][row][chan].instrument - 1;
- if (inst[channel[realchan].inst].volume < 64)
- channel[realchan].vol = inst[channel[realchan].inst].volume;
- else
- channel[realchan].vol = 63;
- if (pattern[pattnr][row][chan].command != 7)
- donote = 1;
- }
- if (pattern[pattnr][row][chan].volume != 255)
- {
- if (pattern[pattnr][row][chan].volume < 64) // set volume
- channel[realchan].vol = pattern[pattnr][row][chan].volume;
- else
- channel[realchan].vol = 63;
- }
- channel[realchan].fx = pattern[pattnr][row][chan].command; // set command
- if (pattern[pattnr][row][chan].info) // set infobyte
- channel[realchan].info = pattern[pattnr][row][chan].info;
-
- // some commands reset the infobyte memory
- switch (channel[realchan].fx)
- {
- case 1:
- case 2:
- case 3:
- case 20:
- channel[realchan].info = pattern[pattnr][row][chan].info;
- break;
- }
-
- // play note
- if (donote)
- playnote (realchan);
- if (pattern[pattnr][row][chan].volume != 255) // set volume
- setvolume (realchan);
-
- // command handling (row dependant)
- info = channel[realchan].info; // fill infobyte cache
- switch (channel[realchan].fx)
- {
- case 1:
- speed = info;
- break; // set speed
- case 2:
- if (info <= ord)
- songend = 1;
- ord = info;
- crow = 0;
- pattbreak = 1;
- break; // jump to order
- case 3:
- if (!pattbreak)
- {
- crow = info;
- ord++;
- pattbreak = 1;
- }
- break; // pattern break
- case 4:
- if (info > 0xf0) // fine volume down
- {
- if (channel[realchan].vol - (info & 0x0f) >= 0)
- channel[realchan].vol -= info & 0x0f;
- else
- channel[realchan].vol = 0;
- }
- if ((info & 0x0f) == 0x0f && info >= 0x1f) // fine volume up
- {
- if (channel[realchan].vol + ((info & 0xf0) >> 4) <= 63)
- channel[realchan].vol += (info & 0xf0) >> 4;
- else
- channel[realchan].vol = 63;
- }
- setvolume (realchan);
- break;
- case 5:
- if (info > 0xf0)
- { // fine slide down
- slide_down (realchan, (unsigned char) (info & 0x0f));
- setfreq (realchan);
- }
- if (info > 0xe0 && info < 0xf0)
- { // extra fine slide down
- slide_down (realchan, (unsigned char) ((info & 0x0f) / 4));
- setfreq (realchan);
- }
- break;
- case 6:
- if (info > 0xf0)
- { // fine slide up
- slide_up (realchan, (unsigned char) (info & 0x0f));
- setfreq (realchan);
- }
- if (info > 0xe0 && info < 0xf0)
- { // extra fine slide up
- slide_up (realchan, (unsigned char) ((info & 0x0f) / 4));
- setfreq (realchan);
- }
- break;
- case 7: // tone portamento
- case 8:
- if ((channel[realchan].fx == 7 || // vibrato (remember info for dual commands)
- channel[realchan].fx == 8) && pattern[pattnr][row][chan].info)
- channel[realchan].dualinfo = info;
- break;
- case 10:
- channel[realchan].trigger = 0;
- break; // arpeggio (set trigger)
- case 19:
- if (info == 0xb0) // set loop start
- loopstart = row;
- if (info > 0xb0 && info <= 0xbf) // pattern loop
- {
- if (!loopcnt)
- {
- loopcnt = info & 0x0f;
- crow = loopstart;
- pattbreak = 1;
- }
- else if (--loopcnt > 0)
- {
- crow = loopstart;
- pattbreak = 1;
- }
- }
- if ((info & 0xf0) == 0xe0) // patterndelay
- del = speed * (info & 0x0f) - 1;
- break;
- case 20:
- tempo = info;
- break; // set tempo
- }
- }
- }
-
- if (!del)
- del = speed - 1; // speed compensation
- if (!pattbreak)
- { // next row (only if no manual advance)
- crow++;
- if (crow > 63)
- {
- crow = 0;
- ord++;
- loopstart = 0;
- }
- }
-
- return !songend; // still playing
-}
-
-void
-Cs3mPlayer::rewind (int subsong)
-{
- // set basic variables
- songend = 0;
- ord = 0;
- crow = 0;
- tempo = header.it;
- speed = header.is;
- del = 0;
- loopstart = 0;
- loopcnt = 0;
-
- memset (channel, 0, sizeof (channel));
-
- opl->init (); // reset OPL chip
- opl->write (1, 32); // Go to ym3812 mode
-}
-
-std::string Cs3mPlayer::gettype ()
-{
- char
- filever[5];
-
- switch (header.cwtv)
- { // determine version number
- case 0x1300:
- strcpy (filever, "3.00");
- break;
- case 0x1301:
- strcpy (filever, "3.01");
- break;
- case 0x1303:
- strcpy (filever, "3.03");
- break;
- case 0x1320:
- strcpy (filever, "3.20");
- break;
- default:
- strcpy (filever, "3.??");
- }
-
- return (std::string ("Scream Tracker ") + filever);
-}
-
-float
-Cs3mPlayer::getrefresh ()
-{
- return (float) (tempo / 2.5);
-}
-
-/*** private methods *************************************/
-
-void
-Cs3mPlayer::load_header (binistream * f, s3mheader * h)
-{
- int i;
-
- f->readString (h->name, 28);
- h->kennung = f->readInt (1);
- h->typ = f->readInt (1);
- f->ignore (2);
- h->ordnum = f->readInt (2);
- h->insnum = f->readInt (2);
- h->patnum = f->readInt (2);
- h->flags = f->readInt (2);
- h->cwtv = f->readInt (2);
- h->ffi = f->readInt (2);
- f->readString (h->scrm, 4);
- h->gv = f->readInt (1);
- h->is = f->readInt (1);
- h->it = f->readInt (1);
- h->mv = f->readInt (1);
- h->uc = f->readInt (1);
- h->dp = f->readInt (1);
- f->ignore (8);
- h->special = f->readInt (2);
- for (i = 0; i < 32; i++)
- h->chanset[i] = f->readInt (1);
-}
-
-void
-Cs3mPlayer::setvolume (unsigned char chan)
-{
- unsigned char op = op_table[chan], insnr = channel[chan].inst;
-
- opl->write (0x43 + op,
- (int) (63 -
- ((63 -
- (inst[insnr].d03 & 63)) / 63.0) * channel[chan].vol) +
- (inst[insnr].d03 & 192));
- if (inst[insnr].d0a & 1)
- opl->write (0x40 + op,
- (int) (63 -
- ((63 -
- (inst[insnr].d02 & 63)) / 63.0) *
- channel[chan].vol) + (inst[insnr].d02 & 192));
-}
-
-void
-Cs3mPlayer::setfreq (unsigned char chan)
-{
- opl->write (0xa0 + chan, channel[chan].freq & 255);
- if (channel[chan].key)
- opl->write (0xb0 + chan,
- (((channel[chan].freq & 768) >> 8) +
- (channel[chan].oct << 2)) | 32);
- else
- opl->write (0xb0 + chan,
- ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2));
-}
-
-void
-Cs3mPlayer::playnote (unsigned char chan)
-{
- unsigned char op = op_table[chan], insnr = channel[chan].inst;
-
- opl->write (0xb0 + chan, 0); // stop old note
-
- // set instrument data
- opl->write (0x20 + op, inst[insnr].d00);
- opl->write (0x23 + op, inst[insnr].d01);
- opl->write (0x40 + op, inst[insnr].d02);
- opl->write (0x43 + op, inst[insnr].d03);
- opl->write (0x60 + op, inst[insnr].d04);
- opl->write (0x63 + op, inst[insnr].d05);
- opl->write (0x80 + op, inst[insnr].d06);
- opl->write (0x83 + op, inst[insnr].d07);
- opl->write (0xe0 + op, inst[insnr].d08);
- opl->write (0xe3 + op, inst[insnr].d09);
- opl->write (0xc0 + chan, inst[insnr].d0a);
-
- // set frequency & play
- channel[chan].key = 1;
- setfreq (chan);
-}
-
-void
-Cs3mPlayer::slide_down (unsigned char chan, unsigned char amount)
-{
- if (channel[chan].freq - amount > 340)
- channel[chan].freq -= amount;
- else if (channel[chan].oct > 0)
- {
- channel[chan].oct--;
- channel[chan].freq = 684;
- }
- else
- channel[chan].freq = 340;
-}
-
-void
-Cs3mPlayer::slide_up (unsigned char chan, unsigned char amount)
-{
- if (channel[chan].freq + amount < 686)
- channel[chan].freq += amount;
- else if (channel[chan].oct < 7)
- {
- channel[chan].oct++;
- channel[chan].freq = 341;
- }
- else
- channel[chan].freq = 686;
-}
-
-void
-Cs3mPlayer::vibrato (unsigned char chan, unsigned char info)
-{
- unsigned char i, speed, depth;
-
- speed = info >> 4;
- depth = (info & 0x0f) / 2;
-
- for (i = 0; i < speed; i++)
- {
- channel[chan].trigger++;
- while (channel[chan].trigger >= 64)
- channel[chan].trigger -= 64;
- if (channel[chan].trigger >= 16 && channel[chan].trigger < 48)
- slide_down (chan,
- (unsigned char) (vibratotab[channel[chan].trigger - 16] /
- (16 - depth)));
- if (channel[chan].trigger < 16)
- slide_up (chan,
- (unsigned char) (vibratotab[channel[chan].trigger + 16] /
- (16 - depth)));
- if (channel[chan].trigger >= 48)
- slide_up (chan,
- (unsigned char) (vibratotab[channel[chan].trigger - 48] /
- (16 - depth)));
- }
- setfreq (chan);
-}
-
-void
-Cs3mPlayer::tone_portamento (unsigned char chan, unsigned char info)
-{
- if (channel[chan].freq + (channel[chan].oct << 10) <
- channel[chan].nextfreq + (channel[chan].nextoct << 10))
- slide_up (chan, info);
- if (channel[chan].freq + (channel[chan].oct << 10) >
- channel[chan].nextfreq + (channel[chan].nextoct << 10))
- slide_down (chan, info);
- setfreq (chan);
-}
diff --git a/src/adplug/core/s3m.h b/src/adplug/core/s3m.h
index 9ad16ed742f1..bee1a94ba2d4 100644
--- a/src/adplug/core/s3m.h
+++ b/src/adplug/core/s3m.h
@@ -31,7 +31,7 @@ public:
Cs3mPlayer(Copl *newopl);
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
@@ -90,7 +90,7 @@ protected:
unsigned char crow,ord,speed,tempo,del,songend,loopstart,loopcnt;
private:
- static const char chnresolv[];
+ static const signed char chnresolv[];
static const unsigned short notetable[12];
static const unsigned char vibratotab[32];
diff --git a/src/adplug/core/sa2.cc b/src/adplug/core/sa2.cc
new file mode 100644
index 000000000000..b1c80e61d393
--- /dev/null
+++ b/src/adplug/core/sa2.cc
@@ -0,0 +1,314 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * sa2.cpp - SAdT2 Loader by Simon Peter <dn.tlp at gmx.net>
+ * SAdT Loader by Mamiya <mamiya at users.sourceforge.net>
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "sa2.h"
+#include "debug.h"
+
+CPlayer *
+Csa2Loader::factory (Copl * newopl)
+{
+ return new Csa2Loader (newopl);
+}
+
+bool
+Csa2Loader::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ struct
+ {
+ unsigned char data[11], arpstart, arpspeed, arppos, arpspdcnt;
+ } insts;
+ unsigned char buf;
+ int i, j, k, notedis = 0;
+ const unsigned char convfx[16] =
+ { 0, 1, 2, 3, 4, 5, 6, 255, 8, 255, 10, 11, 12, 13, 255, 15 };
+ unsigned char sat_type;
+ enum SAT_TYPE
+ {
+ HAS_ARPEGIOLIST = (1 << 7),
+ HAS_V7PATTERNS = (1 << 6),
+ HAS_ACTIVECHANNELS = (1 << 5),
+ HAS_TRACKORDER = (1 << 4),
+ HAS_ARPEGIO = (1 << 3),
+ HAS_OLDBPM = (1 << 2),
+ HAS_OLDPATTERNS = (1 << 1),
+ HAS_UNKNOWN127 = (1 << 0)
+ };
+
+ // read header
+ f->readString (header.sadt, 4);
+ header.version = f->readInt (1);
+
+ // file validation section
+ if (strncmp (header.sadt, "SAdT", 4))
+ {
+ fp.close (f);
+ return false;
+ }
+ switch (header.version)
+ {
+ case 1:
+ notedis = +0x18;
+ sat_type = HAS_UNKNOWN127 | HAS_OLDPATTERNS | HAS_OLDBPM;
+ break;
+ case 2:
+ notedis = +0x18;
+ sat_type = HAS_OLDPATTERNS | HAS_OLDBPM;
+ break;
+ case 3:
+ notedis = +0x0c;
+ sat_type = HAS_OLDPATTERNS | HAS_OLDBPM;
+ break;
+ case 4:
+ notedis = +0x0c;
+ sat_type = HAS_ARPEGIO | HAS_OLDPATTERNS | HAS_OLDBPM;
+ break;
+ case 5:
+ notedis = +0x0c;
+ sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_OLDPATTERNS | HAS_OLDBPM;
+ break;
+ case 6:
+ sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_OLDPATTERNS | HAS_OLDBPM;
+ break;
+ case 7:
+ sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_V7PATTERNS;
+ break;
+ case 8:
+ sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_TRACKORDER;
+ break;
+ case 9:
+ sat_type =
+ HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_TRACKORDER | HAS_ACTIVECHANNELS;
+ break;
+ default: /* unknown */
+ fp.close (f);
+ return false;
+ }
+
+ // load section
+ // instruments
+ for (i = 0; i < 31; i++)
+ {
+ if (sat_type & HAS_ARPEGIO)
+ {
+ for (j = 0; j < 11; j++)
+ insts.data[j] = f->readInt (1);
+ insts.arpstart = f->readInt (1);
+ insts.arpspeed = f->readInt (1);
+ insts.arppos = f->readInt (1);
+ insts.arpspdcnt = f->readInt (1);
+ inst[i].arpstart = insts.arpstart;
+ inst[i].arpspeed = insts.arpspeed;
+ inst[i].arppos = insts.arppos;
+ inst[i].arpspdcnt = insts.arpspdcnt;
+ }
+ else
+ {
+ for (j = 0; j < 11; j++)
+ insts.data[j] = f->readInt (1);
+ inst[i].arpstart = 0;
+ inst[i].arpspeed = 0;
+ inst[i].arppos = 0;
+ inst[i].arpspdcnt = 0;
+ }
+ for (j = 0; j < 11; j++)
+ inst[i].data[j] = insts.data[j];
+ inst[i].misc = 0;
+ inst[i].slide = 0;
+ }
+
+ // instrument names
+ for (i = 0; i < 29; i++)
+ f->readString (instname[i], 17);
+
+ f->ignore (3); // dummy bytes
+ for (i = 0; i < 128; i++)
+ order[i] = f->readInt (1); // pattern orders
+ if (sat_type & HAS_UNKNOWN127)
+ f->ignore (127);
+
+ // infos
+ nop = f->readInt (2);
+ length = f->readInt (1);
+ restartpos = f->readInt (1);
+
+ // bpm
+ bpm = f->readInt (2);
+ if (sat_type & HAS_OLDBPM)
+ {
+ bpm = bpm * 125 / 50; // cps -> bpm
+ }
+
+ if (sat_type & HAS_ARPEGIOLIST)
+ {
+ init_specialarp ();
+ for (i = 0; i < 256; i++)
+ arplist[i] = f->readInt (1); // arpeggio list
+ for (i = 0; i < 256; i++)
+ arpcmd[i] = f->readInt (1); // arpeggio commands
+ }
+
+ for (i = 0; i < 64; i++)
+ { // track orders
+ for (j = 0; j < 9; j++)
+ {
+ if (sat_type & HAS_TRACKORDER)
+ trackord[i][j] = f->readInt (1);
+ else
+ {
+ trackord[i][j] = i * 9 + j;
+ }
+ }
+ }
+
+ if (sat_type & HAS_ACTIVECHANNELS)
+ activechan = f->readInt (2) << 16; // active channels
+
+ AdPlug_LogWrite ("Csa2Loader::load(\"%s\"): sat_type = %x, nop = %d, "
+ "length = %d, restartpos = %d, activechan = %x, bpm = %d\n",
+ fd.filename (), sat_type, nop, length, restartpos, activechan,
+ bpm);
+
+ // track data
+ if (sat_type & HAS_OLDPATTERNS)
+ {
+ i = 0;
+ while (!f->ateof ())
+ {
+ for (j = 0; j < 64; j++)
+ {
+ for (k = 0; k < 9; k++)
+ {
+ buf = f->readInt (1);
+ tracks[i + k][j].note = buf ? (buf + notedis) : 0;
+ tracks[i + k][j].inst = f->readInt (1);
+ tracks[i + k][j].command = convfx[f->readInt (1) & 0xf];
+ tracks[i + k][j].param1 = f->readInt (1);
+ tracks[i + k][j].param2 = f->readInt (1);
+ }
+ }
+ i += 9;
+ }
+ }
+ else if (sat_type & HAS_V7PATTERNS)
+ {
+ i = 0;
+ while (!f->ateof ())
+ {
+ for (j = 0; j < 64; j++)
+ {
+ for (k = 0; k < 9; k++)
+ {
+ buf = f->readInt (1);
+ tracks[i + k][j].note = buf >> 1;
+ tracks[i + k][j].inst = (buf & 1) << 4;
+ buf = f->readInt (1);
+ tracks[i + k][j].inst += buf >> 4;
+ tracks[i + k][j].command = convfx[buf & 0x0f];
+ buf = f->readInt (1);
+ tracks[i + k][j].param1 = buf >> 4;
+ tracks[i + k][j].param2 = buf & 0x0f;
+ }
+ }
+ i += 9;
+ }
+ }
+ else
+ {
+ i = 0;
+ while (!f->ateof ())
+ {
+ for (j = 0; j < 64; j++)
+ {
+ buf = f->readInt (1);
+ tracks[i][j].note = buf >> 1;
+ tracks[i][j].inst = (buf & 1) << 4;
+ buf = f->readInt (1);
+ tracks[i][j].inst += buf >> 4;
+ tracks[i][j].command = convfx[buf & 0x0f];
+ buf = f->readInt (1);
+ tracks[i][j].param1 = buf >> 4;
+ tracks[i][j].param2 = buf & 0x0f;
+ }
+ i++;
+ }
+ }
+ fp.close (f);
+
+ // fix instrument names
+ for (i = 0; i < 29; i++)
+ for (j = 0; j < 17; j++)
+ if (!instname[i][j])
+ instname[i][j] = ' ';
+
+ rewind (0); // rewind module
+ return true;
+}
+
+std::string Csa2Loader::gettype ()
+{
+ char
+ tmpstr[40];
+
+ sprintf (tmpstr, "Surprise! Adlib Tracker 2 (version %d)", header.version);
+ return std::string (tmpstr);
+}
+
+std::string Csa2Loader::gettitle ()
+{
+ char
+ bufinst[29 * 17],
+ buf[18];
+ int
+ i,
+ ptr;
+
+ // parse instrument names for song name
+ memset (bufinst, '\0', 29 * 17);
+ for (i = 0; i < 29; i++)
+ {
+ buf[16] = ' ';
+ buf[17] = '\0';
+ memcpy (buf, instname[i] + 1, 16);
+ for (ptr = 16; ptr > 0; ptr--)
+ if (buf[ptr] == ' ')
+ buf[ptr] = '\0';
+ else
+ {
+ if (ptr < 16)
+ buf[ptr + 1] = ' ';
+ break;
+ }
+ strcat (bufinst, buf);
+ }
+
+ if (strchr (bufinst, '"'))
+ return std::string (bufinst, strchr (bufinst, '"') - bufinst + 1,
+ strrchr (bufinst, '"') - strchr (bufinst, '"') - 1);
+ else
+ return std::string ();
+}
diff --git a/src/adplug/core/sa2.cxx b/src/adplug/core/sa2.cxx
deleted file mode 100644
index 8a664fa9c86e..000000000000
--- a/src/adplug/core/sa2.cxx
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2007 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * sa2.cpp - SAdT2 Loader by Simon Peter <dn.tlp at gmx.net>
- * SAdT Loader by Mamiya <mamiya at users.sourceforge.net>
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "sa2.h"
-#include "debug.h"
-
-CPlayer *
-Csa2Loader::factory (Copl * newopl)
-{
- return new Csa2Loader (newopl);
-}
-
-bool
-Csa2Loader::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- struct
- {
- unsigned char data[11], arpstart, arpspeed, arppos, arpspdcnt;
- } insts;
- unsigned char buf;
- int i, j, k, notedis = 0;
- const unsigned char convfx[16] =
- { 0, 1, 2, 3, 4, 5, 6, 255, 8, 255, 10, 11, 12, 13, 255, 15 };
- unsigned char sat_type;
- enum SAT_TYPE
- {
- HAS_ARPEGIOLIST = (1 << 7),
- HAS_V7PATTERNS = (1 << 6),
- HAS_ACTIVECHANNELS = (1 << 5),
- HAS_TRACKORDER = (1 << 4),
- HAS_ARPEGIO = (1 << 3),
- HAS_OLDBPM = (1 << 2),
- HAS_OLDPATTERNS = (1 << 1),
- HAS_UNKNOWN127 = (1 << 0)
- };
-
- // read header
- f->readString (header.sadt, 4);
- header.version = f->readInt (1);
-
- // file validation section
- if (strncmp (header.sadt, "SAdT", 4))
- {
- fp.close (f);
- return false;
- }
- switch (header.version)
- {
- case 1:
- notedis = +0x18;
- sat_type = HAS_UNKNOWN127 | HAS_OLDPATTERNS | HAS_OLDBPM;
- break;
- case 2:
- notedis = +0x18;
- sat_type = HAS_OLDPATTERNS | HAS_OLDBPM;
- break;
- case 3:
- notedis = +0x0c;
- sat_type = HAS_OLDPATTERNS | HAS_OLDBPM;
- break;
- case 4:
- notedis = +0x0c;
- sat_type = HAS_ARPEGIO | HAS_OLDPATTERNS | HAS_OLDBPM;
- break;
- case 5:
- notedis = +0x0c;
- sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_OLDPATTERNS | HAS_OLDBPM;
- break;
- case 6:
- sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_OLDPATTERNS | HAS_OLDBPM;
- break;
- case 7:
- sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_V7PATTERNS;
- break;
- case 8:
- sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_TRACKORDER;
- break;
- case 9:
- sat_type =
- HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_TRACKORDER | HAS_ACTIVECHANNELS;
- break;
- default: /* unknown */
- fp.close (f);
- return false;
- }
-
- // load section
- // instruments
- for (i = 0; i < 31; i++)
- {
- if (sat_type & HAS_ARPEGIO)
- {
- for (j = 0; j < 11; j++)
- insts.data[j] = f->readInt (1);
- insts.arpstart = f->readInt (1);
- insts.arpspeed = f->readInt (1);
- insts.arppos = f->readInt (1);
- insts.arpspdcnt = f->readInt (1);
- inst[i].arpstart = insts.arpstart;
- inst[i].arpspeed = insts.arpspeed;
- inst[i].arppos = insts.arppos;
- inst[i].arpspdcnt = insts.arpspdcnt;
- }
- else
- {
- for (j = 0; j < 11; j++)
- insts.data[j] = f->readInt (1);
- inst[i].arpstart = 0;
- inst[i].arpspeed = 0;
- inst[i].arppos = 0;
- inst[i].arpspdcnt = 0;
- }
- for (j = 0; j < 11; j++)
- inst[i].data[j] = insts.data[j];
- inst[i].misc = 0;
- inst[i].slide = 0;
- }
-
- // instrument names
- for (i = 0; i < 29; i++)
- f->readString (instname[i], 17);
-
- f->ignore (3); // dummy bytes
- for (i = 0; i < 128; i++)
- order[i] = f->readInt (1); // pattern orders
- if (sat_type & HAS_UNKNOWN127)
- f->ignore (127);
-
- // infos
- nop = f->readInt (2);
- length = f->readInt (1);
- restartpos = f->readInt (1);
-
- // bpm
- bpm = f->readInt (2);
- if (sat_type & HAS_OLDBPM)
- {
- bpm = bpm * 125 / 50; // cps -> bpm
- }
-
- if (sat_type & HAS_ARPEGIOLIST)
- {
- init_specialarp ();
- for (i = 0; i < 256; i++)
- arplist[i] = f->readInt (1); // arpeggio list
- for (i = 0; i < 256; i++)
- arpcmd[i] = f->readInt (1); // arpeggio commands
- }
-
- for (i = 0; i < 64; i++)
- { // track orders
- for (j = 0; j < 9; j++)
- {
- if (sat_type & HAS_TRACKORDER)
- trackord[i][j] = f->readInt (1);
- else
- {
- trackord[i][j] = i * 9 + j;
- }
- }
- }
-
- if (sat_type & HAS_ACTIVECHANNELS)
- activechan = f->readInt (2) << 16; // active channels
-
- AdPlug_LogWrite ("Csa2Loader::load(\"%s\"): sat_type = %x, nop = %d, "
- "length = %d, restartpos = %d, activechan = %x, bpm = %d\n",
- vfs_get_filename (fd), sat_type, nop, length, restartpos, activechan,
- bpm);
-
- // track data
- if (sat_type & HAS_OLDPATTERNS)
- {
- i = 0;
- while (!f->ateof ())
- {
- for (j = 0; j < 64; j++)
- {
- for (k = 0; k < 9; k++)
- {
- buf = f->readInt (1);
- tracks[i + k][j].note = buf ? (buf + notedis) : 0;
- tracks[i + k][j].inst = f->readInt (1);
- tracks[i + k][j].command = convfx[f->readInt (1) & 0xf];
- tracks[i + k][j].param1 = f->readInt (1);
- tracks[i + k][j].param2 = f->readInt (1);
- }
- }
- i += 9;
- }
- }
- else if (sat_type & HAS_V7PATTERNS)
- {
- i = 0;
- while (!f->ateof ())
- {
- for (j = 0; j < 64; j++)
- {
- for (k = 0; k < 9; k++)
- {
- buf = f->readInt (1);
- tracks[i + k][j].note = buf >> 1;
- tracks[i + k][j].inst = (buf & 1) << 4;
- buf = f->readInt (1);
- tracks[i + k][j].inst += buf >> 4;
- tracks[i + k][j].command = convfx[buf & 0x0f];
- buf = f->readInt (1);
- tracks[i + k][j].param1 = buf >> 4;
- tracks[i + k][j].param2 = buf & 0x0f;
- }
- }
- i += 9;
- }
- }
- else
- {
- i = 0;
- while (!f->ateof ())
- {
- for (j = 0; j < 64; j++)
- {
- buf = f->readInt (1);
- tracks[i][j].note = buf >> 1;
- tracks[i][j].inst = (buf & 1) << 4;
- buf = f->readInt (1);
- tracks[i][j].inst += buf >> 4;
- tracks[i][j].command = convfx[buf & 0x0f];
- buf = f->readInt (1);
- tracks[i][j].param1 = buf >> 4;
- tracks[i][j].param2 = buf & 0x0f;
- }
- i++;
- }
- }
- fp.close (f);
-
- // fix instrument names
- for (i = 0; i < 29; i++)
- for (j = 0; j < 17; j++)
- if (!instname[i][j])
- instname[i][j] = ' ';
-
- rewind (0); // rewind module
- return true;
-}
-
-std::string Csa2Loader::gettype ()
-{
- char
- tmpstr[40];
-
- sprintf (tmpstr, "Surprise! Adlib Tracker 2 (version %d)", header.version);
- return std::string (tmpstr);
-}
-
-std::string Csa2Loader::gettitle ()
-{
- char
- bufinst[29 * 17],
- buf[18];
- int
- i,
- ptr;
-
- // parse instrument names for song name
- memset (bufinst, '\0', 29 * 17);
- for (i = 0; i < 29; i++)
- {
- buf[16] = ' ';
- buf[17] = '\0';
- memcpy (buf, instname[i] + 1, 16);
- for (ptr = 16; ptr > 0; ptr--)
- if (buf[ptr] == ' ')
- buf[ptr] = '\0';
- else
- {
- if (ptr < 16)
- buf[ptr + 1] = ' ';
- break;
- }
- strcat (bufinst, buf);
- }
-
- if (strchr (bufinst, '"'))
- return std::string (bufinst, strchr (bufinst, '"') - bufinst + 1,
- strrchr (bufinst, '"') - strchr (bufinst, '"') - 1);
- else
- return std::string ();
-}
diff --git a/src/adplug/core/sa2.h b/src/adplug/core/sa2.h
index 39900f47b365..617638196560 100644
--- a/src/adplug/core/sa2.h
+++ b/src/adplug/core/sa2.h
@@ -31,7 +31,7 @@ public:
: CmodPlayer(newopl)
{ }
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
std::string gettype();
std::string gettitle();
diff --git a/src/adplug/core/sng.cc b/src/adplug/core/sng.cc
new file mode 100644
index 000000000000..104c40c45419
--- /dev/null
+++ b/src/adplug/core/sng.cc
@@ -0,0 +1,113 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2002 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * sng.cpp - SNG Player by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <string.h>
+
+#include "sng.h"
+
+CPlayer *
+CsngPlayer::factory (Copl * newopl)
+{
+ return new CsngPlayer (newopl);
+}
+
+bool
+CsngPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ int i;
+
+ // load header
+ f->readString (header.id, 4);
+ header.length = f->readInt (2);
+ header.start = f->readInt (2);
+ header.loop = f->readInt (2);
+ header.delay = f->readInt (1);
+ header.compressed = f->readInt (1) ? true : false;
+
+ // file validation section
+ if (strncmp (header.id, "ObsM", 4))
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // load section
+ header.length /= 2;
+ header.start /= 2;
+ header.loop /= 2;
+ data = new Sdata[header.length];
+ for (i = 0; i < header.length; i++)
+ {
+ data[i].val = f->readInt (1);
+ data[i].reg = f->readInt (1);
+ }
+
+ rewind (0);
+ fp.close (f);
+ return true;
+}
+
+bool
+CsngPlayer::update ()
+{
+ if (header.compressed && del)
+ {
+ del--;
+ return !songend;
+ }
+
+ while (data[pos].reg)
+ {
+ opl->write (data[pos].reg, data[pos].val);
+ pos++;
+ if (pos >= header.length)
+ {
+ songend = true;
+ pos = header.loop;
+ }
+ }
+
+ if (!header.compressed)
+ opl->write (data[pos].reg, data[pos].val);
+
+ if (data[pos].val)
+ del = data[pos].val - 1;
+ pos++;
+ if (pos >= header.length)
+ {
+ songend = true;
+ pos = header.loop;
+ }
+ return !songend;
+}
+
+void
+CsngPlayer::rewind (int subsong)
+{
+ pos = header.start;
+ del = header.delay;
+ songend = false;
+ opl->init ();
+ opl->write (1, 32); // go to OPL2 mode
+}
diff --git a/src/adplug/core/sng.cxx b/src/adplug/core/sng.cxx
deleted file mode 100644
index c84f8766b292..000000000000
--- a/src/adplug/core/sng.cxx
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2002 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * sng.cpp - SNG Player by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <string.h>
-
-#include "sng.h"
-
-CPlayer *
-CsngPlayer::factory (Copl * newopl)
-{
- return new CsngPlayer (newopl);
-}
-
-bool
-CsngPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- int i;
-
- // load header
- f->readString (header.id, 4);
- header.length = f->readInt (2);
- header.start = f->readInt (2);
- header.loop = f->readInt (2);
- header.delay = f->readInt (1);
- header.compressed = f->readInt (1) ? true : false;
-
- // file validation section
- if (strncmp (header.id, "ObsM", 4))
- {
- fp.close (f);
- return false;
- }
-
- // load section
- header.length /= 2;
- header.start /= 2;
- header.loop /= 2;
- data = new Sdata[header.length];
- for (i = 0; i < header.length; i++)
- {
- data[i].val = f->readInt (1);
- data[i].reg = f->readInt (1);
- }
-
- rewind (0);
- fp.close (f);
- return true;
-}
-
-bool
-CsngPlayer::update ()
-{
- if (header.compressed && del)
- {
- del--;
- return !songend;
- }
-
- while (data[pos].reg)
- {
- opl->write (data[pos].reg, data[pos].val);
- pos++;
- if (pos >= header.length)
- {
- songend = true;
- pos = header.loop;
- }
- }
-
- if (!header.compressed)
- opl->write (data[pos].reg, data[pos].val);
-
- if (data[pos].val)
- del = data[pos].val - 1;
- pos++;
- if (pos >= header.length)
- {
- songend = true;
- pos = header.loop;
- }
- return !songend;
-}
-
-void
-CsngPlayer::rewind (int subsong)
-{
- pos = header.start;
- del = header.delay;
- songend = false;
- opl->init ();
- opl->write (1, 32); // go to OPL2 mode
-}
diff --git a/src/adplug/core/sng.h b/src/adplug/core/sng.h
index d0bd5e44e412..195a2f0a98a8 100644
--- a/src/adplug/core/sng.h
+++ b/src/adplug/core/sng.h
@@ -35,7 +35,7 @@ public:
~CsngPlayer() { if(data) delete [] data; data = 0; };
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh()
diff --git a/src/adplug/core/temuopl.cc b/src/adplug/core/temuopl.cc
new file mode 100644
index 000000000000..f0f5aab16cea
--- /dev/null
+++ b/src/adplug/core/temuopl.cc
@@ -0,0 +1,85 @@
+/*
+ * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2004 Simon Peter <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * temuopl.cpp - Tatsuyuki Satoh's OPL2 emulator, by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include "temuopl.h"
+
+CTemuopl::CTemuopl (int rate, bool bit16, bool usestereo):
+use16bit (bit16),
+stereo (usestereo)
+{
+ opl = OPLCreate (OPL_TYPE_YM3812, 3579545, rate);
+}
+
+CTemuopl::~CTemuopl ()
+{
+ OPLDestroy (opl);
+}
+
+void
+CTemuopl::update (short *buf, int samples)
+{
+ int i;
+
+ if (use16bit)
+ {
+ YM3812UpdateOne (opl, buf, samples);
+
+ if (stereo)
+ for (i = samples - 1; i >= 0; i--)
+ {
+ buf[i * 2] = buf[i];
+ buf[i * 2 + 1] = buf[i];
+ }
+ }
+ else
+ {
+ short *tempbuf = new short[stereo ? samples * 2 : samples];
+ int i;
+
+ YM3812UpdateOne (opl, tempbuf, samples);
+
+ if (stereo)
+ for (i = samples - 1; i >= 0; i--)
+ {
+ tempbuf[i * 2] = tempbuf[i];
+ tempbuf[i * 2 + 1] = tempbuf[i];
+ }
+
+ for (i = 0; i < (stereo ? samples * 2 : samples); i++)
+ ((char *) buf)[i] = (tempbuf[i] >> 8) ^ 0x80;
+
+ delete[]tempbuf;
+ tempbuf = 0;
+ }
+}
+
+void
+CTemuopl::write (int reg, int val)
+{
+ OPLWrite (opl, 0, reg);
+ OPLWrite (opl, 1, val);
+}
+
+void
+CTemuopl::init ()
+{
+ OPLResetChip (opl);
+}
diff --git a/src/adplug/core/temuopl.cxx b/src/adplug/core/temuopl.cxx
deleted file mode 100644
index f0f5aab16cea..000000000000
--- a/src/adplug/core/temuopl.cxx
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2004 Simon Peter <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * temuopl.cpp - Tatsuyuki Satoh's OPL2 emulator, by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include "temuopl.h"
-
-CTemuopl::CTemuopl (int rate, bool bit16, bool usestereo):
-use16bit (bit16),
-stereo (usestereo)
-{
- opl = OPLCreate (OPL_TYPE_YM3812, 3579545, rate);
-}
-
-CTemuopl::~CTemuopl ()
-{
- OPLDestroy (opl);
-}
-
-void
-CTemuopl::update (short *buf, int samples)
-{
- int i;
-
- if (use16bit)
- {
- YM3812UpdateOne (opl, buf, samples);
-
- if (stereo)
- for (i = samples - 1; i >= 0; i--)
- {
- buf[i * 2] = buf[i];
- buf[i * 2 + 1] = buf[i];
- }
- }
- else
- {
- short *tempbuf = new short[stereo ? samples * 2 : samples];
- int i;
-
- YM3812UpdateOne (opl, tempbuf, samples);
-
- if (stereo)
- for (i = samples - 1; i >= 0; i--)
- {
- tempbuf[i * 2] = tempbuf[i];
- tempbuf[i * 2 + 1] = tempbuf[i];
- }
-
- for (i = 0; i < (stereo ? samples * 2 : samples); i++)
- ((char *) buf)[i] = (tempbuf[i] >> 8) ^ 0x80;
-
- delete[]tempbuf;
- tempbuf = 0;
- }
-}
-
-void
-CTemuopl::write (int reg, int val)
-{
- OPLWrite (opl, 0, reg);
- OPLWrite (opl, 1, val);
-}
-
-void
-CTemuopl::init ()
-{
- OPLResetChip (opl);
-}
diff --git a/src/adplug/core/temuopl.h b/src/adplug/core/temuopl.h
index ab34b5ef0584..37908c0811b1 100644
--- a/src/adplug/core/temuopl.h
+++ b/src/adplug/core/temuopl.h
@@ -1,17 +1,17 @@
/*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
+ *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -23,9 +23,7 @@
#define H_ADPLUG_TEMUOPL
#include "opl.h"
-extern "C" {
#include "fmopl.h"
-}
class CTemuopl: public Copl
{
diff --git a/src/adplug/core/u6m.cc b/src/adplug/core/u6m.cc
new file mode 100644
index 000000000000..ce67a3ae29fd
--- /dev/null
+++ b/src/adplug/core/u6m.cc
@@ -0,0 +1,1064 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * u6m.cpp - Ultima 6 Music Player by Marc Winterrowd.
+ * This code extends the Adlib Winamp plug-in by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include "u6m.h"
+
+// Makes security checks on output buffer before writing
+#define SAVE_OUTPUT_ROOT(c, d, p) \
+if(p < d.size) \
+ output_root(c, d.data, p); \
+else \
+ return false;
+
+CPlayer *
+Cu6mPlayer::factory (Copl * newopl)
+{
+ return new Cu6mPlayer (newopl);
+}
+
+bool
+Cu6mPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ // file validation section
+ // this section only checks a few *necessary* conditions
+ unsigned long filesize, decompressed_filesize;
+ binistream *f;
+
+ f = fp.open (fd);
+ if (!f)
+ return false;
+ filesize = fp.filesize (f);
+
+ if (filesize >= 6)
+ {
+ // check if the file has a valid pseudo-header
+ unsigned char pseudo_header[6];
+ f->readString ((char *) pseudo_header, 6);
+ decompressed_filesize = pseudo_header[0] + (pseudo_header[1] << 8);
+
+ if (!((pseudo_header[2] == 0) && (pseudo_header[3] == 0) &&
+ (pseudo_header[4] + ((pseudo_header[5] & 0x1) << 8) == 0x100) &&
+ (decompressed_filesize > (filesize - 4))))
+ {
+ fp.close (f);
+ return (false);
+ }
+ }
+ else
+ {
+ fp.close (f);
+ return (false);
+ }
+
+ // load section
+ song_data = new unsigned char[decompressed_filesize];
+ unsigned char *compressed_song_data = new unsigned char[filesize - 3];
+
+ f->seek (4);
+ f->readString ((char *) compressed_song_data, filesize - 4);
+ fp.close (f);
+
+ // attempt to decompress the song data
+ // if unsuccessful, deallocate song_data[] on the spot, and return(false)
+ data_block source, destination;
+ source.size = filesize - 4;
+ source.data = compressed_song_data;
+ destination.size = decompressed_filesize;
+ destination.data = song_data;
+
+ if (!lzw_decompress (source, destination))
+ {
+ delete[]compressed_song_data;
+ compressed_song_data = 0;
+ delete[]song_data;
+ song_data = 0;
+ return (false);
+ }
+
+ // deallocation section
+ delete[]compressed_song_data;
+ compressed_song_data = 0;
+
+ rewind (0);
+ return (true);
+}
+
+
+bool
+Cu6mPlayer::update ()
+{
+ if (!driver_active)
+ {
+ driver_active = true;
+ dec_clip (read_delay);
+ if (read_delay == 0)
+ {
+ command_loop ();
+ }
+
+ // on all Adlib channels: freq slide/vibrato, mute factor slide
+ for (int i = 0; i < 9; i++)
+ {
+ if (channel_freq_signed_delta[i] != 0)
+ // frequency slide + mute factor slide
+ {
+ // freq slide
+ freq_slide (i);
+
+ // mute factor slide
+ if (carrier_mf_signed_delta[i] != 0)
+ {
+ mf_slide (i);
+ }
+ }
+ else
+ // vibrato + mute factor slide
+ {
+ // vibrato
+ if ((vb_multiplier[i] != 0) && ((channel_freq[i].hi & 0x20) == 0x20))
+ {
+ vibrato (i);
+ }
+
+ // mute factor slide
+ if (carrier_mf_signed_delta[i] != 0)
+ {
+ mf_slide (i);
+ }
+ }
+ }
+
+ driver_active = false;
+ }
+
+ return !songend;
+}
+
+
+void
+Cu6mPlayer::rewind (int subsong)
+{
+ played_ticks = 0;
+ songend = false;
+
+ // set the driver's internal variables
+ byte_pair freq_word = { 0, 0 };
+
+ driver_active = false;
+ song_pos = 0;
+ loop_position = 0; // position of the loop point
+ read_delay = 0; // delay (in timer ticks) before further song data is read
+
+ for (int i = 0; i < 9; i++)
+ {
+ // frequency
+ channel_freq_signed_delta[i] = 0;
+ channel_freq[i] = freq_word; // Adlib freq settings for each channel
+
+ // vibrato ("vb")
+ vb_current_value[i] = 0;
+ vb_double_amplitude[i] = 0;
+ vb_multiplier[i] = 0;
+ vb_direction_flag[i] = 0;
+
+ // mute factor ("mf") == ~(volume)
+ carrier_mf[i] = 0;
+ carrier_mf_signed_delta[i] = 0;
+ carrier_mf_mod_delay_backup[i] = 0;
+ carrier_mf_mod_delay[i] = 0;
+ }
+
+ while (!subsong_stack.empty ()) // empty subsong stack
+ subsong_stack.pop ();
+
+ opl->init ();
+ out_adlib (1, 32); // go to OPL2 mode
+}
+
+
+float
+Cu6mPlayer::getrefresh ()
+{
+ return ((float) 60); // the Ultima 6 music driver expects to be called at 60 Hz
+}
+
+
+// ============================================================================================
+//
+//
+// Functions called by load()
+//
+//
+// ============================================================================================
+
+
+// decompress from memory to memory
+bool
+Cu6mPlayer::lzw_decompress (Cu6mPlayer::data_block source,
+ Cu6mPlayer::data_block dest)
+{
+ bool end_marker_reached = false;
+ int codeword_size = 9;
+ long bits_read = 0;
+ int next_free_codeword = 0x102;
+ int dictionary_size = 0x200;
+ MyDict dictionary = MyDict ();
+ std::stack < unsigned char >root_stack;
+
+ long bytes_written = 0;
+
+ int cW, pW = 0;
+ unsigned char C;
+
+ while (!end_marker_reached)
+ {
+ cW = get_next_codeword (bits_read, source.data, codeword_size);
+ switch (cW)
+ {
+ // re-init the dictionary
+ case 0x100:
+ codeword_size = 9;
+ next_free_codeword = 0x102;
+ dictionary_size = 0x200;
+ dictionary.reset ();
+ cW = get_next_codeword (bits_read, source.data, codeword_size);
+ SAVE_OUTPUT_ROOT ((unsigned char) cW, dest, bytes_written);
+ break;
+ // end of compressed file has been reached
+ case 0x101:
+ end_marker_reached = true;
+ break;
+ // (cW <> 0x100) && (cW <> 0x101)
+ default:
+ if (cW < next_free_codeword) // codeword is already in the dictionary
+ {
+ // create the string associated with cW (on the stack)
+ get_string (cW, dictionary, root_stack);
+ C = root_stack.top ();
+ // output the string represented by cW
+ while (!root_stack.empty ())
+ {
+ SAVE_OUTPUT_ROOT (root_stack.top (), dest, bytes_written);
+ root_stack.pop ();
+ }
+ // add pW+C to the dictionary
+ dictionary.add (C, pW);
+
+ next_free_codeword++;
+ if (next_free_codeword >= dictionary_size)
+ {
+ if (codeword_size < max_codeword_length)
+ {
+ codeword_size += 1;
+ dictionary_size *= 2;
+ }
+ }
+ }
+ else // codeword is not yet defined
+ {
+ // create the string associated with pW (on the stack)
+ get_string (pW, dictionary, root_stack);
+ C = root_stack.top ();
+ // output the string represented by pW
+ while (!root_stack.empty ())
+ {
+ SAVE_OUTPUT_ROOT (root_stack.top (), dest, bytes_written);
+ root_stack.pop ();
+ }
+ // output the char C
+ SAVE_OUTPUT_ROOT (C, dest, bytes_written);
+
+ // the new dictionary entry must correspond to cW
+ // if it doesn't, something is wrong with the lzw-compressed data.
+ if (cW != next_free_codeword)
+ {
+ /* printf("cW != next_free_codeword!\n");
+ exit(-1); */
+ return false;
+ }
+ // add pW+C to the dictionary
+ dictionary.add (C, pW);
+
+ next_free_codeword++;
+ if (next_free_codeword >= dictionary_size)
+ {
+ if (codeword_size < max_codeword_length)
+ {
+ codeword_size += 1;
+ dictionary_size *= 2;
+ }
+ }
+ };
+ break;
+ }
+ // shift roles - the current cW becomes the new pW
+ pW = cW;
+ }
+
+ return (true); // indicate successful decompression
+}
+
+
+// --------------------
+// Additional functions
+// --------------------
+
+
+// Read the next code word from the source buffer
+int
+Cu6mPlayer::get_next_codeword (long &bits_read, unsigned char *source,
+ int codeword_size)
+{
+ unsigned char b0, b1, b2;
+ int codeword;
+
+ b0 = source[bits_read / 8];
+ b1 = source[bits_read / 8 + 1];
+ b2 = source[bits_read / 8 + 2];
+
+ codeword = ((b2 << 16) + (b1 << 8) + b0);
+ codeword = codeword >> (bits_read % 8);
+ switch (codeword_size)
+ {
+ case 0x9:
+ codeword = codeword & 0x1ff;
+ break;
+ case 0xa:
+ codeword = codeword & 0x3ff;
+ break;
+ case 0xb:
+ codeword = codeword & 0x7ff;
+ break;
+ case 0xc:
+ codeword = codeword & 0xfff;
+ break;
+ default:
+ codeword = -1; // indicates that an error has occurred
+ break;
+ }
+
+ bits_read += codeword_size;
+ return (codeword);
+}
+
+
+// output a root to memory
+void
+Cu6mPlayer::output_root (unsigned char root, unsigned char *destination,
+ long &position)
+{
+ destination[position] = root;
+ position++;
+}
+
+
+// output the string represented by a codeword
+void
+Cu6mPlayer::get_string (int codeword, Cu6mPlayer::MyDict & dictionary,
+ std::stack < unsigned char >&root_stack)
+{
+ unsigned char root;
+ int current_codeword;
+
+ current_codeword = codeword;
+
+ while (current_codeword > 0xff)
+ {
+ root = dictionary.get_root (current_codeword);
+ current_codeword = dictionary.get_codeword (current_codeword);
+ root_stack.push (root);
+ }
+
+ // push the root at the leaf
+ root_stack.push ((unsigned char) current_codeword);
+}
+
+
+// ============================================================================================
+//
+//
+// Functions called by update()
+//
+//
+// ============================================================================================
+
+
+// This function reads the song data and executes the embedded commands.
+void
+Cu6mPlayer::command_loop ()
+{
+ unsigned char command_byte; // current command byte
+ int command_nibble_hi; // command byte, bits 4-7
+ int command_nibble_lo; // command byte, bite 0-3
+ bool repeat_loop = true; //
+
+ do
+ {
+ // extract low and high command nibbles
+ command_byte = read_song_byte (); // implicitly increments song_pos
+ command_nibble_hi = command_byte >> 4;
+ command_nibble_lo = command_byte & 0xf;
+
+ switch (command_nibble_hi)
+ {
+ case 0x0:
+ command_0 (command_nibble_lo);
+ break;
+ case 0x1:
+ command_1 (command_nibble_lo);
+ break;
+ case 0x2:
+ command_2 (command_nibble_lo);
+ break;
+ case 0x3:
+ command_3 (command_nibble_lo);
+ break;
+ case 0x4:
+ command_4 (command_nibble_lo);
+ break;
+ case 0x5:
+ command_5 (command_nibble_lo);
+ break;
+ case 0x6:
+ command_6 (command_nibble_lo);
+ break;
+ case 0x7:
+ command_7 (command_nibble_lo);
+ break;
+ case 0x8:
+ switch (command_nibble_lo)
+ {
+ case 1:
+ command_81 ();
+ break;
+ case 2:
+ command_82 ();
+ repeat_loop = false;
+ break;
+ case 3:
+ command_83 ();
+ break;
+ case 5:
+ command_85 ();
+ break;
+ case 6:
+ command_86 ();
+ break;
+ default:
+ break; // maybe generate an error?
+ }
+ break;
+ case 0xE:
+ command_E ();
+ break;
+ case 0xF:
+ command_F ();
+ break;
+ default:
+ break; // maybe generate an error?
+ }
+
+ } while (repeat_loop);
+}
+
+
+// --------------------------------------------------------
+// The commands supported by the U6 music file format
+// --------------------------------------------------------
+
+// ----------------------------------------
+// Set octave and frequency, note off
+// Format: 0c nn
+// c = channel, nn = packed Adlib frequency
+// ----------------------------------------
+void
+Cu6mPlayer::command_0 (int channel)
+{
+ unsigned char freq_byte;
+ byte_pair freq_word;
+
+ freq_byte = read_song_byte ();
+ freq_word = expand_freq_byte (freq_byte);
+ set_adlib_freq (channel, freq_word);
+}
+
+
+// ---------------------------------------------------
+// Set octave and frequency, old note off, new note on
+// Format: 1c nn
+// c = channel, nn = packed Adlib frequency
+// ---------------------------------------------------
+void
+Cu6mPlayer::command_1 (int channel)
+{
+ unsigned char freq_byte;
+ byte_pair freq_word;
+
+ vb_direction_flag[channel] = 0;
+ vb_current_value[channel] = 0;
+
+ freq_byte = read_song_byte ();
+ freq_word = expand_freq_byte (freq_byte);
+ set_adlib_freq (channel, freq_word);
+
+ freq_word.hi = freq_word.hi | 0x20; // note on
+ set_adlib_freq (channel, freq_word);
+}
+
+
+// ----------------------------------------
+// Set octave and frequency, note on
+// Format: 2c nn
+// c = channel, nn = packed Adlib frequency
+// ----------------------------------------
+void
+Cu6mPlayer::command_2 (int channel)
+{
+ unsigned char freq_byte;
+ byte_pair freq_word;
+
+ freq_byte = read_song_byte ();
+ freq_word = expand_freq_byte (freq_byte);
+ freq_word.hi = freq_word.hi | 0x20; // note on
+ set_adlib_freq (channel, freq_word);
+}
+
+
+// --------------------------------------
+// Set "carrier mute factor"==not(volume)
+// Format: 3c nn
+// c = channel, nn = mute factor
+// --------------------------------------
+void
+Cu6mPlayer::command_3 (int channel)
+{
+ unsigned char mf_byte;
+
+ carrier_mf_signed_delta[channel] = 0;
+ mf_byte = read_song_byte ();
+ set_carrier_mf (channel, mf_byte);
+}
+
+
+// ----------------------------------------
+// set "modulator mute factor"==not(volume)
+// Format: 4c nn
+// c = channel, nn = mute factor
+// ----------------------------------------
+void
+Cu6mPlayer::command_4 (int channel)
+{
+ unsigned char mf_byte;
+
+ mf_byte = read_song_byte ();
+ set_modulator_mf (channel, mf_byte);
+}
+
+
+// --------------------------------------------
+// Set portamento (pitch slide)
+// Format: 5c nn
+// c = channel, nn = signed channel pitch delta
+// --------------------------------------------
+void
+Cu6mPlayer::command_5 (int channel)
+{
+ channel_freq_signed_delta[channel] = read_signed_song_byte ();
+}
+
+
+// --------------------------------------------
+// Set vibrato paramters
+// Format: 6c mn
+// c = channel
+// m = vibrato double amplitude
+// n = vibrato multiplier
+// --------------------------------------------
+void
+Cu6mPlayer::command_6 (int channel)
+{
+ unsigned char vb_parameters;
+
+ vb_parameters = read_song_byte ();
+ vb_double_amplitude[channel] = vb_parameters >> 4; // high nibble
+ vb_multiplier[channel] = vb_parameters & 0xF; // low nibble
+}
+
+
+// ----------------------------------------
+// Assign Adlib instrument to Adlib channel
+// Format: 7c nn
+// c = channel, nn = instrument number
+// ----------------------------------------
+void
+Cu6mPlayer::command_7 (int channel)
+{
+ int instrument_offset = instrument_offsets[read_song_byte ()];
+ out_adlib_opcell (channel, false, 0x20,
+ *(song_data + instrument_offset + 0));
+ out_adlib_opcell (channel, false, 0x40,
+ *(song_data + instrument_offset + 1));
+ out_adlib_opcell (channel, false, 0x60,
+ *(song_data + instrument_offset + 2));
+ out_adlib_opcell (channel, false, 0x80,
+ *(song_data + instrument_offset + 3));
+ out_adlib_opcell (channel, false, 0xE0,
+ *(song_data + instrument_offset + 4));
+ out_adlib_opcell (channel, true, 0x20,
+ *(song_data + instrument_offset + 5));
+ out_adlib_opcell (channel, true, 0x40,
+ *(song_data + instrument_offset + 6));
+ out_adlib_opcell (channel, true, 0x60,
+ *(song_data + instrument_offset + 7));
+ out_adlib_opcell (channel, true, 0x80,
+ *(song_data + instrument_offset + 8));
+ out_adlib_opcell (channel, true, 0xE0,
+ *(song_data + instrument_offset + 9));
+ out_adlib (0xC0 + channel, *(song_data + instrument_offset + 10));
+}
+
+
+// -------------------------------------------
+// Branch to a new subsong
+// Format: 81 nn aa bb
+// nn == number of times to repeat the subsong
+// aa == subsong offset (low byte)
+// bb == subsong offset (high byte)
+// -------------------------------------------
+void
+Cu6mPlayer::command_81 ()
+{
+ subsong_info new_ss_info;
+
+ new_ss_info.subsong_repetitions = read_song_byte ();
+ new_ss_info.subsong_start = read_song_byte ();
+ new_ss_info.subsong_start += read_song_byte () << 8;
+ new_ss_info.continue_pos = song_pos;
+
+ subsong_stack.push (new_ss_info);
+ song_pos = new_ss_info.subsong_start;
+}
+
+
+// ------------------------------------------------------------
+// Stop interpreting commands for this timer tick
+// Format: 82 nn
+// nn == delay (in timer ticks) until further data will be read
+// ------------------------------------------------------------
+void
+Cu6mPlayer::command_82 ()
+{
+ read_delay = read_song_byte ();
+}
+
+
+// -----------------------------
+// Adlib instrument data follows
+// Format: 83 nn <11 bytes>
+// nn == instrument number
+// -----------------------------
+void
+Cu6mPlayer::command_83 ()
+{
+ unsigned char instrument_number = read_song_byte ();
+ instrument_offsets[instrument_number] = song_pos;
+ song_pos += 11;
+}
+
+
+// ----------------------------------------------
+// Set -1 mute factor slide (upward volume slide)
+// Format: 85 cn
+// c == channel
+// n == slide delay
+// ----------------------------------------------
+void
+Cu6mPlayer::command_85 ()
+{
+ unsigned char data_byte = read_song_byte ();
+ int channel = data_byte >> 4; // high nibble
+ unsigned char slide_delay = data_byte & 0xF; // low nibble
+ carrier_mf_signed_delta[channel] = +1;
+ carrier_mf_mod_delay[channel] = slide_delay + 1;
+ carrier_mf_mod_delay_backup[channel] = slide_delay + 1;
+}
+
+
+// ------------------------------------------------
+// Set +1 mute factor slide (downward volume slide)
+// Format: 86 cn
+// c == channel
+// n == slide speed
+// ------------------------------------------------
+void
+Cu6mPlayer::command_86 ()
+{
+ unsigned char data_byte = read_song_byte ();
+ int channel = data_byte >> 4; // high nibble
+ unsigned char slide_delay = data_byte & 0xF; // low nibble
+ carrier_mf_signed_delta[channel] = -1;
+ carrier_mf_mod_delay[channel] = slide_delay + 1;
+ carrier_mf_mod_delay_backup[channel] = slide_delay + 1;
+}
+
+
+// --------------
+// Set loop point
+// Format: E?
+// --------------
+void
+Cu6mPlayer::command_E ()
+{
+ loop_position = song_pos;
+}
+
+
+// ---------------------------
+// Return from current subsong
+// Format: F?
+// ---------------------------
+void
+Cu6mPlayer::command_F ()
+{
+ if (!subsong_stack.empty ())
+ {
+ subsong_info temp = subsong_stack.top ();
+ subsong_stack.pop ();
+ temp.subsong_repetitions--;
+ if (temp.subsong_repetitions == 0)
+ {
+ song_pos = temp.continue_pos;
+ }
+ else
+ {
+ song_pos = temp.subsong_start;
+ subsong_stack.push (temp);
+ }
+ }
+ else
+ {
+ song_pos = loop_position;
+ songend = true;
+ }
+}
+
+
+// --------------------
+// Additional functions
+// --------------------
+
+// This function decrements its argument, without allowing it to become negative.
+void
+Cu6mPlayer::dec_clip (int ¶m)
+{
+ param--;
+ if (param < 0)
+ {
+ param = 0;
+ }
+}
+
+
+// Returns the byte at the current song position.
+// Side effect: increments song_pos.
+unsigned char
+Cu6mPlayer::read_song_byte ()
+{
+ unsigned char song_byte;
+ song_byte = song_data[song_pos];
+ song_pos++;
+ return (song_byte);
+}
+
+
+// Same as read_song_byte(), except that it returns a signed byte
+signed char
+Cu6mPlayer::read_signed_song_byte ()
+{
+ unsigned char song_byte;
+ int signed_value;
+ song_byte = *(song_data + song_pos);
+ song_pos++;
+ if (song_byte <= 127)
+ {
+ signed_value = song_byte;
+ }
+ else
+ {
+ signed_value = (int) song_byte - 0x100;
+ }
+ return ((signed char) signed_value);
+}
+
+
+Cu6mPlayer::byte_pair Cu6mPlayer::expand_freq_byte (unsigned char freq_byte)
+{
+ const byte_pair
+ freq_table[24] = {
+ {0x00, 0x00}, {0x58, 0x01}, {0x82, 0x01}, {0xB0, 0x01},
+ {0xCC, 0x01}, {0x03, 0x02}, {0x41, 0x02}, {0x86, 0x02},
+ {0x00, 0x00}, {0x6A, 0x01}, {0x96, 0x01}, {0xC7, 0x01},
+ {0xE4, 0x01}, {0x1E, 0x02}, {0x5F, 0x02}, {0xA8, 0x02},
+ {0x00, 0x00}, {0x47, 0x01}, {0x6E, 0x01}, {0x9A, 0x01},
+ {0xB5, 0x01}, {0xE9, 0x01}, {0x24, 0x02}, {0x66, 0x02}
+ };
+
+ int
+ packed_freq;
+ int
+ octave;
+ byte_pair
+ freq_word;
+
+ packed_freq = freq_byte & 0x1F;
+ octave = freq_byte >> 5;
+
+ // range check (not present in the original U6 music driver)
+ if (packed_freq >= 24)
+ {
+ packed_freq = 0;
+ }
+
+ freq_word.hi = freq_table[packed_freq].hi + (octave << 2);
+ freq_word.lo = freq_table[packed_freq].lo;
+
+ return (freq_word);
+}
+
+
+void
+Cu6mPlayer::set_adlib_freq (int channel, Cu6mPlayer::byte_pair freq_word)
+{
+ out_adlib (0xA0 + channel, freq_word.lo);
+ out_adlib (0xB0 + channel, freq_word.hi);
+ // update the Adlib register backups
+ channel_freq[channel] = freq_word;
+}
+
+
+// this function sets the Adlib frequency, but does not update the register backups
+void
+Cu6mPlayer::set_adlib_freq_no_update (int channel,
+ Cu6mPlayer::byte_pair freq_word)
+{
+ out_adlib (0xA0 + channel, freq_word.lo);
+ out_adlib (0xB0 + channel, freq_word.hi);
+}
+
+
+void
+Cu6mPlayer::set_carrier_mf (int channel, unsigned char mute_factor)
+{
+ out_adlib_opcell (channel, true, 0x40, mute_factor);
+ carrier_mf[channel] = mute_factor;
+}
+
+
+void
+Cu6mPlayer::set_modulator_mf (int channel, unsigned char mute_factor)
+{
+ out_adlib_opcell (channel, false, 0x40, mute_factor);
+}
+
+
+void
+Cu6mPlayer::freq_slide (int channel)
+{
+ byte_pair freq = channel_freq[channel];
+
+ long freq_word =
+ freq.lo + (freq.hi << 8) + channel_freq_signed_delta[channel];
+ if (freq_word < 0)
+ {
+ freq_word += 0x10000;
+ }
+ if (freq_word > 0xFFFF)
+ {
+ freq_word -= 0x10000;
+ }
+
+ freq.lo = freq_word & 0xFF;
+ freq.hi = (freq_word >> 8) & 0xFF;
+ set_adlib_freq (channel, freq);
+}
+
+
+void
+Cu6mPlayer::vibrato (int channel)
+{
+ byte_pair freq;
+
+ if (vb_current_value[channel] >= vb_double_amplitude[channel])
+ {
+ vb_direction_flag[channel] = 1;
+ }
+ else if (vb_current_value[channel] <= 0)
+ {
+ vb_direction_flag[channel] = 0;
+ }
+
+ if (vb_direction_flag[channel] == 0)
+ {
+ vb_current_value[channel]++;
+ }
+ else
+ {
+ vb_current_value[channel]--;
+ }
+
+ long freq_word = channel_freq[channel].lo + (channel_freq[channel].hi << 8);
+ freq_word +=
+ (vb_current_value[channel] -
+ (vb_double_amplitude[channel] >> 1)) * vb_multiplier[channel];
+ if (freq_word < 0)
+ {
+ freq_word += 0x10000;
+ }
+ if (freq_word > 0xFFFF)
+ {
+ freq_word -= 0x10000;
+ }
+
+ freq.lo = freq_word & 0xFF;
+ freq.hi = (freq_word >> 8) & 0xFF;
+ set_adlib_freq_no_update (channel, freq);
+}
+
+
+void
+Cu6mPlayer::mf_slide (int channel)
+{
+ carrier_mf_mod_delay[channel]--;
+ if (carrier_mf_mod_delay[channel] == 0)
+ {
+ carrier_mf_mod_delay[channel] = carrier_mf_mod_delay_backup[channel];
+ int current_mf = carrier_mf[channel] + carrier_mf_signed_delta[channel];
+ if (current_mf > 0x3F)
+ {
+ current_mf = 0x3F;
+ carrier_mf_signed_delta[channel] = 0;
+ }
+ else if (current_mf < 0)
+ {
+ current_mf = 0;
+ carrier_mf_signed_delta[channel] = 0;
+ }
+
+ set_carrier_mf (channel, (unsigned char) current_mf);
+ }
+}
+
+
+void
+Cu6mPlayer::out_adlib (unsigned char adlib_register, unsigned char adlib_data)
+{
+ opl->write (adlib_register, adlib_data);
+}
+
+
+void
+Cu6mPlayer::out_adlib_opcell (int channel, bool carrier,
+ unsigned char adlib_register,
+ unsigned char out_byte)
+{
+ const unsigned char adlib_channel_to_carrier_offset[9] =
+ { 0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15 };
+ const unsigned char adlib_channel_to_modulator_offset[9] =
+ { 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12 };
+
+ if (carrier)
+ {
+ out_adlib (adlib_register + adlib_channel_to_carrier_offset[channel],
+ out_byte);
+ }
+ else
+ {
+ out_adlib (adlib_register + adlib_channel_to_modulator_offset[channel],
+ out_byte);
+ }
+}
+
+
+// ============================================================================================
+//
+//
+// The Dictionary
+//
+//
+// ============================================================================================
+
+
+Cu6mPlayer::MyDict::MyDict ()
+{
+ dict_size = default_dict_size;
+ dictionary = new dict_entry[dict_size - 0x100]; // don't allocate space for the roots
+ contains = 0x102;
+}
+
+
+Cu6mPlayer::MyDict::MyDict (int max_size)
+{
+ dict_size = max_size;
+ dictionary = new dict_entry[dict_size - 0x100]; // don't allocate space for the roots
+ contains = 0x102;
+}
+
+
+Cu6mPlayer::MyDict::~MyDict ()
+{
+ delete[]dictionary;
+ dictionary = 0;
+}
+
+// re-initializes the dictionary
+void
+Cu6mPlayer::MyDict::reset ()
+{
+ contains = 0x102;
+}
+
+
+// Note: If the dictionary is already full, this function does nothing.
+void
+Cu6mPlayer::MyDict::add (unsigned char root, int codeword)
+{
+ if (contains < dict_size)
+ {
+ dictionary[contains - 0x100].root = root;
+ dictionary[contains - 0x100].codeword = codeword;
+ contains++;
+ }
+}
+
+
+unsigned char
+Cu6mPlayer::MyDict::get_root (int codeword)
+{
+ return (dictionary[codeword - 0x100].root);
+}
+
+
+int
+Cu6mPlayer::MyDict::get_codeword (int codeword)
+{
+ return (dictionary[codeword - 0x100].codeword);
+}
diff --git a/src/adplug/core/u6m.cxx b/src/adplug/core/u6m.cxx
deleted file mode 100644
index c2267febc1cf..000000000000
--- a/src/adplug/core/u6m.cxx
+++ /dev/null
@@ -1,1064 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * u6m.cpp - Ultima 6 Music Player by Marc Winterrowd.
- * This code extends the Adlib Winamp plug-in by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include "u6m.h"
-
-// Makes security checks on output buffer before writing
-#define SAVE_OUTPUT_ROOT(c, d, p) \
-if(p < d.size) \
- output_root(c, d.data, p); \
-else \
- return false;
-
-CPlayer *
-Cu6mPlayer::factory (Copl * newopl)
-{
- return new Cu6mPlayer (newopl);
-}
-
-bool
-Cu6mPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- // file validation section
- // this section only checks a few *necessary* conditions
- unsigned long filesize, decompressed_filesize;
- binistream *f;
-
- f = fp.open (fd);
- if (!f)
- return false;
- filesize = fp.filesize (f);
-
- if (filesize >= 6)
- {
- // check if the file has a valid pseudo-header
- unsigned char pseudo_header[6];
- f->readString ((char *) pseudo_header, 6);
- decompressed_filesize = pseudo_header[0] + (pseudo_header[1] << 8);
-
- if (!((pseudo_header[2] == 0) && (pseudo_header[3] == 0) &&
- (pseudo_header[4] + ((pseudo_header[5] & 0x1) << 8) == 0x100) &&
- (decompressed_filesize > (filesize - 4))))
- {
- fp.close (f);
- return (false);
- }
- }
- else
- {
- fp.close (f);
- return (false);
- }
-
- // load section
- song_data = new unsigned char[decompressed_filesize];
- unsigned char *compressed_song_data = new unsigned char[filesize - 3];
-
- f->seek (4);
- f->readString ((char *) compressed_song_data, filesize - 4);
- fp.close (f);
-
- // attempt to decompress the song data
- // if unsuccessful, deallocate song_data[] on the spot, and return(false)
- data_block source, destination;
- source.size = filesize - 4;
- source.data = compressed_song_data;
- destination.size = decompressed_filesize;
- destination.data = song_data;
-
- if (!lzw_decompress (source, destination))
- {
- delete[]compressed_song_data;
- compressed_song_data = 0;
- delete[]song_data;
- song_data = 0;
- return (false);
- }
-
- // deallocation section
- delete[]compressed_song_data;
- compressed_song_data = 0;
-
- rewind (0);
- return (true);
-}
-
-
-bool
-Cu6mPlayer::update ()
-{
- if (!driver_active)
- {
- driver_active = true;
- dec_clip (read_delay);
- if (read_delay == 0)
- {
- command_loop ();
- }
-
- // on all Adlib channels: freq slide/vibrato, mute factor slide
- for (int i = 0; i < 9; i++)
- {
- if (channel_freq_signed_delta[i] != 0)
- // frequency slide + mute factor slide
- {
- // freq slide
- freq_slide (i);
-
- // mute factor slide
- if (carrier_mf_signed_delta[i] != 0)
- {
- mf_slide (i);
- }
- }
- else
- // vibrato + mute factor slide
- {
- // vibrato
- if ((vb_multiplier[i] != 0) && ((channel_freq[i].hi & 0x20) == 0x20))
- {
- vibrato (i);
- }
-
- // mute factor slide
- if (carrier_mf_signed_delta[i] != 0)
- {
- mf_slide (i);
- }
- }
- }
-
- driver_active = false;
- }
-
- return !songend;
-}
-
-
-void
-Cu6mPlayer::rewind (int subsong)
-{
- played_ticks = 0;
- songend = false;
-
- // set the driver's internal variables
- byte_pair freq_word = { 0, 0 };
-
- driver_active = false;
- song_pos = 0;
- loop_position = 0; // position of the loop point
- read_delay = 0; // delay (in timer ticks) before further song data is read
-
- for (int i = 0; i < 9; i++)
- {
- // frequency
- channel_freq_signed_delta[i] = 0;
- channel_freq[i] = freq_word; // Adlib freq settings for each channel
-
- // vibrato ("vb")
- vb_current_value[i] = 0;
- vb_double_amplitude[i] = 0;
- vb_multiplier[i] = 0;
- vb_direction_flag[i] = 0;
-
- // mute factor ("mf") == ~(volume)
- carrier_mf[i] = 0;
- carrier_mf_signed_delta[i] = 0;
- carrier_mf_mod_delay_backup[i] = 0;
- carrier_mf_mod_delay[i] = 0;
- }
-
- while (!subsong_stack.empty ()) // empty subsong stack
- subsong_stack.pop ();
-
- opl->init ();
- out_adlib (1, 32); // go to OPL2 mode
-}
-
-
-float
-Cu6mPlayer::getrefresh ()
-{
- return ((float) 60); // the Ultima 6 music driver expects to be called at 60 Hz
-}
-
-
-// ============================================================================================
-//
-//
-// Functions called by load()
-//
-//
-// ============================================================================================
-
-
-// decompress from memory to memory
-bool
-Cu6mPlayer::lzw_decompress (Cu6mPlayer::data_block source,
- Cu6mPlayer::data_block dest)
-{
- bool end_marker_reached = false;
- int codeword_size = 9;
- long bits_read = 0;
- int next_free_codeword = 0x102;
- int dictionary_size = 0x200;
- MyDict dictionary = MyDict ();
- std::stack < unsigned char >root_stack;
-
- long bytes_written = 0;
-
- int cW, pW = 0;
- unsigned char C;
-
- while (!end_marker_reached)
- {
- cW = get_next_codeword (bits_read, source.data, codeword_size);
- switch (cW)
- {
- // re-init the dictionary
- case 0x100:
- codeword_size = 9;
- next_free_codeword = 0x102;
- dictionary_size = 0x200;
- dictionary.reset ();
- cW = get_next_codeword (bits_read, source.data, codeword_size);
- SAVE_OUTPUT_ROOT ((unsigned char) cW, dest, bytes_written);
- break;
- // end of compressed file has been reached
- case 0x101:
- end_marker_reached = true;
- break;
- // (cW <> 0x100) && (cW <> 0x101)
- default:
- if (cW < next_free_codeword) // codeword is already in the dictionary
- {
- // create the string associated with cW (on the stack)
- get_string (cW, dictionary, root_stack);
- C = root_stack.top ();
- // output the string represented by cW
- while (!root_stack.empty ())
- {
- SAVE_OUTPUT_ROOT (root_stack.top (), dest, bytes_written);
- root_stack.pop ();
- }
- // add pW+C to the dictionary
- dictionary.add (C, pW);
-
- next_free_codeword++;
- if (next_free_codeword >= dictionary_size)
- {
- if (codeword_size < max_codeword_length)
- {
- codeword_size += 1;
- dictionary_size *= 2;
- }
- }
- }
- else // codeword is not yet defined
- {
- // create the string associated with pW (on the stack)
- get_string (pW, dictionary, root_stack);
- C = root_stack.top ();
- // output the string represented by pW
- while (!root_stack.empty ())
- {
- SAVE_OUTPUT_ROOT (root_stack.top (), dest, bytes_written);
- root_stack.pop ();
- }
- // output the char C
- SAVE_OUTPUT_ROOT (C, dest, bytes_written);
-
- // the new dictionary entry must correspond to cW
- // if it doesn't, something is wrong with the lzw-compressed data.
- if (cW != next_free_codeword)
- {
- /* printf("cW != next_free_codeword!\n");
- exit(-1); */
- return false;
- }
- // add pW+C to the dictionary
- dictionary.add (C, pW);
-
- next_free_codeword++;
- if (next_free_codeword >= dictionary_size)
- {
- if (codeword_size < max_codeword_length)
- {
- codeword_size += 1;
- dictionary_size *= 2;
- }
- }
- };
- break;
- }
- // shift roles - the current cW becomes the new pW
- pW = cW;
- }
-
- return (true); // indicate successful decompression
-}
-
-
-// --------------------
-// Additional functions
-// --------------------
-
-
-// Read the next code word from the source buffer
-int
-Cu6mPlayer::get_next_codeword (long &bits_read, unsigned char *source,
- int codeword_size)
-{
- unsigned char b0, b1, b2;
- int codeword;
-
- b0 = source[bits_read / 8];
- b1 = source[bits_read / 8 + 1];
- b2 = source[bits_read / 8 + 2];
-
- codeword = ((b2 << 16) + (b1 << 8) + b0);
- codeword = codeword >> (bits_read % 8);
- switch (codeword_size)
- {
- case 0x9:
- codeword = codeword & 0x1ff;
- break;
- case 0xa:
- codeword = codeword & 0x3ff;
- break;
- case 0xb:
- codeword = codeword & 0x7ff;
- break;
- case 0xc:
- codeword = codeword & 0xfff;
- break;
- default:
- codeword = -1; // indicates that an error has occurred
- break;
- }
-
- bits_read += codeword_size;
- return (codeword);
-}
-
-
-// output a root to memory
-void
-Cu6mPlayer::output_root (unsigned char root, unsigned char *destination,
- long &position)
-{
- destination[position] = root;
- position++;
-}
-
-
-// output the string represented by a codeword
-void
-Cu6mPlayer::get_string (int codeword, Cu6mPlayer::MyDict & dictionary,
- std::stack < unsigned char >&root_stack)
-{
- unsigned char root;
- int current_codeword;
-
- current_codeword = codeword;
-
- while (current_codeword > 0xff)
- {
- root = dictionary.get_root (current_codeword);
- current_codeword = dictionary.get_codeword (current_codeword);
- root_stack.push (root);
- }
-
- // push the root at the leaf
- root_stack.push ((unsigned char) current_codeword);
-}
-
-
-// ============================================================================================
-//
-//
-// Functions called by update()
-//
-//
-// ============================================================================================
-
-
-// This function reads the song data and executes the embedded commands.
-void
-Cu6mPlayer::command_loop ()
-{
- unsigned char command_byte; // current command byte
- int command_nibble_hi; // command byte, bits 4-7
- int command_nibble_lo; // command byte, bite 0-3
- bool repeat_loop = true; //
-
- do
- {
- // extract low and high command nibbles
- command_byte = read_song_byte (); // implicitly increments song_pos
- command_nibble_hi = command_byte >> 4;
- command_nibble_lo = command_byte & 0xf;
-
- switch (command_nibble_hi)
- {
- case 0x0:
- command_0 (command_nibble_lo);
- break;
- case 0x1:
- command_1 (command_nibble_lo);
- break;
- case 0x2:
- command_2 (command_nibble_lo);
- break;
- case 0x3:
- command_3 (command_nibble_lo);
- break;
- case 0x4:
- command_4 (command_nibble_lo);
- break;
- case 0x5:
- command_5 (command_nibble_lo);
- break;
- case 0x6:
- command_6 (command_nibble_lo);
- break;
- case 0x7:
- command_7 (command_nibble_lo);
- break;
- case 0x8:
- switch (command_nibble_lo)
- {
- case 1:
- command_81 ();
- break;
- case 2:
- command_82 ();
- repeat_loop = false;
- break;
- case 3:
- command_83 ();
- break;
- case 5:
- command_85 ();
- break;
- case 6:
- command_86 ();
- break;
- default:
- break; // maybe generate an error?
- }
- break;
- case 0xE:
- command_E ();
- break;
- case 0xF:
- command_F ();
- break;
- default:
- break; // maybe generate an error?
- }
-
- } while (repeat_loop);
-}
-
-
-// --------------------------------------------------------
-// The commands supported by the U6 music file format
-// --------------------------------------------------------
-
-// ----------------------------------------
-// Set octave and frequency, note off
-// Format: 0c nn
-// c = channel, nn = packed Adlib frequency
-// ----------------------------------------
-void
-Cu6mPlayer::command_0 (int channel)
-{
- unsigned char freq_byte;
- byte_pair freq_word;
-
- freq_byte = read_song_byte ();
- freq_word = expand_freq_byte (freq_byte);
- set_adlib_freq (channel, freq_word);
-}
-
-
-// ---------------------------------------------------
-// Set octave and frequency, old note off, new note on
-// Format: 1c nn
-// c = channel, nn = packed Adlib frequency
-// ---------------------------------------------------
-void
-Cu6mPlayer::command_1 (int channel)
-{
- unsigned char freq_byte;
- byte_pair freq_word;
-
- vb_direction_flag[channel] = 0;
- vb_current_value[channel] = 0;
-
- freq_byte = read_song_byte ();
- freq_word = expand_freq_byte (freq_byte);
- set_adlib_freq (channel, freq_word);
-
- freq_word.hi = freq_word.hi | 0x20; // note on
- set_adlib_freq (channel, freq_word);
-}
-
-
-// ----------------------------------------
-// Set octave and frequency, note on
-// Format: 2c nn
-// c = channel, nn = packed Adlib frequency
-// ----------------------------------------
-void
-Cu6mPlayer::command_2 (int channel)
-{
- unsigned char freq_byte;
- byte_pair freq_word;
-
- freq_byte = read_song_byte ();
- freq_word = expand_freq_byte (freq_byte);
- freq_word.hi = freq_word.hi | 0x20; // note on
- set_adlib_freq (channel, freq_word);
-}
-
-
-// --------------------------------------
-// Set "carrier mute factor"==not(volume)
-// Format: 3c nn
-// c = channel, nn = mute factor
-// --------------------------------------
-void
-Cu6mPlayer::command_3 (int channel)
-{
- unsigned char mf_byte;
-
- carrier_mf_signed_delta[channel] = 0;
- mf_byte = read_song_byte ();
- set_carrier_mf (channel, mf_byte);
-}
-
-
-// ----------------------------------------
-// set "modulator mute factor"==not(volume)
-// Format: 4c nn
-// c = channel, nn = mute factor
-// ----------------------------------------
-void
-Cu6mPlayer::command_4 (int channel)
-{
- unsigned char mf_byte;
-
- mf_byte = read_song_byte ();
- set_modulator_mf (channel, mf_byte);
-}
-
-
-// --------------------------------------------
-// Set portamento (pitch slide)
-// Format: 5c nn
-// c = channel, nn = signed channel pitch delta
-// --------------------------------------------
-void
-Cu6mPlayer::command_5 (int channel)
-{
- channel_freq_signed_delta[channel] = read_signed_song_byte ();
-}
-
-
-// --------------------------------------------
-// Set vibrato paramters
-// Format: 6c mn
-// c = channel
-// m = vibrato double amplitude
-// n = vibrato multiplier
-// --------------------------------------------
-void
-Cu6mPlayer::command_6 (int channel)
-{
- unsigned char vb_parameters;
-
- vb_parameters = read_song_byte ();
- vb_double_amplitude[channel] = vb_parameters >> 4; // high nibble
- vb_multiplier[channel] = vb_parameters & 0xF; // low nibble
-}
-
-
-// ----------------------------------------
-// Assign Adlib instrument to Adlib channel
-// Format: 7c nn
-// c = channel, nn = instrument number
-// ----------------------------------------
-void
-Cu6mPlayer::command_7 (int channel)
-{
- int instrument_offset = instrument_offsets[read_song_byte ()];
- out_adlib_opcell (channel, false, 0x20,
- *(song_data + instrument_offset + 0));
- out_adlib_opcell (channel, false, 0x40,
- *(song_data + instrument_offset + 1));
- out_adlib_opcell (channel, false, 0x60,
- *(song_data + instrument_offset + 2));
- out_adlib_opcell (channel, false, 0x80,
- *(song_data + instrument_offset + 3));
- out_adlib_opcell (channel, false, 0xE0,
- *(song_data + instrument_offset + 4));
- out_adlib_opcell (channel, true, 0x20,
- *(song_data + instrument_offset + 5));
- out_adlib_opcell (channel, true, 0x40,
- *(song_data + instrument_offset + 6));
- out_adlib_opcell (channel, true, 0x60,
- *(song_data + instrument_offset + 7));
- out_adlib_opcell (channel, true, 0x80,
- *(song_data + instrument_offset + 8));
- out_adlib_opcell (channel, true, 0xE0,
- *(song_data + instrument_offset + 9));
- out_adlib (0xC0 + channel, *(song_data + instrument_offset + 10));
-}
-
-
-// -------------------------------------------
-// Branch to a new subsong
-// Format: 81 nn aa bb
-// nn == number of times to repeat the subsong
-// aa == subsong offset (low byte)
-// bb == subsong offset (high byte)
-// -------------------------------------------
-void
-Cu6mPlayer::command_81 ()
-{
- subsong_info new_ss_info;
-
- new_ss_info.subsong_repetitions = read_song_byte ();
- new_ss_info.subsong_start = read_song_byte ();
- new_ss_info.subsong_start += read_song_byte () << 8;
- new_ss_info.continue_pos = song_pos;
-
- subsong_stack.push (new_ss_info);
- song_pos = new_ss_info.subsong_start;
-}
-
-
-// ------------------------------------------------------------
-// Stop interpreting commands for this timer tick
-// Format: 82 nn
-// nn == delay (in timer ticks) until further data will be read
-// ------------------------------------------------------------
-void
-Cu6mPlayer::command_82 ()
-{
- read_delay = read_song_byte ();
-}
-
-
-// -----------------------------
-// Adlib instrument data follows
-// Format: 83 nn <11 bytes>
-// nn == instrument number
-// -----------------------------
-void
-Cu6mPlayer::command_83 ()
-{
- unsigned char instrument_number = read_song_byte ();
- instrument_offsets[instrument_number] = song_pos;
- song_pos += 11;
-}
-
-
-// ----------------------------------------------
-// Set -1 mute factor slide (upward volume slide)
-// Format: 85 cn
-// c == channel
-// n == slide delay
-// ----------------------------------------------
-void
-Cu6mPlayer::command_85 ()
-{
- unsigned char data_byte = read_song_byte ();
- int channel = data_byte >> 4; // high nibble
- unsigned char slide_delay = data_byte & 0xF; // low nibble
- carrier_mf_signed_delta[channel] = +1;
- carrier_mf_mod_delay[channel] = slide_delay + 1;
- carrier_mf_mod_delay_backup[channel] = slide_delay + 1;
-}
-
-
-// ------------------------------------------------
-// Set +1 mute factor slide (downward volume slide)
-// Format: 86 cn
-// c == channel
-// n == slide speed
-// ------------------------------------------------
-void
-Cu6mPlayer::command_86 ()
-{
- unsigned char data_byte = read_song_byte ();
- int channel = data_byte >> 4; // high nibble
- unsigned char slide_delay = data_byte & 0xF; // low nibble
- carrier_mf_signed_delta[channel] = -1;
- carrier_mf_mod_delay[channel] = slide_delay + 1;
- carrier_mf_mod_delay_backup[channel] = slide_delay + 1;
-}
-
-
-// --------------
-// Set loop point
-// Format: E?
-// --------------
-void
-Cu6mPlayer::command_E ()
-{
- loop_position = song_pos;
-}
-
-
-// ---------------------------
-// Return from current subsong
-// Format: F?
-// ---------------------------
-void
-Cu6mPlayer::command_F ()
-{
- if (!subsong_stack.empty ())
- {
- subsong_info temp = subsong_stack.top ();
- subsong_stack.pop ();
- temp.subsong_repetitions--;
- if (temp.subsong_repetitions == 0)
- {
- song_pos = temp.continue_pos;
- }
- else
- {
- song_pos = temp.subsong_start;
- subsong_stack.push (temp);
- }
- }
- else
- {
- song_pos = loop_position;
- songend = true;
- }
-}
-
-
-// --------------------
-// Additional functions
-// --------------------
-
-// This function decrements its argument, without allowing it to become negative.
-void
-Cu6mPlayer::dec_clip (int ¶m)
-{
- param--;
- if (param < 0)
- {
- param = 0;
- }
-}
-
-
-// Returns the byte at the current song position.
-// Side effect: increments song_pos.
-unsigned char
-Cu6mPlayer::read_song_byte ()
-{
- unsigned char song_byte;
- song_byte = song_data[song_pos];
- song_pos++;
- return (song_byte);
-}
-
-
-// Same as read_song_byte(), except that it returns a signed byte
-signed char
-Cu6mPlayer::read_signed_song_byte ()
-{
- unsigned char song_byte;
- int signed_value;
- song_byte = *(song_data + song_pos);
- song_pos++;
- if (song_byte <= 127)
- {
- signed_value = song_byte;
- }
- else
- {
- signed_value = (int) song_byte - 0x100;
- }
- return ((signed char) signed_value);
-}
-
-
-Cu6mPlayer::byte_pair Cu6mPlayer::expand_freq_byte (unsigned char freq_byte)
-{
- const byte_pair
- freq_table[24] = {
- {0x00, 0x00}, {0x58, 0x01}, {0x82, 0x01}, {0xB0, 0x01},
- {0xCC, 0x01}, {0x03, 0x02}, {0x41, 0x02}, {0x86, 0x02},
- {0x00, 0x00}, {0x6A, 0x01}, {0x96, 0x01}, {0xC7, 0x01},
- {0xE4, 0x01}, {0x1E, 0x02}, {0x5F, 0x02}, {0xA8, 0x02},
- {0x00, 0x00}, {0x47, 0x01}, {0x6E, 0x01}, {0x9A, 0x01},
- {0xB5, 0x01}, {0xE9, 0x01}, {0x24, 0x02}, {0x66, 0x02}
- };
-
- int
- packed_freq;
- int
- octave;
- byte_pair
- freq_word;
-
- packed_freq = freq_byte & 0x1F;
- octave = freq_byte >> 5;
-
- // range check (not present in the original U6 music driver)
- if (packed_freq >= 24)
- {
- packed_freq = 0;
- }
-
- freq_word.hi = freq_table[packed_freq].hi + (octave << 2);
- freq_word.lo = freq_table[packed_freq].lo;
-
- return (freq_word);
-}
-
-
-void
-Cu6mPlayer::set_adlib_freq (int channel, Cu6mPlayer::byte_pair freq_word)
-{
- out_adlib (0xA0 + channel, freq_word.lo);
- out_adlib (0xB0 + channel, freq_word.hi);
- // update the Adlib register backups
- channel_freq[channel] = freq_word;
-}
-
-
-// this function sets the Adlib frequency, but does not update the register backups
-void
-Cu6mPlayer::set_adlib_freq_no_update (int channel,
- Cu6mPlayer::byte_pair freq_word)
-{
- out_adlib (0xA0 + channel, freq_word.lo);
- out_adlib (0xB0 + channel, freq_word.hi);
-}
-
-
-void
-Cu6mPlayer::set_carrier_mf (int channel, unsigned char mute_factor)
-{
- out_adlib_opcell (channel, true, 0x40, mute_factor);
- carrier_mf[channel] = mute_factor;
-}
-
-
-void
-Cu6mPlayer::set_modulator_mf (int channel, unsigned char mute_factor)
-{
- out_adlib_opcell (channel, false, 0x40, mute_factor);
-}
-
-
-void
-Cu6mPlayer::freq_slide (int channel)
-{
- byte_pair freq = channel_freq[channel];
-
- long freq_word =
- freq.lo + (freq.hi << 8) + channel_freq_signed_delta[channel];
- if (freq_word < 0)
- {
- freq_word += 0x10000;
- }
- if (freq_word > 0xFFFF)
- {
- freq_word -= 0x10000;
- }
-
- freq.lo = freq_word & 0xFF;
- freq.hi = (freq_word >> 8) & 0xFF;
- set_adlib_freq (channel, freq);
-}
-
-
-void
-Cu6mPlayer::vibrato (int channel)
-{
- byte_pair freq;
-
- if (vb_current_value[channel] >= vb_double_amplitude[channel])
- {
- vb_direction_flag[channel] = 1;
- }
- else if (vb_current_value[channel] <= 0)
- {
- vb_direction_flag[channel] = 0;
- }
-
- if (vb_direction_flag[channel] == 0)
- {
- vb_current_value[channel]++;
- }
- else
- {
- vb_current_value[channel]--;
- }
-
- long freq_word = channel_freq[channel].lo + (channel_freq[channel].hi << 8);
- freq_word +=
- (vb_current_value[channel] -
- (vb_double_amplitude[channel] >> 1)) * vb_multiplier[channel];
- if (freq_word < 0)
- {
- freq_word += 0x10000;
- }
- if (freq_word > 0xFFFF)
- {
- freq_word -= 0x10000;
- }
-
- freq.lo = freq_word & 0xFF;
- freq.hi = (freq_word >> 8) & 0xFF;
- set_adlib_freq_no_update (channel, freq);
-}
-
-
-void
-Cu6mPlayer::mf_slide (int channel)
-{
- carrier_mf_mod_delay[channel]--;
- if (carrier_mf_mod_delay[channel] == 0)
- {
- carrier_mf_mod_delay[channel] = carrier_mf_mod_delay_backup[channel];
- int current_mf = carrier_mf[channel] + carrier_mf_signed_delta[channel];
- if (current_mf > 0x3F)
- {
- current_mf = 0x3F;
- carrier_mf_signed_delta[channel] = 0;
- }
- else if (current_mf < 0)
- {
- current_mf = 0;
- carrier_mf_signed_delta[channel] = 0;
- }
-
- set_carrier_mf (channel, (unsigned char) current_mf);
- }
-}
-
-
-void
-Cu6mPlayer::out_adlib (unsigned char adlib_register, unsigned char adlib_data)
-{
- opl->write (adlib_register, adlib_data);
-}
-
-
-void
-Cu6mPlayer::out_adlib_opcell (int channel, bool carrier,
- unsigned char adlib_register,
- unsigned char out_byte)
-{
- const unsigned char adlib_channel_to_carrier_offset[9] =
- { 0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15 };
- const unsigned char adlib_channel_to_modulator_offset[9] =
- { 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12 };
-
- if (carrier)
- {
- out_adlib (adlib_register + adlib_channel_to_carrier_offset[channel],
- out_byte);
- }
- else
- {
- out_adlib (adlib_register + adlib_channel_to_modulator_offset[channel],
- out_byte);
- }
-}
-
-
-// ============================================================================================
-//
-//
-// The Dictionary
-//
-//
-// ============================================================================================
-
-
-Cu6mPlayer::MyDict::MyDict ()
-{
- dict_size = default_dict_size;
- dictionary = new dict_entry[dict_size - 0x100]; // don't allocate space for the roots
- contains = 0x102;
-}
-
-
-Cu6mPlayer::MyDict::MyDict (int max_size)
-{
- dict_size = max_size;
- dictionary = new dict_entry[dict_size - 0x100]; // don't allocate space for the roots
- contains = 0x102;
-}
-
-
-Cu6mPlayer::MyDict::~MyDict ()
-{
- delete[]dictionary;
- dictionary = 0;
-}
-
-// re-initializes the dictionary
-void
-Cu6mPlayer::MyDict::reset ()
-{
- contains = 0x102;
-}
-
-
-// Note: If the dictionary is already full, this function does nothing.
-void
-Cu6mPlayer::MyDict::add (unsigned char root, int codeword)
-{
- if (contains < dict_size)
- {
- dictionary[contains - 0x100].root = root;
- dictionary[contains - 0x100].codeword = codeword;
- contains++;
- }
-}
-
-
-unsigned char
-Cu6mPlayer::MyDict::get_root (int codeword)
-{
- return (dictionary[codeword - 0x100].root);
-}
-
-
-int
-Cu6mPlayer::MyDict::get_codeword (int codeword)
-{
- return (dictionary[codeword - 0x100].codeword);
-}
diff --git a/src/adplug/core/u6m.h b/src/adplug/core/u6m.h
index 9876ffbdd425..302047bb6625 100644
--- a/src/adplug/core/u6m.h
+++ b/src/adplug/core/u6m.h
@@ -42,7 +42,7 @@ class Cu6mPlayer: public CPlayer
if(song_data) { delete[] song_data; song_data = 0; }
};
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
@@ -165,4 +165,3 @@ class Cu6mPlayer: public CPlayer
void output_root(unsigned char root, unsigned char *destination, long& position);
void get_string(int codeword, MyDict& dictionary, std::stack<unsigned char>& root_stack);
};
-
diff --git a/src/adplug/core/xad.cc b/src/adplug/core/xad.cc
new file mode 100644
index 000000000000..f5b406c81caa
--- /dev/null
+++ b/src/adplug/core/xad.cc
@@ -0,0 +1,155 @@
+/*
+ Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ xad.cpp - XAD shell player by Riven the Mage <riven at ok.ru>
+*/
+
+#include "xad.h"
+#include "debug.h"
+
+/* -------- Public Methods -------------------------------- */
+
+CxadPlayer::CxadPlayer (Copl * newopl):CPlayer (newopl)
+{
+ tune = 0;
+}
+
+CxadPlayer::~CxadPlayer ()
+{
+ if (tune)
+ {
+ delete[]tune;
+ tune = 0;
+ }
+}
+
+bool
+CxadPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ bool ret = false;
+
+ // load header
+ xad.id = f->readInt (4);
+ f->readString (xad.title, 36);
+ f->readString (xad.author, 36);
+ xad.fmt = f->readInt (2);
+ xad.speed = f->readInt (1);
+ xad.reserved_a = f->readInt (1);
+
+ // 'XAD!' - signed ?
+ if (xad.id != 0x21444158)
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // get file size
+ tune_size = fp.filesize (f) - 80;
+
+ // load()
+ tune = new unsigned char[tune_size];
+ f->readString ((char *) tune, tune_size);
+ fp.close (f);
+
+ ret = xadplayer_load ();
+
+ if (ret)
+ rewind (0);
+
+ return ret;
+}
+
+void
+CxadPlayer::rewind (int subsong)
+{
+ opl->init ();
+
+ plr.speed = xad.speed;
+ plr.speed_counter = 1;
+ plr.playing = 1;
+ plr.looping = 0;
+
+ // rewind()
+ xadplayer_rewind (subsong);
+
+#ifdef DEBUG
+ AdPlug_LogWrite ("-----------\n");
+#endif
+}
+
+bool
+CxadPlayer::update ()
+{
+ if (--plr.speed_counter)
+ goto update_end;
+
+ plr.speed_counter = plr.speed;
+
+ // update()
+ xadplayer_update ();
+
+update_end:
+ return (plr.playing && (!plr.looping));
+}
+
+float
+CxadPlayer::getrefresh ()
+{
+ return xadplayer_getrefresh ();
+}
+
+std::string CxadPlayer::gettype ()
+{
+ return xadplayer_gettype ();
+}
+
+std::string CxadPlayer::gettitle ()
+{
+ return xadplayer_gettitle ();
+}
+
+std::string CxadPlayer::getauthor ()
+{
+ return xadplayer_getauthor ();
+}
+
+std::string CxadPlayer::getinstrument (unsigned int i)
+{
+ return xadplayer_getinstrument (i);
+}
+
+unsigned int
+CxadPlayer::getinstruments ()
+{
+ return xadplayer_getinstruments ();
+}
+
+/* -------- Protected Methods ------------------------------- */
+
+void
+CxadPlayer::opl_write (int reg, int val)
+{
+ adlib[reg] = val;
+#ifdef DEBUG
+ AdPlug_LogWrite ("[ %02X ] = %02X\n", reg, val);
+#endif
+ opl->write (reg, val);
+}
diff --git a/src/adplug/core/xad.cxx b/src/adplug/core/xad.cxx
deleted file mode 100644
index 4b14752bf8ab..000000000000
--- a/src/adplug/core/xad.cxx
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- Adplug - Replayer for many OPL2/OPL3 audio file formats.
- Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- xad.cpp - XAD shell player by Riven the Mage <riven at ok.ru>
-*/
-
-#include "xad.h"
-#include "debug.h"
-
-/* -------- Public Methods -------------------------------- */
-
-CxadPlayer::CxadPlayer (Copl * newopl):CPlayer (newopl)
-{
- tune = 0;
-}
-
-CxadPlayer::~CxadPlayer ()
-{
- if (tune)
- {
- delete[]tune;
- tune = 0;
- }
-}
-
-bool
-CxadPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- bool ret = false;
-
- // load header
- xad.id = f->readInt (4);
- f->readString (xad.title, 36);
- f->readString (xad.author, 36);
- xad.fmt = f->readInt (2);
- xad.speed = f->readInt (1);
- xad.reserved_a = f->readInt (1);
-
- // 'XAD!' - signed ?
- if (xad.id != 0x21444158)
- {
- fp.close (f);
- return false;
- }
-
- // get file size
- tune_size = fp.filesize (f) - 80;
-
- // load()
- tune = new unsigned char[tune_size];
- f->readString ((char *) tune, tune_size);
- fp.close (f);
-
- ret = xadplayer_load ();
-
- if (ret)
- rewind (0);
-
- return ret;
-}
-
-void
-CxadPlayer::rewind (int subsong)
-{
- opl->init ();
-
- plr.speed = xad.speed;
- plr.speed_counter = 1;
- plr.playing = 1;
- plr.looping = 0;
-
- // rewind()
- xadplayer_rewind (subsong);
-
-#ifdef DEBUG
- AdPlug_LogWrite ("-----------\n");
-#endif
-}
-
-bool
-CxadPlayer::update ()
-{
- if (--plr.speed_counter)
- goto update_end;
-
- plr.speed_counter = plr.speed;
-
- // update()
- xadplayer_update ();
-
-update_end:
- return (plr.playing && (!plr.looping));
-}
-
-float
-CxadPlayer::getrefresh ()
-{
- return xadplayer_getrefresh ();
-}
-
-std::string CxadPlayer::gettype ()
-{
- return xadplayer_gettype ();
-}
-
-std::string CxadPlayer::gettitle ()
-{
- return xadplayer_gettitle ();
-}
-
-std::string CxadPlayer::getauthor ()
-{
- return xadplayer_getauthor ();
-}
-
-std::string CxadPlayer::getinstrument (unsigned int i)
-{
- return xadplayer_getinstrument (i);
-}
-
-unsigned int
-CxadPlayer::getinstruments ()
-{
- return xadplayer_getinstruments ();
-}
-
-/* -------- Protected Methods ------------------------------- */
-
-void
-CxadPlayer::opl_write (int reg, int val)
-{
- adlib[reg] = val;
-#ifdef DEBUG
- AdPlug_LogWrite ("[ %02X ] = %02X\n", reg, val);
-#endif
- opl->write (reg, val);
-}
diff --git a/src/adplug/core/xad.h b/src/adplug/core/xad.h
index 15e4c1dab42f..8dd89127b61e 100644
--- a/src/adplug/core/xad.h
+++ b/src/adplug/core/xad.h
@@ -32,7 +32,7 @@ public:
CxadPlayer(Copl * newopl);
~CxadPlayer();
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
diff --git a/src/adplug/core/xsm.cc b/src/adplug/core/xsm.cc
new file mode 100644
index 000000000000..e943769f31cf
--- /dev/null
+++ b/src/adplug/core/xsm.cc
@@ -0,0 +1,136 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * xsm.cpp - eXtra Simple Music Player, by Simon Peter <dn.tlp at gmx.net>
+ */
+
+#include <string.h>
+
+#include "xsm.h"
+
+CxsmPlayer::CxsmPlayer (Copl * newopl):CPlayer (newopl), music (0)
+{
+}
+
+CxsmPlayer::~CxsmPlayer ()
+{
+ if (music)
+ {
+ delete[]music;
+ music = 0;
+ }
+}
+
+bool
+CxsmPlayer::load (VFSFile & fd, const CFileProvider & fp)
+{
+ binistream *f = fp.open (fd);
+ if (!f)
+ return false;
+ char id[6];
+ int i, j;
+
+ // check if header matches
+ f->readString (id, 6);
+ songlen = f->readInt (2);
+ if (strncmp (id, "ofTAZ!", 6) || songlen > 3200)
+ {
+ fp.close (f);
+ return false;
+ }
+
+ // read and set instruments
+ for (i = 0; i < 9; i++)
+ {
+ opl->write (0x20 + op_table[i], f->readInt (1));
+ opl->write (0x23 + op_table[i], f->readInt (1));
+ opl->write (0x40 + op_table[i], f->readInt (1));
+ opl->write (0x43 + op_table[i], f->readInt (1));
+ opl->write (0x60 + op_table[i], f->readInt (1));
+ opl->write (0x63 + op_table[i], f->readInt (1));
+ opl->write (0x80 + op_table[i], f->readInt (1));
+ opl->write (0x83 + op_table[i], f->readInt (1));
+ opl->write (0xe0 + op_table[i], f->readInt (1));
+ opl->write (0xe3 + op_table[i], f->readInt (1));
+ opl->write (0xc0 + op_table[i], f->readInt (1));
+ f->ignore (5);
+ }
+
+ // read song data
+ music = new char[songlen * 9];
+ for (i = 0; i < 9; i++)
+ for (j = 0; j < songlen; j++)
+ music[j * 9 + i] = f->readInt (1);
+
+ // success
+ fp.close (f);
+ rewind (0);
+ return true;
+}
+
+bool
+CxsmPlayer::update ()
+{
+ int c;
+
+ if (notenum >= songlen)
+ {
+ songend = true;
+ notenum = last = 0;
+ }
+
+ for (c = 0; c < 9; c++)
+ if (music[notenum * 9 + c] != music[last * 9 + c])
+ opl->write (0xb0 + c, 0);
+
+ for (c = 0; c < 9; c++)
+ {
+ if (music[notenum * 9 + c])
+ play_note (c, music[notenum * 9 + c] % 12, music[notenum * 9 + c] / 12);
+ else
+ play_note (c, 0, 0);
+ }
+
+ last = notenum;
+ notenum++;
+ return !songend;
+}
+
+void
+CxsmPlayer::rewind (int subsong)
+{
+ notenum = last = 0;
+ songend = false;
+}
+
+float
+CxsmPlayer::getrefresh ()
+{
+ return 5.0f;
+}
+
+void
+CxsmPlayer::play_note (int c, int note, int octv)
+{
+ int freq = note_table[note];
+
+ if (!note && !octv)
+ freq = 0;
+ opl->write (0xa0 + c, freq & 0xff);
+ opl->write (0xb0 + c, (freq / 0xff) | 32 | (octv * 4));
+}
diff --git a/src/adplug/core/xsm.cxx b/src/adplug/core/xsm.cxx
deleted file mode 100644
index 310084c23b9f..000000000000
--- a/src/adplug/core/xsm.cxx
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp at gmx.net>, et al.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * xsm.cpp - eXtra Simple Music Player, by Simon Peter <dn.tlp at gmx.net>
- */
-
-#include <string.h>
-
-#include "xsm.h"
-
-CxsmPlayer::CxsmPlayer (Copl * newopl):CPlayer (newopl), music (0)
-{
-}
-
-CxsmPlayer::~CxsmPlayer ()
-{
- if (music)
- {
- delete[]music;
- music = 0;
- }
-}
-
-bool
-CxsmPlayer::load (VFSFile * fd, const CFileProvider & fp)
-{
- binistream *f = fp.open (fd);
- if (!f)
- return false;
- char id[6];
- int i, j;
-
- // check if header matches
- f->readString (id, 6);
- songlen = f->readInt (2);
- if (strncmp (id, "ofTAZ!", 6) || songlen > 3200)
- {
- fp.close (f);
- return false;
- }
-
- // read and set instruments
- for (i = 0; i < 9; i++)
- {
- opl->write (0x20 + op_table[i], f->readInt (1));
- opl->write (0x23 + op_table[i], f->readInt (1));
- opl->write (0x40 + op_table[i], f->readInt (1));
- opl->write (0x43 + op_table[i], f->readInt (1));
- opl->write (0x60 + op_table[i], f->readInt (1));
- opl->write (0x63 + op_table[i], f->readInt (1));
- opl->write (0x80 + op_table[i], f->readInt (1));
- opl->write (0x83 + op_table[i], f->readInt (1));
- opl->write (0xe0 + op_table[i], f->readInt (1));
- opl->write (0xe3 + op_table[i], f->readInt (1));
- opl->write (0xc0 + op_table[i], f->readInt (1));
- f->ignore (5);
- }
-
- // read song data
- music = new char[songlen * 9];
- for (i = 0; i < 9; i++)
- for (j = 0; j < songlen; j++)
- music[j * 9 + i] = f->readInt (1);
-
- // success
- fp.close (f);
- rewind (0);
- return true;
-}
-
-bool
-CxsmPlayer::update ()
-{
- int c;
-
- if (notenum >= songlen)
- {
- songend = true;
- notenum = last = 0;
- }
-
- for (c = 0; c < 9; c++)
- if (music[notenum * 9 + c] != music[last * 9 + c])
- opl->write (0xb0 + c, 0);
-
- for (c = 0; c < 9; c++)
- {
- if (music[notenum * 9 + c])
- play_note (c, music[notenum * 9 + c] % 12, music[notenum * 9 + c] / 12);
- else
- play_note (c, 0, 0);
- }
-
- last = notenum;
- notenum++;
- return !songend;
-}
-
-void
-CxsmPlayer::rewind (int subsong)
-{
- notenum = last = 0;
- songend = false;
-}
-
-float
-CxsmPlayer::getrefresh ()
-{
- return 5.0f;
-}
-
-void
-CxsmPlayer::play_note (int c, int note, int octv)
-{
- int freq = note_table[note];
-
- if (!note && !octv)
- freq = 0;
- opl->write (0xa0 + c, freq & 0xff);
- opl->write (0xb0 + c, (freq / 0xff) | 32 | (octv * 4));
-}
diff --git a/src/adplug/core/xsm.h b/src/adplug/core/xsm.h
index 2a3fdfd7a86e..714a0af320e9 100644
--- a/src/adplug/core/xsm.h
+++ b/src/adplug/core/xsm.h
@@ -29,7 +29,7 @@ public:
CxsmPlayer(Copl *newopl);
~CxsmPlayer();
- bool load(VFSFile *fd, const CFileProvider &fp);
+ bool load(VFSFile &fd, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
diff --git a/src/adplug/plugin.c b/src/adplug/plugin.c
deleted file mode 100644
index 8e7170b89395..000000000000
--- a/src/adplug/plugin.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-
-#include "adplug-xmms.h"
-static const char * fmts[] =
- { "a2m", "adl", "amd", "bam", "cff", "cmf", "d00", "dfm", "dmo", "dro",
- "dtm", "hsc", "hsp", "ins", "jbm", "ksm", "laa", "lds", "m", "mad",
- "mkj", "msc", "rad", "raw", "rix", "rol", "s3m", "sa2", "sat", "sci",
- "sng", "wlf", "xad", "xsm",
- NULL };
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("AdPlug (AdLib Player)"),
- .domain = PACKAGE,
- .init = adplug_init,
- .cleanup = adplug_quit,
- .play = adplug_play,
- .probe_for_tuple = adplug_get_tuple,
- .is_our_file_from_vfs = adplug_is_our_fd,
- .extensions = fmts,
-)
diff --git a/src/alarm/Makefile b/src/alarm/Makefile
index 2e8b7611f21b..03357bdad7db 100644
--- a/src/alarm/Makefile
+++ b/src/alarm/Makefile
@@ -1,13 +1,15 @@
PLUGIN = alarm${PLUGIN_SUFFIX}
-SRCS = alarm.c \
- interface.c
+SRCS = alarm.cc \
+ interface.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += ${GTK_LIBS} ${GLIB_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} -I../..
+LIBS += ${GTK_LIBS} -laudgui
diff --git a/src/alarm/alarm.c b/src/alarm/alarm.c
deleted file mode 100644
index 3e3848f33a17..000000000000
--- a/src/alarm/alarm.c
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- * Copyright (C) Adam Feakin <adamf at snika.uklinux.net>
- *
- * modified by Daniel Stodden <stodden at in.tum.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <stdlib.h>
-
-#include <time.h>
-#if TM_IN_SYS_TIME
-# include <sys/time.h>
-#endif
-
-#include <string.h>
-#include <stdio.h>
-
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-#include <pthread.h>
-#include <assert.h>
-#include <math.h>
-
-#include <audacious/debug.h>
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "alarm.h"
-#include "interface.h"
-#include "callbacks.h"
-
-static const gchar * const alarm_defaults[] = {
- /* general */
- "alarm_h", "6",
- "alarm_m", "30",
- "cmd_on", "FALSE",
- "fading", "60",
- "quietvol", "25",
- "reminder_on", "FALSE",
- "stop_h", "1",
- "stop_m", "0",
- "stop_on", "TRUE",
- "volume", "80",
-
- /* days */
- "sun_flags", "3",
- "sun_h", "6",
- "sun_m", "30",
- "mon_flags", "2",
- "mon_h", "6",
- "mon_m", "30",
- "tue_flags", "2",
- "tue_h", "6",
- "tue_m", "30",
- "wed_flags", "2",
- "wed_h", "6",
- "wed_m", "30",
- "thu_flags", "2",
- "thu_h", "6",
- "thu_m", "30",
- "fri_flags", "2",
- "fri_h", "6",
- "fri_m", "30",
- "sat_flags", "2",
- "sat_h", "6",
- "sat_m", "30",
- NULL};
-
-typedef struct
-{
- pthread_t tid;
- volatile gboolean is_valid;
-} alarm_thread_t;
-
-static gint timeout_source;
-static time_t play_start;
-
-static alarm_thread_t stop; /* thread id of stop loop */
-static pthread_mutex_t fader_lock = PTHREAD_MUTEX_INITIALIZER;
-
-static GeneralPlugin alarm_plugin;
-
-/* string tokens to allow loops and shorten code */
-static char day_cb[7][7] = {"sun_cb", "mon_cb", "tue_cb",
- "wed_cb", "thu_cb", "fri_cb", "sat_cb"};
-
-static char day_flags[7][10] = {"sun_flags", "mon_flags", "tue_flags",
- "wed_flags", "thu_flags", "fri_flags", "sat_flags"};
-
-static char day_h[7][6] = {"sun_h", "mon_h", "tue_h",
- "wed_h", "thu_h", "fri_h", "sat_h"};
-
-static char day_m[7][6] = {"sun_m", "mon_m", "tue_m",
- "wed_m", "thu_m", "fri_m", "sat_m"};
-
-static char day_def[7][8] = {"sun_def", "mon_def", "tue_def",
- "wed_def", "thu_def", "fri_def", "sat_def"};
-
-static struct
-{
- GtkSpinButton *alarm_h;
- GtkSpinButton *alarm_m;
-
- GtkToggleButton *stop_on;
- GtkSpinButton *stop_h;
- GtkSpinButton *stop_m;
-
- GtkRange *volume;
- GtkRange *quietvol;
-
- GtkSpinButton *fading;
-
- GtkEntry *cmdstr;
- GtkToggleButton *cmd_on;
-
- GtkEntry *playlist;
-
- int default_hour;
- int default_min;
-
- // array allows looping of days
- alarmday day[7];
-
-
- GtkEntry *reminder;
- GtkToggleButton *reminder_cb;
- gboolean reminder_on;
-}
-alarm_conf;
-
-static gint alarm_h, alarm_m;
-
-static gboolean stop_on;
-static gint stop_h, stop_m;
-
-static gint volume, quietvol;
-
-static gint fading;
-
-static gboolean cmd_on;
-
-static GtkWidget *config_dialog = NULL;
-static GtkWidget *alarm_dialog = NULL;
-
-static GtkWidget *lookup_widget(GtkWidget *w, const gchar *name)
-{
- GtkWidget * widget = g_object_get_data ((GObject *) w, name);
- g_return_val_if_fail(widget != NULL, NULL);
-
- return widget;
-}
-
-/*
- * the callback function that is called when the save button is
- * pressed saves configuration to ~/.bmp/alarmconfig
- */
-void alarm_save(void)
-{
- int daynum = 0; // used to identify day number
-
- /*
- * update the live values and write them out
- */
- alarm_h = alarm_conf.default_hour = gtk_spin_button_get_value_as_int (alarm_conf.alarm_h);
- aud_set_int ("alarm", "alarm_h", alarm_h);
-
- alarm_m = alarm_conf.default_min = gtk_spin_button_get_value_as_int (alarm_conf.alarm_m);
- aud_set_int ("alarm", "alarm_m", alarm_m);
-
- stop_h = gtk_spin_button_get_value_as_int (alarm_conf.stop_h);
- stop_m = gtk_spin_button_get_value_as_int (alarm_conf.stop_m);
- stop_on = gtk_toggle_button_get_active (alarm_conf.stop_on);
-
- /* days of the week */
- for(; daynum < 7; daynum++)
- {
- if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(alarm_conf.day[daynum].cb)))
- alarm_conf.day[daynum].flags = 0;
- else
- alarm_conf.day[daynum].flags = ALARM_OFF;
-
- if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(alarm_conf.day[daynum].cb_def)))
- alarm_conf.day[daynum].flags |= ALARM_DEFAULT;
-
- alarm_conf.day[daynum].hour =
- gtk_spin_button_get_value_as_int(alarm_conf.day[daynum].spin_hr);
- alarm_conf.day[daynum].min =
- gtk_spin_button_get_value_as_int(alarm_conf.day[daynum].spin_min);
-
- aud_set_int ("alarm", day_flags[daynum], alarm_conf.day[daynum].flags);
- aud_set_int ("alarm", day_h[daynum], alarm_conf.day[daynum].hour);
- aud_set_int ("alarm", day_m[daynum], alarm_conf.day[daynum].min);
- }
-
- /* END: days of week */
-
- volume = gtk_range_get_value (alarm_conf.volume);
- aud_set_int ("alarm", "volume", volume);
-
- quietvol = gtk_range_get_value (alarm_conf.quietvol);
- aud_set_int ("alarm", "quietvol", quietvol);
-
- fading = gtk_spin_button_get_value_as_int (alarm_conf.fading);
-
- /* write the new values */
- aud_set_int ("alarm", "stop_h", stop_h);
- aud_set_int ("alarm", "stop_m", stop_m);
- aud_set_int ("alarm", "fading", fading);
- aud_set_bool ("alarm", "stop_on", stop_on);
-
- char * cmdstr = gtk_editable_get_chars ((GtkEditable *) alarm_conf.cmdstr, 0, -1);
- aud_set_str ("alarm", "cmdstr", cmdstr);
- g_free (cmdstr);
-
- cmd_on = gtk_toggle_button_get_active (alarm_conf.cmd_on);
- aud_set_bool ("alarm", "cmd_on", cmd_on);
-
- char * playlist = gtk_editable_get_chars ((GtkEditable *) alarm_conf.playlist, 0, -1);
- aud_set_str ("alarm", "playlist", playlist);
- g_free (playlist);
-
- /* reminder */
- char * reminder_msg = gtk_editable_get_chars ((GtkEditable *) alarm_conf.reminder, 0, -1);
- aud_set_str ("alarm", "reminder_msg", reminder_msg);
- g_free (reminder_msg);
-
- alarm_conf.reminder_on = gtk_toggle_button_get_active (alarm_conf.reminder_cb);
- aud_set_bool ("alarm", "reminder_on", alarm_conf.reminder_on);
-}
-
-/*
- * read the current configuration from the file
- */
-static void alarm_read_config(void)
-{
- int daynum = 0; // used for day number
-
- aud_config_set_defaults ("alarm", alarm_defaults);
-
- alarm_h = aud_get_int ("alarm", "alarm_h");
- alarm_m = aud_get_int ("alarm", "alarm_m");
-
- /* save them here too */
- alarm_conf.default_hour = alarm_h;
- alarm_conf.default_min = alarm_m;
-
- stop_h = aud_get_int ("alarm", "stop_h");
- stop_m = aud_get_int ("alarm", "stop_m");
- stop_on = aud_get_bool ("alarm", "stop_on");
-
- volume = aud_get_int ("alarm", "volume");
- quietvol = aud_get_int ("alarm", "quietvol");
-
- fading = aud_get_int ("alarm", "fading");
-
- cmd_on = aud_get_bool ("alarm", "cmd_on");
-
- alarm_conf.reminder_on = aud_get_bool ("alarm", "reminder_on");
-
- /* day flags and times */
- for(; daynum < 7; daynum++)
- {
- /* read the flags */
- alarm_conf.day[daynum].flags = aud_get_int ("alarm", day_flags[daynum]);
-
- /* read the times */
- alarm_conf.day[daynum].hour = aud_get_int ("alarm", day_h[daynum]);
- alarm_conf.day[daynum].min = aud_get_int ("alarm", day_m[daynum]);
- }
-}
-
-/*
- * displays the configuration window and opens the config file.
- */
-static void alarm_configure(void)
-{
- int daynum = 0; // used to loop days
- GtkWidget *w;
-
- if (config_dialog)
- {
- gtk_window_present(GTK_WINDOW(config_dialog));
- return;
- }
-
- alarm_read_config();
-
- /*
- * Create the widgets
- */
- config_dialog = create_config_dialog();
-
- w = lookup_widget(config_dialog, "alarm_h_spin");
- alarm_conf.alarm_h = GTK_SPIN_BUTTON(w);
- gtk_spin_button_set_value(alarm_conf.alarm_h, alarm_h);
-
- w = lookup_widget(config_dialog, "alarm_m_spin");
- alarm_conf.alarm_m = GTK_SPIN_BUTTON(w);
- gtk_spin_button_set_value(alarm_conf.alarm_m, alarm_m);
-
- w = lookup_widget(config_dialog, "stop_h_spin");
- alarm_conf.stop_h = GTK_SPIN_BUTTON(w);
- gtk_spin_button_set_value(alarm_conf.stop_h, stop_h);
-
- w = lookup_widget(config_dialog, "stop_m_spin");
- alarm_conf.stop_m = GTK_SPIN_BUTTON(w);
- gtk_spin_button_set_value(alarm_conf.stop_m, stop_m);
-
- w = lookup_widget(config_dialog, "stop_checkb");
- alarm_conf.stop_on = GTK_TOGGLE_BUTTON(w);
- gtk_toggle_button_set_active(alarm_conf.stop_on, stop_on);
-
- w = lookup_widget(config_dialog, "vol_scale");
- alarm_conf.volume = GTK_RANGE(w);
- gtk_range_set_adjustment(alarm_conf.volume,
- GTK_ADJUSTMENT(gtk_adjustment_new(volume, 0, 100, 1, 5, 0)));
-
- w = lookup_widget(config_dialog, "quiet_vol_scale");
- alarm_conf.quietvol = GTK_RANGE(w);
- gtk_range_set_adjustment(alarm_conf.quietvol,
- GTK_ADJUSTMENT(gtk_adjustment_new(quietvol, 0, 100, 1, 5, 0)));
-
- /* days of week */
- for(; daynum < 7; daynum++)
- {
- w = lookup_widget(config_dialog, day_cb[daynum]);
- alarm_conf.day[daynum].cb = GTK_CHECK_BUTTON(w);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(alarm_conf.day[daynum].cb),
- !(alarm_conf.day[daynum].flags & ALARM_OFF));
-
- w = lookup_widget(config_dialog, day_def[daynum]);
- alarm_conf.day[daynum].cb_def = GTK_CHECK_BUTTON(w);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(alarm_conf.day[daynum].cb_def),
- alarm_conf.day[daynum].flags & ALARM_DEFAULT);
-
-
- /* Changed to show default time instead of set time when ALARM_DEFAULT set,
- * as suggested by Mark Brown
- */
-/* w = lookup_widget(config_dialog, day_h[daynum]);
- alarm_conf.day[daynum].spin_hr = GTK_SPIN_BUTTON(w);
- gtk_spin_button_set_value(alarm_conf.day[daynum].spin_hr, alarm_conf.day[daynum].hour);
-
- w = lookup_widget(config_dialog, day_m[daynum]);
- alarm_conf.day[daynum].spin_min = GTK_SPIN_BUTTON(w);
- gtk_spin_button_set_value(alarm_conf.day[daynum].spin_min, alarm_conf.day[daynum].min);
-*/
- if(alarm_conf.day[daynum].flags & ALARM_DEFAULT)
- {
- w = lookup_widget(config_dialog, day_h[daynum]);
- alarm_conf.day[daynum].spin_hr = GTK_SPIN_BUTTON(w);
- gtk_spin_button_set_value(alarm_conf.day[daynum].spin_hr, alarm_conf.default_hour);
-
- w = lookup_widget(config_dialog, day_m[daynum]);
- alarm_conf.day[daynum].spin_min = GTK_SPIN_BUTTON(w);
- gtk_spin_button_set_value(alarm_conf.day[daynum].spin_min, alarm_conf.default_min);
-
- gtk_widget_set_sensitive((GtkWidget *)alarm_conf.day[daynum].spin_hr, FALSE);
- gtk_widget_set_sensitive((GtkWidget *)alarm_conf.day[daynum].spin_min, FALSE);
- }
- else
- {
- w = lookup_widget(config_dialog, day_h[daynum]);
- alarm_conf.day[daynum].spin_hr = GTK_SPIN_BUTTON(w);
- gtk_spin_button_set_value(alarm_conf.day[daynum].spin_hr, alarm_conf.day[daynum].hour);
-
- w = lookup_widget(config_dialog, day_m[daynum]);
- alarm_conf.day[daynum].spin_min = GTK_SPIN_BUTTON(w);
- gtk_spin_button_set_value(alarm_conf.day[daynum].spin_min, alarm_conf.day[daynum].min);
-
- gtk_widget_set_sensitive((GtkWidget *)alarm_conf.day[daynum].spin_hr, TRUE);
- gtk_widget_set_sensitive((GtkWidget *)alarm_conf.day[daynum].spin_min, TRUE);
- }
- }
-
- /* END: days of week */
-
- w = lookup_widget(config_dialog,"fading_spin");
- alarm_conf.fading = GTK_SPIN_BUTTON(w);
- gtk_spin_button_set_value(alarm_conf.fading, fading);
-
- char * cmdstr = aud_get_str ("alarm", "cmdstr");
- w = lookup_widget(config_dialog, "cmd_entry");
- alarm_conf.cmdstr = GTK_ENTRY(w);
- gtk_entry_set_text(alarm_conf.cmdstr, cmdstr);
- str_unref (cmdstr);
-
- w = lookup_widget(config_dialog, "cmd_checkb");
- alarm_conf.cmd_on = GTK_TOGGLE_BUTTON(w);
- gtk_toggle_button_set_active(alarm_conf.cmd_on, cmd_on);
-
- char * playlist = aud_get_str ("alarm", "playlist");
- w = lookup_widget(config_dialog, "playlist");
- alarm_conf.playlist = GTK_ENTRY(w);
- gtk_entry_set_text(alarm_conf.playlist, playlist);
- str_unref (playlist);
-
- char * reminder_msg = aud_get_str ("alarm", "reminder_msg");
- w = lookup_widget(config_dialog, "reminder_text");
- alarm_conf.reminder = GTK_ENTRY(w);
- gtk_entry_set_text(alarm_conf.reminder, reminder_msg);
- str_unref (reminder_msg);
-
- w = lookup_widget(config_dialog, "reminder_cb");
- alarm_conf.reminder_cb = GTK_TOGGLE_BUTTON(w);
- gtk_toggle_button_set_active(alarm_conf.reminder_cb, alarm_conf.reminder_on);
-
- g_signal_connect (config_dialog, "destroy", (GCallback) gtk_widget_destroyed,
- & config_dialog);
-
- AUDDBG("END alarm_configure\n");
-}
-
-/* functions for greying out the time for days */
-void on_day_def_toggled(GtkToggleButton *togglebutton, gpointer user_data, int daynum)
-{
- GtkWidget *w;
-
- /* change the time shown too */
- w = lookup_widget(config_dialog, day_h[daynum]);
- if(w == NULL)
- return;
-
- if(gtk_toggle_button_get_active(togglebutton) == TRUE)
- {
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), alarm_conf.default_hour);
- gtk_widget_set_sensitive(w, FALSE);
- }
- else
- {
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), alarm_conf.day[daynum].hour);
- gtk_widget_set_sensitive(w, TRUE);
- }
-
- w = lookup_widget(config_dialog, day_m[daynum]);
- if(gtk_toggle_button_get_active(togglebutton) == TRUE)
- {
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), alarm_conf.default_min);
- gtk_widget_set_sensitive(w, FALSE);
- }
- else
- {
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), alarm_conf.day[daynum].min);
- gtk_widget_set_sensitive(w, TRUE);
- }
-}
-
-void on_sun_def_toggled(GtkToggleButton *togglebutton, gpointer user_data)
-{
- on_day_def_toggled(togglebutton, user_data, 0);
-}
-
-void on_mon_def_toggled(GtkToggleButton *togglebutton, gpointer user_data)
-{
- on_day_def_toggled(togglebutton, user_data, 1);
-}
-
-void on_tue_def_toggled(GtkToggleButton *togglebutton, gpointer user_data)
-{
- on_day_def_toggled(togglebutton, user_data, 2);
-}
-
-void on_wed_def_toggled(GtkToggleButton *togglebutton, gpointer user_data)
-{
- on_day_def_toggled(togglebutton, user_data, 3);
-}
-
-void on_thu_def_toggled(GtkToggleButton *togglebutton, gpointer user_data)
-{
- on_day_def_toggled(togglebutton, user_data, 4);
-}
-
-void on_fri_def_toggled(GtkToggleButton *togglebutton, gpointer user_data)
-{
- on_day_def_toggled(togglebutton, user_data, 5);
-}
-
-void on_sat_def_toggled(GtkToggleButton *togglebutton, gpointer user_data)
-{
- on_day_def_toggled(togglebutton, user_data, 6);
-}
-
-/* END: greying things */
-
-void alarm_current_volume(GtkButton *button, gpointer data)
-{
- gint vol;
- GtkAdjustment *adj;
-
- AUDDBG("on_current_button_clicked\n");
-
- aud_drct_get_volume_main(&vol);
-
- adj = gtk_range_get_adjustment(alarm_conf.volume);
- gtk_adjustment_set_value(adj, (gfloat)vol);
-}
-
-/*
- * a thread safe sleeping function -
- * and it even works in solaris (I think)
- */
-static void threadsleep(float x)
-{
- AUDDBG("threadsleep: waiting %f seconds\n", x);
-
- g_usleep((int) ((float) x * (float) 1000000.0));
-
- return;
-}
-
-static inline alarm_thread_t alarm_thread_create(void *(*start_routine)(void *), void *args, unsigned int detach)
-{
- alarm_thread_t thrd;
- pthread_attr_t attr;
-
- pthread_attr_init(&attr);
-
- if(detach != 0)
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
- pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
- pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
-
- thrd.is_valid = (pthread_create(&thrd.tid, &attr, start_routine, args) == 0);
-
- return thrd;
-}
-
-static void *alarm_fade(void *arg)
-{
- fader *vols = (fader *)arg;
- guint i;
- gint v;
- gint inc, diff, adiff;
-
- /* lock */
- pthread_mutex_lock(&fader_lock);
-
- /* slide volume */
- /* the Kaspar Giger way of fading, check the current mixer volume and
- * increment from there so that if you have some other app lowering the
- * volume at the same time, the alarm plugin will not ignore it. If you have
- * some other app increasing the volume, then it could get louder than you expect
- * though - because the loop does not recalculate the difference each time.
- */
-
- /* difference between the 2 volumes */
- diff = vols->end - vols->start;
- adiff = abs(diff);
-
- /* Are we going up or down? */
- if(diff < 0)
- inc = -1;
- else
- inc = 1;
-
- aud_drct_set_volume_main((gint)vols->start);
- //for(i=0;i<(vols->end - vols->start);i++)
- for(i=0;i<adiff;i++)
- {
- //threadsleep((gfloat)fading / (vols->end - vols->start));
- threadsleep((gfloat)fading / (gfloat)adiff);
- aud_drct_get_volume_main(&v);
- aud_drct_set_volume_main(v + inc);
- }
- /* Setting the volume to the end volume sort of defeats the point if having
- * the code in there to allow other apps to control volume too :)
- */
- //aud_drct_set_volume_main((gint)vols->end);
-
- /* and */
- pthread_mutex_unlock(&fader_lock);
-
- AUDDBG("volume = %f%%\n", (gdouble)vols->end);
- return 0;
-}
-
-static void *alarm_stop_thread(void *args)
-{
- gint currvol;
- fader fade_vols;
- alarm_thread_t f;
-
- AUDDBG("alarm_stop_thread\n");
-
-
- /* sleep for however long we are meant to be sleeping for until
- * its time to shut up
- */
- threadsleep(((stop_h * 60) + stop_m) * 60);
-
- AUDDBG("alarm_stop triggered\n");
-
- if (alarm_dialog)
- gtk_widget_destroy(alarm_dialog);
-
- aud_drct_get_volume_main(&currvol),
-
- /* fade back to zero */
- fade_vols.start = currvol;
- fade_vols.end = 0;
-
- /* The fader thread locks the fader_mutex now */
- f = alarm_thread_create(alarm_fade, &fade_vols, 0);
-
- pthread_join(f.tid, NULL);
- aud_drct_stop();
-
- /* might as well set the volume to something higher than zero so we
- * dont confuse the poor people who just woke up and cant work out why
- * theres no music playing when they press the little play button :)
- */
- aud_drct_set_volume_main(currvol);
-
- AUDDBG("alarm_stop done\n");
- return(NULL);
-}
-
-void alarm_stop_cancel(GtkWidget *w, gpointer data)
-{
- AUDDBG("alarm_stop_cancel\n");
- if (pthread_cancel(stop.tid) == 0)
- stop.is_valid = FALSE;
-}
-
-/* the main alarm thread */
-static gboolean alarm_timeout (void * unused)
-{
- struct tm *currtime;
- time_t timenow;
- guint today;
-
- AUDDBG("Getting time\n");
- timenow = time(NULL);
- currtime = localtime(&timenow);
- today = currtime->tm_wday;
- AUDDBG("Today is %d\n", today);
-
- /* already went off? */
- if (timenow < play_start + 60)
- return TRUE;
-
- if(alarm_conf.day[today].flags & ALARM_OFF)
- return TRUE;
- else
- {
- /* set the alarm_h and alarm_m for today, if not default */
- if(!(alarm_conf.day[today].flags & ALARM_DEFAULT))
- {
- alarm_h = alarm_conf.day[today].hour;
- alarm_m = alarm_conf.day[today].min;
- }
- else
- {
- alarm_h = alarm_conf.default_hour;
- alarm_m = alarm_conf.default_min;
- }
- }
-
- AUDDBG("Alarm time is %d:%d (def: %d:%d)\n", alarm_h, alarm_m,
- alarm_conf.default_hour, alarm_conf.default_min);
-
- AUDDBG("Checking time (%d:%d)\n", currtime->tm_hour, currtime->tm_min);
- if((currtime->tm_hour != alarm_h) || (currtime->tm_min != alarm_m))
- return TRUE;
-
- if(cmd_on == TRUE)
- {
- char * cmdstr = aud_get_str ("alarm", "cmdstr");
- AUDDBG("Executing %s, cmd_on is true\n", cmdstr);
- if(system(cmdstr) == -1)
- AUDDBG("Executing %s failed\n",cmdstr);
- str_unref (cmdstr);
- }
-
- bool_t started = FALSE;
-
- char * playlist = aud_get_str ("alarm", "playlist");
- if (playlist[0])
- {
- aud_drct_pl_open (playlist);
- started = TRUE;
- }
- str_unref (playlist);
-
- if(fading)
- {
- fader fade_vols;
-
- AUDDBG("Fading is true\n");
- aud_drct_set_volume_main(quietvol);
-
- /* start playing */
- play_start = time(NULL);
-
- if (! started)
- aud_drct_play ();
-
- /* fade volume */
- fade_vols.start = quietvol;
- fade_vols.end = volume;
-
- //alarm_fade(quietvol, volume);
- alarm_thread_create(alarm_fade, &fade_vols, 0);
- }
- else
- {
- /* no fading */
-
- /* set volume */
- aud_drct_set_volume_main(volume);
-
- /* start playing */
- play_start = time(NULL);
- aud_drct_play();
- }
-
- if(alarm_conf.reminder_on == TRUE)
- {
- char * reminder_msg = aud_get_str ("alarm", "reminder_msg");
- GtkWidget *reminder_dialog;
- AUDDBG("Showing reminder '%s'\n", reminder_msg);
-
- reminder_dialog = (GtkWidget*) create_reminder_dialog(reminder_msg);
- gtk_widget_show_all(reminder_dialog);
- str_unref (reminder_msg);
- }
-
- /* bring up the wakeup call dialog if stop_on is set TRUE, this
- * has been moved to after making Audacious play so that it doesnt
- * get in the way for people with manual window placement turned on
- *
- * this means that the dialog doesnt get shown until the volume has
- * finished fading though !, so thats something else to fix
- */
- if(stop_on == TRUE)
- {
- alarm_dialog = create_alarm_dialog();
-
- AUDDBG("now starting stop thread\n");
- stop = alarm_thread_create(alarm_stop_thread, NULL, 0);
- AUDDBG("Created wakeup dialog and started stop thread\n");
- }
-
- return TRUE;
-}
-
-/*
- * initialization
- * opens the config file and reads the value, creates a new
- * config in memory if the file doesnt exist and sets default vals
- */
-static gboolean alarm_init (void)
-{
- AUDDBG("alarm_init\n");
-
- alarm_read_config();
-
- timeout_source = g_timeout_add_seconds (10, alarm_timeout, NULL);
-
- aud_plugin_menu_add (AUD_MENU_MAIN, alarm_configure, _("Set Alarm ..."), "appointment-new");
-
- return TRUE;
-}
-
-/*
- * kill the main thread
- */
-static void alarm_cleanup(void)
-{
- AUDDBG("alarm_cleanup\n");
-
- aud_plugin_menu_remove (AUD_MENU_MAIN, alarm_configure);
-
- if (timeout_source)
- {
- g_source_remove (timeout_source);
- timeout_source = 0;
- }
-
- if (stop.is_valid)
- {
- pthread_cancel(stop.tid);
- stop.is_valid = FALSE;
- }
-}
-
-static const char alarm_about[] =
- N_("A plugin that can be used to start playing at a certain time.\n\n"
- "Originally written by Adam Feakin and Daniel Stodden.");
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("Alarm"),
- .domain = PACKAGE,
- .about_text = alarm_about,
- .init = alarm_init,
- .configure = alarm_configure,
- .cleanup = alarm_cleanup,
-)
diff --git a/src/alarm/alarm.cc b/src/alarm/alarm.cc
new file mode 100644
index 000000000000..80a97b3ab8a2
--- /dev/null
+++ b/src/alarm/alarm.cc
@@ -0,0 +1,822 @@
+/*
+ * Copyright (C) Adam Feakin <adamf at snika.uklinux.net>
+ *
+ * modified by Daniel Stodden <stodden at in.tum.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include <pthread.h>
+#include <assert.h>
+#include <math.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/plugins.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/runtime.h>
+
+#include <libaudgui/libaudgui.h>
+#include <libaudgui/libaudgui-gtk.h>
+
+#include "alarm.h"
+#include "interface.h"
+#include "callbacks.h"
+
+class AlarmPlugin : public GeneralPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Alarm"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ constexpr AlarmPlugin () : GeneralPlugin (info, false) {}
+
+ bool init ();
+ void cleanup ();
+};
+
+EXPORT AlarmPlugin aud_plugin_instance;
+
+const char * const AlarmPlugin::defaults[] = {
+ /* general */
+ "alarm_h", "6",
+ "alarm_m", "30",
+ "cmd_on", "FALSE",
+ "fading", "60",
+ "quietvol", "25",
+ "reminder_on", "FALSE",
+ "stop_h", "1",
+ "stop_m", "0",
+ "stop_on", "TRUE",
+ "volume", "80",
+
+ /* days */
+ "sun_flags", "3",
+ "sun_h", "6",
+ "sun_m", "30",
+ "mon_flags", "2",
+ "mon_h", "6",
+ "mon_m", "30",
+ "tue_flags", "2",
+ "tue_h", "6",
+ "tue_m", "30",
+ "wed_flags", "2",
+ "wed_h", "6",
+ "wed_m", "30",
+ "thu_flags", "2",
+ "thu_h", "6",
+ "thu_m", "30",
+ "fri_flags", "2",
+ "fri_h", "6",
+ "fri_m", "30",
+ "sat_flags", "2",
+ "sat_h", "6",
+ "sat_m", "30",
+ nullptr};
+
+typedef struct
+{
+ pthread_t tid;
+ volatile gboolean is_valid;
+} alarm_thread_t;
+
+static int timeout_source;
+static time_t play_start;
+
+static alarm_thread_t stop; /* thread id of stop loop */
+static pthread_mutex_t fader_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/* string tokens to allow loops and shorten code */
+static char day_cb[7][7] = {"sun_cb", "mon_cb", "tue_cb",
+ "wed_cb", "thu_cb", "fri_cb", "sat_cb"};
+
+static char day_flags[7][10] = {"sun_flags", "mon_flags", "tue_flags",
+ "wed_flags", "thu_flags", "fri_flags", "sat_flags"};
+
+static char day_h[7][6] = {"sun_h", "mon_h", "tue_h",
+ "wed_h", "thu_h", "fri_h", "sat_h"};
+
+static char day_m[7][6] = {"sun_m", "mon_m", "tue_m",
+ "wed_m", "thu_m", "fri_m", "sat_m"};
+
+static char day_def[7][8] = {"sun_def", "mon_def", "tue_def",
+ "wed_def", "thu_def", "fri_def", "sat_def"};
+
+static struct
+{
+ GtkSpinButton *alarm_h;
+ GtkSpinButton *alarm_m;
+
+ GtkToggleButton *stop_on;
+ GtkSpinButton *stop_h;
+ GtkSpinButton *stop_m;
+
+ GtkRange *volume;
+ GtkRange *quietvol;
+
+ GtkSpinButton *fading;
+
+ GtkEntry *cmdstr;
+ GtkToggleButton *cmd_on;
+
+ GtkEntry *playlist;
+
+ int default_hour;
+ int default_min;
+
+ // array allows looping of days
+ alarmday day[7];
+
+
+ GtkEntry *reminder;
+ GtkToggleButton *reminder_cb;
+ gboolean reminder_on;
+}
+alarm_conf;
+
+static int alarm_h, alarm_m;
+
+static gboolean stop_on;
+static int stop_h, stop_m;
+
+static int volume, quietvol;
+
+static int fading;
+
+static gboolean cmd_on;
+
+static GtkWidget *config_notebook = nullptr;
+static GtkWidget *alarm_dialog = nullptr;
+
+static GtkWidget *lookup_widget(GtkWidget *w, const char *name)
+{
+ GtkWidget * widget = (GtkWidget *) g_object_get_data ((GObject *) w, name);
+ g_return_val_if_fail(widget != nullptr, nullptr);
+
+ return widget;
+}
+
+/*
+ * the callback function that is called when the save button is
+ * pressed saves configuration to ~/.bmp/alarmconfig
+ */
+static void alarm_save(void)
+{
+ int daynum = 0; // used to identify day number
+
+ /*
+ * update the live values and write them out
+ */
+ alarm_h = alarm_conf.default_hour = gtk_spin_button_get_value_as_int (alarm_conf.alarm_h);
+ aud_set_int ("alarm", "alarm_h", alarm_h);
+
+ alarm_m = alarm_conf.default_min = gtk_spin_button_get_value_as_int (alarm_conf.alarm_m);
+ aud_set_int ("alarm", "alarm_m", alarm_m);
+
+ stop_h = gtk_spin_button_get_value_as_int (alarm_conf.stop_h);
+ stop_m = gtk_spin_button_get_value_as_int (alarm_conf.stop_m);
+ stop_on = gtk_toggle_button_get_active (alarm_conf.stop_on);
+
+ /* days of the week */
+ for(; daynum < 7; daynum++)
+ {
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(alarm_conf.day[daynum].cb)))
+ alarm_conf.day[daynum].flags = 0;
+ else
+ alarm_conf.day[daynum].flags = ALARM_OFF;
+
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(alarm_conf.day[daynum].cb_def)))
+ alarm_conf.day[daynum].flags |= ALARM_DEFAULT;
+
+ alarm_conf.day[daynum].hour =
+ gtk_spin_button_get_value_as_int(alarm_conf.day[daynum].spin_hr);
+ alarm_conf.day[daynum].min =
+ gtk_spin_button_get_value_as_int(alarm_conf.day[daynum].spin_min);
+
+ aud_set_int ("alarm", day_flags[daynum], alarm_conf.day[daynum].flags);
+ aud_set_int ("alarm", day_h[daynum], alarm_conf.day[daynum].hour);
+ aud_set_int ("alarm", day_m[daynum], alarm_conf.day[daynum].min);
+ }
+
+ /* END: days of week */
+
+ volume = gtk_range_get_value (alarm_conf.volume);
+ aud_set_int ("alarm", "volume", volume);
+
+ quietvol = gtk_range_get_value (alarm_conf.quietvol);
+ aud_set_int ("alarm", "quietvol", quietvol);
+
+ fading = gtk_spin_button_get_value_as_int (alarm_conf.fading);
+
+ /* write the new values */
+ aud_set_int ("alarm", "stop_h", stop_h);
+ aud_set_int ("alarm", "stop_m", stop_m);
+ aud_set_int ("alarm", "fading", fading);
+ aud_set_bool ("alarm", "stop_on", stop_on);
+
+ char * cmdstr = gtk_editable_get_chars ((GtkEditable *) alarm_conf.cmdstr, 0, -1);
+ aud_set_str ("alarm", "cmdstr", cmdstr);
+ g_free (cmdstr);
+
+ cmd_on = gtk_toggle_button_get_active (alarm_conf.cmd_on);
+ aud_set_bool ("alarm", "cmd_on", cmd_on);
+
+ char * playlist = gtk_editable_get_chars ((GtkEditable *) alarm_conf.playlist, 0, -1);
+ aud_set_str ("alarm", "playlist", playlist);
+ g_free (playlist);
+
+ /* reminder */
+ char * reminder_msg = gtk_editable_get_chars ((GtkEditable *) alarm_conf.reminder, 0, -1);
+ aud_set_str ("alarm", "reminder_msg", reminder_msg);
+ g_free (reminder_msg);
+
+ alarm_conf.reminder_on = gtk_toggle_button_get_active (alarm_conf.reminder_cb);
+ aud_set_bool ("alarm", "reminder_on", alarm_conf.reminder_on);
+}
+
+/*
+ * read the current configuration from the file
+ */
+static void alarm_read_config(void)
+{
+ int daynum = 0; // used for day number
+
+ alarm_h = aud_get_int ("alarm", "alarm_h");
+ alarm_m = aud_get_int ("alarm", "alarm_m");
+
+ /* save them here too */
+ alarm_conf.default_hour = alarm_h;
+ alarm_conf.default_min = alarm_m;
+
+ stop_h = aud_get_int ("alarm", "stop_h");
+ stop_m = aud_get_int ("alarm", "stop_m");
+ stop_on = aud_get_bool ("alarm", "stop_on");
+
+ volume = aud_get_int ("alarm", "volume");
+ quietvol = aud_get_int ("alarm", "quietvol");
+
+ fading = aud_get_int ("alarm", "fading");
+
+ cmd_on = aud_get_bool ("alarm", "cmd_on");
+
+ alarm_conf.reminder_on = aud_get_bool ("alarm", "reminder_on");
+
+ /* day flags and times */
+ for(; daynum < 7; daynum++)
+ {
+ /* read the flags */
+ alarm_conf.day[daynum].flags = aud_get_int ("alarm", day_flags[daynum]);
+
+ /* read the times */
+ alarm_conf.day[daynum].hour = aud_get_int ("alarm", day_h[daynum]);
+ alarm_conf.day[daynum].min = aud_get_int ("alarm", day_m[daynum]);
+ }
+}
+
+/*
+ * displays the configuration window and opens the config file.
+ */
+static void *alarm_make_config_widget(void)
+{
+ int daynum = 0; // used to loop days
+ GtkWidget *w;
+
+ alarm_read_config();
+
+ /*
+ * Create the widgets
+ */
+ config_notebook = create_config_notebook();
+
+ w = lookup_widget(config_notebook, "alarm_h_spin");
+ alarm_conf.alarm_h = GTK_SPIN_BUTTON(w);
+ gtk_spin_button_set_value(alarm_conf.alarm_h, alarm_h);
+
+ w = lookup_widget(config_notebook, "alarm_m_spin");
+ alarm_conf.alarm_m = GTK_SPIN_BUTTON(w);
+ gtk_spin_button_set_value(alarm_conf.alarm_m, alarm_m);
+
+ w = lookup_widget(config_notebook, "stop_h_spin");
+ alarm_conf.stop_h = GTK_SPIN_BUTTON(w);
+ gtk_spin_button_set_value(alarm_conf.stop_h, stop_h);
+
+ w = lookup_widget(config_notebook, "stop_m_spin");
+ alarm_conf.stop_m = GTK_SPIN_BUTTON(w);
+ gtk_spin_button_set_value(alarm_conf.stop_m, stop_m);
+
+ w = lookup_widget(config_notebook, "stop_checkb");
+ alarm_conf.stop_on = GTK_TOGGLE_BUTTON(w);
+ gtk_toggle_button_set_active(alarm_conf.stop_on, stop_on);
+
+ w = lookup_widget(config_notebook, "vol_scale");
+ alarm_conf.volume = GTK_RANGE(w);
+ gtk_range_set_adjustment(alarm_conf.volume,
+ GTK_ADJUSTMENT(gtk_adjustment_new(volume, 0, 100, 1, 5, 0)));
+
+ w = lookup_widget(config_notebook, "quiet_vol_scale");
+ alarm_conf.quietvol = GTK_RANGE(w);
+ gtk_range_set_adjustment(alarm_conf.quietvol,
+ GTK_ADJUSTMENT(gtk_adjustment_new(quietvol, 0, 100, 1, 5, 0)));
+
+ /* days of week */
+ for(; daynum < 7; daynum++)
+ {
+ w = lookup_widget(config_notebook, day_cb[daynum]);
+ alarm_conf.day[daynum].cb = GTK_CHECK_BUTTON(w);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(alarm_conf.day[daynum].cb),
+ !(alarm_conf.day[daynum].flags & ALARM_OFF));
+
+ w = lookup_widget(config_notebook, day_def[daynum]);
+ alarm_conf.day[daynum].cb_def = GTK_CHECK_BUTTON(w);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(alarm_conf.day[daynum].cb_def),
+ alarm_conf.day[daynum].flags & ALARM_DEFAULT);
+
+
+ /* Changed to show default time instead of set time when ALARM_DEFAULT set,
+ * as suggested by Mark Brown
+ */
+/* w = lookup_widget(config_dialog, day_h[daynum]);
+ alarm_conf.day[daynum].spin_hr = GTK_SPIN_BUTTON(w);
+ gtk_spin_button_set_value(alarm_conf.day[daynum].spin_hr, alarm_conf.day[daynum].hour);
+
+ w = lookup_widget(config_dialog, day_m[daynum]);
+ alarm_conf.day[daynum].spin_min = GTK_SPIN_BUTTON(w);
+ gtk_spin_button_set_value(alarm_conf.day[daynum].spin_min, alarm_conf.day[daynum].min);
+*/
+ if(alarm_conf.day[daynum].flags & ALARM_DEFAULT)
+ {
+ w = lookup_widget(config_notebook, day_h[daynum]);
+ alarm_conf.day[daynum].spin_hr = GTK_SPIN_BUTTON(w);
+ gtk_spin_button_set_value(alarm_conf.day[daynum].spin_hr, alarm_conf.default_hour);
+
+ w = lookup_widget(config_notebook, day_m[daynum]);
+ alarm_conf.day[daynum].spin_min = GTK_SPIN_BUTTON(w);
+ gtk_spin_button_set_value(alarm_conf.day[daynum].spin_min, alarm_conf.default_min);
+
+ gtk_widget_set_sensitive((GtkWidget *)alarm_conf.day[daynum].spin_hr, FALSE);
+ gtk_widget_set_sensitive((GtkWidget *)alarm_conf.day[daynum].spin_min, FALSE);
+ }
+ else
+ {
+ w = lookup_widget(config_notebook, day_h[daynum]);
+ alarm_conf.day[daynum].spin_hr = GTK_SPIN_BUTTON(w);
+ gtk_spin_button_set_value(alarm_conf.day[daynum].spin_hr, alarm_conf.day[daynum].hour);
+
+ w = lookup_widget(config_notebook, day_m[daynum]);
+ alarm_conf.day[daynum].spin_min = GTK_SPIN_BUTTON(w);
+ gtk_spin_button_set_value(alarm_conf.day[daynum].spin_min, alarm_conf.day[daynum].min);
+
+ gtk_widget_set_sensitive((GtkWidget *)alarm_conf.day[daynum].spin_hr, TRUE);
+ gtk_widget_set_sensitive((GtkWidget *)alarm_conf.day[daynum].spin_min, TRUE);
+ }
+ }
+
+ /* END: days of week */
+
+ w = lookup_widget(config_notebook,"fading_spin");
+ alarm_conf.fading = GTK_SPIN_BUTTON(w);
+ gtk_spin_button_set_value(alarm_conf.fading, fading);
+
+ String cmdstr = aud_get_str ("alarm", "cmdstr");
+ w = lookup_widget(config_notebook, "cmd_entry");
+ alarm_conf.cmdstr = GTK_ENTRY(w);
+ gtk_entry_set_text(alarm_conf.cmdstr, cmdstr);
+
+ w = lookup_widget(config_notebook, "cmd_checkb");
+ alarm_conf.cmd_on = GTK_TOGGLE_BUTTON(w);
+ gtk_toggle_button_set_active(alarm_conf.cmd_on, cmd_on);
+
+ String playlist = aud_get_str ("alarm", "playlist");
+ w = lookup_widget(config_notebook, "playlist");
+ alarm_conf.playlist = GTK_ENTRY(w);
+ gtk_entry_set_text(alarm_conf.playlist, playlist);
+
+ String reminder_msg = aud_get_str ("alarm", "reminder_msg");
+ w = lookup_widget(config_notebook, "reminder_text");
+ alarm_conf.reminder = GTK_ENTRY(w);
+ gtk_entry_set_text(alarm_conf.reminder, reminder_msg);
+
+ w = lookup_widget(config_notebook, "reminder_cb");
+ alarm_conf.reminder_cb = GTK_TOGGLE_BUTTON(w);
+ gtk_toggle_button_set_active(alarm_conf.reminder_cb, alarm_conf.reminder_on);
+
+ AUDDBG("END alarm_configure\n");
+
+ return config_notebook;
+}
+
+/* functions for greying out the time for days */
+static void on_day_def_toggled(GtkToggleButton *togglebutton, void * user_data, int daynum)
+{
+ GtkWidget *w;
+
+ /* change the time shown too */
+ w = lookup_widget(config_notebook, day_h[daynum]);
+ if(w == nullptr)
+ return;
+
+ if(gtk_toggle_button_get_active(togglebutton) == TRUE)
+ {
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), alarm_conf.default_hour);
+ gtk_widget_set_sensitive(w, FALSE);
+ }
+ else
+ {
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), alarm_conf.day[daynum].hour);
+ gtk_widget_set_sensitive(w, TRUE);
+ }
+
+ w = lookup_widget(config_notebook, day_m[daynum]);
+ if(gtk_toggle_button_get_active(togglebutton) == TRUE)
+ {
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), alarm_conf.default_min);
+ gtk_widget_set_sensitive(w, FALSE);
+ }
+ else
+ {
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), alarm_conf.day[daynum].min);
+ gtk_widget_set_sensitive(w, TRUE);
+ }
+}
+
+void on_sun_def_toggled(GtkToggleButton *togglebutton, void * user_data)
+{
+ on_day_def_toggled(togglebutton, user_data, 0);
+}
+
+void on_mon_def_toggled(GtkToggleButton *togglebutton, void * user_data)
+{
+ on_day_def_toggled(togglebutton, user_data, 1);
+}
+
+void on_tue_def_toggled(GtkToggleButton *togglebutton, void * user_data)
+{
+ on_day_def_toggled(togglebutton, user_data, 2);
+}
+
+void on_wed_def_toggled(GtkToggleButton *togglebutton, void * user_data)
+{
+ on_day_def_toggled(togglebutton, user_data, 3);
+}
+
+void on_thu_def_toggled(GtkToggleButton *togglebutton, void * user_data)
+{
+ on_day_def_toggled(togglebutton, user_data, 4);
+}
+
+void on_fri_def_toggled(GtkToggleButton *togglebutton, void * user_data)
+{
+ on_day_def_toggled(togglebutton, user_data, 5);
+}
+
+void on_sat_def_toggled(GtkToggleButton *togglebutton, void * user_data)
+{
+ on_day_def_toggled(togglebutton, user_data, 6);
+}
+
+/* END: greying things */
+
+void alarm_current_volume(GtkButton *button, void * data)
+{
+ GtkAdjustment *adj;
+
+ AUDDBG("on_current_button_clicked\n");
+
+ adj = gtk_range_get_adjustment(alarm_conf.volume);
+ gtk_adjustment_set_value(adj, aud_drct_get_volume_main());
+}
+
+/*
+ * a thread safe sleeping function -
+ * and it even works in solaris (I think)
+ */
+static void threadsleep(float x)
+{
+ AUDDBG("threadsleep: waiting %f seconds\n", x);
+
+ g_usleep((int) ((float) x * (float) 1000000.0));
+
+ return;
+}
+
+static inline alarm_thread_t alarm_thread_create(void *(*start_routine)(void *), void *args, unsigned int detach)
+{
+ alarm_thread_t thrd;
+ pthread_attr_t attr;
+
+ pthread_attr_init(&attr);
+
+ if(detach != 0)
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+ pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
+ pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
+
+ thrd.is_valid = (pthread_create(&thrd.tid, &attr, start_routine, args) == 0);
+
+ return thrd;
+}
+
+static void *alarm_fade(void *arg)
+{
+ fader *vols = (fader *)arg;
+ int inc, diff, adiff;
+
+ /* lock */
+ pthread_mutex_lock(&fader_lock);
+
+ /* slide volume */
+ /* the Kaspar Giger way of fading, check the current mixer volume and
+ * increment from there so that if you have some other app lowering the
+ * volume at the same time, the alarm plugin will not ignore it. If you have
+ * some other app increasing the volume, then it could get louder than you expect
+ * though - because the loop does not recalculate the difference each time.
+ */
+
+ /* difference between the 2 volumes */
+ diff = vols->end - vols->start;
+ adiff = abs(diff);
+
+ /* Are we going up or down? */
+ if(diff < 0)
+ inc = -1;
+ else
+ inc = 1;
+
+ aud_drct_set_volume_main((int)vols->start);
+
+ for (int i = 0; i < adiff; i ++)
+ {
+ threadsleep((float)fading / (float)adiff);
+ aud_drct_set_volume_main(aud_drct_get_volume_main() + inc);
+ }
+ /* Setting the volume to the end volume sort of defeats the point if having
+ * the code in there to allow other apps to control volume too :)
+ */
+ //aud_drct_set_volume_main((int)vols->end);
+
+ /* and */
+ pthread_mutex_unlock(&fader_lock);
+
+ AUDDBG("volume = %f%%\n", (double)vols->end);
+ return 0;
+}
+
+static void *alarm_stop_thread(void *args)
+{
+ int currvol;
+ fader fade_vols;
+ alarm_thread_t f;
+
+ AUDDBG("alarm_stop_thread\n");
+
+
+ /* sleep for however long we are meant to be sleeping for until
+ * its time to shut up
+ */
+ threadsleep(((stop_h * 60) + stop_m) * 60);
+
+ AUDDBG("alarm_stop triggered\n");
+
+ if (alarm_dialog)
+ gtk_widget_destroy(alarm_dialog);
+
+ currvol = aud_drct_get_volume_main(),
+
+ /* fade back to zero */
+ fade_vols.start = currvol;
+ fade_vols.end = 0;
+
+ /* The fader thread locks the fader_mutex now */
+ f = alarm_thread_create(alarm_fade, &fade_vols, 0);
+
+ pthread_join(f.tid, nullptr);
+ aud_drct_stop();
+
+ /* might as well set the volume to something higher than zero so we
+ * dont confuse the poor people who just woke up and cant work out why
+ * theres no music playing when they press the little play button :)
+ */
+ aud_drct_set_volume_main(currvol);
+
+ AUDDBG("alarm_stop done\n");
+ return(nullptr);
+}
+
+void alarm_stop_cancel(GtkWidget *w, void * data)
+{
+ AUDDBG("alarm_stop_cancel\n");
+ if (pthread_cancel(stop.tid) == 0)
+ stop.is_valid = FALSE;
+}
+
+/* the main alarm thread */
+static gboolean alarm_timeout (void * unused)
+{
+ struct tm *currtime;
+ time_t timenow;
+ unsigned today;
+
+ AUDDBG("Getting time\n");
+ timenow = time(nullptr);
+ currtime = localtime(&timenow);
+ today = currtime->tm_wday;
+ AUDDBG("Today is %d\n", today);
+
+ /* already went off? */
+ if (timenow < play_start + 60)
+ return TRUE;
+
+ if(alarm_conf.day[today].flags & ALARM_OFF)
+ return TRUE;
+ else
+ {
+ /* set the alarm_h and alarm_m for today, if not default */
+ if(!(alarm_conf.day[today].flags & ALARM_DEFAULT))
+ {
+ alarm_h = alarm_conf.day[today].hour;
+ alarm_m = alarm_conf.day[today].min;
+ }
+ else
+ {
+ alarm_h = alarm_conf.default_hour;
+ alarm_m = alarm_conf.default_min;
+ }
+ }
+
+ AUDDBG("Alarm time is %d:%d (def: %d:%d)\n", alarm_h, alarm_m,
+ alarm_conf.default_hour, alarm_conf.default_min);
+
+ AUDDBG("Checking time (%d:%d)\n", currtime->tm_hour, currtime->tm_min);
+ if((currtime->tm_hour != alarm_h) || (currtime->tm_min != alarm_m))
+ return TRUE;
+
+ if(cmd_on == TRUE)
+ {
+ String cmdstr = aud_get_str ("alarm", "cmdstr");
+ AUDDBG("Executing %s, cmd_on is true\n", (const char *) cmdstr);
+ if(system(cmdstr) == -1)
+ AUDDBG("Executing %s failed\n", (const char *) cmdstr);
+ }
+
+ gboolean started = FALSE;
+
+ String playlist = aud_get_str ("alarm", "playlist");
+ if (playlist[0])
+ {
+ aud_drct_pl_open (playlist);
+ started = TRUE;
+ }
+
+ if(fading)
+ {
+ fader fade_vols;
+
+ AUDDBG("Fading is true\n");
+ aud_drct_set_volume_main(quietvol);
+
+ /* start playing */
+ play_start = time(nullptr);
+
+ if (! started)
+ aud_drct_play ();
+
+ /* fade volume */
+ fade_vols.start = quietvol;
+ fade_vols.end = volume;
+
+ //alarm_fade(quietvol, volume);
+ alarm_thread_create(alarm_fade, &fade_vols, 0);
+ }
+ else
+ {
+ /* no fading */
+
+ /* set volume */
+ aud_drct_set_volume_main(volume);
+
+ /* start playing */
+ play_start = time(nullptr);
+ aud_drct_play();
+ }
+
+ if(alarm_conf.reminder_on == TRUE)
+ {
+ String reminder_msg = aud_get_str ("alarm", "reminder_msg");
+ GtkWidget *reminder_dialog;
+ AUDDBG("Showing reminder '%s'\n", (const char *) reminder_msg);
+
+ reminder_dialog = (GtkWidget*) create_reminder_dialog(reminder_msg);
+ gtk_widget_show_all(reminder_dialog);
+ }
+
+ /* bring up the wakeup call dialog if stop_on is set TRUE, this
+ * has been moved to after making Audacious play so that it doesnt
+ * get in the way for people with manual window placement turned on
+ *
+ * this means that the dialog doesnt get shown until the volume has
+ * finished fading though !, so thats something else to fix
+ */
+ if(stop_on == TRUE)
+ {
+ alarm_dialog = create_alarm_dialog();
+
+ AUDDBG("now starting stop thread\n");
+ stop = alarm_thread_create(alarm_stop_thread, nullptr, 0);
+ AUDDBG("Created wakeup dialog and started stop thread\n");
+ }
+
+ return TRUE;
+}
+
+static void alarm_configure ()
+{
+ audgui_show_plugin_prefs (aud_plugin_by_header (& aud_plugin_instance));
+}
+
+/*
+ * initialization
+ * opens the config file and reads the value, creates a new
+ * config in memory if the file doesnt exist and sets default vals
+ */
+bool AlarmPlugin::init ()
+{
+ AUDDBG("alarm_init\n");
+
+ aud_config_set_defaults ("alarm", defaults);
+
+ alarm_read_config();
+
+ timeout_source = g_timeout_add_seconds (10, alarm_timeout, nullptr);
+
+ aud_plugin_menu_add (AudMenuID::Main, alarm_configure, _("Set Alarm ..."), "appointment-new");
+
+ return true;
+}
+
+/*
+ * kill the main thread
+ */
+void AlarmPlugin::cleanup ()
+{
+ AUDDBG("alarm_cleanup\n");
+
+ aud_plugin_menu_remove (AudMenuID::Main, alarm_configure);
+
+ if (timeout_source)
+ {
+ g_source_remove (timeout_source);
+ timeout_source = 0;
+ }
+
+ if (stop.is_valid)
+ {
+ pthread_cancel(stop.tid);
+ stop.is_valid = FALSE;
+ }
+}
+
+const char AlarmPlugin::about[] =
+ N_("A plugin that can be used to start playing at a certain time.\n\n"
+ "Originally written by Adam Feakin and Daniel Stodden.");
+
+const PreferencesWidget AlarmPlugin::widgets[] = {
+ WidgetCustomGTK (alarm_make_config_widget)
+};
+
+const PluginPreferences AlarmPlugin::prefs = {
+ {widgets},
+ nullptr, // init
+ alarm_save,
+ nullptr // cleanup
+};
diff --git a/src/alarm/alarm.h b/src/alarm/alarm.h
index 2bd08c98e855..cbfd5fd70b73 100644
--- a/src/alarm/alarm.h
+++ b/src/alarm/alarm.h
@@ -28,7 +28,7 @@ typedef struct AlarmDay {
typedef struct Fader {
- guint start, end;
+ unsigned start, end;
} fader;
diff --git a/src/alarm/callbacks.h b/src/alarm/callbacks.h
index 44eae137d766..823bb8d1277b 100644
--- a/src/alarm/callbacks.h
+++ b/src/alarm/callbacks.h
@@ -3,24 +3,22 @@
#include <gtk/gtk.h>
-void alarm_save (void);
+void alarm_current_volume (GtkButton *button, void * data);
-void alarm_current_volume (GtkButton *button, gpointer data);
+void alarm_stop_cancel (GtkWidget *widget, void * data);
-void alarm_stop_cancel (GtkWidget *widget, gpointer data);
+void on_mon_def_toggled (GtkToggleButton *togglebutton, void * data);
-void on_mon_def_toggled (GtkToggleButton *togglebutton, gpointer data);
+void on_tue_def_toggled (GtkToggleButton *togglebutton, void * data);
-void on_tue_def_toggled (GtkToggleButton *togglebutton, gpointer data);
+void on_wed_def_toggled (GtkToggleButton *togglebutton, void * data);
-void on_wed_def_toggled (GtkToggleButton *togglebutton, gpointer data);
+void on_thu_def_toggled (GtkToggleButton *togglebutton, void * data);
-void on_thu_def_toggled (GtkToggleButton *togglebutton, gpointer data);
+void on_fri_def_toggled (GtkToggleButton *togglebutton, void * data);
-void on_fri_def_toggled (GtkToggleButton *togglebutton, gpointer data);
+void on_sat_def_toggled (GtkToggleButton *togglebutton, void * data);
-void on_sat_def_toggled (GtkToggleButton *togglebutton, gpointer data);
-
-void on_sun_def_toggled (GtkToggleButton *togglebutton, gpointer data);
+void on_sun_def_toggled (GtkToggleButton *togglebutton, void * data);
#endif
diff --git a/src/alarm/interface.c b/src/alarm/interface.c
deleted file mode 100644
index 897131ed65c2..000000000000
--- a/src/alarm/interface.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * interface.c
- * Copyright 2012 Thomas Lange
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <gtk/gtk.h>
-#include <audacious/i18n.h>
-#include <libaudgui/libaudgui.h>
-
-#include "callbacks.h"
-
-#if GTK_CHECK_VERSION (3, 12, 0)
- #define gtk_widget_set_margin_right(w, m) gtk_widget_set_margin_end(w, m)
-#endif
-
-const gchar *help[] =
-{
- N_("Time\n"
- " Alarm at:\n"
- " The time for the alarm to come on.\n\n"
-
- " Quiet after:\n"
- " Stop alarm after this amount of time.\n"
- " (if the wakeup dialog is not closed)\n\n\n"
-
- "Days\n"
- " Day:\n"
- " Select the days for the alarm to activate.\n\n"
-
- " Time:\n"
- " Choose the time for the alarm on each day,\n"
- " or select the toggle button to use the default\n"
- " time.\n\n\n"),
-
- N_("Volume\n"
- " Fading:\n"
- " Fade the volume up to the chosen volume\n"
- " for this amount of time.\n\n"
-
- " Start at:\n"
- " Start fading from this volume.\n\n"
-
- " Final:\n"
- " The volume to stop fading at. If the fading\n"
- " time is 0 then set volume to this and start\n"
- " playing.\n\n\n"
-
- "Options:\n"
- " Additional Command:\n"
- " Run this command at the alarm time.\n\n"),
-
- N_(" Playlist:\n"
- " Load this playlist. If no playlist\n"
- " is given, the current one will be used.\n"
- " The URL of an mp3/ogg stream\n"
- " can also be entered here.\n\n"
-
- " Reminder:\n"
- " Display a reminder when the alarm goes off.\n"
- " Type the reminder in the box and turn on the\n"
- " toggle button if you want it to be shown."),
-
- NULL
-};
-
-GtkWidget *create_alarm_dialog (void)
-{
- GtkWidget *alarm_dialog;
-
- alarm_dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, _("This is your wakeup call."));
- gtk_window_set_title (GTK_WINDOW (alarm_dialog), _("Alarm"));
-
- g_signal_connect (alarm_dialog, "response",
- G_CALLBACK (alarm_stop_cancel), NULL);
- g_signal_connect_swapped (alarm_dialog, "response",
- G_CALLBACK (gtk_widget_destroy), alarm_dialog);
-
- gtk_widget_show_all (alarm_dialog);
-
- return alarm_dialog;
-}
-
-GtkWidget *create_reminder_dialog (const gchar *reminder_msg)
-{
- GtkWidget *reminder_dialog;
-
- reminder_dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, _("Your reminder for today is..."));
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (reminder_dialog), "%s", reminder_msg);
- gtk_window_set_title (GTK_WINDOW (reminder_dialog), _("Reminder"));
-
- g_signal_connect_swapped (reminder_dialog, "response",
- G_CALLBACK (gtk_widget_destroy), reminder_dialog);
-
- return reminder_dialog;
-}
-
-static void file_set_cb (GtkFileChooserButton *button, gpointer entry)
-{
- gchar *uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (button));
- gtk_entry_set_text (GTK_ENTRY (entry), uri);
- g_free (uri);
-}
-
-static void config_dialog_response (GtkWidget *dialog, gint response)
-{
- if (response == GTK_RESPONSE_OK)
- alarm_save ();
-
- gtk_widget_destroy (dialog);
-}
-
-GtkWidget *create_config_dialog (void)
-{
- /* General */
- GtkWidget *config_dialog, *content_area, *notebook;
- GtkWidget *vbox, *hbox, *label, *frame, *grid;
- GtkAdjustment *adjustment;
-
- /* Page 1 */
- GtkWidget *alarm_h_spin, *alarm_m_spin;
- GtkWidget *stop_checkb, *stop_h_spin, *stop_m_spin;
-
- /* Page 2 */
- gint i, j;
- GtkWidget *checkbutton;
- GtkWidget *widget[21];
-
- const gchar *weekdays[] = { _("Monday"), _("Tuesday"), _("Wednesday"),
- _("Thursday"), _("Friday"), _("Saturday"), _("Sunday") };
-
- const gchar *day_cb[] = { "mon_cb", "tue_cb", "wed_cb", "thu_cb",
- "fri_cb", "sat_cb", "sun_cb" };
-
- const gchar *day_def[] = { "mon_def", "tue_def", "wed_def", "thu_def",
- "fri_def", "sat_def", "sun_def", };
-
- const gchar *day_h[] = { "mon_h", "tue_h", "wed_h", "thu_h",
- "fri_h", "sat_h", "sun_h" };
-
- const gchar *day_m[] = { "mon_m", "tue_m", "wed_m", "thu_m",
- "fri_m", "sat_m", "sun_m" };
-
- const GCallback cb_def[] = { G_CALLBACK (on_mon_def_toggled), G_CALLBACK (on_tue_def_toggled),
- G_CALLBACK (on_wed_def_toggled), G_CALLBACK (on_thu_def_toggled),
- G_CALLBACK (on_fri_def_toggled), G_CALLBACK (on_sat_def_toggled),
- G_CALLBACK (on_sun_def_toggled) };
-
- /* Page 3 */
- GtkWidget *vbox2, *hbox2;
- GtkWidget *fading_spin, *quiet_vol_scale, *vol_scale, *separator, *current_button;
-
- /* Page 4 */
- GtkWidget *cmd_entry, *playlist_entry, *reminder_text;
- GtkWidget *cmd_checkb, *reminder_checkb, *file_chooser_button;
-
- /* Page 5 */
- GtkWidget *view, *scrolled_window;
- GtkTextBuffer *text_buffer;
- gchar *help_text;
-
-
- /* General */
- config_dialog = gtk_dialog_new_with_buttons (_("Alarm Settings"), NULL, 0,
- _("_OK"), GTK_RESPONSE_OK, _("_Cancel"), GTK_RESPONSE_CANCEL, NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (config_dialog), GTK_RESPONSE_OK);
- content_area = gtk_dialog_get_content_area (GTK_DIALOG (config_dialog));
- notebook = gtk_notebook_new ();
- gtk_box_pack_start (GTK_BOX (content_area), notebook, TRUE, TRUE, 0);
-
-
- /* Page 1 */
- frame = gtk_frame_new (_("Time"));
- gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
- grid = gtk_grid_new ();
- gtk_grid_set_column_spacing (GTK_GRID (grid), 3);
- gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
- gtk_container_set_border_width (GTK_CONTAINER (grid), 5);
-
- label = gtk_label_new (_("Alarm at (default):"));
- gtk_widget_set_margin_right (label, 10);
- gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
-
- adjustment = gtk_adjustment_new (6, 0, 23, 1, 10, 0);
- alarm_h_spin = gtk_spin_button_new (adjustment, 1, 0);
- g_object_set_data (G_OBJECT (config_dialog), "alarm_h_spin", alarm_h_spin);
- gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (alarm_h_spin), GTK_UPDATE_IF_VALID);
- gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (alarm_h_spin), TRUE);
- gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (alarm_h_spin), TRUE);
- gtk_grid_attach (GTK_GRID (grid), alarm_h_spin, 1, 0, 1, 1);
-
- label = gtk_label_new (":");
- gtk_grid_attach (GTK_GRID (grid), label, 2, 0, 1, 1);
-
- adjustment = gtk_adjustment_new (30, 0, 59, 1, 10, 0);
- alarm_m_spin = gtk_spin_button_new (adjustment, 1, 0);
- g_object_set_data (G_OBJECT (config_dialog), "alarm_m_spin", alarm_m_spin);
- gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (alarm_m_spin), GTK_UPDATE_IF_VALID);
- gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (alarm_m_spin), TRUE);
- gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (alarm_m_spin), TRUE);
- gtk_grid_attach (GTK_GRID (grid), alarm_m_spin, 3, 0, 1, 1);
-
- label = gtk_label_new (_("h"));
- gtk_widget_set_halign (label, GTK_ALIGN_START);
- gtk_grid_attach (GTK_GRID (grid), label, 4, 0, 1, 1);
-
- stop_checkb = gtk_check_button_new_with_label (_("Quiet after:"));
- g_object_set_data (G_OBJECT (config_dialog), "stop_checkb", stop_checkb);
- gtk_widget_set_margin_right (stop_checkb, 10);
- gtk_widget_set_valign (stop_checkb, GTK_ALIGN_CENTER);
- gtk_grid_attach (GTK_GRID (grid), stop_checkb, 0, 1, 1, 1);
-
- adjustment = gtk_adjustment_new (0, 0, 100, 1, 10, 0);
- stop_h_spin = gtk_spin_button_new (adjustment, 1, 0);
- g_object_set_data (G_OBJECT (config_dialog), "stop_h_spin", stop_h_spin);
- gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (stop_h_spin), GTK_UPDATE_IF_VALID);
- gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (stop_h_spin), TRUE);
- gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_h_spin), TRUE);
- gtk_grid_attach (GTK_GRID (grid), stop_h_spin, 1, 1, 1, 1);
-
- label = gtk_label_new (_("hours"));
- gtk_widget_set_margin_right (label, 10);
- gtk_grid_attach (GTK_GRID (grid), label, 2, 1, 1, 1);
-
- adjustment = gtk_adjustment_new (0, 0, 59, 1, 10, 0);
- stop_m_spin = gtk_spin_button_new (adjustment, 1, 0);
- g_object_set_data (G_OBJECT (config_dialog), "stop_m_spin", stop_m_spin);
- gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (stop_m_spin), GTK_UPDATE_IF_VALID);
- gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (stop_m_spin), TRUE);
- gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_m_spin), TRUE);
- gtk_grid_attach (GTK_GRID (grid), stop_m_spin, 3, 1, 1, 1);
-
- label = gtk_label_new (_("minutes"));
- gtk_grid_attach (GTK_GRID (grid), label, 4, 1, 1, 1);
- gtk_container_add (GTK_CONTAINER (frame), grid);
-
- label = gtk_label_new (_("Time"));
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
-
-
- /* Page 2 */
- frame = gtk_frame_new (_("Choose the days for the alarm to come on"));
- gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
- grid = gtk_grid_new ();
- gtk_grid_set_column_spacing (GTK_GRID (grid), 15);
- gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
- gtk_container_set_border_width (GTK_CONTAINER (grid), 5);
-
- label = gtk_label_new (_("Day"));
- gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
-
- label = gtk_label_new (_("Time"));
- gtk_grid_attach (GTK_GRID (grid), label, 2, 0, 3, 1);
-
- for (i = 0; i < 7; i ++)
- {
- widget[i] = gtk_check_button_new_with_label (weekdays[i]);
- g_object_set_data (G_OBJECT (config_dialog), day_cb[i], widget[i]);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget[i]), TRUE);
- gtk_widget_set_valign (widget[i], GTK_ALIGN_CENTER);
- gtk_grid_attach (GTK_GRID (grid), widget[i], 0, i + 1, 1, 1);
- }
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget[6]), FALSE);
-
- for (i = 0; i < 7; i ++)
- {
- checkbutton = gtk_check_button_new_with_label (_("Default"));
- g_object_set_data (G_OBJECT (config_dialog), day_def[i], checkbutton);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), TRUE);
- gtk_widget_set_valign (checkbutton, GTK_ALIGN_CENTER);
- g_signal_connect (checkbutton, "toggled", G_CALLBACK (cb_def[i]), NULL);
- gtk_grid_attach (GTK_GRID (grid), checkbutton, 1, i + 1, 1, 1);
- }
-
- for (i = 7, j = 0; i < 14; i ++, j ++)
- {
- adjustment = gtk_adjustment_new (6, 0, 23, 1, 10, 0);
- widget[i] = gtk_spin_button_new (adjustment, 1, 0);
- g_object_set_data (G_OBJECT (config_dialog), day_h[j], widget[i]);
- gtk_grid_attach (GTK_GRID (grid), widget[i], 2, j + 1, 1, 1);
- }
-
- for (i = 0; i < 7; i ++)
- {
- label = gtk_label_new (":");
- gtk_grid_attach (GTK_GRID (grid), label, 3, i + 1, 1, 1);
- }
-
- for (i = 14, j = 0; i < 21; i ++, j ++)
- {
- adjustment = gtk_adjustment_new (30, 0, 59, 1, 10, 0);
- widget[i] = gtk_spin_button_new (adjustment, 1, 0);
- g_object_set_data (G_OBJECT (config_dialog), day_m[j], widget[i]);
- gtk_grid_attach (GTK_GRID (grid), widget[i], 4, j + 1, 1, 1);
- }
-
- label = gtk_label_new (_("Days"));
- gtk_container_add (GTK_CONTAINER (frame), grid);
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
-
-
- /* Page 3 */
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-
- frame = gtk_frame_new (_("Fading"));
- gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
- adjustment = gtk_adjustment_new (120, 0, 3600, 1, 10, 0);
- fading_spin = gtk_spin_button_new (adjustment, 1, 0);
- g_object_set_data (G_OBJECT (config_dialog), "fading_spin", fading_spin);
- gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (fading_spin), TRUE);
- gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (fading_spin), GTK_UPDATE_IF_VALID);
- label = gtk_label_new (_("seconds"));
-
- gtk_container_add (GTK_CONTAINER (hbox), fading_spin);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 3);
- gtk_container_add (GTK_CONTAINER (frame), hbox);
- gtk_container_add (GTK_CONTAINER (vbox), frame);
-
- frame = gtk_frame_new (_("Volume"));
- vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
- gtk_container_set_border_width (GTK_CONTAINER (vbox2), 8);
-
- label = gtk_label_new (_("Start at"));
- gtk_widget_set_margin_bottom (label, 2);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
- gtk_container_add (GTK_CONTAINER (vbox2), label);
-
- quiet_vol_scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, gtk_adjustment_new (20, 0, 100, 1, 5, 0));
- g_object_set_data (G_OBJECT (config_dialog), "quiet_vol_scale", quiet_vol_scale);
- gtk_scale_set_value_pos (GTK_SCALE (quiet_vol_scale), GTK_POS_RIGHT);
- gtk_scale_set_digits (GTK_SCALE (quiet_vol_scale), 0);
- label = gtk_label_new ("%");
- hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
- gtk_box_pack_start (GTK_BOX (hbox2), quiet_vol_scale, TRUE, TRUE, 0);
- gtk_container_add (GTK_CONTAINER (hbox2), label);
- gtk_container_add (GTK_CONTAINER (vbox2), hbox2);
-
- separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_box_pack_start (GTK_BOX (vbox2), separator, FALSE, FALSE, 10);
-
- label = gtk_label_new (_("Final"));
- gtk_widget_set_margin_bottom (label, 2);
- gtk_widget_set_halign (label, GTK_ALIGN_START);
- gtk_container_add (GTK_CONTAINER (vbox2), label);
-
- vol_scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, gtk_adjustment_new (80, 0, 100, 1, 5, 0));
- g_object_set_data (G_OBJECT (config_dialog), "vol_scale", vol_scale);
- gtk_scale_set_value_pos (GTK_SCALE (vol_scale), GTK_POS_RIGHT);
- gtk_scale_set_digits (GTK_SCALE (vol_scale), 0);
- label = gtk_label_new ("%");
- hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
- gtk_box_pack_start (GTK_BOX (hbox2), vol_scale, TRUE, TRUE, 0);
- gtk_container_add (GTK_CONTAINER (hbox2), label);
- gtk_container_add (GTK_CONTAINER (vbox2), hbox2);
-
- current_button = gtk_button_new_with_label (_("Current"));
- gtk_widget_set_margin_top (current_button, 10);
- gtk_widget_set_halign (current_button, GTK_ALIGN_END);
- g_signal_connect (current_button, "clicked", G_CALLBACK (alarm_current_volume), NULL);
- gtk_container_add (GTK_CONTAINER (vbox2), current_button);
-
- gtk_container_add (GTK_CONTAINER (frame), vbox2);
- gtk_container_add (GTK_CONTAINER (vbox), frame);
-
- label = gtk_label_new (_("Volume"));
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
-
-
- /* Page 4 */
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- frame = gtk_frame_new (_("Additional Command"));
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
- cmd_entry = gtk_entry_new ();
- g_object_set_data (G_OBJECT (config_dialog), "cmd_entry", cmd_entry);
- cmd_checkb = gtk_check_button_new_with_label (_("enable"));
- g_object_set_data (G_OBJECT (config_dialog), "cmd_checkb", cmd_checkb);
- gtk_box_pack_start (GTK_BOX (hbox), cmd_entry, TRUE, TRUE, 0);
- gtk_container_add (GTK_CONTAINER (hbox), cmd_checkb);
- gtk_container_add (GTK_CONTAINER (frame), hbox);
- gtk_container_add (GTK_CONTAINER (vbox), frame);
-
- frame = gtk_frame_new (_("Playlist (optional)"));
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
- playlist_entry = gtk_entry_new ();
- g_object_set_data (G_OBJECT (config_dialog), "playlist", playlist_entry);
-
- file_chooser_button = gtk_file_chooser_button_new (_("Select a playlist"), GTK_FILE_CHOOSER_ACTION_OPEN);
- gtk_widget_set_valign (file_chooser_button, GTK_ALIGN_CENTER);
- g_signal_connect (file_chooser_button, "file-set", G_CALLBACK (file_set_cb), playlist_entry);
- gtk_box_pack_start (GTK_BOX (hbox), playlist_entry, TRUE, TRUE, 0);
- gtk_container_add (GTK_CONTAINER (hbox), file_chooser_button);
- gtk_container_add (GTK_CONTAINER (frame), hbox);
- gtk_container_add (GTK_CONTAINER (vbox), frame);
-
- frame = gtk_frame_new (_("Reminder"));
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
- reminder_text = gtk_entry_new ();
- reminder_checkb = gtk_check_button_new_with_label (_("enable"));
- g_object_set_data (G_OBJECT (config_dialog), "reminder_text", reminder_text);
- g_object_set_data (G_OBJECT (config_dialog), "reminder_cb", reminder_checkb);
- gtk_box_pack_start (GTK_BOX (hbox), reminder_text, TRUE, TRUE, 0);
- gtk_container_add (GTK_CONTAINER (hbox), reminder_checkb);
- gtk_container_add (GTK_CONTAINER (frame), hbox);
- gtk_container_add (GTK_CONTAINER (vbox), frame);
-
- label = gtk_label_new (_("Options"));
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
-
-
- /* Page 5 */
- frame = gtk_frame_new (_("What do these options mean?"));
- gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
- view = gtk_text_view_new ();
- gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
- gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
- text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
- help_text = g_strconcat (_(help[0]), _(help[1]), _(help[2]), NULL);
- gtk_text_buffer_set_text (text_buffer, help_text, -1);
- g_free (help_text);
- scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 5);
- gtk_container_add (GTK_CONTAINER (scrolled_window), view);
- gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (scrolled_window));
-
- label = gtk_label_new (_("Help"));
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
-
- g_signal_connect (config_dialog, "response", G_CALLBACK (config_dialog_response), NULL);
-
- gtk_widget_show_all (config_dialog);
-
- return config_dialog;
-}
diff --git a/src/alarm/interface.cc b/src/alarm/interface.cc
new file mode 100644
index 000000000000..a396d9210269
--- /dev/null
+++ b/src/alarm/interface.cc
@@ -0,0 +1,424 @@
+/*
+ * interface.c
+ * Copyright 2012 Thomas Lange
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <gtk/gtk.h>
+#include <libaudcore/i18n.h>
+#include <libaudgui/libaudgui.h>
+
+#include "callbacks.h"
+
+const char *help[] =
+{
+ N_("Time\n"
+ " Alarm at:\n"
+ " The time for the alarm to come on.\n\n"
+
+ " Quiet after:\n"
+ " Stop alarm after this amount of time.\n"
+ " (if the wakeup dialog is not closed)\n\n\n"
+
+ "Days\n"
+ " Day:\n"
+ " Select the days for the alarm to activate.\n\n"
+
+ " Time:\n"
+ " Choose the time for the alarm on each day,\n"
+ " or select the toggle button to use the default\n"
+ " time.\n\n\n"),
+
+ N_("Volume\n"
+ " Fading:\n"
+ " Fade the volume up to the chosen volume\n"
+ " for this amount of time.\n\n"
+
+ " Start at:\n"
+ " Start fading from this volume.\n\n"
+
+ " Final:\n"
+ " The volume to stop fading at. If the fading\n"
+ " time is 0 then set volume to this and start\n"
+ " playing.\n\n\n"
+
+ "Options:\n"
+ " Additional Command:\n"
+ " Run this command at the alarm time.\n\n"),
+
+ N_(" Playlist:\n"
+ " Load this playlist. If no playlist\n"
+ " is given, the current one will be used.\n"
+ " The URL of an mp3/ogg stream\n"
+ " can also be entered here.\n\n"
+
+ " Reminder:\n"
+ " Display a reminder when the alarm goes off.\n"
+ " Type the reminder in the box and turn on the\n"
+ " toggle button if you want it to be shown."),
+
+ nullptr
+};
+
+GtkWidget *create_alarm_dialog (void)
+{
+ GtkWidget *alarm_dialog;
+
+ alarm_dialog = gtk_message_dialog_new (nullptr, GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, _("This is your wakeup call."));
+ gtk_window_set_title (GTK_WINDOW (alarm_dialog), _("Alarm"));
+
+ g_signal_connect (alarm_dialog, "response",
+ G_CALLBACK (alarm_stop_cancel), nullptr);
+ g_signal_connect_swapped (alarm_dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), alarm_dialog);
+
+ gtk_widget_show_all (alarm_dialog);
+
+ return alarm_dialog;
+}
+
+GtkWidget *create_reminder_dialog (const char *reminder_msg)
+{
+ GtkWidget *reminder_dialog;
+
+ reminder_dialog = gtk_message_dialog_new (nullptr, GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, _("Your reminder for today is..."));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (reminder_dialog), "%s", reminder_msg);
+ gtk_window_set_title (GTK_WINDOW (reminder_dialog), _("Reminder"));
+
+ g_signal_connect_swapped (reminder_dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), reminder_dialog);
+
+ return reminder_dialog;
+}
+
+static void file_set_cb (GtkFileChooserButton *button, void * entry)
+{
+ char *uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (button));
+ gtk_entry_set_text (GTK_ENTRY (entry), uri);
+ g_free (uri);
+}
+
+GtkWidget *create_config_notebook (void)
+{
+ /* General */
+ GtkWidget *notebook;
+ GtkWidget *vbox, *hbox, *label, *frame, *grid;
+ GtkAdjustment *adjustment;
+
+ /* Page 1 */
+ GtkWidget *alarm_h_spin, *alarm_m_spin;
+ GtkWidget *stop_checkb, *stop_h_spin, *stop_m_spin;
+
+ /* Page 2 */
+ int i, j;
+ GtkWidget *checkbutton;
+ GtkWidget *widget[21];
+
+ const char *weekdays[] = { _("Monday"), _("Tuesday"), _("Wednesday"),
+ _("Thursday"), _("Friday"), _("Saturday"), _("Sunday") };
+
+ const char *day_cb[] = { "mon_cb", "tue_cb", "wed_cb", "thu_cb",
+ "fri_cb", "sat_cb", "sun_cb" };
+
+ const char *day_def[] = { "mon_def", "tue_def", "wed_def", "thu_def",
+ "fri_def", "sat_def", "sun_def", };
+
+ const char *day_h[] = { "mon_h", "tue_h", "wed_h", "thu_h",
+ "fri_h", "sat_h", "sun_h" };
+
+ const char *day_m[] = { "mon_m", "tue_m", "wed_m", "thu_m",
+ "fri_m", "sat_m", "sun_m" };
+
+ const GCallback cb_def[] = { G_CALLBACK (on_mon_def_toggled), G_CALLBACK (on_tue_def_toggled),
+ G_CALLBACK (on_wed_def_toggled), G_CALLBACK (on_thu_def_toggled),
+ G_CALLBACK (on_fri_def_toggled), G_CALLBACK (on_sat_def_toggled),
+ G_CALLBACK (on_sun_def_toggled) };
+
+ /* Page 3 */
+ GtkWidget *vbox2, *hbox2;
+ GtkWidget *fading_spin, *quiet_vol_scale, *vol_scale, *separator, *current_button;
+
+ /* Page 4 */
+ GtkWidget *cmd_entry, *playlist_entry, *reminder_text;
+ GtkWidget *cmd_checkb, *reminder_checkb, *file_chooser_button;
+
+ /* Page 5 */
+ GtkWidget *view, *scrolled_window;
+ GtkTextBuffer *text_buffer;
+ char *help_text;
+
+
+ /* General */
+ notebook = gtk_notebook_new ();
+
+
+ /* Page 1 */
+ frame = gtk_frame_new (_("Time"));
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
+ grid = gtk_table_new (0, 0, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (grid), 6);
+ gtk_table_set_row_spacings (GTK_TABLE (grid), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (grid), 6);
+
+ label = gtk_label_new (_("Alarm at (default):"));
+ gtk_table_attach (GTK_TABLE (grid), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+
+ adjustment = (GtkAdjustment *) gtk_adjustment_new (6, 0, 23, 1, 10, 0);
+ alarm_h_spin = gtk_spin_button_new (adjustment, 1, 0);
+ g_object_set_data (G_OBJECT (notebook), "alarm_h_spin", alarm_h_spin);
+ gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (alarm_h_spin), GTK_UPDATE_IF_VALID);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (alarm_h_spin), TRUE);
+ gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (alarm_h_spin), TRUE);
+ gtk_table_attach (GTK_TABLE (grid), alarm_h_spin, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+
+ label = gtk_label_new (":");
+ gtk_table_attach (GTK_TABLE (grid), label, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+
+ adjustment = (GtkAdjustment *) gtk_adjustment_new (30, 0, 59, 1, 10, 0);
+ alarm_m_spin = gtk_spin_button_new (adjustment, 1, 0);
+ g_object_set_data (G_OBJECT (notebook), "alarm_m_spin", alarm_m_spin);
+ gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (alarm_m_spin), GTK_UPDATE_IF_VALID);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (alarm_m_spin), TRUE);
+ gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (alarm_m_spin), TRUE);
+ gtk_table_attach (GTK_TABLE (grid), alarm_m_spin, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+
+ label = gtk_label_new (_("h"));
+ gtk_table_attach (GTK_TABLE (grid), label, 4, 5, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+
+ stop_checkb = gtk_check_button_new_with_label (_("Quiet after:"));
+ g_object_set_data (G_OBJECT (notebook), "stop_checkb", stop_checkb);
+ gtk_table_attach (GTK_TABLE (grid), stop_checkb, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+
+ adjustment = (GtkAdjustment *) gtk_adjustment_new (0, 0, 100, 1, 10, 0);
+ stop_h_spin = gtk_spin_button_new (adjustment, 1, 0);
+ g_object_set_data (G_OBJECT (notebook), "stop_h_spin", stop_h_spin);
+ gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (stop_h_spin), GTK_UPDATE_IF_VALID);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (stop_h_spin), TRUE);
+ gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_h_spin), TRUE);
+ gtk_table_attach (GTK_TABLE (grid), stop_h_spin, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+
+ label = gtk_label_new (_("hours"));
+ gtk_table_attach (GTK_TABLE (grid), label, 2, 3, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+
+ adjustment = (GtkAdjustment *) gtk_adjustment_new (0, 0, 59, 1, 10, 0);
+ stop_m_spin = gtk_spin_button_new (adjustment, 1, 0);
+ g_object_set_data (G_OBJECT (notebook), "stop_m_spin", stop_m_spin);
+ gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (stop_m_spin), GTK_UPDATE_IF_VALID);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (stop_m_spin), TRUE);
+ gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (stop_m_spin), TRUE);
+ gtk_table_attach (GTK_TABLE (grid), stop_m_spin, 3, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+
+ label = gtk_label_new (_("minutes"));
+ gtk_table_attach (GTK_TABLE (grid), label, 4, 5, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+ gtk_container_add (GTK_CONTAINER (frame), grid);
+
+ label = gtk_label_new (_("Time"));
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
+
+
+ /* Page 2 */
+ frame = gtk_frame_new (_("Choose the days for the alarm to come on"));
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
+ grid = gtk_table_new (0, 0, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (grid), 6);
+ gtk_table_set_row_spacings (GTK_TABLE (grid), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (grid), 6);
+
+ label = gtk_label_new (_("Day"));
+ gtk_table_attach (GTK_TABLE (grid), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+
+ label = gtk_label_new (_("Time"));
+ gtk_table_attach (GTK_TABLE (grid), label, 2, 5, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+
+ for (i = 0; i < 7; i ++)
+ {
+ widget[i] = gtk_check_button_new_with_label (weekdays[i]);
+ g_object_set_data (G_OBJECT (notebook), day_cb[i], widget[i]);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget[i]), TRUE);
+ gtk_table_attach (GTK_TABLE (grid), widget[i], 0, 1, i + 1, i + 2, GTK_FILL, GTK_FILL, 0, 0);
+ }
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget[6]), FALSE);
+
+ for (i = 0; i < 7; i ++)
+ {
+ checkbutton = gtk_check_button_new_with_label (_("Default"));
+ g_object_set_data (G_OBJECT (notebook), day_def[i], checkbutton);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), TRUE);
+ g_signal_connect (checkbutton, "toggled", G_CALLBACK (cb_def[i]), nullptr);
+ gtk_table_attach (GTK_TABLE (grid), checkbutton, 1, 2, i + 1, i + 2, GTK_FILL, GTK_FILL, 0, 0);
+ }
+
+ for (i = 7, j = 0; i < 14; i ++, j ++)
+ {
+ adjustment = (GtkAdjustment *) gtk_adjustment_new (6, 0, 23, 1, 10, 0);
+ widget[i] = gtk_spin_button_new (adjustment, 1, 0);
+ g_object_set_data (G_OBJECT (notebook), day_h[j], widget[i]);
+ gtk_table_attach (GTK_TABLE (grid), widget[i], 2, 3, j + 1, j + 2, GTK_FILL, GTK_FILL, 0, 0);
+ }
+
+ for (i = 0; i < 7; i ++)
+ {
+ label = gtk_label_new (":");
+ gtk_table_attach (GTK_TABLE (grid), label, 3, 4, i + 1, i + 2, GTK_FILL, GTK_FILL, 0, 0);
+ }
+
+ for (i = 14, j = 0; i < 21; i ++, j ++)
+ {
+ adjustment = (GtkAdjustment *) gtk_adjustment_new (30, 0, 59, 1, 10, 0);
+ widget[i] = gtk_spin_button_new (adjustment, 1, 0);
+ g_object_set_data (G_OBJECT (notebook), day_m[j], widget[i]);
+ gtk_table_attach (GTK_TABLE (grid), widget[i], 4, 5, j + 1, j + 2, GTK_FILL, GTK_FILL, 0, 0);
+ }
+
+ label = gtk_label_new (_("Days"));
+ gtk_container_add (GTK_CONTAINER (frame), grid);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
+
+
+ /* Page 3 */
+ vbox = gtk_vbox_new (FALSE, 6);
+ hbox = gtk_hbox_new (FALSE, 6);
+
+ frame = gtk_frame_new (_("Fading"));
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+ adjustment = (GtkAdjustment *) gtk_adjustment_new (120, 0, 3600, 1, 10, 0);
+ fading_spin = gtk_spin_button_new (adjustment, 1, 0);
+ g_object_set_data (G_OBJECT (notebook), "fading_spin", fading_spin);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (fading_spin), TRUE);
+ gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (fading_spin), GTK_UPDATE_IF_VALID);
+ label = gtk_label_new (_("seconds"));
+
+ gtk_box_pack_start (GTK_BOX (hbox), fading_spin, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+
+ frame = gtk_frame_new (_("Volume"));
+ vbox2 = gtk_vbox_new (FALSE, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox2), 6);
+
+ label = gtk_label_new (_("Start at"));
+ gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
+
+ quiet_vol_scale = gtk_hscale_new ((GtkAdjustment *) gtk_adjustment_new (20, 0, 100, 1, 5, 0));
+ g_object_set_data (G_OBJECT (notebook), "quiet_vol_scale", quiet_vol_scale);
+ gtk_scale_set_value_pos (GTK_SCALE (quiet_vol_scale), GTK_POS_RIGHT);
+ gtk_scale_set_digits (GTK_SCALE (quiet_vol_scale), 0);
+ label = gtk_label_new ("%");
+ hbox2 = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (hbox2), quiet_vol_scale, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0);
+
+ separator = gtk_hseparator_new ();
+ gtk_box_pack_start (GTK_BOX (vbox2), separator, FALSE, FALSE, 0);
+
+ label = gtk_label_new (_("Final"));
+ gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
+
+ vol_scale = gtk_hscale_new ((GtkAdjustment *) gtk_adjustment_new (80, 0, 100, 1, 5, 0));
+ g_object_set_data (G_OBJECT (notebook), "vol_scale", vol_scale);
+ gtk_scale_set_value_pos (GTK_SCALE (vol_scale), GTK_POS_RIGHT);
+ gtk_scale_set_digits (GTK_SCALE (vol_scale), 0);
+ label = gtk_label_new ("%");
+ hbox2 = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (hbox2), vol_scale, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0);
+
+ current_button = gtk_button_new_with_label (_("Current"));
+ g_signal_connect (current_button, "clicked", G_CALLBACK (alarm_current_volume), nullptr);
+ gtk_box_pack_start (GTK_BOX (vbox2), current_button, FALSE, FALSE, 0);
+
+ gtk_container_add (GTK_CONTAINER (frame), vbox2);
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+
+ label = gtk_label_new (_("Volume"));
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
+
+
+ /* Page 4 */
+ vbox = gtk_vbox_new (FALSE, 6);
+ frame = gtk_frame_new (_("Additional Command"));
+ hbox = gtk_hbox_new (FALSE, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+ cmd_entry = gtk_entry_new ();
+ g_object_set_data (G_OBJECT (notebook), "cmd_entry", cmd_entry);
+ cmd_checkb = gtk_check_button_new_with_label (_("enable"));
+ g_object_set_data (G_OBJECT (notebook), "cmd_checkb", cmd_checkb);
+ gtk_box_pack_start (GTK_BOX (hbox), cmd_entry, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), cmd_checkb, FALSE, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+
+ frame = gtk_frame_new (_("Playlist (optional)"));
+ hbox = gtk_hbox_new (FALSE, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+ playlist_entry = gtk_entry_new ();
+ g_object_set_data (G_OBJECT (notebook), "playlist", playlist_entry);
+
+ file_chooser_button = gtk_file_chooser_button_new (_("Select a playlist"), GTK_FILE_CHOOSER_ACTION_OPEN);
+ g_signal_connect (file_chooser_button, "file-set", G_CALLBACK (file_set_cb), playlist_entry);
+ gtk_box_pack_start (GTK_BOX (hbox), playlist_entry, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), file_chooser_button, TRUE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+
+ frame = gtk_frame_new (_("Reminder"));
+ hbox = gtk_hbox_new (FALSE, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+ reminder_text = gtk_entry_new ();
+ reminder_checkb = gtk_check_button_new_with_label (_("enable"));
+ g_object_set_data (G_OBJECT (notebook), "reminder_text", reminder_text);
+ g_object_set_data (G_OBJECT (notebook), "reminder_cb", reminder_checkb);
+ gtk_box_pack_start (GTK_BOX (hbox), reminder_text, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), reminder_checkb, FALSE, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+
+ label = gtk_label_new (_("Options"));
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
+
+
+ /* Page 5 */
+ frame = gtk_frame_new (_("What do these options mean?"));
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
+ view = gtk_text_view_new ();
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
+ gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+ help_text = g_strconcat (_(help[0]), _(help[1]), _(help[2]), nullptr);
+ gtk_text_buffer_set_text (text_buffer, help_text, -1);
+ g_free (help_text);
+ scrolled_window = gtk_scrolled_window_new (nullptr, nullptr);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 6);
+ gtk_container_add (GTK_CONTAINER (scrolled_window), view);
+ gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (scrolled_window));
+
+ label = gtk_label_new (_("Help"));
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
+
+ return notebook;
+}
diff --git a/src/alarm/interface.h b/src/alarm/interface.h
index cb76cb94daad..cea945744656 100644
--- a/src/alarm/interface.h
+++ b/src/alarm/interface.h
@@ -2,7 +2,7 @@
#define __INTERFACE_H
GtkWidget* create_alarm_dialog (void);
-GtkWidget* create_config_dialog (void);
-GtkWidget* create_reminder_dialog (const gchar *reminder_msg);
+GtkWidget* create_config_notebook (void);
+GtkWidget* create_reminder_dialog (const char *reminder_msg);
#endif
diff --git a/src/albumart-qt/Makefile b/src/albumart-qt/Makefile
new file mode 100644
index 000000000000..84be51b113e0
--- /dev/null
+++ b/src/albumart-qt/Makefile
@@ -0,0 +1,13 @@
+PLUGIN = albumart-qt${PLUGIN_SUFFIX}
+
+SRCS = albumart.cc
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+
+LD = ${CXX}
+CFLAGS += ${PLUGIN_CFLAGS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../.. ${QT_CFLAGS}
+LIBS += ${QT_LIBS} -laudqt
diff --git a/src/albumart-qt/albumart.cc b/src/albumart-qt/albumart.cc
new file mode 100644
index 000000000000..3d53c48b41d6
--- /dev/null
+++ b/src/albumart-qt/albumart.cc
@@ -0,0 +1,89 @@
+/*
+ * albumart.cc
+ * Copyright 2014 William Pitcock
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <QLabel>
+#include <QPixmap>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/hook.h>
+
+#include <libaudqt/libaudqt.h>
+
+class AlbumArtQt : public GeneralPlugin {
+public:
+ static constexpr PluginInfo info = {
+ N_("Album Art (Qt)"),
+ PACKAGE
+ };
+
+ constexpr AlbumArtQt () : GeneralPlugin (info, false) {}
+ void * get_qt_widget ();
+
+private:
+ static void update (void * unused, QLabel * widget);
+ static void clear (void * unused, QLabel * widget);
+ static void widget_cleanup (QObject * widget);
+};
+
+void AlbumArtQt::update (void * unused, QLabel * widget)
+{
+ if (! aud_drct_get_playing ())
+ return;
+
+ if (! widget)
+ return;
+
+ QSize size = widget->size ();
+ widget->setPixmap (audqt::art_request_current (size.width (), size.height ()));
+}
+
+void AlbumArtQt::clear (void * unused, QLabel * widget)
+{
+ if (! widget)
+ return;
+
+ widget->setPixmap (QPixmap ());
+}
+
+void AlbumArtQt::widget_cleanup (QObject * widget)
+{
+ hook_dissociate ("playback begin", (HookFunction) update, widget);
+ hook_dissociate ("current art ready", (HookFunction) update, widget);
+ hook_dissociate ("playback stop", (HookFunction) clear, widget);
+}
+
+void * AlbumArtQt::get_qt_widget ()
+{
+ QLabel * widget = new QLabel;
+
+ QObject::connect (widget, &QObject::destroyed, widget_cleanup);
+
+ hook_associate ("playback begin", (HookFunction) update, widget);
+ hook_associate ("current art ready", (HookFunction) update, widget);
+ hook_associate ("playback stop", (HookFunction) clear, widget);
+
+ widget->resize (96, 96);
+ update (nullptr, widget);
+
+ return widget;
+}
+
+EXPORT AlbumArtQt aud_plugin_instance;
diff --git a/src/albumart/Makefile b/src/albumart/Makefile
index fe066cd1833a..8b97ab4d38d9 100644
--- a/src/albumart/Makefile
+++ b/src/albumart/Makefile
@@ -1,12 +1,13 @@
PLUGIN = albumart${PLUGIN_SUFFIX}
-SRCS = albumart.c
+SRCS = albumart.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../.. ${GTK_CFLAGS}
-LIBS += ${GTK_LIBS}
+LIBS += ${GTK_LIBS} -laudgui
diff --git a/src/albumart/albumart.c b/src/albumart/albumart.c
deleted file mode 100644
index 69d63a8aa9c4..000000000000
--- a/src/albumart/albumart.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * albumart.c
- * Copyright 2012-2013 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-static void album_update (void * unused, GtkWidget * widget)
-{
- if (! aud_drct_get_playing ())
- return;
-
- GdkPixbuf * pixbuf = audgui_pixbuf_request_current ();
-
- if (! pixbuf)
- pixbuf = audgui_pixbuf_fallback ();
-
- audgui_scaled_image_set (widget, pixbuf);
-
- if (pixbuf)
- g_object_unref (pixbuf);
-}
-
-static void album_clear (void * unused, GtkWidget * widget)
-{
- audgui_scaled_image_set (widget, NULL);
-}
-
-static void album_cleanup (GtkWidget * widget)
-{
- hook_dissociate_full ("playback begin", (HookFunction) album_update, widget);
- hook_dissociate_full ("current art ready", (HookFunction) album_update, widget);
- hook_dissociate_full ("playback stop", (HookFunction) album_clear, widget);
-}
-
-static void * album_get_widget (void)
-{
- GtkWidget * widget = audgui_scaled_image_new (NULL);
- gtk_widget_set_size_request (widget, 96, 96);
-
- g_signal_connect (widget, "destroy", (GCallback) album_cleanup, NULL);
-
- hook_associate ("playback begin", (HookFunction) album_update, widget);
- hook_associate ("current art ready", (HookFunction) album_update, widget);
- hook_associate ("playback stop", (HookFunction) album_clear, widget);
-
- album_update (NULL, widget);
-
- return widget;
-}
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("Album Art"),
- .domain = PACKAGE,
- .get_widget = album_get_widget
-)
diff --git a/src/albumart/albumart.cc b/src/albumart/albumart.cc
new file mode 100644
index 000000000000..42de4c56b71e
--- /dev/null
+++ b/src/albumart/albumart.cc
@@ -0,0 +1,88 @@
+/*
+ * albumart.c
+ * Copyright 2012-2013 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/hook.h>
+#include <libaudgui/libaudgui.h>
+#include <libaudgui/libaudgui-gtk.h>
+
+class AlbumArtPlugin : public GeneralPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("Album Art"),
+ PACKAGE
+ };
+
+ constexpr AlbumArtPlugin () : GeneralPlugin (info, false) {}
+
+ void * get_gtk_widget ();
+};
+
+EXPORT AlbumArtPlugin aud_plugin_instance;
+
+static void album_update (void * unused, GtkWidget * widget)
+{
+ if (! aud_drct_get_playing ())
+ return;
+
+ GdkPixbuf * pixbuf = audgui_pixbuf_request_current ();
+
+ if (! pixbuf)
+ pixbuf = audgui_pixbuf_fallback ();
+
+ audgui_scaled_image_set (widget, pixbuf);
+
+ if (pixbuf)
+ g_object_unref (pixbuf);
+}
+
+static void album_clear (void * unused, GtkWidget * widget)
+{
+ audgui_scaled_image_set (widget, nullptr);
+}
+
+static void album_cleanup (GtkWidget * widget)
+{
+ hook_dissociate ("playback begin", (HookFunction) album_update, widget);
+ hook_dissociate ("current art ready", (HookFunction) album_update, widget);
+ hook_dissociate ("playback stop", (HookFunction) album_clear, widget);
+
+ audgui_cleanup ();
+}
+
+void * AlbumArtPlugin::get_gtk_widget ()
+{
+ audgui_init ();
+
+ GtkWidget * widget = audgui_scaled_image_new (nullptr);
+ gtk_widget_set_size_request (widget, 96, 96);
+
+ g_signal_connect (widget, "destroy", (GCallback) album_cleanup, nullptr);
+
+ hook_associate ("playback begin", (HookFunction) album_update, widget);
+ hook_associate ("current art ready", (HookFunction) album_update, widget);
+ hook_associate ("playback stop", (HookFunction) album_clear, widget);
+
+ album_update (nullptr, widget);
+
+ return widget;
+}
diff --git a/src/alsa/Makefile b/src/alsa/Makefile
index c600c5a1c17e..802ca9ce9b2e 100644
--- a/src/alsa/Makefile
+++ b/src/alsa/Makefile
@@ -1,14 +1,15 @@
PLUGIN = alsa${PLUGIN_SUFFIX}
-SRCS = alsa.c \
- config.c \
- plugin.c \
+SRCS = alsa.cc \
+ config.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${OUTPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${GTK_CFLAGS} ${ALSA_CFLAGS} -I../..
-LIBS += ${GTK_LIBS} ${ALSA_LIBS}
+CPPFLAGS += ${ALSA_CFLAGS} -I../..
+LIBS += ${ALSA_LIBS}
diff --git a/src/alsa/alsa.c b/src/alsa/alsa.c
deleted file mode 100644
index 73a8ba6e37a6..000000000000
--- a/src/alsa/alsa.c
+++ /dev/null
@@ -1,743 +0,0 @@
-/*
- * ALSA Output Plugin for Audacious
- * Copyright 2009-2012 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-/*
- * Because ALSA is not thread-safe (despite claims to the contrary) we use non-
- * blocking output in the pump thread with the mutex locked, then unlock the
- * mutex and wait for more room in the buffer with poll() while other threads
- * lock the mutex and read the output time. We poll a pipe of our own as well
- * as the ALSA file descriptors so that we can wake up the pump thread when
- * needed.
- *
- * When paused, or when it comes to the end of the data given it, the pump will
- * wait on alsa_cond for the signal to continue. When it has more data waiting,
- * however, it will be sitting in poll() waiting for ALSA's signal that more
- * data can be written.
- *
- * * After adding more data to the buffer, and after resuming from pause,
- * signal on alsa_cond to wake the pump. (There is no need to signal when
- * entering pause.)
- * * After setting the pump_quit flag, signal on alsa_cond AND the poll_pipe
- * before joining the thread.
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <poll.h>
-#include <pthread.h>
-#include <stdint.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <glib.h>
-
-#include <alsa/asoundlib.h>
-
-#include <audacious/debug.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-
-#include "alsa.h"
-
-#define CHECK_VAL_RECOVER(value, function, ...) \
-do { \
- (value) = function (__VA_ARGS__); \
- if ((value) < 0) { \
- CHECK (snd_pcm_recover, alsa_handle, (value), 0); \
- CHECK_VAL ((value), function, __VA_ARGS__); \
- } \
-} while (0)
-
-#define CHECK_RECOVER(function, ...) \
-do { \
- int CHECK_RECOVER_error; \
- CHECK_VAL_RECOVER (CHECK_RECOVER_error, function, __VA_ARGS__); \
-} while (0)
-
-static snd_pcm_t * alsa_handle;
-static pthread_mutex_t alsa_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t alsa_cond = PTHREAD_COND_INITIALIZER;
-
-static snd_pcm_format_t alsa_format;
-static int alsa_channels, alsa_rate;
-
-static void * alsa_buffer;
-static int alsa_buffer_length, alsa_buffer_data_start, alsa_buffer_data_length;
-static int alsa_period; /* milliseconds */
-
-static int64_t alsa_written; /* frames */
-static char alsa_prebuffer, alsa_paused;
-static int alsa_paused_delay; /* frames */
-
-static int poll_pipe[2];
-static int poll_count;
-static struct pollfd * poll_handles;
-
-static char pump_quit;
-static pthread_t pump_thread;
-
-static snd_mixer_t * alsa_mixer;
-static snd_mixer_elem_t * alsa_mixer_element;
-
-static char poll_setup (void)
-{
- if (pipe (poll_pipe))
- {
- ERROR ("Failed to create pipe: %s.\n", strerror (errno));
- return 0;
- }
-
- if (fcntl (poll_pipe[0], F_SETFL, O_NONBLOCK))
- {
- ERROR ("Failed to set O_NONBLOCK on pipe: %s.\n", strerror (errno));
- close (poll_pipe[0]);
- close (poll_pipe[1]);
- return 0;
- }
-
- poll_count = 1 + snd_pcm_poll_descriptors_count (alsa_handle);
- poll_handles = g_new (struct pollfd, poll_count);
- poll_handles[0].fd = poll_pipe[0];
- poll_handles[0].events = POLLIN;
- poll_count = 1 + snd_pcm_poll_descriptors (alsa_handle, poll_handles + 1,
- poll_count - 1);
-
- return 1;
-}
-
-static void poll_sleep (void)
-{
- if (poll (poll_handles, poll_count, -1) < 0)
- {
- ERROR ("Failed to poll: %s.\n", strerror (errno));
- return;
- }
-
- if (poll_handles[0].revents & POLLIN)
- {
- char c;
- while (read (poll_pipe[0], & c, 1) == 1)
- ;
- }
-}
-
-static void poll_wake (void)
-{
- const char c = 0;
- if (write (poll_pipe[1], & c, 1) < 0)
- ERROR ("Failed to write to pipe: %s.\n", strerror (errno));
-}
-
-static void poll_cleanup (void)
-{
- close (poll_pipe[0]);
- close (poll_pipe[1]);
- g_free (poll_handles);
-}
-
-static void * pump (void * unused)
-{
- pthread_mutex_lock (& alsa_mutex);
- pthread_cond_broadcast (& alsa_cond); /* signal thread started */
-
- char failed = 0;
- char workaround = 0;
- int slept = 0;
-
- while (! pump_quit)
- {
- if (alsa_prebuffer || alsa_paused || ! snd_pcm_bytes_to_frames
- (alsa_handle, alsa_buffer_data_length))
- {
- pthread_cond_wait (& alsa_cond, & alsa_mutex);
- continue;
- }
-
- int length;
- CHECK_VAL_RECOVER (length, snd_pcm_avail_update, alsa_handle);
-
- if (! length)
- goto WAIT;
-
- slept = 0;
-
- length = snd_pcm_frames_to_bytes (alsa_handle, length);
- length = MIN (length, alsa_buffer_data_length);
- length = MIN (length, alsa_buffer_length - alsa_buffer_data_start);
- length = snd_pcm_bytes_to_frames (alsa_handle, length);
-
- int written;
- CHECK_VAL_RECOVER (written, snd_pcm_writei, alsa_handle, (char *)
- alsa_buffer + alsa_buffer_data_start, length);
-
- failed = 0;
-
- written = snd_pcm_frames_to_bytes (alsa_handle, written);
- alsa_buffer_data_start += written;
- alsa_buffer_data_length -= written;
-
- pthread_cond_broadcast (& alsa_cond); /* signal write complete */
-
- if (alsa_buffer_data_start == alsa_buffer_length)
- {
- alsa_buffer_data_start = 0;
- continue;
- }
-
- if (! snd_pcm_bytes_to_frames (alsa_handle, alsa_buffer_data_length))
- continue;
-
- WAIT:
- pthread_mutex_unlock (& alsa_mutex);
-
- if (slept > 4)
- {
- AUDDBG ("Activating timer workaround.\n");
- workaround = 1;
- }
-
- if (workaround && slept)
- {
- const struct timespec delay = {.tv_sec = 0, .tv_nsec = 600000 *
- alsa_period};
- nanosleep (& delay, NULL);
- }
- else
- {
- poll_sleep ();
- slept ++;
- }
-
- pthread_mutex_lock (& alsa_mutex);
- continue;
-
- FAILED:
- if (failed)
- break;
-
- failed = 1;
- CHECK (snd_pcm_prepare, alsa_handle);
- }
-
- pthread_mutex_unlock (& alsa_mutex);
- return NULL;
-}
-
-static void pump_start (void)
-{
- AUDDBG ("Starting pump.\n");
- pthread_create (& pump_thread, NULL, pump, NULL);
- pthread_cond_wait (& alsa_cond, & alsa_mutex);
-}
-
-static void pump_stop (void)
-{
- AUDDBG ("Stopping pump.\n");
- pump_quit = 1;
- pthread_cond_broadcast (& alsa_cond);
- poll_wake ();
- pthread_mutex_unlock (& alsa_mutex);
- pthread_join (pump_thread, NULL);
- pthread_mutex_lock (& alsa_mutex);
- pump_quit = 0;
-}
-
-static void start_playback (void)
-{
- AUDDBG ("Starting playback.\n");
- CHECK (snd_pcm_prepare, alsa_handle);
-
-FAILED:
- alsa_prebuffer = 0;
- pthread_cond_broadcast (& alsa_cond);
-}
-
-static int get_delay (void)
-{
- snd_pcm_sframes_t delay = 0;
-
- CHECK_RECOVER (snd_pcm_delay, alsa_handle, & delay);
-
-FAILED:
- return delay;
-}
-
-int alsa_init (void)
-{
- AUDDBG ("Initialize.\n");
- alsa_config_load ();
- alsa_open_mixer ();
- return 1;
-}
-
-void alsa_cleanup (void)
-{
- AUDDBG ("Cleanup.\n");
- alsa_close_mixer ();
- alsa_config_save ();
-}
-
-static int convert_aud_format (int aud_format)
-{
- const struct
- {
- int aud_format, format;
- }
- table[] =
- {
- {FMT_FLOAT, SND_PCM_FORMAT_FLOAT},
- {FMT_S8, SND_PCM_FORMAT_S8},
- {FMT_U8, SND_PCM_FORMAT_U8},
- {FMT_S16_LE, SND_PCM_FORMAT_S16_LE},
- {FMT_S16_BE, SND_PCM_FORMAT_S16_BE},
- {FMT_U16_LE, SND_PCM_FORMAT_U16_LE},
- {FMT_U16_BE, SND_PCM_FORMAT_U16_BE},
- {FMT_S24_LE, SND_PCM_FORMAT_S24_LE},
- {FMT_S24_BE, SND_PCM_FORMAT_S24_BE},
- {FMT_U24_LE, SND_PCM_FORMAT_U24_LE},
- {FMT_U24_BE, SND_PCM_FORMAT_U24_BE},
- {FMT_S32_LE, SND_PCM_FORMAT_S32_LE},
- {FMT_S32_BE, SND_PCM_FORMAT_S32_BE},
- {FMT_U32_LE, SND_PCM_FORMAT_U32_LE},
- {FMT_U32_BE, SND_PCM_FORMAT_U32_BE},
- };
-
- for (int count = 0; count < ARRAY_LEN (table); count ++)
- {
- if (table[count].aud_format == aud_format)
- return table[count].format;
- }
-
- return SND_PCM_FORMAT_UNKNOWN;
-}
-
-int alsa_open_audio (int aud_format, int rate, int channels)
-{
- pthread_mutex_lock (& alsa_mutex);
-
- assert (alsa_handle == NULL);
-
- int format = convert_aud_format (aud_format);
- AUDDBG ("Opening PCM device %s for %s, %d channels, %d Hz.\n",
- alsa_config_pcm, snd_pcm_format_name (format), channels, rate);
- CHECK_NOISY (snd_pcm_open, & alsa_handle, alsa_config_pcm,
- SND_PCM_STREAM_PLAYBACK, 0);
-
- snd_pcm_hw_params_t * params;
- snd_pcm_hw_params_alloca (& params);
- CHECK_NOISY (snd_pcm_hw_params_any, alsa_handle, params);
- CHECK_NOISY (snd_pcm_hw_params_set_access, alsa_handle, params,
- SND_PCM_ACCESS_RW_INTERLEAVED);
-
- CHECK_NOISY (snd_pcm_hw_params_set_format, alsa_handle, params, format);
- CHECK_NOISY (snd_pcm_hw_params_set_channels, alsa_handle, params, channels);
- CHECK_NOISY (snd_pcm_hw_params_set_rate, alsa_handle, params, rate, 0);
-
- alsa_format = format;
- alsa_channels = channels;
- alsa_rate = rate;
-
- int total_buffer = aud_get_int (NULL, "output_buffer_size");
- unsigned int useconds = 1000 * MIN (1000, total_buffer / 2);
- int direction = 0;
- CHECK_NOISY (snd_pcm_hw_params_set_buffer_time_near, alsa_handle, params,
- & useconds, & direction);
- int hard_buffer = useconds / 1000;
-
- useconds = 1000 * (hard_buffer / 4);
- direction = 0;
- CHECK_NOISY (snd_pcm_hw_params_set_period_time_near, alsa_handle, params,
- & useconds, & direction);
- alsa_period = useconds / 1000;
-
- CHECK_NOISY (snd_pcm_hw_params, alsa_handle, params);
-
- int soft_buffer = MAX (total_buffer / 2, total_buffer - hard_buffer);
- AUDDBG ("Buffer: hardware %d ms, software %d ms, period %d ms.\n",
- hard_buffer, soft_buffer, alsa_period);
-
- alsa_buffer_length = snd_pcm_frames_to_bytes (alsa_handle, (int64_t)
- soft_buffer * rate / 1000);
- alsa_buffer = g_malloc (alsa_buffer_length);
- alsa_buffer_data_start = 0;
- alsa_buffer_data_length = 0;
-
- alsa_written = 0;
- alsa_prebuffer = 1;
- alsa_paused = 0;
- alsa_paused_delay = 0;
-
- if (! poll_setup ())
- goto FAILED;
-
- pump_start ();
-
- pthread_mutex_unlock (& alsa_mutex);
- return 1;
-
-FAILED:
- if (alsa_handle != NULL)
- {
- snd_pcm_close (alsa_handle);
- alsa_handle = NULL;
- }
-
- pthread_mutex_unlock (& alsa_mutex);
- return 0;
-}
-
-void alsa_close_audio (void)
-{
- AUDDBG ("Closing audio.\n");
- pthread_mutex_lock (& alsa_mutex);
-
- assert (alsa_handle != NULL);
-
- pump_stop ();
- CHECK (snd_pcm_drop, alsa_handle);
-
-FAILED:
- g_free (alsa_buffer);
- poll_cleanup ();
- snd_pcm_close (alsa_handle);
- alsa_handle = NULL;
-
- pthread_mutex_unlock (& alsa_mutex);
-}
-
-int alsa_buffer_free (void)
-{
- pthread_mutex_lock (& alsa_mutex);
- int avail = alsa_buffer_length - alsa_buffer_data_length;
- pthread_mutex_unlock (& alsa_mutex);
- return avail;
-}
-
-void alsa_write_audio (void * data, int length)
-{
- pthread_mutex_lock (& alsa_mutex);
-
- int start = (alsa_buffer_data_start + alsa_buffer_data_length) %
- alsa_buffer_length;
-
- assert (length <= alsa_buffer_length - alsa_buffer_data_length);
-
- if (length > alsa_buffer_length - start)
- {
- int part = alsa_buffer_length - start;
-
- memcpy ((char *) alsa_buffer + start, data, part);
- memcpy (alsa_buffer, (char *) data + part, length - part);
- }
- else
- memcpy ((char *) alsa_buffer + start, data, length);
-
- alsa_buffer_data_length += length;
- alsa_written += snd_pcm_bytes_to_frames (alsa_handle, length);
-
- if (! alsa_paused)
- pthread_cond_broadcast (& alsa_cond);
-
- pthread_mutex_unlock (& alsa_mutex);
-}
-
-void alsa_period_wait (void)
-{
- pthread_mutex_lock (& alsa_mutex);
-
- while (alsa_buffer_data_length == alsa_buffer_length)
- {
- if (! alsa_paused)
- {
- if (alsa_prebuffer)
- start_playback ();
- else
- pthread_cond_broadcast (& alsa_cond);
- }
-
- pthread_cond_wait (& alsa_cond, & alsa_mutex);
- }
-
- pthread_mutex_unlock (& alsa_mutex);
-}
-
-void alsa_drain (void)
-{
- AUDDBG ("Drain.\n");
- pthread_mutex_lock (& alsa_mutex);
-
- assert (! alsa_paused);
-
- if (alsa_prebuffer)
- start_playback ();
-
- while (snd_pcm_bytes_to_frames (alsa_handle, alsa_buffer_data_length))
- pthread_cond_wait (& alsa_cond, & alsa_mutex);
-
- pump_stop ();
-
- if (alsa_config_drain_workaround)
- {
- int d = get_delay () * 1000 / alsa_rate;
- struct timespec delay = {.tv_sec = d / 1000, .tv_nsec = d % 1000 *
- 1000000};
-
- pthread_mutex_unlock (& alsa_mutex);
- nanosleep (& delay, NULL);
- pthread_mutex_lock (& alsa_mutex);
- }
- else
- {
- while (1)
- {
- int state;
- CHECK_VAL (state, snd_pcm_state, alsa_handle);
-
- if (state != SND_PCM_STATE_RUNNING && state !=
- SND_PCM_STATE_DRAINING)
- break;
-
- pthread_mutex_unlock (& alsa_mutex);
- poll_sleep ();
- pthread_mutex_lock (& alsa_mutex);
- }
- }
-
- pump_start ();
-
-FAILED:
- pthread_mutex_unlock (& alsa_mutex);
- return;
-}
-
-int alsa_output_time (void)
-{
- pthread_mutex_lock (& alsa_mutex);
-
- int64_t frames = alsa_written - snd_pcm_bytes_to_frames (alsa_handle,
- alsa_buffer_data_length);
-
- if (alsa_prebuffer || alsa_paused)
- frames -= alsa_paused_delay;
- else
- frames -= get_delay ();
-
- int time = frames * 1000 / alsa_rate;
-
- pthread_mutex_unlock (& alsa_mutex);
- return time;
-}
-
-void alsa_flush (int time)
-{
- AUDDBG ("Seek requested; discarding buffer.\n");
- pthread_mutex_lock (& alsa_mutex);
-
- pump_stop ();
- CHECK (snd_pcm_drop, alsa_handle);
-
-FAILED:
- alsa_buffer_data_start = 0;
- alsa_buffer_data_length = 0;
-
- alsa_written = (int64_t) time * alsa_rate / 1000;
- alsa_prebuffer = 1;
- alsa_paused_delay = 0;
-
- pthread_cond_broadcast (& alsa_cond); /* interrupt period wait */
-
- pump_start ();
-
- pthread_mutex_unlock (& alsa_mutex);
-}
-
-void alsa_pause (int pause)
-{
- AUDDBG ("%sause.\n", pause ? "P" : "Unp");
- pthread_mutex_lock (& alsa_mutex);
-
- alsa_paused = pause;
-
- if (! alsa_prebuffer)
- {
- if (pause)
- alsa_paused_delay = get_delay ();
-
- CHECK (snd_pcm_pause, alsa_handle, pause);
- }
-
-DONE:
- if (! pause)
- pthread_cond_broadcast (& alsa_cond);
-
- pthread_mutex_unlock (& alsa_mutex);
- return;
-
-FAILED:
- AUDDBG ("Trying to work around broken pause.\n");
-
- if (pause)
- snd_pcm_drop (alsa_handle);
- else
- snd_pcm_prepare (alsa_handle);
-
- goto DONE;
-}
-
-void alsa_open_mixer (void)
-{
- snd_mixer_selem_id_t * selem_id;
-
- alsa_mixer = NULL;
-
- if (alsa_config_mixer_element == NULL)
- goto FAILED;
-
- AUDDBG ("Opening mixer card %s.\n", alsa_config_mixer);
- CHECK_NOISY (snd_mixer_open, & alsa_mixer, 0);
- CHECK_NOISY (snd_mixer_attach, alsa_mixer, alsa_config_mixer);
- CHECK_NOISY (snd_mixer_selem_register, alsa_mixer, NULL, NULL);
- CHECK_NOISY (snd_mixer_load, alsa_mixer);
-
- snd_mixer_selem_id_alloca (& selem_id);
- snd_mixer_selem_id_set_name (selem_id, alsa_config_mixer_element);
- alsa_mixer_element = snd_mixer_find_selem (alsa_mixer, selem_id);
-
- if (alsa_mixer_element == NULL)
- {
- ERROR_NOISY ("snd_mixer_find_selem failed.\n");
- goto FAILED;
- }
-
- CHECK (snd_mixer_selem_set_playback_volume_range, alsa_mixer_element, 0, 100);
- return;
-
-FAILED:
- if (alsa_mixer != NULL)
- {
- snd_mixer_close (alsa_mixer);
- alsa_mixer = NULL;
- }
-}
-
-void alsa_close_mixer (void)
-{
- if (alsa_mixer != NULL)
- snd_mixer_close (alsa_mixer);
-}
-
-void alsa_get_volume (int * left, int * right)
-{
- pthread_mutex_lock (& alsa_mutex);
-
- long left_l = 0, right_l = 0;
-
- if (alsa_mixer == NULL)
- goto FAILED;
-
- CHECK (snd_mixer_handle_events, alsa_mixer);
-
- if (snd_mixer_selem_is_playback_mono (alsa_mixer_element))
- {
- CHECK (snd_mixer_selem_get_playback_volume, alsa_mixer_element,
- SND_MIXER_SCHN_MONO, & left_l);
- right_l = left_l;
-
- if (snd_mixer_selem_has_playback_switch (alsa_mixer_element))
- {
- int on = 0;
- CHECK (snd_mixer_selem_get_playback_switch, alsa_mixer_element,
- SND_MIXER_SCHN_MONO, & on);
-
- if (! on)
- left_l = right_l = 0;
- }
- }
- else
- {
- CHECK (snd_mixer_selem_get_playback_volume, alsa_mixer_element,
- SND_MIXER_SCHN_FRONT_LEFT, & left_l);
- CHECK (snd_mixer_selem_get_playback_volume, alsa_mixer_element,
- SND_MIXER_SCHN_FRONT_RIGHT, & right_l);
-
- if (snd_mixer_selem_has_playback_switch (alsa_mixer_element))
- {
- int left_on = 0, right_on = 0;
- CHECK (snd_mixer_selem_get_playback_switch, alsa_mixer_element,
- SND_MIXER_SCHN_FRONT_LEFT, & left_on);
- CHECK (snd_mixer_selem_get_playback_switch, alsa_mixer_element,
- SND_MIXER_SCHN_FRONT_RIGHT, & right_on);
-
- if (! left_on)
- left_l = 0;
- if (! right_on)
- right_l = 0;
- }
- }
-
-FAILED:
- pthread_mutex_unlock (& alsa_mutex);
-
- * left = left_l;
- * right = right_l;
-}
-
-void alsa_set_volume (int left, int right)
-{
- pthread_mutex_lock (& alsa_mutex);
-
- if (alsa_mixer == NULL)
- goto FAILED;
-
- if (snd_mixer_selem_is_playback_mono (alsa_mixer_element))
- {
- CHECK (snd_mixer_selem_set_playback_volume, alsa_mixer_element,
- SND_MIXER_SCHN_MONO, MAX (left, right));
-
- if (snd_mixer_selem_has_playback_switch (alsa_mixer_element))
- CHECK (snd_mixer_selem_set_playback_switch, alsa_mixer_element,
- SND_MIXER_SCHN_MONO, MAX (left, right) != 0);
- }
- else
- {
- CHECK (snd_mixer_selem_set_playback_volume, alsa_mixer_element,
- SND_MIXER_SCHN_FRONT_LEFT, left);
- CHECK (snd_mixer_selem_set_playback_volume, alsa_mixer_element,
- SND_MIXER_SCHN_FRONT_RIGHT, right);
-
- if (snd_mixer_selem_has_playback_switch (alsa_mixer_element))
- {
- if (snd_mixer_selem_has_playback_switch_joined (alsa_mixer_element))
- CHECK (snd_mixer_selem_set_playback_switch, alsa_mixer_element,
- SND_MIXER_SCHN_FRONT_LEFT, MAX (left, right) != 0);
- else
- {
- CHECK (snd_mixer_selem_set_playback_switch, alsa_mixer_element,
- SND_MIXER_SCHN_FRONT_LEFT, left != 0);
- CHECK (snd_mixer_selem_set_playback_switch, alsa_mixer_element,
- SND_MIXER_SCHN_FRONT_RIGHT, right != 0);
- }
- }
- }
-
- CHECK (snd_mixer_handle_events, alsa_mixer);
-
-FAILED:
- pthread_mutex_unlock (& alsa_mutex);
-}
diff --git a/src/alsa/alsa.cc b/src/alsa/alsa.cc
new file mode 100644
index 000000000000..1d46f12a1932
--- /dev/null
+++ b/src/alsa/alsa.cc
@@ -0,0 +1,675 @@
+/*
+ * ALSA Output Plugin for Audacious
+ * Copyright 2009-2014 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+/*
+ * Because ALSA is not thread-safe (despite claims to the contrary) we use non-
+ * blocking output in the pump thread with the mutex locked, then unlock the
+ * mutex and wait for more room in the buffer with poll() while other threads
+ * lock the mutex and read the output time. We poll a pipe of our own as well
+ * as the ALSA file descriptors so that we can wake up the pump thread when
+ * needed.
+ *
+ * When paused, or when it comes to the end of the data given it, the pump will
+ * wait on alsa_cond for the signal to continue. When it has more data waiting,
+ * however, it will be sitting in poll() waiting for ALSA's signal that more
+ * data can be written.
+ *
+ * * After adding more data to the buffer, and after resuming from pause,
+ * signal on alsa_cond to wake the pump. (There is no need to signal when
+ * entering pause.)
+ * * After setting the pump_quit flag, signal on alsa_cond AND the poll_pipe
+ * before joining the thread.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <poll.h>
+#include <pthread.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <alsa/asoundlib.h>
+#include <libaudcore/ringbuf.h>
+
+#include "alsa.h"
+
+EXPORT ALSAPlugin aud_plugin_instance;
+
+#define CHECK_VAL_RECOVER(value, function, ...) \
+do { \
+ (value) = function (__VA_ARGS__); \
+ if ((value) < 0) { \
+ CHECK (snd_pcm_recover, alsa_handle, (value), 0); \
+ CHECK_VAL ((value), function, __VA_ARGS__); \
+ } \
+} while (0)
+
+#define CHECK_RECOVER(function, ...) \
+do { \
+ int CHECK_RECOVER_error; \
+ CHECK_VAL_RECOVER (CHECK_RECOVER_error, function, __VA_ARGS__); \
+} while (0)
+
+static snd_pcm_t * alsa_handle;
+static pthread_mutex_t alsa_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t alsa_cond = PTHREAD_COND_INITIALIZER;
+
+static snd_pcm_format_t alsa_format;
+static int alsa_channels, alsa_rate;
+
+static RingBuf<char> alsa_buffer;
+static int alsa_period; /* milliseconds */
+
+static bool alsa_prebuffer, alsa_paused;
+static int alsa_paused_delay; /* milliseconds */
+
+static int poll_pipe[2];
+static int poll_count;
+static pollfd * poll_handles;
+
+static bool pump_quit;
+static pthread_t pump_thread;
+
+static snd_mixer_t * alsa_mixer;
+static snd_mixer_elem_t * alsa_mixer_element;
+
+static bool poll_setup ()
+{
+ if (pipe (poll_pipe))
+ {
+ ERROR ("Failed to create pipe: %s.\n", strerror (errno));
+ return false;
+ }
+
+ if (fcntl (poll_pipe[0], F_SETFL, O_NONBLOCK))
+ {
+ ERROR ("Failed to set O_NONBLOCK on pipe: %s.\n", strerror (errno));
+ close (poll_pipe[0]);
+ close (poll_pipe[1]);
+ return false;
+ }
+
+ poll_count = 1 + snd_pcm_poll_descriptors_count (alsa_handle);
+ poll_handles = new pollfd[poll_count];
+ poll_handles[0].fd = poll_pipe[0];
+ poll_handles[0].events = POLLIN;
+ poll_count = 1 + snd_pcm_poll_descriptors (alsa_handle, poll_handles + 1,
+ poll_count - 1);
+
+ return true;
+}
+
+static void poll_sleep ()
+{
+ if (poll (poll_handles, poll_count, -1) < 0)
+ {
+ ERROR ("Failed to poll: %s.\n", strerror (errno));
+ return;
+ }
+
+ if (poll_handles[0].revents & POLLIN)
+ {
+ char c;
+ while (read (poll_pipe[0], & c, 1) == 1)
+ ;
+ }
+}
+
+static void poll_wake ()
+{
+ const char c = 0;
+ if (write (poll_pipe[1], & c, 1) < 0)
+ ERROR ("Failed to write to pipe: %s.\n", strerror (errno));
+}
+
+static void poll_cleanup ()
+{
+ close (poll_pipe[0]);
+ close (poll_pipe[1]);
+ delete[] poll_handles;
+}
+
+static void * pump (void *)
+{
+ pthread_mutex_lock (& alsa_mutex);
+ pthread_cond_broadcast (& alsa_cond); /* signal thread started */
+
+ bool failed_once = false;
+ bool use_timed_wait = false;
+ int wakeups_since_write = 0;
+
+ while (! pump_quit)
+ {
+ int writable = snd_pcm_bytes_to_frames (alsa_handle, alsa_buffer.linear ());
+
+ if (alsa_prebuffer || alsa_paused || ! writable)
+ {
+ pthread_cond_wait (& alsa_cond, & alsa_mutex);
+ continue;
+ }
+
+ int avail;
+ CHECK_VAL_RECOVER (avail, snd_pcm_avail_update, alsa_handle);
+
+ if (avail)
+ {
+ wakeups_since_write = 0;
+
+ int written;
+ CHECK_VAL_RECOVER (written, snd_pcm_writei, alsa_handle,
+ & alsa_buffer[0], aud::min (writable, avail));
+
+ failed_once = false;
+
+ alsa_buffer.discard (snd_pcm_frames_to_bytes (alsa_handle, written));
+
+ pthread_cond_broadcast (& alsa_cond); /* signal write complete */
+
+ if (writable < avail)
+ continue;
+ }
+
+ pthread_mutex_unlock (& alsa_mutex);
+
+ if (wakeups_since_write > 4)
+ {
+ AUDDBG ("Activating timer workaround.\n");
+ use_timed_wait = true;
+ }
+
+ if (use_timed_wait && wakeups_since_write)
+ {
+ timespec delay = {0, 600000 * alsa_period};
+ nanosleep (& delay, nullptr);
+ }
+ else
+ {
+ poll_sleep ();
+ wakeups_since_write ++;
+ }
+
+ pthread_mutex_lock (& alsa_mutex);
+ continue;
+
+ FAILED:
+ if (failed_once)
+ break;
+
+ failed_once = true;
+ CHECK (snd_pcm_prepare, alsa_handle);
+ }
+
+ pthread_mutex_unlock (& alsa_mutex);
+ return nullptr;
+}
+
+static void pump_start ()
+{
+ AUDDBG ("Starting pump.\n");
+ pthread_create (& pump_thread, nullptr, pump, nullptr);
+ pthread_cond_wait (& alsa_cond, & alsa_mutex);
+}
+
+static void pump_stop ()
+{
+ AUDDBG ("Stopping pump.\n");
+ pump_quit = true;
+ pthread_cond_broadcast (& alsa_cond);
+ poll_wake ();
+ pthread_mutex_unlock (& alsa_mutex);
+ pthread_join (pump_thread, nullptr);
+ pthread_mutex_lock (& alsa_mutex);
+ pump_quit = false;
+}
+
+static void start_playback ()
+{
+ AUDDBG ("Starting playback.\n");
+ CHECK (snd_pcm_prepare, alsa_handle);
+
+FAILED:
+ alsa_prebuffer = false;
+ pthread_cond_broadcast (& alsa_cond);
+}
+
+static int get_delay_locked ()
+{
+ snd_pcm_sframes_t delay = 0;
+ CHECK_RECOVER (snd_pcm_delay, alsa_handle, & delay);
+
+FAILED:
+ return aud::rescale ((int) delay, alsa_rate, 1000);
+}
+
+bool ALSAPlugin::init ()
+{
+ AUDDBG ("Initialize.\n");
+ init_config ();
+ open_mixer ();
+ return true;
+}
+
+void ALSAPlugin::cleanup ()
+{
+ AUDDBG ("Cleanup.\n");
+ close_mixer ();
+}
+
+static snd_pcm_format_t convert_aud_format (int aud_format)
+{
+ static const struct
+ {
+ int aud_format;
+ snd_pcm_format_t format;
+ }
+ table[] =
+ {
+ {FMT_FLOAT, SND_PCM_FORMAT_FLOAT},
+ {FMT_S8, SND_PCM_FORMAT_S8},
+ {FMT_U8, SND_PCM_FORMAT_U8},
+ {FMT_S16_LE, SND_PCM_FORMAT_S16_LE},
+ {FMT_S16_BE, SND_PCM_FORMAT_S16_BE},
+ {FMT_U16_LE, SND_PCM_FORMAT_U16_LE},
+ {FMT_U16_BE, SND_PCM_FORMAT_U16_BE},
+ {FMT_S24_LE, SND_PCM_FORMAT_S24_LE},
+ {FMT_S24_BE, SND_PCM_FORMAT_S24_BE},
+ {FMT_U24_LE, SND_PCM_FORMAT_U24_LE},
+ {FMT_U24_BE, SND_PCM_FORMAT_U24_BE},
+ {FMT_S32_LE, SND_PCM_FORMAT_S32_LE},
+ {FMT_S32_BE, SND_PCM_FORMAT_S32_BE},
+ {FMT_U32_LE, SND_PCM_FORMAT_U32_LE},
+ {FMT_U32_BE, SND_PCM_FORMAT_U32_BE},
+ };
+
+ for (auto & conv : table)
+ {
+ if (conv.aud_format == aud_format)
+ return conv.format;
+ }
+
+ return SND_PCM_FORMAT_UNKNOWN;
+}
+
+bool ALSAPlugin::open_audio (int aud_format, int rate, int channels)
+{
+ int total_buffer, hard_buffer, soft_buffer, buffer_frames;
+ unsigned useconds;
+ int direction;
+
+ pthread_mutex_lock (& alsa_mutex);
+
+ assert (! alsa_handle);
+
+ String pcm = aud_get_str ("alsa", "pcm");
+ snd_pcm_format_t format = convert_aud_format (aud_format);
+ AUDDBG ("Opening PCM device %s for %s, %d channels, %d Hz.\n",
+ (const char *) pcm, snd_pcm_format_name (format), channels, rate);
+ CHECK_NOISY (snd_pcm_open, & alsa_handle, pcm, SND_PCM_STREAM_PLAYBACK, 0);
+
+ snd_pcm_hw_params_t * params;
+ snd_pcm_hw_params_alloca (& params);
+ CHECK_NOISY (snd_pcm_hw_params_any, alsa_handle, params);
+ CHECK_NOISY (snd_pcm_hw_params_set_access, alsa_handle, params,
+ SND_PCM_ACCESS_RW_INTERLEAVED);
+
+ CHECK_NOISY (snd_pcm_hw_params_set_format, alsa_handle, params, format);
+ CHECK_NOISY (snd_pcm_hw_params_set_channels, alsa_handle, params, channels);
+ CHECK_NOISY (snd_pcm_hw_params_set_rate, alsa_handle, params, rate, 0);
+
+ alsa_format = format;
+ alsa_channels = channels;
+ alsa_rate = rate;
+
+ total_buffer = aud_get_int (nullptr, "output_buffer_size");
+ useconds = 1000 * aud::min (1000, total_buffer / 2);
+ direction = 0;
+ CHECK_NOISY (snd_pcm_hw_params_set_buffer_time_near, alsa_handle, params,
+ & useconds, & direction);
+ hard_buffer = useconds / 1000;
+
+ useconds = 1000 * (hard_buffer / 4);
+ direction = 0;
+ CHECK_NOISY (snd_pcm_hw_params_set_period_time_near, alsa_handle, params,
+ & useconds, & direction);
+ alsa_period = useconds / 1000;
+
+ CHECK_NOISY (snd_pcm_hw_params, alsa_handle, params);
+
+ soft_buffer = aud::max (total_buffer / 2, total_buffer - hard_buffer);
+ AUDDBG ("Buffer: hardware %d ms, software %d ms, period %d ms.\n",
+ hard_buffer, soft_buffer, alsa_period);
+
+ buffer_frames = aud::rescale<int64_t> (soft_buffer, 1000, rate);
+ alsa_buffer.alloc (snd_pcm_frames_to_bytes (alsa_handle, buffer_frames));
+
+ alsa_prebuffer = true;
+ alsa_paused = false;
+ alsa_paused_delay = 0;
+
+ if (! poll_setup ())
+ goto FAILED;
+
+ pump_start ();
+
+ pthread_mutex_unlock (& alsa_mutex);
+ return true;
+
+FAILED:
+ if (alsa_handle)
+ {
+ snd_pcm_close (alsa_handle);
+ alsa_handle = nullptr;
+ }
+
+ pthread_mutex_unlock (& alsa_mutex);
+ return false;
+}
+
+void ALSAPlugin::close_audio ()
+{
+ AUDDBG ("Closing audio.\n");
+ pthread_mutex_lock (& alsa_mutex);
+
+ assert (alsa_handle);
+
+ pump_stop ();
+ CHECK (snd_pcm_drop, alsa_handle);
+
+FAILED:
+ alsa_buffer.destroy ();
+ poll_cleanup ();
+ snd_pcm_close (alsa_handle);
+ alsa_handle = nullptr;
+
+ pthread_mutex_unlock (& alsa_mutex);
+}
+
+int ALSAPlugin::write_audio (const void * data, int length)
+{
+ pthread_mutex_lock (& alsa_mutex);
+
+ length = aud::min (length, alsa_buffer.space ());
+ alsa_buffer.copy_in ((const char *) data, length);
+
+ if (! alsa_paused)
+ pthread_cond_broadcast (& alsa_cond);
+
+ pthread_mutex_unlock (& alsa_mutex);
+ return length;
+}
+
+void ALSAPlugin::period_wait ()
+{
+ pthread_mutex_lock (& alsa_mutex);
+
+ while (! alsa_buffer.space ())
+ {
+ if (! alsa_paused)
+ {
+ if (alsa_prebuffer)
+ start_playback ();
+ else
+ pthread_cond_broadcast (& alsa_cond);
+ }
+
+ pthread_cond_wait (& alsa_cond, & alsa_mutex);
+ }
+
+ pthread_mutex_unlock (& alsa_mutex);
+}
+
+void ALSAPlugin::drain ()
+{
+ AUDDBG ("Drain.\n");
+ pthread_mutex_lock (& alsa_mutex);
+
+ assert (! alsa_paused);
+
+ if (alsa_prebuffer)
+ start_playback ();
+
+ while (snd_pcm_bytes_to_frames (alsa_handle, alsa_buffer.len ()))
+ pthread_cond_wait (& alsa_cond, & alsa_mutex);
+
+ pump_stop ();
+
+ int d = get_delay_locked ();
+ timespec delay = {d / 1000, d % 1000 * 1000000};
+
+ pthread_mutex_unlock (& alsa_mutex);
+ nanosleep (& delay, nullptr);
+ pthread_mutex_lock (& alsa_mutex);
+
+ pump_start ();
+
+ pthread_mutex_unlock (& alsa_mutex);
+}
+
+int ALSAPlugin::get_delay ()
+{
+ pthread_mutex_lock (& alsa_mutex);
+
+ int buffered = snd_pcm_bytes_to_frames (alsa_handle, alsa_buffer.len ());
+ int delay = aud::rescale (buffered, alsa_rate, 1000);
+
+ if (alsa_prebuffer || alsa_paused)
+ delay += alsa_paused_delay;
+ else
+ delay += get_delay_locked ();
+
+ pthread_mutex_unlock (& alsa_mutex);
+ return delay;
+}
+
+void ALSAPlugin::flush ()
+{
+ AUDDBG ("Seek requested; discarding buffer.\n");
+ pthread_mutex_lock (& alsa_mutex);
+
+ pump_stop ();
+ CHECK (snd_pcm_drop, alsa_handle);
+
+FAILED:
+ alsa_buffer.discard ();
+
+ alsa_prebuffer = true;
+ alsa_paused_delay = 0;
+
+ pthread_cond_broadcast (& alsa_cond); /* interrupt period wait */
+
+ pump_start ();
+
+ pthread_mutex_unlock (& alsa_mutex);
+}
+
+void ALSAPlugin::pause (bool pause)
+{
+ AUDDBG ("%sause.\n", pause ? "P" : "Unp");
+ pthread_mutex_lock (& alsa_mutex);
+
+ alsa_paused = pause;
+
+ if (! alsa_prebuffer)
+ {
+ if (pause)
+ alsa_paused_delay = get_delay_locked ();
+
+ CHECK (snd_pcm_pause, alsa_handle, pause);
+ }
+
+DONE:
+ if (! pause)
+ pthread_cond_broadcast (& alsa_cond);
+
+ pthread_mutex_unlock (& alsa_mutex);
+ return;
+
+FAILED:
+ AUDDBG ("Trying to work around broken pause.\n");
+
+ if (pause)
+ snd_pcm_drop (alsa_handle);
+ else
+ snd_pcm_prepare (alsa_handle);
+
+ goto DONE;
+}
+
+void ALSAPlugin::open_mixer ()
+{
+ alsa_mixer = nullptr;
+
+ String mixer = aud_get_str ("alsa", "mixer");
+ String mixer_element = aud_get_str ("alsa", "mixer-element");
+
+ if (! mixer_element[0])
+ goto FAILED;
+
+ AUDDBG ("Opening mixer card %s.\n", (const char *) mixer);
+ CHECK_NOISY (snd_mixer_open, & alsa_mixer, 0);
+ CHECK_NOISY (snd_mixer_attach, alsa_mixer, mixer);
+ CHECK_NOISY (snd_mixer_selem_register, alsa_mixer, nullptr, nullptr);
+ CHECK_NOISY (snd_mixer_load, alsa_mixer);
+
+ snd_mixer_selem_id_t * selem_id;
+ snd_mixer_selem_id_alloca (& selem_id);
+ snd_mixer_selem_id_set_name (selem_id, mixer_element);
+ alsa_mixer_element = snd_mixer_find_selem (alsa_mixer, selem_id);
+
+ if (! alsa_mixer_element)
+ {
+ ERROR_NOISY ("snd_mixer_find_selem failed.\n");
+ goto FAILED;
+ }
+
+ CHECK (snd_mixer_selem_set_playback_volume_range, alsa_mixer_element, 0, 100);
+ return;
+
+FAILED:
+ if (alsa_mixer)
+ {
+ snd_mixer_close (alsa_mixer);
+ alsa_mixer = nullptr;
+ }
+}
+
+void ALSAPlugin::close_mixer ()
+{
+ if (alsa_mixer)
+ snd_mixer_close (alsa_mixer);
+}
+
+StereoVolume ALSAPlugin::get_volume ()
+{
+ pthread_mutex_lock (& alsa_mutex);
+
+ long left = 0, right = 0;
+
+ if (! alsa_mixer)
+ goto FAILED;
+
+ CHECK (snd_mixer_handle_events, alsa_mixer);
+
+ if (snd_mixer_selem_is_playback_mono (alsa_mixer_element))
+ {
+ CHECK (snd_mixer_selem_get_playback_volume, alsa_mixer_element,
+ SND_MIXER_SCHN_MONO, & left);
+ right = left;
+
+ if (snd_mixer_selem_has_playback_switch (alsa_mixer_element))
+ {
+ int on = 0;
+ CHECK (snd_mixer_selem_get_playback_switch, alsa_mixer_element,
+ SND_MIXER_SCHN_MONO, & on);
+
+ if (! on)
+ left = right = 0;
+ }
+ }
+ else
+ {
+ CHECK (snd_mixer_selem_get_playback_volume, alsa_mixer_element,
+ SND_MIXER_SCHN_FRONT_LEFT, & left);
+ CHECK (snd_mixer_selem_get_playback_volume, alsa_mixer_element,
+ SND_MIXER_SCHN_FRONT_RIGHT, & right);
+
+ if (snd_mixer_selem_has_playback_switch (alsa_mixer_element))
+ {
+ int left_on = 0, right_on = 0;
+ CHECK (snd_mixer_selem_get_playback_switch, alsa_mixer_element,
+ SND_MIXER_SCHN_FRONT_LEFT, & left_on);
+ CHECK (snd_mixer_selem_get_playback_switch, alsa_mixer_element,
+ SND_MIXER_SCHN_FRONT_RIGHT, & right_on);
+
+ if (! left_on)
+ left = 0;
+ if (! right_on)
+ right = 0;
+ }
+ }
+
+FAILED:
+ pthread_mutex_unlock (& alsa_mutex);
+ return {(int) left, (int) right};
+}
+
+void ALSAPlugin::set_volume (StereoVolume v)
+{
+ pthread_mutex_lock (& alsa_mutex);
+
+ if (! alsa_mixer)
+ goto FAILED;
+
+ if (snd_mixer_selem_is_playback_mono (alsa_mixer_element))
+ {
+ CHECK (snd_mixer_selem_set_playback_volume, alsa_mixer_element,
+ SND_MIXER_SCHN_MONO, aud::max (v.left, v.right));
+
+ if (snd_mixer_selem_has_playback_switch (alsa_mixer_element))
+ CHECK (snd_mixer_selem_set_playback_switch, alsa_mixer_element,
+ SND_MIXER_SCHN_MONO, aud::max (v.left, v.right) != 0);
+ }
+ else
+ {
+ CHECK (snd_mixer_selem_set_playback_volume, alsa_mixer_element,
+ SND_MIXER_SCHN_FRONT_LEFT, v.left);
+ CHECK (snd_mixer_selem_set_playback_volume, alsa_mixer_element,
+ SND_MIXER_SCHN_FRONT_RIGHT, v.right);
+
+ if (snd_mixer_selem_has_playback_switch (alsa_mixer_element))
+ {
+ if (snd_mixer_selem_has_playback_switch_joined (alsa_mixer_element))
+ CHECK (snd_mixer_selem_set_playback_switch, alsa_mixer_element,
+ SND_MIXER_SCHN_FRONT_LEFT, aud::max (v.left, v.right) != 0);
+ else
+ {
+ CHECK (snd_mixer_selem_set_playback_switch, alsa_mixer_element,
+ SND_MIXER_SCHN_FRONT_LEFT, v.left != 0);
+ CHECK (snd_mixer_selem_set_playback_switch, alsa_mixer_element,
+ SND_MIXER_SCHN_FRONT_RIGHT, v.right != 0);
+ }
+ }
+ }
+
+ CHECK (snd_mixer_handle_events, alsa_mixer);
+
+FAILED:
+ pthread_mutex_unlock (& alsa_mutex);
+}
diff --git a/src/alsa/alsa.h b/src/alsa/alsa.h
index 294e38c12b3f..f59c24cb770f 100644
--- a/src/alsa/alsa.h
+++ b/src/alsa/alsa.h
@@ -1,6 +1,6 @@
/*
* ALSA Output Plugin for Audacious
- * Copyright 2009-2012 John Lindgren
+ * Copyright 2009-2014 John Lindgren
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -20,15 +20,16 @@
#ifndef AUDACIOUS_ALSA_H
#define AUDACIOUS_ALSA_H
-#include <stdio.h>
-#include <audacious/misc.h>
#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
-#define ERROR(...) fprintf (stderr, "alsa: " __VA_ARGS__)
+#define ERROR AUDERR
#define ERROR_NOISY(...) do { \
- SPRINTF (ERROR_NOISY_buf, "ALSA error: " __VA_ARGS__); \
- aud_interface_show_error (ERROR_NOISY_buf); \
+ aud_ui_show_error (str_printf ("ALSA error: " __VA_ARGS__)); \
} while (0)
#define CHECK_VAL(value, function, ...) \
@@ -55,30 +56,51 @@ do { \
} \
} while (0)
-/* alsa.c */
-int alsa_init (void);
-void alsa_cleanup (void);
-int alsa_open_audio (int aud_format, int rate, int channels);
-void alsa_close_audio (void);
-int alsa_buffer_free (void);
-void alsa_write_audio (void * data, int length);
-void alsa_period_wait (void);
-void alsa_drain (void);
-int alsa_output_time (void);
-void alsa_flush (int time);
-void alsa_pause (int pause);
-void alsa_open_mixer (void);
-void alsa_close_mixer (void);
-void alsa_get_volume (int * left, int * right);
-void alsa_set_volume (int left, int right);
-
-/* config.c */
-extern char * alsa_config_pcm, * alsa_config_mixer, * alsa_config_mixer_element;
-extern int alsa_config_drop_workaround, alsa_config_drain_workaround,
- alsa_config_delay_workaround;
-
-void alsa_config_load (void);
-void alsa_config_save (void);
-void * alsa_create_config_widget (void);
+struct PreferencesWidget;
+
+class ALSAPlugin : public OutputPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("ALSA Output"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ constexpr ALSAPlugin () : OutputPlugin (info, 5) {}
+
+ bool init ();
+ void cleanup ();
+
+ StereoVolume get_volume ();
+ void set_volume (StereoVolume v);
+
+ bool open_audio (int aud_format, int rate, int chans);
+ void close_audio ();
+
+ void period_wait ();
+ int write_audio (const void * data, int size);
+ void drain ();
+
+ int get_delay ();
+
+ void pause (bool pause);
+ void flush ();
+
+private:
+ static void open_mixer ();
+ static void close_mixer ();
+
+ static void init_config ();
+ static void pcm_changed ();
+ static void mixer_changed ();
+ static void element_changed ();
+};
#endif
diff --git a/src/alsa/config.c b/src/alsa/config.c
deleted file mode 100644
index cee3bc86e096..000000000000
--- a/src/alsa/config.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * ALSA Output Plugin for Audacious
- * Copyright 2009-2012 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <alsa/asoundlib.h>
-#include <gtk/gtk.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-
-#include "alsa.h"
-
-char * alsa_config_pcm = NULL, * alsa_config_mixer = NULL,
- * alsa_config_mixer_element = NULL;
-int alsa_config_drain_workaround = 1;
-
-static GtkListStore * pcm_list, * mixer_list, * mixer_element_list;
-static GtkWidget * pcm_combo, * mixer_combo, * mixer_element_combo, * drain_workaround_check;
-
-static GtkTreeIter * list_lookup_member (GtkListStore * list, const char * text)
-{
- static GtkTreeIter iter;
-
- if (! gtk_tree_model_get_iter_first ((GtkTreeModel *) list, & iter))
- return NULL;
-
- do
- {
- char * iter_text;
-
- gtk_tree_model_get ((GtkTreeModel *) list, & iter, 0, & iter_text, -1);
-
- if (! strcmp (iter_text, text))
- {
- g_free (iter_text);
- return & iter;
- }
-
- g_free (iter_text);
- }
- while (gtk_tree_model_iter_next ((GtkTreeModel *) list, & iter));
-
- return NULL;
-}
-
-static int list_has_member (GtkListStore * list, const char * text)
-{
- return (list_lookup_member (list, text) != NULL);
-}
-
-static void get_defined_devices (const char * type, int capture, void (* found)
- (const char * name, const char * description))
-{
- void * * hints = NULL;
- int count;
-
- CHECK (snd_device_name_hint, -1, type, & hints);
-
- for (count = 0; hints[count] != NULL; count ++)
- {
- char * type = snd_device_name_get_hint (hints[count], "IOID");
-
- if (type == NULL || ! strcmp (type, capture ? "Input" : "Output"))
- {
- char * name = snd_device_name_get_hint (hints[count], "NAME");
- char * description = snd_device_name_get_hint (hints[count], "DESC");
-
- found (name, description);
- g_free (name);
- g_free (description);
- }
-
- g_free (type);
- }
-
-FAILED:
- if (hints != NULL)
- snd_device_name_free_hint (hints);
-}
-
-static char * get_card_description (int card)
-{
- char * description = NULL;
-
- CHECK (snd_card_get_name, card, & description);
-
-FAILED:
- return description;
-}
-
-static void get_cards (void (* found) (int card, const char * description))
-{
- int card = -1;
-
- while (1)
- {
- char * description;
-
- CHECK (snd_card_next, & card);
-
- if (card < 0)
- break;
-
- if ((description = get_card_description (card)) != NULL)
- {
- found (card, description);
- g_free (description);
- }
- }
-
-FAILED:
- return;
-}
-
-static char * get_device_description (snd_ctl_t * control, int device, int
- capture)
-{
- snd_pcm_info_t * info;
-
- snd_pcm_info_alloca (& info);
- snd_pcm_info_set_device (info, device);
- snd_pcm_info_set_stream (info, capture ? SND_PCM_STREAM_CAPTURE :
- SND_PCM_STREAM_PLAYBACK);
-
- switch (snd_ctl_pcm_info (control, info))
- {
- case 0:
- return g_strdup (snd_pcm_info_get_name (info));
-
- case -ENOENT: /* capture but we want playback (or other way around) */
- return NULL;
- }
-
- CHECK (snd_ctl_pcm_info, control, info);
-
-FAILED:
- return NULL;
-}
-
-static void get_devices (int card, int capture, void (* found) (const char *
- name, const char * description))
-{
- char card_name[16];
- snd_ctl_t * control = NULL;
- int device = -1;
-
- snprintf (card_name, sizeof card_name, "hw:%d", card);
- CHECK (snd_ctl_open, & control, card_name, 0);
-
- while (1)
- {
- char name[16];
- char * description;
-
- CHECK (snd_ctl_pcm_next_device, control, & device);
-
- if (device < 0)
- break;
-
- snprintf (name, sizeof name, "hw:%d,%d", card, device);
- description = get_device_description (control, device, capture);
-
- if (description != NULL)
- found (name, description);
-
- g_free (description);
- }
-
-FAILED:
- if (control != NULL)
- snd_ctl_close (control);
-}
-
-static void pcm_found (const char * name, const char * description)
-{
- GtkTreeIter iter;
- char new[512];
-
- gtk_list_store_append (pcm_list, & iter);
- snprintf (new, sizeof new, "(%s)", description);
- gtk_list_store_set (pcm_list, & iter, 0, name, 1, new, -1);
-}
-
-static void pcm_card_found (int card, const char * description)
-{
- get_devices (card, 0, pcm_found);
-}
-
-static void pcm_list_fill (void)
-{
- if (pcm_list)
- return;
-
- pcm_list = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
- pcm_found ("default", _("Default PCM device"));
- get_defined_devices ("pcm", 0, pcm_found);
- get_cards (pcm_card_found);
-}
-
-static void mixer_found (const char * name, const char * description)
-{
- GtkTreeIter iter;
- char new[512];
-
- gtk_list_store_append (mixer_list, & iter);
- snprintf (new, sizeof new, "(%s)", description);
- gtk_list_store_set (mixer_list, & iter, 0, name, 1, new, -1);
-}
-
-static void mixer_card_found (int card, const char * description)
-{
- char name[16];
-
- snprintf (name, sizeof name, "hw:%d", card);
- mixer_found (name, description);
-}
-
-static void mixer_list_fill (void)
-{
- if (mixer_list)
- return;
-
- mixer_list = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
- mixer_found ("default", _("Default mixer device"));
- get_defined_devices ("ctl", 0, mixer_found);
- get_cards (mixer_card_found);
-}
-
-static void get_mixer_elements (const char * mixer, void (* found)
- (const char * name))
-{
- snd_mixer_t * mixer_handle = NULL;
- snd_mixer_elem_t * element;
-
- CHECK (snd_mixer_open, & mixer_handle, 0);
- CHECK (snd_mixer_attach, mixer_handle, mixer);
- CHECK (snd_mixer_selem_register, mixer_handle, NULL, NULL);
- CHECK (snd_mixer_load, mixer_handle);
-
- element = snd_mixer_first_elem (mixer_handle);
-
- while (element != NULL)
- {
- if (snd_mixer_selem_has_playback_volume (element))
- found (snd_mixer_selem_get_name (element));
-
- element = snd_mixer_elem_next (element);
- }
-
-FAILED:
- if (mixer_handle != NULL)
- snd_mixer_close (mixer_handle);
-}
-
-static void mixer_element_found (const char * name)
-{
- GtkTreeIter iter;
-
- gtk_list_store_append (mixer_element_list, & iter);
- gtk_list_store_set (mixer_element_list, & iter, 0, name, -1);
-}
-
-static void mixer_element_list_fill (void)
-{
- if (mixer_element_list)
- return;
-
- mixer_element_list = gtk_list_store_new (1, G_TYPE_STRING);
- get_mixer_elements (alsa_config_mixer, mixer_element_found);
-}
-
-static void mixer_element_list_refill (void)
-{
- gtk_list_store_clear (mixer_element_list);
- get_mixer_elements (alsa_config_mixer, mixer_element_found);
-}
-
-static void guess_mixer_element (void)
-{
- mixer_element_list_fill ();
-
- static const char * guesses[] = {"Master", "PCM", "Wave"};
- for (int count = 0; count < ARRAY_LEN (guesses); count ++)
- {
- if (list_has_member (mixer_element_list, guesses[count]))
- {
- str_unref (alsa_config_mixer_element);
- alsa_config_mixer_element = str_get (guesses[count]);
- return;
- }
- }
-
- ERROR_NOISY ("No suitable mixer element found.\n");
-}
-
-static const gchar * const alsa_defaults[] = {
- "pcm", "default",
- "mixer", "default",
- "drain-workaround", "TRUE",
- NULL};
-
-void alsa_config_load (void)
-{
- aud_config_set_defaults ("alsa", alsa_defaults);
-
- alsa_config_pcm = aud_get_str ("alsa", "pcm");
- alsa_config_mixer = aud_get_str ("alsa", "mixer");
- alsa_config_mixer_element = aud_get_str ("alsa", "mixer-element");
- alsa_config_drain_workaround = aud_get_bool ("alsa", "drain-workaround");
-
- if (! alsa_config_mixer_element[0])
- guess_mixer_element ();
-}
-
-void alsa_config_save (void)
-{
- if (pcm_list)
- {
- g_object_unref (pcm_list);
- pcm_list = NULL;
- }
-
- if (mixer_list)
- {
- g_object_unref (mixer_list);
- mixer_list = NULL;
- }
-
- if (mixer_element_list)
- {
- g_object_unref (mixer_element_list);
- mixer_element_list = NULL;
- }
-
- aud_set_str ("alsa", "pcm", alsa_config_pcm);
- aud_set_str ("alsa", "mixer", alsa_config_mixer);
- aud_set_str ("alsa", "mixer-element", alsa_config_mixer_element);
- aud_set_bool ("alsa", "drain-workaround", alsa_config_drain_workaround);
-
- str_unref (alsa_config_pcm);
- alsa_config_pcm = NULL;
- str_unref (alsa_config_mixer);
- alsa_config_mixer = NULL;
- str_unref (alsa_config_mixer_element);
- alsa_config_mixer_element = NULL;
-}
-
-static GtkWidget * combo_new (const char * title, GtkListStore * list,
- GtkWidget * * combo, int has_description)
-{
- GtkWidget * hbox, * label;
- GtkCellRenderer * cell;
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-
- label = gtk_label_new (title);
- gtk_box_pack_start ((GtkBox *) hbox, label, 0, 0, 0);
-
- * combo = gtk_combo_box_new_with_model ((GtkTreeModel *) list);
- gtk_box_pack_start ((GtkBox *) hbox, * combo, 1, 1, 0);
-
- cell = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start ((GtkCellLayout *) * combo, cell, 0);
- gtk_cell_layout_set_attributes ((GtkCellLayout *) * combo, cell, "text", 0,
- NULL);
-
- if (has_description)
- {
- cell = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start ((GtkCellLayout *) * combo, cell, 0);
- gtk_cell_layout_set_attributes ((GtkCellLayout *) * combo, cell, "text",
- 1, NULL);
- }
-
- return hbox;
-}
-
-static void combo_select_by_text (GtkWidget * combo, GtkListStore * list,
- const char * text)
-{
- GtkTreeIter * iter;
-
- if (text == NULL)
- {
- gtk_combo_box_set_active ((GtkComboBox *) combo, -1);
- return;
- }
-
- iter = list_lookup_member (list, text);
-
- if (iter == NULL)
- return;
-
- gtk_combo_box_set_active_iter ((GtkComboBox *) combo, iter);
-}
-
-static const char * combo_selected_text (GtkWidget * combo, GtkListStore * list)
-{
- GtkTreeIter iter;
- const char * text;
-
- if (! gtk_combo_box_get_active_iter ((GtkComboBox *) combo, & iter))
- return NULL;
-
- gtk_tree_model_get ((GtkTreeModel *) list, & iter, 0, & text, -1);
- return text;
-}
-
-static GtkWidget * create_vbox (void)
-{
- GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-
- gtk_box_pack_start ((GtkBox *) vbox, combo_new (_("PCM device:"), pcm_list,
- & pcm_combo, 1), 0, 0, 0);
- gtk_box_pack_start ((GtkBox *) vbox, combo_new (_("Mixer device:"),
- mixer_list, & mixer_combo, 1), 0, 0, 0);
- gtk_box_pack_start ((GtkBox *) vbox, combo_new (_("Mixer element:"),
- mixer_element_list, & mixer_element_combo, 0), 0, 0, 0);
-
- drain_workaround_check = gtk_check_button_new_with_label (_("Work around "
- "drain hangup"));
- gtk_toggle_button_set_active ((GtkToggleButton *) drain_workaround_check,
- alsa_config_drain_workaround);
- gtk_box_pack_start ((GtkBox *) vbox, drain_workaround_check, 0, 0, 0);
-
- return vbox;
-}
-
-static void pcm_changed (GtkComboBox * combo, void * unused)
-{
- const char * new = combo_selected_text (pcm_combo, pcm_list);
-
- if (new == NULL || ! strcmp (new, alsa_config_pcm))
- return;
-
- str_unref (alsa_config_pcm);
- alsa_config_pcm = str_get (combo_selected_text (pcm_combo, pcm_list));
-
- aud_output_reset (OUTPUT_RESET_SOFT);
-}
-
-static void mixer_changed (GtkComboBox * combo, void * unused)
-{
- const char * new = combo_selected_text (mixer_combo, mixer_list);
-
- if (new == NULL || ! strcmp (new, alsa_config_mixer))
- return;
-
- str_unref (alsa_config_mixer);
- alsa_config_mixer = str_get (new);
-
- mixer_element_list_refill ();
- guess_mixer_element ();
- combo_select_by_text (mixer_element_combo, mixer_element_list,
- alsa_config_mixer_element);
-
- alsa_close_mixer ();
- alsa_open_mixer ();
-}
-
-static void mixer_element_changed (GtkComboBox * combo, void * unused)
-{
- const char * new = combo_selected_text (mixer_element_combo,
- mixer_element_list);
-
- if (new == NULL || (alsa_config_mixer_element != NULL && ! strcmp (new,
- alsa_config_mixer_element)))
- return;
-
- str_unref (alsa_config_mixer_element);
- alsa_config_mixer_element = str_get (new);
-
- alsa_close_mixer ();
- alsa_open_mixer ();
-}
-
-static void boolean_toggled (GtkToggleButton * button, void * data)
-{
- * (int *) data = gtk_toggle_button_get_active (button);
-}
-
-static void connect_callbacks (void)
-{
- g_signal_connect ((GObject *) pcm_combo, "changed", (GCallback) pcm_changed,
- NULL);
- g_signal_connect ((GObject *) mixer_combo, "changed", (GCallback)
- mixer_changed, NULL);
- g_signal_connect ((GObject *) mixer_element_combo, "changed", (GCallback)
- mixer_element_changed, NULL);
- g_signal_connect ((GObject *) drain_workaround_check, "toggled", (GCallback)
- boolean_toggled, & alsa_config_drain_workaround);
-}
-
-void * alsa_create_config_widget (void)
-{
- pcm_list_fill ();
- mixer_list_fill ();
- mixer_element_list_fill ();
-
- GtkWidget * vbox = create_vbox ();
-
- combo_select_by_text (pcm_combo, pcm_list, alsa_config_pcm);
- combo_select_by_text (mixer_combo, mixer_list, alsa_config_mixer);
- combo_select_by_text (mixer_element_combo, mixer_element_list,
- alsa_config_mixer_element);
-
- connect_callbacks ();
-
- return vbox;
-}
diff --git a/src/alsa/config.cc b/src/alsa/config.cc
new file mode 100644
index 000000000000..ffe95766a45b
--- /dev/null
+++ b/src/alsa/config.cc
@@ -0,0 +1,330 @@
+/*
+ * ALSA Output Plugin for Audacious
+ * Copyright 2009-2014 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <alsa/asoundlib.h>
+
+#include <libaudcore/hook.h>
+#include <libaudcore/preferences.h>
+
+#include "alsa.h"
+
+const char ALSAPlugin::about[] =
+ N_("ALSA Output Plugin for Audacious\n"
+ "Copyright 2009-2012 John Lindgren\n\n"
+ "My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
+ "code served as a reference when the ALSA manual was not enough.");
+
+struct NameDescPair {
+ String name, desc;
+};
+
+static Index<NameDescPair> pcm_list;
+static Index<NameDescPair> mixer_list;
+static Index<String> element_list;
+
+static Index<ComboItem> pcm_combo_items;
+static Index<ComboItem> mixer_combo_items;
+static Index<ComboItem> element_combo_items;
+
+static void get_defined_devices (const char * type,
+ void (* found) (const char * name, const char * description))
+{
+ void * * hints = nullptr;
+ CHECK (snd_device_name_hint, -1, type, & hints);
+
+ for (int i = 0; hints[i]; i ++)
+ {
+ char * type = snd_device_name_get_hint (hints[i], "IOID");
+
+ if (! type || ! strcmp (type, "Output"))
+ {
+ char * name = snd_device_name_get_hint (hints[i], "NAME");
+ char * description = snd_device_name_get_hint (hints[i], "DESC");
+
+ if (name && strcmp (name, "default"))
+ found (name, description ? description : _("(no description)"));
+
+ free (name);
+ free (description);
+ }
+
+ free (type);
+ }
+
+FAILED:
+ if (hints)
+ snd_device_name_free_hint (hints);
+}
+
+static char * get_card_description (int card)
+{
+ char * description = nullptr;
+ CHECK (snd_card_get_name, card, & description);
+
+FAILED:
+ return description;
+}
+
+static void get_cards (void (* found) (int card, const char * description))
+{
+ for (int card = -1;;)
+ {
+ CHECK (snd_card_next, & card);
+ if (card < 0)
+ break;
+
+ char * description = get_card_description (card);
+ if (description)
+ {
+ found (card, description);
+ free (description);
+ }
+ }
+
+FAILED:
+ return;
+}
+
+static String get_device_description (snd_ctl_t * control, int device)
+{
+ snd_pcm_info_t * info;
+ snd_pcm_info_alloca (& info);
+ snd_pcm_info_set_device (info, device);
+ snd_pcm_info_set_stream (info, SND_PCM_STREAM_PLAYBACK);
+
+ switch (snd_ctl_pcm_info (control, info))
+ {
+ case 0:
+ return String (snd_pcm_info_get_name (info));
+
+ case -ENOENT: /* capture device? */
+ return String ();
+ }
+
+ CHECK (snd_ctl_pcm_info, control, info);
+
+FAILED:
+ return String ();
+}
+
+static void get_devices (int card, void (* found) (const char * name, const char * description))
+{
+ snd_ctl_t * control = nullptr;
+ CHECK (snd_ctl_open, & control, str_printf ("hw:%d", card), 0);
+
+ for (int device = -1;;)
+ {
+ CHECK (snd_ctl_pcm_next_device, control, & device);
+ if (device < 0)
+ break;
+
+ StringBuf name = str_printf ("hw:%d,%d", card, device);
+ String description = get_device_description (control, device);
+
+ if (description)
+ found (name, description);
+ }
+
+FAILED:
+ if (control)
+ snd_ctl_close (control);
+}
+
+static void pcm_found (const char * name, const char * description)
+{
+ NameDescPair & pair = pcm_list.append (
+ String (name),
+ String (str_concat ({name, " â ", description}))
+ );
+
+ pcm_combo_items.append (pair.desc, pair.name);
+}
+
+static void pcm_card_found (int card, const char * description)
+{
+ get_devices (card, pcm_found);
+}
+
+static void pcm_list_fill ()
+{
+ pcm_found ("default", _("Default PCM device"));
+ get_defined_devices ("pcm", pcm_found);
+ get_cards (pcm_card_found);
+}
+
+static void mixer_found (const char * name, const char * description)
+{
+ NameDescPair & pair = mixer_list.append (
+ String (name),
+ String (str_concat ({name, " â ", description}))
+ );
+
+ mixer_combo_items.append (pair.desc, pair.name);
+}
+
+static void mixer_card_found (int card, const char * description)
+{
+ mixer_found (str_printf ("hw:%d", card), description);
+}
+
+static void mixer_list_fill ()
+{
+ mixer_found ("default", _("Default mixer device"));
+ get_defined_devices ("ctl", mixer_found);
+ get_cards (mixer_card_found);
+}
+
+static void get_elements (void (* found) (const char * name))
+{
+ snd_mixer_t * mixer_handle = nullptr;
+ CHECK (snd_mixer_open, & mixer_handle, 0);
+ CHECK (snd_mixer_attach, mixer_handle, aud_get_str ("alsa", "mixer"));
+ CHECK (snd_mixer_selem_register, mixer_handle, nullptr, nullptr);
+ CHECK (snd_mixer_load, mixer_handle);
+
+ for (snd_mixer_elem_t * element = snd_mixer_first_elem (mixer_handle);
+ element; element = snd_mixer_elem_next (element))
+ {
+ if (snd_mixer_selem_has_playback_volume (element))
+ found (snd_mixer_selem_get_name (element));
+ }
+
+FAILED:
+ if (mixer_handle)
+ snd_mixer_close (mixer_handle);
+}
+
+static void element_found (const char * name)
+{
+ String & str = element_list.append (String (name));
+ element_combo_items.append (str, str);
+}
+
+static void element_list_fill ()
+{
+ get_elements (element_found);
+}
+
+static void guess_element ()
+{
+ for (const char * guess : {"Master", "PCM", "Wave"})
+ {
+ for (const String & element : element_list)
+ {
+ if (! strcmp (element, guess))
+ {
+ aud_set_str ("alsa", "mixer-element", guess);
+ return;
+ }
+ }
+ }
+
+ ERROR_NOISY ("No suitable mixer element found.\n");
+}
+
+const char * const ALSAPlugin::defaults[] = {
+ "pcm", "default",
+ "mixer", "default",
+ nullptr
+};
+
+void ALSAPlugin::init_config ()
+{
+ aud_config_set_defaults ("alsa", defaults);
+
+ String element = aud_get_str ("alsa", "mixer-element");
+
+ if (! element[0])
+ {
+ element_list_fill ();
+ guess_element ();
+
+ element_list.clear ();
+ element_combo_items.clear ();
+ }
+}
+
+void ALSAPlugin::pcm_changed ()
+{
+ aud_output_reset (OutputReset::ReopenStream);
+}
+
+void ALSAPlugin::mixer_changed ()
+{
+ element_list.clear ();
+ element_combo_items.clear ();
+
+ element_list_fill ();
+ guess_element ();
+
+ hook_call ("alsa mixer changed", nullptr);
+
+ close_mixer ();
+ open_mixer ();
+}
+
+void ALSAPlugin::element_changed ()
+{
+ close_mixer ();
+ open_mixer ();
+}
+
+static ArrayRef<ComboItem> pcm_combo_fill ()
+ { return {pcm_combo_items.begin (), pcm_combo_items.len ()}; }
+static ArrayRef<ComboItem> mixer_combo_fill ()
+ { return {mixer_combo_items.begin (), mixer_combo_items.len ()}; }
+static ArrayRef<ComboItem> element_combo_fill ()
+ { return {element_combo_items.begin (), element_combo_items.len ()}; }
+
+const PreferencesWidget ALSAPlugin::widgets[] = {
+ WidgetCombo (N_("PCM device:"),
+ WidgetString ("alsa", "pcm", pcm_changed),
+ {nullptr, pcm_combo_fill}),
+ WidgetCombo (N_("Mixer device:"),
+ WidgetString ("alsa", "mixer", mixer_changed),
+ {nullptr, mixer_combo_fill}),
+ WidgetCombo (N_("Mixer element:"),
+ WidgetString ("alsa", "mixer-element", element_changed, "alsa mixer changed"),
+ {nullptr, element_combo_fill})
+};
+
+static void alsa_prefs_init ()
+{
+ pcm_list_fill ();
+ mixer_list_fill ();
+ element_list_fill ();
+}
+
+static void alsa_prefs_cleanup ()
+{
+ pcm_list.clear ();
+ mixer_list.clear ();
+ element_list.clear ();
+
+ pcm_combo_items.clear ();
+ mixer_combo_items.clear ();
+ element_combo_items.clear ();
+}
+
+const PluginPreferences ALSAPlugin::prefs = {
+ {widgets},
+ alsa_prefs_init,
+ nullptr, // apply
+ alsa_prefs_cleanup
+};
diff --git a/src/alsa/plugin.c b/src/alsa/plugin.c
deleted file mode 100644
index c54517f110c5..000000000000
--- a/src/alsa/plugin.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * ALSA Output Plugin for Audacious
- * Copyright 2009-2012 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-#include "alsa.h"
-
-static const char alsa_about[] =
- N_("ALSA Output Plugin for Audacious\n"
- "Copyright 2009-2012 John Lindgren\n\n"
- "My thanks to William Pitcock, author of the ALSA Output Plugin NG, whose "
- "code served as a reference when the ALSA manual was not enough.");
-
-static const PreferencesWidget alsa_widgets[] = {
- {WIDGET_CUSTOM, .data = {.populate = alsa_create_config_widget}}};
-
-static const PluginPreferences alsa_prefs = {
- .widgets = alsa_widgets,
- .n_widgets = ARRAY_LEN (alsa_widgets)};
-
-AUD_OUTPUT_PLUGIN
-(
- .name = N_("ALSA Output"),
- .domain = PACKAGE,
- .about_text = alsa_about,
- .probe_priority = 5,
- .init = alsa_init,
- .cleanup = alsa_cleanup,
- .open_audio = alsa_open_audio,
- .close_audio = alsa_close_audio,
- .buffer_free = alsa_buffer_free,
- .write_audio = alsa_write_audio,
- .period_wait = alsa_period_wait,
- .drain = alsa_drain,
- .output_time = alsa_output_time,
- .flush = alsa_flush,
- .pause = alsa_pause,
- .set_volume = alsa_set_volume,
- .get_volume = alsa_get_volume,
- .prefs = & alsa_prefs,
-)
diff --git a/src/amidi-plug/Makefile b/src/amidi-plug/Makefile
index 40edc8e1e180..dac6d08ee311 100644
--- a/src/amidi-plug/Makefile
+++ b/src/amidi-plug/Makefile
@@ -1,18 +1,19 @@
PLUGIN = amidi-plug${PLUGIN_SUFFIX}
-SRCS = amidi-plug.c \
- backend-fluidsynth/b-fluidsynth.c \
- i_midi.c \
- i_configure.c \
- i_configure-fluidsynth.c \
- i_utils.c \
- i_fileinfo.c
+SRCS = amidi-plug.cc \
+ backend-fluidsynth/b-fluidsynth.cc \
+ i_midi.cc \
+ i_configure.cc \
+ i_configure-fluidsynth.cc \
+ i_fileinfo.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${FLUIDSYNTH_CFLAGS} -I../..
LIBS += ${GTK_LIBS} ${FLUIDSYNTH_LIBS} -lm
diff --git a/src/amidi-plug/amidi-plug.c b/src/amidi-plug/amidi-plug.c
deleted file mode 100644
index 9c765eff2616..000000000000
--- a/src/amidi-plug/amidi-plug.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <audacious/debug.h>
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-
-#include "i_backend.h"
-#include "i_configure.h"
-#include "i_fileinfo.h"
-#include "i_midi.h"
-#include "i_utils.h"
-
-enum
-{
- AMIDIPLUG_STOP,
- AMIDIPLUG_PLAY,
- AMIDIPLUG_ERR
-};
-
-static void amidiplug_play_loop (void);
-
-static bool_t amidiplug_play (const char * filename_uri, VFSFile * file);
-static Tuple * amidiplug_get_song_tuple (const char * filename_uri, VFSFile * file);
-static void amidiplug_skipto (int playing_tick);
-
-static midifile_t midifile;
-
-static const char * const amidiplug_vfs_extensions[] = {"mid", "midi", "rmi", "rmid", NULL};
-
-static void amidiplug_cleanup (void)
-{
- backend_cleanup ();
-}
-
-static bool_t amidiplug_init (void)
-{
- static const char * const defaults[] =
- {
- "ap_opts_transpose_value", "0",
- "ap_opts_drumshift_value", "0",
- "ap_opts_lyrics_extract", "0",
- "ap_opts_comments_extract", "0",
- "fsyn_synth_samplerate", "44100",
- "fsyn_synth_gain", "-1",
- "fsyn_synth_polyphony", "-1",
- "fsyn_synth_reverb", "-1",
- "fsyn_synth_chorus", "-1",
- NULL
- };
-
- aud_config_set_defaults ("amidiplug", defaults);
-
- backend_init ();
-
- return TRUE;
-}
-
-static int amidiplug_is_our_file_from_vfs (const char * filename_uri, VFSFile * fp)
-{
- char magic_bytes[4];
-
- if (fp == NULL)
- return FALSE;
-
- if (vfs_fread (magic_bytes, 1, 4, fp) != 4)
- return FALSE;
-
- if (!strncmp (magic_bytes, "MThd", 4))
- {
- AUDDBG ("MIDI found, %s is a standard midi file\n", filename_uri);
- return TRUE;
- }
-
- if (!strncmp (magic_bytes, "RIFF", 4))
- {
- /* skip the four bytes after RIFF,
- then read the next four */
- if (vfs_fseek (fp, 4, SEEK_CUR) != 0)
- return FALSE;
-
- if (vfs_fread (magic_bytes, 1, 4, fp) != 4)
- return FALSE;
-
- if (!strncmp (magic_bytes, "RMID", 4))
- {
- AUDDBG ("MIDI found, %s is a riff midi file\n", filename_uri);
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static Tuple * amidiplug_get_song_tuple (const char * filename_uri, VFSFile *
- file)
-{
- /* song title, get it from the filename */
- Tuple * tuple = tuple_new_from_filename (filename_uri);
- midifile_t mf;
-
- if (i_midi_parse_from_filename (filename_uri, &mf))
- tuple_set_int (tuple, FIELD_LENGTH, mf.length / 1000);
-
- i_midi_free (&mf);
-
- return tuple;
-}
-
-
-static int s_samplerate, s_channels;
-static int s_bufsize;
-static void * s_buf;
-
-static bool_t audio_init (void)
-{
- int bitdepth;
-
- backend_audio_info (& s_channels, & bitdepth, & s_samplerate);
-
- if (bitdepth != 16 || ! aud_input_open_audio (FMT_S16_NE, s_samplerate, s_channels))
- return FALSE;
-
- s_bufsize = 2 * s_channels * (s_samplerate / 4);
- s_buf = g_malloc (s_bufsize);
-
- return TRUE;
-}
-
-static void audio_generate (double seconds)
-{
- int total = 2 * s_channels * (int) round (seconds * s_samplerate);
-
- while (total)
- {
- int chunk = (total < s_bufsize) ? total : s_bufsize;
-
- backend_generate_audio (s_buf, chunk);
- aud_input_write_audio (s_buf, chunk);
-
- total -= chunk;
- }
-}
-
-static void audio_cleanup (void)
-{
- g_free (s_buf);
-}
-
-static bool_t amidiplug_play (const char * filename_uri, VFSFile * file)
-{
- if (g_atomic_int_compare_and_exchange (& backend_settings_changed, TRUE, FALSE))
- {
- AUDDBG ("Settings changed, reinitializing backend\n");
- backend_cleanup ();
- backend_init ();
- }
-
- if (! audio_init ())
- return FALSE;
-
- AUDDBG ("PLAY requested, midifile init\n");
- /* midifile init */
- i_midi_init (&midifile);
-
- AUDDBG ("PLAY requested, opening file: %s\n", filename_uri);
- midifile.file_pointer = file;
- midifile.file_name = g_strdup (filename_uri);
-
- switch (i_midi_file_read_id (&midifile))
- {
- case MAKE_ID ('R', 'I', 'F', 'F') :
- AUDDBG ("PLAY requested, RIFF chunk found, processing...\n");
-
- /* read riff chunk */
- if (!i_midi_file_parse_riff (&midifile))
- {
- fprintf (stderr, "%s: invalid file format (riff parser)\n", filename_uri);
- goto ERR;
- }
-
- /* if that was read correctly, go ahead and read smf data */
-
- case MAKE_ID ('M', 'T', 'h', 'd') :
- AUDDBG ("PLAY requested, MThd chunk found, processing...\n");
-
- if (!i_midi_file_parse_smf (&midifile, 1))
- {
- fprintf (stderr, "%s: invalid file format (smf parser)\n", filename_uri);
- goto ERR;
- }
-
- if (midifile.time_division < 1)
- {
- fprintf (stderr, "%s: invalid time division (%i)\n", filename_uri, midifile.time_division);
- goto ERR;
- }
-
- AUDDBG ("PLAY requested, setting ppq and tempo...\n");
-
- /* fill midifile.ppq and midifile.tempo using time_division */
- if (!i_midi_setget_tempo (&midifile))
- {
- fprintf (stderr, "%s: invalid values while setting ppq and tempo\n", filename_uri);
- goto ERR;
- }
-
- /* fill midifile.length, keeping in count tempo-changes */
- i_midi_setget_length (&midifile);
- AUDDBG ("PLAY requested, song length calculated: %i msec\n", (int) (midifile.length / 1000));
-
- /* done with file */
- midifile.file_pointer = NULL;
-
- /* play play play! */
- AUDDBG ("PLAY requested, starting play thread\n");
- amidiplug_play_loop ();
- break;
-
- default:
- fprintf (stderr, "%s is not a Standard MIDI File\n", filename_uri);
- goto ERR;
- }
-
- audio_cleanup ();
- return TRUE;
-
-ERR:
- audio_cleanup ();
- return FALSE;
-}
-
-static void generate_to_tick (int tick)
-{
- double ticksecs = (double) midifile.current_tempo / midifile.ppq / 1000000;
- audio_generate (ticksecs * (tick - midifile.playing_tick));
- midifile.playing_tick = tick;
-}
-
-static void amidiplug_play_loop ()
-{
- bool_t stopped = FALSE;
-
- backend_prepare ();
-
- /* initialize current position in each track */
- for (int j = 0; j < midifile.num_tracks; ++j)
- midifile.tracks[j].current_event = midifile.tracks[j].first_event;
-
- while (! (stopped = aud_input_check_stop ()))
- {
- int seektime = aud_input_check_seek ();
- if (seektime >= 0)
- amidiplug_skipto ((int64_t) seektime * 1000 / midifile.avg_microsec_per_tick);
-
- midievent_t * event = NULL;
- midifile_track_t * event_track = NULL;
- int i, min_tick = midifile.max_tick + 1;
-
- /* search next event */
- for (i = 0; i < midifile.num_tracks; ++i)
- {
- midifile_track_t * track = &midifile.tracks[i];
- midievent_t * e2 = track->current_event;
-
- if ((e2) && (e2->tick < min_tick))
- {
- min_tick = e2->tick;
- event = e2;
- event_track = track;
- }
- }
-
- if (!event)
- break; /* end of song reached */
-
- /* advance pointer to next event */
- event_track->current_event = event->next;
-
- if (event->tick > midifile.playing_tick)
- generate_to_tick (event->tick);
-
- switch (event->type)
- {
- case SND_SEQ_EVENT_NOTEON:
- seq_event_noteon (event);
- break;
-
- case SND_SEQ_EVENT_NOTEOFF:
- seq_event_noteoff (event);
- break;
-
- case SND_SEQ_EVENT_KEYPRESS:
- seq_event_keypress (event);
- break;
-
- case SND_SEQ_EVENT_CONTROLLER:
- seq_event_controller (event);
- break;
-
- case SND_SEQ_EVENT_PGMCHANGE:
- seq_event_pgmchange (event);
- break;
-
- case SND_SEQ_EVENT_CHANPRESS:
- seq_event_chanpress (event);
- break;
-
- case SND_SEQ_EVENT_PITCHBEND:
- seq_event_pitchbend (event);
- break;
-
- case SND_SEQ_EVENT_SYSEX:
- seq_event_sysex (event);
- break;
-
- case SND_SEQ_EVENT_TEMPO:
- seq_event_tempo (event);
- AUDDBG ("PLAY thread, processing tempo event with value %i on tick %i\n",
- event->data.tempo, event->tick);
- midifile.current_tempo = event->data.tempo;
- break;
-
- case SND_SEQ_EVENT_META_TEXT:
- /* do nothing */
- break;
-
- case SND_SEQ_EVENT_META_LYRIC:
- /* do nothing */
- break;
-
- default:
- AUDDBG ("PLAY thread, encountered invalid event type %i\n", event->type);
- break;
- }
- }
-
- if (! stopped)
- generate_to_tick (midifile.max_tick);
-
- backend_reset ();
-
- i_midi_free (& midifile);
-}
-
-
-/* amidigplug_skipto: re-do all events that influence the playing of our
- midi file; re-do them using a time-tick of 0, so they are processed
- istantaneously and proceed this way until the playing_tick is reached */
-static void amidiplug_skipto (int playing_tick)
-{
- backend_reset ();
-
- /* this check is always made, for safety*/
- if (playing_tick >= midifile.max_tick)
- playing_tick = midifile.max_tick - 1;
-
- /* initialize current position in each track */
- for (int i = 0; i < midifile.num_tracks; ++i)
- midifile.tracks[i].current_event = midifile.tracks[i].first_event;
-
- for (;;)
- {
- midievent_t * event = NULL;
- midifile_track_t * event_track = NULL;
- int i, min_tick = midifile.max_tick + 1;
-
- /* search next event */
- for (i = 0; i < midifile.num_tracks; ++i)
- {
- midifile_track_t * track = &midifile.tracks[i];
- midievent_t * e2 = track->current_event;
-
- if ((e2) && (e2->tick < min_tick))
- {
- min_tick = e2->tick;
- event = e2;
- event_track = track;
- }
- }
-
- /* unlikely here... unless very strange MIDI files are played :) */
- if (!event)
- {
- AUDDBG ("SKIPTO request, reached the last event but not the requested tick (!)\n");
- break; /* end of song reached */
- }
-
- /* reached the requested tick, job done */
- if (event->tick >= playing_tick)
- {
- AUDDBG ("SKIPTO request, reached the requested tick, exiting from skipto loop\n");
- break;
- }
-
- /* advance pointer to next event */
- event_track->current_event = event->next;
-
- switch (event->type)
- {
- /* do nothing for these
- case SND_SEQ_EVENT_NOTEON:
- case SND_SEQ_EVENT_NOTEOFF:
- case SND_SEQ_EVENT_KEYPRESS:
- {
- break;
- } */
- case SND_SEQ_EVENT_CONTROLLER:
- seq_event_controller (event);
- break;
-
- case SND_SEQ_EVENT_PGMCHANGE:
- seq_event_pgmchange (event);
- break;
-
- case SND_SEQ_EVENT_CHANPRESS:
- seq_event_chanpress (event);
- break;
-
- case SND_SEQ_EVENT_PITCHBEND:
- seq_event_pitchbend (event);
- break;
-
- case SND_SEQ_EVENT_SYSEX:
- seq_event_sysex (event);
- break;
-
- case SND_SEQ_EVENT_TEMPO:
- seq_event_tempo (event);
- midifile.current_tempo = event->data.tempo;
- break;
- }
- }
-
- midifile.playing_tick = playing_tick;
-}
-
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("AMIDI-Plug (MIDI Player)"),
- .domain = PACKAGE,
- .init = amidiplug_init,
- .about = i_about_gui,
- .prefs = & amidiplug_prefs,
- .play = amidiplug_play,
- .cleanup = amidiplug_cleanup,
- .probe_for_tuple = amidiplug_get_song_tuple,
- .file_info_box = i_fileinfo_gui,
- .is_our_file_from_vfs = amidiplug_is_our_file_from_vfs,
- .extensions = amidiplug_vfs_extensions,
-)
diff --git a/src/amidi-plug/amidi-plug.cc b/src/amidi-plug/amidi-plug.cc
new file mode 100644
index 000000000000..fcb3b9d44390
--- /dev/null
+++ b/src/amidi-plug/amidi-plug.cc
@@ -0,0 +1,450 @@
+/*
+*
+* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+*/
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libaudcore/runtime.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+
+#include "i_backend.h"
+#include "i_configure.h"
+#include "i_fileinfo.h"
+#include "i_midi.h"
+
+class AMIDIPlug : public InputPlugin
+{
+public:
+ static const char about[];
+ static const char * const exts[];
+
+ static constexpr PluginInfo info = {
+ N_("AMIDI-Plug (MIDI Player)"),
+ PACKAGE,
+ about,
+ & amidiplug_prefs
+ };
+
+ static constexpr auto iinfo = InputInfo ()
+ .with_exts (exts);
+
+ constexpr AMIDIPlug () : InputPlugin (info, iinfo) {}
+
+ bool init ();
+ void cleanup ();
+
+ bool is_our_file (const char * filename, VFSFile & file);
+ Tuple read_tuple (const char * filename, VFSFile & file);
+ bool play (const char * filename, VFSFile & file);
+
+ bool file_info_box (const char * filename, VFSFile & file)
+ { i_fileinfo_gui (filename, file); return true; }
+
+protected:
+ bool m_backend_initialized = false;
+
+ static bool audio_init ();
+ static void audio_generate (double seconds);
+ static void audio_cleanup ();
+
+ static void generate_ticks (midifile_t & midifile, int num_ticks);
+ static void play_loop (midifile_t & midifile);
+ static int skip_to (midifile_t & midifile, int seektime);
+};
+
+EXPORT AMIDIPlug aud_plugin_instance;
+
+const char * const AMIDIPlug::exts[] = {"mid", "midi", "rmi", "rmid", nullptr};
+
+void AMIDIPlug::cleanup ()
+{
+ if (m_backend_initialized)
+ {
+ backend_cleanup ();
+ m_backend_initialized = false;
+ }
+}
+
+bool AMIDIPlug::init ()
+{
+ static const char * const defaults[] =
+ {
+ "ap_opts_transpose_value", "0",
+ "ap_opts_drumshift_value", "0",
+ "fsyn_synth_samplerate", "44100",
+ "fsyn_synth_gain", "-1",
+ "fsyn_synth_polyphony", "-1",
+ "fsyn_synth_reverb", "-1",
+ "fsyn_synth_chorus", "-1",
+ "skip_leading", "FALSE",
+ "skip_trailing", "FALSE",
+ nullptr
+ };
+
+ aud_config_set_defaults ("amidiplug", defaults);
+
+ return true;
+}
+
+bool AMIDIPlug::is_our_file (const char * filename, VFSFile & file)
+{
+ char magic_bytes[4];
+
+ if (file.fread (magic_bytes, 1, 4) != 4)
+ return false;
+
+ if (!strncmp (magic_bytes, "MThd", 4))
+ {
+ AUDDBG ("MIDI found, %s is a standard midi file\n", filename);
+ return true;
+ }
+
+ if (!strncmp (magic_bytes, "RIFF", 4))
+ {
+ /* skip the four bytes after RIFF,
+ then read the next four */
+ if (file.fseek (4, VFS_SEEK_CUR) != 0)
+ return false;
+
+ if (file.fread (magic_bytes, 1, 4) != 4)
+ return false;
+
+ if (!strncmp (magic_bytes, "RMID", 4))
+ {
+ AUDDBG ("MIDI found, %s is a riff midi file\n", filename);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+Tuple AMIDIPlug::read_tuple (const char * filename, VFSFile & file)
+{
+ /* song title, get it from the filename */
+ Tuple tuple;
+ tuple.set_filename (filename);
+ tuple.set_str (Tuple::Codec, "MIDI");
+
+ midifile_t mf;
+
+ if (mf.parse_from_file (filename, file))
+ tuple.set_int (Tuple::Length, mf.length / 1000);
+
+ return tuple;
+}
+
+
+static int s_samplerate, s_channels;
+static int s_bufsize;
+static int16_t * s_buf;
+
+bool AMIDIPlug::audio_init ()
+{
+ int bitdepth;
+
+ backend_audio_info (& s_channels, & bitdepth, & s_samplerate);
+
+ if (bitdepth != 16)
+ return false;
+
+ open_audio (FMT_S16_NE, s_samplerate, s_channels);
+
+ s_bufsize = 2 * s_channels * (s_samplerate / 4);
+ s_buf = new int16_t[s_bufsize / 2];
+
+ return true;
+}
+
+void AMIDIPlug::audio_generate (double seconds)
+{
+ int total = 2 * s_channels * (int) round (seconds * s_samplerate);
+
+ while (total)
+ {
+ int chunk = (total < s_bufsize) ? total : s_bufsize;
+
+ backend_generate_audio (s_buf, chunk);
+ write_audio (s_buf, chunk);
+
+ total -= chunk;
+ }
+}
+
+void AMIDIPlug::audio_cleanup ()
+{
+ delete[] s_buf;
+}
+
+bool AMIDIPlug::play (const char * filename, VFSFile & file)
+{
+ if (__sync_bool_compare_and_swap (& backend_settings_changed, true, false)
+ && m_backend_initialized)
+ {
+ AUDDBG ("Settings changed, reinitializing backend\n");
+ backend_cleanup ();
+ m_backend_initialized = false;
+ }
+
+ if (! m_backend_initialized)
+ {
+ backend_init ();
+ m_backend_initialized = true;
+ }
+
+ if (! audio_init ())
+ return false;
+
+ AUDDBG ("PLAY requested, midifile init\n");
+ /* midifile init */
+ midifile_t midifile;
+
+ if (! midifile.parse_from_file (filename, file))
+ {
+ audio_cleanup ();
+ return false;
+ }
+
+ AUDDBG ("PLAY requested, starting play thread\n");
+ play_loop (midifile);
+
+ audio_cleanup ();
+ return true;
+}
+
+void AMIDIPlug::generate_ticks (midifile_t & midifile, int num_ticks)
+{
+ double ticksecs = (double) midifile.current_tempo / midifile.ppq / 1000000;
+ audio_generate (ticksecs * num_ticks);
+}
+
+void AMIDIPlug::play_loop (midifile_t & midifile)
+{
+ int tick = midifile.start_tick;
+ bool stopped = false;
+
+ /* initialize current position in each track */
+ for (midifile_track_t & track : midifile.tracks)
+ track.current_event = track.events.head ();
+
+ while (! (stopped = check_stop ()))
+ {
+ int seektime = check_seek ();
+ if (seektime >= 0)
+ tick = skip_to (midifile, seektime);
+
+ midievent_t * event = nullptr;
+ midifile_track_t * event_track = nullptr;
+ int min_tick = midifile.max_tick + 1;
+
+ /* search next event */
+ for (midifile_track_t & track : midifile.tracks)
+ {
+ midievent_t * e2 = track.current_event;
+
+ if ((e2) && (e2->tick < min_tick))
+ {
+ min_tick = e2->tick;
+ event = e2;
+ event_track = & track;
+ }
+ }
+
+ if (!event)
+ break; /* end of song reached */
+
+ /* advance pointer to next event */
+ event_track->current_event = event_track->events.next (event);
+
+ if (event->tick > tick)
+ {
+ generate_ticks (midifile, event->tick - tick);
+ tick = event->tick;
+ }
+
+ switch (event->type)
+ {
+ case SND_SEQ_EVENT_NOTEON:
+ seq_event_noteon (event);
+ break;
+
+ case SND_SEQ_EVENT_NOTEOFF:
+ seq_event_noteoff (event);
+ break;
+
+ case SND_SEQ_EVENT_KEYPRESS:
+ seq_event_keypress (event);
+ break;
+
+ case SND_SEQ_EVENT_CONTROLLER:
+ seq_event_controller (event);
+ break;
+
+ case SND_SEQ_EVENT_PGMCHANGE:
+ seq_event_pgmchange (event);
+ break;
+
+ case SND_SEQ_EVENT_CHANPRESS:
+ seq_event_chanpress (event);
+ break;
+
+ case SND_SEQ_EVENT_PITCHBEND:
+ seq_event_pitchbend (event);
+ break;
+
+ case SND_SEQ_EVENT_SYSEX:
+ seq_event_sysex (event);
+ break;
+
+ case SND_SEQ_EVENT_TEMPO:
+ seq_event_tempo (event);
+ AUDDBG ("PLAY thread, processing tempo event with value %i on tick %i\n",
+ event->tempo, event->tick);
+ midifile.current_tempo = event->tempo;
+ break;
+
+ case SND_SEQ_EVENT_META_TEXT:
+ /* do nothing */
+ break;
+
+ case SND_SEQ_EVENT_META_LYRIC:
+ /* do nothing */
+ break;
+
+ default:
+ AUDDBG ("PLAY thread, encountered invalid event type %i\n", event->type);
+ break;
+ }
+ }
+
+ if (! stopped)
+ generate_ticks (midifile, midifile.max_tick - tick);
+
+ backend_reset ();
+}
+
+
+/* amidigplug_skipto: re-do all events that influence the playing of our
+ midi file; re-do them using a time-tick of 0, so they are processed
+ istantaneously and proceed this way until the playing_tick is reached */
+int AMIDIPlug::skip_to (midifile_t & midifile, int seektime)
+{
+ backend_reset ();
+
+ int tick = midifile.start_tick;
+ if (midifile.avg_microsec_per_tick > 0)
+ tick += (int64_t) seektime * 1000 / midifile.avg_microsec_per_tick;
+
+ /* initialize current position in each track */
+ for (midifile_track_t & track : midifile.tracks)
+ track.current_event = track.events.head ();
+
+ for (;;)
+ {
+ midievent_t * event = nullptr;
+ midifile_track_t * event_track = nullptr;
+ int min_tick = midifile.max_tick + 1;
+
+ /* search next event */
+ for (midifile_track_t & track : midifile.tracks)
+ {
+ midievent_t * e2 = track.current_event;
+
+ if ((e2) && (e2->tick < min_tick))
+ {
+ min_tick = e2->tick;
+ event = e2;
+ event_track = & track;
+ }
+ }
+
+ /* unlikely here... unless very strange MIDI files are played :) */
+ if (!event)
+ {
+ AUDDBG ("SKIPTO request, reached the last event but not the requested tick (!)\n");
+ break; /* end of song reached */
+ }
+
+ /* reached the requested tick, job done */
+ if (event->tick >= tick)
+ {
+ AUDDBG ("SKIPTO request, reached the requested tick, exiting from skipto loop\n");
+ break;
+ }
+
+ /* advance pointer to next event */
+ event_track->current_event = event_track->events.next (event);
+
+ switch (event->type)
+ {
+ /* do nothing for these
+ case SND_SEQ_EVENT_NOTEON:
+ case SND_SEQ_EVENT_NOTEOFF:
+ case SND_SEQ_EVENT_KEYPRESS:
+ {
+ break;
+ } */
+ case SND_SEQ_EVENT_CONTROLLER:
+ seq_event_controller (event);
+ break;
+
+ case SND_SEQ_EVENT_PGMCHANGE:
+ seq_event_pgmchange (event);
+ break;
+
+ case SND_SEQ_EVENT_CHANPRESS:
+ seq_event_chanpress (event);
+ break;
+
+ case SND_SEQ_EVENT_PITCHBEND:
+ seq_event_pitchbend (event);
+ break;
+
+ case SND_SEQ_EVENT_SYSEX:
+ seq_event_sysex (event);
+ break;
+
+ case SND_SEQ_EVENT_TEMPO:
+ seq_event_tempo (event);
+ midifile.current_tempo = event->tempo;
+ break;
+ }
+ }
+
+ return tick;
+}
+
+const char AMIDIPlug::about[] =
+ N_("AMIDI-Plug\n"
+ "modular MIDI music player\n"
+ "http://www.develia.org/projects.php?p=amidiplug\n\n"
+ "written by Giacomo Lozito\n"
+ "<james at develia.org>\n\n"
+ "special thanks to...\n\n"
+ "Clemens Ladisch and Jaroslav Kysela\n"
+ "for their cool programs aplaymidi and amixer; those\n"
+ "were really useful, along with alsa-lib docs, in order\n"
+ "to learn more about the ALSA API\n\n"
+ "Alfredo Spadafina\n"
+ "for the nice midi keyboard logo\n\n"
+ "Tony Vroon\n"
+ "for the good help with alpha testing");
diff --git a/src/amidi-plug/amidi-plug.logo.xpm b/src/amidi-plug/amidi-plug.logo.xpm
deleted file mode 100644
index e165582687a6..000000000000
--- a/src/amidi-plug/amidi-plug.logo.xpm
+++ /dev/null
@@ -1,743 +0,0 @@
-/* XPM */
-static char * amidiplug_xpm_logo[] = {
-"398 123 617 2",
-" c #FFFFFF",
-". c #FCFCFC",
-"+ c #FAFAFA",
-"@ c #F9F9F9",
-"# c #F8F8F8",
-"$ c #F7F7F7",
-"% c #F5F5F5",
-"& c #F4F4F4",
-"* c #F3F3F3",
-"= c #F1F1F1",
-"- c #EFEFEF",
-"; c #EEEEEE",
-"> c #F0F0F0",
-", c #EDEDED",
-"' c #EBEBEB",
-") c #EAEAEA",
-"! c #E9E9E9",
-"~ c #E8E8E8",
-"{ c #E3E3E3",
-"] c #E2E2E2",
-"^ c #E0E0E0",
-"/ c #DEDEDE",
-"( c #E4E4E4",
-"_ c #DADADA",
-": c #5C5C5C",
-"< c #4B4B4B",
-"[ c #4A4A4A",
-"} c #464646",
-"| c #454545",
-"1 c #414141",
-"2 c #404040",
-"3 c #3C3C3C",
-"4 c #383838",
-"5 c #373737",
-"6 c #393939",
-"7 c #3A3A3A",
-"8 c #3B3B3B",
-"9 c #363636",
-"0 c #3D3D3D",
-"a c #3E3E3E",
-"b c #3F3F3F",
-"c c #424242",
-"d c #434343",
-"e c #444444",
-"f c #474747",
-"g c #484848",
-"h c #494949",
-"i c #4C4C4C",
-"j c #4D4D4D",
-"k c #4E4E4E",
-"l c #343434",
-"m c #333333",
-"n c #323232",
-"o c #313131",
-"p c #303030",
-"q c #2F2F2F",
-"r c #2E2E2E",
-"s c #2D2D2D",
-"t c #2C2C2C",
-"u c #2B2B2B",
-"v c #2A2A2A",
-"w c #292929",
-"x c #282828",
-"y c #272727",
-"z c #262626",
-"A c #252525",
-"B c #1E1E1E",
-"C c #1C1C1C",
-"D c #1B1B1B",
-"E c #1A1A1A",
-"F c #181818",
-"G c #161616",
-"H c #202020",
-"I c #A0A0A0",
-"J c #FEFEFE",
-"K c #747474",
-"L c #000000",
-"M c #010101",
-"N c #020202",
-"O c #030303",
-"P c #040404",
-"Q c #050505",
-"R c #060606",
-"S c #070707",
-"T c #080808",
-"U c #090909",
-"V c #0A0A0A",
-"W c #0C0C0C",
-"X c #0D0D0D",
-"Y c #0E0E0E",
-"Z c #0F0F0F",
-"` c #101010",
-" . c #111111",
-".. c #121212",
-"+. c #131313",
-"@. c #141414",
-"#. c #151515",
-"$. c #171717",
-"%. c #191919",
-"&. c #1D1D1D",
-"*. c #1F1F1F",
-"=. c #DFDFDF",
-"-. c #232323",
-";. c #252523",
-">. c #2B2B28",
-",. c #2C2C29",
-"'. c #2C2C2A",
-"). c #2D2D2A",
-"!. c #2D2D2B",
-"~. c #2E2E2B",
-"{. c #2E2E2C",
-"]. c #2F2F2C",
-"^. c #30302D",
-"/. c #242423",
-"(. c #272723",
-"_. c #272724",
-":. c #282824",
-"<. c #292925",
-"[. c #292926",
-"}. c #2A2A26",
-"|. c #2D2D28",
-"1. c #2E2E2A",
-"2. c #2F2F2A",
-"3. c #30302B",
-"4. c #2E302F",
-"5. c #2E3131",
-"6. c #303333",
-"7. c #313434",
-"8. c #303434",
-"9. c #2F312F",
-"0. c #2E2E29",
-"a. c #2C2C28",
-"b. c #2C2C27",
-"c. c #2B2B26",
-"d. c #2C2C26",
-"e. c #2E2E28",
-"f. c #2E2E27",
-"g. c #2D2D27",
-"h. c #1E1E1B",
-"i. c #282825",
-"j. c #33332F",
-"k. c #32322F",
-"l. c #32322E",
-"m. c #31312E",
-"n. c #30302C",
-"o. c #242422",
-"p. c #A4A4A4",
-"q. c #868686",
-"r. c #0B0B0B",
-"s. c #171716",
-"t. c #A2A295",
-"u. c #BEBEAE",
-"v. c #BEBEAF",
-"w. c #BEBEB0",
-"x. c #BFBFB0",
-"y. c #C0C0B0",
-"z. c #C0C0B2",
-"A. c #C1C1B2",
-"B. c #C2C2B2",
-"C. c #7E7E74",
-"D. c #5F5F4F",
-"E. c #B9B998",
-"F. c #BCBC99",
-"G. c #BCBC9A",
-"H. c #BDBD9A",
-"I. c #BEBE9A",
-"J. c #BEBE9B",
-"K. c #C1C19E",
-"L. c #C2C29E",
-"M. c #C3C39F",
-"N. c #9EAA9F",
-"O. c #92A4A4",
-"P. c #92A5A5",
-"Q. c #93A6A6",
-"R. c #94A6A6",
-"S. c #A8B3A3",
-"T. c #C4C4A0",
-"U. c #C5C5A0",
-"V. c #C6C6A1",
-"W. c #C6C6A0",
-"X. c #C7C7A1",
-"Y. c #C9C9A2",
-"Z. c #7C7C65",
-"`. c #949487",
-" + c #CDCDBC",
-".+ c #CDCDBB",
-"++ c #A3A394",
-"@+ c #0B0B0A",
-"#+ c #191918",
-"$+ c #8B8B80",
-"%+ c #9E9E92",
-"&+ c #9F9F92",
-"*+ c #A0A093",
-"=+ c #A0A094",
-"-+ c #A1A194",
-";+ c #67675F",
-">+ c #686857",
-",+ c #D2D2AB",
-"'+ c #D3D3AC",
-")+ c #D4D4AD",
-"!+ c #D5D5AD",
-"~+ c #D5D5AE",
-"{+ c #D6D6AE",
-"]+ c #D6D6AF",
-"^+ c #D7D7AF",
-"/+ c #AEB6A0",
-"(+ c #9AA69A",
-"_+ c #9AA698",
-":+ c #9AA699",
-"<+ c #B5BCA3",
-"[+ c #DBDBB1",
-"}+ c #DADAB1",
-"|+ c #DBDBB0",
-"1+ c #DADAB0",
-"2+ c #969679",
-"3+ c #6C6C64",
-"4+ c #9E9E91",
-"5+ c #9E9E90",
-"6+ c #99998C",
-"7+ c #98988B",
-"8+ c #848478",
-"9+ c #111110",
-"0+ c #B0B0B0",
-"a+ c #959595",
-"b+ c #0C0C0E",
-"c+ c #0E0E10",
-"d+ c #131314",
-"e+ c #696957",
-"f+ c #D8D8B0",
-"g+ c #D6D6AD",
-"h+ c #D7D7AE",
-"i+ c #D8D8AF",
-"j+ c #DBDBB2",
-"k+ c #DCDCB2",
-"l+ c #DCDCB1",
-"m+ c #A8A888",
-"n+ c #0F0F11",
-"o+ c #0E0E0F",
-"p+ c #0A0A0C",
-"q+ c #09090A",
-"r+ c #080809",
-"s+ c #070708",
-"t+ c #060608",
-"u+ c #0B0B0C",
-"v+ c #181817",
-"w+ c #1C1C1B",
-"x+ c #6F6F5C",
-"y+ c #D7D7B0",
-"z+ c #D9D9B0",
-"A+ c #D9D9B1",
-"B+ c #DADAB2",
-"C+ c #B9B995",
-"D+ c #161615",
-"E+ c #161614",
-"F+ c #141413",
-"G+ c #C0C0C0",
-"H+ c #A5A5A5",
-"I+ c #A4A497",
-"J+ c #AAAA9C",
-"K+ c #AAAA9D",
-"L+ c #ABAB9D",
-"M+ c #ACAC9E",
-"N+ c #ACAC9F",
-"O+ c #ADAD9F",
-"P+ c #AEAEA0",
-"Q+ c #5B5B54",
-"R+ c #777762",
-"S+ c #DCDCB3",
-"T+ c #DDDDB3",
-"U+ c #DDDDB2",
-"V+ c #C5C59F",
-"W+ c #4F4F46",
-"X+ c #B6B6A6",
-"Y+ c #BABAAA",
-"Z+ c #B9B9AA",
-"`+ c #B8B8A8",
-" @ c #4F4F49",
-".@ c #595959",
-"+@ c #3C3C39",
-"@@ c #BCBCAD",
-"#@ c #BDBDAE",
-"$@ c #C0C0B1",
-"%@ c #5B5B55",
-"&@ c #808069",
-"*@ c #DBDBB3",
-"=@ c #DCDCB4",
-"-@ c #DDDDB4",
-";@ c #DEDEB4",
-">@ c #CECEA6",
-",@ c #57574C",
-"'@ c #BDBDAC",
-")@ c #C4C4B3",
-"!@ c #C3C3B2",
-"~@ c #63635B",
-"{@ c #CBCBCB",
-"]@ c #ABABAB",
-"^@ c #282826",
-"/@ c #292927",
-"(@ c #2A2A28",
-"_@ c #2B2B29",
-":@ c #84846C",
-"<@ c #D6D6B0",
-"[@ c #DEDEB3",
-"}@ c #DEDEB2",
-"|@ c #D5D5AC",
-"1@ c #3F3F36",
-"2@ c #232321",
-"3@ c #222220",
-"4@ c #212120",
-"5@ c #21211F",
-"6@ c #20201E",
-"7@ c #1F1F1D",
-"8@ c #6B6B6B",
-"9@ c #FBFBFB",
-"0@ c #515144",
-"a@ c #80806A",
-"b@ c #81816A",
-"c@ c #81816B",
-"d@ c #82826B",
-"e@ c #82826C",
-"f@ c #83836C",
-"g@ c #84846D",
-"h@ c #84846E",
-"i@ c #85856E",
-"j@ c #86866E",
-"k@ c #85856D",
-"l@ c #7E7E67",
-"m@ c #7E7E66",
-"n@ c #7D7D66",
-"o@ c #7A7A63",
-"p@ c #D3D3D3",
-"q@ c #BCBCBC",
-"r@ c #212121",
-"s@ c #222222",
-"t@ c #242424",
-"u@ c #525252",
-"v@ c #D4D4D4",
-"w@ c #AFAFAF",
-"x@ c #636363",
-"y@ c #D6D6D6",
-"z@ c #353535",
-"A@ c #505050",
-"B@ c #C3C3C3",
-"C@ c #818181",
-"D@ c #4F4F4F",
-"E@ c #565656",
-"F@ c #585858",
-"G@ c #5D5D5D",
-"H@ c #5E5E5E",
-"I@ c #5F5F5F",
-"J@ c #606060",
-"K@ c #646464",
-"L@ c #676767",
-"M@ c #666666",
-"N@ c #686868",
-"O@ c #6A6A6A",
-"P@ c #656565",
-"Q@ c #6C6C6C",
-"R@ c #707070",
-"S@ c #616161",
-"T@ c #717171",
-"U@ c #727272",
-"V@ c #6E6E6E",
-"W@ c #737373",
-"X@ c #7A7A7A",
-"Y@ c #757575",
-"Z@ c #777777",
-"`@ c #797979",
-" # c #535353",
-".# c #7B7B7B",
-"+# c #767676",
-"@# c #6D6D6D",
-"## c #7E7E7E",
-"$# c #575757",
-"%# c #515151",
-"&# c #626262",
-"*# c #7C7C7C",
-"=# c #838383",
-"-# c #848484",
-";# c #858585",
-"># c #888888",
-",# c #5A5A5A",
-"'# c #7D7D7D",
-")# c #8C8C8C",
-"!# c #8D8D8D",
-"~# c #909090",
-"{# c #919191",
-"]# c #929292",
-"^# c #939393",
-"/# c #949494",
-"(# c #898989",
-"_# c #969696",
-":# c #979797",
-"<# c #555555",
-"[# c #989898",
-"}# c #828282",
-"|# c #8E8E8E",
-"1# c #8B8B8B",
-"2# c #8F8F8F",
-"3# c #545454",
-"4# c #787878",
-"5# c #878787",
-"6# c #999999",
-"7# c #8A8A8A",
-"8# c #ECECEC",
-"9# c #7F7F7F",
-"0# c #5B5B5B",
-"a# c #6F6F6F",
-"b# c #696969",
-"c# c #9A9A9A",
-"d# c #FDFDFD",
-"e# c #AAAAAA",
-"f# c #808080",
-"g# c #9B9B9B",
-"h# c #9C9C9C",
-"i# c #C1C1C1",
-"j# c #F2F2F2",
-"k# c #CCCCCC",
-"l# c #9D9D9D",
-"m# c #E5E5E5",
-"n# c #9E9E9E",
-"o# c #F6F6F6",
-"p# c #C8C8C8",
-"q# c #9F9F9F",
-"r# c #BFBFBF",
-"s# c #A1A1A1",
-"t# c #BEBEBE",
-"u# c #DDDDDD",
-"v# c #BABABA",
-"w# c #A2A2A2",
-"x# c #DCDCDC",
-"y# c #A3A3A3",
-"z# c #A6A6A6",
-"A# c #ACACAC",
-"B# c #ADADAD",
-"C# c #AEAEAE",
-"D# c #B1B1B1",
-"E# c #B2B2B2",
-"F# c #B4B4B4",
-"G# c #B8B8B8",
-"H# c #B9B9B9",
-"I# c #BBBBBB",
-"J# c #BDBDBD",
-"K# c #C6C6C6",
-"L# c #C7C7C7",
-"M# c #CACACA",
-"N# c #CECECE",
-"O# c #D2D2D2",
-"P# c #D8D8D8",
-"Q# c #D9D9D9",
-"R# c #D7D7D7",
-"S# c #DBDBDB",
-"T# c #A8A8A8",
-"U# c #D1D1D1",
-"V# c #D0D0D0",
-"W# c #CFCFCF",
-"X# c #C9C9C9",
-"Y# c #B7B7B7",
-"Z# c #C5C5C5",
-"`# c #C4C4C4",
-" $ c #B6B6B6",
-".$ c #B5B5B5",
-"+$ c #B3B3B3",
-"@$ c #A7A7A7",
-"#$ c #A9A9A9",
-"$$ c #C2C2C2",
-"%$ c #D5D5D5",
-"&$ c #CDCDCD",
-"*$ c #E6E6E6",
-"=$ c #E7E7E7",
-"-$ c #E1E1E1",
-";$ c #8A8989",
-">$ c #6D6B6B",
-",$ c #646262",
-"'$ c #A4A3A3",
-")$ c #AEADAD",
-"!$ c #D4D3D3",
-"~$ c #818080",
-"{$ c #969595",
-"]$ c #A5A4A4",
-"^$ c #8A8888",
-"/$ c #838181",
-"($ c #727070",
-"_$ c #817F7F",
-":$ c #858484",
-"<$ c #868484",
-"[$ c #777575",
-"}$ c #6E6C6C",
-"|$ c #888686",
-"1$ c #BFBEBE",
-"2$ c #898888",
-"3$ c #797878",
-"4$ c #706E6E",
-"5$ c #9F9E9E",
-"6$ c #7A7878",
-"7$ c #DFDEDE",
-"8$ c #656363",
-"9$ c #8D8B8B",
-"0$ c #747373",
-"a$ c #666464",
-"b$ c #C6C5C5",
-"c$ c #EAE9E9",
-"d$ c #999898",
-"e$ c #BDBCBC",
-"f$ c #939292",
-"g$ c #CAC9C9",
-"h$ c #9A9999",
-"i$ c #7E7D7D",
-"j$ c #6C6A6A",
-"k$ c #686666",
-"l$ c #8C8B8B",
-"m$ c #6F6D6D",
-"n$ c #D8D7D7",
-"o$ c #7B7979",
-"p$ c #8E8D8D",
-"q$ c #AAA9A9",
-"r$ c #9E9D9D",
-"s$ c #AFAEAE",
-"t$ c #8B8A8A",
-"u$ c #7E7C7C",
-"v$ c #959494",
-"w$ c #919090",
-"x$ c #8F8E8E",
-"y$ c #6B6969",
-"z$ c #767575",
-"A$ c #929191",
-"B$ c #7C7B7B",
-"C$ c #6F6E6E",
-"D$ c #949393",
-"E$ c #737171",
-"F$ c #828181",
-"G$ c #B7B6B6",
-"H$ c #A9A8A8",
-"I$ c #939191",
-"J$ c #B2B1B1",
-"K$ c #B5B4B4",
-"L$ c #FAF9F9",
-"M$ c #ABA9A9",
-"N$ c #7F7D7D",
-"O$ c #BEBDBD",
-"P$ c #878585",
-"Q$ c #747272",
-"R$ c #D1D0D0",
-"S$ c #A6A4A4",
-"T$ c #9B9999",
-"U$ c #C1C0C0",
-"V$ c #BCBBBB",
-"W$ c #DAD9D9",
-"X$ c #C0BFBF",
-"Y$ c #B1B0B0",
-"Z$ c #969494",
-"`$ c #908F8F",
-" % c #ABAAAA",
-".% c #9C9B9B",
-"+% c #D7D6D6",
-"@% c #DEDDDD",
-"#% c #C7C6C6",
-"$% c #A6A5A5",
-"%% c #807F7F",
-"&% c #7C7A7A",
-"*% c #CDCCCC",
-"=% c #CFCECE",
-"-% c #676565",
-";% c #9A9898",
-">% c #716F6F",
-",% c #696767",
-"'% c #797777",
-")% c #C5C4C4",
-"!% c #B9B8B8",
-"~% c #706F6F",
-"{% c #727171",
-"]% c #A1A0A0",
-"^% c #6A6868",
-"/% c #7D7B7B",
-"(% c #8D8C8C",
-"_% c #B3B2B2",
-":% c #BAB9B9",
-"<% c #CBCACA",
-"[% c #696868",
-"}% c #717070",
-"|% c #9D9B9B",
-"1% c #7A7979",
-"2% c #C3C2C2",
-"3% c #ECEBEB",
-"4% c #EFEEEE",
-"5% c #8E8C8C",
-"6% c #767474",
-"7% c #ADACAC",
-"8% c #989696",
-"9% c #B4B3B3",
-"0% c #ACABAB",
-"a% c #757373",
-"b% c #C4C3C3",
-"c% c #807E7E",
-"d% c #787676",
-"e% c #A7A6A6",
-"f% c #8F8D8D",
-"g% c #BBBABA",
-"h% c #908E8E",
-"i% c #D0CFCF",
-"j% c #7D7C7C",
-"k% c #838282",
-"l% c #9D9C9C",
-"m% c #868585",
-"n% c #9B9A9A",
-"o% c #8C8A8A",
-"p% c #A3A2A2",
-"q% c #C8C7C7",
-"r% c #DBDADA",
-"s% c #9E9C9C",
-"t% c #E1E0E0",
-"u% c #848383",
-"v% c #888787",
-"w% c #858383",
-"x% c #848282",
-"y% c #757474",
-"z% c #A09F9F",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ # # # # # # # # # # # # # # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % & * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * = = = = = = = = = = = = = - ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; - - - - - - - - - - - - - > > > > > > ; , , , ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; , ' ' ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ~ ~ ~ ~ ~ ~ { ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ^ / / / / / ( # ",
-" _ : < [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ } } } } } } } } } } } } } } } } | 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 5 5 5 5 5 5 4 4 4 4 4 4 4 4 4 6 6 6 6 7 7 7 7 7 7 8 8 3 3 3 4 4 4 4 6 6 6 6 7 7 7 7 7 4 9 9 9 9 9 5 5 4 4 4 4 4 4 4 6 7 7 7 7 8 8 3 3 3 0 0 a a b 2 2 1 1 c c d e e | } } | e e } } } f g g h [ [ [ < i i i i i j j j k k k j j j j j j i i i < < [ [ h g g f e c c 1 2 b b a 0 3 8 7 7 4 4 5 9 9 l l m n n o p p q r r s s t t u v v w x x x y y z A B C C C C C C C C D D D E E E E E E E E F G G G G G H I J ",
-" . K L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N O O P P Q R R S T U V W W X Y Y Z ` .....+. at .#.G G $.F F %.E D D C C &.&.B B B B B *.*.*.*.*.*.*.B B B B &.&.C C D D E E F F F G G #. at .@.+... .` ` Z Y Y X W W V U T T S R R Q P P P O N N N N N N N N N N M M M M M M M M M M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L m ' ",
-" =.-.L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M M N N N O P P Q Q R S T U V W X X V ;.>.,.'.).!.~.{.].^./.E (._.:.:.<.[.}.|.1.2.2.2.3.3.4.5.5.6.7.8.8.8.8.8.9.2.2.1.1.0.0.|.a.b.b.c.d.e.f.g.g.h.i.j.k.l.l.m.^.n.n.].o.R T S R Q Q P O O N N N M M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L O p.J ",
-" J q.L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M M N N O O P P Q R R S T U r.W X X Y s.t.u.v.w.x.y.y.z.A.B.C.D.E.F.G.H.I.J.J.K.L.L.M.M.M.M.N.O.O.P.Q.Q.R.R.R.R.S.T.T.U.V.W.W.W.W.W.W.W.X.Y.Y.Y.Y.Z.`. + + + +.+.+.+.+.+++ at +U T S R Q Q P O O N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L a > ",
-" ] x L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N O O P P Q R S T U V W W X Y Y #+$+%+%+&+&+*+=+-+-+t.;+>+,+,+'+'+)+)+!+~+{+{+]+^+^+^+/+(+_+_+:+(+(+(+(+(+<+[+}+}+[+[+[+[+[+[+[+[+|+|+|+1+|+2+3+%+%+%+4+5+5+5+6+7+8+9+V T T R R Q P P O O N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L T 0+ ",
-" J a+L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M M N N N O P P Q R R S T V V W X X Y Z Y ` b+c+` ...d+ at .#.G F e+,+'+'+)+)+~+~+{+]+^+^+f+f+f+{+!+g+{+{+{+h+h+h+h+i+j+j+j+k+k+k+k+k+k+l+l+[+[+[+[+|+m+n+` o+b+p+q+r+r+T s+t+U V U T S R Q P P O O N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L k % ",
-" ) o L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N O O P P Q R R T T V r.W X Y Y Z u+ at .@. at .#.G s.v+F %.w+E x+'+'+)+!+~+{+{+]+^+y+f+f+z+A+A+}+B+B+B+j+j+j+k+k+k+k+k+k+k+k+k+k+k+k+k+k+k+k+l+l+l+C+v+E F v+s.s.D+E+ at .F+D+@+V V T S R R Q P P O N N N M M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L W G+ ",
-" H+L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N O O P P Q R S T U V W W X Y Z ` ,.I+J+K+L+M+M+N+O+P+P+Q+R+'+)+!+~+{+]+^+y+f+f+f+A+A+B+B+B+j+j+j+S+S+S+S+S+S+S+S+S+T+T+T+T+T+U+U+k+k+k+k+k+k+V+W+X+Y+Y+Y+Y+Y+Y+Y+Z+`+ @r.V T T S R Q P P O O N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L .@$ ",
-" - 8 L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N O O P P Q R R S T V V W X Y Y Z ` +@`+@@#@#@u.v.x.y.$@y.%@&@)+!+~+{+]+^+y+f+f+A+A+B+B+B+j+j+*@S+S+S+=@=@- at -@- at -@- at -@- at -@;@T+T+T+T+T+T+U+U+U+U+>@,@'@)@)@!@!@!@!@!@!@!@~@W V U T S R Q P P O O N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L ` {@ ",
-" ]@Q L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N O O P P Q R S T U V r.W X Y Y Z ` #.^@^@^@/@(@(@_@'.'.{.*.:@{+{+{+<@f+f+f+A+B+B+B+B+j+S+=@=@=@=@-@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@[@}@|@1 at o.2@2 at 3@4 at 5@6 at 6@7 at 7@9+W V V T S R R Q P P O N N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L 8 at 9@ ",
-" & [ L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M M N N N O O P P Q R S T U V W W X Y Z ` ` ....+. at .#.G G F F %.E D 0 at a@a at a@b at c@d at e@e at f@g at g@h at h@h at i@i at i@i at j@j at j@j at j@j at j@j at j@j at j@j at i@i at k@g@:@&@l at l@l at m@n at o@<.G @. at .+... .` Z Y Y X W r.V T T R R Q P P O O N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L F p@ ",
-" q at V L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N O O P P Q R R S T V r.W X Y Y Z ` .....+. at .#.G $.F %.E E D C &.B B *.H r at r@s at s@-.-.t at t@t at A A A A A A A A t at t@t at -.-.s@s at r@H H *.B B &.C D E %.F F G G #. at .+... .` ` Z Y X W W V U T S R Q Q P O O N N N M M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L K 9@ ",
-" % u at L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N M M M N P R S T U U Q Q Q R T Z ` ...+.Z V V r.r.#.%.E D C C B B *.H H r at s@s at -.-.G . ...#.t at A A A A r at .... .` D -.-.s at s@r at H H *.B &.C C E E %.$.W T T T V .... .` Z V P P O O S T S R R P N M M L L N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L D v@ ",
-" J w at r.L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N M L L L L O Q R S T S L L L L O Y Z ` ` .V L L L L ..$.F F %.E D D C C &.B B *.H *.r.N N N T H s at s@s at r@D N N N N +.H *.B B &.&.C C D E E F F $.G @.P L L L N ` ` ` ` Y R L L L L P V U T T P L L L L L P Q Q P P P P P P P P P P P P N L L L L L N P P P P L L L L L L O O O O O O O O O O O O N N O M L L L L L M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L x@& ",
-" y at A L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M L L L L L N N N N N M L L M M O P Q R R R R S T T T T T U T R O N N N P W Y Y Y T Q O O O N U ..+.+. at .@. at .G G $.$.F %.E E F O L M L L M C -.t at A G L L L L L Z r q p p W L L L L L w 6 7 7 8 3 3 a a a b b 2 2 2 A L L L L L r at b b a 3 Z L L L L O p 6 4 4 5 9 z at l m n o p q r s E L L L L L +.*.C F +.N L L L L L N N M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L T a+. ",
-" , A at L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M L L L L L M M M M N N N N N M L N O O O O Q R R R L L O P O O Q V V r.r.W W Y Z Y Y Z ` ` +. .L L M M M L @.D C H ` L L L L L T z z y x U L L L L L C r r r r q o p p p p p p p o C L L L L L ` q s t t U L L L L L E z -.s at r@r at B E &.E %.F $.G G ` L L L L L Q ...... at .N L L L L L P r.T T Q L L L L L L N P N N Q O M P N N N N N X .V L L L L L L L L L L L L L L L L L G B@ ",
-" + C at L L L L L L L L L L L L L L L L L L L L R A Z W W W M L L L L L L U X X V L L L L L L Y l 9 9 9 5 5 4 B B 4 &.` ` ` O L L L L L P ` ` ` X L L L L L L t at .. . .T L L L L L +.2 c c c c d d C w e e A @. at . .L L L L L @.d &. at .@.r.L L L L L b j j j k k D at 2 Z j u at u@| F F G N L L L L 2 E at 4 F F ` L L L L &.F at .@t %.E U M M M N < G at G@H at H@H at I@b F J at K@K at K@d C C r.P P P .H at L@M at n C F P P P P t at N@O at O@O at O@O at P@#.k O at 8@8 at Q@O at p E R M M M M 1 R at R@N at t@ .L L L L T S at T@U at G@%.P L L L L B V at U@U at U@U at Q@G E at W@W at W@W at W@W at 4 P L L L L T P at X@X at Y@*.L L L L L &.K X at X@X at X@< -.Z at X@X@`@`@`@`@: P L L L L M #.#.#+#*.L L L L L ..@#X at X@F at O L L L L L t Y at Z@Z at Z@i p W at +#+#+#Y at Y@.###N at Z L L L L L L L L L L L L L L L L L 7 ] ",
-" J 0+Z L L L L L L L L L L L L L L L L L L L L A l F F F ` L L L L L L Q $.%.F V L L L L L L 9 E at E@E@$#$#$#H at 0 h u at r@D D G N L L L L L G C C C ` L L L L L .4 C C C T L L L L L 6 K at K@P at P@M at M@L at n %#L at P@r B B G L L L L L 6 K at A *.*.W L L L L W &#R at T@T at T@U at U@. at H T at K K . at H r@&.M L L L P K@`@} s at s@@.L L L L 9 ##*#7 t at t@W M M M T V@=#-#-#;#;#q.$#s@=#>#>#>#,#y z Z P Q Q +.'#)#!#k y s at R Q Q Q w )#~#~#~#~#{#)#-.J@]#]#]#]#]#A at A W N M M M c ^#/#~#8 C L L L L N U at a+a+>#u W L L L L $.(#_#_#:#:#a+6 <#:#:#:#:#[#[#M at V L L L L L : [#[#:#A at L L L L L V *#[#[#[#[#C at r@}#[#[#[#:#:#:#|#r at L L L L L p {#_#a+I at L L L L L L : /#/#1#z L L L L L W +#{#{#~#-#0 U@~#2#2#|#|#|#|#!#: P L L L L L L L L L L L L L L L L L M@& ",
-" y at A L L L L L L L L L L L L L L L L L L L L Y b &.F F G P L L L L L L ` %.%. at .M L L L L L @.A at E@E@$#$#$#F at J@4 $#b E E D r.L L L L L U r at D D E Q L L L L L s t C C F M L L L L R #K at P@P at P@M at M@K at q &#N at H@s at B B W L L L L N 3#,#H *.B S L L L L D Q at R@T at T@U at U@U at j 9 K K K k r at r@%.L L L L ` V at 4#a s at s@Z L L L L | ##*#9 t at -.U M M N Y K -#-#;#;#q.q.<#s at -#>#(#(#G at y y .R R R ..*#!#|#u at x -.T R R R -.1#~#{#{#{#]#~#r #^#]#]#^#^#&#A ..N N M M u {#/#/#i H O L L L L $#_#_#]#a @.L L L L P Y@:#:#:#:#[#H at s ^#[#[#[#[#[#5#H L L L L L p /#[#6#*#Y L L L L L u@[#[#[#[#_#3 E@[#[#[#[#[#[#[#,#L L L L L T W at _#_#7#B L L L L L B >#/#/#M at P L L L L L z@|#]#]#{#O at g (#~#~#2#2#2#|#|#5#p L L L L L L L L L L L L L L L L L T a+. ",
-" 8#D at L L L L L L L L L L L L L L L L L L L L N l o $.F F X L L L L L L T F %.F U L L L L L M 6 E at E@E@$#$#$#H@} [ E at z E E F O L L L L L &.B D D @.L L L L L R c H C C Z L L L L L *.S at K@P at P@M at M@M at F@5 M at N@D@&.B C R L L L L ` x@[ B *.D N L L L L n R at T@T at T@U at U@U at 6 j K K Y at c r at r@@.L L L L E K 4#5 s at s@r.L L L L k 9#.#l t at s@T N N N Z Y at -#;#;#q.q.5#3#t@;#(#(#7#K at y y ..R R R ..'#|#|#: x t at V S R R H (#{#]#]#]#]#]#c 2 ]#^#^#/#/#K A F N N N N C )#a+a+x at s@T L L L L 4 a+_#_#F at E L L L L L F@[#[#[#[#[#9#C -#[#[#[#[#6#a+0 O L L L L Z -#6#6#/#q L L L L L *.2#6#6#6#6#U at A !#6#6#6#[#[#[#(#E L L L L L 8 /#:#:#0#L L L L L L G at a+a+!#s L L L L L T a#]#]#]#)#< M@~#~#~#~#~#2#2#2#Y@` L L L L L L L L L L L L L L L L L G B@ ",
-" # ##L L L L L L L L L L L L L L L L L L L L L C c D $.F #.N L L L L L M +.F F +.M L L L L L F %#E at E@$#$#$#F at J@9 F@} D E E Z L L L L L Q v D D E U L L L L L B a D C D R L L L L L 2 K at P@P at P@M at M@L at 0 %#N at N@3 B B %.L L L L L -.b#5 *.*.G L L L L L i T at T@T at U@U at U@R at x : K K K 4 r at r@Y L L L L t at 4#+#n s at r@U L L L L 0#9#`@p t at s@T N N N $..#;#;#q.q.5#># #x q.7#7#7#N at y x @.T T T Y `@2#2#x at x A W T T T D q.]#]#]#^#^#^#u at t ]#/#/#/#/#C at w C N N N N Y C at _#_#4#t at X L L L L s@~#:#:#W at B P L L L L n a+[#[#[#[#{#s at b#6#6#6#6#6#6#M at V L L L L L S at c#c#c#I at M L L L L Q K c#c#c#c#{#v O at c#c#6#6#6#6#[#D at L L L L L W ##[#[#7#C L L L L L B 7#_#_#R at T L L L L L p !#^#^#]#4#c =#{#{#~#~#~#~#2#|#A at L L L L L L L L L L L L L L L L L L 4 ^ ",
-" d#/ >#W L L L L L L L L L L L L L L L L L L L L S 2 t $.$.$.V L L L L L L V F F F T L L L L L O a E at E@$#$#$#$#H at h g F at r E E F Q L L L L L C z D D $.N L L L L L 0 u C C G L L L L L V $#K at P@P at M@M at M@K at p J at N@K at t B B ..L L L L L 2 N at v *.*.Y L L L L Q H at R@T at T@U at U@W at O@y O at K Y at T@q r at H V L L L L l X at K s s at H S L L M L K at 9#4#r t at r@R N N O %.*#;#q.q.5#>#>#%#v >#7#1#1#b#y x G T U U U Y@~#~#Q at x z X U U U @.}#^#^#/#/#/#/#J at t@2#a+a+a+a+)#n H O O N N N W at _#_#>#t @.L M L L X =#[#[#>#w U L L L L E !#6#6#6#6#6#k d [#c#c#c#c#c#;#D L L L L L n :#c#c#q. at .L L L L L 2 [#c#c#c#c#G at m a+c#c#c#c#c#c#}#` L L L L L < :#[#[#0#L L L L L L H at _#_#{#z at L L L L L R M@/#/#^#{#F at E@~#]#{#{#{#~#~#~#-#t at L L L L L L L L L L L L L L L L L L P@& ",
-" + e#X L L L L L L L L L L L L L L L L L L L L L s 2 %.$.$...M L L L L L N #.F F ..L L L L L L D u at E@E@$#$#$#F@ $#k B E E .L L L L L O n &.D D Y L L L L L ` [ *.C C W L L L L L t@&#K at P@P at M@M at M@. at z@L at N@G at r@B &.U L L L L P $#&#s at B B T L L L L +.N at T@T at U@U at U@W at J@x R at K Y at V@x r@*.S L L L L f X at R@x s@*.P L M M T Q at f#Z at t t at H P O O O C 9#q.5#5#>#>#(#3#c (#1#1#)#8 at y x G V V V U Y@~#{#K x x ` V V V Z *#/#/#/#/#/#a+U at w )#_#_#_#_#]#a -.S P O O N S@:#:#]#7 E L M M M L K [#[#/#8 ` L L L L P X at 6#6#c#c#c#T@*.|#c#c#c#c#c#_#6 N L L L L .q.g#g#:#5 L L L L L F 1#g#g#g#g#(#s@'#g#c#c#c#c#c#:#a L L L L L G q.6#6#1#C L L L L L s@)#:#:#+#V L L L L L t at 1#/#/#/#-#c 4#]#]#]#]#{#{#~#~#O at T L L L L L L L L L L L L L L L L L T a+. ",
-" ! h L L L L L L L L L L L L L L L L L L L L L @.g y $.$.G R L L L L L L X F F $.R L L L L L P 1 E at E@$#$#$#F at H@[ f F at 9 %.E %.R L L L L L #.o E D %.Q L L L L L r 0 D C E P L L L L L e K at P@P at P@M at M@N at 2 [ N at N@< &.&.E N L L L L #.P at 3#B B D N L L L L z a#T at T@U at U@W at W@A at l K Y at Y@L at -.H &.N L L L L $#X at Q@A s@&.N M M M Y U at f#K x t@*.P O O P r@}#5#5#>#>#(#7#<#g 7#)#)#!#T at x w $.W W W U K {#]#X at w x ` W W W T +#/#a+a+a+_#_#9#z ;#_#_#_#_#_#< t at V P P O O i :#[#:#< H N M M M M F at 6#6#6#E@%.L L L L L 0#c#c#c#c#c#1#D X at c#c#g#g#g#g#x at T L L L L L M at h#h#h#O at P L L L L L N at h#h#h#h#c#} i c#g#g#g#g#g#g#X at U L L L L L $#6#c#[#F at L L L L L M &#[#:#/#a L L L L L M I at a+/#/#/#N at i |#^#]#]#]#]#{#{#|#c L M L L L L L L L L L L L L L L L L G i#J ",
-" # W at L L L L L L L L L L L L L L L L L L L L L Q 3 0 F $.$.Z L L L L L L P G F F ` L L L L L L B #E at E@$#$#$#F@	 E@ #r at E E +.L L L L L L l t at D D ..L L L L L Q [ v D C @.L L L L L ` ,#K at P@P at M@M at M@L at o I at N@L at 5 &.&.G L L L L L s Q at c B B G L L L L L 2 T at T@U at U@U at W@W at a f Y at Y@Y at G@H H E L L L L O K at .#M at s@s at E M M M M $.4#C at U@y t at B O P P P t@=#5#>#>#(#(#7#u at g 7#)#!#!#Y at w w $.W W X U R@]#]#}#s w +.X X W T R at _#_#_#_#_#_#5#t@*#:#:#:#:#[#H at z Y P P P O n _#[#[#K at r@R M M M M z@:#6#6#W at B N L L L L l [#c#c#c#c#:#o F at g#g#g#g#g#g#-#F L L L L L m 6#h#h#|#D L L L L L n [#h#h#h#h#`@t@)#h#h#h#h#h#g#_#l L L L L L C !#c#c#7#E L L L L L s@|#[#[###` L L L L L C q.a+a+a+!#g @#/#^#^#]#]#]#]#{#f#%.L M L L L L L L L L L L L L L L L L 9 ^ ",
-" d#p.r.L L L L L L L L L L L L L L L L L L L L L s@[ -.$.$.G P L L L L L L ` F F G Q L L L L L Q c E at E@$#$#$#F at H@h } . at b %.E %.T L L L L L ` 0 E E E T L L L L L C k &.D D U L L L L L x x at P@P at P@M at M@M@: o M at N@x at y &.&.X L L L L L [ Q at l B B Y L L L L N $#T at T@U at U@U at W@R at v ,#Y at Y@+#u at H H G L L L L X @#.#H at r@s at F L M M M B *#C at V@A t at D P P Q Q u ;#>#>#(#7#7#1#%#g 1#!#|#|#+#w w F X X Y T O@^#^#q.p v @.Y Y Y r.N at _#_#_#:#:#:#|#t R@[#[#[#[#[#a#z +.Q Q P P s@]#6#6#4#-.r.M M M M -.^#c#c#(#x T L L L L E 2#g#g#g#g#g#J at r _#h#h#h#h#h#:#9 N L L L L ..(#h#h#g#f L L L L L Y =#h#h#h#h#:#q S at h#h#h#h#h#h#h#R at P L L L L L x at c#c#c#E at L L L L L M &#[#[#_#g L L L L L L <#a+_#a+a+K d >#/#/#^#^#]#]#]#]#J at P L M L L L L L L L L L L L L L L L L K at j# ",
-" k#F L L L L L L L L L L L L L L L L M L L L L W | 4 $.$.$.W L L L L L L S $.F F Z L L L L L L s at 3#E at E@$#$#$#F@	 E at E@x %.E #.M L L L L L q r E E G M L L L L L 2 7 D D F N L L L L N h P at P@P at M@M at M@L@| h N at N@F at B &.C R L L L L U G at M@y B &.T L L L L ` M at T@T at U@U at W@W at 8@t at M@Y at Y@+#f H H .L L L L %.K *#E at s@s@@.M M M N t@##}#Q at t@A E P Q Q R t q.>#(#7#7#1#1#%#h )#|#|#2#`@v v F Y Y Y U O@/#/#)#9 v $.Z Z Z Y G@:#:#[#[#[#[#^#4 &#[#[#[#6#6#C at x E Q R Q Q @.>#c#c#7#t .N M M M Z ;#c#c#a+7 W L L L L P .#g#g#g#h#h#C at D 5#h#h#h#h#h#h#H at S L L L L L N at l#l#l#+#R L L L L L . at l#l#l#l#l#N at u a+l#l#l#h#h#h#^#x L L L L L A ]#g#g#7#E L L L L L s at 2#6#6#-#@.L L L L L F ;#_#_#_#]# #H@^#/#/#/#^#^#^#]#)#9 L M M L L L L L L L L L L L L L L L R ]#. ",
-" m#d L L L L L L L L L L L L L L L L L L L L L N l h *.$.$. at .N L L L L L M ..F F G P L L L L L S f E at E@$#$#$#$#I at h } . at g E %.%.V L L L L L U e *.E E W L L L L L ` #y D D .L L L L L @.G at K@P at P@M at M@M at M@p : N at N@g C B %.M L L L L %.N@: *.B D O L L L L C @#T at U@U at U@W at W@&#z a#Y at +#Y at 8 H H W L L L L s at 4#*#j s at s@Z N N N O r f#}#L at t@A F S T U U 7 >#(#7#7#1#1#)#D at j !#|#2#~###s v &.#.G $.#.O@/#a+|#7 u &.E D D D F@[#[#[#[#[#6#:#d A at 6#6#c#c#c#)#p B #.%.E %.C '#c#c#/#7 %.Z #. at .@.+.W at g#g#c#j #.U Y Y X X H at h#h#h#h#h#^#r at 8@h#h#h#l#l#l#=##.L P O O N 9 c#l#n#/#s at L L L L L A :#n#n#n#n#2#-.+#l#l#l#l#l#l#l#K at L L L L L Q R at h#h#c#$#L L L L L M K at c#6#[#<#L L L L L L D at _#:#_#_#}#2 ##a+/#/#/#/#^#^#^#`@ .L N L L L L L L L L L L L L L L L L #.i#J ",
-" o#O at L L L L L L L L L L L L L L L L L M L L L L D < n G $.$.Y L L L L L L U $.F F +.L L L L L L A <#E at E@$#$#$#F at x@9 E at F@q %.%.F R L L L L L A 3 %.E E T L L L L L r A at C D D W L L L L L p K at P@P at P@M at M@M at H@p M at b#N at z@&.&.$.L L L L L n Q@< C &.E M L L L L m R at T@U at U@U at W@K #v W at +#+#K m H H V L L L L m X@*#e s at s@Y N N P R b }#}#&#t at A F S S T T c (#7#7#1#)#)#)#i D@|#2#~#~#}#q u H $.F F F O at a+_#]#2 t -.r at s@s at -.F@6#6#6#6#c#c#6#k | c#c#c#c#c#/#8 s at t@[ $#z at y *#c#g#c#[ B E H &.4 b W at g#g#g#O at D Y #. at .+. .,#h#h#h#h#h#g#} | h#l#l#l#l#l#[#l N Q Q P O v c#n#n#l# #L M L L L &./#n#n#n#n#l#A at b g#n#n#n#n#l#l#2#C L L L L L L at h#h#h#1#E L L L L L F at c#c#c#(#E L L L L L 4 _#:#:#:#_#&#D@{#a+a+/#/#/#/#^#]# #L M N L L L L L L L L L L L L L L L L z@/ ",
-" d#I V L L L L L L L L L L L L L L L L M L L L L S 2 f C $.$.$.+.L L L L L N @.$.F F G M L L L L T g E at E@$#$#$#$#I at i | . at D@B %.%.%.T L L L L Q | z E E E V L L L L Q i 7 E D D ` L L L L O k K at P@P at M@M at L@N@} } b#b#K at x &.&.F L L L L L i @#8 &.&.D O L L L L i T at T@U at U@W at W@W at d e +#+#+#R at u H H r.L L L L e *#.#3 s at s@Y L L L L < }#=#J at t@A G L L L L } 7#7#1#)#)#!#!#[ #~#~#{#]#=#q t %.L L L L N at _#:#a+} t E L L L L 3#c#c#c#c#c#c#c#: 4 [#g#g#g#h#c#g A R 5 h G L ##g#g#g#M at r@R L M t at G Y at h#h#h#;#-.R L L L L x at l#h#l#l#l#l#U@*.{#l#n#n#n#n#n#,#R L L L L 4 l#n#n#n#C at X L L L L x c#n#n#n#n#n#f#H >#n#n#n#n#n#n#l#F at L L L L L `@l#h#h#g#F at L L L L L R at g#c#c#c#: L L L L L F@[#[#[#:#:#1#} U at _#_#a+a+/#/#/#/#>#x L N N L L L L L L L L L L L L L L L L J at j# ",
-" p#F L L L L L L L L L L L L L L L L M L L L L L v k 7 s at H C %.G O L L M L B A s at B D F R N L M L u <#E at E@$#$#$#F at x@5 E at .@e y t at H C X N L M M &.k t y s at B .N L L M B 0#6 v z r at G Q N L R F I at P@P at M@M at L@L at N@p 0#b#b#I at l t z B S P L Q ` I at 8@d p x H r.S L T ` S at T@U at U@W at W@K U at u E at +#+#Z at R@b n w @.W L S r.<#*#.#k 5 r F W L R W $#=#=#N at a l *.X M R W #7#1#)#)#!#|#|#[ <#{#{#]#]#>#u at a -...S Q .V@:#[#:#M at c y ..T N ..H at g#c#g#g#h#h#h#8 at o a+h#h#h#h#h#R at 0 C 4 a D E ;#h#h#h#=#c C +.M t@%.f#h#h#h#_# #H $.N ` F U at l#l#l#l#n#n#)#F .#n#n#n#n#n#n#5#r D S V D E at n#n#q#q#c#e C V U C e n#q#q#q#q#q#c#9 ,#n#q#q#q#q#n#n#(#x +.P C z 7#l#l#l#l#)#t G L E B C at g#g#g#g#|#o %.L %.&.S@[#[#[#[#[#[#U@| )#_#_#_#a+a+a+/#/#T at V L O L L L L L L L L L L L L L L L L R ]#. ",
-" ] 0 L L L L L L L L L L L L L L L L M M L L L L ..g D at k k j [ g | 1 e +.a e k %#A at k i h } f #.0 } %#E at E@E@$#$#$#H at k e . at .@. at F@E at 3#%#i i &.4 i u at G@: : . at E@%#A at t@n A at E@&#S at J@H@,#E at 3#o A 3#. at P@M at M@M at M@L at L@I at p M at b#b#b#b#L at K@J at 0#d G F at H@Q at V@@#Q at b#K at J@k ` ,#&#R at U@U at W@W at K K @#A P at +#+#Z at 4#Z at Y@R at 8@x@@.F@@#+#'###'#*#4#U at b#@. #U@*#-#-#;#-#f#`@W@&.h X at C@)#)#!#!#|#2#|#h E@{#]#^#^#/#/#~#5#q.c u q.]#[#6#6#6#_#)#7#<#r at q.]#h#h#h#h#h#h#h#+#w ~#l#l#l#l#l#h#:#2#f#| .#|#c#l#l#l#l#6#~#f#G @#|#[#l#l#l#l#g#]#>#B I@{#[#n#n#n#n#n#n#c#p ,#n#n#n#n#q#q#q#:#^#d 6 ]#[#I q#q#q#q#c#/#F at v 2#[#I I I I I I I a#t@^#q#q#q#q#q#q#n#_#4#E f#a+l#n#n#n#n#l#a+}#C R@/#c#h#h#h#g#g#/#(#v K@{#_#c#6#6#[#[#[#]#j &#_#_#_#_#_#a+a+/#]#| L M O L L L L L L L L L L L L L L L L @.r#J ",
-" % M at L L L L L L L L L L L L L L L L L N L L L L P 7 D at D@A at A@A at A@%#%#E@,#z at u@u@ # # # #3#3#E at J@p 3#E at E@E at E@$#$#$#F at K@z at E@. at .@.@,#,#,#0#0#P at n <#: G at H@H at I@I at I@J at P@m u at S@S@&#&#&#&#x at x@M at 8 < P at P@P at M@M at M@L at L@N at h d N at b#b#O at O@O at 8@8 at 8@A at p Q@@#@#V at V@V at a#a#R at F@-.V at T@U at U@U at W@W at K K K at t@V at +#+#Z at 4#4#4#`@X@@#B V@*#*#'#####9#9#f#+#@.N@=#=#-#;#;#q.5#>#}#B 0#7#1#)#!#!#|#2#2#|#h $#]#^#^#/#a+a+_#_#:#g r _#6#6#c#c#c#g#g#h#M@*./#h#h#l#l#l#l#l#l#}#z 7#n#n#n#n#n#n#n#n#{#| X at l#l#l#l#l#l#l#l#:#q S at l#l#l#l#l#l#n#n#h#3 f l#n#n#n#n#n#n#n#n#. at t 6#q#q#q#q#q#q#q#q#K C ]#I I I I I I I I 5#C -#I I I I I I I I /#-.V at I I I q#q#q#q#q#c#5 ,#n#n#n#n#n#n#n#n#h#u at d [#l#h#h#h#h#h#g#g#O at 3 {#c#c#c#6#6#6#[#[#'#2 -#:#:#_#_#_#a+a+a+=#E L O N L L L L L L L L L L L L L L L L 9 / ",
-" . c#T L L L L L L L L L L L L L L L L N M L L L L H j D at D@A at A@A at A@%#%#K at 8 j u at u@ # # #3#3#3#J at c h <#E at E@E at E@$#$#$#H at k c . at .@.@,#,#,#,#0#H at E@6 G at H@H at H@H at I@I at I@J at J@n I at S@S@&#&#&#x at x@x at P@q H at P@P at P@M at M@M at L@L at N@o ,#b#b#b#O at O@O at 8@8 at 8@7 i @#@#@#V at V@V at a#a#R@} 4 T at T@U at U@U at W@K K K F at z@K +#Z at Z@4#4#`@`@X at P@z Y@*#'#'#####9#f#f#T at C R@=#-#-#;#q.q.5#>#C at s@K at 1#)#)#!#|#2#2#~#2#h F@^#/#/#a+a+_#:#:#[#D at n _#c#c#c#g#g#h#h#h#U at H {#l#n#n#n#n#n#n#n#)#q 9#n#n#n#n#n#n#n#n#:#9 K at n#n#n#n#n#n#n#n#h#f g l#n#n#n#n#n#n#n#n#K at t@:#n#n#n#n#n#n#n#q#C at E (#q#q#q#q#q#q#q#I {#&.U at I I I I I I I I h#9 F at I I I I I I I I q#F at z@g#I I I I I I I q#+#x 2#q#q#q#n#n#n#n#n#(#q X at l#l#l#h#h#h#h#h#/#c L at c#c#c#c#c#6#6#6#_#: E@/#:#:#:#_#_#_#a+/#x at R L P M L L L L L L L L L L L L L L L L J at j# ",
-" B@#.L L L L L L L L L L L L L L L L M N L L L L W e D at D@A at A@A at A@%#%#,#u at a u at u@u@ # # #3#3#$#J at 5 3#<#E at E@E@$#$#$#F at P@5 <#. at .@.@,#,#,#0#: P at 7 u at G@H at H@H at H@I at I@J at x@} g S at S@S@&#&#&#x at x@K@<#6 K at P@P at P@M at M@M at L@L@&#s P at b#b#b#O at O@O at 8@8 at b#r S@@#@#@#V at V@V at a#a#V at 9 <#T at T@U at U@W at W@K K K f | +#+#Z at Z@4#4#`@X at X@,#7 X@*#'#####9#9#f#C at O@o 4#-#-#;#q.q.5#>#>###l V@)#)#!#|#2#2#~#{#|#g ,#/#/#a+_#_#:#:#[#6#J@} _#c#g#g#h#h#h#l#l#f#z@)#n#n#n#n#n#n#q#q#/#4 K q#q#q#q#q#q#q#q#h#[ A at n#n#n#n#n#n#n#n#n#L at l [#n#n#n#n#n#n#n#n#-#*.(#n#n#n#q#q#q#q#q#a+H Q at q#q#q#q#I I I I n#d f n#I I I I I I I I 8 at -._#I I I I I I I I >#*.}#I I I I I I I I [#m x at q#q#q#q#q#n#n#n#h#F at e [#l#l#l#l#h#h#h#h#Z at 7 )#g#g#c#c#c#6#6#6#7#c `@[#:#:#:#_#_#_#a+~#5 L N Q L L L L L L L L L L L L L L L L R ]#9@ ",
-" / 9 L L L L L L L L L L L L L L L L L O L L L L L p k D at D@A at A@A at A@%#u at x@z at D@u at u@ # # #3#3#3# i <#E at E@E at E@$#$#$#H at A@c . at .@.@,#,#0#: : H at H@9 : G at H@H at H@I at I@I at J@K at n 0#S at S@&#&#&#&#x at x@M at 7 u at P@P at P@M at M@M at M@L at N@i a N at b#b#b#O at O@O at 8@8 at I@n O@@#@#V at V@V at a#a#R at O@r P at T@U at U@U at W@W at K K W at 4 $#+#+#Z at 4#4#4#`@X at X@i } *#*#'#####9#f#f#C@ ##-#-#;#q.5#>#>#(#*#z at Y@)#!#|#|#2#~#{#{#|#} H@/#a+_#_#:#[#[#6#c#M@} _#g#h#h#h#l#l#n#n#;#9 (#q#q#q#q#I I I I 6#c L at I I I I I I q#q#q#,#b h#q#q#q#q#q#q#q#q#*#z !#n#n#n#n#n#n#n#n#a+v R at q#q#q#q#q#q#q#q#n#| c n#I I I I I I I I K H /#I I I I s#s#s#s#{#H `@s#s#s#s#s#s#s#s#n#0 D at q#I I I I I I I I 8 at r /#I q#q#q#q#q#q#n#7#r X at n#n#l#l#l#l#h#h#:#g I at c#g#g#c#c#c#c#6#[#8 at h ~#[#[#:#:#:#_#_#_#*#+.L P P L L L L L L L L L L L L L L L L +.t#J ",
-" j#H at L L L L L L L L L L L L L L L L L O M L L L L F [ D at D@D at A@A at A@%#%#I@[ e u at u@u@ # # #3#3#.@,#4 <#<#E at E@E at E@$#$#F at P@z@<#.@,#,#0#0#0#: : K at a k G at H@H at H@H at I@I at I@&#<#7 S at S@S@&#&#&#x at x@x at x@q S at P@P at P@M at M@M at L@L at N@m E at N@b#b#O at O@O at O@8 at Q@g c Q@@#@#V at V@V at a#a#R at J@q @#T at U@U at U@W at W@K K V at q x at +#Z at Z@4#4#`@`@X@`@2 #*#'#'###9#9#f#C@}#. at 0 f#-#;#q.q.5#>#(#7#4#m Z@!#!#|#2#~#{#{#]#2#| &#a+_#_#:#[#[#6#c#c#b#f :#h#l#l#n#n#n#n#q#)#9 =#I I I I I I I I l#[ $#I I I I I I I I I V at l [#I I q#q#q#q#q#q#2#w *#q#q#q#q#q#q#q#q#h#e D at n#q#q#q#q#q#q#q#I 8@&.^#I I I I I I I I {#&.+#s#s#s#s#s#s#s#s#q#e | q#s#s#s#s#s#s#s#s#+#H ~#s#s#s#s#I I I I ^#v V at I I I q#q#q#q#q#l#3#e 6#n#n#n#l#l#l#l#h#*#5 q.g#g#g#g#c#c#c#6#]#[ N@[#[#[#:#:#:#_#_#a+E at L L R N L L L L L L L L L L L L L L L L l u# ",
-" . ~#Q L L L L L L L L L L L L L L L L N O L L L L R a D at D@D at A@A at A@A@%#3#J at 9 %#u at u@ # # # #3#3#K at 4 k <#<#E at E@E@$#$#$#H at A@1 ,#,#,#0#0#0#: : G@&#n 0#G at H@H at H@H at I@I at I@M at 5 3#S at S@S@&#&#&#x at x@P at j 3 K at P@P at P@M at M@M at L@L at S@t K at N@b#b#O at O@O at 8@8 at O@n F@@#@#@#V at V@V at a#a#R at D@0 R at T@U at U@U at W@K K K N at q @#+#Z at Z@4#4#`@X at X@4#5 J@*#'#####9#f#f#C@}#A at e }#-#;#q.5#>#>#(#7#+#z@##!#|#2#~#~#{#]#^#2#e P at _#_#:#[#[#6#c#c#g#O@} :#l#n#n#n#q#q#q#I ~#4 *#I I s#s#s#s#s#s#I E@< I s#s#s#s#s#I I I '#v |#I I I I I I I I [#4 S at q#q#q#q#q#q#q#q#q#I at a c#q#q#q#q#I I I I !#H '#I I I I I I I I q#d g I s#s#s#s#s#s#s#s#Z at B ~#s#s#s#s#s#s#s#s#[#y K at s#s#s#s#s#s#s#I I I at z@[#I I I I q#q#q#q#>#s .#n#n#n#n#l#l#l#l#6#%# #6#h#g#g#g#c#c#c#c#X at 1 (#[#[#[#:#:#:#_#_#)#u L N S L L L L L L L L L L L L L L L L L H at j# ",
-" v#@.L L L L L L L L L L L L L L L L M P L L L L L y k D at D@D at A@A at A@A@%# [ u at u@u@ # # #3#3#,#E at 3 <#<#E at E@E at E@$#$#F at M@z at E@,#,#,#0#0#0#: : &#} f G at G@H at H@H at I@I at I@J at I@n I at S@S at S@&#&#&#x at x@L at l $#K at P@P at P@M at M@M at L@N at A@0 N at N@b#b#O at O@O at 8@8 at P@s P at Q@@#@#V at V@V at a#a#a#7 u at T@T at U@U at W@W at K K K ,#l W at +#Z at 4#4#4#`@X at X@W at o b#'#'#####9#f#f#C at C@g j -#;#q.q.5#>#(#7#7#a#9 f#|#2#2#~#{#]#^#^#2#e L@:#:#[#6#6#c#g#g#h#8 at e _#n#n#q#q#I I I I a+a +#s#w#w#w#w#w#w#w#w#S at e n#w#w#w#s#s#s#s#s#1#v f#I I I I I I I I n#k [ n#I I I I I I q#I *#n )#I I I I I I I I g#b K at I I I I I s#s#s#s#R at t@_#s#s#s#s#s#s#s#s#:#s at b#w#w#w#w#w#w#s#s#s#H at u c#s#s#s#s#s#s#s#s#~#x Z at I I I I I I q#q#l#3#e c#n#n#n#n#n#l#l#l#;#5 C at h#h#g#g#g#g#c#c#_#3#,#_#[#[#[#[#:#:#_#_#W at V L Q R L L L L L L L L L L L L L L L L R 2#9@ ",
-" x#o L L L L L L L L L L L L L L L L L P M L L L L ` f D at D@D at A@A at A@A at A@F at F@7 u at u@u at u@ # # #3#3#K at 4 A@<#<#E at E@E@$#F at F@J at A@b ,#,#,#,#0#0#0#: : K at m ,#G at G@H at H@H at I@I at I@K at d h S at S@S@&#&#&#&#x at K@J at q &#K at P@P at M@M at M@M at L@O at m <#N at N@b#b#O at O@O at 8@Q at .@m 8 at Q@@#@#V at V@V at a#a#T at q &#T at T@U at U@W at W@K K +#k d +#+#Z at 4#4#`@`@X at X@R at p U@'#####9#f#f#C@}#C at d E@;#;#q.5#>#>#(#7#1#R at 7 ;#|#2#~#{#]#]#^#/#~#} L@[#[#6#6#c#g#g#h#l#@#c a+q#q#I I I I s#s#[#c V at w#w#w#w#w#w#w#w#y#Q at 3 c#w#w#w#w#w#w#w#w#_#9 R at s#s#s#s#I I I I I  c#I I I I I I I I ]#9 +#I I I I I I I I I x@%#h#I I s#s#s#s#s#s#^#4 ;#s#s#s#s#s#s#w#w#s#$#k I w#w#w#w#w#w#w#w#|#z (#s#s#s#s#s#s#s#s#I 3#i q#I I I I I I q#q#>#r 7#q#n#n#n#n#n#l#l#g#$#A at h#h#h#g#g#g#c#c#c#;#b >#6#[#[#[#[#:#:#_#/#g L L T O L L L L L L L L L L L L L L L L +.t#J ",
-" > F at L L L L L L L L L L L L L L L L L O P L L L L L 7 <#E at E@E at E@$#$#F at F@c#9 <#,#,#0#0#0#: : : *#8 at c H at H@&#@#V at V@V at a#a#c#4 8 at R@R at R@T at T@T at U@U at 5#M at k Y at +#+#+#+#+#Z at Z@4#h#z at Y@.#*#*#*#*#'#'#'#|#K at 3#9#9#f#f#f#C at C@}#}#g#z@'#-#-#-#;#;#q.q.5#/#G@: >#(#7#7#7#1#1#)#)#6#l (#{#]#]#]#/#/#/#a+n#0#&#[#[#[#6#c#c#g#h#l#^#0 [#q#I s#w#w#p.p.H+z#A at U@]@A#B#C#w at 0+D#E#F#>#2 A#G#H#v#I#J#t#r#G+I#k f#K#L#p#M#{@k#N#O#v@{#g M#P#P#P#P#Q#Q#_ _ R#E@~#S#u#/ / / / / =.=.e#e P#=.=.=.=.=.=.=.=.x#3#-#=./ / / / / u#u#u#T#p {@x#x#/ / u#u#u#x#_ #*#x#S#S#S#_ _ Q#P#R#y#[ G+v at p@O#U#V#W#N#N#X#K@;#{@M#M#X#p#p#p#L#L#I F at Y#K#K#K#Z#`#`#`#B at r#0#2#G+G+G+r#t#t#t#J#J#_#0#F#v#v#v#H#G#G#G#G# $G at I $.$.$F#F#+$E#E#E#_#N at F#0+w at C#C#B#B#A#A#e#�+A#T#T#@$z#z#H+H+p.7#Y L N V M L L L L L L L L L L L L L L L M l u# ",
-" + )#L L L L L L L L L L L L L L L L L N R L L L L L L [ O at O@8 at 8@Q at Q@Q@@#V at e#t 8 at R@R at T@T at U@U at W@W at 1#&#u at +#+#f#y#p.p.H+z#H+D#6 n#z#z#z#z#z#@$T#T#+$P at W@#$#$e#e#e#e#e#]@]@D#4 p.B#C#C#C#w at w@0+0+H#K at K E#E#+$+$F#F#.$.$ $0+3 B#G#G#H#v#v#I#q at q@i#K at X@r#r#G+G+i#$$$$B@`#0+e v#L#p#p#X#M#M#{@k#k#J@=#W#V#U#O#O#p at v@%$y at C#g &$Q#_ S#x#u#/ =.^ S#F@^#m#*$=$~ ! ' 8#, - e#[ ( & o## @ 9 at d#J & E@@$ q@<#d# &#q@ {@E@ K at G# &$g : e# i#j > J d#. j#&#p.o#% & j#= > - ; , w at O@S#~ ~ *$*$( ( ] ] _ a#@$/ u#x#S#_ Q#P#R#R#p.*#k#p at O#U#V#W#N#N#k#K#R at F#X#p#L#K#Z#`#`#$$$$g#|#`#t#t#q at q@I#v#H#G#F#Y at K# $F#+$E#E#D#0+w at C#}#L L L R T L L L L L L L L L L L L L L L L M ,#> ",
-" J F# .L L L L L L L L L L L L L L L L L R N L L L L L M z at O@O at 8@Q at Q@Q@@#@#V@[#2 S at R@R at T@U at U@U at W@K ##;#d +#+#X at I H+H+z#z#z#C#} ]#z#@$@$@$@$T#T#T#B#q.I@#$#$e#e#e#e#]@]@A#w@[ c#B#C#C#C#w at w@0+0++$##K at E#E#+$+$F#F#.$.$ $0+| H+G#G#H#v#v#I#q at q@t#W at b#r#r#G+G+i#$$$$B@`#C#a E#L#p#p#X#M#M#{@k#M#&#K W#V#V#O#O#p at v@%$y at C#c M#Q#_ S#x#u#/ =.^ _ 3#~#m#*$*$~ ! ) 8#, ; T#[ ( & o#$ # + . J * <#@$ I#E at . H at q@ i#0# . at G+ r#E@ J [ G+ z#3## J . 9@! } .$o#% & j#j#> - ; , ~#&#{ ! ~ =$*$m#( ] ] U#[ +$/ u#x#S#_ _ P#R#R#-#'#U#p at O#U#V#W#N#&$k#v#$#q at X#p#L#K#Z#`#`#$$$$K h#$$t#t#q at q@I#v#H#G#z#b#B at F#F#+$E#D#0+0+w at C#: L L L M V Q L L L L L L L L L L L L L L L L R 2#9@ ",
-" S#u L L L L L L L L L L L L L L L L L Q P L L L L L L V z u at 3#3#<#E at E@E@$#$#8 at 6 | F at .@,#. at F@F at F@.@,#,#t ,#0#: +###########.#p P at .#*#*#*#*#'#'#'###0#a *#######9#9#9#9#f###m Q at f#C@}#}#}#}#}#=#-#,#d f#f#f#C at C@}#}#}#=#.#q T at -#;#;#;#q.q.q.5#5#[ h >#(#7#7#1#1#)#)#)#X at r 9#|#2#~#~#~#|#!#!#!#g u@~#~#~#{#]#]#^#^#/#4#l 1#_#:#[#[#6#c#c#g#[#c N at q#q#I h#h#h#l#n#q#+#2 c#y#p.H+z#z#w#y#p.q#g U@#$e#]@B#C#w at 0+E#+$##g C#G#v#v#I#I#q at q@q at F#g -#t#t#t#t#t#t#t#r#r#;#[ q at r#r#v#v#v#H#H#H#E#2 !#G#G#G#G#Y#Y# $q@ $Z at h +$F#F#F#F#+$E#G#G+I m C at e##$T#z#H+p.y#`#D#0#0 ^#_#a+/#/#]#]#6#V#1#v V@|#)#)#1#7#7#(#E#M#k 2 ;#q.;#-#-#-#=#7#M#A#x 8 at f#9#9#####'#'#^#k#K at 3 V at V@V at V@Q at Q@Q at 8@:#]@t H at b#b#N at N@N at L@L at M@h#H at 2 P at K@x at x@&#&#&#: J at 1#q 0#,#,#,#. at F@F at F@$#u@%.L L L L O W N L L L L L L L L L L L L L L L L E r#J ",
-" > F at M L L L L L L L L L L L L L L L L O T L L L L L L O $.C C C C C C C C C C C C C C C C C C C C C C &.&.&.C &.&.C C C C &.B r at t@A z z z z z z z z z y z z z z z z z z z z z y z z z z z z z z z z y y z z z z z z z z y x x y y y y y y y y y x x x x x x x x x x x x x w x x x x x x v v v v v v v v u u u u u t t t t s s s s r r r q q q p p p o o n n n m m l l l z at z@9 9 9 5 5 5 4 4 4 6 6 6 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 7 7 7 6 6 6 4 4 4 5 5 5 9 9 z at z@l l l m m n n n o o p p q . at p r r r s s t t t t 3 Z at v v v v v v w w w w @#W at x x x x x y y y y s ]@H at z z z z z z z z z . at i#[ A A A A A A A A z g#v#6 t at t@t at t@t at t@t at t@z at F#^#t at -.-.-.-.-.-.-.-.1 .$ #s at s@s at s@s at s@s at s@s at A@g#u r at r@r at r@r at r@r at r@H J at M@*.H H H H H H H H C P L L L L L T V L L L L L L L L L L L L L L L L Y g =. ",
-" 9 at 2#Q L L L L L L L L L L L L L L L L N V N L L L L L L ` D E D D D D D D C C C C C C C C C C C C C C C C C C C C &.&.B B s at t@z z z z z z z z z z z z z z z z z z z y z z z z z z z z z z z y z z z z z z z z z z z y z z z z y y y y y y x y y y y y y y y y y y x y y x x x x x x x x w v x w w w w w w v v v t u v u t t t t s s r r p q q q p p p o o n n l z at m l l l z at z@9 9 9 5 7 7 4 6 7 7 7 7 7 8 3 3 2 3 3 3 3 3 3 3 3 3 3 2 c 3 3 3 3 8 8 7 7 7 7 d 0 4 4 4 4 5 9 9 9 9 7 d 5 m l l l m m n n n P at f o p p p q q r r r m 2#3 s t t t t t t t t 3#6#o v v t t t t t t u ~#{#r r r r r r r r s 3 G#C at r s s t t t t t t P at p#R at t t t t t t t t v f#t#g u u u u u u u u v {#g#r v s s s s s s t o h#b#t t t t t t t t t 9 _#1 u u u v v v v v v D L L L L L M Z W L L L L L L L L L L L L L L L R r K at j# ",
-" v#+.L L L L L L L L L L L L L L L L N G X L L L L L L E g [ [ < < < < j j i i i i k k k k k k %#A at D@D at A@A at A@A at A@%# #E@: 0#,#,#0#0#0#0#: G at H@J at S@I at J@J at J@J at J@J at S@S at S@M@&#&#&#&#&#&#K at K@K at K@P at O@M at P@P at M@M at M@M at M@L at L@O@@#b#N at N@O at Q@Q at Q@Q@@#V at U@T at V@V at a#a#R at R@R at R@R at U@`@K U at W@W at W@K K K Y at +#`@##Z at Z@Z at 4#4#`@`@X at X@X@=#}#*#'#}#-#;#;#q.q.5#(#2#7#7#7#1#)#)#|#|#2#~#a+[#]#]#^#/#a+_#_#:#[#[#s#I n#q#I I s#w#w#y#y#z#B#z#z#z#z#@$@$T#T#T##$w at +$e#e#e#e#e#e#e#]@]@]@Y#D#e#e#e#e#e#e#e#e#e#B#v#0+e#A#B#B#A#A#A#A#A#.$I#C#A#A#A#A#A#A#A#A#A#t#G#A#A#A#A#A#A#A#A#A#0+Z#+$A#B#w at 0+0+0+0+0+0+I#L#+$F#F#F#F#F#F#F#F#F#`#Z#F#F#F#F#F#F#F#F#F# $M#G+F#F#F#F#F#F#F#F#E#v#M#H#E#E#E#E#E#E#E#E#D#q at Z#E#D#+$+$E#E#E#E#E#E#J#J#0+0+0+0+0+w at w@C#C#w at J#E#B#B#A#A#A#]@]@e#e#)#Z L L L L L T C ..O L L L L M M N N N P P P O M .r./#. ",
-" ' 9 L L L L L L L L L L L L L L L L L ..H P L L L L L S i K at K@K at P@P at P@M at M@M at L@L at L@N at N@N at b#b#O at O@O at O@8 at 8@Q at Q@Q at V@T at Y@+#Z at 4#4#4#4#`@`@`@X at X@X at X@.#.#.#*#*#*#'#'#'#########9#9#f#f#f#f#C at C@}#}#}#=#=#=#-#-#-#;#;#q.q.q.5#5#>#>#>#(#(#(#7#7#1#1#)#)#)#!#!#|#|#|#2#2#~#~#{#{#]#]#]#^#/#/#/#a+_#_#:#:#[#[#6#c#c#c#g#h#h#l#n#n#q#I I s#w#y#p.p.H+z#z#@$T##$e#]@A#A#B#C#w at 0+D#E#+$F#F#.$ $Y#G#H#v#I#I#q at J#t#r#r#G+i#$$$$B@`#`#Z#Z#K#K#L#L#p#p#p#X#X#M#M#M#M#M#M#{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@{@{@M#M#M#M#M#M#M#X#X#X#X#X#p#p#p#p#L#L#L#L#K#K#K#K#Z#Z#Z#`#`#`#B at B@B@$$$$$$i#i#G+G+G+r#r#r#t#t#v#J at L L L L L L ..z x W T R S T U V V V U T T R N L L t ' ",
-" ~ t at U N L L L L L L L L L L L L L L S w E L L L L L L q &#K at K@K at P@P at M@M at M@M at L@L at N@N at N@N at b#b#O at O@O at 8@8 at Q@V at T@K +#Z at Z@Z at 4#4#4#4#`@`@`@`@X at X@X at .#.#.#*#*#*#*#'#'#'#######9#9#9#f#f#f#C at C@C@}#}#}#=#=#-#-#-#-#;#;#q.q.q.5#5#>#>#>#(#(#7#7#7#1#1#)#)#)#!#!#|#|#|#2#2#~#~#{#{#]#]#^#^#/#/#/#a+_#_#:#:#[#[#6#c#c#g#g#h#h#l#n#n#q#I s#w#w#y#p.p.H+z#@$T#T##$e#]@A#B#C#C#0+0+D#E#+$F#.$ $Y#G#G#v#v#I#q at J#t#t#r#G+i#$$$$B@`#`#Z#K#K#L#L#p#p#p#X#X#M#M#M#M#{@{@{@{@{@k#k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@{@M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#{@{@{@{@{@{@{@{@{@{@{@{@{@{@k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@{@M#M#M#M#M#M#M#X#X#X#X#X#p#p#p#p#L#L#L#L#K#K#K#K#Z#Z#Z#`#`#`#B at B@B@$$$$$$i#i#G+G+G+r#r#r#t#t#]@r L L L L L r.&.[ 4 F ..Z Z Y X r.U R P N M L L L 3 & ",
-" # j t at t@@.U Q N M L L L L L L L L L r at 0 V L L L L L ..,#K at K@K at P@P at P@M at M@M at L@L at L@N at N@N at b#b#b#O at O@8@@#R at K +#+#+#Z at Z@Z at Z@4#4#4#4#`@`@`@X at X@X at X@.#.#.#*#*#*#*#'#'#########9#9#9#f#f#f#C at C@C@}#}#}#=#=#-#-#-#;#;#;#q.q.q.5#5#>#>#>#(#(#7#7#7#1#1#)#)#)#!#!#|#|#|#2#~#~#~#{#{#]#]#^#^#/#/#a+a+_#_#:#:#[#[#6#c#c#g#h#h#l#n#n#q#I I s#w#w#y#p.H+z#z#@$T##$e#e#A#A#B#C#w at 0+D#E#+$F#F# $ $Y#G#H#v#I#q at J#t#t#r#G+i#$$$$B@`#`#Z#K#K#L#L#p#p#X#X#M#M#M#M#{@{@{@k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@{@M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@{@M#M#M#M#M#M#X#X#X#X#X#p#p#p#p#L#L#L#L#K#K#K#K#Z#Z#Z#`#`#`#B at B@B@$$$$$$i#i#G+G+G+r#r#t#t#t#>#W L L L L U H n A at s@+.V S P N M L L L L L L L L 4#J ",
-" J _#U @.Y V U T S Q P O M M L L L .%#3 N L L L L N c K at K@K at K@P at P@P at M@M at M@L at L@L at N@N at N@b#b#O at Q@R at W@Y at +#+#+#+#Z at Z@Z at Z@4#4#4#4#`@`@`@`@X at X@X at .#.#.#*#*#*#*#'#'#'#########9#9#f#f#f#f#C at C@}#}#}#}#=#=#-#-#-#;#;#;#q.q.q.5#5#>#>#>#(#(#7#7#7#1#1#)#)#)#!#!#|#|#|#2#~#~#~#{#{#]#]#^#^#/#/#a+a+_#_#:#[#[#[#6#c#c#g#h#h#l#n#n#q#I I s#w#w#y#p.H+z#z#T#T##$e#]@A#A#C#C#w at 0+D#E#+$F#.$ $Y#G#H#v#v#q at q@J#t#r#G+G+i#$$B@`#`#Z#K#K#L#L#p#p#X#X#M#M#{@{@{@k#k#k#k#k#k#k#k#&$&$&$&$&$&$&$&$k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@{@M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#M#{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@{@M#M#M#M#M#M#X#X#X#X#X#p#p#p#p#L#L#L#L#K#K#K#Z#Z#Z#Z#`#`#`#B at B@B@$$$$i#i#i#G+G+G+r#r#t#t#G#k L L L L N x D at u P L L L L L L L L L L L L L Q J# ",
-" O#` P O M L L L L L M M M L L L ..G at t O L L L L t at I@K at K@K at P@P at P@M at M@M at M@L at L@N at N@N at b#8 at a#U at Y@Y at Y@+#+#+#+#Z at Z@Z at Z@4#4#4#4#4#`@`@`@X at X@X at X@.#.#.#*#*#*#*#'#'#'#######9#9#9#f#f#f#f#C at C@}#}#}#=#=#=#-#-#-#;#;#q.q.q.q.5#5#>#>#>#(#(#7#7#7#1#1#)#)#)#!#!#|#|#|#2#~#~#~#{#{#]#]#^#^#/#/#a+a+_#_#:#[#[#6#6#c#c#g#h#h#l#n#n#q#I I s#w#y#p.p.H+z#@$T#T#e#e#]@A#B#C#w at 0+D#E#E#F#F# $ $Y#G#H#v#I#q at J#t#r#G+G+i#$$B@`#`#Z#K#K#L#p#p#X#X#M#M#M#{@{@k#k#k#k#k#&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@{@{@M#M#M#M#M#M#M#M#M#M#M#M#M#M#{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@{@M#M#M#M#M#M#X#X#X#X#p#p#p#p#p#L#L#L#K#K#K#K#Z#Z#Z#`#`#`#B at B@B@$$$$$$i#i#i#G+G+G+r#r#t#t#s#C L L L N B S at H L L L L L L L L L L L L L L y ~ ",
-" > z at N N L L L L L L L L L L L L M s at H T L L L U u at K@K at K@K at P@P at P@M at M@M at L@L at L@N at O@V at U@K Y at Y@Y at Y@+#+#+#+#+#Z at Z@Z at Z@4#4#4#4#`@`@`@`@X at X@X at .#.#.#.#*#*#*#'#'#'#########9#9#9#f#f#f#C at C@C@}#}#}#=#=#=#-#-#-#;#;#q.q.q.q.5#5#>#>#>#(#(#7#7#7#1#1#)#)#)#!#!#|#|#2#2#~#~#~#{#{#]#]#^#^#/#/#a+a+_#_#:#[#[#6#6#c#c#g#h#h#l#n#n#q#I s#w#w#y#p.p.z#z#@$T##$e#e#A#A#B#C#w at 0+D#E#+$F#.$ $Y#G#H#v#v#q at q@J#t#r#G+i#$$$$B@`#Z#K#K#L#p#p#X#X#M#M#{@{@k#k#k#k#&$&$&$&$N#N#N#N#N#N#N#N#N#N#N#N#N#&$&$&$&$&$&$&$k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@{@{@{@{@M#M#M#M#M#M#M#M#{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@M#M#M#M#M#M#X#X#X#X#X#p#p#p#p#p#L#L#L#K#K#K#K#Z#Z#Z#`#`#`#B at B@B@$$$$$$i#i#G+G+G+r#r#r#t#q at 4#S L L P &.n P L L L L L L L L L L L L L L 3#+ ",
-" d#+#L M L L L L L L L L L L L L L ..t at W L L L l &#x at K@K at K@P at P@P at M@M at M@L at b#@#U at K K Y at Y@Y at Y@+#+#+#+#+#+#Z at Z@Z at 4#4#4#4#4#`@`@`@X at X@X at X@X at .#.#.#*#*#*#*#'#'#'#######9#9#9#9#f#f#f#C at C@C@}#}#}#=#=#=#-#-#-#;#;#q.q.q.5#5#5#>#>#>#(#(#7#7#7#1#1#)#)#)#!#!#|#|#2#2#~#~#~#{#]#]#]#^#^#/#/#a+_#_#:#:#[#[#6#c#c#g#g#h#l#l#n#q#I I s#w#y#p.p.H+z#@$T#T#e#e#A#A#B#C#w at 0+D#E#+$F#.$ $Y#G#H#v#I#q at J#t#r#G+i#$$$$`#`#Z#K#K#p#p#X#M#M#M#{@k#k#&$&$&$N#N#N#W#W#W#W#W#W#W#V#V#V#V#V#V#W#W#W#W#W#N#N#N#N#N#N#N#N#N#&$k#k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@M#M#M#M#M#M#M#X#X#X#X#p#p#p#p#p#L#L#L#K#K#K#K#Z#Z#Z#`#`#`#`#B at B@$$$$$$i#i#i#G+G+G+r#r#t#t#F#a L L T z A L L L L L L L L L L L L L L L l# ",
-" v#O L L L L L L L L L L L L L L U t at ..M L $.,#&#x at x@K at K@K at K@K at P@N at Q@T at Y@+#+#+#+#+#+#+#+#+#+#Z at Z@4#4#4#4#4#4#4#`@`@`@X at X@X at X@X at X@.#.#.#*#*#*#*#'#'#'#########9#9#9#f#f#f#f#C at C@C@}#}#}#=#=#=#-#-#-#;#;#;#q.q.q.5#5#>#>#>#(#(#(#7#7#7#1#1#)#)#!#!#|#|#|#2#2#~#~#~#{#]#]#]#^#/#/#a+a+_#_#:#[#[#6#6#c#g#g#h#l#n#n#q#I s#s#w#y#p.H+z#z#T#T#e#e#A#A#C#C#0+D#E#+$F#.$ $Y#G#v#v#q at J#t#r#G+i#$$B@`#Z#K#L#p#X#M#{@k#k#&$N#N#W#V#V#U#O#O#O#O#p at v@v at v@v at v@v at v@v at v@v at v@v at v@v at v@v at p@p at p@O#O#O#O#U#U#U#V#V#V#V#W#W#N#N#N#N#N#N#N#&$k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@{@k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#k#{@{@{@{@{@{@M#M#M#M#M#M#M#M#M#M#X#X#X#p#p#p#p#p#p#p#L#K#K#K#K#K#K#Z#Z#`#`#`#`#`#B@$$$$$$$$$$i#G+G+G+G+r#t#t#t#t#t#/#..N r.s G L L L L L L L L L L L L L L @.R# ",
-" ( s at L L L L L L L L L L L L L L N *.C C +.2 J at J@J at J@J at S@S@&#M at U@Z at 4#4#4#4#4#4#4#4#4#4#4#4#4#4#4#`@`@`@X at X@X at X@X at X@X at X@.#.#.#.#.#.#*#*#*#*#*#'#'#'#############9#9#f#f#f#f#f#f#f#}#}#}#}#}#}#=#-#-#-#-#-#-#;#q.q.q.q.5#5#5#>#>#>#(#(#7#7#7#1#1#1#)#)#!#!#|#|#|#2#2#~#~#{#{#]#]#^#^#/#a+a+_#_#:#[#[#6#c#c#g#h#h#n#n#q#I s#w#y#p.p.H+z#T#T#e#e#A#A#C#w at 0+D#E#+$F# $Y#G#H#v#I#q at t#t#G+i#$$B@`#Z#K#L#p#p#X#M#{@k#k#&$N#N#W#V#V#U#U#U#O#O#O#O#p at p@p at p@p at p@p at p@p at O#O#O#O#O#O#O#O#U#U#U#V#V#V#V#V#W#W#W#N#N#N#N#N#N#N#N#N#N#&$&$&$&$N#&$&$&$&$&$N#N#N#N#N#N#N#N#N#N#N#N#N#W#W#W#W#W#W#V#V#V#V#V#V#V#V#V#V#V#V#V#V#V#V#V#W#W#W#W#W#W#N#N#N#N#N#N#&$&$&$k#k#k#k#{@{@{@M#M#M#M#X#p#p#p#p#L#L#K#K#K#K#Z#`#`#`#B at B@B@$$$$$$i#G+G+G+G+G+r#t#t#t#J#J#q at q@q at I#I#v#v#v#H#H#G#F#F at F @.r V L L L L L L L L L L L L L L 7 * ",
-" + ,#L L L L L L L L L L L L L L L &.a [ s@ #. at .@.@,#H at J@J at S@N@*#f#f#f#f#f#f#f#f#f#f#f#f#f#f#f#f#f#f#f#f#f#f#C at C@C at C@C at C@C@}#}#}#}#}#}#=#-#-#-#-#-#-#;#;#;#q.q.q.q.5#>#>#>#>#>#(#(#(#(#7#7#7#7#1#)#)#)#)#)#!#!#|#|#|#2#2#2#~#~#~#{#{#]#]#^#]#/#/#/#/#a+a+_#:#[#[#6#6#c#c#g#g#h#h#l#l#n#n#q#I I I w#w#w#y#p.p.H+z#z#@$T#T##$e#]@]@A#B#w at 0+0+D#E#+$F#F#.$ $Y#G#H#v#v#I#q at J#t#t#r#G+i#$$$$`#`#Z#K#L#p#M#{@k#k#&$N#N#W#V#U#U#O#O#v at v@%$y at P#Q#Q#_ _ S#x#x#u#/ / =.^ ^ -$] ] { ( m#m#*$=$~ ~ ~ ~ ! ! ) ) ) ) ) ' 8#8#, , ; ; ; - - > > > > = j#j#j#j#* * & & & & % % o#o#o#o#o#$ $ $ $ # # # # # # # # # # # # # # # $ $ o#o#o#o#% % & & & * * j#j#j#= > > > - ; ; ; ; ; , 8#8#8#' ) ! ~ *$m#( ( { ] -$^ =./ u#x#S#_ Q#P#R#y at y@%$v at p@O#O#U#V#W#W#N#&$&$k#{@M#M#X#X#p#A#i 8 p O L L L L L L L L L L L L L L 4#J ",
-" q#L L L L L L L L L L L L L L L T z +.s@%#u at u@u@ #E at .@I at M@8 at K 9#7#^#:#6#c#c#c#c#c#c#c#c#c#c#c#c#c#c#c#c#g#g#g#h#h#h#h#h#h#h#l#l#n#n#n#n#n#q#I I I I I s#w#w#w#w#y#p.p.p.p.H+H+z#z#z#@$T#T#T##$#$e#e#]@]@A#A#B#B#C#C#w at w@0+0+D#D#E#E#+$F#F#.$.$ $Y#Y#G#G#H#v#v#I#q at q@J#t#t#r#G+G+i#$$$$B@`#Z#Z#K#L#p#p#X#M#M#k#k#&$N#N#V#V#U#O#O#v at v@%$y at R#P#P#_ _ S#x#u#/ =.^ ^ ] ] ( ( m#*$=$~ ! ) ' 8#, ; - > = j#* & % o#$ # @ + 9 at . . d#d#J J J J d#. + + # o#% & j#= > - ; 8#' ) ! ~ =$*$m#( { ] ] ^ ^ / N#u at u ..L L L L L L L L L L L L L L Q J# ",
-" %$+.L L L L L L L L L L L L L L L L L $.z at a } [ < < i i i j A at 3#0#P at U@##1#_#l#s#w#y#y#y#y#y#y#y#y#y#p.p.p.p.p.p.p.H+H+H+H+z#z#z#z#@$@$@$T#T#T##$#$#$e#e#e#]@]@A#A#A#B#B#C#C#C#w at 0+0+0+D#D#E#E#+$+$F#F#.$.$ $Y#Y#G#G#H#H#v#v#I#q at q@J#t#t#r#G+G+i#$$$$B@`#`#Z#K#K#L#p#p#X#M#M#k#k#&$N#N#W#V#U#O#O#p at v@%$y at y@R#P#Q#_ _ x#x#u#/ =.^ -$] { ( ( m#*$=$~ ! ) ' 8#, ; - > = j#* & % o#$ # @ + 9 at . . d#J J J . 9 at + # $ o#& & j#= > - ; 8#8#) ) ~ ~ =$m#y at F#)#o L L L L L L L L L L L L L L L L y ~ ",
-" & d L L L L L L L L L L L L L L L L L L L O W @.D A s n 4 3 2 c e | } g k <#&#R@=#]#h#H+T#e#e#e#e#e#e#e#]@]@]@]@]@A#A#A#A#B#B#B#B#C#B#B#C#C#C#C#w at w@0+0+0+D#D#E#E#E#+$+$F#F#.$.$ $ $Y#Y#G#G#H#H#v#v#I#q at q@J#J#t#r#r#G+G+i#$$$$B@`#`#Z#K#K#L#p#p#X#M#{@{@k#&$N#N#W#V#U#O#O#p at v@v at y@y at R#P#Q#_ _ x#x#u#/ =.^ ^ ] ] ( ( m#*$=$~ ! ) ' 8#, ; - > = j#* & % o#$ # @ + 9 at . d#J J J . 9 at + @ # $ o#& & j#= > - 8#! =$*$m#( ] v at e#+#| G L L L L L L L L L L L L L L L L L 3#+ ",
-" J -#L L L L L L L L L L L L L L L L L L L L L L L L L L L R V Z +.D z p 4 b } [ D at E@H at Q@.#|#I C#G#t#G+G+G+G+G+G+r#t#J#q at I#H#G# $F#D#w at C#C#C#C#w at w@0+0+0+0+D#E#E#E#E#+$F#F#F#.$ $ $ $Y#G#G#G#H#v#v#v#I#q at q@J#J#t#t#r#G+G+i#$$$$B@`#`#Z#K#K#L#p#p#X#M#M#{@k#&$N#N#W#V#V#U#O#p at v@v@%$y at R#P#P#_ _ S#x#u#/ / =.^ -$] { ( m#*$=$~ ! ! ) ' 8#, ; - > = j#* & % o#$ # @ + 9 at . J J J J . 9 at + # $ o#% & * j#> ; *$/ y at W#M#v#^#0#x R L L L L L L L L L L L L L L L L L L L l# ",
-" i#Q L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M U Z G C y z at 2 i 3#S at R@C at _#T# $G+Z#L#K#B at G+t#I#H# $F#D#C#A#]@]@A#A#A#A#B#B#C#C#C#C#w at w@0+0+D#D#D#E#E#+$+$F#F#.$.$ $ $Y#Y#G#G#H#H#v#v#I#q at q@J#t#t#r#r#G+G+i#$$$$B@`#`#Z#K#K#L#p#X#X#M#{@{@k#&$N#N#W#V#U#O#O#p at v@%$y at y@R#P#Q#_ _ S#x#u#/ / ^ ^ ] ] { ( m#*$*$~ ~ ) ) 8#8#; ; - > = j#* & % o#$ # + + . d#J J J J . + @ # o#% & * j#> ; *$u#v at r#)#} @.L L L L L L L L L L L L L L L L L L L L L @.R# ",
-" ) t L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L N V ..%.r at v 7 [ G at T@-#_#H+w at +$F#+$0+C#]@T#T#T#T#T##$#$#$e#e#e#]@]@]@A#A#B#B#B#C#C#w at w@0+0+0+D#D#E#E#+$+$F#F#.$.$ $ $Y#G#G#H#H#v#v#I#q at q@J#J#t#r#r#G+G+i#$$$$B@`#`#Z#K#K#L#p#p#X#M#M#k#k#&$N#N#W#V#V#O#O#p at v@v at y@y at R#P#P#_ _ S#x#u#/ / ^ ^ -$] { ( m#*$=$~ ! ) ) ' 8#, ; - > = j#* & o#o## # + 9 at . d#J J J . 9@@ # o#% & j#= > - 8#^ `#}#l T L L L L L L L L L L L L L L L L L L L L L L L 7 * ",
-" . P at L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L P V ` E x 7 i G at V@##5#q.=#=#=#=#-#-#-#-#-#-#;#q.q.q.q.q.5#5#5#>#>#>#>#(#7#7#7#7#1#1#)#)#)#)#!#|#1#7#1#1#)#)#)#!#|#|#|#2#2#~#~#~#{#]#]#]#^#^#/#/#a+_#_#_#:#:#_#/#/#a+a+_#_#:#[#[#6#6#c#c#g#h#h#h#[#6#6#c#c#g#h#h#l#n#n#q#I I I w#w#y#y#p.p.H+z#@$@$T##$e#e#]@A#A#B#C#C#A#e#e#]@A#A#B#C#w at 0+0+D#E#+$F#F#.$ $Y#G#H#v#I#q at q@t#t#G+G+i#i#$$$$$$B at B@`#`#`#Z#Z#K#$$$$$$$$$$B at B@`#`#`#Z#Z#K#K#K#K#L#L#p#p#p#p#X#X#M#M#M#{@{@k#k#k#M#K#K#K#L#L#L#p#p#p#p#p#p#p#`#i#i#i#i#i#i#i#i#G+G+G+G+G+G+G+r#r#r#t#t#t#t#J#J#q at q@q at I#I#v#v#v#H#H#G#G#Y#Y# $ $ $.$F#w at A#e##$T#z#H+p.y#w#I q#n#l#h#g#6#[#:#_#a+/#/#]#]#{#~#2#|#|#!#)#)#7#7#7#-#j H L L L L L L L L L L L L L L L L L L L L L L L L L L 4#J ",
-" z#L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M N N N N O P P Q R R R S T V W X Z ...+.#.G $.F %.E C C &.B *.H H r at s@s at -.t@A A A t at t@t at t@-.s at s@r at H *.B &.C D E %.F $.G @.+... .` Z Y X W r.U T R Q Q P O N N N M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L Q J# ",
-" _ %.L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N O P P Q R S T U r.W X Y Y ` ` .... at .@.G G F F E E D C &.B B *.H H H r at r@r at s@s at s@r at r@r at H H *.*.B &.C C E E %.F G G @. at .....` ` Y Y X r.V T S R Q P P O N N N M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L y ~ ",
-" o#} L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N O O P Q R R T T V r.W X Y Z ` ` .... at .@.#.G $.F F %.E D C C C &.&.B B B B B B B B B &.&.C C D E E %.F $.G #. at .@.....` ` Y Y X W r.U T S R Q P O O N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L 3#+ ",
-" J >#L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N O O P P Q R S T U V W X Y Y Z ` ` ....+. at .@.G G $.F F F %.E E E E D D D D D D E E E E %.%.F F $.G G @. at .+.....` ` Y Y X W r.V T S R Q P P O O N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L I ",
-" p#V L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N O P P Q R R S T V r.W X Y Y Y ` ` .....+. at .@.#.G G G $.F F F F F F F F F F F F $.G G G #. at .@.+..... .` ` Y Y X W r.V U T R R Q P P O N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L +.R# ",
-" ; p L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N O O P P Q R R T T V r.W W X Y Y Z ` ` .......+. at .@. at .@.#.G G G G G G G G #. at .@. at .@.+....... .` ` Z Y Y X W r.V U T S R Q P P O O N N N M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L 7 * ",
-" . 8 at L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M M N N N O O P P Q R R T T U V r.W X Y Y Y Z ` ` ` .............+.+. at .@.+.+............. .` ` ` Z Y Y X X W r.V U T S R Q P P O O N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L `@J ",
-" E#L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N N O P P P Q R R S T U V r.W W X Y Y Y Y Y ` ` ` ` ` ` ` ` . .` ` ` ` ` ` ` ` Y Y Y Y X W W r.V V T T S R R Q P P O N N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L P G+ ",
-" ] H L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M N N N N O P P P Q R R S T T U V r.r.W W X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y X X W W r.V V U T T R R Q P P P O O N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L y ~ ",
-" # j L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M M N N N N O O P P Q Q R R S T T U V V V r.W W W W W W X X X X X X W W W W W W r.V V U T T T R R R Q P P P O O N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L E at + ",
-" J _#L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M M N N N N O O P P P P R R R R S T T T U U V V V V V V V V V V V V V U U T T T S S R R R Q P P P O O N N N N M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L I ",
-" O#Z L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L M M M M M N N N N N N N N N O O O O O O O O O O O O O O N N N N N N N N M M M M M L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L +.P# ",
-" j#a L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L h % ",
-" J {#O L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L L S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S R Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y X ..+.+.+.+.+.+.+.+.+.G F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F E C C C C C C C C C C C C C C C C C C C C C C C C C C C C C B s at s@s at s@s at s@s at s@s at s@s at s@s at s@s at s@s at s@s at -.z z z z z z z z z v t t t t t t t t t t t t t t t q 3 w# ",
-" ; &$t#q at q@q at q@q at q@q at q@q at B#Y at B#q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@q at q@G+$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$M#&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$N#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#O#v at R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#R#S#x#x#x#x#x#x#x#x#x#=.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ] ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( =$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$=$~ ) ) ) ) ) ) ) ) ) 8#, , , , , , , , , , , , , , , - % . ",
-" 5#2#r U@[ R# ",
-" k s at p $#s A@) ",
-" X#i v A at -#X#A at c# ",
-" X#. at z G# $#v R# ",
-" X#0#K n#u at G# X#X#^#^# ",
-" X#3#-# G#i ) X#^#X#X#X#X# ",
-" G#| G# n#l X#T#T#X# X#X# ",
-" ) ) ) ) ) ) ) ) ) G#5 #$) ) ) c {#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) R#G#5#G#R#) ) ) ) ) G#G#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ",
-" T#T#T#T#T#T#T#T#T#T#s $#T#T#u 9 T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#a#c#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#a#c#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#c#a#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#;$>$,$,$y#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#-#-#T#T#T#T#T#T#T#T#T#T#T#T#c#a#a#-#T#T#T#T#T#T#T#T#-#-#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#a#c#T#T#T#T#T#T#T#T#T#T# ",
-" ) d !# n n ) T#) '$)$ T#) !$~$,$,${$ ]$,$>$^$/ !$/$,$,$($;$= B at _$,$,$:$<$[$}$|$1$. !$/$,$,$($;$= ) T# %$/$,$,$:$2$3$4$5$% = ,$6$ X#X# ) T#T#) X#X# T#) ",
-" a#n $.b -# T#) 7$8$9$ T#) . ,$,$0$ ] a$,$b$ 9@,$,$=. 9@,$a$+ c$d$,$^$9@ 9@,$,$=. ) T# . ,$a$+ e$,$f$ g$,$h$ X#X# ) T#T#) ^# T#) ",
-" ) ) ) ) ) ) ) ) R#C at G A 5 G#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) c#R#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ~ i$,$j$! ) ) ) ) ) ) c#R#) ) ) S#k$,$,$S#) ) ) ) ) ) l$m$,$u#) ) ) ) ) ) ) ) n$,$m$! ) ) ) ) ) ) ) ) n$,$o$) ) ) ) ) p$,$q$) ) ) ) ) ) ) ) n$,$m$! ) ) ) ) ) ) ) ) R#c#) ) ) ) ) ) ) ) ) Q#,$o$) ) ) ( ,$a$! ) ) ) ) ) ) r$,$s$) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) G#G#) ) ) ) ) ) ) G#c#R#) ) ) ) ) ) ) ) ) ) ) ) ) G#G#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) c#R#) ) ) ) ) ) ) ) ) ) ",
-" T#T#T#T#T#T#T#`@r T S G T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#a#c#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#t$u$,$,$l#T#T#T#T#T#T#a#c#T#T#T#v$0$j$,$w$T#T#T#T#T#x$2$8$y$T#T#T#T#T#T#T#T#T#f$,$z$T#T#T#T#T#T#T#T#T#A$,$B$T#T#T#T#T#d$,$C$T#T#T#T#T#T#T#T#f$,$z$T#T#T#T#T#T#T#T#T#c#a#T#T#T#T#T#T#T#T#T#D$,$B$T#T#T#H+,$,$@$T#T#T#T#T#T#E$,$[#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#-#-#T#T#T#T#T#-#S at -#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#S at T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#a#c#T#T#T#T#T#T#T#T#T#T# ",
-" `@8 Q W b '#X# T#) > F$+ 4$,$K# T#) G$]$d$,$H$ o#x$S#,$I$ J$,$q$ s$,$G$ @ ,$a$J J$,$q$ ) T# K$,$G# -$,$o$ 9 at k$a$L$ M$,$,$v$ . N$,$E$ J O$_$P$y$,$,$,$Q$+ X#X# ) T#X# X#X# T#) ",
-" T#5 l +.G#R#-#K ) T#) h$R$ x$,$S$ T#) T$U$V$,$<$ H$W$X$,$Y$ Z$,$b$ `$,$v@ d#,$,$9@ Z$,$b$ ) T# d$,$%$ %,$J$ / ,$_$ d#a$,$K$ o#,$w$ .%8$!$ +%8$J#P#@% X#X# X#T#) ^# ) X#X#X# T#) ",
-" ) ) ) ) ) 5#6 ` #$) c#X at 5 $#g#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) c#R#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) #%l$) ) $%,$%%) ) ) ) ) ) c#R#) ) ) &%*%=%,$-%*$) ) v@{$) ;%,$U$) ) ) ) ) ) ) ) ) [$,$R$) ) ) ) ) ) ) ) ) >%,$/ ) ) ) ) ) u#,$,%) ) ) ) ) ) ) ) [$,$R$) ) ) ) ) ) ) ) ) R#c#) ) ) ) ) ) ) ) ) '%,$=.) ) =%k$z$( ) ) ) ) ) ) Y$,$d$) ) ) ) ) ) ) x#,$,$)%) ) {@,$]$) ) ) ) ) ) !%,$f$) ) -$,$Q$) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) G#G#) ) G#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) G#G#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) R#5#c#G#I@#$) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) c#R#) ) ) ) ) ) ) ) ) ) ",
-" T#T#T#T#T#. at F 9 c#P at 2 p y u at s $#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#a#c#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#z#~%5$T#T#D$,$a$z#T#T#T#T#T#a#c#T#T#@$a$H+@$a$,$6#T#T#3$s#T#{%,$]%T#T#T#T#T#T#T#T#H+8$8$z#T#T#T#T#T#T#T#T#s#,$^%T#T#T#T#T#T#:#,$>%T#T#T#T#T#T#T#H+8$8$z#T#T#T#T#T#T#T#T#T#c#a#T#T#T#T#T#T#T#T#z#8$y$T#H+!#k$4$5$T#T#T#T#T#T#T#/%,$(%T#T#T#T#T#T#T#:#,$,$y#T#T#7#,$A$T#T#T#T#T#T#Q$,$/#T#T#q#,$-%T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#-#-#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#c#a#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#-#a#T#T#c#-#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#a#c#T#T#T#T#T#T#T#T#T#T# ",
-" -#..X@) | {#X#'#X#-#i T#) _%s$ = ,$,$7$ T#) { 6$ ^$,$:% <%G# d#[%}% @%,$u$ U#,$x$ G$,$$% @%,$u$ ) T# ^ ,$}$^$P$|%{@d# 1%,$] 2%,$[$ .%,$3% 4$,$4% g$,$5% X#X# ^# X#^#X# X#T#T# T#) ",
-" G#+.R# I@{#) c#T# n R# T#) ) o$@ 6%,$1$ T#) #%Z$ 7%,$8%# 5%. m#,$x$ U$,$d$ 9%,$0% 2$,$=. U$,$d$ + 9$;$:$a%l$@ b%,$S$ & ,$^%d# 0%,${$ B$}$ c%,$% ;$a$S# X#X# X#X# X#^#X# X#^#X#) T#) ",
-" ) ) ) ) ) ) v }#) |#x K M at c#R#8 R#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) c#R#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ;$d%_$_$_$_$_$}$,${$) ) ) ) ) c#R#) ) ]%e%) ) U$,$E$'$K#) ) :%,$'$) ) ) ) ) ) ) ) ) .%,$q$) ) ) ) ) ) ) ) ) f%,$g%) ) ) ) ) %$8$|$) ) ) ) ) ) ) ) .%,$q$) ) ) ) ) ) ) ) ) ) R#c#) ) ) ) ) ) ) ) 5$,$J$) ) ) ) ) ) ) ) ) ) ) ) `#,$/$) ) ) ) ) ) ) ) h%,$q$) ) { 8$P$) ) ) ) ) ) ) i%>%r#! %a$G$) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) G#G#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) G#G#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) R#c#G#) R#c#G#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) c#R#) ) ) ) ) ) ) ) ) ) ",
-" T#T#T#T#T#T#9 } -#T#`@x l a#T#v !#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#a#c#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#A$j%T#T#T#T#T#T#(%,$m$T#T#T#T#T#a#c#T#T#[$]#T#T#w#,$,$&%T#T#T#k%,$A$T#T#T#T#T#T#T#T#T#0$,$D$T#T#T#T#T#T#T#T#T#>$,$l%T#T#T#T#T#3$a$l#T#T#T#T#T#T#T#T#0$,$D$T#T#T#T#T#T#T#T#T#T#c#a#T#T#T#T#T#T#T#T#6%,${$T#T#T#T#T#T#T#T#T#T#T#T#m%,$F$T#T#T#T#T#T#T#T#>%,$a+T#T#:#,$k%T#T#T#T#T#T#T#T#c#~%Q$B$n%T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#-#-#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#S at T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#-#a#!#-#a#a#c#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#a#c#T#T#T#T#T#T#T#T#T#T# ",
-" G#i '#X# ) S@) 2 ) T#) o#(%# c$,$8$o# T#) E$! 6$^%, o%,$! J }$,$3% * ,$-%d# G$8$K# J }$,$3% ) T# 4$,$, `$,$<% >$,$4% p%,$q% r%m$3% X#X# ^# X#5#n#T#T#X#) T#) ",
-" *#| X# G#`@a#a# T#) Z$x# 9@,$,$K# T#) 3%,$9@ l%9% + ^%,$9@ @%,$,$. #%,$4$. 3%s%>$<% @%,$,$. ) T# t%,$,$. d#}$,$= ,%,$N#v at p%P$,$t% E$,$N#=$; J X#X# X#X# ) n#S at K T#X#) ) X#X#T#^#^#^#^#^#^#^#K ^# T#) ",
-" ) ) ) ) ) ) ) ) G#m b b A@$.S@) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) c#R#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) R$6$,$u%) ) ) ) ) ) `#o$,$,$^%J#) ) ) c#X#:$>%,$i$2%) ) ) ) ) ) v%'%,$,$j%F#) ) ) ) ) S#:$}$,$,$i$b$) ) ) ) ) &$w%^%,$,$E$x%u$N$$%/ ) ) ) ) ) ) ) ) S#:$}$,$,$i$b$) ) ) ) ) ) ) ) ) R#c#) ) ) ) ) x#:$m$,$,$N$F#) ) ) ) ) ) ) ) ) 9%o$,$,$y%s$) ) ) ) ) ) ) ]$^%>%z%{ '%,$z$u#) ) ) ) ) ) [$,$,$,$,$j$s$) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) G#G#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) G#G#) ) ) ) ) ) ) ) R#G#G#c#5#. at 3#*#5#5#5#5#c#G#G#R#) ) ) ) G#c#5#G#) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) c#R#) ) ) ) ) ) ) ) ) ) ",
-" T#T#T#T#T#T#T#T#T#c#$#A at d 4 T#T#T#T#z#g#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#a#c#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#a#c#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#c#a#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#s#[$u$@$T#@$A$,$-%T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#-#-#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#S at a#S at S@S at S@S at S@a#-#-#c#T#T#T#T#T#T#T#T#T#T#T#T#T#T#-#S at -#c#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#a#c#T#T#T#T#T#T#T#T#T#T# ",
-" ) P@) X#J at A# u%,$; { ,$^$ ) T#X# ",
-" } n#X#h < N@ 4$,$U# ~ N$B$3% X#K ) ) X#X#X#X#X#X#X#X# ",
-" u at n# A at i G at G# 7$`$}$/$9$9$1$9@ X#K ^#^#T#X#X#X#X#X#X#-#X#X#X#X#X#X#X#X#X#X#X#X# ",
-" S at 5 `@-#c#|# X#G#^#X#X#X#X#X#X#X#X#X#X#X#T#) ",
-" X#K k ) c#P@) ) T#^#X#X# ",
-" n#U@`@ R#8 X#X#T# ",
-" X#N at v `@R#) 8 `@ ) ",
-" n#I at x g G at 6 X# ",
-" 6#s# ",
-" ",
-" ",
-" "};
diff --git a/src/amidi-plug/amidi-plug.midiicon.xpm b/src/amidi-plug/amidi-plug.midiicon.xpm
index 24b28ec03da4..bff0e97139b3 100644
--- a/src/amidi-plug/amidi-plug.midiicon.xpm
+++ b/src/amidi-plug/amidi-plug.midiicon.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * amidiplug_xpm_midiicon[] = {
+static const char * amidiplug_xpm_midiicon[] = {
"48 52 257 2",
" c None",
". c #000000",
diff --git a/src/amidi-plug/backend-fluidsynth/Makefile b/src/amidi-plug/backend-fluidsynth/Makefile
deleted file mode 100644
index f2f4dafc41ea..000000000000
--- a/src/amidi-plug/backend-fluidsynth/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-PLUGIN = ap-fluidsynth${PLUGIN_SUFFIX}
-
-SRCS = b-fluidsynth.c
-
-include ../../../buildsys.mk
-include ../../../extra.mk
-
-plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}/${AMIDIPLUG_BACKEND_DIR}
-
-CFLAGS += ${PLUGIN_CFLAGS} ${FLUIDSYNTH_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${FLUIDSYNTH_CFLAGS} ${GLIB_CFLAGS} -I../../..
-LIBS += ${FLUIDSYNTH_LIBS} ${GLIB_LIBS}
diff --git a/src/amidi-plug/backend-fluidsynth/b-fluidsynth.c b/src/amidi-plug/backend-fluidsynth/b-fluidsynth.c
deleted file mode 100644
index 12d2115985ec..000000000000
--- a/src/amidi-plug/backend-fluidsynth/b-fluidsynth.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2006
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <fluidsynth.h>
-#include <glib.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-
-#include "../i_backend.h"
-#include "../i_configure.h"
-#include "../i_midievent.h"
-
-/* #define DEBUGMSG(...) fprintf (stderr, __VA_ARGS__) */
-#define DEBUGMSG(...)
-
-typedef struct
-{
- fluid_settings_t * settings;
- fluid_synth_t * synth;
-
- GArray * soundfont_ids;
-}
-sequencer_client_t;
-
-/* sequencer instance */
-static sequencer_client_t sc;
-/* options */
-
-static void i_soundfont_load (void);
-
-void backend_init (void)
-{
- sc.soundfont_ids = g_array_new (FALSE, FALSE, sizeof (int));
- sc.settings = new_fluid_settings();
-
- fluid_settings_setnum (sc.settings, "synth.sample-rate",
- aud_get_int ("amidiplug", "fsyn_synth_samplerate"));
-
- int gain = aud_get_int ("amidiplug", "fsyn_synth_gain");
- int polyphony = aud_get_int ("amidiplug", "fsyn_synth_polyphony");
- int reverb = aud_get_int ("amidiplug", "fsyn_synth_reverb");
- int chorus = aud_get_int ("amidiplug", "fsyn_synth_chorus");
-
- if (gain != -1)
- fluid_settings_setnum (sc.settings, "synth.gain", gain / 10.0);
-
- if (polyphony != -1)
- fluid_settings_setint (sc.settings, "synth.polyphony", polyphony);
-
- if (reverb == 1)
- fluid_settings_setstr (sc.settings, "synth.reverb.active", "yes");
- else if (reverb == 0)
- fluid_settings_setstr (sc.settings, "synth.reverb.active", "no");
-
- if (chorus == 1)
- fluid_settings_setstr (sc.settings, "synth.chorus.active", "yes");
- else if (chorus == 0)
- fluid_settings_setstr (sc.settings, "synth.chorus.active", "no");
-
- sc.synth = new_fluid_synth (sc.settings);
-}
-
-
-void backend_cleanup (void)
-{
- if (sc.soundfont_ids->len > 0)
- {
- /* unload soundfonts */
- int i = 0;
-
- for (i = 0 ; i < sc.soundfont_ids->len ; i++)
- fluid_synth_sfunload (sc.synth, g_array_index (sc.soundfont_ids, int, i), 0);
- }
-
- g_array_free (sc.soundfont_ids, TRUE);
- delete_fluid_synth (sc.synth);
- delete_fluid_settings (sc.settings);
-}
-
-
-void backend_prepare (void)
-{
- /* soundfont loader, check if we should load soundfont on first midifile play */
- if (! sc.soundfont_ids->len)
- i_soundfont_load();
-}
-
-void backend_reset (void)
-{
- fluid_synth_system_reset (sc.synth); /* all notes off and channels reset */
-}
-
-
-void seq_event_noteon (midievent_t * event)
-{
- fluid_synth_noteon (sc.synth,
- event->data.d[0],
- event->data.d[1],
- event->data.d[2]);
-}
-
-
-void seq_event_noteoff (midievent_t * event)
-{
- fluid_synth_noteoff (sc.synth,
- event->data.d[0],
- event->data.d[1]);
-}
-
-
-void seq_event_keypress (midievent_t * event)
-{
- /* KEY PRESSURE events are not handled by FluidSynth sequencer? */
- DEBUGMSG ("KEYPRESS EVENT with FluidSynth backend (unhandled)\n");
-}
-
-
-void seq_event_controller (midievent_t * event)
-{
- fluid_synth_cc (sc.synth,
- event->data.d[0],
- event->data.d[1],
- event->data.d[2]);
-}
-
-
-void seq_event_pgmchange (midievent_t * event)
-{
- fluid_synth_program_change (sc.synth,
- event->data.d[0],
- event->data.d[1]);
-}
-
-
-void seq_event_chanpress (midievent_t * event)
-{
- /* CHANNEL PRESSURE events are not handled by FluidSynth sequencer? */
- DEBUGMSG ("CHANPRESS EVENT with FluidSynth backend (unhandled)\n");
-}
-
-
-void seq_event_pitchbend (midievent_t * event)
-{
- int pb_value = (( (event->data.d[2]) & 0x7f) << 7) | ((event->data.d[1]) & 0x7f);
- fluid_synth_pitch_bend (sc.synth,
- event->data.d[0],
- pb_value);
-}
-
-
-void seq_event_sysex (midievent_t * event)
-{
- DEBUGMSG ("SYSEX EVENT with FluidSynth backend (unhandled)\n");
-}
-
-
-void seq_event_tempo (midievent_t * event)
-{
- /* unhandled */
-}
-
-
-void seq_event_other (midievent_t * event)
-{
- /* unhandled */
-}
-
-
-void seq_event_allnoteoff (int unused)
-{
- int c = 0;
-
- for (c = 0 ; c < 16 ; c++)
- {
- fluid_synth_cc (sc.synth, c, 123 /* all notes off */, 0);
- }
-}
-
-
-void backend_generate_audio (void * buf, int bufsize)
-{
- fluid_synth_write_s16 (sc.synth, bufsize / 4, buf, 0, 2, buf, 1, 2);
-}
-
-
-void backend_audio_info (int * channels, int * bitdepth, int * samplerate)
-{
- *channels = 2;
- *bitdepth = 16; /* always 16 bit, we use fluid_synth_write_s16() */
- *samplerate = aud_get_int ("amidiplug", "fsyn_synth_samplerate");
-}
-
-
-/* ******************************************************************
- *** INTERNALS ****************************************************
- ****************************************************************** */
-
-static void i_soundfont_load (void)
-{
- char * soundfont_file = aud_get_str ("amidiplug", "fsyn_soundfont_file");
-
- if (soundfont_file[0])
- {
- char ** sffiles = g_strsplit (soundfont_file, ";", 0);
- int i = 0;
-
- while (sffiles[i] != NULL)
- {
- int sf_id = 0;
- DEBUGMSG ("loading soundfont %s\n", sffiles[i]);
- sf_id = fluid_synth_sfload (sc.synth, sffiles[i], 0);
-
- if (sf_id == -1)
- {
- g_warning ("unable to load SoundFont file %s\n", sffiles[i]);
- }
- else
- {
- DEBUGMSG ("soundfont %s successfully loaded\n", sffiles[i]);
- g_array_append_val (sc.soundfont_ids, sf_id);
- }
-
- i++;
- }
-
- g_strfreev (sffiles);
-
- fluid_synth_system_reset (sc.synth);
- }
- else
- {
- g_warning ("FluidSynth backend was selected, but no SoundFont has been specified\n");
- }
-
- str_unref (soundfont_file);
-}
diff --git a/src/amidi-plug/backend-fluidsynth/b-fluidsynth.cc b/src/amidi-plug/backend-fluidsynth/b-fluidsynth.cc
new file mode 100644
index 000000000000..098b13e05930
--- /dev/null
+++ b/src/amidi-plug/backend-fluidsynth/b-fluidsynth.cc
@@ -0,0 +1,233 @@
+/*
+*
+* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2006
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <fluidsynth.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/index.h>
+#include <libaudcore/runtime.h>
+
+#include "../i_backend.h"
+#include "../i_configure.h"
+#include "../i_midievent.h"
+
+typedef struct
+{
+ fluid_settings_t * settings;
+ fluid_synth_t * synth;
+
+ Index<int> soundfont_ids;
+}
+sequencer_client_t;
+
+/* sequencer instance */
+static sequencer_client_t sc;
+/* options */
+
+static void i_soundfont_load (void);
+
+void backend_init (void)
+{
+ sc.settings = new_fluid_settings();
+
+ fluid_settings_setnum (sc.settings, "synth.sample-rate",
+ aud_get_int ("amidiplug", "fsyn_synth_samplerate"));
+
+ int gain = aud_get_int ("amidiplug", "fsyn_synth_gain");
+ int polyphony = aud_get_int ("amidiplug", "fsyn_synth_polyphony");
+ int reverb = aud_get_int ("amidiplug", "fsyn_synth_reverb");
+ int chorus = aud_get_int ("amidiplug", "fsyn_synth_chorus");
+
+ if (gain != -1)
+ fluid_settings_setnum (sc.settings, "synth.gain", gain / 10.0);
+
+ if (polyphony != -1)
+ fluid_settings_setint (sc.settings, "synth.polyphony", polyphony);
+
+ if (reverb == 1)
+ fluid_settings_setstr (sc.settings, "synth.reverb.active", "yes");
+ else if (reverb == 0)
+ fluid_settings_setstr (sc.settings, "synth.reverb.active", "no");
+
+ if (chorus == 1)
+ fluid_settings_setstr (sc.settings, "synth.chorus.active", "yes");
+ else if (chorus == 0)
+ fluid_settings_setstr (sc.settings, "synth.chorus.active", "no");
+
+ sc.synth = new_fluid_synth (sc.settings);
+
+ /* load soundfonts */
+ i_soundfont_load();
+}
+
+
+void backend_cleanup (void)
+{
+ /* unload soundfonts */
+ for (int id : sc.soundfont_ids)
+ fluid_synth_sfunload (sc.synth, id, 0);
+
+ sc.soundfont_ids.clear ();
+ delete_fluid_synth (sc.synth);
+ delete_fluid_settings (sc.settings);
+}
+
+
+void backend_reset (void)
+{
+ fluid_synth_system_reset (sc.synth); /* all notes off and channels reset */
+}
+
+
+void seq_event_noteon (midievent_t * event)
+{
+ fluid_synth_noteon (sc.synth,
+ event->d[0],
+ event->d[1],
+ event->d[2]);
+}
+
+
+void seq_event_noteoff (midievent_t * event)
+{
+ fluid_synth_noteoff (sc.synth,
+ event->d[0],
+ event->d[1]);
+}
+
+
+void seq_event_keypress (midievent_t * event)
+{
+ /* KEY PRESSURE events are not handled by FluidSynth sequencer? */
+ AUDDBG ("KEYPRESS EVENT with FluidSynth backend (unhandled)\n");
+}
+
+
+void seq_event_controller (midievent_t * event)
+{
+ fluid_synth_cc (sc.synth,
+ event->d[0],
+ event->d[1],
+ event->d[2]);
+}
+
+
+void seq_event_pgmchange (midievent_t * event)
+{
+ fluid_synth_program_change (sc.synth,
+ event->d[0],
+ event->d[1]);
+}
+
+
+void seq_event_chanpress (midievent_t * event)
+{
+ /* CHANNEL PRESSURE events are not handled by FluidSynth sequencer? */
+ AUDDBG ("CHANPRESS EVENT with FluidSynth backend (unhandled)\n");
+}
+
+
+void seq_event_pitchbend (midievent_t * event)
+{
+ int pb_value = (( (event->d[2]) & 0x7f) << 7) | ((event->d[1]) & 0x7f);
+ fluid_synth_pitch_bend (sc.synth,
+ event->d[0],
+ pb_value);
+}
+
+
+void seq_event_sysex (midievent_t * event)
+{
+ AUDDBG ("SYSEX EVENT with FluidSynth backend (unhandled)\n");
+}
+
+
+void seq_event_tempo (midievent_t * event)
+{
+ /* unhandled */
+}
+
+
+void seq_event_other (midievent_t * event)
+{
+ /* unhandled */
+}
+
+
+void seq_event_allnoteoff (int unused)
+{
+ int c = 0;
+
+ for (c = 0 ; c < 16 ; c++)
+ {
+ fluid_synth_cc (sc.synth, c, 123 /* all notes off */, 0);
+ }
+}
+
+
+void backend_generate_audio (void * buf, int bufsize)
+{
+ fluid_synth_write_s16 (sc.synth, bufsize / 4, buf, 0, 2, buf, 1, 2);
+}
+
+
+void backend_audio_info (int * channels, int * bitdepth, int * samplerate)
+{
+ *channels = 2;
+ *bitdepth = 16; /* always 16 bit, we use fluid_synth_write_s16() */
+ *samplerate = aud_get_int ("amidiplug", "fsyn_synth_samplerate");
+}
+
+
+/* ******************************************************************
+ *** INTERNALS ****************************************************
+ ****************************************************************** */
+
+static void i_soundfont_load (void)
+{
+ String soundfont_file = aud_get_str ("amidiplug", "fsyn_soundfont_file");
+
+ if (soundfont_file[0])
+ {
+ Index<String> sffiles = str_list_to_index (soundfont_file, ";");
+
+ for (const char * sffile : sffiles)
+ {
+ AUDDBG ("loading soundfont %s\n", sffile);
+ int sf_id = fluid_synth_sfload (sc.synth, sffile, 0);
+
+ if (sf_id == -1)
+ AUDWARN ("unable to load SoundFont file %s\n", sffile);
+ else
+ {
+ AUDDBG ("soundfont %s successfully loaded\n", sffile);
+ sc.soundfont_ids.append (sf_id);
+ }
+ }
+
+ fluid_synth_system_reset (sc.synth);
+ }
+ else
+ AUDWARN ("FluidSynth backend was selected, but no SoundFont has been specified\n");
+}
diff --git a/src/amidi-plug/i_backend.h b/src/amidi-plug/i_backend.h
index cabc315adb4c..54aecfbd05de 100644
--- a/src/amidi-plug/i_backend.h
+++ b/src/amidi-plug/i_backend.h
@@ -21,26 +21,25 @@
#ifndef _I_BACKEND_H
#define _I_BACKEND_H 1
-struct midievent_s;
+struct midievent_t;
void backend_init (void);
void backend_cleanup (void);
-void backend_prepare (void);
void backend_reset (void);
void backend_audio_info (int *, int *, int *);
void backend_generate_audio (void * buf, int bufsize);
-void seq_event_noteon (struct midievent_s *);
-void seq_event_noteoff (struct midievent_s *);
+void seq_event_noteon (midievent_t *);
+void seq_event_noteoff (midievent_t *);
void seq_event_allnoteoff (int);
-void seq_event_keypress (struct midievent_s *);
-void seq_event_controller (struct midievent_s *);
-void seq_event_pgmchange (struct midievent_s *);
-void seq_event_chanpress (struct midievent_s *);
-void seq_event_pitchbend (struct midievent_s *);
-void seq_event_sysex (struct midievent_s *);
-void seq_event_tempo (struct midievent_s *);
-void seq_event_other (struct midievent_s *);
+void seq_event_keypress (midievent_t *);
+void seq_event_controller (midievent_t *);
+void seq_event_pgmchange (midievent_t *);
+void seq_event_chanpress (midievent_t *);
+void seq_event_pitchbend (midievent_t *);
+void seq_event_sysex (midievent_t *);
+void seq_event_tempo (midievent_t *);
+void seq_event_other (midievent_t *);
#endif /* !_I_BACKEND_H */
diff --git a/src/amidi-plug/i_configure-fluidsynth.c b/src/amidi-plug/i_configure-fluidsynth.c
deleted file mode 100644
index d4cfe5d93350..000000000000
--- a/src/amidi-plug/i_configure-fluidsynth.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2006
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include "i_configure-fluidsynth.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#include <glib/gstdio.h>
-#include <gtk/gtk.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-
-#include "i_configure.h"
-
-enum
-{
- LISTSFONT_FILENAME_COLUMN = 0,
- LISTSFONT_FILESIZE_COLUMN,
- LISTSFONT_N_COLUMNS
-};
-
-static void i_configure_ev_sflist_commit (void * sfont_lv);
-
-void i_configure_ev_sflist_add (void * sfont_lv)
-{
- GtkWidget * parent_window = gtk_widget_get_toplevel (sfont_lv);
-
- if (gtk_widget_is_toplevel (parent_window))
- {
- GtkTreeSelection * listsel = gtk_tree_view_get_selection (GTK_TREE_VIEW (sfont_lv));
- GtkTreeIter itersel, iterapp;
- GtkWidget * browse_dialog = gtk_file_chooser_dialog_new (_("AMIDI-Plug - select SoundFont file"),
- GTK_WINDOW (parent_window),
- GTK_FILE_CHOOSER_ACTION_OPEN,
- _("_Cancel"), GTK_RESPONSE_CANCEL,
- _("_Open"), GTK_RESPONSE_ACCEPT, NULL);
-
- if (gtk_tree_selection_get_selected (listsel, NULL, &itersel))
- {
- char * selfilename = NULL, *selfiledir = NULL;
- GtkTreeModel * store = gtk_tree_view_get_model (GTK_TREE_VIEW (sfont_lv));
- gtk_tree_model_get (GTK_TREE_MODEL (store), &itersel, LISTSFONT_FILENAME_COLUMN, &selfilename, -1);
- selfiledir = g_path_get_dirname (selfilename);
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (browse_dialog), selfiledir);
- g_free (selfiledir);
- g_free (selfilename);
- }
-
- if (gtk_dialog_run (GTK_DIALOG (browse_dialog)) == GTK_RESPONSE_ACCEPT)
- {
- GStatBuf finfo;
- GtkTreeModel * store = gtk_tree_view_get_model (GTK_TREE_VIEW (sfont_lv));
- char * filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (browse_dialog));
- int filesize = -1;
-
- if (g_stat (filename, &finfo) == 0)
- filesize = finfo.st_size;
-
- gtk_list_store_append (GTK_LIST_STORE (store), &iterapp);
- gtk_list_store_set (GTK_LIST_STORE (store), &iterapp,
- LISTSFONT_FILENAME_COLUMN, filename,
- LISTSFONT_FILESIZE_COLUMN, filesize, -1);
-
- g_free (filename);
- }
-
- gtk_widget_destroy (browse_dialog);
- }
-
- i_configure_ev_sflist_commit (sfont_lv);
-}
-
-
-void i_configure_ev_sflist_rem (void * sfont_lv)
-{
- GtkTreeModel * store;
- GtkTreeIter iter;
- GtkTreeSelection * listsel = gtk_tree_view_get_selection (GTK_TREE_VIEW (sfont_lv));
-
- if (gtk_tree_selection_get_selected (listsel, &store, &iter))
- gtk_list_store_remove (GTK_LIST_STORE (store), &iter);
-
- i_configure_ev_sflist_commit (sfont_lv);
-}
-
-
-void i_configure_ev_sflist_swap (GtkWidget * button, void * sfont_lv)
-{
- GtkTreeModel * store;
- GtkTreeIter iter;
- GtkTreeSelection * listsel = gtk_tree_view_get_selection (GTK_TREE_VIEW (sfont_lv));
-
- if (gtk_tree_selection_get_selected (listsel, &store, &iter))
- {
- unsigned swapdire = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (button), "swapdire"));
-
- if (swapdire == 0) /* move up */
- {
- GtkTreePath * treepath = gtk_tree_model_get_path (store, &iter);
-
- if (gtk_tree_path_prev (treepath))
- {
- GtkTreeIter iter_prev;
-
- if (gtk_tree_model_get_iter (store, &iter_prev, treepath))
- gtk_list_store_swap (GTK_LIST_STORE (store), &iter, &iter_prev);
- }
-
- gtk_tree_path_free (treepath);
- }
- else /* move down */
- {
- GtkTreeIter iter_prev = iter;
-
- if (gtk_tree_model_iter_next (store, &iter))
- gtk_list_store_swap (GTK_LIST_STORE (store), &iter, &iter_prev);
- }
- }
-
- i_configure_ev_sflist_commit (sfont_lv);
-}
-
-
-void i_configure_ev_sflist_commit (void * sfont_lv)
-{
- GtkTreeIter iter;
- GtkTreeModel * store = gtk_tree_view_get_model (GTK_TREE_VIEW (sfont_lv));
- GString * sflist_string = g_string_new ("");
-
- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter) == TRUE)
- {
- bool_t iter_is_valid = FALSE;
-
- do
- {
- char * fname;
- gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
- LISTSFONT_FILENAME_COLUMN, &fname, -1);
- g_string_prepend_c (sflist_string, ';');
- g_string_prepend (sflist_string, fname);
- g_free (fname);
- iter_is_valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
- }
- while (iter_is_valid == TRUE);
- }
-
- if (sflist_string->len > 0)
- g_string_truncate (sflist_string, sflist_string->len - 1);
-
- aud_set_str ("amidiplug", "fsyn_soundfont_file", sflist_string->str);
-
- g_string_free (sflist_string, TRUE);
-
- /* reset backend at beginning of next song to apply changes */
- g_atomic_int_set (& backend_settings_changed, TRUE);
-}
-
-
-void * create_soundfont_list (void)
-{
- GtkListStore * soundfont_file_store;
- GtkCellRenderer * soundfont_file_lv_text_rndr;
- GtkTreeViewColumn * soundfont_file_lv_fname_col, *soundfont_file_lv_fsize_col;
- GtkWidget * soundfont_file_hbox, *soundfont_file_lv, *soundfont_file_lv_sw;
- GtkTreeSelection * soundfont_file_lv_sel;
- GtkWidget * soundfont_file_bbox_vbox, *soundfont_file_bbox_addbt, *soundfont_file_bbox_rembt;
- GtkWidget * soundfont_file_bbox_mvupbt, *soundfont_file_bbox_mvdownbt;
-
- /* soundfont settings - soundfont files - listview */
- soundfont_file_store = gtk_list_store_new (LISTSFONT_N_COLUMNS, G_TYPE_STRING, G_TYPE_INT);
-
- char * soundfont_file = aud_get_str ("amidiplug", "fsyn_soundfont_file");
-
- if (soundfont_file[0])
- {
- /* fill soundfont list with fsyn_soundfont_file information */
- char ** sffiles = g_strsplit (soundfont_file, ";", 0);
- GtkTreeIter iter;
- int i = 0;
-
- while (sffiles[i] != NULL)
- {
- int filesize = -1;
- GStatBuf finfo;
-
- if (g_stat (sffiles[i], &finfo) == 0)
- filesize = finfo.st_size;
-
- gtk_list_store_prepend (GTK_LIST_STORE (soundfont_file_store), &iter);
- gtk_list_store_set (GTK_LIST_STORE (soundfont_file_store), &iter,
- LISTSFONT_FILENAME_COLUMN, sffiles[i],
- LISTSFONT_FILESIZE_COLUMN, filesize, -1);
- i++;
- }
-
- g_strfreev (sffiles);
- }
-
- str_unref (soundfont_file);
-
- soundfont_file_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
- soundfont_file_lv = gtk_tree_view_new_with_model (GTK_TREE_MODEL (soundfont_file_store));
- gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (soundfont_file_lv), TRUE);
- g_object_unref (soundfont_file_store);
- soundfont_file_lv_text_rndr = gtk_cell_renderer_text_new();
- soundfont_file_lv_fname_col = gtk_tree_view_column_new_with_attributes (
- _("Filename"), soundfont_file_lv_text_rndr, "text",
- LISTSFONT_FILENAME_COLUMN, NULL);
- gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (soundfont_file_lv_fname_col), TRUE);
- soundfont_file_lv_fsize_col = gtk_tree_view_column_new_with_attributes (
- _("Size (bytes)"), soundfont_file_lv_text_rndr, "text",
- LISTSFONT_FILESIZE_COLUMN, NULL);
- gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (soundfont_file_lv_fsize_col), FALSE);
- gtk_tree_view_append_column (GTK_TREE_VIEW (soundfont_file_lv), soundfont_file_lv_fname_col);
- gtk_tree_view_append_column (GTK_TREE_VIEW (soundfont_file_lv), soundfont_file_lv_fsize_col);
- soundfont_file_lv_sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (soundfont_file_lv));
- gtk_tree_selection_set_mode (GTK_TREE_SELECTION (soundfont_file_lv_sel), GTK_SELECTION_SINGLE);
-
- soundfont_file_lv_sw = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) soundfont_file_lv_sw, GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy ((GtkScrolledWindow *) soundfont_file_lv_sw,
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_container_add (GTK_CONTAINER (soundfont_file_lv_sw), soundfont_file_lv);
-
- /* soundfont settings - soundfont files - buttonbox */
- soundfont_file_bbox_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- soundfont_file_bbox_addbt = gtk_button_new();
- gtk_button_set_image (GTK_BUTTON (soundfont_file_bbox_addbt),
- gtk_image_new_from_icon_name ("list-add", GTK_ICON_SIZE_MENU));
- g_signal_connect_swapped (G_OBJECT (soundfont_file_bbox_addbt), "clicked",
- G_CALLBACK (i_configure_ev_sflist_add), soundfont_file_lv);
- gtk_box_pack_start (GTK_BOX (soundfont_file_bbox_vbox), soundfont_file_bbox_addbt, FALSE, FALSE, 0);
- soundfont_file_bbox_rembt = gtk_button_new();
- gtk_button_set_image (GTK_BUTTON (soundfont_file_bbox_rembt),
- gtk_image_new_from_icon_name ("list-remove", GTK_ICON_SIZE_MENU));
- g_signal_connect_swapped (G_OBJECT (soundfont_file_bbox_rembt), "clicked",
- G_CALLBACK (i_configure_ev_sflist_rem), soundfont_file_lv);
- gtk_box_pack_start (GTK_BOX (soundfont_file_bbox_vbox), soundfont_file_bbox_rembt, FALSE, FALSE, 0);
- soundfont_file_bbox_mvupbt = gtk_button_new();
- gtk_button_set_image (GTK_BUTTON (soundfont_file_bbox_mvupbt),
- gtk_image_new_from_icon_name ("go-up", GTK_ICON_SIZE_MENU));
- g_object_set_data (G_OBJECT (soundfont_file_bbox_mvupbt), "swapdire", GUINT_TO_POINTER (0));
- g_signal_connect (G_OBJECT (soundfont_file_bbox_mvupbt), "clicked",
- G_CALLBACK (i_configure_ev_sflist_swap), soundfont_file_lv);
- gtk_box_pack_start (GTK_BOX (soundfont_file_bbox_vbox), soundfont_file_bbox_mvupbt, FALSE, FALSE, 0);
- soundfont_file_bbox_mvdownbt = gtk_button_new();
- gtk_button_set_image (GTK_BUTTON (soundfont_file_bbox_mvdownbt),
- gtk_image_new_from_icon_name ("go-down", GTK_ICON_SIZE_MENU));
- g_object_set_data (G_OBJECT (soundfont_file_bbox_mvdownbt), "swapdire", GUINT_TO_POINTER (1));
- g_signal_connect (G_OBJECT (soundfont_file_bbox_mvdownbt), "clicked",
- G_CALLBACK (i_configure_ev_sflist_swap), soundfont_file_lv);
- gtk_box_pack_start (GTK_BOX (soundfont_file_bbox_vbox), soundfont_file_bbox_mvdownbt, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (soundfont_file_hbox), soundfont_file_lv_sw, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (soundfont_file_hbox), soundfont_file_bbox_vbox, FALSE, FALSE, 0);
-
- return soundfont_file_hbox;
-}
diff --git a/src/amidi-plug/i_configure-fluidsynth.cc b/src/amidi-plug/i_configure-fluidsynth.cc
new file mode 100644
index 000000000000..75067015a9bf
--- /dev/null
+++ b/src/amidi-plug/i_configure-fluidsynth.cc
@@ -0,0 +1,275 @@
+/*
+*
+* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2006
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+*/
+
+#include "i_configure-fluidsynth.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+
+#include "i_configure.h"
+
+enum
+{
+ LISTSFONT_FILENAME_COLUMN = 0,
+ LISTSFONT_FILESIZE_COLUMN,
+ LISTSFONT_N_COLUMNS
+};
+
+static void i_configure_ev_sflist_commit (void * sfont_lv);
+
+void i_configure_ev_sflist_add (void * sfont_lv)
+{
+ GtkWidget * parent_window = gtk_widget_get_toplevel ((GtkWidget *) sfont_lv);
+
+ if (gtk_widget_is_toplevel (parent_window))
+ {
+ GtkTreeSelection * listsel = gtk_tree_view_get_selection (GTK_TREE_VIEW (sfont_lv));
+ GtkTreeIter itersel, iterapp;
+ GtkWidget * browse_dialog = gtk_file_chooser_dialog_new (_("AMIDI-Plug - select SoundFont file"),
+ GTK_WINDOW (parent_window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ _("_Open"), GTK_RESPONSE_ACCEPT, nullptr);
+
+ if (gtk_tree_selection_get_selected (listsel, nullptr, &itersel))
+ {
+ char * selfilename = nullptr, *selfiledir = nullptr;
+ GtkTreeModel * store = gtk_tree_view_get_model (GTK_TREE_VIEW (sfont_lv));
+ gtk_tree_model_get (GTK_TREE_MODEL (store), &itersel, LISTSFONT_FILENAME_COLUMN, &selfilename, -1);
+ selfiledir = g_path_get_dirname (selfilename);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (browse_dialog), selfiledir);
+ g_free (selfiledir);
+ g_free (selfilename);
+ }
+
+ if (gtk_dialog_run (GTK_DIALOG (browse_dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ GStatBuf finfo;
+ GtkTreeModel * store = gtk_tree_view_get_model (GTK_TREE_VIEW (sfont_lv));
+ char * filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (browse_dialog));
+ int filesize = -1;
+
+ if (g_stat (filename, &finfo) == 0)
+ filesize = finfo.st_size;
+
+ gtk_list_store_append (GTK_LIST_STORE (store), &iterapp);
+ gtk_list_store_set (GTK_LIST_STORE (store), &iterapp,
+ LISTSFONT_FILENAME_COLUMN, filename,
+ LISTSFONT_FILESIZE_COLUMN, filesize, -1);
+
+ g_free (filename);
+ }
+
+ gtk_widget_destroy (browse_dialog);
+ }
+
+ i_configure_ev_sflist_commit (sfont_lv);
+}
+
+
+void i_configure_ev_sflist_rem (void * sfont_lv)
+{
+ GtkTreeModel * store;
+ GtkTreeIter iter;
+ GtkTreeSelection * listsel = gtk_tree_view_get_selection (GTK_TREE_VIEW (sfont_lv));
+
+ if (gtk_tree_selection_get_selected (listsel, &store, &iter))
+ gtk_list_store_remove (GTK_LIST_STORE (store), &iter);
+
+ i_configure_ev_sflist_commit (sfont_lv);
+}
+
+
+void i_configure_ev_sflist_swap (GtkWidget * button, void * sfont_lv)
+{
+ GtkTreeModel * store;
+ GtkTreeIter iter;
+ GtkTreeSelection * listsel = gtk_tree_view_get_selection (GTK_TREE_VIEW (sfont_lv));
+
+ if (gtk_tree_selection_get_selected (listsel, &store, &iter))
+ {
+ unsigned swapdire = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (button), "swapdire"));
+
+ if (swapdire == 0) /* move up */
+ {
+ GtkTreePath * treepath = gtk_tree_model_get_path (store, &iter);
+
+ if (gtk_tree_path_prev (treepath))
+ {
+ GtkTreeIter iter_prev;
+
+ if (gtk_tree_model_get_iter (store, &iter_prev, treepath))
+ gtk_list_store_swap (GTK_LIST_STORE (store), &iter, &iter_prev);
+ }
+
+ gtk_tree_path_free (treepath);
+ }
+ else /* move down */
+ {
+ GtkTreeIter iter_prev = iter;
+
+ if (gtk_tree_model_iter_next (store, &iter))
+ gtk_list_store_swap (GTK_LIST_STORE (store), &iter, &iter_prev);
+ }
+ }
+
+ i_configure_ev_sflist_commit (sfont_lv);
+}
+
+
+void i_configure_ev_sflist_commit (void * sfont_lv)
+{
+ GtkTreeIter iter;
+ GtkTreeModel * store = gtk_tree_view_get_model (GTK_TREE_VIEW (sfont_lv));
+ GString * sflist_string = g_string_new ("");
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter) == TRUE)
+ {
+ gboolean iter_is_valid = FALSE;
+
+ do
+ {
+ char * fname;
+ gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
+ LISTSFONT_FILENAME_COLUMN, &fname, -1);
+ g_string_prepend_c (sflist_string, ';');
+ g_string_prepend (sflist_string, fname);
+ g_free (fname);
+ iter_is_valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
+ }
+ while (iter_is_valid == TRUE);
+ }
+
+ if (sflist_string->len > 0)
+ g_string_truncate (sflist_string, sflist_string->len - 1);
+
+ aud_set_str ("amidiplug", "fsyn_soundfont_file", sflist_string->str);
+
+ g_string_free (sflist_string, TRUE);
+
+ /* reset backend at beginning of next song to apply changes */
+ __sync_bool_compare_and_swap (& backend_settings_changed, false, true);
+}
+
+
+void * create_soundfont_list (void)
+{
+ GtkListStore * soundfont_file_store;
+ GtkCellRenderer * soundfont_file_lv_text_rndr;
+ GtkTreeViewColumn * soundfont_file_lv_fname_col, *soundfont_file_lv_fsize_col;
+ GtkWidget * soundfont_file_hbox, *soundfont_file_lv, *soundfont_file_lv_sw;
+ GtkTreeSelection * soundfont_file_lv_sel;
+ GtkWidget * soundfont_file_bbox_vbox, *soundfont_file_bbox_addbt, *soundfont_file_bbox_rembt;
+ GtkWidget * soundfont_file_bbox_mvupbt, *soundfont_file_bbox_mvdownbt;
+
+ /* soundfont settings - soundfont files - listview */
+ soundfont_file_store = gtk_list_store_new (LISTSFONT_N_COLUMNS, G_TYPE_STRING, G_TYPE_INT);
+
+ String soundfont_file = aud_get_str ("amidiplug", "fsyn_soundfont_file");
+
+ if (soundfont_file[0])
+ {
+ /* fill soundfont list with fsyn_soundfont_file information */
+ char ** sffiles = g_strsplit (soundfont_file, ";", 0);
+ GtkTreeIter iter;
+ int i = 0;
+
+ while (sffiles[i] != nullptr)
+ {
+ int filesize = -1;
+ GStatBuf finfo;
+
+ if (g_stat (sffiles[i], &finfo) == 0)
+ filesize = finfo.st_size;
+
+ gtk_list_store_prepend (GTK_LIST_STORE (soundfont_file_store), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (soundfont_file_store), &iter,
+ LISTSFONT_FILENAME_COLUMN, sffiles[i],
+ LISTSFONT_FILESIZE_COLUMN, filesize, -1);
+ i++;
+ }
+
+ g_strfreev (sffiles);
+ }
+
+ soundfont_file_hbox = gtk_hbox_new (FALSE, 2);
+ soundfont_file_lv = gtk_tree_view_new_with_model (GTK_TREE_MODEL (soundfont_file_store));
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (soundfont_file_lv), TRUE);
+ g_object_unref (soundfont_file_store);
+ soundfont_file_lv_text_rndr = gtk_cell_renderer_text_new();
+ soundfont_file_lv_fname_col = gtk_tree_view_column_new_with_attributes (
+ _("File name"), soundfont_file_lv_text_rndr, "text",
+ LISTSFONT_FILENAME_COLUMN, nullptr);
+ gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (soundfont_file_lv_fname_col), TRUE);
+ soundfont_file_lv_fsize_col = gtk_tree_view_column_new_with_attributes (
+ _("Size (bytes)"), soundfont_file_lv_text_rndr, "text",
+ LISTSFONT_FILESIZE_COLUMN, nullptr);
+ gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (soundfont_file_lv_fsize_col), FALSE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (soundfont_file_lv), soundfont_file_lv_fname_col);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (soundfont_file_lv), soundfont_file_lv_fsize_col);
+ soundfont_file_lv_sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (soundfont_file_lv));
+ gtk_tree_selection_set_mode (GTK_TREE_SELECTION (soundfont_file_lv_sel), GTK_SELECTION_SINGLE);
+
+ soundfont_file_lv_sw = gtk_scrolled_window_new (nullptr, nullptr);
+ gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) soundfont_file_lv_sw, GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy ((GtkScrolledWindow *) soundfont_file_lv_sw,
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (soundfont_file_lv_sw), soundfont_file_lv);
+
+ /* soundfont settings - soundfont files - buttonbox */
+ soundfont_file_bbox_vbox = gtk_vbox_new (FALSE, 0);
+ soundfont_file_bbox_addbt = gtk_button_new();
+ gtk_button_set_image (GTK_BUTTON (soundfont_file_bbox_addbt),
+ gtk_image_new_from_icon_name ("list-add", GTK_ICON_SIZE_MENU));
+ g_signal_connect_swapped (G_OBJECT (soundfont_file_bbox_addbt), "clicked",
+ G_CALLBACK (i_configure_ev_sflist_add), soundfont_file_lv);
+ gtk_box_pack_start (GTK_BOX (soundfont_file_bbox_vbox), soundfont_file_bbox_addbt, FALSE, FALSE, 0);
+ soundfont_file_bbox_rembt = gtk_button_new();
+ gtk_button_set_image (GTK_BUTTON (soundfont_file_bbox_rembt),
+ gtk_image_new_from_icon_name ("list-remove", GTK_ICON_SIZE_MENU));
+ g_signal_connect_swapped (G_OBJECT (soundfont_file_bbox_rembt), "clicked",
+ G_CALLBACK (i_configure_ev_sflist_rem), soundfont_file_lv);
+ gtk_box_pack_start (GTK_BOX (soundfont_file_bbox_vbox), soundfont_file_bbox_rembt, FALSE, FALSE, 0);
+ soundfont_file_bbox_mvupbt = gtk_button_new();
+ gtk_button_set_image (GTK_BUTTON (soundfont_file_bbox_mvupbt),
+ gtk_image_new_from_icon_name ("go-up", GTK_ICON_SIZE_MENU));
+ g_object_set_data (G_OBJECT (soundfont_file_bbox_mvupbt), "swapdire", GUINT_TO_POINTER (0));
+ g_signal_connect (G_OBJECT (soundfont_file_bbox_mvupbt), "clicked",
+ G_CALLBACK (i_configure_ev_sflist_swap), soundfont_file_lv);
+ gtk_box_pack_start (GTK_BOX (soundfont_file_bbox_vbox), soundfont_file_bbox_mvupbt, FALSE, FALSE, 0);
+ soundfont_file_bbox_mvdownbt = gtk_button_new();
+ gtk_button_set_image (GTK_BUTTON (soundfont_file_bbox_mvdownbt),
+ gtk_image_new_from_icon_name ("go-down", GTK_ICON_SIZE_MENU));
+ g_object_set_data (G_OBJECT (soundfont_file_bbox_mvdownbt), "swapdire", GUINT_TO_POINTER (1));
+ g_signal_connect (G_OBJECT (soundfont_file_bbox_mvdownbt), "clicked",
+ G_CALLBACK (i_configure_ev_sflist_swap), soundfont_file_lv);
+ gtk_box_pack_start (GTK_BOX (soundfont_file_bbox_vbox), soundfont_file_bbox_mvdownbt, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (soundfont_file_hbox), soundfont_file_lv_sw, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (soundfont_file_hbox), soundfont_file_bbox_vbox, FALSE, FALSE, 0);
+
+ return soundfont_file_hbox;
+}
diff --git a/src/amidi-plug/i_configure.c b/src/amidi-plug/i_configure.c
deleted file mode 100644
index a11f426dc9b6..000000000000
--- a/src/amidi-plug/i_configure.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2006
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include "i_configure.h"
-
-#include <glib.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/preferences.h>
-
-#include "i_configure-fluidsynth.h"
-
-int backend_settings_changed = FALSE; /* atomic */
-
-static bool_t override_gain = FALSE;
-static float gain_setting = 0.2;
-static bool_t override_polyphony = FALSE;
-static int polyphony_setting = 256;
-static bool_t override_reverb = FALSE;
-static bool_t reverb_setting = TRUE;
-static bool_t override_chorus = FALSE;
-static bool_t chorus_setting = TRUE;
-
-static void get_values (void)
-{
- int gain = aud_get_int ("amidiplug", "fsyn_synth_gain");
- int polyphony = aud_get_int ("amidiplug", "fsyn_synth_polyphony");
- int reverb = aud_get_int ("amidiplug", "fsyn_synth_reverb");
- int chorus = aud_get_int ("amidiplug", "fsyn_synth_chorus");
-
- if (gain != -1)
- {
- override_gain = TRUE;
- gain_setting = gain / 10.0;
- }
-
- if (polyphony != -1)
- {
- override_polyphony = TRUE;
- polyphony_setting = polyphony;
- }
-
- if (reverb != -1)
- {
- override_reverb = TRUE;
- reverb_setting = reverb;
- }
-
- if (chorus != -1)
- {
- override_chorus = TRUE;
- chorus_setting = chorus;
- }
-}
-
-static void set_values (void)
-{
- int gain = override_gain ? (int) (gain_setting * 10 + 0.5) : -1;
- int polyphony = override_polyphony ? polyphony_setting : -1;
- int reverb = override_reverb ? reverb_setting : -1;
- int chorus = override_chorus ? chorus_setting : -1;
-
- aud_set_int ("amidiplug", "fsyn_synth_gain", gain);
- aud_set_int ("amidiplug", "fsyn_synth_polyphony", polyphony);
- aud_set_int ("amidiplug", "fsyn_synth_reverb", reverb);
- aud_set_int ("amidiplug", "fsyn_synth_chorus", chorus);
-}
-
-static void backend_change (void)
-{
- set_values ();
-
- /* reset backend at beginning of next song to apply changes */
- g_atomic_int_set (& backend_settings_changed, TRUE);
-}
-
-static const PreferencesWidget gain_widgets[] = {
- {WIDGET_CHK_BTN, N_("Override default gain:"),
- .cfg_type = VALUE_BOOLEAN, .cfg = & override_gain, .callback = backend_change},
- {WIDGET_SPIN_BTN, .child = TRUE, .data = {.spin_btn = {0, 10, 0.1}},
- .cfg_type = VALUE_FLOAT, .cfg = & gain_setting, .callback = backend_change}};
-
-static const PreferencesWidget polyphony_widgets[] = {
- {WIDGET_CHK_BTN, N_("Override default polyphony:"),
- .cfg_type = VALUE_BOOLEAN, .cfg = & override_polyphony, .callback = backend_change},
- {WIDGET_SPIN_BTN, .child = TRUE, .data = {.spin_btn = {16, 4096, 1}},
- .cfg_type = VALUE_INT, .cfg = & polyphony_setting, .callback = backend_change}};
-
-static const PreferencesWidget reverb_widgets[] = {
- {WIDGET_CHK_BTN, N_("Override default reverb:"),
- .cfg_type = VALUE_BOOLEAN, .cfg = & override_reverb, .callback = backend_change},
- {WIDGET_CHK_BTN, N_("On"), .child = TRUE,
- .cfg_type = VALUE_BOOLEAN, .cfg = & reverb_setting, .callback = backend_change}};
-
-static const PreferencesWidget chorus_widgets[] = {
- {WIDGET_CHK_BTN, N_("Override default chorus:"),
- .cfg_type = VALUE_BOOLEAN, .cfg = & override_chorus, .callback = backend_change},
- {WIDGET_CHK_BTN, N_("On"), .child = TRUE,
- .cfg_type = VALUE_BOOLEAN, .cfg = & chorus_setting, .callback = backend_change}};
-
-static const PreferencesWidget amidiplug_widgets[] = {
-
- /* global settings */
- {WIDGET_LABEL, N_("<b>Playback</b>")},
- {WIDGET_SPIN_BTN, N_("Transpose:"), .data = {.spin_btn = {-20, 20, 1}},
- .cfg_type = VALUE_INT, .csect = "amidiplug", .cname = "ap_opts_transpose_value"},
- {WIDGET_SPIN_BTN, N_("Drum shift:"), .data = {.spin_btn = {0, 127, 1}},
- .cfg_type = VALUE_INT, .csect = "amidiplug", .cname = "ap_opts_drumshift_value"},
- {WIDGET_LABEL, N_("<b>Advanced</b>")},
- {WIDGET_CHK_BTN, N_("Extract comments from MIDI file"),
- .cfg_type = VALUE_BOOLEAN, .csect = "amidiplug", .cname = "ap_opts_comments_extract"},
- {WIDGET_CHK_BTN, N_("Extract lyrics from MIDI file"),
- .cfg_type = VALUE_BOOLEAN, .csect = "amidiplug", .cname = "ap_opts_lyrics_extract"},
-
- /* backend settings */
- {WIDGET_LABEL, N_("<b>SoundFont</b>")},
- {WIDGET_CUSTOM, .data = {.populate = create_soundfont_list}},
- {WIDGET_LABEL, N_("<b>Synthesizer</b>")},
- {WIDGET_BOX, .data = {.box = {gain_widgets, ARRAY_LEN (gain_widgets), TRUE}}},
- {WIDGET_BOX, .data = {.box = {polyphony_widgets, ARRAY_LEN (polyphony_widgets), TRUE}}},
- {WIDGET_BOX, .data = {.box = {reverb_widgets, ARRAY_LEN (reverb_widgets), TRUE}}},
- {WIDGET_BOX, .data = {.box = {chorus_widgets, ARRAY_LEN (chorus_widgets), TRUE}}},
- {WIDGET_SPIN_BTN, N_("Sampling rate:"), .data = {.spin_btn = {22050, 96000, 1}},
- .cfg_type = VALUE_INT, .csect = "amidiplug", .cname = "fsyn_synth_samplerate",
- .callback = backend_change}};
-
-const PluginPreferences amidiplug_prefs = {
- .init = get_values,
- .widgets = amidiplug_widgets,
- .n_widgets = ARRAY_LEN (amidiplug_widgets)};
diff --git a/src/amidi-plug/i_configure.cc b/src/amidi-plug/i_configure.cc
new file mode 100644
index 000000000000..f192d2b66383
--- /dev/null
+++ b/src/amidi-plug/i_configure.cc
@@ -0,0 +1,156 @@
+/*
+*
+* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2006
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+*/
+
+#include "i_configure.h"
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/preferences.h>
+
+#include "i_configure-fluidsynth.h"
+
+bool backend_settings_changed = false; /* atomic */
+
+static bool override_gain = false;
+static double gain_setting = 0.2;
+static bool override_polyphony = false;
+static int polyphony_setting = 256;
+static bool override_reverb = false;
+static bool reverb_setting = true;
+static bool override_chorus = false;
+static bool chorus_setting = true;
+
+static void get_values (void)
+{
+ int gain = aud_get_int ("amidiplug", "fsyn_synth_gain");
+ int polyphony = aud_get_int ("amidiplug", "fsyn_synth_polyphony");
+ int reverb = aud_get_int ("amidiplug", "fsyn_synth_reverb");
+ int chorus = aud_get_int ("amidiplug", "fsyn_synth_chorus");
+
+ if (gain != -1)
+ {
+ override_gain = true;
+ gain_setting = gain / 10.0;
+ }
+
+ if (polyphony != -1)
+ {
+ override_polyphony = true;
+ polyphony_setting = polyphony;
+ }
+
+ if (reverb != -1)
+ {
+ override_reverb = true;
+ reverb_setting = reverb;
+ }
+
+ if (chorus != -1)
+ {
+ override_chorus = true;
+ chorus_setting = chorus;
+ }
+}
+
+static void set_values (void)
+{
+ int gain = override_gain ? (int) (gain_setting * 10 + 0.5) : -1;
+ int polyphony = override_polyphony ? polyphony_setting : -1;
+ int reverb = override_reverb ? reverb_setting : -1;
+ int chorus = override_chorus ? chorus_setting : -1;
+
+ aud_set_int ("amidiplug", "fsyn_synth_gain", gain);
+ aud_set_int ("amidiplug", "fsyn_synth_polyphony", polyphony);
+ aud_set_int ("amidiplug", "fsyn_synth_reverb", reverb);
+ aud_set_int ("amidiplug", "fsyn_synth_chorus", chorus);
+}
+
+static void backend_change (void)
+{
+ set_values ();
+
+ /* reset backend at beginning of next song to apply changes */
+ __sync_bool_compare_and_swap (& backend_settings_changed, false, true);
+}
+
+static const PreferencesWidget gain_widgets[] = {
+ WidgetCheck (N_("Override default gain:"),
+ WidgetBool (override_gain, backend_change)),
+ WidgetSpin (0, WidgetFloat (gain_setting, backend_change),
+ {0, 10, 0.1},
+ WIDGET_CHILD)
+};
+
+static const PreferencesWidget polyphony_widgets[] = {
+ WidgetCheck (N_("Override default polyphony:"),
+ WidgetBool (override_polyphony, backend_change)),
+ WidgetSpin (0, WidgetInt (polyphony_setting, backend_change),
+ {16, 4096, 1},
+ WIDGET_CHILD)
+};
+
+static const PreferencesWidget reverb_widgets[] = {
+ WidgetCheck (N_("Override default reverb:"),
+ WidgetBool (override_reverb, backend_change)),
+ WidgetCheck (N_("On"),
+ WidgetBool (reverb_setting, backend_change),
+ WIDGET_CHILD)
+};
+
+static const PreferencesWidget chorus_widgets[] = {
+ WidgetCheck (N_("Override default chorus:"),
+ WidgetBool (override_chorus, backend_change)),
+ WidgetCheck (N_("On"),
+ WidgetBool (chorus_setting, backend_change),
+ WIDGET_CHILD)
+};
+
+static const PreferencesWidget amidiplug_widgets[] = {
+
+ /* global settings */
+ WidgetLabel (N_("<b>Playback</b>")),
+ WidgetSpin (N_("Transpose:"),
+ WidgetInt ("amidiplug", "ap_opts_transpose_value"),
+ {-20, 20, 1, N_("semitones")}),
+ WidgetSpin (N_("Drum shift:"),
+ WidgetInt ("amidiplug", "ap_opts_drumshift_value"),
+ {0, 127, 1, N_("note numbers")}),
+ WidgetCheck (N_("Skip leading silence"),
+ WidgetBool ("amidiplug", "skip_leading")),
+ WidgetCheck (N_("Skip trailing silence"),
+ WidgetBool ("amidiplug", "skip_trailing")),
+
+ /* backend settings */
+ WidgetLabel (N_("<b>SoundFont</b>")),
+ WidgetCustomGTK (create_soundfont_list),
+ WidgetLabel (N_("<b>Synthesizer</b>")),
+ WidgetBox ({{gain_widgets}, true}),
+ WidgetBox ({{polyphony_widgets}, true}),
+ WidgetBox ({{reverb_widgets}, true}),
+ WidgetBox ({{chorus_widgets}, true}),
+ WidgetSpin (N_("Sample rate:"),
+ WidgetInt ("amidiplug", "fsyn_synth_samplerate", backend_change),
+ {22050, 96000, 1, N_("Hz")})
+};
+
+const PluginPreferences amidiplug_prefs = {
+ {amidiplug_widgets},
+ get_values
+};
diff --git a/src/amidi-plug/i_configure.h b/src/amidi-plug/i_configure.h
index 6359525aab16..4648b1c053a9 100644
--- a/src/amidi-plug/i_configure.h
+++ b/src/amidi-plug/i_configure.h
@@ -21,9 +21,9 @@
#ifndef _I_CONFIGURE_H
#define _I_CONFIGURE_H 1
-#include <audacious/preferences.h>
+struct PluginPreferences;
-extern int backend_settings_changed; /* atomic */
+extern bool backend_settings_changed; /* atomic */
extern const PluginPreferences amidiplug_prefs;
diff --git a/src/amidi-plug/i_fileinfo.c b/src/amidi-plug/i_fileinfo.c
deleted file mode 100644
index e8f6eb06322c..000000000000
--- a/src/amidi-plug/i_fileinfo.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2006
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include "i_fileinfo.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <gtk/gtk.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-
-#include "i_configure.h"
-/* this is needed to retrieve information */
-#include "i_midi.h"
-/* icon from gnome-mime-audio-midi.png of the GNOME ICON SET */
-#include "amidi-plug.midiicon.xpm"
-
-
-void i_fileinfo_ev_destroy (GtkWidget * win, void * mf)
-{
- i_midi_free ((midifile_t *) mf);
- g_free (mf);
-}
-
-
-void i_fileinfo_ev_close (GtkWidget * button, void * fileinfowin)
-{
- gtk_widget_destroy (GTK_WIDGET (fileinfowin));
-}
-
-
-void i_fileinfo_grid_add_entry (char * field_text, char * value_text,
- GtkWidget * grid, unsigned line, PangoAttrList * attrlist)
-{
- GtkWidget * field, *value;
- field = gtk_label_new (field_text);
- gtk_label_set_attributes (GTK_LABEL (field), attrlist);
- gtk_misc_set_alignment (GTK_MISC (field), 0, 0);
- gtk_label_set_justify (GTK_LABEL (field), GTK_JUSTIFY_LEFT);
- gtk_grid_attach (GTK_GRID (grid), field, 0, line, 1, 1);
- value = gtk_label_new (value_text);
- gtk_misc_set_alignment (GTK_MISC (value), 0, 0);
- gtk_label_set_justify (GTK_LABEL (value), GTK_JUSTIFY_LEFT);
- gtk_grid_attach (GTK_GRID (grid), value, 1, line, 1, 1);
- return;
-}
-
-
-/* COMMENT: this will also reset current position in each track! */
-void i_fileinfo_text_fill (midifile_t * mf, GtkTextBuffer * text_tb, GtkTextBuffer * lyrics_tb)
-{
- int l = 0;
-
- /* initialize current position in each track */
- for (l = 0; l < mf->num_tracks; ++l)
- mf->tracks[l].current_event = mf->tracks[l].first_event;
-
- for (;;)
- {
- midievent_t * event = NULL;
- midifile_track_t * event_track = NULL;
- int i, min_tick = mf->max_tick + 1;
-
- /* search next event */
- for (i = 0 ; i < mf->num_tracks ; ++i)
- {
- midifile_track_t * track = &mf->tracks[i];
- midievent_t * e2 = track->current_event;
-
- if ((e2) && (e2->tick < min_tick))
- {
- min_tick = e2->tick;
- event = e2;
- event_track = track;
- }
- }
-
- if (!event)
- break; /* end of song reached */
-
- /* advance pointer to next event */
- event_track->current_event = event->next;
-
- switch (event->type)
- {
- case SND_SEQ_EVENT_META_TEXT:
- gtk_text_buffer_insert_at_cursor (text_tb, event->data.metat, strlen (event->data.metat));
- break;
-
- case SND_SEQ_EVENT_META_LYRIC:
- gtk_text_buffer_insert_at_cursor (lyrics_tb, event->data.metat, strlen (event->data.metat));
- break;
- }
- }
-}
-
-
-void i_fileinfo_gui (const char * filename_uri)
-{
- static GtkWidget * fileinfowin = NULL;
- GtkWidget * fileinfowin_vbox, *fileinfowin_columns_hbox;
- GtkWidget * midiinfoboxes_vbox, *miditextboxes_vbox, *miditextboxes_paned;
- GtkWidget * title_hbox, *title_icon_image, *title_name_f_label, *title_name_v_entry;
- GtkWidget * info_frame, *info_frame_tl, *info_grid;
- GtkWidget * text_frame, *text_frame_tl, *text_tv, *text_tv_sw;
- GtkWidget * lyrics_frame, *lyrics_tv, *lyrics_tv_sw;
- GtkTextBuffer * text_tb, *lyrics_tb;
- GtkWidget * footer_hbbox, *footer_bclose;
- GdkPixbuf * title_icon_pixbuf;
- PangoAttrList * pangoattrlist;
- PangoAttribute * pangoattr;
- GString * value_gstring;
- char * title, *filename, *filename_utf8;
- int bpm = 0, wavg_bpm = 0;
- midifile_t * mf;
-
- if (fileinfowin)
- return;
-
- mf = g_new (midifile_t, 1);
-
- /****************** midifile parser ******************/
- if (!i_midi_parse_from_filename (filename_uri, mf))
- return;
-
- /* midifile is filled with information at this point,
- bpm information is needed too */
- i_midi_get_bpm (mf, &bpm, &wavg_bpm);
- /*****************************************************/
-
- fileinfowin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_type_hint (GTK_WINDOW (fileinfowin), GDK_WINDOW_TYPE_HINT_DIALOG);
- g_signal_connect (G_OBJECT (fileinfowin), "destroy", G_CALLBACK (i_fileinfo_ev_destroy), mf);
- g_signal_connect (G_OBJECT (fileinfowin), "destroy", G_CALLBACK (gtk_widget_destroyed), &fileinfowin);
- gtk_container_set_border_width (GTK_CONTAINER (fileinfowin), 10);
-
- fileinfowin_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
- gtk_container_add (GTK_CONTAINER (fileinfowin), fileinfowin_vbox);
-
- /* pango attributes */
- pangoattrlist = pango_attr_list_new();
- pangoattr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
- pangoattr->start_index = 0;
- pangoattr->end_index = G_MAXINT;
- pango_attr_list_insert (pangoattrlist, pangoattr);
-
- /******************
- *** TITLE LINE ***/
- title_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_box_pack_start (GTK_BOX (fileinfowin_vbox), title_hbox, FALSE, FALSE, 0);
-
- title_icon_pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) amidiplug_xpm_midiicon);
- title_icon_image = gtk_image_new_from_pixbuf (title_icon_pixbuf);
- g_object_unref (title_icon_pixbuf);
- gtk_misc_set_alignment (GTK_MISC (title_icon_image), 0, 0);
- gtk_box_pack_start (GTK_BOX (title_hbox), title_icon_image, FALSE, FALSE, 0);
-
- title_name_f_label = gtk_label_new (_("Name:"));
- gtk_label_set_attributes (GTK_LABEL (title_name_f_label), pangoattrlist);
- gtk_box_pack_start (GTK_BOX (title_hbox), title_name_f_label, FALSE, FALSE, 0);
-
- title_name_v_entry = gtk_entry_new();
- gtk_editable_set_editable (GTK_EDITABLE (title_name_v_entry), FALSE);
- gtk_widget_set_size_request (GTK_WIDGET (title_name_v_entry), 200, -1);
- gtk_box_pack_start (GTK_BOX (title_hbox), title_name_v_entry, TRUE, TRUE, 0);
-
- fileinfowin_columns_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
- gtk_box_pack_start (GTK_BOX (fileinfowin_vbox), fileinfowin_columns_hbox, TRUE, TRUE, 0);
-
- /*********************
- *** MIDI INFO BOX ***/
- midiinfoboxes_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
-
- int comments_extract = aud_get_int ("amidiplug", "ap_opts_comments_extract");
- int lyrics_extract = aud_get_int ("amidiplug", "ap_opts_lyrics_extract");
-
- /* pick the entire space if both comments and lyrics boxes are not displayed,
- pick only required space if at least one of them is displayed */
- if (! comments_extract && ! lyrics_extract)
- gtk_box_pack_start (GTK_BOX (fileinfowin_columns_hbox), midiinfoboxes_vbox, TRUE, TRUE, 0);
- else
- gtk_box_pack_start (GTK_BOX (fileinfowin_columns_hbox), midiinfoboxes_vbox, FALSE, FALSE, 0);
-
- info_frame_tl = gtk_label_new ("");
- gtk_label_set_markup (GTK_LABEL (info_frame_tl), _("<span size=\"smaller\"> MIDI Info </span>"));
- gtk_box_pack_start (GTK_BOX (midiinfoboxes_vbox), info_frame_tl, FALSE, FALSE, 0);
-
- info_frame = gtk_frame_new (NULL);
- gtk_box_pack_start (GTK_BOX (midiinfoboxes_vbox), info_frame, TRUE, TRUE, 0);
- info_grid = gtk_grid_new();
- gtk_grid_set_row_spacing (GTK_GRID (info_grid), 4);
- gtk_grid_set_column_spacing (GTK_GRID (info_grid), 10);
- gtk_container_set_border_width (GTK_CONTAINER (info_grid), 3);
- gtk_container_add (GTK_CONTAINER (info_frame), info_grid);
- value_gstring = g_string_new ("");
-
- /* midi format */
- g_string_printf (value_gstring, "type %i", mf->format);
- i_fileinfo_grid_add_entry (_("Format:"), value_gstring->str, info_grid, 0, pangoattrlist);
- /* midi length */
- g_string_printf (value_gstring, "%i", (int) (mf->length / 1000));
- i_fileinfo_grid_add_entry (_("Length (msec):"), value_gstring->str, info_grid, 1, pangoattrlist);
- /* midi num of tracks */
- g_string_printf (value_gstring, "%i", mf->num_tracks);
- i_fileinfo_grid_add_entry (_("No. of Tracks:"), value_gstring->str, info_grid, 2, pangoattrlist);
-
- /* midi bpm */
- if (bpm > 0)
- g_string_printf (value_gstring, "%i", bpm); /* fixed bpm */
- else
- g_string_printf (value_gstring, _("variable")); /* variable bpm */
-
- i_fileinfo_grid_add_entry (_("BPM:"), value_gstring->str, info_grid, 3, pangoattrlist);
-
- /* midi weighted average bpm */
- if (bpm > 0)
- g_string_printf (value_gstring, "/"); /* fixed bpm, don't care about wavg_bpm */
- else
- g_string_printf (value_gstring, "%i", wavg_bpm); /* variable bpm, display wavg_bpm */
-
- i_fileinfo_grid_add_entry (_("BPM (wavg):"), value_gstring->str, info_grid, 4, pangoattrlist);
- /* midi time division */
- g_string_printf (value_gstring, "%i", mf->time_division);
- i_fileinfo_grid_add_entry (_("Time Div:"), value_gstring->str, info_grid, 5, pangoattrlist);
-
- g_string_free (value_gstring, TRUE);
-
- /**********************************
- *** MIDI COMMENTS/LYRICS BOXES ***/
- miditextboxes_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
- gtk_box_pack_start (GTK_BOX (fileinfowin_columns_hbox), miditextboxes_vbox, TRUE, TRUE, 0);
-
- text_frame_tl = gtk_label_new ("");
- gtk_label_set_markup (GTK_LABEL (text_frame_tl),
- _("<span size=\"smaller\"> MIDI Comments and Lyrics </span>"));
- gtk_box_pack_start (GTK_BOX (miditextboxes_vbox), text_frame_tl, FALSE, FALSE, 0);
-
- miditextboxes_paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
- gtk_box_pack_start (GTK_BOX (miditextboxes_vbox), miditextboxes_paned, TRUE, TRUE, 0);
-
- text_frame = gtk_frame_new (NULL);
- gtk_paned_pack1 (GTK_PANED (miditextboxes_paned), text_frame, TRUE, TRUE);
- text_tv = gtk_text_view_new();
- gtk_text_view_set_editable (GTK_TEXT_VIEW (text_tv), FALSE);
- gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (text_tv), FALSE);
- gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_tv), GTK_WRAP_WORD);
- gtk_text_view_set_right_margin (GTK_TEXT_VIEW (text_tv), 4);
- gtk_text_view_set_left_margin (GTK_TEXT_VIEW (text_tv), 4);
- gtk_widget_set_size_request (text_tv, 300, 113);
- text_tv_sw = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (text_tv_sw),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
- gtk_container_add (GTK_CONTAINER (text_frame), text_tv_sw);
- gtk_container_add (GTK_CONTAINER (text_tv_sw), text_tv);
-
- lyrics_frame = gtk_frame_new (NULL);
- gtk_paned_pack2 (GTK_PANED (miditextboxes_paned), lyrics_frame, TRUE, TRUE);
- lyrics_tv = gtk_text_view_new();
- gtk_text_view_set_editable (GTK_TEXT_VIEW (lyrics_tv), FALSE);
- gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (lyrics_tv), FALSE);
- gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (lyrics_tv), GTK_WRAP_WORD);
- gtk_text_view_set_right_margin (GTK_TEXT_VIEW (lyrics_tv), 4);
- gtk_text_view_set_left_margin (GTK_TEXT_VIEW (lyrics_tv), 4);
- gtk_widget_set_size_request (lyrics_tv, 300, 113);
- lyrics_tv_sw = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (lyrics_tv_sw),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
- gtk_container_add (GTK_CONTAINER (lyrics_frame), lyrics_tv_sw);
- gtk_container_add (GTK_CONTAINER (lyrics_tv_sw), lyrics_tv);
-
- text_tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_tv));
- lyrics_tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (lyrics_tv));
-
- /* call the buffer fill routine if at least one between comments and lyrics is enabled */
- if (comments_extract || lyrics_extract)
- i_fileinfo_text_fill (mf, text_tb, lyrics_tb);
-
- if (comments_extract && ! gtk_text_buffer_get_char_count (text_tb))
- {
- GtkTextIter start, end;
- GtkTextTag * tag = gtk_text_buffer_create_tag (text_tb, "italicstyle",
- "style", PANGO_STYLE_ITALIC, NULL);
- /*gtk_text_view_set_justification( GTK_TEXT_VIEW(text_tv), GTK_JUSTIFY_CENTER );*/
- gtk_text_buffer_set_text (text_tb, _("* no comments available in this MIDI file *"), -1);
- gtk_text_buffer_get_iter_at_offset (text_tb, &start, 0);
- gtk_text_buffer_get_iter_at_offset (text_tb, &end, -1);
- gtk_text_buffer_apply_tag (text_tb, tag, &start, &end);
- }
-
- if (lyrics_extract && ! gtk_text_buffer_get_char_count (lyrics_tb))
- {
- GtkTextIter start, end;
- GtkTextTag * tag = gtk_text_buffer_create_tag (lyrics_tb, "italicstyle",
- "style", PANGO_STYLE_ITALIC, NULL);
- /*gtk_text_view_set_justification( GTK_TEXT_VIEW(lyrics_tv), GTK_JUSTIFY_CENTER );*/
- gtk_text_buffer_set_text (lyrics_tb, _("* no lyrics available in this MIDI file *"), -1);
- gtk_text_buffer_get_iter_at_offset (lyrics_tb, &start, 0);
- gtk_text_buffer_get_iter_at_offset (lyrics_tb, &end, -1);
- gtk_text_buffer_apply_tag (lyrics_tb, tag, &start, &end);
- }
-
- /* hide boxes for disabled options (comments and/or lyrics) */
- if (! comments_extract && ! lyrics_extract)
- {
- gtk_widget_set_no_show_all (miditextboxes_vbox, TRUE);
- gtk_widget_hide (miditextboxes_vbox);
- }
- else if (! comments_extract)
- {
- gtk_widget_set_no_show_all (text_frame, TRUE);
- gtk_widget_hide (text_frame);
- }
- else if (! lyrics_extract)
- {
- gtk_widget_set_no_show_all (lyrics_frame, TRUE);
- gtk_widget_hide (lyrics_frame);
- }
-
- /**************
- *** FOOTER ***/
- footer_hbbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_button_box_set_layout (GTK_BUTTON_BOX (footer_hbbox), GTK_BUTTONBOX_END);
- footer_bclose = gtk_button_new_with_mnemonic (_("_Close"));
- g_signal_connect (G_OBJECT (footer_bclose), "clicked", G_CALLBACK (i_fileinfo_ev_close), fileinfowin);
- gtk_container_add (GTK_CONTAINER (footer_hbbox), footer_bclose);
- gtk_box_pack_start (GTK_BOX (fileinfowin_vbox), footer_hbbox, FALSE, FALSE, 0);
-
-
- /* utf8-ize filename and set window title */
- filename = g_filename_from_uri (filename_uri, NULL, NULL);
-
- if (!filename)
- filename = g_strdup (filename_uri);
-
- filename_utf8 = g_strdup (g_filename_to_utf8 (filename, -1, NULL, NULL, NULL));
-
- if (!filename_utf8)
- {
- /* utf8 fallback */
- char * chr, *convert_str = g_strdup (filename);
-
- for (chr = convert_str ; *chr ; chr++)
- {
- if (*chr & 0x80)
- *chr = '?';
- }
-
- filename_utf8 = g_strconcat (convert_str, _(" (invalid UTF-8)"), NULL);
- g_free (convert_str);
- }
-
- title = g_path_get_basename (filename_utf8);
- gtk_window_set_title (GTK_WINDOW (fileinfowin), title);
- g_free (title);
- /* set the text for the filename header too */
- gtk_entry_set_text (GTK_ENTRY (title_name_v_entry), filename_utf8);
- gtk_editable_set_position (GTK_EDITABLE (title_name_v_entry), -1);
- g_free (filename_utf8);
- g_free (filename);
-
- gtk_widget_grab_focus (GTK_WIDGET (footer_bclose));
- gtk_widget_show_all (fileinfowin);
-}
diff --git a/src/amidi-plug/i_fileinfo.cc b/src/amidi-plug/i_fileinfo.cc
new file mode 100644
index 000000000000..fc04c4c446a7
--- /dev/null
+++ b/src/amidi-plug/i_fileinfo.cc
@@ -0,0 +1,340 @@
+/*
+*
+* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2006
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+*/
+
+#include "i_fileinfo.h"
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+
+#include "i_configure.h"
+/* this is needed to retrieve information */
+#include "i_midi.h"
+/* icon from gnome-mime-audio-midi.png of the GNOME ICON SET */
+#include "amidi-plug.midiicon.xpm"
+
+
+void i_fileinfo_ev_close (GtkWidget * button, void * fileinfowin)
+{
+ gtk_widget_destroy (GTK_WIDGET (fileinfowin));
+}
+
+
+void i_fileinfo_grid_add_entry (char * field_text, char * value_text,
+ GtkWidget * grid, unsigned line, PangoAttrList * attrlist)
+{
+ GtkWidget * field, *value;
+ field = gtk_label_new (field_text);
+ gtk_label_set_attributes (GTK_LABEL (field), attrlist);
+ gtk_misc_set_alignment (GTK_MISC (field), 0, 0);
+ gtk_table_attach (GTK_TABLE (grid), field, 0, 1, line, line + 1, GTK_FILL, GTK_FILL, 0, 0);
+ value = gtk_label_new (value_text);
+ gtk_misc_set_alignment (GTK_MISC (value), 0, 0);
+ gtk_table_attach (GTK_TABLE (grid), value, 1, 2, line, line + 1, GTK_FILL, GTK_FILL, 0, 0);
+}
+
+
+/* COMMENT: this will also reset current position in each track! */
+void i_fileinfo_text_fill (midifile_t * mf, GtkTextBuffer * text_tb, GtkTextBuffer * lyrics_tb)
+{
+ /* initialize current position in each track */
+ for (midifile_track_t & track : mf->tracks)
+ track.current_event = track.events.head ();
+
+ for (;;)
+ {
+ midievent_t * event = nullptr;
+ midifile_track_t * event_track = nullptr;
+ int min_tick = INT_MAX; /* meta-events may go past max_tick */
+
+ /* search next event */
+ for (midifile_track_t & track : mf->tracks)
+ {
+ midievent_t * e2 = track.current_event;
+
+ if (e2 && e2->tick < min_tick)
+ {
+ min_tick = e2->tick;
+ event = e2;
+ event_track = & track;
+ }
+ }
+
+ if (!event)
+ break; /* end of song reached */
+
+ /* advance pointer to next event */
+ event_track->current_event = event_track->events.next (event);
+
+ switch (event->type)
+ {
+ case SND_SEQ_EVENT_META_TEXT:
+ gtk_text_buffer_insert_at_cursor (text_tb, event->metat, -1);
+ break;
+
+ case SND_SEQ_EVENT_META_LYRIC:
+ gtk_text_buffer_insert_at_cursor (lyrics_tb, event->metat, -1);
+ break;
+ }
+ }
+}
+
+
+void i_fileinfo_gui (const char * filename_uri, VFSFile & file)
+{
+ static GtkWidget * fileinfowin = nullptr;
+ GtkWidget * fileinfowin_vbox, *fileinfowin_columns_hbox;
+ GtkWidget * midiinfoboxes_vbox, *miditextboxes_vbox, *miditextboxes_paned;
+ GtkWidget * title_hbox, *title_icon_image, *title_name_f_label, *title_name_v_entry;
+ GtkWidget * info_frame, *info_frame_tl, *info_grid;
+ GtkWidget * text_frame, *text_frame_tl, *text_tv, *text_tv_sw;
+ GtkWidget * lyrics_frame, *lyrics_tv, *lyrics_tv_sw;
+ GtkTextBuffer * text_tb, *lyrics_tb;
+ GtkWidget * footer_hbbox, *footer_bclose;
+ GdkPixbuf * title_icon_pixbuf;
+ PangoAttrList * pangoattrlist;
+ PangoAttribute * pangoattr;
+ GString * value_gstring;
+ char * title, *filename, *filename_utf8;
+ int bpm = 0, wavg_bpm = 0;
+
+ if (fileinfowin)
+ return;
+
+ midifile_t mf;
+
+ /****************** midifile parser ******************/
+ if (! mf.parse_from_file (filename_uri, file))
+ return;
+
+ /* midifile is filled with information at this point,
+ bpm information is needed too */
+ mf.get_bpm (& bpm, & wavg_bpm);
+ /*****************************************************/
+
+ fileinfowin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_default_size (GTK_WINDOW (fileinfowin), 500, 400);
+ gtk_window_set_type_hint (GTK_WINDOW (fileinfowin), GDK_WINDOW_TYPE_HINT_DIALOG);
+ g_signal_connect (G_OBJECT (fileinfowin), "destroy", G_CALLBACK (gtk_widget_destroyed), &fileinfowin);
+ gtk_container_set_border_width (GTK_CONTAINER (fileinfowin), 10);
+
+ fileinfowin_vbox = gtk_vbox_new (FALSE, 10);
+ gtk_container_add (GTK_CONTAINER (fileinfowin), fileinfowin_vbox);
+
+ /* pango attributes */
+ pangoattrlist = pango_attr_list_new();
+ pangoattr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
+ pangoattr->start_index = 0;
+ pangoattr->end_index = G_MAXINT;
+ pango_attr_list_insert (pangoattrlist, pangoattr);
+
+ /******************
+ *** TITLE LINE ***/
+ title_hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start (GTK_BOX (fileinfowin_vbox), title_hbox, FALSE, FALSE, 0);
+
+ title_icon_pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) amidiplug_xpm_midiicon);
+ title_icon_image = gtk_image_new_from_pixbuf (title_icon_pixbuf);
+ g_object_unref (title_icon_pixbuf);
+ gtk_misc_set_alignment (GTK_MISC (title_icon_image), 0, 0);
+ gtk_box_pack_start (GTK_BOX (title_hbox), title_icon_image, FALSE, FALSE, 0);
+
+ title_name_f_label = gtk_label_new (_("Name:"));
+ gtk_label_set_attributes (GTK_LABEL (title_name_f_label), pangoattrlist);
+ gtk_box_pack_start (GTK_BOX (title_hbox), title_name_f_label, FALSE, FALSE, 0);
+
+ title_name_v_entry = gtk_entry_new();
+ gtk_editable_set_editable (GTK_EDITABLE (title_name_v_entry), FALSE);
+ gtk_widget_set_size_request (GTK_WIDGET (title_name_v_entry), 200, -1);
+ gtk_box_pack_start (GTK_BOX (title_hbox), title_name_v_entry, TRUE, TRUE, 0);
+
+ fileinfowin_columns_hbox = gtk_hbox_new (FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (fileinfowin_vbox), fileinfowin_columns_hbox, TRUE, TRUE, 0);
+
+ /*********************
+ *** MIDI INFO BOX ***/
+ midiinfoboxes_vbox = gtk_vbox_new (FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (fileinfowin_columns_hbox), midiinfoboxes_vbox, FALSE, FALSE, 0);
+
+ info_frame_tl = gtk_label_new ("");
+ gtk_label_set_markup (GTK_LABEL (info_frame_tl), _("<span size=\"smaller\"> MIDI Info </span>"));
+ gtk_box_pack_start (GTK_BOX (midiinfoboxes_vbox), info_frame_tl, FALSE, FALSE, 0);
+
+ info_frame = gtk_frame_new (nullptr);
+ gtk_box_pack_start (GTK_BOX (midiinfoboxes_vbox), info_frame, TRUE, TRUE, 0);
+ info_grid = gtk_table_new (0, 0, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (info_grid), 2);
+ gtk_table_set_col_spacings (GTK_TABLE (info_grid), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (info_grid), 6);
+ gtk_container_add (GTK_CONTAINER (info_frame), info_grid);
+ value_gstring = g_string_new ("");
+
+ /* midi format */
+ g_string_printf (value_gstring, "type %i", mf.format);
+ i_fileinfo_grid_add_entry (_("Format:"), value_gstring->str, info_grid, 0, pangoattrlist);
+ /* midi length */
+ g_string_printf (value_gstring, "%i", (int) (mf.length / 1000));
+ i_fileinfo_grid_add_entry (_("Length (msec):"), value_gstring->str, info_grid, 1, pangoattrlist);
+ /* midi num of tracks */
+ g_string_printf (value_gstring, "%i", mf.tracks.len ());
+ i_fileinfo_grid_add_entry (_("No. of Tracks:"), value_gstring->str, info_grid, 2, pangoattrlist);
+
+ /* midi bpm */
+ if (bpm > 0)
+ g_string_printf (value_gstring, "%i", bpm); /* fixed bpm */
+ else
+ g_string_printf (value_gstring, _("variable")); /* variable bpm */
+
+ i_fileinfo_grid_add_entry (_("BPM:"), value_gstring->str, info_grid, 3, pangoattrlist);
+
+ /* midi weighted average bpm */
+ if (bpm > 0)
+ g_string_printf (value_gstring, "/"); /* fixed bpm, don't care about wavg_bpm */
+ else
+ g_string_printf (value_gstring, "%i", wavg_bpm); /* variable bpm, display wavg_bpm */
+
+ i_fileinfo_grid_add_entry (_("BPM (wavg):"), value_gstring->str, info_grid, 4, pangoattrlist);
+ /* midi time division */
+ g_string_printf (value_gstring, "%i", mf.time_division);
+ i_fileinfo_grid_add_entry (_("Time Div:"), value_gstring->str, info_grid, 5, pangoattrlist);
+
+ g_string_free (value_gstring, TRUE);
+
+ /**********************************
+ *** MIDI COMMENTS/LYRICS BOXES ***/
+ miditextboxes_vbox = gtk_vbox_new (FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (fileinfowin_columns_hbox), miditextboxes_vbox, TRUE, TRUE, 0);
+
+ text_frame_tl = gtk_label_new ("");
+ gtk_label_set_markup (GTK_LABEL (text_frame_tl),
+ _("<span size=\"smaller\"> MIDI Comments and Lyrics </span>"));
+ gtk_box_pack_start (GTK_BOX (miditextboxes_vbox), text_frame_tl, FALSE, FALSE, 0);
+
+ miditextboxes_paned = gtk_vpaned_new ();
+ gtk_box_pack_start (GTK_BOX (miditextboxes_vbox), miditextboxes_paned, TRUE, TRUE, 0);
+
+ text_frame = gtk_frame_new (nullptr);
+ gtk_paned_pack1 (GTK_PANED (miditextboxes_paned), text_frame, TRUE, TRUE);
+ text_tv = gtk_text_view_new();
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (text_tv), FALSE);
+ gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (text_tv), FALSE);
+ gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_tv), GTK_WRAP_WORD);
+ gtk_text_view_set_right_margin (GTK_TEXT_VIEW (text_tv), 4);
+ gtk_text_view_set_left_margin (GTK_TEXT_VIEW (text_tv), 4);
+ gtk_widget_set_size_request (text_tv, 300, 113);
+ text_tv_sw = gtk_scrolled_window_new (nullptr, nullptr);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (text_tv_sw),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (text_frame), text_tv_sw);
+ gtk_container_add (GTK_CONTAINER (text_tv_sw), text_tv);
+
+ lyrics_frame = gtk_frame_new (nullptr);
+ gtk_paned_pack2 (GTK_PANED (miditextboxes_paned), lyrics_frame, TRUE, TRUE);
+ lyrics_tv = gtk_text_view_new();
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (lyrics_tv), FALSE);
+ gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (lyrics_tv), FALSE);
+ gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (lyrics_tv), GTK_WRAP_WORD);
+ gtk_text_view_set_right_margin (GTK_TEXT_VIEW (lyrics_tv), 4);
+ gtk_text_view_set_left_margin (GTK_TEXT_VIEW (lyrics_tv), 4);
+ gtk_widget_set_size_request (lyrics_tv, 300, 113);
+ lyrics_tv_sw = gtk_scrolled_window_new (nullptr, nullptr);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (lyrics_tv_sw),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (lyrics_frame), lyrics_tv_sw);
+ gtk_container_add (GTK_CONTAINER (lyrics_tv_sw), lyrics_tv);
+
+ text_tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_tv));
+ lyrics_tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (lyrics_tv));
+
+ i_fileinfo_text_fill (& mf, text_tb, lyrics_tb);
+
+ if (! gtk_text_buffer_get_char_count (text_tb))
+ {
+ GtkTextIter start, end;
+ GtkTextTag * tag = gtk_text_buffer_create_tag (text_tb, "italicstyle",
+ "style", PANGO_STYLE_ITALIC, nullptr);
+ /*gtk_text_view_set_justification( GTK_TEXT_VIEW(text_tv), GTK_JUSTIFY_CENTER );*/
+ gtk_text_buffer_set_text (text_tb, _("* no comments available in this MIDI file *"), -1);
+ gtk_text_buffer_get_iter_at_offset (text_tb, &start, 0);
+ gtk_text_buffer_get_iter_at_offset (text_tb, &end, -1);
+ gtk_text_buffer_apply_tag (text_tb, tag, &start, &end);
+ }
+
+ if (! gtk_text_buffer_get_char_count (lyrics_tb))
+ {
+ GtkTextIter start, end;
+ GtkTextTag * tag = gtk_text_buffer_create_tag (lyrics_tb, "italicstyle",
+ "style", PANGO_STYLE_ITALIC, nullptr);
+ /*gtk_text_view_set_justification( GTK_TEXT_VIEW(lyrics_tv), GTK_JUSTIFY_CENTER );*/
+ gtk_text_buffer_set_text (lyrics_tb, _("* no lyrics available in this MIDI file *"), -1);
+ gtk_text_buffer_get_iter_at_offset (lyrics_tb, &start, 0);
+ gtk_text_buffer_get_iter_at_offset (lyrics_tb, &end, -1);
+ gtk_text_buffer_apply_tag (lyrics_tb, tag, &start, &end);
+ }
+
+ /**************
+ *** FOOTER ***/
+ footer_hbbox = gtk_hbutton_box_new ();
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (footer_hbbox), GTK_BUTTONBOX_END);
+ footer_bclose = gtk_button_new_with_mnemonic (_("_Close"));
+ g_signal_connect (G_OBJECT (footer_bclose), "clicked", G_CALLBACK (i_fileinfo_ev_close), fileinfowin);
+ gtk_container_add (GTK_CONTAINER (footer_hbbox), footer_bclose);
+ gtk_box_pack_start (GTK_BOX (fileinfowin_vbox), footer_hbbox, FALSE, FALSE, 0);
+
+
+ /* utf8-ize filename and set window title */
+ filename = g_filename_from_uri (filename_uri, nullptr, nullptr);
+
+ if (!filename)
+ filename = g_strdup (filename_uri);
+
+ filename_utf8 = g_strdup (g_filename_to_utf8 (filename, -1, nullptr, nullptr, nullptr));
+
+ if (!filename_utf8)
+ {
+ /* utf8 fallback */
+ char * chr, *convert_str = g_strdup (filename);
+
+ for (chr = convert_str ; *chr ; chr++)
+ {
+ if (*chr & 0x80)
+ *chr = '?';
+ }
+
+ filename_utf8 = g_strconcat (convert_str, _(" (invalid UTF-8)"), nullptr);
+ g_free (convert_str);
+ }
+
+ title = g_path_get_basename (filename_utf8);
+ gtk_window_set_title (GTK_WINDOW (fileinfowin), title);
+ g_free (title);
+ /* set the text for the filename header too */
+ gtk_entry_set_text (GTK_ENTRY (title_name_v_entry), filename_utf8);
+ gtk_editable_set_position (GTK_EDITABLE (title_name_v_entry), -1);
+ g_free (filename_utf8);
+ g_free (filename);
+
+ gtk_widget_grab_focus (GTK_WIDGET (footer_bclose));
+ gtk_widget_show_all (fileinfowin);
+}
diff --git a/src/amidi-plug/i_fileinfo.h b/src/amidi-plug/i_fileinfo.h
index 518e2190d17c..15749e515896 100644
--- a/src/amidi-plug/i_fileinfo.h
+++ b/src/amidi-plug/i_fileinfo.h
@@ -21,6 +21,8 @@
#ifndef _I_FILEINFO_H
#define _I_FILEINFO_H 1
-void i_fileinfo_gui (const char *);
+class VFSFile;
+
+void i_fileinfo_gui (const char * filename_uri, VFSFile & file);
#endif /* !_I_FILEINFO_H */
diff --git a/src/amidi-plug/i_midi.c b/src/amidi-plug/i_midi.c
deleted file mode 100644
index e15358dbc070..000000000000
--- a/src/amidi-plug/i_midi.c
+++ /dev/null
@@ -1,897 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2006
-*
-* MIDI (SMF) parser based on aplaymidi.c from ALSA-utils
-* aplaymidi.c is Copyright (c) 2004 Clemens Ladisch <clemens at ladisch.de>
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include "i_midi.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <audacious/misc.h>
-
-#include "i_configure.h"
-
-/* #define DEBUGMSG(...) fprintf (stderr, __VA_ARGS__) */
-#define DEBUGMSG(...)
-
-#define WARNANDBREAK(...) { fprintf (stderr, __VA_ARGS__); break; }
-
-#define ERRMSG_MIDITRACK() { fprintf(stderr, "%s: invalid MIDI data (offset %#x)", mf->file_name, mf->file_offset ); return 0; }
-
-
-/* skip a certain number of bytes */
-void i_midi_file_skip_bytes (midifile_t * mf, int bytes)
-{
- while (bytes > 0)
- {
- i_midi_file_read_byte (mf);
- --bytes;
- }
-}
-
-
-/* reads a single byte */
-int i_midi_file_read_byte (midifile_t * mf)
-{
- ++mf->file_offset;
- return vfs_getc (mf->file_pointer);
-}
-
-
-/* reads a little-endian 32-bit integer */
-int i_midi_file_read_32_le (midifile_t * mf)
-{
- int value;
- value = i_midi_file_read_byte (mf);
- value |= i_midi_file_read_byte (mf) << 8;
- value |= i_midi_file_read_byte (mf) << 16;
- value |= i_midi_file_read_byte (mf) << 24;
- return !vfs_feof (mf->file_pointer) ? value : -1;
-}
-
-
-/* reads a 4-character identifier */
-int i_midi_file_read_id (midifile_t * mf)
-{
- return i_midi_file_read_32_le (mf);
-}
-
-
-/* reads a fixed-size big-endian number */
-int i_midi_file_read_int (midifile_t * mf, int bytes)
-{
- int c, value = 0;
-
- do
- {
- c = i_midi_file_read_byte (mf);
-
- if (c == EOF) return -1;
-
- value = (value << 8) | c;
- }
- while (--bytes);
-
- return value;
-}
-
-
-/* reads a variable-length number */
-int i_midi_file_read_var (midifile_t * mf)
-{
- int value, c;
-
- c = i_midi_file_read_byte (mf);
- value = c & 0x7f;
-
- if (c & 0x80)
- {
- c = i_midi_file_read_byte (mf);
- value = (value << 7) | (c & 0x7f);
-
- if (c & 0x80)
- {
- c = i_midi_file_read_byte (mf);
- value = (value << 7) | (c & 0x7f);
-
- if (c & 0x80)
- {
- c = i_midi_file_read_byte (mf);
- value = (value << 7) | c;
-
- if (c & 0x80)
- return -1;
- }
- }
- }
-
- return value;
-}
-
-
-/* allocates a new event */
-midievent_t * i_midi_file_new_event (midifile_track_t * track, int sysex_length)
-{
- midievent_t * event;
-
- event = g_new (midievent_t, 1);
- event->sysex = sysex_length ? g_malloc (sysex_length) : NULL;
- event->next = NULL;
-
- /* append at the end of the track's linked list */
- if (track->current_event)
- track->current_event->next = event;
- else
- track->first_event = event;
-
- track->current_event = event;
-
- return event;
-}
-
-
-/* reads one complete track from the file */
-int i_midi_file_read_track (midifile_t * mf, midifile_track_t * track,
- int track_end, int port_count)
-{
- int tick = 0;
- unsigned char last_cmd = 0;
- unsigned char port = 0;
-
- /* the current file position is after the track ID and length */
- while (mf->file_offset < track_end)
- {
- unsigned char cmd;
- midievent_t * event;
- int delta_ticks, len, c;
-
- delta_ticks = i_midi_file_read_var (mf);
-
- if (delta_ticks < 0)
- break;
-
- tick += delta_ticks;
-
- c = i_midi_file_read_byte (mf);
-
- if (c < 0)
- break;
-
- if (c & 0x80)
- {
- /* have command */
- cmd = c;
-
- if (cmd < 0xf0)
- last_cmd = cmd;
- }
- else
- {
- /* running status */
- if (vfs_ungetc (c, mf->file_pointer) < 0)
- break;
-
- mf->file_offset--;
- cmd = last_cmd;
-
- if (!cmd)
- ERRMSG_MIDITRACK();
- }
-
- switch (cmd >> 4)
- {
- /* maps SMF events to ALSA sequencer events */
- static unsigned char cmd_type[] =
- {
- [0x8] = SND_SEQ_EVENT_NOTEOFF,
- [0x9] = SND_SEQ_EVENT_NOTEON,
- [0xa] = SND_SEQ_EVENT_KEYPRESS,
- [0xb] = SND_SEQ_EVENT_CONTROLLER,
- [0xc] = SND_SEQ_EVENT_PGMCHANGE,
- [0xd] = SND_SEQ_EVENT_CHANPRESS,
- [0xe] = SND_SEQ_EVENT_PITCHBEND
- };
-
- case 0x8: /* channel msg with 2 parameter bytes */
- case 0x9:
- case 0xa:
- {
- event = i_midi_file_new_event (track, 0);
- event->type = cmd_type[cmd >> 4];
- event->port = port;
- event->tick = tick;
- event->data.d[0] = cmd & 0x0f;
-
- /* if this note is not in standard drum channel (10), apply transpose */
- if (event->data.d[0] != 9)
- {
- int transpose = aud_get_int ("amidiplug", "ap_opts_transpose_value");
- int data_tr = (i_midi_file_read_byte (mf) & 0x7f) + transpose;
-
- if (data_tr > 127) data_tr = 127;
- else if (data_tr < 0) data_tr = 0;
-
- event->data.d[1] = (unsigned char) data_tr;
- }
- else /* this note is in standard drum channel (10), apply drum shift */
- {
- int drumshift = aud_get_int ("amidiplug", "ap_opts_drumshift_value");
- int data_ds = (i_midi_file_read_byte (mf) & 0x7f) + drumshift; /* always > 0 */
-
- if (data_ds > 127) data_ds -= 127;
-
- event->data.d[1] = (unsigned char) data_ds;
- }
-
- event->data.d[2] = i_midi_file_read_byte (mf) & 0x7f;
- }
- break;
-
- case 0xb: /* channel msg with 2 parameter bytes */
- case 0xe:
- {
- event = i_midi_file_new_event (track, 0);
- event->type = cmd_type[cmd >> 4];
- event->port = port;
- event->tick = tick;
- event->data.d[0] = cmd & 0x0f;
- event->data.d[1] = i_midi_file_read_byte (mf) & 0x7f;
- event->data.d[2] = i_midi_file_read_byte (mf) & 0x7f;
- }
- break;
-
- case 0xc: /* channel msg with 1 parameter byte */
- case 0xd:
- {
- event = i_midi_file_new_event (track, 0);
- event->type = cmd_type[cmd >> 4];
- event->port = port;
- event->tick = tick;
- event->data.d[0] = cmd & 0x0f;
- event->data.d[1] = i_midi_file_read_byte (mf) & 0x7f;
- }
- break;
-
- case 0xf:
- {
- switch (cmd)
- {
- case 0xf0: /* sysex */
- case 0xf7: /* continued sysex, or escaped commands */
- {
- len = i_midi_file_read_var (mf);
-
- if (len < 0)
- ERRMSG_MIDITRACK();
-
- if (cmd == 0xf0)
- ++len;
-
- event = i_midi_file_new_event (track, len);
- event->type = SND_SEQ_EVENT_SYSEX;
- event->port = port;
- event->tick = tick;
- event->data.length = len;
-
- if (cmd == 0xf0)
- {
- event->sysex[0] = 0xf0;
- c = 1;
- }
- else
- {
- c = 0;
- }
-
- for (; c < len; ++c)
- event->sysex[c] = i_midi_file_read_byte (mf);
- }
- break;
-
- case 0xff: /* meta event */
- {
- c = i_midi_file_read_byte (mf);
- len = i_midi_file_read_var (mf);
-
- if (len < 0)
- ERRMSG_MIDITRACK();
-
- switch (c)
- {
- case 0x21: /* port number */
- {
- if (len < 1)
- ERRMSG_MIDITRACK();
-
- port = i_midi_file_read_byte (mf) % port_count;
- i_midi_file_skip_bytes (mf, (len - 1));
- }
- break;
-
- case 0x2f: /* end of track */
- {
- track->end_tick = tick;
- i_midi_file_skip_bytes (mf, (track_end - mf->file_offset));
- return 1;
- }
-
- case 0x51: /* tempo */
- {
- if (len < 3)
- ERRMSG_MIDITRACK();
-
- if (mf->smpte_timing)
- {
- /* SMPTE timing doesn't change */
- i_midi_file_skip_bytes (mf,len);
- }
- else
- {
- event = i_midi_file_new_event (track, 0);
- event->type = SND_SEQ_EVENT_TEMPO;
- event->port = port;
- event->tick = tick;
- event->data.tempo = i_midi_file_read_byte (mf) << 16;
- event->data.tempo |= i_midi_file_read_byte (mf) << 8;
- event->data.tempo |= i_midi_file_read_byte (mf);
- i_midi_file_skip_bytes (mf, (len - 3));
- }
- }
- break;
-
- case 0x01: /* text comments */
- {
- if (aud_get_int ("amidiplug", "ap_opts_comments_extract") > 0)
- {
- int ic = 0;
-
- if (len < 1)
- ERRMSG_MIDITRACK();
-
- event = i_midi_file_new_event (track, 0);
- event->type = SND_SEQ_EVENT_META_TEXT;
- event->tick = tick;
- event->data.metat = g_malloc (len + 1);
-
- for (ic = 0 ; ic < len ; ic++)
- event->data.metat[ic] = i_midi_file_read_byte (mf);
-
- event->data.metat[len] = '\0';
- }
- else
- i_midi_file_skip_bytes (mf,len);
- }
- break;
-
- case 0x05: /* lyrics */
- {
- if (aud_get_int ("amidiplug", "ap_opts_lyrics_extract"))
- {
- int ic = 0;
-
- if (len < 1)
- ERRMSG_MIDITRACK();
-
- event = i_midi_file_new_event (track, 0);
- event->type = SND_SEQ_EVENT_META_LYRIC;
- event->tick = tick;
- event->data.metat = g_malloc (len + 1);
-
- for (ic = 0 ; ic < len ; ic++)
- event->data.metat[ic] = i_midi_file_read_byte (mf);
-
- event->data.metat[len] = '\0';
- }
- else
- i_midi_file_skip_bytes (mf,len);
- }
- break;
-
- default: /* ignore all other meta events */
- {
- i_midi_file_skip_bytes (mf,len);
- }
- break;
- }
- }
- break;
-
- default: /* invalid Fx command */
- ERRMSG_MIDITRACK();
- }
- }
- break;
-
- default: /* cannot happen */
- ERRMSG_MIDITRACK();
- }
- }
-
- ERRMSG_MIDITRACK();
-}
-
-
-/* read a MIDI file in Standard MIDI Format */
-/* return values: 0 = error, 1 = ok */
-int i_midi_file_parse_smf (midifile_t * mf, int port_count)
-{
- int header_len, i;
-
- /* the curren position is immediately after the "MThd" id */
- header_len = i_midi_file_read_int (mf,4);
-
- if (header_len < 6)
- {
- fprintf (stderr, "%s: invalid file format\n", mf->file_name);
- return 0;
- }
-
- mf->format = i_midi_file_read_int (mf,2);
-
- if ((mf->format != 0) && (mf->format != 1))
- {
- fprintf (stderr, "%s: type %d format is not supported\n", mf->file_name, mf->format);
- return 0;
- }
-
- mf->num_tracks = i_midi_file_read_int (mf,2);
-
- if ((mf->num_tracks < 1) || (mf->num_tracks > 1000))
- {
- fprintf (stderr, "%s: invalid number of tracks (%d)\n", mf->file_name, mf->num_tracks);
- mf->num_tracks = 0;
- return 0;
- }
-
- mf->tracks = g_new0 (midifile_track_t, mf->num_tracks);
-
- mf->time_division = i_midi_file_read_int (mf,2);
-
- if (mf->time_division < 0)
- {
- fprintf (stderr, "%s: invalid file format\n", mf->file_name);
- return 0;
- }
-
- mf->smpte_timing = !! (mf->time_division & 0x8000);
-
- /* read tracks */
- for (i = 0 ; i < mf->num_tracks ; ++i)
- {
- int len;
-
- /* search for MTrk chunk */
- for (;;)
- {
- int id = i_midi_file_read_id (mf);
- len = i_midi_file_read_int (mf,4);
-
- if (vfs_feof (mf->file_pointer))
- {
- fprintf (stderr, "%s: unexpected end of file\n", mf->file_name);
- return 0;
- }
-
- if ((len < 0) || (len >= 0x10000000))
- {
- fprintf (stderr, "%s: invalid chunk length %d\n", mf->file_name, len);
- return 0;
- }
-
- if (id == MAKE_ID ('M', 'T', 'r', 'k'))
- break;
-
- i_midi_file_skip_bytes (mf,len);
- }
-
- if (!i_midi_file_read_track (mf, &mf->tracks[i], mf->file_offset + len, port_count))
- return 0;
- }
-
- /* calculate the max_tick for the entire file */
- mf->max_tick = 0;
-
- for (i = 0 ; i < mf->num_tracks ; ++i)
- {
- if (mf->tracks[i].end_tick > mf->max_tick)
- mf->max_tick = mf->tracks[i].end_tick;
- }
-
- /* ok, success */
- return 1;
-}
-
-
-/* read a MIDI file enclosed in RIFF format */
-/* return values: 0 = error, 1 = ok */
-int i_midi_file_parse_riff (midifile_t * mf)
-{
- /* skip file length (4 bytes) */
- i_midi_file_skip_bytes (mf,4);
-
- /* check file type ("RMID" = RIFF MIDI) */
- if (i_midi_file_read_id (mf) != MAKE_ID ('R', 'M', 'I', 'D'))
- return 0;
-
- /* search for "data" chunk */
- for (;;)
- {
- int id = i_midi_file_read_id (mf);
- int len = i_midi_file_read_32_le (mf);
-
- if (vfs_feof (mf->file_pointer))
- return 0;
-
- if (id == MAKE_ID ('d', 'a', 't', 'a'))
- break;
-
- if (len < 0)
- return 0;
-
- i_midi_file_skip_bytes (mf, ((len + 1) & ~1));
- }
-
- /* the "data" chunk must contain data in SMF format */
- if (i_midi_file_read_id (mf) != MAKE_ID ('M', 'T', 'h', 'd'))
- return 0;
-
- /* ok, success */
- return 1;
-}
-
-
-/* midifile init */
-void i_midi_init (midifile_t * mf)
-{
- mf->file_pointer = NULL;
- mf->file_name = NULL;
- mf->file_offset = 0;
- mf->num_tracks = 0;
- mf->tracks = NULL;
- mf->max_tick = 0;
- mf->smpte_timing = 0;
- mf->format = 0;
- mf->time_division = 0;
- mf->ppq = 0;
- mf->current_tempo = 0;
- mf->playing_tick = 0;
- mf->avg_microsec_per_tick = 0;
- mf->length = 0;
- return;
-}
-
-
-void i_midi_free (midifile_t * mf)
-{
- g_free (mf->file_name);
- mf->file_name = NULL;
-
- if (mf->tracks)
- {
- int i;
-
- /* free event list for each track */
- for (i = 0 ; i < mf->num_tracks ; ++i)
- {
- midievent_t * event = mf->tracks[i].first_event;
- midievent_t * event_tmp = NULL;
-
- while (event)
- {
- event_tmp = event;
- event = event->next;
-
- if ((event_tmp->type == SND_SEQ_EVENT_META_TEXT) ||
- (event_tmp->type == SND_SEQ_EVENT_META_LYRIC))
- g_free (event_tmp->data.metat);
-
- g_free (event_tmp->sysex);
- g_free (event_tmp);
- }
- }
-
- /* free track array */
- g_free (mf->tracks);
- mf->tracks = NULL;
- }
-}
-
-
-/* queue set tempo */
-int i_midi_setget_tempo (midifile_t * mf)
-{
- int smpte_timing, i = 0;
- int time_division = mf->time_division;
-
- /* interpret and set tempo */
- smpte_timing = !! (time_division & 0x8000);
-
- if (!smpte_timing)
- {
- /* time_division is ticks per quarter */
- mf->current_tempo = 500000;
- mf->ppq = time_division;
- }
- else
- {
- /* upper byte is negative frames per second */
- i = 0x80 - ((time_division >> 8) & 0x7f);
- /* lower byte is ticks per frame */
- time_division &= 0xff;
-
- /* now pretend that we have quarter-note based timing */
- switch (i)
- {
- case 24:
- mf->current_tempo = 500000;
- mf->ppq = 12 * time_division;
- break;
-
- case 25:
- mf->current_tempo = 400000;
- mf->ppq = 10 * time_division;
- break;
-
- case 29: /* 30 drop-frame */
- mf->current_tempo = 100000000;
- mf->ppq = 2997 * time_division;
- break;
-
- case 30:
- mf->current_tempo = 500000;
- mf->ppq = 15 * time_division;
- break;
-
- default:
- fprintf (stderr, "Invalid number of SMPTE frames per second (%d)\n", i);
- return 0;
- }
- }
-
- DEBUGMSG ("MIDI tempo set -> time division: %i\n", midifile.time_division);
- DEBUGMSG ("MIDI tempo set -> tempo: %i\n", midifile.current_tempo);
- DEBUGMSG ("MIDI tempo set -> ppq: %i\n", midifile.ppq);
- return 1;
-}
-
-
-/* this will set the midi length in microseconds
- COMMENT: this will also reset current position in each track! */
-void i_midi_setget_length (midifile_t * mf)
-{
- int64_t length_microsec = 0;
- int last_tick = 0, i = 0;
- /* get the first microsec_per_tick ratio */
- int microsec_per_tick = (int) (mf->current_tempo / mf->ppq);
-
- /* initialize current position in each track */
- for (i = 0; i < mf->num_tracks; ++i)
- mf->tracks[i].current_event = mf->tracks[i].first_event;
-
- /* search for tempo events in each track; in fact, since the program
- currently supports type 0 and type 1 MIDI files, we should find
- tempo events only in one track */
- DEBUGMSG ("LENGTH calc: starting calc loop\n");
-
- for (;;)
- {
- midievent_t * event = NULL;
- midifile_track_t * event_track = NULL;
- int i, min_tick = mf->max_tick + 1;
-
- /* search next event */
- for (i = 0 ; i < mf->num_tracks ; ++i)
- {
- midifile_track_t * track = &mf->tracks[i];
- midievent_t * e2 = track->current_event;
-
- if (e2 && e2->tick < min_tick)
- {
- min_tick = e2->tick;
- event = e2;
- event_track = track;
- }
- }
-
- if (!event)
- {
- /* calculate the remaining length */
- length_microsec += (microsec_per_tick * (mf->max_tick - last_tick));
- break; /* end of song reached */
- }
-
- /* advance pointer to next event */
- event_track->current_event = event->next;
-
- /* check if this is a tempo event */
- if (event->type == SND_SEQ_EVENT_TEMPO)
- {
- DEBUGMSG ("LENGTH calc: tempo event (%i) encountered during calc on tick %i\n",
- event->data.tempo, event->tick);
- /* increment length_microsec with the amount of microsec before tempo change */
- length_microsec += (microsec_per_tick * (event->tick - last_tick));
- /* now update last_tick and the microsec_per_tick ratio */
- last_tick = event->tick;
- microsec_per_tick = (int) (event->data.tempo / mf->ppq);
- }
- }
-
- /* IMPORTANT
- this couple of important values is set by i_midi_set_length */
- mf->length = length_microsec;
-
- if (mf->max_tick)
- mf->avg_microsec_per_tick = (int) (length_microsec / mf->max_tick);
- else
- mf->avg_microsec_per_tick = 1; /* dummy - protect against div-by-zero */
-
- return;
-}
-
-
-/* this will get the weighted average bpm of the midi file;
- if the file has a variable bpm, 'bpm' is set to -1;
- COMMENT: this will also reset current position in each track! */
-void i_midi_get_bpm (midifile_t * mf, int * bpm, int * wavg_bpm)
-{
- int i = 0, last_tick = 0;
- unsigned weighted_avg_tempo = 0;
- bool_t is_monotempo = TRUE;
- int last_tempo = mf->current_tempo;
-
- /* initialize current position in each track */
- for (i = 0 ; i < mf->num_tracks ; ++i)
- mf->tracks[i].current_event = mf->tracks[i].first_event;
-
- /* search for tempo events in each track; in fact, since the program
- currently supports type 0 and type 1 MIDI files, we should find
- tempo events only in one track */
- DEBUGMSG ("BPM calc: starting calc loop\n");
-
- for (;;)
- {
- midievent_t * event = NULL;
- midifile_track_t * event_track = NULL;
- int i, min_tick = mf->max_tick + 1;
-
- /* search next event */
- for (i = 0 ; i < mf->num_tracks ; ++i)
- {
- midifile_track_t * track = &mf->tracks[i];
- midievent_t * e2 = track->current_event;
-
- if (e2 && e2->tick < min_tick)
- {
- min_tick = e2->tick;
- event = e2;
- event_track = track;
- }
- }
-
- if (!event)
- {
- /* calculate the remaining length */
- weighted_avg_tempo += (unsigned) (last_tempo * ((float) (mf->max_tick - last_tick) / (float) mf->max_tick));
- break; /* end of song reached */
- }
-
- /* advance pointer to next event */
- event_track->current_event = event->next;
-
- /* check if this is a tempo event */
- if (event->type == SND_SEQ_EVENT_TEMPO)
- {
- /* check if this is a tempo change (real change, tempo should be
- different) in the midi file (and it shouldn't be at tick 0); */
- if ((is_monotempo) && (event->tick > 0) && (event->data.tempo != last_tempo))
- is_monotempo = FALSE;
-
- DEBUGMSG ("BPM calc: tempo event (%i) encountered during calc on tick %i\n",
- event->data.tempo, event->tick);
- /* add the previous tempo change multiplied for its weight (the tick interval for the tempo ) */
- weighted_avg_tempo += (unsigned) (last_tempo * ((float) (event->tick - last_tick) / (float) mf->max_tick));
- /* now update last_tick and the microsec_per_tick ratio */
- last_tick = event->tick;
- last_tempo = event->data.tempo;
- }
- }
-
- DEBUGMSG ("BPM calc: weighted average tempo: %i\n", weighted_avg_tempo);
-
- *wavg_bpm = (int) (60000000 / weighted_avg_tempo);
-
- DEBUGMSG ("BPM calc: weighted average bpm: %i\n", *wavg_bpm);
-
- if (is_monotempo)
- *bpm = *wavg_bpm; /* the song has fixed bpm */
- else
- *bpm = -1; /* the song has variable bpm */
-
- return;
-}
-
-
-/* helper function that parses a midi file; returns 1 on success, 0 otherwise */
-int i_midi_parse_from_filename (const char * filename, midifile_t * mf)
-{
- i_midi_init (mf);
- DEBUGMSG ("PARSE_FROM_FILENAME requested, opening file: %s\n", filename);
- mf->file_pointer = vfs_fopen (filename, "rb");
-
- if (!mf->file_pointer)
- {
- fprintf (stderr, "Cannot open %s\n", filename);
- return 0;
- }
-
- mf->file_name = g_strdup (filename);
-
- switch (i_midi_file_read_id (mf))
- {
- case MAKE_ID ('R', 'I', 'F', 'F') :
- {
- DEBUGMSG ("PARSE_FROM_FILENAME requested, RIFF chunk found, processing...\n");
-
- /* read riff chunk */
- if (!i_midi_file_parse_riff (mf))
- WARNANDBREAK ("%s: invalid file format (riff parser)\n", filename);
-
- /* if that was read correctly, go ahead and read smf data */
- }
-
- case MAKE_ID ('M', 'T', 'h', 'd') :
- {
- DEBUGMSG ("PARSE_FROM_FILENAME requested, MThd chunk found, processing...\n");
-
- /* we don't care about port count here, pass 1 */
- if (!i_midi_file_parse_smf (mf, 1))
- WARNANDBREAK ("%s: invalid file format (smf parser)\n", filename);
-
- if (mf->time_division < 1)
- WARNANDBREAK ("%s: invalid time division (%i)\n", filename, mf->time_division);
-
- /* fill mf->ppq and mf->tempo using time_division */
- if (!i_midi_setget_tempo (mf))
- WARNANDBREAK ("%s: invalid values while setting ppq and tempo\n", filename);
-
- /* fill mf->length, keeping in count tempo-changes */
- i_midi_setget_length (mf);
-
- /* ok, mf has been filled with information; successfully return */
- vfs_fclose (mf->file_pointer);
- return 1;
- }
-
- default:
- {
- fprintf (stderr, "%s is not a Standard MIDI File\n", filename);
- break;
- }
- }
-
- /* something failed */
- vfs_fclose (mf->file_pointer);
- return 0;
-}
diff --git a/src/amidi-plug/i_midi.cc b/src/amidi-plug/i_midi.cc
new file mode 100644
index 000000000000..73087128614c
--- /dev/null
+++ b/src/amidi-plug/i_midi.cc
@@ -0,0 +1,803 @@
+/*
+*
+* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2006
+*
+* MIDI (SMF) parser based on aplaymidi.c from ALSA-utils
+* aplaymidi.c is Copyright (c) 2004 Clemens Ladisch <clemens at ladisch.de>
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+*/
+
+#include "i_midi.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/vfs.h>
+
+#include "i_configure.h"
+
+#define MAKE_ID(c1, c2, c3, c4) ((c1) | ((c2) << 8) | ((c3) << 16) | ((c4) << 24))
+
+#define WARNANDBREAK(...) { AUDERR (__VA_ARGS__); break; }
+
+#define ERRMSG_MIDITRACK() { AUDERR ("%s: invalid MIDI data (offset %#x)", \
+ (const char *) file_name, file_offset); return false; }
+
+
+/* skip a certain number of bytes */
+void midifile_t::skip_bytes (int bytes)
+{
+ while (bytes > 0)
+ {
+ read_byte ();
+ --bytes;
+ }
+}
+
+
+/* reads a single byte */
+int midifile_t::read_byte ()
+{
+ if (file_offset >= file_data.len ())
+ {
+ file_eof = true;
+ return -1;
+ }
+
+ return (unsigned char) file_data[file_offset ++];
+}
+
+
+/* reads a little-endian 32-bit integer */
+int midifile_t::read_32_le ()
+{
+ int value;
+ value = read_byte ();
+ value |= read_byte () << 8;
+ value |= read_byte () << 16;
+ value |= read_byte () << 24;
+ return !file_eof ? value : -1;
+}
+
+
+/* reads a 4-character identifier */
+int midifile_t::read_id ()
+{
+ return read_32_le ();
+}
+
+
+/* reads a fixed-size big-endian number */
+int midifile_t::read_int (int bytes)
+{
+ int c, value = 0;
+
+ do
+ {
+ c = read_byte ();
+
+ if (c < 0) return -1;
+
+ value = (value << 8) | c;
+ }
+ while (--bytes);
+
+ return value;
+}
+
+
+/* reads a variable-length number */
+int midifile_t::read_var ()
+{
+ int value, c;
+
+ c = read_byte ();
+ value = c & 0x7f;
+
+ if (c & 0x80)
+ {
+ c = read_byte ();
+ value = (value << 7) | (c & 0x7f);
+
+ if (c & 0x80)
+ {
+ c = read_byte ();
+ value = (value << 7) | (c & 0x7f);
+
+ if (c & 0x80)
+ {
+ c = read_byte ();
+ value = (value << 7) | c;
+
+ if (c & 0x80)
+ return -1;
+ }
+ }
+ }
+
+ return value;
+}
+
+
+/* reads one complete track from the file */
+bool midifile_t::read_track (midifile_track_t & track, int track_end, int port_count)
+{
+ int tick = 0;
+ unsigned char last_cmd = 0;
+ unsigned char port = 0;
+
+ track.start_tick = -1;
+ track.end_tick = -1;
+
+ /* the current file position is after the track ID and length */
+ while (file_offset < track_end)
+ {
+ unsigned char cmd;
+ midievent_t * event;
+ int delta_ticks, len, c;
+
+ delta_ticks = read_var ();
+
+ if (delta_ticks < 0)
+ break;
+
+ tick += delta_ticks;
+
+ c = read_byte ();
+
+ if (c < 0)
+ break;
+
+ if (c & 0x80)
+ {
+ /* have command */
+ cmd = c;
+
+ if (cmd < 0xf0)
+ last_cmd = cmd;
+ }
+ else
+ {
+ /* running status */
+ file_offset--;
+ cmd = last_cmd;
+
+ if (!cmd)
+ ERRMSG_MIDITRACK();
+ }
+
+ switch (cmd >> 4)
+ {
+ /* maps SMF events to ALSA sequencer events */
+ static unsigned char cmd_type[16] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ SND_SEQ_EVENT_NOTEOFF, // 08h
+ SND_SEQ_EVENT_NOTEON, // 09h
+ SND_SEQ_EVENT_KEYPRESS, // 0ah
+ SND_SEQ_EVENT_CONTROLLER, // 0bh
+ SND_SEQ_EVENT_PGMCHANGE, // 0ch
+ SND_SEQ_EVENT_CHANPRESS, // 0dh
+ SND_SEQ_EVENT_PITCHBEND // 0eh
+ };
+
+ case 0x8: /* channel msg with 2 parameter bytes */
+ case 0x9:
+ case 0xa:
+ {
+ event = track.add_event ();
+ event->type = cmd_type[cmd >> 4];
+ event->port = port;
+ event->tick = tick;
+ event->d[0] = cmd & 0x0f;
+
+ /* if this note is not in standard drum channel (10), apply transpose */
+ if (event->d[0] != 9)
+ {
+ int transpose = aud_get_int ("amidiplug", "ap_opts_transpose_value");
+ int data_tr = (read_byte () & 0x7f) + transpose;
+
+ if (data_tr > 127) data_tr = 127;
+ else if (data_tr < 0) data_tr = 0;
+
+ event->d[1] = (unsigned char) data_tr;
+ }
+ else /* this note is in standard drum channel (10), apply drum shift */
+ {
+ int drumshift = aud_get_int ("amidiplug", "ap_opts_drumshift_value");
+ int data_ds = (read_byte () & 0x7f) + drumshift; /* always > 0 */
+
+ if (data_ds > 127) data_ds -= 127;
+
+ event->d[1] = (unsigned char) data_ds;
+ }
+
+ event->d[2] = read_byte () & 0x7f;
+
+ if (event->type == SND_SEQ_EVENT_NOTEON && track.start_tick < 0)
+ track.start_tick = tick;
+ if (track.start_tick >= 0 && tick >= track.start_tick)
+ track.end_tick = tick;
+ }
+ break;
+
+ case 0xb: /* channel msg with 2 parameter bytes */
+ case 0xe:
+ {
+ event = track.add_event ();
+ event->type = cmd_type[cmd >> 4];
+ event->port = port;
+ event->tick = tick;
+ event->d[0] = cmd & 0x0f;
+ event->d[1] = read_byte () & 0x7f;
+ event->d[2] = read_byte () & 0x7f;
+
+ if (track.start_tick >= 0 && tick >= track.start_tick)
+ track.end_tick = tick;
+ }
+ break;
+
+ case 0xc: /* channel msg with 1 parameter byte */
+ case 0xd:
+ {
+ event = track.add_event ();
+ event->type = cmd_type[cmd >> 4];
+ event->port = port;
+ event->tick = tick;
+ event->d[0] = cmd & 0x0f;
+ event->d[1] = read_byte () & 0x7f;
+
+ if (track.start_tick >= 0 && tick >= track.start_tick)
+ track.end_tick = tick;
+ }
+ break;
+
+ case 0xf:
+ {
+ switch (cmd)
+ {
+ case 0xf0: /* sysex */
+ case 0xf7: /* continued sysex, or escaped commands */
+ {
+ len = read_var ();
+
+ if (len < 0)
+ ERRMSG_MIDITRACK();
+
+ /* skip sysex */
+ skip_bytes (len);
+ }
+ break;
+
+ case 0xff: /* meta event */
+ {
+ c = read_byte ();
+ len = read_var ();
+
+ if (len < 0)
+ ERRMSG_MIDITRACK();
+
+ switch (c)
+ {
+ case 0x21: /* port number */
+ {
+ if (len < 1)
+ ERRMSG_MIDITRACK();
+
+ port = read_byte () % port_count;
+ skip_bytes (len - 1);
+ }
+ break;
+
+ case 0x2f: /* end of track */
+ {
+ if (! aud_get_bool ("amidiplug", "skip_leading"))
+ track.start_tick = 0;
+ if (! aud_get_bool ("amidiplug", "skip_trailing"))
+ track.end_tick = tick;
+
+ skip_bytes (track_end - file_offset);
+ return true;
+ }
+
+ case 0x51: /* tempo */
+ {
+ if (len < 3)
+ ERRMSG_MIDITRACK();
+
+ if (smpte_timing)
+ {
+ /* SMPTE timing doesn't change */
+ skip_bytes (len);
+ }
+ else
+ {
+ event = track.add_event ();
+ event->type = SND_SEQ_EVENT_TEMPO;
+ event->port = port;
+ event->tick = tick;
+ event->tempo = read_byte () << 16;
+ event->tempo |= read_byte () << 8;
+ event->tempo |= read_byte ();
+ skip_bytes (len - 3);
+ }
+ }
+ break;
+
+ case 0x01: /* text comments */
+ {
+ if (len < 0)
+ ERRMSG_MIDITRACK();
+
+ event = track.add_event ();
+ event->type = SND_SEQ_EVENT_META_TEXT;
+ event->tick = tick;
+
+ StringBuf buf (len);
+ for (int i = 0; i < len; i ++)
+ buf[i] = read_byte ();
+
+ event->metat = String (str_to_utf8 (std::move (buf)));
+ }
+ break;
+
+ case 0x05: /* lyrics */
+ {
+ if (len < 0)
+ ERRMSG_MIDITRACK();
+
+ event = track.add_event ();
+ event->type = SND_SEQ_EVENT_META_LYRIC;
+ event->tick = tick;
+
+ StringBuf buf (len);
+ for (int i = 0; i < len; i ++)
+ buf[i] = read_byte ();
+
+ event->metat = String (str_to_utf8 (std::move (buf)));
+ }
+ break;
+
+ default: /* ignore all other meta events */
+ {
+ skip_bytes (len);
+ }
+ break;
+ }
+ }
+ break;
+
+ default: /* invalid Fx command */
+ ERRMSG_MIDITRACK();
+ }
+ }
+ break;
+
+ default: /* cannot happen */
+ ERRMSG_MIDITRACK();
+ }
+ }
+
+ ERRMSG_MIDITRACK();
+}
+
+
+/* read a MIDI file in Standard MIDI Format */
+/* return values: 0 = error, 1 = ok */
+bool midifile_t::parse_smf (int port_count)
+{
+ int header_len;
+
+ /* the curren position is immediately after the "MThd" id */
+ header_len = read_int (4);
+
+ if (header_len < 6)
+ {
+ AUDERR ("%s: invalid file format\n", (const char *) file_name);
+ return false;
+ }
+
+ format = read_int (2);
+
+ if (format != 0 && format != 1)
+ {
+ AUDERR ("%s: type %d format is not supported\n", (const char *) file_name, format);
+ return false;
+ }
+
+ int num_tracks = read_int (2);
+
+ if (num_tracks < 1 || num_tracks > 1000)
+ {
+ AUDERR ("%s: invalid number of tracks (%d)\n", (const char *) file_name, num_tracks);
+ num_tracks = 0;
+ return false;
+ }
+
+ tracks.insert (0, num_tracks);
+
+ time_division = read_int (2);
+
+ if (time_division < 0)
+ {
+ AUDERR ("%s: invalid file format\n", (const char *) file_name);
+ return false;
+ }
+
+ smpte_timing = !! (time_division & 0x8000);
+
+ /* read tracks */
+ for (midifile_track_t & track : tracks)
+ {
+ int len;
+
+ /* search for MTrk chunk */
+ for (;;)
+ {
+ int id = read_id ();
+ len = read_int (4);
+
+ if (file_eof)
+ {
+ AUDERR ("%s: unexpected end of file\n", (const char *) file_name);
+ return false;
+ }
+
+ if (len < 0 || len >= 0x10000000)
+ {
+ AUDERR ("%s: invalid chunk length %d\n", (const char *) file_name, len);
+ return false;
+ }
+
+ if (id == MAKE_ID ('M', 'T', 'r', 'k'))
+ break;
+
+ skip_bytes (len);
+ }
+
+ if (! read_track (track, file_offset + len, port_count))
+ return false;
+ }
+
+ /* calculate the max_tick for the entire file */
+ start_tick = -1;
+ max_tick = 0;
+
+ for (midifile_track_t & track : tracks)
+ {
+ if (track.start_tick >= 0 && (start_tick < 0 || track.start_tick < start_tick))
+ start_tick = track.start_tick;
+ if (track.end_tick > max_tick)
+ max_tick = track.end_tick;
+ }
+
+ if (start_tick < 0)
+ start_tick = 0;
+
+ /* ok, success */
+ return true;
+}
+
+
+/* read a MIDI file enclosed in RIFF format */
+/* return values: 0 = error, 1 = ok */
+bool midifile_t::parse_riff ()
+{
+ /* skip file length (4 bytes) */
+ skip_bytes (4);
+
+ /* check file type ("RMID" = RIFF MIDI) */
+ if (read_id () != MAKE_ID ('R', 'M', 'I', 'D'))
+ return false;
+
+ /* search for "data" chunk */
+ for (;;)
+ {
+ int id = read_id ();
+ int len = read_32_le ();
+
+ if (file_eof)
+ return false;
+
+ if (id == MAKE_ID ('d', 'a', 't', 'a'))
+ break;
+
+ if (len < 0)
+ return false;
+
+ skip_bytes ((len + 1) & ~1);
+ }
+
+ /* the "data" chunk must contain data in SMF format */
+ if (read_id () != MAKE_ID ('M', 'T', 'h', 'd'))
+ return false;
+
+ /* ok, success */
+ return true;
+}
+
+
+/* queue set tempo */
+bool midifile_t::setget_tempo ()
+{
+ /* interpret and set tempo */
+ bool smpte_timing = !! (time_division & 0x8000);
+
+ if (!smpte_timing)
+ {
+ /* time_division is ticks per quarter */
+ current_tempo = 500000;
+ ppq = time_division;
+ }
+ else
+ {
+ /* upper byte is negative frames per second */
+ int fps = 0x80 - ((time_division >> 8) & 0x7f);
+ /* lower byte is ticks per frame */
+ int tpf = time_division & 0xff;
+
+ /* now pretend that we have quarter-note based timing */
+ switch (fps)
+ {
+ case 24:
+ current_tempo = 500000;
+ ppq = 12 * tpf;
+ break;
+
+ case 25:
+ current_tempo = 400000;
+ ppq = 10 * tpf;
+ break;
+
+ case 29: /* 30 drop-frame */
+ current_tempo = 100000000;
+ ppq = 2997 * tpf;
+ break;
+
+ case 30:
+ current_tempo = 500000;
+ ppq = 15 * tpf;
+ break;
+
+ default:
+ AUDERR ("Invalid number of SMPTE frames per second (%d)\n", fps);
+ return false;
+ }
+ }
+
+ AUDDBG ("MIDI tempo set -> time division: %i\n", time_division);
+ AUDDBG ("MIDI tempo set -> tempo: %i\n", current_tempo);
+ AUDDBG ("MIDI tempo set -> ppq: %i\n", ppq);
+ return true;
+}
+
+
+/* this will set the midi length in microseconds
+ COMMENT: this will also reset current position in each track! */
+void midifile_t::setget_length ()
+{
+ int64_t length_microsec = 0;
+ int last_tick = start_tick;
+ /* get the first microsec_per_tick ratio */
+ int microsec_per_tick = (int) (current_tempo / ppq);
+
+ /* initialize current position in each track */
+ for (midifile_track_t & track : tracks)
+ track.current_event = track.events.head ();
+
+ /* search for tempo events in each track; in fact, since the program
+ currently supports type 0 and type 1 MIDI files, we should find
+ tempo events only in one track */
+ AUDDBG ("LENGTH calc: starting calc loop\n");
+
+ for (;;)
+ {
+ midievent_t * event = nullptr;
+ midifile_track_t * event_track = nullptr;
+ int min_tick = max_tick + 1;
+
+ /* search next event */
+ for (midifile_track_t & track : tracks)
+ {
+ midievent_t * e2 = track.current_event;
+
+ if (e2 && e2->tick < min_tick)
+ {
+ min_tick = e2->tick;
+ event = e2;
+ event_track = & track;
+ }
+ }
+
+ if (!event)
+ {
+ /* calculate the remaining length */
+ length_microsec += (microsec_per_tick * (max_tick - last_tick));
+ break; /* end of song reached */
+ }
+
+ /* advance pointer to next event */
+ event_track->current_event = event_track->events.next (event);
+
+ /* check if this is a tempo event */
+ if (event->type == SND_SEQ_EVENT_TEMPO)
+ {
+ int tick = aud::max (event->tick, start_tick);
+ AUDDBG ("LENGTH calc: tempo event (%i) on tick %i\n", event->tempo, tick);
+
+ /* increment length_microsec with the amount of microsec before tempo change */
+ length_microsec += (microsec_per_tick * (tick - last_tick));
+ /* now update last_tick and the microsec_per_tick ratio */
+ last_tick = tick;
+ microsec_per_tick = (int) (event->tempo / ppq);
+ }
+ }
+
+ /* IMPORTANT
+ this couple of important values is set by midifile_t::set_length */
+ length = length_microsec;
+
+ if (max_tick > start_tick)
+ avg_microsec_per_tick = (int) (length_microsec / (max_tick - start_tick));
+ else
+ avg_microsec_per_tick = 0;
+
+ return;
+}
+
+
+/* this will get the weighted average bpm of the midi file;
+ if the file has a variable bpm, 'bpm' is set to -1;
+ COMMENT: this will also reset current position in each track! */
+void midifile_t::get_bpm (int * bpm, int * wavg_bpm)
+{
+ int last_tick = start_tick;
+ unsigned weighted_avg_tempo = 0;
+ bool is_monotempo = true;
+ int last_tempo = current_tempo;
+
+ /* initialize current position in each track */
+ for (midifile_track_t & track : tracks)
+ track.current_event = track.events.head ();
+
+ /* search for tempo events in each track; in fact, since the program
+ currently supports type 0 and type 1 MIDI files, we should find
+ tempo events only in one track */
+ AUDDBG ("BPM calc: starting calc loop\n");
+
+ for (;;)
+ {
+ midievent_t * event = nullptr;
+ midifile_track_t * event_track = nullptr;
+ int min_tick = max_tick + 1;
+
+ /* search next event */
+ for (midifile_track_t & track : tracks)
+ {
+ midievent_t * e2 = track.current_event;
+
+ if (e2 && e2->tick < min_tick)
+ {
+ min_tick = e2->tick;
+ event = e2;
+ event_track = & track;
+ }
+ }
+
+ if (!event)
+ {
+ /* calculate the remaining length */
+ if (max_tick > start_tick)
+ weighted_avg_tempo += (unsigned) (last_tempo *
+ ((float) (max_tick - last_tick) / (float) (max_tick - start_tick)));
+
+ break; /* end of song reached */
+ }
+
+ /* advance pointer to next event */
+ event_track->current_event = event_track->events.next (event);
+
+ /* check if this is a tempo event */
+ if (event->type == SND_SEQ_EVENT_TEMPO)
+ {
+ int tick = aud::max (event->tick, start_tick);
+ AUDDBG ("BPM calc: tempo event (%i) on tick %i\n", event->tempo, tick);
+
+ /* check if this is a tempo change (real change, tempo should be
+ different) in the midi file (and it shouldn't be at tick 0); */
+ if (is_monotempo && tick > start_tick && event->tempo != last_tempo)
+ is_monotempo = false;
+
+ /* add the previous tempo change multiplied for its weight (the tick interval for the tempo ) */
+ if (max_tick > start_tick)
+ weighted_avg_tempo += (unsigned) (last_tempo *
+ ((float) (tick - last_tick) / (float) (max_tick - start_tick)));
+
+ /* now update last_tick and the microsec_per_tick ratio */
+ last_tick = tick;
+ last_tempo = event->tempo;
+ }
+ }
+
+ AUDDBG ("BPM calc: weighted average tempo: %i\n", weighted_avg_tempo);
+
+ if (weighted_avg_tempo > 0)
+ *wavg_bpm = (int) (60000000 / weighted_avg_tempo);
+ else
+ *wavg_bpm = 0;
+
+ AUDDBG ("BPM calc: weighted average bpm: %i\n", *wavg_bpm);
+
+ if (is_monotempo)
+ *bpm = *wavg_bpm; /* the song has fixed bpm */
+ else
+ *bpm = -1; /* the song has variable bpm */
+}
+
+
+/* helper function that parses a midi file; returns 1 on success, 0 otherwise */
+bool midifile_t::parse_from_file (const char * filename, VFSFile & file)
+{
+ bool success = false;
+
+ file_name = String (filename);
+ file_data = file.read_all ();
+
+ switch (read_id ())
+ {
+ case MAKE_ID ('R', 'I', 'F', 'F') :
+ AUDDBG ("PARSE_FROM_FILENAME requested, RIFF chunk found, processing...\n");
+
+ /* read riff chunk */
+ if (!parse_riff ())
+ WARNANDBREAK ("%s: invalid file format (riff parser)\n", filename);
+
+ /* if that was read correctly, go ahead and read smf data */
+
+ case MAKE_ID ('M', 'T', 'h', 'd') :
+ AUDDBG ("PARSE_FROM_FILENAME requested, MThd chunk found, processing...\n");
+
+ /* we don't care about port count here, pass 1 */
+ if (!parse_smf (1))
+ WARNANDBREAK ("%s: invalid file format (smf parser)\n", filename);
+
+ if (time_division < 1)
+ WARNANDBREAK ("%s: invalid time division (%i)\n", filename, time_division);
+
+ /* fill ppq and tempo using time_division */
+ if (!setget_tempo ())
+ WARNANDBREAK ("%s: invalid values while setting ppq and tempo\n", filename);
+
+ /* fill length, keeping in count tempo-changes */
+ setget_length ();
+
+ /* ok, mf has been filled with information; successfully return */
+ success = true;
+ break;
+
+ default:
+ AUDERR ("%s is not a Standard MIDI File\n", filename);
+ break;
+ }
+
+ file_name = String ();
+ file_data.clear ();
+
+ return success;
+}
diff --git a/src/amidi-plug/i_midi.h b/src/amidi-plug/i_midi.h
index 7c86e79bd8b6..6863be68cb4e 100644
--- a/src/amidi-plug/i_midi.h
+++ b/src/amidi-plug/i_midi.h
@@ -22,11 +22,11 @@
#define _I_MIDI_H 1
#include <stdint.h>
-#include <libaudcore/vfs.h>
+#include <libaudcore/index.h>
#include "i_midievent.h"
-#define MAKE_ID(c1, c2, c3, c4) ((c1) | ((c2) << 8) | ((c3) << 16) | ((c4) << 24))
+class VFSFile;
/* sequencer event type, got from ALSA header alsa/seq_event.h */
@@ -227,53 +227,61 @@ enum snd_seq_event_type
};
-typedef struct
+struct midifile_track_t
{
- midievent_t * first_event; /* list of all events in this track */
+ List<midievent_t> events; /* list of all events in this track */
+ int start_tick; /* start of this track */
int end_tick; /* length of this track */
midievent_t * current_event; /* used while loading and playing */
-}
-midifile_track_t;
-typedef struct
+ midievent_t * add_event ()
+ {
+ midievent_t * event = new midievent_t ();
+ events.append (event);
+ return event;
+ }
+
+ ~midifile_track_t ()
+ { events.clear (); }
+};
+
+
+struct midifile_t
{
- VFSFile * file_pointer;
- char * file_name;
- int file_offset;
-
- int num_tracks;
- midifile_track_t * tracks;
-
- unsigned short format;
- unsigned max_tick;
- int smpte_timing;
-
- int time_division;
- int ppq;
- int current_tempo;
-
- int playing_tick;
- int avg_microsec_per_tick;
- int64_t length;
-}
-midifile_t;
-
-midievent_t * i_midi_file_new_event (midifile_track_t *, int);
-void i_midi_file_skip_bytes (midifile_t *, int);
-int i_midi_file_read_byte (midifile_t *);
-int i_midi_file_read_32_le (midifile_t *);
-int i_midi_file_read_id (midifile_t *);
-int i_midi_file_read_int (midifile_t *, int);
-int i_midi_file_read_var (midifile_t *);
-int i_midi_file_read_track (midifile_t *, midifile_track_t *, int, int);
-int i_midi_file_parse_riff (midifile_t *);
-int i_midi_file_parse_smf (midifile_t *, int);
-void i_midi_init (midifile_t *);
-void i_midi_free (midifile_t *);
-int i_midi_setget_tempo (midifile_t *);
-void i_midi_setget_length (midifile_t *);
-void i_midi_get_bpm (midifile_t *, int *, int *);
-/* helper function */
-int i_midi_parse_from_filename (const char *, midifile_t *);
+ Index<midifile_track_t> tracks;
+
+ unsigned short format = 0;
+ int start_tick = 0;
+ int max_tick = 0;
+ int smpte_timing = 0;
+
+ int time_division = 0;
+ int ppq = 0;
+ int current_tempo = 0;
+
+ int avg_microsec_per_tick = 0;
+ int64_t length = 0;
+
+ void get_bpm (int *, int *);
+ bool parse_from_file (const char *, VFSFile & file);
+
+private:
+ String file_name;
+ Index<char> file_data;
+ int file_offset = 0;
+ bool file_eof = false;
+
+ void skip_bytes (int);
+ int read_byte ();
+ int read_32_le ();
+ int read_id ();
+ int read_int (int);
+ int read_var ();
+ bool read_track (midifile_track_t &, int, int);
+ bool parse_smf (int);
+ bool parse_riff ();
+ bool setget_tempo ();
+ void setget_length ();
+};
#endif /* !_I_MIDI_H */
diff --git a/src/amidi-plug/i_midievent.h b/src/amidi-plug/i_midievent.h
index 05a379686b3c..b939e5dec360 100644
--- a/src/amidi-plug/i_midievent.h
+++ b/src/amidi-plug/i_midievent.h
@@ -21,22 +21,18 @@
#ifndef _I_MIDIEVENT_H
#define _I_MIDIEVENT_H 1
-struct midievent_s
+#include <libaudcore/list.h>
+#include <libaudcore/objects.h>
+
+struct midievent_t : public ListNode
{
- struct midievent_s * next; /* linked list */
unsigned char type; /* SND_SEQ_EVENT_xxx */
unsigned char port; /* port index */
- unsigned tick;
- union
- {
- unsigned char d[3]; /* channel and data bytes */
- int tempo;
- unsigned length; /* length of sysex data */
- char * metat; /* meta-event text */
- } data;
- unsigned char * sysex;
-};
+ int tick;
-typedef struct midievent_s midievent_t;
+ unsigned char d[3]; /* channel and data bytes */
+ int tempo;
+ String metat; /* meta-event text */
+};
#endif /* !_I_MIDIEVENT_H */
diff --git a/src/amidi-plug/i_utils.c b/src/amidi-plug/i_utils.c
deleted file mode 100644
index d5d8cc419b6c..000000000000
--- a/src/amidi-plug/i_utils.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2006
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include "i_utils.h"
-
-#include <stdlib.h>
-#include <gtk/gtk.h>
-#include <audacious/i18n.h>
-
-#include "amidi-plug.logo.xpm"
-
-
-void i_about_gui (void)
-{
- static GtkWidget * aboutwin = NULL;
- GtkWidget * logo_image;
- GdkPixbuf * logo_pixbuf;
-
- if (aboutwin != NULL)
- return;
-
- aboutwin = gtk_dialog_new_with_buttons (_("About AMIDI-Plug"), NULL, 0,
- _("_Close"), GTK_RESPONSE_CLOSE, NULL);
- gtk_window_set_resizable (GTK_WINDOW (aboutwin), FALSE);
-
- g_signal_connect (aboutwin, "response", (GCallback) gtk_widget_destroy, NULL);
- g_signal_connect (G_OBJECT (aboutwin), "destroy", G_CALLBACK (gtk_widget_destroyed), &aboutwin);
-
- GtkWidget * vbox = gtk_dialog_get_content_area ((GtkDialog *) aboutwin);
-
- logo_pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) amidiplug_xpm_logo);
- logo_image = gtk_image_new_from_pixbuf (logo_pixbuf);
- gtk_box_pack_start ((GtkBox *) vbox, logo_image, FALSE, FALSE, 0);
- g_object_unref (logo_pixbuf);
-
- char * text = g_strjoin (NULL, _("AMIDI-Plug"),
- _("\nmodular MIDI music player\n"
- "http://www.develia.org/projects.php?p=amidiplug\n\n"
- "written by Giacomo Lozito\n"
- "<james at develia.org>\n\n"
- "special thanks to...\n\n"
- "Clemens Ladisch and Jaroslav Kysela\n"
- "for their cool programs aplaymidi and amixer; those\n"
- "were really useful, along with alsa-lib docs, in order\n"
- "to learn more about the ALSA API\n\n"
- "Alfredo Spadafina\n"
- "for the nice midi keyboard logo\n\n"
- "Tony Vroon\n"
- "for the good help with alpha testing"), NULL);
-
- GtkWidget * label = gtk_label_new (text);
- gtk_box_pack_start ((GtkBox *) vbox, label, FALSE, FALSE, 0);
- g_free (text);
-
- gtk_widget_show_all (aboutwin);
-}
diff --git a/src/amidi-plug/i_utils.h b/src/amidi-plug/i_utils.h
deleted file mode 100644
index 2f206bf0886c..000000000000
--- a/src/amidi-plug/i_utils.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2006
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#ifndef _I_UTILS_H
-#define _I_UTILS_H 1
-
-void i_about_gui (void);
-
-#endif /* !_I_UTILS_H */
diff --git a/src/aosd/Makefile b/src/aosd/Makefile
index 136784634f2d..3a02e6565327 100644
--- a/src/aosd/Makefile
+++ b/src/aosd/Makefile
@@ -1,11 +1,11 @@
PLUGIN = aosd${PLUGIN_SUFFIX}
-SRCS = aosd.c \
- aosd_osd.c \
- aosd_style.c \
- aosd_trigger.c \
- aosd_ui.c \
- aosd_cfg.c \
+SRCS = aosd.cc \
+ aosd_osd.cc \
+ aosd_style.cc \
+ aosd_trigger.cc \
+ aosd_ui.cc \
+ aosd_cfg.cc \
ghosd.c \
ghosd-main.c
@@ -14,6 +14,8 @@ include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} ${XRENDER_CFLAGS} ${XCOMPOSITE_CFLAGS} -I../..
LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${XRENDER_LIBS} ${XCOMPOSITE_LIBS} -lm
diff --git a/src/aosd/aosd.c b/src/aosd/aosd.c
deleted file mode 100644
index 03044670b2fe..000000000000
--- a/src/aosd/aosd.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include <audacious/i18n.h>
-
-#include "aosd.h"
-#include "aosd_ui.h"
-#include "aosd_osd.h"
-#include "aosd_cfg.h"
-#include "aosd_trigger.h"
-
-static const char aosd_about[] =
- N_("Audacious OSD\n"
- "http://www.develia.org/projects.php?p=audacious#aosd\n\n"
- "Written by Giacomo Lozito <james at develia.org>\n\n"
- "Based in part on Evan Martin's Ghosd library:\n"
- "http://neugierig.org/software/ghosd/");
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("AOSD (On-Screen Display)"),
- .domain = PACKAGE,
- .about_text = aosd_about,
- .init = aosd_init,
- .configure = aosd_configure,
- .cleanup = aosd_cleanup
-)
-
-aosd_cfg_t * global_config = NULL;
-gboolean plugin_is_active = FALSE;
-
-
-/* ***************** */
-/* plug-in functions */
-
-gboolean aosd_init (void)
-{
- plugin_is_active = TRUE;
- g_log_set_handler( NULL , G_LOG_LEVEL_WARNING , g_log_default_handler , NULL );
-
- global_config = aosd_cfg_new();
- aosd_cfg_load( global_config );
-
- aosd_osd_init( global_config->osd->misc.transparency_mode );
-
- aosd_trigger_start( &global_config->osd->trigger );
-
- return TRUE;
-}
-
-
-void
-aosd_cleanup ( void )
-{
- if ( plugin_is_active == TRUE )
- {
- aosd_trigger_stop( &global_config->osd->trigger );
-
- aosd_osd_shutdown();
- aosd_osd_cleanup();
-
- if ( global_config != NULL )
- {
- aosd_cfg_delete( global_config );
- global_config = NULL;
- }
-
- plugin_is_active = FALSE;
- }
-}
-
-
-void
-aosd_configure ( void )
-{
- /* create a new configuration object */
- aosd_cfg_t *cfg = aosd_cfg_new();
- /* fill it with information from config file */
- aosd_cfg_load( cfg );
- /* call the configuration UI */
- aosd_ui_configure( cfg );
- /* delete configuration object */
- aosd_cfg_delete( cfg );
-}
diff --git a/src/aosd/aosd.cc b/src/aosd/aosd.cc
new file mode 100644
index 000000000000..db49b1fc333e
--- /dev/null
+++ b/src/aosd/aosd.cc
@@ -0,0 +1,59 @@
+/*
+*
+* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+*/
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+
+#include "aosd.h"
+#include "aosd_osd.h"
+#include "aosd_cfg.h"
+#include "aosd_trigger.h"
+
+EXPORT AOSD aud_plugin_instance;
+
+const char AOSD::about[] =
+ N_("Audacious OSD\n"
+ "http://www.develia.org/projects.php?p=audacious#aosd\n\n"
+ "Written by Giacomo Lozito <james at develia.org>\n\n"
+ "Based in part on Evan Martin's Ghosd library:\n"
+ "http://neugierig.org/software/ghosd/");
+
+aosd_cfg_t global_config = aosd_cfg_t ();
+
+
+/* ***************** */
+/* plug-in functions */
+
+bool AOSD::init ()
+{
+ aosd_cfg_load (global_config);
+ aosd_osd_init (global_config.misc.transparency_mode);
+ aosd_trigger_start (global_config.trigger);
+ return true;
+}
+
+
+void AOSD::cleanup ()
+{
+ aosd_trigger_stop (global_config.trigger);
+ aosd_osd_shutdown ();
+ aosd_osd_cleanup ();
+ global_config = aosd_cfg_t ();
+}
diff --git a/src/aosd/aosd.h b/src/aosd/aosd.h
index 5a60597f845e..f7de153f1a3b 100644
--- a/src/aosd/aosd.h
+++ b/src/aosd/aosd.h
@@ -21,15 +21,29 @@
#ifndef _I_AOSD_H
#define _I_AOSD_H 1
-#undef PACKAGE
-#define PACKAGE "audacious-plugins"
+#include <libaudcore/plugin.h>
-#include "aosd_common.h"
-#include <glib.h>
-#include <audacious/plugin.h>
+struct PreferencesWidget;
-gboolean aosd_init (void);
-void aosd_cleanup ( void );
-void aosd_configure ( void );
+class AOSD : public GeneralPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("AOSD (On-Screen Display)"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ constexpr AOSD () : GeneralPlugin (info, false) {}
+
+ bool init ();
+ void cleanup ();
+};
#endif /* !_I_AOSD_H */
diff --git a/src/aosd/aosd_cfg.c b/src/aosd/aosd_cfg.c
deleted file mode 100644
index 0d93f35a8890..000000000000
--- a/src/aosd/aosd_cfg.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include "aosd_cfg.h"
-#include "aosd_style.h"
-#include <glib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-
-static gint
-aosd_cfg_util_str_to_color ( gchar * str , aosd_color_t * color )
-{
- /* color strings are in format "x,x,x,x", where x are numbers
- that represent respectively red, green, blue and alpha values (0-65535) */
- gchar **str_values = g_strsplit( str , "," , 4 );
- gint col_values[4] = { 0 , 0 , 0, 65535 };
- gint i = 0;
- while ( str_values[i] != NULL )
- {
- col_values[i] = (gint)strtol( str_values[i] , NULL , 10 );
- i++;
- }
- g_strfreev( str_values );
- color->red = col_values[0];
- color->green = col_values[1];
- color->blue = col_values[2];
- color->alpha = col_values[3];
- if ( i < 4 )
- return -1;
- else
- return 0;
-}
-
-
-static gint
-aosd_cfg_util_color_to_str ( aosd_color_t color , gchar ** str )
-{
- /* color strings are in format "x,x,x,x", where x are numbers
- that represent respectively red, green, blue and alpha values (0-65535) */
- *str = g_strdup_printf( "%i,%i,%i,%i" , color.red , color.green , color.blue , color.alpha );
- if ( *str != NULL )
- return 0;
- else
- return -1;
-}
-
-
-aosd_cfg_t *
-aosd_cfg_new ( void )
-{
- aosd_cfg_t *cfg = g_malloc0(sizeof(aosd_cfg_t));
- aosd_cfg_osd_t *cfg_osd = aosd_cfg_osd_new();
- cfg->set = FALSE;
- cfg->osd = cfg_osd;
- return cfg;
-}
-
-
-void
-aosd_cfg_delete ( aosd_cfg_t * cfg )
-{
- if ( cfg != NULL )
- {
- if ( cfg->osd != NULL )
- aosd_cfg_osd_delete( cfg->osd );
- g_free( cfg );
- }
- return;
-}
-
-
-aosd_cfg_osd_t *
-aosd_cfg_osd_new( void )
-{
- aosd_cfg_osd_t *cfg_osd = g_malloc0(sizeof(aosd_cfg_osd_t));
- cfg_osd->decoration.colors = g_array_sized_new( FALSE , TRUE , sizeof(aosd_color_t) ,
- aosd_deco_style_get_max_numcol() );
- cfg_osd->trigger.active = g_array_new( FALSE , TRUE , sizeof(gint) );
- return cfg_osd;
-}
-
-
-void
-aosd_cfg_osd_delete ( aosd_cfg_osd_t * cfg_osd )
-{
- if ( cfg_osd != NULL )
- {
- gint i = 0;
- /* free configuration fields */
- for ( i = 0 ; i < AOSD_TEXT_FONTS_NUM ; i++ )
- str_unref (cfg_osd->text.fonts_name[i]);
- if ( cfg_osd->decoration.colors != NULL )
- g_array_free( cfg_osd->decoration.colors , TRUE );
- if ( cfg_osd->trigger.active != NULL )
- g_array_free( cfg_osd->trigger.active , TRUE );
- }
- g_free( cfg_osd );
- return;
-}
-
-
-/* makes a copy of a aosd_cfg_osd_t object (mostly used by aosd_display) */
-aosd_cfg_osd_t *
-aosd_cfg_osd_copy ( aosd_cfg_osd_t * cfg_osd )
-{
- aosd_cfg_osd_t *cfg_osd_copy = aosd_cfg_osd_new();
- gint i = 0;
- /* copy information */
- cfg_osd_copy->position.placement = cfg_osd->position.placement;
- cfg_osd_copy->position.offset_x = cfg_osd->position.offset_x;
- cfg_osd_copy->position.offset_y = cfg_osd->position.offset_y;
- cfg_osd_copy->position.maxsize_width = cfg_osd->position.maxsize_width;
- cfg_osd_copy->position.multimon_id = cfg_osd->position.multimon_id;
- cfg_osd_copy->animation.timing_display = cfg_osd->animation.timing_display;
- cfg_osd_copy->animation.timing_fadein = cfg_osd->animation.timing_fadein;
- cfg_osd_copy->animation.timing_fadeout = cfg_osd->animation.timing_fadeout;
- for ( i = 0 ; i < AOSD_TEXT_FONTS_NUM ; i++ )
- {
- cfg_osd_copy->text.fonts_name[i] = str_ref (cfg_osd->text.fonts_name[i]);
- cfg_osd_copy->text.fonts_color[i] = cfg_osd->text.fonts_color[i];
- cfg_osd_copy->text.fonts_draw_shadow[i] = cfg_osd->text.fonts_draw_shadow[i];
- cfg_osd_copy->text.fonts_shadow_color[i] = cfg_osd->text.fonts_shadow_color[i];
- }
- cfg_osd_copy->text.utf8conv_disable = cfg_osd->text.utf8conv_disable;
- cfg_osd_copy->decoration.code = cfg_osd->decoration.code;
- for ( i = 0 ; i < cfg_osd->decoration.colors->len ; i++ )
- {
- aosd_color_t color = g_array_index( cfg_osd->decoration.colors , aosd_color_t , i );
- g_array_insert_val( cfg_osd_copy->decoration.colors , i , color );
- }
- for ( i = 0 ; i < cfg_osd->trigger.active->len ; i++ )
- {
- gint trigger_id = g_array_index( cfg_osd->trigger.active , gint , i );
- g_array_insert_val( cfg_osd_copy->trigger.active , i , trigger_id );
- }
- cfg_osd_copy->misc.transparency_mode = cfg_osd->misc.transparency_mode;
- return cfg_osd_copy;
-}
-
-
-#ifdef DEBUG
-void
-aosd_cfg_debug ( aosd_cfg_t * cfg )
-{
- gint i = 0;
- GString *string = g_string_new( "" );
- g_print("\n***** debug configuration *****\n\n");
- g_print("POSITION\n");
- g_print(" placement: %i\n", cfg->osd->position.placement);
- g_print(" offset x: %i\n", cfg->osd->position.offset_x);
- g_print(" offset y: %i\n", cfg->osd->position.offset_y);
- g_print(" max OSD width: %i\n", cfg->osd->position.maxsize_width);
- g_print(" multi-monitor id: %i\n", cfg->osd->position.multimon_id);
- g_print("\nANIMATION\n");
- g_print(" timing display: %i\n", cfg->osd->animation.timing_display);
- g_print(" timing fade in: %i\n", cfg->osd->animation.timing_fadein);
- g_print(" timing fade out: %i\n", cfg->osd->animation.timing_fadeout);
- g_print("\nTEXT\n");
- for ( i = 0 ; i < AOSD_TEXT_FONTS_NUM ; i++ )
- {
- g_print(" font %i: %s\n", i, cfg->osd->text.fonts_name[i]);
- g_print(" font color %i: %i,%i,%i (alpha %i)\n", i,
- cfg->osd->text.fonts_color[i].red, cfg->osd->text.fonts_color[i].green,
- cfg->osd->text.fonts_color[i].blue, cfg->osd->text.fonts_color[i].alpha);
- g_print(" font %i use shadow: %i\n", i, cfg->osd->text.fonts_draw_shadow[i]);
- g_print(" font %i shadow color: %i,%i,%i (alpha %i)\n", i,
- cfg->osd->text.fonts_shadow_color[i].red, cfg->osd->text.fonts_shadow_color[i].green,
- cfg->osd->text.fonts_shadow_color[i].blue, cfg->osd->text.fonts_shadow_color[i].alpha);
- }
- g_print(" disable utf8 conversion: %i\n", cfg->osd->text.utf8conv_disable);
- g_print("\nDECORATION\n");
- g_print(" code: %i\n", cfg->osd->decoration.code);
- for ( i = 0 ; i < cfg->osd->decoration.colors->len ; i++ )
- {
- aosd_color_t color = g_array_index( cfg->osd->decoration.colors , aosd_color_t , i );
- g_print(" color %i: %i,%i,%i (alpha %i)\n", i, color.red, color.green, color.blue, color.alpha);
- }
- g_print("\nTRIGGER\n");
- for ( i = 0 ; i < cfg->osd->trigger.active->len ; i++ )
- g_string_append_printf( string , "%i," , g_array_index( cfg->osd->trigger.active , gint , i ) );
- if ( string->len > 1 )
- g_string_truncate( string , string->len - 1 );
- g_print(" active: %s\n", string->str);
- g_string_free( string , TRUE );
- g_print("\nEXTRA\n");
- g_print(" set: %i\n", cfg->set);
- g_print("\n*******************************\n\n");
- return;
-}
-#endif
-
-static const gchar * const aosd_defaults[] = {
- "position_placement", "1", /* AOSD_POSITION_PLACEMENT_TOPLEFT */
- "position_offset_x", "0",
- "position_offset_y", "0",
- "position_maxsize_width", "0",
- "position_multimon_id", "-1",
- "animation_timing_display", "3000",
- "animation_timing_fadein", "300",
- "animation_timing_fadeout", "300",
- "text_fonts_name_0", "Sans 26",
- "text_fonts_color_0", "65535,65535,65535,65535",
- "text_fonts_draw_shadow_0", "TRUE",
- "text_fonts_shadow_color_0", "0,0,0,32767",
- "text_utf8conv_disable", "FALSE",
- "decoration_code", "0",
- "decoration_color_0", "0,0,65535,32767",
- "decoration_color_1", "65535,65535,65535,65535",
- "trigger_active", "0",
- "transparency_mode", "0",
- NULL};
-
-gint
-aosd_cfg_load ( aosd_cfg_t * cfg )
-{
- aud_config_set_defaults ("aosd", aosd_defaults);
-
- gint i = 0;
- gint max_numcol;
- gchar *trig_active_str;
-
- /* position */
- cfg->osd->position.placement = aud_get_int ("aosd", "position_placement");
- cfg->osd->position.offset_x = aud_get_int ("aosd", "position_offset_x");
- cfg->osd->position.offset_y = aud_get_int ("aosd", "position_offset_y");
- cfg->osd->position.maxsize_width = aud_get_int ("aosd", "position_maxsize_width");
- cfg->osd->position.multimon_id = aud_get_int ("aosd", "position_multimon_id");
-
- /* animation */
- cfg->osd->animation.timing_display = aud_get_int ("aosd", "animation_timing_display");
- cfg->osd->animation.timing_fadein = aud_get_int ("aosd", "animation_timing_fadein");
- cfg->osd->animation.timing_fadeout = aud_get_int ("aosd", "animation_timing_fadeout");
-
- /* text */
- for ( i = 0 ; i < AOSD_TEXT_FONTS_NUM ; i++ )
- {
- gchar *color_str = NULL;
- gchar key_str[32];
-
- snprintf (key_str, sizeof key_str, "text_fonts_name_%i" , i );
- cfg->osd->text.fonts_name[i] = aud_get_str ("aosd", key_str);
-
- snprintf (key_str, sizeof key_str, "text_fonts_color_%i", i);
- color_str = aud_get_str ("aosd", key_str);
- aosd_cfg_util_str_to_color( color_str , &(cfg->osd->text.fonts_color[i]) );
- str_unref (color_str);
-
- snprintf (key_str, sizeof key_str, "text_fonts_draw_shadow_%i", i);
- cfg->osd->text.fonts_draw_shadow[i] = aud_get_bool ("aosd", key_str);
-
- snprintf (key_str, sizeof key_str, "text_fonts_shadow_color_%i", i);
- color_str = aud_get_str ("aosd", key_str);
- aosd_cfg_util_str_to_color( color_str , &(cfg->osd->text.fonts_shadow_color[i]) );
- str_unref (color_str);
- }
-
- cfg->osd->text.utf8conv_disable = aud_get_bool ("aosd", "text_utf8conv_disable");
-
- /* decoration */
- cfg->osd->decoration.code = aud_get_int ("aosd", "decoration_code");
-
- /* decoration - colors */
- max_numcol = aosd_deco_style_get_max_numcol();
- for ( i = 0 ; i < max_numcol ; i++ )
- {
- gchar key_str[32];
- gchar *color_str = NULL;
- aosd_color_t color;
- snprintf (key_str, sizeof key_str, "decoration_color_%i", i);
- color_str = aud_get_str ("aosd", key_str);
- aosd_cfg_util_str_to_color( color_str , &color );
- str_unref (color_str);
- g_array_insert_val( cfg->osd->decoration.colors , i , color );
- }
-
- /* trigger */
- trig_active_str = aud_get_str ("aosd", "trigger_active");
-
- if (strcmp (trig_active_str, "x"))
- {
- gchar **trig_active_strv = g_strsplit( trig_active_str , "," , 0 );
- gint j = 0;
- while ( trig_active_strv[j] != NULL )
- {
- gint trig_active_val = strtol( trig_active_strv[j] , NULL , 10 );
- g_array_append_val( cfg->osd->trigger.active , trig_active_val );
- j++;
- }
- g_strfreev( trig_active_strv );
- }
-
- str_unref (trig_active_str);
-
- /* miscellanous */
- cfg->osd->misc.transparency_mode = aud_get_int ("aosd", "transparency_mode");
-
- /* the config object has been filled with information */
- cfg->set = TRUE;
-
- return 0;
-}
-
-
-gint
-aosd_cfg_save ( aosd_cfg_t * cfg )
-{
- gint i = 0;
- gint max_numcol;
- GString *string = g_string_new( "" );
-
- if ( cfg->set == FALSE )
- return -1;
-
- /* position */
- aud_set_int ("aosd", "position_placement", cfg->osd->position.placement);
- aud_set_int ("aosd", "position_offset_x", cfg->osd->position.offset_x);
- aud_set_int ("aosd", "position_offset_y", cfg->osd->position.offset_y);
- aud_set_int ("aosd", "position_maxsize_width", cfg->osd->position.maxsize_width);
- aud_set_int ("aosd", "position_multimon_id", cfg->osd->position.multimon_id);
-
- /* animation */
- aud_set_int ("aosd", "animation_timing_display", cfg->osd->animation.timing_display);
- aud_set_int ("aosd", "animation_timing_fadein", cfg->osd->animation.timing_fadein);
- aud_set_int ("aosd", "animation_timing_fadeout", cfg->osd->animation.timing_fadeout);
-
- /* text */
- for ( i = 0 ; i < AOSD_TEXT_FONTS_NUM ; i++ )
- {
- gchar *color_str = NULL;
- gchar key_str[32];
-
- snprintf (key_str, sizeof key_str, "text_fonts_name_%i", i);
- aud_set_str ("aosd", key_str, cfg->osd->text.fonts_name[i]);
-
- snprintf (key_str, sizeof key_str, "text_fonts_color_%i", i);
- aosd_cfg_util_color_to_str( cfg->osd->text.fonts_color[i] , &color_str );
- aud_set_str ("aosd", key_str, color_str);
- g_free( color_str );
-
- snprintf (key_str, sizeof key_str, "text_fonts_draw_shadow_%i", i);
- aud_set_bool ("aosd", key_str, cfg->osd->text.fonts_draw_shadow[i]);
-
- snprintf (key_str, sizeof key_str, "text_fonts_shadow_color_%i", i);
- aosd_cfg_util_color_to_str( cfg->osd->text.fonts_shadow_color[i] , &color_str );
- aud_set_str ("aosd", key_str, color_str);
- g_free( color_str );
- }
-
- aud_set_bool ("aosd", "text_utf8conv_disable", cfg->osd->text.utf8conv_disable);
-
- /* decoration */
- aud_set_int ("aosd" ,
- "decoration_code" , cfg->osd->decoration.code );
-
- /* decoration - colors */
- max_numcol = aosd_deco_style_get_max_numcol();
- for ( i = 0 ; i < max_numcol ; i++ )
- {
- gchar key_str[32];
- gchar *color_str = NULL;
- aosd_color_t color = g_array_index( cfg->osd->decoration.colors , aosd_color_t , i );
- snprintf (key_str, sizeof key_str, "decoration_color_%i", i);
- aosd_cfg_util_color_to_str( color , &color_str );
- aud_set_str ("aosd", key_str, color_str);
- g_free( color_str );
- }
-
- /* trigger */
- for ( i = 0 ; i < cfg->osd->trigger.active->len ; i++ )
- g_string_append_printf( string , "%i," , g_array_index( cfg->osd->trigger.active , gint , i ) );
- if ( string->len > 1 )
- g_string_truncate( string , string->len - 1 );
- else
- g_string_assign( string , "x" );
- aud_set_str ("aosd", "trigger_active", string->str);
- g_string_free( string , TRUE );
-
- /* miscellaneous */
- aud_set_int ("aosd", "transparency_mode", cfg->osd->misc.transparency_mode);
-
- return 0;
-}
diff --git a/src/aosd/aosd_cfg.cc b/src/aosd/aosd_cfg.cc
new file mode 100644
index 000000000000..c0e242b1e59d
--- /dev/null
+++ b/src/aosd/aosd_cfg.cc
@@ -0,0 +1,174 @@
+/*
+*
+* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+*/
+
+#include "aosd_cfg.h"
+#include "aosd_style.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+
+static aosd_color_t str_to_color (const char * str)
+{
+ /* color strings are in format "x,x,x,x", where x are numbers
+ that represent respectively red, green, blue and alpha values (0-65535) */
+ aosd_color_t color = {0, 0, 0, 65535};
+ sscanf (str, "%d,%d,%d,%d", & color.red, & color.green, & color.blue, & color.alpha);
+ return color;
+}
+
+static StringBuf color_to_str (const aosd_color_t & color)
+{
+ /* color strings are in format "x,x,x,x", where x are numbers
+ that represent respectively red, green, blue and alpha values (0-65535) */
+ return str_printf ("%d,%d,%d,%d", color.red, color.green, color.blue, color.alpha);
+}
+
+static const char * const aosd_defaults[] = {
+ "position_placement", "1", /* AOSD_POSITION_PLACEMENT_TOPLEFT */
+ "position_offset_x", "0",
+ "position_offset_y", "0",
+ "position_maxsize_width", "0",
+ "position_multimon_id", "-1",
+ "animation_timing_display", "3000",
+ "animation_timing_fadein", "300",
+ "animation_timing_fadeout", "300",
+ "text_fonts_name_0", "Sans 26",
+ "text_fonts_color_0", "65535,65535,65535,65535",
+ "text_fonts_draw_shadow_0", "TRUE",
+ "text_fonts_shadow_color_0", "0,0,0,32767",
+ "decoration_code", "0",
+ "decoration_color_0", "0,0,65535,32767",
+ "decoration_color_1", "65535,65535,65535,65535",
+ "trigger_enabled", "1,0,0,0",
+ "transparency_mode", "0",
+ nullptr};
+
+void aosd_cfg_load (aosd_cfg_t & cfg)
+{
+ aud_config_set_defaults ("aosd", aosd_defaults);
+
+ /* position */
+ cfg.position.placement = aud_get_int ("aosd", "position_placement");
+ cfg.position.offset_x = aud_get_int ("aosd", "position_offset_x");
+ cfg.position.offset_y = aud_get_int ("aosd", "position_offset_y");
+ cfg.position.maxsize_width = aud_get_int ("aosd", "position_maxsize_width");
+ cfg.position.multimon_id = aud_get_int ("aosd", "position_multimon_id");
+
+ /* animation */
+ cfg.animation.timing_display = aud_get_int ("aosd", "animation_timing_display");
+ cfg.animation.timing_fadein = aud_get_int ("aosd", "animation_timing_fadein");
+ cfg.animation.timing_fadeout = aud_get_int ("aosd", "animation_timing_fadeout");
+
+ /* text */
+ for (int i = 0; i < AOSD_TEXT_FONTS_NUM; i ++)
+ {
+ char key_str[32];
+
+ snprintf (key_str, sizeof key_str, "text_fonts_name_%i" , i );
+ cfg.text.fonts_name[i] = aud_get_str ("aosd", key_str);
+
+ snprintf (key_str, sizeof key_str, "text_fonts_color_%i", i);
+ cfg.text.fonts_color[i] = str_to_color (aud_get_str ("aosd", key_str));
+
+ snprintf (key_str, sizeof key_str, "text_fonts_draw_shadow_%i", i);
+ cfg.text.fonts_draw_shadow[i] = aud_get_bool ("aosd", key_str);
+
+ snprintf (key_str, sizeof key_str, "text_fonts_shadow_color_%i", i);
+ cfg.text.fonts_shadow_color[i] = str_to_color (aud_get_str ("aosd", key_str));
+ }
+
+ /* decoration */
+ cfg.decoration.code = aud_get_int ("aosd", "decoration_code");
+
+ /* decoration - colors */
+ for (int i = 0; i < AOSD_DECO_STYLE_MAX_COLORS; i ++)
+ {
+ char key_str[32];
+ snprintf (key_str, sizeof key_str, "decoration_color_%i", i);
+ cfg.decoration.colors[i] = str_to_color (aud_get_str ("aosd", key_str));
+ }
+
+ /* trigger */
+ String trig_enabled_str = aud_get_str ("aosd", "trigger_enabled");
+ str_to_int_array (trig_enabled_str, cfg.trigger.enabled,
+ aud::n_elems (cfg.trigger.enabled));
+
+ /* miscellanous */
+ cfg.misc.transparency_mode = aud_get_int ("aosd", "transparency_mode");
+}
+
+
+void aosd_cfg_save (const aosd_cfg_t & cfg)
+{
+ /* position */
+ aud_set_int ("aosd", "position_placement", cfg.position.placement);
+ aud_set_int ("aosd", "position_offset_x", cfg.position.offset_x);
+ aud_set_int ("aosd", "position_offset_y", cfg.position.offset_y);
+ aud_set_int ("aosd", "position_maxsize_width", cfg.position.maxsize_width);
+ aud_set_int ("aosd", "position_multimon_id", cfg.position.multimon_id);
+
+ /* animation */
+ aud_set_int ("aosd", "animation_timing_display", cfg.animation.timing_display);
+ aud_set_int ("aosd", "animation_timing_fadein", cfg.animation.timing_fadein);
+ aud_set_int ("aosd", "animation_timing_fadeout", cfg.animation.timing_fadeout);
+
+ /* text */
+ for (int i = 0; i < AOSD_TEXT_FONTS_NUM; i ++)
+ {
+ char key_str[32];
+
+ snprintf (key_str, sizeof key_str, "text_fonts_name_%i", i);
+ aud_set_str ("aosd", key_str, cfg.text.fonts_name[i]);
+
+ snprintf (key_str, sizeof key_str, "text_fonts_color_%i", i);
+ aud_set_str ("aosd", key_str, color_to_str (cfg.text.fonts_color[i]));
+
+ snprintf (key_str, sizeof key_str, "text_fonts_draw_shadow_%i", i);
+ aud_set_bool ("aosd", key_str, cfg.text.fonts_draw_shadow[i]);
+
+ snprintf (key_str, sizeof key_str, "text_fonts_shadow_color_%i", i);
+ aud_set_str ("aosd", key_str, color_to_str (cfg.text.fonts_shadow_color[i]));
+ }
+
+ /* decoration */
+ aud_set_int ("aosd" ,
+ "decoration_code" , cfg.decoration.code );
+
+ /* decoration - colors */
+ for (int i = 0; i < AOSD_DECO_STYLE_MAX_COLORS; i ++)
+ {
+ char key_str[32];
+ snprintf (key_str, sizeof key_str, "decoration_color_%i", i);
+ aud_set_str ("aosd", key_str, color_to_str (cfg.decoration.colors[i]));
+ }
+
+ /* trigger */
+ StringBuf trig_enabled_str = int_array_to_str (cfg.trigger.enabled,
+ aud::n_elems (cfg.trigger.enabled));
+ aud_set_str ("aosd", "trigger_enabled", trig_enabled_str);
+
+ /* miscellaneous */
+ aud_set_int ("aosd", "transparency_mode", cfg.misc.transparency_mode);
+}
diff --git a/src/aosd/aosd_cfg.h b/src/aosd/aosd_cfg.h
index 20b0c97a3360..a1c6623bd73a 100644
--- a/src/aosd/aosd_cfg.h
+++ b/src/aosd/aosd_cfg.h
@@ -21,8 +21,7 @@
#ifndef _I_AOSD_CFG_H
#define _I_AOSD_CFG_H 1
-#include "aosd_common.h"
-#include <glib.h>
+#include <libaudcore/objects.h>
/* in this release only one user font is supported */
#define AOSD_TEXT_FONTS_NUM 1
@@ -31,6 +30,16 @@
#define AOSD_MISC_TRANSPARENCY_FAKE 0
#define AOSD_MISC_TRANSPARENCY_REAL 1
+#define AOSD_DECO_STYLE_MAX_COLORS 2
+
+enum
+{
+ AOSD_DECO_STYLE_RECT,
+ AOSD_DECO_STYLE_ROUNDRECT,
+ AOSD_DECO_STYLE_CONCAVERECT,
+ AOSD_DECO_STYLE_NONE,
+ AOSD_NUM_DECO_STYLES
+};
enum
{
@@ -45,13 +54,21 @@ enum
AOSD_POSITION_PLACEMENT_BOTTOMRIGHT
};
+enum
+{
+ AOSD_TRIGGER_PB_START = 0,
+ AOSD_TRIGGER_PB_TITLECHANGE,
+ AOSD_TRIGGER_PB_PAUSEON,
+ AOSD_TRIGGER_PB_PAUSEOFF,
+ AOSD_NUM_TRIGGERS
+};
typedef struct
{
- guint16 red;
- guint16 green;
- guint16 blue;
- guint16 alpha;
+ int red;
+ int green;
+ int blue;
+ int alpha;
}
aosd_color_t;
@@ -59,8 +76,8 @@ aosd_color_t;
/* config portion containing osd decoration information */
typedef struct
{
- gint code;
- GArray *colors;
+ int code;
+ aosd_color_t colors[AOSD_DECO_STYLE_MAX_COLORS];
}
aosd_cfg_osd_decoration_t;
@@ -68,11 +85,10 @@ aosd_cfg_osd_decoration_t;
/* config portion containing osd text information */
typedef struct
{
- gchar *fonts_name[AOSD_TEXT_FONTS_NUM]; /* pooled */
+ String fonts_name[AOSD_TEXT_FONTS_NUM];
aosd_color_t fonts_color[AOSD_TEXT_FONTS_NUM];
- gboolean fonts_draw_shadow[AOSD_TEXT_FONTS_NUM];
+ bool fonts_draw_shadow[AOSD_TEXT_FONTS_NUM];
aosd_color_t fonts_shadow_color[AOSD_TEXT_FONTS_NUM];
- gboolean utf8conv_disable;
}
aosd_cfg_osd_text_t;
@@ -80,9 +96,9 @@ aosd_cfg_osd_text_t;
/* config portion containing osd animation information */
typedef struct
{
- gint timing_display;
- gint timing_fadein;
- gint timing_fadeout;
+ int timing_display;
+ int timing_fadein;
+ int timing_fadeout;
}
aosd_cfg_osd_animation_t;
@@ -90,11 +106,11 @@ aosd_cfg_osd_animation_t;
/* config portion containing osd position information */
typedef struct
{
- gint placement;
- gint offset_x;
- gint offset_y;
- gint maxsize_width;
- gint multimon_id;
+ int placement;
+ int offset_x;
+ int offset_y;
+ int maxsize_width;
+ int multimon_id;
}
aosd_cfg_osd_position_t;
@@ -102,7 +118,7 @@ aosd_cfg_osd_position_t;
/* config portion containing osd trigger information */
typedef struct
{
- GArray *active;
+ int enabled[AOSD_NUM_TRIGGERS];
}
aosd_cfg_osd_trigger_t;
@@ -110,7 +126,7 @@ aosd_cfg_osd_trigger_t;
/* config portion containing osd miscellaneous information */
typedef struct
{
- gint transparency_mode;
+ int transparency_mode;
}
aosd_cfg_osd_misc_t;
@@ -125,26 +141,13 @@ typedef struct
aosd_cfg_osd_trigger_t trigger;
aosd_cfg_osd_misc_t misc;
}
-aosd_cfg_osd_t;
-
-
-/* config portion containing all config information */
-typedef struct
-{
- gboolean set;
-
- aosd_cfg_osd_t * osd;
-}
aosd_cfg_t;
/* API */
-aosd_cfg_t * aosd_cfg_new ( void );
-void aosd_cfg_delete ( aosd_cfg_t * cfg );
-aosd_cfg_osd_t * aosd_cfg_osd_new( void );
-void aosd_cfg_osd_delete ( aosd_cfg_osd_t * cfg_osd );
-aosd_cfg_osd_t * aosd_cfg_osd_copy ( aosd_cfg_osd_t * cfg_osd );
-gint aosd_cfg_load ( aosd_cfg_t * cfg );
-gint aosd_cfg_save ( aosd_cfg_t * cfg );
+void aosd_cfg_load (aosd_cfg_t & cfg);
+void aosd_cfg_save (const aosd_cfg_t & cfg);
+
+extern aosd_cfg_t global_config;
#endif /* !_I_AOSD_CFG_H */
diff --git a/src/aosd/aosd_common.h b/src/aosd/aosd_common.h
deleted file mode 100644
index 4147068c1f67..000000000000
--- a/src/aosd/aosd_common.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#ifndef _I_AOSD_COMMON_H
-#define _I_AOSD_COMMON_H 1
-
-#ifdef DEBUG
-#include <stdio.h>
-#define DEBUGMSG(...) { fprintf(stderr, "statusicon(%s:%s:%d): ", __FILE__, __FUNCTION__, (int) __LINE__); fprintf(stderr, __VA_ARGS__); }
-#else
-#define DEBUGMSG(...)
-#endif /* DEBUG */
-
-#define AOSD_VERSION_PLUGIN "0.1beta5"
-
-#endif /* !_I_AOSD_COMMON_H */
diff --git a/src/aosd/aosd_osd.c b/src/aosd/aosd_osd.c
deleted file mode 100644
index 173bf658b59d..000000000000
--- a/src/aosd/aosd_osd.c
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include "aosd_osd.h"
-#include "aosd_style.h"
-#include "aosd_style_private.h"
-#include "aosd_cfg.h"
-#include <glib.h>
-#include <X11/Xlib.h>
-#include <cairo/cairo.h>
-#include <pango/pangocairo.h>
-#include <gdk/gdk.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include "ghosd.h"
-
-
-#define AOSD_STATUS_HIDDEN 0
-#define AOSD_STATUS_FADEIN 1
-#define AOSD_STATUS_SHOW 2
-#define AOSD_STATUS_FADEOUT 3
-#define AOSD_STATUS_DESTROY 4
-/* updating OSD every 50 msec */
-#define AOSD_TIMING 50
-
-
-typedef struct
-{
- cairo_surface_t * surface;
- gfloat alpha;
- gpointer user_data;
- gint width;
- gint height;
- gint deco_code;
-}
-GhosdFadeData;
-
-
-typedef struct
-{
- gchar * markup_message;
- gboolean cfg_is_copied;
- gfloat dalpha_in, dalpha_out, ddisplay_stay;
-
- PangoContext *pango_context;
- PangoLayout *pango_layout;
-
- aosd_cfg_osd_t * cfg_osd;
-
- GhosdFadeData fade_data;
-}
-GhosdData;
-
-
-static gint osd_source_id = 0;
-static gint osd_status = AOSD_STATUS_HIDDEN;
-static Ghosd *osd;
-static GhosdData *osd_data;
-
-
-static void
-aosd_osd_data_alloc ( gchar * markup_string , aosd_cfg_osd_t * cfg_osd , gboolean copy_cfg )
-{
- osd_data = g_malloc0(sizeof(GhosdData));
- osd_data->markup_message = g_strdup( markup_string );
- if ( copy_cfg == TRUE )
- {
- osd_data->cfg_osd = aosd_cfg_osd_copy( cfg_osd );
- osd_data->cfg_is_copied = TRUE;
- }
- else
- {
- osd_data->cfg_osd = cfg_osd;
- osd_data->cfg_is_copied = FALSE;
- }
- return;
-}
-
-
-static void
-aosd_osd_data_free ( void )
-{
- if ( osd_data->fade_data.surface != NULL )
- {
- cairo_surface_destroy( osd_data->fade_data.surface );
- osd_data->fade_data.surface = NULL;
- }
-
- if ( osd_data->markup_message != NULL )
- {
- g_free( osd_data->markup_message );
- osd_data->markup_message = NULL;
- }
-
- if ( osd_data->cfg_is_copied == TRUE )
- {
- aosd_cfg_osd_delete( osd_data->cfg_osd );
- osd_data->cfg_osd = NULL;
- }
-
- if ( osd_data->pango_layout != NULL )
- {
- g_object_unref( osd_data->pango_layout );
- osd_data->pango_layout = NULL;
- }
-
- if ( osd_data->pango_context != NULL )
- {
- g_object_unref( osd_data->pango_context );
- osd_data->pango_context = NULL;
- }
-
- g_free( osd_data );
-}
-
-
-static void
-aosd_osd_hide ( void )
-{
- if ( osd != NULL )
- {
- ghosd_hide( osd );
- ghosd_main_iterations( osd );
- }
- return;
-}
-
-
-static void
-aosd_fade_func ( Ghosd * gosd , cairo_t * cr , void * user_data )
-{
- GhosdFadeData *fade_data = user_data;
-
- if ( fade_data->surface == NULL )
- {
- cairo_t *rendered_cr;
- fade_data->surface = cairo_surface_create_similar( cairo_get_target( cr ) ,
- CAIRO_CONTENT_COLOR_ALPHA , fade_data->width , fade_data->height );
- rendered_cr = cairo_create( fade_data->surface );
- aosd_deco_style_render( fade_data->deco_code , gosd , rendered_cr , fade_data->user_data );
- cairo_destroy( rendered_cr );
- }
-
- cairo_set_source_surface( cr , fade_data->surface , 0 , 0 );
- cairo_paint_with_alpha( cr , fade_data->alpha );
-}
-
-
-static void
-aosd_button_func ( Ghosd * gosd , GhosdEventButton * ev , void * user_data )
-{
- if ( ev->button == 1 )
- {
- osd_status = AOSD_STATUS_DESTROY; /* move to status destroy */
- }
- return;
-}
-
-
-static void
-aosd_osd_create ( void )
-{
- gint max_width, layout_width, layout_height;
- PangoRectangle ink, log;
- GdkScreen *screen = gdk_screen_get_default();
- gint pos_x = 0, pos_y = 0;
- gint pad_left = 0 , pad_right = 0 , pad_top = 0 , pad_bottom = 0;
- gint screen_width, screen_height;
- aosd_deco_style_data_t style_data;
-
- /* calculate screen_width and screen_height */
- if ( osd_data->cfg_osd->position.multimon_id > -1 )
- {
- /* adjust coordinates and size according to selected monitor */
- GdkRectangle rect;
- gdk_screen_get_monitor_geometry( screen , osd_data->cfg_osd->position.multimon_id , &rect );
- pos_x = rect.x;
- pos_y = rect.y;
- screen_width = rect.width;
- screen_height = rect.height;
- }
- else
- {
- /* use total space available, even when composed by multiple monitor */
- screen_width = gdk_screen_get_width( screen );
- screen_height = gdk_screen_get_height( screen );
- pos_x = 0;
- pos_y = 0;
- }
-
- /* pick padding from selected decoration style */
- aosd_deco_style_get_padding( osd_data->cfg_osd->decoration.code ,
- &pad_top , &pad_bottom , &pad_left , &pad_right );
-
- if ( osd_data->cfg_osd->position.maxsize_width > 0 )
- {
- gint max_width_default = screen_width - pad_left - pad_right - abs(osd_data->cfg_osd->position.offset_x);
- max_width = osd_data->cfg_osd->position.maxsize_width - pad_left - pad_right;
- /* ignore user-defined max_width if it is too small or too large */
- if (( max_width < 1 ) || ( max_width > max_width_default ))
- max_width = max_width_default;
- }
- else
- {
- max_width = screen_width - pad_left - pad_right - abs(osd_data->cfg_osd->position.offset_x);
- }
-
- osd_data->pango_context = pango_font_map_create_context
- (pango_cairo_font_map_get_default ());
- osd_data->pango_layout = pango_layout_new(osd_data->pango_context);
- pango_layout_set_markup( osd_data->pango_layout, osd_data->markup_message , -1 );
- pango_layout_set_ellipsize( osd_data->pango_layout , PANGO_ELLIPSIZE_NONE );
- pango_layout_set_justify( osd_data->pango_layout , FALSE );
- pango_layout_set_width( osd_data->pango_layout , PANGO_SCALE * max_width );
- pango_layout_get_pixel_extents( osd_data->pango_layout , &ink , &log );
- layout_width = ink.width;
- layout_height = log.height;
-
- /* osd position */
- switch ( osd_data->cfg_osd->position.placement )
- {
- case AOSD_POSITION_PLACEMENT_TOP:
- pos_x += (screen_width - (layout_width + pad_left + pad_right)) / 2;
- pos_y += 0;
- break;
- case AOSD_POSITION_PLACEMENT_TOPRIGHT:
- pos_x += screen_width - (layout_width + pad_left + pad_right);
- pos_y += 0;
- break;
- case AOSD_POSITION_PLACEMENT_MIDDLELEFT:
- pos_x += 0;
- pos_y += (screen_height - (layout_height + pad_top + pad_bottom)) / 2;
- break;
- case AOSD_POSITION_PLACEMENT_MIDDLE:
- pos_x += (screen_width - (layout_width + pad_left + pad_right)) / 2;
- pos_y += (screen_height - (layout_height + pad_top + pad_bottom)) / 2;
- break;
- case AOSD_POSITION_PLACEMENT_MIDDLERIGHT:
- pos_x += screen_width - (layout_width + pad_left + pad_right);
- pos_y += (screen_height - (layout_height + pad_top + pad_bottom)) / 2;
- break;
- case AOSD_POSITION_PLACEMENT_BOTTOMLEFT:
- pos_x += 0;
- pos_y += screen_height - (layout_height + pad_top + pad_bottom);
- break;
- case AOSD_POSITION_PLACEMENT_BOTTOM:
- pos_x += (screen_width - (layout_width + pad_left + pad_right)) / 2;
- pos_y += screen_height - (layout_height + pad_top + pad_bottom);
- break;
- case AOSD_POSITION_PLACEMENT_BOTTOMRIGHT:
- pos_x += screen_width - (layout_width + pad_left + pad_right);
- pos_y += screen_height - (layout_height + pad_top + pad_bottom);
- break;
- case AOSD_POSITION_PLACEMENT_TOPLEFT:
- default:
- pos_x += 0;
- pos_y += 0;
- break;
- }
-
- /* add offset to position */
- pos_x += osd_data->cfg_osd->position.offset_x;
- pos_y += osd_data->cfg_osd->position.offset_y;
-
- ghosd_set_position( osd , pos_x , pos_y ,
- layout_width + pad_left + pad_right ,
- layout_height + pad_top + pad_bottom );
-
- ghosd_set_event_button_cb( osd , aosd_button_func , NULL );
-
- style_data.layout = osd_data->pango_layout;
- style_data.text = &(osd_data->cfg_osd->text);
- style_data.decoration = &(osd_data->cfg_osd->decoration);
- osd_data->fade_data.surface = NULL;
- osd_data->fade_data.user_data = &style_data;
- osd_data->fade_data.width = layout_width + pad_left + pad_right;
- osd_data->fade_data.height = layout_height + pad_top + pad_bottom;
- osd_data->fade_data.alpha = 0;
- osd_data->fade_data.deco_code = osd_data->cfg_osd->decoration.code;
- osd_data->dalpha_in = 1.0 / ( osd_data->cfg_osd->animation.timing_fadein / (gfloat)AOSD_TIMING );
- osd_data->dalpha_out = 1.0 / ( osd_data->cfg_osd->animation.timing_fadeout / (gfloat)AOSD_TIMING );
- osd_data->ddisplay_stay = 1.0 / ( osd_data->cfg_osd->animation.timing_display / (gfloat)AOSD_TIMING );
- ghosd_set_render( osd , (GhosdRenderFunc)aosd_fade_func , &(osd_data->fade_data) , NULL );
-
- /* show the osd (with alpha 0, invisible) */
- ghosd_show( osd );
- return;
-}
-
-
-static gboolean
-aosd_timer_func ( gpointer none )
-{
- static gfloat display_time = 0;
-
- switch ( osd_status )
- {
- case AOSD_STATUS_FADEIN:
- {
- /* fade in */
- osd_data->fade_data.alpha += osd_data->dalpha_in;
- if ( osd_data->fade_data.alpha < 1.0 )
- {
- ghosd_render( osd );
- ghosd_main_iterations( osd );
- }
- else
- {
- osd_data->fade_data.alpha = 1.0;
- display_time = 0;
- osd_status = AOSD_STATUS_SHOW; /* move to next phase */
- ghosd_render( osd );
- ghosd_main_iterations( osd );
- }
- return TRUE;
- }
-
- case AOSD_STATUS_SHOW:
- {
- display_time += osd_data->ddisplay_stay;
- if ( display_time >= 1.0 )
- {
- osd_status = AOSD_STATUS_FADEOUT; /* move to next phase */
- ghosd_main_iterations( osd );
- }
- else
- {
- ghosd_main_iterations( osd );
- }
- return TRUE;
- }
-
- case AOSD_STATUS_FADEOUT:
- {
- /* fade out */
- osd_data->fade_data.alpha -= osd_data->dalpha_out;
- if ( osd_data->fade_data.alpha > 0.0 )
- {
- ghosd_render( osd );
- ghosd_main_iterations( osd );
- }
- else
- {
- osd_data->fade_data.alpha = 0.0;
- osd_status = AOSD_STATUS_DESTROY; /* move to next phase */
- ghosd_render( osd );
- ghosd_main_iterations( osd );
- }
- return TRUE;
- }
-
- case AOSD_STATUS_DESTROY:
- {
- aosd_osd_hide();
- aosd_osd_data_free();
-
- osd_status = AOSD_STATUS_HIDDEN; /* reset status */
- osd_source_id = 0;
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-
-gint
-aosd_osd_display ( gchar * markup_string , aosd_cfg_osd_t * cfg_osd , gboolean copy_cfg )
-{
- if ( osd != NULL )
- {
- if ( osd_status == AOSD_STATUS_HIDDEN )
- {
- aosd_osd_data_alloc( markup_string , cfg_osd , copy_cfg );
- aosd_osd_create();
- osd_status = AOSD_STATUS_FADEIN;
- osd_source_id = g_timeout_add_full( G_PRIORITY_DEFAULT_IDLE , AOSD_TIMING ,
- aosd_timer_func , NULL , NULL );
- }
- else
- {
- g_source_remove( osd_source_id ); /* remove timer */
- osd_source_id = 0;
- aosd_osd_hide();
- aosd_osd_data_free();
- osd_status = AOSD_STATUS_HIDDEN;
- /* now display new OSD */
- aosd_osd_data_alloc( markup_string , cfg_osd , copy_cfg );
- aosd_osd_create();
- osd_status = AOSD_STATUS_FADEIN;
- osd_source_id = g_timeout_add_full( G_PRIORITY_DEFAULT_IDLE , AOSD_TIMING ,
- aosd_timer_func , NULL , NULL );
- }
- return 0;
- }
- else
- {
- g_warning( "OSD display requested, but no osd object is loaded!\n" );
- }
- return 1;
-}
-
-
-void
-aosd_osd_shutdown ( void )
-{
- if ( osd != NULL )
- {
- if ( osd_status != AOSD_STATUS_HIDDEN ) /* osd is being displayed */
- {
- g_source_remove( osd_source_id ); /* remove timer */
- osd_source_id = 0;
- aosd_osd_hide();
- aosd_osd_data_free();
- osd_status = AOSD_STATUS_HIDDEN;
- }
- }
- else
- {
- g_warning( "OSD shutdown requested, but no osd object is loaded!\n" );
- }
- return;
-}
-
-
-void
-aosd_osd_init ( gint transparency_mode )
-{
- if ( osd == NULL )
- {
- /* create Ghosd object */
- if ( transparency_mode == AOSD_MISC_TRANSPARENCY_FAKE )
- osd = ghosd_new();
- else
-#ifdef HAVE_XCOMPOSITE
- {
- /* check if the composite module is actually loaded */
- if ( aosd_osd_check_composite_ext() )
- osd = ghosd_new_with_argbvisual(); /* ok */
- else
- {
- g_warning( "X Composite module not loaded; falling back to fake transparency.\n");
- osd = ghosd_new(); /* fall back to fake transparency */
- }
- }
-#else
- osd = ghosd_new();
-#endif
-
- if ( osd == NULL )
- g_warning( "Unable to load osd object; OSD will not work properly!\n" );
- }
- return;
-}
-
-
-void
-aosd_osd_cleanup ( void )
-{
- if ( osd != NULL )
- {
- /* destroy Ghosd object */
- ghosd_destroy( osd );
- osd = NULL;
- }
- return;
-}
-
-#ifdef HAVE_XCOMPOSITE
-int
-aosd_osd_check_composite_ext ( void )
-{
- return ghosd_check_composite_ext();
-}
-
-int
-aosd_osd_check_composite_mgr ( void )
-{
- /* ghosd_check_composite_mgr() only checks for composite managers that
- adhere to the Extended Window Manager hint specification ver.1.4 from
- freedesktop ( where composite manager are identified with the hint
- _NET_WM_CM_Sn ); unfortunately, non-standard comp.managers and older
- ones (xcompmgr) do not use this hint; so let's also check if xcompmgr
- is running before reporting a likely absence of running comp.managers */
- int have_comp_mgr = ghosd_check_composite_mgr();
-
- if ( have_comp_mgr != 0 )
- {
- DEBUGMSG("running composite manager found\n");
- return have_comp_mgr;
- }
- else
- {
- /* check if xcompmgr is running; assumes there's a working 'ps'
- utility in the system; not the most elegant of the checking
- systems, but this is more than enough for its purpose */
- gchar *soutput = NULL, *serror = NULL;
- gint exit_status;
-
- if ( g_spawn_command_line_sync( "ps -eo comm" ,
- &soutput , &serror , &exit_status , NULL ) == TRUE )
- {
- if (( soutput != NULL ) && ( strstr( soutput , "\nxcompmgr\n" ) != NULL ))
- {
- DEBUGMSG("running xcompmgr found\n");
- have_comp_mgr = 1;
- }
- else
- {
- DEBUGMSG("running xcompmgr not found\n");
- have_comp_mgr = 0;
- }
- }
- else
- {
- g_warning("command 'ps -eo comm' failed, unable to check if xcompgr is running\n");
- have_comp_mgr = 0;
- }
-
- g_free( soutput );
- g_free( serror );
- return have_comp_mgr;
- }
-}
-#endif
diff --git a/src/aosd/aosd_osd.cc b/src/aosd/aosd_osd.cc
new file mode 100644
index 000000000000..88eea0695d42
--- /dev/null
+++ b/src/aosd/aosd_osd.cc
@@ -0,0 +1,509 @@
+/*
+*
+* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+*/
+
+#include "aosd_osd.h"
+#include "aosd_style.h"
+#include "aosd_style_private.h"
+#include "aosd_cfg.h"
+
+#include <X11/Xlib.h>
+#include <cairo/cairo.h>
+#include <pango/pangocairo.h>
+#include <gdk/gdk.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <libaudcore/runtime.h>
+
+#include "ghosd.h"
+
+
+#define AOSD_STATUS_HIDDEN 0
+#define AOSD_STATUS_FADEIN 1
+#define AOSD_STATUS_SHOW 2
+#define AOSD_STATUS_FADEOUT 3
+#define AOSD_STATUS_DESTROY 4
+/* updating OSD every 50 msec */
+#define AOSD_TIMING 50
+
+
+struct GhosdFadeData
+{
+ cairo_surface_t * surface = nullptr;
+ float alpha = 0.0;
+ void * user_data = nullptr;
+ int width = 0;
+ int height = 0;
+ int deco_code = 0;
+
+ ~GhosdFadeData ()
+ {
+ if (surface)
+ cairo_surface_destroy (surface);
+ }
+};
+
+
+struct GhosdData
+{
+ String markup_message;
+ bool cfg_is_copied = false;
+ float dalpha_in = 0.0, dalpha_out = 0.0, ddisplay_stay = 0.0;
+
+ PangoContext *pango_context = nullptr;
+ PangoLayout *pango_layout = nullptr;
+
+ aosd_cfg_t *cfg_osd = nullptr;
+
+ GhosdFadeData fade_data;
+
+ GhosdData (const char * markup_string, aosd_cfg_t * cfg_osd, bool copy_cfg) :
+ markup_message (markup_string),
+ cfg_is_copied (copy_cfg),
+ cfg_osd (copy_cfg ? new aosd_cfg_t (* cfg_osd) : cfg_osd) {}
+
+ ~GhosdData ()
+ {
+ if (pango_layout)
+ g_object_unref (pango_layout);
+ if (pango_context)
+ g_object_unref (pango_context);
+ if (cfg_is_copied)
+ delete cfg_osd;
+ }
+};
+
+
+static int osd_source_id = 0;
+static int osd_status = AOSD_STATUS_HIDDEN;
+static Ghosd *osd;
+static SmartPtr<GhosdData> osd_data;
+
+
+static void
+aosd_osd_hide ( void )
+{
+ if ( osd != nullptr )
+ {
+ ghosd_hide( osd );
+ ghosd_main_iterations( osd );
+ }
+ return;
+}
+
+
+static void
+aosd_fade_func ( Ghosd * gosd , cairo_t * cr , void * user_data )
+{
+ GhosdFadeData *fade_data = (GhosdFadeData *) user_data;
+
+ if ( fade_data->surface == nullptr )
+ {
+ cairo_t *rendered_cr;
+ fade_data->surface = cairo_surface_create_similar( cairo_get_target( cr ) ,
+ CAIRO_CONTENT_COLOR_ALPHA , fade_data->width , fade_data->height );
+ rendered_cr = cairo_create( fade_data->surface );
+ aosd_deco_style_render( fade_data->deco_code , gosd , rendered_cr , fade_data->user_data );
+ cairo_destroy( rendered_cr );
+ }
+
+ cairo_set_source_surface( cr , fade_data->surface , 0 , 0 );
+ cairo_paint_with_alpha( cr , fade_data->alpha );
+}
+
+
+static void
+aosd_button_func ( Ghosd * gosd , GhosdEventButton * ev , void * user_data )
+{
+ if ( ev->button == 1 )
+ {
+ osd_status = AOSD_STATUS_DESTROY; /* move to status destroy */
+ }
+ return;
+}
+
+
+static void
+aosd_osd_create ( void )
+{
+ int max_width, layout_width, layout_height;
+ PangoRectangle ink, log;
+ GdkScreen *screen = gdk_screen_get_default();
+ int pos_x = 0, pos_y = 0;
+ int pad_left = 0 , pad_right = 0 , pad_top = 0 , pad_bottom = 0;
+ int screen_width, screen_height;
+ aosd_deco_style_data_t style_data;
+
+ /* calculate screen_width and screen_height */
+ if ( osd_data->cfg_osd->position.multimon_id > -1 )
+ {
+ /* adjust coordinates and size according to selected monitor */
+ GdkRectangle rect;
+ gdk_screen_get_monitor_geometry( screen , osd_data->cfg_osd->position.multimon_id , &rect );
+ pos_x = rect.x;
+ pos_y = rect.y;
+ screen_width = rect.width;
+ screen_height = rect.height;
+ }
+ else
+ {
+ /* use total space available, even when composed by multiple monitor */
+ screen_width = gdk_screen_get_width( screen );
+ screen_height = gdk_screen_get_height( screen );
+ pos_x = 0;
+ pos_y = 0;
+ }
+
+ /* pick padding from selected decoration style */
+ aosd_deco_style_get_padding( osd_data->cfg_osd->decoration.code ,
+ &pad_top , &pad_bottom , &pad_left , &pad_right );
+
+ if ( osd_data->cfg_osd->position.maxsize_width > 0 )
+ {
+ int max_width_default = screen_width - pad_left - pad_right - abs(osd_data->cfg_osd->position.offset_x);
+ max_width = osd_data->cfg_osd->position.maxsize_width - pad_left - pad_right;
+ /* ignore user-defined max_width if it is too small or too large */
+ if (( max_width < 1 ) || ( max_width > max_width_default ))
+ max_width = max_width_default;
+ }
+ else
+ {
+ max_width = screen_width - pad_left - pad_right - abs(osd_data->cfg_osd->position.offset_x);
+ }
+
+ osd_data->pango_context = pango_font_map_create_context
+ (pango_cairo_font_map_get_default ());
+ osd_data->pango_layout = pango_layout_new(osd_data->pango_context);
+ pango_layout_set_markup( osd_data->pango_layout, osd_data->markup_message , -1 );
+ pango_layout_set_ellipsize( osd_data->pango_layout , PANGO_ELLIPSIZE_NONE );
+ pango_layout_set_justify( osd_data->pango_layout , FALSE );
+ pango_layout_set_width( osd_data->pango_layout , PANGO_SCALE * max_width );
+ pango_layout_get_pixel_extents( osd_data->pango_layout , &ink , &log );
+ layout_width = ink.width;
+ layout_height = log.height;
+
+ /* osd position */
+ switch ( osd_data->cfg_osd->position.placement )
+ {
+ case AOSD_POSITION_PLACEMENT_TOP:
+ pos_x += (screen_width - (layout_width + pad_left + pad_right)) / 2;
+ pos_y += 0;
+ break;
+ case AOSD_POSITION_PLACEMENT_TOPRIGHT:
+ pos_x += screen_width - (layout_width + pad_left + pad_right);
+ pos_y += 0;
+ break;
+ case AOSD_POSITION_PLACEMENT_MIDDLELEFT:
+ pos_x += 0;
+ pos_y += (screen_height - (layout_height + pad_top + pad_bottom)) / 2;
+ break;
+ case AOSD_POSITION_PLACEMENT_MIDDLE:
+ pos_x += (screen_width - (layout_width + pad_left + pad_right)) / 2;
+ pos_y += (screen_height - (layout_height + pad_top + pad_bottom)) / 2;
+ break;
+ case AOSD_POSITION_PLACEMENT_MIDDLERIGHT:
+ pos_x += screen_width - (layout_width + pad_left + pad_right);
+ pos_y += (screen_height - (layout_height + pad_top + pad_bottom)) / 2;
+ break;
+ case AOSD_POSITION_PLACEMENT_BOTTOMLEFT:
+ pos_x += 0;
+ pos_y += screen_height - (layout_height + pad_top + pad_bottom);
+ break;
+ case AOSD_POSITION_PLACEMENT_BOTTOM:
+ pos_x += (screen_width - (layout_width + pad_left + pad_right)) / 2;
+ pos_y += screen_height - (layout_height + pad_top + pad_bottom);
+ break;
+ case AOSD_POSITION_PLACEMENT_BOTTOMRIGHT:
+ pos_x += screen_width - (layout_width + pad_left + pad_right);
+ pos_y += screen_height - (layout_height + pad_top + pad_bottom);
+ break;
+ case AOSD_POSITION_PLACEMENT_TOPLEFT:
+ default:
+ pos_x += 0;
+ pos_y += 0;
+ break;
+ }
+
+ /* add offset to position */
+ pos_x += osd_data->cfg_osd->position.offset_x;
+ pos_y += osd_data->cfg_osd->position.offset_y;
+
+ ghosd_set_position( osd , pos_x , pos_y ,
+ layout_width + pad_left + pad_right ,
+ layout_height + pad_top + pad_bottom );
+
+ ghosd_set_event_button_cb( osd , aosd_button_func , nullptr );
+
+ style_data.layout = osd_data->pango_layout;
+ style_data.text = &(osd_data->cfg_osd->text);
+ style_data.decoration = &(osd_data->cfg_osd->decoration);
+ osd_data->fade_data.surface = nullptr;
+ osd_data->fade_data.user_data = &style_data;
+ osd_data->fade_data.width = layout_width + pad_left + pad_right;
+ osd_data->fade_data.height = layout_height + pad_top + pad_bottom;
+ osd_data->fade_data.alpha = 0;
+ osd_data->fade_data.deco_code = osd_data->cfg_osd->decoration.code;
+ osd_data->dalpha_in = 1.0 / ( osd_data->cfg_osd->animation.timing_fadein / (float)AOSD_TIMING );
+ osd_data->dalpha_out = 1.0 / ( osd_data->cfg_osd->animation.timing_fadeout / (float)AOSD_TIMING );
+ osd_data->ddisplay_stay = 1.0 / ( osd_data->cfg_osd->animation.timing_display / (float)AOSD_TIMING );
+ ghosd_set_render( osd , (GhosdRenderFunc)aosd_fade_func , &(osd_data->fade_data) , nullptr );
+
+ /* show the osd (with alpha 0, invisible) */
+ ghosd_show( osd );
+ return;
+}
+
+
+static gboolean
+aosd_timer_func ( void * none )
+{
+ static float display_time = 0;
+
+ switch ( osd_status )
+ {
+ case AOSD_STATUS_FADEIN:
+ {
+ /* fade in */
+ osd_data->fade_data.alpha += osd_data->dalpha_in;
+ if ( osd_data->fade_data.alpha < 1.0 )
+ {
+ ghosd_render( osd );
+ ghosd_main_iterations( osd );
+ }
+ else
+ {
+ osd_data->fade_data.alpha = 1.0;
+ display_time = 0;
+ osd_status = AOSD_STATUS_SHOW; /* move to next phase */
+ ghosd_render( osd );
+ ghosd_main_iterations( osd );
+ }
+ return TRUE;
+ }
+
+ case AOSD_STATUS_SHOW:
+ {
+ display_time += osd_data->ddisplay_stay;
+ if ( display_time >= 1.0 )
+ {
+ osd_status = AOSD_STATUS_FADEOUT; /* move to next phase */
+ ghosd_main_iterations( osd );
+ }
+ else
+ {
+ ghosd_main_iterations( osd );
+ }
+ return TRUE;
+ }
+
+ case AOSD_STATUS_FADEOUT:
+ {
+ /* fade out */
+ osd_data->fade_data.alpha -= osd_data->dalpha_out;
+ if ( osd_data->fade_data.alpha > 0.0 )
+ {
+ ghosd_render( osd );
+ ghosd_main_iterations( osd );
+ }
+ else
+ {
+ osd_data->fade_data.alpha = 0.0;
+ osd_status = AOSD_STATUS_DESTROY; /* move to next phase */
+ ghosd_render( osd );
+ ghosd_main_iterations( osd );
+ }
+ return TRUE;
+ }
+
+ case AOSD_STATUS_DESTROY:
+ {
+ aosd_osd_hide();
+ osd_data.clear();
+
+ osd_status = AOSD_STATUS_HIDDEN; /* reset status */
+ osd_source_id = 0;
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+int
+aosd_osd_display ( char * markup_string , aosd_cfg_t * cfg_osd , bool copy_cfg )
+{
+ if ( osd != nullptr )
+ {
+ if ( osd_status == AOSD_STATUS_HIDDEN )
+ {
+ osd_data.capture( new GhosdData( markup_string , cfg_osd , copy_cfg ) );
+ aosd_osd_create();
+ osd_status = AOSD_STATUS_FADEIN;
+ osd_source_id = g_timeout_add_full( G_PRIORITY_DEFAULT_IDLE , AOSD_TIMING ,
+ aosd_timer_func , nullptr , nullptr );
+ }
+ else
+ {
+ g_source_remove( osd_source_id ); /* remove timer */
+ osd_source_id = 0;
+ aosd_osd_hide();
+ osd_data.clear();
+ osd_status = AOSD_STATUS_HIDDEN;
+ /* now display new OSD */
+ osd_data.capture( new GhosdData( markup_string , cfg_osd , copy_cfg ) );
+ aosd_osd_create();
+ osd_status = AOSD_STATUS_FADEIN;
+ osd_source_id = g_timeout_add_full( G_PRIORITY_DEFAULT_IDLE , AOSD_TIMING ,
+ aosd_timer_func , nullptr , nullptr );
+ }
+ return 0;
+ }
+ else
+ {
+ g_warning( "OSD display requested, but no osd object is loaded!\n" );
+ }
+ return 1;
+}
+
+
+void
+aosd_osd_shutdown ( void )
+{
+ if ( osd != nullptr )
+ {
+ if ( osd_status != AOSD_STATUS_HIDDEN ) /* osd is being displayed */
+ {
+ g_source_remove( osd_source_id ); /* remove timer */
+ osd_source_id = 0;
+ aosd_osd_hide();
+ osd_data.clear();
+ osd_status = AOSD_STATUS_HIDDEN;
+ }
+ }
+ else
+ {
+ g_warning( "OSD shutdown requested, but no osd object is loaded!\n" );
+ }
+ return;
+}
+
+
+void
+aosd_osd_init ( int transparency_mode )
+{
+ if ( osd == nullptr )
+ {
+ /* create Ghosd object */
+ if ( transparency_mode == AOSD_MISC_TRANSPARENCY_FAKE )
+ osd = ghosd_new();
+ else
+#ifdef HAVE_XCOMPOSITE
+ {
+ /* check if the composite module is actually loaded */
+ if ( aosd_osd_check_composite_ext() )
+ osd = ghosd_new_with_argbvisual(); /* ok */
+ else
+ {
+ g_warning( "X Composite module not loaded; falling back to fake transparency.\n");
+ osd = ghosd_new(); /* fall back to fake transparency */
+ }
+ }
+#else
+ osd = ghosd_new();
+#endif
+
+ if ( osd == nullptr )
+ g_warning( "Unable to load osd object; OSD will not work properly!\n" );
+ }
+ return;
+}
+
+
+void
+aosd_osd_cleanup ( void )
+{
+ if ( osd != nullptr )
+ {
+ /* destroy Ghosd object */
+ ghosd_destroy( osd );
+ osd = nullptr;
+ }
+ return;
+}
+
+#ifdef HAVE_XCOMPOSITE
+int
+aosd_osd_check_composite_ext ( void )
+{
+ return ghosd_check_composite_ext();
+}
+
+int
+aosd_osd_check_composite_mgr ( void )
+{
+ /* ghosd_check_composite_mgr() only checks for composite managers that
+ adhere to the Extended Window Manager hint specification ver.1.4 from
+ freedesktop ( where composite manager are identified with the hint
+ _NET_WM_CM_Sn ); unfortunately, non-standard comp.managers and older
+ ones (xcompmgr) do not use this hint; so let's also check if xcompmgr
+ is running before reporting a likely absence of running comp.managers */
+ int have_comp_mgr = ghosd_check_composite_mgr();
+
+ if ( have_comp_mgr != 0 )
+ {
+ AUDDBG("running composite manager found\n");
+ return have_comp_mgr;
+ }
+ else
+ {
+ /* check if xcompmgr is running; assumes there's a working 'ps'
+ utility in the system; not the most elegant of the checking
+ systems, but this is more than enough for its purpose */
+ char *soutput = nullptr, *serror = nullptr;
+ int exit_status;
+
+ if ( g_spawn_command_line_sync( "ps -eo comm" ,
+ &soutput , &serror , &exit_status , nullptr ) == TRUE )
+ {
+ if (( soutput != nullptr ) && ( strstr( soutput , "\nxcompmgr\n" ) != nullptr ))
+ {
+ AUDDBG("running xcompmgr found\n");
+ have_comp_mgr = 1;
+ }
+ else
+ {
+ AUDDBG("running xcompmgr not found\n");
+ have_comp_mgr = 0;
+ }
+ }
+ else
+ {
+ g_warning("command 'ps -eo comm' failed, unable to check if xcompgr is running\n");
+ have_comp_mgr = 0;
+ }
+
+ g_free( soutput );
+ g_free( serror );
+ return have_comp_mgr;
+ }
+}
+#endif
diff --git a/src/aosd/aosd_osd.h b/src/aosd/aosd_osd.h
index 25bc63a79c26..bd0cfdf1760a 100644
--- a/src/aosd/aosd_osd.h
+++ b/src/aosd/aosd_osd.h
@@ -21,14 +21,11 @@
#ifndef _I_AOSD_OSD_H
#define _I_AOSD_OSD_H 1
-#include "aosd_common.h"
#include "aosd_cfg.h"
-#include <glib.h>
-
-gint aosd_osd_display ( gchar * markup_string , aosd_cfg_osd_t * cfg_osd , gboolean copy_cfg );
+int aosd_osd_display ( char * markup_string , aosd_cfg_t * cfg_osd , bool copy_cfg );
void aosd_osd_shutdown ( void );
-void aosd_osd_init ( gint transparency_mode ); /* to be called before any OSD usage */
+void aosd_osd_init ( int transparency_mode ); /* to be called before any OSD usage */
void aosd_osd_cleanup ( void ); /* to be called when done with OSD usage */
#ifdef HAVE_XCOMPOSITE
diff --git a/src/aosd/aosd_style.c b/src/aosd/aosd_style.c
deleted file mode 100644
index 326ca1db31f5..000000000000
--- a/src/aosd/aosd_style.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include "aosd_style.h"
-#include "aosd_style_private.h"
-#include "aosd_cfg.h"
-#include <glib.h>
-#include <audacious/i18n.h>
-#include <X11/Xlib.h>
-#include <cairo/cairo.h>
-#include <pango/pangocairo.h>
-#include "ghosd.h"
-
-
-/* HOW TO ADD A NEW DECORATION STYLE
- --------------------------------------------------------------------------
- First, add a new decoration style code; then, provide the decoration style
- information by adding a new entry in the aosd_deco_styles[] array (name,
- render function, etc.); add the new decoration style code in the array
- of decoration style codes, and update the define containing the array size.
- The render function uses three parameters; the Ghosd instance, the cairo
- object you use to draw, and a aosd_deco_style_data_t object that contains
- user-defined options (look into aosd_style.h and aosd_cfg.h for details).
- Have fun! :)
-*/
-
-
-/* decoration style codes ( the code values do not need to be sequential ) */
-enum
-{
- AOSD_DECO_STYLE_RECT = 0,
- AOSD_DECO_STYLE_ROUNDRECT = 1,
- AOSD_DECO_STYLE_CONCAVERECT = 2,
- AOSD_DECO_STYLE_NONE
-};
-
-/* decoration style codes array size */
-#define AOSD_DECO_STYLE_CODES_ARRAY_SIZE 4
-
-/* decoration style codes array */
-gint aosd_deco_style_codes[] =
-{
- AOSD_DECO_STYLE_RECT,
- AOSD_DECO_STYLE_ROUNDRECT,
- AOSD_DECO_STYLE_CONCAVERECT,
- AOSD_DECO_STYLE_NONE
-};
-
-/* prototypes of render functions */
-static void aosd_deco_rfunc_rect ( Ghosd * , cairo_t * , aosd_deco_style_data_t * );
-static void aosd_deco_rfunc_roundrect ( Ghosd * , cairo_t * , aosd_deco_style_data_t * );
-static void aosd_deco_rfunc_concaverect ( Ghosd * , cairo_t * , aosd_deco_style_data_t * );
-static void aosd_deco_rfunc_none ( Ghosd * , cairo_t * , aosd_deco_style_data_t * );
-
-/* map decoration style codes to decoration objects */
-aosd_deco_style_t aosd_deco_styles[] =
-{
- [AOSD_DECO_STYLE_RECT] = { N_("Rectangle") ,
- aosd_deco_rfunc_rect ,
- 2 , { 10 , 10 , 10 , 10 } },
-
- [AOSD_DECO_STYLE_ROUNDRECT] = { N_("Rounded Rectangle") ,
- aosd_deco_rfunc_roundrect ,
- 2 , { 10 , 10 , 10 , 10 } },
-
- [AOSD_DECO_STYLE_CONCAVERECT] = { N_("Concave Rectangle") ,
- aosd_deco_rfunc_concaverect ,
- 2 , { 10 , 10 , 10 , 10 } },
-
- [AOSD_DECO_STYLE_NONE] = { N_("None") ,
- aosd_deco_rfunc_none ,
- 0 , { 2 , 2 , 2 , 2 } }
-};
-
-
-
-/* DECORATION STYLE API */
-
-
-void
-aosd_deco_style_get_codes_array ( gint ** array , gint * array_size )
-{
- *array = aosd_deco_style_codes;
- *array_size = AOSD_DECO_STYLE_CODES_ARRAY_SIZE;
- return;
-}
-
-
-void
-aosd_deco_style_get_padding ( gint deco_code ,
- gint * ptop , gint * pbottom ,
- gint * pleft , gint * pright )
-{
- if ( ptop != NULL ) *ptop = aosd_deco_styles[deco_code].padding.top;
- if ( pbottom != NULL ) *pbottom = aosd_deco_styles[deco_code].padding.bottom;
- if ( pleft != NULL ) *pleft = aosd_deco_styles[deco_code].padding.left;
- if ( pright != NULL ) *pright = aosd_deco_styles[deco_code].padding.right;
- return;
-}
-
-
-const gchar *
-aosd_deco_style_get_desc ( gint deco_code )
-{
- return aosd_deco_styles[deco_code].desc;
-}
-
-
-gint
-aosd_deco_style_get_numcol ( gint deco_code )
-{
- return aosd_deco_styles[deco_code].colors_num;
-}
-
-
-void
-aosd_deco_style_render ( gint deco_code , gpointer ghosd , gpointer cr , gpointer user_data )
-{
- aosd_deco_styles[deco_code].render_func( (Ghosd*)ghosd , (cairo_t*)cr , user_data );
-}
-
-
-gint
-aosd_deco_style_get_first_code ( void )
-{
- return AOSD_DECO_STYLE_RECT;
-}
-
-
-gint
-aosd_deco_style_get_max_numcol ( void )
-{
- gint i = 0;
- gint max_numcol = 0;
-
- for ( i = 0 ; i < AOSD_DECO_STYLE_CODES_ARRAY_SIZE ; i++ )
- {
- gint numcol = aosd_deco_style_get_numcol( aosd_deco_style_codes[i] );
- if ( numcol > max_numcol )
- max_numcol = numcol;
- }
-
- return max_numcol;
-}
-
-
-// sizing helper
-static void
-aosd_layout_size( PangoLayout * layout , gint * width , gint * height , gint * bearing )
-{
- PangoRectangle ink, log;
-
- pango_layout_get_pixel_extents( layout , &ink , &log );
-
- if ( width != NULL )
- *width = ink.width;
- if ( height != NULL )
- *height = log.height;
- if ( bearing != NULL )
- *bearing = -ink.x;
-}
-
-
-/* RENDER FUNCTIONS */
-
-static void
-aosd_deco_rfunc_rect( Ghosd * osd , cairo_t * cr , aosd_deco_style_data_t * data )
-{
- /* decoration information
- ----------------------
- draws a simple rectangular decoration; uses 2 colors
- (user color 1 and 2) and 1 font (user font 1), with optional shadow
- */
- PangoLayout *osd_layout = data->layout;
- aosd_color_t color0 = g_array_index( data->decoration->colors , aosd_color_t , 0 );
- aosd_color_t color1 = g_array_index( data->decoration->colors , aosd_color_t , 1 );
- aosd_color_t textcolor0 = data->text->fonts_color[0];
- aosd_color_t shadowcolor0 = data->text->fonts_shadow_color[0];
- gboolean draw_shadow = data->text->fonts_draw_shadow[0];
- gint width = 0, height = 0, bearing = 0;
-
- aosd_layout_size( osd_layout , &width , &height , &bearing );
-
- /* draw rectangle container */
- cairo_set_source_rgba( cr , (gdouble)color0.red / 65535 , (gdouble)color0.green / 65535 ,
- (gdouble)color0.blue / 65535 , (gdouble)color0.alpha / 65535 );
- cairo_rectangle( cr , 0 , 0 ,
- aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.left + width +
- aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.right,
- aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.top + height +
- aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.bottom );
- cairo_fill_preserve( cr );
- cairo_set_source_rgba( cr , (gdouble)color1.red / 65535 , (gdouble)color1.green / 65535 ,
- (gdouble)color1.blue / 65535 , (gdouble)color1.alpha / 65535 );
- cairo_stroke( cr );
-
- if ( draw_shadow == TRUE )
- {
- /* draw text shadow */
- cairo_set_source_rgba( cr , (gdouble)shadowcolor0.red / 65535 , (gdouble)shadowcolor0.green / 65535 ,
- (gdouble)shadowcolor0.blue / 65535 , (gdouble)shadowcolor0.alpha / 65535 );
- cairo_move_to( cr,
- aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.left + bearing + 2 ,
- aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.top + 2 );
- pango_cairo_show_layout( cr , osd_layout );
- }
-
- /* draw text */
- cairo_set_source_rgba( cr , (gdouble)textcolor0.red / 65535 , (gdouble)textcolor0.green / 65535 ,
- (gdouble)textcolor0.blue / 65535 , (gdouble)textcolor0.alpha / 65535 );
- cairo_move_to( cr,
- aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.left + bearing ,
- aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.top );
- pango_cairo_show_layout( cr , osd_layout );
-}
-
-
-static void
-aosd_deco_rfunc_roundrect ( Ghosd * osd , cairo_t * cr , aosd_deco_style_data_t * data )
-{
- /* decoration information
- ----------------------
- draws a rectangular decoration with rounded angles; uses 2 colors
- (user color 1 and 2) and 1 font (user font 1), with optional shadow
- */
- PangoLayout *osd_layout = data->layout;
- aosd_color_t color0 = g_array_index( data->decoration->colors , aosd_color_t , 0 );
- aosd_color_t color1 = g_array_index( data->decoration->colors , aosd_color_t , 1 );
- aosd_color_t textcolor0 = data->text->fonts_color[0];
- aosd_color_t shadowcolor0 = data->text->fonts_shadow_color[0];
- gboolean draw_shadow = data->text->fonts_draw_shadow[0];
- gint width = 0, height = 0, bearing = 0;
-
- aosd_layout_size( osd_layout , &width , &height , &bearing );
-
- /* draw rounded-rectangle container */
- cairo_set_source_rgba( cr , (gdouble)color0.red / 65535 , (gdouble)color0.green / 65535 ,
- (gdouble)color0.blue / 65535 , (gdouble)color0.alpha / 65535 );
- cairo_move_to( cr , aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left , 0 );
- cairo_arc( cr , width + aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left ,
- aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top ,
- 10. , -G_PI_2 , 0. );
- cairo_arc( cr , width + aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left ,
- aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top + height ,
- 10. , -4. * G_PI_2 , -3. * G_PI_2 );
- cairo_arc( cr , aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left ,
- aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top + height ,
- 10. , -3. * G_PI_2 , -2. * G_PI_2 );
- cairo_arc( cr , aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left ,
- aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top ,
- 10. , -2. * G_PI_2 , -G_PI_2 );
- cairo_close_path( cr );
- cairo_fill_preserve( cr );
- cairo_set_source_rgba( cr , (gdouble)color1.red / 65535 , (gdouble)color1.green / 65535 ,
- (gdouble)color1.blue / 65535 , (gdouble)color1.alpha / 65535 );
- cairo_stroke( cr );
-
- if ( draw_shadow == TRUE )
- {
- /* draw text shadow */
- cairo_set_source_rgba( cr , (gdouble)shadowcolor0.red / 65535 , (gdouble)shadowcolor0.green / 65535 ,
- (gdouble)shadowcolor0.blue / 65535 , (gdouble)shadowcolor0.alpha / 65535 );
- cairo_move_to( cr ,
- aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left + bearing + 2 ,
- aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top + 2 );
- pango_cairo_show_layout( cr , osd_layout );
- }
-
- /* draw text */
- cairo_set_source_rgba( cr , (gdouble)textcolor0.red / 65535 , (gdouble)textcolor0.green / 65535 ,
- (gdouble)textcolor0.blue / 65535 , (gdouble)textcolor0.alpha / 65535 );
- cairo_move_to( cr ,
- aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left + bearing ,
- aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top );
- pango_cairo_show_layout( cr , osd_layout );
-}
-
-
-static void
-aosd_deco_rfunc_concaverect ( Ghosd * osd , cairo_t * cr , aosd_deco_style_data_t * data )
-{
- /* decoration information
- ----------------------
- draws a rectangle with concave angles; uses 2 colors
- (user color 1 and 2) and 1 font (user font 1), with optional shadow
- */
- PangoLayout *osd_layout = data->layout;
- aosd_color_t color0 = g_array_index( data->decoration->colors , aosd_color_t , 0 );
- aosd_color_t color1 = g_array_index( data->decoration->colors , aosd_color_t , 1 );
- aosd_color_t textcolor0 = data->text->fonts_color[0];
- aosd_color_t shadowcolor0 = data->text->fonts_shadow_color[0];
- gboolean draw_shadow = data->text->fonts_draw_shadow[0];
- gint width = 0, height = 0, bearing = 0;
-
- aosd_layout_size( osd_layout , &width , &height , &bearing );
-
- /* draw jigsaw-piece-like container */
- cairo_set_source_rgba( cr , (gdouble)color0.red / 65535 , (gdouble)color0.green / 65535 ,
- (gdouble)color0.blue / 65535 , (gdouble)color0.alpha / 65535 );
- cairo_move_to( cr , aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left , 0 );
- cairo_arc_negative( cr , width + aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left + 2 ,
- aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top - 2 ,
- 8. , -G_PI_2 , 0. );
- cairo_arc_negative( cr , width + aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left + 2 ,
- aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top + height + 2 ,
- 8. , -4. * G_PI_2 , -3. * G_PI_2 );
- cairo_arc_negative( cr , aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left - 2 ,
- aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top + height + 2 ,
- 8. , -3. * G_PI_2 , -2. * G_PI_2 );
- cairo_arc_negative( cr , aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left - 2 ,
- aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top - 2 ,
- 8. , -2. * G_PI_2 , -G_PI_2 );
- cairo_close_path( cr );
- cairo_fill_preserve( cr );
- cairo_set_source_rgba( cr , (gdouble)color1.red / 65535 , (gdouble)color1.green / 65535 ,
- (gdouble)color1.blue / 65535 , (gdouble)color1.alpha / 65535 );
- cairo_stroke( cr );
-
- if ( draw_shadow == TRUE )
- {
- /* draw text shadow */
- cairo_set_source_rgba( cr , (gdouble)shadowcolor0.red / 65535 , (gdouble)shadowcolor0.green / 65535 ,
- (gdouble)shadowcolor0.blue / 65535 , (gdouble)shadowcolor0.alpha / 65535 );
- cairo_move_to( cr ,
- aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left + bearing + 2 ,
- aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top + 2 );
- pango_cairo_show_layout( cr , osd_layout );
- }
-
- /* draw text */
- cairo_set_source_rgba( cr , (gdouble)textcolor0.red / 65535 , (gdouble)textcolor0.green / 65535 ,
- (gdouble)textcolor0.blue / 65535 , (gdouble)textcolor0.alpha / 65535 );
- cairo_move_to( cr ,
- aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left + bearing ,
- aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top );
- pango_cairo_show_layout( cr , osd_layout );
-}
-
-
-static void
-aosd_deco_rfunc_none ( Ghosd * osd , cairo_t * cr , aosd_deco_style_data_t * data )
-{
- /* decoration information
- ----------------------
- does not draw any decoration around text; uses 0 colors
- and 1 font (user font 1), with optional shadow
- */
- PangoLayout *osd_layout = data->layout;
- aosd_color_t textcolor0 = data->text->fonts_color[0];
- aosd_color_t shadowcolor0 = data->text->fonts_shadow_color[0];
- gboolean draw_shadow = data->text->fonts_draw_shadow[0];
- gint width = 0, height = 0, bearing = 0;
-
- aosd_layout_size( osd_layout , &width , &height , &bearing );
-
- if ( draw_shadow == TRUE )
- {
- /* draw text shadow */
- cairo_set_source_rgba( cr , (gdouble)shadowcolor0.red / 65535 , (gdouble)shadowcolor0.green / 65535 ,
- (gdouble)shadowcolor0.blue / 65535 , (gdouble)shadowcolor0.alpha / 65535 );
- cairo_move_to( cr ,
- aosd_deco_styles[AOSD_DECO_STYLE_NONE].padding.left + bearing + 2 ,
- aosd_deco_styles[AOSD_DECO_STYLE_NONE].padding.top + 2 );
- pango_cairo_show_layout( cr , osd_layout );
- }
-
- /* draw text */
- cairo_set_source_rgba( cr , (gdouble)textcolor0.red / 65535 , (gdouble)textcolor0.green / 65535 ,
- (gdouble)textcolor0.blue / 65535 , (gdouble)textcolor0.alpha / 65535 );
- cairo_move_to( cr ,
- aosd_deco_styles[AOSD_DECO_STYLE_NONE].padding.left + bearing ,
- aosd_deco_styles[AOSD_DECO_STYLE_NONE].padding.top );
- pango_cairo_show_layout( cr , osd_layout );
-}
diff --git a/src/aosd/aosd_style.cc b/src/aosd/aosd_style.cc
new file mode 100644
index 000000000000..9cd855b4273b
--- /dev/null
+++ b/src/aosd/aosd_style.cc
@@ -0,0 +1,341 @@
+/*
+*
+* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+*/
+
+#include "aosd_style.h"
+#include "aosd_style_private.h"
+#include "aosd_cfg.h"
+
+#include <libaudcore/i18n.h>
+#include <X11/Xlib.h>
+#include <cairo/cairo.h>
+#include <pango/pangocairo.h>
+#include "ghosd.h"
+
+
+/* HOW TO ADD A NEW DECORATION STYLE
+ --------------------------------------------------------------------------
+ First, add a new decoration style code; then, provide the decoration style
+ information by adding a new entry in the aosd_deco_styles[] array (name,
+ render function, etc.); add the new decoration style code in the array
+ of decoration style codes, and update the define containing the array size.
+ The render function uses three parameters; the Ghosd instance, the cairo
+ object you use to draw, and a aosd_deco_style_data_t object that contains
+ user-defined options (look into aosd_style.h and aosd_cfg.h for details).
+ Have fun! :)
+*/
+
+/* prototypes of render functions */
+static void aosd_deco_rfunc_rect ( Ghosd * , cairo_t * , aosd_deco_style_data_t * );
+static void aosd_deco_rfunc_roundrect ( Ghosd * , cairo_t * , aosd_deco_style_data_t * );
+static void aosd_deco_rfunc_concaverect ( Ghosd * , cairo_t * , aosd_deco_style_data_t * );
+static void aosd_deco_rfunc_none ( Ghosd * , cairo_t * , aosd_deco_style_data_t * );
+
+/* map decoration style codes to decoration objects */
+aosd_deco_style_t aosd_deco_styles[] =
+{
+ // AOSD_DECO_STYLE_RECT
+ { N_("Rectangle") ,
+ aosd_deco_rfunc_rect ,
+ 2 , { 10 , 10 , 10 , 10 } },
+
+ // AOSD_DECO_STYLE_ROUNDRECT
+ { N_("Rounded Rectangle") ,
+ aosd_deco_rfunc_roundrect ,
+ 2 , { 10 , 10 , 10 , 10 } },
+
+ // AOSD_DECO_STYLE_CONCAVERECT
+ { N_("Concave Rectangle") ,
+ aosd_deco_rfunc_concaverect ,
+ 2 , { 10 , 10 , 10 , 10 } },
+
+ // AOSD_DECO_STYLE_NONE
+ { N_("None") ,
+ aosd_deco_rfunc_none ,
+ 0 , { 2 , 2 , 2 , 2 } }
+};
+
+static_assert (aud::n_elems (aosd_deco_styles) == AOSD_NUM_DECO_STYLES, "update aosd_deco_styles");
+
+
+/* DECORATION STYLE API */
+
+void
+aosd_deco_style_get_padding ( int deco_code ,
+ int * ptop , int * pbottom ,
+ int * pleft , int * pright )
+{
+ if ( ptop != nullptr ) *ptop = aosd_deco_styles[deco_code].padding.top;
+ if ( pbottom != nullptr ) *pbottom = aosd_deco_styles[deco_code].padding.bottom;
+ if ( pleft != nullptr ) *pleft = aosd_deco_styles[deco_code].padding.left;
+ if ( pright != nullptr ) *pright = aosd_deco_styles[deco_code].padding.right;
+ return;
+}
+
+
+const char *
+aosd_deco_style_get_desc ( int deco_code )
+{
+ return aosd_deco_styles[deco_code].desc;
+}
+
+
+int
+aosd_deco_style_get_numcol ( int deco_code )
+{
+ return aosd_deco_styles[deco_code].colors_num;
+}
+
+
+void
+aosd_deco_style_render ( int deco_code , void * ghosd , void * cr , void * user_data )
+{
+ aosd_deco_styles[deco_code].render_func ((Ghosd *) ghosd, (cairo_t *) cr,
+ (aosd_deco_style_data_t *) user_data);
+}
+
+
+// sizing helper
+static void
+aosd_layout_size( PangoLayout * layout , int * width , int * height , int * bearing )
+{
+ PangoRectangle ink, log;
+
+ pango_layout_get_pixel_extents( layout , &ink , &log );
+
+ if ( width != nullptr )
+ *width = ink.width;
+ if ( height != nullptr )
+ *height = log.height;
+ if ( bearing != nullptr )
+ *bearing = -ink.x;
+}
+
+
+/* RENDER FUNCTIONS */
+
+static void
+aosd_deco_rfunc_rect( Ghosd * osd , cairo_t * cr , aosd_deco_style_data_t * data )
+{
+ /* decoration information
+ ----------------------
+ draws a simple rectangular decoration; uses 2 colors
+ (user color 1 and 2) and 1 font (user font 1), with optional shadow
+ */
+ PangoLayout *osd_layout = data->layout;
+ aosd_color_t color0 = data->decoration->colors[0];
+ aosd_color_t color1 = data->decoration->colors[1];
+ aosd_color_t textcolor0 = data->text->fonts_color[0];
+ aosd_color_t shadowcolor0 = data->text->fonts_shadow_color[0];
+ gboolean draw_shadow = data->text->fonts_draw_shadow[0];
+ int width = 0, height = 0, bearing = 0;
+
+ aosd_layout_size( osd_layout , &width , &height , &bearing );
+
+ /* draw rectangle container */
+ cairo_set_source_rgba( cr , (double)color0.red / 65535 , (double)color0.green / 65535 ,
+ (double)color0.blue / 65535 , (double)color0.alpha / 65535 );
+ cairo_rectangle( cr , 0 , 0 ,
+ aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.left + width +
+ aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.right,
+ aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.top + height +
+ aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.bottom );
+ cairo_fill_preserve( cr );
+ cairo_set_source_rgba( cr , (double)color1.red / 65535 , (double)color1.green / 65535 ,
+ (double)color1.blue / 65535 , (double)color1.alpha / 65535 );
+ cairo_stroke( cr );
+
+ if ( draw_shadow == TRUE )
+ {
+ /* draw text shadow */
+ cairo_set_source_rgba( cr , (double)shadowcolor0.red / 65535 , (double)shadowcolor0.green / 65535 ,
+ (double)shadowcolor0.blue / 65535 , (double)shadowcolor0.alpha / 65535 );
+ cairo_move_to( cr,
+ aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.left + bearing + 2 ,
+ aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.top + 2 );
+ pango_cairo_show_layout( cr , osd_layout );
+ }
+
+ /* draw text */
+ cairo_set_source_rgba( cr , (double)textcolor0.red / 65535 , (double)textcolor0.green / 65535 ,
+ (double)textcolor0.blue / 65535 , (double)textcolor0.alpha / 65535 );
+ cairo_move_to( cr,
+ aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.left + bearing ,
+ aosd_deco_styles[AOSD_DECO_STYLE_RECT].padding.top );
+ pango_cairo_show_layout( cr , osd_layout );
+}
+
+
+static void
+aosd_deco_rfunc_roundrect ( Ghosd * osd , cairo_t * cr , aosd_deco_style_data_t * data )
+{
+ /* decoration information
+ ----------------------
+ draws a rectangular decoration with rounded angles; uses 2 colors
+ (user color 1 and 2) and 1 font (user font 1), with optional shadow
+ */
+ PangoLayout *osd_layout = data->layout;
+ aosd_color_t color0 = data->decoration->colors[0];
+ aosd_color_t color1 = data->decoration->colors[1];
+ aosd_color_t textcolor0 = data->text->fonts_color[0];
+ aosd_color_t shadowcolor0 = data->text->fonts_shadow_color[0];
+ gboolean draw_shadow = data->text->fonts_draw_shadow[0];
+ int width = 0, height = 0, bearing = 0;
+
+ aosd_layout_size( osd_layout , &width , &height , &bearing );
+
+ /* draw rounded-rectangle container */
+ cairo_set_source_rgba( cr , (double)color0.red / 65535 , (double)color0.green / 65535 ,
+ (double)color0.blue / 65535 , (double)color0.alpha / 65535 );
+ cairo_move_to( cr , aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left , 0 );
+ cairo_arc( cr , width + aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left ,
+ aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top ,
+ 10. , -G_PI_2 , 0. );
+ cairo_arc( cr , width + aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left ,
+ aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top + height ,
+ 10. , -4. * G_PI_2 , -3. * G_PI_2 );
+ cairo_arc( cr , aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left ,
+ aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top + height ,
+ 10. , -3. * G_PI_2 , -2. * G_PI_2 );
+ cairo_arc( cr , aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left ,
+ aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top ,
+ 10. , -2. * G_PI_2 , -G_PI_2 );
+ cairo_close_path( cr );
+ cairo_fill_preserve( cr );
+ cairo_set_source_rgba( cr , (double)color1.red / 65535 , (double)color1.green / 65535 ,
+ (double)color1.blue / 65535 , (double)color1.alpha / 65535 );
+ cairo_stroke( cr );
+
+ if ( draw_shadow == TRUE )
+ {
+ /* draw text shadow */
+ cairo_set_source_rgba( cr , (double)shadowcolor0.red / 65535 , (double)shadowcolor0.green / 65535 ,
+ (double)shadowcolor0.blue / 65535 , (double)shadowcolor0.alpha / 65535 );
+ cairo_move_to( cr ,
+ aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left + bearing + 2 ,
+ aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top + 2 );
+ pango_cairo_show_layout( cr , osd_layout );
+ }
+
+ /* draw text */
+ cairo_set_source_rgba( cr , (double)textcolor0.red / 65535 , (double)textcolor0.green / 65535 ,
+ (double)textcolor0.blue / 65535 , (double)textcolor0.alpha / 65535 );
+ cairo_move_to( cr ,
+ aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.left + bearing ,
+ aosd_deco_styles[AOSD_DECO_STYLE_ROUNDRECT].padding.top );
+ pango_cairo_show_layout( cr , osd_layout );
+}
+
+
+static void
+aosd_deco_rfunc_concaverect ( Ghosd * osd , cairo_t * cr , aosd_deco_style_data_t * data )
+{
+ /* decoration information
+ ----------------------
+ draws a rectangle with concave angles; uses 2 colors
+ (user color 1 and 2) and 1 font (user font 1), with optional shadow
+ */
+ PangoLayout *osd_layout = data->layout;
+ aosd_color_t color0 = data->decoration->colors[0];
+ aosd_color_t color1 = data->decoration->colors[1];
+ aosd_color_t textcolor0 = data->text->fonts_color[0];
+ aosd_color_t shadowcolor0 = data->text->fonts_shadow_color[0];
+ gboolean draw_shadow = data->text->fonts_draw_shadow[0];
+ int width = 0, height = 0, bearing = 0;
+
+ aosd_layout_size( osd_layout , &width , &height , &bearing );
+
+ /* draw jigsaw-piece-like container */
+ cairo_set_source_rgba( cr , (double)color0.red / 65535 , (double)color0.green / 65535 ,
+ (double)color0.blue / 65535 , (double)color0.alpha / 65535 );
+ cairo_move_to( cr , aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left , 0 );
+ cairo_arc_negative( cr , width + aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left + 2 ,
+ aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top - 2 ,
+ 8. , -G_PI_2 , 0. );
+ cairo_arc_negative( cr , width + aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left + 2 ,
+ aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top + height + 2 ,
+ 8. , -4. * G_PI_2 , -3. * G_PI_2 );
+ cairo_arc_negative( cr , aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left - 2 ,
+ aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top + height + 2 ,
+ 8. , -3. * G_PI_2 , -2. * G_PI_2 );
+ cairo_arc_negative( cr , aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left - 2 ,
+ aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top - 2 ,
+ 8. , -2. * G_PI_2 , -G_PI_2 );
+ cairo_close_path( cr );
+ cairo_fill_preserve( cr );
+ cairo_set_source_rgba( cr , (double)color1.red / 65535 , (double)color1.green / 65535 ,
+ (double)color1.blue / 65535 , (double)color1.alpha / 65535 );
+ cairo_stroke( cr );
+
+ if ( draw_shadow == TRUE )
+ {
+ /* draw text shadow */
+ cairo_set_source_rgba( cr , (double)shadowcolor0.red / 65535 , (double)shadowcolor0.green / 65535 ,
+ (double)shadowcolor0.blue / 65535 , (double)shadowcolor0.alpha / 65535 );
+ cairo_move_to( cr ,
+ aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left + bearing + 2 ,
+ aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top + 2 );
+ pango_cairo_show_layout( cr , osd_layout );
+ }
+
+ /* draw text */
+ cairo_set_source_rgba( cr , (double)textcolor0.red / 65535 , (double)textcolor0.green / 65535 ,
+ (double)textcolor0.blue / 65535 , (double)textcolor0.alpha / 65535 );
+ cairo_move_to( cr ,
+ aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.left + bearing ,
+ aosd_deco_styles[AOSD_DECO_STYLE_CONCAVERECT].padding.top );
+ pango_cairo_show_layout( cr , osd_layout );
+}
+
+
+static void
+aosd_deco_rfunc_none ( Ghosd * osd , cairo_t * cr , aosd_deco_style_data_t * data )
+{
+ /* decoration information
+ ----------------------
+ does not draw any decoration around text; uses 0 colors
+ and 1 font (user font 1), with optional shadow
+ */
+ PangoLayout *osd_layout = data->layout;
+ aosd_color_t textcolor0 = data->text->fonts_color[0];
+ aosd_color_t shadowcolor0 = data->text->fonts_shadow_color[0];
+ gboolean draw_shadow = data->text->fonts_draw_shadow[0];
+ int width = 0, height = 0, bearing = 0;
+
+ aosd_layout_size( osd_layout , &width , &height , &bearing );
+
+ if ( draw_shadow == TRUE )
+ {
+ /* draw text shadow */
+ cairo_set_source_rgba( cr , (double)shadowcolor0.red / 65535 , (double)shadowcolor0.green / 65535 ,
+ (double)shadowcolor0.blue / 65535 , (double)shadowcolor0.alpha / 65535 );
+ cairo_move_to( cr ,
+ aosd_deco_styles[AOSD_DECO_STYLE_NONE].padding.left + bearing + 2 ,
+ aosd_deco_styles[AOSD_DECO_STYLE_NONE].padding.top + 2 );
+ pango_cairo_show_layout( cr , osd_layout );
+ }
+
+ /* draw text */
+ cairo_set_source_rgba( cr , (double)textcolor0.red / 65535 , (double)textcolor0.green / 65535 ,
+ (double)textcolor0.blue / 65535 , (double)textcolor0.alpha / 65535 );
+ cairo_move_to( cr ,
+ aosd_deco_styles[AOSD_DECO_STYLE_NONE].padding.left + bearing ,
+ aosd_deco_styles[AOSD_DECO_STYLE_NONE].padding.top );
+ pango_cairo_show_layout( cr , osd_layout );
+}
diff --git a/src/aosd/aosd_style.h b/src/aosd/aosd_style.h
index 2ba603a5d70e..7ac2db7ea9d0 100644
--- a/src/aosd/aosd_style.h
+++ b/src/aosd/aosd_style.h
@@ -21,22 +21,10 @@
#ifndef _I_AOSD_STYLE_H
#define _I_AOSD_STYLE_H 1
-#undef PACKAGE
-#define PACKAGE "audacious-plugins"
-
-#include "aosd_common.h"
-#include <glib.h>
-
-
/* decoration style public API */
-void aosd_deco_style_get_codes_array ( gint ** , gint * );
-void aosd_deco_style_get_padding ( gint , gint * , gint * , gint * , gint * );
-const gchar * aosd_deco_style_get_desc ( gint );
-gint aosd_deco_style_get_numcol ( gint );
-void aosd_deco_style_render ( gint , gpointer , gpointer , gpointer ); /* opaque */
-
-gint aosd_deco_style_get_first_code ( void );
-gint aosd_deco_style_get_max_numcol ( void );
-
+void aosd_deco_style_get_padding ( int , int * , int * , int * , int * );
+const char * aosd_deco_style_get_desc ( int );
+int aosd_deco_style_get_numcol ( int );
+void aosd_deco_style_render ( int , void * , void * , void * ); /* opaque */
#endif /* !_I_AOSD_STYLE_H */
diff --git a/src/aosd/aosd_style_private.h b/src/aosd/aosd_style_private.h
index 94d73ec576f9..935e7c40a32d 100644
--- a/src/aosd/aosd_style_private.h
+++ b/src/aosd/aosd_style_private.h
@@ -21,9 +21,7 @@
#ifndef _I_AOSD_STYLE_PRIVATE_H
#define _I_AOSD_STYLE_PRIVATE_H 1
-#include "aosd_common.h"
#include "aosd_cfg.h"
-#include <glib.h>
#include <cairo/cairo.h>
#include <pango/pangocairo.h>
#include "ghosd.h"
@@ -48,24 +46,23 @@ aosd_deco_style_data_t;
----------------------------------------------------------
desc description
render_func render function used to draw the decoration
- colors_num number of user-definable colors
+ colors_num number of user-definable colors (no more than AOSD_DECO_STYLE_MAX_COLORS)
padding drawable space available around the text
*/
typedef struct
{
- const gchar * desc;
+ const char * desc;
void (*render_func)( Ghosd * , cairo_t * , aosd_deco_style_data_t * );
- gint colors_num;
+ int colors_num;
struct
{
- gint top;
- gint bottom;
- gint left;
- gint right;
+ int top;
+ int bottom;
+ int left;
+ int right;
}
padding;
}
aosd_deco_style_t;
-
#endif /* !_I_AOSD_STYLE_PRIVATE_H */
diff --git a/src/aosd/aosd_trigger.c b/src/aosd/aosd_trigger.c
deleted file mode 100644
index 8d3a28e3ec4b..000000000000
--- a/src/aosd/aosd_trigger.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include <glib.h>
-#include <string.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/playlist.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-
-#include "aosd_trigger.h"
-#include "aosd_trigger_private.h"
-#include "aosd_cfg.h"
-#include "aosd_osd.h"
-
-extern aosd_cfg_t * global_config;
-
-
-/* trigger codes ( the code values do not need to be sequential ) */
-enum
-{
- AOSD_TRIGGER_PB_START = 0,
- AOSD_TRIGGER_PB_TITLECHANGE = 1,
- AOSD_TRIGGER_PB_PAUSEON = 2,
- AOSD_TRIGGER_PB_PAUSEOFF = 3
-};
-
-/* trigger codes array size */
-#define AOSD_TRIGGER_CODES_ARRAY_SIZE 4
-
-/* trigger codes array */
-gint aosd_trigger_codes[] =
-{
- AOSD_TRIGGER_PB_START,
- AOSD_TRIGGER_PB_TITLECHANGE,
- AOSD_TRIGGER_PB_PAUSEON,
- AOSD_TRIGGER_PB_PAUSEOFF
-};
-
-/* prototypes of trigger functions */
-static void aosd_trigger_func_pb_start_onoff ( gboolean );
-static void aosd_trigger_func_pb_start_cb ( gpointer , gpointer );
-static void aosd_trigger_func_pb_titlechange_onoff ( gboolean );
-static void aosd_trigger_func_pb_titlechange_cb ( gpointer , gpointer );
-static void aosd_trigger_func_pb_pauseon_onoff ( gboolean );
-static void aosd_trigger_func_pb_pauseon_cb ( gpointer , gpointer );
-static void aosd_trigger_func_pb_pauseoff_onoff ( gboolean );
-static void aosd_trigger_func_pb_pauseoff_cb ( gpointer , gpointer );
-static void aosd_trigger_func_hook_cb ( gpointer markup_text , gpointer unused );
-
-/* map trigger codes to trigger objects */
-aosd_trigger_t aosd_triggers[] =
-{
- [AOSD_TRIGGER_PB_START] = { N_("Playback Start") ,
- N_("Triggers OSD when a playlist entry is played.") ,
- aosd_trigger_func_pb_start_onoff ,
- aosd_trigger_func_pb_start_cb },
-
- [AOSD_TRIGGER_PB_TITLECHANGE] = { N_("Title Change") ,
- N_("Triggers OSD when, during playback, the song title changes "
- "but the filename is the same. This is mostly useful to display "
- "title changes in internet streams.") ,
- aosd_trigger_func_pb_titlechange_onoff ,
- aosd_trigger_func_pb_titlechange_cb },
-
- [AOSD_TRIGGER_PB_PAUSEON] = { N_("Pause On") ,
- N_("Triggers OSD when playback is paused.") ,
- aosd_trigger_func_pb_pauseon_onoff ,
- aosd_trigger_func_pb_pauseon_cb },
-
- [AOSD_TRIGGER_PB_PAUSEOFF] = { N_("Pause Off") ,
- N_("Triggers OSD when playback is unpaused.") ,
- aosd_trigger_func_pb_pauseoff_onoff ,
- aosd_trigger_func_pb_pauseoff_cb }
-};
-
-
-
-/* TRIGGER API */
-
-void
-aosd_trigger_get_codes_array ( gint ** array , gint * array_size )
-{
- *array = aosd_trigger_codes;
- *array_size = AOSD_TRIGGER_CODES_ARRAY_SIZE;
-}
-
-
-const gchar *
-aosd_trigger_get_name ( gint trig_code )
-{
- if (trig_code >= 0 && trig_code < ARRAY_LEN (aosd_triggers))
- return aosd_triggers[trig_code].name;
- return NULL;
-}
-
-
-const gchar *
-aosd_trigger_get_desc ( gint trig_code )
-{
- if (trig_code >= 0 && trig_code < ARRAY_LEN (aosd_triggers))
- return aosd_triggers[trig_code].desc;
- return NULL;
-}
-
-
-void
-aosd_trigger_start ( aosd_cfg_osd_trigger_t * cfg_trigger )
-{
- gint i = 0;
- for ( i = 0 ; i < cfg_trigger->active->len ; i++ )
- {
- gint trig_code = g_array_index( cfg_trigger->active , gint , i );
- if (trig_code >= 0 && trig_code < ARRAY_LEN (aosd_triggers))
- aosd_triggers[trig_code].onoff_func (TRUE);
- }
- /* When called, this hook will display the text of the user pointer
- or the current playing song, if NULL */
- hook_associate( "aosd toggle" , aosd_trigger_func_hook_cb , NULL );
-}
-
-
-void
-aosd_trigger_stop ( aosd_cfg_osd_trigger_t * cfg_trigger )
-{
- gint i = 0;
- hook_dissociate( "aosd toggle" , aosd_trigger_func_hook_cb );
- for ( i = 0 ; i < cfg_trigger->active->len ; i++ )
- {
- gint trig_code = g_array_index( cfg_trigger->active , gint , i );
- if (trig_code >= 0 && trig_code < ARRAY_LEN (aosd_triggers))
- aosd_triggers[trig_code].onoff_func (FALSE);
- }
-}
-
-
-/* TRIGGER FUNCTIONS */
-
-static void
-aosd_trigger_func_pb_start_onoff(gboolean turn_on)
-{
- if (turn_on == TRUE)
- hook_associate("playback begin", aosd_trigger_func_pb_start_cb, NULL);
- else
- hook_dissociate("playback begin", aosd_trigger_func_pb_start_cb);
-}
-
-static void
-aosd_trigger_func_pb_start_cb(gpointer hook_data, gpointer user_data)
-{
- char * title = aud_drct_get_title ();
- char * markup = g_markup_printf_escaped ("<span font_desc='%s'>%s</span>",
- global_config->osd->text.fonts_name[0], title);
-
- aosd_osd_display (markup, global_config->osd, FALSE);
- g_free (markup);
- str_unref (title);
-}
-
-typedef struct
-{
- gchar *title;
- gchar *filename;
-}
-aosd_pb_titlechange_prevs_t;
-
-static void
-aosd_trigger_func_pb_titlechange_onoff ( gboolean turn_on )
-{
- static aosd_pb_titlechange_prevs_t *prevs = NULL;
-
- if ( turn_on == TRUE )
- {
- prevs = g_malloc0(sizeof(aosd_pb_titlechange_prevs_t));
- prevs->title = NULL;
- prevs->filename = NULL;
- hook_associate( "title change" , aosd_trigger_func_pb_titlechange_cb , prevs );
- }
- else
- {
- hook_dissociate( "title change" , aosd_trigger_func_pb_titlechange_cb );
- if ( prevs != NULL )
- {
- if ( prevs->title != NULL ) g_free( prevs->title );
- if ( prevs->filename != NULL ) g_free( prevs->filename );
- g_free( prevs );
- prevs = NULL;
- }
- }
-}
-
-static void
-aosd_trigger_func_pb_titlechange_cb ( gpointer plentry_gp , gpointer prevs_gp )
-{
- if (aud_drct_get_playing ())
- {
- aosd_pb_titlechange_prevs_t *prevs = prevs_gp;
- gint playlist = aud_playlist_get_playing();
- gint pl_entry = aud_playlist_get_position(playlist);
- gchar * pl_entry_filename = aud_playlist_entry_get_filename (playlist, pl_entry);
- gchar * pl_entry_title = aud_playlist_entry_get_title (playlist, pl_entry, FALSE);
-
- /* same filename but title changed, useful to detect http stream song changes */
-
- if ( ( prevs->title != NULL ) && ( prevs->filename != NULL ) )
- {
- if ( ( pl_entry_filename != NULL ) && ( !strcmp(pl_entry_filename,prevs->filename) ) )
- {
- if ( ( pl_entry_title != NULL ) && ( strcmp(pl_entry_title,prevs->title) ) )
- {
- /* string formatting is done here a.t.m. - TODO - improve this area */
- char * markup = g_markup_printf_escaped
- ("<span font_desc='%s'>%s</span>",
- global_config->osd->text.fonts_name[0], pl_entry_title);
-
- aosd_osd_display (markup, global_config->osd, FALSE);
- g_free (markup);
-
- g_free( prevs->title );
- prevs->title = g_strdup(pl_entry_title);
- }
- }
- else
- {
- g_free(prevs->filename);
- prevs->filename = g_strdup(pl_entry_filename);
- /* if filename changes, reset title as well */
- if ( prevs->title != NULL )
- g_free(prevs->title);
- prevs->title = g_strdup(pl_entry_title);
- }
- }
- else
- {
- if ( prevs->title != NULL )
- g_free(prevs->title);
- prevs->title = g_strdup(pl_entry_title);
- if ( prevs->filename != NULL )
- g_free(prevs->filename);
- prevs->filename = g_strdup(pl_entry_filename);
- }
-
- str_unref (pl_entry_filename);
- str_unref (pl_entry_title);
- }
-}
-
-static void
-aosd_trigger_func_pb_pauseon_onoff ( gboolean turn_on )
-{
- if ( turn_on == TRUE )
- hook_associate( "playback pause" , aosd_trigger_func_pb_pauseon_cb , NULL );
- else
- hook_dissociate( "playback pause" , aosd_trigger_func_pb_pauseon_cb );
-}
-
-static void
-aosd_trigger_func_pb_pauseon_cb ( gpointer unused1 , gpointer unused2 )
-{
- char * markup = g_markup_printf_escaped ("<span font_desc='%s'>Paused</span>",
- global_config->osd->text.fonts_name[0]);
- aosd_osd_display (markup, global_config->osd, FALSE);
- g_free (markup);
-}
-
-
-static void
-aosd_trigger_func_pb_pauseoff_onoff ( gboolean turn_on )
-{
- if ( turn_on == TRUE )
- hook_associate( "playback unpause" , aosd_trigger_func_pb_pauseoff_cb , NULL );
- else
- hook_dissociate( "playback unpause" , aosd_trigger_func_pb_pauseoff_cb );
-}
-
-static void
-aosd_trigger_func_pb_pauseoff_cb ( gpointer unused1 , gpointer unused2 )
-{
- gint active = aud_playlist_get_active();
- gint pos = aud_playlist_get_position(active);
- gint time_cur, time_tot;
- gint time_cur_m, time_cur_s, time_tot_m, time_tot_s;
-
- time_tot = aud_playlist_entry_get_length (active, pos, FALSE) / 1000;
- time_cur = aud_drct_get_time() / 1000;
- time_cur_s = time_cur % 60;
- time_cur_m = (time_cur - time_cur_s) / 60;
- time_tot_s = time_tot % 60;
- time_tot_m = (time_tot - time_tot_s) / 60;
-
- char * title = aud_playlist_entry_get_title (active, pos, FALSE);
- char * markup = g_markup_printf_escaped
- ("<span font_desc='%s'>%s (%i:%02i/%i:%02i)</span>",
- global_config->osd->text.fonts_name[0], title, time_cur_m, time_cur_s,
- time_tot_m, time_tot_s);
-
- aosd_osd_display (markup, global_config->osd, FALSE);
- g_free (markup);
- str_unref (title);
-}
-
-
-/* Call with hook_call("aosd toggle", param);
- If param != NULL, display the supplied text in the OSD
- If param == NULL, display the current playing song */
-static void
-aosd_trigger_func_hook_cb ( gpointer markup_text , gpointer unused )
-{
- if ( markup_text != NULL )
- {
- /* Display text from caller */
- aosd_osd_display( markup_text , global_config->osd , FALSE );
- } else {
- /* Display currently playing song */
- aosd_trigger_func_pb_start_cb (NULL, NULL);
- }
-}
diff --git a/src/aosd/aosd_trigger.cc b/src/aosd/aosd_trigger.cc
new file mode 100644
index 000000000000..e9f3ee7f8074
--- /dev/null
+++ b/src/aosd/aosd_trigger.cc
@@ -0,0 +1,284 @@
+/*
+*
+* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+*/
+
+#include <glib.h>
+#include <string.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/hook.h>
+
+#include "aosd_trigger.h"
+#include "aosd_trigger_private.h"
+#include "aosd_cfg.h"
+#include "aosd_osd.h"
+
+/* prototypes of trigger functions */
+static void aosd_trigger_func_pb_start_onoff ( bool );
+static void aosd_trigger_func_pb_start_cb ( void * , void * );
+static void aosd_trigger_func_pb_titlechange_onoff ( bool );
+static void aosd_trigger_func_pb_titlechange_cb ( void * , void * );
+static void aosd_trigger_func_pb_pauseon_onoff ( bool );
+static void aosd_trigger_func_pb_pauseon_cb ( void * , void * );
+static void aosd_trigger_func_pb_pauseoff_onoff ( bool );
+static void aosd_trigger_func_pb_pauseoff_cb ( void * , void * );
+static void aosd_trigger_func_hook_cb ( void * markup_text , void * unused );
+
+/* map trigger codes to trigger objects */
+aosd_trigger_t aosd_triggers[] =
+{
+ // AOSD_TRIGGER_PB_START
+ { N_("Playback Start") ,
+ N_("Triggers OSD when a playlist entry is played.") ,
+ aosd_trigger_func_pb_start_onoff ,
+ aosd_trigger_func_pb_start_cb },
+
+ // AOSD_TRIGGER_PB_TITLECHANGE
+ { N_("Title Change") ,
+ N_("Triggers OSD when the song title changes (for internet streams).") ,
+ aosd_trigger_func_pb_titlechange_onoff ,
+ aosd_trigger_func_pb_titlechange_cb },
+
+ // AOSD_TRIGGER_PB_PAUSEON
+ { N_("Pause On") ,
+ N_("Triggers OSD when playback is paused.") ,
+ aosd_trigger_func_pb_pauseon_onoff ,
+ aosd_trigger_func_pb_pauseon_cb },
+
+ // AOSD_TRIGGER_PB_PAUSEOFF
+ { N_("Pause Off") ,
+ N_("Triggers OSD when playback is unpaused.") ,
+ aosd_trigger_func_pb_pauseoff_onoff ,
+ aosd_trigger_func_pb_pauseoff_cb }
+};
+
+static_assert (aud::n_elems (aosd_triggers) == AOSD_NUM_TRIGGERS, "update aosd_triggers");
+
+/* TRIGGER API */
+
+const char *
+aosd_trigger_get_name ( int trig_code )
+{
+ if (trig_code >= 0 && trig_code < aud::n_elems (aosd_triggers))
+ return aosd_triggers[trig_code].name;
+ return nullptr;
+}
+
+
+const char *
+aosd_trigger_get_desc ( int trig_code )
+{
+ if (trig_code >= 0 && trig_code < aud::n_elems (aosd_triggers))
+ return aosd_triggers[trig_code].desc;
+ return nullptr;
+}
+
+
+void aosd_trigger_start (const aosd_cfg_osd_trigger_t & cfg_trigger)
+{
+ for (int i = 0; i < AOSD_NUM_TRIGGERS; i ++)
+ {
+ if (cfg_trigger.enabled[i])
+ aosd_triggers[i].onoff_func (true);
+ }
+
+ /* When called, this hook will display the text of the user pointer
+ or the current playing song, if nullptr */
+ hook_associate( "aosd toggle" , aosd_trigger_func_hook_cb , nullptr );
+}
+
+
+void aosd_trigger_stop (const aosd_cfg_osd_trigger_t & cfg_trigger)
+{
+ hook_dissociate( "aosd toggle" , aosd_trigger_func_hook_cb );
+
+ for (int i = 0; i < AOSD_NUM_TRIGGERS; i ++)
+ {
+ if (cfg_trigger.enabled[i])
+ aosd_triggers[i].onoff_func (false);
+ }
+}
+
+
+/* TRIGGER FUNCTIONS */
+
+static void
+aosd_trigger_func_pb_start_onoff ( bool turn_on )
+{
+ if (turn_on == TRUE)
+ hook_associate("playback ready", aosd_trigger_func_pb_start_cb, nullptr);
+ else
+ hook_dissociate("playback ready", aosd_trigger_func_pb_start_cb);
+}
+
+static void
+aosd_trigger_func_pb_start_cb(void * hook_data, void * user_data)
+{
+ String title = aud_drct_get_title ();
+ char * markup = g_markup_printf_escaped ("<span font_desc='%s'>%s</span>",
+ (const char *) global_config.text.fonts_name[0], (const char *) title);
+
+ aosd_osd_display (markup, & global_config, FALSE);
+ g_free (markup);
+}
+
+typedef struct
+{
+ String title;
+ String filename;
+}
+aosd_pb_titlechange_prevs_t;
+
+static void
+aosd_trigger_func_pb_titlechange_onoff ( bool turn_on )
+{
+ static aosd_pb_titlechange_prevs_t *prevs = nullptr;
+
+ if ( turn_on == TRUE )
+ {
+ prevs = new aosd_pb_titlechange_prevs_t;
+ hook_associate( "title change" , aosd_trigger_func_pb_titlechange_cb , prevs );
+ }
+ else
+ {
+ hook_dissociate( "title change" , aosd_trigger_func_pb_titlechange_cb );
+ if ( prevs != nullptr )
+ {
+ delete prevs;
+ prevs = nullptr;
+ }
+ }
+}
+
+static void
+aosd_trigger_func_pb_titlechange_cb ( void * plentry_gp , void * prevs_gp )
+{
+ if (aud_drct_get_playing ())
+ {
+ aosd_pb_titlechange_prevs_t *prevs = (aosd_pb_titlechange_prevs_t *) prevs_gp;
+ String pl_entry_filename = aud_drct_get_filename ();
+ Tuple pl_entry_tuple = aud_drct_get_tuple ();
+ String pl_entry_title = pl_entry_tuple.get_str (Tuple::FormattedTitle);
+
+ /* same filename but title changed, useful to detect http stream song changes */
+
+ if ( ( prevs->title != nullptr ) && ( prevs->filename != nullptr ) )
+ {
+ if ( ( pl_entry_filename != nullptr ) && ( !strcmp(pl_entry_filename,prevs->filename) ) )
+ {
+ if ( ( pl_entry_title != nullptr ) && ( strcmp(pl_entry_title,prevs->title) ) )
+ {
+ /* string formatting is done here a.t.m. - TODO - improve this area */
+ char * markup = g_markup_printf_escaped
+ ("<span font_desc='%s'>%s</span>",
+ (const char *) global_config.text.fonts_name[0],
+ (const char *) pl_entry_title);
+
+ aosd_osd_display (markup, & global_config, FALSE);
+ g_free (markup);
+
+ prevs->title = pl_entry_title;
+ }
+ }
+ else
+ {
+ prevs->filename = pl_entry_filename;
+ /* if filename changes, reset title as well */
+ prevs->title = pl_entry_title;
+ }
+ }
+ else
+ {
+ prevs->title = pl_entry_title;
+ prevs->filename = pl_entry_filename;
+ }
+ }
+}
+
+static void
+aosd_trigger_func_pb_pauseon_onoff ( bool turn_on )
+{
+ if ( turn_on == TRUE )
+ hook_associate( "playback pause" , aosd_trigger_func_pb_pauseon_cb , nullptr );
+ else
+ hook_dissociate( "playback pause" , aosd_trigger_func_pb_pauseon_cb );
+}
+
+static void
+aosd_trigger_func_pb_pauseon_cb ( void * unused1 , void * unused2 )
+{
+ char * markup = g_markup_printf_escaped ("<span font_desc='%s'>Paused</span>",
+ (const char *) global_config.text.fonts_name[0]);
+ aosd_osd_display (markup, & global_config, FALSE);
+ g_free (markup);
+}
+
+
+static void
+aosd_trigger_func_pb_pauseoff_onoff ( bool turn_on )
+{
+ if ( turn_on == TRUE )
+ hook_associate( "playback unpause" , aosd_trigger_func_pb_pauseoff_cb , nullptr );
+ else
+ hook_dissociate( "playback unpause" , aosd_trigger_func_pb_pauseoff_cb );
+}
+
+static void
+aosd_trigger_func_pb_pauseoff_cb ( void * unused1 , void * unused2 )
+{
+ Tuple tuple = aud_drct_get_tuple ();
+ int time_cur, time_tot;
+ int time_cur_m, time_cur_s, time_tot_m, time_tot_s;
+
+ time_tot = tuple.get_int (Tuple::Length) / 1000;
+ time_cur = aud_drct_get_time() / 1000;
+ time_cur_s = time_cur % 60;
+ time_cur_m = (time_cur - time_cur_s) / 60;
+ time_tot_s = time_tot % 60;
+ time_tot_m = (time_tot - time_tot_s) / 60;
+
+ String title = tuple.get_str (Tuple::FormattedTitle);
+ char * markup = g_markup_printf_escaped
+ ("<span font_desc='%s'>%s (%i:%02i/%i:%02i)</span>",
+ (const char *) global_config.text.fonts_name[0], (const char *) title,
+ time_cur_m, time_cur_s, time_tot_m, time_tot_s);
+
+ aosd_osd_display (markup, & global_config, FALSE);
+ g_free (markup);
+}
+
+
+/* Call with hook_call("aosd toggle", param);
+ If param != nullptr, display the supplied text in the OSD
+ If param == nullptr, display the current playing song */
+static void
+aosd_trigger_func_hook_cb ( void * markup_text , void * unused )
+{
+ if ( markup_text != nullptr )
+ {
+ /* Display text from caller */
+ aosd_osd_display ((char *) markup_text, & global_config, FALSE);
+ } else {
+ /* Display currently playing song */
+ aosd_trigger_func_pb_start_cb (nullptr, nullptr);
+ }
+}
diff --git a/src/aosd/aosd_trigger.h b/src/aosd/aosd_trigger.h
index d317da9e8b1a..cd45562004f3 100644
--- a/src/aosd/aosd_trigger.h
+++ b/src/aosd/aosd_trigger.h
@@ -21,20 +21,12 @@
#ifndef _I_AOSD_TRIGGER_H
#define _I_AOSD_TRIGGER_H 1
-#undef PACKAGE
-#define PACKAGE "audacious-plugins"
-
-#include "aosd_common.h"
#include "aosd_cfg.h"
-#include <glib.h>
-
/* trigger public API */
-void aosd_trigger_get_codes_array ( gint ** , gint * );
-const gchar * aosd_trigger_get_name ( gint );
-const gchar * aosd_trigger_get_desc ( gint );
-void aosd_trigger_start ( aosd_cfg_osd_trigger_t * cfg_trigger );
-void aosd_trigger_stop ( aosd_cfg_osd_trigger_t * cfg_trigger );
-
+const char * aosd_trigger_get_name ( int );
+const char * aosd_trigger_get_desc ( int );
+void aosd_trigger_start (const aosd_cfg_osd_trigger_t & cfg_trigger);
+void aosd_trigger_stop (const aosd_cfg_osd_trigger_t & cfg_trigger);
#endif /* !_I_AOSD_TRIGGER_H */
diff --git a/src/aosd/aosd_trigger_private.h b/src/aosd/aosd_trigger_private.h
index 411e6bd814f7..0632598fd6c6 100644
--- a/src/aosd/aosd_trigger_private.h
+++ b/src/aosd/aosd_trigger_private.h
@@ -21,10 +21,6 @@
#ifndef _I_AOSD_TRIGGER_PRIVATE_H
#define _I_AOSD_TRIGGER_PRIVATE_H 1
-#include "aosd_common.h"
-#include <glib.h>
-
-
/* trigger object
----------------------------------------------------------
name name
@@ -34,12 +30,11 @@
*/
typedef struct
{
- const gchar * name;
- const gchar * desc;
- void (*onoff_func)( gboolean );
- void (*callback_func)( gpointer , gpointer );
+ const char * name;
+ const char * desc;
+ void (*onoff_func)( bool );
+ void (*callback_func)( void * , void * );
}
aosd_trigger_t;
-
#endif /* !_I_AOSD_TRIGGER_PRIVATE_H */
diff --git a/src/aosd/aosd_ui.c b/src/aosd/aosd_ui.c
deleted file mode 100644
index 9bf290ca0419..000000000000
--- a/src/aosd/aosd_ui.c
+++ /dev/null
@@ -1,977 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include <math.h>
-
-#include <gtk/gtk.h>
-
-#include <audacious/i18n.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "aosd_ui.h"
-#include "aosd_style.h"
-#include "aosd_trigger.h"
-#include "aosd_cfg.h"
-#include "aosd_osd.h"
-#include "aosd_common.h"
-
-extern aosd_cfg_t * global_config;
-extern gboolean plugin_is_active;
-
-
-static void chooser_get_aosd_color (GtkColorChooser * chooser, aosd_color_t * color)
-{
- GdkRGBA rgba;
- gtk_color_chooser_get_rgba (chooser, & rgba);
-
- color->red = rint (rgba.red * 65535.0);
- color->green = rint (rgba.green * 65535.0);
- color->blue = rint (rgba.blue * 65535.0);
- color->alpha = rint (rgba.alpha * 65535.0);
-}
-
-
-static void chooser_set_aosd_color (GtkColorChooser * chooser, const aosd_color_t * color)
-{
- GdkRGBA rgba =
- {
- .red = color->red / 65535.0,
- .green = color->green / 65535.0,
- .blue = color->blue / 65535.0,
- .alpha = color->alpha / 65535.0
- };
-
- gtk_color_chooser_set_use_alpha (chooser, TRUE);
- gtk_color_chooser_set_rgba (chooser, & rgba);
-}
-
-
-/*************************************************************/
-/* small callback system used by the configuration interface */
-typedef void (*aosd_ui_cb_func_t)( GtkWidget * , aosd_cfg_t * );
-
-typedef struct
-{
- aosd_ui_cb_func_t func;
- GtkWidget * widget;
-}
-aosd_ui_cb_t;
-
-static void
-aosd_callback_list_add ( GList ** list , GtkWidget * widget , aosd_ui_cb_func_t func )
-{
- aosd_ui_cb_t *cb = g_malloc(sizeof(aosd_ui_cb_t));
- cb->widget = widget;
- cb->func = func;
- *list = g_list_append( *list , cb );
-}
-
-static void
-aosd_callback_list_run ( GList * list , aosd_cfg_t * cfg )
-{
- while ( list != NULL )
- {
- aosd_ui_cb_t *cb = (aosd_ui_cb_t*)list->data;
- cb->func( cb->widget , cfg );
- list = g_list_next( list );
- }
-}
-
-static void
-aosd_callback_list_free ( GList * list )
-{
- GList *list_top = list;
- while ( list != NULL )
- {
- g_free( (aosd_ui_cb_t*)list->data );
- list = g_list_next( list );
- }
- g_list_free( list_top );
-}
-/*************************************************************/
-
-
-
-static gboolean
-aosd_cb_configure_position_expose ( GtkWidget * darea ,
- cairo_t * cr ,
- gpointer coord_gp )
-{
- gint coord = GPOINTER_TO_INT(coord_gp);
-
- cairo_set_source_rgb ( cr , 0 , 0 , 0 );
- cairo_rectangle ( cr , (coord % 3) * 10 , (coord / 3) * 16 , 20 , 8 );
- cairo_fill ( cr );
-
- return FALSE;
-}
-
-
-static void
-aosd_cb_configure_position_placement_commit ( GtkWidget * grid , aosd_cfg_t * cfg )
-{
- GList *placbt_list = gtk_container_get_children( GTK_CONTAINER(grid) );
- GList *list_iter = placbt_list;
-
- while ( list_iter != NULL )
- {
- GtkWidget *placbt = list_iter->data;
- if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(placbt) ) == TRUE )
- {
- cfg->osd->position.placement = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(placbt),"value"));
- break;
- }
- list_iter = g_list_next( list_iter );
- }
-
- g_list_free( placbt_list );
-}
-
-
-static void
-aosd_cb_configure_position_offset_commit ( GtkWidget * grid , aosd_cfg_t * cfg )
-{
- cfg->osd->position.offset_x = gtk_spin_button_get_value_as_int(
- GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(grid),"offx")) );
- cfg->osd->position.offset_y = gtk_spin_button_get_value_as_int(
- GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(grid),"offy")) );
-}
-
-
-static void
-aosd_cb_configure_position_maxsize_commit ( GtkWidget * grid , aosd_cfg_t * cfg )
-{
- cfg->osd->position.maxsize_width = gtk_spin_button_get_value_as_int(
- GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(grid),"maxsize_width")) );
-}
-
-
-static void
-aosd_cb_configure_position_multimon_commit ( GtkWidget * combo , aosd_cfg_t * cfg )
-{
- gint active = gtk_combo_box_get_active( GTK_COMBO_BOX(combo) );
- cfg->osd->position.multimon_id = ( active > -1 ) ? (active - 1) : -1;
-}
-
-
-static GtkWidget *
-aosd_ui_configure_position ( aosd_cfg_t * cfg , GList ** cb_list )
-{
- GtkWidget *pos_vbox;
- GtkWidget *pos_placement_frame, *pos_placement_hbox, *pos_placement_grid;
- GtkWidget *pos_placement_bt[9], *pos_placement_bt_darea[9];
- GtkWidget *pos_offset_grid, *pos_offset_x_label, *pos_offset_x_spinbt;
- GtkWidget *pos_offset_y_label, *pos_offset_y_spinbt;
- GtkWidget *pos_maxsize_width_label, *pos_maxsize_width_spinbt;
- GtkWidget *pos_multimon_frame, *pos_multimon_hbox;
- GtkWidget *pos_multimon_label;
- GtkWidget *pos_multimon_combobox;
- gint monitors_num = gdk_screen_get_n_monitors( gdk_screen_get_default() );
- gint i = 0;
-
- pos_vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 4 );
- gtk_container_set_border_width( GTK_CONTAINER(pos_vbox) , 6 );
-
- pos_placement_frame = gtk_frame_new( _("Placement") );
- pos_placement_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 0 );
- gtk_container_set_border_width( GTK_CONTAINER(pos_placement_hbox) , 6 );
- gtk_container_add( GTK_CONTAINER(pos_placement_frame) , pos_placement_hbox );
- gtk_box_pack_start( GTK_BOX(pos_vbox) , pos_placement_frame , FALSE , FALSE , 0 );
-
- pos_placement_grid = gtk_grid_new();
- for ( i = 0 ; i < 9 ; i++ )
- {
- if ( i == 0 )
- pos_placement_bt[i] = gtk_radio_button_new( NULL );
- else
- pos_placement_bt[i] = gtk_radio_button_new_from_widget( GTK_RADIO_BUTTON(pos_placement_bt[0]) );
- gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON(pos_placement_bt[i]) , FALSE );
- pos_placement_bt_darea[i] = gtk_drawing_area_new();
- gtk_widget_set_size_request( pos_placement_bt_darea[i] , 40 , 40 );
- gtk_container_add( GTK_CONTAINER(pos_placement_bt[i]) , pos_placement_bt_darea[i] );
- g_signal_connect( G_OBJECT(pos_placement_bt_darea[i]) , "draw" ,
- G_CALLBACK(aosd_cb_configure_position_expose) , GINT_TO_POINTER(i) );
- gtk_grid_attach( GTK_GRID(pos_placement_grid) , pos_placement_bt[i] , (i % 3) , (i / 3) , 1 , 1 );
- g_object_set_data( G_OBJECT(pos_placement_bt[i]) , "value" , GINT_TO_POINTER(i+1) );
- if ( cfg->osd->position.placement == (i+1) )
- gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pos_placement_bt[i]) , TRUE );
- }
- gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , pos_placement_grid , FALSE , FALSE , 0 );
- aosd_callback_list_add( cb_list , pos_placement_grid , aosd_cb_configure_position_placement_commit );
-
- gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , gtk_separator_new(GTK_ORIENTATION_VERTICAL) , FALSE , FALSE , 6 );
-
- pos_offset_grid = gtk_grid_new();
- gtk_grid_set_row_spacing( GTK_GRID(pos_offset_grid) , 4 );
- gtk_grid_set_column_spacing( GTK_GRID(pos_offset_grid) , 4 );
- pos_offset_x_label = gtk_label_new( _( "Relative X offset:" ) );
- gtk_misc_set_alignment( GTK_MISC(pos_offset_x_label) , 0 , 0.5 );
- gtk_grid_attach( GTK_GRID(pos_offset_grid) , pos_offset_x_label , 0 , 0 , 1 , 1 );
- pos_offset_x_spinbt = gtk_spin_button_new_with_range( -9999 , 9999 , 1 );
- gtk_spin_button_set_value( GTK_SPIN_BUTTON(pos_offset_x_spinbt) , cfg->osd->position.offset_x );
- gtk_grid_attach( GTK_GRID(pos_offset_grid) , pos_offset_x_spinbt , 1 , 0 , 1 , 1 );
- g_object_set_data( G_OBJECT(pos_offset_grid) , "offx" , pos_offset_x_spinbt );
- pos_offset_y_label = gtk_label_new( _( "Relative Y offset:" ) );
- gtk_misc_set_alignment( GTK_MISC(pos_offset_y_label) , 0 , 0.5 );
- gtk_grid_attach( GTK_GRID(pos_offset_grid) , pos_offset_y_label , 0 , 1 , 1 , 1 );
- pos_offset_y_spinbt = gtk_spin_button_new_with_range( -9999 , 9999 , 1 );
- gtk_spin_button_set_value( GTK_SPIN_BUTTON(pos_offset_y_spinbt) , cfg->osd->position.offset_y );
- gtk_grid_attach( GTK_GRID(pos_offset_grid) , pos_offset_y_spinbt , 1 , 1 , 1 , 1 );
- g_object_set_data( G_OBJECT(pos_offset_grid) , "offy" , pos_offset_y_spinbt );
- pos_maxsize_width_label = gtk_label_new( _("Max OSD width:") );
- gtk_misc_set_alignment( GTK_MISC(pos_maxsize_width_label) , 0 , 0.5 );
- gtk_grid_attach( GTK_GRID(pos_offset_grid) , pos_maxsize_width_label , 0 , 2 , 1 , 1 );
- pos_maxsize_width_spinbt = gtk_spin_button_new_with_range( 0 , 99999 , 1 );
- g_object_set_data( G_OBJECT(pos_offset_grid) , "maxsize_width" , pos_maxsize_width_spinbt );
- gtk_spin_button_set_value( GTK_SPIN_BUTTON(pos_maxsize_width_spinbt) , cfg->osd->position.maxsize_width );
- gtk_grid_attach( GTK_GRID(pos_offset_grid) , pos_maxsize_width_spinbt , 1 , 2 , 1 , 1 );
- gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , pos_offset_grid , FALSE , FALSE , 0 );
- aosd_callback_list_add( cb_list , pos_offset_grid , aosd_cb_configure_position_offset_commit );
- aosd_callback_list_add( cb_list , pos_offset_grid , aosd_cb_configure_position_maxsize_commit );
-
- pos_multimon_frame = gtk_frame_new( _("Multi-Monitor options") );
- pos_multimon_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
- gtk_container_set_border_width( GTK_CONTAINER(pos_multimon_hbox) , 6 );
- gtk_container_add( GTK_CONTAINER(pos_multimon_frame), pos_multimon_hbox );
- pos_multimon_label = gtk_label_new( _("Display OSD using:") );
- pos_multimon_combobox = gtk_combo_box_text_new ();
- gtk_combo_box_text_append_text ((GtkComboBoxText *) pos_multimon_combobox, _("all monitors"));
- for ( i = 0 ; i < monitors_num ; i++ )
- {
- gchar *mon_str = g_strdup_printf( _("monitor %i") , i + 1 );
- gtk_combo_box_text_append_text ((GtkComboBoxText *) pos_multimon_combobox, mon_str);
- g_free( mon_str );
- }
- gtk_combo_box_set_active( GTK_COMBO_BOX(pos_multimon_combobox) , (cfg->osd->position.multimon_id + 1) );
- aosd_callback_list_add( cb_list , pos_multimon_combobox , aosd_cb_configure_position_multimon_commit );
- gtk_box_pack_start( GTK_BOX(pos_multimon_hbox) , pos_multimon_label , FALSE , FALSE , 0 );
- gtk_box_pack_start( GTK_BOX(pos_multimon_hbox) , pos_multimon_combobox , FALSE , FALSE , 0 );
- gtk_box_pack_start( GTK_BOX(pos_vbox) , pos_multimon_frame , FALSE , FALSE , 0 );
-
- return pos_vbox;
-}
-
-
-static GtkWidget *
-aosd_ui_configure_animation_timing ( gchar * label_string )
-{
- GtkWidget *hbox, *desc_label, *spinbt;
- hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
- desc_label = gtk_label_new( label_string );
- spinbt = gtk_spin_button_new_with_range( 0 , 99999 , 1 );
- gtk_box_pack_start( GTK_BOX(hbox) , desc_label , FALSE , FALSE , 0 );
- gtk_box_pack_start( GTK_BOX(hbox) , spinbt , FALSE , FALSE , 0 );
- g_object_set_data( G_OBJECT(hbox) , "spinbt" , spinbt );
- return hbox;
-}
-
-
-static void
-aosd_cb_configure_animation_timing_commit ( GtkWidget * timing_hbox , aosd_cfg_t * cfg )
-{
- cfg->osd->animation.timing_display = gtk_spin_button_get_value_as_int(
- GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(timing_hbox),"display")) );
- cfg->osd->animation.timing_fadein = gtk_spin_button_get_value_as_int(
- GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(timing_hbox),"fadein")) );
- cfg->osd->animation.timing_fadeout = gtk_spin_button_get_value_as_int(
- GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(timing_hbox),"fadeout")) );
-}
-
-
-static GtkWidget *
-aosd_ui_configure_animation ( aosd_cfg_t * cfg , GList ** cb_list )
-{
- GtkWidget *ani_vbox;
- GtkWidget *ani_timing_frame, *ani_timing_hbox;
- GtkWidget *ani_timing_fadein_widget, *ani_timing_fadeout_widget, *ani_timing_stay_widget;
- GtkSizeGroup *sizegroup;
-
- ani_vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 0 );
- gtk_container_set_border_width( GTK_CONTAINER(ani_vbox) , 6 );
-
- ani_timing_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 0 );
- ani_timing_frame = gtk_frame_new( _("Timing (ms)") );
- gtk_container_set_border_width( GTK_CONTAINER(ani_timing_hbox) , 6 );
- gtk_container_add( GTK_CONTAINER(ani_timing_frame) , ani_timing_hbox );
- gtk_box_pack_start( GTK_BOX(ani_vbox) , ani_timing_frame , FALSE , FALSE , 0 );
-
- ani_timing_stay_widget = aosd_ui_configure_animation_timing( _("Display:") );
- gtk_spin_button_set_value( GTK_SPIN_BUTTON(g_object_get_data(
- G_OBJECT(ani_timing_stay_widget),"spinbt")) , cfg->osd->animation.timing_display );
- gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , ani_timing_stay_widget , TRUE , TRUE , 0 );
- gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , gtk_separator_new(GTK_ORIENTATION_VERTICAL) , FALSE , FALSE , 4 );
- ani_timing_fadein_widget = aosd_ui_configure_animation_timing( _("Fade in:") );
- gtk_spin_button_set_value( GTK_SPIN_BUTTON(g_object_get_data(
- G_OBJECT(ani_timing_fadein_widget),"spinbt")) , cfg->osd->animation.timing_fadein );
- gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , ani_timing_fadein_widget , TRUE , TRUE , 0 );
- gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , gtk_separator_new(GTK_ORIENTATION_VERTICAL) , FALSE , FALSE , 4 );
- ani_timing_fadeout_widget = aosd_ui_configure_animation_timing( _("Fade out:") );
- gtk_spin_button_set_value( GTK_SPIN_BUTTON(g_object_get_data(
- G_OBJECT(ani_timing_fadeout_widget),"spinbt")) , cfg->osd->animation.timing_fadeout );
- gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , ani_timing_fadeout_widget , TRUE , TRUE , 0 );
- g_object_set_data( G_OBJECT(ani_timing_hbox) , "display" ,
- g_object_get_data(G_OBJECT(ani_timing_stay_widget),"spinbt") );
- g_object_set_data( G_OBJECT(ani_timing_hbox) , "fadein" ,
- g_object_get_data(G_OBJECT(ani_timing_fadein_widget),"spinbt") );
- g_object_set_data( G_OBJECT(ani_timing_hbox) , "fadeout" ,
- g_object_get_data(G_OBJECT(ani_timing_fadeout_widget),"spinbt") );
- sizegroup = gtk_size_group_new( GTK_SIZE_GROUP_HORIZONTAL );
- gtk_size_group_add_widget( sizegroup , ani_timing_stay_widget );
- gtk_size_group_add_widget( sizegroup , ani_timing_fadein_widget );
- gtk_size_group_add_widget( sizegroup , ani_timing_fadeout_widget );
- aosd_callback_list_add( cb_list , ani_timing_hbox , aosd_cb_configure_animation_timing_commit );
-
- return ani_vbox;
-}
-
-
-static void
-aosd_cb_configure_text_font_shadow_toggle ( GtkToggleButton * shadow_togglebt ,
- gpointer shadow_colorbt )
-{
- if ( gtk_toggle_button_get_active( shadow_togglebt ) == TRUE )
- gtk_widget_set_sensitive( GTK_WIDGET(shadow_colorbt) , TRUE );
- else
- gtk_widget_set_sensitive( GTK_WIDGET(shadow_colorbt) , FALSE );
-}
-
-
-static void
-aosd_cb_configure_text_font_commit ( GtkWidget * fontbt , aosd_cfg_t * cfg )
-{
- gint fontnum = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(fontbt) , "fontnum" ));
- GtkColorChooser * chooser;
-
- str_unref (cfg->osd->text.fonts_name[fontnum]);
- cfg->osd->text.fonts_name[fontnum] =
- str_get (gtk_font_button_get_font_name (GTK_FONT_BUTTON (fontbt)));
-
- cfg->osd->text.fonts_draw_shadow[fontnum] = gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(fontbt),"use_shadow")) );
-
- chooser = g_object_get_data ((GObject *) fontbt, "color");
- chooser_get_aosd_color (chooser, & cfg->osd->text.fonts_color[fontnum]);
-
- chooser = g_object_get_data ((GObject *) fontbt, "shadow_color");
- chooser_get_aosd_color (chooser, & cfg->osd->text.fonts_shadow_color[fontnum]);
-}
-
-
-static GtkWidget *
-aosd_ui_configure_text ( aosd_cfg_t * cfg , GList ** cb_list )
-{
- GtkWidget *tex_vbox;
- GtkWidget *tex_font_grid, *tex_font_frame;
- GtkWidget *tex_font_label[3], *tex_font_fontbt[3];
- GtkWidget *tex_font_colorbt[3], *tex_font_shadow_togglebt[3];
- GtkWidget *tex_font_shadow_colorbt[3];
- gint i = 0;
-
- tex_vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 4 );
- gtk_container_set_border_width( GTK_CONTAINER(tex_vbox) , 6 );
-
- tex_font_frame = gtk_frame_new( _("Fonts") );
- tex_font_grid = gtk_grid_new();
- gtk_container_set_border_width( GTK_CONTAINER(tex_font_grid) , 6 );
- gtk_grid_set_row_spacing ( GTK_GRID(tex_font_grid) , 4 );
- gtk_grid_set_column_spacing ( GTK_GRID(tex_font_grid) , 4 );
- for ( i = 0 ; i < AOSD_TEXT_FONTS_NUM ; i++ )
- {
- gchar *label_str = g_strdup_printf( _("Font %i:") , i+1 );
- tex_font_label[i] = gtk_label_new( label_str );
- g_free( label_str );
- tex_font_fontbt[i] = gtk_font_button_new();
- gtk_font_button_set_show_style( GTK_FONT_BUTTON(tex_font_fontbt[i]) , TRUE );
- gtk_font_button_set_show_size( GTK_FONT_BUTTON(tex_font_fontbt[i]) , TRUE );
- gtk_font_button_set_use_font( GTK_FONT_BUTTON(tex_font_fontbt[i]) , FALSE );
- gtk_font_button_set_use_size( GTK_FONT_BUTTON(tex_font_fontbt[i]) , FALSE );
- gtk_font_button_set_font_name( GTK_FONT_BUTTON(tex_font_fontbt[i]) , cfg->osd->text.fonts_name[i] );
- gtk_widget_set_hexpand( tex_font_fontbt[i] , TRUE );
-
- tex_font_colorbt[i] = gtk_color_button_new ();
- chooser_set_aosd_color ((GtkColorChooser *) tex_font_colorbt[i],
- & cfg->osd->text.fonts_color[i]);
-
- tex_font_shadow_togglebt[i] = gtk_toggle_button_new_with_label( _("Shadow") );
- gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON(tex_font_shadow_togglebt[i]) , FALSE );
-
- tex_font_shadow_colorbt[i] = gtk_color_button_new ();
- chooser_set_aosd_color ((GtkColorChooser *) tex_font_shadow_colorbt[i],
- & cfg->osd->text.fonts_shadow_color[i]);
-
- gtk_widget_set_sensitive( tex_font_shadow_colorbt[i] , FALSE );
- g_signal_connect( G_OBJECT(tex_font_shadow_togglebt[i]) , "toggled" ,
- G_CALLBACK(aosd_cb_configure_text_font_shadow_toggle) ,
- tex_font_shadow_colorbt[i] );
- gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(tex_font_shadow_togglebt[i]) ,
- cfg->osd->text.fonts_draw_shadow[i] );
- gtk_grid_attach( GTK_GRID(tex_font_grid) , tex_font_label[i] , 0 , 0 , 1 , 1 );
- gtk_grid_attach( GTK_GRID(tex_font_grid) , tex_font_fontbt[i] , 1 , 0 , 1 , 1 );
- gtk_grid_attach( GTK_GRID(tex_font_grid) , tex_font_colorbt[i] , 2 , 0 , 1 , 1 );
- gtk_grid_attach( GTK_GRID(tex_font_grid) , tex_font_shadow_togglebt[i] , 3 , 0 , 1 , 1 );
- gtk_grid_attach( GTK_GRID(tex_font_grid) , tex_font_shadow_colorbt[i] , 4 , 0 , 1 , 1 );
- g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "fontnum" , GINT_TO_POINTER(i) );
- g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "color" , tex_font_colorbt[i] );
- g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "use_shadow" , tex_font_shadow_togglebt[i] );
- g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "shadow_color" , tex_font_shadow_colorbt[i] );
- aosd_callback_list_add( cb_list , tex_font_fontbt[i] , aosd_cb_configure_text_font_commit );
- }
- gtk_container_add( GTK_CONTAINER(tex_font_frame) , tex_font_grid );
- gtk_box_pack_start( GTK_BOX(tex_vbox) , tex_font_frame , FALSE , FALSE , 0 );
-
- return tex_vbox;
-}
-
-
-static void
-aosd_cb_configure_decoration_style_commit ( GtkWidget * lv , aosd_cfg_t * cfg )
-{
- GtkTreeSelection *sel = gtk_tree_view_get_selection( GTK_TREE_VIEW(lv) );
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- if ( gtk_tree_selection_get_selected( sel , &model , &iter ) == TRUE )
- {
- gint deco_code = 0;
- gtk_tree_model_get( model , &iter , 1 , &deco_code , -1 );
- cfg->osd->decoration.code = deco_code;
- }
-}
-
-
-static void
-aosd_cb_configure_decoration_color_commit ( GtkWidget * colorbt , aosd_cfg_t * cfg )
-{
- aosd_color_t color;
- chooser_get_aosd_color ((GtkColorChooser *) colorbt, & color);
-
- gint colnum = GPOINTER_TO_INT( g_object_get_data( G_OBJECT(colorbt) , "colnum" ) );
- g_array_insert_val( cfg->osd->decoration.colors , colnum , color );
-}
-
-
-static GtkWidget *
-aosd_ui_configure_decoration ( aosd_cfg_t * cfg , GList ** cb_list )
-{
- GtkWidget *dec_hbox;
- GtkWidget *dec_rstyle_lv, *dec_rstyle_lv_frame, *dec_rstyle_lv_sw;
- GtkListStore *dec_rstyle_store;
- GtkCellRenderer *dec_rstyle_lv_rndr_text;
- GtkTreeViewColumn *dec_rstyle_lv_col_desc;
- GtkTreeSelection *dec_rstyle_lv_sel;
- GtkTreeIter iter, iter_sel;
- GtkWidget *dec_rstyle_hbox;
- GtkWidget *dec_rstyleopts_frame, *dec_rstyleopts_grid;
- gint *deco_code_array, deco_code_array_size;
- gint colors_max_num = 0, i = 0;
-
- dec_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
- gtk_container_set_border_width( GTK_CONTAINER(dec_hbox) , 6 );
-
- /* decoration style model
- ---------------------------------------------
- G_TYPE_STRING -> decoration description
- G_TYPE_INT -> decoration code
- G_TYPE_INT -> number of user-definable colors
- ---------------------------------------------
- */
- dec_rstyle_store = gtk_list_store_new( 3 , G_TYPE_STRING , G_TYPE_INT , G_TYPE_INT );
- aosd_deco_style_get_codes_array ( &deco_code_array , &deco_code_array_size );
- for ( i = 0 ; i < deco_code_array_size ; i++ )
- {
- gint colors_num = aosd_deco_style_get_numcol( deco_code_array[i] );
- if ( colors_num > colors_max_num )
- colors_max_num = colors_num;
- gtk_list_store_append( dec_rstyle_store , &iter );
- gtk_list_store_set( dec_rstyle_store , &iter ,
- 0 , _(aosd_deco_style_get_desc( deco_code_array[i] )) ,
- 1 , deco_code_array[i] , 2 , colors_num , -1 );
- if ( deco_code_array[i] == cfg->osd->decoration.code )
- iter_sel = iter;
- }
-
- dec_rstyle_lv_frame = gtk_frame_new( NULL );
- dec_rstyle_lv = gtk_tree_view_new_with_model( GTK_TREE_MODEL(dec_rstyle_store) );
- g_object_unref( dec_rstyle_store );
- dec_rstyle_lv_sel = gtk_tree_view_get_selection( GTK_TREE_VIEW(dec_rstyle_lv) );
- gtk_tree_selection_set_mode( dec_rstyle_lv_sel , GTK_SELECTION_BROWSE );
-
- dec_rstyle_lv_rndr_text = gtk_cell_renderer_text_new();
- dec_rstyle_lv_col_desc = gtk_tree_view_column_new_with_attributes(
- _("Render Style") , dec_rstyle_lv_rndr_text , "text" , 0 , NULL );
- gtk_tree_view_append_column( GTK_TREE_VIEW(dec_rstyle_lv), dec_rstyle_lv_col_desc );
- dec_rstyle_lv_sw = gtk_scrolled_window_new( NULL , NULL );
- gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(dec_rstyle_lv_sw) ,
- GTK_POLICY_NEVER , GTK_POLICY_ALWAYS );
- gtk_container_add( GTK_CONTAINER(dec_rstyle_lv_sw) , dec_rstyle_lv );
- gtk_container_add( GTK_CONTAINER(dec_rstyle_lv_frame) , dec_rstyle_lv_sw );
-
- gtk_tree_selection_select_iter( dec_rstyle_lv_sel , &iter_sel );
- gtk_box_pack_start( GTK_BOX(dec_hbox) , dec_rstyle_lv_frame , FALSE , FALSE , 0 );
- aosd_callback_list_add( cb_list , dec_rstyle_lv , aosd_cb_configure_decoration_style_commit );
-
- dec_rstyle_hbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 4 );
- gtk_box_pack_start( GTK_BOX(dec_hbox) , dec_rstyle_hbox , TRUE , TRUE , 0 );
-
- /* in colors_max_num now there's the maximum number of colors used by decoration styles */
- dec_rstyleopts_frame = gtk_frame_new( _("Colors") );
- dec_rstyleopts_grid = gtk_grid_new();
- gtk_container_set_border_width( GTK_CONTAINER(dec_rstyleopts_grid) , 6 );
- gtk_grid_set_row_spacing( GTK_GRID(dec_rstyleopts_grid) , 4 );
- gtk_grid_set_column_spacing( GTK_GRID(dec_rstyleopts_grid) , 8 );
- gtk_container_add( GTK_CONTAINER(dec_rstyleopts_frame) , dec_rstyleopts_grid );
- for ( i = 0 ; i < colors_max_num ; i++ )
- {
- GtkWidget *hbox, *label;
- gchar *label_str = NULL;
- hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
- label_str = g_strdup_printf( _("Color %i:") , i+1 );
- label = gtk_label_new( label_str );
- g_free( label_str );
-
- GtkWidget * colorbt = gtk_color_button_new ();
- chooser_set_aosd_color ((GtkColorChooser *) colorbt,
- & g_array_index (cfg->osd->decoration.colors, aosd_color_t, i));
-
- gtk_box_pack_start( GTK_BOX(hbox) , label , FALSE , FALSE , 0 );
- gtk_box_pack_start( GTK_BOX(hbox) , colorbt , FALSE , FALSE , 0 );
- gtk_grid_attach( GTK_GRID(dec_rstyleopts_grid) , hbox , (i % 3) , (i / 3) , 1 , 1 );
- g_object_set_data( G_OBJECT(colorbt) , "colnum" , GINT_TO_POINTER(i) );
- aosd_callback_list_add( cb_list , colorbt , aosd_cb_configure_decoration_color_commit );
- }
- gtk_box_pack_start( GTK_BOX(dec_rstyle_hbox) , dec_rstyleopts_frame , FALSE , FALSE , 0 );
-
- return dec_hbox;
-}
-
-
-static void
-aosd_cb_configure_trigger_lvchanged ( GtkTreeSelection *sel , gpointer nb )
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- if ( gtk_tree_selection_get_selected( sel , &model , &iter ) == TRUE )
- {
- gint page_num = 0;
- gtk_tree_model_get( model , &iter , 2 , &page_num , -1 );
- gtk_notebook_set_current_page( GTK_NOTEBOOK(nb) , page_num );
- }
-}
-
-
-static gboolean
-aosd_cb_configure_trigger_findinarr ( GArray * array , gint value )
-{
- gint i = 0;
- for ( i = 0 ; i < array->len ; i++ )
- {
- if ( g_array_index( array , gint , i ) == value )
- return TRUE;
- }
- return FALSE;
-}
-
-
-static void
-aosd_cb_configure_trigger_commit ( GtkWidget * cbt , aosd_cfg_t * cfg )
-{
- if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(cbt) ) == TRUE )
- {
- gint value = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cbt),"code"));
- g_array_append_val( cfg->osd->trigger.active , value );
- }
-}
-
-
-static GtkWidget *
-aosd_ui_configure_trigger ( aosd_cfg_t * cfg , GList ** cb_list )
-{
- GtkWidget *tri_hbox;
- GtkWidget *tri_event_lv, *tri_event_lv_frame, *tri_event_lv_sw;
- GtkListStore *tri_event_store;
- GtkCellRenderer *tri_event_lv_rndr_text;
- GtkTreeViewColumn *tri_event_lv_col_desc;
- GtkTreeSelection *tri_event_lv_sel;
- GtkTreeIter iter;
- gint *trigger_code_array, trigger_code_array_size;
- GtkWidget *tri_event_nb;
- gint i = 0;
-
- tri_event_nb = gtk_notebook_new();
- gtk_notebook_set_tab_pos( GTK_NOTEBOOK(tri_event_nb) , GTK_POS_LEFT );
- gtk_notebook_set_show_tabs( GTK_NOTEBOOK(tri_event_nb) , FALSE );
- gtk_notebook_set_show_border( GTK_NOTEBOOK(tri_event_nb) , FALSE );
-
- tri_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
- gtk_container_set_border_width( GTK_CONTAINER(tri_hbox) , 6 );
-
- /* trigger model
- ---------------------------------------------
- G_TYPE_STRING -> trigger description
- G_TYPE_INT -> trigger code
- G_TYPE_INT -> gtk notebook page number
- ---------------------------------------------
- */
- tri_event_store = gtk_list_store_new( 3 , G_TYPE_STRING , G_TYPE_INT , G_TYPE_INT );
- aosd_trigger_get_codes_array ( &trigger_code_array , &trigger_code_array_size );
- for ( i = 0 ; i < trigger_code_array_size ; i ++ )
- {
- GtkWidget *frame, *vbox, *label, *checkbt;
- gtk_list_store_append( tri_event_store , &iter );
- gtk_list_store_set( tri_event_store , &iter ,
- 0 , _(aosd_trigger_get_name( trigger_code_array[i] )) ,
- 1 , trigger_code_array[i] , 2 , i , -1 );
- vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 0 );
- gtk_container_set_border_width( GTK_CONTAINER(vbox) , 6 );
- label = gtk_label_new( _(aosd_trigger_get_desc( trigger_code_array[i] )) );
- gtk_label_set_line_wrap( GTK_LABEL(label) , TRUE );
- gtk_label_set_max_width_chars( GTK_LABEL(label), 40 );
- gtk_misc_set_alignment( GTK_MISC(label) , 0.0 , 0.0 );
- checkbt = gtk_check_button_new_with_label( _("Enable trigger") );
- if ( aosd_cb_configure_trigger_findinarr( cfg->osd->trigger.active , trigger_code_array[i] ) )
- gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(checkbt) , TRUE );
- else
- gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(checkbt) , FALSE );
- gtk_box_pack_start( GTK_BOX(vbox) , checkbt , FALSE , FALSE , 0 );
- gtk_box_pack_start( GTK_BOX(vbox) , gtk_separator_new(GTK_ORIENTATION_HORIZONTAL) , FALSE , FALSE , 4 );
- gtk_box_pack_start( GTK_BOX(vbox) , label , FALSE , FALSE , 0 );
- frame = gtk_frame_new( NULL );
- gtk_container_add( GTK_CONTAINER(frame) , vbox );
- gtk_notebook_append_page( GTK_NOTEBOOK(tri_event_nb) , frame , NULL );
- g_object_set_data( G_OBJECT(checkbt) , "code" , GINT_TO_POINTER(trigger_code_array[i]) );
- aosd_callback_list_add( cb_list , checkbt , aosd_cb_configure_trigger_commit );
- }
-
- tri_event_lv_frame = gtk_frame_new( NULL );
- tri_event_lv = gtk_tree_view_new_with_model( GTK_TREE_MODEL(tri_event_store) );
- g_object_unref( tri_event_store );
- tri_event_lv_sel = gtk_tree_view_get_selection( GTK_TREE_VIEW(tri_event_lv) );
- gtk_tree_selection_set_mode( tri_event_lv_sel , GTK_SELECTION_BROWSE );
- g_signal_connect( G_OBJECT(tri_event_lv_sel) , "changed" ,
- G_CALLBACK(aosd_cb_configure_trigger_lvchanged) , tri_event_nb );
- if ( gtk_tree_model_get_iter_first( GTK_TREE_MODEL(tri_event_store) , &iter ) == TRUE )
- gtk_tree_selection_select_iter( tri_event_lv_sel , &iter );
-
- tri_event_lv_rndr_text = gtk_cell_renderer_text_new();
- tri_event_lv_col_desc = gtk_tree_view_column_new_with_attributes(
- _("Event") , tri_event_lv_rndr_text , "text" , 0 , NULL );
- gtk_tree_view_append_column( GTK_TREE_VIEW(tri_event_lv), tri_event_lv_col_desc );
- tri_event_lv_sw = gtk_scrolled_window_new( NULL , NULL );
- gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(tri_event_lv_sw) ,
- GTK_POLICY_NEVER , GTK_POLICY_ALWAYS );
- gtk_container_add( GTK_CONTAINER(tri_event_lv_sw) , tri_event_lv );
- gtk_container_add( GTK_CONTAINER(tri_event_lv_frame) , tri_event_lv_sw );
- gtk_tree_selection_select_iter( tri_event_lv_sel , &iter );
-
- gtk_box_pack_start( GTK_BOX(tri_hbox) , tri_event_lv_frame , FALSE , FALSE , 0 );
-
- gtk_box_pack_start( GTK_BOX(tri_hbox) , tri_event_nb , TRUE , TRUE , 0 );
-
- return tri_hbox;
-}
-
-
-#ifdef HAVE_XCOMPOSITE
-static void
-aosd_cb_configure_misc_transp_real_clicked ( GtkToggleButton * real_rbt , gpointer status_hbox )
-{
- GtkWidget *img = g_object_get_data( G_OBJECT(status_hbox) , "img" );
- GtkWidget *label = g_object_get_data( G_OBJECT(status_hbox) , "label" );
- if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(real_rbt) ) )
- {
- if ( aosd_osd_check_composite_mgr() )
- {
- gtk_image_set_from_icon_name( GTK_IMAGE(img) , "face-smile" , GTK_ICON_SIZE_MENU );
- gtk_label_set_text( GTK_LABEL(label) , _("Composite manager detected") );
- gtk_widget_set_sensitive( GTK_WIDGET(status_hbox) , TRUE );
- }
- else
- {
- gtk_image_set_from_icon_name( GTK_IMAGE(img) , "dialog-warning" , GTK_ICON_SIZE_MENU );
- gtk_label_set_text( GTK_LABEL(label) ,
- _("Composite manager not detected;\nunless you know that you have one running, "
- "please activate a composite manager otherwise the OSD won't work properly") );
- gtk_widget_set_sensitive( GTK_WIDGET(status_hbox) , TRUE );
- }
- }
- else
- {
- gtk_image_set_from_icon_name( GTK_IMAGE(img) , "dialog-information" , GTK_ICON_SIZE_MENU );
- gtk_label_set_text( GTK_LABEL(label) , _("Composite manager not required for fake transparency") );
- gtk_widget_set_sensitive( GTK_WIDGET(status_hbox) , FALSE );
- }
-}
-#endif
-
-
-static void
-aosd_cb_configure_misc_transp_commit ( GtkWidget * mis_transp_vbox , aosd_cfg_t * cfg )
-{
- GList *child_list = gtk_container_get_children( GTK_CONTAINER(mis_transp_vbox) );
- while (child_list != NULL)
- {
- if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(child_list->data) ) )
- {
- cfg->osd->misc.transparency_mode = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(child_list->data),"val"));
- break;
- }
- child_list = g_list_next(child_list);
- }
-}
-
-
-static GtkWidget *
-aosd_ui_configure_misc ( aosd_cfg_t * cfg , GList ** cb_list )
-{
- GtkWidget *mis_vbox;
- GtkWidget *mis_transp_frame, *mis_transp_vbox;
- GtkWidget *mis_transp_fake_rbt, *mis_transp_real_rbt;
- GtkWidget *mis_transp_status_frame, *mis_transp_status_hbox;
- GtkWidget *mis_transp_status_img, *mis_transp_status_label;
-
- mis_vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 0 );
- gtk_container_set_border_width( GTK_CONTAINER(mis_vbox) , 6 );
-
- mis_transp_vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , 0 );
- mis_transp_frame = gtk_frame_new( _("Transparency") );
- gtk_container_set_border_width( GTK_CONTAINER(mis_transp_vbox) , 6 );
- gtk_container_add( GTK_CONTAINER(mis_transp_frame) , mis_transp_vbox );
- gtk_box_pack_start( GTK_BOX(mis_vbox) , mis_transp_frame , FALSE , FALSE , 0 );
-
- mis_transp_fake_rbt = gtk_radio_button_new_with_label( NULL ,
- _("Fake transparency") );
- mis_transp_real_rbt = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(mis_transp_fake_rbt) ,
- _("Real transparency (requires X Composite Ext.)") );
- g_object_set_data( G_OBJECT(mis_transp_fake_rbt) , "val" ,
- GINT_TO_POINTER(AOSD_MISC_TRANSPARENCY_FAKE) );
- g_object_set_data( G_OBJECT(mis_transp_real_rbt) , "val" ,
- GINT_TO_POINTER(AOSD_MISC_TRANSPARENCY_REAL) );
- gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_fake_rbt , TRUE , TRUE , 0 );
- gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_real_rbt , TRUE , TRUE , 0 );
-
- mis_transp_status_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
- mis_transp_status_frame = gtk_frame_new( NULL );
- gtk_container_set_border_width( GTK_CONTAINER(mis_transp_status_hbox) , 3 );
- gtk_container_add( GTK_CONTAINER(mis_transp_status_frame) , mis_transp_status_hbox );
- gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_status_frame , TRUE , TRUE , 0 );
-
- mis_transp_status_img = gtk_image_new();
- gtk_misc_set_alignment( GTK_MISC(mis_transp_status_img) , 0.5 , 0 );
- mis_transp_status_label = gtk_label_new( "" );
- gtk_misc_set_alignment( GTK_MISC(mis_transp_status_label) , 0 , 0.5 );
- gtk_label_set_line_wrap( GTK_LABEL(mis_transp_status_label) , TRUE );
- gtk_box_pack_start( GTK_BOX(mis_transp_status_hbox) , mis_transp_status_img , FALSE , FALSE , 0 );
- gtk_box_pack_start( GTK_BOX(mis_transp_status_hbox) , mis_transp_status_label , TRUE , TRUE , 0 );
- g_object_set_data( G_OBJECT(mis_transp_status_hbox) , "img" , mis_transp_status_img );
- g_object_set_data( G_OBJECT(mis_transp_status_hbox) , "label" , mis_transp_status_label );
-
-#ifdef HAVE_XCOMPOSITE
- g_signal_connect( G_OBJECT(mis_transp_real_rbt) , "toggled" ,
- G_CALLBACK(aosd_cb_configure_misc_transp_real_clicked) , mis_transp_status_hbox );
-
- /* check if the composite extension is loaded */
- if ( aosd_osd_check_composite_ext() )
- {
- if ( cfg->osd->misc.transparency_mode == AOSD_MISC_TRANSPARENCY_FAKE )
- gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_fake_rbt) , TRUE );
- else
- gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_real_rbt) , TRUE );
- }
- else
- {
- gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_fake_rbt) , TRUE );
- gtk_widget_set_sensitive( GTK_WIDGET(mis_transp_real_rbt) , FALSE );
- gtk_image_set_from_icon_name( GTK_IMAGE(mis_transp_status_img) ,
- "dialog-error" , GTK_ICON_SIZE_MENU );
- gtk_label_set_text( GTK_LABEL(mis_transp_status_label) , _("Composite extension not loaded") );
- gtk_widget_set_sensitive( GTK_WIDGET(mis_transp_status_hbox) , FALSE );
- }
-#else
- gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_fake_rbt) , TRUE );
- gtk_widget_set_sensitive( GTK_WIDGET(mis_transp_real_rbt) , FALSE );
- gtk_image_set_from_icon_name( GTK_IMAGE(mis_transp_status_img) ,
- "dialog-error" , GTK_ICON_SIZE_MENU );
- gtk_label_set_text( GTK_LABEL(mis_transp_status_label) , _("Composite extension not available") );
- gtk_widget_set_sensitive( GTK_WIDGET(mis_transp_status_hbox) , FALSE );
-#endif
-
- aosd_callback_list_add( cb_list , mis_transp_vbox , aosd_cb_configure_misc_transp_commit );
-
- return mis_vbox;
-}
-
-
-static void
-aosd_cb_configure_test ( gpointer cfg_win )
-{
- gchar *markup_message = NULL;
- aosd_cfg_t *cfg = aosd_cfg_new();
- GList *cb_list = g_object_get_data( G_OBJECT(cfg_win) , "cblist" );
- aosd_callback_list_run( cb_list , cfg );
- cfg->set = TRUE;
- markup_message = g_markup_printf_escaped(
- _("<span font_desc='%s'>Audacious OSD</span>") , cfg->osd->text.fonts_name[0] );
- aosd_osd_shutdown(); /* stop any displayed osd */
- aosd_osd_cleanup(); /* just in case it's active */
- aosd_osd_init( cfg->osd->misc.transparency_mode );
- aosd_osd_display( markup_message , cfg->osd , TRUE );
- g_free( markup_message );
- aosd_cfg_delete( cfg );
-}
-
-
-static void
-aosd_cb_configure_cancel ( gpointer cfg_win )
-{
- GList *cb_list = g_object_get_data( G_OBJECT(cfg_win) , "cblist" );
- aosd_callback_list_free( cb_list );
- aosd_osd_shutdown(); /* stop any displayed osd */
- aosd_osd_cleanup(); /* just in case it's active */
- if ( plugin_is_active == TRUE )
- aosd_osd_init( global_config->osd->misc.transparency_mode );
- gtk_widget_destroy( GTK_WIDGET(cfg_win) );
-}
-
-
-static void
-aosd_cb_configure_ok ( gpointer cfg_win )
-{
- //gchar *markup_message = NULL;
- aosd_cfg_t *cfg = aosd_cfg_new();
- GList *cb_list = g_object_get_data( G_OBJECT(cfg_win) , "cblist" );
- aosd_callback_list_run( cb_list , cfg );
- cfg->set = TRUE;
- aosd_osd_shutdown(); /* stop any displayed osd */
- aosd_osd_cleanup(); /* just in case it's active */
-
- if ( global_config != NULL )
- {
- /* plugin is active */
- aosd_trigger_stop( &global_config->osd->trigger ); /* stop triggers */
- aosd_cfg_delete( global_config ); /* delete old global_config */
- global_config = cfg; /* put the new one */
- aosd_cfg_save( cfg ); /* save the new configuration on config file */
- aosd_osd_init( cfg->osd->misc.transparency_mode ); /* restart osd */
- aosd_trigger_start( &cfg->osd->trigger ); /* restart triggers */
- }
- else
- {
- /* plugin is not active */
- aosd_cfg_save( cfg ); /* save the new configuration on config file */
- }
- aosd_callback_list_free( cb_list );
- gtk_widget_destroy( GTK_WIDGET(cfg_win) );
-}
-
-
-void
-aosd_ui_configure ( aosd_cfg_t * cfg )
-{
- static GtkWidget *cfg_win = NULL;
- GtkWidget *cfg_vbox;
- GtkWidget *cfg_nb;
- GtkWidget *cfg_bbar_hbbox;
- GtkWidget *cfg_bbar_bt_ok, *cfg_bbar_bt_test, *cfg_bbar_bt_cancel;
- GtkWidget *cfg_position_widget;
- GtkWidget *cfg_animation_widget;
- GtkWidget *cfg_text_widget;
- GtkWidget *cfg_decoration_widget;
- GtkWidget *cfg_trigger_widget;
- GdkGeometry cfg_win_hints;
- GList *cb_list = NULL; /* list of custom callbacks */
-
- if ( cfg_win != NULL )
- gtk_window_present( GTK_WINDOW(cfg_win) );
-
- cfg_win = gtk_window_new( GTK_WINDOW_TOPLEVEL );
- gtk_window_set_type_hint( GTK_WINDOW(cfg_win), GDK_WINDOW_TYPE_HINT_DIALOG );
- gtk_window_set_title( GTK_WINDOW(cfg_win) , _("Audacious OSD - configuration") );
- gtk_container_set_border_width( GTK_CONTAINER(cfg_win), 10 );
- g_signal_connect( G_OBJECT(cfg_win) , "destroy" ,
- G_CALLBACK(gtk_widget_destroyed) , &cfg_win );
- cfg_win_hints.min_width = -1;
- cfg_win_hints.min_height = 350;
- gtk_window_set_geometry_hints( GTK_WINDOW(cfg_win) , GTK_WIDGET(cfg_win) ,
- &cfg_win_hints , GDK_HINT_MIN_SIZE );
-
- cfg_vbox = gtk_box_new( GTK_ORIENTATION_VERTICAL , FALSE );
- gtk_container_add( GTK_CONTAINER(cfg_win) , cfg_vbox );
-
- cfg_nb = gtk_notebook_new();
- gtk_notebook_set_tab_pos( GTK_NOTEBOOK(cfg_nb) , GTK_POS_TOP );
- gtk_box_pack_start( GTK_BOX(cfg_vbox) , cfg_nb , TRUE , TRUE , 0 );
-
- gtk_box_pack_start( GTK_BOX(cfg_vbox) , gtk_separator_new(GTK_ORIENTATION_HORIZONTAL) , FALSE , FALSE , 4 );
-
- cfg_bbar_hbbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
- gtk_button_box_set_layout( GTK_BUTTON_BOX(cfg_bbar_hbbox) , GTK_BUTTONBOX_START );
- gtk_box_pack_start( GTK_BOX(cfg_vbox) , cfg_bbar_hbbox , FALSE , FALSE , 0 );
- cfg_bbar_bt_test = audgui_button_new (_("_Test"), "media-playback-start", NULL, NULL);
- gtk_container_add( GTK_CONTAINER(cfg_bbar_hbbox) , cfg_bbar_bt_test );
- gtk_button_box_set_child_secondary( GTK_BUTTON_BOX(cfg_bbar_hbbox) , cfg_bbar_bt_test , FALSE );
- cfg_bbar_bt_cancel = audgui_button_new (_("_Cancel"), "process-stop", NULL, NULL);
- gtk_container_add( GTK_CONTAINER(cfg_bbar_hbbox) , cfg_bbar_bt_cancel );
- gtk_button_box_set_child_secondary( GTK_BUTTON_BOX(cfg_bbar_hbbox) , cfg_bbar_bt_cancel , TRUE );
- cfg_bbar_bt_ok = audgui_button_new (_("_Set"), "system-run", NULL, NULL);
- gtk_container_add( GTK_CONTAINER(cfg_bbar_hbbox) , cfg_bbar_bt_ok );
- gtk_button_box_set_child_secondary( GTK_BUTTON_BOX(cfg_bbar_hbbox) , cfg_bbar_bt_ok , TRUE );
-
- /* add POSITION page */
- cfg_position_widget = aosd_ui_configure_position( cfg , &cb_list );
- gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
- cfg_position_widget , gtk_label_new( _("Position") ) );
-
- /* add ANIMATION page */
- cfg_animation_widget = aosd_ui_configure_animation( cfg , &cb_list );
- gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
- cfg_animation_widget , gtk_label_new( _("Animation") ) );
-
- /* add TEXT page */
- cfg_text_widget = aosd_ui_configure_text( cfg , &cb_list );
- gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
- cfg_text_widget , gtk_label_new( _("Text") ) );
-
- /* add DECORATION page */
- cfg_decoration_widget = aosd_ui_configure_decoration( cfg , &cb_list );
- gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
- cfg_decoration_widget , gtk_label_new( _("Decoration") ) );
-
- /* add TRIGGER page */
- cfg_trigger_widget = aosd_ui_configure_trigger( cfg , &cb_list );
- gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
- cfg_trigger_widget , gtk_label_new( _("Trigger") ) );
-
- /* add MISC page */
- cfg_trigger_widget = aosd_ui_configure_misc( cfg , &cb_list );
- gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
- cfg_trigger_widget , gtk_label_new( _("Misc") ) );
-
- g_object_set_data( G_OBJECT(cfg_win) , "cblist" , cb_list );
-
- g_signal_connect_swapped( G_OBJECT(cfg_bbar_bt_test) , "clicked" ,
- G_CALLBACK(aosd_cb_configure_test) , cfg_win );
- g_signal_connect_swapped( G_OBJECT(cfg_bbar_bt_cancel) , "clicked" ,
- G_CALLBACK(aosd_cb_configure_cancel) , cfg_win );
- g_signal_connect_swapped( G_OBJECT(cfg_bbar_bt_ok) , "clicked" ,
- G_CALLBACK(aosd_cb_configure_ok) , cfg_win );
-
- gtk_widget_show_all( cfg_win );
-}
diff --git a/src/aosd/aosd_ui.cc b/src/aosd/aosd_ui.cc
new file mode 100644
index 000000000000..306d5228ac51
--- /dev/null
+++ b/src/aosd/aosd_ui.cc
@@ -0,0 +1,886 @@
+/*
+*
+* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation; either version 2 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+*/
+
+#include <math.h>
+
+#include <gtk/gtk.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/index.h>
+#include <libaudcore/preferences.h>
+
+#include "aosd.h"
+#include "aosd_style.h"
+#include "aosd_trigger.h"
+#include "aosd_cfg.h"
+#include "aosd_osd.h"
+
+
+static void chooser_get_aosd_color (GtkColorButton * chooser, aosd_color_t * color)
+{
+ GdkColor gdk_color;
+ gtk_color_button_get_color (chooser, & gdk_color);
+
+ color->red = gdk_color.red;
+ color->green = gdk_color.green;
+ color->blue = gdk_color.blue;
+ color->alpha = gtk_color_button_get_alpha (chooser);
+}
+
+
+static void chooser_set_aosd_color (GtkColorButton * chooser, const aosd_color_t * color)
+{
+ GdkColor gdk_color = {0, (uint16_t) color->red, (uint16_t) color->green, (uint16_t) color->blue};
+
+ gtk_color_button_set_color (chooser, & gdk_color);
+ gtk_color_button_set_use_alpha (chooser, TRUE);
+ gtk_color_button_set_alpha (chooser, color->alpha);
+}
+
+
+/*************************************************************/
+/* small callback system used by the configuration interface */
+typedef void (*aosd_ui_cb_func_t)( GtkWidget * , aosd_cfg_t * );
+
+typedef struct
+{
+ GtkWidget * widget;
+ aosd_ui_cb_func_t func;
+}
+aosd_ui_cb_t;
+
+static Index<aosd_ui_cb_t> aosd_cb_list;
+
+static void
+aosd_callback_list_run ( aosd_cfg_t * cfg )
+{
+ for (const aosd_ui_cb_t & cb : aosd_cb_list)
+ cb.func (cb.widget, cfg);
+}
+/*************************************************************/
+
+
+
+static gboolean
+aosd_cb_configure_position_expose ( GtkWidget * darea ,
+ GdkEventExpose * event ,
+ void * coord_gp )
+{
+ int coord = GPOINTER_TO_INT(coord_gp);
+
+ cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (darea));
+ cairo_set_source_rgb ( cr , 0 , 0 , 0 );
+ cairo_rectangle ( cr , (coord % 3) * 10 , (coord / 3) * 16 , 20 , 8 );
+ cairo_fill ( cr );
+ cairo_destroy (cr);
+
+ return FALSE;
+}
+
+
+static void
+aosd_cb_configure_position_placement_commit ( GtkWidget * grid , aosd_cfg_t * cfg )
+{
+ GList *placbt_list = gtk_container_get_children( GTK_CONTAINER(grid) );
+ GList *list_iter = placbt_list;
+
+ while ( list_iter != nullptr )
+ {
+ GtkWidget *placbt = (GtkWidget *) list_iter->data;
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(placbt) ) == TRUE )
+ {
+ cfg->position.placement = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(placbt),"value"));
+ break;
+ }
+ list_iter = g_list_next( list_iter );
+ }
+
+ g_list_free( placbt_list );
+}
+
+
+static void
+aosd_cb_configure_position_offset_commit ( GtkWidget * grid , aosd_cfg_t * cfg )
+{
+ cfg->position.offset_x = gtk_spin_button_get_value_as_int(
+ GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(grid),"offx")) );
+ cfg->position.offset_y = gtk_spin_button_get_value_as_int(
+ GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(grid),"offy")) );
+}
+
+
+static void
+aosd_cb_configure_position_maxsize_commit ( GtkWidget * grid , aosd_cfg_t * cfg )
+{
+ cfg->position.maxsize_width = gtk_spin_button_get_value_as_int(
+ GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(grid),"maxsize_width")) );
+}
+
+
+static void
+aosd_cb_configure_position_multimon_commit ( GtkWidget * combo , aosd_cfg_t * cfg )
+{
+ int active = gtk_combo_box_get_active( GTK_COMBO_BOX(combo) );
+ cfg->position.multimon_id = ( active > -1 ) ? (active - 1) : -1;
+}
+
+
+static GtkWidget *
+aosd_ui_configure_position ( aosd_cfg_t * cfg )
+{
+ GtkWidget *pos_vbox;
+ GtkWidget *pos_placement_frame, *pos_placement_hbox, *pos_placement_grid;
+ GtkWidget *pos_placement_bt[9], *pos_placement_bt_darea[9];
+ GtkWidget *pos_offset_grid, *pos_offset_x_label, *pos_offset_x_spinbt;
+ GtkWidget *pos_offset_y_label, *pos_offset_y_spinbt;
+ GtkWidget *pos_maxsize_width_label, *pos_maxsize_width_spinbt;
+ GtkWidget *pos_multimon_frame, *pos_multimon_hbox;
+ GtkWidget *pos_multimon_label;
+ GtkWidget *pos_multimon_combobox;
+ int monitors_num = gdk_screen_get_n_monitors( gdk_screen_get_default() );
+ int i = 0;
+
+ pos_vbox = gtk_vbox_new( FALSE , 4 );
+ gtk_container_set_border_width( GTK_CONTAINER(pos_vbox) , 6 );
+
+ pos_placement_frame = gtk_frame_new( _("Placement") );
+ pos_placement_hbox = gtk_hbox_new( FALSE , 0 );
+ gtk_container_set_border_width( GTK_CONTAINER(pos_placement_hbox) , 6 );
+ gtk_container_add( GTK_CONTAINER(pos_placement_frame) , pos_placement_hbox );
+ gtk_box_pack_start( GTK_BOX(pos_vbox) , pos_placement_frame , FALSE , FALSE , 0 );
+
+ pos_placement_grid = gtk_table_new (0, 0, FALSE);
+ for ( i = 0 ; i < 9 ; i++ )
+ {
+ if ( i == 0 )
+ pos_placement_bt[i] = gtk_radio_button_new( nullptr );
+ else
+ pos_placement_bt[i] = gtk_radio_button_new_from_widget( GTK_RADIO_BUTTON(pos_placement_bt[0]) );
+ gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON(pos_placement_bt[i]) , FALSE );
+ pos_placement_bt_darea[i] = gtk_drawing_area_new();
+ gtk_widget_set_size_request( pos_placement_bt_darea[i] , 40 , 40 );
+ gtk_container_add( GTK_CONTAINER(pos_placement_bt[i]) , pos_placement_bt_darea[i] );
+ g_signal_connect( G_OBJECT(pos_placement_bt_darea[i]) , "expose-event" ,
+ G_CALLBACK(aosd_cb_configure_position_expose) , GINT_TO_POINTER(i) );
+ gtk_table_attach_defaults( GTK_TABLE(pos_placement_grid) , pos_placement_bt[i] ,
+ (i % 3) , (i % 3) + 1 , (i / 3) , (i / 3) + 1 );
+ g_object_set_data( G_OBJECT(pos_placement_bt[i]) , "value" , GINT_TO_POINTER(i+1) );
+ if ( cfg->position.placement == (i+1) )
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pos_placement_bt[i]) , TRUE );
+ }
+ gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , pos_placement_grid , FALSE , FALSE , 0 );
+ aosd_cb_list.append( pos_placement_grid , aosd_cb_configure_position_placement_commit );
+
+ gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , gtk_vseparator_new() , FALSE , FALSE , 6 );
+
+ pos_offset_grid = gtk_table_new (0, 0, FALSE);
+ gtk_table_set_row_spacings( GTK_TABLE(pos_offset_grid) , 4 );
+ gtk_table_set_col_spacings( GTK_TABLE(pos_offset_grid) , 4 );
+ pos_offset_x_label = gtk_label_new( _( "Relative X offset:" ) );
+ gtk_misc_set_alignment( GTK_MISC(pos_offset_x_label) , 0 , 0.5 );
+ gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_offset_x_label , 0 , 1 , 0 , 1 );
+ pos_offset_x_spinbt = gtk_spin_button_new_with_range( -9999 , 9999 , 1 );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON(pos_offset_x_spinbt) , cfg->position.offset_x );
+ gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_offset_x_spinbt , 1 , 2 , 0 , 1 );
+ g_object_set_data( G_OBJECT(pos_offset_grid) , "offx" , pos_offset_x_spinbt );
+ pos_offset_y_label = gtk_label_new( _( "Relative Y offset:" ) );
+ gtk_misc_set_alignment( GTK_MISC(pos_offset_y_label) , 0 , 0.5 );
+ gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_offset_y_label , 0 , 1 , 1 , 2 );
+ pos_offset_y_spinbt = gtk_spin_button_new_with_range( -9999 , 9999 , 1 );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON(pos_offset_y_spinbt) , cfg->position.offset_y );
+ gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_offset_y_spinbt , 1 , 2 , 1 , 2 );
+ g_object_set_data( G_OBJECT(pos_offset_grid) , "offy" , pos_offset_y_spinbt );
+ pos_maxsize_width_label = gtk_label_new( _("Max OSD width:") );
+ gtk_misc_set_alignment( GTK_MISC(pos_maxsize_width_label) , 0 , 0.5 );
+ gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_maxsize_width_label , 0 , 1 , 2 , 3 );
+ pos_maxsize_width_spinbt = gtk_spin_button_new_with_range( 0 , 99999 , 1 );
+ g_object_set_data( G_OBJECT(pos_offset_grid) , "maxsize_width" , pos_maxsize_width_spinbt );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON(pos_maxsize_width_spinbt) , cfg->position.maxsize_width );
+ gtk_table_attach_defaults( GTK_TABLE(pos_offset_grid) , pos_maxsize_width_spinbt , 1 , 2 , 2 , 3 );
+ gtk_box_pack_start( GTK_BOX(pos_placement_hbox) , pos_offset_grid , FALSE , FALSE , 0 );
+ aosd_cb_list.append( pos_offset_grid , aosd_cb_configure_position_offset_commit );
+ aosd_cb_list.append( pos_offset_grid , aosd_cb_configure_position_maxsize_commit );
+
+ pos_multimon_frame = gtk_frame_new( _("Multi-Monitor options") );
+ pos_multimon_hbox = gtk_hbox_new( FALSE , 4 );
+ gtk_container_set_border_width( GTK_CONTAINER(pos_multimon_hbox) , 6 );
+ gtk_container_add( GTK_CONTAINER(pos_multimon_frame), pos_multimon_hbox );
+ pos_multimon_label = gtk_label_new( _("Display OSD using:") );
+ pos_multimon_combobox = gtk_combo_box_text_new ();
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) pos_multimon_combobox, _("all monitors"));
+ for ( i = 0 ; i < monitors_num ; i++ )
+ {
+ char *mon_str = g_strdup_printf( _("monitor %i") , i + 1 );
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) pos_multimon_combobox, mon_str);
+ g_free( mon_str );
+ }
+ gtk_combo_box_set_active( GTK_COMBO_BOX(pos_multimon_combobox) , (cfg->position.multimon_id + 1) );
+ aosd_cb_list.append( pos_multimon_combobox , aosd_cb_configure_position_multimon_commit );
+ gtk_box_pack_start( GTK_BOX(pos_multimon_hbox) , pos_multimon_label , FALSE , FALSE , 0 );
+ gtk_box_pack_start( GTK_BOX(pos_multimon_hbox) , pos_multimon_combobox , FALSE , FALSE , 0 );
+ gtk_box_pack_start( GTK_BOX(pos_vbox) , pos_multimon_frame , FALSE , FALSE , 0 );
+
+ return pos_vbox;
+}
+
+
+static GtkWidget *
+aosd_ui_configure_animation_timing ( char * label_string )
+{
+ GtkWidget *hbox, *desc_label, *spinbt;
+ hbox = gtk_hbox_new( FALSE , 4 );
+ desc_label = gtk_label_new( label_string );
+ spinbt = gtk_spin_button_new_with_range( 0 , 99999 , 1 );
+ gtk_box_pack_start( GTK_BOX(hbox) , desc_label , FALSE , FALSE , 0 );
+ gtk_box_pack_start( GTK_BOX(hbox) , spinbt , FALSE , FALSE , 0 );
+ g_object_set_data( G_OBJECT(hbox) , "spinbt" , spinbt );
+ return hbox;
+}
+
+
+static void
+aosd_cb_configure_animation_timing_commit ( GtkWidget * timing_hbox , aosd_cfg_t * cfg )
+{
+ cfg->animation.timing_display = gtk_spin_button_get_value_as_int(
+ GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(timing_hbox),"display")) );
+ cfg->animation.timing_fadein = gtk_spin_button_get_value_as_int(
+ GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(timing_hbox),"fadein")) );
+ cfg->animation.timing_fadeout = gtk_spin_button_get_value_as_int(
+ GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(timing_hbox),"fadeout")) );
+}
+
+
+static GtkWidget *
+aosd_ui_configure_animation ( aosd_cfg_t * cfg )
+{
+ GtkWidget *ani_vbox;
+ GtkWidget *ani_timing_frame, *ani_timing_hbox;
+ GtkWidget *ani_timing_fadein_widget, *ani_timing_fadeout_widget, *ani_timing_stay_widget;
+ GtkSizeGroup *sizegroup;
+
+ ani_vbox = gtk_vbox_new( FALSE , 0 );
+ gtk_container_set_border_width( GTK_CONTAINER(ani_vbox) , 6 );
+
+ ani_timing_hbox = gtk_hbox_new( FALSE , 0 );
+ ani_timing_frame = gtk_frame_new( _("Timing (ms)") );
+ gtk_container_set_border_width( GTK_CONTAINER(ani_timing_hbox) , 6 );
+ gtk_container_add( GTK_CONTAINER(ani_timing_frame) , ani_timing_hbox );
+ gtk_box_pack_start( GTK_BOX(ani_vbox) , ani_timing_frame , FALSE , FALSE , 0 );
+
+ ani_timing_stay_widget = aosd_ui_configure_animation_timing( _("Display:") );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON(g_object_get_data(
+ G_OBJECT(ani_timing_stay_widget),"spinbt")) , cfg->animation.timing_display );
+ gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , ani_timing_stay_widget , TRUE , TRUE , 0 );
+ gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , gtk_vseparator_new() , FALSE , FALSE , 4 );
+ ani_timing_fadein_widget = aosd_ui_configure_animation_timing( _("Fade in:") );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON(g_object_get_data(
+ G_OBJECT(ani_timing_fadein_widget),"spinbt")) , cfg->animation.timing_fadein );
+ gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , ani_timing_fadein_widget , TRUE , TRUE , 0 );
+ gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , gtk_vseparator_new() , FALSE , FALSE , 4 );
+ ani_timing_fadeout_widget = aosd_ui_configure_animation_timing( _("Fade out:") );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON(g_object_get_data(
+ G_OBJECT(ani_timing_fadeout_widget),"spinbt")) , cfg->animation.timing_fadeout );
+ gtk_box_pack_start( GTK_BOX(ani_timing_hbox) , ani_timing_fadeout_widget , TRUE , TRUE , 0 );
+ g_object_set_data( G_OBJECT(ani_timing_hbox) , "display" ,
+ g_object_get_data(G_OBJECT(ani_timing_stay_widget),"spinbt") );
+ g_object_set_data( G_OBJECT(ani_timing_hbox) , "fadein" ,
+ g_object_get_data(G_OBJECT(ani_timing_fadein_widget),"spinbt") );
+ g_object_set_data( G_OBJECT(ani_timing_hbox) , "fadeout" ,
+ g_object_get_data(G_OBJECT(ani_timing_fadeout_widget),"spinbt") );
+ sizegroup = gtk_size_group_new( GTK_SIZE_GROUP_HORIZONTAL );
+ gtk_size_group_add_widget( sizegroup , ani_timing_stay_widget );
+ gtk_size_group_add_widget( sizegroup , ani_timing_fadein_widget );
+ gtk_size_group_add_widget( sizegroup , ani_timing_fadeout_widget );
+ aosd_cb_list.append( ani_timing_hbox , aosd_cb_configure_animation_timing_commit );
+
+ return ani_vbox;
+}
+
+
+static void
+aosd_cb_configure_text_font_shadow_toggle ( GtkToggleButton * shadow_togglebt ,
+ void * shadow_colorbt )
+{
+ if ( gtk_toggle_button_get_active( shadow_togglebt ) == TRUE )
+ gtk_widget_set_sensitive( GTK_WIDGET(shadow_colorbt) , TRUE );
+ else
+ gtk_widget_set_sensitive( GTK_WIDGET(shadow_colorbt) , FALSE );
+}
+
+
+static void
+aosd_cb_configure_text_font_commit ( GtkWidget * fontbt , aosd_cfg_t * cfg )
+{
+ int fontnum = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(fontbt) , "fontnum" ));
+ GtkColorButton * chooser;
+
+ cfg->text.fonts_name[fontnum] =
+ String (gtk_font_button_get_font_name (GTK_FONT_BUTTON (fontbt)));
+
+ cfg->text.fonts_draw_shadow[fontnum] = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(fontbt),"use_shadow")) );
+
+ chooser = (GtkColorButton *) g_object_get_data ((GObject *) fontbt, "color");
+ chooser_get_aosd_color (chooser, & cfg->text.fonts_color[fontnum]);
+
+ chooser = (GtkColorButton *) g_object_get_data ((GObject *) fontbt, "shadow_color");
+ chooser_get_aosd_color (chooser, & cfg->text.fonts_shadow_color[fontnum]);
+}
+
+
+static GtkWidget *
+aosd_ui_configure_text ( aosd_cfg_t * cfg )
+{
+ GtkWidget *tex_vbox;
+ GtkWidget *tex_font_grid, *tex_font_frame;
+ GtkWidget *tex_font_label[3], *tex_font_fontbt[3];
+ GtkWidget *tex_font_colorbt[3], *tex_font_shadow_togglebt[3];
+ GtkWidget *tex_font_shadow_colorbt[3];
+ int i = 0;
+
+ tex_vbox = gtk_vbox_new( FALSE , 4 );
+ gtk_container_set_border_width( GTK_CONTAINER(tex_vbox) , 6 );
+
+ tex_font_frame = gtk_frame_new( _("Fonts") );
+ tex_font_grid = gtk_table_new (0, 0, FALSE);
+ gtk_container_set_border_width( GTK_CONTAINER(tex_font_grid) , 6 );
+ gtk_table_set_row_spacings( GTK_TABLE(tex_font_grid) , 4 );
+ gtk_table_set_col_spacings( GTK_TABLE(tex_font_grid) , 4 );
+ for ( i = 0 ; i < AOSD_TEXT_FONTS_NUM ; i++ )
+ {
+ char *label_str = g_strdup_printf( _("Font %i:") , i+1 );
+ tex_font_label[i] = gtk_label_new( label_str );
+ g_free( label_str );
+ tex_font_fontbt[i] = gtk_font_button_new();
+ gtk_font_button_set_show_style( GTK_FONT_BUTTON(tex_font_fontbt[i]) , TRUE );
+ gtk_font_button_set_show_size( GTK_FONT_BUTTON(tex_font_fontbt[i]) , TRUE );
+ gtk_font_button_set_use_font( GTK_FONT_BUTTON(tex_font_fontbt[i]) , FALSE );
+ gtk_font_button_set_use_size( GTK_FONT_BUTTON(tex_font_fontbt[i]) , FALSE );
+ gtk_font_button_set_font_name( GTK_FONT_BUTTON(tex_font_fontbt[i]) , cfg->text.fonts_name[i] );
+
+ tex_font_colorbt[i] = gtk_color_button_new ();
+ chooser_set_aosd_color ((GtkColorButton *) tex_font_colorbt[i],
+ & cfg->text.fonts_color[i]);
+
+ tex_font_shadow_togglebt[i] = gtk_toggle_button_new_with_label( _("Shadow") );
+ gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON(tex_font_shadow_togglebt[i]) , FALSE );
+
+ tex_font_shadow_colorbt[i] = gtk_color_button_new ();
+ chooser_set_aosd_color ((GtkColorButton *) tex_font_shadow_colorbt[i],
+ & cfg->text.fonts_shadow_color[i]);
+
+ gtk_widget_set_sensitive( tex_font_shadow_colorbt[i] , FALSE );
+ g_signal_connect( G_OBJECT(tex_font_shadow_togglebt[i]) , "toggled" ,
+ G_CALLBACK(aosd_cb_configure_text_font_shadow_toggle) ,
+ tex_font_shadow_colorbt[i] );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(tex_font_shadow_togglebt[i]) ,
+ cfg->text.fonts_draw_shadow[i] );
+ gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_label[i] , 0 , 1 , i , i + 1 );
+ gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_fontbt[i] , 1 , 2 , i , i + 1 );
+ gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_colorbt[i] , 2 , 3 , i , i + 1 );
+ gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_shadow_togglebt[i] , 3 , 4 , i , i + 1 );
+ gtk_table_attach_defaults( GTK_TABLE(tex_font_grid) , tex_font_shadow_colorbt[i] , 4 , 5 , i , i + 1 );
+ g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "fontnum" , GINT_TO_POINTER(i) );
+ g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "color" , tex_font_colorbt[i] );
+ g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "use_shadow" , tex_font_shadow_togglebt[i] );
+ g_object_set_data( G_OBJECT(tex_font_fontbt[i]) , "shadow_color" , tex_font_shadow_colorbt[i] );
+ aosd_cb_list.append( tex_font_fontbt[i] , aosd_cb_configure_text_font_commit );
+ }
+ gtk_container_add( GTK_CONTAINER(tex_font_frame) , tex_font_grid );
+ gtk_box_pack_start( GTK_BOX(tex_vbox) , tex_font_frame , FALSE , FALSE , 0 );
+
+ return tex_vbox;
+}
+
+
+static void
+aosd_cb_configure_decoration_style_commit ( GtkWidget * lv , aosd_cfg_t * cfg )
+{
+ GtkTreeSelection *sel = gtk_tree_view_get_selection( GTK_TREE_VIEW(lv) );
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ if ( gtk_tree_selection_get_selected( sel , &model , &iter ) == TRUE )
+ {
+ int deco_code = 0;
+ gtk_tree_model_get( model , &iter , 1 , &deco_code , -1 );
+ cfg->decoration.code = deco_code;
+ }
+}
+
+
+static void
+aosd_cb_configure_decoration_color_commit ( GtkWidget * colorbt , aosd_cfg_t * cfg )
+{
+ aosd_color_t color;
+ chooser_get_aosd_color ((GtkColorButton *) colorbt, & color);
+
+ int colnum = GPOINTER_TO_INT( g_object_get_data( G_OBJECT(colorbt) , "colnum" ) );
+ cfg->decoration.colors[colnum] = color;
+}
+
+
+static GtkWidget *
+aosd_ui_configure_decoration ( aosd_cfg_t * cfg )
+{
+ GtkWidget *dec_hbox;
+ GtkWidget *dec_rstyle_lv, *dec_rstyle_lv_frame, *dec_rstyle_lv_sw;
+ GtkListStore *dec_rstyle_store;
+ GtkCellRenderer *dec_rstyle_lv_rndr_text;
+ GtkTreeViewColumn *dec_rstyle_lv_col_desc;
+ GtkTreeSelection *dec_rstyle_lv_sel;
+ GtkTreeIter iter, iter_sel;
+ GtkWidget *dec_rstyle_hbox;
+ GtkWidget *dec_rstyleopts_frame, *dec_rstyleopts_grid;
+ int colors_max_num = 0, i = 0;
+
+ dec_hbox = gtk_hbox_new( FALSE , 4 );
+ gtk_container_set_border_width( GTK_CONTAINER(dec_hbox) , 6 );
+
+ /* decoration style model
+ ---------------------------------------------
+ G_TYPE_STRING -> decoration description
+ G_TYPE_INT -> decoration code
+ G_TYPE_INT -> number of user-definable colors
+ ---------------------------------------------
+ */
+ dec_rstyle_store = gtk_list_store_new( 3 , G_TYPE_STRING , G_TYPE_INT , G_TYPE_INT );
+ for ( i = 0 ; i < AOSD_NUM_DECO_STYLES ; i++ )
+ {
+ int colors_num = aosd_deco_style_get_numcol( i );
+ if ( colors_num > colors_max_num )
+ colors_max_num = colors_num;
+ gtk_list_store_append( dec_rstyle_store , &iter );
+ gtk_list_store_set( dec_rstyle_store , &iter ,
+ 0 , _(aosd_deco_style_get_desc( i )) ,
+ 1 , i , 2 , colors_num , -1 );
+ if ( i == cfg->decoration.code )
+ iter_sel = iter;
+ }
+
+ dec_rstyle_lv_frame = gtk_frame_new( nullptr );
+ dec_rstyle_lv = gtk_tree_view_new_with_model( GTK_TREE_MODEL(dec_rstyle_store) );
+ g_object_unref( dec_rstyle_store );
+ dec_rstyle_lv_sel = gtk_tree_view_get_selection( GTK_TREE_VIEW(dec_rstyle_lv) );
+ gtk_tree_selection_set_mode( dec_rstyle_lv_sel , GTK_SELECTION_BROWSE );
+
+ dec_rstyle_lv_rndr_text = gtk_cell_renderer_text_new();
+ dec_rstyle_lv_col_desc = gtk_tree_view_column_new_with_attributes(
+ _("Render Style") , dec_rstyle_lv_rndr_text , "text" , 0 , nullptr );
+ gtk_tree_view_append_column( GTK_TREE_VIEW(dec_rstyle_lv), dec_rstyle_lv_col_desc );
+ dec_rstyle_lv_sw = gtk_scrolled_window_new( nullptr , nullptr );
+ gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(dec_rstyle_lv_sw) ,
+ GTK_POLICY_NEVER , GTK_POLICY_ALWAYS );
+ gtk_container_add( GTK_CONTAINER(dec_rstyle_lv_sw) , dec_rstyle_lv );
+ gtk_container_add( GTK_CONTAINER(dec_rstyle_lv_frame) , dec_rstyle_lv_sw );
+
+ gtk_tree_selection_select_iter( dec_rstyle_lv_sel , &iter_sel );
+ gtk_box_pack_start( GTK_BOX(dec_hbox) , dec_rstyle_lv_frame , FALSE , FALSE , 0 );
+ aosd_cb_list.append( dec_rstyle_lv , aosd_cb_configure_decoration_style_commit );
+
+ dec_rstyle_hbox = gtk_vbox_new( FALSE , 4 );
+ gtk_box_pack_start( GTK_BOX(dec_hbox) , dec_rstyle_hbox , TRUE , TRUE , 0 );
+
+ /* in colors_max_num now there's the maximum number of colors used by decoration styles */
+ dec_rstyleopts_frame = gtk_frame_new( _("Colors") );
+ dec_rstyleopts_grid = gtk_table_new (0, 0, FALSE);
+ gtk_container_set_border_width( GTK_CONTAINER(dec_rstyleopts_grid) , 6 );
+ gtk_table_set_row_spacings( GTK_TABLE(dec_rstyleopts_grid) , 4 );
+ gtk_table_set_col_spacings( GTK_TABLE(dec_rstyleopts_grid) , 8 );
+ gtk_container_add( GTK_CONTAINER(dec_rstyleopts_frame) , dec_rstyleopts_grid );
+ for ( i = 0 ; i < colors_max_num ; i++ )
+ {
+ GtkWidget *hbox, *label;
+ char *label_str = nullptr;
+ hbox = gtk_hbox_new( FALSE , 4 );
+ label_str = g_strdup_printf( _("Color %i:") , i+1 );
+ label = gtk_label_new( label_str );
+ g_free( label_str );
+
+ GtkWidget * colorbt = gtk_color_button_new ();
+ chooser_set_aosd_color ((GtkColorButton *) colorbt, & cfg->decoration.colors[i]);
+
+ gtk_box_pack_start( GTK_BOX(hbox) , label , FALSE , FALSE , 0 );
+ gtk_box_pack_start( GTK_BOX(hbox) , colorbt , FALSE , FALSE , 0 );
+ gtk_table_attach_defaults( GTK_TABLE(dec_rstyleopts_grid) , hbox , (i % 3) , (i % 3) + 1, (i / 3) , (i / 3) + 1);
+ g_object_set_data( G_OBJECT(colorbt) , "colnum" , GINT_TO_POINTER(i) );
+ aosd_cb_list.append( colorbt , aosd_cb_configure_decoration_color_commit );
+ }
+ gtk_box_pack_start( GTK_BOX(dec_rstyle_hbox) , dec_rstyleopts_frame , FALSE , FALSE , 0 );
+
+ return dec_hbox;
+}
+
+
+static void
+aosd_cb_configure_trigger_lvchanged ( GtkTreeSelection *sel , void * nb )
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ if ( gtk_tree_selection_get_selected( sel , &model , &iter ) == TRUE )
+ {
+ int page_num = 0;
+ gtk_tree_model_get( model , &iter , 2 , &page_num , -1 );
+ gtk_notebook_set_current_page( GTK_NOTEBOOK(nb) , page_num );
+ }
+}
+
+
+static void
+aosd_cb_configure_trigger_commit ( GtkWidget * cbt , aosd_cfg_t * cfg )
+{
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(cbt) ) == TRUE )
+ {
+ int value = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cbt),"code"));
+ cfg->trigger.enabled[value] = true;
+ }
+}
+
+
+static GtkWidget *
+aosd_ui_configure_trigger ( aosd_cfg_t * cfg )
+{
+ GtkWidget *tri_hbox;
+ GtkWidget *tri_event_lv, *tri_event_lv_frame, *tri_event_lv_sw;
+ GtkListStore *tri_event_store;
+ GtkCellRenderer *tri_event_lv_rndr_text;
+ GtkTreeViewColumn *tri_event_lv_col_desc;
+ GtkTreeSelection *tri_event_lv_sel;
+ GtkTreeIter iter;
+ GtkWidget *tri_event_nb;
+ int i = 0;
+
+ tri_event_nb = gtk_notebook_new();
+ gtk_notebook_set_tab_pos( GTK_NOTEBOOK(tri_event_nb) , GTK_POS_LEFT );
+ gtk_notebook_set_show_tabs( GTK_NOTEBOOK(tri_event_nb) , FALSE );
+ gtk_notebook_set_show_border( GTK_NOTEBOOK(tri_event_nb) , FALSE );
+
+ tri_hbox = gtk_hbox_new( FALSE , 4 );
+ gtk_container_set_border_width( GTK_CONTAINER(tri_hbox) , 6 );
+
+ /* trigger model
+ ---------------------------------------------
+ G_TYPE_STRING -> trigger description
+ G_TYPE_INT -> trigger code
+ G_TYPE_INT -> gtk notebook page number
+ ---------------------------------------------
+ */
+ tri_event_store = gtk_list_store_new( 3 , G_TYPE_STRING , G_TYPE_INT , G_TYPE_INT );
+ for ( i = 0 ; i < AOSD_NUM_TRIGGERS ; i ++ )
+ {
+ GtkWidget *frame, *vbox, *label, *checkbt;
+ gtk_list_store_append( tri_event_store , &iter );
+ gtk_list_store_set( tri_event_store , &iter ,
+ 0 , _(aosd_trigger_get_name( i )) ,
+ 1 , i , 2 , i , -1 );
+ vbox = gtk_vbox_new( FALSE , 0 );
+ gtk_container_set_border_width( GTK_CONTAINER(vbox) , 6 );
+ label = gtk_label_new( _(aosd_trigger_get_desc( i )) );
+ gtk_label_set_line_wrap( GTK_LABEL(label) , TRUE );
+ gtk_label_set_max_width_chars( GTK_LABEL(label), 40 );
+ gtk_misc_set_alignment( GTK_MISC(label) , 0.0 , 0.0 );
+ checkbt = gtk_check_button_new_with_label( _("Enable trigger") );
+ if ( cfg->trigger.enabled[i] )
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(checkbt) , TRUE );
+ else
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(checkbt) , FALSE );
+ gtk_box_pack_start( GTK_BOX(vbox) , checkbt , FALSE , FALSE , 0 );
+ gtk_box_pack_start( GTK_BOX(vbox) , gtk_hseparator_new() , FALSE , FALSE , 4 );
+ gtk_box_pack_start( GTK_BOX(vbox) , label , FALSE , FALSE , 0 );
+ frame = gtk_frame_new( nullptr );
+ gtk_container_add( GTK_CONTAINER(frame) , vbox );
+ gtk_notebook_append_page( GTK_NOTEBOOK(tri_event_nb) , frame , nullptr );
+ g_object_set_data( G_OBJECT(checkbt) , "code" , GINT_TO_POINTER(i) );
+ aosd_cb_list.append( checkbt , aosd_cb_configure_trigger_commit );
+ }
+
+ tri_event_lv_frame = gtk_frame_new( nullptr );
+ tri_event_lv = gtk_tree_view_new_with_model( GTK_TREE_MODEL(tri_event_store) );
+ g_object_unref( tri_event_store );
+ tri_event_lv_sel = gtk_tree_view_get_selection( GTK_TREE_VIEW(tri_event_lv) );
+ gtk_tree_selection_set_mode( tri_event_lv_sel , GTK_SELECTION_BROWSE );
+ g_signal_connect( G_OBJECT(tri_event_lv_sel) , "changed" ,
+ G_CALLBACK(aosd_cb_configure_trigger_lvchanged) , tri_event_nb );
+ if ( gtk_tree_model_get_iter_first( GTK_TREE_MODEL(tri_event_store) , &iter ) == TRUE )
+ gtk_tree_selection_select_iter( tri_event_lv_sel , &iter );
+
+ tri_event_lv_rndr_text = gtk_cell_renderer_text_new();
+ tri_event_lv_col_desc = gtk_tree_view_column_new_with_attributes(
+ _("Event") , tri_event_lv_rndr_text , "text" , 0 , nullptr );
+ gtk_tree_view_append_column( GTK_TREE_VIEW(tri_event_lv), tri_event_lv_col_desc );
+ tri_event_lv_sw = gtk_scrolled_window_new( nullptr , nullptr );
+ gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(tri_event_lv_sw) ,
+ GTK_POLICY_NEVER , GTK_POLICY_ALWAYS );
+ gtk_container_add( GTK_CONTAINER(tri_event_lv_sw) , tri_event_lv );
+ gtk_container_add( GTK_CONTAINER(tri_event_lv_frame) , tri_event_lv_sw );
+ gtk_tree_selection_select_iter( tri_event_lv_sel , &iter );
+
+ gtk_box_pack_start( GTK_BOX(tri_hbox) , tri_event_lv_frame , FALSE , FALSE , 0 );
+
+ gtk_box_pack_start( GTK_BOX(tri_hbox) , tri_event_nb , TRUE , TRUE , 0 );
+
+ return tri_hbox;
+}
+
+
+#ifdef HAVE_XCOMPOSITE
+static void
+aosd_cb_configure_misc_transp_real_clicked ( GtkToggleButton * real_rbt , void * status_hbox )
+{
+ GtkWidget *img = (GtkWidget *) g_object_get_data( G_OBJECT(status_hbox) , "img" );
+ GtkWidget *label = (GtkWidget *) g_object_get_data( G_OBJECT(status_hbox) , "label" );
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(real_rbt) ) )
+ {
+ if ( aosd_osd_check_composite_mgr() )
+ {
+ gtk_image_set_from_icon_name( GTK_IMAGE(img) , "face-smile" , GTK_ICON_SIZE_MENU );
+ gtk_label_set_text( GTK_LABEL(label) , _("Composite manager detected") );
+ gtk_widget_set_sensitive( GTK_WIDGET(status_hbox) , TRUE );
+ }
+ else
+ {
+ gtk_image_set_from_icon_name( GTK_IMAGE(img) , "dialog-warning" , GTK_ICON_SIZE_MENU );
+ gtk_label_set_text( GTK_LABEL(label) ,
+ _("Composite manager not detected;\nunless you know that you have one running, "
+ "please activate a composite manager otherwise the OSD won't work properly") );
+ gtk_widget_set_sensitive( GTK_WIDGET(status_hbox) , TRUE );
+ }
+ }
+ else
+ {
+ gtk_image_set_from_icon_name( GTK_IMAGE(img) , "dialog-information" , GTK_ICON_SIZE_MENU );
+ gtk_label_set_text( GTK_LABEL(label) , _("Composite manager not required for fake transparency") );
+ gtk_widget_set_sensitive( GTK_WIDGET(status_hbox) , FALSE );
+ }
+}
+#endif
+
+
+static void
+aosd_cb_configure_misc_transp_commit ( GtkWidget * mis_transp_vbox , aosd_cfg_t * cfg )
+{
+ GList *child_list = gtk_container_get_children( GTK_CONTAINER(mis_transp_vbox) );
+ while (child_list != nullptr)
+ {
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(child_list->data) ) )
+ {
+ cfg->misc.transparency_mode = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(child_list->data),"val"));
+ break;
+ }
+ child_list = g_list_next(child_list);
+ }
+}
+
+
+static GtkWidget *
+aosd_ui_configure_misc ( aosd_cfg_t * cfg )
+{
+ GtkWidget *mis_vbox;
+ GtkWidget *mis_transp_frame, *mis_transp_vbox;
+ GtkWidget *mis_transp_fake_rbt, *mis_transp_real_rbt;
+ GtkWidget *mis_transp_status_frame, *mis_transp_status_hbox;
+ GtkWidget *mis_transp_status_img, *mis_transp_status_label;
+
+ mis_vbox = gtk_vbox_new( FALSE , 0 );
+ gtk_container_set_border_width( GTK_CONTAINER(mis_vbox) , 6 );
+
+ mis_transp_vbox = gtk_vbox_new( FALSE , 0 );
+ mis_transp_frame = gtk_frame_new( _("Transparency") );
+ gtk_container_set_border_width( GTK_CONTAINER(mis_transp_vbox) , 6 );
+ gtk_container_add( GTK_CONTAINER(mis_transp_frame) , mis_transp_vbox );
+ gtk_box_pack_start( GTK_BOX(mis_vbox) , mis_transp_frame , FALSE , FALSE , 0 );
+
+ mis_transp_fake_rbt = gtk_radio_button_new_with_label( nullptr ,
+ _("Fake transparency") );
+ mis_transp_real_rbt = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(mis_transp_fake_rbt) ,
+ _("Real transparency (requires X Composite Ext.)") );
+ g_object_set_data( G_OBJECT(mis_transp_fake_rbt) , "val" ,
+ GINT_TO_POINTER(AOSD_MISC_TRANSPARENCY_FAKE) );
+ g_object_set_data( G_OBJECT(mis_transp_real_rbt) , "val" ,
+ GINT_TO_POINTER(AOSD_MISC_TRANSPARENCY_REAL) );
+ gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_fake_rbt , TRUE , TRUE , 0 );
+ gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_real_rbt , TRUE , TRUE , 0 );
+
+ mis_transp_status_hbox = gtk_hbox_new( FALSE , 4 );
+ mis_transp_status_frame = gtk_frame_new( nullptr );
+ gtk_container_set_border_width( GTK_CONTAINER(mis_transp_status_hbox) , 3 );
+ gtk_container_add( GTK_CONTAINER(mis_transp_status_frame) , mis_transp_status_hbox );
+ gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_status_frame , TRUE , TRUE , 0 );
+
+ mis_transp_status_img = gtk_image_new();
+ gtk_misc_set_alignment( GTK_MISC(mis_transp_status_img) , 0.5 , 0 );
+ mis_transp_status_label = gtk_label_new( "" );
+ gtk_misc_set_alignment( GTK_MISC(mis_transp_status_label) , 0 , 0.5 );
+ gtk_label_set_line_wrap( GTK_LABEL(mis_transp_status_label) , TRUE );
+ gtk_box_pack_start( GTK_BOX(mis_transp_status_hbox) , mis_transp_status_img , FALSE , FALSE , 0 );
+ gtk_box_pack_start( GTK_BOX(mis_transp_status_hbox) , mis_transp_status_label , TRUE , TRUE , 0 );
+ g_object_set_data( G_OBJECT(mis_transp_status_hbox) , "img" , mis_transp_status_img );
+ g_object_set_data( G_OBJECT(mis_transp_status_hbox) , "label" , mis_transp_status_label );
+
+#ifdef HAVE_XCOMPOSITE
+ g_signal_connect( G_OBJECT(mis_transp_real_rbt) , "toggled" ,
+ G_CALLBACK(aosd_cb_configure_misc_transp_real_clicked) , mis_transp_status_hbox );
+
+ /* check if the composite extension is loaded */
+ if ( aosd_osd_check_composite_ext() )
+ {
+ if ( cfg->misc.transparency_mode == AOSD_MISC_TRANSPARENCY_FAKE )
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_fake_rbt) , TRUE );
+ else
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_real_rbt) , TRUE );
+ }
+ else
+ {
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_fake_rbt) , TRUE );
+ gtk_widget_set_sensitive( GTK_WIDGET(mis_transp_real_rbt) , FALSE );
+ gtk_image_set_from_icon_name( GTK_IMAGE(mis_transp_status_img) ,
+ "dialog-error" , GTK_ICON_SIZE_MENU );
+ gtk_label_set_text( GTK_LABEL(mis_transp_status_label) , _("Composite extension not loaded") );
+ gtk_widget_set_sensitive( GTK_WIDGET(mis_transp_status_hbox) , FALSE );
+ }
+#else
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_fake_rbt) , TRUE );
+ gtk_widget_set_sensitive( GTK_WIDGET(mis_transp_real_rbt) , FALSE );
+ gtk_image_set_from_icon_name( GTK_IMAGE(mis_transp_status_img) ,
+ "dialog-error" , GTK_ICON_SIZE_MENU );
+ gtk_label_set_text( GTK_LABEL(mis_transp_status_label) , _("Composite extension not available") );
+ gtk_widget_set_sensitive( GTK_WIDGET(mis_transp_status_hbox) , FALSE );
+#endif
+
+ aosd_cb_list.append( mis_transp_vbox , aosd_cb_configure_misc_transp_commit );
+
+ return mis_vbox;
+}
+
+
+static void
+aosd_cb_configure_test ( void )
+{
+ aosd_cfg_t cfg = aosd_cfg_t ();
+ aosd_callback_list_run (& cfg);
+
+ char * markup_message = g_markup_printf_escaped
+ (_("<span font_desc='%s'>Audacious OSD</span>"),
+ (const char *) cfg.text.fonts_name[0]);
+
+ aosd_osd_shutdown (); /* stop any displayed osd */
+ aosd_osd_cleanup (); /* just in case it's active */
+ aosd_osd_init (cfg.misc.transparency_mode);
+ aosd_osd_display (markup_message, & cfg, true);
+
+ g_free (markup_message);
+}
+
+
+static void
+aosd_cb_configure_cancel ( void )
+{
+ aosd_cb_list.clear ();
+
+ aosd_osd_shutdown (); /* stop any displayed osd */
+ aosd_osd_cleanup (); /* just in case it's active */
+ aosd_osd_init (global_config.misc.transparency_mode);
+}
+
+
+static void
+aosd_cb_configure_ok ( void )
+{
+ aosd_cfg_t cfg = aosd_cfg_t ();
+
+ aosd_callback_list_run (& cfg);
+ aosd_cb_list.clear ();
+
+ aosd_osd_shutdown (); /* stop any displayed osd */
+ aosd_osd_cleanup (); /* just in case it's active */
+
+ aosd_trigger_stop (global_config.trigger); /* stop triggers */
+ global_config = cfg; /* put the new config */
+ aosd_cfg_save (cfg); /* save the new configuration on config file */
+ aosd_osd_init (cfg.misc.transparency_mode); /* restart osd */
+ aosd_trigger_start (cfg.trigger); /* restart triggers */
+}
+
+
+static void *
+aosd_ui_configure ( void )
+{
+ GtkWidget *cfg_nb;
+ GtkWidget *cfg_position_widget;
+ GtkWidget *cfg_animation_widget;
+ GtkWidget *cfg_text_widget;
+ GtkWidget *cfg_decoration_widget;
+ GtkWidget *cfg_trigger_widget;
+
+ /* create a new configuration object */
+ aosd_cfg_t cfg = aosd_cfg_t();
+ /* fill it with information from config file */
+ aosd_cfg_load( cfg );
+
+ cfg_nb = gtk_notebook_new();
+ gtk_notebook_set_tab_pos( GTK_NOTEBOOK(cfg_nb) , GTK_POS_TOP );
+
+ /* add POSITION page */
+ cfg_position_widget = aosd_ui_configure_position( &cfg );
+ gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
+ cfg_position_widget , gtk_label_new( _("Position") ) );
+
+ /* add ANIMATION page */
+ cfg_animation_widget = aosd_ui_configure_animation( &cfg );
+ gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
+ cfg_animation_widget , gtk_label_new( _("Animation") ) );
+
+ /* add TEXT page */
+ cfg_text_widget = aosd_ui_configure_text( &cfg );
+ gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
+ cfg_text_widget , gtk_label_new( _("Text") ) );
+
+ /* add DECORATION page */
+ cfg_decoration_widget = aosd_ui_configure_decoration( &cfg );
+ gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
+ cfg_decoration_widget , gtk_label_new( _("Decoration") ) );
+
+ /* add TRIGGER page */
+ cfg_trigger_widget = aosd_ui_configure_trigger( &cfg );
+ gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
+ cfg_trigger_widget , gtk_label_new( _("Trigger") ) );
+
+ /* add MISC page */
+ cfg_trigger_widget = aosd_ui_configure_misc( &cfg );
+ gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
+ cfg_trigger_widget , gtk_label_new( _("Misc") ) );
+
+ return cfg_nb;
+}
+
+
+const PreferencesWidget AOSD::widgets[] = {
+ WidgetCustomGTK (aosd_ui_configure),
+ WidgetSeparator ({true}),
+ WidgetButton (N_("Test"), {aosd_cb_configure_test, "media-playback-start"})
+};
+
+const PluginPreferences AOSD::prefs = {
+ {widgets},
+ nullptr, // init
+ aosd_cb_configure_ok,
+ aosd_cb_configure_cancel
+};
diff --git a/src/aosd/aosd_ui.h b/src/aosd/aosd_ui.h
deleted file mode 100644
index 16810c0fc1af..000000000000
--- a/src/aosd/aosd_ui.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-*
-* Author: Giacomo Lozito <james at develia.org>, (C) 2005-2007
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#ifndef _I_AOSD_UI_H
-#define _I_AOSD_UI_H 1
-
-#undef PACKAGE
-#define PACKAGE "audacious-plugins"
-
-#include "aosd_common.h"
-#include "aosd_cfg.h"
-#include <glib.h>
-
-void aosd_ui_configure ( aosd_cfg_t * );
-
-#endif /* !_I_AOSD_UI_H */
diff --git a/src/aosd/ghosd.c b/src/aosd/ghosd.c
index f3e36ced844e..cfe388658caf 100644
--- a/src/aosd/ghosd.c
+++ b/src/aosd/ghosd.c
@@ -8,8 +8,6 @@
* - added/changed some other stuff
*/
-#include "aosd_common.h"
-
#include <stdio.h>
#include <stdlib.h>
#include <cairo/cairo-xlib-xrender.h>
diff --git a/src/aosd/ghosd.h b/src/aosd/ghosd.h
index 4f82efa1da96..70c36a7d184e 100644
--- a/src/aosd/ghosd.h
+++ b/src/aosd/ghosd.h
@@ -16,8 +16,6 @@
#include <limits.h> /* INT_MAX */
#include <sys/time.h> /* timeval */
-#include "aosd_common.h"
-
typedef struct _Ghosd Ghosd;
/* minimal struct to handle button events */
@@ -34,6 +32,10 @@ GhosdEventButton;
typedef void (*GhosdRenderFunc)(Ghosd *ghosd, cairo_t *cr, void *user_data);
typedef void (*GhosdEventButtonCb)(Ghosd *ghosd, GhosdEventButton *event, void *user_data);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
Ghosd *ghosd_new(void);
void ghosd_destroy(Ghosd* ghosd);
#ifdef HAVE_XCOMPOSITE
@@ -60,6 +62,10 @@ void ghosd_flash(Ghosd *ghosd, int fade_ms, int total_display_ms);
int ghosd_get_socket(Ghosd *ghosd);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __GHOSD_H__ */
/* vim: set ts=2 sw=2 et cino=(0 : */
diff --git a/src/asx/Makefile b/src/asx/Makefile
index d867744a8991..3efffb77b93f 100644
--- a/src/asx/Makefile
+++ b/src/asx/Makefile
@@ -1,11 +1,13 @@
PLUGIN = asx${PLUGIN_SUFFIX}
-SRCS = asx.c
+SRCS = asx.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${CONTAINER_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
+
diff --git a/src/asx/asx.c b/src/asx/asx.c
deleted file mode 100644
index 28d96f40fbbb..000000000000
--- a/src/asx/asx.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * asx.c
- * Copyright 2010-2013 William Pitcock and John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/inifile.h>
-
-typedef struct {
- const char * filename;
- bool_t valid_heading;
- Index * filenames;
-} ASXLoadState;
-
-void asx_handle_heading (const char * heading, void * data)
-{
- ASXLoadState * state = data;
-
- state->valid_heading = ! g_ascii_strcasecmp (heading, "reference");
-}
-
-void asx_handle_entry (const char * key, const char * value, void * data)
-{
- ASXLoadState * state = data;
-
- if (! state->valid_heading || g_ascii_strncasecmp (key, "ref", 3))
- return;
-
- char * uri = aud_construct_uri (value, state->filename);
- if (! uri)
- return;
-
- if (! strncmp ("http://", uri, 7))
- {
- index_insert (state->filenames, -1, str_printf ("mms://%s", uri + 7));
- str_unref (uri);
- }
- else
- index_insert (state->filenames, -1, uri);
-}
-
-static bool_t playlist_load_asx (const char * filename, VFSFile * file,
- char * * title, Index * filenames, Index * tuples)
-{
- ASXLoadState state = {
- .filename = filename,
- .valid_heading = FALSE,
- .filenames = filenames
- };
-
- inifile_parse (file, asx_handle_heading, asx_handle_entry, & state);
-
- return (index_count (filenames) != 0);
-}
-
-static const char * const asx_exts[] = {"asx", NULL};
-
-AUD_PLAYLIST_PLUGIN
-(
- .name = N_("ASXv1/ASXv2 Playlists"),
- .domain = PACKAGE,
- .extensions = asx_exts,
- .load = playlist_load_asx
-)
diff --git a/src/asx/asx.cc b/src/asx/asx.cc
new file mode 100644
index 000000000000..9b066a215e61
--- /dev/null
+++ b/src/asx/asx.cc
@@ -0,0 +1,80 @@
+/*
+ * asx.c
+ * Copyright 2010-2013 William Pitcock and John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/inifile.h>
+
+static const char * const asx_exts[] = {"asx"};
+
+class ASXLoader : public PlaylistPlugin
+{
+public:
+ static constexpr PluginInfo info = {N_("ASXv1/ASXv2 Playlists"), PACKAGE};
+
+ constexpr ASXLoader () : PlaylistPlugin (info, asx_exts, false) {}
+
+ bool load (const char * filename, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items);
+};
+
+EXPORT ASXLoader aud_plugin_instance;
+
+class ASXParser : public IniParser
+{
+public:
+ ASXParser (const char * filename, Index<PlaylistAddItem> & items) :
+ filename (filename),
+ items (items),
+ valid_heading (false) {}
+
+private:
+ const char * filename;
+ Index<PlaylistAddItem> & items;
+ bool valid_heading;
+
+ void handle_heading (const char * heading)
+ { valid_heading = ! strcmp_nocase (heading, "reference"); }
+
+ void handle_entry (const char * key, const char * value)
+ {
+ if (! valid_heading || ! str_has_prefix_nocase (key, "ref"))
+ return;
+
+ StringBuf uri = uri_construct (value, filename);
+ if (! uri)
+ return;
+
+ if (! strncmp ("http://", uri, 7))
+ items.append (String (str_printf ("mms://%s", uri + 7)));
+ else
+ items.append (String (uri));
+ }
+};
+
+bool ASXLoader::load (const char * filename, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items)
+{
+ ASXParser (filename, items).parse (file);
+ return (items.len () > 0);
+}
diff --git a/src/asx3/Makefile b/src/asx3/Makefile
index 56a7132a7346..e5abfb0c2948 100644
--- a/src/asx3/Makefile
+++ b/src/asx3/Makefile
@@ -1,12 +1,14 @@
PLUGIN = asx3${PLUGIN_SUFFIX}
-SRCS = asx3.c
+SRCS = asx3.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${CONTAINER_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${XML_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS} ${XML_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${XML_CFLAGS} -I../..
+LIBS += ${XML_LIBS}
diff --git a/src/asx3/asx3.c b/src/asx3/asx3.c
deleted file mode 100644
index 82ec0580c111..000000000000
--- a/src/asx3/asx3.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * asx3.c
- * Copyright 2013 Martin Steiger and John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/xmlsave.h>
-
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-
-static int read_cb (void * file, char * buf, int len)
-{
- return vfs_fread (buf, 1, len, file);
-}
-
-static int write_cb (void * file, const char * buf, int len)
-{
- return vfs_fwrite (buf, 1, len, file);
-}
-
-static int close_cb (void * file)
-{
- return 0;
-}
-
-static const char * get_content (const xmlNode * node)
-{
- const xmlNode * child = node->xmlChildrenNode;
- if (child && child->type == XML_TEXT_NODE && child->content)
- return (const char *) child->content;
-
- return NULL;
-}
-
-static const char * get_prop_nocase (const xmlNode * node, const char * name)
-{
- for (const xmlAttr * prop = node->properties; prop; prop = prop->next)
- {
- if (! xmlStrcasecmp (prop->name, (const xmlChar *) name))
- {
- const xmlNode * child = prop->children;
- if (child && child->type == XML_TEXT_NODE && child->content)
- return (const char *) child->content;
- }
- }
-
- return NULL;
-}
-
-static bool_t check_root (const xmlNode * root)
-{
- if (xmlStrcasecmp (root->name, (const xmlChar *) "asx"))
- {
- fprintf(stderr, "asx3: Not an ASX file\n");
- return FALSE;
- }
-
- const char * version = get_prop_nocase (root, "version");
-
- if (! version)
- {
- fprintf (stderr, "asx3: Unknown ASX version\n");
- return FALSE;
- }
-
- if (strcmp (version, "3.0"))
- {
- fprintf(stderr, "asx3: Unsupported ASX version (%s)\n", version);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void parse_entry (const xmlNode * entry, Index * filenames)
-{
- for (const xmlNode * node = entry->xmlChildrenNode; node; node = node->next)
- {
- if (! xmlStrcasecmp (node->name, (const xmlChar *) "ref"))
- {
- const char * uri = get_prop_nocase (node, "href");
- if (uri)
- index_insert (filenames, -1, str_get (uri));
- }
- }
-}
-
-static bool_t playlist_load_asx3 (const char * filename, VFSFile * file,
- char * * title, Index * filenames, Index * tuples)
-{
- xmlDoc * doc = xmlReadIO (read_cb, close_cb, file, filename, NULL, XML_PARSE_RECOVER);
- if (! doc)
- return FALSE;
-
- xmlNode * root = xmlDocGetRootElement (doc);
-
- if (! root || ! check_root (root))
- {
- xmlFreeDoc(doc);
- return FALSE;
- }
-
- for (xmlNode * node = root->xmlChildrenNode; node; node = node->next)
- {
- if (! xmlStrcasecmp (node->name, (const xmlChar *) "entry"))
- parse_entry (node, filenames);
- else if (! xmlStrcasecmp (node->name, (const xmlChar *) "title"))
- {
- if (! (* title))
- * title = str_get (get_content (node));
- }
- }
-
- xmlFreeDoc(doc);
- return TRUE;
-}
-
-static bool_t playlist_save_asx3 (const char * filename, VFSFile * file,
- const char * title, Index * filenames, Index * tuples)
-{
- xmlDoc * doc = xmlNewDoc ((const xmlChar *) "1.0");
- doc->charset = XML_CHAR_ENCODING_UTF8;
- doc->encoding = xmlStrdup ((const xmlChar *) "UTF-8");
-
- xmlNode * root = xmlNewNode (NULL, (const xmlChar *) "asx");
- xmlSetProp (root, (const xmlChar *) "version", (const xmlChar *) "3.0");
- xmlDocSetRootElement (doc, root);
-
- if (title)
- xmlNewTextChild (root, NULL, (const xmlChar *) "title", (const xmlChar *) title);
-
- int entries = index_count (filenames);
- for (int i = 0; i < entries; i ++)
- {
- xmlNode * entry = xmlNewNode (NULL, (const xmlChar *) "entry");
- xmlNode * ref = xmlNewNode (NULL, (const xmlChar *) "ref");
- xmlSetProp (ref, (const xmlChar *) "href", (const xmlChar *) index_get (filenames, i));
- xmlAddChild (entry, ref);
- xmlAddChild (root, entry);
- }
-
- xmlSaveCtxt * save = xmlSaveToIO (write_cb, close_cb, file, NULL, XML_SAVE_FORMAT);
-
- if (! save || xmlSaveDoc (save, doc) < 0 || xmlSaveClose (save) < 0)
- {
- xmlFreeDoc(doc);
- return FALSE;
- }
-
- xmlFreeDoc (doc);
- return TRUE;
-}
-
-static const char * const asx3_exts[] = {"asx", NULL};
-
-AUD_PLAYLIST_PLUGIN
-(
- .name = N_("ASXv3 Playlists"),
- .domain = PACKAGE,
- .extensions = asx3_exts,
- .load = playlist_load_asx3,
- .save = playlist_save_asx3
-)
diff --git a/src/asx3/asx3.cc b/src/asx3/asx3.cc
new file mode 100644
index 000000000000..3ab2dd943407
--- /dev/null
+++ b/src/asx3/asx3.cc
@@ -0,0 +1,187 @@
+/*
+ * asx3.c
+ * Copyright 2013 Martin Steiger and John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <string.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlsave.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+static const char * const asx3_exts[] = {"asx"};
+
+class ASX3Loader : public PlaylistPlugin
+{
+public:
+ static constexpr PluginInfo info = {N_("ASXv3 Playlists"), PACKAGE};
+
+ constexpr ASX3Loader () : PlaylistPlugin (info, asx3_exts, true) {}
+
+ bool load (const char * filename, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items);
+ bool save (const char * filename, VFSFile & file, const char * title,
+ const Index<PlaylistAddItem> & items);
+};
+
+EXPORT ASX3Loader aud_plugin_instance;
+
+static int read_cb (void * file, char * buf, int len)
+{
+ return ((VFSFile *) file)->fread (buf, 1, len);
+}
+
+static int write_cb (void * file, const char * buf, int len)
+{
+ return ((VFSFile *) file)->fwrite (buf, 1, len);
+}
+
+static int close_cb (void * file)
+{
+ return 0;
+}
+
+static const char * get_content (const xmlNode * node)
+{
+ const xmlNode * child = node->xmlChildrenNode;
+ if (child && child->type == XML_TEXT_NODE && child->content)
+ return (const char *) child->content;
+
+ return nullptr;
+}
+
+static const char * get_prop_nocase (const xmlNode * node, const char * name)
+{
+ for (const xmlAttr * prop = node->properties; prop; prop = prop->next)
+ {
+ if (! xmlStrcasecmp (prop->name, (const xmlChar *) name))
+ {
+ const xmlNode * child = prop->children;
+ if (child && child->type == XML_TEXT_NODE && child->content)
+ return (const char *) child->content;
+ }
+ }
+
+ return nullptr;
+}
+
+static bool check_root (const xmlNode * root)
+{
+ if (xmlStrcasecmp (root->name, (const xmlChar *) "asx"))
+ {
+ AUDERR ("Not an ASX file\n");
+ return false;
+ }
+
+ const char * version = get_prop_nocase (root, "version");
+
+ if (! version)
+ {
+ AUDERR ("Unknown ASX version\n");
+ return false;
+ }
+
+ if (strcmp (version, "3.0"))
+ {
+ AUDERR ("Unsupported ASX version (%s)\n", version);
+ return false;
+ }
+
+ return true;
+}
+
+static void parse_entry (const xmlNode * entry, Index<PlaylistAddItem> & items)
+{
+ for (const xmlNode * node = entry->xmlChildrenNode; node; node = node->next)
+ {
+ if (! xmlStrcasecmp (node->name, (const xmlChar *) "ref"))
+ {
+ const char * uri = get_prop_nocase (node, "href");
+ if (uri)
+ items.append (String (uri));
+ }
+ }
+}
+
+bool ASX3Loader::load (const char * filename, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items)
+{
+ xmlDoc * doc = xmlReadIO (read_cb, close_cb, & file, filename, nullptr, XML_PARSE_RECOVER);
+ if (! doc)
+ return false;
+
+ xmlNode * root = xmlDocGetRootElement (doc);
+
+ if (! root || ! check_root (root))
+ {
+ xmlFreeDoc(doc);
+ return false;
+ }
+
+ for (xmlNode * node = root->xmlChildrenNode; node; node = node->next)
+ {
+ if (! xmlStrcasecmp (node->name, (const xmlChar *) "entry"))
+ parse_entry (node, items);
+ else if (! xmlStrcasecmp (node->name, (const xmlChar *) "title"))
+ {
+ if (! title)
+ title = String (get_content (node));
+ }
+ }
+
+ xmlFreeDoc(doc);
+ return true;
+}
+
+bool ASX3Loader::save (const char * filename, VFSFile & file,
+ const char * title, const Index<PlaylistAddItem> & items)
+{
+ xmlDoc * doc = xmlNewDoc ((const xmlChar *) "1.0");
+ doc->charset = XML_CHAR_ENCODING_UTF8;
+ doc->encoding = xmlStrdup ((const xmlChar *) "UTF-8");
+
+ xmlNode * root = xmlNewNode (nullptr, (const xmlChar *) "asx");
+ xmlSetProp (root, (const xmlChar *) "version", (const xmlChar *) "3.0");
+ xmlDocSetRootElement (doc, root);
+
+ if (title)
+ xmlNewTextChild (root, nullptr, (const xmlChar *) "title", (const xmlChar *) title);
+
+ for (auto & item : items)
+ {
+ xmlNode * entry = xmlNewNode (nullptr, (const xmlChar *) "entry");
+ xmlNode * ref = xmlNewNode (nullptr, (const xmlChar *) "ref");
+ xmlSetProp (ref, (const xmlChar *) "href", (const xmlChar *) (const char *) item.filename);
+ xmlAddChild (entry, ref);
+ xmlAddChild (root, entry);
+ }
+
+ xmlSaveCtxt * save = xmlSaveToIO (write_cb, close_cb, & file, nullptr, XML_SAVE_FORMAT);
+
+ if (! save || xmlSaveDoc (save, doc) < 0 || xmlSaveClose (save) < 0)
+ {
+ xmlFreeDoc(doc);
+ return false;
+ }
+
+ xmlFreeDoc (doc);
+ return true;
+}
diff --git a/src/audpl/Makefile b/src/audpl/Makefile
index 243a09408cd5..3a86ec9632f7 100644
--- a/src/audpl/Makefile
+++ b/src/audpl/Makefile
@@ -1,11 +1,13 @@
PLUGIN = audpl${PLUGIN_SUFFIX}
-SRCS = audpl.c
+SRCS = audpl.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${CONTAINER_PLUGIN_DIR}
+LD = ${CXX}
+
CPPFLAGS += -I../..
CFLAGS += ${PLUGIN_CFLAGS}
diff --git a/src/audpl/audpl.c b/src/audpl/audpl.c
deleted file mode 100644
index 25aa621ecde2..000000000000
--- a/src/audpl/audpl.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Audacious playlist format plugin
- * Copyright 2011 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <stdlib.h>
-
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/inifile.h>
-
-typedef struct {
- char * * title;
- Index * filenames;
- Index * tuples;
- char * uri;
- Tuple * tuple;
-} LoadState;
-
-static void finish_item (LoadState * state)
-{
- index_insert (state->filenames, -1, state->uri);
- index_insert (state->tuples, -1, state->tuple);
- state->uri = NULL;
- state->tuple = NULL;
-}
-
-static void handle_heading (const char * heading, void * data)
-{
- /* no headings */
-}
-
-static void handle_entry (const char * key, const char * value, void * data)
-{
- LoadState * state = data;
-
- if (! strcmp (key, "uri"))
- {
- /* finish previous item */
- if (state->uri)
- finish_item (state);
-
- /* start new item */
- state->uri = str_get (value);
- }
- else if (state->uri)
- {
- /* item field */
- if (! state->tuple)
- state->tuple = tuple_new_from_filename (state->uri);
-
- if (strcmp (key, "empty"))
- {
- int field = tuple_field_by_name (key);
- if (field < 0)
- return;
-
- TupleValueType type = tuple_field_get_type (field);
-
- if (type == TUPLE_STRING)
- {
- char buf[strlen (value) + 1];
- str_decode_percent (value, -1, buf);
- tuple_set_str (state->tuple, field, buf);
- }
- else if (type == TUPLE_INT)
- tuple_set_int (state->tuple, field, atoi (value));
- }
- }
- else
- {
- /* top-level field */
- if (! strcmp (key, "title") && ! * state->title)
- {
- char buf[strlen (value) + 1];
- str_decode_percent (value, -1, buf);
- * state->title = str_get (buf);
- }
- }
-}
-
-static bool_t audpl_load (const char * path, VFSFile * file, char * * title,
- Index * filenames, Index * tuples)
-{
- LoadState state = {
- .title = title,
- .filenames = filenames,
- .tuples = tuples
- };
-
- inifile_parse (file, handle_heading, handle_entry, & state);
-
- /* finish last item */
- if (state.uri)
- finish_item (& state);
-
- return TRUE;
-}
-
-static bool_t write_encoded_entry (VFSFile * file, const char * key, const char * val)
-{
- char buf[3 * strlen (val) + 1];
- str_encode_percent (val, -1, buf);
- return inifile_write_entry (file, key, buf);
-}
-
-static bool_t audpl_save (const char * path, VFSFile * file,
- const char * title, Index * filenames, Index * tuples)
-{
- if (! write_encoded_entry (file, "title", title))
- return FALSE;
-
- int count = index_count (filenames);
-
- for (int i = 0; i < count; i ++)
- {
- if (! inifile_write_entry (file, "uri", index_get (filenames, i)))
- return FALSE;
-
- const Tuple * tuple = tuples ? index_get (tuples, i) : NULL;
-
- if (tuple)
- {
- int keys = 0;
-
- for (int f = 0; f < TUPLE_FIELDS; f ++)
- {
- if (f == FIELD_FILE_PATH || f == FIELD_FILE_NAME || f == FIELD_FILE_EXT)
- continue;
-
- TupleValueType type = tuple_get_value_type (tuple, f);
-
- if (type == TUPLE_STRING)
- {
- char * str = tuple_get_str (tuple, f);
-
- if (! write_encoded_entry (file, tuple_field_get_name (f), str))
- {
- str_unref (str);
- return FALSE;
- }
-
- str_unref (str);
- keys ++;
- }
- else if (type == TUPLE_INT)
- {
- char buf[32];
- str_itoa (tuple_get_int (tuple, f), buf, sizeof buf);
-
- if (! inifile_write_entry (file, tuple_field_get_name (f), buf))
- return FALSE;
-
- keys ++;
- }
- }
-
- /* distinguish between an empty tuple and no tuple at all */
- if (! keys && ! inifile_write_entry (file, "empty", "1"))
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-static const char * const audpl_exts[] = {"audpl", NULL};
-
-AUD_PLAYLIST_PLUGIN
-(
- .name = N_("Audacious Playlists (audpl)"),
- .domain = PACKAGE,
- .extensions = audpl_exts,
- .load = audpl_load,
- .save = audpl_save
-)
diff --git a/src/audpl/audpl.cc b/src/audpl/audpl.cc
new file mode 100644
index 000000000000..0549a780cd31
--- /dev/null
+++ b/src/audpl/audpl.cc
@@ -0,0 +1,170 @@
+/*
+ * Audacious playlist format plugin
+ * Copyright 2011 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/inifile.h>
+
+static const char * const audpl_exts[] = {"audpl"};
+
+class AudPlaylistLoader : public PlaylistPlugin
+{
+public:
+ static constexpr PluginInfo info = {N_("Audacious Playlists (audpl)"), PACKAGE};
+
+ constexpr AudPlaylistLoader () : PlaylistPlugin (info, audpl_exts, true) {}
+
+ bool load (const char * filename, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items);
+ bool save (const char * filename, VFSFile & file, const char * title,
+ const Index<PlaylistAddItem> & items);
+};
+
+EXPORT AudPlaylistLoader aud_plugin_instance;
+
+class AudPlaylistParser : private IniParser
+{
+public:
+ AudPlaylistParser (String & title, Index<PlaylistAddItem> & items) :
+ title (title),
+ items (items) {}
+
+ void parse (VFSFile & file)
+ {
+ IniParser::parse (file);
+
+ /* finish last item */
+ if (uri)
+ finish_item ();
+ }
+
+private:
+ String & title;
+ Index<PlaylistAddItem> & items;
+ String uri;
+ Tuple tuple;
+
+ void finish_item ()
+ { items.append (std::move (uri), std::move (tuple)); }
+
+ /* no headings */
+ void handle_heading (const char * heading) {}
+
+ void handle_entry (const char * key, const char * value)
+ {
+ if (! strcmp (key, "uri"))
+ {
+ /* finish previous item */
+ if (uri)
+ finish_item ();
+
+ /* start new item */
+ uri = String (value);
+ }
+ else if (uri)
+ {
+ /* item field */
+ if (! tuple)
+ tuple.set_filename (uri);
+
+ if (strcmp (key, "empty"))
+ {
+ auto field = Tuple::field_by_name (key);
+ if (field == Tuple::Invalid)
+ return;
+
+ auto type = Tuple::field_get_type (field);
+ if (type == Tuple::String)
+ tuple.set_str (field, str_decode_percent (value));
+ else if (type == Tuple::Int)
+ tuple.set_int (field, atoi (value));
+ }
+ }
+ else
+ {
+ /* top-level field */
+ if (! strcmp (key, "title") && ! title)
+ title = String (str_decode_percent (value));
+ }
+ }
+};
+
+bool AudPlaylistLoader::load (const char * path, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items)
+{
+ AudPlaylistParser (title, items).parse (file);
+ return true;
+}
+
+bool AudPlaylistLoader::save (const char * path, VFSFile & file,
+ const char * title, const Index<PlaylistAddItem> & items)
+{
+ if (! inifile_write_entry (file, "title", str_encode_percent (title)))
+ return false;
+
+ for (auto & item : items)
+ {
+ if (! inifile_write_entry (file, "uri", item.filename))
+ return false;
+
+ const Tuple & tuple = item.tuple;
+
+ if (tuple)
+ {
+ int keys = 0;
+
+ for (auto f : Tuple::all_fields ())
+ {
+ if (f == Tuple::Path || f == Tuple::Basename ||
+ f == Tuple::Suffix || f == Tuple::FormattedTitle)
+ continue;
+
+ const char * key = Tuple::field_get_name (f);
+ Tuple::ValueType type = tuple.get_value_type (f);
+
+ if (type == Tuple::String)
+ {
+ String str = tuple.get_str (f);
+ if (! inifile_write_entry (file, key, str_encode_percent (str)))
+ return false;
+
+ keys ++;
+ }
+ else if (type == Tuple::Int)
+ {
+ int val = tuple.get_int (f);
+ if (! inifile_write_entry (file, key, int_to_str (val)))
+ return false;
+
+ keys ++;
+ }
+ }
+
+ /* distinguish between an empty tuple and no tuple at all */
+ if (! keys && ! inifile_write_entry (file, "empty", "1"))
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/src/blur_scope/Makefile b/src/blur_scope/Makefile
index 1398d3c42fab..8f191874d847 100644
--- a/src/blur_scope/Makefile
+++ b/src/blur_scope/Makefile
@@ -1,12 +1,13 @@
PLUGIN = blur_scope${PLUGIN_SUFFIX}
-SRCS = blur_scope.c
+SRCS = blur_scope.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${VISUALIZATION_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} -I../..
LIBS += ${GTK_LIBS} -lm
diff --git a/src/blur_scope/blur_scope.c b/src/blur_scope/blur_scope.c
deleted file mode 100644
index fbfe1859f27c..000000000000
--- a/src/blur_scope/blur_scope.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Blur Scope plugin for Audacious
- * Copyright (C) 2010-2012 John Lindgren
- *
- * Based on BMP - Cross-platform multimedia player:
- * Copyright (C) 2003-2004 BMP development team.
- *
- * Based on XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <math.h>
-#include <string.h>
-
-#include <gtk/gtk.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-#define D_WIDTH 64
-#define D_HEIGHT 32
-
-static gboolean bscope_init (void);
-static void bscope_cleanup(void);
-static void bscope_clear (void);
-static void bscope_render (const gfloat * data);
-static void /* GtkWidget */ * bscope_get_widget (void);
-static void /* GtkWidget */ * bscope_get_color_chooser (void);
-
-static const PreferencesWidget bscope_widgets[] = {
- {WIDGET_LABEL, N_("<b>Color</b>")},
- {WIDGET_CUSTOM, .data = {.populate = bscope_get_color_chooser}}};
-
-static const PluginPreferences bscope_prefs = {
- .widgets = bscope_widgets,
- .n_widgets = ARRAY_LEN (bscope_widgets)};
-
-AUD_VIS_PLUGIN
-(
- .name = N_("Blur Scope"),
- .domain = PACKAGE,
- .prefs = & bscope_prefs,
- .init = bscope_init, /* init */
- .cleanup = bscope_cleanup, /* cleanup */
- .clear = bscope_clear,
- .render_mono_pcm = bscope_render,
- .get_widget = bscope_get_widget,
-)
-
-static GtkWidget * area = NULL;
-static gint width, height, stride, image_size;
-static guint32 * image = NULL, * corner = NULL;
-
-static const gchar * const bscope_defaults[] = {
- "color", "16727935", /* 0xFF3F7F */
- NULL};
-
-static gint color;
-
-static gboolean bscope_init (void)
-{
- aud_config_set_defaults ("BlurScope", bscope_defaults);
- color = aud_get_int ("BlurScope", "color");
-
- return TRUE;
-}
-
-static void bscope_cleanup (void)
-{
- aud_set_int ("BlurScope", "color", color);
-
- g_free (image);
- image = NULL;
-}
-
-static void bscope_resize (gint w, gint h)
-{
- width = w;
- height = h;
- stride = width + 2;
- image_size = (stride << 2) * (height + 2);
- image = g_realloc (image, image_size);
- memset (image, 0, image_size);
- corner = image + stride + 1;
-}
-
-static void bscope_draw_to_cairo (cairo_t * cr)
-{
- cairo_surface_t * surf = cairo_image_surface_create_for_data ((guchar *)
- image, CAIRO_FORMAT_RGB24, width, height, stride << 2);
- cairo_set_source_surface (cr, surf, 0, 0);
- cairo_paint (cr);
- cairo_surface_destroy (surf);
-}
-
-static void bscope_draw (void)
-{
- if (! area || ! gtk_widget_get_window (area))
- return;
-
- cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (area));
- bscope_draw_to_cairo (cr);
- cairo_destroy (cr);
-}
-
-static gboolean configure_event (GtkWidget * widget, GdkEventConfigure * event)
-{
- bscope_resize (event->width, event->height);
- return TRUE;
-}
-
-static gboolean draw_cb (GtkWidget * widget, cairo_t * cr)
-{
- bscope_draw_to_cairo (cr);
- return TRUE;
-}
-
-static void /* GtkWidget */ * bscope_get_widget (void)
-{
- area = gtk_drawing_area_new ();
- gtk_widget_set_size_request (area, D_WIDTH, D_HEIGHT);
- bscope_resize (D_WIDTH, D_HEIGHT);
-
- g_signal_connect (area, "draw", (GCallback) draw_cb, NULL);
- g_signal_connect (area, "configure-event", (GCallback) configure_event, NULL);
- g_signal_connect (area, "destroy", (GCallback) gtk_widget_destroyed, & area);
-
- GtkWidget * frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type ((GtkFrame *) frame, GTK_SHADOW_IN);
- gtk_container_add ((GtkContainer *) frame, area);
- return frame;
-}
-
-static void bscope_clear (void)
-{
- g_return_if_fail (image != NULL);
- memset (image, 0, image_size);
- bscope_draw ();
-}
-
-static void bscope_blur (void)
-{
- for (gint y = 0; y < height; y ++)
- {
- guint32 * p = corner + stride * y;
- guint32 * end = p + width;
- guint32 * plast = p - stride;
- guint32 * pnext = p + stride;
-
- /* We do a quick and dirty average of four color values, first masking
- * off the lowest two bits. Over a large area, this masking has the net
- * effect of subtracting 1.5 from each value, which by a happy chance
- * is just right for a gradual fade effect. */
- for (; p < end; p ++)
- * p = ((* plast ++ & 0xFCFCFC) + (p[-1] & 0xFCFCFC) + (p[1] &
- 0xFCFCFC) + (* pnext ++ & 0xFCFCFC)) >> 2;
- }
-}
-
-static inline void draw_vert_line (gint x, guint y1, gint y2)
-{
- gint y, h;
-
- if (y1 < y2) {y = y1 + 1; h = y2 - y1;}
- else if (y2 < y1) {y = y2; h = y1 - y2;}
- else {y = y1; h = 1;}
-
- guint32 * p = corner + y * stride + x;
-
- for (; h --; p += stride)
- * p = color;
-}
-
-static void bscope_render (const gfloat * data)
-{
- bscope_blur ();
-
- gint prev_y = (0.5 + data[0]) * height;
- prev_y = CLAMP (prev_y, 0, height - 1);
-
- for (gint i = 0; i < width; i ++)
- {
- gint y = (0.5 + data[i * 512 / width]) * height;
- y = CLAMP (y, 0, height - 1);
- draw_vert_line (i, prev_y, y);
- prev_y = y;
- }
-
- bscope_draw ();
-}
-
-static void color_set_cb (GtkWidget * chooser)
-{
- GdkRGBA rgba;
- gtk_color_chooser_get_rgba ((GtkColorChooser *) chooser, & rgba);
-
- int red = round (rgba.red * 255);
- int green = round (rgba.green * 255);
- int blue = round (rgba.blue * 255);
- color = (red << 16) | (green << 8) | blue;
-}
-
-static void /* GtkWidget */ * bscope_get_color_chooser (void)
-{
- GdkRGBA rgba = {
- .red = ((color & 0xff0000) >> 16) / 255.0,
- .green = ((color & 0xff00) >> 8) / 255.0,
- .blue = (color & 0xff) / 255.0};
-
- GtkWidget * chooser = gtk_color_button_new_with_rgba (& rgba);
- gtk_color_chooser_set_use_alpha ((GtkColorChooser *) chooser, FALSE);
-
- g_signal_connect (chooser, "color-set", (GCallback) color_set_cb, NULL);
-
- return chooser;
-}
diff --git a/src/blur_scope/blur_scope.cc b/src/blur_scope/blur_scope.cc
new file mode 100644
index 000000000000..279009d5cd35
--- /dev/null
+++ b/src/blur_scope/blur_scope.cc
@@ -0,0 +1,234 @@
+/*
+ * Blur Scope plugin for Audacious
+ * Copyright (C) 2010-2012 John Lindgren
+ *
+ * Based on BMP - Cross-platform multimedia player:
+ * Copyright (C) 2003-2004 BMP development team.
+ *
+ * Based on XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+
+#define D_WIDTH 64
+#define D_HEIGHT 32
+
+static void /* GtkWidget */ * bscope_get_color_chooser (void);
+
+static const PreferencesWidget bscope_widgets[] = {
+ WidgetLabel (N_("<b>Color</b>")),
+ WidgetCustomGTK (bscope_get_color_chooser)
+};
+
+static const PluginPreferences bscope_prefs = {{bscope_widgets}};
+
+static const char * const bscope_defaults[] = {
+ "color", "16727935", /* 0xFF3F7F */
+ nullptr};
+
+static int bscope_color;
+
+class BlurScope : public VisPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("Blur Scope"),
+ PACKAGE,
+ nullptr,
+ & bscope_prefs
+ };
+
+ constexpr BlurScope () : VisPlugin (info, Visualizer::MonoPCM) {}
+
+ bool init ();
+ void cleanup ();
+
+ void * get_gtk_widget ();
+
+ void clear ();
+ void render_mono_pcm (const float * pcm);
+
+private:
+ void resize (int w, int h);
+ void draw ();
+
+ void blur ();
+ void draw_vert_line (int x, int y1, int y2);
+
+ static gboolean configure_event (GtkWidget * widget, GdkEventConfigure * event, void * user);
+ static gboolean expose_event (GtkWidget * widget, GdkEventExpose * event, void * user);
+
+ GtkWidget * area = nullptr;
+ int width = 0, height = 0, stride = 0, image_size = 0;
+ uint32_t * image = nullptr, * corner = nullptr;
+};
+
+EXPORT BlurScope aud_plugin_instance;
+
+bool BlurScope::init ()
+{
+ aud_config_set_defaults ("BlurScope", bscope_defaults);
+ bscope_color = aud_get_int ("BlurScope", "color");
+
+ return TRUE;
+}
+
+void BlurScope::cleanup ()
+{
+ aud_set_int ("BlurScope", "color", bscope_color);
+
+ g_free (image);
+ image = nullptr;
+}
+
+void BlurScope::resize (int w, int h)
+{
+ width = w;
+ height = h;
+ stride = width + 2;
+ image_size = (stride << 2) * (height + 2);
+ image = (uint32_t *) g_realloc (image, image_size);
+ memset (image, 0, image_size);
+ corner = image + stride + 1;
+}
+
+void BlurScope::draw ()
+{
+ if (! area || ! gtk_widget_get_window (area))
+ return;
+
+ cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (area));
+ cairo_surface_t * surf = cairo_image_surface_create_for_data
+ ((unsigned char *) image, CAIRO_FORMAT_RGB24, width, height, stride << 2);
+ cairo_set_source_surface (cr, surf, 0, 0);
+ cairo_paint (cr);
+ cairo_surface_destroy (surf);
+ cairo_destroy (cr);
+}
+
+gboolean BlurScope::configure_event (GtkWidget * widget, GdkEventConfigure * event, void * user)
+{
+ ((BlurScope *) user)->resize (event->width, event->height);
+ return TRUE;
+}
+
+gboolean BlurScope::expose_event (GtkWidget * widget, GdkEventExpose * event, void * user)
+{
+ ((BlurScope *) user)->draw ();
+ return TRUE;
+}
+
+void * BlurScope::get_gtk_widget ()
+{
+ area = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (area, D_WIDTH, D_HEIGHT);
+ resize (D_WIDTH, D_HEIGHT);
+
+ g_signal_connect (area, "expose-event", (GCallback) expose_event, this);
+ g_signal_connect (area, "configure-event", (GCallback) configure_event, this);
+ g_signal_connect (area, "destroy", (GCallback) gtk_widget_destroyed, & area);
+
+ GtkWidget * frame = gtk_frame_new (nullptr);
+ gtk_frame_set_shadow_type ((GtkFrame *) frame, GTK_SHADOW_IN);
+ gtk_container_add ((GtkContainer *) frame, area);
+ return frame;
+}
+
+void BlurScope::clear ()
+{
+ memset (image, 0, image_size);
+ draw ();
+}
+
+void BlurScope::blur ()
+{
+ for (int y = 0; y < height; y ++)
+ {
+ uint32_t * p = corner + stride * y;
+ uint32_t * end = p + width;
+ uint32_t * plast = p - stride;
+ uint32_t * pnext = p + stride;
+
+ /* We do a quick and dirty average of four color values, first masking
+ * off the lowest two bits. Over a large area, this masking has the net
+ * effect of subtracting 1.5 from each value, which by a happy chance
+ * is just right for a gradual fade effect. */
+ for (; p < end; p ++)
+ * p = ((* plast ++ & 0xFCFCFC) + (p[-1] & 0xFCFCFC) + (p[1] &
+ 0xFCFCFC) + (* pnext ++ & 0xFCFCFC)) >> 2;
+ }
+}
+
+void BlurScope::draw_vert_line (int x, int y1, int y2)
+{
+ int y, h;
+
+ if (y1 < y2) {y = y1 + 1; h = y2 - y1;}
+ else if (y2 < y1) {y = y2; h = y1 - y2;}
+ else {y = y1; h = 1;}
+
+ uint32_t * p = corner + y * stride + x;
+
+ for (; h --; p += stride)
+ * p = bscope_color;
+}
+
+void BlurScope::render_mono_pcm (const float * pcm)
+{
+ blur ();
+
+ int prev_y = (0.5 + pcm[0]) * height;
+ prev_y = aud::clamp (prev_y, 0, height - 1);
+
+ for (int i = 0; i < width; i ++)
+ {
+ int y = (0.5 + pcm[i * 512 / width]) * height;
+ y = aud::clamp (y, 0, height - 1);
+ draw_vert_line (i, prev_y, y);
+ prev_y = y;
+ }
+
+ draw ();
+}
+
+static void color_set_cb (GtkWidget * chooser)
+{
+ GdkColor gdk_color;
+ gtk_color_button_get_color ((GtkColorButton *) chooser, & gdk_color);
+ bscope_color = ((gdk_color.red & 0xff00) << 8) | (gdk_color.green & 0xff00) | (gdk_color.blue >> 8);
+}
+
+static void /* GtkWidget */ * bscope_get_color_chooser (void)
+{
+ GdkColor gdk_color = {0, (uint16_t) ((bscope_color & 0xff0000) >> 8),
+ (uint16_t) (bscope_color & 0xff00), (uint16_t) ((bscope_color & 0xff) << 8)};
+ GtkWidget * chooser = gtk_color_button_new_with_color (& gdk_color);
+ gtk_color_button_set_use_alpha ((GtkColorButton *) chooser, FALSE);
+
+ g_signal_connect (chooser, "color-set", (GCallback) color_set_cb, nullptr);
+
+ return chooser;
+}
diff --git a/src/bs2b/Makefile b/src/bs2b/Makefile
index 49c4f9b574f1..fd6b5f307775 100644
--- a/src/bs2b/Makefile
+++ b/src/bs2b/Makefile
@@ -1,12 +1,13 @@
PLUGIN = bs2b${PLUGIN_SUFFIX}
-SRCS = plugin.c
+SRCS = plugin.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${BS2B_CFLAGS} -I../..
-LIBS += ${GTK_LIBS} ${BS2B_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${BS2B_CFLAGS} -I../..
+LIBS += ${BS2B_LIBS}
diff --git a/src/bs2b/plugin.c b/src/bs2b/plugin.c
deleted file mode 100644
index 9c0228ffbf58..000000000000
--- a/src/bs2b/plugin.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Audacious bs2b effect plugin
- * Copyright (C) 2009, Sebastian Pipping <sebastian at pipping.org>
- * Copyright (C) 2009, Tony Vroon <chainsaw at gentoo.org>
- * Copyright (C) 2010, John Lindgren <john.lindgren at tds.net>
- * Copyright (C) 2011, MichaÅ Lipski <tallica at o2.pl>
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-#include <bs2b.h>
-
-static t_bs2bdp bs2b = NULL;
-static int bs2b_channels;
-static GtkWidget * feed_slider, * fcut_slider;
-
-static const char * const bs2b_defaults[] = {
- "feed", "45",
- "fcut", "700",
- NULL};
-
-bool_t init (void)
-{
- aud_config_set_defaults ("bs2b", bs2b_defaults);
- bs2b = bs2b_open ();
-
- if (! bs2b)
- return FALSE;
-
- bs2b_set_level_feed (bs2b, aud_get_int ("bs2b", "feed"));
- bs2b_set_level_fcut (bs2b, aud_get_int ("bs2b", "fcut"));
-
- return TRUE;
-}
-
-static void cleanup (void)
-{
- if (! bs2b)
- return;
-
- bs2b_close (bs2b);
- bs2b = NULL;
-}
-
-static void bs2b_start (int * channels, int * rate)
-{
- if (! bs2b)
- return;
-
- bs2b_channels = * channels;
-
- if (* channels != 2)
- return;
-
- bs2b_set_srate (bs2b, * rate);
-}
-
-static void bs2b_process (float * * data, int * samples)
-{
- if (! bs2b || bs2b_channels != 2)
- return;
-
- bs2b_cross_feed_f (bs2b, * data, (* samples) / 2);
-}
-
-static void bs2b_finish (float * * data, int * samples)
-{
- bs2b_process (data, samples);
-}
-
-static void feed_value_changed (GtkRange * range, gpointer data)
-{
- int feed_level = gtk_range_get_value (range);
- aud_set_int ("bs2b", "feed", feed_level);
- bs2b_set_level_feed (bs2b, feed_level);
-}
-
-static char * feed_format_value (GtkScale * scale, double value)
-{
- return g_strdup_printf ("%.1f dB", (float) value / 10);
-}
-
-static void fcut_value_changed (GtkRange * range, gpointer data)
-{
- int fcut_level = gtk_range_get_value (range);
- aud_set_int ("bs2b", "fcut", fcut_level);
- bs2b_set_level_fcut (bs2b, fcut_level);
-}
-
-static char * fcut_format_value (GtkScale * scale, double value)
-{
- return g_strdup_printf ("%d Hz, %d µs", (int) value, bs2b_level_delay ((int) value));
-}
-
-static void preset_button_clicked (GtkButton * button, gpointer data)
-{
- int clevel = GPOINTER_TO_INT (data);
- gtk_range_set_value ((GtkRange *) feed_slider, clevel >> 16);
- gtk_range_set_value ((GtkRange *) fcut_slider, clevel & 0xffff);
-}
-
-static GtkWidget * preset_button (const char * label, int clevel)
-{
- GtkWidget * button = gtk_button_new_with_label (label);
- gtk_button_set_relief ((GtkButton *) button, GTK_RELIEF_NONE);
- g_signal_connect (button, "clicked", (GCallback)
- preset_button_clicked, GINT_TO_POINTER (clevel));
-
- return button;
-}
-
-static void * create_config_widget (void)
-{
- int feed_level = aud_get_int ("bs2b", "feed");
- int fcut_level = aud_get_int ("bs2b", "fcut");
-
- GtkWidget * vbox, * hbox, * button;
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start ((GtkBox *) vbox, hbox, FALSE, FALSE, 0);
-
- gtk_box_pack_start ((GtkBox *) hbox, gtk_label_new (_("Feed level:")), TRUE, FALSE, 0);
-
- feed_slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, BS2B_MINFEED, BS2B_MAXFEED, 1.0);
- gtk_range_set_value ((GtkRange *) feed_slider, feed_level);
- gtk_widget_set_size_request (feed_slider, 200, -1);
- gtk_box_pack_start ((GtkBox *) hbox, feed_slider, FALSE, FALSE, 0);
- g_signal_connect (feed_slider, "value-changed", (GCallback) feed_value_changed, NULL);
- g_signal_connect (feed_slider, "format-value", (GCallback) feed_format_value, NULL);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start ((GtkBox *) vbox, hbox, FALSE, FALSE, 0);
-
- gtk_box_pack_start ((GtkBox *) hbox, gtk_label_new (_("Cut frequency:")), TRUE, FALSE, 0);
-
- fcut_slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, BS2B_MINFCUT, BS2B_MAXFCUT, 1.0);
- gtk_range_set_value ((GtkRange *) fcut_slider, fcut_level);
- gtk_widget_set_size_request (fcut_slider, 200, -1);
- gtk_box_pack_start ((GtkBox *) hbox, fcut_slider, FALSE, FALSE, 0);
- g_signal_connect (fcut_slider, "value-changed", (GCallback) fcut_value_changed, NULL);
- g_signal_connect (fcut_slider, "format-value", (GCallback) fcut_format_value, NULL);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start ((GtkBox *) vbox, hbox, FALSE, FALSE, 0);
-
- gtk_box_pack_start ((GtkBox *) hbox, gtk_label_new (_("Presets:")), TRUE, FALSE, 0);
-
- button = preset_button (_("Default"), BS2B_DEFAULT_CLEVEL);
- gtk_box_pack_start ((GtkBox *) hbox, button, TRUE, FALSE, 0);
-
- button = preset_button ("C. Moy", BS2B_CMOY_CLEVEL);
- gtk_box_pack_start ((GtkBox *) hbox, button, TRUE, FALSE, 0);
-
- button = preset_button ("J. Meier", BS2B_JMEIER_CLEVEL);
- gtk_box_pack_start ((GtkBox *) hbox, button, TRUE, FALSE, 0);
-
- return vbox;
-}
-
-static const PreferencesWidget bs2b_widgets[] = {
- {WIDGET_CUSTOM, .data.populate = create_config_widget}};
-
-static const PluginPreferences bs2b_prefs = {
- .widgets = bs2b_widgets,
- .n_widgets = ARRAY_LEN (bs2b_widgets)};
-
-AUD_EFFECT_PLUGIN
-(
- .name = N_("Bauer Stereophonic-to-Binaural (BS2B)"),
- .domain = PACKAGE,
- .init = init,
- .cleanup = cleanup,
- .prefs = & bs2b_prefs,
- .start = bs2b_start,
- .process = bs2b_process,
- .finish = bs2b_finish,
- .preserves_format = TRUE
-)
diff --git a/src/bs2b/plugin.cc b/src/bs2b/plugin.cc
new file mode 100644
index 000000000000..e208a76ad5ef
--- /dev/null
+++ b/src/bs2b/plugin.cc
@@ -0,0 +1,145 @@
+/*
+ * Audacious bs2b effect plugin
+ * Copyright (C) 2009, Sebastian Pipping <sebastian at pipping.org>
+ * Copyright (C) 2009, Tony Vroon <chainsaw at gentoo.org>
+ * Copyright (C) 2010, John Lindgren <john.lindgren at tds.net>
+ * Copyright (C) 2011, MichaÅ Lipski <tallica at o2.pl>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+
+#include <bs2b.h>
+
+class BS2BPlugin : public EffectPlugin
+{
+public:
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Bauer Stereophonic-to-Binaural (BS2B)"),
+ PACKAGE,
+ nullptr,
+ & prefs
+ };
+
+ constexpr BS2BPlugin () : EffectPlugin (info, 0, true) {}
+
+ bool init ();
+ void cleanup ();
+
+ void start (int & channels, int & rate);
+ Index<float> & process (Index<float> & data);
+};
+
+EXPORT BS2BPlugin aud_plugin_instance;
+
+static t_bs2bdp bs2b = nullptr;
+static int bs2b_channels;
+
+const char * const BS2BPlugin::defaults[] = {
+ "feed", "45",
+ "fcut", "700",
+ nullptr};
+
+bool BS2BPlugin::init ()
+{
+ aud_config_set_defaults ("bs2b", defaults);
+ bs2b = bs2b_open ();
+
+ if (! bs2b)
+ return false;
+
+ bs2b_set_level_feed (bs2b, aud_get_int ("bs2b", "feed"));
+ bs2b_set_level_fcut (bs2b, aud_get_int ("bs2b", "fcut"));
+
+ return true;
+}
+
+void BS2BPlugin::cleanup ()
+{
+ bs2b_close (bs2b);
+ bs2b = nullptr;
+}
+
+void BS2BPlugin::start (int & channels, int & rate)
+{
+ bs2b_channels = channels;
+ bs2b_set_srate (bs2b, rate);
+}
+
+Index<float> & BS2BPlugin::process (Index<float> & data)
+{
+ if (bs2b_channels == 2)
+ bs2b_cross_feed_f (bs2b, data.begin (), data.len () / 2);
+
+ return data;
+}
+
+static void feed_value_changed ()
+{
+ bs2b_set_level_feed (bs2b, aud_get_int ("bs2b", "feed"));
+}
+
+static void fcut_value_changed ()
+{
+ bs2b_set_level_fcut (bs2b, aud_get_int ("bs2b", "fcut"));
+}
+
+static void set_preset (uint32_t preset)
+{
+ int feed = preset >> 16;
+ int fcut = preset & 0xffff;
+
+ aud_set_int ("bs2b", "feed", feed);
+ aud_set_int ("bs2b", "fcut", fcut);
+
+ bs2b_set_level_feed (bs2b, feed);
+ bs2b_set_level_fcut (bs2b, fcut);
+
+ hook_call ("bs2b preset loaded", nullptr);
+}
+
+static void set_default_preset ()
+ { set_preset (BS2B_DEFAULT_CLEVEL); }
+static void set_cmoy_preset ()
+ { set_preset (BS2B_CMOY_CLEVEL); }
+static void set_jmeier_preset ()
+ { set_preset (BS2B_JMEIER_CLEVEL); }
+
+static const PreferencesWidget preset_widgets[] = {
+ WidgetLabel (N_("Presets:")),
+ WidgetButton (N_("Default"), {set_default_preset}),
+ WidgetButton ("C. Moy", {set_cmoy_preset}),
+ WidgetButton ("J. Meier", {set_jmeier_preset})
+};
+
+const PreferencesWidget BS2BPlugin::widgets[] = {
+ WidgetSpin (N_("Feed level:"),
+ WidgetInt ("bs2b", "feed", feed_value_changed, "bs2b preset loaded"),
+ {BS2B_MINFEED, BS2B_MAXFEED, 1, N_("x1/10 dB")}),
+ WidgetSpin (N_("Cut frequency:"),
+ WidgetInt ("bs2b", "fcut", fcut_value_changed, "bs2b preset loaded"),
+ {BS2B_MINFCUT, BS2B_MAXFCUT, 1, N_("Hz")}),
+ WidgetBox ({{preset_widgets}, true})
+};
+
+const PluginPreferences BS2BPlugin::prefs = {{widgets}};
diff --git a/src/cairo-spectrum/Makefile b/src/cairo-spectrum/Makefile
index 42aa5912c6e7..429144c453d3 100644
--- a/src/cairo-spectrum/Makefile
+++ b/src/cairo-spectrum/Makefile
@@ -1,12 +1,13 @@
PLUGIN = cairo-spectrum${PLUGIN_SUFFIX}
-SRCS = cairo-spectrum.c
+SRCS = cairo-spectrum.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${VISUALIZATION_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../.. ${GTK_CFLAGS}
LIBS += -lm ${GTK_LIBS}
diff --git a/src/cairo-spectrum/cairo-spectrum.c b/src/cairo-spectrum/cairo-spectrum.c
deleted file mode 100644
index b396c1b3c337..000000000000
--- a/src/cairo-spectrum/cairo-spectrum.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (c) 2011 William Pitcock <nenolod at dereferenced.org>.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <math.h>
-#include <gtk/gtk.h>
-
-#include <audacious/debug.h>
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <audacious/plugin.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#define MAX_BANDS (256)
-#define VIS_DELAY 2 /* delay before falloff in frames */
-#define VIS_FALLOFF 2 /* falloff in pixels per frame */
-
-static GtkWidget * spect_widget = NULL;
-static gfloat xscale[MAX_BANDS + 1];
-static gint width, height, bands;
-static gint bars[MAX_BANDS + 1];
-static gint delay[MAX_BANDS + 1];
-
-static void calculate_xscale (void)
-{
- for (gint i = 0; i <= bands; i ++)
- xscale[i] = powf (256, (gfloat) i / bands) - 0.5f;
-}
-
-static void render_cb (gfloat * freq)
-{
- g_return_if_fail (spect_widget);
-
- if (! bands)
- return;
-
- for (gint i = 0; i < bands; i ++)
- {
- gint a = ceilf (xscale[i]);
- gint b = floorf (xscale[i + 1]);
- gfloat n = 0;
-
- if (b < a)
- n += freq[b] * (xscale[i + 1] - xscale[i]);
- else
- {
- if (a > 0)
- n += freq[a - 1] * (a - xscale[i]);
- for (; a < b; a ++)
- n += freq[a];
- if (b < 256)
- n += freq[b] * (xscale[i + 1] - b);
- }
-
- /* fudge factor to make the graph have the same overall height as a
- 12-band one no matter how many bands there are */
- n *= (gfloat) bands / 12;
-
- /* 40 dB range */
- gint x = 40 + 20 * log10f (n);
- x = CLAMP (x, 0, 40);
-
- bars[i] -= MAX (0, VIS_FALLOFF - delay[i]);
-
- if (delay[i])
- delay[i]--;
-
- if (x > bars[i])
- {
- bars[i] = x;
- delay[i] = VIS_DELAY;
- }
- }
-
- gtk_widget_queue_draw (spect_widget);
-}
-
-static void rgb_to_hsv (gfloat r, gfloat g, gfloat b, gfloat * h, gfloat * s, gfloat * v)
-{
- gfloat max, min;
-
- max = r;
- if (g > max)
- max = g;
- if (b > max)
- max = b;
-
- min = r;
- if (g < min)
- min = g;
- if (b < min)
- min = b;
-
- * v = max;
-
- if (max == min)
- {
- * h = 0;
- * s = 0;
- return;
- }
-
- if (r == max)
- * h = 1 + (g - b) / (max - min);
- else if (g == max)
- * h = 3 + (b - r) / (max - min);
- else
- * h = 5 + (r - g) / (max - min);
-
- * s = (max - min) / max;
-}
-
-static void hsv_to_rgb (gfloat h, gfloat s, gfloat v, gfloat * r, gfloat * g, gfloat * b)
-{
- for (; h >= 2; h -= 2)
- {
- gfloat * p = r;
- r = g;
- g = b;
- b = p;
- }
-
- if (h < 1)
- {
- * r = 1;
- * g = 0;
- * b = 1 - h;
- }
- else
- {
- * r = 1;
- * g = h - 1;
- * b = 0;
- }
-
- * r = v * (1 - s * (1 - * r));
- * g = v * (1 - s * (1 - * g));
- * b = v * (1 - s * (1 - * b));
-}
-
-static void get_color (gint i, gfloat * r, gfloat * g, gfloat * b)
-{
- static GdkRGBA c;
- static bool_t valid = FALSE;
- gfloat h, s, v, n;
-
- if (! valid)
- {
- /* we want a color that matches the current theme
- * selected color of a GtkEntry should be reasonable */
- GtkStyleContext * style = gtk_style_context_new ();
- GtkWidgetPath * path = gtk_widget_path_new ();
- gtk_widget_path_append_type (path, GTK_TYPE_ENTRY);
- gtk_style_context_set_path (style, path);
- gtk_widget_path_free (path);
- gtk_style_context_get_background_color (style, GTK_STATE_FLAG_SELECTED, & c);
- g_object_unref (style);
- valid = TRUE;
- }
-
- rgb_to_hsv (c.red, c.green, c.blue, & h, & s, & v);
-
- if (s < 0.1) /* monochrome theme? use blue instead */
- {
- h = 5;
- s = 0.75;
- }
-
- n = i / (gfloat) (bands - 1);
- s = 1 - 0.9 * n;
- v = 0.75 + 0.25 * n;
-
- hsv_to_rgb (h, s, v, r, g, b);
-}
-
-static void draw_background (GtkWidget * area, cairo_t * cr)
-{
-#if 0
- GdkColor * c = (gtk_widget_get_style (area))->bg;
-#endif
- GtkAllocation alloc;
- gtk_widget_get_allocation (area, & alloc);
-
-#if 0
- gdk_cairo_set_source_color(cr, c);
-#endif
- cairo_rectangle(cr, 0, 0, alloc.width, alloc.height);
- cairo_fill (cr);
-}
-
-#if 0
-static void draw_grid (GtkWidget * area, cairo_t * cr)
-{
- GdkColor * c = (gtk_widget_get_style (area))->bg;
- GtkAllocation alloc;
- gtk_widget_get_allocation (area, & alloc);
- gint i;
- gfloat base_s = (height / 40);
-
- for (i = 1; i < 41; i++)
- {
- gdk_cairo_set_source_color(cr, c);
- cairo_move_to(cr, 0.0, i * base_s);
- cairo_line_to(cr, alloc.width, i * base_s);
- cairo_stroke(cr);
- }
-}
-#endif
-
-static void draw_visualizer (GtkWidget *widget, cairo_t *cr)
-{
- gfloat base_s = (height / 40);
-
- for (gint i = 0; i <= bands; i++)
- {
- gint x = ((width / bands) * i) + 2;
- gfloat r, g, b;
-
- get_color (i, & r, & g, & b);
- cairo_set_source_rgb (cr, r, g, b);
- cairo_rectangle (cr, x + 1, height - (bars[i] * base_s), (width / bands) - 1, (bars[i] * base_s));
- cairo_fill (cr);
- }
-}
-
-static gboolean configure_event (GtkWidget * widget, GdkEventConfigure * event)
-{
- width = event->width;
- height = event->height;
- gtk_widget_queue_draw(widget);
-
- bands = width / 10;
- bands = CLAMP(bands, 12, MAX_BANDS);
- calculate_xscale ();
-
- return TRUE;
-}
-
-static gboolean draw_event (GtkWidget * widget, cairo_t * cr, GtkWidget * area)
-{
-
- draw_background (widget, cr);
- draw_visualizer (widget, cr);
-#if 0
- draw_grid (widget, cr);
-#endif
-
- return TRUE;
-}
-
-static gboolean destroy_event (void)
-{
- aud_vis_func_remove ((VisFunc) render_cb);
- spect_widget = NULL;
- return TRUE;
-}
-
-static /* GtkWidget * */ gpointer get_widget(void)
-{
- GtkWidget *area = gtk_drawing_area_new();
- spect_widget = area;
-
- g_signal_connect(area, "draw", (GCallback) draw_event, NULL);
- g_signal_connect(area, "configure-event", (GCallback) configure_event, NULL);
- g_signal_connect(area, "destroy", (GCallback) destroy_event, NULL);
-
- aud_vis_func_add (AUD_VIS_TYPE_FREQ, (VisFunc) render_cb);
-
- GtkWidget * frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type ((GtkFrame *) frame, GTK_SHADOW_IN);
- gtk_container_add ((GtkContainer *) frame, area);
- return frame;
-}
-
-AUD_VIS_PLUGIN
-(
- .name = N_("Spectrum Analyzer"),
- .domain = PACKAGE,
- .get_widget = get_widget
-)
diff --git a/src/cairo-spectrum/cairo-spectrum.cc b/src/cairo-spectrum/cairo-spectrum.cc
new file mode 100644
index 000000000000..11f87ffe4452
--- /dev/null
+++ b/src/cairo-spectrum/cairo-spectrum.cc
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2011 William Pitcock <nenolod at dereferenced.org>.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <math.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudgui/libaudgui.h>
+#include <libaudgui/libaudgui-gtk.h>
+
+#define MAX_BANDS (256)
+#define VIS_DELAY 2 /* delay before falloff in frames */
+#define VIS_FALLOFF 2 /* falloff in pixels per frame */
+
+class CairoSpectrum : public VisPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("Spectrum Analyzer"),
+ PACKAGE
+ };
+
+ constexpr CairoSpectrum () : VisPlugin (info, Visualizer::Freq) {}
+
+ void * get_gtk_widget ();
+
+ void clear ();
+ void render_freq (const float * freq);
+};
+
+EXPORT CairoSpectrum aud_plugin_instance;
+
+static GtkWidget * spect_widget = nullptr;
+static float xscale[MAX_BANDS + 1];
+static int width, height, bands;
+static int bars[MAX_BANDS + 1];
+static int delay[MAX_BANDS + 1];
+
+static void calculate_xscale ()
+{
+ for (int i = 0; i <= bands; i ++)
+ xscale[i] = powf (256, (float) i / bands) - 0.5f;
+}
+
+void CairoSpectrum::render_freq (const float * freq)
+{
+ if (! bands)
+ return;
+
+ for (int i = 0; i < bands; i ++)
+ {
+ int a = ceilf (xscale[i]);
+ int b = floorf (xscale[i + 1]);
+ float n = 0;
+
+ if (b < a)
+ n += freq[b] * (xscale[i + 1] - xscale[i]);
+ else
+ {
+ if (a > 0)
+ n += freq[a - 1] * (a - xscale[i]);
+ for (; a < b; a ++)
+ n += freq[a];
+ if (b < 256)
+ n += freq[b] * (xscale[i + 1] - b);
+ }
+
+ /* fudge factor to make the graph have the same overall height as a
+ 12-band one no matter how many bands there are */
+ n *= (float) bands / 12;
+
+ /* 40 dB range */
+ int x = 40 + 20 * log10f (n);
+ x = aud::clamp (x, 0, 40);
+
+ bars[i] -= aud::max (0, VIS_FALLOFF - delay[i]);
+
+ if (delay[i])
+ delay[i]--;
+
+ if (x > bars[i])
+ {
+ bars[i] = x;
+ delay[i] = VIS_DELAY;
+ }
+ }
+
+ if (spect_widget)
+ gtk_widget_queue_draw (spect_widget);
+}
+
+void CairoSpectrum::clear ()
+{
+ memset (bars, 0, sizeof bars);
+ memset (delay, 0, sizeof delay);
+
+ if (spect_widget)
+ gtk_widget_queue_draw (spect_widget);
+}
+
+static void rgb_to_hsv (float r, float g, float b, float * h, float * s, float * v)
+{
+ float max, min;
+
+ max = r;
+ if (g > max)
+ max = g;
+ if (b > max)
+ max = b;
+
+ min = r;
+ if (g < min)
+ min = g;
+ if (b < min)
+ min = b;
+
+ * v = max;
+
+ if (max == min)
+ {
+ * h = 0;
+ * s = 0;
+ return;
+ }
+
+ if (r == max)
+ * h = 1 + (g - b) / (max - min);
+ else if (g == max)
+ * h = 3 + (b - r) / (max - min);
+ else
+ * h = 5 + (r - g) / (max - min);
+
+ * s = (max - min) / max;
+}
+
+static void hsv_to_rgb (float h, float s, float v, float * r, float * g, float * b)
+{
+ for (; h >= 2; h -= 2)
+ {
+ float * p = r;
+ r = g;
+ g = b;
+ b = p;
+ }
+
+ if (h < 1)
+ {
+ * r = 1;
+ * g = 0;
+ * b = 1 - h;
+ }
+ else
+ {
+ * r = 1;
+ * g = h - 1;
+ * b = 0;
+ }
+
+ * r = v * (1 - s * (1 - * r));
+ * g = v * (1 - s * (1 - * g));
+ * b = v * (1 - s * (1 - * b));
+}
+
+static void get_color (GtkWidget * widget, int i, float * r, float * g, float * b)
+{
+ GdkColor * c = (gtk_widget_get_style (widget))->base + GTK_STATE_SELECTED;
+ float h, s, v;
+
+ rgb_to_hsv (c->red / 65535.0, c->green / 65535.0, c->blue / 65535.0, & h, & s, & v);
+
+ if (s < 0.1) /* monochrome theme? use blue instead */
+ {
+ h = 5;
+ s = 0.75;
+ }
+
+ s = 1 - 0.9 * i / (bands - 1);
+ v = 0.75 + 0.25 * i / (bands - 1);
+
+ hsv_to_rgb (h, s, v, r, g, b);
+}
+
+static void draw_background (GtkWidget * area, cairo_t * cr)
+{
+ GtkAllocation alloc;
+ gtk_widget_get_allocation (area, & alloc);
+
+ cairo_rectangle(cr, 0, 0, alloc.width, alloc.height);
+ cairo_fill (cr);
+}
+
+static void draw_visualizer (GtkWidget *widget, cairo_t *cr)
+{
+ for (int i = 0; i < bands; i++)
+ {
+ int x = ((width / bands) * i) + 2;
+ float r, g, b;
+
+ get_color (widget, i, & r, & g, & b);
+ cairo_set_source_rgb (cr, r, g, b);
+ cairo_rectangle (cr, x + 1, height - (bars[i] * height / 40),
+ (width / bands) - 1, (bars[i] * height / 40));
+ cairo_fill (cr);
+ }
+}
+
+static gboolean configure_event (GtkWidget * widget, GdkEventConfigure * event)
+{
+ width = event->width;
+ height = event->height;
+ gtk_widget_queue_draw(widget);
+
+ bands = width / 10;
+ bands = aud::clamp(bands, 12, MAX_BANDS);
+ calculate_xscale ();
+
+ return TRUE;
+}
+
+static gboolean draw_event (GtkWidget * widget)
+{
+ cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (widget));
+
+ draw_background (widget, cr);
+ draw_visualizer (widget, cr);
+
+ cairo_destroy (cr);
+ return TRUE;
+}
+
+void * CairoSpectrum::get_gtk_widget ()
+{
+ GtkWidget *area = gtk_drawing_area_new();
+ spect_widget = area;
+
+ g_signal_connect(area, "expose-event", (GCallback) draw_event, nullptr);
+ g_signal_connect(area, "configure-event", (GCallback) configure_event, nullptr);
+ g_signal_connect(area, "destroy", (GCallback) gtk_widget_destroyed, & spect_widget);
+
+ GtkWidget * frame = gtk_frame_new (nullptr);
+ gtk_frame_set_shadow_type ((GtkFrame *) frame, GTK_SHADOW_IN);
+ gtk_container_add ((GtkContainer *) frame, area);
+ return frame;
+}
diff --git a/src/cd-menu-items/Makefile b/src/cd-menu-items/Makefile
index ce8dac136b4b..824a9d168686 100644
--- a/src/cd-menu-items/Makefile
+++ b/src/cd-menu-items/Makefile
@@ -1,12 +1,13 @@
PLUGIN = cd-menu-items${PLUGIN_SUFFIX}
-SRCS = cd-menu-items.c
+SRCS = cd-menu-items.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
CPPFLAGS += -I../.. ${GTK_CFLAGS}
CFLAGS += ${PLUGIN_CFLAGS}
LIBS += ${GTK_LIBS}
diff --git a/src/cd-menu-items/cd-menu-items.c b/src/cd-menu-items/cd-menu-items.c
deleted file mode 100644
index 4fd04f7b624a..000000000000
--- a/src/cd-menu-items/cd-menu-items.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * cd-menu-items.c
- * Copyright 2009-2011 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <gtk/gtk.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-#define N_ITEMS 2
-#define N_MENUS 3
-
-static const gchar * titles[N_ITEMS] = {N_("Play CD"), N_("Add CD")};
-static const gint menus[N_MENUS] = {AUD_MENU_MAIN, AUD_MENU_PLAYLIST_ADD, AUD_MENU_PLAYLIST};
-
-static void cd_play (void) {aud_drct_pl_open ("cdda://"); }
-static void cd_add (void) {aud_drct_pl_add ("cdda://", -1); }
-static MenuFunc funcs[N_ITEMS] = {cd_play, cd_add};
-
-static gboolean cd_init (void)
-{
- for (gint m = 0; m < N_MENUS; m ++)
- for (gint i = 0; i < N_ITEMS; i ++)
- aud_plugin_menu_add (menus[m], funcs[i], _(titles[i]), "media-optical");
-
- return TRUE;
-}
-
-void cd_cleanup (void)
-{
- for (gint m = 0; m < N_MENUS; m ++)
- for (gint i = 0; i < N_ITEMS; i ++)
- aud_plugin_menu_remove (menus[m], funcs[i]);
-}
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("Audio CD Menu Items"),
- .domain = PACKAGE,
- .enabled_by_default = TRUE,
- .init = cd_init,
- .cleanup = cd_cleanup,
-)
diff --git a/src/cd-menu-items/cd-menu-items.cc b/src/cd-menu-items/cd-menu-items.cc
new file mode 100644
index 000000000000..0719fc4712cc
--- /dev/null
+++ b/src/cd-menu-items/cd-menu-items.cc
@@ -0,0 +1,73 @@
+/*
+ * cd-menu-items.c
+ * Copyright 2009-2011 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+
+#define N_ITEMS 2
+#define N_MENUS 3
+
+class CDMenuItems : public GeneralPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("Audio CD Menu Items"),
+ PACKAGE
+ };
+
+ constexpr CDMenuItems () : GeneralPlugin (info, true) {}
+
+ bool init ();
+ void cleanup ();
+};
+
+EXPORT CDMenuItems aud_plugin_instance;
+
+static constexpr const char * titles[N_ITEMS] = {N_("Play CD"), N_("Add CD")};
+
+static constexpr AudMenuID menus[N_MENUS] = {
+ AudMenuID::Main,
+ AudMenuID::PlaylistAdd,
+ AudMenuID::Playlist
+};
+
+static void cd_play () {aud_drct_pl_open ("cdda://"); }
+static void cd_add () {aud_drct_pl_add ("cdda://", -1); }
+static void (* funcs[N_ITEMS]) () = {cd_play, cd_add};
+
+bool CDMenuItems::init ()
+{
+ for (int m = 0; m < N_MENUS; m ++)
+ for (int i = 0; i < N_ITEMS; i ++)
+ aud_plugin_menu_add (menus[m], funcs[i], _(titles[i]), "media-optical");
+
+ return TRUE;
+}
+
+void CDMenuItems::cleanup ()
+{
+ for (int m = 0; m < N_MENUS; m ++)
+ for (int i = 0; i < N_ITEMS; i ++)
+ aud_plugin_menu_remove (menus[m], funcs[i]);
+}
diff --git a/src/cdaudio-ng/Makefile b/src/cdaudio-ng/Makefile
index ffe42c23d1d1..59f125ad8078 100644
--- a/src/cdaudio-ng/Makefile
+++ b/src/cdaudio-ng/Makefile
@@ -1,12 +1,14 @@
PLUGIN = cdaudio-ng${PLUGIN_SUFFIX}
-SRCS = cdaudio-ng.c
+SRCS = cdaudio-ng.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} ${CDIO_CFLAGS} ${CDDB_CFLAGS} -I../..
-LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${CDIO_LIBS} ${CDDB_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${CDIO_CFLAGS} ${CDDB_CFLAGS} -I../..
+LIBS += ${CDIO_LIBS} ${CDDB_LIBS}
diff --git a/src/cdaudio-ng/cdaudio-ng.c b/src/cdaudio-ng/cdaudio-ng.c
deleted file mode 100644
index 7e70de244409..000000000000
--- a/src/cdaudio-ng/cdaudio-ng.c
+++ /dev/null
@@ -1,873 +0,0 @@
-/*
- * Audacious CD Digital Audio plugin
- *
- * Copyright (c) 2007 Calin Crisan <ccrisan at gmail.com>
- * Copyright (c) 2009-2012 John Lindgren <john.lindgren at aol.com>
- * Copyright (c) 2009 Tomasz MoÅ <desowin at gmail.com>
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- */
-
-#include <pthread.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/* prevent libcdio from redefining PACKAGE, VERSION, etc. */
-#define EXTERNAL_LIBCDIO_CONFIG_H
-
-#include <cdio/cdio.h>
-#include <cdio/cdtext.h>
-#include <cdio/track.h>
-#include <cdio/audio.h>
-#include <cdio/sector.h>
-#include <cdio/cd_types.h>
-
-#if LIBCDIO_VERSION_NUM >= 90
-#include <cdio/paranoia/cdda.h>
-#else
-#include <cdio/cdda.h>
-#endif
-
-#include <cddb/cddb.h>
-
-#include <glib.h>
-
-#include <audacious/debug.h>
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#define DEF_STRING_LEN 256
-
-#define MIN_DISC_SPEED 2
-#define MAX_DISC_SPEED 24
-
-#define MAX_RETRIES 10
-#define MAX_SKIPS 10
-
-#define warn(...) fprintf(stderr, "cdaudio-ng: " __VA_ARGS__)
-
-typedef struct
-{
- char performer[DEF_STRING_LEN];
- char name[DEF_STRING_LEN];
- char genre[DEF_STRING_LEN];
- int startlsn;
- int endlsn;
-}
-trackinfo_t;
-
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static bool_t playing;
-
-/* lock mutex to read / set these variables */
-static int firsttrackno = -1;
-static int lasttrackno = -1;
-static int n_audio_tracks;
-static cdrom_drive_t *pcdrom_drive = NULL;
-static trackinfo_t *trackinfo = NULL;
-static int monitor_source = 0;
-
-static bool_t cdaudio_init (void);
-static int cdaudio_is_our_file (const char * filename, VFSFile * file);
-static bool_t cdaudio_play (const char * name, VFSFile * file);
-static void cdaudio_cleanup (void);
-static Tuple * make_tuple (const char * filename, VFSFile * file);
-static void scan_cd (void);
-static void refresh_trackinfo (bool_t warning);
-static void reset_trackinfo (void);
-static int calculate_track_length (int startlsn, int endlsn);
-static int find_trackno_from_filename (const char * filename);
-
-static const char cdaudio_about[] =
- N_("Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n\n"
- "Many thanks to libcdio developers <http://www.gnu.org/software/libcdio/>\n"
- "and to libcddb developers <http://libcddb.sourceforge.net/>.\n\n"
- "Also thank you to Tony Vroon for mentoring and guiding me.\n\n"
- "This was a Google Summer of Code 2007 project.");
-
-static const char * const schemes[] = {"cdda", NULL};
-
-static const char * const cdaudio_defaults[] = {
- "disc_speed", "2",
- "use_cdtext", "TRUE",
- "use_cddb", "TRUE",
- "cddbhttp", "FALSE",
- "cddbserver", "freedb.org",
- "cddbport", "8880",
- NULL};
-
-static const PreferencesWidget cdaudio_widgets[] = {
- {WIDGET_LABEL, N_("<b>Device</b>")},
- {WIDGET_SPIN_BTN, N_("Read speed:"),
- .cfg_type = VALUE_INT, .csect = "CDDA", .cname = "disc_speed",
- .data = {.spin_btn = {MIN_DISC_SPEED, MAX_DISC_SPEED, 1}}},
- {WIDGET_ENTRY, N_("Override device:"),
- .cfg_type = VALUE_STRING, .csect = "CDDA", .cname = "device"},
- {WIDGET_LABEL, N_("<b>Metadata</b>")},
- {WIDGET_CHK_BTN, N_("Use CD-Text"),
- .cfg_type = VALUE_BOOLEAN, .csect = "CDDA", .cname = "use_cdtext"},
- {WIDGET_CHK_BTN, N_("Use CDDB"),
- .cfg_type = VALUE_BOOLEAN, .csect = "CDDA", .cname = "use_cddb"},
- {WIDGET_CHK_BTN, N_("Use HTTP instead of CDDBP"), .child = TRUE,
- .cfg_type = VALUE_BOOLEAN, .csect = "CDDA", .cname = "cddbhttp"},
- {WIDGET_ENTRY, N_("Server:"), .child = TRUE,
- .cfg_type = VALUE_STRING, .csect = "CDDA", .cname = "cddbserver"},
- {WIDGET_ENTRY, N_("Path:"), .child = TRUE,
- .cfg_type = VALUE_STRING, .csect = "CDDA", .cname = "cddbpath"},
- {WIDGET_SPIN_BTN, N_("Port:"), .child = TRUE,
- .cfg_type = VALUE_INT, .csect = "CDDA", .cname = "cddbport",
- .data = {.spin_btn = {0, 65535, 1}}}};
-
-static const PluginPreferences cdaudio_prefs = {
- .widgets = cdaudio_widgets,
- .n_widgets = ARRAY_LEN (cdaudio_widgets)};
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("Audio CD Plugin"),
- .domain = PACKAGE,
- .about_text = cdaudio_about,
- .prefs = & cdaudio_prefs,
- .init = cdaudio_init,
- .cleanup = cdaudio_cleanup,
- .is_our_file_from_vfs = cdaudio_is_our_file,
- .play = cdaudio_play,
- .probe_for_tuple = make_tuple,
- .schemes = schemes,
- .have_subtune = TRUE,
-)
-
-static void cdaudio_error (const char * message_format, ...)
-{
- va_list args;
- char *msg = NULL;
-
- va_start (args, message_format);
- msg = g_markup_vprintf_escaped (message_format, args);
- va_end (args);
-
- aud_interface_show_error (msg);
- g_free (msg);
-}
-
-/* main thread only */
-static void purge_playlist (int playlist)
-{
- int length = aud_playlist_entry_count (playlist);
-
- for (int count = 0; count < length; count ++)
- {
- char * filename = aud_playlist_entry_get_filename (playlist, count);
-
- if (cdaudio_is_our_file (filename, NULL))
- {
- aud_playlist_entry_delete (playlist, count, 1);
- count--;
- length--;
- }
-
- str_unref (filename);
- }
-}
-
-/* main thread only */
-static void purge_all_playlists (void)
-{
- int playlists = aud_playlist_count ();
- int count;
-
- for (count = 0; count < playlists; count++)
- purge_playlist (count);
-}
-
-/* main thread only */
-static bool_t monitor (gpointer unused)
-{
- pthread_mutex_lock (& mutex);
-
- /* make sure not to close drive handle while playing */
- if (playing)
- {
- pthread_mutex_unlock (& mutex);
- return true;
- }
-
- if (trackinfo != NULL)
- refresh_trackinfo (FALSE);
-
- if (trackinfo != NULL)
- {
- pthread_mutex_unlock (& mutex);
- return TRUE;
- }
-
- monitor_source = 0;
- pthread_mutex_unlock (& mutex);
-
- purge_all_playlists ();
- return FALSE;
-}
-
-/* mutex must be locked */
-static void trigger_monitor (void)
-{
- if (! monitor_source)
- monitor_source = g_timeout_add_seconds (1, monitor, NULL);
-}
-
-/* main thread only */
-static bool_t cdaudio_init (void)
-{
- aud_config_set_defaults ("CDDA", cdaudio_defaults);
-
- if (!cdio_init ())
- {
- cdaudio_error (_("Failed to initialize cdio subsystem."));
- return FALSE;
- }
-
- libcddb_init ();
-
- return TRUE;
-}
-
-/* thread safe (mutex may be locked) */
-static int cdaudio_is_our_file (const char * filename, VFSFile * file)
-{
- return !strncmp (filename, "cdda://", 7);
-}
-
-/* thread safe (mutex may be locked) */
-static void cdaudio_set_strinfo (trackinfo_t * t,
- const char * performer, const char * name,
- const char * genre)
-{
- g_strlcpy (t->performer, performer ? performer : "", DEF_STRING_LEN);
- g_strlcpy (t->name, name ? name : "", DEF_STRING_LEN);
- g_strlcpy (t->genre, genre ? genre : "", DEF_STRING_LEN);
-}
-
-/* thread safe (mutex may be locked) */
-static void cdaudio_set_fullinfo (trackinfo_t * t,
- const lsn_t startlsn, const lsn_t endlsn,
- const char * performer, const char * name,
- const char * genre)
-{
- t->startlsn = startlsn;
- t->endlsn = endlsn;
- cdaudio_set_strinfo (t, performer, name, genre);
-}
-
-/* play thread only */
-static bool_t cdaudio_play (const char * name, VFSFile * file)
-{
- pthread_mutex_lock (& mutex);
-
- if (trackinfo == NULL)
- {
- refresh_trackinfo (TRUE);
-
- if (trackinfo == NULL)
- {
- pthread_mutex_unlock (& mutex);
- return FALSE;
- }
- }
-
- bool_t okay = FALSE;
- int trackno = find_trackno_from_filename (name);
-
- if (trackno < 0)
- cdaudio_error (_("Invalid URI %s."), name);
- else if (trackno < firsttrackno || trackno > lasttrackno)
- cdaudio_error (_("Track %d not found."), trackno);
- else if (! cdda_track_audiop (pcdrom_drive, trackno))
- cdaudio_error (_("Track %d is a data track."), trackno);
- else if (! aud_input_open_audio (FMT_S16_LE, 44100, 2))
- cdaudio_error (_("Failed to open audio output."));
- else
- okay = TRUE;
-
- if (! okay)
- {
- pthread_mutex_unlock (& mutex);
- return FALSE;
- }
-
- int startlsn = trackinfo[trackno].startlsn;
- int endlsn = trackinfo[trackno].endlsn;
-
- playing = TRUE;
-
- aud_input_set_bitrate (1411200);
-
- int buffer_size = aud_get_int (NULL, "output_buffer_size");
- int speed = aud_get_int ("CDDA", "disc_speed");
- speed = CLAMP (speed, MIN_DISC_SPEED, MAX_DISC_SPEED);
- int sectors = CLAMP (buffer_size / 2, 50, 250) * speed * 75 / 1000;
- unsigned char buffer[2352 * sectors];
- int currlsn = startlsn;
- int retry_count = 0, skip_count = 0;
-
- while (! aud_input_check_stop ())
- {
- int seek_time = aud_input_check_seek ();
- if (seek_time >= 0)
- currlsn = startlsn + (seek_time * 75 / 1000);
-
- sectors = MIN (sectors, endlsn + 1 - currlsn);
- if (sectors < 1)
- break;
-
- /* unlock mutex here to avoid blocking
- * other threads must be careful not to close drive handle */
- pthread_mutex_unlock (& mutex);
-
- int ret = cdio_read_audio_sectors (pcdrom_drive->p_cdio, buffer,
- currlsn, sectors);
-
- if (ret == DRIVER_OP_SUCCESS)
- aud_input_write_audio (buffer, 2352 * sectors);
-
- pthread_mutex_lock (& mutex);
-
- if (ret == DRIVER_OP_SUCCESS)
- {
- currlsn += sectors;
- retry_count = 0;
- skip_count = 0;
- }
- else if (sectors > 16)
- {
- /* maybe a smaller read size will help */
- sectors /= 2;
- }
- else if (retry_count < MAX_RETRIES)
- {
- /* still failed; retry a few times */
- retry_count ++;
- }
- else if (skip_count < MAX_SKIPS)
- {
- /* maybe the disk is scratched; try skipping ahead */
- currlsn = MIN (currlsn + 75, endlsn + 1);
- skip_count ++;
- }
- else
- {
- /* still failed; give it up */
- cdaudio_error (_("Error reading audio CD."));
- break;
- }
- }
-
- playing = FALSE;
-
- pthread_mutex_unlock (& mutex);
- return TRUE;
-}
-
-/* main thread only */
-static void cdaudio_cleanup (void)
-{
- pthread_mutex_lock (& mutex);
-
- reset_trackinfo ();
- libcddb_shutdown ();
-
- pthread_mutex_unlock (& mutex);
-}
-
-/* thread safe */
-static Tuple * make_tuple (const char * filename, VFSFile * file)
-{
- bool_t whole_disk = ! strcmp (filename, "cdda://");
- Tuple * tuple = NULL;
-
- pthread_mutex_lock (& mutex);
-
- /* reset cached info when adding CD to the playlist */
- if (whole_disk && ! playing)
- reset_trackinfo ();
-
- if (trackinfo == NULL)
- refresh_trackinfo (TRUE);
- if (trackinfo == NULL)
- goto DONE;
-
- if (whole_disk)
- {
- tuple = tuple_new_from_filename (filename);
-
- int subtunes[n_audio_tracks];
- int i = 0;
-
- /* only add the audio tracks to the playlist */
- for (int trackno = firsttrackno; trackno <= lasttrackno; trackno++)
- if (cdda_track_audiop (pcdrom_drive, trackno))
- subtunes[i ++] = trackno;
-
- tuple_set_subtunes (tuple, n_audio_tracks, subtunes);
-
- goto DONE;
- }
-
- int trackno = find_trackno_from_filename (filename);
-
- if (trackno < firsttrackno || trackno > lasttrackno)
- {
- warn ("Track %d not found.\n", trackno);
- goto DONE;
- }
-
- if (!cdda_track_audiop (pcdrom_drive, trackno))
- {
- warn ("Track %d is a data track.\n", trackno);
- goto DONE;
- }
-
- tuple = tuple_new_from_filename (filename);
- tuple_set_format (tuple, _("Audio CD"), 2, 44100, 1411);
- tuple_set_int (tuple, FIELD_TRACK_NUMBER, trackno);
- tuple_set_int (tuple, FIELD_LENGTH, calculate_track_length
- (trackinfo[trackno].startlsn, trackinfo[trackno].endlsn));
-
- if (trackinfo[trackno].name[0])
- tuple_set_str (tuple, FIELD_TITLE, trackinfo[trackno].name);
- else
- {
- SPRINTF (title, _("Track %d"), trackno);
- tuple_set_str (tuple, FIELD_TITLE, title);
- }
-
- if (trackinfo[trackno].performer[0])
- tuple_set_str (tuple, FIELD_ARTIST, trackinfo[trackno].performer);
- if (trackinfo[0].name[0])
- tuple_set_str (tuple, FIELD_ALBUM, trackinfo[0].name);
- if (trackinfo[trackno].genre[0])
- tuple_set_str (tuple, FIELD_GENRE, trackinfo[trackno].genre);
-
- DONE:
- pthread_mutex_unlock (& mutex);
- return tuple;
-}
-
-/* mutex must be locked */
-static void open_cd (void)
-{
- AUDDBG ("Opening CD drive.\n");
- g_return_if_fail (pcdrom_drive == NULL);
-
- char * device = aud_get_str ("CDDA", "device");
-
- if (device[0])
- {
- if (! (pcdrom_drive = cdda_identify (device, 1, NULL)))
- cdaudio_error (_("Failed to open CD device %s."), device);
- }
- else
- {
- char * * ppcd_drives = cdio_get_devices_with_cap (NULL, CDIO_FS_AUDIO, FALSE);
-
- if (ppcd_drives && ppcd_drives[0])
- {
- if (! (pcdrom_drive = cdda_identify (ppcd_drives[0], 1, NULL)))
- cdaudio_error (_("Failed to open CD device %s."), ppcd_drives[0]);
- }
- else
- cdaudio_error (_("No audio capable CD drive found."));
-
- if (ppcd_drives)
- cdio_free_device_list (ppcd_drives);
- }
-
- str_unref (device);
-}
-
-/* mutex must be locked */
-static void scan_cd (void)
-{
- AUDDBG ("Scanning CD drive.\n");
- g_return_if_fail (pcdrom_drive != NULL);
- g_return_if_fail (trackinfo == NULL);
-
- int trackno;
-
- /* general track initialization */
-
- /* skip endianness detection (because it only affects cdda_read, and we use
- * cdio_read_audio_sectors instead) */
- pcdrom_drive->bigendianp = 0;
-
- /* finish initialization of drive/disc (performs disc TOC sanitization) */
- if (cdda_open (pcdrom_drive) != 0)
- {
- cdaudio_error (_("Failed to finish initializing opened CD drive."));
- goto ERR;
- }
-
- int speed = aud_get_int ("CDDA", "disc_speed");
- speed = CLAMP (speed, MIN_DISC_SPEED, MAX_DISC_SPEED);
- if (cdda_speed_set (pcdrom_drive, speed) != DRIVER_OP_SUCCESS)
- warn ("Cannot set drive speed.\n");
-
- firsttrackno = cdio_get_first_track_num (pcdrom_drive->p_cdio);
- lasttrackno = cdio_get_last_track_num (pcdrom_drive->p_cdio);
- if (firsttrackno == CDIO_INVALID_TRACK || lasttrackno == CDIO_INVALID_TRACK)
- {
- cdaudio_error (_("Failed to retrieve first/last track number."));
- goto ERR;
- }
- AUDDBG ("first track is %d and last track is %d\n", firsttrackno,
- lasttrackno);
-
- trackinfo = (trackinfo_t *) g_new (trackinfo_t, (lasttrackno + 1));
-
- cdaudio_set_fullinfo (&trackinfo[0],
- cdda_track_firstsector (pcdrom_drive, 0),
- cdda_track_lastsector (pcdrom_drive, lasttrackno),
- "", "", "");
-
- n_audio_tracks = 0;
-
- for (trackno = firsttrackno; trackno <= lasttrackno; trackno++)
- {
- cdaudio_set_fullinfo (&trackinfo[trackno],
- cdda_track_firstsector (pcdrom_drive, trackno),
- cdda_track_lastsector (pcdrom_drive, trackno),
- "", "", "");
-
- if (trackinfo[trackno].startlsn == CDIO_INVALID_LSN
- || trackinfo[trackno].endlsn == CDIO_INVALID_LSN)
- {
- cdaudio_error (_("Cannot read start/end LSN for track %d."), trackno);
- goto ERR;
- }
-
- /* count how many tracks are audio tracks */
- if (cdda_track_audiop (pcdrom_drive, trackno))
- n_audio_tracks++;
- }
-
- /* get trackinfo[0] cdtext information (the disc) */
- cdtext_t *pcdtext = NULL;
- if (aud_get_bool ("CDDA", "use_cdtext"))
- {
- AUDDBG ("getting cd-text information for disc\n");
-#if LIBCDIO_VERSION_NUM >= 90
- pcdtext = cdio_get_cdtext (pcdrom_drive->p_cdio);
- if (pcdtext == NULL)
-#else
- pcdtext = cdio_get_cdtext (pcdrom_drive->p_cdio, 0);
- if (pcdtext == NULL || pcdtext->field[CDTEXT_TITLE] == NULL)
-#endif
- {
- AUDDBG ("no cd-text available for disc\n");
- }
- else
- {
- cdaudio_set_strinfo (&trackinfo[0],
-#if LIBCDIO_VERSION_NUM >= 90
- cdtext_get(pcdtext, CDTEXT_FIELD_PERFORMER, 0),
- cdtext_get(pcdtext, CDTEXT_FIELD_TITLE, 0),
- cdtext_get(pcdtext, CDTEXT_FIELD_GENRE, 0));
-#else
- pcdtext->field[CDTEXT_PERFORMER],
- pcdtext->field[CDTEXT_TITLE],
- pcdtext->field[CDTEXT_GENRE]);
-#endif
- }
- }
-
- /* get track information from cdtext */
- bool_t cdtext_was_available = FALSE;
- for (trackno = firsttrackno; trackno <= lasttrackno; trackno++)
- {
-#if LIBCDIO_VERSION_NUM < 90
- if (aud_get_bool ("CDDA", "use_cdtext"))
- {
- AUDDBG ("getting cd-text information for track %d\n", trackno);
- pcdtext = cdio_get_cdtext (pcdrom_drive->p_cdio, trackno);
- if (pcdtext == NULL || pcdtext->field[CDTEXT_PERFORMER] == NULL)
- {
- AUDDBG ("no cd-text available for track %d\n", trackno);
- pcdtext = NULL;
- }
- }
-#endif
-
- if (pcdtext != NULL)
- {
- cdaudio_set_strinfo (&trackinfo[trackno],
-#if LIBCDIO_VERSION_NUM >= 90
- cdtext_get(pcdtext, CDTEXT_FIELD_PERFORMER, trackno),
- cdtext_get(pcdtext, CDTEXT_FIELD_TITLE, trackno),
- cdtext_get(pcdtext, CDTEXT_FIELD_GENRE, trackno));
-#else
- pcdtext->field[CDTEXT_PERFORMER],
- pcdtext->field[CDTEXT_TITLE],
- pcdtext->field[CDTEXT_GENRE]);
-#endif
- cdtext_was_available = TRUE;
- }
- }
-
- if (!cdtext_was_available)
- {
- /* initialize de cddb subsystem */
- cddb_conn_t *pcddb_conn = NULL;
- cddb_disc_t *pcddb_disc = NULL;
- cddb_track_t *pcddb_track = NULL;
- lba_t lba; /* Logical Block Address */
-
- if (aud_get_bool ("CDDA", "use_cddb"))
- {
- pcddb_conn = cddb_new ();
- if (pcddb_conn == NULL)
- cdaudio_error (_("Failed to create the cddb connection."));
- else
- {
- AUDDBG ("getting CDDB info\n");
-
- cddb_cache_enable (pcddb_conn);
- // cddb_cache_set_dir(pcddb_conn, "~/.cddbslave");
-
- char * server = aud_get_str ("CDDA", "cddbserver");
- char * path = aud_get_str ("CDDA", "cddbpath");
- int port = aud_get_int ("CDDA", "cddbport");
-
- if (aud_get_bool (NULL, "use_proxy"))
- {
- char * prhost = aud_get_str (NULL, "proxy_host");
- int prport = aud_get_int (NULL, "proxy_port");
- char * pruser = aud_get_str (NULL, "proxy_user");
- char * prpass = aud_get_str (NULL, "proxy_pass");
-
- cddb_http_proxy_enable (pcddb_conn);
- cddb_set_http_proxy_server_name (pcddb_conn, prhost);
- cddb_set_http_proxy_server_port (pcddb_conn, prport);
- cddb_set_http_proxy_username (pcddb_conn, pruser);
- cddb_set_http_proxy_password (pcddb_conn, prpass);
-
- str_unref (prhost);
- str_unref (pruser);
- str_unref (prpass);
-
- cddb_set_server_name (pcddb_conn, server);
- cddb_set_server_port (pcddb_conn, port);
- }
- else if (aud_get_bool ("CDDA", "cddbhttp"))
- {
- cddb_http_enable (pcddb_conn);
- cddb_set_server_name (pcddb_conn, server);
- cddb_set_server_port (pcddb_conn, port);
- cddb_set_http_path_query (pcddb_conn, path);
- }
- else
- {
- cddb_set_server_name (pcddb_conn, server);
- cddb_set_server_port (pcddb_conn, port);
- }
-
- str_unref (server);
- str_unref (path);
-
- pcddb_disc = cddb_disc_new ();
-
- lba = cdio_get_track_lba (pcdrom_drive->p_cdio,
- CDIO_CDROM_LEADOUT_TRACK);
- cddb_disc_set_length (pcddb_disc, FRAMES_TO_SECONDS (lba));
-
- for (trackno = firsttrackno; trackno <= lasttrackno; trackno++)
- {
- pcddb_track = cddb_track_new ();
- cddb_track_set_frame_offset (pcddb_track,
- cdio_get_track_lba (
- pcdrom_drive->p_cdio,
- trackno));
- cddb_disc_add_track (pcddb_disc, pcddb_track);
- }
-
- cddb_disc_calc_discid (pcddb_disc);
-
-#if DEBUG
- guint discid = cddb_disc_get_discid (pcddb_disc);
- AUDDBG ("CDDB disc id = %x\n", discid);
-#endif
-
- int matches;
- if ((matches = cddb_query (pcddb_conn, pcddb_disc)) == -1)
- {
- if (cddb_errno (pcddb_conn) == CDDB_ERR_OK)
- cdaudio_error (_("Failed to query the CDDB server"));
- else
- cdaudio_error (_("Failed to query the CDDB server: %s"),
- cddb_error_str (cddb_errno
- (pcddb_conn)));
-
- cddb_disc_destroy (pcddb_disc);
- pcddb_disc = NULL;
- }
- else
- {
- if (matches == 0)
- {
- AUDDBG ("no cddb info available for this disc\n");
-
- cddb_disc_destroy (pcddb_disc);
- pcddb_disc = NULL;
- }
- else
- {
- AUDDBG ("CDDB disc category = \"%s\"\n",
- cddb_disc_get_category_str (pcddb_disc));
-
- cddb_read (pcddb_conn, pcddb_disc);
- if (cddb_errno (pcddb_conn) != CDDB_ERR_OK)
- {
- cdaudio_error (_("Failed to read the cddb info: %s"),
- cddb_error_str (cddb_errno
- (pcddb_conn)));
- cddb_disc_destroy (pcddb_disc);
- pcddb_disc = NULL;
- }
- else
- {
- cdaudio_set_strinfo (&trackinfo[0],
- cddb_disc_get_artist
- (pcddb_disc),
- cddb_disc_get_title
- (pcddb_disc),
- cddb_disc_get_genre
- (pcddb_disc));
-
- int trackno;
- for (trackno = firsttrackno; trackno <= lasttrackno;
- trackno++)
- {
- cddb_track_t *pcddb_track =
- cddb_disc_get_track (pcddb_disc,
- trackno - 1);
- cdaudio_set_strinfo (&trackinfo[trackno],
- cddb_track_get_artist
- (pcddb_track),
- cddb_track_get_title
- (pcddb_track),
- cddb_disc_get_genre
- (pcddb_disc));
- }
- }
- }
- }
- }
- }
-
- if (pcddb_disc != NULL)
- cddb_disc_destroy (pcddb_disc);
-
- if (pcddb_conn != NULL)
- cddb_destroy (pcddb_conn);
- }
-
- return;
-
- ERR:
- g_free (trackinfo);
- trackinfo = NULL;
-}
-
-/* mutex must be locked */
-static void refresh_trackinfo (bool_t warning)
-{
- if (pcdrom_drive == NULL)
- {
- open_cd ();
- if (pcdrom_drive == NULL)
- return;
- }
-
- int mode = cdio_get_discmode (pcdrom_drive->p_cdio);
-#ifdef _WIN32 /* cdio_get_discmode reports the wrong disk type sometimes */
- if (mode == CDIO_DISC_MODE_NO_INFO || mode == CDIO_DISC_MODE_ERROR)
-#else
- if (mode != CDIO_DISC_MODE_CD_DA && mode != CDIO_DISC_MODE_CD_MIXED)
-#endif
- {
- if (warning)
- {
- if (mode == CDIO_DISC_MODE_NO_INFO)
- cdaudio_error (_("Drive is empty."));
- else
- cdaudio_error (_("Unsupported disk type."));
- }
-
- reset_trackinfo ();
- return;
- }
-
- if (trackinfo == NULL || cdio_get_media_changed (pcdrom_drive->p_cdio))
- {
- g_free (trackinfo);
- trackinfo = NULL;
- scan_cd ();
-
- if (trackinfo != NULL)
- trigger_monitor ();
- }
-}
-
-/* mutex must be locked */
-static void reset_trackinfo (void)
-{
- if (monitor_source)
- {
- g_source_remove (monitor_source);
- monitor_source = 0;
- }
-
- if (pcdrom_drive != NULL)
- {
- cdda_close (pcdrom_drive);
- pcdrom_drive = NULL;
- }
-
- g_free (trackinfo);
- trackinfo = NULL;
-}
-
-/* thread safe (mutex may be locked) */
-static int calculate_track_length (int startlsn, int endlsn)
-{
- return ((endlsn - startlsn + 1) * 1000) / 75;
-}
-
-/* thread safe (mutex may be locked) */
-static int find_trackno_from_filename (const char * filename)
-{
- int track;
-
- if (strncmp (filename, "cdda://?", 8) || sscanf (filename + 8, "%d",
- &track) != 1)
- return -1;
-
- return track;
-}
diff --git a/src/cdaudio-ng/cdaudio-ng.cc b/src/cdaudio-ng/cdaudio-ng.cc
new file mode 100644
index 000000000000..6ac85edc865a
--- /dev/null
+++ b/src/cdaudio-ng/cdaudio-ng.cc
@@ -0,0 +1,815 @@
+/*
+ * Audacious CD Digital Audio plugin
+ *
+ * Copyright (c) 2007 Calin Crisan <ccrisan at gmail.com>
+ * Copyright (c) 2009-2012 John Lindgren <john.lindgren at aol.com>
+ * Copyright (c) 2009 Tomasz MoÅ <desowin at gmail.com>
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* prevent libcdio from redefining PACKAGE, VERSION, etc. */
+#define EXTERNAL_LIBCDIO_CONFIG_H
+
+#include <cdio/cdio.h>
+#include <cdio/cdtext.h>
+#include <cdio/track.h>
+#include <cdio/audio.h>
+#include <cdio/sector.h>
+#include <cdio/cd_types.h>
+
+#if LIBCDIO_VERSION_NUM >= 90
+#include <cdio/paranoia/cdda.h>
+#else
+#include <cdio/cdda.h>
+#endif
+
+#include <cddb/cddb.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/mainloop.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/runtime.h>
+
+#define MIN_DISC_SPEED 2
+#define MAX_DISC_SPEED 24
+
+#define MAX_RETRIES 10
+#define MAX_SKIPS 10
+
+static const char * const cdaudio_schemes[] = {"cdda", nullptr};
+
+class CDAudio : public InputPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Audio CD Plugin"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ static constexpr auto iinfo = InputInfo (FlagSubtunes)
+ .with_schemes (cdaudio_schemes);
+
+ constexpr CDAudio () : InputPlugin (info, iinfo) {}
+
+ bool init ();
+ void cleanup ();
+
+ bool is_our_file (const char * filename, VFSFile & file);
+ Tuple read_tuple (const char * filename, VFSFile & file);
+ bool play (const char * filename, VFSFile & file);
+};
+
+EXPORT CDAudio aud_plugin_instance;
+
+typedef struct
+{
+ String performer;
+ String name;
+ String genre;
+ int startlsn;
+ int endlsn;
+}
+trackinfo_t;
+
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static bool playing;
+
+/* lock mutex to read / set these variables */
+static int firsttrackno = -1;
+static int lasttrackno = -1;
+static int n_audio_tracks;
+static cdrom_drive_t *pcdrom_drive = nullptr;
+static Index<trackinfo_t> trackinfo;
+static QueuedFunc monitor_source;
+
+static bool scan_cd ();
+static void refresh_trackinfo (bool warning);
+static void reset_trackinfo ();
+static int calculate_track_length (int startlsn, int endlsn);
+static int find_trackno_from_filename (const char * filename);
+
+const char CDAudio::about[] =
+ N_("Copyright (C) 2007-2012 Calin Crisan <ccrisan at gmail.com> and others.\n\n"
+ "Many thanks to libcdio developers <http://www.gnu.org/software/libcdio/>\n"
+ "and to libcddb developers <http://libcddb.sourceforge.net/>.\n\n"
+ "Also thank you to Tony Vroon for mentoring and guiding me.\n\n"
+ "This was a Google Summer of Code 2007 project.");
+
+const char * const CDAudio::defaults[] = {
+ "disc_speed", "2",
+ "use_cdtext", "TRUE",
+ "use_cddb", "TRUE",
+ "cddbhttp", "FALSE",
+ "cddbserver", "freedb.org",
+ "cddbport", "8880",
+ nullptr};
+
+const PreferencesWidget CDAudio::widgets[] = {
+ WidgetLabel (N_("<b>Device</b>")),
+ WidgetSpin (N_("Read speed:"),
+ WidgetInt ("CDDA", "disc_speed"),
+ {MIN_DISC_SPEED, MAX_DISC_SPEED, 1}),
+ WidgetEntry (N_("Override device:"),
+ WidgetString ("CDDA", "device")),
+ WidgetLabel (N_("<b>Metadata</b>")),
+ WidgetCheck (N_("Use CD-Text"),
+ WidgetBool ("CDDA", "use_cdtext")),
+ WidgetCheck (N_("Use CDDB"),
+ WidgetBool ("CDDA", "use_cddb")),
+ WidgetCheck (N_("Use HTTP instead of CDDBP"),
+ WidgetBool ("CDDA", "cddbhttp"),
+ WIDGET_CHILD),
+ WidgetEntry (N_("Server:"),
+ WidgetString ("CDDA", "cddbserver"),
+ {false},
+ WIDGET_CHILD),
+ WidgetEntry (N_("Path:"),
+ WidgetString ("CDDA", "cddbpath"),
+ {false},
+ WIDGET_CHILD),
+ WidgetSpin (N_("Port:"),
+ WidgetInt ("CDDA", "cddbport"),
+ {0, 65535, 1},
+ WIDGET_CHILD)
+};
+
+const PluginPreferences CDAudio::prefs = {{widgets}};
+
+static void cdaudio_error (const char * message_format, ...)
+{
+ va_list args;
+ va_start (args, message_format);
+ StringBuf msg = str_vprintf (message_format, args);
+ va_end (args);
+
+ aud_ui_show_error (msg);
+}
+
+/* main thread only */
+static void purge_playlist (int playlist)
+{
+ int length = aud_playlist_entry_count (playlist);
+
+ for (int count = 0; count < length; count ++)
+ {
+ String filename = aud_playlist_entry_get_filename (playlist, count);
+
+ if (! strncmp (filename, "cdda://", 7))
+ {
+ aud_playlist_entry_delete (playlist, count, 1);
+ count--;
+ length--;
+ }
+ }
+}
+
+/* main thread only */
+static void purge_all_playlists ()
+{
+ int playlists = aud_playlist_count ();
+ int count;
+
+ for (count = 0; count < playlists; count++)
+ purge_playlist (count);
+}
+
+/* main thread only */
+static void monitor (void *)
+{
+ pthread_mutex_lock (& mutex);
+
+ /* make sure not to close drive handle while playing */
+ if (playing)
+ {
+ pthread_mutex_unlock (& mutex);
+ return;
+ }
+
+ if (trackinfo.len ())
+ refresh_trackinfo (false);
+
+ if (trackinfo.len ())
+ {
+ pthread_mutex_unlock (& mutex);
+ return;
+ }
+
+ monitor_source.stop ();
+ pthread_mutex_unlock (& mutex);
+
+ purge_all_playlists ();
+}
+
+/* mutex must be locked */
+static void trigger_monitor ()
+{
+ if (! monitor_source.running ())
+ monitor_source.start (1000, monitor, nullptr);
+}
+
+/* main thread only */
+bool CDAudio::init ()
+{
+ aud_config_set_defaults ("CDDA", defaults);
+
+ if (!cdio_init ())
+ {
+ cdaudio_error (_("Failed to initialize cdio subsystem."));
+ return false;
+ }
+
+ libcddb_init ();
+
+ return true;
+}
+
+/* thread safe (mutex may be locked) */
+bool CDAudio::is_our_file (const char * filename, VFSFile & file)
+{
+ return !strncmp (filename, "cdda://", 7);
+}
+
+/* play thread only */
+bool CDAudio::play (const char * name, VFSFile & file)
+{
+ pthread_mutex_lock (& mutex);
+
+ if (! trackinfo.len ())
+ {
+ refresh_trackinfo (true);
+
+ if (! trackinfo.len ())
+ {
+ pthread_mutex_unlock (& mutex);
+ return false;
+ }
+ }
+
+ bool okay = false;
+ int trackno = find_trackno_from_filename (name);
+
+ if (trackno < 0)
+ cdaudio_error (_("Invalid URI %s."), name);
+ else if (trackno < firsttrackno || trackno > lasttrackno)
+ cdaudio_error (_("Track %d not found."), trackno);
+ else if (! cdda_track_audiop (pcdrom_drive, trackno))
+ cdaudio_error (_("Track %d is a data track."), trackno);
+ else
+ okay = true;
+
+ if (! okay)
+ {
+ pthread_mutex_unlock (& mutex);
+ return false;
+ }
+
+ set_stream_bitrate (1411200);
+ open_audio (FMT_S16_LE, 44100, 2);
+
+ int startlsn = trackinfo[trackno].startlsn;
+ int endlsn = trackinfo[trackno].endlsn;
+
+ playing = true;
+
+ int buffer_size = aud_get_int (nullptr, "output_buffer_size");
+ int speed = aud_get_int ("CDDA", "disc_speed");
+ speed = aud::clamp (speed, MIN_DISC_SPEED, MAX_DISC_SPEED);
+ int sectors = aud::clamp (buffer_size / 2, 50, 250) * speed * 75 / 1000;
+ int currlsn = startlsn;
+ int retry_count = 0, skip_count = 0;
+
+ Index<unsigned char> buffer;
+ buffer.insert (0, 2352 * sectors);
+
+ while (! check_stop ())
+ {
+ int seek_time = check_seek ();
+ if (seek_time >= 0)
+ currlsn = startlsn + (seek_time * 75 / 1000);
+
+ sectors = aud::min (sectors, endlsn + 1 - currlsn);
+ if (sectors < 1)
+ break;
+
+ /* unlock mutex here to avoid blocking
+ * other threads must be careful not to close drive handle */
+ pthread_mutex_unlock (& mutex);
+
+ int ret = cdio_read_audio_sectors (pcdrom_drive->p_cdio,
+ buffer.begin (), currlsn, sectors);
+
+ if (ret == DRIVER_OP_SUCCESS)
+ write_audio (buffer.begin (), 2352 * sectors);
+
+ pthread_mutex_lock (& mutex);
+
+ if (ret == DRIVER_OP_SUCCESS)
+ {
+ currlsn += sectors;
+ retry_count = 0;
+ skip_count = 0;
+ }
+ else if (sectors > 16)
+ {
+ /* maybe a smaller read size will help */
+ sectors /= 2;
+ }
+ else if (retry_count < MAX_RETRIES)
+ {
+ /* still failed; retry a few times */
+ retry_count ++;
+ }
+ else if (skip_count < MAX_SKIPS)
+ {
+ /* maybe the disk is scratched; try skipping ahead */
+ currlsn = aud::min (currlsn + 75, endlsn + 1);
+ skip_count ++;
+ }
+ else
+ {
+ /* still failed; give it up */
+ cdaudio_error (_("Error reading audio CD."));
+ break;
+ }
+ }
+
+ playing = false;
+
+ pthread_mutex_unlock (& mutex);
+ return true;
+}
+
+/* main thread only */
+void CDAudio::cleanup ()
+{
+ pthread_mutex_lock (& mutex);
+
+ reset_trackinfo ();
+ libcddb_shutdown ();
+
+ pthread_mutex_unlock (& mutex);
+}
+
+/* thread safe */
+Tuple CDAudio::read_tuple (const char * filename, VFSFile & file)
+{
+ bool whole_disk = ! strcmp (filename, "cdda://");
+ Tuple tuple;
+
+ pthread_mutex_lock (& mutex);
+
+ /* reset cached info when adding CD to the playlist */
+ if (whole_disk && ! playing)
+ reset_trackinfo ();
+
+ if (! trackinfo.len ())
+ refresh_trackinfo (true);
+ if (! trackinfo.len ())
+ goto DONE;
+
+ if (whole_disk)
+ {
+ tuple.set_filename (filename);
+
+ Index<int> subtunes;
+
+ /* only add the audio tracks to the playlist */
+ for (int trackno = firsttrackno; trackno <= lasttrackno; trackno++)
+ if (cdda_track_audiop (pcdrom_drive, trackno))
+ subtunes.append (trackno);
+
+ tuple.set_subtunes (subtunes.len (), subtunes.begin ());
+ }
+ else
+ {
+ int trackno = find_trackno_from_filename (filename);
+
+ if (trackno < firsttrackno || trackno > lasttrackno)
+ {
+ AUDERR ("Track %d not found.\n", trackno);
+ goto DONE;
+ }
+
+ if (!cdda_track_audiop (pcdrom_drive, trackno))
+ {
+ AUDERR ("Track %d is a data track.\n", trackno);
+ goto DONE;
+ }
+
+ tuple.set_filename (filename);
+ tuple.set_format (_("Audio CD"), 2, 44100, 1411);
+ tuple.set_int (Tuple::Track, trackno);
+ tuple.set_int (Tuple::Length, calculate_track_length
+ (trackinfo[trackno].startlsn, trackinfo[trackno].endlsn));
+
+ if (trackinfo[trackno].name)
+ tuple.set_str (Tuple::Title, trackinfo[trackno].name);
+ if (trackinfo[trackno].performer)
+ tuple.set_str (Tuple::Artist, trackinfo[trackno].performer);
+ if (trackinfo[0].name)
+ tuple.set_str (Tuple::Album, trackinfo[0].name);
+ if (trackinfo[trackno].genre)
+ tuple.set_str (Tuple::Genre, trackinfo[trackno].genre);
+ }
+
+ DONE:
+ pthread_mutex_unlock (& mutex);
+ return tuple;
+}
+
+/* mutex must be locked */
+static void open_cd ()
+{
+ AUDDBG ("Opening CD drive.\n");
+ assert (pcdrom_drive == nullptr);
+
+ String device = aud_get_str ("CDDA", "device");
+
+ if (device[0])
+ {
+ if (! (pcdrom_drive = cdda_identify (device, 1, nullptr)))
+ cdaudio_error (_("Failed to open CD device %s."), (const char *) device);
+ }
+ else
+ {
+ char * * ppcd_drives = cdio_get_devices_with_cap (nullptr, CDIO_FS_AUDIO, false);
+
+ if (ppcd_drives && ppcd_drives[0])
+ {
+ if (! (pcdrom_drive = cdda_identify (ppcd_drives[0], 1, nullptr)))
+ cdaudio_error (_("Failed to open CD device %s."), ppcd_drives[0]);
+ }
+ else
+ cdaudio_error (_("No audio capable CD drive found."));
+
+ if (ppcd_drives)
+ cdio_free_device_list (ppcd_drives);
+ }
+}
+
+/* mutex must be locked */
+static bool scan_cd ()
+{
+ AUDDBG ("Scanning CD drive.\n");
+ assert (pcdrom_drive);
+ assert (! trackinfo.len ());
+
+ int trackno;
+
+ /* general track initialization */
+
+ /* skip endianness detection (because it only affects cdda_read, and we use
+ * cdio_read_audio_sectors instead) */
+ pcdrom_drive->bigendianp = 0;
+
+ /* finish initialization of drive/disc (performs disc TOC sanitization) */
+ if (cdda_open (pcdrom_drive) != 0)
+ {
+ cdaudio_error (_("Failed to finish initializing opened CD drive."));
+ return false;
+ }
+
+ int speed = aud_get_int ("CDDA", "disc_speed");
+ speed = aud::clamp (speed, MIN_DISC_SPEED, MAX_DISC_SPEED);
+ if (cdda_speed_set (pcdrom_drive, speed) != DRIVER_OP_SUCCESS)
+ AUDERR ("Cannot set drive speed.\n");
+
+ firsttrackno = cdio_get_first_track_num (pcdrom_drive->p_cdio);
+ lasttrackno = cdio_get_last_track_num (pcdrom_drive->p_cdio);
+ if (firsttrackno == CDIO_INVALID_TRACK || lasttrackno == CDIO_INVALID_TRACK)
+ {
+ cdaudio_error (_("Failed to retrieve first/last track number."));
+ return false;
+ }
+ AUDDBG ("first track is %d and last track is %d\n", firsttrackno,
+ lasttrackno);
+
+ trackinfo.insert (0, lasttrackno + 1);
+
+ trackinfo[0].startlsn = cdda_track_firstsector (pcdrom_drive, 0);
+ trackinfo[0].endlsn = cdda_track_lastsector (pcdrom_drive, lasttrackno);
+
+ n_audio_tracks = 0;
+
+ for (trackno = firsttrackno; trackno <= lasttrackno; trackno++)
+ {
+ trackinfo[trackno].startlsn = cdda_track_firstsector (pcdrom_drive, trackno);
+ trackinfo[trackno].endlsn = cdda_track_lastsector (pcdrom_drive, trackno);
+
+ if (trackinfo[trackno].startlsn == CDIO_INVALID_LSN
+ || trackinfo[trackno].endlsn == CDIO_INVALID_LSN)
+ {
+ cdaudio_error (_("Cannot read start/end LSN for track %d."), trackno);
+ return false;
+ }
+
+ /* count how many tracks are audio tracks */
+ if (cdda_track_audiop (pcdrom_drive, trackno))
+ n_audio_tracks++;
+ }
+
+ /* get trackinfo[0] cdtext information (the disc) */
+ cdtext_t *pcdtext = nullptr;
+ if (aud_get_bool ("CDDA", "use_cdtext"))
+ {
+ AUDDBG ("getting cd-text information for disc\n");
+#if LIBCDIO_VERSION_NUM >= 90
+ pcdtext = cdio_get_cdtext (pcdrom_drive->p_cdio);
+ if (pcdtext == nullptr)
+#else
+ pcdtext = cdio_get_cdtext (pcdrom_drive->p_cdio, 0);
+ if (pcdtext == nullptr || pcdtext->field[CDTEXT_TITLE] == nullptr)
+#endif
+ {
+ AUDDBG ("no cd-text available for disc\n");
+ }
+ else
+ {
+#if LIBCDIO_VERSION_NUM >= 90
+ trackinfo[0].performer = String (cdtext_get_const (pcdtext, CDTEXT_FIELD_PERFORMER, 0));
+ trackinfo[0].name = String (cdtext_get_const (pcdtext, CDTEXT_FIELD_TITLE, 0));
+ trackinfo[0].genre = String (cdtext_get_const (pcdtext, CDTEXT_FIELD_GENRE, 0));
+#else
+ trackinfo[0].performer = String (pcdtext->field[CDTEXT_PERFORMER]);
+ trackinfo[0].name = String (pcdtext->field[CDTEXT_TITLE]);
+ trackinfo[0].genre = String (pcdtext->field[CDTEXT_GENRE]);
+#endif
+ }
+ }
+
+ /* get track information from cdtext */
+ bool cdtext_was_available = false;
+ for (trackno = firsttrackno; trackno <= lasttrackno; trackno++)
+ {
+#if LIBCDIO_VERSION_NUM < 90
+ if (aud_get_bool ("CDDA", "use_cdtext"))
+ {
+ AUDDBG ("getting cd-text information for track %d\n", trackno);
+ pcdtext = cdio_get_cdtext (pcdrom_drive->p_cdio, trackno);
+ if (pcdtext == nullptr || pcdtext->field[CDTEXT_PERFORMER] == nullptr)
+ {
+ AUDDBG ("no cd-text available for track %d\n", trackno);
+ pcdtext = nullptr;
+ }
+ }
+#endif
+
+ if (pcdtext != nullptr)
+ {
+#if LIBCDIO_VERSION_NUM >= 90
+ trackinfo[trackno].performer = String (cdtext_get_const (pcdtext, CDTEXT_FIELD_PERFORMER, trackno));
+ trackinfo[trackno].name = String (cdtext_get_const (pcdtext, CDTEXT_FIELD_TITLE, trackno));
+ trackinfo[trackno].genre = String (cdtext_get_const (pcdtext, CDTEXT_FIELD_GENRE, trackno));
+#else
+ trackinfo[trackno].performer = String (pcdtext->field[CDTEXT_PERFORMER]);
+ trackinfo[trackno].name = String (pcdtext->field[CDTEXT_TITLE]);
+ trackinfo[trackno].genre = String (pcdtext->field[CDTEXT_GENRE]);
+#endif
+ cdtext_was_available = true;
+ }
+ }
+
+ if (!cdtext_was_available)
+ {
+ /* initialize de cddb subsystem */
+ cddb_conn_t *pcddb_conn = nullptr;
+ cddb_disc_t *pcddb_disc = nullptr;
+ cddb_track_t *pcddb_track = nullptr;
+ lba_t lba; /* Logical Block Address */
+
+ if (aud_get_bool ("CDDA", "use_cddb"))
+ {
+ pcddb_conn = cddb_new ();
+ if (pcddb_conn == nullptr)
+ cdaudio_error (_("Failed to create the cddb connection."));
+ else
+ {
+ AUDDBG ("getting CDDB info\n");
+
+ cddb_cache_enable (pcddb_conn);
+ // cddb_cache_set_dir(pcddb_conn, "~/.cddbslave");
+
+ String server = aud_get_str ("CDDA", "cddbserver");
+ String path = aud_get_str ("CDDA", "cddbpath");
+ int port = aud_get_int ("CDDA", "cddbport");
+
+ if (aud_get_bool (nullptr, "use_proxy"))
+ {
+ String prhost = aud_get_str (nullptr, "proxy_host");
+ int prport = aud_get_int (nullptr, "proxy_port");
+ String pruser = aud_get_str (nullptr, "proxy_user");
+ String prpass = aud_get_str (nullptr, "proxy_pass");
+
+ cddb_http_proxy_enable (pcddb_conn);
+ cddb_set_http_proxy_server_name (pcddb_conn, prhost);
+ cddb_set_http_proxy_server_port (pcddb_conn, prport);
+ cddb_set_http_proxy_username (pcddb_conn, pruser);
+ cddb_set_http_proxy_password (pcddb_conn, prpass);
+
+ cddb_set_server_name (pcddb_conn, server);
+ cddb_set_server_port (pcddb_conn, port);
+ }
+ else if (aud_get_bool ("CDDA", "cddbhttp"))
+ {
+ cddb_http_enable (pcddb_conn);
+ cddb_set_server_name (pcddb_conn, server);
+ cddb_set_server_port (pcddb_conn, port);
+ cddb_set_http_path_query (pcddb_conn, path);
+ }
+ else
+ {
+ cddb_set_server_name (pcddb_conn, server);
+ cddb_set_server_port (pcddb_conn, port);
+ }
+
+ pcddb_disc = cddb_disc_new ();
+
+ lba = cdio_get_track_lba (pcdrom_drive->p_cdio,
+ CDIO_CDROM_LEADOUT_TRACK);
+ cddb_disc_set_length (pcddb_disc, FRAMES_TO_SECONDS (lba));
+
+ for (trackno = firsttrackno; trackno <= lasttrackno; trackno++)
+ {
+ pcddb_track = cddb_track_new ();
+ cddb_track_set_frame_offset (pcddb_track,
+ cdio_get_track_lba (
+ pcdrom_drive->p_cdio,
+ trackno));
+ cddb_disc_add_track (pcddb_disc, pcddb_track);
+ }
+
+ cddb_disc_calc_discid (pcddb_disc);
+
+ unsigned discid = cddb_disc_get_discid (pcddb_disc);
+ AUDDBG ("CDDB disc id = %x\n", discid);
+
+ int matches;
+ if ((matches = cddb_query (pcddb_conn, pcddb_disc)) == -1)
+ {
+ if (cddb_errno (pcddb_conn) == CDDB_ERR_OK)
+ cdaudio_error (_("Failed to query the CDDB server"));
+ else
+ cdaudio_error (_("Failed to query the CDDB server: %s"),
+ cddb_error_str (cddb_errno
+ (pcddb_conn)));
+
+ cddb_disc_destroy (pcddb_disc);
+ pcddb_disc = nullptr;
+ }
+ else
+ {
+ if (matches == 0)
+ {
+ AUDDBG ("no cddb info available for this disc\n");
+
+ cddb_disc_destroy (pcddb_disc);
+ pcddb_disc = nullptr;
+ }
+ else
+ {
+ AUDDBG ("CDDB disc category = \"%s\"\n",
+ cddb_disc_get_category_str (pcddb_disc));
+
+ cddb_read (pcddb_conn, pcddb_disc);
+ if (cddb_errno (pcddb_conn) != CDDB_ERR_OK)
+ {
+ cdaudio_error (_("Failed to read the cddb info: %s"),
+ cddb_error_str (cddb_errno
+ (pcddb_conn)));
+ cddb_disc_destroy (pcddb_disc);
+ pcddb_disc = nullptr;
+ }
+ else
+ {
+ trackinfo[0].performer = String (cddb_disc_get_artist (pcddb_disc));
+ trackinfo[0].name = String (cddb_disc_get_title (pcddb_disc));
+ trackinfo[0].genre = String (cddb_disc_get_genre (pcddb_disc));
+
+ int trackno;
+ for (trackno = firsttrackno; trackno <= lasttrackno;
+ trackno++)
+ {
+ cddb_track_t *pcddb_track =
+ cddb_disc_get_track (pcddb_disc,
+ trackno - 1);
+
+ trackinfo[trackno].performer = String (cddb_track_get_artist (pcddb_track));
+ trackinfo[trackno].name = String (cddb_track_get_title (pcddb_track));
+ trackinfo[trackno].genre = String (cddb_disc_get_genre (pcddb_disc));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (pcddb_disc != nullptr)
+ cddb_disc_destroy (pcddb_disc);
+
+ if (pcddb_conn != nullptr)
+ cddb_destroy (pcddb_conn);
+ }
+
+ return true;
+}
+
+/* mutex must be locked */
+static void refresh_trackinfo (bool warning)
+{
+ if (pcdrom_drive == nullptr)
+ {
+ open_cd ();
+ if (pcdrom_drive == nullptr)
+ return;
+ }
+
+ int mode = cdio_get_discmode (pcdrom_drive->p_cdio);
+#ifdef _WIN32 /* cdio_get_discmode reports the wrong disk type sometimes */
+ if (mode == CDIO_DISC_MODE_NO_INFO || mode == CDIO_DISC_MODE_ERROR)
+#else
+ if (mode != CDIO_DISC_MODE_CD_DA && mode != CDIO_DISC_MODE_CD_MIXED)
+#endif
+ {
+ if (warning)
+ {
+ if (mode == CDIO_DISC_MODE_NO_INFO)
+ cdaudio_error (_("Drive is empty."));
+ else
+ cdaudio_error (_("Unsupported disk type."));
+ }
+
+ reset_trackinfo ();
+ return;
+ }
+
+ if (! trackinfo.len () || cdio_get_media_changed (pcdrom_drive->p_cdio))
+ {
+ trackinfo.clear ();
+
+ if (scan_cd ())
+ trigger_monitor ();
+ else
+ reset_trackinfo ();
+ }
+}
+
+/* mutex must be locked */
+static void reset_trackinfo ()
+{
+ monitor_source.stop ();
+
+ if (pcdrom_drive != nullptr)
+ {
+ cdda_close (pcdrom_drive);
+ pcdrom_drive = nullptr;
+ }
+
+ trackinfo.clear ();
+}
+
+/* thread safe (mutex may be locked) */
+static int calculate_track_length (int startlsn, int endlsn)
+{
+ return ((endlsn - startlsn + 1) * 1000) / 75;
+}
+
+/* thread safe (mutex may be locked) */
+static int find_trackno_from_filename (const char * filename)
+{
+ int track;
+
+ if (strncmp (filename, "cdda://?", 8) || sscanf (filename + 8, "%d",
+ &track) != 1)
+ return -1;
+
+ return track;
+}
diff --git a/src/compressor/Makefile b/src/compressor/Makefile
index 06786087b345..43787e0ef518 100644
--- a/src/compressor/Makefile
+++ b/src/compressor/Makefile
@@ -1,12 +1,13 @@
PLUGIN = compressor${PLUGIN_SUFFIX}
-SRCS = compressor.c plugin.c
+SRCS = compressor.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += -lm ${GLIB_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
+LIBS += -lm
diff --git a/src/compressor/compressor.c b/src/compressor/compressor.c
deleted file mode 100644
index e9ac74bf27f6..000000000000
--- a/src/compressor/compressor.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Dynamic Range Compression Plugin for Audacious
- * Copyright 2010-2012 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <audacious/misc.h>
-
-#include "compressor.h"
-
-/* Response time adjustments. Maybe this should be adjustable. Or maybe that
- * would just be confusing. I don't know. */
-#define CHUNK_TIME 0.2 /* seconds */
-#define CHUNKS 5
-#define DECAY 0.3
-
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-
-static float * buffer, * output, * peaks;
-static int output_size;
-static int chunk_size, buffer_size;
-static int ring_at, buffer_filled, peaks_filled;
-static float current_peak;
-static int output_filled;
-static int current_channels, current_rate;
-
-static void buffer_append (float * * data, int * length)
-{
- int offset = (chunk_size * ring_at + buffer_filled) % buffer_size;
- int writable = MIN (* length, buffer_size - buffer_filled);
-
- if (writable <= buffer_size - offset)
- memcpy (buffer + offset, * data, sizeof (float) * writable);
- else
- {
- int part = buffer_size - offset;
-
- memcpy (buffer + offset, * data, part);
- memcpy (buffer, (* data) + part, writable - part);
- }
-
- buffer_filled += writable;
- * data += writable;
- * length -= writable;
-}
-
-/* I used to find the maximum sample and take that as the peak, but that doesn't
- * work well on badly clipped tracks. Now, I use the highly sophisticated
- * method of averaging the absolute value of the samples and multiplying by 6, a
- * number proved by experiment (on exactly three files) to best approximate the
- * actual peak. */
-
-static float calc_peak (float * data, int length)
-{
- if (! length)
- return 0;
-
- float sum = 0;
-
- float * end = data + length;
- while (data < end)
- sum += fabsf (* data ++);
-
- return sum / length * 6;
-}
-
-static void do_ramp (float * data, int length, float peak_a, float peak_b)
-{
- float center = aud_get_double ("compressor", "center");
- float range = aud_get_double ("compressor", "range");
- float a = powf (peak_a / center, range - 1);
- float b = powf (peak_b / center, range - 1);
-
- for (int count = 0; count < length; count ++)
- {
- * data = (* data) * (a * (length - count) + b * count) / length;
- data ++;
- }
-}
-
-static void output_append (float * data, int length)
-{
- if (output_size < output_filled + length)
- {
- output_size = output_filled + length;
- output = g_renew (float, output, output_size);
- }
-
- memcpy (output + output_filled, data, sizeof (float) * length);
- output_filled += length;
-}
-
-static void reset (void)
-{
- ring_at = 0;
- buffer_filled = 0;
- peaks_filled = 0;
- current_peak = 0.0;
-}
-
-#define IN_RING(i) ((ring_at + i) % CHUNKS)
-#define GET_PEAK(i) peaks[IN_RING (i)]
-
-static inline float FMAX (float a, float b)
-{
- return a > b ? a : b;
-}
-
-static void do_compress (float * * data, int * samples, char finish)
-{
- float new_peak;
-
- output_filled = 0;
-
- while (1)
- {
- buffer_append (data, samples);
-
- if (buffer_filled < buffer_size)
- break;
-
- for (; peaks_filled < CHUNKS; peaks_filled ++)
- GET_PEAK (peaks_filled) = calc_peak (buffer + chunk_size * IN_RING
- (peaks_filled), chunk_size);
-
- if (current_peak == 0.0)
- current_peak = FMAX (0.01, calc_peak (peaks, CHUNKS));
-
- new_peak = FMAX (0.01, GET_PEAK (0));
- new_peak = FMAX (new_peak, current_peak * (1.0 - DECAY));
-
- for (int count = 1; count < CHUNKS; count ++)
- new_peak = FMAX (new_peak, current_peak + (GET_PEAK (count) -
- current_peak) / count);
-
- do_ramp (buffer + chunk_size * ring_at, chunk_size, current_peak,
- new_peak);
-
- output_append (buffer + chunk_size * ring_at, chunk_size);
-
- ring_at = IN_RING (1);
- buffer_filled -= chunk_size;
- peaks_filled --;
- current_peak = new_peak;
- }
-
- if (finish)
- {
- int offset = chunk_size * ring_at;
- int first = MIN (buffer_filled, buffer_size - offset);
- int second = buffer_filled - first;
-
- if (current_peak == 0.0)
- {
- current_peak = FMAX (0.01, calc_peak (buffer + offset, first));
- current_peak = FMAX (current_peak, calc_peak (buffer, second));
- }
-
- do_ramp (buffer + offset, first, current_peak, current_peak);
- do_ramp (buffer, second, current_peak, current_peak);
-
- output_append (buffer + offset, first);
- output_append (buffer, second);
-
- reset ();
- }
-
- * data = output;
- * samples = output_filled;
-}
-
-int compressor_init (void)
-{
- compressor_config_load ();
-
- buffer = NULL;
- output = NULL;
- output_size = 0;
- peaks = NULL;
-
- return 1;
-}
-
-void compressor_cleanup (void)
-{
- g_free (buffer);
- g_free (output);
- g_free (peaks);
-}
-
-void compressor_start (int * channels, int * rate)
-{
- chunk_size = (* channels) * (int) ((* rate) * CHUNK_TIME);
- buffer_size = chunk_size * CHUNKS;
- buffer = g_renew (float, buffer, buffer_size);
- peaks = g_renew (float, peaks, CHUNKS);
-
- current_channels = * channels;
- current_rate = * rate;
-
- reset ();
-}
-
-void compressor_process (float * * data, int * samples)
-{
- do_compress (data, samples, 0);
-}
-
-void compressor_flush (void)
-{
- reset ();
-}
-
-void compressor_finish (float * * data, int * samples)
-{
- do_compress (data, samples, 1);
-}
-
-int compressor_adjust_delay (int delay)
-{
- return delay + (int64_t) (buffer_filled / current_channels) * 1000 / current_rate;
-}
diff --git a/src/compressor/compressor.cc b/src/compressor/compressor.cc
new file mode 100644
index 000000000000..04a02c1d214e
--- /dev/null
+++ b/src/compressor/compressor.cc
@@ -0,0 +1,232 @@
+/*
+ * Dynamic Range Compression Plugin for Audacious
+ * Copyright 2010-2014 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <math.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/ringbuf.h>
+#include <libaudcore/runtime.h>
+
+/* Response time adjustments. Maybe this should be adjustable? */
+#define CHUNK_TIME 0.2f /* seconds */
+#define CHUNKS 5
+#define DECAY 0.3f
+
+/* What is a "normal" volume? Replay Gain stuff claims to use 89 dB, but what
+ * does that translate to in our PCM range? */
+static const char * const compressor_defaults[] = {
+ "center", "0.5",
+ "range", "0.5",
+ nullptr
+};
+
+static const PreferencesWidget compressor_widgets[] = {
+ WidgetLabel (N_("<b>Compression</b>")),
+ WidgetSpin (N_("Center volume:"),
+ WidgetFloat ("compressor", "center"),
+ {0.1, 1, 0.1}),
+ WidgetSpin (N_("Dynamic range:"),
+ WidgetFloat ("compressor", "range"),
+ {0.0, 3.0, 0.1})
+};
+
+static const PluginPreferences compressor_prefs = {{compressor_widgets}};
+
+static const char compressor_about[] =
+ N_("Dynamic Range Compression Plugin for Audacious\n"
+ "Copyright 2010-2014 John Lindgren");
+
+class Compressor : public EffectPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("Dynamic Range Compressor"),
+ PACKAGE,
+ compressor_about,
+ & compressor_prefs
+ };
+
+ constexpr Compressor () : EffectPlugin (info, 0, true) {}
+
+ bool init ();
+ void cleanup ();
+
+ void start (int & channels, int & rate);
+ Index<float> & process (Index<float> & data);
+ bool flush (bool force);
+ Index<float> & finish (Index<float> & data, bool end_of_playlist);
+ int adjust_delay (int delay);
+};
+
+EXPORT Compressor aud_plugin_instance;
+
+/* The read pointer of the ring buffer is kept aligned to the chunk size at all
+ * times. To preserve the alignment, each read from the buffer must either (a)
+ * read a multiple of the chunk size or (b) empty the buffer completely. Writes
+ * to the buffer need not be aligned to the chunk size. */
+
+static RingBuf<float> buffer, peaks;
+static Index<float> output;
+static int chunk_size;
+static float current_peak;
+static int current_channels, current_rate;
+
+/* I used to find the maximum sample and take that as the peak, but that doesn't
+ * work well on badly clipped tracks. Now, I use the highly sophisticated
+ * method of averaging the absolute value of the samples and multiplying by 6, a
+ * number proved by experiment (on exactly three files) to best approximate the
+ * actual peak. */
+
+static float calc_peak (float * data, int length)
+{
+ float sum = 0;
+
+ float * end = data + length;
+ while (data < end)
+ sum += fabsf (* data ++);
+
+ return aud::max (0.01f, sum / length * 6);
+}
+
+static void do_ramp (float * data, int length, float peak_a, float peak_b)
+{
+ float center = aud_get_double ("compressor", "center");
+ float range = aud_get_double ("compressor", "range");
+ float a = powf (peak_a / center, range - 1);
+ float b = powf (peak_b / center, range - 1);
+
+ for (int count = 0; count < length; count ++)
+ {
+ * data = (* data) * (a * (length - count) + b * count) / length;
+ data ++;
+ }
+}
+
+bool Compressor::init ()
+{
+ aud_config_set_defaults ("compressor", compressor_defaults);
+ return true;
+}
+
+void Compressor::cleanup ()
+{
+ buffer.destroy ();
+ peaks.destroy ();
+ output.clear ();
+}
+
+void Compressor::start (int & channels, int & rate)
+{
+ current_channels = channels;
+ current_rate = rate;
+
+ chunk_size = channels * (int) (rate * CHUNK_TIME);
+
+ buffer.alloc (chunk_size * CHUNKS);
+ peaks.alloc (CHUNKS);
+
+ flush (true);
+}
+
+Index<float> & Compressor::process (Index<float> & data)
+{
+ output.resize (0);
+
+ int offset = 0;
+ int remain = data.len ();
+
+ while (1)
+ {
+ int writable = aud::min (remain, buffer.space ());
+
+ buffer.copy_in (& data[offset], writable);
+
+ offset += writable;
+ remain -= writable;
+
+ if (buffer.space ())
+ break;
+
+ while (peaks.len () < CHUNKS)
+ peaks.push (calc_peak (& buffer[chunk_size * peaks.len ()], chunk_size));
+
+ if (current_peak == 0.0f)
+ {
+ for (int i = 0; i < CHUNKS; i ++)
+ current_peak = aud::max (current_peak, peaks[i]);
+ }
+
+ float new_peak = aud::max (peaks[0], current_peak * (1.0f - DECAY));
+
+ for (int count = 1; count < CHUNKS; count ++)
+ new_peak = aud::max (new_peak, current_peak + (peaks[count] - current_peak) / count);
+
+ do_ramp (& buffer[0], chunk_size, current_peak, new_peak);
+
+ buffer.move_out (output, -1, chunk_size);
+
+ current_peak = new_peak;
+ peaks.pop ();
+ }
+
+ return output;
+}
+
+bool Compressor::flush (bool force)
+{
+ buffer.discard ();
+ peaks.discard ();
+
+ current_peak = 0.0f;
+ return true;
+}
+
+Index<float> & Compressor::finish (Index<float> & data, bool end_of_playlist)
+{
+ output.resize (0);
+
+ peaks.discard ();
+
+ while (buffer.len ())
+ {
+ int writable = buffer.linear ();
+
+ if (current_peak != 0.0f)
+ do_ramp (& buffer[0], writable, current_peak, current_peak);
+
+ buffer.move_out (output, -1, writable);
+ }
+
+ if (current_peak != 0.0f)
+ do_ramp (data.begin (), data.len (), current_peak, current_peak);
+
+ output.insert (data.begin (), -1, data.len ());
+
+ return output;
+}
+
+int Compressor::adjust_delay (int delay)
+{
+ return delay + aud::rescale<int64_t> (buffer.len () / current_channels, current_rate, 1000);
+}
diff --git a/src/compressor/compressor.h b/src/compressor/compressor.h
deleted file mode 100644
index 2676ef261f46..000000000000
--- a/src/compressor/compressor.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Dynamic Range Compression Plugin for Audacious
- * Copyright 2010 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-void compressor_config_load (void);
-
-int compressor_init (void);
-void compressor_cleanup (void);
-void compressor_start (int * channels, int * rate);
-void compressor_process (float * * data, int * samples);
-void compressor_flush (void);
-void compressor_finish (float * * data, int * samples);
-int compressor_adjust_delay (int delay);
diff --git a/src/compressor/plugin.c b/src/compressor/plugin.c
deleted file mode 100644
index eabc77aef9cd..000000000000
--- a/src/compressor/plugin.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Dynamic Range Compression Plugin for Audacious
- * Copyright 2010-2012 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-#include "compressor.h"
-
-/* What is a "normal" volume? Replay Gain stuff claims to use 89 dB, but what
- * does that translate to in our PCM range? Does anybody even know? */
-static const char * const compressor_defaults[] = {
- "center", "0.5",
- "range", "0.5",
- NULL};
-
-static const PreferencesWidget compressor_widgets[] = {
- {WIDGET_LABEL, N_("<b>Compression</b>")},
- {WIDGET_SPIN_BTN, N_("Center volume:"),
- .cfg_type = VALUE_FLOAT, .csect = "compressor", .cname = "center",
- .data = {.spin_btn = {0.1, 1, 0.1}}},
- {WIDGET_SPIN_BTN, N_("Dynamic range:"),
- .cfg_type = VALUE_FLOAT, .csect = "compressor", .cname = "range",
- .data = {.spin_btn = {0.0, 3.0, 0.1}}}};
-
-static const PluginPreferences compressor_prefs = {
- .widgets = compressor_widgets,
- .n_widgets = ARRAY_LEN (compressor_widgets)};
-
-void compressor_config_load (void)
-{
- aud_config_set_defaults ("compressor", compressor_defaults);
-}
-
-static const char compressor_about[] =
- N_("Dynamic Range Compression Plugin for Audacious\n"
- "Copyright 2010-2012 John Lindgren");
-
-AUD_EFFECT_PLUGIN
-(
- .name = N_("Dynamic Range Compressor"),
- .domain = PACKAGE,
- .about_text = compressor_about,
- .prefs = & compressor_prefs,
- .init = compressor_init,
- .cleanup = compressor_cleanup,
- .start = compressor_start,
- .process = compressor_process,
- .flush = compressor_flush,
- .finish = compressor_finish,
- .adjust_delay = compressor_adjust_delay,
- .preserves_format = TRUE
-)
diff --git a/src/console/Audacious_Driver.cc b/src/console/Audacious_Driver.cc
new file mode 100644
index 000000000000..4d90bc781dc4
--- /dev/null
+++ b/src/console/Audacious_Driver.cc
@@ -0,0 +1,292 @@
+/*
+ * Audacious: Cross platform multimedia player
+ * Copyright (c) 2005-2009 Audacious Team
+ *
+ * Driver for Game_Music_Emu library. See details at:
+ * http://www.slack.net/~ant/libs/
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/runtime.h>
+
+#include "configure.h"
+#include "plugin.h"
+#include "Music_Emu.h"
+#include "Gzip_Reader.h"
+
+static const int fade_threshold = 10 * 1000;
+static const int fade_length = 8 * 1000;
+
+static bool log_err(blargg_err_t err)
+{
+ if (err)
+ AUDERR("%s\n", err);
+ return !!err;
+}
+
+static void log_warning(Music_Emu * emu)
+{
+ const char *str = emu->warning();
+ if (str)
+ AUDWARN("%s\n", str);
+}
+
+/* Handles URL parsing, file opening and identification, and file
+ * loading. Keeps file header around when loading rest of file to
+ * avoid seeking and re-reading.
+ */
+class ConsoleFileHandler {
+public:
+ String m_path; // path without track number specification
+ int m_track; // track number (0 = first track)
+ Music_Emu* m_emu; // set to 0 to take ownership
+ gme_type_t m_type;
+
+ // Parses path and identifies file type
+ ConsoleFileHandler(const char* path, VFSFile &fd);
+
+ // Creates emulator and returns 0. If this wasn't a music file or
+ // emulator couldn't be created, returns 1.
+ int load(int sample_rate);
+
+ // Deletes owned emu and closes file
+ ~ConsoleFileHandler();
+
+private:
+ char m_header[4];
+ Vfs_File_Reader vfs_in;
+ Gzip_Reader gzip_in;
+};
+
+ConsoleFileHandler::ConsoleFileHandler(const char *path, VFSFile &fd)
+{
+ m_emu = nullptr;
+ m_type = 0;
+ m_track = -1;
+
+ const char * sub;
+ uri_parse (path, nullptr, nullptr, & sub, & m_track);
+ m_path = String (str_copy (path, sub - path));
+
+ m_track -= 1;
+
+ // open vfs
+ vfs_in.reset(fd);
+
+ // now open gzip_reader on top of vfs
+ if (log_err(gzip_in.open(&vfs_in)))
+ return;
+
+ // read and identify header
+ if (!log_err(gzip_in.read(m_header, sizeof(m_header))))
+ {
+ m_type = gme_identify_extension(gme_identify_header(m_header));
+ if (!m_type)
+ {
+ m_type = gme_identify_extension(m_path);
+ if (m_type != gme_gym_type) // only trust file extension for headerless .gym files
+ m_type = 0;
+ }
+ }
+}
+
+ConsoleFileHandler::~ConsoleFileHandler()
+{
+ gme_delete(m_emu);
+}
+
+int ConsoleFileHandler::load(int sample_rate)
+{
+ if (!m_type)
+ return 1;
+
+ m_emu = gme_new_emu(m_type, sample_rate);
+ if (m_emu == nullptr)
+ {
+ log_err("Out of memory allocating emulator engine. Fatal error.");
+ return 1;
+ }
+
+ // combine header with remaining file data
+ Remaining_Reader reader(m_header, sizeof(m_header), &gzip_in);
+ if (log_err(m_emu->load(reader)))
+ return 1;
+
+ // files can be closed now
+ gzip_in.close();
+ vfs_in.close();
+
+ log_warning(m_emu);
+
+#if 0
+ // load .m3u from same directory( replace/add extension with ".m3u")
+ char *m3u_path = g_strdup(m_path);
+ char *ext = strrchr(m3u_path, '.');
+ if (ext == nullptr)
+ {
+ ext = g_strdup_printf("%s.m3u", m3u_path);
+ g_free(m3u_path);
+ m3u_path = ext;
+ }
+
+ Vfs_File_Reader m3u;
+ if (!m3u.open(m3u_path))
+ {
+ if (log_err(m_emu->load_m3u(m3u))) // TODO: fail if m3u can't be loaded?
+ log_warning(m_emu); // this will log line number of first problem in m3u
+ }
+#endif
+
+ return 0;
+}
+
+static Tuple get_track_ti(const char *path, const track_info_t *info, const int track)
+{
+ Tuple tuple;
+ tuple.set_filename (path);
+
+ tuple.set_str (Tuple::Artist, info->author);
+ tuple.set_str (Tuple::Album, info->game);
+ tuple.set_str (Tuple::Title, info->song);
+ tuple.set_str (Tuple::Copyright, info->copyright);
+ tuple.set_str (Tuple::Codec, info->system);
+ tuple.set_str (Tuple::Comment, info->comment);
+
+ if (track >= 0)
+ {
+ tuple.set_int (Tuple::Track, track + 1);
+ tuple.set_int (Tuple::Subtune, track + 1);
+ tuple.set_int (Tuple::NumSubtunes, info->track_count);
+ }
+ else
+ tuple.set_subtunes (info->track_count, nullptr);
+
+ int length = info->length;
+ if (length <= 0)
+ length = info->intro_length + 2 * info->loop_length;
+ if (length <= 0)
+ length = audcfg.loop_length * 1000;
+ else if (length >= fade_threshold)
+ length += fade_length;
+ tuple.set_int (Tuple::Length, length);
+
+ return tuple;
+}
+
+Tuple ConsolePlugin::read_tuple(const char *filename, VFSFile &file)
+{
+ ConsoleFileHandler fh(filename, file);
+
+ if (!fh.m_type)
+ return Tuple ();
+
+ if (!fh.load(gme_info_only))
+ {
+ track_info_t info;
+ if (!log_err(fh.m_emu->track_info(&info, fh.m_track < 0 ? 0 : fh.m_track)))
+ return get_track_ti(fh.m_path, &info, fh.m_track);
+ }
+
+ return Tuple ();
+}
+
+bool ConsolePlugin::play(const char *filename, VFSFile &file)
+{
+ int length, sample_rate;
+ track_info_t info;
+
+ // identify file
+ ConsoleFileHandler fh(filename, file);
+ if (!fh.m_type)
+ return false;
+
+ if (fh.m_track < 0)
+ fh.m_track = 0;
+
+ // select sample rate
+ sample_rate = 0;
+ if (fh.m_type == gme_spc_type)
+ sample_rate = 32000;
+ if (audcfg.resample)
+ sample_rate = audcfg.resample_rate;
+ if (sample_rate == 0)
+ sample_rate = 44100;
+
+ // create emulator and load file
+ if (fh.load(sample_rate))
+ return false;
+
+ // stereo echo depth
+ gme_set_stereo_depth(fh.m_emu, 1.0 / 100 * audcfg.echo);
+
+ // set equalizer
+ if (audcfg.treble || audcfg.bass)
+ {
+ Music_Emu::equalizer_t eq;
+
+ // bass - logarithmic, 2 to 8194 Hz
+ double bass = 1.0 - (audcfg.bass / 200.0 + 0.5);
+ eq.bass = (long) (2.0 + pow( 2.0, bass * 13 ));
+
+ // treble - -50 to 0 to +5 dB
+ double treble = audcfg.treble / 100.0;
+ eq.treble = treble * (treble < 0 ? 50.0 : 5.0);
+
+ fh.m_emu->set_equalizer(eq);
+ }
+
+ // get info
+ length = -1;
+ if (!log_err(fh.m_emu->track_info(&info, fh.m_track)))
+ {
+ if (fh.m_type == gme_spc_type && audcfg.ignore_spc_length)
+ info.length = -1;
+
+ Tuple tuple = get_track_ti(fh.m_path, &info, fh.m_track);
+ if (tuple)
+ {
+ length = tuple.get_int (Tuple::Length);
+ set_stream_bitrate(fh.m_emu->voice_count() * 1000);
+ }
+ }
+
+ // start track
+ if (log_err(fh.m_emu->start_track(fh.m_track)))
+ return false;
+
+ log_warning(fh.m_emu);
+
+ open_audio(FMT_S16_NE, sample_rate, 2);
+
+ // set fade time
+ if (length <= 0)
+ length = audcfg.loop_length * 1000;
+ if (length >= fade_threshold + fade_length)
+ length -= fade_length / 2;
+ fh.m_emu->set_fade(length, fade_length);
+
+ while (!check_stop())
+ {
+ /* Perform seek, if requested */
+ int seek_value = check_seek();
+ if (seek_value >= 0)
+ fh.m_emu->seek(seek_value);
+
+ /* Fill and play buffer of audio */
+ int const buf_size = 1024;
+ Music_Emu::sample_t buf[buf_size];
+
+ fh.m_emu->play(buf_size, buf);
+
+ write_audio(buf, sizeof(buf));
+
+ if (fh.m_emu->track_ended())
+ break;
+ }
+
+ return true;
+}
diff --git a/src/console/Audacious_Driver.cxx b/src/console/Audacious_Driver.cxx
deleted file mode 100644
index b0c27b562697..000000000000
--- a/src/console/Audacious_Driver.cxx
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Audacious: Cross platform multimedia player
- * Copyright (c) 2005-2009 Audacious Team
- *
- * Driver for Game_Music_Emu library. See details at:
- * http://www.slack.net/~ant/libs/
- */
-
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-
-extern "C" {
-#include <libaudcore/audstrings.h>
-#include <audacious/input.h>
-#include <audacious/plugin.h>
-}
-
-#include "configure.h"
-#include "Music_Emu.h"
-#include "Gzip_Reader.h"
-
-static const int fade_threshold = 10 * 1000;
-static const int fade_length = 8 * 1000;
-
-static blargg_err_t log_err(blargg_err_t err)
-{
- if (err)
- fprintf (stderr, "console: %s\n", err);
- return err;
-}
-
-static void log_warning(Music_Emu * emu)
-{
- const char *str = emu->warning();
- if (str != NULL)
- fprintf (stderr, "console: %s\n", str);
-}
-
-/* Handles URL parsing, file opening and identification, and file
- * loading. Keeps file header around when loading rest of file to
- * avoid seeking and re-reading.
- */
-class ConsoleFileHandler {
-public:
- char *m_path; // path without track number specification
- int m_track; // track number (0 = first track)
- Music_Emu* m_emu; // set to 0 to take ownership
- gme_type_t m_type;
-
- // Parses path and identifies file type
- ConsoleFileHandler(const char* path, VFSFile *fd = NULL);
-
- // Creates emulator and returns 0. If this wasn't a music file or
- // emulator couldn't be created, returns 1.
- int load(int sample_rate);
-
- // Deletes owned emu and closes file
- ~ConsoleFileHandler();
-
-private:
- char m_header[4];
- Vfs_File_Reader vfs_in;
- Gzip_Reader gzip_in;
-};
-
-ConsoleFileHandler::ConsoleFileHandler(const char *path, VFSFile *fd)
-{
- m_emu = NULL;
- m_type = 0;
- m_track = -1;
-
- const char * sub;
- uri_parse (path, NULL, NULL, & sub, & m_track);
- m_path = str_nget (path, sub - path);
-
- m_track -= 1;
-
- // open vfs
- if (fd != NULL)
- vfs_in.reset(fd);
- else if (log_err(vfs_in.open(m_path)))
- return;
-
- // now open gzip_reader on top of vfs
- if (log_err(gzip_in.open(&vfs_in)))
- return;
-
- // read and identify header
- if (!log_err(gzip_in.read(m_header, sizeof(m_header))))
- {
- m_type = gme_identify_extension(gme_identify_header(m_header));
- if (!m_type)
- {
- m_type = gme_identify_extension(m_path);
- if (m_type != gme_gym_type) // only trust file extension for headerless .gym files
- m_type = 0;
- }
- }
-}
-
-ConsoleFileHandler::~ConsoleFileHandler()
-{
- gme_delete(m_emu);
- str_unref (m_path);
-}
-
-int ConsoleFileHandler::load(int sample_rate)
-{
- if (!m_type)
- return 1;
-
- m_emu = gme_new_emu(m_type, sample_rate);
- if (m_emu == NULL)
- {
- log_err("Out of memory allocating emulator engine. Fatal error.");
- return 1;
- }
-
- // combine header with remaining file data
- Remaining_Reader reader(m_header, sizeof(m_header), &gzip_in);
- if (log_err(m_emu->load(reader)))
- return 1;
-
- // files can be closed now
- gzip_in.close();
- vfs_in.close();
-
- log_warning(m_emu);
-
-#if 0
- // load .m3u from same directory( replace/add extension with ".m3u")
- char *m3u_path = g_strdup(m_path);
- char *ext = strrchr(m3u_path, '.');
- if (ext == NULL)
- {
- ext = g_strdup_printf("%s.m3u", m3u_path);
- g_free(m3u_path);
- m3u_path = ext;
- }
-
- Vfs_File_Reader m3u;
- if (!m3u.open(m3u_path))
- {
- if (log_err(m_emu->load_m3u(m3u))) // TODO: fail if m3u can't be loaded?
- log_warning(m_emu); // this will log line number of first problem in m3u
- }
-#endif
-
- return 0;
-}
-
-static Tuple * get_track_ti(const char *path, const track_info_t *info, const int track)
-{
- Tuple *ti = tuple_new_from_filename(path);
-
- if (ti != NULL)
- {
- tuple_set_str (ti, FIELD_ARTIST, info->author);
- tuple_set_str (ti, FIELD_ALBUM, info->game);
- tuple_set_str (ti, FIELD_TITLE, info->song);
- tuple_set_str (ti, FIELD_COPYRIGHT, info->copyright);
- tuple_set_str (ti, FIELD_CODEC, info->system);
- tuple_set_str (ti, FIELD_COMMENT, info->comment);
-
- if (track >= 0)
- {
- tuple_set_int(ti, FIELD_TRACK_NUMBER, track + 1);
- tuple_set_int(ti, FIELD_SUBSONG_ID, track + 1);
- tuple_set_int(ti, FIELD_SUBSONG_NUM, info->track_count);
- }
- else
- tuple_set_subtunes (ti, info->track_count, NULL);
-
- int length = info->length;
- if (length <= 0)
- length = info->intro_length + 2 * info->loop_length;
- if (length <= 0)
- length = audcfg.loop_length * 1000;
- else if (length >= fade_threshold)
- length += fade_length;
- tuple_set_int(ti, FIELD_LENGTH, length);
- }
-
- return ti;
-}
-
-extern "C" Tuple * console_probe_for_tuple(const char *filename, VFSFile *fd)
-{
- ConsoleFileHandler fh(filename, fd);
-
- if (!fh.m_type)
- return NULL;
-
- if (!fh.load(gme_info_only))
- {
- track_info_t info;
- if (!log_err(fh.m_emu->track_info(&info, fh.m_track < 0 ? 0 : fh.m_track)))
- return get_track_ti(fh.m_path, &info, fh.m_track);
- }
-
- return NULL;
-}
-
-extern "C" bool_t console_play(const char *filename, VFSFile *file)
-{
- int length, sample_rate;
- track_info_t info;
-
- // identify file
- ConsoleFileHandler fh(filename);
- if (!fh.m_type)
- return FALSE;
-
- if (fh.m_track < 0)
- fh.m_track = 0;
-
- // select sample rate
- sample_rate = 0;
- if (fh.m_type == gme_spc_type)
- sample_rate = 32000;
- if (audcfg.resample)
- sample_rate = audcfg.resample_rate;
- if (sample_rate == 0)
- sample_rate = 44100;
-
- // create emulator and load file
- if (fh.load(sample_rate))
- return FALSE;
-
- // stereo echo depth
- gme_set_stereo_depth(fh.m_emu, 1.0 / 100 * audcfg.echo);
-
- // set equalizer
- if (audcfg.treble || audcfg.bass)
- {
- Music_Emu::equalizer_t eq;
-
- // bass - logarithmic, 2 to 8194 Hz
- double bass = 1.0 - (audcfg.bass / 200.0 + 0.5);
- eq.bass = (long) (2.0 + pow( 2.0, bass * 13 ));
-
- // treble - -50 to 0 to +5 dB
- double treble = audcfg.treble / 100.0;
- eq.treble = treble * (treble < 0 ? 50.0 : 5.0);
-
- fh.m_emu->set_equalizer(eq);
- }
-
- // get info
- length = -1;
- if (!log_err(fh.m_emu->track_info(&info, fh.m_track)))
- {
- if (fh.m_type == gme_spc_type && audcfg.ignore_spc_length)
- info.length = -1;
-
- Tuple *ti = get_track_ti(fh.m_path, &info, fh.m_track);
- if (ti != NULL)
- {
- length = tuple_get_int(ti, FIELD_LENGTH);
- tuple_unref(ti);
- aud_input_set_bitrate(fh.m_emu->voice_count() * 1000);
- }
- }
-
- // start track
- if (log_err(fh.m_emu->start_track(fh.m_track)))
- return FALSE;
-
- log_warning(fh.m_emu);
-
- if (!aud_input_open_audio(FMT_S16_NE, sample_rate, 2))
- return FALSE;
-
- // set fade time
- if (length <= 0)
- length = audcfg.loop_length * 1000;
- if (length >= fade_threshold + fade_length)
- length -= fade_length / 2;
- fh.m_emu->set_fade(length, fade_length);
-
- while (!aud_input_check_stop())
- {
- /* Perform seek, if requested */
- int seek_value = aud_input_check_seek();
- if (seek_value >= 0)
- fh.m_emu->seek(seek_value);
-
- /* Fill and play buffer of audio */
- int const buf_size = 1024;
- Music_Emu::sample_t buf[buf_size];
-
- fh.m_emu->play(buf_size, buf);
-
- aud_input_write_audio(buf, sizeof(buf));
-
- if (fh.m_emu->track_ended())
- break;
- }
-
- return TRUE;
-}
diff --git a/src/console/Ay_Apu.cc b/src/console/Ay_Apu.cc
new file mode 100644
index 000000000000..107d058334bc
--- /dev/null
+++ b/src/console/Ay_Apu.cc
@@ -0,0 +1,395 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Ay_Apu.h"
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+// Emulation inaccuracies:
+// * Noise isn't run when not in use
+// * Changes to envelope and noise periods are delayed until next reload
+// * Super-sonic tone should attenuate output to about 60%, not 50%
+
+// Tones above this frequency are treated as disabled tone at half volume.
+// Power of two is more efficient (avoids division).
+unsigned const inaudible_freq = 16384;
+
+int const period_factor = 16;
+
+static byte const amp_table [16] =
+{
+#define ENTRY( n ) byte (n * Ay_Apu::amp_range + 0.5)
+ // With channels tied together and 1K resistor to ground (as datasheet recommends),
+ // output nearly matches logarithmic curve as claimed. Approx. 1.5 dB per step.
+ ENTRY(0.000000),ENTRY(0.007813),ENTRY(0.011049),ENTRY(0.015625),
+ ENTRY(0.022097),ENTRY(0.031250),ENTRY(0.044194),ENTRY(0.062500),
+ ENTRY(0.088388),ENTRY(0.125000),ENTRY(0.176777),ENTRY(0.250000),
+ ENTRY(0.353553),ENTRY(0.500000),ENTRY(0.707107),ENTRY(1.000000),
+
+ /*
+ // Measured from an AY-3-8910A chip with date code 8611.
+
+ // Direct voltages without any load (very linear)
+ ENTRY(0.000000),ENTRY(0.046237),ENTRY(0.064516),ENTRY(0.089785),
+ ENTRY(0.124731),ENTRY(0.173118),ENTRY(0.225806),ENTRY(0.329032),
+ ENTRY(0.360215),ENTRY(0.494624),ENTRY(0.594624),ENTRY(0.672043),
+ ENTRY(0.766129),ENTRY(0.841935),ENTRY(0.926882),ENTRY(1.000000),
+ // With only some load
+ ENTRY(0.000000),ENTRY(0.011940),ENTRY(0.017413),ENTRY(0.024876),
+ ENTRY(0.036318),ENTRY(0.054229),ENTRY(0.072637),ENTRY(0.122388),
+ ENTRY(0.174129),ENTRY(0.239303),ENTRY(0.323881),ENTRY(0.410945),
+ ENTRY(0.527363),ENTRY(0.651741),ENTRY(0.832338),ENTRY(1.000000),
+ */
+#undef ENTRY
+};
+
+static byte const modes [8] =
+{
+#define MODE( a0,a1, b0,b1, c0,c1 ) \
+ (a0 | a1<<1 | b0<<2 | b1<<3 | c0<<4 | c1<<5)
+ MODE( 1,0, 1,0, 1,0 ),
+ MODE( 1,0, 0,0, 0,0 ),
+ MODE( 1,0, 0,1, 1,0 ),
+ MODE( 1,0, 1,1, 1,1 ),
+ MODE( 0,1, 0,1, 0,1 ),
+ MODE( 0,1, 1,1, 1,1 ),
+ MODE( 0,1, 1,0, 0,1 ),
+ MODE( 0,1, 0,0, 0,0 ),
+};
+
+Ay_Apu::Ay_Apu()
+{
+ // build full table of the upper 8 envelope waveforms
+ for ( int m = 8; m--; )
+ {
+ byte* out = env.modes [m];
+ int flags = modes [m];
+ for ( int x = 3; --x >= 0; )
+ {
+ int amp = flags & 1;
+ int end = flags >> 1 & 1;
+ int step = end - amp;
+ amp *= 15;
+ for ( int y = 16; --y >= 0; )
+ {
+ *out++ = amp_table [amp];
+ amp += step;
+ }
+ flags >>= 2;
+ }
+ }
+
+ output( 0 );
+ volume( 1.0 );
+ reset();
+}
+
+void Ay_Apu::reset()
+{
+ last_time = 0;
+ noise.delay = 0;
+ noise.lfsr = 1;
+
+ osc_t* osc = &oscs [osc_count];
+ do
+ {
+ osc--;
+ osc->period = period_factor;
+ osc->delay = 0;
+ osc->last_amp = 0;
+ osc->phase = 0;
+ }
+ while ( osc != oscs );
+
+ for ( int i = sizeof regs; --i >= 0; )
+ regs [i] = 0;
+ regs [7] = 0xFF;
+ write_data_( 13, 0 );
+}
+
+void Ay_Apu::write_data_( int addr, int data )
+{
+ assert( (unsigned) addr < reg_count );
+
+ if ( (unsigned) addr >= 14 )
+ {
+ #ifdef debug_printf
+ debug_printf( "Wrote to I/O port %02X\n", (int) addr );
+ #endif
+ }
+
+ // envelope mode
+ if ( addr == 13 )
+ {
+ if ( !(data & 8) ) // convert modes 0-7 to proper equivalents
+ data = (data & 4) ? 15 : 9;
+ env.wave = env.modes [data - 7];
+ env.pos = -48;
+ env.delay = 0; // will get set to envelope period in run_until()
+ }
+ regs [addr] = data;
+
+ // handle period changes accurately
+ int i = addr >> 1;
+ if ( i < osc_count )
+ {
+ blip_time_t period = (regs [i * 2 + 1] & 0x0F) * (0x100L * period_factor) +
+ regs [i * 2] * period_factor;
+ if ( !period )
+ period = period_factor;
+
+ // adjust time of next timer expiration based on change in period
+ osc_t& osc = oscs [i];
+ if ( (osc.delay += period - osc.period) < 0 )
+ osc.delay = 0;
+ osc.period = period;
+ }
+
+ // TODO: same as above for envelope timer, and it also has a divide by two after it
+}
+
+int const noise_off = 0x08;
+int const tone_off = 0x01;
+
+void Ay_Apu::run_until( blip_time_t final_end_time )
+{
+ require( final_end_time >= last_time );
+
+ // noise period and initial values
+ blip_time_t const noise_period_factor = period_factor * 2; // verified
+ blip_time_t noise_period = (regs [6] & 0x1F) * noise_period_factor;
+ if ( !noise_period )
+ noise_period = noise_period_factor;
+ blip_time_t const old_noise_delay = noise.delay;
+ blargg_ulong const old_noise_lfsr = noise.lfsr;
+
+ // envelope period
+ blip_time_t const env_period_factor = period_factor * 2; // verified
+ blip_time_t env_period = (regs [12] * 0x100L + regs [11]) * env_period_factor;
+ if ( !env_period )
+ env_period = env_period_factor; // same as period 1 on my AY chip
+ if ( !env.delay )
+ env.delay = env_period;
+
+ // run each osc separately
+ for ( int index = 0; index < osc_count; index++ )
+ {
+ osc_t* const osc = &oscs [index];
+ int osc_mode = regs [7] >> index;
+
+ // output
+ Blip_Buffer* const osc_output = osc->output;
+ if ( !osc_output )
+ continue;
+ osc_output->set_modified();
+
+ // period
+ int half_vol = 0;
+ blip_time_t inaudible_period = (blargg_ulong) (osc_output->clock_rate() +
+ inaudible_freq) / (inaudible_freq * 2);
+ if ( osc->period <= inaudible_period && !(osc_mode & tone_off) )
+ {
+ half_vol = 1; // Actually around 60%, but 50% is close enough
+ osc_mode |= tone_off;
+ }
+
+ // envelope
+ blip_time_t start_time = last_time;
+ blip_time_t end_time = final_end_time;
+ int const vol_mode = regs [0x08 + index];
+ int volume = amp_table [vol_mode & 0x0F] >> half_vol;
+ int osc_env_pos = env.pos;
+ if ( vol_mode & 0x10 )
+ {
+ volume = env.wave [osc_env_pos] >> half_vol;
+ // use envelope only if it's a repeating wave or a ramp that hasn't finished
+ if ( !(regs [13] & 1) || osc_env_pos < -32 )
+ {
+ end_time = start_time + env.delay;
+ if ( end_time >= final_end_time )
+ end_time = final_end_time;
+
+ //if ( !(regs [12] | regs [11]) )
+ // debug_printf( "Used envelope period 0\n" );
+ }
+ else if ( !volume )
+ {
+ osc_mode = noise_off | tone_off;
+ }
+ }
+ else if ( !volume )
+ {
+ osc_mode = noise_off | tone_off;
+ }
+
+ // tone time
+ blip_time_t const period = osc->period;
+ blip_time_t time = start_time + osc->delay;
+ if ( osc_mode & tone_off ) // maintain tone's phase when off
+ {
+ blargg_long count = (final_end_time - time + period - 1) / period;
+ time += count * period;
+ osc->phase ^= count & 1;
+ }
+
+ // noise time
+ blip_time_t ntime = final_end_time;
+ blargg_ulong noise_lfsr = 1;
+ if ( !(osc_mode & noise_off) )
+ {
+ ntime = start_time + old_noise_delay;
+ noise_lfsr = old_noise_lfsr;
+ //if ( (regs [6] & 0x1F) == 0 )
+ // debug_printf( "Used noise period 0\n" );
+ }
+
+ // The following efficiently handles several cases (least demanding first):
+ // * Tone, noise, and envelope disabled, where channel acts as 4-bit DAC
+ // * Just tone or just noise, envelope disabled
+ // * Envelope controlling tone and/or noise
+ // * Tone and noise disabled, envelope enabled with high frequency
+ // * Tone and noise together
+ // * Tone and noise together with envelope
+
+ // This loop only runs one iteration if envelope is disabled. If envelope
+ // is being used as a waveform (tone and noise disabled), this loop will
+ // still be reasonably efficient since the bulk of it will be skipped.
+ while ( 1 )
+ {
+ // current amplitude
+ int amp = 0;
+ if ( (osc_mode | osc->phase) & 1 & (osc_mode >> 3 | noise_lfsr) )
+ amp = volume;
+ {
+ int delta = amp - osc->last_amp;
+ if ( delta )
+ {
+ osc->last_amp = amp;
+ synth_.offset( start_time, delta, osc_output );
+ }
+ }
+
+ // Run wave and noise interleved with each catching up to the other.
+ // If one or both are disabled, their "current time" will be past end time,
+ // so there will be no significant performance hit.
+ if ( ntime < end_time || time < end_time )
+ {
+ // Since amplitude was updated above, delta will always be +/- volume,
+ // so we can avoid using last_amp every time to calculate the delta.
+ int delta = amp * 2 - volume;
+ int delta_non_zero = delta != 0;
+ int phase = osc->phase | (osc_mode & tone_off); assert( tone_off == 0x01 );
+ do
+ {
+ // run noise
+ blip_time_t end = end_time;
+ if ( end_time > time ) end = time;
+ if ( phase & delta_non_zero )
+ {
+ while ( ntime <= end ) // must advance *past* time to avoid hang
+ {
+ int changed = noise_lfsr + 1;
+ noise_lfsr = (-(noise_lfsr & 1) & 0x12000) ^ (noise_lfsr >> 1);
+ if ( changed & 2 )
+ {
+ delta = -delta;
+ synth_.offset( ntime, delta, osc_output );
+ }
+ ntime += noise_period;
+ }
+ }
+ else
+ {
+ // 20 or more noise periods on average for some music
+ blargg_long remain = end - ntime;
+ blargg_long count = remain / noise_period;
+ if ( remain >= 0 )
+ ntime += noise_period + count * noise_period;
+ }
+
+ // run tone
+ end = end_time;
+ if ( end_time > ntime ) end = ntime;
+ if ( noise_lfsr & delta_non_zero )
+ {
+ while ( time < end )
+ {
+ delta = -delta;
+ synth_.offset( time, delta, osc_output );
+ time += period;
+ //phase ^= 1;
+ }
+ //assert( phase == (delta > 0) );
+ phase = unsigned (-delta) >> (CHAR_BIT * sizeof (unsigned) - 1);
+ // (delta > 0)
+ }
+ else
+ {
+ // loop usually runs less than once
+ //SUB_CASE_COUNTER( (time < end) * (end - time + period - 1) / period );
+
+ while ( time < end )
+ {
+ time += period;
+ phase ^= 1;
+ }
+ }
+ }
+ while ( time < end_time || ntime < end_time );
+
+ osc->last_amp = (delta + volume) >> 1;
+ if ( !(osc_mode & tone_off) )
+ osc->phase = phase;
+ }
+
+ if ( end_time >= final_end_time )
+ break; // breaks first time when envelope is disabled
+
+ // next envelope step
+ if ( ++osc_env_pos >= 0 )
+ osc_env_pos -= 32;
+ volume = env.wave [osc_env_pos] >> half_vol;
+
+ start_time = end_time;
+ end_time += env_period;
+ if ( end_time > final_end_time )
+ end_time = final_end_time;
+ }
+ osc->delay = time - final_end_time;
+
+ if ( !(osc_mode & noise_off) )
+ {
+ noise.delay = ntime - final_end_time;
+ noise.lfsr = noise_lfsr;
+ }
+ }
+
+ // TODO: optimized saw wave envelope?
+
+ // maintain envelope phase
+ blip_time_t remain = final_end_time - last_time - env.delay;
+ if ( remain >= 0 )
+ {
+ blargg_long count = (remain + env_period) / env_period;
+ env.pos += count;
+ if ( env.pos >= 0 )
+ env.pos = (env.pos & 31) - 32;
+ remain -= count * env_period;
+ assert( -remain <= env_period );
+ }
+ env.delay = -remain;
+ assert( env.delay > 0 );
+ assert( env.pos < 0 );
+
+ last_time = final_end_time;
+}
diff --git a/src/console/Ay_Apu.cxx b/src/console/Ay_Apu.cxx
deleted file mode 100644
index 107d058334bc..000000000000
--- a/src/console/Ay_Apu.cxx
+++ /dev/null
@@ -1,395 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Ay_Apu.h"
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Emulation inaccuracies:
-// * Noise isn't run when not in use
-// * Changes to envelope and noise periods are delayed until next reload
-// * Super-sonic tone should attenuate output to about 60%, not 50%
-
-// Tones above this frequency are treated as disabled tone at half volume.
-// Power of two is more efficient (avoids division).
-unsigned const inaudible_freq = 16384;
-
-int const period_factor = 16;
-
-static byte const amp_table [16] =
-{
-#define ENTRY( n ) byte (n * Ay_Apu::amp_range + 0.5)
- // With channels tied together and 1K resistor to ground (as datasheet recommends),
- // output nearly matches logarithmic curve as claimed. Approx. 1.5 dB per step.
- ENTRY(0.000000),ENTRY(0.007813),ENTRY(0.011049),ENTRY(0.015625),
- ENTRY(0.022097),ENTRY(0.031250),ENTRY(0.044194),ENTRY(0.062500),
- ENTRY(0.088388),ENTRY(0.125000),ENTRY(0.176777),ENTRY(0.250000),
- ENTRY(0.353553),ENTRY(0.500000),ENTRY(0.707107),ENTRY(1.000000),
-
- /*
- // Measured from an AY-3-8910A chip with date code 8611.
-
- // Direct voltages without any load (very linear)
- ENTRY(0.000000),ENTRY(0.046237),ENTRY(0.064516),ENTRY(0.089785),
- ENTRY(0.124731),ENTRY(0.173118),ENTRY(0.225806),ENTRY(0.329032),
- ENTRY(0.360215),ENTRY(0.494624),ENTRY(0.594624),ENTRY(0.672043),
- ENTRY(0.766129),ENTRY(0.841935),ENTRY(0.926882),ENTRY(1.000000),
- // With only some load
- ENTRY(0.000000),ENTRY(0.011940),ENTRY(0.017413),ENTRY(0.024876),
- ENTRY(0.036318),ENTRY(0.054229),ENTRY(0.072637),ENTRY(0.122388),
- ENTRY(0.174129),ENTRY(0.239303),ENTRY(0.323881),ENTRY(0.410945),
- ENTRY(0.527363),ENTRY(0.651741),ENTRY(0.832338),ENTRY(1.000000),
- */
-#undef ENTRY
-};
-
-static byte const modes [8] =
-{
-#define MODE( a0,a1, b0,b1, c0,c1 ) \
- (a0 | a1<<1 | b0<<2 | b1<<3 | c0<<4 | c1<<5)
- MODE( 1,0, 1,0, 1,0 ),
- MODE( 1,0, 0,0, 0,0 ),
- MODE( 1,0, 0,1, 1,0 ),
- MODE( 1,0, 1,1, 1,1 ),
- MODE( 0,1, 0,1, 0,1 ),
- MODE( 0,1, 1,1, 1,1 ),
- MODE( 0,1, 1,0, 0,1 ),
- MODE( 0,1, 0,0, 0,0 ),
-};
-
-Ay_Apu::Ay_Apu()
-{
- // build full table of the upper 8 envelope waveforms
- for ( int m = 8; m--; )
- {
- byte* out = env.modes [m];
- int flags = modes [m];
- for ( int x = 3; --x >= 0; )
- {
- int amp = flags & 1;
- int end = flags >> 1 & 1;
- int step = end - amp;
- amp *= 15;
- for ( int y = 16; --y >= 0; )
- {
- *out++ = amp_table [amp];
- amp += step;
- }
- flags >>= 2;
- }
- }
-
- output( 0 );
- volume( 1.0 );
- reset();
-}
-
-void Ay_Apu::reset()
-{
- last_time = 0;
- noise.delay = 0;
- noise.lfsr = 1;
-
- osc_t* osc = &oscs [osc_count];
- do
- {
- osc--;
- osc->period = period_factor;
- osc->delay = 0;
- osc->last_amp = 0;
- osc->phase = 0;
- }
- while ( osc != oscs );
-
- for ( int i = sizeof regs; --i >= 0; )
- regs [i] = 0;
- regs [7] = 0xFF;
- write_data_( 13, 0 );
-}
-
-void Ay_Apu::write_data_( int addr, int data )
-{
- assert( (unsigned) addr < reg_count );
-
- if ( (unsigned) addr >= 14 )
- {
- #ifdef debug_printf
- debug_printf( "Wrote to I/O port %02X\n", (int) addr );
- #endif
- }
-
- // envelope mode
- if ( addr == 13 )
- {
- if ( !(data & 8) ) // convert modes 0-7 to proper equivalents
- data = (data & 4) ? 15 : 9;
- env.wave = env.modes [data - 7];
- env.pos = -48;
- env.delay = 0; // will get set to envelope period in run_until()
- }
- regs [addr] = data;
-
- // handle period changes accurately
- int i = addr >> 1;
- if ( i < osc_count )
- {
- blip_time_t period = (regs [i * 2 + 1] & 0x0F) * (0x100L * period_factor) +
- regs [i * 2] * period_factor;
- if ( !period )
- period = period_factor;
-
- // adjust time of next timer expiration based on change in period
- osc_t& osc = oscs [i];
- if ( (osc.delay += period - osc.period) < 0 )
- osc.delay = 0;
- osc.period = period;
- }
-
- // TODO: same as above for envelope timer, and it also has a divide by two after it
-}
-
-int const noise_off = 0x08;
-int const tone_off = 0x01;
-
-void Ay_Apu::run_until( blip_time_t final_end_time )
-{
- require( final_end_time >= last_time );
-
- // noise period and initial values
- blip_time_t const noise_period_factor = period_factor * 2; // verified
- blip_time_t noise_period = (regs [6] & 0x1F) * noise_period_factor;
- if ( !noise_period )
- noise_period = noise_period_factor;
- blip_time_t const old_noise_delay = noise.delay;
- blargg_ulong const old_noise_lfsr = noise.lfsr;
-
- // envelope period
- blip_time_t const env_period_factor = period_factor * 2; // verified
- blip_time_t env_period = (regs [12] * 0x100L + regs [11]) * env_period_factor;
- if ( !env_period )
- env_period = env_period_factor; // same as period 1 on my AY chip
- if ( !env.delay )
- env.delay = env_period;
-
- // run each osc separately
- for ( int index = 0; index < osc_count; index++ )
- {
- osc_t* const osc = &oscs [index];
- int osc_mode = regs [7] >> index;
-
- // output
- Blip_Buffer* const osc_output = osc->output;
- if ( !osc_output )
- continue;
- osc_output->set_modified();
-
- // period
- int half_vol = 0;
- blip_time_t inaudible_period = (blargg_ulong) (osc_output->clock_rate() +
- inaudible_freq) / (inaudible_freq * 2);
- if ( osc->period <= inaudible_period && !(osc_mode & tone_off) )
- {
- half_vol = 1; // Actually around 60%, but 50% is close enough
- osc_mode |= tone_off;
- }
-
- // envelope
- blip_time_t start_time = last_time;
- blip_time_t end_time = final_end_time;
- int const vol_mode = regs [0x08 + index];
- int volume = amp_table [vol_mode & 0x0F] >> half_vol;
- int osc_env_pos = env.pos;
- if ( vol_mode & 0x10 )
- {
- volume = env.wave [osc_env_pos] >> half_vol;
- // use envelope only if it's a repeating wave or a ramp that hasn't finished
- if ( !(regs [13] & 1) || osc_env_pos < -32 )
- {
- end_time = start_time + env.delay;
- if ( end_time >= final_end_time )
- end_time = final_end_time;
-
- //if ( !(regs [12] | regs [11]) )
- // debug_printf( "Used envelope period 0\n" );
- }
- else if ( !volume )
- {
- osc_mode = noise_off | tone_off;
- }
- }
- else if ( !volume )
- {
- osc_mode = noise_off | tone_off;
- }
-
- // tone time
- blip_time_t const period = osc->period;
- blip_time_t time = start_time + osc->delay;
- if ( osc_mode & tone_off ) // maintain tone's phase when off
- {
- blargg_long count = (final_end_time - time + period - 1) / period;
- time += count * period;
- osc->phase ^= count & 1;
- }
-
- // noise time
- blip_time_t ntime = final_end_time;
- blargg_ulong noise_lfsr = 1;
- if ( !(osc_mode & noise_off) )
- {
- ntime = start_time + old_noise_delay;
- noise_lfsr = old_noise_lfsr;
- //if ( (regs [6] & 0x1F) == 0 )
- // debug_printf( "Used noise period 0\n" );
- }
-
- // The following efficiently handles several cases (least demanding first):
- // * Tone, noise, and envelope disabled, where channel acts as 4-bit DAC
- // * Just tone or just noise, envelope disabled
- // * Envelope controlling tone and/or noise
- // * Tone and noise disabled, envelope enabled with high frequency
- // * Tone and noise together
- // * Tone and noise together with envelope
-
- // This loop only runs one iteration if envelope is disabled. If envelope
- // is being used as a waveform (tone and noise disabled), this loop will
- // still be reasonably efficient since the bulk of it will be skipped.
- while ( 1 )
- {
- // current amplitude
- int amp = 0;
- if ( (osc_mode | osc->phase) & 1 & (osc_mode >> 3 | noise_lfsr) )
- amp = volume;
- {
- int delta = amp - osc->last_amp;
- if ( delta )
- {
- osc->last_amp = amp;
- synth_.offset( start_time, delta, osc_output );
- }
- }
-
- // Run wave and noise interleved with each catching up to the other.
- // If one or both are disabled, their "current time" will be past end time,
- // so there will be no significant performance hit.
- if ( ntime < end_time || time < end_time )
- {
- // Since amplitude was updated above, delta will always be +/- volume,
- // so we can avoid using last_amp every time to calculate the delta.
- int delta = amp * 2 - volume;
- int delta_non_zero = delta != 0;
- int phase = osc->phase | (osc_mode & tone_off); assert( tone_off == 0x01 );
- do
- {
- // run noise
- blip_time_t end = end_time;
- if ( end_time > time ) end = time;
- if ( phase & delta_non_zero )
- {
- while ( ntime <= end ) // must advance *past* time to avoid hang
- {
- int changed = noise_lfsr + 1;
- noise_lfsr = (-(noise_lfsr & 1) & 0x12000) ^ (noise_lfsr >> 1);
- if ( changed & 2 )
- {
- delta = -delta;
- synth_.offset( ntime, delta, osc_output );
- }
- ntime += noise_period;
- }
- }
- else
- {
- // 20 or more noise periods on average for some music
- blargg_long remain = end - ntime;
- blargg_long count = remain / noise_period;
- if ( remain >= 0 )
- ntime += noise_period + count * noise_period;
- }
-
- // run tone
- end = end_time;
- if ( end_time > ntime ) end = ntime;
- if ( noise_lfsr & delta_non_zero )
- {
- while ( time < end )
- {
- delta = -delta;
- synth_.offset( time, delta, osc_output );
- time += period;
- //phase ^= 1;
- }
- //assert( phase == (delta > 0) );
- phase = unsigned (-delta) >> (CHAR_BIT * sizeof (unsigned) - 1);
- // (delta > 0)
- }
- else
- {
- // loop usually runs less than once
- //SUB_CASE_COUNTER( (time < end) * (end - time + period - 1) / period );
-
- while ( time < end )
- {
- time += period;
- phase ^= 1;
- }
- }
- }
- while ( time < end_time || ntime < end_time );
-
- osc->last_amp = (delta + volume) >> 1;
- if ( !(osc_mode & tone_off) )
- osc->phase = phase;
- }
-
- if ( end_time >= final_end_time )
- break; // breaks first time when envelope is disabled
-
- // next envelope step
- if ( ++osc_env_pos >= 0 )
- osc_env_pos -= 32;
- volume = env.wave [osc_env_pos] >> half_vol;
-
- start_time = end_time;
- end_time += env_period;
- if ( end_time > final_end_time )
- end_time = final_end_time;
- }
- osc->delay = time - final_end_time;
-
- if ( !(osc_mode & noise_off) )
- {
- noise.delay = ntime - final_end_time;
- noise.lfsr = noise_lfsr;
- }
- }
-
- // TODO: optimized saw wave envelope?
-
- // maintain envelope phase
- blip_time_t remain = final_end_time - last_time - env.delay;
- if ( remain >= 0 )
- {
- blargg_long count = (remain + env_period) / env_period;
- env.pos += count;
- if ( env.pos >= 0 )
- env.pos = (env.pos & 31) - 32;
- remain -= count * env_period;
- assert( -remain <= env_period );
- }
- env.delay = -remain;
- assert( env.delay > 0 );
- assert( env.pos < 0 );
-
- last_time = final_end_time;
-}
diff --git a/src/console/Ay_Apu.h b/src/console/Ay_Apu.h
index fe5d12518de0..b7f223898426 100644
--- a/src/console/Ay_Apu.h
+++ b/src/console/Ay_Apu.h
@@ -9,7 +9,7 @@
class Ay_Apu {
public:
- // Set buffer to generate all sound into, or disable sound if NULL
+ // Set buffer to generate all sound into, or disable sound if nullptr
void output( Blip_Buffer* );
// Reset sound chip
@@ -27,7 +27,7 @@ public:
// Additional features
// Set sound output of specific oscillator to buffer, where index is
- // 0, 1, or 2. If buffer is NULL, the specified oscillator is muted.
+ // 0, 1, or 2. If buffer is nullptr, the specified oscillator is muted.
enum { osc_count = 3 };
void osc_output( int index, Blip_Buffer* );
@@ -50,7 +50,6 @@ private:
Blip_Buffer* output;
} oscs [osc_count];
blip_time_t last_time;
- byte latch;
byte regs [reg_count];
struct {
diff --git a/src/console/Ay_Cpu.cc b/src/console/Ay_Cpu.cc
new file mode 100644
index 000000000000..bee9eedf7e56
--- /dev/null
+++ b/src/console/Ay_Cpu.cc
@@ -0,0 +1,1661 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+/*
+Last validated with zexall 2006.11.21 5:26 PM
+* Doesn't implement the R register or immediate interrupt after EI.
+* Address wrap-around isn't completely correct, but is prevented from crashing emulator.
+*/
+
+#include "Ay_Cpu.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+
+//#include "z80_cpu_log.h"
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#define SYNC_TIME() (void) (s.time = s_time)
+#define RELOAD_TIME() (void) (s_time = s.time)
+
+// Callbacks to emulator
+
+#define CPU_OUT( cpu, addr, data, TIME )\
+ ay_cpu_out( cpu, TIME, addr, data )
+
+#define CPU_IN( cpu, addr, TIME )\
+ ay_cpu_in( cpu, addr )
+
+#include "blargg_source.h"
+
+// flags, named with hex value for clarity
+int const S80 = 0x80;
+int const Z40 = 0x40;
+int const F20 = 0x20;
+int const H10 = 0x10;
+int const F08 = 0x08;
+int const V04 = 0x04;
+int const P04 = 0x04;
+int const N02 = 0x02;
+int const C01 = 0x01;
+
+#define SZ28P( n ) szpc [n]
+#define SZ28PC( n ) szpc [n]
+#define SZ28C( n ) (szpc [n] & ~P04)
+#define SZ28( n ) SZ28C( n )
+
+#define SET_R( n ) (void) (r.r = n)
+#define GET_R() (r.r)
+
+Ay_Cpu::Ay_Cpu()
+{
+ state = &state_;
+ for ( int i = 0x100; --i >= 0; )
+ {
+ int even = 1;
+ for ( int p = i; p; p >>= 1 )
+ even ^= p;
+ int n = (i & (S80 | F20 | F08)) | ((even & 1) * P04);
+ szpc [i] = n;
+ szpc [i + 0x100] = n | C01;
+ }
+ szpc [0x000] |= Z40;
+ szpc [0x100] |= Z40;
+}
+
+void Ay_Cpu::reset( void* m )
+{
+ mem = (uint8_t*) m;
+
+ check( state == &state_ );
+ state = &state_;
+ state_.time = 0;
+ state_.base = 0;
+ end_time_ = 0;
+
+ memset( &r, 0, sizeof r );
+}
+
+#define TIME (s_time + s.base)
+#define READ_PROG( addr ) (mem [addr])
+#define INSTR( offset ) READ_PROG( pc + (offset) )
+#define GET_ADDR() GET_LE16( &READ_PROG( pc ) )
+#define READ( addr ) READ_PROG( addr )
+#define WRITE( addr, data ) (void) (READ_PROG( addr ) = data)
+#define READ_WORD( addr ) GET_LE16( &READ_PROG( addr ) )
+#define WRITE_WORD( addr, data ) SET_LE16( &READ_PROG( addr ), data )
+#define IN( addr ) CPU_IN( this, addr, TIME )
+#define OUT( addr, data ) CPU_OUT( this, addr, data, TIME )
+
+#if BLARGG_BIG_ENDIAN
+ #define R8( n, offset ) ((r8_ - offset) [n])
+#elif BLARGG_LITTLE_ENDIAN
+ #define R8( n, offset ) ((r8_ - offset) [(n) ^ 1])
+#else
+ #error "Byte order of CPU must be known"
+#endif
+
+//#define R16( n, shift, offset ) (r16_ [((n) >> shift) - (offset >> shift)])
+
+// help compiler see that it can just adjust stack offset, saving an extra instruction
+#define R16( n, shift, offset )\
+ (*(uint16_t*) ((char*) r16_ - (offset >> (shift - 1)) + ((n) >> (shift - 1))))
+
+#define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e
+#define CASE6( a, b, c, d, e, f ) CASE5( a, b, c, d, e ): case 0x##f
+#define CASE7( a, b, c, d, e, f, g ) CASE6( a, b, c, d, e, f ): case 0x##g
+#define CASE8( a, b, c, d, e, f, g, h ) CASE7( a, b, c, d, e, f, g ): case 0x##h
+
+// high four bits are $ED time - 8, low four bits are $DD/$FD time - 8
+static byte const ed_dd_timing [0x100] = {
+//0 1 2 3 4 5 6 7 8 9 A B C D E F
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x06,0x0C,0x02,0x00,0x00,0x03,0x00,0x00,0x07,0x0C,0x02,0x00,0x00,0x03,0x00,
+0x00,0x00,0x00,0x00,0x0F,0x0F,0x0B,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
+0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
+0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,
+0x4B,0x4B,0x7B,0xCB,0x0B,0x6B,0x00,0x0B,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
+0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,
+0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x06,0x00,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+// even on x86, using short and unsigned char was slower
+typedef int fint16;
+typedef unsigned fuint16;
+typedef unsigned fuint8;
+
+bool Ay_Cpu::run( cpu_time_t end_time )
+{
+ set_end_time( end_time );
+ state_t s = this->state_;
+ this->state = &s;
+ bool warning = false;
+
+ union {
+ regs_t rg;
+ pairs_t rp;
+ uint8_t r8_ [8]; // indexed
+ uint16_t r16_ [4];
+ };
+ rg = this->r.b;
+
+ cpu_time_t s_time = s.time;
+ uint8_t* const mem = this->mem; // cache
+ fuint16 pc = r.pc;
+ fuint16 sp = r.sp;
+ fuint16 ix = r.ix; // TODO: keep in memory for direct access?
+ fuint16 iy = r.iy;
+ int flags = r.b.flags;
+
+ goto loop;
+jr_not_taken:
+ s_time -= 5;
+ goto loop;
+call_not_taken:
+ s_time -= 7;
+jp_not_taken:
+ pc += 2;
+loop:
+
+ check( (unsigned long) pc < 0x10000 );
+ check( (unsigned long) sp < 0x10000 );
+ check( (unsigned) flags < 0x100 );
+ check( (unsigned) ix < 0x10000 );
+ check( (unsigned) iy < 0x10000 );
+
+ fuint8 opcode;
+ opcode = READ_PROG( pc );
+ pc++;
+
+ static byte const base_timing [0x100] = {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 0
+ 13,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, // 1
+ 12,10,16, 6, 4, 4, 7, 4,12,11,16, 6, 4, 4, 7, 4, // 2
+ 12,10,13, 6,11,11,10, 4,12,11,13, 6, 4, 4, 7, 4, // 3
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 4
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 5
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 6
+ 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 7
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 8
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 9
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // A
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // B
+ 11,10,10,10,17,11, 7,11,11,10,10, 8,17,17, 7,11, // C
+ 11,10,10,11,17,11, 7,11,11, 4,10,11,17, 8, 7,11, // D
+ 11,10,10,19,17,11, 7,11,11, 4,10, 4,17, 8, 7,11, // E
+ 11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F
+ };
+
+ fuint16 data;
+ data = base_timing [opcode];
+ if ( (s_time += data) >= 0 )
+ goto possibly_out_of_time;
+almost_out_of_time:
+
+ data = READ_PROG( pc );
+
+ #ifdef Z80_CPU_LOG_H
+ //log_opcode( opcode, READ_PROG( pc ) );
+ z80_log_regs( rg.a, rp.bc, rp.de, rp.hl, sp, ix, iy );
+ z80_cpu_log( "new", pc - 1, opcode, READ_PROG( pc ),
+ READ_PROG( pc + 1 ), READ_PROG( pc + 2 ) );
+ #endif
+
+ switch ( opcode )
+ {
+possibly_out_of_time:
+ if ( s_time < (int) data )
+ goto almost_out_of_time;
+ s_time -= data;
+ goto out_of_time;
+
+// Common
+
+ case 0x00: // NOP
+ CASE7( 40, 49, 52, 5B, 64, 6D, 7F ): // LD B,B etc.
+ goto loop;
+
+ case 0x08:{// EX AF,AF'
+ int temp = r.alt.b.a;
+ r.alt.b.a = rg.a;
+ rg.a = temp;
+
+ temp = r.alt.b.flags;
+ r.alt.b.flags = flags;
+ flags = temp;
+ goto loop;
+ }
+
+ case 0xD3: // OUT (imm),A
+ pc++;
+ OUT( data + rg.a * 0x100, rg.a );
+ goto loop;
+
+ case 0x2E: // LD L,imm
+ pc++;
+ rg.l = data;
+ goto loop;
+
+ case 0x3E: // LD A,imm
+ pc++;
+ rg.a = data;
+ goto loop;
+
+ case 0x3A:{// LD A,(addr)
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ rg.a = READ( addr );
+ goto loop;
+ }
+
+// Conditional
+
+#define ZERO (flags & Z40)
+#define CARRY (flags & C01)
+#define EVEN (flags & P04)
+#define MINUS (flags & S80)
+
+// JR
+#define JR( cond ) {\
+ int disp = (int8_t) data;\
+ pc++;\
+ if ( !(cond) )\
+ goto jr_not_taken;\
+ pc += disp;\
+ goto loop;\
+}
+
+ case 0x20: JR( !ZERO ) // JR NZ,disp
+ case 0x28: JR( ZERO ) // JR Z,disp
+ case 0x30: JR( !CARRY ) // JR NC,disp
+ case 0x38: JR( CARRY ) // JR C,disp
+ case 0x18: JR( true ) // JR disp
+
+ case 0x10:{// DJNZ disp
+ int temp = rg.b - 1;
+ rg.b = temp;
+ JR( temp )
+ }
+
+// JP
+#define JP( cond ) if ( !(cond) ) goto jp_not_taken; pc = GET_ADDR(); goto loop;
+
+ case 0xC2: JP( !ZERO ) // JP NZ,addr
+ case 0xCA: JP( ZERO ) // JP Z,addr
+ case 0xD2: JP( !CARRY ) // JP NC,addr
+ case 0xDA: JP( CARRY ) // JP C,addr
+ case 0xE2: JP( !EVEN ) // JP PO,addr
+ case 0xEA: JP( EVEN ) // JP PE,addr
+ case 0xF2: JP( !MINUS ) // JP P,addr
+ case 0xFA: JP( MINUS ) // JP M,addr
+
+ case 0xC3: // JP addr
+ pc = GET_ADDR();
+ goto loop;
+
+ case 0xE9: // JP HL
+ pc = rp.hl;
+ goto loop;
+
+// RET
+#define RET( cond ) if ( cond ) goto ret_taken; s_time -= 6; goto loop;
+
+ case 0xC0: RET( !ZERO ) // RET NZ
+ case 0xC8: RET( ZERO ) // RET Z
+ case 0xD0: RET( !CARRY ) // RET NC
+ case 0xD8: RET( CARRY ) // RET C
+ case 0xE0: RET( !EVEN ) // RET PO
+ case 0xE8: RET( EVEN ) // RET PE
+ case 0xF0: RET( !MINUS ) // RET P
+ case 0xF8: RET( MINUS ) // RET M
+
+ case 0xC9: // RET
+ ret_taken:
+ pc = READ_WORD( sp );
+ sp = uint16_t (sp + 2);
+ goto loop;
+
+// CALL
+#define CALL( cond ) if ( cond ) goto call_taken; goto call_not_taken;
+
+ case 0xC4: CALL( !ZERO ) // CALL NZ,addr
+ case 0xCC: CALL( ZERO ) // CALL Z,addr
+ case 0xD4: CALL( !CARRY ) // CALL NC,addr
+ case 0xDC: CALL( CARRY ) // CALL C,addr
+ case 0xE4: CALL( !EVEN ) // CALL PO,addr
+ case 0xEC: CALL( EVEN ) // CALL PE,addr
+ case 0xF4: CALL( !MINUS ) // CALL P,addr
+ case 0xFC: CALL( MINUS ) // CALL M,addr
+
+ case 0xCD:{// CALL addr
+ call_taken:
+ fuint16 addr = pc + 2;
+ pc = GET_ADDR();
+ sp = uint16_t (sp - 2);
+ WRITE_WORD( sp, addr );
+ goto loop;
+ }
+
+ case 0xFF: // RST
+ if ( (pc - 1) > 0xFFFF )
+ {
+ pc = uint16_t (pc - 1);
+ s_time -= 11;
+ goto loop;
+ }
+ CASE7( C7, CF, D7, DF, E7, EF, F7 ):
+ data = pc;
+ pc = opcode & 0x38;
+ goto push_data;
+
+// PUSH/POP
+ case 0xF5: // PUSH AF
+ data = rg.a * 0x100u + flags;
+ goto push_data;
+
+ case 0xC5: // PUSH BC
+ case 0xD5: // PUSH DE
+ case 0xE5: // PUSH HL
+ data = R16( opcode, 4, 0xC5 );
+ push_data:
+ sp = uint16_t (sp - 2);
+ WRITE_WORD( sp, data );
+ goto loop;
+
+ case 0xF1: // POP AF
+ flags = READ( sp );
+ rg.a = READ( sp + 1 );
+ sp = uint16_t (sp + 2);
+ goto loop;
+
+ case 0xC1: // POP BC
+ case 0xD1: // POP DE
+ case 0xE1: // POP HL
+ R16( opcode, 4, 0xC1 ) = READ_WORD( sp );
+ sp = uint16_t (sp + 2);
+ goto loop;
+
+// ADC/ADD/SBC/SUB
+ case 0x96: // SUB (HL)
+ case 0x86: // ADD (HL)
+ flags &= ~C01;
+ case 0x9E: // SBC (HL)
+ case 0x8E: // ADC (HL)
+ data = READ( rp.hl );
+ goto adc_data;
+
+ case 0xD6: // SUB A,imm
+ case 0xC6: // ADD imm
+ flags &= ~C01;
+ case 0xDE: // SBC A,imm
+ case 0xCE: // ADC imm
+ pc++;
+ goto adc_data;
+
+ CASE7( 90, 91, 92, 93, 94, 95, 97 ): // SUB r
+ CASE7( 80, 81, 82, 83, 84, 85, 87 ): // ADD r
+ flags &= ~C01;
+ CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // SBC r
+ CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // ADC r
+ data = R8( opcode & 7, 0 );
+ adc_data: {
+ int result = data + (flags & C01);
+ data ^= rg.a;
+ flags = opcode >> 3 & N02; // bit 4 is set in subtract opcodes
+ if ( flags )
+ result = -result;
+ result += rg.a;
+ data ^= result;
+ flags |=(data & H10) |
+ ((data - -0x80) >> 6 & V04) |
+ SZ28C( result & 0x1FF );
+ rg.a = result;
+ goto loop;
+ }
+
+// CP
+ case 0xBE: // CP (HL)
+ data = READ( rp.hl );
+ goto cp_data;
+
+ case 0xFE: // CP imm
+ pc++;
+ goto cp_data;
+
+ CASE7( B8, B9, BA, BB, BC, BD, BF ): // CP r
+ data = R8( opcode, 0xB8 );
+ cp_data: {
+ int result = rg.a - data;
+ flags = N02 | (data & (F20 | F08)) | (result >> 8 & C01);
+ data ^= rg.a;
+ flags |=(((result ^ rg.a) & data) >> 5 & V04) |
+ (((data & H10) ^ result) & (S80 | H10));
+ if ( (uint8_t) result )
+ goto loop;
+ flags |= Z40;
+ goto loop;
+ }
+
+// ADD HL,rp
+
+ case 0x39: // ADD HL,SP
+ data = sp;
+ goto add_hl_data;
+
+ case 0x09: // ADD HL,BC
+ case 0x19: // ADD HL,DE
+ case 0x29: // ADD HL,HL
+ data = R16( opcode, 4, 0x09 );
+ add_hl_data: {
+ blargg_ulong sum = rp.hl + data;
+ data ^= rp.hl;
+ rp.hl = sum;
+ flags = (flags & (S80 | Z40 | V04)) |
+ (sum >> 16) |
+ (sum >> 8 & (F20 | F08)) |
+ ((data ^ sum) >> 8 & H10);
+ goto loop;
+ }
+
+ case 0x27:{// DAA
+ int a = rg.a;
+ if ( a > 0x99 )
+ flags |= C01;
+
+ int adjust = 0x60 & -(flags & C01);
+
+ if ( flags & H10 || (a & 0x0F) > 9 )
+ adjust |= 0x06;
+
+ if ( flags & N02 )
+ adjust = -adjust;
+ a += adjust;
+
+ flags = (flags & (C01 | N02)) |
+ ((rg.a ^ a) & H10) |
+ SZ28P( (uint8_t) a );
+ rg.a = a;
+ goto loop;
+ }
+ /*
+ case 0x27:{// DAA
+ // more optimized, but probably not worth the obscurity
+ int f = (rg.a + (0xFF - 0x99)) >> 8 | flags; // (a > 0x99 ? C01 : 0) | flags
+ int adjust = 0x60 & -(f & C01); // f & C01 ? 0x60 : 0
+
+ if ( (((rg.a + (0x0F - 9)) ^ rg.a) | f) & H10 ) // flags & H10 || (rg.a & 0x0F) > 9
+ adjust |= 0x06;
+
+ if ( f & N02 )
+ adjust = -adjust;
+ int a = rg.a + adjust;
+
+ flags = (f & (N02 | C01)) | ((rg.a ^ a) & H10) | SZ28P( (uint8_t) a );
+ rg.a = a;
+ goto loop;
+ }
+ */
+
+// INC/DEC
+ case 0x34: // INC (HL)
+ data = READ( rp.hl ) + 1;
+ WRITE( rp.hl, data );
+ goto inc_set_flags;
+
+ CASE7( 04, 0C, 14, 1C, 24, 2C, 3C ): // INC r
+ data = ++R8( opcode >> 3, 0 );
+ inc_set_flags:
+ flags = (flags & C01) |
+ (((data & 0x0F) - 1) & H10) |
+ SZ28( (uint8_t) data );
+ if ( data != 0x80 )
+ goto loop;
+ flags |= V04;
+ goto loop;
+
+ case 0x35: // DEC (HL)
+ data = READ( rp.hl ) - 1;
+ WRITE( rp.hl, data );
+ goto dec_set_flags;
+
+ CASE7( 05, 0D, 15, 1D, 25, 2D, 3D ): // DEC r
+ data = --R8( opcode >> 3, 0 );
+ dec_set_flags:
+ flags = (flags & C01) | N02 |
+ (((data & 0x0F) + 1) & H10) |
+ SZ28( (uint8_t) data );
+ if ( data != 0x7F )
+ goto loop;
+ flags |= V04;
+ goto loop;
+
+ case 0x03: // INC BC
+ case 0x13: // INC DE
+ case 0x23: // INC HL
+ R16( opcode, 4, 0x03 )++;
+ goto loop;
+
+ case 0x33: // INC SP
+ sp = uint16_t (sp + 1);
+ goto loop;
+
+ case 0x0B: // DEC BC
+ case 0x1B: // DEC DE
+ case 0x2B: // DEC HL
+ R16( opcode, 4, 0x0B )--;
+ goto loop;
+
+ case 0x3B: // DEC SP
+ sp = uint16_t (sp - 1);
+ goto loop;
+
+// AND
+ case 0xA6: // AND (HL)
+ data = READ( rp.hl );
+ goto and_data;
+
+ case 0xE6: // AND imm
+ pc++;
+ goto and_data;
+
+ CASE7( A0, A1, A2, A3, A4, A5, A7 ): // AND r
+ data = R8( opcode, 0xA0 );
+ and_data:
+ rg.a &= data;
+ flags = SZ28P( rg.a ) | H10;
+ goto loop;
+
+// OR
+ case 0xB6: // OR (HL)
+ data = READ( rp.hl );
+ goto or_data;
+
+ case 0xF6: // OR imm
+ pc++;
+ goto or_data;
+
+ CASE7( B0, B1, B2, B3, B4, B5, B7 ): // OR r
+ data = R8( opcode, 0xB0 );
+ or_data:
+ rg.a |= data;
+ flags = SZ28P( rg.a );
+ goto loop;
+
+// XOR
+ case 0xAE: // XOR (HL)
+ data = READ( rp.hl );
+ goto xor_data;
+
+ case 0xEE: // XOR imm
+ pc++;
+ goto xor_data;
+
+ CASE7( A8, A9, AA, AB, AC, AD, AF ): // XOR r
+ data = R8( opcode, 0xA8 );
+ xor_data:
+ rg.a ^= data;
+ flags = SZ28P( rg.a );
+ goto loop;
+
+// LD
+ CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (HL),r
+ WRITE( rp.hl, R8( opcode, 0x70 ) );
+ goto loop;
+
+ CASE6( 41, 42, 43, 44, 45, 47 ): // LD B,r
+ CASE6( 48, 4A, 4B, 4C, 4D, 4F ): // LD C,r
+ CASE6( 50, 51, 53, 54, 55, 57 ): // LD D,r
+ CASE6( 58, 59, 5A, 5C, 5D, 5F ): // LD E,r
+ CASE6( 60, 61, 62, 63, 65, 67 ): // LD H,r
+ CASE6( 68, 69, 6A, 6B, 6C, 6F ): // LD L,r
+ CASE6( 78, 79, 7A, 7B, 7C, 7D ): // LD A,r
+ R8( opcode >> 3 & 7, 0 ) = R8( opcode & 7, 0 );
+ goto loop;
+
+ CASE5( 06, 0E, 16, 1E, 26 ): // LD r,imm
+ R8( opcode >> 3, 0 ) = data;
+ pc++;
+ goto loop;
+
+ case 0x36: // LD (HL),imm
+ pc++;
+ WRITE( rp.hl, data );
+ goto loop;
+
+ CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(HL)
+ R8( opcode >> 3, 8 ) = READ( rp.hl );
+ goto loop;
+
+ case 0x01: // LD rp,imm
+ case 0x11:
+ case 0x21:
+ R16( opcode, 4, 0x01 ) = GET_ADDR();
+ pc += 2;
+ goto loop;
+
+ case 0x31: // LD sp,imm
+ sp = GET_ADDR();
+ pc += 2;
+ goto loop;
+
+ case 0x2A:{// LD HL,(addr)
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ rp.hl = READ_WORD( addr );
+ goto loop;
+ }
+
+ case 0x32:{// LD (addr),A
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ WRITE( addr, rg.a );
+ goto loop;
+ }
+
+ case 0x22:{// LD (addr),HL
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ WRITE_WORD( addr, rp.hl );
+ goto loop;
+ }
+
+ case 0x02: // LD (BC),A
+ case 0x12: // LD (DE),A
+ WRITE( R16( opcode, 4, 0x02 ), rg.a );
+ goto loop;
+
+ case 0x0A: // LD A,(BC)
+ case 0x1A: // LD A,(DE)
+ rg.a = READ( R16( opcode, 4, 0x0A ) );
+ goto loop;
+
+ case 0xF9: // LD SP,HL
+ sp = rp.hl;
+ goto loop;
+
+// Rotate
+
+ case 0x07:{// RLCA
+ fuint16 temp = rg.a;
+ temp = (temp << 1) | (temp >> 7);
+ flags = (flags & (S80 | Z40 | P04)) |
+ (temp & (F20 | F08 | C01));
+ rg.a = temp;
+ goto loop;
+ }
+
+ case 0x0F:{// RRCA
+ fuint16 temp = rg.a;
+ flags = (flags & (S80 | Z40 | P04)) |
+ (temp & C01);
+ temp = (temp << 7) | (temp >> 1);
+ flags |= temp & (F20 | F08);
+ rg.a = temp;
+ goto loop;
+ }
+
+ case 0x17:{// RLA
+ blargg_ulong temp = (rg.a << 1) | (flags & C01);
+ flags = (flags & (S80 | Z40 | P04)) |
+ (temp & (F20 | F08)) |
+ (temp >> 8);
+ rg.a = temp;
+ goto loop;
+ }
+
+ case 0x1F:{// RRA
+ fuint16 temp = (flags << 7) | (rg.a >> 1);
+ flags = (flags & (S80 | Z40 | P04)) |
+ (temp & (F20 | F08)) |
+ (rg.a & C01);
+ rg.a = temp;
+ goto loop;
+ }
+
+// Misc
+ case 0x2F:{// CPL
+ fuint16 temp = ~rg.a;
+ flags = (flags & (S80 | Z40 | P04 | C01)) |
+ (temp & (F20 | F08)) |
+ (H10 | N02);
+ rg.a = temp;
+ goto loop;
+ }
+
+ case 0x3F:{// CCF
+ flags = ((flags & (S80 | Z40 | P04 | C01)) ^ C01) |
+ (flags << 4 & H10) |
+ (rg.a & (F20 | F08));
+ goto loop;
+ }
+
+ case 0x37: // SCF
+ flags = (flags & (S80 | Z40 | P04)) | C01 |
+ (rg.a & (F20 | F08));
+ goto loop;
+
+ case 0xDB: // IN A,(imm)
+ pc++;
+ rg.a = IN( data + rg.a * 0x100 );
+ goto loop;
+
+ case 0xE3:{// EX (SP),HL
+ fuint16 temp = READ_WORD( sp );
+ WRITE_WORD( sp, rp.hl );
+ rp.hl = temp;
+ goto loop;
+ }
+
+ case 0xEB:{// EX DE,HL
+ fuint16 temp = rp.hl;
+ rp.hl = rp.de;
+ rp.de = temp;
+ goto loop;
+ }
+
+ case 0xD9:{// EXX DE,HL
+ fuint16 temp = r.alt.w.bc;
+ r.alt.w.bc = rp.bc;
+ rp.bc = temp;
+
+ temp = r.alt.w.de;
+ r.alt.w.de = rp.de;
+ rp.de = temp;
+
+ temp = r.alt.w.hl;
+ r.alt.w.hl = rp.hl;
+ rp.hl = temp;
+ goto loop;
+ }
+
+ case 0xF3: // DI
+ r.iff1 = 0;
+ r.iff2 = 0;
+ goto loop;
+
+ case 0xFB: // EI
+ r.iff1 = 1;
+ r.iff2 = 1;
+ // TODO: delayed effect
+ goto loop;
+
+ case 0x76: // HALT
+ goto halt;
+
+//////////////////////////////////////// CB prefix
+ {
+ case 0xCB:
+ pc++;
+ switch ( data )
+ {
+
+ // Rotate left
+
+ #define RLC( read, write ) {\
+ fuint8 result = read;\
+ result = uint8_t (result << 1) | (result >> 7);\
+ flags = SZ28P( result ) | (result & C01);\
+ write;\
+ goto loop;\
+ }
+
+ case 0x06: // RLC (HL)
+ s_time += 7;
+ data = rp.hl;
+ rlc_data_addr:
+ RLC( READ( data ), WRITE( data, result ) )
+
+ CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r
+ uint8_t& reg = R8( data, 0 );
+ RLC( reg, reg = result )
+ }
+
+ #define RL( read, write ) {\
+ fuint16 result = (read << 1) | (flags & C01);\
+ flags = SZ28PC( result );\
+ write;\
+ goto loop;\
+ }
+
+ case 0x16: // RL (HL)
+ s_time += 7;
+ data = rp.hl;
+ rl_data_addr:
+ RL( READ( data ), WRITE( data, result ) )
+
+ CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r
+ uint8_t& reg = R8( data, 0x10 );
+ RL( reg, reg = result )
+ }
+
+ #define SLA( read, add, write ) {\
+ fuint16 result = (read << 1) | add;\
+ flags = SZ28PC( result );\
+ write;\
+ goto loop;\
+ }
+
+ case 0x26: // SLA (HL)
+ s_time += 7;
+ data = rp.hl;
+ sla_data_addr:
+ SLA( READ( data ), 0, WRITE( data, result ) )
+
+ CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r
+ uint8_t& reg = R8( data, 0x20 );
+ SLA( reg, 0, reg = result )
+ }
+
+ case 0x36: // SLL (HL)
+ s_time += 7;
+ data = rp.hl;
+ sll_data_addr:
+ SLA( READ( data ), 1, WRITE( data, result ) )
+
+ CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r
+ uint8_t& reg = R8( data, 0x30 );
+ SLA( reg, 1, reg = result )
+ }
+
+ // Rotate right
+
+ #define RRC( read, write ) {\
+ fuint8 result = read;\
+ flags = result & C01;\
+ result = uint8_t (result << 7) | (result >> 1);\
+ flags |= SZ28P( result );\
+ write;\
+ goto loop;\
+ }
+
+ case 0x0E: // RRC (HL)
+ s_time += 7;
+ data = rp.hl;
+ rrc_data_addr:
+ RRC( READ( data ), WRITE( data, result ) )
+
+ CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r
+ uint8_t& reg = R8( data, 0x08 );
+ RRC( reg, reg = result )
+ }
+
+ #define RR( read, write ) {\
+ fuint8 result = read;\
+ fuint8 temp = result & C01;\
+ result = uint8_t (flags << 7) | (result >> 1);\
+ flags = SZ28P( result ) | temp;\
+ write;\
+ goto loop;\
+ }
+
+ case 0x1E: // RR (HL)
+ s_time += 7;
+ data = rp.hl;
+ rr_data_addr:
+ RR( READ( data ), WRITE( data, result ) )
+
+ CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r
+ uint8_t& reg = R8( data, 0x18 );
+ RR( reg, reg = result )
+ }
+
+ #define SRA( read, write ) {\
+ fuint8 result = read;\
+ flags = result & C01;\
+ result = (result & 0x80) | (result >> 1);\
+ flags |= SZ28P( result );\
+ write;\
+ goto loop;\
+ }
+
+ case 0x2E: // SRA (HL)
+ data = rp.hl;
+ s_time += 7;
+ sra_data_addr:
+ SRA( READ( data ), WRITE( data, result ) )
+
+ CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r
+ uint8_t& reg = R8( data, 0x28 );
+ SRA( reg, reg = result )
+ }
+
+ #define SRL( read, write ) {\
+ fuint8 result = read;\
+ flags = result & C01;\
+ result >>= 1;\
+ flags |= SZ28P( result );\
+ write;\
+ goto loop;\
+ }
+
+ case 0x3E: // SRL (HL)
+ s_time += 7;
+ data = rp.hl;
+ srl_data_addr:
+ SRL( READ( data ), WRITE( data, result ) )
+
+ CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r
+ uint8_t& reg = R8( data, 0x38 );
+ SRL( reg, reg = result )
+ }
+
+ // BIT
+ {
+ unsigned temp;
+ CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL)
+ s_time += 4;
+ temp = READ( rp.hl );
+ flags &= C01;
+ goto bit_temp;
+ CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r
+ CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r
+ CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r
+ CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r
+ CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r
+ CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r
+ CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r
+ CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r
+ temp = R8( data & 7, 0 );
+ flags = (flags & C01) | (temp & (F20 | F08));
+ bit_temp:
+ int masked = temp & 1 << (data >> 3 & 7);
+ flags |=(masked & S80) | H10 |
+ ((masked - 1) >> 8 & (Z40 | P04));
+ goto loop;
+ }
+
+ // SET/RES
+ CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL)
+ CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL)
+ s_time += 7;
+ int temp = READ( rp.hl );
+ int bit = 1 << (data >> 3 & 7);
+ temp |= bit; // SET
+ if ( !(data & 0x40) )
+ temp ^= bit; // RES
+ WRITE( rp.hl, temp );
+ goto loop;
+ }
+
+ CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r
+ CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r
+ CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r
+ CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r
+ CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r
+ CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r
+ CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r
+ CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r
+ R8( data & 7, 0 ) |= 1 << (data >> 3 & 7);
+ goto loop;
+
+ CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r
+ CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r
+ CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r
+ CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r
+ CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r
+ CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r
+ CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r
+ CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r
+ R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7));
+ goto loop;
+ }
+ assert( false );
+ }
+
+//////////////////////////////////////// ED prefix
+ {
+ case 0xED:
+ pc++;
+ s_time += ed_dd_timing [data] >> 4;
+ switch ( data )
+ {
+ {
+ blargg_ulong temp;
+ case 0x72: // SBC HL,SP
+ case 0x7A: // ADC HL,SP
+ temp = sp;
+ if ( 0 )
+ case 0x42: // SBC HL,BC
+ case 0x52: // SBC HL,DE
+ case 0x62: // SBC HL,HL
+ case 0x4A: // ADC HL,BC
+ case 0x5A: // ADC HL,DE
+ case 0x6A: // ADC HL,HL
+ temp = R16( data >> 3 & 6, 1, 0 );
+ blargg_ulong sum = temp + (flags & C01);
+ flags = ~data >> 2 & N02;
+ if ( flags )
+ sum = -sum;
+ sum += rp.hl;
+ temp ^= rp.hl;
+ temp ^= sum;
+ flags |=(sum >> 16 & C01) |
+ (temp >> 8 & H10) |
+ (sum >> 8 & (S80 | F20 | F08)) |
+ ((temp - -0x8000) >> 14 & V04);
+ rp.hl = sum;
+ if ( (uint16_t) sum )
+ goto loop;
+ flags |= Z40;
+ goto loop;
+ }
+
+ CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C)
+ int temp = IN( rp.bc );
+ R8( data >> 3, 8 ) = temp;
+ flags = (flags & C01) | SZ28P( temp );
+ goto loop;
+ }
+
+ case 0x71: // OUT (C),0
+ rg.flags = 0;
+ CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r
+ OUT( rp.bc, R8( data >> 3, 8 ) );
+ goto loop;
+
+ {
+ unsigned temp;
+ case 0x73: // LD (ADDR),SP
+ temp = sp;
+ if ( 0 )
+ case 0x43: // LD (ADDR),BC
+ case 0x53: // LD (ADDR),DE
+ temp = R16( data, 4, 0x43 );
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ WRITE_WORD( addr, temp );
+ goto loop;
+ }
+
+ case 0x4B: // LD BC,(ADDR)
+ case 0x5B:{// LD DE,(ADDR)
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ R16( data, 4, 0x4B ) = READ_WORD( addr );
+ goto loop;
+ }
+
+ case 0x7B:{// LD SP,(ADDR)
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ sp = READ_WORD( addr );
+ goto loop;
+ }
+
+ case 0x67:{// RRD
+ fuint8 temp = READ( rp.hl );
+ WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
+ temp = (rg.a & 0xF0) | (temp & 0x0F);
+ flags = (flags & C01) | SZ28P( temp );
+ rg.a = temp;
+ goto loop;
+ }
+
+ case 0x6F:{// RLD
+ fuint8 temp = READ( rp.hl );
+ WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
+ temp = (rg.a & 0xF0) | (temp >> 4);
+ flags = (flags & C01) | SZ28P( temp );
+ rg.a = temp;
+ goto loop;
+ }
+
+ CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG
+ opcode = 0x10; // flag to do SBC instead of ADC
+ flags &= ~C01;
+ data = rg.a;
+ rg.a = 0;
+ goto adc_data;
+
+ {
+ int inc;
+ case 0xA9: // CPD
+ case 0xB9: // CPDR
+ inc = -1;
+ if ( 0 )
+ case 0xA1: // CPI
+ case 0xB1: // CPIR
+ inc = +1;
+ fuint16 addr = rp.hl;
+ rp.hl = addr + inc;
+ int temp = READ( addr );
+
+ int result = rg.a - temp;
+ flags = (flags & C01) | N02 |
+ ((((temp ^ rg.a) & H10) ^ result) & (S80 | H10));
+
+ if ( !(uint8_t) result ) flags |= Z40;
+ result -= (flags & H10) >> 4;
+ flags |= result & F08;
+ flags |= result << 4 & F20;
+ if ( !--rp.bc )
+ goto loop;
+
+ flags |= V04;
+ if ( flags & Z40 || data < 0xB0 )
+ goto loop;
+
+ pc -= 2;
+ s_time += 5;
+ goto loop;
+ }
+
+ {
+ int inc;
+ case 0xA8: // LDD
+ case 0xB8: // LDDR
+ inc = -1;
+ if ( 0 )
+ case 0xA0: // LDI
+ case 0xB0: // LDIR
+ inc = +1;
+ fuint16 addr = rp.hl;
+ rp.hl = addr + inc;
+ int temp = READ( addr );
+
+ addr = rp.de;
+ rp.de = addr + inc;
+ WRITE( addr, temp );
+
+ temp += rg.a;
+ flags = (flags & (S80 | Z40 | C01)) |
+ (temp & F08) | (temp << 4 & F20);
+ if ( !--rp.bc )
+ goto loop;
+
+ flags |= V04;
+ if ( data < 0xB0 )
+ goto loop;
+
+ pc -= 2;
+ s_time += 5;
+ goto loop;
+ }
+
+ {
+ int inc;
+ case 0xAB: // OUTD
+ case 0xBB: // OTDR
+ inc = -1;
+ if ( 0 )
+ case 0xA3: // OUTI
+ case 0xB3: // OTIR
+ inc = +1;
+ fuint16 addr = rp.hl;
+ rp.hl = addr + inc;
+ int temp = READ( addr );
+
+ int b = --rg.b;
+ flags = (temp >> 6 & N02) | SZ28( b );
+ if ( b && data >= 0xB0 )
+ {
+ pc -= 2;
+ s_time += 5;
+ }
+
+ OUT( rp.bc, temp );
+ goto loop;
+ }
+
+ {
+ int inc;
+ case 0xAA: // IND
+ case 0xBA: // INDR
+ inc = -1;
+ if ( 0 )
+ case 0xA2: // INI
+ case 0xB2: // INIR
+ inc = +1;
+
+ fuint16 addr = rp.hl;
+ rp.hl = addr + inc;
+
+ int temp = IN( rp.bc );
+
+ int b = --rg.b;
+ flags = (temp >> 6 & N02) | SZ28( b );
+ if ( b && data >= 0xB0 )
+ {
+ pc -= 2;
+ s_time += 5;
+ }
+
+ WRITE( addr, temp );
+ goto loop;
+ }
+
+ case 0x47: // LD I,A
+ r.i = rg.a;
+ goto loop;
+
+ case 0x4F: // LD R,A
+ SET_R( rg.a );
+ debug_printf( "LD R,A not supported\n" );
+ warning = true;
+ goto loop;
+
+ case 0x57: // LD A,I
+ rg.a = r.i;
+ goto ld_ai_common;
+
+ case 0x5F: // LD A,R
+ rg.a = GET_R();
+ debug_printf( "LD A,R not supported\n" );
+ warning = true;
+ ld_ai_common:
+ flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
+ goto loop;
+
+ CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN
+ r.iff1 = r.iff2;
+ goto ret_taken;
+
+ case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0
+ r.im = 0;
+ goto loop;
+
+ case 0x56: case 0x76: // IM 1
+ r.im = 1;
+ goto loop;
+
+ case 0x5E: case 0x7E: // IM 2
+ r.im = 2;
+ goto loop;
+
+ default:
+ debug_printf( "Opcode $ED $%02X not supported\n", data );
+ warning = true;
+ goto loop;
+ }
+ assert( false );
+ }
+
+//////////////////////////////////////// DD/FD prefix
+ {
+ fuint16 ixy;
+ case 0xDD:
+ ixy = ix;
+ goto ix_prefix;
+ case 0xFD:
+ ixy = iy;
+ ix_prefix:
+ pc++;
+ unsigned data2 = READ_PROG( pc );
+ s_time += ed_dd_timing [data] & 0x0F;
+ switch ( data )
+ {
+ // TODO: more efficient way of avoid negative address
+ #define IXY_DISP( ixy, disp ) uint16_t ((ixy) + (disp))
+
+ #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in;
+
+ // ADD/ADC/SUB/SBC
+
+ case 0x96: // SUB (IXY+disp)
+ case 0x86: // ADD (IXY+disp)
+ flags &= ~C01;
+ case 0x9E: // SBC (IXY+disp)
+ case 0x8E: // ADC (IXY+disp)
+ pc++;
+ opcode = data;
+ data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
+ goto adc_data;
+
+ case 0x94: // SUB HXY
+ case 0x84: // ADD HXY
+ flags &= ~C01;
+ case 0x9C: // SBC HXY
+ case 0x8C: // ADC HXY
+ opcode = data;
+ data = ixy >> 8;
+ goto adc_data;
+
+ case 0x95: // SUB LXY
+ case 0x85: // ADD LXY
+ flags &= ~C01;
+ case 0x9D: // SBC LXY
+ case 0x8D: // ADC LXY
+ opcode = data;
+ data = (uint8_t) ixy;
+ goto adc_data;
+
+ {
+ unsigned temp;
+ case 0x39: // ADD IXY,SP
+ temp = sp;
+ goto add_ixy_data;
+
+ case 0x29: // ADD IXY,HL
+ temp = ixy;
+ goto add_ixy_data;
+
+ case 0x09: // ADD IXY,BC
+ case 0x19: // ADD IXY,DE
+ temp = R16( data, 4, 0x09 );
+ add_ixy_data: {
+ blargg_ulong sum = ixy + temp;
+ temp ^= ixy;
+ ixy = (uint16_t) sum;
+ flags = (flags & (S80 | Z40 | V04)) |
+ (sum >> 16) |
+ (sum >> 8 & (F20 | F08)) |
+ ((temp ^ sum) >> 8 & H10);
+ goto set_ixy;
+ }
+ }
+
+ // AND
+ case 0xA6: // AND (IXY+disp)
+ pc++;
+ data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
+ goto and_data;
+
+ case 0xA4: // AND HXY
+ data = ixy >> 8;
+ goto and_data;
+
+ case 0xA5: // AND LXY
+ data = (uint8_t) ixy;
+ goto and_data;
+
+ // OR
+ case 0xB6: // OR (IXY+disp)
+ pc++;
+ data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
+ goto or_data;
+
+ case 0xB4: // OR HXY
+ data = ixy >> 8;
+ goto or_data;
+
+ case 0xB5: // OR LXY
+ data = (uint8_t) ixy;
+ goto or_data;
+
+ // XOR
+ case 0xAE: // XOR (IXY+disp)
+ pc++;
+ data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
+ goto xor_data;
+
+ case 0xAC: // XOR HXY
+ data = ixy >> 8;
+ goto xor_data;
+
+ case 0xAD: // XOR LXY
+ data = (uint8_t) ixy;
+ goto xor_data;
+
+ // CP
+ case 0xBE: // CP (IXY+disp)
+ pc++;
+ data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
+ goto cp_data;
+
+ case 0xBC: // CP HXY
+ data = ixy >> 8;
+ goto cp_data;
+
+ case 0xBD: // CP LXY
+ data = (uint8_t) ixy;
+ goto cp_data;
+
+ // LD
+ CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r
+ data = R8( data, 0x70 );
+ if ( 0 )
+ case 0x36: // LD (IXY+disp),imm
+ pc++, data = READ_PROG( pc );
+ pc++;
+ WRITE( IXY_DISP( ixy, (int8_t) data2 ), data );
+ goto loop;
+
+ CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY
+ R8( data >> 3, 8 ) = ixy >> 8;
+ goto loop;
+
+ case 0x64: // LD HXY,HXY
+ case 0x6D: // LD LXY,LXY
+ goto loop;
+
+ CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY
+ R8( data >> 3, 8 ) = ixy;
+ goto loop;
+
+ CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp)
+ pc++;
+ R8( data >> 3, 8 ) = READ( IXY_DISP( ixy, (int8_t) data2 ) );
+ goto loop;
+
+ case 0x26: // LD HXY,imm
+ pc++;
+ goto ld_hxy_data;
+
+ case 0x65: // LD HXY,LXY
+ data2 = (uint8_t) ixy;
+ goto ld_hxy_data;
+
+ CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r
+ data2 = R8( data, 0x60 );
+ ld_hxy_data:
+ ixy = (uint8_t) ixy | (data2 << 8);
+ goto set_ixy;
+
+ case 0x2E: // LD LXY,imm
+ pc++;
+ goto ld_lxy_data;
+
+ case 0x6C: // LD LXY,HXY
+ data2 = ixy >> 8;
+ goto ld_lxy_data;
+
+ CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r
+ data2 = R8( data, 0x68 );
+ ld_lxy_data:
+ ixy = (ixy & 0xFF00) | data2;
+ set_ixy:
+ if ( opcode == 0xDD )
+ {
+ ix = ixy;
+ goto loop;
+ }
+ iy = ixy;
+ goto loop;
+
+ case 0xF9: // LD SP,IXY
+ sp = ixy;
+ goto loop;
+
+ case 0x22:{// LD (ADDR),IXY
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ WRITE_WORD( addr, ixy );
+ goto loop;
+ }
+
+ case 0x21: // LD IXY,imm
+ ixy = GET_ADDR();
+ pc += 2;
+ goto set_ixy;
+
+ case 0x2A:{// LD IXY,(addr)
+ fuint16 addr = GET_ADDR();
+ ixy = READ_WORD( addr );
+ pc += 2;
+ goto set_ixy;
+ }
+
+ // DD/FD CB prefix
+ case 0xCB: {
+ data = IXY_DISP( ixy, (int8_t) data2 );
+ pc++;
+ data2 = READ_PROG( pc );
+ pc++;
+ switch ( data2 )
+ {
+ case 0x06: goto rlc_data_addr; // RLC (IXY)
+ case 0x16: goto rl_data_addr; // RL (IXY)
+ case 0x26: goto sla_data_addr; // SLA (IXY)
+ case 0x36: goto sll_data_addr; // SLL (IXY)
+ case 0x0E: goto rrc_data_addr; // RRC (IXY)
+ case 0x1E: goto rr_data_addr; // RR (IXY)
+ case 0x2E: goto sra_data_addr; // SRA (IXY)
+ case 0x3E: goto srl_data_addr; // SRL (IXY)
+
+ CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
+ fuint8 temp = READ( data );
+ int masked = temp & 1 << (data2 >> 3 & 7);
+ flags = (flags & C01) | H10 |
+ (masked & S80) |
+ ((masked - 1) >> 8 & (Z40 | P04));
+ goto loop;
+ }
+
+ CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp)
+ CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp)
+ int temp = READ( data );
+ int bit = 1 << (data2 >> 3 & 7);
+ temp |= bit; // SET
+ if ( !(data2 & 0x40) )
+ temp ^= bit; // RES
+ WRITE( data, temp );
+ goto loop;
+ }
+
+ default:
+ debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
+ warning = true;
+ goto loop;
+ }
+ assert( false );
+ }
+
+ // INC/DEC
+ case 0x23: // INC IXY
+ ixy = uint16_t (ixy + 1);
+ goto set_ixy;
+
+ case 0x2B: // DEC IXY
+ ixy = uint16_t (ixy - 1);
+ goto set_ixy;
+
+ case 0x34: // INC (IXY+disp)
+ ixy = IXY_DISP( ixy, (int8_t) data2 );
+ pc++;
+ data = READ( ixy ) + 1;
+ WRITE( ixy, data );
+ goto inc_set_flags;
+
+ case 0x35: // DEC (IXY+disp)
+ ixy = IXY_DISP( ixy, (int8_t) data2 );
+ pc++;
+ data = READ( ixy ) - 1;
+ WRITE( ixy, data );
+ goto dec_set_flags;
+
+ case 0x24: // INC HXY
+ ixy = uint16_t (ixy + 0x100);
+ data = ixy >> 8;
+ goto inc_xy_common;
+
+ case 0x2C: // INC LXY
+ data = uint8_t (ixy + 1);
+ ixy = (ixy & 0xFF00) | data;
+ inc_xy_common:
+ if ( opcode == 0xDD )
+ {
+ ix = ixy;
+ goto inc_set_flags;
+ }
+ iy = ixy;
+ goto inc_set_flags;
+
+ case 0x25: // DEC HXY
+ ixy = uint16_t (ixy - 0x100);
+ data = ixy >> 8;
+ goto dec_xy_common;
+
+ case 0x2D: // DEC LXY
+ data = uint8_t (ixy - 1);
+ ixy = (ixy & 0xFF00) | data;
+ dec_xy_common:
+ if ( opcode == 0xDD )
+ {
+ ix = ixy;
+ goto dec_set_flags;
+ }
+ iy = ixy;
+ goto dec_set_flags;
+
+ // PUSH/POP
+ case 0xE5: // PUSH IXY
+ data = ixy;
+ goto push_data;
+
+ case 0xE1:{// POP IXY
+ ixy = READ_WORD( sp );
+ sp = uint16_t (sp + 2);
+ goto set_ixy;
+ }
+
+ // Misc
+
+ case 0xE9: // JP (IXY)
+ pc = ixy;
+ goto loop;
+
+ case 0xE3:{// EX (SP),IXY
+ fuint16 temp = READ_WORD( sp );
+ WRITE_WORD( sp, ixy );
+ ixy = temp;
+ goto set_ixy;
+ }
+
+ default:
+ debug_printf( "Unnecessary DD/FD prefix encountered\n" );
+ warning = true;
+ pc--;
+ goto loop;
+ }
+ assert( false );
+ }
+
+ }
+ debug_printf( "Unhandled main opcode: $%02X\n", opcode );
+ assert( false );
+
+halt:
+ s_time &= 3; // increment by multiple of 4
+out_of_time:
+ pc--;
+
+ s.time = s_time;
+ rg.flags = flags;
+ r.ix = ix;
+ r.iy = iy;
+ r.sp = sp;
+ r.pc = pc;
+ this->r.b = rg;
+ this->state_ = s;
+ this->state = &this->state_;
+
+ return warning;
+}
diff --git a/src/console/Ay_Cpu.cxx b/src/console/Ay_Cpu.cxx
deleted file mode 100644
index bee9eedf7e56..000000000000
--- a/src/console/Ay_Cpu.cxx
+++ /dev/null
@@ -1,1661 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-/*
-Last validated with zexall 2006.11.21 5:26 PM
-* Doesn't implement the R register or immediate interrupt after EI.
-* Address wrap-around isn't completely correct, but is prevented from crashing emulator.
-*/
-
-#include "Ay_Cpu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-//#include "z80_cpu_log.h"
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#define SYNC_TIME() (void) (s.time = s_time)
-#define RELOAD_TIME() (void) (s_time = s.time)
-
-// Callbacks to emulator
-
-#define CPU_OUT( cpu, addr, data, TIME )\
- ay_cpu_out( cpu, TIME, addr, data )
-
-#define CPU_IN( cpu, addr, TIME )\
- ay_cpu_in( cpu, addr )
-
-#include "blargg_source.h"
-
-// flags, named with hex value for clarity
-int const S80 = 0x80;
-int const Z40 = 0x40;
-int const F20 = 0x20;
-int const H10 = 0x10;
-int const F08 = 0x08;
-int const V04 = 0x04;
-int const P04 = 0x04;
-int const N02 = 0x02;
-int const C01 = 0x01;
-
-#define SZ28P( n ) szpc [n]
-#define SZ28PC( n ) szpc [n]
-#define SZ28C( n ) (szpc [n] & ~P04)
-#define SZ28( n ) SZ28C( n )
-
-#define SET_R( n ) (void) (r.r = n)
-#define GET_R() (r.r)
-
-Ay_Cpu::Ay_Cpu()
-{
- state = &state_;
- for ( int i = 0x100; --i >= 0; )
- {
- int even = 1;
- for ( int p = i; p; p >>= 1 )
- even ^= p;
- int n = (i & (S80 | F20 | F08)) | ((even & 1) * P04);
- szpc [i] = n;
- szpc [i + 0x100] = n | C01;
- }
- szpc [0x000] |= Z40;
- szpc [0x100] |= Z40;
-}
-
-void Ay_Cpu::reset( void* m )
-{
- mem = (uint8_t*) m;
-
- check( state == &state_ );
- state = &state_;
- state_.time = 0;
- state_.base = 0;
- end_time_ = 0;
-
- memset( &r, 0, sizeof r );
-}
-
-#define TIME (s_time + s.base)
-#define READ_PROG( addr ) (mem [addr])
-#define INSTR( offset ) READ_PROG( pc + (offset) )
-#define GET_ADDR() GET_LE16( &READ_PROG( pc ) )
-#define READ( addr ) READ_PROG( addr )
-#define WRITE( addr, data ) (void) (READ_PROG( addr ) = data)
-#define READ_WORD( addr ) GET_LE16( &READ_PROG( addr ) )
-#define WRITE_WORD( addr, data ) SET_LE16( &READ_PROG( addr ), data )
-#define IN( addr ) CPU_IN( this, addr, TIME )
-#define OUT( addr, data ) CPU_OUT( this, addr, data, TIME )
-
-#if BLARGG_BIG_ENDIAN
- #define R8( n, offset ) ((r8_ - offset) [n])
-#elif BLARGG_LITTLE_ENDIAN
- #define R8( n, offset ) ((r8_ - offset) [(n) ^ 1])
-#else
- #error "Byte order of CPU must be known"
-#endif
-
-//#define R16( n, shift, offset ) (r16_ [((n) >> shift) - (offset >> shift)])
-
-// help compiler see that it can just adjust stack offset, saving an extra instruction
-#define R16( n, shift, offset )\
- (*(uint16_t*) ((char*) r16_ - (offset >> (shift - 1)) + ((n) >> (shift - 1))))
-
-#define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e
-#define CASE6( a, b, c, d, e, f ) CASE5( a, b, c, d, e ): case 0x##f
-#define CASE7( a, b, c, d, e, f, g ) CASE6( a, b, c, d, e, f ): case 0x##g
-#define CASE8( a, b, c, d, e, f, g, h ) CASE7( a, b, c, d, e, f, g ): case 0x##h
-
-// high four bits are $ED time - 8, low four bits are $DD/$FD time - 8
-static byte const ed_dd_timing [0x100] = {
-//0 1 2 3 4 5 6 7 8 9 A B C D E F
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x06,0x0C,0x02,0x00,0x00,0x03,0x00,0x00,0x07,0x0C,0x02,0x00,0x00,0x03,0x00,
-0x00,0x00,0x00,0x00,0x0F,0x0F,0x0B,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,
-0x4B,0x4B,0x7B,0xCB,0x0B,0x6B,0x00,0x0B,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
-0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,
-0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x06,0x00,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-
-bool Ay_Cpu::run( cpu_time_t end_time )
-{
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- bool warning = false;
-
- union {
- regs_t rg;
- pairs_t rp;
- uint8_t r8_ [8]; // indexed
- uint16_t r16_ [4];
- };
- rg = this->r.b;
-
- cpu_time_t s_time = s.time;
- uint8_t* const mem = this->mem; // cache
- fuint16 pc = r.pc;
- fuint16 sp = r.sp;
- fuint16 ix = r.ix; // TODO: keep in memory for direct access?
- fuint16 iy = r.iy;
- int flags = r.b.flags;
-
- goto loop;
-jr_not_taken:
- s_time -= 5;
- goto loop;
-call_not_taken:
- s_time -= 7;
-jp_not_taken:
- pc += 2;
-loop:
-
- check( (unsigned long) pc < 0x10000 );
- check( (unsigned long) sp < 0x10000 );
- check( (unsigned) flags < 0x100 );
- check( (unsigned) ix < 0x10000 );
- check( (unsigned) iy < 0x10000 );
-
- fuint8 opcode;
- opcode = READ_PROG( pc );
- pc++;
-
- static byte const base_timing [0x100] = {
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 0
- 13,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, // 1
- 12,10,16, 6, 4, 4, 7, 4,12,11,16, 6, 4, 4, 7, 4, // 2
- 12,10,13, 6,11,11,10, 4,12,11,13, 6, 4, 4, 7, 4, // 3
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 4
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 5
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 6
- 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 7
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 8
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 9
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // A
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // B
- 11,10,10,10,17,11, 7,11,11,10,10, 8,17,17, 7,11, // C
- 11,10,10,11,17,11, 7,11,11, 4,10,11,17, 8, 7,11, // D
- 11,10,10,19,17,11, 7,11,11, 4,10, 4,17, 8, 7,11, // E
- 11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F
- };
-
- fuint16 data;
- data = base_timing [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = READ_PROG( pc );
-
- #ifdef Z80_CPU_LOG_H
- //log_opcode( opcode, READ_PROG( pc ) );
- z80_log_regs( rg.a, rp.bc, rp.de, rp.hl, sp, ix, iy );
- z80_cpu_log( "new", pc - 1, opcode, READ_PROG( pc ),
- READ_PROG( pc + 1 ), READ_PROG( pc + 2 ) );
- #endif
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-
-// Common
-
- case 0x00: // NOP
- CASE7( 40, 49, 52, 5B, 64, 6D, 7F ): // LD B,B etc.
- goto loop;
-
- case 0x08:{// EX AF,AF'
- int temp = r.alt.b.a;
- r.alt.b.a = rg.a;
- rg.a = temp;
-
- temp = r.alt.b.flags;
- r.alt.b.flags = flags;
- flags = temp;
- goto loop;
- }
-
- case 0xD3: // OUT (imm),A
- pc++;
- OUT( data + rg.a * 0x100, rg.a );
- goto loop;
-
- case 0x2E: // LD L,imm
- pc++;
- rg.l = data;
- goto loop;
-
- case 0x3E: // LD A,imm
- pc++;
- rg.a = data;
- goto loop;
-
- case 0x3A:{// LD A,(addr)
- fuint16 addr = GET_ADDR();
- pc += 2;
- rg.a = READ( addr );
- goto loop;
- }
-
-// Conditional
-
-#define ZERO (flags & Z40)
-#define CARRY (flags & C01)
-#define EVEN (flags & P04)
-#define MINUS (flags & S80)
-
-// JR
-#define JR( cond ) {\
- int disp = (int8_t) data;\
- pc++;\
- if ( !(cond) )\
- goto jr_not_taken;\
- pc += disp;\
- goto loop;\
-}
-
- case 0x20: JR( !ZERO ) // JR NZ,disp
- case 0x28: JR( ZERO ) // JR Z,disp
- case 0x30: JR( !CARRY ) // JR NC,disp
- case 0x38: JR( CARRY ) // JR C,disp
- case 0x18: JR( true ) // JR disp
-
- case 0x10:{// DJNZ disp
- int temp = rg.b - 1;
- rg.b = temp;
- JR( temp )
- }
-
-// JP
-#define JP( cond ) if ( !(cond) ) goto jp_not_taken; pc = GET_ADDR(); goto loop;
-
- case 0xC2: JP( !ZERO ) // JP NZ,addr
- case 0xCA: JP( ZERO ) // JP Z,addr
- case 0xD2: JP( !CARRY ) // JP NC,addr
- case 0xDA: JP( CARRY ) // JP C,addr
- case 0xE2: JP( !EVEN ) // JP PO,addr
- case 0xEA: JP( EVEN ) // JP PE,addr
- case 0xF2: JP( !MINUS ) // JP P,addr
- case 0xFA: JP( MINUS ) // JP M,addr
-
- case 0xC3: // JP addr
- pc = GET_ADDR();
- goto loop;
-
- case 0xE9: // JP HL
- pc = rp.hl;
- goto loop;
-
-// RET
-#define RET( cond ) if ( cond ) goto ret_taken; s_time -= 6; goto loop;
-
- case 0xC0: RET( !ZERO ) // RET NZ
- case 0xC8: RET( ZERO ) // RET Z
- case 0xD0: RET( !CARRY ) // RET NC
- case 0xD8: RET( CARRY ) // RET C
- case 0xE0: RET( !EVEN ) // RET PO
- case 0xE8: RET( EVEN ) // RET PE
- case 0xF0: RET( !MINUS ) // RET P
- case 0xF8: RET( MINUS ) // RET M
-
- case 0xC9: // RET
- ret_taken:
- pc = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto loop;
-
-// CALL
-#define CALL( cond ) if ( cond ) goto call_taken; goto call_not_taken;
-
- case 0xC4: CALL( !ZERO ) // CALL NZ,addr
- case 0xCC: CALL( ZERO ) // CALL Z,addr
- case 0xD4: CALL( !CARRY ) // CALL NC,addr
- case 0xDC: CALL( CARRY ) // CALL C,addr
- case 0xE4: CALL( !EVEN ) // CALL PO,addr
- case 0xEC: CALL( EVEN ) // CALL PE,addr
- case 0xF4: CALL( !MINUS ) // CALL P,addr
- case 0xFC: CALL( MINUS ) // CALL M,addr
-
- case 0xCD:{// CALL addr
- call_taken:
- fuint16 addr = pc + 2;
- pc = GET_ADDR();
- sp = uint16_t (sp - 2);
- WRITE_WORD( sp, addr );
- goto loop;
- }
-
- case 0xFF: // RST
- if ( (pc - 1) > 0xFFFF )
- {
- pc = uint16_t (pc - 1);
- s_time -= 11;
- goto loop;
- }
- CASE7( C7, CF, D7, DF, E7, EF, F7 ):
- data = pc;
- pc = opcode & 0x38;
- goto push_data;
-
-// PUSH/POP
- case 0xF5: // PUSH AF
- data = rg.a * 0x100u + flags;
- goto push_data;
-
- case 0xC5: // PUSH BC
- case 0xD5: // PUSH DE
- case 0xE5: // PUSH HL
- data = R16( opcode, 4, 0xC5 );
- push_data:
- sp = uint16_t (sp - 2);
- WRITE_WORD( sp, data );
- goto loop;
-
- case 0xF1: // POP AF
- flags = READ( sp );
- rg.a = READ( sp + 1 );
- sp = uint16_t (sp + 2);
- goto loop;
-
- case 0xC1: // POP BC
- case 0xD1: // POP DE
- case 0xE1: // POP HL
- R16( opcode, 4, 0xC1 ) = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto loop;
-
-// ADC/ADD/SBC/SUB
- case 0x96: // SUB (HL)
- case 0x86: // ADD (HL)
- flags &= ~C01;
- case 0x9E: // SBC (HL)
- case 0x8E: // ADC (HL)
- data = READ( rp.hl );
- goto adc_data;
-
- case 0xD6: // SUB A,imm
- case 0xC6: // ADD imm
- flags &= ~C01;
- case 0xDE: // SBC A,imm
- case 0xCE: // ADC imm
- pc++;
- goto adc_data;
-
- CASE7( 90, 91, 92, 93, 94, 95, 97 ): // SUB r
- CASE7( 80, 81, 82, 83, 84, 85, 87 ): // ADD r
- flags &= ~C01;
- CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // SBC r
- CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // ADC r
- data = R8( opcode & 7, 0 );
- adc_data: {
- int result = data + (flags & C01);
- data ^= rg.a;
- flags = opcode >> 3 & N02; // bit 4 is set in subtract opcodes
- if ( flags )
- result = -result;
- result += rg.a;
- data ^= result;
- flags |=(data & H10) |
- ((data - -0x80) >> 6 & V04) |
- SZ28C( result & 0x1FF );
- rg.a = result;
- goto loop;
- }
-
-// CP
- case 0xBE: // CP (HL)
- data = READ( rp.hl );
- goto cp_data;
-
- case 0xFE: // CP imm
- pc++;
- goto cp_data;
-
- CASE7( B8, B9, BA, BB, BC, BD, BF ): // CP r
- data = R8( opcode, 0xB8 );
- cp_data: {
- int result = rg.a - data;
- flags = N02 | (data & (F20 | F08)) | (result >> 8 & C01);
- data ^= rg.a;
- flags |=(((result ^ rg.a) & data) >> 5 & V04) |
- (((data & H10) ^ result) & (S80 | H10));
- if ( (uint8_t) result )
- goto loop;
- flags |= Z40;
- goto loop;
- }
-
-// ADD HL,rp
-
- case 0x39: // ADD HL,SP
- data = sp;
- goto add_hl_data;
-
- case 0x09: // ADD HL,BC
- case 0x19: // ADD HL,DE
- case 0x29: // ADD HL,HL
- data = R16( opcode, 4, 0x09 );
- add_hl_data: {
- blargg_ulong sum = rp.hl + data;
- data ^= rp.hl;
- rp.hl = sum;
- flags = (flags & (S80 | Z40 | V04)) |
- (sum >> 16) |
- (sum >> 8 & (F20 | F08)) |
- ((data ^ sum) >> 8 & H10);
- goto loop;
- }
-
- case 0x27:{// DAA
- int a = rg.a;
- if ( a > 0x99 )
- flags |= C01;
-
- int adjust = 0x60 & -(flags & C01);
-
- if ( flags & H10 || (a & 0x0F) > 9 )
- adjust |= 0x06;
-
- if ( flags & N02 )
- adjust = -adjust;
- a += adjust;
-
- flags = (flags & (C01 | N02)) |
- ((rg.a ^ a) & H10) |
- SZ28P( (uint8_t) a );
- rg.a = a;
- goto loop;
- }
- /*
- case 0x27:{// DAA
- // more optimized, but probably not worth the obscurity
- int f = (rg.a + (0xFF - 0x99)) >> 8 | flags; // (a > 0x99 ? C01 : 0) | flags
- int adjust = 0x60 & -(f & C01); // f & C01 ? 0x60 : 0
-
- if ( (((rg.a + (0x0F - 9)) ^ rg.a) | f) & H10 ) // flags & H10 || (rg.a & 0x0F) > 9
- adjust |= 0x06;
-
- if ( f & N02 )
- adjust = -adjust;
- int a = rg.a + adjust;
-
- flags = (f & (N02 | C01)) | ((rg.a ^ a) & H10) | SZ28P( (uint8_t) a );
- rg.a = a;
- goto loop;
- }
- */
-
-// INC/DEC
- case 0x34: // INC (HL)
- data = READ( rp.hl ) + 1;
- WRITE( rp.hl, data );
- goto inc_set_flags;
-
- CASE7( 04, 0C, 14, 1C, 24, 2C, 3C ): // INC r
- data = ++R8( opcode >> 3, 0 );
- inc_set_flags:
- flags = (flags & C01) |
- (((data & 0x0F) - 1) & H10) |
- SZ28( (uint8_t) data );
- if ( data != 0x80 )
- goto loop;
- flags |= V04;
- goto loop;
-
- case 0x35: // DEC (HL)
- data = READ( rp.hl ) - 1;
- WRITE( rp.hl, data );
- goto dec_set_flags;
-
- CASE7( 05, 0D, 15, 1D, 25, 2D, 3D ): // DEC r
- data = --R8( opcode >> 3, 0 );
- dec_set_flags:
- flags = (flags & C01) | N02 |
- (((data & 0x0F) + 1) & H10) |
- SZ28( (uint8_t) data );
- if ( data != 0x7F )
- goto loop;
- flags |= V04;
- goto loop;
-
- case 0x03: // INC BC
- case 0x13: // INC DE
- case 0x23: // INC HL
- R16( opcode, 4, 0x03 )++;
- goto loop;
-
- case 0x33: // INC SP
- sp = uint16_t (sp + 1);
- goto loop;
-
- case 0x0B: // DEC BC
- case 0x1B: // DEC DE
- case 0x2B: // DEC HL
- R16( opcode, 4, 0x0B )--;
- goto loop;
-
- case 0x3B: // DEC SP
- sp = uint16_t (sp - 1);
- goto loop;
-
-// AND
- case 0xA6: // AND (HL)
- data = READ( rp.hl );
- goto and_data;
-
- case 0xE6: // AND imm
- pc++;
- goto and_data;
-
- CASE7( A0, A1, A2, A3, A4, A5, A7 ): // AND r
- data = R8( opcode, 0xA0 );
- and_data:
- rg.a &= data;
- flags = SZ28P( rg.a ) | H10;
- goto loop;
-
-// OR
- case 0xB6: // OR (HL)
- data = READ( rp.hl );
- goto or_data;
-
- case 0xF6: // OR imm
- pc++;
- goto or_data;
-
- CASE7( B0, B1, B2, B3, B4, B5, B7 ): // OR r
- data = R8( opcode, 0xB0 );
- or_data:
- rg.a |= data;
- flags = SZ28P( rg.a );
- goto loop;
-
-// XOR
- case 0xAE: // XOR (HL)
- data = READ( rp.hl );
- goto xor_data;
-
- case 0xEE: // XOR imm
- pc++;
- goto xor_data;
-
- CASE7( A8, A9, AA, AB, AC, AD, AF ): // XOR r
- data = R8( opcode, 0xA8 );
- xor_data:
- rg.a ^= data;
- flags = SZ28P( rg.a );
- goto loop;
-
-// LD
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (HL),r
- WRITE( rp.hl, R8( opcode, 0x70 ) );
- goto loop;
-
- CASE6( 41, 42, 43, 44, 45, 47 ): // LD B,r
- CASE6( 48, 4A, 4B, 4C, 4D, 4F ): // LD C,r
- CASE6( 50, 51, 53, 54, 55, 57 ): // LD D,r
- CASE6( 58, 59, 5A, 5C, 5D, 5F ): // LD E,r
- CASE6( 60, 61, 62, 63, 65, 67 ): // LD H,r
- CASE6( 68, 69, 6A, 6B, 6C, 6F ): // LD L,r
- CASE6( 78, 79, 7A, 7B, 7C, 7D ): // LD A,r
- R8( opcode >> 3 & 7, 0 ) = R8( opcode & 7, 0 );
- goto loop;
-
- CASE5( 06, 0E, 16, 1E, 26 ): // LD r,imm
- R8( opcode >> 3, 0 ) = data;
- pc++;
- goto loop;
-
- case 0x36: // LD (HL),imm
- pc++;
- WRITE( rp.hl, data );
- goto loop;
-
- CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(HL)
- R8( opcode >> 3, 8 ) = READ( rp.hl );
- goto loop;
-
- case 0x01: // LD rp,imm
- case 0x11:
- case 0x21:
- R16( opcode, 4, 0x01 ) = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x31: // LD sp,imm
- sp = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x2A:{// LD HL,(addr)
- fuint16 addr = GET_ADDR();
- pc += 2;
- rp.hl = READ_WORD( addr );
- goto loop;
- }
-
- case 0x32:{// LD (addr),A
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE( addr, rg.a );
- goto loop;
- }
-
- case 0x22:{// LD (addr),HL
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, rp.hl );
- goto loop;
- }
-
- case 0x02: // LD (BC),A
- case 0x12: // LD (DE),A
- WRITE( R16( opcode, 4, 0x02 ), rg.a );
- goto loop;
-
- case 0x0A: // LD A,(BC)
- case 0x1A: // LD A,(DE)
- rg.a = READ( R16( opcode, 4, 0x0A ) );
- goto loop;
-
- case 0xF9: // LD SP,HL
- sp = rp.hl;
- goto loop;
-
-// Rotate
-
- case 0x07:{// RLCA
- fuint16 temp = rg.a;
- temp = (temp << 1) | (temp >> 7);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08 | C01));
- rg.a = temp;
- goto loop;
- }
-
- case 0x0F:{// RRCA
- fuint16 temp = rg.a;
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & C01);
- temp = (temp << 7) | (temp >> 1);
- flags |= temp & (F20 | F08);
- rg.a = temp;
- goto loop;
- }
-
- case 0x17:{// RLA
- blargg_ulong temp = (rg.a << 1) | (flags & C01);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08)) |
- (temp >> 8);
- rg.a = temp;
- goto loop;
- }
-
- case 0x1F:{// RRA
- fuint16 temp = (flags << 7) | (rg.a >> 1);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08)) |
- (rg.a & C01);
- rg.a = temp;
- goto loop;
- }
-
-// Misc
- case 0x2F:{// CPL
- fuint16 temp = ~rg.a;
- flags = (flags & (S80 | Z40 | P04 | C01)) |
- (temp & (F20 | F08)) |
- (H10 | N02);
- rg.a = temp;
- goto loop;
- }
-
- case 0x3F:{// CCF
- flags = ((flags & (S80 | Z40 | P04 | C01)) ^ C01) |
- (flags << 4 & H10) |
- (rg.a & (F20 | F08));
- goto loop;
- }
-
- case 0x37: // SCF
- flags = (flags & (S80 | Z40 | P04)) | C01 |
- (rg.a & (F20 | F08));
- goto loop;
-
- case 0xDB: // IN A,(imm)
- pc++;
- rg.a = IN( data + rg.a * 0x100 );
- goto loop;
-
- case 0xE3:{// EX (SP),HL
- fuint16 temp = READ_WORD( sp );
- WRITE_WORD( sp, rp.hl );
- rp.hl = temp;
- goto loop;
- }
-
- case 0xEB:{// EX DE,HL
- fuint16 temp = rp.hl;
- rp.hl = rp.de;
- rp.de = temp;
- goto loop;
- }
-
- case 0xD9:{// EXX DE,HL
- fuint16 temp = r.alt.w.bc;
- r.alt.w.bc = rp.bc;
- rp.bc = temp;
-
- temp = r.alt.w.de;
- r.alt.w.de = rp.de;
- rp.de = temp;
-
- temp = r.alt.w.hl;
- r.alt.w.hl = rp.hl;
- rp.hl = temp;
- goto loop;
- }
-
- case 0xF3: // DI
- r.iff1 = 0;
- r.iff2 = 0;
- goto loop;
-
- case 0xFB: // EI
- r.iff1 = 1;
- r.iff2 = 1;
- // TODO: delayed effect
- goto loop;
-
- case 0x76: // HALT
- goto halt;
-
-//////////////////////////////////////// CB prefix
- {
- case 0xCB:
- pc++;
- switch ( data )
- {
-
- // Rotate left
-
- #define RLC( read, write ) {\
- fuint8 result = read;\
- result = uint8_t (result << 1) | (result >> 7);\
- flags = SZ28P( result ) | (result & C01);\
- write;\
- goto loop;\
- }
-
- case 0x06: // RLC (HL)
- s_time += 7;
- data = rp.hl;
- rlc_data_addr:
- RLC( READ( data ), WRITE( data, result ) )
-
- CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r
- uint8_t& reg = R8( data, 0 );
- RLC( reg, reg = result )
- }
-
- #define RL( read, write ) {\
- fuint16 result = (read << 1) | (flags & C01);\
- flags = SZ28PC( result );\
- write;\
- goto loop;\
- }
-
- case 0x16: // RL (HL)
- s_time += 7;
- data = rp.hl;
- rl_data_addr:
- RL( READ( data ), WRITE( data, result ) )
-
- CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r
- uint8_t& reg = R8( data, 0x10 );
- RL( reg, reg = result )
- }
-
- #define SLA( read, add, write ) {\
- fuint16 result = (read << 1) | add;\
- flags = SZ28PC( result );\
- write;\
- goto loop;\
- }
-
- case 0x26: // SLA (HL)
- s_time += 7;
- data = rp.hl;
- sla_data_addr:
- SLA( READ( data ), 0, WRITE( data, result ) )
-
- CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r
- uint8_t& reg = R8( data, 0x20 );
- SLA( reg, 0, reg = result )
- }
-
- case 0x36: // SLL (HL)
- s_time += 7;
- data = rp.hl;
- sll_data_addr:
- SLA( READ( data ), 1, WRITE( data, result ) )
-
- CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r
- uint8_t& reg = R8( data, 0x30 );
- SLA( reg, 1, reg = result )
- }
-
- // Rotate right
-
- #define RRC( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result = uint8_t (result << 7) | (result >> 1);\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x0E: // RRC (HL)
- s_time += 7;
- data = rp.hl;
- rrc_data_addr:
- RRC( READ( data ), WRITE( data, result ) )
-
- CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r
- uint8_t& reg = R8( data, 0x08 );
- RRC( reg, reg = result )
- }
-
- #define RR( read, write ) {\
- fuint8 result = read;\
- fuint8 temp = result & C01;\
- result = uint8_t (flags << 7) | (result >> 1);\
- flags = SZ28P( result ) | temp;\
- write;\
- goto loop;\
- }
-
- case 0x1E: // RR (HL)
- s_time += 7;
- data = rp.hl;
- rr_data_addr:
- RR( READ( data ), WRITE( data, result ) )
-
- CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r
- uint8_t& reg = R8( data, 0x18 );
- RR( reg, reg = result )
- }
-
- #define SRA( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result = (result & 0x80) | (result >> 1);\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x2E: // SRA (HL)
- data = rp.hl;
- s_time += 7;
- sra_data_addr:
- SRA( READ( data ), WRITE( data, result ) )
-
- CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r
- uint8_t& reg = R8( data, 0x28 );
- SRA( reg, reg = result )
- }
-
- #define SRL( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result >>= 1;\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x3E: // SRL (HL)
- s_time += 7;
- data = rp.hl;
- srl_data_addr:
- SRL( READ( data ), WRITE( data, result ) )
-
- CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r
- uint8_t& reg = R8( data, 0x38 );
- SRL( reg, reg = result )
- }
-
- // BIT
- {
- unsigned temp;
- CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL)
- s_time += 4;
- temp = READ( rp.hl );
- flags &= C01;
- goto bit_temp;
- CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r
- CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r
- CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r
- CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r
- CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r
- CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r
- CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r
- temp = R8( data & 7, 0 );
- flags = (flags & C01) | (temp & (F20 | F08));
- bit_temp:
- int masked = temp & 1 << (data >> 3 & 7);
- flags |=(masked & S80) | H10 |
- ((masked - 1) >> 8 & (Z40 | P04));
- goto loop;
- }
-
- // SET/RES
- CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL)
- CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL)
- s_time += 7;
- int temp = READ( rp.hl );
- int bit = 1 << (data >> 3 & 7);
- temp |= bit; // SET
- if ( !(data & 0x40) )
- temp ^= bit; // RES
- WRITE( rp.hl, temp );
- goto loop;
- }
-
- CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r
- CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r
- CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r
- CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r
- CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r
- CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r
- CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r
- CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r
- R8( data & 7, 0 ) |= 1 << (data >> 3 & 7);
- goto loop;
-
- CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r
- CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r
- CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r
- CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r
- CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r
- CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r
- CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r
- CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r
- R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7));
- goto loop;
- }
- assert( false );
- }
-
-//////////////////////////////////////// ED prefix
- {
- case 0xED:
- pc++;
- s_time += ed_dd_timing [data] >> 4;
- switch ( data )
- {
- {
- blargg_ulong temp;
- case 0x72: // SBC HL,SP
- case 0x7A: // ADC HL,SP
- temp = sp;
- if ( 0 )
- case 0x42: // SBC HL,BC
- case 0x52: // SBC HL,DE
- case 0x62: // SBC HL,HL
- case 0x4A: // ADC HL,BC
- case 0x5A: // ADC HL,DE
- case 0x6A: // ADC HL,HL
- temp = R16( data >> 3 & 6, 1, 0 );
- blargg_ulong sum = temp + (flags & C01);
- flags = ~data >> 2 & N02;
- if ( flags )
- sum = -sum;
- sum += rp.hl;
- temp ^= rp.hl;
- temp ^= sum;
- flags |=(sum >> 16 & C01) |
- (temp >> 8 & H10) |
- (sum >> 8 & (S80 | F20 | F08)) |
- ((temp - -0x8000) >> 14 & V04);
- rp.hl = sum;
- if ( (uint16_t) sum )
- goto loop;
- flags |= Z40;
- goto loop;
- }
-
- CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C)
- int temp = IN( rp.bc );
- R8( data >> 3, 8 ) = temp;
- flags = (flags & C01) | SZ28P( temp );
- goto loop;
- }
-
- case 0x71: // OUT (C),0
- rg.flags = 0;
- CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r
- OUT( rp.bc, R8( data >> 3, 8 ) );
- goto loop;
-
- {
- unsigned temp;
- case 0x73: // LD (ADDR),SP
- temp = sp;
- if ( 0 )
- case 0x43: // LD (ADDR),BC
- case 0x53: // LD (ADDR),DE
- temp = R16( data, 4, 0x43 );
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, temp );
- goto loop;
- }
-
- case 0x4B: // LD BC,(ADDR)
- case 0x5B:{// LD DE,(ADDR)
- fuint16 addr = GET_ADDR();
- pc += 2;
- R16( data, 4, 0x4B ) = READ_WORD( addr );
- goto loop;
- }
-
- case 0x7B:{// LD SP,(ADDR)
- fuint16 addr = GET_ADDR();
- pc += 2;
- sp = READ_WORD( addr );
- goto loop;
- }
-
- case 0x67:{// RRD
- fuint8 temp = READ( rp.hl );
- WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
- temp = (rg.a & 0xF0) | (temp & 0x0F);
- flags = (flags & C01) | SZ28P( temp );
- rg.a = temp;
- goto loop;
- }
-
- case 0x6F:{// RLD
- fuint8 temp = READ( rp.hl );
- WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
- temp = (rg.a & 0xF0) | (temp >> 4);
- flags = (flags & C01) | SZ28P( temp );
- rg.a = temp;
- goto loop;
- }
-
- CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG
- opcode = 0x10; // flag to do SBC instead of ADC
- flags &= ~C01;
- data = rg.a;
- rg.a = 0;
- goto adc_data;
-
- {
- int inc;
- case 0xA9: // CPD
- case 0xB9: // CPDR
- inc = -1;
- if ( 0 )
- case 0xA1: // CPI
- case 0xB1: // CPIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- int result = rg.a - temp;
- flags = (flags & C01) | N02 |
- ((((temp ^ rg.a) & H10) ^ result) & (S80 | H10));
-
- if ( !(uint8_t) result ) flags |= Z40;
- result -= (flags & H10) >> 4;
- flags |= result & F08;
- flags |= result << 4 & F20;
- if ( !--rp.bc )
- goto loop;
-
- flags |= V04;
- if ( flags & Z40 || data < 0xB0 )
- goto loop;
-
- pc -= 2;
- s_time += 5;
- goto loop;
- }
-
- {
- int inc;
- case 0xA8: // LDD
- case 0xB8: // LDDR
- inc = -1;
- if ( 0 )
- case 0xA0: // LDI
- case 0xB0: // LDIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- addr = rp.de;
- rp.de = addr + inc;
- WRITE( addr, temp );
-
- temp += rg.a;
- flags = (flags & (S80 | Z40 | C01)) |
- (temp & F08) | (temp << 4 & F20);
- if ( !--rp.bc )
- goto loop;
-
- flags |= V04;
- if ( data < 0xB0 )
- goto loop;
-
- pc -= 2;
- s_time += 5;
- goto loop;
- }
-
- {
- int inc;
- case 0xAB: // OUTD
- case 0xBB: // OTDR
- inc = -1;
- if ( 0 )
- case 0xA3: // OUTI
- case 0xB3: // OTIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- int b = --rg.b;
- flags = (temp >> 6 & N02) | SZ28( b );
- if ( b && data >= 0xB0 )
- {
- pc -= 2;
- s_time += 5;
- }
-
- OUT( rp.bc, temp );
- goto loop;
- }
-
- {
- int inc;
- case 0xAA: // IND
- case 0xBA: // INDR
- inc = -1;
- if ( 0 )
- case 0xA2: // INI
- case 0xB2: // INIR
- inc = +1;
-
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
-
- int temp = IN( rp.bc );
-
- int b = --rg.b;
- flags = (temp >> 6 & N02) | SZ28( b );
- if ( b && data >= 0xB0 )
- {
- pc -= 2;
- s_time += 5;
- }
-
- WRITE( addr, temp );
- goto loop;
- }
-
- case 0x47: // LD I,A
- r.i = rg.a;
- goto loop;
-
- case 0x4F: // LD R,A
- SET_R( rg.a );
- debug_printf( "LD R,A not supported\n" );
- warning = true;
- goto loop;
-
- case 0x57: // LD A,I
- rg.a = r.i;
- goto ld_ai_common;
-
- case 0x5F: // LD A,R
- rg.a = GET_R();
- debug_printf( "LD A,R not supported\n" );
- warning = true;
- ld_ai_common:
- flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
- goto loop;
-
- CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN
- r.iff1 = r.iff2;
- goto ret_taken;
-
- case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0
- r.im = 0;
- goto loop;
-
- case 0x56: case 0x76: // IM 1
- r.im = 1;
- goto loop;
-
- case 0x5E: case 0x7E: // IM 2
- r.im = 2;
- goto loop;
-
- default:
- debug_printf( "Opcode $ED $%02X not supported\n", data );
- warning = true;
- goto loop;
- }
- assert( false );
- }
-
-//////////////////////////////////////// DD/FD prefix
- {
- fuint16 ixy;
- case 0xDD:
- ixy = ix;
- goto ix_prefix;
- case 0xFD:
- ixy = iy;
- ix_prefix:
- pc++;
- unsigned data2 = READ_PROG( pc );
- s_time += ed_dd_timing [data] & 0x0F;
- switch ( data )
- {
- // TODO: more efficient way of avoid negative address
- #define IXY_DISP( ixy, disp ) uint16_t ((ixy) + (disp))
-
- #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in;
-
- // ADD/ADC/SUB/SBC
-
- case 0x96: // SUB (IXY+disp)
- case 0x86: // ADD (IXY+disp)
- flags &= ~C01;
- case 0x9E: // SBC (IXY+disp)
- case 0x8E: // ADC (IXY+disp)
- pc++;
- opcode = data;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto adc_data;
-
- case 0x94: // SUB HXY
- case 0x84: // ADD HXY
- flags &= ~C01;
- case 0x9C: // SBC HXY
- case 0x8C: // ADC HXY
- opcode = data;
- data = ixy >> 8;
- goto adc_data;
-
- case 0x95: // SUB LXY
- case 0x85: // ADD LXY
- flags &= ~C01;
- case 0x9D: // SBC LXY
- case 0x8D: // ADC LXY
- opcode = data;
- data = (uint8_t) ixy;
- goto adc_data;
-
- {
- unsigned temp;
- case 0x39: // ADD IXY,SP
- temp = sp;
- goto add_ixy_data;
-
- case 0x29: // ADD IXY,HL
- temp = ixy;
- goto add_ixy_data;
-
- case 0x09: // ADD IXY,BC
- case 0x19: // ADD IXY,DE
- temp = R16( data, 4, 0x09 );
- add_ixy_data: {
- blargg_ulong sum = ixy + temp;
- temp ^= ixy;
- ixy = (uint16_t) sum;
- flags = (flags & (S80 | Z40 | V04)) |
- (sum >> 16) |
- (sum >> 8 & (F20 | F08)) |
- ((temp ^ sum) >> 8 & H10);
- goto set_ixy;
- }
- }
-
- // AND
- case 0xA6: // AND (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto and_data;
-
- case 0xA4: // AND HXY
- data = ixy >> 8;
- goto and_data;
-
- case 0xA5: // AND LXY
- data = (uint8_t) ixy;
- goto and_data;
-
- // OR
- case 0xB6: // OR (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto or_data;
-
- case 0xB4: // OR HXY
- data = ixy >> 8;
- goto or_data;
-
- case 0xB5: // OR LXY
- data = (uint8_t) ixy;
- goto or_data;
-
- // XOR
- case 0xAE: // XOR (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto xor_data;
-
- case 0xAC: // XOR HXY
- data = ixy >> 8;
- goto xor_data;
-
- case 0xAD: // XOR LXY
- data = (uint8_t) ixy;
- goto xor_data;
-
- // CP
- case 0xBE: // CP (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto cp_data;
-
- case 0xBC: // CP HXY
- data = ixy >> 8;
- goto cp_data;
-
- case 0xBD: // CP LXY
- data = (uint8_t) ixy;
- goto cp_data;
-
- // LD
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r
- data = R8( data, 0x70 );
- if ( 0 )
- case 0x36: // LD (IXY+disp),imm
- pc++, data = READ_PROG( pc );
- pc++;
- WRITE( IXY_DISP( ixy, (int8_t) data2 ), data );
- goto loop;
-
- CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY
- R8( data >> 3, 8 ) = ixy >> 8;
- goto loop;
-
- case 0x64: // LD HXY,HXY
- case 0x6D: // LD LXY,LXY
- goto loop;
-
- CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY
- R8( data >> 3, 8 ) = ixy;
- goto loop;
-
- CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp)
- pc++;
- R8( data >> 3, 8 ) = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto loop;
-
- case 0x26: // LD HXY,imm
- pc++;
- goto ld_hxy_data;
-
- case 0x65: // LD HXY,LXY
- data2 = (uint8_t) ixy;
- goto ld_hxy_data;
-
- CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r
- data2 = R8( data, 0x60 );
- ld_hxy_data:
- ixy = (uint8_t) ixy | (data2 << 8);
- goto set_ixy;
-
- case 0x2E: // LD LXY,imm
- pc++;
- goto ld_lxy_data;
-
- case 0x6C: // LD LXY,HXY
- data2 = ixy >> 8;
- goto ld_lxy_data;
-
- CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r
- data2 = R8( data, 0x68 );
- ld_lxy_data:
- ixy = (ixy & 0xFF00) | data2;
- set_ixy:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto loop;
- }
- iy = ixy;
- goto loop;
-
- case 0xF9: // LD SP,IXY
- sp = ixy;
- goto loop;
-
- case 0x22:{// LD (ADDR),IXY
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, ixy );
- goto loop;
- }
-
- case 0x21: // LD IXY,imm
- ixy = GET_ADDR();
- pc += 2;
- goto set_ixy;
-
- case 0x2A:{// LD IXY,(addr)
- fuint16 addr = GET_ADDR();
- ixy = READ_WORD( addr );
- pc += 2;
- goto set_ixy;
- }
-
- // DD/FD CB prefix
- case 0xCB: {
- data = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data2 = READ_PROG( pc );
- pc++;
- switch ( data2 )
- {
- case 0x06: goto rlc_data_addr; // RLC (IXY)
- case 0x16: goto rl_data_addr; // RL (IXY)
- case 0x26: goto sla_data_addr; // SLA (IXY)
- case 0x36: goto sll_data_addr; // SLL (IXY)
- case 0x0E: goto rrc_data_addr; // RRC (IXY)
- case 0x1E: goto rr_data_addr; // RR (IXY)
- case 0x2E: goto sra_data_addr; // SRA (IXY)
- case 0x3E: goto srl_data_addr; // SRL (IXY)
-
- CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
- fuint8 temp = READ( data );
- int masked = temp & 1 << (data2 >> 3 & 7);
- flags = (flags & C01) | H10 |
- (masked & S80) |
- ((masked - 1) >> 8 & (Z40 | P04));
- goto loop;
- }
-
- CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp)
- CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp)
- int temp = READ( data );
- int bit = 1 << (data2 >> 3 & 7);
- temp |= bit; // SET
- if ( !(data2 & 0x40) )
- temp ^= bit; // RES
- WRITE( data, temp );
- goto loop;
- }
-
- default:
- debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
- warning = true;
- goto loop;
- }
- assert( false );
- }
-
- // INC/DEC
- case 0x23: // INC IXY
- ixy = uint16_t (ixy + 1);
- goto set_ixy;
-
- case 0x2B: // DEC IXY
- ixy = uint16_t (ixy - 1);
- goto set_ixy;
-
- case 0x34: // INC (IXY+disp)
- ixy = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data = READ( ixy ) + 1;
- WRITE( ixy, data );
- goto inc_set_flags;
-
- case 0x35: // DEC (IXY+disp)
- ixy = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data = READ( ixy ) - 1;
- WRITE( ixy, data );
- goto dec_set_flags;
-
- case 0x24: // INC HXY
- ixy = uint16_t (ixy + 0x100);
- data = ixy >> 8;
- goto inc_xy_common;
-
- case 0x2C: // INC LXY
- data = uint8_t (ixy + 1);
- ixy = (ixy & 0xFF00) | data;
- inc_xy_common:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto inc_set_flags;
- }
- iy = ixy;
- goto inc_set_flags;
-
- case 0x25: // DEC HXY
- ixy = uint16_t (ixy - 0x100);
- data = ixy >> 8;
- goto dec_xy_common;
-
- case 0x2D: // DEC LXY
- data = uint8_t (ixy - 1);
- ixy = (ixy & 0xFF00) | data;
- dec_xy_common:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto dec_set_flags;
- }
- iy = ixy;
- goto dec_set_flags;
-
- // PUSH/POP
- case 0xE5: // PUSH IXY
- data = ixy;
- goto push_data;
-
- case 0xE1:{// POP IXY
- ixy = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto set_ixy;
- }
-
- // Misc
-
- case 0xE9: // JP (IXY)
- pc = ixy;
- goto loop;
-
- case 0xE3:{// EX (SP),IXY
- fuint16 temp = READ_WORD( sp );
- WRITE_WORD( sp, ixy );
- ixy = temp;
- goto set_ixy;
- }
-
- default:
- debug_printf( "Unnecessary DD/FD prefix encountered\n" );
- warning = true;
- pc--;
- goto loop;
- }
- assert( false );
- }
-
- }
- debug_printf( "Unhandled main opcode: $%02X\n", opcode );
- assert( false );
-
-halt:
- s_time &= 3; // increment by multiple of 4
-out_of_time:
- pc--;
-
- s.time = s_time;
- rg.flags = flags;
- r.ix = ix;
- r.iy = iy;
- r.sp = sp;
- r.pc = pc;
- this->r.b = rg;
- this->state_ = s;
- this->state = &this->state_;
-
- return warning;
-}
diff --git a/src/console/Ay_Emu.cc b/src/console/Ay_Emu.cc
new file mode 100644
index 000000000000..663842d09f07
--- /dev/null
+++ b/src/console/Ay_Emu.cc
@@ -0,0 +1,405 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Ay_Emu.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+long const spectrum_clock = 3546900;
+long const cpc_clock = 2000000;
+
+unsigned const ram_start = 0x4000;
+int const osc_count = Ay_Apu::osc_count + 1;
+
+Ay_Emu::Ay_Emu()
+{
+ beeper_output = 0;
+ set_type( gme_ay_type );
+
+ static const char* const names [osc_count] = {
+ "Wave 1", "Wave 2", "Wave 3", "Beeper"
+ };
+ set_voice_names( names );
+
+ static int const types [osc_count] = {
+ wave_type | 0, wave_type | 1, wave_type | 2, mixed_type | 0
+ };
+ set_voice_types( types );
+ set_silence_lookahead( 6 );
+}
+
+Ay_Emu::~Ay_Emu() { }
+
+// Track info
+
+static byte const* get_data( Ay_Emu::file_t const& file, byte const* ptr, int min_size )
+{
+ long pos = ptr - (byte const*) file.header;
+ long file_size = file.end - (byte const*) file.header;
+ assert( (unsigned long) pos <= (unsigned long) file_size - 2 );
+ int offset = (int16_t) GET_BE16( ptr );
+ if ( !offset || blargg_ulong (pos + offset) > blargg_ulong (file_size - min_size) )
+ return 0;
+ return ptr + offset;
+}
+
+static blargg_err_t parse_header( byte const* in, long size, Ay_Emu::file_t* out )
+{
+ typedef Ay_Emu::header_t header_t;
+ out->header = (header_t const*) in;
+ out->end = in + size;
+
+ if ( size < Ay_Emu::header_size )
+ return gme_wrong_file_type;
+
+ header_t const& h = *(header_t const*) in;
+ if ( memcmp( h.tag, "ZXAYEMUL", 8 ) )
+ return gme_wrong_file_type;
+
+ out->tracks = get_data( *out, h.track_info, (h.max_track + 1) * 4 );
+ if ( !out->tracks )
+ return "Missing track data";
+
+ return 0;
+}
+
+static void copy_ay_fields( Ay_Emu::file_t const& file, track_info_t* out, int track )
+{
+ Gme_File::copy_field_( out->song, (char const*) get_data( file, file.tracks + track * 4, 1 ) );
+ byte const* track_info = get_data( file, file.tracks + track * 4 + 2, 6 );
+ if ( track_info )
+ out->length = GET_BE16( track_info + 4 ) * (1000L / 50); // frames to msec
+
+ Gme_File::copy_field_( out->author, (char const*) get_data( file, file.header->author, 1 ) );
+ Gme_File::copy_field_( out->comment, (char const*) get_data( file, file.header->comment, 1 ) );
+}
+
+blargg_err_t Ay_Emu::track_info_( track_info_t* out, int track ) const
+{
+ copy_ay_fields( file, out, track );
+ return 0;
+}
+
+struct Ay_File : Gme_Info_
+{
+ Ay_Emu::file_t file;
+
+ Ay_File() { set_type( gme_ay_type ); }
+
+ blargg_err_t load_mem_( byte const* begin, long size )
+ {
+ RETURN_ERR( parse_header( begin, size, &file ) );
+ set_track_count( file.header->max_track + 1 );
+ return 0;
+ }
+
+ blargg_err_t track_info_( track_info_t* out, int track ) const
+ {
+ copy_ay_fields( file, out, track );
+ return 0;
+ }
+};
+
+static Music_Emu* new_ay_emu () { return BLARGG_NEW Ay_Emu ; }
+static Music_Emu* new_ay_file() { return BLARGG_NEW Ay_File; }
+
+static gme_type_t_ const gme_ay_type_ = { "ZX Spectrum", 0, &new_ay_emu, &new_ay_file, "AY", 1 };
+gme_type_t const gme_ay_type = &gme_ay_type_;
+
+// Setup
+
+blargg_err_t Ay_Emu::load_mem_( byte const* in, long size )
+{
+ assert( offsetof (header_t,track_info [2]) == header_size );
+
+ RETURN_ERR( parse_header( in, size, &file ) );
+ set_track_count( file.header->max_track + 1 );
+
+ if ( file.header->vers > 2 )
+ set_warning( "Unknown file version" );
+
+ set_voice_count( osc_count );
+ apu.volume( gain() );
+
+ return setup_buffer( spectrum_clock );
+}
+
+void Ay_Emu::update_eq( blip_eq_t const& eq )
+{
+ apu.treble_eq( eq );
+}
+
+void Ay_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer*, Blip_Buffer* )
+{
+ if ( i >= Ay_Apu::osc_count )
+ beeper_output = center;
+ else
+ apu.osc_output( i, center );
+}
+
+// Emulation
+
+void Ay_Emu::set_tempo_( double t )
+{
+ play_period = blip_time_t (clock_rate() / 50 / t);
+}
+
+blargg_err_t Ay_Emu::start_track_( int track )
+{
+ RETURN_ERR( Classic_Emu::start_track_( track ) );
+
+ memset( mem.ram + 0x0000, 0xC9, 0x100 ); // fill RST vectors with RET
+ memset( mem.ram + 0x0100, 0xFF, 0x4000 - 0x100 );
+ memset( mem.ram + ram_start, 0x00, sizeof mem.ram - ram_start );
+ memset( mem.padding1, 0xFF, sizeof mem.padding1 );
+ memset( mem.ram + 0x10000, 0xFF, sizeof mem.ram - 0x10000 );
+
+ // locate data blocks
+ byte const* const data = get_data( file, file.tracks + track * 4 + 2, 14 );
+ if ( !data ) return "File data missing";
+
+ byte const* const more_data = get_data( file, data + 10, 6 );
+ if ( !more_data ) return "File data missing";
+
+ byte const* blocks = get_data( file, data + 12, 8 );
+ if ( !blocks ) return "File data missing";
+
+ // initial addresses
+ cpu::reset( mem.ram );
+ r.sp = GET_BE16( more_data );
+ r.b.a = r.b.b = r.b.d = r.b.h = data [8];
+ r.b.flags = r.b.c = r.b.e = r.b.l = data [9];
+ r.alt.w = r.w;
+ r.ix = r.iy = r.w.hl;
+
+ unsigned addr = GET_BE16( blocks );
+ if ( !addr ) return "File data missing";
+
+ unsigned init = GET_BE16( more_data + 2 );
+ if ( !init )
+ init = addr;
+
+ // copy blocks into memory
+ do
+ {
+ blocks += 2;
+ unsigned len = GET_BE16( blocks ); blocks += 2;
+ if ( addr + len > 0x10000 )
+ {
+ set_warning( "Bad data block size" );
+ len = 0x10000 - addr;
+ }
+ check( len );
+ byte const* in = get_data( file, blocks, 0 ); blocks += 2;
+ if ( len > blargg_ulong (file.end - in) )
+ {
+ set_warning( "Missing file data" );
+ len = file.end - in;
+ }
+ //debug_printf( "addr: $%04X, len: $%04X\n", addr, len );
+ if ( addr < ram_start && addr >= 0x400 ) // several tracks use low data
+ debug_printf( "Block addr in ROM\n" );
+ memcpy( mem.ram + addr, in, len );
+
+ if ( file.end - blocks < 8 )
+ {
+ set_warning( "Missing file data" );
+ break;
+ }
+ }
+ while ( (addr = GET_BE16( blocks )) != 0 );
+
+ // copy and configure driver
+ static byte const passive [] = {
+ 0xF3, // DI
+ 0xCD, 0, 0, // CALL init
+ 0xED, 0x5E, // LOOP: IM 2
+ 0xFB, // EI
+ 0x76, // HALT
+ 0x18, 0xFA // JR LOOP
+ };
+ static byte const active [] = {
+ 0xF3, // DI
+ 0xCD, 0, 0, // CALL init
+ 0xED, 0x56, // LOOP: IM 1
+ 0xFB, // EI
+ 0x76, // HALT
+ 0xCD, 0, 0, // CALL play
+ 0x18, 0xF7 // JR LOOP
+ };
+ memcpy( mem.ram, passive, sizeof passive );
+ unsigned play_addr = GET_BE16( more_data + 4 );
+ //debug_printf( "Play: $%04X\n", play_addr );
+ if ( play_addr )
+ {
+ memcpy( mem.ram, active, sizeof active );
+ mem.ram [ 9] = play_addr;
+ mem.ram [10] = play_addr >> 8;
+ }
+ mem.ram [2] = init;
+ mem.ram [3] = init >> 8;
+
+ mem.ram [0x38] = 0xFB; // Put EI at interrupt vector (followed by RET)
+
+ memcpy( mem.ram + 0x10000, mem.ram, 0x80 ); // some code wraps around (ugh)
+
+ beeper_delta = int (apu.amp_range * 0.65);
+ last_beeper = 0;
+ apu.reset();
+ next_play = play_period;
+
+ // start at spectrum speed
+ change_clock_rate( spectrum_clock );
+ set_tempo( tempo() );
+
+ spectrum_mode = false;
+ cpc_mode = false;
+ cpc_latch = 0;
+
+ return 0;
+}
+
+// Emulation
+
+void Ay_Emu::cpu_out_misc( cpu_time_t time, unsigned addr, int data )
+{
+ if ( !cpc_mode )
+ {
+ switch ( addr & 0xFEFF )
+ {
+ case 0xFEFD:
+ spectrum_mode = true;
+ apu_addr = data & 0x0F;
+ return;
+
+ case 0xBEFD:
+ spectrum_mode = true;
+ apu.write( time, apu_addr, data );
+ return;
+ }
+ }
+
+ if ( !spectrum_mode )
+ {
+ switch ( addr >> 8 )
+ {
+ case 0xF6:
+ switch ( data & 0xC0 )
+ {
+ case 0xC0:
+ apu_addr = cpc_latch & 0x0F;
+ goto enable_cpc;
+
+ case 0x80:
+ apu.write( time, apu_addr, cpc_latch );
+ goto enable_cpc;
+ }
+ break;
+
+ case 0xF4:
+ cpc_latch = data;
+ goto enable_cpc;
+ }
+ }
+
+ debug_printf( "Unmapped OUT: $%04X <- $%02X\n", addr, data );
+ return;
+
+enable_cpc:
+ if ( !cpc_mode )
+ {
+ cpc_mode = true;
+ change_clock_rate( cpc_clock );
+ set_tempo( tempo() );
+ }
+}
+
+void ay_cpu_out( Ay_Cpu* cpu, cpu_time_t time, unsigned addr, int data )
+{
+ Ay_Emu& emu = STATIC_CAST(Ay_Emu&,*cpu);
+
+ if ( (addr & 0xFF) == 0xFE && !emu.cpc_mode )
+ {
+ int delta = emu.beeper_delta;
+ data &= 0x10;
+ if ( emu.last_beeper != data )
+ {
+ emu.last_beeper = data;
+ emu.beeper_delta = -delta;
+ emu.spectrum_mode = true;
+ if ( emu.beeper_output )
+ emu.apu.synth_.offset( time, delta, emu.beeper_output );
+ }
+ }
+ else
+ {
+ emu.cpu_out_misc( time, addr, data );
+ }
+}
+
+int ay_cpu_in( Ay_Cpu*, unsigned addr )
+{
+ // keyboard read and other things
+ if ( (addr & 0xFF) == 0xFE )
+ return 0xFF; // other values break some beeper tunes
+
+ debug_printf( "Unmapped IN : $%04X\n", addr );
+ return 0xFF;
+}
+
+blargg_err_t Ay_Emu::run_clocks( blip_time_t& duration, int )
+{
+ set_time( 0 );
+ if ( !(spectrum_mode | cpc_mode) )
+ duration /= 2; // until mode is set, leave room for halved clock rate
+
+ while ( time() < duration )
+ {
+ cpu::run( min( duration, (blip_time_t) next_play ) );
+
+ if ( time() >= next_play )
+ {
+ next_play += play_period;
+
+ if ( r.iff1 )
+ {
+ if ( mem.ram [r.pc] == 0x76 )
+ r.pc++;
+
+ r.iff1 = r.iff2 = 0;
+
+ mem.ram [--r.sp] = uint8_t (r.pc >> 8);
+ mem.ram [--r.sp] = uint8_t (r.pc);
+ r.pc = 0x38;
+ cpu::adjust_time( 12 );
+ if ( r.im == 2 )
+ {
+ cpu::adjust_time( 6 );
+ unsigned addr = r.i * 0x100u + 0xFF;
+ r.pc = mem.ram [(addr + 1) & 0xFFFF] * 0x100u + mem.ram [addr];
+ }
+ }
+ }
+ }
+ duration = time();
+ next_play -= duration;
+ check( next_play >= 0 );
+ adjust_time( -duration );
+
+ apu.end_frame( duration );
+
+ return 0;
+}
diff --git a/src/console/Ay_Emu.cxx b/src/console/Ay_Emu.cxx
deleted file mode 100644
index 663842d09f07..000000000000
--- a/src/console/Ay_Emu.cxx
+++ /dev/null
@@ -1,405 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Ay_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-long const spectrum_clock = 3546900;
-long const cpc_clock = 2000000;
-
-unsigned const ram_start = 0x4000;
-int const osc_count = Ay_Apu::osc_count + 1;
-
-Ay_Emu::Ay_Emu()
-{
- beeper_output = 0;
- set_type( gme_ay_type );
-
- static const char* const names [osc_count] = {
- "Wave 1", "Wave 2", "Wave 3", "Beeper"
- };
- set_voice_names( names );
-
- static int const types [osc_count] = {
- wave_type | 0, wave_type | 1, wave_type | 2, mixed_type | 0
- };
- set_voice_types( types );
- set_silence_lookahead( 6 );
-}
-
-Ay_Emu::~Ay_Emu() { }
-
-// Track info
-
-static byte const* get_data( Ay_Emu::file_t const& file, byte const* ptr, int min_size )
-{
- long pos = ptr - (byte const*) file.header;
- long file_size = file.end - (byte const*) file.header;
- assert( (unsigned long) pos <= (unsigned long) file_size - 2 );
- int offset = (int16_t) GET_BE16( ptr );
- if ( !offset || blargg_ulong (pos + offset) > blargg_ulong (file_size - min_size) )
- return 0;
- return ptr + offset;
-}
-
-static blargg_err_t parse_header( byte const* in, long size, Ay_Emu::file_t* out )
-{
- typedef Ay_Emu::header_t header_t;
- out->header = (header_t const*) in;
- out->end = in + size;
-
- if ( size < Ay_Emu::header_size )
- return gme_wrong_file_type;
-
- header_t const& h = *(header_t const*) in;
- if ( memcmp( h.tag, "ZXAYEMUL", 8 ) )
- return gme_wrong_file_type;
-
- out->tracks = get_data( *out, h.track_info, (h.max_track + 1) * 4 );
- if ( !out->tracks )
- return "Missing track data";
-
- return 0;
-}
-
-static void copy_ay_fields( Ay_Emu::file_t const& file, track_info_t* out, int track )
-{
- Gme_File::copy_field_( out->song, (char const*) get_data( file, file.tracks + track * 4, 1 ) );
- byte const* track_info = get_data( file, file.tracks + track * 4 + 2, 6 );
- if ( track_info )
- out->length = GET_BE16( track_info + 4 ) * (1000L / 50); // frames to msec
-
- Gme_File::copy_field_( out->author, (char const*) get_data( file, file.header->author, 1 ) );
- Gme_File::copy_field_( out->comment, (char const*) get_data( file, file.header->comment, 1 ) );
-}
-
-blargg_err_t Ay_Emu::track_info_( track_info_t* out, int track ) const
-{
- copy_ay_fields( file, out, track );
- return 0;
-}
-
-struct Ay_File : Gme_Info_
-{
- Ay_Emu::file_t file;
-
- Ay_File() { set_type( gme_ay_type ); }
-
- blargg_err_t load_mem_( byte const* begin, long size )
- {
- RETURN_ERR( parse_header( begin, size, &file ) );
- set_track_count( file.header->max_track + 1 );
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int track ) const
- {
- copy_ay_fields( file, out, track );
- return 0;
- }
-};
-
-static Music_Emu* new_ay_emu () { return BLARGG_NEW Ay_Emu ; }
-static Music_Emu* new_ay_file() { return BLARGG_NEW Ay_File; }
-
-static gme_type_t_ const gme_ay_type_ = { "ZX Spectrum", 0, &new_ay_emu, &new_ay_file, "AY", 1 };
-gme_type_t const gme_ay_type = &gme_ay_type_;
-
-// Setup
-
-blargg_err_t Ay_Emu::load_mem_( byte const* in, long size )
-{
- assert( offsetof (header_t,track_info [2]) == header_size );
-
- RETURN_ERR( parse_header( in, size, &file ) );
- set_track_count( file.header->max_track + 1 );
-
- if ( file.header->vers > 2 )
- set_warning( "Unknown file version" );
-
- set_voice_count( osc_count );
- apu.volume( gain() );
-
- return setup_buffer( spectrum_clock );
-}
-
-void Ay_Emu::update_eq( blip_eq_t const& eq )
-{
- apu.treble_eq( eq );
-}
-
-void Ay_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer*, Blip_Buffer* )
-{
- if ( i >= Ay_Apu::osc_count )
- beeper_output = center;
- else
- apu.osc_output( i, center );
-}
-
-// Emulation
-
-void Ay_Emu::set_tempo_( double t )
-{
- play_period = blip_time_t (clock_rate() / 50 / t);
-}
-
-blargg_err_t Ay_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( mem.ram + 0x0000, 0xC9, 0x100 ); // fill RST vectors with RET
- memset( mem.ram + 0x0100, 0xFF, 0x4000 - 0x100 );
- memset( mem.ram + ram_start, 0x00, sizeof mem.ram - ram_start );
- memset( mem.padding1, 0xFF, sizeof mem.padding1 );
- memset( mem.ram + 0x10000, 0xFF, sizeof mem.ram - 0x10000 );
-
- // locate data blocks
- byte const* const data = get_data( file, file.tracks + track * 4 + 2, 14 );
- if ( !data ) return "File data missing";
-
- byte const* const more_data = get_data( file, data + 10, 6 );
- if ( !more_data ) return "File data missing";
-
- byte const* blocks = get_data( file, data + 12, 8 );
- if ( !blocks ) return "File data missing";
-
- // initial addresses
- cpu::reset( mem.ram );
- r.sp = GET_BE16( more_data );
- r.b.a = r.b.b = r.b.d = r.b.h = data [8];
- r.b.flags = r.b.c = r.b.e = r.b.l = data [9];
- r.alt.w = r.w;
- r.ix = r.iy = r.w.hl;
-
- unsigned addr = GET_BE16( blocks );
- if ( !addr ) return "File data missing";
-
- unsigned init = GET_BE16( more_data + 2 );
- if ( !init )
- init = addr;
-
- // copy blocks into memory
- do
- {
- blocks += 2;
- unsigned len = GET_BE16( blocks ); blocks += 2;
- if ( addr + len > 0x10000 )
- {
- set_warning( "Bad data block size" );
- len = 0x10000 - addr;
- }
- check( len );
- byte const* in = get_data( file, blocks, 0 ); blocks += 2;
- if ( len > blargg_ulong (file.end - in) )
- {
- set_warning( "Missing file data" );
- len = file.end - in;
- }
- //debug_printf( "addr: $%04X, len: $%04X\n", addr, len );
- if ( addr < ram_start && addr >= 0x400 ) // several tracks use low data
- debug_printf( "Block addr in ROM\n" );
- memcpy( mem.ram + addr, in, len );
-
- if ( file.end - blocks < 8 )
- {
- set_warning( "Missing file data" );
- break;
- }
- }
- while ( (addr = GET_BE16( blocks )) != 0 );
-
- // copy and configure driver
- static byte const passive [] = {
- 0xF3, // DI
- 0xCD, 0, 0, // CALL init
- 0xED, 0x5E, // LOOP: IM 2
- 0xFB, // EI
- 0x76, // HALT
- 0x18, 0xFA // JR LOOP
- };
- static byte const active [] = {
- 0xF3, // DI
- 0xCD, 0, 0, // CALL init
- 0xED, 0x56, // LOOP: IM 1
- 0xFB, // EI
- 0x76, // HALT
- 0xCD, 0, 0, // CALL play
- 0x18, 0xF7 // JR LOOP
- };
- memcpy( mem.ram, passive, sizeof passive );
- unsigned play_addr = GET_BE16( more_data + 4 );
- //debug_printf( "Play: $%04X\n", play_addr );
- if ( play_addr )
- {
- memcpy( mem.ram, active, sizeof active );
- mem.ram [ 9] = play_addr;
- mem.ram [10] = play_addr >> 8;
- }
- mem.ram [2] = init;
- mem.ram [3] = init >> 8;
-
- mem.ram [0x38] = 0xFB; // Put EI at interrupt vector (followed by RET)
-
- memcpy( mem.ram + 0x10000, mem.ram, 0x80 ); // some code wraps around (ugh)
-
- beeper_delta = int (apu.amp_range * 0.65);
- last_beeper = 0;
- apu.reset();
- next_play = play_period;
-
- // start at spectrum speed
- change_clock_rate( spectrum_clock );
- set_tempo( tempo() );
-
- spectrum_mode = false;
- cpc_mode = false;
- cpc_latch = 0;
-
- return 0;
-}
-
-// Emulation
-
-void Ay_Emu::cpu_out_misc( cpu_time_t time, unsigned addr, int data )
-{
- if ( !cpc_mode )
- {
- switch ( addr & 0xFEFF )
- {
- case 0xFEFD:
- spectrum_mode = true;
- apu_addr = data & 0x0F;
- return;
-
- case 0xBEFD:
- spectrum_mode = true;
- apu.write( time, apu_addr, data );
- return;
- }
- }
-
- if ( !spectrum_mode )
- {
- switch ( addr >> 8 )
- {
- case 0xF6:
- switch ( data & 0xC0 )
- {
- case 0xC0:
- apu_addr = cpc_latch & 0x0F;
- goto enable_cpc;
-
- case 0x80:
- apu.write( time, apu_addr, cpc_latch );
- goto enable_cpc;
- }
- break;
-
- case 0xF4:
- cpc_latch = data;
- goto enable_cpc;
- }
- }
-
- debug_printf( "Unmapped OUT: $%04X <- $%02X\n", addr, data );
- return;
-
-enable_cpc:
- if ( !cpc_mode )
- {
- cpc_mode = true;
- change_clock_rate( cpc_clock );
- set_tempo( tempo() );
- }
-}
-
-void ay_cpu_out( Ay_Cpu* cpu, cpu_time_t time, unsigned addr, int data )
-{
- Ay_Emu& emu = STATIC_CAST(Ay_Emu&,*cpu);
-
- if ( (addr & 0xFF) == 0xFE && !emu.cpc_mode )
- {
- int delta = emu.beeper_delta;
- data &= 0x10;
- if ( emu.last_beeper != data )
- {
- emu.last_beeper = data;
- emu.beeper_delta = -delta;
- emu.spectrum_mode = true;
- if ( emu.beeper_output )
- emu.apu.synth_.offset( time, delta, emu.beeper_output );
- }
- }
- else
- {
- emu.cpu_out_misc( time, addr, data );
- }
-}
-
-int ay_cpu_in( Ay_Cpu*, unsigned addr )
-{
- // keyboard read and other things
- if ( (addr & 0xFF) == 0xFE )
- return 0xFF; // other values break some beeper tunes
-
- debug_printf( "Unmapped IN : $%04X\n", addr );
- return 0xFF;
-}
-
-blargg_err_t Ay_Emu::run_clocks( blip_time_t& duration, int )
-{
- set_time( 0 );
- if ( !(spectrum_mode | cpc_mode) )
- duration /= 2; // until mode is set, leave room for halved clock rate
-
- while ( time() < duration )
- {
- cpu::run( min( duration, (blip_time_t) next_play ) );
-
- if ( time() >= next_play )
- {
- next_play += play_period;
-
- if ( r.iff1 )
- {
- if ( mem.ram [r.pc] == 0x76 )
- r.pc++;
-
- r.iff1 = r.iff2 = 0;
-
- mem.ram [--r.sp] = uint8_t (r.pc >> 8);
- mem.ram [--r.sp] = uint8_t (r.pc);
- r.pc = 0x38;
- cpu::adjust_time( 12 );
- if ( r.im == 2 )
- {
- cpu::adjust_time( 6 );
- unsigned addr = r.i * 0x100u + 0xFF;
- r.pc = mem.ram [(addr + 1) & 0xFFFF] * 0x100u + mem.ram [addr];
- }
- }
- }
- }
- duration = time();
- next_play -= duration;
- check( next_play >= 0 );
- adjust_time( -duration );
-
- apu.end_frame( duration );
-
- return 0;
-}
diff --git a/src/console/Ay_Emu.h b/src/console/Ay_Emu.h
index 4865c0dc09a3..5015ac5ef052 100644
--- a/src/console/Ay_Emu.h
+++ b/src/console/Ay_Emu.h
@@ -46,7 +46,6 @@ protected:
private:
file_t file;
- unsigned play_addr;
cpu_time_t play_period;
cpu_time_t next_play;
Blip_Buffer* beeper_output;
diff --git a/src/console/Blip_Buffer.cc b/src/console/Blip_Buffer.cc
new file mode 100644
index 000000000000..a46b0e350d42
--- /dev/null
+++ b/src/console/Blip_Buffer.cc
@@ -0,0 +1,460 @@
+// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
+
+#include "Blip_Buffer.h"
+
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifdef BLARGG_ENABLE_OPTIMIZER
+ #include BLARGG_ENABLE_OPTIMIZER
+#endif
+
+int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
+
+Blip_Buffer::Blip_Buffer()
+{
+ factor_ = (blip_ulong)-1 / 2;
+ offset_ = 0;
+ buffer_ = 0;
+ buffer_size_ = 0;
+ sample_rate_ = 0;
+ reader_accum_ = 0;
+ bass_shift_ = 0;
+ clock_rate_ = 0;
+ bass_freq_ = 16;
+ length_ = 0;
+
+ // assumptions code makes about implementation-defined features
+ #ifndef NDEBUG
+ // right shift of negative value preserves sign
+ buf_t_ i = -0x7FFFFFFE;
+ assert( (i >> 1) == -0x3FFFFFFF );
+
+ // casting to short truncates to 16 bits and sign-extends
+ i = 0x18000;
+ assert( (short) i == -0x8000 );
+ #endif
+}
+
+Blip_Buffer::~Blip_Buffer()
+{
+ if ( buffer_size_ != silent_buf_size )
+ free( buffer_ );
+}
+
+Silent_Blip_Buffer::Silent_Blip_Buffer()
+{
+ factor_ = 0;
+ buffer_ = buf;
+ buffer_size_ = silent_buf_size;
+ memset( buf, 0, sizeof buf ); // in case machine takes exception for signed overflow
+}
+
+void Blip_Buffer::clear( int entire_buffer )
+{
+ offset_ = 0;
+ reader_accum_ = 0;
+ modified_ = 0;
+ if ( buffer_ )
+ {
+ long count = (entire_buffer ? buffer_size_ : samples_avail());
+ memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) );
+ }
+}
+
+Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec )
+{
+ if ( buffer_size_ == silent_buf_size )
+ {
+ assert( 0 );
+ return "Internal (tried to resize Silent_Blip_Buffer)";
+ }
+
+ // start with maximum length that resampled time can represent
+ long new_size = (UINT_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
+ if ( msec != blip_max_length )
+ {
+ long s = (new_rate * (msec + 1) + 999) / 1000;
+ if ( s < new_size )
+ new_size = s;
+ else
+ assert( 0 ); // fails if requested buffer length exceeds limit
+ }
+
+ if ( buffer_size_ != new_size )
+ {
+ void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ );
+ if ( !p )
+ return "Out of memory";
+ buffer_ = (buf_t_*) p;
+ }
+
+ buffer_size_ = new_size;
+ assert( buffer_size_ != silent_buf_size );
+
+ // update things based on the sample rate
+ sample_rate_ = new_rate;
+ length_ = new_size * 1000 / new_rate - 1;
+ if ( msec )
+ assert( length_ == msec ); // ensure length is same as that passed in
+ if ( clock_rate_ )
+ clock_rate( clock_rate_ );
+ bass_freq( bass_freq_ );
+
+ clear();
+
+ return 0; // success
+}
+
+blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
+{
+ double ratio = (double) sample_rate_ / rate;
+ blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 );
+ assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large
+ return (blip_resampled_time_t) factor;
+}
+
+void Blip_Buffer::bass_freq( int freq )
+{
+ bass_freq_ = freq;
+ int shift = 31;
+ if ( freq > 0 )
+ {
+ shift = 13;
+ long f = (freq << 16) / sample_rate_;
+ while ( (f >>= 1) && --shift ) { }
+ }
+ bass_shift_ = shift;
+}
+
+void Blip_Buffer::end_frame( blip_time_t t )
+{
+ offset_ += t * factor_;
+ assert( samples_avail() <= (long) buffer_size_ ); // time outside buffer length
+}
+
+void Blip_Buffer::remove_silence( long count )
+{
+ assert( count <= samples_avail() ); // tried to remove more samples than available
+ offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
+}
+
+long Blip_Buffer::count_samples( blip_time_t t ) const
+{
+ unsigned long last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY;
+ unsigned long first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
+ return (long) (last_sample - first_sample);
+}
+
+blip_time_t Blip_Buffer::count_clocks( long count ) const
+{
+ if ( !factor_ )
+ {
+ assert( 0 ); // sample rate and clock rates must be set first
+ return 0;
+ }
+
+ if ( count > buffer_size_ )
+ count = buffer_size_;
+ blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
+ return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
+}
+
+void Blip_Buffer::remove_samples( long count )
+{
+ if ( count )
+ {
+ remove_silence( count );
+
+ // copy remaining samples to beginning and clear old samples
+ long remain = samples_avail() + blip_buffer_extra_;
+ memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ );
+ memset( buffer_ + remain, 0, count * sizeof *buffer_ );
+ }
+}
+
+// Blip_Synth_
+
+Blip_Synth_Fast_::Blip_Synth_Fast_()
+{
+ buf = 0;
+ last_amp = 0;
+ delta_factor = 0;
+}
+
+void Blip_Synth_Fast_::volume_unit( double new_unit )
+{
+ delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5);
+}
+
+#if !BLIP_BUFFER_FAST
+
+Blip_Synth_::Blip_Synth_( short* p, int w ) :
+ impulses( p ),
+ width( w )
+{
+ volume_unit_ = 0.0;
+ kernel_unit = 0;
+ buf = 0;
+ last_amp = 0;
+ delta_factor = 0;
+}
+
+#undef PI
+#define PI 3.1415926535897932384626433832795029
+
+static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff )
+{
+ if ( cutoff >= 0.999 )
+ cutoff = 0.999;
+
+ if ( treble < -300.0 )
+ treble = -300.0;
+ if ( treble > 5.0 )
+ treble = 5.0;
+
+ double const maxh = 4096.0;
+ double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) );
+ double const pow_a_n = pow( rolloff, maxh - maxh * cutoff );
+ double const to_angle = PI / 2 / maxh / oversample;
+ for ( int i = 0; i < count; i++ )
+ {
+ double angle = ((i - count) * 2 + 1) * to_angle;
+ double angle_maxh = angle * maxh;
+ double angle_maxh_mid = angle_maxh * cutoff;
+
+ double y = maxh;
+
+ // 0 to Fs/2*cutoff, flat
+ if ( angle_maxh_mid ) // unstable at t=0
+ y *= sin( angle_maxh_mid ) / angle_maxh_mid;
+
+ // Fs/2*cutoff to Fs/2, logarithmic rolloff
+ double cosa = cos( angle );
+ double den = 1 + rolloff * (rolloff - cosa - cosa);
+
+ // Becomes unstable when rolloff is near 1.0 and t is near 0,
+ // which is the only time den becomes small
+ if ( den > 1e-13 )
+ {
+ double num =
+ (cos( angle_maxh - angle ) * rolloff - cos( angle_maxh )) * pow_a_n -
+ cos( angle_maxh_mid - angle ) * rolloff + cos( angle_maxh_mid );
+
+ y = y * cutoff + num / den;
+ }
+
+ out [i] = (float) y;
+ }
+}
+
+void blip_eq_t::generate( float* out, int count ) const
+{
+ // lower cutoff freq for narrow kernels with their wider transition band
+ // (8 points->1.49, 16 points->1.15)
+ double oversample = blip_res * 2.25 / count + 0.85;
+ double half_rate = sample_rate * 0.5;
+ if ( cutoff_freq )
+ oversample = half_rate / cutoff_freq;
+ double cutoff = rolloff_freq * oversample / half_rate;
+
+ gen_sinc( out, count, blip_res * oversample, treble, cutoff );
+
+ // apply (half of) hamming window
+ double to_fraction = PI / (count - 1);
+ for ( int i = count; i--; )
+ out [i] *= 0.54f - 0.46f * (float) cos( i * to_fraction );
+}
+
+void Blip_Synth_::adjust_impulse()
+{
+ // sum pairs for each phase and add error correction to end of first half
+ int const size = impulses_size();
+ for ( int p = blip_res; p-- >= blip_res / 2; )
+ {
+ int p2 = blip_res - 2 - p;
+ long error = kernel_unit;
+ for ( int i = 1; i < size; i += blip_res )
+ {
+ error -= impulses [i + p ];
+ error -= impulses [i + p2];
+ }
+ if ( p == p2 )
+ error /= 2; // phase = 0.5 impulse uses same half for both sides
+ impulses [size - blip_res + p] += (short) error;
+ //printf( "error: %ld\n", error );
+ }
+
+ //for ( int i = blip_res; i--; printf( "\n" ) )
+ // for ( int j = 0; j < width / 2; j++ )
+ // printf( "%5ld,", impulses [j * blip_res + i + 1] );
+}
+
+void Blip_Synth_::treble_eq( blip_eq_t const& eq )
+{
+ float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2];
+
+ int const half_size = blip_res / 2 * (width - 1);
+ eq.generate( &fimpulse [blip_res], half_size );
+
+ int i;
+
+ // need mirror slightly past center for calculation
+ for ( i = blip_res; i--; )
+ fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
+
+ // starts at 0
+ for ( i = 0; i < blip_res; i++ )
+ fimpulse [i] = 0.0f;
+
+ // find rescale factor
+ double total = 0.0;
+ for ( i = 0; i < half_size; i++ )
+ total += fimpulse [blip_res + i];
+
+ //double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
+ //double const base_unit = 37888.0; // allows treble to +5 dB
+ double const base_unit = 32768.0; // necessary for blip_unscaled to work
+ double rescale = base_unit / 2 / total;
+ kernel_unit = (long) base_unit;
+
+ // integrate, first difference, rescale, convert to int
+ double sum = 0.0;
+ double next = 0.0;
+ int const impulses_size = this->impulses_size();
+ for ( i = 0; i < impulses_size; i++ )
+ {
+ impulses [i] = (short) floor( (next - sum) * rescale + 0.5 );
+ sum += fimpulse [i];
+ next += fimpulse [i + blip_res];
+ }
+ adjust_impulse();
+
+ // volume might require rescaling
+ double vol = volume_unit_;
+ if ( vol )
+ {
+ volume_unit_ = 0.0;
+ volume_unit( vol );
+ }
+}
+
+void Blip_Synth_::volume_unit( double new_unit )
+{
+ if ( new_unit != volume_unit_ )
+ {
+ // use default eq if it hasn't been set yet
+ if ( !kernel_unit )
+ treble_eq( -8.0 );
+
+ volume_unit_ = new_unit;
+ double factor = new_unit * (1L << blip_sample_bits) / kernel_unit;
+
+ if ( factor > 0.0 )
+ {
+ int shift = 0;
+
+ // if unit is really small, might need to attenuate kernel
+ while ( factor < 2.0 )
+ {
+ shift++;
+ factor *= 2.0;
+ }
+
+ if ( shift )
+ {
+ kernel_unit >>= shift;
+ assert( kernel_unit > 0 ); // fails if volume unit is too low
+
+ // keep values positive to avoid round-towards-zero of sign-preserving
+ // right shift for negative values
+ long offset = 0x8000 + (1 << (shift - 1));
+ long offset2 = 0x8000 >> shift;
+ for ( int i = impulses_size(); i--; )
+ impulses [i] = (short) (((impulses [i] + offset) >> shift) - offset2);
+ adjust_impulse();
+ }
+ }
+ delta_factor = (int) floor( factor + 0.5 );
+ //printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit );
+ }
+}
+#endif
+
+long Blip_Buffer::read_samples( blip_sample_t* BLIP_RESTRICT out, long max_samples, int stereo )
+{
+ long count = samples_avail();
+ if ( count > max_samples )
+ count = max_samples;
+
+ if ( count )
+ {
+ int const bass = BLIP_READER_BASS( *this );
+ BLIP_READER_BEGIN( reader, *this );
+
+ if ( !stereo )
+ {
+ for ( blip_long n = count; n; --n )
+ {
+ blip_long s = BLIP_READER_READ( reader );
+ if ( (blip_sample_t) s != s )
+ s = 0x7FFF - (s >> 24);
+ *out++ = (blip_sample_t) s;
+ BLIP_READER_NEXT( reader, bass );
+ }
+ }
+ else
+ {
+ for ( blip_long n = count; n; --n )
+ {
+ blip_long s = BLIP_READER_READ( reader );
+ if ( (blip_sample_t) s != s )
+ s = 0x7FFF - (s >> 24);
+ *out = (blip_sample_t) s;
+ out += 2;
+ BLIP_READER_NEXT( reader, bass );
+ }
+ }
+ BLIP_READER_END( reader, *this );
+
+ remove_samples( count );
+ }
+ return count;
+}
+
+void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
+{
+ if ( buffer_size_ == silent_buf_size )
+ {
+ assert( 0 );
+ return;
+ }
+
+ buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
+
+ int const sample_shift = blip_sample_bits - 16;
+ int prev = 0;
+ while ( count-- )
+ {
+ blip_long s = (blip_long) *in++ << sample_shift;
+ *out += s - prev;
+ prev = s;
+ ++out;
+ }
+ *out -= prev;
+}
+
diff --git a/src/console/Blip_Buffer.cxx b/src/console/Blip_Buffer.cxx
deleted file mode 100644
index a46b0e350d42..000000000000
--- a/src/console/Blip_Buffer.cxx
+++ /dev/null
@@ -1,460 +0,0 @@
-// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
-
-#include "Blip_Buffer.h"
-
-#include <assert.h>
-#include <limits.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
-
-Blip_Buffer::Blip_Buffer()
-{
- factor_ = (blip_ulong)-1 / 2;
- offset_ = 0;
- buffer_ = 0;
- buffer_size_ = 0;
- sample_rate_ = 0;
- reader_accum_ = 0;
- bass_shift_ = 0;
- clock_rate_ = 0;
- bass_freq_ = 16;
- length_ = 0;
-
- // assumptions code makes about implementation-defined features
- #ifndef NDEBUG
- // right shift of negative value preserves sign
- buf_t_ i = -0x7FFFFFFE;
- assert( (i >> 1) == -0x3FFFFFFF );
-
- // casting to short truncates to 16 bits and sign-extends
- i = 0x18000;
- assert( (short) i == -0x8000 );
- #endif
-}
-
-Blip_Buffer::~Blip_Buffer()
-{
- if ( buffer_size_ != silent_buf_size )
- free( buffer_ );
-}
-
-Silent_Blip_Buffer::Silent_Blip_Buffer()
-{
- factor_ = 0;
- buffer_ = buf;
- buffer_size_ = silent_buf_size;
- memset( buf, 0, sizeof buf ); // in case machine takes exception for signed overflow
-}
-
-void Blip_Buffer::clear( int entire_buffer )
-{
- offset_ = 0;
- reader_accum_ = 0;
- modified_ = 0;
- if ( buffer_ )
- {
- long count = (entire_buffer ? buffer_size_ : samples_avail());
- memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) );
- }
-}
-
-Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec )
-{
- if ( buffer_size_ == silent_buf_size )
- {
- assert( 0 );
- return "Internal (tried to resize Silent_Blip_Buffer)";
- }
-
- // start with maximum length that resampled time can represent
- long new_size = (UINT_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
- if ( msec != blip_max_length )
- {
- long s = (new_rate * (msec + 1) + 999) / 1000;
- if ( s < new_size )
- new_size = s;
- else
- assert( 0 ); // fails if requested buffer length exceeds limit
- }
-
- if ( buffer_size_ != new_size )
- {
- void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ );
- if ( !p )
- return "Out of memory";
- buffer_ = (buf_t_*) p;
- }
-
- buffer_size_ = new_size;
- assert( buffer_size_ != silent_buf_size );
-
- // update things based on the sample rate
- sample_rate_ = new_rate;
- length_ = new_size * 1000 / new_rate - 1;
- if ( msec )
- assert( length_ == msec ); // ensure length is same as that passed in
- if ( clock_rate_ )
- clock_rate( clock_rate_ );
- bass_freq( bass_freq_ );
-
- clear();
-
- return 0; // success
-}
-
-blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
-{
- double ratio = (double) sample_rate_ / rate;
- blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 );
- assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large
- return (blip_resampled_time_t) factor;
-}
-
-void Blip_Buffer::bass_freq( int freq )
-{
- bass_freq_ = freq;
- int shift = 31;
- if ( freq > 0 )
- {
- shift = 13;
- long f = (freq << 16) / sample_rate_;
- while ( (f >>= 1) && --shift ) { }
- }
- bass_shift_ = shift;
-}
-
-void Blip_Buffer::end_frame( blip_time_t t )
-{
- offset_ += t * factor_;
- assert( samples_avail() <= (long) buffer_size_ ); // time outside buffer length
-}
-
-void Blip_Buffer::remove_silence( long count )
-{
- assert( count <= samples_avail() ); // tried to remove more samples than available
- offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
-}
-
-long Blip_Buffer::count_samples( blip_time_t t ) const
-{
- unsigned long last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY;
- unsigned long first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
- return (long) (last_sample - first_sample);
-}
-
-blip_time_t Blip_Buffer::count_clocks( long count ) const
-{
- if ( !factor_ )
- {
- assert( 0 ); // sample rate and clock rates must be set first
- return 0;
- }
-
- if ( count > buffer_size_ )
- count = buffer_size_;
- blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
- return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
-}
-
-void Blip_Buffer::remove_samples( long count )
-{
- if ( count )
- {
- remove_silence( count );
-
- // copy remaining samples to beginning and clear old samples
- long remain = samples_avail() + blip_buffer_extra_;
- memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ );
- memset( buffer_ + remain, 0, count * sizeof *buffer_ );
- }
-}
-
-// Blip_Synth_
-
-Blip_Synth_Fast_::Blip_Synth_Fast_()
-{
- buf = 0;
- last_amp = 0;
- delta_factor = 0;
-}
-
-void Blip_Synth_Fast_::volume_unit( double new_unit )
-{
- delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5);
-}
-
-#if !BLIP_BUFFER_FAST
-
-Blip_Synth_::Blip_Synth_( short* p, int w ) :
- impulses( p ),
- width( w )
-{
- volume_unit_ = 0.0;
- kernel_unit = 0;
- buf = 0;
- last_amp = 0;
- delta_factor = 0;
-}
-
-#undef PI
-#define PI 3.1415926535897932384626433832795029
-
-static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff )
-{
- if ( cutoff >= 0.999 )
- cutoff = 0.999;
-
- if ( treble < -300.0 )
- treble = -300.0;
- if ( treble > 5.0 )
- treble = 5.0;
-
- double const maxh = 4096.0;
- double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) );
- double const pow_a_n = pow( rolloff, maxh - maxh * cutoff );
- double const to_angle = PI / 2 / maxh / oversample;
- for ( int i = 0; i < count; i++ )
- {
- double angle = ((i - count) * 2 + 1) * to_angle;
- double angle_maxh = angle * maxh;
- double angle_maxh_mid = angle_maxh * cutoff;
-
- double y = maxh;
-
- // 0 to Fs/2*cutoff, flat
- if ( angle_maxh_mid ) // unstable at t=0
- y *= sin( angle_maxh_mid ) / angle_maxh_mid;
-
- // Fs/2*cutoff to Fs/2, logarithmic rolloff
- double cosa = cos( angle );
- double den = 1 + rolloff * (rolloff - cosa - cosa);
-
- // Becomes unstable when rolloff is near 1.0 and t is near 0,
- // which is the only time den becomes small
- if ( den > 1e-13 )
- {
- double num =
- (cos( angle_maxh - angle ) * rolloff - cos( angle_maxh )) * pow_a_n -
- cos( angle_maxh_mid - angle ) * rolloff + cos( angle_maxh_mid );
-
- y = y * cutoff + num / den;
- }
-
- out [i] = (float) y;
- }
-}
-
-void blip_eq_t::generate( float* out, int count ) const
-{
- // lower cutoff freq for narrow kernels with their wider transition band
- // (8 points->1.49, 16 points->1.15)
- double oversample = blip_res * 2.25 / count + 0.85;
- double half_rate = sample_rate * 0.5;
- if ( cutoff_freq )
- oversample = half_rate / cutoff_freq;
- double cutoff = rolloff_freq * oversample / half_rate;
-
- gen_sinc( out, count, blip_res * oversample, treble, cutoff );
-
- // apply (half of) hamming window
- double to_fraction = PI / (count - 1);
- for ( int i = count; i--; )
- out [i] *= 0.54f - 0.46f * (float) cos( i * to_fraction );
-}
-
-void Blip_Synth_::adjust_impulse()
-{
- // sum pairs for each phase and add error correction to end of first half
- int const size = impulses_size();
- for ( int p = blip_res; p-- >= blip_res / 2; )
- {
- int p2 = blip_res - 2 - p;
- long error = kernel_unit;
- for ( int i = 1; i < size; i += blip_res )
- {
- error -= impulses [i + p ];
- error -= impulses [i + p2];
- }
- if ( p == p2 )
- error /= 2; // phase = 0.5 impulse uses same half for both sides
- impulses [size - blip_res + p] += (short) error;
- //printf( "error: %ld\n", error );
- }
-
- //for ( int i = blip_res; i--; printf( "\n" ) )
- // for ( int j = 0; j < width / 2; j++ )
- // printf( "%5ld,", impulses [j * blip_res + i + 1] );
-}
-
-void Blip_Synth_::treble_eq( blip_eq_t const& eq )
-{
- float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2];
-
- int const half_size = blip_res / 2 * (width - 1);
- eq.generate( &fimpulse [blip_res], half_size );
-
- int i;
-
- // need mirror slightly past center for calculation
- for ( i = blip_res; i--; )
- fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
-
- // starts at 0
- for ( i = 0; i < blip_res; i++ )
- fimpulse [i] = 0.0f;
-
- // find rescale factor
- double total = 0.0;
- for ( i = 0; i < half_size; i++ )
- total += fimpulse [blip_res + i];
-
- //double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
- //double const base_unit = 37888.0; // allows treble to +5 dB
- double const base_unit = 32768.0; // necessary for blip_unscaled to work
- double rescale = base_unit / 2 / total;
- kernel_unit = (long) base_unit;
-
- // integrate, first difference, rescale, convert to int
- double sum = 0.0;
- double next = 0.0;
- int const impulses_size = this->impulses_size();
- for ( i = 0; i < impulses_size; i++ )
- {
- impulses [i] = (short) floor( (next - sum) * rescale + 0.5 );
- sum += fimpulse [i];
- next += fimpulse [i + blip_res];
- }
- adjust_impulse();
-
- // volume might require rescaling
- double vol = volume_unit_;
- if ( vol )
- {
- volume_unit_ = 0.0;
- volume_unit( vol );
- }
-}
-
-void Blip_Synth_::volume_unit( double new_unit )
-{
- if ( new_unit != volume_unit_ )
- {
- // use default eq if it hasn't been set yet
- if ( !kernel_unit )
- treble_eq( -8.0 );
-
- volume_unit_ = new_unit;
- double factor = new_unit * (1L << blip_sample_bits) / kernel_unit;
-
- if ( factor > 0.0 )
- {
- int shift = 0;
-
- // if unit is really small, might need to attenuate kernel
- while ( factor < 2.0 )
- {
- shift++;
- factor *= 2.0;
- }
-
- if ( shift )
- {
- kernel_unit >>= shift;
- assert( kernel_unit > 0 ); // fails if volume unit is too low
-
- // keep values positive to avoid round-towards-zero of sign-preserving
- // right shift for negative values
- long offset = 0x8000 + (1 << (shift - 1));
- long offset2 = 0x8000 >> shift;
- for ( int i = impulses_size(); i--; )
- impulses [i] = (short) (((impulses [i] + offset) >> shift) - offset2);
- adjust_impulse();
- }
- }
- delta_factor = (int) floor( factor + 0.5 );
- //printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit );
- }
-}
-#endif
-
-long Blip_Buffer::read_samples( blip_sample_t* BLIP_RESTRICT out, long max_samples, int stereo )
-{
- long count = samples_avail();
- if ( count > max_samples )
- count = max_samples;
-
- if ( count )
- {
- int const bass = BLIP_READER_BASS( *this );
- BLIP_READER_BEGIN( reader, *this );
-
- if ( !stereo )
- {
- for ( blip_long n = count; n; --n )
- {
- blip_long s = BLIP_READER_READ( reader );
- if ( (blip_sample_t) s != s )
- s = 0x7FFF - (s >> 24);
- *out++ = (blip_sample_t) s;
- BLIP_READER_NEXT( reader, bass );
- }
- }
- else
- {
- for ( blip_long n = count; n; --n )
- {
- blip_long s = BLIP_READER_READ( reader );
- if ( (blip_sample_t) s != s )
- s = 0x7FFF - (s >> 24);
- *out = (blip_sample_t) s;
- out += 2;
- BLIP_READER_NEXT( reader, bass );
- }
- }
- BLIP_READER_END( reader, *this );
-
- remove_samples( count );
- }
- return count;
-}
-
-void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
-{
- if ( buffer_size_ == silent_buf_size )
- {
- assert( 0 );
- return;
- }
-
- buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
-
- int const sample_shift = blip_sample_bits - 16;
- int prev = 0;
- while ( count-- )
- {
- blip_long s = (blip_long) *in++ << sample_shift;
- *out += s - prev;
- prev = s;
- ++out;
- }
- *out -= prev;
-}
-
diff --git a/src/console/Blip_Buffer.h b/src/console/Blip_Buffer.h
index 667c3b0730d7..063ed4fe6c32 100644
--- a/src/console/Blip_Buffer.h
+++ b/src/console/Blip_Buffer.h
@@ -25,7 +25,7 @@ public:
typedef const char* blargg_err_t;
// Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults
- // to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there
+ // to 1/4 second), then clear buffer. Returns nullptr on success, otherwise if there
// isn't enough memory, returns error without affecting current buffer setup.
blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 );
diff --git a/src/console/Classic_Emu.cc b/src/console/Classic_Emu.cc
new file mode 100644
index 000000000000..9c22311e9a41
--- /dev/null
+++ b/src/console/Classic_Emu.cc
@@ -0,0 +1,184 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Classic_Emu.h"
+
+#include "Multi_Buffer.h"
+#include <string.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+Classic_Emu::Classic_Emu()
+{
+ buf = 0;
+ stereo_buffer = 0;
+ voice_types = 0;
+
+ // avoid inconsistency in our duplicated constants
+ assert( (int) wave_type == (int) Multi_Buffer::wave_type );
+ assert( (int) noise_type == (int) Multi_Buffer::noise_type );
+ assert( (int) mixed_type == (int) Multi_Buffer::mixed_type );
+}
+
+Classic_Emu::~Classic_Emu()
+{
+ delete stereo_buffer;
+}
+
+void Classic_Emu::set_equalizer_( equalizer_t const& eq )
+{
+ Music_Emu::set_equalizer_( eq );
+ update_eq( eq.treble );
+ if ( buf )
+ buf->bass_freq( (int) equalizer().bass );
+}
+
+blargg_err_t Classic_Emu::set_sample_rate_( long rate )
+{
+ if ( !buf )
+ {
+ if ( !stereo_buffer )
+ CHECK_ALLOC( stereo_buffer = BLARGG_NEW Stereo_Buffer );
+ buf = stereo_buffer;
+ }
+ return buf->set_sample_rate( rate, 1000 / 20 );
+}
+
+void Classic_Emu::mute_voices_( int mask )
+{
+ Music_Emu::mute_voices_( mask );
+ for ( int i = voice_count(); i--; )
+ {
+ if ( mask & (1 << i) )
+ {
+ set_voice( i, 0, 0, 0 );
+ }
+ else
+ {
+ Multi_Buffer::channel_t ch = buf->channel( i, (voice_types ? voice_types [i] : 0) );
+ assert( (ch.center && ch.left && ch.right) ||
+ (!ch.center && !ch.left && !ch.right) ); // all or nothing
+ set_voice( i, ch.center, ch.left, ch.right );
+ }
+ }
+}
+
+void Classic_Emu::change_clock_rate( long rate )
+{
+ clock_rate_ = rate;
+ buf->clock_rate( rate );
+}
+
+blargg_err_t Classic_Emu::setup_buffer( long rate )
+{
+ change_clock_rate( rate );
+ RETURN_ERR( buf->set_channel_count( voice_count() ) );
+ set_equalizer( equalizer() );
+ buf_changed_count = buf->channels_changed_count();
+ return 0;
+}
+
+blargg_err_t Classic_Emu::start_track_( int track )
+{
+ RETURN_ERR( Music_Emu::start_track_( track ) );
+ buf->clear();
+ return 0;
+}
+
+blargg_err_t Classic_Emu::play_( long count, sample_t* out )
+{
+ long remain = count;
+ while ( remain )
+ {
+ remain -= buf->read_samples( &out [count - remain], remain );
+ if ( remain )
+ {
+ if ( buf_changed_count != buf->channels_changed_count() )
+ {
+ buf_changed_count = buf->channels_changed_count();
+ remute_voices();
+ }
+ int msec = buf->length();
+ blip_time_t clocks_emulated = (blargg_long) msec * clock_rate_ / 1000;
+ RETURN_ERR( run_clocks( clocks_emulated, msec ) );
+ assert( clocks_emulated );
+ buf->end_frame( clocks_emulated );
+ }
+ }
+ return 0;
+}
+
+// Rom_Data
+
+blargg_err_t Rom_Data_::load_rom_data_( Data_Reader& in,
+ int header_size, void* header_out, int fill, long pad_size )
+{
+ long file_offset = pad_size - header_size;
+
+ rom_addr = 0;
+ mask = 0;
+ size_ = 0;
+ rom.clear();
+
+ file_size_ = in.remain();
+ if ( file_size_ <= header_size ) // <= because there must be data after header
+ return gme_wrong_file_type;
+ blargg_err_t err = rom.resize( file_offset + file_size_ + pad_size );
+ if ( !err )
+ err = in.read( rom.begin() + file_offset, file_size_ );
+ if ( err )
+ {
+ rom.clear();
+ return err;
+ }
+
+ file_size_ -= header_size;
+ memcpy( header_out, &rom [file_offset], header_size );
+
+ memset( rom.begin() , fill, pad_size );
+ memset( rom.end() - pad_size, fill, pad_size );
+
+ return 0;
+}
+
+void Rom_Data_::set_addr_( long addr, int unit )
+{
+ rom_addr = addr - unit - pad_extra;
+
+ long rounded = (addr + file_size_ + unit - 1) / unit * unit;
+ if ( rounded <= 0 )
+ {
+ rounded = 0;
+ }
+ else
+ {
+ int shift = 0;
+ unsigned long max_addr = (unsigned long) (rounded - 1);
+ while ( max_addr >> shift )
+ shift++;
+ mask = (1L << shift) - 1;
+ }
+
+ if ( addr < 0 )
+ addr = 0;
+ size_ = rounded;
+ if ( rom.resize( rounded - rom_addr + pad_extra ) ) { } // OK if shrink fails
+
+ if ( 0 )
+ {
+ debug_printf( "addr: %X\n", addr );
+ debug_printf( "file_size: %d\n", file_size_ );
+ debug_printf( "rounded: %d\n", rounded );
+ debug_printf( "mask: $%X\n", mask );
+ }
+}
diff --git a/src/console/Classic_Emu.cxx b/src/console/Classic_Emu.cxx
deleted file mode 100644
index 9c22311e9a41..000000000000
--- a/src/console/Classic_Emu.cxx
+++ /dev/null
@@ -1,184 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Classic_Emu.h"
-
-#include "Multi_Buffer.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Classic_Emu::Classic_Emu()
-{
- buf = 0;
- stereo_buffer = 0;
- voice_types = 0;
-
- // avoid inconsistency in our duplicated constants
- assert( (int) wave_type == (int) Multi_Buffer::wave_type );
- assert( (int) noise_type == (int) Multi_Buffer::noise_type );
- assert( (int) mixed_type == (int) Multi_Buffer::mixed_type );
-}
-
-Classic_Emu::~Classic_Emu()
-{
- delete stereo_buffer;
-}
-
-void Classic_Emu::set_equalizer_( equalizer_t const& eq )
-{
- Music_Emu::set_equalizer_( eq );
- update_eq( eq.treble );
- if ( buf )
- buf->bass_freq( (int) equalizer().bass );
-}
-
-blargg_err_t Classic_Emu::set_sample_rate_( long rate )
-{
- if ( !buf )
- {
- if ( !stereo_buffer )
- CHECK_ALLOC( stereo_buffer = BLARGG_NEW Stereo_Buffer );
- buf = stereo_buffer;
- }
- return buf->set_sample_rate( rate, 1000 / 20 );
-}
-
-void Classic_Emu::mute_voices_( int mask )
-{
- Music_Emu::mute_voices_( mask );
- for ( int i = voice_count(); i--; )
- {
- if ( mask & (1 << i) )
- {
- set_voice( i, 0, 0, 0 );
- }
- else
- {
- Multi_Buffer::channel_t ch = buf->channel( i, (voice_types ? voice_types [i] : 0) );
- assert( (ch.center && ch.left && ch.right) ||
- (!ch.center && !ch.left && !ch.right) ); // all or nothing
- set_voice( i, ch.center, ch.left, ch.right );
- }
- }
-}
-
-void Classic_Emu::change_clock_rate( long rate )
-{
- clock_rate_ = rate;
- buf->clock_rate( rate );
-}
-
-blargg_err_t Classic_Emu::setup_buffer( long rate )
-{
- change_clock_rate( rate );
- RETURN_ERR( buf->set_channel_count( voice_count() ) );
- set_equalizer( equalizer() );
- buf_changed_count = buf->channels_changed_count();
- return 0;
-}
-
-blargg_err_t Classic_Emu::start_track_( int track )
-{
- RETURN_ERR( Music_Emu::start_track_( track ) );
- buf->clear();
- return 0;
-}
-
-blargg_err_t Classic_Emu::play_( long count, sample_t* out )
-{
- long remain = count;
- while ( remain )
- {
- remain -= buf->read_samples( &out [count - remain], remain );
- if ( remain )
- {
- if ( buf_changed_count != buf->channels_changed_count() )
- {
- buf_changed_count = buf->channels_changed_count();
- remute_voices();
- }
- int msec = buf->length();
- blip_time_t clocks_emulated = (blargg_long) msec * clock_rate_ / 1000;
- RETURN_ERR( run_clocks( clocks_emulated, msec ) );
- assert( clocks_emulated );
- buf->end_frame( clocks_emulated );
- }
- }
- return 0;
-}
-
-// Rom_Data
-
-blargg_err_t Rom_Data_::load_rom_data_( Data_Reader& in,
- int header_size, void* header_out, int fill, long pad_size )
-{
- long file_offset = pad_size - header_size;
-
- rom_addr = 0;
- mask = 0;
- size_ = 0;
- rom.clear();
-
- file_size_ = in.remain();
- if ( file_size_ <= header_size ) // <= because there must be data after header
- return gme_wrong_file_type;
- blargg_err_t err = rom.resize( file_offset + file_size_ + pad_size );
- if ( !err )
- err = in.read( rom.begin() + file_offset, file_size_ );
- if ( err )
- {
- rom.clear();
- return err;
- }
-
- file_size_ -= header_size;
- memcpy( header_out, &rom [file_offset], header_size );
-
- memset( rom.begin() , fill, pad_size );
- memset( rom.end() - pad_size, fill, pad_size );
-
- return 0;
-}
-
-void Rom_Data_::set_addr_( long addr, int unit )
-{
- rom_addr = addr - unit - pad_extra;
-
- long rounded = (addr + file_size_ + unit - 1) / unit * unit;
- if ( rounded <= 0 )
- {
- rounded = 0;
- }
- else
- {
- int shift = 0;
- unsigned long max_addr = (unsigned long) (rounded - 1);
- while ( max_addr >> shift )
- shift++;
- mask = (1L << shift) - 1;
- }
-
- if ( addr < 0 )
- addr = 0;
- size_ = rounded;
- if ( rom.resize( rounded - rom_addr + pad_extra ) ) { } // OK if shrink fails
-
- if ( 0 )
- {
- debug_printf( "addr: %X\n", addr );
- debug_printf( "file_size: %d\n", file_size_ );
- debug_printf( "rounded: %d\n", rounded );
- debug_printf( "mask: $%X\n", mask );
- }
-}
diff --git a/src/console/Classic_Emu.h b/src/console/Classic_Emu.h
index b2ab769f7e20..94e19e26089b 100644
--- a/src/console/Classic_Emu.h
+++ b/src/console/Classic_Emu.h
@@ -34,7 +34,7 @@ protected:
blargg_err_t play_( long, sample_t* );
private:
Multi_Buffer* buf;
- Multi_Buffer* stereo_buffer; // NULL if using custom buffer
+ Multi_Buffer* stereo_buffer; // nullptr if using custom buffer
long clock_rate_;
unsigned buf_changed_count;
int const* voice_types;
@@ -70,7 +70,7 @@ template<int unit>
class Rom_Data : public Rom_Data_ {
enum { pad_size = unit + pad_extra };
public:
- // Load file data, using already-loaded header 'h' if not NULL. Copy header
+ // Load file data, using already-loaded header 'h' if not nullptr. Copy header
// from loaded file data into *out and fill unmapped bytes with 'fill'.
blargg_err_t load( Data_Reader& in, int header_size, void* header_out, int fill )
{
diff --git a/src/console/Data_Reader.cc b/src/console/Data_Reader.cc
new file mode 100644
index 000000000000..48e834728329
--- /dev/null
+++ b/src/console/Data_Reader.cc
@@ -0,0 +1,315 @@
+// File_Extractor 0.4.0. http://www.slack.net/~ant/
+
+#include "Data_Reader.h"
+
+#include "blargg_endian.h"
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+/* Copyright (C) 2005-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+const char Data_Reader::eof_error [] = "Unexpected end of file";
+
+blargg_err_t Data_Reader::read( void* p, long s )
+{
+ long result = read_avail( p, s );
+ if ( result != s )
+ {
+ if ( result >= 0 && result < s )
+ return eof_error;
+
+ return "Read error";
+ }
+
+ return 0;
+}
+
+blargg_err_t Data_Reader::skip( long count )
+{
+ char buf [512];
+ while ( count )
+ {
+ long n = sizeof buf;
+ if ( n > count )
+ n = count;
+ count -= n;
+ RETURN_ERR( read( buf, n ) );
+ }
+ return 0;
+}
+
+long File_Reader::remain() const { return size() - tell(); }
+
+blargg_err_t File_Reader::skip( long n )
+{
+ assert( n >= 0 );
+ if ( !n )
+ return 0;
+ return seek( tell() + n );
+}
+
+// Subset_Reader
+
+Subset_Reader::Subset_Reader( Data_Reader* dr, long size )
+{
+ in = dr;
+ remain_ = dr->remain();
+ if ( remain_ > size )
+ remain_ = size;
+}
+
+long Subset_Reader::remain() const { return remain_; }
+
+long Subset_Reader::read_avail( void* p, long s )
+{
+ if ( s > remain_ )
+ s = remain_;
+ remain_ -= s;
+ return in->read_avail( p, s );
+}
+
+// Remaining_Reader
+
+Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r )
+{
+ header = (char const*) h;
+ header_end = header + size;
+ in = r;
+}
+
+long Remaining_Reader::remain() const { return header_end - header + in->remain(); }
+
+long Remaining_Reader::read_first( void* out, long count )
+{
+ long first = header_end - header;
+ if ( first )
+ {
+ if ( first > count )
+ first = count;
+ void const* old = header;
+ header += first;
+ memcpy( out, old, first );
+ }
+ return first;
+}
+
+long Remaining_Reader::read_avail( void* out, long count )
+{
+ long first = read_first( out, count );
+ long second = count - first;
+ if ( second )
+ {
+ second = in->read_avail( (char*) out + first, second );
+ if ( second <= 0 )
+ return second;
+ }
+ return first + second;
+}
+
+blargg_err_t Remaining_Reader::read( void* out, long count )
+{
+ long first = read_first( out, count );
+ long second = count - first;
+ if ( !second )
+ return 0;
+ return in->read( (char*) out + first, second );
+}
+
+// Mem_File_Reader
+
+Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
+ begin( (const char*) p ),
+ size_( s )
+{
+ pos = 0;
+}
+
+long Mem_File_Reader::size() const { return size_; }
+
+long Mem_File_Reader::read_avail( void* p, long s )
+{
+ long r = remain();
+ if ( s > r )
+ s = r;
+ memcpy( p, begin + pos, s );
+ pos += s;
+ return s;
+}
+
+long Mem_File_Reader::tell() const { return pos; }
+
+blargg_err_t Mem_File_Reader::seek( long n )
+{
+ if ( n > size_ )
+ return eof_error;
+ pos = n;
+ return 0;
+}
+
+// Callback_Reader
+
+Callback_Reader::Callback_Reader( callback_t c, long size, void* d ) :
+ callback( c ),
+ data( d )
+{
+ remain_ = size;
+}
+
+long Callback_Reader::remain() const { return remain_; }
+
+long Callback_Reader::read_avail( void* out, long count )
+{
+ if ( count > remain_ )
+ count = remain_;
+ if ( Callback_Reader::read( out, count ) )
+ count = -1;
+ return count;
+}
+
+blargg_err_t Callback_Reader::read( void* out, long count )
+{
+ if ( count > remain_ )
+ return eof_error;
+ return callback( data, out, count );
+}
+
+// Std_File_Reader
+
+Std_File_Reader::Std_File_Reader() : file_( 0 ) { }
+
+Std_File_Reader::~Std_File_Reader() { close(); }
+
+blargg_err_t Std_File_Reader::open( const char* path )
+{
+ file_ = fopen( path, "rb" );
+ if ( !file_ )
+ return "Couldn't open file";
+ return 0;
+}
+
+long Std_File_Reader::size() const
+{
+ long pos = tell();
+ fseek( (FILE*) file_, 0, SEEK_END );
+ long result = tell();
+ fseek( (FILE*) file_, pos, SEEK_SET );
+ return result;
+}
+
+long Std_File_Reader::read_avail( void* p, long s )
+{
+ return fread( p, 1, s, (FILE*) file_ );
+}
+
+blargg_err_t Std_File_Reader::read( void* p, long s )
+{
+ if ( s == (long) fread( p, 1, s, (FILE*) file_ ) )
+ return 0;
+ if ( feof( (FILE*) file_ ) )
+ return eof_error;
+ return "Couldn't read from file";
+}
+
+long Std_File_Reader::tell() const { return ftell( (FILE*) file_ ); }
+
+blargg_err_t Std_File_Reader::seek( long n )
+{
+ if ( !fseek( (FILE*) file_, n, SEEK_SET ) )
+ return 0;
+ if ( n > size() )
+ return eof_error;
+ return "Error seeking in file";
+}
+
+void Std_File_Reader::close()
+{
+ if ( file_ )
+ {
+ fclose( (FILE*) file_ );
+ file_ = 0;
+ }
+}
+
+// Gzip_File_Reader
+
+static const char* get_gzip_eof( const char* path, long* eof )
+{
+ FILE* file = fopen( path, "rb" );
+ if ( !file )
+ return "Couldn't open file";
+
+ unsigned char buf[4];
+ if (fread (buf, 2, 1, file) == 1 && buf[0] == 0x1F && buf[1] == 0x8B)
+ {
+ if (fseek (file, -4, SEEK_END) != 0 || fread (buf, 4, 1, file) != 1)
+ goto ERR_CLOSE;
+ *eof = GET_LE32 (buf);
+ }
+ else
+ {
+ long pos;
+ if (fseek (file, 0, SEEK_END) != 0 || (pos = ftell (file) < 0))
+ goto ERR_CLOSE;
+ *eof = pos;
+ }
+
+ fclose (file);
+ return 0;
+
+ERR_CLOSE:
+ fclose (file);
+ return "Couldn't get file size";
+}
+
+Gzip_File_Reader::Gzip_File_Reader() : file_( 0 ) { }
+
+Gzip_File_Reader::~Gzip_File_Reader() { close(); }
+
+blargg_err_t Gzip_File_Reader::open( const char* path )
+{
+ close();
+
+ RETURN_ERR( get_gzip_eof( path, &size_ ) );
+
+ file_ = gzopen( path, "rb" );
+ if ( !file_ )
+ return "Couldn't open file";
+
+ return 0;
+}
+
+long Gzip_File_Reader::size() const { return size_; }
+
+long Gzip_File_Reader::read_avail( void* p, long s ) { return gzread( file_, p, s ); }
+
+long Gzip_File_Reader::tell() const { return gztell( file_ ); }
+
+blargg_err_t Gzip_File_Reader::seek( long n )
+{
+ if ( gzseek( file_, n, SEEK_SET ) >= 0 )
+ return 0;
+ if ( n > size_ )
+ return eof_error;
+ return "Error seeking in file";
+}
+
+void Gzip_File_Reader::close()
+{
+ if ( file_ )
+ {
+ gzclose( file_ );
+ file_ = 0;
+ }
+}
diff --git a/src/console/Data_Reader.cxx b/src/console/Data_Reader.cxx
deleted file mode 100644
index 48e834728329..000000000000
--- a/src/console/Data_Reader.cxx
+++ /dev/null
@@ -1,315 +0,0 @@
-// File_Extractor 0.4.0. http://www.slack.net/~ant/
-
-#include "Data_Reader.h"
-
-#include "blargg_endian.h"
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-
-/* Copyright (C) 2005-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-const char Data_Reader::eof_error [] = "Unexpected end of file";
-
-blargg_err_t Data_Reader::read( void* p, long s )
-{
- long result = read_avail( p, s );
- if ( result != s )
- {
- if ( result >= 0 && result < s )
- return eof_error;
-
- return "Read error";
- }
-
- return 0;
-}
-
-blargg_err_t Data_Reader::skip( long count )
-{
- char buf [512];
- while ( count )
- {
- long n = sizeof buf;
- if ( n > count )
- n = count;
- count -= n;
- RETURN_ERR( read( buf, n ) );
- }
- return 0;
-}
-
-long File_Reader::remain() const { return size() - tell(); }
-
-blargg_err_t File_Reader::skip( long n )
-{
- assert( n >= 0 );
- if ( !n )
- return 0;
- return seek( tell() + n );
-}
-
-// Subset_Reader
-
-Subset_Reader::Subset_Reader( Data_Reader* dr, long size )
-{
- in = dr;
- remain_ = dr->remain();
- if ( remain_ > size )
- remain_ = size;
-}
-
-long Subset_Reader::remain() const { return remain_; }
-
-long Subset_Reader::read_avail( void* p, long s )
-{
- if ( s > remain_ )
- s = remain_;
- remain_ -= s;
- return in->read_avail( p, s );
-}
-
-// Remaining_Reader
-
-Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r )
-{
- header = (char const*) h;
- header_end = header + size;
- in = r;
-}
-
-long Remaining_Reader::remain() const { return header_end - header + in->remain(); }
-
-long Remaining_Reader::read_first( void* out, long count )
-{
- long first = header_end - header;
- if ( first )
- {
- if ( first > count )
- first = count;
- void const* old = header;
- header += first;
- memcpy( out, old, first );
- }
- return first;
-}
-
-long Remaining_Reader::read_avail( void* out, long count )
-{
- long first = read_first( out, count );
- long second = count - first;
- if ( second )
- {
- second = in->read_avail( (char*) out + first, second );
- if ( second <= 0 )
- return second;
- }
- return first + second;
-}
-
-blargg_err_t Remaining_Reader::read( void* out, long count )
-{
- long first = read_first( out, count );
- long second = count - first;
- if ( !second )
- return 0;
- return in->read( (char*) out + first, second );
-}
-
-// Mem_File_Reader
-
-Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
- begin( (const char*) p ),
- size_( s )
-{
- pos = 0;
-}
-
-long Mem_File_Reader::size() const { return size_; }
-
-long Mem_File_Reader::read_avail( void* p, long s )
-{
- long r = remain();
- if ( s > r )
- s = r;
- memcpy( p, begin + pos, s );
- pos += s;
- return s;
-}
-
-long Mem_File_Reader::tell() const { return pos; }
-
-blargg_err_t Mem_File_Reader::seek( long n )
-{
- if ( n > size_ )
- return eof_error;
- pos = n;
- return 0;
-}
-
-// Callback_Reader
-
-Callback_Reader::Callback_Reader( callback_t c, long size, void* d ) :
- callback( c ),
- data( d )
-{
- remain_ = size;
-}
-
-long Callback_Reader::remain() const { return remain_; }
-
-long Callback_Reader::read_avail( void* out, long count )
-{
- if ( count > remain_ )
- count = remain_;
- if ( Callback_Reader::read( out, count ) )
- count = -1;
- return count;
-}
-
-blargg_err_t Callback_Reader::read( void* out, long count )
-{
- if ( count > remain_ )
- return eof_error;
- return callback( data, out, count );
-}
-
-// Std_File_Reader
-
-Std_File_Reader::Std_File_Reader() : file_( 0 ) { }
-
-Std_File_Reader::~Std_File_Reader() { close(); }
-
-blargg_err_t Std_File_Reader::open( const char* path )
-{
- file_ = fopen( path, "rb" );
- if ( !file_ )
- return "Couldn't open file";
- return 0;
-}
-
-long Std_File_Reader::size() const
-{
- long pos = tell();
- fseek( (FILE*) file_, 0, SEEK_END );
- long result = tell();
- fseek( (FILE*) file_, pos, SEEK_SET );
- return result;
-}
-
-long Std_File_Reader::read_avail( void* p, long s )
-{
- return fread( p, 1, s, (FILE*) file_ );
-}
-
-blargg_err_t Std_File_Reader::read( void* p, long s )
-{
- if ( s == (long) fread( p, 1, s, (FILE*) file_ ) )
- return 0;
- if ( feof( (FILE*) file_ ) )
- return eof_error;
- return "Couldn't read from file";
-}
-
-long Std_File_Reader::tell() const { return ftell( (FILE*) file_ ); }
-
-blargg_err_t Std_File_Reader::seek( long n )
-{
- if ( !fseek( (FILE*) file_, n, SEEK_SET ) )
- return 0;
- if ( n > size() )
- return eof_error;
- return "Error seeking in file";
-}
-
-void Std_File_Reader::close()
-{
- if ( file_ )
- {
- fclose( (FILE*) file_ );
- file_ = 0;
- }
-}
-
-// Gzip_File_Reader
-
-static const char* get_gzip_eof( const char* path, long* eof )
-{
- FILE* file = fopen( path, "rb" );
- if ( !file )
- return "Couldn't open file";
-
- unsigned char buf[4];
- if (fread (buf, 2, 1, file) == 1 && buf[0] == 0x1F && buf[1] == 0x8B)
- {
- if (fseek (file, -4, SEEK_END) != 0 || fread (buf, 4, 1, file) != 1)
- goto ERR_CLOSE;
- *eof = GET_LE32 (buf);
- }
- else
- {
- long pos;
- if (fseek (file, 0, SEEK_END) != 0 || (pos = ftell (file) < 0))
- goto ERR_CLOSE;
- *eof = pos;
- }
-
- fclose (file);
- return 0;
-
-ERR_CLOSE:
- fclose (file);
- return "Couldn't get file size";
-}
-
-Gzip_File_Reader::Gzip_File_Reader() : file_( 0 ) { }
-
-Gzip_File_Reader::~Gzip_File_Reader() { close(); }
-
-blargg_err_t Gzip_File_Reader::open( const char* path )
-{
- close();
-
- RETURN_ERR( get_gzip_eof( path, &size_ ) );
-
- file_ = gzopen( path, "rb" );
- if ( !file_ )
- return "Couldn't open file";
-
- return 0;
-}
-
-long Gzip_File_Reader::size() const { return size_; }
-
-long Gzip_File_Reader::read_avail( void* p, long s ) { return gzread( file_, p, s ); }
-
-long Gzip_File_Reader::tell() const { return gztell( file_ ); }
-
-blargg_err_t Gzip_File_Reader::seek( long n )
-{
- if ( gzseek( file_, n, SEEK_SET ) >= 0 )
- return 0;
- if ( n > size_ )
- return eof_error;
- return "Error seeking in file";
-}
-
-void Gzip_File_Reader::close()
-{
- if ( file_ )
- {
- gzclose( file_ );
- file_ = 0;
- }
-}
diff --git a/src/console/Dual_Resampler.cc b/src/console/Dual_Resampler.cc
new file mode 100644
index 000000000000..c6bba8cca4be
--- /dev/null
+++ b/src/console/Dual_Resampler.cc
@@ -0,0 +1,129 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Dual_Resampler.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+Dual_Resampler::Dual_Resampler() { }
+
+Dual_Resampler::~Dual_Resampler() { }
+
+blargg_err_t Dual_Resampler::reset( int pairs )
+{
+ // expand allocations a bit
+ RETURN_ERR( sample_buf.resize( (pairs + (pairs >> 2)) * 2 ) );
+ resize( pairs );
+ resampler_size = oversamples_per_frame + (oversamples_per_frame >> 2);
+ return resampler.buffer_size( resampler_size );
+}
+
+void Dual_Resampler::resize( int pairs )
+{
+ int new_sample_buf_size = pairs * 2;
+ if ( sample_buf_size != new_sample_buf_size )
+ {
+ if ( (unsigned) new_sample_buf_size > sample_buf.size() )
+ {
+ check( false );
+ return;
+ }
+ sample_buf_size = new_sample_buf_size;
+ oversamples_per_frame = int (pairs * resampler.ratio()) * 2 + 2;
+ clear();
+ }
+}
+
+void Dual_Resampler::play_frame_( Blip_Buffer& blip_buf, dsample_t* out )
+{
+ long pair_count = sample_buf_size >> 1;
+ blip_time_t blip_time = blip_buf.count_clocks( pair_count );
+ int sample_count = oversamples_per_frame - resampler.written();
+
+ int new_count = play_frame( blip_time, sample_count, resampler.buffer() );
+ assert( new_count < resampler_size );
+
+ blip_buf.end_frame( blip_time );
+ assert( blip_buf.samples_avail() == pair_count );
+
+ resampler.write( new_count );
+
+ long count = resampler.read( sample_buf.begin(), sample_buf_size );
+ assert( count == (long) sample_buf_size );
+
+ mix_samples( blip_buf, out );
+ blip_buf.remove_samples( pair_count );
+}
+
+void Dual_Resampler::dual_play( long count, dsample_t* out, Blip_Buffer& blip_buf )
+{
+ // empty extra buffer
+ long remain = sample_buf_size - buf_pos;
+ if ( remain )
+ {
+ if ( remain > count )
+ remain = count;
+ count -= remain;
+ memcpy( out, &sample_buf [buf_pos], remain * sizeof *out );
+ out += remain;
+ buf_pos += remain;
+ }
+
+ // entire frames
+ while ( count >= (long) sample_buf_size )
+ {
+ play_frame_( blip_buf, out );
+ out += sample_buf_size;
+ count -= sample_buf_size;
+ }
+
+ // extra
+ if ( count )
+ {
+ play_frame_( blip_buf, sample_buf.begin() );
+ buf_pos = count;
+ memcpy( out, sample_buf.begin(), count * sizeof *out );
+ out += count;
+ }
+}
+
+void Dual_Resampler::mix_samples( Blip_Buffer& blip_buf, dsample_t* out )
+{
+ Blip_Reader sn;
+ int bass = sn.begin( blip_buf );
+ const dsample_t* in = sample_buf.begin();
+
+ for ( int n = sample_buf_size >> 1; n--; )
+ {
+ int s = sn.read();
+ blargg_long l = (blargg_long) in [0] * 2 + s;
+ if ( (int16_t) l != l )
+ l = 0x7FFF - (l >> 24);
+
+ sn.next( bass );
+ blargg_long r = (blargg_long) in [1] * 2 + s;
+ if ( (int16_t) r != r )
+ r = 0x7FFF - (r >> 24);
+
+ in += 2;
+ out [0] = l;
+ out [1] = r;
+ out += 2;
+ }
+
+ sn.end( blip_buf );
+}
+
diff --git a/src/console/Dual_Resampler.cxx b/src/console/Dual_Resampler.cxx
deleted file mode 100644
index 7a2caa4db4e7..000000000000
--- a/src/console/Dual_Resampler.cxx
+++ /dev/null
@@ -1,131 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Dual_Resampler.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-unsigned const resampler_extra = 256;
-
-Dual_Resampler::Dual_Resampler() { }
-
-Dual_Resampler::~Dual_Resampler() { }
-
-blargg_err_t Dual_Resampler::reset( int pairs )
-{
- // expand allocations a bit
- RETURN_ERR( sample_buf.resize( (pairs + (pairs >> 2)) * 2 ) );
- resize( pairs );
- resampler_size = oversamples_per_frame + (oversamples_per_frame >> 2);
- return resampler.buffer_size( resampler_size );
-}
-
-void Dual_Resampler::resize( int pairs )
-{
- int new_sample_buf_size = pairs * 2;
- if ( sample_buf_size != new_sample_buf_size )
- {
- if ( (unsigned) new_sample_buf_size > sample_buf.size() )
- {
- check( false );
- return;
- }
- sample_buf_size = new_sample_buf_size;
- oversamples_per_frame = int (pairs * resampler.ratio()) * 2 + 2;
- clear();
- }
-}
-
-void Dual_Resampler::play_frame_( Blip_Buffer& blip_buf, dsample_t* out )
-{
- long pair_count = sample_buf_size >> 1;
- blip_time_t blip_time = blip_buf.count_clocks( pair_count );
- int sample_count = oversamples_per_frame - resampler.written();
-
- int new_count = play_frame( blip_time, sample_count, resampler.buffer() );
- assert( new_count < resampler_size );
-
- blip_buf.end_frame( blip_time );
- assert( blip_buf.samples_avail() == pair_count );
-
- resampler.write( new_count );
-
- long count = resampler.read( sample_buf.begin(), sample_buf_size );
- assert( count == (long) sample_buf_size );
-
- mix_samples( blip_buf, out );
- blip_buf.remove_samples( pair_count );
-}
-
-void Dual_Resampler::dual_play( long count, dsample_t* out, Blip_Buffer& blip_buf )
-{
- // empty extra buffer
- long remain = sample_buf_size - buf_pos;
- if ( remain )
- {
- if ( remain > count )
- remain = count;
- count -= remain;
- memcpy( out, &sample_buf [buf_pos], remain * sizeof *out );
- out += remain;
- buf_pos += remain;
- }
-
- // entire frames
- while ( count >= (long) sample_buf_size )
- {
- play_frame_( blip_buf, out );
- out += sample_buf_size;
- count -= sample_buf_size;
- }
-
- // extra
- if ( count )
- {
- play_frame_( blip_buf, sample_buf.begin() );
- buf_pos = count;
- memcpy( out, sample_buf.begin(), count * sizeof *out );
- out += count;
- }
-}
-
-void Dual_Resampler::mix_samples( Blip_Buffer& blip_buf, dsample_t* out )
-{
- Blip_Reader sn;
- int bass = sn.begin( blip_buf );
- const dsample_t* in = sample_buf.begin();
-
- for ( int n = sample_buf_size >> 1; n--; )
- {
- int s = sn.read();
- blargg_long l = (blargg_long) in [0] * 2 + s;
- if ( (int16_t) l != l )
- l = 0x7FFF - (l >> 24);
-
- sn.next( bass );
- blargg_long r = (blargg_long) in [1] * 2 + s;
- if ( (int16_t) r != r )
- r = 0x7FFF - (r >> 24);
-
- in += 2;
- out [0] = l;
- out [1] = r;
- out += 2;
- }
-
- sn.end( blip_buf );
-}
-
diff --git a/src/console/Effects_Buffer.cc b/src/console/Effects_Buffer.cc
new file mode 100644
index 000000000000..a4e0f93dc58f
--- /dev/null
+++ b/src/console/Effects_Buffer.cc
@@ -0,0 +1,529 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Effects_Buffer.h"
+
+#include <string.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+#ifdef BLARGG_ENABLE_OPTIMIZER
+ #include BLARGG_ENABLE_OPTIMIZER
+#endif
+
+typedef blargg_long fixed_t;
+
+#define TO_FIXED( f ) fixed_t ((f) * (1L << 15) + 0.5)
+#define FMUL( x, y ) (((x) * (y)) >> 15)
+
+const unsigned echo_size = 4096;
+const unsigned echo_mask = echo_size - 1;
+BOOST_STATIC_ASSERT( (echo_size & echo_mask) == 0 ); // must be power of 2
+
+const unsigned reverb_size = 8192 * 2;
+const unsigned reverb_mask = reverb_size - 1;
+BOOST_STATIC_ASSERT( (reverb_size & reverb_mask) == 0 ); // must be power of 2
+
+Effects_Buffer::config_t::config_t()
+{
+ pan_1 = -0.15f;
+ pan_2 = 0.15f;
+ reverb_delay = 88.0f;
+ reverb_level = 0.12f;
+ echo_delay = 61.0f;
+ echo_level = 0.10f;
+ delay_variance = 18.0f;
+ effects_enabled = false;
+}
+
+void Effects_Buffer::set_depth( double d )
+{
+ float f = (float) d;
+ config_t c;
+ c.pan_1 = -0.6f * f;
+ c.pan_2 = 0.6f * f;
+ c.reverb_delay = 880 * 0.1f;
+ c.echo_delay = 610 * 0.1f;
+ if ( f > 0.5 )
+ f = 0.5; // TODO: more linear reduction of extreme reverb/echo
+ c.reverb_level = 0.5f * f;
+ c.echo_level = 0.30f * f;
+ c.delay_variance = 180 * 0.1f;
+ c.effects_enabled = (d > 0.0f);
+ config( c );
+}
+
+Effects_Buffer::Effects_Buffer( bool center_only ) : Multi_Buffer( 2 )
+{
+ buf_count = center_only ? max_buf_count - 4 : max_buf_count;
+
+ echo_pos = 0;
+ reverb_pos = 0;
+
+ stereo_remain = 0;
+ effect_remain = 0;
+ effects_enabled = false;
+ set_depth( 0 );
+}
+
+Effects_Buffer::~Effects_Buffer() { }
+
+blargg_err_t Effects_Buffer::set_sample_rate( long rate, int msec )
+{
+ if ( !echo_buf.size() )
+ RETURN_ERR( echo_buf.resize( echo_size ) );
+
+ if ( !reverb_buf.size() )
+ RETURN_ERR( reverb_buf.resize( reverb_size ) );
+
+ for ( int i = 0; i < buf_count; i++ )
+ RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
+
+ config( config_ );
+ clear();
+
+ return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
+}
+
+void Effects_Buffer::clock_rate( long rate )
+{
+ for ( int i = 0; i < buf_count; i++ )
+ bufs [i].clock_rate( rate );
+}
+
+void Effects_Buffer::bass_freq( int freq )
+{
+ for ( int i = 0; i < buf_count; i++ )
+ bufs [i].bass_freq( freq );
+}
+
+void Effects_Buffer::clear()
+{
+ stereo_remain = 0;
+ effect_remain = 0;
+ if ( echo_buf.size() )
+ memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
+
+ if ( reverb_buf.size() )
+ memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
+
+ for ( int i = 0; i < buf_count; i++ )
+ bufs [i].clear();
+}
+
+inline int pin_range( int n, int max, int min = 0 )
+{
+ if ( n < min )
+ return min;
+ if ( n > max )
+ return max;
+ return n;
+}
+
+void Effects_Buffer::config( const config_t& cfg )
+{
+ channels_changed();
+
+ // clear echo and reverb buffers
+ if ( !config_.effects_enabled && cfg.effects_enabled && echo_buf.size() )
+ {
+ memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
+ memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
+ }
+
+ config_ = cfg;
+
+ if ( config_.effects_enabled )
+ {
+ // convert to internal format
+
+ chans.pan_1_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_1 );
+ chans.pan_1_levels [1] = TO_FIXED( 2 ) - chans.pan_1_levels [0];
+
+ chans.pan_2_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_2 );
+ chans.pan_2_levels [1] = TO_FIXED( 2 ) - chans.pan_2_levels [0];
+
+ chans.reverb_level = TO_FIXED( config_.reverb_level );
+ chans.echo_level = TO_FIXED( config_.echo_level );
+
+ int delay_offset = int (1.0 / 2000 * config_.delay_variance * sample_rate());
+
+ int reverb_sample_delay = int (1.0 / 1000 * config_.reverb_delay * sample_rate());
+ chans.reverb_delay_l = pin_range( reverb_size -
+ (reverb_sample_delay - delay_offset) * 2, reverb_size - 2, 0 );
+ chans.reverb_delay_r = pin_range( reverb_size + 1 -
+ (reverb_sample_delay + delay_offset) * 2, reverb_size - 1, 1 );
+
+ int echo_sample_delay = int (1.0 / 1000 * config_.echo_delay * sample_rate());
+ chans.echo_delay_l = pin_range( echo_size - 1 - (echo_sample_delay - delay_offset),
+ echo_size - 1 );
+ chans.echo_delay_r = pin_range( echo_size - 1 - (echo_sample_delay + delay_offset),
+ echo_size - 1 );
+
+ chan_types [0].center = &bufs [0];
+ chan_types [0].left = &bufs [3];
+ chan_types [0].right = &bufs [4];
+
+ chan_types [1].center = &bufs [1];
+ chan_types [1].left = &bufs [3];
+ chan_types [1].right = &bufs [4];
+
+ chan_types [2].center = &bufs [2];
+ chan_types [2].left = &bufs [5];
+ chan_types [2].right = &bufs [6];
+ assert( 2 < chan_types_count );
+ }
+ else
+ {
+ // set up outputs
+ for ( unsigned i = 0; i < chan_types_count; i++ )
+ {
+ channel_t& c = chan_types [i];
+ c.center = &bufs [0];
+ c.left = &bufs [1];
+ c.right = &bufs [2];
+ }
+ }
+
+ if ( buf_count < max_buf_count )
+ {
+ for ( int i = 0; i < chan_types_count; i++ )
+ {
+ channel_t& c = chan_types [i];
+ c.left = c.center;
+ c.right = c.center;
+ }
+ }
+}
+
+Effects_Buffer::channel_t Effects_Buffer::channel( int i, int type )
+{
+ int out = 2;
+ if ( !type )
+ {
+ out = i % 5;
+ if ( out > 2 )
+ out = 2;
+ }
+ else if ( !(type & noise_type) && (type & type_index_mask) % 3 != 0 )
+ {
+ out = type & 1;
+ }
+ return chan_types [out];
+}
+
+void Effects_Buffer::end_frame( blip_time_t clock_count )
+{
+ int bufs_used = 0;
+ for ( int i = 0; i < buf_count; i++ )
+ {
+ bufs_used |= bufs [i].clear_modified() << i;
+ bufs [i].end_frame( clock_count );
+ }
+
+ int stereo_mask = (config_.effects_enabled ? 0x78 : 0x06);
+ if ( (bufs_used & stereo_mask) && buf_count == max_buf_count )
+ stereo_remain = bufs [0].samples_avail() + bufs [0].output_latency();
+
+ if ( effects_enabled || config_.effects_enabled )
+ effect_remain = bufs [0].samples_avail() + bufs [0].output_latency();
+
+ effects_enabled = config_.effects_enabled;
+}
+
+long Effects_Buffer::samples_avail() const
+{
+ return bufs [0].samples_avail() * 2;
+}
+
+long Effects_Buffer::read_samples( blip_sample_t* out, long total_samples )
+{
+ require( total_samples % 2 == 0 ); // count must be even
+
+ long remain = bufs [0].samples_avail();
+ if ( remain > (total_samples >> 1) )
+ remain = (total_samples >> 1);
+ total_samples = remain;
+ while ( remain )
+ {
+ int active_bufs = buf_count;
+ long count = remain;
+
+ // optimizing mixing to skip any channels which had nothing added
+ if ( effect_remain )
+ {
+ if ( count > effect_remain )
+ count = effect_remain;
+
+ if ( stereo_remain )
+ {
+ mix_enhanced( out, count );
+ }
+ else
+ {
+ mix_mono_enhanced( out, count );
+ active_bufs = 3;
+ }
+ }
+ else if ( stereo_remain )
+ {
+ mix_stereo( out, count );
+ active_bufs = 3;
+ }
+ else
+ {
+ mix_mono( out, count );
+ active_bufs = 1;
+ }
+
+ out += count * 2;
+ remain -= count;
+
+ stereo_remain -= count;
+ if ( stereo_remain < 0 )
+ stereo_remain = 0;
+
+ effect_remain -= count;
+ if ( effect_remain < 0 )
+ effect_remain = 0;
+
+ for ( int i = 0; i < buf_count; i++ )
+ {
+ if ( i < active_bufs )
+ bufs [i].remove_samples( count );
+ else
+ bufs [i].remove_silence( count ); // keep time synchronized
+ }
+ }
+
+ return total_samples * 2;
+}
+
+void Effects_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
+{
+ blip_sample_t* BLIP_RESTRICT out = out_;
+ int const bass = BLIP_READER_BASS( bufs [0] );
+ BLIP_READER_BEGIN( c, bufs [0] );
+
+ // unrolled loop
+ for ( blargg_long n = count >> 1; n; --n )
+ {
+ blargg_long cs0 = BLIP_READER_READ( c );
+ BLIP_READER_NEXT( c, bass );
+
+ blargg_long cs1 = BLIP_READER_READ( c );
+ BLIP_READER_NEXT( c, bass );
+
+ if ( (int16_t) cs0 != cs0 )
+ cs0 = 0x7FFF - (cs0 >> 24);
+ ((uint32_t*) out) [0] = ((uint16_t) cs0) | (cs0 << 16);
+
+ if ( (int16_t) cs1 != cs1 )
+ cs1 = 0x7FFF - (cs1 >> 24);
+ ((uint32_t*) out) [1] = ((uint16_t) cs1) | (cs1 << 16);
+ out += 4;
+ }
+
+ if ( count & 1 )
+ {
+ int s = BLIP_READER_READ( c );
+ BLIP_READER_NEXT( c, bass );
+ out [0] = s;
+ out [1] = s;
+ if ( (int16_t) s != s )
+ {
+ s = 0x7FFF - (s >> 24);
+ out [0] = s;
+ out [1] = s;
+ }
+ }
+
+ BLIP_READER_END( c, bufs [0] );
+}
+
+void Effects_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count )
+{
+ blip_sample_t* BLIP_RESTRICT out = out_;
+ int const bass = BLIP_READER_BASS( bufs [0] );
+ BLIP_READER_BEGIN( c, bufs [0] );
+ BLIP_READER_BEGIN( l, bufs [1] );
+ BLIP_READER_BEGIN( r, bufs [2] );
+
+ while ( count-- )
+ {
+ int cs = BLIP_READER_READ( c );
+ BLIP_READER_NEXT( c, bass );
+ int left = cs + BLIP_READER_READ( l );
+ int right = cs + BLIP_READER_READ( r );
+ BLIP_READER_NEXT( l, bass );
+ BLIP_READER_NEXT( r, bass );
+
+ if ( (int16_t) left != left )
+ left = 0x7FFF - (left >> 24);
+
+ out [0] = left;
+ out [1] = right;
+
+ out += 2;
+
+ if ( (int16_t) right != right )
+ out [-1] = 0x7FFF - (right >> 24);
+ }
+
+ BLIP_READER_END( r, bufs [2] );
+ BLIP_READER_END( l, bufs [1] );
+ BLIP_READER_END( c, bufs [0] );
+}
+
+void Effects_Buffer::mix_mono_enhanced( blip_sample_t* out_, blargg_long count )
+{
+ blip_sample_t* BLIP_RESTRICT out = out_;
+ int const bass = BLIP_READER_BASS( bufs [2] );
+ BLIP_READER_BEGIN( center, bufs [2] );
+ BLIP_READER_BEGIN( sq1, bufs [0] );
+ BLIP_READER_BEGIN( sq2, bufs [1] );
+
+ blip_sample_t* const reverb_buf = this->reverb_buf.begin();
+ blip_sample_t* const echo_buf = this->echo_buf.begin();
+ int echo_pos = this->echo_pos;
+ int reverb_pos = this->reverb_pos;
+
+ while ( count-- )
+ {
+ int sum1_s = BLIP_READER_READ( sq1 );
+ int sum2_s = BLIP_READER_READ( sq2 );
+
+ BLIP_READER_NEXT( sq1, bass );
+ BLIP_READER_NEXT( sq2, bass );
+
+ int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) +
+ FMUL( sum2_s, chans.pan_2_levels [0] ) +
+ reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask];
+
+ int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) +
+ FMUL( sum2_s, chans.pan_2_levels [1] ) +
+ reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask];
+
+ fixed_t reverb_level = chans.reverb_level;
+ reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level );
+ reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level );
+ reverb_pos = (reverb_pos + 2) & reverb_mask;
+
+ int sum3_s = BLIP_READER_READ( center );
+ BLIP_READER_NEXT( center, bass );
+
+ int left = new_reverb_l + sum3_s + FMUL( chans.echo_level,
+ echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
+ int right = new_reverb_r + sum3_s + FMUL( chans.echo_level,
+ echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
+
+ echo_buf [echo_pos] = sum3_s;
+ echo_pos = (echo_pos + 1) & echo_mask;
+
+ if ( (int16_t) left != left )
+ left = 0x7FFF - (left >> 24);
+
+ out [0] = left;
+ out [1] = right;
+
+ out += 2;
+
+ if ( (int16_t) right != right )
+ out [-1] = 0x7FFF - (right >> 24);
+ }
+ this->reverb_pos = reverb_pos;
+ this->echo_pos = echo_pos;
+
+ BLIP_READER_END( sq1, bufs [0] );
+ BLIP_READER_END( sq2, bufs [1] );
+ BLIP_READER_END( center, bufs [2] );
+}
+
+void Effects_Buffer::mix_enhanced( blip_sample_t* out_, blargg_long count )
+{
+ blip_sample_t* BLIP_RESTRICT out = out_;
+ int const bass = BLIP_READER_BASS( bufs [2] );
+ BLIP_READER_BEGIN( center, bufs [2] );
+ BLIP_READER_BEGIN( l1, bufs [3] );
+ BLIP_READER_BEGIN( r1, bufs [4] );
+ BLIP_READER_BEGIN( l2, bufs [5] );
+ BLIP_READER_BEGIN( r2, bufs [6] );
+ BLIP_READER_BEGIN( sq1, bufs [0] );
+ BLIP_READER_BEGIN( sq2, bufs [1] );
+
+ blip_sample_t* const reverb_buf = this->reverb_buf.begin();
+ blip_sample_t* const echo_buf = this->echo_buf.begin();
+ int echo_pos = this->echo_pos;
+ int reverb_pos = this->reverb_pos;
+
+ while ( count-- )
+ {
+ int sum1_s = BLIP_READER_READ( sq1 );
+ int sum2_s = BLIP_READER_READ( sq2 );
+
+ BLIP_READER_NEXT( sq1, bass );
+ BLIP_READER_NEXT( sq2, bass );
+
+ int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) +
+ FMUL( sum2_s, chans.pan_2_levels [0] ) + BLIP_READER_READ( l1 ) +
+ reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask];
+
+ int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) +
+ FMUL( sum2_s, chans.pan_2_levels [1] ) + BLIP_READER_READ( r1 ) +
+ reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask];
+
+ BLIP_READER_NEXT( l1, bass );
+ BLIP_READER_NEXT( r1, bass );
+
+ fixed_t reverb_level = chans.reverb_level;
+ reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level );
+ reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level );
+ reverb_pos = (reverb_pos + 2) & reverb_mask;
+
+ int sum3_s = BLIP_READER_READ( center );
+ BLIP_READER_NEXT( center, bass );
+
+ int left = new_reverb_l + sum3_s + BLIP_READER_READ( l2 ) + FMUL( chans.echo_level,
+ echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
+ int right = new_reverb_r + sum3_s + BLIP_READER_READ( r2 ) + FMUL( chans.echo_level,
+ echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
+
+ BLIP_READER_NEXT( l2, bass );
+ BLIP_READER_NEXT( r2, bass );
+
+ echo_buf [echo_pos] = sum3_s;
+ echo_pos = (echo_pos + 1) & echo_mask;
+
+ if ( (int16_t) left != left )
+ left = 0x7FFF - (left >> 24);
+
+ out [0] = left;
+ out [1] = right;
+
+ out += 2;
+
+ if ( (int16_t) right != right )
+ out [-1] = 0x7FFF - (right >> 24);
+ }
+ this->reverb_pos = reverb_pos;
+ this->echo_pos = echo_pos;
+
+ BLIP_READER_END( l1, bufs [3] );
+ BLIP_READER_END( r1, bufs [4] );
+ BLIP_READER_END( l2, bufs [5] );
+ BLIP_READER_END( r2, bufs [6] );
+ BLIP_READER_END( sq1, bufs [0] );
+ BLIP_READER_END( sq2, bufs [1] );
+ BLIP_READER_END( center, bufs [2] );
+}
+
diff --git a/src/console/Effects_Buffer.cxx b/src/console/Effects_Buffer.cxx
deleted file mode 100644
index a4e0f93dc58f..000000000000
--- a/src/console/Effects_Buffer.cxx
+++ /dev/null
@@ -1,529 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Effects_Buffer.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-typedef blargg_long fixed_t;
-
-#define TO_FIXED( f ) fixed_t ((f) * (1L << 15) + 0.5)
-#define FMUL( x, y ) (((x) * (y)) >> 15)
-
-const unsigned echo_size = 4096;
-const unsigned echo_mask = echo_size - 1;
-BOOST_STATIC_ASSERT( (echo_size & echo_mask) == 0 ); // must be power of 2
-
-const unsigned reverb_size = 8192 * 2;
-const unsigned reverb_mask = reverb_size - 1;
-BOOST_STATIC_ASSERT( (reverb_size & reverb_mask) == 0 ); // must be power of 2
-
-Effects_Buffer::config_t::config_t()
-{
- pan_1 = -0.15f;
- pan_2 = 0.15f;
- reverb_delay = 88.0f;
- reverb_level = 0.12f;
- echo_delay = 61.0f;
- echo_level = 0.10f;
- delay_variance = 18.0f;
- effects_enabled = false;
-}
-
-void Effects_Buffer::set_depth( double d )
-{
- float f = (float) d;
- config_t c;
- c.pan_1 = -0.6f * f;
- c.pan_2 = 0.6f * f;
- c.reverb_delay = 880 * 0.1f;
- c.echo_delay = 610 * 0.1f;
- if ( f > 0.5 )
- f = 0.5; // TODO: more linear reduction of extreme reverb/echo
- c.reverb_level = 0.5f * f;
- c.echo_level = 0.30f * f;
- c.delay_variance = 180 * 0.1f;
- c.effects_enabled = (d > 0.0f);
- config( c );
-}
-
-Effects_Buffer::Effects_Buffer( bool center_only ) : Multi_Buffer( 2 )
-{
- buf_count = center_only ? max_buf_count - 4 : max_buf_count;
-
- echo_pos = 0;
- reverb_pos = 0;
-
- stereo_remain = 0;
- effect_remain = 0;
- effects_enabled = false;
- set_depth( 0 );
-}
-
-Effects_Buffer::~Effects_Buffer() { }
-
-blargg_err_t Effects_Buffer::set_sample_rate( long rate, int msec )
-{
- if ( !echo_buf.size() )
- RETURN_ERR( echo_buf.resize( echo_size ) );
-
- if ( !reverb_buf.size() )
- RETURN_ERR( reverb_buf.resize( reverb_size ) );
-
- for ( int i = 0; i < buf_count; i++ )
- RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
-
- config( config_ );
- clear();
-
- return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
-}
-
-void Effects_Buffer::clock_rate( long rate )
-{
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clock_rate( rate );
-}
-
-void Effects_Buffer::bass_freq( int freq )
-{
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].bass_freq( freq );
-}
-
-void Effects_Buffer::clear()
-{
- stereo_remain = 0;
- effect_remain = 0;
- if ( echo_buf.size() )
- memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
-
- if ( reverb_buf.size() )
- memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
-
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clear();
-}
-
-inline int pin_range( int n, int max, int min = 0 )
-{
- if ( n < min )
- return min;
- if ( n > max )
- return max;
- return n;
-}
-
-void Effects_Buffer::config( const config_t& cfg )
-{
- channels_changed();
-
- // clear echo and reverb buffers
- if ( !config_.effects_enabled && cfg.effects_enabled && echo_buf.size() )
- {
- memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
- memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
- }
-
- config_ = cfg;
-
- if ( config_.effects_enabled )
- {
- // convert to internal format
-
- chans.pan_1_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_1 );
- chans.pan_1_levels [1] = TO_FIXED( 2 ) - chans.pan_1_levels [0];
-
- chans.pan_2_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_2 );
- chans.pan_2_levels [1] = TO_FIXED( 2 ) - chans.pan_2_levels [0];
-
- chans.reverb_level = TO_FIXED( config_.reverb_level );
- chans.echo_level = TO_FIXED( config_.echo_level );
-
- int delay_offset = int (1.0 / 2000 * config_.delay_variance * sample_rate());
-
- int reverb_sample_delay = int (1.0 / 1000 * config_.reverb_delay * sample_rate());
- chans.reverb_delay_l = pin_range( reverb_size -
- (reverb_sample_delay - delay_offset) * 2, reverb_size - 2, 0 );
- chans.reverb_delay_r = pin_range( reverb_size + 1 -
- (reverb_sample_delay + delay_offset) * 2, reverb_size - 1, 1 );
-
- int echo_sample_delay = int (1.0 / 1000 * config_.echo_delay * sample_rate());
- chans.echo_delay_l = pin_range( echo_size - 1 - (echo_sample_delay - delay_offset),
- echo_size - 1 );
- chans.echo_delay_r = pin_range( echo_size - 1 - (echo_sample_delay + delay_offset),
- echo_size - 1 );
-
- chan_types [0].center = &bufs [0];
- chan_types [0].left = &bufs [3];
- chan_types [0].right = &bufs [4];
-
- chan_types [1].center = &bufs [1];
- chan_types [1].left = &bufs [3];
- chan_types [1].right = &bufs [4];
-
- chan_types [2].center = &bufs [2];
- chan_types [2].left = &bufs [5];
- chan_types [2].right = &bufs [6];
- assert( 2 < chan_types_count );
- }
- else
- {
- // set up outputs
- for ( unsigned i = 0; i < chan_types_count; i++ )
- {
- channel_t& c = chan_types [i];
- c.center = &bufs [0];
- c.left = &bufs [1];
- c.right = &bufs [2];
- }
- }
-
- if ( buf_count < max_buf_count )
- {
- for ( int i = 0; i < chan_types_count; i++ )
- {
- channel_t& c = chan_types [i];
- c.left = c.center;
- c.right = c.center;
- }
- }
-}
-
-Effects_Buffer::channel_t Effects_Buffer::channel( int i, int type )
-{
- int out = 2;
- if ( !type )
- {
- out = i % 5;
- if ( out > 2 )
- out = 2;
- }
- else if ( !(type & noise_type) && (type & type_index_mask) % 3 != 0 )
- {
- out = type & 1;
- }
- return chan_types [out];
-}
-
-void Effects_Buffer::end_frame( blip_time_t clock_count )
-{
- int bufs_used = 0;
- for ( int i = 0; i < buf_count; i++ )
- {
- bufs_used |= bufs [i].clear_modified() << i;
- bufs [i].end_frame( clock_count );
- }
-
- int stereo_mask = (config_.effects_enabled ? 0x78 : 0x06);
- if ( (bufs_used & stereo_mask) && buf_count == max_buf_count )
- stereo_remain = bufs [0].samples_avail() + bufs [0].output_latency();
-
- if ( effects_enabled || config_.effects_enabled )
- effect_remain = bufs [0].samples_avail() + bufs [0].output_latency();
-
- effects_enabled = config_.effects_enabled;
-}
-
-long Effects_Buffer::samples_avail() const
-{
- return bufs [0].samples_avail() * 2;
-}
-
-long Effects_Buffer::read_samples( blip_sample_t* out, long total_samples )
-{
- require( total_samples % 2 == 0 ); // count must be even
-
- long remain = bufs [0].samples_avail();
- if ( remain > (total_samples >> 1) )
- remain = (total_samples >> 1);
- total_samples = remain;
- while ( remain )
- {
- int active_bufs = buf_count;
- long count = remain;
-
- // optimizing mixing to skip any channels which had nothing added
- if ( effect_remain )
- {
- if ( count > effect_remain )
- count = effect_remain;
-
- if ( stereo_remain )
- {
- mix_enhanced( out, count );
- }
- else
- {
- mix_mono_enhanced( out, count );
- active_bufs = 3;
- }
- }
- else if ( stereo_remain )
- {
- mix_stereo( out, count );
- active_bufs = 3;
- }
- else
- {
- mix_mono( out, count );
- active_bufs = 1;
- }
-
- out += count * 2;
- remain -= count;
-
- stereo_remain -= count;
- if ( stereo_remain < 0 )
- stereo_remain = 0;
-
- effect_remain -= count;
- if ( effect_remain < 0 )
- effect_remain = 0;
-
- for ( int i = 0; i < buf_count; i++ )
- {
- if ( i < active_bufs )
- bufs [i].remove_samples( count );
- else
- bufs [i].remove_silence( count ); // keep time synchronized
- }
- }
-
- return total_samples * 2;
-}
-
-void Effects_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [0] );
- BLIP_READER_BEGIN( c, bufs [0] );
-
- // unrolled loop
- for ( blargg_long n = count >> 1; n; --n )
- {
- blargg_long cs0 = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
-
- blargg_long cs1 = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
-
- if ( (int16_t) cs0 != cs0 )
- cs0 = 0x7FFF - (cs0 >> 24);
- ((uint32_t*) out) [0] = ((uint16_t) cs0) | (cs0 << 16);
-
- if ( (int16_t) cs1 != cs1 )
- cs1 = 0x7FFF - (cs1 >> 24);
- ((uint32_t*) out) [1] = ((uint16_t) cs1) | (cs1 << 16);
- out += 4;
- }
-
- if ( count & 1 )
- {
- int s = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
- out [0] = s;
- out [1] = s;
- if ( (int16_t) s != s )
- {
- s = 0x7FFF - (s >> 24);
- out [0] = s;
- out [1] = s;
- }
- }
-
- BLIP_READER_END( c, bufs [0] );
-}
-
-void Effects_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [0] );
- BLIP_READER_BEGIN( c, bufs [0] );
- BLIP_READER_BEGIN( l, bufs [1] );
- BLIP_READER_BEGIN( r, bufs [2] );
-
- while ( count-- )
- {
- int cs = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
- int left = cs + BLIP_READER_READ( l );
- int right = cs + BLIP_READER_READ( r );
- BLIP_READER_NEXT( l, bass );
- BLIP_READER_NEXT( r, bass );
-
- if ( (int16_t) left != left )
- left = 0x7FFF - (left >> 24);
-
- out [0] = left;
- out [1] = right;
-
- out += 2;
-
- if ( (int16_t) right != right )
- out [-1] = 0x7FFF - (right >> 24);
- }
-
- BLIP_READER_END( r, bufs [2] );
- BLIP_READER_END( l, bufs [1] );
- BLIP_READER_END( c, bufs [0] );
-}
-
-void Effects_Buffer::mix_mono_enhanced( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [2] );
- BLIP_READER_BEGIN( center, bufs [2] );
- BLIP_READER_BEGIN( sq1, bufs [0] );
- BLIP_READER_BEGIN( sq2, bufs [1] );
-
- blip_sample_t* const reverb_buf = this->reverb_buf.begin();
- blip_sample_t* const echo_buf = this->echo_buf.begin();
- int echo_pos = this->echo_pos;
- int reverb_pos = this->reverb_pos;
-
- while ( count-- )
- {
- int sum1_s = BLIP_READER_READ( sq1 );
- int sum2_s = BLIP_READER_READ( sq2 );
-
- BLIP_READER_NEXT( sq1, bass );
- BLIP_READER_NEXT( sq2, bass );
-
- int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) +
- FMUL( sum2_s, chans.pan_2_levels [0] ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask];
-
- int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) +
- FMUL( sum2_s, chans.pan_2_levels [1] ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask];
-
- fixed_t reverb_level = chans.reverb_level;
- reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level );
- reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level );
- reverb_pos = (reverb_pos + 2) & reverb_mask;
-
- int sum3_s = BLIP_READER_READ( center );
- BLIP_READER_NEXT( center, bass );
-
- int left = new_reverb_l + sum3_s + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
- int right = new_reverb_r + sum3_s + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
-
- echo_buf [echo_pos] = sum3_s;
- echo_pos = (echo_pos + 1) & echo_mask;
-
- if ( (int16_t) left != left )
- left = 0x7FFF - (left >> 24);
-
- out [0] = left;
- out [1] = right;
-
- out += 2;
-
- if ( (int16_t) right != right )
- out [-1] = 0x7FFF - (right >> 24);
- }
- this->reverb_pos = reverb_pos;
- this->echo_pos = echo_pos;
-
- BLIP_READER_END( sq1, bufs [0] );
- BLIP_READER_END( sq2, bufs [1] );
- BLIP_READER_END( center, bufs [2] );
-}
-
-void Effects_Buffer::mix_enhanced( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [2] );
- BLIP_READER_BEGIN( center, bufs [2] );
- BLIP_READER_BEGIN( l1, bufs [3] );
- BLIP_READER_BEGIN( r1, bufs [4] );
- BLIP_READER_BEGIN( l2, bufs [5] );
- BLIP_READER_BEGIN( r2, bufs [6] );
- BLIP_READER_BEGIN( sq1, bufs [0] );
- BLIP_READER_BEGIN( sq2, bufs [1] );
-
- blip_sample_t* const reverb_buf = this->reverb_buf.begin();
- blip_sample_t* const echo_buf = this->echo_buf.begin();
- int echo_pos = this->echo_pos;
- int reverb_pos = this->reverb_pos;
-
- while ( count-- )
- {
- int sum1_s = BLIP_READER_READ( sq1 );
- int sum2_s = BLIP_READER_READ( sq2 );
-
- BLIP_READER_NEXT( sq1, bass );
- BLIP_READER_NEXT( sq2, bass );
-
- int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) +
- FMUL( sum2_s, chans.pan_2_levels [0] ) + BLIP_READER_READ( l1 ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask];
-
- int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) +
- FMUL( sum2_s, chans.pan_2_levels [1] ) + BLIP_READER_READ( r1 ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask];
-
- BLIP_READER_NEXT( l1, bass );
- BLIP_READER_NEXT( r1, bass );
-
- fixed_t reverb_level = chans.reverb_level;
- reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level );
- reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level );
- reverb_pos = (reverb_pos + 2) & reverb_mask;
-
- int sum3_s = BLIP_READER_READ( center );
- BLIP_READER_NEXT( center, bass );
-
- int left = new_reverb_l + sum3_s + BLIP_READER_READ( l2 ) + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
- int right = new_reverb_r + sum3_s + BLIP_READER_READ( r2 ) + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
-
- BLIP_READER_NEXT( l2, bass );
- BLIP_READER_NEXT( r2, bass );
-
- echo_buf [echo_pos] = sum3_s;
- echo_pos = (echo_pos + 1) & echo_mask;
-
- if ( (int16_t) left != left )
- left = 0x7FFF - (left >> 24);
-
- out [0] = left;
- out [1] = right;
-
- out += 2;
-
- if ( (int16_t) right != right )
- out [-1] = 0x7FFF - (right >> 24);
- }
- this->reverb_pos = reverb_pos;
- this->echo_pos = echo_pos;
-
- BLIP_READER_END( l1, bufs [3] );
- BLIP_READER_END( r1, bufs [4] );
- BLIP_READER_END( l2, bufs [5] );
- BLIP_READER_END( r2, bufs [6] );
- BLIP_READER_END( sq1, bufs [0] );
- BLIP_READER_END( sq2, bufs [1] );
- BLIP_READER_END( center, bufs [2] );
-}
-
diff --git a/src/console/Fir_Resampler.cc b/src/console/Fir_Resampler.cc
new file mode 100644
index 000000000000..d8cbc3d246f3
--- /dev/null
+++ b/src/console/Fir_Resampler.cc
@@ -0,0 +1,199 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Fir_Resampler.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+/* Copyright (C) 2004-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+#undef PI
+#define PI 3.1415926535897932384626433832795029
+
+static void gen_sinc( double rolloff, int width, double offset, double spacing, double scale,
+ int count, short* out )
+{
+ double const maxh = 256;
+ double const step = PI / maxh * spacing;
+ double const to_w = maxh * 2 / width;
+ double const pow_a_n = pow( rolloff, maxh );
+ scale /= maxh * 2;
+
+ double angle = (count / 2 - 1 + offset) * -step;
+ while ( count-- )
+ {
+ *out++ = 0;
+ double w = angle * to_w;
+ if ( fabs( w ) < PI )
+ {
+ double rolloff_cos_a = rolloff * cos( angle );
+ double num = 1 - rolloff_cos_a -
+ pow_a_n * cos( maxh * angle ) +
+ pow_a_n * rolloff * cos( (maxh - 1) * angle );
+ double den = 1 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff;
+ double sinc = scale * num / den - scale;
+
+ out [-1] = (short) (cos( w ) * sinc + sinc);
+ }
+ angle += step;
+ }
+}
+
+Fir_Resampler_::Fir_Resampler_( int width, sample_t* impulses_ ) :
+ width_( width ),
+ write_offset( width * stereo - stereo ),
+ impulses( impulses_ )
+{
+ write_pos = 0;
+ res = 1;
+ imp_phase = 0;
+ skip_bits = 0;
+ step = stereo;
+ ratio_ = 1.0;
+}
+
+Fir_Resampler_::~Fir_Resampler_() { }
+
+void Fir_Resampler_::clear()
+{
+ imp_phase = 0;
+ if ( buf.size() )
+ {
+ write_pos = &buf [write_offset];
+ memset( buf.begin(), 0, write_offset * sizeof buf [0] );
+ }
+}
+
+blargg_err_t Fir_Resampler_::buffer_size( int new_size )
+{
+ RETURN_ERR( buf.resize( new_size + write_offset ) );
+ clear();
+ return 0;
+}
+
+double Fir_Resampler_::time_ratio( double new_factor, double rolloff, double gain )
+{
+ ratio_ = new_factor;
+
+ double fstep = 0.0;
+ {
+ double least_error = 2;
+ double pos = 0;
+ res = -1;
+ for ( int r = 1; r <= max_res; r++ )
+ {
+ pos += ratio_;
+ double nearest = floor( pos + 0.5 );
+ double error = fabs( pos - nearest );
+ if ( error < least_error )
+ {
+ res = r;
+ fstep = nearest / res;
+ least_error = error;
+ }
+ }
+ }
+
+ skip_bits = 0;
+
+ step = stereo * (int) floor( fstep );
+
+ ratio_ = fstep;
+ fstep = fmod( fstep, 1.0 );
+
+ double filter = (ratio_ < 1.0) ? 1.0 : 1.0 / ratio_;
+ double pos = 0.0;
+ input_per_cycle = 0;
+ for ( int i = 0; i < res; i++ )
+ {
+ gen_sinc( rolloff, int (width_ * filter + 1) & ~1, pos, filter,
+ double (0x7FFF * gain * filter),
+ (int) width_, impulses + i * width_ );
+
+ pos += fstep;
+ input_per_cycle += step;
+ if ( pos >= 0.9999999 )
+ {
+ pos -= 1.0;
+ skip_bits |= 1 << i;
+ input_per_cycle++;
+ }
+ }
+
+ clear();
+
+ return ratio_;
+}
+
+int Fir_Resampler_::input_needed( blargg_long output_count ) const
+{
+ blargg_long input_count = 0;
+
+ unsigned long skip = skip_bits >> imp_phase;
+ int remain = res - imp_phase;
+ while ( (output_count -= 2) > 0 )
+ {
+ input_count += step + (skip & 1) * stereo;
+ skip >>= 1;
+ if ( !--remain )
+ {
+ skip = skip_bits;
+ remain = res;
+ }
+ output_count -= 2;
+ }
+
+ long input_extra = input_count - (write_pos - &buf [(width_ - 1) * stereo]);
+ if ( input_extra < 0 )
+ input_extra = 0;
+ return input_extra;
+}
+
+int Fir_Resampler_::avail_( blargg_long input_count ) const
+{
+ int cycle_count = input_count / input_per_cycle;
+ int output_count = cycle_count * res * stereo;
+ input_count -= cycle_count * input_per_cycle;
+
+ blargg_ulong skip = skip_bits >> imp_phase;
+ int remain = res - imp_phase;
+ while ( input_count >= 0 )
+ {
+ input_count -= step + (skip & 1) * stereo;
+ skip >>= 1;
+ if ( !--remain )
+ {
+ skip = skip_bits;
+ remain = res;
+ }
+ output_count += 2;
+ }
+ return output_count;
+}
+
+int Fir_Resampler_::skip_input( long count )
+{
+ int remain = write_pos - buf.begin();
+ int max_count = remain - width_ * stereo;
+ if ( count > max_count )
+ count = max_count;
+
+ remain -= count;
+ write_pos = &buf [remain];
+ memmove( buf.begin(), &buf [count], remain * sizeof buf [0] );
+
+ return count;
+}
diff --git a/src/console/Fir_Resampler.cxx b/src/console/Fir_Resampler.cxx
deleted file mode 100644
index d8cbc3d246f3..000000000000
--- a/src/console/Fir_Resampler.cxx
+++ /dev/null
@@ -1,199 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Fir_Resampler.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-
-/* Copyright (C) 2004-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#undef PI
-#define PI 3.1415926535897932384626433832795029
-
-static void gen_sinc( double rolloff, int width, double offset, double spacing, double scale,
- int count, short* out )
-{
- double const maxh = 256;
- double const step = PI / maxh * spacing;
- double const to_w = maxh * 2 / width;
- double const pow_a_n = pow( rolloff, maxh );
- scale /= maxh * 2;
-
- double angle = (count / 2 - 1 + offset) * -step;
- while ( count-- )
- {
- *out++ = 0;
- double w = angle * to_w;
- if ( fabs( w ) < PI )
- {
- double rolloff_cos_a = rolloff * cos( angle );
- double num = 1 - rolloff_cos_a -
- pow_a_n * cos( maxh * angle ) +
- pow_a_n * rolloff * cos( (maxh - 1) * angle );
- double den = 1 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff;
- double sinc = scale * num / den - scale;
-
- out [-1] = (short) (cos( w ) * sinc + sinc);
- }
- angle += step;
- }
-}
-
-Fir_Resampler_::Fir_Resampler_( int width, sample_t* impulses_ ) :
- width_( width ),
- write_offset( width * stereo - stereo ),
- impulses( impulses_ )
-{
- write_pos = 0;
- res = 1;
- imp_phase = 0;
- skip_bits = 0;
- step = stereo;
- ratio_ = 1.0;
-}
-
-Fir_Resampler_::~Fir_Resampler_() { }
-
-void Fir_Resampler_::clear()
-{
- imp_phase = 0;
- if ( buf.size() )
- {
- write_pos = &buf [write_offset];
- memset( buf.begin(), 0, write_offset * sizeof buf [0] );
- }
-}
-
-blargg_err_t Fir_Resampler_::buffer_size( int new_size )
-{
- RETURN_ERR( buf.resize( new_size + write_offset ) );
- clear();
- return 0;
-}
-
-double Fir_Resampler_::time_ratio( double new_factor, double rolloff, double gain )
-{
- ratio_ = new_factor;
-
- double fstep = 0.0;
- {
- double least_error = 2;
- double pos = 0;
- res = -1;
- for ( int r = 1; r <= max_res; r++ )
- {
- pos += ratio_;
- double nearest = floor( pos + 0.5 );
- double error = fabs( pos - nearest );
- if ( error < least_error )
- {
- res = r;
- fstep = nearest / res;
- least_error = error;
- }
- }
- }
-
- skip_bits = 0;
-
- step = stereo * (int) floor( fstep );
-
- ratio_ = fstep;
- fstep = fmod( fstep, 1.0 );
-
- double filter = (ratio_ < 1.0) ? 1.0 : 1.0 / ratio_;
- double pos = 0.0;
- input_per_cycle = 0;
- for ( int i = 0; i < res; i++ )
- {
- gen_sinc( rolloff, int (width_ * filter + 1) & ~1, pos, filter,
- double (0x7FFF * gain * filter),
- (int) width_, impulses + i * width_ );
-
- pos += fstep;
- input_per_cycle += step;
- if ( pos >= 0.9999999 )
- {
- pos -= 1.0;
- skip_bits |= 1 << i;
- input_per_cycle++;
- }
- }
-
- clear();
-
- return ratio_;
-}
-
-int Fir_Resampler_::input_needed( blargg_long output_count ) const
-{
- blargg_long input_count = 0;
-
- unsigned long skip = skip_bits >> imp_phase;
- int remain = res - imp_phase;
- while ( (output_count -= 2) > 0 )
- {
- input_count += step + (skip & 1) * stereo;
- skip >>= 1;
- if ( !--remain )
- {
- skip = skip_bits;
- remain = res;
- }
- output_count -= 2;
- }
-
- long input_extra = input_count - (write_pos - &buf [(width_ - 1) * stereo]);
- if ( input_extra < 0 )
- input_extra = 0;
- return input_extra;
-}
-
-int Fir_Resampler_::avail_( blargg_long input_count ) const
-{
- int cycle_count = input_count / input_per_cycle;
- int output_count = cycle_count * res * stereo;
- input_count -= cycle_count * input_per_cycle;
-
- blargg_ulong skip = skip_bits >> imp_phase;
- int remain = res - imp_phase;
- while ( input_count >= 0 )
- {
- input_count -= step + (skip & 1) * stereo;
- skip >>= 1;
- if ( !--remain )
- {
- skip = skip_bits;
- remain = res;
- }
- output_count += 2;
- }
- return output_count;
-}
-
-int Fir_Resampler_::skip_input( long count )
-{
- int remain = write_pos - buf.begin();
- int max_count = remain - width_ * stereo;
- if ( count > max_count )
- count = max_count;
-
- remain -= count;
- write_pos = &buf [remain];
- memmove( buf.begin(), &buf [count], remain * sizeof buf [0] );
-
- return count;
-}
diff --git a/src/console/Gb_Apu.cc b/src/console/Gb_Apu.cc
new file mode 100644
index 000000000000..834977ea9eed
--- /dev/null
+++ b/src/console/Gb_Apu.cc
@@ -0,0 +1,306 @@
+// Gb_Snd_Emu 0.1.5. http://www.slack.net/~ant/
+
+#include "Gb_Apu.h"
+
+#include <string.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+unsigned const vol_reg = 0xFF24;
+unsigned const status_reg = 0xFF26;
+
+Gb_Apu::Gb_Apu()
+{
+ square1.synth = &square_synth;
+ square2.synth = &square_synth;
+ wave.synth = &other_synth;
+ noise.synth = &other_synth;
+
+ oscs [0] = &square1;
+ oscs [1] = &square2;
+ oscs [2] = &wave;
+ oscs [3] = &noise;
+
+ for ( int i = 0; i < osc_count; i++ )
+ {
+ Gb_Osc& osc = *oscs [i];
+ osc.regs = ®s [i * 5];
+ osc.output = 0;
+ osc.outputs [0] = 0;
+ osc.outputs [1] = 0;
+ osc.outputs [2] = 0;
+ osc.outputs [3] = 0;
+ }
+
+ set_tempo( 1.0 );
+ volume( 1.0 );
+ reset();
+}
+
+void Gb_Apu::treble_eq( const blip_eq_t& eq )
+{
+ square_synth.treble_eq( eq );
+ other_synth.treble_eq( eq );
+}
+
+void Gb_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
+{
+ require( (unsigned) index < osc_count );
+ require( (center && left && right) || (!center && !left && !right) );
+ Gb_Osc& osc = *oscs [index];
+ osc.outputs [1] = right;
+ osc.outputs [2] = left;
+ osc.outputs [3] = center;
+ osc.output = osc.outputs [osc.output_select];
+}
+
+void Gb_Apu::output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
+{
+ for ( int i = 0; i < osc_count; i++ )
+ osc_output( i, center, left, right );
+}
+
+void Gb_Apu::update_volume()
+{
+ // TODO: doesn't handle differing left/right global volume (support would
+ // require modification to all oscillator code)
+ int data = regs [vol_reg - start_addr];
+ double vol = (max( data & 7, data >> 4 & 7 ) + 1) * volume_unit;
+ square_synth.volume( vol );
+ other_synth.volume( vol );
+}
+
+static unsigned char const powerup_regs [0x20] = {
+ 0x80,0x3F,0x00,0xFF,0xBF, // square 1
+ 0xFF,0x3F,0x00,0xFF,0xBF, // square 2
+ 0x7F,0xFF,0x9F,0xFF,0xBF, // wave
+ 0xFF,0xFF,0x00,0x00,0xBF, // noise
+ 0x00, // left/right enables
+ 0x77, // master volume
+ 0x80, // power
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+void Gb_Apu::set_tempo( double t )
+{
+ frame_period = 4194304 / 256; // 256 Hz
+ if ( t != 1.0 )
+ frame_period = blip_time_t (frame_period / t);
+}
+
+void Gb_Apu::reset()
+{
+ next_frame_time = 0;
+ last_time = 0;
+ frame_count = 0;
+
+ square1.reset();
+ square2.reset();
+ wave.reset();
+ noise.reset();
+ noise.bits = 1;
+ wave.wave_pos = 0;
+
+ // avoid click at beginning
+ regs [vol_reg - start_addr] = 0x77;
+ update_volume();
+
+ regs [status_reg - start_addr] = 0x01; // force power
+ write_register( 0, status_reg, 0x00 );
+
+ static unsigned char const initial_wave [] = {
+ 0x84,0x40,0x43,0xAA,0x2D,0x78,0x92,0x3C, // wave table
+ 0x60,0x59,0x59,0xB0,0x34,0xB8,0x2E,0xDA
+ };
+ memcpy( wave.wave, initial_wave, sizeof wave.wave );
+}
+
+void Gb_Apu::run_until( blip_time_t end_time )
+{
+ require( end_time >= last_time ); // end_time must not be before previous time
+ if ( end_time == last_time )
+ return;
+
+ while ( true )
+ {
+ blip_time_t time = next_frame_time;
+ if ( time > end_time )
+ time = end_time;
+
+ // run oscillators
+ for ( int i = 0; i < osc_count; ++i )
+ {
+ Gb_Osc& osc = *oscs [i];
+ if ( osc.output )
+ {
+ osc.output->set_modified(); // TODO: misses optimization opportunities?
+ int playing = false;
+ if ( osc.enabled && osc.volume &&
+ (!(osc.regs [4] & osc.len_enabled_mask) || osc.length) )
+ playing = -1;
+ switch ( i )
+ {
+ case 0: square1.run( last_time, time, playing ); break;
+ case 1: square2.run( last_time, time, playing ); break;
+ case 2: wave .run( last_time, time, playing ); break;
+ case 3: noise .run( last_time, time, playing ); break;
+ }
+ }
+ }
+ last_time = time;
+
+ if ( time == end_time )
+ break;
+
+ next_frame_time += frame_period;
+
+ // 256 Hz actions
+ square1.clock_length();
+ square2.clock_length();
+ wave.clock_length();
+ noise.clock_length();
+
+ frame_count = (frame_count + 1) & 3;
+ if ( frame_count == 0 )
+ {
+ // 64 Hz actions
+ square1.clock_envelope();
+ square2.clock_envelope();
+ noise.clock_envelope();
+ }
+
+ if ( frame_count & 1 )
+ square1.clock_sweep(); // 128 Hz action
+ }
+}
+
+void Gb_Apu::end_frame( blip_time_t end_time )
+{
+ if ( end_time > last_time )
+ run_until( end_time );
+
+ assert( next_frame_time >= end_time );
+ next_frame_time -= end_time;
+
+ assert( last_time >= end_time );
+ last_time -= end_time;
+}
+
+void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data )
+{
+ require( (unsigned) data < 0x100 );
+
+ int reg = addr - start_addr;
+ if ( (unsigned) reg >= register_count )
+ return;
+
+ run_until( time );
+
+ int old_reg = regs [reg];
+ regs [reg] = data;
+
+ if ( addr < vol_reg )
+ {
+ write_osc( reg / 5, reg, data );
+ }
+ else if ( addr == vol_reg && data != old_reg ) // global volume
+ {
+ // return all oscs to 0
+ for ( int i = 0; i < osc_count; i++ )
+ {
+ Gb_Osc& osc = *oscs [i];
+ int amp = osc.last_amp;
+ osc.last_amp = 0;
+ if ( amp && osc.enabled && osc.output )
+ other_synth.offset( time, -amp, osc.output );
+ }
+
+ if ( wave.outputs [3] )
+ other_synth.offset( time, 30, wave.outputs [3] );
+
+ update_volume();
+
+ if ( wave.outputs [3] )
+ other_synth.offset( time, -30, wave.outputs [3] );
+
+ // oscs will update with new amplitude when next run
+ }
+ else if ( addr == 0xFF25 || addr == status_reg )
+ {
+ int mask = (regs [status_reg - start_addr] & 0x80) ? ~0 : 0;
+ int flags = regs [0xFF25 - start_addr] & mask;
+
+ // left/right assignments
+ for ( int i = 0; i < osc_count; i++ )
+ {
+ Gb_Osc& osc = *oscs [i];
+ osc.enabled &= mask;
+ int bits = flags >> i;
+ Blip_Buffer* old_output = osc.output;
+ osc.output_select = (bits >> 3 & 2) | (bits & 1);
+ osc.output = osc.outputs [osc.output_select];
+ if ( osc.output != old_output )
+ {
+ int amp = osc.last_amp;
+ osc.last_amp = 0;
+ if ( amp && old_output )
+ other_synth.offset( time, -amp, old_output );
+ }
+ }
+
+ if ( addr == status_reg && data != old_reg )
+ {
+ if ( !(data & 0x80) )
+ {
+ for ( unsigned i = 0; i < sizeof powerup_regs; i++ )
+ {
+ if ( i != status_reg - start_addr )
+ write_register( time, i + start_addr, powerup_regs [i] );
+ }
+ }
+ else
+ {
+ //debug_printf( "APU powered on\n" );
+ }
+ }
+ }
+ else if ( addr >= 0xFF30 )
+ {
+ int index = (addr & 0x0F) * 2;
+ wave.wave [index] = data >> 4;
+ wave.wave [index + 1] = data & 0x0F;
+ }
+}
+
+int Gb_Apu::read_register( blip_time_t time, unsigned addr )
+{
+ run_until( time );
+
+ int index = addr - start_addr;
+ require( (unsigned) index < register_count );
+ int data = regs [index];
+
+ if ( addr == status_reg )
+ {
+ data = (data & 0x80) | 0x70;
+ for ( int i = 0; i < osc_count; i++ )
+ {
+ const Gb_Osc& osc = *oscs [i];
+ if ( osc.enabled && (osc.length || !(osc.regs [4] & osc.len_enabled_mask)) )
+ data |= 1 << i;
+ }
+ }
+
+ return data;
+}
diff --git a/src/console/Gb_Apu.cxx b/src/console/Gb_Apu.cxx
deleted file mode 100644
index 834977ea9eed..000000000000
--- a/src/console/Gb_Apu.cxx
+++ /dev/null
@@ -1,306 +0,0 @@
-// Gb_Snd_Emu 0.1.5. http://www.slack.net/~ant/
-
-#include "Gb_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-unsigned const vol_reg = 0xFF24;
-unsigned const status_reg = 0xFF26;
-
-Gb_Apu::Gb_Apu()
-{
- square1.synth = &square_synth;
- square2.synth = &square_synth;
- wave.synth = &other_synth;
- noise.synth = &other_synth;
-
- oscs [0] = &square1;
- oscs [1] = &square2;
- oscs [2] = &wave;
- oscs [3] = &noise;
-
- for ( int i = 0; i < osc_count; i++ )
- {
- Gb_Osc& osc = *oscs [i];
- osc.regs = ®s [i * 5];
- osc.output = 0;
- osc.outputs [0] = 0;
- osc.outputs [1] = 0;
- osc.outputs [2] = 0;
- osc.outputs [3] = 0;
- }
-
- set_tempo( 1.0 );
- volume( 1.0 );
- reset();
-}
-
-void Gb_Apu::treble_eq( const blip_eq_t& eq )
-{
- square_synth.treble_eq( eq );
- other_synth.treble_eq( eq );
-}
-
-void Gb_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- require( (unsigned) index < osc_count );
- require( (center && left && right) || (!center && !left && !right) );
- Gb_Osc& osc = *oscs [index];
- osc.outputs [1] = right;
- osc.outputs [2] = left;
- osc.outputs [3] = center;
- osc.output = osc.outputs [osc.output_select];
-}
-
-void Gb_Apu::output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, center, left, right );
-}
-
-void Gb_Apu::update_volume()
-{
- // TODO: doesn't handle differing left/right global volume (support would
- // require modification to all oscillator code)
- int data = regs [vol_reg - start_addr];
- double vol = (max( data & 7, data >> 4 & 7 ) + 1) * volume_unit;
- square_synth.volume( vol );
- other_synth.volume( vol );
-}
-
-static unsigned char const powerup_regs [0x20] = {
- 0x80,0x3F,0x00,0xFF,0xBF, // square 1
- 0xFF,0x3F,0x00,0xFF,0xBF, // square 2
- 0x7F,0xFF,0x9F,0xFF,0xBF, // wave
- 0xFF,0xFF,0x00,0x00,0xBF, // noise
- 0x00, // left/right enables
- 0x77, // master volume
- 0x80, // power
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
-};
-
-void Gb_Apu::set_tempo( double t )
-{
- frame_period = 4194304 / 256; // 256 Hz
- if ( t != 1.0 )
- frame_period = blip_time_t (frame_period / t);
-}
-
-void Gb_Apu::reset()
-{
- next_frame_time = 0;
- last_time = 0;
- frame_count = 0;
-
- square1.reset();
- square2.reset();
- wave.reset();
- noise.reset();
- noise.bits = 1;
- wave.wave_pos = 0;
-
- // avoid click at beginning
- regs [vol_reg - start_addr] = 0x77;
- update_volume();
-
- regs [status_reg - start_addr] = 0x01; // force power
- write_register( 0, status_reg, 0x00 );
-
- static unsigned char const initial_wave [] = {
- 0x84,0x40,0x43,0xAA,0x2D,0x78,0x92,0x3C, // wave table
- 0x60,0x59,0x59,0xB0,0x34,0xB8,0x2E,0xDA
- };
- memcpy( wave.wave, initial_wave, sizeof wave.wave );
-}
-
-void Gb_Apu::run_until( blip_time_t end_time )
-{
- require( end_time >= last_time ); // end_time must not be before previous time
- if ( end_time == last_time )
- return;
-
- while ( true )
- {
- blip_time_t time = next_frame_time;
- if ( time > end_time )
- time = end_time;
-
- // run oscillators
- for ( int i = 0; i < osc_count; ++i )
- {
- Gb_Osc& osc = *oscs [i];
- if ( osc.output )
- {
- osc.output->set_modified(); // TODO: misses optimization opportunities?
- int playing = false;
- if ( osc.enabled && osc.volume &&
- (!(osc.regs [4] & osc.len_enabled_mask) || osc.length) )
- playing = -1;
- switch ( i )
- {
- case 0: square1.run( last_time, time, playing ); break;
- case 1: square2.run( last_time, time, playing ); break;
- case 2: wave .run( last_time, time, playing ); break;
- case 3: noise .run( last_time, time, playing ); break;
- }
- }
- }
- last_time = time;
-
- if ( time == end_time )
- break;
-
- next_frame_time += frame_period;
-
- // 256 Hz actions
- square1.clock_length();
- square2.clock_length();
- wave.clock_length();
- noise.clock_length();
-
- frame_count = (frame_count + 1) & 3;
- if ( frame_count == 0 )
- {
- // 64 Hz actions
- square1.clock_envelope();
- square2.clock_envelope();
- noise.clock_envelope();
- }
-
- if ( frame_count & 1 )
- square1.clock_sweep(); // 128 Hz action
- }
-}
-
-void Gb_Apu::end_frame( blip_time_t end_time )
-{
- if ( end_time > last_time )
- run_until( end_time );
-
- assert( next_frame_time >= end_time );
- next_frame_time -= end_time;
-
- assert( last_time >= end_time );
- last_time -= end_time;
-}
-
-void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data )
-{
- require( (unsigned) data < 0x100 );
-
- int reg = addr - start_addr;
- if ( (unsigned) reg >= register_count )
- return;
-
- run_until( time );
-
- int old_reg = regs [reg];
- regs [reg] = data;
-
- if ( addr < vol_reg )
- {
- write_osc( reg / 5, reg, data );
- }
- else if ( addr == vol_reg && data != old_reg ) // global volume
- {
- // return all oscs to 0
- for ( int i = 0; i < osc_count; i++ )
- {
- Gb_Osc& osc = *oscs [i];
- int amp = osc.last_amp;
- osc.last_amp = 0;
- if ( amp && osc.enabled && osc.output )
- other_synth.offset( time, -amp, osc.output );
- }
-
- if ( wave.outputs [3] )
- other_synth.offset( time, 30, wave.outputs [3] );
-
- update_volume();
-
- if ( wave.outputs [3] )
- other_synth.offset( time, -30, wave.outputs [3] );
-
- // oscs will update with new amplitude when next run
- }
- else if ( addr == 0xFF25 || addr == status_reg )
- {
- int mask = (regs [status_reg - start_addr] & 0x80) ? ~0 : 0;
- int flags = regs [0xFF25 - start_addr] & mask;
-
- // left/right assignments
- for ( int i = 0; i < osc_count; i++ )
- {
- Gb_Osc& osc = *oscs [i];
- osc.enabled &= mask;
- int bits = flags >> i;
- Blip_Buffer* old_output = osc.output;
- osc.output_select = (bits >> 3 & 2) | (bits & 1);
- osc.output = osc.outputs [osc.output_select];
- if ( osc.output != old_output )
- {
- int amp = osc.last_amp;
- osc.last_amp = 0;
- if ( amp && old_output )
- other_synth.offset( time, -amp, old_output );
- }
- }
-
- if ( addr == status_reg && data != old_reg )
- {
- if ( !(data & 0x80) )
- {
- for ( unsigned i = 0; i < sizeof powerup_regs; i++ )
- {
- if ( i != status_reg - start_addr )
- write_register( time, i + start_addr, powerup_regs [i] );
- }
- }
- else
- {
- //debug_printf( "APU powered on\n" );
- }
- }
- }
- else if ( addr >= 0xFF30 )
- {
- int index = (addr & 0x0F) * 2;
- wave.wave [index] = data >> 4;
- wave.wave [index + 1] = data & 0x0F;
- }
-}
-
-int Gb_Apu::read_register( blip_time_t time, unsigned addr )
-{
- run_until( time );
-
- int index = addr - start_addr;
- require( (unsigned) index < register_count );
- int data = regs [index];
-
- if ( addr == status_reg )
- {
- data = (data & 0x80) | 0x70;
- for ( int i = 0; i < osc_count; i++ )
- {
- const Gb_Osc& osc = *oscs [i];
- if ( osc.enabled && (osc.length || !(osc.regs [4] & osc.len_enabled_mask)) )
- data |= 1 << i;
- }
- }
-
- return data;
-}
diff --git a/src/console/Gb_Apu.h b/src/console/Gb_Apu.h
index 557ef8bd556c..b2695385e8c0 100644
--- a/src/console/Gb_Apu.h
+++ b/src/console/Gb_Apu.h
@@ -19,12 +19,12 @@ public:
// buffers for stereo output (using Stereo_Buffer to do the mixing).
// Assign all oscillator outputs to specified buffer(s). If buffer
- // is NULL, silences all oscillators.
+ // is nullptr, silences all oscillators.
void output( Blip_Buffer* mono );
void output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
// Assign single oscillator output to buffer(s). Valid indicies are 0 to 3,
- // which refer to Square 1, Square 2, Wave, and Noise. If buffer is NULL,
+ // which refer to Square 1, Square 2, Wave, and Noise. If buffer is nullptr,
// silences oscillator.
enum { osc_count = 4 };
void osc_output( int index, Blip_Buffer* mono );
diff --git a/src/console/Gb_Cpu.cc b/src/console/Gb_Cpu.cc
new file mode 100644
index 000000000000..9954b5026a33
--- /dev/null
+++ b/src/console/Gb_Cpu.cc
@@ -0,0 +1,1052 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Gb_Cpu.h"
+
+#include <string.h>
+
+//#include "gb_cpu_log.h"
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "gb_cpu_io.h"
+
+#include "blargg_source.h"
+
+// Common instructions:
+//
+// 365880 FA LD A,IND16
+// 355863 20 JR NZ
+// 313655 21 LD HL,IMM
+// 274580 28 JR Z
+// 252878 FE CMP IMM
+// 230541 7E LD A,(HL)
+// 226209 2A LD A,(HL+)
+// 217467 CD CALL
+// 212034 C9 RET
+// 208376 CB CB prefix
+//
+// 27486 CB 7E BIT 7,(HL)
+// 15925 CB 76 BIT 6,(HL)
+// 13035 CB 19 RR C
+// 11557 CB 7F BIT 7,A
+// 10898 CB 37 SWAP A
+// 10208 CB 66 BIT 4,(HL)
+
+#if BLARGG_NONPORTABLE
+ #define PAGE_OFFSET( addr ) (addr)
+#else
+ #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
+#endif
+
+inline void Gb_Cpu::set_code_page( int i, uint8_t* p )
+{
+ state->code_map [i] = p - PAGE_OFFSET( i * (blargg_long) page_size );
+}
+
+void Gb_Cpu::reset( void* unmapped )
+{
+ check( state == &state_ );
+ state = &state_;
+
+ state_.remain = 0;
+
+ for ( int i = 0; i < page_count + 1; i++ )
+ set_code_page( i, (uint8_t*) unmapped );
+
+ memset( &r, 0, sizeof r );
+ //interrupts_enabled = false;
+}
+
+void Gb_Cpu::map_code( gb_addr_t start, unsigned size, void* data )
+{
+ // address range must begin and end on page boundaries
+ require( start % page_size == 0 );
+ require( size % page_size == 0 );
+
+ unsigned first_page = start / page_size;
+ for ( unsigned i = size / page_size; i--; )
+ set_code_page( first_page + i, (uint8_t*) data + i * page_size );
+}
+
+#define READ( addr ) CPU_READ( this, (addr), s.remain )
+#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), s.remain );}
+#define READ_FAST( addr, out ) CPU_READ_FAST( this, (addr), s.remain, out )
+#define READ_PROG( addr ) (s.code_map [(addr) >> page_shift] [PAGE_OFFSET( addr )])
+
+unsigned const z_flag = 0x80;
+unsigned const n_flag = 0x40;
+unsigned const h_flag = 0x20;
+unsigned const c_flag = 0x10;
+
+bool Gb_Cpu::run( blargg_long cycle_count )
+{
+ state_.remain = blargg_ulong (cycle_count + clocks_per_instr) / clocks_per_instr;
+ state_t s;
+ this->state = &s;
+ memcpy( &s, &this->state_, sizeof s );
+
+#if BLARGG_BIG_ENDIAN
+ #define R8( n ) (r8_ [n])
+#elif BLARGG_LITTLE_ENDIAN
+ #define R8( n ) (r8_ [(n) ^ 1])
+#else
+ #error "Byte order of CPU must be known"
+#endif
+
+ union {
+ core_regs_t rg; // individual registers
+
+ struct {
+ uint16_t bc, de, hl, unused; // pairs
+ } rp;
+
+ uint8_t r8_ [8]; // indexed registers (use R8 macro due to endian dependence)
+ uint16_t r16 [4]; // indexed pairs
+ };
+ BOOST_STATIC_ASSERT( sizeof rg == 8 && sizeof rp == 8 );
+
+ rg = r;
+ unsigned pc = r.pc;
+ unsigned sp = r.sp;
+ unsigned flags = r.flags;
+
+loop:
+
+ check( (unsigned long) pc < 0x10000 );
+ check( (unsigned long) sp < 0x10000 );
+ check( (flags & ~0xF0) == 0 );
+
+ uint8_t const* instr = s.code_map [pc >> page_shift];
+ unsigned op;
+
+ // TODO: eliminate this special case
+ #if BLARGG_NONPORTABLE
+ op = instr [pc];
+ pc++;
+ instr += pc;
+ #else
+ instr += PAGE_OFFSET( pc );
+ op = *instr++;
+ pc++;
+ #endif
+
+#define GET_ADDR() GET_LE16( instr )
+
+ if ( !--s.remain )
+ goto stop;
+
+ unsigned data;
+ data = *instr;
+
+ #ifdef GB_CPU_LOG_H
+ gb_cpu_log( "new", pc - 1, op, data, instr [1] );
+ #endif
+
+ switch ( op )
+ {
+
+// TODO: more efficient way to handle negative branch that wraps PC around
+#define BRANCH( cond )\
+{\
+ pc++;\
+ int offset = (int8_t) data;\
+ if ( !(cond) ) goto loop;\
+ pc = uint16_t (pc + offset);\
+ goto loop;\
+}
+
+// Most Common
+
+ case 0x20: // JR NZ
+ BRANCH( !(flags & z_flag) )
+
+ case 0x21: // LD HL,IMM (common)
+ rp.hl = GET_ADDR();
+ pc += 2;
+ goto loop;
+
+ case 0x28: // JR Z
+ BRANCH( flags & z_flag )
+
+ {
+ unsigned temp;
+ case 0xF0: // LD A,(0xFF00+imm)
+ temp = data | 0xFF00;
+ pc++;
+ goto ld_a_ind_comm;
+
+ case 0xF2: // LD A,(0xFF00+C)
+ temp = rg.c | 0xFF00;
+ goto ld_a_ind_comm;
+
+ case 0x0A: // LD A,(BC)
+ temp = rp.bc;
+ goto ld_a_ind_comm;
+
+ case 0x3A: // LD A,(HL-)
+ temp = rp.hl;
+ rp.hl = temp - 1;
+ goto ld_a_ind_comm;
+
+ case 0x1A: // LD A,(DE)
+ temp = rp.de;
+ goto ld_a_ind_comm;
+
+ case 0x2A: // LD A,(HL+) (common)
+ temp = rp.hl;
+ rp.hl = temp + 1;
+ goto ld_a_ind_comm;
+
+ case 0xFA: // LD A,IND16 (common)
+ temp = GET_ADDR();
+ pc += 2;
+ ld_a_ind_comm:
+ READ_FAST( temp, rg.a );
+ goto loop;
+ }
+
+ case 0xBE: // CMP (HL)
+ data = READ( rp.hl );
+ goto cmp_comm;
+
+ case 0xB8: // CMP B
+ case 0xB9: // CMP C
+ case 0xBA: // CMP D
+ case 0xBB: // CMP E
+ case 0xBC: // CMP H
+ case 0xBD: // CMP L
+ data = R8( op & 7 );
+ goto cmp_comm;
+
+ case 0xFE: // CMP IMM
+ pc++;
+ cmp_comm:
+ op = rg.a;
+ data = op - data;
+ sub_set_flags:
+ flags = ((op & 15) - (data & 15)) & h_flag;
+ flags |= (data >> 4) & c_flag;
+ flags |= n_flag;
+ if ( data & 0xFF )
+ goto loop;
+ flags |= z_flag;
+ goto loop;
+
+ case 0x46: // LD B,(HL)
+ case 0x4E: // LD C,(HL)
+ case 0x56: // LD D,(HL)
+ case 0x5E: // LD E,(HL)
+ case 0x66: // LD H,(HL)
+ case 0x6E: // LD L,(HL)
+ case 0x7E:{// LD A,(HL)
+ unsigned addr = rp.hl;
+ READ_FAST( addr, R8( (op >> 3) & 7 ) );
+ goto loop;
+ }
+
+ case 0xC4: // CNZ (next-most-common)
+ pc += 2;
+ if ( flags & z_flag )
+ goto loop;
+ call:
+ pc -= 2;
+ case 0xCD: // CALL (most-common)
+ data = pc + 2;
+ pc = GET_ADDR();
+ push:
+ sp = (sp - 1) & 0xFFFF;
+ WRITE( sp, data >> 8 );
+ sp = (sp - 1) & 0xFFFF;
+ WRITE( sp, data & 0xFF );
+ goto loop;
+
+ case 0xC8: // RNZ (next-most-common)
+ if ( !(flags & z_flag) )
+ goto loop;
+ case 0xC9: // RET (most common)
+ ret:
+ pc = READ( sp );
+ pc += 0x100 * READ( sp + 1 );
+ sp = (sp + 2) & 0xFFFF;
+ goto loop;
+
+ case 0x00: // NOP
+ case 0x40: // LD B,B
+ case 0x49: // LD C,C
+ case 0x52: // LD D,D
+ case 0x5B: // LD E,E
+ case 0x64: // LD H,H
+ case 0x6D: // LD L,L
+ case 0x7F: // LD A,A
+ goto loop;
+
+// CB Instructions
+
+ case 0xCB:
+ pc++;
+ // now data is the opcode
+ switch ( data ) {
+
+ {
+ int temp;
+ case 0x46: // BIT b,(HL)
+ case 0x4E:
+ case 0x56:
+ case 0x5E:
+ case 0x66:
+ case 0x6E:
+ case 0x76:
+ case 0x7E:
+ {
+ unsigned addr = rp.hl;
+ READ_FAST( addr, temp );
+ goto bit_comm;
+ }
+
+ case 0x40: case 0x41: case 0x42: case 0x43: // BIT b,r
+ case 0x44: case 0x45: case 0x47: case 0x48:
+ case 0x49: case 0x4A: case 0x4B: case 0x4C:
+ case 0x4D: case 0x4F: case 0x50: case 0x51:
+ case 0x52: case 0x53: case 0x54: case 0x55:
+ case 0x57: case 0x58: case 0x59: case 0x5A:
+ case 0x5B: case 0x5C: case 0x5D: case 0x5F:
+ case 0x60: case 0x61: case 0x62: case 0x63:
+ case 0x64: case 0x65: case 0x67: case 0x68:
+ case 0x69: case 0x6A: case 0x6B: case 0x6C:
+ case 0x6D: case 0x6F: case 0x70: case 0x71:
+ case 0x72: case 0x73: case 0x74: case 0x75:
+ case 0x77: case 0x78: case 0x79: case 0x7A:
+ case 0x7B: case 0x7C: case 0x7D: case 0x7F:
+ temp = R8( data & 7 );
+ bit_comm:
+ int bit = (~data >> 3) & 7;
+ flags &= ~n_flag;
+ flags |= h_flag | z_flag;
+ flags ^= (temp << bit) & z_flag;
+ goto loop;
+ }
+
+ case 0x86: // RES b,(HL)
+ case 0x8E:
+ case 0x96:
+ case 0x9E:
+ case 0xA6:
+ case 0xAE:
+ case 0xB6:
+ case 0xBE:
+ case 0xC6: // SET b,(HL)
+ case 0xCE:
+ case 0xD6:
+ case 0xDE:
+ case 0xE6:
+ case 0xEE:
+ case 0xF6:
+ case 0xFE: {
+ int temp = READ( rp.hl );
+ int bit = 1 << ((data >> 3) & 7);
+ temp &= ~bit;
+ if ( !(data & 0x40) )
+ bit = 0;
+ WRITE( rp.hl, temp | bit );
+ goto loop;
+ }
+
+ case 0xC0: case 0xC1: case 0xC2: case 0xC3: // SET b,r
+ case 0xC4: case 0xC5: case 0xC7: case 0xC8:
+ case 0xC9: case 0xCA: case 0xCB: case 0xCC:
+ case 0xCD: case 0xCF: case 0xD0: case 0xD1:
+ case 0xD2: case 0xD3: case 0xD4: case 0xD5:
+ case 0xD7: case 0xD8: case 0xD9: case 0xDA:
+ case 0xDB: case 0xDC: case 0xDD: case 0xDF:
+ case 0xE0: case 0xE1: case 0xE2: case 0xE3:
+ case 0xE4: case 0xE5: case 0xE7: case 0xE8:
+ case 0xE9: case 0xEA: case 0xEB: case 0xEC:
+ case 0xED: case 0xEF: case 0xF0: case 0xF1:
+ case 0xF2: case 0xF3: case 0xF4: case 0xF5:
+ case 0xF7: case 0xF8: case 0xF9: case 0xFA:
+ case 0xFB: case 0xFC: case 0xFD: case 0xFF:
+ R8( data & 7 ) |= 1 << ((data >> 3) & 7);
+ goto loop;
+
+ case 0x80: case 0x81: case 0x82: case 0x83: // RES b,r
+ case 0x84: case 0x85: case 0x87: case 0x88:
+ case 0x89: case 0x8A: case 0x8B: case 0x8C:
+ case 0x8D: case 0x8F: case 0x90: case 0x91:
+ case 0x92: case 0x93: case 0x94: case 0x95:
+ case 0x97: case 0x98: case 0x99: case 0x9A:
+ case 0x9B: case 0x9C: case 0x9D: case 0x9F:
+ case 0xA0: case 0xA1: case 0xA2: case 0xA3:
+ case 0xA4: case 0xA5: case 0xA7: case 0xA8:
+ case 0xA9: case 0xAA: case 0xAB: case 0xAC:
+ case 0xAD: case 0xAF: case 0xB0: case 0xB1:
+ case 0xB2: case 0xB3: case 0xB4: case 0xB5:
+ case 0xB7: case 0xB8: case 0xB9: case 0xBA:
+ case 0xBB: case 0xBC: case 0xBD: case 0xBF:
+ R8( data & 7 ) &= ~(1 << ((data >> 3) & 7));
+ goto loop;
+
+ {
+ int temp;
+ case 0x36: // SWAP (HL)
+ temp = READ( rp.hl );
+ goto swap_comm;
+
+ case 0x30: // SWAP B
+ case 0x31: // SWAP C
+ case 0x32: // SWAP D
+ case 0x33: // SWAP E
+ case 0x34: // SWAP H
+ case 0x35: // SWAP L
+ case 0x37: // SWAP A
+ temp = R8( data & 7 );
+ swap_comm:
+ op = (temp >> 4) | (temp << 4);
+ flags = 0;
+ goto shift_comm;
+ }
+
+// Shift/Rotate
+
+ case 0x06: // RLC (HL)
+ case 0x16: // RL (HL)
+ case 0x26: // SLA (HL)
+ op = READ( rp.hl );
+ goto rl_comm;
+
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x27: // SLA A
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x07: // RLC A
+ case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x17: // RL A
+ op = R8( data & 7 );
+ goto rl_comm;
+
+ case 0x3E: // SRL (HL)
+ data += 0x10; // bump up to 0x4n to avoid preserving sign bit
+ case 0x1E: // RR (HL)
+ case 0x0E: // RRC (HL)
+ case 0x2E: // SRA (HL)
+ op = READ( rp.hl );
+ goto rr_comm;
+
+ case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3F: // SRL A
+ data += 0x10; // bump up to 0x4n
+ case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1F: // RR A
+ case 0x08: case 0x09: case 0x0A: case 0x0B: case 0x0C: case 0x0D: case 0x0F: // RRC A
+ case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2F: // SRA A
+ op = R8( data & 7 );
+ goto rr_comm;
+
+ } // CB op
+ assert( false ); // unhandled CB op
+
+ case 0x07: // RLCA
+ case 0x17: // RLA
+ data = op;
+ op = rg.a;
+ rl_comm:
+ op <<= 1;
+ op |= ((data & flags) >> 4) & 1; // RL and carry is set
+ flags = (op >> 4) & c_flag; // C = bit shifted out
+ if ( data < 0x10 ) // RLC
+ op |= op >> 8;
+ // SLA doesn't fill lower bit
+ goto shift_comm;
+
+ case 0x0F: // RRCA
+ case 0x1F: // RRA
+ data = op;
+ op = rg.a;
+ rr_comm:
+ op |= (data & flags) << 4; // RR and carry is set
+ flags = (op << 4) & c_flag; // C = bit shifted out
+ if ( data < 0x10 ) // RRC
+ op |= op << 8;
+ op >>= 1;
+ if ( data & 0x20 ) // SRA propagates sign bit
+ op |= (op << 1) & 0x80;
+ shift_comm:
+ data &= 7;
+ if ( !(op & 0xFF) )
+ flags |= z_flag;
+ if ( data == 6 )
+ goto write_hl_op_ff;
+ R8( data ) = op;
+ goto loop;
+
+// Load
+
+ case 0x70: // LD (HL),B
+ case 0x71: // LD (HL),C
+ case 0x72: // LD (HL),D
+ case 0x73: // LD (HL),E
+ case 0x74: // LD (HL),H
+ case 0x75: // LD (HL),L
+ case 0x77: // LD (HL),A
+ op = R8( op & 7 );
+ write_hl_op_ff:
+ WRITE( rp.hl, op & 0xFF );
+ goto loop;
+
+ case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x47: // LD r,r
+ case 0x48: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4F:
+ case 0x50: case 0x51: case 0x53: case 0x54: case 0x55: case 0x57:
+ case 0x58: case 0x59: case 0x5A: case 0x5C: case 0x5D: case 0x5F:
+ case 0x60: case 0x61: case 0x62: case 0x63: case 0x65: case 0x67:
+ case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6F:
+ case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D:
+ R8( (op >> 3) & 7 ) = R8( op & 7 );
+ goto loop;
+
+ case 0x08: // LD IND16,SP
+ data = GET_ADDR();
+ pc += 2;
+ WRITE( data, sp&0xFF );
+ data++;
+ WRITE( data, sp >> 8 );
+ goto loop;
+
+ case 0xF9: // LD SP,HL
+ sp = rp.hl;
+ goto loop;
+
+ case 0x31: // LD SP,IMM
+ sp = GET_ADDR();
+ pc += 2;
+ goto loop;
+
+ case 0x01: // LD BC,IMM
+ case 0x11: // LD DE,IMM
+ r16 [op >> 4] = GET_ADDR();
+ pc += 2;
+ goto loop;
+
+ {
+ unsigned temp;
+ case 0xE0: // LD (0xFF00+imm),A
+ temp = data | 0xFF00;
+ pc++;
+ goto write_data_rg_a;
+
+ case 0xE2: // LD (0xFF00+C),A
+ temp = rg.c | 0xFF00;
+ goto write_data_rg_a;
+
+ case 0x32: // LD (HL-),A
+ temp = rp.hl;
+ rp.hl = temp - 1;
+ goto write_data_rg_a;
+
+ case 0x02: // LD (BC),A
+ temp = rp.bc;
+ goto write_data_rg_a;
+
+ case 0x12: // LD (DE),A
+ temp = rp.de;
+ goto write_data_rg_a;
+
+ case 0x22: // LD (HL+),A
+ temp = rp.hl;
+ rp.hl = temp + 1;
+ goto write_data_rg_a;
+
+ case 0xEA: // LD IND16,A (common)
+ temp = GET_ADDR();
+ pc += 2;
+ write_data_rg_a:
+ WRITE( temp, rg.a );
+ goto loop;
+ }
+
+ case 0x06: // LD B,IMM
+ rg.b = data;
+ pc++;
+ goto loop;
+
+ case 0x0E: // LD C,IMM
+ rg.c = data;
+ pc++;
+ goto loop;
+
+ case 0x16: // LD D,IMM
+ rg.d = data;
+ pc++;
+ goto loop;
+
+ case 0x1E: // LD E,IMM
+ rg.e = data;
+ pc++;
+ goto loop;
+
+ case 0x26: // LD H,IMM
+ rg.h = data;
+ pc++;
+ goto loop;
+
+ case 0x2E: // LD L,IMM
+ rg.l = data;
+ pc++;
+ goto loop;
+
+ case 0x36: // LD (HL),IMM
+ WRITE( rp.hl, data );
+ pc++;
+ goto loop;
+
+ case 0x3E: // LD A,IMM
+ rg.a = data;
+ pc++;
+ goto loop;
+
+// Increment/Decrement
+
+ case 0x03: // INC BC
+ case 0x13: // INC DE
+ case 0x23: // INC HL
+ r16 [op >> 4]++;
+ goto loop;
+
+ case 0x33: // INC SP
+ sp = (sp + 1) & 0xFFFF;
+ goto loop;
+
+ case 0x0B: // DEC BC
+ case 0x1B: // DEC DE
+ case 0x2B: // DEC HL
+ r16 [op >> 4]--;
+ goto loop;
+
+ case 0x3B: // DEC SP
+ sp = (sp - 1) & 0xFFFF;
+ goto loop;
+
+ case 0x34: // INC (HL)
+ op = rp.hl;
+ data = READ( op );
+ data++;
+ WRITE( op, data & 0xFF );
+ goto inc_comm;
+
+ case 0x04: // INC B
+ case 0x0C: // INC C (common)
+ case 0x14: // INC D
+ case 0x1C: // INC E
+ case 0x24: // INC H
+ case 0x2C: // INC L
+ case 0x3C: // INC A
+ op = (op >> 3) & 7;
+ R8( op ) = data = R8( op ) + 1;
+ inc_comm:
+ flags = (flags & c_flag) | (((data & 15) - 1) & h_flag) | ((data >> 1) & z_flag);
+ goto loop;
+
+ case 0x35: // DEC (HL)
+ op = rp.hl;
+ data = READ( op );
+ data--;
+ WRITE( op, data & 0xFF );
+ goto dec_comm;
+
+ case 0x05: // DEC B
+ case 0x0D: // DEC C
+ case 0x15: // DEC D
+ case 0x1D: // DEC E
+ case 0x25: // DEC H
+ case 0x2D: // DEC L
+ case 0x3D: // DEC A
+ op = (op >> 3) & 7;
+ data = R8( op ) - 1;
+ R8( op ) = data;
+ dec_comm:
+ flags = (flags & c_flag) | n_flag | (((data & 15) + 0x31) & h_flag);
+ if ( data & 0xFF )
+ goto loop;
+ flags |= z_flag;
+ goto loop;
+
+// Add 16-bit
+
+ {
+ blargg_ulong temp; // need more than 16 bits for carry
+ unsigned prev;
+
+ case 0xF8: // LD HL,SP+imm
+ temp = int8_t (data); // sign-extend to 16 bits
+ pc++;
+ flags = 0;
+ temp += sp;
+ prev = sp;
+ goto add_16_hl;
+
+ case 0xE8: // ADD SP,IMM
+ temp = int8_t (data); // sign-extend to 16 bits
+ pc++;
+ flags = 0;
+ temp += sp;
+ prev = sp;
+ sp = temp & 0xFFFF;
+ goto add_16_comm;
+
+ case 0x39: // ADD HL,SP
+ temp = sp;
+ goto add_hl_comm;
+
+ case 0x09: // ADD HL,BC
+ case 0x19: // ADD HL,DE
+ case 0x29: // ADD HL,HL
+ temp = r16 [op >> 4];
+ add_hl_comm:
+ prev = rp.hl;
+ temp += prev;
+ flags &= z_flag;
+ add_16_hl:
+ rp.hl = temp;
+ add_16_comm:
+ flags |= (temp >> 12) & c_flag;
+ flags |= (((temp & 0x0FFF) - (prev & 0x0FFF)) >> 7) & h_flag;
+ goto loop;
+ }
+
+ case 0x86: // ADD (HL)
+ data = READ( rp.hl );
+ goto add_comm;
+
+ case 0x80: // ADD B
+ case 0x81: // ADD C
+ case 0x82: // ADD D
+ case 0x83: // ADD E
+ case 0x84: // ADD H
+ case 0x85: // ADD L
+ case 0x87: // ADD A
+ data = R8( op & 7 );
+ goto add_comm;
+
+ case 0xC6: // ADD IMM
+ pc++;
+ add_comm:
+ flags = rg.a;
+ data += flags;
+ flags = ((data & 15) - (flags & 15)) & h_flag;
+ flags |= (data >> 4) & c_flag;
+ rg.a = data;
+ if ( data & 0xFF )
+ goto loop;
+ flags |= z_flag;
+ goto loop;
+
+// Add/Subtract
+
+ case 0x8E: // ADC (HL)
+ data = READ( rp.hl );
+ goto adc_comm;
+
+ case 0x88: // ADC B
+ case 0x89: // ADC C
+ case 0x8A: // ADC D
+ case 0x8B: // ADC E
+ case 0x8C: // ADC H
+ case 0x8D: // ADC L
+ case 0x8F: // ADC A
+ data = R8( op & 7 );
+ goto adc_comm;
+
+ case 0xCE: // ADC IMM
+ pc++;
+ adc_comm:
+ data += (flags >> 4) & 1;
+ data &= 0xFF; // to do: does carry get set when sum + carry = 0x100?
+ goto add_comm;
+
+ case 0x96: // SUB (HL)
+ data = READ( rp.hl );
+ goto sub_comm;
+
+ case 0x90: // SUB B
+ case 0x91: // SUB C
+ case 0x92: // SUB D
+ case 0x93: // SUB E
+ case 0x94: // SUB H
+ case 0x95: // SUB L
+ case 0x97: // SUB A
+ data = R8( op & 7 );
+ goto sub_comm;
+
+ case 0xD6: // SUB IMM
+ pc++;
+ sub_comm:
+ op = rg.a;
+ data = op - data;
+ rg.a = data;
+ goto sub_set_flags;
+
+ case 0x9E: // SBC (HL)
+ data = READ( rp.hl );
+ goto sbc_comm;
+
+ case 0x98: // SBC B
+ case 0x99: // SBC C
+ case 0x9A: // SBC D
+ case 0x9B: // SBC E
+ case 0x9C: // SBC H
+ case 0x9D: // SBC L
+ case 0x9F: // SBC A
+ data = R8( op & 7 );
+ goto sbc_comm;
+
+ case 0xDE: // SBC IMM
+ pc++;
+ sbc_comm:
+ data += (flags >> 4) & 1;
+ data &= 0xFF; // to do: does carry get set when sum + carry = 0x100?
+ goto sub_comm;
+
+// Logical
+
+ case 0xA0: // AND B
+ case 0xA1: // AND C
+ case 0xA2: // AND D
+ case 0xA3: // AND E
+ case 0xA4: // AND H
+ case 0xA5: // AND L
+ data = R8( op & 7 );
+ goto and_comm;
+
+ case 0xA6: // AND (HL)
+ data = READ( rp.hl );
+ pc--;
+ case 0xE6: // AND IMM
+ pc++;
+ and_comm:
+ rg.a &= data;
+ case 0xA7: // AND A
+ flags = h_flag | (((rg.a - 1) >> 1) & z_flag);
+ goto loop;
+
+ case 0xB0: // OR B
+ case 0xB1: // OR C
+ case 0xB2: // OR D
+ case 0xB3: // OR E
+ case 0xB4: // OR H
+ case 0xB5: // OR L
+ data = R8( op & 7 );
+ goto or_comm;
+
+ case 0xB6: // OR (HL)
+ data = READ( rp.hl );
+ pc--;
+ case 0xF6: // OR IMM
+ pc++;
+ or_comm:
+ rg.a |= data;
+ case 0xB7: // OR A
+ flags = ((rg.a - 1) >> 1) & z_flag;
+ goto loop;
+
+ case 0xA8: // XOR B
+ case 0xA9: // XOR C
+ case 0xAA: // XOR D
+ case 0xAB: // XOR E
+ case 0xAC: // XOR H
+ case 0xAD: // XOR L
+ data = R8( op & 7 );
+ goto xor_comm;
+
+ case 0xAE: // XOR (HL)
+ data = READ( rp.hl );
+ pc--;
+ case 0xEE: // XOR IMM
+ pc++;
+ xor_comm:
+ data ^= rg.a;
+ rg.a = data;
+ data--;
+ flags = (data >> 1) & z_flag;
+ goto loop;
+
+ case 0xAF: // XOR A
+ rg.a = 0;
+ flags = z_flag;
+ goto loop;
+
+// Stack
+
+ case 0xF1: // POP FA
+ case 0xC1: // POP BC
+ case 0xD1: // POP DE
+ case 0xE1: // POP HL (common)
+ data = READ( sp );
+ r16 [(op >> 4) & 3] = data + 0x100 * READ( sp + 1 );
+ sp = (sp + 2) & 0xFFFF;
+ if ( op != 0xF1 )
+ goto loop;
+ flags = rg.flags & 0xF0;
+ goto loop;
+
+ case 0xC5: // PUSH BC
+ data = rp.bc;
+ goto push;
+
+ case 0xD5: // PUSH DE
+ data = rp.de;
+ goto push;
+
+ case 0xE5: // PUSH HL
+ data = rp.hl;
+ goto push;
+
+ case 0xF5: // PUSH FA
+ data = (flags << 8) | rg.a;
+ goto push;
+
+// Flow control
+
+ case 0xFF:
+ if ( pc == idle_addr + 1 )
+ goto stop;
+ case 0xC7: case 0xCF: case 0xD7: case 0xDF: // RST
+ case 0xE7: case 0xEF: case 0xF7:
+ data = pc;
+ pc = (op & 0x38) + rst_base;
+ goto push;
+
+ case 0xCC: // CZ
+ pc += 2;
+ if ( flags & z_flag )
+ goto call;
+ goto loop;
+
+ case 0xD4: // CNC
+ pc += 2;
+ if ( !(flags & c_flag) )
+ goto call;
+ goto loop;
+
+ case 0xDC: // CC
+ pc += 2;
+ if ( flags & c_flag )
+ goto call;
+ goto loop;
+
+ case 0xD9: // RETI
+ //interrupts_enabled = 1;
+ goto ret;
+
+ case 0xC0: // RZ
+ if ( !(flags & z_flag) )
+ goto ret;
+ goto loop;
+
+ case 0xD0: // RNC
+ if ( !(flags & c_flag) )
+ goto ret;
+ goto loop;
+
+ case 0xD8: // RC
+ if ( flags & c_flag )
+ goto ret;
+ goto loop;
+
+ case 0x18: // JR
+ BRANCH( true )
+
+ case 0x30: // JR NC
+ BRANCH( !(flags & c_flag) )
+
+ case 0x38: // JR C
+ BRANCH( flags & c_flag )
+
+ case 0xE9: // JP_HL
+ pc = rp.hl;
+ goto loop;
+
+ case 0xC3: // JP (next-most-common)
+ pc = GET_ADDR();
+ goto loop;
+
+ case 0xC2: // JP NZ
+ pc += 2;
+ if ( !(flags & z_flag) )
+ goto jp_taken;
+ goto loop;
+
+ case 0xCA: // JP Z (most common)
+ pc += 2;
+ if ( !(flags & z_flag) )
+ goto loop;
+ jp_taken:
+ pc -= 2;
+ pc = GET_ADDR();
+ goto loop;
+
+ case 0xD2: // JP NC
+ pc += 2;
+ if ( !(flags & c_flag) )
+ goto jp_taken;
+ goto loop;
+
+ case 0xDA: // JP C
+ pc += 2;
+ if ( flags & c_flag )
+ goto jp_taken;
+ goto loop;
+
+// Flags
+
+ case 0x2F: // CPL
+ rg.a = ~rg.a;
+ flags |= n_flag | h_flag;
+ goto loop;
+
+ case 0x3F: // CCF
+ flags = (flags ^ c_flag) & ~(n_flag | h_flag);
+ goto loop;
+
+ case 0x37: // SCF
+ flags = (flags | c_flag) & ~(n_flag | h_flag);
+ goto loop;
+
+ case 0xF3: // DI
+ //interrupts_enabled = 0;
+ goto loop;
+
+ case 0xFB: // EI
+ //interrupts_enabled = 1;
+ goto loop;
+
+// Special
+
+ case 0xDD: case 0xD3: case 0xDB: case 0xE3: case 0xE4: // ?
+ case 0xEB: case 0xEC: case 0xF4: case 0xFD: case 0xFC:
+ case 0x10: // STOP
+ case 0x27: // DAA (I'll have to implement this eventually...)
+ case 0xBF:
+ case 0xED: // Z80 prefix
+ case 0x76: // HALT
+ s.remain++;
+ goto stop;
+ }
+
+ // If this fails then the case above is missing an opcode
+ assert( false );
+
+stop:
+ pc--;
+
+ // copy state back
+ STATIC_CAST(core_regs_t&,r) = rg;
+ r.pc = pc;
+ r.sp = sp;
+ r.flags = flags;
+
+ this->state = &state_;
+ memcpy( &this->state_, &s, sizeof this->state_ );
+
+ return s.remain > 0;
+}
diff --git a/src/console/Gb_Cpu.cxx b/src/console/Gb_Cpu.cxx
deleted file mode 100644
index 9954b5026a33..000000000000
--- a/src/console/Gb_Cpu.cxx
+++ /dev/null
@@ -1,1052 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Gb_Cpu.h"
-
-#include <string.h>
-
-//#include "gb_cpu_log.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "gb_cpu_io.h"
-
-#include "blargg_source.h"
-
-// Common instructions:
-//
-// 365880 FA LD A,IND16
-// 355863 20 JR NZ
-// 313655 21 LD HL,IMM
-// 274580 28 JR Z
-// 252878 FE CMP IMM
-// 230541 7E LD A,(HL)
-// 226209 2A LD A,(HL+)
-// 217467 CD CALL
-// 212034 C9 RET
-// 208376 CB CB prefix
-//
-// 27486 CB 7E BIT 7,(HL)
-// 15925 CB 76 BIT 6,(HL)
-// 13035 CB 19 RR C
-// 11557 CB 7F BIT 7,A
-// 10898 CB 37 SWAP A
-// 10208 CB 66 BIT 4,(HL)
-
-#if BLARGG_NONPORTABLE
- #define PAGE_OFFSET( addr ) (addr)
-#else
- #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
-#endif
-
-inline void Gb_Cpu::set_code_page( int i, uint8_t* p )
-{
- state->code_map [i] = p - PAGE_OFFSET( i * (blargg_long) page_size );
-}
-
-void Gb_Cpu::reset( void* unmapped )
-{
- check( state == &state_ );
- state = &state_;
-
- state_.remain = 0;
-
- for ( int i = 0; i < page_count + 1; i++ )
- set_code_page( i, (uint8_t*) unmapped );
-
- memset( &r, 0, sizeof r );
- //interrupts_enabled = false;
-}
-
-void Gb_Cpu::map_code( gb_addr_t start, unsigned size, void* data )
-{
- // address range must begin and end on page boundaries
- require( start % page_size == 0 );
- require( size % page_size == 0 );
-
- unsigned first_page = start / page_size;
- for ( unsigned i = size / page_size; i--; )
- set_code_page( first_page + i, (uint8_t*) data + i * page_size );
-}
-
-#define READ( addr ) CPU_READ( this, (addr), s.remain )
-#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), s.remain );}
-#define READ_FAST( addr, out ) CPU_READ_FAST( this, (addr), s.remain, out )
-#define READ_PROG( addr ) (s.code_map [(addr) >> page_shift] [PAGE_OFFSET( addr )])
-
-unsigned const z_flag = 0x80;
-unsigned const n_flag = 0x40;
-unsigned const h_flag = 0x20;
-unsigned const c_flag = 0x10;
-
-bool Gb_Cpu::run( blargg_long cycle_count )
-{
- state_.remain = blargg_ulong (cycle_count + clocks_per_instr) / clocks_per_instr;
- state_t s;
- this->state = &s;
- memcpy( &s, &this->state_, sizeof s );
-
-#if BLARGG_BIG_ENDIAN
- #define R8( n ) (r8_ [n])
-#elif BLARGG_LITTLE_ENDIAN
- #define R8( n ) (r8_ [(n) ^ 1])
-#else
- #error "Byte order of CPU must be known"
-#endif
-
- union {
- core_regs_t rg; // individual registers
-
- struct {
- uint16_t bc, de, hl, unused; // pairs
- } rp;
-
- uint8_t r8_ [8]; // indexed registers (use R8 macro due to endian dependence)
- uint16_t r16 [4]; // indexed pairs
- };
- BOOST_STATIC_ASSERT( sizeof rg == 8 && sizeof rp == 8 );
-
- rg = r;
- unsigned pc = r.pc;
- unsigned sp = r.sp;
- unsigned flags = r.flags;
-
-loop:
-
- check( (unsigned long) pc < 0x10000 );
- check( (unsigned long) sp < 0x10000 );
- check( (flags & ~0xF0) == 0 );
-
- uint8_t const* instr = s.code_map [pc >> page_shift];
- unsigned op;
-
- // TODO: eliminate this special case
- #if BLARGG_NONPORTABLE
- op = instr [pc];
- pc++;
- instr += pc;
- #else
- instr += PAGE_OFFSET( pc );
- op = *instr++;
- pc++;
- #endif
-
-#define GET_ADDR() GET_LE16( instr )
-
- if ( !--s.remain )
- goto stop;
-
- unsigned data;
- data = *instr;
-
- #ifdef GB_CPU_LOG_H
- gb_cpu_log( "new", pc - 1, op, data, instr [1] );
- #endif
-
- switch ( op )
- {
-
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define BRANCH( cond )\
-{\
- pc++;\
- int offset = (int8_t) data;\
- if ( !(cond) ) goto loop;\
- pc = uint16_t (pc + offset);\
- goto loop;\
-}
-
-// Most Common
-
- case 0x20: // JR NZ
- BRANCH( !(flags & z_flag) )
-
- case 0x21: // LD HL,IMM (common)
- rp.hl = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x28: // JR Z
- BRANCH( flags & z_flag )
-
- {
- unsigned temp;
- case 0xF0: // LD A,(0xFF00+imm)
- temp = data | 0xFF00;
- pc++;
- goto ld_a_ind_comm;
-
- case 0xF2: // LD A,(0xFF00+C)
- temp = rg.c | 0xFF00;
- goto ld_a_ind_comm;
-
- case 0x0A: // LD A,(BC)
- temp = rp.bc;
- goto ld_a_ind_comm;
-
- case 0x3A: // LD A,(HL-)
- temp = rp.hl;
- rp.hl = temp - 1;
- goto ld_a_ind_comm;
-
- case 0x1A: // LD A,(DE)
- temp = rp.de;
- goto ld_a_ind_comm;
-
- case 0x2A: // LD A,(HL+) (common)
- temp = rp.hl;
- rp.hl = temp + 1;
- goto ld_a_ind_comm;
-
- case 0xFA: // LD A,IND16 (common)
- temp = GET_ADDR();
- pc += 2;
- ld_a_ind_comm:
- READ_FAST( temp, rg.a );
- goto loop;
- }
-
- case 0xBE: // CMP (HL)
- data = READ( rp.hl );
- goto cmp_comm;
-
- case 0xB8: // CMP B
- case 0xB9: // CMP C
- case 0xBA: // CMP D
- case 0xBB: // CMP E
- case 0xBC: // CMP H
- case 0xBD: // CMP L
- data = R8( op & 7 );
- goto cmp_comm;
-
- case 0xFE: // CMP IMM
- pc++;
- cmp_comm:
- op = rg.a;
- data = op - data;
- sub_set_flags:
- flags = ((op & 15) - (data & 15)) & h_flag;
- flags |= (data >> 4) & c_flag;
- flags |= n_flag;
- if ( data & 0xFF )
- goto loop;
- flags |= z_flag;
- goto loop;
-
- case 0x46: // LD B,(HL)
- case 0x4E: // LD C,(HL)
- case 0x56: // LD D,(HL)
- case 0x5E: // LD E,(HL)
- case 0x66: // LD H,(HL)
- case 0x6E: // LD L,(HL)
- case 0x7E:{// LD A,(HL)
- unsigned addr = rp.hl;
- READ_FAST( addr, R8( (op >> 3) & 7 ) );
- goto loop;
- }
-
- case 0xC4: // CNZ (next-most-common)
- pc += 2;
- if ( flags & z_flag )
- goto loop;
- call:
- pc -= 2;
- case 0xCD: // CALL (most-common)
- data = pc + 2;
- pc = GET_ADDR();
- push:
- sp = (sp - 1) & 0xFFFF;
- WRITE( sp, data >> 8 );
- sp = (sp - 1) & 0xFFFF;
- WRITE( sp, data & 0xFF );
- goto loop;
-
- case 0xC8: // RNZ (next-most-common)
- if ( !(flags & z_flag) )
- goto loop;
- case 0xC9: // RET (most common)
- ret:
- pc = READ( sp );
- pc += 0x100 * READ( sp + 1 );
- sp = (sp + 2) & 0xFFFF;
- goto loop;
-
- case 0x00: // NOP
- case 0x40: // LD B,B
- case 0x49: // LD C,C
- case 0x52: // LD D,D
- case 0x5B: // LD E,E
- case 0x64: // LD H,H
- case 0x6D: // LD L,L
- case 0x7F: // LD A,A
- goto loop;
-
-// CB Instructions
-
- case 0xCB:
- pc++;
- // now data is the opcode
- switch ( data ) {
-
- {
- int temp;
- case 0x46: // BIT b,(HL)
- case 0x4E:
- case 0x56:
- case 0x5E:
- case 0x66:
- case 0x6E:
- case 0x76:
- case 0x7E:
- {
- unsigned addr = rp.hl;
- READ_FAST( addr, temp );
- goto bit_comm;
- }
-
- case 0x40: case 0x41: case 0x42: case 0x43: // BIT b,r
- case 0x44: case 0x45: case 0x47: case 0x48:
- case 0x49: case 0x4A: case 0x4B: case 0x4C:
- case 0x4D: case 0x4F: case 0x50: case 0x51:
- case 0x52: case 0x53: case 0x54: case 0x55:
- case 0x57: case 0x58: case 0x59: case 0x5A:
- case 0x5B: case 0x5C: case 0x5D: case 0x5F:
- case 0x60: case 0x61: case 0x62: case 0x63:
- case 0x64: case 0x65: case 0x67: case 0x68:
- case 0x69: case 0x6A: case 0x6B: case 0x6C:
- case 0x6D: case 0x6F: case 0x70: case 0x71:
- case 0x72: case 0x73: case 0x74: case 0x75:
- case 0x77: case 0x78: case 0x79: case 0x7A:
- case 0x7B: case 0x7C: case 0x7D: case 0x7F:
- temp = R8( data & 7 );
- bit_comm:
- int bit = (~data >> 3) & 7;
- flags &= ~n_flag;
- flags |= h_flag | z_flag;
- flags ^= (temp << bit) & z_flag;
- goto loop;
- }
-
- case 0x86: // RES b,(HL)
- case 0x8E:
- case 0x96:
- case 0x9E:
- case 0xA6:
- case 0xAE:
- case 0xB6:
- case 0xBE:
- case 0xC6: // SET b,(HL)
- case 0xCE:
- case 0xD6:
- case 0xDE:
- case 0xE6:
- case 0xEE:
- case 0xF6:
- case 0xFE: {
- int temp = READ( rp.hl );
- int bit = 1 << ((data >> 3) & 7);
- temp &= ~bit;
- if ( !(data & 0x40) )
- bit = 0;
- WRITE( rp.hl, temp | bit );
- goto loop;
- }
-
- case 0xC0: case 0xC1: case 0xC2: case 0xC3: // SET b,r
- case 0xC4: case 0xC5: case 0xC7: case 0xC8:
- case 0xC9: case 0xCA: case 0xCB: case 0xCC:
- case 0xCD: case 0xCF: case 0xD0: case 0xD1:
- case 0xD2: case 0xD3: case 0xD4: case 0xD5:
- case 0xD7: case 0xD8: case 0xD9: case 0xDA:
- case 0xDB: case 0xDC: case 0xDD: case 0xDF:
- case 0xE0: case 0xE1: case 0xE2: case 0xE3:
- case 0xE4: case 0xE5: case 0xE7: case 0xE8:
- case 0xE9: case 0xEA: case 0xEB: case 0xEC:
- case 0xED: case 0xEF: case 0xF0: case 0xF1:
- case 0xF2: case 0xF3: case 0xF4: case 0xF5:
- case 0xF7: case 0xF8: case 0xF9: case 0xFA:
- case 0xFB: case 0xFC: case 0xFD: case 0xFF:
- R8( data & 7 ) |= 1 << ((data >> 3) & 7);
- goto loop;
-
- case 0x80: case 0x81: case 0x82: case 0x83: // RES b,r
- case 0x84: case 0x85: case 0x87: case 0x88:
- case 0x89: case 0x8A: case 0x8B: case 0x8C:
- case 0x8D: case 0x8F: case 0x90: case 0x91:
- case 0x92: case 0x93: case 0x94: case 0x95:
- case 0x97: case 0x98: case 0x99: case 0x9A:
- case 0x9B: case 0x9C: case 0x9D: case 0x9F:
- case 0xA0: case 0xA1: case 0xA2: case 0xA3:
- case 0xA4: case 0xA5: case 0xA7: case 0xA8:
- case 0xA9: case 0xAA: case 0xAB: case 0xAC:
- case 0xAD: case 0xAF: case 0xB0: case 0xB1:
- case 0xB2: case 0xB3: case 0xB4: case 0xB5:
- case 0xB7: case 0xB8: case 0xB9: case 0xBA:
- case 0xBB: case 0xBC: case 0xBD: case 0xBF:
- R8( data & 7 ) &= ~(1 << ((data >> 3) & 7));
- goto loop;
-
- {
- int temp;
- case 0x36: // SWAP (HL)
- temp = READ( rp.hl );
- goto swap_comm;
-
- case 0x30: // SWAP B
- case 0x31: // SWAP C
- case 0x32: // SWAP D
- case 0x33: // SWAP E
- case 0x34: // SWAP H
- case 0x35: // SWAP L
- case 0x37: // SWAP A
- temp = R8( data & 7 );
- swap_comm:
- op = (temp >> 4) | (temp << 4);
- flags = 0;
- goto shift_comm;
- }
-
-// Shift/Rotate
-
- case 0x06: // RLC (HL)
- case 0x16: // RL (HL)
- case 0x26: // SLA (HL)
- op = READ( rp.hl );
- goto rl_comm;
-
- case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x27: // SLA A
- case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x07: // RLC A
- case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x17: // RL A
- op = R8( data & 7 );
- goto rl_comm;
-
- case 0x3E: // SRL (HL)
- data += 0x10; // bump up to 0x4n to avoid preserving sign bit
- case 0x1E: // RR (HL)
- case 0x0E: // RRC (HL)
- case 0x2E: // SRA (HL)
- op = READ( rp.hl );
- goto rr_comm;
-
- case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3F: // SRL A
- data += 0x10; // bump up to 0x4n
- case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1F: // RR A
- case 0x08: case 0x09: case 0x0A: case 0x0B: case 0x0C: case 0x0D: case 0x0F: // RRC A
- case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2F: // SRA A
- op = R8( data & 7 );
- goto rr_comm;
-
- } // CB op
- assert( false ); // unhandled CB op
-
- case 0x07: // RLCA
- case 0x17: // RLA
- data = op;
- op = rg.a;
- rl_comm:
- op <<= 1;
- op |= ((data & flags) >> 4) & 1; // RL and carry is set
- flags = (op >> 4) & c_flag; // C = bit shifted out
- if ( data < 0x10 ) // RLC
- op |= op >> 8;
- // SLA doesn't fill lower bit
- goto shift_comm;
-
- case 0x0F: // RRCA
- case 0x1F: // RRA
- data = op;
- op = rg.a;
- rr_comm:
- op |= (data & flags) << 4; // RR and carry is set
- flags = (op << 4) & c_flag; // C = bit shifted out
- if ( data < 0x10 ) // RRC
- op |= op << 8;
- op >>= 1;
- if ( data & 0x20 ) // SRA propagates sign bit
- op |= (op << 1) & 0x80;
- shift_comm:
- data &= 7;
- if ( !(op & 0xFF) )
- flags |= z_flag;
- if ( data == 6 )
- goto write_hl_op_ff;
- R8( data ) = op;
- goto loop;
-
-// Load
-
- case 0x70: // LD (HL),B
- case 0x71: // LD (HL),C
- case 0x72: // LD (HL),D
- case 0x73: // LD (HL),E
- case 0x74: // LD (HL),H
- case 0x75: // LD (HL),L
- case 0x77: // LD (HL),A
- op = R8( op & 7 );
- write_hl_op_ff:
- WRITE( rp.hl, op & 0xFF );
- goto loop;
-
- case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x47: // LD r,r
- case 0x48: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4F:
- case 0x50: case 0x51: case 0x53: case 0x54: case 0x55: case 0x57:
- case 0x58: case 0x59: case 0x5A: case 0x5C: case 0x5D: case 0x5F:
- case 0x60: case 0x61: case 0x62: case 0x63: case 0x65: case 0x67:
- case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6F:
- case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D:
- R8( (op >> 3) & 7 ) = R8( op & 7 );
- goto loop;
-
- case 0x08: // LD IND16,SP
- data = GET_ADDR();
- pc += 2;
- WRITE( data, sp&0xFF );
- data++;
- WRITE( data, sp >> 8 );
- goto loop;
-
- case 0xF9: // LD SP,HL
- sp = rp.hl;
- goto loop;
-
- case 0x31: // LD SP,IMM
- sp = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x01: // LD BC,IMM
- case 0x11: // LD DE,IMM
- r16 [op >> 4] = GET_ADDR();
- pc += 2;
- goto loop;
-
- {
- unsigned temp;
- case 0xE0: // LD (0xFF00+imm),A
- temp = data | 0xFF00;
- pc++;
- goto write_data_rg_a;
-
- case 0xE2: // LD (0xFF00+C),A
- temp = rg.c | 0xFF00;
- goto write_data_rg_a;
-
- case 0x32: // LD (HL-),A
- temp = rp.hl;
- rp.hl = temp - 1;
- goto write_data_rg_a;
-
- case 0x02: // LD (BC),A
- temp = rp.bc;
- goto write_data_rg_a;
-
- case 0x12: // LD (DE),A
- temp = rp.de;
- goto write_data_rg_a;
-
- case 0x22: // LD (HL+),A
- temp = rp.hl;
- rp.hl = temp + 1;
- goto write_data_rg_a;
-
- case 0xEA: // LD IND16,A (common)
- temp = GET_ADDR();
- pc += 2;
- write_data_rg_a:
- WRITE( temp, rg.a );
- goto loop;
- }
-
- case 0x06: // LD B,IMM
- rg.b = data;
- pc++;
- goto loop;
-
- case 0x0E: // LD C,IMM
- rg.c = data;
- pc++;
- goto loop;
-
- case 0x16: // LD D,IMM
- rg.d = data;
- pc++;
- goto loop;
-
- case 0x1E: // LD E,IMM
- rg.e = data;
- pc++;
- goto loop;
-
- case 0x26: // LD H,IMM
- rg.h = data;
- pc++;
- goto loop;
-
- case 0x2E: // LD L,IMM
- rg.l = data;
- pc++;
- goto loop;
-
- case 0x36: // LD (HL),IMM
- WRITE( rp.hl, data );
- pc++;
- goto loop;
-
- case 0x3E: // LD A,IMM
- rg.a = data;
- pc++;
- goto loop;
-
-// Increment/Decrement
-
- case 0x03: // INC BC
- case 0x13: // INC DE
- case 0x23: // INC HL
- r16 [op >> 4]++;
- goto loop;
-
- case 0x33: // INC SP
- sp = (sp + 1) & 0xFFFF;
- goto loop;
-
- case 0x0B: // DEC BC
- case 0x1B: // DEC DE
- case 0x2B: // DEC HL
- r16 [op >> 4]--;
- goto loop;
-
- case 0x3B: // DEC SP
- sp = (sp - 1) & 0xFFFF;
- goto loop;
-
- case 0x34: // INC (HL)
- op = rp.hl;
- data = READ( op );
- data++;
- WRITE( op, data & 0xFF );
- goto inc_comm;
-
- case 0x04: // INC B
- case 0x0C: // INC C (common)
- case 0x14: // INC D
- case 0x1C: // INC E
- case 0x24: // INC H
- case 0x2C: // INC L
- case 0x3C: // INC A
- op = (op >> 3) & 7;
- R8( op ) = data = R8( op ) + 1;
- inc_comm:
- flags = (flags & c_flag) | (((data & 15) - 1) & h_flag) | ((data >> 1) & z_flag);
- goto loop;
-
- case 0x35: // DEC (HL)
- op = rp.hl;
- data = READ( op );
- data--;
- WRITE( op, data & 0xFF );
- goto dec_comm;
-
- case 0x05: // DEC B
- case 0x0D: // DEC C
- case 0x15: // DEC D
- case 0x1D: // DEC E
- case 0x25: // DEC H
- case 0x2D: // DEC L
- case 0x3D: // DEC A
- op = (op >> 3) & 7;
- data = R8( op ) - 1;
- R8( op ) = data;
- dec_comm:
- flags = (flags & c_flag) | n_flag | (((data & 15) + 0x31) & h_flag);
- if ( data & 0xFF )
- goto loop;
- flags |= z_flag;
- goto loop;
-
-// Add 16-bit
-
- {
- blargg_ulong temp; // need more than 16 bits for carry
- unsigned prev;
-
- case 0xF8: // LD HL,SP+imm
- temp = int8_t (data); // sign-extend to 16 bits
- pc++;
- flags = 0;
- temp += sp;
- prev = sp;
- goto add_16_hl;
-
- case 0xE8: // ADD SP,IMM
- temp = int8_t (data); // sign-extend to 16 bits
- pc++;
- flags = 0;
- temp += sp;
- prev = sp;
- sp = temp & 0xFFFF;
- goto add_16_comm;
-
- case 0x39: // ADD HL,SP
- temp = sp;
- goto add_hl_comm;
-
- case 0x09: // ADD HL,BC
- case 0x19: // ADD HL,DE
- case 0x29: // ADD HL,HL
- temp = r16 [op >> 4];
- add_hl_comm:
- prev = rp.hl;
- temp += prev;
- flags &= z_flag;
- add_16_hl:
- rp.hl = temp;
- add_16_comm:
- flags |= (temp >> 12) & c_flag;
- flags |= (((temp & 0x0FFF) - (prev & 0x0FFF)) >> 7) & h_flag;
- goto loop;
- }
-
- case 0x86: // ADD (HL)
- data = READ( rp.hl );
- goto add_comm;
-
- case 0x80: // ADD B
- case 0x81: // ADD C
- case 0x82: // ADD D
- case 0x83: // ADD E
- case 0x84: // ADD H
- case 0x85: // ADD L
- case 0x87: // ADD A
- data = R8( op & 7 );
- goto add_comm;
-
- case 0xC6: // ADD IMM
- pc++;
- add_comm:
- flags = rg.a;
- data += flags;
- flags = ((data & 15) - (flags & 15)) & h_flag;
- flags |= (data >> 4) & c_flag;
- rg.a = data;
- if ( data & 0xFF )
- goto loop;
- flags |= z_flag;
- goto loop;
-
-// Add/Subtract
-
- case 0x8E: // ADC (HL)
- data = READ( rp.hl );
- goto adc_comm;
-
- case 0x88: // ADC B
- case 0x89: // ADC C
- case 0x8A: // ADC D
- case 0x8B: // ADC E
- case 0x8C: // ADC H
- case 0x8D: // ADC L
- case 0x8F: // ADC A
- data = R8( op & 7 );
- goto adc_comm;
-
- case 0xCE: // ADC IMM
- pc++;
- adc_comm:
- data += (flags >> 4) & 1;
- data &= 0xFF; // to do: does carry get set when sum + carry = 0x100?
- goto add_comm;
-
- case 0x96: // SUB (HL)
- data = READ( rp.hl );
- goto sub_comm;
-
- case 0x90: // SUB B
- case 0x91: // SUB C
- case 0x92: // SUB D
- case 0x93: // SUB E
- case 0x94: // SUB H
- case 0x95: // SUB L
- case 0x97: // SUB A
- data = R8( op & 7 );
- goto sub_comm;
-
- case 0xD6: // SUB IMM
- pc++;
- sub_comm:
- op = rg.a;
- data = op - data;
- rg.a = data;
- goto sub_set_flags;
-
- case 0x9E: // SBC (HL)
- data = READ( rp.hl );
- goto sbc_comm;
-
- case 0x98: // SBC B
- case 0x99: // SBC C
- case 0x9A: // SBC D
- case 0x9B: // SBC E
- case 0x9C: // SBC H
- case 0x9D: // SBC L
- case 0x9F: // SBC A
- data = R8( op & 7 );
- goto sbc_comm;
-
- case 0xDE: // SBC IMM
- pc++;
- sbc_comm:
- data += (flags >> 4) & 1;
- data &= 0xFF; // to do: does carry get set when sum + carry = 0x100?
- goto sub_comm;
-
-// Logical
-
- case 0xA0: // AND B
- case 0xA1: // AND C
- case 0xA2: // AND D
- case 0xA3: // AND E
- case 0xA4: // AND H
- case 0xA5: // AND L
- data = R8( op & 7 );
- goto and_comm;
-
- case 0xA6: // AND (HL)
- data = READ( rp.hl );
- pc--;
- case 0xE6: // AND IMM
- pc++;
- and_comm:
- rg.a &= data;
- case 0xA7: // AND A
- flags = h_flag | (((rg.a - 1) >> 1) & z_flag);
- goto loop;
-
- case 0xB0: // OR B
- case 0xB1: // OR C
- case 0xB2: // OR D
- case 0xB3: // OR E
- case 0xB4: // OR H
- case 0xB5: // OR L
- data = R8( op & 7 );
- goto or_comm;
-
- case 0xB6: // OR (HL)
- data = READ( rp.hl );
- pc--;
- case 0xF6: // OR IMM
- pc++;
- or_comm:
- rg.a |= data;
- case 0xB7: // OR A
- flags = ((rg.a - 1) >> 1) & z_flag;
- goto loop;
-
- case 0xA8: // XOR B
- case 0xA9: // XOR C
- case 0xAA: // XOR D
- case 0xAB: // XOR E
- case 0xAC: // XOR H
- case 0xAD: // XOR L
- data = R8( op & 7 );
- goto xor_comm;
-
- case 0xAE: // XOR (HL)
- data = READ( rp.hl );
- pc--;
- case 0xEE: // XOR IMM
- pc++;
- xor_comm:
- data ^= rg.a;
- rg.a = data;
- data--;
- flags = (data >> 1) & z_flag;
- goto loop;
-
- case 0xAF: // XOR A
- rg.a = 0;
- flags = z_flag;
- goto loop;
-
-// Stack
-
- case 0xF1: // POP FA
- case 0xC1: // POP BC
- case 0xD1: // POP DE
- case 0xE1: // POP HL (common)
- data = READ( sp );
- r16 [(op >> 4) & 3] = data + 0x100 * READ( sp + 1 );
- sp = (sp + 2) & 0xFFFF;
- if ( op != 0xF1 )
- goto loop;
- flags = rg.flags & 0xF0;
- goto loop;
-
- case 0xC5: // PUSH BC
- data = rp.bc;
- goto push;
-
- case 0xD5: // PUSH DE
- data = rp.de;
- goto push;
-
- case 0xE5: // PUSH HL
- data = rp.hl;
- goto push;
-
- case 0xF5: // PUSH FA
- data = (flags << 8) | rg.a;
- goto push;
-
-// Flow control
-
- case 0xFF:
- if ( pc == idle_addr + 1 )
- goto stop;
- case 0xC7: case 0xCF: case 0xD7: case 0xDF: // RST
- case 0xE7: case 0xEF: case 0xF7:
- data = pc;
- pc = (op & 0x38) + rst_base;
- goto push;
-
- case 0xCC: // CZ
- pc += 2;
- if ( flags & z_flag )
- goto call;
- goto loop;
-
- case 0xD4: // CNC
- pc += 2;
- if ( !(flags & c_flag) )
- goto call;
- goto loop;
-
- case 0xDC: // CC
- pc += 2;
- if ( flags & c_flag )
- goto call;
- goto loop;
-
- case 0xD9: // RETI
- //interrupts_enabled = 1;
- goto ret;
-
- case 0xC0: // RZ
- if ( !(flags & z_flag) )
- goto ret;
- goto loop;
-
- case 0xD0: // RNC
- if ( !(flags & c_flag) )
- goto ret;
- goto loop;
-
- case 0xD8: // RC
- if ( flags & c_flag )
- goto ret;
- goto loop;
-
- case 0x18: // JR
- BRANCH( true )
-
- case 0x30: // JR NC
- BRANCH( !(flags & c_flag) )
-
- case 0x38: // JR C
- BRANCH( flags & c_flag )
-
- case 0xE9: // JP_HL
- pc = rp.hl;
- goto loop;
-
- case 0xC3: // JP (next-most-common)
- pc = GET_ADDR();
- goto loop;
-
- case 0xC2: // JP NZ
- pc += 2;
- if ( !(flags & z_flag) )
- goto jp_taken;
- goto loop;
-
- case 0xCA: // JP Z (most common)
- pc += 2;
- if ( !(flags & z_flag) )
- goto loop;
- jp_taken:
- pc -= 2;
- pc = GET_ADDR();
- goto loop;
-
- case 0xD2: // JP NC
- pc += 2;
- if ( !(flags & c_flag) )
- goto jp_taken;
- goto loop;
-
- case 0xDA: // JP C
- pc += 2;
- if ( flags & c_flag )
- goto jp_taken;
- goto loop;
-
-// Flags
-
- case 0x2F: // CPL
- rg.a = ~rg.a;
- flags |= n_flag | h_flag;
- goto loop;
-
- case 0x3F: // CCF
- flags = (flags ^ c_flag) & ~(n_flag | h_flag);
- goto loop;
-
- case 0x37: // SCF
- flags = (flags | c_flag) & ~(n_flag | h_flag);
- goto loop;
-
- case 0xF3: // DI
- //interrupts_enabled = 0;
- goto loop;
-
- case 0xFB: // EI
- //interrupts_enabled = 1;
- goto loop;
-
-// Special
-
- case 0xDD: case 0xD3: case 0xDB: case 0xE3: case 0xE4: // ?
- case 0xEB: case 0xEC: case 0xF4: case 0xFD: case 0xFC:
- case 0x10: // STOP
- case 0x27: // DAA (I'll have to implement this eventually...)
- case 0xBF:
- case 0xED: // Z80 prefix
- case 0x76: // HALT
- s.remain++;
- goto stop;
- }
-
- // If this fails then the case above is missing an opcode
- assert( false );
-
-stop:
- pc--;
-
- // copy state back
- STATIC_CAST(core_regs_t&,r) = rg;
- r.pc = pc;
- r.sp = sp;
- r.flags = flags;
-
- this->state = &state_;
- memcpy( &this->state_, &s, sizeof this->state_ );
-
- return s.remain > 0;
-}
diff --git a/src/console/Gb_Oscs.cc b/src/console/Gb_Oscs.cc
new file mode 100644
index 000000000000..56dbff6cfdb9
--- /dev/null
+++ b/src/console/Gb_Oscs.cc
@@ -0,0 +1,336 @@
+// Gb_Snd_Emu 0.1.5. http://www.slack.net/~ant/
+
+#include "Gb_Apu.h"
+
+#include <string.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+// Gb_Osc
+
+void Gb_Osc::reset()
+{
+ delay = 0;
+ last_amp = 0;
+ length = 0;
+ output_select = 3;
+ output = outputs [output_select];
+}
+
+void Gb_Osc::clock_length()
+{
+ if ( (regs [4] & len_enabled_mask) && length )
+ length--;
+}
+
+// Gb_Env
+
+void Gb_Env::clock_envelope()
+{
+ if ( env_delay && !--env_delay )
+ {
+ env_delay = regs [2] & 7;
+ int v = volume - 1 + (regs [2] >> 2 & 2);
+ if ( (unsigned) v < 15 )
+ volume = v;
+ }
+}
+
+bool Gb_Env::write_register( int reg, int data )
+{
+ switch ( reg )
+ {
+ case 1:
+ length = 64 - (regs [1] & 0x3F);
+ break;
+
+ case 2:
+ if ( !(data >> 4) )
+ enabled = false;
+ break;
+
+ case 4:
+ if ( data & trigger )
+ {
+ env_delay = regs [2] & 7;
+ volume = regs [2] >> 4;
+ enabled = true;
+ if ( length == 0 )
+ length = 64;
+ return true;
+ }
+ }
+ return false;
+}
+
+// Gb_Square
+
+void Gb_Square::reset()
+{
+ phase = 0;
+ sweep_freq = 0;
+ sweep_delay = 0;
+ Gb_Env::reset();
+}
+
+void Gb_Square::clock_sweep()
+{
+ int sweep_period = (regs [0] & period_mask) >> 4;
+ if ( sweep_period && sweep_delay && !--sweep_delay )
+ {
+ sweep_delay = sweep_period;
+ regs [3] = sweep_freq & 0xFF;
+ regs [4] = (regs [4] & ~0x07) | (sweep_freq >> 8 & 0x07);
+
+ int offset = sweep_freq >> (regs [0] & shift_mask);
+ if ( regs [0] & 0x08 )
+ offset = -offset;
+ sweep_freq += offset;
+
+ if ( sweep_freq < 0 )
+ {
+ sweep_freq = 0;
+ }
+ else if ( sweep_freq >= 2048 )
+ {
+ sweep_delay = 0; // don't modify channel frequency any further
+ sweep_freq = 2048; // silence sound immediately
+ }
+ }
+}
+
+void Gb_Square::run( blip_time_t time, blip_time_t end_time, int playing )
+{
+ if ( sweep_freq == 2048 )
+ playing = false;
+
+ static unsigned char const table [4] = { 1, 2, 4, 6 };
+ int const duty = table [regs [1] >> 6];
+ int amp = volume & playing;
+ if ( phase >= duty )
+ amp = -amp;
+
+ int frequency = this->frequency();
+ if ( unsigned (frequency - 1) > 2040 ) // frequency < 1 || frequency > 2041
+ {
+ // really high frequency results in DC at half volume
+ amp = volume >> 1;
+ playing = false;
+ }
+
+ {
+ int delta = amp - last_amp;
+ if ( delta )
+ {
+ last_amp = amp;
+ synth->offset( time, delta, output );
+ }
+ }
+
+ time += delay;
+ if ( !playing )
+ time = end_time;
+
+ if ( time < end_time )
+ {
+ int const period = (2048 - frequency) * 4;
+ Blip_Buffer* const output = this->output;
+ int phase = this->phase;
+ int delta = amp * 2;
+ do
+ {
+ phase = (phase + 1) & 7;
+ if ( phase == 0 || phase == duty )
+ {
+ delta = -delta;
+ synth->offset_inline( time, delta, output );
+ }
+ time += period;
+ }
+ while ( time < end_time );
+
+ this->phase = phase;
+ last_amp = delta >> 1;
+ }
+ delay = time - end_time;
+}
+
+// Gb_Noise
+
+void Gb_Noise::run( blip_time_t time, blip_time_t end_time, int playing )
+{
+ int amp = volume & playing;
+ int tap = 13 - (regs [3] & 8);
+ if ( bits >> tap & 2 )
+ amp = -amp;
+
+ {
+ int delta = amp - last_amp;
+ if ( delta )
+ {
+ last_amp = amp;
+ synth->offset( time, delta, output );
+ }
+ }
+
+ time += delay;
+ if ( !playing )
+ time = end_time;
+
+ if ( time < end_time )
+ {
+ static unsigned char const table [8] = { 8, 16, 32, 48, 64, 80, 96, 112 };
+ int period = table [regs [3] & 7] << (regs [3] >> 4);
+
+ // keep parallel resampled time to eliminate time conversion in the loop
+ Blip_Buffer* const output = this->output;
+ const blip_resampled_time_t resampled_period =
+ output->resampled_duration( period );
+ blip_resampled_time_t resampled_time = output->resampled_time( time );
+ unsigned bits = this->bits;
+ int delta = amp * 2;
+
+ do
+ {
+ unsigned changed = (bits >> tap) + 1;
+ time += period;
+ bits <<= 1;
+ if ( changed & 2 )
+ {
+ delta = -delta;
+ bits |= 1;
+ synth->offset_resampled( resampled_time, delta, output );
+ }
+ resampled_time += resampled_period;
+ }
+ while ( time < end_time );
+
+ this->bits = bits;
+ last_amp = delta >> 1;
+ }
+ delay = time - end_time;
+}
+
+// Gb_Wave
+
+inline void Gb_Wave::write_register( int reg, int data )
+{
+ switch ( reg )
+ {
+ case 0:
+ if ( !(data & 0x80) )
+ enabled = false;
+ break;
+
+ case 1:
+ length = 256 - regs [1];
+ break;
+
+ case 2:
+ volume = data >> 5 & 3;
+ break;
+
+ case 4:
+ if ( data & trigger & regs [0] )
+ {
+ wave_pos = 0;
+ enabled = true;
+ if ( length == 0 )
+ length = 256;
+ }
+ }
+}
+
+void Gb_Wave::run( blip_time_t time, blip_time_t end_time, int playing )
+{
+ int volume_shift = (volume - 1) & 7; // volume = 0 causes shift = 7
+ int frequency;
+ {
+ int amp = (wave [wave_pos] >> volume_shift & playing) * 2;
+
+ frequency = this->frequency();
+ if ( unsigned (frequency - 1) > 2044 ) // frequency < 1 || frequency > 2045
+ {
+ amp = 30 >> volume_shift & playing;
+ playing = false;
+ }
+
+ int delta = amp - last_amp;
+ if ( delta )
+ {
+ last_amp = amp;
+ synth->offset( time, delta, output );
+ }
+ }
+
+ time += delay;
+ if ( !playing )
+ time = end_time;
+
+ if ( time < end_time )
+ {
+ Blip_Buffer* const output = this->output;
+ int const period = (2048 - frequency) * 2;
+ int wave_pos = (this->wave_pos + 1) & (wave_size - 1);
+
+ do
+ {
+ int amp = (wave [wave_pos] >> volume_shift) * 2;
+ wave_pos = (wave_pos + 1) & (wave_size - 1);
+ int delta = amp - last_amp;
+ if ( delta )
+ {
+ last_amp = amp;
+ synth->offset_inline( time, delta, output );
+ }
+ time += period;
+ }
+ while ( time < end_time );
+
+ this->wave_pos = (wave_pos - 1) & (wave_size - 1);
+ }
+ delay = time - end_time;
+}
+
+// Gb_Apu::write_osc
+
+void Gb_Apu::write_osc( int index, int reg, int data )
+{
+ reg -= index * 5;
+ Gb_Square* sq = &square2;
+ switch ( index )
+ {
+ case 0:
+ sq = &square1;
+ case 1:
+ if ( sq->write_register( reg, data ) && index == 0 )
+ {
+ square1.sweep_freq = square1.frequency();
+ if ( (regs [0] & sq->period_mask) && (regs [0] & sq->shift_mask) )
+ {
+ square1.sweep_delay = 1; // cause sweep to recalculate now
+ square1.clock_sweep();
+ }
+ }
+ break;
+
+ case 2:
+ wave.write_register( reg, data );
+ break;
+
+ case 3:
+ if ( noise.write_register( reg, data ) )
+ noise.bits = 0x7FFF;
+ }
+}
diff --git a/src/console/Gb_Oscs.cxx b/src/console/Gb_Oscs.cxx
deleted file mode 100644
index 56dbff6cfdb9..000000000000
--- a/src/console/Gb_Oscs.cxx
+++ /dev/null
@@ -1,336 +0,0 @@
-// Gb_Snd_Emu 0.1.5. http://www.slack.net/~ant/
-
-#include "Gb_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Gb_Osc
-
-void Gb_Osc::reset()
-{
- delay = 0;
- last_amp = 0;
- length = 0;
- output_select = 3;
- output = outputs [output_select];
-}
-
-void Gb_Osc::clock_length()
-{
- if ( (regs [4] & len_enabled_mask) && length )
- length--;
-}
-
-// Gb_Env
-
-void Gb_Env::clock_envelope()
-{
- if ( env_delay && !--env_delay )
- {
- env_delay = regs [2] & 7;
- int v = volume - 1 + (regs [2] >> 2 & 2);
- if ( (unsigned) v < 15 )
- volume = v;
- }
-}
-
-bool Gb_Env::write_register( int reg, int data )
-{
- switch ( reg )
- {
- case 1:
- length = 64 - (regs [1] & 0x3F);
- break;
-
- case 2:
- if ( !(data >> 4) )
- enabled = false;
- break;
-
- case 4:
- if ( data & trigger )
- {
- env_delay = regs [2] & 7;
- volume = regs [2] >> 4;
- enabled = true;
- if ( length == 0 )
- length = 64;
- return true;
- }
- }
- return false;
-}
-
-// Gb_Square
-
-void Gb_Square::reset()
-{
- phase = 0;
- sweep_freq = 0;
- sweep_delay = 0;
- Gb_Env::reset();
-}
-
-void Gb_Square::clock_sweep()
-{
- int sweep_period = (regs [0] & period_mask) >> 4;
- if ( sweep_period && sweep_delay && !--sweep_delay )
- {
- sweep_delay = sweep_period;
- regs [3] = sweep_freq & 0xFF;
- regs [4] = (regs [4] & ~0x07) | (sweep_freq >> 8 & 0x07);
-
- int offset = sweep_freq >> (regs [0] & shift_mask);
- if ( regs [0] & 0x08 )
- offset = -offset;
- sweep_freq += offset;
-
- if ( sweep_freq < 0 )
- {
- sweep_freq = 0;
- }
- else if ( sweep_freq >= 2048 )
- {
- sweep_delay = 0; // don't modify channel frequency any further
- sweep_freq = 2048; // silence sound immediately
- }
- }
-}
-
-void Gb_Square::run( blip_time_t time, blip_time_t end_time, int playing )
-{
- if ( sweep_freq == 2048 )
- playing = false;
-
- static unsigned char const table [4] = { 1, 2, 4, 6 };
- int const duty = table [regs [1] >> 6];
- int amp = volume & playing;
- if ( phase >= duty )
- amp = -amp;
-
- int frequency = this->frequency();
- if ( unsigned (frequency - 1) > 2040 ) // frequency < 1 || frequency > 2041
- {
- // really high frequency results in DC at half volume
- amp = volume >> 1;
- playing = false;
- }
-
- {
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( !playing )
- time = end_time;
-
- if ( time < end_time )
- {
- int const period = (2048 - frequency) * 4;
- Blip_Buffer* const output = this->output;
- int phase = this->phase;
- int delta = amp * 2;
- do
- {
- phase = (phase + 1) & 7;
- if ( phase == 0 || phase == duty )
- {
- delta = -delta;
- synth->offset_inline( time, delta, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- this->phase = phase;
- last_amp = delta >> 1;
- }
- delay = time - end_time;
-}
-
-// Gb_Noise
-
-void Gb_Noise::run( blip_time_t time, blip_time_t end_time, int playing )
-{
- int amp = volume & playing;
- int tap = 13 - (regs [3] & 8);
- if ( bits >> tap & 2 )
- amp = -amp;
-
- {
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( !playing )
- time = end_time;
-
- if ( time < end_time )
- {
- static unsigned char const table [8] = { 8, 16, 32, 48, 64, 80, 96, 112 };
- int period = table [regs [3] & 7] << (regs [3] >> 4);
-
- // keep parallel resampled time to eliminate time conversion in the loop
- Blip_Buffer* const output = this->output;
- const blip_resampled_time_t resampled_period =
- output->resampled_duration( period );
- blip_resampled_time_t resampled_time = output->resampled_time( time );
- unsigned bits = this->bits;
- int delta = amp * 2;
-
- do
- {
- unsigned changed = (bits >> tap) + 1;
- time += period;
- bits <<= 1;
- if ( changed & 2 )
- {
- delta = -delta;
- bits |= 1;
- synth->offset_resampled( resampled_time, delta, output );
- }
- resampled_time += resampled_period;
- }
- while ( time < end_time );
-
- this->bits = bits;
- last_amp = delta >> 1;
- }
- delay = time - end_time;
-}
-
-// Gb_Wave
-
-inline void Gb_Wave::write_register( int reg, int data )
-{
- switch ( reg )
- {
- case 0:
- if ( !(data & 0x80) )
- enabled = false;
- break;
-
- case 1:
- length = 256 - regs [1];
- break;
-
- case 2:
- volume = data >> 5 & 3;
- break;
-
- case 4:
- if ( data & trigger & regs [0] )
- {
- wave_pos = 0;
- enabled = true;
- if ( length == 0 )
- length = 256;
- }
- }
-}
-
-void Gb_Wave::run( blip_time_t time, blip_time_t end_time, int playing )
-{
- int volume_shift = (volume - 1) & 7; // volume = 0 causes shift = 7
- int frequency;
- {
- int amp = (wave [wave_pos] >> volume_shift & playing) * 2;
-
- frequency = this->frequency();
- if ( unsigned (frequency - 1) > 2044 ) // frequency < 1 || frequency > 2045
- {
- amp = 30 >> volume_shift & playing;
- playing = false;
- }
-
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( !playing )
- time = end_time;
-
- if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
- int const period = (2048 - frequency) * 2;
- int wave_pos = (this->wave_pos + 1) & (wave_size - 1);
-
- do
- {
- int amp = (wave [wave_pos] >> volume_shift) * 2;
- wave_pos = (wave_pos + 1) & (wave_size - 1);
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset_inline( time, delta, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- this->wave_pos = (wave_pos - 1) & (wave_size - 1);
- }
- delay = time - end_time;
-}
-
-// Gb_Apu::write_osc
-
-void Gb_Apu::write_osc( int index, int reg, int data )
-{
- reg -= index * 5;
- Gb_Square* sq = &square2;
- switch ( index )
- {
- case 0:
- sq = &square1;
- case 1:
- if ( sq->write_register( reg, data ) && index == 0 )
- {
- square1.sweep_freq = square1.frequency();
- if ( (regs [0] & sq->period_mask) && (regs [0] & sq->shift_mask) )
- {
- square1.sweep_delay = 1; // cause sweep to recalculate now
- square1.clock_sweep();
- }
- }
- break;
-
- case 2:
- wave.write_register( reg, data );
- break;
-
- case 3:
- if ( noise.write_register( reg, data ) )
- noise.bits = 0x7FFF;
- }
-}
diff --git a/src/console/Gb_Oscs.h b/src/console/Gb_Oscs.h
index cd5c1c3eedcd..5cad0a1e1733 100644
--- a/src/console/Gb_Oscs.h
+++ b/src/console/Gb_Oscs.h
@@ -12,7 +12,7 @@ struct Gb_Osc
enum { trigger = 0x80 };
enum { len_enabled_mask = 0x40 };
- Blip_Buffer* outputs [4]; // NULL, right, left, center
+ Blip_Buffer* outputs [4]; // nullptr, right, left, center
Blip_Buffer* output;
int output_select;
uint8_t* regs; // osc's 5 registers
diff --git a/src/console/Gbs_Emu.cc b/src/console/Gbs_Emu.cc
new file mode 100644
index 000000000000..265d8036464c
--- /dev/null
+++ b/src/console/Gbs_Emu.cc
@@ -0,0 +1,289 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Gbs_Emu.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+Gbs_Emu::equalizer_t const Gbs_Emu::handheld_eq = { -47.0, 2000 };
+Gbs_Emu::equalizer_t const Gbs_Emu::headphones_eq = { 0.0, 300 };
+
+Gbs_Emu::Gbs_Emu()
+{
+ set_type( gme_gbs_type );
+
+ static const char* const names [Gb_Apu::osc_count] = {
+ "Square 1", "Square 2", "Wave", "Noise"
+ };
+ set_voice_names( names );
+
+ static int const types [Gb_Apu::osc_count] = {
+ wave_type | 1, wave_type | 2, wave_type | 0, mixed_type | 0
+ };
+ set_voice_types( types );
+
+ set_silence_lookahead( 6 );
+ set_max_initial_silence( 21 );
+ set_gain( 1.2 );
+
+ static equalizer_t const eq = { -1.0, 120 };
+ set_equalizer( eq );
+}
+
+Gbs_Emu::~Gbs_Emu() { }
+
+void Gbs_Emu::unload()
+{
+ rom.clear();
+ Music_Emu::unload();
+}
+
+// Track info
+
+static void copy_gbs_fields( Gbs_Emu::header_t const& h, track_info_t* out )
+{
+ GME_COPY_FIELD( h, out, game );
+ GME_COPY_FIELD( h, out, author );
+ GME_COPY_FIELD( h, out, copyright );
+}
+
+blargg_err_t Gbs_Emu::track_info_( track_info_t* out, int ) const
+{
+ copy_gbs_fields( header_, out );
+ return 0;
+}
+
+static blargg_err_t check_gbs_header( void const* header )
+{
+ if ( memcmp( header, "GBS", 3 ) )
+ return gme_wrong_file_type;
+ return 0;
+}
+
+struct Gbs_File : Gme_Info_
+{
+ Gbs_Emu::header_t h;
+
+ Gbs_File() { set_type( gme_gbs_type ); }
+
+ blargg_err_t load_( Data_Reader& in )
+ {
+ blargg_err_t err = in.read( &h, Gbs_Emu::header_size );
+ if ( err )
+ return (err == in.eof_error ? gme_wrong_file_type : err);
+
+ set_track_count( h.track_count );
+ return check_gbs_header( &h );
+ }
+
+ blargg_err_t track_info_( track_info_t* out, int ) const
+ {
+ copy_gbs_fields( h, out );
+ return 0;
+ }
+};
+
+static Music_Emu* new_gbs_emu () { return BLARGG_NEW Gbs_Emu ; }
+static Music_Emu* new_gbs_file() { return BLARGG_NEW Gbs_File; }
+
+static gme_type_t_ const gme_gbs_type_ = { "Game Boy", 0, &new_gbs_emu, &new_gbs_file, "GBS", 1 };
+gme_type_t const gme_gbs_type = &gme_gbs_type_;
+
+// Setup
+
+blargg_err_t Gbs_Emu::load_( Data_Reader& in )
+{
+ assert( offsetof (header_t,copyright [32]) == header_size );
+ RETURN_ERR( rom.load( in, header_size, &header_, 0 ) );
+
+ set_track_count( header_.track_count );
+ RETURN_ERR( check_gbs_header( &header_ ) );
+
+ if ( header_.vers != 1 )
+ set_warning( "Unknown file version" );
+
+ if ( header_.timer_mode & 0x78 )
+ set_warning( "Invalid timer mode" );
+
+ unsigned load_addr = GET_LE16( header_.load_addr );
+ if ( (header_.load_addr [1] | header_.init_addr [1] | header_.play_addr [1]) > 0x7F ||
+ load_addr < 0x400 )
+ set_warning( "Invalid load/init/play address" );
+
+ set_voice_count( Gb_Apu::osc_count );
+
+ apu.volume( gain() );
+
+ return setup_buffer( 4194304 );
+}
+
+void Gbs_Emu::update_eq( blip_eq_t const& eq )
+{
+ apu.treble_eq( eq );
+}
+
+void Gbs_Emu::set_voice( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r )
+{
+ apu.osc_output( i, c, l, r );
+}
+
+// Emulation
+
+// see gb_cpu_io.h for read/write functions
+
+void Gbs_Emu::set_bank( int n )
+{
+ blargg_long addr = rom.mask_addr( n * (blargg_long) bank_size );
+ if ( addr == 0 && rom.size() > bank_size )
+ {
+ // TODO: what is the correct behavior? Current Game & Watch Gallery
+ // rip requires that this have no effect or set to bank 1.
+ //debug_printf( "Selected ROM bank 0\n" );
+ return;
+ //n = 1;
+ }
+ cpu::map_code( bank_size, bank_size, rom.at_addr( addr ) );
+}
+
+void Gbs_Emu::update_timer()
+{
+ if ( header_.timer_mode & 0x04 )
+ {
+ static byte const rates [4] = { 10, 4, 6, 8 };
+ int shift = rates [ram [hi_page + 7] & 3] - (header_.timer_mode >> 7);
+ play_period = (256L - ram [hi_page + 6]) << shift;
+ }
+ else
+ {
+ play_period = 70224; // 59.73 Hz
+ }
+ if ( tempo() != 1.0 )
+ play_period = blip_time_t (play_period / tempo());
+}
+
+static uint8_t const sound_data [Gb_Apu::register_count] = {
+ 0x80, 0xBF, 0x00, 0x00, 0xBF, // square 1
+ 0x00, 0x3F, 0x00, 0x00, 0xBF, // square 2
+ 0x7F, 0xFF, 0x9F, 0x00, 0xBF, // wave
+ 0x00, 0xFF, 0x00, 0x00, 0xBF, // noise
+ 0x77, 0xF3, 0xF1, // vin/volume, status, power mode
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, // unused
+ 0xAC, 0xDD, 0xDA, 0x48, 0x36, 0x02, 0xCF, 0x16, // waveform data
+ 0x2C, 0x04, 0xE5, 0x2C, 0xAC, 0xDD, 0xDA, 0x48
+};
+
+void Gbs_Emu::cpu_jsr( gb_addr_t addr )
+{
+ check( cpu::r.sp == GET_LE16( header_.stack_ptr ) );
+ cpu::r.pc = addr;
+ cpu_write( --cpu::r.sp, idle_addr >> 8 );
+ cpu_write( --cpu::r.sp, idle_addr&0xFF );
+}
+
+void Gbs_Emu::set_tempo_( double t )
+{
+ apu.set_tempo( t );
+ update_timer();
+}
+
+blargg_err_t Gbs_Emu::start_track_( int track )
+{
+ RETURN_ERR( Classic_Emu::start_track_( track ) );
+
+ memset( ram, 0, 0x4000 );
+ memset( ram + 0x4000, 0xFF, 0x1F80 );
+ memset( ram + 0x5F80, 0, sizeof ram - 0x5F80 );
+ ram [hi_page] = 0; // joypad reads back as 0
+
+ apu.reset();
+ for ( int i = 0; i < (int) sizeof sound_data; i++ )
+ apu.write_register( 0, i + apu.start_addr, sound_data [i] );
+
+ unsigned load_addr = GET_LE16( header_.load_addr );
+ rom.set_addr( load_addr );
+ cpu::rst_base = load_addr;
+
+ cpu::reset( rom.unmapped() );
+
+ cpu::map_code( ram_addr, 0x10000 - ram_addr, ram );
+ cpu::map_code( 0, bank_size, rom.at_addr( 0 ) );
+ set_bank( rom.size() > bank_size );
+
+ ram [hi_page + 6] = header_.timer_modulo;
+ ram [hi_page + 7] = header_.timer_mode;
+ update_timer();
+ next_play = play_period;
+
+ cpu::r.a = track;
+ cpu::r.pc = idle_addr;
+ cpu::r.sp = GET_LE16( header_.stack_ptr );
+ cpu_time = 0;
+ cpu_jsr( GET_LE16( header_.init_addr ) );
+
+ return 0;
+}
+
+blargg_err_t Gbs_Emu::run_clocks( blip_time_t& duration, int )
+{
+ cpu_time = 0;
+ while ( cpu_time < duration )
+ {
+ long count = duration - cpu_time;
+ cpu_time = duration;
+ bool result = cpu::run( count );
+ cpu_time -= cpu::remain();
+
+ if ( result )
+ {
+ if ( cpu::r.pc == idle_addr )
+ {
+ if ( next_play > duration )
+ {
+ cpu_time = duration;
+ break;
+ }
+
+ if ( cpu_time < next_play )
+ cpu_time = next_play;
+ next_play += play_period;
+ cpu_jsr( GET_LE16( header_.play_addr ) );
+ GME_FRAME_HOOK( this );
+ // TODO: handle timer rates different than 60 Hz
+ }
+ else if ( cpu::r.pc > 0xFFFF )
+ {
+ debug_printf( "PC wrapped around\n" );
+ cpu::r.pc &= 0xFFFF;
+ }
+ else
+ {
+ set_warning( "Emulation error (illegal/unsupported instruction)" );
+ debug_printf( "Bad opcode $%.2x at $%.4x\n",
+ (int) *cpu::get_code( cpu::r.pc ), (int) cpu::r.pc );
+ cpu::r.pc = (cpu::r.pc + 1) & 0xFFFF;
+ cpu_time += 6;
+ }
+ }
+ }
+
+ duration = cpu_time;
+ next_play -= cpu_time;
+ if ( next_play < 0 ) // could go negative if routine is taking too long to return
+ next_play = 0;
+ apu.end_frame( cpu_time );
+
+ return 0;
+}
diff --git a/src/console/Gbs_Emu.cxx b/src/console/Gbs_Emu.cxx
deleted file mode 100644
index 265d8036464c..000000000000
--- a/src/console/Gbs_Emu.cxx
+++ /dev/null
@@ -1,289 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Gbs_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Gbs_Emu::equalizer_t const Gbs_Emu::handheld_eq = { -47.0, 2000 };
-Gbs_Emu::equalizer_t const Gbs_Emu::headphones_eq = { 0.0, 300 };
-
-Gbs_Emu::Gbs_Emu()
-{
- set_type( gme_gbs_type );
-
- static const char* const names [Gb_Apu::osc_count] = {
- "Square 1", "Square 2", "Wave", "Noise"
- };
- set_voice_names( names );
-
- static int const types [Gb_Apu::osc_count] = {
- wave_type | 1, wave_type | 2, wave_type | 0, mixed_type | 0
- };
- set_voice_types( types );
-
- set_silence_lookahead( 6 );
- set_max_initial_silence( 21 );
- set_gain( 1.2 );
-
- static equalizer_t const eq = { -1.0, 120 };
- set_equalizer( eq );
-}
-
-Gbs_Emu::~Gbs_Emu() { }
-
-void Gbs_Emu::unload()
-{
- rom.clear();
- Music_Emu::unload();
-}
-
-// Track info
-
-static void copy_gbs_fields( Gbs_Emu::header_t const& h, track_info_t* out )
-{
- GME_COPY_FIELD( h, out, game );
- GME_COPY_FIELD( h, out, author );
- GME_COPY_FIELD( h, out, copyright );
-}
-
-blargg_err_t Gbs_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_gbs_fields( header_, out );
- return 0;
-}
-
-static blargg_err_t check_gbs_header( void const* header )
-{
- if ( memcmp( header, "GBS", 3 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Gbs_File : Gme_Info_
-{
- Gbs_Emu::header_t h;
-
- Gbs_File() { set_type( gme_gbs_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- blargg_err_t err = in.read( &h, Gbs_Emu::header_size );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
-
- set_track_count( h.track_count );
- return check_gbs_header( &h );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_gbs_fields( h, out );
- return 0;
- }
-};
-
-static Music_Emu* new_gbs_emu () { return BLARGG_NEW Gbs_Emu ; }
-static Music_Emu* new_gbs_file() { return BLARGG_NEW Gbs_File; }
-
-static gme_type_t_ const gme_gbs_type_ = { "Game Boy", 0, &new_gbs_emu, &new_gbs_file, "GBS", 1 };
-gme_type_t const gme_gbs_type = &gme_gbs_type_;
-
-// Setup
-
-blargg_err_t Gbs_Emu::load_( Data_Reader& in )
-{
- assert( offsetof (header_t,copyright [32]) == header_size );
- RETURN_ERR( rom.load( in, header_size, &header_, 0 ) );
-
- set_track_count( header_.track_count );
- RETURN_ERR( check_gbs_header( &header_ ) );
-
- if ( header_.vers != 1 )
- set_warning( "Unknown file version" );
-
- if ( header_.timer_mode & 0x78 )
- set_warning( "Invalid timer mode" );
-
- unsigned load_addr = GET_LE16( header_.load_addr );
- if ( (header_.load_addr [1] | header_.init_addr [1] | header_.play_addr [1]) > 0x7F ||
- load_addr < 0x400 )
- set_warning( "Invalid load/init/play address" );
-
- set_voice_count( Gb_Apu::osc_count );
-
- apu.volume( gain() );
-
- return setup_buffer( 4194304 );
-}
-
-void Gbs_Emu::update_eq( blip_eq_t const& eq )
-{
- apu.treble_eq( eq );
-}
-
-void Gbs_Emu::set_voice( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r )
-{
- apu.osc_output( i, c, l, r );
-}
-
-// Emulation
-
-// see gb_cpu_io.h for read/write functions
-
-void Gbs_Emu::set_bank( int n )
-{
- blargg_long addr = rom.mask_addr( n * (blargg_long) bank_size );
- if ( addr == 0 && rom.size() > bank_size )
- {
- // TODO: what is the correct behavior? Current Game & Watch Gallery
- // rip requires that this have no effect or set to bank 1.
- //debug_printf( "Selected ROM bank 0\n" );
- return;
- //n = 1;
- }
- cpu::map_code( bank_size, bank_size, rom.at_addr( addr ) );
-}
-
-void Gbs_Emu::update_timer()
-{
- if ( header_.timer_mode & 0x04 )
- {
- static byte const rates [4] = { 10, 4, 6, 8 };
- int shift = rates [ram [hi_page + 7] & 3] - (header_.timer_mode >> 7);
- play_period = (256L - ram [hi_page + 6]) << shift;
- }
- else
- {
- play_period = 70224; // 59.73 Hz
- }
- if ( tempo() != 1.0 )
- play_period = blip_time_t (play_period / tempo());
-}
-
-static uint8_t const sound_data [Gb_Apu::register_count] = {
- 0x80, 0xBF, 0x00, 0x00, 0xBF, // square 1
- 0x00, 0x3F, 0x00, 0x00, 0xBF, // square 2
- 0x7F, 0xFF, 0x9F, 0x00, 0xBF, // wave
- 0x00, 0xFF, 0x00, 0x00, 0xBF, // noise
- 0x77, 0xF3, 0xF1, // vin/volume, status, power mode
- 0, 0, 0, 0, 0, 0, 0, 0, 0, // unused
- 0xAC, 0xDD, 0xDA, 0x48, 0x36, 0x02, 0xCF, 0x16, // waveform data
- 0x2C, 0x04, 0xE5, 0x2C, 0xAC, 0xDD, 0xDA, 0x48
-};
-
-void Gbs_Emu::cpu_jsr( gb_addr_t addr )
-{
- check( cpu::r.sp == GET_LE16( header_.stack_ptr ) );
- cpu::r.pc = addr;
- cpu_write( --cpu::r.sp, idle_addr >> 8 );
- cpu_write( --cpu::r.sp, idle_addr&0xFF );
-}
-
-void Gbs_Emu::set_tempo_( double t )
-{
- apu.set_tempo( t );
- update_timer();
-}
-
-blargg_err_t Gbs_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( ram, 0, 0x4000 );
- memset( ram + 0x4000, 0xFF, 0x1F80 );
- memset( ram + 0x5F80, 0, sizeof ram - 0x5F80 );
- ram [hi_page] = 0; // joypad reads back as 0
-
- apu.reset();
- for ( int i = 0; i < (int) sizeof sound_data; i++ )
- apu.write_register( 0, i + apu.start_addr, sound_data [i] );
-
- unsigned load_addr = GET_LE16( header_.load_addr );
- rom.set_addr( load_addr );
- cpu::rst_base = load_addr;
-
- cpu::reset( rom.unmapped() );
-
- cpu::map_code( ram_addr, 0x10000 - ram_addr, ram );
- cpu::map_code( 0, bank_size, rom.at_addr( 0 ) );
- set_bank( rom.size() > bank_size );
-
- ram [hi_page + 6] = header_.timer_modulo;
- ram [hi_page + 7] = header_.timer_mode;
- update_timer();
- next_play = play_period;
-
- cpu::r.a = track;
- cpu::r.pc = idle_addr;
- cpu::r.sp = GET_LE16( header_.stack_ptr );
- cpu_time = 0;
- cpu_jsr( GET_LE16( header_.init_addr ) );
-
- return 0;
-}
-
-blargg_err_t Gbs_Emu::run_clocks( blip_time_t& duration, int )
-{
- cpu_time = 0;
- while ( cpu_time < duration )
- {
- long count = duration - cpu_time;
- cpu_time = duration;
- bool result = cpu::run( count );
- cpu_time -= cpu::remain();
-
- if ( result )
- {
- if ( cpu::r.pc == idle_addr )
- {
- if ( next_play > duration )
- {
- cpu_time = duration;
- break;
- }
-
- if ( cpu_time < next_play )
- cpu_time = next_play;
- next_play += play_period;
- cpu_jsr( GET_LE16( header_.play_addr ) );
- GME_FRAME_HOOK( this );
- // TODO: handle timer rates different than 60 Hz
- }
- else if ( cpu::r.pc > 0xFFFF )
- {
- debug_printf( "PC wrapped around\n" );
- cpu::r.pc &= 0xFFFF;
- }
- else
- {
- set_warning( "Emulation error (illegal/unsupported instruction)" );
- debug_printf( "Bad opcode $%.2x at $%.4x\n",
- (int) *cpu::get_code( cpu::r.pc ), (int) cpu::r.pc );
- cpu::r.pc = (cpu::r.pc + 1) & 0xFFFF;
- cpu_time += 6;
- }
- }
- }
-
- duration = cpu_time;
- next_play -= cpu_time;
- if ( next_play < 0 ) // could go negative if routine is taking too long to return
- next_play = 0;
- apu.end_frame( cpu_time );
-
- return 0;
-}
diff --git a/src/console/Gme_File.cc b/src/console/Gme_File.cc
new file mode 100644
index 000000000000..303c7bad0a05
--- /dev/null
+++ b/src/console/Gme_File.cc
@@ -0,0 +1,215 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Gme_File.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+const char* const gme_wrong_file_type = "Wrong file type for this emulator";
+
+void Gme_File::clear_playlist()
+{
+ playlist.clear();
+ clear_playlist_();
+ track_count_ = raw_track_count_;
+}
+
+void Gme_File::unload()
+{
+ clear_playlist(); // *before* clearing track count
+ track_count_ = 0;
+ raw_track_count_ = 0;
+ file_data.clear();
+}
+
+Gme_File::Gme_File()
+{
+ type_ = 0;
+ user_data_ = 0;
+ user_cleanup_ = 0;
+ unload(); // clears fields
+}
+
+Gme_File::~Gme_File()
+{
+ if ( user_cleanup_ )
+ user_cleanup_( user_data_ );
+}
+
+blargg_err_t Gme_File::load_mem_( byte const* data, long size )
+{
+ require( data != file_data.begin() ); // load_mem_() or load_() must be overridden
+ Mem_File_Reader in( data, size );
+ return load_( in );
+}
+
+blargg_err_t Gme_File::load_( Data_Reader& in )
+{
+ RETURN_ERR( file_data.resize( in.remain() ) );
+ RETURN_ERR( in.read( file_data.begin(), file_data.size() ) );
+ return load_mem_( file_data.begin(), file_data.size() );
+}
+
+// public load functions call this at beginning
+void Gme_File::pre_load() { unload(); }
+
+void Gme_File::post_load_() { }
+
+// public load functions call this at end
+blargg_err_t Gme_File::post_load( blargg_err_t err )
+{
+ if ( !track_count() )
+ set_track_count( type()->track_count );
+ if ( !err )
+ post_load_();
+ else
+ unload();
+
+ return err;
+}
+
+// Public load functions
+
+blargg_err_t Gme_File::load_mem( void const* in, long size )
+{
+ pre_load();
+ return post_load( load_mem_( (byte const*) in, size ) );
+}
+
+blargg_err_t Gme_File::load( Data_Reader& in )
+{
+ pre_load();
+ return post_load( load_( in ) );
+}
+
+blargg_err_t Gme_File::load_file( const char* path )
+{
+ pre_load();
+ GME_FILE_READER in;
+ RETURN_ERR( in.open( path ) );
+ return post_load( load_( in ) );
+}
+
+blargg_err_t Gme_File::load_remaining_( void const* h, long s, Data_Reader& in )
+{
+ Remaining_Reader rem( h, s, &in );
+ return load( rem );
+}
+
+// Track info
+
+void Gme_File::copy_field_( char* out, const char* in, int in_size )
+{
+ if ( !in || !*in )
+ return;
+
+ // remove spaces/junk from beginning
+ while ( in_size && unsigned (*in - 1) <= ' ' - 1 )
+ {
+ in++;
+ in_size--;
+ }
+
+ // truncate
+ if ( in_size > max_field_ )
+ in_size = max_field_;
+
+ // find terminator
+ int len = 0;
+ while ( len < in_size && in [len] )
+ len++;
+
+ // remove spaces/junk from end
+ while ( len && unsigned (in [len - 1]) <= ' ' )
+ len--;
+
+ // copy
+ out [len] = 0;
+ memcpy( out, in, len );
+
+ // strip out stupid fields that should have been left blank
+ if ( !strcmp( out, "?" ) || !strcmp( out, "<?>" ) || !strcmp( out, "< ? >" ) )
+ out [0] = 0;
+}
+
+void Gme_File::copy_field_( char* out, const char* in )
+{
+ copy_field_( out, in, max_field_ );
+}
+
+blargg_err_t Gme_File::remap_track_( int* track_io ) const
+{
+ if ( (unsigned) *track_io >= (unsigned) track_count() )
+ return "Invalid track";
+
+ if ( (unsigned) *track_io < (unsigned) playlist.size() )
+ {
+ M3u_Playlist::entry_t const& e = playlist [*track_io];
+ *track_io = 0;
+ if ( e.track >= 0 )
+ {
+ *track_io = e.track;
+ if ( !(type_->flags_ & 0x02) )
+ *track_io -= e.decimal_track;
+ }
+ if ( *track_io >= raw_track_count_ )
+ return "Invalid track in m3u playlist";
+ }
+ else
+ {
+ check( !playlist.size() );
+ }
+ return 0;
+}
+
+blargg_err_t Gme_File::track_info( track_info_t* out, int track ) const
+{
+ out->track_count = track_count();
+ out->length = -1;
+ out->loop_length = -1;
+ out->intro_length = -1;
+ out->song [0] = 0;
+
+ out->game [0] = 0;
+ out->author [0] = 0;
+ out->copyright [0] = 0;
+ out->comment [0] = 0;
+ out->dumper [0] = 0;
+ out->system [0] = 0;
+
+ copy_field_( out->system, type()->system );
+
+ int remapped = track;
+ RETURN_ERR( remap_track_( &remapped ) );
+ RETURN_ERR( track_info_( out, remapped ) );
+
+ // override with m3u info
+ if ( playlist.size() )
+ {
+ M3u_Playlist::info_t const& i = playlist.info();
+ copy_field_( out->game , i.title );
+ copy_field_( out->author, i.engineer );
+ copy_field_( out->author, i.composer );
+ copy_field_( out->dumper, i.ripping );
+
+ M3u_Playlist::entry_t const& e = playlist [track];
+ copy_field_( out->song, e.name );
+ if ( e.length >= 0 ) out->length = e.length * 1000L;
+ if ( e.intro >= 0 ) out->intro_length = e.intro * 1000L;
+ if ( e.loop >= 0 ) out->loop_length = e.loop * 1000L;
+ }
+ return 0;
+}
diff --git a/src/console/Gme_File.cxx b/src/console/Gme_File.cxx
deleted file mode 100644
index 303c7bad0a05..000000000000
--- a/src/console/Gme_File.cxx
+++ /dev/null
@@ -1,215 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Gme_File.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-const char* const gme_wrong_file_type = "Wrong file type for this emulator";
-
-void Gme_File::clear_playlist()
-{
- playlist.clear();
- clear_playlist_();
- track_count_ = raw_track_count_;
-}
-
-void Gme_File::unload()
-{
- clear_playlist(); // *before* clearing track count
- track_count_ = 0;
- raw_track_count_ = 0;
- file_data.clear();
-}
-
-Gme_File::Gme_File()
-{
- type_ = 0;
- user_data_ = 0;
- user_cleanup_ = 0;
- unload(); // clears fields
-}
-
-Gme_File::~Gme_File()
-{
- if ( user_cleanup_ )
- user_cleanup_( user_data_ );
-}
-
-blargg_err_t Gme_File::load_mem_( byte const* data, long size )
-{
- require( data != file_data.begin() ); // load_mem_() or load_() must be overridden
- Mem_File_Reader in( data, size );
- return load_( in );
-}
-
-blargg_err_t Gme_File::load_( Data_Reader& in )
-{
- RETURN_ERR( file_data.resize( in.remain() ) );
- RETURN_ERR( in.read( file_data.begin(), file_data.size() ) );
- return load_mem_( file_data.begin(), file_data.size() );
-}
-
-// public load functions call this at beginning
-void Gme_File::pre_load() { unload(); }
-
-void Gme_File::post_load_() { }
-
-// public load functions call this at end
-blargg_err_t Gme_File::post_load( blargg_err_t err )
-{
- if ( !track_count() )
- set_track_count( type()->track_count );
- if ( !err )
- post_load_();
- else
- unload();
-
- return err;
-}
-
-// Public load functions
-
-blargg_err_t Gme_File::load_mem( void const* in, long size )
-{
- pre_load();
- return post_load( load_mem_( (byte const*) in, size ) );
-}
-
-blargg_err_t Gme_File::load( Data_Reader& in )
-{
- pre_load();
- return post_load( load_( in ) );
-}
-
-blargg_err_t Gme_File::load_file( const char* path )
-{
- pre_load();
- GME_FILE_READER in;
- RETURN_ERR( in.open( path ) );
- return post_load( load_( in ) );
-}
-
-blargg_err_t Gme_File::load_remaining_( void const* h, long s, Data_Reader& in )
-{
- Remaining_Reader rem( h, s, &in );
- return load( rem );
-}
-
-// Track info
-
-void Gme_File::copy_field_( char* out, const char* in, int in_size )
-{
- if ( !in || !*in )
- return;
-
- // remove spaces/junk from beginning
- while ( in_size && unsigned (*in - 1) <= ' ' - 1 )
- {
- in++;
- in_size--;
- }
-
- // truncate
- if ( in_size > max_field_ )
- in_size = max_field_;
-
- // find terminator
- int len = 0;
- while ( len < in_size && in [len] )
- len++;
-
- // remove spaces/junk from end
- while ( len && unsigned (in [len - 1]) <= ' ' )
- len--;
-
- // copy
- out [len] = 0;
- memcpy( out, in, len );
-
- // strip out stupid fields that should have been left blank
- if ( !strcmp( out, "?" ) || !strcmp( out, "<?>" ) || !strcmp( out, "< ? >" ) )
- out [0] = 0;
-}
-
-void Gme_File::copy_field_( char* out, const char* in )
-{
- copy_field_( out, in, max_field_ );
-}
-
-blargg_err_t Gme_File::remap_track_( int* track_io ) const
-{
- if ( (unsigned) *track_io >= (unsigned) track_count() )
- return "Invalid track";
-
- if ( (unsigned) *track_io < (unsigned) playlist.size() )
- {
- M3u_Playlist::entry_t const& e = playlist [*track_io];
- *track_io = 0;
- if ( e.track >= 0 )
- {
- *track_io = e.track;
- if ( !(type_->flags_ & 0x02) )
- *track_io -= e.decimal_track;
- }
- if ( *track_io >= raw_track_count_ )
- return "Invalid track in m3u playlist";
- }
- else
- {
- check( !playlist.size() );
- }
- return 0;
-}
-
-blargg_err_t Gme_File::track_info( track_info_t* out, int track ) const
-{
- out->track_count = track_count();
- out->length = -1;
- out->loop_length = -1;
- out->intro_length = -1;
- out->song [0] = 0;
-
- out->game [0] = 0;
- out->author [0] = 0;
- out->copyright [0] = 0;
- out->comment [0] = 0;
- out->dumper [0] = 0;
- out->system [0] = 0;
-
- copy_field_( out->system, type()->system );
-
- int remapped = track;
- RETURN_ERR( remap_track_( &remapped ) );
- RETURN_ERR( track_info_( out, remapped ) );
-
- // override with m3u info
- if ( playlist.size() )
- {
- M3u_Playlist::info_t const& i = playlist.info();
- copy_field_( out->game , i.title );
- copy_field_( out->author, i.engineer );
- copy_field_( out->author, i.composer );
- copy_field_( out->dumper, i.ripping );
-
- M3u_Playlist::entry_t const& e = playlist [track];
- copy_field_( out->song, e.name );
- if ( e.length >= 0 ) out->length = e.length * 1000L;
- if ( e.intro >= 0 ) out->intro_length = e.intro * 1000L;
- if ( e.loop >= 0 ) out->loop_length = e.loop * 1000L;
- }
- return 0;
-}
diff --git a/src/console/Gme_File.h b/src/console/Gme_File.h
index c47a6043e356..4554d9dce23a 100644
--- a/src/console/Gme_File.h
+++ b/src/console/Gme_File.h
@@ -76,7 +76,7 @@ public:
// is an NSFE emulator, and you can cast to an Nsfe_Emu* if necessary.
gme_type_t type() const;
- // Most recent warning string, or NULL if none. Clears current warning after
+ // Most recent warning string, or nullptr if none. Clears current warning after
// returning.
const char* warning();
@@ -94,7 +94,7 @@ public:
void set_user_data( void* p ) { user_data_ = p; }
void* user_data() const { return user_data_; }
- // Register cleanup function to be called when deleting emulator, or NULL to
+ // Register cleanup function to be called when deleting emulator, or nullptr to
// clear it. Passes user_data to cleanup function.
void set_user_cleanup( gme_user_cleanup_t func ) { user_cleanup_ = func; }
diff --git a/src/console/Gym_Emu.cc b/src/console/Gym_Emu.cc
new file mode 100644
index 000000000000..e850497976a9
--- /dev/null
+++ b/src/console/Gym_Emu.cc
@@ -0,0 +1,380 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Gym_Emu.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+double const min_tempo = 0.25;
+double const oversample_factor = 5 / 3.0;
+double const fm_gain = 3.0;
+
+const long base_clock = 53700300;
+const long clock_rate = base_clock / 15;
+
+Gym_Emu::Gym_Emu()
+{
+ data = 0;
+ pos = 0;
+ set_type( gme_gym_type );
+
+ static const char* const names [] = {
+ "FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
+ };
+ set_voice_names( names );
+ set_silence_lookahead( 1 ); // tracks should already be trimmed
+}
+
+Gym_Emu::~Gym_Emu() { }
+
+// Track info
+
+static void get_gym_info( Gym_Emu::header_t const& h, long length, track_info_t* out )
+{
+ if ( !memcmp( h.tag, "GYMX", 4 ) )
+ {
+ length = length * 50 / 3; // 1000 / 60
+ long loop = GET_LE32( h.loop_start );
+ if ( loop )
+ {
+ out->intro_length = loop * 50 / 3;
+ out->loop_length = length - out->intro_length;
+ }
+ else
+ {
+ out->length = length;
+ out->intro_length = length; // make it clear that track is no longer than length
+ out->loop_length = 0;
+ }
+
+ // more stupidity where the field should have been left
+ if ( strcmp( h.song, "Unknown Song" ) )
+ GME_COPY_FIELD( h, out, song );
+
+ if ( strcmp( h.game, "Unknown Game" ) )
+ GME_COPY_FIELD( h, out, game );
+
+ if ( strcmp( h.copyright, "Unknown Publisher" ) )
+ GME_COPY_FIELD( h, out, copyright );
+
+ if ( strcmp( h.dumper, "Unknown Person" ) )
+ GME_COPY_FIELD( h, out, dumper );
+
+ if ( strcmp( h.comment, "Header added by YMAMP" ) )
+ GME_COPY_FIELD( h, out, comment );
+ }
+}
+
+blargg_err_t Gym_Emu::track_info_( track_info_t* out, int ) const
+{
+ get_gym_info( header_, track_length(), out );
+ return 0;
+}
+
+static long gym_track_length( byte const* p, byte const* end )
+{
+ long time = 0;
+ while ( p < end )
+ {
+ switch ( *p++ )
+ {
+ case 0:
+ time++;
+ break;
+
+ case 1:
+ case 2:
+ p += 2;
+ break;
+
+ case 3:
+ p += 1;
+ break;
+ }
+ }
+ return time;
+}
+
+long Gym_Emu::track_length() const { return gym_track_length( data, data_end ); }
+
+static blargg_err_t check_header( byte const* in, long size, int* data_offset = 0 )
+{
+ if ( size < 4 )
+ return gme_wrong_file_type;
+
+ if ( memcmp( in, "GYMX", 4 ) == 0 )
+ {
+ if ( size < Gym_Emu::header_size + 1 )
+ return gme_wrong_file_type;
+
+ if ( memcmp( ((Gym_Emu::header_t const*) in)->packed, "\0\0\0\0", 4 ) != 0 )
+ return "Packed GYM file not supported";
+
+ if ( data_offset )
+ *data_offset = Gym_Emu::header_size;
+ }
+ else if ( *in > 3 )
+ {
+ return gme_wrong_file_type;
+ }
+
+ return 0;
+}
+
+struct Gym_File : Gme_Info_
+{
+ byte const* file_begin;
+ byte const* file_end;
+ int data_offset;
+
+ Gym_File() { set_type( gme_gym_type ); }
+
+ blargg_err_t load_mem_( byte const* in, long size )
+ {
+ file_begin = in;
+ file_end = in + size;
+ data_offset = 0;
+ return check_header( in, size, &data_offset );
+ }
+
+ blargg_err_t track_info_( track_info_t* out, int ) const
+ {
+ long length = gym_track_length( &file_begin [data_offset], file_end );
+ get_gym_info( *(Gym_Emu::header_t const*) file_begin, length, out );
+ return 0;
+ }
+};
+
+static Music_Emu* new_gym_emu () { return BLARGG_NEW Gym_Emu ; }
+static Music_Emu* new_gym_file() { return BLARGG_NEW Gym_File; }
+
+static gme_type_t_ const gme_gym_type_ = { "Sega Genesis", 1, &new_gym_emu, &new_gym_file, "GYM", 0 };
+gme_type_t const gme_gym_type = &gme_gym_type_;
+
+// Setup
+
+blargg_err_t Gym_Emu::set_sample_rate_( long sample_rate )
+{
+ blip_eq_t eq( -32, 8000, sample_rate );
+ apu.treble_eq( eq );
+ dac_synth.treble_eq( eq );
+ apu.volume( 0.135 * fm_gain * gain() );
+ dac_synth.volume( 0.125 / 256 * fm_gain * gain() );
+ double factor = Dual_Resampler::setup( oversample_factor, 0.990, fm_gain * gain() );
+ fm_sample_rate = sample_rate * factor;
+
+ RETURN_ERR( blip_buf.set_sample_rate( sample_rate, int (1000 / 60.0 / min_tempo) ) );
+ blip_buf.clock_rate( clock_rate );
+
+ RETURN_ERR( fm.set_rate( fm_sample_rate, base_clock / 7.0 ) );
+ RETURN_ERR( Dual_Resampler::reset( long (1.0 / 60 / min_tempo * sample_rate) ) );
+
+ return 0;
+}
+
+void Gym_Emu::set_tempo_( double t )
+{
+ if ( t < min_tempo )
+ {
+ set_tempo( min_tempo );
+ return;
+ }
+
+ if ( blip_buf.sample_rate() )
+ {
+ clocks_per_frame = long (clock_rate / 60 / tempo());
+ Dual_Resampler::resize( long (sample_rate() / (60.0 * tempo())) );
+ }
+}
+
+void Gym_Emu::mute_voices_( int mask )
+{
+ Music_Emu::mute_voices_( mask );
+ fm.mute_voices( mask );
+ dac_muted = (mask & 0x40) != 0;
+ apu.output( (mask & 0x80) ? 0 : &blip_buf );
+}
+
+blargg_err_t Gym_Emu::load_mem_( byte const* in, long size )
+{
+ assert( offsetof (header_t,packed [4]) == header_size );
+ int offset = 0;
+ RETURN_ERR( check_header( in, size, &offset ) );
+ set_voice_count( 8 );
+
+ data = in + offset;
+ data_end = in + size;
+ loop_begin = 0;
+
+ if ( offset )
+ header_ = *(header_t const*) in;
+ else
+ memset( &header_, 0, sizeof header_ );
+
+ return 0;
+}
+
+// Emulation
+
+blargg_err_t Gym_Emu::start_track_( int track )
+{
+ RETURN_ERR( Music_Emu::start_track_( track ) );
+
+ pos = data;
+ loop_remain = GET_LE32( header_.loop_start );
+
+ prev_dac_count = 0;
+ dac_enabled = false;
+ dac_amp = -1;
+
+ fm.reset();
+ apu.reset();
+ blip_buf.clear();
+ Dual_Resampler::clear();
+ return 0;
+}
+
+void Gym_Emu::run_dac( int dac_count )
+{
+ // Guess beginning and end of sample and adjust rate and buffer position accordingly.
+
+ // count dac samples in next frame
+ int next_dac_count = 0;
+ const byte* p = this->pos;
+ int cmd;
+ while ( (cmd = *p++) != 0 )
+ {
+ int data = *p++;
+ if ( cmd <= 2 )
+ ++p;
+ if ( cmd == 1 && data == 0x2A )
+ next_dac_count++;
+ }
+
+ // detect beginning and end of sample
+ int rate_count = dac_count;
+ int start = 0;
+ if ( !prev_dac_count && next_dac_count && dac_count < next_dac_count )
+ {
+ rate_count = next_dac_count;
+ start = next_dac_count - dac_count;
+ }
+ else if ( prev_dac_count && !next_dac_count && dac_count < prev_dac_count )
+ {
+ rate_count = prev_dac_count;
+ }
+
+ // Evenly space samples within buffer section being used
+ blip_resampled_time_t period = blip_buf.resampled_duration( clocks_per_frame ) / rate_count;
+
+ blip_resampled_time_t time = blip_buf.resampled_time( 0 ) +
+ period * start + (period >> 1);
+
+ int dac_amp = this->dac_amp;
+ if ( dac_amp < 0 )
+ dac_amp = dac_buf [0];
+
+ for ( int i = 0; i < dac_count; i++ )
+ {
+ int delta = dac_buf [i] - dac_amp;
+ dac_amp += delta;
+ dac_synth.offset_resampled( time, delta, &blip_buf );
+ time += period;
+ }
+ this->dac_amp = dac_amp;
+}
+
+void Gym_Emu::parse_frame()
+{
+ int dac_count = 0;
+ const byte* pos = this->pos;
+
+ if ( loop_remain && !--loop_remain )
+ loop_begin = pos; // find loop on first time through sequence
+
+ int cmd;
+ while ( (cmd = *pos++) != 0 )
+ {
+ int data = *pos++;
+ if ( cmd == 1 )
+ {
+ int data2 = *pos++;
+ if ( data != 0x2A )
+ {
+ if ( data == 0x2B )
+ dac_enabled = (data2 & 0x80) != 0;
+
+ fm.write0( data, data2 );
+ }
+ else if ( dac_count < (int) sizeof dac_buf )
+ {
+ dac_buf [dac_count] = data2;
+ dac_count += dac_enabled;
+ }
+ }
+ else if ( cmd == 2 )
+ {
+ fm.write1( data, *pos++ );
+ }
+ else if ( cmd == 3 )
+ {
+ apu.write_data( 0, data );
+ }
+ else
+ {
+ // to do: many GYM streams are full of errors, and error count should
+ // reflect cases where music is really having problems
+ //log_error();
+ --pos; // put data back
+ }
+ }
+
+ // loop
+ if ( pos >= data_end )
+ {
+ check( pos == data_end );
+
+ if ( loop_begin )
+ pos = loop_begin;
+ else
+ set_track_ended();
+ }
+ this->pos = pos;
+
+ // dac
+ if ( dac_count && !dac_muted )
+ run_dac( dac_count );
+ prev_dac_count = dac_count;
+}
+
+int Gym_Emu::play_frame( blip_time_t blip_time, int sample_count, sample_t* buf )
+{
+ if ( !track_ended() )
+ parse_frame();
+
+ apu.end_frame( blip_time );
+
+ memset( buf, 0, sample_count * sizeof *buf );
+ fm.run( sample_count >> 1, buf );
+
+ return sample_count;
+}
+
+blargg_err_t Gym_Emu::play_( long count, sample_t* out )
+{
+ Dual_Resampler::dual_play( count, out, blip_buf );
+ return 0;
+}
diff --git a/src/console/Gym_Emu.cxx b/src/console/Gym_Emu.cxx
deleted file mode 100644
index e850497976a9..000000000000
--- a/src/console/Gym_Emu.cxx
+++ /dev/null
@@ -1,380 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Gym_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-double const min_tempo = 0.25;
-double const oversample_factor = 5 / 3.0;
-double const fm_gain = 3.0;
-
-const long base_clock = 53700300;
-const long clock_rate = base_clock / 15;
-
-Gym_Emu::Gym_Emu()
-{
- data = 0;
- pos = 0;
- set_type( gme_gym_type );
-
- static const char* const names [] = {
- "FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
- };
- set_voice_names( names );
- set_silence_lookahead( 1 ); // tracks should already be trimmed
-}
-
-Gym_Emu::~Gym_Emu() { }
-
-// Track info
-
-static void get_gym_info( Gym_Emu::header_t const& h, long length, track_info_t* out )
-{
- if ( !memcmp( h.tag, "GYMX", 4 ) )
- {
- length = length * 50 / 3; // 1000 / 60
- long loop = GET_LE32( h.loop_start );
- if ( loop )
- {
- out->intro_length = loop * 50 / 3;
- out->loop_length = length - out->intro_length;
- }
- else
- {
- out->length = length;
- out->intro_length = length; // make it clear that track is no longer than length
- out->loop_length = 0;
- }
-
- // more stupidity where the field should have been left
- if ( strcmp( h.song, "Unknown Song" ) )
- GME_COPY_FIELD( h, out, song );
-
- if ( strcmp( h.game, "Unknown Game" ) )
- GME_COPY_FIELD( h, out, game );
-
- if ( strcmp( h.copyright, "Unknown Publisher" ) )
- GME_COPY_FIELD( h, out, copyright );
-
- if ( strcmp( h.dumper, "Unknown Person" ) )
- GME_COPY_FIELD( h, out, dumper );
-
- if ( strcmp( h.comment, "Header added by YMAMP" ) )
- GME_COPY_FIELD( h, out, comment );
- }
-}
-
-blargg_err_t Gym_Emu::track_info_( track_info_t* out, int ) const
-{
- get_gym_info( header_, track_length(), out );
- return 0;
-}
-
-static long gym_track_length( byte const* p, byte const* end )
-{
- long time = 0;
- while ( p < end )
- {
- switch ( *p++ )
- {
- case 0:
- time++;
- break;
-
- case 1:
- case 2:
- p += 2;
- break;
-
- case 3:
- p += 1;
- break;
- }
- }
- return time;
-}
-
-long Gym_Emu::track_length() const { return gym_track_length( data, data_end ); }
-
-static blargg_err_t check_header( byte const* in, long size, int* data_offset = 0 )
-{
- if ( size < 4 )
- return gme_wrong_file_type;
-
- if ( memcmp( in, "GYMX", 4 ) == 0 )
- {
- if ( size < Gym_Emu::header_size + 1 )
- return gme_wrong_file_type;
-
- if ( memcmp( ((Gym_Emu::header_t const*) in)->packed, "\0\0\0\0", 4 ) != 0 )
- return "Packed GYM file not supported";
-
- if ( data_offset )
- *data_offset = Gym_Emu::header_size;
- }
- else if ( *in > 3 )
- {
- return gme_wrong_file_type;
- }
-
- return 0;
-}
-
-struct Gym_File : Gme_Info_
-{
- byte const* file_begin;
- byte const* file_end;
- int data_offset;
-
- Gym_File() { set_type( gme_gym_type ); }
-
- blargg_err_t load_mem_( byte const* in, long size )
- {
- file_begin = in;
- file_end = in + size;
- data_offset = 0;
- return check_header( in, size, &data_offset );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- long length = gym_track_length( &file_begin [data_offset], file_end );
- get_gym_info( *(Gym_Emu::header_t const*) file_begin, length, out );
- return 0;
- }
-};
-
-static Music_Emu* new_gym_emu () { return BLARGG_NEW Gym_Emu ; }
-static Music_Emu* new_gym_file() { return BLARGG_NEW Gym_File; }
-
-static gme_type_t_ const gme_gym_type_ = { "Sega Genesis", 1, &new_gym_emu, &new_gym_file, "GYM", 0 };
-gme_type_t const gme_gym_type = &gme_gym_type_;
-
-// Setup
-
-blargg_err_t Gym_Emu::set_sample_rate_( long sample_rate )
-{
- blip_eq_t eq( -32, 8000, sample_rate );
- apu.treble_eq( eq );
- dac_synth.treble_eq( eq );
- apu.volume( 0.135 * fm_gain * gain() );
- dac_synth.volume( 0.125 / 256 * fm_gain * gain() );
- double factor = Dual_Resampler::setup( oversample_factor, 0.990, fm_gain * gain() );
- fm_sample_rate = sample_rate * factor;
-
- RETURN_ERR( blip_buf.set_sample_rate( sample_rate, int (1000 / 60.0 / min_tempo) ) );
- blip_buf.clock_rate( clock_rate );
-
- RETURN_ERR( fm.set_rate( fm_sample_rate, base_clock / 7.0 ) );
- RETURN_ERR( Dual_Resampler::reset( long (1.0 / 60 / min_tempo * sample_rate) ) );
-
- return 0;
-}
-
-void Gym_Emu::set_tempo_( double t )
-{
- if ( t < min_tempo )
- {
- set_tempo( min_tempo );
- return;
- }
-
- if ( blip_buf.sample_rate() )
- {
- clocks_per_frame = long (clock_rate / 60 / tempo());
- Dual_Resampler::resize( long (sample_rate() / (60.0 * tempo())) );
- }
-}
-
-void Gym_Emu::mute_voices_( int mask )
-{
- Music_Emu::mute_voices_( mask );
- fm.mute_voices( mask );
- dac_muted = (mask & 0x40) != 0;
- apu.output( (mask & 0x80) ? 0 : &blip_buf );
-}
-
-blargg_err_t Gym_Emu::load_mem_( byte const* in, long size )
-{
- assert( offsetof (header_t,packed [4]) == header_size );
- int offset = 0;
- RETURN_ERR( check_header( in, size, &offset ) );
- set_voice_count( 8 );
-
- data = in + offset;
- data_end = in + size;
- loop_begin = 0;
-
- if ( offset )
- header_ = *(header_t const*) in;
- else
- memset( &header_, 0, sizeof header_ );
-
- return 0;
-}
-
-// Emulation
-
-blargg_err_t Gym_Emu::start_track_( int track )
-{
- RETURN_ERR( Music_Emu::start_track_( track ) );
-
- pos = data;
- loop_remain = GET_LE32( header_.loop_start );
-
- prev_dac_count = 0;
- dac_enabled = false;
- dac_amp = -1;
-
- fm.reset();
- apu.reset();
- blip_buf.clear();
- Dual_Resampler::clear();
- return 0;
-}
-
-void Gym_Emu::run_dac( int dac_count )
-{
- // Guess beginning and end of sample and adjust rate and buffer position accordingly.
-
- // count dac samples in next frame
- int next_dac_count = 0;
- const byte* p = this->pos;
- int cmd;
- while ( (cmd = *p++) != 0 )
- {
- int data = *p++;
- if ( cmd <= 2 )
- ++p;
- if ( cmd == 1 && data == 0x2A )
- next_dac_count++;
- }
-
- // detect beginning and end of sample
- int rate_count = dac_count;
- int start = 0;
- if ( !prev_dac_count && next_dac_count && dac_count < next_dac_count )
- {
- rate_count = next_dac_count;
- start = next_dac_count - dac_count;
- }
- else if ( prev_dac_count && !next_dac_count && dac_count < prev_dac_count )
- {
- rate_count = prev_dac_count;
- }
-
- // Evenly space samples within buffer section being used
- blip_resampled_time_t period = blip_buf.resampled_duration( clocks_per_frame ) / rate_count;
-
- blip_resampled_time_t time = blip_buf.resampled_time( 0 ) +
- period * start + (period >> 1);
-
- int dac_amp = this->dac_amp;
- if ( dac_amp < 0 )
- dac_amp = dac_buf [0];
-
- for ( int i = 0; i < dac_count; i++ )
- {
- int delta = dac_buf [i] - dac_amp;
- dac_amp += delta;
- dac_synth.offset_resampled( time, delta, &blip_buf );
- time += period;
- }
- this->dac_amp = dac_amp;
-}
-
-void Gym_Emu::parse_frame()
-{
- int dac_count = 0;
- const byte* pos = this->pos;
-
- if ( loop_remain && !--loop_remain )
- loop_begin = pos; // find loop on first time through sequence
-
- int cmd;
- while ( (cmd = *pos++) != 0 )
- {
- int data = *pos++;
- if ( cmd == 1 )
- {
- int data2 = *pos++;
- if ( data != 0x2A )
- {
- if ( data == 0x2B )
- dac_enabled = (data2 & 0x80) != 0;
-
- fm.write0( data, data2 );
- }
- else if ( dac_count < (int) sizeof dac_buf )
- {
- dac_buf [dac_count] = data2;
- dac_count += dac_enabled;
- }
- }
- else if ( cmd == 2 )
- {
- fm.write1( data, *pos++ );
- }
- else if ( cmd == 3 )
- {
- apu.write_data( 0, data );
- }
- else
- {
- // to do: many GYM streams are full of errors, and error count should
- // reflect cases where music is really having problems
- //log_error();
- --pos; // put data back
- }
- }
-
- // loop
- if ( pos >= data_end )
- {
- check( pos == data_end );
-
- if ( loop_begin )
- pos = loop_begin;
- else
- set_track_ended();
- }
- this->pos = pos;
-
- // dac
- if ( dac_count && !dac_muted )
- run_dac( dac_count );
- prev_dac_count = dac_count;
-}
-
-int Gym_Emu::play_frame( blip_time_t blip_time, int sample_count, sample_t* buf )
-{
- if ( !track_ended() )
- parse_frame();
-
- apu.end_frame( blip_time );
-
- memset( buf, 0, sample_count * sizeof *buf );
- fm.run( sample_count >> 1, buf );
-
- return sample_count;
-}
-
-blargg_err_t Gym_Emu::play_( long count, sample_t* out )
-{
- Dual_Resampler::dual_play( count, out, blip_buf );
- return 0;
-}
diff --git a/src/console/Gzip_Reader.cc b/src/console/Gzip_Reader.cc
new file mode 100644
index 000000000000..2402cf5770ff
--- /dev/null
+++ b/src/console/Gzip_Reader.cc
@@ -0,0 +1,108 @@
+// File_Extractor 0.4.0. http://www.slack.net/~ant/
+
+#include "Gzip_Reader.h"
+
+#include "blargg_endian.h"
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+void Gzip_Reader::close()
+{
+ in = 0;
+ tell_ = 0;
+ size_ = 0;
+ inflater.end();
+}
+
+Gzip_Reader::Gzip_Reader() { close(); }
+
+Gzip_Reader::~Gzip_Reader() { }
+
+static blargg_err_t gzip_reader_read( void* file, void* out, long* count )
+{
+ *count = ((File_Reader*) file)->read_avail( out, *count );
+ return (*count < 0 ? "Read error" : 0);
+}
+
+blargg_err_t Gzip_Reader::open( File_Reader* new_in )
+{
+ close();
+
+ RETURN_ERR( inflater.begin( inflater.mode_auto, gzip_reader_read, new_in ) );
+
+ size_ = -1; // defer seeking to end of file until size is actually needed
+ in = new_in;
+ return 0;
+}
+
+blargg_err_t Gzip_Reader::calc_size()
+{
+ long size = in->size();
+ if ( inflater.deflated() )
+ {
+ byte trailer [4];
+ long pos = in->tell();
+ RETURN_ERR( in->seek( size - sizeof trailer ) );
+ RETURN_ERR( in->read( trailer, sizeof trailer ) );
+ RETURN_ERR( in->seek( pos ) );
+ size = GET_LE32( trailer );
+ }
+ size_ = size;
+ return 0;
+}
+
+long Gzip_Reader::remain() const
+{
+ if ( size_ < 0 )
+ {
+ if ( !in )
+ return 0;
+
+ // need to cast away constness to change cached value
+ if ( ((Gzip_Reader*) this)->calc_size() )
+ return -1;
+ }
+ return size_ - tell_;
+}
+
+blargg_err_t Gzip_Reader::read_( void* out, long* count )
+{
+ blargg_err_t err = inflater.read( out, count, gzip_reader_read, in );
+ tell_ += *count;
+ if ( size_ >= 0 && tell_ > size_ )
+ {
+ tell_ = size_;
+ return "Corrupt gzip file";
+ }
+ return err;
+}
+
+blargg_err_t Gzip_Reader::read( void* out, long count )
+{
+ if ( in )
+ {
+ long actual = count;
+ RETURN_ERR( read_( out, &actual ) );
+ if ( actual == count )
+ return 0;
+ }
+ return eof_error;
+}
+
+long Gzip_Reader::read_avail( void* out, long count )
+{
+ if ( !in || read_( out, &count ) )
+ count = -1;
+ return count;
+}
diff --git a/src/console/Gzip_Reader.cxx b/src/console/Gzip_Reader.cxx
deleted file mode 100644
index 2402cf5770ff..000000000000
--- a/src/console/Gzip_Reader.cxx
+++ /dev/null
@@ -1,108 +0,0 @@
-// File_Extractor 0.4.0. http://www.slack.net/~ant/
-
-#include "Gzip_Reader.h"
-
-#include "blargg_endian.h"
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-void Gzip_Reader::close()
-{
- in = 0;
- tell_ = 0;
- size_ = 0;
- inflater.end();
-}
-
-Gzip_Reader::Gzip_Reader() { close(); }
-
-Gzip_Reader::~Gzip_Reader() { }
-
-static blargg_err_t gzip_reader_read( void* file, void* out, long* count )
-{
- *count = ((File_Reader*) file)->read_avail( out, *count );
- return (*count < 0 ? "Read error" : 0);
-}
-
-blargg_err_t Gzip_Reader::open( File_Reader* new_in )
-{
- close();
-
- RETURN_ERR( inflater.begin( inflater.mode_auto, gzip_reader_read, new_in ) );
-
- size_ = -1; // defer seeking to end of file until size is actually needed
- in = new_in;
- return 0;
-}
-
-blargg_err_t Gzip_Reader::calc_size()
-{
- long size = in->size();
- if ( inflater.deflated() )
- {
- byte trailer [4];
- long pos = in->tell();
- RETURN_ERR( in->seek( size - sizeof trailer ) );
- RETURN_ERR( in->read( trailer, sizeof trailer ) );
- RETURN_ERR( in->seek( pos ) );
- size = GET_LE32( trailer );
- }
- size_ = size;
- return 0;
-}
-
-long Gzip_Reader::remain() const
-{
- if ( size_ < 0 )
- {
- if ( !in )
- return 0;
-
- // need to cast away constness to change cached value
- if ( ((Gzip_Reader*) this)->calc_size() )
- return -1;
- }
- return size_ - tell_;
-}
-
-blargg_err_t Gzip_Reader::read_( void* out, long* count )
-{
- blargg_err_t err = inflater.read( out, count, gzip_reader_read, in );
- tell_ += *count;
- if ( size_ >= 0 && tell_ > size_ )
- {
- tell_ = size_;
- return "Corrupt gzip file";
- }
- return err;
-}
-
-blargg_err_t Gzip_Reader::read( void* out, long count )
-{
- if ( in )
- {
- long actual = count;
- RETURN_ERR( read_( out, &actual ) );
- if ( actual == count )
- return 0;
- }
- return eof_error;
-}
-
-long Gzip_Reader::read_avail( void* out, long count )
-{
- if ( !in || read_( out, &count ) )
- count = -1;
- return count;
-}
diff --git a/src/console/Hes_Apu.cc b/src/console/Hes_Apu.cc
new file mode 100644
index 000000000000..245a4bf55417
--- /dev/null
+++ b/src/console/Hes_Apu.cc
@@ -0,0 +1,315 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Hes_Apu.h"
+
+#include <string.h>
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+bool const center_waves = true; // reduces asymmetry and clamping when starting notes
+
+Hes_Apu::Hes_Apu()
+{
+ Hes_Osc* osc = &oscs [osc_count];
+ do
+ {
+ osc--;
+ osc->outputs [0] = 0;
+ osc->outputs [1] = 0;
+ osc->chans [0] = 0;
+ osc->chans [1] = 0;
+ osc->chans [2] = 0;
+ }
+ while ( osc != oscs );
+
+ reset();
+}
+
+void Hes_Apu::reset()
+{
+ latch = 0;
+ balance = 0xFF;
+
+ Hes_Osc* osc = &oscs [osc_count];
+ do
+ {
+ osc--;
+ memset( osc, 0, offsetof (Hes_Osc,outputs) );
+ osc->noise_lfsr = 1;
+ osc->control = 0x40;
+ osc->balance = 0xFF;
+ }
+ while ( osc != oscs );
+}
+
+void Hes_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
+{
+ require( (unsigned) index < osc_count );
+ oscs [index].chans [0] = center;
+ oscs [index].chans [1] = left;
+ oscs [index].chans [2] = right;
+
+ Hes_Osc* osc = &oscs [osc_count];
+ do
+ {
+ osc--;
+ balance_changed( *osc );
+ }
+ while ( osc != oscs );
+}
+
+void Hes_Osc::run_until( synth_t& synth_, blip_time_t end_time )
+{
+ Blip_Buffer* const osc_outputs_0 = outputs [0]; // cache often-used values
+ if ( osc_outputs_0 && control & 0x80 )
+ {
+ int dac = this->dac;
+
+ int const volume_0 = volume [0];
+ {
+ int delta = dac * volume_0 - last_amp [0];
+ if ( delta )
+ synth_.offset( last_time, delta, osc_outputs_0 );
+ osc_outputs_0->set_modified();
+ }
+
+ Blip_Buffer* const osc_outputs_1 = outputs [1];
+ int const volume_1 = volume [1];
+ if ( osc_outputs_1 )
+ {
+ int delta = dac * volume_1 - last_amp [1];
+ if ( delta )
+ synth_.offset( last_time, delta, osc_outputs_1 );
+ osc_outputs_1->set_modified();
+ }
+
+ blip_time_t time = last_time + delay;
+ if ( time < end_time )
+ {
+ if ( noise & 0x80 )
+ {
+ if ( volume_0 | volume_1 )
+ {
+ // noise
+ int const period = (32 - (noise & 0x1F)) * 64; // TODO: correct?
+ unsigned noise_lfsr = this->noise_lfsr;
+ do
+ {
+ int new_dac = 0x1F & -(noise_lfsr >> 1 & 1);
+ // Implemented using "Galios configuration"
+ // TODO: find correct LFSR algorithm
+ noise_lfsr = (noise_lfsr >> 1) ^ (0xE008 & -(noise_lfsr & 1));
+ //noise_lfsr = (noise_lfsr >> 1) ^ (0x6000 & -(noise_lfsr & 1));
+ int delta = new_dac - dac;
+ if ( delta )
+ {
+ dac = new_dac;
+ synth_.offset( time, delta * volume_0, osc_outputs_0 );
+ if ( osc_outputs_1 )
+ synth_.offset( time, delta * volume_1, osc_outputs_1 );
+ }
+ time += period;
+ }
+ while ( time < end_time );
+
+ this->noise_lfsr = noise_lfsr;
+ assert( noise_lfsr );
+ }
+ }
+ else if ( !(control & 0x40) )
+ {
+ // wave
+ int phase = (this->phase + 1) & 0x1F; // pre-advance for optimal inner loop
+ int period = this->period * 2;
+ if ( period >= 14 && (volume_0 | volume_1) )
+ {
+ do
+ {
+ int new_dac = wave [phase];
+ phase = (phase + 1) & 0x1F;
+ int delta = new_dac - dac;
+ if ( delta )
+ {
+ dac = new_dac;
+ synth_.offset( time, delta * volume_0, osc_outputs_0 );
+ if ( osc_outputs_1 )
+ synth_.offset( time, delta * volume_1, osc_outputs_1 );
+ }
+ time += period;
+ }
+ while ( time < end_time );
+ }
+ else
+ {
+ if ( !period )
+ {
+ // TODO: Gekisha Boy assumes that period = 0 silences wave
+ //period = 0x1000 * 2;
+ period = 1;
+ //if ( !(volume_0 | volume_1) )
+ // debug_printf( "Used period 0\n" );
+ }
+
+ // maintain phase when silent
+ blargg_long count = (end_time - time + period - 1) / period;
+ phase += count; // phase will be masked below
+ time += count * period;
+ }
+ this->phase = (phase - 1) & 0x1F; // undo pre-advance
+ }
+ }
+ time -= end_time;
+ if ( time < 0 )
+ time = 0;
+ delay = time;
+
+ this->dac = dac;
+ last_amp [0] = dac * volume_0;
+ last_amp [1] = dac * volume_1;
+ }
+ last_time = end_time;
+}
+
+void Hes_Apu::balance_changed( Hes_Osc& osc )
+{
+ static short const log_table [32] = { // ~1.5 db per step
+ #define ENTRY( factor ) short (factor * Hes_Osc::amp_range / 31.0 + 0.5)
+ ENTRY( 0.000000 ),ENTRY( 0.005524 ),ENTRY( 0.006570 ),ENTRY( 0.007813 ),
+ ENTRY( 0.009291 ),ENTRY( 0.011049 ),ENTRY( 0.013139 ),ENTRY( 0.015625 ),
+ ENTRY( 0.018581 ),ENTRY( 0.022097 ),ENTRY( 0.026278 ),ENTRY( 0.031250 ),
+ ENTRY( 0.037163 ),ENTRY( 0.044194 ),ENTRY( 0.052556 ),ENTRY( 0.062500 ),
+ ENTRY( 0.074325 ),ENTRY( 0.088388 ),ENTRY( 0.105112 ),ENTRY( 0.125000 ),
+ ENTRY( 0.148651 ),ENTRY( 0.176777 ),ENTRY( 0.210224 ),ENTRY( 0.250000 ),
+ ENTRY( 0.297302 ),ENTRY( 0.353553 ),ENTRY( 0.420448 ),ENTRY( 0.500000 ),
+ ENTRY( 0.594604 ),ENTRY( 0.707107 ),ENTRY( 0.840896 ),ENTRY( 1.000000 ),
+ #undef ENTRY
+ };
+
+ int vol = (osc.control & 0x1F) - 0x1E * 2;
+
+ int left = vol + (osc.balance >> 3 & 0x1E) + (balance >> 3 & 0x1E);
+ if ( left < 0 ) left = 0;
+
+ int right = vol + (osc.balance << 1 & 0x1E) + (balance << 1 & 0x1E);
+ if ( right < 0 ) right = 0;
+
+ left = log_table [left ];
+ right = log_table [right];
+
+ // optimizing for the common case of being centered also allows easy
+ // panning using Effects_Buffer
+ osc.outputs [0] = osc.chans [0]; // center
+ osc.outputs [1] = 0;
+ if ( left != right )
+ {
+ osc.outputs [0] = osc.chans [1]; // left
+ osc.outputs [1] = osc.chans [2]; // right
+ }
+
+ if ( center_waves )
+ {
+ osc.last_amp [0] += (left - osc.volume [0]) * 16;
+ osc.last_amp [1] += (right - osc.volume [1]) * 16;
+ }
+
+ osc.volume [0] = left;
+ osc.volume [1] = right;
+}
+
+void Hes_Apu::write_data( blip_time_t time, int addr, int data )
+{
+ if ( addr == 0x800 )
+ {
+ latch = data & 7;
+ }
+ else if ( addr == 0x801 )
+ {
+ if ( balance != data )
+ {
+ balance = data;
+
+ Hes_Osc* osc = &oscs [osc_count];
+ do
+ {
+ osc--;
+ osc->run_until( synth, time );
+ balance_changed( *oscs );
+ }
+ while ( osc != oscs );
+ }
+ }
+ else if ( latch < osc_count )
+ {
+ Hes_Osc& osc = oscs [latch];
+ osc.run_until( synth, time );
+ switch ( addr )
+ {
+ case 0x802:
+ osc.period = (osc.period & 0xF00) | data;
+ break;
+
+ case 0x803:
+ osc.period = (osc.period & 0x0FF) | ((data & 0x0F) << 8);
+ break;
+
+ case 0x804:
+ if ( osc.control & 0x40 & ~data )
+ osc.phase = 0;
+ osc.control = data;
+ balance_changed( osc );
+ break;
+
+ case 0x805:
+ osc.balance = data;
+ balance_changed( osc );
+ break;
+
+ case 0x806:
+ data &= 0x1F;
+ if ( !(osc.control & 0x40) )
+ {
+ osc.wave [osc.phase] = data;
+ osc.phase = (osc.phase + 1) & 0x1F;
+ }
+ else if ( osc.control & 0x80 )
+ {
+ osc.dac = data;
+ }
+ break;
+
+ case 0x807:
+ if ( &osc >= &oscs [4] )
+ osc.noise = data;
+ break;
+
+ case 0x809:
+ if ( !(data & 0x80) && (data & 0x03) != 0 )
+ debug_printf( "HES LFO not supported\n" );
+ }
+ }
+}
+
+void Hes_Apu::end_frame( blip_time_t end_time )
+{
+ Hes_Osc* osc = &oscs [osc_count];
+ do
+ {
+ osc--;
+ if ( end_time > osc->last_time )
+ osc->run_until( synth, end_time );
+ assert( osc->last_time >= end_time );
+ osc->last_time -= end_time;
+ }
+ while ( osc != oscs );
+}
diff --git a/src/console/Hes_Apu.cxx b/src/console/Hes_Apu.cxx
deleted file mode 100644
index 245a4bf55417..000000000000
--- a/src/console/Hes_Apu.cxx
+++ /dev/null
@@ -1,315 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Hes_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-bool const center_waves = true; // reduces asymmetry and clamping when starting notes
-
-Hes_Apu::Hes_Apu()
-{
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- osc->outputs [0] = 0;
- osc->outputs [1] = 0;
- osc->chans [0] = 0;
- osc->chans [1] = 0;
- osc->chans [2] = 0;
- }
- while ( osc != oscs );
-
- reset();
-}
-
-void Hes_Apu::reset()
-{
- latch = 0;
- balance = 0xFF;
-
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- memset( osc, 0, offsetof (Hes_Osc,outputs) );
- osc->noise_lfsr = 1;
- osc->control = 0x40;
- osc->balance = 0xFF;
- }
- while ( osc != oscs );
-}
-
-void Hes_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- require( (unsigned) index < osc_count );
- oscs [index].chans [0] = center;
- oscs [index].chans [1] = left;
- oscs [index].chans [2] = right;
-
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- balance_changed( *osc );
- }
- while ( osc != oscs );
-}
-
-void Hes_Osc::run_until( synth_t& synth_, blip_time_t end_time )
-{
- Blip_Buffer* const osc_outputs_0 = outputs [0]; // cache often-used values
- if ( osc_outputs_0 && control & 0x80 )
- {
- int dac = this->dac;
-
- int const volume_0 = volume [0];
- {
- int delta = dac * volume_0 - last_amp [0];
- if ( delta )
- synth_.offset( last_time, delta, osc_outputs_0 );
- osc_outputs_0->set_modified();
- }
-
- Blip_Buffer* const osc_outputs_1 = outputs [1];
- int const volume_1 = volume [1];
- if ( osc_outputs_1 )
- {
- int delta = dac * volume_1 - last_amp [1];
- if ( delta )
- synth_.offset( last_time, delta, osc_outputs_1 );
- osc_outputs_1->set_modified();
- }
-
- blip_time_t time = last_time + delay;
- if ( time < end_time )
- {
- if ( noise & 0x80 )
- {
- if ( volume_0 | volume_1 )
- {
- // noise
- int const period = (32 - (noise & 0x1F)) * 64; // TODO: correct?
- unsigned noise_lfsr = this->noise_lfsr;
- do
- {
- int new_dac = 0x1F & -(noise_lfsr >> 1 & 1);
- // Implemented using "Galios configuration"
- // TODO: find correct LFSR algorithm
- noise_lfsr = (noise_lfsr >> 1) ^ (0xE008 & -(noise_lfsr & 1));
- //noise_lfsr = (noise_lfsr >> 1) ^ (0x6000 & -(noise_lfsr & 1));
- int delta = new_dac - dac;
- if ( delta )
- {
- dac = new_dac;
- synth_.offset( time, delta * volume_0, osc_outputs_0 );
- if ( osc_outputs_1 )
- synth_.offset( time, delta * volume_1, osc_outputs_1 );
- }
- time += period;
- }
- while ( time < end_time );
-
- this->noise_lfsr = noise_lfsr;
- assert( noise_lfsr );
- }
- }
- else if ( !(control & 0x40) )
- {
- // wave
- int phase = (this->phase + 1) & 0x1F; // pre-advance for optimal inner loop
- int period = this->period * 2;
- if ( period >= 14 && (volume_0 | volume_1) )
- {
- do
- {
- int new_dac = wave [phase];
- phase = (phase + 1) & 0x1F;
- int delta = new_dac - dac;
- if ( delta )
- {
- dac = new_dac;
- synth_.offset( time, delta * volume_0, osc_outputs_0 );
- if ( osc_outputs_1 )
- synth_.offset( time, delta * volume_1, osc_outputs_1 );
- }
- time += period;
- }
- while ( time < end_time );
- }
- else
- {
- if ( !period )
- {
- // TODO: Gekisha Boy assumes that period = 0 silences wave
- //period = 0x1000 * 2;
- period = 1;
- //if ( !(volume_0 | volume_1) )
- // debug_printf( "Used period 0\n" );
- }
-
- // maintain phase when silent
- blargg_long count = (end_time - time + period - 1) / period;
- phase += count; // phase will be masked below
- time += count * period;
- }
- this->phase = (phase - 1) & 0x1F; // undo pre-advance
- }
- }
- time -= end_time;
- if ( time < 0 )
- time = 0;
- delay = time;
-
- this->dac = dac;
- last_amp [0] = dac * volume_0;
- last_amp [1] = dac * volume_1;
- }
- last_time = end_time;
-}
-
-void Hes_Apu::balance_changed( Hes_Osc& osc )
-{
- static short const log_table [32] = { // ~1.5 db per step
- #define ENTRY( factor ) short (factor * Hes_Osc::amp_range / 31.0 + 0.5)
- ENTRY( 0.000000 ),ENTRY( 0.005524 ),ENTRY( 0.006570 ),ENTRY( 0.007813 ),
- ENTRY( 0.009291 ),ENTRY( 0.011049 ),ENTRY( 0.013139 ),ENTRY( 0.015625 ),
- ENTRY( 0.018581 ),ENTRY( 0.022097 ),ENTRY( 0.026278 ),ENTRY( 0.031250 ),
- ENTRY( 0.037163 ),ENTRY( 0.044194 ),ENTRY( 0.052556 ),ENTRY( 0.062500 ),
- ENTRY( 0.074325 ),ENTRY( 0.088388 ),ENTRY( 0.105112 ),ENTRY( 0.125000 ),
- ENTRY( 0.148651 ),ENTRY( 0.176777 ),ENTRY( 0.210224 ),ENTRY( 0.250000 ),
- ENTRY( 0.297302 ),ENTRY( 0.353553 ),ENTRY( 0.420448 ),ENTRY( 0.500000 ),
- ENTRY( 0.594604 ),ENTRY( 0.707107 ),ENTRY( 0.840896 ),ENTRY( 1.000000 ),
- #undef ENTRY
- };
-
- int vol = (osc.control & 0x1F) - 0x1E * 2;
-
- int left = vol + (osc.balance >> 3 & 0x1E) + (balance >> 3 & 0x1E);
- if ( left < 0 ) left = 0;
-
- int right = vol + (osc.balance << 1 & 0x1E) + (balance << 1 & 0x1E);
- if ( right < 0 ) right = 0;
-
- left = log_table [left ];
- right = log_table [right];
-
- // optimizing for the common case of being centered also allows easy
- // panning using Effects_Buffer
- osc.outputs [0] = osc.chans [0]; // center
- osc.outputs [1] = 0;
- if ( left != right )
- {
- osc.outputs [0] = osc.chans [1]; // left
- osc.outputs [1] = osc.chans [2]; // right
- }
-
- if ( center_waves )
- {
- osc.last_amp [0] += (left - osc.volume [0]) * 16;
- osc.last_amp [1] += (right - osc.volume [1]) * 16;
- }
-
- osc.volume [0] = left;
- osc.volume [1] = right;
-}
-
-void Hes_Apu::write_data( blip_time_t time, int addr, int data )
-{
- if ( addr == 0x800 )
- {
- latch = data & 7;
- }
- else if ( addr == 0x801 )
- {
- if ( balance != data )
- {
- balance = data;
-
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- osc->run_until( synth, time );
- balance_changed( *oscs );
- }
- while ( osc != oscs );
- }
- }
- else if ( latch < osc_count )
- {
- Hes_Osc& osc = oscs [latch];
- osc.run_until( synth, time );
- switch ( addr )
- {
- case 0x802:
- osc.period = (osc.period & 0xF00) | data;
- break;
-
- case 0x803:
- osc.period = (osc.period & 0x0FF) | ((data & 0x0F) << 8);
- break;
-
- case 0x804:
- if ( osc.control & 0x40 & ~data )
- osc.phase = 0;
- osc.control = data;
- balance_changed( osc );
- break;
-
- case 0x805:
- osc.balance = data;
- balance_changed( osc );
- break;
-
- case 0x806:
- data &= 0x1F;
- if ( !(osc.control & 0x40) )
- {
- osc.wave [osc.phase] = data;
- osc.phase = (osc.phase + 1) & 0x1F;
- }
- else if ( osc.control & 0x80 )
- {
- osc.dac = data;
- }
- break;
-
- case 0x807:
- if ( &osc >= &oscs [4] )
- osc.noise = data;
- break;
-
- case 0x809:
- if ( !(data & 0x80) && (data & 0x03) != 0 )
- debug_printf( "HES LFO not supported\n" );
- }
- }
-}
-
-void Hes_Apu::end_frame( blip_time_t end_time )
-{
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- if ( end_time > osc->last_time )
- osc->run_until( synth, end_time );
- assert( osc->last_time >= end_time );
- osc->last_time -= end_time;
- }
- while ( osc != oscs );
-}
diff --git a/src/console/Hes_Cpu.cc b/src/console/Hes_Cpu.cc
new file mode 100644
index 000000000000..24ef7b36835f
--- /dev/null
+++ b/src/console/Hes_Cpu.cc
@@ -0,0 +1,1301 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Hes_Cpu.h"
+
+#include "blargg_endian.h"
+
+//#include "hes_cpu_log.h"
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+// TODO: support T flag, including clearing it at appropriate times?
+
+// all zero-page should really use whatever is at page 1, but that would
+// reduce efficiency quite a bit
+int const ram_addr = 0x2000;
+
+#define FLUSH_TIME() (void) (s.time = s_time)
+#define CACHE_TIME() (void) (s_time = s.time)
+
+#include "hes_cpu_io.h"
+
+#include "blargg_source.h"
+
+#if BLARGG_NONPORTABLE
+ #define PAGE_OFFSET( addr ) (addr)
+#else
+ #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
+#endif
+
+// status flags
+int const st_n = 0x80;
+int const st_v = 0x40;
+//int const st_t = 0x20;
+int const st_b = 0x10;
+int const st_d = 0x08;
+int const st_i = 0x04;
+int const st_z = 0x02;
+int const st_c = 0x01;
+
+void Hes_Cpu::reset()
+{
+ check( state == &state_ );
+ state = &state_;
+
+ state_.time = 0;
+ state_.base = 0;
+ irq_time_ = future_hes_time;
+ end_time_ = future_hes_time;
+
+ r.status = st_i;
+ r.sp = 0;
+ r.pc = 0;
+ r.a = 0;
+ r.x = 0;
+ r.y = 0;
+}
+
+void Hes_Cpu::set_mmr( int reg, int bank )
+{
+ assert( (unsigned) reg <= page_count ); // allow page past end to be set
+ assert( (unsigned) bank < 0x100 );
+ mmr [reg] = bank;
+ uint8_t const* code = CPU_SET_MMR( this, reg, bank );
+ state->code_map [reg] = code - PAGE_OFFSET( reg << page_shift );
+}
+
+#define TIME (s_time + s.base)
+
+#define READ( addr ) CPU_READ( this, (addr), TIME )
+#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), TIME );}
+#define READ_LOW( addr ) (ram [int (addr)])
+#define WRITE_LOW( addr, data ) (void) (READ_LOW( addr ) = (data))
+#define READ_PROG( addr ) (s.code_map [(addr) >> page_shift] [PAGE_OFFSET( addr )])
+
+#define SET_SP( v ) (sp = ((v) + 1) | 0x100)
+#define GET_SP() ((sp - 1) & 0xFF)
+#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
+
+// even on x86, using short and unsigned char was slower
+typedef int fint16;
+typedef unsigned fuint16;
+typedef unsigned fuint8;
+typedef blargg_long fint32;
+
+bool Hes_Cpu::run( hes_time_t end_time )
+{
+ bool illegal_encountered = false;
+ set_end_time( end_time );
+ state_t s = this->state_;
+ this->state = &s;
+ // even on x86, using s.time in place of s_time was slower
+ fint16 s_time = s.time;
+
+ // registers
+ fuint16 pc = r.pc;
+ fuint8 a = r.a;
+ fuint8 x = r.x;
+ fuint8 y = r.y;
+ fuint16 sp;
+ SET_SP( r.sp );
+
+ #define IS_NEG (nz & 0x8080)
+
+ #define CALC_STATUS( out ) do {\
+ out = status & (st_v | st_d | st_i);\
+ out |= ((nz >> 8) | nz) & st_n;\
+ out |= c >> 8 & st_c;\
+ if ( !(nz & 0xFF) ) out |= st_z;\
+ } while ( 0 )
+
+ #define SET_STATUS( in ) do {\
+ status = in & (st_v | st_d | st_i);\
+ nz = in << 8;\
+ c = nz;\
+ nz |= ~in & st_z;\
+ } while ( 0 )
+
+ fuint8 status;
+ fuint16 c; // carry set if (c & 0x100) != 0
+ fuint16 nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
+ {
+ fuint8 temp = r.status;
+ SET_STATUS( temp );
+ }
+
+ goto loop;
+branch_not_taken:
+ s_time -= 2;
+loop:
+
+ #ifndef NDEBUG
+ {
+ hes_time_t correct = end_time_;
+ if ( !(status & st_i) && correct > irq_time_ )
+ correct = irq_time_;
+ check( s.base == correct );
+ /*
+ static long count;
+ if ( count == 1844 ) Debugger();
+ if ( s.base != correct ) debug_printf( "%ld\n", count );
+ count++;
+ */
+ }
+ #endif
+
+ check( (unsigned) GET_SP() < 0x100 );
+ check( (unsigned) a < 0x100 );
+ check( (unsigned) x < 0x100 );
+
+ uint8_t const* instr = s.code_map [pc >> page_shift];
+ fuint8 opcode;
+
+ // TODO: eliminate this special case
+ #if BLARGG_NONPORTABLE
+ opcode = instr [pc];
+ pc++;
+ instr += pc;
+ #else
+ instr += PAGE_OFFSET( pc );
+ opcode = *instr++;
+ pc++;
+ #endif
+
+ // TODO: each reference lists slightly different timing values, ugh
+ static uint8_t const clock_table [256] =
+ {// 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 1,7,3, 4,6,4,6,7,3,2,2,2,7,5,7,6,// 0
+ 4,7,7, 4,6,4,6,7,2,5,2,2,7,5,7,6,// 1
+ 7,7,3, 4,4,4,6,7,4,2,2,2,5,5,7,6,// 2
+ 4,7,7, 2,4,4,6,7,2,5,2,2,5,5,7,6,// 3
+ 7,7,3, 4,8,4,6,7,3,2,2,2,4,5,7,6,// 4
+ 4,7,7, 5,2,4,6,7,2,5,3,2,2,5,7,6,// 5
+ 7,7,2, 2,4,4,6,7,4,2,2,2,7,5,7,6,// 6
+ 4,7,7,17,4,4,6,7,2,5,4,2,7,5,7,6,// 7
+ 4,7,2, 7,4,4,4,7,2,2,2,2,5,5,5,6,// 8
+ 4,7,7, 8,4,4,4,7,2,5,2,2,5,5,5,6,// 9
+ 2,7,2, 7,4,4,4,7,2,2,2,2,5,5,5,6,// A
+ 4,7,7, 8,4,4,4,7,2,5,2,2,5,5,5,6,// B
+ 2,7,2,17,4,4,6,7,2,2,2,2,5,5,7,6,// C
+ 4,7,7,17,2,4,6,7,2,5,3,2,2,5,7,6,// D
+ 2,7,2,17,4,4,6,7,2,2,2,2,5,5,7,6,// E
+ 4,7,7,17,2,4,6,7,2,5,4,2,2,5,7,6 // F
+ }; // 0x00 was 8
+
+ fuint16 data;
+ data = clock_table [opcode];
+ if ( (s_time += data) >= 0 )
+ goto possibly_out_of_time;
+almost_out_of_time:
+
+ data = *instr;
+
+ #ifdef HES_CPU_LOG_H
+ log_cpu( "new", pc - 1, opcode, instr [0], instr [1], instr [2],
+ instr [3], instr [4], instr [5] );
+ //log_opcode( opcode );
+ #endif
+
+ switch ( opcode )
+ {
+possibly_out_of_time:
+ if ( s_time < (int) data )
+ goto almost_out_of_time;
+ s_time -= data;
+ goto out_of_time;
+
+// Macros
+
+#define GET_MSB() (instr [1])
+#define ADD_PAGE( out ) (pc++, out = data + 0x100 * GET_MSB());
+#define GET_ADDR() GET_LE16( instr )
+
+// TODO: is the penalty really always added? the original 6502 was much better
+//#define PAGE_CROSS_PENALTY( lsb ) (void) (s_time += (lsb) >> 8)
+#define PAGE_CROSS_PENALTY( lsb )
+
+// Branch
+
+// TODO: more efficient way to handle negative branch that wraps PC around
+#define BRANCH( cond )\
+{\
+ fint16 offset = (int8_t) data;\
+ pc++;\
+ if ( !(cond) ) goto branch_not_taken;\
+ pc = uint16_t (pc + offset);\
+ goto loop;\
+}
+
+ case 0xF0: // BEQ
+ BRANCH( !((uint8_t) nz) );
+
+ case 0xD0: // BNE
+ BRANCH( (uint8_t) nz );
+
+ case 0x10: // BPL
+ BRANCH( !IS_NEG );
+
+ case 0x90: // BCC
+ BRANCH( !(c & 0x100) )
+
+ case 0x30: // BMI
+ BRANCH( IS_NEG )
+
+ case 0x50: // BVC
+ BRANCH( !(status & st_v) )
+
+ case 0x70: // BVS
+ BRANCH( status & st_v )
+
+ case 0xB0: // BCS
+ BRANCH( c & 0x100 )
+
+ case 0x80: // BRA
+ branch_taken:
+ BRANCH( true );
+
+ case 0xFF:
+ if ( pc == idle_addr + 1 )
+ goto idle_done;
+ case 0x0F: // BBRn
+ case 0x1F:
+ case 0x2F:
+ case 0x3F:
+ case 0x4F:
+ case 0x5F:
+ case 0x6F:
+ case 0x7F:
+ case 0x8F: // BBSn
+ case 0x9F:
+ case 0xAF:
+ case 0xBF:
+ case 0xCF:
+ case 0xDF:
+ case 0xEF: {
+ fuint16 t = 0x101 * READ_LOW( data );
+ t ^= 0xFF;
+ pc++;
+ data = GET_MSB();
+ BRANCH( t & (1 << (opcode >> 4)) )
+ }
+
+ case 0x4C: // JMP abs
+ pc = GET_ADDR();
+ goto loop;
+
+ case 0x7C: // JMP (ind+X)
+ data += x;
+ case 0x6C:{// JMP (ind)
+ data += 0x100 * GET_MSB();
+ pc = GET_LE16( &READ_PROG( data ) );
+ goto loop;
+ }
+
+// Subroutine
+
+ case 0x44: // BSR
+ WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
+ sp = (sp - 2) | 0x100;
+ WRITE_LOW( sp, pc );
+ goto branch_taken;
+
+ case 0x20: { // JSR
+ fuint16 temp = pc + 1;
+ pc = GET_ADDR();
+ WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
+ sp = (sp - 2) | 0x100;
+ WRITE_LOW( sp, temp );
+ goto loop;
+ }
+
+ case 0x60: // RTS
+ pc = 0x100 * READ_LOW( 0x100 | (sp - 0xFF) );
+ pc += 1 + READ_LOW( sp );
+ sp = (sp - 0xFE) | 0x100;
+ goto loop;
+
+ case 0x00: // BRK
+ goto handle_brk;
+
+// Common
+
+ case 0xBD:{// LDA abs,X
+ PAGE_CROSS_PENALTY( data + x );
+ fuint16 addr = GET_ADDR() + x;
+ pc += 2;
+ CPU_READ_FAST( this, addr, TIME, nz );
+ a = nz;
+ goto loop;
+ }
+
+ case 0x9D:{// STA abs,X
+ fuint16 addr = GET_ADDR() + x;
+ pc += 2;
+ CPU_WRITE_FAST( this, addr, a, TIME );
+ goto loop;
+ }
+
+ case 0x95: // STA zp,x
+ data = uint8_t (data + x);
+ case 0x85: // STA zp
+ pc++;
+ WRITE_LOW( data, a );
+ goto loop;
+
+ case 0xAE:{// LDX abs
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ CPU_READ_FAST( this, addr, TIME, nz );
+ x = nz;
+ goto loop;
+ }
+
+ case 0xA5: // LDA zp
+ a = nz = READ_LOW( data );
+ pc++;
+ goto loop;
+
+// Load/store
+
+ {
+ fuint16 addr;
+ case 0x91: // STA (ind),Y
+ addr = 0x100 * READ_LOW( uint8_t (data + 1) );
+ addr += READ_LOW( data ) + y;
+ pc++;
+ goto sta_ptr;
+
+ case 0x81: // STA (ind,X)
+ data = uint8_t (data + x);
+ case 0x92: // STA (ind)
+ addr = 0x100 * READ_LOW( uint8_t (data + 1) );
+ addr += READ_LOW( data );
+ pc++;
+ goto sta_ptr;
+
+ case 0x99: // STA abs,Y
+ data += y;
+ case 0x8D: // STA abs
+ addr = data + 0x100 * GET_MSB();
+ pc += 2;
+ sta_ptr:
+ CPU_WRITE_FAST( this, addr, a, TIME );
+ goto loop;
+ }
+
+ {
+ fuint16 addr;
+ case 0xA1: // LDA (ind,X)
+ data = uint8_t (data + x);
+ case 0xB2: // LDA (ind)
+ addr = 0x100 * READ_LOW( uint8_t (data + 1) );
+ addr += READ_LOW( data );
+ pc++;
+ goto a_nz_read_addr;
+
+ case 0xB1:// LDA (ind),Y
+ addr = READ_LOW( data ) + y;
+ PAGE_CROSS_PENALTY( addr );
+ addr += 0x100 * READ_LOW( (uint8_t) (data + 1) );
+ pc++;
+ goto a_nz_read_addr;
+
+ case 0xB9: // LDA abs,Y
+ data += y;
+ PAGE_CROSS_PENALTY( data );
+ case 0xAD: // LDA abs
+ addr = data + 0x100 * GET_MSB();
+ pc += 2;
+ a_nz_read_addr:
+ CPU_READ_FAST( this, addr, TIME, nz );
+ a = nz;
+ goto loop;
+ }
+
+ case 0xBE:{// LDX abs,y
+ PAGE_CROSS_PENALTY( data + y );
+ fuint16 addr = GET_ADDR() + y;
+ pc += 2;
+ FLUSH_TIME();
+ x = nz = READ( addr );
+ CACHE_TIME();
+ goto loop;
+ }
+
+ case 0xB5: // LDA zp,x
+ a = nz = READ_LOW( uint8_t (data + x) );
+ pc++;
+ goto loop;
+
+ case 0xA9: // LDA #imm
+ pc++;
+ a = data;
+ nz = data;
+ goto loop;
+
+// Bit operations
+
+ case 0x3C: // BIT abs,x
+ data += x;
+ case 0x2C:{// BIT abs
+ fuint16 addr;
+ ADD_PAGE( addr );
+ FLUSH_TIME();
+ nz = READ( addr );
+ CACHE_TIME();
+ goto bit_common;
+ }
+ case 0x34: // BIT zp,x
+ data = uint8_t (data + x);
+ case 0x24: // BIT zp
+ data = READ_LOW( data );
+ case 0x89: // BIT imm
+ nz = data;
+ bit_common:
+ pc++;
+ status &= ~st_v;
+ status |= nz & st_v;
+ if ( nz & a )
+ goto loop; // Z should be clear, and nz must be non-zero if nz & a is
+ nz <<= 8; // set Z flag without affecting N flag
+ goto loop;
+
+ {
+ fuint16 addr;
+
+ case 0xB3: // TST abs,x
+ addr = GET_MSB() + x;
+ goto tst_abs;
+
+ case 0x93: // TST abs
+ addr = GET_MSB();
+ tst_abs:
+ addr += 0x100 * instr [2];
+ pc++;
+ FLUSH_TIME();
+ nz = READ( addr );
+ CACHE_TIME();
+ goto tst_common;
+ }
+
+ case 0xA3: // TST zp,x
+ nz = READ_LOW( uint8_t (GET_MSB() + x) );
+ goto tst_common;
+
+ case 0x83: // TST zp
+ nz = READ_LOW( GET_MSB() );
+ tst_common:
+ pc += 2;
+ status &= ~st_v;
+ status |= nz & st_v;
+ if ( nz & data )
+ goto loop; // Z should be clear, and nz must be non-zero if nz & data is
+ nz <<= 8; // set Z flag without affecting N flag
+ goto loop;
+
+ {
+ fuint16 addr;
+ case 0x0C: // TSB abs
+ case 0x1C: // TRB abs
+ addr = GET_ADDR();
+ pc++;
+ goto txb_addr;
+
+ // TODO: everyone lists different behaviors for the status flags, ugh
+ case 0x04: // TSB zp
+ case 0x14: // TRB zp
+ addr = data + ram_addr;
+ txb_addr:
+ FLUSH_TIME();
+ nz = a | READ( addr );
+ if ( opcode & 0x10 )
+ nz ^= a; // bits from a will already be set, so this clears them
+ status &= ~st_v;
+ status |= nz & st_v;
+ pc++;
+ WRITE( addr, nz );
+ CACHE_TIME();
+ goto loop;
+ }
+
+ case 0x07: // RMBn
+ case 0x17:
+ case 0x27:
+ case 0x37:
+ case 0x47:
+ case 0x57:
+ case 0x67:
+ case 0x77:
+ pc++;
+ READ_LOW( data ) &= ~(1 << (opcode >> 4));
+ goto loop;
+
+ case 0x87: // SMBn
+ case 0x97:
+ case 0xA7:
+ case 0xB7:
+ case 0xC7:
+ case 0xD7:
+ case 0xE7:
+ case 0xF7:
+ pc++;
+ READ_LOW( data ) |= 1 << ((opcode >> 4) - 8);
+ goto loop;
+
+// Load/store
+
+ case 0x9E: // STZ abs,x
+ data += x;
+ case 0x9C: // STZ abs
+ ADD_PAGE( data );
+ pc++;
+ FLUSH_TIME();
+ WRITE( data, 0 );
+ CACHE_TIME();
+ goto loop;
+
+ case 0x74: // STZ zp,x
+ data = uint8_t (data + x);
+ case 0x64: // STZ zp
+ pc++;
+ WRITE_LOW( data, 0 );
+ goto loop;
+
+ case 0x94: // STY zp,x
+ data = uint8_t (data + x);
+ case 0x84: // STY zp
+ pc++;
+ WRITE_LOW( data, y );
+ goto loop;
+
+ case 0x96: // STX zp,y
+ data = uint8_t (data + y);
+ case 0x86: // STX zp
+ pc++;
+ WRITE_LOW( data, x );
+ goto loop;
+
+ case 0xB6: // LDX zp,y
+ data = uint8_t (data + y);
+ case 0xA6: // LDX zp
+ data = READ_LOW( data );
+ case 0xA2: // LDX #imm
+ pc++;
+ x = data;
+ nz = data;
+ goto loop;
+
+ case 0xB4: // LDY zp,x
+ data = uint8_t (data + x);
+ case 0xA4: // LDY zp
+ data = READ_LOW( data );
+ case 0xA0: // LDY #imm
+ pc++;
+ y = data;
+ nz = data;
+ goto loop;
+
+ case 0xBC: // LDY abs,X
+ data += x;
+ PAGE_CROSS_PENALTY( data );
+ case 0xAC:{// LDY abs
+ fuint16 addr = data + 0x100 * GET_MSB();
+ pc += 2;
+ FLUSH_TIME();
+ y = nz = READ( addr );
+ CACHE_TIME();
+ goto loop;
+ }
+
+ {
+ fuint8 temp;
+ case 0x8C: // STY abs
+ temp = y;
+ goto store_abs;
+
+ case 0x8E: // STX abs
+ temp = x;
+ store_abs:
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ FLUSH_TIME();
+ WRITE( addr, temp );
+ CACHE_TIME();
+ goto loop;
+ }
+
+// Compare
+
+ case 0xEC:{// CPX abs
+ fuint16 addr = GET_ADDR();
+ pc++;
+ FLUSH_TIME();
+ data = READ( addr );
+ CACHE_TIME();
+ goto cpx_data;
+ }
+
+ case 0xE4: // CPX zp
+ data = READ_LOW( data );
+ case 0xE0: // CPX #imm
+ cpx_data:
+ nz = x - data;
+ pc++;
+ c = ~nz;
+ nz &= 0xFF;
+ goto loop;
+
+ case 0xCC:{// CPY abs
+ fuint16 addr = GET_ADDR();
+ pc++;
+ FLUSH_TIME();
+ data = READ( addr );
+ CACHE_TIME();
+ goto cpy_data;
+ }
+
+ case 0xC4: // CPY zp
+ data = READ_LOW( data );
+ case 0xC0: // CPY #imm
+ cpy_data:
+ nz = y - data;
+ pc++;
+ c = ~nz;
+ nz &= 0xFF;
+ goto loop;
+
+// Logical
+
+#define ARITH_ADDR_MODES( op )\
+ case op - 0x04: /* (ind,x) */\
+ data = uint8_t (data + x);\
+ case op + 0x0D: /* (ind) */\
+ data = 0x100 * READ_LOW( uint8_t (data + 1) ) + READ_LOW( data );\
+ goto ptr##op;\
+ case op + 0x0C:{/* (ind),y */\
+ fuint16 temp = READ_LOW( data ) + y;\
+ PAGE_CROSS_PENALTY( temp );\
+ data = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
+ goto ptr##op;\
+ }\
+ case op + 0x10: /* zp,X */\
+ data = uint8_t (data + x);\
+ case op + 0x00: /* zp */\
+ data = READ_LOW( data );\
+ goto imm##op;\
+ case op + 0x14: /* abs,Y */\
+ data += y;\
+ goto ind##op;\
+ case op + 0x18: /* abs,X */\
+ data += x;\
+ ind##op:\
+ PAGE_CROSS_PENALTY( data );\
+ case op + 0x08: /* abs */\
+ ADD_PAGE( data );\
+ ptr##op:\
+ FLUSH_TIME();\
+ data = READ( data );\
+ CACHE_TIME();\
+ case op + 0x04: /* imm */\
+ imm##op:
+
+ ARITH_ADDR_MODES( 0xC5 ) // CMP
+ nz = a - data;
+ pc++;
+ c = ~nz;
+ nz &= 0xFF;
+ goto loop;
+
+ ARITH_ADDR_MODES( 0x25 ) // AND
+ nz = (a &= data);
+ pc++;
+ goto loop;
+
+ ARITH_ADDR_MODES( 0x45 ) // EOR
+ nz = (a ^= data);
+ pc++;
+ goto loop;
+
+ ARITH_ADDR_MODES( 0x05 ) // ORA
+ nz = (a |= data);
+ pc++;
+ goto loop;
+
+// Add/subtract
+
+ ARITH_ADDR_MODES( 0xE5 ) // SBC
+ data ^= 0xFF;
+ goto adc_imm;
+
+ ARITH_ADDR_MODES( 0x65 ) // ADC
+ adc_imm: {
+ if ( status & st_d )
+ debug_printf( "Decimal mode not supported\n" );
+ fint16 carry = c >> 8 & 1;
+ fint16 ov = (a ^ 0x80) + carry + (int8_t) data; // sign-extend
+ status &= ~st_v;
+ status |= ov >> 2 & 0x40;
+ c = nz = a + data + carry;
+ pc++;
+ a = (uint8_t) nz;
+ goto loop;
+ }
+
+// Shift/rotate
+
+ case 0x4A: // LSR A
+ c = 0;
+ case 0x6A: // ROR A
+ nz = c >> 1 & 0x80;
+ c = a << 8;
+ nz |= a >> 1;
+ a = nz;
+ goto loop;
+
+ case 0x0A: // ASL A
+ nz = a << 1;
+ c = nz;
+ a = (uint8_t) nz;
+ goto loop;
+
+ case 0x2A: { // ROL A
+ nz = a << 1;
+ fint16 temp = c >> 8 & 1;
+ c = nz;
+ nz |= temp;
+ a = (uint8_t) nz;
+ goto loop;
+ }
+
+ case 0x5E: // LSR abs,X
+ data += x;
+ case 0x4E: // LSR abs
+ c = 0;
+ case 0x6E: // ROR abs
+ ror_abs: {
+ ADD_PAGE( data );
+ FLUSH_TIME();
+ int temp = READ( data );
+ nz = (c >> 1 & 0x80) | (temp >> 1);
+ c = temp << 8;
+ goto rotate_common;
+ }
+
+ case 0x3E: // ROL abs,X
+ data += x;
+ goto rol_abs;
+
+ case 0x1E: // ASL abs,X
+ data += x;
+ case 0x0E: // ASL abs
+ c = 0;
+ case 0x2E: // ROL abs
+ rol_abs:
+ ADD_PAGE( data );
+ nz = c >> 8 & 1;
+ FLUSH_TIME();
+ nz |= (c = READ( data ) << 1);
+ rotate_common:
+ pc++;
+ WRITE( data, (uint8_t) nz );
+ CACHE_TIME();
+ goto loop;
+
+ case 0x7E: // ROR abs,X
+ data += x;
+ goto ror_abs;
+
+ case 0x76: // ROR zp,x
+ data = uint8_t (data + x);
+ goto ror_zp;
+
+ case 0x56: // LSR zp,x
+ data = uint8_t (data + x);
+ case 0x46: // LSR zp
+ c = 0;
+ case 0x66: // ROR zp
+ ror_zp: {
+ int temp = READ_LOW( data );
+ nz = (c >> 1 & 0x80) | (temp >> 1);
+ c = temp << 8;
+ goto write_nz_zp;
+ }
+
+ case 0x36: // ROL zp,x
+ data = uint8_t (data + x);
+ goto rol_zp;
+
+ case 0x16: // ASL zp,x
+ data = uint8_t (data + x);
+ case 0x06: // ASL zp
+ c = 0;
+ case 0x26: // ROL zp
+ rol_zp:
+ nz = c >> 8 & 1;
+ nz |= (c = READ_LOW( data ) << 1);
+ goto write_nz_zp;
+
+// Increment/decrement
+
+#define INC_DEC_AXY( reg, n ) reg = uint8_t (nz = reg + n); goto loop;
+
+ case 0x1A: // INA
+ INC_DEC_AXY( a, +1 )
+
+ case 0xE8: // INX
+ INC_DEC_AXY( x, +1 )
+
+ case 0xC8: // INY
+ INC_DEC_AXY( y, +1 )
+
+ case 0x3A: // DEA
+ INC_DEC_AXY( a, -1 )
+
+ case 0xCA: // DEX
+ INC_DEC_AXY( x, -1 )
+
+ case 0x88: // DEY
+ INC_DEC_AXY( y, -1 )
+
+ case 0xF6: // INC zp,x
+ data = uint8_t (data + x);
+ case 0xE6: // INC zp
+ nz = 1;
+ goto add_nz_zp;
+
+ case 0xD6: // DEC zp,x
+ data = uint8_t (data + x);
+ case 0xC6: // DEC zp
+ nz = (unsigned) -1;
+ add_nz_zp:
+ nz += READ_LOW( data );
+ write_nz_zp:
+ pc++;
+ WRITE_LOW( data, nz );
+ goto loop;
+
+ case 0xFE: // INC abs,x
+ data = x + GET_ADDR();
+ goto inc_ptr;
+
+ case 0xEE: // INC abs
+ data = GET_ADDR();
+ inc_ptr:
+ nz = 1;
+ goto inc_common;
+
+ case 0xDE: // DEC abs,x
+ data = x + GET_ADDR();
+ goto dec_ptr;
+
+ case 0xCE: // DEC abs
+ data = GET_ADDR();
+ dec_ptr:
+ nz = (unsigned) -1;
+ inc_common:
+ FLUSH_TIME();
+ nz += READ( data );
+ pc += 2;
+ WRITE( data, (uint8_t) nz );
+ CACHE_TIME();
+ goto loop;
+
+// Transfer
+
+ case 0xA8: // TAY
+ y = a;
+ nz = a;
+ goto loop;
+
+ case 0x98: // TYA
+ a = y;
+ nz = y;
+ goto loop;
+
+ case 0xAA: // TAX
+ x = a;
+ nz = a;
+ goto loop;
+
+ case 0x8A: // TXA
+ a = x;
+ nz = x;
+ goto loop;
+
+ case 0x9A: // TXS
+ SET_SP( x ); // verified (no flag change)
+ goto loop;
+
+ case 0xBA: // TSX
+ x = nz = GET_SP();
+ goto loop;
+
+ #define SWAP_REGS( r1, r2 ) {\
+ fuint8 t = r1;\
+ r1 = r2;\
+ r2 = t;\
+ goto loop;\
+ }
+
+ case 0x02: // SXY
+ SWAP_REGS( x, y );
+
+ case 0x22: // SAX
+ SWAP_REGS( a, x );
+
+ case 0x42: // SAY
+ SWAP_REGS( a, y );
+
+ case 0x62: // CLA
+ a = 0;
+ goto loop;
+
+ case 0x82: // CLX
+ x = 0;
+ goto loop;
+
+ case 0xC2: // CLY
+ y = 0;
+ goto loop;
+
+// Stack
+
+ case 0x48: // PHA
+ PUSH( a );
+ goto loop;
+
+ case 0xDA: // PHX
+ PUSH( x );
+ goto loop;
+
+ case 0x5A: // PHY
+ PUSH( y );
+ goto loop;
+
+ case 0x40:{// RTI
+ fuint8 temp = READ_LOW( sp );
+ pc = READ_LOW( 0x100 | (sp - 0xFF) );
+ pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
+ sp = (sp - 0xFD) | 0x100;
+ data = status;
+ SET_STATUS( temp );
+ this->r.status = status; // update externally-visible I flag
+ if ( (data ^ status) & st_i )
+ {
+ hes_time_t new_time = end_time_;
+ if ( !(status & st_i) && new_time > irq_time_ )
+ new_time = irq_time_;
+ blargg_long delta = s.base - new_time;
+ s.base = new_time;
+ s_time += delta;
+ }
+ goto loop;
+ }
+
+ #define POP() READ_LOW( sp ); sp = (sp - 0xFF) | 0x100
+
+ case 0x68: // PLA
+ a = nz = POP();
+ goto loop;
+
+ case 0xFA: // PLX
+ x = nz = POP();
+ goto loop;
+
+ case 0x7A: // PLY
+ y = nz = POP();
+ goto loop;
+
+ case 0x28:{// PLP
+ fuint8 temp = POP();
+ fuint8 changed = status ^ temp;
+ SET_STATUS( temp );
+ if ( !(changed & st_i) )
+ goto loop; // I flag didn't change
+ if ( status & st_i )
+ goto handle_sei;
+ goto handle_cli;
+ }
+ #undef POP
+
+ case 0x08: { // PHP
+ fuint8 temp;
+ CALC_STATUS( temp );
+ PUSH( temp | st_b );
+ goto loop;
+ }
+
+// Flags
+
+ case 0x38: // SEC
+ c = (unsigned) ~0;
+ goto loop;
+
+ case 0x18: // CLC
+ c = 0;
+ goto loop;
+
+ case 0xB8: // CLV
+ status &= ~st_v;
+ goto loop;
+
+ case 0xD8: // CLD
+ status &= ~st_d;
+ goto loop;
+
+ case 0xF8: // SED
+ status |= st_d;
+ goto loop;
+
+ case 0x58: // CLI
+ if ( !(status & st_i) )
+ goto loop;
+ status &= ~st_i;
+ handle_cli: {
+ this->r.status = status; // update externally-visible I flag
+ blargg_long delta = s.base - irq_time_;
+ if ( delta <= 0 )
+ {
+ if ( TIME < irq_time_ )
+ goto loop;
+ goto delayed_cli;
+ }
+ s.base = irq_time_;
+ s_time += delta;
+ if ( s_time < 0 )
+ goto loop;
+
+ if ( delta >= s_time + 1 )
+ {
+ // delayed irq until after next instruction
+ s.base += s_time + 1;
+ s_time = -1;
+ irq_time_ = s.base; // TODO: remove, as only to satisfy debug check in loop
+ goto loop;
+ }
+ delayed_cli:
+ debug_printf( "Delayed CLI not supported\n" ); // TODO: implement
+ goto loop;
+ }
+
+ case 0x78: // SEI
+ if ( status & st_i )
+ goto loop;
+ status |= st_i;
+ handle_sei: {
+ this->r.status = status; // update externally-visible I flag
+ blargg_long delta = s.base - end_time_;
+ s.base = end_time_;
+ s_time += delta;
+ if ( s_time < 0 )
+ goto loop;
+ debug_printf( "Delayed SEI not supported\n" ); // TODO: implement
+ goto loop;
+ }
+
+// Special
+
+ case 0x53:{// TAM
+ fuint8 const bits = data; // avoid using data across function call
+ pc++;
+ for ( int i = 0; i < 8; i++ )
+ if ( bits & (1 << i) )
+ set_mmr( i, a );
+ goto loop;
+ }
+
+ case 0x43:{// TMA
+ pc++;
+ byte const* in = mmr;
+ do
+ {
+ if ( data & 1 )
+ a = *in;
+ in++;
+ }
+ while ( (data >>= 1) != 0 );
+ goto loop;
+ }
+
+ case 0x03: // ST0
+ case 0x13: // ST1
+ case 0x23:{// ST2
+ fuint16 addr = opcode >> 4;
+ if ( addr )
+ addr++;
+ pc++;
+ FLUSH_TIME();
+ CPU_WRITE_VDP( this, addr, data, TIME );
+ CACHE_TIME();
+ goto loop;
+ }
+
+ case 0xEA: // NOP
+ goto loop;
+
+ case 0x54: // CSL
+ debug_printf( "CSL not supported\n" );
+ illegal_encountered = true;
+ goto loop;
+
+ case 0xD4: // CSH
+ goto loop;
+
+ case 0xF4: { // SET
+ //fuint16 operand = GET_MSB();
+ debug_printf( "SET not handled\n" );
+ //switch ( data )
+ //{
+ //}
+ illegal_encountered = true;
+ goto loop;
+ }
+
+// Block transfer
+
+ {
+ fuint16 in_alt;
+ fint16 in_inc;
+ fuint16 out_alt;
+ fint16 out_inc;
+
+ case 0xE3: // TIA
+ in_alt = 0;
+ goto bxfer_alt;
+
+ case 0xF3: // TAI
+ in_alt = 1;
+ bxfer_alt:
+ in_inc = in_alt ^ 1;
+ out_alt = in_inc;
+ out_inc = in_alt;
+ goto bxfer;
+
+ case 0xD3: // TIN
+ in_inc = 1;
+ out_inc = 0;
+ goto bxfer_no_alt;
+
+ case 0xC3: // TDD
+ in_inc = -1;
+ out_inc = -1;
+ goto bxfer_no_alt;
+
+ case 0x73: // TII
+ in_inc = 1;
+ out_inc = 1;
+ bxfer_no_alt:
+ in_alt = 0;
+ out_alt = 0;
+ bxfer:
+ fuint16 in = GET_LE16( instr + 0 );
+ fuint16 out = GET_LE16( instr + 2 );
+ int count = GET_LE16( instr + 4 );
+ if ( !count )
+ count = 0x10000;
+ pc += 6;
+ WRITE_LOW( 0x100 | (sp - 1), y );
+ WRITE_LOW( 0x100 | (sp - 2), a );
+ WRITE_LOW( 0x100 | (sp - 3), x );
+ FLUSH_TIME();
+ do
+ {
+ // TODO: reads from $0800-$1400 in I/O page return 0 and don't access I/O
+ fuint8 t = READ( in );
+ in += in_inc;
+ in &= 0xFFFF;
+ s.time += 6;
+ if ( in_alt )
+ in_inc = -in_inc;
+ WRITE( out, t );
+ out += out_inc;
+ out &= 0xFFFF;
+ if ( out_alt )
+ out_inc = -out_inc;
+ }
+ while ( --count );
+ CACHE_TIME();
+ goto loop;
+ }
+
+// Illegal
+
+ default:
+ assert( (unsigned) opcode <= 0xFF );
+ debug_printf( "Illegal opcode $%02X at $%04X\n", (int) opcode, (int) pc - 1 );
+ illegal_encountered = true;
+ goto loop;
+ }
+ assert( false );
+
+ int result_;
+handle_brk:
+ pc++;
+ result_ = 6;
+
+interrupt:
+ {
+ s_time += 7;
+
+ WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
+ WRITE_LOW( 0x100 | (sp - 2), pc );
+ pc = GET_LE16( &READ_PROG( 0xFFF0 ) + result_ );
+
+ sp = (sp - 3) | 0x100;
+ fuint8 temp;
+ CALC_STATUS( temp );
+ if ( result_ == 6 )
+ temp |= st_b;
+ WRITE_LOW( sp, temp );
+
+ status &= ~st_d;
+ status |= st_i;
+ this->r.status = status; // update externally-visible I flag
+
+ blargg_long delta = s.base - end_time_;
+ s.base = end_time_;
+ s_time += delta;
+ goto loop;
+ }
+
+idle_done:
+ s_time = 0;
+out_of_time:
+ pc--;
+ FLUSH_TIME();
+ CPU_DONE( this, TIME, result_ );
+ CACHE_TIME();
+ if ( result_ > 0 )
+ goto interrupt;
+ if ( s_time < 0 )
+ goto loop;
+
+ s.time = s_time;
+
+ r.pc = pc;
+ r.sp = GET_SP();
+ r.a = a;
+ r.x = x;
+ r.y = y;
+
+ {
+ fuint8 temp;
+ CALC_STATUS( temp );
+ r.status = temp;
+ }
+
+ this->state_ = s;
+ this->state = &this->state_;
+
+ return illegal_encountered;
+}
+
diff --git a/src/console/Hes_Cpu.cxx b/src/console/Hes_Cpu.cxx
deleted file mode 100644
index bc0965ccfae8..000000000000
--- a/src/console/Hes_Cpu.cxx
+++ /dev/null
@@ -1,1301 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Hes_Cpu.h"
-
-#include "blargg_endian.h"
-
-//#include "hes_cpu_log.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-// TODO: support T flag, including clearing it at appropriate times?
-
-// all zero-page should really use whatever is at page 1, but that would
-// reduce efficiency quite a bit
-int const ram_addr = 0x2000;
-
-#define FLUSH_TIME() (void) (s.time = s_time)
-#define CACHE_TIME() (void) (s_time = s.time)
-
-#include "hes_cpu_io.h"
-
-#include "blargg_source.h"
-
-#if BLARGG_NONPORTABLE
- #define PAGE_OFFSET( addr ) (addr)
-#else
- #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
-#endif
-
-// status flags
-int const st_n = 0x80;
-int const st_v = 0x40;
-int const st_t = 0x20;
-int const st_b = 0x10;
-int const st_d = 0x08;
-int const st_i = 0x04;
-int const st_z = 0x02;
-int const st_c = 0x01;
-
-void Hes_Cpu::reset()
-{
- check( state == &state_ );
- state = &state_;
-
- state_.time = 0;
- state_.base = 0;
- irq_time_ = future_hes_time;
- end_time_ = future_hes_time;
-
- r.status = st_i;
- r.sp = 0;
- r.pc = 0;
- r.a = 0;
- r.x = 0;
- r.y = 0;
-}
-
-void Hes_Cpu::set_mmr( int reg, int bank )
-{
- assert( (unsigned) reg <= page_count ); // allow page past end to be set
- assert( (unsigned) bank < 0x100 );
- mmr [reg] = bank;
- uint8_t const* code = CPU_SET_MMR( this, reg, bank );
- state->code_map [reg] = code - PAGE_OFFSET( reg << page_shift );
-}
-
-#define TIME (s_time + s.base)
-
-#define READ( addr ) CPU_READ( this, (addr), TIME )
-#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), TIME );}
-#define READ_LOW( addr ) (ram [int (addr)])
-#define WRITE_LOW( addr, data ) (void) (READ_LOW( addr ) = (data))
-#define READ_PROG( addr ) (s.code_map [(addr) >> page_shift] [PAGE_OFFSET( addr )])
-
-#define SET_SP( v ) (sp = ((v) + 1) | 0x100)
-#define GET_SP() ((sp - 1) & 0xFF)
-#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-typedef blargg_long fint32;
-
-bool Hes_Cpu::run( hes_time_t end_time )
-{
- bool illegal_encountered = false;
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- // even on x86, using s.time in place of s_time was slower
- fint16 s_time = s.time;
-
- // registers
- fuint16 pc = r.pc;
- fuint8 a = r.a;
- fuint8 x = r.x;
- fuint8 y = r.y;
- fuint16 sp;
- SET_SP( r.sp );
-
- #define IS_NEG (nz & 0x8080)
-
- #define CALC_STATUS( out ) do {\
- out = status & (st_v | st_d | st_i);\
- out |= ((nz >> 8) | nz) & st_n;\
- out |= c >> 8 & st_c;\
- if ( !(nz & 0xFF) ) out |= st_z;\
- } while ( 0 )
-
- #define SET_STATUS( in ) do {\
- status = in & (st_v | st_d | st_i);\
- nz = in << 8;\
- c = nz;\
- nz |= ~in & st_z;\
- } while ( 0 )
-
- fuint8 status;
- fuint16 c; // carry set if (c & 0x100) != 0
- fuint16 nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
- {
- fuint8 temp = r.status;
- SET_STATUS( temp );
- }
-
- goto loop;
-branch_not_taken:
- s_time -= 2;
-loop:
-
- #ifndef NDEBUG
- {
- hes_time_t correct = end_time_;
- if ( !(status & st_i) && correct > irq_time_ )
- correct = irq_time_;
- check( s.base == correct );
- /*
- static long count;
- if ( count == 1844 ) Debugger();
- if ( s.base != correct ) debug_printf( "%ld\n", count );
- count++;
- */
- }
- #endif
-
- check( (unsigned) GET_SP() < 0x100 );
- check( (unsigned) a < 0x100 );
- check( (unsigned) x < 0x100 );
-
- uint8_t const* instr = s.code_map [pc >> page_shift];
- fuint8 opcode;
-
- // TODO: eliminate this special case
- #if BLARGG_NONPORTABLE
- opcode = instr [pc];
- pc++;
- instr += pc;
- #else
- instr += PAGE_OFFSET( pc );
- opcode = *instr++;
- pc++;
- #endif
-
- // TODO: each reference lists slightly different timing values, ugh
- static uint8_t const clock_table [256] =
- {// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 1,7,3, 4,6,4,6,7,3,2,2,2,7,5,7,6,// 0
- 4,7,7, 4,6,4,6,7,2,5,2,2,7,5,7,6,// 1
- 7,7,3, 4,4,4,6,7,4,2,2,2,5,5,7,6,// 2
- 4,7,7, 2,4,4,6,7,2,5,2,2,5,5,7,6,// 3
- 7,7,3, 4,8,4,6,7,3,2,2,2,4,5,7,6,// 4
- 4,7,7, 5,2,4,6,7,2,5,3,2,2,5,7,6,// 5
- 7,7,2, 2,4,4,6,7,4,2,2,2,7,5,7,6,// 6
- 4,7,7,17,4,4,6,7,2,5,4,2,7,5,7,6,// 7
- 4,7,2, 7,4,4,4,7,2,2,2,2,5,5,5,6,// 8
- 4,7,7, 8,4,4,4,7,2,5,2,2,5,5,5,6,// 9
- 2,7,2, 7,4,4,4,7,2,2,2,2,5,5,5,6,// A
- 4,7,7, 8,4,4,4,7,2,5,2,2,5,5,5,6,// B
- 2,7,2,17,4,4,6,7,2,2,2,2,5,5,7,6,// C
- 4,7,7,17,2,4,6,7,2,5,3,2,2,5,7,6,// D
- 2,7,2,17,4,4,6,7,2,2,2,2,5,5,7,6,// E
- 4,7,7,17,2,4,6,7,2,5,4,2,2,5,7,6 // F
- }; // 0x00 was 8
-
- fuint16 data;
- data = clock_table [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = *instr;
-
- #ifdef HES_CPU_LOG_H
- log_cpu( "new", pc - 1, opcode, instr [0], instr [1], instr [2],
- instr [3], instr [4], instr [5] );
- //log_opcode( opcode );
- #endif
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-
-// Macros
-
-#define GET_MSB() (instr [1])
-#define ADD_PAGE( out ) (pc++, out = data + 0x100 * GET_MSB());
-#define GET_ADDR() GET_LE16( instr )
-
-// TODO: is the penalty really always added? the original 6502 was much better
-//#define PAGE_CROSS_PENALTY( lsb ) (void) (s_time += (lsb) >> 8)
-#define PAGE_CROSS_PENALTY( lsb )
-
-// Branch
-
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define BRANCH( cond )\
-{\
- fint16 offset = (int8_t) data;\
- pc++;\
- if ( !(cond) ) goto branch_not_taken;\
- pc = uint16_t (pc + offset);\
- goto loop;\
-}
-
- case 0xF0: // BEQ
- BRANCH( !((uint8_t) nz) );
-
- case 0xD0: // BNE
- BRANCH( (uint8_t) nz );
-
- case 0x10: // BPL
- BRANCH( !IS_NEG );
-
- case 0x90: // BCC
- BRANCH( !(c & 0x100) )
-
- case 0x30: // BMI
- BRANCH( IS_NEG )
-
- case 0x50: // BVC
- BRANCH( !(status & st_v) )
-
- case 0x70: // BVS
- BRANCH( status & st_v )
-
- case 0xB0: // BCS
- BRANCH( c & 0x100 )
-
- case 0x80: // BRA
- branch_taken:
- BRANCH( true );
-
- case 0xFF:
- if ( pc == idle_addr + 1 )
- goto idle_done;
- case 0x0F: // BBRn
- case 0x1F:
- case 0x2F:
- case 0x3F:
- case 0x4F:
- case 0x5F:
- case 0x6F:
- case 0x7F:
- case 0x8F: // BBSn
- case 0x9F:
- case 0xAF:
- case 0xBF:
- case 0xCF:
- case 0xDF:
- case 0xEF: {
- fuint16 t = 0x101 * READ_LOW( data );
- t ^= 0xFF;
- pc++;
- data = GET_MSB();
- BRANCH( t & (1 << (opcode >> 4)) )
- }
-
- case 0x4C: // JMP abs
- pc = GET_ADDR();
- goto loop;
-
- case 0x7C: // JMP (ind+X)
- data += x;
- case 0x6C:{// JMP (ind)
- data += 0x100 * GET_MSB();
- pc = GET_LE16( &READ_PROG( data ) );
- goto loop;
- }
-
-// Subroutine
-
- case 0x44: // BSR
- WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
- sp = (sp - 2) | 0x100;
- WRITE_LOW( sp, pc );
- goto branch_taken;
-
- case 0x20: { // JSR
- fuint16 temp = pc + 1;
- pc = GET_ADDR();
- WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
- sp = (sp - 2) | 0x100;
- WRITE_LOW( sp, temp );
- goto loop;
- }
-
- case 0x60: // RTS
- pc = 0x100 * READ_LOW( 0x100 | (sp - 0xFF) );
- pc += 1 + READ_LOW( sp );
- sp = (sp - 0xFE) | 0x100;
- goto loop;
-
- case 0x00: // BRK
- goto handle_brk;
-
-// Common
-
- case 0xBD:{// LDA abs,X
- PAGE_CROSS_PENALTY( data + x );
- fuint16 addr = GET_ADDR() + x;
- pc += 2;
- CPU_READ_FAST( this, addr, TIME, nz );
- a = nz;
- goto loop;
- }
-
- case 0x9D:{// STA abs,X
- fuint16 addr = GET_ADDR() + x;
- pc += 2;
- CPU_WRITE_FAST( this, addr, a, TIME );
- goto loop;
- }
-
- case 0x95: // STA zp,x
- data = uint8_t (data + x);
- case 0x85: // STA zp
- pc++;
- WRITE_LOW( data, a );
- goto loop;
-
- case 0xAE:{// LDX abs
- fuint16 addr = GET_ADDR();
- pc += 2;
- CPU_READ_FAST( this, addr, TIME, nz );
- x = nz;
- goto loop;
- }
-
- case 0xA5: // LDA zp
- a = nz = READ_LOW( data );
- pc++;
- goto loop;
-
-// Load/store
-
- {
- fuint16 addr;
- case 0x91: // STA (ind),Y
- addr = 0x100 * READ_LOW( uint8_t (data + 1) );
- addr += READ_LOW( data ) + y;
- pc++;
- goto sta_ptr;
-
- case 0x81: // STA (ind,X)
- data = uint8_t (data + x);
- case 0x92: // STA (ind)
- addr = 0x100 * READ_LOW( uint8_t (data + 1) );
- addr += READ_LOW( data );
- pc++;
- goto sta_ptr;
-
- case 0x99: // STA abs,Y
- data += y;
- case 0x8D: // STA abs
- addr = data + 0x100 * GET_MSB();
- pc += 2;
- sta_ptr:
- CPU_WRITE_FAST( this, addr, a, TIME );
- goto loop;
- }
-
- {
- fuint16 addr;
- case 0xA1: // LDA (ind,X)
- data = uint8_t (data + x);
- case 0xB2: // LDA (ind)
- addr = 0x100 * READ_LOW( uint8_t (data + 1) );
- addr += READ_LOW( data );
- pc++;
- goto a_nz_read_addr;
-
- case 0xB1:// LDA (ind),Y
- addr = READ_LOW( data ) + y;
- PAGE_CROSS_PENALTY( addr );
- addr += 0x100 * READ_LOW( (uint8_t) (data + 1) );
- pc++;
- goto a_nz_read_addr;
-
- case 0xB9: // LDA abs,Y
- data += y;
- PAGE_CROSS_PENALTY( data );
- case 0xAD: // LDA abs
- addr = data + 0x100 * GET_MSB();
- pc += 2;
- a_nz_read_addr:
- CPU_READ_FAST( this, addr, TIME, nz );
- a = nz;
- goto loop;
- }
-
- case 0xBE:{// LDX abs,y
- PAGE_CROSS_PENALTY( data + y );
- fuint16 addr = GET_ADDR() + y;
- pc += 2;
- FLUSH_TIME();
- x = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- case 0xB5: // LDA zp,x
- a = nz = READ_LOW( uint8_t (data + x) );
- pc++;
- goto loop;
-
- case 0xA9: // LDA #imm
- pc++;
- a = data;
- nz = data;
- goto loop;
-
-// Bit operations
-
- case 0x3C: // BIT abs,x
- data += x;
- case 0x2C:{// BIT abs
- fuint16 addr;
- ADD_PAGE( addr );
- FLUSH_TIME();
- nz = READ( addr );
- CACHE_TIME();
- goto bit_common;
- }
- case 0x34: // BIT zp,x
- data = uint8_t (data + x);
- case 0x24: // BIT zp
- data = READ_LOW( data );
- case 0x89: // BIT imm
- nz = data;
- bit_common:
- pc++;
- status &= ~st_v;
- status |= nz & st_v;
- if ( nz & a )
- goto loop; // Z should be clear, and nz must be non-zero if nz & a is
- nz <<= 8; // set Z flag without affecting N flag
- goto loop;
-
- {
- fuint16 addr;
-
- case 0xB3: // TST abs,x
- addr = GET_MSB() + x;
- goto tst_abs;
-
- case 0x93: // TST abs
- addr = GET_MSB();
- tst_abs:
- addr += 0x100 * instr [2];
- pc++;
- FLUSH_TIME();
- nz = READ( addr );
- CACHE_TIME();
- goto tst_common;
- }
-
- case 0xA3: // TST zp,x
- nz = READ_LOW( uint8_t (GET_MSB() + x) );
- goto tst_common;
-
- case 0x83: // TST zp
- nz = READ_LOW( GET_MSB() );
- tst_common:
- pc += 2;
- status &= ~st_v;
- status |= nz & st_v;
- if ( nz & data )
- goto loop; // Z should be clear, and nz must be non-zero if nz & data is
- nz <<= 8; // set Z flag without affecting N flag
- goto loop;
-
- {
- fuint16 addr;
- case 0x0C: // TSB abs
- case 0x1C: // TRB abs
- addr = GET_ADDR();
- pc++;
- goto txb_addr;
-
- // TODO: everyone lists different behaviors for the status flags, ugh
- case 0x04: // TSB zp
- case 0x14: // TRB zp
- addr = data + ram_addr;
- txb_addr:
- FLUSH_TIME();
- nz = a | READ( addr );
- if ( opcode & 0x10 )
- nz ^= a; // bits from a will already be set, so this clears them
- status &= ~st_v;
- status |= nz & st_v;
- pc++;
- WRITE( addr, nz );
- CACHE_TIME();
- goto loop;
- }
-
- case 0x07: // RMBn
- case 0x17:
- case 0x27:
- case 0x37:
- case 0x47:
- case 0x57:
- case 0x67:
- case 0x77:
- pc++;
- READ_LOW( data ) &= ~(1 << (opcode >> 4));
- goto loop;
-
- case 0x87: // SMBn
- case 0x97:
- case 0xA7:
- case 0xB7:
- case 0xC7:
- case 0xD7:
- case 0xE7:
- case 0xF7:
- pc++;
- READ_LOW( data ) |= 1 << ((opcode >> 4) - 8);
- goto loop;
-
-// Load/store
-
- case 0x9E: // STZ abs,x
- data += x;
- case 0x9C: // STZ abs
- ADD_PAGE( data );
- pc++;
- FLUSH_TIME();
- WRITE( data, 0 );
- CACHE_TIME();
- goto loop;
-
- case 0x74: // STZ zp,x
- data = uint8_t (data + x);
- case 0x64: // STZ zp
- pc++;
- WRITE_LOW( data, 0 );
- goto loop;
-
- case 0x94: // STY zp,x
- data = uint8_t (data + x);
- case 0x84: // STY zp
- pc++;
- WRITE_LOW( data, y );
- goto loop;
-
- case 0x96: // STX zp,y
- data = uint8_t (data + y);
- case 0x86: // STX zp
- pc++;
- WRITE_LOW( data, x );
- goto loop;
-
- case 0xB6: // LDX zp,y
- data = uint8_t (data + y);
- case 0xA6: // LDX zp
- data = READ_LOW( data );
- case 0xA2: // LDX #imm
- pc++;
- x = data;
- nz = data;
- goto loop;
-
- case 0xB4: // LDY zp,x
- data = uint8_t (data + x);
- case 0xA4: // LDY zp
- data = READ_LOW( data );
- case 0xA0: // LDY #imm
- pc++;
- y = data;
- nz = data;
- goto loop;
-
- case 0xBC: // LDY abs,X
- data += x;
- PAGE_CROSS_PENALTY( data );
- case 0xAC:{// LDY abs
- fuint16 addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- y = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- {
- fuint8 temp;
- case 0x8C: // STY abs
- temp = y;
- goto store_abs;
-
- case 0x8E: // STX abs
- temp = x;
- store_abs:
- fuint16 addr = GET_ADDR();
- pc += 2;
- FLUSH_TIME();
- WRITE( addr, temp );
- CACHE_TIME();
- goto loop;
- }
-
-// Compare
-
- case 0xEC:{// CPX abs
- fuint16 addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpx_data;
- }
-
- case 0xE4: // CPX zp
- data = READ_LOW( data );
- case 0xE0: // CPX #imm
- cpx_data:
- nz = x - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0xCC:{// CPY abs
- fuint16 addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpy_data;
- }
-
- case 0xC4: // CPY zp
- data = READ_LOW( data );
- case 0xC0: // CPY #imm
- cpy_data:
- nz = y - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
-// Logical
-
-#define ARITH_ADDR_MODES( op )\
- case op - 0x04: /* (ind,x) */\
- data = uint8_t (data + x);\
- case op + 0x0D: /* (ind) */\
- data = 0x100 * READ_LOW( uint8_t (data + 1) ) + READ_LOW( data );\
- goto ptr##op;\
- case op + 0x0C:{/* (ind),y */\
- fuint16 temp = READ_LOW( data ) + y;\
- PAGE_CROSS_PENALTY( temp );\
- data = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
- goto ptr##op;\
- }\
- case op + 0x10: /* zp,X */\
- data = uint8_t (data + x);\
- case op + 0x00: /* zp */\
- data = READ_LOW( data );\
- goto imm##op;\
- case op + 0x14: /* abs,Y */\
- data += y;\
- goto ind##op;\
- case op + 0x18: /* abs,X */\
- data += x;\
- ind##op:\
- PAGE_CROSS_PENALTY( data );\
- case op + 0x08: /* abs */\
- ADD_PAGE( data );\
- ptr##op:\
- FLUSH_TIME();\
- data = READ( data );\
- CACHE_TIME();\
- case op + 0x04: /* imm */\
- imm##op:
-
- ARITH_ADDR_MODES( 0xC5 ) // CMP
- nz = a - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- ARITH_ADDR_MODES( 0x25 ) // AND
- nz = (a &= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x45 ) // EOR
- nz = (a ^= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x05 ) // ORA
- nz = (a |= data);
- pc++;
- goto loop;
-
-// Add/subtract
-
- ARITH_ADDR_MODES( 0xE5 ) // SBC
- data ^= 0xFF;
- goto adc_imm;
-
- ARITH_ADDR_MODES( 0x65 ) // ADC
- adc_imm: {
- if ( status & st_d )
- debug_printf( "Decimal mode not supported\n" );
- fint16 carry = c >> 8 & 1;
- fint16 ov = (a ^ 0x80) + carry + (int8_t) data; // sign-extend
- status &= ~st_v;
- status |= ov >> 2 & 0x40;
- c = nz = a + data + carry;
- pc++;
- a = (uint8_t) nz;
- goto loop;
- }
-
-// Shift/rotate
-
- case 0x4A: // LSR A
- c = 0;
- case 0x6A: // ROR A
- nz = c >> 1 & 0x80;
- c = a << 8;
- nz |= a >> 1;
- a = nz;
- goto loop;
-
- case 0x0A: // ASL A
- nz = a << 1;
- c = nz;
- a = (uint8_t) nz;
- goto loop;
-
- case 0x2A: { // ROL A
- nz = a << 1;
- fint16 temp = c >> 8 & 1;
- c = nz;
- nz |= temp;
- a = (uint8_t) nz;
- goto loop;
- }
-
- case 0x5E: // LSR abs,X
- data += x;
- case 0x4E: // LSR abs
- c = 0;
- case 0x6E: // ROR abs
- ror_abs: {
- ADD_PAGE( data );
- FLUSH_TIME();
- int temp = READ( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto rotate_common;
- }
-
- case 0x3E: // ROL abs,X
- data += x;
- goto rol_abs;
-
- case 0x1E: // ASL abs,X
- data += x;
- case 0x0E: // ASL abs
- c = 0;
- case 0x2E: // ROL abs
- rol_abs:
- ADD_PAGE( data );
- nz = c >> 8 & 1;
- FLUSH_TIME();
- nz |= (c = READ( data ) << 1);
- rotate_common:
- pc++;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
- case 0x7E: // ROR abs,X
- data += x;
- goto ror_abs;
-
- case 0x76: // ROR zp,x
- data = uint8_t (data + x);
- goto ror_zp;
-
- case 0x56: // LSR zp,x
- data = uint8_t (data + x);
- case 0x46: // LSR zp
- c = 0;
- case 0x66: // ROR zp
- ror_zp: {
- int temp = READ_LOW( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto write_nz_zp;
- }
-
- case 0x36: // ROL zp,x
- data = uint8_t (data + x);
- goto rol_zp;
-
- case 0x16: // ASL zp,x
- data = uint8_t (data + x);
- case 0x06: // ASL zp
- c = 0;
- case 0x26: // ROL zp
- rol_zp:
- nz = c >> 8 & 1;
- nz |= (c = READ_LOW( data ) << 1);
- goto write_nz_zp;
-
-// Increment/decrement
-
-#define INC_DEC_AXY( reg, n ) reg = uint8_t (nz = reg + n); goto loop;
-
- case 0x1A: // INA
- INC_DEC_AXY( a, +1 )
-
- case 0xE8: // INX
- INC_DEC_AXY( x, +1 )
-
- case 0xC8: // INY
- INC_DEC_AXY( y, +1 )
-
- case 0x3A: // DEA
- INC_DEC_AXY( a, -1 )
-
- case 0xCA: // DEX
- INC_DEC_AXY( x, -1 )
-
- case 0x88: // DEY
- INC_DEC_AXY( y, -1 )
-
- case 0xF6: // INC zp,x
- data = uint8_t (data + x);
- case 0xE6: // INC zp
- nz = 1;
- goto add_nz_zp;
-
- case 0xD6: // DEC zp,x
- data = uint8_t (data + x);
- case 0xC6: // DEC zp
- nz = (unsigned) -1;
- add_nz_zp:
- nz += READ_LOW( data );
- write_nz_zp:
- pc++;
- WRITE_LOW( data, nz );
- goto loop;
-
- case 0xFE: // INC abs,x
- data = x + GET_ADDR();
- goto inc_ptr;
-
- case 0xEE: // INC abs
- data = GET_ADDR();
- inc_ptr:
- nz = 1;
- goto inc_common;
-
- case 0xDE: // DEC abs,x
- data = x + GET_ADDR();
- goto dec_ptr;
-
- case 0xCE: // DEC abs
- data = GET_ADDR();
- dec_ptr:
- nz = (unsigned) -1;
- inc_common:
- FLUSH_TIME();
- nz += READ( data );
- pc += 2;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
-// Transfer
-
- case 0xA8: // TAY
- y = a;
- nz = a;
- goto loop;
-
- case 0x98: // TYA
- a = y;
- nz = y;
- goto loop;
-
- case 0xAA: // TAX
- x = a;
- nz = a;
- goto loop;
-
- case 0x8A: // TXA
- a = x;
- nz = x;
- goto loop;
-
- case 0x9A: // TXS
- SET_SP( x ); // verified (no flag change)
- goto loop;
-
- case 0xBA: // TSX
- x = nz = GET_SP();
- goto loop;
-
- #define SWAP_REGS( r1, r2 ) {\
- fuint8 t = r1;\
- r1 = r2;\
- r2 = t;\
- goto loop;\
- }
-
- case 0x02: // SXY
- SWAP_REGS( x, y );
-
- case 0x22: // SAX
- SWAP_REGS( a, x );
-
- case 0x42: // SAY
- SWAP_REGS( a, y );
-
- case 0x62: // CLA
- a = 0;
- goto loop;
-
- case 0x82: // CLX
- x = 0;
- goto loop;
-
- case 0xC2: // CLY
- y = 0;
- goto loop;
-
-// Stack
-
- case 0x48: // PHA
- PUSH( a );
- goto loop;
-
- case 0xDA: // PHX
- PUSH( x );
- goto loop;
-
- case 0x5A: // PHY
- PUSH( y );
- goto loop;
-
- case 0x40:{// RTI
- fuint8 temp = READ_LOW( sp );
- pc = READ_LOW( 0x100 | (sp - 0xFF) );
- pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
- sp = (sp - 0xFD) | 0x100;
- data = status;
- SET_STATUS( temp );
- this->r.status = status; // update externally-visible I flag
- if ( (data ^ status) & st_i )
- {
- hes_time_t new_time = end_time_;
- if ( !(status & st_i) && new_time > irq_time_ )
- new_time = irq_time_;
- blargg_long delta = s.base - new_time;
- s.base = new_time;
- s_time += delta;
- }
- goto loop;
- }
-
- #define POP() READ_LOW( sp ); sp = (sp - 0xFF) | 0x100
-
- case 0x68: // PLA
- a = nz = POP();
- goto loop;
-
- case 0xFA: // PLX
- x = nz = POP();
- goto loop;
-
- case 0x7A: // PLY
- y = nz = POP();
- goto loop;
-
- case 0x28:{// PLP
- fuint8 temp = POP();
- fuint8 changed = status ^ temp;
- SET_STATUS( temp );
- if ( !(changed & st_i) )
- goto loop; // I flag didn't change
- if ( status & st_i )
- goto handle_sei;
- goto handle_cli;
- }
- #undef POP
-
- case 0x08: { // PHP
- fuint8 temp;
- CALC_STATUS( temp );
- PUSH( temp | st_b );
- goto loop;
- }
-
-// Flags
-
- case 0x38: // SEC
- c = (unsigned) ~0;
- goto loop;
-
- case 0x18: // CLC
- c = 0;
- goto loop;
-
- case 0xB8: // CLV
- status &= ~st_v;
- goto loop;
-
- case 0xD8: // CLD
- status &= ~st_d;
- goto loop;
-
- case 0xF8: // SED
- status |= st_d;
- goto loop;
-
- case 0x58: // CLI
- if ( !(status & st_i) )
- goto loop;
- status &= ~st_i;
- handle_cli: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - irq_time_;
- if ( delta <= 0 )
- {
- if ( TIME < irq_time_ )
- goto loop;
- goto delayed_cli;
- }
- s.base = irq_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
-
- if ( delta >= s_time + 1 )
- {
- // delayed irq until after next instruction
- s.base += s_time + 1;
- s_time = -1;
- irq_time_ = s.base; // TODO: remove, as only to satisfy debug check in loop
- goto loop;
- }
- delayed_cli:
- debug_printf( "Delayed CLI not supported\n" ); // TODO: implement
- goto loop;
- }
-
- case 0x78: // SEI
- if ( status & st_i )
- goto loop;
- status |= st_i;
- handle_sei: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
- debug_printf( "Delayed SEI not supported\n" ); // TODO: implement
- goto loop;
- }
-
-// Special
-
- case 0x53:{// TAM
- fuint8 const bits = data; // avoid using data across function call
- pc++;
- for ( int i = 0; i < 8; i++ )
- if ( bits & (1 << i) )
- set_mmr( i, a );
- goto loop;
- }
-
- case 0x43:{// TMA
- pc++;
- byte const* in = mmr;
- do
- {
- if ( data & 1 )
- a = *in;
- in++;
- }
- while ( (data >>= 1) != 0 );
- goto loop;
- }
-
- case 0x03: // ST0
- case 0x13: // ST1
- case 0x23:{// ST2
- fuint16 addr = opcode >> 4;
- if ( addr )
- addr++;
- pc++;
- FLUSH_TIME();
- CPU_WRITE_VDP( this, addr, data, TIME );
- CACHE_TIME();
- goto loop;
- }
-
- case 0xEA: // NOP
- goto loop;
-
- case 0x54: // CSL
- debug_printf( "CSL not supported\n" );
- illegal_encountered = true;
- goto loop;
-
- case 0xD4: // CSH
- goto loop;
-
- case 0xF4: { // SET
- //fuint16 operand = GET_MSB();
- debug_printf( "SET not handled\n" );
- //switch ( data )
- //{
- //}
- illegal_encountered = true;
- goto loop;
- }
-
-// Block transfer
-
- {
- fuint16 in_alt;
- fint16 in_inc;
- fuint16 out_alt;
- fint16 out_inc;
-
- case 0xE3: // TIA
- in_alt = 0;
- goto bxfer_alt;
-
- case 0xF3: // TAI
- in_alt = 1;
- bxfer_alt:
- in_inc = in_alt ^ 1;
- out_alt = in_inc;
- out_inc = in_alt;
- goto bxfer;
-
- case 0xD3: // TIN
- in_inc = 1;
- out_inc = 0;
- goto bxfer_no_alt;
-
- case 0xC3: // TDD
- in_inc = -1;
- out_inc = -1;
- goto bxfer_no_alt;
-
- case 0x73: // TII
- in_inc = 1;
- out_inc = 1;
- bxfer_no_alt:
- in_alt = 0;
- out_alt = 0;
- bxfer:
- fuint16 in = GET_LE16( instr + 0 );
- fuint16 out = GET_LE16( instr + 2 );
- int count = GET_LE16( instr + 4 );
- if ( !count )
- count = 0x10000;
- pc += 6;
- WRITE_LOW( 0x100 | (sp - 1), y );
- WRITE_LOW( 0x100 | (sp - 2), a );
- WRITE_LOW( 0x100 | (sp - 3), x );
- FLUSH_TIME();
- do
- {
- // TODO: reads from $0800-$1400 in I/O page return 0 and don't access I/O
- fuint8 t = READ( in );
- in += in_inc;
- in &= 0xFFFF;
- s.time += 6;
- if ( in_alt )
- in_inc = -in_inc;
- WRITE( out, t );
- out += out_inc;
- out &= 0xFFFF;
- if ( out_alt )
- out_inc = -out_inc;
- }
- while ( --count );
- CACHE_TIME();
- goto loop;
- }
-
-// Illegal
-
- default:
- assert( (unsigned) opcode <= 0xFF );
- debug_printf( "Illegal opcode $%02X at $%04X\n", (int) opcode, (int) pc - 1 );
- illegal_encountered = true;
- goto loop;
- }
- assert( false );
-
- int result_;
-handle_brk:
- pc++;
- result_ = 6;
-
-interrupt:
- {
- s_time += 7;
-
- WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
- WRITE_LOW( 0x100 | (sp - 2), pc );
- pc = GET_LE16( &READ_PROG( 0xFFF0 ) + result_ );
-
- sp = (sp - 3) | 0x100;
- fuint8 temp;
- CALC_STATUS( temp );
- if ( result_ == 6 )
- temp |= st_b;
- WRITE_LOW( sp, temp );
-
- status &= ~st_d;
- status |= st_i;
- this->r.status = status; // update externally-visible I flag
-
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- goto loop;
- }
-
-idle_done:
- s_time = 0;
-out_of_time:
- pc--;
- FLUSH_TIME();
- CPU_DONE( this, TIME, result_ );
- CACHE_TIME();
- if ( result_ > 0 )
- goto interrupt;
- if ( s_time < 0 )
- goto loop;
-
- s.time = s_time;
-
- r.pc = pc;
- r.sp = GET_SP();
- r.a = a;
- r.x = x;
- r.y = y;
-
- {
- fuint8 temp;
- CALC_STATUS( temp );
- r.status = temp;
- }
-
- this->state_ = s;
- this->state = &this->state_;
-
- return illegal_encountered;
-}
-
diff --git a/src/console/Hes_Emu.cc b/src/console/Hes_Emu.cc
new file mode 100644
index 000000000000..265d3d780c9f
--- /dev/null
+++ b/src/console/Hes_Emu.cc
@@ -0,0 +1,531 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Hes_Emu.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+int const timer_mask = 0x04;
+int const vdp_mask = 0x02;
+int const i_flag_mask = 0x04;
+int const unmapped = 0xFF;
+
+long const period_60hz = 262 * 455L; // scanlines * clocks per scanline
+
+Hes_Emu::Hes_Emu()
+{
+ timer.raw_load = 0;
+ set_type( gme_hes_type );
+
+ static const char* const names [Hes_Apu::osc_count] = {
+ "Wave 1", "Wave 2", "Wave 3", "Wave 4", "Multi 1", "Multi 2"
+ };
+ set_voice_names( names );
+
+ static int const types [Hes_Apu::osc_count] = {
+ wave_type | 0, wave_type | 1, wave_type | 2, wave_type | 3,
+ mixed_type | 0, mixed_type | 1
+ };
+ set_voice_types( types );
+ set_silence_lookahead( 6 );
+ set_gain( 1.11 );
+}
+
+Hes_Emu::~Hes_Emu() { }
+
+void Hes_Emu::unload()
+{
+ rom.clear();
+ Music_Emu::unload();
+}
+
+// Track info
+
+static byte const* copy_field( byte const* in, char* out )
+{
+ if ( in )
+ {
+ int len = 0x20;
+ if ( in [0x1F] && !in [0x2F] )
+ len = 0x30; // fields are sometimes 16 bytes longer (ugh)
+
+ // since text fields are where any data could be, detect non-text
+ // and fields with data after zero byte terminator
+
+ int i = 0;
+ for ( i = 0; i < len && in [i]; i++ )
+ if ( ((in [i] + 1) & 0xFF) < ' ' + 1 ) // also treat 0xFF as non-text
+ return 0; // non-ASCII found
+
+ for ( ; i < len; i++ )
+ if ( in [i] )
+ return 0; // data after terminator
+
+ Gme_File::copy_field_( out, (char const*) in, len );
+ in += len;
+ }
+ return in;
+}
+
+static void copy_hes_fields( byte const* in, track_info_t* out )
+{
+ if ( *in >= ' ' )
+ {
+ in = copy_field( in, out->game );
+ in = copy_field( in, out->author );
+ in = copy_field( in, out->copyright );
+ }
+}
+
+blargg_err_t Hes_Emu::track_info_( track_info_t* out, int ) const
+{
+ copy_hes_fields( rom.begin() + 0x20, out );
+ return 0;
+}
+
+static blargg_err_t check_hes_header( void const* header )
+{
+ if ( memcmp( header, "HESM", 4 ) )
+ return gme_wrong_file_type;
+ return 0;
+}
+
+struct Hes_File : Gme_Info_
+{
+ struct header_t {
+ char header [Hes_Emu::header_size];
+ char unused [0x20];
+ byte fields [0x30 * 3];
+ } h;
+
+ Hes_File() { set_type( gme_hes_type ); }
+
+ blargg_err_t load_( Data_Reader& in )
+ {
+ assert( offsetof (header_t,fields) == Hes_Emu::header_size + 0x20 );
+ blargg_err_t err = in.read( &h, sizeof h );
+ if ( err )
+ return (err == in.eof_error ? gme_wrong_file_type : err);
+ return check_hes_header( &h );
+ }
+
+ blargg_err_t track_info_( track_info_t* out, int ) const
+ {
+ copy_hes_fields( h.fields, out );
+ return 0;
+ }
+};
+
+static Music_Emu* new_hes_emu () { return BLARGG_NEW Hes_Emu ; }
+static Music_Emu* new_hes_file() { return BLARGG_NEW Hes_File; }
+
+static gme_type_t_ const gme_hes_type_ = { "PC Engine", 256, &new_hes_emu, &new_hes_file, "HES", 1 };
+gme_type_t const gme_hes_type = &gme_hes_type_;
+
+
+// Setup
+
+blargg_err_t Hes_Emu::load_( Data_Reader& in )
+{
+ assert( offsetof (header_t,unused [4]) == header_size );
+ RETURN_ERR( rom.load( in, header_size, &header_, unmapped ) );
+
+ RETURN_ERR( check_hes_header( header_.tag ) );
+
+ if ( header_.vers != 0 )
+ set_warning( "Unknown file version" );
+
+ if ( memcmp( header_.data_tag, "DATA", 4 ) )
+ set_warning( "Data header missing" );
+
+ if ( memcmp( header_.unused, "\0\0\0\0", 4 ) )
+ set_warning( "Unknown header data" );
+
+ // File spec supports multiple blocks, but I haven't found any, and
+ // many files have bad sizes in the only block, so it's simpler to
+ // just try to load the damn data as best as possible.
+
+ long addr = GET_LE32( header_.addr );
+ long size = GET_LE32( header_.size );
+ long const rom_max = 0x100000;
+ if ( addr & ~(rom_max - 1) )
+ {
+ set_warning( "Invalid address" );
+ addr &= rom_max - 1;
+ }
+ if ( (unsigned long) (addr + size) > (unsigned long) rom_max )
+ set_warning( "Invalid size" );
+
+ if ( size != rom.file_size() )
+ {
+ if ( size <= rom.file_size() - 4 && !memcmp( rom.begin() + size, "DATA", 4 ) )
+ set_warning( "Multiple DATA not supported" );
+ else if ( size < rom.file_size() )
+ set_warning( "Extra file data" );
+ else
+ set_warning( "Missing file data" );
+ }
+
+ rom.set_addr( addr );
+
+ set_voice_count( apu.osc_count );
+
+ apu.volume( gain() );
+
+ return setup_buffer( 7159091 );
+}
+
+void Hes_Emu::update_eq( blip_eq_t const& eq )
+{
+ apu.treble_eq( eq );
+}
+
+void Hes_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
+{
+ apu.osc_output( i, center, left, right );
+}
+
+// Emulation
+
+void Hes_Emu::recalc_timer_load()
+{
+ timer.load = timer.raw_load * timer_base + 1;
+}
+
+void Hes_Emu::set_tempo_( double t )
+{
+ play_period = hes_time_t (period_60hz / t);
+ timer_base = int (1024 / t);
+ recalc_timer_load();
+}
+
+blargg_err_t Hes_Emu::start_track_( int track )
+{
+ RETURN_ERR( Classic_Emu::start_track_( track ) );
+
+ memset( ram, 0, sizeof ram ); // some HES music relies on zero fill
+ memset( sgx, 0, sizeof sgx );
+
+ apu.reset();
+ cpu::reset();
+
+ for ( unsigned i = 0; i < sizeof header_.banks; i++ )
+ set_mmr( i, header_.banks [i] );
+ set_mmr( page_count, 0xFF ); // unmapped beyond end of address space
+
+ irq.disables = timer_mask | vdp_mask;
+ irq.timer = future_hes_time;
+ irq.vdp = future_hes_time;
+
+ timer.enabled = false;
+ timer.raw_load= 0x80;
+ timer.count = timer.load;
+ timer.fired = false;
+ timer.last_time = 0;
+
+ vdp.latch = 0;
+ vdp.control = 0;
+ vdp.next_vbl = 0;
+
+ ram [0x1FF] = (idle_addr - 1) >> 8;
+ ram [0x1FE] = (idle_addr - 1) & 0xFF;
+ r.sp = 0xFD;
+ r.pc = GET_LE16( header_.init_addr );
+ r.a = track;
+
+ recalc_timer_load();
+ last_frame_hook = 0;
+
+ return 0;
+}
+
+// Hardware
+
+void Hes_Emu::cpu_write_vdp( int addr, int data )
+{
+ switch ( addr )
+ {
+ case 0:
+ vdp.latch = data & 0x1F;
+ break;
+
+ case 2:
+ if ( vdp.latch == 5 )
+ {
+ if ( data & 0x04 )
+ set_warning( "Scanline interrupt unsupported" );
+ run_until( time() );
+ vdp.control = data;
+ irq_changed();
+ }
+ else
+ {
+ debug_printf( "VDP not supported: $%02X <- $%02X\n", vdp.latch, data );
+ }
+ break;
+
+ case 3:
+ debug_printf( "VDP MSB not supported: $%02X <- $%02X\n", vdp.latch, data );
+ break;
+ }
+}
+
+void Hes_Emu::cpu_write_( hes_addr_t addr, int data )
+{
+ if ( unsigned (addr - apu.start_addr) <= apu.end_addr - apu.start_addr )
+ {
+ GME_APU_HOOK( this, addr - apu.start_addr, data );
+ // avoid going way past end when a long block xfer is writing to I/O space
+ hes_time_t t = min( time(), end_time() + 8 );
+ apu.write_data( t, addr, data );
+ return;
+ }
+
+ hes_time_t time = this->time();
+ switch ( addr )
+ {
+ case 0x0000:
+ case 0x0002:
+ case 0x0003:
+ cpu_write_vdp( addr, data );
+ return;
+
+ case 0x0C00: {
+ run_until( time );
+ timer.raw_load = (data & 0x7F) + 1;
+ recalc_timer_load();
+ timer.count = timer.load;
+ break;
+ }
+
+ case 0x0C01:
+ data &= 1;
+ if ( timer.enabled == data )
+ return;
+ run_until( time );
+ timer.enabled = data;
+ if ( data )
+ timer.count = timer.load;
+ break;
+
+ case 0x1402:
+ run_until( time );
+ irq.disables = data;
+ if ( (data & 0xF8) && (data & 0xF8) != 0xF8 ) // flag questionable values
+ debug_printf( "Int mask: $%02X\n", data );
+ break;
+
+ case 0x1403:
+ run_until( time );
+ if ( timer.enabled )
+ timer.count = timer.load;
+ timer.fired = false;
+ break;
+
+#ifndef NDEBUG
+ case 0x1000: // I/O port
+ case 0x0402: // palette
+ case 0x0403:
+ case 0x0404:
+ case 0x0405:
+ return;
+
+ default:
+ debug_printf( "unmapped write $%04X <- $%02X\n", addr, data );
+ return;
+#endif
+ }
+
+ irq_changed();
+}
+
+int Hes_Emu::cpu_read_( hes_addr_t addr )
+{
+ hes_time_t time = this->time();
+ addr &= page_size - 1;
+ switch ( addr )
+ {
+ case 0x0000:
+ if ( irq.vdp > time )
+ return 0;
+ irq.vdp = future_hes_time;
+ run_until( time );
+ irq_changed();
+ return 0x20;
+
+ case 0x0002:
+ case 0x0003:
+ debug_printf( "VDP read not supported: %d\n", addr );
+ return 0;
+
+ case 0x0C01:
+ //return timer.enabled; // TODO: remove?
+ case 0x0C00:
+ run_until( time );
+ debug_printf( "Timer count read\n" );
+ return (unsigned) (timer.count - 1) / timer_base;
+
+ case 0x1402:
+ return irq.disables;
+
+ case 0x1403:
+ {
+ int status = 0;
+ if ( irq.timer <= time ) status |= timer_mask;
+ if ( irq.vdp <= time ) status |= vdp_mask;
+ return status;
+ }
+
+ #ifndef NDEBUG
+ case 0x1000: // I/O port
+ case 0x180C: // CD-ROM
+ case 0x180D:
+ break;
+
+ default:
+ debug_printf( "unmapped read $%04X\n", addr );
+ #endif
+ }
+
+ return unmapped;
+}
+
+// see hes_cpu_io.h for core read/write functions
+
+// Emulation
+
+void Hes_Emu::run_until( hes_time_t present )
+{
+ while ( vdp.next_vbl < present )
+ vdp.next_vbl += play_period;
+
+ hes_time_t elapsed = present - timer.last_time;
+ if ( elapsed > 0 )
+ {
+ if ( timer.enabled )
+ {
+ timer.count -= elapsed;
+ if ( timer.count <= 0 )
+ timer.count += timer.load;
+ }
+ timer.last_time = present;
+ }
+}
+
+void Hes_Emu::irq_changed()
+{
+ hes_time_t present = time();
+
+ if ( irq.timer > present )
+ {
+ irq.timer = future_hes_time;
+ if ( timer.enabled && !timer.fired )
+ irq.timer = present + timer.count;
+ }
+
+ if ( irq.vdp > present )
+ {
+ irq.vdp = future_hes_time;
+ if ( vdp.control & 0x08 )
+ irq.vdp = vdp.next_vbl;
+ }
+
+ hes_time_t time = future_hes_time;
+ if ( !(irq.disables & timer_mask) ) time = irq.timer;
+ if ( !(irq.disables & vdp_mask) ) time = min( time, irq.vdp );
+
+ set_irq_time( time );
+}
+
+int Hes_Emu::cpu_done()
+{
+ check( time() >= end_time() ||
+ (!(r.status & i_flag_mask) && time() >= irq_time()) );
+
+ if ( !(r.status & i_flag_mask) )
+ {
+ hes_time_t present = time();
+
+ if ( irq.timer <= present && !(irq.disables & timer_mask) )
+ {
+ timer.fired = true;
+ irq.timer = future_hes_time;
+ irq_changed(); // overkill, but not worth writing custom code
+ #if GME_FRAME_HOOK_DEFINED
+ {
+ unsigned const threshold = period_60hz / 30;
+ unsigned long elapsed = present - last_frame_hook;
+ if ( elapsed - period_60hz + threshold / 2 < threshold )
+ {
+ last_frame_hook = present;
+ GME_FRAME_HOOK( this );
+ }
+ }
+ #endif
+ return 0x0A;
+ }
+
+ if ( irq.vdp <= present && !(irq.disables & vdp_mask) )
+ {
+ // work around for bugs with music not acknowledging VDP
+ //run_until( present );
+ //irq.vdp = future_hes_time;
+ //irq_changed();
+ #if GME_FRAME_HOOK_DEFINED
+ last_frame_hook = present;
+ GME_FRAME_HOOK( this );
+ #endif
+ return 0x08;
+ }
+ }
+ return 0;
+}
+
+static void adjust_time( blargg_long& time, hes_time_t delta )
+{
+ if ( time < future_hes_time )
+ {
+ time -= delta;
+ if ( time < 0 )
+ time = 0;
+ }
+}
+
+blargg_err_t Hes_Emu::run_clocks( blip_time_t& duration_, int )
+{
+ blip_time_t const duration = duration_; // cache
+
+ if ( cpu::run( duration ) )
+ set_warning( "Emulation error (illegal instruction)" );
+
+ check( time() >= duration );
+ //check( time() - duration < 20 ); // Txx instruction could cause going way over
+
+ run_until( duration );
+
+ // end time frame
+ timer.last_time -= duration;
+ vdp.next_vbl -= duration;
+ #if GME_FRAME_HOOK_DEFINED
+ last_frame_hook -= duration;
+ #endif
+ cpu::end_frame( duration );
+ ::adjust_time( irq.timer, duration );
+ ::adjust_time( irq.vdp, duration );
+ apu.end_frame( duration );
+
+ return 0;
+}
diff --git a/src/console/Hes_Emu.cxx b/src/console/Hes_Emu.cxx
deleted file mode 100644
index 265d3d780c9f..000000000000
--- a/src/console/Hes_Emu.cxx
+++ /dev/null
@@ -1,531 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Hes_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const timer_mask = 0x04;
-int const vdp_mask = 0x02;
-int const i_flag_mask = 0x04;
-int const unmapped = 0xFF;
-
-long const period_60hz = 262 * 455L; // scanlines * clocks per scanline
-
-Hes_Emu::Hes_Emu()
-{
- timer.raw_load = 0;
- set_type( gme_hes_type );
-
- static const char* const names [Hes_Apu::osc_count] = {
- "Wave 1", "Wave 2", "Wave 3", "Wave 4", "Multi 1", "Multi 2"
- };
- set_voice_names( names );
-
- static int const types [Hes_Apu::osc_count] = {
- wave_type | 0, wave_type | 1, wave_type | 2, wave_type | 3,
- mixed_type | 0, mixed_type | 1
- };
- set_voice_types( types );
- set_silence_lookahead( 6 );
- set_gain( 1.11 );
-}
-
-Hes_Emu::~Hes_Emu() { }
-
-void Hes_Emu::unload()
-{
- rom.clear();
- Music_Emu::unload();
-}
-
-// Track info
-
-static byte const* copy_field( byte const* in, char* out )
-{
- if ( in )
- {
- int len = 0x20;
- if ( in [0x1F] && !in [0x2F] )
- len = 0x30; // fields are sometimes 16 bytes longer (ugh)
-
- // since text fields are where any data could be, detect non-text
- // and fields with data after zero byte terminator
-
- int i = 0;
- for ( i = 0; i < len && in [i]; i++ )
- if ( ((in [i] + 1) & 0xFF) < ' ' + 1 ) // also treat 0xFF as non-text
- return 0; // non-ASCII found
-
- for ( ; i < len; i++ )
- if ( in [i] )
- return 0; // data after terminator
-
- Gme_File::copy_field_( out, (char const*) in, len );
- in += len;
- }
- return in;
-}
-
-static void copy_hes_fields( byte const* in, track_info_t* out )
-{
- if ( *in >= ' ' )
- {
- in = copy_field( in, out->game );
- in = copy_field( in, out->author );
- in = copy_field( in, out->copyright );
- }
-}
-
-blargg_err_t Hes_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_hes_fields( rom.begin() + 0x20, out );
- return 0;
-}
-
-static blargg_err_t check_hes_header( void const* header )
-{
- if ( memcmp( header, "HESM", 4 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Hes_File : Gme_Info_
-{
- struct header_t {
- char header [Hes_Emu::header_size];
- char unused [0x20];
- byte fields [0x30 * 3];
- } h;
-
- Hes_File() { set_type( gme_hes_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- assert( offsetof (header_t,fields) == Hes_Emu::header_size + 0x20 );
- blargg_err_t err = in.read( &h, sizeof h );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
- return check_hes_header( &h );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_hes_fields( h.fields, out );
- return 0;
- }
-};
-
-static Music_Emu* new_hes_emu () { return BLARGG_NEW Hes_Emu ; }
-static Music_Emu* new_hes_file() { return BLARGG_NEW Hes_File; }
-
-static gme_type_t_ const gme_hes_type_ = { "PC Engine", 256, &new_hes_emu, &new_hes_file, "HES", 1 };
-gme_type_t const gme_hes_type = &gme_hes_type_;
-
-
-// Setup
-
-blargg_err_t Hes_Emu::load_( Data_Reader& in )
-{
- assert( offsetof (header_t,unused [4]) == header_size );
- RETURN_ERR( rom.load( in, header_size, &header_, unmapped ) );
-
- RETURN_ERR( check_hes_header( header_.tag ) );
-
- if ( header_.vers != 0 )
- set_warning( "Unknown file version" );
-
- if ( memcmp( header_.data_tag, "DATA", 4 ) )
- set_warning( "Data header missing" );
-
- if ( memcmp( header_.unused, "\0\0\0\0", 4 ) )
- set_warning( "Unknown header data" );
-
- // File spec supports multiple blocks, but I haven't found any, and
- // many files have bad sizes in the only block, so it's simpler to
- // just try to load the damn data as best as possible.
-
- long addr = GET_LE32( header_.addr );
- long size = GET_LE32( header_.size );
- long const rom_max = 0x100000;
- if ( addr & ~(rom_max - 1) )
- {
- set_warning( "Invalid address" );
- addr &= rom_max - 1;
- }
- if ( (unsigned long) (addr + size) > (unsigned long) rom_max )
- set_warning( "Invalid size" );
-
- if ( size != rom.file_size() )
- {
- if ( size <= rom.file_size() - 4 && !memcmp( rom.begin() + size, "DATA", 4 ) )
- set_warning( "Multiple DATA not supported" );
- else if ( size < rom.file_size() )
- set_warning( "Extra file data" );
- else
- set_warning( "Missing file data" );
- }
-
- rom.set_addr( addr );
-
- set_voice_count( apu.osc_count );
-
- apu.volume( gain() );
-
- return setup_buffer( 7159091 );
-}
-
-void Hes_Emu::update_eq( blip_eq_t const& eq )
-{
- apu.treble_eq( eq );
-}
-
-void Hes_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- apu.osc_output( i, center, left, right );
-}
-
-// Emulation
-
-void Hes_Emu::recalc_timer_load()
-{
- timer.load = timer.raw_load * timer_base + 1;
-}
-
-void Hes_Emu::set_tempo_( double t )
-{
- play_period = hes_time_t (period_60hz / t);
- timer_base = int (1024 / t);
- recalc_timer_load();
-}
-
-blargg_err_t Hes_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( ram, 0, sizeof ram ); // some HES music relies on zero fill
- memset( sgx, 0, sizeof sgx );
-
- apu.reset();
- cpu::reset();
-
- for ( unsigned i = 0; i < sizeof header_.banks; i++ )
- set_mmr( i, header_.banks [i] );
- set_mmr( page_count, 0xFF ); // unmapped beyond end of address space
-
- irq.disables = timer_mask | vdp_mask;
- irq.timer = future_hes_time;
- irq.vdp = future_hes_time;
-
- timer.enabled = false;
- timer.raw_load= 0x80;
- timer.count = timer.load;
- timer.fired = false;
- timer.last_time = 0;
-
- vdp.latch = 0;
- vdp.control = 0;
- vdp.next_vbl = 0;
-
- ram [0x1FF] = (idle_addr - 1) >> 8;
- ram [0x1FE] = (idle_addr - 1) & 0xFF;
- r.sp = 0xFD;
- r.pc = GET_LE16( header_.init_addr );
- r.a = track;
-
- recalc_timer_load();
- last_frame_hook = 0;
-
- return 0;
-}
-
-// Hardware
-
-void Hes_Emu::cpu_write_vdp( int addr, int data )
-{
- switch ( addr )
- {
- case 0:
- vdp.latch = data & 0x1F;
- break;
-
- case 2:
- if ( vdp.latch == 5 )
- {
- if ( data & 0x04 )
- set_warning( "Scanline interrupt unsupported" );
- run_until( time() );
- vdp.control = data;
- irq_changed();
- }
- else
- {
- debug_printf( "VDP not supported: $%02X <- $%02X\n", vdp.latch, data );
- }
- break;
-
- case 3:
- debug_printf( "VDP MSB not supported: $%02X <- $%02X\n", vdp.latch, data );
- break;
- }
-}
-
-void Hes_Emu::cpu_write_( hes_addr_t addr, int data )
-{
- if ( unsigned (addr - apu.start_addr) <= apu.end_addr - apu.start_addr )
- {
- GME_APU_HOOK( this, addr - apu.start_addr, data );
- // avoid going way past end when a long block xfer is writing to I/O space
- hes_time_t t = min( time(), end_time() + 8 );
- apu.write_data( t, addr, data );
- return;
- }
-
- hes_time_t time = this->time();
- switch ( addr )
- {
- case 0x0000:
- case 0x0002:
- case 0x0003:
- cpu_write_vdp( addr, data );
- return;
-
- case 0x0C00: {
- run_until( time );
- timer.raw_load = (data & 0x7F) + 1;
- recalc_timer_load();
- timer.count = timer.load;
- break;
- }
-
- case 0x0C01:
- data &= 1;
- if ( timer.enabled == data )
- return;
- run_until( time );
- timer.enabled = data;
- if ( data )
- timer.count = timer.load;
- break;
-
- case 0x1402:
- run_until( time );
- irq.disables = data;
- if ( (data & 0xF8) && (data & 0xF8) != 0xF8 ) // flag questionable values
- debug_printf( "Int mask: $%02X\n", data );
- break;
-
- case 0x1403:
- run_until( time );
- if ( timer.enabled )
- timer.count = timer.load;
- timer.fired = false;
- break;
-
-#ifndef NDEBUG
- case 0x1000: // I/O port
- case 0x0402: // palette
- case 0x0403:
- case 0x0404:
- case 0x0405:
- return;
-
- default:
- debug_printf( "unmapped write $%04X <- $%02X\n", addr, data );
- return;
-#endif
- }
-
- irq_changed();
-}
-
-int Hes_Emu::cpu_read_( hes_addr_t addr )
-{
- hes_time_t time = this->time();
- addr &= page_size - 1;
- switch ( addr )
- {
- case 0x0000:
- if ( irq.vdp > time )
- return 0;
- irq.vdp = future_hes_time;
- run_until( time );
- irq_changed();
- return 0x20;
-
- case 0x0002:
- case 0x0003:
- debug_printf( "VDP read not supported: %d\n", addr );
- return 0;
-
- case 0x0C01:
- //return timer.enabled; // TODO: remove?
- case 0x0C00:
- run_until( time );
- debug_printf( "Timer count read\n" );
- return (unsigned) (timer.count - 1) / timer_base;
-
- case 0x1402:
- return irq.disables;
-
- case 0x1403:
- {
- int status = 0;
- if ( irq.timer <= time ) status |= timer_mask;
- if ( irq.vdp <= time ) status |= vdp_mask;
- return status;
- }
-
- #ifndef NDEBUG
- case 0x1000: // I/O port
- case 0x180C: // CD-ROM
- case 0x180D:
- break;
-
- default:
- debug_printf( "unmapped read $%04X\n", addr );
- #endif
- }
-
- return unmapped;
-}
-
-// see hes_cpu_io.h for core read/write functions
-
-// Emulation
-
-void Hes_Emu::run_until( hes_time_t present )
-{
- while ( vdp.next_vbl < present )
- vdp.next_vbl += play_period;
-
- hes_time_t elapsed = present - timer.last_time;
- if ( elapsed > 0 )
- {
- if ( timer.enabled )
- {
- timer.count -= elapsed;
- if ( timer.count <= 0 )
- timer.count += timer.load;
- }
- timer.last_time = present;
- }
-}
-
-void Hes_Emu::irq_changed()
-{
- hes_time_t present = time();
-
- if ( irq.timer > present )
- {
- irq.timer = future_hes_time;
- if ( timer.enabled && !timer.fired )
- irq.timer = present + timer.count;
- }
-
- if ( irq.vdp > present )
- {
- irq.vdp = future_hes_time;
- if ( vdp.control & 0x08 )
- irq.vdp = vdp.next_vbl;
- }
-
- hes_time_t time = future_hes_time;
- if ( !(irq.disables & timer_mask) ) time = irq.timer;
- if ( !(irq.disables & vdp_mask) ) time = min( time, irq.vdp );
-
- set_irq_time( time );
-}
-
-int Hes_Emu::cpu_done()
-{
- check( time() >= end_time() ||
- (!(r.status & i_flag_mask) && time() >= irq_time()) );
-
- if ( !(r.status & i_flag_mask) )
- {
- hes_time_t present = time();
-
- if ( irq.timer <= present && !(irq.disables & timer_mask) )
- {
- timer.fired = true;
- irq.timer = future_hes_time;
- irq_changed(); // overkill, but not worth writing custom code
- #if GME_FRAME_HOOK_DEFINED
- {
- unsigned const threshold = period_60hz / 30;
- unsigned long elapsed = present - last_frame_hook;
- if ( elapsed - period_60hz + threshold / 2 < threshold )
- {
- last_frame_hook = present;
- GME_FRAME_HOOK( this );
- }
- }
- #endif
- return 0x0A;
- }
-
- if ( irq.vdp <= present && !(irq.disables & vdp_mask) )
- {
- // work around for bugs with music not acknowledging VDP
- //run_until( present );
- //irq.vdp = future_hes_time;
- //irq_changed();
- #if GME_FRAME_HOOK_DEFINED
- last_frame_hook = present;
- GME_FRAME_HOOK( this );
- #endif
- return 0x08;
- }
- }
- return 0;
-}
-
-static void adjust_time( blargg_long& time, hes_time_t delta )
-{
- if ( time < future_hes_time )
- {
- time -= delta;
- if ( time < 0 )
- time = 0;
- }
-}
-
-blargg_err_t Hes_Emu::run_clocks( blip_time_t& duration_, int )
-{
- blip_time_t const duration = duration_; // cache
-
- if ( cpu::run( duration ) )
- set_warning( "Emulation error (illegal instruction)" );
-
- check( time() >= duration );
- //check( time() - duration < 20 ); // Txx instruction could cause going way over
-
- run_until( duration );
-
- // end time frame
- timer.last_time -= duration;
- vdp.next_vbl -= duration;
- #if GME_FRAME_HOOK_DEFINED
- last_frame_hook -= duration;
- #endif
- cpu::end_frame( duration );
- ::adjust_time( irq.timer, duration );
- ::adjust_time( irq.vdp, duration );
- apu.end_frame( duration );
-
- return 0;
-}
diff --git a/src/console/Kss_Cpu.cc b/src/console/Kss_Cpu.cc
new file mode 100644
index 000000000000..0f397e1fc4bb
--- /dev/null
+++ b/src/console/Kss_Cpu.cc
@@ -0,0 +1,1704 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+/*
+Last validated with zexall 2006.11.14 2:19 PM
+* Doesn't implement the R register or immediate interrupt after EI.
+* Address wrap-around isn't completely correct, but is prevented from crashing emulator.
+*/
+
+#include "Kss_Cpu.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+
+//#include "z80_cpu_log.h"
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#define SYNC_TIME() (void) (s.time = s_time)
+#define RELOAD_TIME() (void) (s_time = s.time)
+
+// Callbacks to emulator
+
+#define CPU_OUT( cpu, addr, data, time )\
+ kss_cpu_out( this, time, addr, data )
+
+#define CPU_IN( cpu, addr, time )\
+ kss_cpu_in( this, time, addr )
+
+#define CPU_WRITE( cpu, addr, data, time )\
+ (SYNC_TIME(), kss_cpu_write( this, addr, data ))
+
+#include "blargg_source.h"
+
+// flags, named with hex value for clarity
+int const S80 = 0x80;
+int const Z40 = 0x40;
+int const F20 = 0x20;
+int const H10 = 0x10;
+int const F08 = 0x08;
+int const V04 = 0x04;
+int const P04 = 0x04;
+int const N02 = 0x02;
+int const C01 = 0x01;
+
+#define SZ28P( n ) szpc [n]
+#define SZ28PC( n ) szpc [n]
+#define SZ28C( n ) (szpc [n] & ~P04)
+#define SZ28( n ) SZ28C( n )
+
+#define SET_R( n ) (void) (r.r = n)
+#define GET_R() (r.r)
+
+Kss_Cpu::Kss_Cpu()
+{
+ state = &state_;
+
+ for ( int i = 0x100; --i >= 0; )
+ {
+ int even = 1;
+ for ( int p = i; p; p >>= 1 )
+ even ^= p;
+ int n = (i & (S80 | F20 | F08)) | ((even & 1) * P04);
+ szpc [i] = n;
+ szpc [i + 0x100] = n | C01;
+ }
+ szpc [0x000] |= Z40;
+ szpc [0x100] |= Z40;
+}
+
+inline void Kss_Cpu::set_page( int i, void* write, void const* read )
+{
+ blargg_long offset = KSS_CPU_PAGE_OFFSET( i * (blargg_long) page_size );
+ state->write [i] = (byte *) write - offset;
+ state->read [i] = (byte const*) read - offset;
+}
+
+void Kss_Cpu::reset( void* unmapped_write, void const* unmapped_read )
+{
+ check( state == &state_ );
+ state = &state_;
+ state_.time = 0;
+ state_.base = 0;
+ end_time_ = 0;
+
+ for ( int i = 0; i < page_count + 1; i++ )
+ set_page( i, unmapped_write, unmapped_read );
+
+ memset( &r, 0, sizeof r );
+}
+
+void Kss_Cpu::map_mem( unsigned addr, blargg_ulong size, void* write, void const* read )
+{
+ // address range must begin and end on page boundaries
+ require( addr % page_size == 0 );
+ require( size % page_size == 0 );
+
+ unsigned first_page = addr / page_size;
+ for ( unsigned i = size / page_size; i--; )
+ {
+ blargg_long offset = i * (blargg_long) page_size;
+ set_page( first_page + i, (byte*) write + offset, (byte const*) read + offset );
+ }
+}
+
+#define TIME (s_time + s.base)
+#define RW_MEM( addr, rw ) (s.rw [(addr) >> page_shift] [KSS_CPU_PAGE_OFFSET( addr )])
+#define READ_PROG( addr ) RW_MEM( addr, read )
+#define READ( addr ) READ_PROG( addr )
+//#define WRITE( addr, data ) (void) (RW_MEM( addr, write ) = data)
+#define WRITE( addr, data ) CPU_WRITE( this, addr, data, TIME )
+#define READ_WORD( addr ) GET_LE16( &READ( addr ) )
+#define WRITE_WORD( addr, data ) SET_LE16( &RW_MEM( addr, write ), data )
+#define IN( addr ) CPU_IN( this, addr, TIME )
+#define OUT( addr, data ) CPU_OUT( this, addr, data, TIME )
+
+#if BLARGG_BIG_ENDIAN
+ #define R8( n, offset ) ((r8_ - offset) [n])
+#elif BLARGG_LITTLE_ENDIAN
+ #define R8( n, offset ) ((r8_ - offset) [(n) ^ 1])
+#else
+ #error "Byte order of CPU must be known"
+#endif
+
+//#define R16( n, shift, offset ) (r16_ [((n) >> shift) - (offset >> shift)])
+
+// help compiler see that it can just adjust stack offset, saving an extra instruction
+#define R16( n, shift, offset )\
+ (*(uint16_t*) ((char*) r16_ - (offset >> (shift - 1)) + ((n) >> (shift - 1))))
+
+#define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e
+#define CASE6( a, b, c, d, e, f ) CASE5( a, b, c, d, e ): case 0x##f
+#define CASE7( a, b, c, d, e, f, g ) CASE6( a, b, c, d, e, f ): case 0x##g
+#define CASE8( a, b, c, d, e, f, g, h ) CASE7( a, b, c, d, e, f, g ): case 0x##h
+
+// high four bits are $ED time - 8, low four bits are $DD/$FD time - 8
+static byte const ed_dd_timing [0x100] = {
+//0 1 2 3 4 5 6 7 8 9 A B C D E F
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x06,0x0C,0x02,0x00,0x00,0x03,0x00,0x00,0x07,0x0C,0x02,0x00,0x00,0x03,0x00,
+0x00,0x00,0x00,0x00,0x0F,0x0F,0x0B,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
+0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
+0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,
+0x4B,0x4B,0x7B,0xCB,0x0B,0x6B,0x00,0x0B,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
+0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,
+0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x06,0x00,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+// even on x86, using short and unsigned char was slower
+typedef int fint16;
+typedef unsigned fuint16;
+typedef unsigned fuint8;
+
+bool Kss_Cpu::run( cpu_time_t end_time )
+{
+ set_end_time( end_time );
+ state_t s = this->state_;
+ this->state = &s;
+ bool warning = false;
+
+ typedef int8_t int8_t;
+
+ union {
+ regs_t rg;
+ pairs_t rp;
+ uint8_t r8_ [8]; // indexed
+ uint16_t r16_ [4];
+ };
+ rg = this->r.b;
+
+ cpu_time_t s_time = s.time;
+ fuint16 pc = r.pc;
+ fuint16 sp = r.sp;
+ fuint16 ix = r.ix; // TODO: keep in memory for direct access?
+ fuint16 iy = r.iy;
+ int flags = r.b.flags;
+
+ goto loop;
+jr_not_taken:
+ s_time -= 5;
+ goto loop;
+call_not_taken:
+ s_time -= 7;
+jp_not_taken:
+ pc += 2;
+loop:
+
+ check( (unsigned long) pc < 0x10000 );
+ check( (unsigned long) sp < 0x10000 );
+ check( (unsigned) flags < 0x100 );
+ check( (unsigned) ix < 0x10000 );
+ check( (unsigned) iy < 0x10000 );
+
+ uint8_t const* instr = s.read [pc >> page_shift];
+#define GET_ADDR() GET_LE16( instr )
+
+ fuint8 opcode;
+
+ // TODO: eliminate this special case
+ #if BLARGG_NONPORTABLE
+ opcode = instr [pc];
+ pc++;
+ instr += pc;
+ #else
+ instr += KSS_CPU_PAGE_OFFSET( pc );
+ opcode = *instr++;
+ pc++;
+ #endif
+
+ static byte const base_timing [0x100] = {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 0
+ 13,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, // 1
+ 12,10,16, 6, 4, 4, 7, 4,12,11,16, 6, 4, 4, 7, 4, // 2
+ 12,10,13, 6,11,11,10, 4,12,11,13, 6, 4, 4, 7, 4, // 3
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 4
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 5
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 6
+ 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 7
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 8
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 9
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // A
+ 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // B
+ 11,10,10,10,17,11, 7,11,11,10,10, 8,17,17, 7,11, // C
+ 11,10,10,11,17,11, 7,11,11, 4,10,11,17, 8, 7,11, // D
+ 11,10,10,19,17,11, 7,11,11, 4,10, 4,17, 8, 7,11, // E
+ 11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F
+ };
+
+ fuint16 data;
+ data = base_timing [opcode];
+ if ( (s_time += data) >= 0 )
+ goto possibly_out_of_time;
+almost_out_of_time:
+
+ data = READ_PROG( pc );
+
+ #ifdef Z80_CPU_LOG_H
+ //log_opcode( opcode, READ_PROG( pc ) );
+ z80_log_regs( rg.a, rp.bc, rp.de, rp.hl, sp, ix, iy );
+ z80_cpu_log( "new", pc - 1, opcode, READ_PROG( pc ),
+ READ_PROG( pc + 1 ), READ_PROG( pc + 2 ) );
+ #endif
+
+ switch ( opcode )
+ {
+possibly_out_of_time:
+ if ( s_time < (int) data )
+ goto almost_out_of_time;
+ s_time -= data;
+ goto out_of_time;
+
+// Common
+
+ case 0x00: // NOP
+ CASE7( 40, 49, 52, 5B, 64, 6D, 7F ): // LD B,B etc.
+ goto loop;
+
+ case 0x08:{// EX AF,AF'
+ int temp = r.alt.b.a;
+ r.alt.b.a = rg.a;
+ rg.a = temp;
+
+ temp = r.alt.b.flags;
+ r.alt.b.flags = flags;
+ flags = temp;
+ goto loop;
+ }
+
+ case 0xD3: // OUT (imm),A
+ pc++;
+ OUT( data + rg.a * 0x100, rg.a );
+ goto loop;
+
+ case 0x2E: // LD L,imm
+ pc++;
+ rg.l = data;
+ goto loop;
+
+ case 0x3E: // LD A,imm
+ pc++;
+ rg.a = data;
+ goto loop;
+
+ case 0x3A:{// LD A,(addr)
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ rg.a = READ( addr );
+ goto loop;
+ }
+
+// Conditional
+
+#define ZERO (flags & Z40)
+#define CARRY (flags & C01)
+#define EVEN (flags & P04)
+#define MINUS (flags & S80)
+
+// JR
+// TODO: more efficient way to handle negative branch that wraps PC around
+#define JR( cond ) {\
+ int offset = (int8_t) data;\
+ pc++;\
+ if ( !(cond) )\
+ goto jr_not_taken;\
+ pc = uint16_t (pc + offset);\
+ goto loop;\
+}
+
+ case 0x20: JR( !ZERO ) // JR NZ,disp
+ case 0x28: JR( ZERO ) // JR Z,disp
+ case 0x30: JR( !CARRY ) // JR NC,disp
+ case 0x38: JR( CARRY ) // JR C,disp
+ case 0x18: JR( true ) // JR disp
+
+ case 0x10:{// DJNZ disp
+ int temp = rg.b - 1;
+ rg.b = temp;
+ JR( temp )
+ }
+
+// JP
+#define JP( cond ) if ( !(cond) ) goto jp_not_taken; pc = GET_ADDR(); goto loop;
+
+ case 0xC2: JP( !ZERO ) // JP NZ,addr
+ case 0xCA: JP( ZERO ) // JP Z,addr
+ case 0xD2: JP( !CARRY ) // JP NC,addr
+ case 0xDA: JP( CARRY ) // JP C,addr
+ case 0xE2: JP( !EVEN ) // JP PO,addr
+ case 0xEA: JP( EVEN ) // JP PE,addr
+ case 0xF2: JP( !MINUS ) // JP P,addr
+ case 0xFA: JP( MINUS ) // JP M,addr
+
+ case 0xC3: // JP addr
+ pc = GET_ADDR();
+ goto loop;
+
+ case 0xE9: // JP HL
+ pc = rp.hl;
+ goto loop;
+
+// RET
+#define RET( cond ) if ( cond ) goto ret_taken; s_time -= 6; goto loop;
+
+ case 0xC0: RET( !ZERO ) // RET NZ
+ case 0xC8: RET( ZERO ) // RET Z
+ case 0xD0: RET( !CARRY ) // RET NC
+ case 0xD8: RET( CARRY ) // RET C
+ case 0xE0: RET( !EVEN ) // RET PO
+ case 0xE8: RET( EVEN ) // RET PE
+ case 0xF0: RET( !MINUS ) // RET P
+ case 0xF8: RET( MINUS ) // RET M
+
+ case 0xC9: // RET
+ ret_taken:
+ pc = READ_WORD( sp );
+ sp = uint16_t (sp + 2);
+ goto loop;
+
+// CALL
+#define CALL( cond ) if ( cond ) goto call_taken; goto call_not_taken;
+
+ case 0xC4: CALL( !ZERO ) // CALL NZ,addr
+ case 0xCC: CALL( ZERO ) // CALL Z,addr
+ case 0xD4: CALL( !CARRY ) // CALL NC,addr
+ case 0xDC: CALL( CARRY ) // CALL C,addr
+ case 0xE4: CALL( !EVEN ) // CALL PO,addr
+ case 0xEC: CALL( EVEN ) // CALL PE,addr
+ case 0xF4: CALL( !MINUS ) // CALL P,addr
+ case 0xFC: CALL( MINUS ) // CALL M,addr
+
+ case 0xCD:{// CALL addr
+ call_taken:
+ fuint16 addr = pc + 2;
+ pc = GET_ADDR();
+ sp = uint16_t (sp - 2);
+ WRITE_WORD( sp, addr );
+ goto loop;
+ }
+
+ case 0xFF: // RST
+ if ( pc > idle_addr )
+ goto hit_idle_addr;
+ CASE7( C7, CF, D7, DF, E7, EF, F7 ):
+ data = pc;
+ pc = opcode & 0x38;
+ goto push_data;
+
+// PUSH/POP
+ case 0xF5: // PUSH AF
+ data = rg.a * 0x100u + flags;
+ goto push_data;
+
+ case 0xC5: // PUSH BC
+ case 0xD5: // PUSH DE
+ case 0xE5: // PUSH HL
+ data = R16( opcode, 4, 0xC5 );
+ push_data:
+ sp = uint16_t (sp - 2);
+ WRITE_WORD( sp, data );
+ goto loop;
+
+ case 0xF1: // POP AF
+ flags = READ( sp );
+ rg.a = READ( sp + 1 );
+ sp = uint16_t (sp + 2);
+ goto loop;
+
+ case 0xC1: // POP BC
+ case 0xD1: // POP DE
+ case 0xE1: // POP HL
+ R16( opcode, 4, 0xC1 ) = READ_WORD( sp );
+ sp = uint16_t (sp + 2);
+ goto loop;
+
+// ADC/ADD/SBC/SUB
+ case 0x96: // SUB (HL)
+ case 0x86: // ADD (HL)
+ flags &= ~C01;
+ case 0x9E: // SBC (HL)
+ case 0x8E: // ADC (HL)
+ data = READ( rp.hl );
+ goto adc_data;
+
+ case 0xD6: // SUB A,imm
+ case 0xC6: // ADD imm
+ flags &= ~C01;
+ case 0xDE: // SBC A,imm
+ case 0xCE: // ADC imm
+ pc++;
+ goto adc_data;
+
+ CASE7( 90, 91, 92, 93, 94, 95, 97 ): // SUB r
+ CASE7( 80, 81, 82, 83, 84, 85, 87 ): // ADD r
+ flags &= ~C01;
+ CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // SBC r
+ CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // ADC r
+ data = R8( opcode & 7, 0 );
+ adc_data: {
+ int result = data + (flags & C01);
+ data ^= rg.a;
+ flags = opcode >> 3 & N02; // bit 4 is set in subtract opcodes
+ if ( flags )
+ result = -result;
+ result += rg.a;
+ data ^= result;
+ flags |=(data & H10) |
+ ((data - -0x80) >> 6 & V04) |
+ SZ28C( result & 0x1FF );
+ rg.a = result;
+ goto loop;
+ }
+
+// CP
+ case 0xBE: // CP (HL)
+ data = READ( rp.hl );
+ goto cp_data;
+
+ case 0xFE: // CP imm
+ pc++;
+ goto cp_data;
+
+ CASE7( B8, B9, BA, BB, BC, BD, BF ): // CP r
+ data = R8( opcode, 0xB8 );
+ cp_data: {
+ int result = rg.a - data;
+ flags = N02 | (data & (F20 | F08)) | (result >> 8 & C01);
+ data ^= rg.a;
+ flags |=(((result ^ rg.a) & data) >> 5 & V04) |
+ (((data & H10) ^ result) & (S80 | H10));
+ if ( (uint8_t) result )
+ goto loop;
+ flags |= Z40;
+ goto loop;
+ }
+
+// ADD HL,rp
+
+ case 0x39: // ADD HL,SP
+ data = sp;
+ goto add_hl_data;
+
+ case 0x09: // ADD HL,BC
+ case 0x19: // ADD HL,DE
+ case 0x29: // ADD HL,HL
+ data = R16( opcode, 4, 0x09 );
+ add_hl_data: {
+ blargg_ulong sum = rp.hl + data;
+ data ^= rp.hl;
+ rp.hl = sum;
+ flags = (flags & (S80 | Z40 | V04)) |
+ (sum >> 16) |
+ (sum >> 8 & (F20 | F08)) |
+ ((data ^ sum) >> 8 & H10);
+ goto loop;
+ }
+
+ case 0x27:{// DAA
+ int a = rg.a;
+ if ( a > 0x99 )
+ flags |= C01;
+
+ int adjust = 0x60 & -(flags & C01);
+
+ if ( flags & H10 || (a & 0x0F) > 9 )
+ adjust |= 0x06;
+
+ if ( flags & N02 )
+ adjust = -adjust;
+ a += adjust;
+
+ flags = (flags & (C01 | N02)) |
+ ((rg.a ^ a) & H10) |
+ SZ28P( (uint8_t) a );
+ rg.a = a;
+ goto loop;
+ }
+ /*
+ case 0x27:{// DAA
+ // more optimized, but probably not worth the obscurity
+ int f = (rg.a + (0xFF - 0x99)) >> 8 | flags; // (a > 0x99 ? C01 : 0) | flags
+ int adjust = 0x60 & -(f & C01); // f & C01 ? 0x60 : 0
+
+ if ( (((rg.a + (0x0F - 9)) ^ rg.a) | f) & H10 ) // flags & H10 || (rg.a & 0x0F) > 9
+ adjust |= 0x06;
+
+ if ( f & N02 )
+ adjust = -adjust;
+ int a = rg.a + adjust;
+
+ flags = (f & (N02 | C01)) | ((rg.a ^ a) & H10) | SZ28P( (uint8_t) a );
+ rg.a = a;
+ goto loop;
+ }
+ */
+
+// INC/DEC
+ case 0x34: // INC (HL)
+ data = READ( rp.hl ) + 1;
+ WRITE( rp.hl, data );
+ goto inc_set_flags;
+
+ CASE7( 04, 0C, 14, 1C, 24, 2C, 3C ): // INC r
+ data = ++R8( opcode >> 3, 0 );
+ inc_set_flags:
+ flags = (flags & C01) |
+ (((data & 0x0F) - 1) & H10) |
+ SZ28( (uint8_t) data );
+ if ( data != 0x80 )
+ goto loop;
+ flags |= V04;
+ goto loop;
+
+ case 0x35: // DEC (HL)
+ data = READ( rp.hl ) - 1;
+ WRITE( rp.hl, data );
+ goto dec_set_flags;
+
+ CASE7( 05, 0D, 15, 1D, 25, 2D, 3D ): // DEC r
+ data = --R8( opcode >> 3, 0 );
+ dec_set_flags:
+ flags = (flags & C01) | N02 |
+ (((data & 0x0F) + 1) & H10) |
+ SZ28( (uint8_t) data );
+ if ( data != 0x7F )
+ goto loop;
+ flags |= V04;
+ goto loop;
+
+ case 0x03: // INC BC
+ case 0x13: // INC DE
+ case 0x23: // INC HL
+ R16( opcode, 4, 0x03 )++;
+ goto loop;
+
+ case 0x33: // INC SP
+ sp = uint16_t (sp + 1);
+ goto loop;
+
+ case 0x0B: // DEC BC
+ case 0x1B: // DEC DE
+ case 0x2B: // DEC HL
+ R16( opcode, 4, 0x0B )--;
+ goto loop;
+
+ case 0x3B: // DEC SP
+ sp = uint16_t (sp - 1);
+ goto loop;
+
+// AND
+ case 0xA6: // AND (HL)
+ data = READ( rp.hl );
+ goto and_data;
+
+ case 0xE6: // AND imm
+ pc++;
+ goto and_data;
+
+ CASE7( A0, A1, A2, A3, A4, A5, A7 ): // AND r
+ data = R8( opcode, 0xA0 );
+ and_data:
+ rg.a &= data;
+ flags = SZ28P( rg.a ) | H10;
+ goto loop;
+
+// OR
+ case 0xB6: // OR (HL)
+ data = READ( rp.hl );
+ goto or_data;
+
+ case 0xF6: // OR imm
+ pc++;
+ goto or_data;
+
+ CASE7( B0, B1, B2, B3, B4, B5, B7 ): // OR r
+ data = R8( opcode, 0xB0 );
+ or_data:
+ rg.a |= data;
+ flags = SZ28P( rg.a );
+ goto loop;
+
+// XOR
+ case 0xAE: // XOR (HL)
+ data = READ( rp.hl );
+ goto xor_data;
+
+ case 0xEE: // XOR imm
+ pc++;
+ goto xor_data;
+
+ CASE7( A8, A9, AA, AB, AC, AD, AF ): // XOR r
+ data = R8( opcode, 0xA8 );
+ xor_data:
+ rg.a ^= data;
+ flags = SZ28P( rg.a );
+ goto loop;
+
+// LD
+ CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (HL),r
+ WRITE( rp.hl, R8( opcode, 0x70 ) );
+ goto loop;
+
+ CASE6( 41, 42, 43, 44, 45, 47 ): // LD B,r
+ CASE6( 48, 4A, 4B, 4C, 4D, 4F ): // LD C,r
+ CASE6( 50, 51, 53, 54, 55, 57 ): // LD D,r
+ CASE6( 58, 59, 5A, 5C, 5D, 5F ): // LD E,r
+ CASE6( 60, 61, 62, 63, 65, 67 ): // LD H,r
+ CASE6( 68, 69, 6A, 6B, 6C, 6F ): // LD L,r
+ CASE6( 78, 79, 7A, 7B, 7C, 7D ): // LD A,r
+ R8( opcode >> 3 & 7, 0 ) = R8( opcode & 7, 0 );
+ goto loop;
+
+ CASE5( 06, 0E, 16, 1E, 26 ): // LD r,imm
+ R8( opcode >> 3, 0 ) = data;
+ pc++;
+ goto loop;
+
+ case 0x36: // LD (HL),imm
+ pc++;
+ WRITE( rp.hl, data );
+ goto loop;
+
+ CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(HL)
+ R8( opcode >> 3, 8 ) = READ( rp.hl );
+ goto loop;
+
+ case 0x01: // LD rp,imm
+ case 0x11:
+ case 0x21:
+ R16( opcode, 4, 0x01 ) = GET_ADDR();
+ pc += 2;
+ goto loop;
+
+ case 0x31: // LD sp,imm
+ sp = GET_ADDR();
+ pc += 2;
+ goto loop;
+
+ case 0x2A:{// LD HL,(addr)
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ rp.hl = READ_WORD( addr );
+ goto loop;
+ }
+
+ case 0x32:{// LD (addr),A
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ WRITE( addr, rg.a );
+ goto loop;
+ }
+
+ case 0x22:{// LD (addr),HL
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ WRITE_WORD( addr, rp.hl );
+ goto loop;
+ }
+
+ case 0x02: // LD (BC),A
+ case 0x12: // LD (DE),A
+ WRITE( R16( opcode, 4, 0x02 ), rg.a );
+ goto loop;
+
+ case 0x0A: // LD A,(BC)
+ case 0x1A: // LD A,(DE)
+ rg.a = READ( R16( opcode, 4, 0x0A ) );
+ goto loop;
+
+ case 0xF9: // LD SP,HL
+ sp = rp.hl;
+ goto loop;
+
+// Rotate
+
+ case 0x07:{// RLCA
+ fuint16 temp = rg.a;
+ temp = (temp << 1) | (temp >> 7);
+ flags = (flags & (S80 | Z40 | P04)) |
+ (temp & (F20 | F08 | C01));
+ rg.a = temp;
+ goto loop;
+ }
+
+ case 0x0F:{// RRCA
+ fuint16 temp = rg.a;
+ flags = (flags & (S80 | Z40 | P04)) |
+ (temp & C01);
+ temp = (temp << 7) | (temp >> 1);
+ flags |= temp & (F20 | F08);
+ rg.a = temp;
+ goto loop;
+ }
+
+ case 0x17:{// RLA
+ blargg_ulong temp = (rg.a << 1) | (flags & C01);
+ flags = (flags & (S80 | Z40 | P04)) |
+ (temp & (F20 | F08)) |
+ (temp >> 8);
+ rg.a = temp;
+ goto loop;
+ }
+
+ case 0x1F:{// RRA
+ fuint16 temp = (flags << 7) | (rg.a >> 1);
+ flags = (flags & (S80 | Z40 | P04)) |
+ (temp & (F20 | F08)) |
+ (rg.a & C01);
+ rg.a = temp;
+ goto loop;
+ }
+
+// Misc
+ case 0x2F:{// CPL
+ fuint16 temp = ~rg.a;
+ flags = (flags & (S80 | Z40 | P04 | C01)) |
+ (temp & (F20 | F08)) |
+ (H10 | N02);
+ rg.a = temp;
+ goto loop;
+ }
+
+ case 0x3F:{// CCF
+ flags = ((flags & (S80 | Z40 | P04 | C01)) ^ C01) |
+ (flags << 4 & H10) |
+ (rg.a & (F20 | F08));
+ goto loop;
+ }
+
+ case 0x37: // SCF
+ flags = (flags & (S80 | Z40 | P04)) | C01 |
+ (rg.a & (F20 | F08));
+ goto loop;
+
+ case 0xDB: // IN A,(imm)
+ pc++;
+ rg.a = IN( data + rg.a * 0x100 );
+ goto loop;
+
+ case 0xE3:{// EX (SP),HL
+ fuint16 temp = READ_WORD( sp );
+ WRITE_WORD( sp, rp.hl );
+ rp.hl = temp;
+ goto loop;
+ }
+
+ case 0xEB:{// EX DE,HL
+ fuint16 temp = rp.hl;
+ rp.hl = rp.de;
+ rp.de = temp;
+ goto loop;
+ }
+
+ case 0xD9:{// EXX DE,HL
+ fuint16 temp = r.alt.w.bc;
+ r.alt.w.bc = rp.bc;
+ rp.bc = temp;
+
+ temp = r.alt.w.de;
+ r.alt.w.de = rp.de;
+ rp.de = temp;
+
+ temp = r.alt.w.hl;
+ r.alt.w.hl = rp.hl;
+ rp.hl = temp;
+ goto loop;
+ }
+
+ case 0xF3: // DI
+ r.iff1 = 0;
+ r.iff2 = 0;
+ goto loop;
+
+ case 0xFB: // EI
+ r.iff1 = 1;
+ r.iff2 = 1;
+ // TODO: delayed effect
+ goto loop;
+
+ case 0x76: // HALT
+ goto halt;
+
+//////////////////////////////////////// CB prefix
+ {
+ case 0xCB:
+ pc++;
+ switch ( data )
+ {
+
+ // Rotate left
+
+ #define RLC( read, write ) {\
+ fuint8 result = read;\
+ result = uint8_t (result << 1) | (result >> 7);\
+ flags = SZ28P( result ) | (result & C01);\
+ write;\
+ goto loop;\
+ }
+
+ case 0x06: // RLC (HL)
+ s_time += 7;
+ data = rp.hl;
+ rlc_data_addr:
+ RLC( READ( data ), WRITE( data, result ) )
+
+ CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r
+ uint8_t& reg = R8( data, 0 );
+ RLC( reg, reg = result )
+ }
+
+ #define RL( read, write ) {\
+ fuint16 result = (read << 1) | (flags & C01);\
+ flags = SZ28PC( result );\
+ write;\
+ goto loop;\
+ }
+
+ case 0x16: // RL (HL)
+ s_time += 7;
+ data = rp.hl;
+ rl_data_addr:
+ RL( READ( data ), WRITE( data, result ) )
+
+ CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r
+ uint8_t& reg = R8( data, 0x10 );
+ RL( reg, reg = result )
+ }
+
+ #define SLA( read, add, write ) {\
+ fuint16 result = (read << 1) | add;\
+ flags = SZ28PC( result );\
+ write;\
+ goto loop;\
+ }
+
+ case 0x26: // SLA (HL)
+ s_time += 7;
+ data = rp.hl;
+ sla_data_addr:
+ SLA( READ( data ), 0, WRITE( data, result ) )
+
+ CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r
+ uint8_t& reg = R8( data, 0x20 );
+ SLA( reg, 0, reg = result )
+ }
+
+ case 0x36: // SLL (HL)
+ s_time += 7;
+ data = rp.hl;
+ sll_data_addr:
+ SLA( READ( data ), 1, WRITE( data, result ) )
+
+ CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r
+ uint8_t& reg = R8( data, 0x30 );
+ SLA( reg, 1, reg = result )
+ }
+
+ // Rotate right
+
+ #define RRC( read, write ) {\
+ fuint8 result = read;\
+ flags = result & C01;\
+ result = uint8_t (result << 7) | (result >> 1);\
+ flags |= SZ28P( result );\
+ write;\
+ goto loop;\
+ }
+
+ case 0x0E: // RRC (HL)
+ s_time += 7;
+ data = rp.hl;
+ rrc_data_addr:
+ RRC( READ( data ), WRITE( data, result ) )
+
+ CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r
+ uint8_t& reg = R8( data, 0x08 );
+ RRC( reg, reg = result )
+ }
+
+ #define RR( read, write ) {\
+ fuint8 result = read;\
+ fuint8 temp = result & C01;\
+ result = uint8_t (flags << 7) | (result >> 1);\
+ flags = SZ28P( result ) | temp;\
+ write;\
+ goto loop;\
+ }
+
+ case 0x1E: // RR (HL)
+ s_time += 7;
+ data = rp.hl;
+ rr_data_addr:
+ RR( READ( data ), WRITE( data, result ) )
+
+ CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r
+ uint8_t& reg = R8( data, 0x18 );
+ RR( reg, reg = result )
+ }
+
+ #define SRA( read, write ) {\
+ fuint8 result = read;\
+ flags = result & C01;\
+ result = (result & 0x80) | (result >> 1);\
+ flags |= SZ28P( result );\
+ write;\
+ goto loop;\
+ }
+
+ case 0x2E: // SRA (HL)
+ data = rp.hl;
+ s_time += 7;
+ sra_data_addr:
+ SRA( READ( data ), WRITE( data, result ) )
+
+ CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r
+ uint8_t& reg = R8( data, 0x28 );
+ SRA( reg, reg = result )
+ }
+
+ #define SRL( read, write ) {\
+ fuint8 result = read;\
+ flags = result & C01;\
+ result >>= 1;\
+ flags |= SZ28P( result );\
+ write;\
+ goto loop;\
+ }
+
+ case 0x3E: // SRL (HL)
+ s_time += 7;
+ data = rp.hl;
+ srl_data_addr:
+ SRL( READ( data ), WRITE( data, result ) )
+
+ CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r
+ uint8_t& reg = R8( data, 0x38 );
+ SRL( reg, reg = result )
+ }
+
+ // BIT
+ {
+ unsigned temp;
+ CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL)
+ s_time += 4;
+ temp = READ( rp.hl );
+ flags &= C01;
+ goto bit_temp;
+ CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r
+ CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r
+ CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r
+ CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r
+ CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r
+ CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r
+ CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r
+ CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r
+ temp = R8( data & 7, 0 );
+ flags = (flags & C01) | (temp & (F20 | F08));
+ bit_temp:
+ int masked = temp & 1 << (data >> 3 & 7);
+ flags |=(masked & S80) | H10 |
+ ((masked - 1) >> 8 & (Z40 | P04));
+ goto loop;
+ }
+
+ // SET/RES
+ CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL)
+ CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL)
+ s_time += 7;
+ int temp = READ( rp.hl );
+ int bit = 1 << (data >> 3 & 7);
+ temp |= bit; // SET
+ if ( !(data & 0x40) )
+ temp ^= bit; // RES
+ WRITE( rp.hl, temp );
+ goto loop;
+ }
+
+ CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r
+ CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r
+ CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r
+ CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r
+ CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r
+ CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r
+ CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r
+ CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r
+ R8( data & 7, 0 ) |= 1 << (data >> 3 & 7);
+ goto loop;
+
+ CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r
+ CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r
+ CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r
+ CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r
+ CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r
+ CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r
+ CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r
+ CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r
+ R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7));
+ goto loop;
+ }
+ assert( false );
+ }
+
+#undef GET_ADDR
+#define GET_ADDR() GET_LE16( instr + 1 )
+
+//////////////////////////////////////// ED prefix
+ {
+ case 0xED:
+ pc++;
+ s_time += ed_dd_timing [data] >> 4;
+ switch ( data )
+ {
+ {
+ blargg_ulong temp;
+ case 0x72: // SBC HL,SP
+ case 0x7A: // ADC HL,SP
+ temp = sp;
+ if ( 0 )
+ case 0x42: // SBC HL,BC
+ case 0x52: // SBC HL,DE
+ case 0x62: // SBC HL,HL
+ case 0x4A: // ADC HL,BC
+ case 0x5A: // ADC HL,DE
+ case 0x6A: // ADC HL,HL
+ temp = R16( data >> 3 & 6, 1, 0 );
+ blargg_ulong sum = temp + (flags & C01);
+ flags = ~data >> 2 & N02;
+ if ( flags )
+ sum = -sum;
+ sum += rp.hl;
+ temp ^= rp.hl;
+ temp ^= sum;
+ flags |=(sum >> 16 & C01) |
+ (temp >> 8 & H10) |
+ (sum >> 8 & (S80 | F20 | F08)) |
+ ((temp - -0x8000) >> 14 & V04);
+ rp.hl = sum;
+ if ( (uint16_t) sum )
+ goto loop;
+ flags |= Z40;
+ goto loop;
+ }
+
+ CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C)
+ int temp = IN( rp.bc );
+ R8( data >> 3, 8 ) = temp;
+ flags = (flags & C01) | SZ28P( temp );
+ goto loop;
+ }
+
+ case 0x71: // OUT (C),0
+ rg.flags = 0;
+ CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r
+ OUT( rp.bc, R8( data >> 3, 8 ) );
+ goto loop;
+
+ {
+ unsigned temp;
+ case 0x73: // LD (ADDR),SP
+ temp = sp;
+ if ( 0 )
+ case 0x43: // LD (ADDR),BC
+ case 0x53: // LD (ADDR),DE
+ temp = R16( data, 4, 0x43 );
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ WRITE_WORD( addr, temp );
+ goto loop;
+ }
+
+ case 0x4B: // LD BC,(ADDR)
+ case 0x5B:{// LD DE,(ADDR)
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ R16( data, 4, 0x4B ) = READ_WORD( addr );
+ goto loop;
+ }
+
+ case 0x7B:{// LD SP,(ADDR)
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ sp = READ_WORD( addr );
+ goto loop;
+ }
+
+ case 0x67:{// RRD
+ fuint8 temp = READ( rp.hl );
+ WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
+ temp = (rg.a & 0xF0) | (temp & 0x0F);
+ flags = (flags & C01) | SZ28P( temp );
+ rg.a = temp;
+ goto loop;
+ }
+
+ case 0x6F:{// RLD
+ fuint8 temp = READ( rp.hl );
+ WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
+ temp = (rg.a & 0xF0) | (temp >> 4);
+ flags = (flags & C01) | SZ28P( temp );
+ rg.a = temp;
+ goto loop;
+ }
+
+ CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG
+ opcode = 0x10; // flag to do SBC instead of ADC
+ flags &= ~C01;
+ data = rg.a;
+ rg.a = 0;
+ goto adc_data;
+
+ {
+ int inc;
+ case 0xA9: // CPD
+ case 0xB9: // CPDR
+ inc = -1;
+ if ( 0 )
+ case 0xA1: // CPI
+ case 0xB1: // CPIR
+ inc = +1;
+ fuint16 addr = rp.hl;
+ rp.hl = addr + inc;
+ int temp = READ( addr );
+
+ int result = rg.a - temp;
+ flags = (flags & C01) | N02 |
+ ((((temp ^ rg.a) & H10) ^ result) & (S80 | H10));
+
+ if ( !(uint8_t) result ) flags |= Z40;
+ result -= (flags & H10) >> 4;
+ flags |= result & F08;
+ flags |= result << 4 & F20;
+ if ( !--rp.bc )
+ goto loop;
+
+ flags |= V04;
+ if ( flags & Z40 || data < 0xB0 )
+ goto loop;
+
+ pc -= 2;
+ s_time += 5;
+ goto loop;
+ }
+
+ {
+ int inc;
+ case 0xA8: // LDD
+ case 0xB8: // LDDR
+ inc = -1;
+ if ( 0 )
+ case 0xA0: // LDI
+ case 0xB0: // LDIR
+ inc = +1;
+ fuint16 addr = rp.hl;
+ rp.hl = addr + inc;
+ int temp = READ( addr );
+
+ addr = rp.de;
+ rp.de = addr + inc;
+ WRITE( addr, temp );
+
+ temp += rg.a;
+ flags = (flags & (S80 | Z40 | C01)) |
+ (temp & F08) | (temp << 4 & F20);
+ if ( !--rp.bc )
+ goto loop;
+
+ flags |= V04;
+ if ( data < 0xB0 )
+ goto loop;
+
+ pc -= 2;
+ s_time += 5;
+ goto loop;
+ }
+
+ {
+ int inc;
+ case 0xAB: // OUTD
+ case 0xBB: // OTDR
+ inc = -1;
+ if ( 0 )
+ case 0xA3: // OUTI
+ case 0xB3: // OTIR
+ inc = +1;
+ fuint16 addr = rp.hl;
+ rp.hl = addr + inc;
+ int temp = READ( addr );
+
+ int b = --rg.b;
+ flags = (temp >> 6 & N02) | SZ28( b );
+ if ( b && data >= 0xB0 )
+ {
+ pc -= 2;
+ s_time += 5;
+ }
+
+ OUT( rp.bc, temp );
+ goto loop;
+ }
+
+ {
+ int inc;
+ case 0xAA: // IND
+ case 0xBA: // INDR
+ inc = -1;
+ if ( 0 )
+ case 0xA2: // INI
+ case 0xB2: // INIR
+ inc = +1;
+
+ fuint16 addr = rp.hl;
+ rp.hl = addr + inc;
+
+ int temp = IN( rp.bc );
+
+ int b = --rg.b;
+ flags = (temp >> 6 & N02) | SZ28( b );
+ if ( b && data >= 0xB0 )
+ {
+ pc -= 2;
+ s_time += 5;
+ }
+
+ WRITE( addr, temp );
+ goto loop;
+ }
+
+ case 0x47: // LD I,A
+ r.i = rg.a;
+ goto loop;
+
+ case 0x4F: // LD R,A
+ SET_R( rg.a );
+ debug_printf( "LD R,A not supported\n" );
+ warning = true;
+ goto loop;
+
+ case 0x57: // LD A,I
+ rg.a = r.i;
+ goto ld_ai_common;
+
+ case 0x5F: // LD A,R
+ rg.a = GET_R();
+ debug_printf( "LD A,R not supported\n" );
+ warning = true;
+ ld_ai_common:
+ flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
+ goto loop;
+
+ CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN
+ r.iff1 = r.iff2;
+ goto ret_taken;
+
+ case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0
+ r.im = 0;
+ goto loop;
+
+ case 0x56: case 0x76: // IM 1
+ r.im = 1;
+ goto loop;
+
+ case 0x5E: case 0x7E: // IM 2
+ r.im = 2;
+ goto loop;
+
+ default:
+ debug_printf( "Opcode $ED $%02X not supported\n", data );
+ warning = true;
+ goto loop;
+ }
+ assert( false );
+ }
+
+//////////////////////////////////////// DD/FD prefix
+ {
+ fuint16 ixy;
+ case 0xDD:
+ ixy = ix;
+ goto ix_prefix;
+ case 0xFD:
+ ixy = iy;
+ ix_prefix:
+ pc++;
+ unsigned data2 = READ_PROG( pc );
+ s_time += ed_dd_timing [data] & 0x0F;
+ switch ( data )
+ {
+ // TODO: more efficient way of avoid negative address
+ // TODO: avoid using this as argument to READ() since it is evaluated twice
+ #define IXY_DISP( ixy, disp ) uint16_t ((ixy) + (disp))
+
+ #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in;
+
+ // ADD/ADC/SUB/SBC
+
+ case 0x96: // SUB (IXY+disp)
+ case 0x86: // ADD (IXY+disp)
+ flags &= ~C01;
+ case 0x9E: // SBC (IXY+disp)
+ case 0x8E: // ADC (IXY+disp)
+ pc++;
+ opcode = data;
+ data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
+ goto adc_data;
+
+ case 0x94: // SUB HXY
+ case 0x84: // ADD HXY
+ flags &= ~C01;
+ case 0x9C: // SBC HXY
+ case 0x8C: // ADC HXY
+ opcode = data;
+ data = ixy >> 8;
+ goto adc_data;
+
+ case 0x95: // SUB LXY
+ case 0x85: // ADD LXY
+ flags &= ~C01;
+ case 0x9D: // SBC LXY
+ case 0x8D: // ADC LXY
+ opcode = data;
+ data = (uint8_t) ixy;
+ goto adc_data;
+
+ {
+ unsigned temp;
+ case 0x39: // ADD IXY,SP
+ temp = sp;
+ goto add_ixy_data;
+
+ case 0x29: // ADD IXY,HL
+ temp = ixy;
+ goto add_ixy_data;
+
+ case 0x09: // ADD IXY,BC
+ case 0x19: // ADD IXY,DE
+ temp = R16( data, 4, 0x09 );
+ add_ixy_data: {
+ blargg_ulong sum = ixy + temp;
+ temp ^= ixy;
+ ixy = (uint16_t) sum;
+ flags = (flags & (S80 | Z40 | V04)) |
+ (sum >> 16) |
+ (sum >> 8 & (F20 | F08)) |
+ ((temp ^ sum) >> 8 & H10);
+ goto set_ixy;
+ }
+ }
+
+ // AND
+ case 0xA6: // AND (IXY+disp)
+ pc++;
+ data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
+ goto and_data;
+
+ case 0xA4: // AND HXY
+ data = ixy >> 8;
+ goto and_data;
+
+ case 0xA5: // AND LXY
+ data = (uint8_t) ixy;
+ goto and_data;
+
+ // OR
+ case 0xB6: // OR (IXY+disp)
+ pc++;
+ data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
+ goto or_data;
+
+ case 0xB4: // OR HXY
+ data = ixy >> 8;
+ goto or_data;
+
+ case 0xB5: // OR LXY
+ data = (uint8_t) ixy;
+ goto or_data;
+
+ // XOR
+ case 0xAE: // XOR (IXY+disp)
+ pc++;
+ data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
+ goto xor_data;
+
+ case 0xAC: // XOR HXY
+ data = ixy >> 8;
+ goto xor_data;
+
+ case 0xAD: // XOR LXY
+ data = (uint8_t) ixy;
+ goto xor_data;
+
+ // CP
+ case 0xBE: // CP (IXY+disp)
+ pc++;
+ data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
+ goto cp_data;
+
+ case 0xBC: // CP HXY
+ data = ixy >> 8;
+ goto cp_data;
+
+ case 0xBD: // CP LXY
+ data = (uint8_t) ixy;
+ goto cp_data;
+
+ // LD
+ CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r
+ data = R8( data, 0x70 );
+ if ( 0 )
+ case 0x36: // LD (IXY+disp),imm
+ pc++, data = READ_PROG( pc );
+ pc++;
+ WRITE( IXY_DISP( ixy, (int8_t) data2 ), data );
+ goto loop;
+
+ CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY
+ R8( data >> 3, 8 ) = ixy >> 8;
+ goto loop;
+
+ case 0x64: // LD HXY,HXY
+ case 0x6D: // LD LXY,LXY
+ goto loop;
+
+ CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY
+ R8( data >> 3, 8 ) = ixy;
+ goto loop;
+
+ CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp)
+ pc++;
+ R8( data >> 3, 8 ) = READ( IXY_DISP( ixy, (int8_t) data2 ) );
+ goto loop;
+
+ case 0x26: // LD HXY,imm
+ pc++;
+ goto ld_hxy_data;
+
+ case 0x65: // LD HXY,LXY
+ data2 = (uint8_t) ixy;
+ goto ld_hxy_data;
+
+ CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r
+ data2 = R8( data, 0x60 );
+ ld_hxy_data:
+ ixy = (uint8_t) ixy | (data2 << 8);
+ goto set_ixy;
+
+ case 0x2E: // LD LXY,imm
+ pc++;
+ goto ld_lxy_data;
+
+ case 0x6C: // LD LXY,HXY
+ data2 = ixy >> 8;
+ goto ld_lxy_data;
+
+ CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r
+ data2 = R8( data, 0x68 );
+ ld_lxy_data:
+ ixy = (ixy & 0xFF00) | data2;
+ set_ixy:
+ if ( opcode == 0xDD )
+ {
+ ix = ixy;
+ goto loop;
+ }
+ iy = ixy;
+ goto loop;
+
+ case 0xF9: // LD SP,IXY
+ sp = ixy;
+ goto loop;
+
+ case 0x22:{// LD (ADDR),IXY
+ fuint16 addr = GET_ADDR();
+ pc += 2;
+ WRITE_WORD( addr, ixy );
+ goto loop;
+ }
+
+ case 0x21: // LD IXY,imm
+ ixy = GET_ADDR();
+ pc += 2;
+ goto set_ixy;
+
+ case 0x2A:{// LD IXY,(addr)
+ fuint16 addr = GET_ADDR();
+ ixy = READ_WORD( addr );
+ pc += 2;
+ goto set_ixy;
+ }
+
+ // DD/FD CB prefix
+ case 0xCB: {
+ data = IXY_DISP( ixy, (int8_t) data2 );
+ pc++;
+ data2 = READ_PROG( pc );
+ pc++;
+ switch ( data2 )
+ {
+ case 0x06: goto rlc_data_addr; // RLC (IXY)
+ case 0x16: goto rl_data_addr; // RL (IXY)
+ case 0x26: goto sla_data_addr; // SLA (IXY)
+ case 0x36: goto sll_data_addr; // SLL (IXY)
+ case 0x0E: goto rrc_data_addr; // RRC (IXY)
+ case 0x1E: goto rr_data_addr; // RR (IXY)
+ case 0x2E: goto sra_data_addr; // SRA (IXY)
+ case 0x3E: goto srl_data_addr; // SRL (IXY)
+
+ CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
+ fuint8 temp = READ( data );
+ int masked = temp & 1 << (data2 >> 3 & 7);
+ flags = (flags & C01) | H10 |
+ (masked & S80) |
+ ((masked - 1) >> 8 & (Z40 | P04));
+ goto loop;
+ }
+
+ CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp)
+ CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp)
+ int temp = READ( data );
+ int bit = 1 << (data2 >> 3 & 7);
+ temp |= bit; // SET
+ if ( !(data2 & 0x40) )
+ temp ^= bit; // RES
+ WRITE( data, temp );
+ goto loop;
+ }
+
+ default:
+ debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
+ warning = true;
+ goto loop;
+ }
+ assert( false );
+ }
+
+ // INC/DEC
+ case 0x23: // INC IXY
+ ixy = uint16_t (ixy + 1);
+ goto set_ixy;
+
+ case 0x2B: // DEC IXY
+ ixy = uint16_t (ixy - 1);
+ goto set_ixy;
+
+ case 0x34: // INC (IXY+disp)
+ ixy = IXY_DISP( ixy, (int8_t) data2 );
+ pc++;
+ data = READ( ixy ) + 1;
+ WRITE( ixy, data );
+ goto inc_set_flags;
+
+ case 0x35: // DEC (IXY+disp)
+ ixy = IXY_DISP( ixy, (int8_t) data2 );
+ pc++;
+ data = READ( ixy ) - 1;
+ WRITE( ixy, data );
+ goto dec_set_flags;
+
+ case 0x24: // INC HXY
+ ixy = uint16_t (ixy + 0x100);
+ data = ixy >> 8;
+ goto inc_xy_common;
+
+ case 0x2C: // INC LXY
+ data = uint8_t (ixy + 1);
+ ixy = (ixy & 0xFF00) | data;
+ inc_xy_common:
+ if ( opcode == 0xDD )
+ {
+ ix = ixy;
+ goto inc_set_flags;
+ }
+ iy = ixy;
+ goto inc_set_flags;
+
+ case 0x25: // DEC HXY
+ ixy = uint16_t (ixy - 0x100);
+ data = ixy >> 8;
+ goto dec_xy_common;
+
+ case 0x2D: // DEC LXY
+ data = uint8_t (ixy - 1);
+ ixy = (ixy & 0xFF00) | data;
+ dec_xy_common:
+ if ( opcode == 0xDD )
+ {
+ ix = ixy;
+ goto dec_set_flags;
+ }
+ iy = ixy;
+ goto dec_set_flags;
+
+ // PUSH/POP
+ case 0xE5: // PUSH IXY
+ data = ixy;
+ goto push_data;
+
+ case 0xE1:{// POP IXY
+ ixy = READ_WORD( sp );
+ sp = uint16_t (sp + 2);
+ goto set_ixy;
+ }
+
+ // Misc
+
+ case 0xE9: // JP (IXY)
+ pc = ixy;
+ goto loop;
+
+ case 0xE3:{// EX (SP),IXY
+ fuint16 temp = READ_WORD( sp );
+ WRITE_WORD( sp, ixy );
+ ixy = temp;
+ goto set_ixy;
+ }
+
+ default:
+ debug_printf( "Unnecessary DD/FD prefix encountered\n" );
+ warning = true;
+ pc--;
+ goto loop;
+ }
+ assert( false );
+ }
+
+ }
+ debug_printf( "Unhandled main opcode: $%02X\n", opcode );
+ assert( false );
+
+hit_idle_addr:
+ s_time -= 11;
+ goto out_of_time;
+halt:
+ s_time &= 3; // increment by multiple of 4
+out_of_time:
+ pc--;
+
+ s.time = s_time;
+ rg.flags = flags;
+ r.ix = ix;
+ r.iy = iy;
+ r.sp = sp;
+ r.pc = pc;
+ this->r.b = rg;
+ this->state_ = s;
+ this->state = &this->state_;
+
+ return warning;
+}
diff --git a/src/console/Kss_Cpu.cxx b/src/console/Kss_Cpu.cxx
deleted file mode 100644
index 0f397e1fc4bb..000000000000
--- a/src/console/Kss_Cpu.cxx
+++ /dev/null
@@ -1,1704 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-/*
-Last validated with zexall 2006.11.14 2:19 PM
-* Doesn't implement the R register or immediate interrupt after EI.
-* Address wrap-around isn't completely correct, but is prevented from crashing emulator.
-*/
-
-#include "Kss_Cpu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-//#include "z80_cpu_log.h"
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#define SYNC_TIME() (void) (s.time = s_time)
-#define RELOAD_TIME() (void) (s_time = s.time)
-
-// Callbacks to emulator
-
-#define CPU_OUT( cpu, addr, data, time )\
- kss_cpu_out( this, time, addr, data )
-
-#define CPU_IN( cpu, addr, time )\
- kss_cpu_in( this, time, addr )
-
-#define CPU_WRITE( cpu, addr, data, time )\
- (SYNC_TIME(), kss_cpu_write( this, addr, data ))
-
-#include "blargg_source.h"
-
-// flags, named with hex value for clarity
-int const S80 = 0x80;
-int const Z40 = 0x40;
-int const F20 = 0x20;
-int const H10 = 0x10;
-int const F08 = 0x08;
-int const V04 = 0x04;
-int const P04 = 0x04;
-int const N02 = 0x02;
-int const C01 = 0x01;
-
-#define SZ28P( n ) szpc [n]
-#define SZ28PC( n ) szpc [n]
-#define SZ28C( n ) (szpc [n] & ~P04)
-#define SZ28( n ) SZ28C( n )
-
-#define SET_R( n ) (void) (r.r = n)
-#define GET_R() (r.r)
-
-Kss_Cpu::Kss_Cpu()
-{
- state = &state_;
-
- for ( int i = 0x100; --i >= 0; )
- {
- int even = 1;
- for ( int p = i; p; p >>= 1 )
- even ^= p;
- int n = (i & (S80 | F20 | F08)) | ((even & 1) * P04);
- szpc [i] = n;
- szpc [i + 0x100] = n | C01;
- }
- szpc [0x000] |= Z40;
- szpc [0x100] |= Z40;
-}
-
-inline void Kss_Cpu::set_page( int i, void* write, void const* read )
-{
- blargg_long offset = KSS_CPU_PAGE_OFFSET( i * (blargg_long) page_size );
- state->write [i] = (byte *) write - offset;
- state->read [i] = (byte const*) read - offset;
-}
-
-void Kss_Cpu::reset( void* unmapped_write, void const* unmapped_read )
-{
- check( state == &state_ );
- state = &state_;
- state_.time = 0;
- state_.base = 0;
- end_time_ = 0;
-
- for ( int i = 0; i < page_count + 1; i++ )
- set_page( i, unmapped_write, unmapped_read );
-
- memset( &r, 0, sizeof r );
-}
-
-void Kss_Cpu::map_mem( unsigned addr, blargg_ulong size, void* write, void const* read )
-{
- // address range must begin and end on page boundaries
- require( addr % page_size == 0 );
- require( size % page_size == 0 );
-
- unsigned first_page = addr / page_size;
- for ( unsigned i = size / page_size; i--; )
- {
- blargg_long offset = i * (blargg_long) page_size;
- set_page( first_page + i, (byte*) write + offset, (byte const*) read + offset );
- }
-}
-
-#define TIME (s_time + s.base)
-#define RW_MEM( addr, rw ) (s.rw [(addr) >> page_shift] [KSS_CPU_PAGE_OFFSET( addr )])
-#define READ_PROG( addr ) RW_MEM( addr, read )
-#define READ( addr ) READ_PROG( addr )
-//#define WRITE( addr, data ) (void) (RW_MEM( addr, write ) = data)
-#define WRITE( addr, data ) CPU_WRITE( this, addr, data, TIME )
-#define READ_WORD( addr ) GET_LE16( &READ( addr ) )
-#define WRITE_WORD( addr, data ) SET_LE16( &RW_MEM( addr, write ), data )
-#define IN( addr ) CPU_IN( this, addr, TIME )
-#define OUT( addr, data ) CPU_OUT( this, addr, data, TIME )
-
-#if BLARGG_BIG_ENDIAN
- #define R8( n, offset ) ((r8_ - offset) [n])
-#elif BLARGG_LITTLE_ENDIAN
- #define R8( n, offset ) ((r8_ - offset) [(n) ^ 1])
-#else
- #error "Byte order of CPU must be known"
-#endif
-
-//#define R16( n, shift, offset ) (r16_ [((n) >> shift) - (offset >> shift)])
-
-// help compiler see that it can just adjust stack offset, saving an extra instruction
-#define R16( n, shift, offset )\
- (*(uint16_t*) ((char*) r16_ - (offset >> (shift - 1)) + ((n) >> (shift - 1))))
-
-#define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e
-#define CASE6( a, b, c, d, e, f ) CASE5( a, b, c, d, e ): case 0x##f
-#define CASE7( a, b, c, d, e, f, g ) CASE6( a, b, c, d, e, f ): case 0x##g
-#define CASE8( a, b, c, d, e, f, g, h ) CASE7( a, b, c, d, e, f, g ): case 0x##h
-
-// high four bits are $ED time - 8, low four bits are $DD/$FD time - 8
-static byte const ed_dd_timing [0x100] = {
-//0 1 2 3 4 5 6 7 8 9 A B C D E F
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x06,0x0C,0x02,0x00,0x00,0x03,0x00,0x00,0x07,0x0C,0x02,0x00,0x00,0x03,0x00,
-0x00,0x00,0x00,0x00,0x0F,0x0F,0x0B,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,
-0x4B,0x4B,0x7B,0xCB,0x0B,0x6B,0x00,0x0B,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
-0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,
-0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x06,0x00,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-
-bool Kss_Cpu::run( cpu_time_t end_time )
-{
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- bool warning = false;
-
- typedef int8_t int8_t;
-
- union {
- regs_t rg;
- pairs_t rp;
- uint8_t r8_ [8]; // indexed
- uint16_t r16_ [4];
- };
- rg = this->r.b;
-
- cpu_time_t s_time = s.time;
- fuint16 pc = r.pc;
- fuint16 sp = r.sp;
- fuint16 ix = r.ix; // TODO: keep in memory for direct access?
- fuint16 iy = r.iy;
- int flags = r.b.flags;
-
- goto loop;
-jr_not_taken:
- s_time -= 5;
- goto loop;
-call_not_taken:
- s_time -= 7;
-jp_not_taken:
- pc += 2;
-loop:
-
- check( (unsigned long) pc < 0x10000 );
- check( (unsigned long) sp < 0x10000 );
- check( (unsigned) flags < 0x100 );
- check( (unsigned) ix < 0x10000 );
- check( (unsigned) iy < 0x10000 );
-
- uint8_t const* instr = s.read [pc >> page_shift];
-#define GET_ADDR() GET_LE16( instr )
-
- fuint8 opcode;
-
- // TODO: eliminate this special case
- #if BLARGG_NONPORTABLE
- opcode = instr [pc];
- pc++;
- instr += pc;
- #else
- instr += KSS_CPU_PAGE_OFFSET( pc );
- opcode = *instr++;
- pc++;
- #endif
-
- static byte const base_timing [0x100] = {
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 0
- 13,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, // 1
- 12,10,16, 6, 4, 4, 7, 4,12,11,16, 6, 4, 4, 7, 4, // 2
- 12,10,13, 6,11,11,10, 4,12,11,13, 6, 4, 4, 7, 4, // 3
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 4
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 5
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 6
- 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 7
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 8
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 9
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // A
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // B
- 11,10,10,10,17,11, 7,11,11,10,10, 8,17,17, 7,11, // C
- 11,10,10,11,17,11, 7,11,11, 4,10,11,17, 8, 7,11, // D
- 11,10,10,19,17,11, 7,11,11, 4,10, 4,17, 8, 7,11, // E
- 11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F
- };
-
- fuint16 data;
- data = base_timing [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = READ_PROG( pc );
-
- #ifdef Z80_CPU_LOG_H
- //log_opcode( opcode, READ_PROG( pc ) );
- z80_log_regs( rg.a, rp.bc, rp.de, rp.hl, sp, ix, iy );
- z80_cpu_log( "new", pc - 1, opcode, READ_PROG( pc ),
- READ_PROG( pc + 1 ), READ_PROG( pc + 2 ) );
- #endif
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-
-// Common
-
- case 0x00: // NOP
- CASE7( 40, 49, 52, 5B, 64, 6D, 7F ): // LD B,B etc.
- goto loop;
-
- case 0x08:{// EX AF,AF'
- int temp = r.alt.b.a;
- r.alt.b.a = rg.a;
- rg.a = temp;
-
- temp = r.alt.b.flags;
- r.alt.b.flags = flags;
- flags = temp;
- goto loop;
- }
-
- case 0xD3: // OUT (imm),A
- pc++;
- OUT( data + rg.a * 0x100, rg.a );
- goto loop;
-
- case 0x2E: // LD L,imm
- pc++;
- rg.l = data;
- goto loop;
-
- case 0x3E: // LD A,imm
- pc++;
- rg.a = data;
- goto loop;
-
- case 0x3A:{// LD A,(addr)
- fuint16 addr = GET_ADDR();
- pc += 2;
- rg.a = READ( addr );
- goto loop;
- }
-
-// Conditional
-
-#define ZERO (flags & Z40)
-#define CARRY (flags & C01)
-#define EVEN (flags & P04)
-#define MINUS (flags & S80)
-
-// JR
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define JR( cond ) {\
- int offset = (int8_t) data;\
- pc++;\
- if ( !(cond) )\
- goto jr_not_taken;\
- pc = uint16_t (pc + offset);\
- goto loop;\
-}
-
- case 0x20: JR( !ZERO ) // JR NZ,disp
- case 0x28: JR( ZERO ) // JR Z,disp
- case 0x30: JR( !CARRY ) // JR NC,disp
- case 0x38: JR( CARRY ) // JR C,disp
- case 0x18: JR( true ) // JR disp
-
- case 0x10:{// DJNZ disp
- int temp = rg.b - 1;
- rg.b = temp;
- JR( temp )
- }
-
-// JP
-#define JP( cond ) if ( !(cond) ) goto jp_not_taken; pc = GET_ADDR(); goto loop;
-
- case 0xC2: JP( !ZERO ) // JP NZ,addr
- case 0xCA: JP( ZERO ) // JP Z,addr
- case 0xD2: JP( !CARRY ) // JP NC,addr
- case 0xDA: JP( CARRY ) // JP C,addr
- case 0xE2: JP( !EVEN ) // JP PO,addr
- case 0xEA: JP( EVEN ) // JP PE,addr
- case 0xF2: JP( !MINUS ) // JP P,addr
- case 0xFA: JP( MINUS ) // JP M,addr
-
- case 0xC3: // JP addr
- pc = GET_ADDR();
- goto loop;
-
- case 0xE9: // JP HL
- pc = rp.hl;
- goto loop;
-
-// RET
-#define RET( cond ) if ( cond ) goto ret_taken; s_time -= 6; goto loop;
-
- case 0xC0: RET( !ZERO ) // RET NZ
- case 0xC8: RET( ZERO ) // RET Z
- case 0xD0: RET( !CARRY ) // RET NC
- case 0xD8: RET( CARRY ) // RET C
- case 0xE0: RET( !EVEN ) // RET PO
- case 0xE8: RET( EVEN ) // RET PE
- case 0xF0: RET( !MINUS ) // RET P
- case 0xF8: RET( MINUS ) // RET M
-
- case 0xC9: // RET
- ret_taken:
- pc = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto loop;
-
-// CALL
-#define CALL( cond ) if ( cond ) goto call_taken; goto call_not_taken;
-
- case 0xC4: CALL( !ZERO ) // CALL NZ,addr
- case 0xCC: CALL( ZERO ) // CALL Z,addr
- case 0xD4: CALL( !CARRY ) // CALL NC,addr
- case 0xDC: CALL( CARRY ) // CALL C,addr
- case 0xE4: CALL( !EVEN ) // CALL PO,addr
- case 0xEC: CALL( EVEN ) // CALL PE,addr
- case 0xF4: CALL( !MINUS ) // CALL P,addr
- case 0xFC: CALL( MINUS ) // CALL M,addr
-
- case 0xCD:{// CALL addr
- call_taken:
- fuint16 addr = pc + 2;
- pc = GET_ADDR();
- sp = uint16_t (sp - 2);
- WRITE_WORD( sp, addr );
- goto loop;
- }
-
- case 0xFF: // RST
- if ( pc > idle_addr )
- goto hit_idle_addr;
- CASE7( C7, CF, D7, DF, E7, EF, F7 ):
- data = pc;
- pc = opcode & 0x38;
- goto push_data;
-
-// PUSH/POP
- case 0xF5: // PUSH AF
- data = rg.a * 0x100u + flags;
- goto push_data;
-
- case 0xC5: // PUSH BC
- case 0xD5: // PUSH DE
- case 0xE5: // PUSH HL
- data = R16( opcode, 4, 0xC5 );
- push_data:
- sp = uint16_t (sp - 2);
- WRITE_WORD( sp, data );
- goto loop;
-
- case 0xF1: // POP AF
- flags = READ( sp );
- rg.a = READ( sp + 1 );
- sp = uint16_t (sp + 2);
- goto loop;
-
- case 0xC1: // POP BC
- case 0xD1: // POP DE
- case 0xE1: // POP HL
- R16( opcode, 4, 0xC1 ) = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto loop;
-
-// ADC/ADD/SBC/SUB
- case 0x96: // SUB (HL)
- case 0x86: // ADD (HL)
- flags &= ~C01;
- case 0x9E: // SBC (HL)
- case 0x8E: // ADC (HL)
- data = READ( rp.hl );
- goto adc_data;
-
- case 0xD6: // SUB A,imm
- case 0xC6: // ADD imm
- flags &= ~C01;
- case 0xDE: // SBC A,imm
- case 0xCE: // ADC imm
- pc++;
- goto adc_data;
-
- CASE7( 90, 91, 92, 93, 94, 95, 97 ): // SUB r
- CASE7( 80, 81, 82, 83, 84, 85, 87 ): // ADD r
- flags &= ~C01;
- CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // SBC r
- CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // ADC r
- data = R8( opcode & 7, 0 );
- adc_data: {
- int result = data + (flags & C01);
- data ^= rg.a;
- flags = opcode >> 3 & N02; // bit 4 is set in subtract opcodes
- if ( flags )
- result = -result;
- result += rg.a;
- data ^= result;
- flags |=(data & H10) |
- ((data - -0x80) >> 6 & V04) |
- SZ28C( result & 0x1FF );
- rg.a = result;
- goto loop;
- }
-
-// CP
- case 0xBE: // CP (HL)
- data = READ( rp.hl );
- goto cp_data;
-
- case 0xFE: // CP imm
- pc++;
- goto cp_data;
-
- CASE7( B8, B9, BA, BB, BC, BD, BF ): // CP r
- data = R8( opcode, 0xB8 );
- cp_data: {
- int result = rg.a - data;
- flags = N02 | (data & (F20 | F08)) | (result >> 8 & C01);
- data ^= rg.a;
- flags |=(((result ^ rg.a) & data) >> 5 & V04) |
- (((data & H10) ^ result) & (S80 | H10));
- if ( (uint8_t) result )
- goto loop;
- flags |= Z40;
- goto loop;
- }
-
-// ADD HL,rp
-
- case 0x39: // ADD HL,SP
- data = sp;
- goto add_hl_data;
-
- case 0x09: // ADD HL,BC
- case 0x19: // ADD HL,DE
- case 0x29: // ADD HL,HL
- data = R16( opcode, 4, 0x09 );
- add_hl_data: {
- blargg_ulong sum = rp.hl + data;
- data ^= rp.hl;
- rp.hl = sum;
- flags = (flags & (S80 | Z40 | V04)) |
- (sum >> 16) |
- (sum >> 8 & (F20 | F08)) |
- ((data ^ sum) >> 8 & H10);
- goto loop;
- }
-
- case 0x27:{// DAA
- int a = rg.a;
- if ( a > 0x99 )
- flags |= C01;
-
- int adjust = 0x60 & -(flags & C01);
-
- if ( flags & H10 || (a & 0x0F) > 9 )
- adjust |= 0x06;
-
- if ( flags & N02 )
- adjust = -adjust;
- a += adjust;
-
- flags = (flags & (C01 | N02)) |
- ((rg.a ^ a) & H10) |
- SZ28P( (uint8_t) a );
- rg.a = a;
- goto loop;
- }
- /*
- case 0x27:{// DAA
- // more optimized, but probably not worth the obscurity
- int f = (rg.a + (0xFF - 0x99)) >> 8 | flags; // (a > 0x99 ? C01 : 0) | flags
- int adjust = 0x60 & -(f & C01); // f & C01 ? 0x60 : 0
-
- if ( (((rg.a + (0x0F - 9)) ^ rg.a) | f) & H10 ) // flags & H10 || (rg.a & 0x0F) > 9
- adjust |= 0x06;
-
- if ( f & N02 )
- adjust = -adjust;
- int a = rg.a + adjust;
-
- flags = (f & (N02 | C01)) | ((rg.a ^ a) & H10) | SZ28P( (uint8_t) a );
- rg.a = a;
- goto loop;
- }
- */
-
-// INC/DEC
- case 0x34: // INC (HL)
- data = READ( rp.hl ) + 1;
- WRITE( rp.hl, data );
- goto inc_set_flags;
-
- CASE7( 04, 0C, 14, 1C, 24, 2C, 3C ): // INC r
- data = ++R8( opcode >> 3, 0 );
- inc_set_flags:
- flags = (flags & C01) |
- (((data & 0x0F) - 1) & H10) |
- SZ28( (uint8_t) data );
- if ( data != 0x80 )
- goto loop;
- flags |= V04;
- goto loop;
-
- case 0x35: // DEC (HL)
- data = READ( rp.hl ) - 1;
- WRITE( rp.hl, data );
- goto dec_set_flags;
-
- CASE7( 05, 0D, 15, 1D, 25, 2D, 3D ): // DEC r
- data = --R8( opcode >> 3, 0 );
- dec_set_flags:
- flags = (flags & C01) | N02 |
- (((data & 0x0F) + 1) & H10) |
- SZ28( (uint8_t) data );
- if ( data != 0x7F )
- goto loop;
- flags |= V04;
- goto loop;
-
- case 0x03: // INC BC
- case 0x13: // INC DE
- case 0x23: // INC HL
- R16( opcode, 4, 0x03 )++;
- goto loop;
-
- case 0x33: // INC SP
- sp = uint16_t (sp + 1);
- goto loop;
-
- case 0x0B: // DEC BC
- case 0x1B: // DEC DE
- case 0x2B: // DEC HL
- R16( opcode, 4, 0x0B )--;
- goto loop;
-
- case 0x3B: // DEC SP
- sp = uint16_t (sp - 1);
- goto loop;
-
-// AND
- case 0xA6: // AND (HL)
- data = READ( rp.hl );
- goto and_data;
-
- case 0xE6: // AND imm
- pc++;
- goto and_data;
-
- CASE7( A0, A1, A2, A3, A4, A5, A7 ): // AND r
- data = R8( opcode, 0xA0 );
- and_data:
- rg.a &= data;
- flags = SZ28P( rg.a ) | H10;
- goto loop;
-
-// OR
- case 0xB6: // OR (HL)
- data = READ( rp.hl );
- goto or_data;
-
- case 0xF6: // OR imm
- pc++;
- goto or_data;
-
- CASE7( B0, B1, B2, B3, B4, B5, B7 ): // OR r
- data = R8( opcode, 0xB0 );
- or_data:
- rg.a |= data;
- flags = SZ28P( rg.a );
- goto loop;
-
-// XOR
- case 0xAE: // XOR (HL)
- data = READ( rp.hl );
- goto xor_data;
-
- case 0xEE: // XOR imm
- pc++;
- goto xor_data;
-
- CASE7( A8, A9, AA, AB, AC, AD, AF ): // XOR r
- data = R8( opcode, 0xA8 );
- xor_data:
- rg.a ^= data;
- flags = SZ28P( rg.a );
- goto loop;
-
-// LD
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (HL),r
- WRITE( rp.hl, R8( opcode, 0x70 ) );
- goto loop;
-
- CASE6( 41, 42, 43, 44, 45, 47 ): // LD B,r
- CASE6( 48, 4A, 4B, 4C, 4D, 4F ): // LD C,r
- CASE6( 50, 51, 53, 54, 55, 57 ): // LD D,r
- CASE6( 58, 59, 5A, 5C, 5D, 5F ): // LD E,r
- CASE6( 60, 61, 62, 63, 65, 67 ): // LD H,r
- CASE6( 68, 69, 6A, 6B, 6C, 6F ): // LD L,r
- CASE6( 78, 79, 7A, 7B, 7C, 7D ): // LD A,r
- R8( opcode >> 3 & 7, 0 ) = R8( opcode & 7, 0 );
- goto loop;
-
- CASE5( 06, 0E, 16, 1E, 26 ): // LD r,imm
- R8( opcode >> 3, 0 ) = data;
- pc++;
- goto loop;
-
- case 0x36: // LD (HL),imm
- pc++;
- WRITE( rp.hl, data );
- goto loop;
-
- CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(HL)
- R8( opcode >> 3, 8 ) = READ( rp.hl );
- goto loop;
-
- case 0x01: // LD rp,imm
- case 0x11:
- case 0x21:
- R16( opcode, 4, 0x01 ) = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x31: // LD sp,imm
- sp = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x2A:{// LD HL,(addr)
- fuint16 addr = GET_ADDR();
- pc += 2;
- rp.hl = READ_WORD( addr );
- goto loop;
- }
-
- case 0x32:{// LD (addr),A
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE( addr, rg.a );
- goto loop;
- }
-
- case 0x22:{// LD (addr),HL
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, rp.hl );
- goto loop;
- }
-
- case 0x02: // LD (BC),A
- case 0x12: // LD (DE),A
- WRITE( R16( opcode, 4, 0x02 ), rg.a );
- goto loop;
-
- case 0x0A: // LD A,(BC)
- case 0x1A: // LD A,(DE)
- rg.a = READ( R16( opcode, 4, 0x0A ) );
- goto loop;
-
- case 0xF9: // LD SP,HL
- sp = rp.hl;
- goto loop;
-
-// Rotate
-
- case 0x07:{// RLCA
- fuint16 temp = rg.a;
- temp = (temp << 1) | (temp >> 7);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08 | C01));
- rg.a = temp;
- goto loop;
- }
-
- case 0x0F:{// RRCA
- fuint16 temp = rg.a;
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & C01);
- temp = (temp << 7) | (temp >> 1);
- flags |= temp & (F20 | F08);
- rg.a = temp;
- goto loop;
- }
-
- case 0x17:{// RLA
- blargg_ulong temp = (rg.a << 1) | (flags & C01);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08)) |
- (temp >> 8);
- rg.a = temp;
- goto loop;
- }
-
- case 0x1F:{// RRA
- fuint16 temp = (flags << 7) | (rg.a >> 1);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08)) |
- (rg.a & C01);
- rg.a = temp;
- goto loop;
- }
-
-// Misc
- case 0x2F:{// CPL
- fuint16 temp = ~rg.a;
- flags = (flags & (S80 | Z40 | P04 | C01)) |
- (temp & (F20 | F08)) |
- (H10 | N02);
- rg.a = temp;
- goto loop;
- }
-
- case 0x3F:{// CCF
- flags = ((flags & (S80 | Z40 | P04 | C01)) ^ C01) |
- (flags << 4 & H10) |
- (rg.a & (F20 | F08));
- goto loop;
- }
-
- case 0x37: // SCF
- flags = (flags & (S80 | Z40 | P04)) | C01 |
- (rg.a & (F20 | F08));
- goto loop;
-
- case 0xDB: // IN A,(imm)
- pc++;
- rg.a = IN( data + rg.a * 0x100 );
- goto loop;
-
- case 0xE3:{// EX (SP),HL
- fuint16 temp = READ_WORD( sp );
- WRITE_WORD( sp, rp.hl );
- rp.hl = temp;
- goto loop;
- }
-
- case 0xEB:{// EX DE,HL
- fuint16 temp = rp.hl;
- rp.hl = rp.de;
- rp.de = temp;
- goto loop;
- }
-
- case 0xD9:{// EXX DE,HL
- fuint16 temp = r.alt.w.bc;
- r.alt.w.bc = rp.bc;
- rp.bc = temp;
-
- temp = r.alt.w.de;
- r.alt.w.de = rp.de;
- rp.de = temp;
-
- temp = r.alt.w.hl;
- r.alt.w.hl = rp.hl;
- rp.hl = temp;
- goto loop;
- }
-
- case 0xF3: // DI
- r.iff1 = 0;
- r.iff2 = 0;
- goto loop;
-
- case 0xFB: // EI
- r.iff1 = 1;
- r.iff2 = 1;
- // TODO: delayed effect
- goto loop;
-
- case 0x76: // HALT
- goto halt;
-
-//////////////////////////////////////// CB prefix
- {
- case 0xCB:
- pc++;
- switch ( data )
- {
-
- // Rotate left
-
- #define RLC( read, write ) {\
- fuint8 result = read;\
- result = uint8_t (result << 1) | (result >> 7);\
- flags = SZ28P( result ) | (result & C01);\
- write;\
- goto loop;\
- }
-
- case 0x06: // RLC (HL)
- s_time += 7;
- data = rp.hl;
- rlc_data_addr:
- RLC( READ( data ), WRITE( data, result ) )
-
- CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r
- uint8_t& reg = R8( data, 0 );
- RLC( reg, reg = result )
- }
-
- #define RL( read, write ) {\
- fuint16 result = (read << 1) | (flags & C01);\
- flags = SZ28PC( result );\
- write;\
- goto loop;\
- }
-
- case 0x16: // RL (HL)
- s_time += 7;
- data = rp.hl;
- rl_data_addr:
- RL( READ( data ), WRITE( data, result ) )
-
- CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r
- uint8_t& reg = R8( data, 0x10 );
- RL( reg, reg = result )
- }
-
- #define SLA( read, add, write ) {\
- fuint16 result = (read << 1) | add;\
- flags = SZ28PC( result );\
- write;\
- goto loop;\
- }
-
- case 0x26: // SLA (HL)
- s_time += 7;
- data = rp.hl;
- sla_data_addr:
- SLA( READ( data ), 0, WRITE( data, result ) )
-
- CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r
- uint8_t& reg = R8( data, 0x20 );
- SLA( reg, 0, reg = result )
- }
-
- case 0x36: // SLL (HL)
- s_time += 7;
- data = rp.hl;
- sll_data_addr:
- SLA( READ( data ), 1, WRITE( data, result ) )
-
- CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r
- uint8_t& reg = R8( data, 0x30 );
- SLA( reg, 1, reg = result )
- }
-
- // Rotate right
-
- #define RRC( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result = uint8_t (result << 7) | (result >> 1);\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x0E: // RRC (HL)
- s_time += 7;
- data = rp.hl;
- rrc_data_addr:
- RRC( READ( data ), WRITE( data, result ) )
-
- CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r
- uint8_t& reg = R8( data, 0x08 );
- RRC( reg, reg = result )
- }
-
- #define RR( read, write ) {\
- fuint8 result = read;\
- fuint8 temp = result & C01;\
- result = uint8_t (flags << 7) | (result >> 1);\
- flags = SZ28P( result ) | temp;\
- write;\
- goto loop;\
- }
-
- case 0x1E: // RR (HL)
- s_time += 7;
- data = rp.hl;
- rr_data_addr:
- RR( READ( data ), WRITE( data, result ) )
-
- CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r
- uint8_t& reg = R8( data, 0x18 );
- RR( reg, reg = result )
- }
-
- #define SRA( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result = (result & 0x80) | (result >> 1);\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x2E: // SRA (HL)
- data = rp.hl;
- s_time += 7;
- sra_data_addr:
- SRA( READ( data ), WRITE( data, result ) )
-
- CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r
- uint8_t& reg = R8( data, 0x28 );
- SRA( reg, reg = result )
- }
-
- #define SRL( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result >>= 1;\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x3E: // SRL (HL)
- s_time += 7;
- data = rp.hl;
- srl_data_addr:
- SRL( READ( data ), WRITE( data, result ) )
-
- CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r
- uint8_t& reg = R8( data, 0x38 );
- SRL( reg, reg = result )
- }
-
- // BIT
- {
- unsigned temp;
- CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL)
- s_time += 4;
- temp = READ( rp.hl );
- flags &= C01;
- goto bit_temp;
- CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r
- CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r
- CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r
- CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r
- CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r
- CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r
- CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r
- temp = R8( data & 7, 0 );
- flags = (flags & C01) | (temp & (F20 | F08));
- bit_temp:
- int masked = temp & 1 << (data >> 3 & 7);
- flags |=(masked & S80) | H10 |
- ((masked - 1) >> 8 & (Z40 | P04));
- goto loop;
- }
-
- // SET/RES
- CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL)
- CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL)
- s_time += 7;
- int temp = READ( rp.hl );
- int bit = 1 << (data >> 3 & 7);
- temp |= bit; // SET
- if ( !(data & 0x40) )
- temp ^= bit; // RES
- WRITE( rp.hl, temp );
- goto loop;
- }
-
- CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r
- CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r
- CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r
- CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r
- CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r
- CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r
- CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r
- CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r
- R8( data & 7, 0 ) |= 1 << (data >> 3 & 7);
- goto loop;
-
- CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r
- CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r
- CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r
- CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r
- CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r
- CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r
- CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r
- CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r
- R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7));
- goto loop;
- }
- assert( false );
- }
-
-#undef GET_ADDR
-#define GET_ADDR() GET_LE16( instr + 1 )
-
-//////////////////////////////////////// ED prefix
- {
- case 0xED:
- pc++;
- s_time += ed_dd_timing [data] >> 4;
- switch ( data )
- {
- {
- blargg_ulong temp;
- case 0x72: // SBC HL,SP
- case 0x7A: // ADC HL,SP
- temp = sp;
- if ( 0 )
- case 0x42: // SBC HL,BC
- case 0x52: // SBC HL,DE
- case 0x62: // SBC HL,HL
- case 0x4A: // ADC HL,BC
- case 0x5A: // ADC HL,DE
- case 0x6A: // ADC HL,HL
- temp = R16( data >> 3 & 6, 1, 0 );
- blargg_ulong sum = temp + (flags & C01);
- flags = ~data >> 2 & N02;
- if ( flags )
- sum = -sum;
- sum += rp.hl;
- temp ^= rp.hl;
- temp ^= sum;
- flags |=(sum >> 16 & C01) |
- (temp >> 8 & H10) |
- (sum >> 8 & (S80 | F20 | F08)) |
- ((temp - -0x8000) >> 14 & V04);
- rp.hl = sum;
- if ( (uint16_t) sum )
- goto loop;
- flags |= Z40;
- goto loop;
- }
-
- CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C)
- int temp = IN( rp.bc );
- R8( data >> 3, 8 ) = temp;
- flags = (flags & C01) | SZ28P( temp );
- goto loop;
- }
-
- case 0x71: // OUT (C),0
- rg.flags = 0;
- CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r
- OUT( rp.bc, R8( data >> 3, 8 ) );
- goto loop;
-
- {
- unsigned temp;
- case 0x73: // LD (ADDR),SP
- temp = sp;
- if ( 0 )
- case 0x43: // LD (ADDR),BC
- case 0x53: // LD (ADDR),DE
- temp = R16( data, 4, 0x43 );
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, temp );
- goto loop;
- }
-
- case 0x4B: // LD BC,(ADDR)
- case 0x5B:{// LD DE,(ADDR)
- fuint16 addr = GET_ADDR();
- pc += 2;
- R16( data, 4, 0x4B ) = READ_WORD( addr );
- goto loop;
- }
-
- case 0x7B:{// LD SP,(ADDR)
- fuint16 addr = GET_ADDR();
- pc += 2;
- sp = READ_WORD( addr );
- goto loop;
- }
-
- case 0x67:{// RRD
- fuint8 temp = READ( rp.hl );
- WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
- temp = (rg.a & 0xF0) | (temp & 0x0F);
- flags = (flags & C01) | SZ28P( temp );
- rg.a = temp;
- goto loop;
- }
-
- case 0x6F:{// RLD
- fuint8 temp = READ( rp.hl );
- WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
- temp = (rg.a & 0xF0) | (temp >> 4);
- flags = (flags & C01) | SZ28P( temp );
- rg.a = temp;
- goto loop;
- }
-
- CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG
- opcode = 0x10; // flag to do SBC instead of ADC
- flags &= ~C01;
- data = rg.a;
- rg.a = 0;
- goto adc_data;
-
- {
- int inc;
- case 0xA9: // CPD
- case 0xB9: // CPDR
- inc = -1;
- if ( 0 )
- case 0xA1: // CPI
- case 0xB1: // CPIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- int result = rg.a - temp;
- flags = (flags & C01) | N02 |
- ((((temp ^ rg.a) & H10) ^ result) & (S80 | H10));
-
- if ( !(uint8_t) result ) flags |= Z40;
- result -= (flags & H10) >> 4;
- flags |= result & F08;
- flags |= result << 4 & F20;
- if ( !--rp.bc )
- goto loop;
-
- flags |= V04;
- if ( flags & Z40 || data < 0xB0 )
- goto loop;
-
- pc -= 2;
- s_time += 5;
- goto loop;
- }
-
- {
- int inc;
- case 0xA8: // LDD
- case 0xB8: // LDDR
- inc = -1;
- if ( 0 )
- case 0xA0: // LDI
- case 0xB0: // LDIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- addr = rp.de;
- rp.de = addr + inc;
- WRITE( addr, temp );
-
- temp += rg.a;
- flags = (flags & (S80 | Z40 | C01)) |
- (temp & F08) | (temp << 4 & F20);
- if ( !--rp.bc )
- goto loop;
-
- flags |= V04;
- if ( data < 0xB0 )
- goto loop;
-
- pc -= 2;
- s_time += 5;
- goto loop;
- }
-
- {
- int inc;
- case 0xAB: // OUTD
- case 0xBB: // OTDR
- inc = -1;
- if ( 0 )
- case 0xA3: // OUTI
- case 0xB3: // OTIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- int b = --rg.b;
- flags = (temp >> 6 & N02) | SZ28( b );
- if ( b && data >= 0xB0 )
- {
- pc -= 2;
- s_time += 5;
- }
-
- OUT( rp.bc, temp );
- goto loop;
- }
-
- {
- int inc;
- case 0xAA: // IND
- case 0xBA: // INDR
- inc = -1;
- if ( 0 )
- case 0xA2: // INI
- case 0xB2: // INIR
- inc = +1;
-
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
-
- int temp = IN( rp.bc );
-
- int b = --rg.b;
- flags = (temp >> 6 & N02) | SZ28( b );
- if ( b && data >= 0xB0 )
- {
- pc -= 2;
- s_time += 5;
- }
-
- WRITE( addr, temp );
- goto loop;
- }
-
- case 0x47: // LD I,A
- r.i = rg.a;
- goto loop;
-
- case 0x4F: // LD R,A
- SET_R( rg.a );
- debug_printf( "LD R,A not supported\n" );
- warning = true;
- goto loop;
-
- case 0x57: // LD A,I
- rg.a = r.i;
- goto ld_ai_common;
-
- case 0x5F: // LD A,R
- rg.a = GET_R();
- debug_printf( "LD A,R not supported\n" );
- warning = true;
- ld_ai_common:
- flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
- goto loop;
-
- CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN
- r.iff1 = r.iff2;
- goto ret_taken;
-
- case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0
- r.im = 0;
- goto loop;
-
- case 0x56: case 0x76: // IM 1
- r.im = 1;
- goto loop;
-
- case 0x5E: case 0x7E: // IM 2
- r.im = 2;
- goto loop;
-
- default:
- debug_printf( "Opcode $ED $%02X not supported\n", data );
- warning = true;
- goto loop;
- }
- assert( false );
- }
-
-//////////////////////////////////////// DD/FD prefix
- {
- fuint16 ixy;
- case 0xDD:
- ixy = ix;
- goto ix_prefix;
- case 0xFD:
- ixy = iy;
- ix_prefix:
- pc++;
- unsigned data2 = READ_PROG( pc );
- s_time += ed_dd_timing [data] & 0x0F;
- switch ( data )
- {
- // TODO: more efficient way of avoid negative address
- // TODO: avoid using this as argument to READ() since it is evaluated twice
- #define IXY_DISP( ixy, disp ) uint16_t ((ixy) + (disp))
-
- #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in;
-
- // ADD/ADC/SUB/SBC
-
- case 0x96: // SUB (IXY+disp)
- case 0x86: // ADD (IXY+disp)
- flags &= ~C01;
- case 0x9E: // SBC (IXY+disp)
- case 0x8E: // ADC (IXY+disp)
- pc++;
- opcode = data;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto adc_data;
-
- case 0x94: // SUB HXY
- case 0x84: // ADD HXY
- flags &= ~C01;
- case 0x9C: // SBC HXY
- case 0x8C: // ADC HXY
- opcode = data;
- data = ixy >> 8;
- goto adc_data;
-
- case 0x95: // SUB LXY
- case 0x85: // ADD LXY
- flags &= ~C01;
- case 0x9D: // SBC LXY
- case 0x8D: // ADC LXY
- opcode = data;
- data = (uint8_t) ixy;
- goto adc_data;
-
- {
- unsigned temp;
- case 0x39: // ADD IXY,SP
- temp = sp;
- goto add_ixy_data;
-
- case 0x29: // ADD IXY,HL
- temp = ixy;
- goto add_ixy_data;
-
- case 0x09: // ADD IXY,BC
- case 0x19: // ADD IXY,DE
- temp = R16( data, 4, 0x09 );
- add_ixy_data: {
- blargg_ulong sum = ixy + temp;
- temp ^= ixy;
- ixy = (uint16_t) sum;
- flags = (flags & (S80 | Z40 | V04)) |
- (sum >> 16) |
- (sum >> 8 & (F20 | F08)) |
- ((temp ^ sum) >> 8 & H10);
- goto set_ixy;
- }
- }
-
- // AND
- case 0xA6: // AND (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto and_data;
-
- case 0xA4: // AND HXY
- data = ixy >> 8;
- goto and_data;
-
- case 0xA5: // AND LXY
- data = (uint8_t) ixy;
- goto and_data;
-
- // OR
- case 0xB6: // OR (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto or_data;
-
- case 0xB4: // OR HXY
- data = ixy >> 8;
- goto or_data;
-
- case 0xB5: // OR LXY
- data = (uint8_t) ixy;
- goto or_data;
-
- // XOR
- case 0xAE: // XOR (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto xor_data;
-
- case 0xAC: // XOR HXY
- data = ixy >> 8;
- goto xor_data;
-
- case 0xAD: // XOR LXY
- data = (uint8_t) ixy;
- goto xor_data;
-
- // CP
- case 0xBE: // CP (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto cp_data;
-
- case 0xBC: // CP HXY
- data = ixy >> 8;
- goto cp_data;
-
- case 0xBD: // CP LXY
- data = (uint8_t) ixy;
- goto cp_data;
-
- // LD
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r
- data = R8( data, 0x70 );
- if ( 0 )
- case 0x36: // LD (IXY+disp),imm
- pc++, data = READ_PROG( pc );
- pc++;
- WRITE( IXY_DISP( ixy, (int8_t) data2 ), data );
- goto loop;
-
- CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY
- R8( data >> 3, 8 ) = ixy >> 8;
- goto loop;
-
- case 0x64: // LD HXY,HXY
- case 0x6D: // LD LXY,LXY
- goto loop;
-
- CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY
- R8( data >> 3, 8 ) = ixy;
- goto loop;
-
- CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp)
- pc++;
- R8( data >> 3, 8 ) = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto loop;
-
- case 0x26: // LD HXY,imm
- pc++;
- goto ld_hxy_data;
-
- case 0x65: // LD HXY,LXY
- data2 = (uint8_t) ixy;
- goto ld_hxy_data;
-
- CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r
- data2 = R8( data, 0x60 );
- ld_hxy_data:
- ixy = (uint8_t) ixy | (data2 << 8);
- goto set_ixy;
-
- case 0x2E: // LD LXY,imm
- pc++;
- goto ld_lxy_data;
-
- case 0x6C: // LD LXY,HXY
- data2 = ixy >> 8;
- goto ld_lxy_data;
-
- CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r
- data2 = R8( data, 0x68 );
- ld_lxy_data:
- ixy = (ixy & 0xFF00) | data2;
- set_ixy:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto loop;
- }
- iy = ixy;
- goto loop;
-
- case 0xF9: // LD SP,IXY
- sp = ixy;
- goto loop;
-
- case 0x22:{// LD (ADDR),IXY
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, ixy );
- goto loop;
- }
-
- case 0x21: // LD IXY,imm
- ixy = GET_ADDR();
- pc += 2;
- goto set_ixy;
-
- case 0x2A:{// LD IXY,(addr)
- fuint16 addr = GET_ADDR();
- ixy = READ_WORD( addr );
- pc += 2;
- goto set_ixy;
- }
-
- // DD/FD CB prefix
- case 0xCB: {
- data = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data2 = READ_PROG( pc );
- pc++;
- switch ( data2 )
- {
- case 0x06: goto rlc_data_addr; // RLC (IXY)
- case 0x16: goto rl_data_addr; // RL (IXY)
- case 0x26: goto sla_data_addr; // SLA (IXY)
- case 0x36: goto sll_data_addr; // SLL (IXY)
- case 0x0E: goto rrc_data_addr; // RRC (IXY)
- case 0x1E: goto rr_data_addr; // RR (IXY)
- case 0x2E: goto sra_data_addr; // SRA (IXY)
- case 0x3E: goto srl_data_addr; // SRL (IXY)
-
- CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
- fuint8 temp = READ( data );
- int masked = temp & 1 << (data2 >> 3 & 7);
- flags = (flags & C01) | H10 |
- (masked & S80) |
- ((masked - 1) >> 8 & (Z40 | P04));
- goto loop;
- }
-
- CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp)
- CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp)
- int temp = READ( data );
- int bit = 1 << (data2 >> 3 & 7);
- temp |= bit; // SET
- if ( !(data2 & 0x40) )
- temp ^= bit; // RES
- WRITE( data, temp );
- goto loop;
- }
-
- default:
- debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
- warning = true;
- goto loop;
- }
- assert( false );
- }
-
- // INC/DEC
- case 0x23: // INC IXY
- ixy = uint16_t (ixy + 1);
- goto set_ixy;
-
- case 0x2B: // DEC IXY
- ixy = uint16_t (ixy - 1);
- goto set_ixy;
-
- case 0x34: // INC (IXY+disp)
- ixy = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data = READ( ixy ) + 1;
- WRITE( ixy, data );
- goto inc_set_flags;
-
- case 0x35: // DEC (IXY+disp)
- ixy = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data = READ( ixy ) - 1;
- WRITE( ixy, data );
- goto dec_set_flags;
-
- case 0x24: // INC HXY
- ixy = uint16_t (ixy + 0x100);
- data = ixy >> 8;
- goto inc_xy_common;
-
- case 0x2C: // INC LXY
- data = uint8_t (ixy + 1);
- ixy = (ixy & 0xFF00) | data;
- inc_xy_common:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto inc_set_flags;
- }
- iy = ixy;
- goto inc_set_flags;
-
- case 0x25: // DEC HXY
- ixy = uint16_t (ixy - 0x100);
- data = ixy >> 8;
- goto dec_xy_common;
-
- case 0x2D: // DEC LXY
- data = uint8_t (ixy - 1);
- ixy = (ixy & 0xFF00) | data;
- dec_xy_common:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto dec_set_flags;
- }
- iy = ixy;
- goto dec_set_flags;
-
- // PUSH/POP
- case 0xE5: // PUSH IXY
- data = ixy;
- goto push_data;
-
- case 0xE1:{// POP IXY
- ixy = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto set_ixy;
- }
-
- // Misc
-
- case 0xE9: // JP (IXY)
- pc = ixy;
- goto loop;
-
- case 0xE3:{// EX (SP),IXY
- fuint16 temp = READ_WORD( sp );
- WRITE_WORD( sp, ixy );
- ixy = temp;
- goto set_ixy;
- }
-
- default:
- debug_printf( "Unnecessary DD/FD prefix encountered\n" );
- warning = true;
- pc--;
- goto loop;
- }
- assert( false );
- }
-
- }
- debug_printf( "Unhandled main opcode: $%02X\n", opcode );
- assert( false );
-
-hit_idle_addr:
- s_time -= 11;
- goto out_of_time;
-halt:
- s_time &= 3; // increment by multiple of 4
-out_of_time:
- pc--;
-
- s.time = s_time;
- rg.flags = flags;
- r.ix = ix;
- r.iy = iy;
- r.sp = sp;
- r.pc = pc;
- this->r.b = rg;
- this->state_ = s;
- this->state = &this->state_;
-
- return warning;
-}
diff --git a/src/console/Kss_Emu.cc b/src/console/Kss_Emu.cc
new file mode 100644
index 000000000000..1de2361e67f0
--- /dev/null
+++ b/src/console/Kss_Emu.cc
@@ -0,0 +1,416 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Kss_Emu.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+long const clock_rate = 3579545;
+int const osc_count = Ay_Apu::osc_count + Scc_Apu::osc_count;
+
+Kss_Emu::Kss_Emu()
+{
+ sn = 0;
+ set_type( gme_kss_type );
+ set_silence_lookahead( 6 );
+ static const char* const names [osc_count] = {
+ "Square 1", "Square 2", "Square 3",
+ "Wave 1", "Wave 2", "Wave 3", "Wave 4", "Wave 5"
+ };
+ set_voice_names( names );
+
+ static int const types [osc_count] = {
+ wave_type | 0, wave_type | 1, wave_type | 2,
+ wave_type | 3, wave_type | 4, wave_type | 5, wave_type | 6, wave_type | 7
+ };
+ set_voice_types( types );
+
+ memset( unmapped_read, 0xFF, sizeof unmapped_read );
+}
+
+Kss_Emu::~Kss_Emu() { unload(); }
+
+void Kss_Emu::unload()
+{
+ delete sn;
+ sn = 0;
+ Classic_Emu::unload();
+}
+
+// Track info
+
+static void copy_kss_fields( Kss_Emu::header_t const& h, track_info_t* out )
+{
+ const char* system = "MSX";
+ if ( h.device_flags & 0x02 )
+ {
+ system = "Sega Master System";
+ if ( h.device_flags & 0x04 )
+ system = "Game Gear";
+ }
+ Gme_File::copy_field_( out->system, system );
+}
+
+blargg_err_t Kss_Emu::track_info_( track_info_t* out, int ) const
+{
+ copy_kss_fields( header_, out );
+ return 0;
+}
+
+static blargg_err_t check_kss_header( void const* header )
+{
+ if ( memcmp( header, "KSCC", 4 ) && memcmp( header, "KSSX", 4 ) )
+ return gme_wrong_file_type;
+ return 0;
+}
+
+struct Kss_File : Gme_Info_
+{
+ Kss_Emu::header_t header_;
+
+ Kss_File() { set_type( gme_kss_type ); }
+
+ blargg_err_t load_( Data_Reader& in )
+ {
+ blargg_err_t err = in.read( &header_, Kss_Emu::header_size );
+ if ( err )
+ return (err == in.eof_error ? gme_wrong_file_type : err);
+ return check_kss_header( &header_ );
+ }
+
+ blargg_err_t track_info_( track_info_t* out, int ) const
+ {
+ copy_kss_fields( header_, out );
+ return 0;
+ }
+};
+
+static Music_Emu* new_kss_emu () { return BLARGG_NEW Kss_Emu ; }
+static Music_Emu* new_kss_file() { return BLARGG_NEW Kss_File; }
+
+static gme_type_t_ const gme_kss_type_ = { "MSX", 256, &new_kss_emu, &new_kss_file, "KSS", 0x03 };
+gme_type_t const gme_kss_type = &gme_kss_type_;
+
+
+// Setup
+
+void Kss_Emu::update_gain()
+{
+ double g = gain() * 1.4;
+ if ( scc_accessed )
+ g *= 1.5;
+ ay.volume( g );
+ scc.volume( g );
+ if ( sn )
+ sn->volume( g );
+}
+
+blargg_err_t Kss_Emu::load_( Data_Reader& in )
+{
+ memset( &header_, 0, sizeof header_ );
+ assert( offsetof (header_t,device_flags) == header_size - 1 );
+ assert( offsetof (ext_header_t,msx_audio_vol) == ext_header_size - 1 );
+ RETURN_ERR( rom.load( in, header_size, STATIC_CAST(header_t*,&header_), 0 ) );
+
+ RETURN_ERR( check_kss_header( header_.tag ) );
+
+ if ( header_.tag [3] == 'C' )
+ {
+ if ( header_.extra_header )
+ {
+ header_.extra_header = 0;
+ set_warning( "Unknown data in header" );
+ }
+ if ( header_.device_flags & ~0x0F )
+ {
+ header_.device_flags &= 0x0F;
+ set_warning( "Unknown data in header" );
+ }
+ }
+ else
+ {
+ ext_header_t& ext = header_;
+ memcpy( &ext, rom.begin(), min( (int) ext_header_size, (int) header_.extra_header ) );
+ if ( header_.extra_header > 0x10 )
+ set_warning( "Unknown data in header" );
+ }
+
+ if ( header_.device_flags & 0x09 )
+ set_warning( "FM sound not supported" );
+
+ scc_enabled = 0xC000;
+ if ( header_.device_flags & 0x04 )
+ scc_enabled = 0;
+
+ if ( header_.device_flags & 0x02 && !sn )
+ CHECK_ALLOC( sn = BLARGG_NEW( Sms_Apu ) );
+
+ set_voice_count( osc_count );
+
+ return setup_buffer( ::clock_rate );
+}
+
+void Kss_Emu::update_eq( blip_eq_t const& eq )
+{
+ ay.treble_eq( eq );
+ scc.treble_eq( eq );
+ if ( sn )
+ sn->treble_eq( eq );
+}
+
+void Kss_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
+{
+ int i2 = i - ay.osc_count;
+ if ( i2 >= 0 )
+ scc.osc_output( i2, center );
+ else
+ ay.osc_output( i, center );
+ if ( sn && i < sn->osc_count )
+ sn->osc_output( i, center, left, right );
+}
+
+// Emulation
+
+void Kss_Emu::set_tempo_( double t )
+{
+ blip_time_t period =
+ (header_.device_flags & 0x40 ? ::clock_rate / 50 : ::clock_rate / 60);
+ play_period = blip_time_t (period / t);
+}
+
+blargg_err_t Kss_Emu::start_track_( int track )
+{
+ RETURN_ERR( Classic_Emu::start_track_( track ) );
+
+ memset( ram, 0xC9, 0x4000 );
+ memset( ram + 0x4000, 0, sizeof ram - 0x4000 );
+
+ // copy driver code to lo RAM
+ static byte const bios [] = {
+ 0xD3, 0xA0, 0xF5, 0x7B, 0xD3, 0xA1, 0xF1, 0xC9, // $0001: WRTPSG
+ 0xD3, 0xA0, 0xDB, 0xA2, 0xC9 // $0009: RDPSG
+ };
+ static byte const vectors [] = {
+ 0xC3, 0x01, 0x00, // $0093: WRTPSG vector
+ 0xC3, 0x09, 0x00, // $0096: RDPSG vector
+ };
+ memcpy( ram + 0x01, bios, sizeof bios );
+ memcpy( ram + 0x93, vectors, sizeof vectors );
+
+ // copy non-banked data into RAM
+ unsigned load_addr = GET_LE16( header_.load_addr );
+ long orig_load_size = GET_LE16( header_.load_size );
+ long load_size = min( orig_load_size, rom.file_size() );
+ load_size = min( load_size, long (mem_size - load_addr) );
+ if ( load_size != orig_load_size )
+ set_warning( "Excessive data size" );
+ memcpy( ram + load_addr, rom.begin() + header_.extra_header, load_size );
+
+ rom.set_addr( -load_size - header_.extra_header );
+
+ // check available bank data
+ blargg_long const bank_size = this->bank_size();
+ int max_banks = (rom.file_size() - load_size + bank_size - 1) / bank_size;
+ bank_count = header_.bank_mode & 0x7F;
+ if ( bank_count > max_banks )
+ {
+ bank_count = max_banks;
+ set_warning( "Bank data missing" );
+ }
+ //debug_printf( "load_size : $%X\n", load_size );
+ //debug_printf( "bank_size : $%X\n", bank_size );
+ //debug_printf( "bank_count: %d (%d claimed)\n", bank_count, header_.bank_mode & 0x7F );
+
+ ram [idle_addr] = 0xFF;
+ cpu::reset( unmapped_write, unmapped_read );
+ cpu::map_mem( 0, mem_size, ram, ram );
+
+ ay.reset();
+ scc.reset();
+ if ( sn )
+ sn->reset();
+ r.sp = 0xF380;
+ ram [--r.sp] = idle_addr >> 8;
+ ram [--r.sp] = idle_addr & 0xFF;
+ r.b.a = track;
+ r.pc = GET_LE16( header_.init_addr );
+ next_play = play_period;
+ scc_accessed = false;
+ gain_updated = false;
+ update_gain();
+ ay_latch = 0;
+
+ return 0;
+}
+
+void Kss_Emu::set_bank( int logical, int physical )
+{
+ unsigned const bank_size = this->bank_size();
+
+ unsigned addr = 0x8000;
+ if ( logical && bank_size == 8 * 1024 )
+ addr = 0xA000;
+
+ physical -= header_.first_bank;
+ if ( (unsigned) physical >= (unsigned) bank_count )
+ {
+ byte* data = ram + addr;
+ cpu::map_mem( addr, bank_size, data, data );
+ }
+ else
+ {
+ long phys = physical * (blargg_long) bank_size;
+ for ( unsigned offset = 0; offset < bank_size; offset += page_size )
+ cpu::map_mem( addr + offset, page_size,
+ unmapped_write, rom.at_addr( phys + offset ) );
+ }
+}
+
+void Kss_Emu::cpu_write( unsigned addr, int data )
+{
+ data &= 0xFF;
+ switch ( addr )
+ {
+ case 0x9000:
+ set_bank( 0, data );
+ return;
+
+ case 0xB000:
+ set_bank( 1, data );
+ return;
+ }
+
+ int scc_addr = (addr & 0xDFFF) ^ 0x9800;
+ if ( scc_addr < scc.reg_count )
+ {
+ scc_accessed = true;
+ scc.write( time(), scc_addr, data );
+ return;
+ }
+
+ debug_printf( "LD ($%04X),$%02X\n", addr, data );
+}
+
+void kss_cpu_write( Kss_Cpu* cpu, unsigned addr, int data )
+{
+ *cpu->write( addr ) = data;
+ if ( (addr & STATIC_CAST(Kss_Emu&,*cpu).scc_enabled) == 0x8000 )
+ STATIC_CAST(Kss_Emu&,*cpu).cpu_write( addr, data );
+}
+
+void kss_cpu_out( Kss_Cpu* cpu, cpu_time_t time, unsigned addr, int data )
+{
+ data &= 0xFF;
+ Kss_Emu& emu = STATIC_CAST(Kss_Emu&,*cpu);
+ switch ( addr & 0xFF )
+ {
+ case 0xA0:
+ emu.ay_latch = data & 0x0F;
+ return;
+
+ case 0xA1:
+ GME_APU_HOOK( &emu, emu.ay_latch, data );
+ emu.ay.write( time, emu.ay_latch, data );
+ return;
+
+ case 0x06:
+ if ( emu.sn && (emu.header_.device_flags & 0x04) )
+ {
+ emu.sn->write_ggstereo( time, data );
+ return;
+ }
+ break;
+
+ case 0x7E:
+ case 0x7F:
+ if ( emu.sn )
+ {
+ GME_APU_HOOK( &emu, 16, data );
+ emu.sn->write_data( time, data );
+ return;
+ }
+ break;
+
+ case 0xFE:
+ emu.set_bank( 0, data );
+ return;
+
+ #ifndef NDEBUG
+ case 0xF1: // FM data
+ if ( data )
+ break; // trap non-zero data
+ case 0xF0: // FM addr
+ case 0xA8: // PPI
+ return;
+ #endif
+ }
+
+ debug_printf( "OUT $%04X,$%02X\n", addr, data );
+}
+
+int kss_cpu_in( Kss_Cpu*, cpu_time_t, unsigned addr )
+{
+ //Kss_Emu& emu = STATIC_CAST(Kss_Emu&,*cpu);
+ //switch ( addr & 0xFF )
+ //{
+ //}
+
+ debug_printf( "IN $%04X\n", addr );
+ return 0;
+}
+
+// Emulation
+
+blargg_err_t Kss_Emu::run_clocks( blip_time_t& duration, int )
+{
+ while ( time() < duration )
+ {
+ blip_time_t end = min( duration, next_play );
+ cpu::run( min( duration, next_play ) );
+ if ( r.pc == idle_addr )
+ set_time( end );
+
+ if ( time() >= next_play )
+ {
+ next_play += play_period;
+ if ( r.pc == idle_addr )
+ {
+ if ( !gain_updated )
+ {
+ gain_updated = true;
+ if ( scc_accessed )
+ update_gain();
+ }
+
+ ram [--r.sp] = idle_addr >> 8;
+ ram [--r.sp] = idle_addr & 0xFF;
+ r.pc = GET_LE16( header_.play_addr );
+ GME_FRAME_HOOK( this );
+ }
+ }
+ }
+
+ duration = time();
+ next_play -= duration;
+ check( next_play >= 0 );
+ adjust_time( -duration );
+ ay.end_frame( duration );
+ scc.end_frame( duration );
+ if ( sn )
+ sn->end_frame( duration );
+
+ return 0;
+}
diff --git a/src/console/Kss_Emu.cxx b/src/console/Kss_Emu.cxx
deleted file mode 100644
index 1de2361e67f0..000000000000
--- a/src/console/Kss_Emu.cxx
+++ /dev/null
@@ -1,416 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Kss_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-long const clock_rate = 3579545;
-int const osc_count = Ay_Apu::osc_count + Scc_Apu::osc_count;
-
-Kss_Emu::Kss_Emu()
-{
- sn = 0;
- set_type( gme_kss_type );
- set_silence_lookahead( 6 );
- static const char* const names [osc_count] = {
- "Square 1", "Square 2", "Square 3",
- "Wave 1", "Wave 2", "Wave 3", "Wave 4", "Wave 5"
- };
- set_voice_names( names );
-
- static int const types [osc_count] = {
- wave_type | 0, wave_type | 1, wave_type | 2,
- wave_type | 3, wave_type | 4, wave_type | 5, wave_type | 6, wave_type | 7
- };
- set_voice_types( types );
-
- memset( unmapped_read, 0xFF, sizeof unmapped_read );
-}
-
-Kss_Emu::~Kss_Emu() { unload(); }
-
-void Kss_Emu::unload()
-{
- delete sn;
- sn = 0;
- Classic_Emu::unload();
-}
-
-// Track info
-
-static void copy_kss_fields( Kss_Emu::header_t const& h, track_info_t* out )
-{
- const char* system = "MSX";
- if ( h.device_flags & 0x02 )
- {
- system = "Sega Master System";
- if ( h.device_flags & 0x04 )
- system = "Game Gear";
- }
- Gme_File::copy_field_( out->system, system );
-}
-
-blargg_err_t Kss_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_kss_fields( header_, out );
- return 0;
-}
-
-static blargg_err_t check_kss_header( void const* header )
-{
- if ( memcmp( header, "KSCC", 4 ) && memcmp( header, "KSSX", 4 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Kss_File : Gme_Info_
-{
- Kss_Emu::header_t header_;
-
- Kss_File() { set_type( gme_kss_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- blargg_err_t err = in.read( &header_, Kss_Emu::header_size );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
- return check_kss_header( &header_ );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_kss_fields( header_, out );
- return 0;
- }
-};
-
-static Music_Emu* new_kss_emu () { return BLARGG_NEW Kss_Emu ; }
-static Music_Emu* new_kss_file() { return BLARGG_NEW Kss_File; }
-
-static gme_type_t_ const gme_kss_type_ = { "MSX", 256, &new_kss_emu, &new_kss_file, "KSS", 0x03 };
-gme_type_t const gme_kss_type = &gme_kss_type_;
-
-
-// Setup
-
-void Kss_Emu::update_gain()
-{
- double g = gain() * 1.4;
- if ( scc_accessed )
- g *= 1.5;
- ay.volume( g );
- scc.volume( g );
- if ( sn )
- sn->volume( g );
-}
-
-blargg_err_t Kss_Emu::load_( Data_Reader& in )
-{
- memset( &header_, 0, sizeof header_ );
- assert( offsetof (header_t,device_flags) == header_size - 1 );
- assert( offsetof (ext_header_t,msx_audio_vol) == ext_header_size - 1 );
- RETURN_ERR( rom.load( in, header_size, STATIC_CAST(header_t*,&header_), 0 ) );
-
- RETURN_ERR( check_kss_header( header_.tag ) );
-
- if ( header_.tag [3] == 'C' )
- {
- if ( header_.extra_header )
- {
- header_.extra_header = 0;
- set_warning( "Unknown data in header" );
- }
- if ( header_.device_flags & ~0x0F )
- {
- header_.device_flags &= 0x0F;
- set_warning( "Unknown data in header" );
- }
- }
- else
- {
- ext_header_t& ext = header_;
- memcpy( &ext, rom.begin(), min( (int) ext_header_size, (int) header_.extra_header ) );
- if ( header_.extra_header > 0x10 )
- set_warning( "Unknown data in header" );
- }
-
- if ( header_.device_flags & 0x09 )
- set_warning( "FM sound not supported" );
-
- scc_enabled = 0xC000;
- if ( header_.device_flags & 0x04 )
- scc_enabled = 0;
-
- if ( header_.device_flags & 0x02 && !sn )
- CHECK_ALLOC( sn = BLARGG_NEW( Sms_Apu ) );
-
- set_voice_count( osc_count );
-
- return setup_buffer( ::clock_rate );
-}
-
-void Kss_Emu::update_eq( blip_eq_t const& eq )
-{
- ay.treble_eq( eq );
- scc.treble_eq( eq );
- if ( sn )
- sn->treble_eq( eq );
-}
-
-void Kss_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- int i2 = i - ay.osc_count;
- if ( i2 >= 0 )
- scc.osc_output( i2, center );
- else
- ay.osc_output( i, center );
- if ( sn && i < sn->osc_count )
- sn->osc_output( i, center, left, right );
-}
-
-// Emulation
-
-void Kss_Emu::set_tempo_( double t )
-{
- blip_time_t period =
- (header_.device_flags & 0x40 ? ::clock_rate / 50 : ::clock_rate / 60);
- play_period = blip_time_t (period / t);
-}
-
-blargg_err_t Kss_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( ram, 0xC9, 0x4000 );
- memset( ram + 0x4000, 0, sizeof ram - 0x4000 );
-
- // copy driver code to lo RAM
- static byte const bios [] = {
- 0xD3, 0xA0, 0xF5, 0x7B, 0xD3, 0xA1, 0xF1, 0xC9, // $0001: WRTPSG
- 0xD3, 0xA0, 0xDB, 0xA2, 0xC9 // $0009: RDPSG
- };
- static byte const vectors [] = {
- 0xC3, 0x01, 0x00, // $0093: WRTPSG vector
- 0xC3, 0x09, 0x00, // $0096: RDPSG vector
- };
- memcpy( ram + 0x01, bios, sizeof bios );
- memcpy( ram + 0x93, vectors, sizeof vectors );
-
- // copy non-banked data into RAM
- unsigned load_addr = GET_LE16( header_.load_addr );
- long orig_load_size = GET_LE16( header_.load_size );
- long load_size = min( orig_load_size, rom.file_size() );
- load_size = min( load_size, long (mem_size - load_addr) );
- if ( load_size != orig_load_size )
- set_warning( "Excessive data size" );
- memcpy( ram + load_addr, rom.begin() + header_.extra_header, load_size );
-
- rom.set_addr( -load_size - header_.extra_header );
-
- // check available bank data
- blargg_long const bank_size = this->bank_size();
- int max_banks = (rom.file_size() - load_size + bank_size - 1) / bank_size;
- bank_count = header_.bank_mode & 0x7F;
- if ( bank_count > max_banks )
- {
- bank_count = max_banks;
- set_warning( "Bank data missing" );
- }
- //debug_printf( "load_size : $%X\n", load_size );
- //debug_printf( "bank_size : $%X\n", bank_size );
- //debug_printf( "bank_count: %d (%d claimed)\n", bank_count, header_.bank_mode & 0x7F );
-
- ram [idle_addr] = 0xFF;
- cpu::reset( unmapped_write, unmapped_read );
- cpu::map_mem( 0, mem_size, ram, ram );
-
- ay.reset();
- scc.reset();
- if ( sn )
- sn->reset();
- r.sp = 0xF380;
- ram [--r.sp] = idle_addr >> 8;
- ram [--r.sp] = idle_addr & 0xFF;
- r.b.a = track;
- r.pc = GET_LE16( header_.init_addr );
- next_play = play_period;
- scc_accessed = false;
- gain_updated = false;
- update_gain();
- ay_latch = 0;
-
- return 0;
-}
-
-void Kss_Emu::set_bank( int logical, int physical )
-{
- unsigned const bank_size = this->bank_size();
-
- unsigned addr = 0x8000;
- if ( logical && bank_size == 8 * 1024 )
- addr = 0xA000;
-
- physical -= header_.first_bank;
- if ( (unsigned) physical >= (unsigned) bank_count )
- {
- byte* data = ram + addr;
- cpu::map_mem( addr, bank_size, data, data );
- }
- else
- {
- long phys = physical * (blargg_long) bank_size;
- for ( unsigned offset = 0; offset < bank_size; offset += page_size )
- cpu::map_mem( addr + offset, page_size,
- unmapped_write, rom.at_addr( phys + offset ) );
- }
-}
-
-void Kss_Emu::cpu_write( unsigned addr, int data )
-{
- data &= 0xFF;
- switch ( addr )
- {
- case 0x9000:
- set_bank( 0, data );
- return;
-
- case 0xB000:
- set_bank( 1, data );
- return;
- }
-
- int scc_addr = (addr & 0xDFFF) ^ 0x9800;
- if ( scc_addr < scc.reg_count )
- {
- scc_accessed = true;
- scc.write( time(), scc_addr, data );
- return;
- }
-
- debug_printf( "LD ($%04X),$%02X\n", addr, data );
-}
-
-void kss_cpu_write( Kss_Cpu* cpu, unsigned addr, int data )
-{
- *cpu->write( addr ) = data;
- if ( (addr & STATIC_CAST(Kss_Emu&,*cpu).scc_enabled) == 0x8000 )
- STATIC_CAST(Kss_Emu&,*cpu).cpu_write( addr, data );
-}
-
-void kss_cpu_out( Kss_Cpu* cpu, cpu_time_t time, unsigned addr, int data )
-{
- data &= 0xFF;
- Kss_Emu& emu = STATIC_CAST(Kss_Emu&,*cpu);
- switch ( addr & 0xFF )
- {
- case 0xA0:
- emu.ay_latch = data & 0x0F;
- return;
-
- case 0xA1:
- GME_APU_HOOK( &emu, emu.ay_latch, data );
- emu.ay.write( time, emu.ay_latch, data );
- return;
-
- case 0x06:
- if ( emu.sn && (emu.header_.device_flags & 0x04) )
- {
- emu.sn->write_ggstereo( time, data );
- return;
- }
- break;
-
- case 0x7E:
- case 0x7F:
- if ( emu.sn )
- {
- GME_APU_HOOK( &emu, 16, data );
- emu.sn->write_data( time, data );
- return;
- }
- break;
-
- case 0xFE:
- emu.set_bank( 0, data );
- return;
-
- #ifndef NDEBUG
- case 0xF1: // FM data
- if ( data )
- break; // trap non-zero data
- case 0xF0: // FM addr
- case 0xA8: // PPI
- return;
- #endif
- }
-
- debug_printf( "OUT $%04X,$%02X\n", addr, data );
-}
-
-int kss_cpu_in( Kss_Cpu*, cpu_time_t, unsigned addr )
-{
- //Kss_Emu& emu = STATIC_CAST(Kss_Emu&,*cpu);
- //switch ( addr & 0xFF )
- //{
- //}
-
- debug_printf( "IN $%04X\n", addr );
- return 0;
-}
-
-// Emulation
-
-blargg_err_t Kss_Emu::run_clocks( blip_time_t& duration, int )
-{
- while ( time() < duration )
- {
- blip_time_t end = min( duration, next_play );
- cpu::run( min( duration, next_play ) );
- if ( r.pc == idle_addr )
- set_time( end );
-
- if ( time() >= next_play )
- {
- next_play += play_period;
- if ( r.pc == idle_addr )
- {
- if ( !gain_updated )
- {
- gain_updated = true;
- if ( scc_accessed )
- update_gain();
- }
-
- ram [--r.sp] = idle_addr >> 8;
- ram [--r.sp] = idle_addr & 0xFF;
- r.pc = GET_LE16( header_.play_addr );
- GME_FRAME_HOOK( this );
- }
- }
- }
-
- duration = time();
- next_play -= duration;
- check( next_play >= 0 );
- adjust_time( -duration );
- ay.end_frame( duration );
- scc.end_frame( duration );
- if ( sn )
- sn->end_frame( duration );
-
- return 0;
-}
diff --git a/src/console/Kss_Emu.h b/src/console/Kss_Emu.h
index e209555a0cec..715cd37ff0f5 100644
--- a/src/console/Kss_Emu.h
+++ b/src/console/Kss_Emu.h
@@ -68,7 +68,6 @@ private:
void update_gain();
unsigned scc_enabled; // 0 or 0xC000
- byte const* bank_data;
int bank_count;
void set_bank( int logical, int physical );
blargg_long bank_size() const { return (16 * 1024L) >> (header_.bank_mode >> 7 & 1); }
diff --git a/src/console/Kss_Scc_Apu.cc b/src/console/Kss_Scc_Apu.cc
new file mode 100644
index 000000000000..960ab6010eae
--- /dev/null
+++ b/src/console/Kss_Scc_Apu.cc
@@ -0,0 +1,97 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Kss_Scc_Apu.h"
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+// Tones above this frequency are treated as disabled tone at half volume.
+// Power of two is more efficient (avoids division).
+unsigned const inaudible_freq = 16384;
+
+int const wave_size = 0x20;
+
+void Scc_Apu::run_until( blip_time_t end_time )
+{
+ for ( int index = 0; index < osc_count; index++ )
+ {
+ osc_t& osc = oscs [index];
+
+ Blip_Buffer* const output = osc.output;
+ if ( !output )
+ continue;
+ output->set_modified();
+
+ blip_time_t period = (regs [0x80 + index * 2 + 1] & 0x0F) * 0x100 +
+ regs [0x80 + index * 2] + 1;
+ int volume = 0;
+ if ( regs [0x8F] & (1 << index) )
+ {
+ blip_time_t inaudible_period = (blargg_ulong) (output->clock_rate() +
+ inaudible_freq * 32) / (inaudible_freq * 16);
+ if ( period > inaudible_period )
+ volume = (regs [0x8A + index] & 0x0F) * (amp_range / 256 / 15);
+ }
+
+ int8_t const* wave = (int8_t*) regs + index * wave_size;
+ if ( index == osc_count - 1 )
+ wave -= wave_size; // last two oscs share wave
+ {
+ int amp = wave [osc.phase] * volume;
+ int delta = amp - osc.last_amp;
+ if ( delta )
+ {
+ osc.last_amp = amp;
+ synth.offset( last_time, delta, output );
+ }
+ }
+
+ blip_time_t time = last_time + osc.delay;
+ if ( time < end_time )
+ {
+ if ( !volume )
+ {
+ // maintain phase
+ blargg_long count = (end_time - time + period - 1) / period;
+ osc.phase = (osc.phase + count) & (wave_size - 1);
+ time += count * period;
+ }
+ else
+ {
+
+ int phase = osc.phase;
+ int last_wave = wave [phase];
+ phase = (phase + 1) & (wave_size - 1); // pre-advance for optimal inner loop
+
+ do
+ {
+ int amp = wave [phase];
+ phase = (phase + 1) & (wave_size - 1);
+ int delta = amp - last_wave;
+ if ( delta )
+ {
+ last_wave = amp;
+ synth.offset( time, delta * volume, output );
+ }
+ time += period;
+ }
+ while ( time < end_time );
+
+ osc.phase = phase = (phase - 1) & (wave_size - 1); // undo pre-advance
+ osc.last_amp = wave [phase] * volume;
+ }
+ }
+ osc.delay = time - end_time;
+ }
+ last_time = end_time;
+}
diff --git a/src/console/Kss_Scc_Apu.cxx b/src/console/Kss_Scc_Apu.cxx
deleted file mode 100644
index 960ab6010eae..000000000000
--- a/src/console/Kss_Scc_Apu.cxx
+++ /dev/null
@@ -1,97 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Kss_Scc_Apu.h"
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Tones above this frequency are treated as disabled tone at half volume.
-// Power of two is more efficient (avoids division).
-unsigned const inaudible_freq = 16384;
-
-int const wave_size = 0x20;
-
-void Scc_Apu::run_until( blip_time_t end_time )
-{
- for ( int index = 0; index < osc_count; index++ )
- {
- osc_t& osc = oscs [index];
-
- Blip_Buffer* const output = osc.output;
- if ( !output )
- continue;
- output->set_modified();
-
- blip_time_t period = (regs [0x80 + index * 2 + 1] & 0x0F) * 0x100 +
- regs [0x80 + index * 2] + 1;
- int volume = 0;
- if ( regs [0x8F] & (1 << index) )
- {
- blip_time_t inaudible_period = (blargg_ulong) (output->clock_rate() +
- inaudible_freq * 32) / (inaudible_freq * 16);
- if ( period > inaudible_period )
- volume = (regs [0x8A + index] & 0x0F) * (amp_range / 256 / 15);
- }
-
- int8_t const* wave = (int8_t*) regs + index * wave_size;
- if ( index == osc_count - 1 )
- wave -= wave_size; // last two oscs share wave
- {
- int amp = wave [osc.phase] * volume;
- int delta = amp - osc.last_amp;
- if ( delta )
- {
- osc.last_amp = amp;
- synth.offset( last_time, delta, output );
- }
- }
-
- blip_time_t time = last_time + osc.delay;
- if ( time < end_time )
- {
- if ( !volume )
- {
- // maintain phase
- blargg_long count = (end_time - time + period - 1) / period;
- osc.phase = (osc.phase + count) & (wave_size - 1);
- time += count * period;
- }
- else
- {
-
- int phase = osc.phase;
- int last_wave = wave [phase];
- phase = (phase + 1) & (wave_size - 1); // pre-advance for optimal inner loop
-
- do
- {
- int amp = wave [phase];
- phase = (phase + 1) & (wave_size - 1);
- int delta = amp - last_wave;
- if ( delta )
- {
- last_wave = amp;
- synth.offset( time, delta * volume, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- osc.phase = phase = (phase - 1) & (wave_size - 1); // undo pre-advance
- osc.last_amp = wave [phase] * volume;
- }
- }
- osc.delay = time - end_time;
- }
- last_time = end_time;
-}
diff --git a/src/console/Kss_Scc_Apu.h b/src/console/Kss_Scc_Apu.h
index 59587331f947..74dffa861e48 100644
--- a/src/console/Kss_Scc_Apu.h
+++ b/src/console/Kss_Scc_Apu.h
@@ -10,7 +10,7 @@
class Scc_Apu {
public:
- // Set buffer to generate all sound into, or disable sound if NULL
+ // Set buffer to generate all sound into, or disable sound if nullptr
void output( Blip_Buffer* );
// Reset sound chip
@@ -28,7 +28,7 @@ public:
// Additional features
// Set sound output of specific oscillator to buffer, where index is
- // 0 to 4. If buffer is NULL, the specified oscillator is muted.
+ // 0 to 4. If buffer is nullptr, the specified oscillator is muted.
enum { osc_count = 5 };
void osc_output( int index, Blip_Buffer* );
diff --git a/src/console/M3u_Playlist.cc b/src/console/M3u_Playlist.cc
new file mode 100644
index 000000000000..a52248c689ff
--- /dev/null
+++ b/src/console/M3u_Playlist.cc
@@ -0,0 +1,426 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "M3u_Playlist.h"
+#include "Music_Emu.h"
+
+#include <string.h>
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+// gme functions defined here to avoid linking in m3u code unless it's used
+
+blargg_err_t Gme_File::load_m3u_( blargg_err_t err )
+{
+ require( raw_track_count_ ); // file must be loaded first
+
+ if ( !err )
+ {
+ if ( playlist.size() )
+ track_count_ = playlist.size();
+
+ int line = playlist.first_error();
+ if ( line )
+ {
+ // avoid using bloated printf()
+ char* out = &playlist_warning [sizeof playlist_warning];
+ *--out = 0;
+ do {
+ *--out = line % 10 + '0';
+ } while ( (line /= 10) > 0 );
+
+ static const char str [] = "Problem in m3u at line ";
+ out -= sizeof str - 1;
+ memcpy( out, str, sizeof str - 1 );
+ set_warning( out );
+ }
+ }
+ return err;
+}
+
+blargg_err_t Gme_File::load_m3u( const char* path ) { return load_m3u_( playlist.load( path ) ); }
+
+blargg_err_t Gme_File::load_m3u( Data_Reader& in ) { return load_m3u_( playlist.load( in ) ); }
+
+BLARGG_EXPORT gme_err_t gme_load_m3u( Music_Emu* me, const char* path ) { return me->load_m3u( path ); }
+
+BLARGG_EXPORT gme_err_t gme_load_m3u_data( Music_Emu* me, const void* data, long size )
+{
+ Mem_File_Reader in( data, size );
+ return me->load_m3u( in );
+}
+
+
+
+static char* skip_white( char* in )
+{
+ while ( *in == ' ' )
+ in++;
+ return in;
+}
+
+inline unsigned from_dec( unsigned n ) { return n - '0'; }
+
+static char* parse_filename( char* in, M3u_Playlist::entry_t& entry )
+{
+ entry.file = in;
+ entry.type = "";
+ char* out = in;
+ while ( 1 )
+ {
+ int c = *in;
+ if ( !c ) break;
+ in++;
+
+ if ( c == ',' ) // commas in filename
+ {
+ char* p = skip_white( in );
+ if ( *p == '$' || from_dec( *p ) <= 9 )
+ {
+ in = p;
+ break;
+ }
+ }
+
+ if ( c == ':' && in [0] == ':' && in [1] && in [2] != ',' ) // ::type suffix
+ {
+ entry.type = ++in;
+ while ( (c = *in) != 0 && c != ',' )
+ in++;
+ if ( c == ',' )
+ {
+ *in++ = 0; // terminate type
+ in = skip_white( in );
+ }
+ break;
+ }
+
+ if ( c == '\\' ) // \ prefix for special characters
+ {
+ c = *in;
+ if ( !c ) break;
+ in++;
+ }
+ *out++ = (char) c;
+ }
+ *out = 0; // terminate string
+ return in;
+}
+
+static char* next_field( char* in, int* result )
+{
+ while ( 1 )
+ {
+ in = skip_white( in );
+
+ if ( !*in )
+ break;
+
+ if ( *in == ',' )
+ {
+ in++;
+ break;
+ }
+
+ *result = 1;
+ in++;
+ }
+ return skip_white( in );
+}
+
+static char* parse_int_( char* in, int* out )
+{
+ int n = 0;
+ while ( 1 )
+ {
+ unsigned d = from_dec( *in );
+ if ( d > 9 )
+ break;
+ in++;
+ n = n * 10 + d;
+ *out = n;
+ }
+ return in;
+}
+
+static char* parse_int( char* in, int* out, int* result )
+{
+ return next_field( parse_int_( in, out ), result );
+}
+
+// Returns 16 or greater if not hex
+inline int from_hex_char( int h )
+{
+ h -= 0x30;
+ if ( (unsigned) h > 9 )
+ h = ((h - 0x11) & 0xDF) + 10;
+ return h;
+}
+
+static char* parse_track( char* in, M3u_Playlist::entry_t& entry, int* result )
+{
+ if ( *in == '$' )
+ {
+ in++;
+ int n = 0;
+ while ( 1 )
+ {
+ int h = from_hex_char( *in );
+ if ( h > 15 )
+ break;
+ in++;
+ n = n * 16 + h;
+ entry.track = n;
+ }
+ }
+ else
+ {
+ in = parse_int_( in, &entry.track );
+ if ( entry.track >= 0 )
+ entry.decimal_track = 1;
+ }
+ return next_field( in, result );
+}
+
+static char* parse_time_( char* in, int* out )
+{
+ *out = -1;
+ int n = -1;
+ in = parse_int_( in, &n );
+ if ( n >= 0 )
+ {
+ *out = n;
+ if ( *in == ':' )
+ {
+ n = -1;
+ in = parse_int_( in + 1, &n );
+ if ( n >= 0 )
+ *out = *out * 60 + n;
+ }
+ }
+ return in;
+}
+
+static char* parse_time( char* in, int* out, int* result )
+{
+ return next_field( parse_time_( in, out ), result );
+}
+
+static char* parse_name( char* in )
+{
+ char* out = in;
+ while ( 1 )
+ {
+ int c = *in;
+ if ( !c ) break;
+ in++;
+
+ if ( c == ',' ) // commas in string
+ {
+ char* p = skip_white( in );
+ if ( *p == ',' || *p == '-' || from_dec( *p ) <= 9 )
+ {
+ in = p;
+ break;
+ }
+ }
+
+ if ( c == '\\' ) // \ prefix for special characters
+ {
+ c = *in;
+ if ( !c ) break;
+ in++;
+ }
+ *out++ = (char) c;
+ }
+ *out = 0; // terminate string
+ return in;
+}
+
+static int parse_line( char* in, M3u_Playlist::entry_t& entry )
+{
+ int result = 0;
+
+ // file
+ entry.file = in;
+ entry.type = "";
+ in = parse_filename( in, entry );
+
+ // track
+ entry.track = -1;
+ entry.decimal_track = 0;
+ in = parse_track( in, entry, &result );
+
+ // name
+ entry.name = in;
+ in = parse_name( in );
+
+ // time
+ entry.length = -1;
+ in = parse_time( in, &entry.length, &result );
+
+ // loop
+ entry.intro = -1;
+ entry.loop = -1;
+ if ( *in == '-' )
+ {
+ entry.loop = entry.length;
+ in++;
+ }
+ else
+ {
+ in = parse_time_( in, &entry.loop );
+ if ( entry.loop >= 0 )
+ {
+ entry.intro = 0;
+ if ( *in == '-' ) // trailing '-' means that intro length was specified
+ {
+ in++;
+ entry.intro = entry.loop;
+ entry.loop = entry.length - entry.intro;
+ }
+ }
+ }
+ in = next_field( in, &result );
+
+ // fade
+ entry.fade = -1;
+ in = parse_time( in, &entry.fade, &result );
+
+ // repeat
+ entry.repeat = -1;
+ in = parse_int( in, &entry.repeat, &result );
+
+ return result;
+}
+
+static void parse_comment( char* in, M3u_Playlist::info_t& info, bool first )
+{
+ in = skip_white( in + 1 );
+ const char* field = in;
+ while ( *in && *in != ':' )
+ in++;
+
+ if ( *in == ':' )
+ {
+ const char* text = skip_white( in + 1 );
+ if ( *text )
+ {
+ *in = 0;
+ if ( !strcmp( "Composer", field ) ) info.composer = text;
+ else if ( !strcmp( "Engineer", field ) ) info.engineer = text;
+ else if ( !strcmp( "Ripping" , field ) ) info.ripping = text;
+ else if ( !strcmp( "Tagging" , field ) ) info.tagging = text;
+ else
+ text = 0;
+ if ( text )
+ return;
+ *in = ':';
+ }
+ }
+
+ if ( first )
+ info.title = field;
+}
+
+blargg_err_t M3u_Playlist::parse_()
+{
+ info_.title = "";
+ info_.composer = "";
+ info_.engineer = "";
+ info_.ripping = "";
+ info_.tagging = "";
+
+ int const CR = 13;
+ int const LF = 10;
+
+ data.end() [-1] = LF; // terminate input
+
+ first_error_ = 0;
+ bool first_comment = true;
+ int line = 0;
+ int count = 0;
+ char* in = data.begin();
+ while ( in < data.end() )
+ {
+ // find end of line and terminate it
+ line++;
+ char* begin = in;
+ while ( *in != CR && *in != LF )
+ {
+ if ( !*in )
+ return "Not an m3u playlist";
+ in++;
+ }
+ if ( in [0] == CR && in [1] == LF ) // treat CR,LF as a single line
+ *in++ = 0;
+ *in++ = 0;
+
+ // parse line
+ if ( *begin == '#' )
+ {
+ parse_comment( begin, info_, first_comment );
+ first_comment = false;
+ }
+ else if ( *begin )
+ {
+ if ( (int) entries.size() <= count )
+ RETURN_ERR( entries.resize( count * 2 + 64 ) );
+
+ if ( !parse_line( begin, entries [count] ) )
+ count++;
+ else if ( !first_error_ )
+ first_error_ = line;
+ first_comment = false;
+ }
+ }
+ if ( count <= 0 )
+ return "Not an m3u playlist";
+
+ if ( !(info_.composer [0] | info_.engineer [0] | info_.ripping [0] | info_.tagging [0]) )
+ info_.title = "";
+
+ return entries.resize( count );
+}
+
+blargg_err_t M3u_Playlist::parse()
+{
+ blargg_err_t err = parse_();
+ if ( err )
+ {
+ entries.clear();
+ data.clear();
+ }
+ return err;
+}
+
+blargg_err_t M3u_Playlist::load( Data_Reader& in )
+{
+ RETURN_ERR( data.resize( in.remain() + 1 ) );
+ RETURN_ERR( in.read( data.begin(), data.size() - 1 ) );
+ return parse();
+}
+
+blargg_err_t M3u_Playlist::load( const char* path )
+{
+ GME_FILE_READER in;
+ RETURN_ERR( in.open( path ) );
+ return load( in );
+}
+
+blargg_err_t M3u_Playlist::load( void const* in, long size )
+{
+ RETURN_ERR( data.resize( size + 1 ) );
+ memcpy( data.begin(), in, size );
+ return parse();
+}
diff --git a/src/console/M3u_Playlist.cxx b/src/console/M3u_Playlist.cxx
deleted file mode 100644
index a52248c689ff..000000000000
--- a/src/console/M3u_Playlist.cxx
+++ /dev/null
@@ -1,426 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "M3u_Playlist.h"
-#include "Music_Emu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// gme functions defined here to avoid linking in m3u code unless it's used
-
-blargg_err_t Gme_File::load_m3u_( blargg_err_t err )
-{
- require( raw_track_count_ ); // file must be loaded first
-
- if ( !err )
- {
- if ( playlist.size() )
- track_count_ = playlist.size();
-
- int line = playlist.first_error();
- if ( line )
- {
- // avoid using bloated printf()
- char* out = &playlist_warning [sizeof playlist_warning];
- *--out = 0;
- do {
- *--out = line % 10 + '0';
- } while ( (line /= 10) > 0 );
-
- static const char str [] = "Problem in m3u at line ";
- out -= sizeof str - 1;
- memcpy( out, str, sizeof str - 1 );
- set_warning( out );
- }
- }
- return err;
-}
-
-blargg_err_t Gme_File::load_m3u( const char* path ) { return load_m3u_( playlist.load( path ) ); }
-
-blargg_err_t Gme_File::load_m3u( Data_Reader& in ) { return load_m3u_( playlist.load( in ) ); }
-
-BLARGG_EXPORT gme_err_t gme_load_m3u( Music_Emu* me, const char* path ) { return me->load_m3u( path ); }
-
-BLARGG_EXPORT gme_err_t gme_load_m3u_data( Music_Emu* me, const void* data, long size )
-{
- Mem_File_Reader in( data, size );
- return me->load_m3u( in );
-}
-
-
-
-static char* skip_white( char* in )
-{
- while ( *in == ' ' )
- in++;
- return in;
-}
-
-inline unsigned from_dec( unsigned n ) { return n - '0'; }
-
-static char* parse_filename( char* in, M3u_Playlist::entry_t& entry )
-{
- entry.file = in;
- entry.type = "";
- char* out = in;
- while ( 1 )
- {
- int c = *in;
- if ( !c ) break;
- in++;
-
- if ( c == ',' ) // commas in filename
- {
- char* p = skip_white( in );
- if ( *p == '$' || from_dec( *p ) <= 9 )
- {
- in = p;
- break;
- }
- }
-
- if ( c == ':' && in [0] == ':' && in [1] && in [2] != ',' ) // ::type suffix
- {
- entry.type = ++in;
- while ( (c = *in) != 0 && c != ',' )
- in++;
- if ( c == ',' )
- {
- *in++ = 0; // terminate type
- in = skip_white( in );
- }
- break;
- }
-
- if ( c == '\\' ) // \ prefix for special characters
- {
- c = *in;
- if ( !c ) break;
- in++;
- }
- *out++ = (char) c;
- }
- *out = 0; // terminate string
- return in;
-}
-
-static char* next_field( char* in, int* result )
-{
- while ( 1 )
- {
- in = skip_white( in );
-
- if ( !*in )
- break;
-
- if ( *in == ',' )
- {
- in++;
- break;
- }
-
- *result = 1;
- in++;
- }
- return skip_white( in );
-}
-
-static char* parse_int_( char* in, int* out )
-{
- int n = 0;
- while ( 1 )
- {
- unsigned d = from_dec( *in );
- if ( d > 9 )
- break;
- in++;
- n = n * 10 + d;
- *out = n;
- }
- return in;
-}
-
-static char* parse_int( char* in, int* out, int* result )
-{
- return next_field( parse_int_( in, out ), result );
-}
-
-// Returns 16 or greater if not hex
-inline int from_hex_char( int h )
-{
- h -= 0x30;
- if ( (unsigned) h > 9 )
- h = ((h - 0x11) & 0xDF) + 10;
- return h;
-}
-
-static char* parse_track( char* in, M3u_Playlist::entry_t& entry, int* result )
-{
- if ( *in == '$' )
- {
- in++;
- int n = 0;
- while ( 1 )
- {
- int h = from_hex_char( *in );
- if ( h > 15 )
- break;
- in++;
- n = n * 16 + h;
- entry.track = n;
- }
- }
- else
- {
- in = parse_int_( in, &entry.track );
- if ( entry.track >= 0 )
- entry.decimal_track = 1;
- }
- return next_field( in, result );
-}
-
-static char* parse_time_( char* in, int* out )
-{
- *out = -1;
- int n = -1;
- in = parse_int_( in, &n );
- if ( n >= 0 )
- {
- *out = n;
- if ( *in == ':' )
- {
- n = -1;
- in = parse_int_( in + 1, &n );
- if ( n >= 0 )
- *out = *out * 60 + n;
- }
- }
- return in;
-}
-
-static char* parse_time( char* in, int* out, int* result )
-{
- return next_field( parse_time_( in, out ), result );
-}
-
-static char* parse_name( char* in )
-{
- char* out = in;
- while ( 1 )
- {
- int c = *in;
- if ( !c ) break;
- in++;
-
- if ( c == ',' ) // commas in string
- {
- char* p = skip_white( in );
- if ( *p == ',' || *p == '-' || from_dec( *p ) <= 9 )
- {
- in = p;
- break;
- }
- }
-
- if ( c == '\\' ) // \ prefix for special characters
- {
- c = *in;
- if ( !c ) break;
- in++;
- }
- *out++ = (char) c;
- }
- *out = 0; // terminate string
- return in;
-}
-
-static int parse_line( char* in, M3u_Playlist::entry_t& entry )
-{
- int result = 0;
-
- // file
- entry.file = in;
- entry.type = "";
- in = parse_filename( in, entry );
-
- // track
- entry.track = -1;
- entry.decimal_track = 0;
- in = parse_track( in, entry, &result );
-
- // name
- entry.name = in;
- in = parse_name( in );
-
- // time
- entry.length = -1;
- in = parse_time( in, &entry.length, &result );
-
- // loop
- entry.intro = -1;
- entry.loop = -1;
- if ( *in == '-' )
- {
- entry.loop = entry.length;
- in++;
- }
- else
- {
- in = parse_time_( in, &entry.loop );
- if ( entry.loop >= 0 )
- {
- entry.intro = 0;
- if ( *in == '-' ) // trailing '-' means that intro length was specified
- {
- in++;
- entry.intro = entry.loop;
- entry.loop = entry.length - entry.intro;
- }
- }
- }
- in = next_field( in, &result );
-
- // fade
- entry.fade = -1;
- in = parse_time( in, &entry.fade, &result );
-
- // repeat
- entry.repeat = -1;
- in = parse_int( in, &entry.repeat, &result );
-
- return result;
-}
-
-static void parse_comment( char* in, M3u_Playlist::info_t& info, bool first )
-{
- in = skip_white( in + 1 );
- const char* field = in;
- while ( *in && *in != ':' )
- in++;
-
- if ( *in == ':' )
- {
- const char* text = skip_white( in + 1 );
- if ( *text )
- {
- *in = 0;
- if ( !strcmp( "Composer", field ) ) info.composer = text;
- else if ( !strcmp( "Engineer", field ) ) info.engineer = text;
- else if ( !strcmp( "Ripping" , field ) ) info.ripping = text;
- else if ( !strcmp( "Tagging" , field ) ) info.tagging = text;
- else
- text = 0;
- if ( text )
- return;
- *in = ':';
- }
- }
-
- if ( first )
- info.title = field;
-}
-
-blargg_err_t M3u_Playlist::parse_()
-{
- info_.title = "";
- info_.composer = "";
- info_.engineer = "";
- info_.ripping = "";
- info_.tagging = "";
-
- int const CR = 13;
- int const LF = 10;
-
- data.end() [-1] = LF; // terminate input
-
- first_error_ = 0;
- bool first_comment = true;
- int line = 0;
- int count = 0;
- char* in = data.begin();
- while ( in < data.end() )
- {
- // find end of line and terminate it
- line++;
- char* begin = in;
- while ( *in != CR && *in != LF )
- {
- if ( !*in )
- return "Not an m3u playlist";
- in++;
- }
- if ( in [0] == CR && in [1] == LF ) // treat CR,LF as a single line
- *in++ = 0;
- *in++ = 0;
-
- // parse line
- if ( *begin == '#' )
- {
- parse_comment( begin, info_, first_comment );
- first_comment = false;
- }
- else if ( *begin )
- {
- if ( (int) entries.size() <= count )
- RETURN_ERR( entries.resize( count * 2 + 64 ) );
-
- if ( !parse_line( begin, entries [count] ) )
- count++;
- else if ( !first_error_ )
- first_error_ = line;
- first_comment = false;
- }
- }
- if ( count <= 0 )
- return "Not an m3u playlist";
-
- if ( !(info_.composer [0] | info_.engineer [0] | info_.ripping [0] | info_.tagging [0]) )
- info_.title = "";
-
- return entries.resize( count );
-}
-
-blargg_err_t M3u_Playlist::parse()
-{
- blargg_err_t err = parse_();
- if ( err )
- {
- entries.clear();
- data.clear();
- }
- return err;
-}
-
-blargg_err_t M3u_Playlist::load( Data_Reader& in )
-{
- RETURN_ERR( data.resize( in.remain() + 1 ) );
- RETURN_ERR( in.read( data.begin(), data.size() - 1 ) );
- return parse();
-}
-
-blargg_err_t M3u_Playlist::load( const char* path )
-{
- GME_FILE_READER in;
- RETURN_ERR( in.open( path ) );
- return load( in );
-}
-
-blargg_err_t M3u_Playlist::load( void const* in, long size )
-{
- RETURN_ERR( data.resize( size + 1 ) );
- memcpy( data.begin(), in, size );
- return parse();
-}
diff --git a/src/console/Makefile b/src/console/Makefile
index 33fd260c5023..c3714b894e5a 100644
--- a/src/console/Makefile
+++ b/src/console/Makefile
@@ -1,57 +1,57 @@
PLUGIN = console${PLUGIN_SUFFIX}
-SRCS = Ay_Apu.cxx \
- Ay_Cpu.cxx \
- Ay_Emu.cxx \
- Blip_Buffer.cxx \
- Classic_Emu.cxx \
- Data_Reader.cxx \
- Dual_Resampler.cxx \
- Effects_Buffer.cxx \
- Fir_Resampler.cxx \
- Gbs_Emu.cxx \
- Gb_Apu.cxx \
- Gb_Cpu.cxx \
- Gb_Oscs.cxx \
- gme.cxx \
- Gme_File.cxx \
- Gym_Emu.cxx \
- Gzip_Reader.cxx \
- Hes_Apu.cxx \
- Hes_Cpu.cxx \
- Hes_Emu.cxx \
- Kss_Cpu.cxx \
- Kss_Emu.cxx \
- Kss_Scc_Apu.cxx \
- M3u_Playlist.cxx \
- Multi_Buffer.cxx \
- Music_Emu.cxx \
- Nes_Apu.cxx \
- Nes_Cpu.cxx \
- Nes_Fme7_Apu.cxx \
- Nes_Namco_Apu.cxx \
- Nes_Oscs.cxx \
- Nes_Vrc6_Apu.cxx \
- Nsfe_Emu.cxx \
- Nsf_Emu.cxx \
- Sap_Apu.cxx \
- Sap_Cpu.cxx \
- Sap_Emu.cxx \
- Sms_Apu.cxx \
- Snes_Spc.cxx \
- Spc_Cpu.cxx \
- Spc_Dsp.cxx \
- Spc_Emu.cxx \
- Spc_Filter.cxx \
- Vfs_File.cxx \
- Vgm_Emu.cxx \
- Vgm_Emu_Impl.cxx \
- Ym2413_Emu.cxx \
- Ym2612_Emu.cxx \
- Zlib_Inflater.cxx \
- Audacious_Driver.cxx \
- configure.c \
- plugin.c
+SRCS = Ay_Apu.cc \
+ Ay_Cpu.cc \
+ Ay_Emu.cc \
+ Blip_Buffer.cc \
+ Classic_Emu.cc \
+ Data_Reader.cc \
+ Dual_Resampler.cc \
+ Effects_Buffer.cc \
+ Fir_Resampler.cc \
+ Gbs_Emu.cc \
+ Gb_Apu.cc \
+ Gb_Cpu.cc \
+ Gb_Oscs.cc \
+ gme.cc \
+ Gme_File.cc \
+ Gym_Emu.cc \
+ Gzip_Reader.cc \
+ Hes_Apu.cc \
+ Hes_Cpu.cc \
+ Hes_Emu.cc \
+ Kss_Cpu.cc \
+ Kss_Emu.cc \
+ Kss_Scc_Apu.cc \
+ M3u_Playlist.cc \
+ Multi_Buffer.cc \
+ Music_Emu.cc \
+ Nes_Apu.cc \
+ Nes_Cpu.cc \
+ Nes_Fme7_Apu.cc \
+ Nes_Namco_Apu.cc \
+ Nes_Oscs.cc \
+ Nes_Vrc6_Apu.cc \
+ Nsfe_Emu.cc \
+ Nsf_Emu.cc \
+ Sap_Apu.cc \
+ Sap_Cpu.cc \
+ Sap_Emu.cc \
+ Sms_Apu.cc \
+ Snes_Spc.cc \
+ Spc_Cpu.cc \
+ Spc_Dsp.cc \
+ Spc_Emu.cc \
+ Spc_Filter.cc \
+ Vfs_File.cc \
+ Vgm_Emu.cc \
+ Vgm_Emu_Impl.cc \
+ Ym2413_Emu.cc \
+ Ym2612_Emu.cc \
+ Zlib_Inflater.cc \
+ Audacious_Driver.cc \
+ configure.cc \
+ plugin.cc
include ../../buildsys.mk
include ../../extra.mk
@@ -62,5 +62,5 @@ LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CXXFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
LIBS += -lz
diff --git a/src/console/Multi_Buffer.cc b/src/console/Multi_Buffer.cc
new file mode 100644
index 000000000000..13770dbb287f
--- /dev/null
+++ b/src/console/Multi_Buffer.cc
@@ -0,0 +1,232 @@
+// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
+
+#include "Multi_Buffer.h"
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+#ifdef BLARGG_ENABLE_OPTIMIZER
+ #include BLARGG_ENABLE_OPTIMIZER
+#endif
+
+Multi_Buffer::Multi_Buffer( int spf ) : samples_per_frame_( spf )
+{
+ length_ = 0;
+ sample_rate_ = 0;
+ channels_changed_count_ = 1;
+}
+
+blargg_err_t Multi_Buffer::set_channel_count( int ) { return 0; }
+
+// Silent_Buffer
+
+Silent_Buffer::Silent_Buffer() : Multi_Buffer( 1 ) // 0 channels would probably confuse
+{
+ // TODO: better to use empty Blip_Buffer so caller never has to check for nullptr?
+ chan.left = 0;
+ chan.center = 0;
+ chan.right = 0;
+}
+
+// Mono_Buffer
+
+Mono_Buffer::Mono_Buffer() : Multi_Buffer( 1 )
+{
+ chan.center = &buf;
+ chan.left = &buf;
+ chan.right = &buf;
+}
+
+Mono_Buffer::~Mono_Buffer() { }
+
+blargg_err_t Mono_Buffer::set_sample_rate( long rate, int msec )
+{
+ RETURN_ERR( buf.set_sample_rate( rate, msec ) );
+ return Multi_Buffer::set_sample_rate( buf.sample_rate(), buf.length() );
+}
+
+// Stereo_Buffer
+
+Stereo_Buffer::Stereo_Buffer() : Multi_Buffer( 2 )
+{
+ chan.center = &bufs [0];
+ chan.left = &bufs [1];
+ chan.right = &bufs [2];
+}
+
+Stereo_Buffer::~Stereo_Buffer() { }
+
+blargg_err_t Stereo_Buffer::set_sample_rate( long rate, int msec )
+{
+ for ( int i = 0; i < buf_count; i++ )
+ RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
+ return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
+}
+
+void Stereo_Buffer::clock_rate( long rate )
+{
+ for ( int i = 0; i < buf_count; i++ )
+ bufs [i].clock_rate( rate );
+}
+
+void Stereo_Buffer::bass_freq( int bass )
+{
+ for ( unsigned i = 0; i < buf_count; i++ )
+ bufs [i].bass_freq( bass );
+}
+
+void Stereo_Buffer::clear()
+{
+ stereo_added = 0;
+ was_stereo = false;
+ for ( int i = 0; i < buf_count; i++ )
+ bufs [i].clear();
+}
+
+void Stereo_Buffer::end_frame( blip_time_t clock_count )
+{
+ stereo_added = 0;
+ for ( unsigned i = 0; i < buf_count; i++ )
+ {
+ stereo_added |= bufs [i].clear_modified() << i;
+ bufs [i].end_frame( clock_count );
+ }
+}
+
+long Stereo_Buffer::read_samples( blip_sample_t* out, long count )
+{
+ require( !(count & 1) ); // count must be even
+ count = (unsigned) count / 2;
+
+ long avail = bufs [0].samples_avail();
+ if ( count > avail )
+ count = avail;
+ if ( count )
+ {
+ int bufs_used = stereo_added | was_stereo;
+ //debug_printf( "%X\n", bufs_used );
+ if ( bufs_used <= 1 )
+ {
+ mix_mono( out, count );
+ bufs [0].remove_samples( count );
+ bufs [1].remove_silence( count );
+ bufs [2].remove_silence( count );
+ }
+ else if ( bufs_used & 1 )
+ {
+ mix_stereo( out, count );
+ bufs [0].remove_samples( count );
+ bufs [1].remove_samples( count );
+ bufs [2].remove_samples( count );
+ }
+ else
+ {
+ mix_stereo_no_center( out, count );
+ bufs [0].remove_silence( count );
+ bufs [1].remove_samples( count );
+ bufs [2].remove_samples( count );
+ }
+
+ // to do: this might miss opportunities for optimization
+ if ( !bufs [0].samples_avail() )
+ {
+ was_stereo = stereo_added;
+ stereo_added = 0;
+ }
+ }
+
+ return count * 2;
+}
+
+void Stereo_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count )
+{
+ blip_sample_t* BLIP_RESTRICT out = out_;
+ int const bass = BLIP_READER_BASS( bufs [1] );
+ BLIP_READER_BEGIN( left, bufs [1] );
+ BLIP_READER_BEGIN( right, bufs [2] );
+ BLIP_READER_BEGIN( center, bufs [0] );
+
+ for ( ; count; --count )
+ {
+ int c = BLIP_READER_READ( center );
+ blargg_long l = c + BLIP_READER_READ( left );
+ blargg_long r = c + BLIP_READER_READ( right );
+ if ( (int16_t) l != l )
+ l = 0x7FFF - (l >> 24);
+
+ BLIP_READER_NEXT( center, bass );
+ if ( (int16_t) r != r )
+ r = 0x7FFF - (r >> 24);
+
+ BLIP_READER_NEXT( left, bass );
+ BLIP_READER_NEXT( right, bass );
+
+ out [0] = l;
+ out [1] = r;
+ out += 2;
+ }
+
+ BLIP_READER_END( center, bufs [0] );
+ BLIP_READER_END( right, bufs [2] );
+ BLIP_READER_END( left, bufs [1] );
+}
+
+void Stereo_Buffer::mix_stereo_no_center( blip_sample_t* out_, blargg_long count )
+{
+ blip_sample_t* BLIP_RESTRICT out = out_;
+ int const bass = BLIP_READER_BASS( bufs [1] );
+ BLIP_READER_BEGIN( left, bufs [1] );
+ BLIP_READER_BEGIN( right, bufs [2] );
+
+ for ( ; count; --count )
+ {
+ blargg_long l = BLIP_READER_READ( left );
+ if ( (int16_t) l != l )
+ l = 0x7FFF - (l >> 24);
+
+ blargg_long r = BLIP_READER_READ( right );
+ if ( (int16_t) r != r )
+ r = 0x7FFF - (r >> 24);
+
+ BLIP_READER_NEXT( left, bass );
+ BLIP_READER_NEXT( right, bass );
+
+ out [0] = l;
+ out [1] = r;
+ out += 2;
+ }
+
+ BLIP_READER_END( right, bufs [2] );
+ BLIP_READER_END( left, bufs [1] );
+}
+
+void Stereo_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
+{
+ blip_sample_t* BLIP_RESTRICT out = out_;
+ int const bass = BLIP_READER_BASS( bufs [0] );
+ BLIP_READER_BEGIN( center, bufs [0] );
+
+ for ( ; count; --count )
+ {
+ blargg_long s = BLIP_READER_READ( center );
+ if ( (int16_t) s != s )
+ s = 0x7FFF - (s >> 24);
+
+ BLIP_READER_NEXT( center, bass );
+ out [0] = s;
+ out [1] = s;
+ out += 2;
+ }
+
+ BLIP_READER_END( center, bufs [0] );
+}
diff --git a/src/console/Multi_Buffer.cxx b/src/console/Multi_Buffer.cxx
deleted file mode 100644
index dd74b44f5387..000000000000
--- a/src/console/Multi_Buffer.cxx
+++ /dev/null
@@ -1,232 +0,0 @@
-// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
-
-#include "Multi_Buffer.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-Multi_Buffer::Multi_Buffer( int spf ) : samples_per_frame_( spf )
-{
- length_ = 0;
- sample_rate_ = 0;
- channels_changed_count_ = 1;
-}
-
-blargg_err_t Multi_Buffer::set_channel_count( int ) { return 0; }
-
-// Silent_Buffer
-
-Silent_Buffer::Silent_Buffer() : Multi_Buffer( 1 ) // 0 channels would probably confuse
-{
- // TODO: better to use empty Blip_Buffer so caller never has to check for NULL?
- chan.left = 0;
- chan.center = 0;
- chan.right = 0;
-}
-
-// Mono_Buffer
-
-Mono_Buffer::Mono_Buffer() : Multi_Buffer( 1 )
-{
- chan.center = &buf;
- chan.left = &buf;
- chan.right = &buf;
-}
-
-Mono_Buffer::~Mono_Buffer() { }
-
-blargg_err_t Mono_Buffer::set_sample_rate( long rate, int msec )
-{
- RETURN_ERR( buf.set_sample_rate( rate, msec ) );
- return Multi_Buffer::set_sample_rate( buf.sample_rate(), buf.length() );
-}
-
-// Stereo_Buffer
-
-Stereo_Buffer::Stereo_Buffer() : Multi_Buffer( 2 )
-{
- chan.center = &bufs [0];
- chan.left = &bufs [1];
- chan.right = &bufs [2];
-}
-
-Stereo_Buffer::~Stereo_Buffer() { }
-
-blargg_err_t Stereo_Buffer::set_sample_rate( long rate, int msec )
-{
- for ( int i = 0; i < buf_count; i++ )
- RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
- return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
-}
-
-void Stereo_Buffer::clock_rate( long rate )
-{
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clock_rate( rate );
-}
-
-void Stereo_Buffer::bass_freq( int bass )
-{
- for ( unsigned i = 0; i < buf_count; i++ )
- bufs [i].bass_freq( bass );
-}
-
-void Stereo_Buffer::clear()
-{
- stereo_added = 0;
- was_stereo = false;
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clear();
-}
-
-void Stereo_Buffer::end_frame( blip_time_t clock_count )
-{
- stereo_added = 0;
- for ( unsigned i = 0; i < buf_count; i++ )
- {
- stereo_added |= bufs [i].clear_modified() << i;
- bufs [i].end_frame( clock_count );
- }
-}
-
-long Stereo_Buffer::read_samples( blip_sample_t* out, long count )
-{
- require( !(count & 1) ); // count must be even
- count = (unsigned) count / 2;
-
- long avail = bufs [0].samples_avail();
- if ( count > avail )
- count = avail;
- if ( count )
- {
- int bufs_used = stereo_added | was_stereo;
- //debug_printf( "%X\n", bufs_used );
- if ( bufs_used <= 1 )
- {
- mix_mono( out, count );
- bufs [0].remove_samples( count );
- bufs [1].remove_silence( count );
- bufs [2].remove_silence( count );
- }
- else if ( bufs_used & 1 )
- {
- mix_stereo( out, count );
- bufs [0].remove_samples( count );
- bufs [1].remove_samples( count );
- bufs [2].remove_samples( count );
- }
- else
- {
- mix_stereo_no_center( out, count );
- bufs [0].remove_silence( count );
- bufs [1].remove_samples( count );
- bufs [2].remove_samples( count );
- }
-
- // to do: this might miss opportunities for optimization
- if ( !bufs [0].samples_avail() )
- {
- was_stereo = stereo_added;
- stereo_added = 0;
- }
- }
-
- return count * 2;
-}
-
-void Stereo_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [1] );
- BLIP_READER_BEGIN( left, bufs [1] );
- BLIP_READER_BEGIN( right, bufs [2] );
- BLIP_READER_BEGIN( center, bufs [0] );
-
- for ( ; count; --count )
- {
- int c = BLIP_READER_READ( center );
- blargg_long l = c + BLIP_READER_READ( left );
- blargg_long r = c + BLIP_READER_READ( right );
- if ( (int16_t) l != l )
- l = 0x7FFF - (l >> 24);
-
- BLIP_READER_NEXT( center, bass );
- if ( (int16_t) r != r )
- r = 0x7FFF - (r >> 24);
-
- BLIP_READER_NEXT( left, bass );
- BLIP_READER_NEXT( right, bass );
-
- out [0] = l;
- out [1] = r;
- out += 2;
- }
-
- BLIP_READER_END( center, bufs [0] );
- BLIP_READER_END( right, bufs [2] );
- BLIP_READER_END( left, bufs [1] );
-}
-
-void Stereo_Buffer::mix_stereo_no_center( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [1] );
- BLIP_READER_BEGIN( left, bufs [1] );
- BLIP_READER_BEGIN( right, bufs [2] );
-
- for ( ; count; --count )
- {
- blargg_long l = BLIP_READER_READ( left );
- if ( (int16_t) l != l )
- l = 0x7FFF - (l >> 24);
-
- blargg_long r = BLIP_READER_READ( right );
- if ( (int16_t) r != r )
- r = 0x7FFF - (r >> 24);
-
- BLIP_READER_NEXT( left, bass );
- BLIP_READER_NEXT( right, bass );
-
- out [0] = l;
- out [1] = r;
- out += 2;
- }
-
- BLIP_READER_END( right, bufs [2] );
- BLIP_READER_END( left, bufs [1] );
-}
-
-void Stereo_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [0] );
- BLIP_READER_BEGIN( center, bufs [0] );
-
- for ( ; count; --count )
- {
- blargg_long s = BLIP_READER_READ( center );
- if ( (int16_t) s != s )
- s = 0x7FFF - (s >> 24);
-
- BLIP_READER_NEXT( center, bass );
- out [0] = s;
- out [1] = s;
- out += 2;
- }
-
- BLIP_READER_END( center, bufs [0] );
-}
diff --git a/src/console/Music_Emu.cc b/src/console/Music_Emu.cc
new file mode 100644
index 000000000000..0500aa015a0e
--- /dev/null
+++ b/src/console/Music_Emu.cc
@@ -0,0 +1,411 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Music_Emu.h"
+
+#include "Multi_Buffer.h"
+#include <string.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+int const stereo = 2; // number of channels for stereo
+int const silence_max = 6; // seconds
+int const silence_threshold = 0x10;
+long const fade_block_size = 512;
+int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift)
+
+Music_Emu::equalizer_t const Music_Emu::tv_eq = { -8.0, 180 };
+
+void Music_Emu::clear_track_vars()
+{
+ current_track_ = -1;
+ out_time = 0;
+ emu_time = 0;
+ emu_track_ended_ = true;
+ track_ended_ = true;
+ fade_start = INT_MAX / 2 + 1;
+ fade_step = 1;
+ silence_time = 0;
+ silence_count = 0;
+ buf_remain = 0;
+ warning(); // clear warning
+}
+
+void Music_Emu::unload()
+{
+ voice_count_ = 0;
+ clear_track_vars();
+ Gme_File::unload();
+}
+
+Music_Emu::Music_Emu()
+{
+ effects_buffer = 0;
+
+ sample_rate_ = 0;
+ mute_mask_ = 0;
+ tempo_ = 1.0;
+ gain_ = 1.0;
+
+ // defaults
+ max_initial_silence = 2;
+ silence_lookahead = 3;
+ ignore_silence_ = false;
+ equalizer_.treble = -1.0;
+ equalizer_.bass = 60;
+
+ static const char* const names [] = {
+ "Voice 1", "Voice 2", "Voice 3", "Voice 4",
+ "Voice 5", "Voice 6", "Voice 7", "Voice 8"
+ };
+ set_voice_names( names );
+ Music_Emu::unload(); // non-virtual
+}
+
+Music_Emu::~Music_Emu() { delete effects_buffer; }
+
+blargg_err_t Music_Emu::set_sample_rate( long rate )
+{
+ require( !sample_rate() ); // sample rate can't be changed once set
+ RETURN_ERR( set_sample_rate_( rate ) );
+ RETURN_ERR( buf.resize( buf_size ) );
+ sample_rate_ = rate;
+ return 0;
+}
+
+void Music_Emu::pre_load()
+{
+ require( sample_rate() ); // set_sample_rate() must be called before loading a file
+ Gme_File::pre_load();
+}
+
+void Music_Emu::set_equalizer( equalizer_t const& eq )
+{
+ equalizer_ = eq;
+ set_equalizer_( eq );
+}
+
+void Music_Emu::mute_voice( int index, bool mute )
+{
+ require( (unsigned) index < (unsigned) voice_count() );
+ int bit = 1 << index;
+ int mask = mute_mask_ | bit;
+ if ( !mute )
+ mask ^= bit;
+ mute_voices( mask );
+}
+
+void Music_Emu::mute_voices( int mask )
+{
+ require( sample_rate() ); // sample rate must be set first
+ mute_mask_ = mask;
+ mute_voices_( mask );
+}
+
+void Music_Emu::set_tempo( double t )
+{
+ require( sample_rate() ); // sample rate must be set first
+ double const min = 0.02;
+ double const max = 4.00;
+ if ( t < min ) t = min;
+ if ( t > max ) t = max;
+ tempo_ = t;
+ set_tempo_( t );
+}
+
+void Music_Emu::post_load_()
+{
+ set_tempo( tempo_ );
+ remute_voices();
+}
+
+blargg_err_t Music_Emu::start_track( int track )
+{
+ clear_track_vars();
+
+ int remapped = track;
+ RETURN_ERR( remap_track_( &remapped ) );
+ current_track_ = track;
+ RETURN_ERR( start_track_( remapped ) );
+
+ emu_track_ended_ = false;
+ track_ended_ = false;
+
+ if ( !ignore_silence_ )
+ {
+ // play until non-silence or end of track
+ for ( long end = max_initial_silence * stereo * sample_rate(); emu_time < end; )
+ {
+ fill_buf();
+ if ( buf_remain | (int) emu_track_ended_ )
+ break;
+ }
+
+ emu_time = buf_remain;
+ out_time = 0;
+ silence_time = 0;
+ silence_count = 0;
+ }
+ return track_ended() ? warning() : 0;
+}
+
+void Music_Emu::end_track_if_error( blargg_err_t err )
+{
+ if ( err )
+ {
+ emu_track_ended_ = true;
+ set_warning( err );
+ }
+}
+
+// Tell/Seek
+
+blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const
+{
+ blargg_long sec = msec / 1000;
+ msec -= sec * 1000;
+ return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo;
+}
+
+long Music_Emu::tell() const
+{
+ blargg_long rate = sample_rate() * stereo;
+ blargg_long sec = out_time / rate;
+ return sec * 1000 + (out_time - sec * rate) * 1000 / rate;
+}
+
+blargg_err_t Music_Emu::seek( long msec )
+{
+ blargg_long time = msec_to_samples( msec );
+ if ( time < out_time )
+ RETURN_ERR( start_track( current_track_ ) );
+ return skip( time - out_time );
+}
+
+blargg_err_t Music_Emu::skip( long count )
+{
+ require( current_track() >= 0 ); // start_track() must have been called already
+ out_time += count;
+
+ // remove from silence and buf first
+ {
+ long n = min( count, silence_count );
+ silence_count -= n;
+ count -= n;
+
+ n = min( count, buf_remain );
+ buf_remain -= n;
+ count -= n;
+ }
+
+ if ( count && !emu_track_ended_ )
+ {
+ emu_time += count;
+ end_track_if_error( skip_( count ) );
+ }
+
+ if ( !(silence_count | buf_remain) ) // caught up to emulator, so update track ended
+ track_ended_ |= emu_track_ended_;
+
+ return 0;
+}
+
+blargg_err_t Music_Emu::skip_( long count )
+{
+ // for long skip, mute sound
+ const long threshold = 30000;
+ if ( count > threshold )
+ {
+ int saved_mute = mute_mask_;
+ mute_voices( ~0 );
+
+ while ( count > threshold / 2 && !emu_track_ended_ )
+ {
+ RETURN_ERR( play_( buf_size, buf.begin() ) );
+ count -= buf_size;
+ }
+
+ mute_voices( saved_mute );
+ }
+
+ while ( count && !emu_track_ended_ )
+ {
+ long n = buf_size;
+ if ( n > count )
+ n = count;
+ count -= n;
+ RETURN_ERR( play_( n, buf.begin() ) );
+ }
+ return 0;
+}
+
+// Fading
+
+void Music_Emu::set_fade( long start_msec, long length_msec )
+{
+ fade_step = sample_rate() * length_msec / (fade_block_size * fade_shift * 1000 / stereo);
+ fade_start = msec_to_samples( start_msec );
+}
+
+// unit / pow( 2.0, (double) x / step )
+static int int_log( blargg_long x, int step, int unit )
+{
+ int shift = x / step;
+ int fraction = (x - shift * step) * unit / step;
+ return ((unit - fraction) + (fraction >> 1)) >> shift;
+}
+
+void Music_Emu::handle_fade( long out_count, sample_t* out )
+{
+ for ( int i = 0; i < out_count; i += fade_block_size )
+ {
+ int const shift = 14;
+ int const unit = 1 << shift;
+ int gain = int_log( (out_time + i - fade_start) / fade_block_size,
+ fade_step, unit );
+ if ( gain < (unit >> fade_shift) )
+ track_ended_ = emu_track_ended_ = true;
+
+ sample_t* io = &out [i];
+ for ( int count = min( fade_block_size, out_count - i ); count; --count )
+ {
+ *io = sample_t ((*io * gain) >> shift);
+ ++io;
+ }
+ }
+}
+
+// Silence detection
+
+void Music_Emu::emu_play( long count, sample_t* out )
+{
+ check( current_track_ >= 0 );
+ emu_time += count;
+ if ( current_track_ >= 0 && !emu_track_ended_ )
+ end_track_if_error( play_( count, out ) );
+ else
+ memset( out, 0, count * sizeof *out );
+}
+
+// number of consecutive silent samples at end
+static long count_silence( Music_Emu::sample_t* begin, long size )
+{
+ Music_Emu::sample_t first = *begin;
+ *begin = silence_threshold; // sentinel
+ Music_Emu::sample_t* p = begin + size;
+ while ( (unsigned) (*--p + silence_threshold / 2) <= (unsigned) silence_threshold ) { }
+ *begin = first;
+ return size - (p - begin);
+}
+
+// fill internal buffer and check it for silence
+void Music_Emu::fill_buf()
+{
+ assert( !buf_remain );
+ if ( !emu_track_ended_ )
+ {
+ emu_play( buf_size, buf.begin() );
+ long silence = count_silence( buf.begin(), buf_size );
+ if ( silence < buf_size )
+ {
+ silence_time = emu_time - silence;
+ buf_remain = buf_size;
+ return;
+ }
+ }
+ silence_count += buf_size;
+}
+
+blargg_err_t Music_Emu::play( long out_count, sample_t* out )
+{
+ if ( track_ended_ )
+ {
+ memset( out, 0, out_count * sizeof *out );
+ }
+ else
+ {
+ require( current_track() >= 0 );
+ require( out_count % stereo == 0 );
+
+ assert( emu_time >= out_time );
+
+ // prints nifty graph of how far ahead we are when searching for silence
+ //debug_printf( "%*s \n", int ((emu_time - out_time) * 7 / sample_rate()), "*" );
+
+ long pos = 0;
+ if ( silence_count )
+ {
+ // during a run of silence, run emulator at >=2x speed so it gets ahead
+ long ahead_time = silence_lookahead * (out_time + out_count - silence_time) + silence_time;
+ while ( emu_time < ahead_time && !(buf_remain | emu_track_ended_) )
+ fill_buf();
+
+ // fill with silence
+ pos = min( silence_count, out_count );
+ memset( out, 0, pos * sizeof *out );
+ silence_count -= pos;
+
+ if ( emu_time - silence_time > silence_max * stereo * sample_rate() )
+ {
+ track_ended_ = emu_track_ended_ = true;
+ silence_count = 0;
+ buf_remain = 0;
+ }
+ }
+
+ if ( buf_remain )
+ {
+ // empty silence buf
+ long n = min( buf_remain, out_count - pos );
+ memcpy( &out [pos], buf.begin() + (buf_size - buf_remain), n * sizeof *out );
+ buf_remain -= n;
+ pos += n;
+ }
+
+ // generate remaining samples normally
+ long remain = out_count - pos;
+ if ( remain )
+ {
+ emu_play( remain, out + pos );
+ track_ended_ |= emu_track_ended_;
+
+ if ( !ignore_silence_ || out_time > fade_start )
+ {
+ // check end for a new run of silence
+ long silence = count_silence( out + pos, remain );
+ if ( silence < remain )
+ silence_time = emu_time - silence;
+
+ if ( emu_time - silence_time >= buf_size )
+ fill_buf(); // cause silence detection on next play()
+ }
+ }
+
+ if ( out_time > fade_start )
+ handle_fade( out_count, out );
+ }
+ out_time += out_count;
+ return 0;
+}
+
+// Gme_Info_
+
+blargg_err_t Gme_Info_::set_sample_rate_( long ) { return 0; }
+void Gme_Info_::pre_load() { Gme_File::pre_load(); } // skip Music_Emu
+void Gme_Info_::post_load_() { Gme_File::post_load_(); } // skip Music_Emu
+void Gme_Info_::set_equalizer_( equalizer_t const& ){ check( false ); }
+void Gme_Info_::enable_accuracy_( bool ) { check( false ); }
+void Gme_Info_::mute_voices_( int ) { check( false ); }
+void Gme_Info_::set_tempo_( double ) { }
+blargg_err_t Gme_Info_::start_track_( int ) { return "Use full emulator for playback"; }
+blargg_err_t Gme_Info_::play_( long, sample_t* ) { return "Use full emulator for playback"; }
diff --git a/src/console/Music_Emu.cxx b/src/console/Music_Emu.cxx
deleted file mode 100644
index 0500aa015a0e..000000000000
--- a/src/console/Music_Emu.cxx
+++ /dev/null
@@ -1,411 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Music_Emu.h"
-
-#include "Multi_Buffer.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const stereo = 2; // number of channels for stereo
-int const silence_max = 6; // seconds
-int const silence_threshold = 0x10;
-long const fade_block_size = 512;
-int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift)
-
-Music_Emu::equalizer_t const Music_Emu::tv_eq = { -8.0, 180 };
-
-void Music_Emu::clear_track_vars()
-{
- current_track_ = -1;
- out_time = 0;
- emu_time = 0;
- emu_track_ended_ = true;
- track_ended_ = true;
- fade_start = INT_MAX / 2 + 1;
- fade_step = 1;
- silence_time = 0;
- silence_count = 0;
- buf_remain = 0;
- warning(); // clear warning
-}
-
-void Music_Emu::unload()
-{
- voice_count_ = 0;
- clear_track_vars();
- Gme_File::unload();
-}
-
-Music_Emu::Music_Emu()
-{
- effects_buffer = 0;
-
- sample_rate_ = 0;
- mute_mask_ = 0;
- tempo_ = 1.0;
- gain_ = 1.0;
-
- // defaults
- max_initial_silence = 2;
- silence_lookahead = 3;
- ignore_silence_ = false;
- equalizer_.treble = -1.0;
- equalizer_.bass = 60;
-
- static const char* const names [] = {
- "Voice 1", "Voice 2", "Voice 3", "Voice 4",
- "Voice 5", "Voice 6", "Voice 7", "Voice 8"
- };
- set_voice_names( names );
- Music_Emu::unload(); // non-virtual
-}
-
-Music_Emu::~Music_Emu() { delete effects_buffer; }
-
-blargg_err_t Music_Emu::set_sample_rate( long rate )
-{
- require( !sample_rate() ); // sample rate can't be changed once set
- RETURN_ERR( set_sample_rate_( rate ) );
- RETURN_ERR( buf.resize( buf_size ) );
- sample_rate_ = rate;
- return 0;
-}
-
-void Music_Emu::pre_load()
-{
- require( sample_rate() ); // set_sample_rate() must be called before loading a file
- Gme_File::pre_load();
-}
-
-void Music_Emu::set_equalizer( equalizer_t const& eq )
-{
- equalizer_ = eq;
- set_equalizer_( eq );
-}
-
-void Music_Emu::mute_voice( int index, bool mute )
-{
- require( (unsigned) index < (unsigned) voice_count() );
- int bit = 1 << index;
- int mask = mute_mask_ | bit;
- if ( !mute )
- mask ^= bit;
- mute_voices( mask );
-}
-
-void Music_Emu::mute_voices( int mask )
-{
- require( sample_rate() ); // sample rate must be set first
- mute_mask_ = mask;
- mute_voices_( mask );
-}
-
-void Music_Emu::set_tempo( double t )
-{
- require( sample_rate() ); // sample rate must be set first
- double const min = 0.02;
- double const max = 4.00;
- if ( t < min ) t = min;
- if ( t > max ) t = max;
- tempo_ = t;
- set_tempo_( t );
-}
-
-void Music_Emu::post_load_()
-{
- set_tempo( tempo_ );
- remute_voices();
-}
-
-blargg_err_t Music_Emu::start_track( int track )
-{
- clear_track_vars();
-
- int remapped = track;
- RETURN_ERR( remap_track_( &remapped ) );
- current_track_ = track;
- RETURN_ERR( start_track_( remapped ) );
-
- emu_track_ended_ = false;
- track_ended_ = false;
-
- if ( !ignore_silence_ )
- {
- // play until non-silence or end of track
- for ( long end = max_initial_silence * stereo * sample_rate(); emu_time < end; )
- {
- fill_buf();
- if ( buf_remain | (int) emu_track_ended_ )
- break;
- }
-
- emu_time = buf_remain;
- out_time = 0;
- silence_time = 0;
- silence_count = 0;
- }
- return track_ended() ? warning() : 0;
-}
-
-void Music_Emu::end_track_if_error( blargg_err_t err )
-{
- if ( err )
- {
- emu_track_ended_ = true;
- set_warning( err );
- }
-}
-
-// Tell/Seek
-
-blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const
-{
- blargg_long sec = msec / 1000;
- msec -= sec * 1000;
- return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo;
-}
-
-long Music_Emu::tell() const
-{
- blargg_long rate = sample_rate() * stereo;
- blargg_long sec = out_time / rate;
- return sec * 1000 + (out_time - sec * rate) * 1000 / rate;
-}
-
-blargg_err_t Music_Emu::seek( long msec )
-{
- blargg_long time = msec_to_samples( msec );
- if ( time < out_time )
- RETURN_ERR( start_track( current_track_ ) );
- return skip( time - out_time );
-}
-
-blargg_err_t Music_Emu::skip( long count )
-{
- require( current_track() >= 0 ); // start_track() must have been called already
- out_time += count;
-
- // remove from silence and buf first
- {
- long n = min( count, silence_count );
- silence_count -= n;
- count -= n;
-
- n = min( count, buf_remain );
- buf_remain -= n;
- count -= n;
- }
-
- if ( count && !emu_track_ended_ )
- {
- emu_time += count;
- end_track_if_error( skip_( count ) );
- }
-
- if ( !(silence_count | buf_remain) ) // caught up to emulator, so update track ended
- track_ended_ |= emu_track_ended_;
-
- return 0;
-}
-
-blargg_err_t Music_Emu::skip_( long count )
-{
- // for long skip, mute sound
- const long threshold = 30000;
- if ( count > threshold )
- {
- int saved_mute = mute_mask_;
- mute_voices( ~0 );
-
- while ( count > threshold / 2 && !emu_track_ended_ )
- {
- RETURN_ERR( play_( buf_size, buf.begin() ) );
- count -= buf_size;
- }
-
- mute_voices( saved_mute );
- }
-
- while ( count && !emu_track_ended_ )
- {
- long n = buf_size;
- if ( n > count )
- n = count;
- count -= n;
- RETURN_ERR( play_( n, buf.begin() ) );
- }
- return 0;
-}
-
-// Fading
-
-void Music_Emu::set_fade( long start_msec, long length_msec )
-{
- fade_step = sample_rate() * length_msec / (fade_block_size * fade_shift * 1000 / stereo);
- fade_start = msec_to_samples( start_msec );
-}
-
-// unit / pow( 2.0, (double) x / step )
-static int int_log( blargg_long x, int step, int unit )
-{
- int shift = x / step;
- int fraction = (x - shift * step) * unit / step;
- return ((unit - fraction) + (fraction >> 1)) >> shift;
-}
-
-void Music_Emu::handle_fade( long out_count, sample_t* out )
-{
- for ( int i = 0; i < out_count; i += fade_block_size )
- {
- int const shift = 14;
- int const unit = 1 << shift;
- int gain = int_log( (out_time + i - fade_start) / fade_block_size,
- fade_step, unit );
- if ( gain < (unit >> fade_shift) )
- track_ended_ = emu_track_ended_ = true;
-
- sample_t* io = &out [i];
- for ( int count = min( fade_block_size, out_count - i ); count; --count )
- {
- *io = sample_t ((*io * gain) >> shift);
- ++io;
- }
- }
-}
-
-// Silence detection
-
-void Music_Emu::emu_play( long count, sample_t* out )
-{
- check( current_track_ >= 0 );
- emu_time += count;
- if ( current_track_ >= 0 && !emu_track_ended_ )
- end_track_if_error( play_( count, out ) );
- else
- memset( out, 0, count * sizeof *out );
-}
-
-// number of consecutive silent samples at end
-static long count_silence( Music_Emu::sample_t* begin, long size )
-{
- Music_Emu::sample_t first = *begin;
- *begin = silence_threshold; // sentinel
- Music_Emu::sample_t* p = begin + size;
- while ( (unsigned) (*--p + silence_threshold / 2) <= (unsigned) silence_threshold ) { }
- *begin = first;
- return size - (p - begin);
-}
-
-// fill internal buffer and check it for silence
-void Music_Emu::fill_buf()
-{
- assert( !buf_remain );
- if ( !emu_track_ended_ )
- {
- emu_play( buf_size, buf.begin() );
- long silence = count_silence( buf.begin(), buf_size );
- if ( silence < buf_size )
- {
- silence_time = emu_time - silence;
- buf_remain = buf_size;
- return;
- }
- }
- silence_count += buf_size;
-}
-
-blargg_err_t Music_Emu::play( long out_count, sample_t* out )
-{
- if ( track_ended_ )
- {
- memset( out, 0, out_count * sizeof *out );
- }
- else
- {
- require( current_track() >= 0 );
- require( out_count % stereo == 0 );
-
- assert( emu_time >= out_time );
-
- // prints nifty graph of how far ahead we are when searching for silence
- //debug_printf( "%*s \n", int ((emu_time - out_time) * 7 / sample_rate()), "*" );
-
- long pos = 0;
- if ( silence_count )
- {
- // during a run of silence, run emulator at >=2x speed so it gets ahead
- long ahead_time = silence_lookahead * (out_time + out_count - silence_time) + silence_time;
- while ( emu_time < ahead_time && !(buf_remain | emu_track_ended_) )
- fill_buf();
-
- // fill with silence
- pos = min( silence_count, out_count );
- memset( out, 0, pos * sizeof *out );
- silence_count -= pos;
-
- if ( emu_time - silence_time > silence_max * stereo * sample_rate() )
- {
- track_ended_ = emu_track_ended_ = true;
- silence_count = 0;
- buf_remain = 0;
- }
- }
-
- if ( buf_remain )
- {
- // empty silence buf
- long n = min( buf_remain, out_count - pos );
- memcpy( &out [pos], buf.begin() + (buf_size - buf_remain), n * sizeof *out );
- buf_remain -= n;
- pos += n;
- }
-
- // generate remaining samples normally
- long remain = out_count - pos;
- if ( remain )
- {
- emu_play( remain, out + pos );
- track_ended_ |= emu_track_ended_;
-
- if ( !ignore_silence_ || out_time > fade_start )
- {
- // check end for a new run of silence
- long silence = count_silence( out + pos, remain );
- if ( silence < remain )
- silence_time = emu_time - silence;
-
- if ( emu_time - silence_time >= buf_size )
- fill_buf(); // cause silence detection on next play()
- }
- }
-
- if ( out_time > fade_start )
- handle_fade( out_count, out );
- }
- out_time += out_count;
- return 0;
-}
-
-// Gme_Info_
-
-blargg_err_t Gme_Info_::set_sample_rate_( long ) { return 0; }
-void Gme_Info_::pre_load() { Gme_File::pre_load(); } // skip Music_Emu
-void Gme_Info_::post_load_() { Gme_File::post_load_(); } // skip Music_Emu
-void Gme_Info_::set_equalizer_( equalizer_t const& ){ check( false ); }
-void Gme_Info_::enable_accuracy_( bool ) { check( false ); }
-void Gme_Info_::mute_voices_( int ) { check( false ); }
-void Gme_Info_::set_tempo_( double ) { }
-blargg_err_t Gme_Info_::start_track_( int ) { return "Use full emulator for playback"; }
-blargg_err_t Gme_Info_::play_( long, sample_t* ) { return "Use full emulator for playback"; }
diff --git a/src/console/Nes_Apu.cc b/src/console/Nes_Apu.cc
new file mode 100644
index 000000000000..1fe3f3f0df62
--- /dev/null
+++ b/src/console/Nes_Apu.cc
@@ -0,0 +1,391 @@
+// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
+
+#include "Nes_Apu.h"
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+int const amp_range = 15;
+
+Nes_Apu::Nes_Apu() :
+ square1( &square_synth ),
+ square2( &square_synth )
+{
+ tempo_ = 1.0;
+ dmc.apu = this;
+ dmc.prg_reader = nullptr;
+ irq_notifier_ = nullptr;
+
+ oscs [0] = &square1;
+ oscs [1] = &square2;
+ oscs [2] = ▵
+ oscs [3] = &noise;
+ oscs [4] = &dmc;
+
+ output( nullptr );
+ volume( 1.0 );
+ reset( false );
+}
+
+void Nes_Apu::treble_eq( const blip_eq_t& eq )
+{
+ square_synth.treble_eq( eq );
+ triangle.synth.treble_eq( eq );
+ noise.synth.treble_eq( eq );
+ dmc.synth.treble_eq( eq );
+}
+
+void Nes_Apu::enable_nonlinear( double v )
+{
+ dmc.nonlinear = true;
+ square_synth.volume( 1.3 * 0.25751258 / 0.742467605 * 0.25 / amp_range * v );
+
+ const double tnd = 0.48 / 202 * nonlinear_tnd_gain();
+ triangle.synth.volume( 3.0 * tnd );
+ noise.synth.volume( 2.0 * tnd );
+ dmc.synth.volume( tnd );
+
+ square1 .last_amp = 0;
+ square2 .last_amp = 0;
+ triangle.last_amp = 0;
+ noise .last_amp = 0;
+ dmc .last_amp = 0;
+}
+
+void Nes_Apu::volume( double v )
+{
+ dmc.nonlinear = false;
+ square_synth.volume( 0.1128 / amp_range * v );
+ triangle.synth.volume( 0.12765 / amp_range * v );
+ noise.synth.volume( 0.0741 / amp_range * v );
+ dmc.synth.volume( 0.42545 / 127 * v );
+}
+
+void Nes_Apu::output( Blip_Buffer* buffer )
+{
+ for ( int i = 0; i < osc_count; i++ )
+ osc_output( i, buffer );
+}
+
+void Nes_Apu::set_tempo( double t )
+{
+ tempo_ = t;
+ frame_period = (dmc.pal_mode ? 8314 : 7458);
+ if ( t != 1.0 )
+ frame_period = (int) (frame_period / t) & ~1; // must be even
+}
+
+void Nes_Apu::reset( bool pal_mode, int initial_dmc_dac )
+{
+ dmc.pal_mode = pal_mode;
+ set_tempo( tempo_ );
+
+ square1.reset();
+ square2.reset();
+ triangle.reset();
+ noise.reset();
+ dmc.reset();
+
+ last_time = 0;
+ last_dmc_time = 0;
+ osc_enables = 0;
+ irq_flag = false;
+ earliest_irq_ = no_irq;
+ frame_delay = 1;
+ write_register( 0, 0x4017, 0x00 );
+ write_register( 0, 0x4015, 0x00 );
+
+ for ( nes_addr_t addr = start_addr; addr <= 0x4013; addr++ )
+ write_register( 0, addr, (addr & 3) ? 0x00 : 0x10 );
+
+ dmc.dac = initial_dmc_dac;
+ if ( !dmc.nonlinear )
+ triangle.last_amp = 15;
+ if ( !dmc.nonlinear ) // TODO: remove?
+ dmc.last_amp = initial_dmc_dac; // prevent output transition
+}
+
+void Nes_Apu::irq_changed()
+{
+ nes_time_t new_irq = dmc.next_irq;
+ if ( dmc.irq_flag | irq_flag ) {
+ new_irq = 0;
+ }
+ else if ( new_irq > next_irq ) {
+ new_irq = next_irq;
+ }
+
+ if ( new_irq != earliest_irq_ ) {
+ earliest_irq_ = new_irq;
+ if ( irq_notifier_ )
+ irq_notifier_( irq_data );
+ }
+}
+
+// frames
+
+void Nes_Apu::run_until( nes_time_t end_time )
+{
+ require( end_time >= last_dmc_time );
+ if ( end_time > next_dmc_read_time() )
+ {
+ nes_time_t start = last_dmc_time;
+ last_dmc_time = end_time;
+ dmc.run( start, end_time );
+ }
+}
+
+void Nes_Apu::run_until_( nes_time_t end_time )
+{
+ require( end_time >= last_time );
+
+ if ( end_time == last_time )
+ return;
+
+ if ( last_dmc_time < end_time )
+ {
+ nes_time_t start = last_dmc_time;
+ last_dmc_time = end_time;
+ dmc.run( start, end_time );
+ }
+
+ while ( true )
+ {
+ // earlier of next frame time or end time
+ nes_time_t time = last_time + frame_delay;
+ if ( time > end_time )
+ time = end_time;
+ frame_delay -= time - last_time;
+
+ // run oscs to present
+ square1.run( last_time, time );
+ square2.run( last_time, time );
+ triangle.run( last_time, time );
+ noise.run( last_time, time );
+ last_time = time;
+
+ if ( time == end_time )
+ break; // no more frames to run
+
+ // take frame-specific actions
+ frame_delay = frame_period;
+ switch ( frame++ )
+ {
+ case 0:
+ if ( !(frame_mode & 0xC0) ) {
+ next_irq = time + frame_period * 4 + 2;
+ irq_flag = true;
+ }
+ // fall through
+ case 2:
+ // clock length and sweep on frames 0 and 2
+ square1.clock_length( 0x20 );
+ square2.clock_length( 0x20 );
+ noise.clock_length( 0x20 );
+ triangle.clock_length( 0x80 ); // different bit for halt flag on triangle
+
+ square1.clock_sweep( -1 );
+ square2.clock_sweep( 0 );
+
+ // frame 2 is slightly shorter in mode 1
+ if ( dmc.pal_mode && frame == 3 )
+ frame_delay -= 2;
+ break;
+
+ case 1:
+ // frame 1 is slightly shorter in mode 0
+ if ( !dmc.pal_mode )
+ frame_delay -= 2;
+ break;
+
+ case 3:
+ frame = 0;
+
+ // frame 3 is almost twice as long in mode 1
+ if ( frame_mode & 0x80 )
+ frame_delay += frame_period - (dmc.pal_mode ? 2 : 6);
+ break;
+ }
+
+ // clock envelopes and linear counter every frame
+ triangle.clock_linear_counter();
+ square1.clock_envelope();
+ square2.clock_envelope();
+ noise.clock_envelope();
+ }
+}
+
+template<class T>
+inline void zero_apu_osc( T* osc, nes_time_t time )
+{
+ Blip_Buffer* output = osc->output;
+ int last_amp = osc->last_amp;
+ osc->last_amp = 0;
+ if ( output && last_amp )
+ osc->synth.offset( time, -last_amp, output );
+}
+
+void Nes_Apu::end_frame( nes_time_t end_time )
+{
+ if ( end_time > last_time )
+ run_until_( end_time );
+
+ if ( dmc.nonlinear )
+ {
+ zero_apu_osc( &square1, last_time );
+ zero_apu_osc( &square2, last_time );
+ zero_apu_osc( &triangle, last_time );
+ zero_apu_osc( &noise, last_time );
+ zero_apu_osc( &dmc, last_time );
+ }
+
+ // make times relative to new frame
+ last_time -= end_time;
+ require( last_time >= 0 );
+
+ last_dmc_time -= end_time;
+ require( last_dmc_time >= 0 );
+
+ if ( next_irq != no_irq ) {
+ next_irq -= end_time;
+ check( next_irq >= 0 );
+ }
+ if ( dmc.next_irq != no_irq ) {
+ dmc.next_irq -= end_time;
+ check( dmc.next_irq >= 0 );
+ }
+ if ( earliest_irq_ != no_irq ) {
+ earliest_irq_ -= end_time;
+ if ( earliest_irq_ < 0 )
+ earliest_irq_ = 0;
+ }
+}
+
+// registers
+
+static const unsigned char length_table [0x20] = {
+ 0x0A, 0xFE, 0x14, 0x02, 0x28, 0x04, 0x50, 0x06,
+ 0xA0, 0x08, 0x3C, 0x0A, 0x0E, 0x0C, 0x1A, 0x0E,
+ 0x0C, 0x10, 0x18, 0x12, 0x30, 0x14, 0x60, 0x16,
+ 0xC0, 0x18, 0x48, 0x1A, 0x10, 0x1C, 0x20, 0x1E
+};
+
+void Nes_Apu::write_register( nes_time_t time, nes_addr_t addr, int data )
+{
+ require( addr > 0x20 ); // addr must be actual address (i.e. 0x40xx)
+ require( (unsigned) data <= 0xFF );
+
+ // Ignore addresses outside range
+ if ( unsigned (addr - start_addr) > end_addr - start_addr )
+ return;
+
+ run_until_( time );
+
+ if ( addr < 0x4014 )
+ {
+ // Write to channel
+ int osc_index = (addr - start_addr) >> 2;
+ Nes_Osc* osc = oscs [osc_index];
+
+ int reg = addr & 3;
+ osc->regs [reg] = data;
+ osc->reg_written [reg] = true;
+
+ if ( osc_index == 4 )
+ {
+ // handle DMC specially
+ dmc.write_register( reg, data );
+ }
+ else if ( reg == 3 )
+ {
+ // load length counter
+ if ( (osc_enables >> osc_index) & 1 )
+ osc->length_counter = length_table [(data >> 3) & 0x1F];
+
+ // reset square phase
+ if ( osc_index < 2 )
+ ((Nes_Square*) osc)->phase = Nes_Square::phase_range - 1;
+ }
+ }
+ else if ( addr == 0x4015 )
+ {
+ // Channel enables
+ for ( int i = osc_count; i--; )
+ if ( !((data >> i) & 1) )
+ oscs [i]->length_counter = 0;
+
+ bool recalc_irq = dmc.irq_flag;
+ dmc.irq_flag = false;
+
+ int old_enables = osc_enables;
+ osc_enables = data;
+ if ( !(data & 0x10) ) {
+ dmc.next_irq = no_irq;
+ recalc_irq = true;
+ }
+ else if ( !(old_enables & 0x10) ) {
+ dmc.start(); // dmc just enabled
+ }
+
+ if ( recalc_irq )
+ irq_changed();
+ }
+ else if ( addr == 0x4017 )
+ {
+ // Frame mode
+ frame_mode = data;
+
+ bool irq_enabled = !(data & 0x40);
+ irq_flag &= irq_enabled;
+ next_irq = no_irq;
+
+ // mode 1
+ frame_delay = (frame_delay & 1);
+ frame = 0;
+
+ if ( !(data & 0x80) )
+ {
+ // mode 0
+ frame = 1;
+ frame_delay += frame_period;
+ if ( irq_enabled )
+ next_irq = time + frame_delay + frame_period * 3 + 1;
+ }
+
+ irq_changed();
+ }
+}
+
+int Nes_Apu::read_status( nes_time_t time )
+{
+ run_until_( time - 1 );
+
+ int result = (dmc.irq_flag << 7) | (irq_flag << 6);
+
+ for ( int i = 0; i < osc_count; i++ )
+ if ( oscs [i]->length_counter )
+ result |= 1 << i;
+
+ run_until_( time );
+
+ if ( irq_flag )
+ {
+ result |= 0x40;
+ irq_flag = false;
+ irq_changed();
+ }
+
+ //debug_printf( "%6d/%d Read $4015->$%02X\n", frame_delay, frame, result );
+
+ return result;
+}
diff --git a/src/console/Nes_Apu.cxx b/src/console/Nes_Apu.cxx
deleted file mode 100644
index 6da8ac88cd31..000000000000
--- a/src/console/Nes_Apu.cxx
+++ /dev/null
@@ -1,391 +0,0 @@
-// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
-
-#include "Nes_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const amp_range = 15;
-
-Nes_Apu::Nes_Apu() :
- square1( &square_synth ),
- square2( &square_synth )
-{
- tempo_ = 1.0;
- dmc.apu = this;
- dmc.prg_reader = NULL;
- irq_notifier_ = NULL;
-
- oscs [0] = &square1;
- oscs [1] = &square2;
- oscs [2] = ▵
- oscs [3] = &noise;
- oscs [4] = &dmc;
-
- output( NULL );
- volume( 1.0 );
- reset( false );
-}
-
-void Nes_Apu::treble_eq( const blip_eq_t& eq )
-{
- square_synth.treble_eq( eq );
- triangle.synth.treble_eq( eq );
- noise.synth.treble_eq( eq );
- dmc.synth.treble_eq( eq );
-}
-
-void Nes_Apu::enable_nonlinear( double v )
-{
- dmc.nonlinear = true;
- square_synth.volume( 1.3 * 0.25751258 / 0.742467605 * 0.25 / amp_range * v );
-
- const double tnd = 0.48 / 202 * nonlinear_tnd_gain();
- triangle.synth.volume( 3.0 * tnd );
- noise.synth.volume( 2.0 * tnd );
- dmc.synth.volume( tnd );
-
- square1 .last_amp = 0;
- square2 .last_amp = 0;
- triangle.last_amp = 0;
- noise .last_amp = 0;
- dmc .last_amp = 0;
-}
-
-void Nes_Apu::volume( double v )
-{
- dmc.nonlinear = false;
- square_synth.volume( 0.1128 / amp_range * v );
- triangle.synth.volume( 0.12765 / amp_range * v );
- noise.synth.volume( 0.0741 / amp_range * v );
- dmc.synth.volume( 0.42545 / 127 * v );
-}
-
-void Nes_Apu::output( Blip_Buffer* buffer )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, buffer );
-}
-
-void Nes_Apu::set_tempo( double t )
-{
- tempo_ = t;
- frame_period = (dmc.pal_mode ? 8314 : 7458);
- if ( t != 1.0 )
- frame_period = (int) (frame_period / t) & ~1; // must be even
-}
-
-void Nes_Apu::reset( bool pal_mode, int initial_dmc_dac )
-{
- dmc.pal_mode = pal_mode;
- set_tempo( tempo_ );
-
- square1.reset();
- square2.reset();
- triangle.reset();
- noise.reset();
- dmc.reset();
-
- last_time = 0;
- last_dmc_time = 0;
- osc_enables = 0;
- irq_flag = false;
- earliest_irq_ = no_irq;
- frame_delay = 1;
- write_register( 0, 0x4017, 0x00 );
- write_register( 0, 0x4015, 0x00 );
-
- for ( nes_addr_t addr = start_addr; addr <= 0x4013; addr++ )
- write_register( 0, addr, (addr & 3) ? 0x00 : 0x10 );
-
- dmc.dac = initial_dmc_dac;
- if ( !dmc.nonlinear )
- triangle.last_amp = 15;
- if ( !dmc.nonlinear ) // TODO: remove?
- dmc.last_amp = initial_dmc_dac; // prevent output transition
-}
-
-void Nes_Apu::irq_changed()
-{
- nes_time_t new_irq = dmc.next_irq;
- if ( dmc.irq_flag | irq_flag ) {
- new_irq = 0;
- }
- else if ( new_irq > next_irq ) {
- new_irq = next_irq;
- }
-
- if ( new_irq != earliest_irq_ ) {
- earliest_irq_ = new_irq;
- if ( irq_notifier_ )
- irq_notifier_( irq_data );
- }
-}
-
-// frames
-
-void Nes_Apu::run_until( nes_time_t end_time )
-{
- require( end_time >= last_dmc_time );
- if ( end_time > next_dmc_read_time() )
- {
- nes_time_t start = last_dmc_time;
- last_dmc_time = end_time;
- dmc.run( start, end_time );
- }
-}
-
-void Nes_Apu::run_until_( nes_time_t end_time )
-{
- require( end_time >= last_time );
-
- if ( end_time == last_time )
- return;
-
- if ( last_dmc_time < end_time )
- {
- nes_time_t start = last_dmc_time;
- last_dmc_time = end_time;
- dmc.run( start, end_time );
- }
-
- while ( true )
- {
- // earlier of next frame time or end time
- nes_time_t time = last_time + frame_delay;
- if ( time > end_time )
- time = end_time;
- frame_delay -= time - last_time;
-
- // run oscs to present
- square1.run( last_time, time );
- square2.run( last_time, time );
- triangle.run( last_time, time );
- noise.run( last_time, time );
- last_time = time;
-
- if ( time == end_time )
- break; // no more frames to run
-
- // take frame-specific actions
- frame_delay = frame_period;
- switch ( frame++ )
- {
- case 0:
- if ( !(frame_mode & 0xC0) ) {
- next_irq = time + frame_period * 4 + 2;
- irq_flag = true;
- }
- // fall through
- case 2:
- // clock length and sweep on frames 0 and 2
- square1.clock_length( 0x20 );
- square2.clock_length( 0x20 );
- noise.clock_length( 0x20 );
- triangle.clock_length( 0x80 ); // different bit for halt flag on triangle
-
- square1.clock_sweep( -1 );
- square2.clock_sweep( 0 );
-
- // frame 2 is slightly shorter in mode 1
- if ( dmc.pal_mode && frame == 3 )
- frame_delay -= 2;
- break;
-
- case 1:
- // frame 1 is slightly shorter in mode 0
- if ( !dmc.pal_mode )
- frame_delay -= 2;
- break;
-
- case 3:
- frame = 0;
-
- // frame 3 is almost twice as long in mode 1
- if ( frame_mode & 0x80 )
- frame_delay += frame_period - (dmc.pal_mode ? 2 : 6);
- break;
- }
-
- // clock envelopes and linear counter every frame
- triangle.clock_linear_counter();
- square1.clock_envelope();
- square2.clock_envelope();
- noise.clock_envelope();
- }
-}
-
-template<class T>
-inline void zero_apu_osc( T* osc, nes_time_t time )
-{
- Blip_Buffer* output = osc->output;
- int last_amp = osc->last_amp;
- osc->last_amp = 0;
- if ( output && last_amp )
- osc->synth.offset( time, -last_amp, output );
-}
-
-void Nes_Apu::end_frame( nes_time_t end_time )
-{
- if ( end_time > last_time )
- run_until_( end_time );
-
- if ( dmc.nonlinear )
- {
- zero_apu_osc( &square1, last_time );
- zero_apu_osc( &square2, last_time );
- zero_apu_osc( &triangle, last_time );
- zero_apu_osc( &noise, last_time );
- zero_apu_osc( &dmc, last_time );
- }
-
- // make times relative to new frame
- last_time -= end_time;
- require( last_time >= 0 );
-
- last_dmc_time -= end_time;
- require( last_dmc_time >= 0 );
-
- if ( next_irq != no_irq ) {
- next_irq -= end_time;
- check( next_irq >= 0 );
- }
- if ( dmc.next_irq != no_irq ) {
- dmc.next_irq -= end_time;
- check( dmc.next_irq >= 0 );
- }
- if ( earliest_irq_ != no_irq ) {
- earliest_irq_ -= end_time;
- if ( earliest_irq_ < 0 )
- earliest_irq_ = 0;
- }
-}
-
-// registers
-
-static const unsigned char length_table [0x20] = {
- 0x0A, 0xFE, 0x14, 0x02, 0x28, 0x04, 0x50, 0x06,
- 0xA0, 0x08, 0x3C, 0x0A, 0x0E, 0x0C, 0x1A, 0x0E,
- 0x0C, 0x10, 0x18, 0x12, 0x30, 0x14, 0x60, 0x16,
- 0xC0, 0x18, 0x48, 0x1A, 0x10, 0x1C, 0x20, 0x1E
-};
-
-void Nes_Apu::write_register( nes_time_t time, nes_addr_t addr, int data )
-{
- require( addr > 0x20 ); // addr must be actual address (i.e. 0x40xx)
- require( (unsigned) data <= 0xFF );
-
- // Ignore addresses outside range
- if ( unsigned (addr - start_addr) > end_addr - start_addr )
- return;
-
- run_until_( time );
-
- if ( addr < 0x4014 )
- {
- // Write to channel
- int osc_index = (addr - start_addr) >> 2;
- Nes_Osc* osc = oscs [osc_index];
-
- int reg = addr & 3;
- osc->regs [reg] = data;
- osc->reg_written [reg] = true;
-
- if ( osc_index == 4 )
- {
- // handle DMC specially
- dmc.write_register( reg, data );
- }
- else if ( reg == 3 )
- {
- // load length counter
- if ( (osc_enables >> osc_index) & 1 )
- osc->length_counter = length_table [(data >> 3) & 0x1F];
-
- // reset square phase
- if ( osc_index < 2 )
- ((Nes_Square*) osc)->phase = Nes_Square::phase_range - 1;
- }
- }
- else if ( addr == 0x4015 )
- {
- // Channel enables
- for ( int i = osc_count; i--; )
- if ( !((data >> i) & 1) )
- oscs [i]->length_counter = 0;
-
- bool recalc_irq = dmc.irq_flag;
- dmc.irq_flag = false;
-
- int old_enables = osc_enables;
- osc_enables = data;
- if ( !(data & 0x10) ) {
- dmc.next_irq = no_irq;
- recalc_irq = true;
- }
- else if ( !(old_enables & 0x10) ) {
- dmc.start(); // dmc just enabled
- }
-
- if ( recalc_irq )
- irq_changed();
- }
- else if ( addr == 0x4017 )
- {
- // Frame mode
- frame_mode = data;
-
- bool irq_enabled = !(data & 0x40);
- irq_flag &= irq_enabled;
- next_irq = no_irq;
-
- // mode 1
- frame_delay = (frame_delay & 1);
- frame = 0;
-
- if ( !(data & 0x80) )
- {
- // mode 0
- frame = 1;
- frame_delay += frame_period;
- if ( irq_enabled )
- next_irq = time + frame_delay + frame_period * 3 + 1;
- }
-
- irq_changed();
- }
-}
-
-int Nes_Apu::read_status( nes_time_t time )
-{
- run_until_( time - 1 );
-
- int result = (dmc.irq_flag << 7) | (irq_flag << 6);
-
- for ( int i = 0; i < osc_count; i++ )
- if ( oscs [i]->length_counter )
- result |= 1 << i;
-
- run_until_( time );
-
- if ( irq_flag )
- {
- result |= 0x40;
- irq_flag = false;
- irq_changed();
- }
-
- //debug_printf( "%6d/%d Read $4015->$%02X\n", frame_delay, frame, result );
-
- return result;
-}
diff --git a/src/console/Nes_Apu.h b/src/console/Nes_Apu.h
index 69b9f55f1298..5a8f486faa14 100644
--- a/src/console/Nes_Apu.h
+++ b/src/console/Nes_Apu.h
@@ -16,13 +16,13 @@ class Nes_Buffer;
class Nes_Apu {
public:
- // Set buffer to generate all sound into, or disable sound if NULL
+ // Set buffer to generate all sound into, or disable sound if nullptr
void output( Blip_Buffer* );
// Set memory reader callback used by DMC oscillator to fetch samples.
// When callback is invoked, 'user_data' is passed unchanged as the
// first parameter.
- void dmc_reader( int (*callback)( void* user_data, nes_addr_t ), void* user_data = NULL );
+ void dmc_reader( int (*callback)( void* user_data, nes_addr_t ), void* user_data = nullptr );
// All time values are the number of CPU clock cycles relative to the
// beginning of the current time frame. Before resetting the CPU clock
@@ -63,7 +63,7 @@ public:
// Set treble equalization (see notes.txt)
void treble_eq( const blip_eq_t& );
- // Set sound output of specific oscillator to buffer. If buffer is NULL,
+ // Set sound output of specific oscillator to buffer. If buffer is nullptr,
// the specified oscillator is muted and emulation accuracy is reduced.
// The oscillators are indexed as follows: 0) Square 1, 1) Square 2,
// 2) Triangle, 3) Noise, 4) DMC.
@@ -71,9 +71,9 @@ public:
void osc_output( int index, Blip_Buffer* buffer );
// Set IRQ time callback that is invoked when the time of earliest IRQ
- // may have changed, or NULL to disable. When callback is invoked,
+ // may have changed, or nullptr to disable. When callback is invoked,
// 'user_data' is passed unchanged as the first parameter.
- void irq_notifier( void (*callback)( void* user_data ), void* user_data = NULL );
+ void irq_notifier( void (*callback)( void* user_data ), void* user_data = nullptr );
// Get time that APU-generated IRQ will occur if no further register reads
// or writes occur. If IRQ is already pending, returns irq_waiting. If no
@@ -83,9 +83,9 @@ public:
nes_time_t earliest_irq( nes_time_t ) const;
// Count number of DMC reads that would occur if 'run_until( t )' were executed.
- // If last_read is not NULL, set *last_read to the earliest time that
+ // If last_read is not nullptr, set *last_read to the earliest time that
// 'count_dmc_reads( time )' would result in the same result.
- int count_dmc_reads( nes_time_t t, nes_time_t* last_read = NULL ) const;
+ int count_dmc_reads( nes_time_t t, nes_time_t* last_read = nullptr ) const;
// Time when next DMC memory read will occur
nes_time_t next_dmc_read_time() const;
diff --git a/src/console/Nes_Cpu.cc b/src/console/Nes_Cpu.cc
new file mode 100644
index 000000000000..ce9b5df7981d
--- /dev/null
+++ b/src/console/Nes_Cpu.cc
@@ -0,0 +1,1082 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Nes_Cpu.h"
+
+#include "blargg_endian.h"
+#include <limits.h>
+
+#define BLARGG_CPU_X86 1
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifdef BLARGG_ENABLE_OPTIMIZER
+ #include BLARGG_ENABLE_OPTIMIZER
+#endif
+
+#define FLUSH_TIME() (void) (s.time = s_time)
+#define CACHE_TIME() (void) (s_time = s.time)
+
+#include "nes_cpu_io.h"
+
+#include "blargg_source.h"
+
+#ifndef CPU_DONE
+ #define CPU_DONE( cpu, time, result_out ) { result_out = -1; }
+#endif
+
+#ifndef CPU_READ_PPU
+ #define CPU_READ_PPU( cpu, addr, out, time )\
+ {\
+ FLUSH_TIME();\
+ out = CPU_READ( cpu, addr, time );\
+ CACHE_TIME();\
+ }
+#endif
+
+#if BLARGG_NONPORTABLE
+ #define PAGE_OFFSET( addr ) (addr)
+#else
+ #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
+#endif
+
+inline void Nes_Cpu::set_code_page( int i, void const* p )
+{
+ state->code_map [i] = (uint8_t const*) p - PAGE_OFFSET( i * page_size );
+}
+
+int const st_n = 0x80;
+int const st_v = 0x40;
+int const st_r = 0x20;
+int const st_b = 0x10;
+int const st_d = 0x08;
+int const st_i = 0x04;
+int const st_z = 0x02;
+int const st_c = 0x01;
+
+void Nes_Cpu::reset( void const* unmapped_page )
+{
+ check( state == &state_ );
+ state = &state_;
+ r.status = st_i;
+ r.sp = 0xFF;
+ r.pc = 0;
+ r.a = 0;
+ r.x = 0;
+ r.y = 0;
+ state_.time = 0;
+ state_.base = 0;
+ irq_time_ = future_nes_time;
+ end_time_ = future_nes_time;
+ error_count_ = 0;
+
+ assert( page_size == 0x800 ); // assumes this
+ set_code_page( page_count, unmapped_page );
+ map_code( 0x2000, 0xE000, unmapped_page, true );
+ map_code( 0x0000, 0x2000, low_mem, true );
+}
+
+void Nes_Cpu::map_code( nes_addr_t start, unsigned size, void const* data, bool mirror )
+{
+ // address range must begin and end on page boundaries
+ require( start % page_size == 0 );
+ require( size % page_size == 0 );
+ require( start + size <= 0x10000 );
+
+ unsigned page = start / page_size;
+ for ( unsigned n = size / page_size; n; --n )
+ {
+ set_code_page( page++, data );
+ if ( !mirror )
+ data = (char const*) data + page_size;
+ }
+}
+
+#define TIME (s_time + s.base)
+#define READ_LIKELY_PPU( addr, out ) {CPU_READ_PPU( this, (addr), out, TIME );}
+#define READ( addr ) CPU_READ( this, (addr), TIME )
+#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), TIME );}
+#define READ_LOW( addr ) (low_mem [int (addr)])
+#define WRITE_LOW( addr, data ) (void) (READ_LOW( addr ) = (data))
+#define READ_PROG( addr ) (s.code_map [(addr) >> page_bits] [PAGE_OFFSET( addr )])
+
+#define SET_SP( v ) (sp = ((v) + 1) | 0x100)
+#define GET_SP() ((sp - 1) & 0xFF)
+#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
+
+// even on x86, using short and unsigned char was slower
+typedef int fint16;
+typedef unsigned fuint16;
+typedef unsigned fuint8;
+
+bool Nes_Cpu::run( nes_time_t end_time )
+{
+ set_end_time( end_time );
+ state_t s = this->state_;
+ this->state = &s;
+ // even on x86, using s.time in place of s_time was slower
+ fint16 s_time = s.time;
+
+ // registers
+ fuint16 pc = r.pc;
+ fuint8 a = r.a;
+ fuint8 x = r.x;
+ fuint8 y = r.y;
+ fuint16 sp;
+ SET_SP( r.sp );
+
+ // status flags
+ #define IS_NEG (nz & 0x8080)
+
+ #define CALC_STATUS( out ) do {\
+ out = status & (st_v | st_d | st_i);\
+ out |= ((nz >> 8) | nz) & st_n;\
+ out |= c >> 8 & st_c;\
+ if ( !(nz & 0xFF) ) out |= st_z;\
+ } while ( 0 )
+
+ #define SET_STATUS( in ) do {\
+ status = in & (st_v | st_d | st_i);\
+ nz = in << 8;\
+ c = nz;\
+ nz |= ~in & st_z;\
+ } while ( 0 )
+
+ fuint8 status;
+ fuint16 c; // carry set if (c & 0x100) != 0
+ fuint16 nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
+ {
+ fuint8 temp = r.status;
+ SET_STATUS( temp );
+ }
+
+ goto loop;
+dec_clock_loop:
+ s_time--;
+loop:
+
+ check( (unsigned) GET_SP() < 0x100 );
+ check( (unsigned) pc < 0x10000 );
+ check( (unsigned) a < 0x100 );
+ check( (unsigned) x < 0x100 );
+ check( (unsigned) y < 0x100 );
+ check( -32768 <= s_time && s_time < 32767 );
+
+ uint8_t const* instr = s.code_map [pc >> page_bits];
+ fuint8 opcode;
+
+ // TODO: eliminate this special case
+ #if BLARGG_NONPORTABLE
+ opcode = instr [pc];
+ pc++;
+ instr += pc;
+ #else
+ instr += PAGE_OFFSET( pc );
+ opcode = *instr++;
+ pc++;
+ #endif
+
+ static uint8_t const clock_table [256] =
+ {// 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,// 0
+ 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 1
+ 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,// 2
+ 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 3
+ 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,// 4
+ 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 5
+ 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,// 6
+ 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 7
+ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// 8
+ 3,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,// 9
+ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// A
+ 3,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,// B
+ 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// C
+ 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// D
+ 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// E
+ 3,5,0,8,4,4,6,6,2,4,2,7,4,4,7,7 // F
+ }; // 0x00 was 7 and 0xF2 was 2
+
+ fuint16 data;
+
+#if !BLARGG_CPU_X86
+ if ( s_time >= 0 )
+ goto out_of_time;
+ s_time += clock_table [opcode];
+
+ data = *instr;
+
+ switch ( opcode )
+ {
+#else
+
+ data = clock_table [opcode];
+ if ( (s_time += data) >= 0 )
+ goto possibly_out_of_time;
+almost_out_of_time:
+
+ data = *instr;
+
+ switch ( opcode )
+ {
+possibly_out_of_time:
+ if ( s_time < (int) data )
+ goto almost_out_of_time;
+ s_time -= data;
+ goto out_of_time;
+#endif
+
+// Macros
+
+#define GET_MSB() (instr [1])
+#define ADD_PAGE() (pc++, data += 0x100 * GET_MSB())
+#define GET_ADDR() GET_LE16( instr )
+
+#define NO_PAGE_CROSSING( lsb )
+#define HANDLE_PAGE_CROSSING( lsb ) s_time += (lsb) >> 8;
+
+#define INC_DEC_XY( reg, n ) reg = uint8_t (nz = reg + n); goto loop;
+
+#define IND_Y( cross, out ) {\
+ fuint16 temp = READ_LOW( data ) + y;\
+ out = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
+ cross( temp );\
+ }
+
+#define IND_X( out ) {\
+ fuint16 temp = data + x;\
+ out = 0x100 * READ_LOW( uint8_t (temp + 1) ) + READ_LOW( uint8_t (temp) );\
+ }
+
+#define ARITH_ADDR_MODES( op )\
+case op - 0x04: /* (ind,x) */\
+ IND_X( data )\
+ goto ptr##op;\
+case op + 0x0C: /* (ind),y */\
+ IND_Y( HANDLE_PAGE_CROSSING, data )\
+ goto ptr##op;\
+case op + 0x10: /* zp,X */\
+ data = uint8_t (data + x);\
+case op + 0x00: /* zp */\
+ data = READ_LOW( data );\
+ goto imm##op;\
+case op + 0x14: /* abs,Y */\
+ data += y;\
+ goto ind##op;\
+case op + 0x18: /* abs,X */\
+ data += x;\
+ind##op:\
+ HANDLE_PAGE_CROSSING( data );\
+case op + 0x08: /* abs */\
+ ADD_PAGE();\
+ptr##op:\
+ FLUSH_TIME();\
+ data = READ( data );\
+ CACHE_TIME();\
+case op + 0x04: /* imm */\
+imm##op:
+
+// TODO: more efficient way to handle negative branch that wraps PC around
+#define BRANCH( cond )\
+{\
+ fint16 offset = (int8_t) data;\
+ fuint16 extra_clock = (++pc & 0xFF) + offset;\
+ if ( !(cond) ) goto dec_clock_loop;\
+ pc = uint16_t (pc + offset);\
+ s_time += extra_clock >> 8 & 1;\
+ goto loop;\
+}
+
+// Often-Used
+
+ case 0xB5: // LDA zp,x
+ a = nz = READ_LOW( uint8_t (data + x) );
+ pc++;
+ goto loop;
+
+ case 0xA5: // LDA zp
+ a = nz = READ_LOW( data );
+ pc++;
+ goto loop;
+
+ case 0xD0: // BNE
+ BRANCH( (uint8_t) nz );
+
+ case 0x20: { // JSR
+ fuint16 temp = pc + 1;
+ pc = GET_ADDR();
+ WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
+ sp = (sp - 2) | 0x100;
+ WRITE_LOW( sp, temp );
+ goto loop;
+ }
+
+ case 0x4C: // JMP abs
+ pc = GET_ADDR();
+ goto loop;
+
+ case 0xE8: // INX
+ INC_DEC_XY( x, 1 )
+
+ case 0x10: // BPL
+ BRANCH( !IS_NEG )
+
+ ARITH_ADDR_MODES( 0xC5 ) // CMP
+ nz = a - data;
+ pc++;
+ c = ~nz;
+ nz &= 0xFF;
+ goto loop;
+
+ case 0x30: // BMI
+ BRANCH( IS_NEG )
+
+ case 0xF0: // BEQ
+ BRANCH( !(uint8_t) nz );
+
+ case 0x95: // STA zp,x
+ data = uint8_t (data + x);
+ case 0x85: // STA zp
+ pc++;
+ WRITE_LOW( data, a );
+ goto loop;
+
+ case 0xC8: // INY
+ INC_DEC_XY( y, 1 )
+
+ case 0xA8: // TAY
+ y = a;
+ nz = a;
+ goto loop;
+
+ case 0x98: // TYA
+ a = y;
+ nz = y;
+ goto loop;
+
+ case 0xAD:{// LDA abs
+ unsigned addr = GET_ADDR();
+ pc += 2;
+ READ_LIKELY_PPU( addr, nz );
+ a = nz;
+ goto loop;
+ }
+
+ case 0x60: // RTS
+ pc = 1 + READ_LOW( sp );
+ pc += 0x100 * READ_LOW( 0x100 | (sp - 0xFF) );
+ sp = (sp - 0xFE) | 0x100;
+ goto loop;
+
+ {
+ fuint16 addr;
+
+ case 0x99: // STA abs,Y
+ addr = y + GET_ADDR();
+ pc += 2;
+ if ( addr <= 0x7FF )
+ {
+ WRITE_LOW( addr, a );
+ goto loop;
+ }
+ goto sta_ptr;
+
+ case 0x8D: // STA abs
+ addr = GET_ADDR();
+ pc += 2;
+ if ( addr <= 0x7FF )
+ {
+ WRITE_LOW( addr, a );
+ goto loop;
+ }
+ goto sta_ptr;
+
+ case 0x9D: // STA abs,X (slightly more common than STA abs)
+ addr = x + GET_ADDR();
+ pc += 2;
+ if ( addr <= 0x7FF )
+ {
+ WRITE_LOW( addr, a );
+ goto loop;
+ }
+ sta_ptr:
+ FLUSH_TIME();
+ WRITE( addr, a );
+ CACHE_TIME();
+ goto loop;
+
+ case 0x91: // STA (ind),Y
+ IND_Y( NO_PAGE_CROSSING, addr )
+ pc++;
+ goto sta_ptr;
+
+ case 0x81: // STA (ind,X)
+ IND_X( addr )
+ pc++;
+ goto sta_ptr;
+
+ }
+
+ case 0xA9: // LDA #imm
+ pc++;
+ a = data;
+ nz = data;
+ goto loop;
+
+ // common read instructions
+ {
+ fuint16 addr;
+
+ case 0xA1: // LDA (ind,X)
+ IND_X( addr )
+ pc++;
+ goto a_nz_read_addr;
+
+ case 0xB1:// LDA (ind),Y
+ addr = READ_LOW( data ) + y;
+ HANDLE_PAGE_CROSSING( addr );
+ addr += 0x100 * READ_LOW( (uint8_t) (data + 1) );
+ pc++;
+ a = nz = READ_PROG( addr );
+ if ( (addr ^ 0x8000) <= 0x9FFF )
+ goto loop;
+ goto a_nz_read_addr;
+
+ case 0xB9: // LDA abs,Y
+ HANDLE_PAGE_CROSSING( data + y );
+ addr = GET_ADDR() + y;
+ pc += 2;
+ a = nz = READ_PROG( addr );
+ if ( (addr ^ 0x8000) <= 0x9FFF )
+ goto loop;
+ goto a_nz_read_addr;
+
+ case 0xBD: // LDA abs,X
+ HANDLE_PAGE_CROSSING( data + x );
+ addr = GET_ADDR() + x;
+ pc += 2;
+ a = nz = READ_PROG( addr );
+ if ( (addr ^ 0x8000) <= 0x9FFF )
+ goto loop;
+ a_nz_read_addr:
+ FLUSH_TIME();
+ a = nz = READ( addr );
+ CACHE_TIME();
+ goto loop;
+
+ }
+
+// Branch
+
+ case 0x50: // BVC
+ BRANCH( !(status & st_v) )
+
+ case 0x70: // BVS
+ BRANCH( status & st_v )
+
+ case 0xB0: // BCS
+ BRANCH( c & 0x100 )
+
+ case 0x90: // BCC
+ BRANCH( !(c & 0x100) )
+
+// Load/store
+
+ case 0x94: // STY zp,x
+ data = uint8_t (data + x);
+ case 0x84: // STY zp
+ pc++;
+ WRITE_LOW( data, y );
+ goto loop;
+
+ case 0x96: // STX zp,y
+ data = uint8_t (data + y);
+ case 0x86: // STX zp
+ pc++;
+ WRITE_LOW( data, x );
+ goto loop;
+
+ case 0xB6: // LDX zp,y
+ data = uint8_t (data + y);
+ case 0xA6: // LDX zp
+ data = READ_LOW( data );
+ case 0xA2: // LDX #imm
+ pc++;
+ x = data;
+ nz = data;
+ goto loop;
+
+ case 0xB4: // LDY zp,x
+ data = uint8_t (data + x);
+ case 0xA4: // LDY zp
+ data = READ_LOW( data );
+ case 0xA0: // LDY #imm
+ pc++;
+ y = data;
+ nz = data;
+ goto loop;
+
+ case 0xBC: // LDY abs,X
+ data += x;
+ HANDLE_PAGE_CROSSING( data );
+ case 0xAC:{// LDY abs
+ unsigned addr = data + 0x100 * GET_MSB();
+ pc += 2;
+ FLUSH_TIME();
+ y = nz = READ( addr );
+ CACHE_TIME();
+ goto loop;
+ }
+
+ case 0xBE: // LDX abs,y
+ data += y;
+ HANDLE_PAGE_CROSSING( data );
+ case 0xAE:{// LDX abs
+ unsigned addr = data + 0x100 * GET_MSB();
+ pc += 2;
+ FLUSH_TIME();
+ x = nz = READ( addr );
+ CACHE_TIME();
+ goto loop;
+ }
+
+ {
+ fuint8 temp;
+ case 0x8C: // STY abs
+ temp = y;
+ goto store_abs;
+
+ case 0x8E: // STX abs
+ temp = x;
+ store_abs:
+ unsigned addr = GET_ADDR();
+ pc += 2;
+ if ( addr <= 0x7FF )
+ {
+ WRITE_LOW( addr, temp );
+ goto loop;
+ }
+ FLUSH_TIME();
+ WRITE( addr, temp );
+ CACHE_TIME();
+ goto loop;
+ }
+
+// Compare
+
+ case 0xEC:{// CPX abs
+ unsigned addr = GET_ADDR();
+ pc++;
+ FLUSH_TIME();
+ data = READ( addr );
+ CACHE_TIME();
+ goto cpx_data;
+ }
+
+ case 0xE4: // CPX zp
+ data = READ_LOW( data );
+ case 0xE0: // CPX #imm
+ cpx_data:
+ nz = x - data;
+ pc++;
+ c = ~nz;
+ nz &= 0xFF;
+ goto loop;
+
+ case 0xCC:{// CPY abs
+ unsigned addr = GET_ADDR();
+ pc++;
+ FLUSH_TIME();
+ data = READ( addr );
+ CACHE_TIME();
+ goto cpy_data;
+ }
+
+ case 0xC4: // CPY zp
+ data = READ_LOW( data );
+ case 0xC0: // CPY #imm
+ cpy_data:
+ nz = y - data;
+ pc++;
+ c = ~nz;
+ nz &= 0xFF;
+ goto loop;
+
+// Logical
+
+ ARITH_ADDR_MODES( 0x25 ) // AND
+ nz = (a &= data);
+ pc++;
+ goto loop;
+
+ ARITH_ADDR_MODES( 0x45 ) // EOR
+ nz = (a ^= data);
+ pc++;
+ goto loop;
+
+ ARITH_ADDR_MODES( 0x05 ) // ORA
+ nz = (a |= data);
+ pc++;
+ goto loop;
+
+ case 0x2C:{// BIT abs
+ unsigned addr = GET_ADDR();
+ pc += 2;
+ status &= ~st_v;
+ READ_LIKELY_PPU( addr, nz );
+ status |= nz & st_v;
+ if ( a & nz )
+ goto loop;
+ nz <<= 8; // result must be zero, even if N bit is set
+ goto loop;
+ }
+
+ case 0x24: // BIT zp
+ nz = READ_LOW( data );
+ pc++;
+ status &= ~st_v;
+ status |= nz & st_v;
+ if ( a & nz )
+ goto loop;
+ nz <<= 8; // result must be zero, even if N bit is set
+ goto loop;
+
+// Add/subtract
+
+ ARITH_ADDR_MODES( 0xE5 ) // SBC
+ case 0xEB: // unofficial equivalent
+ data ^= 0xFF;
+ goto adc_imm;
+
+ ARITH_ADDR_MODES( 0x65 ) // ADC
+ adc_imm: {
+ fint16 carry = c >> 8 & 1;
+ fint16 ov = (a ^ 0x80) + carry + (int8_t) data; // sign-extend
+ status &= ~st_v;
+ status |= ov >> 2 & 0x40;
+ c = nz = a + data + carry;
+ pc++;
+ a = (uint8_t) nz;
+ goto loop;
+ }
+
+// Shift/rotate
+
+ case 0x4A: // LSR A
+ c = 0;
+ case 0x6A: // ROR A
+ nz = c >> 1 & 0x80;
+ c = a << 8;
+ nz |= a >> 1;
+ a = nz;
+ goto loop;
+
+ case 0x0A: // ASL A
+ nz = a << 1;
+ c = nz;
+ a = (uint8_t) nz;
+ goto loop;
+
+ case 0x2A: { // ROL A
+ nz = a << 1;
+ fint16 temp = c >> 8 & 1;
+ c = nz;
+ nz |= temp;
+ a = (uint8_t) nz;
+ goto loop;
+ }
+
+ case 0x5E: // LSR abs,X
+ data += x;
+ case 0x4E: // LSR abs
+ c = 0;
+ case 0x6E: // ROR abs
+ ror_abs: {
+ ADD_PAGE();
+ FLUSH_TIME();
+ int temp = READ( data );
+ nz = (c >> 1 & 0x80) | (temp >> 1);
+ c = temp << 8;
+ goto rotate_common;
+ }
+
+ case 0x3E: // ROL abs,X
+ data += x;
+ goto rol_abs;
+
+ case 0x1E: // ASL abs,X
+ data += x;
+ case 0x0E: // ASL abs
+ c = 0;
+ case 0x2E: // ROL abs
+ rol_abs:
+ ADD_PAGE();
+ nz = c >> 8 & 1;
+ FLUSH_TIME();
+ nz |= (c = READ( data ) << 1);
+ rotate_common:
+ pc++;
+ WRITE( data, (uint8_t) nz );
+ CACHE_TIME();
+ goto loop;
+
+ case 0x7E: // ROR abs,X
+ data += x;
+ goto ror_abs;
+
+ case 0x76: // ROR zp,x
+ data = uint8_t (data + x);
+ goto ror_zp;
+
+ case 0x56: // LSR zp,x
+ data = uint8_t (data + x);
+ case 0x46: // LSR zp
+ c = 0;
+ case 0x66: // ROR zp
+ ror_zp: {
+ int temp = READ_LOW( data );
+ nz = (c >> 1 & 0x80) | (temp >> 1);
+ c = temp << 8;
+ goto write_nz_zp;
+ }
+
+ case 0x36: // ROL zp,x
+ data = uint8_t (data + x);
+ goto rol_zp;
+
+ case 0x16: // ASL zp,x
+ data = uint8_t (data + x);
+ case 0x06: // ASL zp
+ c = 0;
+ case 0x26: // ROL zp
+ rol_zp:
+ nz = c >> 8 & 1;
+ nz |= (c = READ_LOW( data ) << 1);
+ goto write_nz_zp;
+
+// Increment/decrement
+
+ case 0xCA: // DEX
+ INC_DEC_XY( x, -1 )
+
+ case 0x88: // DEY
+ INC_DEC_XY( y, -1 )
+
+ case 0xF6: // INC zp,x
+ data = uint8_t (data + x);
+ case 0xE6: // INC zp
+ nz = 1;
+ goto add_nz_zp;
+
+ case 0xD6: // DEC zp,x
+ data = uint8_t (data + x);
+ case 0xC6: // DEC zp
+ nz = (unsigned) -1;
+ add_nz_zp:
+ nz += READ_LOW( data );
+ write_nz_zp:
+ pc++;
+ WRITE_LOW( data, nz );
+ goto loop;
+
+ case 0xFE: // INC abs,x
+ data = x + GET_ADDR();
+ goto inc_ptr;
+
+ case 0xEE: // INC abs
+ data = GET_ADDR();
+ inc_ptr:
+ nz = 1;
+ goto inc_common;
+
+ case 0xDE: // DEC abs,x
+ data = x + GET_ADDR();
+ goto dec_ptr;
+
+ case 0xCE: // DEC abs
+ data = GET_ADDR();
+ dec_ptr:
+ nz = (unsigned) -1;
+ inc_common:
+ FLUSH_TIME();
+ nz += READ( data );
+ pc += 2;
+ WRITE( data, (uint8_t) nz );
+ CACHE_TIME();
+ goto loop;
+
+// Transfer
+
+ case 0xAA: // TAX
+ x = a;
+ nz = a;
+ goto loop;
+
+ case 0x8A: // TXA
+ a = x;
+ nz = x;
+ goto loop;
+
+ case 0x9A: // TXS
+ SET_SP( x ); // verified (no flag change)
+ goto loop;
+
+ case 0xBA: // TSX
+ x = nz = GET_SP();
+ goto loop;
+
+// Stack
+
+ case 0x48: // PHA
+ PUSH( a ); // verified
+ goto loop;
+
+ case 0x68: // PLA
+ a = nz = READ_LOW( sp );
+ sp = (sp - 0xFF) | 0x100;
+ goto loop;
+
+ case 0x40:{// RTI
+ fuint8 temp = READ_LOW( sp );
+ pc = READ_LOW( 0x100 | (sp - 0xFF) );
+ pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
+ sp = (sp - 0xFD) | 0x100;
+ data = status;
+ SET_STATUS( temp );
+ if ( !((data ^ status) & st_i) ) goto loop; // I flag didn't change
+ this->r.status = status; // update externally-visible I flag
+ blargg_long delta = s.base - irq_time_;
+ if ( delta <= 0 ) goto loop;
+ if ( status & st_i ) goto loop;
+ s_time += delta;
+ s.base = irq_time_;
+ goto loop;
+ }
+
+ case 0x28:{// PLP
+ fuint8 temp = READ_LOW( sp );
+ sp = (sp - 0xFF) | 0x100;
+ fuint8 changed = status ^ temp;
+ SET_STATUS( temp );
+ if ( !(changed & st_i) )
+ goto loop; // I flag didn't change
+ if ( status & st_i )
+ goto handle_sei;
+ goto handle_cli;
+ }
+
+ case 0x08: { // PHP
+ fuint8 temp;
+ CALC_STATUS( temp );
+ PUSH( temp | (st_b | st_r) );
+ goto loop;
+ }
+
+ case 0x6C:{// JMP (ind)
+ data = GET_ADDR();
+ check( unsigned (data - 0x2000) >= 0x4000 ); // ensure it's outside I/O space
+ uint8_t const* page = s.code_map [data >> page_bits];
+ pc = page [PAGE_OFFSET( data )];
+ data = (data & 0xFF00) | ((data + 1) & 0xFF);
+ pc |= page [PAGE_OFFSET( data )] << 8;
+ goto loop;
+ }
+
+ case 0x00: // BRK
+ goto handle_brk;
+
+// Flags
+
+ case 0x38: // SEC
+ c = (unsigned) ~0;
+ goto loop;
+
+ case 0x18: // CLC
+ c = 0;
+ goto loop;
+
+ case 0xB8: // CLV
+ status &= ~st_v;
+ goto loop;
+
+ case 0xD8: // CLD
+ status &= ~st_d;
+ goto loop;
+
+ case 0xF8: // SED
+ status |= st_d;
+ goto loop;
+
+ case 0x58: // CLI
+ if ( !(status & st_i) )
+ goto loop;
+ status &= ~st_i;
+ handle_cli: {
+ //debug_printf( "CLI at %d\n", TIME );
+ this->r.status = status; // update externally-visible I flag
+ blargg_long delta = s.base - irq_time_;
+ if ( delta <= 0 )
+ {
+ if ( TIME < irq_time_ )
+ goto loop;
+ goto delayed_cli;
+ }
+ s.base = irq_time_;
+ s_time += delta;
+ if ( s_time < 0 )
+ goto loop;
+
+ if ( delta >= s_time + 1 )
+ {
+ s.base += s_time + 1;
+ s_time = -1;
+ goto loop;
+ }
+
+ // TODO: implement
+ delayed_cli:
+ debug_printf( "Delayed CLI not emulated\n" );
+ goto loop;
+ }
+
+ case 0x78: // SEI
+ if ( status & st_i )
+ goto loop;
+ status |= st_i;
+ handle_sei: {
+ this->r.status = status; // update externally-visible I flag
+ blargg_long delta = s.base - end_time_;
+ s.base = end_time_;
+ s_time += delta;
+ if ( s_time < 0 )
+ goto loop;
+
+ debug_printf( "Delayed SEI not emulated\n" );
+ goto loop;
+ }
+
+// Unofficial
+
+ // SKW - Skip word
+ case 0x1C: case 0x3C: case 0x5C: case 0x7C: case 0xDC: case 0xFC:
+ HANDLE_PAGE_CROSSING( data + x );
+ case 0x0C:
+ pc++;
+ // SKB - Skip byte
+ case 0x74: case 0x04: case 0x14: case 0x34: case 0x44: case 0x54: case 0x64:
+ case 0x80: case 0x82: case 0x89: case 0xC2: case 0xD4: case 0xE2: case 0xF4:
+ pc++;
+ goto loop;
+
+ // NOP
+ case 0xEA: case 0x1A: case 0x3A: case 0x5A: case 0x7A: case 0xDA: case 0xFA:
+ goto loop;
+
+ case bad_opcode: // HLT
+ pc--;
+ if ( pc > 0xFFFF )
+ {
+ // handle wrap-around (assumes caller has put page of HLT at 0x10000)
+ pc &= 0xFFFF;
+ goto loop;
+ }
+ case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52:
+ case 0x62: case 0x72: case 0x92: case 0xB2: case 0xD2:
+ goto stop;
+
+// Unimplemented
+
+ case 0xFF: // force 256-entry jump table for optimization purposes
+ c |= 1;
+ default:
+ check( (unsigned) opcode <= 0xFF );
+ // skip over proper number of bytes
+ static unsigned char const illop_lens [8] = {
+ 0x40, 0x40, 0x40, 0x80, 0x40, 0x40, 0x80, 0xA0
+ };
+ fuint8 opcode = instr [-1];
+ fint16 len = illop_lens [opcode >> 2 & 7] >> (opcode << 1 & 6) & 3;
+ if ( opcode == 0x9C )
+ len = 2;
+ pc += len;
+ error_count_++;
+
+ if ( (opcode >> 4) == 0x0B )
+ {
+ if ( opcode == 0xB3 )
+ data = READ_LOW( data );
+ if ( opcode != 0xB7 )
+ HANDLE_PAGE_CROSSING( data + y );
+ }
+ goto loop;
+ }
+ assert( false );
+
+ int result_;
+handle_brk:
+ pc++;
+ result_ = 4;
+
+interrupt:
+ {
+ s_time += 7;
+
+ WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
+ WRITE_LOW( 0x100 | (sp - 2), pc );
+ pc = GET_LE16( &READ_PROG( 0xFFFA ) + result_ );
+
+ sp = (sp - 3) | 0x100;
+ fuint8 temp;
+ CALC_STATUS( temp );
+ temp |= st_r;
+ if ( result_ )
+ temp |= st_b; // TODO: incorrectly sets B flag for IRQ
+ WRITE_LOW( sp, temp );
+
+ this->r.status = status |= st_i;
+ blargg_long delta = s.base - end_time_;
+ if ( delta >= 0 ) goto loop;
+ s_time += delta;
+ s.base = end_time_;
+ goto loop;
+ }
+
+out_of_time:
+ pc--;
+ FLUSH_TIME();
+ CPU_DONE( this, TIME, result_ );
+ CACHE_TIME();
+ if ( result_ >= 0 )
+ goto interrupt;
+ if ( s_time < 0 )
+ goto loop;
+
+stop:
+
+ s.time = s_time;
+
+ r.pc = pc;
+ r.sp = GET_SP();
+ r.a = a;
+ r.x = x;
+ r.y = y;
+
+ {
+ fuint8 temp;
+ CALC_STATUS( temp );
+ r.status = temp;
+ }
+
+ this->state_ = s;
+ this->state = &this->state_;
+
+ return s_time < 0;
+}
+
diff --git a/src/console/Nes_Cpu.cxx b/src/console/Nes_Cpu.cxx
deleted file mode 100644
index ce9b5df7981d..000000000000
--- a/src/console/Nes_Cpu.cxx
+++ /dev/null
@@ -1,1082 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Nes_Cpu.h"
-
-#include "blargg_endian.h"
-#include <limits.h>
-
-#define BLARGG_CPU_X86 1
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-#define FLUSH_TIME() (void) (s.time = s_time)
-#define CACHE_TIME() (void) (s_time = s.time)
-
-#include "nes_cpu_io.h"
-
-#include "blargg_source.h"
-
-#ifndef CPU_DONE
- #define CPU_DONE( cpu, time, result_out ) { result_out = -1; }
-#endif
-
-#ifndef CPU_READ_PPU
- #define CPU_READ_PPU( cpu, addr, out, time )\
- {\
- FLUSH_TIME();\
- out = CPU_READ( cpu, addr, time );\
- CACHE_TIME();\
- }
-#endif
-
-#if BLARGG_NONPORTABLE
- #define PAGE_OFFSET( addr ) (addr)
-#else
- #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
-#endif
-
-inline void Nes_Cpu::set_code_page( int i, void const* p )
-{
- state->code_map [i] = (uint8_t const*) p - PAGE_OFFSET( i * page_size );
-}
-
-int const st_n = 0x80;
-int const st_v = 0x40;
-int const st_r = 0x20;
-int const st_b = 0x10;
-int const st_d = 0x08;
-int const st_i = 0x04;
-int const st_z = 0x02;
-int const st_c = 0x01;
-
-void Nes_Cpu::reset( void const* unmapped_page )
-{
- check( state == &state_ );
- state = &state_;
- r.status = st_i;
- r.sp = 0xFF;
- r.pc = 0;
- r.a = 0;
- r.x = 0;
- r.y = 0;
- state_.time = 0;
- state_.base = 0;
- irq_time_ = future_nes_time;
- end_time_ = future_nes_time;
- error_count_ = 0;
-
- assert( page_size == 0x800 ); // assumes this
- set_code_page( page_count, unmapped_page );
- map_code( 0x2000, 0xE000, unmapped_page, true );
- map_code( 0x0000, 0x2000, low_mem, true );
-}
-
-void Nes_Cpu::map_code( nes_addr_t start, unsigned size, void const* data, bool mirror )
-{
- // address range must begin and end on page boundaries
- require( start % page_size == 0 );
- require( size % page_size == 0 );
- require( start + size <= 0x10000 );
-
- unsigned page = start / page_size;
- for ( unsigned n = size / page_size; n; --n )
- {
- set_code_page( page++, data );
- if ( !mirror )
- data = (char const*) data + page_size;
- }
-}
-
-#define TIME (s_time + s.base)
-#define READ_LIKELY_PPU( addr, out ) {CPU_READ_PPU( this, (addr), out, TIME );}
-#define READ( addr ) CPU_READ( this, (addr), TIME )
-#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), TIME );}
-#define READ_LOW( addr ) (low_mem [int (addr)])
-#define WRITE_LOW( addr, data ) (void) (READ_LOW( addr ) = (data))
-#define READ_PROG( addr ) (s.code_map [(addr) >> page_bits] [PAGE_OFFSET( addr )])
-
-#define SET_SP( v ) (sp = ((v) + 1) | 0x100)
-#define GET_SP() ((sp - 1) & 0xFF)
-#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-
-bool Nes_Cpu::run( nes_time_t end_time )
-{
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- // even on x86, using s.time in place of s_time was slower
- fint16 s_time = s.time;
-
- // registers
- fuint16 pc = r.pc;
- fuint8 a = r.a;
- fuint8 x = r.x;
- fuint8 y = r.y;
- fuint16 sp;
- SET_SP( r.sp );
-
- // status flags
- #define IS_NEG (nz & 0x8080)
-
- #define CALC_STATUS( out ) do {\
- out = status & (st_v | st_d | st_i);\
- out |= ((nz >> 8) | nz) & st_n;\
- out |= c >> 8 & st_c;\
- if ( !(nz & 0xFF) ) out |= st_z;\
- } while ( 0 )
-
- #define SET_STATUS( in ) do {\
- status = in & (st_v | st_d | st_i);\
- nz = in << 8;\
- c = nz;\
- nz |= ~in & st_z;\
- } while ( 0 )
-
- fuint8 status;
- fuint16 c; // carry set if (c & 0x100) != 0
- fuint16 nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
- {
- fuint8 temp = r.status;
- SET_STATUS( temp );
- }
-
- goto loop;
-dec_clock_loop:
- s_time--;
-loop:
-
- check( (unsigned) GET_SP() < 0x100 );
- check( (unsigned) pc < 0x10000 );
- check( (unsigned) a < 0x100 );
- check( (unsigned) x < 0x100 );
- check( (unsigned) y < 0x100 );
- check( -32768 <= s_time && s_time < 32767 );
-
- uint8_t const* instr = s.code_map [pc >> page_bits];
- fuint8 opcode;
-
- // TODO: eliminate this special case
- #if BLARGG_NONPORTABLE
- opcode = instr [pc];
- pc++;
- instr += pc;
- #else
- instr += PAGE_OFFSET( pc );
- opcode = *instr++;
- pc++;
- #endif
-
- static uint8_t const clock_table [256] =
- {// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,// 0
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 1
- 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,// 2
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 3
- 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,// 4
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 5
- 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,// 6
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 7
- 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// 8
- 3,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,// 9
- 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// A
- 3,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,// B
- 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// C
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// D
- 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// E
- 3,5,0,8,4,4,6,6,2,4,2,7,4,4,7,7 // F
- }; // 0x00 was 7 and 0xF2 was 2
-
- fuint16 data;
-
-#if !BLARGG_CPU_X86
- if ( s_time >= 0 )
- goto out_of_time;
- s_time += clock_table [opcode];
-
- data = *instr;
-
- switch ( opcode )
- {
-#else
-
- data = clock_table [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = *instr;
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-#endif
-
-// Macros
-
-#define GET_MSB() (instr [1])
-#define ADD_PAGE() (pc++, data += 0x100 * GET_MSB())
-#define GET_ADDR() GET_LE16( instr )
-
-#define NO_PAGE_CROSSING( lsb )
-#define HANDLE_PAGE_CROSSING( lsb ) s_time += (lsb) >> 8;
-
-#define INC_DEC_XY( reg, n ) reg = uint8_t (nz = reg + n); goto loop;
-
-#define IND_Y( cross, out ) {\
- fuint16 temp = READ_LOW( data ) + y;\
- out = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
- cross( temp );\
- }
-
-#define IND_X( out ) {\
- fuint16 temp = data + x;\
- out = 0x100 * READ_LOW( uint8_t (temp + 1) ) + READ_LOW( uint8_t (temp) );\
- }
-
-#define ARITH_ADDR_MODES( op )\
-case op - 0x04: /* (ind,x) */\
- IND_X( data )\
- goto ptr##op;\
-case op + 0x0C: /* (ind),y */\
- IND_Y( HANDLE_PAGE_CROSSING, data )\
- goto ptr##op;\
-case op + 0x10: /* zp,X */\
- data = uint8_t (data + x);\
-case op + 0x00: /* zp */\
- data = READ_LOW( data );\
- goto imm##op;\
-case op + 0x14: /* abs,Y */\
- data += y;\
- goto ind##op;\
-case op + 0x18: /* abs,X */\
- data += x;\
-ind##op:\
- HANDLE_PAGE_CROSSING( data );\
-case op + 0x08: /* abs */\
- ADD_PAGE();\
-ptr##op:\
- FLUSH_TIME();\
- data = READ( data );\
- CACHE_TIME();\
-case op + 0x04: /* imm */\
-imm##op:
-
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define BRANCH( cond )\
-{\
- fint16 offset = (int8_t) data;\
- fuint16 extra_clock = (++pc & 0xFF) + offset;\
- if ( !(cond) ) goto dec_clock_loop;\
- pc = uint16_t (pc + offset);\
- s_time += extra_clock >> 8 & 1;\
- goto loop;\
-}
-
-// Often-Used
-
- case 0xB5: // LDA zp,x
- a = nz = READ_LOW( uint8_t (data + x) );
- pc++;
- goto loop;
-
- case 0xA5: // LDA zp
- a = nz = READ_LOW( data );
- pc++;
- goto loop;
-
- case 0xD0: // BNE
- BRANCH( (uint8_t) nz );
-
- case 0x20: { // JSR
- fuint16 temp = pc + 1;
- pc = GET_ADDR();
- WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
- sp = (sp - 2) | 0x100;
- WRITE_LOW( sp, temp );
- goto loop;
- }
-
- case 0x4C: // JMP abs
- pc = GET_ADDR();
- goto loop;
-
- case 0xE8: // INX
- INC_DEC_XY( x, 1 )
-
- case 0x10: // BPL
- BRANCH( !IS_NEG )
-
- ARITH_ADDR_MODES( 0xC5 ) // CMP
- nz = a - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0x30: // BMI
- BRANCH( IS_NEG )
-
- case 0xF0: // BEQ
- BRANCH( !(uint8_t) nz );
-
- case 0x95: // STA zp,x
- data = uint8_t (data + x);
- case 0x85: // STA zp
- pc++;
- WRITE_LOW( data, a );
- goto loop;
-
- case 0xC8: // INY
- INC_DEC_XY( y, 1 )
-
- case 0xA8: // TAY
- y = a;
- nz = a;
- goto loop;
-
- case 0x98: // TYA
- a = y;
- nz = y;
- goto loop;
-
- case 0xAD:{// LDA abs
- unsigned addr = GET_ADDR();
- pc += 2;
- READ_LIKELY_PPU( addr, nz );
- a = nz;
- goto loop;
- }
-
- case 0x60: // RTS
- pc = 1 + READ_LOW( sp );
- pc += 0x100 * READ_LOW( 0x100 | (sp - 0xFF) );
- sp = (sp - 0xFE) | 0x100;
- goto loop;
-
- {
- fuint16 addr;
-
- case 0x99: // STA abs,Y
- addr = y + GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- goto sta_ptr;
-
- case 0x8D: // STA abs
- addr = GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- goto sta_ptr;
-
- case 0x9D: // STA abs,X (slightly more common than STA abs)
- addr = x + GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- sta_ptr:
- FLUSH_TIME();
- WRITE( addr, a );
- CACHE_TIME();
- goto loop;
-
- case 0x91: // STA (ind),Y
- IND_Y( NO_PAGE_CROSSING, addr )
- pc++;
- goto sta_ptr;
-
- case 0x81: // STA (ind,X)
- IND_X( addr )
- pc++;
- goto sta_ptr;
-
- }
-
- case 0xA9: // LDA #imm
- pc++;
- a = data;
- nz = data;
- goto loop;
-
- // common read instructions
- {
- fuint16 addr;
-
- case 0xA1: // LDA (ind,X)
- IND_X( addr )
- pc++;
- goto a_nz_read_addr;
-
- case 0xB1:// LDA (ind),Y
- addr = READ_LOW( data ) + y;
- HANDLE_PAGE_CROSSING( addr );
- addr += 0x100 * READ_LOW( (uint8_t) (data + 1) );
- pc++;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- goto a_nz_read_addr;
-
- case 0xB9: // LDA abs,Y
- HANDLE_PAGE_CROSSING( data + y );
- addr = GET_ADDR() + y;
- pc += 2;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- goto a_nz_read_addr;
-
- case 0xBD: // LDA abs,X
- HANDLE_PAGE_CROSSING( data + x );
- addr = GET_ADDR() + x;
- pc += 2;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- a_nz_read_addr:
- FLUSH_TIME();
- a = nz = READ( addr );
- CACHE_TIME();
- goto loop;
-
- }
-
-// Branch
-
- case 0x50: // BVC
- BRANCH( !(status & st_v) )
-
- case 0x70: // BVS
- BRANCH( status & st_v )
-
- case 0xB0: // BCS
- BRANCH( c & 0x100 )
-
- case 0x90: // BCC
- BRANCH( !(c & 0x100) )
-
-// Load/store
-
- case 0x94: // STY zp,x
- data = uint8_t (data + x);
- case 0x84: // STY zp
- pc++;
- WRITE_LOW( data, y );
- goto loop;
-
- case 0x96: // STX zp,y
- data = uint8_t (data + y);
- case 0x86: // STX zp
- pc++;
- WRITE_LOW( data, x );
- goto loop;
-
- case 0xB6: // LDX zp,y
- data = uint8_t (data + y);
- case 0xA6: // LDX zp
- data = READ_LOW( data );
- case 0xA2: // LDX #imm
- pc++;
- x = data;
- nz = data;
- goto loop;
-
- case 0xB4: // LDY zp,x
- data = uint8_t (data + x);
- case 0xA4: // LDY zp
- data = READ_LOW( data );
- case 0xA0: // LDY #imm
- pc++;
- y = data;
- nz = data;
- goto loop;
-
- case 0xBC: // LDY abs,X
- data += x;
- HANDLE_PAGE_CROSSING( data );
- case 0xAC:{// LDY abs
- unsigned addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- y = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- case 0xBE: // LDX abs,y
- data += y;
- HANDLE_PAGE_CROSSING( data );
- case 0xAE:{// LDX abs
- unsigned addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- x = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- {
- fuint8 temp;
- case 0x8C: // STY abs
- temp = y;
- goto store_abs;
-
- case 0x8E: // STX abs
- temp = x;
- store_abs:
- unsigned addr = GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, temp );
- goto loop;
- }
- FLUSH_TIME();
- WRITE( addr, temp );
- CACHE_TIME();
- goto loop;
- }
-
-// Compare
-
- case 0xEC:{// CPX abs
- unsigned addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpx_data;
- }
-
- case 0xE4: // CPX zp
- data = READ_LOW( data );
- case 0xE0: // CPX #imm
- cpx_data:
- nz = x - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0xCC:{// CPY abs
- unsigned addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpy_data;
- }
-
- case 0xC4: // CPY zp
- data = READ_LOW( data );
- case 0xC0: // CPY #imm
- cpy_data:
- nz = y - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
-// Logical
-
- ARITH_ADDR_MODES( 0x25 ) // AND
- nz = (a &= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x45 ) // EOR
- nz = (a ^= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x05 ) // ORA
- nz = (a |= data);
- pc++;
- goto loop;
-
- case 0x2C:{// BIT abs
- unsigned addr = GET_ADDR();
- pc += 2;
- status &= ~st_v;
- READ_LIKELY_PPU( addr, nz );
- status |= nz & st_v;
- if ( a & nz )
- goto loop;
- nz <<= 8; // result must be zero, even if N bit is set
- goto loop;
- }
-
- case 0x24: // BIT zp
- nz = READ_LOW( data );
- pc++;
- status &= ~st_v;
- status |= nz & st_v;
- if ( a & nz )
- goto loop;
- nz <<= 8; // result must be zero, even if N bit is set
- goto loop;
-
-// Add/subtract
-
- ARITH_ADDR_MODES( 0xE5 ) // SBC
- case 0xEB: // unofficial equivalent
- data ^= 0xFF;
- goto adc_imm;
-
- ARITH_ADDR_MODES( 0x65 ) // ADC
- adc_imm: {
- fint16 carry = c >> 8 & 1;
- fint16 ov = (a ^ 0x80) + carry + (int8_t) data; // sign-extend
- status &= ~st_v;
- status |= ov >> 2 & 0x40;
- c = nz = a + data + carry;
- pc++;
- a = (uint8_t) nz;
- goto loop;
- }
-
-// Shift/rotate
-
- case 0x4A: // LSR A
- c = 0;
- case 0x6A: // ROR A
- nz = c >> 1 & 0x80;
- c = a << 8;
- nz |= a >> 1;
- a = nz;
- goto loop;
-
- case 0x0A: // ASL A
- nz = a << 1;
- c = nz;
- a = (uint8_t) nz;
- goto loop;
-
- case 0x2A: { // ROL A
- nz = a << 1;
- fint16 temp = c >> 8 & 1;
- c = nz;
- nz |= temp;
- a = (uint8_t) nz;
- goto loop;
- }
-
- case 0x5E: // LSR abs,X
- data += x;
- case 0x4E: // LSR abs
- c = 0;
- case 0x6E: // ROR abs
- ror_abs: {
- ADD_PAGE();
- FLUSH_TIME();
- int temp = READ( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto rotate_common;
- }
-
- case 0x3E: // ROL abs,X
- data += x;
- goto rol_abs;
-
- case 0x1E: // ASL abs,X
- data += x;
- case 0x0E: // ASL abs
- c = 0;
- case 0x2E: // ROL abs
- rol_abs:
- ADD_PAGE();
- nz = c >> 8 & 1;
- FLUSH_TIME();
- nz |= (c = READ( data ) << 1);
- rotate_common:
- pc++;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
- case 0x7E: // ROR abs,X
- data += x;
- goto ror_abs;
-
- case 0x76: // ROR zp,x
- data = uint8_t (data + x);
- goto ror_zp;
-
- case 0x56: // LSR zp,x
- data = uint8_t (data + x);
- case 0x46: // LSR zp
- c = 0;
- case 0x66: // ROR zp
- ror_zp: {
- int temp = READ_LOW( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto write_nz_zp;
- }
-
- case 0x36: // ROL zp,x
- data = uint8_t (data + x);
- goto rol_zp;
-
- case 0x16: // ASL zp,x
- data = uint8_t (data + x);
- case 0x06: // ASL zp
- c = 0;
- case 0x26: // ROL zp
- rol_zp:
- nz = c >> 8 & 1;
- nz |= (c = READ_LOW( data ) << 1);
- goto write_nz_zp;
-
-// Increment/decrement
-
- case 0xCA: // DEX
- INC_DEC_XY( x, -1 )
-
- case 0x88: // DEY
- INC_DEC_XY( y, -1 )
-
- case 0xF6: // INC zp,x
- data = uint8_t (data + x);
- case 0xE6: // INC zp
- nz = 1;
- goto add_nz_zp;
-
- case 0xD6: // DEC zp,x
- data = uint8_t (data + x);
- case 0xC6: // DEC zp
- nz = (unsigned) -1;
- add_nz_zp:
- nz += READ_LOW( data );
- write_nz_zp:
- pc++;
- WRITE_LOW( data, nz );
- goto loop;
-
- case 0xFE: // INC abs,x
- data = x + GET_ADDR();
- goto inc_ptr;
-
- case 0xEE: // INC abs
- data = GET_ADDR();
- inc_ptr:
- nz = 1;
- goto inc_common;
-
- case 0xDE: // DEC abs,x
- data = x + GET_ADDR();
- goto dec_ptr;
-
- case 0xCE: // DEC abs
- data = GET_ADDR();
- dec_ptr:
- nz = (unsigned) -1;
- inc_common:
- FLUSH_TIME();
- nz += READ( data );
- pc += 2;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
-// Transfer
-
- case 0xAA: // TAX
- x = a;
- nz = a;
- goto loop;
-
- case 0x8A: // TXA
- a = x;
- nz = x;
- goto loop;
-
- case 0x9A: // TXS
- SET_SP( x ); // verified (no flag change)
- goto loop;
-
- case 0xBA: // TSX
- x = nz = GET_SP();
- goto loop;
-
-// Stack
-
- case 0x48: // PHA
- PUSH( a ); // verified
- goto loop;
-
- case 0x68: // PLA
- a = nz = READ_LOW( sp );
- sp = (sp - 0xFF) | 0x100;
- goto loop;
-
- case 0x40:{// RTI
- fuint8 temp = READ_LOW( sp );
- pc = READ_LOW( 0x100 | (sp - 0xFF) );
- pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
- sp = (sp - 0xFD) | 0x100;
- data = status;
- SET_STATUS( temp );
- if ( !((data ^ status) & st_i) ) goto loop; // I flag didn't change
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - irq_time_;
- if ( delta <= 0 ) goto loop;
- if ( status & st_i ) goto loop;
- s_time += delta;
- s.base = irq_time_;
- goto loop;
- }
-
- case 0x28:{// PLP
- fuint8 temp = READ_LOW( sp );
- sp = (sp - 0xFF) | 0x100;
- fuint8 changed = status ^ temp;
- SET_STATUS( temp );
- if ( !(changed & st_i) )
- goto loop; // I flag didn't change
- if ( status & st_i )
- goto handle_sei;
- goto handle_cli;
- }
-
- case 0x08: { // PHP
- fuint8 temp;
- CALC_STATUS( temp );
- PUSH( temp | (st_b | st_r) );
- goto loop;
- }
-
- case 0x6C:{// JMP (ind)
- data = GET_ADDR();
- check( unsigned (data - 0x2000) >= 0x4000 ); // ensure it's outside I/O space
- uint8_t const* page = s.code_map [data >> page_bits];
- pc = page [PAGE_OFFSET( data )];
- data = (data & 0xFF00) | ((data + 1) & 0xFF);
- pc |= page [PAGE_OFFSET( data )] << 8;
- goto loop;
- }
-
- case 0x00: // BRK
- goto handle_brk;
-
-// Flags
-
- case 0x38: // SEC
- c = (unsigned) ~0;
- goto loop;
-
- case 0x18: // CLC
- c = 0;
- goto loop;
-
- case 0xB8: // CLV
- status &= ~st_v;
- goto loop;
-
- case 0xD8: // CLD
- status &= ~st_d;
- goto loop;
-
- case 0xF8: // SED
- status |= st_d;
- goto loop;
-
- case 0x58: // CLI
- if ( !(status & st_i) )
- goto loop;
- status &= ~st_i;
- handle_cli: {
- //debug_printf( "CLI at %d\n", TIME );
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - irq_time_;
- if ( delta <= 0 )
- {
- if ( TIME < irq_time_ )
- goto loop;
- goto delayed_cli;
- }
- s.base = irq_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
-
- if ( delta >= s_time + 1 )
- {
- s.base += s_time + 1;
- s_time = -1;
- goto loop;
- }
-
- // TODO: implement
- delayed_cli:
- debug_printf( "Delayed CLI not emulated\n" );
- goto loop;
- }
-
- case 0x78: // SEI
- if ( status & st_i )
- goto loop;
- status |= st_i;
- handle_sei: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
-
- debug_printf( "Delayed SEI not emulated\n" );
- goto loop;
- }
-
-// Unofficial
-
- // SKW - Skip word
- case 0x1C: case 0x3C: case 0x5C: case 0x7C: case 0xDC: case 0xFC:
- HANDLE_PAGE_CROSSING( data + x );
- case 0x0C:
- pc++;
- // SKB - Skip byte
- case 0x74: case 0x04: case 0x14: case 0x34: case 0x44: case 0x54: case 0x64:
- case 0x80: case 0x82: case 0x89: case 0xC2: case 0xD4: case 0xE2: case 0xF4:
- pc++;
- goto loop;
-
- // NOP
- case 0xEA: case 0x1A: case 0x3A: case 0x5A: case 0x7A: case 0xDA: case 0xFA:
- goto loop;
-
- case bad_opcode: // HLT
- pc--;
- if ( pc > 0xFFFF )
- {
- // handle wrap-around (assumes caller has put page of HLT at 0x10000)
- pc &= 0xFFFF;
- goto loop;
- }
- case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52:
- case 0x62: case 0x72: case 0x92: case 0xB2: case 0xD2:
- goto stop;
-
-// Unimplemented
-
- case 0xFF: // force 256-entry jump table for optimization purposes
- c |= 1;
- default:
- check( (unsigned) opcode <= 0xFF );
- // skip over proper number of bytes
- static unsigned char const illop_lens [8] = {
- 0x40, 0x40, 0x40, 0x80, 0x40, 0x40, 0x80, 0xA0
- };
- fuint8 opcode = instr [-1];
- fint16 len = illop_lens [opcode >> 2 & 7] >> (opcode << 1 & 6) & 3;
- if ( opcode == 0x9C )
- len = 2;
- pc += len;
- error_count_++;
-
- if ( (opcode >> 4) == 0x0B )
- {
- if ( opcode == 0xB3 )
- data = READ_LOW( data );
- if ( opcode != 0xB7 )
- HANDLE_PAGE_CROSSING( data + y );
- }
- goto loop;
- }
- assert( false );
-
- int result_;
-handle_brk:
- pc++;
- result_ = 4;
-
-interrupt:
- {
- s_time += 7;
-
- WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
- WRITE_LOW( 0x100 | (sp - 2), pc );
- pc = GET_LE16( &READ_PROG( 0xFFFA ) + result_ );
-
- sp = (sp - 3) | 0x100;
- fuint8 temp;
- CALC_STATUS( temp );
- temp |= st_r;
- if ( result_ )
- temp |= st_b; // TODO: incorrectly sets B flag for IRQ
- WRITE_LOW( sp, temp );
-
- this->r.status = status |= st_i;
- blargg_long delta = s.base - end_time_;
- if ( delta >= 0 ) goto loop;
- s_time += delta;
- s.base = end_time_;
- goto loop;
- }
-
-out_of_time:
- pc--;
- FLUSH_TIME();
- CPU_DONE( this, TIME, result_ );
- CACHE_TIME();
- if ( result_ >= 0 )
- goto interrupt;
- if ( s_time < 0 )
- goto loop;
-
-stop:
-
- s.time = s_time;
-
- r.pc = pc;
- r.sp = GET_SP();
- r.a = a;
- r.x = x;
- r.y = y;
-
- {
- fuint8 temp;
- CALC_STATUS( temp );
- r.status = temp;
- }
-
- this->state_ = s;
- this->state = &this->state_;
-
- return s_time < 0;
-}
-
diff --git a/src/console/Nes_Fme7_Apu.cc b/src/console/Nes_Fme7_Apu.cc
new file mode 100644
index 000000000000..84030f865da4
--- /dev/null
+++ b/src/console/Nes_Fme7_Apu.cc
@@ -0,0 +1,121 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Nes_Fme7_Apu.h"
+
+#include <string.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+void Nes_Fme7_Apu::reset()
+{
+ last_time = 0;
+
+ for ( int i = 0; i < osc_count; i++ )
+ oscs [i].last_amp = 0;
+
+ fme7_apu_state_t* state = this;
+ memset( state, 0, sizeof *state );
+}
+
+unsigned char const Nes_Fme7_Apu::amp_table [16] =
+{
+ #define ENTRY( n ) (unsigned char) (n * amp_range + 0.5)
+ ENTRY(0.0000), ENTRY(0.0078), ENTRY(0.0110), ENTRY(0.0156),
+ ENTRY(0.0221), ENTRY(0.0312), ENTRY(0.0441), ENTRY(0.0624),
+ ENTRY(0.0883), ENTRY(0.1249), ENTRY(0.1766), ENTRY(0.2498),
+ ENTRY(0.3534), ENTRY(0.4998), ENTRY(0.7070), ENTRY(1.0000)
+ #undef ENTRY
+};
+
+void Nes_Fme7_Apu::run_until( blip_time_t end_time )
+{
+ require( end_time >= last_time );
+
+ for ( int index = 0; index < osc_count; index++ )
+ {
+ int mode = regs [7] >> index;
+ int vol_mode = regs [010 + index];
+ int volume = amp_table [vol_mode & 0x0F];
+
+ Blip_Buffer* const osc_output = oscs [index].output;
+ if ( !osc_output )
+ continue;
+ osc_output->set_modified();
+
+ // check for unsupported mode
+ #ifndef NDEBUG
+ if ( (mode & 011) <= 001 && vol_mode & 0x1F )
+ debug_printf( "FME7 used unimplemented sound mode: %02X, vol_mode: %02X\n",
+ mode, vol_mode & 0x1F );
+ #endif
+
+ if ( (mode & 001) | (vol_mode & 0x10) )
+ volume = 0; // noise and envelope aren't supported
+
+ // period
+ int const period_factor = 16;
+ unsigned period = (regs [index * 2 + 1] & 0x0F) * 0x100 * period_factor +
+ regs [index * 2] * period_factor;
+ if ( period < 50 ) // around 22 kHz
+ {
+ volume = 0;
+ if ( !period ) // on my AY-3-8910A, period doesn't have extra one added
+ period = period_factor;
+ }
+
+ // current amplitude
+ int amp = volume;
+ if ( !phases [index] )
+ amp = 0;
+ {
+ int delta = amp - oscs [index].last_amp;
+ if ( delta )
+ {
+ oscs [index].last_amp = amp;
+ synth.offset( last_time, delta, osc_output );
+ }
+ }
+
+ blip_time_t time = last_time + delays [index];
+ if ( time < end_time )
+ {
+ int delta = amp * 2 - volume;
+ if ( volume )
+ {
+ do
+ {
+ delta = -delta;
+ synth.offset_inline( time, delta, osc_output );
+ time += period;
+ }
+ while ( time < end_time );
+
+ oscs [index].last_amp = (delta + volume) >> 1;
+ phases [index] = (delta > 0);
+ }
+ else
+ {
+ // maintain phase when silent
+ int count = (end_time - time + period - 1) / period;
+ phases [index] ^= count & 1;
+ time += (blargg_long) count * period;
+ }
+ }
+
+ delays [index] = time - end_time;
+ }
+
+ last_time = end_time;
+}
+
diff --git a/src/console/Nes_Fme7_Apu.cxx b/src/console/Nes_Fme7_Apu.cxx
deleted file mode 100644
index 84030f865da4..000000000000
--- a/src/console/Nes_Fme7_Apu.cxx
+++ /dev/null
@@ -1,121 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Nes_Fme7_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-void Nes_Fme7_Apu::reset()
-{
- last_time = 0;
-
- for ( int i = 0; i < osc_count; i++ )
- oscs [i].last_amp = 0;
-
- fme7_apu_state_t* state = this;
- memset( state, 0, sizeof *state );
-}
-
-unsigned char const Nes_Fme7_Apu::amp_table [16] =
-{
- #define ENTRY( n ) (unsigned char) (n * amp_range + 0.5)
- ENTRY(0.0000), ENTRY(0.0078), ENTRY(0.0110), ENTRY(0.0156),
- ENTRY(0.0221), ENTRY(0.0312), ENTRY(0.0441), ENTRY(0.0624),
- ENTRY(0.0883), ENTRY(0.1249), ENTRY(0.1766), ENTRY(0.2498),
- ENTRY(0.3534), ENTRY(0.4998), ENTRY(0.7070), ENTRY(1.0000)
- #undef ENTRY
-};
-
-void Nes_Fme7_Apu::run_until( blip_time_t end_time )
-{
- require( end_time >= last_time );
-
- for ( int index = 0; index < osc_count; index++ )
- {
- int mode = regs [7] >> index;
- int vol_mode = regs [010 + index];
- int volume = amp_table [vol_mode & 0x0F];
-
- Blip_Buffer* const osc_output = oscs [index].output;
- if ( !osc_output )
- continue;
- osc_output->set_modified();
-
- // check for unsupported mode
- #ifndef NDEBUG
- if ( (mode & 011) <= 001 && vol_mode & 0x1F )
- debug_printf( "FME7 used unimplemented sound mode: %02X, vol_mode: %02X\n",
- mode, vol_mode & 0x1F );
- #endif
-
- if ( (mode & 001) | (vol_mode & 0x10) )
- volume = 0; // noise and envelope aren't supported
-
- // period
- int const period_factor = 16;
- unsigned period = (regs [index * 2 + 1] & 0x0F) * 0x100 * period_factor +
- regs [index * 2] * period_factor;
- if ( period < 50 ) // around 22 kHz
- {
- volume = 0;
- if ( !period ) // on my AY-3-8910A, period doesn't have extra one added
- period = period_factor;
- }
-
- // current amplitude
- int amp = volume;
- if ( !phases [index] )
- amp = 0;
- {
- int delta = amp - oscs [index].last_amp;
- if ( delta )
- {
- oscs [index].last_amp = amp;
- synth.offset( last_time, delta, osc_output );
- }
- }
-
- blip_time_t time = last_time + delays [index];
- if ( time < end_time )
- {
- int delta = amp * 2 - volume;
- if ( volume )
- {
- do
- {
- delta = -delta;
- synth.offset_inline( time, delta, osc_output );
- time += period;
- }
- while ( time < end_time );
-
- oscs [index].last_amp = (delta + volume) >> 1;
- phases [index] = (delta > 0);
- }
- else
- {
- // maintain phase when silent
- int count = (end_time - time + period - 1) / period;
- phases [index] ^= count & 1;
- time += (blargg_long) count * period;
- }
- }
-
- delays [index] = time - end_time;
- }
-
- last_time = end_time;
-}
-
diff --git a/src/console/Nes_Fme7_Apu.h b/src/console/Nes_Fme7_Apu.h
index 4b2d6fba8146..4df44acb4f25 100644
--- a/src/console/Nes_Fme7_Apu.h
+++ b/src/console/Nes_Fme7_Apu.h
@@ -85,7 +85,7 @@ inline void Nes_Fme7_Apu::output( Blip_Buffer* buf )
inline Nes_Fme7_Apu::Nes_Fme7_Apu()
{
- output( NULL );
+ output( nullptr );
volume( 1.0 );
reset();
}
diff --git a/src/console/Nes_Namco_Apu.cc b/src/console/Nes_Namco_Apu.cc
new file mode 100644
index 000000000000..e382dfb13054
--- /dev/null
+++ b/src/console/Nes_Namco_Apu.cc
@@ -0,0 +1,145 @@
+// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
+
+#include "Nes_Namco_Apu.h"
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+Nes_Namco_Apu::Nes_Namco_Apu()
+{
+ output( nullptr );
+ volume( 1.0 );
+ reset();
+}
+
+void Nes_Namco_Apu::reset()
+{
+ last_time = 0;
+ addr_reg = 0;
+
+ int i;
+ for ( i = 0; i < reg_count; i++ )
+ reg [i] = 0;
+
+ for ( i = 0; i < osc_count; i++ )
+ {
+ Namco_Osc& osc = oscs [i];
+ osc.delay = 0;
+ osc.last_amp = 0;
+ osc.wave_pos = 0;
+ }
+}
+
+void Nes_Namco_Apu::output( Blip_Buffer* buf )
+{
+ for ( int i = 0; i < osc_count; i++ )
+ osc_output( i, buf );
+}
+
+/*
+void Nes_Namco_Apu::reflect_state( Tagged_Data& data )
+{
+ reflect_int16( data, BLARGG_4CHAR('A','D','D','R'), &addr_reg );
+
+ static const char hex [17] = "0123456789ABCDEF";
+ int i;
+ for ( i = 0; i < reg_count; i++ )
+ reflect_int16( data, 'RG\0\0' + hex [i >> 4] * 0x100 + hex [i & 15], ® [i] );
+
+ for ( i = 0; i < osc_count; i++ )
+ {
+ reflect_int32( data, BLARGG_4CHAR('D','L','Y','0') + i, &oscs [i].delay );
+ reflect_int16( data, BLARGG_4CHAR('P','O','S','0') + i, &oscs [i].wave_pos );
+ }
+}
+*/
+
+void Nes_Namco_Apu::end_frame( blip_time_t time )
+{
+ if ( time > last_time )
+ run_until( time );
+
+ assert( last_time >= time );
+ last_time -= time;
+}
+
+void Nes_Namco_Apu::run_until( blip_time_t nes_end_time )
+{
+ int active_oscs = (reg [0x7F] >> 4 & 7) + 1;
+ for ( int i = osc_count - active_oscs; i < osc_count; i++ )
+ {
+ Namco_Osc& osc = oscs [i];
+ Blip_Buffer* output = osc.output;
+ if ( !output )
+ continue;
+ output->set_modified();
+
+ blip_resampled_time_t time =
+ output->resampled_time( last_time ) + osc.delay;
+ blip_resampled_time_t end_time = output->resampled_time( nes_end_time );
+ osc.delay = 0;
+ if ( time < end_time )
+ {
+ const uint8_t* osc_reg = ® [i * 8 + 0x40];
+ if ( !(osc_reg [4] & 0xE0) )
+ continue;
+
+ int volume = osc_reg [7] & 15;
+ if ( !volume )
+ continue;
+
+ blargg_long freq = (osc_reg [4] & 3) * 0x10000 + osc_reg [2] * 0x100L + osc_reg [0];
+ if ( freq < 64 * active_oscs )
+ continue; // prevent low frequencies from excessively delaying freq changes
+ blip_resampled_time_t period =
+ output->resampled_duration( 983040 ) / freq * active_oscs;
+
+ int wave_size = 32 - (osc_reg [4] >> 2 & 7) * 4;
+ if ( !wave_size )
+ continue;
+
+ int last_amp = osc.last_amp;
+ int wave_pos = osc.wave_pos;
+
+ do
+ {
+ // read wave sample
+ int addr = wave_pos + osc_reg [6];
+ int sample = reg [addr >> 1] >> (addr << 2 & 4);
+ wave_pos++;
+ sample = (sample & 15) * volume;
+
+ // output impulse if amplitude changed
+ int delta = sample - last_amp;
+ if ( delta )
+ {
+ last_amp = sample;
+ synth.offset_resampled( time, delta, output );
+ }
+
+ // next sample
+ time += period;
+ if ( wave_pos >= wave_size )
+ wave_pos = 0;
+ }
+ while ( time < end_time );
+
+ osc.wave_pos = wave_pos;
+ osc.last_amp = last_amp;
+ }
+ osc.delay = time - end_time;
+ }
+
+ last_time = nes_end_time;
+}
+
diff --git a/src/console/Nes_Namco_Apu.cxx b/src/console/Nes_Namco_Apu.cxx
deleted file mode 100644
index 76bdb70d31db..000000000000
--- a/src/console/Nes_Namco_Apu.cxx
+++ /dev/null
@@ -1,145 +0,0 @@
-// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
-
-#include "Nes_Namco_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Nes_Namco_Apu::Nes_Namco_Apu()
-{
- output( NULL );
- volume( 1.0 );
- reset();
-}
-
-void Nes_Namco_Apu::reset()
-{
- last_time = 0;
- addr_reg = 0;
-
- int i;
- for ( i = 0; i < reg_count; i++ )
- reg [i] = 0;
-
- for ( i = 0; i < osc_count; i++ )
- {
- Namco_Osc& osc = oscs [i];
- osc.delay = 0;
- osc.last_amp = 0;
- osc.wave_pos = 0;
- }
-}
-
-void Nes_Namco_Apu::output( Blip_Buffer* buf )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, buf );
-}
-
-/*
-void Nes_Namco_Apu::reflect_state( Tagged_Data& data )
-{
- reflect_int16( data, BLARGG_4CHAR('A','D','D','R'), &addr_reg );
-
- static const char hex [17] = "0123456789ABCDEF";
- int i;
- for ( i = 0; i < reg_count; i++ )
- reflect_int16( data, 'RG\0\0' + hex [i >> 4] * 0x100 + hex [i & 15], ® [i] );
-
- for ( i = 0; i < osc_count; i++ )
- {
- reflect_int32( data, BLARGG_4CHAR('D','L','Y','0') + i, &oscs [i].delay );
- reflect_int16( data, BLARGG_4CHAR('P','O','S','0') + i, &oscs [i].wave_pos );
- }
-}
-*/
-
-void Nes_Namco_Apu::end_frame( blip_time_t time )
-{
- if ( time > last_time )
- run_until( time );
-
- assert( last_time >= time );
- last_time -= time;
-}
-
-void Nes_Namco_Apu::run_until( blip_time_t nes_end_time )
-{
- int active_oscs = (reg [0x7F] >> 4 & 7) + 1;
- for ( int i = osc_count - active_oscs; i < osc_count; i++ )
- {
- Namco_Osc& osc = oscs [i];
- Blip_Buffer* output = osc.output;
- if ( !output )
- continue;
- output->set_modified();
-
- blip_resampled_time_t time =
- output->resampled_time( last_time ) + osc.delay;
- blip_resampled_time_t end_time = output->resampled_time( nes_end_time );
- osc.delay = 0;
- if ( time < end_time )
- {
- const uint8_t* osc_reg = ® [i * 8 + 0x40];
- if ( !(osc_reg [4] & 0xE0) )
- continue;
-
- int volume = osc_reg [7] & 15;
- if ( !volume )
- continue;
-
- blargg_long freq = (osc_reg [4] & 3) * 0x10000 + osc_reg [2] * 0x100L + osc_reg [0];
- if ( freq < 64 * active_oscs )
- continue; // prevent low frequencies from excessively delaying freq changes
- blip_resampled_time_t period =
- output->resampled_duration( 983040 ) / freq * active_oscs;
-
- int wave_size = 32 - (osc_reg [4] >> 2 & 7) * 4;
- if ( !wave_size )
- continue;
-
- int last_amp = osc.last_amp;
- int wave_pos = osc.wave_pos;
-
- do
- {
- // read wave sample
- int addr = wave_pos + osc_reg [6];
- int sample = reg [addr >> 1] >> (addr << 2 & 4);
- wave_pos++;
- sample = (sample & 15) * volume;
-
- // output impulse if amplitude changed
- int delta = sample - last_amp;
- if ( delta )
- {
- last_amp = sample;
- synth.offset_resampled( time, delta, output );
- }
-
- // next sample
- time += period;
- if ( wave_pos >= wave_size )
- wave_pos = 0;
- }
- while ( time < end_time );
-
- osc.wave_pos = wave_pos;
- osc.last_amp = last_amp;
- }
- osc.delay = time - end_time;
- }
-
- last_time = nes_end_time;
-}
-
diff --git a/src/console/Nes_Oscs.cc b/src/console/Nes_Oscs.cc
new file mode 100644
index 000000000000..5ab7d084a2bd
--- /dev/null
+++ b/src/console/Nes_Oscs.cc
@@ -0,0 +1,551 @@
+// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
+
+#include "Nes_Apu.h"
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+// Nes_Osc
+
+void Nes_Osc::clock_length( int halt_mask )
+{
+ if ( length_counter && !(regs [0] & halt_mask) )
+ length_counter--;
+}
+
+void Nes_Envelope::clock_envelope()
+{
+ int period = regs [0] & 15;
+ if ( reg_written [3] ) {
+ reg_written [3] = false;
+ env_delay = period;
+ envelope = 15;
+ }
+ else if ( --env_delay < 0 ) {
+ env_delay = period;
+ if ( envelope | (regs [0] & 0x20) )
+ envelope = (envelope - 1) & 15;
+ }
+}
+
+int Nes_Envelope::volume() const
+{
+ return length_counter == 0 ? 0 : (regs [0] & 0x10) ? (regs [0] & 15) : envelope;
+}
+
+// Nes_Square
+
+void Nes_Square::clock_sweep( int negative_adjust )
+{
+ int sweep = regs [1];
+
+ if ( --sweep_delay < 0 )
+ {
+ reg_written [1] = true;
+
+ int period = this->period();
+ int shift = sweep & shift_mask;
+ if ( shift && (sweep & 0x80) && period >= 8 )
+ {
+ int offset = period >> shift;
+
+ if ( sweep & negate_flag )
+ offset = negative_adjust - offset;
+
+ if ( period + offset < 0x800 )
+ {
+ period += offset;
+ // rewrite period
+ regs [2] = period & 0xFF;
+ regs [3] = (regs [3] & ~7) | ((period >> 8) & 7);
+ }
+ }
+ }
+
+ if ( reg_written [1] ) {
+ reg_written [1] = false;
+ sweep_delay = (sweep >> 4) & 7;
+ }
+}
+
+// TODO: clean up
+inline nes_time_t Nes_Square::maintain_phase( nes_time_t time, nes_time_t end_time,
+ nes_time_t timer_period )
+{
+ nes_time_t remain = end_time - time;
+ if ( remain > 0 )
+ {
+ int count = (remain + timer_period - 1) / timer_period;
+ phase = (phase + count) & (phase_range - 1);
+ time += (blargg_long) count * timer_period;
+ }
+ return time;
+}
+
+void Nes_Square::run( nes_time_t time, nes_time_t end_time )
+{
+ const int period = this->period();
+ const int timer_period = (period + 1) * 2;
+
+ if ( !output )
+ {
+ delay = maintain_phase( time + delay, end_time, timer_period ) - end_time;
+ return;
+ }
+
+ output->set_modified();
+
+ int offset = period >> (regs [1] & shift_mask);
+ if ( regs [1] & negate_flag )
+ offset = 0;
+
+ const int volume = this->volume();
+ if ( volume == 0 || period < 8 || (period + offset) >= 0x800 )
+ {
+ if ( last_amp ) {
+ synth.offset( time, -last_amp, output );
+ last_amp = 0;
+ }
+
+ time += delay;
+ time = maintain_phase( time, end_time, timer_period );
+ }
+ else
+ {
+ // handle duty select
+ int duty_select = (regs [0] >> 6) & 3;
+ int duty = 1 << duty_select; // 1, 2, 4, 2
+ int amp = 0;
+ if ( duty_select == 3 ) {
+ duty = 2; // negated 25%
+ amp = volume;
+ }
+ if ( phase < duty )
+ amp ^= volume;
+
+ {
+ int delta = update_amp( amp );
+ if ( delta )
+ synth.offset( time, delta, output );
+ }
+
+ time += delay;
+ if ( time < end_time )
+ {
+ Blip_Buffer* const output = this->output;
+ const Synth& synth = this->synth;
+ int delta = amp * 2 - volume;
+ int phase = this->phase;
+
+ do {
+ phase = (phase + 1) & (phase_range - 1);
+ if ( phase == 0 || phase == duty ) {
+ delta = -delta;
+ synth.offset_inline( time, delta, output );
+ }
+ time += timer_period;
+ }
+ while ( time < end_time );
+
+ last_amp = (delta + volume) >> 1;
+ this->phase = phase;
+ }
+ }
+
+ delay = time - end_time;
+}
+
+// Nes_Triangle
+
+void Nes_Triangle::clock_linear_counter()
+{
+ if ( reg_written [3] )
+ linear_counter = regs [0] & 0x7F;
+ else if ( linear_counter )
+ linear_counter--;
+
+ if ( !(regs [0] & 0x80) )
+ reg_written [3] = false;
+}
+
+inline int Nes_Triangle::calc_amp() const
+{
+ int amp = phase_range - phase;
+ if ( amp < 0 )
+ amp = phase - (phase_range + 1);
+ return amp;
+}
+
+// TODO: clean up
+inline nes_time_t Nes_Triangle::maintain_phase( nes_time_t time, nes_time_t end_time,
+ nes_time_t timer_period )
+{
+ nes_time_t remain = end_time - time;
+ if ( remain > 0 )
+ {
+ int count = (remain + timer_period - 1) / timer_period;
+ phase = ((unsigned) phase + 1 - count) & (phase_range * 2 - 1);
+ phase++;
+ time += (blargg_long) count * timer_period;
+ }
+ return time;
+}
+
+void Nes_Triangle::run( nes_time_t time, nes_time_t end_time )
+{
+ const int timer_period = period() + 1;
+ if ( !output )
+ {
+ time += delay;
+ delay = 0;
+ if ( length_counter && linear_counter && timer_period >= 3 )
+ delay = maintain_phase( time, end_time, timer_period ) - end_time;
+ return;
+ }
+
+ output->set_modified();
+
+ // to do: track phase when period < 3
+ // to do: Output 7.5 on dac when period < 2? More accurate, but results in more clicks.
+
+ int delta = update_amp( calc_amp() );
+ if ( delta )
+ synth.offset( time, delta, output );
+
+ time += delay;
+ if ( length_counter == 0 || linear_counter == 0 || timer_period < 3 )
+ {
+ time = end_time;
+ }
+ else if ( time < end_time )
+ {
+ Blip_Buffer* const output = this->output;
+
+ int phase = this->phase;
+ int volume = 1;
+ if ( phase > phase_range ) {
+ phase -= phase_range;
+ volume = -volume;
+ }
+
+ do {
+ if ( --phase == 0 ) {
+ phase = phase_range;
+ volume = -volume;
+ }
+ else {
+ synth.offset_inline( time, volume, output );
+ }
+
+ time += timer_period;
+ }
+ while ( time < end_time );
+
+ if ( volume < 0 )
+ phase += phase_range;
+ this->phase = phase;
+ last_amp = calc_amp();
+ }
+ delay = time - end_time;
+}
+
+// Nes_Dmc
+
+void Nes_Dmc::reset()
+{
+ address = 0;
+ dac = 0;
+ buf = 0;
+ bits_remain = 1;
+ bits = 0;
+ buf_full = false;
+ silence = true;
+ next_irq = Nes_Apu::no_irq;
+ irq_flag = false;
+ irq_enabled = false;
+
+ Nes_Osc::reset();
+ period = 0x1AC;
+}
+
+void Nes_Dmc::recalc_irq()
+{
+ nes_time_t irq = Nes_Apu::no_irq;
+ if ( irq_enabled && length_counter )
+ irq = apu->last_dmc_time + delay +
+ ((length_counter - 1) * 8 + bits_remain - 1) * nes_time_t (period) + 1;
+ if ( irq != next_irq ) {
+ next_irq = irq;
+ apu->irq_changed();
+ }
+}
+
+int Nes_Dmc::count_reads( nes_time_t time, nes_time_t* last_read ) const
+{
+ if ( last_read )
+ *last_read = time;
+
+ if ( length_counter == 0 )
+ return 0; // not reading
+
+ nes_time_t first_read = next_read_time();
+ nes_time_t avail = time - first_read;
+ if ( avail <= 0 )
+ return 0;
+
+ int count = (avail - 1) / (period * 8) + 1;
+ if ( !(regs [0] & loop_flag) && count > length_counter )
+ count = length_counter;
+
+ if ( last_read )
+ {
+ *last_read = first_read + (count - 1) * (period * 8) + 1;
+ check( *last_read <= time );
+ check( count == count_reads( *last_read, nullptr ) );
+ check( count - 1 == count_reads( *last_read - 1, nullptr ) );
+ }
+
+ return count;
+}
+
+static short const dmc_period_table [2] [16] = {
+ {428, 380, 340, 320, 286, 254, 226, 214, // NTSC
+ 190, 160, 142, 128, 106, 84, 72, 54},
+
+ {398, 354, 316, 298, 276, 236, 210, 198, // PAL
+ 176, 148, 132, 118, 98, 78, 66, 50}
+};
+
+inline void Nes_Dmc::reload_sample()
+{
+ address = 0x4000 + regs [2] * 0x40;
+ length_counter = regs [3] * 0x10 + 1;
+}
+
+static byte const dac_table [128] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9,10,11,12,13,14,
+ 15,15,16,17,18,19,20,20,21,22,23,24,24,25,26,27,
+ 27,28,29,30,31,31,32,33,33,34,35,36,36,37,38,38,
+ 39,40,41,41,42,43,43,44,45,45,46,47,47,48,48,49,
+ 50,50,51,52,52,53,53,54,55,55,56,56,57,58,58,59,
+ 59,60,60,61,61,62,63,63,64,64,65,65,66,66,67,67,
+ 68,68,69,70,70,71,71,72,72,73,73,74,74,75,75,75,
+ 76,76,77,77,78,78,79,79,80,80,81,81,82,82,82,83,
+};
+
+void Nes_Dmc::write_register( int addr, int data )
+{
+ if ( addr == 0 )
+ {
+ period = dmc_period_table [pal_mode] [data & 15];
+ irq_enabled = (data & 0xC0) == 0x80; // enabled only if loop disabled
+ irq_flag &= irq_enabled;
+ recalc_irq();
+ }
+ else if ( addr == 1 )
+ {
+ int old_dac = dac;
+ dac = data & 0x7F;
+
+ // adjust last_amp so that "pop" amplitude will be properly non-linear
+ // with respect to change in dac
+ int faked_nonlinear = dac - (dac_table [dac] - dac_table [old_dac]);
+ if ( !nonlinear )
+ last_amp = faked_nonlinear;
+ }
+}
+
+void Nes_Dmc::start()
+{
+ reload_sample();
+ fill_buffer();
+ recalc_irq();
+}
+
+void Nes_Dmc::fill_buffer()
+{
+ if ( !buf_full && length_counter )
+ {
+ require( prg_reader ); // prg_reader must be set
+ buf = prg_reader( prg_reader_data, 0x8000u + address );
+ address = (address + 1) & 0x7FFF;
+ buf_full = true;
+ if ( --length_counter == 0 )
+ {
+ if ( regs [0] & loop_flag ) {
+ reload_sample();
+ }
+ else {
+ apu->osc_enables &= ~0x10;
+ irq_flag = irq_enabled;
+ next_irq = Nes_Apu::no_irq;
+ apu->irq_changed();
+ }
+ }
+ }
+}
+
+void Nes_Dmc::run( nes_time_t time, nes_time_t end_time )
+{
+ int delta = update_amp( dac );
+ if ( !output )
+ {
+ silence = true;
+ }
+ else
+ {
+ output->set_modified();
+ if ( delta )
+ synth.offset( time, delta, output );
+ }
+
+ time += delay;
+ if ( time < end_time )
+ {
+ int bits_remain = this->bits_remain;
+ if ( silence && !buf_full )
+ {
+ int count = (end_time - time + period - 1) / period;
+ bits_remain = (bits_remain - 1 + 8 - (count % 8)) % 8 + 1;
+ time += count * period;
+ }
+ else
+ {
+ Blip_Buffer* const output = this->output;
+ const int period = this->period;
+ int bits = this->bits;
+ int dac = this->dac;
+
+ do
+ {
+ if ( !silence )
+ {
+ int step = (bits & 1) * 4 - 2;
+ bits >>= 1;
+ if ( unsigned (dac + step) <= 0x7F ) {
+ dac += step;
+ synth.offset_inline( time, step, output );
+ }
+ }
+
+ time += period;
+
+ if ( --bits_remain == 0 )
+ {
+ bits_remain = 8;
+ if ( !buf_full ) {
+ silence = true;
+ }
+ else {
+ silence = false;
+ bits = buf;
+ buf_full = false;
+ if ( !output )
+ silence = true;
+ fill_buffer();
+ }
+ }
+ }
+ while ( time < end_time );
+
+ this->dac = dac;
+ this->last_amp = dac;
+ this->bits = bits;
+ }
+ this->bits_remain = bits_remain;
+ }
+ delay = time - end_time;
+}
+
+// Nes_Noise
+
+static short const noise_period_table [16] = {
+ 0x004, 0x008, 0x010, 0x020, 0x040, 0x060, 0x080, 0x0A0,
+ 0x0CA, 0x0FE, 0x17C, 0x1FC, 0x2FA, 0x3F8, 0x7F2, 0xFE4
+};
+
+void Nes_Noise::run( nes_time_t time, nes_time_t end_time )
+{
+ int period = noise_period_table [regs [2] & 15];
+
+ if ( !output )
+ {
+ // TODO: clean up
+ time += delay;
+ delay = time + (end_time - time + period - 1) / period * period - end_time;
+ return;
+ }
+
+ output->set_modified();
+
+ const int volume = this->volume();
+ int amp = (noise & 1) ? volume : 0;
+ {
+ int delta = update_amp( amp );
+ if ( delta )
+ synth.offset( time, delta, output );
+ }
+
+ time += delay;
+ if ( time < end_time )
+ {
+ const int mode_flag = 0x80;
+
+ if ( !volume )
+ {
+ // round to next multiple of period
+ time += (end_time - time + period - 1) / period * period;
+
+ // approximate noise cycling while muted, by shuffling up noise register
+ // to do: precise muted noise cycling?
+ if ( !(regs [2] & mode_flag) ) {
+ int feedback = (noise << 13) ^ (noise << 14);
+ noise = (feedback & 0x4000) | (noise >> 1);
+ }
+ }
+ else
+ {
+ Blip_Buffer* const output = this->output;
+
+ // using resampled time avoids conversion in synth.offset()
+ blip_resampled_time_t rperiod = output->resampled_duration( period );
+ blip_resampled_time_t rtime = output->resampled_time( time );
+
+ int noise = this->noise;
+ int delta = amp * 2 - volume;
+ const int tap = (regs [2] & mode_flag ? 8 : 13);
+
+ do {
+ int feedback = (noise << tap) ^ (noise << 14);
+ time += period;
+
+ if ( (noise + 1) & 2 ) {
+ // bits 0 and 1 of noise differ
+ delta = -delta;
+ synth.offset_resampled( rtime, delta, output );
+ }
+
+ rtime += rperiod;
+ noise = (feedback & 0x4000) | (noise >> 1);
+ }
+ while ( time < end_time );
+
+ last_amp = (delta + volume) >> 1;
+ this->noise = noise;
+ }
+ }
+
+ delay = time - end_time;
+}
+
diff --git a/src/console/Nes_Oscs.cxx b/src/console/Nes_Oscs.cxx
deleted file mode 100644
index f09a0e183cdc..000000000000
--- a/src/console/Nes_Oscs.cxx
+++ /dev/null
@@ -1,551 +0,0 @@
-// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
-
-#include "Nes_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Nes_Osc
-
-void Nes_Osc::clock_length( int halt_mask )
-{
- if ( length_counter && !(regs [0] & halt_mask) )
- length_counter--;
-}
-
-void Nes_Envelope::clock_envelope()
-{
- int period = regs [0] & 15;
- if ( reg_written [3] ) {
- reg_written [3] = false;
- env_delay = period;
- envelope = 15;
- }
- else if ( --env_delay < 0 ) {
- env_delay = period;
- if ( envelope | (regs [0] & 0x20) )
- envelope = (envelope - 1) & 15;
- }
-}
-
-int Nes_Envelope::volume() const
-{
- return length_counter == 0 ? 0 : (regs [0] & 0x10) ? (regs [0] & 15) : envelope;
-}
-
-// Nes_Square
-
-void Nes_Square::clock_sweep( int negative_adjust )
-{
- int sweep = regs [1];
-
- if ( --sweep_delay < 0 )
- {
- reg_written [1] = true;
-
- int period = this->period();
- int shift = sweep & shift_mask;
- if ( shift && (sweep & 0x80) && period >= 8 )
- {
- int offset = period >> shift;
-
- if ( sweep & negate_flag )
- offset = negative_adjust - offset;
-
- if ( period + offset < 0x800 )
- {
- period += offset;
- // rewrite period
- regs [2] = period & 0xFF;
- regs [3] = (regs [3] & ~7) | ((period >> 8) & 7);
- }
- }
- }
-
- if ( reg_written [1] ) {
- reg_written [1] = false;
- sweep_delay = (sweep >> 4) & 7;
- }
-}
-
-// TODO: clean up
-inline nes_time_t Nes_Square::maintain_phase( nes_time_t time, nes_time_t end_time,
- nes_time_t timer_period )
-{
- nes_time_t remain = end_time - time;
- if ( remain > 0 )
- {
- int count = (remain + timer_period - 1) / timer_period;
- phase = (phase + count) & (phase_range - 1);
- time += (blargg_long) count * timer_period;
- }
- return time;
-}
-
-void Nes_Square::run( nes_time_t time, nes_time_t end_time )
-{
- const int period = this->period();
- const int timer_period = (period + 1) * 2;
-
- if ( !output )
- {
- delay = maintain_phase( time + delay, end_time, timer_period ) - end_time;
- return;
- }
-
- output->set_modified();
-
- int offset = period >> (regs [1] & shift_mask);
- if ( regs [1] & negate_flag )
- offset = 0;
-
- const int volume = this->volume();
- if ( volume == 0 || period < 8 || (period + offset) >= 0x800 )
- {
- if ( last_amp ) {
- synth.offset( time, -last_amp, output );
- last_amp = 0;
- }
-
- time += delay;
- time = maintain_phase( time, end_time, timer_period );
- }
- else
- {
- // handle duty select
- int duty_select = (regs [0] >> 6) & 3;
- int duty = 1 << duty_select; // 1, 2, 4, 2
- int amp = 0;
- if ( duty_select == 3 ) {
- duty = 2; // negated 25%
- amp = volume;
- }
- if ( phase < duty )
- amp ^= volume;
-
- {
- int delta = update_amp( amp );
- if ( delta )
- synth.offset( time, delta, output );
- }
-
- time += delay;
- if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
- const Synth& synth = this->synth;
- int delta = amp * 2 - volume;
- int phase = this->phase;
-
- do {
- phase = (phase + 1) & (phase_range - 1);
- if ( phase == 0 || phase == duty ) {
- delta = -delta;
- synth.offset_inline( time, delta, output );
- }
- time += timer_period;
- }
- while ( time < end_time );
-
- last_amp = (delta + volume) >> 1;
- this->phase = phase;
- }
- }
-
- delay = time - end_time;
-}
-
-// Nes_Triangle
-
-void Nes_Triangle::clock_linear_counter()
-{
- if ( reg_written [3] )
- linear_counter = regs [0] & 0x7F;
- else if ( linear_counter )
- linear_counter--;
-
- if ( !(regs [0] & 0x80) )
- reg_written [3] = false;
-}
-
-inline int Nes_Triangle::calc_amp() const
-{
- int amp = phase_range - phase;
- if ( amp < 0 )
- amp = phase - (phase_range + 1);
- return amp;
-}
-
-// TODO: clean up
-inline nes_time_t Nes_Triangle::maintain_phase( nes_time_t time, nes_time_t end_time,
- nes_time_t timer_period )
-{
- nes_time_t remain = end_time - time;
- if ( remain > 0 )
- {
- int count = (remain + timer_period - 1) / timer_period;
- phase = ((unsigned) phase + 1 - count) & (phase_range * 2 - 1);
- phase++;
- time += (blargg_long) count * timer_period;
- }
- return time;
-}
-
-void Nes_Triangle::run( nes_time_t time, nes_time_t end_time )
-{
- const int timer_period = period() + 1;
- if ( !output )
- {
- time += delay;
- delay = 0;
- if ( length_counter && linear_counter && timer_period >= 3 )
- delay = maintain_phase( time, end_time, timer_period ) - end_time;
- return;
- }
-
- output->set_modified();
-
- // to do: track phase when period < 3
- // to do: Output 7.5 on dac when period < 2? More accurate, but results in more clicks.
-
- int delta = update_amp( calc_amp() );
- if ( delta )
- synth.offset( time, delta, output );
-
- time += delay;
- if ( length_counter == 0 || linear_counter == 0 || timer_period < 3 )
- {
- time = end_time;
- }
- else if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
-
- int phase = this->phase;
- int volume = 1;
- if ( phase > phase_range ) {
- phase -= phase_range;
- volume = -volume;
- }
-
- do {
- if ( --phase == 0 ) {
- phase = phase_range;
- volume = -volume;
- }
- else {
- synth.offset_inline( time, volume, output );
- }
-
- time += timer_period;
- }
- while ( time < end_time );
-
- if ( volume < 0 )
- phase += phase_range;
- this->phase = phase;
- last_amp = calc_amp();
- }
- delay = time - end_time;
-}
-
-// Nes_Dmc
-
-void Nes_Dmc::reset()
-{
- address = 0;
- dac = 0;
- buf = 0;
- bits_remain = 1;
- bits = 0;
- buf_full = false;
- silence = true;
- next_irq = Nes_Apu::no_irq;
- irq_flag = false;
- irq_enabled = false;
-
- Nes_Osc::reset();
- period = 0x1AC;
-}
-
-void Nes_Dmc::recalc_irq()
-{
- nes_time_t irq = Nes_Apu::no_irq;
- if ( irq_enabled && length_counter )
- irq = apu->last_dmc_time + delay +
- ((length_counter - 1) * 8 + bits_remain - 1) * nes_time_t (period) + 1;
- if ( irq != next_irq ) {
- next_irq = irq;
- apu->irq_changed();
- }
-}
-
-int Nes_Dmc::count_reads( nes_time_t time, nes_time_t* last_read ) const
-{
- if ( last_read )
- *last_read = time;
-
- if ( length_counter == 0 )
- return 0; // not reading
-
- nes_time_t first_read = next_read_time();
- nes_time_t avail = time - first_read;
- if ( avail <= 0 )
- return 0;
-
- int count = (avail - 1) / (period * 8) + 1;
- if ( !(regs [0] & loop_flag) && count > length_counter )
- count = length_counter;
-
- if ( last_read )
- {
- *last_read = first_read + (count - 1) * (period * 8) + 1;
- check( *last_read <= time );
- check( count == count_reads( *last_read, NULL ) );
- check( count - 1 == count_reads( *last_read - 1, NULL ) );
- }
-
- return count;
-}
-
-static short const dmc_period_table [2] [16] = {
- {428, 380, 340, 320, 286, 254, 226, 214, // NTSC
- 190, 160, 142, 128, 106, 84, 72, 54},
-
- {398, 354, 316, 298, 276, 236, 210, 198, // PAL
- 176, 148, 132, 118, 98, 78, 66, 50}
-};
-
-inline void Nes_Dmc::reload_sample()
-{
- address = 0x4000 + regs [2] * 0x40;
- length_counter = regs [3] * 0x10 + 1;
-}
-
-static byte const dac_table [128] =
-{
- 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9,10,11,12,13,14,
- 15,15,16,17,18,19,20,20,21,22,23,24,24,25,26,27,
- 27,28,29,30,31,31,32,33,33,34,35,36,36,37,38,38,
- 39,40,41,41,42,43,43,44,45,45,46,47,47,48,48,49,
- 50,50,51,52,52,53,53,54,55,55,56,56,57,58,58,59,
- 59,60,60,61,61,62,63,63,64,64,65,65,66,66,67,67,
- 68,68,69,70,70,71,71,72,72,73,73,74,74,75,75,75,
- 76,76,77,77,78,78,79,79,80,80,81,81,82,82,82,83,
-};
-
-void Nes_Dmc::write_register( int addr, int data )
-{
- if ( addr == 0 )
- {
- period = dmc_period_table [pal_mode] [data & 15];
- irq_enabled = (data & 0xC0) == 0x80; // enabled only if loop disabled
- irq_flag &= irq_enabled;
- recalc_irq();
- }
- else if ( addr == 1 )
- {
- int old_dac = dac;
- dac = data & 0x7F;
-
- // adjust last_amp so that "pop" amplitude will be properly non-linear
- // with respect to change in dac
- int faked_nonlinear = dac - (dac_table [dac] - dac_table [old_dac]);
- if ( !nonlinear )
- last_amp = faked_nonlinear;
- }
-}
-
-void Nes_Dmc::start()
-{
- reload_sample();
- fill_buffer();
- recalc_irq();
-}
-
-void Nes_Dmc::fill_buffer()
-{
- if ( !buf_full && length_counter )
- {
- require( prg_reader ); // prg_reader must be set
- buf = prg_reader( prg_reader_data, 0x8000u + address );
- address = (address + 1) & 0x7FFF;
- buf_full = true;
- if ( --length_counter == 0 )
- {
- if ( regs [0] & loop_flag ) {
- reload_sample();
- }
- else {
- apu->osc_enables &= ~0x10;
- irq_flag = irq_enabled;
- next_irq = Nes_Apu::no_irq;
- apu->irq_changed();
- }
- }
- }
-}
-
-void Nes_Dmc::run( nes_time_t time, nes_time_t end_time )
-{
- int delta = update_amp( dac );
- if ( !output )
- {
- silence = true;
- }
- else
- {
- output->set_modified();
- if ( delta )
- synth.offset( time, delta, output );
- }
-
- time += delay;
- if ( time < end_time )
- {
- int bits_remain = this->bits_remain;
- if ( silence && !buf_full )
- {
- int count = (end_time - time + period - 1) / period;
- bits_remain = (bits_remain - 1 + 8 - (count % 8)) % 8 + 1;
- time += count * period;
- }
- else
- {
- Blip_Buffer* const output = this->output;
- const int period = this->period;
- int bits = this->bits;
- int dac = this->dac;
-
- do
- {
- if ( !silence )
- {
- int step = (bits & 1) * 4 - 2;
- bits >>= 1;
- if ( unsigned (dac + step) <= 0x7F ) {
- dac += step;
- synth.offset_inline( time, step, output );
- }
- }
-
- time += period;
-
- if ( --bits_remain == 0 )
- {
- bits_remain = 8;
- if ( !buf_full ) {
- silence = true;
- }
- else {
- silence = false;
- bits = buf;
- buf_full = false;
- if ( !output )
- silence = true;
- fill_buffer();
- }
- }
- }
- while ( time < end_time );
-
- this->dac = dac;
- this->last_amp = dac;
- this->bits = bits;
- }
- this->bits_remain = bits_remain;
- }
- delay = time - end_time;
-}
-
-// Nes_Noise
-
-static short const noise_period_table [16] = {
- 0x004, 0x008, 0x010, 0x020, 0x040, 0x060, 0x080, 0x0A0,
- 0x0CA, 0x0FE, 0x17C, 0x1FC, 0x2FA, 0x3F8, 0x7F2, 0xFE4
-};
-
-void Nes_Noise::run( nes_time_t time, nes_time_t end_time )
-{
- int period = noise_period_table [regs [2] & 15];
-
- if ( !output )
- {
- // TODO: clean up
- time += delay;
- delay = time + (end_time - time + period - 1) / period * period - end_time;
- return;
- }
-
- output->set_modified();
-
- const int volume = this->volume();
- int amp = (noise & 1) ? volume : 0;
- {
- int delta = update_amp( amp );
- if ( delta )
- synth.offset( time, delta, output );
- }
-
- time += delay;
- if ( time < end_time )
- {
- const int mode_flag = 0x80;
-
- if ( !volume )
- {
- // round to next multiple of period
- time += (end_time - time + period - 1) / period * period;
-
- // approximate noise cycling while muted, by shuffling up noise register
- // to do: precise muted noise cycling?
- if ( !(regs [2] & mode_flag) ) {
- int feedback = (noise << 13) ^ (noise << 14);
- noise = (feedback & 0x4000) | (noise >> 1);
- }
- }
- else
- {
- Blip_Buffer* const output = this->output;
-
- // using resampled time avoids conversion in synth.offset()
- blip_resampled_time_t rperiod = output->resampled_duration( period );
- blip_resampled_time_t rtime = output->resampled_time( time );
-
- int noise = this->noise;
- int delta = amp * 2 - volume;
- const int tap = (regs [2] & mode_flag ? 8 : 13);
-
- do {
- int feedback = (noise << tap) ^ (noise << 14);
- time += period;
-
- if ( (noise + 1) & 2 ) {
- // bits 0 and 1 of noise differ
- delta = -delta;
- synth.offset_resampled( rtime, delta, output );
- }
-
- rtime += rperiod;
- noise = (feedback & 0x4000) | (noise >> 1);
- }
- while ( time < end_time );
-
- last_amp = (delta + volume) >> 1;
- this->noise = noise;
- }
- }
-
- delay = time - end_time;
-}
-
diff --git a/src/console/Nes_Vrc6_Apu.cc b/src/console/Nes_Vrc6_Apu.cc
new file mode 100644
index 000000000000..195f60588e9a
--- /dev/null
+++ b/src/console/Nes_Vrc6_Apu.cc
@@ -0,0 +1,215 @@
+// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
+
+#include "Nes_Vrc6_Apu.h"
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+Nes_Vrc6_Apu::Nes_Vrc6_Apu()
+{
+ output( nullptr );
+ volume( 1.0 );
+ reset();
+}
+
+void Nes_Vrc6_Apu::reset()
+{
+ last_time = 0;
+ for ( int i = 0; i < osc_count; i++ )
+ {
+ Vrc6_Osc& osc = oscs [i];
+ for ( int j = 0; j < reg_count; j++ )
+ osc.regs [j] = 0;
+ osc.delay = 0;
+ osc.last_amp = 0;
+ osc.phase = 1;
+ osc.amp = 0;
+ }
+}
+
+void Nes_Vrc6_Apu::output( Blip_Buffer* buf )
+{
+ for ( int i = 0; i < osc_count; i++ )
+ osc_output( i, buf );
+}
+
+void Nes_Vrc6_Apu::run_until( blip_time_t time )
+{
+ require( time >= last_time );
+ run_square( oscs [0], time );
+ run_square( oscs [1], time );
+ run_saw( time );
+ last_time = time;
+}
+
+void Nes_Vrc6_Apu::write_osc( blip_time_t time, int osc_index, int reg, int data )
+{
+ require( (unsigned) osc_index < osc_count );
+ require( (unsigned) reg < reg_count );
+
+ run_until( time );
+ oscs [osc_index].regs [reg] = data;
+}
+
+void Nes_Vrc6_Apu::end_frame( blip_time_t time )
+{
+ if ( time > last_time )
+ run_until( time );
+
+ assert( last_time >= time );
+ last_time -= time;
+}
+
+void Nes_Vrc6_Apu::save_state( vrc6_apu_state_t* out ) const
+{
+ assert( sizeof (vrc6_apu_state_t) == 20 );
+ out->saw_amp = oscs [2].amp;
+ for ( int i = 0; i < osc_count; i++ )
+ {
+ Vrc6_Osc const& osc = oscs [i];
+ for ( int r = 0; r < reg_count; r++ )
+ out->regs [i] [r] = osc.regs [r];
+
+ out->delays [i] = osc.delay;
+ out->phases [i] = osc.phase;
+ }
+}
+
+void Nes_Vrc6_Apu::load_state( vrc6_apu_state_t const& in )
+{
+ reset();
+ oscs [2].amp = in.saw_amp;
+ for ( int i = 0; i < osc_count; i++ )
+ {
+ Vrc6_Osc& osc = oscs [i];
+ for ( int r = 0; r < reg_count; r++ )
+ osc.regs [r] = in.regs [i] [r];
+
+ osc.delay = in.delays [i];
+ osc.phase = in.phases [i];
+ }
+ if ( !oscs [2].phase )
+ oscs [2].phase = 1;
+}
+
+void Nes_Vrc6_Apu::run_square( Vrc6_Osc& osc, blip_time_t end_time )
+{
+ Blip_Buffer* output = osc.output;
+ if ( !output )
+ return;
+ output->set_modified();
+
+ int volume = osc.regs [0] & 15;
+ if ( !(osc.regs [2] & 0x80) )
+ volume = 0;
+
+ int gate = osc.regs [0] & 0x80;
+ int duty = ((osc.regs [0] >> 4) & 7) + 1;
+ int delta = ((gate || osc.phase < duty) ? volume : 0) - osc.last_amp;
+ blip_time_t time = last_time;
+ if ( delta )
+ {
+ osc.last_amp += delta;
+ square_synth.offset( time, delta, output );
+ }
+
+ time += osc.delay;
+ osc.delay = 0;
+ int period = osc.period();
+ if ( volume && !gate && period > 4 )
+ {
+ if ( time < end_time )
+ {
+ int phase = osc.phase;
+
+ do
+ {
+ phase++;
+ if ( phase == 16 )
+ {
+ phase = 0;
+ osc.last_amp = volume;
+ square_synth.offset( time, volume, output );
+ }
+ if ( phase == duty )
+ {
+ osc.last_amp = 0;
+ square_synth.offset( time, -volume, output );
+ }
+ time += period;
+ }
+ while ( time < end_time );
+
+ osc.phase = phase;
+ }
+ osc.delay = time - end_time;
+ }
+}
+
+void Nes_Vrc6_Apu::run_saw( blip_time_t end_time )
+{
+ Vrc6_Osc& osc = oscs [2];
+ Blip_Buffer* output = osc.output;
+ if ( !output )
+ return;
+ output->set_modified();
+
+ int amp = osc.amp;
+ int amp_step = osc.regs [0] & 0x3F;
+ blip_time_t time = last_time;
+ int last_amp = osc.last_amp;
+ if ( !(osc.regs [2] & 0x80) || !(amp_step | amp) )
+ {
+ osc.delay = 0;
+ int delta = (amp >> 3) - last_amp;
+ last_amp = amp >> 3;
+ saw_synth.offset( time, delta, output );
+ }
+ else
+ {
+ time += osc.delay;
+ if ( time < end_time )
+ {
+ int period = osc.period() * 2;
+ int phase = osc.phase;
+
+ do
+ {
+ if ( --phase == 0 )
+ {
+ phase = 7;
+ amp = 0;
+ }
+
+ int delta = (amp >> 3) - last_amp;
+ if ( delta )
+ {
+ last_amp = amp >> 3;
+ saw_synth.offset( time, delta, output );
+ }
+
+ time += period;
+ amp = (amp + amp_step) & 0xFF;
+ }
+ while ( time < end_time );
+
+ osc.phase = phase;
+ osc.amp = amp;
+ }
+
+ osc.delay = time - end_time;
+ }
+
+ osc.last_amp = last_amp;
+}
+
diff --git a/src/console/Nes_Vrc6_Apu.cxx b/src/console/Nes_Vrc6_Apu.cxx
deleted file mode 100644
index bd689c5a1743..000000000000
--- a/src/console/Nes_Vrc6_Apu.cxx
+++ /dev/null
@@ -1,215 +0,0 @@
-// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
-
-#include "Nes_Vrc6_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Nes_Vrc6_Apu::Nes_Vrc6_Apu()
-{
- output( NULL );
- volume( 1.0 );
- reset();
-}
-
-void Nes_Vrc6_Apu::reset()
-{
- last_time = 0;
- for ( int i = 0; i < osc_count; i++ )
- {
- Vrc6_Osc& osc = oscs [i];
- for ( int j = 0; j < reg_count; j++ )
- osc.regs [j] = 0;
- osc.delay = 0;
- osc.last_amp = 0;
- osc.phase = 1;
- osc.amp = 0;
- }
-}
-
-void Nes_Vrc6_Apu::output( Blip_Buffer* buf )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, buf );
-}
-
-void Nes_Vrc6_Apu::run_until( blip_time_t time )
-{
- require( time >= last_time );
- run_square( oscs [0], time );
- run_square( oscs [1], time );
- run_saw( time );
- last_time = time;
-}
-
-void Nes_Vrc6_Apu::write_osc( blip_time_t time, int osc_index, int reg, int data )
-{
- require( (unsigned) osc_index < osc_count );
- require( (unsigned) reg < reg_count );
-
- run_until( time );
- oscs [osc_index].regs [reg] = data;
-}
-
-void Nes_Vrc6_Apu::end_frame( blip_time_t time )
-{
- if ( time > last_time )
- run_until( time );
-
- assert( last_time >= time );
- last_time -= time;
-}
-
-void Nes_Vrc6_Apu::save_state( vrc6_apu_state_t* out ) const
-{
- assert( sizeof (vrc6_apu_state_t) == 20 );
- out->saw_amp = oscs [2].amp;
- for ( int i = 0; i < osc_count; i++ )
- {
- Vrc6_Osc const& osc = oscs [i];
- for ( int r = 0; r < reg_count; r++ )
- out->regs [i] [r] = osc.regs [r];
-
- out->delays [i] = osc.delay;
- out->phases [i] = osc.phase;
- }
-}
-
-void Nes_Vrc6_Apu::load_state( vrc6_apu_state_t const& in )
-{
- reset();
- oscs [2].amp = in.saw_amp;
- for ( int i = 0; i < osc_count; i++ )
- {
- Vrc6_Osc& osc = oscs [i];
- for ( int r = 0; r < reg_count; r++ )
- osc.regs [r] = in.regs [i] [r];
-
- osc.delay = in.delays [i];
- osc.phase = in.phases [i];
- }
- if ( !oscs [2].phase )
- oscs [2].phase = 1;
-}
-
-void Nes_Vrc6_Apu::run_square( Vrc6_Osc& osc, blip_time_t end_time )
-{
- Blip_Buffer* output = osc.output;
- if ( !output )
- return;
- output->set_modified();
-
- int volume = osc.regs [0] & 15;
- if ( !(osc.regs [2] & 0x80) )
- volume = 0;
-
- int gate = osc.regs [0] & 0x80;
- int duty = ((osc.regs [0] >> 4) & 7) + 1;
- int delta = ((gate || osc.phase < duty) ? volume : 0) - osc.last_amp;
- blip_time_t time = last_time;
- if ( delta )
- {
- osc.last_amp += delta;
- square_synth.offset( time, delta, output );
- }
-
- time += osc.delay;
- osc.delay = 0;
- int period = osc.period();
- if ( volume && !gate && period > 4 )
- {
- if ( time < end_time )
- {
- int phase = osc.phase;
-
- do
- {
- phase++;
- if ( phase == 16 )
- {
- phase = 0;
- osc.last_amp = volume;
- square_synth.offset( time, volume, output );
- }
- if ( phase == duty )
- {
- osc.last_amp = 0;
- square_synth.offset( time, -volume, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- osc.phase = phase;
- }
- osc.delay = time - end_time;
- }
-}
-
-void Nes_Vrc6_Apu::run_saw( blip_time_t end_time )
-{
- Vrc6_Osc& osc = oscs [2];
- Blip_Buffer* output = osc.output;
- if ( !output )
- return;
- output->set_modified();
-
- int amp = osc.amp;
- int amp_step = osc.regs [0] & 0x3F;
- blip_time_t time = last_time;
- int last_amp = osc.last_amp;
- if ( !(osc.regs [2] & 0x80) || !(amp_step | amp) )
- {
- osc.delay = 0;
- int delta = (amp >> 3) - last_amp;
- last_amp = amp >> 3;
- saw_synth.offset( time, delta, output );
- }
- else
- {
- time += osc.delay;
- if ( time < end_time )
- {
- int period = osc.period() * 2;
- int phase = osc.phase;
-
- do
- {
- if ( --phase == 0 )
- {
- phase = 7;
- amp = 0;
- }
-
- int delta = (amp >> 3) - last_amp;
- if ( delta )
- {
- last_amp = amp >> 3;
- saw_synth.offset( time, delta, output );
- }
-
- time += period;
- amp = (amp + amp_step) & 0xFF;
- }
- while ( time < end_time );
-
- osc.phase = phase;
- osc.amp = amp;
- }
-
- osc.delay = time - end_time;
- }
-
- osc.last_amp = last_amp;
-}
-
diff --git a/src/console/Nsf_Emu.cc b/src/console/Nsf_Emu.cc
new file mode 100644
index 000000000000..80c9038712ad
--- /dev/null
+++ b/src/console/Nsf_Emu.cc
@@ -0,0 +1,559 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Nsf_Emu.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+#include <stdio.h>
+
+#if !NSF_EMU_APU_ONLY
+ #include "Nes_Namco_Apu.h"
+ #include "Nes_Vrc6_Apu.h"
+ #include "Nes_Fme7_Apu.h"
+#endif
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+int const vrc6_flag = 0x01;
+int const namco_flag = 0x10;
+int const fme7_flag = 0x20;
+
+long const clock_divisor = 12;
+
+Nsf_Emu::equalizer_t const Nsf_Emu::nes_eq = { -1.0, 80 };
+Nsf_Emu::equalizer_t const Nsf_Emu::famicom_eq = { -15.0, 80 };
+
+int Nsf_Emu::pcm_read( void* emu, nes_addr_t addr )
+{
+ return *((Nsf_Emu*) emu)->cpu::get_code( addr );
+}
+
+Nsf_Emu::Nsf_Emu()
+{
+ vrc6 = 0;
+ namco = 0;
+ fme7 = 0;
+
+ set_type( gme_nsf_type );
+ set_silence_lookahead( 6 );
+ apu.dmc_reader( pcm_read, this );
+ Music_Emu::set_equalizer( nes_eq );
+ set_gain( 1.4 );
+ memset( unmapped_code, Nes_Cpu::bad_opcode, sizeof unmapped_code );
+}
+
+Nsf_Emu::~Nsf_Emu() { unload(); }
+
+void Nsf_Emu::unload()
+{
+ #if !NSF_EMU_APU_ONLY
+ {
+ delete vrc6;
+ vrc6 = 0;
+
+ delete namco;
+ namco = 0;
+
+ delete fme7;
+ fme7 = 0;
+ }
+ #endif
+
+ rom.clear();
+ Music_Emu::unload();
+}
+
+// Track info
+
+static void copy_nsf_fields( Nsf_Emu::header_t const& h, track_info_t* out )
+{
+ GME_COPY_FIELD( h, out, game );
+ GME_COPY_FIELD( h, out, author );
+ GME_COPY_FIELD( h, out, copyright );
+ if ( h.chip_flags )
+ Gme_File::copy_field_( out->system, "Famicom" );
+}
+
+blargg_err_t Nsf_Emu::track_info_( track_info_t* out, int ) const
+{
+ copy_nsf_fields( header_, out );
+ return 0;
+}
+
+static blargg_err_t check_nsf_header( void const* header )
+{
+ if ( memcmp( header, "NESM\x1A", 5 ) )
+ return gme_wrong_file_type;
+ return 0;
+}
+
+struct Nsf_File : Gme_Info_
+{
+ Nsf_Emu::header_t h;
+
+ Nsf_File() { set_type( gme_nsf_type ); }
+
+ blargg_err_t load_( Data_Reader& in )
+ {
+ blargg_err_t err = in.read( &h, Nsf_Emu::header_size );
+ if ( err )
+ return (err == in.eof_error ? gme_wrong_file_type : err);
+
+ if ( h.chip_flags & ~(namco_flag | vrc6_flag | fme7_flag) )
+ set_warning( "Uses unsupported audio expansion hardware" );
+
+ set_track_count( h.track_count );
+ return check_nsf_header( &h );
+ }
+
+ blargg_err_t track_info_( track_info_t* out, int ) const
+ {
+ copy_nsf_fields( h, out );
+ return 0;
+ }
+};
+
+static Music_Emu* new_nsf_emu () { return BLARGG_NEW Nsf_Emu ; }
+static Music_Emu* new_nsf_file() { return BLARGG_NEW Nsf_File; }
+
+static gme_type_t_ const gme_nsf_type_ = { "Nintendo NES", 0, &new_nsf_emu, &new_nsf_file, "NSF", 1 };
+gme_type_t const gme_nsf_type = &gme_nsf_type_;
+
+
+// Setup
+
+void Nsf_Emu::set_tempo_( double t )
+{
+ unsigned playback_rate = GET_LE16( header_.ntsc_speed );
+ unsigned standard_rate = 0x411A;
+ clock_rate_ = 1789772.72727;
+ play_period = 262 * 341L * 4 - 2; // two fewer PPU clocks every four frames
+
+ if ( pal_only )
+ {
+ play_period = 33247 * clock_divisor;
+ clock_rate_ = 1662607.125;
+ standard_rate = 0x4E20;
+ playback_rate = GET_LE16( header_.pal_speed );
+ }
+
+ if ( !playback_rate )
+ playback_rate = standard_rate;
+
+ if ( playback_rate != standard_rate || t != 1.0 )
+ play_period = long (playback_rate * clock_rate_ / (1000000.0 / clock_divisor * t));
+
+ apu.set_tempo( t );
+}
+
+blargg_err_t Nsf_Emu::init_sound()
+{
+ if ( header_.chip_flags & ~(namco_flag | vrc6_flag | fme7_flag) )
+ set_warning( "Uses unsupported audio expansion hardware" );
+
+ {
+ #define APU_NAMES "Square 1", "Square 2", "Triangle", "Noise", "DMC"
+
+ int const count = Nes_Apu::osc_count;
+ static const char* const apu_names [count] = { APU_NAMES };
+ set_voice_count( count );
+ set_voice_names( apu_names );
+
+ }
+
+ static int const types [] = {
+ wave_type | 1, wave_type | 2, wave_type | 0,
+ noise_type | 0, mixed_type | 1,
+ wave_type | 3, wave_type | 4, wave_type | 5,
+ wave_type | 6, wave_type | 7, wave_type | 8, wave_type | 9,
+ wave_type |10, wave_type |11, wave_type |12, wave_type |13
+ };
+ set_voice_types( types ); // common to all sound chip configurations
+
+ double adjusted_gain = gain();
+
+ #if NSF_EMU_APU_ONLY
+ {
+ if ( header_.chip_flags )
+ set_warning( "Uses unsupported audio expansion hardware" );
+ }
+ #else
+ {
+ if ( header_.chip_flags & (namco_flag | vrc6_flag | fme7_flag) )
+ set_voice_count( Nes_Apu::osc_count + 3 );
+
+ if ( header_.chip_flags & namco_flag )
+ {
+ namco = BLARGG_NEW Nes_Namco_Apu;
+ CHECK_ALLOC( namco );
+ adjusted_gain *= 0.75;
+
+ int const count = Nes_Apu::osc_count + Nes_Namco_Apu::osc_count;
+ static const char* const names [count] = {
+ APU_NAMES,
+ "Wave 1", "Wave 2", "Wave 3", "Wave 4",
+ "Wave 5", "Wave 6", "Wave 7", "Wave 8"
+ };
+ set_voice_count( count );
+ set_voice_names( names );
+ }
+
+ if ( header_.chip_flags & vrc6_flag )
+ {
+ vrc6 = BLARGG_NEW Nes_Vrc6_Apu;
+ CHECK_ALLOC( vrc6 );
+ adjusted_gain *= 0.75;
+
+ {
+ int const count = Nes_Apu::osc_count + Nes_Vrc6_Apu::osc_count;
+ static const char* const names [count] = {
+ APU_NAMES,
+ "Saw Wave", "Square 3", "Square 4"
+ };
+ set_voice_count( count );
+ set_voice_names( names );
+ }
+
+ if ( header_.chip_flags & namco_flag )
+ {
+ int const count = Nes_Apu::osc_count + Nes_Vrc6_Apu::osc_count +
+ Nes_Namco_Apu::osc_count;
+ static const char* const names [count] = {
+ APU_NAMES,
+ "Saw Wave", "Square 3", "Square 4",
+ "Wave 1", "Wave 2", "Wave 3", "Wave 4",
+ "Wave 5", "Wave 6", "Wave 7", "Wave 8"
+ };
+ set_voice_count( count );
+ set_voice_names( names );
+ }
+ }
+
+ if ( header_.chip_flags & fme7_flag )
+ {
+ fme7 = BLARGG_NEW Nes_Fme7_Apu;
+ CHECK_ALLOC( fme7 );
+ adjusted_gain *= 0.75;
+
+ int const count = Nes_Apu::osc_count + Nes_Fme7_Apu::osc_count;
+ static const char* const names [count] = {
+ APU_NAMES,
+ "Square 3", "Square 4", "Square 5"
+ };
+ set_voice_count( count );
+ set_voice_names( names );
+ }
+
+ if ( namco ) namco->volume( adjusted_gain );
+ if ( vrc6 ) vrc6 ->volume( adjusted_gain );
+ if ( fme7 ) fme7 ->volume( adjusted_gain );
+ }
+ #endif
+
+ apu.volume( adjusted_gain );
+
+ return 0;
+}
+
+blargg_err_t Nsf_Emu::load_( Data_Reader& in )
+{
+ assert( offsetof (header_t,unused [4]) == header_size );
+ RETURN_ERR( rom.load( in, header_size, &header_, 0 ) );
+
+ set_track_count( header_.track_count );
+ RETURN_ERR( check_nsf_header( &header_ ) );
+
+ if ( header_.vers != 1 )
+ set_warning( "Unknown file version" );
+
+ // sound and memory
+ blargg_err_t err = init_sound();
+ if ( err )
+ return err;
+
+ // set up data
+ nes_addr_t load_addr = GET_LE16( header_.load_addr );
+ init_addr = GET_LE16( header_.init_addr );
+ play_addr = GET_LE16( header_.play_addr );
+ if ( !load_addr ) load_addr = rom_begin;
+ if ( !init_addr ) init_addr = rom_begin;
+ if ( !play_addr ) play_addr = rom_begin;
+ if ( load_addr < rom_begin || init_addr < rom_begin )
+ {
+ const char* w = warning();
+ if ( !w )
+ w = "Corrupt file (invalid load/init/play address)";
+ return w;
+ }
+
+ rom.set_addr( load_addr % bank_size );
+ int total_banks = rom.size() / bank_size;
+
+ // bank switching
+ int first_bank = (load_addr - rom_begin) / bank_size;
+ for ( int i = 0; i < bank_count; i++ )
+ {
+ unsigned bank = i - first_bank;
+ if ( bank >= (unsigned) total_banks )
+ bank = 0;
+ initial_banks [i] = bank;
+
+ if ( header_.banks [i] )
+ {
+ // bank-switched
+ memcpy( initial_banks, header_.banks, sizeof initial_banks );
+ break;
+ }
+ }
+
+ pal_only = (header_.speed_flags & 3) == 1;
+
+ #if !NSF_EMU_EXTRA_FLAGS
+ header_.speed_flags = 0;
+ #endif
+
+ set_tempo( tempo() );
+
+ return setup_buffer( (long) (clock_rate_ + 0.5) );
+}
+
+void Nsf_Emu::update_eq( blip_eq_t const& eq )
+{
+ apu.treble_eq( eq );
+
+ #if !NSF_EMU_APU_ONLY
+ {
+ if ( namco ) namco->treble_eq( eq );
+ if ( vrc6 ) vrc6 ->treble_eq( eq );
+ if ( fme7 ) fme7 ->treble_eq( eq );
+ }
+ #endif
+}
+
+void Nsf_Emu::set_voice( int i, Blip_Buffer* buf, Blip_Buffer*, Blip_Buffer* )
+{
+ if ( i < Nes_Apu::osc_count )
+ {
+ apu.osc_output( i, buf );
+ return;
+ }
+ i -= Nes_Apu::osc_count;
+
+ #if !NSF_EMU_APU_ONLY
+ {
+ if ( fme7 && i < Nes_Fme7_Apu::osc_count )
+ {
+ fme7->osc_output( i, buf );
+ return;
+ }
+
+ if ( vrc6 )
+ {
+ if ( i < Nes_Vrc6_Apu::osc_count )
+ {
+ // put saw first
+ if ( --i < 0 )
+ i = 2;
+ vrc6->osc_output( i, buf );
+ return;
+ }
+ i -= Nes_Vrc6_Apu::osc_count;
+ }
+
+ if ( namco && i < Nes_Namco_Apu::osc_count )
+ {
+ namco->osc_output( i, buf );
+ return;
+ }
+ }
+ #endif
+}
+
+// Emulation
+
+// see nes_cpu_io.h for read/write functions
+
+void Nsf_Emu::cpu_write_misc( nes_addr_t addr, int data )
+{
+ #if !NSF_EMU_APU_ONLY
+ {
+ if ( namco )
+ {
+ switch ( addr )
+ {
+ case Nes_Namco_Apu::data_reg_addr:
+ namco->write_data( time(), data );
+ return;
+
+ case Nes_Namco_Apu::addr_reg_addr:
+ namco->write_addr( data );
+ return;
+ }
+ }
+
+ if ( addr >= Nes_Fme7_Apu::latch_addr && fme7 )
+ {
+ switch ( addr & Nes_Fme7_Apu::addr_mask )
+ {
+ case Nes_Fme7_Apu::latch_addr:
+ fme7->write_latch( data );
+ return;
+
+ case Nes_Fme7_Apu::data_addr:
+ fme7->write_data( time(), data );
+ return;
+ }
+ }
+
+ if ( vrc6 )
+ {
+ unsigned reg = addr & (Nes_Vrc6_Apu::addr_step - 1);
+ unsigned osc = unsigned (addr - Nes_Vrc6_Apu::base_addr) / Nes_Vrc6_Apu::addr_step;
+ if ( osc < Nes_Vrc6_Apu::osc_count && reg < Nes_Vrc6_Apu::reg_count )
+ {
+ vrc6->write_osc( time(), osc, reg, data );
+ return;
+ }
+ }
+ }
+ #endif
+
+ // unmapped write
+
+ #ifndef NDEBUG
+ {
+ // some games write to $8000 and $8001 repeatedly
+ if ( addr == 0x8000 || addr == 0x8001 ) return;
+
+ // probably namco sound mistakenly turned on in mck
+ if ( addr == 0x4800 || addr == 0xF800 ) return;
+
+ // memory mapper?
+ if ( addr == 0xFFF8 ) return;
+
+ debug_printf( "write_unmapped( 0x%04X, 0x%02X )\n", (unsigned) addr, (unsigned) data );
+ }
+ #endif
+}
+
+blargg_err_t Nsf_Emu::start_track_( int track )
+{
+ RETURN_ERR( Classic_Emu::start_track_( track ) );
+
+ memset( low_mem, 0, sizeof low_mem );
+ memset( sram, 0, sizeof sram );
+
+ cpu::reset( unmapped_code ); // also maps low_mem
+ cpu::map_code( sram_addr, sizeof sram, sram );
+ for ( int i = 0; i < bank_count; ++i )
+ cpu_write( bank_select_addr + i, initial_banks [i] );
+
+ apu.reset( pal_only, (header_.speed_flags & 0x20) ? 0x3F : 0 );
+ apu.write_register( 0, 0x4015, 0x0F );
+ apu.write_register( 0, 0x4017, (header_.speed_flags & 0x10) ? 0x80 : 0 );
+ #if !NSF_EMU_APU_ONLY
+ {
+ if ( namco ) namco->reset();
+ if ( vrc6 ) vrc6 ->reset();
+ if ( fme7 ) fme7 ->reset();
+ }
+ #endif
+
+ play_ready = 4;
+ play_extra = 0;
+ next_play = play_period / clock_divisor;
+
+ saved_state.pc = badop_addr;
+ low_mem [0x1FF] = (badop_addr - 1) >> 8;
+ low_mem [0x1FE] = (badop_addr - 1) & 0xFF;
+ r.sp = 0xFD;
+ r.pc = init_addr;
+ r.a = track;
+ r.x = pal_only;
+
+ return 0;
+}
+
+blargg_err_t Nsf_Emu::run_clocks( blip_time_t& duration, int )
+{
+ set_time( 0 );
+ while ( time() < duration )
+ {
+ nes_time_t end = min( (blip_time_t) next_play, duration );
+ end = min( end, time() + 32767 ); // allows CPU to use 16-bit time delta
+ if ( cpu::run( end ) )
+ {
+ if ( r.pc != badop_addr )
+ {
+ set_warning( "Emulation error (illegal instruction)" );
+ r.pc++;
+ }
+ else
+ {
+ play_ready = 1;
+ if ( saved_state.pc != badop_addr )
+ {
+ cpu::r = saved_state;
+ saved_state.pc = badop_addr;
+ }
+ else
+ {
+ set_time( end );
+ }
+ }
+ }
+
+ if ( time() >= next_play )
+ {
+ nes_time_t period = (play_period + play_extra) / clock_divisor;
+ play_extra = play_period - period * clock_divisor;
+ next_play += period;
+ if ( play_ready && !--play_ready )
+ {
+ check( saved_state.pc == badop_addr );
+ if ( r.pc != badop_addr )
+ saved_state = cpu::r;
+
+ r.pc = play_addr;
+ low_mem [0x100 + r.sp--] = (badop_addr - 1) >> 8;
+ low_mem [0x100 + r.sp--] = (badop_addr - 1) & 0xFF;
+ GME_FRAME_HOOK( this );
+ }
+ }
+ }
+
+ if ( cpu::error_count() )
+ {
+ cpu::clear_error_count();
+ set_warning( "Emulation error (illegal instruction)" );
+ }
+
+ duration = time();
+ next_play -= duration;
+ check( next_play >= 0 );
+ if ( next_play < 0 )
+ next_play = 0;
+
+ apu.end_frame( duration );
+
+ #if !NSF_EMU_APU_ONLY
+ {
+ if ( namco ) namco->end_frame( duration );
+ if ( vrc6 ) vrc6 ->end_frame( duration );
+ if ( fme7 ) fme7 ->end_frame( duration );
+ }
+ #endif
+
+ return 0;
+}
diff --git a/src/console/Nsf_Emu.cxx b/src/console/Nsf_Emu.cxx
deleted file mode 100644
index 80c9038712ad..000000000000
--- a/src/console/Nsf_Emu.cxx
+++ /dev/null
@@ -1,559 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Nsf_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-#include <stdio.h>
-
-#if !NSF_EMU_APU_ONLY
- #include "Nes_Namco_Apu.h"
- #include "Nes_Vrc6_Apu.h"
- #include "Nes_Fme7_Apu.h"
-#endif
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const vrc6_flag = 0x01;
-int const namco_flag = 0x10;
-int const fme7_flag = 0x20;
-
-long const clock_divisor = 12;
-
-Nsf_Emu::equalizer_t const Nsf_Emu::nes_eq = { -1.0, 80 };
-Nsf_Emu::equalizer_t const Nsf_Emu::famicom_eq = { -15.0, 80 };
-
-int Nsf_Emu::pcm_read( void* emu, nes_addr_t addr )
-{
- return *((Nsf_Emu*) emu)->cpu::get_code( addr );
-}
-
-Nsf_Emu::Nsf_Emu()
-{
- vrc6 = 0;
- namco = 0;
- fme7 = 0;
-
- set_type( gme_nsf_type );
- set_silence_lookahead( 6 );
- apu.dmc_reader( pcm_read, this );
- Music_Emu::set_equalizer( nes_eq );
- set_gain( 1.4 );
- memset( unmapped_code, Nes_Cpu::bad_opcode, sizeof unmapped_code );
-}
-
-Nsf_Emu::~Nsf_Emu() { unload(); }
-
-void Nsf_Emu::unload()
-{
- #if !NSF_EMU_APU_ONLY
- {
- delete vrc6;
- vrc6 = 0;
-
- delete namco;
- namco = 0;
-
- delete fme7;
- fme7 = 0;
- }
- #endif
-
- rom.clear();
- Music_Emu::unload();
-}
-
-// Track info
-
-static void copy_nsf_fields( Nsf_Emu::header_t const& h, track_info_t* out )
-{
- GME_COPY_FIELD( h, out, game );
- GME_COPY_FIELD( h, out, author );
- GME_COPY_FIELD( h, out, copyright );
- if ( h.chip_flags )
- Gme_File::copy_field_( out->system, "Famicom" );
-}
-
-blargg_err_t Nsf_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_nsf_fields( header_, out );
- return 0;
-}
-
-static blargg_err_t check_nsf_header( void const* header )
-{
- if ( memcmp( header, "NESM\x1A", 5 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Nsf_File : Gme_Info_
-{
- Nsf_Emu::header_t h;
-
- Nsf_File() { set_type( gme_nsf_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- blargg_err_t err = in.read( &h, Nsf_Emu::header_size );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
-
- if ( h.chip_flags & ~(namco_flag | vrc6_flag | fme7_flag) )
- set_warning( "Uses unsupported audio expansion hardware" );
-
- set_track_count( h.track_count );
- return check_nsf_header( &h );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_nsf_fields( h, out );
- return 0;
- }
-};
-
-static Music_Emu* new_nsf_emu () { return BLARGG_NEW Nsf_Emu ; }
-static Music_Emu* new_nsf_file() { return BLARGG_NEW Nsf_File; }
-
-static gme_type_t_ const gme_nsf_type_ = { "Nintendo NES", 0, &new_nsf_emu, &new_nsf_file, "NSF", 1 };
-gme_type_t const gme_nsf_type = &gme_nsf_type_;
-
-
-// Setup
-
-void Nsf_Emu::set_tempo_( double t )
-{
- unsigned playback_rate = GET_LE16( header_.ntsc_speed );
- unsigned standard_rate = 0x411A;
- clock_rate_ = 1789772.72727;
- play_period = 262 * 341L * 4 - 2; // two fewer PPU clocks every four frames
-
- if ( pal_only )
- {
- play_period = 33247 * clock_divisor;
- clock_rate_ = 1662607.125;
- standard_rate = 0x4E20;
- playback_rate = GET_LE16( header_.pal_speed );
- }
-
- if ( !playback_rate )
- playback_rate = standard_rate;
-
- if ( playback_rate != standard_rate || t != 1.0 )
- play_period = long (playback_rate * clock_rate_ / (1000000.0 / clock_divisor * t));
-
- apu.set_tempo( t );
-}
-
-blargg_err_t Nsf_Emu::init_sound()
-{
- if ( header_.chip_flags & ~(namco_flag | vrc6_flag | fme7_flag) )
- set_warning( "Uses unsupported audio expansion hardware" );
-
- {
- #define APU_NAMES "Square 1", "Square 2", "Triangle", "Noise", "DMC"
-
- int const count = Nes_Apu::osc_count;
- static const char* const apu_names [count] = { APU_NAMES };
- set_voice_count( count );
- set_voice_names( apu_names );
-
- }
-
- static int const types [] = {
- wave_type | 1, wave_type | 2, wave_type | 0,
- noise_type | 0, mixed_type | 1,
- wave_type | 3, wave_type | 4, wave_type | 5,
- wave_type | 6, wave_type | 7, wave_type | 8, wave_type | 9,
- wave_type |10, wave_type |11, wave_type |12, wave_type |13
- };
- set_voice_types( types ); // common to all sound chip configurations
-
- double adjusted_gain = gain();
-
- #if NSF_EMU_APU_ONLY
- {
- if ( header_.chip_flags )
- set_warning( "Uses unsupported audio expansion hardware" );
- }
- #else
- {
- if ( header_.chip_flags & (namco_flag | vrc6_flag | fme7_flag) )
- set_voice_count( Nes_Apu::osc_count + 3 );
-
- if ( header_.chip_flags & namco_flag )
- {
- namco = BLARGG_NEW Nes_Namco_Apu;
- CHECK_ALLOC( namco );
- adjusted_gain *= 0.75;
-
- int const count = Nes_Apu::osc_count + Nes_Namco_Apu::osc_count;
- static const char* const names [count] = {
- APU_NAMES,
- "Wave 1", "Wave 2", "Wave 3", "Wave 4",
- "Wave 5", "Wave 6", "Wave 7", "Wave 8"
- };
- set_voice_count( count );
- set_voice_names( names );
- }
-
- if ( header_.chip_flags & vrc6_flag )
- {
- vrc6 = BLARGG_NEW Nes_Vrc6_Apu;
- CHECK_ALLOC( vrc6 );
- adjusted_gain *= 0.75;
-
- {
- int const count = Nes_Apu::osc_count + Nes_Vrc6_Apu::osc_count;
- static const char* const names [count] = {
- APU_NAMES,
- "Saw Wave", "Square 3", "Square 4"
- };
- set_voice_count( count );
- set_voice_names( names );
- }
-
- if ( header_.chip_flags & namco_flag )
- {
- int const count = Nes_Apu::osc_count + Nes_Vrc6_Apu::osc_count +
- Nes_Namco_Apu::osc_count;
- static const char* const names [count] = {
- APU_NAMES,
- "Saw Wave", "Square 3", "Square 4",
- "Wave 1", "Wave 2", "Wave 3", "Wave 4",
- "Wave 5", "Wave 6", "Wave 7", "Wave 8"
- };
- set_voice_count( count );
- set_voice_names( names );
- }
- }
-
- if ( header_.chip_flags & fme7_flag )
- {
- fme7 = BLARGG_NEW Nes_Fme7_Apu;
- CHECK_ALLOC( fme7 );
- adjusted_gain *= 0.75;
-
- int const count = Nes_Apu::osc_count + Nes_Fme7_Apu::osc_count;
- static const char* const names [count] = {
- APU_NAMES,
- "Square 3", "Square 4", "Square 5"
- };
- set_voice_count( count );
- set_voice_names( names );
- }
-
- if ( namco ) namco->volume( adjusted_gain );
- if ( vrc6 ) vrc6 ->volume( adjusted_gain );
- if ( fme7 ) fme7 ->volume( adjusted_gain );
- }
- #endif
-
- apu.volume( adjusted_gain );
-
- return 0;
-}
-
-blargg_err_t Nsf_Emu::load_( Data_Reader& in )
-{
- assert( offsetof (header_t,unused [4]) == header_size );
- RETURN_ERR( rom.load( in, header_size, &header_, 0 ) );
-
- set_track_count( header_.track_count );
- RETURN_ERR( check_nsf_header( &header_ ) );
-
- if ( header_.vers != 1 )
- set_warning( "Unknown file version" );
-
- // sound and memory
- blargg_err_t err = init_sound();
- if ( err )
- return err;
-
- // set up data
- nes_addr_t load_addr = GET_LE16( header_.load_addr );
- init_addr = GET_LE16( header_.init_addr );
- play_addr = GET_LE16( header_.play_addr );
- if ( !load_addr ) load_addr = rom_begin;
- if ( !init_addr ) init_addr = rom_begin;
- if ( !play_addr ) play_addr = rom_begin;
- if ( load_addr < rom_begin || init_addr < rom_begin )
- {
- const char* w = warning();
- if ( !w )
- w = "Corrupt file (invalid load/init/play address)";
- return w;
- }
-
- rom.set_addr( load_addr % bank_size );
- int total_banks = rom.size() / bank_size;
-
- // bank switching
- int first_bank = (load_addr - rom_begin) / bank_size;
- for ( int i = 0; i < bank_count; i++ )
- {
- unsigned bank = i - first_bank;
- if ( bank >= (unsigned) total_banks )
- bank = 0;
- initial_banks [i] = bank;
-
- if ( header_.banks [i] )
- {
- // bank-switched
- memcpy( initial_banks, header_.banks, sizeof initial_banks );
- break;
- }
- }
-
- pal_only = (header_.speed_flags & 3) == 1;
-
- #if !NSF_EMU_EXTRA_FLAGS
- header_.speed_flags = 0;
- #endif
-
- set_tempo( tempo() );
-
- return setup_buffer( (long) (clock_rate_ + 0.5) );
-}
-
-void Nsf_Emu::update_eq( blip_eq_t const& eq )
-{
- apu.treble_eq( eq );
-
- #if !NSF_EMU_APU_ONLY
- {
- if ( namco ) namco->treble_eq( eq );
- if ( vrc6 ) vrc6 ->treble_eq( eq );
- if ( fme7 ) fme7 ->treble_eq( eq );
- }
- #endif
-}
-
-void Nsf_Emu::set_voice( int i, Blip_Buffer* buf, Blip_Buffer*, Blip_Buffer* )
-{
- if ( i < Nes_Apu::osc_count )
- {
- apu.osc_output( i, buf );
- return;
- }
- i -= Nes_Apu::osc_count;
-
- #if !NSF_EMU_APU_ONLY
- {
- if ( fme7 && i < Nes_Fme7_Apu::osc_count )
- {
- fme7->osc_output( i, buf );
- return;
- }
-
- if ( vrc6 )
- {
- if ( i < Nes_Vrc6_Apu::osc_count )
- {
- // put saw first
- if ( --i < 0 )
- i = 2;
- vrc6->osc_output( i, buf );
- return;
- }
- i -= Nes_Vrc6_Apu::osc_count;
- }
-
- if ( namco && i < Nes_Namco_Apu::osc_count )
- {
- namco->osc_output( i, buf );
- return;
- }
- }
- #endif
-}
-
-// Emulation
-
-// see nes_cpu_io.h for read/write functions
-
-void Nsf_Emu::cpu_write_misc( nes_addr_t addr, int data )
-{
- #if !NSF_EMU_APU_ONLY
- {
- if ( namco )
- {
- switch ( addr )
- {
- case Nes_Namco_Apu::data_reg_addr:
- namco->write_data( time(), data );
- return;
-
- case Nes_Namco_Apu::addr_reg_addr:
- namco->write_addr( data );
- return;
- }
- }
-
- if ( addr >= Nes_Fme7_Apu::latch_addr && fme7 )
- {
- switch ( addr & Nes_Fme7_Apu::addr_mask )
- {
- case Nes_Fme7_Apu::latch_addr:
- fme7->write_latch( data );
- return;
-
- case Nes_Fme7_Apu::data_addr:
- fme7->write_data( time(), data );
- return;
- }
- }
-
- if ( vrc6 )
- {
- unsigned reg = addr & (Nes_Vrc6_Apu::addr_step - 1);
- unsigned osc = unsigned (addr - Nes_Vrc6_Apu::base_addr) / Nes_Vrc6_Apu::addr_step;
- if ( osc < Nes_Vrc6_Apu::osc_count && reg < Nes_Vrc6_Apu::reg_count )
- {
- vrc6->write_osc( time(), osc, reg, data );
- return;
- }
- }
- }
- #endif
-
- // unmapped write
-
- #ifndef NDEBUG
- {
- // some games write to $8000 and $8001 repeatedly
- if ( addr == 0x8000 || addr == 0x8001 ) return;
-
- // probably namco sound mistakenly turned on in mck
- if ( addr == 0x4800 || addr == 0xF800 ) return;
-
- // memory mapper?
- if ( addr == 0xFFF8 ) return;
-
- debug_printf( "write_unmapped( 0x%04X, 0x%02X )\n", (unsigned) addr, (unsigned) data );
- }
- #endif
-}
-
-blargg_err_t Nsf_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( low_mem, 0, sizeof low_mem );
- memset( sram, 0, sizeof sram );
-
- cpu::reset( unmapped_code ); // also maps low_mem
- cpu::map_code( sram_addr, sizeof sram, sram );
- for ( int i = 0; i < bank_count; ++i )
- cpu_write( bank_select_addr + i, initial_banks [i] );
-
- apu.reset( pal_only, (header_.speed_flags & 0x20) ? 0x3F : 0 );
- apu.write_register( 0, 0x4015, 0x0F );
- apu.write_register( 0, 0x4017, (header_.speed_flags & 0x10) ? 0x80 : 0 );
- #if !NSF_EMU_APU_ONLY
- {
- if ( namco ) namco->reset();
- if ( vrc6 ) vrc6 ->reset();
- if ( fme7 ) fme7 ->reset();
- }
- #endif
-
- play_ready = 4;
- play_extra = 0;
- next_play = play_period / clock_divisor;
-
- saved_state.pc = badop_addr;
- low_mem [0x1FF] = (badop_addr - 1) >> 8;
- low_mem [0x1FE] = (badop_addr - 1) & 0xFF;
- r.sp = 0xFD;
- r.pc = init_addr;
- r.a = track;
- r.x = pal_only;
-
- return 0;
-}
-
-blargg_err_t Nsf_Emu::run_clocks( blip_time_t& duration, int )
-{
- set_time( 0 );
- while ( time() < duration )
- {
- nes_time_t end = min( (blip_time_t) next_play, duration );
- end = min( end, time() + 32767 ); // allows CPU to use 16-bit time delta
- if ( cpu::run( end ) )
- {
- if ( r.pc != badop_addr )
- {
- set_warning( "Emulation error (illegal instruction)" );
- r.pc++;
- }
- else
- {
- play_ready = 1;
- if ( saved_state.pc != badop_addr )
- {
- cpu::r = saved_state;
- saved_state.pc = badop_addr;
- }
- else
- {
- set_time( end );
- }
- }
- }
-
- if ( time() >= next_play )
- {
- nes_time_t period = (play_period + play_extra) / clock_divisor;
- play_extra = play_period - period * clock_divisor;
- next_play += period;
- if ( play_ready && !--play_ready )
- {
- check( saved_state.pc == badop_addr );
- if ( r.pc != badop_addr )
- saved_state = cpu::r;
-
- r.pc = play_addr;
- low_mem [0x100 + r.sp--] = (badop_addr - 1) >> 8;
- low_mem [0x100 + r.sp--] = (badop_addr - 1) & 0xFF;
- GME_FRAME_HOOK( this );
- }
- }
- }
-
- if ( cpu::error_count() )
- {
- cpu::clear_error_count();
- set_warning( "Emulation error (illegal instruction)" );
- }
-
- duration = time();
- next_play -= duration;
- check( next_play >= 0 );
- if ( next_play < 0 )
- next_play = 0;
-
- apu.end_frame( duration );
-
- #if !NSF_EMU_APU_ONLY
- {
- if ( namco ) namco->end_frame( duration );
- if ( vrc6 ) vrc6 ->end_frame( duration );
- if ( fme7 ) fme7 ->end_frame( duration );
- }
- #endif
-
- return 0;
-}
diff --git a/src/console/Nsfe_Emu.cc b/src/console/Nsfe_Emu.cc
new file mode 100644
index 000000000000..2f3d5a762ed4
--- /dev/null
+++ b/src/console/Nsfe_Emu.cc
@@ -0,0 +1,332 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Nsfe_Emu.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+#include <ctype.h>
+
+/* Copyright (C) 2005-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+Nsfe_Info::Nsfe_Info() { playlist_disabled = false; }
+
+Nsfe_Info::~Nsfe_Info() { }
+
+inline void Nsfe_Info::unload()
+{
+ track_name_data.clear();
+ track_names.clear();
+ playlist.clear();
+ track_times.clear();
+}
+
+// TODO: if no playlist, treat as if there is a playlist that is just 1,2,3,4,5... ?
+void Nsfe_Info::disable_playlist( bool b )
+{
+ playlist_disabled = b;
+ info.track_count = playlist.size();
+ if ( !info.track_count || playlist_disabled )
+ info.track_count = actual_track_count_;
+}
+
+int Nsfe_Info::remap_track( int track ) const
+{
+ if ( !playlist_disabled && (unsigned) track < playlist.size() )
+ track = playlist [track];
+ return track;
+}
+
+// Read multiple strings and separate into individual strings
+static blargg_err_t read_strs( Data_Reader& in, long size, blargg_vector<char>& chars,
+ blargg_vector<const char*>& strs )
+{
+ RETURN_ERR( chars.resize( size + 1 ) );
+ chars [size] = 0; // in case last string doesn't have terminator
+ RETURN_ERR( in.read( &chars [0], size ) );
+
+ RETURN_ERR( strs.resize( 128 ) );
+ int count = 0;
+ for ( int i = 0; i < size; i++ )
+ {
+ if ( (int) strs.size() <= count )
+ RETURN_ERR( strs.resize( count * 2 ) );
+ strs [count++] = &chars [i];
+ while ( i < size && chars [i] )
+ i++;
+ }
+
+ return strs.resize( count );
+}
+
+// Copy in to out, where out has out_max characters allocated. Truncate to
+// out_max - 1 characters.
+static void copy_str( const char* in, char* out, int out_max )
+{
+ out [out_max - 1] = 0;
+ strncpy( out, in, out_max - 1 );
+}
+
+struct nsfe_info_t
+{
+ byte load_addr [2];
+ byte init_addr [2];
+ byte play_addr [2];
+ byte speed_flags;
+ byte chip_flags;
+ byte track_count;
+ byte first_track;
+ byte unused [6];
+};
+
+blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu )
+{
+ int const nsfe_info_size = 16;
+ assert( offsetof (nsfe_info_t,unused [6]) == nsfe_info_size );
+
+ // check header
+ byte signature [4];
+ blargg_err_t err = in.read( signature, sizeof signature );
+ if ( err )
+ return (err == in.eof_error ? gme_wrong_file_type : err);
+ if ( memcmp( signature, "NSFE", 4 ) )
+ return gme_wrong_file_type;
+
+ // free previous info
+ track_name_data.clear();
+ track_names.clear();
+ playlist.clear();
+ track_times.clear();
+
+ // default nsf header
+ static const Nsf_Emu::header_t base_header =
+ {
+ {'N','E','S','M','\x1A'},// tag
+ 1, // version
+ 1, 1, // track count, first track
+ {0,0},{0,0},{0,0}, // addresses
+ "","","", // strings
+ {0x1A, 0x41}, // NTSC rate
+ {0,0,0,0,0,0,0,0}, // banks
+ {0x20, 0x4E}, // PAL rate
+ 0, 0, // flags
+ {0,0,0,0} // unused
+ };
+ Nsf_Emu::header_t& header = info;
+ header = base_header;
+
+ // parse tags
+ int phase = 0;
+ while ( phase != 3 )
+ {
+ // read size and tag
+ byte block_header [2] [4];
+ RETURN_ERR( in.read( block_header, sizeof block_header ) );
+ blargg_long size = GET_LE32( block_header [0] );
+ blargg_long tag = GET_LE32( block_header [1] );
+
+ //debug_printf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) );
+
+ switch ( tag )
+ {
+ case BLARGG_4CHAR('O','F','N','I'): {
+ check( phase == 0 );
+ if ( size < 8 )
+ return "Corrupt file";
+
+ nsfe_info_t finfo;
+ finfo.track_count = 1;
+ finfo.first_track = 0;
+
+ RETURN_ERR( in.read( &finfo, min( size, (blargg_long) nsfe_info_size ) ) );
+ if ( size > nsfe_info_size )
+ RETURN_ERR( in.skip( size - nsfe_info_size ) );
+ phase = 1;
+ info.speed_flags = finfo.speed_flags;
+ info.chip_flags = finfo.chip_flags;
+ info.track_count = finfo.track_count;
+ this->actual_track_count_ = finfo.track_count;
+ info.first_track = finfo.first_track;
+ memcpy( info.load_addr, finfo.load_addr, 2 * 3 );
+ break;
+ }
+
+ case BLARGG_4CHAR('K','N','A','B'):
+ if ( size > (int) sizeof info.banks )
+ return "Corrupt file";
+ RETURN_ERR( in.read( info.banks, size ) );
+ break;
+
+ case BLARGG_4CHAR('h','t','u','a'): {
+ blargg_vector<char> chars;
+ blargg_vector<const char*> strs;
+ RETURN_ERR( read_strs( in, size, chars, strs ) );
+ int n = strs.size();
+
+ if ( n > 3 )
+ copy_str( strs [3], info.dumper, sizeof info.dumper );
+
+ if ( n > 2 )
+ copy_str( strs [2], info.copyright, sizeof info.copyright );
+
+ if ( n > 1 )
+ copy_str( strs [1], info.author, sizeof info.author );
+
+ if ( n > 0 )
+ copy_str( strs [0], info.game, sizeof info.game );
+
+ break;
+ }
+
+ case BLARGG_4CHAR('e','m','i','t'):
+ RETURN_ERR( track_times.resize( size / 4 ) );
+ RETURN_ERR( in.read( track_times.begin(), track_times.size() * 4 ) );
+ break;
+
+ case BLARGG_4CHAR('l','b','l','t'):
+ RETURN_ERR( read_strs( in, size, track_name_data, track_names ) );
+ break;
+
+ case BLARGG_4CHAR('t','s','l','p'):
+ RETURN_ERR( playlist.resize( size ) );
+ RETURN_ERR( in.read( &playlist [0], size ) );
+ break;
+
+ case BLARGG_4CHAR('A','T','A','D'): {
+ check( phase == 1 );
+ phase = 2;
+ if ( !nsf_emu )
+ {
+ RETURN_ERR( in.skip( size ) );
+ }
+ else
+ {
+ Subset_Reader sub( &in, size ); // limit emu to nsf data
+ Remaining_Reader rem( &header, Nsf_Emu::header_size, &sub );
+ RETURN_ERR( nsf_emu->load( rem ) );
+ check( rem.remain() == 0 );
+ }
+ break;
+ }
+
+ case BLARGG_4CHAR('D','N','E','N'):
+ check( phase == 2 );
+ phase = 3;
+ break;
+
+ default:
+ // tags that can be skipped start with a lowercase character
+ check( islower( (tag >> 24) & 0xFF ) );
+ RETURN_ERR( in.skip( size ) );
+ break;
+ }
+ }
+
+ return 0;
+}
+
+blargg_err_t Nsfe_Info::track_info_( track_info_t* out, int track ) const
+{
+ int remapped = remap_track( track );
+ if ( (unsigned) remapped < track_times.size() )
+ {
+ long length = (int32_t) GET_LE32( track_times [remapped] );
+ if ( length > 0 )
+ out->length = length;
+ }
+ if ( (unsigned) remapped < track_names.size() )
+ Gme_File::copy_field_( out->song, track_names [remapped] );
+
+ GME_COPY_FIELD( info, out, game );
+ GME_COPY_FIELD( info, out, author );
+ GME_COPY_FIELD( info, out, copyright );
+ GME_COPY_FIELD( info, out, dumper );
+ return 0;
+}
+
+Nsfe_Emu::Nsfe_Emu()
+{
+ loading = false;
+ set_type( gme_nsfe_type );
+}
+
+Nsfe_Emu::~Nsfe_Emu() { }
+
+void Nsfe_Emu::unload()
+{
+ if ( !loading )
+ info.unload(); // TODO: extremely hacky!
+ Nsf_Emu::unload();
+}
+
+blargg_err_t Nsfe_Emu::track_info_( track_info_t* out, int track ) const
+{
+ return info.track_info_( out, track );
+}
+
+struct Nsfe_File : Gme_Info_
+{
+ Nsfe_Info info;
+
+ Nsfe_File() { set_type( gme_nsfe_type ); }
+
+ blargg_err_t load_( Data_Reader& in )
+ {
+ RETURN_ERR( info.load( in, 0 ) );
+ info.disable_playlist( false );
+ set_track_count( info.info.track_count );
+ return 0;
+ }
+
+ blargg_err_t track_info_( track_info_t* out, int track ) const
+ {
+ return info.track_info_( out, track );
+ }
+};
+
+static Music_Emu* new_nsfe_emu () { return BLARGG_NEW Nsfe_Emu ; }
+static Music_Emu* new_nsfe_file() { return BLARGG_NEW Nsfe_File; }
+
+static gme_type_t_ const gme_nsfe_type_ = { "Nintendo NES", 0, &new_nsfe_emu, &new_nsfe_file, "NSFE", 1 };
+gme_type_t const gme_nsfe_type = &gme_nsfe_type_;
+
+
+blargg_err_t Nsfe_Emu::load_( Data_Reader& in )
+{
+ if ( loading )
+ return Nsf_Emu::load_( in );
+
+ // TODO: this hacky recursion-avoidance could have subtle problems
+ loading = true;
+ blargg_err_t err = info.load( in, this );
+ loading = false;
+ disable_playlist( false );
+ return err;
+}
+
+void Nsfe_Emu::disable_playlist( bool b )
+{
+ info.disable_playlist( b );
+ set_track_count( info.info.track_count );
+}
+
+void Nsfe_Emu::clear_playlist_()
+{
+ disable_playlist();
+ Nsf_Emu::clear_playlist_();
+}
+
+blargg_err_t Nsfe_Emu::start_track_( int track )
+{
+ return Nsf_Emu::start_track_( info.remap_track( track ) );
+}
diff --git a/src/console/Nsfe_Emu.cxx b/src/console/Nsfe_Emu.cxx
deleted file mode 100644
index 2f3d5a762ed4..000000000000
--- a/src/console/Nsfe_Emu.cxx
+++ /dev/null
@@ -1,332 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Nsfe_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-#include <ctype.h>
-
-/* Copyright (C) 2005-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Nsfe_Info::Nsfe_Info() { playlist_disabled = false; }
-
-Nsfe_Info::~Nsfe_Info() { }
-
-inline void Nsfe_Info::unload()
-{
- track_name_data.clear();
- track_names.clear();
- playlist.clear();
- track_times.clear();
-}
-
-// TODO: if no playlist, treat as if there is a playlist that is just 1,2,3,4,5... ?
-void Nsfe_Info::disable_playlist( bool b )
-{
- playlist_disabled = b;
- info.track_count = playlist.size();
- if ( !info.track_count || playlist_disabled )
- info.track_count = actual_track_count_;
-}
-
-int Nsfe_Info::remap_track( int track ) const
-{
- if ( !playlist_disabled && (unsigned) track < playlist.size() )
- track = playlist [track];
- return track;
-}
-
-// Read multiple strings and separate into individual strings
-static blargg_err_t read_strs( Data_Reader& in, long size, blargg_vector<char>& chars,
- blargg_vector<const char*>& strs )
-{
- RETURN_ERR( chars.resize( size + 1 ) );
- chars [size] = 0; // in case last string doesn't have terminator
- RETURN_ERR( in.read( &chars [0], size ) );
-
- RETURN_ERR( strs.resize( 128 ) );
- int count = 0;
- for ( int i = 0; i < size; i++ )
- {
- if ( (int) strs.size() <= count )
- RETURN_ERR( strs.resize( count * 2 ) );
- strs [count++] = &chars [i];
- while ( i < size && chars [i] )
- i++;
- }
-
- return strs.resize( count );
-}
-
-// Copy in to out, where out has out_max characters allocated. Truncate to
-// out_max - 1 characters.
-static void copy_str( const char* in, char* out, int out_max )
-{
- out [out_max - 1] = 0;
- strncpy( out, in, out_max - 1 );
-}
-
-struct nsfe_info_t
-{
- byte load_addr [2];
- byte init_addr [2];
- byte play_addr [2];
- byte speed_flags;
- byte chip_flags;
- byte track_count;
- byte first_track;
- byte unused [6];
-};
-
-blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu )
-{
- int const nsfe_info_size = 16;
- assert( offsetof (nsfe_info_t,unused [6]) == nsfe_info_size );
-
- // check header
- byte signature [4];
- blargg_err_t err = in.read( signature, sizeof signature );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
- if ( memcmp( signature, "NSFE", 4 ) )
- return gme_wrong_file_type;
-
- // free previous info
- track_name_data.clear();
- track_names.clear();
- playlist.clear();
- track_times.clear();
-
- // default nsf header
- static const Nsf_Emu::header_t base_header =
- {
- {'N','E','S','M','\x1A'},// tag
- 1, // version
- 1, 1, // track count, first track
- {0,0},{0,0},{0,0}, // addresses
- "","","", // strings
- {0x1A, 0x41}, // NTSC rate
- {0,0,0,0,0,0,0,0}, // banks
- {0x20, 0x4E}, // PAL rate
- 0, 0, // flags
- {0,0,0,0} // unused
- };
- Nsf_Emu::header_t& header = info;
- header = base_header;
-
- // parse tags
- int phase = 0;
- while ( phase != 3 )
- {
- // read size and tag
- byte block_header [2] [4];
- RETURN_ERR( in.read( block_header, sizeof block_header ) );
- blargg_long size = GET_LE32( block_header [0] );
- blargg_long tag = GET_LE32( block_header [1] );
-
- //debug_printf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) );
-
- switch ( tag )
- {
- case BLARGG_4CHAR('O','F','N','I'): {
- check( phase == 0 );
- if ( size < 8 )
- return "Corrupt file";
-
- nsfe_info_t finfo;
- finfo.track_count = 1;
- finfo.first_track = 0;
-
- RETURN_ERR( in.read( &finfo, min( size, (blargg_long) nsfe_info_size ) ) );
- if ( size > nsfe_info_size )
- RETURN_ERR( in.skip( size - nsfe_info_size ) );
- phase = 1;
- info.speed_flags = finfo.speed_flags;
- info.chip_flags = finfo.chip_flags;
- info.track_count = finfo.track_count;
- this->actual_track_count_ = finfo.track_count;
- info.first_track = finfo.first_track;
- memcpy( info.load_addr, finfo.load_addr, 2 * 3 );
- break;
- }
-
- case BLARGG_4CHAR('K','N','A','B'):
- if ( size > (int) sizeof info.banks )
- return "Corrupt file";
- RETURN_ERR( in.read( info.banks, size ) );
- break;
-
- case BLARGG_4CHAR('h','t','u','a'): {
- blargg_vector<char> chars;
- blargg_vector<const char*> strs;
- RETURN_ERR( read_strs( in, size, chars, strs ) );
- int n = strs.size();
-
- if ( n > 3 )
- copy_str( strs [3], info.dumper, sizeof info.dumper );
-
- if ( n > 2 )
- copy_str( strs [2], info.copyright, sizeof info.copyright );
-
- if ( n > 1 )
- copy_str( strs [1], info.author, sizeof info.author );
-
- if ( n > 0 )
- copy_str( strs [0], info.game, sizeof info.game );
-
- break;
- }
-
- case BLARGG_4CHAR('e','m','i','t'):
- RETURN_ERR( track_times.resize( size / 4 ) );
- RETURN_ERR( in.read( track_times.begin(), track_times.size() * 4 ) );
- break;
-
- case BLARGG_4CHAR('l','b','l','t'):
- RETURN_ERR( read_strs( in, size, track_name_data, track_names ) );
- break;
-
- case BLARGG_4CHAR('t','s','l','p'):
- RETURN_ERR( playlist.resize( size ) );
- RETURN_ERR( in.read( &playlist [0], size ) );
- break;
-
- case BLARGG_4CHAR('A','T','A','D'): {
- check( phase == 1 );
- phase = 2;
- if ( !nsf_emu )
- {
- RETURN_ERR( in.skip( size ) );
- }
- else
- {
- Subset_Reader sub( &in, size ); // limit emu to nsf data
- Remaining_Reader rem( &header, Nsf_Emu::header_size, &sub );
- RETURN_ERR( nsf_emu->load( rem ) );
- check( rem.remain() == 0 );
- }
- break;
- }
-
- case BLARGG_4CHAR('D','N','E','N'):
- check( phase == 2 );
- phase = 3;
- break;
-
- default:
- // tags that can be skipped start with a lowercase character
- check( islower( (tag >> 24) & 0xFF ) );
- RETURN_ERR( in.skip( size ) );
- break;
- }
- }
-
- return 0;
-}
-
-blargg_err_t Nsfe_Info::track_info_( track_info_t* out, int track ) const
-{
- int remapped = remap_track( track );
- if ( (unsigned) remapped < track_times.size() )
- {
- long length = (int32_t) GET_LE32( track_times [remapped] );
- if ( length > 0 )
- out->length = length;
- }
- if ( (unsigned) remapped < track_names.size() )
- Gme_File::copy_field_( out->song, track_names [remapped] );
-
- GME_COPY_FIELD( info, out, game );
- GME_COPY_FIELD( info, out, author );
- GME_COPY_FIELD( info, out, copyright );
- GME_COPY_FIELD( info, out, dumper );
- return 0;
-}
-
-Nsfe_Emu::Nsfe_Emu()
-{
- loading = false;
- set_type( gme_nsfe_type );
-}
-
-Nsfe_Emu::~Nsfe_Emu() { }
-
-void Nsfe_Emu::unload()
-{
- if ( !loading )
- info.unload(); // TODO: extremely hacky!
- Nsf_Emu::unload();
-}
-
-blargg_err_t Nsfe_Emu::track_info_( track_info_t* out, int track ) const
-{
- return info.track_info_( out, track );
-}
-
-struct Nsfe_File : Gme_Info_
-{
- Nsfe_Info info;
-
- Nsfe_File() { set_type( gme_nsfe_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- RETURN_ERR( info.load( in, 0 ) );
- info.disable_playlist( false );
- set_track_count( info.info.track_count );
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int track ) const
- {
- return info.track_info_( out, track );
- }
-};
-
-static Music_Emu* new_nsfe_emu () { return BLARGG_NEW Nsfe_Emu ; }
-static Music_Emu* new_nsfe_file() { return BLARGG_NEW Nsfe_File; }
-
-static gme_type_t_ const gme_nsfe_type_ = { "Nintendo NES", 0, &new_nsfe_emu, &new_nsfe_file, "NSFE", 1 };
-gme_type_t const gme_nsfe_type = &gme_nsfe_type_;
-
-
-blargg_err_t Nsfe_Emu::load_( Data_Reader& in )
-{
- if ( loading )
- return Nsf_Emu::load_( in );
-
- // TODO: this hacky recursion-avoidance could have subtle problems
- loading = true;
- blargg_err_t err = info.load( in, this );
- loading = false;
- disable_playlist( false );
- return err;
-}
-
-void Nsfe_Emu::disable_playlist( bool b )
-{
- info.disable_playlist( b );
- set_track_count( info.info.track_count );
-}
-
-void Nsfe_Emu::clear_playlist_()
-{
- disable_playlist();
- Nsf_Emu::clear_playlist_();
-}
-
-blargg_err_t Nsfe_Emu::start_track_( int track )
-{
- return Nsf_Emu::start_track_( info.remap_track( track ) );
-}
diff --git a/src/console/Sap_Apu.cc b/src/console/Sap_Apu.cc
new file mode 100644
index 000000000000..064f487c72c0
--- /dev/null
+++ b/src/console/Sap_Apu.cc
@@ -0,0 +1,334 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Sap_Apu.h"
+
+#include <string.h>
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+int const max_frequency = 12000; // pure waves above this frequency are silenced
+
+static void gen_poly( blargg_ulong mask, int count, byte* out )
+{
+ blargg_ulong n = 1;
+ do
+ {
+ int bits = 0;
+ int b = 0;
+ do
+ {
+ // implemented using "Galios configuration"
+ bits |= (n & 1) << b;
+ n = (n >> 1) ^ (mask & -(n & 1));
+ }
+ while ( b++ < 7 );
+ *out++ = bits;
+ }
+ while ( --count );
+}
+
+// poly5
+int const poly5_len = (1 << 5) - 1;
+blargg_ulong const poly5_mask = (1UL << poly5_len) - 1;
+blargg_ulong const poly5 = 0x167C6EA1;
+
+inline blargg_ulong run_poly5( blargg_ulong in, int shift )
+{
+ return (in << shift & poly5_mask) | (in >> (poly5_len - shift));
+}
+
+#define POLY_MASK( width, tap1, tap2 ) \
+ ((1UL << (width - 1 - tap1)) | (1UL << (width - 1 - tap2)))
+
+Sap_Apu_Impl::Sap_Apu_Impl()
+{
+ gen_poly( POLY_MASK( 4, 1, 0 ), sizeof poly4, poly4 );
+ gen_poly( POLY_MASK( 9, 5, 0 ), sizeof poly9, poly9 );
+ gen_poly( POLY_MASK( 17, 5, 0 ), sizeof poly17, poly17 );
+
+ if ( 0 ) // comment out to recauculate poly5 constant
+ {
+ byte poly5 [4];
+ gen_poly( POLY_MASK( 5, 2, 0 ), sizeof poly5, poly5 );
+ blargg_ulong n = poly5 [3] * 0x1000000L + poly5 [2] * 0x10000L +
+ poly5 [1] * 0x100L + poly5 [0];
+ blargg_ulong rev = n & 1;
+ for ( int i = 1; i < poly5_len; i++ )
+ rev |= (n >> i & 1) << (poly5_len - i);
+ debug_printf( "poly5: 0x%08lX\n", rev );
+ }
+}
+
+Sap_Apu::Sap_Apu()
+{
+ impl = 0;
+ for ( int i = 0; i < osc_count; i++ )
+ osc_output( i, 0 );
+}
+
+void Sap_Apu::reset( Sap_Apu_Impl* new_impl )
+{
+ impl = new_impl;
+ last_time = 0;
+ poly5_pos = 0;
+ poly4_pos = 0;
+ polym_pos = 0;
+ control = 0;
+
+ for ( int i = 0; i < osc_count; i++ )
+ memset( &oscs [i], 0, offsetof (osc_t,output) );
+}
+
+inline void Sap_Apu::calc_periods()
+{
+ // 15/64 kHz clock
+ int divider = 28;
+ if ( this->control & 1 )
+ divider = 114;
+
+ for ( int i = 0; i < osc_count; i++ )
+ {
+ osc_t* const osc = &oscs [i];
+
+ int const osc_reload = osc->regs [0]; // cache
+ blargg_long period = (osc_reload + 1) * divider;
+ static byte const fast_bits [osc_count] = { 1 << 6, 1 << 4, 1 << 5, 1 << 3 };
+ if ( this->control & fast_bits [i] )
+ {
+ period = osc_reload + 4;
+ if ( i & 1 )
+ {
+ period = osc_reload * 0x100L + osc [-1].regs [0] + 7;
+ if ( !(this->control & fast_bits [i - 1]) )
+ period = (period - 6) * divider;
+
+ if ( (osc [-1].regs [1] & 0x1F) > 0x10 )
+ debug_printf( "Use of slave channel in 16-bit mode not supported\n" );
+ }
+ }
+ osc->period = period;
+ }
+}
+
+void Sap_Apu::run_until( blip_time_t end_time )
+{
+ calc_periods();
+ Sap_Apu_Impl* const impl = this->impl; // cache
+
+ // 17/9-bit poly selection
+ byte const* polym = impl->poly17;
+ int polym_len = poly17_len;
+ if ( this->control & 0x80 )
+ {
+ polym_len = poly9_len;
+ polym = impl->poly9;
+ }
+ polym_pos %= polym_len;
+
+ for ( int i = 0; i < osc_count; i++ )
+ {
+ osc_t* const osc = &oscs [i];
+ blip_time_t time = last_time + osc->delay;
+ blip_time_t const period = osc->period;
+
+ // output
+ Blip_Buffer* output = osc->output;
+ if ( output )
+ {
+ output->set_modified();
+
+ int const osc_control = osc->regs [1]; // cache
+ int volume = (osc_control & 0x0F) * 2;
+ if ( !volume || osc_control & 0x10 || // silent, DAC mode, or inaudible frequency
+ ((osc_control & 0xA0) == 0xA0 && period < 1789773 / 2 / max_frequency) )
+ {
+ if ( !(osc_control & 0x10) )
+ volume >>= 1; // inaudible frequency = half volume
+
+ int delta = volume - osc->last_amp;
+ if ( delta )
+ {
+ osc->last_amp = volume;
+ impl->synth.offset( last_time, delta, output );
+ }
+
+ // TODO: doesn't maintain high pass flip-flop (very minor issue)
+ }
+ else
+ {
+ // high pass
+ static byte const hipass_bits [osc_count] = { 1 << 2, 1 << 1, 0, 0 };
+ blip_time_t period2 = 0; // unused if no high pass
+ blip_time_t time2 = end_time;
+ if ( this->control & hipass_bits [i] )
+ {
+ period2 = osc [2].period;
+ time2 = last_time + osc [2].delay;
+ if ( osc->invert )
+ {
+ // trick inner wave loop into inverting output
+ osc->last_amp -= volume;
+ volume = -volume;
+ }
+ }
+
+ if ( time < end_time || time2 < end_time )
+ {
+ // poly source
+ static byte const poly1 [] = { 0x55, 0x55 }; // square wave
+ byte const* poly = poly1;
+ int poly_len = 8 * sizeof poly1; // can be just 2 bits, but this is faster
+ int poly_pos = osc->phase & 1;
+ int poly_inc = 1;
+ if ( !(osc_control & 0x20) )
+ {
+ poly = polym;
+ poly_len = polym_len;
+ poly_pos = polym_pos;
+ if ( osc_control & 0x40 )
+ {
+ poly = impl->poly4;
+ poly_len = poly4_len;
+ poly_pos = poly4_pos;
+ }
+ poly_inc = period % poly_len;
+ poly_pos = (poly_pos + osc->delay) % poly_len;
+ }
+ poly_inc -= poly_len; // allows more optimized inner loop below
+
+ // square/poly5 wave
+ blargg_ulong wave = poly5;
+ check( poly5 & 1 ); // low bit is set for pure wave
+ int poly5_inc = 0;
+ if ( !(osc_control & 0x80) )
+ {
+ wave = run_poly5( wave, (osc->delay + poly5_pos) % poly5_len );
+ poly5_inc = period % poly5_len;
+ }
+
+ // Run wave and high pass interleved with each catching up to the other.
+ // Disabled high pass has no performance effect since inner wave loop
+ // makes no compromise for high pass, and only runs once in that case.
+ int osc_last_amp = osc->last_amp;
+ do
+ {
+ // run high pass
+ if ( time2 < time )
+ {
+ int delta = -osc_last_amp;
+ if ( volume < 0 )
+ delta += volume;
+ if ( delta )
+ {
+ osc_last_amp += delta - volume;
+ volume = -volume;
+ impl->synth.offset( time2, delta, output );
+ }
+ }
+ while ( time2 <= time ) // must advance *past* time to avoid hang
+ time2 += period2;
+
+ // run wave
+ blip_time_t end = end_time;
+ if ( end > time2 )
+ end = time2;
+ while ( time < end )
+ {
+ if ( wave & 1 )
+ {
+ int amp = volume & -(poly [poly_pos >> 3] >> (poly_pos & 7) & 1);
+ if ( (poly_pos += poly_inc) < 0 )
+ poly_pos += poly_len;
+ int delta = amp - osc_last_amp;
+ if ( delta )
+ {
+ osc_last_amp = amp;
+ impl->synth.offset( time, delta, output );
+ }
+ }
+ wave = run_poly5( wave, poly5_inc );
+ time += period;
+ }
+ }
+ while ( time < end_time || time2 < end_time );
+
+ osc->phase = poly_pos;
+ osc->last_amp = osc_last_amp;
+ }
+
+ osc->invert = 0;
+ if ( volume < 0 )
+ {
+ // undo inversion trickery
+ osc->last_amp -= volume;
+ osc->invert = 1;
+ }
+ }
+ }
+
+ // maintain divider
+ blip_time_t remain = end_time - time;
+ if ( remain > 0 )
+ {
+ blargg_long count = (remain + period - 1) / period;
+ osc->phase ^= count;
+ time += count * period;
+ }
+ osc->delay = time - end_time;
+ }
+
+ // advance polies
+ blip_time_t duration = end_time - last_time;
+ last_time = end_time;
+ poly4_pos = (poly4_pos + duration) % poly4_len;
+ poly5_pos = (poly5_pos + duration) % poly5_len;
+ polym_pos += duration; // will get %'d on next call
+}
+
+void Sap_Apu::write_data( blip_time_t time, unsigned addr, int data )
+{
+ run_until( time );
+ int i = (addr ^ 0xD200) >> 1;
+ if ( i < osc_count )
+ {
+ oscs [i].regs [addr & 1] = data;
+ }
+ else if ( addr == 0xD208 )
+ {
+ control = data;
+ }
+ else if ( addr == 0xD209 )
+ {
+ oscs [0].delay = 0;
+ oscs [1].delay = 0;
+ oscs [2].delay = 0;
+ oscs [3].delay = 0;
+ }
+ /*
+ // TODO: are polynomials reset in this case?
+ else if ( addr == 0xD20F )
+ {
+ if ( (data & 3) == 0 )
+ polym_pos = 0;
+ }
+ */
+}
+
+void Sap_Apu::end_frame( blip_time_t end_time )
+{
+ if ( end_time > last_time )
+ run_until( end_time );
+
+ last_time -= end_time;
+}
diff --git a/src/console/Sap_Apu.cxx b/src/console/Sap_Apu.cxx
deleted file mode 100644
index 064f487c72c0..000000000000
--- a/src/console/Sap_Apu.cxx
+++ /dev/null
@@ -1,334 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Sap_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const max_frequency = 12000; // pure waves above this frequency are silenced
-
-static void gen_poly( blargg_ulong mask, int count, byte* out )
-{
- blargg_ulong n = 1;
- do
- {
- int bits = 0;
- int b = 0;
- do
- {
- // implemented using "Galios configuration"
- bits |= (n & 1) << b;
- n = (n >> 1) ^ (mask & -(n & 1));
- }
- while ( b++ < 7 );
- *out++ = bits;
- }
- while ( --count );
-}
-
-// poly5
-int const poly5_len = (1 << 5) - 1;
-blargg_ulong const poly5_mask = (1UL << poly5_len) - 1;
-blargg_ulong const poly5 = 0x167C6EA1;
-
-inline blargg_ulong run_poly5( blargg_ulong in, int shift )
-{
- return (in << shift & poly5_mask) | (in >> (poly5_len - shift));
-}
-
-#define POLY_MASK( width, tap1, tap2 ) \
- ((1UL << (width - 1 - tap1)) | (1UL << (width - 1 - tap2)))
-
-Sap_Apu_Impl::Sap_Apu_Impl()
-{
- gen_poly( POLY_MASK( 4, 1, 0 ), sizeof poly4, poly4 );
- gen_poly( POLY_MASK( 9, 5, 0 ), sizeof poly9, poly9 );
- gen_poly( POLY_MASK( 17, 5, 0 ), sizeof poly17, poly17 );
-
- if ( 0 ) // comment out to recauculate poly5 constant
- {
- byte poly5 [4];
- gen_poly( POLY_MASK( 5, 2, 0 ), sizeof poly5, poly5 );
- blargg_ulong n = poly5 [3] * 0x1000000L + poly5 [2] * 0x10000L +
- poly5 [1] * 0x100L + poly5 [0];
- blargg_ulong rev = n & 1;
- for ( int i = 1; i < poly5_len; i++ )
- rev |= (n >> i & 1) << (poly5_len - i);
- debug_printf( "poly5: 0x%08lX\n", rev );
- }
-}
-
-Sap_Apu::Sap_Apu()
-{
- impl = 0;
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, 0 );
-}
-
-void Sap_Apu::reset( Sap_Apu_Impl* new_impl )
-{
- impl = new_impl;
- last_time = 0;
- poly5_pos = 0;
- poly4_pos = 0;
- polym_pos = 0;
- control = 0;
-
- for ( int i = 0; i < osc_count; i++ )
- memset( &oscs [i], 0, offsetof (osc_t,output) );
-}
-
-inline void Sap_Apu::calc_periods()
-{
- // 15/64 kHz clock
- int divider = 28;
- if ( this->control & 1 )
- divider = 114;
-
- for ( int i = 0; i < osc_count; i++ )
- {
- osc_t* const osc = &oscs [i];
-
- int const osc_reload = osc->regs [0]; // cache
- blargg_long period = (osc_reload + 1) * divider;
- static byte const fast_bits [osc_count] = { 1 << 6, 1 << 4, 1 << 5, 1 << 3 };
- if ( this->control & fast_bits [i] )
- {
- period = osc_reload + 4;
- if ( i & 1 )
- {
- period = osc_reload * 0x100L + osc [-1].regs [0] + 7;
- if ( !(this->control & fast_bits [i - 1]) )
- period = (period - 6) * divider;
-
- if ( (osc [-1].regs [1] & 0x1F) > 0x10 )
- debug_printf( "Use of slave channel in 16-bit mode not supported\n" );
- }
- }
- osc->period = period;
- }
-}
-
-void Sap_Apu::run_until( blip_time_t end_time )
-{
- calc_periods();
- Sap_Apu_Impl* const impl = this->impl; // cache
-
- // 17/9-bit poly selection
- byte const* polym = impl->poly17;
- int polym_len = poly17_len;
- if ( this->control & 0x80 )
- {
- polym_len = poly9_len;
- polym = impl->poly9;
- }
- polym_pos %= polym_len;
-
- for ( int i = 0; i < osc_count; i++ )
- {
- osc_t* const osc = &oscs [i];
- blip_time_t time = last_time + osc->delay;
- blip_time_t const period = osc->period;
-
- // output
- Blip_Buffer* output = osc->output;
- if ( output )
- {
- output->set_modified();
-
- int const osc_control = osc->regs [1]; // cache
- int volume = (osc_control & 0x0F) * 2;
- if ( !volume || osc_control & 0x10 || // silent, DAC mode, or inaudible frequency
- ((osc_control & 0xA0) == 0xA0 && period < 1789773 / 2 / max_frequency) )
- {
- if ( !(osc_control & 0x10) )
- volume >>= 1; // inaudible frequency = half volume
-
- int delta = volume - osc->last_amp;
- if ( delta )
- {
- osc->last_amp = volume;
- impl->synth.offset( last_time, delta, output );
- }
-
- // TODO: doesn't maintain high pass flip-flop (very minor issue)
- }
- else
- {
- // high pass
- static byte const hipass_bits [osc_count] = { 1 << 2, 1 << 1, 0, 0 };
- blip_time_t period2 = 0; // unused if no high pass
- blip_time_t time2 = end_time;
- if ( this->control & hipass_bits [i] )
- {
- period2 = osc [2].period;
- time2 = last_time + osc [2].delay;
- if ( osc->invert )
- {
- // trick inner wave loop into inverting output
- osc->last_amp -= volume;
- volume = -volume;
- }
- }
-
- if ( time < end_time || time2 < end_time )
- {
- // poly source
- static byte const poly1 [] = { 0x55, 0x55 }; // square wave
- byte const* poly = poly1;
- int poly_len = 8 * sizeof poly1; // can be just 2 bits, but this is faster
- int poly_pos = osc->phase & 1;
- int poly_inc = 1;
- if ( !(osc_control & 0x20) )
- {
- poly = polym;
- poly_len = polym_len;
- poly_pos = polym_pos;
- if ( osc_control & 0x40 )
- {
- poly = impl->poly4;
- poly_len = poly4_len;
- poly_pos = poly4_pos;
- }
- poly_inc = period % poly_len;
- poly_pos = (poly_pos + osc->delay) % poly_len;
- }
- poly_inc -= poly_len; // allows more optimized inner loop below
-
- // square/poly5 wave
- blargg_ulong wave = poly5;
- check( poly5 & 1 ); // low bit is set for pure wave
- int poly5_inc = 0;
- if ( !(osc_control & 0x80) )
- {
- wave = run_poly5( wave, (osc->delay + poly5_pos) % poly5_len );
- poly5_inc = period % poly5_len;
- }
-
- // Run wave and high pass interleved with each catching up to the other.
- // Disabled high pass has no performance effect since inner wave loop
- // makes no compromise for high pass, and only runs once in that case.
- int osc_last_amp = osc->last_amp;
- do
- {
- // run high pass
- if ( time2 < time )
- {
- int delta = -osc_last_amp;
- if ( volume < 0 )
- delta += volume;
- if ( delta )
- {
- osc_last_amp += delta - volume;
- volume = -volume;
- impl->synth.offset( time2, delta, output );
- }
- }
- while ( time2 <= time ) // must advance *past* time to avoid hang
- time2 += period2;
-
- // run wave
- blip_time_t end = end_time;
- if ( end > time2 )
- end = time2;
- while ( time < end )
- {
- if ( wave & 1 )
- {
- int amp = volume & -(poly [poly_pos >> 3] >> (poly_pos & 7) & 1);
- if ( (poly_pos += poly_inc) < 0 )
- poly_pos += poly_len;
- int delta = amp - osc_last_amp;
- if ( delta )
- {
- osc_last_amp = amp;
- impl->synth.offset( time, delta, output );
- }
- }
- wave = run_poly5( wave, poly5_inc );
- time += period;
- }
- }
- while ( time < end_time || time2 < end_time );
-
- osc->phase = poly_pos;
- osc->last_amp = osc_last_amp;
- }
-
- osc->invert = 0;
- if ( volume < 0 )
- {
- // undo inversion trickery
- osc->last_amp -= volume;
- osc->invert = 1;
- }
- }
- }
-
- // maintain divider
- blip_time_t remain = end_time - time;
- if ( remain > 0 )
- {
- blargg_long count = (remain + period - 1) / period;
- osc->phase ^= count;
- time += count * period;
- }
- osc->delay = time - end_time;
- }
-
- // advance polies
- blip_time_t duration = end_time - last_time;
- last_time = end_time;
- poly4_pos = (poly4_pos + duration) % poly4_len;
- poly5_pos = (poly5_pos + duration) % poly5_len;
- polym_pos += duration; // will get %'d on next call
-}
-
-void Sap_Apu::write_data( blip_time_t time, unsigned addr, int data )
-{
- run_until( time );
- int i = (addr ^ 0xD200) >> 1;
- if ( i < osc_count )
- {
- oscs [i].regs [addr & 1] = data;
- }
- else if ( addr == 0xD208 )
- {
- control = data;
- }
- else if ( addr == 0xD209 )
- {
- oscs [0].delay = 0;
- oscs [1].delay = 0;
- oscs [2].delay = 0;
- oscs [3].delay = 0;
- }
- /*
- // TODO: are polynomials reset in this case?
- else if ( addr == 0xD20F )
- {
- if ( (data & 3) == 0 )
- polym_pos = 0;
- }
- */
-}
-
-void Sap_Apu::end_frame( blip_time_t end_time )
-{
- if ( end_time > last_time )
- run_until( end_time );
-
- last_time -= end_time;
-}
diff --git a/src/console/Sap_Cpu.cc b/src/console/Sap_Cpu.cc
new file mode 100644
index 000000000000..7528de1b36a9
--- /dev/null
+++ b/src/console/Sap_Cpu.cc
@@ -0,0 +1,1009 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Sap_Cpu.h"
+
+#include <limits.h>
+#include "blargg_endian.h"
+
+//#include "nes_cpu_log.h"
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#define FLUSH_TIME() (void) (s.time = s_time)
+#define CACHE_TIME() (void) (s_time = s.time)
+
+#include "sap_cpu_io.h"
+
+#ifndef CPU_DONE
+ #define CPU_DONE( cpu, time, result_out ) { result_out = -1; }
+#endif
+
+#include "blargg_source.h"
+
+int const st_n = 0x80;
+int const st_v = 0x40;
+int const st_r = 0x20;
+int const st_b = 0x10;
+int const st_d = 0x08;
+int const st_i = 0x04;
+int const st_z = 0x02;
+int const st_c = 0x01;
+
+void Sap_Cpu::reset( void* new_mem )
+{
+ check( state == &state_ );
+ state = &state_;
+ mem = (uint8_t*) new_mem;
+ r.status = st_i;
+ r.sp = 0xFF;
+ r.pc = 0;
+ r.a = 0;
+ r.x = 0;
+ r.y = 0;
+ state_.time = 0;
+ state_.base = 0;
+ irq_time_ = future_sap_time;
+ end_time_ = future_sap_time;
+}
+
+#define TIME (s_time + s.base)
+#define READ( addr ) CPU_READ( this, (addr), TIME )
+#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), TIME );}
+#define READ_LOW( addr ) (mem [int (addr)])
+#define WRITE_LOW( addr, data ) (void) (READ_LOW( addr ) = (data))
+#define READ_PROG( addr ) (READ_LOW( addr ))
+
+#define SET_SP( v ) (sp = ((v) + 1) | 0x100)
+#define GET_SP() ((sp - 1) & 0xFF)
+#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
+
+// even on x86, using short and unsigned char was slower
+typedef int fint16;
+typedef unsigned fuint16;
+typedef unsigned fuint8;
+typedef blargg_long fint32;
+
+bool Sap_Cpu::run( sap_time_t end_time )
+{
+ bool illegal_encountered = false;
+ set_end_time( end_time );
+ state_t s = this->state_;
+ this->state = &s;
+ fint32 s_time = s.time;
+ uint8_t* const mem = this->mem; // cache
+
+ // registers
+ fuint16 pc = r.pc;
+ fuint8 a = r.a;
+ fuint8 x = r.x;
+ fuint8 y = r.y;
+ fuint16 sp;
+ SET_SP( r.sp );
+
+ // status flags
+ #define IS_NEG (nz & 0x8080)
+
+ #define CALC_STATUS( out ) do {\
+ out = status & (st_v | st_d | st_i);\
+ out |= ((nz >> 8) | nz) & st_n;\
+ out |= c >> 8 & st_c;\
+ if ( !(nz & 0xFF) ) out |= st_z;\
+ } while ( 0 )
+
+ #define SET_STATUS( in ) do {\
+ status = in & (st_v | st_d | st_i);\
+ nz = in << 8;\
+ c = nz;\
+ nz |= ~in & st_z;\
+ } while ( 0 )
+
+ fuint8 status;
+ fuint16 c; // carry set if (c & 0x100) != 0
+ fuint16 nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
+ {
+ fuint8 temp = r.status;
+ SET_STATUS( temp );
+ }
+
+ goto loop;
+dec_clock_loop:
+ s_time--;
+loop:
+
+ #ifndef NDEBUG
+ {
+ sap_time_t correct = end_time_;
+ if ( !(status & st_i) && correct > irq_time_ )
+ correct = irq_time_;
+ check( s.base == correct );
+ }
+ #endif
+
+ check( (unsigned) GET_SP() < 0x100 );
+ check( (unsigned) a < 0x100 );
+ check( (unsigned) x < 0x100 );
+ check( (unsigned) y < 0x100 );
+
+ fuint8 opcode = mem [pc];
+ pc++;
+ uint8_t const* instr = mem + pc;
+
+ static uint8_t const clock_table [256] =
+ {// 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,// 0
+ 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 1
+ 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,// 2
+ 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 3
+ 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,// 4
+ 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 5
+ 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,// 6
+ 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 7
+ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// 8
+ 3,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,// 9
+ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// A
+ 3,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,// B
+ 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// C
+ 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// D
+ 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// E
+ 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7 // F
+ }; // 0x00 was 7
+
+ fuint16 data;
+ data = clock_table [opcode];
+ if ( (s_time += data) >= 0 )
+ goto possibly_out_of_time;
+almost_out_of_time:
+
+ data = *instr;
+
+ #ifdef NES_CPU_LOG_H
+ nes_cpu_log( "cpu_log", pc - 1, opcode, instr [0], instr [1] );
+ #endif
+
+ switch ( opcode )
+ {
+possibly_out_of_time:
+ if ( s_time < (int) data )
+ goto almost_out_of_time;
+ s_time -= data;
+ goto out_of_time;
+
+// Macros
+
+#define GET_MSB() (instr [1])
+#define ADD_PAGE() (pc++, data += 0x100 * GET_MSB())
+#define GET_ADDR() GET_LE16( instr )
+
+#define NO_PAGE_CROSSING( lsb )
+#define HANDLE_PAGE_CROSSING( lsb ) s_time += (lsb) >> 8;
+
+#define INC_DEC_XY( reg, n ) reg = uint8_t (nz = reg + n); goto loop;
+
+#define IND_Y( cross, out ) {\
+ fuint16 temp = READ_LOW( data ) + y;\
+ out = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
+ cross( temp );\
+ }
+
+#define IND_X( out ) {\
+ fuint16 temp = data + x;\
+ out = 0x100 * READ_LOW( uint8_t (temp + 1) ) + READ_LOW( uint8_t (temp) );\
+ }
+
+#define ARITH_ADDR_MODES( op )\
+case op - 0x04: /* (ind,x) */\
+ IND_X( data )\
+ goto ptr##op;\
+case op + 0x0C: /* (ind),y */\
+ IND_Y( HANDLE_PAGE_CROSSING, data )\
+ goto ptr##op;\
+case op + 0x10: /* zp,X */\
+ data = uint8_t (data + x);\
+case op + 0x00: /* zp */\
+ data = READ_LOW( data );\
+ goto imm##op;\
+case op + 0x14: /* abs,Y */\
+ data += y;\
+ goto ind##op;\
+case op + 0x18: /* abs,X */\
+ data += x;\
+ind##op:\
+ HANDLE_PAGE_CROSSING( data );\
+case op + 0x08: /* abs */\
+ ADD_PAGE();\
+ptr##op:\
+ FLUSH_TIME();\
+ data = READ( data );\
+ CACHE_TIME();\
+case op + 0x04: /* imm */\
+imm##op:
+
+// TODO: more efficient way to handle negative branch that wraps PC around
+#define BRANCH( cond )\
+{\
+ fint16 offset = (int8_t) data;\
+ fuint16 extra_clock = (++pc & 0xFF) + offset;\
+ if ( !(cond) ) goto dec_clock_loop;\
+ pc += offset;\
+ s_time += extra_clock >> 8 & 1;\
+ goto loop;\
+}
+
+// Often-Used
+
+ case 0xB5: // LDA zp,x
+ a = nz = READ_LOW( uint8_t (data + x) );
+ pc++;
+ goto loop;
+
+ case 0xA5: // LDA zp
+ a = nz = READ_LOW( data );
+ pc++;
+ goto loop;
+
+ case 0xD0: // BNE
+ BRANCH( (uint8_t) nz );
+
+ case 0x20: { // JSR
+ fuint16 temp = pc + 1;
+ pc = GET_ADDR();
+ WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
+ sp = (sp - 2) | 0x100;
+ WRITE_LOW( sp, temp );
+ goto loop;
+ }
+
+ case 0x4C: // JMP abs
+ pc = GET_ADDR();
+ goto loop;
+
+ case 0xE8: // INX
+ INC_DEC_XY( x, 1 )
+
+ case 0x10: // BPL
+ BRANCH( !IS_NEG )
+
+ ARITH_ADDR_MODES( 0xC5 ) // CMP
+ nz = a - data;
+ pc++;
+ c = ~nz;
+ nz &= 0xFF;
+ goto loop;
+
+ case 0x30: // BMI
+ BRANCH( IS_NEG )
+
+ case 0xF0: // BEQ
+ BRANCH( !(uint8_t) nz );
+
+ case 0x95: // STA zp,x
+ data = uint8_t (data + x);
+ case 0x85: // STA zp
+ pc++;
+ WRITE_LOW( data, a );
+ goto loop;
+
+ case 0xC8: // INY
+ INC_DEC_XY( y, 1 )
+
+ case 0xA8: // TAY
+ y = a;
+ nz = a;
+ goto loop;
+
+ case 0x98: // TYA
+ a = y;
+ nz = y;
+ goto loop;
+
+ case 0xAD:{// LDA abs
+ unsigned addr = GET_ADDR();
+ pc += 2;
+ nz = READ( addr );
+ a = nz;
+ goto loop;
+ }
+
+ case 0x60: // RTS
+ pc = 1 + READ_LOW( sp );
+ pc += 0x100 * READ_LOW( 0x100 | (sp - 0xFF) );
+ sp = (sp - 0xFE) | 0x100;
+ goto loop;
+
+ {
+ fuint16 addr;
+
+ case 0x99: // STA abs,Y
+ addr = y + GET_ADDR();
+ pc += 2;
+ if ( addr <= 0x7FF )
+ {
+ WRITE_LOW( addr, a );
+ goto loop;
+ }
+ goto sta_ptr;
+
+ case 0x8D: // STA abs
+ addr = GET_ADDR();
+ pc += 2;
+ if ( addr <= 0x7FF )
+ {
+ WRITE_LOW( addr, a );
+ goto loop;
+ }
+ goto sta_ptr;
+
+ case 0x9D: // STA abs,X (slightly more common than STA abs)
+ addr = x + GET_ADDR();
+ pc += 2;
+ if ( addr <= 0x7FF )
+ {
+ WRITE_LOW( addr, a );
+ goto loop;
+ }
+ sta_ptr:
+ FLUSH_TIME();
+ WRITE( addr, a );
+ CACHE_TIME();
+ goto loop;
+
+ case 0x91: // STA (ind),Y
+ IND_Y( NO_PAGE_CROSSING, addr )
+ pc++;
+ goto sta_ptr;
+
+ case 0x81: // STA (ind,X)
+ IND_X( addr )
+ pc++;
+ goto sta_ptr;
+
+ }
+
+ case 0xA9: // LDA #imm
+ pc++;
+ a = data;
+ nz = data;
+ goto loop;
+
+ // common read instructions
+ {
+ fuint16 addr;
+
+ case 0xA1: // LDA (ind,X)
+ IND_X( addr )
+ pc++;
+ goto a_nz_read_addr;
+
+ case 0xB1:// LDA (ind),Y
+ addr = READ_LOW( data ) + y;
+ HANDLE_PAGE_CROSSING( addr );
+ addr += 0x100 * READ_LOW( (uint8_t) (data + 1) );
+ pc++;
+ a = nz = READ_PROG( addr );
+ if ( (addr ^ 0x8000) <= 0x9FFF )
+ goto loop;
+ goto a_nz_read_addr;
+
+ case 0xB9: // LDA abs,Y
+ HANDLE_PAGE_CROSSING( data + y );
+ addr = GET_ADDR() + y;
+ pc += 2;
+ a = nz = READ_PROG( addr );
+ if ( (addr ^ 0x8000) <= 0x9FFF )
+ goto loop;
+ goto a_nz_read_addr;
+
+ case 0xBD: // LDA abs,X
+ HANDLE_PAGE_CROSSING( data + x );
+ addr = GET_ADDR() + x;
+ pc += 2;
+ a = nz = READ_PROG( addr );
+ if ( (addr ^ 0x8000) <= 0x9FFF )
+ goto loop;
+ a_nz_read_addr:
+ FLUSH_TIME();
+ a = nz = READ( addr );
+ CACHE_TIME();
+ goto loop;
+
+ }
+
+// Branch
+
+ case 0x50: // BVC
+ BRANCH( !(status & st_v) )
+
+ case 0x70: // BVS
+ BRANCH( status & st_v )
+
+ case 0xB0: // BCS
+ BRANCH( c & 0x100 )
+
+ case 0x90: // BCC
+ BRANCH( !(c & 0x100) )
+
+// Load/store
+
+ case 0x94: // STY zp,x
+ data = uint8_t (data + x);
+ case 0x84: // STY zp
+ pc++;
+ WRITE_LOW( data, y );
+ goto loop;
+
+ case 0x96: // STX zp,y
+ data = uint8_t (data + y);
+ case 0x86: // STX zp
+ pc++;
+ WRITE_LOW( data, x );
+ goto loop;
+
+ case 0xB6: // LDX zp,y
+ data = uint8_t (data + y);
+ case 0xA6: // LDX zp
+ data = READ_LOW( data );
+ case 0xA2: // LDX #imm
+ pc++;
+ x = data;
+ nz = data;
+ goto loop;
+
+ case 0xB4: // LDY zp,x
+ data = uint8_t (data + x);
+ case 0xA4: // LDY zp
+ data = READ_LOW( data );
+ case 0xA0: // LDY #imm
+ pc++;
+ y = data;
+ nz = data;
+ goto loop;
+
+ case 0xBC: // LDY abs,X
+ data += x;
+ HANDLE_PAGE_CROSSING( data );
+ case 0xAC:{// LDY abs
+ unsigned addr = data + 0x100 * GET_MSB();
+ pc += 2;
+ FLUSH_TIME();
+ y = nz = READ( addr );
+ CACHE_TIME();
+ goto loop;
+ }
+
+ case 0xBE: // LDX abs,y
+ data += y;
+ HANDLE_PAGE_CROSSING( data );
+ case 0xAE:{// LDX abs
+ unsigned addr = data + 0x100 * GET_MSB();
+ pc += 2;
+ FLUSH_TIME();
+ x = nz = READ( addr );
+ CACHE_TIME();
+ goto loop;
+ }
+
+ {
+ fuint8 temp;
+ case 0x8C: // STY abs
+ temp = y;
+ goto store_abs;
+
+ case 0x8E: // STX abs
+ temp = x;
+ store_abs:
+ unsigned addr = GET_ADDR();
+ pc += 2;
+ if ( addr <= 0x7FF )
+ {
+ WRITE_LOW( addr, temp );
+ goto loop;
+ }
+ FLUSH_TIME();
+ WRITE( addr, temp );
+ CACHE_TIME();
+ goto loop;
+ }
+
+// Compare
+
+ case 0xEC:{// CPX abs
+ unsigned addr = GET_ADDR();
+ pc++;
+ FLUSH_TIME();
+ data = READ( addr );
+ CACHE_TIME();
+ goto cpx_data;
+ }
+
+ case 0xE4: // CPX zp
+ data = READ_LOW( data );
+ case 0xE0: // CPX #imm
+ cpx_data:
+ nz = x - data;
+ pc++;
+ c = ~nz;
+ nz &= 0xFF;
+ goto loop;
+
+ case 0xCC:{// CPY abs
+ unsigned addr = GET_ADDR();
+ pc++;
+ FLUSH_TIME();
+ data = READ( addr );
+ CACHE_TIME();
+ goto cpy_data;
+ }
+
+ case 0xC4: // CPY zp
+ data = READ_LOW( data );
+ case 0xC0: // CPY #imm
+ cpy_data:
+ nz = y - data;
+ pc++;
+ c = ~nz;
+ nz &= 0xFF;
+ goto loop;
+
+// Logical
+
+ ARITH_ADDR_MODES( 0x25 ) // AND
+ nz = (a &= data);
+ pc++;
+ goto loop;
+
+ ARITH_ADDR_MODES( 0x45 ) // EOR
+ nz = (a ^= data);
+ pc++;
+ goto loop;
+
+ ARITH_ADDR_MODES( 0x05 ) // ORA
+ nz = (a |= data);
+ pc++;
+ goto loop;
+
+ case 0x2C:{// BIT abs
+ unsigned addr = GET_ADDR();
+ pc += 2;
+ status &= ~st_v;
+ nz = READ( addr );
+ status |= nz & st_v;
+ if ( a & nz )
+ goto loop;
+ nz <<= 8; // result must be zero, even if N bit is set
+ goto loop;
+ }
+
+ case 0x24: // BIT zp
+ nz = READ_LOW( data );
+ pc++;
+ status &= ~st_v;
+ status |= nz & st_v;
+ if ( a & nz )
+ goto loop;
+ nz <<= 8; // result must be zero, even if N bit is set
+ goto loop;
+
+// Add/subtract
+
+ ARITH_ADDR_MODES( 0xE5 ) // SBC
+ case 0xEB: // unofficial equivalent
+ data ^= 0xFF;
+ goto adc_imm;
+
+ ARITH_ADDR_MODES( 0x65 ) // ADC
+ adc_imm: {
+ check( !(status & st_d) );
+ fint16 carry = c >> 8 & 1;
+ fint16 ov = (a ^ 0x80) + carry + (int8_t) data; // sign-extend
+ status &= ~st_v;
+ status |= ov >> 2 & 0x40;
+ c = nz = a + data + carry;
+ pc++;
+ a = (uint8_t) nz;
+ goto loop;
+ }
+
+// Shift/rotate
+
+ case 0x4A: // LSR A
+ c = 0;
+ case 0x6A: // ROR A
+ nz = c >> 1 & 0x80;
+ c = a << 8;
+ nz |= a >> 1;
+ a = nz;
+ goto loop;
+
+ case 0x0A: // ASL A
+ nz = a << 1;
+ c = nz;
+ a = (uint8_t) nz;
+ goto loop;
+
+ case 0x2A: { // ROL A
+ nz = a << 1;
+ fint16 temp = c >> 8 & 1;
+ c = nz;
+ nz |= temp;
+ a = (uint8_t) nz;
+ goto loop;
+ }
+
+ case 0x5E: // LSR abs,X
+ data += x;
+ case 0x4E: // LSR abs
+ c = 0;
+ case 0x6E: // ROR abs
+ ror_abs: {
+ ADD_PAGE();
+ FLUSH_TIME();
+ int temp = READ( data );
+ nz = (c >> 1 & 0x80) | (temp >> 1);
+ c = temp << 8;
+ goto rotate_common;
+ }
+
+ case 0x3E: // ROL abs,X
+ data += x;
+ goto rol_abs;
+
+ case 0x1E: // ASL abs,X
+ data += x;
+ case 0x0E: // ASL abs
+ c = 0;
+ case 0x2E: // ROL abs
+ rol_abs:
+ ADD_PAGE();
+ nz = c >> 8 & 1;
+ FLUSH_TIME();
+ nz |= (c = READ( data ) << 1);
+ rotate_common:
+ pc++;
+ WRITE( data, (uint8_t) nz );
+ CACHE_TIME();
+ goto loop;
+
+ case 0x7E: // ROR abs,X
+ data += x;
+ goto ror_abs;
+
+ case 0x76: // ROR zp,x
+ data = uint8_t (data + x);
+ goto ror_zp;
+
+ case 0x56: // LSR zp,x
+ data = uint8_t (data + x);
+ case 0x46: // LSR zp
+ c = 0;
+ case 0x66: // ROR zp
+ ror_zp: {
+ int temp = READ_LOW( data );
+ nz = (c >> 1 & 0x80) | (temp >> 1);
+ c = temp << 8;
+ goto write_nz_zp;
+ }
+
+ case 0x36: // ROL zp,x
+ data = uint8_t (data + x);
+ goto rol_zp;
+
+ case 0x16: // ASL zp,x
+ data = uint8_t (data + x);
+ case 0x06: // ASL zp
+ c = 0;
+ case 0x26: // ROL zp
+ rol_zp:
+ nz = c >> 8 & 1;
+ nz |= (c = READ_LOW( data ) << 1);
+ goto write_nz_zp;
+
+// Increment/decrement
+
+ case 0xCA: // DEX
+ INC_DEC_XY( x, -1 )
+
+ case 0x88: // DEY
+ INC_DEC_XY( y, -1 )
+
+ case 0xF6: // INC zp,x
+ data = uint8_t (data + x);
+ case 0xE6: // INC zp
+ nz = 1;
+ goto add_nz_zp;
+
+ case 0xD6: // DEC zp,x
+ data = uint8_t (data + x);
+ case 0xC6: // DEC zp
+ nz = (unsigned) -1;
+ add_nz_zp:
+ nz += READ_LOW( data );
+ write_nz_zp:
+ pc++;
+ WRITE_LOW( data, nz );
+ goto loop;
+
+ case 0xFE: // INC abs,x
+ data = x + GET_ADDR();
+ goto inc_ptr;
+
+ case 0xEE: // INC abs
+ data = GET_ADDR();
+ inc_ptr:
+ nz = 1;
+ goto inc_common;
+
+ case 0xDE: // DEC abs,x
+ data = x + GET_ADDR();
+ goto dec_ptr;
+
+ case 0xCE: // DEC abs
+ data = GET_ADDR();
+ dec_ptr:
+ nz = (unsigned) -1;
+ inc_common:
+ FLUSH_TIME();
+ nz += READ( data );
+ pc += 2;
+ WRITE( data, (uint8_t) nz );
+ CACHE_TIME();
+ goto loop;
+
+// Transfer
+
+ case 0xAA: // TAX
+ x = a;
+ nz = a;
+ goto loop;
+
+ case 0x8A: // TXA
+ a = x;
+ nz = x;
+ goto loop;
+
+ case 0x9A: // TXS
+ SET_SP( x ); // verified (no flag change)
+ goto loop;
+
+ case 0xBA: // TSX
+ x = nz = GET_SP();
+ goto loop;
+
+// Stack
+
+ case 0x48: // PHA
+ PUSH( a ); // verified
+ goto loop;
+
+ case 0x68: // PLA
+ a = nz = READ_LOW( sp );
+ sp = (sp - 0xFF) | 0x100;
+ goto loop;
+
+ case 0x40:{// RTI
+ fuint8 temp = READ_LOW( sp );
+ pc = READ_LOW( 0x100 | (sp - 0xFF) );
+ pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
+ sp = (sp - 0xFD) | 0x100;
+ data = status;
+ SET_STATUS( temp );
+ this->r.status = status; // update externally-visible I flag
+ if ( (data ^ status) & st_i )
+ {
+ sap_time_t new_time = end_time_;
+ if ( !(status & st_i) && new_time > irq_time_ )
+ new_time = irq_time_;
+ blargg_long delta = s.base - new_time;
+ s.base = new_time;
+ s_time += delta;
+ }
+ goto loop;
+ }
+
+ case 0x28:{// PLP
+ fuint8 temp = READ_LOW( sp );
+ sp = (sp - 0xFF) | 0x100;
+ fuint8 changed = status ^ temp;
+ SET_STATUS( temp );
+ if ( !(changed & st_i) )
+ goto loop; // I flag didn't change
+ if ( status & st_i )
+ goto handle_sei;
+ goto handle_cli;
+ }
+
+ case 0x08: { // PHP
+ fuint8 temp;
+ CALC_STATUS( temp );
+ PUSH( temp | (st_b | st_r) );
+ goto loop;
+ }
+
+ case 0x6C:{// JMP (ind)
+ data = GET_ADDR();
+ pc = READ_PROG( data );
+ data = (data & 0xFF00) | ((data + 1) & 0xFF);
+ pc |= 0x100 * READ_PROG( data );
+ goto loop;
+ }
+
+ case 0x00: // BRK
+ goto handle_brk;
+
+// Flags
+
+ case 0x38: // SEC
+ c = (unsigned) ~0;
+ goto loop;
+
+ case 0x18: // CLC
+ c = 0;
+ goto loop;
+
+ case 0xB8: // CLV
+ status &= ~st_v;
+ goto loop;
+
+ case 0xD8: // CLD
+ status &= ~st_d;
+ goto loop;
+
+ case 0xF8: // SED
+ status |= st_d;
+ goto loop;
+
+ case 0x58: // CLI
+ if ( !(status & st_i) )
+ goto loop;
+ status &= ~st_i;
+ handle_cli: {
+ this->r.status = status; // update externally-visible I flag
+ blargg_long delta = s.base - irq_time_;
+ if ( delta <= 0 )
+ {
+ if ( TIME < irq_time_ )
+ goto loop;
+ goto delayed_cli;
+ }
+ s.base = irq_time_;
+ s_time += delta;
+ if ( s_time < 0 )
+ goto loop;
+
+ if ( delta >= s_time + 1 )
+ {
+ // delayed irq until after next instruction
+ s.base += s_time + 1;
+ s_time = -1;
+ irq_time_ = s.base; // TODO: remove, as only to satisfy debug check in loop
+ goto loop;
+ }
+ delayed_cli:
+ debug_printf( "Delayed CLI not emulated\n" );
+ goto loop;
+ }
+
+ case 0x78: // SEI
+ if ( status & st_i )
+ goto loop;
+ status |= st_i;
+ handle_sei: {
+ this->r.status = status; // update externally-visible I flag
+ blargg_long delta = s.base - end_time_;
+ s.base = end_time_;
+ s_time += delta;
+ if ( s_time < 0 )
+ goto loop;
+ debug_printf( "Delayed SEI not emulated\n" );
+ goto loop;
+ }
+
+// Unofficial
+
+ // SKW - Skip word
+ case 0x1C: case 0x3C: case 0x5C: case 0x7C: case 0xDC: case 0xFC:
+ HANDLE_PAGE_CROSSING( data + x );
+ case 0x0C:
+ pc++;
+ // SKB - Skip byte
+ case 0x74: case 0x04: case 0x14: case 0x34: case 0x44: case 0x54: case 0x64:
+ case 0x80: case 0x82: case 0x89: case 0xC2: case 0xD4: case 0xE2: case 0xF4:
+ pc++;
+ goto loop;
+
+ // NOP
+ case 0xEA: case 0x1A: case 0x3A: case 0x5A: case 0x7A: case 0xDA: case 0xFA:
+ goto loop;
+
+// Unimplemented
+
+ // halt
+ //case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52:
+ //case 0x62: case 0x72: case 0x92: case 0xB2: case 0xD2: case 0xF2:
+
+ default:
+ assert( (unsigned) opcode <= 0xFF );
+ illegal_encountered = true;
+ pc--;
+ goto stop;
+ }
+ assert( false );
+
+ int result_;
+handle_brk:
+ if ( (pc - 1) >= idle_addr )
+ goto idle_done;
+ pc++;
+ result_ = 4;
+ debug_printf( "BRK executed\n" );
+
+interrupt:
+ {
+ s_time += 7;
+
+ WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
+ WRITE_LOW( 0x100 | (sp - 2), pc );
+ pc = GET_LE16( &READ_PROG( 0xFFFA ) + result_ );
+
+ sp = (sp - 3) | 0x100;
+ fuint8 temp;
+ CALC_STATUS( temp );
+ temp |= st_r;
+ if ( result_ )
+ temp |= st_b; // TODO: incorrectly sets B flag for IRQ
+ WRITE_LOW( sp, temp );
+
+ status &= ~st_d;
+ status |= st_i;
+ this->r.status = status; // update externally-visible I flag
+
+ blargg_long delta = s.base - end_time_;
+ s.base = end_time_;
+ s_time += delta;
+ goto loop;
+ }
+
+idle_done:
+ //s_time = 0;
+ pc--;
+ goto stop;
+out_of_time:
+ pc--;
+ FLUSH_TIME();
+ CPU_DONE( this, TIME, result_ );
+ CACHE_TIME();
+ if ( result_ >= 0 )
+ goto interrupt;
+ if ( s_time < 0 )
+ goto loop;
+
+stop:
+
+ s.time = s_time;
+
+ r.pc = pc;
+ r.sp = GET_SP();
+ r.a = a;
+ r.x = x;
+ r.y = y;
+
+ {
+ fuint8 temp;
+ CALC_STATUS( temp );
+ r.status = temp;
+ }
+
+ this->state_ = s;
+ this->state = &this->state_;
+
+ return illegal_encountered;
+}
+
diff --git a/src/console/Sap_Cpu.cxx b/src/console/Sap_Cpu.cxx
deleted file mode 100644
index 7528de1b36a9..000000000000
--- a/src/console/Sap_Cpu.cxx
+++ /dev/null
@@ -1,1009 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Sap_Cpu.h"
-
-#include <limits.h>
-#include "blargg_endian.h"
-
-//#include "nes_cpu_log.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#define FLUSH_TIME() (void) (s.time = s_time)
-#define CACHE_TIME() (void) (s_time = s.time)
-
-#include "sap_cpu_io.h"
-
-#ifndef CPU_DONE
- #define CPU_DONE( cpu, time, result_out ) { result_out = -1; }
-#endif
-
-#include "blargg_source.h"
-
-int const st_n = 0x80;
-int const st_v = 0x40;
-int const st_r = 0x20;
-int const st_b = 0x10;
-int const st_d = 0x08;
-int const st_i = 0x04;
-int const st_z = 0x02;
-int const st_c = 0x01;
-
-void Sap_Cpu::reset( void* new_mem )
-{
- check( state == &state_ );
- state = &state_;
- mem = (uint8_t*) new_mem;
- r.status = st_i;
- r.sp = 0xFF;
- r.pc = 0;
- r.a = 0;
- r.x = 0;
- r.y = 0;
- state_.time = 0;
- state_.base = 0;
- irq_time_ = future_sap_time;
- end_time_ = future_sap_time;
-}
-
-#define TIME (s_time + s.base)
-#define READ( addr ) CPU_READ( this, (addr), TIME )
-#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), TIME );}
-#define READ_LOW( addr ) (mem [int (addr)])
-#define WRITE_LOW( addr, data ) (void) (READ_LOW( addr ) = (data))
-#define READ_PROG( addr ) (READ_LOW( addr ))
-
-#define SET_SP( v ) (sp = ((v) + 1) | 0x100)
-#define GET_SP() ((sp - 1) & 0xFF)
-#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-typedef blargg_long fint32;
-
-bool Sap_Cpu::run( sap_time_t end_time )
-{
- bool illegal_encountered = false;
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- fint32 s_time = s.time;
- uint8_t* const mem = this->mem; // cache
-
- // registers
- fuint16 pc = r.pc;
- fuint8 a = r.a;
- fuint8 x = r.x;
- fuint8 y = r.y;
- fuint16 sp;
- SET_SP( r.sp );
-
- // status flags
- #define IS_NEG (nz & 0x8080)
-
- #define CALC_STATUS( out ) do {\
- out = status & (st_v | st_d | st_i);\
- out |= ((nz >> 8) | nz) & st_n;\
- out |= c >> 8 & st_c;\
- if ( !(nz & 0xFF) ) out |= st_z;\
- } while ( 0 )
-
- #define SET_STATUS( in ) do {\
- status = in & (st_v | st_d | st_i);\
- nz = in << 8;\
- c = nz;\
- nz |= ~in & st_z;\
- } while ( 0 )
-
- fuint8 status;
- fuint16 c; // carry set if (c & 0x100) != 0
- fuint16 nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
- {
- fuint8 temp = r.status;
- SET_STATUS( temp );
- }
-
- goto loop;
-dec_clock_loop:
- s_time--;
-loop:
-
- #ifndef NDEBUG
- {
- sap_time_t correct = end_time_;
- if ( !(status & st_i) && correct > irq_time_ )
- correct = irq_time_;
- check( s.base == correct );
- }
- #endif
-
- check( (unsigned) GET_SP() < 0x100 );
- check( (unsigned) a < 0x100 );
- check( (unsigned) x < 0x100 );
- check( (unsigned) y < 0x100 );
-
- fuint8 opcode = mem [pc];
- pc++;
- uint8_t const* instr = mem + pc;
-
- static uint8_t const clock_table [256] =
- {// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,// 0
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 1
- 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,// 2
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 3
- 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,// 4
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 5
- 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,// 6
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 7
- 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// 8
- 3,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,// 9
- 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// A
- 3,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,// B
- 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// C
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// D
- 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// E
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7 // F
- }; // 0x00 was 7
-
- fuint16 data;
- data = clock_table [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = *instr;
-
- #ifdef NES_CPU_LOG_H
- nes_cpu_log( "cpu_log", pc - 1, opcode, instr [0], instr [1] );
- #endif
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-
-// Macros
-
-#define GET_MSB() (instr [1])
-#define ADD_PAGE() (pc++, data += 0x100 * GET_MSB())
-#define GET_ADDR() GET_LE16( instr )
-
-#define NO_PAGE_CROSSING( lsb )
-#define HANDLE_PAGE_CROSSING( lsb ) s_time += (lsb) >> 8;
-
-#define INC_DEC_XY( reg, n ) reg = uint8_t (nz = reg + n); goto loop;
-
-#define IND_Y( cross, out ) {\
- fuint16 temp = READ_LOW( data ) + y;\
- out = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
- cross( temp );\
- }
-
-#define IND_X( out ) {\
- fuint16 temp = data + x;\
- out = 0x100 * READ_LOW( uint8_t (temp + 1) ) + READ_LOW( uint8_t (temp) );\
- }
-
-#define ARITH_ADDR_MODES( op )\
-case op - 0x04: /* (ind,x) */\
- IND_X( data )\
- goto ptr##op;\
-case op + 0x0C: /* (ind),y */\
- IND_Y( HANDLE_PAGE_CROSSING, data )\
- goto ptr##op;\
-case op + 0x10: /* zp,X */\
- data = uint8_t (data + x);\
-case op + 0x00: /* zp */\
- data = READ_LOW( data );\
- goto imm##op;\
-case op + 0x14: /* abs,Y */\
- data += y;\
- goto ind##op;\
-case op + 0x18: /* abs,X */\
- data += x;\
-ind##op:\
- HANDLE_PAGE_CROSSING( data );\
-case op + 0x08: /* abs */\
- ADD_PAGE();\
-ptr##op:\
- FLUSH_TIME();\
- data = READ( data );\
- CACHE_TIME();\
-case op + 0x04: /* imm */\
-imm##op:
-
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define BRANCH( cond )\
-{\
- fint16 offset = (int8_t) data;\
- fuint16 extra_clock = (++pc & 0xFF) + offset;\
- if ( !(cond) ) goto dec_clock_loop;\
- pc += offset;\
- s_time += extra_clock >> 8 & 1;\
- goto loop;\
-}
-
-// Often-Used
-
- case 0xB5: // LDA zp,x
- a = nz = READ_LOW( uint8_t (data + x) );
- pc++;
- goto loop;
-
- case 0xA5: // LDA zp
- a = nz = READ_LOW( data );
- pc++;
- goto loop;
-
- case 0xD0: // BNE
- BRANCH( (uint8_t) nz );
-
- case 0x20: { // JSR
- fuint16 temp = pc + 1;
- pc = GET_ADDR();
- WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
- sp = (sp - 2) | 0x100;
- WRITE_LOW( sp, temp );
- goto loop;
- }
-
- case 0x4C: // JMP abs
- pc = GET_ADDR();
- goto loop;
-
- case 0xE8: // INX
- INC_DEC_XY( x, 1 )
-
- case 0x10: // BPL
- BRANCH( !IS_NEG )
-
- ARITH_ADDR_MODES( 0xC5 ) // CMP
- nz = a - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0x30: // BMI
- BRANCH( IS_NEG )
-
- case 0xF0: // BEQ
- BRANCH( !(uint8_t) nz );
-
- case 0x95: // STA zp,x
- data = uint8_t (data + x);
- case 0x85: // STA zp
- pc++;
- WRITE_LOW( data, a );
- goto loop;
-
- case 0xC8: // INY
- INC_DEC_XY( y, 1 )
-
- case 0xA8: // TAY
- y = a;
- nz = a;
- goto loop;
-
- case 0x98: // TYA
- a = y;
- nz = y;
- goto loop;
-
- case 0xAD:{// LDA abs
- unsigned addr = GET_ADDR();
- pc += 2;
- nz = READ( addr );
- a = nz;
- goto loop;
- }
-
- case 0x60: // RTS
- pc = 1 + READ_LOW( sp );
- pc += 0x100 * READ_LOW( 0x100 | (sp - 0xFF) );
- sp = (sp - 0xFE) | 0x100;
- goto loop;
-
- {
- fuint16 addr;
-
- case 0x99: // STA abs,Y
- addr = y + GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- goto sta_ptr;
-
- case 0x8D: // STA abs
- addr = GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- goto sta_ptr;
-
- case 0x9D: // STA abs,X (slightly more common than STA abs)
- addr = x + GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- sta_ptr:
- FLUSH_TIME();
- WRITE( addr, a );
- CACHE_TIME();
- goto loop;
-
- case 0x91: // STA (ind),Y
- IND_Y( NO_PAGE_CROSSING, addr )
- pc++;
- goto sta_ptr;
-
- case 0x81: // STA (ind,X)
- IND_X( addr )
- pc++;
- goto sta_ptr;
-
- }
-
- case 0xA9: // LDA #imm
- pc++;
- a = data;
- nz = data;
- goto loop;
-
- // common read instructions
- {
- fuint16 addr;
-
- case 0xA1: // LDA (ind,X)
- IND_X( addr )
- pc++;
- goto a_nz_read_addr;
-
- case 0xB1:// LDA (ind),Y
- addr = READ_LOW( data ) + y;
- HANDLE_PAGE_CROSSING( addr );
- addr += 0x100 * READ_LOW( (uint8_t) (data + 1) );
- pc++;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- goto a_nz_read_addr;
-
- case 0xB9: // LDA abs,Y
- HANDLE_PAGE_CROSSING( data + y );
- addr = GET_ADDR() + y;
- pc += 2;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- goto a_nz_read_addr;
-
- case 0xBD: // LDA abs,X
- HANDLE_PAGE_CROSSING( data + x );
- addr = GET_ADDR() + x;
- pc += 2;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- a_nz_read_addr:
- FLUSH_TIME();
- a = nz = READ( addr );
- CACHE_TIME();
- goto loop;
-
- }
-
-// Branch
-
- case 0x50: // BVC
- BRANCH( !(status & st_v) )
-
- case 0x70: // BVS
- BRANCH( status & st_v )
-
- case 0xB0: // BCS
- BRANCH( c & 0x100 )
-
- case 0x90: // BCC
- BRANCH( !(c & 0x100) )
-
-// Load/store
-
- case 0x94: // STY zp,x
- data = uint8_t (data + x);
- case 0x84: // STY zp
- pc++;
- WRITE_LOW( data, y );
- goto loop;
-
- case 0x96: // STX zp,y
- data = uint8_t (data + y);
- case 0x86: // STX zp
- pc++;
- WRITE_LOW( data, x );
- goto loop;
-
- case 0xB6: // LDX zp,y
- data = uint8_t (data + y);
- case 0xA6: // LDX zp
- data = READ_LOW( data );
- case 0xA2: // LDX #imm
- pc++;
- x = data;
- nz = data;
- goto loop;
-
- case 0xB4: // LDY zp,x
- data = uint8_t (data + x);
- case 0xA4: // LDY zp
- data = READ_LOW( data );
- case 0xA0: // LDY #imm
- pc++;
- y = data;
- nz = data;
- goto loop;
-
- case 0xBC: // LDY abs,X
- data += x;
- HANDLE_PAGE_CROSSING( data );
- case 0xAC:{// LDY abs
- unsigned addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- y = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- case 0xBE: // LDX abs,y
- data += y;
- HANDLE_PAGE_CROSSING( data );
- case 0xAE:{// LDX abs
- unsigned addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- x = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- {
- fuint8 temp;
- case 0x8C: // STY abs
- temp = y;
- goto store_abs;
-
- case 0x8E: // STX abs
- temp = x;
- store_abs:
- unsigned addr = GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, temp );
- goto loop;
- }
- FLUSH_TIME();
- WRITE( addr, temp );
- CACHE_TIME();
- goto loop;
- }
-
-// Compare
-
- case 0xEC:{// CPX abs
- unsigned addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpx_data;
- }
-
- case 0xE4: // CPX zp
- data = READ_LOW( data );
- case 0xE0: // CPX #imm
- cpx_data:
- nz = x - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0xCC:{// CPY abs
- unsigned addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpy_data;
- }
-
- case 0xC4: // CPY zp
- data = READ_LOW( data );
- case 0xC0: // CPY #imm
- cpy_data:
- nz = y - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
-// Logical
-
- ARITH_ADDR_MODES( 0x25 ) // AND
- nz = (a &= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x45 ) // EOR
- nz = (a ^= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x05 ) // ORA
- nz = (a |= data);
- pc++;
- goto loop;
-
- case 0x2C:{// BIT abs
- unsigned addr = GET_ADDR();
- pc += 2;
- status &= ~st_v;
- nz = READ( addr );
- status |= nz & st_v;
- if ( a & nz )
- goto loop;
- nz <<= 8; // result must be zero, even if N bit is set
- goto loop;
- }
-
- case 0x24: // BIT zp
- nz = READ_LOW( data );
- pc++;
- status &= ~st_v;
- status |= nz & st_v;
- if ( a & nz )
- goto loop;
- nz <<= 8; // result must be zero, even if N bit is set
- goto loop;
-
-// Add/subtract
-
- ARITH_ADDR_MODES( 0xE5 ) // SBC
- case 0xEB: // unofficial equivalent
- data ^= 0xFF;
- goto adc_imm;
-
- ARITH_ADDR_MODES( 0x65 ) // ADC
- adc_imm: {
- check( !(status & st_d) );
- fint16 carry = c >> 8 & 1;
- fint16 ov = (a ^ 0x80) + carry + (int8_t) data; // sign-extend
- status &= ~st_v;
- status |= ov >> 2 & 0x40;
- c = nz = a + data + carry;
- pc++;
- a = (uint8_t) nz;
- goto loop;
- }
-
-// Shift/rotate
-
- case 0x4A: // LSR A
- c = 0;
- case 0x6A: // ROR A
- nz = c >> 1 & 0x80;
- c = a << 8;
- nz |= a >> 1;
- a = nz;
- goto loop;
-
- case 0x0A: // ASL A
- nz = a << 1;
- c = nz;
- a = (uint8_t) nz;
- goto loop;
-
- case 0x2A: { // ROL A
- nz = a << 1;
- fint16 temp = c >> 8 & 1;
- c = nz;
- nz |= temp;
- a = (uint8_t) nz;
- goto loop;
- }
-
- case 0x5E: // LSR abs,X
- data += x;
- case 0x4E: // LSR abs
- c = 0;
- case 0x6E: // ROR abs
- ror_abs: {
- ADD_PAGE();
- FLUSH_TIME();
- int temp = READ( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto rotate_common;
- }
-
- case 0x3E: // ROL abs,X
- data += x;
- goto rol_abs;
-
- case 0x1E: // ASL abs,X
- data += x;
- case 0x0E: // ASL abs
- c = 0;
- case 0x2E: // ROL abs
- rol_abs:
- ADD_PAGE();
- nz = c >> 8 & 1;
- FLUSH_TIME();
- nz |= (c = READ( data ) << 1);
- rotate_common:
- pc++;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
- case 0x7E: // ROR abs,X
- data += x;
- goto ror_abs;
-
- case 0x76: // ROR zp,x
- data = uint8_t (data + x);
- goto ror_zp;
-
- case 0x56: // LSR zp,x
- data = uint8_t (data + x);
- case 0x46: // LSR zp
- c = 0;
- case 0x66: // ROR zp
- ror_zp: {
- int temp = READ_LOW( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto write_nz_zp;
- }
-
- case 0x36: // ROL zp,x
- data = uint8_t (data + x);
- goto rol_zp;
-
- case 0x16: // ASL zp,x
- data = uint8_t (data + x);
- case 0x06: // ASL zp
- c = 0;
- case 0x26: // ROL zp
- rol_zp:
- nz = c >> 8 & 1;
- nz |= (c = READ_LOW( data ) << 1);
- goto write_nz_zp;
-
-// Increment/decrement
-
- case 0xCA: // DEX
- INC_DEC_XY( x, -1 )
-
- case 0x88: // DEY
- INC_DEC_XY( y, -1 )
-
- case 0xF6: // INC zp,x
- data = uint8_t (data + x);
- case 0xE6: // INC zp
- nz = 1;
- goto add_nz_zp;
-
- case 0xD6: // DEC zp,x
- data = uint8_t (data + x);
- case 0xC6: // DEC zp
- nz = (unsigned) -1;
- add_nz_zp:
- nz += READ_LOW( data );
- write_nz_zp:
- pc++;
- WRITE_LOW( data, nz );
- goto loop;
-
- case 0xFE: // INC abs,x
- data = x + GET_ADDR();
- goto inc_ptr;
-
- case 0xEE: // INC abs
- data = GET_ADDR();
- inc_ptr:
- nz = 1;
- goto inc_common;
-
- case 0xDE: // DEC abs,x
- data = x + GET_ADDR();
- goto dec_ptr;
-
- case 0xCE: // DEC abs
- data = GET_ADDR();
- dec_ptr:
- nz = (unsigned) -1;
- inc_common:
- FLUSH_TIME();
- nz += READ( data );
- pc += 2;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
-// Transfer
-
- case 0xAA: // TAX
- x = a;
- nz = a;
- goto loop;
-
- case 0x8A: // TXA
- a = x;
- nz = x;
- goto loop;
-
- case 0x9A: // TXS
- SET_SP( x ); // verified (no flag change)
- goto loop;
-
- case 0xBA: // TSX
- x = nz = GET_SP();
- goto loop;
-
-// Stack
-
- case 0x48: // PHA
- PUSH( a ); // verified
- goto loop;
-
- case 0x68: // PLA
- a = nz = READ_LOW( sp );
- sp = (sp - 0xFF) | 0x100;
- goto loop;
-
- case 0x40:{// RTI
- fuint8 temp = READ_LOW( sp );
- pc = READ_LOW( 0x100 | (sp - 0xFF) );
- pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
- sp = (sp - 0xFD) | 0x100;
- data = status;
- SET_STATUS( temp );
- this->r.status = status; // update externally-visible I flag
- if ( (data ^ status) & st_i )
- {
- sap_time_t new_time = end_time_;
- if ( !(status & st_i) && new_time > irq_time_ )
- new_time = irq_time_;
- blargg_long delta = s.base - new_time;
- s.base = new_time;
- s_time += delta;
- }
- goto loop;
- }
-
- case 0x28:{// PLP
- fuint8 temp = READ_LOW( sp );
- sp = (sp - 0xFF) | 0x100;
- fuint8 changed = status ^ temp;
- SET_STATUS( temp );
- if ( !(changed & st_i) )
- goto loop; // I flag didn't change
- if ( status & st_i )
- goto handle_sei;
- goto handle_cli;
- }
-
- case 0x08: { // PHP
- fuint8 temp;
- CALC_STATUS( temp );
- PUSH( temp | (st_b | st_r) );
- goto loop;
- }
-
- case 0x6C:{// JMP (ind)
- data = GET_ADDR();
- pc = READ_PROG( data );
- data = (data & 0xFF00) | ((data + 1) & 0xFF);
- pc |= 0x100 * READ_PROG( data );
- goto loop;
- }
-
- case 0x00: // BRK
- goto handle_brk;
-
-// Flags
-
- case 0x38: // SEC
- c = (unsigned) ~0;
- goto loop;
-
- case 0x18: // CLC
- c = 0;
- goto loop;
-
- case 0xB8: // CLV
- status &= ~st_v;
- goto loop;
-
- case 0xD8: // CLD
- status &= ~st_d;
- goto loop;
-
- case 0xF8: // SED
- status |= st_d;
- goto loop;
-
- case 0x58: // CLI
- if ( !(status & st_i) )
- goto loop;
- status &= ~st_i;
- handle_cli: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - irq_time_;
- if ( delta <= 0 )
- {
- if ( TIME < irq_time_ )
- goto loop;
- goto delayed_cli;
- }
- s.base = irq_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
-
- if ( delta >= s_time + 1 )
- {
- // delayed irq until after next instruction
- s.base += s_time + 1;
- s_time = -1;
- irq_time_ = s.base; // TODO: remove, as only to satisfy debug check in loop
- goto loop;
- }
- delayed_cli:
- debug_printf( "Delayed CLI not emulated\n" );
- goto loop;
- }
-
- case 0x78: // SEI
- if ( status & st_i )
- goto loop;
- status |= st_i;
- handle_sei: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
- debug_printf( "Delayed SEI not emulated\n" );
- goto loop;
- }
-
-// Unofficial
-
- // SKW - Skip word
- case 0x1C: case 0x3C: case 0x5C: case 0x7C: case 0xDC: case 0xFC:
- HANDLE_PAGE_CROSSING( data + x );
- case 0x0C:
- pc++;
- // SKB - Skip byte
- case 0x74: case 0x04: case 0x14: case 0x34: case 0x44: case 0x54: case 0x64:
- case 0x80: case 0x82: case 0x89: case 0xC2: case 0xD4: case 0xE2: case 0xF4:
- pc++;
- goto loop;
-
- // NOP
- case 0xEA: case 0x1A: case 0x3A: case 0x5A: case 0x7A: case 0xDA: case 0xFA:
- goto loop;
-
-// Unimplemented
-
- // halt
- //case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52:
- //case 0x62: case 0x72: case 0x92: case 0xB2: case 0xD2: case 0xF2:
-
- default:
- assert( (unsigned) opcode <= 0xFF );
- illegal_encountered = true;
- pc--;
- goto stop;
- }
- assert( false );
-
- int result_;
-handle_brk:
- if ( (pc - 1) >= idle_addr )
- goto idle_done;
- pc++;
- result_ = 4;
- debug_printf( "BRK executed\n" );
-
-interrupt:
- {
- s_time += 7;
-
- WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
- WRITE_LOW( 0x100 | (sp - 2), pc );
- pc = GET_LE16( &READ_PROG( 0xFFFA ) + result_ );
-
- sp = (sp - 3) | 0x100;
- fuint8 temp;
- CALC_STATUS( temp );
- temp |= st_r;
- if ( result_ )
- temp |= st_b; // TODO: incorrectly sets B flag for IRQ
- WRITE_LOW( sp, temp );
-
- status &= ~st_d;
- status |= st_i;
- this->r.status = status; // update externally-visible I flag
-
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- goto loop;
- }
-
-idle_done:
- //s_time = 0;
- pc--;
- goto stop;
-out_of_time:
- pc--;
- FLUSH_TIME();
- CPU_DONE( this, TIME, result_ );
- CACHE_TIME();
- if ( result_ >= 0 )
- goto interrupt;
- if ( s_time < 0 )
- goto loop;
-
-stop:
-
- s.time = s_time;
-
- r.pc = pc;
- r.sp = GET_SP();
- r.a = a;
- r.x = x;
- r.y = y;
-
- {
- fuint8 temp;
- CALC_STATUS( temp );
- r.status = temp;
- }
-
- this->state_ = s;
- this->state = &this->state_;
-
- return illegal_encountered;
-}
-
diff --git a/src/console/Sap_Emu.cc b/src/console/Sap_Emu.cc
new file mode 100644
index 000000000000..75fbd2655a37
--- /dev/null
+++ b/src/console/Sap_Emu.cc
@@ -0,0 +1,525 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Sap_Emu.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+long const base_scanline_period = 114;
+
+Sap_Emu::Sap_Emu()
+{
+ set_type( gme_sap_type );
+
+ static const char* const names [Sap_Apu::osc_count * 2] = {
+ "Wave 1", "Wave 2", "Wave 3", "Wave 4",
+ "Wave 5", "Wave 6", "Wave 7", "Wave 8",
+ };
+ set_voice_names( names );
+
+ static int const types [Sap_Apu::osc_count * 2] = {
+ wave_type | 1, wave_type | 2, wave_type | 3, wave_type | 0,
+ wave_type | 5, wave_type | 6, wave_type | 7, wave_type | 4,
+ };
+ set_voice_types( types );
+ set_silence_lookahead( 6 );
+}
+
+Sap_Emu::~Sap_Emu() { }
+
+// Track info
+
+// Returns 16 or greater if not hex
+inline int from_hex_char( int h )
+{
+ h -= 0x30;
+ if ( (unsigned) h > 9 )
+ h = ((h - 0x11) & 0xDF) + 10;
+ return h;
+}
+
+static long from_hex( byte const* in )
+{
+ unsigned result = 0;
+ for ( int n = 4; n--; )
+ {
+ int h = from_hex_char( *in++ );
+ if ( h > 15 )
+ return -1;
+ result = result * 0x10 + h;
+ }
+ return result;
+}
+
+static int from_dec( byte const* in, byte const* end )
+{
+ if ( in >= end )
+ return -1;
+
+ int n = 0;
+ while ( in < end )
+ {
+ int dig = *in++ - '0';
+ if ( (unsigned) dig > 9 )
+ return -1;
+ n = n * 10 + dig;
+ }
+ return n;
+}
+
+static void parse_string( byte const* in, byte const* end, int len, char* out )
+{
+ byte const* start = in;
+ if ( *in++ == '\"' )
+ {
+ start++;
+ while ( in < end && *in != '\"' )
+ in++;
+ }
+ else
+ {
+ in = end;
+ }
+ len = min( len - 1, int (in - start) );
+ out [len] = 0;
+ memcpy( out, start, len );
+}
+
+static byte const* parse_int_( byte const* in, int* out )
+{
+ int n = 0;
+ while ( 1 )
+ {
+ unsigned d = from_dec( in, in + 1 );
+ if ( d > 9 )
+ break;
+ in++;
+ n = n * 10 + d;
+ *out = n;
+ }
+ return in;
+}
+
+static byte const* parse_time( byte const* in, int* out )
+{
+ *out = -1;
+ int n = -1;
+ in = parse_int_( in, &n );
+ if ( n >= 0 )
+ {
+ *out = n;
+ if ( *in == ':' )
+ {
+ n = -1;
+ in = parse_int_( in + 1, &n );
+ if ( n >= 0 )
+ *out = *out * 60 + n;
+ }
+ }
+ *out = *out * 1000;
+ return in;
+}
+
+static blargg_err_t parse_info( byte const* in, long size, Sap_Emu::info_t* out )
+{
+ out->track_count = 1;
+ out->author [0] = 0;
+ out->name [0] = 0;
+ out->copyright [0] = 0;
+
+ if ( size < 16 || memcmp( in, "SAP\x0D\x0A", 5 ) )
+ return gme_wrong_file_type;
+
+ byte const* file_end = in + size - 5;
+ in += 5;
+ while ( in < file_end && (in [0] != 0xFF || in [1] != 0xFF) )
+ {
+ byte const* line_end = in;
+ while ( line_end < file_end && *line_end != 0x0D )
+ line_end++;
+
+ char const* tag = (char const*) in;
+ while ( in < line_end && *in > ' ' )
+ in++;
+ int tag_len = (char const*) in - tag;
+
+ while ( in < line_end && *in <= ' ' ) in++;
+
+ if ( tag_len <= 0 )
+ {
+ // skip line
+ }
+ else if ( !strncmp( "INIT", tag, tag_len ) )
+ {
+ out->init_addr = from_hex( in );
+ if ( (unsigned long) out->init_addr > 0xFFFF )
+ return "Invalid init address";
+ }
+ else if ( !strncmp( "PLAYER", tag, tag_len ) )
+ {
+ out->play_addr = from_hex( in );
+ if ( (unsigned long) out->play_addr > 0xFFFF )
+ return "Invalid play address";
+ }
+ else if ( !strncmp( "MUSIC", tag, tag_len ) )
+ {
+ out->music_addr = from_hex( in );
+ if ( (unsigned long) out->music_addr > 0xFFFF )
+ return "Invalid music address";
+ }
+ else if ( !strncmp( "SONGS", tag, tag_len ) )
+ {
+ out->track_count = from_dec( in, line_end );
+ if ( out->track_count <= 0 )
+ return "Invalid track count";
+ }
+ else if ( !strncmp( "TYPE", tag, tag_len ) )
+ {
+ switch ( out->type = *in )
+ {
+ case 'D':
+ case 'C':
+ case 'B':
+ break;
+
+ default:
+ return "Unsupported player type";
+ }
+ }
+ else if ( !strncmp( "STEREO", tag, tag_len ) )
+ {
+ out->stereo = true;
+ }
+ else if ( !strncmp( "NTSC", tag, tag_len ) )
+ {
+ out->ntsc = true;
+ }
+ else if ( !strncmp( "FASTPLAY", tag, tag_len ) )
+ {
+ out->fastplay = from_dec( in, line_end );
+ if ( out->fastplay <= 0 )
+ return "Invalid fastplay value";
+ }
+ else if ( !strncmp( "AUTHOR", tag, tag_len ) )
+ {
+ parse_string( in, line_end, sizeof out->author, out->author );
+ }
+ else if ( !strncmp( "NAME", tag, tag_len ) )
+ {
+ parse_string( in, line_end, sizeof out->name, out->name );
+ }
+ else if ( !strncmp( "DATE", tag, tag_len ) )
+ {
+ parse_string( in, line_end, sizeof out->copyright, out->copyright );
+ }
+ else if ( !strncmp( "TIME", tag, tag_len ) )
+ {
+ parse_time( in, &out->length );
+ }
+
+ in = line_end + 2;
+ }
+
+ if ( in [0] != 0xFF || in [1] != 0xFF )
+ return "ROM data missing";
+ out->rom_data = in + 2;
+
+ return 0;
+}
+
+static void copy_sap_fields( Sap_Emu::info_t const& in, track_info_t* out )
+{
+ Gme_File::copy_field_( out->song, in.name );
+ Gme_File::copy_field_( out->author, in.author );
+ Gme_File::copy_field_( out->copyright, in.copyright );
+ out->length = in.length;
+}
+
+blargg_err_t Sap_Emu::track_info_( track_info_t* out, int ) const
+{
+ copy_sap_fields( info, out );
+ return 0;
+}
+
+struct Sap_File : Gme_Info_
+{
+ Sap_Emu::info_t info;
+
+ Sap_File() { set_type( gme_sap_type ); }
+
+ blargg_err_t load_mem_( byte const* begin, long size )
+ {
+ RETURN_ERR( parse_info( begin, size, &info ) );
+ set_track_count( info.track_count );
+ return 0;
+ }
+
+ blargg_err_t track_info_( track_info_t* out, int ) const
+ {
+ copy_sap_fields( info, out );
+ return 0;
+ }
+};
+
+static Music_Emu* new_sap_emu () { return BLARGG_NEW Sap_Emu ; }
+static Music_Emu* new_sap_file() { return BLARGG_NEW Sap_File; }
+
+static gme_type_t_ const gme_sap_type_ = { "Atari XL", 0, &new_sap_emu, &new_sap_file, "SAP", 1 };
+gme_type_t const gme_sap_type = &gme_sap_type_;
+
+
+// Setup
+
+blargg_err_t Sap_Emu::load_mem_( byte const* in, long size )
+{
+ file_end = in + size;
+
+ info.warning = 0;
+ info.type = 'B';
+ info.stereo = false;
+ info.init_addr = -1;
+ info.play_addr = -1;
+ info.music_addr = -1;
+ info.fastplay = 312;
+ RETURN_ERR( parse_info( in, size, &info ) );
+
+ set_warning( info.warning );
+ set_track_count( info.track_count );
+ set_voice_count( Sap_Apu::osc_count << info.stereo );
+ apu_impl.volume( gain() );
+
+ return setup_buffer( 1773447 );
+}
+
+void Sap_Emu::update_eq( blip_eq_t const& eq )
+{
+ apu_impl.synth.treble_eq( eq );
+}
+
+void Sap_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
+{
+ int i2 = i - Sap_Apu::osc_count;
+ if ( i2 >= 0 )
+ apu2.osc_output( i2, right );
+ else
+ apu.osc_output( i, (info.stereo ? left : center) );
+}
+
+// Emulation
+
+void Sap_Emu::set_tempo_( double t )
+{
+ scanline_period = sap_time_t (base_scanline_period / t);
+}
+
+inline sap_time_t Sap_Emu::play_period() const { return info.fastplay * scanline_period; }
+
+void Sap_Emu::cpu_jsr( sap_addr_t addr )
+{
+ check( r.sp >= 0xFE ); // catch anything trying to leave data on stack
+ r.pc = addr;
+ int high_byte = (idle_addr - 1) >> 8;
+ if ( r.sp == 0xFE && mem.ram [0x1FF] == high_byte )
+ r.sp = 0xFF; // pop extra byte off
+ mem.ram [0x100 + r.sp--] = high_byte; // some routines use RTI to return
+ mem.ram [0x100 + r.sp--] = high_byte;
+ mem.ram [0x100 + r.sp--] = (idle_addr - 1) & 0xFF;
+}
+
+void Sap_Emu::run_routine( sap_addr_t addr )
+{
+ cpu_jsr( addr );
+ cpu::run( ( info.ntsc ? 262 : 312 ) * base_scanline_period * 60 );
+ check( r.pc == idle_addr );
+}
+
+inline void Sap_Emu::call_init( int track )
+{
+ uint8_t sp;
+ uint16_t code_base;
+
+ switch ( info.type )
+ {
+ case 'B':
+ r.a = track;
+ run_routine( info.init_addr );
+ break;
+
+ case 'C':
+ r.a = 0x70;
+ r.x = info.music_addr&0xFF;
+ r.y = info.music_addr >> 8;
+ run_routine( info.play_addr + 3 );
+ r.a = 0;
+ r.x = track;
+ run_routine( info.play_addr + 3 );
+ break;
+
+ case 'D':
+ r.a = track;
+ r.x = 0;
+ r.y = 0;
+ r.sp = 0xFF;
+ run_routine( info.init_addr );
+
+ sp = r.sp;
+
+ mem.ram [0x100 + sp] = r.pc >> 8;
+ sp = (sp - 1) & 0xFF;
+ mem.ram [0x100 + sp] = ( r.pc & 0xFF );
+ r.sp = (sp - 1) & 0xFF;
+
+ code_base = 0xd200;
+ mem.ram [code_base] = 0x08;
+ mem.ram [code_base + 1] = 0x48;
+ mem.ram [code_base + 2] = 0x8a;
+ mem.ram [code_base + 3] = 0x48;
+ mem.ram [code_base + 4] = 0x98;
+ mem.ram [code_base + 5] = 0x48;
+ mem.ram [code_base + 6] = 0x20;
+ mem.ram [code_base + 7] = code_base & 0xFF;
+ mem.ram [code_base + 8] = (code_base >> 8);
+ mem.ram [code_base + 9] = 0x68;
+ mem.ram [code_base + 10] = 0xa8;
+ mem.ram [code_base + 11] = 0x68;
+ mem.ram [code_base + 12] = 0xaa;
+ mem.ram [code_base + 13] = 0x68;
+ mem.ram [code_base + 14] = 0x40;
+ info.play_addr = code_base;
+ break;
+ }
+}
+
+blargg_err_t Sap_Emu::start_track_( int track )
+{
+ RETURN_ERR( Classic_Emu::start_track_( track ) );
+
+ memset( &mem, 0, sizeof mem );
+
+ byte const* in = info.rom_data;
+ while ( file_end - in >= 5 )
+ {
+ unsigned start = GET_LE16( in );
+ unsigned end = GET_LE16( in + 2 );
+ //debug_printf( "Block $%04X-$%04X\n", start, end );
+ in += 4;
+ if ( end < start )
+ {
+ set_warning( "Invalid file data block" );
+ break;
+ }
+ long len = end - start + 1;
+ if ( len > file_end - in )
+ {
+ set_warning( "Invalid file data block" );
+ break;
+ }
+
+ memcpy( mem.ram + start, in, len );
+ in += len;
+ if ( file_end - in >= 2 && in [0] == 0xFF && in [1] == 0xFF )
+ in += 2;
+ }
+
+ apu.reset( &apu_impl );
+ apu2.reset( &apu_impl );
+ cpu::reset( mem.ram );
+ time_mask = 0; // disables sound during init
+ call_init( track );
+ time_mask = -1;
+
+ next_play = play_period();
+
+ return 0;
+}
+
+// Emulation
+
+// see sap_cpu_io.h for read/write functions
+
+void Sap_Emu::cpu_write_( sap_addr_t addr, int data )
+{
+ if ( (addr ^ Sap_Apu::start_addr) <= (Sap_Apu::end_addr - Sap_Apu::start_addr) )
+ {
+ GME_APU_HOOK( this, addr - Sap_Apu::start_addr, data );
+ apu.write_data( time() & time_mask, addr, data );
+ return;
+ }
+
+ if ( (addr ^ (Sap_Apu::start_addr + 0x10)) <= (Sap_Apu::end_addr - Sap_Apu::start_addr) &&
+ info.stereo )
+ {
+ GME_APU_HOOK( this, addr - 0x10 - Sap_Apu::start_addr + 10, data );
+ apu2.write_data( time() & time_mask, addr ^ 0x10, data );
+ return;
+ }
+
+ if ( (addr & ~0x0010) != 0xD20F || data != 0x03 )
+ debug_printf( "Unmapped write $%04X <- $%02X\n", addr, data );
+}
+
+inline void Sap_Emu::call_play()
+{
+ switch ( info.type )
+ {
+ case 'D':
+ cpu_jsr( info.play_addr );
+ break;
+ case 'B':
+ cpu_jsr( info.play_addr );
+ break;
+
+ case 'C':
+ cpu_jsr( info.play_addr + 6 );
+ break;
+ }
+}
+
+blargg_err_t Sap_Emu::run_clocks( blip_time_t& duration, int )
+{
+ set_time( 0 );
+ while ( time() < duration )
+ {
+ if ( cpu::run( duration ) || r.pc > idle_addr )
+ return "Emulation error (illegal instruction)";
+
+ if ( r.pc == idle_addr )
+ {
+ if ( next_play <= duration )
+ {
+ set_time( next_play );
+ next_play += play_period();
+ call_play();
+ GME_FRAME_HOOK( this );
+ }
+ else
+ {
+ set_time( duration );
+ }
+ }
+ }
+
+ duration = time();
+ next_play -= duration;
+ check( next_play >= 0 );
+ if ( next_play < 0 )
+ next_play = 0;
+ apu.end_frame( duration );
+ if ( info.stereo )
+ apu2.end_frame( duration );
+
+ return 0;
+}
diff --git a/src/console/Sap_Emu.cxx b/src/console/Sap_Emu.cxx
deleted file mode 100644
index 64a47303c729..000000000000
--- a/src/console/Sap_Emu.cxx
+++ /dev/null
@@ -1,444 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Sap_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-long const base_scanline_period = 114;
-
-Sap_Emu::Sap_Emu()
-{
- set_type( gme_sap_type );
-
- static const char* const names [Sap_Apu::osc_count * 2] = {
- "Wave 1", "Wave 2", "Wave 3", "Wave 4",
- "Wave 5", "Wave 6", "Wave 7", "Wave 8",
- };
- set_voice_names( names );
-
- static int const types [Sap_Apu::osc_count * 2] = {
- wave_type | 1, wave_type | 2, wave_type | 3, wave_type | 0,
- wave_type | 5, wave_type | 6, wave_type | 7, wave_type | 4,
- };
- set_voice_types( types );
- set_silence_lookahead( 6 );
-}
-
-Sap_Emu::~Sap_Emu() { }
-
-// Track info
-
-// Returns 16 or greater if not hex
-inline int from_hex_char( int h )
-{
- h -= 0x30;
- if ( (unsigned) h > 9 )
- h = ((h - 0x11) & 0xDF) + 10;
- return h;
-}
-
-static long from_hex( byte const* in )
-{
- unsigned result = 0;
- for ( int n = 4; n--; )
- {
- int h = from_hex_char( *in++ );
- if ( h > 15 )
- return -1;
- result = result * 0x10 + h;
- }
- return result;
-}
-
-static int from_dec( byte const* in, byte const* end )
-{
- if ( in >= end )
- return -1;
-
- int n = 0;
- while ( in < end )
- {
- int dig = *in++ - '0';
- if ( (unsigned) dig > 9 )
- return -1;
- n = n * 10 + dig;
- }
- return n;
-}
-
-static void parse_string( byte const* in, byte const* end, int len, char* out )
-{
- byte const* start = in;
- if ( *in++ == '\"' )
- {
- start++;
- while ( in < end && *in != '\"' )
- in++;
- }
- else
- {
- in = end;
- }
- len = min( len - 1, int (in - start) );
- out [len] = 0;
- memcpy( out, start, len );
-}
-
-static blargg_err_t parse_info( byte const* in, long size, Sap_Emu::info_t* out )
-{
- out->track_count = 1;
- out->author [0] = 0;
- out->name [0] = 0;
- out->copyright [0] = 0;
-
- if ( size < 16 || memcmp( in, "SAP\x0D\x0A", 5 ) )
- return gme_wrong_file_type;
-
- byte const* file_end = in + size - 5;
- in += 5;
- while ( in < file_end && (in [0] != 0xFF || in [1] != 0xFF) )
- {
- byte const* line_end = in;
- while ( line_end < file_end && *line_end != 0x0D )
- line_end++;
-
- char const* tag = (char const*) in;
- while ( in < line_end && *in > ' ' )
- in++;
- int tag_len = (char const*) in - tag;
-
- while ( in < line_end && *in <= ' ' ) in++;
-
- if ( tag_len <= 0 )
- {
- // skip line
- }
- else if ( !strncmp( "INIT", tag, tag_len ) )
- {
- out->init_addr = from_hex( in );
- if ( (unsigned long) out->init_addr > 0xFFFF )
- return "Invalid init address";
- }
- else if ( !strncmp( "PLAYER", tag, tag_len ) )
- {
- out->play_addr = from_hex( in );
- if ( (unsigned long) out->play_addr > 0xFFFF )
- return "Invalid play address";
- }
- else if ( !strncmp( "MUSIC", tag, tag_len ) )
- {
- out->music_addr = from_hex( in );
- if ( (unsigned long) out->music_addr > 0xFFFF )
- return "Invalid music address";
- }
- else if ( !strncmp( "SONGS", tag, tag_len ) )
- {
- out->track_count = from_dec( in, line_end );
- if ( out->track_count <= 0 )
- return "Invalid track count";
- }
- else if ( !strncmp( "TYPE", tag, tag_len ) )
- {
- switch ( out->type = *in )
- {
- case 'C':
- case 'B':
- break;
-
- case 'D':
- return "Digimusic not supported";
-
- default:
- return "Unsupported player type";
- }
- }
- else if ( !strncmp( "STEREO", tag, tag_len ) )
- {
- out->stereo = true;
- }
- else if ( !strncmp( "FASTPLAY", tag, tag_len ) )
- {
- out->fastplay = from_dec( in, line_end );
- if ( out->fastplay <= 0 )
- return "Invalid fastplay value";
- }
- else if ( !strncmp( "AUTHOR", tag, tag_len ) )
- {
- parse_string( in, line_end, sizeof out->author, out->author );
- }
- else if ( !strncmp( "NAME", tag, tag_len ) )
- {
- parse_string( in, line_end, sizeof out->name, out->name );
- }
- else if ( !strncmp( "DATE", tag, tag_len ) )
- {
- parse_string( in, line_end, sizeof out->copyright, out->copyright );
- }
-
- in = line_end + 2;
- }
-
- if ( in [0] != 0xFF || in [1] != 0xFF )
- return "ROM data missing";
- out->rom_data = in + 2;
-
- return 0;
-}
-
-static void copy_sap_fields( Sap_Emu::info_t const& in, track_info_t* out )
-{
- Gme_File::copy_field_( out->song, in.name );
- Gme_File::copy_field_( out->author, in.author );
- Gme_File::copy_field_( out->copyright, in.copyright );
-}
-
-blargg_err_t Sap_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_sap_fields( info, out );
- return 0;
-}
-
-struct Sap_File : Gme_Info_
-{
- Sap_Emu::info_t info;
-
- Sap_File() { set_type( gme_sap_type ); }
-
- blargg_err_t load_mem_( byte const* begin, long size )
- {
- RETURN_ERR( parse_info( begin, size, &info ) );
- set_track_count( info.track_count );
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_sap_fields( info, out );
- return 0;
- }
-};
-
-static Music_Emu* new_sap_emu () { return BLARGG_NEW Sap_Emu ; }
-static Music_Emu* new_sap_file() { return BLARGG_NEW Sap_File; }
-
-static gme_type_t_ const gme_sap_type_ = { "Atari XL", 0, &new_sap_emu, &new_sap_file, "SAP", 1 };
-gme_type_t const gme_sap_type = &gme_sap_type_;
-
-
-// Setup
-
-blargg_err_t Sap_Emu::load_mem_( byte const* in, long size )
-{
- file_end = in + size;
-
- info.warning = 0;
- info.type = 'B';
- info.stereo = false;
- info.init_addr = -1;
- info.play_addr = -1;
- info.music_addr = -1;
- info.fastplay = 312;
- RETURN_ERR( parse_info( in, size, &info ) );
-
- set_warning( info.warning );
- set_track_count( info.track_count );
- set_voice_count( Sap_Apu::osc_count << info.stereo );
- apu_impl.volume( gain() );
-
- return setup_buffer( 1773447 );
-}
-
-void Sap_Emu::update_eq( blip_eq_t const& eq )
-{
- apu_impl.synth.treble_eq( eq );
-}
-
-void Sap_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- int i2 = i - Sap_Apu::osc_count;
- if ( i2 >= 0 )
- apu2.osc_output( i2, right );
- else
- apu.osc_output( i, (info.stereo ? left : center) );
-}
-
-// Emulation
-
-void Sap_Emu::set_tempo_( double t )
-{
- scanline_period = sap_time_t (base_scanline_period / t);
-}
-
-inline sap_time_t Sap_Emu::play_period() const { return info.fastplay * scanline_period; }
-
-void Sap_Emu::cpu_jsr( sap_addr_t addr )
-{
- check( r.sp >= 0xFE ); // catch anything trying to leave data on stack
- r.pc = addr;
- int high_byte = (idle_addr - 1) >> 8;
- if ( r.sp == 0xFE && mem.ram [0x1FF] == high_byte )
- r.sp = 0xFF; // pop extra byte off
- mem.ram [0x100 + r.sp--] = high_byte; // some routines use RTI to return
- mem.ram [0x100 + r.sp--] = high_byte;
- mem.ram [0x100 + r.sp--] = (idle_addr - 1) & 0xFF;
-}
-
-void Sap_Emu::run_routine( sap_addr_t addr )
-{
- cpu_jsr( addr );
- cpu::run( 312 * base_scanline_period * 60 );
- check( r.pc == idle_addr );
-}
-
-inline void Sap_Emu::call_init( int track )
-{
- switch ( info.type )
- {
- case 'B':
- r.a = track;
- run_routine( info.init_addr );
- break;
-
- case 'C':
- r.a = 0x70;
- r.x = info.music_addr&0xFF;
- r.y = info.music_addr >> 8;
- run_routine( info.play_addr + 3 );
- r.a = 0;
- r.x = track;
- run_routine( info.play_addr + 3 );
- break;
- }
-}
-
-blargg_err_t Sap_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( &mem, 0, sizeof mem );
-
- byte const* in = info.rom_data;
- while ( file_end - in >= 5 )
- {
- unsigned start = GET_LE16( in );
- unsigned end = GET_LE16( in + 2 );
- //debug_printf( "Block $%04X-$%04X\n", start, end );
- in += 4;
- if ( end < start )
- {
- set_warning( "Invalid file data block" );
- break;
- }
- long len = end - start + 1;
- if ( len > file_end - in )
- {
- set_warning( "Invalid file data block" );
- break;
- }
-
- memcpy( mem.ram + start, in, len );
- in += len;
- if ( file_end - in >= 2 && in [0] == 0xFF && in [1] == 0xFF )
- in += 2;
- }
-
- apu.reset( &apu_impl );
- apu2.reset( &apu_impl );
- cpu::reset( mem.ram );
- time_mask = 0; // disables sound during init
- call_init( track );
- time_mask = -1;
-
- next_play = play_period();
-
- return 0;
-}
-
-// Emulation
-
-// see sap_cpu_io.h for read/write functions
-
-void Sap_Emu::cpu_write_( sap_addr_t addr, int data )
-{
- if ( (addr ^ Sap_Apu::start_addr) <= (Sap_Apu::end_addr - Sap_Apu::start_addr) )
- {
- GME_APU_HOOK( this, addr - Sap_Apu::start_addr, data );
- apu.write_data( time() & time_mask, addr, data );
- return;
- }
-
- if ( (addr ^ (Sap_Apu::start_addr + 0x10)) <= (Sap_Apu::end_addr - Sap_Apu::start_addr) &&
- info.stereo )
- {
- GME_APU_HOOK( this, addr - 0x10 - Sap_Apu::start_addr + 10, data );
- apu2.write_data( time() & time_mask, addr ^ 0x10, data );
- return;
- }
-
- if ( (addr & ~0x0010) != 0xD20F || data != 0x03 )
- debug_printf( "Unmapped write $%04X <- $%02X\n", addr, data );
-}
-
-inline void Sap_Emu::call_play()
-{
- switch ( info.type )
- {
- case 'B':
- cpu_jsr( info.play_addr );
- break;
-
- case 'C':
- cpu_jsr( info.play_addr + 6 );
- break;
- }
-}
-
-blargg_err_t Sap_Emu::run_clocks( blip_time_t& duration, int )
-{
- set_time( 0 );
- while ( time() < duration )
- {
- if ( cpu::run( duration ) || r.pc > idle_addr )
- return "Emulation error (illegal instruction)";
-
- if ( r.pc == idle_addr )
- {
- if ( next_play <= duration )
- {
- set_time( next_play );
- next_play += play_period();
- call_play();
- GME_FRAME_HOOK( this );
- }
- else
- {
- set_time( duration );
- }
- }
- }
-
- duration = time();
- next_play -= duration;
- check( next_play >= 0 );
- if ( next_play < 0 )
- next_play = 0;
- apu.end_frame( duration );
- if ( info.stereo )
- apu2.end_frame( duration );
-
- return 0;
-}
diff --git a/src/console/Sap_Emu.h b/src/console/Sap_Emu.h
index 818129a5ea7a..426ad3e7596c 100644
--- a/src/console/Sap_Emu.h
+++ b/src/console/Sap_Emu.h
@@ -24,7 +24,9 @@ public:
int type;
int track_count;
int fastplay;
+ int length;
bool stereo;
+ bool ntsc;
char author [256];
char name [256];
char copyright [ 32];
diff --git a/src/console/Sms_Apu.cc b/src/console/Sms_Apu.cc
new file mode 100644
index 000000000000..60d093701694
--- /dev/null
+++ b/src/console/Sms_Apu.cc
@@ -0,0 +1,330 @@
+// Sms_Snd_Emu 0.1.4. http://www.slack.net/~ant/
+
+#include "Sms_Apu.h"
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+// Sms_Osc
+
+Sms_Osc::Sms_Osc()
+{
+ output = 0;
+ outputs [0] = 0; // always stays nullptr
+ outputs [1] = 0;
+ outputs [2] = 0;
+ outputs [3] = 0;
+}
+
+void Sms_Osc::reset()
+{
+ delay = 0;
+ last_amp = 0;
+ volume = 0;
+ output_select = 3;
+ output = outputs [3];
+}
+
+// Sms_Square
+
+inline void Sms_Square::reset()
+{
+ period = 0;
+ phase = 0;
+ Sms_Osc::reset();
+}
+
+void Sms_Square::run( blip_time_t time, blip_time_t end_time )
+{
+ if ( !volume || period <= 128 )
+ {
+ // ignore 16kHz and higher
+ if ( last_amp )
+ {
+ synth->offset( time, -last_amp, output );
+ last_amp = 0;
+ }
+ time += delay;
+ if ( !period )
+ {
+ time = end_time;
+ }
+ else if ( time < end_time )
+ {
+ // keep calculating phase
+ int count = (end_time - time + period - 1) / period;
+ phase = (phase + count) & 1;
+ time += count * period;
+ }
+ }
+ else
+ {
+ int amp = phase ? volume : -volume;
+ {
+ int delta = amp - last_amp;
+ if ( delta )
+ {
+ last_amp = amp;
+ synth->offset( time, delta, output );
+ }
+ }
+
+ time += delay;
+ if ( time < end_time )
+ {
+ Blip_Buffer* const output = this->output;
+ int delta = amp * 2;
+ do
+ {
+ delta = -delta;
+ synth->offset_inline( time, delta, output );
+ time += period;
+ phase ^= 1;
+ }
+ while ( time < end_time );
+ this->last_amp = phase ? volume : -volume;
+ }
+ }
+ delay = time - end_time;
+}
+
+// Sms_Noise
+
+static int const noise_periods [3] = { 0x100, 0x200, 0x400 };
+
+inline void Sms_Noise::reset()
+{
+ period = &noise_periods [0];
+ shifter = 0x8000;
+ feedback = 0x9000;
+ Sms_Osc::reset();
+}
+
+void Sms_Noise::run( blip_time_t time, blip_time_t end_time )
+{
+ int amp = volume;
+ if ( shifter & 1 )
+ amp = -amp;
+
+ {
+ int delta = amp - last_amp;
+ if ( delta )
+ {
+ last_amp = amp;
+ synth.offset( time, delta, output );
+ }
+ }
+
+ time += delay;
+ if ( !volume )
+ time = end_time;
+
+ if ( time < end_time )
+ {
+ Blip_Buffer* const output = this->output;
+ unsigned shifter = this->shifter;
+ int delta = amp * 2;
+ int period = *this->period * 2;
+ if ( !period )
+ period = 16;
+
+ do
+ {
+ int changed = shifter + 1;
+ shifter = (feedback & -(shifter & 1)) ^ (shifter >> 1);
+ if ( changed & 2 ) // true if bits 0 and 1 differ
+ {
+ delta = -delta;
+ synth.offset_inline( time, delta, output );
+ }
+ time += period;
+ }
+ while ( time < end_time );
+
+ this->shifter = shifter;
+ this->last_amp = delta >> 1;
+ }
+ delay = time - end_time;
+}
+
+// Sms_Apu
+
+Sms_Apu::Sms_Apu()
+{
+ for ( int i = 0; i < 3; i++ )
+ {
+ squares [i].synth = &square_synth;
+ oscs [i] = &squares [i];
+ }
+ oscs [3] = &noise;
+
+ volume( 1.0 );
+ reset();
+}
+
+Sms_Apu::~Sms_Apu()
+{
+}
+
+void Sms_Apu::volume( double vol )
+{
+ vol *= 0.85 / (osc_count * 64 * 2);
+ square_synth.volume( vol );
+ noise.synth.volume( vol );
+}
+
+void Sms_Apu::treble_eq( const blip_eq_t& eq )
+{
+ square_synth.treble_eq( eq );
+ noise.synth.treble_eq( eq );
+}
+
+void Sms_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
+{
+ require( (unsigned) index < osc_count );
+ require( (center && left && right) || (!center && !left && !right) );
+ Sms_Osc& osc = *oscs [index];
+ osc.outputs [1] = right;
+ osc.outputs [2] = left;
+ osc.outputs [3] = center;
+ osc.output = osc.outputs [osc.output_select];
+}
+
+void Sms_Apu::output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
+{
+ for ( int i = 0; i < osc_count; i++ )
+ osc_output( i, center, left, right );
+}
+
+void Sms_Apu::reset( unsigned feedback, int noise_width )
+{
+ last_time = 0;
+ latch = 0;
+
+ if ( !feedback || !noise_width )
+ {
+ feedback = 0x0009;
+ noise_width = 16;
+ }
+ // convert to "Galios configuration"
+ looped_feedback = 1 << (noise_width - 1);
+ noise_feedback = 0;
+ while ( noise_width-- )
+ {
+ noise_feedback = (noise_feedback << 1) | (feedback & 1);
+ feedback >>= 1;
+ }
+
+ squares [0].reset();
+ squares [1].reset();
+ squares [2].reset();
+ noise.reset();
+}
+
+void Sms_Apu::run_until( blip_time_t end_time )
+{
+ require( end_time >= last_time ); // end_time must not be before previous time
+
+ if ( end_time > last_time )
+ {
+ // run oscillators
+ for ( int i = 0; i < osc_count; ++i )
+ {
+ Sms_Osc& osc = *oscs [i];
+ if ( osc.output )
+ {
+ osc.output->set_modified();
+ if ( i < 3 )
+ squares [i].run( last_time, end_time );
+ else
+ noise.run( last_time, end_time );
+ }
+ }
+
+ last_time = end_time;
+ }
+}
+
+void Sms_Apu::end_frame( blip_time_t end_time )
+{
+ if ( end_time > last_time )
+ run_until( end_time );
+
+ assert( last_time >= end_time );
+ last_time -= end_time;
+}
+
+void Sms_Apu::write_ggstereo( blip_time_t time, int data )
+{
+ require( (unsigned) data <= 0xFF );
+
+ run_until( time );
+
+ for ( int i = 0; i < osc_count; i++ )
+ {
+ Sms_Osc& osc = *oscs [i];
+ int flags = data >> i;
+ Blip_Buffer* old_output = osc.output;
+ osc.output_select = (flags >> 3 & 2) | (flags & 1);
+ osc.output = osc.outputs [osc.output_select];
+ if ( osc.output != old_output && osc.last_amp )
+ {
+ if ( old_output )
+ {
+ old_output->set_modified();
+ square_synth.offset( time, -osc.last_amp, old_output );
+ }
+ osc.last_amp = 0;
+ }
+ }
+}
+
+// volumes [i] = 64 * pow( 1.26, 15 - i ) / pow( 1.26, 15 )
+static unsigned char const volumes [16] = {
+ 64, 50, 39, 31, 24, 19, 15, 12, 9, 7, 5, 4, 3, 2, 1, 0
+};
+
+void Sms_Apu::write_data( blip_time_t time, int data )
+{
+ require( (unsigned) data <= 0xFF );
+
+ run_until( time );
+
+ if ( data & 0x80 )
+ latch = data;
+
+ int index = (latch >> 5) & 3;
+ if ( latch & 0x10 )
+ {
+ oscs [index]->volume = volumes [data & 15];
+ }
+ else if ( index < 3 )
+ {
+ Sms_Square& sq = squares [index];
+ if ( data & 0x80 )
+ sq.period = (sq.period & 0xFF00) | (data << 4 & 0x00FF);
+ else
+ sq.period = (sq.period & 0x00FF) | (data << 8 & 0x3F00);
+ }
+ else
+ {
+ int select = data & 3;
+ if ( select < 3 )
+ noise.period = &noise_periods [select];
+ else
+ noise.period = &squares [2].period;
+
+ noise.feedback = (data & 0x04) ? noise_feedback : looped_feedback;
+ noise.shifter = 0x8000;
+ }
+}
diff --git a/src/console/Sms_Apu.cxx b/src/console/Sms_Apu.cxx
deleted file mode 100644
index 7a91385f4786..000000000000
--- a/src/console/Sms_Apu.cxx
+++ /dev/null
@@ -1,330 +0,0 @@
-// Sms_Snd_Emu 0.1.4. http://www.slack.net/~ant/
-
-#include "Sms_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Sms_Osc
-
-Sms_Osc::Sms_Osc()
-{
- output = 0;
- outputs [0] = 0; // always stays NULL
- outputs [1] = 0;
- outputs [2] = 0;
- outputs [3] = 0;
-}
-
-void Sms_Osc::reset()
-{
- delay = 0;
- last_amp = 0;
- volume = 0;
- output_select = 3;
- output = outputs [3];
-}
-
-// Sms_Square
-
-inline void Sms_Square::reset()
-{
- period = 0;
- phase = 0;
- Sms_Osc::reset();
-}
-
-void Sms_Square::run( blip_time_t time, blip_time_t end_time )
-{
- if ( !volume || period <= 128 )
- {
- // ignore 16kHz and higher
- if ( last_amp )
- {
- synth->offset( time, -last_amp, output );
- last_amp = 0;
- }
- time += delay;
- if ( !period )
- {
- time = end_time;
- }
- else if ( time < end_time )
- {
- // keep calculating phase
- int count = (end_time - time + period - 1) / period;
- phase = (phase + count) & 1;
- time += count * period;
- }
- }
- else
- {
- int amp = phase ? volume : -volume;
- {
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
- int delta = amp * 2;
- do
- {
- delta = -delta;
- synth->offset_inline( time, delta, output );
- time += period;
- phase ^= 1;
- }
- while ( time < end_time );
- this->last_amp = phase ? volume : -volume;
- }
- }
- delay = time - end_time;
-}
-
-// Sms_Noise
-
-static int const noise_periods [3] = { 0x100, 0x200, 0x400 };
-
-inline void Sms_Noise::reset()
-{
- period = &noise_periods [0];
- shifter = 0x8000;
- feedback = 0x9000;
- Sms_Osc::reset();
-}
-
-void Sms_Noise::run( blip_time_t time, blip_time_t end_time )
-{
- int amp = volume;
- if ( shifter & 1 )
- amp = -amp;
-
- {
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth.offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( !volume )
- time = end_time;
-
- if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
- unsigned shifter = this->shifter;
- int delta = amp * 2;
- int period = *this->period * 2;
- if ( !period )
- period = 16;
-
- do
- {
- int changed = shifter + 1;
- shifter = (feedback & -(shifter & 1)) ^ (shifter >> 1);
- if ( changed & 2 ) // true if bits 0 and 1 differ
- {
- delta = -delta;
- synth.offset_inline( time, delta, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- this->shifter = shifter;
- this->last_amp = delta >> 1;
- }
- delay = time - end_time;
-}
-
-// Sms_Apu
-
-Sms_Apu::Sms_Apu()
-{
- for ( int i = 0; i < 3; i++ )
- {
- squares [i].synth = &square_synth;
- oscs [i] = &squares [i];
- }
- oscs [3] = &noise;
-
- volume( 1.0 );
- reset();
-}
-
-Sms_Apu::~Sms_Apu()
-{
-}
-
-void Sms_Apu::volume( double vol )
-{
- vol *= 0.85 / (osc_count * 64 * 2);
- square_synth.volume( vol );
- noise.synth.volume( vol );
-}
-
-void Sms_Apu::treble_eq( const blip_eq_t& eq )
-{
- square_synth.treble_eq( eq );
- noise.synth.treble_eq( eq );
-}
-
-void Sms_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- require( (unsigned) index < osc_count );
- require( (center && left && right) || (!center && !left && !right) );
- Sms_Osc& osc = *oscs [index];
- osc.outputs [1] = right;
- osc.outputs [2] = left;
- osc.outputs [3] = center;
- osc.output = osc.outputs [osc.output_select];
-}
-
-void Sms_Apu::output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, center, left, right );
-}
-
-void Sms_Apu::reset( unsigned feedback, int noise_width )
-{
- last_time = 0;
- latch = 0;
-
- if ( !feedback || !noise_width )
- {
- feedback = 0x0009;
- noise_width = 16;
- }
- // convert to "Galios configuration"
- looped_feedback = 1 << (noise_width - 1);
- noise_feedback = 0;
- while ( noise_width-- )
- {
- noise_feedback = (noise_feedback << 1) | (feedback & 1);
- feedback >>= 1;
- }
-
- squares [0].reset();
- squares [1].reset();
- squares [2].reset();
- noise.reset();
-}
-
-void Sms_Apu::run_until( blip_time_t end_time )
-{
- require( end_time >= last_time ); // end_time must not be before previous time
-
- if ( end_time > last_time )
- {
- // run oscillators
- for ( int i = 0; i < osc_count; ++i )
- {
- Sms_Osc& osc = *oscs [i];
- if ( osc.output )
- {
- osc.output->set_modified();
- if ( i < 3 )
- squares [i].run( last_time, end_time );
- else
- noise.run( last_time, end_time );
- }
- }
-
- last_time = end_time;
- }
-}
-
-void Sms_Apu::end_frame( blip_time_t end_time )
-{
- if ( end_time > last_time )
- run_until( end_time );
-
- assert( last_time >= end_time );
- last_time -= end_time;
-}
-
-void Sms_Apu::write_ggstereo( blip_time_t time, int data )
-{
- require( (unsigned) data <= 0xFF );
-
- run_until( time );
-
- for ( int i = 0; i < osc_count; i++ )
- {
- Sms_Osc& osc = *oscs [i];
- int flags = data >> i;
- Blip_Buffer* old_output = osc.output;
- osc.output_select = (flags >> 3 & 2) | (flags & 1);
- osc.output = osc.outputs [osc.output_select];
- if ( osc.output != old_output && osc.last_amp )
- {
- if ( old_output )
- {
- old_output->set_modified();
- square_synth.offset( time, -osc.last_amp, old_output );
- }
- osc.last_amp = 0;
- }
- }
-}
-
-// volumes [i] = 64 * pow( 1.26, 15 - i ) / pow( 1.26, 15 )
-static unsigned char const volumes [16] = {
- 64, 50, 39, 31, 24, 19, 15, 12, 9, 7, 5, 4, 3, 2, 1, 0
-};
-
-void Sms_Apu::write_data( blip_time_t time, int data )
-{
- require( (unsigned) data <= 0xFF );
-
- run_until( time );
-
- if ( data & 0x80 )
- latch = data;
-
- int index = (latch >> 5) & 3;
- if ( latch & 0x10 )
- {
- oscs [index]->volume = volumes [data & 15];
- }
- else if ( index < 3 )
- {
- Sms_Square& sq = squares [index];
- if ( data & 0x80 )
- sq.period = (sq.period & 0xFF00) | (data << 4 & 0x00FF);
- else
- sq.period = (sq.period & 0x00FF) | (data << 8 & 0x3F00);
- }
- else
- {
- int select = data & 3;
- if ( select < 3 )
- noise.period = &noise_periods [select];
- else
- noise.period = &squares [2].period;
-
- noise.feedback = (data & 0x04) ? noise_feedback : looped_feedback;
- noise.shifter = 0x8000;
- }
-}
diff --git a/src/console/Sms_Apu.h b/src/console/Sms_Apu.h
index ec8bc87ec379..c8401f10aab5 100644
--- a/src/console/Sms_Apu.h
+++ b/src/console/Sms_Apu.h
@@ -18,12 +18,12 @@ public:
// buffers for stereo output (using Stereo_Buffer to do the mixing).
// Assign all oscillator outputs to specified buffer(s). If buffer
- // is NULL, silences all oscillators.
+ // is nullptr, silences all oscillators.
void output( Blip_Buffer* mono );
void output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
// Assign single oscillator output to buffer(s). Valid indicies are 0 to 3,
- // which refer to Square 1, Square 2, Square 3, and Noise. If buffer is NULL,
+ // which refer to Square 1, Square 2, Square 3, and Noise. If buffer is nullptr,
// silences oscillator.
enum { osc_count = 4 };
void osc_output( int index, Blip_Buffer* mono );
diff --git a/src/console/Sms_Oscs.h b/src/console/Sms_Oscs.h
index 282cb18a0af4..ba7e14d90d67 100644
--- a/src/console/Sms_Oscs.h
+++ b/src/console/Sms_Oscs.h
@@ -9,7 +9,7 @@
struct Sms_Osc
{
- Blip_Buffer* outputs [4]; // NULL, right, left, center
+ Blip_Buffer* outputs [4]; // nullptr, right, left, center
Blip_Buffer* output;
int output_select;
diff --git a/src/console/Snes_Spc.cc b/src/console/Snes_Spc.cc
new file mode 100644
index 000000000000..2b2e9eff229f
--- /dev/null
+++ b/src/console/Snes_Spc.cc
@@ -0,0 +1,380 @@
+// SPC emulation support: init, sample buffering, reset, SPC loading
+
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Snes_Spc.h"
+
+#include <string.h>
+
+/* Copyright (C) 2004-2007 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+#define RAM (m.ram.ram)
+#define REGS (m.smp_regs [0])
+#define REGS_IN (m.smp_regs [1])
+
+// (n ? n : 256)
+#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1)
+
+
+//// Init
+
+blargg_err_t Snes_Spc::init()
+{
+ memset( &m, 0, sizeof m );
+ dsp.init( RAM );
+
+ m.tempo = tempo_unit;
+
+ // Most SPC music doesn't need ROM, and almost all the rest only rely
+ // on these two bytes
+ m.rom [0x3E] = 0xFF;
+ m.rom [0x3F] = 0xC0;
+
+ static unsigned char const cycle_table [128] =
+ {// 01 23 45 67 89 AB CD EF
+ 0x28,0x47,0x34,0x36,0x26,0x54,0x54,0x68, // 0
+ 0x48,0x47,0x45,0x56,0x55,0x65,0x22,0x46, // 1
+ 0x28,0x47,0x34,0x36,0x26,0x54,0x54,0x74, // 2
+ 0x48,0x47,0x45,0x56,0x55,0x65,0x22,0x38, // 3
+ 0x28,0x47,0x34,0x36,0x26,0x44,0x54,0x66, // 4
+ 0x48,0x47,0x45,0x56,0x55,0x45,0x22,0x43, // 5
+ 0x28,0x47,0x34,0x36,0x26,0x44,0x54,0x75, // 6
+ 0x48,0x47,0x45,0x56,0x55,0x55,0x22,0x36, // 7
+ 0x28,0x47,0x34,0x36,0x26,0x54,0x52,0x45, // 8
+ 0x48,0x47,0x45,0x56,0x55,0x55,0x22,0xC5, // 9
+ 0x38,0x47,0x34,0x36,0x26,0x44,0x52,0x44, // A
+ 0x48,0x47,0x45,0x56,0x55,0x55,0x22,0x34, // B
+ 0x38,0x47,0x45,0x47,0x25,0x64,0x52,0x49, // C
+ 0x48,0x47,0x56,0x67,0x45,0x55,0x22,0x83, // D
+ 0x28,0x47,0x34,0x36,0x24,0x53,0x43,0x40, // E
+ 0x48,0x47,0x45,0x56,0x34,0x54,0x22,0x60, // F
+ };
+
+ // unpack cycle table
+ for ( int i = 0; i < 128; i++ )
+ {
+ int n = cycle_table [i];
+ m.cycle_table [i * 2 + 0] = n >> 4;
+ m.cycle_table [i * 2 + 1] = n & 0x0F;
+ }
+
+ #if SPC_LESS_ACCURATE
+ memcpy( reg_times, reg_times_, sizeof reg_times );
+ #endif
+
+ reset();
+ return 0;
+}
+
+void Snes_Spc::init_rom( uint8_t const in [rom_size] )
+{
+ memcpy( m.rom, in, sizeof m.rom );
+}
+
+void Snes_Spc::set_tempo( int t )
+{
+ m.tempo = t;
+ int const timer2_shift = 4; // 64 kHz
+ int const other_shift = 3; // 8 kHz
+
+ #if SPC_DISABLE_TEMPO
+ m.timers [2].prescaler = timer2_shift;
+ m.timers [1].prescaler = timer2_shift + other_shift;
+ m.timers [0].prescaler = timer2_shift + other_shift;
+ #else
+ if ( !t )
+ t = 1;
+ int const timer2_rate = 1 << timer2_shift;
+ int rate = (timer2_rate * tempo_unit + (t >> 1)) / t;
+ if ( rate < timer2_rate / 4 )
+ rate = timer2_rate / 4; // max 4x tempo
+ m.timers [2].prescaler = rate;
+ m.timers [1].prescaler = rate << other_shift;
+ m.timers [0].prescaler = rate << other_shift;
+ #endif
+}
+
+// Timer registers have been loaded. Applies these to the timers. Does not
+// reset timer prescalers or dividers.
+void Snes_Spc::timers_loaded()
+{
+ int i;
+ for ( i = 0; i < timer_count; i++ )
+ {
+ Timer* t = &m.timers [i];
+ t->period = IF_0_THEN_256( REGS [r_t0target + i] );
+ t->enabled = REGS [r_control] >> i & 1;
+ t->counter = REGS_IN [r_t0out + i] & 0x0F;
+ }
+
+ set_tempo( m.tempo );
+}
+
+// Loads registers from unified 16-byte format
+void Snes_Spc::load_regs( uint8_t const in [reg_count] )
+{
+ memcpy( REGS, in, reg_count );
+ memcpy( REGS_IN, REGS, reg_count );
+
+ // These always read back as 0
+ REGS_IN [r_test ] = 0;
+ REGS_IN [r_control ] = 0;
+ REGS_IN [r_t0target] = 0;
+ REGS_IN [r_t1target] = 0;
+ REGS_IN [r_t2target] = 0;
+}
+
+// RAM was just loaded from SPC, with $F0-$FF containing SMP registers
+// and timer counts. Copies these to proper registers.
+void Snes_Spc::ram_loaded()
+{
+ m.rom_enabled = 0;
+ load_regs( &RAM [0xF0] );
+
+ // Put STOP instruction around memory to catch PC underflow/overflow
+ memset( m.ram.padding1, cpu_pad_fill, sizeof m.ram.padding1 );
+ memset( m.ram.padding2, cpu_pad_fill, sizeof m.ram.padding2 );
+}
+
+// Registers were just loaded. Applies these new values.
+void Snes_Spc::regs_loaded()
+{
+ enable_rom( REGS [r_control] & 0x80 );
+ timers_loaded();
+}
+
+void Snes_Spc::reset_time_regs()
+{
+ m.cpu_error = 0;
+ m.echo_accessed = 0;
+ m.spc_time = 0;
+ m.dsp_time = 0;
+ #if SPC_LESS_ACCURATE
+ m.dsp_time = clocks_per_sample + 1;
+ #endif
+
+ for ( int i = 0; i < timer_count; i++ )
+ {
+ Timer* t = &m.timers [i];
+ t->next_time = 1;
+ t->divider = 0;
+ }
+
+ regs_loaded();
+
+ m.extra_clocks = 0;
+ reset_buf();
+}
+
+void Snes_Spc::reset_common( int timer_counter_init )
+{
+ int i;
+ for ( i = 0; i < timer_count; i++ )
+ REGS_IN [r_t0out + i] = timer_counter_init;
+
+ // Run IPL ROM
+ memset( &m.cpu_regs, 0, sizeof m.cpu_regs );
+ m.cpu_regs.pc = rom_addr;
+
+ REGS [r_test ] = 0x0A;
+ REGS [r_control] = 0xB0; // ROM enabled, clear ports
+ for ( i = 0; i < port_count; i++ )
+ REGS_IN [r_cpuio0 + i] = 0;
+
+ reset_time_regs();
+}
+
+void Snes_Spc::soft_reset()
+{
+ reset_common( 0 );
+ dsp.soft_reset();
+}
+
+void Snes_Spc::reset()
+{
+ memset( RAM, 0xFF, 0x10000 );
+ ram_loaded();
+ reset_common( 0x0F );
+ dsp.reset();
+}
+
+char const Snes_Spc::signature [signature_size + 1] =
+ "SNES-SPC700 Sound File Data v0.30\x1A\x1A";
+
+blargg_err_t Snes_Spc::load_spc( void const* data, long size )
+{
+ spc_file_t const* const spc = (spc_file_t const*) data;
+
+ // be sure compiler didn't insert any padding into fle_t
+ assert( sizeof (spc_file_t) == spc_min_file_size + 0x80 );
+
+ // Check signature and file size
+ if ( size < signature_size || memcmp( spc, signature, 27 ) )
+ return "Not an SPC file";
+
+ if ( size < spc_min_file_size )
+ return "Corrupt SPC file";
+
+ // CPU registers
+ m.cpu_regs.pc = spc->pch * 0x100 + spc->pcl;
+ m.cpu_regs.a = spc->a;
+ m.cpu_regs.x = spc->x;
+ m.cpu_regs.y = spc->y;
+ m.cpu_regs.psw = spc->psw;
+ m.cpu_regs.sp = spc->sp;
+
+ // RAM and registers
+ memcpy( RAM, spc->ram, 0x10000 );
+ ram_loaded();
+
+ // DSP registers
+ dsp.load( spc->dsp );
+
+ reset_time_regs();
+
+ return 0;
+}
+
+void Snes_Spc::clear_echo()
+{
+ if ( !(dsp.read( Spc_Dsp::r_flg ) & 0x20) )
+ {
+ int addr = 0x100 * dsp.read( Spc_Dsp::r_esa );
+ int end = addr + 0x800 * (dsp.read( Spc_Dsp::r_edl ) & 0x0F);
+ if ( end > 0x10000 )
+ end = 0x10000;
+ memset( &RAM [addr], 0xFF, end - addr );
+ }
+}
+
+
+//// Sample output
+
+void Snes_Spc::reset_buf()
+{
+ // Start with half extra buffer of silence
+ sample_t* out = m.extra_buf;
+ while ( out < &m.extra_buf [extra_size / 2] )
+ *out++ = 0;
+
+ m.extra_pos = out;
+ m.buf_begin = 0;
+
+ dsp.set_output( 0, 0 );
+}
+
+void Snes_Spc::set_output( sample_t* out, int size )
+{
+ require( (size & 1) == 0 ); // size must be even
+
+ m.extra_clocks &= clocks_per_sample - 1;
+ if ( out )
+ {
+ sample_t const* out_end = out + size;
+ m.buf_begin = out;
+ m.buf_end = out_end;
+
+ // Copy extra to output
+ sample_t const* in = m.extra_buf;
+ while ( in < m.extra_pos && out < out_end )
+ *out++ = *in++;
+
+ // Handle output being full already
+ if ( out >= out_end )
+ {
+ // Have DSP write to remaining extra space
+ out = dsp.extra();
+ out_end = &dsp.extra() [extra_size];
+
+ // Copy any remaining extra samples as if DSP wrote them
+ while ( in < m.extra_pos )
+ *out++ = *in++;
+ assert( out <= out_end );
+ }
+
+ dsp.set_output( out, out_end - out );
+ }
+ else
+ {
+ reset_buf();
+ }
+}
+
+void Snes_Spc::save_extra()
+{
+ // Get end pointers
+ sample_t const* main_end = m.buf_end; // end of data written to buf
+ sample_t const* dsp_end = dsp.out_pos(); // end of data written to dsp.extra()
+ if ( m.buf_begin <= dsp_end && dsp_end <= main_end )
+ {
+ main_end = dsp_end;
+ dsp_end = dsp.extra(); // nothing in DSP's extra
+ }
+
+ // Copy any extra samples at these ends into extra_buf
+ sample_t* out = m.extra_buf;
+ sample_t const* in;
+ for ( in = m.buf_begin + sample_count(); in < main_end; in++ )
+ *out++ = *in;
+ for ( in = dsp.extra(); in < dsp_end ; in++ )
+ *out++ = *in;
+
+ m.extra_pos = out;
+ assert( out <= &m.extra_buf [extra_size] );
+}
+
+blargg_err_t Snes_Spc::play( int count, sample_t* out )
+{
+ require( (count & 1) == 0 ); // must be even
+ if ( count )
+ {
+ set_output( out, count );
+ end_frame( count * (clocks_per_sample / 2) );
+ }
+
+ const char* err = m.cpu_error;
+ m.cpu_error = 0;
+ return err;
+}
+
+blargg_err_t Snes_Spc::skip( int count )
+{
+ #if SPC_LESS_ACCURATE
+ if ( count > 2 * sample_rate * 2 )
+ {
+ set_output( 0, 0 );
+
+ // Skip a multiple of 4 samples
+ time_t end = count;
+ count = (count & 3) + 1 * sample_rate * 2;
+ end = (end - count) * (clocks_per_sample / 2);
+
+ m.skipped_kon = 0;
+ m.skipped_koff = 0;
+
+ // Preserve DSP and timer synchronization
+ // TODO: verify that this really preserves it
+ int old_dsp_time = m.dsp_time + m.spc_time;
+ m.dsp_time = end - m.spc_time + skipping_time;
+ end_frame( end );
+ m.dsp_time = m.dsp_time - skipping_time + old_dsp_time;
+
+ dsp.write( Spc_Dsp::r_koff, m.skipped_koff & ~m.skipped_kon );
+ dsp.write( Spc_Dsp::r_kon , m.skipped_kon );
+ clear_echo();
+ }
+ #endif
+
+ return play( count, 0 );
+}
diff --git a/src/console/Snes_Spc.cxx b/src/console/Snes_Spc.cxx
deleted file mode 100644
index 2b2e9eff229f..000000000000
--- a/src/console/Snes_Spc.cxx
+++ /dev/null
@@ -1,380 +0,0 @@
-// SPC emulation support: init, sample buffering, reset, SPC loading
-
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Snes_Spc.h"
-
-#include <string.h>
-
-/* Copyright (C) 2004-2007 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#define RAM (m.ram.ram)
-#define REGS (m.smp_regs [0])
-#define REGS_IN (m.smp_regs [1])
-
-// (n ? n : 256)
-#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1)
-
-
-//// Init
-
-blargg_err_t Snes_Spc::init()
-{
- memset( &m, 0, sizeof m );
- dsp.init( RAM );
-
- m.tempo = tempo_unit;
-
- // Most SPC music doesn't need ROM, and almost all the rest only rely
- // on these two bytes
- m.rom [0x3E] = 0xFF;
- m.rom [0x3F] = 0xC0;
-
- static unsigned char const cycle_table [128] =
- {// 01 23 45 67 89 AB CD EF
- 0x28,0x47,0x34,0x36,0x26,0x54,0x54,0x68, // 0
- 0x48,0x47,0x45,0x56,0x55,0x65,0x22,0x46, // 1
- 0x28,0x47,0x34,0x36,0x26,0x54,0x54,0x74, // 2
- 0x48,0x47,0x45,0x56,0x55,0x65,0x22,0x38, // 3
- 0x28,0x47,0x34,0x36,0x26,0x44,0x54,0x66, // 4
- 0x48,0x47,0x45,0x56,0x55,0x45,0x22,0x43, // 5
- 0x28,0x47,0x34,0x36,0x26,0x44,0x54,0x75, // 6
- 0x48,0x47,0x45,0x56,0x55,0x55,0x22,0x36, // 7
- 0x28,0x47,0x34,0x36,0x26,0x54,0x52,0x45, // 8
- 0x48,0x47,0x45,0x56,0x55,0x55,0x22,0xC5, // 9
- 0x38,0x47,0x34,0x36,0x26,0x44,0x52,0x44, // A
- 0x48,0x47,0x45,0x56,0x55,0x55,0x22,0x34, // B
- 0x38,0x47,0x45,0x47,0x25,0x64,0x52,0x49, // C
- 0x48,0x47,0x56,0x67,0x45,0x55,0x22,0x83, // D
- 0x28,0x47,0x34,0x36,0x24,0x53,0x43,0x40, // E
- 0x48,0x47,0x45,0x56,0x34,0x54,0x22,0x60, // F
- };
-
- // unpack cycle table
- for ( int i = 0; i < 128; i++ )
- {
- int n = cycle_table [i];
- m.cycle_table [i * 2 + 0] = n >> 4;
- m.cycle_table [i * 2 + 1] = n & 0x0F;
- }
-
- #if SPC_LESS_ACCURATE
- memcpy( reg_times, reg_times_, sizeof reg_times );
- #endif
-
- reset();
- return 0;
-}
-
-void Snes_Spc::init_rom( uint8_t const in [rom_size] )
-{
- memcpy( m.rom, in, sizeof m.rom );
-}
-
-void Snes_Spc::set_tempo( int t )
-{
- m.tempo = t;
- int const timer2_shift = 4; // 64 kHz
- int const other_shift = 3; // 8 kHz
-
- #if SPC_DISABLE_TEMPO
- m.timers [2].prescaler = timer2_shift;
- m.timers [1].prescaler = timer2_shift + other_shift;
- m.timers [0].prescaler = timer2_shift + other_shift;
- #else
- if ( !t )
- t = 1;
- int const timer2_rate = 1 << timer2_shift;
- int rate = (timer2_rate * tempo_unit + (t >> 1)) / t;
- if ( rate < timer2_rate / 4 )
- rate = timer2_rate / 4; // max 4x tempo
- m.timers [2].prescaler = rate;
- m.timers [1].prescaler = rate << other_shift;
- m.timers [0].prescaler = rate << other_shift;
- #endif
-}
-
-// Timer registers have been loaded. Applies these to the timers. Does not
-// reset timer prescalers or dividers.
-void Snes_Spc::timers_loaded()
-{
- int i;
- for ( i = 0; i < timer_count; i++ )
- {
- Timer* t = &m.timers [i];
- t->period = IF_0_THEN_256( REGS [r_t0target + i] );
- t->enabled = REGS [r_control] >> i & 1;
- t->counter = REGS_IN [r_t0out + i] & 0x0F;
- }
-
- set_tempo( m.tempo );
-}
-
-// Loads registers from unified 16-byte format
-void Snes_Spc::load_regs( uint8_t const in [reg_count] )
-{
- memcpy( REGS, in, reg_count );
- memcpy( REGS_IN, REGS, reg_count );
-
- // These always read back as 0
- REGS_IN [r_test ] = 0;
- REGS_IN [r_control ] = 0;
- REGS_IN [r_t0target] = 0;
- REGS_IN [r_t1target] = 0;
- REGS_IN [r_t2target] = 0;
-}
-
-// RAM was just loaded from SPC, with $F0-$FF containing SMP registers
-// and timer counts. Copies these to proper registers.
-void Snes_Spc::ram_loaded()
-{
- m.rom_enabled = 0;
- load_regs( &RAM [0xF0] );
-
- // Put STOP instruction around memory to catch PC underflow/overflow
- memset( m.ram.padding1, cpu_pad_fill, sizeof m.ram.padding1 );
- memset( m.ram.padding2, cpu_pad_fill, sizeof m.ram.padding2 );
-}
-
-// Registers were just loaded. Applies these new values.
-void Snes_Spc::regs_loaded()
-{
- enable_rom( REGS [r_control] & 0x80 );
- timers_loaded();
-}
-
-void Snes_Spc::reset_time_regs()
-{
- m.cpu_error = 0;
- m.echo_accessed = 0;
- m.spc_time = 0;
- m.dsp_time = 0;
- #if SPC_LESS_ACCURATE
- m.dsp_time = clocks_per_sample + 1;
- #endif
-
- for ( int i = 0; i < timer_count; i++ )
- {
- Timer* t = &m.timers [i];
- t->next_time = 1;
- t->divider = 0;
- }
-
- regs_loaded();
-
- m.extra_clocks = 0;
- reset_buf();
-}
-
-void Snes_Spc::reset_common( int timer_counter_init )
-{
- int i;
- for ( i = 0; i < timer_count; i++ )
- REGS_IN [r_t0out + i] = timer_counter_init;
-
- // Run IPL ROM
- memset( &m.cpu_regs, 0, sizeof m.cpu_regs );
- m.cpu_regs.pc = rom_addr;
-
- REGS [r_test ] = 0x0A;
- REGS [r_control] = 0xB0; // ROM enabled, clear ports
- for ( i = 0; i < port_count; i++ )
- REGS_IN [r_cpuio0 + i] = 0;
-
- reset_time_regs();
-}
-
-void Snes_Spc::soft_reset()
-{
- reset_common( 0 );
- dsp.soft_reset();
-}
-
-void Snes_Spc::reset()
-{
- memset( RAM, 0xFF, 0x10000 );
- ram_loaded();
- reset_common( 0x0F );
- dsp.reset();
-}
-
-char const Snes_Spc::signature [signature_size + 1] =
- "SNES-SPC700 Sound File Data v0.30\x1A\x1A";
-
-blargg_err_t Snes_Spc::load_spc( void const* data, long size )
-{
- spc_file_t const* const spc = (spc_file_t const*) data;
-
- // be sure compiler didn't insert any padding into fle_t
- assert( sizeof (spc_file_t) == spc_min_file_size + 0x80 );
-
- // Check signature and file size
- if ( size < signature_size || memcmp( spc, signature, 27 ) )
- return "Not an SPC file";
-
- if ( size < spc_min_file_size )
- return "Corrupt SPC file";
-
- // CPU registers
- m.cpu_regs.pc = spc->pch * 0x100 + spc->pcl;
- m.cpu_regs.a = spc->a;
- m.cpu_regs.x = spc->x;
- m.cpu_regs.y = spc->y;
- m.cpu_regs.psw = spc->psw;
- m.cpu_regs.sp = spc->sp;
-
- // RAM and registers
- memcpy( RAM, spc->ram, 0x10000 );
- ram_loaded();
-
- // DSP registers
- dsp.load( spc->dsp );
-
- reset_time_regs();
-
- return 0;
-}
-
-void Snes_Spc::clear_echo()
-{
- if ( !(dsp.read( Spc_Dsp::r_flg ) & 0x20) )
- {
- int addr = 0x100 * dsp.read( Spc_Dsp::r_esa );
- int end = addr + 0x800 * (dsp.read( Spc_Dsp::r_edl ) & 0x0F);
- if ( end > 0x10000 )
- end = 0x10000;
- memset( &RAM [addr], 0xFF, end - addr );
- }
-}
-
-
-//// Sample output
-
-void Snes_Spc::reset_buf()
-{
- // Start with half extra buffer of silence
- sample_t* out = m.extra_buf;
- while ( out < &m.extra_buf [extra_size / 2] )
- *out++ = 0;
-
- m.extra_pos = out;
- m.buf_begin = 0;
-
- dsp.set_output( 0, 0 );
-}
-
-void Snes_Spc::set_output( sample_t* out, int size )
-{
- require( (size & 1) == 0 ); // size must be even
-
- m.extra_clocks &= clocks_per_sample - 1;
- if ( out )
- {
- sample_t const* out_end = out + size;
- m.buf_begin = out;
- m.buf_end = out_end;
-
- // Copy extra to output
- sample_t const* in = m.extra_buf;
- while ( in < m.extra_pos && out < out_end )
- *out++ = *in++;
-
- // Handle output being full already
- if ( out >= out_end )
- {
- // Have DSP write to remaining extra space
- out = dsp.extra();
- out_end = &dsp.extra() [extra_size];
-
- // Copy any remaining extra samples as if DSP wrote them
- while ( in < m.extra_pos )
- *out++ = *in++;
- assert( out <= out_end );
- }
-
- dsp.set_output( out, out_end - out );
- }
- else
- {
- reset_buf();
- }
-}
-
-void Snes_Spc::save_extra()
-{
- // Get end pointers
- sample_t const* main_end = m.buf_end; // end of data written to buf
- sample_t const* dsp_end = dsp.out_pos(); // end of data written to dsp.extra()
- if ( m.buf_begin <= dsp_end && dsp_end <= main_end )
- {
- main_end = dsp_end;
- dsp_end = dsp.extra(); // nothing in DSP's extra
- }
-
- // Copy any extra samples at these ends into extra_buf
- sample_t* out = m.extra_buf;
- sample_t const* in;
- for ( in = m.buf_begin + sample_count(); in < main_end; in++ )
- *out++ = *in;
- for ( in = dsp.extra(); in < dsp_end ; in++ )
- *out++ = *in;
-
- m.extra_pos = out;
- assert( out <= &m.extra_buf [extra_size] );
-}
-
-blargg_err_t Snes_Spc::play( int count, sample_t* out )
-{
- require( (count & 1) == 0 ); // must be even
- if ( count )
- {
- set_output( out, count );
- end_frame( count * (clocks_per_sample / 2) );
- }
-
- const char* err = m.cpu_error;
- m.cpu_error = 0;
- return err;
-}
-
-blargg_err_t Snes_Spc::skip( int count )
-{
- #if SPC_LESS_ACCURATE
- if ( count > 2 * sample_rate * 2 )
- {
- set_output( 0, 0 );
-
- // Skip a multiple of 4 samples
- time_t end = count;
- count = (count & 3) + 1 * sample_rate * 2;
- end = (end - count) * (clocks_per_sample / 2);
-
- m.skipped_kon = 0;
- m.skipped_koff = 0;
-
- // Preserve DSP and timer synchronization
- // TODO: verify that this really preserves it
- int old_dsp_time = m.dsp_time + m.spc_time;
- m.dsp_time = end - m.spc_time + skipping_time;
- end_frame( end );
- m.dsp_time = m.dsp_time - skipping_time + old_dsp_time;
-
- dsp.write( Spc_Dsp::r_koff, m.skipped_koff & ~m.skipped_kon );
- dsp.write( Spc_Dsp::r_kon , m.skipped_kon );
- clear_echo();
- }
- #endif
-
- return play( count, 0 );
-}
diff --git a/src/console/Snes_Spc.h b/src/console/Snes_Spc.h
index 63f54ad54d51..477ced4de6cd 100644
--- a/src/console/Snes_Spc.h
+++ b/src/console/Snes_Spc.h
@@ -76,7 +76,7 @@ public:
void clear_echo();
// Plays for count samples and write samples to out. Discards samples if out
- // is NULL. Count must be a multiple of 2 since output is stereo.
+ // is nullptr. Count must be a multiple of 2 since output is stereo.
blargg_err_t play( int count, sample_t* out );
// Skips count samples. Several times faster than play() when using fast DSP.
diff --git a/src/console/Spc_Cpu.cc b/src/console/Spc_Cpu.cc
new file mode 100644
index 000000000000..603447e9940b
--- /dev/null
+++ b/src/console/Spc_Cpu.cc
@@ -0,0 +1,565 @@
+// Core SPC emulation: CPU, timers, SMP registers, memory
+
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Snes_Spc.h"
+
+#include <string.h>
+
+/* Copyright (C) 2004-2007 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+#define RAM (m.ram.ram)
+#define REGS (m.smp_regs [0])
+#define REGS_IN (m.smp_regs [1])
+
+// (n ? n : 256)
+#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1)
+
+// Note: SPC_MORE_ACCURACY exists mainly so I can run my validation tests, which
+// do crazy echo buffer accesses.
+#ifndef SPC_MORE_ACCURACY
+ #define SPC_MORE_ACCURACY 0
+#endif
+
+#ifdef BLARGG_ENABLE_OPTIMIZER
+ #include BLARGG_ENABLE_OPTIMIZER
+#endif
+
+
+//// Timers
+
+#if SPC_DISABLE_TEMPO
+ #define TIMER_DIV( t, n ) ((n) >> t->prescaler)
+ #define TIMER_MUL( t, n ) ((n) << t->prescaler)
+#else
+ #define TIMER_DIV( t, n ) ((n) / t->prescaler)
+ #define TIMER_MUL( t, n ) ((n) * t->prescaler)
+#endif
+
+Snes_Spc::Timer* Snes_Spc::run_timer_( Timer* t, rel_time_t time )
+{
+ int elapsed = TIMER_DIV( t, time - t->next_time ) + 1;
+ t->next_time += TIMER_MUL( t, elapsed );
+
+ if ( t->enabled )
+ {
+ int remain = IF_0_THEN_256( t->period - t->divider );
+ int divider = t->divider + elapsed;
+ int over = elapsed - remain;
+ if ( over >= 0 )
+ {
+ int n = over / t->period;
+ t->counter = (t->counter + 1 + n) & 0x0F;
+ divider = over - n * t->period;
+ }
+ t->divider = (uint8_t) divider;
+ }
+ return t;
+}
+
+inline Snes_Spc::Timer* Snes_Spc::run_timer( Timer* t, rel_time_t time )
+{
+ if ( time >= t->next_time )
+ t = run_timer_( t, time );
+ return t;
+}
+
+
+//// ROM
+
+void Snes_Spc::enable_rom( int enable )
+{
+ if ( m.rom_enabled != enable )
+ {
+ m.rom_enabled = enable;
+ if ( enable )
+ memcpy( m.hi_ram, &RAM [rom_addr], sizeof m.hi_ram );
+ memcpy( &RAM [rom_addr], (enable ? m.rom : m.hi_ram), rom_size );
+ // TODO: ROM can still get overwritten when DSP writes to echo buffer
+ }
+}
+
+
+//// DSP
+
+#if SPC_LESS_ACCURATE
+ int const max_reg_time = 29;
+
+ signed char const Snes_Spc::reg_times_ [256] =
+ {
+ -1, 0,-11,-10,-15,-11, -2, -2, 4, 3, 14, 14, 26, 26, 14, 22,
+ 2, 3, 0, 1,-12, 0, 1, 1, 7, 6, 14, 14, 27, 14, 14, 23,
+ 5, 6, 3, 4, -1, 3, 4, 4, 10, 9, 14, 14, 26, -5, 14, 23,
+ 8, 9, 6, 7, 2, 6, 7, 7, 13, 12, 14, 14, 27, -4, 14, 24,
+ 11, 12, 9, 10, 5, 9, 10, 10, 16, 15, 14, 14, -2, -4, 14, 24,
+ 14, 15, 12, 13, 8, 12, 13, 13, 19, 18, 14, 14, -2,-36, 14, 24,
+ 17, 18, 15, 16, 11, 15, 16, 16, 22, 21, 14, 14, 28, -3, 14, 25,
+ 20, 21, 18, 19, 14, 18, 19, 19, 25, 24, 14, 14, 14, 29, 14, 25,
+
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ };
+
+ #define RUN_DSP( time, offset ) \
+ int count = (time) - (offset) - m.dsp_time;\
+ if ( count >= 0 )\
+ {\
+ int clock_count = (count & ~(clocks_per_sample - 1)) + clocks_per_sample;\
+ m.dsp_time += clock_count;\
+ dsp.run( clock_count );\
+ }
+#else
+ #define RUN_DSP( time, offset ) \
+ {\
+ int count = (time) - m.dsp_time;\
+ if ( !SPC_MORE_ACCURACY || count )\
+ {\
+ assert( count > 0 );\
+ m.dsp_time = (time);\
+ dsp.run( count );\
+ }\
+ }
+#endif
+
+int Snes_Spc::dsp_read( rel_time_t time )
+{
+ RUN_DSP( time, reg_times [REGS [r_dspaddr] & 0x7F] );
+
+ int result = dsp.read( REGS [r_dspaddr] & 0x7F );
+
+ #ifdef SPC_DSP_READ_HOOK
+ SPC_DSP_READ_HOOK( spc_time + time, (REGS [r_dspaddr] & 0x7F), result );
+ #endif
+
+ return result;
+}
+
+inline void Snes_Spc::dsp_write( int data, rel_time_t time )
+{
+ RUN_DSP( time, reg_times [REGS [r_dspaddr]] )
+ #if SPC_LESS_ACCURATE
+ else if ( m.dsp_time == skipping_time )
+ {
+ int r = REGS [r_dspaddr];
+ if ( r == Spc_Dsp::r_kon )
+ m.skipped_kon |= data & ~dsp.read( Spc_Dsp::r_koff );
+
+ if ( r == Spc_Dsp::r_koff )
+ {
+ m.skipped_koff |= data;
+ m.skipped_kon &= ~data;
+ }
+ }
+ #endif
+
+ #ifdef SPC_DSP_WRITE_HOOK
+ SPC_DSP_WRITE_HOOK( m.spc_time + time, REGS [r_dspaddr], (uint8_t) data );
+ #endif
+
+ if ( REGS [r_dspaddr] <= 0x7F )
+ dsp.write( REGS [r_dspaddr], data );
+ else if ( !SPC_MORE_ACCURACY )
+ debug_printf( "SPC wrote to DSP register > $7F\n" );
+}
+
+
+//// Memory access extras
+
+#if SPC_MORE_ACCURACY
+ #define MEM_ACCESS( time, addr ) \
+ {\
+ if ( time >= m.dsp_time )\
+ {\
+ RUN_DSP( time, max_reg_time );\
+ }\
+ }
+#elif !defined (NDEBUG)
+ // Debug-only check for read/write within echo buffer, since this might result in
+ // inaccurate emulation due to the DSP not being caught up to the present.
+
+ bool Snes_Spc::check_echo_access( int addr )
+ {
+ if ( !(dsp.read( Spc_Dsp::r_flg ) & 0x20) )
+ {
+ int start = 0x100 * dsp.read( Spc_Dsp::r_esa );
+ int size = 0x800 * (dsp.read( Spc_Dsp::r_edl ) & 0x0F);
+ int end = start + (size ? size : 4);
+ if ( start <= addr && addr < end )
+ {
+ if ( !m.echo_accessed )
+ {
+ m.echo_accessed = 1;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ #define MEM_ACCESS( time, addr ) check( !check_echo_access( (uint16_t) addr ) );
+#else
+ #define MEM_ACCESS( time, addr )
+#endif
+
+
+//// CPU write
+
+#if SPC_MORE_ACCURACY
+static unsigned char const glitch_probs [3] [256] =
+{
+ 0xC3,0x92,0x5B,0x1C,0xD1,0x92,0x5B,0x1C,0xDB,0x9C,0x72,0x18,0xCD,0x5C,0x38,0x0B,
+ 0xE1,0x9C,0x74,0x17,0xCF,0x75,0x45,0x0C,0xCF,0x6E,0x4A,0x0D,0xA3,0x3A,0x1D,0x08,
+ 0xDB,0xA0,0x82,0x19,0xD9,0x73,0x3C,0x0E,0xCB,0x76,0x52,0x0B,0xA5,0x46,0x1D,0x09,
+ 0xDA,0x74,0x55,0x0F,0xA2,0x3F,0x21,0x05,0x9A,0x40,0x20,0x07,0x63,0x1E,0x10,0x01,
+ 0xDF,0xA9,0x85,0x1D,0xD3,0x84,0x4B,0x0E,0xCF,0x6F,0x49,0x0F,0xB3,0x48,0x1E,0x05,
+ 0xD8,0x77,0x52,0x12,0xB7,0x49,0x23,0x06,0xAA,0x45,0x28,0x07,0x7D,0x28,0x0F,0x07,
+ 0xCC,0x7B,0x4A,0x0E,0xB2,0x4F,0x24,0x07,0xAD,0x43,0x2C,0x06,0x86,0x29,0x11,0x07,
+ 0xAE,0x48,0x1F,0x0A,0x76,0x21,0x19,0x05,0x76,0x21,0x14,0x05,0x44,0x11,0x0B,0x01,
+ 0xE7,0xAD,0x96,0x23,0xDC,0x86,0x59,0x0E,0xDC,0x7C,0x5F,0x15,0xBB,0x53,0x2E,0x09,
+ 0xD6,0x7C,0x4A,0x16,0xBB,0x4A,0x25,0x08,0xB3,0x4F,0x28,0x0B,0x8E,0x23,0x15,0x08,
+ 0xCF,0x7F,0x57,0x11,0xB5,0x4A,0x23,0x0A,0xAA,0x42,0x28,0x05,0x7D,0x22,0x12,0x03,
+ 0xA6,0x49,0x28,0x09,0x82,0x2B,0x0D,0x04,0x7A,0x20,0x0F,0x04,0x3D,0x0F,0x09,0x03,
+ 0xD1,0x7C,0x4C,0x0F,0xAF,0x4E,0x21,0x09,0xA8,0x46,0x2A,0x07,0x85,0x1F,0x0E,0x07,
+ 0xA6,0x3F,0x26,0x07,0x7C,0x24,0x14,0x07,0x78,0x22,0x16,0x04,0x46,0x12,0x0A,0x02,
+ 0xA6,0x41,0x2C,0x0A,0x7E,0x28,0x11,0x05,0x73,0x1B,0x14,0x05,0x3D,0x11,0x0A,0x02,
+ 0x70,0x22,0x17,0x05,0x48,0x13,0x08,0x03,0x3C,0x07,0x0D,0x07,0x26,0x07,0x06,0x01,
+
+ 0xE0,0x9F,0xDA,0x7C,0x4F,0x18,0x28,0x0D,0xE9,0x9F,0xDA,0x7C,0x4F,0x18,0x1F,0x07,
+ 0xE6,0x97,0xD8,0x72,0x64,0x13,0x26,0x09,0xDC,0x67,0xA9,0x38,0x21,0x07,0x15,0x06,
+ 0xE9,0x91,0xD2,0x6B,0x63,0x14,0x2B,0x0E,0xD6,0x61,0xB7,0x41,0x2B,0x0E,0x10,0x09,
+ 0xCF,0x59,0xB0,0x2F,0x35,0x08,0x0F,0x07,0xB6,0x30,0x7A,0x21,0x17,0x07,0x09,0x03,
+ 0xE7,0xA3,0xE5,0x6B,0x65,0x1F,0x34,0x09,0xD8,0x6B,0xBE,0x45,0x27,0x07,0x10,0x07,
+ 0xDA,0x54,0xB1,0x39,0x2E,0x0E,0x17,0x08,0xA9,0x3C,0x86,0x22,0x16,0x06,0x07,0x03,
+ 0xD4,0x51,0xBC,0x3D,0x38,0x0A,0x13,0x06,0xB2,0x37,0x79,0x1C,0x17,0x05,0x0E,0x06,
+ 0xA7,0x31,0x74,0x1C,0x11,0x06,0x0C,0x02,0x6D,0x1A,0x38,0x10,0x0B,0x05,0x06,0x03,
+ 0xEB,0x9A,0xE1,0x7A,0x6F,0x13,0x34,0x0E,0xE6,0x75,0xC5,0x45,0x3E,0x0B,0x1A,0x05,
+ 0xD8,0x63,0xC1,0x40,0x3C,0x1B,0x19,0x06,0xB3,0x42,0x83,0x29,0x18,0x0A,0x08,0x04,
+ 0xD4,0x58,0xBA,0x43,0x3F,0x0A,0x1F,0x09,0xB1,0x33,0x8A,0x1F,0x1F,0x06,0x0D,0x05,
+ 0xAF,0x3C,0x7A,0x1F,0x16,0x08,0x0A,0x01,0x72,0x1B,0x52,0x0D,0x0B,0x09,0x06,0x01,
+ 0xCF,0x63,0xB7,0x47,0x40,0x10,0x14,0x06,0xC0,0x41,0x96,0x20,0x1C,0x09,0x10,0x05,
+ 0xA6,0x35,0x82,0x1A,0x20,0x0C,0x0E,0x04,0x80,0x1F,0x53,0x0F,0x0B,0x02,0x06,0x01,
+ 0xA6,0x31,0x81,0x1B,0x1D,0x01,0x08,0x08,0x7B,0x20,0x4D,0x19,0x0E,0x05,0x07,0x03,
+ 0x6B,0x17,0x49,0x07,0x0E,0x03,0x0A,0x05,0x37,0x0B,0x1F,0x06,0x04,0x02,0x07,0x01,
+
+ 0xF0,0xD6,0xED,0xAD,0xEC,0xB1,0xEB,0x79,0xAC,0x22,0x47,0x1E,0x6E,0x1B,0x32,0x0A,
+ 0xF0,0xD6,0xEA,0xA4,0xED,0xC4,0xDE,0x82,0x98,0x1F,0x50,0x13,0x52,0x15,0x2A,0x0A,
+ 0xF1,0xD1,0xEB,0xA2,0xEB,0xB7,0xD8,0x69,0xA2,0x1F,0x5B,0x18,0x55,0x18,0x2C,0x0A,
+ 0xED,0xB5,0xDE,0x7E,0xE6,0x85,0xD3,0x59,0x59,0x0F,0x2C,0x09,0x24,0x07,0x15,0x09,
+ 0xF1,0xD6,0xEA,0xA0,0xEC,0xBB,0xDA,0x77,0xA9,0x23,0x58,0x14,0x5D,0x12,0x2F,0x09,
+ 0xF1,0xC1,0xE3,0x86,0xE4,0x87,0xD2,0x4E,0x68,0x15,0x26,0x0B,0x27,0x09,0x15,0x02,
+ 0xEE,0xA6,0xE0,0x5C,0xE0,0x77,0xC3,0x41,0x67,0x1B,0x3C,0x07,0x2A,0x06,0x19,0x07,
+ 0xE4,0x75,0xC6,0x43,0xCC,0x50,0x95,0x23,0x35,0x09,0x14,0x04,0x15,0x05,0x0B,0x04,
+ 0xEE,0xD6,0xED,0xAD,0xEC,0xB1,0xEB,0x79,0xAC,0x22,0x56,0x14,0x5A,0x12,0x26,0x0A,
+ 0xEE,0xBB,0xE7,0x7E,0xE9,0x8D,0xCB,0x49,0x67,0x11,0x34,0x07,0x2B,0x0B,0x14,0x07,
+ 0xED,0xA7,0xE5,0x76,0xE3,0x7E,0xC4,0x4B,0x77,0x14,0x34,0x08,0x27,0x07,0x14,0x04,
+ 0xE7,0x8B,0xD2,0x4C,0xCA,0x56,0x9E,0x31,0x36,0x0C,0x11,0x07,0x14,0x04,0x0A,0x02,
+ 0xF0,0x9B,0xEA,0x6F,0xE5,0x81,0xC4,0x43,0x74,0x10,0x30,0x0B,0x2D,0x08,0x1B,0x06,
+ 0xE6,0x83,0xCA,0x48,0xD9,0x56,0xA7,0x23,0x3B,0x09,0x12,0x09,0x15,0x07,0x0A,0x03,
+ 0xE5,0x5F,0xCB,0x3C,0xCF,0x48,0x91,0x22,0x31,0x0A,0x17,0x08,0x15,0x04,0x0D,0x02,
+ 0xD1,0x43,0x91,0x20,0xA9,0x2D,0x54,0x12,0x17,0x07,0x09,0x02,0x0C,0x04,0x05,0x03,
+};
+#endif
+
+// Read/write handlers are divided into multiple functions to keep rarely-used
+// functionality separate so often-used functionality can be optimized better
+// by compiler.
+
+// If write isn't preceded by read, data has this added to it
+int const no_read_before_write = 0x2000;
+
+void Snes_Spc::cpu_write_smp_reg_( int data, rel_time_t time, int addr )
+{
+ switch ( addr )
+ {
+ case r_t0target:
+ case r_t1target:
+ case r_t2target: {
+ Timer* t = &m.timers [addr - r_t0target];
+ int period = IF_0_THEN_256( data );
+ if ( t->period != period )
+ {
+ t = run_timer( t, time );
+ #if SPC_MORE_ACCURACY
+ // Insane behavior when target is written just after counter is
+ // clocked and counter matches new period and new period isn't 1, 2, 4, or 8
+ if ( t->divider == (period & 0xFF) &&
+ t->next_time == time + TIMER_MUL( t, 1 ) &&
+ ((period - 1) | ~0x0F) & period )
+ {
+ //debug_printf( "SPC pathological timer target write\n" );
+
+ // If the period is 3, 5, or 9, there's a probability this behavior won't occur,
+ // based on the previous period
+ int prob = 0xFF;
+ int old_period = t->period & 0xFF;
+ if ( period == 3 ) prob = glitch_probs [0] [old_period];
+ if ( period == 5 ) prob = glitch_probs [1] [old_period];
+ if ( period == 9 ) prob = glitch_probs [2] [old_period];
+
+ // The glitch suppresses incrementing of one of the counter bits, based on
+ // the lowest set bit in the new period
+ int b = 1;
+ while ( !(period & b) )
+ b <<= 1;
+
+ if ( (rand() >> 4 & 0xFF) <= prob )
+ t->divider = (t->divider - b) & 0xFF;
+ }
+ #endif
+ t->period = period;
+ }
+ break;
+ }
+
+ case r_t0out:
+ case r_t1out:
+ case r_t2out:
+ if ( !SPC_MORE_ACCURACY )
+ debug_printf( "SPC wrote to counter %d\n", (int) addr - r_t0out );
+
+ if ( data < no_read_before_write / 2 )
+ run_timer( &m.timers [addr - r_t0out], time - 1 )->counter = 0;
+ break;
+
+ // Registers that act like RAM
+ case 0x8:
+ case 0x9:
+ REGS_IN [addr] = (uint8_t) data;
+ break;
+
+ case r_test:
+ if ( (uint8_t) data != 0x0A )
+ debug_printf( "SPC wrote to test register\n" );
+ break;
+
+ case r_control:
+ // port clears
+ if ( data & 0x10 )
+ {
+ REGS_IN [r_cpuio0] = 0;
+ REGS_IN [r_cpuio1] = 0;
+ }
+ if ( data & 0x20 )
+ {
+ REGS_IN [r_cpuio2] = 0;
+ REGS_IN [r_cpuio3] = 0;
+ }
+
+ // timers
+ {
+ for ( int i = 0; i < timer_count; i++ )
+ {
+ Timer* t = &m.timers [i];
+ int enabled = data >> i & 1;
+ if ( t->enabled != enabled )
+ {
+ t = run_timer( t, time );
+ t->enabled = enabled;
+ if ( enabled )
+ {
+ t->divider = 0;
+ t->counter = 0;
+ }
+ }
+ }
+ }
+ enable_rom( data & 0x80 );
+ break;
+ }
+}
+
+void Snes_Spc::cpu_write_smp_reg( int data, rel_time_t time, int addr )
+{
+ if ( addr == r_dspdata ) // 99%
+ dsp_write( data, time );
+ else
+ cpu_write_smp_reg_( data, time, addr );
+}
+
+void Snes_Spc::cpu_write_high( int data, int i, rel_time_t time )
+{
+ if ( i < rom_size )
+ {
+ m.hi_ram [i] = (uint8_t) data;
+ if ( m.rom_enabled )
+ RAM [i + rom_addr] = m.rom [i]; // restore overwritten ROM
+ }
+ else
+ {
+ assert( RAM [i + rom_addr - 0x10000] == (uint8_t) data );
+ RAM [i + rom_addr - 0x10000] = cpu_pad_fill; // restore overwritten padding
+ cpu_write( data, i + rom_addr - 0x10000, time );
+ }
+}
+
+int const bits_in_int = CHAR_BIT * sizeof (int);
+
+void Snes_Spc::cpu_write( int data, int addr, rel_time_t time )
+{
+ MEM_ACCESS( time, addr )
+
+ // RAM
+ RAM [addr] = (uint8_t) data;
+ int reg = addr - 0xF0;
+ if ( reg >= 0 ) // 64%
+ {
+ // $F0-$FF
+ if ( reg < reg_count ) // 87%
+ {
+ REGS [reg] = (uint8_t) data;
+
+ // Ports
+ #ifdef SPC_PORT_WRITE_HOOK
+ if ( (unsigned) (reg - r_cpuio0) < port_count )
+ SPC_PORT_WRITE_HOOK( m.spc_time + time, (reg - r_cpuio0),
+ (uint8_t) data, ®S [r_cpuio0] );
+ #endif
+
+ // Registers other than $F2 and $F4-$F7
+ //if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 )
+ // TODO: this is a bit on the fragile side
+ if ( ((~0x2F00 << (bits_in_int - 16)) << reg) < 0 ) // 36%
+ cpu_write_smp_reg( data, time, reg );
+ }
+ // High mem/address wrap-around
+ else
+ {
+ reg -= rom_addr - 0xF0;
+ if ( reg >= 0 ) // 1% in IPL ROM area or address wrapped around
+ cpu_write_high( data, reg, time );
+ }
+ }
+}
+
+
+//// CPU read
+
+inline int Snes_Spc::cpu_read_smp_reg( int reg, rel_time_t time )
+{
+ int result = REGS_IN [reg];
+ reg -= r_dspaddr;
+ // DSP addr and data
+ if ( (unsigned) reg <= 1 ) // 4% 0xF2 and 0xF3
+ {
+ result = REGS [r_dspaddr];
+ if ( (unsigned) reg == 1 )
+ result = dsp_read( time ); // 0xF3
+ }
+ return result;
+}
+
+int Snes_Spc::cpu_read( int addr, rel_time_t time )
+{
+ MEM_ACCESS( time, addr )
+
+ // RAM
+ int result = RAM [addr];
+ int reg = addr - 0xF0;
+ if ( reg >= 0 ) // 40%
+ {
+ reg -= 0x10;
+ if ( (unsigned) reg >= 0xFF00 ) // 21%
+ {
+ reg += 0x10 - r_t0out;
+
+ // Timers
+ if ( (unsigned) reg < timer_count ) // 90%
+ {
+ Timer* t = &m.timers [reg];
+ if ( time >= t->next_time )
+ t = run_timer_( t, time );
+ result = t->counter;
+ t->counter = 0;
+ }
+ // Other registers
+ else if ( reg < 0 ) // 10%
+ {
+ result = cpu_read_smp_reg( reg + r_t0out, time );
+ }
+ else // 1%
+ {
+ assert( reg + (r_t0out + 0xF0 - 0x10000) < 0x100 );
+ result = cpu_read( reg + (r_t0out + 0xF0 - 0x10000), time );
+ }
+ }
+ }
+
+ return result;
+}
+
+
+//// Run
+
+// Prefix and suffix for CPU emulator function
+#define SPC_CPU_RUN_FUNC \
+uint8_t* Snes_Spc::run_until_( time_t end_time )\
+{\
+ rel_time_t rel_time = m.spc_time - end_time;\
+ assert( rel_time <= 0 );\
+ m.spc_time = end_time;\
+ m.dsp_time += rel_time;\
+ m.timers [0].next_time += rel_time;\
+ m.timers [1].next_time += rel_time;\
+ m.timers [2].next_time += rel_time;
+
+#define SPC_CPU_RUN_FUNC_END \
+ m.spc_time += rel_time;\
+ m.dsp_time -= rel_time;\
+ m.timers [0].next_time -= rel_time;\
+ m.timers [1].next_time -= rel_time;\
+ m.timers [2].next_time -= rel_time;\
+ assert( m.spc_time <= end_time );\
+ return ®S [r_cpuio0];\
+}
+
+int const cpu_lag_max = 12 - 1; // DIV YA,X takes 12 clocks
+
+void Snes_Spc::end_frame( time_t end_time )
+{
+ // Catch CPU up to as close to end as possible. If final instruction
+ // would exceed end, does NOT execute it and leaves m.spc_time < end.
+ if ( end_time > m.spc_time )
+ run_until_( end_time );
+
+ m.spc_time -= end_time;
+ m.extra_clocks += end_time;
+
+ // Greatest number of clocks early that emulation can stop early due to
+ // not being able to execute current instruction without going over
+ // allowed time.
+ assert( -cpu_lag_max <= m.spc_time && m.spc_time <= 0 );
+
+ // Catch timers up to CPU
+ for ( int i = 0; i < timer_count; i++ )
+ run_timer( &m.timers [i], 0 );
+
+ // Catch DSP up to CPU
+ if ( m.dsp_time < 0 )
+ {
+ RUN_DSP( 0, max_reg_time );
+ }
+
+ // Save any extra samples beyond what should be generated
+ if ( m.buf_begin )
+ save_extra();
+}
+
+// Inclusion here allows static memory access functions and better optimization
+#include "Spc_Cpu.h"
diff --git a/src/console/Spc_Cpu.cxx b/src/console/Spc_Cpu.cxx
deleted file mode 100644
index 603447e9940b..000000000000
--- a/src/console/Spc_Cpu.cxx
+++ /dev/null
@@ -1,565 +0,0 @@
-// Core SPC emulation: CPU, timers, SMP registers, memory
-
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Snes_Spc.h"
-
-#include <string.h>
-
-/* Copyright (C) 2004-2007 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#define RAM (m.ram.ram)
-#define REGS (m.smp_regs [0])
-#define REGS_IN (m.smp_regs [1])
-
-// (n ? n : 256)
-#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1)
-
-// Note: SPC_MORE_ACCURACY exists mainly so I can run my validation tests, which
-// do crazy echo buffer accesses.
-#ifndef SPC_MORE_ACCURACY
- #define SPC_MORE_ACCURACY 0
-#endif
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-
-//// Timers
-
-#if SPC_DISABLE_TEMPO
- #define TIMER_DIV( t, n ) ((n) >> t->prescaler)
- #define TIMER_MUL( t, n ) ((n) << t->prescaler)
-#else
- #define TIMER_DIV( t, n ) ((n) / t->prescaler)
- #define TIMER_MUL( t, n ) ((n) * t->prescaler)
-#endif
-
-Snes_Spc::Timer* Snes_Spc::run_timer_( Timer* t, rel_time_t time )
-{
- int elapsed = TIMER_DIV( t, time - t->next_time ) + 1;
- t->next_time += TIMER_MUL( t, elapsed );
-
- if ( t->enabled )
- {
- int remain = IF_0_THEN_256( t->period - t->divider );
- int divider = t->divider + elapsed;
- int over = elapsed - remain;
- if ( over >= 0 )
- {
- int n = over / t->period;
- t->counter = (t->counter + 1 + n) & 0x0F;
- divider = over - n * t->period;
- }
- t->divider = (uint8_t) divider;
- }
- return t;
-}
-
-inline Snes_Spc::Timer* Snes_Spc::run_timer( Timer* t, rel_time_t time )
-{
- if ( time >= t->next_time )
- t = run_timer_( t, time );
- return t;
-}
-
-
-//// ROM
-
-void Snes_Spc::enable_rom( int enable )
-{
- if ( m.rom_enabled != enable )
- {
- m.rom_enabled = enable;
- if ( enable )
- memcpy( m.hi_ram, &RAM [rom_addr], sizeof m.hi_ram );
- memcpy( &RAM [rom_addr], (enable ? m.rom : m.hi_ram), rom_size );
- // TODO: ROM can still get overwritten when DSP writes to echo buffer
- }
-}
-
-
-//// DSP
-
-#if SPC_LESS_ACCURATE
- int const max_reg_time = 29;
-
- signed char const Snes_Spc::reg_times_ [256] =
- {
- -1, 0,-11,-10,-15,-11, -2, -2, 4, 3, 14, 14, 26, 26, 14, 22,
- 2, 3, 0, 1,-12, 0, 1, 1, 7, 6, 14, 14, 27, 14, 14, 23,
- 5, 6, 3, 4, -1, 3, 4, 4, 10, 9, 14, 14, 26, -5, 14, 23,
- 8, 9, 6, 7, 2, 6, 7, 7, 13, 12, 14, 14, 27, -4, 14, 24,
- 11, 12, 9, 10, 5, 9, 10, 10, 16, 15, 14, 14, -2, -4, 14, 24,
- 14, 15, 12, 13, 8, 12, 13, 13, 19, 18, 14, 14, -2,-36, 14, 24,
- 17, 18, 15, 16, 11, 15, 16, 16, 22, 21, 14, 14, 28, -3, 14, 25,
- 20, 21, 18, 19, 14, 18, 19, 19, 25, 24, 14, 14, 14, 29, 14, 25,
-
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- };
-
- #define RUN_DSP( time, offset ) \
- int count = (time) - (offset) - m.dsp_time;\
- if ( count >= 0 )\
- {\
- int clock_count = (count & ~(clocks_per_sample - 1)) + clocks_per_sample;\
- m.dsp_time += clock_count;\
- dsp.run( clock_count );\
- }
-#else
- #define RUN_DSP( time, offset ) \
- {\
- int count = (time) - m.dsp_time;\
- if ( !SPC_MORE_ACCURACY || count )\
- {\
- assert( count > 0 );\
- m.dsp_time = (time);\
- dsp.run( count );\
- }\
- }
-#endif
-
-int Snes_Spc::dsp_read( rel_time_t time )
-{
- RUN_DSP( time, reg_times [REGS [r_dspaddr] & 0x7F] );
-
- int result = dsp.read( REGS [r_dspaddr] & 0x7F );
-
- #ifdef SPC_DSP_READ_HOOK
- SPC_DSP_READ_HOOK( spc_time + time, (REGS [r_dspaddr] & 0x7F), result );
- #endif
-
- return result;
-}
-
-inline void Snes_Spc::dsp_write( int data, rel_time_t time )
-{
- RUN_DSP( time, reg_times [REGS [r_dspaddr]] )
- #if SPC_LESS_ACCURATE
- else if ( m.dsp_time == skipping_time )
- {
- int r = REGS [r_dspaddr];
- if ( r == Spc_Dsp::r_kon )
- m.skipped_kon |= data & ~dsp.read( Spc_Dsp::r_koff );
-
- if ( r == Spc_Dsp::r_koff )
- {
- m.skipped_koff |= data;
- m.skipped_kon &= ~data;
- }
- }
- #endif
-
- #ifdef SPC_DSP_WRITE_HOOK
- SPC_DSP_WRITE_HOOK( m.spc_time + time, REGS [r_dspaddr], (uint8_t) data );
- #endif
-
- if ( REGS [r_dspaddr] <= 0x7F )
- dsp.write( REGS [r_dspaddr], data );
- else if ( !SPC_MORE_ACCURACY )
- debug_printf( "SPC wrote to DSP register > $7F\n" );
-}
-
-
-//// Memory access extras
-
-#if SPC_MORE_ACCURACY
- #define MEM_ACCESS( time, addr ) \
- {\
- if ( time >= m.dsp_time )\
- {\
- RUN_DSP( time, max_reg_time );\
- }\
- }
-#elif !defined (NDEBUG)
- // Debug-only check for read/write within echo buffer, since this might result in
- // inaccurate emulation due to the DSP not being caught up to the present.
-
- bool Snes_Spc::check_echo_access( int addr )
- {
- if ( !(dsp.read( Spc_Dsp::r_flg ) & 0x20) )
- {
- int start = 0x100 * dsp.read( Spc_Dsp::r_esa );
- int size = 0x800 * (dsp.read( Spc_Dsp::r_edl ) & 0x0F);
- int end = start + (size ? size : 4);
- if ( start <= addr && addr < end )
- {
- if ( !m.echo_accessed )
- {
- m.echo_accessed = 1;
- return true;
- }
- }
- }
- return false;
- }
-
- #define MEM_ACCESS( time, addr ) check( !check_echo_access( (uint16_t) addr ) );
-#else
- #define MEM_ACCESS( time, addr )
-#endif
-
-
-//// CPU write
-
-#if SPC_MORE_ACCURACY
-static unsigned char const glitch_probs [3] [256] =
-{
- 0xC3,0x92,0x5B,0x1C,0xD1,0x92,0x5B,0x1C,0xDB,0x9C,0x72,0x18,0xCD,0x5C,0x38,0x0B,
- 0xE1,0x9C,0x74,0x17,0xCF,0x75,0x45,0x0C,0xCF,0x6E,0x4A,0x0D,0xA3,0x3A,0x1D,0x08,
- 0xDB,0xA0,0x82,0x19,0xD9,0x73,0x3C,0x0E,0xCB,0x76,0x52,0x0B,0xA5,0x46,0x1D,0x09,
- 0xDA,0x74,0x55,0x0F,0xA2,0x3F,0x21,0x05,0x9A,0x40,0x20,0x07,0x63,0x1E,0x10,0x01,
- 0xDF,0xA9,0x85,0x1D,0xD3,0x84,0x4B,0x0E,0xCF,0x6F,0x49,0x0F,0xB3,0x48,0x1E,0x05,
- 0xD8,0x77,0x52,0x12,0xB7,0x49,0x23,0x06,0xAA,0x45,0x28,0x07,0x7D,0x28,0x0F,0x07,
- 0xCC,0x7B,0x4A,0x0E,0xB2,0x4F,0x24,0x07,0xAD,0x43,0x2C,0x06,0x86,0x29,0x11,0x07,
- 0xAE,0x48,0x1F,0x0A,0x76,0x21,0x19,0x05,0x76,0x21,0x14,0x05,0x44,0x11,0x0B,0x01,
- 0xE7,0xAD,0x96,0x23,0xDC,0x86,0x59,0x0E,0xDC,0x7C,0x5F,0x15,0xBB,0x53,0x2E,0x09,
- 0xD6,0x7C,0x4A,0x16,0xBB,0x4A,0x25,0x08,0xB3,0x4F,0x28,0x0B,0x8E,0x23,0x15,0x08,
- 0xCF,0x7F,0x57,0x11,0xB5,0x4A,0x23,0x0A,0xAA,0x42,0x28,0x05,0x7D,0x22,0x12,0x03,
- 0xA6,0x49,0x28,0x09,0x82,0x2B,0x0D,0x04,0x7A,0x20,0x0F,0x04,0x3D,0x0F,0x09,0x03,
- 0xD1,0x7C,0x4C,0x0F,0xAF,0x4E,0x21,0x09,0xA8,0x46,0x2A,0x07,0x85,0x1F,0x0E,0x07,
- 0xA6,0x3F,0x26,0x07,0x7C,0x24,0x14,0x07,0x78,0x22,0x16,0x04,0x46,0x12,0x0A,0x02,
- 0xA6,0x41,0x2C,0x0A,0x7E,0x28,0x11,0x05,0x73,0x1B,0x14,0x05,0x3D,0x11,0x0A,0x02,
- 0x70,0x22,0x17,0x05,0x48,0x13,0x08,0x03,0x3C,0x07,0x0D,0x07,0x26,0x07,0x06,0x01,
-
- 0xE0,0x9F,0xDA,0x7C,0x4F,0x18,0x28,0x0D,0xE9,0x9F,0xDA,0x7C,0x4F,0x18,0x1F,0x07,
- 0xE6,0x97,0xD8,0x72,0x64,0x13,0x26,0x09,0xDC,0x67,0xA9,0x38,0x21,0x07,0x15,0x06,
- 0xE9,0x91,0xD2,0x6B,0x63,0x14,0x2B,0x0E,0xD6,0x61,0xB7,0x41,0x2B,0x0E,0x10,0x09,
- 0xCF,0x59,0xB0,0x2F,0x35,0x08,0x0F,0x07,0xB6,0x30,0x7A,0x21,0x17,0x07,0x09,0x03,
- 0xE7,0xA3,0xE5,0x6B,0x65,0x1F,0x34,0x09,0xD8,0x6B,0xBE,0x45,0x27,0x07,0x10,0x07,
- 0xDA,0x54,0xB1,0x39,0x2E,0x0E,0x17,0x08,0xA9,0x3C,0x86,0x22,0x16,0x06,0x07,0x03,
- 0xD4,0x51,0xBC,0x3D,0x38,0x0A,0x13,0x06,0xB2,0x37,0x79,0x1C,0x17,0x05,0x0E,0x06,
- 0xA7,0x31,0x74,0x1C,0x11,0x06,0x0C,0x02,0x6D,0x1A,0x38,0x10,0x0B,0x05,0x06,0x03,
- 0xEB,0x9A,0xE1,0x7A,0x6F,0x13,0x34,0x0E,0xE6,0x75,0xC5,0x45,0x3E,0x0B,0x1A,0x05,
- 0xD8,0x63,0xC1,0x40,0x3C,0x1B,0x19,0x06,0xB3,0x42,0x83,0x29,0x18,0x0A,0x08,0x04,
- 0xD4,0x58,0xBA,0x43,0x3F,0x0A,0x1F,0x09,0xB1,0x33,0x8A,0x1F,0x1F,0x06,0x0D,0x05,
- 0xAF,0x3C,0x7A,0x1F,0x16,0x08,0x0A,0x01,0x72,0x1B,0x52,0x0D,0x0B,0x09,0x06,0x01,
- 0xCF,0x63,0xB7,0x47,0x40,0x10,0x14,0x06,0xC0,0x41,0x96,0x20,0x1C,0x09,0x10,0x05,
- 0xA6,0x35,0x82,0x1A,0x20,0x0C,0x0E,0x04,0x80,0x1F,0x53,0x0F,0x0B,0x02,0x06,0x01,
- 0xA6,0x31,0x81,0x1B,0x1D,0x01,0x08,0x08,0x7B,0x20,0x4D,0x19,0x0E,0x05,0x07,0x03,
- 0x6B,0x17,0x49,0x07,0x0E,0x03,0x0A,0x05,0x37,0x0B,0x1F,0x06,0x04,0x02,0x07,0x01,
-
- 0xF0,0xD6,0xED,0xAD,0xEC,0xB1,0xEB,0x79,0xAC,0x22,0x47,0x1E,0x6E,0x1B,0x32,0x0A,
- 0xF0,0xD6,0xEA,0xA4,0xED,0xC4,0xDE,0x82,0x98,0x1F,0x50,0x13,0x52,0x15,0x2A,0x0A,
- 0xF1,0xD1,0xEB,0xA2,0xEB,0xB7,0xD8,0x69,0xA2,0x1F,0x5B,0x18,0x55,0x18,0x2C,0x0A,
- 0xED,0xB5,0xDE,0x7E,0xE6,0x85,0xD3,0x59,0x59,0x0F,0x2C,0x09,0x24,0x07,0x15,0x09,
- 0xF1,0xD6,0xEA,0xA0,0xEC,0xBB,0xDA,0x77,0xA9,0x23,0x58,0x14,0x5D,0x12,0x2F,0x09,
- 0xF1,0xC1,0xE3,0x86,0xE4,0x87,0xD2,0x4E,0x68,0x15,0x26,0x0B,0x27,0x09,0x15,0x02,
- 0xEE,0xA6,0xE0,0x5C,0xE0,0x77,0xC3,0x41,0x67,0x1B,0x3C,0x07,0x2A,0x06,0x19,0x07,
- 0xE4,0x75,0xC6,0x43,0xCC,0x50,0x95,0x23,0x35,0x09,0x14,0x04,0x15,0x05,0x0B,0x04,
- 0xEE,0xD6,0xED,0xAD,0xEC,0xB1,0xEB,0x79,0xAC,0x22,0x56,0x14,0x5A,0x12,0x26,0x0A,
- 0xEE,0xBB,0xE7,0x7E,0xE9,0x8D,0xCB,0x49,0x67,0x11,0x34,0x07,0x2B,0x0B,0x14,0x07,
- 0xED,0xA7,0xE5,0x76,0xE3,0x7E,0xC4,0x4B,0x77,0x14,0x34,0x08,0x27,0x07,0x14,0x04,
- 0xE7,0x8B,0xD2,0x4C,0xCA,0x56,0x9E,0x31,0x36,0x0C,0x11,0x07,0x14,0x04,0x0A,0x02,
- 0xF0,0x9B,0xEA,0x6F,0xE5,0x81,0xC4,0x43,0x74,0x10,0x30,0x0B,0x2D,0x08,0x1B,0x06,
- 0xE6,0x83,0xCA,0x48,0xD9,0x56,0xA7,0x23,0x3B,0x09,0x12,0x09,0x15,0x07,0x0A,0x03,
- 0xE5,0x5F,0xCB,0x3C,0xCF,0x48,0x91,0x22,0x31,0x0A,0x17,0x08,0x15,0x04,0x0D,0x02,
- 0xD1,0x43,0x91,0x20,0xA9,0x2D,0x54,0x12,0x17,0x07,0x09,0x02,0x0C,0x04,0x05,0x03,
-};
-#endif
-
-// Read/write handlers are divided into multiple functions to keep rarely-used
-// functionality separate so often-used functionality can be optimized better
-// by compiler.
-
-// If write isn't preceded by read, data has this added to it
-int const no_read_before_write = 0x2000;
-
-void Snes_Spc::cpu_write_smp_reg_( int data, rel_time_t time, int addr )
-{
- switch ( addr )
- {
- case r_t0target:
- case r_t1target:
- case r_t2target: {
- Timer* t = &m.timers [addr - r_t0target];
- int period = IF_0_THEN_256( data );
- if ( t->period != period )
- {
- t = run_timer( t, time );
- #if SPC_MORE_ACCURACY
- // Insane behavior when target is written just after counter is
- // clocked and counter matches new period and new period isn't 1, 2, 4, or 8
- if ( t->divider == (period & 0xFF) &&
- t->next_time == time + TIMER_MUL( t, 1 ) &&
- ((period - 1) | ~0x0F) & period )
- {
- //debug_printf( "SPC pathological timer target write\n" );
-
- // If the period is 3, 5, or 9, there's a probability this behavior won't occur,
- // based on the previous period
- int prob = 0xFF;
- int old_period = t->period & 0xFF;
- if ( period == 3 ) prob = glitch_probs [0] [old_period];
- if ( period == 5 ) prob = glitch_probs [1] [old_period];
- if ( period == 9 ) prob = glitch_probs [2] [old_period];
-
- // The glitch suppresses incrementing of one of the counter bits, based on
- // the lowest set bit in the new period
- int b = 1;
- while ( !(period & b) )
- b <<= 1;
-
- if ( (rand() >> 4 & 0xFF) <= prob )
- t->divider = (t->divider - b) & 0xFF;
- }
- #endif
- t->period = period;
- }
- break;
- }
-
- case r_t0out:
- case r_t1out:
- case r_t2out:
- if ( !SPC_MORE_ACCURACY )
- debug_printf( "SPC wrote to counter %d\n", (int) addr - r_t0out );
-
- if ( data < no_read_before_write / 2 )
- run_timer( &m.timers [addr - r_t0out], time - 1 )->counter = 0;
- break;
-
- // Registers that act like RAM
- case 0x8:
- case 0x9:
- REGS_IN [addr] = (uint8_t) data;
- break;
-
- case r_test:
- if ( (uint8_t) data != 0x0A )
- debug_printf( "SPC wrote to test register\n" );
- break;
-
- case r_control:
- // port clears
- if ( data & 0x10 )
- {
- REGS_IN [r_cpuio0] = 0;
- REGS_IN [r_cpuio1] = 0;
- }
- if ( data & 0x20 )
- {
- REGS_IN [r_cpuio2] = 0;
- REGS_IN [r_cpuio3] = 0;
- }
-
- // timers
- {
- for ( int i = 0; i < timer_count; i++ )
- {
- Timer* t = &m.timers [i];
- int enabled = data >> i & 1;
- if ( t->enabled != enabled )
- {
- t = run_timer( t, time );
- t->enabled = enabled;
- if ( enabled )
- {
- t->divider = 0;
- t->counter = 0;
- }
- }
- }
- }
- enable_rom( data & 0x80 );
- break;
- }
-}
-
-void Snes_Spc::cpu_write_smp_reg( int data, rel_time_t time, int addr )
-{
- if ( addr == r_dspdata ) // 99%
- dsp_write( data, time );
- else
- cpu_write_smp_reg_( data, time, addr );
-}
-
-void Snes_Spc::cpu_write_high( int data, int i, rel_time_t time )
-{
- if ( i < rom_size )
- {
- m.hi_ram [i] = (uint8_t) data;
- if ( m.rom_enabled )
- RAM [i + rom_addr] = m.rom [i]; // restore overwritten ROM
- }
- else
- {
- assert( RAM [i + rom_addr - 0x10000] == (uint8_t) data );
- RAM [i + rom_addr - 0x10000] = cpu_pad_fill; // restore overwritten padding
- cpu_write( data, i + rom_addr - 0x10000, time );
- }
-}
-
-int const bits_in_int = CHAR_BIT * sizeof (int);
-
-void Snes_Spc::cpu_write( int data, int addr, rel_time_t time )
-{
- MEM_ACCESS( time, addr )
-
- // RAM
- RAM [addr] = (uint8_t) data;
- int reg = addr - 0xF0;
- if ( reg >= 0 ) // 64%
- {
- // $F0-$FF
- if ( reg < reg_count ) // 87%
- {
- REGS [reg] = (uint8_t) data;
-
- // Ports
- #ifdef SPC_PORT_WRITE_HOOK
- if ( (unsigned) (reg - r_cpuio0) < port_count )
- SPC_PORT_WRITE_HOOK( m.spc_time + time, (reg - r_cpuio0),
- (uint8_t) data, ®S [r_cpuio0] );
- #endif
-
- // Registers other than $F2 and $F4-$F7
- //if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 )
- // TODO: this is a bit on the fragile side
- if ( ((~0x2F00 << (bits_in_int - 16)) << reg) < 0 ) // 36%
- cpu_write_smp_reg( data, time, reg );
- }
- // High mem/address wrap-around
- else
- {
- reg -= rom_addr - 0xF0;
- if ( reg >= 0 ) // 1% in IPL ROM area or address wrapped around
- cpu_write_high( data, reg, time );
- }
- }
-}
-
-
-//// CPU read
-
-inline int Snes_Spc::cpu_read_smp_reg( int reg, rel_time_t time )
-{
- int result = REGS_IN [reg];
- reg -= r_dspaddr;
- // DSP addr and data
- if ( (unsigned) reg <= 1 ) // 4% 0xF2 and 0xF3
- {
- result = REGS [r_dspaddr];
- if ( (unsigned) reg == 1 )
- result = dsp_read( time ); // 0xF3
- }
- return result;
-}
-
-int Snes_Spc::cpu_read( int addr, rel_time_t time )
-{
- MEM_ACCESS( time, addr )
-
- // RAM
- int result = RAM [addr];
- int reg = addr - 0xF0;
- if ( reg >= 0 ) // 40%
- {
- reg -= 0x10;
- if ( (unsigned) reg >= 0xFF00 ) // 21%
- {
- reg += 0x10 - r_t0out;
-
- // Timers
- if ( (unsigned) reg < timer_count ) // 90%
- {
- Timer* t = &m.timers [reg];
- if ( time >= t->next_time )
- t = run_timer_( t, time );
- result = t->counter;
- t->counter = 0;
- }
- // Other registers
- else if ( reg < 0 ) // 10%
- {
- result = cpu_read_smp_reg( reg + r_t0out, time );
- }
- else // 1%
- {
- assert( reg + (r_t0out + 0xF0 - 0x10000) < 0x100 );
- result = cpu_read( reg + (r_t0out + 0xF0 - 0x10000), time );
- }
- }
- }
-
- return result;
-}
-
-
-//// Run
-
-// Prefix and suffix for CPU emulator function
-#define SPC_CPU_RUN_FUNC \
-uint8_t* Snes_Spc::run_until_( time_t end_time )\
-{\
- rel_time_t rel_time = m.spc_time - end_time;\
- assert( rel_time <= 0 );\
- m.spc_time = end_time;\
- m.dsp_time += rel_time;\
- m.timers [0].next_time += rel_time;\
- m.timers [1].next_time += rel_time;\
- m.timers [2].next_time += rel_time;
-
-#define SPC_CPU_RUN_FUNC_END \
- m.spc_time += rel_time;\
- m.dsp_time -= rel_time;\
- m.timers [0].next_time -= rel_time;\
- m.timers [1].next_time -= rel_time;\
- m.timers [2].next_time -= rel_time;\
- assert( m.spc_time <= end_time );\
- return ®S [r_cpuio0];\
-}
-
-int const cpu_lag_max = 12 - 1; // DIV YA,X takes 12 clocks
-
-void Snes_Spc::end_frame( time_t end_time )
-{
- // Catch CPU up to as close to end as possible. If final instruction
- // would exceed end, does NOT execute it and leaves m.spc_time < end.
- if ( end_time > m.spc_time )
- run_until_( end_time );
-
- m.spc_time -= end_time;
- m.extra_clocks += end_time;
-
- // Greatest number of clocks early that emulation can stop early due to
- // not being able to execute current instruction without going over
- // allowed time.
- assert( -cpu_lag_max <= m.spc_time && m.spc_time <= 0 );
-
- // Catch timers up to CPU
- for ( int i = 0; i < timer_count; i++ )
- run_timer( &m.timers [i], 0 );
-
- // Catch DSP up to CPU
- if ( m.dsp_time < 0 )
- {
- RUN_DSP( 0, max_reg_time );
- }
-
- // Save any extra samples beyond what should be generated
- if ( m.buf_begin )
- save_extra();
-}
-
-// Inclusion here allows static memory access functions and better optimization
-#include "Spc_Cpu.h"
diff --git a/src/console/Spc_Dsp.cc b/src/console/Spc_Dsp.cc
new file mode 100644
index 000000000000..1786addc008f
--- /dev/null
+++ b/src/console/Spc_Dsp.cc
@@ -0,0 +1,701 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Spc_Dsp.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+
+/* Copyright (C) 2007 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+#ifdef BLARGG_ENABLE_OPTIMIZER
+ #include BLARGG_ENABLE_OPTIMIZER
+#endif
+
+#if INT_MAX < 0x7FFFFFFF
+ #error "Requires that int type have at least 32 bits"
+#endif
+
+
+// TODO: add to blargg_endian.h
+#define GET_LE16SA( addr ) ((int16_t) GET_LE16( addr ))
+#define GET_LE16A( addr ) GET_LE16( addr )
+#define SET_LE16A( addr, data ) SET_LE16( addr, data )
+
+static uint8_t const initial_regs [Spc_Dsp::register_count] =
+{
+ 0x45,0x8B,0x5A,0x9A,0xE4,0x82,0x1B,0x78,0x00,0x00,0xAA,0x96,0x89,0x0E,0xE0,0x80,
+ 0x2A,0x49,0x3D,0xBA,0x14,0xA0,0xAC,0xC5,0x00,0x00,0x51,0xBB,0x9C,0x4E,0x7B,0xFF,
+ 0xF4,0xFD,0x57,0x32,0x37,0xD9,0x42,0x22,0x00,0x00,0x5B,0x3C,0x9F,0x1B,0x87,0x9A,
+ 0x6F,0x27,0xAF,0x7B,0xE5,0x68,0x0A,0xD9,0x00,0x00,0x9A,0xC5,0x9C,0x4E,0x7B,0xFF,
+ 0xEA,0x21,0x78,0x4F,0xDD,0xED,0x24,0x14,0x00,0x00,0x77,0xB1,0xD1,0x36,0xC1,0x67,
+ 0x52,0x57,0x46,0x3D,0x59,0xF4,0x87,0xA4,0x00,0x00,0x7E,0x44,0x9C,0x4E,0x7B,0xFF,
+ 0x75,0xF5,0x06,0x97,0x10,0xC3,0x24,0xBB,0x00,0x00,0x7B,0x7A,0xE0,0x60,0x12,0x0F,
+ 0xF7,0x74,0x1C,0xE5,0x39,0x3D,0x73,0xC1,0x00,0x00,0x7A,0xB3,0xFF,0x4E,0x7B,0xFF
+};
+
+// if ( io < -32768 ) io = -32768;
+// if ( io > 32767 ) io = 32767;
+#define CLAMP16( io )\
+{\
+ if ( (int16_t) io != io )\
+ io = (io >> 31) ^ 0x7FFF;\
+}
+
+// Access global DSP register
+#define REG(n) m.regs [r_##n]
+
+// Access voice DSP register
+#define VREG(r,n) r [v_##n]
+
+#define WRITE_SAMPLES( l, r, out ) \
+{\
+ out [0] = l;\
+ out [1] = r;\
+ out += 2;\
+ if ( out >= m.out_end )\
+ {\
+ check( out == m.out_end );\
+ check( m.out_end != &m.extra [extra_size] || \
+ (m.extra <= m.out_begin && m.extra < &m.extra [extra_size]) );\
+ out = m.extra;\
+ m.out_end = &m.extra [extra_size];\
+ }\
+}\
+
+void Spc_Dsp::set_output( sample_t* out, int size )
+{
+ require( (size & 1) == 0 ); // must be even
+ if ( !out )
+ {
+ out = m.extra;
+ size = extra_size;
+ }
+ m.out_begin = out;
+ m.out = out;
+ m.out_end = out + size;
+}
+
+// Volume registers and efb are signed! Easy to forget int8_t cast.
+// Prefixes are to avoid accidental use of locals with same names.
+
+// Interleved gauss table (to improve cache coherency)
+// interleved_gauss [i] = gauss [(i & 1) * 256 + 255 - (i >> 1 & 0xFF)]
+static short const interleved_gauss [512] =
+{
+ 370,1305, 366,1305, 362,1304, 358,1304, 354,1304, 351,1304, 347,1304, 343,1303,
+ 339,1303, 336,1303, 332,1302, 328,1302, 325,1301, 321,1300, 318,1300, 314,1299,
+ 311,1298, 307,1297, 304,1297, 300,1296, 297,1295, 293,1294, 290,1293, 286,1292,
+ 283,1291, 280,1290, 276,1288, 273,1287, 270,1286, 267,1284, 263,1283, 260,1282,
+ 257,1280, 254,1279, 251,1277, 248,1275, 245,1274, 242,1272, 239,1270, 236,1269,
+ 233,1267, 230,1265, 227,1263, 224,1261, 221,1259, 218,1257, 215,1255, 212,1253,
+ 210,1251, 207,1248, 204,1246, 201,1244, 199,1241, 196,1239, 193,1237, 191,1234,
+ 188,1232, 186,1229, 183,1227, 180,1224, 178,1221, 175,1219, 173,1216, 171,1213,
+ 168,1210, 166,1207, 163,1205, 161,1202, 159,1199, 156,1196, 154,1193, 152,1190,
+ 150,1186, 147,1183, 145,1180, 143,1177, 141,1174, 139,1170, 137,1167, 134,1164,
+ 132,1160, 130,1157, 128,1153, 126,1150, 124,1146, 122,1143, 120,1139, 118,1136,
+ 117,1132, 115,1128, 113,1125, 111,1121, 109,1117, 107,1113, 106,1109, 104,1106,
+ 102,1102, 100,1098, 99,1094, 97,1090, 95,1086, 94,1082, 92,1078, 90,1074,
+ 89,1070, 87,1066, 86,1061, 84,1057, 83,1053, 81,1049, 80,1045, 78,1040,
+ 77,1036, 76,1032, 74,1027, 73,1023, 71,1019, 70,1014, 69,1010, 67,1005,
+ 66,1001, 65, 997, 64, 992, 62, 988, 61, 983, 60, 978, 59, 974, 58, 969,
+ 56, 965, 55, 960, 54, 955, 53, 951, 52, 946, 51, 941, 50, 937, 49, 932,
+ 48, 927, 47, 923, 46, 918, 45, 913, 44, 908, 43, 904, 42, 899, 41, 894,
+ 40, 889, 39, 884, 38, 880, 37, 875, 36, 870, 36, 865, 35, 860, 34, 855,
+ 33, 851, 32, 846, 32, 841, 31, 836, 30, 831, 29, 826, 29, 821, 28, 816,
+ 27, 811, 27, 806, 26, 802, 25, 797, 24, 792, 24, 787, 23, 782, 23, 777,
+ 22, 772, 21, 767, 21, 762, 20, 757, 20, 752, 19, 747, 19, 742, 18, 737,
+ 17, 732, 17, 728, 16, 723, 16, 718, 15, 713, 15, 708, 15, 703, 14, 698,
+ 14, 693, 13, 688, 13, 683, 12, 678, 12, 674, 11, 669, 11, 664, 11, 659,
+ 10, 654, 10, 649, 10, 644, 9, 640, 9, 635, 9, 630, 8, 625, 8, 620,
+ 8, 615, 7, 611, 7, 606, 7, 601, 6, 596, 6, 592, 6, 587, 6, 582,
+ 5, 577, 5, 573, 5, 568, 5, 563, 4, 559, 4, 554, 4, 550, 4, 545,
+ 4, 540, 3, 536, 3, 531, 3, 527, 3, 522, 3, 517, 2, 513, 2, 508,
+ 2, 504, 2, 499, 2, 495, 2, 491, 2, 486, 1, 482, 1, 477, 1, 473,
+ 1, 469, 1, 464, 1, 460, 1, 456, 1, 451, 1, 447, 1, 443, 1, 439,
+ 0, 434, 0, 430, 0, 426, 0, 422, 0, 418, 0, 414, 0, 410, 0, 405,
+ 0, 401, 0, 397, 0, 393, 0, 389, 0, 385, 0, 381, 0, 378, 0, 374,
+};
+
+
+//// Counters
+
+#define RATE( rate, div )\
+ (rate >= div ? rate / div * 8 - 1 : rate - 1)
+
+static unsigned const counter_mask [32] =
+{
+ RATE( 2,2), RATE(2048,4), RATE(1536,3),
+ RATE(1280,5), RATE(1024,4), RATE( 768,3),
+ RATE( 640,5), RATE( 512,4), RATE( 384,3),
+ RATE( 320,5), RATE( 256,4), RATE( 192,3),
+ RATE( 160,5), RATE( 128,4), RATE( 96,3),
+ RATE( 80,5), RATE( 64,4), RATE( 48,3),
+ RATE( 40,5), RATE( 32,4), RATE( 24,3),
+ RATE( 20,5), RATE( 16,4), RATE( 12,3),
+ RATE( 10,5), RATE( 8,4), RATE( 6,3),
+ RATE( 5,5), RATE( 4,4), RATE( 3,3),
+ RATE( 2,4),
+ RATE( 1,4)
+};
+#undef RATE
+
+inline void Spc_Dsp::init_counter()
+{
+ // counters start out with this synchronization
+ m.counters [0] = 1;
+ m.counters [1] = 0;
+ m.counters [2] = -0x20u;
+ m.counters [3] = 0x0B;
+
+ int n = 2;
+ for ( int i = 1; i < 32; i++ )
+ {
+ m.counter_select [i] = &m.counters [n];
+ if ( !--n )
+ n = 3;
+ }
+ m.counter_select [ 0] = &m.counters [0];
+ m.counter_select [30] = &m.counters [2];
+}
+
+inline void Spc_Dsp::run_counter( int i )
+{
+ int n = m.counters [i];
+ if ( !(n-- & 7) )
+ n -= 6 - i;
+ m.counters [i] = n;
+}
+
+#define READ_COUNTER( rate )\
+ (*m.counter_select [rate] & counter_mask [rate])
+
+
+//// Emulation
+
+void Spc_Dsp::run( int clock_count )
+{
+ int new_phase = m.phase + clock_count;
+ int count = new_phase >> 5;
+ m.phase = new_phase & 31;
+ if ( !count )
+ return;
+
+ uint8_t* const ram = m.ram;
+ uint8_t const* const dir = &ram [REG(dir) * 0x100];
+ int const slow_gaussian = (REG(pmon) >> 1) | REG(non);
+ int const noise_rate = REG(flg) & 0x1F;
+
+ // Global volume
+ int mvoll = (int8_t) REG(mvoll);
+ int mvolr = (int8_t) REG(mvolr);
+ if ( mvoll * mvolr < m.surround_threshold )
+ mvoll = -mvoll; // eliminate surround
+
+ do
+ {
+ // KON/KOFF reading
+ if ( (m.every_other_sample ^= 1) != 0 )
+ {
+ m.new_kon &= ~m.kon;
+ m.kon = m.new_kon;
+ m.t_koff = REG(koff);
+ }
+
+ run_counter( 1 );
+ run_counter( 2 );
+ run_counter( 3 );
+
+ // Noise
+ if ( !READ_COUNTER( noise_rate ) )
+ {
+ int feedback = (m.noise << 13) ^ (m.noise << 14);
+ m.noise = (feedback & 0x4000) ^ (m.noise >> 1);
+ }
+
+ // Voices
+ int pmon_input = 0;
+ int main_out_l = 0;
+ int main_out_r = 0;
+ int echo_out_l = 0;
+ int echo_out_r = 0;
+ voice_t* v = m.voices;
+ uint8_t* v_regs = m.regs;
+ int vbit = 1;
+ do
+ {
+ #define SAMPLE_PTR(i) GET_LE16A( &dir [VREG(v_regs,srcn) * 4 + i * 2] )
+
+ int brr_header = ram [v->brr_addr];
+ int kon_delay = v->kon_delay;
+
+ // Pitch
+ int pitch = GET_LE16A( &VREG(v_regs,pitchl) ) & 0x3FFF;
+ if ( REG(pmon) & vbit )
+ pitch += ((pmon_input >> 5) * pitch) >> 10;
+
+ // KON phases
+ if ( --kon_delay >= 0 )
+ {
+ v->kon_delay = kon_delay;
+
+ // Get ready to start BRR decoding on next sample
+ if ( kon_delay == 4 )
+ {
+ v->brr_addr = SAMPLE_PTR( 0 );
+ v->brr_offset = 1;
+ v->buf_pos = v->buf;
+ brr_header = 0; // header is ignored on this sample
+ }
+
+ // Envelope is never run during KON
+ v->env = 0;
+ v->hidden_env = 0;
+
+ // Disable BRR decoding until last three samples
+ v->interp_pos = (kon_delay & 3 ? 0x4000 : 0);
+
+ // Pitch is never added during KON
+ pitch = 0;
+ }
+
+ int env = v->env;
+
+ // Gaussian interpolation
+ {
+ int output = 0;
+ VREG(v_regs,envx) = (uint8_t) (env >> 4);
+ if ( env )
+ {
+ // Make pointers into gaussian based on fractional position between samples
+ int offset = (unsigned) v->interp_pos >> 3 & 0x1FE;
+ short const* fwd = interleved_gauss + offset;
+ short const* rev = interleved_gauss + 510 - offset; // mirror left half of gaussian
+
+ int const* in = &v->buf_pos [(unsigned) v->interp_pos >> 12];
+
+ if ( !(slow_gaussian & vbit) ) // 99%
+ {
+ // Faster approximation when exact sample value isn't necessary for pitch mod
+ output = (fwd [0] * in [0] +
+ fwd [1] * in [1] +
+ rev [1] * in [2] +
+ rev [0] * in [3]) >> 11;
+ output = (output * env) >> 11;
+ }
+ else
+ {
+ output = (int16_t) (m.noise * 2);
+ if ( !(REG(non) & vbit) )
+ {
+ output = (fwd [0] * in [0]) >> 11;
+ output += (fwd [1] * in [1]) >> 11;
+ output += (rev [1] * in [2]) >> 11;
+ output = (int16_t) output;
+ output += (rev [0] * in [3]) >> 11;
+
+ CLAMP16( output );
+ output &= ~1;
+ }
+ output = (output * env) >> 11 & ~1;
+ }
+
+ // Output
+ int l = output * v->volume [0];
+ int r = output * v->volume [1];
+
+ main_out_l += l;
+ main_out_r += r;
+
+ if ( REG(eon) & vbit )
+ {
+ echo_out_l += l;
+ echo_out_r += r;
+ }
+ }
+
+ pmon_input = output;
+ VREG(v_regs,outx) = (uint8_t) (output >> 8);
+ }
+
+ // Soft reset or end of sample
+ if ( REG(flg) & 0x80 || (brr_header & 3) == 1 )
+ {
+ v->env_mode = env_release;
+ env = 0;
+ }
+
+ if ( m.every_other_sample )
+ {
+ // KOFF
+ if ( m.t_koff & vbit )
+ v->env_mode = env_release;
+
+ // KON
+ if ( m.kon & vbit )
+ {
+ v->kon_delay = 5;
+ v->env_mode = env_attack;
+ REG(endx) &= ~vbit;
+ }
+ }
+
+ // Envelope
+ if ( !v->kon_delay )
+ {
+ if ( v->env_mode == env_release ) // 97%
+ {
+ env -= 0x8;
+ v->env = env;
+ if ( env <= 0 )
+ {
+ v->env = 0;
+ goto skip_brr; // no BRR decoding for you!
+ }
+ }
+ else // 3%
+ {
+ int rate;
+ int const adsr0 = VREG(v_regs,adsr0);
+ int env_data = VREG(v_regs,adsr1);
+ if ( adsr0 >= 0x80 ) // 97% ADSR
+ {
+ if ( v->env_mode > env_decay ) // 89%
+ {
+ env--;
+ env -= env >> 8;
+ rate = env_data & 0x1F;
+
+ // optimized handling
+ v->hidden_env = env;
+ if ( READ_COUNTER( rate ) )
+ goto exit_env;
+ v->env = env;
+ goto exit_env;
+ }
+ else if ( v->env_mode == env_decay )
+ {
+ env--;
+ env -= env >> 8;
+ rate = (adsr0 >> 3 & 0x0E) + 0x10;
+ }
+ else // env_attack
+ {
+ rate = (adsr0 & 0x0F) * 2 + 1;
+ env += rate < 31 ? 0x20 : 0x400;
+ }
+ }
+ else // GAIN
+ {
+ int mode;
+ env_data = VREG(v_regs,gain);
+ mode = env_data >> 5;
+ if ( mode < 4 ) // direct
+ {
+ env = env_data * 0x10;
+ rate = 31;
+ }
+ else
+ {
+ rate = env_data & 0x1F;
+ if ( mode == 4 ) // 4: linear decrease
+ {
+ env -= 0x20;
+ }
+ else if ( mode < 6 ) // 5: exponential decrease
+ {
+ env--;
+ env -= env >> 8;
+ }
+ else // 6,7: linear increase
+ {
+ env += 0x20;
+ if ( mode > 6 && (unsigned) v->hidden_env >= 0x600 )
+ env += 0x8 - 0x20; // 7: two-slope linear increase
+ }
+ }
+ }
+
+ // Sustain level
+ if ( (env >> 8) == (env_data >> 5) && v->env_mode == env_decay )
+ v->env_mode = env_sustain;
+
+ v->hidden_env = env;
+
+ // unsigned cast because linear decrease going negative also triggers this
+ if ( (unsigned) env > 0x7FF )
+ {
+ env = (env < 0 ? 0 : 0x7FF);
+ if ( v->env_mode == env_attack )
+ v->env_mode = env_decay;
+ }
+
+ if ( !READ_COUNTER( rate ) )
+ v->env = env; // nothing else is controlled by the counter
+ }
+ }
+ exit_env:
+
+ {
+ // Apply pitch
+ int old_pos = v->interp_pos;
+ int interp_pos = (old_pos & 0x3FFF) + pitch;
+ if ( interp_pos > 0x7FFF )
+ interp_pos = 0x7FFF;
+ v->interp_pos = interp_pos;
+
+ // BRR decode if necessary
+ if ( old_pos >= 0x4000 )
+ {
+ // Arrange the four input nybbles in 0xABCD order for easy decoding
+ int nybbles = ram [(v->brr_addr + v->brr_offset) & 0xFFFF] * 0x100 +
+ ram [(v->brr_addr + v->brr_offset + 1) & 0xFFFF];
+
+ // Advance read position
+ int const brr_block_size = 9;
+ int brr_offset = v->brr_offset;
+ if ( (brr_offset += 2) >= brr_block_size )
+ {
+ // Next BRR block
+ int brr_addr = (v->brr_addr + brr_block_size) & 0xFFFF;
+ assert( brr_offset == brr_block_size );
+ if ( brr_header & 1 )
+ {
+ brr_addr = SAMPLE_PTR( 1 );
+ if ( !v->kon_delay )
+ REG(endx) |= vbit;
+ }
+ v->brr_addr = brr_addr;
+ brr_offset = 1;
+ }
+ v->brr_offset = brr_offset;
+
+ // Decode
+
+ // 0: >>1 1: <<0 2: <<1 ... 12: <<11 13-15: >>4 <<11
+ static unsigned char const shifts [16 * 2] = {
+ 13,12,12,12,12,12,12,12,12,12,12, 12, 12, 16, 16, 16,
+ 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 11
+ };
+ int const scale = brr_header >> 4;
+ int const right_shift = shifts [scale];
+ int const left_shift = shifts [scale + 16];
+
+ // Write to next four samples in circular buffer
+ int* pos = v->buf_pos;
+ int* end;
+
+ // Decode four samples
+ for ( end = pos + 4; pos < end; pos++, nybbles <<= 4 )
+ {
+ // Extract upper nybble and scale appropriately
+ int s = ((int16_t) nybbles >> right_shift) << left_shift;
+
+ // Apply IIR filter (8 is the most commonly used)
+ int const filter = brr_header & 0x0C;
+ int const p1 = pos [brr_buf_size - 1];
+ int const p2 = pos [brr_buf_size - 2] >> 1;
+ if ( filter >= 8 )
+ {
+ s += p1;
+ s -= p2;
+ if ( filter == 8 ) // s += p1 * 0.953125 - p2 * 0.46875
+ {
+ s += p2 >> 4;
+ s += (p1 * -3) >> 6;
+ }
+ else // s += p1 * 0.8984375 - p2 * 0.40625
+ {
+ s += (p1 * -13) >> 7;
+ s += (p2 * 3) >> 4;
+ }
+ }
+ else if ( filter ) // s += p1 * 0.46875
+ {
+ s += p1 >> 1;
+ s += (-p1) >> 5;
+ }
+
+ // Adjust and write sample
+ CLAMP16( s );
+ s = (int16_t) (s * 2);
+ pos [brr_buf_size] = pos [0] = s; // second copy simplifies wrap-around
+ }
+
+ if ( pos >= &v->buf [brr_buf_size] )
+ pos = v->buf;
+ v->buf_pos = pos;
+ }
+ }
+skip_brr:
+ // Next voice
+ vbit <<= 1;
+ v_regs += 0x10;
+ v++;
+ }
+ while ( vbit < 0x100 );
+
+ // Echo position
+ int echo_offset = m.echo_offset;
+ uint8_t* const echo_ptr = &ram [(REG(esa) * 0x100 + echo_offset) & 0xFFFF];
+ if ( !echo_offset )
+ m.echo_length = (REG(edl) & 0x0F) * 0x800;
+ echo_offset += 4;
+ if ( echo_offset >= m.echo_length )
+ echo_offset = 0;
+ m.echo_offset = echo_offset;
+
+ // FIR
+ int echo_in_l = GET_LE16SA( echo_ptr + 0 );
+ int echo_in_r = GET_LE16SA( echo_ptr + 2 );
+
+ int (*echo_hist_pos) [2] = m.echo_hist_pos;
+ if ( ++echo_hist_pos >= &m.echo_hist [echo_hist_size] )
+ echo_hist_pos = m.echo_hist;
+ m.echo_hist_pos = echo_hist_pos;
+
+ echo_hist_pos [0] [0] = echo_hist_pos [8] [0] = echo_in_l;
+ echo_hist_pos [0] [1] = echo_hist_pos [8] [1] = echo_in_r;
+
+ #define CALC_FIR_( i, in ) ((in) * (int8_t) REG(fir + i * 0x10))
+ echo_in_l = CALC_FIR_( 7, echo_in_l );
+ echo_in_r = CALC_FIR_( 7, echo_in_r );
+
+ #define CALC_FIR( i, ch ) CALC_FIR_( i, echo_hist_pos [i + 1] [ch] )
+ #define DO_FIR( i )\
+ echo_in_l += CALC_FIR( i, 0 );\
+ echo_in_r += CALC_FIR( i, 1 );
+ DO_FIR( 0 );
+ DO_FIR( 1 );
+ DO_FIR( 2 );
+ #if defined (__MWERKS__) && __MWERKS__ < 0x3200
+ __eieio(); // keeps compiler from stupidly "caching" things in memory
+ #endif
+ DO_FIR( 3 );
+ DO_FIR( 4 );
+ DO_FIR( 5 );
+ DO_FIR( 6 );
+
+ // Echo out
+ if ( !(REG(flg) & 0x20) )
+ {
+ int l = (echo_out_l >> 7) + ((echo_in_l * (int8_t) REG(efb)) >> 14);
+ int r = (echo_out_r >> 7) + ((echo_in_r * (int8_t) REG(efb)) >> 14);
+
+ // just to help pass more validation tests
+ #if SPC_MORE_ACCURACY
+ l &= ~1;
+ r &= ~1;
+ #endif
+
+ CLAMP16( l );
+ CLAMP16( r );
+
+ SET_LE16A( echo_ptr + 0, l );
+ SET_LE16A( echo_ptr + 2, r );
+ }
+
+ // Sound out
+ int l = (main_out_l * mvoll + echo_in_l * (int8_t) REG(evoll)) >> 14;
+ int r = (main_out_r * mvolr + echo_in_r * (int8_t) REG(evolr)) >> 14;
+
+ CLAMP16( l );
+ CLAMP16( r );
+
+ if ( (REG(flg) & 0x40) )
+ {
+ l = 0;
+ r = 0;
+ }
+
+ sample_t* out = m.out;
+ WRITE_SAMPLES( l, r, out );
+ m.out = out;
+ }
+ while ( --count );
+}
+
+
+//// Setup
+
+void Spc_Dsp::mute_voices( int mask )
+{
+ m.mute_mask = mask;
+ for ( int i = 0; i < voice_count; i++ )
+ {
+ m.voices [i].enabled = (mask >> i & 1) - 1;
+ update_voice_vol( i * 0x10 );
+ }
+}
+
+void Spc_Dsp::init( void* ram_64k )
+{
+ m.ram = (uint8_t*) ram_64k;
+ mute_voices( 0 );
+ disable_surround( false );
+ set_output( 0, 0 );
+ reset();
+
+ #ifndef NDEBUG
+ // be sure this sign-extends
+ assert( (int16_t) 0x8000 == -0x8000 );
+
+ // be sure right shift preserves sign
+ assert( (-1 >> 1) == -1 );
+
+ // check clamp macro
+ int i;
+ i = +0x8000; CLAMP16( i ); assert( i == +0x7FFF );
+ i = -0x8001; CLAMP16( i ); assert( i == -0x8000 );
+ #endif
+}
+
+void Spc_Dsp::soft_reset_common()
+{
+ require( m.ram ); // init() must have been called already
+
+ m.noise = 0x4000;
+ m.echo_hist_pos = m.echo_hist;
+ m.every_other_sample = 1;
+ m.echo_offset = 0;
+ m.phase = 0;
+
+ init_counter();
+}
+
+void Spc_Dsp::soft_reset()
+{
+ REG(flg) = 0xE0;
+ soft_reset_common();
+}
+
+void Spc_Dsp::load( uint8_t const regs [register_count] )
+{
+ memcpy( m.regs, regs, sizeof m.regs );
+ memset( &m.regs [register_count], 0, offsetof (state_t,ram) - register_count );
+
+ // Internal state
+ int i;
+ for ( i = voice_count; --i >= 0; )
+ {
+ voice_t& v = m.voices [i];
+ v.brr_offset = 1;
+ v.buf_pos = v.buf;
+ }
+ m.new_kon = REG(kon);
+
+ mute_voices( m.mute_mask );
+ soft_reset_common();
+}
+
+void Spc_Dsp::reset() { load( initial_regs ); }
diff --git a/src/console/Spc_Dsp.cxx b/src/console/Spc_Dsp.cxx
deleted file mode 100644
index 1786addc008f..000000000000
--- a/src/console/Spc_Dsp.cxx
+++ /dev/null
@@ -1,701 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Spc_Dsp.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2007 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-#if INT_MAX < 0x7FFFFFFF
- #error "Requires that int type have at least 32 bits"
-#endif
-
-
-// TODO: add to blargg_endian.h
-#define GET_LE16SA( addr ) ((int16_t) GET_LE16( addr ))
-#define GET_LE16A( addr ) GET_LE16( addr )
-#define SET_LE16A( addr, data ) SET_LE16( addr, data )
-
-static uint8_t const initial_regs [Spc_Dsp::register_count] =
-{
- 0x45,0x8B,0x5A,0x9A,0xE4,0x82,0x1B,0x78,0x00,0x00,0xAA,0x96,0x89,0x0E,0xE0,0x80,
- 0x2A,0x49,0x3D,0xBA,0x14,0xA0,0xAC,0xC5,0x00,0x00,0x51,0xBB,0x9C,0x4E,0x7B,0xFF,
- 0xF4,0xFD,0x57,0x32,0x37,0xD9,0x42,0x22,0x00,0x00,0x5B,0x3C,0x9F,0x1B,0x87,0x9A,
- 0x6F,0x27,0xAF,0x7B,0xE5,0x68,0x0A,0xD9,0x00,0x00,0x9A,0xC5,0x9C,0x4E,0x7B,0xFF,
- 0xEA,0x21,0x78,0x4F,0xDD,0xED,0x24,0x14,0x00,0x00,0x77,0xB1,0xD1,0x36,0xC1,0x67,
- 0x52,0x57,0x46,0x3D,0x59,0xF4,0x87,0xA4,0x00,0x00,0x7E,0x44,0x9C,0x4E,0x7B,0xFF,
- 0x75,0xF5,0x06,0x97,0x10,0xC3,0x24,0xBB,0x00,0x00,0x7B,0x7A,0xE0,0x60,0x12,0x0F,
- 0xF7,0x74,0x1C,0xE5,0x39,0x3D,0x73,0xC1,0x00,0x00,0x7A,0xB3,0xFF,0x4E,0x7B,0xFF
-};
-
-// if ( io < -32768 ) io = -32768;
-// if ( io > 32767 ) io = 32767;
-#define CLAMP16( io )\
-{\
- if ( (int16_t) io != io )\
- io = (io >> 31) ^ 0x7FFF;\
-}
-
-// Access global DSP register
-#define REG(n) m.regs [r_##n]
-
-// Access voice DSP register
-#define VREG(r,n) r [v_##n]
-
-#define WRITE_SAMPLES( l, r, out ) \
-{\
- out [0] = l;\
- out [1] = r;\
- out += 2;\
- if ( out >= m.out_end )\
- {\
- check( out == m.out_end );\
- check( m.out_end != &m.extra [extra_size] || \
- (m.extra <= m.out_begin && m.extra < &m.extra [extra_size]) );\
- out = m.extra;\
- m.out_end = &m.extra [extra_size];\
- }\
-}\
-
-void Spc_Dsp::set_output( sample_t* out, int size )
-{
- require( (size & 1) == 0 ); // must be even
- if ( !out )
- {
- out = m.extra;
- size = extra_size;
- }
- m.out_begin = out;
- m.out = out;
- m.out_end = out + size;
-}
-
-// Volume registers and efb are signed! Easy to forget int8_t cast.
-// Prefixes are to avoid accidental use of locals with same names.
-
-// Interleved gauss table (to improve cache coherency)
-// interleved_gauss [i] = gauss [(i & 1) * 256 + 255 - (i >> 1 & 0xFF)]
-static short const interleved_gauss [512] =
-{
- 370,1305, 366,1305, 362,1304, 358,1304, 354,1304, 351,1304, 347,1304, 343,1303,
- 339,1303, 336,1303, 332,1302, 328,1302, 325,1301, 321,1300, 318,1300, 314,1299,
- 311,1298, 307,1297, 304,1297, 300,1296, 297,1295, 293,1294, 290,1293, 286,1292,
- 283,1291, 280,1290, 276,1288, 273,1287, 270,1286, 267,1284, 263,1283, 260,1282,
- 257,1280, 254,1279, 251,1277, 248,1275, 245,1274, 242,1272, 239,1270, 236,1269,
- 233,1267, 230,1265, 227,1263, 224,1261, 221,1259, 218,1257, 215,1255, 212,1253,
- 210,1251, 207,1248, 204,1246, 201,1244, 199,1241, 196,1239, 193,1237, 191,1234,
- 188,1232, 186,1229, 183,1227, 180,1224, 178,1221, 175,1219, 173,1216, 171,1213,
- 168,1210, 166,1207, 163,1205, 161,1202, 159,1199, 156,1196, 154,1193, 152,1190,
- 150,1186, 147,1183, 145,1180, 143,1177, 141,1174, 139,1170, 137,1167, 134,1164,
- 132,1160, 130,1157, 128,1153, 126,1150, 124,1146, 122,1143, 120,1139, 118,1136,
- 117,1132, 115,1128, 113,1125, 111,1121, 109,1117, 107,1113, 106,1109, 104,1106,
- 102,1102, 100,1098, 99,1094, 97,1090, 95,1086, 94,1082, 92,1078, 90,1074,
- 89,1070, 87,1066, 86,1061, 84,1057, 83,1053, 81,1049, 80,1045, 78,1040,
- 77,1036, 76,1032, 74,1027, 73,1023, 71,1019, 70,1014, 69,1010, 67,1005,
- 66,1001, 65, 997, 64, 992, 62, 988, 61, 983, 60, 978, 59, 974, 58, 969,
- 56, 965, 55, 960, 54, 955, 53, 951, 52, 946, 51, 941, 50, 937, 49, 932,
- 48, 927, 47, 923, 46, 918, 45, 913, 44, 908, 43, 904, 42, 899, 41, 894,
- 40, 889, 39, 884, 38, 880, 37, 875, 36, 870, 36, 865, 35, 860, 34, 855,
- 33, 851, 32, 846, 32, 841, 31, 836, 30, 831, 29, 826, 29, 821, 28, 816,
- 27, 811, 27, 806, 26, 802, 25, 797, 24, 792, 24, 787, 23, 782, 23, 777,
- 22, 772, 21, 767, 21, 762, 20, 757, 20, 752, 19, 747, 19, 742, 18, 737,
- 17, 732, 17, 728, 16, 723, 16, 718, 15, 713, 15, 708, 15, 703, 14, 698,
- 14, 693, 13, 688, 13, 683, 12, 678, 12, 674, 11, 669, 11, 664, 11, 659,
- 10, 654, 10, 649, 10, 644, 9, 640, 9, 635, 9, 630, 8, 625, 8, 620,
- 8, 615, 7, 611, 7, 606, 7, 601, 6, 596, 6, 592, 6, 587, 6, 582,
- 5, 577, 5, 573, 5, 568, 5, 563, 4, 559, 4, 554, 4, 550, 4, 545,
- 4, 540, 3, 536, 3, 531, 3, 527, 3, 522, 3, 517, 2, 513, 2, 508,
- 2, 504, 2, 499, 2, 495, 2, 491, 2, 486, 1, 482, 1, 477, 1, 473,
- 1, 469, 1, 464, 1, 460, 1, 456, 1, 451, 1, 447, 1, 443, 1, 439,
- 0, 434, 0, 430, 0, 426, 0, 422, 0, 418, 0, 414, 0, 410, 0, 405,
- 0, 401, 0, 397, 0, 393, 0, 389, 0, 385, 0, 381, 0, 378, 0, 374,
-};
-
-
-//// Counters
-
-#define RATE( rate, div )\
- (rate >= div ? rate / div * 8 - 1 : rate - 1)
-
-static unsigned const counter_mask [32] =
-{
- RATE( 2,2), RATE(2048,4), RATE(1536,3),
- RATE(1280,5), RATE(1024,4), RATE( 768,3),
- RATE( 640,5), RATE( 512,4), RATE( 384,3),
- RATE( 320,5), RATE( 256,4), RATE( 192,3),
- RATE( 160,5), RATE( 128,4), RATE( 96,3),
- RATE( 80,5), RATE( 64,4), RATE( 48,3),
- RATE( 40,5), RATE( 32,4), RATE( 24,3),
- RATE( 20,5), RATE( 16,4), RATE( 12,3),
- RATE( 10,5), RATE( 8,4), RATE( 6,3),
- RATE( 5,5), RATE( 4,4), RATE( 3,3),
- RATE( 2,4),
- RATE( 1,4)
-};
-#undef RATE
-
-inline void Spc_Dsp::init_counter()
-{
- // counters start out with this synchronization
- m.counters [0] = 1;
- m.counters [1] = 0;
- m.counters [2] = -0x20u;
- m.counters [3] = 0x0B;
-
- int n = 2;
- for ( int i = 1; i < 32; i++ )
- {
- m.counter_select [i] = &m.counters [n];
- if ( !--n )
- n = 3;
- }
- m.counter_select [ 0] = &m.counters [0];
- m.counter_select [30] = &m.counters [2];
-}
-
-inline void Spc_Dsp::run_counter( int i )
-{
- int n = m.counters [i];
- if ( !(n-- & 7) )
- n -= 6 - i;
- m.counters [i] = n;
-}
-
-#define READ_COUNTER( rate )\
- (*m.counter_select [rate] & counter_mask [rate])
-
-
-//// Emulation
-
-void Spc_Dsp::run( int clock_count )
-{
- int new_phase = m.phase + clock_count;
- int count = new_phase >> 5;
- m.phase = new_phase & 31;
- if ( !count )
- return;
-
- uint8_t* const ram = m.ram;
- uint8_t const* const dir = &ram [REG(dir) * 0x100];
- int const slow_gaussian = (REG(pmon) >> 1) | REG(non);
- int const noise_rate = REG(flg) & 0x1F;
-
- // Global volume
- int mvoll = (int8_t) REG(mvoll);
- int mvolr = (int8_t) REG(mvolr);
- if ( mvoll * mvolr < m.surround_threshold )
- mvoll = -mvoll; // eliminate surround
-
- do
- {
- // KON/KOFF reading
- if ( (m.every_other_sample ^= 1) != 0 )
- {
- m.new_kon &= ~m.kon;
- m.kon = m.new_kon;
- m.t_koff = REG(koff);
- }
-
- run_counter( 1 );
- run_counter( 2 );
- run_counter( 3 );
-
- // Noise
- if ( !READ_COUNTER( noise_rate ) )
- {
- int feedback = (m.noise << 13) ^ (m.noise << 14);
- m.noise = (feedback & 0x4000) ^ (m.noise >> 1);
- }
-
- // Voices
- int pmon_input = 0;
- int main_out_l = 0;
- int main_out_r = 0;
- int echo_out_l = 0;
- int echo_out_r = 0;
- voice_t* v = m.voices;
- uint8_t* v_regs = m.regs;
- int vbit = 1;
- do
- {
- #define SAMPLE_PTR(i) GET_LE16A( &dir [VREG(v_regs,srcn) * 4 + i * 2] )
-
- int brr_header = ram [v->brr_addr];
- int kon_delay = v->kon_delay;
-
- // Pitch
- int pitch = GET_LE16A( &VREG(v_regs,pitchl) ) & 0x3FFF;
- if ( REG(pmon) & vbit )
- pitch += ((pmon_input >> 5) * pitch) >> 10;
-
- // KON phases
- if ( --kon_delay >= 0 )
- {
- v->kon_delay = kon_delay;
-
- // Get ready to start BRR decoding on next sample
- if ( kon_delay == 4 )
- {
- v->brr_addr = SAMPLE_PTR( 0 );
- v->brr_offset = 1;
- v->buf_pos = v->buf;
- brr_header = 0; // header is ignored on this sample
- }
-
- // Envelope is never run during KON
- v->env = 0;
- v->hidden_env = 0;
-
- // Disable BRR decoding until last three samples
- v->interp_pos = (kon_delay & 3 ? 0x4000 : 0);
-
- // Pitch is never added during KON
- pitch = 0;
- }
-
- int env = v->env;
-
- // Gaussian interpolation
- {
- int output = 0;
- VREG(v_regs,envx) = (uint8_t) (env >> 4);
- if ( env )
- {
- // Make pointers into gaussian based on fractional position between samples
- int offset = (unsigned) v->interp_pos >> 3 & 0x1FE;
- short const* fwd = interleved_gauss + offset;
- short const* rev = interleved_gauss + 510 - offset; // mirror left half of gaussian
-
- int const* in = &v->buf_pos [(unsigned) v->interp_pos >> 12];
-
- if ( !(slow_gaussian & vbit) ) // 99%
- {
- // Faster approximation when exact sample value isn't necessary for pitch mod
- output = (fwd [0] * in [0] +
- fwd [1] * in [1] +
- rev [1] * in [2] +
- rev [0] * in [3]) >> 11;
- output = (output * env) >> 11;
- }
- else
- {
- output = (int16_t) (m.noise * 2);
- if ( !(REG(non) & vbit) )
- {
- output = (fwd [0] * in [0]) >> 11;
- output += (fwd [1] * in [1]) >> 11;
- output += (rev [1] * in [2]) >> 11;
- output = (int16_t) output;
- output += (rev [0] * in [3]) >> 11;
-
- CLAMP16( output );
- output &= ~1;
- }
- output = (output * env) >> 11 & ~1;
- }
-
- // Output
- int l = output * v->volume [0];
- int r = output * v->volume [1];
-
- main_out_l += l;
- main_out_r += r;
-
- if ( REG(eon) & vbit )
- {
- echo_out_l += l;
- echo_out_r += r;
- }
- }
-
- pmon_input = output;
- VREG(v_regs,outx) = (uint8_t) (output >> 8);
- }
-
- // Soft reset or end of sample
- if ( REG(flg) & 0x80 || (brr_header & 3) == 1 )
- {
- v->env_mode = env_release;
- env = 0;
- }
-
- if ( m.every_other_sample )
- {
- // KOFF
- if ( m.t_koff & vbit )
- v->env_mode = env_release;
-
- // KON
- if ( m.kon & vbit )
- {
- v->kon_delay = 5;
- v->env_mode = env_attack;
- REG(endx) &= ~vbit;
- }
- }
-
- // Envelope
- if ( !v->kon_delay )
- {
- if ( v->env_mode == env_release ) // 97%
- {
- env -= 0x8;
- v->env = env;
- if ( env <= 0 )
- {
- v->env = 0;
- goto skip_brr; // no BRR decoding for you!
- }
- }
- else // 3%
- {
- int rate;
- int const adsr0 = VREG(v_regs,adsr0);
- int env_data = VREG(v_regs,adsr1);
- if ( adsr0 >= 0x80 ) // 97% ADSR
- {
- if ( v->env_mode > env_decay ) // 89%
- {
- env--;
- env -= env >> 8;
- rate = env_data & 0x1F;
-
- // optimized handling
- v->hidden_env = env;
- if ( READ_COUNTER( rate ) )
- goto exit_env;
- v->env = env;
- goto exit_env;
- }
- else if ( v->env_mode == env_decay )
- {
- env--;
- env -= env >> 8;
- rate = (adsr0 >> 3 & 0x0E) + 0x10;
- }
- else // env_attack
- {
- rate = (adsr0 & 0x0F) * 2 + 1;
- env += rate < 31 ? 0x20 : 0x400;
- }
- }
- else // GAIN
- {
- int mode;
- env_data = VREG(v_regs,gain);
- mode = env_data >> 5;
- if ( mode < 4 ) // direct
- {
- env = env_data * 0x10;
- rate = 31;
- }
- else
- {
- rate = env_data & 0x1F;
- if ( mode == 4 ) // 4: linear decrease
- {
- env -= 0x20;
- }
- else if ( mode < 6 ) // 5: exponential decrease
- {
- env--;
- env -= env >> 8;
- }
- else // 6,7: linear increase
- {
- env += 0x20;
- if ( mode > 6 && (unsigned) v->hidden_env >= 0x600 )
- env += 0x8 - 0x20; // 7: two-slope linear increase
- }
- }
- }
-
- // Sustain level
- if ( (env >> 8) == (env_data >> 5) && v->env_mode == env_decay )
- v->env_mode = env_sustain;
-
- v->hidden_env = env;
-
- // unsigned cast because linear decrease going negative also triggers this
- if ( (unsigned) env > 0x7FF )
- {
- env = (env < 0 ? 0 : 0x7FF);
- if ( v->env_mode == env_attack )
- v->env_mode = env_decay;
- }
-
- if ( !READ_COUNTER( rate ) )
- v->env = env; // nothing else is controlled by the counter
- }
- }
- exit_env:
-
- {
- // Apply pitch
- int old_pos = v->interp_pos;
- int interp_pos = (old_pos & 0x3FFF) + pitch;
- if ( interp_pos > 0x7FFF )
- interp_pos = 0x7FFF;
- v->interp_pos = interp_pos;
-
- // BRR decode if necessary
- if ( old_pos >= 0x4000 )
- {
- // Arrange the four input nybbles in 0xABCD order for easy decoding
- int nybbles = ram [(v->brr_addr + v->brr_offset) & 0xFFFF] * 0x100 +
- ram [(v->brr_addr + v->brr_offset + 1) & 0xFFFF];
-
- // Advance read position
- int const brr_block_size = 9;
- int brr_offset = v->brr_offset;
- if ( (brr_offset += 2) >= brr_block_size )
- {
- // Next BRR block
- int brr_addr = (v->brr_addr + brr_block_size) & 0xFFFF;
- assert( brr_offset == brr_block_size );
- if ( brr_header & 1 )
- {
- brr_addr = SAMPLE_PTR( 1 );
- if ( !v->kon_delay )
- REG(endx) |= vbit;
- }
- v->brr_addr = brr_addr;
- brr_offset = 1;
- }
- v->brr_offset = brr_offset;
-
- // Decode
-
- // 0: >>1 1: <<0 2: <<1 ... 12: <<11 13-15: >>4 <<11
- static unsigned char const shifts [16 * 2] = {
- 13,12,12,12,12,12,12,12,12,12,12, 12, 12, 16, 16, 16,
- 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 11
- };
- int const scale = brr_header >> 4;
- int const right_shift = shifts [scale];
- int const left_shift = shifts [scale + 16];
-
- // Write to next four samples in circular buffer
- int* pos = v->buf_pos;
- int* end;
-
- // Decode four samples
- for ( end = pos + 4; pos < end; pos++, nybbles <<= 4 )
- {
- // Extract upper nybble and scale appropriately
- int s = ((int16_t) nybbles >> right_shift) << left_shift;
-
- // Apply IIR filter (8 is the most commonly used)
- int const filter = brr_header & 0x0C;
- int const p1 = pos [brr_buf_size - 1];
- int const p2 = pos [brr_buf_size - 2] >> 1;
- if ( filter >= 8 )
- {
- s += p1;
- s -= p2;
- if ( filter == 8 ) // s += p1 * 0.953125 - p2 * 0.46875
- {
- s += p2 >> 4;
- s += (p1 * -3) >> 6;
- }
- else // s += p1 * 0.8984375 - p2 * 0.40625
- {
- s += (p1 * -13) >> 7;
- s += (p2 * 3) >> 4;
- }
- }
- else if ( filter ) // s += p1 * 0.46875
- {
- s += p1 >> 1;
- s += (-p1) >> 5;
- }
-
- // Adjust and write sample
- CLAMP16( s );
- s = (int16_t) (s * 2);
- pos [brr_buf_size] = pos [0] = s; // second copy simplifies wrap-around
- }
-
- if ( pos >= &v->buf [brr_buf_size] )
- pos = v->buf;
- v->buf_pos = pos;
- }
- }
-skip_brr:
- // Next voice
- vbit <<= 1;
- v_regs += 0x10;
- v++;
- }
- while ( vbit < 0x100 );
-
- // Echo position
- int echo_offset = m.echo_offset;
- uint8_t* const echo_ptr = &ram [(REG(esa) * 0x100 + echo_offset) & 0xFFFF];
- if ( !echo_offset )
- m.echo_length = (REG(edl) & 0x0F) * 0x800;
- echo_offset += 4;
- if ( echo_offset >= m.echo_length )
- echo_offset = 0;
- m.echo_offset = echo_offset;
-
- // FIR
- int echo_in_l = GET_LE16SA( echo_ptr + 0 );
- int echo_in_r = GET_LE16SA( echo_ptr + 2 );
-
- int (*echo_hist_pos) [2] = m.echo_hist_pos;
- if ( ++echo_hist_pos >= &m.echo_hist [echo_hist_size] )
- echo_hist_pos = m.echo_hist;
- m.echo_hist_pos = echo_hist_pos;
-
- echo_hist_pos [0] [0] = echo_hist_pos [8] [0] = echo_in_l;
- echo_hist_pos [0] [1] = echo_hist_pos [8] [1] = echo_in_r;
-
- #define CALC_FIR_( i, in ) ((in) * (int8_t) REG(fir + i * 0x10))
- echo_in_l = CALC_FIR_( 7, echo_in_l );
- echo_in_r = CALC_FIR_( 7, echo_in_r );
-
- #define CALC_FIR( i, ch ) CALC_FIR_( i, echo_hist_pos [i + 1] [ch] )
- #define DO_FIR( i )\
- echo_in_l += CALC_FIR( i, 0 );\
- echo_in_r += CALC_FIR( i, 1 );
- DO_FIR( 0 );
- DO_FIR( 1 );
- DO_FIR( 2 );
- #if defined (__MWERKS__) && __MWERKS__ < 0x3200
- __eieio(); // keeps compiler from stupidly "caching" things in memory
- #endif
- DO_FIR( 3 );
- DO_FIR( 4 );
- DO_FIR( 5 );
- DO_FIR( 6 );
-
- // Echo out
- if ( !(REG(flg) & 0x20) )
- {
- int l = (echo_out_l >> 7) + ((echo_in_l * (int8_t) REG(efb)) >> 14);
- int r = (echo_out_r >> 7) + ((echo_in_r * (int8_t) REG(efb)) >> 14);
-
- // just to help pass more validation tests
- #if SPC_MORE_ACCURACY
- l &= ~1;
- r &= ~1;
- #endif
-
- CLAMP16( l );
- CLAMP16( r );
-
- SET_LE16A( echo_ptr + 0, l );
- SET_LE16A( echo_ptr + 2, r );
- }
-
- // Sound out
- int l = (main_out_l * mvoll + echo_in_l * (int8_t) REG(evoll)) >> 14;
- int r = (main_out_r * mvolr + echo_in_r * (int8_t) REG(evolr)) >> 14;
-
- CLAMP16( l );
- CLAMP16( r );
-
- if ( (REG(flg) & 0x40) )
- {
- l = 0;
- r = 0;
- }
-
- sample_t* out = m.out;
- WRITE_SAMPLES( l, r, out );
- m.out = out;
- }
- while ( --count );
-}
-
-
-//// Setup
-
-void Spc_Dsp::mute_voices( int mask )
-{
- m.mute_mask = mask;
- for ( int i = 0; i < voice_count; i++ )
- {
- m.voices [i].enabled = (mask >> i & 1) - 1;
- update_voice_vol( i * 0x10 );
- }
-}
-
-void Spc_Dsp::init( void* ram_64k )
-{
- m.ram = (uint8_t*) ram_64k;
- mute_voices( 0 );
- disable_surround( false );
- set_output( 0, 0 );
- reset();
-
- #ifndef NDEBUG
- // be sure this sign-extends
- assert( (int16_t) 0x8000 == -0x8000 );
-
- // be sure right shift preserves sign
- assert( (-1 >> 1) == -1 );
-
- // check clamp macro
- int i;
- i = +0x8000; CLAMP16( i ); assert( i == +0x7FFF );
- i = -0x8001; CLAMP16( i ); assert( i == -0x8000 );
- #endif
-}
-
-void Spc_Dsp::soft_reset_common()
-{
- require( m.ram ); // init() must have been called already
-
- m.noise = 0x4000;
- m.echo_hist_pos = m.echo_hist;
- m.every_other_sample = 1;
- m.echo_offset = 0;
- m.phase = 0;
-
- init_counter();
-}
-
-void Spc_Dsp::soft_reset()
-{
- REG(flg) = 0xE0;
- soft_reset_common();
-}
-
-void Spc_Dsp::load( uint8_t const regs [register_count] )
-{
- memcpy( m.regs, regs, sizeof m.regs );
- memset( &m.regs [register_count], 0, offsetof (state_t,ram) - register_count );
-
- // Internal state
- int i;
- for ( i = voice_count; --i >= 0; )
- {
- voice_t& v = m.voices [i];
- v.brr_offset = 1;
- v.buf_pos = v.buf;
- }
- m.new_kon = REG(kon);
-
- mute_voices( m.mute_mask );
- soft_reset_common();
-}
-
-void Spc_Dsp::reset() { load( initial_regs ); }
diff --git a/src/console/Spc_Dsp.h b/src/console/Spc_Dsp.h
index 080c1d2978f2..bc1070d6bad1 100644
--- a/src/console/Spc_Dsp.h
+++ b/src/console/Spc_Dsp.h
@@ -13,7 +13,7 @@ public:
// Initializes DSP and has it use the 64K RAM provided
void init( void* ram_64k );
- // Sets destination for output samples. If out is NULL or out_size is 0,
+ // Sets destination for output samples. If out is nullptr or out_size is 0,
// doesn't generate any.
typedef short sample_t;
void set_output( sample_t* out, int out_size );
diff --git a/src/console/Spc_Emu.cc b/src/console/Spc_Emu.cc
new file mode 100644
index 000000000000..b147c1cc9449
--- /dev/null
+++ b/src/console/Spc_Emu.cc
@@ -0,0 +1,352 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Spc_Emu.h"
+
+#include "blargg_endian.h"
+#include <stdlib.h>
+#include <string.h>
+
+/* Copyright (C) 2004-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+// TODO: support Spc_Filter's bass
+
+Spc_Emu::Spc_Emu()
+{
+ set_type( gme_spc_type );
+
+ static const char* const names [Snes_Spc::voice_count] = {
+ "DSP 1", "DSP 2", "DSP 3", "DSP 4", "DSP 5", "DSP 6", "DSP 7", "DSP 8"
+ };
+ set_voice_names( names );
+
+ set_gain( 1.4 );
+}
+
+Spc_Emu::~Spc_Emu() { }
+
+// Track info
+
+long const trailer_offset = 0x10200;
+
+byte const* Spc_Emu::trailer() const { return &file_data [min( file_size, trailer_offset )]; }
+
+long Spc_Emu::trailer_size() const { return max( 0L, file_size - trailer_offset ); }
+
+static void get_spc_xid6( byte const* begin, long size, track_info_t* out )
+{
+ // header
+ byte const* end = begin + size;
+ if ( size < 8 || memcmp( begin, "xid6", 4 ) )
+ {
+ check( false );
+ return;
+ }
+ long info_size = GET_LE32( begin + 4 );
+ byte const* in = begin + 8;
+ if ( end - in > info_size )
+ {
+ debug_printf( "Extra data after SPC xid6 info\n" );
+ end = in + info_size;
+ }
+
+ int year = 0;
+ char copyright [256 + 5];
+ int copyright_len = 0;
+ int const year_len = 5;
+
+ while ( end - in >= 4 )
+ {
+ // header
+ int id = in [0];
+ int data = in [3] * 0x100 + in [2];
+ int type = in [1];
+ int len = type ? data : 0;
+ in += 4;
+ if ( len > end - in )
+ {
+ check( false );
+ break; // block goes past end of data
+ }
+
+ // handle specific block types
+ char* field = 0;
+ switch ( id )
+ {
+ case 0x01: field = out->song; break;
+ case 0x02: field = out->game; break;
+ case 0x03: field = out->author; break;
+ case 0x04: field = out->dumper; break;
+ case 0x07: field = out->comment; break;
+ case 0x14: year = data; break;
+
+ //case 0x30: // intro length
+ // Many SPCs have intro length set wrong for looped tracks, making it useless
+ /*
+ case 0x30:
+ check( len == 4 );
+ if ( len >= 4 )
+ {
+ out->intro_length = GET_LE32( in ) / 64;
+ if ( out->length > 0 )
+ {
+ long loop = out->length - out->intro_length;
+ if ( loop >= 2000 )
+ out->loop_length = loop;
+ }
+ }
+ break;
+ */
+
+ case 0x13:
+ copyright_len = min( len, (int) sizeof copyright - year_len );
+ memcpy( ©right [year_len], in, copyright_len );
+ break;
+
+ default:
+ if ( id < 0x01 || (id > 0x07 && id < 0x10) ||
+ (id > 0x14 && id < 0x30) || id > 0x36 )
+ debug_printf( "Unknown SPC xid6 block: %X\n", (int) id );
+ break;
+ }
+ if ( field )
+ {
+ check( type == 1 );
+ Gme_File::copy_field_( field, (char const*) in, len );
+ }
+
+ // skip to next block
+ in += len;
+
+ // blocks are supposed to be 4-byte aligned with zero-padding...
+ byte const* unaligned = in;
+ while ( (in - begin) & 3 && in < end )
+ {
+ if ( *in++ != 0 )
+ {
+ // ...but some files have no padding
+ in = unaligned;
+ debug_printf( "SPC info tag wasn't properly padded to align\n" );
+ break;
+ }
+ }
+ }
+
+ char* p = ©right [year_len];
+ if ( year )
+ {
+ *--p = ' ';
+ for ( int n = 4; n--; )
+ {
+ *--p = char (year % 10 + '0');
+ year /= 10;
+ }
+ copyright_len += year_len;
+ }
+ if ( copyright_len )
+ Gme_File::copy_field_( out->copyright, p, copyright_len );
+
+ check( in == end );
+}
+
+static void get_spc_info( Spc_Emu::header_t const& h, byte const* xid6, long xid6_size,
+ track_info_t* out )
+{
+ // decode length (can be in text or binary format, sometimes ambiguous ugh)
+ long len_secs = 0;
+ for ( int i = 0; i < 3; i++ )
+ {
+ unsigned n = h.len_secs [i] - '0';
+ if ( n > 9 )
+ {
+ // ignore single-digit text lengths
+ // (except if author field is present and begins at offset 1, ugh)
+ if ( i == 1 && (h.author [0] || !h.author [1]) )
+ len_secs = 0;
+ break;
+ }
+ len_secs *= 10;
+ len_secs += n;
+ }
+ if ( !len_secs || len_secs > 0x1FFF )
+ len_secs = GET_LE16( h.len_secs );
+ if ( len_secs < 0x1FFF )
+ out->length = len_secs * 1000;
+
+ int offset = (h.author [0] < ' ' || unsigned (h.author [0] - '0') <= 9);
+ Gme_File::copy_field_( out->author, &h.author [offset], sizeof h.author - offset );
+
+ GME_COPY_FIELD( h, out, song );
+ GME_COPY_FIELD( h, out, game );
+ GME_COPY_FIELD( h, out, dumper );
+ GME_COPY_FIELD( h, out, comment );
+
+ if ( xid6_size )
+ get_spc_xid6( xid6, xid6_size, out );
+}
+
+blargg_err_t Spc_Emu::track_info_( track_info_t* out, int ) const
+{
+ get_spc_info( header(), trailer(), trailer_size(), out );
+ return 0;
+}
+
+static blargg_err_t check_spc_header( void const* header )
+{
+ if ( memcmp( header, "SNES-SPC700 Sound File Data", 27 ) )
+ return gme_wrong_file_type;
+ return 0;
+}
+
+struct Spc_File : Gme_Info_
+{
+ Spc_Emu::header_t header;
+ blargg_vector<byte> xid6;
+
+ Spc_File() { set_type( gme_spc_type ); }
+
+ blargg_err_t load_( Data_Reader& in )
+ {
+ long file_size = in.remain();
+ if ( file_size < Snes_Spc::spc_min_file_size )
+ return gme_wrong_file_type;
+ RETURN_ERR( in.read( &header, Spc_Emu::header_size ) );
+ RETURN_ERR( check_spc_header( header.tag ) );
+ long const xid6_offset = 0x10200;
+ long xid6_size = file_size - xid6_offset;
+ if ( xid6_size > 0 )
+ {
+ RETURN_ERR( xid6.resize( xid6_size ) );
+ RETURN_ERR( in.skip( xid6_offset - Spc_Emu::header_size ) );
+ RETURN_ERR( in.read( xid6.begin(), xid6.size() ) );
+ }
+ return 0;
+ }
+
+ blargg_err_t track_info_( track_info_t* out, int ) const
+ {
+ get_spc_info( header, xid6.begin(), xid6.size(), out );
+ return 0;
+ }
+};
+
+static Music_Emu* new_spc_emu () { return BLARGG_NEW Spc_Emu ; }
+static Music_Emu* new_spc_file() { return BLARGG_NEW Spc_File; }
+
+static gme_type_t_ const gme_spc_type_ = { "Super Nintendo", 1, &new_spc_emu, &new_spc_file, "SPC", 0 };
+gme_type_t const gme_spc_type = &gme_spc_type_;
+
+
+// Setup
+
+blargg_err_t Spc_Emu::set_sample_rate_( long sample_rate )
+{
+ RETURN_ERR( apu.init() );
+ enable_accuracy( false );
+ if ( sample_rate != native_sample_rate )
+ {
+ RETURN_ERR( resampler.buffer_size( native_sample_rate / 20 * 2 ) );
+ resampler.time_ratio( (double) native_sample_rate / sample_rate, 0.9965 );
+ }
+ return 0;
+}
+
+void Spc_Emu::enable_accuracy_( bool b )
+{
+ Music_Emu::enable_accuracy_( b );
+ filter.enable( b );
+}
+
+void Spc_Emu::mute_voices_( int m )
+{
+ Music_Emu::mute_voices_( m );
+ apu.mute_voices( m );
+}
+
+blargg_err_t Spc_Emu::load_mem_( byte const* in, long size )
+{
+ assert( offsetof (header_t,unused2 [46]) == header_size );
+ file_data = in;
+ file_size = size;
+ set_voice_count( Snes_Spc::voice_count );
+ if ( size < Snes_Spc::spc_min_file_size )
+ return gme_wrong_file_type;
+ return check_spc_header( in );
+}
+
+// Emulation
+
+void Spc_Emu::set_tempo_( double t )
+{
+ apu.set_tempo( (int) (t * apu.tempo_unit) );
+}
+
+blargg_err_t Spc_Emu::start_track_( int track )
+{
+ RETURN_ERR( Music_Emu::start_track_( track ) );
+ resampler.clear();
+ filter.clear();
+ RETURN_ERR( apu.load_spc( file_data, file_size ) );
+ filter.set_gain( (int) (gain() * SPC_Filter::gain_unit) );
+ apu.clear_echo();
+ return 0;
+}
+
+blargg_err_t Spc_Emu::play_and_filter( long count, sample_t out [] )
+{
+ RETURN_ERR( apu.play( count, out ) );
+ filter.run( out, count );
+ return 0;
+}
+
+blargg_err_t Spc_Emu::skip_( long count )
+{
+ if ( sample_rate() != native_sample_rate )
+ {
+ count = long (count * resampler.ratio()) & ~1;
+ count -= resampler.skip_input( count );
+ }
+
+ // TODO: shouldn't skip be adjusted for the 64 samples read afterwards?
+
+ if ( count > 0 )
+ {
+ RETURN_ERR( apu.skip( count ) );
+ filter.clear();
+ }
+
+ // eliminate pop due to resampler
+ const int resampler_latency = 64;
+ sample_t buf [resampler_latency];
+ return play_( resampler_latency, buf );
+}
+
+blargg_err_t Spc_Emu::play_( long count, sample_t* out )
+{
+ if ( sample_rate() == native_sample_rate )
+ return play_and_filter( count, out );
+
+ long remain = count;
+ while ( remain > 0 )
+ {
+ remain -= resampler.read( &out [count - remain], remain );
+ if ( remain > 0 )
+ {
+ long n = resampler.max_write();
+ RETURN_ERR( play_and_filter( n, resampler.buffer() ) );
+ resampler.write( n );
+ }
+ }
+ check( remain == 0 );
+ return 0;
+}
diff --git a/src/console/Spc_Emu.cxx b/src/console/Spc_Emu.cxx
deleted file mode 100644
index b147c1cc9449..000000000000
--- a/src/console/Spc_Emu.cxx
+++ /dev/null
@@ -1,352 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Spc_Emu.h"
-
-#include "blargg_endian.h"
-#include <stdlib.h>
-#include <string.h>
-
-/* Copyright (C) 2004-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// TODO: support Spc_Filter's bass
-
-Spc_Emu::Spc_Emu()
-{
- set_type( gme_spc_type );
-
- static const char* const names [Snes_Spc::voice_count] = {
- "DSP 1", "DSP 2", "DSP 3", "DSP 4", "DSP 5", "DSP 6", "DSP 7", "DSP 8"
- };
- set_voice_names( names );
-
- set_gain( 1.4 );
-}
-
-Spc_Emu::~Spc_Emu() { }
-
-// Track info
-
-long const trailer_offset = 0x10200;
-
-byte const* Spc_Emu::trailer() const { return &file_data [min( file_size, trailer_offset )]; }
-
-long Spc_Emu::trailer_size() const { return max( 0L, file_size - trailer_offset ); }
-
-static void get_spc_xid6( byte const* begin, long size, track_info_t* out )
-{
- // header
- byte const* end = begin + size;
- if ( size < 8 || memcmp( begin, "xid6", 4 ) )
- {
- check( false );
- return;
- }
- long info_size = GET_LE32( begin + 4 );
- byte const* in = begin + 8;
- if ( end - in > info_size )
- {
- debug_printf( "Extra data after SPC xid6 info\n" );
- end = in + info_size;
- }
-
- int year = 0;
- char copyright [256 + 5];
- int copyright_len = 0;
- int const year_len = 5;
-
- while ( end - in >= 4 )
- {
- // header
- int id = in [0];
- int data = in [3] * 0x100 + in [2];
- int type = in [1];
- int len = type ? data : 0;
- in += 4;
- if ( len > end - in )
- {
- check( false );
- break; // block goes past end of data
- }
-
- // handle specific block types
- char* field = 0;
- switch ( id )
- {
- case 0x01: field = out->song; break;
- case 0x02: field = out->game; break;
- case 0x03: field = out->author; break;
- case 0x04: field = out->dumper; break;
- case 0x07: field = out->comment; break;
- case 0x14: year = data; break;
-
- //case 0x30: // intro length
- // Many SPCs have intro length set wrong for looped tracks, making it useless
- /*
- case 0x30:
- check( len == 4 );
- if ( len >= 4 )
- {
- out->intro_length = GET_LE32( in ) / 64;
- if ( out->length > 0 )
- {
- long loop = out->length - out->intro_length;
- if ( loop >= 2000 )
- out->loop_length = loop;
- }
- }
- break;
- */
-
- case 0x13:
- copyright_len = min( len, (int) sizeof copyright - year_len );
- memcpy( ©right [year_len], in, copyright_len );
- break;
-
- default:
- if ( id < 0x01 || (id > 0x07 && id < 0x10) ||
- (id > 0x14 && id < 0x30) || id > 0x36 )
- debug_printf( "Unknown SPC xid6 block: %X\n", (int) id );
- break;
- }
- if ( field )
- {
- check( type == 1 );
- Gme_File::copy_field_( field, (char const*) in, len );
- }
-
- // skip to next block
- in += len;
-
- // blocks are supposed to be 4-byte aligned with zero-padding...
- byte const* unaligned = in;
- while ( (in - begin) & 3 && in < end )
- {
- if ( *in++ != 0 )
- {
- // ...but some files have no padding
- in = unaligned;
- debug_printf( "SPC info tag wasn't properly padded to align\n" );
- break;
- }
- }
- }
-
- char* p = ©right [year_len];
- if ( year )
- {
- *--p = ' ';
- for ( int n = 4; n--; )
- {
- *--p = char (year % 10 + '0');
- year /= 10;
- }
- copyright_len += year_len;
- }
- if ( copyright_len )
- Gme_File::copy_field_( out->copyright, p, copyright_len );
-
- check( in == end );
-}
-
-static void get_spc_info( Spc_Emu::header_t const& h, byte const* xid6, long xid6_size,
- track_info_t* out )
-{
- // decode length (can be in text or binary format, sometimes ambiguous ugh)
- long len_secs = 0;
- for ( int i = 0; i < 3; i++ )
- {
- unsigned n = h.len_secs [i] - '0';
- if ( n > 9 )
- {
- // ignore single-digit text lengths
- // (except if author field is present and begins at offset 1, ugh)
- if ( i == 1 && (h.author [0] || !h.author [1]) )
- len_secs = 0;
- break;
- }
- len_secs *= 10;
- len_secs += n;
- }
- if ( !len_secs || len_secs > 0x1FFF )
- len_secs = GET_LE16( h.len_secs );
- if ( len_secs < 0x1FFF )
- out->length = len_secs * 1000;
-
- int offset = (h.author [0] < ' ' || unsigned (h.author [0] - '0') <= 9);
- Gme_File::copy_field_( out->author, &h.author [offset], sizeof h.author - offset );
-
- GME_COPY_FIELD( h, out, song );
- GME_COPY_FIELD( h, out, game );
- GME_COPY_FIELD( h, out, dumper );
- GME_COPY_FIELD( h, out, comment );
-
- if ( xid6_size )
- get_spc_xid6( xid6, xid6_size, out );
-}
-
-blargg_err_t Spc_Emu::track_info_( track_info_t* out, int ) const
-{
- get_spc_info( header(), trailer(), trailer_size(), out );
- return 0;
-}
-
-static blargg_err_t check_spc_header( void const* header )
-{
- if ( memcmp( header, "SNES-SPC700 Sound File Data", 27 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Spc_File : Gme_Info_
-{
- Spc_Emu::header_t header;
- blargg_vector<byte> xid6;
-
- Spc_File() { set_type( gme_spc_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- long file_size = in.remain();
- if ( file_size < Snes_Spc::spc_min_file_size )
- return gme_wrong_file_type;
- RETURN_ERR( in.read( &header, Spc_Emu::header_size ) );
- RETURN_ERR( check_spc_header( header.tag ) );
- long const xid6_offset = 0x10200;
- long xid6_size = file_size - xid6_offset;
- if ( xid6_size > 0 )
- {
- RETURN_ERR( xid6.resize( xid6_size ) );
- RETURN_ERR( in.skip( xid6_offset - Spc_Emu::header_size ) );
- RETURN_ERR( in.read( xid6.begin(), xid6.size() ) );
- }
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- get_spc_info( header, xid6.begin(), xid6.size(), out );
- return 0;
- }
-};
-
-static Music_Emu* new_spc_emu () { return BLARGG_NEW Spc_Emu ; }
-static Music_Emu* new_spc_file() { return BLARGG_NEW Spc_File; }
-
-static gme_type_t_ const gme_spc_type_ = { "Super Nintendo", 1, &new_spc_emu, &new_spc_file, "SPC", 0 };
-gme_type_t const gme_spc_type = &gme_spc_type_;
-
-
-// Setup
-
-blargg_err_t Spc_Emu::set_sample_rate_( long sample_rate )
-{
- RETURN_ERR( apu.init() );
- enable_accuracy( false );
- if ( sample_rate != native_sample_rate )
- {
- RETURN_ERR( resampler.buffer_size( native_sample_rate / 20 * 2 ) );
- resampler.time_ratio( (double) native_sample_rate / sample_rate, 0.9965 );
- }
- return 0;
-}
-
-void Spc_Emu::enable_accuracy_( bool b )
-{
- Music_Emu::enable_accuracy_( b );
- filter.enable( b );
-}
-
-void Spc_Emu::mute_voices_( int m )
-{
- Music_Emu::mute_voices_( m );
- apu.mute_voices( m );
-}
-
-blargg_err_t Spc_Emu::load_mem_( byte const* in, long size )
-{
- assert( offsetof (header_t,unused2 [46]) == header_size );
- file_data = in;
- file_size = size;
- set_voice_count( Snes_Spc::voice_count );
- if ( size < Snes_Spc::spc_min_file_size )
- return gme_wrong_file_type;
- return check_spc_header( in );
-}
-
-// Emulation
-
-void Spc_Emu::set_tempo_( double t )
-{
- apu.set_tempo( (int) (t * apu.tempo_unit) );
-}
-
-blargg_err_t Spc_Emu::start_track_( int track )
-{
- RETURN_ERR( Music_Emu::start_track_( track ) );
- resampler.clear();
- filter.clear();
- RETURN_ERR( apu.load_spc( file_data, file_size ) );
- filter.set_gain( (int) (gain() * SPC_Filter::gain_unit) );
- apu.clear_echo();
- return 0;
-}
-
-blargg_err_t Spc_Emu::play_and_filter( long count, sample_t out [] )
-{
- RETURN_ERR( apu.play( count, out ) );
- filter.run( out, count );
- return 0;
-}
-
-blargg_err_t Spc_Emu::skip_( long count )
-{
- if ( sample_rate() != native_sample_rate )
- {
- count = long (count * resampler.ratio()) & ~1;
- count -= resampler.skip_input( count );
- }
-
- // TODO: shouldn't skip be adjusted for the 64 samples read afterwards?
-
- if ( count > 0 )
- {
- RETURN_ERR( apu.skip( count ) );
- filter.clear();
- }
-
- // eliminate pop due to resampler
- const int resampler_latency = 64;
- sample_t buf [resampler_latency];
- return play_( resampler_latency, buf );
-}
-
-blargg_err_t Spc_Emu::play_( long count, sample_t* out )
-{
- if ( sample_rate() == native_sample_rate )
- return play_and_filter( count, out );
-
- long remain = count;
- while ( remain > 0 )
- {
- remain -= resampler.read( &out [count - remain], remain );
- if ( remain > 0 )
- {
- long n = resampler.max_write();
- RETURN_ERR( play_and_filter( n, resampler.buffer() ) );
- resampler.write( n );
- }
- }
- check( remain == 0 );
- return 0;
-}
diff --git a/src/console/Spc_Filter.cc b/src/console/Spc_Filter.cc
new file mode 100644
index 000000000000..af478127af82
--- /dev/null
+++ b/src/console/Spc_Filter.cc
@@ -0,0 +1,83 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Spc_Filter.h"
+
+#include <string.h>
+
+/* Copyright (C) 2007 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+void SPC_Filter::clear() { memset( ch, 0, sizeof ch ); }
+
+SPC_Filter::SPC_Filter()
+{
+ enabled = true;
+ gain = gain_unit;
+ bass = bass_norm;
+ clear();
+}
+
+void SPC_Filter::run( short* io, int count )
+{
+ require( (count & 1) == 0 ); // must be even
+
+ int const gain = this->gain;
+ if ( enabled )
+ {
+ int const bass = this->bass;
+ chan_t* c = &ch [2];
+ do
+ {
+ // cache in registers
+ int sum = (--c)->sum;
+ int pp1 = c->pp1;
+ int p1 = c->p1;
+
+ for ( int i = 0; i < count; i += 2 )
+ {
+ // Low-pass filter (two point FIR with coeffs 0.25, 0.75)
+ int f = io [i] + p1;
+ p1 = io [i] * 3;
+
+ // High-pass filter ("leaky integrator")
+ int delta = f - pp1;
+ pp1 = f;
+ int s = sum >> (gain_bits + 2);
+ sum += (delta * gain) - (sum >> bass);
+
+ // Clamp to 16 bits
+ if ( (short) s != s )
+ s = (s >> 31) ^ 0x7FFF;
+
+ io [i] = (short) s;
+ }
+
+ c->p1 = p1;
+ c->pp1 = pp1;
+ c->sum = sum;
+ ++io;
+ }
+ while ( c != ch );
+ }
+ else if ( gain != gain_unit )
+ {
+ short* const end = io + count;
+ while ( io < end )
+ {
+ int s = (*io * gain) >> gain_bits;
+ if ( (short) s != s )
+ s = (s >> 31) ^ 0x7FFF;
+ *io++ = (short) s;
+ }
+ }
+}
diff --git a/src/console/Spc_Filter.cxx b/src/console/Spc_Filter.cxx
deleted file mode 100644
index af478127af82..000000000000
--- a/src/console/Spc_Filter.cxx
+++ /dev/null
@@ -1,83 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Spc_Filter.h"
-
-#include <string.h>
-
-/* Copyright (C) 2007 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-void SPC_Filter::clear() { memset( ch, 0, sizeof ch ); }
-
-SPC_Filter::SPC_Filter()
-{
- enabled = true;
- gain = gain_unit;
- bass = bass_norm;
- clear();
-}
-
-void SPC_Filter::run( short* io, int count )
-{
- require( (count & 1) == 0 ); // must be even
-
- int const gain = this->gain;
- if ( enabled )
- {
- int const bass = this->bass;
- chan_t* c = &ch [2];
- do
- {
- // cache in registers
- int sum = (--c)->sum;
- int pp1 = c->pp1;
- int p1 = c->p1;
-
- for ( int i = 0; i < count; i += 2 )
- {
- // Low-pass filter (two point FIR with coeffs 0.25, 0.75)
- int f = io [i] + p1;
- p1 = io [i] * 3;
-
- // High-pass filter ("leaky integrator")
- int delta = f - pp1;
- pp1 = f;
- int s = sum >> (gain_bits + 2);
- sum += (delta * gain) - (sum >> bass);
-
- // Clamp to 16 bits
- if ( (short) s != s )
- s = (s >> 31) ^ 0x7FFF;
-
- io [i] = (short) s;
- }
-
- c->p1 = p1;
- c->pp1 = pp1;
- c->sum = sum;
- ++io;
- }
- while ( c != ch );
- }
- else if ( gain != gain_unit )
- {
- short* const end = io + count;
- while ( io < end )
- {
- int s = (*io * gain) >> gain_bits;
- if ( (short) s != s )
- s = (s >> 31) ^ 0x7FFF;
- *io++ = (short) s;
- }
- }
-}
diff --git a/src/console/Track_Emu.cc b/src/console/Track_Emu.cc
new file mode 100644
index 000000000000..d70ea861a37a
--- /dev/null
+++ b/src/console/Track_Emu.cc
@@ -0,0 +1,186 @@
+
+// Game_Music_Emu 0.3.0. http://www.slack.net/~ant/
+
+#include "Track_Emu.h"
+
+#include <string.h>
+#include <math.h>
+
+/* Copyright (C) 2005-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include BLARGG_SOURCE_BEGIN
+
+int const stereo = 2; // channels for a stereo signal
+int const fade_block_size = 512;
+int const fade_length = 8000; // msec
+int const silence_max = 6; // seconds
+int const silence_threshold = 0x10;
+
+long Track_Emu::msec_to_samples( long msec ) const
+{
+ long rate = emu->sample_rate() * stereo;
+ return (msec / 1000L) * rate + (msec % 1000L) * rate / 1000;
+}
+
+void Track_Emu::sync( long time )
+{
+ buf_count = 0;
+ silence_count = 0;
+ emu_time = time;
+ out_time = time;
+ silence_time = time;
+ track_ended = time > fade_time + fade_length * stereo * emu->sample_rate();
+}
+
+void Track_Emu::restart_track()
+{
+ emu->start_track( track );
+ sync ( 0 );
+
+ // skip initial silence
+ for ( int n = 40 * stereo * emu->sample_rate() / buf_size; n--; )
+ {
+ fill_buf( true );
+ if ( buf_count || track_ended )
+ break;
+ }
+ sync( 0 );
+}
+
+void Track_Emu::seek( long time )
+{
+ long pos = msec_to_samples( time ) & ~1;
+ if ( pos < out_time )
+ restart_track();
+ emu->skip( pos - emu_time );
+ sync( pos );
+}
+
+long Track_Emu::tell() const
+{
+ long rate = emu->sample_rate() * stereo;
+ return (out_time / rate * 1000) + (out_time % rate * 1000 / rate);
+}
+
+void Track_Emu::start_track( Music_Emu* e, int t, long length, bool ds )
+{
+// to do: remove
+//length = 50 * 1000;
+//ds = true;
+//t = 23;
+
+ emu = e;
+ track = t;
+ detect_silence = ds;
+ fade_factor = pow( 0.005, 1.0 / msec_to_samples( fade_length ) );
+ fade_time = msec_to_samples( length );
+ restart_track();
+}
+
+static bool is_silence( const Music_Emu::sample_t* p, int count )
+{
+ while ( count-- )
+ {
+ if ( (unsigned) (*p++ + silence_threshold / 2) > (unsigned) silence_threshold )
+ return false;
+ }
+ return true;
+}
+
+void Track_Emu::fill_buf( bool check_silence )
+{
+ emu->play( buf_size, buf );
+ emu_time += buf_size;
+ if ( (check_silence || emu_time > fade_time) && is_silence( buf, buf_size ) )
+ {
+ silence_count += buf_size;
+ }
+ else
+ {
+ silence_time = emu_time;
+ buf_count = buf_size;
+ }
+ if ( emu->track_ended() || emu->error_count() )
+ track_ended = true;
+}
+
+inline void Track_Emu::end_track()
+{
+ silence_count = 0;
+ buf_count = 0;
+ track_ended = true;
+}
+
+bool Track_Emu::play( int out_count, Music_Emu::sample_t* out )
+{
+ assert( out_count % 2 == 0 );
+ assert( emu );
+
+ int pos = 0;
+ while ( pos < out_count )
+ {
+ // fill with any remaining silence
+ int count = min( silence_count, out_count - pos );
+ if ( count )
+ {
+ silence_count -= count;
+ memset( &out [pos], 0, count * sizeof *out );
+ }
+ else
+ {
+ // empty internal buffer
+ count = min( buf_count, out_count - pos );
+ if ( !count && track_ended )
+ {
+ memset( &out [pos], 0, (out_count - pos) * sizeof *out );
+ return true;
+ }
+
+ memcpy( &out [pos], &buf [buf_size - buf_count], count * sizeof *out );
+ buf_count -= count;
+ }
+ pos += count;
+
+ // keep internal buffer full and possibly run ahead
+ for ( int n = 6; n--; )
+ {
+ if ( buf_count || track_ended ||
+ emu_time - out_time > silence_max * stereo * emu->sample_rate() )
+ break;
+ fill_buf( detect_silence );
+ }
+ }
+ out_time += out_count;
+
+ if ( detect_silence &&
+ ( emu_time - silence_time > silence_max * stereo * emu->sample_rate() && silence_time ) )
+ end_track();
+
+ // fade if track is ending
+ if ( out_time > fade_time )
+ {
+ for ( int i = 0; i < out_count; i += fade_block_size )
+ {
+ double gain = pow( fade_factor, (double) (out_time + i - fade_time) );
+ if ( gain < 0.005 )
+ end_track();
+
+ int count = min( fade_block_size, out_count - i );
+ int igain = (unsigned int)((double)gain * (1 << 15));;
+ for ( int j = 0; j < count; j++ )
+ out [i + j] = (out [i + j] * igain) >> 15;
+ }
+ }
+
+ return !silence_count && !buf_count && track_ended;
+}
+
diff --git a/src/console/Track_Emu.cxx b/src/console/Track_Emu.cxx
deleted file mode 100644
index d70ea861a37a..000000000000
--- a/src/console/Track_Emu.cxx
+++ /dev/null
@@ -1,186 +0,0 @@
-
-// Game_Music_Emu 0.3.0. http://www.slack.net/~ant/
-
-#include "Track_Emu.h"
-
-#include <string.h>
-#include <math.h>
-
-/* Copyright (C) 2005-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include BLARGG_SOURCE_BEGIN
-
-int const stereo = 2; // channels for a stereo signal
-int const fade_block_size = 512;
-int const fade_length = 8000; // msec
-int const silence_max = 6; // seconds
-int const silence_threshold = 0x10;
-
-long Track_Emu::msec_to_samples( long msec ) const
-{
- long rate = emu->sample_rate() * stereo;
- return (msec / 1000L) * rate + (msec % 1000L) * rate / 1000;
-}
-
-void Track_Emu::sync( long time )
-{
- buf_count = 0;
- silence_count = 0;
- emu_time = time;
- out_time = time;
- silence_time = time;
- track_ended = time > fade_time + fade_length * stereo * emu->sample_rate();
-}
-
-void Track_Emu::restart_track()
-{
- emu->start_track( track );
- sync ( 0 );
-
- // skip initial silence
- for ( int n = 40 * stereo * emu->sample_rate() / buf_size; n--; )
- {
- fill_buf( true );
- if ( buf_count || track_ended )
- break;
- }
- sync( 0 );
-}
-
-void Track_Emu::seek( long time )
-{
- long pos = msec_to_samples( time ) & ~1;
- if ( pos < out_time )
- restart_track();
- emu->skip( pos - emu_time );
- sync( pos );
-}
-
-long Track_Emu::tell() const
-{
- long rate = emu->sample_rate() * stereo;
- return (out_time / rate * 1000) + (out_time % rate * 1000 / rate);
-}
-
-void Track_Emu::start_track( Music_Emu* e, int t, long length, bool ds )
-{
-// to do: remove
-//length = 50 * 1000;
-//ds = true;
-//t = 23;
-
- emu = e;
- track = t;
- detect_silence = ds;
- fade_factor = pow( 0.005, 1.0 / msec_to_samples( fade_length ) );
- fade_time = msec_to_samples( length );
- restart_track();
-}
-
-static bool is_silence( const Music_Emu::sample_t* p, int count )
-{
- while ( count-- )
- {
- if ( (unsigned) (*p++ + silence_threshold / 2) > (unsigned) silence_threshold )
- return false;
- }
- return true;
-}
-
-void Track_Emu::fill_buf( bool check_silence )
-{
- emu->play( buf_size, buf );
- emu_time += buf_size;
- if ( (check_silence || emu_time > fade_time) && is_silence( buf, buf_size ) )
- {
- silence_count += buf_size;
- }
- else
- {
- silence_time = emu_time;
- buf_count = buf_size;
- }
- if ( emu->track_ended() || emu->error_count() )
- track_ended = true;
-}
-
-inline void Track_Emu::end_track()
-{
- silence_count = 0;
- buf_count = 0;
- track_ended = true;
-}
-
-bool Track_Emu::play( int out_count, Music_Emu::sample_t* out )
-{
- assert( out_count % 2 == 0 );
- assert( emu );
-
- int pos = 0;
- while ( pos < out_count )
- {
- // fill with any remaining silence
- int count = min( silence_count, out_count - pos );
- if ( count )
- {
- silence_count -= count;
- memset( &out [pos], 0, count * sizeof *out );
- }
- else
- {
- // empty internal buffer
- count = min( buf_count, out_count - pos );
- if ( !count && track_ended )
- {
- memset( &out [pos], 0, (out_count - pos) * sizeof *out );
- return true;
- }
-
- memcpy( &out [pos], &buf [buf_size - buf_count], count * sizeof *out );
- buf_count -= count;
- }
- pos += count;
-
- // keep internal buffer full and possibly run ahead
- for ( int n = 6; n--; )
- {
- if ( buf_count || track_ended ||
- emu_time - out_time > silence_max * stereo * emu->sample_rate() )
- break;
- fill_buf( detect_silence );
- }
- }
- out_time += out_count;
-
- if ( detect_silence &&
- ( emu_time - silence_time > silence_max * stereo * emu->sample_rate() && silence_time ) )
- end_track();
-
- // fade if track is ending
- if ( out_time > fade_time )
- {
- for ( int i = 0; i < out_count; i += fade_block_size )
- {
- double gain = pow( fade_factor, (double) (out_time + i - fade_time) );
- if ( gain < 0.005 )
- end_track();
-
- int count = min( fade_block_size, out_count - i );
- int igain = (unsigned int)((double)gain * (1 << 15));;
- for ( int j = 0; j < count; j++ )
- out [i + j] = (out [i + j] * igain) >> 15;
- }
- }
-
- return !silence_count && !buf_count && track_ended;
-}
-
diff --git a/src/console/Vfs_File.cc b/src/console/Vfs_File.cc
new file mode 100644
index 000000000000..648d60481e6c
--- /dev/null
+++ b/src/console/Vfs_File.cc
@@ -0,0 +1,57 @@
+#include <stdio.h>
+
+#include "Vfs_File.h"
+
+#include "libaudcore/vfs.h"
+
+void Vfs_File_Reader::reset(VFSFile &file_)
+{
+ close();
+ file = &file_;
+}
+
+Vfs_File_Reader::error_t Vfs_File_Reader::open( const char* path )
+{
+ close();
+ file = owned_file = new VFSFile (path, "r");
+
+ if (! * file)
+ {
+ close();
+ return "Couldn't open file";
+ }
+
+ return 0;
+}
+
+long Vfs_File_Reader::size() const
+{
+ return file->fsize ();
+}
+
+long Vfs_File_Reader::read_avail (void * buf, long size)
+{
+ return (long) file->fread (buf, 1, size);
+}
+
+long Vfs_File_Reader::tell() const
+{
+ return file->ftell ();
+}
+
+Vfs_File_Reader::error_t Vfs_File_Reader::seek( long n )
+{
+ if (file->fseek (n, VFS_SEEK_SET) < 0)
+ return eof_error;
+ return 0;
+}
+
+void Vfs_File_Reader::close()
+{
+ file = 0;
+ if (owned_file)
+ {
+ delete owned_file;
+ owned_file = 0;
+ }
+}
diff --git a/src/console/Vfs_File.cxx b/src/console/Vfs_File.cxx
deleted file mode 100644
index 618c0a777dff..000000000000
--- a/src/console/Vfs_File.cxx
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <stdio.h>
-
-#include "Vfs_File.h"
-
-extern "C" {
-#include "libaudcore/vfs.h"
-}
-
-struct reader_private {
- VFSFile * file, * owned_file;
-};
-
-Vfs_File_Reader::Vfs_File_Reader ()
-{
- p = new struct reader_private;
- p->file = 0;
- p->owned_file = 0;
-}
-
-Vfs_File_Reader::~Vfs_File_Reader ()
-{
- close ();
- delete p;
-}
-
-void Vfs_File_Reader::reset (/* VFSFile * */ void * file)
-{
- close ();
- p->file = (VFSFile *) file;
-}
-
-Vfs_File_Reader::error_t Vfs_File_Reader::open( const char* path )
-{
- close();
- p->file = p->owned_file = vfs_fopen (path, "r");
- if (! p->file)
- return "Couldn't open file";
- return 0;
-}
-
-long Vfs_File_Reader::size() const
-{
- return vfs_fsize (p->file);
-}
-
-long Vfs_File_Reader::read_avail (void * buf, long size)
-{
- return (long) vfs_fread (buf, 1, size, p->file);
-}
-
-long Vfs_File_Reader::tell() const
-{
- return vfs_ftell (p->file);
-}
-
-Vfs_File_Reader::error_t Vfs_File_Reader::seek( long n )
-{
- if (vfs_fseek (p->file, n, SEEK_SET) < 0)
- return eof_error;
- return 0;
-}
-
-void Vfs_File_Reader::close()
-{
- p->file = 0;
- if (p->owned_file)
- {
- vfs_fclose (p->owned_file);
- p->owned_file = 0;
- }
-}
diff --git a/src/console/Vfs_File.h b/src/console/Vfs_File.h
index 267558314446..36e373b67e3d 100644
--- a/src/console/Vfs_File.h
+++ b/src/console/Vfs_File.h
@@ -5,22 +5,24 @@
#include "Data_Reader.h"
+class VFSFile;
+
class Vfs_File_Reader : public File_Reader {
public:
// use already-open file and doesn't close it in close()
- void reset (/* VFSFile * */ void * file);
+ void reset(VFSFile &file_);
error_t open( const char* path );
void close();
-public:
- Vfs_File_Reader();
- ~Vfs_File_Reader();
+ ~Vfs_File_Reader()
+ { close(); }
+
long size() const;
long read_avail( void*, long );
long tell() const;
error_t seek( long );
private:
- struct reader_private * p;
+ VFSFile *file = nullptr, *owned_file = nullptr;
};
#endif
diff --git a/src/console/Vgm_Emu.cc b/src/console/Vgm_Emu.cc
new file mode 100644
index 000000000000..68028687e554
--- /dev/null
+++ b/src/console/Vgm_Emu.cc
@@ -0,0 +1,416 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Vgm_Emu.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+#include <math.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+double const fm_gain = 3.0; // FM emulators are internally quieter to avoid 16-bit overflow
+double const rolloff = 0.990;
+double const oversample_factor = 1.5;
+
+Vgm_Emu::Vgm_Emu()
+{
+ disable_oversampling_ = false;
+ psg_rate = 0;
+ set_type( gme_vgm_type );
+
+ static int const types [8] = {
+ wave_type | 1, wave_type | 0, wave_type | 2, noise_type | 0
+ };
+ set_voice_types( types );
+
+ set_silence_lookahead( 1 ); // tracks should already be trimmed
+
+ static equalizer_t const eq = { -14.0, 80 };
+ set_equalizer( eq );
+}
+
+Vgm_Emu::~Vgm_Emu() { }
+
+// Track info
+
+static byte const* skip_gd3_str( byte const* in, byte const* end )
+{
+ while ( end - in >= 2 )
+ {
+ in += 2;
+ if ( !(in [-2] | in [-1]) )
+ break;
+ }
+ return in;
+}
+
+static byte const* get_gd3_str( byte const* in, byte const* end, char* field )
+{
+ byte const* mid = skip_gd3_str( in, end );
+ int len = (mid - in) / 2 - 1;
+ if ( len > 0 )
+ {
+ len = min( len, (int) Gme_File::max_field_ );
+ field [len] = 0;
+ for ( int i = 0; i < len; i++ )
+ field [i] = (in [i * 2 + 1] ? '?' : in [i * 2]); // TODO: convert to utf-8
+ }
+ return mid;
+}
+
+static byte const* get_gd3_pair( byte const* in, byte const* end, char* field )
+{
+ return skip_gd3_str( get_gd3_str( in, end, field ), end );
+}
+
+static void parse_gd3( byte const* in, byte const* end, track_info_t* out )
+{
+ in = get_gd3_pair( in, end, out->song );
+ in = get_gd3_pair( in, end, out->game );
+ in = get_gd3_pair( in, end, out->system );
+ in = get_gd3_pair( in, end, out->author );
+ in = get_gd3_str ( in, end, out->copyright );
+ in = get_gd3_pair( in, end, out->dumper );
+ in = get_gd3_str ( in, end, out->comment );
+}
+
+int const gd3_header_size = 12;
+
+static long check_gd3_header( byte const* h, long remain )
+{
+ if ( remain < gd3_header_size ) return 0;
+ if ( memcmp( h, "Gd3 ", 4 ) ) return 0;
+ if ( GET_LE32( h + 4 ) >= 0x200 ) return 0;
+
+ long gd3_size = GET_LE32( h + 8 );
+ if ( gd3_size > remain - gd3_header_size ) return 0;
+
+ return gd3_size;
+}
+
+byte const* Vgm_Emu::gd3_data( int* size ) const
+{
+ if ( size )
+ *size = 0;
+
+ long gd3_offset = GET_LE32( header().gd3_offset ) - 0x2C;
+ if ( gd3_offset < 0 )
+ return 0;
+
+ byte const* gd3 = data + header_size + gd3_offset;
+ long gd3_size = check_gd3_header( gd3, data_end - gd3 );
+ if ( !gd3_size )
+ return 0;
+
+ if ( size )
+ *size = gd3_size + gd3_header_size;
+
+ return gd3;
+}
+
+static void get_vgm_length( Vgm_Emu::header_t const& h, track_info_t* out )
+{
+ long length = GET_LE32( h.track_duration ) * 10 / 441;
+ if ( length > 0 )
+ {
+ long loop = GET_LE32( h.loop_duration );
+ if ( loop > 0 && GET_LE32( h.loop_offset ) )
+ {
+ out->loop_length = loop * 10 / 441;
+ out->intro_length = length - out->loop_length;
+ }
+ else
+ {
+ out->length = length; // 1000 / 44100 (VGM files used 44100 as timebase)
+ out->intro_length = length; // make it clear that track is no longer than length
+ out->loop_length = 0;
+ }
+ }
+}
+
+blargg_err_t Vgm_Emu::track_info_( track_info_t* out, int ) const
+{
+ get_vgm_length( header(), out );
+
+ int size;
+ byte const* gd3 = gd3_data( &size );
+ if ( gd3 )
+ parse_gd3( gd3 + gd3_header_size, gd3 + size, out );
+
+ return 0;
+}
+
+static blargg_err_t check_vgm_header( Vgm_Emu::header_t const& h )
+{
+ if ( memcmp( h.tag, "Vgm ", 4 ) )
+ return gme_wrong_file_type;
+ return 0;
+}
+
+struct Vgm_File : Gme_Info_
+{
+ Vgm_Emu::header_t h;
+ blargg_vector<byte> gd3;
+
+ Vgm_File() { set_type( gme_vgm_type ); }
+
+ blargg_err_t load_( Data_Reader& in )
+ {
+ long file_size = in.remain();
+ if ( file_size <= Vgm_Emu::header_size )
+ return gme_wrong_file_type;
+
+ RETURN_ERR( in.read( &h, Vgm_Emu::header_size ) );
+ RETURN_ERR( check_vgm_header( h ) );
+
+ long gd3_offset = GET_LE32( h.gd3_offset ) - 0x2C;
+ long remain = file_size - Vgm_Emu::header_size - gd3_offset;
+ byte gd3_h [gd3_header_size];
+ if ( gd3_offset > 0 && remain >= gd3_header_size )
+ {
+ RETURN_ERR( in.skip( gd3_offset ) );
+ RETURN_ERR( in.read( gd3_h, sizeof gd3_h ) );
+ long gd3_size = check_gd3_header( gd3_h, remain );
+ if ( gd3_size )
+ {
+ RETURN_ERR( gd3.resize( gd3_size ) );
+ RETURN_ERR( in.read( gd3.begin(), gd3.size() ) );
+ }
+ }
+ return 0;
+ }
+
+ blargg_err_t track_info_( track_info_t* out, int ) const
+ {
+ get_vgm_length( h, out );
+ if ( gd3.size() )
+ parse_gd3( gd3.begin(), gd3.end(), out );
+ return 0;
+ }
+};
+
+static Music_Emu* new_vgm_emu () { return BLARGG_NEW Vgm_Emu ; }
+static Music_Emu* new_vgm_file() { return BLARGG_NEW Vgm_File; }
+
+static gme_type_t_ const gme_vgm_type_ = { "Sega SMS/Genesis", 1, &new_vgm_emu, &new_vgm_file, "VGM", 1 };
+gme_type_t const gme_vgm_type = &gme_vgm_type_;
+
+static gme_type_t_ const gme_vgz_type_ = { "Sega SMS/Genesis", 1, &new_vgm_emu, &new_vgm_file, "VGZ", 1 };
+gme_type_t const gme_vgz_type = &gme_vgz_type_;
+
+
+// Setup
+
+void Vgm_Emu::set_tempo_( double t )
+{
+ if ( psg_rate )
+ {
+ vgm_rate = (long) (44100 * t + 0.5);
+ blip_time_factor = (long) floor( double (1L << blip_time_bits) / vgm_rate * psg_rate + 0.5 );
+ //debug_printf( "blip_time_factor: %ld\n", blip_time_factor );
+ //debug_printf( "vgm_rate: %ld\n", vgm_rate );
+ // TODO: remove? calculates vgm_rate more accurately (above differs at most by one Hz only)
+ //blip_time_factor = (long) floor( double (1L << blip_time_bits) * psg_rate / 44100 / t + 0.5 );
+ //vgm_rate = (long) floor( double (1L << blip_time_bits) * psg_rate / blip_time_factor + 0.5 );
+
+ fm_time_factor = 2 + (long) floor( fm_rate * (1L << fm_time_bits) / vgm_rate + 0.5 );
+ }
+}
+
+blargg_err_t Vgm_Emu::set_sample_rate_( long sample_rate )
+{
+ RETURN_ERR( blip_buf.set_sample_rate( sample_rate, 1000 / 30 ) );
+ return Classic_Emu::set_sample_rate_( sample_rate );
+}
+
+void Vgm_Emu::update_eq( blip_eq_t const& eq )
+{
+ psg.treble_eq( eq );
+ dac_synth.treble_eq( eq );
+}
+
+void Vgm_Emu::set_voice( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r )
+{
+ if ( i < psg.osc_count )
+ psg.osc_output( i, c, l, r );
+}
+
+void Vgm_Emu::mute_voices_( int mask )
+{
+ Classic_Emu::mute_voices_( mask );
+ dac_synth.output( &blip_buf );
+ if ( uses_fm )
+ {
+ psg.output( (mask & 0x80) ? 0 : &blip_buf );
+ if ( ym2612.enabled() )
+ {
+ dac_synth.volume( (mask & 0x40) ? 0.0 : 0.1115 / 256 * fm_gain * gain() );
+ ym2612.mute_voices( mask );
+ }
+
+ if ( ym2413.enabled() )
+ {
+ int m = mask & 0x3F;
+ if ( mask & 0x20 )
+ m |= 0x01E0; // channels 5-8
+ if ( mask & 0x40 )
+ m |= 0x3E00;
+ ym2413.mute_voices( m );
+ }
+ }
+}
+
+blargg_err_t Vgm_Emu::load_mem_( byte const* new_data, long new_size )
+{
+ assert( offsetof (header_t,unused2 [8]) == header_size );
+
+ if ( new_size <= header_size )
+ return gme_wrong_file_type;
+
+ header_t const& h = *(header_t const*) new_data;
+
+ RETURN_ERR( check_vgm_header( h ) );
+
+ check( GET_LE32( h.version ) <= 0x150 );
+
+ // psg rate
+ psg_rate = GET_LE32( h.psg_rate );
+ if ( !psg_rate )
+ psg_rate = 3579545;
+ blip_buf.clock_rate( psg_rate );
+
+ data = new_data;
+ data_end = new_data + new_size;
+
+ // get loop
+ loop_begin = data_end;
+ if ( GET_LE32( h.loop_offset ) )
+ loop_begin = &data [GET_LE32( h.loop_offset ) + offsetof (header_t,loop_offset)];
+
+ set_voice_count( psg.osc_count );
+
+ RETURN_ERR( setup_fm() );
+
+ static const char* const fm_names [] = {
+ "FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
+ };
+ static const char* const psg_names [] = { "Square 1", "Square 2", "Square 3", "Noise" };
+ set_voice_names( uses_fm ? fm_names : psg_names );
+
+ // do after FM in case output buffer is changed
+ return Classic_Emu::setup_buffer( psg_rate );
+}
+
+blargg_err_t Vgm_Emu::setup_fm()
+{
+ long ym2612_rate = GET_LE32( header().ym2612_rate );
+ long ym2413_rate = GET_LE32( header().ym2413_rate );
+ if ( ym2413_rate && GET_LE32( header().version ) < 0x110 )
+ update_fm_rates( &ym2413_rate, &ym2612_rate );
+
+ uses_fm = false;
+
+ fm_rate = blip_buf.sample_rate() * oversample_factor;
+
+ if ( ym2612_rate )
+ {
+ uses_fm = true;
+ if ( disable_oversampling_ )
+ fm_rate = ym2612_rate / 144.0;
+ Dual_Resampler::setup( fm_rate / blip_buf.sample_rate(), rolloff, fm_gain * gain() );
+ RETURN_ERR( ym2612.set_rate( fm_rate, ym2612_rate ) );
+ ym2612.enable( true );
+ set_voice_count( 8 );
+ }
+
+ if ( !uses_fm && ym2413_rate )
+ {
+ uses_fm = true;
+ if ( disable_oversampling_ )
+ fm_rate = ym2413_rate / 72.0;
+ Dual_Resampler::setup( fm_rate / blip_buf.sample_rate(), rolloff, fm_gain * gain() );
+ int result = ym2413.set_rate( fm_rate, ym2413_rate );
+ if ( result == 2 )
+ return "YM2413 FM sound isn't supported";
+ CHECK_ALLOC( !result );
+ ym2413.enable( true );
+ set_voice_count( 8 );
+ }
+
+ if ( uses_fm )
+ {
+ RETURN_ERR( Dual_Resampler::reset( blip_buf.length() * blip_buf.sample_rate() / 1000 ) );
+ psg.volume( 0.135 * fm_gain * gain() );
+ }
+ else
+ {
+ ym2612.enable( false );
+ ym2413.enable( false );
+ psg.volume( gain() );
+ }
+
+ return 0;
+}
+
+// Emulation
+
+blargg_err_t Vgm_Emu::start_track_( int track )
+{
+ RETURN_ERR( Classic_Emu::start_track_( track ) );
+ psg.reset( GET_LE16( header().noise_feedback ), header().noise_width );
+
+ dac_disabled = -1;
+ pos = data + header_size;
+ pcm_data = pos;
+ pcm_pos = pos;
+ dac_amp = -1;
+ vgm_time = 0;
+ if ( GET_LE32( header().version ) >= 0x150 )
+ {
+ long data_offset = GET_LE32( header().data_offset );
+ check( data_offset );
+ if ( data_offset )
+ pos += data_offset + offsetof (header_t,data_offset) - 0x40;
+ }
+
+ if ( uses_fm )
+ {
+ if ( ym2413.enabled() )
+ ym2413.reset();
+
+ if ( ym2612.enabled() )
+ ym2612.reset();
+
+ fm_time_offset = 0;
+ blip_buf.clear();
+ Dual_Resampler::clear();
+ }
+ return 0;
+}
+
+blargg_err_t Vgm_Emu::run_clocks( blip_time_t& time_io, int msec )
+{
+ time_io = run_commands( msec * vgm_rate / 1000 );
+ psg.end_frame( time_io );
+ return 0;
+}
+
+blargg_err_t Vgm_Emu::play_( long count, sample_t* out )
+{
+ if ( !uses_fm )
+ return Classic_Emu::play_( count, out );
+
+ Dual_Resampler::dual_play( count, out, blip_buf );
+ return 0;
+}
diff --git a/src/console/Vgm_Emu.cxx b/src/console/Vgm_Emu.cxx
deleted file mode 100644
index 68028687e554..000000000000
--- a/src/console/Vgm_Emu.cxx
+++ /dev/null
@@ -1,416 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Vgm_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-#include <math.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-double const fm_gain = 3.0; // FM emulators are internally quieter to avoid 16-bit overflow
-double const rolloff = 0.990;
-double const oversample_factor = 1.5;
-
-Vgm_Emu::Vgm_Emu()
-{
- disable_oversampling_ = false;
- psg_rate = 0;
- set_type( gme_vgm_type );
-
- static int const types [8] = {
- wave_type | 1, wave_type | 0, wave_type | 2, noise_type | 0
- };
- set_voice_types( types );
-
- set_silence_lookahead( 1 ); // tracks should already be trimmed
-
- static equalizer_t const eq = { -14.0, 80 };
- set_equalizer( eq );
-}
-
-Vgm_Emu::~Vgm_Emu() { }
-
-// Track info
-
-static byte const* skip_gd3_str( byte const* in, byte const* end )
-{
- while ( end - in >= 2 )
- {
- in += 2;
- if ( !(in [-2] | in [-1]) )
- break;
- }
- return in;
-}
-
-static byte const* get_gd3_str( byte const* in, byte const* end, char* field )
-{
- byte const* mid = skip_gd3_str( in, end );
- int len = (mid - in) / 2 - 1;
- if ( len > 0 )
- {
- len = min( len, (int) Gme_File::max_field_ );
- field [len] = 0;
- for ( int i = 0; i < len; i++ )
- field [i] = (in [i * 2 + 1] ? '?' : in [i * 2]); // TODO: convert to utf-8
- }
- return mid;
-}
-
-static byte const* get_gd3_pair( byte const* in, byte const* end, char* field )
-{
- return skip_gd3_str( get_gd3_str( in, end, field ), end );
-}
-
-static void parse_gd3( byte const* in, byte const* end, track_info_t* out )
-{
- in = get_gd3_pair( in, end, out->song );
- in = get_gd3_pair( in, end, out->game );
- in = get_gd3_pair( in, end, out->system );
- in = get_gd3_pair( in, end, out->author );
- in = get_gd3_str ( in, end, out->copyright );
- in = get_gd3_pair( in, end, out->dumper );
- in = get_gd3_str ( in, end, out->comment );
-}
-
-int const gd3_header_size = 12;
-
-static long check_gd3_header( byte const* h, long remain )
-{
- if ( remain < gd3_header_size ) return 0;
- if ( memcmp( h, "Gd3 ", 4 ) ) return 0;
- if ( GET_LE32( h + 4 ) >= 0x200 ) return 0;
-
- long gd3_size = GET_LE32( h + 8 );
- if ( gd3_size > remain - gd3_header_size ) return 0;
-
- return gd3_size;
-}
-
-byte const* Vgm_Emu::gd3_data( int* size ) const
-{
- if ( size )
- *size = 0;
-
- long gd3_offset = GET_LE32( header().gd3_offset ) - 0x2C;
- if ( gd3_offset < 0 )
- return 0;
-
- byte const* gd3 = data + header_size + gd3_offset;
- long gd3_size = check_gd3_header( gd3, data_end - gd3 );
- if ( !gd3_size )
- return 0;
-
- if ( size )
- *size = gd3_size + gd3_header_size;
-
- return gd3;
-}
-
-static void get_vgm_length( Vgm_Emu::header_t const& h, track_info_t* out )
-{
- long length = GET_LE32( h.track_duration ) * 10 / 441;
- if ( length > 0 )
- {
- long loop = GET_LE32( h.loop_duration );
- if ( loop > 0 && GET_LE32( h.loop_offset ) )
- {
- out->loop_length = loop * 10 / 441;
- out->intro_length = length - out->loop_length;
- }
- else
- {
- out->length = length; // 1000 / 44100 (VGM files used 44100 as timebase)
- out->intro_length = length; // make it clear that track is no longer than length
- out->loop_length = 0;
- }
- }
-}
-
-blargg_err_t Vgm_Emu::track_info_( track_info_t* out, int ) const
-{
- get_vgm_length( header(), out );
-
- int size;
- byte const* gd3 = gd3_data( &size );
- if ( gd3 )
- parse_gd3( gd3 + gd3_header_size, gd3 + size, out );
-
- return 0;
-}
-
-static blargg_err_t check_vgm_header( Vgm_Emu::header_t const& h )
-{
- if ( memcmp( h.tag, "Vgm ", 4 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Vgm_File : Gme_Info_
-{
- Vgm_Emu::header_t h;
- blargg_vector<byte> gd3;
-
- Vgm_File() { set_type( gme_vgm_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- long file_size = in.remain();
- if ( file_size <= Vgm_Emu::header_size )
- return gme_wrong_file_type;
-
- RETURN_ERR( in.read( &h, Vgm_Emu::header_size ) );
- RETURN_ERR( check_vgm_header( h ) );
-
- long gd3_offset = GET_LE32( h.gd3_offset ) - 0x2C;
- long remain = file_size - Vgm_Emu::header_size - gd3_offset;
- byte gd3_h [gd3_header_size];
- if ( gd3_offset > 0 && remain >= gd3_header_size )
- {
- RETURN_ERR( in.skip( gd3_offset ) );
- RETURN_ERR( in.read( gd3_h, sizeof gd3_h ) );
- long gd3_size = check_gd3_header( gd3_h, remain );
- if ( gd3_size )
- {
- RETURN_ERR( gd3.resize( gd3_size ) );
- RETURN_ERR( in.read( gd3.begin(), gd3.size() ) );
- }
- }
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- get_vgm_length( h, out );
- if ( gd3.size() )
- parse_gd3( gd3.begin(), gd3.end(), out );
- return 0;
- }
-};
-
-static Music_Emu* new_vgm_emu () { return BLARGG_NEW Vgm_Emu ; }
-static Music_Emu* new_vgm_file() { return BLARGG_NEW Vgm_File; }
-
-static gme_type_t_ const gme_vgm_type_ = { "Sega SMS/Genesis", 1, &new_vgm_emu, &new_vgm_file, "VGM", 1 };
-gme_type_t const gme_vgm_type = &gme_vgm_type_;
-
-static gme_type_t_ const gme_vgz_type_ = { "Sega SMS/Genesis", 1, &new_vgm_emu, &new_vgm_file, "VGZ", 1 };
-gme_type_t const gme_vgz_type = &gme_vgz_type_;
-
-
-// Setup
-
-void Vgm_Emu::set_tempo_( double t )
-{
- if ( psg_rate )
- {
- vgm_rate = (long) (44100 * t + 0.5);
- blip_time_factor = (long) floor( double (1L << blip_time_bits) / vgm_rate * psg_rate + 0.5 );
- //debug_printf( "blip_time_factor: %ld\n", blip_time_factor );
- //debug_printf( "vgm_rate: %ld\n", vgm_rate );
- // TODO: remove? calculates vgm_rate more accurately (above differs at most by one Hz only)
- //blip_time_factor = (long) floor( double (1L << blip_time_bits) * psg_rate / 44100 / t + 0.5 );
- //vgm_rate = (long) floor( double (1L << blip_time_bits) * psg_rate / blip_time_factor + 0.5 );
-
- fm_time_factor = 2 + (long) floor( fm_rate * (1L << fm_time_bits) / vgm_rate + 0.5 );
- }
-}
-
-blargg_err_t Vgm_Emu::set_sample_rate_( long sample_rate )
-{
- RETURN_ERR( blip_buf.set_sample_rate( sample_rate, 1000 / 30 ) );
- return Classic_Emu::set_sample_rate_( sample_rate );
-}
-
-void Vgm_Emu::update_eq( blip_eq_t const& eq )
-{
- psg.treble_eq( eq );
- dac_synth.treble_eq( eq );
-}
-
-void Vgm_Emu::set_voice( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r )
-{
- if ( i < psg.osc_count )
- psg.osc_output( i, c, l, r );
-}
-
-void Vgm_Emu::mute_voices_( int mask )
-{
- Classic_Emu::mute_voices_( mask );
- dac_synth.output( &blip_buf );
- if ( uses_fm )
- {
- psg.output( (mask & 0x80) ? 0 : &blip_buf );
- if ( ym2612.enabled() )
- {
- dac_synth.volume( (mask & 0x40) ? 0.0 : 0.1115 / 256 * fm_gain * gain() );
- ym2612.mute_voices( mask );
- }
-
- if ( ym2413.enabled() )
- {
- int m = mask & 0x3F;
- if ( mask & 0x20 )
- m |= 0x01E0; // channels 5-8
- if ( mask & 0x40 )
- m |= 0x3E00;
- ym2413.mute_voices( m );
- }
- }
-}
-
-blargg_err_t Vgm_Emu::load_mem_( byte const* new_data, long new_size )
-{
- assert( offsetof (header_t,unused2 [8]) == header_size );
-
- if ( new_size <= header_size )
- return gme_wrong_file_type;
-
- header_t const& h = *(header_t const*) new_data;
-
- RETURN_ERR( check_vgm_header( h ) );
-
- check( GET_LE32( h.version ) <= 0x150 );
-
- // psg rate
- psg_rate = GET_LE32( h.psg_rate );
- if ( !psg_rate )
- psg_rate = 3579545;
- blip_buf.clock_rate( psg_rate );
-
- data = new_data;
- data_end = new_data + new_size;
-
- // get loop
- loop_begin = data_end;
- if ( GET_LE32( h.loop_offset ) )
- loop_begin = &data [GET_LE32( h.loop_offset ) + offsetof (header_t,loop_offset)];
-
- set_voice_count( psg.osc_count );
-
- RETURN_ERR( setup_fm() );
-
- static const char* const fm_names [] = {
- "FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
- };
- static const char* const psg_names [] = { "Square 1", "Square 2", "Square 3", "Noise" };
- set_voice_names( uses_fm ? fm_names : psg_names );
-
- // do after FM in case output buffer is changed
- return Classic_Emu::setup_buffer( psg_rate );
-}
-
-blargg_err_t Vgm_Emu::setup_fm()
-{
- long ym2612_rate = GET_LE32( header().ym2612_rate );
- long ym2413_rate = GET_LE32( header().ym2413_rate );
- if ( ym2413_rate && GET_LE32( header().version ) < 0x110 )
- update_fm_rates( &ym2413_rate, &ym2612_rate );
-
- uses_fm = false;
-
- fm_rate = blip_buf.sample_rate() * oversample_factor;
-
- if ( ym2612_rate )
- {
- uses_fm = true;
- if ( disable_oversampling_ )
- fm_rate = ym2612_rate / 144.0;
- Dual_Resampler::setup( fm_rate / blip_buf.sample_rate(), rolloff, fm_gain * gain() );
- RETURN_ERR( ym2612.set_rate( fm_rate, ym2612_rate ) );
- ym2612.enable( true );
- set_voice_count( 8 );
- }
-
- if ( !uses_fm && ym2413_rate )
- {
- uses_fm = true;
- if ( disable_oversampling_ )
- fm_rate = ym2413_rate / 72.0;
- Dual_Resampler::setup( fm_rate / blip_buf.sample_rate(), rolloff, fm_gain * gain() );
- int result = ym2413.set_rate( fm_rate, ym2413_rate );
- if ( result == 2 )
- return "YM2413 FM sound isn't supported";
- CHECK_ALLOC( !result );
- ym2413.enable( true );
- set_voice_count( 8 );
- }
-
- if ( uses_fm )
- {
- RETURN_ERR( Dual_Resampler::reset( blip_buf.length() * blip_buf.sample_rate() / 1000 ) );
- psg.volume( 0.135 * fm_gain * gain() );
- }
- else
- {
- ym2612.enable( false );
- ym2413.enable( false );
- psg.volume( gain() );
- }
-
- return 0;
-}
-
-// Emulation
-
-blargg_err_t Vgm_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
- psg.reset( GET_LE16( header().noise_feedback ), header().noise_width );
-
- dac_disabled = -1;
- pos = data + header_size;
- pcm_data = pos;
- pcm_pos = pos;
- dac_amp = -1;
- vgm_time = 0;
- if ( GET_LE32( header().version ) >= 0x150 )
- {
- long data_offset = GET_LE32( header().data_offset );
- check( data_offset );
- if ( data_offset )
- pos += data_offset + offsetof (header_t,data_offset) - 0x40;
- }
-
- if ( uses_fm )
- {
- if ( ym2413.enabled() )
- ym2413.reset();
-
- if ( ym2612.enabled() )
- ym2612.reset();
-
- fm_time_offset = 0;
- blip_buf.clear();
- Dual_Resampler::clear();
- }
- return 0;
-}
-
-blargg_err_t Vgm_Emu::run_clocks( blip_time_t& time_io, int msec )
-{
- time_io = run_commands( msec * vgm_rate / 1000 );
- psg.end_frame( time_io );
- return 0;
-}
-
-blargg_err_t Vgm_Emu::play_( long count, sample_t* out )
-{
- if ( !uses_fm )
- return Classic_Emu::play_( count, out );
-
- Dual_Resampler::dual_play( count, out, blip_buf );
- return 0;
-}
diff --git a/src/console/Vgm_Emu_Impl.cc b/src/console/Vgm_Emu_Impl.cc
new file mode 100644
index 000000000000..24bdf29d4cc5
--- /dev/null
+++ b/src/console/Vgm_Emu_Impl.cc
@@ -0,0 +1,314 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Vgm_Emu.h"
+
+#include <math.h>
+#include <string.h>
+#include "blargg_endian.h"
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+enum {
+ cmd_gg_stereo = 0x4F,
+ cmd_psg = 0x50,
+ cmd_ym2413 = 0x51,
+ cmd_ym2612_port0 = 0x52,
+ cmd_ym2612_port1 = 0x53,
+ cmd_ym2151 = 0x54,
+ cmd_delay = 0x61,
+ cmd_delay_735 = 0x62,
+ cmd_delay_882 = 0x63,
+ cmd_byte_delay = 0x64,
+ cmd_end = 0x66,
+ cmd_data_block = 0x67,
+ cmd_short_delay = 0x70,
+ cmd_pcm_delay = 0x80,
+ cmd_pcm_seek = 0xE0,
+
+ pcm_block_type = 0x00,
+ ym2612_dac_port = 0x2A
+};
+
+inline int command_len( int command )
+{
+ switch ( command >> 4 )
+ {
+ case 0x03:
+ case 0x04:
+ return 2;
+
+ case 0x05:
+ case 0x0A:
+ case 0x0B:
+ return 3;
+
+ case 0x0C:
+ case 0x0D:
+ return 4;
+
+ case 0x0E:
+ case 0x0F:
+ return 5;
+ }
+
+ check( false );
+ return 1;
+}
+
+template<class Emu>
+inline void Ym_Emu<Emu>::begin_frame( short* p )
+{
+ require( enabled() );
+ out = p;
+ last_time = 0;
+}
+
+template<class Emu>
+inline int Ym_Emu<Emu>::run_until( int time )
+{
+ int count = time - last_time;
+ if ( count > 0 )
+ {
+ if ( last_time < 0 )
+ return false;
+ last_time = time;
+ short* p = out;
+ out += count * Emu::out_chan_count;
+ Emu::run( count, p );
+ }
+ return true;
+}
+
+inline Vgm_Emu_Impl::fm_time_t Vgm_Emu_Impl::to_fm_time( vgm_time_t t ) const
+{
+ return (t * fm_time_factor + fm_time_offset) >> fm_time_bits;
+}
+
+inline blip_time_t Vgm_Emu_Impl::to_blip_time( vgm_time_t t ) const
+{
+ return (t * blip_time_factor) >> blip_time_bits;
+}
+
+void Vgm_Emu_Impl::write_pcm( vgm_time_t vgm_time, int amp )
+{
+ blip_time_t blip_time = to_blip_time( vgm_time );
+ int old = dac_amp;
+ int delta = amp - old;
+ dac_amp = amp;
+ if ( old >= 0 )
+ dac_synth.offset_inline( blip_time, delta, &blip_buf );
+ else
+ dac_amp |= dac_disabled;
+}
+
+blip_time_t Vgm_Emu_Impl::run_commands( vgm_time_t end_time )
+{
+ vgm_time_t vgm_time = this->vgm_time;
+ byte const* pos = this->pos;
+ if ( pos >= data_end )
+ {
+ set_track_ended();
+ if ( pos > data_end )
+ set_warning( "Stream lacked end event" );
+ }
+
+ while ( vgm_time < end_time && pos < data_end )
+ {
+ // TODO: be sure there are enough bytes left in stream for particular command
+ // so we don't read past end
+ switch ( *pos++ )
+ {
+ case cmd_end:
+ pos = loop_begin; // if not looped, loop_begin == data_end
+ break;
+
+ case cmd_delay_735:
+ vgm_time += 735;
+ break;
+
+ case cmd_delay_882:
+ vgm_time += 882;
+ break;
+
+ case cmd_gg_stereo:
+ psg.write_ggstereo( to_blip_time( vgm_time ), *pos++ );
+ break;
+
+ case cmd_psg:
+ psg.write_data( to_blip_time( vgm_time ), *pos++ );
+ break;
+
+ case cmd_delay:
+ vgm_time += pos [1] * 0x100L + pos [0];
+ pos += 2;
+ break;
+
+ case cmd_byte_delay:
+ vgm_time += *pos++;
+ break;
+
+ case cmd_ym2413:
+ if ( ym2413.run_until( to_fm_time( vgm_time ) ) )
+ ym2413.write( pos [0], pos [1] );
+ pos += 2;
+ break;
+
+ case cmd_ym2612_port0:
+ if ( pos [0] == ym2612_dac_port )
+ {
+ write_pcm( vgm_time, pos [1] );
+ }
+ else if ( ym2612.run_until( to_fm_time( vgm_time ) ) )
+ {
+ if ( pos [0] == 0x2B )
+ {
+ dac_disabled = (pos [1] >> 7 & 1) - 1;
+ dac_amp |= dac_disabled;
+ }
+ ym2612.write0( pos [0], pos [1] );
+ }
+ pos += 2;
+ break;
+
+ case cmd_ym2612_port1:
+ if ( ym2612.run_until( to_fm_time( vgm_time ) ) )
+ ym2612.write1( pos [0], pos [1] );
+ pos += 2;
+ break;
+
+ case cmd_data_block: {
+ check( *pos == cmd_end );
+ int type = pos [1];
+ long size = GET_LE32( pos + 2 );
+ pos += 6;
+ if ( type == pcm_block_type )
+ pcm_data = pos;
+ pos += size;
+ break;
+ }
+
+ case cmd_pcm_seek:
+ pcm_pos = pcm_data + pos [3] * 0x1000000L + pos [2] * 0x10000L +
+ pos [1] * 0x100L + pos [0];
+ pos += 4;
+ break;
+
+ default:
+ int cmd = pos [-1];
+ switch ( cmd & 0xF0 )
+ {
+ case cmd_pcm_delay:
+ write_pcm( vgm_time, *pcm_pos++ );
+ vgm_time += cmd & 0x0F;
+ break;
+
+ case cmd_short_delay:
+ vgm_time += (cmd & 0x0F) + 1;
+ break;
+
+ case 0x50:
+ pos += 2;
+ break;
+
+ default:
+ pos += command_len( cmd ) - 1;
+ set_warning( "Unknown stream event" );
+ }
+ }
+ }
+ vgm_time -= end_time;
+ this->pos = pos;
+ this->vgm_time = vgm_time;
+
+ return to_blip_time( end_time );
+}
+
+int Vgm_Emu_Impl::play_frame( blip_time_t blip_time, int sample_count, sample_t* buf )
+{
+ // to do: timing is working mostly by luck
+
+ int min_pairs = sample_count >> 1;
+ int vgm_time = ((long) min_pairs << fm_time_bits) / fm_time_factor - 1;
+ assert( to_fm_time( vgm_time ) <= min_pairs );
+ int pairs = min_pairs;
+ while ( (pairs = to_fm_time( vgm_time )) < min_pairs )
+ vgm_time++;
+ //debug_printf( "pairs: %d, min_pairs: %d\n", pairs, min_pairs );
+
+ if ( ym2612.enabled() )
+ {
+ ym2612.begin_frame( buf );
+ memset( buf, 0, pairs * stereo * sizeof *buf );
+ }
+ else if ( ym2413.enabled() )
+ {
+ ym2413.begin_frame( buf );
+ }
+
+ run_commands( vgm_time );
+ ym2612.run_until( pairs );
+ ym2413.run_until( pairs );
+
+ fm_time_offset = (vgm_time * fm_time_factor + fm_time_offset) -
+ ((long) pairs << fm_time_bits);
+
+ psg.end_frame( blip_time );
+
+ return pairs * stereo;
+}
+
+// Update pre-1.10 header FM rates by scanning commands
+void Vgm_Emu_Impl::update_fm_rates( long* ym2413_rate, long* ym2612_rate ) const
+{
+ byte const* p = data + 0x40;
+ while ( p < data_end )
+ {
+ switch ( *p )
+ {
+ case cmd_end:
+ return;
+
+ case cmd_psg:
+ case cmd_byte_delay:
+ p += 2;
+ break;
+
+ case cmd_delay:
+ p += 3;
+ break;
+
+ case cmd_data_block:
+ p += 7 + GET_LE32( p + 3 );
+ break;
+
+ case cmd_ym2413:
+ *ym2612_rate = 0;
+ return;
+
+ case cmd_ym2612_port0:
+ case cmd_ym2612_port1:
+ *ym2612_rate = *ym2413_rate;
+ *ym2413_rate = 0;
+ return;
+
+ case cmd_ym2151:
+ *ym2413_rate = 0;
+ *ym2612_rate = 0;
+ return;
+
+ default:
+ p += command_len( *p );
+ }
+ }
+}
diff --git a/src/console/Vgm_Emu_Impl.cxx b/src/console/Vgm_Emu_Impl.cxx
deleted file mode 100644
index 24bdf29d4cc5..000000000000
--- a/src/console/Vgm_Emu_Impl.cxx
+++ /dev/null
@@ -1,314 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Vgm_Emu.h"
-
-#include <math.h>
-#include <string.h>
-#include "blargg_endian.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-enum {
- cmd_gg_stereo = 0x4F,
- cmd_psg = 0x50,
- cmd_ym2413 = 0x51,
- cmd_ym2612_port0 = 0x52,
- cmd_ym2612_port1 = 0x53,
- cmd_ym2151 = 0x54,
- cmd_delay = 0x61,
- cmd_delay_735 = 0x62,
- cmd_delay_882 = 0x63,
- cmd_byte_delay = 0x64,
- cmd_end = 0x66,
- cmd_data_block = 0x67,
- cmd_short_delay = 0x70,
- cmd_pcm_delay = 0x80,
- cmd_pcm_seek = 0xE0,
-
- pcm_block_type = 0x00,
- ym2612_dac_port = 0x2A
-};
-
-inline int command_len( int command )
-{
- switch ( command >> 4 )
- {
- case 0x03:
- case 0x04:
- return 2;
-
- case 0x05:
- case 0x0A:
- case 0x0B:
- return 3;
-
- case 0x0C:
- case 0x0D:
- return 4;
-
- case 0x0E:
- case 0x0F:
- return 5;
- }
-
- check( false );
- return 1;
-}
-
-template<class Emu>
-inline void Ym_Emu<Emu>::begin_frame( short* p )
-{
- require( enabled() );
- out = p;
- last_time = 0;
-}
-
-template<class Emu>
-inline int Ym_Emu<Emu>::run_until( int time )
-{
- int count = time - last_time;
- if ( count > 0 )
- {
- if ( last_time < 0 )
- return false;
- last_time = time;
- short* p = out;
- out += count * Emu::out_chan_count;
- Emu::run( count, p );
- }
- return true;
-}
-
-inline Vgm_Emu_Impl::fm_time_t Vgm_Emu_Impl::to_fm_time( vgm_time_t t ) const
-{
- return (t * fm_time_factor + fm_time_offset) >> fm_time_bits;
-}
-
-inline blip_time_t Vgm_Emu_Impl::to_blip_time( vgm_time_t t ) const
-{
- return (t * blip_time_factor) >> blip_time_bits;
-}
-
-void Vgm_Emu_Impl::write_pcm( vgm_time_t vgm_time, int amp )
-{
- blip_time_t blip_time = to_blip_time( vgm_time );
- int old = dac_amp;
- int delta = amp - old;
- dac_amp = amp;
- if ( old >= 0 )
- dac_synth.offset_inline( blip_time, delta, &blip_buf );
- else
- dac_amp |= dac_disabled;
-}
-
-blip_time_t Vgm_Emu_Impl::run_commands( vgm_time_t end_time )
-{
- vgm_time_t vgm_time = this->vgm_time;
- byte const* pos = this->pos;
- if ( pos >= data_end )
- {
- set_track_ended();
- if ( pos > data_end )
- set_warning( "Stream lacked end event" );
- }
-
- while ( vgm_time < end_time && pos < data_end )
- {
- // TODO: be sure there are enough bytes left in stream for particular command
- // so we don't read past end
- switch ( *pos++ )
- {
- case cmd_end:
- pos = loop_begin; // if not looped, loop_begin == data_end
- break;
-
- case cmd_delay_735:
- vgm_time += 735;
- break;
-
- case cmd_delay_882:
- vgm_time += 882;
- break;
-
- case cmd_gg_stereo:
- psg.write_ggstereo( to_blip_time( vgm_time ), *pos++ );
- break;
-
- case cmd_psg:
- psg.write_data( to_blip_time( vgm_time ), *pos++ );
- break;
-
- case cmd_delay:
- vgm_time += pos [1] * 0x100L + pos [0];
- pos += 2;
- break;
-
- case cmd_byte_delay:
- vgm_time += *pos++;
- break;
-
- case cmd_ym2413:
- if ( ym2413.run_until( to_fm_time( vgm_time ) ) )
- ym2413.write( pos [0], pos [1] );
- pos += 2;
- break;
-
- case cmd_ym2612_port0:
- if ( pos [0] == ym2612_dac_port )
- {
- write_pcm( vgm_time, pos [1] );
- }
- else if ( ym2612.run_until( to_fm_time( vgm_time ) ) )
- {
- if ( pos [0] == 0x2B )
- {
- dac_disabled = (pos [1] >> 7 & 1) - 1;
- dac_amp |= dac_disabled;
- }
- ym2612.write0( pos [0], pos [1] );
- }
- pos += 2;
- break;
-
- case cmd_ym2612_port1:
- if ( ym2612.run_until( to_fm_time( vgm_time ) ) )
- ym2612.write1( pos [0], pos [1] );
- pos += 2;
- break;
-
- case cmd_data_block: {
- check( *pos == cmd_end );
- int type = pos [1];
- long size = GET_LE32( pos + 2 );
- pos += 6;
- if ( type == pcm_block_type )
- pcm_data = pos;
- pos += size;
- break;
- }
-
- case cmd_pcm_seek:
- pcm_pos = pcm_data + pos [3] * 0x1000000L + pos [2] * 0x10000L +
- pos [1] * 0x100L + pos [0];
- pos += 4;
- break;
-
- default:
- int cmd = pos [-1];
- switch ( cmd & 0xF0 )
- {
- case cmd_pcm_delay:
- write_pcm( vgm_time, *pcm_pos++ );
- vgm_time += cmd & 0x0F;
- break;
-
- case cmd_short_delay:
- vgm_time += (cmd & 0x0F) + 1;
- break;
-
- case 0x50:
- pos += 2;
- break;
-
- default:
- pos += command_len( cmd ) - 1;
- set_warning( "Unknown stream event" );
- }
- }
- }
- vgm_time -= end_time;
- this->pos = pos;
- this->vgm_time = vgm_time;
-
- return to_blip_time( end_time );
-}
-
-int Vgm_Emu_Impl::play_frame( blip_time_t blip_time, int sample_count, sample_t* buf )
-{
- // to do: timing is working mostly by luck
-
- int min_pairs = sample_count >> 1;
- int vgm_time = ((long) min_pairs << fm_time_bits) / fm_time_factor - 1;
- assert( to_fm_time( vgm_time ) <= min_pairs );
- int pairs = min_pairs;
- while ( (pairs = to_fm_time( vgm_time )) < min_pairs )
- vgm_time++;
- //debug_printf( "pairs: %d, min_pairs: %d\n", pairs, min_pairs );
-
- if ( ym2612.enabled() )
- {
- ym2612.begin_frame( buf );
- memset( buf, 0, pairs * stereo * sizeof *buf );
- }
- else if ( ym2413.enabled() )
- {
- ym2413.begin_frame( buf );
- }
-
- run_commands( vgm_time );
- ym2612.run_until( pairs );
- ym2413.run_until( pairs );
-
- fm_time_offset = (vgm_time * fm_time_factor + fm_time_offset) -
- ((long) pairs << fm_time_bits);
-
- psg.end_frame( blip_time );
-
- return pairs * stereo;
-}
-
-// Update pre-1.10 header FM rates by scanning commands
-void Vgm_Emu_Impl::update_fm_rates( long* ym2413_rate, long* ym2612_rate ) const
-{
- byte const* p = data + 0x40;
- while ( p < data_end )
- {
- switch ( *p )
- {
- case cmd_end:
- return;
-
- case cmd_psg:
- case cmd_byte_delay:
- p += 2;
- break;
-
- case cmd_delay:
- p += 3;
- break;
-
- case cmd_data_block:
- p += 7 + GET_LE32( p + 3 );
- break;
-
- case cmd_ym2413:
- *ym2612_rate = 0;
- return;
-
- case cmd_ym2612_port0:
- case cmd_ym2612_port1:
- *ym2612_rate = *ym2413_rate;
- *ym2413_rate = 0;
- return;
-
- case cmd_ym2151:
- *ym2413_rate = 0;
- *ym2612_rate = 0;
- return;
-
- default:
- p += command_len( *p );
- }
- }
-}
diff --git a/src/console/Vgm_Emu_Impl.h b/src/console/Vgm_Emu_Impl.h
index 3225ea799fca..871b9e10c290 100644
--- a/src/console/Vgm_Emu_Impl.h
+++ b/src/console/Vgm_Emu_Impl.h
@@ -17,7 +17,7 @@ protected:
short* out;
enum { disabled_time = -1 };
public:
- Ym_Emu() : last_time( disabled_time ), out( NULL ) { }
+ Ym_Emu() : last_time( disabled_time ), out( nullptr ) { }
void enable( bool b ) { last_time = b ? 0 : disabled_time; }
bool enabled() const { return last_time != disabled_time; }
void begin_frame( short* p );
diff --git a/src/console/Ym2413_Emu.cc b/src/console/Ym2413_Emu.cc
new file mode 100644
index 000000000000..6e3fafe25d97
--- /dev/null
+++ b/src/console/Ym2413_Emu.cc
@@ -0,0 +1,2216 @@
+
+// Game_Music_Emu 0.3.0. http://www.slack.net/~ant/
+
+/***********************************************************************************
+
+ emu2413.c -- YM2413 emulator written by Mitsutaka Okazaki 2001
+
+ 2001 01-08 : Version 0.10 -- 1st version.
+ 2001 01-15 : Version 0.20 -- semi-public version.
+ 2001 01-16 : Version 0.30 -- 1st public version.
+ 2001 01-17 : Version 0.31 -- Fixed bassdrum problem.
+ : Version 0.32 -- LPF implemented.
+ 2001 01-18 : Version 0.33 -- Fixed the drum problem, refine the mix-down method.
+ -- Fixed the LFO bug.
+ 2001 01-24 : Version 0.35 -- Fixed the drum problem,
+ support undocumented EG behavior.
+ 2001 02-02 : Version 0.38 -- Improved the performance.
+ Fixed the hi-hat and cymbal model.
+ Fixed the default percussive datas.
+ Noise reduction.
+ Fixed the feedback problem.
+ 2001 03-03 : Version 0.39 -- Fixed some drum bugs.
+ Improved the performance.
+ 2001 03-04 : Version 0.40 -- Improved the feedback.
+ Change the default table size.
+ Clock and Rate can be changed during play.
+ 2001 06-24 : Version 0.50 -- Improved the hi-hat and the cymbal tone.
+ Added VRC7 patch (OPLL_reset_patch is changed).
+ Fixed OPLL_reset() bug.
+ Added OPLL_setMask, OPLL_getMask and OPLL_toggleMask.
+ Added OPLL_writeIO.
+ 2001 09-28 : Version 0.51 -- Removed the noise table.
+ 2002 01-28 : Version 0.52 -- Added Stereo mode.
+ 2002 02-07 : Version 0.53 -- Fixed some drum bugs.
+ 2002 02-20 : Version 0.54 -- Added the best quality mode.
+ 2002 03-02 : Version 0.55 -- Removed OPLL_init & OPLL_close.
+ 2002 05-30 : Version 0.60 -- Fixed HH&CYM generator and all voice datas.
+ 2004 04-10 : Version 0.61 -- Added YMF281B tone (defined by Chabin).
+
+ References:
+ fmopl.c -- 1999,2000 written by Tatsuyuki Satoh (MAME development).
+ fmopl.c(fixed) -- (C) 2002 Jarek Burczynski.
+ s_opl.c -- 2001 written by Mamiya (NEZplug development).
+ fmgen.cpp -- 1999,2000 written by cisc.
+ fmpac.ill -- 2000 created by NARUTO.
+ MSX-Datapack
+ YMU757 data sheet
+ YM2143 data sheet
+
+**************************************************************************************/
+
+
+#ifndef _EMU2413_H_
+#define _EMU2413_H_
+
+typedef signed char e_int8;
+typedef unsigned char e_uint8;
+typedef signed short e_int16;
+typedef unsigned short e_uint16;
+typedef signed long e_int32;
+typedef unsigned long e_uint32;
+
+#ifdef EMU2413_DLL_EXPORTS
+ #define EMU2413_API __declspec(dllexport)
+#elif defined(EMU2413_DLL_IMPORTS)
+ #define EMU2413_API __declspec(dllimport)
+#else
+ #define EMU2413_API
+#endif
+
+#define PI 3.14159265358979323846
+
+enum OPLL_TONE_ENUM {OPLL_2413_TONE=0, OPLL_VRC7_TONE=1, OPLL_281B_TONE=2} ;
+
+/* voice data */
+typedef struct __OPLL_PATCH {
+ e_uint32 TL,FB,EG,ML,AR,DR,SL,RR,KR,KL,AM,PM,WF ;
+} OPLL_PATCH ;
+
+/* slot */
+typedef struct __OPLL_SLOT {
+
+ OPLL_PATCH *patch;
+
+ e_int32 type ; /* 0 : modulator 1 : carrier */
+
+ /* OUTPUT */
+ e_int32 feedback ;
+ e_int32 output[2] ; /* Output value of slot */
+
+ /* for Phase Generator (PG) */
+ e_uint16 *sintbl ; /* Wavetable */
+ e_uint32 phase ; /* Phase */
+ e_uint32 dphase ; /* Phase increment amount */
+ e_uint32 pgout ; /* output */
+
+ /* for Envelope Generator (EG) */
+ e_int32 fnum ; /* F-Number */
+ e_int32 block ; /* Block */
+ e_int32 volume ; /* Current volume */
+ e_int32 sustine ; /* Sustine 1 = ON, 0 = OFF */
+ e_uint32 tll ; /* Total Level + Key scale level*/
+ e_uint32 rks ; /* Key scale offset (Rks) */
+ e_int32 eg_mode ; /* Current state */
+ e_uint32 eg_phase ; /* Phase */
+ e_uint32 eg_dphase ; /* Phase increment amount */
+ e_uint32 egout ; /* output */
+
+} OPLL_SLOT ;
+
+/* Mask */
+#define OPLL_MASK_CH(x) (1<<(x))
+#define OPLL_MASK_HH (1<<(9))
+#define OPLL_MASK_CYM (1<<(10))
+#define OPLL_MASK_TOM (1<<(11))
+#define OPLL_MASK_SD (1<<(12))
+#define OPLL_MASK_BD (1<<(13))
+#define OPLL_MASK_RHYTHM ( OPLL_MASK_HH | OPLL_MASK_CYM | OPLL_MASK_TOM | OPLL_MASK_SD | OPLL_MASK_BD )
+
+/* opll */
+typedef struct OPLL {
+
+ e_uint32 adr ;
+ e_int32 out ;
+
+#ifndef EMU2413_COMPACTION
+ e_uint32 realstep ;
+ e_uint32 oplltime ;
+ e_uint32 opllstep ;
+ e_int32 prev, next ;
+ e_int32 sprev[2],snext[2];
+ e_int32 pan[16];
+#endif
+
+ /* Register */
+ e_uint8 reg[0x40] ;
+ e_int32 slot_on_flag[18] ;
+
+ /* Pitch Modulator */
+ e_uint32 pm_phase ;
+ e_int32 lfo_pm ;
+
+ /* Amp Modulator */
+ e_int32 am_phase ;
+ e_int32 lfo_am ;
+
+ e_uint32 quality;
+
+ /* Noise Generator */
+ e_uint32 noise_seed ;
+
+ /* Channel Data */
+ e_int32 patch_number[9];
+ e_int32 key_status[9] ;
+
+ /* Slot */
+ OPLL_SLOT slot[18] ;
+
+ /* Voice Data */
+ OPLL_PATCH patch[19*2] ;
+ e_int32 patch_update[2] ; /* flag for check patch update */
+
+ e_uint32 mask ;
+
+} OPLL ;
+
+/* Create Object */
+EMU2413_API OPLL *OPLL_new(e_uint32 clk, e_uint32 rate) ;
+EMU2413_API void OPLL_delete(OPLL *) ;
+
+/* Setup */
+EMU2413_API void OPLL_reset(OPLL *) ;
+EMU2413_API void OPLL_reset_patch(OPLL *, e_int32) ;
+EMU2413_API void OPLL_set_rate(OPLL *opll, e_uint32 r) ;
+EMU2413_API void OPLL_set_quality(OPLL *opll, e_uint32 q) ;
+EMU2413_API void OPLL_set_pan(OPLL *, e_uint32 ch, e_uint32 pan);
+
+/* Port/Register access */
+EMU2413_API void OPLL_writeIO(OPLL *, e_uint32 reg, e_uint32 val) ;
+EMU2413_API void OPLL_writeReg(OPLL *, e_uint32 reg, e_uint32 val) ;
+
+/* Synthsize */
+EMU2413_API e_int16 OPLL_calc(OPLL *) ;
+EMU2413_API void OPLL_calc_stereo(OPLL *, e_int32 out[2]) ;
+
+/* Misc */
+EMU2413_API void OPLL_setPatch(OPLL *, const e_uint8 *dump) ;
+EMU2413_API void OPLL_copyPatch(OPLL *, e_int32, OPLL_PATCH *) ;
+EMU2413_API void OPLL_forceRefresh(OPLL *) ;
+/* Utility */
+EMU2413_API void OPLL_dump2patch(const e_uint8 *dump, OPLL_PATCH *patch) ;
+EMU2413_API void OPLL_patch2dump(const OPLL_PATCH *patch, e_uint8 *dump) ;
+EMU2413_API void OPLL_getDefaultPatch(e_int32 type, e_int32 num, OPLL_PATCH *) ;
+
+/* Channel Mask */
+EMU2413_API e_uint32 OPLL_setMask(OPLL *, e_uint32 mask) ;
+EMU2413_API e_uint32 OPLL_toggleMask(OPLL *, e_uint32 mask) ;
+
+#define dump2patch OPLL_dump2patch
+
+#endif
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#define EMU2413_COMPACTION
+#define INLINE inline
+
+#ifdef EMU2413_COMPACTION
+#define OPLL_TONE_NUM 1
+static unsigned char default_inst[OPLL_TONE_NUM][(16 + 3) * 16] = {
+ {
+/* YM2413 tone by okazaki at angel.ne.jp */
+0x49,0x4c,0x4c,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x61,0x61,0x1e,0x17,0xf0,0x7f,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x13,0x41,0x16,0x0e,0xfd,0xf4,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x03,0x01,0x9a,0x04,0xf3,0xf3,0x13,0xf3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x11,0x61,0x0e,0x07,0xfa,0x64,0x70,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x22,0x21,0x1e,0x06,0xf0,0x76,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x21,0x22,0x16,0x05,0xf0,0x71,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x21,0x61,0x1d,0x07,0x82,0x80,0x17,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x23,0x21,0x2d,0x16,0x90,0x90,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x21,0x21,0x1b,0x06,0x64,0x65,0x10,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x21,0x21,0x0b,0x1a,0x85,0xa0,0x70,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x23,0x01,0x83,0x10,0xff,0xb4,0x10,0xf4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x97,0xc1,0x20,0x07,0xff,0xf4,0x22,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x61,0x00,0x0c,0x05,0xc2,0xf6,0x40,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x01,0x01,0x56,0x03,0x94,0xc2,0x03,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x21,0x01,0x89,0x03,0xf1,0xe4,0xf0,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ }
+};
+#else
+#define OPLL_TONE_NUM 3
+static unsigned char default_inst[OPLL_TONE_NUM][(16 + 3) * 16] = {
+ {
+#include "2413tone.h"
+ },
+ {
+#include "vrc7tone.h"
+ },
+ {
+#include "281btone.h"
+ }
+};
+#endif
+
+/* Size of Sintable ( 8 -- 18 can be used. 9 recommended.) */
+#define PG_BITS 9
+#define PG_WIDTH (1<<PG_BITS)
+
+/* Phase increment counter */
+#define DP_BITS 18
+#define DP_WIDTH (1<<DP_BITS)
+#define DP_BASE_BITS (DP_BITS - PG_BITS)
+
+/* Dynamic range (Accuracy of sin table) */
+#define DB_BITS 8
+#define DB_STEP (48.0/(1<<DB_BITS))
+#define DB_MUTE (1<<DB_BITS)
+
+/* Dynamic range of envelope */
+#define EG_STEP 0.375
+#define EG_BITS 7
+#define EG_MUTE (1<<EG_BITS)
+
+/* Dynamic range of total level */
+#define TL_STEP 0.75
+#define TL_BITS 6
+#define TL_MUTE (1<<TL_BITS)
+
+/* Dynamic range of sustine level */
+#define SL_STEP 3.0
+#define SL_BITS 4
+#define SL_MUTE (1<<SL_BITS)
+
+#define EG2DB(d) ((d)*(e_int32)(EG_STEP/DB_STEP))
+#define TL2EG(d) ((d)*(e_int32)(TL_STEP/EG_STEP))
+#define SL2EG(d) ((d)*(e_int32)(SL_STEP/EG_STEP))
+
+#define DB_POS(x) (e_uint32)((x)/DB_STEP)
+#define DB_NEG(x) (e_uint32)(DB_MUTE+DB_MUTE+(x)/DB_STEP)
+
+/* Bits for liner value */
+#define DB2LIN_AMP_BITS 8
+#define SLOT_AMP_BITS (DB2LIN_AMP_BITS)
+
+/* Bits for envelope phase incremental counter */
+#define EG_DP_BITS 22
+#define EG_DP_WIDTH (1<<EG_DP_BITS)
+
+/* Bits for Pitch and Amp modulator */
+#define PM_PG_BITS 8
+#define PM_PG_WIDTH (1<<PM_PG_BITS)
+#define PM_DP_BITS 16
+#define PM_DP_WIDTH (1<<PM_DP_BITS)
+#define AM_PG_BITS 8
+#define AM_PG_WIDTH (1<<AM_PG_BITS)
+#define AM_DP_BITS 16
+#define AM_DP_WIDTH (1<<AM_DP_BITS)
+
+/* PM table is calcurated by PM_AMP * pow(2,PM_DEPTH*sin(x)/1200) */
+#define PM_AMP_BITS 8
+#define PM_AMP (1<<PM_AMP_BITS)
+
+/* PM speed(Hz) and depth(cent) */
+#define PM_SPEED 6.4
+#define PM_DEPTH 13.75
+
+/* AM speed(Hz) and depth(dB) */
+#define AM_SPEED 3.6413
+#define AM_DEPTH 4.875
+
+/* Cut the lower b bit(s) off. */
+#define HIGHBITS(c,b) ((c)>>(b))
+
+/* Leave the lower b bit(s). */
+#define LOWBITS(c,b) ((c)&((1<<(b))-1))
+
+/* Expand x which is s bits to d bits. */
+#define EXPAND_BITS(x,s,d) ((x)<<((d)-(s)))
+
+/* Expand x which is s bits to d bits and fill expanded bits '1' */
+#define EXPAND_BITS_X(x,s,d) (((x)<<((d)-(s)))|((1<<((d)-(s)))-1))
+
+/* Adjust envelope speed which depends on sampling rate. */
+#define RATE_ADJUST(x) (rate==49716?x:(e_uint32)((double)(x)*clk/72/rate + 0.5)) /* added 0.5 to round the value*/
+
+#define MOD(o,x) (&(o)->slot[(x)<<1])
+#define CAR(o,x) (&(o)->slot[((x)<<1)|1])
+
+#define BIT(s,b) (((s)>>(b))&1)
+
+/* Input clock */
+static e_uint32 clk = 844451141;
+/* Sampling rate */
+static e_uint32 rate = 3354932;
+
+/* WaveTable for each envelope amp */
+static e_uint16 fullsintable[PG_WIDTH];
+static e_uint16 halfsintable[PG_WIDTH];
+
+static e_uint16 *waveform[2] = { fullsintable, halfsintable };
+
+/* LFO Table */
+static e_int32 pmtable[PM_PG_WIDTH];
+static e_int32 amtable[AM_PG_WIDTH];
+
+/* Phase delta for LFO */
+static e_uint32 pm_dphase;
+static e_uint32 am_dphase;
+
+/* dB to Liner table */
+static e_int16 DB2LIN_TABLE[(DB_MUTE + DB_MUTE) * 2];
+
+/* Liner to Log curve conversion table (for Attack rate). */
+static e_uint16 AR_ADJUST_TABLE[1 << EG_BITS];
+
+/* Empty voice data */
+static OPLL_PATCH null_patch = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+/* Basic voice Data */
+static OPLL_PATCH default_patch[OPLL_TONE_NUM][(16 + 3) * 2];
+
+/* Definition of envelope mode */
+enum OPLL_EG_STATE
+{ READY, ATTACK, DECAY, SUSHOLD, SUSTINE, RELEASE, SETTLE, FINISH };
+
+/* Phase incr table for Attack */
+static e_uint32 dphaseARTable[16][16];
+/* Phase incr table for Decay and Release */
+static e_uint32 dphaseDRTable[16][16];
+
+/* KSL + TL Table */
+static e_uint32 tllTable[16][8][1 << TL_BITS][4];
+static e_int32 rksTable[2][8][2];
+
+/* Phase incr table for PG */
+static e_uint32 dphaseTable[512][8][16];
+
+/***************************************************
+
+ Create tables
+
+****************************************************/
+INLINE static e_int32
+Min (e_int32 i, e_int32 j)
+{
+ if (i < j)
+ return i;
+ else
+ return j;
+}
+
+/* Table for AR to LogCurve. */
+static void
+makeAdjustTable (void)
+{
+ e_int32 i;
+
+ AR_ADJUST_TABLE[0] = (1 << EG_BITS) - 1;
+ for (i = 1; i < (1<<EG_BITS); i++)
+ AR_ADJUST_TABLE[i] = (e_uint16) ((double) (1<<EG_BITS)-1 - ((1<<EG_BITS)-1)*log(i)/log(127));
+}
+
+
+/* Table for dB(0 -- (1<<DB_BITS)-1) to Liner(0 -- DB2LIN_AMP_WIDTH) */
+static void
+makeDB2LinTable (void)
+{
+ e_int32 i;
+
+ for (i = 0; i < DB_MUTE + DB_MUTE; i++)
+ {
+ DB2LIN_TABLE[i] = (e_int16) ((double) ((1 << DB2LIN_AMP_BITS) - 1) * pow (10, -(double) i * DB_STEP / 20));
+ if (i >= DB_MUTE) DB2LIN_TABLE[i] = 0;
+ DB2LIN_TABLE[i + DB_MUTE + DB_MUTE] = (e_int16) (-DB2LIN_TABLE[i]);
+ }
+}
+
+/* Liner(+0.0 - +1.0) to dB((1<<DB_BITS) - 1 -- 0) */
+static e_int32
+lin2db (double d)
+{
+ if (d == 0)
+ return (DB_MUTE - 1);
+ else
+ return Min (-(e_int32) (20.0 * log10 (d) / DB_STEP), DB_MUTE-1); /* 0 -- 127 */
+}
+
+
+/* Sin Table */
+static void
+makeSinTable (void)
+{
+ e_int32 i;
+
+ for (i = 0; i < PG_WIDTH / 4; i++)
+ {
+ fullsintable[i] = (e_uint32) lin2db (sin (2.0 * PI * i / PG_WIDTH) );
+ }
+
+ for (i = 0; i < PG_WIDTH / 4; i++)
+ {
+ fullsintable[PG_WIDTH / 2 - 1 - i] = fullsintable[i];
+ }
+
+ for (i = 0; i < PG_WIDTH / 2; i++)
+ {
+ fullsintable[PG_WIDTH / 2 + i] = (e_uint32) (DB_MUTE + DB_MUTE + fullsintable[i]);
+ }
+
+ for (i = 0; i < PG_WIDTH / 2; i++)
+ halfsintable[i] = fullsintable[i];
+ for (i = PG_WIDTH / 2; i < PG_WIDTH; i++)
+ halfsintable[i] = fullsintable[0];
+}
+
+static double saw(double phase)
+{
+ if(phase <= PI/2)
+ return phase * 2 / PI ;
+ else if(phase <= PI*3/2)
+ return 2.0 - ( phase * 2 / PI );
+ else
+ return -4.0 + phase * 2 / PI;
+}
+
+/* Table for Pitch Modulator */
+static void
+makePmTable (void)
+{
+ e_int32 i;
+
+ for (i = 0; i < PM_PG_WIDTH; i++)
+ /* pmtable[i] = (e_int32) ((double) PM_AMP * pow (2, (double) PM_DEPTH * sin (2.0 * PI * i / PM_PG_WIDTH) / 1200)); */
+ pmtable[i] = (e_int32) ((double) PM_AMP * pow (2, (double) PM_DEPTH * saw (2.0 * PI * i / PM_PG_WIDTH) / 1200));
+}
+
+/* Table for Amp Modulator */
+static void
+makeAmTable (void)
+{
+ e_int32 i;
+
+ for (i = 0; i < AM_PG_WIDTH; i++)
+ /* amtable[i] = (e_int32) ((double) AM_DEPTH / 2 / DB_STEP * (1.0 + sin (2.0 * PI * i / PM_PG_WIDTH))); */
+ amtable[i] = (e_int32) ((double) AM_DEPTH / 2 / DB_STEP * (1.0 + saw (2.0 * PI * i / PM_PG_WIDTH)));
+}
+
+/* Phase increment counter table */
+static void
+makeDphaseTable (void)
+{
+ e_uint32 fnum, block, ML;
+ e_uint32 mltable[16] =
+ { 1, 1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2, 6 * 2, 7 * 2, 8 * 2, 9 * 2, 10 * 2, 10 * 2, 12 * 2, 12 * 2, 15 * 2, 15 * 2 };
+
+ for (fnum = 0; fnum < 512; fnum++)
+ for (block = 0; block < 8; block++)
+ for (ML = 0; ML < 16; ML++)
+ dphaseTable[fnum][block][ML] = RATE_ADJUST (((fnum * mltable[ML]) << block) >> (20 - DP_BITS));
+}
+
+static void
+makeTllTable (void)
+{
+#define dB2(x) ((x)*2)
+
+ static double kltable[16] = {
+ dB2 (0.000), dB2 (9.000), dB2 (12.000), dB2 (13.875), dB2 (15.000), dB2 (16.125), dB2 (16.875), dB2 (17.625),
+ dB2 (18.000), dB2 (18.750), dB2 (19.125), dB2 (19.500), dB2 (19.875), dB2 (20.250), dB2 (20.625), dB2 (21.000)
+ };
+
+ e_int32 tmp;
+ e_int32 fnum, block, TL, KL;
+
+ for (fnum = 0; fnum < 16; fnum++)
+ for (block = 0; block < 8; block++)
+ for (TL = 0; TL < 64; TL++)
+ for (KL = 0; KL < 4; KL++)
+ {
+ if (KL == 0)
+ {
+ tllTable[fnum][block][TL][KL] = TL2EG (TL);
+ }
+ else
+ {
+ tmp = (e_int32) (kltable[fnum] - dB2 (3.000) * (7 - block));
+ if (tmp <= 0)
+ tllTable[fnum][block][TL][KL] = TL2EG (TL);
+ else
+ tllTable[fnum][block][TL][KL] = (e_uint32) ((tmp >> (3 - KL)) / EG_STEP) + TL2EG (TL);
+ }
+ }
+}
+
+#ifdef USE_SPEC_ENV_SPEED
+static double attacktime[16][4] = {
+ {0, 0, 0, 0},
+ {1730.15, 1400.60, 1153.43, 988.66},
+ {865.08, 700.30, 576.72, 494.33},
+ {432.54, 350.15, 288.36, 247.16},
+ {216.27, 175.07, 144.18, 123.58},
+ {108.13, 87.54, 72.09, 61.79},
+ {54.07, 43.77, 36.04, 30.90},
+ {27.03, 21.88, 18.02, 15.45},
+ {13.52, 10.94, 9.01, 7.72},
+ {6.76, 5.47, 4.51, 3.86},
+ {3.38, 2.74, 2.25, 1.93},
+ {1.69, 1.37, 1.13, 0.97},
+ {0.84, 0.70, 0.60, 0.54},
+ {0.50, 0.42, 0.34, 0.30},
+ {0.28, 0.22, 0.18, 0.14},
+ {0.00, 0.00, 0.00, 0.00}
+};
+
+static double decaytime[16][4] = {
+ {0, 0, 0, 0},
+ {20926.60, 16807.20, 14006.00, 12028.60},
+ {10463.30, 8403.58, 7002.98, 6014.32},
+ {5231.64, 4201.79, 3501.49, 3007.16},
+ {2615.82, 2100.89, 1750.75, 1503.58},
+ {1307.91, 1050.45, 875.37, 751.79},
+ {653.95, 525.22, 437.69, 375.90},
+ {326.98, 262.61, 218.84, 187.95},
+ {163.49, 131.31, 109.42, 93.97},
+ {81.74, 65.65, 54.71, 46.99},
+ {40.87, 32.83, 27.36, 23.49},
+ {20.44, 16.41, 13.68, 11.75},
+ {10.22, 8.21, 6.84, 5.87},
+ {5.11, 4.10, 3.42, 2.94},
+ {2.55, 2.05, 1.71, 1.47},
+ {1.27, 1.27, 1.27, 1.27}
+};
+#endif
+
+/* Rate Table for Attack */
+static void
+makeDphaseARTable (void)
+{
+ e_int32 AR, Rks, RM, RL;
+
+#ifdef USE_SPEC_ENV_SPEED
+ e_uint32 attacktable[16][4];
+
+ for (RM = 0; RM < 16; RM++)
+ for (RL = 0; RL < 4; RL++)
+ {
+ if (RM == 0)
+ attacktable[RM][RL] = 0;
+ else if (RM == 15)
+ attacktable[RM][RL] = EG_DP_WIDTH;
+ else
+ attacktable[RM][RL] = (e_uint32) ((double) (1 << EG_DP_BITS) / (attacktime[RM][RL] * 3579545 / 72000));
+
+ }
+#endif
+
+ for (AR = 0; AR < 16; AR++)
+ for (Rks = 0; Rks < 16; Rks++)
+ {
+ RM = AR + (Rks >> 2);
+ RL = Rks & 3;
+ if (RM > 15)
+ RM = 15;
+ switch (AR)
+ {
+ case 0:
+ dphaseARTable[AR][Rks] = 0;
+ break;
+ case 15:
+ dphaseARTable[AR][Rks] = 0;/*EG_DP_WIDTH;*/
+ break;
+ default:
+#ifdef USE_SPEC_ENV_SPEED
+ dphaseARTable[AR][Rks] = RATE_ADJUST (attacktable[RM][RL]);
+#else
+ dphaseARTable[AR][Rks] = RATE_ADJUST ((3 * (RL + 4) << (RM + 1)));
+#endif
+ break;
+ }
+ }
+}
+
+/* Rate Table for Decay and Release */
+static void
+makeDphaseDRTable (void)
+{
+ e_int32 DR, Rks, RM, RL;
+
+#ifdef USE_SPEC_ENV_SPEED
+ e_uint32 decaytable[16][4];
+
+ for (RM = 0; RM < 16; RM++)
+ for (RL = 0; RL < 4; RL++)
+ if (RM == 0)
+ decaytable[RM][RL] = 0;
+ else
+ decaytable[RM][RL] = (e_uint32) ((double) (1 << EG_DP_BITS) / (decaytime[RM][RL] * 3579545 / 72000));
+#endif
+
+ for (DR = 0; DR < 16; DR++)
+ for (Rks = 0; Rks < 16; Rks++)
+ {
+ RM = DR + (Rks >> 2);
+ RL = Rks & 3;
+ if (RM > 15)
+ RM = 15;
+ switch (DR)
+ {
+ case 0:
+ dphaseDRTable[DR][Rks] = 0;
+ break;
+ default:
+#ifdef USE_SPEC_ENV_SPEED
+ dphaseDRTable[DR][Rks] = RATE_ADJUST (decaytable[RM][RL]);
+#else
+ dphaseDRTable[DR][Rks] = RATE_ADJUST ((RL + 4) << (RM - 1));
+#endif
+ break;
+ }
+ }
+}
+
+static void
+makeRksTable (void)
+{
+
+ e_int32 fnum8, block, KR;
+
+ for (fnum8 = 0; fnum8 < 2; fnum8++)
+ for (block = 0; block < 8; block++)
+ for (KR = 0; KR < 2; KR++)
+ {
+ if (KR != 0)
+ rksTable[fnum8][block][KR] = (block << 1) + fnum8;
+ else
+ rksTable[fnum8][block][KR] = block >> 1;
+ }
+}
+
+void
+OPLL_dump2patch (const e_uint8 * dump, OPLL_PATCH * patch)
+{
+ patch[0].AM = (dump[0] >> 7) & 1;
+ patch[1].AM = (dump[1] >> 7) & 1;
+ patch[0].PM = (dump[0] >> 6) & 1;
+ patch[1].PM = (dump[1] >> 6) & 1;
+ patch[0].EG = (dump[0] >> 5) & 1;
+ patch[1].EG = (dump[1] >> 5) & 1;
+ patch[0].KR = (dump[0] >> 4) & 1;
+ patch[1].KR = (dump[1] >> 4) & 1;
+ patch[0].ML = (dump[0]) & 15;
+ patch[1].ML = (dump[1]) & 15;
+ patch[0].KL = (dump[2] >> 6) & 3;
+ patch[1].KL = (dump[3] >> 6) & 3;
+ patch[0].TL = (dump[2]) & 63;
+ patch[0].FB = (dump[3]) & 7;
+ patch[0].WF = (dump[3] >> 3) & 1;
+ patch[1].WF = (dump[3] >> 4) & 1;
+ patch[0].AR = (dump[4] >> 4) & 15;
+ patch[1].AR = (dump[5] >> 4) & 15;
+ patch[0].DR = (dump[4]) & 15;
+ patch[1].DR = (dump[5]) & 15;
+ patch[0].SL = (dump[6] >> 4) & 15;
+ patch[1].SL = (dump[7] >> 4) & 15;
+ patch[0].RR = (dump[6]) & 15;
+ patch[1].RR = (dump[7]) & 15;
+}
+
+void
+OPLL_getDefaultPatch (e_int32 type, e_int32 num, OPLL_PATCH * patch)
+{
+ OPLL_dump2patch (default_inst[type] + num * 16, patch);
+}
+
+static void
+makeDefaultPatch ()
+{
+ e_int32 i, j;
+
+ for (i = 0; i < OPLL_TONE_NUM; i++)
+ for (j = 0; j < 19; j++)
+ OPLL_getDefaultPatch (i, j, &default_patch[i][j * 2]);
+
+}
+
+void
+OPLL_setPatch (OPLL * opll, const e_uint8 * dump)
+{
+ OPLL_PATCH patch[2];
+ int i;
+
+ for (i = 0; i < 19; i++)
+ {
+ OPLL_dump2patch (dump + i * 16, patch);
+ memcpy (&opll->patch[i*2+0], &patch[0], sizeof (OPLL_PATCH));
+ memcpy (&opll->patch[i*2+1], &patch[1], sizeof (OPLL_PATCH));
+ }
+}
+
+void
+OPLL_patch2dump (const OPLL_PATCH * patch, e_uint8 * dump)
+{
+ dump[0] = (e_uint8) ((patch[0].AM << 7) + (patch[0].PM << 6) + (patch[0].EG << 5) + (patch[0].KR << 4) + patch[0].ML);
+ dump[1] = (e_uint8) ((patch[1].AM << 7) + (patch[1].PM << 6) + (patch[1].EG << 5) + (patch[1].KR << 4) + patch[1].ML);
+ dump[2] = (e_uint8) ((patch[0].KL << 6) + patch[0].TL);
+ dump[3] = (e_uint8) ((patch[1].KL << 6) + (patch[1].WF << 4) + (patch[0].WF << 3) + patch[0].FB);
+ dump[4] = (e_uint8) ((patch[0].AR << 4) + patch[0].DR);
+ dump[5] = (e_uint8) ((patch[1].AR << 4) + patch[1].DR);
+ dump[6] = (e_uint8) ((patch[0].SL << 4) + patch[0].RR);
+ dump[7] = (e_uint8) ((patch[1].SL << 4) + patch[1].RR);
+ dump[8] = 0;
+ dump[9] = 0;
+ dump[10] = 0;
+ dump[11] = 0;
+ dump[12] = 0;
+ dump[13] = 0;
+ dump[14] = 0;
+ dump[15] = 0;
+}
+
+/************************************************************
+
+ Calc Parameters
+
+************************************************************/
+
+INLINE static e_uint32
+calc_eg_dphase (OPLL_SLOT * slot)
+{
+
+ switch (slot->eg_mode)
+ {
+ case ATTACK:
+ return dphaseARTable[slot->patch->AR][slot->rks];
+
+ case DECAY:
+ return dphaseDRTable[slot->patch->DR][slot->rks];
+
+ case SUSHOLD:
+ return 0;
+
+ case SUSTINE:
+ return dphaseDRTable[slot->patch->RR][slot->rks];
+
+ case RELEASE:
+ if (slot->sustine)
+ return dphaseDRTable[5][slot->rks];
+ else if (slot->patch->EG)
+ return dphaseDRTable[slot->patch->RR][slot->rks];
+ else
+ return dphaseDRTable[7][slot->rks];
+
+ case SETTLE:
+ return dphaseDRTable[15][0];
+
+ case FINISH:
+ return 0;
+
+ default:
+ return 0;
+ }
+}
+
+/*************************************************************
+
+ OPLL internal interfaces
+
+*************************************************************/
+#define SLOT_BD1 12
+#define SLOT_BD2 13
+#define SLOT_HH 14
+#define SLOT_SD 15
+#define SLOT_TOM 16
+#define SLOT_CYM 17
+
+#define UPDATE_PG(S) (S)->dphase = dphaseTable[(S)->fnum][(S)->block][(S)->patch->ML]
+#define UPDATE_TLL(S)\
+(((S)->type==0)?\
+((S)->tll = tllTable[((S)->fnum)>>5][(S)->block][(S)->patch->TL][(S)->patch->KL]):\
+((S)->tll = tllTable[((S)->fnum)>>5][(S)->block][(S)->volume][(S)->patch->KL]))
+#define UPDATE_RKS(S) (S)->rks = rksTable[((S)->fnum)>>8][(S)->block][(S)->patch->KR]
+#define UPDATE_WF(S) (S)->sintbl = waveform[(S)->patch->WF]
+#define UPDATE_EG(S) (S)->eg_dphase = calc_eg_dphase(S)
+#define UPDATE_ALL(S)\
+ UPDATE_PG(S);\
+ UPDATE_TLL(S);\
+ UPDATE_RKS(S);\
+ UPDATE_WF(S); \
+ UPDATE_EG(S) /* EG should be updated last. */
+
+
+/* Slot key on */
+INLINE static void
+slotOn (OPLL_SLOT * slot)
+{
+ slot->eg_mode = ATTACK;
+ slot->eg_phase = 0;
+ slot->phase = 0;
+ UPDATE_EG(slot);
+}
+
+/* Slot key on without reseting the phase */
+INLINE static void
+slotOn2 (OPLL_SLOT * slot)
+{
+ slot->eg_mode = ATTACK;
+ slot->eg_phase = 0;
+ UPDATE_EG(slot);
+}
+
+/* Slot key off */
+INLINE static void
+slotOff (OPLL_SLOT * slot)
+{
+ if (slot->eg_mode == ATTACK)
+ slot->eg_phase = EXPAND_BITS (AR_ADJUST_TABLE[HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS)], EG_BITS, EG_DP_BITS);
+ slot->eg_mode = RELEASE;
+ UPDATE_EG(slot);
+}
+
+/* Channel key on */
+INLINE static void
+keyOn (OPLL * opll, e_int32 i)
+{
+ if (!opll->slot_on_flag[i * 2])
+ slotOn (MOD(opll,i));
+ if (!opll->slot_on_flag[i * 2 + 1])
+ slotOn (CAR(opll,i));
+ opll->key_status[i] = 1;
+}
+
+/* Channel key off */
+INLINE static void
+keyOff (OPLL * opll, e_int32 i)
+{
+ if (opll->slot_on_flag[i * 2 + 1])
+ slotOff (CAR(opll,i));
+ opll->key_status[i] = 0;
+}
+
+INLINE static void
+keyOn_BD (OPLL * opll)
+{
+ keyOn (opll, 6);
+}
+INLINE static void
+keyOn_SD (OPLL * opll)
+{
+ if (!opll->slot_on_flag[SLOT_SD])
+ slotOn (CAR(opll,7));
+}
+INLINE static void
+keyOn_TOM (OPLL * opll)
+{
+ if (!opll->slot_on_flag[SLOT_TOM])
+ slotOn (MOD(opll,8));
+}
+INLINE static void
+keyOn_HH (OPLL * opll)
+{
+ if (!opll->slot_on_flag[SLOT_HH])
+ slotOn2 (MOD(opll,7));
+}
+INLINE static void
+keyOn_CYM (OPLL * opll)
+{
+ if (!opll->slot_on_flag[SLOT_CYM])
+ slotOn2 (CAR(opll,8));
+}
+
+/* Drum key off */
+INLINE static void
+keyOff_BD (OPLL * opll)
+{
+ keyOff (opll, 6);
+}
+INLINE static void
+keyOff_SD (OPLL * opll)
+{
+ if (opll->slot_on_flag[SLOT_SD])
+ slotOff (CAR(opll,7));
+}
+INLINE static void
+keyOff_TOM (OPLL * opll)
+{
+ if (opll->slot_on_flag[SLOT_TOM])
+ slotOff (MOD(opll,8));
+}
+INLINE static void
+keyOff_HH (OPLL * opll)
+{
+ if (opll->slot_on_flag[SLOT_HH])
+ slotOff (MOD(opll,7));
+}
+INLINE static void
+keyOff_CYM (OPLL * opll)
+{
+ if (opll->slot_on_flag[SLOT_CYM])
+ slotOff (CAR(opll,8));
+}
+
+/* Change a voice */
+INLINE static void
+setPatch (OPLL * opll, e_int32 i, e_int32 num)
+{
+ opll->patch_number[i] = num;
+ MOD(opll,i)->patch = &opll->patch[num * 2 + 0];
+ CAR(opll,i)->patch = &opll->patch[num * 2 + 1];
+}
+
+/* Change a rhythm voice */
+INLINE static void
+setSlotPatch (OPLL_SLOT * slot, OPLL_PATCH * patch)
+{
+ slot->patch = patch;
+}
+
+/* Set sustine parameter */
+INLINE static void
+setSustine (OPLL * opll, e_int32 c, e_int32 sustine)
+{
+ CAR(opll,c)->sustine = sustine;
+ if (MOD(opll,c)->type)
+ MOD(opll,c)->sustine = sustine;
+}
+
+/* Volume : 6bit ( Volume register << 2 ) */
+INLINE static void
+setVolume (OPLL * opll, e_int32 c, e_int32 volume)
+{
+ CAR(opll,c)->volume = volume;
+}
+
+INLINE static void
+setSlotVolume (OPLL_SLOT * slot, e_int32 volume)
+{
+ slot->volume = volume;
+}
+
+/* Set F-Number ( fnum : 9bit ) */
+INLINE static void
+setFnumber (OPLL * opll, e_int32 c, e_int32 fnum)
+{
+ CAR(opll,c)->fnum = fnum;
+ MOD(opll,c)->fnum = fnum;
+}
+
+/* Set Block data (block : 3bit ) */
+INLINE static void
+setBlock (OPLL * opll, e_int32 c, e_int32 block)
+{
+ CAR(opll,c)->block = block;
+ MOD(opll,c)->block = block;
+}
+
+/* Change Rhythm Mode */
+INLINE static void
+update_rhythm_mode (OPLL * opll)
+{
+ if (opll->patch_number[6] & 0x10)
+ {
+ if (!(opll->slot_on_flag[SLOT_BD2] | (opll->reg[0x0e] & 32)))
+ {
+ opll->slot[SLOT_BD1].eg_mode = FINISH;
+ opll->slot[SLOT_BD2].eg_mode = FINISH;
+ setPatch (opll, 6, opll->reg[0x36] >> 4);
+ }
+ }
+ else if (opll->reg[0x0e] & 32)
+ {
+ opll->patch_number[6] = 16;
+ opll->slot[SLOT_BD1].eg_mode = FINISH;
+ opll->slot[SLOT_BD2].eg_mode = FINISH;
+ setSlotPatch (&opll->slot[SLOT_BD1], &opll->patch[16 * 2 + 0]);
+ setSlotPatch (&opll->slot[SLOT_BD2], &opll->patch[16 * 2 + 1]);
+ }
+
+ if (opll->patch_number[7] & 0x10)
+ {
+ if (!((opll->slot_on_flag[SLOT_HH] && opll->slot_on_flag[SLOT_SD]) | (opll->reg[0x0e] & 32)))
+ {
+ opll->slot[SLOT_HH].type = 0;
+ opll->slot[SLOT_HH].eg_mode = FINISH;
+ opll->slot[SLOT_SD].eg_mode = FINISH;
+ setPatch (opll, 7, opll->reg[0x37] >> 4);
+ }
+ }
+ else if (opll->reg[0x0e] & 32)
+ {
+ opll->patch_number[7] = 17;
+ opll->slot[SLOT_HH].type = 1;
+ opll->slot[SLOT_HH].eg_mode = FINISH;
+ opll->slot[SLOT_SD].eg_mode = FINISH;
+ setSlotPatch (&opll->slot[SLOT_HH], &opll->patch[17 * 2 + 0]);
+ setSlotPatch (&opll->slot[SLOT_SD], &opll->patch[17 * 2 + 1]);
+ }
+
+ if (opll->patch_number[8] & 0x10)
+ {
+ if (!((opll->slot_on_flag[SLOT_CYM] && opll->slot_on_flag[SLOT_TOM]) | (opll->reg[0x0e] & 32)))
+ {
+ opll->slot[SLOT_TOM].type = 0;
+ opll->slot[SLOT_TOM].eg_mode = FINISH;
+ opll->slot[SLOT_CYM].eg_mode = FINISH;
+ setPatch (opll, 8, opll->reg[0x38] >> 4);
+ }
+ }
+ else if (opll->reg[0x0e] & 32)
+ {
+ opll->patch_number[8] = 18;
+ opll->slot[SLOT_TOM].type = 1;
+ opll->slot[SLOT_TOM].eg_mode = FINISH;
+ opll->slot[SLOT_CYM].eg_mode = FINISH;
+ setSlotPatch (&opll->slot[SLOT_TOM], &opll->patch[18 * 2 + 0]);
+ setSlotPatch (&opll->slot[SLOT_CYM], &opll->patch[18 * 2 + 1]);
+ }
+}
+
+INLINE static void
+update_key_status (OPLL * opll)
+{
+ int ch;
+
+ for (ch = 0; ch < 9; ch++)
+ opll->slot_on_flag[ch * 2] = opll->slot_on_flag[ch * 2 + 1] = (opll->reg[0x20 + ch]) & 0x10;
+
+ if (opll->reg[0x0e] & 32)
+ {
+ opll->slot_on_flag[SLOT_BD1] |= (opll->reg[0x0e] & 0x10);
+ opll->slot_on_flag[SLOT_BD2] |= (opll->reg[0x0e] & 0x10);
+ opll->slot_on_flag[SLOT_SD] |= (opll->reg[0x0e] & 0x08);
+ opll->slot_on_flag[SLOT_HH] |= (opll->reg[0x0e] & 0x01);
+ opll->slot_on_flag[SLOT_TOM] |= (opll->reg[0x0e] & 0x04);
+ opll->slot_on_flag[SLOT_CYM] |= (opll->reg[0x0e] & 0x02);
+ }
+}
+
+void
+OPLL_copyPatch (OPLL * opll, e_int32 num, OPLL_PATCH * patch)
+{
+ memcpy (&opll->patch[num], patch, sizeof (OPLL_PATCH));
+}
+
+/***********************************************************
+
+ Initializing
+
+***********************************************************/
+
+static void
+OPLL_SLOT_reset (OPLL_SLOT * slot, int type)
+{
+ slot->type = type;
+ slot->sintbl = waveform[0];
+ slot->phase = 0;
+ slot->dphase = 0;
+ slot->output[0] = 0;
+ slot->output[1] = 0;
+ slot->feedback = 0;
+ slot->eg_mode = FINISH;
+ slot->eg_phase = EG_DP_WIDTH;
+ slot->eg_dphase = 0;
+ slot->rks = 0;
+ slot->tll = 0;
+ slot->sustine = 0;
+ slot->fnum = 0;
+ slot->block = 0;
+ slot->volume = 0;
+ slot->pgout = 0;
+ slot->egout = 0;
+ slot->patch = &null_patch;
+}
+
+static void
+internal_refresh (void)
+{
+ makeDphaseTable ();
+ makeDphaseARTable ();
+ makeDphaseDRTable ();
+ pm_dphase = (e_uint32) RATE_ADJUST (PM_SPEED * PM_DP_WIDTH / (clk / 72));
+ am_dphase = (e_uint32) RATE_ADJUST (AM_SPEED * AM_DP_WIDTH / (clk / 72));
+}
+
+static void
+maketables (e_uint32 c, e_uint32 r)
+{
+ if (c != clk)
+ {
+ clk = c;
+ makePmTable ();
+ makeAmTable ();
+ makeDB2LinTable ();
+ makeAdjustTable ();
+ makeTllTable ();
+ makeRksTable ();
+ makeSinTable ();
+ makeDefaultPatch ();
+ }
+
+ if (r != rate)
+ {
+ rate = r;
+ internal_refresh ();
+ }
+}
+
+OPLL *
+OPLL_new (e_uint32 clk, e_uint32 rate)
+{
+ OPLL *opll;
+ e_int32 i;
+
+ maketables (clk, rate);
+
+ opll = (OPLL *) calloc (sizeof (OPLL), 1);
+ if (opll == nullptr)
+ return nullptr;
+
+ for (i = 0; i < 19 * 2; i++)
+ memcpy(&opll->patch[i],&null_patch,sizeof(OPLL_PATCH));
+
+ opll->mask = 0;
+
+ OPLL_reset (opll);
+ OPLL_reset_patch (opll, 0);
+
+ return opll;
+}
+
+
+void
+OPLL_delete (OPLL * opll)
+{
+ free (opll);
+}
+
+
+/* Reset patch datas by system default. */
+void
+OPLL_reset_patch (OPLL * opll, e_int32 type)
+{
+ e_int32 i;
+
+ for (i = 0; i < 19 * 2; i++)
+ OPLL_copyPatch (opll, i, &default_patch[type % OPLL_TONE_NUM][i]);
+}
+
+/* Reset whole of OPLL except patch datas. */
+void
+OPLL_reset (OPLL * opll)
+{
+ e_int32 i;
+
+ if (!opll)
+ return;
+
+ opll->adr = 0;
+ opll->out = 0;
+
+ opll->pm_phase = 0;
+ opll->am_phase = 0;
+
+ opll->noise_seed = 0xffff;
+ opll->mask = 0;
+
+ for (i = 0; i <18; i++)
+ OPLL_SLOT_reset(&opll->slot[i], i%2);
+
+ for (i = 0; i < 9; i++)
+ {
+ opll->key_status[i] = 0;
+ setPatch (opll, i, 0);
+ }
+
+ for (i = 0; i < 0x40; i++)
+ OPLL_writeReg (opll, i, 0);
+
+#ifndef EMU2413_COMPACTION
+ opll->realstep = (e_uint32) ((1 << 31) / rate);
+ opll->opllstep = (e_uint32) ((1 << 31) / (clk / 72));
+ opll->oplltime = 0;
+ for (i = 0; i < 14; i++)
+ opll->pan[i] = 127; /* Maxim: pan is 0..255 */
+ opll->sprev[0] = opll->sprev[1] = 0;
+ opll->snext[0] = opll->snext[1] = 0;
+#endif
+}
+
+/* Force Refresh (When external program changes some parameters). */
+void
+OPLL_forceRefresh (OPLL * opll)
+{
+ e_int32 i;
+
+ if (opll == nullptr)
+ return;
+
+ for (i = 0; i < 9; i++)
+ setPatch(opll,i,opll->patch_number[i]);
+
+ for (i = 0; i < 18; i++)
+ {
+ UPDATE_PG (&opll->slot[i]);
+ UPDATE_RKS (&opll->slot[i]);
+ UPDATE_TLL (&opll->slot[i]);
+ UPDATE_WF (&opll->slot[i]);
+ UPDATE_EG (&opll->slot[i]);
+ }
+}
+
+void
+OPLL_set_rate (OPLL * opll, e_uint32 r)
+{
+ if (opll->quality)
+ rate = 49716;
+ else
+ rate = r;
+ internal_refresh ();
+ rate = r;
+}
+
+void
+OPLL_set_quality (OPLL * opll, e_uint32 q)
+{
+ opll->quality = q;
+ OPLL_set_rate (opll, rate);
+}
+
+/*********************************************************
+
+ Generate wave data
+
+*********************************************************/
+/* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 2PI). */
+#if ( SLOT_AMP_BITS - PG_BITS ) > 0
+#define wave2_2pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS ))
+#else
+#define wave2_2pi(e) ( (e) << ( PG_BITS - SLOT_AMP_BITS ))
+#endif
+
+/* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 4PI). */
+#if ( SLOT_AMP_BITS - PG_BITS - 1 ) == 0
+#define wave2_4pi(e) (e)
+#elif ( SLOT_AMP_BITS - PG_BITS - 1 ) > 0
+#define wave2_4pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS - 1 ))
+#else
+#define wave2_4pi(e) ( (e) << ( 1 + PG_BITS - SLOT_AMP_BITS ))
+#endif
+
+/* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 8PI). */
+#if ( SLOT_AMP_BITS - PG_BITS - 2 ) == 0
+#define wave2_8pi(e) (e)
+#elif ( SLOT_AMP_BITS - PG_BITS - 2 ) > 0
+#define wave2_8pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS - 2 ))
+#else
+#define wave2_8pi(e) ( (e) << ( 2 + PG_BITS - SLOT_AMP_BITS ))
+#endif
+
+/* Update AM, PM unit */
+static void
+update_ampm (OPLL * opll)
+{
+ opll->pm_phase = (opll->pm_phase + pm_dphase) & (PM_DP_WIDTH - 1);
+ opll->am_phase = (opll->am_phase + am_dphase) & (AM_DP_WIDTH - 1);
+ opll->lfo_am = amtable[HIGHBITS (opll->am_phase, AM_DP_BITS - AM_PG_BITS)];
+ opll->lfo_pm = pmtable[HIGHBITS (opll->pm_phase, PM_DP_BITS - PM_PG_BITS)];
+}
+
+/* PG */
+INLINE static void
+calc_phase (OPLL_SLOT * slot, e_int32 lfo)
+{
+ if (slot->patch->PM)
+ slot->phase += (slot->dphase * lfo) >> PM_AMP_BITS;
+ else
+ slot->phase += slot->dphase;
+
+ slot->phase &= (DP_WIDTH - 1);
+
+ slot->pgout = HIGHBITS (slot->phase, DP_BASE_BITS);
+}
+
+/* Update Noise unit */
+static void
+update_noise (OPLL * opll)
+{
+ if(opll->noise_seed&1) opll->noise_seed ^= 0x8003020;
+ opll->noise_seed >>= 1;
+}
+
+/* EG */
+static void
+calc_envelope (OPLL_SLOT * slot, e_int32 lfo)
+{
+#define S2E(x) (SL2EG((e_int32)(x/SL_STEP))<<(EG_DP_BITS-EG_BITS))
+
+ static e_uint32 SL[16] = {
+ S2E (0.0), S2E (3.0), S2E (6.0), S2E (9.0), S2E (12.0), S2E (15.0), S2E (18.0), S2E (21.0),
+ S2E (24.0), S2E (27.0), S2E (30.0), S2E (33.0), S2E (36.0), S2E (39.0), S2E (42.0), S2E (48.0)
+ };
+
+ e_uint32 egout;
+
+ switch (slot->eg_mode)
+ {
+ case ATTACK:
+ egout = AR_ADJUST_TABLE[HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS)];
+ slot->eg_phase += slot->eg_dphase;
+ if((EG_DP_WIDTH & slot->eg_phase)||(slot->patch->AR==15))
+ {
+ egout = 0;
+ slot->eg_phase = 0;
+ slot->eg_mode = DECAY;
+ UPDATE_EG (slot);
+ }
+ break;
+
+ case DECAY:
+ egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS);
+ slot->eg_phase += slot->eg_dphase;
+ if (slot->eg_phase >= SL[slot->patch->SL])
+ {
+ if (slot->patch->EG)
+ {
+ slot->eg_phase = SL[slot->patch->SL];
+ slot->eg_mode = SUSHOLD;
+ UPDATE_EG (slot);
+ }
+ else
+ {
+ slot->eg_phase = SL[slot->patch->SL];
+ slot->eg_mode = SUSTINE;
+ UPDATE_EG (slot);
+ }
+ }
+ break;
+
+ case SUSHOLD:
+ egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS);
+ if (slot->patch->EG == 0)
+ {
+ slot->eg_mode = SUSTINE;
+ UPDATE_EG (slot);
+ }
+ break;
+
+ case SUSTINE:
+ case RELEASE:
+ egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS);
+ slot->eg_phase += slot->eg_dphase;
+ if (egout >= (1 << EG_BITS))
+ {
+ slot->eg_mode = FINISH;
+ egout = (1 << EG_BITS) - 1;
+ }
+ break;
+
+ case SETTLE:
+ egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS);
+ slot->eg_phase += slot->eg_dphase;
+ if (egout >= (1 << EG_BITS))
+ {
+ slot->eg_mode = ATTACK;
+ egout = (1 << EG_BITS) - 1;
+ UPDATE_EG(slot);
+ }
+ break;
+
+ case FINISH:
+ egout = (1 << EG_BITS) - 1;
+ break;
+
+ default:
+ egout = (1 << EG_BITS) - 1;
+ break;
+ }
+
+ if (slot->patch->AM)
+ egout = EG2DB (egout + slot->tll) + lfo;
+ else
+ egout = EG2DB (egout + slot->tll);
+
+ if (egout >= DB_MUTE)
+ egout = DB_MUTE - 1;
+
+ slot->egout = egout | 3;
+}
+
+/* CARRIOR */
+INLINE static e_int32
+calc_slot_car (OPLL_SLOT * slot, e_int32 fm)
+{
+ if (slot->egout >= (DB_MUTE - 1))
+ {
+ slot->output[0] = 0;
+ }
+ else
+ {
+ slot->output[0] = DB2LIN_TABLE[slot->sintbl[(slot->pgout+wave2_8pi(fm))&(PG_WIDTH-1)] + slot->egout];
+ }
+
+ slot->output[1] = (slot->output[1] + slot->output[0]) >> 1;
+ return slot->output[1];
+}
+
+/* MODULATOR */
+INLINE static e_int32
+calc_slot_mod (OPLL_SLOT * slot)
+{
+ e_int32 fm;
+
+ slot->output[1] = slot->output[0];
+
+ if (slot->egout >= (DB_MUTE - 1))
+ {
+ slot->output[0] = 0;
+ }
+ else if (slot->patch->FB != 0)
+ {
+ fm = wave2_4pi (slot->feedback) >> (7 - slot->patch->FB);
+ slot->output[0] = DB2LIN_TABLE[slot->sintbl[(slot->pgout+fm)&(PG_WIDTH-1)] + slot->egout];
+ }
+ else
+ {
+ slot->output[0] = DB2LIN_TABLE[slot->sintbl[slot->pgout] + slot->egout];
+ }
+
+ slot->feedback = (slot->output[1] + slot->output[0]) >> 1;
+
+ return slot->feedback;
+
+}
+
+/* TOM */
+INLINE static e_int32
+calc_slot_tom (OPLL_SLOT * slot)
+{
+ if (slot->egout >= (DB_MUTE - 1))
+ return 0;
+
+ return DB2LIN_TABLE[slot->sintbl[slot->pgout] + slot->egout];
+
+}
+
+/* SNARE */
+INLINE static e_int32
+calc_slot_snare (OPLL_SLOT * slot, e_uint32 noise)
+{
+ if(slot->egout>=(DB_MUTE-1))
+ return 0;
+
+ if(BIT(slot->pgout,7))
+ return DB2LIN_TABLE[(noise?DB_POS(0.0):DB_POS(15.0))+slot->egout];
+ else
+ return DB2LIN_TABLE[(noise?DB_NEG(0.0):DB_NEG(15.0))+slot->egout];
+}
+
+/*
+ TOP-CYM
+ */
+INLINE static e_int32
+calc_slot_cym (OPLL_SLOT * slot, e_uint32 pgout_hh)
+{
+ e_uint32 dbout;
+
+ if (slot->egout >= (DB_MUTE - 1))
+ return 0;
+ else if(
+ /* the same as fmopl.c */
+ ((BIT(pgout_hh,PG_BITS-8)^BIT(pgout_hh,PG_BITS-1))|BIT(pgout_hh,PG_BITS-7)) ^
+ /* different from fmopl.c */
+ (BIT(slot->pgout,PG_BITS-7)&!BIT(slot->pgout,PG_BITS-5))
+ )
+ dbout = DB_NEG(3.0);
+ else
+ dbout = DB_POS(3.0);
+
+ return DB2LIN_TABLE[dbout + slot->egout];
+}
+
+/*
+ HI-HAT
+*/
+INLINE static e_int32
+calc_slot_hat (OPLL_SLOT *slot, e_int32 pgout_cym, e_uint32 noise)
+{
+ e_uint32 dbout;
+
+ if (slot->egout >= (DB_MUTE - 1))
+ return 0;
+ else if(
+ /* the same as fmopl.c */
+ ((BIT(slot->pgout,PG_BITS-8)^BIT(slot->pgout,PG_BITS-1))|BIT(slot->pgout,PG_BITS-7)) ^
+ /* different from fmopl.c */
+ (BIT(pgout_cym,PG_BITS-7)&!BIT(pgout_cym,PG_BITS-5))
+ )
+ {
+ if(noise)
+ dbout = DB_NEG(12.0);
+ else
+ dbout = DB_NEG(24.0);
+ }
+ else
+ {
+ if(noise)
+ dbout = DB_POS(12.0);
+ else
+ dbout = DB_POS(24.0);
+ }
+
+ return DB2LIN_TABLE[dbout + slot->egout];
+}
+
+INLINE static e_int16
+calc (OPLL * opll)
+{
+ e_int32 inst = 0, perc = 0, out = 0;
+ e_int32 i;
+
+ update_ampm (opll);
+ update_noise (opll);
+
+ for (i = 0; i < 18; i++)
+ {
+ calc_phase(&opll->slot[i],opll->lfo_pm);
+ calc_envelope(&opll->slot[i],opll->lfo_am);
+ }
+
+ for (i = 0; i < 6; i++)
+ if (!(opll->mask & OPLL_MASK_CH (i)) && (CAR(opll,i)->eg_mode != FINISH))
+ inst += calc_slot_car (CAR(opll,i), calc_slot_mod(MOD(opll,i)));
+
+ /* CH6 */
+ if (opll->patch_number[6] <= 15)
+ {
+ if (!(opll->mask & OPLL_MASK_CH (6)) && (CAR(opll,6)->eg_mode != FINISH))
+ inst += calc_slot_car (CAR(opll,6), calc_slot_mod(MOD(opll,6)));
+ }
+ else
+ {
+ if (!(opll->mask & OPLL_MASK_BD) && (CAR(opll,6)->eg_mode != FINISH))
+ perc += calc_slot_car (CAR(opll,6), calc_slot_mod(MOD(opll,6)));
+ }
+
+ /* CH7 */
+ if (opll->patch_number[7] <= 15)
+ {
+ if (!(opll->mask & OPLL_MASK_CH (7)) && (CAR(opll,7)->eg_mode != FINISH))
+ inst += calc_slot_car (CAR(opll,7), calc_slot_mod(MOD(opll,7)));
+ }
+ else
+ {
+ if (!(opll->mask & OPLL_MASK_HH) && (MOD(opll,7)->eg_mode != FINISH))
+ perc += calc_slot_hat (MOD(opll,7), CAR(opll,8)->pgout, opll->noise_seed&1);
+ if (!(opll->mask & OPLL_MASK_SD) && (CAR(opll,7)->eg_mode != FINISH))
+ perc -= calc_slot_snare (CAR(opll,7), opll->noise_seed&1);
+ }
+
+ /* CH8 */
+ if (opll->patch_number[8] <= 15)
+ {
+ if (!(opll->mask & OPLL_MASK_CH(8)) && (CAR(opll,8)->eg_mode != FINISH))
+ inst += calc_slot_car (CAR(opll,8), calc_slot_mod (MOD(opll,8)));
+ }
+ else
+ {
+ if (!(opll->mask & OPLL_MASK_TOM) && (MOD(opll,8)->eg_mode != FINISH))
+ perc += calc_slot_tom (MOD(opll,8));
+ if (!(opll->mask & OPLL_MASK_CYM) && (CAR(opll,8)->eg_mode != FINISH))
+ perc -= calc_slot_cym (CAR(opll,8), MOD(opll,7)->pgout);
+ }
+
+ out = inst + (perc << 1);
+ return (e_int16) out << 3;
+}
+
+#ifdef EMU2413_COMPACTION
+e_int16
+OPLL_calc (OPLL * opll)
+{
+ return calc (opll);
+}
+#else
+e_int16
+OPLL_calc (OPLL * opll)
+{
+ if (!opll->quality)
+ return calc (opll);
+
+ while (opll->realstep > opll->oplltime)
+ {
+ opll->oplltime += opll->opllstep;
+ opll->prev = opll->next;
+ opll->next = calc (opll);
+ }
+
+ opll->oplltime -= opll->realstep;
+ opll->out = (e_int16) (((double) opll->next * (opll->opllstep - opll->oplltime)
+ + (double) opll->prev * opll->oplltime) / opll->opllstep);
+
+ return (e_int16) opll->out;
+}
+#endif
+
+e_uint32
+OPLL_setMask (OPLL * opll, e_uint32 mask)
+{
+ e_uint32 ret;
+
+ if (opll)
+ {
+ ret = opll->mask;
+ opll->mask = mask;
+ return ret;
+ }
+ else
+ return 0;
+}
+
+e_uint32
+OPLL_toggleMask (OPLL * opll, e_uint32 mask)
+{
+ e_uint32 ret;
+
+ if (opll)
+ {
+ ret = opll->mask;
+ opll->mask ^= mask;
+ return ret;
+ }
+ else
+ return 0;
+}
+
+/****************************************************
+
+ I/O Ctrl
+
+*****************************************************/
+
+void
+OPLL_writeReg (OPLL * opll, e_uint32 reg, e_uint32 data)
+{
+ e_int32 i, v, ch;
+
+ data = data & 0xff;
+ reg = reg & 0x3f;
+ opll->reg[reg] = (e_uint8) data;
+
+ switch (reg)
+ {
+ case 0x00:
+ opll->patch[0].AM = (data >> 7) & 1;
+ opll->patch[0].PM = (data >> 6) & 1;
+ opll->patch[0].EG = (data >> 5) & 1;
+ opll->patch[0].KR = (data >> 4) & 1;
+ opll->patch[0].ML = (data) & 15;
+ for (i = 0; i < 9; i++)
+ {
+ if (opll->patch_number[i] == 0)
+ {
+ UPDATE_PG (MOD(opll,i));
+ UPDATE_RKS (MOD(opll,i));
+ UPDATE_EG (MOD(opll,i));
+ }
+ }
+ break;
+
+ case 0x01:
+ opll->patch[1].AM = (data >> 7) & 1;
+ opll->patch[1].PM = (data >> 6) & 1;
+ opll->patch[1].EG = (data >> 5) & 1;
+ opll->patch[1].KR = (data >> 4) & 1;
+ opll->patch[1].ML = (data) & 15;
+ for (i = 0; i < 9; i++)
+ {
+ if (opll->patch_number[i] == 0)
+ {
+ UPDATE_PG (CAR(opll,i));
+ UPDATE_RKS (CAR(opll,i));
+ UPDATE_EG (CAR(opll,i));
+ }
+ }
+ break;
+
+ case 0x02:
+ opll->patch[0].KL = (data >> 6) & 3;
+ opll->patch[0].TL = (data) & 63;
+ for (i = 0; i < 9; i++)
+ {
+ if (opll->patch_number[i] == 0)
+ {
+ UPDATE_TLL(MOD(opll,i));
+ }
+ }
+ break;
+
+ case 0x03:
+ opll->patch[1].KL = (data >> 6) & 3;
+ opll->patch[1].WF = (data >> 4) & 1;
+ opll->patch[0].WF = (data >> 3) & 1;
+ opll->patch[0].FB = (data) & 7;
+ for (i = 0; i < 9; i++)
+ {
+ if (opll->patch_number[i] == 0)
+ {
+ UPDATE_WF(MOD(opll,i));
+ UPDATE_WF(CAR(opll,i));
+ }
+ }
+ break;
+
+ case 0x04:
+ opll->patch[0].AR = (data >> 4) & 15;
+ opll->patch[0].DR = (data) & 15;
+ for (i = 0; i < 9; i++)
+ {
+ if (opll->patch_number[i] == 0)
+ {
+ UPDATE_EG (MOD(opll,i));
+ }
+ }
+ break;
+
+ case 0x05:
+ opll->patch[1].AR = (data >> 4) & 15;
+ opll->patch[1].DR = (data) & 15;
+ for (i = 0; i < 9; i++)
+ {
+ if (opll->patch_number[i] == 0)
+ {
+ UPDATE_EG(CAR(opll,i));
+ }
+ }
+ break;
+
+ case 0x06:
+ opll->patch[0].SL = (data >> 4) & 15;
+ opll->patch[0].RR = (data) & 15;
+ for (i = 0; i < 9; i++)
+ {
+ if (opll->patch_number[i] == 0)
+ {
+ UPDATE_EG (MOD(opll,i));
+ }
+ }
+ break;
+
+ case 0x07:
+ opll->patch[1].SL = (data >> 4) & 15;
+ opll->patch[1].RR = (data) & 15;
+ for (i = 0; i < 9; i++)
+ {
+ if (opll->patch_number[i] == 0)
+ {
+ UPDATE_EG (CAR(opll,i));
+ }
+ }
+ break;
+
+ case 0x0e:
+ update_rhythm_mode (opll);
+ if (data & 32)
+ {
+ if (data & 0x10)
+ keyOn_BD (opll);
+ else
+ keyOff_BD (opll);
+ if (data & 0x8)
+ keyOn_SD (opll);
+ else
+ keyOff_SD (opll);
+ if (data & 0x4)
+ keyOn_TOM (opll);
+ else
+ keyOff_TOM (opll);
+ if (data & 0x2)
+ keyOn_CYM (opll);
+ else
+ keyOff_CYM (opll);
+ if (data & 0x1)
+ keyOn_HH (opll);
+ else
+ keyOff_HH (opll);
+ }
+ update_key_status (opll);
+
+ UPDATE_ALL (MOD(opll,6));
+ UPDATE_ALL (CAR(opll,6));
+ UPDATE_ALL (MOD(opll,7));
+ UPDATE_ALL (CAR(opll,7));
+ UPDATE_ALL (MOD(opll,8));
+ UPDATE_ALL (CAR(opll,8));
+
+ break;
+
+ case 0x0f:
+ break;
+
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ case 0x18:
+ ch = reg - 0x10;
+ setFnumber (opll, ch, data + ((opll->reg[0x20 + ch] & 1) << 8));
+ UPDATE_ALL (MOD(opll,ch));
+ UPDATE_ALL (CAR(opll,ch));
+ break;
+
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x23:
+ case 0x24:
+ case 0x25:
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ ch = reg - 0x20;
+ setFnumber (opll, ch, ((data & 1) << 8) + opll->reg[0x10 + ch]);
+ setBlock (opll, ch, (data >> 1) & 7);
+ setSustine (opll, ch, (data >> 5) & 1);
+ if (data & 0x10)
+ keyOn (opll, ch);
+ else
+ keyOff (opll, ch);
+ UPDATE_ALL (MOD(opll,ch));
+ UPDATE_ALL (CAR(opll,ch));
+ update_key_status (opll);
+ update_rhythm_mode (opll);
+ break;
+
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ case 0x38:
+ i = (data >> 4) & 15;
+ v = data & 15;
+ if ((opll->reg[0x0e] & 32) && (reg >= 0x36))
+ {
+ switch (reg)
+ {
+ case 0x37:
+ setSlotVolume (MOD(opll,7), i << 2);
+ break;
+ case 0x38:
+ setSlotVolume (MOD(opll,8), i << 2);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ setPatch (opll, reg - 0x30, i);
+ }
+ setVolume (opll, reg - 0x30, v << 2);
+ UPDATE_ALL (MOD(opll,reg - 0x30));
+ UPDATE_ALL (CAR(opll,reg - 0x30));
+ break;
+
+ default:
+ break;
+
+ }
+}
+
+void
+OPLL_writeIO (OPLL * opll, e_uint32 adr, e_uint32 val)
+{
+ if (adr & 1)
+ OPLL_writeReg (opll, opll->adr, val);
+ else
+ opll->adr = val;
+}
+
+#ifndef EMU2413_COMPACTION
+/* STEREO MODE (OPT) */
+void
+OPLL_set_pan (OPLL * opll, e_uint32 ch, e_uint32 pan)
+{
+ opll->pan[ch & 15] = pan & 255; /* Maxim: pan is 0..255 */
+}
+
+static void
+calc_stereo (OPLL * opll, e_int32 out[2])
+{
+ /* Maxim: changed panning to be 0..255, 127 is centre */
+ e_int32 l=0,r=0;
+// e_int32 b[4] = { 0, 0, 0, 0 }; /* Ignore, Right, Left, Center */
+// e_int32 r[4] = { 0, 0, 0, 0 }; /* Ignore, Right, Left, Center */
+ e_int32 i;
+ e_int32 channel;
+
+ update_ampm (opll);
+ update_noise (opll);
+
+ for(i=0;i<18;i++)
+ {
+ calc_phase(&opll->slot[i],opll->lfo_pm);
+ calc_envelope(&opll->slot[i],opll->lfo_am);
+ }
+
+ for (i = 0; i < 6; i++)
+ if (!(opll->mask & OPLL_MASK_CH (i)) && (CAR(opll,i)->eg_mode != FINISH))
+ {
+ channel = calc_slot_car (CAR(opll,i), calc_slot_mod (MOD(opll,i)));
+ if ( opll->pan[i] == 127 )
+ {
+ l += channel;
+ r += channel;
+ }
+ else
+ {
+ l += channel * (255-opll->pan[i]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
+ r += channel * ( opll->pan[i]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
+ }
+ }
+
+
+ if (opll->patch_number[6] <= 15)
+ {
+ if (!(opll->mask & OPLL_MASK_CH (6)) && (CAR(opll,6)->eg_mode != FINISH))
+ {
+ channel = calc_slot_car (CAR(opll,6), calc_slot_mod (MOD(opll,6)));
+ if ( opll->pan[6] == 127 )
+ {
+ l += channel;
+ r += channel;
+ }
+ else
+ {
+ l += channel * (255-opll->pan[6]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
+ r += channel * ( opll->pan[6]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
+ }
+
+ }
+ }
+ else
+ {
+ if (!(opll->mask & OPLL_MASK_BD) && (CAR(opll,6)->eg_mode != FINISH))
+ {
+ channel = calc_slot_car (CAR(opll,6), calc_slot_mod (MOD(opll,6)));
+ if ( opll->pan[9] == 127 )
+ {
+ l += channel;
+ r += channel;
+ }
+ else
+ {
+ l += channel * (255-opll->pan[9]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
+ r += channel * ( opll->pan[9]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
+ }
+ }
+ }
+
+ if (opll->patch_number[7] <= 15)
+ {
+ if (!(opll->mask & OPLL_MASK_CH (7)) && (CAR (opll,7)->eg_mode != FINISH))
+ {
+ channel = calc_slot_car (CAR (opll,7), calc_slot_mod (MOD (opll,7)));
+ if ( opll->pan[7] == 127 )
+ {
+ l += channel;
+ r += channel;
+ }
+ else
+ {
+ l += channel * (255-opll->pan[7]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
+ r += channel * ( opll->pan[7]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
+ }
+ }
+ }
+ else
+ {
+ if (!(opll->mask & OPLL_MASK_HH) && (MOD (opll,7)->eg_mode != FINISH))
+ {
+ channel = calc_slot_hat (MOD (opll,7), CAR(opll,8)->pgout, opll->noise_seed&1);
+ if ( opll->pan[10] == 127 )
+ {
+ l += channel;
+ r += channel;
+ }
+ else
+ {
+ l += channel * (255-opll->pan[10]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
+ r += channel * ( opll->pan[10]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
+ }
+ }
+ if (!(opll->mask & OPLL_MASK_SD) && (CAR (opll,7)->eg_mode != FINISH))
+ {
+ channel = -calc_slot_snare (CAR (opll,7), opll->noise_seed&1); // this one is negated
+ if ( opll->pan[11] == 127 )
+ {
+ l += channel;
+ r += channel;
+ }
+ else
+ {
+ l += channel * (255-opll->pan[11]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
+ r += channel * ( opll->pan[11]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
+ }
+ }
+ }
+
+ if (opll->patch_number[8] <= 15)
+ {
+ if (!(opll->mask & OPLL_MASK_CH (8)) && (CAR (opll,8)->eg_mode != FINISH))
+ {
+ channel = calc_slot_car (CAR (opll,8), calc_slot_mod (MOD (opll,8)));
+ if ( opll->pan[8] == 127 )
+ {
+ l += channel;
+ r += channel;
+ }
+ else
+ {
+ l += channel * (255-opll->pan[8]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
+ r += channel * ( opll->pan[8]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
+ }
+ }
+ }
+ else
+ {
+ if (!(opll->mask & OPLL_MASK_TOM) && (MOD (opll,8)->eg_mode != FINISH))
+ {
+ channel = calc_slot_tom (MOD (opll,8));
+ if ( opll->pan[12] == 127 )
+ {
+ l += channel;
+ r += channel;
+ }
+ else
+ {
+ l += channel * (255-opll->pan[12]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
+ r += channel * ( opll->pan[12]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
+ }
+ }
+ if (!(opll->mask & OPLL_MASK_CYM) && (CAR (opll,8)->eg_mode != FINISH))
+ {
+ channel = -calc_slot_cym (CAR (opll,8), MOD(opll,7)->pgout); // negated
+ if ( opll->pan[13] == 127 )
+ {
+ l += channel;
+ r += channel;
+ }
+ else
+ {
+ l += channel * (255-opll->pan[13]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
+ r += channel * ( opll->pan[13]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
+ }
+ }
+ }
+/*
+ out[1] = (b[1] + b[3] + ((r[1] + r[3]) << 1)) <<3;
+ out[0] = (b[2] + b[3] + ((r[2] + r[3]) << 1)) <<3;
+ */
+ out[0] = l << 3;
+ out[1] = r << 3;
+}
+
+void
+OPLL_calc_stereo (OPLL * opll, e_int32 out[2])
+{
+ if (!opll->quality)
+ {
+ calc_stereo (opll, out);
+ return;
+ }
+
+ while (opll->realstep > opll->oplltime)
+ {
+ opll->oplltime += opll->opllstep;
+ opll->sprev[0] = opll->snext[0];
+ opll->sprev[1] = opll->snext[1];
+ calc_stereo (opll, opll->snext);
+ }
+
+ opll->oplltime -= opll->realstep;
+ out[0] = (e_int16) (((double) opll->snext[0] * (opll->opllstep - opll->oplltime)
+ + (double) opll->sprev[0] * opll->oplltime) / opll->opllstep);
+ out[1] = (e_int16) (((double) opll->snext[1] * (opll->opllstep - opll->oplltime)
+ + (double) opll->sprev[1] * opll->oplltime) / opll->opllstep);
+}
+#endif /* EMU2413_COMPACTION */
+
+// Ym2413_Emu
+#include "Ym2413_Emu.h"
+
+#include <assert.h>
+
+static int use_count = 0;
+
+Ym2413_Emu::~Ym2413_Emu()
+{
+ if ( opll )
+ {
+ use_count--;
+ OPLL_delete( opll );
+ }
+}
+
+Ym2413_Emu::Ym2413_Emu()
+{
+ opll = 0;
+}
+
+int Ym2413_Emu::set_rate( double sample_rate, double clock_rate )
+{
+ if ( opll )
+ {
+ OPLL_delete( opll );
+ opll = 0;
+ use_count--;
+ }
+
+ // Only one YM2413 may be used at a time (emu2413 uses lots of global data)
+ assert( use_count == 0 );
+ use_count++;
+
+ opll = OPLL_new ((int) clock_rate, (int) sample_rate);
+ if ( !opll )
+ return 1;
+
+ reset();
+ return 0;
+}
+
+void Ym2413_Emu::reset()
+{
+ OPLL_reset( opll );
+ OPLL_reset_patch( opll, 0 );
+ OPLL_setMask( opll, 0 );
+ OPLL_set_quality( opll, 0 );
+}
+
+void Ym2413_Emu::write( int addr, int data )
+{
+ OPLL_writeReg( opll, addr, data );
+}
+
+void Ym2413_Emu::mute_voices( int mask )
+{
+ OPLL_setMask( opll, mask );
+}
+
+void Ym2413_Emu::run( int pair_count, sample_t* out )
+{
+ while ( pair_count-- )
+ {
+ int s = OPLL_calc( opll );
+ out [0] = s;
+ out [1] = s;
+ out += 2;
+ }
+}
+
diff --git a/src/console/Ym2413_Emu.cxx b/src/console/Ym2413_Emu.cxx
deleted file mode 100644
index 9d8595922453..000000000000
--- a/src/console/Ym2413_Emu.cxx
+++ /dev/null
@@ -1,2224 +0,0 @@
-
-// Game_Music_Emu 0.3.0. http://www.slack.net/~ant/
-
-/***********************************************************************************
-
- emu2413.c -- YM2413 emulator written by Mitsutaka Okazaki 2001
-
- 2001 01-08 : Version 0.10 -- 1st version.
- 2001 01-15 : Version 0.20 -- semi-public version.
- 2001 01-16 : Version 0.30 -- 1st public version.
- 2001 01-17 : Version 0.31 -- Fixed bassdrum problem.
- : Version 0.32 -- LPF implemented.
- 2001 01-18 : Version 0.33 -- Fixed the drum problem, refine the mix-down method.
- -- Fixed the LFO bug.
- 2001 01-24 : Version 0.35 -- Fixed the drum problem,
- support undocumented EG behavior.
- 2001 02-02 : Version 0.38 -- Improved the performance.
- Fixed the hi-hat and cymbal model.
- Fixed the default percussive datas.
- Noise reduction.
- Fixed the feedback problem.
- 2001 03-03 : Version 0.39 -- Fixed some drum bugs.
- Improved the performance.
- 2001 03-04 : Version 0.40 -- Improved the feedback.
- Change the default table size.
- Clock and Rate can be changed during play.
- 2001 06-24 : Version 0.50 -- Improved the hi-hat and the cymbal tone.
- Added VRC7 patch (OPLL_reset_patch is changed).
- Fixed OPLL_reset() bug.
- Added OPLL_setMask, OPLL_getMask and OPLL_toggleMask.
- Added OPLL_writeIO.
- 2001 09-28 : Version 0.51 -- Removed the noise table.
- 2002 01-28 : Version 0.52 -- Added Stereo mode.
- 2002 02-07 : Version 0.53 -- Fixed some drum bugs.
- 2002 02-20 : Version 0.54 -- Added the best quality mode.
- 2002 03-02 : Version 0.55 -- Removed OPLL_init & OPLL_close.
- 2002 05-30 : Version 0.60 -- Fixed HH&CYM generator and all voice datas.
- 2004 04-10 : Version 0.61 -- Added YMF281B tone (defined by Chabin).
-
- References:
- fmopl.c -- 1999,2000 written by Tatsuyuki Satoh (MAME development).
- fmopl.c(fixed) -- (C) 2002 Jarek Burczynski.
- s_opl.c -- 2001 written by Mamiya (NEZplug development).
- fmgen.cpp -- 1999,2000 written by cisc.
- fmpac.ill -- 2000 created by NARUTO.
- MSX-Datapack
- YMU757 data sheet
- YM2143 data sheet
-
-**************************************************************************************/
-
-
-#ifndef _EMU2413_H_
-#define _EMU2413_H_
-
-typedef signed char e_int8;
-typedef unsigned char e_uint8;
-typedef signed short e_int16;
-typedef unsigned short e_uint16;
-typedef signed long e_int32;
-typedef unsigned long e_uint32;
-
-#ifdef EMU2413_DLL_EXPORTS
- #define EMU2413_API __declspec(dllexport)
-#elif defined(EMU2413_DLL_IMPORTS)
- #define EMU2413_API __declspec(dllimport)
-#else
- #define EMU2413_API
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PI 3.14159265358979323846
-
-enum OPLL_TONE_ENUM {OPLL_2413_TONE=0, OPLL_VRC7_TONE=1, OPLL_281B_TONE=2} ;
-
-/* voice data */
-typedef struct __OPLL_PATCH {
- e_uint32 TL,FB,EG,ML,AR,DR,SL,RR,KR,KL,AM,PM,WF ;
-} OPLL_PATCH ;
-
-/* slot */
-typedef struct __OPLL_SLOT {
-
- OPLL_PATCH *patch;
-
- e_int32 type ; /* 0 : modulator 1 : carrier */
-
- /* OUTPUT */
- e_int32 feedback ;
- e_int32 output[2] ; /* Output value of slot */
-
- /* for Phase Generator (PG) */
- e_uint16 *sintbl ; /* Wavetable */
- e_uint32 phase ; /* Phase */
- e_uint32 dphase ; /* Phase increment amount */
- e_uint32 pgout ; /* output */
-
- /* for Envelope Generator (EG) */
- e_int32 fnum ; /* F-Number */
- e_int32 block ; /* Block */
- e_int32 volume ; /* Current volume */
- e_int32 sustine ; /* Sustine 1 = ON, 0 = OFF */
- e_uint32 tll ; /* Total Level + Key scale level*/
- e_uint32 rks ; /* Key scale offset (Rks) */
- e_int32 eg_mode ; /* Current state */
- e_uint32 eg_phase ; /* Phase */
- e_uint32 eg_dphase ; /* Phase increment amount */
- e_uint32 egout ; /* output */
-
-} OPLL_SLOT ;
-
-/* Mask */
-#define OPLL_MASK_CH(x) (1<<(x))
-#define OPLL_MASK_HH (1<<(9))
-#define OPLL_MASK_CYM (1<<(10))
-#define OPLL_MASK_TOM (1<<(11))
-#define OPLL_MASK_SD (1<<(12))
-#define OPLL_MASK_BD (1<<(13))
-#define OPLL_MASK_RHYTHM ( OPLL_MASK_HH | OPLL_MASK_CYM | OPLL_MASK_TOM | OPLL_MASK_SD | OPLL_MASK_BD )
-
-/* opll */
-typedef struct OPLL {
-
- e_uint32 adr ;
- e_int32 out ;
-
-#ifndef EMU2413_COMPACTION
- e_uint32 realstep ;
- e_uint32 oplltime ;
- e_uint32 opllstep ;
- e_int32 prev, next ;
- e_int32 sprev[2],snext[2];
- e_int32 pan[16];
-#endif
-
- /* Register */
- e_uint8 reg[0x40] ;
- e_int32 slot_on_flag[18] ;
-
- /* Pitch Modulator */
- e_uint32 pm_phase ;
- e_int32 lfo_pm ;
-
- /* Amp Modulator */
- e_int32 am_phase ;
- e_int32 lfo_am ;
-
- e_uint32 quality;
-
- /* Noise Generator */
- e_uint32 noise_seed ;
-
- /* Channel Data */
- e_int32 patch_number[9];
- e_int32 key_status[9] ;
-
- /* Slot */
- OPLL_SLOT slot[18] ;
-
- /* Voice Data */
- OPLL_PATCH patch[19*2] ;
- e_int32 patch_update[2] ; /* flag for check patch update */
-
- e_uint32 mask ;
-
-} OPLL ;
-
-/* Create Object */
-EMU2413_API OPLL *OPLL_new(e_uint32 clk, e_uint32 rate) ;
-EMU2413_API void OPLL_delete(OPLL *) ;
-
-/* Setup */
-EMU2413_API void OPLL_reset(OPLL *) ;
-EMU2413_API void OPLL_reset_patch(OPLL *, e_int32) ;
-EMU2413_API void OPLL_set_rate(OPLL *opll, e_uint32 r) ;
-EMU2413_API void OPLL_set_quality(OPLL *opll, e_uint32 q) ;
-EMU2413_API void OPLL_set_pan(OPLL *, e_uint32 ch, e_uint32 pan);
-
-/* Port/Register access */
-EMU2413_API void OPLL_writeIO(OPLL *, e_uint32 reg, e_uint32 val) ;
-EMU2413_API void OPLL_writeReg(OPLL *, e_uint32 reg, e_uint32 val) ;
-
-/* Synthsize */
-EMU2413_API e_int16 OPLL_calc(OPLL *) ;
-EMU2413_API void OPLL_calc_stereo(OPLL *, e_int32 out[2]) ;
-
-/* Misc */
-EMU2413_API void OPLL_setPatch(OPLL *, const e_uint8 *dump) ;
-EMU2413_API void OPLL_copyPatch(OPLL *, e_int32, OPLL_PATCH *) ;
-EMU2413_API void OPLL_forceRefresh(OPLL *) ;
-/* Utility */
-EMU2413_API void OPLL_dump2patch(const e_uint8 *dump, OPLL_PATCH *patch) ;
-EMU2413_API void OPLL_patch2dump(const OPLL_PATCH *patch, e_uint8 *dump) ;
-EMU2413_API void OPLL_getDefaultPatch(e_int32 type, e_int32 num, OPLL_PATCH *) ;
-
-/* Channel Mask */
-EMU2413_API e_uint32 OPLL_setMask(OPLL *, e_uint32 mask) ;
-EMU2413_API e_uint32 OPLL_toggleMask(OPLL *, e_uint32 mask) ;
-
-#define dump2patch OPLL_dump2patch
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#define EMU2413_COMPACTION
-#define INLINE inline
-
-#ifdef EMU2413_COMPACTION
-#define OPLL_TONE_NUM 1
-static unsigned char default_inst[OPLL_TONE_NUM][(16 + 3) * 16] = {
- {
-/* YM2413 tone by okazaki at angel.ne.jp */
-0x49,0x4c,0x4c,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x61,0x61,0x1e,0x17,0xf0,0x7f,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x13,0x41,0x16,0x0e,0xfd,0xf4,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x03,0x01,0x9a,0x04,0xf3,0xf3,0x13,0xf3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x11,0x61,0x0e,0x07,0xfa,0x64,0x70,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x22,0x21,0x1e,0x06,0xf0,0x76,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x21,0x22,0x16,0x05,0xf0,0x71,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x21,0x61,0x1d,0x07,0x82,0x80,0x17,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x23,0x21,0x2d,0x16,0x90,0x90,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x21,0x21,0x1b,0x06,0x64,0x65,0x10,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x21,0x21,0x0b,0x1a,0x85,0xa0,0x70,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x23,0x01,0x83,0x10,0xff,0xb4,0x10,0xf4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x97,0xc1,0x20,0x07,0xff,0xf4,0x22,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x61,0x00,0x0c,0x05,0xc2,0xf6,0x40,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x01,0x01,0x56,0x03,0x94,0xc2,0x03,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x21,0x01,0x89,0x03,0xf1,0xe4,0xf0,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- }
-};
-#else
-#define OPLL_TONE_NUM 3
-static unsigned char default_inst[OPLL_TONE_NUM][(16 + 3) * 16] = {
- {
-#include "2413tone.h"
- },
- {
-#include "vrc7tone.h"
- },
- {
-#include "281btone.h"
- }
-};
-#endif
-
-/* Size of Sintable ( 8 -- 18 can be used. 9 recommended.) */
-#define PG_BITS 9
-#define PG_WIDTH (1<<PG_BITS)
-
-/* Phase increment counter */
-#define DP_BITS 18
-#define DP_WIDTH (1<<DP_BITS)
-#define DP_BASE_BITS (DP_BITS - PG_BITS)
-
-/* Dynamic range (Accuracy of sin table) */
-#define DB_BITS 8
-#define DB_STEP (48.0/(1<<DB_BITS))
-#define DB_MUTE (1<<DB_BITS)
-
-/* Dynamic range of envelope */
-#define EG_STEP 0.375
-#define EG_BITS 7
-#define EG_MUTE (1<<EG_BITS)
-
-/* Dynamic range of total level */
-#define TL_STEP 0.75
-#define TL_BITS 6
-#define TL_MUTE (1<<TL_BITS)
-
-/* Dynamic range of sustine level */
-#define SL_STEP 3.0
-#define SL_BITS 4
-#define SL_MUTE (1<<SL_BITS)
-
-#define EG2DB(d) ((d)*(e_int32)(EG_STEP/DB_STEP))
-#define TL2EG(d) ((d)*(e_int32)(TL_STEP/EG_STEP))
-#define SL2EG(d) ((d)*(e_int32)(SL_STEP/EG_STEP))
-
-#define DB_POS(x) (e_uint32)((x)/DB_STEP)
-#define DB_NEG(x) (e_uint32)(DB_MUTE+DB_MUTE+(x)/DB_STEP)
-
-/* Bits for liner value */
-#define DB2LIN_AMP_BITS 8
-#define SLOT_AMP_BITS (DB2LIN_AMP_BITS)
-
-/* Bits for envelope phase incremental counter */
-#define EG_DP_BITS 22
-#define EG_DP_WIDTH (1<<EG_DP_BITS)
-
-/* Bits for Pitch and Amp modulator */
-#define PM_PG_BITS 8
-#define PM_PG_WIDTH (1<<PM_PG_BITS)
-#define PM_DP_BITS 16
-#define PM_DP_WIDTH (1<<PM_DP_BITS)
-#define AM_PG_BITS 8
-#define AM_PG_WIDTH (1<<AM_PG_BITS)
-#define AM_DP_BITS 16
-#define AM_DP_WIDTH (1<<AM_DP_BITS)
-
-/* PM table is calcurated by PM_AMP * pow(2,PM_DEPTH*sin(x)/1200) */
-#define PM_AMP_BITS 8
-#define PM_AMP (1<<PM_AMP_BITS)
-
-/* PM speed(Hz) and depth(cent) */
-#define PM_SPEED 6.4
-#define PM_DEPTH 13.75
-
-/* AM speed(Hz) and depth(dB) */
-#define AM_SPEED 3.6413
-#define AM_DEPTH 4.875
-
-/* Cut the lower b bit(s) off. */
-#define HIGHBITS(c,b) ((c)>>(b))
-
-/* Leave the lower b bit(s). */
-#define LOWBITS(c,b) ((c)&((1<<(b))-1))
-
-/* Expand x which is s bits to d bits. */
-#define EXPAND_BITS(x,s,d) ((x)<<((d)-(s)))
-
-/* Expand x which is s bits to d bits and fill expanded bits '1' */
-#define EXPAND_BITS_X(x,s,d) (((x)<<((d)-(s)))|((1<<((d)-(s)))-1))
-
-/* Adjust envelope speed which depends on sampling rate. */
-#define RATE_ADJUST(x) (rate==49716?x:(e_uint32)((double)(x)*clk/72/rate + 0.5)) /* added 0.5 to round the value*/
-
-#define MOD(o,x) (&(o)->slot[(x)<<1])
-#define CAR(o,x) (&(o)->slot[((x)<<1)|1])
-
-#define BIT(s,b) (((s)>>(b))&1)
-
-/* Input clock */
-static e_uint32 clk = 844451141;
-/* Sampling rate */
-static e_uint32 rate = 3354932;
-
-/* WaveTable for each envelope amp */
-static e_uint16 fullsintable[PG_WIDTH];
-static e_uint16 halfsintable[PG_WIDTH];
-
-static e_uint16 *waveform[2] = { fullsintable, halfsintable };
-
-/* LFO Table */
-static e_int32 pmtable[PM_PG_WIDTH];
-static e_int32 amtable[AM_PG_WIDTH];
-
-/* Phase delta for LFO */
-static e_uint32 pm_dphase;
-static e_uint32 am_dphase;
-
-/* dB to Liner table */
-static e_int16 DB2LIN_TABLE[(DB_MUTE + DB_MUTE) * 2];
-
-/* Liner to Log curve conversion table (for Attack rate). */
-static e_uint16 AR_ADJUST_TABLE[1 << EG_BITS];
-
-/* Empty voice data */
-static OPLL_PATCH null_patch = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-/* Basic voice Data */
-static OPLL_PATCH default_patch[OPLL_TONE_NUM][(16 + 3) * 2];
-
-/* Definition of envelope mode */
-enum OPLL_EG_STATE
-{ READY, ATTACK, DECAY, SUSHOLD, SUSTINE, RELEASE, SETTLE, FINISH };
-
-/* Phase incr table for Attack */
-static e_uint32 dphaseARTable[16][16];
-/* Phase incr table for Decay and Release */
-static e_uint32 dphaseDRTable[16][16];
-
-/* KSL + TL Table */
-static e_uint32 tllTable[16][8][1 << TL_BITS][4];
-static e_int32 rksTable[2][8][2];
-
-/* Phase incr table for PG */
-static e_uint32 dphaseTable[512][8][16];
-
-/***************************************************
-
- Create tables
-
-****************************************************/
-INLINE static e_int32
-Min (e_int32 i, e_int32 j)
-{
- if (i < j)
- return i;
- else
- return j;
-}
-
-/* Table for AR to LogCurve. */
-static void
-makeAdjustTable (void)
-{
- e_int32 i;
-
- AR_ADJUST_TABLE[0] = (1 << EG_BITS) - 1;
- for (i = 1; i < (1<<EG_BITS); i++)
- AR_ADJUST_TABLE[i] = (e_uint16) ((double) (1<<EG_BITS)-1 - ((1<<EG_BITS)-1)*log(i)/log(127));
-}
-
-
-/* Table for dB(0 -- (1<<DB_BITS)-1) to Liner(0 -- DB2LIN_AMP_WIDTH) */
-static void
-makeDB2LinTable (void)
-{
- e_int32 i;
-
- for (i = 0; i < DB_MUTE + DB_MUTE; i++)
- {
- DB2LIN_TABLE[i] = (e_int16) ((double) ((1 << DB2LIN_AMP_BITS) - 1) * pow (10, -(double) i * DB_STEP / 20));
- if (i >= DB_MUTE) DB2LIN_TABLE[i] = 0;
- DB2LIN_TABLE[i + DB_MUTE + DB_MUTE] = (e_int16) (-DB2LIN_TABLE[i]);
- }
-}
-
-/* Liner(+0.0 - +1.0) to dB((1<<DB_BITS) - 1 -- 0) */
-static e_int32
-lin2db (double d)
-{
- if (d == 0)
- return (DB_MUTE - 1);
- else
- return Min (-(e_int32) (20.0 * log10 (d) / DB_STEP), DB_MUTE-1); /* 0 -- 127 */
-}
-
-
-/* Sin Table */
-static void
-makeSinTable (void)
-{
- e_int32 i;
-
- for (i = 0; i < PG_WIDTH / 4; i++)
- {
- fullsintable[i] = (e_uint32) lin2db (sin (2.0 * PI * i / PG_WIDTH) );
- }
-
- for (i = 0; i < PG_WIDTH / 4; i++)
- {
- fullsintable[PG_WIDTH / 2 - 1 - i] = fullsintable[i];
- }
-
- for (i = 0; i < PG_WIDTH / 2; i++)
- {
- fullsintable[PG_WIDTH / 2 + i] = (e_uint32) (DB_MUTE + DB_MUTE + fullsintable[i]);
- }
-
- for (i = 0; i < PG_WIDTH / 2; i++)
- halfsintable[i] = fullsintable[i];
- for (i = PG_WIDTH / 2; i < PG_WIDTH; i++)
- halfsintable[i] = fullsintable[0];
-}
-
-static double saw(double phase)
-{
- if(phase <= PI/2)
- return phase * 2 / PI ;
- else if(phase <= PI*3/2)
- return 2.0 - ( phase * 2 / PI );
- else
- return -4.0 + phase * 2 / PI;
-}
-
-/* Table for Pitch Modulator */
-static void
-makePmTable (void)
-{
- e_int32 i;
-
- for (i = 0; i < PM_PG_WIDTH; i++)
- /* pmtable[i] = (e_int32) ((double) PM_AMP * pow (2, (double) PM_DEPTH * sin (2.0 * PI * i / PM_PG_WIDTH) / 1200)); */
- pmtable[i] = (e_int32) ((double) PM_AMP * pow (2, (double) PM_DEPTH * saw (2.0 * PI * i / PM_PG_WIDTH) / 1200));
-}
-
-/* Table for Amp Modulator */
-static void
-makeAmTable (void)
-{
- e_int32 i;
-
- for (i = 0; i < AM_PG_WIDTH; i++)
- /* amtable[i] = (e_int32) ((double) AM_DEPTH / 2 / DB_STEP * (1.0 + sin (2.0 * PI * i / PM_PG_WIDTH))); */
- amtable[i] = (e_int32) ((double) AM_DEPTH / 2 / DB_STEP * (1.0 + saw (2.0 * PI * i / PM_PG_WIDTH)));
-}
-
-/* Phase increment counter table */
-static void
-makeDphaseTable (void)
-{
- e_uint32 fnum, block, ML;
- e_uint32 mltable[16] =
- { 1, 1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2, 6 * 2, 7 * 2, 8 * 2, 9 * 2, 10 * 2, 10 * 2, 12 * 2, 12 * 2, 15 * 2, 15 * 2 };
-
- for (fnum = 0; fnum < 512; fnum++)
- for (block = 0; block < 8; block++)
- for (ML = 0; ML < 16; ML++)
- dphaseTable[fnum][block][ML] = RATE_ADJUST (((fnum * mltable[ML]) << block) >> (20 - DP_BITS));
-}
-
-static void
-makeTllTable (void)
-{
-#define dB2(x) ((x)*2)
-
- static double kltable[16] = {
- dB2 (0.000), dB2 (9.000), dB2 (12.000), dB2 (13.875), dB2 (15.000), dB2 (16.125), dB2 (16.875), dB2 (17.625),
- dB2 (18.000), dB2 (18.750), dB2 (19.125), dB2 (19.500), dB2 (19.875), dB2 (20.250), dB2 (20.625), dB2 (21.000)
- };
-
- e_int32 tmp;
- e_int32 fnum, block, TL, KL;
-
- for (fnum = 0; fnum < 16; fnum++)
- for (block = 0; block < 8; block++)
- for (TL = 0; TL < 64; TL++)
- for (KL = 0; KL < 4; KL++)
- {
- if (KL == 0)
- {
- tllTable[fnum][block][TL][KL] = TL2EG (TL);
- }
- else
- {
- tmp = (e_int32) (kltable[fnum] - dB2 (3.000) * (7 - block));
- if (tmp <= 0)
- tllTable[fnum][block][TL][KL] = TL2EG (TL);
- else
- tllTable[fnum][block][TL][KL] = (e_uint32) ((tmp >> (3 - KL)) / EG_STEP) + TL2EG (TL);
- }
- }
-}
-
-#ifdef USE_SPEC_ENV_SPEED
-static double attacktime[16][4] = {
- {0, 0, 0, 0},
- {1730.15, 1400.60, 1153.43, 988.66},
- {865.08, 700.30, 576.72, 494.33},
- {432.54, 350.15, 288.36, 247.16},
- {216.27, 175.07, 144.18, 123.58},
- {108.13, 87.54, 72.09, 61.79},
- {54.07, 43.77, 36.04, 30.90},
- {27.03, 21.88, 18.02, 15.45},
- {13.52, 10.94, 9.01, 7.72},
- {6.76, 5.47, 4.51, 3.86},
- {3.38, 2.74, 2.25, 1.93},
- {1.69, 1.37, 1.13, 0.97},
- {0.84, 0.70, 0.60, 0.54},
- {0.50, 0.42, 0.34, 0.30},
- {0.28, 0.22, 0.18, 0.14},
- {0.00, 0.00, 0.00, 0.00}
-};
-
-static double decaytime[16][4] = {
- {0, 0, 0, 0},
- {20926.60, 16807.20, 14006.00, 12028.60},
- {10463.30, 8403.58, 7002.98, 6014.32},
- {5231.64, 4201.79, 3501.49, 3007.16},
- {2615.82, 2100.89, 1750.75, 1503.58},
- {1307.91, 1050.45, 875.37, 751.79},
- {653.95, 525.22, 437.69, 375.90},
- {326.98, 262.61, 218.84, 187.95},
- {163.49, 131.31, 109.42, 93.97},
- {81.74, 65.65, 54.71, 46.99},
- {40.87, 32.83, 27.36, 23.49},
- {20.44, 16.41, 13.68, 11.75},
- {10.22, 8.21, 6.84, 5.87},
- {5.11, 4.10, 3.42, 2.94},
- {2.55, 2.05, 1.71, 1.47},
- {1.27, 1.27, 1.27, 1.27}
-};
-#endif
-
-/* Rate Table for Attack */
-static void
-makeDphaseARTable (void)
-{
- e_int32 AR, Rks, RM, RL;
-
-#ifdef USE_SPEC_ENV_SPEED
- e_uint32 attacktable[16][4];
-
- for (RM = 0; RM < 16; RM++)
- for (RL = 0; RL < 4; RL++)
- {
- if (RM == 0)
- attacktable[RM][RL] = 0;
- else if (RM == 15)
- attacktable[RM][RL] = EG_DP_WIDTH;
- else
- attacktable[RM][RL] = (e_uint32) ((double) (1 << EG_DP_BITS) / (attacktime[RM][RL] * 3579545 / 72000));
-
- }
-#endif
-
- for (AR = 0; AR < 16; AR++)
- for (Rks = 0; Rks < 16; Rks++)
- {
- RM = AR + (Rks >> 2);
- RL = Rks & 3;
- if (RM > 15)
- RM = 15;
- switch (AR)
- {
- case 0:
- dphaseARTable[AR][Rks] = 0;
- break;
- case 15:
- dphaseARTable[AR][Rks] = 0;/*EG_DP_WIDTH;*/
- break;
- default:
-#ifdef USE_SPEC_ENV_SPEED
- dphaseARTable[AR][Rks] = RATE_ADJUST (attacktable[RM][RL]);
-#else
- dphaseARTable[AR][Rks] = RATE_ADJUST ((3 * (RL + 4) << (RM + 1)));
-#endif
- break;
- }
- }
-}
-
-/* Rate Table for Decay and Release */
-static void
-makeDphaseDRTable (void)
-{
- e_int32 DR, Rks, RM, RL;
-
-#ifdef USE_SPEC_ENV_SPEED
- e_uint32 decaytable[16][4];
-
- for (RM = 0; RM < 16; RM++)
- for (RL = 0; RL < 4; RL++)
- if (RM == 0)
- decaytable[RM][RL] = 0;
- else
- decaytable[RM][RL] = (e_uint32) ((double) (1 << EG_DP_BITS) / (decaytime[RM][RL] * 3579545 / 72000));
-#endif
-
- for (DR = 0; DR < 16; DR++)
- for (Rks = 0; Rks < 16; Rks++)
- {
- RM = DR + (Rks >> 2);
- RL = Rks & 3;
- if (RM > 15)
- RM = 15;
- switch (DR)
- {
- case 0:
- dphaseDRTable[DR][Rks] = 0;
- break;
- default:
-#ifdef USE_SPEC_ENV_SPEED
- dphaseDRTable[DR][Rks] = RATE_ADJUST (decaytable[RM][RL]);
-#else
- dphaseDRTable[DR][Rks] = RATE_ADJUST ((RL + 4) << (RM - 1));
-#endif
- break;
- }
- }
-}
-
-static void
-makeRksTable (void)
-{
-
- e_int32 fnum8, block, KR;
-
- for (fnum8 = 0; fnum8 < 2; fnum8++)
- for (block = 0; block < 8; block++)
- for (KR = 0; KR < 2; KR++)
- {
- if (KR != 0)
- rksTable[fnum8][block][KR] = (block << 1) + fnum8;
- else
- rksTable[fnum8][block][KR] = block >> 1;
- }
-}
-
-void
-OPLL_dump2patch (const e_uint8 * dump, OPLL_PATCH * patch)
-{
- patch[0].AM = (dump[0] >> 7) & 1;
- patch[1].AM = (dump[1] >> 7) & 1;
- patch[0].PM = (dump[0] >> 6) & 1;
- patch[1].PM = (dump[1] >> 6) & 1;
- patch[0].EG = (dump[0] >> 5) & 1;
- patch[1].EG = (dump[1] >> 5) & 1;
- patch[0].KR = (dump[0] >> 4) & 1;
- patch[1].KR = (dump[1] >> 4) & 1;
- patch[0].ML = (dump[0]) & 15;
- patch[1].ML = (dump[1]) & 15;
- patch[0].KL = (dump[2] >> 6) & 3;
- patch[1].KL = (dump[3] >> 6) & 3;
- patch[0].TL = (dump[2]) & 63;
- patch[0].FB = (dump[3]) & 7;
- patch[0].WF = (dump[3] >> 3) & 1;
- patch[1].WF = (dump[3] >> 4) & 1;
- patch[0].AR = (dump[4] >> 4) & 15;
- patch[1].AR = (dump[5] >> 4) & 15;
- patch[0].DR = (dump[4]) & 15;
- patch[1].DR = (dump[5]) & 15;
- patch[0].SL = (dump[6] >> 4) & 15;
- patch[1].SL = (dump[7] >> 4) & 15;
- patch[0].RR = (dump[6]) & 15;
- patch[1].RR = (dump[7]) & 15;
-}
-
-void
-OPLL_getDefaultPatch (e_int32 type, e_int32 num, OPLL_PATCH * patch)
-{
- OPLL_dump2patch (default_inst[type] + num * 16, patch);
-}
-
-static void
-makeDefaultPatch ()
-{
- e_int32 i, j;
-
- for (i = 0; i < OPLL_TONE_NUM; i++)
- for (j = 0; j < 19; j++)
- OPLL_getDefaultPatch (i, j, &default_patch[i][j * 2]);
-
-}
-
-void
-OPLL_setPatch (OPLL * opll, const e_uint8 * dump)
-{
- OPLL_PATCH patch[2];
- int i;
-
- for (i = 0; i < 19; i++)
- {
- OPLL_dump2patch (dump + i * 16, patch);
- memcpy (&opll->patch[i*2+0], &patch[0], sizeof (OPLL_PATCH));
- memcpy (&opll->patch[i*2+1], &patch[1], sizeof (OPLL_PATCH));
- }
-}
-
-void
-OPLL_patch2dump (const OPLL_PATCH * patch, e_uint8 * dump)
-{
- dump[0] = (e_uint8) ((patch[0].AM << 7) + (patch[0].PM << 6) + (patch[0].EG << 5) + (patch[0].KR << 4) + patch[0].ML);
- dump[1] = (e_uint8) ((patch[1].AM << 7) + (patch[1].PM << 6) + (patch[1].EG << 5) + (patch[1].KR << 4) + patch[1].ML);
- dump[2] = (e_uint8) ((patch[0].KL << 6) + patch[0].TL);
- dump[3] = (e_uint8) ((patch[1].KL << 6) + (patch[1].WF << 4) + (patch[0].WF << 3) + patch[0].FB);
- dump[4] = (e_uint8) ((patch[0].AR << 4) + patch[0].DR);
- dump[5] = (e_uint8) ((patch[1].AR << 4) + patch[1].DR);
- dump[6] = (e_uint8) ((patch[0].SL << 4) + patch[0].RR);
- dump[7] = (e_uint8) ((patch[1].SL << 4) + patch[1].RR);
- dump[8] = 0;
- dump[9] = 0;
- dump[10] = 0;
- dump[11] = 0;
- dump[12] = 0;
- dump[13] = 0;
- dump[14] = 0;
- dump[15] = 0;
-}
-
-/************************************************************
-
- Calc Parameters
-
-************************************************************/
-
-INLINE static e_uint32
-calc_eg_dphase (OPLL_SLOT * slot)
-{
-
- switch (slot->eg_mode)
- {
- case ATTACK:
- return dphaseARTable[slot->patch->AR][slot->rks];
-
- case DECAY:
- return dphaseDRTable[slot->patch->DR][slot->rks];
-
- case SUSHOLD:
- return 0;
-
- case SUSTINE:
- return dphaseDRTable[slot->patch->RR][slot->rks];
-
- case RELEASE:
- if (slot->sustine)
- return dphaseDRTable[5][slot->rks];
- else if (slot->patch->EG)
- return dphaseDRTable[slot->patch->RR][slot->rks];
- else
- return dphaseDRTable[7][slot->rks];
-
- case SETTLE:
- return dphaseDRTable[15][0];
-
- case FINISH:
- return 0;
-
- default:
- return 0;
- }
-}
-
-/*************************************************************
-
- OPLL internal interfaces
-
-*************************************************************/
-#define SLOT_BD1 12
-#define SLOT_BD2 13
-#define SLOT_HH 14
-#define SLOT_SD 15
-#define SLOT_TOM 16
-#define SLOT_CYM 17
-
-#define UPDATE_PG(S) (S)->dphase = dphaseTable[(S)->fnum][(S)->block][(S)->patch->ML]
-#define UPDATE_TLL(S)\
-(((S)->type==0)?\
-((S)->tll = tllTable[((S)->fnum)>>5][(S)->block][(S)->patch->TL][(S)->patch->KL]):\
-((S)->tll = tllTable[((S)->fnum)>>5][(S)->block][(S)->volume][(S)->patch->KL]))
-#define UPDATE_RKS(S) (S)->rks = rksTable[((S)->fnum)>>8][(S)->block][(S)->patch->KR]
-#define UPDATE_WF(S) (S)->sintbl = waveform[(S)->patch->WF]
-#define UPDATE_EG(S) (S)->eg_dphase = calc_eg_dphase(S)
-#define UPDATE_ALL(S)\
- UPDATE_PG(S);\
- UPDATE_TLL(S);\
- UPDATE_RKS(S);\
- UPDATE_WF(S); \
- UPDATE_EG(S) /* EG should be updated last. */
-
-
-/* Slot key on */
-INLINE static void
-slotOn (OPLL_SLOT * slot)
-{
- slot->eg_mode = ATTACK;
- slot->eg_phase = 0;
- slot->phase = 0;
- UPDATE_EG(slot);
-}
-
-/* Slot key on without reseting the phase */
-INLINE static void
-slotOn2 (OPLL_SLOT * slot)
-{
- slot->eg_mode = ATTACK;
- slot->eg_phase = 0;
- UPDATE_EG(slot);
-}
-
-/* Slot key off */
-INLINE static void
-slotOff (OPLL_SLOT * slot)
-{
- if (slot->eg_mode == ATTACK)
- slot->eg_phase = EXPAND_BITS (AR_ADJUST_TABLE[HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS)], EG_BITS, EG_DP_BITS);
- slot->eg_mode = RELEASE;
- UPDATE_EG(slot);
-}
-
-/* Channel key on */
-INLINE static void
-keyOn (OPLL * opll, e_int32 i)
-{
- if (!opll->slot_on_flag[i * 2])
- slotOn (MOD(opll,i));
- if (!opll->slot_on_flag[i * 2 + 1])
- slotOn (CAR(opll,i));
- opll->key_status[i] = 1;
-}
-
-/* Channel key off */
-INLINE static void
-keyOff (OPLL * opll, e_int32 i)
-{
- if (opll->slot_on_flag[i * 2 + 1])
- slotOff (CAR(opll,i));
- opll->key_status[i] = 0;
-}
-
-INLINE static void
-keyOn_BD (OPLL * opll)
-{
- keyOn (opll, 6);
-}
-INLINE static void
-keyOn_SD (OPLL * opll)
-{
- if (!opll->slot_on_flag[SLOT_SD])
- slotOn (CAR(opll,7));
-}
-INLINE static void
-keyOn_TOM (OPLL * opll)
-{
- if (!opll->slot_on_flag[SLOT_TOM])
- slotOn (MOD(opll,8));
-}
-INLINE static void
-keyOn_HH (OPLL * opll)
-{
- if (!opll->slot_on_flag[SLOT_HH])
- slotOn2 (MOD(opll,7));
-}
-INLINE static void
-keyOn_CYM (OPLL * opll)
-{
- if (!opll->slot_on_flag[SLOT_CYM])
- slotOn2 (CAR(opll,8));
-}
-
-/* Drum key off */
-INLINE static void
-keyOff_BD (OPLL * opll)
-{
- keyOff (opll, 6);
-}
-INLINE static void
-keyOff_SD (OPLL * opll)
-{
- if (opll->slot_on_flag[SLOT_SD])
- slotOff (CAR(opll,7));
-}
-INLINE static void
-keyOff_TOM (OPLL * opll)
-{
- if (opll->slot_on_flag[SLOT_TOM])
- slotOff (MOD(opll,8));
-}
-INLINE static void
-keyOff_HH (OPLL * opll)
-{
- if (opll->slot_on_flag[SLOT_HH])
- slotOff (MOD(opll,7));
-}
-INLINE static void
-keyOff_CYM (OPLL * opll)
-{
- if (opll->slot_on_flag[SLOT_CYM])
- slotOff (CAR(opll,8));
-}
-
-/* Change a voice */
-INLINE static void
-setPatch (OPLL * opll, e_int32 i, e_int32 num)
-{
- opll->patch_number[i] = num;
- MOD(opll,i)->patch = &opll->patch[num * 2 + 0];
- CAR(opll,i)->patch = &opll->patch[num * 2 + 1];
-}
-
-/* Change a rhythm voice */
-INLINE static void
-setSlotPatch (OPLL_SLOT * slot, OPLL_PATCH * patch)
-{
- slot->patch = patch;
-}
-
-/* Set sustine parameter */
-INLINE static void
-setSustine (OPLL * opll, e_int32 c, e_int32 sustine)
-{
- CAR(opll,c)->sustine = sustine;
- if (MOD(opll,c)->type)
- MOD(opll,c)->sustine = sustine;
-}
-
-/* Volume : 6bit ( Volume register << 2 ) */
-INLINE static void
-setVolume (OPLL * opll, e_int32 c, e_int32 volume)
-{
- CAR(opll,c)->volume = volume;
-}
-
-INLINE static void
-setSlotVolume (OPLL_SLOT * slot, e_int32 volume)
-{
- slot->volume = volume;
-}
-
-/* Set F-Number ( fnum : 9bit ) */
-INLINE static void
-setFnumber (OPLL * opll, e_int32 c, e_int32 fnum)
-{
- CAR(opll,c)->fnum = fnum;
- MOD(opll,c)->fnum = fnum;
-}
-
-/* Set Block data (block : 3bit ) */
-INLINE static void
-setBlock (OPLL * opll, e_int32 c, e_int32 block)
-{
- CAR(opll,c)->block = block;
- MOD(opll,c)->block = block;
-}
-
-/* Change Rhythm Mode */
-INLINE static void
-update_rhythm_mode (OPLL * opll)
-{
- if (opll->patch_number[6] & 0x10)
- {
- if (!(opll->slot_on_flag[SLOT_BD2] | (opll->reg[0x0e] & 32)))
- {
- opll->slot[SLOT_BD1].eg_mode = FINISH;
- opll->slot[SLOT_BD2].eg_mode = FINISH;
- setPatch (opll, 6, opll->reg[0x36] >> 4);
- }
- }
- else if (opll->reg[0x0e] & 32)
- {
- opll->patch_number[6] = 16;
- opll->slot[SLOT_BD1].eg_mode = FINISH;
- opll->slot[SLOT_BD2].eg_mode = FINISH;
- setSlotPatch (&opll->slot[SLOT_BD1], &opll->patch[16 * 2 + 0]);
- setSlotPatch (&opll->slot[SLOT_BD2], &opll->patch[16 * 2 + 1]);
- }
-
- if (opll->patch_number[7] & 0x10)
- {
- if (!((opll->slot_on_flag[SLOT_HH] && opll->slot_on_flag[SLOT_SD]) | (opll->reg[0x0e] & 32)))
- {
- opll->slot[SLOT_HH].type = 0;
- opll->slot[SLOT_HH].eg_mode = FINISH;
- opll->slot[SLOT_SD].eg_mode = FINISH;
- setPatch (opll, 7, opll->reg[0x37] >> 4);
- }
- }
- else if (opll->reg[0x0e] & 32)
- {
- opll->patch_number[7] = 17;
- opll->slot[SLOT_HH].type = 1;
- opll->slot[SLOT_HH].eg_mode = FINISH;
- opll->slot[SLOT_SD].eg_mode = FINISH;
- setSlotPatch (&opll->slot[SLOT_HH], &opll->patch[17 * 2 + 0]);
- setSlotPatch (&opll->slot[SLOT_SD], &opll->patch[17 * 2 + 1]);
- }
-
- if (opll->patch_number[8] & 0x10)
- {
- if (!((opll->slot_on_flag[SLOT_CYM] && opll->slot_on_flag[SLOT_TOM]) | (opll->reg[0x0e] & 32)))
- {
- opll->slot[SLOT_TOM].type = 0;
- opll->slot[SLOT_TOM].eg_mode = FINISH;
- opll->slot[SLOT_CYM].eg_mode = FINISH;
- setPatch (opll, 8, opll->reg[0x38] >> 4);
- }
- }
- else if (opll->reg[0x0e] & 32)
- {
- opll->patch_number[8] = 18;
- opll->slot[SLOT_TOM].type = 1;
- opll->slot[SLOT_TOM].eg_mode = FINISH;
- opll->slot[SLOT_CYM].eg_mode = FINISH;
- setSlotPatch (&opll->slot[SLOT_TOM], &opll->patch[18 * 2 + 0]);
- setSlotPatch (&opll->slot[SLOT_CYM], &opll->patch[18 * 2 + 1]);
- }
-}
-
-INLINE static void
-update_key_status (OPLL * opll)
-{
- int ch;
-
- for (ch = 0; ch < 9; ch++)
- opll->slot_on_flag[ch * 2] = opll->slot_on_flag[ch * 2 + 1] = (opll->reg[0x20 + ch]) & 0x10;
-
- if (opll->reg[0x0e] & 32)
- {
- opll->slot_on_flag[SLOT_BD1] |= (opll->reg[0x0e] & 0x10);
- opll->slot_on_flag[SLOT_BD2] |= (opll->reg[0x0e] & 0x10);
- opll->slot_on_flag[SLOT_SD] |= (opll->reg[0x0e] & 0x08);
- opll->slot_on_flag[SLOT_HH] |= (opll->reg[0x0e] & 0x01);
- opll->slot_on_flag[SLOT_TOM] |= (opll->reg[0x0e] & 0x04);
- opll->slot_on_flag[SLOT_CYM] |= (opll->reg[0x0e] & 0x02);
- }
-}
-
-void
-OPLL_copyPatch (OPLL * opll, e_int32 num, OPLL_PATCH * patch)
-{
- memcpy (&opll->patch[num], patch, sizeof (OPLL_PATCH));
-}
-
-/***********************************************************
-
- Initializing
-
-***********************************************************/
-
-static void
-OPLL_SLOT_reset (OPLL_SLOT * slot, int type)
-{
- slot->type = type;
- slot->sintbl = waveform[0];
- slot->phase = 0;
- slot->dphase = 0;
- slot->output[0] = 0;
- slot->output[1] = 0;
- slot->feedback = 0;
- slot->eg_mode = FINISH;
- slot->eg_phase = EG_DP_WIDTH;
- slot->eg_dphase = 0;
- slot->rks = 0;
- slot->tll = 0;
- slot->sustine = 0;
- slot->fnum = 0;
- slot->block = 0;
- slot->volume = 0;
- slot->pgout = 0;
- slot->egout = 0;
- slot->patch = &null_patch;
-}
-
-static void
-internal_refresh (void)
-{
- makeDphaseTable ();
- makeDphaseARTable ();
- makeDphaseDRTable ();
- pm_dphase = (e_uint32) RATE_ADJUST (PM_SPEED * PM_DP_WIDTH / (clk / 72));
- am_dphase = (e_uint32) RATE_ADJUST (AM_SPEED * AM_DP_WIDTH / (clk / 72));
-}
-
-static void
-maketables (e_uint32 c, e_uint32 r)
-{
- if (c != clk)
- {
- clk = c;
- makePmTable ();
- makeAmTable ();
- makeDB2LinTable ();
- makeAdjustTable ();
- makeTllTable ();
- makeRksTable ();
- makeSinTable ();
- makeDefaultPatch ();
- }
-
- if (r != rate)
- {
- rate = r;
- internal_refresh ();
- }
-}
-
-OPLL *
-OPLL_new (e_uint32 clk, e_uint32 rate)
-{
- OPLL *opll;
- e_int32 i;
-
- maketables (clk, rate);
-
- opll = (OPLL *) calloc (sizeof (OPLL), 1);
- if (opll == NULL)
- return NULL;
-
- for (i = 0; i < 19 * 2; i++)
- memcpy(&opll->patch[i],&null_patch,sizeof(OPLL_PATCH));
-
- opll->mask = 0;
-
- OPLL_reset (opll);
- OPLL_reset_patch (opll, 0);
-
- return opll;
-}
-
-
-void
-OPLL_delete (OPLL * opll)
-{
- free (opll);
-}
-
-
-/* Reset patch datas by system default. */
-void
-OPLL_reset_patch (OPLL * opll, e_int32 type)
-{
- e_int32 i;
-
- for (i = 0; i < 19 * 2; i++)
- OPLL_copyPatch (opll, i, &default_patch[type % OPLL_TONE_NUM][i]);
-}
-
-/* Reset whole of OPLL except patch datas. */
-void
-OPLL_reset (OPLL * opll)
-{
- e_int32 i;
-
- if (!opll)
- return;
-
- opll->adr = 0;
- opll->out = 0;
-
- opll->pm_phase = 0;
- opll->am_phase = 0;
-
- opll->noise_seed = 0xffff;
- opll->mask = 0;
-
- for (i = 0; i <18; i++)
- OPLL_SLOT_reset(&opll->slot[i], i%2);
-
- for (i = 0; i < 9; i++)
- {
- opll->key_status[i] = 0;
- setPatch (opll, i, 0);
- }
-
- for (i = 0; i < 0x40; i++)
- OPLL_writeReg (opll, i, 0);
-
-#ifndef EMU2413_COMPACTION
- opll->realstep = (e_uint32) ((1 << 31) / rate);
- opll->opllstep = (e_uint32) ((1 << 31) / (clk / 72));
- opll->oplltime = 0;
- for (i = 0; i < 14; i++)
- opll->pan[i] = 127; /* Maxim: pan is 0..255 */
- opll->sprev[0] = opll->sprev[1] = 0;
- opll->snext[0] = opll->snext[1] = 0;
-#endif
-}
-
-/* Force Refresh (When external program changes some parameters). */
-void
-OPLL_forceRefresh (OPLL * opll)
-{
- e_int32 i;
-
- if (opll == NULL)
- return;
-
- for (i = 0; i < 9; i++)
- setPatch(opll,i,opll->patch_number[i]);
-
- for (i = 0; i < 18; i++)
- {
- UPDATE_PG (&opll->slot[i]);
- UPDATE_RKS (&opll->slot[i]);
- UPDATE_TLL (&opll->slot[i]);
- UPDATE_WF (&opll->slot[i]);
- UPDATE_EG (&opll->slot[i]);
- }
-}
-
-void
-OPLL_set_rate (OPLL * opll, e_uint32 r)
-{
- if (opll->quality)
- rate = 49716;
- else
- rate = r;
- internal_refresh ();
- rate = r;
-}
-
-void
-OPLL_set_quality (OPLL * opll, e_uint32 q)
-{
- opll->quality = q;
- OPLL_set_rate (opll, rate);
-}
-
-/*********************************************************
-
- Generate wave data
-
-*********************************************************/
-/* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 2PI). */
-#if ( SLOT_AMP_BITS - PG_BITS ) > 0
-#define wave2_2pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS ))
-#else
-#define wave2_2pi(e) ( (e) << ( PG_BITS - SLOT_AMP_BITS ))
-#endif
-
-/* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 4PI). */
-#if ( SLOT_AMP_BITS - PG_BITS - 1 ) == 0
-#define wave2_4pi(e) (e)
-#elif ( SLOT_AMP_BITS - PG_BITS - 1 ) > 0
-#define wave2_4pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS - 1 ))
-#else
-#define wave2_4pi(e) ( (e) << ( 1 + PG_BITS - SLOT_AMP_BITS ))
-#endif
-
-/* Convert Amp(0 to EG_HEIGHT) to Phase(0 to 8PI). */
-#if ( SLOT_AMP_BITS - PG_BITS - 2 ) == 0
-#define wave2_8pi(e) (e)
-#elif ( SLOT_AMP_BITS - PG_BITS - 2 ) > 0
-#define wave2_8pi(e) ( (e) >> ( SLOT_AMP_BITS - PG_BITS - 2 ))
-#else
-#define wave2_8pi(e) ( (e) << ( 2 + PG_BITS - SLOT_AMP_BITS ))
-#endif
-
-/* Update AM, PM unit */
-static void
-update_ampm (OPLL * opll)
-{
- opll->pm_phase = (opll->pm_phase + pm_dphase) & (PM_DP_WIDTH - 1);
- opll->am_phase = (opll->am_phase + am_dphase) & (AM_DP_WIDTH - 1);
- opll->lfo_am = amtable[HIGHBITS (opll->am_phase, AM_DP_BITS - AM_PG_BITS)];
- opll->lfo_pm = pmtable[HIGHBITS (opll->pm_phase, PM_DP_BITS - PM_PG_BITS)];
-}
-
-/* PG */
-INLINE static void
-calc_phase (OPLL_SLOT * slot, e_int32 lfo)
-{
- if (slot->patch->PM)
- slot->phase += (slot->dphase * lfo) >> PM_AMP_BITS;
- else
- slot->phase += slot->dphase;
-
- slot->phase &= (DP_WIDTH - 1);
-
- slot->pgout = HIGHBITS (slot->phase, DP_BASE_BITS);
-}
-
-/* Update Noise unit */
-static void
-update_noise (OPLL * opll)
-{
- if(opll->noise_seed&1) opll->noise_seed ^= 0x8003020;
- opll->noise_seed >>= 1;
-}
-
-/* EG */
-static void
-calc_envelope (OPLL_SLOT * slot, e_int32 lfo)
-{
-#define S2E(x) (SL2EG((e_int32)(x/SL_STEP))<<(EG_DP_BITS-EG_BITS))
-
- static e_uint32 SL[16] = {
- S2E (0.0), S2E (3.0), S2E (6.0), S2E (9.0), S2E (12.0), S2E (15.0), S2E (18.0), S2E (21.0),
- S2E (24.0), S2E (27.0), S2E (30.0), S2E (33.0), S2E (36.0), S2E (39.0), S2E (42.0), S2E (48.0)
- };
-
- e_uint32 egout;
-
- switch (slot->eg_mode)
- {
- case ATTACK:
- egout = AR_ADJUST_TABLE[HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS)];
- slot->eg_phase += slot->eg_dphase;
- if((EG_DP_WIDTH & slot->eg_phase)||(slot->patch->AR==15))
- {
- egout = 0;
- slot->eg_phase = 0;
- slot->eg_mode = DECAY;
- UPDATE_EG (slot);
- }
- break;
-
- case DECAY:
- egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS);
- slot->eg_phase += slot->eg_dphase;
- if (slot->eg_phase >= SL[slot->patch->SL])
- {
- if (slot->patch->EG)
- {
- slot->eg_phase = SL[slot->patch->SL];
- slot->eg_mode = SUSHOLD;
- UPDATE_EG (slot);
- }
- else
- {
- slot->eg_phase = SL[slot->patch->SL];
- slot->eg_mode = SUSTINE;
- UPDATE_EG (slot);
- }
- }
- break;
-
- case SUSHOLD:
- egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS);
- if (slot->patch->EG == 0)
- {
- slot->eg_mode = SUSTINE;
- UPDATE_EG (slot);
- }
- break;
-
- case SUSTINE:
- case RELEASE:
- egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS);
- slot->eg_phase += slot->eg_dphase;
- if (egout >= (1 << EG_BITS))
- {
- slot->eg_mode = FINISH;
- egout = (1 << EG_BITS) - 1;
- }
- break;
-
- case SETTLE:
- egout = HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS);
- slot->eg_phase += slot->eg_dphase;
- if (egout >= (1 << EG_BITS))
- {
- slot->eg_mode = ATTACK;
- egout = (1 << EG_BITS) - 1;
- UPDATE_EG(slot);
- }
- break;
-
- case FINISH:
- egout = (1 << EG_BITS) - 1;
- break;
-
- default:
- egout = (1 << EG_BITS) - 1;
- break;
- }
-
- if (slot->patch->AM)
- egout = EG2DB (egout + slot->tll) + lfo;
- else
- egout = EG2DB (egout + slot->tll);
-
- if (egout >= DB_MUTE)
- egout = DB_MUTE - 1;
-
- slot->egout = egout | 3;
-}
-
-/* CARRIOR */
-INLINE static e_int32
-calc_slot_car (OPLL_SLOT * slot, e_int32 fm)
-{
- if (slot->egout >= (DB_MUTE - 1))
- {
- slot->output[0] = 0;
- }
- else
- {
- slot->output[0] = DB2LIN_TABLE[slot->sintbl[(slot->pgout+wave2_8pi(fm))&(PG_WIDTH-1)] + slot->egout];
- }
-
- slot->output[1] = (slot->output[1] + slot->output[0]) >> 1;
- return slot->output[1];
-}
-
-/* MODULATOR */
-INLINE static e_int32
-calc_slot_mod (OPLL_SLOT * slot)
-{
- e_int32 fm;
-
- slot->output[1] = slot->output[0];
-
- if (slot->egout >= (DB_MUTE - 1))
- {
- slot->output[0] = 0;
- }
- else if (slot->patch->FB != 0)
- {
- fm = wave2_4pi (slot->feedback) >> (7 - slot->patch->FB);
- slot->output[0] = DB2LIN_TABLE[slot->sintbl[(slot->pgout+fm)&(PG_WIDTH-1)] + slot->egout];
- }
- else
- {
- slot->output[0] = DB2LIN_TABLE[slot->sintbl[slot->pgout] + slot->egout];
- }
-
- slot->feedback = (slot->output[1] + slot->output[0]) >> 1;
-
- return slot->feedback;
-
-}
-
-/* TOM */
-INLINE static e_int32
-calc_slot_tom (OPLL_SLOT * slot)
-{
- if (slot->egout >= (DB_MUTE - 1))
- return 0;
-
- return DB2LIN_TABLE[slot->sintbl[slot->pgout] + slot->egout];
-
-}
-
-/* SNARE */
-INLINE static e_int32
-calc_slot_snare (OPLL_SLOT * slot, e_uint32 noise)
-{
- if(slot->egout>=(DB_MUTE-1))
- return 0;
-
- if(BIT(slot->pgout,7))
- return DB2LIN_TABLE[(noise?DB_POS(0.0):DB_POS(15.0))+slot->egout];
- else
- return DB2LIN_TABLE[(noise?DB_NEG(0.0):DB_NEG(15.0))+slot->egout];
-}
-
-/*
- TOP-CYM
- */
-INLINE static e_int32
-calc_slot_cym (OPLL_SLOT * slot, e_uint32 pgout_hh)
-{
- e_uint32 dbout;
-
- if (slot->egout >= (DB_MUTE - 1))
- return 0;
- else if(
- /* the same as fmopl.c */
- ((BIT(pgout_hh,PG_BITS-8)^BIT(pgout_hh,PG_BITS-1))|BIT(pgout_hh,PG_BITS-7)) ^
- /* different from fmopl.c */
- (BIT(slot->pgout,PG_BITS-7)&!BIT(slot->pgout,PG_BITS-5))
- )
- dbout = DB_NEG(3.0);
- else
- dbout = DB_POS(3.0);
-
- return DB2LIN_TABLE[dbout + slot->egout];
-}
-
-/*
- HI-HAT
-*/
-INLINE static e_int32
-calc_slot_hat (OPLL_SLOT *slot, e_int32 pgout_cym, e_uint32 noise)
-{
- e_uint32 dbout;
-
- if (slot->egout >= (DB_MUTE - 1))
- return 0;
- else if(
- /* the same as fmopl.c */
- ((BIT(slot->pgout,PG_BITS-8)^BIT(slot->pgout,PG_BITS-1))|BIT(slot->pgout,PG_BITS-7)) ^
- /* different from fmopl.c */
- (BIT(pgout_cym,PG_BITS-7)&!BIT(pgout_cym,PG_BITS-5))
- )
- {
- if(noise)
- dbout = DB_NEG(12.0);
- else
- dbout = DB_NEG(24.0);
- }
- else
- {
- if(noise)
- dbout = DB_POS(12.0);
- else
- dbout = DB_POS(24.0);
- }
-
- return DB2LIN_TABLE[dbout + slot->egout];
-}
-
-INLINE static e_int16
-calc (OPLL * opll)
-{
- e_int32 inst = 0, perc = 0, out = 0;
- e_int32 i;
-
- update_ampm (opll);
- update_noise (opll);
-
- for (i = 0; i < 18; i++)
- {
- calc_phase(&opll->slot[i],opll->lfo_pm);
- calc_envelope(&opll->slot[i],opll->lfo_am);
- }
-
- for (i = 0; i < 6; i++)
- if (!(opll->mask & OPLL_MASK_CH (i)) && (CAR(opll,i)->eg_mode != FINISH))
- inst += calc_slot_car (CAR(opll,i), calc_slot_mod(MOD(opll,i)));
-
- /* CH6 */
- if (opll->patch_number[6] <= 15)
- {
- if (!(opll->mask & OPLL_MASK_CH (6)) && (CAR(opll,6)->eg_mode != FINISH))
- inst += calc_slot_car (CAR(opll,6), calc_slot_mod(MOD(opll,6)));
- }
- else
- {
- if (!(opll->mask & OPLL_MASK_BD) && (CAR(opll,6)->eg_mode != FINISH))
- perc += calc_slot_car (CAR(opll,6), calc_slot_mod(MOD(opll,6)));
- }
-
- /* CH7 */
- if (opll->patch_number[7] <= 15)
- {
- if (!(opll->mask & OPLL_MASK_CH (7)) && (CAR(opll,7)->eg_mode != FINISH))
- inst += calc_slot_car (CAR(opll,7), calc_slot_mod(MOD(opll,7)));
- }
- else
- {
- if (!(opll->mask & OPLL_MASK_HH) && (MOD(opll,7)->eg_mode != FINISH))
- perc += calc_slot_hat (MOD(opll,7), CAR(opll,8)->pgout, opll->noise_seed&1);
- if (!(opll->mask & OPLL_MASK_SD) && (CAR(opll,7)->eg_mode != FINISH))
- perc -= calc_slot_snare (CAR(opll,7), opll->noise_seed&1);
- }
-
- /* CH8 */
- if (opll->patch_number[8] <= 15)
- {
- if (!(opll->mask & OPLL_MASK_CH(8)) && (CAR(opll,8)->eg_mode != FINISH))
- inst += calc_slot_car (CAR(opll,8), calc_slot_mod (MOD(opll,8)));
- }
- else
- {
- if (!(opll->mask & OPLL_MASK_TOM) && (MOD(opll,8)->eg_mode != FINISH))
- perc += calc_slot_tom (MOD(opll,8));
- if (!(opll->mask & OPLL_MASK_CYM) && (CAR(opll,8)->eg_mode != FINISH))
- perc -= calc_slot_cym (CAR(opll,8), MOD(opll,7)->pgout);
- }
-
- out = inst + (perc << 1);
- return (e_int16) out << 3;
-}
-
-#ifdef EMU2413_COMPACTION
-e_int16
-OPLL_calc (OPLL * opll)
-{
- return calc (opll);
-}
-#else
-e_int16
-OPLL_calc (OPLL * opll)
-{
- if (!opll->quality)
- return calc (opll);
-
- while (opll->realstep > opll->oplltime)
- {
- opll->oplltime += opll->opllstep;
- opll->prev = opll->next;
- opll->next = calc (opll);
- }
-
- opll->oplltime -= opll->realstep;
- opll->out = (e_int16) (((double) opll->next * (opll->opllstep - opll->oplltime)
- + (double) opll->prev * opll->oplltime) / opll->opllstep);
-
- return (e_int16) opll->out;
-}
-#endif
-
-e_uint32
-OPLL_setMask (OPLL * opll, e_uint32 mask)
-{
- e_uint32 ret;
-
- if (opll)
- {
- ret = opll->mask;
- opll->mask = mask;
- return ret;
- }
- else
- return 0;
-}
-
-e_uint32
-OPLL_toggleMask (OPLL * opll, e_uint32 mask)
-{
- e_uint32 ret;
-
- if (opll)
- {
- ret = opll->mask;
- opll->mask ^= mask;
- return ret;
- }
- else
- return 0;
-}
-
-/****************************************************
-
- I/O Ctrl
-
-*****************************************************/
-
-void
-OPLL_writeReg (OPLL * opll, e_uint32 reg, e_uint32 data)
-{
- e_int32 i, v, ch;
-
- data = data & 0xff;
- reg = reg & 0x3f;
- opll->reg[reg] = (e_uint8) data;
-
- switch (reg)
- {
- case 0x00:
- opll->patch[0].AM = (data >> 7) & 1;
- opll->patch[0].PM = (data >> 6) & 1;
- opll->patch[0].EG = (data >> 5) & 1;
- opll->patch[0].KR = (data >> 4) & 1;
- opll->patch[0].ML = (data) & 15;
- for (i = 0; i < 9; i++)
- {
- if (opll->patch_number[i] == 0)
- {
- UPDATE_PG (MOD(opll,i));
- UPDATE_RKS (MOD(opll,i));
- UPDATE_EG (MOD(opll,i));
- }
- }
- break;
-
- case 0x01:
- opll->patch[1].AM = (data >> 7) & 1;
- opll->patch[1].PM = (data >> 6) & 1;
- opll->patch[1].EG = (data >> 5) & 1;
- opll->patch[1].KR = (data >> 4) & 1;
- opll->patch[1].ML = (data) & 15;
- for (i = 0; i < 9; i++)
- {
- if (opll->patch_number[i] == 0)
- {
- UPDATE_PG (CAR(opll,i));
- UPDATE_RKS (CAR(opll,i));
- UPDATE_EG (CAR(opll,i));
- }
- }
- break;
-
- case 0x02:
- opll->patch[0].KL = (data >> 6) & 3;
- opll->patch[0].TL = (data) & 63;
- for (i = 0; i < 9; i++)
- {
- if (opll->patch_number[i] == 0)
- {
- UPDATE_TLL(MOD(opll,i));
- }
- }
- break;
-
- case 0x03:
- opll->patch[1].KL = (data >> 6) & 3;
- opll->patch[1].WF = (data >> 4) & 1;
- opll->patch[0].WF = (data >> 3) & 1;
- opll->patch[0].FB = (data) & 7;
- for (i = 0; i < 9; i++)
- {
- if (opll->patch_number[i] == 0)
- {
- UPDATE_WF(MOD(opll,i));
- UPDATE_WF(CAR(opll,i));
- }
- }
- break;
-
- case 0x04:
- opll->patch[0].AR = (data >> 4) & 15;
- opll->patch[0].DR = (data) & 15;
- for (i = 0; i < 9; i++)
- {
- if (opll->patch_number[i] == 0)
- {
- UPDATE_EG (MOD(opll,i));
- }
- }
- break;
-
- case 0x05:
- opll->patch[1].AR = (data >> 4) & 15;
- opll->patch[1].DR = (data) & 15;
- for (i = 0; i < 9; i++)
- {
- if (opll->patch_number[i] == 0)
- {
- UPDATE_EG(CAR(opll,i));
- }
- }
- break;
-
- case 0x06:
- opll->patch[0].SL = (data >> 4) & 15;
- opll->patch[0].RR = (data) & 15;
- for (i = 0; i < 9; i++)
- {
- if (opll->patch_number[i] == 0)
- {
- UPDATE_EG (MOD(opll,i));
- }
- }
- break;
-
- case 0x07:
- opll->patch[1].SL = (data >> 4) & 15;
- opll->patch[1].RR = (data) & 15;
- for (i = 0; i < 9; i++)
- {
- if (opll->patch_number[i] == 0)
- {
- UPDATE_EG (CAR(opll,i));
- }
- }
- break;
-
- case 0x0e:
- update_rhythm_mode (opll);
- if (data & 32)
- {
- if (data & 0x10)
- keyOn_BD (opll);
- else
- keyOff_BD (opll);
- if (data & 0x8)
- keyOn_SD (opll);
- else
- keyOff_SD (opll);
- if (data & 0x4)
- keyOn_TOM (opll);
- else
- keyOff_TOM (opll);
- if (data & 0x2)
- keyOn_CYM (opll);
- else
- keyOff_CYM (opll);
- if (data & 0x1)
- keyOn_HH (opll);
- else
- keyOff_HH (opll);
- }
- update_key_status (opll);
-
- UPDATE_ALL (MOD(opll,6));
- UPDATE_ALL (CAR(opll,6));
- UPDATE_ALL (MOD(opll,7));
- UPDATE_ALL (CAR(opll,7));
- UPDATE_ALL (MOD(opll,8));
- UPDATE_ALL (CAR(opll,8));
-
- break;
-
- case 0x0f:
- break;
-
- case 0x10:
- case 0x11:
- case 0x12:
- case 0x13:
- case 0x14:
- case 0x15:
- case 0x16:
- case 0x17:
- case 0x18:
- ch = reg - 0x10;
- setFnumber (opll, ch, data + ((opll->reg[0x20 + ch] & 1) << 8));
- UPDATE_ALL (MOD(opll,ch));
- UPDATE_ALL (CAR(opll,ch));
- break;
-
- case 0x20:
- case 0x21:
- case 0x22:
- case 0x23:
- case 0x24:
- case 0x25:
- case 0x26:
- case 0x27:
- case 0x28:
- ch = reg - 0x20;
- setFnumber (opll, ch, ((data & 1) << 8) + opll->reg[0x10 + ch]);
- setBlock (opll, ch, (data >> 1) & 7);
- setSustine (opll, ch, (data >> 5) & 1);
- if (data & 0x10)
- keyOn (opll, ch);
- else
- keyOff (opll, ch);
- UPDATE_ALL (MOD(opll,ch));
- UPDATE_ALL (CAR(opll,ch));
- update_key_status (opll);
- update_rhythm_mode (opll);
- break;
-
- case 0x30:
- case 0x31:
- case 0x32:
- case 0x33:
- case 0x34:
- case 0x35:
- case 0x36:
- case 0x37:
- case 0x38:
- i = (data >> 4) & 15;
- v = data & 15;
- if ((opll->reg[0x0e] & 32) && (reg >= 0x36))
- {
- switch (reg)
- {
- case 0x37:
- setSlotVolume (MOD(opll,7), i << 2);
- break;
- case 0x38:
- setSlotVolume (MOD(opll,8), i << 2);
- break;
- default:
- break;
- }
- }
- else
- {
- setPatch (opll, reg - 0x30, i);
- }
- setVolume (opll, reg - 0x30, v << 2);
- UPDATE_ALL (MOD(opll,reg - 0x30));
- UPDATE_ALL (CAR(opll,reg - 0x30));
- break;
-
- default:
- break;
-
- }
-}
-
-void
-OPLL_writeIO (OPLL * opll, e_uint32 adr, e_uint32 val)
-{
- if (adr & 1)
- OPLL_writeReg (opll, opll->adr, val);
- else
- opll->adr = val;
-}
-
-#ifndef EMU2413_COMPACTION
-/* STEREO MODE (OPT) */
-void
-OPLL_set_pan (OPLL * opll, e_uint32 ch, e_uint32 pan)
-{
- opll->pan[ch & 15] = pan & 255; /* Maxim: pan is 0..255 */
-}
-
-static void
-calc_stereo (OPLL * opll, e_int32 out[2])
-{
- /* Maxim: changed panning to be 0..255, 127 is centre */
- e_int32 l=0,r=0;
-// e_int32 b[4] = { 0, 0, 0, 0 }; /* Ignore, Right, Left, Center */
-// e_int32 r[4] = { 0, 0, 0, 0 }; /* Ignore, Right, Left, Center */
- e_int32 i;
- e_int32 channel;
-
- update_ampm (opll);
- update_noise (opll);
-
- for(i=0;i<18;i++)
- {
- calc_phase(&opll->slot[i],opll->lfo_pm);
- calc_envelope(&opll->slot[i],opll->lfo_am);
- }
-
- for (i = 0; i < 6; i++)
- if (!(opll->mask & OPLL_MASK_CH (i)) && (CAR(opll,i)->eg_mode != FINISH))
- {
- channel = calc_slot_car (CAR(opll,i), calc_slot_mod (MOD(opll,i)));
- if ( opll->pan[i] == 127 )
- {
- l += channel;
- r += channel;
- }
- else
- {
- l += channel * (255-opll->pan[i]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
- r += channel * ( opll->pan[i]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
- }
- }
-
-
- if (opll->patch_number[6] <= 15)
- {
- if (!(opll->mask & OPLL_MASK_CH (6)) && (CAR(opll,6)->eg_mode != FINISH))
- {
- channel = calc_slot_car (CAR(opll,6), calc_slot_mod (MOD(opll,6)));
- if ( opll->pan[6] == 127 )
- {
- l += channel;
- r += channel;
- }
- else
- {
- l += channel * (255-opll->pan[6]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
- r += channel * ( opll->pan[6]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
- }
-
- }
- }
- else
- {
- if (!(opll->mask & OPLL_MASK_BD) && (CAR(opll,6)->eg_mode != FINISH))
- {
- channel = calc_slot_car (CAR(opll,6), calc_slot_mod (MOD(opll,6)));
- if ( opll->pan[9] == 127 )
- {
- l += channel;
- r += channel;
- }
- else
- {
- l += channel * (255-opll->pan[9]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
- r += channel * ( opll->pan[9]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
- }
- }
- }
-
- if (opll->patch_number[7] <= 15)
- {
- if (!(opll->mask & OPLL_MASK_CH (7)) && (CAR (opll,7)->eg_mode != FINISH))
- {
- channel = calc_slot_car (CAR (opll,7), calc_slot_mod (MOD (opll,7)));
- if ( opll->pan[7] == 127 )
- {
- l += channel;
- r += channel;
- }
- else
- {
- l += channel * (255-opll->pan[7]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
- r += channel * ( opll->pan[7]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
- }
- }
- }
- else
- {
- if (!(opll->mask & OPLL_MASK_HH) && (MOD (opll,7)->eg_mode != FINISH))
- {
- channel = calc_slot_hat (MOD (opll,7), CAR(opll,8)->pgout, opll->noise_seed&1);
- if ( opll->pan[10] == 127 )
- {
- l += channel;
- r += channel;
- }
- else
- {
- l += channel * (255-opll->pan[10]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
- r += channel * ( opll->pan[10]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
- }
- }
- if (!(opll->mask & OPLL_MASK_SD) && (CAR (opll,7)->eg_mode != FINISH))
- {
- channel = -calc_slot_snare (CAR (opll,7), opll->noise_seed&1); // this one is negated
- if ( opll->pan[11] == 127 )
- {
- l += channel;
- r += channel;
- }
- else
- {
- l += channel * (255-opll->pan[11]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
- r += channel * ( opll->pan[11]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
- }
- }
- }
-
- if (opll->patch_number[8] <= 15)
- {
- if (!(opll->mask & OPLL_MASK_CH (8)) && (CAR (opll,8)->eg_mode != FINISH))
- {
- channel = calc_slot_car (CAR (opll,8), calc_slot_mod (MOD (opll,8)));
- if ( opll->pan[8] == 127 )
- {
- l += channel;
- r += channel;
- }
- else
- {
- l += channel * (255-opll->pan[8]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
- r += channel * ( opll->pan[8]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
- }
- }
- }
- else
- {
- if (!(opll->mask & OPLL_MASK_TOM) && (MOD (opll,8)->eg_mode != FINISH))
- {
- channel = calc_slot_tom (MOD (opll,8));
- if ( opll->pan[12] == 127 )
- {
- l += channel;
- r += channel;
- }
- else
- {
- l += channel * (255-opll->pan[12]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
- r += channel * ( opll->pan[12]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
- }
- }
- if (!(opll->mask & OPLL_MASK_CYM) && (CAR (opll,8)->eg_mode != FINISH))
- {
- channel = -calc_slot_cym (CAR (opll,8), MOD(opll,7)->pgout); // negated
- if ( opll->pan[13] == 127 )
- {
- l += channel;
- r += channel;
- }
- else
- {
- l += channel * (255-opll->pan[13]) / 127; // 0 -> 2, 127 -> 1, 255 -> 0 (nearly)
- r += channel * ( opll->pan[13]) / 127; // 255 -> 2, 127 -> 1, 0 -> 0 (nearly)
- }
- }
- }
-/*
- out[1] = (b[1] + b[3] + ((r[1] + r[3]) << 1)) <<3;
- out[0] = (b[2] + b[3] + ((r[2] + r[3]) << 1)) <<3;
- */
- out[0] = l << 3;
- out[1] = r << 3;
-}
-
-void
-OPLL_calc_stereo (OPLL * opll, e_int32 out[2])
-{
- if (!opll->quality)
- {
- calc_stereo (opll, out);
- return;
- }
-
- while (opll->realstep > opll->oplltime)
- {
- opll->oplltime += opll->opllstep;
- opll->sprev[0] = opll->snext[0];
- opll->sprev[1] = opll->snext[1];
- calc_stereo (opll, opll->snext);
- }
-
- opll->oplltime -= opll->realstep;
- out[0] = (e_int16) (((double) opll->snext[0] * (opll->opllstep - opll->oplltime)
- + (double) opll->sprev[0] * opll->oplltime) / opll->opllstep);
- out[1] = (e_int16) (((double) opll->snext[1] * (opll->opllstep - opll->oplltime)
- + (double) opll->sprev[1] * opll->oplltime) / opll->opllstep);
-}
-#endif /* EMU2413_COMPACTION */
-
-// Ym2413_Emu
-#include "Ym2413_Emu.h"
-
-#include <assert.h>
-
-static int use_count = 0;
-
-Ym2413_Emu::~Ym2413_Emu()
-{
- if ( opll )
- {
- use_count--;
- OPLL_delete( opll );
- }
-}
-
-Ym2413_Emu::Ym2413_Emu()
-{
- opll = 0;
-}
-
-int Ym2413_Emu::set_rate( double sample_rate, double clock_rate )
-{
- if ( opll )
- {
- OPLL_delete( opll );
- opll = 0;
- use_count--;
- }
-
- // Only one YM2413 may be used at a time (emu2413 uses lots of global data)
- assert( use_count == 0 );
- use_count++;
-
- opll = OPLL_new ((int) clock_rate, (int) sample_rate);
- if ( !opll )
- return 1;
-
- reset();
- return 0;
-}
-
-void Ym2413_Emu::reset()
-{
- OPLL_reset( opll );
- OPLL_reset_patch( opll, 0 );
- OPLL_setMask( opll, 0 );
- OPLL_set_quality( opll, 0 );
-}
-
-void Ym2413_Emu::write( int addr, int data )
-{
- OPLL_writeReg( opll, addr, data );
-}
-
-void Ym2413_Emu::mute_voices( int mask )
-{
- OPLL_setMask( opll, mask );
-}
-
-void Ym2413_Emu::run( int pair_count, sample_t* out )
-{
- while ( pair_count-- )
- {
- int s = OPLL_calc( opll );
- out [0] = s;
- out [1] = s;
- out += 2;
- }
-}
-
diff --git a/src/console/Ym2612_Emu.cc b/src/console/Ym2612_Emu.cc
new file mode 100644
index 000000000000..cfacd2fe1234
--- /dev/null
+++ b/src/console/Ym2612_Emu.cc
@@ -0,0 +1,1319 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+// Based on Gens 2.10 ym2612.c
+
+#include "Ym2612_Emu.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <stdio.h>
+#include <math.h>
+
+/* Copyright (C) 2002 Stéphane Dallongeville (gens AT consolemul.com) */
+/* Copyright (C) 2004-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+// This is mostly the original source in its C style and all.
+//
+// Somewhat optimized and simplified. Uses a template to generate the many
+// variants of Update_Chan. Rewrote header file. In need of full rewrite by
+// someone more familiar with FM sound and the YM2612. Has some inaccuracies
+// compared to the Sega Genesis sound, particularly being mixed at such a
+// high sample accuracy (the Genesis sounds like it has only 8 bit samples).
+// - Shay
+
+#ifdef BLARGG_ENABLE_OPTIMIZER
+ #include BLARGG_ENABLE_OPTIMIZER
+#endif
+
+const int output_bits = 14;
+
+struct slot_t
+{
+ const int *DT; // parametre detune
+ int MUL; // parametre "multiple de frequence"
+ int TL; // Total Level = volume lorsque l'enveloppe est au plus haut
+ int TLL; // Total Level ajusted
+ int SLL; // Sustin Level (ajusted) = volume où l'enveloppe termine sa premiere phase de regression
+ int KSR_S; // Key Scale Rate Shift = facteur de prise en compte du KSL dans la variations de l'enveloppe
+ int KSR; // Key Scale Rate = cette valeur est calculee par rapport à la frequence actuelle, elle va influer
+ // sur les differents parametres de l'enveloppe comme l'attaque, le decay ... comme dans la realite !
+ int SEG; // Type enveloppe SSG
+ int env_xor;
+ int env_max;
+
+ const int *AR; // Attack Rate (table pointeur) = Taux d'attaque (AR[KSR])
+ const int *DR; // Decay Rate (table pointeur) = Taux pour la regression (DR[KSR])
+ const int *SR; // Sustin Rate (table pointeur) = Taux pour le maintien (SR[KSR])
+ const int *RR; // Release Rate (table pointeur) = Taux pour le rel'chement (RR[KSR])
+ int Fcnt; // Frequency Count = compteur-frequence pour determiner l'amplitude actuelle (SIN[Finc >> 16])
+ int Finc; // frequency step = pas d'incrementation du compteur-frequence
+ // plus le pas est grand, plus la frequence est aïgu (ou haute)
+ int Ecurp; // Envelope current phase = cette variable permet de savoir dans quelle phase
+ // de l'enveloppe on se trouve, par exemple phase d'attaque ou phase de maintenue ...
+ // en fonction de la valeur de cette variable, on va appeler une fonction permettant
+ // de mettre à jour l'enveloppe courante.
+ int Ecnt; // Envelope counter = le compteur-enveloppe permet de savoir où l'on se trouve dans l'enveloppe
+ int Einc; // Envelope step courant
+ int Ecmp; // Envelope counter limite pour la prochaine phase
+ int EincA; // Envelope step for Attack = pas d'incrementation du compteur durant la phase d'attaque
+ // cette valeur est egal à AR[KSR]
+ int EincD; // Envelope step for Decay = pas d'incrementation du compteur durant la phase de regression
+ // cette valeur est egal à DR[KSR]
+ int EincS; // Envelope step for Sustain = pas d'incrementation du compteur durant la phase de maintenue
+ // cette valeur est egal à SR[KSR]
+ int EincR; // Envelope step for Release = pas d'incrementation du compteur durant la phase de rel'chement
+ // cette valeur est egal à RR[KSR]
+ int *OUTp; // pointeur of SLOT output = pointeur permettant de connecter la sortie de ce slot à l'entree
+ // d'un autre ou carrement à la sortie de la voie
+ int INd; // input data of the slot = donnees en entree du slot
+ int ChgEnM; // Change envelop mask.
+ int AMS; // AMS depth level of this SLOT = degre de modulation de l'amplitude par le LFO
+ int AMSon; // AMS enable flag = drapeau d'activation de l'AMS
+};
+
+struct channel_t
+{
+ int S0_OUT[4]; // anciennes sorties slot 0 (pour le feed back)
+ int LEFT; // LEFT enable flag
+ int RIGHT; // RIGHT enable flag
+ int ALGO; // Algorythm = determine les connections entre les operateurs
+ int FB; // shift count of self feed back = degre de "Feed-Back" du SLOT 1 (il est son unique entree)
+ int FMS; // Frequency Modulation Sensitivity of channel = degre de modulation de la frequence sur la voie par le LFO
+ int AMS; // Amplitude Modulation Sensitivity of channel = degre de modulation de l'amplitude sur la voie par le LFO
+ int FNUM[4]; // hauteur frequence de la voie (+ 3 pour le mode special)
+ int FOCT[4]; // octave de la voie (+ 3 pour le mode special)
+ int KC[4]; // Key Code = valeur fonction de la frequence (voir KSR pour les slots, KSR = KC >> KSR_S)
+ slot_t SLOT[4]; // four slot.operators = les 4 slots de la voie
+ int FFlag; // Frequency step recalculation flag
+};
+
+struct state_t
+{
+ int TimerBase; // TimerBase calculation
+ int Status; // YM2612 Status (timer overflow)
+ int TimerA; // timerA limit = valeur jusqu'à laquelle le timer A doit compter
+ int TimerAL;
+ int TimerAcnt; // timerA counter = valeur courante du Timer A
+ int TimerB; // timerB limit = valeur jusqu'à laquelle le timer B doit compter
+ int TimerBL;
+ int TimerBcnt; // timerB counter = valeur courante du Timer B
+ int Mode; // Mode actuel des voie 3 et 6 (normal / special)
+ int DAC; // DAC enabled flag
+ channel_t CHANNEL[Ym2612_Emu::channel_count]; // Les 6 voies du YM2612
+ int REG[2][0x100]; // Sauvegardes des valeurs de tout les registres, c'est facultatif
+ // cela nous rend le debuggage plus facile
+};
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+
+#define ATTACK 0
+#define DECAY 1
+#define SUBSTAIN 2
+#define RELEASE 3
+
+// SIN_LBITS <= 16
+// LFO_HBITS <= 16
+// (SIN_LBITS + SIN_HBITS) <= 26
+// (ENV_LBITS + ENV_HBITS) <= 28
+// (LFO_LBITS + LFO_HBITS) <= 28
+
+#define SIN_HBITS 12 // Sinus phase counter int part
+#define SIN_LBITS (26 - SIN_HBITS) // Sinus phase counter float part (best setting)
+
+#if (SIN_LBITS > 16)
+#define SIN_LBITS 16 // Can't be greater than 16 bits
+#endif
+
+#define ENV_HBITS 12 // Env phase counter int part
+#define ENV_LBITS (28 - ENV_HBITS) // Env phase counter float part (best setting)
+
+#define LFO_HBITS 10 // LFO phase counter int part
+#define LFO_LBITS (28 - LFO_HBITS) // LFO phase counter float part (best setting)
+
+#define SIN_LENGHT (1 << SIN_HBITS)
+#define ENV_LENGHT (1 << ENV_HBITS)
+#define LFO_LENGHT (1 << LFO_HBITS)
+
+#define TL_LENGHT (ENV_LENGHT * 3) // Env + TL scaling + LFO
+
+#define SIN_MASK (SIN_LENGHT - 1)
+#define ENV_MASK (ENV_LENGHT - 1)
+#define LFO_MASK (LFO_LENGHT - 1)
+
+#define ENV_STEP (96.0 / ENV_LENGHT) // ENV_MAX = 96 dB
+
+#define ENV_ATTACK ((ENV_LENGHT * 0) << ENV_LBITS)
+#define ENV_DECAY ((ENV_LENGHT * 1) << ENV_LBITS)
+#define ENV_END ((ENV_LENGHT * 2) << ENV_LBITS)
+
+#define MAX_OUT_BITS (SIN_HBITS + SIN_LBITS + 2) // Modulation = -4 <--> +4
+#define MAX_OUT ((1 << MAX_OUT_BITS) - 1)
+
+#define PG_CUT_OFF ((int) (78.0 / ENV_STEP))
+#define ENV_CUT_OFF ((int) (68.0 / ENV_STEP))
+
+#define AR_RATE 399128
+#define DR_RATE 5514396
+
+//#define AR_RATE 426136
+//#define DR_RATE (AR_RATE * 12)
+
+#define LFO_FMS_LBITS 9 // FIXED (LFO_FMS_BASE gives somethink as 1)
+#define LFO_FMS_BASE ((int) (0.05946309436 * 0.0338 * (double) (1 << LFO_FMS_LBITS)))
+
+#define S0 0 // Stupid typo of the YM2612
+#define S1 2
+#define S2 1
+#define S3 3
+
+inline void set_seg( slot_t& s, int seg )
+{
+ s.env_xor = 0;
+ s.env_max = INT_MAX;
+ s.SEG = seg;
+ if ( seg & 4 )
+ {
+ s.env_xor = ENV_MASK;
+ s.env_max = ENV_MASK;
+ }
+}
+
+struct tables_t
+{
+ short SIN_TAB [SIN_LENGHT]; // SINUS TABLE (offset into TL TABLE)
+ int LFOcnt; // LFO counter = compteur-frequence pour le LFO
+ int LFOinc; // LFO step counter = pas d'incrementation du compteur-frequence du LFO
+ // plus le pas est grand, plus la frequence est grande
+ unsigned int AR_TAB [128]; // Attack rate table
+ unsigned int DR_TAB [96]; // Decay rate table
+ unsigned int DT_TAB [8] [32]; // Detune table
+ unsigned int SL_TAB [16]; // Substain level table
+ unsigned int NULL_RATE [32]; // Table for nullptr rate
+ int LFO_INC_TAB [8]; // LFO step table
+
+ short ENV_TAB [2 * ENV_LENGHT + 8]; // ENV CURVE TABLE (attack & decay)
+
+ short LFO_ENV_TAB [LFO_LENGHT]; // LFO AMS TABLE (adjusted for 11.8 dB)
+ short LFO_FREQ_TAB [LFO_LENGHT]; // LFO FMS TABLE
+ int TL_TAB [TL_LENGHT * 2]; // TOTAL LEVEL TABLE (positif and minus)
+ unsigned int DECAY_TO_ATTACK [ENV_LENGHT]; // Conversion from decay to attack phase
+ unsigned int FINC_TAB [2048]; // Frequency step table
+};
+
+static const unsigned char DT_DEF_TAB [4 * 32] =
+{
+// FD = 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+// FD = 1
+ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
+ 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
+
+// FD = 2
+ 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
+ 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 16, 16, 16, 16,
+
+// FD = 3
+ 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
+ 8 , 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 20, 22, 22, 22, 22
+};
+
+static const unsigned char FKEY_TAB [16] =
+{
+ 0, 0, 0, 0,
+ 0, 0, 0, 1,
+ 2, 3, 3, 3,
+ 3, 3, 3, 3
+};
+
+static const unsigned char LFO_AMS_TAB [4] =
+{
+ 31, 4, 1, 0
+};
+
+static const unsigned char LFO_FMS_TAB [8] =
+{
+ LFO_FMS_BASE * 0, LFO_FMS_BASE * 1,
+ LFO_FMS_BASE * 2, LFO_FMS_BASE * 3,
+ LFO_FMS_BASE * 4, LFO_FMS_BASE * 6,
+ LFO_FMS_BASE * 12, LFO_FMS_BASE * 24
+};
+
+inline void YM2612_Special_Update() { }
+
+struct Ym2612_Impl
+{
+ enum { channel_count = Ym2612_Emu::channel_count };
+
+ state_t YM2612;
+ int mute_mask;
+ tables_t g;
+
+ void KEY_ON( channel_t&, int );
+ void KEY_OFF( channel_t&, int );
+ int SLOT_SET( int, int );
+ int CHANNEL_SET( int, int );
+ int YM_SET( int, int );
+
+ void set_rate( double sample_rate, double clock_factor );
+ void reset();
+ void write0( int addr, int data );
+ void write1( int addr, int data );
+ void run_timer( int );
+ void run( int pair_count, Ym2612_Emu::sample_t* );
+};
+
+void Ym2612_Impl::KEY_ON( channel_t& ch, int nsl)
+{
+ slot_t *SL = &(ch.SLOT [nsl]); // on recupere le bon pointeur de slot
+
+ if (SL->Ecurp == RELEASE) // la touche est-elle rel'chee ?
+ {
+ SL->Fcnt = 0;
+
+ // Fix Ecco 2 splash sound
+
+ SL->Ecnt = (g.DECAY_TO_ATTACK [g.ENV_TAB [SL->Ecnt >> ENV_LBITS]] + ENV_ATTACK) & SL->ChgEnM;
+ SL->ChgEnM = ~0;
+
+// SL->Ecnt = g.DECAY_TO_ATTACK [g.ENV_TAB [SL->Ecnt >> ENV_LBITS]] + ENV_ATTACK;
+// SL->Ecnt = 0;
+
+ SL->Einc = SL->EincA;
+ SL->Ecmp = ENV_DECAY;
+ SL->Ecurp = ATTACK;
+ }
+}
+
+
+void Ym2612_Impl::KEY_OFF(channel_t& ch, int nsl)
+{
+ slot_t *SL = &(ch.SLOT [nsl]); // on recupere le bon pointeur de slot
+
+ if (SL->Ecurp != RELEASE) // la touche est-elle appuyee ?
+ {
+ if (SL->Ecnt < ENV_DECAY) // attack phase ?
+ {
+ SL->Ecnt = (g.ENV_TAB [SL->Ecnt >> ENV_LBITS] << ENV_LBITS) + ENV_DECAY;
+ }
+
+ SL->Einc = SL->EincR;
+ SL->Ecmp = ENV_END;
+ SL->Ecurp = RELEASE;
+ }
+}
+
+
+int Ym2612_Impl::SLOT_SET( int Adr, int data )
+{
+ int nch = Adr & 3;
+ if ( nch == 3 )
+ return 1;
+
+ channel_t& ch = YM2612.CHANNEL [nch + (Adr & 0x100 ? 3 : 0)];
+ slot_t& sl = ch.SLOT [(Adr >> 2) & 3];
+
+ switch ( Adr & 0xF0 )
+ {
+ case 0x30:
+ if ( (sl.MUL = (data & 0x0F)) != 0 ) sl.MUL <<= 1;
+ else sl.MUL = 1;
+
+ sl.DT = (int*) g.DT_TAB [(data >> 4) & 7];
+
+ ch.SLOT [0].Finc = -1;
+
+ break;
+
+ case 0x40:
+ sl.TL = data & 0x7F;
+
+ // SOR2 do a lot of TL adjustement and this fix R.Shinobi jump sound...
+ YM2612_Special_Update();
+
+#if ((ENV_HBITS - 7) < 0)
+ sl.TLL = sl.TL >> (7 - ENV_HBITS);
+#else
+ sl.TLL = sl.TL << (ENV_HBITS - 7);
+#endif
+
+ break;
+
+ case 0x50:
+ sl.KSR_S = 3 - (data >> 6);
+
+ ch.SLOT [0].Finc = -1;
+
+ if (data &= 0x1F) sl.AR = (int*) &g.AR_TAB [data << 1];
+ else sl.AR = (int*) &g.NULL_RATE [0];
+
+ sl.EincA = sl.AR [sl.KSR];
+ if (sl.Ecurp == ATTACK) sl.Einc = sl.EincA;
+ break;
+
+ case 0x60:
+ if ( (sl.AMSon = (data & 0x80)) != 0 ) sl.AMS = ch.AMS;
+ else sl.AMS = 31;
+
+ if (data &= 0x1F) sl.DR = (int*) &g.DR_TAB [data << 1];
+ else sl.DR = (int*) &g.NULL_RATE [0];
+
+ sl.EincD = sl.DR [sl.KSR];
+ if (sl.Ecurp == DECAY) sl.Einc = sl.EincD;
+ break;
+
+ case 0x70:
+ if (data &= 0x1F) sl.SR = (int*) &g.DR_TAB [data << 1];
+ else sl.SR = (int*) &g.NULL_RATE [0];
+
+ sl.EincS = sl.SR [sl.KSR];
+ if ((sl.Ecurp == SUBSTAIN) && (sl.Ecnt < ENV_END)) sl.Einc = sl.EincS;
+ break;
+
+ case 0x80:
+ sl.SLL = g.SL_TAB [data >> 4];
+
+ sl.RR = (int*) &g.DR_TAB [((data & 0xF) << 2) + 2];
+
+ sl.EincR = sl.RR [sl.KSR];
+ if ((sl.Ecurp == RELEASE) && (sl.Ecnt < ENV_END)) sl.Einc = sl.EincR;
+ break;
+
+ case 0x90:
+ // SSG-EG envelope shapes :
+ /*
+ E At Al H
+
+ 1 0 0 0 \\\\
+ 1 0 0 1 \___
+ 1 0 1 0 \/\/
+ 1 0 1 1 \
+ 1 1 0 0 ////
+ 1 1 0 1 /
+ 1 1 1 0 /\/\
+ 1 1 1 1 /___
+
+ E = SSG-EG enable
+ At = Start negate
+ Al = Altern
+ H = Hold */
+
+ set_seg( sl, (data & 8) ? (data & 0x0F) : 0 );
+ break;
+ }
+
+ return 0;
+}
+
+
+int Ym2612_Impl::CHANNEL_SET( int Adr, int data )
+{
+ int num = Adr & 3;
+ if ( num == 3 )
+ return 1;
+
+ channel_t& ch = YM2612.CHANNEL [num + (Adr & 0x100 ? 3 : 0)];
+
+ switch ( Adr & 0xFC )
+ {
+ case 0xA0:
+ YM2612_Special_Update();
+
+ ch.FNUM [0] = (ch.FNUM [0] & 0x700) + data;
+ ch.KC [0] = (ch.FOCT [0] << 2) | FKEY_TAB [ch.FNUM [0] >> 7];
+
+ ch.SLOT [0].Finc = -1;
+ break;
+
+ case 0xA4:
+ YM2612_Special_Update();
+
+ ch.FNUM [0] = (ch.FNUM [0] & 0x0FF) + ((data & 0x07) << 8);
+ ch.FOCT [0] = (data & 0x38) >> 3;
+ ch.KC [0] = (ch.FOCT [0] << 2) | FKEY_TAB [ch.FNUM [0] >> 7];
+
+ ch.SLOT [0].Finc = -1;
+ break;
+
+ case 0xA8:
+ if ( Adr < 0x100 )
+ {
+ num++;
+
+ YM2612_Special_Update();
+
+ YM2612.CHANNEL [2].FNUM [num] = (YM2612.CHANNEL [2].FNUM [num] & 0x700) + data;
+ YM2612.CHANNEL [2].KC [num] = (YM2612.CHANNEL [2].FOCT [num] << 2) |
+ FKEY_TAB [YM2612.CHANNEL [2].FNUM [num] >> 7];
+
+ YM2612.CHANNEL [2].SLOT [0].Finc = -1;
+ }
+ break;
+
+ case 0xAC:
+ if ( Adr < 0x100 )
+ {
+ num++;
+
+ YM2612_Special_Update();
+
+ YM2612.CHANNEL [2].FNUM [num] = (YM2612.CHANNEL [2].FNUM [num] & 0x0FF) + ((data & 0x07) << 8);
+ YM2612.CHANNEL [2].FOCT [num] = (data & 0x38) >> 3;
+ YM2612.CHANNEL [2].KC [num] = (YM2612.CHANNEL [2].FOCT [num] << 2) |
+ FKEY_TAB [YM2612.CHANNEL [2].FNUM [num] >> 7];
+
+ YM2612.CHANNEL [2].SLOT [0].Finc = -1;
+ }
+ break;
+
+ case 0xB0:
+ if ( ch.ALGO != (data & 7) )
+ {
+ // Fix VectorMan 2 heli sound (level 1)
+ YM2612_Special_Update();
+
+ ch.ALGO = data & 7;
+
+ ch.SLOT [0].ChgEnM = 0;
+ ch.SLOT [1].ChgEnM = 0;
+ ch.SLOT [2].ChgEnM = 0;
+ ch.SLOT [3].ChgEnM = 0;
+ }
+
+ ch.FB = 9 - ((data >> 3) & 7); // Real thing ?
+
+// if (ch.FB = ((data >> 3) & 7)) ch.FB = 9 - ch.FB; // Thunder force 4 (music stage 8), Gynoug, Aladdin bug sound...
+// else ch.FB = 31;
+ break;
+
+ case 0xB4: {
+ YM2612_Special_Update();
+
+ ch.LEFT = 0 - ((data >> 7) & 1);
+ ch.RIGHT = 0 - ((data >> 6) & 1);
+
+ ch.AMS = LFO_AMS_TAB [(data >> 4) & 3];
+ ch.FMS = LFO_FMS_TAB [data & 7];
+
+ for ( int i = 0; i < 4; i++ )
+ {
+ slot_t& sl = ch.SLOT [i];
+ sl.AMS = (sl.AMSon ? ch.AMS : 31);
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+int Ym2612_Impl::YM_SET(int Adr, int data)
+{
+ switch ( Adr )
+ {
+ case 0x22:
+ if (data & 8) // LFO enable
+ {
+ // Cool Spot music 1, LFO modified severals time which
+ // distord the sound, have to check that on a real genesis...
+
+ g.LFOinc = g.LFO_INC_TAB [data & 7];
+ }
+ else
+ {
+ g.LFOinc = g.LFOcnt = 0;
+ }
+ break;
+
+ case 0x24:
+ YM2612.TimerA = (YM2612.TimerA & 0x003) | (((int) data) << 2);
+
+ if (YM2612.TimerAL != (1024 - YM2612.TimerA) << 12)
+ {
+ YM2612.TimerAcnt = YM2612.TimerAL = (1024 - YM2612.TimerA) << 12;
+ }
+ break;
+
+ case 0x25:
+ YM2612.TimerA = (YM2612.TimerA & 0x3FC) | (data & 3);
+
+ if (YM2612.TimerAL != (1024 - YM2612.TimerA) << 12)
+ {
+ YM2612.TimerAcnt = YM2612.TimerAL = (1024 - YM2612.TimerA) << 12;
+ }
+ break;
+
+ case 0x26:
+ YM2612.TimerB = data;
+
+ if (YM2612.TimerBL != (256 - YM2612.TimerB) << (4 + 12))
+ {
+ YM2612.TimerBcnt = YM2612.TimerBL = (256 - YM2612.TimerB) << (4 + 12);
+ }
+ break;
+
+ case 0x27:
+ // Parametre divers
+ // b7 = CSM MODE
+ // b6 = 3 slot mode
+ // b5 = reset b
+ // b4 = reset a
+ // b3 = timer enable b
+ // b2 = timer enable a
+ // b1 = load b
+ // b0 = load a
+
+ if ((data ^ YM2612.Mode) & 0x40)
+ {
+ // We changed the channel 2 mode, so recalculate phase step
+ // This fix the punch sound in Street of Rage 2
+
+ YM2612_Special_Update();
+
+ YM2612.CHANNEL [2].SLOT [0].Finc = -1; // recalculate phase step
+ }
+
+// if ((data & 2) && (YM2612.Status & 2)) YM2612.TimerBcnt = YM2612.TimerBL;
+// if ((data & 1) && (YM2612.Status & 1)) YM2612.TimerAcnt = YM2612.TimerAL;
+
+// YM2612.Status &= (~data >> 4); // Reset du Status au cas ou c'est demande
+ YM2612.Status &= (~data >> 4) & (data >> 2); // Reset Status
+
+ YM2612.Mode = data;
+ break;
+
+ case 0x28: {
+ int nch = data & 3;
+ if ( nch == 3 )
+ return 1;
+ if ( data & 4 )
+ nch += 3;
+ channel_t& ch = YM2612.CHANNEL [nch];
+
+ YM2612_Special_Update();
+
+ if (data & 0x10) KEY_ON(ch, S0); // On appuie sur la touche pour le slot 1
+ else KEY_OFF(ch, S0); // On rel'che la touche pour le slot 1
+ if (data & 0x20) KEY_ON(ch, S1); // On appuie sur la touche pour le slot 3
+ else KEY_OFF(ch, S1); // On rel'che la touche pour le slot 3
+ if (data & 0x40) KEY_ON(ch, S2); // On appuie sur la touche pour le slot 2
+ else KEY_OFF(ch, S2); // On rel'che la touche pour le slot 2
+ if (data & 0x80) KEY_ON(ch, S3); // On appuie sur la touche pour le slot 4
+ else KEY_OFF(ch, S3); // On rel'che la touche pour le slot 4
+ break;
+ }
+
+ case 0x2B:
+ if (YM2612.DAC ^ (data & 0x80)) YM2612_Special_Update();
+
+ YM2612.DAC = data & 0x80; // activation/desactivation du DAC
+ break;
+ }
+
+ return 0;
+}
+
+void Ym2612_Impl::set_rate( double sample_rate, double clock_rate )
+{
+ assert( sample_rate );
+ assert( clock_rate > sample_rate );
+
+ int i;
+
+ // 144 = 12 * (prescale * 2) = 12 * 6 * 2
+ // prescale set to 6 by default
+
+ double Frequence = clock_rate / sample_rate / 144.0;
+ if ( fabs( Frequence - 1.0 ) < 0.0000001 )
+ Frequence = 1.0;
+ YM2612.TimerBase = int (Frequence * 4096.0);
+
+ // Tableau TL :
+ // [0 - 4095] = +output [4095 - ...] = +output overflow (fill with 0)
+ // [12288 - 16383] = -output [16384 - ...] = -output overflow (fill with 0)
+
+ for(i = 0; i < TL_LENGHT; i++)
+ {
+ if (i >= PG_CUT_OFF) // YM2612 cut off sound after 78 dB (14 bits output ?)
+ {
+ g.TL_TAB [TL_LENGHT + i] = g.TL_TAB [i] = 0;
+ }
+ else
+ {
+ double x = MAX_OUT; // Max output
+ x /= pow( 10.0, (ENV_STEP * i) / 20.0 ); // Decibel -> Voltage
+
+ g.TL_TAB [i] = (int) x;
+ g.TL_TAB [TL_LENGHT + i] = -g.TL_TAB [i];
+ }
+ }
+
+ // Tableau SIN :
+ // g.SIN_TAB [x] [y] = sin(x) * y;
+ // x = phase and y = volume
+
+ g.SIN_TAB [0] = g.SIN_TAB [SIN_LENGHT / 2] = PG_CUT_OFF;
+
+ for(i = 1; i <= SIN_LENGHT / 4; i++)
+ {
+ double x = sin(2.0 * PI * (double) (i) / (double) (SIN_LENGHT)); // Sinus
+ x = 20 * log10(1 / x); // convert to dB
+
+ int j = (int) (x / ENV_STEP); // Get TL range
+
+ if (j > PG_CUT_OFF) j = (int) PG_CUT_OFF;
+
+ g.SIN_TAB [i] = g.SIN_TAB [(SIN_LENGHT / 2) - i] = j;
+ g.SIN_TAB [(SIN_LENGHT / 2) + i] = g.SIN_TAB [SIN_LENGHT - i] = TL_LENGHT + j;
+ }
+
+ // Tableau LFO (LFO wav) :
+
+ for(i = 0; i < LFO_LENGHT; i++)
+ {
+ double x = sin(2.0 * PI * (double) (i) / (double) (LFO_LENGHT)); // Sinus
+ x += 1.0;
+ x /= 2.0; // positive only
+ x *= 11.8 / ENV_STEP; // ajusted to MAX enveloppe modulation
+
+ g.LFO_ENV_TAB [i] = (int) x;
+
+ x = sin(2.0 * PI * (double) (i) / (double) (LFO_LENGHT)); // Sinus
+ x *= (double) ((1 << (LFO_HBITS - 1)) - 1);
+
+ g.LFO_FREQ_TAB [i] = (int) x;
+
+ }
+
+ // Tableau Enveloppe :
+ // g.ENV_TAB [0] -> g.ENV_TAB [ENV_LENGHT - 1] = attack curve
+ // g.ENV_TAB [ENV_LENGHT] -> g.ENV_TAB [2 * ENV_LENGHT - 1] = decay curve
+
+ for(i = 0; i < ENV_LENGHT; i++)
+ {
+ // Attack curve (x^8 - music level 2 Vectorman 2)
+ double x = pow(((double) ((ENV_LENGHT - 1) - i) / (double) (ENV_LENGHT)), 8);
+ x *= ENV_LENGHT;
+
+ g.ENV_TAB [i] = (int) x;
+
+ // Decay curve (just linear)
+ x = pow(((double) (i) / (double) (ENV_LENGHT)), 1);
+ x *= ENV_LENGHT;
+
+ g.ENV_TAB [ENV_LENGHT + i] = (int) x;
+ }
+ for ( i = 0; i < 8; i++ )
+ g.ENV_TAB [i + ENV_LENGHT * 2] = 0;
+
+ g.ENV_TAB [ENV_END >> ENV_LBITS] = ENV_LENGHT - 1; // for the stopped state
+
+ // Tableau pour la conversion Attack -> Decay and Decay -> Attack
+
+ int j = ENV_LENGHT - 1;
+ for ( i = 0; i < ENV_LENGHT; i++ )
+ {
+ while ( j && g.ENV_TAB [j] < i )
+ j--;
+
+ g.DECAY_TO_ATTACK [i] = j << ENV_LBITS;
+ }
+
+ // Tableau pour le Substain Level
+
+ for(i = 0; i < 15; i++)
+ {
+ double x = i * 3; // 3 and not 6 (Mickey Mania first music for test)
+ x /= ENV_STEP;
+
+ g.SL_TAB [i] = ((int) x << ENV_LBITS) + ENV_DECAY;
+ }
+
+ g.SL_TAB [15] = ((ENV_LENGHT - 1) << ENV_LBITS) + ENV_DECAY; // special case : volume off
+
+ // Tableau Frequency Step
+
+ for(i = 0; i < 2048; i++)
+ {
+ double x = (double) (i) * Frequence;
+
+#if ((SIN_LBITS + SIN_HBITS - (21 - 7)) < 0)
+ x /= (double) (1 << ((21 - 7) - SIN_LBITS - SIN_HBITS));
+#else
+ x *= (double) (1 << (SIN_LBITS + SIN_HBITS - (21 - 7)));
+#endif
+
+ x /= 2.0; // because MUL = value * 2
+
+ g.FINC_TAB [i] = (unsigned int) x;
+ }
+
+ // Tableaux Attack & Decay Rate
+
+ for(i = 0; i < 4; i++)
+ {
+ g.AR_TAB [i] = 0;
+ g.DR_TAB [i] = 0;
+ }
+
+ for(i = 0; i < 60; i++)
+ {
+ double x = Frequence;
+
+ x *= 1.0 + ((i & 3) * 0.25); // bits 0-1 : x1.00, x1.25, x1.50, x1.75
+ x *= (double) (1 << ((i >> 2))); // bits 2-5 : shift bits (x2^0 - x2^15)
+ x *= (double) (ENV_LENGHT << ENV_LBITS); // on ajuste pour le tableau g.ENV_TAB
+
+ g.AR_TAB [i + 4] = (unsigned int) (x / AR_RATE);
+ g.DR_TAB [i + 4] = (unsigned int) (x / DR_RATE);
+ }
+
+ for(i = 64; i < 96; i++)
+ {
+ g.AR_TAB [i] = g.AR_TAB [63];
+ g.DR_TAB [i] = g.DR_TAB [63];
+
+ g.NULL_RATE [i - 64] = 0;
+ }
+
+ for ( i = 96; i < 128; i++ )
+ g.AR_TAB [i] = 0;
+
+ // Tableau Detune
+
+ for(i = 0; i < 4; i++)
+ {
+ for (int j = 0; j < 32; j++)
+ {
+#if ((SIN_LBITS + SIN_HBITS - 21) < 0)
+ double y = (double) DT_DEF_TAB [(i << 5) + j] * Frequence / (double) (1 << (21 - SIN_LBITS - SIN_HBITS));
+#else
+ double y = (double) DT_DEF_TAB [(i << 5) + j] * Frequence * (double) (1 << (SIN_LBITS + SIN_HBITS - 21));
+#endif
+
+ g.DT_TAB [i + 0] [j] = (int) y;
+ g.DT_TAB [i + 4] [j] = (int) -y;
+ }
+ }
+
+ // Tableau LFO
+ g.LFO_INC_TAB [0] = (unsigned int) (3.98 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
+ g.LFO_INC_TAB [1] = (unsigned int) (5.56 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
+ g.LFO_INC_TAB [2] = (unsigned int) (6.02 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
+ g.LFO_INC_TAB [3] = (unsigned int) (6.37 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
+ g.LFO_INC_TAB [4] = (unsigned int) (6.88 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
+ g.LFO_INC_TAB [5] = (unsigned int) (9.63 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
+ g.LFO_INC_TAB [6] = (unsigned int) (48.1 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
+ g.LFO_INC_TAB [7] = (unsigned int) (72.2 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
+
+ reset();
+}
+
+const char* Ym2612_Emu::set_rate( double sample_rate, double clock_rate )
+{
+ if ( !impl )
+ {
+ impl = (Ym2612_Impl*) malloc( sizeof *impl );
+ if ( !impl )
+ return "Out of memory";
+ impl->mute_mask = 0;
+ }
+ memset( &impl->YM2612, 0, sizeof impl->YM2612 );
+
+ impl->set_rate( sample_rate, clock_rate );
+
+ return 0;
+}
+
+Ym2612_Emu::~Ym2612_Emu()
+{
+ free( impl );
+}
+
+inline void Ym2612_Impl::write0( int opn_addr, int data )
+{
+ assert( (unsigned) data <= 0xFF );
+
+ if ( opn_addr < 0x30 )
+ {
+ YM2612.REG [0] [opn_addr] = data;
+ YM_SET( opn_addr, data );
+ }
+ else if ( YM2612.REG [0] [opn_addr] != data )
+ {
+ YM2612.REG [0] [opn_addr] = data;
+
+ if ( opn_addr < 0xA0 )
+ SLOT_SET( opn_addr, data );
+ else
+ CHANNEL_SET( opn_addr, data );
+ }
+}
+
+inline void Ym2612_Impl::write1( int opn_addr, int data )
+{
+ assert( (unsigned) data <= 0xFF );
+
+ if ( opn_addr >= 0x30 && YM2612.REG [1] [opn_addr] != data )
+ {
+ YM2612.REG [1] [opn_addr] = data;
+
+ if ( opn_addr < 0xA0 )
+ SLOT_SET( opn_addr + 0x100, data );
+ else
+ CHANNEL_SET( opn_addr + 0x100, data );
+ }
+}
+
+void Ym2612_Emu::reset()
+{
+ impl->reset();
+}
+
+void Ym2612_Impl::reset()
+{
+ g.LFOcnt = 0;
+ YM2612.TimerA = 0;
+ YM2612.TimerAL = 0;
+ YM2612.TimerAcnt = 0;
+ YM2612.TimerB = 0;
+ YM2612.TimerBL = 0;
+ YM2612.TimerBcnt = 0;
+ YM2612.DAC = 0;
+
+ YM2612.Status = 0;
+
+ int i;
+ for ( i = 0; i < channel_count; i++ )
+ {
+ channel_t& ch = YM2612.CHANNEL [i];
+
+ ch.LEFT = ~0;
+ ch.RIGHT = ~0;
+ ch.ALGO = 0;
+ ch.FB = 31;
+ ch.FMS = 0;
+ ch.AMS = 0;
+
+ for ( int j = 0 ;j < 4 ; j++ )
+ {
+ ch.S0_OUT [j] = 0;
+ ch.FNUM [j] = 0;
+ ch.FOCT [j] = 0;
+ ch.KC [j] = 0;
+
+ ch.SLOT [j].Fcnt = 0;
+ ch.SLOT [j].Finc = 0;
+ ch.SLOT [j].Ecnt = ENV_END; // Put it at the end of Decay phase...
+ ch.SLOT [j].Einc = 0;
+ ch.SLOT [j].Ecmp = 0;
+ ch.SLOT [j].Ecurp = RELEASE;
+
+ ch.SLOT [j].ChgEnM = 0;
+ }
+ }
+
+ for ( i = 0; i < 0x100; i++ )
+ {
+ YM2612.REG [0] [i] = -1;
+ YM2612.REG [1] [i] = -1;
+ }
+
+ for ( i = 0xB6; i >= 0xB4; i-- )
+ {
+ write0( i, 0xC0 );
+ write1( i, 0xC0 );
+ }
+
+ for ( i = 0xB2; i >= 0x22; i-- )
+ {
+ write0( i, 0 );
+ write1( i, 0 );
+ }
+
+ write0( 0x2A, 0x80 );
+}
+
+void Ym2612_Emu::write0( int addr, int data )
+{
+ impl->write0( addr, data );
+}
+
+void Ym2612_Emu::write1( int addr, int data )
+{
+ impl->write1( addr, data );
+}
+
+void Ym2612_Emu::mute_voices( int mask ) { impl->mute_mask = mask; }
+
+static void update_envelope_( slot_t* sl )
+{
+ switch ( sl->Ecurp )
+ {
+ case 0:
+ // Env_Attack_Next
+
+ // Verified with Gynoug even in HQ (explode SFX)
+ sl->Ecnt = ENV_DECAY;
+
+ sl->Einc = sl->EincD;
+ sl->Ecmp = sl->SLL;
+ sl->Ecurp = DECAY;
+ break;
+
+ case 1:
+ // Env_Decay_Next
+
+ // Verified with Gynoug even in HQ (explode SFX)
+ sl->Ecnt = sl->SLL;
+
+ sl->Einc = sl->EincS;
+ sl->Ecmp = ENV_END;
+ sl->Ecurp = SUBSTAIN;
+ break;
+
+ case 2:
+ // Env_Substain_Next(slot_t *SL)
+ if (sl->SEG & 8) // SSG envelope type
+ {
+ int release = sl->SEG & 1;
+
+ if ( !release )
+ {
+ // re KEY ON
+
+ // sl->Fcnt = 0;
+ // sl->ChgEnM = ~0;
+
+ sl->Ecnt = 0;
+ sl->Einc = sl->EincA;
+ sl->Ecmp = ENV_DECAY;
+ sl->Ecurp = ATTACK;
+ }
+
+ set_seg( *sl, (sl->SEG << 1) & 4 );
+
+ if ( !release )
+ break;
+ }
+ // fall through
+
+ case 3:
+ // Env_Release_Next
+ sl->Ecnt = ENV_END;
+ sl->Einc = 0;
+ sl->Ecmp = ENV_END + 1;
+ break;
+
+ // default: no op
+ }
+}
+
+inline void update_envelope( slot_t& sl )
+{
+ int ecmp = sl.Ecmp;
+ if ( (sl.Ecnt += sl.Einc) >= ecmp )
+ update_envelope_( &sl );
+}
+
+template<int algo>
+struct ym2612_update_chan {
+ static void func( tables_t&, channel_t&, Ym2612_Emu::sample_t*, int );
+};
+
+typedef void (*ym2612_update_chan_t)( tables_t&, channel_t&, Ym2612_Emu::sample_t*, int );
+
+template<int algo>
+void ym2612_update_chan<algo>::func( tables_t& g, channel_t& ch,
+ Ym2612_Emu::sample_t* buf, int length )
+{
+ int not_end = ch.SLOT [S3].Ecnt - ENV_END;
+
+ // algo is a compile-time constant, so all conditions based on it are resolved
+ // during compilation
+
+ // special cases
+ if ( algo == 7 )
+ not_end |= ch.SLOT [S0].Ecnt - ENV_END;
+
+ if ( algo >= 5 )
+ not_end |= ch.SLOT [S2].Ecnt - ENV_END;
+
+ if ( algo >= 4 )
+ not_end |= ch.SLOT [S1].Ecnt - ENV_END;
+
+ int CH_S0_OUT_1 = ch.S0_OUT [1];
+
+ int in0 = ch.SLOT [S0].Fcnt;
+ int in1 = ch.SLOT [S1].Fcnt;
+ int in2 = ch.SLOT [S2].Fcnt;
+ int in3 = ch.SLOT [S3].Fcnt;
+
+ int YM2612_LFOinc = g.LFOinc;
+ int YM2612_LFOcnt = g.LFOcnt + YM2612_LFOinc;
+
+ if ( !not_end )
+ return;
+
+ do
+ {
+ // envelope
+ int const env_LFO = g.LFO_ENV_TAB [YM2612_LFOcnt >> LFO_LBITS & LFO_MASK];
+
+ short const* const ENV_TAB = g.ENV_TAB;
+
+ #define CALC_EN( x ) \
+ int temp##x = ENV_TAB [ch.SLOT [S##x].Ecnt >> ENV_LBITS] + ch.SLOT [S##x].TLL; \
+ int en##x = ((temp##x ^ ch.SLOT [S##x].env_xor) + (env_LFO >> ch.SLOT [S##x].AMS)) & \
+ ((temp##x - ch.SLOT [S##x].env_max) >> 31);
+
+ CALC_EN( 0 )
+ CALC_EN( 1 )
+ CALC_EN( 2 )
+ CALC_EN( 3 )
+
+ int const* const TL_TAB = g.TL_TAB;
+
+ #define SINT( i, o ) (TL_TAB [g.SIN_TAB [(i)] + (o)])
+
+ // feedback
+ int CH_S0_OUT_0 = ch.S0_OUT [0];
+ {
+ int temp = in0 + ((CH_S0_OUT_0 + CH_S0_OUT_1) >> ch.FB);
+ CH_S0_OUT_1 = CH_S0_OUT_0;
+ CH_S0_OUT_0 = SINT( (temp >> SIN_LBITS) & SIN_MASK, en0 );
+ }
+
+ int CH_OUTd;
+ if ( algo == 0 )
+ {
+ int temp = in1 + CH_S0_OUT_1;
+ temp = in2 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en1 );
+ temp = in3 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en2 );
+ CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
+ }
+ else if ( algo == 1 )
+ {
+ int temp = in2 + CH_S0_OUT_1 + SINT( (in1 >> SIN_LBITS) & SIN_MASK, en1 );
+ temp = in3 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en2 );
+ CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
+ }
+ else if ( algo == 2 )
+ {
+ int temp = in2 + SINT( (in1 >> SIN_LBITS) & SIN_MASK, en1 );
+ temp = in3 + CH_S0_OUT_1 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en2 );
+ CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
+ }
+ else if ( algo == 3 )
+ {
+ int temp = in1 + CH_S0_OUT_1;
+ temp = in3 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en1 ) +
+ SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 );
+ CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
+ }
+ else if ( algo == 4 )
+ {
+ int temp = in3 + SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 );
+ CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 ) +
+ SINT( ((in1 + CH_S0_OUT_1) >> SIN_LBITS) & SIN_MASK, en1 );
+ //DO_LIMIT
+ }
+ else if ( algo == 5 )
+ {
+ int temp = CH_S0_OUT_1;
+ CH_OUTd = SINT( ((in3 + temp) >> SIN_LBITS) & SIN_MASK, en3 ) +
+ SINT( ((in1 + temp) >> SIN_LBITS) & SIN_MASK, en1 ) +
+ SINT( ((in2 + temp) >> SIN_LBITS) & SIN_MASK, en2 );
+ //DO_LIMIT
+ }
+ else if ( algo == 6 )
+ {
+ CH_OUTd = SINT( (in3 >> SIN_LBITS) & SIN_MASK, en3 ) +
+ SINT( ((in1 + CH_S0_OUT_1) >> SIN_LBITS) & SIN_MASK, en1 ) +
+ SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 );
+ //DO_LIMIT
+ }
+ else if ( algo == 7 )
+ {
+ CH_OUTd = SINT( (in3 >> SIN_LBITS) & SIN_MASK, en3 ) +
+ SINT( (in1 >> SIN_LBITS) & SIN_MASK, en1 ) +
+ SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 ) + CH_S0_OUT_1;
+ //DO_LIMIT
+ }
+
+ CH_OUTd >>= MAX_OUT_BITS - output_bits + 2;
+
+ // update phase
+ unsigned freq_LFO = ((g.LFO_FREQ_TAB [YM2612_LFOcnt >> LFO_LBITS & LFO_MASK] *
+ ch.FMS) >> (LFO_HBITS - 1 + 1)) + (1L << (LFO_FMS_LBITS - 1));
+ YM2612_LFOcnt += YM2612_LFOinc;
+ in0 += (ch.SLOT [S0].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
+ in1 += (ch.SLOT [S1].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
+ in2 += (ch.SLOT [S2].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
+ in3 += (ch.SLOT [S3].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
+
+ int t0 = buf [0] + (CH_OUTd & ch.LEFT);
+ int t1 = buf [1] + (CH_OUTd & ch.RIGHT);
+
+ update_envelope( ch.SLOT [0] );
+ update_envelope( ch.SLOT [1] );
+ update_envelope( ch.SLOT [2] );
+ update_envelope( ch.SLOT [3] );
+
+ ch.S0_OUT [0] = CH_S0_OUT_0;
+ buf [0] = t0;
+ buf [1] = t1;
+ buf += 2;
+ }
+ while ( --length );
+
+ ch.S0_OUT [1] = CH_S0_OUT_1;
+
+ ch.SLOT [S0].Fcnt = in0;
+ ch.SLOT [S1].Fcnt = in1;
+ ch.SLOT [S2].Fcnt = in2;
+ ch.SLOT [S3].Fcnt = in3;
+}
+
+static const ym2612_update_chan_t UPDATE_CHAN [8] = {
+ &ym2612_update_chan<0>::func,
+ &ym2612_update_chan<1>::func,
+ &ym2612_update_chan<2>::func,
+ &ym2612_update_chan<3>::func,
+ &ym2612_update_chan<4>::func,
+ &ym2612_update_chan<5>::func,
+ &ym2612_update_chan<6>::func,
+ &ym2612_update_chan<7>::func
+};
+
+void Ym2612_Impl::run_timer( int length )
+{
+ int const step = 6;
+ int remain = length;
+ do
+ {
+ int n = step;
+ if ( n > remain )
+ n = remain;
+ remain -= n;
+
+ long i = n * YM2612.TimerBase;
+ if (YM2612.Mode & 1) // Timer A ON ?
+ {
+ // if ((YM2612.TimerAcnt -= 14073) <= 0) // 13879=NTSC (old: 14475=NTSC 14586=PAL)
+ if ((YM2612.TimerAcnt -= i) <= 0)
+ {
+ // timer a overflow
+
+ YM2612.Status |= (YM2612.Mode & 0x04) >> 2;
+ YM2612.TimerAcnt += YM2612.TimerAL;
+
+ if (YM2612.Mode & 0x80)
+ {
+ KEY_ON( YM2612.CHANNEL [2], 0 );
+ KEY_ON( YM2612.CHANNEL [2], 1 );
+ KEY_ON( YM2612.CHANNEL [2], 2 );
+ KEY_ON( YM2612.CHANNEL [2], 3 );
+ }
+ }
+ }
+
+ if (YM2612.Mode & 2) // Timer B ON ?
+ {
+ // if ((YM2612.TimerBcnt -= 14073) <= 0) // 13879=NTSC (old: 14475=NTSC 14586=PAL)
+ if ((YM2612.TimerBcnt -= i) <= 0)
+ {
+ // timer b overflow
+ YM2612.Status |= (YM2612.Mode & 0x08) >> 2;
+ YM2612.TimerBcnt += YM2612.TimerBL;
+ }
+ }
+ }
+ while ( remain > 0 );
+}
+
+void Ym2612_Impl::run( int pair_count, Ym2612_Emu::sample_t* out )
+{
+ if ( pair_count <= 0 )
+ return;
+
+ if ( YM2612.Mode & 3 )
+ run_timer( pair_count );
+
+ // Mise à jour des pas des compteurs-frequences s'ils ont ete modifies
+
+ for ( int chi = 0; chi < channel_count; chi++ )
+ {
+ channel_t& ch = YM2612.CHANNEL [chi];
+ if ( ch.SLOT [0].Finc != -1 )
+ continue;
+
+ int i2 = 0;
+ if ( chi == 2 && (YM2612.Mode & 0x40) )
+ i2 = 2;
+
+ for ( int i = 0; i < 4; i++ )
+ {
+ // static int seq [4] = { 2, 1, 3, 0 };
+ // if ( i2 ) i2 = seq [i];
+
+ slot_t& sl = ch.SLOT [i];
+ int finc = g.FINC_TAB [ch.FNUM [i2]] >> (7 - ch.FOCT [i2]);
+ int ksr = ch.KC [i2] >> sl.KSR_S; // keycode attenuation
+ sl.Finc = (finc + sl.DT [ch.KC [i2]]) * sl.MUL;
+ if (sl.KSR != ksr) // si le KSR a change alors
+ { // les differents taux pour l'enveloppe sont mis à jour
+ sl.KSR = ksr;
+
+ sl.EincA = sl.AR [ksr];
+ sl.EincD = sl.DR [ksr];
+ sl.EincS = sl.SR [ksr];
+ sl.EincR = sl.RR [ksr];
+
+ if (sl.Ecurp == ATTACK)
+ {
+ sl.Einc = sl.EincA;
+ }
+ else if (sl.Ecurp == DECAY)
+ {
+ sl.Einc = sl.EincD;
+ }
+ else if (sl.Ecnt < ENV_END)
+ {
+ if (sl.Ecurp == SUBSTAIN)
+ sl.Einc = sl.EincS;
+ else if (sl.Ecurp == RELEASE)
+ sl.Einc = sl.EincR;
+ }
+ }
+
+ if ( i2 )
+ i2 = (i2 ^ 2) ^ (i2 >> 1);
+ }
+ }
+
+ for ( int i = 0; i < channel_count; i++ )
+ {
+ if ( !(mute_mask & (1 << i)) && (i != 5 || !YM2612.DAC) )
+ UPDATE_CHAN [YM2612.CHANNEL [i].ALGO]( g, YM2612.CHANNEL [i], out, pair_count );
+ }
+
+ g.LFOcnt += g.LFOinc * pair_count;
+}
+
+void Ym2612_Emu::run( int pair_count, sample_t* out ) { impl->run( pair_count, out ); }
diff --git a/src/console/Ym2612_Emu.cxx b/src/console/Ym2612_Emu.cxx
deleted file mode 100644
index cfb3588e545e..000000000000
--- a/src/console/Ym2612_Emu.cxx
+++ /dev/null
@@ -1,1319 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-// Based on Gens 2.10 ym2612.c
-
-#include "Ym2612_Emu.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <stdio.h>
-#include <math.h>
-
-/* Copyright (C) 2002 Stéphane Dallongeville (gens AT consolemul.com) */
-/* Copyright (C) 2004-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-// This is mostly the original source in its C style and all.
-//
-// Somewhat optimized and simplified. Uses a template to generate the many
-// variants of Update_Chan. Rewrote header file. In need of full rewrite by
-// someone more familiar with FM sound and the YM2612. Has some inaccuracies
-// compared to the Sega Genesis sound, particularly being mixed at such a
-// high sample accuracy (the Genesis sounds like it has only 8 bit samples).
-// - Shay
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-const int output_bits = 14;
-
-struct slot_t
-{
- const int *DT; // parametre detune
- int MUL; // parametre "multiple de frequence"
- int TL; // Total Level = volume lorsque l'enveloppe est au plus haut
- int TLL; // Total Level ajusted
- int SLL; // Sustin Level (ajusted) = volume où l'enveloppe termine sa premiere phase de regression
- int KSR_S; // Key Scale Rate Shift = facteur de prise en compte du KSL dans la variations de l'enveloppe
- int KSR; // Key Scale Rate = cette valeur est calculee par rapport à la frequence actuelle, elle va influer
- // sur les differents parametres de l'enveloppe comme l'attaque, le decay ... comme dans la realite !
- int SEG; // Type enveloppe SSG
- int env_xor;
- int env_max;
-
- const int *AR; // Attack Rate (table pointeur) = Taux d'attaque (AR[KSR])
- const int *DR; // Decay Rate (table pointeur) = Taux pour la regression (DR[KSR])
- const int *SR; // Sustin Rate (table pointeur) = Taux pour le maintien (SR[KSR])
- const int *RR; // Release Rate (table pointeur) = Taux pour le rel'chement (RR[KSR])
- int Fcnt; // Frequency Count = compteur-frequence pour determiner l'amplitude actuelle (SIN[Finc >> 16])
- int Finc; // frequency step = pas d'incrementation du compteur-frequence
- // plus le pas est grand, plus la frequence est aïgu (ou haute)
- int Ecurp; // Envelope current phase = cette variable permet de savoir dans quelle phase
- // de l'enveloppe on se trouve, par exemple phase d'attaque ou phase de maintenue ...
- // en fonction de la valeur de cette variable, on va appeler une fonction permettant
- // de mettre à jour l'enveloppe courante.
- int Ecnt; // Envelope counter = le compteur-enveloppe permet de savoir où l'on se trouve dans l'enveloppe
- int Einc; // Envelope step courant
- int Ecmp; // Envelope counter limite pour la prochaine phase
- int EincA; // Envelope step for Attack = pas d'incrementation du compteur durant la phase d'attaque
- // cette valeur est egal à AR[KSR]
- int EincD; // Envelope step for Decay = pas d'incrementation du compteur durant la phase de regression
- // cette valeur est egal à DR[KSR]
- int EincS; // Envelope step for Sustain = pas d'incrementation du compteur durant la phase de maintenue
- // cette valeur est egal à SR[KSR]
- int EincR; // Envelope step for Release = pas d'incrementation du compteur durant la phase de rel'chement
- // cette valeur est egal à RR[KSR]
- int *OUTp; // pointeur of SLOT output = pointeur permettant de connecter la sortie de ce slot à l'entree
- // d'un autre ou carrement à la sortie de la voie
- int INd; // input data of the slot = donnees en entree du slot
- int ChgEnM; // Change envelop mask.
- int AMS; // AMS depth level of this SLOT = degre de modulation de l'amplitude par le LFO
- int AMSon; // AMS enable flag = drapeau d'activation de l'AMS
-};
-
-struct channel_t
-{
- int S0_OUT[4]; // anciennes sorties slot 0 (pour le feed back)
- int LEFT; // LEFT enable flag
- int RIGHT; // RIGHT enable flag
- int ALGO; // Algorythm = determine les connections entre les operateurs
- int FB; // shift count of self feed back = degre de "Feed-Back" du SLOT 1 (il est son unique entree)
- int FMS; // Frequency Modulation Sensitivity of channel = degre de modulation de la frequence sur la voie par le LFO
- int AMS; // Amplitude Modulation Sensitivity of channel = degre de modulation de l'amplitude sur la voie par le LFO
- int FNUM[4]; // hauteur frequence de la voie (+ 3 pour le mode special)
- int FOCT[4]; // octave de la voie (+ 3 pour le mode special)
- int KC[4]; // Key Code = valeur fonction de la frequence (voir KSR pour les slots, KSR = KC >> KSR_S)
- slot_t SLOT[4]; // four slot.operators = les 4 slots de la voie
- int FFlag; // Frequency step recalculation flag
-};
-
-struct state_t
-{
- int TimerBase; // TimerBase calculation
- int Status; // YM2612 Status (timer overflow)
- int TimerA; // timerA limit = valeur jusqu'à laquelle le timer A doit compter
- int TimerAL;
- int TimerAcnt; // timerA counter = valeur courante du Timer A
- int TimerB; // timerB limit = valeur jusqu'à laquelle le timer B doit compter
- int TimerBL;
- int TimerBcnt; // timerB counter = valeur courante du Timer B
- int Mode; // Mode actuel des voie 3 et 6 (normal / special)
- int DAC; // DAC enabled flag
- channel_t CHANNEL[Ym2612_Emu::channel_count]; // Les 6 voies du YM2612
- int REG[2][0x100]; // Sauvegardes des valeurs de tout les registres, c'est facultatif
- // cela nous rend le debuggage plus facile
-};
-
-#ifndef PI
-#define PI 3.14159265358979323846
-#endif
-
-#define ATTACK 0
-#define DECAY 1
-#define SUBSTAIN 2
-#define RELEASE 3
-
-// SIN_LBITS <= 16
-// LFO_HBITS <= 16
-// (SIN_LBITS + SIN_HBITS) <= 26
-// (ENV_LBITS + ENV_HBITS) <= 28
-// (LFO_LBITS + LFO_HBITS) <= 28
-
-#define SIN_HBITS 12 // Sinus phase counter int part
-#define SIN_LBITS (26 - SIN_HBITS) // Sinus phase counter float part (best setting)
-
-#if (SIN_LBITS > 16)
-#define SIN_LBITS 16 // Can't be greater than 16 bits
-#endif
-
-#define ENV_HBITS 12 // Env phase counter int part
-#define ENV_LBITS (28 - ENV_HBITS) // Env phase counter float part (best setting)
-
-#define LFO_HBITS 10 // LFO phase counter int part
-#define LFO_LBITS (28 - LFO_HBITS) // LFO phase counter float part (best setting)
-
-#define SIN_LENGHT (1 << SIN_HBITS)
-#define ENV_LENGHT (1 << ENV_HBITS)
-#define LFO_LENGHT (1 << LFO_HBITS)
-
-#define TL_LENGHT (ENV_LENGHT * 3) // Env + TL scaling + LFO
-
-#define SIN_MASK (SIN_LENGHT - 1)
-#define ENV_MASK (ENV_LENGHT - 1)
-#define LFO_MASK (LFO_LENGHT - 1)
-
-#define ENV_STEP (96.0 / ENV_LENGHT) // ENV_MAX = 96 dB
-
-#define ENV_ATTACK ((ENV_LENGHT * 0) << ENV_LBITS)
-#define ENV_DECAY ((ENV_LENGHT * 1) << ENV_LBITS)
-#define ENV_END ((ENV_LENGHT * 2) << ENV_LBITS)
-
-#define MAX_OUT_BITS (SIN_HBITS + SIN_LBITS + 2) // Modulation = -4 <--> +4
-#define MAX_OUT ((1 << MAX_OUT_BITS) - 1)
-
-#define PG_CUT_OFF ((int) (78.0 / ENV_STEP))
-#define ENV_CUT_OFF ((int) (68.0 / ENV_STEP))
-
-#define AR_RATE 399128
-#define DR_RATE 5514396
-
-//#define AR_RATE 426136
-//#define DR_RATE (AR_RATE * 12)
-
-#define LFO_FMS_LBITS 9 // FIXED (LFO_FMS_BASE gives somethink as 1)
-#define LFO_FMS_BASE ((int) (0.05946309436 * 0.0338 * (double) (1 << LFO_FMS_LBITS)))
-
-#define S0 0 // Stupid typo of the YM2612
-#define S1 2
-#define S2 1
-#define S3 3
-
-inline void set_seg( slot_t& s, int seg )
-{
- s.env_xor = 0;
- s.env_max = INT_MAX;
- s.SEG = seg;
- if ( seg & 4 )
- {
- s.env_xor = ENV_MASK;
- s.env_max = ENV_MASK;
- }
-}
-
-struct tables_t
-{
- short SIN_TAB [SIN_LENGHT]; // SINUS TABLE (offset into TL TABLE)
- int LFOcnt; // LFO counter = compteur-frequence pour le LFO
- int LFOinc; // LFO step counter = pas d'incrementation du compteur-frequence du LFO
- // plus le pas est grand, plus la frequence est grande
- unsigned int AR_TAB [128]; // Attack rate table
- unsigned int DR_TAB [96]; // Decay rate table
- unsigned int DT_TAB [8] [32]; // Detune table
- unsigned int SL_TAB [16]; // Substain level table
- unsigned int NULL_RATE [32]; // Table for NULL rate
- int LFO_INC_TAB [8]; // LFO step table
-
- short ENV_TAB [2 * ENV_LENGHT + 8]; // ENV CURVE TABLE (attack & decay)
-
- short LFO_ENV_TAB [LFO_LENGHT]; // LFO AMS TABLE (adjusted for 11.8 dB)
- short LFO_FREQ_TAB [LFO_LENGHT]; // LFO FMS TABLE
- int TL_TAB [TL_LENGHT * 2]; // TOTAL LEVEL TABLE (positif and minus)
- unsigned int DECAY_TO_ATTACK [ENV_LENGHT]; // Conversion from decay to attack phase
- unsigned int FINC_TAB [2048]; // Frequency step table
-};
-
-static const unsigned char DT_DEF_TAB [4 * 32] =
-{
-// FD = 0
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
-// FD = 1
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
- 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
-
-// FD = 2
- 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
- 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 16, 16, 16, 16,
-
-// FD = 3
- 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
- 8 , 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 20, 22, 22, 22, 22
-};
-
-static const unsigned char FKEY_TAB [16] =
-{
- 0, 0, 0, 0,
- 0, 0, 0, 1,
- 2, 3, 3, 3,
- 3, 3, 3, 3
-};
-
-static const unsigned char LFO_AMS_TAB [4] =
-{
- 31, 4, 1, 0
-};
-
-static const unsigned char LFO_FMS_TAB [8] =
-{
- LFO_FMS_BASE * 0, LFO_FMS_BASE * 1,
- LFO_FMS_BASE * 2, LFO_FMS_BASE * 3,
- LFO_FMS_BASE * 4, LFO_FMS_BASE * 6,
- LFO_FMS_BASE * 12, LFO_FMS_BASE * 24
-};
-
-inline void YM2612_Special_Update() { }
-
-struct Ym2612_Impl
-{
- enum { channel_count = Ym2612_Emu::channel_count };
-
- state_t YM2612;
- int mute_mask;
- tables_t g;
-
- void KEY_ON( channel_t&, int );
- void KEY_OFF( channel_t&, int );
- int SLOT_SET( int, int );
- int CHANNEL_SET( int, int );
- int YM_SET( int, int );
-
- void set_rate( double sample_rate, double clock_factor );
- void reset();
- void write0( int addr, int data );
- void write1( int addr, int data );
- void run_timer( int );
- void run( int pair_count, Ym2612_Emu::sample_t* );
-};
-
-void Ym2612_Impl::KEY_ON( channel_t& ch, int nsl)
-{
- slot_t *SL = &(ch.SLOT [nsl]); // on recupere le bon pointeur de slot
-
- if (SL->Ecurp == RELEASE) // la touche est-elle rel'chee ?
- {
- SL->Fcnt = 0;
-
- // Fix Ecco 2 splash sound
-
- SL->Ecnt = (g.DECAY_TO_ATTACK [g.ENV_TAB [SL->Ecnt >> ENV_LBITS]] + ENV_ATTACK) & SL->ChgEnM;
- SL->ChgEnM = ~0;
-
-// SL->Ecnt = g.DECAY_TO_ATTACK [g.ENV_TAB [SL->Ecnt >> ENV_LBITS]] + ENV_ATTACK;
-// SL->Ecnt = 0;
-
- SL->Einc = SL->EincA;
- SL->Ecmp = ENV_DECAY;
- SL->Ecurp = ATTACK;
- }
-}
-
-
-void Ym2612_Impl::KEY_OFF(channel_t& ch, int nsl)
-{
- slot_t *SL = &(ch.SLOT [nsl]); // on recupere le bon pointeur de slot
-
- if (SL->Ecurp != RELEASE) // la touche est-elle appuyee ?
- {
- if (SL->Ecnt < ENV_DECAY) // attack phase ?
- {
- SL->Ecnt = (g.ENV_TAB [SL->Ecnt >> ENV_LBITS] << ENV_LBITS) + ENV_DECAY;
- }
-
- SL->Einc = SL->EincR;
- SL->Ecmp = ENV_END;
- SL->Ecurp = RELEASE;
- }
-}
-
-
-int Ym2612_Impl::SLOT_SET( int Adr, int data )
-{
- int nch = Adr & 3;
- if ( nch == 3 )
- return 1;
-
- channel_t& ch = YM2612.CHANNEL [nch + (Adr & 0x100 ? 3 : 0)];
- slot_t& sl = ch.SLOT [(Adr >> 2) & 3];
-
- switch ( Adr & 0xF0 )
- {
- case 0x30:
- if ( (sl.MUL = (data & 0x0F)) != 0 ) sl.MUL <<= 1;
- else sl.MUL = 1;
-
- sl.DT = (int*) g.DT_TAB [(data >> 4) & 7];
-
- ch.SLOT [0].Finc = -1;
-
- break;
-
- case 0x40:
- sl.TL = data & 0x7F;
-
- // SOR2 do a lot of TL adjustement and this fix R.Shinobi jump sound...
- YM2612_Special_Update();
-
-#if ((ENV_HBITS - 7) < 0)
- sl.TLL = sl.TL >> (7 - ENV_HBITS);
-#else
- sl.TLL = sl.TL << (ENV_HBITS - 7);
-#endif
-
- break;
-
- case 0x50:
- sl.KSR_S = 3 - (data >> 6);
-
- ch.SLOT [0].Finc = -1;
-
- if (data &= 0x1F) sl.AR = (int*) &g.AR_TAB [data << 1];
- else sl.AR = (int*) &g.NULL_RATE [0];
-
- sl.EincA = sl.AR [sl.KSR];
- if (sl.Ecurp == ATTACK) sl.Einc = sl.EincA;
- break;
-
- case 0x60:
- if ( (sl.AMSon = (data & 0x80)) != 0 ) sl.AMS = ch.AMS;
- else sl.AMS = 31;
-
- if (data &= 0x1F) sl.DR = (int*) &g.DR_TAB [data << 1];
- else sl.DR = (int*) &g.NULL_RATE [0];
-
- sl.EincD = sl.DR [sl.KSR];
- if (sl.Ecurp == DECAY) sl.Einc = sl.EincD;
- break;
-
- case 0x70:
- if (data &= 0x1F) sl.SR = (int*) &g.DR_TAB [data << 1];
- else sl.SR = (int*) &g.NULL_RATE [0];
-
- sl.EincS = sl.SR [sl.KSR];
- if ((sl.Ecurp == SUBSTAIN) && (sl.Ecnt < ENV_END)) sl.Einc = sl.EincS;
- break;
-
- case 0x80:
- sl.SLL = g.SL_TAB [data >> 4];
-
- sl.RR = (int*) &g.DR_TAB [((data & 0xF) << 2) + 2];
-
- sl.EincR = sl.RR [sl.KSR];
- if ((sl.Ecurp == RELEASE) && (sl.Ecnt < ENV_END)) sl.Einc = sl.EincR;
- break;
-
- case 0x90:
- // SSG-EG envelope shapes :
- /*
- E At Al H
-
- 1 0 0 0 \\\\
- 1 0 0 1 \___
- 1 0 1 0 \/\/
- 1 0 1 1 \
- 1 1 0 0 ////
- 1 1 0 1 /
- 1 1 1 0 /\/\
- 1 1 1 1 /___
-
- E = SSG-EG enable
- At = Start negate
- Al = Altern
- H = Hold */
-
- set_seg( sl, (data & 8) ? (data & 0x0F) : 0 );
- break;
- }
-
- return 0;
-}
-
-
-int Ym2612_Impl::CHANNEL_SET( int Adr, int data )
-{
- int num = Adr & 3;
- if ( num == 3 )
- return 1;
-
- channel_t& ch = YM2612.CHANNEL [num + (Adr & 0x100 ? 3 : 0)];
-
- switch ( Adr & 0xFC )
- {
- case 0xA0:
- YM2612_Special_Update();
-
- ch.FNUM [0] = (ch.FNUM [0] & 0x700) + data;
- ch.KC [0] = (ch.FOCT [0] << 2) | FKEY_TAB [ch.FNUM [0] >> 7];
-
- ch.SLOT [0].Finc = -1;
- break;
-
- case 0xA4:
- YM2612_Special_Update();
-
- ch.FNUM [0] = (ch.FNUM [0] & 0x0FF) + ((data & 0x07) << 8);
- ch.FOCT [0] = (data & 0x38) >> 3;
- ch.KC [0] = (ch.FOCT [0] << 2) | FKEY_TAB [ch.FNUM [0] >> 7];
-
- ch.SLOT [0].Finc = -1;
- break;
-
- case 0xA8:
- if ( Adr < 0x100 )
- {
- num++;
-
- YM2612_Special_Update();
-
- YM2612.CHANNEL [2].FNUM [num] = (YM2612.CHANNEL [2].FNUM [num] & 0x700) + data;
- YM2612.CHANNEL [2].KC [num] = (YM2612.CHANNEL [2].FOCT [num] << 2) |
- FKEY_TAB [YM2612.CHANNEL [2].FNUM [num] >> 7];
-
- YM2612.CHANNEL [2].SLOT [0].Finc = -1;
- }
- break;
-
- case 0xAC:
- if ( Adr < 0x100 )
- {
- num++;
-
- YM2612_Special_Update();
-
- YM2612.CHANNEL [2].FNUM [num] = (YM2612.CHANNEL [2].FNUM [num] & 0x0FF) + ((data & 0x07) << 8);
- YM2612.CHANNEL [2].FOCT [num] = (data & 0x38) >> 3;
- YM2612.CHANNEL [2].KC [num] = (YM2612.CHANNEL [2].FOCT [num] << 2) |
- FKEY_TAB [YM2612.CHANNEL [2].FNUM [num] >> 7];
-
- YM2612.CHANNEL [2].SLOT [0].Finc = -1;
- }
- break;
-
- case 0xB0:
- if ( ch.ALGO != (data & 7) )
- {
- // Fix VectorMan 2 heli sound (level 1)
- YM2612_Special_Update();
-
- ch.ALGO = data & 7;
-
- ch.SLOT [0].ChgEnM = 0;
- ch.SLOT [1].ChgEnM = 0;
- ch.SLOT [2].ChgEnM = 0;
- ch.SLOT [3].ChgEnM = 0;
- }
-
- ch.FB = 9 - ((data >> 3) & 7); // Real thing ?
-
-// if (ch.FB = ((data >> 3) & 7)) ch.FB = 9 - ch.FB; // Thunder force 4 (music stage 8), Gynoug, Aladdin bug sound...
-// else ch.FB = 31;
- break;
-
- case 0xB4: {
- YM2612_Special_Update();
-
- ch.LEFT = 0 - ((data >> 7) & 1);
- ch.RIGHT = 0 - ((data >> 6) & 1);
-
- ch.AMS = LFO_AMS_TAB [(data >> 4) & 3];
- ch.FMS = LFO_FMS_TAB [data & 7];
-
- for ( int i = 0; i < 4; i++ )
- {
- slot_t& sl = ch.SLOT [i];
- sl.AMS = (sl.AMSon ? ch.AMS : 31);
- }
- break;
- }
- }
-
- return 0;
-}
-
-
-int Ym2612_Impl::YM_SET(int Adr, int data)
-{
- switch ( Adr )
- {
- case 0x22:
- if (data & 8) // LFO enable
- {
- // Cool Spot music 1, LFO modified severals time which
- // distord the sound, have to check that on a real genesis...
-
- g.LFOinc = g.LFO_INC_TAB [data & 7];
- }
- else
- {
- g.LFOinc = g.LFOcnt = 0;
- }
- break;
-
- case 0x24:
- YM2612.TimerA = (YM2612.TimerA & 0x003) | (((int) data) << 2);
-
- if (YM2612.TimerAL != (1024 - YM2612.TimerA) << 12)
- {
- YM2612.TimerAcnt = YM2612.TimerAL = (1024 - YM2612.TimerA) << 12;
- }
- break;
-
- case 0x25:
- YM2612.TimerA = (YM2612.TimerA & 0x3FC) | (data & 3);
-
- if (YM2612.TimerAL != (1024 - YM2612.TimerA) << 12)
- {
- YM2612.TimerAcnt = YM2612.TimerAL = (1024 - YM2612.TimerA) << 12;
- }
- break;
-
- case 0x26:
- YM2612.TimerB = data;
-
- if (YM2612.TimerBL != (256 - YM2612.TimerB) << (4 + 12))
- {
- YM2612.TimerBcnt = YM2612.TimerBL = (256 - YM2612.TimerB) << (4 + 12);
- }
- break;
-
- case 0x27:
- // Parametre divers
- // b7 = CSM MODE
- // b6 = 3 slot mode
- // b5 = reset b
- // b4 = reset a
- // b3 = timer enable b
- // b2 = timer enable a
- // b1 = load b
- // b0 = load a
-
- if ((data ^ YM2612.Mode) & 0x40)
- {
- // We changed the channel 2 mode, so recalculate phase step
- // This fix the punch sound in Street of Rage 2
-
- YM2612_Special_Update();
-
- YM2612.CHANNEL [2].SLOT [0].Finc = -1; // recalculate phase step
- }
-
-// if ((data & 2) && (YM2612.Status & 2)) YM2612.TimerBcnt = YM2612.TimerBL;
-// if ((data & 1) && (YM2612.Status & 1)) YM2612.TimerAcnt = YM2612.TimerAL;
-
-// YM2612.Status &= (~data >> 4); // Reset du Status au cas ou c'est demande
- YM2612.Status &= (~data >> 4) & (data >> 2); // Reset Status
-
- YM2612.Mode = data;
- break;
-
- case 0x28: {
- int nch = data & 3;
- if ( nch == 3 )
- return 1;
- if ( data & 4 )
- nch += 3;
- channel_t& ch = YM2612.CHANNEL [nch];
-
- YM2612_Special_Update();
-
- if (data & 0x10) KEY_ON(ch, S0); // On appuie sur la touche pour le slot 1
- else KEY_OFF(ch, S0); // On rel'che la touche pour le slot 1
- if (data & 0x20) KEY_ON(ch, S1); // On appuie sur la touche pour le slot 3
- else KEY_OFF(ch, S1); // On rel'che la touche pour le slot 3
- if (data & 0x40) KEY_ON(ch, S2); // On appuie sur la touche pour le slot 2
- else KEY_OFF(ch, S2); // On rel'che la touche pour le slot 2
- if (data & 0x80) KEY_ON(ch, S3); // On appuie sur la touche pour le slot 4
- else KEY_OFF(ch, S3); // On rel'che la touche pour le slot 4
- break;
- }
-
- case 0x2B:
- if (YM2612.DAC ^ (data & 0x80)) YM2612_Special_Update();
-
- YM2612.DAC = data & 0x80; // activation/desactivation du DAC
- break;
- }
-
- return 0;
-}
-
-void Ym2612_Impl::set_rate( double sample_rate, double clock_rate )
-{
- assert( sample_rate );
- assert( clock_rate > sample_rate );
-
- int i;
-
- // 144 = 12 * (prescale * 2) = 12 * 6 * 2
- // prescale set to 6 by default
-
- double Frequence = clock_rate / sample_rate / 144.0;
- if ( fabs( Frequence - 1.0 ) < 0.0000001 )
- Frequence = 1.0;
- YM2612.TimerBase = int (Frequence * 4096.0);
-
- // Tableau TL :
- // [0 - 4095] = +output [4095 - ...] = +output overflow (fill with 0)
- // [12288 - 16383] = -output [16384 - ...] = -output overflow (fill with 0)
-
- for(i = 0; i < TL_LENGHT; i++)
- {
- if (i >= PG_CUT_OFF) // YM2612 cut off sound after 78 dB (14 bits output ?)
- {
- g.TL_TAB [TL_LENGHT + i] = g.TL_TAB [i] = 0;
- }
- else
- {
- double x = MAX_OUT; // Max output
- x /= pow( 10.0, (ENV_STEP * i) / 20.0 ); // Decibel -> Voltage
-
- g.TL_TAB [i] = (int) x;
- g.TL_TAB [TL_LENGHT + i] = -g.TL_TAB [i];
- }
- }
-
- // Tableau SIN :
- // g.SIN_TAB [x] [y] = sin(x) * y;
- // x = phase and y = volume
-
- g.SIN_TAB [0] = g.SIN_TAB [SIN_LENGHT / 2] = PG_CUT_OFF;
-
- for(i = 1; i <= SIN_LENGHT / 4; i++)
- {
- double x = sin(2.0 * PI * (double) (i) / (double) (SIN_LENGHT)); // Sinus
- x = 20 * log10(1 / x); // convert to dB
-
- int j = (int) (x / ENV_STEP); // Get TL range
-
- if (j > PG_CUT_OFF) j = (int) PG_CUT_OFF;
-
- g.SIN_TAB [i] = g.SIN_TAB [(SIN_LENGHT / 2) - i] = j;
- g.SIN_TAB [(SIN_LENGHT / 2) + i] = g.SIN_TAB [SIN_LENGHT - i] = TL_LENGHT + j;
- }
-
- // Tableau LFO (LFO wav) :
-
- for(i = 0; i < LFO_LENGHT; i++)
- {
- double x = sin(2.0 * PI * (double) (i) / (double) (LFO_LENGHT)); // Sinus
- x += 1.0;
- x /= 2.0; // positive only
- x *= 11.8 / ENV_STEP; // ajusted to MAX enveloppe modulation
-
- g.LFO_ENV_TAB [i] = (int) x;
-
- x = sin(2.0 * PI * (double) (i) / (double) (LFO_LENGHT)); // Sinus
- x *= (double) ((1 << (LFO_HBITS - 1)) - 1);
-
- g.LFO_FREQ_TAB [i] = (int) x;
-
- }
-
- // Tableau Enveloppe :
- // g.ENV_TAB [0] -> g.ENV_TAB [ENV_LENGHT - 1] = attack curve
- // g.ENV_TAB [ENV_LENGHT] -> g.ENV_TAB [2 * ENV_LENGHT - 1] = decay curve
-
- for(i = 0; i < ENV_LENGHT; i++)
- {
- // Attack curve (x^8 - music level 2 Vectorman 2)
- double x = pow(((double) ((ENV_LENGHT - 1) - i) / (double) (ENV_LENGHT)), 8);
- x *= ENV_LENGHT;
-
- g.ENV_TAB [i] = (int) x;
-
- // Decay curve (just linear)
- x = pow(((double) (i) / (double) (ENV_LENGHT)), 1);
- x *= ENV_LENGHT;
-
- g.ENV_TAB [ENV_LENGHT + i] = (int) x;
- }
- for ( i = 0; i < 8; i++ )
- g.ENV_TAB [i + ENV_LENGHT * 2] = 0;
-
- g.ENV_TAB [ENV_END >> ENV_LBITS] = ENV_LENGHT - 1; // for the stopped state
-
- // Tableau pour la conversion Attack -> Decay and Decay -> Attack
-
- int j = ENV_LENGHT - 1;
- for ( i = 0; i < ENV_LENGHT; i++ )
- {
- while ( j && g.ENV_TAB [j] < i )
- j--;
-
- g.DECAY_TO_ATTACK [i] = j << ENV_LBITS;
- }
-
- // Tableau pour le Substain Level
-
- for(i = 0; i < 15; i++)
- {
- double x = i * 3; // 3 and not 6 (Mickey Mania first music for test)
- x /= ENV_STEP;
-
- g.SL_TAB [i] = ((int) x << ENV_LBITS) + ENV_DECAY;
- }
-
- g.SL_TAB [15] = ((ENV_LENGHT - 1) << ENV_LBITS) + ENV_DECAY; // special case : volume off
-
- // Tableau Frequency Step
-
- for(i = 0; i < 2048; i++)
- {
- double x = (double) (i) * Frequence;
-
-#if ((SIN_LBITS + SIN_HBITS - (21 - 7)) < 0)
- x /= (double) (1 << ((21 - 7) - SIN_LBITS - SIN_HBITS));
-#else
- x *= (double) (1 << (SIN_LBITS + SIN_HBITS - (21 - 7)));
-#endif
-
- x /= 2.0; // because MUL = value * 2
-
- g.FINC_TAB [i] = (unsigned int) x;
- }
-
- // Tableaux Attack & Decay Rate
-
- for(i = 0; i < 4; i++)
- {
- g.AR_TAB [i] = 0;
- g.DR_TAB [i] = 0;
- }
-
- for(i = 0; i < 60; i++)
- {
- double x = Frequence;
-
- x *= 1.0 + ((i & 3) * 0.25); // bits 0-1 : x1.00, x1.25, x1.50, x1.75
- x *= (double) (1 << ((i >> 2))); // bits 2-5 : shift bits (x2^0 - x2^15)
- x *= (double) (ENV_LENGHT << ENV_LBITS); // on ajuste pour le tableau g.ENV_TAB
-
- g.AR_TAB [i + 4] = (unsigned int) (x / AR_RATE);
- g.DR_TAB [i + 4] = (unsigned int) (x / DR_RATE);
- }
-
- for(i = 64; i < 96; i++)
- {
- g.AR_TAB [i] = g.AR_TAB [63];
- g.DR_TAB [i] = g.DR_TAB [63];
-
- g.NULL_RATE [i - 64] = 0;
- }
-
- for ( i = 96; i < 128; i++ )
- g.AR_TAB [i] = 0;
-
- // Tableau Detune
-
- for(i = 0; i < 4; i++)
- {
- for (int j = 0; j < 32; j++)
- {
-#if ((SIN_LBITS + SIN_HBITS - 21) < 0)
- double y = (double) DT_DEF_TAB [(i << 5) + j] * Frequence / (double) (1 << (21 - SIN_LBITS - SIN_HBITS));
-#else
- double y = (double) DT_DEF_TAB [(i << 5) + j] * Frequence * (double) (1 << (SIN_LBITS + SIN_HBITS - 21));
-#endif
-
- g.DT_TAB [i + 0] [j] = (int) y;
- g.DT_TAB [i + 4] [j] = (int) -y;
- }
- }
-
- // Tableau LFO
- g.LFO_INC_TAB [0] = (unsigned int) (3.98 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [1] = (unsigned int) (5.56 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [2] = (unsigned int) (6.02 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [3] = (unsigned int) (6.37 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [4] = (unsigned int) (6.88 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [5] = (unsigned int) (9.63 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [6] = (unsigned int) (48.1 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [7] = (unsigned int) (72.2 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
-
- reset();
-}
-
-const char* Ym2612_Emu::set_rate( double sample_rate, double clock_rate )
-{
- if ( !impl )
- {
- impl = (Ym2612_Impl*) malloc( sizeof *impl );
- if ( !impl )
- return "Out of memory";
- impl->mute_mask = 0;
- }
- memset( &impl->YM2612, 0, sizeof impl->YM2612 );
-
- impl->set_rate( sample_rate, clock_rate );
-
- return 0;
-}
-
-Ym2612_Emu::~Ym2612_Emu()
-{
- free( impl );
-}
-
-inline void Ym2612_Impl::write0( int opn_addr, int data )
-{
- assert( (unsigned) data <= 0xFF );
-
- if ( opn_addr < 0x30 )
- {
- YM2612.REG [0] [opn_addr] = data;
- YM_SET( opn_addr, data );
- }
- else if ( YM2612.REG [0] [opn_addr] != data )
- {
- YM2612.REG [0] [opn_addr] = data;
-
- if ( opn_addr < 0xA0 )
- SLOT_SET( opn_addr, data );
- else
- CHANNEL_SET( opn_addr, data );
- }
-}
-
-inline void Ym2612_Impl::write1( int opn_addr, int data )
-{
- assert( (unsigned) data <= 0xFF );
-
- if ( opn_addr >= 0x30 && YM2612.REG [1] [opn_addr] != data )
- {
- YM2612.REG [1] [opn_addr] = data;
-
- if ( opn_addr < 0xA0 )
- SLOT_SET( opn_addr + 0x100, data );
- else
- CHANNEL_SET( opn_addr + 0x100, data );
- }
-}
-
-void Ym2612_Emu::reset()
-{
- impl->reset();
-}
-
-void Ym2612_Impl::reset()
-{
- g.LFOcnt = 0;
- YM2612.TimerA = 0;
- YM2612.TimerAL = 0;
- YM2612.TimerAcnt = 0;
- YM2612.TimerB = 0;
- YM2612.TimerBL = 0;
- YM2612.TimerBcnt = 0;
- YM2612.DAC = 0;
-
- YM2612.Status = 0;
-
- int i;
- for ( i = 0; i < channel_count; i++ )
- {
- channel_t& ch = YM2612.CHANNEL [i];
-
- ch.LEFT = ~0;
- ch.RIGHT = ~0;
- ch.ALGO = 0;
- ch.FB = 31;
- ch.FMS = 0;
- ch.AMS = 0;
-
- for ( int j = 0 ;j < 4 ; j++ )
- {
- ch.S0_OUT [j] = 0;
- ch.FNUM [j] = 0;
- ch.FOCT [j] = 0;
- ch.KC [j] = 0;
-
- ch.SLOT [j].Fcnt = 0;
- ch.SLOT [j].Finc = 0;
- ch.SLOT [j].Ecnt = ENV_END; // Put it at the end of Decay phase...
- ch.SLOT [j].Einc = 0;
- ch.SLOT [j].Ecmp = 0;
- ch.SLOT [j].Ecurp = RELEASE;
-
- ch.SLOT [j].ChgEnM = 0;
- }
- }
-
- for ( i = 0; i < 0x100; i++ )
- {
- YM2612.REG [0] [i] = -1;
- YM2612.REG [1] [i] = -1;
- }
-
- for ( i = 0xB6; i >= 0xB4; i-- )
- {
- write0( i, 0xC0 );
- write1( i, 0xC0 );
- }
-
- for ( i = 0xB2; i >= 0x22; i-- )
- {
- write0( i, 0 );
- write1( i, 0 );
- }
-
- write0( 0x2A, 0x80 );
-}
-
-void Ym2612_Emu::write0( int addr, int data )
-{
- impl->write0( addr, data );
-}
-
-void Ym2612_Emu::write1( int addr, int data )
-{
- impl->write1( addr, data );
-}
-
-void Ym2612_Emu::mute_voices( int mask ) { impl->mute_mask = mask; }
-
-static void update_envelope_( slot_t* sl )
-{
- switch ( sl->Ecurp )
- {
- case 0:
- // Env_Attack_Next
-
- // Verified with Gynoug even in HQ (explode SFX)
- sl->Ecnt = ENV_DECAY;
-
- sl->Einc = sl->EincD;
- sl->Ecmp = sl->SLL;
- sl->Ecurp = DECAY;
- break;
-
- case 1:
- // Env_Decay_Next
-
- // Verified with Gynoug even in HQ (explode SFX)
- sl->Ecnt = sl->SLL;
-
- sl->Einc = sl->EincS;
- sl->Ecmp = ENV_END;
- sl->Ecurp = SUBSTAIN;
- break;
-
- case 2:
- // Env_Substain_Next(slot_t *SL)
- if (sl->SEG & 8) // SSG envelope type
- {
- int release = sl->SEG & 1;
-
- if ( !release )
- {
- // re KEY ON
-
- // sl->Fcnt = 0;
- // sl->ChgEnM = ~0;
-
- sl->Ecnt = 0;
- sl->Einc = sl->EincA;
- sl->Ecmp = ENV_DECAY;
- sl->Ecurp = ATTACK;
- }
-
- set_seg( *sl, (sl->SEG << 1) & 4 );
-
- if ( !release )
- break;
- }
- // fall through
-
- case 3:
- // Env_Release_Next
- sl->Ecnt = ENV_END;
- sl->Einc = 0;
- sl->Ecmp = ENV_END + 1;
- break;
-
- // default: no op
- }
-}
-
-inline void update_envelope( slot_t& sl )
-{
- int ecmp = sl.Ecmp;
- if ( (sl.Ecnt += sl.Einc) >= ecmp )
- update_envelope_( &sl );
-}
-
-template<int algo>
-struct ym2612_update_chan {
- static void func( tables_t&, channel_t&, Ym2612_Emu::sample_t*, int );
-};
-
-typedef void (*ym2612_update_chan_t)( tables_t&, channel_t&, Ym2612_Emu::sample_t*, int );
-
-template<int algo>
-void ym2612_update_chan<algo>::func( tables_t& g, channel_t& ch,
- Ym2612_Emu::sample_t* buf, int length )
-{
- int not_end = ch.SLOT [S3].Ecnt - ENV_END;
-
- // algo is a compile-time constant, so all conditions based on it are resolved
- // during compilation
-
- // special cases
- if ( algo == 7 )
- not_end |= ch.SLOT [S0].Ecnt - ENV_END;
-
- if ( algo >= 5 )
- not_end |= ch.SLOT [S2].Ecnt - ENV_END;
-
- if ( algo >= 4 )
- not_end |= ch.SLOT [S1].Ecnt - ENV_END;
-
- int CH_S0_OUT_1 = ch.S0_OUT [1];
-
- int in0 = ch.SLOT [S0].Fcnt;
- int in1 = ch.SLOT [S1].Fcnt;
- int in2 = ch.SLOT [S2].Fcnt;
- int in3 = ch.SLOT [S3].Fcnt;
-
- int YM2612_LFOinc = g.LFOinc;
- int YM2612_LFOcnt = g.LFOcnt + YM2612_LFOinc;
-
- if ( !not_end )
- return;
-
- do
- {
- // envelope
- int const env_LFO = g.LFO_ENV_TAB [YM2612_LFOcnt >> LFO_LBITS & LFO_MASK];
-
- short const* const ENV_TAB = g.ENV_TAB;
-
- #define CALC_EN( x ) \
- int temp##x = ENV_TAB [ch.SLOT [S##x].Ecnt >> ENV_LBITS] + ch.SLOT [S##x].TLL; \
- int en##x = ((temp##x ^ ch.SLOT [S##x].env_xor) + (env_LFO >> ch.SLOT [S##x].AMS)) & \
- ((temp##x - ch.SLOT [S##x].env_max) >> 31);
-
- CALC_EN( 0 )
- CALC_EN( 1 )
- CALC_EN( 2 )
- CALC_EN( 3 )
-
- int const* const TL_TAB = g.TL_TAB;
-
- #define SINT( i, o ) (TL_TAB [g.SIN_TAB [(i)] + (o)])
-
- // feedback
- int CH_S0_OUT_0 = ch.S0_OUT [0];
- {
- int temp = in0 + ((CH_S0_OUT_0 + CH_S0_OUT_1) >> ch.FB);
- CH_S0_OUT_1 = CH_S0_OUT_0;
- CH_S0_OUT_0 = SINT( (temp >> SIN_LBITS) & SIN_MASK, en0 );
- }
-
- int CH_OUTd;
- if ( algo == 0 )
- {
- int temp = in1 + CH_S0_OUT_1;
- temp = in2 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en1 );
- temp = in3 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
- }
- else if ( algo == 1 )
- {
- int temp = in2 + CH_S0_OUT_1 + SINT( (in1 >> SIN_LBITS) & SIN_MASK, en1 );
- temp = in3 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
- }
- else if ( algo == 2 )
- {
- int temp = in2 + SINT( (in1 >> SIN_LBITS) & SIN_MASK, en1 );
- temp = in3 + CH_S0_OUT_1 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
- }
- else if ( algo == 3 )
- {
- int temp = in1 + CH_S0_OUT_1;
- temp = in3 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en1 ) +
- SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
- }
- else if ( algo == 4 )
- {
- int temp = in3 + SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 ) +
- SINT( ((in1 + CH_S0_OUT_1) >> SIN_LBITS) & SIN_MASK, en1 );
- //DO_LIMIT
- }
- else if ( algo == 5 )
- {
- int temp = CH_S0_OUT_1;
- CH_OUTd = SINT( ((in3 + temp) >> SIN_LBITS) & SIN_MASK, en3 ) +
- SINT( ((in1 + temp) >> SIN_LBITS) & SIN_MASK, en1 ) +
- SINT( ((in2 + temp) >> SIN_LBITS) & SIN_MASK, en2 );
- //DO_LIMIT
- }
- else if ( algo == 6 )
- {
- CH_OUTd = SINT( (in3 >> SIN_LBITS) & SIN_MASK, en3 ) +
- SINT( ((in1 + CH_S0_OUT_1) >> SIN_LBITS) & SIN_MASK, en1 ) +
- SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 );
- //DO_LIMIT
- }
- else if ( algo == 7 )
- {
- CH_OUTd = SINT( (in3 >> SIN_LBITS) & SIN_MASK, en3 ) +
- SINT( (in1 >> SIN_LBITS) & SIN_MASK, en1 ) +
- SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 ) + CH_S0_OUT_1;
- //DO_LIMIT
- }
-
- CH_OUTd >>= MAX_OUT_BITS - output_bits + 2;
-
- // update phase
- unsigned freq_LFO = ((g.LFO_FREQ_TAB [YM2612_LFOcnt >> LFO_LBITS & LFO_MASK] *
- ch.FMS) >> (LFO_HBITS - 1 + 1)) + (1L << (LFO_FMS_LBITS - 1));
- YM2612_LFOcnt += YM2612_LFOinc;
- in0 += (ch.SLOT [S0].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
- in1 += (ch.SLOT [S1].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
- in2 += (ch.SLOT [S2].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
- in3 += (ch.SLOT [S3].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
-
- int t0 = buf [0] + (CH_OUTd & ch.LEFT);
- int t1 = buf [1] + (CH_OUTd & ch.RIGHT);
-
- update_envelope( ch.SLOT [0] );
- update_envelope( ch.SLOT [1] );
- update_envelope( ch.SLOT [2] );
- update_envelope( ch.SLOT [3] );
-
- ch.S0_OUT [0] = CH_S0_OUT_0;
- buf [0] = t0;
- buf [1] = t1;
- buf += 2;
- }
- while ( --length );
-
- ch.S0_OUT [1] = CH_S0_OUT_1;
-
- ch.SLOT [S0].Fcnt = in0;
- ch.SLOT [S1].Fcnt = in1;
- ch.SLOT [S2].Fcnt = in2;
- ch.SLOT [S3].Fcnt = in3;
-}
-
-static const ym2612_update_chan_t UPDATE_CHAN [8] = {
- &ym2612_update_chan<0>::func,
- &ym2612_update_chan<1>::func,
- &ym2612_update_chan<2>::func,
- &ym2612_update_chan<3>::func,
- &ym2612_update_chan<4>::func,
- &ym2612_update_chan<5>::func,
- &ym2612_update_chan<6>::func,
- &ym2612_update_chan<7>::func
-};
-
-void Ym2612_Impl::run_timer( int length )
-{
- int const step = 6;
- int remain = length;
- do
- {
- int n = step;
- if ( n > remain )
- n = remain;
- remain -= n;
-
- long i = n * YM2612.TimerBase;
- if (YM2612.Mode & 1) // Timer A ON ?
- {
- // if ((YM2612.TimerAcnt -= 14073) <= 0) // 13879=NTSC (old: 14475=NTSC 14586=PAL)
- if ((YM2612.TimerAcnt -= i) <= 0)
- {
- // timer a overflow
-
- YM2612.Status |= (YM2612.Mode & 0x04) >> 2;
- YM2612.TimerAcnt += YM2612.TimerAL;
-
- if (YM2612.Mode & 0x80)
- {
- KEY_ON( YM2612.CHANNEL [2], 0 );
- KEY_ON( YM2612.CHANNEL [2], 1 );
- KEY_ON( YM2612.CHANNEL [2], 2 );
- KEY_ON( YM2612.CHANNEL [2], 3 );
- }
- }
- }
-
- if (YM2612.Mode & 2) // Timer B ON ?
- {
- // if ((YM2612.TimerBcnt -= 14073) <= 0) // 13879=NTSC (old: 14475=NTSC 14586=PAL)
- if ((YM2612.TimerBcnt -= i) <= 0)
- {
- // timer b overflow
- YM2612.Status |= (YM2612.Mode & 0x08) >> 2;
- YM2612.TimerBcnt += YM2612.TimerBL;
- }
- }
- }
- while ( remain > 0 );
-}
-
-void Ym2612_Impl::run( int pair_count, Ym2612_Emu::sample_t* out )
-{
- if ( pair_count <= 0 )
- return;
-
- if ( YM2612.Mode & 3 )
- run_timer( pair_count );
-
- // Mise à jour des pas des compteurs-frequences s'ils ont ete modifies
-
- for ( int chi = 0; chi < channel_count; chi++ )
- {
- channel_t& ch = YM2612.CHANNEL [chi];
- if ( ch.SLOT [0].Finc != -1 )
- continue;
-
- int i2 = 0;
- if ( chi == 2 && (YM2612.Mode & 0x40) )
- i2 = 2;
-
- for ( int i = 0; i < 4; i++ )
- {
- // static int seq [4] = { 2, 1, 3, 0 };
- // if ( i2 ) i2 = seq [i];
-
- slot_t& sl = ch.SLOT [i];
- int finc = g.FINC_TAB [ch.FNUM [i2]] >> (7 - ch.FOCT [i2]);
- int ksr = ch.KC [i2] >> sl.KSR_S; // keycode attenuation
- sl.Finc = (finc + sl.DT [ch.KC [i2]]) * sl.MUL;
- if (sl.KSR != ksr) // si le KSR a change alors
- { // les differents taux pour l'enveloppe sont mis à jour
- sl.KSR = ksr;
-
- sl.EincA = sl.AR [ksr];
- sl.EincD = sl.DR [ksr];
- sl.EincS = sl.SR [ksr];
- sl.EincR = sl.RR [ksr];
-
- if (sl.Ecurp == ATTACK)
- {
- sl.Einc = sl.EincA;
- }
- else if (sl.Ecurp == DECAY)
- {
- sl.Einc = sl.EincD;
- }
- else if (sl.Ecnt < ENV_END)
- {
- if (sl.Ecurp == SUBSTAIN)
- sl.Einc = sl.EincS;
- else if (sl.Ecurp == RELEASE)
- sl.Einc = sl.EincR;
- }
- }
-
- if ( i2 )
- i2 = (i2 ^ 2) ^ (i2 >> 1);
- }
- }
-
- for ( int i = 0; i < channel_count; i++ )
- {
- if ( !(mute_mask & (1 << i)) && (i != 5 || !YM2612.DAC) )
- UPDATE_CHAN [YM2612.CHANNEL [i].ALGO]( g, YM2612.CHANNEL [i], out, pair_count );
- }
-
- g.LFOcnt += g.LFOinc * pair_count;
-}
-
-void Ym2612_Emu::run( int pair_count, sample_t* out ) { impl->run( pair_count, out ); }
diff --git a/src/console/Zlib_Inflater.cc b/src/console/Zlib_Inflater.cc
new file mode 100644
index 000000000000..ed64e8d96173
--- /dev/null
+++ b/src/console/Zlib_Inflater.cc
@@ -0,0 +1,175 @@
+// File_Extractor 0.4.0. http://www.slack.net/~ant/
+
+#include "Zlib_Inflater.h"
+
+#include <assert.h>
+#include <string.h>
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+static const char* get_zlib_err( int code )
+{
+ assert( code != Z_OK );
+ if ( code == Z_MEM_ERROR )
+ return "Out of memory";
+
+ const char* str = zError( code );
+ if ( code == Z_DATA_ERROR )
+ str = "Zip data is corrupt";
+ if ( !str )
+ str = "Zip error";
+ return str;
+}
+
+void Zlib_Inflater::end()
+{
+ if ( deflated_ )
+ {
+ deflated_ = false;
+ if ( inflateEnd( &zbuf ) )
+ check( false );
+ }
+ buf.clear();
+
+ static z_stream const empty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ memcpy( &zbuf, &empty, sizeof zbuf );
+}
+
+Zlib_Inflater::Zlib_Inflater()
+{
+ deflated_ = false;
+ end(); // initialize things
+}
+
+Zlib_Inflater::~Zlib_Inflater()
+{
+ end();
+}
+
+blargg_err_t Zlib_Inflater::begin( mode_t mode, callback_t callback, void* user_data,
+ long buf_size )
+{
+ end();
+
+ if ( buf_size && buf.resize( buf_size ) )
+ buf_size = 0; // not enough memory for requested size, so use default
+
+ if ( !buf_size )
+ RETURN_ERR( buf.resize( 16 * 1024L ) );
+
+ // Fill buffer with some data, less than normal buffer size since caller might
+ // just be examining beginning of file. 4K is a common disk block size.
+ long count = (buf_size ? buf_size : 4096);
+ RETURN_ERR( callback( user_data, buf.begin(), &count ) );
+ zbuf.avail_in = count;
+ zbuf.next_in = buf.begin();
+
+ if ( mode == mode_auto )
+ {
+ // examine buffer for gzip header
+ mode = mode_copy;
+ int const min_gzip_size = 2 + 8 + 8;
+ if ( count >= min_gzip_size && buf [0] == 0x1F && buf [1] == 0x8B )
+ mode = mode_ungz;
+ }
+
+ if ( mode != mode_copy )
+ {
+ int wb = MAX_WBITS + 16; // have zlib handle gzip header
+ if ( mode == mode_raw_deflate )
+ wb = -MAX_WBITS;
+
+ int zerr = inflateInit2( &zbuf, wb );
+ if ( zerr )
+ return get_zlib_err( zerr );
+
+ deflated_ = true;
+ }
+ return 0;
+}
+
+
+blargg_err_t Zlib_Inflater::read( void* out, long* count_io,
+ callback_t callback, void* user_data )
+{
+ if ( !*count_io )
+ return 0;
+
+ if ( !deflated_ )
+ {
+ // copy buffered data
+ long first = zbuf.avail_in;
+ if ( first )
+ {
+ if ( first > *count_io )
+ first = *count_io;
+ memcpy( out, zbuf.next_in, first );
+ zbuf.next_in += first;
+ zbuf.avail_in -= first;
+ if ( !zbuf.avail_in )
+ buf.clear(); // done with buffer
+ }
+
+ // read remaining directly
+ long second = *count_io - first;
+ if ( second )
+ {
+ long actual = second;
+ RETURN_ERR( callback( user_data, (char*) out + first, &actual ) );
+ *count_io -= second - actual;
+ }
+ }
+ else
+ {
+ zbuf.next_out = (Bytef*) out;
+ zbuf.avail_out = *count_io;
+
+ while ( 1 )
+ {
+ uInt old_avail_in = zbuf.avail_in;
+ int err = inflate( &zbuf, Z_NO_FLUSH );
+ if ( err == Z_STREAM_END )
+ {
+ *count_io -= zbuf.avail_out;
+ end();
+ break; // all data deflated
+ }
+
+ if ( err == Z_BUF_ERROR && !old_avail_in )
+ err = 0; // we just need to provide more input
+
+ if ( err )
+ return get_zlib_err( err );
+
+ if ( !zbuf.avail_out )
+ break; // requested number of bytes deflated
+
+ if ( zbuf.avail_in )
+ {
+ // inflate() should never leave input if there's still space for output
+ assert( false );
+ return "Corrupt zip data";
+ }
+
+ // refill buffer
+ long count = buf.size();
+ RETURN_ERR( callback( user_data, buf.begin(), &count ) );
+ zbuf.next_in = buf.begin();
+ zbuf.avail_in = count;
+ if ( !zbuf.avail_in )
+ return "Corrupt zip data"; // stream didn't end but there's no more data
+ }
+ }
+ return 0;
+}
diff --git a/src/console/Zlib_Inflater.cxx b/src/console/Zlib_Inflater.cxx
deleted file mode 100644
index ed64e8d96173..000000000000
--- a/src/console/Zlib_Inflater.cxx
+++ /dev/null
@@ -1,175 +0,0 @@
-// File_Extractor 0.4.0. http://www.slack.net/~ant/
-
-#include "Zlib_Inflater.h"
-
-#include <assert.h>
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-static const char* get_zlib_err( int code )
-{
- assert( code != Z_OK );
- if ( code == Z_MEM_ERROR )
- return "Out of memory";
-
- const char* str = zError( code );
- if ( code == Z_DATA_ERROR )
- str = "Zip data is corrupt";
- if ( !str )
- str = "Zip error";
- return str;
-}
-
-void Zlib_Inflater::end()
-{
- if ( deflated_ )
- {
- deflated_ = false;
- if ( inflateEnd( &zbuf ) )
- check( false );
- }
- buf.clear();
-
- static z_stream const empty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- memcpy( &zbuf, &empty, sizeof zbuf );
-}
-
-Zlib_Inflater::Zlib_Inflater()
-{
- deflated_ = false;
- end(); // initialize things
-}
-
-Zlib_Inflater::~Zlib_Inflater()
-{
- end();
-}
-
-blargg_err_t Zlib_Inflater::begin( mode_t mode, callback_t callback, void* user_data,
- long buf_size )
-{
- end();
-
- if ( buf_size && buf.resize( buf_size ) )
- buf_size = 0; // not enough memory for requested size, so use default
-
- if ( !buf_size )
- RETURN_ERR( buf.resize( 16 * 1024L ) );
-
- // Fill buffer with some data, less than normal buffer size since caller might
- // just be examining beginning of file. 4K is a common disk block size.
- long count = (buf_size ? buf_size : 4096);
- RETURN_ERR( callback( user_data, buf.begin(), &count ) );
- zbuf.avail_in = count;
- zbuf.next_in = buf.begin();
-
- if ( mode == mode_auto )
- {
- // examine buffer for gzip header
- mode = mode_copy;
- int const min_gzip_size = 2 + 8 + 8;
- if ( count >= min_gzip_size && buf [0] == 0x1F && buf [1] == 0x8B )
- mode = mode_ungz;
- }
-
- if ( mode != mode_copy )
- {
- int wb = MAX_WBITS + 16; // have zlib handle gzip header
- if ( mode == mode_raw_deflate )
- wb = -MAX_WBITS;
-
- int zerr = inflateInit2( &zbuf, wb );
- if ( zerr )
- return get_zlib_err( zerr );
-
- deflated_ = true;
- }
- return 0;
-}
-
-
-blargg_err_t Zlib_Inflater::read( void* out, long* count_io,
- callback_t callback, void* user_data )
-{
- if ( !*count_io )
- return 0;
-
- if ( !deflated_ )
- {
- // copy buffered data
- long first = zbuf.avail_in;
- if ( first )
- {
- if ( first > *count_io )
- first = *count_io;
- memcpy( out, zbuf.next_in, first );
- zbuf.next_in += first;
- zbuf.avail_in -= first;
- if ( !zbuf.avail_in )
- buf.clear(); // done with buffer
- }
-
- // read remaining directly
- long second = *count_io - first;
- if ( second )
- {
- long actual = second;
- RETURN_ERR( callback( user_data, (char*) out + first, &actual ) );
- *count_io -= second - actual;
- }
- }
- else
- {
- zbuf.next_out = (Bytef*) out;
- zbuf.avail_out = *count_io;
-
- while ( 1 )
- {
- uInt old_avail_in = zbuf.avail_in;
- int err = inflate( &zbuf, Z_NO_FLUSH );
- if ( err == Z_STREAM_END )
- {
- *count_io -= zbuf.avail_out;
- end();
- break; // all data deflated
- }
-
- if ( err == Z_BUF_ERROR && !old_avail_in )
- err = 0; // we just need to provide more input
-
- if ( err )
- return get_zlib_err( err );
-
- if ( !zbuf.avail_out )
- break; // requested number of bytes deflated
-
- if ( zbuf.avail_in )
- {
- // inflate() should never leave input if there's still space for output
- assert( false );
- return "Corrupt zip data";
- }
-
- // refill buffer
- long count = buf.size();
- RETURN_ERR( callback( user_data, buf.begin(), &count ) );
- zbuf.next_in = buf.begin();
- zbuf.avail_in = count;
- if ( !zbuf.avail_in )
- return "Corrupt zip data"; // stream didn't end but there's no more data
- }
- }
- return 0;
-}
diff --git a/src/console/blargg_endian.h b/src/console/blargg_endian.h
index 5ca8b7dd25f1..8c59128a1194 100644
--- a/src/console/blargg_endian.h
+++ b/src/console/blargg_endian.h
@@ -3,7 +3,8 @@
#ifndef BLARGG_ENDIAN
#define BLARGG_ENDIAN
-#include <glib.h>
+#define WANT_AUD_BSWAP
+#include <libaudcore/audio.h>
#include "blargg_common.h"
@@ -19,21 +20,21 @@
#define BLARGG_CPU_RISC 1
#endif
-#if G_BYTE_ORDER == G_BIG_ENDIAN
+#ifdef WORDS_BIGENDIAN
#define BLARGG_BIG_ENDIAN 1
#else
#define BLARGG_LITTLE_ENDIAN 1
#endif
-inline unsigned GET_LE16 (const void * p) { return GUINT16_FROM_LE (* (uint16_t *) p); }
-inline unsigned GET_BE16 (const void * p) { return GUINT16_FROM_BE (* (uint16_t *) p); }
-inline unsigned GET_LE32 (const void * p) { return GUINT32_FROM_LE (* (uint32_t *) p); }
-inline unsigned GET_BE32 (const void * p) { return GUINT32_FROM_BE (* (uint32_t *) p); }
+inline unsigned GET_LE16 (const void * p) { return FROM_LE16 (* (uint16_t *) p); }
+inline unsigned GET_BE16 (const void * p) { return FROM_BE16 (* (uint16_t *) p); }
+inline unsigned GET_LE32 (const void * p) { return FROM_LE32 (* (uint32_t *) p); }
+inline unsigned GET_BE32 (const void * p) { return FROM_BE32 (* (uint32_t *) p); }
-inline void SET_LE16 (void * p, uint16_t n) { * (uint16_t *) p = GUINT16_TO_LE (n); }
-inline void SET_BE16 (void * p, uint16_t n) { * (uint16_t *) p = GUINT16_TO_BE (n); }
-inline void SET_LE32 (void * p, uint32_t n) { * (uint32_t *) p = GUINT32_TO_LE (n); }
-inline void SET_BE32 (void * p, uint32_t n) { * (uint32_t *) p = GUINT32_TO_BE (n); }
+inline void SET_LE16 (void * p, uint16_t n) { * (uint16_t *) p = TO_LE16 (n); }
+inline void SET_BE16 (void * p, uint16_t n) { * (uint16_t *) p = TO_BE16 (n); }
+inline void SET_LE32 (void * p, uint32_t n) { * (uint32_t *) p = TO_LE32 (n); }
+inline void SET_BE32 (void * p, uint32_t n) { * (uint32_t *) p = TO_BE32 (n); }
// auto-selecting versions
diff --git a/src/console/configure.c b/src/console/configure.c
deleted file mode 100644
index fc99dea66779..000000000000
--- a/src/console/configure.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Audacious: Cross platform multimedia player
- * Copyright (c) 2005-2009 Audacious Team
- *
- * Driver for Game_Music_Emu library. See details at:
- * http://www.slack.net/~ant/libs/
- *
- * Preferences GUI by Giacomo Lozito
- */
-
-#include "configure.h"
-
-#include <audacious/misc.h>
-
-#define CON_CFGID "console"
-
-AudaciousConsoleConfig audcfg;
-
-static const char * const console_defaults[] = {
- "loop_length", "180",
- "resample", "FALSE",
- "resample_rate", "32000",
- "treble", "0",
- "bass", "0",
- "ignore_spc_length", "FALSE",
- "echo", "0",
- "inc_spc_reverb", "FALSE",
- NULL};
-
-bool_t console_cfg_load (void)
-{
- aud_config_set_defaults (CON_CFGID, console_defaults);
-
- audcfg.loop_length = aud_get_int (CON_CFGID, "loop_length");
- audcfg.resample = aud_get_bool (CON_CFGID, "resample");
- audcfg.resample_rate = aud_get_int (CON_CFGID, "resample_rate");
- audcfg.treble = aud_get_int (CON_CFGID, "treble");
- audcfg.bass = aud_get_int (CON_CFGID, "bass");
- audcfg.ignore_spc_length = aud_get_bool (CON_CFGID, "ignore_spc_length");
- audcfg.echo = aud_get_int (CON_CFGID, "echo");
- audcfg.inc_spc_reverb = aud_get_bool (CON_CFGID, "inc_spc_reverb");
-
- return TRUE;
-}
-
-void console_cfg_save (void)
-{
- aud_set_int (CON_CFGID, "loop_length", audcfg.loop_length);
- aud_set_bool (CON_CFGID, "resample", audcfg.resample);
- aud_set_int (CON_CFGID, "resample_rate", audcfg.resample_rate);
- aud_set_int (CON_CFGID, "treble", audcfg.treble);
- aud_set_int (CON_CFGID, "bass", audcfg.bass);
- aud_set_bool (CON_CFGID, "ignore_spc_length", audcfg.ignore_spc_length);
- aud_set_int (CON_CFGID, "echo", audcfg.echo);
- aud_set_bool (CON_CFGID, "inc_spc_reverb", audcfg.inc_spc_reverb);
-}
diff --git a/src/console/configure.cc b/src/console/configure.cc
new file mode 100644
index 000000000000..57ae3d7c72ac
--- /dev/null
+++ b/src/console/configure.cc
@@ -0,0 +1,57 @@
+/*
+ * Audacious: Cross platform multimedia player
+ * Copyright (c) 2005-2009 Audacious Team
+ *
+ * Driver for Game_Music_Emu library. See details at:
+ * http://www.slack.net/~ant/libs/
+ *
+ * Preferences GUI by Giacomo Lozito
+ */
+
+#include "configure.h"
+#include "plugin.h"
+
+#include <libaudcore/runtime.h>
+
+#define CON_CFGID "console"
+
+AudaciousConsoleConfig audcfg;
+
+const char * const ConsolePlugin::defaults[] = {
+ "loop_length", "180",
+ "resample", "FALSE",
+ "resample_rate", "32000",
+ "treble", "0",
+ "bass", "0",
+ "ignore_spc_length", "FALSE",
+ "echo", "0",
+ "inc_spc_reverb", "FALSE",
+ nullptr};
+
+bool ConsolePlugin::init ()
+{
+ aud_config_set_defaults (CON_CFGID, defaults);
+
+ audcfg.loop_length = aud_get_int (CON_CFGID, "loop_length");
+ audcfg.resample = aud_get_bool (CON_CFGID, "resample");
+ audcfg.resample_rate = aud_get_int (CON_CFGID, "resample_rate");
+ audcfg.treble = aud_get_int (CON_CFGID, "treble");
+ audcfg.bass = aud_get_int (CON_CFGID, "bass");
+ audcfg.ignore_spc_length = aud_get_bool (CON_CFGID, "ignore_spc_length");
+ audcfg.echo = aud_get_int (CON_CFGID, "echo");
+ audcfg.inc_spc_reverb = aud_get_bool (CON_CFGID, "inc_spc_reverb");
+
+ return true;
+}
+
+void ConsolePlugin::cleanup ()
+{
+ aud_set_int (CON_CFGID, "loop_length", audcfg.loop_length);
+ aud_set_bool (CON_CFGID, "resample", audcfg.resample);
+ aud_set_int (CON_CFGID, "resample_rate", audcfg.resample_rate);
+ aud_set_int (CON_CFGID, "treble", audcfg.treble);
+ aud_set_int (CON_CFGID, "bass", audcfg.bass);
+ aud_set_bool (CON_CFGID, "ignore_spc_length", audcfg.ignore_spc_length);
+ aud_set_int (CON_CFGID, "echo", audcfg.echo);
+ aud_set_bool (CON_CFGID, "inc_spc_reverb", audcfg.inc_spc_reverb);
+}
diff --git a/src/console/configure.h b/src/console/configure.h
index b8a23170be79..b1c9d8d94e72 100644
--- a/src/console/configure.h
+++ b/src/console/configure.h
@@ -9,31 +9,17 @@
#ifndef AUD_CONSOLE_CONFIGURE_H
#define AUD_CONSOLE_CONFIGURE_H 1
-#include <libaudcore/core.h>
-
typedef struct {
int loop_length; /* length of tracks that lack timing information */
- bool_t resample; /* whether or not to resample */
+ bool resample; /* whether or not to resample */
int resample_rate; /* rate to resample at */
int treble; /* -100 to +100 */
int bass; /* -100 to +100 */
- bool_t ignore_spc_length; /* if true, ignore length from SPC tags */
+ bool ignore_spc_length; /* if true, ignore length from SPC tags */
int echo; /* 0 to +100 */
- bool_t inc_spc_reverb; /* if true, increases the default reverb */
+ bool inc_spc_reverb; /* if true, increases the default reverb */
} AudaciousConsoleConfig;
extern AudaciousConsoleConfig audcfg;
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-bool_t console_cfg_load(void);
-void console_cfg_save(void);
-void console_cfg_ui(void);
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* AUD_CONSOLE_CONFIGURE_H */
diff --git a/src/console/gme.cc b/src/console/gme.cc
new file mode 100644
index 000000000000..f6d01a8e3706
--- /dev/null
+++ b/src/console/gme.cc
@@ -0,0 +1,374 @@
+// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
+
+#include "Music_Emu.h"
+
+#include "gme_types.h"
+#if !GME_DISABLE_STEREO_DEPTH
+#include "Effects_Buffer.h"
+#endif
+#include "blargg_endian.h"
+#include <string.h>
+#include <ctype.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+BLARGG_EXPORT gme_type_t const* gme_type_list()
+{
+ static gme_type_t const gme_type_list_ [] = {
+#ifdef GME_TYPE_LIST
+ GME_TYPE_LIST,
+#else
+ #ifdef USE_GME_AY
+ gme_ay_type,
+ #endif
+ #ifdef USE_GME_GBS
+ gme_gbs_type,
+ #endif
+ #ifdef USE_GME_GYM
+ gme_gym_type,
+ #endif
+ #ifdef USE_GME_HES
+ gme_hes_type,
+ #endif
+ #ifdef USE_GME_KSS
+ gme_kss_type,
+ #endif
+ #ifdef USE_GME_NSF
+ gme_nsf_type,
+ #endif
+ #ifdef USE_GME_NSFE
+ gme_nsfe_type,
+ #endif
+ #ifdef USE_GME_SAP
+ gme_sap_type,
+ #endif
+ #ifdef USE_GME_SPC
+ gme_spc_type,
+ #endif
+ #ifdef USE_GME_VGM
+ gme_vgm_type,
+ gme_vgz_type,
+ #endif
+#endif
+ 0
+ };
+
+ return gme_type_list_;
+}
+
+BLARGG_EXPORT const char* gme_identify_header( void const* header )
+{
+ switch ( GET_BE32( header ) )
+ {
+ case BLARGG_4CHAR('Z','X','A','Y'): return "AY";
+ case BLARGG_4CHAR('G','B','S',0x01): return "GBS";
+ case BLARGG_4CHAR('G','Y','M','X'): return "GYM";
+ case BLARGG_4CHAR('H','E','S','M'): return "HES";
+ case BLARGG_4CHAR('K','S','C','C'):
+ case BLARGG_4CHAR('K','S','S','X'): return "KSS";
+ case BLARGG_4CHAR('N','E','S','M'): return "NSF";
+ case BLARGG_4CHAR('N','S','F','E'): return "NSFE";
+ case BLARGG_4CHAR('S','A','P',0x0D): return "SAP";
+ case BLARGG_4CHAR('S','N','E','S'): return "SPC";
+ case BLARGG_4CHAR('V','g','m',' '): return "VGM";
+ }
+ return "";
+}
+
+static void to_uppercase( const char* in, int len, char* out )
+{
+ for ( int i = 0; i < len; i++ )
+ {
+ if ( !(out [i] = toupper( in [i] )) )
+ return;
+ }
+ *out = 0; // extension too long
+}
+
+BLARGG_EXPORT gme_type_t gme_identify_extension( const char* extension_ )
+{
+ char const* end = strrchr( extension_, '.' );
+ if ( end )
+ extension_ = end + 1;
+
+ char extension [6];
+ to_uppercase( extension_, sizeof extension, extension );
+
+ for ( gme_type_t const* types = gme_type_list(); *types; types++ )
+ if ( !strcmp( extension, (*types)->extension_ ) )
+ return *types;
+ return 0;
+}
+
+BLARGG_EXPORT gme_err_t gme_identify_file( const char* path, gme_type_t* type_out )
+{
+ *type_out = gme_identify_extension( path );
+ // TODO: don't examine header if file has extension?
+ if ( !*type_out )
+ {
+ char header [4];
+ GME_FILE_READER in;
+ RETURN_ERR( in.open( path ) );
+ RETURN_ERR( in.read( header, sizeof header ) );
+ *type_out = gme_identify_extension( gme_identify_header( header ) );
+ }
+ return 0;
+}
+
+BLARGG_EXPORT gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate )
+{
+ require( (data || !size) && out );
+ *out = 0;
+
+ gme_type_t file_type = 0;
+ if ( size >= 4 )
+ file_type = gme_identify_extension( gme_identify_header( data ) );
+ if ( !file_type )
+ return gme_wrong_file_type;
+
+ Music_Emu* emu = gme_new_emu( file_type, sample_rate );
+ CHECK_ALLOC( emu );
+
+ gme_err_t err = gme_load_data( emu, data, size );
+
+ if ( err )
+ delete emu;
+ else
+ *out = emu;
+
+ return err;
+}
+
+BLARGG_EXPORT gme_err_t gme_open_file( const char* path, Music_Emu** out, int sample_rate )
+{
+ require( path && out );
+ *out = 0;
+
+ GME_FILE_READER in;
+ RETURN_ERR( in.open( path ) );
+
+ char header [4];
+ int header_size = 0;
+
+ gme_type_t file_type = gme_identify_extension( path );
+ if ( !file_type )
+ {
+ header_size = sizeof header;
+ RETURN_ERR( in.read( header, sizeof header ) );
+ file_type = gme_identify_extension( gme_identify_header( header ) );
+ }
+ if ( !file_type )
+ return gme_wrong_file_type;
+
+ Music_Emu* emu = gme_new_emu( file_type, sample_rate );
+ CHECK_ALLOC( emu );
+
+ // optimization: avoids seeking/re-reading header
+ Remaining_Reader rem( header, header_size, &in );
+ gme_err_t err = emu->load( rem );
+ in.close();
+
+ if ( err )
+ delete emu;
+ else
+ *out = emu;
+
+ return err;
+}
+
+BLARGG_EXPORT Music_Emu* gme_new_emu( gme_type_t type, int rate )
+{
+ if ( type )
+ {
+ if ( rate == gme_info_only )
+ return type->new_info();
+
+ Music_Emu* me = type->new_emu();
+ if ( me )
+ {
+ #if !GME_DISABLE_STEREO_DEPTH
+ if ( type->flags_ & 1 )
+ {
+ me->effects_buffer = BLARGG_NEW Effects_Buffer;
+ if ( me->effects_buffer )
+ me->set_buffer( me->effects_buffer );
+ }
+
+ if ( !(type->flags_ & 1) || me->effects_buffer )
+ #endif
+ {
+ if ( !me->set_sample_rate( rate ) )
+ {
+ check( me->type() == type );
+ return me;
+ }
+ }
+ delete me;
+ }
+ }
+ return 0;
+}
+
+BLARGG_EXPORT gme_err_t gme_load_file( Music_Emu* me, const char* path ) { return me->load_file( path ); }
+
+BLARGG_EXPORT gme_err_t gme_load_data( Music_Emu* me, void const* data, long size )
+{
+ Mem_File_Reader in( data, size );
+ return me->load( in );
+}
+
+BLARGG_EXPORT gme_err_t gme_load_custom( Music_Emu* me, gme_reader_t func, long size, void* data )
+{
+ Callback_Reader in( func, size, data );
+ return me->load( in );
+}
+
+BLARGG_EXPORT void gme_delete( Music_Emu* me ) { delete me; }
+
+BLARGG_EXPORT gme_type_t gme_type( Music_Emu const* me ) { return me->type(); }
+
+BLARGG_EXPORT const char* gme_warning( Music_Emu* me ) { return me->warning(); }
+
+BLARGG_EXPORT int gme_track_count( Music_Emu const* me ) { return me->track_count(); }
+
+struct gme_info_t_ : gme_info_t
+{
+ track_info_t info;
+};
+
+BLARGG_EXPORT gme_err_t gme_track_info( Music_Emu const* me, gme_info_t** out, int track )
+{
+ *out = nullptr;
+
+ gme_info_t_* info = BLARGG_NEW gme_info_t_;
+ CHECK_ALLOC( info );
+
+ gme_err_t err = me->track_info( &info->info, track );
+ if ( err )
+ {
+ gme_free_info( info );
+ return err;
+ }
+
+ #define COPY(name) info->name = info->info.name;
+
+ COPY( length );
+ COPY( intro_length );
+ COPY( loop_length );
+
+ info->i4 = -1;
+ info->i5 = -1;
+ info->i6 = -1;
+ info->i7 = -1;
+ info->i8 = -1;
+ info->i9 = -1;
+ info->i10 = -1;
+ info->i11 = -1;
+ info->i12 = -1;
+ info->i13 = -1;
+ info->i14 = -1;
+ info->i15 = -1;
+
+ info->s7 = "";
+ info->s8 = "";
+ info->s9 = "";
+ info->s10 = "";
+ info->s11 = "";
+ info->s12 = "";
+ info->s13 = "";
+ info->s14 = "";
+ info->s15 = "";
+
+ COPY( system );
+ COPY( game );
+ COPY( song );
+ COPY( author );
+ COPY( copyright );
+ COPY( comment );
+ COPY( dumper );
+
+ #undef COPY
+
+ info->play_length = info->length;
+ if ( info->play_length <= 0 )
+ {
+ info->play_length = info->intro_length + 2 * info->loop_length; // intro + 2 loops
+ if ( info->play_length <= 0 )
+ info->play_length = 150 * 1000; // 2.5 minutes
+ }
+
+ *out = info;
+
+ return 0;
+}
+
+BLARGG_EXPORT void gme_free_info( gme_info_t* info )
+{
+ delete STATIC_CAST(gme_info_t_*,info);
+}
+
+BLARGG_EXPORT void gme_set_stereo_depth( Music_Emu* me, double depth )
+{
+#if !GME_DISABLE_STEREO_DEPTH
+ if ( me->effects_buffer )
+ STATIC_CAST(Effects_Buffer*,me->effects_buffer)->set_depth( depth );
+#endif
+}
+
+BLARGG_EXPORT void* gme_user_data ( Music_Emu const* me ) { return me->user_data(); }
+BLARGG_EXPORT void gme_set_user_data ( Music_Emu* me, void* new_user_data ) { me->set_user_data( new_user_data ); }
+BLARGG_EXPORT void gme_set_user_cleanup(Music_Emu* me, gme_user_cleanup_t func ) { me->set_user_cleanup( func ); }
+
+BLARGG_EXPORT gme_err_t gme_start_track ( Music_Emu* me, int index ) { return me->start_track( index ); }
+BLARGG_EXPORT gme_err_t gme_play ( Music_Emu* me, int n, short* p ) { return me->play( n, p ); }
+BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
+BLARGG_EXPORT int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
+BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); }
+BLARGG_EXPORT gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); }
+BLARGG_EXPORT int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
+BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
+BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }
+BLARGG_EXPORT void gme_mute_voice ( Music_Emu* me, int index, int mute ) { me->mute_voice( index, mute != 0 ); }
+BLARGG_EXPORT void gme_mute_voices ( Music_Emu* me, int mask ) { me->mute_voices( mask ); }
+BLARGG_EXPORT void gme_enable_accuracy( Music_Emu* me, int enabled ) { me->enable_accuracy( enabled ); }
+BLARGG_EXPORT void gme_clear_playlist ( Music_Emu* me ) { me->clear_playlist(); }
+BLARGG_EXPORT int gme_type_multitrack( gme_type_t t ) { return t->track_count != 1; }
+
+BLARGG_EXPORT void gme_set_equalizer ( Music_Emu* me, gme_equalizer_t const* eq )
+{
+ Music_Emu::equalizer_t e = me->equalizer();
+ e.treble = eq->treble;
+ e.bass = eq->bass;
+ me->set_equalizer( e );
+}
+
+BLARGG_EXPORT void gme_equalizer( Music_Emu const* me, gme_equalizer_t* out )
+{
+ gme_equalizer_t e = { };
+ e.treble = me->equalizer().treble;
+ e.bass = me->equalizer().bass;
+ *out = e;
+}
+
+BLARGG_EXPORT const char* gme_voice_name( Music_Emu const* me, int i )
+{
+ assert( (unsigned) i < (unsigned) me->voice_count() );
+ return me->voice_names() [i];
+}
+
+BLARGG_EXPORT const char* gme_type_system( gme_type_t type )
+{
+ assert( type );
+ return type->system;
+}
diff --git a/src/console/gme.cxx b/src/console/gme.cxx
deleted file mode 100644
index 8dcc4e7ffb99..000000000000
--- a/src/console/gme.cxx
+++ /dev/null
@@ -1,374 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Music_Emu.h"
-
-#include "gme_types.h"
-#if !GME_DISABLE_STEREO_DEPTH
-#include "Effects_Buffer.h"
-#endif
-#include "blargg_endian.h"
-#include <string.h>
-#include <ctype.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-BLARGG_EXPORT gme_type_t const* gme_type_list()
-{
- static gme_type_t const gme_type_list_ [] = {
-#ifdef GME_TYPE_LIST
- GME_TYPE_LIST,
-#else
- #ifdef USE_GME_AY
- gme_ay_type,
- #endif
- #ifdef USE_GME_GBS
- gme_gbs_type,
- #endif
- #ifdef USE_GME_GYM
- gme_gym_type,
- #endif
- #ifdef USE_GME_HES
- gme_hes_type,
- #endif
- #ifdef USE_GME_KSS
- gme_kss_type,
- #endif
- #ifdef USE_GME_NSF
- gme_nsf_type,
- #endif
- #ifdef USE_GME_NSFE
- gme_nsfe_type,
- #endif
- #ifdef USE_GME_SAP
- gme_sap_type,
- #endif
- #ifdef USE_GME_SPC
- gme_spc_type,
- #endif
- #ifdef USE_GME_VGM
- gme_vgm_type,
- gme_vgz_type,
- #endif
-#endif
- 0
- };
-
- return gme_type_list_;
-}
-
-BLARGG_EXPORT const char* gme_identify_header( void const* header )
-{
- switch ( GET_BE32( header ) )
- {
- case BLARGG_4CHAR('Z','X','A','Y'): return "AY";
- case BLARGG_4CHAR('G','B','S',0x01): return "GBS";
- case BLARGG_4CHAR('G','Y','M','X'): return "GYM";
- case BLARGG_4CHAR('H','E','S','M'): return "HES";
- case BLARGG_4CHAR('K','S','C','C'):
- case BLARGG_4CHAR('K','S','S','X'): return "KSS";
- case BLARGG_4CHAR('N','E','S','M'): return "NSF";
- case BLARGG_4CHAR('N','S','F','E'): return "NSFE";
- case BLARGG_4CHAR('S','A','P',0x0D): return "SAP";
- case BLARGG_4CHAR('S','N','E','S'): return "SPC";
- case BLARGG_4CHAR('V','g','m',' '): return "VGM";
- }
- return "";
-}
-
-static void to_uppercase( const char* in, int len, char* out )
-{
- for ( int i = 0; i < len; i++ )
- {
- if ( !(out [i] = toupper( in [i] )) )
- return;
- }
- *out = 0; // extension too long
-}
-
-BLARGG_EXPORT gme_type_t gme_identify_extension( const char* extension_ )
-{
- char const* end = strrchr( extension_, '.' );
- if ( end )
- extension_ = end + 1;
-
- char extension [6];
- to_uppercase( extension_, sizeof extension, extension );
-
- for ( gme_type_t const* types = gme_type_list(); *types; types++ )
- if ( !strcmp( extension, (*types)->extension_ ) )
- return *types;
- return 0;
-}
-
-BLARGG_EXPORT gme_err_t gme_identify_file( const char* path, gme_type_t* type_out )
-{
- *type_out = gme_identify_extension( path );
- // TODO: don't examine header if file has extension?
- if ( !*type_out )
- {
- char header [4];
- GME_FILE_READER in;
- RETURN_ERR( in.open( path ) );
- RETURN_ERR( in.read( header, sizeof header ) );
- *type_out = gme_identify_extension( gme_identify_header( header ) );
- }
- return 0;
-}
-
-BLARGG_EXPORT gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate )
-{
- require( (data || !size) && out );
- *out = 0;
-
- gme_type_t file_type = 0;
- if ( size >= 4 )
- file_type = gme_identify_extension( gme_identify_header( data ) );
- if ( !file_type )
- return gme_wrong_file_type;
-
- Music_Emu* emu = gme_new_emu( file_type, sample_rate );
- CHECK_ALLOC( emu );
-
- gme_err_t err = gme_load_data( emu, data, size );
-
- if ( err )
- delete emu;
- else
- *out = emu;
-
- return err;
-}
-
-BLARGG_EXPORT gme_err_t gme_open_file( const char* path, Music_Emu** out, int sample_rate )
-{
- require( path && out );
- *out = 0;
-
- GME_FILE_READER in;
- RETURN_ERR( in.open( path ) );
-
- char header [4];
- int header_size = 0;
-
- gme_type_t file_type = gme_identify_extension( path );
- if ( !file_type )
- {
- header_size = sizeof header;
- RETURN_ERR( in.read( header, sizeof header ) );
- file_type = gme_identify_extension( gme_identify_header( header ) );
- }
- if ( !file_type )
- return gme_wrong_file_type;
-
- Music_Emu* emu = gme_new_emu( file_type, sample_rate );
- CHECK_ALLOC( emu );
-
- // optimization: avoids seeking/re-reading header
- Remaining_Reader rem( header, header_size, &in );
- gme_err_t err = emu->load( rem );
- in.close();
-
- if ( err )
- delete emu;
- else
- *out = emu;
-
- return err;
-}
-
-BLARGG_EXPORT Music_Emu* gme_new_emu( gme_type_t type, int rate )
-{
- if ( type )
- {
- if ( rate == gme_info_only )
- return type->new_info();
-
- Music_Emu* me = type->new_emu();
- if ( me )
- {
- #if !GME_DISABLE_STEREO_DEPTH
- if ( type->flags_ & 1 )
- {
- me->effects_buffer = BLARGG_NEW Effects_Buffer;
- if ( me->effects_buffer )
- me->set_buffer( me->effects_buffer );
- }
-
- if ( !(type->flags_ & 1) || me->effects_buffer )
- #endif
- {
- if ( !me->set_sample_rate( rate ) )
- {
- check( me->type() == type );
- return me;
- }
- }
- delete me;
- }
- }
- return 0;
-}
-
-BLARGG_EXPORT gme_err_t gme_load_file( Music_Emu* me, const char* path ) { return me->load_file( path ); }
-
-BLARGG_EXPORT gme_err_t gme_load_data( Music_Emu* me, void const* data, long size )
-{
- Mem_File_Reader in( data, size );
- return me->load( in );
-}
-
-BLARGG_EXPORT gme_err_t gme_load_custom( Music_Emu* me, gme_reader_t func, long size, void* data )
-{
- Callback_Reader in( func, size, data );
- return me->load( in );
-}
-
-BLARGG_EXPORT void gme_delete( Music_Emu* me ) { delete me; }
-
-BLARGG_EXPORT gme_type_t gme_type( Music_Emu const* me ) { return me->type(); }
-
-BLARGG_EXPORT const char* gme_warning( Music_Emu* me ) { return me->warning(); }
-
-BLARGG_EXPORT int gme_track_count( Music_Emu const* me ) { return me->track_count(); }
-
-struct gme_info_t_ : gme_info_t
-{
- track_info_t info;
-};
-
-BLARGG_EXPORT gme_err_t gme_track_info( Music_Emu const* me, gme_info_t** out, int track )
-{
- *out = NULL;
-
- gme_info_t_* info = BLARGG_NEW gme_info_t_;
- CHECK_ALLOC( info );
-
- gme_err_t err = me->track_info( &info->info, track );
- if ( err )
- {
- gme_free_info( info );
- return err;
- }
-
- #define COPY(name) info->name = info->info.name;
-
- COPY( length );
- COPY( intro_length );
- COPY( loop_length );
-
- info->i4 = -1;
- info->i5 = -1;
- info->i6 = -1;
- info->i7 = -1;
- info->i8 = -1;
- info->i9 = -1;
- info->i10 = -1;
- info->i11 = -1;
- info->i12 = -1;
- info->i13 = -1;
- info->i14 = -1;
- info->i15 = -1;
-
- info->s7 = "";
- info->s8 = "";
- info->s9 = "";
- info->s10 = "";
- info->s11 = "";
- info->s12 = "";
- info->s13 = "";
- info->s14 = "";
- info->s15 = "";
-
- COPY( system );
- COPY( game );
- COPY( song );
- COPY( author );
- COPY( copyright );
- COPY( comment );
- COPY( dumper );
-
- #undef COPY
-
- info->play_length = info->length;
- if ( info->play_length <= 0 )
- {
- info->play_length = info->intro_length + 2 * info->loop_length; // intro + 2 loops
- if ( info->play_length <= 0 )
- info->play_length = 150 * 1000; // 2.5 minutes
- }
-
- *out = info;
-
- return 0;
-}
-
-BLARGG_EXPORT void gme_free_info( gme_info_t* info )
-{
- delete STATIC_CAST(gme_info_t_*,info);
-}
-
-BLARGG_EXPORT void gme_set_stereo_depth( Music_Emu* me, double depth )
-{
-#if !GME_DISABLE_STEREO_DEPTH
- if ( me->effects_buffer )
- STATIC_CAST(Effects_Buffer*,me->effects_buffer)->set_depth( depth );
-#endif
-}
-
-BLARGG_EXPORT void* gme_user_data ( Music_Emu const* me ) { return me->user_data(); }
-BLARGG_EXPORT void gme_set_user_data ( Music_Emu* me, void* new_user_data ) { me->set_user_data( new_user_data ); }
-BLARGG_EXPORT void gme_set_user_cleanup(Music_Emu* me, gme_user_cleanup_t func ) { me->set_user_cleanup( func ); }
-
-BLARGG_EXPORT gme_err_t gme_start_track ( Music_Emu* me, int index ) { return me->start_track( index ); }
-BLARGG_EXPORT gme_err_t gme_play ( Music_Emu* me, int n, short* p ) { return me->play( n, p ); }
-BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
-BLARGG_EXPORT int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
-BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); }
-BLARGG_EXPORT gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); }
-BLARGG_EXPORT int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
-BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
-BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }
-BLARGG_EXPORT void gme_mute_voice ( Music_Emu* me, int index, int mute ) { me->mute_voice( index, mute != 0 ); }
-BLARGG_EXPORT void gme_mute_voices ( Music_Emu* me, int mask ) { me->mute_voices( mask ); }
-BLARGG_EXPORT void gme_enable_accuracy( Music_Emu* me, int enabled ) { me->enable_accuracy( enabled ); }
-BLARGG_EXPORT void gme_clear_playlist ( Music_Emu* me ) { me->clear_playlist(); }
-BLARGG_EXPORT int gme_type_multitrack( gme_type_t t ) { return t->track_count != 1; }
-
-BLARGG_EXPORT void gme_set_equalizer ( Music_Emu* me, gme_equalizer_t const* eq )
-{
- Music_Emu::equalizer_t e = me->equalizer();
- e.treble = eq->treble;
- e.bass = eq->bass;
- me->set_equalizer( e );
-}
-
-BLARGG_EXPORT void gme_equalizer( Music_Emu const* me, gme_equalizer_t* out )
-{
- gme_equalizer_t e = { };
- e.treble = me->equalizer().treble;
- e.bass = me->equalizer().bass;
- *out = e;
-}
-
-BLARGG_EXPORT const char* gme_voice_name( Music_Emu const* me, int i )
-{
- assert( (unsigned) i < (unsigned) me->voice_count() );
- return me->voice_names() [i];
-}
-
-BLARGG_EXPORT const char* gme_type_system( gme_type_t type )
-{
- assert( type );
- return type->system;
-}
diff --git a/src/console/gme.h b/src/console/gme.h
index b6648d8f57c3..2d18b21d6098 100644
--- a/src/console/gme.h
+++ b/src/console/gme.h
@@ -4,11 +4,7 @@
#ifndef GME_H
#define GME_H
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Error string returned by library functions, or NULL if no error (success) */
+/* Error string returned by library functions, or nullptr if no error (success) */
typedef const char* gme_err_t;
/* First parameter of most gme_ functions is a pointer to the Music_Emu */
@@ -55,7 +51,7 @@ gme_err_t gme_seek( Music_Emu*, int msec );
sample_rate to open/load. */
enum { gme_info_only = -1 };
-/* Most recent warning string, or NULL if none. Clears current warning after returning.
+/* Most recent warning string, or nullptr if none. Clears current warning after returning.
Warning is also cleared when loading a file and starting a track. */
const char* gme_warning( Music_Emu* );
@@ -148,7 +144,7 @@ void gme_enable_accuracy( Music_Emu*, int enabled );
/******** Game music types ********/
-/* Music file type identifier. Can also hold NULL. */
+/* Music file type identifier. Can also hold nullptr. */
typedef const struct gme_type_t_* gme_type_t;
/* Emulator type constants for each supported file type */
@@ -168,7 +164,7 @@ extern const gme_type_t
/* Type of this emulator */
gme_type_t gme_type( Music_Emu const* );
-/* Pointer to array of all music types, with NULL entry at end. Allows a player linked
+/* Pointer to array of all music types, with nullptr entry at end. Allows a player linked
to this library to support new music types without having to be updated. */
gme_type_t const* gme_type_list();
@@ -199,7 +195,7 @@ gme_type_t gme_identify_extension( const char path_or_extension [] );
Sets *type_out to type, or 0 if unrecognized or error. */
gme_err_t gme_identify_file( const char path [], gme_type_t* type_out );
-/* Create new emulator and set sample rate. Returns NULL if out of memory. If you only need
+/* Create new emulator and set sample rate. Returns nullptr if out of memory. If you only need
track information, pass gme_info_only for sample_rate. */
Music_Emu* gme_new_emu( gme_type_t, int sample_rate );
@@ -225,14 +221,9 @@ You can use this for whatever you want. */
void gme_set_user_data( Music_Emu*, void* new_user_data );
void* gme_user_data( Music_Emu const* );
-/* Register cleanup function to be called when deleting emulator, or NULL to
+/* Register cleanup function to be called when deleting emulator, or nullptr to
clear it. Passes user_data to cleanup function. */
typedef void (*gme_user_cleanup_t)( void* user_data );
void gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func );
-
-#ifdef __cplusplus
- }
-#endif
-
#endif
diff --git a/src/console/gme_design.txt b/src/console/gme_design.txt
index 579a989fa4a7..ccb9addf075e 100644
--- a/src/console/gme_design.txt
+++ b/src/console/gme_design.txt
@@ -36,7 +36,7 @@ any functions which automatically select it based on a file's extension
or header contents. For each emulator type there is a global object with
pointers to functions to create the emulator or a track information
reader. The emulator type is thus a pointer to this, which conveniently
-allows for a NULL value. The user referencing this emulator type object
+allows for a nullptr value. The user referencing this emulator type object
is what ultimately links the emulator in (unless new Foo_Emu is used in
C++, of course).
diff --git a/src/console/gme_notes.txt b/src/console/gme_notes.txt
index b3ce1e63a5b4..19ddafabd602 100644
--- a/src/console/gme_notes.txt
+++ b/src/console/gme_notes.txt
@@ -84,7 +84,7 @@ Error handling
--------------
Functions which can fail have a return type of gme_err_t, which is a
pointer to an error string (const char*). If a function is successful it
-returns NULL. Errors that you can easily avoid are checked with debug
+returns nullptr. Errors that you can easily avoid are checked with debug
assertions; gme_err_t return values are only used for genuine run-time
errors that can't be easily predicted in advance (out of memory, I/O
errors, incompatible file data). Your code should check all error
@@ -93,7 +93,7 @@ values.
To improve usability for C programmers, C++ programmers unfamiliar with
exceptions, and compatibility with older C++ compilers, the library does
*not* throw any C++ exceptions and uses malloc() instead of the standard
-operator new. This means that you *must* check for NULL when creating a
+operator new. This means that you *must* check for nullptr when creating a
library object with the new operator.
When loading a music file in the wrong emulator or trying to load a
@@ -244,7 +244,7 @@ load_file() with the path of a file:
// code that reads 'count' bytes into 'out' buffer
// and return 0 if no error
}
-
+
gme_load_custom( music_emu, my_read, file_size, my_data );
* If you must load the file data into memory yourself, you can have the
@@ -259,11 +259,11 @@ performance reasons, use Remaining_Reader:
Std_File_Reader in;
in.open( file_path );
-
+
char header [4];
in.read( &header, sizeof header );
...
-
+
Remaining_Reader rem( &header, sizeof header, &in );
music_emu->load( rem );
diff --git a/src/console/gme_type_list.cc b/src/console/gme_type_list.cc
new file mode 100644
index 000000000000..00a72ad3b0e8
--- /dev/null
+++ b/src/console/gme_type_list.cc
@@ -0,0 +1,38 @@
+// Game_Music_Emu 0.5.1. http://www.slack.net/~ant/
+
+// separate file to avoid linking all emulators if this is not used
+
+#include "gme.h"
+
+/* Copyright (C) 2006 Shay Green. This module 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
+module 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 module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+gme_type_t const* gme_type_list()
+{
+ static gme_type_t const gme_type_list_ [] =
+ {
+ gme_ay_type,
+ gme_gbs_type,
+ gme_gym_type,
+ gme_hes_type,
+ gme_kss_type,
+ gme_nsf_type,
+ gme_nsfe_type,
+ gme_sap_type,
+ gme_spc_type,
+ gme_vgm_type,
+ gme_vgz_type,
+ 0
+ };
+ return gme_type_list_;
+}
diff --git a/src/console/gme_type_list.cxx b/src/console/gme_type_list.cxx
deleted file mode 100644
index 00a72ad3b0e8..000000000000
--- a/src/console/gme_type_list.cxx
+++ /dev/null
@@ -1,38 +0,0 @@
-// Game_Music_Emu 0.5.1. http://www.slack.net/~ant/
-
-// separate file to avoid linking all emulators if this is not used
-
-#include "gme.h"
-
-/* Copyright (C) 2006 Shay Green. This module 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
-module 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 module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-gme_type_t const* gme_type_list()
-{
- static gme_type_t const gme_type_list_ [] =
- {
- gme_ay_type,
- gme_gbs_type,
- gme_gym_type,
- gme_hes_type,
- gme_kss_type,
- gme_nsf_type,
- gme_nsfe_type,
- gme_sap_type,
- gme_spc_type,
- gme_vgm_type,
- gme_vgz_type,
- 0
- };
- return gme_type_list_;
-}
diff --git a/src/console/plugin.c b/src/console/plugin.c
deleted file mode 100644
index e9611edfaf7c..000000000000
--- a/src/console/plugin.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Audacious: Cross platform multimedia player
- * Copyright (c) 2009 Audacious Team
- *
- * Driver for Game_Music_Emu library. See details at:
- * http://www.slack.net/~ant/libs/
- */
-
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-#include "configure.h"
-
-Tuple * console_probe_for_tuple(const char *filename, VFSFile *fd);
-bool_t console_play(const char *filename, VFSFile *file);
-
-static const char console_about[] =
- N_("Console music decoder engine based on Game_Music_Emu 0.5.2\n"
- "Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n\n"
- "Audacious plugin by:\n"
- "William Pitcock <nenolod at dereferenced.org>\n"
- "Shay Green <gblargg at gmail.com>");
-
-static const char *gme_fmts[] = {
- "ay", "gbs", "gym",
- "hes", "kss", "nsf",
- "nsfe", "sap", "spc",
- "vgm", "vgz", NULL
-};
-
-static const PreferencesWidget console_widgets[] = {
- {WIDGET_LABEL, N_("<b>Playback</b>")},
- {WIDGET_SPIN_BTN, N_("Bass:"), .data = {.spin_btn = {-100, 100, 1}},
- .cfg_type = VALUE_INT, .cfg = & audcfg.bass},
- {WIDGET_SPIN_BTN, N_("Treble:"), .data = {.spin_btn = {-100, 100, 1}},
- .cfg_type = VALUE_INT, .cfg = & audcfg.treble},
- {WIDGET_SPIN_BTN, N_("Echo:"), .data = {.spin_btn = {0, 100, 1}},
- .cfg_type = VALUE_INT, .cfg = & audcfg.echo},
- {WIDGET_SPIN_BTN, N_("Default song length:"),
- .data = {.spin_btn = {-100, 100, 1, N_("seconds")}},
- .cfg_type = VALUE_INT, .cfg = & audcfg.loop_length},
- {WIDGET_LABEL, N_("<b>Resampling</b>")},
- {WIDGET_CHK_BTN, N_("Enable audio resampling"),
- .cfg_type = VALUE_BOOLEAN, .cfg = & audcfg.resample},
- {WIDGET_SPIN_BTN, N_("Resampling rate:"), .child = TRUE,
- .data = {.spin_btn = {11025, 96000, 100, N_("Hz")}},
- .cfg_type = VALUE_INT, .cfg = & audcfg.resample_rate},
- {WIDGET_LABEL, N_("<b>SPC</b>")},
- {WIDGET_CHK_BTN, N_("Ignore length from SPC tags"),
- .cfg_type = VALUE_BOOLEAN, .cfg = & audcfg.ignore_spc_length},
- {WIDGET_CHK_BTN, N_("Increase reverb"),
- .cfg_type = VALUE_BOOLEAN, .cfg = & audcfg.inc_spc_reverb}};
-
-static const PluginPreferences console_prefs = {
- .widgets = console_widgets,
- .n_widgets = ARRAY_LEN (console_widgets)};
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("Game Console Music Decoder"),
- .domain = PACKAGE,
- .about_text = console_about,
- .init = console_cfg_load,
- .cleanup = console_cfg_save,
- .prefs = & console_prefs,
- .play = console_play,
- .extensions = gme_fmts,
- .probe_for_tuple = console_probe_for_tuple,
- .have_subtune = TRUE
-)
diff --git a/src/console/plugin.cc b/src/console/plugin.cc
new file mode 100644
index 000000000000..c75ee8bae83f
--- /dev/null
+++ b/src/console/plugin.cc
@@ -0,0 +1,56 @@
+/*
+ * Audacious: Cross platform multimedia player
+ * Copyright (c) 2009 Audacious Team
+ *
+ * Driver for Game_Music_Emu library. See details at:
+ * http://www.slack.net/~ant/libs/
+ */
+
+#include "configure.h"
+#include "plugin.h"
+
+EXPORT ConsolePlugin aud_plugin_instance;
+
+const char ConsolePlugin::about[] =
+ N_("Console music decoder engine based on Game_Music_Emu 0.5.2\n"
+ "Supported formats: AY, GBS, GYM, HES, KSS, NSF, NSFE, SAP, SPC, VGM, VGZ\n\n"
+ "Audacious plugin by:\n"
+ "William Pitcock <nenolod at dereferenced.org>\n"
+ "Shay Green <gblargg at gmail.com>");
+
+const char * const ConsolePlugin::exts[] = {
+ "ay", "gbs", "gym",
+ "hes", "kss", "nsf",
+ "nsfe", "sap", "spc",
+ "vgm", "vgz", nullptr
+};
+
+const PreferencesWidget ConsolePlugin::widgets[] = {
+ WidgetLabel (N_("<b>Playback</b>")),
+ WidgetSpin (N_("Bass:"),
+ WidgetInt (audcfg.bass),
+ {-100, 100, 1}),
+ WidgetSpin (N_("Treble:"),
+ WidgetInt (audcfg.treble),
+ {-100, 100, 1}),
+ WidgetSpin (N_("Echo:"),
+ WidgetInt (audcfg.echo),
+ {0, 100, 1}),
+ WidgetSpin (N_("Default song length:"),
+ WidgetInt (audcfg.loop_length),
+ {-100, 100, 1, N_("seconds")}),
+ WidgetLabel (N_("<b>Resampling</b>")),
+ WidgetCheck (N_("Enable audio resampling"),
+ WidgetBool (audcfg.resample)),
+ WidgetSpin (N_("Sample rate:"),
+ WidgetInt (audcfg.resample_rate),
+ {11025, 96000, 100, N_("Hz")},
+ WIDGET_CHILD),
+ WidgetLabel (N_("<b>SPC</b>")),
+ WidgetCheck (N_("Ignore length from SPC tags"),
+ WidgetBool (audcfg.ignore_spc_length)),
+ WidgetCheck (N_("Increase reverb"),
+ WidgetBool (audcfg.inc_spc_reverb))
+};
+
+const PluginPreferences ConsolePlugin::prefs = {{widgets}};
diff --git a/src/console/plugin.h b/src/console/plugin.h
new file mode 100644
index 000000000000..1c24eef841eb
--- /dev/null
+++ b/src/console/plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Audacious: Cross platform multimedia player
+ * Copyright (c) 2009-2014 Audacious Team
+ *
+ * Driver for Game_Music_Emu library. See details at:
+ * http://www.slack.net/~ant/libs/
+ */
+
+#ifndef CONSOLE_PLUGIN_H
+#define CONSOLE_PLUGIN_H
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+
+class ConsolePlugin : public InputPlugin
+{
+public:
+ static const char about[];
+ static const char * const exts[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Game Console Music Decoder"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ static constexpr auto iinfo = InputInfo (FlagSubtunes)
+ .with_exts (exts);
+
+ constexpr ConsolePlugin () : InputPlugin (info, iinfo) {}
+
+ bool init ();
+ void cleanup ();
+
+ bool is_our_file (const char * filename, VFSFile & file)
+ { return false; }
+
+ Tuple read_tuple (const char * filename, VFSFile & file);
+ bool play (const char * filename, VFSFile & file);
+};
+
+#endif // CONSOLE_PLUGIN_H
diff --git a/src/console/sap_cpu_io.h b/src/console/sap_cpu_io.h
index 3103ecdb6fad..e2acbacf069e 100644
--- a/src/console/sap_cpu_io.h
+++ b/src/console/sap_cpu_io.h
@@ -4,6 +4,7 @@
#include "blargg_source.h"
#define CPU_WRITE( cpu, addr, data, time ) STATIC_CAST(Sap_Emu&,*cpu).cpu_write( addr, data )
+#define CPU_READ( cpu, addr, time ) STATIC_CAST(Sap_Emu&,*cpu).cpu_read( addr )
void Sap_Emu::cpu_write( sap_addr_t addr, int data )
{
@@ -12,15 +13,22 @@ void Sap_Emu::cpu_write( sap_addr_t addr, int data )
cpu_write_( addr, data );
}
-#ifdef NDEBUG
- #define CPU_READ( cpu, addr, time ) READ_LOW( addr )
-#else
- #define CPU_READ( cpu, addr, time ) STATIC_CAST(Sap_Emu&,*cpu).cpu_read( addr )
-
int Sap_Emu::cpu_read( sap_addr_t addr )
{
- if ( (addr & 0xF900) == 0xD000 )
+ switch ( (addr & 0xFF1F) )
+ {
+ case 0xD000:
debug_printf( "Unmapped read $%04X\n", addr );
+ break;
+ case 0xD014:
+ return info.ntsc ? 0xf : 1;
+ case 0xD40B:
+ case 0xD41B:
+ if ( time() > ( info.ntsc ? 262 : 312 ) * 114 )
+ return 0;
+ return time() / 228;
+ default:
+ break;
+ }
return mem.ram [addr];
}
-#endif
diff --git a/src/coreaudio/Makefile b/src/coreaudio/Makefile
new file mode 100644
index 000000000000..d1faefd88af4
--- /dev/null
+++ b/src/coreaudio/Makefile
@@ -0,0 +1,13 @@
+PLUGIN = coreaudio${PLUGIN_SUFFIX}
+
+SRCS = coreaudio.cc
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+plugindir := ${plugindir}/${OUTPUT_PLUGIN_DIR}
+
+LD = ${CXX}
+CPPFLAGS += -I../..
+CXXFLAGS += ${PLUGIN_CFLAGS}
+LIBS += -lm -framework CoreAudio
diff --git a/src/coreaudio/coreaudio.cc b/src/coreaudio/coreaudio.cc
new file mode 100644
index 000000000000..e2af9b3c931c
--- /dev/null
+++ b/src/coreaudio/coreaudio.cc
@@ -0,0 +1,470 @@
+/*
+ * CoreAudio Output Plugin for Audacious
+ * Copyright 2014 William Pitcock
+ *
+ * Based on:
+ * SDL Output Plugin for Audacious
+ * Copyright 2010 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <math.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/ringbuf.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/preferences.h>
+
+#include <CoreAudio/CoreAudio.h>
+#include <AudioUnit/AudioUnit.h>
+
+class CoreAudioPlugin : public OutputPlugin {
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("CoreAudio output"),
+ PACKAGE,
+ about,
+ & prefs,
+ };
+
+ constexpr CoreAudioPlugin () : OutputPlugin (info, 5) {}
+
+ bool init ();
+ void cleanup ();
+
+ StereoVolume get_volume ();
+ void set_volume (StereoVolume vol);
+
+ bool open_audio (int format, int rate_, int chan_);
+ void close_audio ();
+
+ void period_wait ();
+ int write_audio (const void * data, int len);
+ void drain ();
+
+ int get_delay ();
+ void pause (bool paused);
+ void flush ();
+
+protected:
+ static OSStatus callback (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
+ void check_started ();
+};
+
+EXPORT CoreAudioPlugin aud_plugin_instance;
+
+#define VOLUME_RANGE 40 /* decibels */
+
+#define error(...) do { \
+ aud_ui_show_error (str_printf ("CoreAudio error: " __VA_ARGS__)); \
+} while (0)
+
+struct AudioUnitFormatDescriptionMap {
+ int aud_format;
+ unsigned int mBitsPerChannel;
+ unsigned int mBytesPerChannel;
+ unsigned int mFormatFlags;
+};
+static struct AudioUnitFormatDescriptionMap AUFormatMap[] = {
+ {FMT_S16_LE, 16, sizeof (int16_t), kAudioFormatFlagIsSignedInteger},
+ {FMT_S16_BE, 16, sizeof (int16_t), kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsBigEndian},
+ {FMT_U16_LE, 16, sizeof (int16_t), 0},
+ {FMT_U16_BE, 16, sizeof (int16_t), kAudioFormatFlagIsBigEndian},
+ {FMT_S24_LE, 24, sizeof (int32_t), kAudioFormatFlagIsSignedInteger},
+ {FMT_S24_BE, 24, sizeof (int32_t), kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsBigEndian},
+ {FMT_U24_LE, 24, sizeof (int32_t), 0},
+ {FMT_U24_BE, 24, sizeof (int32_t), kAudioFormatFlagIsBigEndian},
+ {FMT_S32_LE, 32, sizeof (int32_t), kAudioFormatFlagIsSignedInteger},
+ {FMT_S32_BE, 32, sizeof (int32_t), kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsBigEndian},
+ {FMT_U32_LE, 32, sizeof (int32_t), 0},
+ {FMT_U32_BE, 32, sizeof (int32_t), kAudioFormatFlagIsBigEndian},
+ {FMT_FLOAT, 32, sizeof (float), kAudioFormatFlagIsFloat},
+};
+
+static RingBuf <unsigned char> buffer;
+static int vol_left = 0, vol_right = 0;
+static int chan = 0;
+static int rate = 0;
+static int buffer_bytes_per_channel = 0;
+
+static bool prebuffer_flag = false;
+static bool paused_flag = false;
+
+static int block_delay = 0;
+static struct timeval block_time = {0, 0};
+
+static AudioComponent output_comp = nullptr;
+static AudioComponentInstance output_instance = nullptr;
+
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+
+static bool is_exclusive = false;
+
+const char CoreAudioPlugin::about[] =
+ N_("CoreAudio Output Plugin for Audacious\n"
+ "Copyright 2014 William Pitcock\n\n"
+ "Based on SDL Output Plugin for Audacious\n"
+ "Copyright 2010 John Lindgren");
+
+const char * const CoreAudioPlugin::defaults[] = {
+ "vol_left", "100",
+ "vol_right", "100",
+ "exclusive_mode", "FALSE",
+ nullptr};
+
+const PreferencesWidget CoreAudioPlugin::widgets[] = {
+ WidgetCheck (N_("Use exclusive mode"),
+ WidgetBool ("coreaudio", "exclusive_mode")),
+};
+
+const PluginPreferences CoreAudioPlugin::prefs = {
+ {widgets},
+ nullptr,
+ nullptr,
+ nullptr
+};
+
+bool CoreAudioPlugin::init (void)
+{
+ aud_config_set_defaults ("coreaudio", defaults);
+
+ vol_left = aud_get_int ("coreaudio", "vol_left");
+ vol_right = aud_get_int ("coreaudio", "vol_right");
+
+ /* open the default audio device */
+ AudioComponentDescription desc;
+ desc.componentType = kAudioUnitType_Output;
+ desc.componentSubType = kAudioUnitSubType_DefaultOutput;
+ desc.componentFlags = 0;
+ desc.componentFlagsMask = 0;
+ desc.componentManufacturer = 0;
+
+ output_comp = AudioComponentFindNext (NULL, & desc);
+ if (! output_comp)
+ {
+ error ("Failed to open default audio device.\n");
+ return 0;
+ }
+
+ if (AudioComponentInstanceNew (output_comp, & output_instance))
+ {
+ error ("Failed to open default audio device.\n");
+ return 0;
+ }
+
+ AURenderCallbackStruct input;
+ input.inputProc = callback;
+ input.inputProcRefCon = this;
+
+ if (AudioUnitSetProperty (output_instance, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, & input, sizeof input))
+ {
+ error ("Unable to attach an IOProc to the selected audio unit.\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+void CoreAudioPlugin::cleanup (void)
+{
+}
+
+StereoVolume CoreAudioPlugin::get_volume ()
+{
+ return {vol_left, vol_right};
+}
+
+void CoreAudioPlugin::set_volume (StereoVolume vol)
+{
+ int vol_max;
+ float factor;
+
+ vol_left = vol.left;
+ vol_right = vol.right;
+
+ vol_max = aud::max (vol_left, vol_right);
+
+ aud_set_int ("coreaudio", "vol_left", vol_left);
+ aud_set_int ("coreaudio", "vol_right", vol_right);
+
+ factor = (vol_max == 0) ? 0.0 : powf (10, (float) VOLUME_RANGE * (vol_max - 100) / 100 / 20);
+
+ AudioUnitSetParameter (output_instance, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, factor, 0);
+}
+
+OSStatus CoreAudioPlugin::callback (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
+{
+ pthread_mutex_lock (& mutex);
+
+ int len = ioData->mBuffers[0].mDataByteSize;
+ unsigned char * buf = (unsigned char *) ioData->mBuffers[0].mData;
+ ioData->mBuffers[0].mNumberChannels = chan;
+
+ int copy = aud::min (len, buffer.len ());
+
+ buffer.move_out (buf, copy);
+ if (copy < len)
+ memset (buf + copy, 0, len - copy);
+
+ /* At this moment, we know that there is a delay of (at least) the block of
+ * data just written. We save the block size and the current time for
+ * estimating the delay later on. */
+ block_delay = copy / (buffer_bytes_per_channel * chan) * 1000 / rate;
+ gettimeofday (& block_time, nullptr);
+
+ pthread_cond_broadcast (& cond);
+ pthread_mutex_unlock (& mutex);
+
+ return 0;
+}
+
+bool CoreAudioPlugin::open_audio (int format, int rate_, int chan_)
+{
+ struct AudioUnitFormatDescriptionMap * m = nullptr;
+
+ for (struct AudioUnitFormatDescriptionMap it : AUFormatMap)
+ {
+ if (it.aud_format == format)
+ {
+ m = & it;
+ break;
+ }
+ }
+
+ if (! m)
+ {
+ error ("The requested audio format %d is unsupported.\n", format);
+ return 0;
+ }
+
+ AUDDBG ("Opening audio for %d channels, %d Hz.\n", chan, rate);
+
+ chan = chan_;
+ rate = rate_;
+
+ buffer_bytes_per_channel = m->mBytesPerChannel;
+
+ int buffer_size = buffer_bytes_per_channel * chan * (aud_get_int (nullptr, "output_buffer_size") * rate / 1000);
+ buffer.alloc (buffer_size);
+
+ prebuffer_flag = true;
+ paused_flag = false;
+
+ if (AudioUnitInitialize (output_instance))
+ {
+ error ("Unable to initialize audio unit instance\n");
+ return 0;
+ }
+
+ AudioStreamBasicDescription streamFormat;
+ streamFormat.mSampleRate = rate;
+ streamFormat.mFormatID = kAudioFormatLinearPCM;
+ streamFormat.mFormatFlags = m->mFormatFlags;
+ streamFormat.mFramesPerPacket = 1;
+ streamFormat.mChannelsPerFrame = chan;
+ streamFormat.mBitsPerChannel = m->mBitsPerChannel;
+ streamFormat.mBytesPerPacket = chan * buffer_bytes_per_channel;
+ streamFormat.mBytesPerFrame = chan * buffer_bytes_per_channel;
+
+ AUDDBG("Stream format:\n");
+ AUDDBG(" Channels: %d\n", streamFormat.mChannelsPerFrame);
+ AUDDBG(" Sample rate: %f\n", streamFormat.mSampleRate);
+ AUDDBG(" Bits per channel: %d\n", streamFormat.mBitsPerChannel);
+ AUDDBG(" Bytes per frame: %d\n", streamFormat.mBytesPerFrame);
+
+ if (AudioUnitSetProperty (output_instance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamFormat, sizeof(streamFormat)))
+ {
+ error ("Failed to set audio unit input property.\n");
+ buffer.destroy ();
+ return 0;
+ }
+
+ bool exclusive = aud_get_bool ("coreaudio", "exclusive_mode");
+ if (exclusive)
+ {
+ UInt32 hog_mode = 1;
+
+ AudioObjectPropertyAddress prop;
+
+ prop.mSelector = kAudioDevicePropertyHogMode;
+ prop.mScope = kAudioObjectPropertyScopeGlobal;
+ prop.mElement = kAudioObjectPropertyElementMaster;
+
+ OSStatus err = AudioObjectSetPropertyData (kAudioObjectSystemObject, & prop, 0, NULL, sizeof hog_mode, & hog_mode);
+ if (err != noErr)
+ {
+ AUDWARN ("Failed to open device for exclusive mode, continuing anyway... [%d]\n", err);
+ is_exclusive = false;
+ }
+ else
+ is_exclusive = true;
+ }
+
+ if (AudioOutputUnitStart (output_instance))
+ {
+ error ("Unable to start audio unit.\n");
+ buffer.destroy ();
+ return 0;
+ }
+
+ return 1;
+}
+
+void CoreAudioPlugin::close_audio ()
+{
+ AUDDBG ("Closing audio.\n");
+
+ AudioOutputUnitStop (output_instance);
+
+ if (is_exclusive)
+ {
+ UInt32 hog_mode = 0;
+
+ AudioObjectPropertyAddress prop;
+
+ prop.mSelector = kAudioDevicePropertyHogMode;
+ prop.mScope = kAudioObjectPropertyScopeGlobal;
+ prop.mElement = kAudioObjectPropertyElementMaster;
+
+ OSStatus err = AudioObjectSetPropertyData (kAudioObjectSystemObject, & prop, 0, NULL, sizeof hog_mode, & hog_mode);
+ if (err != noErr)
+ AUDWARN ("Failed to release device from exclusive mode, continuing anyway...");
+
+ is_exclusive = false;
+ }
+
+ buffer.destroy ();
+}
+
+void CoreAudioPlugin::check_started ()
+{
+ if (! prebuffer_flag)
+ return;
+
+ AUDDBG ("Starting playback.\n");
+ prebuffer_flag = false;
+ block_delay = 0;
+}
+
+void CoreAudioPlugin::period_wait ()
+{
+ pthread_mutex_lock (& mutex);
+
+ while (! buffer.space ())
+ {
+ if (! paused_flag)
+ check_started ();
+
+ pthread_cond_wait (& cond, & mutex);
+ }
+
+ pthread_mutex_unlock (& mutex);
+}
+
+int CoreAudioPlugin::write_audio (const void * data, int len)
+{
+ pthread_mutex_lock (& mutex);
+
+ len = aud::min (len, buffer.space ());
+ buffer.copy_in ((const unsigned char *) data, len);
+
+ pthread_mutex_unlock (& mutex);
+ return len;
+}
+
+void CoreAudioPlugin::drain ()
+{
+ AUDDBG ("Draining.\n");
+ pthread_mutex_lock (& mutex);
+
+ check_started ();
+
+ while (buffer.len ())
+ pthread_cond_wait (& cond, & mutex);
+
+ pthread_mutex_unlock (& mutex);
+}
+
+int CoreAudioPlugin::get_delay ()
+{
+ auto timediff = [] (const timeval & a, const timeval & b) -> int64_t
+ { return 1000 * (int64_t) (b.tv_sec - a.tv_sec) + (b.tv_usec - a.tv_usec) / 1000; };
+
+ pthread_mutex_lock (& mutex);
+
+ int delay = aud::rescale (buffer.len (), buffer_bytes_per_channel * chan * rate, 1000);
+
+ /* Estimate the additional delay of the last block written. */
+ if (! prebuffer_flag && ! paused_flag && block_delay)
+ {
+ struct timeval cur;
+ gettimeofday (& cur, nullptr);
+
+ delay += aud::max (block_delay - timediff (block_time, cur), (int64_t) 0);
+ }
+
+ pthread_mutex_unlock (& mutex);
+ return delay;
+}
+
+void CoreAudioPlugin::pause (bool pause)
+{
+ AUDDBG ("%sause.\n", pause ? "P" : "Unp");
+ pthread_mutex_lock (& mutex);
+
+ paused_flag = pause;
+
+ if (pause)
+ AudioOutputUnitStop (output_instance);
+ else
+ {
+ if (AudioOutputUnitStart (output_instance))
+ {
+ error ("Unable to restart audio unit after pausing.\n");
+ close_audio ();
+ }
+ }
+
+ pthread_cond_broadcast (& cond); /* wake up period wait */
+ pthread_mutex_unlock (& mutex);
+}
+
+void CoreAudioPlugin::flush ()
+{
+ AUDDBG ("Seek requested; discarding buffer.\n");
+ pthread_mutex_lock (& mutex);
+
+ buffer.discard ();
+
+ prebuffer_flag = true;
+
+ pthread_cond_broadcast (& cond); /* wake up period wait */
+ pthread_mutex_unlock (& mutex);
+}
diff --git a/src/crossfade/Makefile b/src/crossfade/Makefile
index 6a7601269660..ab7243de0c2c 100644
--- a/src/crossfade/Makefile
+++ b/src/crossfade/Makefile
@@ -1,12 +1,12 @@
PLUGIN = crossfade${PLUGIN_SUFFIX}
-SRCS = crossfade.c
+SRCS = crossfade.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
diff --git a/src/crossfade/crossfade.c b/src/crossfade/crossfade.c
deleted file mode 100644
index 711451103524..000000000000
--- a/src/crossfade/crossfade.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Crossfade Plugin for Audacious
- * Copyright 2010-2012 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-enum
-{
- STATE_OFF,
- STATE_PREBUFFER,
- STATE_RUNNING,
- STATE_BETWEEN,
- STATE_STOPPING,
-};
-
-static const char * const crossfade_defaults[] = {
- "length", "3",
- NULL};
-
-static char state = STATE_OFF;
-static int current_channels = 0, current_rate = 0;
-static float * buffer = NULL;
-static int buffer_size = 0, buffer_filled = 0;
-static int prebuffer_filled = 0;
-static float * output = NULL;
-static int output_size = 0;
-
-static void reset (void)
-{
- state = STATE_OFF;
- current_channels = 0;
- current_rate = 0;
- g_free (buffer);
- buffer = NULL;
- buffer_size = 0;
- buffer_filled = 0;
- prebuffer_filled = 0;
- g_free (output);
- output = NULL;
- output_size = 0;
-}
-
-static bool_t crossfade_init (void)
-{
- aud_config_set_defaults ("crossfade", crossfade_defaults);
- return TRUE;
-}
-
-static void crossfade_cleanup (void)
-{
- reset ();
-}
-
-static void crossfade_start (int * channels, int * rate)
-{
- if (state != STATE_BETWEEN)
- reset ();
- else if (* channels != current_channels)
- {
- aud_interface_show_error (_("Crossfading failed because the songs had "
- "a different number of channels. You can use the Channel Mixer to "
- "convert the songs to the same number of channels."));
- reset ();
- }
- else if (* rate != current_rate)
- {
- aud_interface_show_error (_("Crossfading failed because the songs had "
- "different sample rates. You can use the Sample Rate Converter to "
- "convert the songs to the same sample rate."));
- reset ();
- }
-
- state = STATE_PREBUFFER;
- current_channels = * channels;
- current_rate = * rate;
- prebuffer_filled = 0;
-}
-
-static void do_ramp (float * data, int length, float a, float b)
-{
- int count;
-
- for (count = 0; count < length; count ++)
- {
- * data = (* data) * (a * (length - count) + b * count) / length;
- data ++;
- }
-}
-
-static void mix (float * data, float * new, int length)
-{
- while (length --)
- (* data ++) += (* new ++);
-}
-
-static void enlarge_buffer (int length)
-{
- if (length > buffer_size)
- {
- buffer = g_renew (float, buffer, length);
- buffer_size = length;
- }
-}
-
-static void add_data (float * data, int length)
-{
- if (state == STATE_PREBUFFER)
- {
- int full = current_channels * current_rate * aud_get_int ("crossfade", "length");
-
- if (prebuffer_filled < full)
- {
- int copy = MIN (length, full - prebuffer_filled);
- float a = (float) prebuffer_filled / full;
- float b = (float) (prebuffer_filled + copy) / full;
-
- if (prebuffer_filled + copy > buffer_filled)
- {
- enlarge_buffer (prebuffer_filled + copy);
- memset (buffer + buffer_filled, 0, sizeof (float) *
- (prebuffer_filled + copy - buffer_filled));
- buffer_filled = prebuffer_filled + copy;
- }
-
- do_ramp (data, copy, a, b);
- mix (buffer + prebuffer_filled, data, copy);
- prebuffer_filled += copy;
- data += copy;
- length -= copy;
- }
-
- if (prebuffer_filled < full)
- return;
-
- if (prebuffer_filled < buffer_filled)
- {
- int copy = MIN (length, buffer_filled - prebuffer_filled);
-
- mix (buffer + prebuffer_filled, data, copy);
- prebuffer_filled += copy;
- data += copy;
- length -= copy;
- }
-
- if (prebuffer_filled < buffer_filled)
- return;
-
- state = STATE_RUNNING;
- }
-
- if (state != STATE_RUNNING)
- return;
-
- enlarge_buffer (buffer_filled + length);
- memcpy (buffer + buffer_filled, data, sizeof (float) * length);
- buffer_filled += length;
-}
-
-static void enlarge_output (int length)
-{
- if (length > output_size)
- {
- output = g_renew (float, output, length);
- output_size = length;
- }
-}
-
-static void return_data (float * * data, int * length)
-{
- int full = current_channels * current_rate * aud_get_int ("crossfade", "length");
- int copy = buffer_filled - full;
-
- /* only return if we have at least 1/2 second -- this reduces memmove's */
- if (state != STATE_RUNNING || copy < current_channels * (current_rate / 2))
- {
- * data = NULL;
- * length = 0;
- return;
- }
-
- enlarge_output (copy);
- memcpy (output, buffer, sizeof (float) * copy);
- buffer_filled -= copy;
- memmove (buffer, buffer + copy, sizeof (float) * buffer_filled);
- * data = output;
- * length = copy;
-}
-
-static void crossfade_process (float * * data, int * samples)
-{
- add_data (* data, * samples);
- return_data (data, samples);
-}
-
-static void crossfade_flush (void)
-{
- if (state == STATE_PREBUFFER || state == STATE_RUNNING)
- {
- state = STATE_RUNNING;
- buffer_filled = 0;
- }
-}
-
-static void crossfade_finish (float * * data, int * samples)
-{
- if (state == STATE_BETWEEN) /* second call, end of last song */
- {
- enlarge_output (buffer_filled);
- memcpy (output, buffer, sizeof (float) * buffer_filled);
- * data = output;
- * samples = buffer_filled;
- buffer_filled = 0;
- state = STATE_OFF;
- return;
- }
-
- add_data (* data, * samples);
- return_data (data, samples);
-
- if (state == STATE_PREBUFFER || state == STATE_RUNNING)
- {
- do_ramp (buffer, buffer_filled, 1.0, 0.0);
- state = STATE_BETWEEN;
- }
-}
-
-static int crossfade_adjust_delay (int delay)
-{
- return delay + (int64_t) (buffer_filled / current_channels) * 1000 / current_rate;
-}
-
-static const char crossfade_about[] =
- N_("Crossfade Plugin for Audacious\n"
- "Copyright 2010-2012 John Lindgren");
-
-static const PreferencesWidget crossfade_widgets[] = {
- {WIDGET_LABEL, N_("<b>Crossfade</b>")},
- {WIDGET_SPIN_BTN, N_("Overlap:"),
- .cfg_type = VALUE_INT, .csect = "crossfade", .cname = "length",
- .data = {.spin_btn = {1, 10, 1, N_("seconds")}}}};
-
-static const PluginPreferences crossfade_prefs = {
- .widgets = crossfade_widgets,
- .n_widgets = ARRAY_LEN (crossfade_widgets)};
-
-AUD_EFFECT_PLUGIN
-(
- .name = N_("Crossfade"),
- .domain = PACKAGE,
- .about_text = crossfade_about,
- .prefs = & crossfade_prefs,
- .init = crossfade_init,
- .cleanup = crossfade_cleanup,
- .start = crossfade_start,
- .process = crossfade_process,
- .flush = crossfade_flush,
- .finish = crossfade_finish,
- .adjust_delay = crossfade_adjust_delay,
- .order = 5, /* must be after resample and mixer */
- .preserves_format = TRUE
-)
diff --git a/src/crossfade/crossfade.cc b/src/crossfade/crossfade.cc
new file mode 100644
index 000000000000..b7b15d7030eb
--- /dev/null
+++ b/src/crossfade/crossfade.cc
@@ -0,0 +1,308 @@
+/*
+ * Crossfade Plugin for Audacious
+ * Copyright 2010-2014 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/runtime.h>
+
+enum
+{
+ STATE_OFF,
+ STATE_FADEIN,
+ STATE_RUNNING,
+ STATE_FINISHED,
+ STATE_FLUSHED
+};
+
+static const char * const crossfade_defaults[] = {
+ "automatic", "TRUE",
+ "length", "5",
+ "manual", "TRUE",
+ "manual_length", "0.2",
+ nullptr
+};
+
+static const char crossfade_about[] =
+ N_("Crossfade Plugin for Audacious\n"
+ "Copyright 2010-2014 John Lindgren");
+
+static const PreferencesWidget crossfade_widgets[] = {
+ WidgetLabel (N_("<b>Crossfade</b>")),
+ WidgetCheck (N_("On automatic song change"),
+ WidgetBool ("crossfade", "automatic")),
+ WidgetSpin (N_("Overlap:"),
+ WidgetFloat ("crossfade", "length"),
+ {1, 15, 0.5, N_("seconds")},
+ WIDGET_CHILD),
+ WidgetCheck (N_("On seek or manual song change"),
+ WidgetBool ("crossfade", "manual")),
+ WidgetSpin (N_("Overlap:"),
+ WidgetFloat ("crossfade", "manual_length"),
+ {0.1, 3.0, 0.1, N_("seconds")},
+ WIDGET_CHILD),
+ WidgetLabel (N_("<b>Tip</b>")),
+ WidgetLabel (N_("For better crossfading, enable\n"
+ "the Silence Removal effect."))
+};
+
+static const PluginPreferences crossfade_prefs = {{crossfade_widgets}};
+
+class Crossfade : public EffectPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("Crossfade"),
+ PACKAGE,
+ crossfade_about,
+ & crossfade_prefs
+ };
+
+ /* order #5: must be after resample and mixer */
+ constexpr Crossfade () : EffectPlugin (info, 5, true) {}
+
+ bool init ();
+ void cleanup ();
+
+ void start (int & channels, int & rate);
+ Index<float> & process (Index<float> & data);
+ bool flush (bool force);
+ Index<float> & finish (Index<float> & data, bool end_of_playlist);
+ int adjust_delay (int delay);
+};
+
+EXPORT Crossfade aud_plugin_instance;
+
+static char state = STATE_OFF;
+static int current_channels = 0, current_rate = 0;
+static Index<float> buffer, output;
+static int fadein_point;
+
+static void reset ()
+{
+ state = STATE_OFF;
+ current_channels = 0;
+ current_rate = 0;
+ buffer.clear ();
+ output.clear ();
+}
+
+bool Crossfade::init ()
+{
+ aud_config_set_defaults ("crossfade", crossfade_defaults);
+ return true;
+}
+
+void Crossfade::cleanup ()
+{
+ reset ();
+}
+
+static void do_ramp (float * data, int length, float a, float b)
+{
+ for (int i = 0; i < length; i ++)
+ {
+ * data = (* data) * (a * (length - i) + b * i) / length;
+ data ++;
+ }
+}
+
+static void mix (float * data, float * add, int length)
+{
+ while (length --)
+ (* data ++) += (* add ++);
+}
+
+static int buffer_needed_for_state ()
+{
+ double overlap = 0;
+
+ if (state != STATE_FLUSHED && aud_get_bool ("crossfade", "automatic"))
+ overlap = aud_get_double ("crossfade", "length");
+
+ if (state != STATE_FINISHED && aud_get_bool ("crossfade", "manual"))
+ overlap = aud::max (overlap, aud_get_double ("crossfade", "manual_length"));
+
+ return current_channels * (int) (current_rate * overlap);
+}
+
+static void output_data_as_ready (int buffer_needed, bool exact)
+{
+ int copy = buffer.len () - buffer_needed;
+
+ /* if allowed, wait until we have at least 1/2 second ready to output */
+ if (exact ? (copy > 0) : (copy >= current_channels * (current_rate / 2)))
+ output.move_from (buffer, 0, -1, copy, true, true);
+}
+
+void Crossfade::start (int & channels, int & rate)
+{
+ if (state != STATE_OFF)
+ {
+ if (channels != current_channels)
+ {
+ aud_ui_show_error (_("Crossfading failed because the songs had "
+ "a different number of channels. You can use the Channel Mixer to "
+ "convert the songs to the same number of channels."));
+ state = STATE_OFF;
+ }
+ else if (rate != current_rate)
+ {
+ aud_ui_show_error (_("Crossfading failed because the songs had "
+ "different sample rates. You can use the Sample Rate Converter to "
+ "convert the songs to the same sample rate."));
+ state = STATE_OFF;
+ }
+ }
+
+ if (state == STATE_OFF)
+ {
+ reset ();
+
+ current_channels = channels;
+ current_rate = rate;
+
+ if (aud_get_bool ("crossfade", "manual"))
+ {
+ state = STATE_FLUSHED;
+ buffer.insert (0, buffer_needed_for_state ());
+ }
+ else
+ state = STATE_RUNNING;
+ }
+}
+
+static void run_fadeout ()
+{
+ do_ramp (buffer.begin (), buffer.len (), 1.0, 0.0);
+
+ state = STATE_FADEIN;
+ fadein_point = 0;
+}
+
+static void run_fadein (Index<float> & data)
+{
+ int length = buffer.len ();
+
+ if (fadein_point < length)
+ {
+ int copy = aud::min (data.len (), length - fadein_point);
+ float a = (float) fadein_point / length;
+ float b = (float) (fadein_point + copy) / length;
+
+ do_ramp (data.begin (), copy, a, b);
+ mix (& buffer[fadein_point], data.begin (), copy);
+ data.remove (0, copy);
+
+ fadein_point += copy;
+ }
+
+ if (fadein_point == length)
+ state = STATE_RUNNING;
+}
+
+Index<float> & Crossfade::process (Index<float> & data)
+{
+ if (state == STATE_OFF)
+ return data;
+
+ output.resize (0);
+
+ if (state == STATE_FINISHED || state == STATE_FLUSHED)
+ run_fadeout ();
+
+ if (state == STATE_FADEIN)
+ run_fadein (data);
+
+ if (state == STATE_RUNNING)
+ {
+ buffer.insert (data.begin (), -1, data.len ());
+ output_data_as_ready (buffer_needed_for_state (), false);
+ }
+
+ return output;
+}
+
+bool Crossfade::flush (bool force)
+{
+ if (state == STATE_OFF)
+ return true;
+
+ if (! force && aud_get_bool ("crossfade", "manual"))
+ {
+ state = STATE_FLUSHED;
+ int buffer_needed = buffer_needed_for_state ();
+ if (buffer.len () > buffer_needed)
+ buffer.remove (buffer_needed, -1);
+
+ return false;
+ }
+
+ state = STATE_RUNNING;
+ buffer.resize (0);
+
+ return true;
+}
+
+Index<float> & Crossfade::finish (Index<float> & data, bool end_of_playlist)
+{
+ if (state == STATE_OFF)
+ return data;
+
+ output.resize (0);
+
+ if (state == STATE_FADEIN)
+ run_fadein (data);
+
+ if (state == STATE_RUNNING || state == STATE_FINISHED || state == STATE_FLUSHED)
+ {
+ buffer.insert (data.begin (), -1, data.len ());
+ output_data_as_ready (buffer_needed_for_state (), state != STATE_RUNNING);
+ }
+
+ if (state == STATE_FADEIN || state == STATE_RUNNING)
+ {
+ if (aud_get_bool ("crossfade", "automatic"))
+ {
+ state = STATE_FINISHED;
+ output_data_as_ready (buffer_needed_for_state (), true);
+ }
+ else
+ {
+ state = STATE_OFF;
+ output_data_as_ready (0, true);
+ }
+ }
+
+ if (end_of_playlist && (state == STATE_FINISHED || state == STATE_FLUSHED))
+ {
+ do_ramp (buffer.begin (), buffer.len (), 1.0, 0.0);
+
+ state = STATE_OFF;
+ output_data_as_ready (0, true);
+ }
+
+ return output;
+}
+
+int Crossfade::adjust_delay (int delay)
+{
+ return delay + aud::rescale<int64_t> (buffer.len () / current_channels, current_rate, 1000);
+}
diff --git a/src/crystalizer/Makefile b/src/crystalizer/Makefile
index eea09a4b4a71..3eecf6ec405e 100644
--- a/src/crystalizer/Makefile
+++ b/src/crystalizer/Makefile
@@ -1,11 +1,12 @@
PLUGIN = crystalizer${PLUGIN_SUFFIX}
-SRCS = crystalizer.c
+SRCS = crystalizer.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
diff --git a/src/crystalizer/crystalizer.c b/src/crystalizer/crystalizer.c
deleted file mode 100644
index d30c28d0ef85..000000000000
--- a/src/crystalizer/crystalizer.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2008 William Pitcock <nenolod at nenolod.net>
- * Copyright (c) 2010-2012 John Lindgren <john.lindgren at tds.net>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice is present in all copies.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-static bool_t init (void);
-static void cryst_start (int * channels, int * rate);
-static void cryst_process (float * * data, int * samples);
-static void cryst_flush ();
-static void cryst_finish (float * * data, int * samples);
-
-static const char * const cryst_defaults[] = {
- "intensity", "1",
- NULL};
-
-static const PreferencesWidget cryst_widgets[] = {
- {WIDGET_LABEL, N_("<b>Crystalizer</b>")},
- {WIDGET_SPIN_BTN, N_("Intensity:"),
- .cfg_type = VALUE_FLOAT, .csect = "crystalizer", .cname = "intensity",
- .data = {.spin_btn = {0, 10, 0.1}}}};
-
-static const PluginPreferences cryst_prefs = {
- .widgets = cryst_widgets,
- .n_widgets = ARRAY_LEN (cryst_widgets)};
-
-AUD_EFFECT_PLUGIN
-(
- .name = N_("Crystalizer"),
- .domain = PACKAGE,
- .prefs = & cryst_prefs,
- .init = init,
- .start = cryst_start,
- .process = cryst_process,
- .flush = cryst_flush,
- .finish = cryst_finish,
- .preserves_format = TRUE
-)
-
-static int cryst_channels;
-static float * cryst_prev;
-
-static bool_t init (void)
-{
- aud_config_set_defaults ("crystalizer", cryst_defaults);
- return TRUE;
-}
-
-static void cryst_start (int * channels, int * rate)
-{
- cryst_channels = * channels;
- cryst_prev = realloc (cryst_prev, sizeof (float) * cryst_channels);
- memset (cryst_prev, 0, sizeof (float) * cryst_channels);
-}
-
-static void cryst_process (float * * data, int * samples)
-{
- float value = aud_get_double ("crystalizer", "intensity");
- float * f = * data;
- float * end = f + (* samples);
- int channel;
-
- while (f < end)
- {
- for (channel = 0; channel < cryst_channels; channel ++)
- {
- float current = * f;
-
- * f ++ = current + (current - cryst_prev[channel]) * value;
- cryst_prev[channel] = current;
- }
- }
-}
-
-static void cryst_flush ()
-{
- memset (cryst_prev, 0, sizeof (float) * cryst_channels);
-}
-
-static void cryst_finish (float * * data, int * samples)
-{
- cryst_process (data, samples);
-}
diff --git a/src/crystalizer/crystalizer.cc b/src/crystalizer/crystalizer.cc
new file mode 100644
index 000000000000..bec4d16034c5
--- /dev/null
+++ b/src/crystalizer/crystalizer.cc
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2008 William Pitcock <nenolod at nenolod.net>
+ * Copyright (c) 2010-2012 John Lindgren <john.lindgren at tds.net>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+
+static const char * const cryst_defaults[] = {
+ "intensity", "1",
+ nullptr};
+
+static const PreferencesWidget cryst_widgets[] = {
+ WidgetLabel (N_("<b>Crystalizer</b>")),
+ WidgetSpin (N_("Intensity:"),
+ WidgetFloat ("crystalizer", "intensity"),
+ {0, 10, 0.1})
+};
+
+static const PluginPreferences cryst_prefs = {{cryst_widgets}};
+
+class Crystalizer : public EffectPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("Crystalizer"),
+ PACKAGE,
+ nullptr,
+ & cryst_prefs
+ };
+
+ constexpr Crystalizer () : EffectPlugin (info, 0, true) {}
+
+ bool init ();
+ void cleanup ();
+
+ void start (int & channels, int & rate);
+ Index<float> & process (Index<float> & data);
+ bool flush (bool force);
+};
+
+EXPORT Crystalizer aud_plugin_instance;
+
+static int cryst_channels;
+static Index<float> cryst_prev;
+
+bool Crystalizer::init ()
+{
+ aud_config_set_defaults ("crystalizer", cryst_defaults);
+ return true;
+}
+
+void Crystalizer::cleanup ()
+{
+ cryst_prev.clear ();
+}
+
+void Crystalizer::start (int & channels, int & rate)
+{
+ cryst_channels = channels;
+ cryst_prev.resize (cryst_channels);
+ cryst_prev.erase (0, cryst_channels);
+}
+
+Index<float> & Crystalizer::process (Index<float> & data)
+{
+ float value = aud_get_double ("crystalizer", "intensity");
+ float * f = data.begin ();
+ float * end = data.end ();
+
+ while (f < end)
+ {
+ for (int channel = 0; channel < cryst_channels; channel ++)
+ {
+ float current = * f;
+ * f ++ = current + (current - cryst_prev[channel]) * value;
+ cryst_prev[channel] = current;
+ }
+ }
+
+ return data;
+}
+
+bool Crystalizer::flush (bool force)
+{
+ cryst_prev.erase (0, cryst_channels);
+ return true;
+}
diff --git a/src/cue/Makefile b/src/cue/Makefile
index 98ce920c694b..85592bf8b956 100644
--- a/src/cue/Makefile
+++ b/src/cue/Makefile
@@ -1,12 +1,14 @@
PLUGIN = cue${PLUGIN_SUFFIX}
-SRCS = cue.c
+SRCS = cue.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${CONTAINER_PLUGIN_DIR}
-CPPFLAGS += -I../.. ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${CUE_CFLAGS}
+LD = ${CXX}
+
+CPPFLAGS += -I../.. ${PLUGIN_CPPFLAGS} ${CUE_CFLAGS}
CFLAGS += ${PLUGIN_CFLAGS}
-LIBS += ${GLIB_LIBS} ${CUE_LIBS}
+LIBS += ${CUE_LIBS}
diff --git a/src/cue/cue.c b/src/cue/cue.c
deleted file mode 100644
index 04937aaa9155..000000000000
--- a/src/cue/cue.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Cue Sheet Plugin for Audacious
- * Copyright (c) 2009-2011 William Pitcock and John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <libcue/libcue.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-typedef struct {
- int tuple_type;
- int pti;
-} TuplePTIMap;
-
-TuplePTIMap pti_map[] = {
- { FIELD_ARTIST, PTI_PERFORMER },
- { FIELD_TITLE, PTI_TITLE },
-};
-
-static void
-tuple_attach_cdtext(Tuple *tuple, Track *track, int tuple_type, int pti)
-{
- Cdtext *cdtext;
- const char *text;
-
- cdtext = track_get_cdtext(track);
- if (cdtext == NULL)
- return;
-
- text = cdtext_get(pti, cdtext);
- if (text == NULL)
- return;
-
- tuple_set_str (tuple, tuple_type, text);
-}
-
-static bool_t playlist_load_cue (const char * cue_filename, VFSFile * file,
- char * * title, Index * filenames, Index * tuples)
-{
- void * buffer = NULL;
- vfs_file_read_all (file, & buffer, NULL);
- if (! buffer)
- return FALSE;
-
- * title = NULL;
-
- Cd * cd = cue_parse_string (buffer);
- g_free (buffer);
- if (cd == NULL)
- return FALSE;
-
- int tracks = cd_get_ntrack (cd);
- if (tracks == 0)
- return FALSE;
-
- Track * current = cd_get_track (cd, 1);
- if (current == NULL)
- return FALSE;
-
- char * track_filename = track_get_filename (current);
- if (track_filename == NULL)
- return FALSE;
-
- char * filename = aud_construct_uri (track_filename, cue_filename);
-
- Tuple * base_tuple = NULL;
- bool_t base_tuple_scanned = FALSE;
-
- for (int track = 1; track <= tracks; track ++)
- {
- if (current == NULL || filename == NULL)
- return FALSE;
-
- if (base_tuple == NULL && ! base_tuple_scanned)
- {
- base_tuple_scanned = TRUE;
- PluginHandle * decoder = aud_file_find_decoder (filename, FALSE);
- if (decoder != NULL)
- base_tuple = aud_file_read_tuple (filename, decoder);
- }
-
- Track * next = (track + 1 <= tracks) ? cd_get_track (cd, track + 1) : NULL;
- char * next_filename = (next != NULL) ? aud_construct_uri
- (track_get_filename (next), cue_filename) : NULL;
- bool_t last_track = (next_filename == NULL || strcmp (next_filename, filename));
-
- Tuple * tuple = (base_tuple != NULL) ? tuple_copy (base_tuple) :
- tuple_new_from_filename (filename);
- tuple_set_int (tuple, FIELD_TRACK_NUMBER, track);
-
- int begin = (int64_t) track_get_start (current) * 1000 / 75;
- tuple_set_int (tuple, FIELD_SEGMENT_START, begin);
-
- if (last_track)
- {
- if (base_tuple != NULL && tuple_get_value_type (base_tuple,
- FIELD_LENGTH) == TUPLE_INT)
- tuple_set_int (tuple, FIELD_LENGTH, tuple_get_int
- (base_tuple, FIELD_LENGTH) - begin);
- }
- else
- {
- int length = (int64_t) track_get_length (current) * 1000 / 75;
- tuple_set_int (tuple, FIELD_LENGTH, length);
- tuple_set_int (tuple, FIELD_SEGMENT_END, begin + length);
- }
-
- for (int i = 0; i < ARRAY_LEN (pti_map); i ++)
- tuple_attach_cdtext (tuple, current, pti_map[i].tuple_type, pti_map[i].pti);
-
- index_insert (filenames, -1, str_get (filename));
- index_insert (tuples, -1, tuple);
-
- current = next;
- str_unref (filename);
- filename = next_filename;
-
- if (last_track && base_tuple != NULL)
- {
- tuple_unref (base_tuple);
- base_tuple = NULL;
- base_tuple_scanned = FALSE;
- }
- }
-
- return TRUE;
-}
-
-static const char * const cue_exts[] = {"cue", NULL};
-
-AUD_PLAYLIST_PLUGIN
-(
- .name = N_("Cue Sheet Plugin"),
- .domain = PACKAGE,
- .extensions = cue_exts,
- .load = playlist_load_cue
-)
diff --git a/src/cue/cue.cc b/src/cue/cue.cc
new file mode 100644
index 000000000000..79de658c53f5
--- /dev/null
+++ b/src/cue/cue.cc
@@ -0,0 +1,155 @@
+/*
+ * Cue Sheet Plugin for Audacious
+ * Copyright (c) 2009-2011 William Pitcock and John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+extern "C" {
+#include <libcue/libcue.h>
+}
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/probe.h>
+
+static const char * const cue_exts[] = {"cue"};
+
+class CueLoader : public PlaylistPlugin
+{
+public:
+ static constexpr PluginInfo info = {N_("Cue Sheet Plugin"), PACKAGE};
+
+ constexpr CueLoader () : PlaylistPlugin (info, cue_exts, false) {}
+
+ bool load (const char * filename, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items);
+};
+
+EXPORT CueLoader aud_plugin_instance;
+
+static const struct {
+ Tuple::Field field;
+ int pti;
+} pti_map[] = {
+ { Tuple::Artist, PTI_PERFORMER },
+ { Tuple::Title, PTI_TITLE },
+};
+
+static void
+tuple_attach_cdtext(Tuple &tuple, Track *track, Tuple::Field field, int pti)
+{
+ Cdtext *cdtext;
+ const char *text;
+
+ cdtext = track_get_cdtext(track);
+ if (cdtext == nullptr)
+ return;
+
+ text = cdtext_get(pti, cdtext);
+ if (text == nullptr)
+ return;
+
+ tuple.set_str (field, text);
+}
+
+bool CueLoader::load (const char * cue_filename, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items)
+{
+ Index<char> buffer = file.read_all ();
+ if (! buffer.len ())
+ return false;
+
+ buffer.append (0); /* null-terminated */
+
+ Cd * cd = cue_parse_string (buffer.begin ());
+ if (cd == nullptr)
+ return false;
+
+ int tracks = cd_get_ntrack (cd);
+ if (tracks == 0)
+ return false;
+
+ Track * current = cd_get_track (cd, 1);
+ if (current == nullptr)
+ return false;
+
+ char * track_filename = track_get_filename (current);
+ if (track_filename == nullptr)
+ return false;
+
+ String filename = String (uri_construct (track_filename, cue_filename));
+
+ Tuple base_tuple;
+ bool base_tuple_scanned = false;
+
+ for (int track = 1; track <= tracks; track ++)
+ {
+ if (current == nullptr || ! filename)
+ return false;
+
+ if (! base_tuple_scanned)
+ {
+ base_tuple_scanned = true;
+ PluginHandle * decoder = aud_file_find_decoder (filename, false);
+ if (decoder != nullptr)
+ base_tuple = aud_file_read_tuple (filename, decoder);
+ }
+
+ Track * next = (track + 1 <= tracks) ? cd_get_track (cd, track + 1) : nullptr;
+ String next_filename = (next != nullptr) ? String (uri_construct
+ (track_get_filename (next), cue_filename)) : String ();
+ bool last_track = (! next_filename || strcmp (next_filename, filename));
+
+ Tuple tuple = base_tuple.ref ();
+ tuple.set_filename (filename);
+ tuple.set_int (Tuple::Track, track);
+
+ int begin = (int64_t) track_get_start (current) * 1000 / 75;
+ tuple.set_int (Tuple::StartTime, begin);
+
+ if (last_track)
+ {
+ if (base_tuple.get_value_type (Tuple::Length) == Tuple::Int)
+ tuple.set_int (Tuple::Length, base_tuple.get_int (Tuple::Length) - begin);
+ }
+ else
+ {
+ int length = (int64_t) track_get_length (current) * 1000 / 75;
+ tuple.set_int (Tuple::Length, length);
+ tuple.set_int (Tuple::EndTime, begin + length);
+ }
+
+ for (auto & pti : pti_map)
+ tuple_attach_cdtext (tuple, current, pti.field, pti.pti);
+
+ items.append (filename, std::move (tuple));
+
+ current = next;
+ filename = next_filename;
+
+ if (last_track)
+ {
+ base_tuple = Tuple ();
+ base_tuple_scanned = false;
+ }
+ }
+
+ return true;
+}
diff --git a/src/delete-files/Makefile b/src/delete-files/Makefile
index 4002a85263d4..416a7ae9f3f2 100644
--- a/src/delete-files/Makefile
+++ b/src/delete-files/Makefile
@@ -1,12 +1,14 @@
PLUGIN = delete-files${PLUGIN_SUFFIX}
-SRCS = delete-files.c
+SRCS = delete-files.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
+
CPPFLAGS += -I../.. ${GIO_CFLAGS} ${GTK_CFLAGS}
CFLAGS += ${PLUGIN_CFLAGS}
-LIBS += ${GIO_LIBS} ${GTK_LIBS}
+LIBS += ${GIO_LIBS} ${GTK_LIBS} -laudgui
diff --git a/src/delete-files/delete-files.c b/src/delete-files/delete-files.c
deleted file mode 100644
index 56b0883b90d7..000000000000
--- a/src/delete-files/delete-files.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * delete-files.c
- * Copyright 2013 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <gio/gio.h>
-#include <glib/gstdio.h>
-#include <gtk/gtk.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-#include <libaudcore/audstrings.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-static const int menus[] = {AUD_MENU_MAIN, AUD_MENU_PLAYLIST, AUD_MENU_PLAYLIST_REMOVE};
-
-static GtkWidget * dialog = NULL;
-
-static void move_to_trash (const char * filename)
-{
- GFile * gfile = g_file_new_for_path (filename);
- GError * gerror = NULL;
-
- if (! g_file_trash (gfile, NULL, & gerror))
- {
- SPRINTF (error, _("Error moving %s to trash: %s."), filename, gerror->message);
- aud_interface_show_error (error);
- g_error_free (gerror);
- }
-
- g_object_unref ((GObject *) gfile);
-}
-
-static void really_delete (const char * filename)
-{
- if (g_unlink (filename) < 0)
- {
- SPRINTF (error, _("Error deleting %s: %s."), filename, strerror (errno));
- aud_interface_show_error (error);
- }
-}
-
-static void confirm_delete (void)
-{
- Index * files = index_new ();
-
- int playlist = aud_playlist_get_active ();
- int entry_count = aud_playlist_entry_count (playlist);
-
- for (int i = 0; i < entry_count; i ++)
- {
- if (aud_playlist_entry_get_selected (playlist, i))
- index_insert (files, -1, aud_playlist_entry_get_filename (playlist, i));
- }
-
- aud_playlist_delete_selected (playlist);
-
- int file_count = index_count (files);
-
- for (int i = 0; i < file_count; i ++)
- {
- char * uri = index_get (files, i);
- char * filename = uri_to_filename (uri);
-
- if (filename)
- {
- if (aud_get_bool ("delete_files", "use_trash"))
- move_to_trash (filename);
- else
- really_delete (filename);
-
- str_unref (filename);
- }
- else
- {
- SPRINTF (error, _("Error deleting %s: not a local file."), uri);
- aud_interface_show_error (error);
- }
- }
-
- index_free_full (files, (IndexFreeFunc) str_unref);
-}
-
-static void start_delete (void)
-{
- if (dialog)
- {
- gtk_window_present ((GtkWindow *) dialog);
- return;
- }
-
- const char * message;
- GtkWidget * button1, * button2;
-
- if (aud_get_bool ("delete_files", "use_trash"))
- {
- message = _("Do you want to move the selected files to the trash?");
- button1 = audgui_button_new (_("Move to Trash"), "user-trash",
- (AudguiCallback) confirm_delete, NULL);
- }
- else
- {
- message = _("Do you want to permanently delete the selected files?");
- button1 = audgui_button_new (_("Delete"), "edit-delete",
- (AudguiCallback) confirm_delete, NULL);
- }
-
- button2 = audgui_button_new (_("Cancel"), "process-stop", NULL, NULL);
- dialog = audgui_dialog_new (GTK_MESSAGE_QUESTION, _("Delete Files"),
- message, button1, button2);
-
- g_signal_connect (dialog, "destroy", (GCallback) gtk_widget_destroyed, & dialog);
- gtk_widget_show_all (dialog);
-}
-
-static const char * const delete_files_defaults[] = {
- "use_trash", "TRUE",
- NULL};
-
-static bool_t delete_files_init (void)
-{
- aud_config_set_defaults ("delete_files", delete_files_defaults);
-
- for (int i = 0; i < ARRAY_LEN (menus); i ++)
- aud_plugin_menu_add (menus[i], start_delete, _("Delete Selected Files"), "edit-delete");
-
- return TRUE;
-}
-
-static void delete_files_cleanup (void)
-{
- if (dialog)
- gtk_widget_destroy (dialog);
-
- for (int i = 0; i < ARRAY_LEN (menus); i ++)
- aud_plugin_menu_remove (menus[i], start_delete);
-}
-
-static const PreferencesWidget delete_files_widgets[] = {
- {WIDGET_LABEL, N_("<b>Delete Method</b>")},
- {WIDGET_CHK_BTN, N_("Move to trash instead of deleting immediately"),
- .cfg_type = VALUE_BOOLEAN, .csect = "delete_files", .cname = "use_trash"}};
-
-static const PluginPreferences delete_files_prefs = {
- .widgets = delete_files_widgets,
- .n_widgets = ARRAY_LEN (delete_files_widgets)};
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("Delete Files"),
- .domain = PACKAGE,
- .init = delete_files_init,
- .cleanup = delete_files_cleanup,
- .prefs = & delete_files_prefs,
-)
diff --git a/src/delete-files/delete-files.cc b/src/delete-files/delete-files.cc
new file mode 100644
index 000000000000..92fe939232bd
--- /dev/null
+++ b/src/delete-files/delete-files.cc
@@ -0,0 +1,186 @@
+/*
+ * delete-files.c
+ * Copyright 2013 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gio/gio.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/runtime.h>
+#include <libaudgui/libaudgui-gtk.h>
+
+class DeleteFiles : public GeneralPlugin
+{
+public:
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Delete Files"),
+ PACKAGE,
+ nullptr,
+ & prefs
+ };
+
+ constexpr DeleteFiles () : GeneralPlugin (info, false) {}
+
+ bool init ();
+ void cleanup ();
+};
+
+EXPORT DeleteFiles aud_plugin_instance;
+
+static constexpr AudMenuID menus[] = {
+ AudMenuID::Main,
+ AudMenuID::Playlist,
+ AudMenuID::PlaylistRemove
+};
+
+static GtkWidget * dialog = nullptr;
+
+static void move_to_trash (const char * filename)
+{
+ GFile * gfile = g_file_new_for_path (filename);
+ GError * gerror = nullptr;
+
+ if (! g_file_trash (gfile, nullptr, & gerror))
+ {
+ aud_ui_show_error (str_printf (_("Error moving %s to trash: %s."),
+ filename, gerror->message));
+ g_error_free (gerror);
+ }
+
+ g_object_unref ((GObject *) gfile);
+}
+
+static void really_delete (const char * filename)
+{
+ if (g_unlink (filename) < 0)
+ aud_ui_show_error (str_printf (_("Error deleting %s: %s."), filename, strerror (errno)));
+}
+
+static void confirm_delete (void)
+{
+ Index<String> files;
+
+ int playlist = aud_playlist_get_active ();
+ int entry_count = aud_playlist_entry_count (playlist);
+
+ for (int i = 0; i < entry_count; i ++)
+ {
+ if (aud_playlist_entry_get_selected (playlist, i))
+ files.append (aud_playlist_entry_get_filename (playlist, i));
+ }
+
+ aud_playlist_delete_selected (playlist);
+
+ for (const String & uri : files)
+ {
+ StringBuf filename = uri_to_filename (uri);
+
+ if (filename)
+ {
+ if (aud_get_bool ("delete_files", "use_trash"))
+ move_to_trash (filename);
+ else
+ really_delete (filename);
+ }
+ else
+ aud_ui_show_error (str_printf
+ (_("Error deleting %s: not a local file."), (const char *) uri));
+ }
+}
+
+static void start_delete (void)
+{
+ if (dialog)
+ {
+ gtk_window_present ((GtkWindow *) dialog);
+ return;
+ }
+
+ const char * message;
+ GtkWidget * button1, * button2;
+
+ if (aud_get_bool ("delete_files", "use_trash"))
+ {
+ message = _("Do you want to move the selected files to the trash?");
+ button1 = audgui_button_new (_("Move to Trash"), "user-trash",
+ (AudguiCallback) confirm_delete, nullptr);
+ }
+ else
+ {
+ message = _("Do you want to permanently delete the selected files?");
+ button1 = audgui_button_new (_("Delete"), "edit-delete",
+ (AudguiCallback) confirm_delete, nullptr);
+ }
+
+ button2 = audgui_button_new (_("Cancel"), "process-stop", nullptr, nullptr);
+ dialog = audgui_dialog_new (GTK_MESSAGE_QUESTION, _("Delete Files"),
+ message, button1, button2);
+
+ g_signal_connect (dialog, "destroy", (GCallback) gtk_widget_destroyed, & dialog);
+ gtk_widget_show_all (dialog);
+}
+
+const char * const DeleteFiles::defaults[] = {
+ "use_trash", "TRUE",
+ nullptr};
+
+bool DeleteFiles::init (void)
+{
+#if ! GLIB_CHECK_VERSION (2, 36, 0)
+ g_type_init ();
+#endif
+
+ aud_config_set_defaults ("delete_files", defaults);
+
+ for (AudMenuID menu : menus)
+ aud_plugin_menu_add (menu, start_delete, _("Delete Selected Files"), "edit-delete");
+
+ return TRUE;
+}
+
+void DeleteFiles::cleanup (void)
+{
+ if (dialog)
+ gtk_widget_destroy (dialog);
+
+ for (AudMenuID menu : menus)
+ aud_plugin_menu_remove (menu, start_delete);
+}
+
+const PreferencesWidget DeleteFiles::widgets[] = {
+ WidgetLabel (N_("<b>Delete Method</b>")),
+ WidgetCheck (N_("Move to trash instead of deleting immediately"),
+ WidgetBool ("delete_files", "use_trash"))
+};
+
+const PluginPreferences DeleteFiles::prefs = {{widgets}};
diff --git a/src/echo_plugin/Makefile b/src/echo_plugin/Makefile
index 308de83d3c72..ca1b950c8079 100644
--- a/src/echo_plugin/Makefile
+++ b/src/echo_plugin/Makefile
@@ -1,12 +1,12 @@
PLUGIN = echo${PLUGIN_SUFFIX}
-SRCS = echo.c
+SRCS = echo.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
diff --git a/src/echo_plugin/echo.c b/src/echo_plugin/echo.c
deleted file mode 100644
index 35e3ef552e79..000000000000
--- a/src/echo_plugin/echo.c
+++ /dev/null
@@ -1,132 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-#define MAX_DELAY 1000
-#define MAX_SRATE 50000
-#define MAX_CHANNELS 2
-#define BYTES_PS sizeof(float)
-#define BUFFER_SAMPLES (MAX_SRATE * MAX_DELAY / 1000)
-#define BUFFER_SHORTS (BUFFER_SAMPLES * MAX_CHANNELS)
-#define BUFFER_BYTES (BUFFER_SHORTS * BYTES_PS)
-
-static const char * const echo_defaults[] = {
- "delay", "500",
- "feedback", "50",
- "volume", "50",
- NULL};
-
-static const PreferencesWidget echo_widgets[] = {
- {WIDGET_LABEL, N_("<b>Echo</b>")},
- {WIDGET_SPIN_BTN, N_("Delay:"),
- .cfg_type = VALUE_INT, .csect = "echo_plugin", .cname = "delay",
- .data = {.spin_btn = {0, MAX_DELAY, 10, N_("ms")}}},
- {WIDGET_SPIN_BTN, N_("Feedback:"),
- .cfg_type = VALUE_INT, .csect = "echo_plugin", .cname = "feedback",
- .data = {.spin_btn = {0, 100, 1, "%"}}},
- {WIDGET_SPIN_BTN, N_("Volume:"),
- .cfg_type = VALUE_INT, .csect = "echo_plugin", .cname = "volume",
- .data = {.spin_btn = {0, 100, 1, "%"}}}};
-
-static const PluginPreferences echo_prefs = {
- .widgets = echo_widgets,
- .n_widgets = ARRAY_LEN (echo_widgets)};
-
-static float *buffer = NULL;
-static int w_ofs;
-
-static bool_t init (void)
-{
- aud_config_set_defaults ("echo_plugin", echo_defaults);
- return TRUE;
-}
-
-static void cleanup(void)
-{
- g_free(buffer);
- buffer = NULL;
-}
-
-static int echo_channels = 0;
-static int echo_rate = 0;
-
-static void echo_start(int *channels, int *rate)
-{
- static int old_srate, old_nch;
-
- if (buffer == NULL)
- buffer = g_malloc (BUFFER_BYTES);
-
- echo_channels = *channels;
- echo_rate = *rate;
-
- if (echo_channels != old_nch || echo_rate != old_srate)
- {
- memset(buffer, 0, BUFFER_BYTES);
- w_ofs = 0;
- old_nch = echo_channels;
- old_srate = echo_rate;
- }
-}
-
-static void echo_process(float **d, int *samples)
-{
- int delay = aud_get_int ("echo_plugin", "delay");
- int feedback = aud_get_int ("echo_plugin", "feedback");
- int volume = aud_get_int ("echo_plugin", "volume");
-
- float in, out, buf;
- int r_ofs;
- float *data = *d;
- float *end = *d + *samples;
-
- r_ofs = w_ofs - (echo_rate * delay / 1000) * echo_channels;
- if (r_ofs < 0)
- r_ofs += BUFFER_SHORTS;
-
- for (; data < end; data++)
- {
- in = *data;
-
- buf = buffer[r_ofs];
- out = in + buf * volume / 100;
- buf = in + buf * feedback / 100;
- buffer[w_ofs] = buf;
- *data = out;
-
- if (++r_ofs >= BUFFER_SHORTS)
- r_ofs -= BUFFER_SHORTS;
- if (++w_ofs >= BUFFER_SHORTS)
- w_ofs -= BUFFER_SHORTS;
- }
-}
-
-static void echo_finish(float **d, int *samples)
-{
- echo_process(d, samples);
-}
-
-static const char echo_about[] =
- N_("Echo Plugin\n"
- "By Johan Levin, 1999\n\n"
- "Surround echo by Carl van Schaik, 1999");
-
-AUD_EFFECT_PLUGIN
-(
- .name = N_("Echo"),
- .domain = PACKAGE,
- .about_text = echo_about,
- .prefs = & echo_prefs,
- .init = init,
- .cleanup = cleanup,
- .start = echo_start,
- .process = echo_process,
- .finish = echo_finish,
- .preserves_format = TRUE
-)
diff --git a/src/echo_plugin/echo.cc b/src/echo_plugin/echo.cc
new file mode 100644
index 000000000000..967361c790c1
--- /dev/null
+++ b/src/echo_plugin/echo.cc
@@ -0,0 +1,115 @@
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+
+#define MAX_DELAY 1000
+
+static const char echo_about[] =
+ N_("Echo Plugin\n"
+ "By Johan Levin, 1999\n"
+ "Surround echo by Carl van Schaik, 1999\n"
+ "Updated for Audacious by William Pitcock and John Lindgren, 2010-2014");
+
+static const char * const echo_defaults[] = {
+ "delay", "500",
+ "feedback", "50",
+ "volume", "50",
+ nullptr};
+
+static const PreferencesWidget echo_widgets[] = {
+ WidgetLabel (N_("<b>Echo</b>")),
+ WidgetSpin (N_("Delay:"),
+ WidgetInt ("echo_plugin", "delay"),
+ {0, MAX_DELAY, 10, N_("ms")}),
+ WidgetSpin (N_("Feedback:"),
+ WidgetInt ("echo_plugin", "feedback"),
+ {0, 100, 1, "%"}),
+ WidgetSpin (N_("Volume:"),
+ WidgetInt ("echo_plugin", "volume"),
+ {0, 100, 1, "%"})
+};
+
+static const PluginPreferences echo_prefs = {{echo_widgets}};
+
+class EchoPlugin : public EffectPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("Echo"),
+ PACKAGE,
+ echo_about,
+ & echo_prefs
+ };
+
+ constexpr EchoPlugin () : EffectPlugin (info, 0, true) {}
+
+ bool init ();
+ void cleanup ();
+
+ void start (int & channels, int & rate);
+ Index<float> & process (Index<float> & data);
+};
+
+EXPORT EchoPlugin aud_plugin_instance;
+
+static Index<float> buffer;
+static int w_ofs;
+
+bool EchoPlugin::init ()
+{
+ aud_config_set_defaults ("echo_plugin", echo_defaults);
+ return true;
+}
+
+void EchoPlugin::cleanup ()
+{
+ buffer.clear ();
+}
+
+static int echo_channels = 0;
+static int echo_rate = 0;
+
+void EchoPlugin::start (int & channels, int & rate)
+{
+ if (channels != echo_channels || rate != echo_rate)
+ {
+ echo_channels = channels;
+ echo_rate = rate;
+
+ buffer.resize (aud::rescale (MAX_DELAY, 1000, rate) * channels);
+ buffer.erase (0, -1);
+
+ w_ofs = 0;
+ }
+}
+
+Index<float> & EchoPlugin::process (Index<float> & data)
+{
+ int delay = aud_get_int ("echo_plugin", "delay");
+ float feedback = aud_get_int ("echo_plugin", "feedback") / 100.0f;
+ float volume = aud_get_int ("echo_plugin", "volume") / 100.0f;
+
+ int interval = aud::rescale (delay, 1000, echo_rate) * echo_channels;
+ interval = aud::clamp (interval, 0, buffer.len ()); // sanity check
+
+ int r_ofs = w_ofs - interval;
+ if (r_ofs < 0)
+ r_ofs += buffer.len ();
+
+ float * end = data.end ();
+
+ for (float * f = data.begin (); f < end; f++)
+ {
+ float in = * f;
+ float buf = buffer[r_ofs];
+
+ * f = in + buf * volume;
+ buffer[w_ofs] = in + buf * feedback;
+
+ r_ofs = (r_ofs + 1) % buffer.len ();
+ w_ofs = (w_ofs + 1) % buffer.len ();
+ }
+
+ return data;
+}
diff --git a/src/ffaudio/Makefile b/src/ffaudio/Makefile
index 20433de831e3..c127287561d3 100644
--- a/src/ffaudio/Makefile
+++ b/src/ffaudio/Makefile
@@ -1,12 +1,14 @@
PLUGIN = ffaudio${PLUGIN_SUFFIX}
-SRCS = ffaudio-core.c ffaudio-io.c
+SRCS = ffaudio-core.cc ffaudio-io.cc itunes-cover.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} ${FFMPEG_CFLAGS} -I../.. -std=c99 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE
-LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${FFMPEG_LIBS} -laudtag
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${FFMPEG_CFLAGS} -I../..
+LIBS += ${FFMPEG_LIBS} -laudtag
diff --git a/src/ffaudio/ffaudio-core.c b/src/ffaudio/ffaudio-core.c
deleted file mode 100644
index b3a81abb6458..000000000000
--- a/src/ffaudio/ffaudio-core.c
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * Audacious FFaudio Plugin
- * Copyright © 2009 William Pitcock <nenolod at dereferenced.org>
- * Matti Hämäläinen <ccr at tnsp.org>
- * Copyright © 2011 John Lindgren <john.lindgren at tds.net>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- */
-
-/*
- * NOTE: Using libav with this code is entirely unsupported. Do so at your own
- * risk. Any bugs filed against this plugin on systems using libav will be rejected
- * by us.
- */
-
-#include <glib.h>
-#include <pthread.h>
-
-#undef FFAUDIO_DOUBLECHECK /* Doublecheck probing result for debugging purposes */
-#undef FFAUDIO_NO_BLACKLIST /* Don't blacklist any recognized codecs/formats */
-
-#include "ffaudio-stdinc.h"
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-#include <audacious/debug.h>
-#include <audacious/audtag.h>
-#include <libaudcore/audstrings.h>
-
-static pthread_mutex_t data_mutex = PTHREAD_MUTEX_INITIALIZER;
-static GHashTable * extension_dict = NULL;
-
-typedef struct
-{
- int stream_idx;
- AVStream * stream;
- AVCodecContext * context;
- AVCodec * codec;
-}
-CodecInfo;
-
-static gint lockmgr (void * * mutexp, enum AVLockOp op)
-{
- switch (op)
- {
- case AV_LOCK_CREATE:
- * mutexp = g_slice_new (pthread_mutex_t);
- pthread_mutex_init (* mutexp, NULL);
- break;
- case AV_LOCK_OBTAIN:
- pthread_mutex_lock (* mutexp);
- break;
- case AV_LOCK_RELEASE:
- pthread_mutex_unlock (* mutexp);
- break;
- case AV_LOCK_DESTROY:
- pthread_mutex_destroy (* mutexp);
- g_slice_free (pthread_mutex_t, * mutexp);
- break;
- }
-
- return 0;
-}
-
-static gboolean ffaudio_init (void)
-{
- av_register_all();
- av_lockmgr_register (lockmgr);
-
- return TRUE;
-}
-
-static void
-ffaudio_cleanup(void)
-{
- if (extension_dict)
- g_hash_table_destroy (extension_dict);
-
- av_lockmgr_register (NULL);
-}
-
-static const gchar * ffaudio_strerror (gint error)
-{
- static gchar buf[256];
- return (! av_strerror (error, buf, sizeof buf)) ? buf : "unknown error";
-}
-
-static GHashTable * create_extension_dict (void)
-{
- GHashTable * dict = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) str_unref, NULL);
-
- AVInputFormat * f;
- for (f = av_iformat_next (NULL); f; f = av_iformat_next (f))
- {
- if (! f->extensions)
- continue;
-
- gchar * exts = g_ascii_strdown (f->extensions, -1);
-
- gchar * parse, * next;
- for (parse = exts; parse; parse = next)
- {
- next = strchr (parse, ',');
- if (next)
- {
- * next = 0;
- next ++;
- }
-
- g_hash_table_insert (dict, str_get(parse), f);
- }
-
- g_free (exts);
- }
-
- return dict;
-}
-
-static AVInputFormat * get_format_by_extension (const gchar * name)
-{
- const gchar * ext0, * sub;
- uri_parse (name, NULL, & ext0, & sub, NULL);
-
- if (ext0 == sub)
- return NULL;
-
- gchar * ext = g_ascii_strdown (ext0 + 1, sub - ext0 - 1);
-
- AUDDBG ("Get format by extension: %s\n", name);
- pthread_mutex_lock (& data_mutex);
-
- if (! extension_dict)
- extension_dict = create_extension_dict ();
-
- AVInputFormat * f = g_hash_table_lookup (extension_dict, ext);
- pthread_mutex_unlock (& data_mutex);
-
- if (f)
- AUDDBG ("Format %s.\n", f->name);
- else
- AUDDBG ("Format unknown.\n");
-
- g_free (ext);
- return f;
-}
-
-static AVInputFormat * get_format_by_content (const gchar * name, VFSFile * file)
-{
- AUDDBG ("Get format by content: %s\n", name);
-
- AVInputFormat * f = NULL;
-
- guchar buf[16384 + AVPROBE_PADDING_SIZE];
- gint size = 16;
- gint filled = 0;
- gint target = 100;
- gint score = 0;
-
- while (1)
- {
- if (filled < size)
- filled += vfs_fread (buf + filled, 1, size - filled, file);
-
- memset (buf + filled, 0, AVPROBE_PADDING_SIZE);
- AVProbeData d = {name, buf, filled};
- score = target;
-
- f = av_probe_input_format2 (& d, TRUE, & score);
- if (f)
- break;
-
- if (size < 16384 && filled == size)
- size *= 4;
- else if (target > 10)
- target = 10;
- else
- break;
- }
-
- if (f)
- AUDDBG ("Format %s, buffer size %d, score %d.\n", f->name, filled, score);
- else
- AUDDBG ("Format unknown.\n");
-
- if (vfs_fseek (file, 0, SEEK_SET) < 0)
- ; /* ignore errors here */
-
- return f;
-}
-
-static AVInputFormat * get_format (const gchar * name, VFSFile * file)
-{
- AVInputFormat * f = get_format_by_extension (name);
- return f ? f : get_format_by_content (name, file);
-}
-
-static AVFormatContext * open_input_file (const gchar * name, VFSFile * file)
-{
- AVInputFormat * f = get_format (name, file);
-
- if (! f)
- {
- fprintf (stderr, "ffaudio: Unknown format for %s.\n", name);
- return NULL;
- }
-
- AVFormatContext * c = avformat_alloc_context ();
- AVIOContext * io = io_context_new (file);
- c->pb = io;
-
- gint ret = avformat_open_input (& c, name, f, NULL);
-
- if (ret < 0)
- {
- fprintf (stderr, "ffaudio: avformat_open_input failed for %s: %s.\n", name, ffaudio_strerror (ret));
- io_context_free (io);
- return NULL;
- }
-
- return c;
-}
-
-static void close_input_file (AVFormatContext * c)
-{
- AVIOContext * io = c->pb;
-
-#if CHECK_LIBAVFORMAT_VERSION (53, 24, 1)
- avformat_close_input (&c);
-#else
- av_close_input_file (c);
-#endif
-
- io_context_free (io);
-}
-
-static bool_t find_codec (AVFormatContext * c, CodecInfo * cinfo)
-{
- avformat_find_stream_info (c, NULL);
-
- for (int i = 0; i < c->nb_streams; i++)
- {
- AVStream * stream = c->streams[i];
-
- if (stream && stream->codec && stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)
- {
- AVCodec * codec = avcodec_find_decoder (stream->codec->codec_id);
-
- if (codec)
- {
- cinfo->stream_idx = i;
- cinfo->stream = stream;
- cinfo->context = stream->codec;
- cinfo->codec = codec;
-
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
-static gboolean
-ffaudio_codec_is_seekable(AVCodec *codec)
-{
- /*
- * Blacklist certain codecs from seeking, which have problems. Codecs which have
- * problems with seeking should have bugs reported to upstream FFmpeg. --nenolod
- */
- switch (codec->id) {
-#ifndef FFAUDIO_NO_BLACKLIST
-#if CHECK_LIBAVCODEC_VERSION(54, 25, 0)
- case AV_CODEC_ID_MUSEPACK8:
-#else
- case CODEC_ID_MUSEPACK8:
-#endif
- AUDDBG("codec is blacklisted from seeking\n");
- return FALSE;
-#endif
- default:
- return TRUE;
- }
-}
-
-static gboolean ffaudio_probe (const gchar * filename, VFSFile * file)
-{
- if (! file)
- return FALSE;
-
- return get_format (filename, file) ? TRUE : FALSE;
-}
-
-typedef struct {
- TupleValueType ttype; /* Tuple field value type */
- gint field; /* Tuple field constant */
- gchar *keys[5]; /* Keys to match (case-insensitive), ended by NULL */
-} ffaudio_meta_t;
-
-static const ffaudio_meta_t metaentries[] = {
- {TUPLE_STRING, FIELD_ARTIST, {"author", "hor", "artist", NULL}},
- {TUPLE_STRING, FIELD_TITLE, {"title", "le", NULL}},
- {TUPLE_STRING, FIELD_ALBUM, {"album", "WM/AlbumTitle", NULL}},
- {TUPLE_STRING, FIELD_PERFORMER, {"performer", NULL}},
- {TUPLE_STRING, FIELD_COPYRIGHT, {"copyright", NULL}},
- {TUPLE_STRING, FIELD_GENRE, {"genre", "WM/Genre", NULL}},
- {TUPLE_STRING, FIELD_COMMENT, {"comment", NULL}},
- {TUPLE_STRING, FIELD_COMPOSER, {"composer", NULL}},
- {TUPLE_INT, FIELD_YEAR, {"year", "WM/Year", "date", NULL}},
- {TUPLE_INT, FIELD_TRACK_NUMBER, {"track", "WM/TrackNumber", NULL}},
-};
-
-static void read_metadata_dict (Tuple * tuple, AVDictionary * dict)
-{
- for (int i = 0; i < ARRAY_LEN (metaentries); i ++)
- {
- const ffaudio_meta_t * m = & metaentries[i];
- AVDictionaryEntry * entry = NULL;
-
- for (int j = 0; ! entry && m->keys[j]; j ++)
- entry = av_dict_get (dict, m->keys[j], NULL, 0);
-
- if (entry && entry->value)
- {
- if (m->ttype == TUPLE_STRING)
- tuple_set_str (tuple, m->field, entry->value);
- else if (m->ttype == TUPLE_INT)
- tuple_set_int (tuple, m->field, atoi (entry->value));
- }
- }
-}
-
-static Tuple * read_tuple (const gchar * filename, VFSFile * file)
-{
- Tuple * tuple = NULL;
- AVFormatContext * ic = open_input_file (filename, file);
-
- if (ic)
- {
- CodecInfo cinfo;
-
- if (find_codec (ic, & cinfo))
- {
- tuple = tuple_new_from_filename (filename);
-
- tuple_set_int (tuple, FIELD_LENGTH, ic->duration / 1000);
- tuple_set_int (tuple, FIELD_BITRATE, ic->bit_rate / 1000);
-
- if (cinfo.codec->long_name)
- tuple_set_str (tuple, FIELD_CODEC, cinfo.codec->long_name);
-
- if (ic->metadata)
- read_metadata_dict (tuple, ic->metadata);
- if (cinfo.stream->metadata)
- read_metadata_dict (tuple, cinfo.stream->metadata);
- }
-
- close_input_file (ic);
- }
-
- return tuple;
-}
-
-static Tuple *
-ffaudio_probe_for_tuple(const gchar *filename, VFSFile *fd)
-{
- if (! fd)
- return NULL;
-
- Tuple * t = read_tuple (filename, fd);
- if (t == NULL)
- return NULL;
-
- if (! vfs_fseek (fd, 0, SEEK_SET))
- tag_tuple_read (t, fd);
-
- return t;
-}
-
-static gboolean ffaudio_write_tag (const char * filename, VFSFile * file, const Tuple * tuple)
-{
- if (! file)
- return FALSE;
-
- if (str_has_suffix_nocase (vfs_get_filename (file), ".ape"))
- return tag_tuple_write(tuple, file, TAG_TYPE_APE);
-
- return tag_tuple_write(tuple, file, TAG_TYPE_NONE);
-}
-
-static gboolean ffaudio_play (const gchar * filename, VFSFile * file)
-{
- AUDDBG ("Playing %s.\n", filename);
- if (! file)
- return FALSE;
-
- AVPacket pkt = {.data = NULL};
- gint errcount;
- gboolean codec_opened = FALSE;
- gint out_fmt;
- gboolean planar;
- gboolean seekable;
- gboolean error = FALSE;
-
- void *buf = NULL;
- gint bufsize = 0;
-
- AVFormatContext * ic = open_input_file (filename, file);
- if (! ic)
- return FALSE;
-
- CodecInfo cinfo;
-
- if (! find_codec (ic, & cinfo))
- {
- fprintf (stderr, "ffaudio: No codec found for %s.\n", filename);
- goto error_exit;
- }
-
- AUDDBG("got codec %s for stream index %d, opening\n", cinfo.codec->name, cinfo.stream_idx);
-
- if (avcodec_open2 (cinfo.context, cinfo.codec, NULL) < 0)
- goto error_exit;
-
- codec_opened = TRUE;
-
- switch (cinfo.context->sample_fmt)
- {
- case AV_SAMPLE_FMT_U8: out_fmt = FMT_U8; planar = FALSE; break;
- case AV_SAMPLE_FMT_S16: out_fmt = FMT_S16_NE; planar = FALSE; break;
- case AV_SAMPLE_FMT_S32: out_fmt = FMT_S32_NE; planar = FALSE; break;
- case AV_SAMPLE_FMT_FLT: out_fmt = FMT_FLOAT; planar = FALSE; break;
-
- case AV_SAMPLE_FMT_U8P: out_fmt = FMT_U8; planar = TRUE; break;
- case AV_SAMPLE_FMT_S16P: out_fmt = FMT_S16_NE; planar = TRUE; break;
- case AV_SAMPLE_FMT_S32P: out_fmt = FMT_S32_NE; planar = TRUE; break;
- case AV_SAMPLE_FMT_FLTP: out_fmt = FMT_FLOAT; planar = TRUE; break;
-
- default:
- fprintf (stderr, "ffaudio: Unsupported audio format %d\n", (int) cinfo.context->sample_fmt);
- goto error_exit;
- }
-
- /* Open audio output */
- AUDDBG("opening audio output\n");
-
- if (aud_input_open_audio(out_fmt, cinfo.context->sample_rate, cinfo.context->channels) <= 0)
- {
- error = TRUE;
- goto error_exit;
- }
-
- AUDDBG("setting parameters\n");
-
- aud_input_set_bitrate(ic->bit_rate);
-
- errcount = 0;
- seekable = ffaudio_codec_is_seekable(cinfo.codec);
-
- while (! aud_input_check_stop ())
- {
- int seek_value = aud_input_check_seek ();
-
- if (seek_value >= 0 && seekable)
- {
- if (av_seek_frame (ic, -1, (gint64) seek_value * AV_TIME_BASE /
- 1000, AVSEEK_FLAG_ANY) < 0)
- {
- _ERROR("error while seeking\n");
- } else
- errcount = 0;
-
- seek_value = -1;
- }
-
- AVPacket tmp;
- gint ret;
-
- /* Read next frame (or more) of data */
- if ((ret = av_read_frame(ic, &pkt)) < 0)
- {
- if (ret == AVERROR_EOF)
- {
- AUDDBG("eof reached\n");
- break;
- }
- else
- {
- if (++errcount > 4)
- {
- _ERROR("av_read_frame error %d, giving up.\n", ret);
- break;
- } else
- continue;
- }
- } else
- errcount = 0;
-
- /* Ignore any other substreams */
- if (pkt.stream_index != cinfo.stream_idx)
- {
- av_free_packet(&pkt);
- continue;
- }
-
- /* Decode and play packet/frame */
- memcpy(&tmp, &pkt, sizeof(tmp));
- while (tmp.size > 0 && ! aud_input_check_stop ())
- {
- /* Check for seek request and bail out if we have one */
- if (seek_value < 0)
- seek_value = aud_input_check_seek ();
-
- if (seek_value >= 0)
- break;
-
-#if CHECK_LIBAVCODEC_VERSION (55, 28, 1)
- AVFrame * frame = av_frame_alloc ();
-#else
- AVFrame * frame = avcodec_alloc_frame ();
-#endif
- int decoded = 0;
- int len = avcodec_decode_audio4 (cinfo.context, frame, & decoded, & tmp);
-
- if (len < 0)
- {
- fprintf (stderr, "ffaudio: decode_audio() failed, code %d\n", len);
- break;
- }
-
- tmp.size -= len;
- tmp.data += len;
-
- if (! decoded)
- continue;
-
- gint size = FMT_SIZEOF (out_fmt) * cinfo.context->channels * frame->nb_samples;
-
- if (planar)
- {
- if (bufsize < size)
- {
- buf = g_realloc (buf, size);
- bufsize = size;
- }
-
- audio_interlace ((const void * *) frame->data, out_fmt,
- cinfo.context->channels, buf, frame->nb_samples);
- aud_input_write_audio (buf, size);
- }
- else
- aud_input_write_audio (frame->data[0], size);
-
-#if CHECK_LIBAVCODEC_VERSION (55, 28, 1)
- av_frame_free (& frame);
-#else
- avcodec_free_frame (& frame);
-#endif
- }
-
- if (pkt.data)
- av_free_packet(&pkt);
- }
-
-error_exit:
- if (pkt.data)
- av_free_packet(&pkt);
- if (codec_opened)
- avcodec_close(cinfo.context);
- if (ic != NULL)
- close_input_file(ic);
-
- g_free (buf);
-
- return ! error;
-}
-
-static const char ffaudio_about[] =
- N_("Multi-format audio decoding plugin for Audacious using\n"
- "FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
- "\n"
- "Audacious plugin by:\n"
- "William Pitcock <nenolod at nenolod.net>\n"
- "Matti Hämäläinen <ccr at tnsp.org>");
-
-static const gchar *ffaudio_fmts[] = {
- /* musepack, SV7/SV8 */
- "mpc", "mp+", "mpp",
-
- /* windows media audio */
- "wma",
-
- /* shorten */
- "shn",
-
- /* atrac3 */
- "aa3", "oma",
-
- /* MPEG 2/4 AC3 */
- "ac3",
-
- /* monkey's audio */
- "ape",
-
- /* VQF */
- "vqf",
-
- /* Apple Lossless */
- "m4a",
-
- /* WAV (there are some WAV formats sndfile can't handle) */
- "wav",
-
- /* Handle OGG streams (FLAC/Vorbis etc.) */
- "ogg", "oga",
-
- /* Opus */
- "opus",
-
- /* Speex */
- "spx",
-
- /* end of table */
- NULL
-};
-
-static const char * const ffaudio_mimes[] = {"application/ogg", NULL};
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("FFmpeg Plugin"),
- .domain = PACKAGE,
- .about_text = ffaudio_about,
- .init = ffaudio_init,
- .cleanup = ffaudio_cleanup,
- .extensions = ffaudio_fmts,
- .mimes = ffaudio_mimes,
- .is_our_file_from_vfs = ffaudio_probe,
- .probe_for_tuple = ffaudio_probe_for_tuple,
- .play = ffaudio_play,
- .update_song_tuple = ffaudio_write_tag,
-
- /* lowest priority fallback */
- .priority = 10,
-)
diff --git a/src/ffaudio/ffaudio-core.cc b/src/ffaudio/ffaudio-core.cc
new file mode 100644
index 000000000000..b10b2459e21d
--- /dev/null
+++ b/src/ffaudio/ffaudio-core.cc
@@ -0,0 +1,622 @@
+/*
+ * Audacious FFaudio Plugin
+ * Copyright © 2009 William Pitcock <nenolod at dereferenced.org>
+ * Matti Hämäläinen <ccr at tnsp.org>
+ * Copyright © 2011 John Lindgren <john.lindgren at tds.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ */
+
+#include <pthread.h>
+
+#undef FFAUDIO_DOUBLECHECK /* Doublecheck probing result for debugging purposes */
+#undef FFAUDIO_NO_BLACKLIST /* Don't blacklist any recognized codecs/formats */
+
+#include "ffaudio-stdinc.h"
+
+#include <audacious/audtag.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/multihash.h>
+#include <libaudcore/runtime.h>
+
+class FFaudio : public InputPlugin
+{
+public:
+ static const char about[];
+ static const char * const exts[], * const mimes[];
+
+ static constexpr PluginInfo info = {
+ N_("FFmpeg Plugin"),
+ PACKAGE,
+ about
+ };
+
+ static constexpr auto iinfo = InputInfo (FlagWritesTag)
+ .with_priority (10) /* lowest priority fallback */
+ .with_exts (exts)
+ .with_mimes (mimes);
+
+ constexpr FFaudio () : InputPlugin (info, iinfo) {}
+
+ bool init ();
+ void cleanup ();
+
+ bool is_our_file (const char * filename, VFSFile & file);
+ Tuple read_tuple (const char * filename, VFSFile & file);
+ Index<char> read_image (const char * filename, VFSFile & file);
+ bool write_tuple (const char * filename, VFSFile & file, const Tuple & tuple);
+ bool play (const char * filename, VFSFile & file);
+};
+
+EXPORT FFaudio aud_plugin_instance;
+
+typedef struct
+{
+ int stream_idx;
+ AVStream * stream;
+ AVCodecContext * context;
+ AVCodec * codec;
+}
+CodecInfo;
+
+static SimpleHash<String, AVInputFormat *> extension_dict;
+
+static void create_extension_dict ();
+
+static int lockmgr (void * * mutexp, enum AVLockOp op)
+{
+ switch (op)
+ {
+ case AV_LOCK_CREATE:
+ * mutexp = new pthread_mutex_t;
+ pthread_mutex_init ((pthread_mutex_t *) * mutexp, nullptr);
+ break;
+ case AV_LOCK_OBTAIN:
+ pthread_mutex_lock ((pthread_mutex_t *) * mutexp);
+ break;
+ case AV_LOCK_RELEASE:
+ pthread_mutex_unlock ((pthread_mutex_t *) * mutexp);
+ break;
+ case AV_LOCK_DESTROY:
+ pthread_mutex_destroy ((pthread_mutex_t *) * mutexp);
+ delete (pthread_mutex_t *) * mutexp;
+ break;
+ }
+
+ return 0;
+}
+
+static void ffaudio_log_cb (void * avcl, int av_level, const char * fmt, va_list va)
+{
+ audlog::Level level = audlog::Debug;
+ char message [2048];
+
+ switch (av_level)
+ {
+ case AV_LOG_QUIET:
+ return;
+ case AV_LOG_PANIC:
+ case AV_LOG_FATAL:
+ case AV_LOG_ERROR:
+ level = audlog::Error;
+ break;
+ case AV_LOG_WARNING:
+ level = audlog::Warning;
+ break;
+ case AV_LOG_INFO:
+ level = audlog::Info;
+ break;
+ default:
+ break;
+ }
+
+ AVClass * avc = avcl ? * (AVClass * *) avcl : nullptr;
+
+ vsnprintf (message, sizeof message, fmt, va);
+
+ audlog::log (level, __FILE__, __LINE__, avc ? avc->item_name(avcl) : __FUNCTION__,
+ "<%p> %s", avcl, message);
+}
+
+bool FFaudio::init ()
+{
+ av_register_all();
+ av_lockmgr_register (lockmgr);
+
+ create_extension_dict ();
+
+ av_log_set_callback (ffaudio_log_cb);
+
+ return true;
+}
+
+void FFaudio::cleanup ()
+{
+ extension_dict.clear ();
+
+ av_lockmgr_register (nullptr);
+}
+
+static const char * ffaudio_strerror (int error)
+{
+ static char buf[256];
+ return (! av_strerror (error, buf, sizeof buf)) ? buf : "unknown error";
+}
+
+static void create_extension_dict ()
+{
+ AVInputFormat * f;
+ for (f = av_iformat_next (nullptr); f; f = av_iformat_next (f))
+ {
+ if (! f->extensions)
+ continue;
+
+ StringBuf exts = str_tolower (f->extensions);
+ Index<String> extlist = str_list_to_index (exts, ",");
+
+ for (auto & ext : extlist)
+ extension_dict.add (ext, std::move (f));
+ }
+}
+
+static AVInputFormat * get_format_by_extension (const char * name)
+{
+ StringBuf ext = uri_get_extension (name);
+ if (! ext)
+ return nullptr;
+
+ AUDDBG ("Get format by extension: %s\n", name);
+ AVInputFormat * * f = extension_dict.lookup (String (str_tolower (ext)));
+
+ if (f && * f)
+ AUDDBG ("Format %s.\n", (* f)->name);
+ else
+ AUDDBG ("Format unknown.\n");
+
+ return f ? * f : nullptr;
+}
+
+static AVInputFormat * get_format_by_content (const char * name, VFSFile & file)
+{
+ AUDDBG ("Get format by content: %s\n", name);
+
+ AVInputFormat * f = nullptr;
+
+ unsigned char buf[16384 + AVPROBE_PADDING_SIZE];
+ int size = 16;
+ int filled = 0;
+ int target = 100;
+ int score = 0;
+
+ while (1)
+ {
+ if (filled < size)
+ filled += file.fread (buf + filled, 1, size - filled);
+
+ memset (buf + filled, 0, AVPROBE_PADDING_SIZE);
+ AVProbeData d = {name, buf, filled};
+ score = target;
+
+ f = av_probe_input_format2 (& d, true, & score);
+ if (f)
+ break;
+
+ if (size < 16384 && filled == size)
+ size *= 4;
+ else if (target > 10)
+ target = 10;
+ else
+ break;
+ }
+
+ if (f)
+ AUDDBG ("Format %s, buffer size %d, score %d.\n", f->name, filled, score);
+ else
+ AUDDBG ("Format unknown.\n");
+
+ if (file.fseek (0, VFS_SEEK_SET) < 0)
+ ; /* ignore errors here */
+
+ return f;
+}
+
+static AVInputFormat * get_format (const char * name, VFSFile & file)
+{
+ AVInputFormat * f = get_format_by_extension (name);
+ return f ? f : get_format_by_content (name, file);
+}
+
+static AVFormatContext * open_input_file (const char * name, VFSFile & file)
+{
+ AVInputFormat * f = get_format (name, file);
+
+ if (! f)
+ {
+ AUDERR ("Unknown format for %s.\n", name);
+ return nullptr;
+ }
+
+ AVFormatContext * c = avformat_alloc_context ();
+ AVIOContext * io = io_context_new (file);
+ c->pb = io;
+
+ int ret = avformat_open_input (& c, name, f, nullptr);
+
+ if (ret < 0)
+ {
+ AUDERR ("avformat_open_input failed for %s: %s.\n", name, ffaudio_strerror (ret));
+ io_context_free (io);
+ return nullptr;
+ }
+
+ return c;
+}
+
+static void close_input_file (AVFormatContext * c)
+{
+ AVIOContext * io = c->pb;
+
+#if CHECK_LIBAVFORMAT_VERSION (53, 25, 0, 53, 17, 0)
+ avformat_close_input (&c);
+#else
+ av_close_input_file (c);
+#endif
+
+ io_context_free (io);
+}
+
+static bool find_codec (AVFormatContext * c, CodecInfo * cinfo)
+{
+ avformat_find_stream_info (c, nullptr);
+
+ for (unsigned i = 0; i < c->nb_streams; i++)
+ {
+ AVStream * stream = c->streams[i];
+
+ if (stream && stream->codec && stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+ {
+ AVCodec * codec = avcodec_find_decoder (stream->codec->codec_id);
+
+ if (codec)
+ {
+ cinfo->stream_idx = i;
+ cinfo->stream = stream;
+ cinfo->context = stream->codec;
+ cinfo->codec = codec;
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool FFaudio::is_our_file (const char * filename, VFSFile & file)
+{
+ return (bool) get_format (filename, file);
+}
+
+static const struct {
+ Tuple::ValueType ttype; /* Tuple field value type */
+ Tuple::Field field; /* Tuple field constant */
+ const char * keys[5]; /* Keys to match (case-insensitive), ended by nullptr */
+} metaentries[] = {
+ {Tuple::String, Tuple::Artist, {"author", "hor", "artist", nullptr}},
+ {Tuple::String, Tuple::Title, {"title", "le", nullptr}},
+ {Tuple::String, Tuple::Album, {"album", "WM/AlbumTitle", nullptr}},
+ {Tuple::String, Tuple::Performer, {"performer", nullptr}},
+ {Tuple::String, Tuple::Copyright, {"copyright", nullptr}},
+ {Tuple::String, Tuple::Genre, {"genre", "WM/Genre", nullptr}},
+ {Tuple::String, Tuple::Comment, {"comment", nullptr}},
+ {Tuple::String, Tuple::Composer, {"composer", nullptr}},
+ {Tuple::Int, Tuple::Year, {"year", "WM/Year", "date", nullptr}},
+ {Tuple::Int, Tuple::Track, {"track", "WM/TrackNumber", nullptr}},
+};
+
+static void read_metadata_dict (Tuple & tuple, AVDictionary * dict)
+{
+ for (auto & meta : metaentries)
+ {
+ AVDictionaryEntry * entry = nullptr;
+
+ for (int j = 0; ! entry && meta.keys[j]; j ++)
+ entry = av_dict_get (dict, meta.keys[j], nullptr, 0);
+
+ if (entry && entry->value)
+ {
+ if (meta.ttype == Tuple::String)
+ tuple.set_str (meta.field, entry->value);
+ else if (meta.ttype == Tuple::Int)
+ tuple.set_int (meta.field, atoi (entry->value));
+ }
+ }
+}
+
+Tuple FFaudio::read_tuple (const char * filename, VFSFile & file)
+{
+ Tuple tuple;
+ AVFormatContext * ic = open_input_file (filename, file);
+
+ if (ic)
+ {
+ CodecInfo cinfo;
+
+ if (find_codec (ic, & cinfo))
+ {
+ tuple.set_filename (filename);
+
+ tuple.set_int (Tuple::Length, ic->duration / 1000);
+ tuple.set_int (Tuple::Bitrate, ic->bit_rate / 1000);
+
+ if (cinfo.codec->long_name)
+ tuple.set_str (Tuple::Codec, cinfo.codec->long_name);
+
+ if (ic->metadata)
+ read_metadata_dict (tuple, ic->metadata);
+ if (cinfo.stream->metadata)
+ read_metadata_dict (tuple, cinfo.stream->metadata);
+ }
+
+ close_input_file (ic);
+ }
+
+ if (tuple && ! file.fseek (0, VFS_SEEK_SET))
+ audtag::tuple_read (tuple, file);
+
+ return tuple;
+}
+
+bool FFaudio::write_tuple (const char * filename, VFSFile & file, const Tuple & tuple)
+{
+ if (str_has_suffix_nocase (filename, ".ape"))
+ return audtag::tuple_write (tuple, file, audtag::TagType::APE);
+
+ return audtag::tuple_write (tuple, file, audtag::TagType::None);
+}
+
+Index<char> FFaudio::read_image (const char * filename, VFSFile & file)
+{
+ if (str_has_suffix_nocase (filename, ".m4a") || str_has_suffix_nocase (filename, ".mp4"))
+ return read_itunes_cover (filename, file);
+
+ return Index<char> ();
+}
+
+bool FFaudio::play (const char * filename, VFSFile & file)
+{
+ AUDDBG ("Playing %s.\n", filename);
+
+ AVPacket pkt = AVPacket();
+ int errcount;
+ bool codec_opened = false;
+ int out_fmt;
+ bool planar;
+ bool error = false;
+
+ Index<char> buf;
+
+ AVFormatContext * ic = open_input_file (filename, file);
+ if (! ic)
+ return false;
+
+ CodecInfo cinfo;
+
+ if (! find_codec (ic, & cinfo))
+ {
+ AUDERR ("No codec found for %s.\n", filename);
+ goto error_exit;
+ }
+
+ AUDDBG("got codec %s for stream index %d, opening\n", cinfo.codec->name, cinfo.stream_idx);
+
+ if (avcodec_open2 (cinfo.context, cinfo.codec, nullptr) < 0)
+ goto error_exit;
+
+ codec_opened = true;
+
+ switch (cinfo.context->sample_fmt)
+ {
+ case AV_SAMPLE_FMT_U8: out_fmt = FMT_U8; planar = false; break;
+ case AV_SAMPLE_FMT_S16: out_fmt = FMT_S16_NE; planar = false; break;
+ case AV_SAMPLE_FMT_S32: out_fmt = FMT_S32_NE; planar = false; break;
+ case AV_SAMPLE_FMT_FLT: out_fmt = FMT_FLOAT; planar = false; break;
+
+ case AV_SAMPLE_FMT_U8P: out_fmt = FMT_U8; planar = true; break;
+ case AV_SAMPLE_FMT_S16P: out_fmt = FMT_S16_NE; planar = true; break;
+ case AV_SAMPLE_FMT_S32P: out_fmt = FMT_S32_NE; planar = true; break;
+ case AV_SAMPLE_FMT_FLTP: out_fmt = FMT_FLOAT; planar = true; break;
+
+ default:
+ AUDERR ("Unsupported audio format %d\n", (int) cinfo.context->sample_fmt);
+ goto error_exit;
+ }
+
+ /* Open audio output */
+ AUDDBG("opening audio output\n");
+
+ set_stream_bitrate(ic->bit_rate);
+ open_audio(out_fmt, cinfo.context->sample_rate, cinfo.context->channels);
+
+ errcount = 0;
+
+ while (! check_stop ())
+ {
+ int seek_value = check_seek ();
+
+ if (seek_value >= 0)
+ {
+ if (av_seek_frame (ic, -1, (int64_t) seek_value * AV_TIME_BASE /
+ 1000, AVSEEK_FLAG_ANY) < 0)
+ {
+ AUDERR ("error while seeking\n");
+ } else
+ errcount = 0;
+
+ seek_value = -1;
+ }
+
+ AVPacket tmp;
+ int ret;
+
+ /* Read next frame (or more) of data */
+ if ((ret = av_read_frame(ic, &pkt)) < 0)
+ {
+ if (ret == (int) AVERROR_EOF)
+ {
+ AUDDBG("eof reached\n");
+ break;
+ }
+ else
+ {
+ if (++errcount > 4)
+ {
+ AUDERR ("av_read_frame error %d, giving up.\n", ret);
+ break;
+ } else
+ continue;
+ }
+ } else
+ errcount = 0;
+
+ /* Ignore any other substreams */
+ if (pkt.stream_index != cinfo.stream_idx)
+ {
+ av_free_packet(&pkt);
+ continue;
+ }
+
+ /* Decode and play packet/frame */
+ memcpy(&tmp, &pkt, sizeof(tmp));
+ while (tmp.size > 0 && ! check_stop ())
+ {
+ /* Check for seek request and bail out if we have one */
+ if (seek_value < 0)
+ seek_value = check_seek ();
+
+ if (seek_value >= 0)
+ break;
+
+#if CHECK_LIBAVCODEC_VERSION (55, 45, 101, 55, 28, 1)
+ AVFrame * frame = av_frame_alloc ();
+#else
+ AVFrame * frame = avcodec_alloc_frame ();
+#endif
+ int decoded = 0;
+ int len = avcodec_decode_audio4 (cinfo.context, frame, & decoded, & tmp);
+
+ if (len < 0)
+ {
+ AUDERR ("decode_audio() failed, code %d\n", len);
+ break;
+ }
+
+ tmp.size -= len;
+ tmp.data += len;
+
+ if (! decoded)
+ continue;
+
+ int size = FMT_SIZEOF (out_fmt) * cinfo.context->channels * frame->nb_samples;
+
+ if (planar)
+ {
+ if (size > buf.len ())
+ buf.resize (size);
+
+ audio_interlace ((const void * *) frame->data, out_fmt,
+ cinfo.context->channels, buf.begin (), frame->nb_samples);
+ write_audio (buf.begin (), size);
+ }
+ else
+ write_audio (frame->data[0], size);
+
+#if CHECK_LIBAVCODEC_VERSION (55, 45, 101, 55, 28, 1)
+ av_frame_free (& frame);
+#elif CHECK_LIBAVCODEC_VERSION (54, 59, 100, 54, 28, 0)
+ avcodec_free_frame (& frame);
+#else
+ av_free (frame);
+#endif
+ }
+
+ if (pkt.data)
+ av_free_packet(&pkt);
+ }
+
+error_exit:
+ if (pkt.data)
+ av_free_packet(&pkt);
+ if (codec_opened)
+ avcodec_close(cinfo.context);
+ if (ic != nullptr)
+ close_input_file(ic);
+
+ return ! error;
+}
+
+const char FFaudio::about[] =
+ N_("Multi-format audio decoding plugin for Audacious using\n"
+ "FFmpeg multimedia framework (http://www.ffmpeg.org/)\n"
+ "\n"
+ "Audacious plugin by:\n"
+ "William Pitcock <nenolod at nenolod.net>\n"
+ "Matti Hämäläinen <ccr at tnsp.org>");
+
+const char * const FFaudio::exts[] = {
+ /* musepack, SV7/SV8 */
+ "mpc", "mp+", "mpp",
+
+ /* windows media audio */
+ "wma",
+
+ /* shorten */
+ "shn",
+
+ /* atrac3 */
+ "aa3", "oma",
+
+ /* MPEG 2/4 AC3 */
+ "ac3",
+
+ /* monkey's audio */
+ "ape",
+
+ /* DTS */
+ "dts",
+
+ /* VQF */
+ "vqf",
+
+ /* MPEG-4 */
+ "m4a", "mp4",
+
+ /* WAV (there are some WAV formats sndfile can't handle) */
+ "wav",
+
+ /* Handle OGG streams (FLAC/Vorbis etc.) */
+ "ogg", "oga",
+
+ /* Opus */
+ "opus",
+
+ /* Speex */
+ "spx",
+
+ /* end of table */
+ nullptr
+};
+
+const char * const FFaudio::mimes[] = {"application/ogg", nullptr};
diff --git a/src/ffaudio/ffaudio-io.c b/src/ffaudio/ffaudio-io.c
deleted file mode 100644
index 036209da49f3..000000000000
--- a/src/ffaudio/ffaudio-io.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * ffaudio-io.c
- * Copyright 2011 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- */
-
-#include <glib.h>
-
-#include "ffaudio-stdinc.h"
-
-#define IOBUF 4096
-
-static gint read_cb (void * file, guchar * buf, gint size)
-{
- return vfs_fread (buf, 1, size, file);
-}
-
-static gint64 seek_cb (void * file, gint64 offset, gint whence)
-{
- if (whence == AVSEEK_SIZE)
- return vfs_fsize (file);
- if (vfs_fseek (file, offset, whence & ~(gint) AVSEEK_FORCE))
- return -1;
- return vfs_ftell (file);
-}
-
-AVIOContext * io_context_new (VFSFile * file)
-{
- guchar * buf = av_malloc (IOBUF);
- return avio_alloc_context (buf, IOBUF, 0, file, read_cb, NULL, seek_cb);
-}
-
-void io_context_free (AVIOContext * io)
-{
- av_free (io->buffer);
- av_free (io);
-}
diff --git a/src/ffaudio/ffaudio-io.cc b/src/ffaudio/ffaudio-io.cc
new file mode 100644
index 000000000000..b4481c30b4f6
--- /dev/null
+++ b/src/ffaudio/ffaudio-io.cc
@@ -0,0 +1,48 @@
+/*
+ * ffaudio-io.c
+ * Copyright 2011 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ */
+
+#define WANT_VFS_STDIO_COMPAT
+#include "ffaudio-stdinc.h"
+
+#define IOBUF 4096
+
+static int read_cb (void * file, unsigned char * buf, int size)
+{
+ return ((VFSFile *) file)->fread (buf, 1, size);
+}
+
+static int64_t seek_cb (void * file, int64_t offset, int whence)
+{
+ if (whence == AVSEEK_SIZE)
+ return ((VFSFile *) file)->fsize ();
+ if (((VFSFile *) file)->fseek (offset, to_vfs_seek_type (whence & ~(int) AVSEEK_FORCE)))
+ return -1;
+ return ((VFSFile *) file)->ftell ();
+}
+
+AVIOContext * io_context_new (VFSFile & file)
+{
+ void * buf = av_malloc (IOBUF);
+ return avio_alloc_context ((unsigned char *) buf, IOBUF, 0, & file, read_cb, nullptr, seek_cb);
+}
+
+void io_context_free (AVIOContext * io)
+{
+ av_free (io->buffer);
+ av_free (io);
+}
diff --git a/src/ffaudio/ffaudio-stdinc.h b/src/ffaudio/ffaudio-stdinc.h
index 4d7df824e0b3..548ec30dd100 100644
--- a/src/ffaudio/ffaudio-stdinc.h
+++ b/src/ffaudio/ffaudio-stdinc.h
@@ -19,18 +19,32 @@
#ifndef __FFAUDIO_STDINC_H__GUARD
#define __FFAUDIO_STDINC_H__GUARD
-#define _ERROR(...) printf ("ffaudio: " __VA_ARGS__)
+#define __STDC_CONSTANT_MACROS
+#include <libaudcore/plugin.h>
-#include <audacious/plugin.h>
+extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
+}
-#define CHECK_LIBAVCODEC_VERSION(a, b, c) (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT (a, b, c))
-#define CHECK_LIBAVFORMAT_VERSION(a, b, c) (LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT (a, b, c))
-#define CHECK_LIBAVUTIL_VERSION(a, b, c) (LIBAVUTIL_VERSION_INT >= AV_VERSION_INT (a, b, c))
+/* FFmpeg and libav remain mostly compatible but have different version numbers.
+ * The first three numbers are the required FFmpeg version; the last three are for libav. */
+#ifdef HAVE_FFMPEG
+#define CHECK_LIBAVCODEC_VERSION(a, b, c, a2, b2, c2) (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT (a, b, c))
+#define CHECK_LIBAVFORMAT_VERSION(a, b, c, a2, b2, c2) (LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT (a, b, c))
+#define CHECK_LIBAVUTIL_VERSION(a, b, c, a2, b2, c2) (LIBAVUTIL_VERSION_INT >= AV_VERSION_INT (a, b, c))
+#elif defined HAVE_LIBAV
+#define CHECK_LIBAVCODEC_VERSION(a, b, c, a2, b2, c2) (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT (a2, b2, c2))
+#define CHECK_LIBAVFORMAT_VERSION(a, b, c, a2, b2, c2) (LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT (a2, b2, c2))
+#define CHECK_LIBAVUTIL_VERSION(a, b, c, a2, b2, c2) (LIBAVUTIL_VERSION_INT >= AV_VERSION_INT (a2, b2, c2))
+#else
+#error Please define either HAVE_FFMPEG or HAVE_LIBAV
+#endif
-AVIOContext * io_context_new (VFSFile * file);
+AVIOContext * io_context_new (VFSFile & file);
void io_context_free (AVIOContext * context);
+Index<char> read_itunes_cover (const char * filename, VFSFile & file);
+
#endif
diff --git a/src/ffaudio/itunes-cover.cc b/src/ffaudio/itunes-cover.cc
new file mode 100644
index 000000000000..fa51c5883c3e
--- /dev/null
+++ b/src/ffaudio/itunes-cover.cc
@@ -0,0 +1,91 @@
+/*
+ * itunes-cover.c
+ * John Lindgren, 2010
+ *
+ * The author hereby releases this code into the public domain.
+ *
+ * Reference:
+ * http://atomicparsley.sourceforge.net/mpeg-4files.html
+ */
+
+#define __STDC_LIMIT_MACROS
+#include "ffaudio-stdinc.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static const struct {
+ const char * id;
+ int skip;
+} hierarchy[] = {
+ {"moov", 0},
+ {"udta", 0},
+ {"meta", 4},
+ {"ilst", 0},
+ {"covr", 0},
+ {"data", 8}
+};
+
+Index<char> read_itunes_cover(const char * filename, VFSFile & file)
+{
+ unsigned char b[8];
+ int bsize;
+
+ Index<char> data;
+
+ /* Check for ftyp frame. */
+
+ if (file.fread (b, 1, 8) != 8)
+ return data;
+ if ((bsize = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]) < 8)
+ return data;
+ if (strncmp ((char *) b + 4, "ftyp", 4))
+ return data;
+ if (file.fseek (bsize - 8, VFS_SEEK_CUR))
+ return data;
+
+ int64_t stop = INT64_MAX;
+ int64_t at = bsize;
+
+ /* Descend into frame hierarchy. */
+
+ for (auto & frame : hierarchy)
+ {
+ while (1)
+ {
+ if (file.fread (b, 1, 8) != 8)
+ return data;
+ if ((bsize = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]) < 8 || at + bsize > stop)
+ return data;
+ if (! strncmp ((char *) b + 4, frame.id, 4))
+ break;
+ if (file.fseek (bsize - 8, VFS_SEEK_CUR))
+ return data;
+
+ at += bsize;
+ }
+
+ stop = at + bsize;
+ at += 8;
+
+ /* Skip leading bytes in some frames. */
+
+ if (frame.skip)
+ {
+ if (file.fseek (frame.skip, VFS_SEEK_CUR))
+ return data;
+ at += frame.skip;
+ }
+ }
+
+ /* We're there. */
+
+ data.insert (0, stop - at);
+
+ if (file.fread (data.begin (), 1, stop - at) != stop - at)
+ data.clear ();
+
+ return data;
+}
diff --git a/src/filewriter/Makefile b/src/filewriter/Makefile
index f659f1f85f05..347babaead01 100644
--- a/src/filewriter/Makefile
+++ b/src/filewriter/Makefile
@@ -1,17 +1,19 @@
PLUGIN = filewriter${PLUGIN_SUFFIX}
-SRCS = filewriter.c \
- wav.c \
- mp3.c \
- vorbis.c \
- flac.c \
- convert.c
+SRCS = filewriter.cc \
+ wav.cc \
+ mp3.cc \
+ vorbis.cc \
+ flac.cc \
+ convert.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${OUTPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${GTK_CFLAGS} ${FILEWRITER_CFLAGS} -I../..
LIBS += ${GTK_LIBS} ${FILEWRITER_LIBS}
diff --git a/src/filewriter/convert.c b/src/filewriter/convert.c
deleted file mode 100644
index 5a0b212cad0f..000000000000
--- a/src/filewriter/convert.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "convert.h"
-
-gpointer convert_output = NULL;
-static gint nch;
-static gint in_fmt;
-static gint out_fmt;
-
-gboolean convert_init(gint input_fmt, gint output_fmt, gint channels)
-{
- in_fmt = input_fmt;
- out_fmt = output_fmt;
- nch = channels;
-
- return TRUE;
-}
-
-gint convert_process(gpointer ptr, gint length)
-{
- gint samples = length / FMT_SIZEOF (in_fmt);
- gfloat * temp;
-
- convert_output = g_realloc (convert_output, FMT_SIZEOF (out_fmt) * samples);
-
- if (in_fmt == out_fmt)
- memcpy (convert_output, ptr, FMT_SIZEOF (in_fmt) * samples);
- else if (in_fmt == FMT_FLOAT)
- audio_to_int (ptr, convert_output, out_fmt, samples);
- else if (out_fmt == FMT_FLOAT)
- audio_from_int (ptr, in_fmt, convert_output, samples);
- else
- {
- temp = g_malloc (sizeof (gfloat) * samples);
- audio_from_int (ptr, in_fmt, temp, samples);
- audio_to_int (temp, convert_output, out_fmt, samples);
- g_free (temp);
- }
-
- return FMT_SIZEOF (out_fmt) * samples;
-}
-
-void convert_free(void)
-{
- g_free (convert_output);
- convert_output = NULL;
-}
diff --git a/src/filewriter/convert.cc b/src/filewriter/convert.cc
new file mode 100644
index 000000000000..2462f308fda6
--- /dev/null
+++ b/src/filewriter/convert.cc
@@ -0,0 +1,43 @@
+#include "convert.h"
+
+#include <string.h>
+
+static int in_fmt;
+static int out_fmt;
+
+static Index<char> convert_output;
+static Index<float> convert_temp;
+
+void convert_init (int input_fmt, int output_fmt)
+{
+ in_fmt = input_fmt;
+ out_fmt = output_fmt;
+}
+
+const Index<char> & convert_process (const void * ptr, int length)
+{
+ int samples = length / FMT_SIZEOF (in_fmt);
+
+ convert_output.resize (FMT_SIZEOF (out_fmt) * samples);
+
+ if (in_fmt == out_fmt)
+ memcpy (convert_output.begin (), ptr, FMT_SIZEOF (in_fmt) * samples);
+ else if (in_fmt == FMT_FLOAT)
+ audio_to_int ((const float *) ptr, convert_output.begin (), out_fmt, samples);
+ else if (out_fmt == FMT_FLOAT)
+ audio_from_int (ptr, in_fmt, (float *) convert_output.begin (), samples);
+ else
+ {
+ convert_temp.resize (samples);
+ audio_from_int (ptr, in_fmt, convert_temp.begin (), samples);
+ audio_to_int (convert_temp.begin (), convert_output.begin (), out_fmt, samples);
+ }
+
+ return convert_output;
+}
+
+void convert_free ()
+{
+ convert_output.clear ();
+ convert_temp.clear ();
+}
diff --git a/src/filewriter/convert.h b/src/filewriter/convert.h
index ba417af6da45..5c1869b88b90 100644
--- a/src/filewriter/convert.h
+++ b/src/filewriter/convert.h
@@ -3,12 +3,8 @@
#include "filewriter.h"
-gpointer convert_output;
-
-gboolean convert_init(gint input_fmt, gint output_fmt, gint channels);
-
-gint convert_process(gpointer ptr, gint length);
-
-void convert_free(void);
+void convert_init (int input_fmt, int output_fmt);
+const Index<char> & convert_process (const void * ptr, int length);
+void convert_free ();
#endif
diff --git a/src/filewriter/filewriter.c b/src/filewriter/filewriter.c
deleted file mode 100644
index 5771e3494ac4..000000000000
--- a/src/filewriter/filewriter.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/* FileWriter-Plugin
- * (C) copyright 2007 merging of Disk Writer and Out-Lame by Michael Färber
- *
- * Original Out-Lame-Plugin:
- * (C) copyright 2002 Lars Siebold <khandha5 at gmx.net>
- * (C) copyright 2006-2007 porting to audacious by Yoshiki Yazawa <yaz at cc.rim.or.jp>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <gtk/gtk.h>
-#include <stdlib.h>
-
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <audacious/preferences.h>
-#include <libaudcore/audstrings.h>
-#include <libaudgui/libaudgui.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "filewriter.h"
-#include "plugins.h"
-#include "convert.h"
-
-struct format_info input;
-
-static GtkWidget * path_hbox, * path_dirbrowser;
-static GtkWidget * fileext_combo, * plugin_button;
-
-enum fileext_t
-{
- WAV = 0,
-#ifdef FILEWRITER_MP3
- MP3,
-#endif
-#ifdef FILEWRITER_VORBIS
- VORBIS,
-#endif
-#ifdef FILEWRITER_FLAC
- FLAC,
-#endif
- FILEEXT_MAX
-};
-
-static gint fileext;
-static const gchar *fileext_str[FILEEXT_MAX] =
-{
- "wav",
-#ifdef FILEWRITER_MP3
- "mp3",
-#endif
-#ifdef FILEWRITER_VORBIS
- "ogg",
-#endif
-#ifdef FILEWRITER_FLAC
- "flac"
-#endif
-};
-
-static FileWriter *plugin;
-
-static gboolean save_original;
-
-static GtkWidget *filenamefrom_hbox, *filenamefrom_label;
-static gboolean filenamefromtags;
-
-static GtkWidget *use_suffix_toggle = NULL;
-static gboolean use_suffix;
-
-static GtkWidget *prependnumber_toggle;
-static gboolean prependnumber;
-
-static gchar *file_path;
-
-VFSFile *output_file = NULL;
-Tuple *tuple = NULL;
-
-static gint64 samples_written;
-
-FileWriter *plugins[FILEEXT_MAX] = {
- &wav_plugin,
-#ifdef FILEWRITER_MP3
- &mp3_plugin,
-#endif
-#ifdef FILEWRITER_VORBIS
- &vorbis_plugin,
-#endif
-#ifdef FILEWRITER_FLAC
- &flac_plugin,
-#endif
-};
-
-static void set_plugin(void)
-{
- if (fileext < 0 || fileext >= FILEEXT_MAX)
- fileext = 0;
-
- plugin = plugins[fileext];
-}
-
-static gint file_write_output (void * data, gint length)
-{
- return vfs_fwrite (data, 1, length, output_file);
-}
-
-static const gchar * const filewriter_defaults[] = {
- "fileext", "0", /* WAV */
- "filenamefromtags", "TRUE",
- "prependnumber", "FALSE",
- "save_original", "TRUE",
- "use_suffix", "FALSE",
- NULL};
-
-static gboolean file_init (void)
-{
- aud_config_set_defaults ("filewriter", filewriter_defaults);
-
- fileext = aud_get_int ("filewriter", "fileext");
- filenamefromtags = aud_get_bool ("filewriter", "filenamefromtags");
- file_path = aud_get_str ("filewriter", "file_path");
- prependnumber = aud_get_bool ("filewriter", "prependnumber");
- save_original = aud_get_bool ("filewriter", "save_original");
- use_suffix = aud_get_bool ("filewriter", "use_suffix");
-
- if (! file_path[0])
- {
- str_unref (file_path);
- file_path = filename_to_uri (g_get_home_dir ());
- g_return_val_if_fail (file_path != NULL, FALSE);
- }
-
- set_plugin();
- if (plugin->init)
- plugin->init(&file_write_output);
-
- return TRUE;
-}
-
-static void file_cleanup (void)
-{
- str_unref (file_path);
- file_path = NULL;
-}
-
-static VFSFile * safe_create (const gchar * filename)
-{
- if (! vfs_file_test (filename, G_FILE_TEST_EXISTS))
- return vfs_fopen (filename, "w");
-
- const gchar * extension = strrchr (filename, '.');
- gint length = strlen (filename);
- gchar scratch[length + 3];
- gint count;
-
- for (count = 1; count < 100; count ++)
- {
- if (extension == NULL)
- sprintf (scratch, "%s-%d", filename, count);
- else
- sprintf (scratch, "%.*s-%d%s", (gint) (extension - filename),
- filename, count, extension);
-
- if (! vfs_file_test (scratch, G_FILE_TEST_EXISTS))
- return vfs_fopen (scratch, "w");
- }
-
- return NULL;
-}
-
-static gint file_open(gint fmt, gint rate, gint nch)
-{
- gchar *filename = NULL, *temp = NULL;
- gchar * directory;
- gint pos;
- gint rv;
- gint playlist;
-
- input.format = fmt;
- input.frequency = rate;
- input.channels = nch;
-
- playlist = aud_playlist_get_playing ();
- if (playlist < 0)
- return 0;
-
- pos = aud_playlist_get_position(playlist);
- tuple = aud_playlist_entry_get_tuple (playlist, pos, FALSE);
- if (tuple == NULL)
- return 0;
-
- if (filenamefromtags)
- {
- gchar * utf8 = aud_playlist_entry_get_title (playlist, pos, FALSE);
- str_replace_char (utf8, '/', ' ');
-
- gchar buf[3 * strlen (utf8) + 1];
- str_encode_percent (utf8, -1, buf);
- str_unref (utf8);
-
- filename = g_strdup (buf);
- }
- else
- {
- temp = aud_playlist_entry_get_filename (playlist, pos);
- gchar * original = strrchr (temp, '/');
- g_return_val_if_fail (original != NULL, 0);
- filename = g_strdup (original + 1);
- str_unref (temp);
-
- if (!use_suffix)
- if ((temp = strrchr(filename, '.')) != NULL)
- *temp = '\0';
- }
-
- if (prependnumber)
- {
- gint number = tuple_get_int(tuple, FIELD_TRACK_NUMBER);
- if (!tuple || !number)
- number = pos + 1;
-
- temp = g_strdup_printf ("%d%%20%s", number, filename);
- g_free(filename);
- filename = temp;
- }
-
- if (save_original)
- {
- temp = aud_playlist_entry_get_filename (playlist, pos);
- directory = g_strdup (temp);
- str_unref (temp);
- temp = strrchr (directory, '/');
- g_return_val_if_fail (temp != NULL, 0);
- temp[1] = 0;
- }
- else
- {
- g_return_val_if_fail (file_path[0], 0);
- if (file_path[strlen (file_path) - 1] == '/')
- directory = g_strdup (file_path);
- else
- directory = g_strdup_printf ("%s/", file_path);
- }
-
- temp = g_strdup_printf ("%s%s.%s", directory, filename, fileext_str[fileext]);
- g_free (directory);
- g_free (filename);
- filename = temp;
-
- output_file = safe_create (filename);
- g_free (filename);
-
- if (output_file == NULL)
- return 0;
-
- convert_init (fmt, plugin->format_required (fmt), nch);
-
- rv = (plugin->open)();
-
- samples_written = 0;
-
- return rv;
-}
-
-static void file_write(void *ptr, gint length)
-{
- int len = convert_process (ptr, length);
-
- plugin->write(convert_output, len);
-
- samples_written += length / FMT_SIZEOF (input.format);
-}
-
-static void file_drain (void)
-{
-}
-
-static void file_close(void)
-{
- plugin->close();
- convert_free();
-
- if (output_file != NULL)
- vfs_fclose(output_file);
- output_file = NULL;
-
- if (tuple)
- {
- tuple_unref (tuple);
- tuple = NULL;
- }
-}
-
-static void file_flush(gint time)
-{
- samples_written = time * (gint64) input.channels * input.frequency / 1000;
-}
-
-static void file_pause (gboolean p)
-{
-}
-
-static gint file_get_time (void)
-{
- return samples_written * 1000 / (input.channels * input.frequency);
-}
-
-static void configure_response_cb (void)
-{
- fileext = gtk_combo_box_get_active(GTK_COMBO_BOX(fileext_combo));
-
- char * temp = gtk_file_chooser_get_uri ((GtkFileChooser *) path_dirbrowser);
- str_unref (file_path);
- file_path = str_get (temp);
- g_free (temp);
-
- use_suffix =
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(use_suffix_toggle));
-
- prependnumber =
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prependnumber_toggle));
-
- aud_set_int ("filewriter", "fileext", fileext);
- aud_set_bool ("filewriter", "filenamefromtags", filenamefromtags);
- aud_set_str ("filewriter", "file_path", file_path);
- aud_set_bool ("filewriter", "prependnumber", prependnumber);
- aud_set_bool ("filewriter", "save_original", save_original);
- aud_set_bool ("filewriter", "use_suffix", use_suffix);
-}
-
-static void fileext_cb(GtkWidget *combo, gpointer data)
-{
- fileext = gtk_combo_box_get_active(GTK_COMBO_BOX(fileext_combo));
- set_plugin();
- if (plugin->init)
- plugin->init(&file_write_output);
-
- gtk_widget_set_sensitive(plugin_button, plugin->configure != NULL);
-}
-
-static void plugin_configure_cb(GtkWidget *button, gpointer data)
-{
- if (plugin->configure)
- plugin->configure();
-}
-
-
-static void saveplace_original_cb(GtkWidget *button, gpointer data)
-{
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
- {
- gtk_widget_set_sensitive(path_hbox, FALSE);
- save_original = TRUE;
- }
-}
-
-static void saveplace_custom_cb(GtkWidget *button, gpointer data)
-{
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
- {
- gtk_widget_set_sensitive(path_hbox, TRUE);
- save_original = FALSE;
- }
-}
-
-static void filenamefromtags_cb(GtkWidget *button, gpointer data)
-{
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
- {
- gtk_widget_set_sensitive(use_suffix_toggle, FALSE);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_suffix_toggle), FALSE);
- use_suffix = FALSE;
- filenamefromtags = TRUE;
- }
-}
-
-static void filenamefromfilename_cb(GtkWidget *button, gpointer data)
-{
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
- {
- gtk_widget_set_sensitive(use_suffix_toggle, TRUE);
- filenamefromtags = FALSE;
- }
-}
-
-static void * file_configure (void)
-{
- GtkWidget * configure_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-
- GtkWidget * fileext_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_box_pack_start(GTK_BOX(configure_vbox), fileext_hbox, FALSE, FALSE, 0);
-
- GtkWidget * fileext_label = gtk_label_new (_("Output file format:"));
- gtk_box_pack_start(GTK_BOX(fileext_hbox), fileext_label, FALSE, FALSE, 0);
-
- fileext_combo = gtk_combo_box_text_new ();
- gtk_combo_box_text_append_text ((GtkComboBoxText *) fileext_combo, "WAV");
-#ifdef FILEWRITER_MP3
- gtk_combo_box_text_append_text ((GtkComboBoxText *) fileext_combo, "MP3");
-#endif
-#ifdef FILEWRITER_VORBIS
- gtk_combo_box_text_append_text ((GtkComboBoxText *) fileext_combo, "Vorbis");
-#endif
-#ifdef FILEWRITER_FLAC
- gtk_combo_box_text_append_text ((GtkComboBoxText *) fileext_combo, "FLAC");
-#endif
- gtk_box_pack_start(GTK_BOX(fileext_hbox), fileext_combo, FALSE, FALSE, 0);
- gtk_combo_box_set_active(GTK_COMBO_BOX(fileext_combo), fileext);
-
- plugin_button = gtk_button_new_with_label(_("Configure"));
- gtk_widget_set_sensitive(plugin_button, plugin->configure != NULL);
- gtk_box_pack_end(GTK_BOX(fileext_hbox), plugin_button, FALSE, FALSE, 0);
-
- gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_separator_new(GTK_ORIENTATION_HORIZONTAL), FALSE, FALSE, 0);
-
- GtkWidget * saveplace_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_add(GTK_CONTAINER(configure_vbox), saveplace_hbox);
-
- GtkWidget * saveplace1 = gtk_radio_button_new_with_label (NULL,
- _("Save into original directory"));
- gtk_box_pack_start ((GtkBox *) saveplace_hbox, saveplace1, FALSE, FALSE, 0);
-
- GtkWidget * saveplace2 = gtk_radio_button_new_with_label_from_widget
- ((GtkRadioButton *) saveplace1, _("Save into custom directory"));
-
- if (!save_original)
- gtk_toggle_button_set_active ((GtkToggleButton *) saveplace2, TRUE);
-
- gtk_box_pack_start ((GtkBox *) saveplace_hbox, saveplace2, FALSE, FALSE, 0);
-
- path_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_box_pack_start(GTK_BOX(configure_vbox), path_hbox, FALSE, FALSE, 0);
-
- GtkWidget * path_label = gtk_label_new (_("Output file folder:"));
- gtk_box_pack_start ((GtkBox *) path_hbox, path_label, FALSE, FALSE, 0);
-
- path_dirbrowser =
- gtk_file_chooser_button_new (_("Pick a folder"),
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
- gtk_file_chooser_set_uri ((GtkFileChooser *) path_dirbrowser, file_path);
- gtk_box_pack_start(GTK_BOX(path_hbox), path_dirbrowser, TRUE, TRUE, 0);
-
- if (save_original)
- gtk_widget_set_sensitive(path_hbox, FALSE);
-
- gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_separator_new(GTK_ORIENTATION_HORIZONTAL), FALSE, FALSE, 0);
-
- filenamefrom_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_add(GTK_CONTAINER(configure_vbox), filenamefrom_hbox);
-
- filenamefrom_label = gtk_label_new(_("Get filename from:"));
- gtk_box_pack_start(GTK_BOX(filenamefrom_hbox), filenamefrom_label, FALSE, FALSE, 0);
-
- GtkWidget * filenamefrom_toggle1 = gtk_radio_button_new_with_label
- (NULL, _("original file tags"));
- gtk_box_pack_start ((GtkBox *) filenamefrom_hbox, filenamefrom_toggle1, FALSE, FALSE, 0);
-
- GtkWidget * filenamefrom_toggle2 =
- gtk_radio_button_new_with_label_from_widget
- ((GtkRadioButton *) filenamefrom_toggle1, _("original filename"));
- gtk_box_pack_start ((GtkBox *) filenamefrom_hbox, filenamefrom_toggle2, FALSE, FALSE, 0);
-
- if (!filenamefromtags)
- gtk_toggle_button_set_active ((GtkToggleButton *) filenamefrom_toggle2, TRUE);
-
- use_suffix_toggle = gtk_check_button_new_with_label(_("Don't strip file name extension"));
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_suffix_toggle), use_suffix);
- gtk_box_pack_start(GTK_BOX(configure_vbox), use_suffix_toggle, FALSE, FALSE, 0);
-
- if (filenamefromtags)
- gtk_widget_set_sensitive(use_suffix_toggle, FALSE);
-
- gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_separator_new(GTK_ORIENTATION_HORIZONTAL), FALSE, FALSE, 0);
-
- prependnumber_toggle = gtk_check_button_new_with_label(_("Prepend track number to filename"));
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prependnumber_toggle), prependnumber);
- gtk_box_pack_start(GTK_BOX(configure_vbox), prependnumber_toggle, FALSE, FALSE, 0);
-
- g_signal_connect (fileext_combo, "changed", (GCallback) fileext_cb, NULL);
- g_signal_connect (plugin_button, "clicked", (GCallback) plugin_configure_cb, NULL);
- g_signal_connect (saveplace1, "toggled", (GCallback) saveplace_original_cb, NULL);
- g_signal_connect (saveplace2, "toggled", (GCallback) saveplace_custom_cb, NULL);
- g_signal_connect (filenamefrom_toggle1, "toggled", (GCallback) filenamefromtags_cb, NULL);
- g_signal_connect (filenamefrom_toggle2, "toggled",
- (GCallback) filenamefromfilename_cb, NULL);
-
- return configure_vbox;
-}
-
-static const char file_about[] =
- N_("This program is free software; you can redistribute it and/or modify\n"
- "it under the terms of the GNU General Public License as published by\n"
- "the Free Software Foundation; either version 2 of the License, or\n"
- "(at your option) any later version.\n"
- "\n"
- "This program is distributed in the hope that it will be useful,\n"
- "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
- "GNU General Public License for more details.\n"
- "\n"
- "You should have received a copy of the GNU General Public License\n"
- "along with this program; if not, write to the Free Software\n"
- "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
- "USA.");
-
-static const PreferencesWidget file_widgets[] = {
- {WIDGET_CUSTOM, .data = {.populate = file_configure}}};
-
-static const PluginPreferences file_prefs = {
- .widgets = file_widgets,
- .n_widgets = ARRAY_LEN (file_widgets),
- .apply = configure_response_cb};
-
-AUD_OUTPUT_PLUGIN
-(
- .name = N_("FileWriter Plugin"),
- .domain = PACKAGE,
- .about_text = file_about,
- .init = file_init,
- .cleanup = file_cleanup,
- .prefs = & file_prefs,
- .probe_priority = 0,
- .open_audio = file_open,
- .close_audio = file_close,
- .write_audio = file_write,
- .drain = file_drain,
- .output_time = file_get_time,
- .pause = file_pause,
- .flush = file_flush,
- .force_reopen = TRUE
-)
diff --git a/src/filewriter/filewriter.cc b/src/filewriter/filewriter.cc
new file mode 100644
index 000000000000..c2c2a9a5c7e4
--- /dev/null
+++ b/src/filewriter/filewriter.cc
@@ -0,0 +1,507 @@
+/* FileWriter-Plugin
+ * (C) copyright 2007 merging of Disk Writer and Out-Lame by Michael Färber
+ *
+ * Original Out-Lame-Plugin:
+ * (C) copyright 2002 Lars Siebold <khandha5 at gmx.net>
+ * (C) copyright 2006-2007 porting to audacious by Yoshiki Yazawa <yaz at cc.rim.or.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/runtime.h>
+
+#include "filewriter.h"
+#include "plugins.h"
+#include "convert.h"
+
+class FileWriter : public OutputPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("FileWriter Plugin"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ constexpr FileWriter () : OutputPlugin (info, 0, true) {}
+
+ bool init ();
+ void cleanup ();
+
+ StereoVolume get_volume () { return {0, 0}; }
+ void set_volume (StereoVolume v) {}
+
+ void set_info (const char * filename, const Tuple & tuple);
+ bool open_audio (int fmt, int rate, int nch);
+ void close_audio ();
+
+ void period_wait () {}
+ int write_audio (const void * ptr, int length);
+ void drain () {}
+
+ int get_delay ()
+ { return 0; }
+
+ void pause (bool pause) {}
+ void flush () {}
+};
+
+EXPORT FileWriter aud_plugin_instance;
+
+static String in_filename;
+static Tuple in_tuple;
+
+struct format_info input;
+
+static GtkWidget * path_hbox, * path_dirbrowser;
+static GtkWidget * fileext_combo, * plugin_button;
+
+enum fileext_t
+{
+ WAV = 0,
+#ifdef FILEWRITER_MP3
+ MP3,
+#endif
+#ifdef FILEWRITER_VORBIS
+ VORBIS,
+#endif
+#ifdef FILEWRITER_FLAC
+ FLAC,
+#endif
+ FILEEXT_MAX
+};
+
+static int fileext;
+static const char *fileext_str[FILEEXT_MAX] =
+{
+ "wav",
+#ifdef FILEWRITER_MP3
+ "mp3",
+#endif
+#ifdef FILEWRITER_VORBIS
+ "ogg",
+#endif
+#ifdef FILEWRITER_FLAC
+ "flac"
+#endif
+};
+
+static FileWriterImpl *plugin;
+
+static gboolean save_original;
+
+static GtkWidget *filenamefrom_hbox, *filenamefrom_label;
+static gboolean filenamefromtags;
+
+static GtkWidget *use_suffix_toggle = nullptr;
+static gboolean use_suffix;
+
+static GtkWidget *prependnumber_toggle;
+static gboolean prependnumber;
+
+static String file_path;
+
+static VFSFile output_file;
+
+FileWriterImpl *plugins[FILEEXT_MAX] = {
+ &wav_plugin,
+#ifdef FILEWRITER_MP3
+ &mp3_plugin,
+#endif
+#ifdef FILEWRITER_VORBIS
+ &vorbis_plugin,
+#endif
+#ifdef FILEWRITER_FLAC
+ &flac_plugin,
+#endif
+};
+
+static void set_plugin(void)
+{
+ if (fileext < 0 || fileext >= FILEEXT_MAX)
+ fileext = 0;
+
+ plugin = plugins[fileext];
+}
+
+const char * const FileWriter::defaults[] = {
+ "fileext", "0", /* WAV */
+ "filenamefromtags", "TRUE",
+ "prependnumber", "FALSE",
+ "save_original", "TRUE",
+ "use_suffix", "FALSE",
+ nullptr};
+
+bool FileWriter::init ()
+{
+ aud_config_set_defaults ("filewriter", defaults);
+
+ fileext = aud_get_int ("filewriter", "fileext");
+ filenamefromtags = aud_get_bool ("filewriter", "filenamefromtags");
+ file_path = aud_get_str ("filewriter", "file_path");
+ prependnumber = aud_get_bool ("filewriter", "prependnumber");
+ save_original = aud_get_bool ("filewriter", "save_original");
+ use_suffix = aud_get_bool ("filewriter", "use_suffix");
+
+ if (! file_path[0])
+ {
+ file_path = String (filename_to_uri (g_get_home_dir ()));
+ g_return_val_if_fail (file_path != nullptr, false);
+ }
+
+ set_plugin();
+ if (plugin->init)
+ plugin->init();
+
+ return true;
+}
+
+void FileWriter::cleanup ()
+{
+ file_path = String ();
+}
+
+static VFSFile safe_create (const char * filename)
+{
+ if (! VFSFile::test_file (filename, VFS_EXISTS))
+ return VFSFile (filename, "w");
+
+ const char * extension = strrchr (filename, '.');
+
+ for (int count = 1; count < 100; count ++)
+ {
+ StringBuf scratch = extension ?
+ str_printf ("%.*s-%d%s", (int) (extension - filename), filename, count, extension) :
+ str_printf ("%s-%d", filename, count);
+
+ if (! VFSFile::test_file (scratch, VFS_EXISTS))
+ return VFSFile (scratch, "w");
+ }
+
+ return VFSFile ();
+}
+
+void FileWriter::set_info (const char * filename, const Tuple & tuple)
+{
+ in_filename = String (filename);
+ in_tuple = tuple.ref ();
+}
+
+bool FileWriter::open_audio (int fmt, int rate, int nch)
+{
+ String filename, directory;
+
+ input.format = fmt;
+ input.frequency = rate;
+ input.channels = nch;
+
+ if (filenamefromtags)
+ {
+ String title = in_tuple.get_str (Tuple::FormattedTitle);
+ StringBuf buf = str_encode_percent (title);
+ str_replace_char (buf, '/', '-');
+ filename = String (buf);
+ }
+ else
+ {
+ const char * original = strrchr (in_filename, '/');
+ g_return_val_if_fail (original != nullptr, 0);
+ filename = String (original + 1);
+
+ if (! use_suffix)
+ {
+ const char * temp;
+ if ((temp = strrchr (filename, '.')))
+ filename = String (str_copy (filename, temp - filename));
+ }
+ }
+
+ if (prependnumber)
+ {
+ int number = in_tuple.get_int (Tuple::Track);
+ if (number >= 0)
+ filename = String (str_printf ("%d%%20%s", number, (const char *) filename));
+ }
+
+ if (save_original)
+ {
+ const char * temp = strrchr (in_filename, '/');
+ g_return_val_if_fail (temp != nullptr, 0);
+ directory = String (str_copy (in_filename, temp + 1 - in_filename));
+ }
+ else
+ {
+ g_return_val_if_fail (file_path[0], 0);
+ if (file_path[strlen (file_path) - 1] == '/')
+ directory = String (file_path);
+ else
+ directory = String (str_concat ({file_path, "/"}));
+ }
+
+ filename = String (str_printf ("%s%s.%s", (const char *) directory,
+ (const char *) filename, fileext_str[fileext]));
+
+ output_file = safe_create (filename);
+ if (! output_file)
+ goto err;
+
+ convert_init (fmt, plugin->format_required (fmt));
+
+ if (plugin->open (output_file, input, in_tuple))
+ return true;
+
+err:
+ in_filename = String ();
+ in_tuple = Tuple ();
+ return false;
+}
+
+int FileWriter::write_audio (const void * ptr, int length)
+{
+ auto & buf = convert_process (ptr, length);
+ plugin->write (output_file, buf.begin (), buf.len ());
+
+ return length;
+}
+
+void FileWriter::close_audio ()
+{
+ plugin->close (output_file);
+ convert_free ();
+
+ output_file = VFSFile ();
+ in_filename = String ();
+ in_tuple = Tuple ();
+}
+
+static void configure_response_cb (void)
+{
+ fileext = gtk_combo_box_get_active(GTK_COMBO_BOX(fileext_combo));
+
+ char * temp = gtk_file_chooser_get_uri ((GtkFileChooser *) path_dirbrowser);
+ file_path = String (temp);
+ g_free (temp);
+
+ use_suffix =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(use_suffix_toggle));
+
+ prependnumber =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prependnumber_toggle));
+
+ aud_set_int ("filewriter", "fileext", fileext);
+ aud_set_bool ("filewriter", "filenamefromtags", filenamefromtags);
+ aud_set_str ("filewriter", "file_path", file_path);
+ aud_set_bool ("filewriter", "prependnumber", prependnumber);
+ aud_set_bool ("filewriter", "save_original", save_original);
+ aud_set_bool ("filewriter", "use_suffix", use_suffix);
+}
+
+static void fileext_cb(GtkWidget *combo, void * data)
+{
+ fileext = gtk_combo_box_get_active(GTK_COMBO_BOX(fileext_combo));
+ set_plugin();
+ if (plugin->init)
+ plugin->init();
+
+ gtk_widget_set_sensitive(plugin_button, plugin->configure != nullptr);
+}
+
+static void plugin_configure_cb(GtkWidget *button, void * data)
+{
+ if (plugin->configure)
+ plugin->configure();
+}
+
+
+static void saveplace_original_cb(GtkWidget *button, void * data)
+{
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
+ {
+ gtk_widget_set_sensitive(path_hbox, FALSE);
+ save_original = TRUE;
+ }
+}
+
+static void saveplace_custom_cb(GtkWidget *button, void * data)
+{
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
+ {
+ gtk_widget_set_sensitive(path_hbox, TRUE);
+ save_original = FALSE;
+ }
+}
+
+static void filenamefromtags_cb(GtkWidget *button, void * data)
+{
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
+ {
+ gtk_widget_set_sensitive(use_suffix_toggle, FALSE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_suffix_toggle), FALSE);
+ use_suffix = FALSE;
+ filenamefromtags = TRUE;
+ }
+}
+
+static void filenamefromfilename_cb(GtkWidget *button, void * data)
+{
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
+ {
+ gtk_widget_set_sensitive(use_suffix_toggle, TRUE);
+ filenamefromtags = FALSE;
+ }
+}
+
+static void * file_configure (void)
+{
+ GtkWidget * configure_vbox = gtk_vbox_new (FALSE, 6);
+
+ GtkWidget * fileext_hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(configure_vbox), fileext_hbox, FALSE, FALSE, 0);
+
+ GtkWidget * fileext_label = gtk_label_new (_("Output file format:"));
+ gtk_box_pack_start(GTK_BOX(fileext_hbox), fileext_label, FALSE, FALSE, 0);
+
+ fileext_combo = gtk_combo_box_text_new ();
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) fileext_combo, "WAV");
+#ifdef FILEWRITER_MP3
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) fileext_combo, "MP3");
+#endif
+#ifdef FILEWRITER_VORBIS
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) fileext_combo, "Vorbis");
+#endif
+#ifdef FILEWRITER_FLAC
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) fileext_combo, "FLAC");
+#endif
+ gtk_box_pack_start(GTK_BOX(fileext_hbox), fileext_combo, FALSE, FALSE, 0);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(fileext_combo), fileext);
+
+ plugin_button = gtk_button_new_with_label(_("Configure"));
+ gtk_widget_set_sensitive(plugin_button, plugin->configure != nullptr);
+ gtk_box_pack_end(GTK_BOX(fileext_hbox), plugin_button, FALSE, FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_hseparator_new(), FALSE, FALSE, 0);
+
+ GtkWidget * saveplace_hbox = gtk_hbox_new (FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(configure_vbox), saveplace_hbox);
+
+ GtkWidget * saveplace1 = gtk_radio_button_new_with_label (nullptr,
+ _("Save into original directory"));
+ gtk_box_pack_start ((GtkBox *) saveplace_hbox, saveplace1, FALSE, FALSE, 0);
+
+ GtkWidget * saveplace2 = gtk_radio_button_new_with_label_from_widget
+ ((GtkRadioButton *) saveplace1, _("Save into custom directory"));
+
+ if (!save_original)
+ gtk_toggle_button_set_active ((GtkToggleButton *) saveplace2, TRUE);
+
+ gtk_box_pack_start ((GtkBox *) saveplace_hbox, saveplace2, FALSE, FALSE, 0);
+
+ path_hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(configure_vbox), path_hbox, FALSE, FALSE, 0);
+
+ GtkWidget * path_label = gtk_label_new (_("Output file folder:"));
+ gtk_box_pack_start ((GtkBox *) path_hbox, path_label, FALSE, FALSE, 0);
+
+ path_dirbrowser =
+ gtk_file_chooser_button_new (_("Pick a folder"),
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+ gtk_file_chooser_set_uri ((GtkFileChooser *) path_dirbrowser, file_path);
+ gtk_box_pack_start(GTK_BOX(path_hbox), path_dirbrowser, TRUE, TRUE, 0);
+
+ if (save_original)
+ gtk_widget_set_sensitive(path_hbox, FALSE);
+
+ gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_hseparator_new(), FALSE, FALSE, 0);
+
+ filenamefrom_hbox = gtk_hbox_new (FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(configure_vbox), filenamefrom_hbox);
+
+ filenamefrom_label = gtk_label_new(_("Generate file name from:"));
+ gtk_box_pack_start(GTK_BOX(filenamefrom_hbox), filenamefrom_label, FALSE, FALSE, 0);
+
+ GtkWidget * filenamefrom_toggle1 = gtk_radio_button_new_with_label
+ (nullptr, _("Original file tag"));
+ gtk_box_pack_start ((GtkBox *) filenamefrom_hbox, filenamefrom_toggle1, FALSE, FALSE, 0);
+
+ GtkWidget * filenamefrom_toggle2 =
+ gtk_radio_button_new_with_label_from_widget
+ ((GtkRadioButton *) filenamefrom_toggle1, _("Original file name"));
+ gtk_box_pack_start ((GtkBox *) filenamefrom_hbox, filenamefrom_toggle2, FALSE, FALSE, 0);
+
+ if (!filenamefromtags)
+ gtk_toggle_button_set_active ((GtkToggleButton *) filenamefrom_toggle2, TRUE);
+
+ use_suffix_toggle = gtk_check_button_new_with_label(_("Include original file name extension"));
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_suffix_toggle), use_suffix);
+ gtk_box_pack_start(GTK_BOX(configure_vbox), use_suffix_toggle, FALSE, FALSE, 0);
+
+ if (filenamefromtags)
+ gtk_widget_set_sensitive(use_suffix_toggle, FALSE);
+
+ gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_hseparator_new(), FALSE, FALSE, 0);
+
+ prependnumber_toggle = gtk_check_button_new_with_label(_("Prepend track number to file name"));
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prependnumber_toggle), prependnumber);
+ gtk_box_pack_start(GTK_BOX(configure_vbox), prependnumber_toggle, FALSE, FALSE, 0);
+
+ g_signal_connect (fileext_combo, "changed", (GCallback) fileext_cb, nullptr);
+ g_signal_connect (plugin_button, "clicked", (GCallback) plugin_configure_cb, nullptr);
+ g_signal_connect (saveplace1, "toggled", (GCallback) saveplace_original_cb, nullptr);
+ g_signal_connect (saveplace2, "toggled", (GCallback) saveplace_custom_cb, nullptr);
+ g_signal_connect (filenamefrom_toggle1, "toggled", (GCallback) filenamefromtags_cb, nullptr);
+ g_signal_connect (filenamefrom_toggle2, "toggled",
+ (GCallback) filenamefromfilename_cb, nullptr);
+
+ return configure_vbox;
+}
+
+const char FileWriter::about[] =
+ N_("This program is free software; you can redistribute it and/or modify\n"
+ "it under the terms of the GNU General Public License as published by\n"
+ "the Free Software Foundation; either version 2 of the License, or\n"
+ "(at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
+ "USA.");
+
+const PreferencesWidget FileWriter::widgets[] = {
+ WidgetCustomGTK (file_configure)
+};
+
+const PluginPreferences FileWriter::prefs = {
+ {widgets},
+ nullptr, // init
+ configure_response_cb
+};
diff --git a/src/filewriter/filewriter.h b/src/filewriter/filewriter.h
index a4186b94e997..4fe437bb3f7b 100644
--- a/src/filewriter/filewriter.h
+++ b/src/filewriter/filewriter.h
@@ -23,35 +23,25 @@
#ifndef FILEWRITER_H
#define FILEWRITER_H
-#include <gtk/gtk.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <audacious/plugin.h>
-#include <audacious/i18n.h>
+#define WANT_AUD_BSWAP
+#include <libaudcore/audio.h>
+#include <libaudcore/tuple.h>
+#include <libaudcore/vfs.h>
struct format_info {
- gint format;
+ int format;
int frequency;
int channels;
};
-extern struct format_info input;
-
-extern VFSFile *output_file;
-extern guint64 offset;
-extern Tuple * tuple;
-
-typedef gint (*write_output_callback)(void *ptr, gint length);
-
-typedef struct _FileWriter
+struct FileWriterImpl
{
- void (*init)(write_output_callback write_output_func);
- void (*configure)(void);
- gint (*open)(void);
- void (*write)(void *ptr, gint length);
- void (*close)(void);
- int (*format_required)(int fmt);
-} FileWriter;
+ void (* init) ();
+ void (* configure) ();
+ bool (* open) (VFSFile & file, const format_info & info, const Tuple & tuple);
+ void (* write) (VFSFile & file, const void * data, int length);
+ void (* close) (VFSFile & file);
+ int (* format_required) (int fmt);
+};
#endif
diff --git a/src/filewriter/flac.c b/src/filewriter/flac.c
deleted file mode 100644
index f9eb8a325eb7..000000000000
--- a/src/filewriter/flac.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* FileWriter FLAC Plugin
- * Copyright (c) 2007 William Pitcock <nenolod at sacredspiral.co.uk>
- *
- * Partially derived from Og(g)re - Ogg-Output-Plugin:
- * Copyright (c) 2002 Lars Siebold <khandha5 at gmx.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "plugins.h"
-
-#ifdef FILEWRITER_FLAC
-
-#include <FLAC/all.h>
-#include <stdlib.h>
-
-static FLAC__StreamEncoder *flac_encoder;
-static FLAC__StreamMetadata *flac_metadata;
-
-static FLAC__StreamEncoderWriteStatus flac_write_cb(const FLAC__StreamEncoder *encoder,
- const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, gpointer data)
-{
- if (vfs_fwrite (buffer, 1, bytes, data) != bytes)
- return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
-
- return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
-}
-
-static FLAC__StreamEncoderSeekStatus flac_seek_cb(const FLAC__StreamEncoder *encoder,
- FLAC__uint64 absolute_byte_offset, gpointer data)
-{
- VFSFile *file = (VFSFile *) data;
-
- if (vfs_fseek(file, absolute_byte_offset, SEEK_SET) < 0)
- return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;
-
- return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
-}
-
-static FLAC__StreamEncoderTellStatus flac_tell_cb(const FLAC__StreamEncoder *encoder,
- FLAC__uint64 *absolute_byte_offset, gpointer data)
-{
- VFSFile *file = (VFSFile *) data;
-
- *absolute_byte_offset = vfs_ftell(file);
-
- return FLAC__STREAM_ENCODER_TELL_STATUS_OK;
-}
-
-static void insert_vorbis_comment (FLAC__StreamMetadata * meta,
- const char * name, const Tuple * tuple, int field)
-{
- TupleValueType type = tuple_field_get_type (field);
- if (tuple_get_value_type (tuple, field) != type)
- return;
-
- char * temp;
-
- switch (type)
- {
- case TUPLE_INT:;
- int ival = tuple_get_int (tuple, field);
- temp = g_strdup_printf ("%s=%d", name, ival);
- break;
- case TUPLE_STRING:;
- char * sval = tuple_get_str (tuple, field);
- temp = g_strdup_printf ("%s=%s", name, sval);
- str_unref (sval);
- break;
- default:
- return;
- }
-
- FLAC__StreamMetadata_VorbisComment_Entry comment;
- comment.length = strlen (temp);
- comment.entry = (unsigned char *) temp;
-
- FLAC__metadata_object_vorbiscomment_insert_comment (meta,
- meta->data.vorbis_comment.num_comments, comment, TRUE);
-
- g_free (temp);
-}
-
-static gint flac_open(void)
-{
- flac_encoder = FLAC__stream_encoder_new();
-
- FLAC__stream_encoder_set_channels(flac_encoder, input.channels);
- FLAC__stream_encoder_set_sample_rate(flac_encoder, input.frequency);
-
- if (tuple)
- {
- flac_metadata = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
-
- insert_vorbis_comment (flac_metadata, "TITLE", tuple, FIELD_TITLE);
- insert_vorbis_comment (flac_metadata, "ARTIST", tuple, FIELD_ARTIST);
- insert_vorbis_comment (flac_metadata, "ALBUM", tuple, FIELD_ALBUM);
- insert_vorbis_comment (flac_metadata, "GENRE", tuple, FIELD_GENRE);
- insert_vorbis_comment (flac_metadata, "COMMENT", tuple, FIELD_COMMENT);
- insert_vorbis_comment (flac_metadata, "DATE", tuple, FIELD_DATE);
- insert_vorbis_comment (flac_metadata, "YEAR", tuple, FIELD_YEAR);
- insert_vorbis_comment (flac_metadata, "TRACKNUMBER", tuple, FIELD_TRACK_NUMBER);
-
- FLAC__stream_encoder_set_metadata(flac_encoder, &flac_metadata, 1);
- }
-
- FLAC__stream_encoder_init_stream(flac_encoder, flac_write_cb, flac_seek_cb,
- flac_tell_cb, NULL, output_file);
-
- return 1;
-}
-
-static void flac_write(gpointer data, gint length)
-{
-#if 1
- FLAC__int32 *encbuffer[2];
- short int *tmpdata = data;
- int i;
-
- encbuffer[0] = g_new0(FLAC__int32, length / input.channels);
- encbuffer[1] = g_new0(FLAC__int32, length / input.channels);
-
- if (input.channels == 1)
- {
- for (i = 0; i < (length / 2); i++)
- {
- encbuffer[0][i] = tmpdata[i];
- encbuffer[1][i] = tmpdata[i];
- }
- }
- else
- {
- for (i = 0; i < (length / 4); i++)
- {
- encbuffer[0][i] = tmpdata[2 * i];
- encbuffer[1][i] = tmpdata[2 * i + 1];
- }
- }
-
- FLAC__stream_encoder_process(flac_encoder, (const FLAC__int32 **)encbuffer, length / (input.channels * 2));
-
- g_free(encbuffer[0]);
- g_free(encbuffer[1]);
-#else
- FLAC__int32 *encbuffer;
- gint16 *tmpdata = data;
- int i;
-
- encbuffer = g_new0(FLAC__int32, length);
-
- for (i=0; i < length; i++) {
- encbuffer[i] = tmpdata[i];
- }
-
- FLAC__stream_encoder_process_interleaved(flac_encoder, encbuffer, length);
-
- g_free(encbuffer);
-#endif
-}
-
-static void flac_close(void)
-{
- if (flac_encoder)
- {
- FLAC__stream_encoder_finish(flac_encoder);
- FLAC__stream_encoder_delete(flac_encoder);
- flac_encoder = NULL;
- }
-
- if (flac_metadata)
- {
- FLAC__metadata_object_delete(flac_metadata);
- flac_metadata = NULL;
- }
-}
-
-static int flac_format_required (int fmt)
-{
- return FMT_S16_NE;
-}
-
-FileWriter flac_plugin =
-{
- .init = NULL,
- .configure = NULL,
- .open = flac_open,
- .write = flac_write,
- .close = flac_close,
- .format_required = flac_format_required,
-};
-
-#endif
diff --git a/src/filewriter/flac.cc b/src/filewriter/flac.cc
new file mode 100644
index 000000000000..8ea22f4aaad4
--- /dev/null
+++ b/src/filewriter/flac.cc
@@ -0,0 +1,206 @@
+/* FileWriter FLAC Plugin
+ * Copyright (c) 2007 William Pitcock <nenolod at sacredspiral.co.uk>
+ *
+ * Partially derived from Og(g)re - Ogg-Output-Plugin:
+ * Copyright (c) 2002 Lars Siebold <khandha5 at gmx.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "plugins.h"
+
+#ifdef FILEWRITER_FLAC
+
+#include <FLAC/all.h>
+
+#include <libaudcore/audstrings.h>
+
+static int channels;
+static FLAC__StreamEncoder *flac_encoder;
+static FLAC__StreamMetadata *flac_metadata;
+
+static FLAC__StreamEncoderWriteStatus flac_write_cb(const FLAC__StreamEncoder *encoder,
+ const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void * data)
+{
+ VFSFile *file = (VFSFile *) data;
+
+ if (file->fwrite (buffer, 1, bytes) != (int64_t) bytes)
+ return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
+
+ return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
+}
+
+static FLAC__StreamEncoderSeekStatus flac_seek_cb(const FLAC__StreamEncoder *encoder,
+ FLAC__uint64 absolute_byte_offset, void * data)
+{
+ VFSFile *file = (VFSFile *) data;
+
+ if (file->fseek (absolute_byte_offset, VFS_SEEK_SET) < 0)
+ return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;
+
+ return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
+}
+
+static FLAC__StreamEncoderTellStatus flac_tell_cb(const FLAC__StreamEncoder *encoder,
+ FLAC__uint64 *absolute_byte_offset, void * data)
+{
+ VFSFile *file = (VFSFile *) data;
+
+ *absolute_byte_offset = file->ftell ();
+
+ return FLAC__STREAM_ENCODER_TELL_STATUS_OK;
+}
+
+static void insert_vorbis_comment (FLAC__StreamMetadata * meta,
+ const char * name, const Tuple & tuple, Tuple::Field field)
+{
+ Tuple::ValueType type = Tuple::field_get_type (field);
+ if (tuple.get_value_type (field) != type)
+ return;
+
+ StringBuf temp;
+
+ switch (type)
+ {
+ case Tuple::Int:
+ {
+ int ival = tuple.get_int (field);
+ temp.steal (str_printf ("%s=%d", name, ival));
+ break;
+ }
+ case Tuple::String:
+ {
+ String sval = tuple.get_str (field);
+ temp.steal (str_printf ("%s=%s", name, (const char *) sval));
+ break;
+ }
+ default:
+ return;
+ }
+
+ FLAC__StreamMetadata_VorbisComment_Entry comment;
+ comment.length = temp.len ();
+ comment.entry = (unsigned char *) (char *) temp;
+
+ FLAC__metadata_object_vorbiscomment_insert_comment (meta,
+ meta->data.vorbis_comment.num_comments, comment, true);
+}
+
+static bool flac_open (VFSFile & file, const format_info & info, const Tuple & tuple)
+{
+ flac_encoder = FLAC__stream_encoder_new();
+
+ FLAC__stream_encoder_set_channels(flac_encoder, info.channels);
+ FLAC__stream_encoder_set_sample_rate(flac_encoder, info.frequency);
+
+ flac_metadata = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
+
+ insert_vorbis_comment (flac_metadata, "TITLE", tuple, Tuple::Title);
+ insert_vorbis_comment (flac_metadata, "ARTIST", tuple, Tuple::Artist);
+ insert_vorbis_comment (flac_metadata, "ALBUM", tuple, Tuple::Album);
+ insert_vorbis_comment (flac_metadata, "GENRE", tuple, Tuple::Genre);
+ insert_vorbis_comment (flac_metadata, "COMMENT", tuple, Tuple::Comment);
+ insert_vorbis_comment (flac_metadata, "DATE", tuple, Tuple::Date);
+ insert_vorbis_comment (flac_metadata, "YEAR", tuple, Tuple::Year);
+ insert_vorbis_comment (flac_metadata, "TRACKNUMBER", tuple, Tuple::Track);
+
+ FLAC__stream_encoder_set_metadata(flac_encoder, &flac_metadata, 1);
+
+ FLAC__stream_encoder_init_stream(flac_encoder, flac_write_cb, flac_seek_cb,
+ flac_tell_cb, nullptr, &file);
+
+ channels = info.channels;
+ return true;
+}
+
+static void flac_write (VFSFile & file, const void * data, int length)
+{
+#if 1
+ FLAC__int32 *encbuffer[2];
+ int16_t *tmpdata = (int16_t *) data;
+ int i;
+
+ encbuffer[0] = new FLAC__int32[length / channels];
+ encbuffer[1] = new FLAC__int32[length / channels];
+
+ if (channels == 1)
+ {
+ for (i = 0; i < (length / 2); i++)
+ {
+ encbuffer[0][i] = tmpdata[i];
+ encbuffer[1][i] = tmpdata[i];
+ }
+ }
+ else
+ {
+ for (i = 0; i < (length / 4); i++)
+ {
+ encbuffer[0][i] = tmpdata[2 * i];
+ encbuffer[1][i] = tmpdata[2 * i + 1];
+ }
+ }
+
+ FLAC__stream_encoder_process(flac_encoder, (const FLAC__int32 **)encbuffer, length / (channels * 2));
+
+ delete[] encbuffer[0];
+ delete[] encbuffer[1];
+#else
+ FLAC__int32 *encbuffer;
+ int16_t *tmpdata = (int16_t *) data;
+ int i;
+
+ encbuffer = new FLAC__int32[length];
+
+ for (i=0; i < length; i++) {
+ encbuffer[i] = tmpdata[i];
+ }
+
+ FLAC__stream_encoder_process_interleaved(flac_encoder, encbuffer, length);
+
+ delete[] encbuffer;
+#endif
+}
+
+static void flac_close (VFSFile & file)
+{
+ if (flac_encoder)
+ {
+ FLAC__stream_encoder_finish(flac_encoder);
+ FLAC__stream_encoder_delete(flac_encoder);
+ flac_encoder = nullptr;
+ }
+
+ if (flac_metadata)
+ {
+ FLAC__metadata_object_delete(flac_metadata);
+ flac_metadata = nullptr;
+ }
+}
+
+static int flac_format_required (int fmt)
+{
+ return FMT_S16_NE;
+}
+
+FileWriterImpl flac_plugin = {
+ nullptr, // init
+ nullptr, // configure
+ flac_open,
+ flac_write,
+ flac_close,
+ flac_format_required,
+};
+
+#endif
diff --git a/src/filewriter/mp3.c b/src/filewriter/mp3.c
deleted file mode 100644
index a6365d046b97..000000000000
--- a/src/filewriter/mp3.c
+++ /dev/null
@@ -1,1238 +0,0 @@
-/* FileWriter-Plugin
- * (C) copyright 2007 merging of Disk Writer and Out-Lame by Michael Färber
- *
- * Original Out-Lame-Plugin:
- * (C) copyright 2002 Lars Siebold <khandha5 at gmx.net>
- * (C) copyright 2006-2007 porting to audacious by Yoshiki Yazawa <yaz at cc.rim.or.jp>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/* #define AUD_DEBUG 1 */
-
-#include "plugins.h"
-
-#ifdef FILEWRITER_MP3
-
-#include <lame/lame.h>
-
-#include <audacious/debug.h>
-#include <audacious/misc.h>
-#include <libaudcore/audstrings.h>
-
-#define MODES 4
-enum {MODE_AUTO = 4, MODE_JOINT = 1, MODE_STEREO = 0, MODE_MONO = 3};
-static const gint modes[MODES] = {MODE_AUTO, MODE_JOINT, MODE_STEREO, MODE_MONO};
-static const gchar * const mode_names[MODES] = {N_("Auto"), N_("Joint Stereo"),
- N_("Stereo"), N_("Mono")};
-
-static gint (*write_output)(void *ptr, gint length);
-
-static GtkWidget *configure_win = NULL;
-static GtkWidget *alg_quality_spin;
-static GtkWidget *alg_quality_hbox;
-static GtkAdjustment * alg_quality_adj;
-static GtkWidget *vbox, *notebook;
-static GtkWidget *quality_vbox, *quality_hbox1, *alg_quality_frame;
-static GtkWidget *enc_quality_frame, *enc_quality_label1, *enc_quality_label2;
-static GtkWidget * enc_radio1, * enc_radio2;
-static GtkWidget *compression_spin;
-static GtkAdjustment * compression_adj;
-static GtkWidget * mode_hbox, * mode_frame;
-static GtkWidget * samplerate_hbox, * samplerate_label, * samplerate_frame;
-static GtkWidget *misc_frame, *misc_vbox, *enforce_iso_toggle,
- *error_protection_toggle;
-static GtkWidget *vbr_vbox, *vbr_toggle, *vbr_options_vbox, *vbr_type_frame,
- *vbr_type_hbox, *vbr_type_radio1, *vbr_type_radio2;
-static GtkWidget * abr_frame, * abr_hbox, * abr_label;
-static GtkWidget *vbr_frame, *vbr_options_vbox2;
-static GtkWidget * vbr_options_hbox1, * vbr_min_label;
-static GtkWidget * vbr_options_hbox2, * vbr_max_label, * enforce_min_toggle;
-static GtkWidget *vbr_options_hbox3, *vbr_quality_spin, *vbr_quality_label;
-static GtkAdjustment * vbr_quality_adj;
-static GtkWidget *xing_header_toggle;
-static GtkWidget *tags_vbox, *tags_frames_frame, *tags_frames_hbox,
- *tags_copyright_toggle, *tags_original_toggle;
-static GtkWidget *tags_id3_frame, *tags_id3_vbox, *tags_id3_hbox,
- *tags_force_id3v2_toggle, *tags_only_v1_toggle, *tags_only_v2_toggle;
-
-static GtkWidget *enc_quality_vbox, *hbox1, *hbox2;
-
-static unsigned long numsamples = 0;
-static int inside;
-
-static gint available_samplerates[] =
-{ 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 } ;
-
-static gint available_bitrates[] =
-{ 8, 16, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } ;
-
-typedef struct {
- gchar *track_name;
- gchar *album_name;
- gchar *performer;
- gchar *genre;
- gchar *year;
- gchar *track_number;
-} lameid3_t;
-
-static lameid3_t lameid3;
-
-static lame_global_flags *gfp;
-static unsigned char encbuffer[LAME_MAXMP3BUFFER];
-static int id3v2_size;
-
-static guchar * write_buffer;
-static gint write_buffer_size;
-
-static void free_lameid3(lameid3_t *p)
-{
- str_unref (p->track_name);
- str_unref (p->album_name);
- str_unref (p->performer);
- str_unref (p->genre);
- str_unref (p->year);
- str_unref (p->track_number);
-
- p->track_name = NULL;
- p->album_name = NULL;
- p->performer = NULL;
- p->genre = NULL;
- p->year = NULL;
- p->track_number = NULL;
-}
-
-static void lame_debugf(const char *format, va_list ap)
-{
- (void) vfprintf(stdout, format, ap);
-}
-
-static const gchar * const mp3_defaults[] = {
- "vbr_on", "0",
- "vbr_type", "0",
- "vbr_min_val", "32",
- "vbr_max_val", "320",
- "enforce_min_val", "0",
- "vbr_quality_val", "4",
- "abr_val", "128",
- "toggle_xing_val", "1",
- "mark_original_val", "1",
- "mark_copyright_val", "0",
- "force_v2_val", "0",
- "only_v1_val", "0",
- "only_v2_val", "0",
- "algo_quality_val", "5",
- "out_samplerate_val", "0",
- "bitrate_val", "128",
- "compression_val", "11",
- "enc_toggle_val", "0",
- "audio_mode_val", "4", /* MODE_AUTO */
- "enforce_iso_val", "0",
- "error_protect_val", "0",
- NULL};
-
-static gint vbr_on, vbr_type, vbr_min_val, vbr_max_val, enforce_min_val,
- vbr_quality_val, abr_val, toggle_xing_val, mark_original_val,
- mark_copyright_val, force_v2_val, only_v1_val, only_v2_val, algo_quality_val,
- out_samplerate_val, bitrate_val;
-static gfloat compression_val;
-static gint enc_toggle_val, audio_mode_val, enforce_iso_val, error_protect_val;
-
-static void mp3_init(write_output_callback write_output_func)
-{
- aud_config_set_defaults ("filewriter_mp3", mp3_defaults);
-
- vbr_on = aud_get_int ("filewriter_mp3", "vbr_on");
- vbr_type = aud_get_int ("filewriter_mp3", "vbr_type");
- vbr_min_val = aud_get_int ("filewriter_mp3", "vbr_min_val");
- vbr_max_val = aud_get_int ("filewriter_mp3", "vbr_max_val");
- enforce_min_val = aud_get_int ("filewriter_mp3", "enforce_min_val");
- vbr_quality_val = aud_get_int ("filewriter_mp3", "vbr_quality_val");
- abr_val = aud_get_int ("filewriter_mp3", "abr_val");
- toggle_xing_val = aud_get_int ("filewriter_mp3", "toggle_xing_val");
- mark_original_val = aud_get_int ("filewriter_mp3", "mark_original_val");
- mark_copyright_val = aud_get_int ("filewriter_mp3", "mark_copyright_val");
- force_v2_val = aud_get_int ("filewriter_mp3", "force_v2_val");
- only_v1_val = aud_get_int ("filewriter_mp3", "only_v1_val");
- only_v2_val = aud_get_int ("filewriter_mp3", "only_v2_val");
- algo_quality_val = aud_get_int ("filewriter_mp3", "algo_quality_val");
- out_samplerate_val = aud_get_int ("filewriter_mp3", "out_samplerate_val");
- bitrate_val = aud_get_int ("filewriter_mp3", "bitrate_val");
- compression_val = aud_get_double ("filewriter_mp3", "compression_val");
- enc_toggle_val = aud_get_int ("filewriter_mp3", "enc_toggle_val");
- audio_mode_val = aud_get_int ("filewriter_mp3", "audio_mode_val");
- enforce_iso_val = aud_get_int ("filewriter_mp3", "enforce_iso_val");
- error_protect_val = aud_get_int ("filewriter_mp3", "error_protect_val");
-
- if (write_output_func)
- write_output=write_output_func;
-}
-
-static gint mp3_open(void)
-{
- int imp3;
-
- gfp = lame_init();
- if (gfp == NULL)
- return 0;
-
- /* setup id3 data */
- id3tag_init(gfp);
-
- if (tuple) {
- /* XXX write UTF-8 even though libmp3lame does id3v2.3. --yaz */
- lameid3.track_name = tuple_get_str (tuple, FIELD_TITLE);
- id3tag_set_title(gfp, lameid3.track_name);
-
- lameid3.performer = tuple_get_str (tuple, FIELD_ARTIST);
- id3tag_set_artist(gfp, lameid3.performer);
-
- lameid3.album_name = tuple_get_str (tuple, FIELD_ALBUM);
- id3tag_set_album(gfp, lameid3.album_name);
-
- lameid3.genre = tuple_get_str (tuple, FIELD_GENRE);
- id3tag_set_genre(gfp, lameid3.genre);
-
- lameid3.year = int_to_str (tuple_get_int (tuple, FIELD_YEAR));
- id3tag_set_year(gfp, lameid3.year);
-
- lameid3.track_number = int_to_str (tuple_get_int (tuple, FIELD_TRACK_NUMBER));
- id3tag_set_track(gfp, lameid3.track_number);
-
- if (force_v2_val) {
- id3tag_add_v2(gfp);
- }
- if (only_v1_val) {
- id3tag_v1_only(gfp);
- }
- if (only_v2_val) {
- id3tag_v2_only(gfp);
- }
- }
-
- /* input stream description */
-
- lame_set_in_samplerate(gfp, input.frequency);
- lame_set_num_channels(gfp, input.channels);
- /* Maybe implement this? */
- /* lame_set_scale(lame_global_flags *, float); */
- lame_set_out_samplerate(gfp, out_samplerate_val);
-
- /* general control parameters */
-
- lame_set_bWriteVbrTag(gfp, toggle_xing_val);
- lame_set_quality(gfp, algo_quality_val);
- if (audio_mode_val != 4) {
- AUDDBG("set mode to %d\n", audio_mode_val);
- lame_set_mode(gfp, audio_mode_val);
- }
-
- lame_set_errorf(gfp, lame_debugf);
- lame_set_debugf(gfp, lame_debugf);
- lame_set_msgf(gfp, lame_debugf);
-
- if (enc_toggle_val == 0 && vbr_on == 0)
- lame_set_brate(gfp, bitrate_val);
- else if (vbr_on == 0)
- lame_set_compression_ratio(gfp, compression_val);
-
- /* frame params */
-
- lame_set_copyright(gfp, mark_copyright_val);
- lame_set_original(gfp, mark_original_val);
- lame_set_error_protection(gfp, error_protect_val);
- lame_set_strict_ISO(gfp, enforce_iso_val);
-
- if (vbr_on != 0) {
- if (vbr_type == 0)
- lame_set_VBR(gfp, 2);
- else
- lame_set_VBR(gfp, 3);
- lame_set_VBR_q(gfp, vbr_quality_val);
- lame_set_VBR_mean_bitrate_kbps(gfp, abr_val);
- lame_set_VBR_min_bitrate_kbps(gfp, vbr_min_val);
- lame_set_VBR_max_bitrate_kbps(gfp, vbr_max_val);
- lame_set_VBR_hard_min(gfp, enforce_min_val);
- }
-
- /* not to write id3 tag automatically. */
- lame_set_write_id3tag_automatic(gfp, 0);
-
- if (lame_init_params(gfp) == -1)
- return 0;
-
- /* write id3v2 header */
- imp3 = lame_get_id3v2_tag(gfp, encbuffer, sizeof(encbuffer));
-
- if (imp3 > 0) {
- write_output(encbuffer, imp3);
- id3v2_size = imp3;
- }
- else {
- id3v2_size = 0;
- }
-
- write_buffer = NULL;
- write_buffer_size = 0;
-
- return 1;
-}
-
-static void mp3_write(void *ptr, gint length)
-{
- gint encoded;
-
- if (write_buffer_size == 0)
- {
- write_buffer_size = 8192;
- write_buffer = g_realloc (write_buffer, write_buffer_size);
- }
-
-RETRY:
- if (input.channels == 1)
- encoded = lame_encode_buffer (gfp, ptr, ptr, length / 2, write_buffer,
- write_buffer_size);
- else
- encoded = lame_encode_buffer_interleaved (gfp, ptr, length / 4,
- write_buffer, write_buffer_size);
-
- if (encoded == -1)
- {
- write_buffer_size *= 2;
- write_buffer = g_realloc (write_buffer, write_buffer_size);
- goto RETRY;
- }
-
- if (encoded > 0)
- write_output (write_buffer, encoded);
-
- numsamples += length / (2 * input.channels);
-}
-
-static void mp3_close(void)
-{
- if (output_file) {
- int imp3, encout;
-
- /* write remaining mp3 data */
- encout = lame_encode_flush_nogap(gfp, encbuffer, LAME_MAXMP3BUFFER);
- write_output(encbuffer, encout);
-
- /* set gfp->num_samples for valid TLEN tag */
- lame_set_num_samples(gfp, numsamples);
-
- /* append v1 tag */
- imp3 = lame_get_id3v1_tag(gfp, encbuffer, sizeof(encbuffer));
- if (imp3 > 0)
- write_output(encbuffer, imp3);
-
- /* update v2 tag */
- imp3 = lame_get_id3v2_tag(gfp, encbuffer, sizeof(encbuffer));
- if (imp3 > 0) {
- if (vfs_fseek(output_file, 0, SEEK_SET) != 0) {
- AUDDBG("can't rewind\n");
- }
- else {
- write_output(encbuffer, imp3);
- }
- }
-
- /* update lame tag */
- if (id3v2_size) {
- if (vfs_fseek(output_file, id3v2_size, SEEK_SET) != 0) {
- AUDDBG("fatal error: can't update LAME-tag frame!\n");
- }
- else {
- imp3 = lame_get_lametag_frame(gfp, encbuffer, sizeof(encbuffer));
- write_output(encbuffer, imp3);
- }
- }
- }
-
- g_free (write_buffer);
-
- lame_close(gfp);
- AUDDBG("lame_close() done\n");
-
- free_lameid3(&lameid3);
- numsamples = 0;
-}
-
-/*****************/
-/* Configuration */
-/*****************/
-
-/* Various Signal-Fuctions */
-
-static void algo_qual(GtkAdjustment * adjustment, gpointer user_data)
-{
-
- algo_quality_val =
- gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON
- (alg_quality_spin));
-
-}
-
-static void samplerate_changed (GtkComboBox * combo)
-{
- gint i = gtk_combo_box_get_active (combo) - 1;
-
- if (i >= 0 && i < ARRAY_LEN (available_samplerates))
- out_samplerate_val = available_samplerates[i];
- else
- out_samplerate_val = 0;
-}
-
-static void bitrate_changed (GtkComboBox * combo)
-{
- gint i = gtk_combo_box_get_active (combo);
-
- if (i >= 0 && i < ARRAY_LEN (available_bitrates))
- bitrate_val = available_bitrates[i];
- else
- bitrate_val = 128;
-}
-
-static void compression_change(GtkAdjustment * adjustment,
- gpointer user_data)
-{
- compression_val = gtk_spin_button_get_value ((GtkSpinButton *)
- compression_spin);
-}
-
-static void encoding_toggle(GtkToggleButton * togglebutton,
- gpointer user_data)
-{
-
- enc_toggle_val = GPOINTER_TO_INT(user_data);
-
-}
-
-static void mode_changed (GtkComboBox * combo)
-{
- gint i = gtk_combo_box_get_active (combo);
-
- if (i >= 0 && i < MODES)
- audio_mode_val = modes[i];
- else
- audio_mode_val = MODE_AUTO;
-}
-
-static void toggle_enforce_iso(GtkToggleButton * togglebutton,
- gpointer user_data)
-{
-
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enforce_iso_toggle))
- == TRUE)
- enforce_iso_val = 1;
- else
- enforce_iso_val = 0;
-
-}
-
-static void toggle_error_protect(GtkToggleButton * togglebutton,
- gpointer user_data)
-{
-
- if (gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON(error_protection_toggle)) == TRUE)
- error_protect_val = 1;
- else
- error_protect_val = 0;
-
-}
-
-static void toggle_vbr(GtkToggleButton * togglebutton, gpointer user_data)
-{
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(vbr_toggle)) ==
- TRUE) {
- gtk_widget_set_sensitive(vbr_options_vbox, TRUE);
- gtk_widget_set_sensitive(enc_quality_frame, FALSE);
- vbr_on = 1;
-
- if (vbr_type == 0) {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (vbr_type_radio1), TRUE);
- gtk_widget_set_sensitive(abr_frame, FALSE);
- gtk_widget_set_sensitive(vbr_frame, TRUE);
- }
- else if (vbr_type == 1) {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (vbr_type_radio2), TRUE);
- gtk_widget_set_sensitive(abr_frame, TRUE);
- gtk_widget_set_sensitive(vbr_frame, FALSE);
- }
-
- }
- else {
- gtk_widget_set_sensitive(vbr_options_vbox, FALSE);
- gtk_widget_set_sensitive(enc_quality_frame, TRUE);
- vbr_on = 0;
- }
-}
-
-static void vbr_abr_toggle(GtkToggleButton * togglebutton,
- gpointer user_data)
-{
- if (!strcmp(user_data, "VBR")) {
- gtk_widget_set_sensitive(abr_frame, FALSE);
- gtk_widget_set_sensitive(vbr_frame, TRUE);
- vbr_type = 0;
- }
- else if (!strcmp(user_data, "ABR")) {
- gtk_widget_set_sensitive(abr_frame, TRUE);
- gtk_widget_set_sensitive(vbr_frame, FALSE);
- vbr_type = 1;
- }
-}
-
-static void vbr_min_changed (GtkComboBox * combo)
-{
- gint i = gtk_combo_box_get_active (combo);
-
- if (i >= 0 && i < ARRAY_LEN (available_bitrates))
- vbr_min_val = available_bitrates[i];
- else
- vbr_min_val = 32;
-}
-
-static void vbr_max_changed (GtkComboBox * combo)
-{
- gint i = gtk_combo_box_get_active (combo);
-
- if (i >= 0 && i < ARRAY_LEN (available_bitrates))
- vbr_max_val = available_bitrates[i];
- else
- vbr_max_val = 320;
-}
-
-static void toggle_enforce_min(GtkToggleButton * togglebutton,
- gpointer user_data)
-{
-
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enforce_min_toggle))
- == TRUE)
- enforce_min_val = 1;
- else
- enforce_min_val = 0;
-
-}
-
-static void vbr_qual(GtkAdjustment * adjustment, gpointer user_data)
-{
-
- vbr_quality_val =
- gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON
- (vbr_quality_spin));
-
-}
-
-static void abr_changed (GtkComboBox * combo)
-{
- gint i = gtk_combo_box_get_active (combo);
-
- if (i >= 0 && i < ARRAY_LEN (available_bitrates))
- abr_val = available_bitrates[i];
- else
- abr_val = 128;
-}
-
-static void toggle_xing(GtkToggleButton * togglebutton, gpointer user_data)
-{
-
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(xing_header_toggle)) == TRUE)
- toggle_xing_val = 0;
- else
- toggle_xing_val = 1;
-
-}
-
-static void toggle_original(GtkToggleButton * togglebutton,
- gpointer user_data)
-{
-
- if (gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON(tags_original_toggle)) == TRUE)
- mark_original_val = 1;
- else
- mark_original_val = 0;
-
-}
-
-static void toggle_copyright(GtkToggleButton * togglebutton,
- gpointer user_data)
-{
-
- if (gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON(tags_copyright_toggle)) == TRUE)
- mark_copyright_val = 1;
- else
- mark_copyright_val = 0;
-
-}
-
-static void force_v2_toggle(GtkToggleButton * togglebutton,
- gpointer user_data)
-{
-
- if (gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON(tags_force_id3v2_toggle)) == TRUE) {
- force_v2_val = 1;
- if (gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON(tags_only_v1_toggle)) == TRUE) {
- inside = 1;
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (tags_only_v1_toggle), FALSE);
- only_v1_val = 0;
- inside = 0;
- }
- }
- else
- force_v2_val = 0;
-
-}
-
-static void id3_only_version(GtkToggleButton * togglebutton,
- gpointer user_data)
-{
- if (!strcmp(user_data, "v1") && inside != 1) {
- if (gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON(tags_only_v1_toggle)) == TRUE)
- {
- inside = 1;
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (tags_only_v2_toggle), FALSE);
- only_v1_val = 1;
- only_v2_val = 0;
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (tags_force_id3v2_toggle), FALSE);
- inside = 0;
- }
- }
- else if (!strcmp(user_data, "v2") && inside != 1) {
- if (gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON(tags_only_v2_toggle)) == TRUE)
- {
- inside = 1;
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (tags_only_v1_toggle), FALSE);
- only_v1_val = 0;
- only_v2_val = 1;
- inside = 0;
- }
- }
-
-}
-
-
-
-/* Save Configuration */
-
-static void configure_response_cb (GtkWidget * window, int response)
-{
- if (response != GTK_RESPONSE_OK)
- {
- gtk_widget_destroy (window);
- return;
- }
-
- if (vbr_min_val > vbr_max_val)
- vbr_max_val = vbr_min_val;
-
- aud_set_int ("filewriter_mp3", "vbr_on", vbr_on);
- aud_set_int ("filewriter_mp3", "vbr_type", vbr_type);
- aud_set_int ("filewriter_mp3", "vbr_min_val", vbr_min_val);
- aud_set_int ("filewriter_mp3", "vbr_max_val", vbr_max_val);
- aud_set_int ("filewriter_mp3", "enforce_min_val", enforce_min_val);
- aud_set_int ("filewriter_mp3", "vbr_quality_val", vbr_quality_val);
- aud_set_int ("filewriter_mp3", "abr_val", abr_val);
- aud_set_int ("filewriter_mp3", "toggle_xing_val", toggle_xing_val);
- aud_set_int ("filewriter_mp3", "mark_original_val", mark_original_val);
- aud_set_int ("filewriter_mp3", "mark_copyright_val", mark_copyright_val);
- aud_set_int ("filewriter_mp3", "force_v2_val", force_v2_val);
- aud_set_int ("filewriter_mp3", "only_v1_val", only_v1_val);
- aud_set_int ("filewriter_mp3", "only_v2_val", only_v2_val);
- aud_set_int ("filewriter_mp3", "algo_quality_val", algo_quality_val);
- aud_set_int ("filewriter_mp3", "out_samplerate_val", out_samplerate_val);
- aud_set_int ("filewriter_mp3", "bitrate_val", bitrate_val);
- aud_set_double ("filewriter_mp3", "compression_val", compression_val);
- aud_set_int ("filewriter_mp3", "enc_toggle_val", enc_toggle_val);
- aud_set_int ("filewriter_mp3", "audio_mode_val", audio_mode_val);
- aud_set_int ("filewriter_mp3", "enforce_iso_val", enforce_iso_val);
- aud_set_int ("filewriter_mp3", "error_protect_val", error_protect_val);
-
- gtk_widget_destroy (window);
-}
-
-
-/************************/
-/* Configuration Widget */
-/************************/
-
-
-static void mp3_configure(void)
-{
- if (! configure_win)
- {
- configure_win = gtk_dialog_new_with_buttons (_("MP3 Configuration"),
- NULL, 0, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_OK"), GTK_RESPONSE_OK,
- NULL);
-
- g_signal_connect (configure_win, "response", (GCallback) configure_response_cb, NULL);
- g_signal_connect (configure_win, "destroy", (GCallback)
- gtk_widget_destroyed, & configure_win);
-
- vbox = gtk_dialog_get_content_area ((GtkDialog *) configure_win);
-
- notebook = gtk_notebook_new();
- gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
-
- /* Quality */
-
- quality_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(quality_vbox), 5);
-
- quality_hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_box_pack_start(GTK_BOX(quality_vbox), quality_hbox1, FALSE,
- FALSE, 0);
-
- /* Algorithm Quality */
-
- alg_quality_frame = gtk_frame_new(_("Algorithm Quality:"));
- gtk_container_set_border_width(GTK_CONTAINER(alg_quality_frame),
- 5);
- gtk_box_pack_start(GTK_BOX(quality_hbox1), alg_quality_frame,
- FALSE, FALSE, 0);
-
- alg_quality_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(alg_quality_hbox),
- 10);
- gtk_container_add(GTK_CONTAINER(alg_quality_frame),
- alg_quality_hbox);
-
- alg_quality_adj = (GtkAdjustment *) gtk_adjustment_new (5, 0, 9, 1, 1, 0);
- alg_quality_spin =
- gtk_spin_button_new(GTK_ADJUSTMENT(alg_quality_adj), 8, 0);
- gtk_box_pack_start(GTK_BOX(alg_quality_hbox), alg_quality_spin,
- TRUE, TRUE, 0);
- g_signal_connect (alg_quality_adj, "value-changed", (GCallback)
- algo_qual, NULL);
-
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(alg_quality_spin),
- algo_quality_val);
-
- /* Output Samplerate */
-
- samplerate_frame = gtk_frame_new(_("Output Samplerate:"));
- gtk_container_set_border_width(GTK_CONTAINER(samplerate_frame), 5);
- gtk_box_pack_start(GTK_BOX(quality_hbox1), samplerate_frame, FALSE,
- FALSE, 0);
-
- samplerate_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(samplerate_hbox), 10);
- gtk_container_add(GTK_CONTAINER(samplerate_frame),
- samplerate_hbox);
-
- GtkWidget * combo = gtk_combo_box_text_new ();
- gtk_combo_box_text_append_text ((GtkComboBoxText *) combo, _("Auto"));
- if (! out_samplerate_val)
- gtk_combo_box_set_active ((GtkComboBox *) combo, 0);
-
- for (int i = 0; i < ARRAY_LEN (available_samplerates); i ++)
- {
- gchar buf[10];
- str_itoa (available_samplerates[i], buf, sizeof buf);
- gtk_combo_box_text_append_text ((GtkComboBoxText *) combo, buf);
-
- if (out_samplerate_val == available_samplerates[i])
- gtk_combo_box_set_active ((GtkComboBox *) combo, 1 + i);
- }
-
- gtk_box_pack_start ((GtkBox *) samplerate_hbox, combo, FALSE, FALSE, 0);
- g_signal_connect (combo, "changed", (GCallback) samplerate_changed, NULL);
-
- samplerate_label = gtk_label_new(_("(Hz)"));
- gtk_misc_set_alignment(GTK_MISC(samplerate_label), 0, 0.5);
- gtk_box_pack_start(GTK_BOX(samplerate_hbox), samplerate_label,
- FALSE, FALSE, 0);
-
- /* Encoder Quality */
-
- enc_quality_frame = gtk_frame_new(_("Bitrate / Compression ratio:"));
- gtk_container_set_border_width(GTK_CONTAINER(enc_quality_frame),
- 5);
- gtk_box_pack_start(GTK_BOX(quality_vbox), enc_quality_frame, FALSE,
- FALSE, 0);
-
- // vbox sorrounding hbox1 and hbox2
- enc_quality_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(enc_quality_vbox), 10);
-
- // pack vbox to frame
- gtk_container_add(GTK_CONTAINER(enc_quality_frame), enc_quality_vbox);
-
- // hbox1 for bitrate
- hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_add(GTK_CONTAINER(enc_quality_vbox), hbox1);
-
- // radio 1
- enc_radio1 = gtk_radio_button_new(NULL);
- if (enc_toggle_val == 0)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enc_radio1), TRUE);
- gtk_box_pack_start(GTK_BOX(hbox1), enc_radio1, FALSE, FALSE, 0);
-
- // label 1
- enc_quality_label1 = gtk_label_new(_("Bitrate (kbps):"));
- gtk_box_pack_start(GTK_BOX(hbox1), enc_quality_label1, FALSE, FALSE, 0);
-
- // bitrate menu
-
- combo = gtk_combo_box_text_new ();
-
- for (int i = 0; i < ARRAY_LEN (available_bitrates); i ++)
- {
- gchar buf[10];
- str_itoa (available_bitrates[i], buf, sizeof buf);
- gtk_combo_box_text_append_text ((GtkComboBoxText *) combo, buf);
-
- if (bitrate_val == available_bitrates[i])
- gtk_combo_box_set_active ((GtkComboBox *) combo, i);
- }
-
- gtk_box_pack_start ((GtkBox *) hbox1, combo, FALSE, FALSE, 0);
- g_signal_connect (combo, "changed", (GCallback) bitrate_changed, NULL);
-
- // hbox2 for compression ratio
- hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_add(GTK_CONTAINER(enc_quality_vbox), hbox2);
-
- // radio 2
- enc_radio2 = gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(enc_radio1));
- if (enc_toggle_val == 1)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enc_radio2),
- TRUE);
- // pack radio 2
- gtk_box_pack_start(GTK_BOX(hbox2), enc_radio2, FALSE, FALSE, 0);
-
- // label
- enc_quality_label2 = gtk_label_new(_("Compression ratio:"));
- gtk_box_pack_start(GTK_BOX(hbox2), enc_quality_label2, FALSE, FALSE, 0);
-
- // comp-ratio spin
- compression_adj = (GtkAdjustment *) gtk_adjustment_new (11, 0, 100, 1,
- 1, 0);
- compression_spin =
- gtk_spin_button_new(GTK_ADJUSTMENT(compression_adj), 8, 0);
- gtk_box_pack_end(GTK_BOX(hbox2), compression_spin, FALSE, FALSE, 0);
-
- g_signal_connect (compression_adj, "value-changed", (GCallback)
- compression_change, NULL);
-
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(compression_spin),
- compression_val);
-
- // radio button signale connect
- g_signal_connect (enc_radio1, "toggled", (GCallback) encoding_toggle,
- GINT_TO_POINTER (0));
- g_signal_connect (enc_radio2, "toggled", (GCallback) encoding_toggle,
- GINT_TO_POINTER (1));
-
- /* Audio Mode */
-
- mode_frame = gtk_frame_new(_("Audio Mode:"));
- gtk_container_set_border_width(GTK_CONTAINER(mode_frame), 5);
- gtk_box_pack_start(GTK_BOX(quality_vbox), mode_frame, FALSE, FALSE,
- 0);
-
- mode_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
- gtk_container_set_border_width(GTK_CONTAINER(mode_hbox), 10);
- gtk_container_add(GTK_CONTAINER(mode_frame), mode_hbox);
-
- combo = gtk_combo_box_text_new ();
-
- for (int i = 0; i < MODES; i ++)
- {
- gtk_combo_box_text_append_text ((GtkComboBoxText *) combo,
- _(mode_names[i]));
-
- if (audio_mode_val == modes[i])
- gtk_combo_box_set_active ((GtkComboBox *) combo, i);
- }
-
- gtk_box_pack_start ((GtkBox *) mode_hbox, combo, FALSE, FALSE, 0);
- g_signal_connect (combo, "changed", (GCallback) mode_changed, NULL);
-
- /* Misc */
-
- misc_frame = gtk_frame_new(_("Misc:"));
- gtk_container_set_border_width(GTK_CONTAINER(misc_frame), 5);
- gtk_box_pack_start(GTK_BOX(quality_vbox), misc_frame, FALSE, FALSE,
- 0);
-
- misc_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(misc_vbox), 5);
- gtk_container_add(GTK_CONTAINER(misc_frame), misc_vbox);
-
- enforce_iso_toggle =
- gtk_check_button_new_with_label
- (_("Enforce strict ISO complience"));
- gtk_box_pack_start(GTK_BOX(misc_vbox), enforce_iso_toggle, TRUE,
- TRUE, 2);
- g_signal_connect (enforce_iso_toggle, "toggled", (GCallback)
- toggle_enforce_iso, NULL);
-
- if (enforce_iso_val == 1)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (enforce_iso_toggle), TRUE);
-
- error_protection_toggle =
- gtk_check_button_new_with_label(_("Error protection"));
- gtk_box_pack_start(GTK_BOX(misc_vbox), error_protection_toggle,
- TRUE, TRUE, 2);
- g_signal_connect (error_protection_toggle, "toggled", (GCallback)
- toggle_error_protect, NULL);
-
- if (error_protect_val == 1)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (error_protection_toggle), TRUE);
-
- /* Add the Notebook */
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook), quality_vbox,
- gtk_label_new(_("Quality")));
-
- /* VBR/ABR */
-
- vbr_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(vbr_vbox), 5);
-
- /* Toggle VBR */
-
- vbr_toggle = gtk_check_button_new_with_label(_("Enable VBR/ABR"));
- gtk_box_pack_start(GTK_BOX(vbr_vbox), vbr_toggle, FALSE, FALSE, 2);
- g_signal_connect (vbr_toggle, "toggled", (GCallback) toggle_vbr, NULL);
-
- vbr_options_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add(GTK_CONTAINER(vbr_vbox), vbr_options_vbox);
- gtk_widget_set_sensitive(vbr_options_vbox, FALSE);
-
- /* Choose VBR/ABR */
-
- vbr_type_frame = gtk_frame_new(_("Type:"));
- gtk_container_set_border_width(GTK_CONTAINER(vbr_type_frame), 5);
- gtk_box_pack_start(GTK_BOX(vbr_options_vbox), vbr_type_frame,
- FALSE, FALSE, 2);
-
- vbr_type_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(vbr_type_hbox), 5);
- gtk_container_add(GTK_CONTAINER(vbr_type_frame), vbr_type_hbox);
-
- vbr_type_radio1 = gtk_radio_button_new_with_label(NULL, "VBR");
- gtk_box_pack_start(GTK_BOX(vbr_type_hbox), vbr_type_radio1, TRUE,
- TRUE, 2);
- if (vbr_type == 0)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (vbr_type_radio1), TRUE);
-
- vbr_type_radio2 =
- gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON
- (vbr_type_radio1),
- "ABR");
- gtk_box_pack_start(GTK_BOX(vbr_type_hbox), vbr_type_radio2, TRUE,
- TRUE, 2);
- if (vbr_type == 1)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (vbr_type_radio2), TRUE);
-
- g_signal_connect (vbr_type_radio1, "toggled", (GCallback)
- vbr_abr_toggle, "VBR");
- g_signal_connect (vbr_type_radio2, "toggled", (GCallback)
- vbr_abr_toggle, "ABR");
-
- /* VBR Options */
-
- vbr_frame = gtk_frame_new(_("VBR Options:"));
- gtk_container_set_border_width(GTK_CONTAINER(vbr_frame), 5);
- gtk_box_pack_start(GTK_BOX(vbr_options_vbox), vbr_frame, FALSE,
- FALSE, 2);
-
- vbr_options_vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(vbr_options_vbox2),
- 5);
- gtk_container_add(GTK_CONTAINER(vbr_frame), vbr_options_vbox2);
-
- vbr_options_hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(vbr_options_hbox1),
- 5);
- gtk_container_add(GTK_CONTAINER(vbr_options_vbox2),
- vbr_options_hbox1);
-
- vbr_min_label = gtk_label_new(_("Minimum bitrate (kbps):"));
- gtk_misc_set_alignment(GTK_MISC(vbr_min_label), 0, 0.5);
- gtk_box_pack_start(GTK_BOX(vbr_options_hbox1), vbr_min_label, TRUE,
- TRUE, 0);
-
- combo = gtk_combo_box_text_new ();
-
- for (int i = 0; i < ARRAY_LEN (available_bitrates); i ++)
- {
- gchar buf[10];
- str_itoa (available_bitrates[i], buf, sizeof buf);
- gtk_combo_box_text_append_text ((GtkComboBoxText *) combo, buf);
-
- if (vbr_min_val == available_bitrates[i])
- gtk_combo_box_set_active ((GtkComboBox *) combo, i);
- }
-
- gtk_box_pack_start ((GtkBox *) vbr_options_hbox1, combo, FALSE, FALSE,
- 0);
- g_signal_connect (combo, "changed", (GCallback) vbr_min_changed, NULL);
-
- vbr_options_hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(vbr_options_hbox2),
- 5);
- gtk_container_add(GTK_CONTAINER(vbr_options_vbox2),
- vbr_options_hbox2);
-
- vbr_max_label = gtk_label_new(_("Maximum bitrate (kbps):"));
- gtk_misc_set_alignment(GTK_MISC(vbr_max_label), 0, 0.5);
- gtk_box_pack_start(GTK_BOX(vbr_options_hbox2), vbr_max_label, TRUE,
- TRUE, 0);
-
- combo = gtk_combo_box_text_new ();
-
- for (int i = 0; i < ARRAY_LEN (available_bitrates); i ++)
- {
- gchar buf[10];
- str_itoa (available_bitrates[i], buf, sizeof buf);
- gtk_combo_box_text_append_text ((GtkComboBoxText *) combo, buf);
-
- if (vbr_max_val == available_bitrates[i])
- gtk_combo_box_set_active ((GtkComboBox *) combo, i);
- }
-
- gtk_box_pack_start ((GtkBox *) vbr_options_hbox2, combo, FALSE, FALSE,
- 0);
- g_signal_connect (combo, "changed", (GCallback) vbr_max_changed, NULL);
-
- enforce_min_toggle =
- gtk_check_button_new_with_label
- (_("Strictly enforce minimum bitrate"));
- gtk_box_pack_start(GTK_BOX(vbr_options_vbox2), enforce_min_toggle,
- FALSE, FALSE, 2);
- g_signal_connect (enforce_min_toggle, "toggled", (GCallback)
- toggle_enforce_min, NULL);
-
- if (enforce_min_val == 1)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (enforce_min_toggle), TRUE);
-
- /* ABR Options */
-
- abr_frame = gtk_frame_new(_("ABR Options:"));
- gtk_container_set_border_width(GTK_CONTAINER(abr_frame), 5);
- gtk_box_pack_start(GTK_BOX(vbr_options_vbox), abr_frame, FALSE,
- FALSE, 2);
- gtk_widget_set_sensitive(abr_frame, FALSE);
-
- abr_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(abr_hbox), 5);
- gtk_container_add(GTK_CONTAINER(abr_frame), abr_hbox);
-
- abr_label = gtk_label_new(_("Average bitrate (kbps):"));
- gtk_misc_set_alignment(GTK_MISC(abr_label), 0, 0.5);
- gtk_box_pack_start(GTK_BOX(abr_hbox), abr_label, TRUE, TRUE, 0);
-
- combo = gtk_combo_box_text_new ();
-
- for (int i = 0; i < ARRAY_LEN (available_bitrates); i ++)
- {
- gchar buf[10];
- str_itoa (available_bitrates[i], buf, sizeof buf);
- gtk_combo_box_text_append_text ((GtkComboBoxText *) combo, buf);
-
- if (abr_val == available_bitrates[i])
- gtk_combo_box_set_active ((GtkComboBox *) combo, i);
- }
-
- gtk_box_pack_start ((GtkBox *) abr_hbox, combo, FALSE, FALSE,
- 0);
- g_signal_connect (combo, "changed", (GCallback) abr_changed, NULL);
-
- /* Quality Level */
-
- vbr_options_hbox3 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(vbr_options_hbox3),
- 5);
- gtk_container_add(GTK_CONTAINER(vbr_options_vbox),
- vbr_options_hbox3);
-
- vbr_quality_label = gtk_label_new(_("VBR quality level:"));
- gtk_misc_set_alignment(GTK_MISC(vbr_quality_label), 0, 0.5);
- gtk_box_pack_start(GTK_BOX(vbr_options_hbox3), vbr_quality_label,
- TRUE, TRUE, 0);
-
- vbr_quality_adj = (GtkAdjustment *) gtk_adjustment_new (4, 0, 9, 1, 1, 0);
- vbr_quality_spin =
- gtk_spin_button_new(GTK_ADJUSTMENT(vbr_quality_adj), 8, 0);
- gtk_box_pack_start(GTK_BOX(vbr_options_hbox3), vbr_quality_spin,
- TRUE, TRUE, 0);
- g_signal_connect (vbr_quality_adj, "value-changed", (GCallback)
- vbr_qual, NULL);
-
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(vbr_quality_spin),
- vbr_quality_val);
-
- /* Xing Header */
-
- xing_header_toggle =
- gtk_check_button_new_with_label(_("Don't write Xing VBR header"));
- gtk_box_pack_start(GTK_BOX(vbr_options_vbox), xing_header_toggle,
- FALSE, FALSE, 2);
- g_signal_connect (xing_header_toggle, "toggled", (GCallback)
- toggle_xing, NULL);
-
- if (toggle_xing_val == 0)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (xing_header_toggle), TRUE);
-
- /* Add the Notebook */
-
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbr_vbox,
- gtk_label_new(_("VBR/ABR")));
-
- /* Tags */
-
- tags_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(tags_vbox), 5);
-
- /* Frame Params */
-
- tags_frames_frame = gtk_frame_new(_("Frame parameters:"));
- gtk_container_set_border_width(GTK_CONTAINER(tags_frames_frame),
- 5);
- gtk_box_pack_start(GTK_BOX(tags_vbox), tags_frames_frame, FALSE,
- FALSE, 2);
-
- tags_frames_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(tags_frames_hbox), 5);
- gtk_container_add(GTK_CONTAINER(tags_frames_frame),
- tags_frames_hbox);
-
- tags_copyright_toggle =
- gtk_check_button_new_with_label(_("Mark as copyright"));
- gtk_box_pack_start(GTK_BOX(tags_frames_hbox),
- tags_copyright_toggle, FALSE, FALSE, 2);
- g_signal_connect (tags_copyright_toggle, "toggled", (GCallback)
- toggle_copyright, NULL);
-
- if (mark_copyright_val == 1)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (tags_copyright_toggle), TRUE);
-
- tags_original_toggle =
- gtk_check_button_new_with_label(_("Mark as original"));
- gtk_box_pack_start(GTK_BOX(tags_frames_hbox), tags_original_toggle,
- FALSE, FALSE, 2);
- g_signal_connect (tags_original_toggle, "toggled", (GCallback)
- toggle_original, NULL);
-
- if (mark_original_val == 1)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (tags_original_toggle), TRUE);
-
- /* ID3 Params */
-
- tags_id3_frame = gtk_frame_new(_("ID3 params:"));
- gtk_container_set_border_width(GTK_CONTAINER(tags_id3_frame), 5);
- gtk_box_pack_start(GTK_BOX(tags_vbox), tags_id3_frame, FALSE,
- FALSE, 2);
-
- tags_id3_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(tags_id3_vbox), 5);
- gtk_container_add(GTK_CONTAINER(tags_id3_frame), tags_id3_vbox);
-
- tags_force_id3v2_toggle =
- gtk_check_button_new_with_label
- (_("Force addition of version 2 tag"));
- gtk_box_pack_start(GTK_BOX(tags_id3_vbox), tags_force_id3v2_toggle,
- FALSE, FALSE, 2);
- g_signal_connect (tags_force_id3v2_toggle, "toggled", (GCallback)
- force_v2_toggle, NULL);
-
- tags_id3_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_add(GTK_CONTAINER(tags_id3_vbox), tags_id3_hbox);
-
- tags_only_v1_toggle =
- gtk_check_button_new_with_label(_("Only add v1 tag"));
- gtk_box_pack_start(GTK_BOX(tags_id3_hbox), tags_only_v1_toggle,
- FALSE, FALSE, 2);
- g_signal_connect (tags_only_v1_toggle, "toggled", (GCallback)
- id3_only_version, "v1");
-
- tags_only_v2_toggle =
- gtk_check_button_new_with_label(_("Only add v2 tag"));
- gtk_box_pack_start(GTK_BOX(tags_id3_hbox), tags_only_v2_toggle,
- FALSE, FALSE, 2);
- g_signal_connect (tags_only_v2_toggle, "toggled", (GCallback)
- id3_only_version, "v2");
-
- if (force_v2_val == 1)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (tags_force_id3v2_toggle), TRUE);
-
- if (only_v1_val == 1)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (tags_only_v1_toggle), TRUE);
-
- if (only_v2_val == 1)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (tags_only_v2_toggle), TRUE);
-
- /* Add the Notebook */
-
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tags_vbox,
- gtk_label_new(_("Tags")));
-
- /* Set States */
-
- if (vbr_on == 1)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vbr_toggle),
- TRUE);
- else
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vbr_toggle),
- FALSE);
-
- /* Show it! */
-
- gtk_widget_show_all(configure_win);
- }
-}
-
-static int mp3_format_required (int fmt)
-{
- return FMT_S16_NE;
-}
-
-FileWriter mp3_plugin =
-{
- .init = mp3_init,
- .configure = mp3_configure,
- .open = mp3_open,
- .write = mp3_write,
- .close = mp3_close,
- .format_required = mp3_format_required,
-};
-
-#endif
diff --git a/src/filewriter/mp3.cc b/src/filewriter/mp3.cc
new file mode 100644
index 000000000000..81f2aab589b3
--- /dev/null
+++ b/src/filewriter/mp3.cc
@@ -0,0 +1,1200 @@
+/* FileWriter-Plugin
+ * (C) copyright 2007 merging of Disk Writer and Out-Lame by Michael Färber
+ *
+ * Original Out-Lame-Plugin:
+ * (C) copyright 2002 Lars Siebold <khandha5 at gmx.net>
+ * (C) copyright 2006-2007 porting to audacious by Yoshiki Yazawa <yaz at cc.rim.or.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/* #define AUD_DEBUG 1 */
+
+#include "plugins.h"
+
+#ifdef FILEWRITER_MP3
+
+#include <string.h>
+#include <lame/lame.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+
+#define MODES 4
+enum {MODE_AUTO = 4, MODE_JOINT = 1, MODE_STEREO = 0, MODE_MONO = 3};
+static const int modes[MODES] = {MODE_AUTO, MODE_JOINT, MODE_STEREO, MODE_MONO};
+static const char * const mode_names[MODES] = {N_("Auto"), N_("Joint Stereo"),
+ N_("Stereo"), N_("Mono")};
+
+static GtkWidget *configure_win = nullptr;
+static GtkWidget *alg_quality_spin;
+static GtkWidget *alg_quality_hbox;
+static GtkAdjustment * alg_quality_adj;
+static GtkWidget *vbox, *notebook;
+static GtkWidget *quality_vbox, *quality_hbox1, *alg_quality_frame;
+static GtkWidget *enc_quality_frame, *enc_quality_label1, *enc_quality_label2;
+static GtkWidget * enc_radio1, * enc_radio2;
+static GtkWidget *compression_spin;
+static GtkAdjustment * compression_adj;
+static GtkWidget * mode_hbox, * mode_frame;
+static GtkWidget * samplerate_hbox, * samplerate_label, * samplerate_frame;
+static GtkWidget *misc_frame, *misc_vbox, *enforce_iso_toggle,
+ *error_protection_toggle;
+static GtkWidget *vbr_vbox, *vbr_toggle, *vbr_options_vbox, *vbr_type_frame,
+ *vbr_type_hbox, *vbr_type_radio1, *vbr_type_radio2;
+static GtkWidget * abr_frame, * abr_hbox, * abr_label;
+static GtkWidget *vbr_frame, *vbr_options_vbox2;
+static GtkWidget * vbr_options_hbox1, * vbr_min_label;
+static GtkWidget * vbr_options_hbox2, * vbr_max_label, * enforce_min_toggle;
+static GtkWidget *vbr_options_hbox3, *vbr_quality_spin, *vbr_quality_label;
+static GtkAdjustment * vbr_quality_adj;
+static GtkWidget *xing_header_toggle;
+static GtkWidget *tags_vbox, *tags_frames_frame, *tags_frames_hbox,
+ *tags_copyright_toggle, *tags_original_toggle;
+static GtkWidget *tags_id3_frame, *tags_id3_vbox, *tags_id3_hbox,
+ *tags_force_id3v2_toggle, *tags_only_v1_toggle, *tags_only_v2_toggle;
+
+static GtkWidget *enc_quality_vbox, *hbox1, *hbox2;
+
+static unsigned long numsamples = 0;
+static int inside;
+
+static int available_samplerates[] =
+{ 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 } ;
+
+static int available_bitrates[] =
+{ 8, 16, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } ;
+
+struct lameid3_t {
+ String track_name;
+ String album_name;
+ String performer;
+ String genre;
+ String year;
+ String track_number;
+};
+
+static lameid3_t lameid3;
+
+static lame_global_flags *gfp;
+static unsigned char encbuffer[LAME_MAXMP3BUFFER];
+static int id3v2_size;
+
+static int channels;
+static Index<unsigned char> write_buffer;
+
+static void lame_debugf(const char *format, va_list ap)
+{
+ (void) vprintf(format, ap);
+}
+
+static const char * const mp3_defaults[] = {
+ "vbr_on", "0",
+ "vbr_type", "0",
+ "vbr_min_val", "32",
+ "vbr_max_val", "320",
+ "enforce_min_val", "0",
+ "vbr_quality_val", "4",
+ "abr_val", "128",
+ "toggle_xing_val", "1",
+ "mark_original_val", "1",
+ "mark_copyright_val", "0",
+ "force_v2_val", "0",
+ "only_v1_val", "0",
+ "only_v2_val", "0",
+ "algo_quality_val", "5",
+ "out_samplerate_val", "0",
+ "bitrate_val", "128",
+ "compression_val", "11",
+ "enc_toggle_val", "0",
+ "audio_mode_val", "4", /* MODE_AUTO */
+ "enforce_iso_val", "0",
+ "error_protect_val", "0",
+ nullptr};
+
+static int vbr_on, vbr_type, vbr_min_val, vbr_max_val, enforce_min_val,
+ vbr_quality_val, abr_val, toggle_xing_val, mark_original_val,
+ mark_copyright_val, force_v2_val, only_v1_val, only_v2_val, algo_quality_val,
+ out_samplerate_val, bitrate_val;
+static float compression_val;
+static int enc_toggle_val, audio_mode_val, enforce_iso_val, error_protect_val;
+
+static void mp3_init ()
+{
+ aud_config_set_defaults ("filewriter_mp3", mp3_defaults);
+
+ vbr_on = aud_get_int ("filewriter_mp3", "vbr_on");
+ vbr_type = aud_get_int ("filewriter_mp3", "vbr_type");
+ vbr_min_val = aud_get_int ("filewriter_mp3", "vbr_min_val");
+ vbr_max_val = aud_get_int ("filewriter_mp3", "vbr_max_val");
+ enforce_min_val = aud_get_int ("filewriter_mp3", "enforce_min_val");
+ vbr_quality_val = aud_get_int ("filewriter_mp3", "vbr_quality_val");
+ abr_val = aud_get_int ("filewriter_mp3", "abr_val");
+ toggle_xing_val = aud_get_int ("filewriter_mp3", "toggle_xing_val");
+ mark_original_val = aud_get_int ("filewriter_mp3", "mark_original_val");
+ mark_copyright_val = aud_get_int ("filewriter_mp3", "mark_copyright_val");
+ force_v2_val = aud_get_int ("filewriter_mp3", "force_v2_val");
+ only_v1_val = aud_get_int ("filewriter_mp3", "only_v1_val");
+ only_v2_val = aud_get_int ("filewriter_mp3", "only_v2_val");
+ algo_quality_val = aud_get_int ("filewriter_mp3", "algo_quality_val");
+ out_samplerate_val = aud_get_int ("filewriter_mp3", "out_samplerate_val");
+ bitrate_val = aud_get_int ("filewriter_mp3", "bitrate_val");
+ compression_val = aud_get_double ("filewriter_mp3", "compression_val");
+ enc_toggle_val = aud_get_int ("filewriter_mp3", "enc_toggle_val");
+ audio_mode_val = aud_get_int ("filewriter_mp3", "audio_mode_val");
+ enforce_iso_val = aud_get_int ("filewriter_mp3", "enforce_iso_val");
+ error_protect_val = aud_get_int ("filewriter_mp3", "error_protect_val");
+}
+
+static bool mp3_open (VFSFile & file, const format_info & info, const Tuple & tuple)
+{
+ int imp3;
+
+ gfp = lame_init();
+ if (gfp == nullptr)
+ return false;
+
+ /* setup id3 data */
+ id3tag_init(gfp);
+
+ /* XXX write UTF-8 even though libmp3lame does id3v2.3. --yaz */
+ lameid3.track_name = tuple.get_str (Tuple::Title);
+ id3tag_set_title(gfp, lameid3.track_name);
+
+ lameid3.performer = tuple.get_str (Tuple::Artist);
+ id3tag_set_artist(gfp, lameid3.performer);
+
+ lameid3.album_name = tuple.get_str (Tuple::Album);
+ id3tag_set_album(gfp, lameid3.album_name);
+
+ lameid3.genre = tuple.get_str (Tuple::Genre);
+ id3tag_set_genre(gfp, lameid3.genre);
+
+ lameid3.year = String (int_to_str (tuple.get_int (Tuple::Year)));
+ id3tag_set_year(gfp, lameid3.year);
+
+ lameid3.track_number = String (int_to_str (tuple.get_int (Tuple::Track)));
+ id3tag_set_track(gfp, lameid3.track_number);
+
+ if (force_v2_val)
+ id3tag_add_v2(gfp);
+ if (only_v1_val)
+ id3tag_v1_only(gfp);
+ if (only_v2_val)
+ id3tag_v2_only(gfp);
+
+ /* input stream description */
+
+ lame_set_in_samplerate(gfp, info.frequency);
+ lame_set_num_channels(gfp, info.channels);
+ /* Maybe implement this? */
+ /* lame_set_scale(lame_global_flags *, float); */
+ lame_set_out_samplerate(gfp, out_samplerate_val);
+
+ /* general control parameters */
+
+ lame_set_bWriteVbrTag(gfp, toggle_xing_val);
+ lame_set_quality(gfp, algo_quality_val);
+ if (audio_mode_val != 4) {
+ AUDDBG("set mode to %d\n", audio_mode_val);
+ lame_set_mode(gfp, (MPEG_mode) audio_mode_val);
+ }
+
+ lame_set_errorf(gfp, lame_debugf);
+ lame_set_debugf(gfp, lame_debugf);
+ lame_set_msgf(gfp, lame_debugf);
+
+ if (enc_toggle_val == 0 && vbr_on == 0)
+ lame_set_brate(gfp, bitrate_val);
+ else if (vbr_on == 0)
+ lame_set_compression_ratio(gfp, compression_val);
+
+ /* frame params */
+
+ lame_set_copyright(gfp, mark_copyright_val);
+ lame_set_original(gfp, mark_original_val);
+ lame_set_error_protection(gfp, error_protect_val);
+ lame_set_strict_ISO(gfp, enforce_iso_val);
+
+ if (vbr_on != 0) {
+ if (vbr_type == 0)
+ lame_set_VBR(gfp, (vbr_mode) 2);
+ else
+ lame_set_VBR(gfp, (vbr_mode) 3);
+ lame_set_VBR_q(gfp, vbr_quality_val);
+ lame_set_VBR_mean_bitrate_kbps(gfp, abr_val);
+ lame_set_VBR_min_bitrate_kbps(gfp, vbr_min_val);
+ lame_set_VBR_max_bitrate_kbps(gfp, vbr_max_val);
+ lame_set_VBR_hard_min(gfp, enforce_min_val);
+ }
+
+ /* not to write id3 tag automatically. */
+ lame_set_write_id3tag_automatic(gfp, 0);
+
+ if (lame_init_params(gfp) == -1)
+ return false;
+
+ /* write id3v2 header */
+ imp3 = lame_get_id3v2_tag(gfp, encbuffer, sizeof(encbuffer));
+
+ if (imp3 > 0) {
+ if (file.fwrite (encbuffer, 1, imp3) != imp3)
+ AUDERR ("write error\n");
+ id3v2_size = imp3;
+ }
+ else {
+ id3v2_size = 0;
+ }
+
+ channels = info.channels;
+ return true;
+}
+
+static void mp3_write (VFSFile & file, const void * data, int length)
+{
+ int encoded;
+
+ if (! write_buffer.len ())
+ write_buffer.resize (8192);
+
+ while (1)
+ {
+ if (channels == 1)
+ encoded = lame_encode_buffer (gfp, (int16_t *) data, (int16_t *) data,
+ length / 2, write_buffer.begin (), write_buffer.len ());
+ else
+ encoded = lame_encode_buffer_interleaved (gfp, (int16_t *) data,
+ length / 4, write_buffer.begin (), write_buffer.len ());
+
+ if (encoded != -1)
+ break;
+
+ write_buffer.resize (write_buffer.len () * 2);
+ }
+
+ if (encoded > 0 && file.fwrite (write_buffer.begin (), 1, encoded) != encoded)
+ AUDERR ("write error\n");
+
+ numsamples += length / (2 * channels);
+}
+
+static void mp3_close (VFSFile & file)
+{
+ int imp3, encout;
+
+ /* write remaining mp3 data */
+ encout = lame_encode_flush_nogap(gfp, encbuffer, LAME_MAXMP3BUFFER);
+ if (file.fwrite (encbuffer, 1, encout) != encout)
+ AUDERR ("write error\n");
+
+ /* set gfp->num_samples for valid TLEN tag */
+ lame_set_num_samples(gfp, numsamples);
+
+ /* append v1 tag */
+ imp3 = lame_get_id3v1_tag(gfp, encbuffer, sizeof(encbuffer));
+ if (imp3 > 0 && file.fwrite (encbuffer, 1, imp3) != imp3)
+ AUDERR ("write error\n");
+
+ /* update v2 tag */
+ imp3 = lame_get_id3v2_tag(gfp, encbuffer, sizeof(encbuffer));
+ if (imp3 > 0) {
+ if (file.fseek (0, VFS_SEEK_SET) != 0)
+ AUDERR ("seek error\n");
+ else if (file.fwrite (encbuffer, 1, imp3) != imp3)
+ AUDERR ("write error\n");
+ }
+
+ /* update lame tag */
+ if (id3v2_size) {
+ if (file.fseek (id3v2_size, VFS_SEEK_SET) != 0)
+ AUDERR ("seek error\n");
+ else {
+ imp3 = lame_get_lametag_frame(gfp, encbuffer, sizeof(encbuffer));
+ if (file.fwrite (encbuffer, 1, imp3) != imp3)
+ AUDERR ("write error\n");
+ }
+ }
+
+ write_buffer.clear ();
+
+ lame_close(gfp);
+ AUDDBG("lame_close() done\n");
+
+ lameid3 = lameid3_t ();
+ numsamples = 0;
+}
+
+/*****************/
+/* Configuration */
+/*****************/
+
+/* Various Signal-Fuctions */
+
+static void algo_qual(GtkAdjustment * adjustment, void * user_data)
+{
+
+ algo_quality_val =
+ gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON
+ (alg_quality_spin));
+
+}
+
+static void samplerate_changed (GtkComboBox * combo)
+{
+ int i = gtk_combo_box_get_active (combo) - 1;
+
+ if (i >= 0 && i < aud::n_elems (available_samplerates))
+ out_samplerate_val = available_samplerates[i];
+ else
+ out_samplerate_val = 0;
+}
+
+static void bitrate_changed (GtkComboBox * combo)
+{
+ int i = gtk_combo_box_get_active (combo);
+
+ if (i >= 0 && i < aud::n_elems (available_bitrates))
+ bitrate_val = available_bitrates[i];
+ else
+ bitrate_val = 128;
+}
+
+static void compression_change(GtkAdjustment * adjustment,
+ void * user_data)
+{
+ compression_val = gtk_spin_button_get_value ((GtkSpinButton *)
+ compression_spin);
+}
+
+static void encoding_toggle(GtkToggleButton * togglebutton,
+ void * user_data)
+{
+
+ enc_toggle_val = GPOINTER_TO_INT(user_data);
+
+}
+
+static void mode_changed (GtkComboBox * combo)
+{
+ int i = gtk_combo_box_get_active (combo);
+
+ if (i >= 0 && i < MODES)
+ audio_mode_val = modes[i];
+ else
+ audio_mode_val = MODE_AUTO;
+}
+
+static void toggle_enforce_iso(GtkToggleButton * togglebutton,
+ void * user_data)
+{
+
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enforce_iso_toggle))
+ == TRUE)
+ enforce_iso_val = 1;
+ else
+ enforce_iso_val = 0;
+
+}
+
+static void toggle_error_protect(GtkToggleButton * togglebutton,
+ void * user_data)
+{
+
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(error_protection_toggle)) == TRUE)
+ error_protect_val = 1;
+ else
+ error_protect_val = 0;
+
+}
+
+static void toggle_vbr(GtkToggleButton * togglebutton, void * user_data)
+{
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(vbr_toggle)) ==
+ TRUE) {
+ gtk_widget_set_sensitive(vbr_options_vbox, TRUE);
+ gtk_widget_set_sensitive(enc_quality_frame, FALSE);
+ vbr_on = 1;
+
+ if (vbr_type == 0) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (vbr_type_radio1), TRUE);
+ gtk_widget_set_sensitive(abr_frame, FALSE);
+ gtk_widget_set_sensitive(vbr_frame, TRUE);
+ }
+ else if (vbr_type == 1) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (vbr_type_radio2), TRUE);
+ gtk_widget_set_sensitive(abr_frame, TRUE);
+ gtk_widget_set_sensitive(vbr_frame, FALSE);
+ }
+
+ }
+ else {
+ gtk_widget_set_sensitive(vbr_options_vbox, FALSE);
+ gtk_widget_set_sensitive(enc_quality_frame, TRUE);
+ vbr_on = 0;
+ }
+}
+
+static void vbr_abr_toggle(GtkToggleButton * togglebutton,
+ void * user_data)
+{
+ if (!strcmp((char *) user_data, "VBR")) {
+ gtk_widget_set_sensitive(abr_frame, FALSE);
+ gtk_widget_set_sensitive(vbr_frame, TRUE);
+ vbr_type = 0;
+ }
+ else if (!strcmp((char *) user_data, "ABR")) {
+ gtk_widget_set_sensitive(abr_frame, TRUE);
+ gtk_widget_set_sensitive(vbr_frame, FALSE);
+ vbr_type = 1;
+ }
+}
+
+static void vbr_min_changed (GtkComboBox * combo)
+{
+ int i = gtk_combo_box_get_active (combo);
+
+ if (i >= 0 && i < aud::n_elems (available_bitrates))
+ vbr_min_val = available_bitrates[i];
+ else
+ vbr_min_val = 32;
+}
+
+static void vbr_max_changed (GtkComboBox * combo)
+{
+ int i = gtk_combo_box_get_active (combo);
+
+ if (i >= 0 && i < aud::n_elems (available_bitrates))
+ vbr_max_val = available_bitrates[i];
+ else
+ vbr_max_val = 320;
+}
+
+static void toggle_enforce_min(GtkToggleButton * togglebutton,
+ void * user_data)
+{
+
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enforce_min_toggle))
+ == TRUE)
+ enforce_min_val = 1;
+ else
+ enforce_min_val = 0;
+
+}
+
+static void vbr_qual(GtkAdjustment * adjustment, void * user_data)
+{
+
+ vbr_quality_val =
+ gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON
+ (vbr_quality_spin));
+
+}
+
+static void abr_changed (GtkComboBox * combo)
+{
+ int i = gtk_combo_box_get_active (combo);
+
+ if (i >= 0 && i < aud::n_elems (available_bitrates))
+ abr_val = available_bitrates[i];
+ else
+ abr_val = 128;
+}
+
+static void toggle_xing(GtkToggleButton * togglebutton, void * user_data)
+{
+
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(xing_header_toggle)) == TRUE)
+ toggle_xing_val = 0;
+ else
+ toggle_xing_val = 1;
+
+}
+
+static void toggle_original(GtkToggleButton * togglebutton,
+ void * user_data)
+{
+
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(tags_original_toggle)) == TRUE)
+ mark_original_val = 1;
+ else
+ mark_original_val = 0;
+
+}
+
+static void toggle_copyright(GtkToggleButton * togglebutton,
+ void * user_data)
+{
+
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(tags_copyright_toggle)) == TRUE)
+ mark_copyright_val = 1;
+ else
+ mark_copyright_val = 0;
+
+}
+
+static void force_v2_toggle(GtkToggleButton * togglebutton,
+ void * user_data)
+{
+
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(tags_force_id3v2_toggle)) == TRUE) {
+ force_v2_val = 1;
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(tags_only_v1_toggle)) == TRUE) {
+ inside = 1;
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (tags_only_v1_toggle), FALSE);
+ only_v1_val = 0;
+ inside = 0;
+ }
+ }
+ else
+ force_v2_val = 0;
+
+}
+
+static void id3_only_version(GtkToggleButton * togglebutton,
+ void * user_data)
+{
+ if (!strcmp((char *) user_data, "v1") && inside != 1) {
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(tags_only_v1_toggle)) == TRUE)
+ {
+ inside = 1;
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (tags_only_v2_toggle), FALSE);
+ only_v1_val = 1;
+ only_v2_val = 0;
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (tags_force_id3v2_toggle), FALSE);
+ inside = 0;
+ }
+ }
+ else if (!strcmp((char *) user_data, "v2") && inside != 1) {
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(tags_only_v2_toggle)) == TRUE)
+ {
+ inside = 1;
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (tags_only_v1_toggle), FALSE);
+ only_v1_val = 0;
+ only_v2_val = 1;
+ inside = 0;
+ }
+ }
+
+}
+
+
+
+/* Save Configuration */
+
+static void configure_response_cb (GtkWidget * window, int response)
+{
+ if (response != GTK_RESPONSE_OK)
+ {
+ gtk_widget_destroy (window);
+ return;
+ }
+
+ if (vbr_min_val > vbr_max_val)
+ vbr_max_val = vbr_min_val;
+
+ aud_set_int ("filewriter_mp3", "vbr_on", vbr_on);
+ aud_set_int ("filewriter_mp3", "vbr_type", vbr_type);
+ aud_set_int ("filewriter_mp3", "vbr_min_val", vbr_min_val);
+ aud_set_int ("filewriter_mp3", "vbr_max_val", vbr_max_val);
+ aud_set_int ("filewriter_mp3", "enforce_min_val", enforce_min_val);
+ aud_set_int ("filewriter_mp3", "vbr_quality_val", vbr_quality_val);
+ aud_set_int ("filewriter_mp3", "abr_val", abr_val);
+ aud_set_int ("filewriter_mp3", "toggle_xing_val", toggle_xing_val);
+ aud_set_int ("filewriter_mp3", "mark_original_val", mark_original_val);
+ aud_set_int ("filewriter_mp3", "mark_copyright_val", mark_copyright_val);
+ aud_set_int ("filewriter_mp3", "force_v2_val", force_v2_val);
+ aud_set_int ("filewriter_mp3", "only_v1_val", only_v1_val);
+ aud_set_int ("filewriter_mp3", "only_v2_val", only_v2_val);
+ aud_set_int ("filewriter_mp3", "algo_quality_val", algo_quality_val);
+ aud_set_int ("filewriter_mp3", "out_samplerate_val", out_samplerate_val);
+ aud_set_int ("filewriter_mp3", "bitrate_val", bitrate_val);
+ aud_set_double ("filewriter_mp3", "compression_val", compression_val);
+ aud_set_int ("filewriter_mp3", "enc_toggle_val", enc_toggle_val);
+ aud_set_int ("filewriter_mp3", "audio_mode_val", audio_mode_val);
+ aud_set_int ("filewriter_mp3", "enforce_iso_val", enforce_iso_val);
+ aud_set_int ("filewriter_mp3", "error_protect_val", error_protect_val);
+
+ gtk_widget_destroy (window);
+}
+
+
+/************************/
+/* Configuration Widget */
+/************************/
+
+
+static void mp3_configure(void)
+{
+ if (! configure_win)
+ {
+ configure_win = gtk_dialog_new_with_buttons (_("MP3 Configuration"),
+ nullptr, (GtkDialogFlags) 0, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_OK"),
+ GTK_RESPONSE_OK, nullptr);
+
+ g_signal_connect (configure_win, "response", (GCallback) configure_response_cb, nullptr);
+ g_signal_connect (configure_win, "destroy", (GCallback)
+ gtk_widget_destroyed, & configure_win);
+
+ vbox = gtk_dialog_get_content_area ((GtkDialog *) configure_win);
+
+ notebook = gtk_notebook_new();
+ gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
+
+ /* Quality */
+
+ quality_vbox = gtk_vbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(quality_vbox), 5);
+
+ quality_hbox1 = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(quality_vbox), quality_hbox1, FALSE,
+ FALSE, 0);
+
+ /* Algorithm Quality */
+
+ alg_quality_frame = gtk_frame_new(_("Algorithm Quality:"));
+ gtk_container_set_border_width(GTK_CONTAINER(alg_quality_frame),
+ 5);
+ gtk_box_pack_start(GTK_BOX(quality_hbox1), alg_quality_frame,
+ FALSE, FALSE, 0);
+
+ alg_quality_hbox = gtk_hbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(alg_quality_hbox),
+ 10);
+ gtk_container_add(GTK_CONTAINER(alg_quality_frame),
+ alg_quality_hbox);
+
+ alg_quality_adj = (GtkAdjustment *) gtk_adjustment_new (5, 0, 9, 1, 1, 0);
+ alg_quality_spin =
+ gtk_spin_button_new(GTK_ADJUSTMENT(alg_quality_adj), 8, 0);
+ gtk_box_pack_start(GTK_BOX(alg_quality_hbox), alg_quality_spin,
+ TRUE, TRUE, 0);
+ g_signal_connect (alg_quality_adj, "value-changed", (GCallback)
+ algo_qual, nullptr);
+
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(alg_quality_spin),
+ algo_quality_val);
+
+ /* Output Samplerate */
+
+ samplerate_frame = gtk_frame_new(_("Output Sample Rate:"));
+ gtk_container_set_border_width(GTK_CONTAINER(samplerate_frame), 5);
+ gtk_box_pack_start(GTK_BOX(quality_hbox1), samplerate_frame, FALSE,
+ FALSE, 0);
+
+ samplerate_hbox = gtk_hbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(samplerate_hbox), 10);
+ gtk_container_add(GTK_CONTAINER(samplerate_frame),
+ samplerate_hbox);
+
+ GtkWidget * combo = gtk_combo_box_text_new ();
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) combo, _("Auto"));
+ if (! out_samplerate_val)
+ gtk_combo_box_set_active ((GtkComboBox *) combo, 0);
+
+ for (int i = 0; i < aud::n_elems (available_samplerates); i ++)
+ {
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) combo,
+ int_to_str (available_samplerates[i]));
+
+ if (out_samplerate_val == available_samplerates[i])
+ gtk_combo_box_set_active ((GtkComboBox *) combo, 1 + i);
+ }
+
+ gtk_box_pack_start ((GtkBox *) samplerate_hbox, combo, FALSE, FALSE, 0);
+ g_signal_connect (combo, "changed", (GCallback) samplerate_changed, nullptr);
+
+ samplerate_label = gtk_label_new(_("(Hz)"));
+ gtk_misc_set_alignment(GTK_MISC(samplerate_label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(samplerate_hbox), samplerate_label,
+ FALSE, FALSE, 0);
+
+ /* Encoder Quality */
+
+ enc_quality_frame = gtk_frame_new(_("Bitrate / Compression Ratio:"));
+ gtk_container_set_border_width(GTK_CONTAINER(enc_quality_frame),
+ 5);
+ gtk_box_pack_start(GTK_BOX(quality_vbox), enc_quality_frame, FALSE,
+ FALSE, 0);
+
+ // vbox sorrounding hbox1 and hbox2
+ enc_quality_vbox = gtk_vbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(enc_quality_vbox), 10);
+
+ // pack vbox to frame
+ gtk_container_add(GTK_CONTAINER(enc_quality_frame), enc_quality_vbox);
+
+ // hbox1 for bitrate
+ hbox1 = gtk_hbox_new (FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(enc_quality_vbox), hbox1);
+
+ // radio 1
+ enc_radio1 = gtk_radio_button_new(nullptr);
+ if (enc_toggle_val == 0)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enc_radio1), TRUE);
+ gtk_box_pack_start(GTK_BOX(hbox1), enc_radio1, FALSE, FALSE, 0);
+
+ // label 1
+ enc_quality_label1 = gtk_label_new(_("Bitrate (kbps):"));
+ gtk_box_pack_start(GTK_BOX(hbox1), enc_quality_label1, FALSE, FALSE, 0);
+
+ // bitrate menu
+
+ combo = gtk_combo_box_text_new ();
+
+ for (int i = 0; i < aud::n_elems (available_bitrates); i ++)
+ {
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) combo,
+ int_to_str (available_bitrates[i]));
+
+ if (bitrate_val == available_bitrates[i])
+ gtk_combo_box_set_active ((GtkComboBox *) combo, i);
+ }
+
+ gtk_box_pack_start ((GtkBox *) hbox1, combo, FALSE, FALSE, 0);
+ g_signal_connect (combo, "changed", (GCallback) bitrate_changed, nullptr);
+
+ // hbox2 for compression ratio
+ hbox2 = gtk_hbox_new (FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(enc_quality_vbox), hbox2);
+
+ // radio 2
+ enc_radio2 = gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(enc_radio1));
+ if (enc_toggle_val == 1)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enc_radio2),
+ TRUE);
+ // pack radio 2
+ gtk_box_pack_start(GTK_BOX(hbox2), enc_radio2, FALSE, FALSE, 0);
+
+ // label
+ enc_quality_label2 = gtk_label_new(_("Compression ratio:"));
+ gtk_box_pack_start(GTK_BOX(hbox2), enc_quality_label2, FALSE, FALSE, 0);
+
+ // comp-ratio spin
+ compression_adj = (GtkAdjustment *) gtk_adjustment_new (11, 0, 100, 1,
+ 1, 0);
+ compression_spin =
+ gtk_spin_button_new(GTK_ADJUSTMENT(compression_adj), 8, 0);
+ gtk_box_pack_end(GTK_BOX(hbox2), compression_spin, FALSE, FALSE, 0);
+
+ g_signal_connect (compression_adj, "value-changed", (GCallback)
+ compression_change, nullptr);
+
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(compression_spin),
+ compression_val);
+
+ // radio button signale connect
+ g_signal_connect (enc_radio1, "toggled", (GCallback) encoding_toggle,
+ GINT_TO_POINTER (0));
+ g_signal_connect (enc_radio2, "toggled", (GCallback) encoding_toggle,
+ GINT_TO_POINTER (1));
+
+ /* Audio Mode */
+
+ mode_frame = gtk_frame_new(_("Audio Mode:"));
+ gtk_container_set_border_width(GTK_CONTAINER(mode_frame), 5);
+ gtk_box_pack_start(GTK_BOX(quality_vbox), mode_frame, FALSE, FALSE,
+ 0);
+
+ mode_hbox = gtk_hbox_new (FALSE, 10);
+ gtk_container_set_border_width(GTK_CONTAINER(mode_hbox), 10);
+ gtk_container_add(GTK_CONTAINER(mode_frame), mode_hbox);
+
+ combo = gtk_combo_box_text_new ();
+
+ for (int i = 0; i < MODES; i ++)
+ {
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) combo,
+ _(mode_names[i]));
+
+ if (audio_mode_val == modes[i])
+ gtk_combo_box_set_active ((GtkComboBox *) combo, i);
+ }
+
+ gtk_box_pack_start ((GtkBox *) mode_hbox, combo, FALSE, FALSE, 0);
+ g_signal_connect (combo, "changed", (GCallback) mode_changed, nullptr);
+
+ /* Misc */
+
+ misc_frame = gtk_frame_new(_("Miscellaneous:"));
+ gtk_container_set_border_width(GTK_CONTAINER(misc_frame), 5);
+ gtk_box_pack_start(GTK_BOX(quality_vbox), misc_frame, FALSE, FALSE,
+ 0);
+
+ misc_vbox = gtk_vbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(misc_vbox), 5);
+ gtk_container_add(GTK_CONTAINER(misc_frame), misc_vbox);
+
+ enforce_iso_toggle =
+ gtk_check_button_new_with_label
+ (_("Enforce strict ISO compliance"));
+ gtk_box_pack_start(GTK_BOX(misc_vbox), enforce_iso_toggle, TRUE,
+ TRUE, 2);
+ g_signal_connect (enforce_iso_toggle, "toggled", (GCallback)
+ toggle_enforce_iso, nullptr);
+
+ if (enforce_iso_val == 1)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (enforce_iso_toggle), TRUE);
+
+ error_protection_toggle =
+ gtk_check_button_new_with_label(_("Error protection"));
+ gtk_box_pack_start(GTK_BOX(misc_vbox), error_protection_toggle,
+ TRUE, TRUE, 2);
+ g_signal_connect (error_protection_toggle, "toggled", (GCallback)
+ toggle_error_protect, nullptr);
+
+ if (error_protect_val == 1)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (error_protection_toggle), TRUE);
+
+ /* Add the Notebook */
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook), quality_vbox,
+ gtk_label_new(_("Quality")));
+
+ /* VBR/ABR */
+
+ vbr_vbox = gtk_vbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(vbr_vbox), 5);
+
+ /* Toggle VBR */
+
+ vbr_toggle = gtk_check_button_new_with_label(_("Enable VBR/ABR"));
+ gtk_box_pack_start(GTK_BOX(vbr_vbox), vbr_toggle, FALSE, FALSE, 2);
+ g_signal_connect (vbr_toggle, "toggled", (GCallback) toggle_vbr, nullptr);
+
+ vbr_options_vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(vbr_vbox), vbr_options_vbox);
+ gtk_widget_set_sensitive(vbr_options_vbox, FALSE);
+
+ /* Choose VBR/ABR */
+
+ vbr_type_frame = gtk_frame_new(_("Type:"));
+ gtk_container_set_border_width(GTK_CONTAINER(vbr_type_frame), 5);
+ gtk_box_pack_start(GTK_BOX(vbr_options_vbox), vbr_type_frame,
+ FALSE, FALSE, 2);
+
+ vbr_type_hbox = gtk_hbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(vbr_type_hbox), 5);
+ gtk_container_add(GTK_CONTAINER(vbr_type_frame), vbr_type_hbox);
+
+ vbr_type_radio1 = gtk_radio_button_new_with_label(nullptr, "VBR");
+ gtk_box_pack_start(GTK_BOX(vbr_type_hbox), vbr_type_radio1, TRUE,
+ TRUE, 2);
+ if (vbr_type == 0)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (vbr_type_radio1), TRUE);
+
+ vbr_type_radio2 =
+ gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON
+ (vbr_type_radio1),
+ "ABR");
+ gtk_box_pack_start(GTK_BOX(vbr_type_hbox), vbr_type_radio2, TRUE,
+ TRUE, 2);
+ if (vbr_type == 1)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (vbr_type_radio2), TRUE);
+
+ g_signal_connect (vbr_type_radio1, "toggled", (GCallback)
+ vbr_abr_toggle, (void *) "VBR");
+ g_signal_connect (vbr_type_radio2, "toggled", (GCallback)
+ vbr_abr_toggle, (void *) "ABR");
+
+ /* VBR Options */
+
+ vbr_frame = gtk_frame_new(_("VBR Options:"));
+ gtk_container_set_border_width(GTK_CONTAINER(vbr_frame), 5);
+ gtk_box_pack_start(GTK_BOX(vbr_options_vbox), vbr_frame, FALSE,
+ FALSE, 2);
+
+ vbr_options_vbox2 = gtk_vbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(vbr_options_vbox2),
+ 5);
+ gtk_container_add(GTK_CONTAINER(vbr_frame), vbr_options_vbox2);
+
+ vbr_options_hbox1 = gtk_hbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(vbr_options_hbox1),
+ 5);
+ gtk_container_add(GTK_CONTAINER(vbr_options_vbox2),
+ vbr_options_hbox1);
+
+ vbr_min_label = gtk_label_new(_("Minimum bitrate (kbps):"));
+ gtk_misc_set_alignment(GTK_MISC(vbr_min_label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(vbr_options_hbox1), vbr_min_label, TRUE,
+ TRUE, 0);
+
+ combo = gtk_combo_box_text_new ();
+
+ for (int i = 0; i < aud::n_elems (available_bitrates); i ++)
+ {
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) combo,
+ int_to_str (available_bitrates[i]));
+
+ if (vbr_min_val == available_bitrates[i])
+ gtk_combo_box_set_active ((GtkComboBox *) combo, i);
+ }
+
+ gtk_box_pack_start ((GtkBox *) vbr_options_hbox1, combo, FALSE, FALSE,
+ 0);
+ g_signal_connect (combo, "changed", (GCallback) vbr_min_changed, nullptr);
+
+ vbr_options_hbox2 = gtk_hbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(vbr_options_hbox2),
+ 5);
+ gtk_container_add(GTK_CONTAINER(vbr_options_vbox2),
+ vbr_options_hbox2);
+
+ vbr_max_label = gtk_label_new(_("Maximum bitrate (kbps):"));
+ gtk_misc_set_alignment(GTK_MISC(vbr_max_label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(vbr_options_hbox2), vbr_max_label, TRUE,
+ TRUE, 0);
+
+ combo = gtk_combo_box_text_new ();
+
+ for (int i = 0; i < aud::n_elems (available_bitrates); i ++)
+ {
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) combo,
+ int_to_str (available_bitrates[i]));
+
+ if (vbr_max_val == available_bitrates[i])
+ gtk_combo_box_set_active ((GtkComboBox *) combo, i);
+ }
+
+ gtk_box_pack_start ((GtkBox *) vbr_options_hbox2, combo, FALSE, FALSE,
+ 0);
+ g_signal_connect (combo, "changed", (GCallback) vbr_max_changed, nullptr);
+
+ enforce_min_toggle =
+ gtk_check_button_new_with_label
+ (_("Strictly enforce minimum bitrate"));
+ gtk_box_pack_start(GTK_BOX(vbr_options_vbox2), enforce_min_toggle,
+ FALSE, FALSE, 2);
+ g_signal_connect (enforce_min_toggle, "toggled", (GCallback)
+ toggle_enforce_min, nullptr);
+
+ if (enforce_min_val == 1)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (enforce_min_toggle), TRUE);
+
+ /* ABR Options */
+
+ abr_frame = gtk_frame_new(_("ABR Options:"));
+ gtk_container_set_border_width(GTK_CONTAINER(abr_frame), 5);
+ gtk_box_pack_start(GTK_BOX(vbr_options_vbox), abr_frame, FALSE,
+ FALSE, 2);
+ gtk_widget_set_sensitive(abr_frame, FALSE);
+
+ abr_hbox = gtk_hbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(abr_hbox), 5);
+ gtk_container_add(GTK_CONTAINER(abr_frame), abr_hbox);
+
+ abr_label = gtk_label_new(_("Average bitrate (kbps):"));
+ gtk_misc_set_alignment(GTK_MISC(abr_label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(abr_hbox), abr_label, TRUE, TRUE, 0);
+
+ combo = gtk_combo_box_text_new ();
+
+ for (int i = 0; i < aud::n_elems (available_bitrates); i ++)
+ {
+ gtk_combo_box_text_append_text ((GtkComboBoxText *) combo,
+ int_to_str (available_bitrates[i]));
+
+ if (abr_val == available_bitrates[i])
+ gtk_combo_box_set_active ((GtkComboBox *) combo, i);
+ }
+
+ gtk_box_pack_start ((GtkBox *) abr_hbox, combo, FALSE, FALSE,
+ 0);
+ g_signal_connect (combo, "changed", (GCallback) abr_changed, nullptr);
+
+ /* Quality Level */
+
+ vbr_options_hbox3 = gtk_hbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(vbr_options_hbox3),
+ 5);
+ gtk_container_add(GTK_CONTAINER(vbr_options_vbox),
+ vbr_options_hbox3);
+
+ vbr_quality_label = gtk_label_new(_("VBR quality level:"));
+ gtk_misc_set_alignment(GTK_MISC(vbr_quality_label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(vbr_options_hbox3), vbr_quality_label,
+ TRUE, TRUE, 0);
+
+ vbr_quality_adj = (GtkAdjustment *) gtk_adjustment_new (4, 0, 9, 1, 1, 0);
+ vbr_quality_spin =
+ gtk_spin_button_new(GTK_ADJUSTMENT(vbr_quality_adj), 8, 0);
+ gtk_box_pack_start(GTK_BOX(vbr_options_hbox3), vbr_quality_spin,
+ TRUE, TRUE, 0);
+ g_signal_connect (vbr_quality_adj, "value-changed", (GCallback)
+ vbr_qual, nullptr);
+
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(vbr_quality_spin),
+ vbr_quality_val);
+
+ /* Xing Header */
+
+ xing_header_toggle =
+ gtk_check_button_new_with_label(_("Omit Xing VBR header"));
+ gtk_box_pack_start(GTK_BOX(vbr_options_vbox), xing_header_toggle,
+ FALSE, FALSE, 2);
+ g_signal_connect (xing_header_toggle, "toggled", (GCallback)
+ toggle_xing, nullptr);
+
+ if (toggle_xing_val == 0)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (xing_header_toggle), TRUE);
+
+ /* Add the Notebook */
+
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbr_vbox,
+ gtk_label_new(_("VBR/ABR")));
+
+ /* Tags */
+
+ tags_vbox = gtk_vbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(tags_vbox), 5);
+
+ /* Frame Params */
+
+ tags_frames_frame = gtk_frame_new(_("Frame Parameters:"));
+ gtk_container_set_border_width(GTK_CONTAINER(tags_frames_frame),
+ 5);
+ gtk_box_pack_start(GTK_BOX(tags_vbox), tags_frames_frame, FALSE,
+ FALSE, 2);
+
+ tags_frames_hbox = gtk_hbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(tags_frames_hbox), 5);
+ gtk_container_add(GTK_CONTAINER(tags_frames_frame),
+ tags_frames_hbox);
+
+ tags_copyright_toggle =
+ gtk_check_button_new_with_label(_("Mark as copyright"));
+ gtk_box_pack_start(GTK_BOX(tags_frames_hbox),
+ tags_copyright_toggle, FALSE, FALSE, 2);
+ g_signal_connect (tags_copyright_toggle, "toggled", (GCallback)
+ toggle_copyright, nullptr);
+
+ if (mark_copyright_val == 1)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (tags_copyright_toggle), TRUE);
+
+ tags_original_toggle =
+ gtk_check_button_new_with_label(_("Mark as original"));
+ gtk_box_pack_start(GTK_BOX(tags_frames_hbox), tags_original_toggle,
+ FALSE, FALSE, 2);
+ g_signal_connect (tags_original_toggle, "toggled", (GCallback)
+ toggle_original, nullptr);
+
+ if (mark_original_val == 1)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (tags_original_toggle), TRUE);
+
+ /* ID3 Params */
+
+ tags_id3_frame = gtk_frame_new(_("ID3 Parameters:"));
+ gtk_container_set_border_width(GTK_CONTAINER(tags_id3_frame), 5);
+ gtk_box_pack_start(GTK_BOX(tags_vbox), tags_id3_frame, FALSE,
+ FALSE, 2);
+
+ tags_id3_vbox = gtk_vbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(tags_id3_vbox), 5);
+ gtk_container_add(GTK_CONTAINER(tags_id3_frame), tags_id3_vbox);
+
+ tags_force_id3v2_toggle =
+ gtk_check_button_new_with_label
+ (_("Force addition of version 2 tag"));
+ gtk_box_pack_start(GTK_BOX(tags_id3_vbox), tags_force_id3v2_toggle,
+ FALSE, FALSE, 2);
+ g_signal_connect (tags_force_id3v2_toggle, "toggled", (GCallback)
+ force_v2_toggle, nullptr);
+
+ tags_id3_hbox = gtk_hbox_new (FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(tags_id3_vbox), tags_id3_hbox);
+
+ tags_only_v1_toggle =
+ gtk_check_button_new_with_label(_("Only add v1 tag"));
+ gtk_box_pack_start(GTK_BOX(tags_id3_hbox), tags_only_v1_toggle,
+ FALSE, FALSE, 2);
+ g_signal_connect (tags_only_v1_toggle, "toggled", (GCallback)
+ id3_only_version, (void *) "v1");
+
+ tags_only_v2_toggle =
+ gtk_check_button_new_with_label(_("Only add v2 tag"));
+ gtk_box_pack_start(GTK_BOX(tags_id3_hbox), tags_only_v2_toggle,
+ FALSE, FALSE, 2);
+ g_signal_connect (tags_only_v2_toggle, "toggled", (GCallback)
+ id3_only_version, (void *) "v2");
+
+ if (force_v2_val == 1)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (tags_force_id3v2_toggle), TRUE);
+
+ if (only_v1_val == 1)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (tags_only_v1_toggle), TRUE);
+
+ if (only_v2_val == 1)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (tags_only_v2_toggle), TRUE);
+
+ /* Add the Notebook */
+
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tags_vbox,
+ gtk_label_new(_("Tags")));
+
+ /* Set States */
+
+ if (vbr_on == 1)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vbr_toggle),
+ TRUE);
+ else
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vbr_toggle),
+ FALSE);
+
+ /* Show it! */
+
+ gtk_widget_show_all(configure_win);
+ }
+}
+
+static int mp3_format_required (int fmt)
+{
+ return FMT_S16_NE;
+}
+
+FileWriterImpl mp3_plugin = {
+ mp3_init,
+ mp3_configure,
+ mp3_open,
+ mp3_write,
+ mp3_close,
+ mp3_format_required,
+};
+
+#endif
diff --git a/src/filewriter/plugins.h b/src/filewriter/plugins.h
index fde0734af835..3293295ba278 100644
--- a/src/filewriter/plugins.h
+++ b/src/filewriter/plugins.h
@@ -25,15 +25,15 @@
#include "filewriter.h"
-extern FileWriter wav_plugin;
+extern FileWriterImpl wav_plugin;
#ifdef FILEWRITER_MP3
-extern FileWriter mp3_plugin;
+extern FileWriterImpl mp3_plugin;
#endif
#ifdef FILEWRITER_VORBIS
-extern FileWriter vorbis_plugin;
+extern FileWriterImpl vorbis_plugin;
#endif
#ifdef FILEWRITER_FLAC
-extern FileWriter flac_plugin;
+extern FileWriterImpl flac_plugin;
#endif
#endif
diff --git a/src/filewriter/vorbis.c b/src/filewriter/vorbis.c
deleted file mode 100644
index 1891fa7086aa..000000000000
--- a/src/filewriter/vorbis.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/* FileWriter Vorbis Plugin
- * Copyright (c) 2007 William Pitcock <nenolod at sacredspiral.co.uk>
- *
- * Partially derived from Og(g)re - Ogg-Output-Plugin:
- * Copyright (c) 2002 Lars Siebold <khandha5 at gmx.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "plugins.h"
-
-#ifdef FILEWRITER_VORBIS
-
-#include <vorbis/vorbisenc.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <audacious/misc.h>
-#include <libaudcore/audstrings.h>
-
-static gint (*write_output)(void *ptr, gint length);
-
-static ogg_stream_state os;
-static ogg_page og;
-static ogg_packet op;
-
-static vorbis_dsp_state vd;
-static vorbis_block vb;
-static vorbis_info vi;
-static vorbis_comment vc;
-
-static const gchar * const vorbis_defaults[] = {
- "base_quality", "0.5",
- NULL};
-
-static gdouble v_base_quality;
-
-static void vorbis_init(write_output_callback write_output_func)
-{
- aud_config_set_defaults ("filewriter_vorbis", vorbis_defaults);
-
- v_base_quality = aud_get_double ("filewriter_vorbis", "base_quality");
-
- if (write_output_func)
- write_output=write_output_func;
-}
-
-static void add_string_from_tuple (vorbis_comment * vc, const char * name,
- const Tuple * tuple, gint field)
-{
- gchar * val = tuple_get_str (tuple, field);
- if (! val)
- return;
-
- vorbis_comment_add_tag (vc, name, val);
- str_unref (val);
-}
-
-static gint vorbis_open(void)
-{
- ogg_packet header;
- ogg_packet header_comm;
- ogg_packet header_code;
-
- vorbis_init(NULL);
-
- vorbis_info_init(&vi);
- vorbis_comment_init(&vc);
-
- if (tuple)
- {
- gchar tmpstr[32];
- gint scrint;
-
- add_string_from_tuple (& vc, "title", tuple, FIELD_TITLE);
- add_string_from_tuple (& vc, "artist", tuple, FIELD_ARTIST);
- add_string_from_tuple (& vc, "album", tuple, FIELD_ALBUM);
- add_string_from_tuple (& vc, "genre", tuple, FIELD_GENRE);
- add_string_from_tuple (& vc, "date", tuple, FIELD_DATE);
- add_string_from_tuple (& vc, "comment", tuple, FIELD_COMMENT);
-
- if ((scrint = tuple_get_int(tuple, FIELD_TRACK_NUMBER)))
- {
- str_itoa (scrint, tmpstr, sizeof tmpstr);
- vorbis_comment_add_tag(&vc, "tracknumber", tmpstr);
- }
-
- if ((scrint = tuple_get_int(tuple, FIELD_YEAR)))
- {
- str_itoa (scrint, tmpstr, sizeof tmpstr);
- vorbis_comment_add_tag(&vc, "year", tmpstr);
- }
- }
-
- if (vorbis_encode_init_vbr (& vi, input.channels, input.frequency,
- v_base_quality))
- {
- vorbis_info_clear(&vi);
- return 0;
- }
-
- vorbis_analysis_init(&vd, &vi);
- vorbis_block_init(&vd, &vb);
-
- srand(time(NULL));
- ogg_stream_init(&os, rand());
-
- vorbis_analysis_headerout(&vd, &vc, &header, &header_comm, &header_code);
-
- ogg_stream_packetin(&os, &header);
- ogg_stream_packetin(&os, &header_comm);
- ogg_stream_packetin(&os, &header_code);
-
- while (ogg_stream_flush (& os, & og))
- {
- write_output(og.header, og.header_len);
- write_output(og.body, og.body_len);
- }
-
- return 1;
-}
-
-static void vorbis_write_real (void * data, gint length)
-{
- int samples = length / sizeof (float);
- int channel, result;
- float * end = (float *) data + samples;
- float * * buffer = vorbis_analysis_buffer (& vd, samples / input.channels);
- float * from, * to;
-
- for (channel = 0; channel < input.channels; channel ++)
- {
- to = buffer[channel];
-
- for (from = (float *) data + channel; from < end; from += input.channels)
- * to ++ = * from;
- }
-
- vorbis_analysis_wrote (& vd, samples / input.channels);
-
- while(vorbis_analysis_blockout(&vd, &vb) == 1)
- {
- vorbis_analysis(&vb, &op);
- vorbis_bitrate_addblock(&vb);
-
- while (vorbis_bitrate_flushpacket(&vd, &op))
- {
- ogg_stream_packetin(&os, &op);
-
- while ((result = ogg_stream_pageout(&os, &og)))
- {
- write_output(og.header, og.header_len);
- write_output(og.body, og.body_len);
- }
- }
- }
-}
-
-static void vorbis_write (void * data, gint length)
-{
- if (length > 0) /* don't signal end of file yet */
- vorbis_write_real (data, length);
-}
-
-static void vorbis_close(void)
-{
- vorbis_write_real (NULL, 0); /* signal end of file */
-
- while (ogg_stream_flush (& os, & og))
- {
- write_output (og.header, og.header_len);
- write_output (og.body, og.body_len);
- }
-
- ogg_stream_clear(&os);
-
- vorbis_block_clear(&vb);
- vorbis_dsp_clear(&vd);
- vorbis_info_clear(&vi);
-}
-
-/* configuration stuff */
-static GtkWidget *configure_win = NULL;
-static GtkWidget *quality_frame, *quality_vbox, *quality_hbox1, *quality_spin, *quality_label;
-static GtkAdjustment * quality_adj;
-
-static void quality_change(GtkAdjustment *adjustment, gpointer user_data)
-{
- v_base_quality = gtk_spin_button_get_value ((GtkSpinButton *) quality_spin) / 10;
- aud_set_double ("filewriter_vorbis", "base_quality", v_base_quality);
-}
-
-static void vorbis_configure(void)
-{
- if (! configure_win)
- {
- configure_win = gtk_dialog_new_with_buttons
- (_("Vorbis Encoder Configuration"), NULL, 0, _("_Close"),
- GTK_RESPONSE_CLOSE, NULL);
-
- g_signal_connect (configure_win, "response", (GCallback) gtk_widget_destroy, NULL);
- g_signal_connect (configure_win, "destroy", (GCallback)
- gtk_widget_destroyed, & configure_win);
-
- GtkWidget * vbox = gtk_dialog_get_content_area ((GtkDialog *) configure_win);
-
- /* quality options */
- quality_frame = gtk_frame_new(_("Quality"));
- gtk_container_set_border_width(GTK_CONTAINER(quality_frame), 5);
- gtk_box_pack_start(GTK_BOX(vbox), quality_frame, FALSE, FALSE, 2);
-
- quality_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(quality_vbox), 10);
- gtk_container_add(GTK_CONTAINER(quality_frame), quality_vbox);
-
- /* quality option: vbr level */
- quality_hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
- gtk_container_set_border_width(GTK_CONTAINER(quality_hbox1), 10);
- gtk_container_add(GTK_CONTAINER(quality_vbox), quality_hbox1);
-
- quality_label = gtk_label_new(_("Quality level (0 - 10):"));
- gtk_misc_set_alignment(GTK_MISC(quality_label), 0, 0.5);
- gtk_box_pack_start(GTK_BOX(quality_hbox1), quality_label, TRUE, TRUE, 0);
-
- quality_adj = (GtkAdjustment *) gtk_adjustment_new (5, 0, 10, 0.1, 1, 0);
- quality_spin = gtk_spin_button_new(GTK_ADJUSTMENT(quality_adj), 1, 2);
- gtk_box_pack_start(GTK_BOX(quality_hbox1), quality_spin, TRUE, TRUE, 0);
- g_signal_connect(G_OBJECT(quality_adj), "value-changed", G_CALLBACK(quality_change), NULL);
-
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(quality_spin), (v_base_quality * 10));
- }
-
- gtk_widget_show_all(configure_win);
-}
-
-static int vorbis_format_required (int fmt)
-{
- return FMT_FLOAT;
-}
-
-FileWriter vorbis_plugin =
-{
- .init = vorbis_init,
- .configure = vorbis_configure,
- .open = vorbis_open,
- .write = vorbis_write,
- .close = vorbis_close,
- .format_required = vorbis_format_required,
-};
-
-#endif
diff --git a/src/filewriter/vorbis.cc b/src/filewriter/vorbis.cc
new file mode 100644
index 000000000000..c97ac3d445b1
--- /dev/null
+++ b/src/filewriter/vorbis.cc
@@ -0,0 +1,248 @@
+/* FileWriter Vorbis Plugin
+ * Copyright (c) 2007 William Pitcock <nenolod at sacredspiral.co.uk>
+ *
+ * Partially derived from Og(g)re - Ogg-Output-Plugin:
+ * Copyright (c) 2002 Lars Siebold <khandha5 at gmx.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "plugins.h"
+
+#ifdef FILEWRITER_VORBIS
+
+#include <stdlib.h>
+#include <vorbis/vorbisenc.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+
+static ogg_stream_state os;
+static ogg_page og;
+static ogg_packet op;
+
+static vorbis_dsp_state vd;
+static vorbis_block vb;
+static vorbis_info vi;
+static vorbis_comment vc;
+
+static const char * const vorbis_defaults[] = {
+ "base_quality", "0.5",
+ nullptr};
+
+static double v_base_quality;
+static int channels;
+
+static void vorbis_init ()
+{
+ aud_config_set_defaults ("filewriter_vorbis", vorbis_defaults);
+
+ v_base_quality = aud_get_double ("filewriter_vorbis", "base_quality");
+}
+
+static void add_string_from_tuple (vorbis_comment * vc, const char * name,
+ const Tuple & tuple, Tuple::Field field)
+{
+ String val = tuple.get_str (field);
+ if (val)
+ vorbis_comment_add_tag (vc, name, val);
+}
+
+static bool vorbis_open (VFSFile & file, const format_info & info, const Tuple & tuple)
+{
+ ogg_packet header;
+ ogg_packet header_comm;
+ ogg_packet header_code;
+
+ vorbis_init();
+
+ vorbis_info_init(&vi);
+ vorbis_comment_init(&vc);
+
+ int scrint;
+
+ add_string_from_tuple (& vc, "title", tuple, Tuple::Title);
+ add_string_from_tuple (& vc, "artist", tuple, Tuple::Artist);
+ add_string_from_tuple (& vc, "album", tuple, Tuple::Album);
+ add_string_from_tuple (& vc, "genre", tuple, Tuple::Genre);
+ add_string_from_tuple (& vc, "date", tuple, Tuple::Date);
+ add_string_from_tuple (& vc, "comment", tuple, Tuple::Comment);
+
+ if ((scrint = tuple.get_int (Tuple::Track)) > 0)
+ vorbis_comment_add_tag(&vc, "tracknumber", int_to_str (scrint));
+
+ if ((scrint = tuple.get_int (Tuple::Year)) > 0)
+ vorbis_comment_add_tag(&vc, "year", int_to_str (scrint));
+
+ if (vorbis_encode_init_vbr (& vi, info.channels, info.frequency, v_base_quality))
+ {
+ vorbis_info_clear(&vi);
+ return false;
+ }
+
+ vorbis_analysis_init(&vd, &vi);
+ vorbis_block_init(&vd, &vb);
+
+ ogg_stream_init(&os, rand());
+
+ vorbis_analysis_headerout(&vd, &vc, &header, &header_comm, &header_code);
+
+ ogg_stream_packetin(&os, &header);
+ ogg_stream_packetin(&os, &header_comm);
+ ogg_stream_packetin(&os, &header_code);
+
+ while (ogg_stream_flush (& os, & og))
+ {
+ if (file.fwrite (og.header, 1, og.header_len) != og.header_len ||
+ file.fwrite (og.body, 1, og.body_len) != og.body_len)
+ AUDERR ("write error\n");
+ }
+
+ channels = info.channels;
+ return true;
+}
+
+static void vorbis_write_real (VFSFile & file, const void * data, int length)
+{
+ int samples = length / sizeof (float);
+ int channel;
+ float * end = (float *) data + samples;
+ float * * buffer = vorbis_analysis_buffer (& vd, samples / channels);
+ float * from, * to;
+
+ for (channel = 0; channel < channels; channel ++)
+ {
+ to = buffer[channel];
+
+ for (from = (float *) data + channel; from < end; from += channels)
+ * to ++ = * from;
+ }
+
+ vorbis_analysis_wrote (& vd, samples / channels);
+
+ while(vorbis_analysis_blockout(&vd, &vb) == 1)
+ {
+ vorbis_analysis(&vb, &op);
+ vorbis_bitrate_addblock(&vb);
+
+ while (vorbis_bitrate_flushpacket(&vd, &op))
+ {
+ ogg_stream_packetin(&os, &op);
+
+ while (ogg_stream_pageout(&os, &og))
+ {
+ if (file.fwrite (og.header, 1, og.header_len) != og.header_len ||
+ file.fwrite (og.body, 1, og.body_len) != og.body_len)
+ AUDERR ("write error\n");
+ }
+ }
+ }
+}
+
+static void vorbis_write (VFSFile & file, const void * data, int length)
+{
+ if (length > 0) /* don't signal end of file yet */
+ vorbis_write_real (file, data, length);
+}
+
+static void vorbis_close (VFSFile & file)
+{
+ vorbis_write_real (file, nullptr, 0); /* signal end of file */
+
+ while (ogg_stream_flush (& os, & og))
+ {
+ if (file.fwrite (og.header, 1, og.header_len) != og.header_len ||
+ file.fwrite (og.body, 1, og.body_len) != og.body_len)
+ AUDERR ("write error\n");
+ }
+
+ ogg_stream_clear(&os);
+
+ vorbis_block_clear(&vb);
+ vorbis_dsp_clear(&vd);
+ vorbis_info_clear(&vi);
+}
+
+/* configuration stuff */
+static GtkWidget *configure_win = nullptr;
+static GtkWidget *quality_frame, *quality_vbox, *quality_hbox1, *quality_spin, *quality_label;
+static GtkAdjustment * quality_adj;
+
+static void quality_change(GtkAdjustment *adjustment, void * user_data)
+{
+ v_base_quality = gtk_spin_button_get_value ((GtkSpinButton *) quality_spin) / 10;
+ aud_set_double ("filewriter_vorbis", "base_quality", v_base_quality);
+}
+
+static void vorbis_configure(void)
+{
+ if (! configure_win)
+ {
+ configure_win = gtk_dialog_new_with_buttons
+ (_("Vorbis Encoder Configuration"), nullptr, (GtkDialogFlags) 0,
+ _("_Close"), GTK_RESPONSE_CLOSE, nullptr);
+
+ g_signal_connect (configure_win, "response", (GCallback) gtk_widget_destroy, nullptr);
+ g_signal_connect (configure_win, "destroy", (GCallback)
+ gtk_widget_destroyed, & configure_win);
+
+ GtkWidget * vbox = gtk_dialog_get_content_area ((GtkDialog *) configure_win);
+
+ /* quality options */
+ quality_frame = gtk_frame_new(_("Quality"));
+ gtk_container_set_border_width(GTK_CONTAINER(quality_frame), 5);
+ gtk_box_pack_start(GTK_BOX(vbox), quality_frame, FALSE, FALSE, 2);
+
+ quality_vbox = gtk_vbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(quality_vbox), 10);
+ gtk_container_add(GTK_CONTAINER(quality_frame), quality_vbox);
+
+ /* quality option: vbr level */
+ quality_hbox1 = gtk_hbox_new (FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(quality_hbox1), 10);
+ gtk_container_add(GTK_CONTAINER(quality_vbox), quality_hbox1);
+
+ quality_label = gtk_label_new(_("Quality level (0 - 10):"));
+ gtk_misc_set_alignment(GTK_MISC(quality_label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(quality_hbox1), quality_label, TRUE, TRUE, 0);
+
+ quality_adj = (GtkAdjustment *) gtk_adjustment_new (5, 0, 10, 0.1, 1, 0);
+ quality_spin = gtk_spin_button_new(GTK_ADJUSTMENT(quality_adj), 1, 2);
+ gtk_box_pack_start(GTK_BOX(quality_hbox1), quality_spin, TRUE, TRUE, 0);
+ g_signal_connect(G_OBJECT(quality_adj), "value-changed", G_CALLBACK(quality_change), nullptr);
+
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(quality_spin), (v_base_quality * 10));
+ }
+
+ gtk_widget_show_all(configure_win);
+}
+
+static int vorbis_format_required (int fmt)
+{
+ return FMT_FLOAT;
+}
+
+FileWriterImpl vorbis_plugin = {
+ vorbis_init,
+ vorbis_configure,
+ vorbis_open,
+ vorbis_write,
+ vorbis_close,
+ vorbis_format_required,
+};
+
+#endif
diff --git a/src/filewriter/wav.c b/src/filewriter/wav.c
deleted file mode 100644
index fe51fc52bc06..000000000000
--- a/src/filewriter/wav.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/* FileWriter-Plugin
- * (C) copyright 2012 MichaÅ Lipski
- * (C) copyright 2007 merging of Disk Writer and Out-Lame by Michael Färber
- *
- * Original Out-Lame-Plugin:
- * (C) copyright 2002 Lars Siebold <khandha5 at gmx.net>
- * (C) copyright 2006-2007 porting to audacious by Yoshiki Yazawa <yaz at cc.rim.or.jp>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "plugins.h"
-
-#pragma pack(push) /* must be byte-aligned */
-#pragma pack(1)
-struct wavhead
-{
- guint32 main_chunk;
- guint32 length;
- guint32 chunk_type;
- guint32 sub_chunk;
- guint32 sc_len;
- guint16 format;
- guint16 modus;
- guint32 sample_fq;
- guint32 byte_p_sec;
- guint16 byte_p_spl;
- guint16 bit_p_spl;
- guint32 data_chunk;
- guint32 data_length;
-};
-#pragma pack(pop)
-
-static struct wavhead header;
-
-static guint64 written;
-
-static gint wav_open(void)
-{
- memcpy(&header.main_chunk, "RIFF", 4);
- header.length = GUINT32_TO_LE(0);
- memcpy(&header.chunk_type, "WAVE", 4);
- memcpy(&header.sub_chunk, "fmt ", 4);
- header.sc_len = GUINT32_TO_LE(16);
- if (input.format == FMT_FLOAT)
- header.format = GUINT16_TO_LE(3);
- else
- header.format = GUINT16_TO_LE(1);
- header.modus = GUINT16_TO_LE(input.channels);
- header.sample_fq = GUINT32_TO_LE(input.frequency);
- if (input.format == FMT_S16_LE)
- header.bit_p_spl = GUINT16_TO_LE(16);
- else if (input.format == FMT_S24_LE)
- header.bit_p_spl = GUINT16_TO_LE(24);
- else
- header.bit_p_spl = GUINT16_TO_LE(32);
- header.byte_p_sec = GUINT32_TO_LE(input.frequency * header.modus * (GUINT16_FROM_LE(header.bit_p_spl) / 8));
- header.byte_p_spl = GUINT16_TO_LE((GUINT16_FROM_LE(header.bit_p_spl) / (8 / input.channels)));
- memcpy(&header.data_chunk, "data", 4);
- header.data_length = GUINT32_TO_LE(0);
-
- if (vfs_fwrite (& header, 1, sizeof header, output_file) != sizeof header)
- return 0;
-
- written = 0;
-
- return 1;
-}
-
-static void pack24 (void * * data, int * len)
-{
- int samples = (* len) / sizeof (int32_t);
- char * new = g_malloc (samples * 3);
- int32_t * data32 = * data;
- int32_t * end = data32 + samples;
-
- * data = new;
- * len = samples * 3;
-
- while (data32 < end)
- {
- memcpy (new, data32 ++, 3);
- new += 3;
- }
-}
-
-static void wav_write (void * data, gint len)
-{
- if (input.format == FMT_S24_LE)
- pack24 (& data, & len);
-
- written += len;
- if (vfs_fwrite (data, 1, len, output_file) != len)
- fprintf (stderr, "Error while writing to .wav output file.\n");
-
- if (input.format == FMT_S24_LE)
- g_free (data);
-}
-
-static void wav_close(void)
-{
- if (output_file)
- {
- header.length = GUINT32_TO_LE(written + sizeof (struct wavhead) - 8);
- header.data_length = GUINT32_TO_LE(written);
-
- if (vfs_fseek (output_file, 0, SEEK_SET) || vfs_fwrite (& header, 1,
- sizeof header, output_file) != sizeof header)
- fprintf (stderr, "Error while writing to .wav output file.\n");
- }
-}
-
-static int wav_format_required (int fmt)
-{
- switch (fmt)
- {
- case FMT_S16_LE:
- case FMT_S24_LE:
- case FMT_S32_LE:
- case FMT_FLOAT:
- return fmt;
- default:
- return FMT_S16_LE;
- }
-}
-
-FileWriter wav_plugin =
-{
- .init = NULL,
- .configure = NULL,
- .open = wav_open,
- .write = wav_write,
- .close = wav_close,
- .format_required = wav_format_required,
-};
diff --git a/src/filewriter/wav.cc b/src/filewriter/wav.cc
new file mode 100644
index 000000000000..ab914fdc159c
--- /dev/null
+++ b/src/filewriter/wav.cc
@@ -0,0 +1,152 @@
+/* FileWriter-Plugin
+ * (C) copyright 2012 MichaÅ Lipski
+ * (C) copyright 2007 merging of Disk Writer and Out-Lame by Michael Färber
+ *
+ * Original Out-Lame-Plugin:
+ * (C) copyright 2002 Lars Siebold <khandha5 at gmx.net>
+ * (C) copyright 2006-2007 porting to audacious by Yoshiki Yazawa <yaz at cc.rim.or.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "plugins.h"
+
+#include <string.h>
+#include <libaudcore/runtime.h>
+
+#pragma pack(push) /* must be byte-aligned */
+#pragma pack(1)
+struct wavhead
+{
+ uint32_t main_chunk;
+ uint32_t length;
+ uint32_t chunk_type;
+ uint32_t sub_chunk;
+ uint32_t sc_len;
+ uint16_t format;
+ uint16_t modus;
+ uint32_t sample_fq;
+ uint32_t byte_p_sec;
+ uint16_t byte_p_spl;
+ uint16_t bit_p_spl;
+ uint32_t data_chunk;
+ uint32_t data_length;
+};
+#pragma pack(pop)
+
+static struct wavhead header;
+
+static int format;
+static Index<char> packbuf;
+
+static uint64_t written;
+
+
+static bool wav_open (VFSFile & file, const format_info & info, const Tuple &)
+{
+ memcpy(&header.main_chunk, "RIFF", 4);
+ header.length = TO_LE32(0);
+ memcpy(&header.chunk_type, "WAVE", 4);
+ memcpy(&header.sub_chunk, "fmt ", 4);
+ header.sc_len = TO_LE32(16);
+ if (info.format == FMT_FLOAT)
+ header.format = TO_LE16(3);
+ else
+ header.format = TO_LE16(1);
+ header.modus = TO_LE16(info.channels);
+ header.sample_fq = TO_LE32(info.frequency);
+ if (info.format == FMT_S16_LE)
+ header.bit_p_spl = TO_LE16(16);
+ else if (info.format == FMT_S24_LE)
+ header.bit_p_spl = TO_LE16(24);
+ else
+ header.bit_p_spl = TO_LE16(32);
+ header.byte_p_sec = TO_LE32(info.frequency * header.modus * (FROM_LE16(header.bit_p_spl) / 8));
+ header.byte_p_spl = TO_LE16((FROM_LE16(header.bit_p_spl) / (8 / info.channels)));
+ memcpy(&header.data_chunk, "data", 4);
+ header.data_length = TO_LE32(0);
+
+ if (file.fwrite (& header, 1, sizeof header) != sizeof header)
+ return false;
+
+ format = info.format;
+ written = 0;
+
+ return true;
+}
+
+static void pack24 (const void * * data, int * len)
+{
+ int samples = (* len) / sizeof (int32_t);
+ auto data32 = (const int32_t *) * data;
+ auto end = data32 + samples;
+
+ packbuf.resize (samples * 3);
+ char * buf = packbuf.begin ();
+
+ * data = buf;
+ * len = samples * 3;
+
+ while (data32 < end)
+ {
+ memcpy (buf, data32 ++, 3);
+ buf += 3;
+ }
+}
+
+static void wav_write (VFSFile & file, const void * data, int len)
+{
+ if (format == FMT_S24_LE)
+ pack24 (& data, & len);
+
+ written += len;
+ if (file.fwrite (data, 1, len) != len)
+ AUDERR ("Error while writing to .wav output file.\n");
+}
+
+static void wav_close (VFSFile & file)
+{
+ header.length = TO_LE32(written + sizeof (struct wavhead) - 8);
+ header.data_length = TO_LE32(written);
+
+ if (file.fseek (0, VFS_SEEK_SET) ||
+ file.fwrite (& header, 1, sizeof header) != sizeof header)
+ AUDERR ("Error while writing to .wav output file.\n");
+
+ packbuf.clear ();
+}
+
+static int wav_format_required (int fmt)
+{
+ switch (fmt)
+ {
+ case FMT_S16_LE:
+ case FMT_S24_LE:
+ case FMT_S32_LE:
+ case FMT_FLOAT:
+ return fmt;
+ default:
+ return FMT_S16_LE;
+ }
+}
+
+FileWriterImpl wav_plugin = {
+ nullptr, // init
+ nullptr, // configure
+ wav_open,
+ wav_write,
+ wav_close,
+ wav_format_required,
+};
diff --git a/src/flacng/Makefile b/src/flacng/Makefile
index b47566644396..fb53a2bb2bb6 100644
--- a/src/flacng/Makefile
+++ b/src/flacng/Makefile
@@ -1,15 +1,17 @@
PLUGIN = flacng${PLUGIN_SUFFIX}
-SRCS = plugin.c \
- tools.c \
- seekable_stream_callbacks.c \
- metadata.c
+SRCS = plugin.cc \
+ tools.cc \
+ seekable_stream_callbacks.cc \
+ metadata.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${LIBFLAC_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS} ${LIBFLAC_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${LIBFLAC_CFLAGS} -I../..
+LIBS += ${LIBFLAC_LIBS}
diff --git a/src/flacng/flacng.h b/src/flacng/flacng.h
index 955eefeb6573..1f1d9aa987cb 100644
--- a/src/flacng/flacng.h
+++ b/src/flacng/flacng.h
@@ -22,13 +22,36 @@
#include <FLAC/all.h>
-#include <libaudcore/audio.h>
-#include <libaudcore/tuple.h>
-#include <libaudcore/vfs.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
-#define FLACNG_ERROR(...) do { \
- printf("flacng: " __VA_ARGS__); \
-} while (0)
+class FLACng : public InputPlugin
+{
+public:
+ static const char about[];
+ static const char *const exts[];
+
+ static constexpr PluginInfo info = {
+ N_("FLAC Decoder"),
+ PACKAGE,
+ about
+ };
+
+ static constexpr auto iinfo = InputInfo(FlagWritesTag)
+ .with_priority(1)
+ .with_exts(exts);
+
+ constexpr FLACng() : InputPlugin(info, iinfo) {}
+
+ bool init();
+ void cleanup();
+
+ bool is_our_file(const char *filename, VFSFile &file);
+ Tuple read_tuple(const char *filename, VFSFile &file);
+ Index<char> read_image(const char *filename, VFSFile &file);
+ bool write_tuple(const char *filename, VFSFile &file, const Tuple &tuple);
+ bool play(const char *filename, VFSFile &file);
+};
#define BUFFER_SIZE_SAMP (FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS)
#define BUFFER_SIZE_BYTE (BUFFER_SIZE_SAMP * (FLAC__MAX_BITS_PER_SAMPLE/8))
@@ -36,22 +59,35 @@
#define SAMPLE_SIZE(a) (a == 8 ? 1 : (a == 16 ? 2 : 4))
#define SAMPLE_FMT(a) (a == 8 ? FMT_S8 : (a == 16 ? FMT_S16_NE : (a == 24 ? FMT_S24_NE : FMT_S32_NE)))
-typedef struct callback_info {
- unsigned bits_per_sample;
- unsigned sample_rate;
- unsigned channels;
- unsigned long total_samples;
- int32_t* output_buffer;
- int32_t* write_pointer;
- unsigned buffer_used;
- VFSFile* fd;
- int bitrate;
-} callback_info;
+struct callback_info
+{
+ unsigned bits_per_sample = 0;
+ unsigned sample_rate = 0;
+ unsigned channels = 0;
+ unsigned long total_samples = 0;
+ Index<int32_t> output_buffer;
+ int32_t *write_pointer = nullptr;
+ unsigned buffer_used = 0;
+ VFSFile *fd = nullptr;
+ int bitrate = 0;
+
+ void alloc()
+ {
+ output_buffer.resize(BUFFER_SIZE_SAMP);
+ reset();
+ }
+
+ void reset()
+ {
+ buffer_used = 0;
+ write_pointer = output_buffer.begin();
+ }
+};
/* metadata.c */
-bool_t flac_update_song_tuple(const char *filename, VFSFile *fd, const Tuple *tuple);
-bool_t flac_get_image(const char *filename, VFSFile *fd, void **data, int64_t *length);
-Tuple *flac_probe_for_tuple(const char *filename, VFSFile *fd);
+bool flac_update_song_tuple(const char *filename, VFSFile &fd, const Tuple &tuple);
+Index<char> flac_get_image(const char *filename, VFSFile &fd);
+Tuple flac_probe_for_tuple(const char *filename, VFSFile &fd);
/* seekable_stream_callbacks.c */
FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
@@ -64,9 +100,6 @@ void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderError
void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
/* tools.c */
-callback_info* init_callback_info(void);
-void clean_callback_info(callback_info* info);
-void reset_info(callback_info* info);
-bool_t read_metadata(FLAC__StreamDecoder* decoder, callback_info* info);
+bool read_metadata(FLAC__StreamDecoder* decoder, callback_info* info);
#endif
diff --git a/src/flacng/metadata.c b/src/flacng/metadata.c
deleted file mode 100644
index d1dd23c2ca18..000000000000
--- a/src/flacng/metadata.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * A FLAC decoder plugin for the Audacious Media Player
- * Copyright (C) 2005 Ralf Ertzinger
- * Copyright (C) 2010 John Lindgren
- * Copyright (C) 2010 MichaÅ Lipski <tallica at o2.pl>
- *
- * 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <audacious/debug.h>
-#include <audacious/i18n.h>
-#include <libaudcore/audstrings.h>
-
-#include "flacng.h"
-
-static size_t read_cb(void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle)
-{
- size_t read;
-
- if (handle == NULL)
- {
- FLACNG_ERROR("Trying to read data from an uninitialized file!\n");
- return -1;
- }
-
- read = vfs_fread(ptr, size, nmemb, handle);
-
- switch (read)
- {
- case -1:
- FLACNG_ERROR("Error while reading from stream!\n");
- return -1;
-
- case 0:
- AUDDBG("Stream reached EOF\n");
- return 0;
-
- default:
- return read;
- }
-}
-
-static size_t write_cb(const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle)
-{
- return vfs_fwrite(ptr, size, nmemb, handle);
-}
-
-static int seek_cb(FLAC__IOHandle handle, FLAC__int64 offset, int whence)
-{
- if (vfs_fseek(handle, offset, whence) != 0)
- {
- FLACNG_ERROR("Could not seek to %ld!\n", (long)offset);
- return -1;
- }
-
- return 0;
-}
-
-static FLAC__int64 tell_cb(FLAC__IOHandle handle)
-{
- uint64_t offset;
-
- if ((offset = vfs_ftell(handle)) == -1)
- {
- FLACNG_ERROR("Could not tell current position!\n");
- return -1;
- }
-
- AUDDBG ("Current position: %d\n", (int) offset);
- return offset;
-}
-
-static int eof_cb(FLAC__IOHandle handle)
-{
- return vfs_feof(handle);
-}
-
-static FLAC__IOCallbacks io_callbacks = {
- read_cb,
- write_cb,
- seek_cb,
- tell_cb,
- eof_cb,
- NULL
-};
-
-static void insert_str_tuple_to_vc (FLAC__StreamMetadata * vc_block,
- const Tuple * tuple, int tuple_name, char * field_name)
-{
- FLAC__StreamMetadata_VorbisComment_Entry entry;
- char *val = tuple_get_str(tuple, tuple_name);
-
- if (val == NULL)
- return;
-
- SPRINTF (str, "%s=%s", field_name, val);
- entry.entry = (FLAC__byte *) str;
- entry.length = strlen(str);
- FLAC__metadata_object_vorbiscomment_insert_comment(vc_block,
- vc_block->data.vorbis_comment.num_comments, entry, true);
- str_unref(val);
-}
-
-static void insert_int_tuple_to_vc (FLAC__StreamMetadata * vc_block,
- const Tuple * tuple, int tuple_name, char * field_name)
-{
- FLAC__StreamMetadata_VorbisComment_Entry entry;
- int val = tuple_get_int(tuple, tuple_name);
-
- if (val <= 0)
- return;
-
- SPRINTF (str, "%s=%d", field_name, val);
- entry.entry = (FLAC__byte *) str;
- entry.length = strlen(str);
- FLAC__metadata_object_vorbiscomment_insert_comment(vc_block,
- vc_block->data.vorbis_comment.num_comments, entry, true);
-}
-
-bool_t flac_update_song_tuple(const char *filename, VFSFile *fd, const Tuple *tuple)
-{
- AUDDBG("Update song tuple.\n");
-
- FLAC__Metadata_Iterator *iter;
- FLAC__Metadata_Chain *chain;
- FLAC__StreamMetadata *vc_block;
- FLAC__Metadata_ChainStatus status;
-
- chain = FLAC__metadata_chain_new();
-
- if (!FLAC__metadata_chain_read_with_callbacks(chain, fd, io_callbacks))
- goto ERR;
-
- iter = FLAC__metadata_iterator_new();
-
- FLAC__metadata_iterator_init(iter, chain);
-
- while (FLAC__metadata_iterator_next(iter))
- if (FLAC__metadata_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_VORBIS_COMMENT)
- {
- FLAC__metadata_iterator_delete_block(iter, true);
- break;
- }
-
- vc_block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
-
- insert_str_tuple_to_vc(vc_block, tuple, FIELD_TITLE, "TITLE");
- insert_str_tuple_to_vc(vc_block, tuple, FIELD_ARTIST, "ARTIST");
- insert_str_tuple_to_vc(vc_block, tuple, FIELD_ALBUM, "ALBUM");
- insert_str_tuple_to_vc(vc_block, tuple, FIELD_GENRE, "GENRE");
- insert_str_tuple_to_vc(vc_block, tuple, FIELD_COMMENT, "COMMENT");
-
- insert_int_tuple_to_vc(vc_block, tuple, FIELD_YEAR, "DATE");
- insert_int_tuple_to_vc(vc_block, tuple, FIELD_TRACK_NUMBER, "TRACKNUMBER");
-
- FLAC__metadata_iterator_insert_block_after(iter, vc_block);
-
- FLAC__metadata_iterator_delete(iter);
- FLAC__metadata_chain_sort_padding(chain);
-
- if (!FLAC__metadata_chain_write_with_callbacks(chain, TRUE, fd, io_callbacks))
- goto ERR;
-
- FLAC__metadata_chain_delete(chain);
- return TRUE;
-
-ERR:
- status = FLAC__metadata_chain_status(chain);
- FLAC__metadata_chain_delete(chain);
-
- FLACNG_ERROR("An error occured: %s\n", FLAC__Metadata_ChainStatusString[status]);
- return FALSE;
-}
-
-bool_t flac_get_image(const char *filename, VFSFile *fd, void **data, int64_t *length)
-{
- AUDDBG("Probe for song image.\n");
-
- FLAC__Metadata_Iterator *iter;
- FLAC__Metadata_Chain *chain;
- FLAC__StreamMetadata *metadata = NULL;
- FLAC__Metadata_ChainStatus status;
- bool_t has_image = FALSE;
-
- chain = FLAC__metadata_chain_new();
-
- if (!FLAC__metadata_chain_read_with_callbacks(chain, fd, io_callbacks))
- goto ERR;
-
- iter = FLAC__metadata_iterator_new();
-
- FLAC__metadata_iterator_init(iter, chain);
-
- while (FLAC__metadata_iterator_next(iter))
- if (FLAC__metadata_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_PICTURE)
- break;
-
- if (FLAC__metadata_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_PICTURE)
- {
- metadata = FLAC__metadata_iterator_get_block(iter);
-
- if (metadata->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER)
- {
- AUDDBG("FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER found.");
-
- * data = g_malloc (metadata->data.picture.data_length);
- * length = metadata->data.picture.data_length;
- memcpy (* data, metadata->data.picture.data, * length);
- has_image = TRUE;
- }
- }
-
- FLAC__metadata_iterator_delete(iter);
- FLAC__metadata_chain_delete(chain);
-
- return has_image;
-
-ERR:
- status = FLAC__metadata_chain_status(chain);
- FLAC__metadata_chain_delete(chain);
-
- FLACNG_ERROR("An error occured: %s\n", FLAC__Metadata_ChainStatusString[status]);
- return FALSE;
-}
-
-static void parse_gain_text(const char *text, int *value, int *unit)
-{
- int sign = 1;
-
- *value = 0;
- *unit = 1;
-
- if (*text == '-')
- {
- sign = -1;
- text++;
- }
-
- while (*text >= '0' && *text <= '9')
- {
- *value = *value * 10 + (*text - '0');
- text++;
- }
-
- if (*text == '.')
- {
- text++;
-
- while (*text >= '0' && *text <= '9' && *value < INT_MAX / 10)
- {
- *value = *value * 10 + (*text - '0');
- *unit = *unit * 10;
- text++;
- }
- }
-
- *value = *value * sign;
-}
-
-static void set_gain_info(Tuple *tuple, int field, int unit_field, const char *text)
-{
- int value, unit;
-
- parse_gain_text(text, &value, &unit);
-
- if (tuple_get_value_type(tuple, unit_field) == TUPLE_INT)
- value = value * (int64_t) tuple_get_int(tuple, unit_field) / unit;
- else
- tuple_set_int(tuple, unit_field, unit);
-
- tuple_set_int(tuple, field, value);
-}
-
-static void add_text (Tuple * tuple, int field, const char * value)
-{
- char * cur = tuple_get_str (tuple, field);
- if (cur)
- {
- SPRINTF (both, "%s, %s", cur, value);
- tuple_set_str (tuple, field, both);
- }
- else
- tuple_set_str (tuple, field, value);
-
- str_unref(cur);
-}
-
-static void parse_comment (Tuple * tuple, const char * key, const char * value)
-{
- AUDDBG ("Found key %s <%s>\n", key, value);
-
- const struct {
- const char * key;
- int field;
- } tfields[] = {
- {"ARTIST", FIELD_ARTIST},
- {"ALBUM", FIELD_ALBUM},
- {"TITLE", FIELD_TITLE},
- {"COMMENT", FIELD_COMMENT},
- {"GENRE", FIELD_GENRE}};
-
- for (int i = 0; i < ARRAY_LEN (tfields); i ++)
- {
- if (! g_ascii_strcasecmp (key, tfields[i].key))
- {
- add_text (tuple, tfields[i].field, value);
- return;
- }
- }
-
- if (! g_ascii_strcasecmp (key, "TRACKNUMBER"))
- tuple_set_int(tuple, FIELD_TRACK_NUMBER, atoi(value));
- else if (! g_ascii_strcasecmp (key, "DATE"))
- tuple_set_int(tuple, FIELD_YEAR, atoi(value));
- else if (! g_ascii_strcasecmp (key, "REPLAYGAIN_TRACK_GAIN"))
- set_gain_info(tuple, FIELD_GAIN_TRACK_GAIN, FIELD_GAIN_GAIN_UNIT, value);
- else if (! g_ascii_strcasecmp (key, "REPLAYGAIN_TRACK_PEAK"))
- set_gain_info(tuple, FIELD_GAIN_TRACK_PEAK, FIELD_GAIN_PEAK_UNIT, value);
- else if (! g_ascii_strcasecmp (key, "REPLAYGAIN_ALBUM_GAIN"))
- set_gain_info(tuple, FIELD_GAIN_ALBUM_GAIN, FIELD_GAIN_GAIN_UNIT, value);
- else if (! g_ascii_strcasecmp (key, "REPLAYGAIN_ALBUM_PEAK"))
- set_gain_info(tuple, FIELD_GAIN_ALBUM_PEAK, FIELD_GAIN_PEAK_UNIT, value);
-}
-
-Tuple *flac_probe_for_tuple(const char *filename, VFSFile *fd)
-{
- AUDDBG("Probe for tuple.\n");
-
- Tuple *tuple = NULL;
- FLAC__Metadata_Iterator *iter;
- FLAC__Metadata_Chain *chain;
- FLAC__StreamMetadata *metadata = NULL;
- FLAC__Metadata_ChainStatus status;
- FLAC__StreamMetadata_VorbisComment_Entry *entry;
- char *key;
- char *value;
-
- tuple = tuple_new_from_filename(filename);
-
- tuple_set_str(tuple, FIELD_CODEC, "Free Lossless Audio Codec (FLAC)");
- tuple_set_str(tuple, FIELD_QUALITY, _("lossless"));
-
- chain = FLAC__metadata_chain_new();
-
- if (!FLAC__metadata_chain_read_with_callbacks(chain, fd, io_callbacks))
- goto ERR;
-
- iter = FLAC__metadata_iterator_new();
-
- FLAC__metadata_iterator_init(iter, chain);
-
- do
- {
- switch (FLAC__metadata_iterator_get_block_type(iter))
- {
- case FLAC__METADATA_TYPE_VORBIS_COMMENT:
-
- if (FLAC__metadata_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_VORBIS_COMMENT)
- {
- metadata = FLAC__metadata_iterator_get_block(iter);
-
- AUDDBG("Vorbis comment contains %d fields\n", metadata->data.vorbis_comment.num_comments);
- AUDDBG("Vendor string: %s\n", metadata->data.vorbis_comment.vendor_string.entry);
-
- entry = metadata->data.vorbis_comment.comments;
-
- for (int i = 0; i < metadata->data.vorbis_comment.num_comments; i++, entry++)
- {
- if (FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(*entry, &key, &value) == false)
- AUDDBG("Could not parse comment\n");
- else
- {
- parse_comment(tuple, key, value);
- g_free(key);
- g_free(value);
- }
- }
- }
- break;
-
- case FLAC__METADATA_TYPE_STREAMINFO:
- metadata = FLAC__metadata_iterator_get_block(iter);
-
- /* Calculate the stream length (milliseconds) */
- if (metadata->data.stream_info.sample_rate == 0)
- {
- FLACNG_ERROR("Invalid sample rate for stream!\n");
- tuple_set_int(tuple, FIELD_LENGTH, -1);
- }
- else
- {
- tuple_set_int(tuple, FIELD_LENGTH,
- (metadata->data.stream_info.total_samples / metadata->data.stream_info.sample_rate) * 1000);
- AUDDBG("Stream length: %d seconds\n", tuple_get_int(tuple, FIELD_LENGTH));
- }
-
- int64_t size = vfs_fsize(fd);
-
- if (size == -1 || metadata->data.stream_info.total_samples == 0)
- tuple_set_int(tuple, FIELD_BITRATE, 0);
- else
- {
- int bitrate = 8 * size *
- (int64_t) metadata->data.stream_info.sample_rate / metadata->data.stream_info.total_samples;
-
- tuple_set_int(tuple, FIELD_BITRATE, (bitrate + 500) / 1000);
- }
- break;
-
- default:
- ;
- }
- } while (FLAC__metadata_iterator_next(iter));
-
- FLAC__metadata_iterator_delete(iter);
- FLAC__metadata_chain_delete(chain);
-
- return tuple;
-
-ERR:
- status = FLAC__metadata_chain_status(chain);
- FLAC__metadata_chain_delete(chain);
-
- FLACNG_ERROR("An error occured: %s\n", FLAC__Metadata_ChainStatusString[status]);
- return tuple;
-}
diff --git a/src/flacng/metadata.cc b/src/flacng/metadata.cc
new file mode 100644
index 000000000000..837f844ba6f7
--- /dev/null
+++ b/src/flacng/metadata.cc
@@ -0,0 +1,438 @@
+/*
+ * A FLAC decoder plugin for the Audacious Media Player
+ * Copyright (C) 2005 Ralf Ertzinger
+ * Copyright (C) 2010 John Lindgren
+ * Copyright (C) 2010 MichaÅ Lipski <tallica at o2.pl>
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define WANT_VFS_STDIO_COMPAT
+#include <libaudcore/runtime.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/audstrings.h>
+
+#include "flacng.h"
+
+static size_t read_cb(void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle)
+{
+ int64_t read;
+
+ if (handle == nullptr)
+ {
+ AUDERR("Trying to read data from an uninitialized file!\n");
+ return -1;
+ }
+
+ read = ((VFSFile *) handle)->fread (ptr, size, nmemb);
+
+ switch (read)
+ {
+ case -1:
+ AUDERR("Error while reading from stream!\n");
+ return -1;
+
+ case 0:
+ AUDDBG("Stream reached EOF\n");
+ return 0;
+
+ default:
+ return read;
+ }
+}
+
+static size_t write_cb(const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle)
+{
+ return ((VFSFile *) handle)->fwrite (ptr, size, nmemb);
+}
+
+static int seek_cb(FLAC__IOHandle handle, FLAC__int64 offset, int whence)
+{
+ if (((VFSFile *) handle)->fseek (offset, to_vfs_seek_type (whence)) != 0)
+ {
+ AUDERR("Could not seek to %ld!\n", (long)offset);
+ return -1;
+ }
+
+ return 0;
+}
+
+static FLAC__int64 tell_cb(FLAC__IOHandle handle)
+{
+ int64_t offset;
+
+ if ((offset = ((VFSFile *) handle)->ftell ()) < 0)
+ {
+ AUDERR("Could not tell current position!\n");
+ return -1;
+ }
+
+ AUDDBG ("Current position: %d\n", (int) offset);
+ return offset;
+}
+
+static int eof_cb(FLAC__IOHandle handle)
+{
+ return ((VFSFile *) handle)->feof ();
+}
+
+static FLAC__IOCallbacks io_callbacks = {
+ read_cb,
+ write_cb,
+ seek_cb,
+ tell_cb,
+ eof_cb,
+ nullptr
+};
+
+static void insert_str_tuple_to_vc (FLAC__StreamMetadata * vc_block,
+ const Tuple & tuple, Tuple::Field field, const char * field_name)
+{
+ FLAC__StreamMetadata_VorbisComment_Entry entry;
+ String val = tuple.get_str (field);
+
+ if (! val)
+ return;
+
+ StringBuf str = str_printf ("%s=%s", field_name, (const char *) val);
+ entry.entry = (FLAC__byte *) (char *) str;
+ entry.length = strlen(str);
+ FLAC__metadata_object_vorbiscomment_insert_comment(vc_block,
+ vc_block->data.vorbis_comment.num_comments, entry, true);
+}
+
+static void insert_int_tuple_to_vc (FLAC__StreamMetadata * vc_block,
+ const Tuple & tuple, Tuple::Field field, const char * field_name)
+{
+ FLAC__StreamMetadata_VorbisComment_Entry entry;
+ int val = tuple.get_int (field);
+
+ if (val <= 0)
+ return;
+
+ StringBuf str = str_printf ("%s=%d", field_name, val);
+ entry.entry = (FLAC__byte *) (char *) str;
+ entry.length = strlen(str);
+ FLAC__metadata_object_vorbiscomment_insert_comment(vc_block,
+ vc_block->data.vorbis_comment.num_comments, entry, true);
+}
+
+bool FLACng::write_tuple(const char *filename, VFSFile &file, const Tuple &tuple)
+{
+ AUDDBG("Update song tuple.\n");
+
+ FLAC__Metadata_Iterator *iter;
+ FLAC__Metadata_Chain *chain;
+ FLAC__StreamMetadata *vc_block;
+ FLAC__Metadata_ChainStatus status;
+
+ chain = FLAC__metadata_chain_new();
+
+ if (!FLAC__metadata_chain_read_with_callbacks(chain, &file, io_callbacks))
+ goto ERR;
+
+ iter = FLAC__metadata_iterator_new();
+
+ FLAC__metadata_iterator_init(iter, chain);
+
+ while (FLAC__metadata_iterator_next(iter))
+ if (FLAC__metadata_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_VORBIS_COMMENT)
+ {
+ FLAC__metadata_iterator_delete_block(iter, true);
+ break;
+ }
+
+ vc_block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
+
+ insert_str_tuple_to_vc(vc_block, tuple, Tuple::Title, "TITLE");
+ insert_str_tuple_to_vc(vc_block, tuple, Tuple::Artist, "ARTIST");
+ insert_str_tuple_to_vc(vc_block, tuple, Tuple::Album, "ALBUM");
+ insert_str_tuple_to_vc(vc_block, tuple, Tuple::Genre, "GENRE");
+ insert_str_tuple_to_vc(vc_block, tuple, Tuple::Comment, "COMMENT");
+
+ insert_int_tuple_to_vc(vc_block, tuple, Tuple::Year, "DATE");
+ insert_int_tuple_to_vc(vc_block, tuple, Tuple::Track, "TRACKNUMBER");
+
+ FLAC__metadata_iterator_insert_block_after(iter, vc_block);
+
+ FLAC__metadata_iterator_delete(iter);
+ FLAC__metadata_chain_sort_padding(chain);
+
+ if (!FLAC__metadata_chain_write_with_callbacks(chain, true, &file, io_callbacks))
+ goto ERR;
+
+ FLAC__metadata_chain_delete(chain);
+ return true;
+
+ERR:
+ status = FLAC__metadata_chain_status(chain);
+ FLAC__metadata_chain_delete(chain);
+
+ AUDERR("An error occured: %s\n", FLAC__Metadata_ChainStatusString[status]);
+ return false;
+}
+
+Index<char> FLACng::read_image(const char *filename, VFSFile &file)
+{
+ AUDDBG("Probe for song image.\n");
+
+ FLAC__Metadata_Iterator *iter;
+ FLAC__Metadata_Chain *chain;
+ FLAC__StreamMetadata *metadata = nullptr;
+ FLAC__Metadata_ChainStatus status;
+
+ Index<char> data;
+
+ chain = FLAC__metadata_chain_new();
+
+ if (!FLAC__metadata_chain_read_with_callbacks(chain, &file, io_callbacks))
+ goto ERR;
+
+ iter = FLAC__metadata_iterator_new();
+
+ FLAC__metadata_iterator_init(iter, chain);
+
+ while (FLAC__metadata_iterator_next(iter))
+ if (FLAC__metadata_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_PICTURE)
+ break;
+
+ if (FLAC__metadata_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_PICTURE)
+ {
+ metadata = FLAC__metadata_iterator_get_block(iter);
+
+ if (metadata->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER)
+ {
+ AUDDBG("FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER found.");
+ data.insert ((const char *) metadata->data.picture.data, 0,
+ metadata->data.picture.data_length);
+ }
+ }
+
+ FLAC__metadata_iterator_delete(iter);
+ FLAC__metadata_chain_delete(chain);
+
+ return data;
+
+ERR:
+ status = FLAC__metadata_chain_status(chain);
+ FLAC__metadata_chain_delete(chain);
+
+ AUDERR("An error occured: %s\n", FLAC__Metadata_ChainStatusString[status]);
+ return data;
+}
+
+static void parse_gain_text(const char *text, int *value, int *unit)
+{
+ int sign = 1;
+
+ *value = 0;
+ *unit = 1;
+
+ if (*text == '-')
+ {
+ sign = -1;
+ text++;
+ }
+
+ while (*text >= '0' && *text <= '9')
+ {
+ *value = *value * 10 + (*text - '0');
+ text++;
+ }
+
+ if (*text == '.')
+ {
+ text++;
+
+ while (*text >= '0' && *text <= '9' && *value < INT_MAX / 10)
+ {
+ *value = *value * 10 + (*text - '0');
+ *unit = *unit * 10;
+ text++;
+ }
+ }
+
+ *value = *value * sign;
+}
+
+static void set_gain_info(Tuple &tuple, Tuple::Field field, Tuple::Field unit_field, const char *text)
+{
+ int value, unit;
+
+ parse_gain_text(text, &value, &unit);
+
+ if (tuple.get_value_type (unit_field) == Tuple::Int)
+ value = value * (int64_t) tuple.get_int (unit_field) / unit;
+ else
+ tuple.set_int (unit_field, unit);
+
+ tuple.set_int (field, value);
+}
+
+static void add_text (Tuple & tuple, Tuple::Field field, const char * value)
+{
+ String cur = tuple.get_str (field);
+ if (cur)
+ tuple.set_str (field, str_concat ({cur, ", ", value}));
+ else
+ tuple.set_str (field, value);
+}
+
+static void parse_comment (Tuple & tuple, const char * key, const char * value)
+{
+ AUDDBG ("Found key %s <%s>\n", key, value);
+
+ static const struct {
+ const char * key;
+ Tuple::Field field;
+ } tfields[] = {
+ {"ARTIST", Tuple::Artist},
+ {"ALBUM", Tuple::Album},
+ {"TITLE", Tuple::Title},
+ {"COMMENT", Tuple::Comment},
+ {"GENRE", Tuple::Genre}
+ };
+
+ for (auto & tfield : tfields)
+ {
+ if (!strcmp_nocase(key, tfield.key))
+ {
+ add_text (tuple, tfield.field, value);
+ return;
+ }
+ }
+
+ if (!strcmp_nocase(key, "TRACKNUMBER"))
+ tuple.set_int(Tuple::Track, atoi(value));
+ else if (!strcmp_nocase(key, "DATE"))
+ tuple.set_int(Tuple::Year, atoi(value));
+ else if (!strcmp_nocase(key, "REPLAYGAIN_TRACK_GAIN"))
+ set_gain_info(tuple, Tuple::TrackGain, Tuple::GainDivisor, value);
+ else if (!strcmp_nocase(key, "REPLAYGAIN_TRACK_PEAK"))
+ set_gain_info(tuple, Tuple::TrackPeak, Tuple::PeakDivisor, value);
+ else if (!strcmp_nocase(key, "REPLAYGAIN_ALBUM_GAIN"))
+ set_gain_info(tuple, Tuple::AlbumGain, Tuple::GainDivisor, value);
+ else if (!strcmp_nocase(key, "REPLAYGAIN_ALBUM_PEAK"))
+ set_gain_info(tuple, Tuple::AlbumPeak, Tuple::PeakDivisor, value);
+}
+
+Tuple FLACng::read_tuple(const char *filename, VFSFile &file)
+{
+ AUDDBG("Probe for tuple.\n");
+
+ Tuple tuple;
+ FLAC__Metadata_Iterator *iter;
+ FLAC__Metadata_Chain *chain;
+ FLAC__StreamMetadata *metadata = nullptr;
+ FLAC__Metadata_ChainStatus status;
+ FLAC__StreamMetadata_VorbisComment_Entry *entry;
+ char *key;
+ char *value;
+
+ tuple.set_filename (filename);
+
+ tuple.set_str (Tuple::Codec, "Free Lossless Audio Codec (FLAC)");
+ tuple.set_str (Tuple::Quality, _("lossless"));
+
+ chain = FLAC__metadata_chain_new();
+
+ if (!FLAC__metadata_chain_read_with_callbacks(chain, &file, io_callbacks))
+ goto ERR;
+
+ iter = FLAC__metadata_iterator_new();
+
+ FLAC__metadata_iterator_init(iter, chain);
+
+ do
+ {
+ switch (FLAC__metadata_iterator_get_block_type(iter))
+ {
+ case FLAC__METADATA_TYPE_VORBIS_COMMENT:
+
+ if (FLAC__metadata_iterator_get_block_type(iter) == FLAC__METADATA_TYPE_VORBIS_COMMENT)
+ {
+ metadata = FLAC__metadata_iterator_get_block(iter);
+
+ AUDDBG("Vorbis comment contains %d fields\n", metadata->data.vorbis_comment.num_comments);
+ AUDDBG("Vendor string: %s\n", metadata->data.vorbis_comment.vendor_string.entry);
+
+ entry = metadata->data.vorbis_comment.comments;
+
+ for (unsigned i = 0; i < metadata->data.vorbis_comment.num_comments; i++, entry++)
+ {
+ if (FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(*entry, &key, &value) == false)
+ AUDDBG("Could not parse comment\n");
+ else
+ {
+ parse_comment(tuple, key, value);
+ free(key);
+ free(value);
+ }
+ }
+ }
+ break;
+
+ case FLAC__METADATA_TYPE_STREAMINFO:
+ {
+ metadata = FLAC__metadata_iterator_get_block(iter);
+
+ /* Calculate the stream length (milliseconds) */
+ if (metadata->data.stream_info.sample_rate == 0)
+ {
+ AUDERR("Invalid sample rate for stream!\n");
+ tuple.set_int (Tuple::Length, -1);
+ }
+ else
+ {
+ tuple.set_int (Tuple::Length,
+ (metadata->data.stream_info.total_samples / metadata->data.stream_info.sample_rate) * 1000);
+ AUDDBG("Stream length: %d seconds\n", tuple.get_int (Tuple::Length));
+ }
+
+ int64_t size = file.fsize ();
+
+ if (size < 0 || metadata->data.stream_info.total_samples == 0)
+ tuple.set_int (Tuple::Bitrate, 0);
+ else
+ {
+ int bitrate = 8 * size *
+ (int64_t) metadata->data.stream_info.sample_rate / metadata->data.stream_info.total_samples;
+
+ tuple.set_int (Tuple::Bitrate, (bitrate + 500) / 1000);
+ }
+ break;
+ }
+
+ default:
+ ;
+ }
+ } while (FLAC__metadata_iterator_next(iter));
+
+ FLAC__metadata_iterator_delete(iter);
+ FLAC__metadata_chain_delete(chain);
+
+ return tuple;
+
+ERR:
+ status = FLAC__metadata_chain_status(chain);
+ FLAC__metadata_chain_delete(chain);
+
+ AUDERR("An error occured: %s\n", FLAC__Metadata_ChainStatusString[status]);
+ return tuple;
+}
diff --git a/src/flacng/plugin.c b/src/flacng/plugin.c
deleted file mode 100644
index 8a4a928ef2c7..000000000000
--- a/src/flacng/plugin.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * A FLAC decoder plugin for the Audacious Media Player
- * Copyright (C) 2005 Ralf Ertzinger
- * Copyright (C) 2010-2012 MichaÅ Lipski
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <string.h>
-#include <glib.h>
-
-#include <audacious/debug.h>
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-#include <audacious/plugin.h>
-
-#include "flacng.h"
-
-static FLAC__StreamDecoder *decoder;
-static callback_info *info;
-
-static bool_t flac_init (void)
-{
- FLAC__StreamDecoderInitStatus ret;
-
- /* Callback structure and decoder for main decoding loop */
-
- if ((info = init_callback_info()) == NULL)
- {
- FLACNG_ERROR("Could not initialize the main callback structure!\n");
- return FALSE;
- }
-
- if ((decoder = FLAC__stream_decoder_new()) == NULL)
- {
- FLACNG_ERROR("Could not create the main FLAC decoder instance!\n");
- return FALSE;
- }
-
- if (FLAC__STREAM_DECODER_INIT_STATUS_OK != (ret = FLAC__stream_decoder_init_stream(
- decoder,
- read_callback,
- seek_callback,
- tell_callback,
- length_callback,
- eof_callback,
- write_callback,
- metadata_callback,
- error_callback,
- info)))
- {
- FLACNG_ERROR("Could not initialize the main FLAC decoder: %s(%d)\n",
- FLAC__StreamDecoderInitStatusString[ret], ret);
- return FALSE;
- }
-
- AUDDBG("Plugin initialized.\n");
- return TRUE;
-}
-
-static void flac_cleanup(void)
-{
- FLAC__stream_decoder_delete(decoder);
- clean_callback_info(info);
-}
-
-bool_t flac_is_our_fd(const char *filename, VFSFile *fd)
-{
- AUDDBG("Probe for FLAC.\n");
-
- if (!fd)
- return FALSE;
-
- char buf[4];
- if (vfs_fread (buf, 1, sizeof buf, fd) != sizeof buf)
- return FALSE;
-
- return ! strncmp (buf, "fLaC", sizeof buf);
-}
-
-static void squeeze_audio(int32_t* src, void* dst, unsigned count, unsigned res)
-{
- int i;
- int32_t* rp = src;
- int8_t* wp = dst;
- int16_t* wp2 = dst;
- int32_t* wp4 = dst;
-
- switch (res)
- {
- case 8:
- for (i = 0; i < count; i++, wp++, rp++)
- *wp = *rp & 0xff;
- break;
-
- case 16:
- for (i = 0; i < count; i++, wp2++, rp++)
- *wp2 = *rp & 0xffff;
- break;
-
- case 24:
- case 32:
- for (i = 0; i < count; i++, wp4++, rp++)
- *wp4 = *rp;
- break;
-
- default:
- FLACNG_ERROR("Can not convert to %u bps\n", res);
- }
-}
-
-static bool_t flac_play (const char * filename, VFSFile * file)
-{
- if (!file)
- return FALSE;
-
- void * play_buffer = NULL;
- bool_t error = FALSE;
-
- info->fd = file;
-
- if (read_metadata(decoder, info) == FALSE)
- {
- FLACNG_ERROR("Could not prepare file for playing!\n");
- error = TRUE;
- goto ERR_NO_CLOSE;
- }
-
- play_buffer = g_malloc (BUFFER_SIZE_BYTE);
-
- if (! aud_input_open_audio (SAMPLE_FMT (info->bits_per_sample),
- info->sample_rate, info->channels))
- {
- error = TRUE;
- goto ERR_NO_CLOSE;
- }
-
- aud_input_set_bitrate(info->bitrate);
-
- while (FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_END_OF_STREAM)
- {
- if (aud_input_check_stop ())
- break;
-
- int seek_value = aud_input_check_seek ();
- if (seek_value >= 0)
- FLAC__stream_decoder_seek_absolute (decoder, (int64_t)
- seek_value * info->sample_rate / 1000);
-
- /* Try to decode a single frame of audio */
- if (FLAC__stream_decoder_process_single(decoder) == FALSE)
- {
- FLACNG_ERROR("Error while decoding!\n");
- error = TRUE;
- break;
- }
-
- squeeze_audio(info->output_buffer, play_buffer, info->buffer_used, info->bits_per_sample);
- aud_input_write_audio(play_buffer, info->buffer_used * SAMPLE_SIZE(info->bits_per_sample));
-
- reset_info(info);
- }
-
-ERR_NO_CLOSE:
- g_free (play_buffer);
- reset_info(info);
-
- if (FLAC__stream_decoder_flush(decoder) == FALSE)
- FLACNG_ERROR("Could not flush decoder state!\n");
-
- return ! error;
-}
-
-static const char flac_about[] =
- N_("Original code by\n"
- "Ralf Ertzinger <ralf at skytale.net>\n\n"
- "http://www.skytale.net/projects/bmp-flac2/");
-
-static const char *flac_fmts[] = { "flac", "fla", NULL };
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("FLAC Decoder"),
- .domain = PACKAGE,
- .about_text = flac_about,
- .init = flac_init,
- .cleanup = flac_cleanup,
- .play = flac_play,
- .probe_for_tuple = flac_probe_for_tuple,
- .is_our_file_from_vfs = flac_is_our_fd,
- .extensions = flac_fmts,
- .update_song_tuple = flac_update_song_tuple,
- .get_song_image = flac_get_image,
- .priority = 1
-)
diff --git a/src/flacng/plugin.cc b/src/flacng/plugin.cc
new file mode 100644
index 000000000000..444e2b4a4ee8
--- /dev/null
+++ b/src/flacng/plugin.cc
@@ -0,0 +1,173 @@
+/*
+ * A FLAC decoder plugin for the Audacious Media Player
+ * Copyright (C) 2005 Ralf Ertzinger
+ * Copyright (C) 2010-2012 MichaÅ Lipski
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <string.h>
+
+#include <libaudcore/runtime.h>
+
+#include "flacng.h"
+
+EXPORT FLACng aud_plugin_instance;
+
+static FLAC__StreamDecoder *decoder;
+static callback_info *cinfo;
+
+bool FLACng::init()
+{
+ FLAC__StreamDecoderInitStatus ret;
+
+ /* Callback structure and decoder for main decoding loop */
+
+ cinfo = new callback_info;
+
+ if ((decoder = FLAC__stream_decoder_new()) == nullptr)
+ {
+ AUDERR("Could not create the main FLAC decoder instance!\n");
+ return false;
+ }
+
+ if (FLAC__STREAM_DECODER_INIT_STATUS_OK != (ret = FLAC__stream_decoder_init_stream(
+ decoder,
+ read_callback,
+ seek_callback,
+ tell_callback,
+ length_callback,
+ eof_callback,
+ write_callback,
+ metadata_callback,
+ error_callback,
+ cinfo)))
+ {
+ AUDERR("Could not initialize the main FLAC decoder: %s(%d)\n",
+ FLAC__StreamDecoderInitStatusString[ret], ret);
+ return false;
+ }
+
+ AUDDBG("Plugin initialized.\n");
+ return true;
+}
+
+void FLACng::cleanup()
+{
+ FLAC__stream_decoder_delete(decoder);
+ delete cinfo;
+}
+
+bool FLACng::is_our_file(const char *filename, VFSFile &file)
+{
+ AUDDBG("Probe for FLAC.\n");
+
+ char buf[4];
+ if (file.fread (buf, 1, sizeof buf) != sizeof buf)
+ return false;
+
+ return ! strncmp (buf, "fLaC", sizeof buf);
+}
+
+static void squeeze_audio(int32_t* src, void* dst, unsigned count, unsigned res)
+{
+ int32_t* rp = src;
+ int8_t* wp = (int8_t*) dst;
+ int16_t* wp2 = (int16_t*) dst;
+ int32_t* wp4 = (int32_t*) dst;
+
+ switch (res)
+ {
+ case 8:
+ for (unsigned i = 0; i < count; i++, wp++, rp++)
+ *wp = *rp & 0xff;
+ break;
+
+ case 16:
+ for (unsigned i = 0; i < count; i++, wp2++, rp++)
+ *wp2 = *rp & 0xffff;
+ break;
+
+ case 24:
+ case 32:
+ for (unsigned i = 0; i < count; i++, wp4++, rp++)
+ *wp4 = *rp;
+ break;
+
+ default:
+ AUDERR("Can not convert to %u bps\n", res);
+ }
+}
+
+bool FLACng::play(const char *filename, VFSFile &file)
+{
+ Index<char> play_buffer;
+ bool error = false;
+
+ cinfo->fd = &file;
+
+ if (read_metadata(decoder, cinfo) == false)
+ {
+ AUDERR("Could not prepare file for playing!\n");
+ error = true;
+ goto ERR_NO_CLOSE;
+ }
+
+ play_buffer.resize(BUFFER_SIZE_BYTE);
+
+ set_stream_bitrate(cinfo->bitrate);
+ open_audio(SAMPLE_FMT(cinfo->bits_per_sample), cinfo->sample_rate, cinfo->channels);
+
+ while (FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_END_OF_STREAM)
+ {
+ if (check_stop ())
+ break;
+
+ int seek_value = check_seek ();
+ if (seek_value >= 0)
+ FLAC__stream_decoder_seek_absolute (decoder, (int64_t)
+ seek_value * cinfo->sample_rate / 1000);
+
+ /* Try to decode a single frame of audio */
+ if (FLAC__stream_decoder_process_single(decoder) == false)
+ {
+ AUDERR("Error while decoding!\n");
+ error = true;
+ break;
+ }
+
+ squeeze_audio(cinfo->output_buffer.begin(), play_buffer.begin(),
+ cinfo->buffer_used, cinfo->bits_per_sample);
+ write_audio(play_buffer.begin(), cinfo->buffer_used *
+ SAMPLE_SIZE(cinfo->bits_per_sample));
+
+ cinfo->reset();
+ }
+
+ERR_NO_CLOSE:
+ cinfo->reset();
+
+ if (FLAC__stream_decoder_flush(decoder) == false)
+ AUDERR("Could not flush decoder state!\n");
+
+ return ! error;
+}
+
+const char FLACng::about[] =
+ N_("Original code by\n"
+ "Ralf Ertzinger <ralf at skytale.net>\n\n"
+ "http://www.skytale.net/projects/bmp-flac2/");
+
+const char *const FLACng::exts[] = { "flac", "fla", nullptr };
diff --git a/src/flacng/seekable_stream_callbacks.c b/src/flacng/seekable_stream_callbacks.c
deleted file mode 100644
index 4a93e9fbb5f2..000000000000
--- a/src/flacng/seekable_stream_callbacks.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * A FLAC decoder plugin for the Audacious Media Player
- * Copyright (C) 2005 Ralf Ertzinger
- * Copyright (C) 2010-2012 MichaÅ Lipski
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <string.h>
-#include <FLAC/all.h>
-
-#include <audacious/debug.h>
-
-#include "flacng.h"
-
-FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
-{
- callback_info* info = (callback_info*) client_data;
- size_t read;
-
- if (info->fd == NULL)
- {
- FLACNG_ERROR("Trying to read data from an uninitialized file!\n");
- return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
- }
-
- if (*bytes == 0)
- return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
-
- read = vfs_fread(buffer, 1, *bytes, info->fd);
- *bytes = read;
-
- switch (read)
- {
- case -1:
- FLACNG_ERROR("Error while reading from stream!\n");
- return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
-
- case 0:
- AUDDBG("Stream reached EOF\n");
- return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
-
- default:
- return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
- }
-}
-
-FLAC__StreamDecoderSeekStatus seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 offset, void *client_data)
-{
- callback_info *info = (callback_info*) client_data;
-
- if (vfs_fseek(info->fd, offset, SEEK_SET) != 0)
- {
- FLACNG_ERROR("Could not seek to %ld!\n", (long)offset);
- return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
- }
-
- return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
-}
-
-FLAC__StreamDecoderTellStatus tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *offset, void *client_data)
-{
- callback_info *info = (callback_info*) client_data;
-
- if ((*offset = vfs_ftell(info->fd)) == -1)
- {
- FLACNG_ERROR("Could not tell current position!\n");
- return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
- }
-
- AUDDBG ("Current position: %d\n", (int) * offset);
-
- return FLAC__STREAM_DECODER_TELL_STATUS_OK;
-}
-
-FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
-{
- callback_info *info = (callback_info*) client_data;
- return vfs_feof(info->fd);
-}
-
-FLAC__StreamDecoderLengthStatus length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *length, void *client_data)
-{
- callback_info *info = (callback_info*) client_data;
-
- if ((*length = vfs_fsize(info->fd)) == -1)
- {
- /*
- * Could not get the stream size. This is not necessarily an
- * error, maybe the stream has no fixed size (think streaming
- * audio)
- */
- AUDDBG("Stream length is unknown.\n");
- *length = 0;
- return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
- }
-
- AUDDBG ("Stream length is %d bytes\n", (int) * length);
-
- return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
-}
-
-FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data)
-{
- callback_info *info = (callback_info*) client_data;
-
- if (info->channels != frame->header.channels ||
- info->sample_rate != frame->header.sample_rate)
- {
- return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
- }
-
- for (long sample = 0; sample < frame->header.blocksize; sample++)
- {
- for (short channel = 0; channel < frame->header.channels; channel++)
- {
- *(info->write_pointer++) = buffer[channel][sample];
- info->buffer_used += 1;
- }
- }
-
- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
-}
-
-void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
-{
- FLACNG_ERROR("FLAC decoder error callback was called: %d\n", status);
-}
-
-void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
-{
- callback_info *info = (callback_info*) client_data;
- int64_t size;
-
- if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO)
- {
- info->total_samples = metadata->data.stream_info.total_samples;
- AUDDBG("total_total_samples=%ld\n", (long) metadata->data.stream_info.total_samples);
-
- info->bits_per_sample = metadata->data.stream_info.bits_per_sample;
- AUDDBG("bits_per_sample=%d\n", metadata->data.stream_info.bits_per_sample);
-
- info->channels = metadata->data.stream_info.channels;
- AUDDBG("channels=%d\n", metadata->data.stream_info.channels);
-
- info->sample_rate = metadata->data.stream_info.sample_rate;
- AUDDBG("sample_rate=%d\n", metadata->data.stream_info.sample_rate);
-
- size = vfs_fsize(info->fd);
-
- if (size == -1 || info->total_samples == 0)
- info->bitrate = 0;
- else
- info->bitrate = 8 * size * (int64_t) info->sample_rate / info->total_samples;
-
- AUDDBG("bitrate=%d\n", info->bitrate);
- }
-}
diff --git a/src/flacng/seekable_stream_callbacks.cc b/src/flacng/seekable_stream_callbacks.cc
new file mode 100644
index 000000000000..8b3e7aaa505b
--- /dev/null
+++ b/src/flacng/seekable_stream_callbacks.cc
@@ -0,0 +1,173 @@
+/*
+ * A FLAC decoder plugin for the Audacious Media Player
+ * Copyright (C) 2005 Ralf Ertzinger
+ * Copyright (C) 2010-2012 MichaÅ Lipski
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <string.h>
+#include <FLAC/all.h>
+
+#include <libaudcore/runtime.h>
+
+#include "flacng.h"
+
+FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
+{
+ callback_info* info = (callback_info*) client_data;
+ int64_t read;
+
+ if (*bytes == 0)
+ return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+
+ read = info->fd->fread (buffer, 1, *bytes);
+ *bytes = read;
+
+ switch (read)
+ {
+ case -1:
+ AUDERR("Error while reading from stream!\n");
+ return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
+
+ case 0:
+ AUDDBG("Stream reached EOF\n");
+ return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+
+ default:
+ return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
+ }
+}
+
+FLAC__StreamDecoderSeekStatus seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 offset, void *client_data)
+{
+ callback_info *info = (callback_info*) client_data;
+
+ if (info->fd->fseek (offset, VFS_SEEK_SET) != 0)
+ {
+ AUDERR("Could not seek to %ld!\n", (long)offset);
+ return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
+ }
+
+ return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
+}
+
+FLAC__StreamDecoderTellStatus tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *offset, void *client_data)
+{
+ callback_info *info = (callback_info*) client_data;
+
+ int64_t result = info->fd->ftell ();
+ if (result < 0)
+ {
+ AUDERR("Could not tell current position!\n");
+ return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
+ }
+
+ *offset = result;
+
+ AUDDBG ("Current position: %d\n", (int) * offset);
+
+ return FLAC__STREAM_DECODER_TELL_STATUS_OK;
+}
+
+FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
+{
+ callback_info *info = (callback_info*) client_data;
+ return info->fd->feof ();
+}
+
+FLAC__StreamDecoderLengthStatus length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *length, void *client_data)
+{
+ callback_info *info = (callback_info*) client_data;
+
+ int64_t result = info->fd->fsize ();
+ if (result < 0)
+ {
+ /*
+ * Could not get the stream size. This is not necessarily an
+ * error, maybe the stream has no fixed size (think streaming
+ * audio)
+ */
+ AUDDBG("Stream length is unknown.\n");
+ *length = 0;
+ return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
+ }
+
+ *length = result;
+
+ AUDDBG ("Stream length is %d bytes\n", (int) * length);
+
+ return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
+}
+
+FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data)
+{
+ callback_info *info = (callback_info*) client_data;
+
+ if (info->channels != frame->header.channels ||
+ info->sample_rate != frame->header.sample_rate)
+ {
+ return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+ }
+
+ if (!info->output_buffer.len())
+ info->alloc();
+
+ for (unsigned sample = 0; sample < frame->header.blocksize; sample++)
+ {
+ for (unsigned channel = 0; channel < frame->header.channels; channel++)
+ {
+ *(info->write_pointer++) = buffer[channel][sample];
+ info->buffer_used += 1;
+ }
+ }
+
+ return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+}
+
+void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
+{
+ AUDERR("FLAC decoder error callback was called: %d\n", status);
+}
+
+void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
+{
+ callback_info *info = (callback_info*) client_data;
+ int64_t size;
+
+ if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO)
+ {
+ info->total_samples = metadata->data.stream_info.total_samples;
+ AUDDBG("total_total_samples=%ld\n", (long) metadata->data.stream_info.total_samples);
+
+ info->bits_per_sample = metadata->data.stream_info.bits_per_sample;
+ AUDDBG("bits_per_sample=%d\n", metadata->data.stream_info.bits_per_sample);
+
+ info->channels = metadata->data.stream_info.channels;
+ AUDDBG("channels=%d\n", metadata->data.stream_info.channels);
+
+ info->sample_rate = metadata->data.stream_info.sample_rate;
+ AUDDBG("sample_rate=%d\n", metadata->data.stream_info.sample_rate);
+
+ size = info->fd->fsize ();
+
+ if (size == -1 || info->total_samples == 0)
+ info->bitrate = 0;
+ else
+ info->bitrate = 8 * size * (int64_t) info->sample_rate / info->total_samples;
+
+ AUDDBG("bitrate=%d\n", info->bitrate);
+ }
+}
diff --git a/src/flacng/tools.c b/src/flacng/tools.c
deleted file mode 100644
index 02db04bc3d18..000000000000
--- a/src/flacng/tools.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * A FLAC decoder plugin for the Audacious Media Player
- * Copyright (C) 2005 Ralf Ertzinger
- * Copyright (C) 2010 John Lindgren
- * Copyright (C) 2010-2012 MichaÅ Lipski
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <string.h>
-#include <glib.h>
-
-#include <audacious/debug.h>
-
-#include "flacng.h"
-
-callback_info *init_callback_info(void)
-{
- callback_info *info;
-
- info = g_new0 (callback_info, 1);
- info->output_buffer = g_malloc (BUFFER_SIZE_BYTE);
-
- reset_info(info);
-
- AUDDBG("Playback buffer allocated for %d samples, %d bytes\n", BUFFER_SIZE_SAMP, BUFFER_SIZE_BYTE);
-
- return info;
-}
-
-void clean_callback_info(callback_info *info)
-{
- g_free (info->output_buffer);
- g_free (info);
-}
-
-void reset_info(callback_info *info)
-{
- info->buffer_used = 0;
- info->write_pointer = info->output_buffer;
-}
-
-bool_t read_metadata(FLAC__StreamDecoder *decoder, callback_info *info)
-{
- FLAC__StreamDecoderState ret;
-
- reset_info(info);
-
- /* Reset the decoder */
- if (FLAC__stream_decoder_reset(decoder) == false)
- {
- FLACNG_ERROR("Could not reset the decoder!\n");
- return FALSE;
- }
-
- /* Try to decode the metadata */
- if (FLAC__stream_decoder_process_until_end_of_metadata(decoder) == false)
- {
- ret = FLAC__stream_decoder_get_state(decoder);
- AUDDBG("Could not read the metadata: %s(%d)!\n",
- FLAC__StreamDecoderStateString[ret], ret);
- reset_info(info);
- return FALSE;
- }
-
- return TRUE;
-}
diff --git a/src/flacng/tools.cc b/src/flacng/tools.cc
new file mode 100644
index 000000000000..e5c1a23acfc9
--- /dev/null
+++ b/src/flacng/tools.cc
@@ -0,0 +1,52 @@
+/*
+ * A FLAC decoder plugin for the Audacious Media Player
+ * Copyright (C) 2005 Ralf Ertzinger
+ * Copyright (C) 2010 John Lindgren
+ * Copyright (C) 2010-2012 MichaÅ Lipski
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <string.h>
+
+#include <libaudcore/runtime.h>
+
+#include "flacng.h"
+
+bool read_metadata(FLAC__StreamDecoder *decoder, callback_info *info)
+{
+ FLAC__StreamDecoderState ret;
+
+ info->reset();
+
+ /* Reset the decoder */
+ if (FLAC__stream_decoder_reset(decoder) == false)
+ {
+ AUDERR("Could not reset the decoder!\n");
+ return false;
+ }
+
+ /* Try to decode the metadata */
+ if (FLAC__stream_decoder_process_until_end_of_metadata(decoder) == false)
+ {
+ ret = FLAC__stream_decoder_get_state(decoder);
+ AUDDBG("Could not read the metadata: %s(%d)!\n",
+ FLAC__StreamDecoderStateString[ret], ret);
+ info->reset();
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/gio/Makefile b/src/gio/Makefile
index 6d0ebb9c0362..f491c09e5729 100644
--- a/src/gio/Makefile
+++ b/src/gio/Makefile
@@ -1,12 +1,14 @@
PLUGIN = gio${PLUGIN_SUFFIX}
-SRCS = gio.c
+SRCS = gio.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${TRANSPORT_PLUGIN_DIR}
+LD = ${CXX}
+
CPPFLAGS += -I../.. ${GIO_CFLAGS}
CFLAGS += ${PLUGIN_CFLAGS}
LIBS += ${GIO_LIBS}
diff --git a/src/gio/gio.c b/src/gio/gio.c
deleted file mode 100644
index 94273252d07a..000000000000
--- a/src/gio/gio.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * GIO Transport Plugin for Audacious
- * Copyright 2009-2012 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <gio/gio.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-typedef struct {
- GFile * file;
- GIOStream * iostream;
- GInputStream * istream;
- GOutputStream * ostream;
- GSeekable * seekable;
-} FileData;
-
-#define gio_error(...) do { \
- SPRINTF (gio_error_buf, __VA_ARGS__); \
- aud_interface_show_error (gio_error_buf); \
-} while (0)
-
-#define CHECK_ERROR(op, name) do { \
- if (error) { \
- gio_error ("Cannot %s %s: %s.", op, name, error->message); \
- g_error_free (error); \
- goto FAILED; \
- } \
-} while (0)
-
-static void * gio_fopen (const char * filename, const char * mode)
-{
- GError * error = 0;
-
- FileData * data = g_new0 (FileData, 1);
-
- data->file = g_file_new_for_uri (filename);
-
- switch (mode[0])
- {
- case 'r':
- if (strchr (mode, '+'))
- {
- data->iostream = (GIOStream *) g_file_open_readwrite (data->file, 0, & error);
- CHECK_ERROR ("open", filename);
- data->istream = g_io_stream_get_input_stream (data->iostream);
- data->ostream = g_io_stream_get_output_stream (data->iostream);
- data->seekable = (GSeekable *) data->iostream;
- }
- else
- {
- data->istream = (GInputStream *) g_file_read (data->file, 0, & error);
- CHECK_ERROR ("open", filename);
- data->seekable = (GSeekable *) data->istream;
- }
- break;
- case 'w':
- if (strchr (mode, '+'))
- {
- data->iostream = (GIOStream *) g_file_replace_readwrite (data->file, 0, 0, 0, 0, & error);
- CHECK_ERROR ("open", filename);
- data->istream = g_io_stream_get_input_stream (data->iostream);
- data->ostream = g_io_stream_get_output_stream (data->iostream);
- data->seekable = (GSeekable *) data->iostream;
- }
- else
- {
- data->ostream = (GOutputStream *) g_file_replace (data->file, 0, 0, 0, 0, & error);
- CHECK_ERROR ("open", filename);
- data->seekable = (GSeekable *) data->ostream;
- }
- break;
- case 'a':
- if (strchr (mode, '+'))
- {
- gio_error ("Cannot open %s: GIO does not support read-and-append mode.", filename);
- goto FAILED;
- }
- else
- {
- data->ostream = (GOutputStream *) g_file_append_to (data->file, 0, 0, & error);
- CHECK_ERROR ("open", filename);
- data->seekable = (GSeekable *) data->ostream;
- }
- break;
- default:
- gio_error ("Cannot open %s: invalid mode.", filename);
- goto FAILED;
- }
-
- return data;
-
-FAILED:
- g_free (data);
- return 0;
-}
-
-static int gio_fclose (VFSFile * file)
-{
- FileData * data = vfs_get_handle (file);
- GError * error = 0;
-
- if (data->iostream)
- {
- g_io_stream_close (data->iostream, 0, & error);
- g_object_unref (data->iostream);
- CHECK_ERROR ("close", vfs_get_filename (file));
- }
- else if (data->istream)
- {
- g_input_stream_close (data->istream, 0, & error);
- g_object_unref (data->istream);
- CHECK_ERROR ("close", vfs_get_filename (file));
- }
- else if (data->ostream)
- {
- g_output_stream_close (data->ostream, 0, & error);
- g_object_unref (data->ostream);
- CHECK_ERROR ("close", vfs_get_filename (file));
- }
-
- if (data->file)
- g_object_unref (data->file);
-
- return 0;
-
-FAILED:
- if (data->file)
- g_object_unref (data->file);
-
- return -1;
-}
-
-static int64_t gio_fread (void * buf, int64_t size, int64_t nitems, VFSFile * file)
-{
- FileData * data = vfs_get_handle (file);
- GError * error = 0;
-
- if (! data->istream)
- {
- gio_error ("Cannot read from %s: not open for reading.", vfs_get_filename (file));
- return 0;
- }
-
- int64_t readed = g_input_stream_read (data->istream, buf, size * nitems, 0, & error);
- CHECK_ERROR ("read from", vfs_get_filename (file));
-
- return (size > 0) ? readed / size : 0;
-
-FAILED:
- return 0;
-}
-
-static int64_t gio_fwrite (const void * buf, int64_t size, int64_t nitems, VFSFile * file)
-{
- FileData * data = vfs_get_handle (file);
- GError * error = 0;
-
- if (! data->ostream)
- {
- gio_error ("Cannot write to %s: not open for writing.", vfs_get_filename (file));
- return 0;
- }
-
- int64_t written = g_output_stream_write (data->ostream, buf, size * nitems, 0, & error);
- CHECK_ERROR ("write to", vfs_get_filename (file));
-
- return (size > 0) ? written / size : 0;
-
-FAILED:
- return 0;
-}
-
-static int gio_fseek (VFSFile * file, int64_t offset, int whence)
-{
- FileData * data = vfs_get_handle (file);
- GError * error = 0;
- GSeekType gwhence;
-
- switch (whence)
- {
- case SEEK_SET:
- gwhence = G_SEEK_SET;
- break;
- case SEEK_CUR:
- gwhence = G_SEEK_CUR;
- break;
- case SEEK_END:
- gwhence = G_SEEK_END;
- break;
- default:
- gio_error ("Cannot seek within %s: invalid whence.", vfs_get_filename (file));
- return -1;
- }
-
- g_seekable_seek (data->seekable, offset, gwhence, NULL, & error);
- CHECK_ERROR ("seek within", vfs_get_filename (file));
-
- return 0;
-
-FAILED:
- return -1;
-}
-
-static int64_t gio_ftell (VFSFile * file)
-{
- FileData * data = vfs_get_handle (file);
- return g_seekable_tell (data->seekable);
-}
-
-static int gio_getc (VFSFile * file)
-{
- unsigned char c;
- return (gio_fread (& c, 1, 1, file) == 1) ? c : -1;
-}
-
-static int gio_ungetc (int c, VFSFile * file)
-{
- return (! gio_fseek (file, -1, SEEK_CUR)) ? c : -1;
-}
-
-static bool_t gio_feof (VFSFile * file)
-{
- int test = gio_getc (file);
-
- if (test < 0)
- return TRUE;
-
- gio_ungetc (test, file);
- return FALSE;
-}
-
-static int gio_ftruncate (VFSFile * file, int64_t length)
-{
- FileData * data = vfs_get_handle (file);
- GError * error = 0;
-
- g_seekable_truncate (data->seekable, length, NULL, & error);
- CHECK_ERROR ("truncate", vfs_get_filename (file));
-
- return 0;
-
-FAILED:
- return -1;
-}
-
-static int64_t gio_fsize (VFSFile * file)
-{
- FileData * data = vfs_get_handle (file);
- GError * error = 0;
-
- /* Audacious core expects one of two cases:
- * 1) File size is known and file is seekable.
- * 2) File size is unknown and file is not seekable.
- * Therefore, we return -1 for size if file is not seekable. */
- if (! g_seekable_can_seek (data->seekable))
- return -1;
-
- GFileInfo * info = g_file_query_info (data->file,
- G_FILE_ATTRIBUTE_STANDARD_SIZE, 0, 0, & error);
- CHECK_ERROR ("get size of", vfs_get_filename (file));
-
- int64_t size = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
-
- g_object_unref (info);
- return size;
-
-FAILED:
- return -1;
-}
-
-static const char gio_about[] =
- N_("GIO Plugin for Audacious\n"
- "Copyright 2009-2012 John Lindgren");
-
-static const char * const gio_schemes[] = {"ftp", "sftp", "smb", 0};
-
-static VFSConstructor constructor = {
- .vfs_fopen_impl = gio_fopen,
- .vfs_fclose_impl = gio_fclose,
- .vfs_fread_impl = gio_fread,
- .vfs_fwrite_impl = gio_fwrite,
- .vfs_fseek_impl = gio_fseek,
- .vfs_ftell_impl = gio_ftell,
- .vfs_feof_impl = gio_feof,
- .vfs_ftruncate_impl = gio_ftruncate,
- .vfs_fsize_impl = gio_fsize
-};
-
-AUD_TRANSPORT_PLUGIN
-(
- .name = N_("GIO Plugin"),
- .domain = PACKAGE,
- .about_text = gio_about,
- .schemes = gio_schemes,
- .vtable = & constructor
-)
diff --git a/src/gio/gio.cc b/src/gio/gio.cc
new file mode 100644
index 000000000000..0d3d3fd2655a
--- /dev/null
+++ b/src/gio/gio.cc
@@ -0,0 +1,388 @@
+/*
+ * GIO Transport Plugin for Audacious
+ * Copyright 2009-2012 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gio/gio.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+
+static const char gio_about[] =
+ N_("GIO Plugin for Audacious\n"
+ "Copyright 2009-2012 John Lindgren");
+
+static const char * const gio_schemes[] = {"ftp", "sftp", "smb"};
+
+class GIOTransport : public TransportPlugin
+{
+public:
+ static constexpr PluginInfo info = {N_("GIO Plugin"), PACKAGE, gio_about};
+
+ constexpr GIOTransport () : TransportPlugin (info, gio_schemes) {}
+
+ VFSImpl * fopen (const char * path, const char * mode, String & error);
+};
+
+EXPORT GIOTransport aud_plugin_instance;
+
+class GIOFile : public VFSImpl
+{
+public:
+ GIOFile (const char * filename, const char * mode);
+ ~GIOFile ();
+
+ // exception
+ struct OpenError {
+ String error;
+ };
+
+protected:
+ int64_t fread (void * ptr, int64_t size, int64_t nmemb);
+ int64_t fwrite (const void * buf, int64_t size, int64_t nitems);
+
+ int fseek (int64_t offset, VFSSeekType whence);
+ int64_t ftell ();
+
+ int getc ();
+ int ungetc (int c);
+
+ bool feof ();
+
+ int ftruncate (int64_t length);
+ int64_t fsize ();
+
+ int fflush ();
+
+private:
+ String m_filename;
+ GFile * m_file = nullptr;
+ GIOStream * m_iostream = nullptr;
+ GInputStream * m_istream = nullptr;
+ GOutputStream * m_ostream = nullptr;
+ GSeekable * m_seekable = nullptr;
+};
+
+#define CHECK_ERROR(op, name) do { \
+ if (error) { \
+ AUDERR ("Cannot %s %s: %s.\n", op, (const char *) name, error->message); \
+ g_error_free (error); \
+ goto FAILED; \
+ } \
+} while (0)
+
+#define CHECK_AND_SAVE_ERROR(op, name) do { \
+ if (error) { \
+ AUDERR ("Cannot %s %s: %s.\n", op, (const char *) name, error->message); \
+ errorstr = String (error->message); \
+ g_error_free (error); \
+ goto FAILED; \
+ } \
+} while (0)
+
+GIOFile::GIOFile (const char * filename, const char * mode) :
+ m_filename (filename)
+{
+ GError * error = nullptr;
+ String errorstr;
+
+ m_file = g_file_new_for_uri (filename);
+
+ switch (mode[0])
+ {
+ case 'r':
+ if (strchr (mode, '+'))
+ {
+ m_iostream = (GIOStream *) g_file_open_readwrite (m_file, 0, & error);
+ CHECK_AND_SAVE_ERROR ("open", filename);
+ m_istream = g_io_stream_get_input_stream (m_iostream);
+ m_ostream = g_io_stream_get_output_stream (m_iostream);
+ m_seekable = (GSeekable *) m_iostream;
+ }
+ else
+ {
+ m_istream = (GInputStream *) g_file_read (m_file, 0, & error);
+ CHECK_AND_SAVE_ERROR ("open", filename);
+ m_seekable = (GSeekable *) m_istream;
+ }
+ break;
+ case 'w':
+ if (strchr (mode, '+'))
+ {
+ m_iostream = (GIOStream *) g_file_replace_readwrite (m_file,
+ 0, 0, (GFileCreateFlags) 0, 0, & error);
+ CHECK_AND_SAVE_ERROR ("open", filename);
+ m_istream = g_io_stream_get_input_stream (m_iostream);
+ m_ostream = g_io_stream_get_output_stream (m_iostream);
+ m_seekable = (GSeekable *) m_iostream;
+ }
+ else
+ {
+ m_ostream = (GOutputStream *) g_file_replace (m_file, 0, 0,
+ (GFileCreateFlags) 0, 0, & error);
+ CHECK_AND_SAVE_ERROR ("open", filename);
+ m_seekable = (GSeekable *) m_ostream;
+ }
+ break;
+ case 'a':
+ if (strchr (mode, '+'))
+ {
+ AUDERR ("Cannot open %s: GIO does not support read-and-append mode.\n", filename);
+ errorstr = String (_("Read-and-append mode not supported"));
+ goto FAILED;
+ }
+ else
+ {
+ m_ostream = (GOutputStream *) g_file_append_to (m_file,
+ (GFileCreateFlags) 0, 0, & error);
+ CHECK_AND_SAVE_ERROR ("open", filename);
+ m_seekable = (GSeekable *) m_ostream;
+ }
+ break;
+ default:
+ AUDERR ("Cannot open %s: invalid mode.\n", filename);
+ errorstr = String (_("Invalid open mode"));
+ goto FAILED;
+ }
+
+ return;
+
+FAILED:
+ g_object_unref (m_file);
+ throw OpenError {errorstr};
+}
+
+GIOFile::~GIOFile ()
+{
+ GError * error = 0;
+
+ if (m_iostream)
+ {
+ g_io_stream_close (m_iostream, 0, & error);
+ g_object_unref (m_iostream);
+ CHECK_ERROR ("close", m_filename);
+ }
+ else if (m_istream)
+ {
+ g_input_stream_close (m_istream, 0, & error);
+ g_object_unref (m_istream);
+ CHECK_ERROR ("close", m_filename);
+ }
+ else if (m_ostream)
+ {
+ g_output_stream_close (m_ostream, 0, & error);
+ g_object_unref (m_ostream);
+ CHECK_ERROR ("close", m_filename);
+ }
+
+FAILED:
+ g_object_unref (m_file);
+}
+
+VFSImpl * GIOTransport::fopen (const char * filename, const char * mode, String & error)
+{
+#if ! GLIB_CHECK_VERSION (2, 36, 0)
+ g_type_init ();
+#endif
+
+ try { return new GIOFile (filename, mode); }
+ catch (GIOFile::OpenError & ex)
+ {
+ error = std::move (ex.error);
+ return nullptr;
+ }
+}
+
+int64_t GIOFile::fread (void * buf, int64_t size, int64_t nitems)
+{
+ GError * error = 0;
+
+ if (! m_istream)
+ {
+ AUDERR ("Cannot read from %s: not open for reading.\n", (const char *) m_filename);
+ return 0;
+ }
+
+ int64_t total = 0;
+ int64_t remain = size * nitems;
+
+ while (remain > 0)
+ {
+ int64_t part = g_input_stream_read (m_istream, buf, remain, 0, & error);
+ CHECK_ERROR ("read from", m_filename);
+
+ if (part <= 0)
+ break;
+
+ buf = (char *) buf + part;
+ total += part;
+ remain -= part;
+ }
+
+FAILED:
+ return (size > 0) ? total / size : 0;
+}
+
+int64_t GIOFile::fwrite (const void * buf, int64_t size, int64_t nitems)
+{
+ GError * error = 0;
+
+ if (! m_ostream)
+ {
+ AUDERR ("Cannot write to %s: not open for writing.\n", (const char *) m_filename);
+ return 0;
+ }
+
+ int64_t total = 0;
+ int64_t remain = size * nitems;
+
+ while (remain > 0)
+ {
+ int64_t part = g_output_stream_write (m_ostream, buf, remain, 0, & error);
+ CHECK_ERROR ("write to", m_filename);
+
+ if (part <= 0)
+ break;
+
+ buf = (const char *) buf + part;
+ total += part;
+ remain -= part;
+ }
+
+FAILED:
+ return (size > 0) ? total / size : 0;
+}
+
+int GIOFile::fseek (int64_t offset, VFSSeekType whence)
+{
+ GError * error = 0;
+ GSeekType gwhence;
+
+ switch (whence)
+ {
+ case VFS_SEEK_SET:
+ gwhence = G_SEEK_SET;
+ break;
+ case VFS_SEEK_CUR:
+ gwhence = G_SEEK_CUR;
+ break;
+ case VFS_SEEK_END:
+ gwhence = G_SEEK_END;
+ break;
+ default:
+ AUDERR ("Cannot seek within %s: invalid whence.\n", (const char *) m_filename);
+ return -1;
+ }
+
+ g_seekable_seek (m_seekable, offset, gwhence, nullptr, & error);
+ CHECK_ERROR ("seek within", m_filename);
+
+ return 0;
+
+FAILED:
+ return -1;
+}
+
+int64_t GIOFile::ftell ()
+{
+ return g_seekable_tell (m_seekable);
+}
+
+int GIOFile::getc ()
+{
+ unsigned char c;
+ return (fread (& c, 1, 1) == 1) ? c : -1;
+}
+
+int GIOFile::ungetc (int c)
+{
+ return (! fseek (-1, VFS_SEEK_CUR)) ? c : -1;
+}
+
+bool GIOFile::feof ()
+{
+ int test = getc ();
+
+ if (test < 0)
+ return TRUE;
+
+ ungetc (test);
+ return FALSE;
+}
+
+int GIOFile::ftruncate (int64_t length)
+{
+ GError * error = 0;
+
+ g_seekable_truncate (m_seekable, length, nullptr, & error);
+ CHECK_ERROR ("truncate", m_filename);
+
+ return 0;
+
+FAILED:
+ return -1;
+}
+
+int64_t GIOFile::fsize ()
+{
+ GError * error = 0;
+ int64_t size;
+
+ /* Audacious core expects one of two cases:
+ * 1) File size is known and file is seekable.
+ * 2) File size is unknown and file is not seekable.
+ * Therefore, we return -1 for size if file is not seekable. */
+ if (! g_seekable_can_seek (m_seekable))
+ return -1;
+
+ GFileInfo * info = g_file_query_info (m_file,
+ G_FILE_ATTRIBUTE_STANDARD_SIZE, (GFileQueryInfoFlags) 0, 0, & error);
+ CHECK_ERROR ("get size of", m_filename);
+
+ size = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
+
+ g_object_unref (info);
+ return size;
+
+FAILED:
+ return -1;
+}
+
+int GIOFile::fflush ()
+{
+ int result;
+ GError * error = nullptr;
+
+ if (! m_ostream)
+ return 0; /* no-op */
+
+ result = g_output_stream_flush (m_ostream, nullptr, & error);
+ CHECK_ERROR ("flush", m_filename);
+
+ return result;
+
+FAILED:
+ return -1;
+}
diff --git a/src/gl-spectrum-qt/Makefile b/src/gl-spectrum-qt/Makefile
new file mode 100644
index 000000000000..c4abd2be6f88
--- /dev/null
+++ b/src/gl-spectrum-qt/Makefile
@@ -0,0 +1,13 @@
+PLUGIN = gl-spectrum-qt${PLUGIN_SUFFIX}
+
+SRCS = gl-spectrum.cc
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+plugindir := ${plugindir}/${VISUALIZATION_PLUGIN_DIR}
+
+LD = ${CXX}
+CFLAGS += ${PLUGIN_CFLAGS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../.. ${QTOPENGL_CFLAGS} ${GL_CFLAGS}
+LIBS += -lm ${QTOPENGL_LIBS} ${GL_LIBS}
diff --git a/src/gl-spectrum-qt/gl-spectrum.cc b/src/gl-spectrum-qt/gl-spectrum.cc
new file mode 100644
index 000000000000..f081f25a6fff
--- /dev/null
+++ b/src/gl-spectrum-qt/gl-spectrum.cc
@@ -0,0 +1,292 @@
+/*
+ * OpenGL Spectrum Analyzer for Audacious
+ * Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini
+ * Copyright 2014 William Pitcock
+ *
+ * Based on the XMMS plugin:
+ * Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and
+ * 4Front Technologies
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+#include <string.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+
+#include <QGLWidget>
+#include <QGLFunctions>
+
+#define NUM_BANDS 32
+#define DB_RANGE 40
+
+#define BAR_SPACING (3.2f / NUM_BANDS)
+#define BAR_WIDTH (0.8f * BAR_SPACING)
+
+static const char gl_about[] =
+ N_("OpenGL Spectrum Analyzer for Audacious\n"
+ "Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n"
+ "Copyright 2014 William Pitcock\n\n"
+ "Based on the XMMS plugin:\n"
+ "Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, "
+ "and 4Front Technologies\n\n"
+ "License: GPLv2+");
+
+class GLSpectrumQt : public VisPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("OpenGL Spectrum Analyzer (Qt)"),
+ PACKAGE,
+ gl_about
+ };
+
+ constexpr GLSpectrumQt () : VisPlugin (info, Visualizer::Freq) {}
+
+ bool init ();
+
+ void * get_qt_widget ();
+
+ void clear ();
+ void render_freq (const float * freq);
+};
+
+EXPORT GLSpectrumQt aud_plugin_instance;
+
+static float logscale[NUM_BANDS + 1];
+static float colors[NUM_BANDS][NUM_BANDS][3];
+
+static int s_pos = 0;
+static float s_angle = 25, s_anglespeed = 0.05f;
+static float s_bars[NUM_BANDS][NUM_BANDS];
+
+class GLSpectrumWidget : public QGLWidget, protected QGLFunctions
+{
+public:
+ GLSpectrumWidget (QWidget *parent = nullptr);
+ ~GLSpectrumWidget ();
+
+private:
+ void paintGL ();
+ void resizeGL (int w, int h);
+};
+
+GLSpectrumWidget * s_widget = nullptr;
+
+bool GLSpectrumQt::init ()
+{
+ for (int i = 0; i <= NUM_BANDS; i ++)
+ logscale[i] = powf (256, (float) i / NUM_BANDS) - 0.5f;
+
+ for (int y = 0; y < NUM_BANDS; y ++)
+ {
+ float yf = (float) y / (NUM_BANDS - 1);
+
+ for (int x = 0; x < NUM_BANDS; x ++)
+ {
+ float xf = (float) x / (NUM_BANDS - 1);
+
+ colors[x][y][0] = (1 - xf) * (1 - yf);
+ colors[x][y][1] = xf;
+ colors[x][y][2] = yf;
+ }
+ }
+
+ return true;
+}
+
+/* stolen from the skins plugin */
+/* convert linear frequency graph to logarithmic one */
+static void make_log_graph (const float * freq, float * graph)
+{
+ for (int i = 0; i < NUM_BANDS; i ++)
+ {
+ /* sum up values in freq array between logscale[i] and logscale[i + 1],
+ including fractional parts */
+ int a = ceilf (logscale[i]);
+ int b = floorf (logscale[i + 1]);
+ float sum = 0;
+
+ if (b < a)
+ sum += freq[b] * (logscale[i + 1] - logscale[i]);
+ else
+ {
+ if (a > 0)
+ sum += freq[a - 1] * (a - logscale[i]);
+ for (; a < b; a ++)
+ sum += freq[a];
+ if (b < 256)
+ sum += freq[b] * (logscale[i + 1] - b);
+ }
+
+ /* fudge factor to make the graph have the same overall height as a
+ 12-band one no matter how many bands there are */
+ sum *= (float) NUM_BANDS / 12;
+
+ /* convert to dB */
+ float val = 20 * log10f (sum);
+
+ /* scale (-DB_RANGE, 0.0) to (0.0, 1.0) */
+ val = 1 + val / DB_RANGE;
+
+ graph[i] = aud::clamp (val, 0.0f, 1.0f);
+ }
+}
+
+void GLSpectrumQt::render_freq (const float * freq)
+{
+ make_log_graph (freq, s_bars[s_pos]);
+ s_pos = (s_pos + 1) % NUM_BANDS;
+
+ s_angle += s_anglespeed;
+ if (s_angle > 45 || s_angle < -45)
+ s_anglespeed = -s_anglespeed;
+
+ if (s_widget)
+ s_widget->updateGL ();
+}
+
+void GLSpectrumQt::clear ()
+{
+#ifdef XXX_NOTYET
+ memset (s_bars, 0, sizeof s_bars);
+
+ if (s_widget)
+ s_widget->updateGL ();
+#endif
+}
+
+static void draw_rectangle (float x1, float y1, float z1, float x2, float y2,
+ float z2, float r, float g, float b)
+{
+ glColor3f (r, g, b);
+
+ glBegin (GL_POLYGON);
+ glVertex3f (x1, y2, z1);
+ glVertex3f (x2, y2, z1);
+ glVertex3f (x2, y2, z2);
+ glVertex3f (x1, y2, z2);
+ glEnd ();
+
+ glColor3f (0.65f * r, 0.65f * g, 0.65f * b);
+
+ glBegin (GL_POLYGON);
+ glVertex3f (x1, y1, z1);
+ glVertex3f (x1, y2, z1);
+ glVertex3f (x1, y2, z2);
+ glVertex3f (x1, y1, z2);
+ glEnd ();
+
+ glBegin (GL_POLYGON);
+ glVertex3f (x2, y2, z1);
+ glVertex3f (x2, y1, z1);
+ glVertex3f (x2, y1, z2);
+ glVertex3f (x2, y2, z2);
+ glEnd ();
+
+ glColor3f (0.8f * r, 0.8f * g, 0.8f * b);
+
+ glBegin (GL_POLYGON);
+ glVertex3f (x1, y1, z1);
+ glVertex3f (x2, y1, z1);
+ glVertex3f (x2, y2, z1);
+ glVertex3f (x1, y2, z1);
+ glEnd ();
+}
+
+static void draw_bar (float x, float z, float h, float r, float g, float b)
+{
+ draw_rectangle (x, 0, z, x + BAR_WIDTH, h, z + BAR_WIDTH,
+ r * (0.2f + 0.8f * h), g * (0.2f + 0.8f * h), b * (0.2f + 0.8f * h));
+}
+
+static void draw_bars ()
+{
+ glPushMatrix ();
+ glTranslatef (0.0f, -0.5f, -5.0f);
+ glRotatef (38.0f, 1.0f, 0.0f, 0.0f);
+ glRotatef (s_angle + 180.0f, 0.0f, 1.0f, 0.0f);
+ glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
+
+ for (int i = 0; i < NUM_BANDS; i ++)
+ {
+ float z = -1.6f + (NUM_BANDS - i) * BAR_SPACING;
+
+ for (int j = 0; j < NUM_BANDS; j ++)
+ {
+ draw_bar (1.6f - BAR_SPACING * j, z,
+ s_bars[(s_pos + i) % NUM_BANDS][j] * 1.6,
+ colors[i][j][0], colors[i][j][1], colors[i][j][2]);
+ }
+ }
+
+ glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
+ glPopMatrix ();
+}
+
+GLSpectrumWidget::GLSpectrumWidget (QWidget * parent) : QGLWidget (parent)
+{
+ setObjectName ("GLSpectrumWidget");
+}
+
+GLSpectrumWidget::~GLSpectrumWidget ()
+{
+ s_widget = nullptr;
+}
+
+void GLSpectrumWidget::paintGL ()
+{
+ glDisable (GL_BLEND);
+ glMatrixMode (GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glFrustum (-1.1f, 1, -1.5f, 1, 2, 10);
+ glMatrixMode (GL_MODELVIEW);
+ glPushMatrix ();
+ glLoadIdentity ();
+ glEnable (GL_DEPTH_TEST);
+ glDepthFunc (GL_LESS);
+ glPolygonMode (GL_FRONT, GL_FILL);
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glClearColor (0, 0, 0, 1);
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ draw_bars ();
+
+ glPopMatrix ();
+ glMatrixMode (GL_PROJECTION);
+ glPopMatrix ();
+ glDisable (GL_DEPTH_TEST);
+ glDisable (GL_BLEND);
+ glDepthMask (GL_TRUE);
+}
+
+void GLSpectrumWidget::resizeGL (int w, int h)
+{
+ glViewport (0, 0, w, h);
+}
+
+void * GLSpectrumQt::get_qt_widget ()
+{
+ if (s_widget)
+ return s_widget;
+
+ s_widget = new GLSpectrumWidget;
+ return s_widget;
+}
diff --git a/src/gl-spectrum/Makefile b/src/gl-spectrum/Makefile
index e2dd330a4ec0..423054de7c8e 100644
--- a/src/gl-spectrum/Makefile
+++ b/src/gl-spectrum/Makefile
@@ -1,12 +1,13 @@
PLUGIN = gl-spectrum${PLUGIN_SUFFIX}
-SRCS = gl-spectrum.c
+SRCS = gl-spectrum.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${VISUALIZATION_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../.. ${GTK_CFLAGS}
LIBS += -lm ${GTK_LIBS} ${GL_LIBS}
diff --git a/src/gl-spectrum/gl-spectrum.c b/src/gl-spectrum/gl-spectrum.c
deleted file mode 100644
index 10fb22efd943..000000000000
--- a/src/gl-spectrum/gl-spectrum.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * OpenGL Spectrum Analyzer for Audacious
- * Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini
- *
- * Based on the XMMS plugin:
- * Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and
- * 4Front Technologies
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <math.h>
-#include <string.h>
-
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-
-#include <GL/gl.h>
-
-#ifdef GDK_WINDOWING_X11
-#include <GL/glx.h>
-#include <gdk/gdkx.h>
-#endif
-
-#ifdef GDK_WINDOWING_WIN32
-#include <gdk/gdkwin32.h>
-#endif
-
-#define NUM_BANDS 32
-#define DB_RANGE 40
-
-#define BAR_SPACING (3.2f / NUM_BANDS)
-#define BAR_WIDTH (0.8f * BAR_SPACING)
-
-static float logscale[NUM_BANDS + 1];
-static float colors[NUM_BANDS][NUM_BANDS][3];
-
-#ifdef GDK_WINDOWING_X11
-static Display * s_display;
-static Window s_xwindow;
-static GLXContext s_context;
-#endif
-
-#ifdef GDK_WINDOWING_WIN32
-static HWND s_hwnd;
-static HDC s_hdc;
-static HGLRC s_glrc;
-#endif
-
-static GtkWidget * s_widget = NULL;
-
-static int s_pos = 0;
-static float s_angle = 25, s_anglespeed = 0.05f;
-static float s_bars[NUM_BANDS][NUM_BANDS];
-
-static bool_t init (void)
-{
- for (int i = 0; i <= NUM_BANDS; i ++)
- logscale[i] = powf (256, (float) i / NUM_BANDS) - 0.5f;
-
- for (int y = 0; y < NUM_BANDS; y ++)
- {
- float yf = (float) y / (NUM_BANDS - 1);
-
- for (int x = 0; x < NUM_BANDS; x ++)
- {
- float xf = (float) x / (NUM_BANDS - 1);
-
- colors[x][y][0] = (1 - xf) * (1 - yf);
- colors[x][y][1] = xf;
- colors[x][y][2] = yf;
- }
- }
-
- return TRUE;
-}
-
-/* stolen from the skins plugin */
-/* convert linear frequency graph to logarithmic one */
-static void make_log_graph (const float * freq, float * graph)
-{
- for (int i = 0; i < NUM_BANDS; i ++)
- {
- /* sum up values in freq array between logscale[i] and logscale[i + 1],
- including fractional parts */
- int a = ceilf (logscale[i]);
- int b = floorf (logscale[i + 1]);
- float sum = 0;
-
- if (b < a)
- sum += freq[b] * (logscale[i + 1] - logscale[i]);
- else
- {
- if (a > 0)
- sum += freq[a - 1] * (a - logscale[i]);
- for (; a < b; a ++)
- sum += freq[a];
- if (b < 256)
- sum += freq[b] * (logscale[i + 1] - b);
- }
-
- /* fudge factor to make the graph have the same overall height as a
- 12-band one no matter how many bands there are */
- sum *= (float) NUM_BANDS / 12;
-
- /* convert to dB */
- float val = 20 * log10f (sum);
-
- /* scale (-DB_RANGE, 0.0) to (0.0, 1.0) */
- val = 1 + val / DB_RANGE;
-
- graph[i] = CLAMP (val, 0, 1);
- }
-}
-
-static void render_freq (const float * freq)
-{
- make_log_graph (freq, s_bars[s_pos]);
- s_pos = (s_pos + 1) % NUM_BANDS;
-
- s_angle += s_anglespeed;
- if (s_angle > 45 || s_angle < -45)
- s_anglespeed = -s_anglespeed;
-
- if (s_widget)
- gtk_widget_queue_draw (s_widget);
-}
-
-static void clear (void)
-{
- memset (s_bars, 0, sizeof s_bars);
-
- if (s_widget)
- gtk_widget_queue_draw (s_widget);
-}
-
-static void draw_rectangle (float x1, float y1, float z1, float x2, float y2,
- float z2, float r, float g, float b)
-{
- glColor3f (r, g, b);
-
- glBegin (GL_POLYGON);
- glVertex3f (x1, y2, z1);
- glVertex3f (x2, y2, z1);
- glVertex3f (x2, y2, z2);
- glVertex3f (x1, y2, z2);
- glEnd ();
-
- glColor3f (0.65f * r, 0.65f * g, 0.65f * b);
-
- glBegin (GL_POLYGON);
- glVertex3f (x1, y1, z1);
- glVertex3f (x1, y2, z1);
- glVertex3f (x1, y2, z2);
- glVertex3f (x1, y1, z2);
- glEnd ();
-
- glBegin (GL_POLYGON);
- glVertex3f (x2, y2, z1);
- glVertex3f (x2, y1, z1);
- glVertex3f (x2, y1, z2);
- glVertex3f (x2, y2, z2);
- glEnd ();
-
- glColor3f (0.8f * r, 0.8f * g, 0.8f * b);
-
- glBegin (GL_POLYGON);
- glVertex3f (x1, y1, z1);
- glVertex3f (x2, y1, z1);
- glVertex3f (x2, y2, z1);
- glVertex3f (x1, y2, z1);
- glEnd ();
-}
-
-static void draw_bar (float x, float z, float h, float r, float g, float b)
-{
- draw_rectangle (x, 0, z, x + BAR_WIDTH, h, z + BAR_WIDTH,
- r * (0.2f + 0.8f * h), g * (0.2f + 0.8f * h), b * (0.2f + 0.8f * h));
-}
-
-static void draw_bars (void)
-{
- glPushMatrix ();
- glTranslatef (0.0f, -0.5f, -5.0f);
- glRotatef (38.0f, 1.0f, 0.0f, 0.0f);
- glRotatef (s_angle + 180.0f, 0.0f, 1.0f, 0.0f);
- glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
-
- for (int i = 0; i < NUM_BANDS; i ++)
- {
- float z = -1.6f + (NUM_BANDS - i) * BAR_SPACING;
-
- for (int j = 0; j < NUM_BANDS; j ++)
- {
- draw_bar (1.6f - BAR_SPACING * j, z,
- s_bars[(s_pos + i) % NUM_BANDS][j] * 1.6,
- colors[i][j][0], colors[i][j][1], colors[i][j][2]);
- }
- }
-
- glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
- glPopMatrix ();
-}
-
-static bool_t draw_cb (GtkWidget * widget, cairo_t * cr)
-{
-#ifdef GDK_WINDOWING_X11
- if (! s_context)
- return FALSE;
-#endif
-
-#ifdef GDK_WINDOWING_WIN32
- if (! s_glrc)
- return FALSE;
-#endif
-
- GtkAllocation alloc;
- gtk_widget_get_allocation (widget, & alloc);
- glViewport (0, 0, alloc.width, alloc.height);
-
- glDisable (GL_BLEND);
- glMatrixMode (GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glFrustum (-1.1f, 1, -1.5f, 1, 2, 10);
- glMatrixMode (GL_MODELVIEW);
- glPushMatrix ();
- glLoadIdentity ();
- glEnable (GL_DEPTH_TEST);
- glDepthFunc (GL_LESS);
- glPolygonMode (GL_FRONT, GL_FILL);
- glEnable (GL_BLEND);
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glClearColor (0, 0, 0, 1);
- glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- draw_bars ();
-
- glPopMatrix ();
- glMatrixMode (GL_PROJECTION);
- glPopMatrix ();
- glDisable (GL_DEPTH_TEST);
- glDisable (GL_BLEND);
- glDepthMask (GL_TRUE);
-
-#ifdef GDK_WINDOWING_X11
- glXSwapBuffers (s_display, s_xwindow);
-#endif
-
-#ifdef GDK_WINDOWING_WIN32
- SwapBuffers (s_hdc);
-#endif
-
- return TRUE;
-}
-
-static void widget_realized (void)
-{
- GdkWindow * window = gtk_widget_get_window (s_widget);
-
-#ifdef GDK_WINDOWING_X11
- GdkScreen * screen = gdk_window_get_screen (window);
- int nscreen = GDK_SCREEN_XNUMBER (screen);
-
- s_display = GDK_SCREEN_XDISPLAY (screen);
- s_xwindow = GDK_WINDOW_XID (window);
-
- /* Create s_context */
- int attribs[] = {
- GLX_RGBA,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- GLX_ALPHA_SIZE, 1,
- GLX_DOUBLEBUFFER,
- GLX_DEPTH_SIZE, 1,
- None
- };
-
- XVisualInfo * xvinfo = glXChooseVisual (s_display, nscreen, attribs);
- g_return_if_fail (xvinfo);
-
- /* Fix up visual/colormap */
- GdkVisual * visual = gdk_x11_screen_lookup_visual (screen, xvinfo->visualid);
- g_return_if_fail (visual);
-
- gtk_widget_set_visual (s_widget, visual);
-
- s_context = glXCreateContext (s_display, xvinfo, 0, True);
- g_return_if_fail (s_context);
-
- XFree (xvinfo);
-
- glXMakeCurrent (s_display, s_xwindow, s_context);
-#endif
-
-#ifdef GDK_WINDOWING_WIN32
- s_hwnd = GDK_WINDOW_HWND (window);
- s_hdc = GetDC (s_hwnd);
-
- PIXELFORMATDESCRIPTOR desc = {
- sizeof (PIXELFORMATDESCRIPTOR),
- 1, // version number (?)
- PFD_DRAW_TO_WINDOW | // format must support window
- PFD_SUPPORT_OPENGL | // format must support OpenGL
- PFD_DOUBLEBUFFER, // must support double buffering
- PFD_TYPE_RGBA, // request an RGBA format
- 24, // select a 8:8:8 bit color depth
- 0, 0, 0, 0, 0, 0, // color bits ignored (?)
- 0, // no alpha buffer
- 0, // shift bit ignored (?)
- 0, // no accumulation buffer
- 0, 0, 0, 0, // accumulation bits ignored (?)
- 16, // 16-bit z-buffer (depth buffer)
- 0, // no stencil buffer
- 0, // no auxiliary buffer (?)
- PFD_MAIN_PLANE, // main drawing layer
- 0, // reserved (?)
- 0, 0, 0 // layer masks ignored (?)
- };
-
- int format = ChoosePixelFormat (s_hdc, & desc);
- g_return_if_fail (format != 0);
-
- SetPixelFormat (s_hdc, format, & desc);
-
- s_glrc = wglCreateContext (s_hdc);
- g_return_if_fail (s_glrc);
-
- wglMakeCurrent (s_hdc, s_glrc);
-#endif
-}
-
-static void widget_destroyed (void)
-{
- s_widget = NULL;
-
-#ifdef GDK_WINDOWING_X11
- if (s_context)
- {
- glXDestroyContext (s_display, s_context);
- s_context = NULL;
- }
-
- s_display = NULL;
-#endif
-
-#ifdef GDK_WINDOWING_WIN32
- if (s_glrc)
- {
- wglMakeCurrent (s_hdc, NULL);
- wglDeleteContext (s_glrc);
- s_glrc = NULL;
- }
-
- if (s_hdc)
- {
- ReleaseDC (s_hwnd, s_hdc);
- s_hdc = NULL;
- }
-
- s_hwnd = NULL;
-#endif
-}
-
-static /* GtkWidget * */ void * get_widget (void)
-{
- if (s_widget)
- return s_widget;
-
- s_widget = gtk_drawing_area_new ();
-
- g_signal_connect (s_widget, "draw", (GCallback) draw_cb, NULL);
- g_signal_connect (s_widget, "realize", (GCallback) widget_realized, NULL);
- g_signal_connect (s_widget, "destroy", (GCallback) widget_destroyed, NULL);
-
- /* Disable GTK double buffering */
- gtk_widget_set_double_buffered (s_widget, FALSE);
-
- return s_widget;
-}
-
-static const char about_text[] =
- N_("OpenGL Spectrum Analyzer for Audacious\n"
- "Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n\n"
- "Based on the XMMS plugin:\n"
- "Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, "
- "and 4Front Technologies\n\n"
- "License: GPLv2+");
-
-AUD_VIS_PLUGIN
-(
- .name = N_("OpenGL Spectrum Analyzer"),
- .domain = PACKAGE,
- .about_text = about_text,
- .init = init,
- .render_freq = render_freq,
- .clear = clear,
- .get_widget = get_widget,
-)
diff --git a/src/gl-spectrum/gl-spectrum.cc b/src/gl-spectrum/gl-spectrum.cc
new file mode 100644
index 000000000000..8ce3ca13ea10
--- /dev/null
+++ b/src/gl-spectrum/gl-spectrum.cc
@@ -0,0 +1,426 @@
+/*
+ * OpenGL Spectrum Analyzer for Audacious
+ * Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini
+ *
+ * Based on the XMMS plugin:
+ * Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, and
+ * 4Front Technologies
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+#include <string.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+#include <GL/gl.h>
+
+#ifdef GDK_WINDOWING_X11
+#include <GL/glx.h>
+#include <gdk/gdkx.h>
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+#include <gdk/gdkwin32.h>
+#endif
+
+#define NUM_BANDS 32
+#define DB_RANGE 40
+
+#define BAR_SPACING (3.2f / NUM_BANDS)
+#define BAR_WIDTH (0.8f * BAR_SPACING)
+
+static const char gl_about[] =
+ N_("OpenGL Spectrum Analyzer for Audacious\n"
+ "Copyright 2013 Christophe Budé, John Lindgren, and Carlo Bramini\n\n"
+ "Based on the XMMS plugin:\n"
+ "Copyright 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson, "
+ "and 4Front Technologies\n\n"
+ "License: GPLv2+");
+
+class GLSpectrum : public VisPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("OpenGL Spectrum Analyzer"),
+ PACKAGE,
+ gl_about
+ };
+
+ constexpr GLSpectrum () : VisPlugin (info, Visualizer::Freq) {}
+
+ bool init ();
+
+ void * get_gtk_widget ();
+
+ void clear ();
+ void render_freq (const float * freq);
+};
+
+EXPORT GLSpectrum aud_plugin_instance;
+
+static float logscale[NUM_BANDS + 1];
+static float colors[NUM_BANDS][NUM_BANDS][3];
+
+#ifdef GDK_WINDOWING_X11
+static Display * s_display;
+static Window s_xwindow;
+static GLXContext s_context;
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+static HWND s_hwnd;
+static HDC s_hdc;
+static HGLRC s_glrc;
+#endif
+
+static GtkWidget * s_widget = nullptr;
+
+static int s_pos = 0;
+static float s_angle = 25, s_anglespeed = 0.05f;
+static float s_bars[NUM_BANDS][NUM_BANDS];
+
+bool GLSpectrum::init ()
+{
+ for (int i = 0; i <= NUM_BANDS; i ++)
+ logscale[i] = powf (256, (float) i / NUM_BANDS) - 0.5f;
+
+ for (int y = 0; y < NUM_BANDS; y ++)
+ {
+ float yf = (float) y / (NUM_BANDS - 1);
+
+ for (int x = 0; x < NUM_BANDS; x ++)
+ {
+ float xf = (float) x / (NUM_BANDS - 1);
+
+ colors[x][y][0] = (1 - xf) * (1 - yf);
+ colors[x][y][1] = xf;
+ colors[x][y][2] = yf;
+ }
+ }
+
+ return true;
+}
+
+/* stolen from the skins plugin */
+/* convert linear frequency graph to logarithmic one */
+static void make_log_graph (const float * freq, float * graph)
+{
+ for (int i = 0; i < NUM_BANDS; i ++)
+ {
+ /* sum up values in freq array between logscale[i] and logscale[i + 1],
+ including fractional parts */
+ int a = ceilf (logscale[i]);
+ int b = floorf (logscale[i + 1]);
+ float sum = 0;
+
+ if (b < a)
+ sum += freq[b] * (logscale[i + 1] - logscale[i]);
+ else
+ {
+ if (a > 0)
+ sum += freq[a - 1] * (a - logscale[i]);
+ for (; a < b; a ++)
+ sum += freq[a];
+ if (b < 256)
+ sum += freq[b] * (logscale[i + 1] - b);
+ }
+
+ /* fudge factor to make the graph have the same overall height as a
+ 12-band one no matter how many bands there are */
+ sum *= (float) NUM_BANDS / 12;
+
+ /* convert to dB */
+ float val = 20 * log10f (sum);
+
+ /* scale (-DB_RANGE, 0.0) to (0.0, 1.0) */
+ val = 1 + val / DB_RANGE;
+
+ graph[i] = aud::clamp (val, 0.0f, 1.0f);
+ }
+}
+
+void GLSpectrum::render_freq (const float * freq)
+{
+ make_log_graph (freq, s_bars[s_pos]);
+ s_pos = (s_pos + 1) % NUM_BANDS;
+
+ s_angle += s_anglespeed;
+ if (s_angle > 45 || s_angle < -45)
+ s_anglespeed = -s_anglespeed;
+
+ if (s_widget)
+ gtk_widget_queue_draw (s_widget);
+}
+
+void GLSpectrum::clear ()
+{
+ memset (s_bars, 0, sizeof s_bars);
+
+ if (s_widget)
+ gtk_widget_queue_draw (s_widget);
+}
+
+static void draw_rectangle (float x1, float y1, float z1, float x2, float y2,
+ float z2, float r, float g, float b)
+{
+ glColor3f (r, g, b);
+
+ glBegin (GL_POLYGON);
+ glVertex3f (x1, y2, z1);
+ glVertex3f (x2, y2, z1);
+ glVertex3f (x2, y2, z2);
+ glVertex3f (x1, y2, z2);
+ glEnd ();
+
+ glColor3f (0.65f * r, 0.65f * g, 0.65f * b);
+
+ glBegin (GL_POLYGON);
+ glVertex3f (x1, y1, z1);
+ glVertex3f (x1, y2, z1);
+ glVertex3f (x1, y2, z2);
+ glVertex3f (x1, y1, z2);
+ glEnd ();
+
+ glBegin (GL_POLYGON);
+ glVertex3f (x2, y2, z1);
+ glVertex3f (x2, y1, z1);
+ glVertex3f (x2, y1, z2);
+ glVertex3f (x2, y2, z2);
+ glEnd ();
+
+ glColor3f (0.8f * r, 0.8f * g, 0.8f * b);
+
+ glBegin (GL_POLYGON);
+ glVertex3f (x1, y1, z1);
+ glVertex3f (x2, y1, z1);
+ glVertex3f (x2, y2, z1);
+ glVertex3f (x1, y2, z1);
+ glEnd ();
+}
+
+static void draw_bar (float x, float z, float h, float r, float g, float b)
+{
+ draw_rectangle (x, 0, z, x + BAR_WIDTH, h, z + BAR_WIDTH,
+ r * (0.2f + 0.8f * h), g * (0.2f + 0.8f * h), b * (0.2f + 0.8f * h));
+}
+
+static void draw_bars ()
+{
+ glPushMatrix ();
+ glTranslatef (0.0f, -0.5f, -5.0f);
+ glRotatef (38.0f, 1.0f, 0.0f, 0.0f);
+ glRotatef (s_angle + 180.0f, 0.0f, 1.0f, 0.0f);
+ glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
+
+ for (int i = 0; i < NUM_BANDS; i ++)
+ {
+ float z = -1.6f + (NUM_BANDS - i) * BAR_SPACING;
+
+ for (int j = 0; j < NUM_BANDS; j ++)
+ {
+ draw_bar (1.6f - BAR_SPACING * j, z,
+ s_bars[(s_pos + i) % NUM_BANDS][j] * 1.6,
+ colors[i][j][0], colors[i][j][1], colors[i][j][2]);
+ }
+ }
+
+ glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
+ glPopMatrix ();
+}
+
+static gboolean draw_cb (GtkWidget * widget)
+{
+#ifdef GDK_WINDOWING_X11
+ if (! s_context)
+ return false;
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+ if (! s_glrc)
+ return false;
+#endif
+
+ GtkAllocation alloc;
+ gtk_widget_get_allocation (widget, & alloc);
+ glViewport (0, 0, alloc.width, alloc.height);
+
+ glDisable (GL_BLEND);
+ glMatrixMode (GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glFrustum (-1.1f, 1, -1.5f, 1, 2, 10);
+ glMatrixMode (GL_MODELVIEW);
+ glPushMatrix ();
+ glLoadIdentity ();
+ glEnable (GL_DEPTH_TEST);
+ glDepthFunc (GL_LESS);
+ glPolygonMode (GL_FRONT, GL_FILL);
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glClearColor (0, 0, 0, 1);
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ draw_bars ();
+
+ glPopMatrix ();
+ glMatrixMode (GL_PROJECTION);
+ glPopMatrix ();
+ glDisable (GL_DEPTH_TEST);
+ glDisable (GL_BLEND);
+ glDepthMask (GL_TRUE);
+
+#ifdef GDK_WINDOWING_X11
+ glXSwapBuffers (s_display, s_xwindow);
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+ SwapBuffers (s_hdc);
+#endif
+
+ return true;
+}
+
+static void widget_realized ()
+{
+ GdkWindow * window = gtk_widget_get_window (s_widget);
+
+#ifdef GDK_WINDOWING_X11
+ GdkScreen * screen = gdk_window_get_screen (window);
+ int nscreen = GDK_SCREEN_XNUMBER (screen);
+
+ s_display = GDK_SCREEN_XDISPLAY (screen);
+ s_xwindow = GDK_WINDOW_XID (window);
+
+ /* Create s_context */
+ int attribs[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ GLX_DEPTH_SIZE, 1,
+ None
+ };
+
+ XVisualInfo * xvinfo = glXChooseVisual (s_display, nscreen, attribs);
+ g_return_if_fail (xvinfo);
+
+ /* Fix up visual/colormap */
+ GdkVisual * visual = gdk_x11_screen_lookup_visual (screen, xvinfo->visualid);
+ g_return_if_fail (visual);
+
+ gtk_widget_set_visual (s_widget, visual);
+
+ s_context = glXCreateContext (s_display, xvinfo, 0, true);
+ g_return_if_fail (s_context);
+
+ XFree (xvinfo);
+
+ glXMakeCurrent (s_display, s_xwindow, s_context);
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+ s_hwnd = (HWND) GDK_WINDOW_HWND (window);
+ s_hdc = GetDC (s_hwnd);
+
+ PIXELFORMATDESCRIPTOR desc = {
+ sizeof (PIXELFORMATDESCRIPTOR),
+ 1, // version number (?)
+ PFD_DRAW_TO_WINDOW | // format must support window
+ PFD_SUPPORT_OPENGL | // format must support OpenGL
+ PFD_DOUBLEBUFFER, // must support double buffering
+ PFD_TYPE_RGBA, // request an RGBA format
+ 24, // select a 8:8:8 bit color depth
+ 0, 0, 0, 0, 0, 0, // color bits ignored (?)
+ 0, // no alpha buffer
+ 0, // shift bit ignored (?)
+ 0, // no accumulation buffer
+ 0, 0, 0, 0, // accumulation bits ignored (?)
+ 16, // 16-bit z-buffer (depth buffer)
+ 0, // no stencil buffer
+ 0, // no auxiliary buffer (?)
+ PFD_MAIN_PLANE, // main drawing layer
+ 0, // reserved (?)
+ 0, 0, 0 // layer masks ignored (?)
+ };
+
+ int format = ChoosePixelFormat (s_hdc, & desc);
+ g_return_if_fail (format != 0);
+
+ SetPixelFormat (s_hdc, format, & desc);
+
+ s_glrc = wglCreateContext (s_hdc);
+ g_return_if_fail (s_glrc);
+
+ wglMakeCurrent (s_hdc, s_glrc);
+#endif
+}
+
+static void widget_destroyed ()
+{
+ s_widget = nullptr;
+
+#ifdef GDK_WINDOWING_X11
+ if (s_context)
+ {
+ glXDestroyContext (s_display, s_context);
+ s_context = nullptr;
+ }
+
+ s_display = nullptr;
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+ if (s_glrc)
+ {
+ wglMakeCurrent (s_hdc, nullptr);
+ wglDeleteContext (s_glrc);
+ s_glrc = nullptr;
+ }
+
+ if (s_hdc)
+ {
+ ReleaseDC (s_hwnd, s_hdc);
+ s_hdc = nullptr;
+ }
+
+ s_hwnd = nullptr;
+#endif
+}
+
+void * GLSpectrum::get_gtk_widget ()
+{
+ if (s_widget)
+ return s_widget;
+
+ s_widget = gtk_drawing_area_new ();
+
+ g_signal_connect (s_widget, "expose-event", (GCallback) draw_cb, nullptr);
+ g_signal_connect (s_widget, "realize", (GCallback) widget_realized, nullptr);
+ g_signal_connect (s_widget, "destroy", (GCallback) widget_destroyed, nullptr);
+
+ /* Disable GTK double buffering */
+ gtk_widget_set_double_buffered (s_widget, false);
+
+ return s_widget;
+}
diff --git a/src/gnomeshortcuts/Makefile b/src/gnomeshortcuts/Makefile
index 13b8e1d36b62..b8ef5dfab14b 100644
--- a/src/gnomeshortcuts/Makefile
+++ b/src/gnomeshortcuts/Makefile
@@ -1,12 +1,13 @@
PLUGIN = gnomeshortcuts${PLUGIN_SUFFIX}
-SRCS = gnomeshortcuts.c
+SRCS = gnomeshortcuts.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${DBUS_CFLAGS} -I../.. -I..
LIBS += ${GLIB_LIBS} ${DBUS_LIBS} ${GTK_LIBS}
diff --git a/src/gnomeshortcuts/gnomeshortcuts.c b/src/gnomeshortcuts/gnomeshortcuts.c
deleted file mode 100644
index e415645ff211..000000000000
--- a/src/gnomeshortcuts/gnomeshortcuts.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * This file is part of audacious-gnome-shortcut plugin for audacious
- *
- * Copyright (c) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>
- * Name: plugin.c
- * Description: plugin.c
- *
- * audacious-gnome-shortcut 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.
- *
- * audacious-gnome-shortcut 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 audacious-gnome-shortcut; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <string.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-bindings.h>
-#include <glib-object.h>
-
-#include <audacious/drct.h>
-#include <audacious/plugin.h>
-#include <audacious/i18n.h>
-
-static gboolean init (void);
-static void cleanup (void);
-void gnome_remote_init();
-void gnome_remote_uninit();
-
-static gboolean loaded = FALSE;
-static DBusGProxy *media_player_keys_proxy = NULL;
-
-static const char about[] =
- N_("Gnome Shortcut Plugin\n"
- "Lets you control the player with Gnome's shortcuts.\n\n"
- "Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>");
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("Gnome Shortcuts"),
- .domain = PACKAGE,
- .about_text = about,
- .init = init,
- .cleanup = cleanup
-)
-
-#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
-
-
-static void
-hotkey_marshal_VOID__STRING_STRING (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__STRING_STRING) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2);
- register GMarshalFunc_VOID__STRING_STRING callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1;
-
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- } else {
- data1 = g_value_peek_pointer (param_values + 0);
- }
- callback = (GMarshalFunc_VOID__STRING_STRING) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_string (param_values + 1),
- g_marshal_value_peek_string (param_values + 2));
-}
-
-static void
-on_media_player_key_pressed (DBusGProxy *proxy, const gchar *application, const gchar *key)
-{
- if (strcmp ("Audacious", application) == 0) {
- gint current_volume /* , old_volume */ ;
- static gint volume_static = 0;
- gboolean mute;
-
- /* get current volume */
- aud_drct_get_volume_main (¤t_volume);
- /* old_volume = current_volume; */
- if (current_volume)
- {
- /* volume is not mute */
- mute = FALSE;
- } else {
- /* volume is mute */
- mute = TRUE;
- }
-
- /* mute the playback */
- if (strcmp ("Mute", key) == 0)
- {
- if (!mute)
- {
- volume_static = current_volume;
- aud_drct_set_volume_main (0);
- mute = TRUE;
- } else {
- aud_drct_set_volume_main (volume_static);
- mute = FALSE;
- }
- return;
- }
-
- /* decreace volume */
-/* if ((keycode == plugin_cfg.vol_down) && (state == plugin_cfg.vol_down_mask))
- {
- if (mute)
- {
- current_volume = old_volume;
- old_volume = 0;
- mute = FALSE;
- }
-
- if ((current_volume -= plugin_cfg.vol_decrement) < 0)
- {
- current_volume = 0;
- }
-
- if (current_volume != old_volume)
- {
- xmms_remote_set_main_volume (audacioushotkey.xmms_session,
- current_volume);
- }
-
- old_volume = current_volume;
- return TRUE;
- }*/
-
- /* increase volume */
-/* if ((keycode == plugin_cfg.vol_up) && (state == plugin_cfg.vol_up_mask))
- {
- if (mute)
- {
- current_volume = old_volume;
- old_volume = 0;
- mute = FALSE;
- }
-
- if ((current_volume += plugin_cfg.vol_increment) > 100)
- {
- current_volume = 100;
- }
-
- if (current_volume != old_volume)
- {
- xmms_remote_set_main_volume (audacioushotkey.xmms_session,
- current_volume);
- }
-
- old_volume = current_volume;
- return TRUE;
- }*/
-
- /* play or pause */
- if (strcmp ("Play", key) == 0 || strcmp ("Pause", key) == 0)
- {
- aud_drct_play_pause ();
- return;
- }
-
- /* stop */
- if (strcmp ("Stop", key) == 0)
- {
- aud_drct_stop ();
- return;
- }
-
- /* prev track */
- if (strcmp ("Previous", key) == 0)
- {
- aud_drct_pl_prev ();
- return;
- }
-
- /* next track */
- if (strcmp ("Next", key) == 0)
- {
- aud_drct_pl_next ();
- return;
- }
- }
-}
-
-void gnome_remote_uninit ()
-{
- GError *error = NULL;
- if (media_player_keys_proxy == NULL) return;
-
- dbus_g_proxy_disconnect_signal (media_player_keys_proxy, "MediaPlayerKeyPressed",
- G_CALLBACK (on_media_player_key_pressed), NULL);
-
- dbus_g_proxy_call (media_player_keys_proxy,
- "ReleaseMediaPlayerKeys", &error,
- G_TYPE_STRING, "Audacious",
- G_TYPE_INVALID, G_TYPE_INVALID);
- if (error != NULL) {
- g_warning ("Could not release media player keys: %s", error->message);
- g_error_free (error);
- }
- g_object_unref(media_player_keys_proxy);
- media_player_keys_proxy = NULL;
-}
-
-void gnome_remote_init ()
-{
- DBusGConnection *bus;
- GError *error = NULL;
- dbus_g_thread_init();
-
- bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
- if ((bus == NULL) && error) {
- g_warning ("Error connecting to DBus: %s", error->message);
- g_error_free (error);
- } else {
- media_player_keys_proxy = dbus_g_proxy_new_for_name (bus,
- "org.gnome.SettingsDaemon",
- "/org/gnome/SettingsDaemon/MediaKeys",
- "org.gnome.SettingsDaemon.MediaKeys");
- if (media_player_keys_proxy == NULL) return;
-
- dbus_g_proxy_call (media_player_keys_proxy,
- "GrabMediaPlayerKeys", &error,
- G_TYPE_STRING, "Audacious",
- G_TYPE_UINT, 0,
- G_TYPE_INVALID,
- G_TYPE_INVALID);
- if (error != NULL) {
- g_error_free (error);
- error = NULL;
- g_object_unref(media_player_keys_proxy);
- media_player_keys_proxy = NULL;
- media_player_keys_proxy = dbus_g_proxy_new_for_name (bus,
- "org.gnome.SettingsDaemon",
- "/org/gnome/SettingsDaemon",
- "org.gnome.SettingsDaemon");
- if (media_player_keys_proxy == NULL) return;
-
- dbus_g_proxy_call (media_player_keys_proxy,
- "GrabMediaPlayerKeys", &error,
- G_TYPE_STRING, "Audacious",
- G_TYPE_UINT, 0,
- G_TYPE_INVALID,
- G_TYPE_INVALID);
- if (error != NULL) {
- g_warning ("Could not grab media player keys: %s", error->message);
- g_error_free (error);
- g_object_unref(media_player_keys_proxy);
- media_player_keys_proxy = NULL;
- return;
- }
- }
-
- dbus_g_object_register_marshaller (hotkey_marshal_VOID__STRING_STRING,
- G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
-
- dbus_g_proxy_add_signal (media_player_keys_proxy, "MediaPlayerKeyPressed",
- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
-
- dbus_g_proxy_connect_signal (media_player_keys_proxy, "MediaPlayerKeyPressed",
- G_CALLBACK (on_media_player_key_pressed), NULL, NULL);
- }
-}
-
-static gboolean init (void)
-{
- gnome_remote_init();
- loaded = TRUE;
- return TRUE;
-}
-
-static void cleanup (void)
-{
- if (!loaded) return;
- gnome_remote_uninit();
- loaded = FALSE;
-}
diff --git a/src/gnomeshortcuts/gnomeshortcuts.cc b/src/gnomeshortcuts/gnomeshortcuts.cc
new file mode 100644
index 000000000000..6749e5f6b000
--- /dev/null
+++ b/src/gnomeshortcuts/gnomeshortcuts.cc
@@ -0,0 +1,289 @@
+/*
+ * This file is part of audacious-gnome-shortcut plugin for audacious
+ *
+ * Copyright (c) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>
+ * Name: plugin.c
+ * Description: plugin.c
+ *
+ * audacious-gnome-shortcut 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.
+ *
+ * audacious-gnome-shortcut 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 audacious-gnome-shortcut; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <string.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <glib-object.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/i18n.h>
+
+class GNOMEShortcuts : public GeneralPlugin
+{
+public:
+ static const char about[];
+
+ static constexpr PluginInfo info = {
+ N_("GNOME Shortcuts"),
+ PACKAGE,
+ about
+ };
+
+ constexpr GNOMEShortcuts () : GeneralPlugin (info, false) {}
+
+ bool init ();
+ void cleanup ();
+};
+
+EXPORT GNOMEShortcuts aud_plugin_instance;
+
+static DBusGProxy *media_player_keys_proxy = nullptr;
+
+const char GNOMEShortcuts::about[] =
+ N_("GNOME Shortcut Plugin\n"
+ "Lets you control the player with GNOME's shortcuts.\n\n"
+ "Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>");
+
+#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
+
+
+static void
+hotkey_marshal_VOID__STRING_STRING (GClosure *closure,
+ GValue *return_value,
+ unsigned n_param_values,
+ const GValue *param_values,
+ void * invocation_hint,
+ void * marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__STRING_STRING) (void * data1,
+ void * arg_1,
+ void * arg_2);
+ GMarshalFunc_VOID__STRING_STRING callback;
+ GCClosure *cc = (GCClosure*) closure;
+ void * data1;
+
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ } else {
+ data1 = g_value_peek_pointer (param_values + 0);
+ }
+ callback = (GMarshalFunc_VOID__STRING_STRING) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_string (param_values + 1),
+ g_marshal_value_peek_string (param_values + 2));
+}
+
+static void
+on_media_player_key_pressed (DBusGProxy *proxy, const char *application, const char *key)
+{
+ if (strcmp ("Audacious", application) == 0) {
+ int current_volume /* , old_volume */ ;
+ static int volume_static = 0;
+ bool mute;
+
+ /* get current volume */
+ current_volume = aud_drct_get_volume_main ();
+ /* old_volume = current_volume; */
+ if (current_volume)
+ {
+ /* volume is not mute */
+ mute = false;
+ } else {
+ /* volume is mute */
+ mute = true;
+ }
+
+ /* mute the playback */
+ if (strcmp ("Mute", key) == 0)
+ {
+ if (!mute)
+ {
+ volume_static = current_volume;
+ aud_drct_set_volume_main (0);
+ mute = true;
+ } else {
+ aud_drct_set_volume_main (volume_static);
+ mute = false;
+ }
+ return;
+ }
+
+ /* decreace volume */
+/* if ((keycode == plugin_cfg.vol_down) && (state == plugin_cfg.vol_down_mask))
+ {
+ if (mute)
+ {
+ current_volume = old_volume;
+ old_volume = 0;
+ mute = false;
+ }
+
+ if ((current_volume -= plugin_cfg.vol_decrement) < 0)
+ {
+ current_volume = 0;
+ }
+
+ if (current_volume != old_volume)
+ {
+ xmms_remote_set_main_volume (audacioushotkey.xmms_session,
+ current_volume);
+ }
+
+ old_volume = current_volume;
+ return true;
+ }*/
+
+ /* increase volume */
+/* if ((keycode == plugin_cfg.vol_up) && (state == plugin_cfg.vol_up_mask))
+ {
+ if (mute)
+ {
+ current_volume = old_volume;
+ old_volume = 0;
+ mute = false;
+ }
+
+ if ((current_volume += plugin_cfg.vol_increment) > 100)
+ {
+ current_volume = 100;
+ }
+
+ if (current_volume != old_volume)
+ {
+ xmms_remote_set_main_volume (audacioushotkey.xmms_session,
+ current_volume);
+ }
+
+ old_volume = current_volume;
+ return true;
+ }*/
+
+ /* play or pause */
+ if (strcmp ("Play", key) == 0 || strcmp ("Pause", key) == 0)
+ {
+ aud_drct_play_pause ();
+ return;
+ }
+
+ /* stop */
+ if (strcmp ("Stop", key) == 0)
+ {
+ aud_drct_stop ();
+ return;
+ }
+
+ /* prev track */
+ if (strcmp ("Previous", key) == 0)
+ {
+ aud_drct_pl_prev ();
+ return;
+ }
+
+ /* next track */
+ if (strcmp ("Next", key) == 0)
+ {
+ aud_drct_pl_next ();
+ return;
+ }
+ }
+}
+
+void GNOMEShortcuts::cleanup ()
+{
+ GError *error = nullptr;
+ if (media_player_keys_proxy == nullptr) return;
+
+ dbus_g_proxy_disconnect_signal (media_player_keys_proxy, "MediaPlayerKeyPressed",
+ G_CALLBACK (on_media_player_key_pressed), nullptr);
+
+ dbus_g_proxy_call (media_player_keys_proxy,
+ "ReleaseMediaPlayerKeys", &error,
+ G_TYPE_STRING, "Audacious",
+ G_TYPE_INVALID, G_TYPE_INVALID);
+ if (error != nullptr) {
+ g_warning ("Could not release media player keys: %s", error->message);
+ g_error_free (error);
+ }
+ g_object_unref(media_player_keys_proxy);
+ media_player_keys_proxy = nullptr;
+}
+
+bool GNOMEShortcuts::init ()
+{
+ DBusGConnection *bus;
+ GError *error = nullptr;
+ dbus_g_thread_init();
+
+ bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if ((bus == nullptr) && error) {
+ g_warning ("Error connecting to DBus: %s", error->message);
+ g_error_free (error);
+ return false;
+ } else {
+ media_player_keys_proxy = dbus_g_proxy_new_for_name (bus,
+ "org.gnome.SettingsDaemon",
+ "/org/gnome/SettingsDaemon/MediaKeys",
+ "org.gnome.SettingsDaemon.MediaKeys");
+ if (media_player_keys_proxy == nullptr)
+ return false;
+
+ dbus_g_proxy_call (media_player_keys_proxy,
+ "GrabMediaPlayerKeys", &error,
+ G_TYPE_STRING, "Audacious",
+ G_TYPE_UINT, 0,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ if (error != nullptr) {
+ g_error_free (error);
+ error = nullptr;
+ g_object_unref(media_player_keys_proxy);
+ media_player_keys_proxy = nullptr;
+ media_player_keys_proxy = dbus_g_proxy_new_for_name (bus,
+ "org.gnome.SettingsDaemon",
+ "/org/gnome/SettingsDaemon",
+ "org.gnome.SettingsDaemon");
+ if (media_player_keys_proxy == nullptr)
+ return false;
+
+ dbus_g_proxy_call (media_player_keys_proxy,
+ "GrabMediaPlayerKeys", &error,
+ G_TYPE_STRING, "Audacious",
+ G_TYPE_UINT, 0,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ if (error != nullptr) {
+ g_warning ("Could not grab media player keys: %s", error->message);
+ g_error_free (error);
+ g_object_unref(media_player_keys_proxy);
+ media_player_keys_proxy = nullptr;
+ return false;
+ }
+ }
+
+ dbus_g_object_register_marshaller (hotkey_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+
+ dbus_g_proxy_add_signal (media_player_keys_proxy, "MediaPlayerKeyPressed",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal (media_player_keys_proxy, "MediaPlayerKeyPressed",
+ G_CALLBACK (on_media_player_key_pressed), nullptr, nullptr);
+
+ return true;
+ }
+}
diff --git a/src/gtkui/Makefile b/src/gtkui/Makefile
index ecdf78e42400..cdfe244bc1bd 100644
--- a/src/gtkui/Makefile
+++ b/src/gtkui/Makefile
@@ -1,21 +1,23 @@
PLUGIN = gtkui${PLUGIN_SUFFIX}
-SRCS = columns.c \
- layout.c \
- menus.c \
- ui_infoarea.c \
- ui_gtk.c \
- ui_playlist_widget.c \
- ui_playlist_notebook.c \
- ui_statusbar.c \
- playlist_util.c \
- settings.c
+SRCS = columns.cc \
+ layout.cc \
+ menus.cc \
+ ui_infoarea.cc \
+ ui_gtk.cc \
+ ui_playlist_widget.cc \
+ ui_playlist_notebook.cc \
+ ui_statusbar.cc \
+ playlist_util.cc \
+ settings.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../.. ${GTK_CFLAGS}
-LIBS += -lm ${GTK_LIBS}
+LIBS += -lm ${GTK_LIBS} -laudgui
diff --git a/src/gtkui/columns.c b/src/gtkui/columns.c
deleted file mode 100644
index 4f9d773cae84..000000000000
--- a/src/gtkui/columns.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * columns.c
- * Copyright 2011 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <string.h>
-
-#include <gtk/gtk.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <libaudcore/index.h>
-#include <libaudcore/audstrings.h>
-#include <libaudgui/libaudgui-gtk.h>
-#include <libaudgui/list.h>
-
-#include "ui_playlist_notebook.h"
-#include "ui_playlist_widget.h"
-
-const char * const pw_col_names[PW_COLS] = {N_("Entry number"), N_("Title"),
- N_("Artist"), N_("Year"), N_("Album"), N_("Track"), N_("Genre"),
- N_("Queue position"), N_("Length"), N_("File path"), N_("File name"),
- N_("Custom title"), N_("Bitrate")};
-
-int pw_num_cols;
-int pw_cols[PW_COLS];
-
-static const char * const pw_col_keys[PW_COLS] = {"number", "title", "artist",
- "year", "album", "track", "genre", "queued", "length", "path", "filename",
- "custom", "bitrate"};
-
-void pw_col_init (void)
-{
- pw_num_cols = 0;
-
- char * columns = aud_get_str ("gtkui", "playlist_columns");
- Index * index = str_list_to_index (columns, " ");
-
- int count = index_count (index);
- if (count > PW_COLS)
- count = PW_COLS;
-
- for (int c = 0; c < count; c ++)
- {
- char * column = index_get (index, c);
-
- int i = 0;
- while (i < PW_COLS && strcmp (column, pw_col_keys[i]))
- i ++;
-
- if (i == PW_COLS)
- break;
-
- pw_cols[pw_num_cols ++] = i;
- }
-
- index_free_full (index, (IndexFreeFunc) str_unref);
- str_unref (columns);
-}
-
-typedef struct {
- int column;
- bool_t selected;
-} Column;
-
-static GtkWidget * chosen_list = NULL, * avail_list = NULL;
-static Index * chosen = NULL, * avail = NULL;
-
-static void apply_changes (void)
-{
- int cols = index_count (chosen);
- g_return_if_fail (cols <= PW_COLS);
-
- ui_playlist_notebook_empty ();
-
- for (pw_num_cols = 0; pw_num_cols < cols; pw_num_cols ++)
- pw_cols[pw_num_cols] = ((Column *) index_get (chosen, pw_num_cols))->column;
-
- aud_set_str ("gtkui", "column_widths", "");
- aud_set_str ("gtkui", "column_expand", "");
-
- ui_playlist_notebook_populate ();
-}
-
-static void get_value (void * user, int row, int column, GValue * value)
-{
- g_return_if_fail (row >= 0 && row < index_count (user));
- Column * c = index_get (user, row);
- g_value_set_string (value, _(pw_col_names[c->column]));
-}
-
-static bool_t get_selected (void * user, int row)
-{
- g_return_val_if_fail (row >= 0 && row < index_count (user), FALSE);
- return ((Column *) index_get (user, row))->selected;
-}
-
-static void set_selected (void * user, int row, bool_t selected)
-{
- g_return_if_fail (row >= 0 && row < index_count (user));
- ((Column *) index_get (user, row))->selected = selected;
-}
-
-static void select_all (void * user, bool_t selected)
-{
- int rows = index_count (user);
- for (int row = 0; row < rows; row ++)
- ((Column *) index_get (user, row))->selected = selected;
-}
-
-static void shift_rows (void * user, int row, int before)
-{
- int rows = index_count (user);
- g_return_if_fail (row >= 0 && row < rows);
- g_return_if_fail (before >= 0 && before <= rows);
-
- if (before == row)
- return;
-
- Index * move = index_new ();
- Index * others = index_new ();
-
- int begin, end;
- if (before < row)
- {
- begin = before;
- end = row + 1;
- while (end < rows && ((Column *) index_get (user, end))->selected)
- end ++;
- }
- else
- {
- begin = row;
- while (begin > 0 && ((Column *) index_get (user, begin - 1))->selected)
- begin --;
- end = before;
- }
-
- for (int i = begin; i < end; i ++)
- {
- Column * c = index_get (user, i);
- index_insert (c->selected ? move : others, -1, c);
- }
-
- if (before < row)
- {
- index_copy_insert (others, 0, move, -1, -1);
- index_free (others);
- }
- else
- {
- index_copy_insert (move, 0, others, -1, -1);
- index_free (move);
- move = others;
- }
-
- index_copy_set (move, 0, user, begin, end - begin);
- index_free (move);
-
- GtkWidget * list = (user == chosen) ? chosen_list : avail_list;
- audgui_list_update_rows (list, begin, end - begin);
- audgui_list_update_selection (list, begin, end - begin);
-
- apply_changes ();
-}
-
-static const AudguiListCallbacks callbacks = {
- .get_value = get_value,
- .get_selected = get_selected,
- .set_selected = set_selected,
- .select_all = select_all,
- .shift_rows = shift_rows};
-
-static void transfer (Index * source)
-{
- Index * dest;
- GtkWidget * source_list, * dest_list;
- if (source == chosen)
- {
- dest = avail;
- source_list = chosen_list;
- dest_list = avail_list;
- }
- else
- {
- dest = chosen;
- source_list = avail_list;
- dest_list = chosen_list;
- }
-
- int source_rows = index_count (source);
- int dest_rows = index_count (dest);
-
- for (int row = 0; row < source_rows; )
- {
- Column * c = index_get (source, row);
- if (! c->selected)
- {
- row ++;
- continue;
- }
-
- index_delete (source, row, 1);
- audgui_list_delete_rows (source_list, row, 1);
- source_rows --;
- index_insert (dest, -1, c);
- audgui_list_insert_rows (dest_list, dest_rows, 1);
- dest_rows ++;
- }
-
- apply_changes ();
-}
-
-static void destroy_cb (void)
-{
- chosen_list = NULL;
- avail_list = NULL;
-
- int rows = index_count (chosen);
- for (int row = 0; row < rows; row ++)
- g_slice_free (Column, index_get (chosen, row));
- index_free (chosen);
- chosen = NULL;
-
- rows = index_count (avail);
- for (int row = 0; row < rows; row ++)
- g_slice_free (Column, index_get (avail, row));
- index_free (avail);
- avail = NULL;
-}
-
-void * pw_col_create_chooser (void)
-{
- chosen = index_new ();
- avail = index_new ();
-
- bool_t added[PW_COLS];
- memset (added, 0, sizeof added);
-
- for (int i = 0; i < pw_num_cols; i ++)
- {
- if (added[pw_cols[i]])
- continue;
- added[pw_cols[i]] = TRUE;
- Column * column = g_slice_new (Column);
- column->column = pw_cols[i];
- column->selected = 0;
- index_insert (chosen, -1, column);
- }
-
- for (int i = 0; i < PW_COLS; i ++)
- {
- if (added[i])
- continue;
- Column * column = g_slice_new (Column);
- column->column = i;
- column->selected = 0;
- index_insert (avail, -1, column);
- }
-
- GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_widget_set_size_request (hbox, -1, 160);
-
- GtkWidget * scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scroll,
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scroll,
- GTK_SHADOW_IN);
- gtk_box_pack_start ((GtkBox *) hbox, scroll, TRUE, TRUE, 0);
-
- avail_list = audgui_list_new (& callbacks, avail, index_count (avail));
- audgui_list_add_column (avail_list, _("Available columns"), 0, G_TYPE_STRING, -1);
- gtk_container_add ((GtkContainer *) scroll, avail_list);
-
- GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_box_pack_start ((GtkBox *) hbox, vbox, FALSE, FALSE, 0);
-
- GtkWidget * button = gtk_button_new ();
- gtk_container_add ((GtkContainer *) button, gtk_image_new_from_icon_name
- ("go-next", GTK_ICON_SIZE_BUTTON));
- gtk_box_pack_start ((GtkBox *) vbox, button, TRUE, FALSE, 0);
- g_signal_connect_swapped (button, "clicked", (GCallback) transfer, avail);
-
- button = gtk_button_new ();
- gtk_container_add ((GtkContainer *) button, gtk_image_new_from_icon_name
- ("go-previous", GTK_ICON_SIZE_BUTTON));
- gtk_box_pack_start ((GtkBox *) vbox, button, TRUE, FALSE, 0);
- g_signal_connect_swapped (button, "clicked", (GCallback) transfer, chosen);
-
- scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scroll,
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scroll,
- GTK_SHADOW_IN);
- gtk_box_pack_start ((GtkBox *) hbox, scroll, TRUE, TRUE, 0);
-
- chosen_list = audgui_list_new (& callbacks, chosen, index_count (chosen));
- audgui_list_add_column (chosen_list, _("Displayed columns"), 0, G_TYPE_STRING, -1);
- gtk_container_add ((GtkContainer *) scroll, chosen_list);
-
- g_signal_connect (hbox, "destroy", (GCallback) destroy_cb, NULL);
-
- return hbox;
-}
-
-void pw_col_save (void)
-{
- Index * index = index_new ();
-
- for (int i = 0; i < pw_num_cols; i ++)
- index_insert (index, -1, (void *) pw_col_keys[pw_cols[i]]);
-
- char * columns = index_to_str_list (index, " ");
- aud_set_str ("gtkui", "playlist_columns", columns);
- str_unref (columns);
-
- index_free (index);
-}
diff --git a/src/gtkui/columns.cc b/src/gtkui/columns.cc
new file mode 100644
index 000000000000..1ba300f9685c
--- /dev/null
+++ b/src/gtkui/columns.cc
@@ -0,0 +1,350 @@
+/*
+ * columns.c
+ * Copyright 2011 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/index.h>
+#include <libaudcore/audstrings.h>
+#include <libaudgui/libaudgui-gtk.h>
+#include <libaudgui/list.h>
+
+#include "ui_playlist_notebook.h"
+#include "ui_playlist_widget.h"
+
+const char * const pw_col_names[PW_COLS] = {
+ N_("Entry number"),
+ N_("Title"),
+ N_("Artist"),
+ N_("Year"),
+ N_("Album"),
+ N_("Album artist"),
+ N_("Track"),
+ N_("Genre"),
+ N_("Queue position"),
+ N_("Length"),
+ N_("File path"),
+ N_("File name"),
+ N_("Custom title"),
+ N_("Bitrate")
+};
+
+int pw_num_cols;
+int pw_cols[PW_COLS];
+int pw_col_widths[PW_COLS];
+
+static const char * const pw_col_keys[PW_COLS] = {
+ "number",
+ "title",
+ "artist",
+ "year",
+ "album",
+ "album-artist",
+ "track",
+ "genre",
+ "queued",
+ "length",
+ "path",
+ "filename",
+ "custom",
+ "bitrate"
+};
+
+static const int pw_default_widths[PW_COLS] = {
+ 10, // entry number
+ 275, // title
+ 175, // artist
+ 10, // year
+ 175, // album
+ 175, // album artist
+ 10, // track
+ 100, // genre
+ 10, // queue position
+ 10, // length
+ 275, // path
+ 275, // filename
+ 275, // custom title
+ 10 // bitrate
+};
+
+void pw_col_init ()
+{
+ pw_num_cols = 0;
+
+ String columns = aud_get_str ("gtkui", "playlist_columns");
+ Index<String> index = str_list_to_index (columns, " ");
+
+ int count = index.len ();
+ if (count > PW_COLS)
+ count = PW_COLS;
+
+ for (int c = 0; c < count; c ++)
+ {
+ const String & column = index[c];
+
+ int i = 0;
+ while (i < PW_COLS && strcmp (column, pw_col_keys[i]))
+ i ++;
+
+ if (i == PW_COLS)
+ break;
+
+ pw_cols[pw_num_cols ++] = i;
+ }
+
+ String widths = aud_get_str ("gtkui", "column_widths");
+ if (! str_to_int_array (widths, pw_col_widths, PW_COLS))
+ memcpy (pw_col_widths, pw_default_widths, sizeof pw_col_widths);
+}
+
+struct Column {
+ int column;
+ bool selected;
+};
+
+static GtkWidget * chosen_list = nullptr, * avail_list = nullptr;
+static Index<Column> chosen, avail;
+
+static void apply_changes ()
+{
+ int cols = chosen.len ();
+ g_return_if_fail (cols <= PW_COLS);
+
+ ui_playlist_notebook_empty ();
+
+ for (pw_num_cols = 0; pw_num_cols < cols; pw_num_cols ++)
+ pw_cols[pw_num_cols] = chosen[pw_num_cols].column;
+
+ ui_playlist_notebook_populate ();
+}
+
+static void get_value (void * user, int row, int column, GValue * value)
+{
+ auto & index = * (Index<Column> *) user;
+ g_return_if_fail (row >= 0 && row < index.len ());
+ g_value_set_string (value, _(pw_col_names[index[row].column]));
+}
+
+static bool get_selected (void * user, int row)
+{
+ auto & index = * (Index<Column> *) user;
+ g_return_val_if_fail (row >= 0 && row < index.len (), false);
+ return index[row].selected;
+}
+
+static void set_selected (void * user, int row, bool selected)
+{
+ auto & index = * (Index<Column> *) user;
+ g_return_if_fail (row >= 0 && row < index.len ());
+ index[row].selected = selected;
+}
+
+static void select_all (void * user, bool selected)
+{
+ auto & index = * (Index<Column> *) user;
+ for (Column & col : index)
+ col.selected = selected;
+}
+
+static void shift_rows (void * user, int row, int before)
+{
+ auto & index = * (Index<Column> *) user;
+ int rows = index.len ();
+ g_return_if_fail (row >= 0 && row < rows);
+ g_return_if_fail (before >= 0 && before <= rows);
+
+ if (before == row)
+ return;
+
+ Index<Column> move;
+ Index<Column> others;
+
+ int begin, end;
+ if (before < row)
+ {
+ begin = before;
+ end = row + 1;
+ while (end < rows && index[end].selected)
+ end ++;
+ }
+ else
+ {
+ begin = row;
+ while (begin > 0 && index[begin - 1].selected)
+ begin --;
+ end = before;
+ }
+
+ for (int i = begin; i < end; i ++)
+ {
+ if (index[i].selected)
+ move.append (index[i]);
+ else
+ others.append (index[i]);
+ }
+
+ if (before < row)
+ move.move_from (others, 0, -1, -1, true, true);
+ else
+ move.move_from (others, 0, 0, -1, true, true);
+
+ index.move_from (move, 0, begin, end - begin, false, true);
+
+ GtkWidget * list = (& index == & chosen) ? chosen_list : avail_list;
+ audgui_list_update_rows (list, begin, end - begin);
+ audgui_list_update_selection (list, begin, end - begin);
+
+ apply_changes ();
+}
+
+static const AudguiListCallbacks callbacks = {
+ get_value,
+ get_selected,
+ set_selected,
+ select_all,
+ nullptr, // activate_row
+ nullptr, // right_click
+ shift_rows
+};
+
+static void transfer (Index<Column> * source)
+{
+ Index<Column> * dest;
+ GtkWidget * source_list, * dest_list;
+ if (source == & chosen)
+ {
+ dest = & avail;
+ source_list = chosen_list;
+ dest_list = avail_list;
+ }
+ else
+ {
+ dest = & chosen;
+ source_list = avail_list;
+ dest_list = chosen_list;
+ }
+
+ int source_rows = source->len ();
+ int dest_rows = dest->len ();
+
+ for (int row = 0; row < source_rows; )
+ {
+ Column c = (* source)[row];
+ if (! c.selected)
+ {
+ row ++;
+ continue;
+ }
+
+ source->remove (row, 1);
+ audgui_list_delete_rows (source_list, row, 1);
+ source_rows --;
+ dest->append (c);
+ audgui_list_insert_rows (dest_list, dest_rows, 1);
+ dest_rows ++;
+ }
+
+ apply_changes ();
+}
+
+static void destroy_cb ()
+{
+ chosen_list = nullptr;
+ avail_list = nullptr;
+
+ chosen.clear ();
+ avail.clear ();
+}
+
+void * pw_col_create_chooser ()
+{
+ bool added[PW_COLS] = {};
+
+ for (int i = 0; i < pw_num_cols; i ++)
+ {
+ if (! added[pw_cols[i]])
+ {
+ added[pw_cols[i]] = true;
+ chosen.append (pw_cols[i], false);
+ }
+ }
+
+ for (int i = 0; i < PW_COLS; i ++)
+ {
+ if (! added[i])
+ avail.append (i, false);
+ }
+
+ GtkWidget * hbox = gtk_hbox_new (false, 6);
+ gtk_widget_set_size_request (hbox, -1, 160);
+
+ GtkWidget * scroll = gtk_scrolled_window_new (nullptr, nullptr);
+ gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scroll,
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scroll,
+ GTK_SHADOW_IN);
+ gtk_box_pack_start ((GtkBox *) hbox, scroll, true, true, 0);
+
+ avail_list = audgui_list_new (& callbacks, & avail, avail.len ());
+ audgui_list_add_column (avail_list, _("Available columns"), 0, G_TYPE_STRING, -1);
+ gtk_container_add ((GtkContainer *) scroll, avail_list);
+
+ GtkWidget * vbox = gtk_vbox_new (false, 6);
+ gtk_box_pack_start ((GtkBox *) hbox, vbox, false, false, 0);
+
+ GtkWidget * button = gtk_button_new ();
+ gtk_container_add ((GtkContainer *) button, gtk_image_new_from_icon_name
+ ("go-next", GTK_ICON_SIZE_BUTTON));
+ gtk_box_pack_start ((GtkBox *) vbox, button, true, false, 0);
+ g_signal_connect_swapped (button, "clicked", (GCallback) transfer, & avail);
+
+ button = gtk_button_new ();
+ gtk_container_add ((GtkContainer *) button, gtk_image_new_from_icon_name
+ ("go-previous", GTK_ICON_SIZE_BUTTON));
+ gtk_box_pack_start ((GtkBox *) vbox, button, true, false, 0);
+ g_signal_connect_swapped (button, "clicked", (GCallback) transfer, & chosen);
+
+ scroll = gtk_scrolled_window_new (nullptr, nullptr);
+ gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scroll,
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scroll,
+ GTK_SHADOW_IN);
+ gtk_box_pack_start ((GtkBox *) hbox, scroll, true, true, 0);
+
+ chosen_list = audgui_list_new (& callbacks, & chosen, chosen.len ());
+ audgui_list_add_column (chosen_list, _("Displayed columns"), 0, G_TYPE_STRING, -1);
+ gtk_container_add ((GtkContainer *) scroll, chosen_list);
+
+ g_signal_connect (hbox, "destroy", (GCallback) destroy_cb, nullptr);
+
+ return hbox;
+}
+
+void pw_col_save ()
+{
+ Index<String> index;
+ for (int i = 0; i < pw_num_cols; i ++)
+ index.append (String (pw_col_keys[pw_cols[i]]));
+
+ aud_set_str ("gtkui", "playlist_columns", index_to_str_list (index, " "));
+ aud_set_str ("gtkui", "column_widths", int_array_to_str (pw_col_widths, PW_COLS));
+}
diff --git a/src/gtkui/gtkui.h b/src/gtkui/gtkui.h
index a3d392f58d71..08d40edb4cbd 100644
--- a/src/gtkui/gtkui.h
+++ b/src/gtkui/gtkui.h
@@ -21,9 +21,9 @@
#define GTKUI_H
#include <stdint.h>
-
#include <gtk/gtk.h>
-#include <audacious/types.h>
+
+struct PluginPreferences;
/* menus.c */
GtkWidget * make_menu_bar (GtkAccelGroup * accel);
@@ -36,16 +36,17 @@ extern int menu_tab_playlist_id;
extern const PluginPreferences gtkui_prefs;
/* ui_gtk.c */
-void set_ab_repeat_a (void);
-void set_ab_repeat_b (void);
-void clear_ab_repeat (void);
-void show_hide_menu (void);
-void show_hide_infoarea (void);
-void show_hide_infoarea_vis (void);
-void show_hide_statusbar (void);
+void set_ab_repeat_a ();
+void set_ab_repeat_b ();
+void clear_ab_repeat ();
+void show_hide_menu ();
+void show_hide_infoarea ();
+void show_hide_infoarea_vis ();
+void show_hide_statusbar ();
void popup_menu_rclick (unsigned button, uint32_t time);
void popup_menu_tab (unsigned button, uint32_t time, int playlist);
-void activate_search_tool (void);
-void update_step_size (void);
+void activate_search_tool ();
+void activate_playlist_manager ();
+void update_step_size ();
#endif
diff --git a/src/gtkui/layout.c b/src/gtkui/layout.c
deleted file mode 100644
index d9a6c8b16378..000000000000
--- a/src/gtkui/layout.c
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * layout.c
- * Copyright 2011 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <string.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugins.h>
-
-#include "layout.h"
-
-#define DEFAULT_WIDTH 300
-#define DEFAULT_HEIGHT 200
-
-enum {DOCK_LEFT, DOCK_RIGHT, DOCK_TOP, DOCK_BOTTOM, DOCKS};
-
-#define IS_VERTICAL(d) ((d) & 2)
-#define IS_AFTER(d) ((d) & 1)
-
-#define NULL_ON_DESTROY(w) g_signal_connect ((w), "destroy", (GCallback) \
- gtk_widget_destroyed, & (w))
-
-typedef struct {
- char * name;
- GtkWidget * widget, * vbox, * paned, * window;
- int dock, x, y, w, h;
-} Item;
-
-static GList * items = NULL;
-
-static GtkWidget * layout = NULL;
-static GtkWidget * center = NULL;
-static GtkWidget * docks[DOCKS] = {NULL, NULL, NULL, NULL};
-static GtkWidget * menu = NULL;
-
-GtkWidget * layout_new (void)
-{
- g_return_val_if_fail (! layout, NULL);
- layout = gtk_alignment_new (0, 0, 1, 1);
- gtk_alignment_set_padding ((GtkAlignment *) layout, 3, 3, 3, 3);
- NULL_ON_DESTROY (layout);
- return layout;
-}
-
-void layout_add_center (GtkWidget * widget)
-{
- g_return_if_fail (layout && ! center && widget);
- center = widget;
- gtk_container_add ((GtkContainer *) layout, center);
- NULL_ON_DESTROY (center);
-}
-
-static void layout_move (GtkWidget * widget, int dock);
-
-static void layout_dock_left (GtkWidget * widget)
-{
- layout_move (widget, DOCK_LEFT);
-}
-
-static void layout_dock_right (GtkWidget * widget)
-{
- layout_move (widget, DOCK_RIGHT);
-}
-
-static void layout_dock_top (GtkWidget * widget)
-{
- layout_move (widget, DOCK_TOP);
-}
-
-static void layout_dock_bottom (GtkWidget * widget)
-{
- layout_move (widget, DOCK_BOTTOM);
-}
-
-static void layout_undock (GtkWidget * widget)
-{
- layout_move (widget, -1);
-}
-
-static void layout_disable (GtkWidget * widget)
-{
- PluginHandle * plugin = aud_plugin_by_widget (widget);
- g_return_if_fail (plugin);
- aud_plugin_enable (plugin, FALSE);
-}
-
-static bool_t menu_cb (GtkWidget * widget, GdkEventButton * event)
-{
- g_return_val_if_fail (widget && event, FALSE);
-
- if (event->type != GDK_BUTTON_PRESS || event->button != 3)
- return FALSE;
-
- if (menu)
- gtk_widget_destroy (menu);
-
- menu = gtk_menu_new ();
- g_signal_connect (menu, "destroy", (GCallback) gtk_widget_destroyed, & menu);
-
- const char * names[6] = {N_("Dock at Left"), N_("Dock at Right"),
- N_("Dock at Top"), N_("Dock at Bottom"), N_("Undock"), N_("Disable")};
- void (* const funcs[6]) (GtkWidget * widget) = {layout_dock_left,
- layout_dock_right, layout_dock_top, layout_dock_bottom, layout_undock,
- layout_disable};
-
- for (int i = 0; i < 6; i ++)
- {
- GtkWidget * item = gtk_menu_item_new_with_label (_(names[i]));
- gtk_menu_shell_append ((GtkMenuShell *) menu, item);
- g_signal_connect_swapped (item, "activate", (GCallback) funcs[i], widget);
- }
-
- gtk_widget_show_all (menu);
- gtk_menu_popup ((GtkMenu *) menu, NULL, NULL, NULL, NULL, event->button, event->time);
-
- return TRUE;
-}
-
-static GtkWidget * vbox_new (GtkWidget * widget, const char * name)
-{
- g_return_val_if_fail (widget && name, NULL);
-
- GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
-
- GtkWidget * ebox = gtk_event_box_new ();
- gtk_box_pack_start ((GtkBox *) vbox, ebox, FALSE, FALSE, 0);
- g_signal_connect_swapped (ebox, "button-press-event", (GCallback) menu_cb,
- widget);
-
- GtkWidget * label = gtk_label_new (NULL);
- char * markup = g_markup_printf_escaped ("<small><b>%s</b></small>", name);
- gtk_label_set_markup ((GtkLabel *) label, markup);
- g_free (markup);
- gtk_misc_set_alignment ((GtkMisc *) label, 0, 0);
- gtk_container_add ((GtkContainer *) ebox, label);
-
- gtk_box_pack_start ((GtkBox *) vbox, widget, TRUE, TRUE, 0);
-
- gtk_widget_show_all (vbox);
-
- return vbox;
-}
-
-typedef struct {
- GtkWidget * paned;
- GtkWidget * widget;
- bool_t vertical;
- int w, h;
-} RestoreSizeData;
-
-static bool_t restore_size_cb (RestoreSizeData * d)
-{
- GtkAllocation rect;
- gtk_widget_get_allocation (d->widget, & rect);
- int pos = gtk_paned_get_position ((GtkPaned *) d->paned);
- pos -= d->vertical ? d->h - rect.height : d->w - rect.width;
- gtk_paned_set_position ((GtkPaned *) d->paned, pos);
-
- g_slice_free (RestoreSizeData, d);
- return FALSE;
-}
-
-static GtkWidget * paned_new (bool_t vertical, bool_t after, int w, int h)
-{
- GtkWidget * paned = gtk_paned_new (vertical ? GTK_ORIENTATION_VERTICAL :
- GTK_ORIENTATION_HORIZONTAL);
-
- GtkWidget * mine = gtk_alignment_new (0, 0, 1, 1);
- GtkWidget * next = gtk_alignment_new (0, 0, 1, 1);
- gtk_paned_pack1 ((GtkPaned *) paned, after ? next : mine, after, FALSE);
- gtk_paned_pack2 ((GtkPaned *) paned, after ? mine : next, ! after, FALSE);
-
- g_object_set_data ((GObject *) paned, "mine", mine);
- g_object_set_data ((GObject *) paned, "next", next);
-
- gtk_widget_show_all (paned);
-
- if (vertical ? h : w)
- {
- if (after)
- {
- /* hack to set the size of the second pane */
- RestoreSizeData * d = g_slice_new (RestoreSizeData);
- d->paned = paned;
- d->widget = mine;
- d->vertical = vertical;
- d->w = w;
- d->h = h;
- g_idle_add ((GSourceFunc) restore_size_cb, d);
- }
- else
- gtk_paned_set_position ((GtkPaned *) paned, vertical ? h : w);
- }
-
- return paned;
-}
-
-static Item * item_new (const char * name)
-{
- Item * item = g_slice_new (Item);
- item->name = str_get (name);
- item->widget = item->vbox = item->paned = item->window = NULL;
- item->dock = item->x = item->y = -1;
- item->w = DEFAULT_WIDTH;
- item->h = DEFAULT_HEIGHT;
-
- if (! strcmp (name, _("Search Tool")))
- {
- item->dock = DOCK_LEFT;
- item->w = 200;
- }
-
- items = g_list_append (items, item);
- return item;
-}
-
-static int item_by_widget (Item * item, GtkWidget * widget)
-{
- return (item->widget != widget);
-}
-
-static int item_by_name (Item * item, const char * name)
-{
- return strcmp (item->name, name);
-}
-
-static bool_t delete_cb (GtkWidget * widget)
-{
- layout_disable (widget);
- return TRUE;
-}
-
-static bool_t escape_cb (GtkWidget * widget, GdkEventKey * event)
-{
- if (event->keyval == GDK_KEY_Escape)
- {
- layout_disable (widget);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static GtkWidget * dock_get_parent (int dock)
-{
- g_return_val_if_fail (dock >= 0 && dock < DOCKS, NULL);
-
- for (int scan = dock; scan --; )
- {
- if (docks[scan])
- return g_object_get_data ((GObject *) docks[scan], "next");
- }
-
- return layout;
-}
-
-static Item * item_get_prev (Item * item)
-{
- GList * this = g_list_find (items, item);
- g_return_val_if_fail (this, NULL);
-
- for (GList * node = this->prev; node; node = node->prev)
- {
- Item * test = node->data;
- if (test->widget && test->dock == item->dock)
- return test;
- }
-
- return NULL;
-}
-
-static Item * item_get_next (Item * item)
-{
- GList * this = g_list_find (items, item);
- g_return_val_if_fail (this, NULL);
-
- for (GList * node = this->next; node; node = node->next)
- {
- Item * test = node->data;
- if (test->widget && test->dock == item->dock)
- return test;
- }
-
- return NULL;
-}
-
-static GtkWidget * item_get_parent (Item * item)
-{
- Item * prev = item_get_prev (item);
- return prev ? g_object_get_data ((GObject *) prev->paned, "next") :
- g_object_get_data ((GObject *) docks[item->dock], "mine");
-}
-
-static void item_add (Item * item)
-{
- g_return_if_fail (item->name && item->widget && item->vbox && ! item->paned
- && ! item->window && item->dock < DOCKS);
-
- if (item->dock < 0)
- {
- item->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- NULL_ON_DESTROY (item->window);
-
- gtk_window_set_title ((GtkWindow *) item->window, item->name);
- gtk_container_set_border_width ((GtkContainer *) item->window, 2);
- gtk_window_set_has_resize_grip ((GtkWindow *) item->window, FALSE);
-
- g_signal_connect_swapped (item->window, "delete-event", (GCallback)
- delete_cb, item->widget);
- g_signal_connect_swapped (item->window, "key-press-event", (GCallback)
- escape_cb, item->widget);
-
- if (item->x >= 0 && item->y >= 0)
- gtk_window_move ((GtkWindow *) item->window, item->x, item->y);
- if (item->w > 0 && item->h > 0)
- gtk_window_set_default_size ((GtkWindow *) item->window, item->w,
- item->h);
-
- gtk_container_add ((GtkContainer *) item->window, item->vbox);
- gtk_widget_show_all (item->window);
- }
- else
- {
- /* Screwy logic to figure out where we need to add a GtkPaned and which
- * widget goes in which pane of it. */
- bool_t swap = FALSE;
- Item * where = item;
- GtkWidget * parent, * paned;
-
- if (docks[item->dock])
- {
- if (! item_get_next (item))
- {
- swap = TRUE;
- where = item_get_prev (item);
- g_return_if_fail (where && ! where->paned);
- }
-
- parent = item_get_parent (where);
- g_return_if_fail (parent);
-
- paned = paned_new (! IS_VERTICAL (where->dock), FALSE, where->w,
- where->h);
- where->paned = paned;
- NULL_ON_DESTROY (where->paned);
- }
- else
- {
- parent = dock_get_parent (item->dock);
- g_return_if_fail (parent);
-
- paned = paned_new (IS_VERTICAL (item->dock), IS_AFTER (item->dock),
- item->w, item->h);
- docks[item->dock] = paned;
- NULL_ON_DESTROY (docks[item->dock]);
- }
-
- GtkWidget * mine = g_object_get_data ((GObject *) paned, "mine");
- GtkWidget * next = g_object_get_data ((GObject *) paned, "next");
- GtkWidget * child = gtk_bin_get_child ((GtkBin *) parent);
- g_return_if_fail (mine && next && child);
-
- g_object_ref (child);
- gtk_container_remove ((GtkContainer *) parent, child);
- gtk_container_add ((GtkContainer *) parent, paned);
- gtk_container_add ((GtkContainer *) (swap ? next : mine), item->vbox);
- gtk_container_add ((GtkContainer *) (swap ? mine : next), child);
- g_object_unref (child);
- }
-}
-
-static void item_remove (Item * item)
-{
- g_return_if_fail (item->widget && item->vbox);
-
- if (item->dock < 0)
- {
- g_return_if_fail (item->window);
- gtk_container_remove ((GtkContainer *) item->window, item->vbox);
- gtk_widget_destroy (item->window);
- }
- else
- {
- /* Screwy logic to figure out which GtkPaned we need to remove and which
- * pane of it has the widget we need to keep. */
- bool_t swap = FALSE;
- Item * where = item;
- GtkWidget * parent, * paned;
-
- Item * prev = item_get_prev (item);
- if (item->paned || prev)
- {
- if (! item->paned)
- {
- swap = TRUE;
- where = item_get_prev (item);
- g_return_if_fail (where && where->paned);
- }
-
- parent = item_get_parent (where);
- g_return_if_fail (parent);
-
- paned = where->paned;
- }
- else
- {
- parent = dock_get_parent (item->dock);
- g_return_if_fail (parent);
-
- paned = docks[item->dock];
- }
-
- GtkWidget * mine = g_object_get_data ((GObject *) paned, "mine");
- GtkWidget * next = g_object_get_data ((GObject *) paned, "next");
- GtkWidget * child = gtk_bin_get_child ((GtkBin *) (swap ? mine : next));
- g_return_if_fail (mine && next && child);
-
- g_object_ref (child);
- gtk_container_remove ((GtkContainer *) (swap ? next : mine), item->vbox);
- gtk_container_remove ((GtkContainer *) (swap ? mine : next), child);
- gtk_container_remove ((GtkContainer *) parent, paned);
- gtk_container_add ((GtkContainer *) parent, child);
- g_object_unref (child);
- }
-}
-
-static void size_changed_cb (GtkWidget * widget, GdkRectangle * rect, Item * item)
-{
- item->w = rect->width;
- item->h = rect->height;
-
- if (item->dock < 0)
- {
- g_return_if_fail (item->window);
- gtk_window_get_position ((GtkWindow *) item->window, & item->x, & item->y);
- }
-}
-
-void layout_add (GtkWidget * widget, const char * name)
-{
- g_return_if_fail (layout && center && widget && name && strlen (name) <= 256
- && ! strchr (name, '\n'));
-
- GList * node = g_list_find_custom (items, name, (GCompareFunc) item_by_name);
- Item * item = node ? node->data : NULL;
-
- if (item)
- {
- g_return_if_fail (! item->widget && ! item->vbox && ! item->window);
- if (item->dock >= DOCKS)
- item->dock = -1;
- }
- else
- item = item_new (name);
-
- item->widget = widget;
- NULL_ON_DESTROY (item->widget);
- item->vbox = vbox_new (widget, name);
- NULL_ON_DESTROY (item->vbox);
-
- g_signal_connect (item->vbox, "size-allocate", (GCallback) size_changed_cb, item);
-
- item_add (item);
-}
-
-static void layout_move (GtkWidget * widget, int dock)
-{
- g_return_if_fail (layout && center && widget && dock < DOCKS);
-
- GList * node = g_list_find_custom (items, widget, (GCompareFunc) item_by_widget);
- g_return_if_fail (node && node->data);
- Item * item = node->data;
-
- g_return_if_fail (item->vbox);
- g_object_ref (item->vbox);
-
- item_remove (item);
- items = g_list_remove_link (items, node);
- item->dock = dock;
- items = g_list_concat (items, node);
- item_add (item);
-
- g_object_unref (item->vbox);
-}
-
-void layout_remove (GtkWidget * widget)
-{
- g_return_if_fail (layout && center && widget);
-
- /* menu may hold pointers to this widget */
- if (menu)
- gtk_widget_destroy (menu);
-
- GList * node = g_list_find_custom (items, widget, (GCompareFunc) item_by_widget);
- g_return_if_fail (node && node->data);
- Item * item = node->data;
-
- item_remove (item);
- g_return_if_fail (! item->widget && ! item->vbox && ! item->window);
-}
-
-void layout_save (void)
-{
- int i = 0;
-
- for (GList * node = items; node; node = node->next)
- {
- Item * item = node->data;
- g_return_if_fail (item && item->name);
-
- char key[16], value[64];
-
- snprintf (key, sizeof key, "item%d_name", i);
- aud_set_str ("gtkui-layout", key, item->name);
-
- snprintf (key, sizeof key, "item%d_pos", i);
- snprintf (value, sizeof value, "%d,%d,%d,%d,%d", item->dock, item->x,
- item->y, item->w, item->h);
- aud_set_str ("gtkui-layout", key, value);
-
- i ++;
- }
-
- aud_set_int ("gtkui-layout", "item_count", i);
-}
-
-void layout_load (void)
-{
- g_return_if_fail (! items);
-
- int count = aud_get_int ("gtkui-layout", "item_count");
-
- for (int i = 0; i < count; i ++)
- {
- char key[16];
-
- snprintf (key, sizeof key, "item%d_name", i);
- char * name = aud_get_str ("gtkui-layout", key);
- Item * item = item_new (name);
- str_unref (name);
-
- snprintf (key, sizeof key, "item%d_pos", i);
- char * pos = aud_get_str ("gtkui-layout", key);
- sscanf (pos, "%d,%d,%d,%d,%d", & item->dock, & item->x, & item->y, & item->w, & item->h);
- str_unref (pos);
- }
-}
-
-void layout_cleanup (void)
-{
- for (GList * node = items; node; node = node->next)
- {
- Item * item = node->data;
- g_return_if_fail (item && ! item->widget && ! item->vbox && ! item->window);
- str_unref (item->name);
- g_slice_free (Item, item);
- }
-
- g_list_free (items);
- items = NULL;
-}
diff --git a/src/gtkui/layout.cc b/src/gtkui/layout.cc
new file mode 100644
index 000000000000..3619ea236d4c
--- /dev/null
+++ b/src/gtkui/layout.cc
@@ -0,0 +1,616 @@
+/*
+ * layout.c
+ * Copyright 2011 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <string.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugins.h>
+
+#include "layout.h"
+
+#define DEFAULT_WIDTH 300
+#define DEFAULT_HEIGHT 200
+
+enum {
+ DOCK_LEFT,
+ DOCK_RIGHT,
+ DOCK_TOP,
+ DOCK_BOTTOM,
+ DOCKS
+};
+
+#define IS_VERTICAL(d) ((d) & 2)
+#define IS_AFTER(d) ((d) & 1)
+
+#define NULL_ON_DESTROY(w) g_signal_connect ((w), "destroy", (GCallback) \
+ gtk_widget_destroyed, & (w))
+
+typedef struct {
+ String name;
+ PluginHandle * plugin;
+ GtkWidget * widget, * vbox, * paned, * window;
+ int dock, x, y, w, h;
+} Item;
+
+static GList * items = nullptr;
+
+static GtkWidget * layout = nullptr;
+static GtkWidget * center = nullptr;
+static GtkWidget * docks[DOCKS] = {nullptr, nullptr, nullptr, nullptr};
+static GtkWidget * menu = nullptr;
+
+static Item * item_new (const char * name)
+{
+ Item * item = new Item ();
+ item->name = String (name);
+ item->plugin = nullptr;
+ item->widget = item->vbox = item->paned = item->window = nullptr;
+ item->dock = item->x = item->y = -1;
+ item->w = DEFAULT_WIDTH;
+ item->h = DEFAULT_HEIGHT;
+
+ if (! strcmp (name, _("Search Tool")))
+ {
+ item->dock = DOCK_LEFT;
+ item->w = 200;
+ }
+
+ items = g_list_append (items, item);
+ return item;
+}
+
+static int item_by_plugin (Item * item, PluginHandle * plugin)
+{
+ return (item->plugin != plugin);
+}
+
+static int item_by_widget (Item * item, GtkWidget * widget)
+{
+ return (item->widget != widget);
+}
+
+static int item_by_name (Item * item, const char * name)
+{
+ return strcmp (item->name, name);
+}
+
+GtkWidget * layout_new ()
+{
+ g_return_val_if_fail (! layout, nullptr);
+ layout = gtk_alignment_new (0, 0, 1, 1);
+ gtk_alignment_set_padding ((GtkAlignment *) layout, 3, 3, 3, 3);
+ NULL_ON_DESTROY (layout);
+ return layout;
+}
+
+void layout_add_center (GtkWidget * widget)
+{
+ g_return_if_fail (layout && ! center && widget);
+ center = widget;
+ gtk_container_add ((GtkContainer *) layout, center);
+ NULL_ON_DESTROY (center);
+}
+
+static void layout_move (GtkWidget * widget, int dock);
+
+static void layout_dock_left (GtkWidget * widget)
+{
+ layout_move (widget, DOCK_LEFT);
+}
+
+static void layout_dock_right (GtkWidget * widget)
+{
+ layout_move (widget, DOCK_RIGHT);
+}
+
+static void layout_dock_top (GtkWidget * widget)
+{
+ layout_move (widget, DOCK_TOP);
+}
+
+static void layout_dock_bottom (GtkWidget * widget)
+{
+ layout_move (widget, DOCK_BOTTOM);
+}
+
+static void layout_undock (GtkWidget * widget)
+{
+ layout_move (widget, -1);
+}
+
+static void layout_disable (GtkWidget * widget)
+{
+ g_return_if_fail (layout && center && widget);
+
+ GList * node = g_list_find_custom (items, widget, (GCompareFunc) item_by_widget);
+ g_return_if_fail (node);
+
+ Item * item = (Item *) node->data;
+ g_return_if_fail (item->plugin);
+
+ aud_plugin_enable (item->plugin, false);
+}
+
+static gboolean menu_cb (GtkWidget * widget, GdkEventButton * event)
+{
+ g_return_val_if_fail (widget && event, false);
+
+ if (event->type != GDK_BUTTON_PRESS || event->button != 3)
+ return false;
+
+ if (menu)
+ gtk_widget_destroy (menu);
+
+ menu = gtk_menu_new ();
+ g_signal_connect (menu, "destroy", (GCallback) gtk_widget_destroyed, & menu);
+
+ const char * names[6] = {N_("Dock at Left"), N_("Dock at Right"),
+ N_("Dock at Top"), N_("Dock at Bottom"), N_("Undock"), N_("Disable")};
+ void (* const funcs[6]) (GtkWidget * widget) = {layout_dock_left,
+ layout_dock_right, layout_dock_top, layout_dock_bottom, layout_undock,
+ layout_disable};
+
+ for (int i = 0; i < 6; i ++)
+ {
+ GtkWidget * item = gtk_menu_item_new_with_label (_(names[i]));
+ gtk_menu_shell_append ((GtkMenuShell *) menu, item);
+ g_signal_connect_swapped (item, "activate", (GCallback) funcs[i], widget);
+ }
+
+ gtk_widget_show_all (menu);
+ gtk_menu_popup ((GtkMenu *) menu, nullptr, nullptr, nullptr, nullptr, event->button, event->time);
+
+ return true;
+}
+
+static GtkWidget * vbox_new (GtkWidget * widget, const char * name)
+{
+ g_return_val_if_fail (widget && name, nullptr);
+
+ GtkWidget * vbox = gtk_vbox_new (false, 2);
+
+ GtkWidget * ebox = gtk_event_box_new ();
+ gtk_box_pack_start ((GtkBox *) vbox, ebox, false, false, 0);
+ g_signal_connect_swapped (ebox, "button-press-event", (GCallback) menu_cb,
+ widget);
+
+ GtkWidget * label = gtk_label_new (nullptr);
+ char * markup = g_markup_printf_escaped ("<small><b>%s</b></small>", name);
+ gtk_label_set_markup ((GtkLabel *) label, markup);
+ g_free (markup);
+ gtk_misc_set_alignment ((GtkMisc *) label, 0, 0);
+ gtk_container_add ((GtkContainer *) ebox, label);
+
+ gtk_box_pack_start ((GtkBox *) vbox, widget, true, true, 0);
+
+ gtk_widget_show_all (vbox);
+
+ return vbox;
+}
+
+typedef struct {
+ GtkWidget * paned;
+ GtkWidget * widget;
+ bool vertical;
+ int w, h;
+} RestoreSizeData;
+
+static gboolean restore_size_cb (RestoreSizeData * d)
+{
+ GtkAllocation rect;
+ gtk_widget_get_allocation (d->widget, & rect);
+ int pos = gtk_paned_get_position ((GtkPaned *) d->paned);
+ pos -= d->vertical ? d->h - rect.height : d->w - rect.width;
+ gtk_paned_set_position ((GtkPaned *) d->paned, pos);
+
+ g_slice_free (RestoreSizeData, d);
+ return false;
+}
+
+static GtkWidget * paned_new (bool vertical, bool after, int w, int h)
+{
+ GtkWidget * paned = vertical ? gtk_vpaned_new () : gtk_hpaned_new ();
+
+ GtkWidget * mine = gtk_alignment_new (0, 0, 1, 1);
+ GtkWidget * next = gtk_alignment_new (0, 0, 1, 1);
+ gtk_paned_pack1 ((GtkPaned *) paned, after ? next : mine, after, false);
+ gtk_paned_pack2 ((GtkPaned *) paned, after ? mine : next, ! after, false);
+
+ g_object_set_data ((GObject *) paned, "mine", mine);
+ g_object_set_data ((GObject *) paned, "next", next);
+
+ gtk_widget_show_all (paned);
+
+ if (vertical ? h : w)
+ {
+ if (after)
+ {
+ /* hack to set the size of the second pane */
+ RestoreSizeData * d = g_slice_new (RestoreSizeData);
+ d->paned = paned;
+ d->widget = mine;
+ d->vertical = vertical;
+ d->w = w;
+ d->h = h;
+ g_idle_add ((GSourceFunc) restore_size_cb, d);
+ }
+ else
+ gtk_paned_set_position ((GtkPaned *) paned, vertical ? h : w);
+ }
+
+ return paned;
+}
+
+static gboolean delete_cb (GtkWidget * widget)
+{
+ layout_disable (widget);
+ return true;
+}
+
+static gboolean escape_cb (GtkWidget * widget, GdkEventKey * event)
+{
+ if (event->keyval == GDK_KEY_Escape)
+ {
+ layout_disable (widget);
+ return true;
+ }
+
+ return false;
+}
+
+static GtkWidget * dock_get_parent (int dock)
+{
+ g_return_val_if_fail (dock >= 0 && dock < DOCKS, nullptr);
+
+ for (int scan = dock; scan --; )
+ {
+ if (docks[scan])
+ return (GtkWidget *) g_object_get_data ((GObject *) docks[scan], "next");
+ }
+
+ return layout;
+}
+
+static Item * item_get_prev (Item * item)
+{
+ GList * node = g_list_find (items, item);
+ g_return_val_if_fail (node, nullptr);
+
+ while ((node = node->prev))
+ {
+ Item * test = (Item *) node->data;
+ if (test->widget && test->dock == item->dock)
+ return test;
+ }
+
+ return nullptr;
+}
+
+static Item * item_get_next (Item * item)
+{
+ GList * node = g_list_find (items, item);
+ g_return_val_if_fail (node, nullptr);
+
+ while ((node = node->next))
+ {
+ Item * test = (Item *) node->data;
+ if (test->widget && test->dock == item->dock)
+ return test;
+ }
+
+ return nullptr;
+}
+
+static GtkWidget * item_get_parent (Item * item)
+{
+ Item * prev = item_get_prev (item);
+
+ if (prev)
+ return (GtkWidget *) g_object_get_data ((GObject *) prev->paned, "next");
+ else
+ return (GtkWidget *) g_object_get_data ((GObject *) docks[item->dock], "mine");
+}
+
+static void item_add (Item * item)
+{
+ g_return_if_fail (item->name && item->widget && item->vbox && ! item->paned
+ && ! item->window && item->dock < DOCKS);
+
+ if (item->dock < 0)
+ {
+ item->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ NULL_ON_DESTROY (item->window);
+
+ gtk_window_set_title ((GtkWindow *) item->window, item->name);
+ gtk_container_set_border_width ((GtkContainer *) item->window, 2);
+
+ g_signal_connect_swapped (item->window, "delete-event", (GCallback)
+ delete_cb, item->widget);
+ g_signal_connect_swapped (item->window, "key-press-event", (GCallback)
+ escape_cb, item->widget);
+
+ if (item->x >= 0 && item->y >= 0)
+ gtk_window_move ((GtkWindow *) item->window, item->x, item->y);
+ if (item->w > 0 && item->h > 0)
+ gtk_window_set_default_size ((GtkWindow *) item->window, item->w,
+ item->h);
+
+ gtk_container_add ((GtkContainer *) item->window, item->vbox);
+ gtk_widget_show_all (item->window);
+ }
+ else
+ {
+ /* Screwy logic to figure out where we need to add a GtkPaned and which
+ * widget goes in which pane of it. */
+ bool swap = false;
+ Item * where = item;
+ GtkWidget * parent, * paned;
+
+ if (docks[item->dock])
+ {
+ if (! item_get_next (item))
+ {
+ swap = true;
+ where = item_get_prev (item);
+ g_return_if_fail (where && ! where->paned);
+ }
+
+ parent = item_get_parent (where);
+ g_return_if_fail (parent);
+
+ paned = paned_new (! IS_VERTICAL (where->dock), false, where->w,
+ where->h);
+ where->paned = paned;
+ NULL_ON_DESTROY (where->paned);
+ }
+ else
+ {
+ parent = dock_get_parent (item->dock);
+ g_return_if_fail (parent);
+
+ paned = paned_new (IS_VERTICAL (item->dock), IS_AFTER (item->dock),
+ item->w, item->h);
+ docks[item->dock] = paned;
+ NULL_ON_DESTROY (docks[item->dock]);
+ }
+
+ GtkWidget * mine = (GtkWidget *) g_object_get_data ((GObject *) paned, "mine");
+ GtkWidget * next = (GtkWidget *) g_object_get_data ((GObject *) paned, "next");
+ GtkWidget * child = gtk_bin_get_child ((GtkBin *) parent);
+ g_return_if_fail (mine && next && child);
+
+ g_object_ref (child);
+ gtk_container_remove ((GtkContainer *) parent, child);
+ gtk_container_add ((GtkContainer *) parent, paned);
+ gtk_container_add ((GtkContainer *) (swap ? next : mine), item->vbox);
+ gtk_container_add ((GtkContainer *) (swap ? mine : next), child);
+ g_object_unref (child);
+ }
+}
+
+static void item_remove (Item * item)
+{
+ g_return_if_fail (item->widget && item->vbox);
+
+ if (item->dock < 0)
+ {
+ g_return_if_fail (item->window);
+ gtk_container_remove ((GtkContainer *) item->window, item->vbox);
+ gtk_widget_destroy (item->window);
+ }
+ else
+ {
+ /* Screwy logic to figure out which GtkPaned we need to remove and which
+ * pane of it has the widget we need to keep. */
+ bool swap = false;
+ Item * where = item;
+ GtkWidget * parent, * paned;
+
+ Item * prev = item_get_prev (item);
+ if (item->paned || prev)
+ {
+ if (! item->paned)
+ {
+ swap = true;
+ where = item_get_prev (item);
+ g_return_if_fail (where && where->paned);
+ }
+
+ parent = item_get_parent (where);
+ g_return_if_fail (parent);
+
+ paned = where->paned;
+ }
+ else
+ {
+ parent = dock_get_parent (item->dock);
+ g_return_if_fail (parent);
+
+ paned = docks[item->dock];
+ }
+
+ GtkWidget * mine = (GtkWidget *) g_object_get_data ((GObject *) paned, "mine");
+ GtkWidget * next = (GtkWidget *) g_object_get_data ((GObject *) paned, "next");
+ GtkWidget * child = gtk_bin_get_child ((GtkBin *) (swap ? mine : next));
+ g_return_if_fail (mine && next && child);
+
+ g_object_ref (child);
+ gtk_container_remove ((GtkContainer *) (swap ? next : mine), item->vbox);
+ gtk_container_remove ((GtkContainer *) (swap ? mine : next), child);
+ gtk_container_remove ((GtkContainer *) parent, paned);
+ gtk_container_add ((GtkContainer *) parent, child);
+ g_object_unref (child);
+ }
+}
+
+static void size_changed_cb (GtkWidget * widget, GdkRectangle * rect, Item * item)
+{
+ item->w = rect->width;
+ item->h = rect->height;
+
+ if (item->dock < 0)
+ {
+ g_return_if_fail (item->window);
+ gtk_window_get_position ((GtkWindow *) item->window, & item->x, & item->y);
+ }
+}
+
+void layout_add (PluginHandle * plugin, GtkWidget * widget)
+{
+ g_return_if_fail (layout && center && plugin && widget);
+
+ const char * name = aud_plugin_get_name (plugin);
+ g_return_if_fail (name);
+
+ GList * node = g_list_find_custom (items, name, (GCompareFunc) item_by_name);
+ Item * item = node ? (Item *) node->data : nullptr;
+
+ if (item)
+ {
+ g_return_if_fail (! item->widget && ! item->vbox && ! item->window);
+ if (item->dock >= DOCKS)
+ item->dock = -1;
+ }
+ else
+ item = item_new (name);
+
+ item->plugin = plugin;
+ item->widget = widget;
+ NULL_ON_DESTROY (item->widget);
+ item->vbox = vbox_new (widget, name);
+ NULL_ON_DESTROY (item->vbox);
+
+ g_signal_connect (item->vbox, "size-allocate", (GCallback) size_changed_cb, item);
+
+ item_add (item);
+}
+
+static void layout_move (GtkWidget * widget, int dock)
+{
+ g_return_if_fail (layout && center && widget && dock < DOCKS);
+
+ GList * node = g_list_find_custom (items, widget, (GCompareFunc) item_by_widget);
+ g_return_if_fail (node);
+ Item * item = (Item *) node->data;
+
+ g_return_if_fail (item->vbox);
+ g_object_ref (item->vbox);
+
+ item_remove (item);
+ items = g_list_remove_link (items, node);
+ item->dock = dock;
+ items = g_list_concat (items, node);
+ item_add (item);
+
+ g_object_unref (item->vbox);
+}
+
+void layout_remove (PluginHandle * plugin)
+{
+ g_return_if_fail (layout && center && plugin);
+
+ GList * node = g_list_find_custom (items, plugin, (GCompareFunc) item_by_plugin);
+ if (! node)
+ return;
+
+ /* menu may hold pointers to this widget */
+ if (menu)
+ gtk_widget_destroy (menu);
+
+ item_remove ((Item *) node->data);
+}
+
+void layout_focus (PluginHandle * plugin)
+{
+ g_return_if_fail (layout && center && plugin);
+
+ GList * node = g_list_find_custom (items, plugin, (GCompareFunc) item_by_plugin);
+ if (! node)
+ return;
+
+ Item * item = (Item *) node->data;
+ g_return_if_fail (item);
+
+ if (item->window)
+ gtk_window_present ((GtkWindow *) item->window);
+
+ aud_plugin_send_message (plugin, "grab focus", nullptr, 0);
+}
+
+void layout_save ()
+{
+ int i = 0;
+
+ for (GList * node = items; node; node = node->next)
+ {
+ Item * item = (Item *) node->data;
+ g_return_if_fail (item && item->name);
+
+ char key[16], value[64];
+
+ snprintf (key, sizeof key, "item%d_name", i);
+ aud_set_str ("gtkui-layout", key, item->name);
+
+ snprintf (key, sizeof key, "item%d_pos", i);
+ snprintf (value, sizeof value, "%d,%d,%d,%d,%d", item->dock, item->x,
+ item->y, item->w, item->h);
+ aud_set_str ("gtkui-layout", key, value);
+
+ i ++;
+ }
+
+ aud_set_int ("gtkui-layout", "item_count", i);
+}
+
+void layout_load ()
+{
+ g_return_if_fail (! items);
+
+ int count = aud_get_int ("gtkui-layout", "item_count");
+
+ for (int i = 0; i < count; i ++)
+ {
+ char key[16];
+
+ snprintf (key, sizeof key, "item%d_name", i);
+ String name = aud_get_str ("gtkui-layout", key);
+ Item * item = item_new (name);
+
+ snprintf (key, sizeof key, "item%d_pos", i);
+ String pos = aud_get_str ("gtkui-layout", key);
+ sscanf (pos, "%d,%d,%d,%d,%d", & item->dock, & item->x, & item->y, & item->w, & item->h);
+ }
+}
+
+void layout_cleanup ()
+{
+ for (GList * node = items; node; node = node->next)
+ {
+ Item * item = (Item *) node->data;
+ g_return_if_fail (! item->widget && ! item->vbox && ! item->window);
+ delete item;
+ }
+
+ g_list_free (items);
+ items = nullptr;
+}
diff --git a/src/gtkui/layout.h b/src/gtkui/layout.h
index eb6494583c93..e2a8b67743de 100644
--- a/src/gtkui/layout.h
+++ b/src/gtkui/layout.h
@@ -22,13 +22,14 @@
#include <gtk/gtk.h>
-void layout_load (void);
-void layout_save (void);
-void layout_cleanup (void);
+void layout_load ();
+void layout_save ();
+void layout_cleanup ();
-GtkWidget * layout_new (void);
-void layout_add_center (GtkWidget * add);
-void layout_add (GtkWidget * add, const char * name);
-void layout_remove (GtkWidget * rem);
+GtkWidget * layout_new ();
+void layout_add_center (GtkWidget * widget);
+void layout_add (PluginHandle * plugin, GtkWidget * widget);
+void layout_remove (PluginHandle * plugin);
+void layout_focus (PluginHandle * plugin);
#endif
diff --git a/src/gtkui/menus.c b/src/gtkui/menus.c
deleted file mode 100644
index 75eb36a9118f..000000000000
--- a/src/gtkui/menus.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * menus.c
- * Copyright 2011-2014 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <libaudgui/libaudgui.h>
-#include <libaudgui/menu.h>
-
-#include "gtkui.h"
-#include "playlist_util.h"
-#include "ui_playlist_notebook.h"
-#include "ui_playlist_widget.h"
-
-#define SHIFT GDK_SHIFT_MASK
-#define CTRL GDK_CONTROL_MASK
-#define ALT GDK_MOD1_MASK
-
-int menu_tab_playlist_id = -1; /* should really be stored in the menu somehow */
-
-static void open_files (void) {audgui_run_filebrowser (TRUE); }
-static void open_url (void) {audgui_show_add_url_window (TRUE); }
-static void add_files (void) {audgui_run_filebrowser (FALSE); }
-static void add_url (void) {audgui_show_add_url_window (FALSE); }
-
-static void configure_effects (void) {aud_show_prefs_for_plugin_type (PLUGIN_TYPE_EFFECT); }
-static void configure_visualizations (void) {aud_show_prefs_for_plugin_type (PLUGIN_TYPE_VIS); }
-
-static void pl_sort_track (void) {aud_playlist_sort_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_TRACK); }
-static void pl_sort_title (void) {aud_playlist_sort_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_TITLE); }
-static void pl_sort_artist (void) {aud_playlist_sort_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_ARTIST); }
-static void pl_sort_album (void) {aud_playlist_sort_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_ALBUM); }
-static void pl_sort_date (void) {aud_playlist_sort_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_DATE); }
-static void pl_sort_length (void) {aud_playlist_sort_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_LENGTH); }
-static void pl_sort_path (void) {aud_playlist_sort_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_PATH); }
-static void pl_sort_custom (void) {aud_playlist_sort_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_FORMATTED_TITLE); }
-static void pl_reverse (void) {aud_playlist_reverse (aud_playlist_get_active ()); }
-static void pl_random (void) {aud_playlist_randomize (aud_playlist_get_active ()); }
-
-static void pl_sort_selected_track (void) {aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_TRACK); }
-static void pl_sort_selected_title (void) {aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_TITLE); }
-static void pl_sort_selected_artist (void) {aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_ARTIST); }
-static void pl_sort_selected_album (void) {aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_ALBUM); }
-static void pl_sort_selected_date (void) {aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_DATE); }
-static void pl_sort_selected_length (void) {aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_LENGTH); }
-static void pl_sort_selected_path (void) {aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_PATH); }
-static void pl_sort_selected_custom (void) {aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_FORMATTED_TITLE); }
-static void pl_reverse_selected (void) {aud_playlist_reverse_selected (aud_playlist_get_active ()); }
-static void pl_random_selected (void) {aud_playlist_randomize_selected (aud_playlist_get_active ()); }
-
-static void pl_new (void)
-{
- aud_playlist_insert (-1);
- aud_playlist_set_active (aud_playlist_count () - 1);
-}
-
-static void pl_play (void) {aud_drct_play_playlist (aud_playlist_get_active ()); }
-static void pl_refresh (void) {aud_playlist_rescan (aud_playlist_get_active ()); }
-static void pl_remove_failed (void) {aud_playlist_remove_failed (aud_playlist_get_active ()); }
-static void pl_remove_dupes_by_title (void) {aud_playlist_remove_duplicates_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_TITLE); }
-static void pl_remove_dupes_by_filename (void) {aud_playlist_remove_duplicates_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_FILENAME); }
-static void pl_remove_dupes_by_path (void) {aud_playlist_remove_duplicates_by_scheme (aud_playlist_get_active (), PLAYLIST_SORT_PATH); }
-static void pl_rename (void) {start_rename_playlist (aud_playlist_get_active ()); }
-static void pl_close (void) {audgui_confirm_playlist_delete (aud_playlist_get_active ()); }
-static void pl_refresh_sel (void) {aud_playlist_rescan_selected (aud_playlist_get_active ()); }
-static void pl_select_all (void) {aud_playlist_select_all (aud_playlist_get_active (), TRUE); }
-
-static void pl_tab_play (void)
-{
- int playlist = aud_playlist_by_unique_id (menu_tab_playlist_id);
- if (playlist >= 0)
- aud_drct_play_playlist (playlist);
-}
-
-static void pl_tab_rename (void)
-{
- int playlist = aud_playlist_by_unique_id (menu_tab_playlist_id);
- if (playlist >= 0)
- start_rename_playlist (playlist);
-}
-
-static void pl_tab_close (void)
-{
- int playlist = aud_playlist_by_unique_id (menu_tab_playlist_id);
- if (playlist >= 0)
- audgui_confirm_playlist_delete (playlist);
-}
-
-static GtkWidget * get_services_main (void) {return aud_get_plugin_menu (AUD_MENU_MAIN); }
-static GtkWidget * get_services_pl (void) {return aud_get_plugin_menu (AUD_MENU_PLAYLIST); }
-
-static void volume_up (void)
-{
- int vol = 0;
- aud_drct_get_volume_main (& vol);
- aud_drct_set_volume_main (vol + 5);
-}
-
-static void volume_down (void)
-{
- int vol = 0;
- aud_drct_get_volume_main (& vol);
- aud_drct_set_volume_main (vol - 5);
-}
-
-static const AudguiMenuItem file_items[] = {
- {N_("_Open Files ..."), "document-open", 'o', CTRL, .func = open_files},
- {N_("Open _URL ..."), "folder-remote", 'l', CTRL, .func = open_url},
- {N_("_Add Files ..."), "list-add", 'o', SHIFT | CTRL, .func = add_files},
- {N_("Add U_RL ..."), "folder-remote", 'l', SHIFT | CTRL, .func = add_url},
- {.sep = TRUE},
- {N_("Search _Library"), "edit-find", 'y', CTRL, .func = activate_search_tool},
- {.sep = TRUE},
- {N_("A_bout ..."), "help-about", .func = audgui_show_about_window},
- {N_("_Settings ..."), "preferences-system", .func = aud_show_prefs_window},
- {N_("_Quit"), "application-exit", 'q', CTRL, .func = aud_drct_quit}};
-
-static const AudguiMenuItem playback_items[] = {
- {N_("_Play"), "media-playback-start", GDK_KEY_Return, CTRL, .func = aud_drct_play},
- {N_("Paus_e"), "media-playback-pause", ',', CTRL, .func = aud_drct_pause},
- {N_("_Stop"), "media-playback-stop", '.', CTRL, .func = aud_drct_stop},
- {N_("Pre_vious"), "media-skip-backward", GDK_KEY_Up, ALT, .func = aud_drct_pl_prev},
- {N_("_Next"), "media-skip-forward", GDK_KEY_Down, ALT, .func = aud_drct_pl_next},
- {.sep = TRUE},
- {N_("_Repeat"), NULL, 'r', CTRL, .cname = "repeat", .hook = "set repeat"},
- {N_("S_huffle"), NULL, 's', CTRL, .cname = "shuffle", .hook = "set shuffle"},
- {N_("N_o Playlist Advance"), NULL, 'n', CTRL,
- .cname = "no_playlist_advance", .hook = "set no_playlist_advance"},
- {N_("Stop A_fter This Song"), NULL, 'm', CTRL,
- .cname = "stop_after_current_song", .hook = "set stop_after_current_song"},
- {.sep = TRUE},
- {N_("Song _Info ..."), "dialog-information", 'i', CTRL, .func = audgui_infowin_show_current},
- {N_("Jump to _Time ..."), "go-jump", 'k', CTRL, .func = audgui_jump_to_time},
- {N_("_Jump to Song ..."), "go-jump", 'j', CTRL, .func = audgui_jump_to_track},
- {.sep = TRUE},
- {N_("Set Repeat Point _A"), NULL, '1', CTRL, .func = set_ab_repeat_a},
- {N_("Set Repeat Point _B"), NULL, '2', CTRL, .func = set_ab_repeat_b},
- {N_("_Clear Repeat Points"), NULL, '3', CTRL, .func = clear_ab_repeat}};
-
-static const AudguiMenuItem dupe_items[] = {
- {N_("By _Title"), .func = pl_remove_dupes_by_title},
- {N_("By _Filename"), .func = pl_remove_dupes_by_filename},
- {N_("By File _Path"), .func = pl_remove_dupes_by_path}};
-
-static const AudguiMenuItem sort_items[] = {
- {N_("By Track _Number"), .func = pl_sort_track},
- {N_("By _Title"), .func = pl_sort_title},
- {N_("By _Artist"), .func = pl_sort_artist},
- {N_("By Al_bum"), .func = pl_sort_album},
- {N_("By Release _Date"), .func = pl_sort_date},
- {N_("By _Length"), .func = pl_sort_length},
- {N_("By _File Path"), .func = pl_sort_path},
- {N_("By _Custom Title"), .func = pl_sort_custom},
- {.sep = TRUE},
- {N_("R_everse Order"), "view-sort-descending", .func = pl_reverse},
- {N_("_Random Order"), .func = pl_random}};
-
- static const AudguiMenuItem sort_selected_items[] = {
- {N_("By Track _Number"), .func = pl_sort_selected_track},
- {N_("By _Title"), .func = pl_sort_selected_title},
- {N_("By _Artist"), .func = pl_sort_selected_artist},
- {N_("By Al_bum"), .func = pl_sort_selected_album},
- {N_("By Release _Date"), .func = pl_sort_selected_date},
- {N_("By _Length"), .func = pl_sort_selected_length},
- {N_("By _File Path"), .func = pl_sort_selected_path},
- {N_("By _Custom Title"), .func = pl_sort_selected_custom},
- {.sep = TRUE},
- {N_("R_everse Order"), "view-sort-descending", .func = pl_reverse_selected},
- {N_("_Random Order"), .func = pl_random_selected}};
-
-static const AudguiMenuItem playlist_items[] = {
- {N_("_Play This Playlist"), "media-playback-start", GDK_KEY_Return, SHIFT, .func = pl_play},
- {N_("_Refresh"), "view-refresh", GDK_KEY_F5, .func = pl_refresh},
- {.sep = TRUE},
- {N_("_Sort"), "view-sort-ascending", .items = sort_items, ARRAY_LEN (sort_items)},
- {N_("Sort Se_lected"), "view-sort-ascending", .items = sort_selected_items, ARRAY_LEN (sort_selected_items)},
- {N_("Remove _Duplicates"), "edit-copy", .items = dupe_items, ARRAY_LEN (dupe_items)},
- {N_("Remove _Unavailable Files"), "dialog-warning", .func = pl_remove_failed},
- {.sep = TRUE},
- {N_("_New"), "document-new", 't', CTRL, .func = pl_new},
- {N_("Ren_ame ..."), "insert-text", GDK_KEY_F2, .func = pl_rename},
- {N_("Remo_ve"), "edit-delete", 'w', CTRL, .func = pl_close},
- {.sep = TRUE},
- {N_("_Import ..."), "document-open", .func = audgui_import_playlist},
- {N_("_Export ..."), "document-save", .func = audgui_export_playlist},
- {.sep = TRUE},
- {N_("Playlist _Manager ..."), "audio-x-generic", 'p', CTRL, .func = audgui_playlist_manager},
- {N_("_Queue Manager ..."), NULL, 'u', CTRL, .func = audgui_queue_manager_show}};
-
-static const AudguiMenuItem output_items[] = {
- {N_("Volume _Up"), "audio-volume-high", '+', CTRL, .func = volume_up},
- {N_("Volume _Down"), "audio-volume-low", '-', CTRL, .func = volume_down},
- {.sep = TRUE},
- {N_("_Equalizer"), "multimedia-volume-control", 'e', CTRL, .func = audgui_show_equalizer_window},
- {.sep = TRUE},
- {N_("E_ffects ..."), .func = configure_effects}};
-
-static const AudguiMenuItem view_items[] = {
- {N_("Show _Menu Bar"), NULL, 'm', SHIFT | CTRL,
- .csect = "gtkui", "menu_visible", .func = show_hide_menu},
- {N_("Show I_nfo Bar"), NULL, 'i', SHIFT | CTRL,
- .csect = "gtkui", "infoarea_visible", .func = show_hide_infoarea},
- {N_("Show Info Bar Vis_ualization"),
- .csect = "gtkui", "infoarea_show_vis", .func = show_hide_infoarea_vis},
- {N_("Show _Status Bar"), NULL, 's', SHIFT | CTRL,
- .csect = "gtkui", "statusbar_visible", .func = show_hide_statusbar},
- {.sep = TRUE},
- {N_("Show _Remaining Time"), NULL, 'r', SHIFT | CTRL,
- .csect = "gtkui", "show_remaining_time"},
- {.sep = TRUE},
- {N_("_Visualizations ..."), .func = configure_visualizations}};
-
-static const AudguiMenuItem main_items[] = {
- {N_("_File"), .items = file_items, ARRAY_LEN (file_items)},
- {N_("_Playback"), .items = playback_items, ARRAY_LEN (playback_items)},
- {N_("P_laylist"), .items = playlist_items, ARRAY_LEN (playlist_items)},
- {N_("_Services"), .get_sub = get_services_main},
- {N_("_Output"), .items = output_items, ARRAY_LEN (output_items)},
- {N_("_View"), .items = view_items, ARRAY_LEN (view_items)}};
-
-static const AudguiMenuItem rclick_items[] = {
- {N_("Song _Info ..."), "dialog-information", 'i', ALT, .func = playlist_song_info},
- {N_("_Queue/Unqueue"), NULL, 'q', ALT, .func = playlist_queue_toggle},
- {N_("_Refresh"), "view-refresh", GDK_KEY_F6, .func = pl_refresh_sel},
- {.sep = TRUE},
- {N_("Cu_t"), "edit-cut", .func = playlist_cut},
- {N_("_Copy"), "edit-copy", .func = playlist_copy},
- {N_("_Paste"), "edit-paste", .func = playlist_paste},
- {N_("Select _All"), "edit-select-all", .func = pl_select_all},
- {.sep = TRUE},
- {N_("_Services"), .get_sub = get_services_pl}};
-
-static const AudguiMenuItem tab_items[] = {
- {N_("_Play"), "media-playback-start", .func = pl_tab_play},
- {N_("_Rename ..."), "insert-text", .func = pl_tab_rename},
- {N_("Remo_ve"), "edit-delete", .func = pl_tab_close}};
-
-
-GtkWidget * make_menu_bar (GtkAccelGroup * accel)
-{
- GtkWidget * bar = gtk_menu_bar_new ();
- audgui_menu_init (bar, main_items, ARRAY_LEN (main_items), accel);
- return bar;
-}
-
-GtkWidget * make_menu_main (GtkAccelGroup * accel)
-{
- GtkWidget * shell = gtk_menu_new ();
- audgui_menu_init (shell, main_items, ARRAY_LEN (main_items), accel);
- return shell;
-}
-
-GtkWidget * make_menu_rclick (GtkAccelGroup * accel)
-{
- GtkWidget * shell = gtk_menu_new ();
- audgui_menu_init (shell, rclick_items, ARRAY_LEN (rclick_items), accel);
- return shell;
-}
-
-GtkWidget * make_menu_tab (GtkAccelGroup * accel)
-{
- GtkWidget * shell = gtk_menu_new ();
- audgui_menu_init (shell, tab_items, ARRAY_LEN (tab_items), accel);
- return shell;
-}
diff --git a/src/gtkui/menus.cc b/src/gtkui/menus.cc
new file mode 100644
index 000000000000..553158c16237
--- /dev/null
+++ b/src/gtkui/menus.cc
@@ -0,0 +1,293 @@
+/*
+ * menus.c
+ * Copyright 2011-2014 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/plugins.h>
+#include <libaudcore/runtime.h>
+#include <libaudgui/libaudgui.h>
+#include <libaudgui/libaudgui-gtk.h>
+#include <libaudgui/menu.h>
+
+#include "gtkui.h"
+#include "playlist_util.h"
+#include "ui_playlist_notebook.h"
+#include "ui_playlist_widget.h"
+
+#define SHIFT GDK_SHIFT_MASK
+#define CTRL GDK_CONTROL_MASK
+#define ALT GDK_MOD1_MASK
+
+#define SHIFT_CTRL (GdkModifierType) (SHIFT | CTRL)
+#define NONE 0, (GdkModifierType) 0
+
+int menu_tab_playlist_id = -1; /* should really be stored in the menu somehow */
+
+static void open_files () { audgui_run_filebrowser (true); }
+static void open_url () { audgui_show_add_url_window (true); }
+static void add_files () { audgui_run_filebrowser (false); }
+static void add_url () { audgui_show_add_url_window (false); }
+
+static void configure_effects () { audgui_show_prefs_for_plugin_type (PluginType::Effect); }
+static void configure_visualizations () { audgui_show_prefs_for_plugin_type (PluginType::Vis); }
+
+static void pl_sort_track () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Track); }
+static void pl_sort_title () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Title); }
+static void pl_sort_artist () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Artist); }
+static void pl_sort_album () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Album); }
+static void pl_sort_album_artist () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::AlbumArtist); }
+static void pl_sort_date () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Date); }
+static void pl_sort_genre () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Genre); }
+static void pl_sort_length () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Length); }
+static void pl_sort_path () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Path); }
+static void pl_sort_custom () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::FormattedTitle); }
+static void pl_reverse () { aud_playlist_reverse (aud_playlist_get_active ()); }
+static void pl_random () { aud_playlist_randomize (aud_playlist_get_active ()); }
+
+static void pl_sort_selected_track () { aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), Playlist::Track); }
+static void pl_sort_selected_title () { aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), Playlist::Title); }
+static void pl_sort_selected_artist () { aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), Playlist::Artist); }
+static void pl_sort_selected_album () { aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), Playlist::Album); }
+static void pl_sort_selected_album_artist () { aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), Playlist::AlbumArtist); }
+static void pl_sort_selected_date () { aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), Playlist::Date); }
+static void pl_sort_selected_genre () { aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), Playlist::Genre); }
+static void pl_sort_selected_length () { aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), Playlist::Length); }
+static void pl_sort_selected_path () { aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), Playlist::Path); }
+static void pl_sort_selected_custom () { aud_playlist_sort_selected_by_scheme (aud_playlist_get_active (), Playlist::FormattedTitle); }
+static void pl_reverse_selected () { aud_playlist_reverse_selected (aud_playlist_get_active ()); }
+static void pl_random_selected () { aud_playlist_randomize_selected (aud_playlist_get_active ()); }
+
+static void pl_new ()
+{
+ aud_playlist_insert (-1);
+ aud_playlist_set_active (aud_playlist_count () - 1);
+}
+
+static void pl_play () { aud_playlist_play (aud_playlist_get_active ()); }
+static void pl_refresh () { aud_playlist_rescan (aud_playlist_get_active ()); }
+static void pl_remove_failed () { aud_playlist_remove_failed (aud_playlist_get_active ()); }
+static void pl_remove_dupes_by_title () { aud_playlist_remove_duplicates_by_scheme (aud_playlist_get_active (), Playlist::Title); }
+static void pl_remove_dupes_by_filename () { aud_playlist_remove_duplicates_by_scheme (aud_playlist_get_active (), Playlist::Filename); }
+static void pl_remove_dupes_by_path () { aud_playlist_remove_duplicates_by_scheme (aud_playlist_get_active (), Playlist::Path); }
+static void pl_rename () { start_rename_playlist (aud_playlist_get_active ()); }
+static void pl_close () { audgui_confirm_playlist_delete (aud_playlist_get_active ()); }
+static void pl_refresh_sel () { aud_playlist_rescan_selected (aud_playlist_get_active ()); }
+static void pl_select_all () { aud_playlist_select_all (aud_playlist_get_active (), true); }
+
+static void pl_tab_play ()
+{
+ int playlist = aud_playlist_by_unique_id (menu_tab_playlist_id);
+ if (playlist >= 0)
+ aud_playlist_play (playlist);
+}
+
+static void pl_tab_rename ()
+{
+ int playlist = aud_playlist_by_unique_id (menu_tab_playlist_id);
+ if (playlist >= 0)
+ start_rename_playlist (playlist);
+}
+
+static void pl_tab_close ()
+{
+ int playlist = aud_playlist_by_unique_id (menu_tab_playlist_id);
+ if (playlist >= 0)
+ audgui_confirm_playlist_delete (playlist);
+}
+
+static GtkWidget * get_services_main () { return audgui_get_plugin_menu (AudMenuID::Main); }
+static GtkWidget * get_services_pl () { return audgui_get_plugin_menu (AudMenuID::Playlist); }
+
+static void volume_up () { aud_drct_set_volume_main (aud_drct_get_volume_main () + 5); }
+static void volume_down () { aud_drct_set_volume_main (aud_drct_get_volume_main () - 5); }
+
+static const AudguiMenuItem file_items[] = {
+ MenuCommand (N_("_Open Files ..."), "document-open", 'o', CTRL, open_files),
+ MenuCommand (N_("Open _URL ..."), "folder-remote", 'l', CTRL, open_url),
+ MenuCommand (N_("_Add Files ..."), "list-add", 'o', SHIFT_CTRL, add_files),
+ MenuCommand (N_("Add U_RL ..."), "folder-remote", 'l', SHIFT_CTRL, add_url),
+ MenuSep (),
+ MenuCommand (N_("Search _Library"), "edit-find", 'y', CTRL, activate_search_tool),
+ MenuSep (),
+ MenuCommand (N_("A_bout ..."), "help-about", NONE, audgui_show_about_window),
+ MenuCommand (N_("_Settings ..."), "preferences-system", NONE, audgui_show_prefs_window),
+ MenuCommand (N_("_Quit"), "application-exit", 'q', CTRL, aud_quit)
+};
+
+static const AudguiMenuItem playback_items[] = {
+ MenuCommand (N_("_Play"), "media-playback-start", GDK_KEY_Return, CTRL, aud_drct_play),
+ MenuCommand (N_("Paus_e"), "media-playback-pause", ',', CTRL, aud_drct_pause),
+ MenuCommand (N_("_Stop"), "media-playback-stop", '.', CTRL, aud_drct_stop),
+ MenuCommand (N_("Pre_vious"), "media-skip-backward", GDK_KEY_Up, ALT, aud_drct_pl_prev),
+ MenuCommand (N_("_Next"), "media-skip-forward", GDK_KEY_Down, ALT, aud_drct_pl_next),
+ MenuSep (),
+ MenuToggle (N_("_Repeat"), nullptr, 'r', CTRL, nullptr, "repeat", nullptr, "set repeat"),
+ MenuToggle (N_("S_huffle"), nullptr, 's', CTRL, nullptr, "shuffle", nullptr, "set shuffle"),
+ MenuToggle (N_("N_o Playlist Advance"), nullptr, 'n', CTRL, nullptr, "no_playlist_advance", nullptr, "set no_playlist_advance"),
+ MenuToggle (N_("Stop A_fter This Song"), nullptr, 'm', CTRL, nullptr, "stop_after_current_song", nullptr, "set stop_after_current_song"),
+ MenuSep (),
+ MenuCommand (N_("Song _Info ..."), "dialog-information", 'i', CTRL, audgui_infowin_show_current),
+ MenuCommand (N_("Jump to _Time ..."), "go-jump", 'k', CTRL, audgui_jump_to_time),
+ MenuCommand (N_("_Jump to Song ..."), "go-jump", 'j', CTRL, audgui_jump_to_track),
+ MenuSep (),
+ MenuCommand (N_("Set Repeat Point _A"), nullptr, '1', CTRL, set_ab_repeat_a),
+ MenuCommand (N_("Set Repeat Point _B"), nullptr, '2', CTRL, set_ab_repeat_b),
+ MenuCommand (N_("_Clear Repeat Points"), nullptr, '3', CTRL, clear_ab_repeat)
+};
+
+static const AudguiMenuItem dupe_items[] = {
+ MenuCommand (N_("By _Title"), nullptr, NONE, pl_remove_dupes_by_title),
+ MenuCommand (N_("By _File Name"), nullptr, NONE, pl_remove_dupes_by_filename),
+ MenuCommand (N_("By File _Path"), nullptr, NONE, pl_remove_dupes_by_path)
+};
+
+static const AudguiMenuItem sort_items[] = {
+ MenuCommand (N_("By Track _Number"), nullptr, NONE, pl_sort_track),
+ MenuCommand (N_("By _Title"), nullptr, NONE, pl_sort_title),
+ MenuCommand (N_("By _Artist"), nullptr, NONE, pl_sort_artist),
+ MenuCommand (N_("By Al_bum"), nullptr, NONE, pl_sort_album),
+ MenuCommand (N_("By Albu_m Artist"), nullptr, NONE, pl_sort_album_artist),
+ MenuCommand (N_("By Release _Date"), nullptr, NONE, pl_sort_date),
+ MenuCommand (N_("By _Genre"), nullptr, NONE, pl_sort_genre),
+ MenuCommand (N_("By _Length"), nullptr, NONE, pl_sort_length),
+ MenuCommand (N_("By _File Path"), nullptr, NONE, pl_sort_path),
+ MenuCommand (N_("By _Custom Title"), nullptr, NONE, pl_sort_custom),
+ MenuSep (),
+ MenuCommand (N_("R_everse Order"), "view-sort-descending", NONE, pl_reverse),
+ MenuCommand (N_("_Random Order"), nullptr, NONE, pl_random)
+};
+
+static const AudguiMenuItem sort_selected_items[] = {
+ MenuCommand (N_("By Track _Number"), nullptr, NONE, pl_sort_selected_track),
+ MenuCommand (N_("By _Title"), nullptr, NONE, pl_sort_selected_title),
+ MenuCommand (N_("By _Artist"), nullptr, NONE, pl_sort_selected_artist),
+ MenuCommand (N_("By Al_bum"), nullptr, NONE, pl_sort_selected_album),
+ MenuCommand (N_("By Albu_m Artist"), nullptr, NONE, pl_sort_selected_album_artist),
+ MenuCommand (N_("By Release _Date"), nullptr, NONE, pl_sort_selected_date),
+ MenuCommand (N_("By _Genre"), nullptr, NONE, pl_sort_selected_genre),
+ MenuCommand (N_("By _Length"), nullptr, NONE, pl_sort_selected_length),
+ MenuCommand (N_("By _File Path"), nullptr, NONE, pl_sort_selected_path),
+ MenuCommand (N_("By _Custom Title"), nullptr, NONE, pl_sort_selected_custom),
+ MenuSep (),
+ MenuCommand (N_("R_everse Order"), "view-sort-descending", NONE, pl_reverse_selected),
+ MenuCommand (N_("_Random Order"), nullptr, NONE, pl_random_selected)
+};
+
+static const AudguiMenuItem playlist_items[] = {
+ MenuCommand (N_("_Play/Resume"), "media-playback-start", GDK_KEY_Return, SHIFT, pl_play),
+ MenuCommand (N_("_Refresh"), "view-refresh", GDK_KEY_F5, (GdkModifierType) 0, pl_refresh),
+ MenuSep (),
+ MenuSub (N_("_Sort"), "view-sort-ascending", {sort_items}),
+ MenuSub (N_("Sort Se_lected"), "view-sort-ascending", {sort_selected_items}),
+ MenuSub (N_("Remove _Duplicates"), "edit-copy", {dupe_items}),
+ MenuCommand (N_("Remove _Unavailable Files"), "dialog-warning", NONE, pl_remove_failed),
+ MenuSep (),
+ MenuCommand (N_("_New"), "document-new", 't', CTRL, pl_new),
+ MenuCommand (N_("Ren_ame ..."), "insert-text", GDK_KEY_F2, (GdkModifierType) 0, pl_rename),
+ MenuCommand (N_("Remo_ve"), "edit-delete", 'w', CTRL, pl_close),
+ MenuSep (),
+ MenuCommand (N_("_Import ..."), "document-open", NONE, audgui_import_playlist),
+ MenuCommand (N_("_Export ..."), "document-save", NONE, audgui_export_playlist),
+ MenuSep (),
+ MenuCommand (N_("Playlist _Manager ..."), "audio-x-generic", 'p', CTRL, activate_playlist_manager),
+ MenuCommand (N_("_Queue Manager ..."), nullptr, 'u', CTRL, audgui_queue_manager_show)
+};
+
+static const AudguiMenuItem output_items[] = {
+ MenuCommand (N_("Volume _Up"), "audio-volume-high", '+', CTRL, volume_up),
+ MenuCommand (N_("Volume _Down"), "audio-volume-low", '-', CTRL, volume_down),
+ MenuSep (),
+ MenuCommand (N_("_Equalizer"), "multimedia-volume-control", 'e', CTRL, audgui_show_equalizer_window),
+ MenuSep (),
+ MenuCommand (N_("E_ffects ..."), nullptr, NONE, configure_effects)
+};
+
+static const AudguiMenuItem view_items[] = {
+ MenuToggle (N_("Show _Menu Bar"), nullptr, 'm', SHIFT_CTRL, "gtkui", "menu_visible", show_hide_menu),
+ MenuToggle (N_("Show I_nfo Bar"), nullptr, 'i', SHIFT_CTRL, "gtkui", "infoarea_visible", show_hide_infoarea),
+ MenuToggle (N_("Show Info Bar Vis_ualization"), nullptr, NONE, "gtkui", "infoarea_show_vis", show_hide_infoarea_vis),
+ MenuToggle (N_("Show _Status Bar"), nullptr, 's', SHIFT_CTRL, "gtkui", "statusbar_visible", show_hide_statusbar),
+ MenuSep (),
+ MenuToggle (N_("Show _Remaining Time"), nullptr, 'r', SHIFT_CTRL, "gtkui", "show_remaining_time"),
+ MenuSep (),
+ MenuCommand (N_("_Visualizations ..."), nullptr, NONE, configure_visualizations)
+};
+
+static const AudguiMenuItem main_items[] = {
+ MenuSub (N_("_File"), nullptr, {file_items}),
+ MenuSub (N_("_Playback"), nullptr, {playback_items}),
+ MenuSub (N_("P_laylist"), nullptr, {playlist_items}),
+ MenuSub (N_("_Services"), nullptr, get_services_main),
+ MenuSub (N_("_Output"), nullptr, {output_items}),
+ MenuSub (N_("_View"), nullptr, {view_items})
+};
+
+static const AudguiMenuItem rclick_items[] = {
+ MenuCommand (N_("Song _Info ..."), "dialog-information", 'i', ALT, playlist_song_info),
+ MenuCommand (N_("_Queue/Unqueue"), nullptr, 'q', ALT, playlist_queue_toggle),
+ MenuSep (),
+ MenuCommand (N_("_Open Containing Folder"), "folder", NONE, playlist_open_folder),
+ MenuCommand (N_("_Refresh"), "view-refresh", GDK_KEY_F6, (GdkModifierType) 0, pl_refresh_sel),
+ MenuSep (),
+ MenuCommand (N_("Cu_t"), "edit-cut", NONE, playlist_cut),
+ MenuCommand (N_("_Copy"), "edit-copy", NONE, playlist_copy),
+ MenuCommand (N_("_Paste"), "edit-paste", NONE, playlist_paste),
+ MenuCommand (N_("Select _All"), "edit-select-all", NONE, pl_select_all),
+ MenuSep (),
+ MenuSub (N_("_Services"), nullptr, get_services_pl)
+};
+
+static const AudguiMenuItem tab_items[] = {
+ MenuCommand (N_("_Play"), "media-playback-start", NONE, pl_tab_play),
+ MenuCommand (N_("_Rename ..."), "insert-text", NONE, pl_tab_rename),
+ MenuCommand (N_("Remo_ve"), "edit-delete", NONE, pl_tab_close)
+};
+
+GtkWidget * make_menu_bar (GtkAccelGroup * accel)
+{
+ GtkWidget * bar = gtk_menu_bar_new ();
+ audgui_menu_init (bar, {main_items}, accel);
+ return bar;
+}
+
+GtkWidget * make_menu_main (GtkAccelGroup * accel)
+{
+ GtkWidget * shell = gtk_menu_new ();
+ audgui_menu_init (shell, {main_items}, accel);
+ return shell;
+}
+
+GtkWidget * make_menu_rclick (GtkAccelGroup * accel)
+{
+ GtkWidget * shell = gtk_menu_new ();
+ audgui_menu_init (shell, {rclick_items}, accel);
+ return shell;
+}
+
+GtkWidget * make_menu_tab (GtkAccelGroup * accel)
+{
+ GtkWidget * shell = gtk_menu_new ();
+ audgui_menu_init (shell, {tab_items}, accel);
+ return shell;
+}
diff --git a/src/gtkui/playlist_util.c b/src/gtkui/playlist_util.c
deleted file mode 100644
index c63a9252fa07..000000000000
--- a/src/gtkui/playlist_util.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * playlist_util.c
- * Copyright 2010-2011 MichaÅ Lipski and John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <gtk/gtk.h>
-
-#include <audacious/drct.h>
-#include <audacious/playlist.h>
-#include <libaudgui/libaudgui.h>
-#include <libaudgui/list.h>
-
-#include "playlist_util.h"
-#include "ui_playlist_notebook.h"
-
-GtkWidget * playlist_get_treeview (int playlist)
-{
- GtkWidget *page = gtk_notebook_get_nth_page(UI_PLAYLIST_NOTEBOOK, playlist);
-
- if (!page)
- return NULL;
-
- return g_object_get_data ((GObject *) page, "treeview");
-}
-
-int playlist_count_selected_in_range (int list, int top, int length)
-{
- int selected = 0;
- int count;
-
- for (count = 0; count < length; count ++)
- {
- if (aud_playlist_entry_get_selected (list, top + count))
- selected ++;
- }
-
- return selected;
-}
-
-void playlist_song_info (void)
-{
- int list = aud_playlist_get_active ();
- int focus = aud_playlist_get_focus (list);
-
- if (focus < 0)
- return;
-
- audgui_infowin_show (list, focus);
-}
-
-void playlist_queue_toggle (void)
-{
- int list = aud_playlist_get_active ();
- int focus = aud_playlist_get_focus (list);
-
- if (focus < 0)
- return;
-
- int at = aud_playlist_queue_find_entry (list, focus);
-
- if (at < 0)
- aud_playlist_queue_insert (list, -1, focus);
- else
- aud_playlist_queue_delete (list, at, 1);
-}
-
-void playlist_delete_selected (void)
-{
- int list = aud_playlist_get_active ();
- aud_playlist_delete_selected (list);
- aud_playlist_entry_set_selected (list, aud_playlist_get_focus (list), TRUE);
-}
-
-void playlist_copy (void)
-{
- char * text = audgui_urilist_create_from_selected (aud_playlist_get_active ());
- if (! text)
- return;
-
- gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), text, -1);
- g_free (text);
-}
-
-void playlist_cut (void)
-{
- playlist_copy ();
- playlist_delete_selected ();
-}
-
-void playlist_paste (void)
-{
- char * text = gtk_clipboard_wait_for_text (gtk_clipboard_get
- (GDK_SELECTION_CLIPBOARD));
- if (! text)
- return;
-
- int list = aud_playlist_get_active ();
- audgui_urilist_insert (list, aud_playlist_get_focus (list), text);
- g_free (text);
-}
-
-void playlist_shift (int offset)
-{
- int list = aud_playlist_get_active ();
- int focus = aud_playlist_get_focus (list);
-
- if (focus < 0 || ! aud_playlist_entry_get_selected (list, focus))
- return;
-
- aud_playlist_shift (list, focus, offset);
-}
diff --git a/src/gtkui/playlist_util.cc b/src/gtkui/playlist_util.cc
new file mode 100644
index 000000000000..6ecf2161c7d4
--- /dev/null
+++ b/src/gtkui/playlist_util.cc
@@ -0,0 +1,150 @@
+/*
+ * playlist_util.c
+ * Copyright 2010-2011 MichaÅ Lipski and John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/playlist.h>
+#include <libaudgui/libaudgui.h>
+#include <libaudgui/list.h>
+
+#include "playlist_util.h"
+#include "ui_playlist_notebook.h"
+
+GtkWidget * playlist_get_treeview (int playlist)
+{
+ GtkWidget * page = gtk_notebook_get_nth_page (UI_PLAYLIST_NOTEBOOK, playlist);
+
+ if (!page)
+ return nullptr;
+
+ return (GtkWidget *) g_object_get_data ((GObject *) page, "treeview");
+}
+
+int playlist_count_selected_in_range (int list, int top, int length)
+{
+ int selected = 0;
+
+ for (int count = 0; count < length; count ++)
+ {
+ if (aud_playlist_entry_get_selected (list, top + count))
+ selected ++;
+ }
+
+ return selected;
+}
+
+void playlist_song_info ()
+{
+ int list = aud_playlist_get_active ();
+ int focus = aud_playlist_get_focus (list);
+
+ if (focus < 0)
+ return;
+
+ audgui_infowin_show (list, focus);
+}
+
+void playlist_open_folder ()
+{
+ int list = aud_playlist_get_active ();
+ int focus = aud_playlist_get_focus (list);
+
+ if (focus < 0)
+ return;
+
+ StringBuf filename = uri_to_filename (aud_playlist_entry_get_filename (list, focus));
+ if (! filename)
+ return;
+
+ char * dirname = g_path_get_dirname (filename);
+ StringBuf uri = filename_to_uri (dirname);
+ g_free (dirname);
+
+ GdkScreen * screen = gdk_screen_get_default ();
+ gtk_show_uri (screen, uri, GDK_CURRENT_TIME, nullptr);
+}
+
+void playlist_queue_toggle ()
+{
+ int list = aud_playlist_get_active ();
+ int focus = aud_playlist_get_focus (list);
+
+ if (focus < 0)
+ return;
+
+ /* make sure focused row is selected */
+ if (! aud_playlist_entry_get_selected (list, focus))
+ {
+ aud_playlist_select_all (list, false);
+ aud_playlist_entry_set_selected (list, focus, true);
+ }
+
+ int at = aud_playlist_queue_find_entry (list, focus);
+
+ if (at < 0)
+ aud_playlist_queue_insert_selected (list, -1);
+ else
+ aud_playlist_queue_delete_selected (list);
+}
+
+void playlist_delete_selected ()
+{
+ int list = aud_playlist_get_active ();
+ aud_playlist_delete_selected (list);
+ aud_playlist_entry_set_selected (list, aud_playlist_get_focus (list), true);
+}
+
+void playlist_copy ()
+{
+ Index<char> text = audgui_urilist_create_from_selected (aud_playlist_get_active ());
+ if (! text.len ())
+ return;
+
+ gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), text.begin (), text.len ());
+}
+
+void playlist_cut ()
+{
+ playlist_copy ();
+ playlist_delete_selected ();
+}
+
+void playlist_paste ()
+{
+ char * text = gtk_clipboard_wait_for_text (gtk_clipboard_get
+ (GDK_SELECTION_CLIPBOARD));
+ if (! text)
+ return;
+
+ int list = aud_playlist_get_active ();
+ audgui_urilist_insert (list, aud_playlist_get_focus (list), text);
+ g_free (text);
+}
+
+void playlist_shift (int offset)
+{
+ int list = aud_playlist_get_active ();
+ int focus = aud_playlist_get_focus (list);
+
+ if (focus < 0 || ! aud_playlist_entry_get_selected (list, focus))
+ return;
+
+ aud_playlist_shift (list, focus, offset);
+}
diff --git a/src/gtkui/playlist_util.h b/src/gtkui/playlist_util.h
index 3786152f6e75..b13b1f59fec5 100644
--- a/src/gtkui/playlist_util.h
+++ b/src/gtkui/playlist_util.h
@@ -23,12 +23,13 @@
GtkWidget * playlist_get_treeview (int playlist);
int playlist_count_selected_in_range (int list, int top, int length);
-void playlist_song_info (void);
-void playlist_queue_toggle (void);
-void playlist_delete_selected (void);
-void playlist_copy (void);
-void playlist_cut (void);
-void playlist_paste (void);
+void playlist_song_info ();
+void playlist_open_folder ();
+void playlist_queue_toggle ();
+void playlist_delete_selected ();
+void playlist_copy ();
+void playlist_cut ();
+void playlist_paste ();
void playlist_shift (int offset);
#endif
diff --git a/src/gtkui/settings.c b/src/gtkui/settings.c
deleted file mode 100644
index eb47f6d41aee..000000000000
--- a/src/gtkui/settings.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * settings.c
- * Copyright 2013 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include "gtkui.h"
-
-#include <audacious/i18n.h>
-#include <audacious/preferences.h>
-
-#include "ui_playlist_notebook.h"
-#include "ui_playlist_widget.h"
-
-static void redisplay_playlists (void)
-{
- ui_playlist_notebook_empty ();
- ui_playlist_notebook_populate ();
-}
-
-static PreferencesWidget gtkui_widgets[] = {
- {WIDGET_LABEL, N_("<b>Playlist Tabs</b>")},
- {WIDGET_CHK_BTN, N_("Always show tabs"),
- .cfg_type = VALUE_BOOLEAN, .csect = "gtkui", .cname = "playlist_tabs_visible",
- .callback = show_hide_playlist_tabs},
- {WIDGET_CHK_BTN, N_("Show entry counts"),
- .cfg_type = VALUE_BOOLEAN, .csect = "gtkui", .cname = "entry_count_visible",
- .callback = redisplay_playlists},
- {WIDGET_CHK_BTN, N_("Show close buttons"),
- .cfg_type = VALUE_BOOLEAN, .csect = "gtkui", .cname = "close_button_visible",
- .callback = redisplay_playlists},
- {WIDGET_LABEL, N_("<b>Playlist Columns</b>")},
- {WIDGET_CUSTOM, .data.populate = pw_col_create_chooser},
- {WIDGET_CHK_BTN, N_("Show column headers"),
- .cfg_type = VALUE_BOOLEAN, .csect = "gtkui", .cname = "playlist_headers",
- .callback = redisplay_playlists},
- {WIDGET_LABEL, N_("<b>Miscellaneous</b>")},
- {WIDGET_SPIN_BTN, N_("Arrow keys seek by:"),
- .cfg_type = VALUE_FLOAT, .csect = "gtkui", .cname = "step_size",
- .callback= update_step_size, .data.spin_btn = {0.1, 60, 0.1, N_("seconds")}},
- {WIDGET_CHK_BTN, N_("Scroll on song change"),
- .cfg_type = VALUE_BOOLEAN, .csect = "gtkui", .cname = "autoscroll"}
-};
-
-const PluginPreferences gtkui_prefs = {
- .widgets = gtkui_widgets,
- .n_widgets = ARRAY_LEN (gtkui_widgets)
-};
-
diff --git a/src/gtkui/settings.cc b/src/gtkui/settings.cc
new file mode 100644
index 000000000000..e459eccc8085
--- /dev/null
+++ b/src/gtkui/settings.cc
@@ -0,0 +1,54 @@
+/*
+ * settings.c
+ * Copyright 2013 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include "gtkui.h"
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/preferences.h>
+
+#include "ui_playlist_notebook.h"
+#include "ui_playlist_widget.h"
+
+static void redisplay_playlists ()
+{
+ ui_playlist_notebook_empty ();
+ ui_playlist_notebook_populate ();
+}
+
+static const PreferencesWidget gtkui_widgets[] = {
+ WidgetLabel (N_("<b>Playlist Tabs</b>")),
+ WidgetCheck (N_("Always show tabs"),
+ WidgetBool ("gtkui", "playlist_tabs_visible", show_hide_playlist_tabs)),
+ WidgetCheck (N_("Show entry counts"),
+ WidgetBool ("gtkui", "entry_count_visible", redisplay_playlists)),
+ WidgetCheck (N_("Show close buttons"),
+ WidgetBool ("gtkui", "close_button_visible", redisplay_playlists)),
+ WidgetLabel (N_("<b>Playlist Columns</b>")),
+ WidgetCustomGTK (pw_col_create_chooser),
+ WidgetCheck (N_("Show column headers"),
+ WidgetBool ("gtkui", "playlist_headers", redisplay_playlists)),
+ WidgetLabel (N_("<b>Miscellaneous</b>")),
+ WidgetSpin (N_("Arrow keys seek by:"),
+ WidgetFloat ("gtkui", "step_size", update_step_size),
+ {0.1, 60, 0.1, N_("seconds")}),
+ WidgetCheck (N_("Scroll on song change"),
+ WidgetBool ("gtkui", "autoscroll"))
+};
+
+const PluginPreferences gtkui_prefs = {{gtkui_widgets}};
diff --git a/src/gtkui/ui_gtk.c b/src/gtkui/ui_gtk.c
deleted file mode 100644
index ac2f39662070..000000000000
--- a/src/gtkui/ui_gtk.c
+++ /dev/null
@@ -1,1022 +0,0 @@
-/*
- * ui_gtk.c
- * Copyright 2009-2012 William Pitcock, Tomasz MoÅ, MichaÅ Lipski, and John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <string.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-#include <audacious/debug.h>
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/playlist.h>
-#include <audacious/plugin.h>
-#include <audacious/plugins.h>
-#include <audacious/misc.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui.h>
-
-#include "gtkui.h"
-#include "layout.h"
-#include "ui_playlist_notebook.h"
-#include "ui_playlist_widget.h"
-#include "ui_infoarea.h"
-#include "ui_statusbar.h"
-#include "playlist_util.h"
-
-static const char * const gtkui_defaults[] = {
- "infoarea_show_vis", "TRUE",
- "infoarea_visible", "TRUE",
- "menu_visible", "TRUE",
- "playlist_tabs_visible", "TRUE",
- "statusbar_visible", "TRUE",
- "entry_count_visible", "FALSE",
- "close_button_visible", "TRUE",
-
- "autoscroll", "TRUE",
- "playlist_columns", "title artist album queued length",
- "playlist_headers", "TRUE",
- "show_remaining_time", "FALSE",
- "step_size", "5",
-
- "player_x", "-1000",
- "player_y", "-1000",
- "player_width", "760",
- "player_height", "460",
-
- NULL
-};
-
-static PluginHandle * search_tool;
-
-static GtkWidget *volume;
-static bool_t volume_slider_is_moving = FALSE;
-static unsigned update_volume_timeout_source = 0;
-static gulong volume_change_handler_id;
-
-static GtkAccelGroup * accel;
-
-static GtkWidget * window, * vbox_outer, * menu_box, * menu, * toolbar, * vbox,
- * infoarea, * statusbar;
-static GtkToolItem * menu_button, * search_button, * button_play, * button_stop,
- * button_shuffle, * button_repeat;
-static GtkWidget * slider, * label_time;
-static GtkWidget * menu_main, * menu_rclick, * menu_tab;
-
-static bool_t slider_is_moving = FALSE;
-static int slider_seek_time = -1;
-static unsigned delayed_title_change_source = 0;
-static unsigned update_song_timeout_source = 0;
-
-static bool_t init (void);
-static void cleanup (void);
-static void ui_show (bool_t show);
-
-AUD_IFACE_PLUGIN
-(
- .name = N_("GTK Interface"),
- .domain = PACKAGE,
- .prefs = & gtkui_prefs,
- .init = init,
- .cleanup = cleanup,
- .show = ui_show,
- .run_gtk_plugin = (void (*) (void *, const char *)) layout_add,
- .stop_gtk_plugin = (void (*) (void *)) layout_remove,
-)
-
-static void save_window_size (void)
-{
- int x, y, w, h;
- gtk_window_get_position ((GtkWindow *) window, & x, & y);
- gtk_window_get_size ((GtkWindow *) window, & w, & h);
-
- aud_set_int ("gtkui", "player_x", x);
- aud_set_int ("gtkui", "player_y", y);
- aud_set_int ("gtkui", "player_width", w);
- aud_set_int ("gtkui", "player_height", h);
-}
-
-static void restore_window_size (void)
-{
- int x = aud_get_int ("gtkui", "player_x");
- int y = aud_get_int ("gtkui", "player_y");
- int w = aud_get_int ("gtkui", "player_width");
- int h = aud_get_int ("gtkui", "player_height");
-
- gtk_window_set_default_size ((GtkWindow *) window, w, h);
-
- if (x > -1000 && y > -1000)
- gtk_window_move ((GtkWindow *) window, x, y);
-}
-
-static bool_t window_delete()
-{
- bool_t handle = FALSE;
-
- hook_call("window close", &handle);
-
- if (handle)
- return TRUE;
-
- aud_drct_quit ();
- return TRUE;
-}
-
-static void button_open_pressed (void)
-{
- audgui_run_filebrowser (TRUE);
-}
-
-static void button_add_pressed (void)
-{
- audgui_run_filebrowser (FALSE);
-}
-
-void set_ab_repeat_a (void)
-{
- if (! aud_drct_get_playing ())
- return;
-
- int a, b;
- aud_drct_get_ab_repeat (& a, & b);
- a = aud_drct_get_time ();
- aud_drct_set_ab_repeat (a, b);
-}
-
-void set_ab_repeat_b (void)
-{
- if (! aud_drct_get_playing ())
- return;
-
- int a, b;
- aud_drct_get_ab_repeat (& a, & b);
- b = aud_drct_get_time ();
- aud_drct_set_ab_repeat (a, b);
-}
-
-void clear_ab_repeat (void)
-{
- aud_drct_set_ab_repeat (-1, -1);
-}
-
-static bool_t title_change_cb (void)
-{
- if (delayed_title_change_source)
- {
- g_source_remove (delayed_title_change_source);
- delayed_title_change_source = 0;
- }
-
- if (aud_drct_get_playing ())
- {
- if (aud_drct_get_ready ())
- {
- char * title = aud_drct_get_title ();
- SPRINTF (title_s, _("%s - Audacious"), title);
- gtk_window_set_title ((GtkWindow *) window, title_s);
- str_unref (title);
- }
- else
- gtk_window_set_title ((GtkWindow *) window, _("Buffering ..."));
- }
- else
- gtk_window_set_title ((GtkWindow *) window, _("Audacious"));
-
- return FALSE;
-}
-
-static void ui_show (bool_t show)
-{
- if (show)
- {
- if (! gtk_widget_get_visible (window))
- restore_window_size ();
-
- gtk_window_present ((GtkWindow *) window);
- }
- else
- {
- if (gtk_widget_get_visible (window))
- save_window_size ();
-
- gtk_widget_hide (window);
- }
-
- show_hide_infoarea_vis ();
-}
-
-static void append_str (char * buf, int bufsize, const char * str)
-{
- snprintf (buf + strlen (buf), bufsize - strlen (buf), "%s", str);
-}
-
-static void append_time_str (char * buf, int bufsize, int time)
-{
- audgui_format_time (buf + strlen (buf), bufsize - strlen (buf), time);
-}
-
-static void set_time_label (int time, int len)
-{
- char s[128] = "<b>";
-
- if (len && aud_get_bool ("gtkui", "show_remaining_time"))
- append_time_str (s, sizeof s, len - time);
- else
- append_time_str (s, sizeof s, time);
-
- if (len)
- {
- append_str (s, sizeof s, " / ");
- append_time_str (s, sizeof s, len);
-
- int a, b;
- aud_drct_get_ab_repeat (& a, & b);
-
- if (a >= 0)
- {
- append_str (s, sizeof s, " A=");
- append_time_str (s, sizeof s, a);
- }
-
- if (b >= 0)
- {
- append_str (s, sizeof s, " B=");
- append_time_str (s, sizeof s, b);
- }
- }
-
- append_str (s, sizeof s, "</b>");
-
- /* only update label if necessary */
- if (strcmp (gtk_label_get_label ((GtkLabel *) label_time), s))
- gtk_label_set_markup ((GtkLabel *) label_time, s);
-}
-
-static void set_slider (int time)
-{
- gtk_range_set_value ((GtkRange *) slider, time);
-}
-
-static bool_t time_counter_cb (void)
-{
- if (slider_is_moving)
- return TRUE;
-
- slider_seek_time = -1; // delayed reset to avoid seeking twice
-
- int time = aud_drct_get_time ();
- int length = aud_drct_get_length ();
-
- if (length > 0)
- set_slider (time);
-
- set_time_label (time, length);
-
- return TRUE;
-}
-
-static void do_seek (int time)
-{
- int length = aud_drct_get_length ();
- time = CLAMP (time, 0, length);
-
- set_slider (time);
- set_time_label (time, length);
- aud_drct_seek (time);
-
- // Trick: Unschedule and then schedule the update function. This gives the
- // player 1/4 second to perform the seek before we update the display again,
- // in an attempt to reduce flickering.
- if (update_song_timeout_source)
- {
- g_source_remove (update_song_timeout_source);
- update_song_timeout_source = g_timeout_add (250, (GSourceFunc) time_counter_cb, NULL);
- }
-}
-
-static bool_t ui_slider_change_value_cb (GtkRange * range,
- GtkScrollType scroll, double value)
-{
- int length = aud_drct_get_length ();
- int time = CLAMP ((int) value, 0, length);
-
- set_time_label (time, length);
-
- if (slider_is_moving)
- slider_seek_time = time;
- else if (time != slider_seek_time) // avoid seeking twice
- do_seek (time);
-
- return FALSE;
-}
-
-static bool_t ui_slider_button_press_cb(GtkWidget * widget, GdkEventButton * event, void * user_data)
-{
- slider_is_moving = TRUE;
- return FALSE;
-}
-
-static bool_t ui_slider_button_release_cb(GtkWidget * widget, GdkEventButton * event, void * user_data)
-{
- if (slider_seek_time != -1)
- do_seek (slider_seek_time);
-
- slider_is_moving = FALSE;
- return FALSE;
-}
-
-static bool_t ui_volume_value_changed_cb(GtkButton * button, double volume, void * user_data)
-{
- aud_drct_set_volume((int) volume, (int) volume);
-
- return TRUE;
-}
-
-static void ui_volume_pressed_cb(GtkButton *button, void * user_data)
-{
- volume_slider_is_moving = TRUE;
-}
-
-static void ui_volume_released_cb(GtkButton *button, void * user_data)
-{
- volume_slider_is_moving = FALSE;
-}
-
-static bool_t ui_volume_slider_update(void * data)
-{
- int volume;
-
- if (volume_slider_is_moving || data == NULL)
- return TRUE;
-
- aud_drct_get_volume_main(&volume);
-
- if (volume == (int) gtk_scale_button_get_value(GTK_SCALE_BUTTON(data)))
- return TRUE;
-
- g_signal_handler_block(data, volume_change_handler_id);
- gtk_scale_button_set_value(GTK_SCALE_BUTTON(data), volume);
- g_signal_handler_unblock(data, volume_change_handler_id);
-
- return TRUE;
-}
-
-static void set_slider_length (int length)
-{
- if (length > 0)
- {
- gtk_range_set_range ((GtkRange *) slider, 0, length);
- gtk_widget_show (slider);
- }
- else
- gtk_widget_hide (slider);
-}
-
-void update_step_size (void)
-{
- double step_size = aud_get_double ("gtkui", "step_size");
- gtk_range_set_increments ((GtkRange *) slider, step_size * 1000, step_size * 1000);
-}
-
-static void pause_cb (void)
-{
- gtk_tool_button_set_icon_name ((GtkToolButton *) button_play,
- aud_drct_get_paused () ? "media-playback-start" : "media-playback-pause");
-}
-
-static void ui_playback_begin (void)
-{
- pause_cb ();
- gtk_widget_set_sensitive ((GtkWidget *) button_stop, TRUE);
-
- if (delayed_title_change_source)
- g_source_remove (delayed_title_change_source);
-
- /* If "title change" is not called by 1/4 second after starting playback,
- * show "Buffering ..." as the window title. */
- delayed_title_change_source = g_timeout_add (250, (GSourceFunc)
- title_change_cb, NULL);
-}
-
-static void ui_playback_ready (void)
-{
- title_change_cb ();
- set_slider_length (aud_drct_get_length ());
- time_counter_cb ();
-
- /* update time counter 4 times a second */
- if (! update_song_timeout_source)
- update_song_timeout_source = g_timeout_add (250, (GSourceFunc)
- time_counter_cb, NULL);
-
- gtk_widget_show (label_time);
-}
-
-static void ui_playback_stop (void)
-{
- if (update_song_timeout_source)
- {
- g_source_remove(update_song_timeout_source);
- update_song_timeout_source = 0;
- }
-
- if (delayed_title_change_source)
- g_source_remove (delayed_title_change_source);
-
- /* Don't update the window title immediately; we may be about to start
- * another song. */
- delayed_title_change_source = g_idle_add ((GSourceFunc) title_change_cb,
- NULL);
-
- gtk_tool_button_set_icon_name ((GtkToolButton *) button_play, "media-playback-start");
- gtk_widget_set_sensitive ((GtkWidget *) button_stop, FALSE);
- gtk_widget_hide (slider);
- gtk_widget_hide (label_time);
-}
-
-static GtkToolItem * toolbar_button_add (GtkWidget * toolbar,
- void (* callback) (void), const char * icon)
-{
- GtkToolItem * item = gtk_tool_button_new (NULL, NULL);
- gtk_tool_button_set_icon_name ((GtkToolButton *) item, icon);
- gtk_toolbar_insert ((GtkToolbar *) toolbar, item, -1);
- g_signal_connect (item, "clicked", callback, NULL);
- return item;
-}
-
-static GtkToolItem * toggle_button_new (const char * icon,
- void (* toggled) (GtkToggleToolButton * button))
-{
- GtkToolItem * item = gtk_toggle_tool_button_new ();
- gtk_tool_button_set_icon_name ((GtkToolButton *) item, icon);
- g_signal_connect (item, "toggled", (GCallback) toggled, NULL);
- return item;
-}
-
-static GtkWidget *markup_label_new(const char * str)
-{
- GtkWidget *label = gtk_label_new(str);
- g_object_set(G_OBJECT(label), "use-markup", TRUE, NULL);
- return label;
-}
-
-static void window_mapped_cb (GtkWidget * widget, void * unused)
-{
- gtk_widget_grab_focus (playlist_get_treeview (aud_playlist_get_active ()));
-}
-
-static bool_t window_keypress_cb (GtkWidget * widget, GdkEventKey * event, void * unused)
-{
- switch (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK))
- {
- case 0:;
- GtkWidget * focused = gtk_window_get_focus ((GtkWindow *) window);
-
- /* escape key returns focus to playlist */
- if (event->keyval == GDK_KEY_Escape)
- {
- if (! focused || ! gtk_widget_is_ancestor (focused, (GtkWidget *) UI_PLAYLIST_NOTEBOOK))
- gtk_widget_grab_focus (playlist_get_treeview (aud_playlist_get_active ()));
-
- return FALSE;
- }
-
- /* single-key shortcuts; must not interfere with text entry */
- if (focused && GTK_IS_ENTRY (focused))
- return FALSE;
-
- switch (event->keyval)
- {
- case 'z':
- aud_drct_pl_prev ();
- return TRUE;
- case 'x':
- aud_drct_play ();
- return TRUE;
- case 'c':
- case ' ':
- aud_drct_pause ();
- return TRUE;
- case 'v':
- aud_drct_stop ();
- return TRUE;
- case 'b':
- aud_drct_pl_next ();
- return TRUE;
- case GDK_KEY_Left:
- if (aud_drct_get_playing ())
- do_seek (aud_drct_get_time () - aud_get_double ("gtkui", "step_size") * 1000);
- return TRUE;
- case GDK_KEY_Right:
- if (aud_drct_get_playing ())
- do_seek (aud_drct_get_time () + aud_get_double ("gtkui", "step_size") * 1000);
- return TRUE;
- }
-
- return FALSE;
-
- case GDK_CONTROL_MASK:
- switch (event->keyval)
- {
- case GDK_KEY_ISO_Left_Tab:
- case GDK_KEY_Tab:
- aud_playlist_set_active ((aud_playlist_get_active () + 1) %
- aud_playlist_count ());
- break;
-
- default:
- return FALSE;
- }
- break;
- case (GDK_CONTROL_MASK | GDK_SHIFT_MASK):
- switch (event->keyval)
- {
- case GDK_KEY_ISO_Left_Tab:
- case GDK_KEY_Tab:
- aud_playlist_set_active (aud_playlist_get_active () ?
- aud_playlist_get_active () - 1 : aud_playlist_count () - 1);
- break;
- default:
- return FALSE;
- }
- break;
- case GDK_MOD1_MASK:
- switch (event->keyval)
- {
- case GDK_KEY_Left:
- if (aud_drct_get_playing ())
- do_seek (aud_drct_get_time () - aud_get_double ("gtkui", "step_size") * 1000);
- break;
- case GDK_KEY_Right:
- if (aud_drct_get_playing ())
- do_seek (aud_drct_get_time () + aud_get_double ("gtkui", "step_size") * 1000);
- break;
- default:
- return FALSE;
- }
- default:
- return FALSE;
- }
-
- return TRUE;
-}
-
-static bool_t playlist_keypress_cb (GtkWidget * widget, GdkEventKey * event, void * unused)
-{
- switch (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK))
- {
- case 0:
- switch (event->keyval)
- {
- case GDK_KEY_Escape:
- ui_playlist_notebook_position (GINT_TO_POINTER (aud_playlist_get_active ()), NULL);
- return TRUE;
- case GDK_KEY_Delete:
- playlist_delete_selected ();
- return TRUE;
- case GDK_KEY_Menu:
- popup_menu_rclick (0, event->time);
- return TRUE;
- }
-
- break;
- case GDK_CONTROL_MASK:
- switch (event->keyval)
- {
- case 'x':
- playlist_cut ();
- return TRUE;
- case 'c':
- playlist_copy ();
- return TRUE;
- case 'v':
- playlist_paste ();
- return TRUE;
- case 'a':
- aud_playlist_select_all (aud_playlist_get_active (), TRUE);
- return TRUE;
- }
-
- break;
- }
-
- return FALSE;
-}
-
-static void update_toggles (void * data, void * user)
-{
- gtk_toggle_tool_button_set_active ((GtkToggleToolButton *) button_repeat,
- aud_get_bool (NULL, "repeat"));
- gtk_toggle_tool_button_set_active ((GtkToggleToolButton *) button_shuffle,
- aud_get_bool (NULL, "shuffle"));
-}
-
-static void toggle_repeat (GtkToggleToolButton * button)
-{
- aud_set_bool (NULL, "repeat", gtk_toggle_tool_button_get_active (button));
-}
-
-static void toggle_shuffle (GtkToggleToolButton * button)
-{
- aud_set_bool (NULL, "shuffle", gtk_toggle_tool_button_get_active (button));
-}
-
-static void toggle_search_tool (GtkToggleToolButton * button)
-{
- aud_plugin_enable (search_tool, gtk_toggle_tool_button_get_active (button));
-}
-
-static bool_t search_tool_toggled (PluginHandle * plugin, void * unused)
-{
- gtk_toggle_tool_button_set_active ((GtkToggleToolButton *) search_button,
- aud_plugin_get_enabled (plugin));
- return TRUE;
-}
-
-static void config_save (void)
-{
- if (gtk_widget_get_visible (window))
- save_window_size ();
-
- layout_save ();
- pw_col_save ();
-}
-
-static void ui_hooks_associate(void)
-{
- hook_associate ("title change", (HookFunction) title_change_cb, NULL);
- hook_associate ("playback begin", (HookFunction) ui_playback_begin, NULL);
- hook_associate ("playback ready", (HookFunction) ui_playback_ready, NULL);
- hook_associate ("playback pause", (HookFunction) pause_cb, NULL);
- hook_associate ("playback unpause", (HookFunction) pause_cb, NULL);
- hook_associate ("playback stop", (HookFunction) ui_playback_stop, NULL);
- hook_associate ("playlist update", ui_playlist_notebook_update, NULL);
- hook_associate ("playlist activate", ui_playlist_notebook_activate, NULL);
- hook_associate ("playlist set playing", ui_playlist_notebook_set_playing, NULL);
- hook_associate ("playlist position", ui_playlist_notebook_position, NULL);
- hook_associate ("set shuffle", update_toggles, NULL);
- hook_associate ("set repeat", update_toggles, NULL);
- hook_associate ("config save", (HookFunction) config_save, NULL);
-}
-
-static void ui_hooks_disassociate(void)
-{
- hook_dissociate ("title change", (HookFunction) title_change_cb);
- hook_dissociate ("playback begin", (HookFunction) ui_playback_begin);
- hook_dissociate ("playback ready", (HookFunction) ui_playback_ready);
- hook_dissociate ("playback pause", (HookFunction) pause_cb);
- hook_dissociate ("playback unpause", (HookFunction) pause_cb);
- hook_dissociate ("playback stop", (HookFunction) ui_playback_stop);
- hook_dissociate("playlist update", ui_playlist_notebook_update);
- hook_dissociate ("playlist activate", ui_playlist_notebook_activate);
- hook_dissociate ("playlist set playing", ui_playlist_notebook_set_playing);
- hook_dissociate ("playlist position", ui_playlist_notebook_position);
- hook_dissociate ("set shuffle", update_toggles);
- hook_dissociate ("set repeat", update_toggles);
- hook_dissociate ("config save", (HookFunction) config_save);
-}
-
-static bool_t init (void)
-{
- search_tool = aud_plugin_lookup_basename ("search-tool");
-
- aud_config_set_defaults ("gtkui", gtkui_defaults);
-
- pw_col_init ();
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_has_resize_grip ((GtkWindow *) window, FALSE);
-
- g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(window_delete), NULL);
-
- accel = gtk_accel_group_new ();
- gtk_window_add_accel_group ((GtkWindow *) window, accel);
-
- vbox_outer = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add ((GtkContainer *) window, vbox_outer);
-
- menu_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_pack_start ((GtkBox *) vbox_outer, menu_box, FALSE, FALSE, 0);
-
- toolbar = gtk_toolbar_new ();
- gtk_toolbar_set_style ((GtkToolbar *) toolbar, GTK_TOOLBAR_ICONS);
- GtkStyleContext * context = gtk_widget_get_style_context (toolbar);
- gtk_style_context_add_class (context, GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
- gtk_box_pack_start ((GtkBox *) vbox_outer, toolbar, FALSE, FALSE, 0);
-
- /* search button */
- if (search_tool)
- {
- search_button = toggle_button_new ("edit-find", toggle_search_tool);
- gtk_toolbar_insert ((GtkToolbar *) toolbar, search_button, -1);
- gtk_toggle_tool_button_set_active ((GtkToggleToolButton *) search_button,
- aud_plugin_get_enabled (search_tool));
- aud_plugin_add_watch (search_tool, search_tool_toggled, NULL);
- }
-
- /* playback buttons */
- toolbar_button_add (toolbar, button_open_pressed, "document-open");
- toolbar_button_add (toolbar, button_add_pressed, "list-add");
- button_play = toolbar_button_add (toolbar, aud_drct_play_pause, "media-playback-start");
- button_stop = toolbar_button_add (toolbar, aud_drct_stop, "media-playback-stop");
- toolbar_button_add (toolbar, aud_drct_pl_prev, "media-skip-backward");
- toolbar_button_add (toolbar, aud_drct_pl_next, "media-skip-forward");
-
- /* time slider and label */
- GtkToolItem * boxitem1 = gtk_tool_item_new ();
- gtk_tool_item_set_expand (boxitem1, TRUE);
- gtk_toolbar_insert ((GtkToolbar *) toolbar, boxitem1, -1);
-
- GtkWidget * box1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_container_add ((GtkContainer *) boxitem1, box1);
-
- slider = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
- gtk_scale_set_draw_value(GTK_SCALE(slider), FALSE);
- gtk_widget_set_size_request(slider, 120, -1);
- gtk_widget_set_valign (slider, GTK_ALIGN_CENTER);
- gtk_widget_set_can_focus(slider, FALSE);
- gtk_box_pack_start ((GtkBox *) box1, slider, TRUE, TRUE, 6);
-
- update_step_size ();
-
- label_time = markup_label_new(NULL);
- gtk_box_pack_end ((GtkBox *) box1, label_time, FALSE, FALSE, 6);
-
- gtk_widget_set_no_show_all (slider, TRUE);
- gtk_widget_set_no_show_all (label_time, TRUE);
-
- /* repeat and shuffle buttons */
- button_repeat = toggle_button_new ("media-playlist-repeat", toggle_repeat);
- gtk_toolbar_insert ((GtkToolbar *) toolbar, button_repeat, -1);
- button_shuffle = toggle_button_new ("media-playlist-shuffle", toggle_shuffle);
- gtk_toolbar_insert ((GtkToolbar *) toolbar, button_shuffle, -1);
-
- /* volume button */
- GtkToolItem * boxitem2 = gtk_tool_item_new ();
- gtk_toolbar_insert ((GtkToolbar *) toolbar, boxitem2, -1);
-
- GtkWidget * box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_container_add ((GtkContainer *) boxitem2, box2);
-
- volume = gtk_volume_button_new();
- g_object_set ((GObject *) volume, "size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
- gtk_button_set_relief(GTK_BUTTON(volume), GTK_RELIEF_NONE);
- gtk_scale_button_set_adjustment(GTK_SCALE_BUTTON(volume), GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 100, 1, 5, 0)));
- gtk_widget_set_can_focus(volume, FALSE);
-
- int lvol = 0, rvol = 0;
- aud_drct_get_volume(&lvol, &rvol);
- gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume), (lvol + rvol) / 2);
-
- gtk_box_pack_start ((GtkBox *) box2, volume, FALSE, FALSE, 0);
-
- /* main UI layout */
- layout_load ();
-
- GtkWidget * layout = layout_new ();
- gtk_box_pack_start ((GtkBox *) vbox_outer, layout, TRUE, TRUE, 0);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- layout_add_center (vbox);
-
- ui_playlist_notebook_new ();
- gtk_box_pack_start ((GtkBox *) vbox, (GtkWidget *) UI_PLAYLIST_NOTEBOOK, TRUE, TRUE, 0);
-
- /* optional UI elements */
- show_hide_menu ();
- show_hide_infoarea ();
- show_hide_statusbar ();
-
- AUDDBG("hooks associate\n");
- ui_hooks_associate();
-
- AUDDBG("playlist associate\n");
- ui_playlist_notebook_populate();
-
- g_signal_connect(slider, "change-value", G_CALLBACK(ui_slider_change_value_cb), NULL);
- g_signal_connect(slider, "button-press-event", G_CALLBACK(ui_slider_button_press_cb), NULL);
- g_signal_connect(slider, "button-release-event", G_CALLBACK(ui_slider_button_release_cb), NULL);
-
- volume_change_handler_id = g_signal_connect(volume, "value-changed", G_CALLBACK(ui_volume_value_changed_cb), NULL);
- g_signal_connect(volume, "pressed", G_CALLBACK(ui_volume_pressed_cb), NULL);
- g_signal_connect(volume, "released", G_CALLBACK(ui_volume_released_cb), NULL);
- update_volume_timeout_source = g_timeout_add(250, (GSourceFunc) ui_volume_slider_update, volume);
-
- g_signal_connect (window, "map-event", (GCallback) window_mapped_cb, NULL);
- g_signal_connect (window, "key-press-event", (GCallback) window_keypress_cb, NULL);
- g_signal_connect (UI_PLAYLIST_NOTEBOOK, "key-press-event", (GCallback) playlist_keypress_cb, NULL);
-
- if (aud_drct_get_playing ())
- {
- ui_playback_begin ();
- if (aud_drct_get_ready ())
- ui_playback_ready ();
- }
- else
- ui_playback_stop ();
-
- title_change_cb ();
-
- gtk_widget_show_all (vbox_outer);
-
- update_toggles (NULL, NULL);
-
- menu_rclick = make_menu_rclick (accel);
- menu_tab = make_menu_tab (accel);
-
- return TRUE;
-}
-
-static void cleanup (void)
-{
- if (menu_main)
- gtk_widget_destroy (menu_main);
-
- gtk_widget_destroy (menu_rclick);
- gtk_widget_destroy (menu_tab);
-
- if (update_song_timeout_source)
- {
- g_source_remove(update_song_timeout_source);
- update_song_timeout_source = 0;
- }
-
- if (update_volume_timeout_source)
- {
- g_source_remove(update_volume_timeout_source);
- update_volume_timeout_source = 0;
- }
-
- if (delayed_title_change_source)
- {
- g_source_remove (delayed_title_change_source);
- delayed_title_change_source = 0;
- }
-
- ui_hooks_disassociate();
-
- if (search_tool)
- aud_plugin_remove_watch (search_tool, search_tool_toggled, NULL);
-
- gtk_widget_destroy (window);
- layout_cleanup ();
-}
-
-static void menu_position_cb (GtkMenu * menu, int * x, int * y, int * push, void * button)
-{
- int xorig, yorig, xwin, ywin;
-
- gdk_window_get_origin (gtk_widget_get_window (window), & xorig, & yorig);
- gtk_widget_translate_coordinates (button, window, 0, 0, & xwin, & ywin);
-
- * x = xorig + xwin;
- * y = yorig + ywin + gtk_widget_get_allocated_height (button);
- * push = TRUE;
-}
-
-static void menu_button_cb (void)
-{
- if (gtk_toggle_tool_button_get_active ((GtkToggleToolButton *) menu_button))
- gtk_menu_popup ((GtkMenu *) menu_main, NULL, NULL, menu_position_cb,
- menu_button, 0, gtk_get_current_event_time ());
- else
- gtk_widget_hide (menu_main);
-}
-
-static void menu_hide_cb (void)
-{
- gtk_toggle_tool_button_set_active ((GtkToggleToolButton *) menu_button, FALSE);
-}
-
-void show_hide_menu (void)
-{
- if (aud_get_bool ("gtkui", "menu_visible"))
- {
- /* remove menu button from toolbar and show menu bar */
- if (menu_main)
- gtk_widget_destroy (menu_main);
- if (menu_button)
- gtk_widget_destroy ((GtkWidget *) menu_button);
-
- if (! menu)
- {
- menu = make_menu_bar (accel);
- g_signal_connect (menu, "destroy", (GCallback) gtk_widget_destroyed,
- & menu);
- gtk_widget_show (menu);
- gtk_box_pack_start ((GtkBox *) menu_box, menu, TRUE, TRUE, 0);
- }
- }
- else
- {
- /* hide menu bar and add menu item to toolbar */
- if (menu)
- gtk_widget_destroy (menu);
-
- if (! menu_main)
- {
- menu_main = make_menu_main (accel);
- g_signal_connect (menu_main, "destroy", (GCallback)
- gtk_widget_destroyed, & menu_main);
- g_signal_connect (menu_main, "hide", (GCallback) menu_hide_cb, NULL);
- }
-
- if (! menu_button)
- {
- menu_button = gtk_toggle_tool_button_new ();
- gtk_tool_button_set_icon_name ((GtkToolButton *) menu_button, "audacious");
- g_signal_connect (menu_button, "destroy", (GCallback)
- gtk_widget_destroyed, & menu_button);
- gtk_widget_show ((GtkWidget *) menu_button);
- gtk_toolbar_insert ((GtkToolbar *) toolbar, menu_button, 0);
- g_signal_connect (menu_button, "toggled", (GCallback) menu_button_cb, NULL);
- }
- }
-}
-
-void show_hide_infoarea (void)
-{
- bool_t show = aud_get_bool ("gtkui", "infoarea_visible");
-
- if (show && ! infoarea)
- {
- infoarea = ui_infoarea_new ();
- g_signal_connect (infoarea, "destroy", (GCallback) gtk_widget_destroyed, & infoarea);
- gtk_box_pack_end ((GtkBox *) vbox, infoarea, FALSE, FALSE, 0);
- gtk_widget_show_all (infoarea);
-
- show_hide_infoarea_vis ();
- }
-
- if (! show && infoarea)
- {
- gtk_widget_destroy (infoarea);
- infoarea = NULL;
- }
-}
-
-void show_hide_infoarea_vis (void)
-{
- /* only turn on visualization if interface is shown */
- ui_infoarea_show_vis (gtk_widget_get_visible (window) && aud_get_bool
- ("gtkui", "infoarea_show_vis"));
-}
-
-void show_hide_statusbar (void)
-{
- bool_t show = aud_get_bool ("gtkui", "statusbar_visible");
-
- if (show && ! statusbar)
- {
- statusbar = ui_statusbar_new ();
- g_signal_connect (statusbar, "destroy", (GCallback) gtk_widget_destroyed, & statusbar);
- gtk_box_pack_end ((GtkBox *) vbox_outer, statusbar, FALSE, FALSE, 0);
- gtk_widget_show_all (statusbar);
- }
-
- if (! show && statusbar)
- {
- gtk_widget_destroy (statusbar);
- statusbar = NULL;
- }
-}
-
-void popup_menu_rclick (unsigned button, uint32_t time)
-{
- gtk_menu_popup ((GtkMenu *) menu_rclick, NULL, NULL, NULL, NULL, button,
- time);
-}
-
-void popup_menu_tab (unsigned button, uint32_t time, int playlist)
-{
- menu_tab_playlist_id = aud_playlist_get_unique_id (playlist);
- gtk_menu_popup ((GtkMenu *) menu_tab, NULL, NULL, NULL, NULL, button, time);
-}
-
-void activate_search_tool (void)
-{
- if (! search_tool)
- return;
-
- if (! aud_plugin_get_enabled (search_tool))
- aud_plugin_enable (search_tool, TRUE);
-
- aud_plugin_send_message (search_tool, "grab focus", NULL, 0);
-}
diff --git a/src/gtkui/ui_gtk.cc b/src/gtkui/ui_gtk.cc
new file mode 100644
index 000000000000..b70d005f8aaa
--- /dev/null
+++ b/src/gtkui/ui_gtk.cc
@@ -0,0 +1,1120 @@
+/*
+ * ui_gtk.c
+ * Copyright 2009-2012 William Pitcock, Tomasz MoÅ, MichaÅ Lipski, and John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <string.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/runtime.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/plugins.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/hook.h>
+#include <libaudgui/libaudgui.h>
+
+#include "gtkui.h"
+#include "layout.h"
+#include "ui_playlist_notebook.h"
+#include "ui_playlist_widget.h"
+#include "ui_infoarea.h"
+#include "ui_statusbar.h"
+#include "playlist_util.h"
+
+static const char * const gtkui_defaults[] = {
+ "infoarea_show_vis", "TRUE",
+ "infoarea_visible", "TRUE",
+ "menu_visible", "TRUE",
+ "playlist_tabs_visible", "TRUE",
+ "statusbar_visible", "TRUE",
+ "entry_count_visible", "FALSE",
+ "close_button_visible", "TRUE",
+
+ "autoscroll", "TRUE",
+ "playlist_columns", "title artist album queued length",
+ "playlist_headers", "TRUE",
+ "show_remaining_time", "FALSE",
+ "step_size", "5",
+
+ "player_x", "-1000",
+ "player_y", "-1000",
+ "player_width", "760",
+ "player_height", "460",
+
+ nullptr
+};
+
+class GtkUI : public IfacePlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("GTK Interface"),
+ PACKAGE,
+ nullptr,
+ & gtkui_prefs
+ };
+
+ constexpr GtkUI () : IfacePlugin (info) {}
+
+ bool init ();
+ void cleanup ();
+ void show (bool show);
+
+ void run ()
+ { gtk_main (); }
+ void quit ()
+ { gtk_main_quit (); }
+
+ void show_about_window ()
+ { audgui_show_about_window (); }
+ void hide_about_window ()
+ { audgui_hide_about_window (); }
+ void show_filebrowser (bool open)
+ { audgui_run_filebrowser (open); }
+ void hide_filebrowser ()
+ { audgui_hide_filebrowser (); }
+ void show_jump_to_song ()
+ { audgui_jump_to_track (); }
+ void hide_jump_to_song ()
+ { audgui_jump_to_track_hide (); }
+ void show_prefs_window ()
+ { audgui_show_prefs_window (); }
+ void hide_prefs_window ()
+ { audgui_hide_prefs_window (); }
+ void plugin_menu_add (AudMenuID id, void func (), const char * name, const char * icon)
+ { audgui_plugin_menu_add (id, func, name, icon); }
+ void plugin_menu_remove (AudMenuID id, void func ())
+ { audgui_plugin_menu_remove (id, func); }
+};
+
+EXPORT GtkUI aud_plugin_instance;
+
+static PluginHandle * search_tool;
+
+static GtkWidget * volume;
+static bool volume_slider_is_moving = false;
+static unsigned update_volume_timeout_source = 0;
+static unsigned long volume_change_handler_id;
+
+static GtkAccelGroup * accel;
+
+static GtkWidget * window, * vbox_outer, * menu_box, * menu, * toolbar, * vbox,
+ * infoarea, * statusbar;
+static GtkToolItem * menu_button, * search_button, * button_play, * button_stop,
+ * button_shuffle, * button_repeat;
+static GtkWidget * slider, * label_time;
+static GtkWidget * menu_main, * menu_rclick, * menu_tab;
+
+static gboolean slider_is_moving = false;
+static int slider_seek_time = -1;
+static unsigned delayed_title_change_source = 0;
+static unsigned update_song_timeout_source = 0;
+
+static void save_window_size ()
+{
+ int x, y, w, h;
+ gtk_window_get_position ((GtkWindow *) window, & x, & y);
+ gtk_window_get_size ((GtkWindow *) window, & w, & h);
+
+ aud_set_int ("gtkui", "player_x", x);
+ aud_set_int ("gtkui", "player_y", y);
+ aud_set_int ("gtkui", "player_width", w);
+ aud_set_int ("gtkui", "player_height", h);
+}
+
+static void restore_window_size ()
+{
+ int x = aud_get_int ("gtkui", "player_x");
+ int y = aud_get_int ("gtkui", "player_y");
+ int w = aud_get_int ("gtkui", "player_width");
+ int h = aud_get_int ("gtkui", "player_height");
+
+ gtk_window_set_default_size ((GtkWindow *) window, w, h);
+
+ if (x > -1000 && y > -1000)
+ gtk_window_move ((GtkWindow *) window, x, y);
+}
+
+static gboolean window_delete ()
+{
+ bool handle = false;
+
+ hook_call ("window close", & handle);
+
+ if (handle)
+ return true;
+
+ aud_quit ();
+ return true;
+}
+
+static void button_open_pressed ()
+{
+ audgui_run_filebrowser (true);
+}
+
+static void button_add_pressed ()
+{
+ audgui_run_filebrowser (false);
+}
+
+void set_ab_repeat_a ()
+{
+ if (! aud_drct_get_playing ())
+ return;
+
+ int a, b;
+ aud_drct_get_ab_repeat (a, b);
+ a = aud_drct_get_time ();
+ aud_drct_set_ab_repeat (a, b);
+}
+
+void set_ab_repeat_b ()
+{
+ if (! aud_drct_get_playing ())
+ return;
+
+ int a, b;
+ aud_drct_get_ab_repeat (a, b);
+ b = aud_drct_get_time ();
+ aud_drct_set_ab_repeat (a, b);
+}
+
+void clear_ab_repeat ()
+{
+ aud_drct_set_ab_repeat (-1, -1);
+}
+
+static gboolean title_change_cb ()
+{
+ if (delayed_title_change_source)
+ {
+ g_source_remove (delayed_title_change_source);
+ delayed_title_change_source = 0;
+ }
+
+ if (aud_drct_get_playing ())
+ {
+ if (aud_drct_get_ready ())
+ {
+ String title = aud_drct_get_title ();
+ gtk_window_set_title ((GtkWindow *) window,
+ str_printf (_("%s - Audacious"), (const char *) title));
+ }
+ else
+ gtk_window_set_title ((GtkWindow *) window, _("Buffering ..."));
+ }
+ else
+ gtk_window_set_title ((GtkWindow *) window, _("Audacious"));
+
+ return false;
+}
+
+void GtkUI::show (bool show)
+{
+ if (show)
+ {
+ if (! gtk_widget_get_visible (window))
+ restore_window_size ();
+
+ gtk_window_present ((GtkWindow *) window);
+ }
+ else
+ {
+ if (gtk_widget_get_visible (window))
+ save_window_size ();
+
+ gtk_widget_hide (window);
+ }
+
+ show_hide_infoarea_vis ();
+}
+
+static void append_str (char * buf, int bufsize, const char * str)
+{
+ snprintf (buf + strlen (buf), bufsize - strlen (buf), "%s", str);
+}
+
+static void set_time_label (int time, int len)
+{
+ char s[128] = "<b>";
+
+ if (len && aud_get_bool ("gtkui", "show_remaining_time"))
+ append_str (s, sizeof s, str_format_time (len - time));
+ else
+ append_str (s, sizeof s, str_format_time (time));
+
+ if (len)
+ {
+ append_str (s, sizeof s, " / ");
+ append_str (s, sizeof s, str_format_time (len));
+
+ int a, b;
+ aud_drct_get_ab_repeat (a, b);
+
+ if (a >= 0)
+ {
+ append_str (s, sizeof s, " A=");
+ append_str (s, sizeof s, str_format_time (a));
+ }
+
+ if (b >= 0)
+ {
+ append_str (s, sizeof s, " B=");
+ append_str (s, sizeof s, str_format_time (b));
+ }
+ }
+
+ append_str (s, sizeof s, "</b>");
+
+ /* only update label if necessary */
+ if (strcmp (gtk_label_get_label ((GtkLabel *) label_time), s))
+ gtk_label_set_markup ((GtkLabel *) label_time, s);
+}
+
+static void set_slider (int time)
+{
+ gtk_range_set_value ((GtkRange *) slider, time);
+}
+
+static gboolean time_counter_cb ()
+{
+ if (slider_is_moving)
+ return true;
+
+ slider_seek_time = -1; // delayed reset to avoid seeking twice
+
+ int time = aud_drct_get_time ();
+ int length = aud_drct_get_length ();
+
+ if (length > 0)
+ set_slider (time);
+
+ set_time_label (time, length);
+
+ return true;
+}
+
+static void do_seek (int time)
+{
+ int length = aud_drct_get_length ();
+ time = aud::clamp (time, 0, length);
+
+ set_slider (time);
+ set_time_label (time, length);
+ aud_drct_seek (time);
+
+ // Trick: Unschedule and then schedule the update function. This gives the
+ // player 1/4 second to perform the seek before we update the display again,
+ // in an attempt to reduce flickering.
+ if (update_song_timeout_source)
+ {
+ g_source_remove (update_song_timeout_source);
+ update_song_timeout_source = g_timeout_add (250, (GSourceFunc) time_counter_cb, nullptr);
+ }
+}
+
+static gboolean ui_slider_change_value_cb (GtkRange * range,
+ GtkScrollType scroll, double value)
+{
+ int length = aud_drct_get_length ();
+ int time = aud::clamp ((int) value, 0, length);
+
+ set_time_label (time, length);
+
+ if (slider_is_moving)
+ slider_seek_time = time;
+ else if (time != slider_seek_time) // avoid seeking twice
+ do_seek (time);
+
+ return false;
+}
+
+static gboolean ui_slider_button_press_cb (GtkWidget * widget, GdkEventButton * event)
+{
+ gboolean primary_warps = false;
+ g_object_get (gtk_widget_get_settings (widget),
+ "gtk-primary-button-warps-slider", & primary_warps, nullptr);
+
+ if (event->button == 1 && ! primary_warps)
+ event->button = 2;
+
+ slider_is_moving = true;
+ return false;
+}
+
+static gboolean ui_slider_button_release_cb (GtkWidget * widget, GdkEventButton * event)
+{
+ gboolean primary_warps = false;
+ g_object_get (gtk_widget_get_settings (widget),
+ "gtk-primary-button-warps-slider", & primary_warps, nullptr);
+
+ if (event->button == 1 && ! primary_warps)
+ event->button = 2;
+
+ if (slider_seek_time != -1)
+ do_seek (slider_seek_time);
+
+ slider_is_moving = false;
+ return false;
+}
+
+static gboolean ui_volume_value_changed_cb (GtkButton * button, double volume)
+{
+ aud_drct_set_volume_main (volume);
+ return true;
+}
+
+static void ui_volume_pressed_cb (GtkButton * button)
+{
+ volume_slider_is_moving = true;
+}
+
+static void ui_volume_released_cb (GtkButton * button)
+{
+ volume_slider_is_moving = false;
+}
+
+static gboolean ui_volume_slider_update (void * button)
+{
+ if (volume_slider_is_moving || ! button)
+ return true;
+
+ int volume = aud_drct_get_volume_main ();
+
+ if (volume == (int) gtk_scale_button_get_value ((GtkScaleButton *) button))
+ return true;
+
+ g_signal_handler_block (button, volume_change_handler_id);
+ gtk_scale_button_set_value ((GtkScaleButton *) button, volume);
+ g_signal_handler_unblock (button, volume_change_handler_id);
+
+ return true;
+}
+
+static void set_slider_length (int length)
+{
+ if (length > 0)
+ {
+ gtk_range_set_range ((GtkRange *) slider, 0, length);
+ gtk_widget_show (slider);
+ }
+ else
+ gtk_widget_hide (slider);
+}
+
+void update_step_size ()
+{
+ double step_size = aud_get_double ("gtkui", "step_size");
+ gtk_range_set_increments ((GtkRange *) slider, step_size * 1000, step_size * 1000);
+}
+
+static void pause_cb ()
+{
+ gtk_tool_button_set_icon_name ((GtkToolButton *) button_play,
+ aud_drct_get_paused () ? "media-playback-start" : "media-playback-pause");
+}
+
+static void ui_playback_begin ()
+{
+ pause_cb ();
+ gtk_widget_set_sensitive ((GtkWidget *) button_stop, true);
+
+ if (delayed_title_change_source)
+ g_source_remove (delayed_title_change_source);
+
+ /* If "title change" is not called by 1/4 second after starting playback,
+ * show "Buffering ..." as the window title. */
+ delayed_title_change_source = g_timeout_add (250, (GSourceFunc)
+ title_change_cb, nullptr);
+}
+
+static void ui_playback_ready ()
+{
+ title_change_cb ();
+ set_slider_length (aud_drct_get_length ());
+ time_counter_cb ();
+
+ /* update time counter 4 times a second */
+ if (! update_song_timeout_source)
+ update_song_timeout_source = g_timeout_add (250, (GSourceFunc)
+ time_counter_cb, nullptr);
+
+ gtk_widget_show (label_time);
+}
+
+static void ui_playback_stop ()
+{
+ if (update_song_timeout_source)
+ {
+ g_source_remove (update_song_timeout_source);
+ update_song_timeout_source = 0;
+ }
+
+ if (delayed_title_change_source)
+ g_source_remove (delayed_title_change_source);
+
+ /* Don't update the window title immediately; we may be about to start
+ * another song. */
+ delayed_title_change_source = g_idle_add ((GSourceFunc) title_change_cb, nullptr);
+
+ gtk_tool_button_set_icon_name ((GtkToolButton *) button_play, "media-playback-start");
+ gtk_widget_set_sensitive ((GtkWidget *) button_stop, false);
+ gtk_widget_hide (slider);
+ gtk_widget_hide (label_time);
+}
+
+static GtkToolItem * toolbar_button_add (GtkWidget * toolbar,
+ void (* callback) (), const char * icon)
+{
+ GtkToolItem * item = gtk_tool_button_new (nullptr, nullptr);
+ gtk_tool_button_set_icon_name ((GtkToolButton *) item, icon);
+ gtk_toolbar_insert ((GtkToolbar *) toolbar, item, -1);
+ g_signal_connect (item, "clicked", callback, nullptr);
+ return item;
+}
+
+static GtkToolItem * toggle_button_new (const char * icon,
+ void (* toggled) (GtkToggleToolButton * button))
+{
+ GtkToolItem * item = gtk_toggle_tool_button_new ();
+ gtk_tool_button_set_icon_name ((GtkToolButton *) item, icon);
+ g_signal_connect (item, "toggled", (GCallback) toggled, nullptr);
+ return item;
+}
+
+static GtkWidget * markup_label_new (const char * str)
+{
+ GtkWidget * label = gtk_label_new (str);
+ gtk_label_set_use_markup ((GtkLabel *) label, true);
+ return label;
+}
+
+static void window_mapped_cb (GtkWidget * widget)
+{
+ gtk_widget_grab_focus (playlist_get_treeview (aud_playlist_get_active ()));
+}
+
+static gboolean window_keypress_cb (GtkWidget * widget, GdkEventKey * event)
+{
+ switch (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK))
+ {
+ case 0:
+ {
+ GtkWidget * focused = gtk_window_get_focus ((GtkWindow *) window);
+
+ /* escape key returns focus to playlist */
+ if (event->keyval == GDK_KEY_Escape)
+ {
+ if (! focused || ! gtk_widget_is_ancestor (focused, (GtkWidget *) UI_PLAYLIST_NOTEBOOK))
+ gtk_widget_grab_focus (playlist_get_treeview (aud_playlist_get_active ()));
+
+ return false;
+ }
+
+ /* single-key shortcuts; must not interfere with text entry */
+ if (focused && GTK_IS_ENTRY (focused))
+ return false;
+
+ switch (event->keyval)
+ {
+ case 'z':
+ aud_drct_pl_prev ();
+ return true;
+ case 'x':
+ aud_drct_play ();
+ return true;
+ case 'c':
+ case ' ':
+ aud_drct_pause ();
+ return true;
+ case 'v':
+ aud_drct_stop ();
+ return true;
+ case 'b':
+ aud_drct_pl_next ();
+ return true;
+ case GDK_KEY_Left:
+ if (aud_drct_get_playing ())
+ do_seek (aud_drct_get_time () - aud_get_double ("gtkui", "step_size") * 1000);
+ return true;
+ case GDK_KEY_Right:
+ if (aud_drct_get_playing ())
+ do_seek (aud_drct_get_time () + aud_get_double ("gtkui", "step_size") * 1000);
+ return true;
+ }
+
+ return false;
+ }
+
+ case GDK_CONTROL_MASK:
+ switch (event->keyval)
+ {
+ case GDK_KEY_ISO_Left_Tab:
+ case GDK_KEY_Tab:
+ aud_playlist_set_active ((aud_playlist_get_active () + 1) %
+ aud_playlist_count ());
+ break;
+
+ default:
+ return false;
+ }
+ break;
+ case (GDK_CONTROL_MASK | GDK_SHIFT_MASK):
+ switch (event->keyval)
+ {
+ case GDK_KEY_ISO_Left_Tab:
+ case GDK_KEY_Tab:
+ aud_playlist_set_active (aud_playlist_get_active () ?
+ aud_playlist_get_active () - 1 : aud_playlist_count () - 1);
+ break;
+ default:
+ return false;
+ }
+ break;
+ case GDK_MOD1_MASK:
+ switch (event->keyval)
+ {
+ case GDK_KEY_Left:
+ if (aud_drct_get_playing ())
+ do_seek (aud_drct_get_time () - aud_get_double ("gtkui", "step_size") * 1000);
+ break;
+ case GDK_KEY_Right:
+ if (aud_drct_get_playing ())
+ do_seek (aud_drct_get_time () + aud_get_double ("gtkui", "step_size") * 1000);
+ break;
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+static gboolean playlist_keypress_cb (GtkWidget * widget, GdkEventKey * event)
+{
+ switch (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK))
+ {
+ case 0:
+ switch (event->keyval)
+ {
+ case GDK_KEY_Escape:
+ ui_playlist_notebook_position (aud::to_ptr (aud_playlist_get_active ()), nullptr);
+ return true;
+ case GDK_KEY_Delete:
+ playlist_delete_selected ();
+ return true;
+ case GDK_KEY_Menu:
+ popup_menu_rclick (0, event->time);
+ return true;
+ }
+
+ break;
+ case GDK_CONTROL_MASK:
+ switch (event->keyval)
+ {
+ case 'x':
+ playlist_cut ();
+ return true;
+ case 'c':
+ playlist_copy ();
+ return true;
+ case 'v':
+ playlist_paste ();
+ return true;
+ case 'a':
+ aud_playlist_select_all (aud_playlist_get_active (), true);
+ return true;
+ }
+
+ break;
+ }
+
+ return false;
+}
+
+static void update_toggles (void * data, void * user)
+{
+ gtk_toggle_tool_button_set_active ((GtkToggleToolButton *) button_repeat,
+ aud_get_bool (nullptr, "repeat"));
+ gtk_toggle_tool_button_set_active ((GtkToggleToolButton *) button_shuffle,
+ aud_get_bool (nullptr, "shuffle"));
+}
+
+static void toggle_repeat (GtkToggleToolButton * button)
+{
+ aud_set_bool (nullptr, "repeat", gtk_toggle_tool_button_get_active (button));
+}
+
+static void toggle_shuffle (GtkToggleToolButton * button)
+{
+ aud_set_bool (nullptr, "shuffle", gtk_toggle_tool_button_get_active (button));
+}
+
+static void toggle_search_tool (GtkToggleToolButton * button)
+{
+ aud_plugin_enable (search_tool, gtk_toggle_tool_button_get_active (button));
+}
+
+static bool search_tool_toggled (PluginHandle * plugin, void *)
+{
+ gtk_toggle_tool_button_set_active ((GtkToggleToolButton *) search_button,
+ aud_plugin_get_enabled (plugin));
+ return true;
+}
+
+static void config_save ()
+{
+ if (gtk_widget_get_visible (window))
+ save_window_size ();
+
+ layout_save ();
+ pw_col_save ();
+}
+
+static void ui_hooks_associate ()
+{
+ hook_associate ("title change", (HookFunction) title_change_cb, nullptr);
+ hook_associate ("playback begin", (HookFunction) ui_playback_begin, nullptr);
+ hook_associate ("playback ready", (HookFunction) ui_playback_ready, nullptr);
+ hook_associate ("playback pause", (HookFunction) pause_cb, nullptr);
+ hook_associate ("playback unpause", (HookFunction) pause_cb, nullptr);
+ hook_associate ("playback stop", (HookFunction) ui_playback_stop, nullptr);
+ hook_associate ("playlist update", ui_playlist_notebook_update, nullptr);
+ hook_associate ("playlist activate", ui_playlist_notebook_activate, nullptr);
+ hook_associate ("playlist set playing", ui_playlist_notebook_set_playing, nullptr);
+ hook_associate ("playlist position", ui_playlist_notebook_position, nullptr);
+ hook_associate ("set shuffle", update_toggles, nullptr);
+ hook_associate ("set repeat", update_toggles, nullptr);
+ hook_associate ("config save", (HookFunction) config_save, nullptr);
+}
+
+static void ui_hooks_disassociate ()
+{
+ hook_dissociate ("title change", (HookFunction) title_change_cb);
+ hook_dissociate ("playback begin", (HookFunction) ui_playback_begin);
+ hook_dissociate ("playback ready", (HookFunction) ui_playback_ready);
+ hook_dissociate ("playback pause", (HookFunction) pause_cb);
+ hook_dissociate ("playback unpause", (HookFunction) pause_cb);
+ hook_dissociate ("playback stop", (HookFunction) ui_playback_stop);
+ hook_dissociate ("playlist update", ui_playlist_notebook_update);
+ hook_dissociate ("playlist activate", ui_playlist_notebook_activate);
+ hook_dissociate ("playlist set playing", ui_playlist_notebook_set_playing);
+ hook_dissociate ("playlist position", ui_playlist_notebook_position);
+ hook_dissociate ("set shuffle", update_toggles);
+ hook_dissociate ("set repeat", update_toggles);
+ hook_dissociate ("config save", (HookFunction) config_save);
+}
+
+static void add_dock_plugin (PluginHandle * plugin, void *)
+{
+ GtkWidget * widget = (GtkWidget *) aud_plugin_get_gtk_widget (plugin);
+ if (widget)
+ layout_add (plugin, widget);
+}
+
+static void remove_dock_plugin (PluginHandle * plugin, void *)
+{
+ layout_remove (plugin);
+}
+
+static void add_dock_plugins ()
+{
+ for (PluginHandle * plugin : aud_plugin_list (PluginType::General))
+ {
+ if (aud_plugin_get_enabled (plugin))
+ add_dock_plugin (plugin, nullptr);
+ }
+
+ for (PluginHandle * plugin : aud_plugin_list (PluginType::Vis))
+ {
+ if (aud_plugin_get_enabled (plugin))
+ add_dock_plugin (plugin, nullptr);
+ }
+
+ hook_associate ("dock plugin enabled", (HookFunction) add_dock_plugin, nullptr);
+ hook_associate ("dock plugin disabled", (HookFunction) remove_dock_plugin, nullptr);
+}
+
+static void remove_dock_plugins ()
+{
+ for (PluginHandle * plugin : aud_plugin_list (PluginType::General))
+ {
+ if (aud_plugin_get_enabled (plugin))
+ remove_dock_plugin (plugin, nullptr);
+ }
+
+ for (PluginHandle * plugin : aud_plugin_list (PluginType::Vis))
+ {
+ if (aud_plugin_get_enabled (plugin))
+ remove_dock_plugin (plugin, nullptr);
+ }
+
+ hook_dissociate ("dock plugin enabled", (HookFunction) add_dock_plugin);
+ hook_dissociate ("dock plugin disabled", (HookFunction) remove_dock_plugin);
+}
+
+bool GtkUI::init ()
+{
+ if (aud_get_mainloop_type () != MainloopType::GLib)
+ return false;
+
+ audgui_init ();
+
+ search_tool = aud_plugin_lookup_basename ("search-tool");
+
+ aud_config_set_defaults ("gtkui", gtkui_defaults);
+
+ pw_col_init ();
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ accel = gtk_accel_group_new ();
+ gtk_window_add_accel_group ((GtkWindow *) window, accel);
+
+ vbox_outer = gtk_vbox_new (false, 0);
+ gtk_container_add ((GtkContainer *) window, vbox_outer);
+
+ menu_box = gtk_hbox_new (false, 0);
+ gtk_box_pack_start ((GtkBox *) vbox_outer, menu_box, false, false, 0);
+
+ toolbar = gtk_toolbar_new ();
+ gtk_toolbar_set_style ((GtkToolbar *) toolbar, GTK_TOOLBAR_ICONS);
+ gtk_box_pack_start ((GtkBox *) vbox_outer, toolbar, false, false, 0);
+
+ /* search button */
+ if (search_tool)
+ {
+ search_button = toggle_button_new ("edit-find", toggle_search_tool);
+ gtk_toolbar_insert ((GtkToolbar *) toolbar, search_button, -1);
+ gtk_toggle_tool_button_set_active ((GtkToggleToolButton *) search_button,
+ aud_plugin_get_enabled (search_tool));
+ aud_plugin_add_watch (search_tool, search_tool_toggled, nullptr);
+ }
+
+ /* playback buttons */
+ toolbar_button_add (toolbar, button_open_pressed, "document-open");
+ toolbar_button_add (toolbar, button_add_pressed, "list-add");
+ button_play = toolbar_button_add (toolbar, aud_drct_play_pause, "media-playback-start");
+ button_stop = toolbar_button_add (toolbar, aud_drct_stop, "media-playback-stop");
+ toolbar_button_add (toolbar, aud_drct_pl_prev, "media-skip-backward");
+ toolbar_button_add (toolbar, aud_drct_pl_next, "media-skip-forward");
+
+ /* time slider and label */
+ GtkToolItem * boxitem1 = gtk_tool_item_new ();
+ gtk_tool_item_set_expand (boxitem1, true);
+ gtk_toolbar_insert ((GtkToolbar *) toolbar, boxitem1, -1);
+
+ GtkWidget * box1 = gtk_hbox_new (false, 0);
+ gtk_container_add ((GtkContainer *) boxitem1, box1);
+
+ slider = gtk_hscale_new (nullptr);
+ gtk_scale_set_draw_value ((GtkScale *) slider, false);
+ gtk_widget_set_size_request (slider, 120, -1);
+ gtk_widget_set_can_focus (slider, false);
+ gtk_box_pack_start ((GtkBox *) box1, slider, true, true, 6);
+
+ update_step_size ();
+
+ label_time = markup_label_new (nullptr);
+ gtk_box_pack_end ((GtkBox *) box1, label_time, false, false, 6);
+
+ gtk_widget_set_no_show_all (slider, true);
+ gtk_widget_set_no_show_all (label_time, true);
+
+ /* repeat and shuffle buttons */
+ button_repeat = toggle_button_new ("media-playlist-repeat", toggle_repeat);
+ gtk_toolbar_insert ((GtkToolbar *) toolbar, button_repeat, -1);
+ button_shuffle = toggle_button_new ("media-playlist-shuffle", toggle_shuffle);
+ gtk_toolbar_insert ((GtkToolbar *) toolbar, button_shuffle, -1);
+
+ /* volume button */
+ GtkToolItem * boxitem2 = gtk_tool_item_new ();
+ gtk_toolbar_insert ((GtkToolbar *) toolbar, boxitem2, -1);
+
+ GtkWidget * box2 = gtk_hbox_new (false, 0);
+ gtk_container_add ((GtkContainer *) boxitem2, box2);
+
+ volume = gtk_volume_button_new ();
+ g_object_set ((GObject *) volume, "size", GTK_ICON_SIZE_LARGE_TOOLBAR, nullptr);
+ gtk_button_set_relief ((GtkButton *) volume, GTK_RELIEF_NONE);
+ gtk_scale_button_set_adjustment ((GtkScaleButton *) volume,
+ (GtkAdjustment *) gtk_adjustment_new (0, 0, 100, 1, 5, 0));
+ gtk_widget_set_can_focus (volume, false);
+
+ gtk_scale_button_set_value ((GtkScaleButton *) volume, aud_drct_get_volume_main ());
+
+ gtk_box_pack_start ((GtkBox *) box2, volume, false, false, 0);
+
+ /* main UI layout */
+ layout_load ();
+
+ GtkWidget * layout = layout_new ();
+ gtk_box_pack_start ((GtkBox *) vbox_outer, layout, true, true, 0);
+
+ vbox = gtk_vbox_new (false, 6);
+ layout_add_center (vbox);
+
+ ui_playlist_notebook_new ();
+ gtk_box_pack_start ((GtkBox *) vbox, (GtkWidget *) UI_PLAYLIST_NOTEBOOK, true, true, 0);
+
+ /* optional UI elements */
+ show_hide_menu ();
+ show_hide_infoarea ();
+ show_hide_statusbar ();
+
+ AUDDBG ("hooks associate\n");
+ ui_hooks_associate ();
+
+ AUDDBG ("playlist associate\n");
+ ui_playlist_notebook_populate ();
+
+ g_signal_connect (slider, "change-value", (GCallback) ui_slider_change_value_cb , nullptr);
+ g_signal_connect (slider, "button-press-event", (GCallback) ui_slider_button_press_cb, nullptr);
+ g_signal_connect (slider, "button-release-event", (GCallback) ui_slider_button_release_cb, nullptr);
+
+ volume_change_handler_id = g_signal_connect (volume, "value-changed", (GCallback) ui_volume_value_changed_cb, nullptr);
+ g_signal_connect (volume, "pressed", (GCallback) ui_volume_pressed_cb, nullptr);
+ g_signal_connect (volume, "released", (GCallback) ui_volume_released_cb, nullptr);
+ update_volume_timeout_source = g_timeout_add (250, (GSourceFunc) ui_volume_slider_update, volume);
+
+ g_signal_connect (window, "map-event", (GCallback) window_mapped_cb, nullptr);
+ g_signal_connect (window, "delete-event", (GCallback) window_delete, nullptr);
+ g_signal_connect (window, "key-press-event", (GCallback) window_keypress_cb, nullptr);
+ g_signal_connect (UI_PLAYLIST_NOTEBOOK, "key-press-event", (GCallback) playlist_keypress_cb, nullptr);
+
+ if (aud_drct_get_playing ())
+ {
+ ui_playback_begin ();
+ if (aud_drct_get_ready ())
+ ui_playback_ready ();
+ }
+ else
+ ui_playback_stop ();
+
+ title_change_cb ();
+
+ gtk_widget_show_all (vbox_outer);
+
+ update_toggles (nullptr, nullptr);
+
+ menu_rclick = make_menu_rclick (accel);
+ menu_tab = make_menu_tab (accel);
+
+ add_dock_plugins ();
+
+ return true;
+}
+
+void GtkUI::cleanup ()
+{
+ remove_dock_plugins ();
+
+ if (menu_main)
+ gtk_widget_destroy (menu_main);
+
+ gtk_widget_destroy (menu_rclick);
+ gtk_widget_destroy (menu_tab);
+
+ if (update_song_timeout_source)
+ {
+ g_source_remove (update_song_timeout_source);
+ update_song_timeout_source = 0;
+ }
+
+ if (update_volume_timeout_source)
+ {
+ g_source_remove (update_volume_timeout_source);
+ update_volume_timeout_source = 0;
+ }
+
+ if (delayed_title_change_source)
+ {
+ g_source_remove (delayed_title_change_source);
+ delayed_title_change_source = 0;
+ }
+
+ ui_hooks_disassociate ();
+
+ if (search_tool)
+ aud_plugin_remove_watch (search_tool, search_tool_toggled, nullptr);
+
+ gtk_widget_destroy (window);
+ layout_cleanup ();
+
+ audgui_cleanup ();
+}
+
+static void menu_position_cb (GtkMenu * menu, int * x, int * y, int * push, void * button)
+{
+ GtkAllocation alloc;
+ int xorig, yorig, xwin, ywin;
+
+ gtk_widget_get_allocation ((GtkWidget *) button, & alloc);
+ gdk_window_get_origin (gtk_widget_get_window (window), & xorig, & yorig);
+ gtk_widget_translate_coordinates ((GtkWidget *) button, window, 0, 0, & xwin, & ywin);
+
+ * x = xorig + xwin;
+ * y = yorig + ywin + alloc.height;
+ * push = true;
+}
+
+static void menu_button_cb ()
+{
+ if (gtk_toggle_tool_button_get_active ((GtkToggleToolButton *) menu_button))
+ gtk_menu_popup ((GtkMenu *) menu_main, nullptr, nullptr, menu_position_cb,
+ menu_button, 0, gtk_get_current_event_time ());
+ else
+ gtk_widget_hide (menu_main);
+}
+
+static void menu_hide_cb ()
+{
+ gtk_toggle_tool_button_set_active ((GtkToggleToolButton *) menu_button, false);
+}
+
+void show_hide_menu ()
+{
+ if (aud_get_bool ("gtkui", "menu_visible"))
+ {
+ /* remove menu button from toolbar and show menu bar */
+ if (menu_main)
+ gtk_widget_destroy (menu_main);
+ if (menu_button)
+ gtk_widget_destroy ((GtkWidget *) menu_button);
+
+ if (! menu)
+ {
+ menu = make_menu_bar (accel);
+ g_signal_connect (menu, "destroy", (GCallback) gtk_widget_destroyed,
+ & menu);
+ gtk_widget_show (menu);
+ gtk_box_pack_start ((GtkBox *) menu_box, menu, true, true, 0);
+ }
+ }
+ else
+ {
+ /* hide menu bar and add menu item to toolbar */
+ if (menu)
+ gtk_widget_destroy (menu);
+
+ if (! menu_main)
+ {
+ menu_main = make_menu_main (accel);
+ g_signal_connect (menu_main, "destroy", (GCallback)
+ gtk_widget_destroyed, & menu_main);
+ g_signal_connect (menu_main, "hide", (GCallback) menu_hide_cb, nullptr);
+ }
+
+ if (! menu_button)
+ {
+ menu_button = gtk_toggle_tool_button_new ();
+ gtk_tool_button_set_icon_name ((GtkToolButton *) menu_button, "audacious");
+ g_signal_connect (menu_button, "destroy", (GCallback)
+ gtk_widget_destroyed, & menu_button);
+ gtk_widget_show ((GtkWidget *) menu_button);
+ gtk_toolbar_insert ((GtkToolbar *) toolbar, menu_button, 0);
+ g_signal_connect (menu_button, "toggled", (GCallback) menu_button_cb, nullptr);
+ }
+ }
+}
+
+void show_hide_infoarea ()
+{
+ bool show = aud_get_bool ("gtkui", "infoarea_visible");
+
+ if (show && ! infoarea)
+ {
+ infoarea = ui_infoarea_new ();
+ g_signal_connect (infoarea, "destroy", (GCallback) gtk_widget_destroyed, & infoarea);
+ gtk_box_pack_end ((GtkBox *) vbox, infoarea, false, false, 0);
+ gtk_widget_show_all (infoarea);
+
+ show_hide_infoarea_vis ();
+ }
+
+ if (! show && infoarea)
+ {
+ gtk_widget_destroy (infoarea);
+ infoarea = nullptr;
+ }
+}
+
+void show_hide_infoarea_vis ()
+{
+ /* only turn on visualization if interface is shown */
+ ui_infoarea_show_vis (gtk_widget_get_visible (window) && aud_get_bool
+ ("gtkui", "infoarea_show_vis"));
+}
+
+void show_hide_statusbar ()
+{
+ bool show = aud_get_bool ("gtkui", "statusbar_visible");
+
+ if (show && ! statusbar)
+ {
+ statusbar = ui_statusbar_new ();
+ g_signal_connect (statusbar, "destroy", (GCallback) gtk_widget_destroyed, & statusbar);
+ gtk_box_pack_end ((GtkBox *) vbox_outer, statusbar, false, false, 0);
+ gtk_widget_show_all (statusbar);
+ }
+
+ if (! show && statusbar)
+ {
+ gtk_widget_destroy (statusbar);
+ statusbar = nullptr;
+ }
+}
+
+void popup_menu_rclick (unsigned button, uint32_t time)
+{
+ gtk_menu_popup ((GtkMenu *) menu_rclick, nullptr, nullptr, nullptr, nullptr, button,
+ time);
+}
+
+void popup_menu_tab (unsigned button, uint32_t time, int playlist)
+{
+ menu_tab_playlist_id = aud_playlist_get_unique_id (playlist);
+ gtk_menu_popup ((GtkMenu *) menu_tab, nullptr, nullptr, nullptr, nullptr, button, time);
+}
+
+void activate_search_tool ()
+{
+ if (! search_tool)
+ return;
+
+ aud_plugin_enable (search_tool, true);
+ layout_focus (search_tool);
+}
+
+void activate_playlist_manager ()
+{
+ PluginHandle * manager = aud_plugin_lookup_basename ("playlist-manager");
+ if (! manager)
+ return;
+
+ aud_plugin_enable (manager, true);
+ layout_focus (manager);
+}
diff --git a/src/gtkui/ui_infoarea.c b/src/gtkui/ui_infoarea.c
deleted file mode 100644
index e92876f722ea..000000000000
--- a/src/gtkui/ui_infoarea.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- * ui_infoarea.c
- * Copyright 2010-2012 William Pitcock and John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <math.h>
-#include <string.h>
-
-#include <gtk/gtk.h>
-
-#include <audacious/drct.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "ui_infoarea.h"
-
-#define SPACING 8
-#define ICON_SIZE 64
-#define HEIGHT (ICON_SIZE + 2 * SPACING)
-
-#define VIS_BANDS 12
-#define VIS_WIDTH (8 * VIS_BANDS - 2)
-#define VIS_CENTER (ICON_SIZE * 5 / 8 + SPACING)
-#define VIS_DELAY 2 /* delay before falloff in frames */
-#define VIS_FALLOFF 2 /* falloff in pixels per frame */
-
-typedef struct {
- GtkWidget * box, * main;
-
- char * title, * artist, * album; /* pooled */
- char * last_title, * last_artist, * last_album; /* pooled */
- float alpha, last_alpha;
-
- bool_t stopped;
- int fade_timeout;
-
- GdkPixbuf * pb, * last_pb;
-} UIInfoArea;
-
-static struct {
- GtkWidget * widget;
- char bars[VIS_BANDS];
- char delay[VIS_BANDS];
-} vis;
-
-/****************************************************************************/
-
-static UIInfoArea * area = NULL;
-
-static void vis_render_cb (const float * freq)
-{
- /* xscale[i] = pow (256, i / VIS_BANDS) - 0.5; */
- const float xscale[VIS_BANDS + 1] = {0.5, 1.09, 2.02, 3.5, 5.85, 9.58,
- 15.5, 24.9, 39.82, 63.5, 101.09, 160.77, 255.5};
-
- for (int i = 0; i < VIS_BANDS; i ++)
- {
- int a = ceilf (xscale[i]);
- int b = floorf (xscale[i + 1]);
- float n = 0;
-
- if (b < a)
- n += freq[b] * (xscale[i + 1] - xscale[i]);
- else
- {
- if (a > 0)
- n += freq[a - 1] * (a - xscale[i]);
- for (; a < b; a ++)
- n += freq[a];
- if (b < 256)
- n += freq[b] * (xscale[i + 1] - b);
- }
-
- /* 40 dB range */
- int x = 40 + 20 * log10f (n);
- x = CLAMP (x, 0, 40);
-
- vis.bars[i] -= MAX (0, VIS_FALLOFF - vis.delay[i]);
-
- if (vis.delay[i])
- vis.delay[i] --;
-
- if (x > vis.bars[i])
- {
- vis.bars[i] = x;
- vis.delay[i] = VIS_DELAY;
- }
- }
-
- if (vis.widget)
- gtk_widget_queue_draw (vis.widget);
-}
-
-static void vis_clear_cb (void)
-{
- memset (vis.bars, 0, sizeof vis.bars);
- memset (vis.delay, 0, sizeof vis.delay);
-
- if (vis.widget)
- gtk_widget_queue_draw (vis.widget);
-}
-
-/****************************************************************************/
-
-static void clear (GtkWidget * widget, cairo_t * cr)
-{
- GtkAllocation alloc;
- gtk_widget_get_allocation (widget, & alloc);
-
- cairo_pattern_t * gradient = cairo_pattern_create_linear (0, 0, 0, alloc.height);
- cairo_pattern_add_color_stop_rgb (gradient, 0, 0.25, 0.25, 0.25);
- cairo_pattern_add_color_stop_rgb (gradient, 0.5, 0.15, 0.15, 0.15);
- cairo_pattern_add_color_stop_rgb (gradient, 0.5, 0.1, 0.1, 0.1);
- cairo_pattern_add_color_stop_rgb (gradient, 1, 0, 0, 0);
-
- cairo_set_source (cr, gradient);
- cairo_rectangle (cr, 0, 0, alloc.width, alloc.height);
- cairo_fill (cr);
-
- cairo_pattern_destroy (gradient);
-}
-
-static void draw_text (GtkWidget * widget, cairo_t * cr, int x, int y, int
- width, float r, float g, float b, float a, const char * font,
- const char * text)
-{
- cairo_move_to(cr, x, y);
- cairo_set_operator(cr, CAIRO_OPERATOR_ATOP);
- cairo_set_source_rgba(cr, r, g, b, a);
-
- PangoFontDescription * desc = pango_font_description_from_string (font);
- PangoLayout * pl = gtk_widget_create_pango_layout (widget, NULL);
- pango_layout_set_text (pl, text, -1);
- pango_layout_set_font_description(pl, desc);
- pango_font_description_free(desc);
- pango_layout_set_width (pl, width * PANGO_SCALE);
- pango_layout_set_ellipsize (pl, PANGO_ELLIPSIZE_END);
-
- pango_cairo_show_layout(cr, pl);
-
- g_object_unref(pl);
-}
-
-/****************************************************************************/
-
-static void rgb_to_hsv (float r, float g, float b, float * h, float * s,
- float * v)
-{
- float max, min;
-
- max = r;
- if (g > max)
- max = g;
- if (b > max)
- max = b;
-
- min = r;
- if (g < min)
- min = g;
- if (b < min)
- min = b;
-
- * v = max;
-
- if (max == min)
- {
- * h = 0;
- * s = 0;
- return;
- }
-
- if (r == max)
- * h = 1 + (g - b) / (max - min);
- else if (g == max)
- * h = 3 + (b - r) / (max - min);
- else
- * h = 5 + (r - g) / (max - min);
-
- * s = (max - min) / max;
-}
-
-static void hsv_to_rgb (float h, float s, float v, float * r, float * g,
- float * b)
-{
- for (; h >= 2; h -= 2)
- {
- float * p = r;
- r = g;
- g = b;
- b = p;
- }
-
- if (h < 1)
- {
- * r = 1;
- * g = 0;
- * b = 1 - h;
- }
- else
- {
- * r = 1;
- * g = h - 1;
- * b = 0;
- }
-
- * r = v * (1 - s * (1 - * r));
- * g = v * (1 - s * (1 - * g));
- * b = v * (1 - s * (1 - * b));
-}
-
-static void get_color (int i, float * r, float * g, float * b)
-{
- static GdkRGBA c;
- static bool_t valid = FALSE;
-
- if (! valid)
- {
- /* we want a color that matches the current theme
- * selected color of a GtkEntry should be reasonable */
- GtkStyleContext * style = gtk_style_context_new ();
- GtkWidgetPath * path = gtk_widget_path_new ();
- gtk_widget_path_append_type (path, GTK_TYPE_ENTRY);
- gtk_style_context_set_path (style, path);
- gtk_widget_path_free (path);
- gtk_style_context_get_background_color (style, GTK_STATE_FLAG_SELECTED, & c);
- g_object_unref (style);
- valid = TRUE;
- }
-
- float h, s, v;
- rgb_to_hsv (c.red, c.green, c.blue, & h, & s, & v);
-
- if (s < 0.1) /* monochrome theme? use blue instead */
- {
- h = 5;
- s = 0.75;
- }
-
- s = 1 - 0.9 * i / (VIS_BANDS - 1);
- v = 0.75 + 0.25 * i / (VIS_BANDS - 1);
-
- hsv_to_rgb (h, s, v, r, g, b);
-}
-
-static bool_t draw_vis_cb (GtkWidget * widget, cairo_t * cr)
-{
- clear (widget, cr);
-
- for (int i = 0; i < VIS_BANDS; i++)
- {
- int x = SPACING + 8 * i;
- int t = VIS_CENTER - vis.bars[i];
- int m = MIN (VIS_CENTER + vis.bars[i], HEIGHT);
-
- float r, g, b;
- get_color (i, & r, & g, & b);
-
- cairo_set_source_rgb (cr, r, g, b);
- cairo_rectangle (cr, x, t, 6, VIS_CENTER - t);
- cairo_fill (cr);
-
- cairo_set_source_rgb (cr, r * 0.3, g * 0.3, b * 0.3);
- cairo_rectangle (cr, x, VIS_CENTER, 6, m - VIS_CENTER);
- cairo_fill (cr);
- }
-
- return TRUE;
-}
-
-static void draw_album_art (cairo_t * cr)
-{
- g_return_if_fail (area);
-
- if (area->pb != NULL)
- {
- gdk_cairo_set_source_pixbuf (cr, area->pb, SPACING, SPACING);
- cairo_paint_with_alpha (cr, area->alpha);
- }
-
- if (area->last_pb != NULL)
- {
- gdk_cairo_set_source_pixbuf (cr, area->last_pb, SPACING, SPACING);
- cairo_paint_with_alpha (cr, area->last_alpha);
- }
-}
-
-static void draw_title (cairo_t * cr)
-{
- g_return_if_fail (area);
-
- GtkAllocation alloc;
- gtk_widget_get_allocation (area->main, & alloc);
-
- int x = ICON_SIZE + SPACING * 2;
- int width = alloc.width - x;
-
- if (area->title != NULL)
- draw_text (area->main, cr, x, SPACING, width, 1, 1, 1, area->alpha,
- "18", area->title);
- if (area->last_title != NULL)
- draw_text (area->main, cr, x, SPACING, width, 1, 1, 1, area->last_alpha,
- "18", area->last_title);
- if (area->artist != NULL)
- draw_text (area->main, cr, x, SPACING + ICON_SIZE / 2, width, 1, 1, 1,
- area->alpha, "9", area->artist);
- if (area->last_artist != NULL)
- draw_text (area->main, cr, x, SPACING + ICON_SIZE / 2, width, 1, 1, 1,
- area->last_alpha, "9", area->last_artist);
- if (area->album != NULL)
- draw_text (area->main, cr, x, SPACING + ICON_SIZE * 3 / 4, width, 0.7,
- 0.7, 0.7, area->alpha, "9", area->album);
- if (area->last_album != NULL)
- draw_text (area->main, cr, x, SPACING + ICON_SIZE * 3 / 4, width, 0.7,
- 0.7, 0.7, area->last_alpha, "9", area->last_album);
-}
-
-static bool_t draw_cb (GtkWidget * widget, cairo_t * cr)
-{
- g_return_val_if_fail (area, FALSE);
-
- clear (widget, cr);
-
- draw_album_art (cr);
- draw_title (cr);
-
- return TRUE;
-}
-
-static bool_t ui_infoarea_do_fade (void)
-{
- g_return_val_if_fail (area, FALSE);
- bool_t ret = FALSE;
-
- if (aud_drct_get_playing () && area->alpha < 1)
- {
- area->alpha += 0.1;
- ret = TRUE;
- }
-
- if (area->last_alpha > 0)
- {
- area->last_alpha -= 0.1;
- ret = TRUE;
- }
-
- gtk_widget_queue_draw (area->main);
-
- if (! ret)
- area->fade_timeout = 0;
-
- return ret;
-}
-
-static void ui_infoarea_set_title (void)
-{
- g_return_if_fail (area);
-
- if (! aud_drct_get_playing ())
- return;
-
- int playlist = aud_playlist_get_playing ();
- int entry = aud_playlist_get_position (playlist);
-
- char * title, * artist, * album;
- aud_playlist_entry_describe (playlist, entry, & title, & artist, & album, TRUE);
-
- if (! g_strcmp0 (title, area->title) && ! g_strcmp0 (artist, area->artist)
- && ! g_strcmp0 (album, area->album))
- {
- str_unref (title);
- str_unref (artist);
- str_unref (album);
- return;
- }
-
- str_unref (area->title);
- str_unref (area->artist);
- str_unref (area->album);
- area->title = title;
- area->artist = artist;
- area->album = album;
-
- gtk_widget_queue_draw (area->main);
-}
-
-static void set_album_art (void)
-{
- g_return_if_fail (area);
-
- if (area->pb)
- g_object_unref (area->pb);
-
- area->pb = audgui_pixbuf_request_current ();
- if (! area->pb)
- area->pb = audgui_pixbuf_fallback ();
- if (area->pb)
- audgui_pixbuf_scale_within (& area->pb, ICON_SIZE);
-}
-
-static void album_art_ready (void)
-{
- g_return_if_fail (area);
-
- if (! aud_drct_get_playing ())
- return;
-
- set_album_art ();
- gtk_widget_queue_draw (area->main);
-}
-
-static void infoarea_next (void)
-{
- g_return_if_fail (area);
-
- if (area->last_pb)
- g_object_unref (area->last_pb);
- area->last_pb = area->pb;
- area->pb = NULL;
-
- str_unref (area->last_title);
- area->last_title = area->title;
- area->title = NULL;
-
- str_unref (area->last_artist);
- area->last_artist = area->artist;
- area->artist = NULL;
-
- str_unref (area->last_album);
- area->last_album = area->album;
- area->album = NULL;
-
- area->last_alpha = area->alpha;
- area->alpha = 0;
-
- gtk_widget_queue_draw (area->main);
-}
-
-static void ui_infoarea_playback_start (void)
-{
- g_return_if_fail (area);
-
- if (! area->stopped) /* moved to the next song without stopping? */
- infoarea_next ();
- area->stopped = FALSE;
-
- ui_infoarea_set_title ();
- set_album_art ();
-
- if (! area->fade_timeout)
- area->fade_timeout = g_timeout_add (30, (GSourceFunc)
- ui_infoarea_do_fade, area);
-}
-
-static void ui_infoarea_playback_stop (void)
-{
- g_return_if_fail (area);
-
- infoarea_next ();
- area->stopped = TRUE;
-
- if (! area->fade_timeout)
- area->fade_timeout = g_timeout_add (30, (GSourceFunc)
- ui_infoarea_do_fade, area);
-}
-
-static void realize_cb (GtkWidget * widget)
-{
- /* using a native window avoids redrawing parent widgets */
- gdk_window_ensure_native (gtk_widget_get_window (widget));
-}
-
-void ui_infoarea_show_vis (bool_t show)
-{
- if (! area)
- return;
-
- if (show)
- {
- if (vis.widget)
- return;
-
- vis.widget = gtk_drawing_area_new ();
-
- /* note: "realize" signal must be connected before adding to box */
- g_signal_connect (vis.widget, "realize", (GCallback) realize_cb, NULL);
-
- gtk_widget_set_size_request (vis.widget, VIS_WIDTH + 2 * SPACING, HEIGHT);
- gtk_box_pack_start ((GtkBox *) area->box, vis.widget, FALSE, FALSE, 0);
-
- g_signal_connect (vis.widget, "draw", (GCallback) draw_vis_cb, NULL);
- gtk_widget_show (vis.widget);
-
- aud_vis_func_add (AUD_VIS_TYPE_CLEAR, (VisFunc) vis_clear_cb);
- aud_vis_func_add (AUD_VIS_TYPE_FREQ, (VisFunc) vis_render_cb);
- }
- else
- {
- if (! vis.widget)
- return;
-
- aud_vis_func_remove ((VisFunc) vis_clear_cb);
- aud_vis_func_remove ((VisFunc) vis_render_cb);
-
- gtk_widget_destroy (vis.widget);
-
- memset (& vis, 0, sizeof vis);
- }
-}
-
-static void destroy_cb (GtkWidget * widget)
-{
- g_return_if_fail (area);
-
- ui_infoarea_show_vis (FALSE);
-
- hook_dissociate ("playlist update", (HookFunction) ui_infoarea_set_title);
- hook_dissociate ("playback begin", (HookFunction) ui_infoarea_playback_start);
- hook_dissociate ("playback stop", (HookFunction) ui_infoarea_playback_stop);
- hook_dissociate ("current art ready", (HookFunction) album_art_ready);
-
- if (area->fade_timeout)
- {
- g_source_remove (area->fade_timeout);
- area->fade_timeout = 0;
- }
-
- str_unref (area->title);
- str_unref (area->artist);
- str_unref (area->album);
- str_unref (area->last_title);
- str_unref (area->last_artist);
- str_unref (area->last_album);
-
- if (area->pb)
- g_object_unref (area->pb);
- if (area->last_pb)
- g_object_unref (area->last_pb);
-
- g_slice_free (UIInfoArea, area);
- area = NULL;
-}
-
-GtkWidget * ui_infoarea_new (void)
-{
- g_return_val_if_fail (! area, NULL);
- area = g_slice_new0 (UIInfoArea);
-
- area->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-
- area->main = gtk_drawing_area_new ();
- gtk_widget_set_size_request (area->main, ICON_SIZE + 2 * SPACING, HEIGHT);
- gtk_box_pack_start ((GtkBox *) area->box, area->main, TRUE, TRUE, 0);
-
- g_signal_connect (area->main, "draw", (GCallback) draw_cb, NULL);
-
- hook_associate ("playlist update", (HookFunction) ui_infoarea_set_title, NULL);
- hook_associate ("playback begin", (HookFunction) ui_infoarea_playback_start, NULL);
- hook_associate ("playback stop", (HookFunction) ui_infoarea_playback_stop, NULL);
- hook_associate ("current art ready", (HookFunction) album_art_ready, NULL);
-
- g_signal_connect (area->box, "destroy", (GCallback) destroy_cb, NULL);
-
- if (aud_drct_get_playing ())
- {
- ui_infoarea_playback_start ();
-
- /* skip fade-in */
- area->alpha = 1;
-
- if (area->fade_timeout)
- {
- g_source_remove (area->fade_timeout);
- area->fade_timeout = 0;
- }
- }
-
- GtkWidget * frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type ((GtkFrame *) frame, GTK_SHADOW_IN);
- gtk_container_add ((GtkContainer *) frame, area->box);
- return frame;
-}
diff --git a/src/gtkui/ui_infoarea.cc b/src/gtkui/ui_infoarea.cc
new file mode 100644
index 000000000000..d3c9bc880d28
--- /dev/null
+++ b/src/gtkui/ui_infoarea.cc
@@ -0,0 +1,566 @@
+/*
+ * ui_infoarea.c
+ * Copyright 2010-2012 William Pitcock and John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <math.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/interface.h>
+#include <libaudgui/libaudgui-gtk.h>
+
+#include "ui_infoarea.h"
+
+#define SPACING 8
+#define ICON_SIZE 64
+#define HEIGHT (ICON_SIZE + 2 * SPACING)
+
+#define VIS_BANDS 12
+#define VIS_WIDTH (8 * VIS_BANDS - 2)
+#define VIS_CENTER (ICON_SIZE * 5 / 8 + SPACING)
+#define VIS_DELAY 2 /* delay before falloff in frames */
+#define VIS_FALLOFF 2 /* falloff in pixels per frame */
+
+typedef struct {
+ GtkWidget * box, * main;
+
+ String title, artist, album;
+ String last_title, last_artist, last_album;
+ float alpha, last_alpha;
+
+ bool stopped;
+ int fade_timeout;
+
+ GdkPixbuf * pb, * last_pb;
+} UIInfoArea;
+
+class InfoAreaVis : public Visualizer
+{
+public:
+ constexpr InfoAreaVis () :
+ Visualizer (Freq) {}
+
+ GtkWidget * widget = nullptr;
+ char bars[VIS_BANDS] {};
+ char delay[VIS_BANDS] {};
+
+ void clear ();
+ void render_freq (const float * freq);
+};
+
+static InfoAreaVis vis;
+
+/****************************************************************************/
+
+static UIInfoArea * area = nullptr;
+
+void InfoAreaVis::render_freq (const float * freq)
+{
+ /* xscale[i] = pow (256, i / VIS_BANDS) - 0.5; */
+ const float xscale[VIS_BANDS + 1] = {0.5, 1.09, 2.02, 3.5, 5.85, 9.58,
+ 15.5, 24.9, 39.82, 63.5, 101.09, 160.77, 255.5};
+
+ for (int i = 0; i < VIS_BANDS; i ++)
+ {
+ int a = ceilf (xscale[i]);
+ int b = floorf (xscale[i + 1]);
+ float n = 0;
+
+ if (b < a)
+ n += freq[b] * (xscale[i + 1] - xscale[i]);
+ else
+ {
+ if (a > 0)
+ n += freq[a - 1] * (a - xscale[i]);
+ for (; a < b; a ++)
+ n += freq[a];
+ if (b < 256)
+ n += freq[b] * (xscale[i + 1] - b);
+ }
+
+ /* 40 dB range */
+ int x = 40 + 20 * log10f (n);
+ x = aud::clamp (x, 0, 40);
+
+ bars[i] -= aud::max (0, VIS_FALLOFF - delay[i]);
+
+ if (delay[i])
+ delay[i] --;
+
+ if (x > bars[i])
+ {
+ bars[i] = x;
+ delay[i] = VIS_DELAY;
+ }
+ }
+
+ if (widget)
+ gtk_widget_queue_draw (widget);
+}
+
+void InfoAreaVis::clear ()
+{
+ memset (bars, 0, sizeof bars);
+ memset (delay, 0, sizeof delay);
+
+ if (widget)
+ gtk_widget_queue_draw (widget);
+}
+
+/****************************************************************************/
+
+static void clear (GtkWidget * widget, cairo_t * cr)
+{
+ GtkAllocation alloc;
+ gtk_widget_get_allocation (widget, & alloc);
+
+ cairo_pattern_t * gradient = cairo_pattern_create_linear (0, 0, 0, alloc.height);
+ cairo_pattern_add_color_stop_rgb (gradient, 0, 0.25, 0.25, 0.25);
+ cairo_pattern_add_color_stop_rgb (gradient, 0.5, 0.15, 0.15, 0.15);
+ cairo_pattern_add_color_stop_rgb (gradient, 0.5, 0.1, 0.1, 0.1);
+ cairo_pattern_add_color_stop_rgb (gradient, 1, 0, 0, 0);
+
+ cairo_set_source (cr, gradient);
+ cairo_rectangle (cr, 0, 0, alloc.width, alloc.height);
+ cairo_fill (cr);
+
+ cairo_pattern_destroy (gradient);
+}
+
+static void draw_text (GtkWidget * widget, cairo_t * cr, int x, int y, int
+ width, float r, float g, float b, float a, const char * font,
+ const char * text)
+{
+ cairo_move_to (cr, x, y);
+ cairo_set_source_rgba (cr, r, g, b, a);
+
+ PangoFontDescription * desc = pango_font_description_from_string (font);
+ PangoLayout * pl = gtk_widget_create_pango_layout (widget, nullptr);
+ pango_layout_set_text (pl, text, -1);
+ pango_layout_set_font_description (pl, desc);
+ pango_font_description_free (desc);
+ pango_layout_set_width (pl, width * PANGO_SCALE);
+ pango_layout_set_ellipsize (pl, PANGO_ELLIPSIZE_END);
+
+ pango_cairo_show_layout (cr, pl);
+
+ g_object_unref (pl);
+}
+
+/****************************************************************************/
+
+static void rgb_to_hsv (float r, float g, float b, float * h, float * s,
+ float * v)
+{
+ float max, min;
+
+ max = r;
+ if (g > max)
+ max = g;
+ if (b > max)
+ max = b;
+
+ min = r;
+ if (g < min)
+ min = g;
+ if (b < min)
+ min = b;
+
+ * v = max;
+
+ if (max == min)
+ {
+ * h = 0;
+ * s = 0;
+ return;
+ }
+
+ if (r == max)
+ * h = 1 + (g - b) / (max - min);
+ else if (g == max)
+ * h = 3 + (b - r) / (max - min);
+ else
+ * h = 5 + (r - g) / (max - min);
+
+ * s = (max - min) / max;
+}
+
+static void hsv_to_rgb (float h, float s, float v, float * r, float * g,
+ float * b)
+{
+ for (; h >= 2; h -= 2)
+ {
+ float * p = r;
+ r = g;
+ g = b;
+ b = p;
+ }
+
+ if (h < 1)
+ {
+ * r = 1;
+ * g = 0;
+ * b = 1 - h;
+ }
+ else
+ {
+ * r = 1;
+ * g = h - 1;
+ * b = 0;
+ }
+
+ * r = v * (1 - s * (1 - * r));
+ * g = v * (1 - s * (1 - * g));
+ * b = v * (1 - s * (1 - * b));
+}
+
+static void get_color (GtkWidget * widget, int i, float * r, float * g, float * b)
+{
+ GdkColor * c = (gtk_widget_get_style (widget))->base + GTK_STATE_SELECTED;
+ float h, s, v;
+
+ rgb_to_hsv (c->red / 65535.0, c->green / 65535.0, c->blue / 65535.0, & h, & s, & v);
+
+ if (s < 0.1) /* monochrome theme? use blue instead */
+ {
+ h = 5;
+ s = 0.75;
+ }
+
+ s = 1 - 0.9 * i / (VIS_BANDS - 1);
+ v = 0.75 + 0.25 * i / (VIS_BANDS - 1);
+
+ hsv_to_rgb (h, s, v, r, g, b);
+}
+
+static int expose_vis_cb (GtkWidget * widget, GdkEventExpose * event)
+{
+ cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (widget));
+
+ clear (widget, cr);
+
+ for (int i = 0; i < VIS_BANDS; i++)
+ {
+ int x = SPACING + 8 * i;
+ int t = VIS_CENTER - vis.bars[i];
+ int m = aud::min (VIS_CENTER + vis.bars[i], HEIGHT);
+
+ float r, g, b;
+ get_color (widget, i, & r, & g, & b);
+
+ cairo_set_source_rgb (cr, r, g, b);
+ cairo_rectangle (cr, x, t, 6, VIS_CENTER - t);
+ cairo_fill (cr);
+
+ cairo_set_source_rgb (cr, r * 0.3, g * 0.3, b * 0.3);
+ cairo_rectangle (cr, x, VIS_CENTER, 6, m - VIS_CENTER);
+ cairo_fill (cr);
+ }
+
+ cairo_destroy (cr);
+ return true;
+}
+
+static void draw_album_art (cairo_t * cr)
+{
+ g_return_if_fail (area);
+
+ if (area->pb)
+ {
+ gdk_cairo_set_source_pixbuf (cr, area->pb, SPACING, SPACING);
+ cairo_paint_with_alpha (cr, area->alpha);
+ }
+
+ if (area->last_pb)
+ {
+ gdk_cairo_set_source_pixbuf (cr, area->last_pb, SPACING, SPACING);
+ cairo_paint_with_alpha (cr, area->last_alpha);
+ }
+}
+
+static void draw_title (cairo_t * cr)
+{
+ g_return_if_fail (area);
+
+ GtkAllocation alloc;
+ gtk_widget_get_allocation (area->main, & alloc);
+
+ int x = ICON_SIZE + SPACING * 2;
+ int width = alloc.width - x;
+
+ if (area->title)
+ draw_text (area->main, cr, x, SPACING, width, 1, 1, 1, area->alpha,
+ "18", area->title);
+ if (area->last_title)
+ draw_text (area->main, cr, x, SPACING, width, 1, 1, 1, area->last_alpha,
+ "18", area->last_title);
+ if (area->artist)
+ draw_text (area->main, cr, x, SPACING + ICON_SIZE / 2, width, 1, 1, 1,
+ area->alpha, "9", area->artist);
+ if (area->last_artist)
+ draw_text (area->main, cr, x, SPACING + ICON_SIZE / 2, width, 1, 1, 1,
+ area->last_alpha, "9", area->last_artist);
+ if (area->album)
+ draw_text (area->main, cr, x, SPACING + ICON_SIZE * 3 / 4, width, 0.7,
+ 0.7, 0.7, area->alpha, "9", area->album);
+ if (area->last_album)
+ draw_text (area->main, cr, x, SPACING + ICON_SIZE * 3 / 4, width, 0.7,
+ 0.7, 0.7, area->last_alpha, "9", area->last_album);
+}
+
+static int expose_cb (GtkWidget * widget, GdkEventExpose * event)
+{
+ cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (widget));
+
+ clear (widget, cr);
+
+ draw_album_art (cr);
+ draw_title (cr);
+
+ cairo_destroy (cr);
+ return true;
+}
+
+static gboolean ui_infoarea_do_fade ()
+{
+ g_return_val_if_fail (area, false);
+ gboolean ret = false;
+
+ if (aud_drct_get_playing () && area->alpha < 1)
+ {
+ area->alpha += 0.1;
+ ret = true;
+ }
+
+ if (area->last_alpha > 0)
+ {
+ area->last_alpha -= 0.1;
+ ret = true;
+ }
+
+ gtk_widget_queue_draw (area->main);
+
+ if (! ret)
+ area->fade_timeout = 0;
+
+ return ret;
+}
+
+static void ui_infoarea_set_title ()
+{
+ g_return_if_fail (area);
+
+ Tuple tuple = aud_drct_get_tuple ();
+ String title = tuple.get_str (Tuple::Title);
+ String artist = tuple.get_str (Tuple::Artist);
+ String album = tuple.get_str (Tuple::Album);
+
+ if (! g_strcmp0 (title, area->title) && ! g_strcmp0 (artist, area->artist)
+ && ! g_strcmp0 (album, area->album))
+ return;
+
+ area->title = std::move (title);
+ area->artist = std::move (artist);
+ area->album = std::move (album);
+
+ gtk_widget_queue_draw (area->main);
+}
+
+static void set_album_art ()
+{
+ g_return_if_fail (area);
+
+ if (area->pb)
+ g_object_unref (area->pb);
+
+ area->pb = audgui_pixbuf_request_current ();
+ if (! area->pb)
+ area->pb = audgui_pixbuf_fallback ();
+ if (area->pb)
+ audgui_pixbuf_scale_within (& area->pb, ICON_SIZE);
+}
+
+static void album_art_ready ()
+{
+ g_return_if_fail (area);
+
+ if (! aud_drct_get_playing ())
+ return;
+
+ set_album_art ();
+ gtk_widget_queue_draw (area->main);
+}
+
+static void infoarea_next ()
+{
+ g_return_if_fail (area);
+
+ if (area->last_pb)
+ g_object_unref (area->last_pb);
+ area->last_pb = area->pb;
+ area->pb = nullptr;
+
+ area->last_title = std::move (area->title);
+ area->last_artist = std::move (area->artist);
+ area->last_album = std::move (area->album);
+
+ area->last_alpha = area->alpha;
+ area->alpha = 0;
+
+ gtk_widget_queue_draw (area->main);
+}
+
+static void ui_infoarea_playback_start ()
+{
+ g_return_if_fail (area);
+
+ if (! area->stopped) /* moved to the next song without stopping? */
+ infoarea_next ();
+ area->stopped = false;
+
+ ui_infoarea_set_title ();
+ set_album_art ();
+
+ if (! area->fade_timeout)
+ area->fade_timeout = g_timeout_add (30, (GSourceFunc)
+ ui_infoarea_do_fade, area);
+}
+
+static void ui_infoarea_playback_stop ()
+{
+ g_return_if_fail (area);
+
+ infoarea_next ();
+ area->stopped = true;
+
+ if (! area->fade_timeout)
+ area->fade_timeout = g_timeout_add (30, (GSourceFunc)
+ ui_infoarea_do_fade, area);
+}
+
+static void realize_cb (GtkWidget * widget)
+{
+ /* using a native window avoids redrawing parent widgets */
+ gdk_window_ensure_native (gtk_widget_get_window (widget));
+}
+
+void ui_infoarea_show_vis (bool show)
+{
+ if (! area)
+ return;
+
+ if (show)
+ {
+ if (vis.widget)
+ return;
+
+ vis.widget = gtk_drawing_area_new ();
+
+ /* note: "realize" signal must be connected before adding to box */
+ g_signal_connect (vis.widget, "realize", (GCallback) realize_cb, nullptr);
+
+ gtk_widget_set_size_request (vis.widget, VIS_WIDTH + 2 * SPACING, HEIGHT);
+ gtk_box_pack_start ((GtkBox *) area->box, vis.widget, false, false, 0);
+
+ g_signal_connect (vis.widget, "expose-event", (GCallback) expose_vis_cb, nullptr);
+ gtk_widget_show (vis.widget);
+
+ aud_visualizer_add (& vis);
+ }
+ else
+ {
+ if (! vis.widget)
+ return;
+
+ aud_visualizer_remove (& vis);
+
+ gtk_widget_destroy (vis.widget);
+ vis.widget = nullptr;
+
+ vis.clear ();
+ }
+}
+
+static void destroy_cb (GtkWidget * widget)
+{
+ g_return_if_fail (area);
+
+ ui_infoarea_show_vis (false);
+
+ hook_dissociate ("tuple change", (HookFunction) ui_infoarea_set_title);
+ hook_dissociate ("playback ready", (HookFunction) ui_infoarea_playback_start);
+ hook_dissociate ("playback stop", (HookFunction) ui_infoarea_playback_stop);
+ hook_dissociate ("current art ready", (HookFunction) album_art_ready);
+
+ if (area->fade_timeout)
+ {
+ g_source_remove (area->fade_timeout);
+ area->fade_timeout = 0;
+ }
+
+ if (area->pb)
+ g_object_unref (area->pb);
+ if (area->last_pb)
+ g_object_unref (area->last_pb);
+
+ delete area;
+ area = nullptr;
+}
+
+GtkWidget * ui_infoarea_new ()
+{
+ g_return_val_if_fail (! area, nullptr);
+ area = new UIInfoArea ();
+
+ area->box = gtk_hbox_new (false, 0);
+
+ area->main = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (area->main, ICON_SIZE + 2 * SPACING, HEIGHT);
+ gtk_box_pack_start ((GtkBox *) area->box, area->main, true, true, 0);
+
+ g_signal_connect (area->main, "expose-event", (GCallback) expose_cb, nullptr);
+
+ hook_associate ("tuple change", (HookFunction) ui_infoarea_set_title, nullptr);
+ hook_associate ("playback ready", (HookFunction) ui_infoarea_playback_start, nullptr);
+ hook_associate ("playback stop", (HookFunction) ui_infoarea_playback_stop, nullptr);
+ hook_associate ("current art ready", (HookFunction) album_art_ready, nullptr);
+
+ g_signal_connect (area->box, "destroy", (GCallback) destroy_cb, nullptr);
+
+ if (aud_drct_get_ready ())
+ {
+ ui_infoarea_playback_start ();
+
+ /* skip fade-in */
+ area->alpha = 1;
+
+ if (area->fade_timeout)
+ {
+ g_source_remove (area->fade_timeout);
+ area->fade_timeout = 0;
+ }
+ }
+
+ GtkWidget * frame = gtk_frame_new (nullptr);
+ gtk_frame_set_shadow_type ((GtkFrame *) frame, GTK_SHADOW_IN);
+ gtk_container_add ((GtkContainer *) frame, area->box);
+ return frame;
+}
diff --git a/src/gtkui/ui_infoarea.h b/src/gtkui/ui_infoarea.h
index 55874716d1e1..2377455741bd 100644
--- a/src/gtkui/ui_infoarea.h
+++ b/src/gtkui/ui_infoarea.h
@@ -22,7 +22,7 @@
#include <gtk/gtk.h>
-GtkWidget * ui_infoarea_new (void);
-void ui_infoarea_show_vis (bool_t show);
+GtkWidget * ui_infoarea_new ();
+void ui_infoarea_show_vis (bool show);
#endif
diff --git a/src/gtkui/ui_playlist_notebook.c b/src/gtkui/ui_playlist_notebook.c
deleted file mode 100644
index f0bd92aa18e3..000000000000
--- a/src/gtkui/ui_playlist_notebook.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * ui_playlist_notebook.c
- * Copyright 2010-2012 MichaÅ Lipski and John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <stdlib.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-#include <audacious/debug.h>
-#include <audacious/drct.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/list.h>
-#include <libaudgui/libaudgui.h>
-
-#include "gtkui.h"
-#include "ui_playlist_notebook.h"
-#include "ui_playlist_widget.h"
-#include "playlist_util.h"
-
-static GtkWidget * notebook = NULL;
-static int highlighted = -1;
-
-static int switch_handler = 0;
-static int reorder_handler = 0;
-
-static void add_button_cb (GtkButton * button, void * unused)
-{
- aud_playlist_insert (-1);
- aud_playlist_set_active (aud_playlist_count () - 1);
-}
-
-static void make_add_button (GtkWidget * notebook)
-{
- GtkWidget * button = gtk_button_new ();
- gtk_button_set_relief ((GtkButton *) button, GTK_RELIEF_NONE);
- gtk_container_add ((GtkContainer *) button, gtk_image_new_from_icon_name
- ("list-add", GTK_ICON_SIZE_MENU));
- gtk_widget_set_can_focus (button, FALSE);
-
- g_signal_connect (button, "clicked", (GCallback) add_button_cb, NULL);
- gtk_widget_show_all (button);
-
- gtk_notebook_set_action_widget ((GtkNotebook *) notebook, button, GTK_PACK_END);
-}
-
-static void close_button_cb (GtkWidget * button, void * id)
-{
- audgui_confirm_playlist_delete (aud_playlist_by_unique_id (GPOINTER_TO_INT (id)));
-}
-
-static GtkWidget * make_close_button (GtkWidget * ebox, int list)
-{
- GtkWidget * button = gtk_button_new ();
- GtkWidget * image = gtk_image_new_from_icon_name ("window-close", GTK_ICON_SIZE_MENU);
- gtk_button_set_image ((GtkButton *) button, image);
- gtk_button_set_relief ((GtkButton *) button, GTK_RELIEF_NONE);
- gtk_button_set_focus_on_click ((GtkButton *) button, FALSE);
- gtk_widget_set_name (button, "gtkui-tab-close-button");
-
- g_signal_connect (button, "clicked", (GCallback) close_button_cb,
- GINT_TO_POINTER (aud_playlist_get_unique_id (list)));
-
- GtkCssProvider * provider = gtk_css_provider_new ();
- gtk_css_provider_load_from_data (provider,
- "#gtkui-tab-close-button {"
- " -GtkButton-default-border: 0;"
- " -GtkButton-default-outside-border: 0;"
- " -GtkButton-inner-border: 0;"
- " -GtkWidget-focus-padding: 0;"
- " -GtkWidget-focus-line-width: 0;"
- " margin: 0;"
- " padding: 0; }",
- -1, NULL);
-
- gtk_style_context_add_provider (gtk_widget_get_style_context (button),
- GTK_STYLE_PROVIDER (provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
- g_object_unref (provider);
-
- gtk_widget_show (button);
-
- return button;
-}
-
-GtkNotebook *ui_playlist_get_notebook(void)
-{
- return GTK_NOTEBOOK(notebook);
-}
-
-static void save_column_widths ()
-{
- int current = gtk_notebook_get_current_page ((GtkNotebook *) notebook);
- GtkWidget * treeview = playlist_get_treeview (current);
-
- char * widths, * expand;
- ui_playlist_widget_get_column_widths (treeview, & widths, & expand);
-
- aud_set_str ("gtkui", "column_widths", widths);
- aud_set_str ("gtkui", "column_expand", expand);
-
- str_unref (widths);
- str_unref (expand);
-}
-
-static void apply_column_widths (GtkWidget * treeview)
-{
- char * widths = aud_get_str ("gtkui", "column_widths");
- char * expand = aud_get_str ("gtkui", "column_expand");
-
- if (widths && widths[0] && expand && expand[0])
- ui_playlist_widget_set_column_widths (treeview, widths, expand);
-
- str_unref (widths);
- str_unref (expand);
-}
-
-static void tab_title_reset(GtkWidget *ebox)
-{
- GtkWidget *label = g_object_get_data(G_OBJECT(ebox), "label");
- GtkWidget *entry = g_object_get_data(G_OBJECT(ebox), "entry");
- gtk_widget_hide(entry);
- gtk_widget_show(label);
-}
-
-static void tab_title_save(GtkEntry *entry, void * ebox)
-{
- int id = GPOINTER_TO_INT (g_object_get_data ((GObject *) ebox, "playlist-id"));
- GtkWidget *label = g_object_get_data(G_OBJECT(ebox), "label");
-
- aud_playlist_set_title (aud_playlist_by_unique_id (id), gtk_entry_get_text (entry));
- gtk_widget_hide(GTK_WIDGET(entry));
- gtk_widget_show(label);
-}
-
-static bool_t tab_key_press_cb(GtkWidget *widget, GdkEventKey *event, void * user_data)
-{
- if (event->keyval == GDK_KEY_Escape)
- tab_title_reset(widget);
-
- return FALSE;
-}
-
-static bool_t tab_button_press_cb(GtkWidget *ebox, GdkEventButton *event, void * user_data)
-{
- int id = GPOINTER_TO_INT (g_object_get_data ((GObject *) ebox, "playlist-id"));
- int playlist = aud_playlist_by_unique_id (id);
-
- if (event->type == GDK_2BUTTON_PRESS && event->button == 1)
- aud_drct_play_playlist (playlist);
-
- if (event->type == GDK_BUTTON_PRESS && event->button == 2)
- audgui_confirm_playlist_delete (playlist);
-
- if (event->type == GDK_BUTTON_PRESS && event->button == 3)
- popup_menu_tab (event->button, event->time, playlist);
-
- return FALSE;
-}
-
-static bool_t scroll_cb (GtkWidget * widget, GdkEventScroll * event)
-{
- switch (event->direction)
- {
- case GDK_SCROLL_UP:
- case GDK_SCROLL_LEFT:
- aud_playlist_set_active (aud_playlist_get_active () - 1);
- return TRUE;
-
- case GDK_SCROLL_DOWN:
- case GDK_SCROLL_RIGHT:
- aud_playlist_set_active (aud_playlist_get_active () + 1);
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
-static void tab_changed (GtkNotebook * notebook, GtkWidget * page, int
- page_num, void * unused)
-{
- save_column_widths ();
- apply_column_widths (playlist_get_treeview (page_num));
-
- aud_playlist_set_active (page_num);
-}
-
-static void tab_reordered(GtkNotebook *notebook, GtkWidget *child, unsigned page_num, void * user_data)
-{
- GtkWidget * widget = g_object_get_data ((GObject *) child, "treeview");
- g_return_if_fail (widget);
- aud_playlist_reorder (ui_playlist_widget_get_playlist (widget), page_num, 1);
-}
-
-static GtkLabel *get_tab_label(int playlist)
-{
- GtkWidget *page = gtk_notebook_get_nth_page(UI_PLAYLIST_NOTEBOOK, playlist);
- GtkWidget *ebox = gtk_notebook_get_tab_label(UI_PLAYLIST_NOTEBOOK, page);
- return GTK_LABEL(g_object_get_data(G_OBJECT(ebox), "label"));
-}
-
-static void set_tab_label (int list, GtkLabel * label)
-{
- char * title = aud_playlist_get_title (list);
-
- if (aud_get_bool ("gtkui", "entry_count_visible"))
- {
- char * temp = str_printf ("%s (%d)", title, aud_playlist_entry_count (list));
- str_unref (title);
- title = temp;
- }
-
- if (list == aud_playlist_get_playing ())
- {
- char * markup = g_markup_printf_escaped ("<b>%s</b>", title);
- gtk_label_set_markup (label, markup);
- g_free (markup);
- }
- else
- gtk_label_set_text (label, title);
-
- str_unref (title);
-}
-
-void start_rename_playlist (int playlist)
-{
- if (! gtk_notebook_get_show_tabs ((GtkNotebook *) notebook))
- {
- audgui_show_playlist_rename (playlist);
- return;
- }
-
- GtkWidget * page = gtk_notebook_get_nth_page (UI_PLAYLIST_NOTEBOOK, playlist);
- GtkWidget * ebox = gtk_notebook_get_tab_label (UI_PLAYLIST_NOTEBOOK, page);
-
- GtkWidget *label = g_object_get_data(G_OBJECT(ebox), "label");
- GtkWidget *entry = g_object_get_data(G_OBJECT(ebox), "entry");
- gtk_widget_hide(label);
-
- char * title = aud_playlist_get_title (playlist);
- gtk_entry_set_text ((GtkEntry *) entry, title);
- str_unref (title);
- gtk_widget_grab_focus(entry);
- gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
- gtk_widget_show(entry);
-}
-
-void ui_playlist_notebook_create_tab(int playlist)
-{
- GtkWidget *scrollwin, *treeview;
- GtkWidget *label, *entry, *ebox, *hbox;
- GtkAdjustment *vscroll;
- int position = aud_playlist_get_position (playlist);
-
- scrollwin = gtk_scrolled_window_new(NULL, NULL);
- vscroll = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrollwin));
-
- treeview = ui_playlist_widget_new(playlist);
- apply_column_widths (treeview);
-
- g_object_set_data(G_OBJECT(scrollwin), "treeview", treeview);
-
- gtk_container_add(GTK_CONTAINER(scrollwin), treeview);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_widget_show_all(scrollwin);
-
- ebox = gtk_event_box_new();
- gtk_event_box_set_visible_window ((GtkEventBox *) ebox, FALSE);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
-
- label = gtk_label_new ("");
- set_tab_label (playlist, (GtkLabel *) label);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
- entry = gtk_entry_new();
- gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
- gtk_container_add(GTK_CONTAINER(ebox), hbox);
- gtk_widget_show_all(ebox);
- gtk_widget_hide(entry);
-
- GtkWidget * button = NULL;
-
- if (aud_get_bool ("gtkui", "close_button_visible"))
- {
- button = make_close_button (ebox, playlist);
- gtk_box_pack_end ((GtkBox *) hbox, button, FALSE, FALSE, 0);
- }
-
- g_object_set_data(G_OBJECT(ebox), "label", label);
- g_object_set_data(G_OBJECT(ebox), "entry", entry);
- g_object_set_data(G_OBJECT(ebox), "page", scrollwin);
-
- gtk_notebook_insert_page (UI_PLAYLIST_NOTEBOOK, scrollwin, ebox, playlist);
- gtk_notebook_set_tab_reorderable(UI_PLAYLIST_NOTEBOOK, scrollwin, TRUE);
-
- int id = aud_playlist_get_unique_id (playlist);
- g_object_set_data ((GObject *) ebox, "playlist-id", GINT_TO_POINTER (id));
- g_object_set_data ((GObject *) treeview, "playlist-id", GINT_TO_POINTER (id));
-
- if (position >= 0)
- {
- aud_playlist_select_all (playlist, FALSE);
- aud_playlist_entry_set_selected (playlist, position, TRUE);
- aud_playlist_set_focus (playlist, position);
- audgui_list_set_highlight (treeview, position);
- audgui_list_set_focus (treeview, position);
- }
-
- g_signal_connect(ebox, "button-press-event", G_CALLBACK(tab_button_press_cb), NULL);
- g_signal_connect(ebox, "key-press-event", G_CALLBACK(tab_key_press_cb), NULL);
- g_signal_connect(entry, "activate", G_CALLBACK(tab_title_save), ebox);
- g_signal_connect_swapped (vscroll, "value-changed",
- G_CALLBACK(ui_playlist_widget_scroll), treeview);
-
- /* we have to connect to "scroll-event" on the notebook, the tabs, AND the
- * close buttons (sigh) */
- gtk_widget_add_events (ebox, GDK_SCROLL_MASK);
- g_signal_connect (ebox, "scroll-event", (GCallback) scroll_cb, NULL);
-
- if (button)
- {
- gtk_widget_add_events (button, GDK_SCROLL_MASK);
- g_signal_connect (button, "scroll-event", (GCallback) scroll_cb, NULL);
- }
-}
-
-void ui_playlist_notebook_populate(void)
-{
- int playlists = aud_playlist_count();
- int count;
-
- for (count = 0; count < playlists; count++)
- ui_playlist_notebook_create_tab(count);
-
- gtk_notebook_set_current_page (UI_PLAYLIST_NOTEBOOK, aud_playlist_get_active ());
- highlighted = aud_playlist_get_unique_id (aud_playlist_get_playing ());
-
- if (! switch_handler)
- switch_handler = g_signal_connect (notebook, "switch-page", (GCallback)
- tab_changed, NULL);
- if (! reorder_handler)
- reorder_handler = g_signal_connect (notebook, "page-reordered",
- (GCallback) tab_reordered, NULL);
-
- gtk_widget_grab_focus (playlist_get_treeview (aud_playlist_get_active ()));
-}
-
-void ui_playlist_notebook_empty (void)
-{
- if (switch_handler)
- g_signal_handler_disconnect (notebook, switch_handler);
- switch_handler = 0;
- if (reorder_handler)
- g_signal_handler_disconnect (notebook, reorder_handler);
- reorder_handler = 0;
-
- int n_pages = gtk_notebook_get_n_pages ((GtkNotebook *) notebook);
- while (n_pages)
- gtk_notebook_remove_page ((GtkNotebook *) notebook, -- n_pages);
-}
-
-static void add_remove_pages (void)
-{
- g_signal_handlers_block_by_func (notebook, (void *) tab_changed, NULL);
- g_signal_handlers_block_by_func (notebook, (void *) tab_reordered, NULL);
-
- save_column_widths ();
-
- int lists = aud_playlist_count ();
- int pages = gtk_notebook_get_n_pages ((GtkNotebook *) notebook);
-
- /* scan through existing treeviews */
- for (int i = 0; i < pages; )
- {
- GtkWidget * page = gtk_notebook_get_nth_page ((GtkNotebook *) notebook, i);
- GtkWidget * tree = g_object_get_data ((GObject *) page, "treeview");
- int tree_id = GPOINTER_TO_INT (g_object_get_data ((GObject *) tree, "playlist-id"));
-
- /* do we have an orphaned treeview? */
- if (aud_playlist_by_unique_id (tree_id) < 0)
- {
- gtk_notebook_remove_page ((GtkNotebook *) notebook, i);
- pages --;
- continue;
- }
-
- /* do we have the right treeview? */
- int list_id = aud_playlist_get_unique_id (i);
-
- if (tree_id == list_id)
- {
- ui_playlist_widget_set_playlist (tree, i);
- i ++;
- continue;
- }
-
- /* look for the right treeview */
- int found = FALSE;
-
- for (int j = i + 1; j < pages; j ++)
- {
- page = gtk_notebook_get_nth_page ((GtkNotebook *) notebook, j);
- tree = g_object_get_data ((GObject *) page, "treeview");
- tree_id = GPOINTER_TO_INT (g_object_get_data ((GObject *) tree, "playlist-id"));
-
- /* found it? move it to the right place */
- if (tree_id == list_id)
- {
- gtk_notebook_reorder_child ((GtkNotebook *) notebook, page, i);
- found = TRUE;
- break;
- }
- }
-
- /* didn't find it? create it */
- if (! found)
- {
- ui_playlist_notebook_create_tab (i);
- pages ++;
- continue;
- }
- }
-
- /* create new treeviews */
- while (pages < lists)
- {
- ui_playlist_notebook_create_tab (pages);
- pages ++;
- }
-
- int active = aud_playlist_get_active ();
- apply_column_widths (playlist_get_treeview (active));
- gtk_notebook_set_current_page ((GtkNotebook *) notebook, active);
-
- show_hide_playlist_tabs ();
-
- g_signal_handlers_unblock_by_func (notebook, (void *) tab_changed, NULL);
- g_signal_handlers_unblock_by_func (notebook, (void *) tab_reordered, NULL);
-}
-
-void ui_playlist_notebook_update (void * data, void * user)
-{
- int global_level = GPOINTER_TO_INT (data);
-
- if (global_level == PLAYLIST_UPDATE_STRUCTURE)
- add_remove_pages ();
-
- int lists = aud_playlist_count ();
-
- for (int list = 0; list < lists; list ++)
- {
- if (global_level >= PLAYLIST_UPDATE_METADATA)
- set_tab_label (list, get_tab_label (list));
-
- GtkWidget * treeview = playlist_get_treeview (list);
-
- int at, count;
- int level = aud_playlist_updated_range (list, & at, & count);
-
- if (level)
- ui_playlist_widget_update (treeview, level, at, count);
-
- audgui_list_set_highlight (treeview, aud_playlist_get_position (list));
- }
-
- gtk_notebook_set_current_page ((GtkNotebook *) notebook, aud_playlist_get_active ());
-}
-
-void ui_playlist_notebook_position (void * data, void * user)
-{
- int list = GPOINTER_TO_INT (data);
- int row = aud_playlist_get_position (list);
-
- if (aud_get_bool ("gtkui", "autoscroll"))
- {
- aud_playlist_select_all (list, FALSE);
- aud_playlist_entry_set_selected (list, row, TRUE);
- aud_playlist_set_focus (list, row);
- }
-
- if (! aud_playlist_update_pending ())
- audgui_list_set_highlight (playlist_get_treeview (list), row);
-}
-
-void ui_playlist_notebook_activate (void * data, void * user)
-{
- if (! aud_playlist_update_pending ())
- gtk_notebook_set_current_page ((GtkNotebook *) notebook, aud_playlist_get_active ());
-}
-
-void ui_playlist_notebook_set_playing (void * data, void * user)
-{
- int new = aud_playlist_get_unique_id (aud_playlist_get_playing ());
-
- if (highlighted == new)
- return;
-
- int pages = gtk_notebook_get_n_pages ((GtkNotebook *) notebook);
-
- for (int i = 0; i < pages; i ++)
- {
- GtkWidget * page = gtk_notebook_get_nth_page ((GtkNotebook *) notebook, i);
- GtkWidget * tree = g_object_get_data ((GObject *) page, "treeview");
- int tree_id = GPOINTER_TO_INT (g_object_get_data ((GObject *) tree, "playlist-id"));
-
- if (tree_id == highlighted || tree_id == new)
- set_tab_label (i, get_tab_label (i));
- }
-
- highlighted = new;
-}
-
-static void destroy_cb (void)
-{
- hook_dissociate ("config save", (HookFunction) save_column_widths);
-
- notebook = NULL;
- switch_handler = 0;
- reorder_handler = 0;
-}
-
-GtkWidget * ui_playlist_notebook_new (void)
-{
- notebook = gtk_notebook_new ();
- gtk_notebook_set_scrollable ((GtkNotebook *) notebook, TRUE);
- make_add_button (notebook);
-
- show_hide_playlist_tabs ();
-
- hook_associate ("config save", (HookFunction) save_column_widths, NULL);
-
- gtk_widget_add_events (notebook, GDK_SCROLL_MASK);
- g_signal_connect (notebook, "scroll-event", (GCallback) scroll_cb, NULL);
- g_signal_connect (notebook, "destroy", (GCallback) destroy_cb, NULL);
-
- return notebook;
-}
-
-void show_hide_playlist_tabs (void)
-{
- gtk_notebook_set_show_tabs ((GtkNotebook *) notebook, aud_get_bool ("gtkui",
- "playlist_tabs_visible") || aud_playlist_count () > 1);
-}
diff --git a/src/gtkui/ui_playlist_notebook.cc b/src/gtkui/ui_playlist_notebook.cc
new file mode 100644
index 000000000000..dc919cbafaac
--- /dev/null
+++ b/src/gtkui/ui_playlist_notebook.cc
@@ -0,0 +1,573 @@
+/*
+ * ui_playlist_notebook.c
+ * Copyright 2010-2012 MichaÅ Lipski and John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <stdlib.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/runtime.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/hook.h>
+#include <libaudgui/list.h>
+#include <libaudgui/libaudgui.h>
+
+#include "gtkui.h"
+#include "ui_playlist_notebook.h"
+#include "ui_playlist_widget.h"
+#include "playlist_util.h"
+
+static GtkWidget * notebook = nullptr;
+static int highlighted = -1;
+
+static int switch_handler = 0;
+static int reorder_handler = 0;
+
+void apply_column_widths (GtkWidget * treeview)
+{
+ /* skip righthand column since it expands with the window */
+ for (int i = 0; i < pw_num_cols - 1; i ++)
+ {
+ GtkTreeViewColumn * col = gtk_tree_view_get_column ((GtkTreeView *) treeview, i);
+ gtk_tree_view_column_set_fixed_width (col, pw_col_widths[pw_cols[i]]);
+ }
+}
+
+static void size_allocate_cb (GtkWidget * treeview)
+{
+ int current = gtk_notebook_get_current_page ((GtkNotebook *) notebook);
+
+ if (current < 0 || treeview != playlist_get_treeview (current))
+ return;
+
+ bool changed = false;
+
+ /* skip righthand column since it expands with the window */
+ for (int i = 0; i < pw_num_cols - 1; i ++)
+ {
+ GtkTreeViewColumn * col = gtk_tree_view_get_column ((GtkTreeView *) treeview, i);
+ int width = gtk_tree_view_column_get_width (col);
+
+ if (width != pw_col_widths[pw_cols[i]])
+ {
+ pw_col_widths[pw_cols[i]] = width;
+ changed = true;
+ }
+ }
+
+ if (changed)
+ {
+ int count = gtk_notebook_get_n_pages ((GtkNotebook *) notebook);
+
+ for (int i = 0; i < count; i ++)
+ {
+ if (i != current)
+ apply_column_widths (playlist_get_treeview (i));
+ }
+ }
+}
+
+static void add_button_cb (GtkButton * button)
+{
+ aud_playlist_insert (-1);
+ aud_playlist_set_active (aud_playlist_count () - 1);
+}
+
+static void make_add_button (GtkWidget * notebook)
+{
+ GtkWidget * button = gtk_button_new ();
+ gtk_button_set_relief ((GtkButton *) button, GTK_RELIEF_NONE);
+ gtk_container_add ((GtkContainer *) button, gtk_image_new_from_icon_name
+ ("list-add", GTK_ICON_SIZE_MENU));
+ gtk_widget_set_can_focus (button, false);
+
+ g_signal_connect (button, "clicked", (GCallback) add_button_cb, nullptr);
+ gtk_widget_show_all (button);
+
+ gtk_notebook_set_action_widget ((GtkNotebook *) notebook, button, GTK_PACK_END);
+}
+
+static void close_button_cb (GtkWidget * button, void * id)
+{
+ audgui_confirm_playlist_delete (aud_playlist_by_unique_id (GPOINTER_TO_INT (id)));
+}
+
+static void close_button_style_set (GtkWidget * button)
+{
+ int w, h;
+ gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (button),
+ GTK_ICON_SIZE_MENU, & w, & h);
+ gtk_widget_set_size_request (button, w + 2, h + 2);
+}
+
+static GtkWidget * make_close_button (GtkWidget * ebox, int list)
+{
+ GtkWidget * button = gtk_button_new ();
+ GtkWidget * image = gtk_image_new_from_icon_name ("window-close", GTK_ICON_SIZE_MENU);
+ gtk_button_set_image ((GtkButton *) button, image);
+ gtk_button_set_relief ((GtkButton *) button, GTK_RELIEF_NONE);
+ gtk_button_set_focus_on_click ((GtkButton *) button, false);
+ gtk_widget_set_name (button, "gtkui-tab-close-button");
+
+ g_signal_connect (button, "clicked", (GCallback) close_button_cb,
+ GINT_TO_POINTER (aud_playlist_get_unique_id (list)));
+
+ gtk_rc_parse_string (
+ "style \"gtkui-tab-close-button-style\" {"
+ " GtkButton::default-border = {0, 0, 0, 0}"
+ " GtkButton::default-outside-border = {0, 0, 0, 0}"
+ " GtkButton::inner-border = {0, 0, 0, 0}"
+ " GtkWidget::focus-padding = 0"
+ " GtkWidget::focus-line-width = 0"
+ " xthickness = 0"
+ " ythickness = 0 }"
+ "widget \"*.gtkui-tab-close-button\" style \"gtkui-tab-close-button-style\""
+ );
+
+ g_signal_connect (button, "style-set", (GCallback) close_button_style_set, nullptr);
+
+ gtk_widget_show (button);
+
+ return button;
+}
+
+GtkNotebook * ui_playlist_get_notebook ()
+{
+ return (GtkNotebook *) notebook;
+}
+
+static void tab_title_reset (GtkWidget * ebox)
+{
+ GtkWidget * label = (GtkWidget *) g_object_get_data ((GObject *) ebox, "label");
+ GtkWidget * entry = (GtkWidget *) g_object_get_data ((GObject *) ebox, "entry");
+ gtk_widget_hide (entry);
+ gtk_widget_show (label);
+}
+
+static void tab_title_save (GtkEntry * entry, void * ebox)
+{
+ int id = GPOINTER_TO_INT (g_object_get_data ((GObject *) ebox, "playlist-id"));
+ GtkWidget * label = (GtkWidget *) g_object_get_data ((GObject *) ebox, "label");
+
+ aud_playlist_set_title (aud_playlist_by_unique_id (id), gtk_entry_get_text (entry));
+ gtk_widget_hide ((GtkWidget *) entry);
+ gtk_widget_show (label);
+}
+
+static gboolean tab_key_press_cb (GtkWidget * widget, GdkEventKey * event)
+{
+ if (event->keyval == GDK_KEY_Escape)
+ tab_title_reset (widget);
+
+ return false;
+}
+
+static gboolean tab_button_press_cb (GtkWidget * ebox, GdkEventButton * event)
+{
+ int id = GPOINTER_TO_INT (g_object_get_data ((GObject *) ebox, "playlist-id"));
+ int playlist = aud_playlist_by_unique_id (id);
+
+ if (event->type == GDK_2BUTTON_PRESS && event->button == 1)
+ aud_playlist_play (playlist);
+
+ if (event->type == GDK_BUTTON_PRESS && event->button == 2)
+ audgui_confirm_playlist_delete (playlist);
+
+ if (event->type == GDK_BUTTON_PRESS && event->button == 3)
+ popup_menu_tab (event->button, event->time, playlist);
+
+ return false;
+}
+
+static gboolean scroll_cb (GtkWidget * widget, GdkEventScroll * event)
+{
+ switch (event->direction)
+ {
+ case GDK_SCROLL_UP:
+ case GDK_SCROLL_LEFT:
+ aud_playlist_set_active (aud_playlist_get_active () - 1);
+ return true;
+
+ case GDK_SCROLL_DOWN:
+ case GDK_SCROLL_RIGHT:
+ aud_playlist_set_active (aud_playlist_get_active () + 1);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static gboolean scroll_ignore_cb ()
+{
+ return true;
+}
+
+static void tab_changed (GtkNotebook * notebook, GtkWidget * page, unsigned page_num)
+{
+ aud_playlist_set_active (page_num);
+}
+
+static void tab_reordered (GtkNotebook * notebook, GtkWidget * child, unsigned page_num)
+{
+ GtkWidget * widget = (GtkWidget *) g_object_get_data ((GObject *) child, "treeview");
+ g_return_if_fail (widget);
+ aud_playlist_reorder (ui_playlist_widget_get_playlist (widget), page_num, 1);
+}
+
+static GtkLabel * get_tab_label (int playlist)
+{
+ GtkWidget * page = gtk_notebook_get_nth_page (UI_PLAYLIST_NOTEBOOK, playlist);
+ GtkWidget * ebox = gtk_notebook_get_tab_label (UI_PLAYLIST_NOTEBOOK, page);
+ return (GtkLabel *) g_object_get_data ((GObject *) ebox, "label");
+}
+
+static void set_tab_label (int list, GtkLabel * label)
+{
+ String title0 = aud_playlist_get_title (list);
+ StringBuf title = aud_get_bool ("gtkui", "entry_count_visible") ?
+ str_printf ("%s (%d)", (const char *) title0, aud_playlist_entry_count (list)) :
+ str_copy (title0);
+
+ if (list == aud_playlist_get_playing ())
+ {
+ char * markup = g_markup_printf_escaped ("<b>%s</b>", (const char *) title);
+ gtk_label_set_markup (label, markup);
+ g_free (markup);
+ }
+ else
+ gtk_label_set_text (label, title);
+}
+
+void start_rename_playlist (int playlist)
+{
+ if (! gtk_notebook_get_show_tabs ((GtkNotebook *) notebook))
+ {
+ audgui_show_playlist_rename (playlist);
+ return;
+ }
+
+ GtkWidget * page = gtk_notebook_get_nth_page (UI_PLAYLIST_NOTEBOOK, playlist);
+ GtkWidget * ebox = gtk_notebook_get_tab_label (UI_PLAYLIST_NOTEBOOK, page);
+
+ GtkWidget * label = (GtkWidget *) g_object_get_data ((GObject *) ebox, "label");
+ GtkWidget * entry = (GtkWidget *) g_object_get_data ((GObject *) ebox, "entry");
+ gtk_widget_hide (label);
+
+ gtk_entry_set_text ((GtkEntry *) entry, aud_playlist_get_title (playlist));
+
+ gtk_widget_grab_focus (entry);
+ gtk_editable_select_region ((GtkEditable *) entry, 0, -1);
+ gtk_widget_show (entry);
+}
+
+void ui_playlist_notebook_create_tab (int playlist)
+{
+ int position = aud_playlist_get_position (playlist);
+
+ GtkWidget * scrollwin = gtk_scrolled_window_new (nullptr, nullptr);
+ GtkAdjustment * vscroll = gtk_scrolled_window_get_vadjustment ((GtkScrolledWindow *) scrollwin);
+
+ /* do not allow scroll events to propagate up to the notebook */
+ g_signal_connect_after (scrollwin, "scroll-event", (GCallback) scroll_ignore_cb, nullptr);
+
+ GtkWidget * treeview = ui_playlist_widget_new (playlist);
+
+ apply_column_widths (treeview);
+ g_signal_connect (treeview, "size-allocate", (GCallback) size_allocate_cb, nullptr);
+
+ g_object_set_data ((GObject *) scrollwin, "treeview", treeview);
+
+ gtk_container_add ((GtkContainer *) scrollwin, treeview);
+ gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrollwin,
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_widget_show_all (scrollwin);
+
+ GtkWidget * ebox = gtk_event_box_new ();
+ gtk_event_box_set_visible_window ((GtkEventBox *) ebox, false);
+
+ GtkWidget * hbox = gtk_hbox_new (false, 2);
+
+ GtkWidget * label = gtk_label_new ("");
+ set_tab_label (playlist, (GtkLabel *) label);
+ gtk_box_pack_start ((GtkBox *) hbox, label, false, false, 0);
+
+ GtkWidget * entry = gtk_entry_new ();
+ gtk_box_pack_start ((GtkBox *) hbox, entry, false, false, 0);
+ gtk_container_add ((GtkContainer *) ebox, hbox);
+ gtk_widget_show_all (ebox);
+ gtk_widget_hide (entry);
+
+ GtkWidget * button = nullptr;
+
+ if (aud_get_bool ("gtkui", "close_button_visible"))
+ {
+ button = make_close_button (ebox, playlist);
+ gtk_box_pack_end ((GtkBox *) hbox, button, false, false, 0);
+ }
+
+ g_object_set_data ((GObject *) ebox, "label", label);
+ g_object_set_data ((GObject *) ebox, "entry", entry);
+ g_object_set_data ((GObject *) ebox, "page", scrollwin);
+
+ gtk_notebook_insert_page (UI_PLAYLIST_NOTEBOOK, scrollwin, ebox, playlist);
+ gtk_notebook_set_tab_reorderable (UI_PLAYLIST_NOTEBOOK, scrollwin, true);
+
+ int id = aud_playlist_get_unique_id (playlist);
+ g_object_set_data ((GObject *) ebox, "playlist-id", GINT_TO_POINTER (id));
+ g_object_set_data ((GObject *) treeview, "playlist-id", GINT_TO_POINTER (id));
+
+ if (position >= 0)
+ {
+ aud_playlist_select_all (playlist, false);
+ aud_playlist_entry_set_selected (playlist, position, true);
+ aud_playlist_set_focus (playlist, position);
+ audgui_list_set_highlight (treeview, position);
+ audgui_list_set_focus (treeview, position);
+ }
+
+ g_signal_connect (ebox, "button-press-event", (GCallback) tab_button_press_cb, nullptr);
+ g_signal_connect (ebox, "key-press-event", (GCallback) tab_key_press_cb, nullptr);
+ g_signal_connect (entry, "activate", (GCallback) tab_title_save, ebox);
+ g_signal_connect_swapped (vscroll, "value-changed",
+ (GCallback) ui_playlist_widget_scroll, treeview);
+
+ /* we have to connect to "scroll-event" on the notebook, the tabs, AND the
+ * close buttons (sigh) */
+ gtk_widget_add_events (ebox, GDK_SCROLL_MASK);
+ g_signal_connect (ebox, "scroll-event", (GCallback) scroll_cb, nullptr);
+
+ if (button)
+ {
+ gtk_widget_add_events (button, GDK_SCROLL_MASK);
+ g_signal_connect (button, "scroll-event", (GCallback) scroll_cb, nullptr);
+ }
+}
+
+void ui_playlist_notebook_populate ()
+{
+ int playlist = aud_playlist_get_active ();
+
+ for (int count = 0; count < aud_playlist_count (); count ++)
+ ui_playlist_notebook_create_tab (count);
+
+ gtk_notebook_set_current_page (UI_PLAYLIST_NOTEBOOK, playlist);
+ highlighted = aud_playlist_get_unique_id (aud_playlist_get_playing ());
+
+ if (! switch_handler)
+ switch_handler = g_signal_connect (notebook, "switch-page", (GCallback)
+ tab_changed, nullptr);
+ if (! reorder_handler)
+ reorder_handler = g_signal_connect (notebook, "page-reordered",
+ (GCallback) tab_reordered, nullptr);
+
+ gtk_widget_grab_focus (playlist_get_treeview (playlist));
+}
+
+void ui_playlist_notebook_empty ()
+{
+ if (switch_handler)
+ g_signal_handler_disconnect (notebook, switch_handler);
+ switch_handler = 0;
+ if (reorder_handler)
+ g_signal_handler_disconnect (notebook, reorder_handler);
+ reorder_handler = 0;
+
+ int n_pages = gtk_notebook_get_n_pages ((GtkNotebook *) notebook);
+ while (n_pages)
+ gtk_notebook_remove_page ((GtkNotebook *) notebook, -- n_pages);
+}
+
+static void add_remove_pages ()
+{
+ g_signal_handlers_block_by_func (notebook, (void *) tab_changed, nullptr);
+ g_signal_handlers_block_by_func (notebook, (void *) tab_reordered, nullptr);
+
+ int lists = aud_playlist_count ();
+ int pages = gtk_notebook_get_n_pages ((GtkNotebook *) notebook);
+
+ /* scan through existing treeviews */
+ for (int i = 0; i < pages; )
+ {
+ GtkWidget * page = gtk_notebook_get_nth_page ((GtkNotebook *) notebook, i);
+ GtkWidget * tree = (GtkWidget *) g_object_get_data ((GObject *) page, "treeview");
+ int tree_id = GPOINTER_TO_INT (g_object_get_data ((GObject *) tree, "playlist-id"));
+
+ /* do we have an orphaned treeview? */
+ if (aud_playlist_by_unique_id (tree_id) < 0)
+ {
+ gtk_notebook_remove_page ((GtkNotebook *) notebook, i);
+ pages --;
+ continue;
+ }
+
+ /* do we have the right treeview? */
+ int list_id = aud_playlist_get_unique_id (i);
+
+ if (tree_id == list_id)
+ {
+ ui_playlist_widget_set_playlist (tree, i);
+ i ++;
+ continue;
+ }
+
+ /* look for the right treeview */
+ int found = false;
+
+ for (int j = i + 1; j < pages; j ++)
+ {
+ page = gtk_notebook_get_nth_page ((GtkNotebook *) notebook, j);
+ tree = (GtkWidget *) g_object_get_data ((GObject *) page, "treeview");
+ tree_id = GPOINTER_TO_INT (g_object_get_data ((GObject *) tree, "playlist-id"));
+
+ /* found it? move it to the right place */
+ if (tree_id == list_id)
+ {
+ gtk_notebook_reorder_child ((GtkNotebook *) notebook, page, i);
+ found = true;
+ break;
+ }
+ }
+
+ /* didn't find it? create it */
+ if (! found)
+ {
+ ui_playlist_notebook_create_tab (i);
+ pages ++;
+ continue;
+ }
+ }
+
+ /* create new treeviews */
+ while (pages < lists)
+ {
+ ui_playlist_notebook_create_tab (pages);
+ pages ++;
+ }
+
+ gtk_notebook_set_current_page ((GtkNotebook *) notebook, aud_playlist_get_active ());
+
+ show_hide_playlist_tabs ();
+
+ g_signal_handlers_unblock_by_func (notebook, (void *) tab_changed, nullptr);
+ g_signal_handlers_unblock_by_func (notebook, (void *) tab_reordered, nullptr);
+}
+
+void ui_playlist_notebook_update (void * data, void * user)
+{
+ auto global_level = aud::from_ptr<Playlist::UpdateLevel> (data);
+ if (global_level == Playlist::Structure)
+ add_remove_pages ();
+
+ int lists = aud_playlist_count ();
+
+ for (int list = 0; list < lists; list ++)
+ {
+ if (global_level >= Playlist::Metadata)
+ set_tab_label (list, get_tab_label (list));
+
+ GtkWidget * treeview = playlist_get_treeview (list);
+
+ auto update = aud_playlist_update_detail (list);
+ if (update.level)
+ ui_playlist_widget_update (treeview, update);
+
+ audgui_list_set_highlight (treeview, aud_playlist_get_position (list));
+ }
+
+ gtk_notebook_set_current_page ((GtkNotebook *) notebook, aud_playlist_get_active ());
+}
+
+void ui_playlist_notebook_position (void * data, void * user)
+{
+ int list = aud::from_ptr<int> (data);
+ int row = aud_playlist_get_position (list);
+
+ if (aud_get_bool ("gtkui", "autoscroll"))
+ {
+ aud_playlist_select_all (list, false);
+ aud_playlist_entry_set_selected (list, row, true);
+ aud_playlist_set_focus (list, row);
+ }
+
+ if (! aud_playlist_update_pending ())
+ audgui_list_set_highlight (playlist_get_treeview (list), row);
+}
+
+void ui_playlist_notebook_activate (void * data, void * user)
+{
+ if (! aud_playlist_update_pending ())
+ gtk_notebook_set_current_page ((GtkNotebook *) notebook, aud_playlist_get_active ());
+}
+
+void ui_playlist_notebook_set_playing (void * data, void * user)
+{
+ int id = aud_playlist_get_unique_id (aud_playlist_get_playing ());
+
+ // if the previous playing playlist was deleted, ignore it
+ if (aud_playlist_by_unique_id (highlighted) < 0)
+ highlighted = -1;
+
+ if (highlighted == id)
+ return;
+
+ int pages = gtk_notebook_get_n_pages ((GtkNotebook *) notebook);
+
+ for (int i = 0; i < pages; i ++)
+ {
+ GtkWidget * page = gtk_notebook_get_nth_page ((GtkNotebook *) notebook, i);
+ GtkWidget * tree = (GtkWidget *) g_object_get_data ((GObject *) page, "treeview");
+ int tree_id = GPOINTER_TO_INT (g_object_get_data ((GObject *) tree, "playlist-id"));
+
+ if (tree_id == highlighted || tree_id == id)
+ set_tab_label (i, get_tab_label (i));
+ }
+
+ highlighted = id;
+}
+
+static void destroy_cb ()
+{
+ notebook = nullptr;
+ switch_handler = 0;
+ reorder_handler = 0;
+}
+
+GtkWidget * ui_playlist_notebook_new ()
+{
+ notebook = gtk_notebook_new ();
+ gtk_notebook_set_scrollable ((GtkNotebook *) notebook, true);
+ make_add_button (notebook);
+
+ show_hide_playlist_tabs ();
+
+ gtk_widget_add_events (notebook, GDK_SCROLL_MASK);
+ g_signal_connect (notebook, "scroll-event", (GCallback) scroll_cb, nullptr);
+ g_signal_connect (notebook, "destroy", (GCallback) destroy_cb, nullptr);
+
+ return notebook;
+}
+
+void show_hide_playlist_tabs ()
+{
+ gtk_notebook_set_show_tabs ((GtkNotebook *) notebook, aud_get_bool ("gtkui",
+ "playlist_tabs_visible") || aud_playlist_count () > 1);
+}
diff --git a/src/gtkui/ui_playlist_notebook.h b/src/gtkui/ui_playlist_notebook.h
index 1bd5ae2f676e..1deb65128a8f 100644
--- a/src/gtkui/ui_playlist_notebook.h
+++ b/src/gtkui/ui_playlist_notebook.h
@@ -22,19 +22,20 @@
#include <gtk/gtk.h>
-#define UI_PLAYLIST_NOTEBOOK ui_playlist_get_notebook()
+#define UI_PLAYLIST_NOTEBOOK ui_playlist_get_notebook ()
-GtkNotebook *ui_playlist_get_notebook(void);
-GtkWidget *ui_playlist_notebook_new();
-void ui_playlist_notebook_create_tab(int playlist);
-void ui_playlist_notebook_populate(void);
-void ui_playlist_notebook_empty (void);
+GtkNotebook * ui_playlist_get_notebook ();
+GtkWidget * ui_playlist_notebook_new ();
+
+void ui_playlist_notebook_create_tab (int playlist);
+void ui_playlist_notebook_populate ();
+void ui_playlist_notebook_empty ();
void ui_playlist_notebook_update (void * data, void * user);
void ui_playlist_notebook_activate (void * data, void * user);
void ui_playlist_notebook_set_playing (void * data, void * user);
void ui_playlist_notebook_position (void * data, void * user);
void start_rename_playlist (int playlist);
-void show_hide_playlist_tabs (void);
+void show_hide_playlist_tabs ();
#endif
diff --git a/src/gtkui/ui_playlist_widget.c b/src/gtkui/ui_playlist_widget.c
deleted file mode 100644
index 685e740208c3..000000000000
--- a/src/gtkui/ui_playlist_widget.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * ui_playlist_widget.c
- * Copyright 2011-2012 John Lindgren, William Pitcock, and MichaÅ Lipski
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <string.h>
-
-#include <gtk/gtk.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <libaudcore/audstrings.h>
-#include <libaudgui/libaudgui.h>
-#include <libaudgui/libaudgui-gtk.h>
-#include <libaudgui/list.h>
-
-#include "gtkui.h"
-#include "playlist_util.h"
-#include "ui_playlist_widget.h"
-
-static const GType pw_col_types[PW_COLS] = {G_TYPE_INT, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_STRING};
-static const bool_t pw_col_widths[PW_COLS] = {7, -1, -1, 4, -1, 2, -1, 3, 7,
- -1, -1, -1, 3};
-static const bool_t pw_col_label[PW_COLS] = {FALSE, TRUE, TRUE, TRUE, TRUE,
- FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE};
-
-typedef struct {
- int list;
- GList * queue;
- int popup_source, popup_pos;
- bool_t popup_shown;
-} PlaylistWidgetData;
-
-static void set_int_from_tuple (GValue * value, const Tuple * tuple, int field)
-{
- int i = tuple ? tuple_get_int (tuple, field) : 0;
- if (i > 0)
- g_value_take_string (value, g_strdup_printf ("%d", i));
- else
- g_value_set_string (value, "");
-}
-
-static void set_string_from_tuple (GValue * value, const Tuple * tuple,
- int field)
-{
- char *str = tuple ? tuple_get_str (tuple, field) : NULL;
- g_value_set_string (value, str);
- str_unref(str);
-}
-
-static void set_queued (GValue * value, int list, int row)
-{
- int q = aud_playlist_queue_find_entry (list, row);
- if (q < 0)
- g_value_set_string (value, "");
- else
- g_value_take_string (value, g_strdup_printf ("#%d", 1 + q));
-}
-
-static void set_length (GValue * value, int list, int row)
-{
- int len = aud_playlist_entry_get_length (list, row, TRUE);
- if (len)
- {
- char s[16];
- audgui_format_time (s, sizeof s, len);
- g_value_set_string (value, s);
- }
- else
- g_value_set_string (value, "");
-}
-
-static void get_value (void * user, int row, int column, GValue * value)
-{
- PlaylistWidgetData * data = user;
- g_return_if_fail (column >= 0 && column < pw_num_cols);
- g_return_if_fail (row >= 0 && row < aud_playlist_entry_count (data->list));
-
- column = pw_cols[column];
-
- char * title = NULL, * artist = NULL, * album = NULL;
- Tuple * tuple = NULL;
-
- if (column == PW_COL_TITLE || column == PW_COL_ARTIST || column ==
- PW_COL_ALBUM)
- aud_playlist_entry_describe (data->list, row, & title, & artist,
- & album, TRUE);
- else if (column == PW_COL_YEAR || column == PW_COL_TRACK || column ==
- PW_COL_GENRE || column == PW_COL_FILENAME || column == PW_COL_PATH ||
- column == PW_COL_BITRATE)
- tuple = aud_playlist_entry_get_tuple (data->list, row, TRUE);
-
- switch (column)
- {
- case PW_COL_NUMBER:
- g_value_set_int (value, 1 + row);
- break;
- case PW_COL_TITLE:
- g_value_set_string (value, title);
- break;
- case PW_COL_ARTIST:
- g_value_set_string (value, artist);
- break;
- case PW_COL_YEAR:
- set_int_from_tuple (value, tuple, FIELD_YEAR);
- break;
- case PW_COL_ALBUM:
- g_value_set_string (value, album);
- break;
- case PW_COL_TRACK:
- set_int_from_tuple (value, tuple, FIELD_TRACK_NUMBER);
- break;
- case PW_COL_GENRE:
- set_string_from_tuple (value, tuple, FIELD_GENRE);
- break;
- case PW_COL_QUEUED:
- set_queued (value, data->list, row);
- break;
- case PW_COL_LENGTH:
- set_length (value, data->list, row);
- break;
- case PW_COL_FILENAME:
- set_string_from_tuple (value, tuple, FIELD_FILE_NAME);
- break;
- case PW_COL_PATH:
- set_string_from_tuple (value, tuple, FIELD_FILE_PATH);
- break;
- case PW_COL_CUSTOM:;
- char * custom = aud_playlist_entry_get_title (data->list, row, TRUE);
- g_value_set_string (value, custom);
- str_unref (custom);
- break;
- case PW_COL_BITRATE:
- set_int_from_tuple (value, tuple, FIELD_BITRATE);
- break;
- }
-
- str_unref (title);
- str_unref (artist);
- str_unref (album);
- if (tuple)
- tuple_unref (tuple);
-}
-
-static bool_t get_selected (void * user, int row)
-{
- return aud_playlist_entry_get_selected (((PlaylistWidgetData *) user)->list,
- row);
-}
-
-static void set_selected (void * user, int row, bool_t selected)
-{
- aud_playlist_entry_set_selected (((PlaylistWidgetData *) user)->list, row,
- selected);
-}
-
-static void select_all (void * user, bool_t selected)
-{
- aud_playlist_select_all (((PlaylistWidgetData *) user)->list, selected);
-}
-
-static void focus_change (void * user, int row)
-{
- aud_playlist_set_focus (((PlaylistWidgetData *) user)->list, row);
-}
-
-static void activate_row (void * user, int row)
-{
- int list = ((PlaylistWidgetData *) user)->list;
- aud_playlist_set_position (list, row);
- aud_drct_play_playlist (list);
-}
-
-static void right_click (void * user, GdkEventButton * event)
-{
- popup_menu_rclick (event->button, event->time);
-}
-
-static void shift_rows (void * user, int row, int before)
-{
- int list = ((PlaylistWidgetData *) user)->list;
-
- /* Adjust the shift amount so that the selected entry closest to the
- * destination ends up at the destination. */
- if (before > row)
- before -= playlist_count_selected_in_range (list, row, before - row);
- else
- before += playlist_count_selected_in_range (list, before, row - before);
-
- aud_playlist_shift (list, row, before - row);
-}
-
-static bool_t popup_show (PlaylistWidgetData * data)
-{
- audgui_infopopup_show (data->list, data->popup_pos);
- data->popup_shown = TRUE;
-
- g_source_remove (data->popup_source);
- data->popup_source = 0;
- return FALSE;
-}
-
-static void popup_hide (PlaylistWidgetData * data)
-{
- if (data->popup_source)
- {
- g_source_remove (data->popup_source);
- data->popup_source = 0;
- }
-
- if (data->popup_shown)
- {
- audgui_infopopup_hide ();
- data->popup_shown = FALSE;
- }
-
- data->popup_pos = -1;
-}
-
-static void popup_trigger (PlaylistWidgetData * data, int pos)
-{
- popup_hide (data);
-
- data->popup_pos = pos;
- data->popup_source = g_timeout_add (aud_get_int (NULL, "filepopup_delay") *
- 100, (GSourceFunc) popup_show, data);
-}
-
-static void mouse_motion (void * user, GdkEventMotion * event, int row)
-{
- PlaylistWidgetData * data = (PlaylistWidgetData *) user;
-
- if (row < 0)
- {
- popup_hide (data);
- return;
- }
-
- if (aud_get_bool (NULL, "show_filepopup_for_tuple") && data->popup_pos != row)
- popup_trigger (data, row);
-}
-
-static void mouse_leave (void * user, GdkEventMotion * event, int row)
-{
- popup_hide ((PlaylistWidgetData *) user);
-}
-
-static void get_data (void * user, void * * data, int * length)
-{
- char * text = audgui_urilist_create_from_selected
- (((PlaylistWidgetData *) user)->list);
- g_return_if_fail (text);
- * data = text;
- * length = strlen (text);
-}
-
-static void receive_data (void * user, int row, const void * data, int length)
-{
- SNCOPY (text, data, length);
- audgui_urilist_insert (((PlaylistWidgetData *) user)->list, row, text);
-}
-
-static const AudguiListCallbacks callbacks = {
- .get_value = get_value,
- .get_selected = get_selected,
- .set_selected = set_selected,
- .select_all = select_all,
- .focus_change = focus_change,
- .activate_row = activate_row,
- .right_click = right_click,
- .shift_rows = shift_rows,
- .mouse_motion = mouse_motion,
- .mouse_leave = mouse_leave,
- .data_type = "text/uri-list",
- .get_data = get_data,
- .receive_data = receive_data};
-
-static bool_t search_cb (GtkTreeModel * model, int column, const char * search,
- GtkTreeIter * iter, void * user)
-{
- GtkTreePath * path = gtk_tree_model_get_path (model, iter);
- g_return_val_if_fail (path, TRUE);
- int row = gtk_tree_path_get_indices (path)[0];
- g_return_val_if_fail (row >= 0, TRUE);
- gtk_tree_path_free (path);
-
- Index * keys = str_list_to_index (search, " ");
- int n_keys = index_count (keys);
-
- bool_t matched = FALSE;
-
- if (n_keys)
- {
- char * s[3] = {NULL, NULL, NULL};
- aud_playlist_entry_describe (((PlaylistWidgetData *) user)->list, row,
- & s[0], & s[1], & s[2], FALSE);
-
- for (int i = 0; i < ARRAY_LEN (s); i ++)
- {
- if (! s[i])
- continue;
-
- for (int j = 0; j < n_keys;)
- {
- if (strstr_nocase_utf8 (s[i], index_get (keys, j)))
- {
- index_delete_full (keys, j, 1, (IndexFreeFunc) str_unref);
- n_keys --;
- }
- else
- j ++;
- }
-
- str_unref (s[i]);
- }
-
- matched = ! n_keys;
- }
-
- index_free_full (keys, (IndexFreeFunc) str_unref);
-
- return ! matched;
-}
-
-static void destroy_cb (PlaylistWidgetData * data)
-{
- g_list_free (data->queue);
- g_slice_free (PlaylistWidgetData, data);
-}
-
-GtkWidget * ui_playlist_widget_new (int playlist)
-{
- PlaylistWidgetData * data = g_slice_new (PlaylistWidgetData);
- data->list = playlist;
- data->queue = NULL;
- data->popup_source = 0;
- data->popup_pos = -1;
- data->popup_shown = FALSE;
-
- GtkWidget * list = audgui_list_new (& callbacks, data,
- aud_playlist_entry_count (playlist));
-
- gtk_tree_view_set_headers_visible ((GtkTreeView *) list,
- aud_get_bool ("gtkui", "playlist_headers"));
- gtk_tree_view_set_search_equal_func ((GtkTreeView *) list, search_cb, data,
- NULL);
- g_signal_connect_swapped (list, "destroy", (GCallback) destroy_cb, data);
-
- /* Disable type-to-search because it blocks CTRL-V, causing URI's to be
- * pasted into the search box rather than added to the playlist. The search
- * box can still be brought up with CTRL-F. */
- gtk_tree_view_set_enable_search ((GtkTreeView *) list, FALSE);
-
- for (int i = 0; i < pw_num_cols; i ++)
- {
- int n = pw_cols[i];
- audgui_list_add_column (list, pw_col_label[n] ? _(pw_col_names[n]) :
- NULL, i, pw_col_types[n], pw_col_widths[n]);
- }
-
- return list;
-}
-
-int ui_playlist_widget_get_playlist (GtkWidget * widget)
-{
- PlaylistWidgetData * data = audgui_list_get_user (widget);
- g_return_val_if_fail (data, -1);
- return data->list;
-}
-
-void ui_playlist_widget_set_playlist (GtkWidget * widget, int list)
-{
- PlaylistWidgetData * data = audgui_list_get_user (widget);
- g_return_if_fail (data);
- data->list = list;
-}
-
-static void update_queue (GtkWidget * widget, PlaylistWidgetData * data)
-{
- for (GList * node = data->queue; node; node = node->next)
- audgui_list_update_rows (widget, GPOINTER_TO_INT (node->data), 1);
-
- g_list_free (data->queue);
- data->queue = NULL;
-
- for (int i = aud_playlist_queue_count (data->list); i --; )
- data->queue = g_list_prepend (data->queue, GINT_TO_POINTER
- (aud_playlist_queue_get_entry (data->list, i)));
-
- for (GList * node = data->queue; node; node = node->next)
- audgui_list_update_rows (widget, GPOINTER_TO_INT (node->data), 1);
-}
-
-void ui_playlist_widget_update (GtkWidget * widget, int type, int at,
- int count)
-{
- PlaylistWidgetData * data = audgui_list_get_user (widget);
- g_return_if_fail (data);
-
- if (type == PLAYLIST_UPDATE_STRUCTURE)
- {
- int old_entries = audgui_list_row_count (widget);
- int entries = aud_playlist_entry_count (data->list);
-
- audgui_list_delete_rows (widget, at, old_entries - (entries - count));
- audgui_list_insert_rows (widget, at, count);
-
- /* scroll to end of playlist if entries were added there
- (but not if a newly added entry is playing) */
- if (entries > old_entries && at + count == entries &&
- aud_playlist_get_focus (data->list) < old_entries)
- aud_playlist_set_focus (data->list, entries - 1);
-
- ui_playlist_widget_scroll (widget);
- }
- else if (type == PLAYLIST_UPDATE_METADATA)
- audgui_list_update_rows (widget, at, count);
-
- audgui_list_update_selection (widget, at, count);
- audgui_list_set_focus (widget, aud_playlist_get_focus (data->list));
- update_queue (widget, data);
-}
-
-void ui_playlist_widget_scroll (GtkWidget * widget)
-{
- PlaylistWidgetData * data = audgui_list_get_user (widget);
- g_return_if_fail (data);
-
- int row = -1;
-
- if (gtk_widget_get_realized (widget))
- {
- int x, y;
- audgui_get_mouse_coords (widget, & x, & y);
- row = audgui_list_row_at_point (widget, x, y);
- }
-
- /* Only update the info popup if it is already shown or about to be shown;
- * this makes sure that it doesn't pop up when the Audacious window isn't
- * even visible. */
- if (row >= 0 && (data->popup_source || data->popup_shown))
- popup_trigger (data, row);
- else
- popup_hide (data);
-}
-
-void ui_playlist_widget_get_column_widths (GtkWidget * widget, char * * widths,
- char * * expand)
-{
- int w[pw_num_cols], ex[pw_num_cols];
-
- for (int i = 0; i < pw_num_cols; i ++)
- {
- GtkTreeViewColumn * col = gtk_tree_view_get_column ((GtkTreeView *) widget, i);
- w[i] = gtk_tree_view_column_get_fixed_width (col);
- ex[i] = gtk_tree_view_column_get_expand (col);
- }
-
- * widths = int_array_to_str (w, pw_num_cols);
- * expand = int_array_to_str (ex, pw_num_cols);
-}
-
-void ui_playlist_widget_set_column_widths (GtkWidget * widget,
- const char * widths, const char * expand)
-{
- int w[pw_num_cols], ex[pw_num_cols];
-
- if (! str_to_int_array (widths, w, pw_num_cols) ||
- ! str_to_int_array (expand, ex, pw_num_cols))
- return;
-
- for (int i = 0; i < pw_num_cols; i ++)
- {
- GtkTreeViewColumn * col = gtk_tree_view_get_column ((GtkTreeView *) widget, i);
- gtk_tree_view_column_set_fixed_width (col, w[i]);
- gtk_tree_view_column_set_expand (col, ex[i]);
- }
-}
diff --git a/src/gtkui/ui_playlist_widget.cc b/src/gtkui/ui_playlist_widget.cc
new file mode 100644
index 000000000000..a95e2ea088fb
--- /dev/null
+++ b/src/gtkui/ui_playlist_widget.cc
@@ -0,0 +1,488 @@
+/*
+ * ui_playlist_widget.c
+ * Copyright 2011-2012 John Lindgren, William Pitcock, and MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/tuple.h>
+#include <libaudgui/libaudgui.h>
+#include <libaudgui/libaudgui-gtk.h>
+#include <libaudgui/list.h>
+
+#include "gtkui.h"
+#include "playlist_util.h"
+#include "ui_playlist_widget.h"
+
+static const GType pw_col_types[PW_COLS] =
+{
+ G_TYPE_INT, // entry number
+ G_TYPE_STRING, // title
+ G_TYPE_STRING, // artist
+ G_TYPE_STRING, // year
+ G_TYPE_STRING, // album
+ G_TYPE_STRING, // album artist
+ G_TYPE_STRING, // track
+ G_TYPE_STRING, // genre
+ G_TYPE_STRING, // queue position
+ G_TYPE_STRING, // length
+ G_TYPE_STRING, // path
+ G_TYPE_STRING, // file name
+ G_TYPE_STRING, // custom title
+ G_TYPE_STRING // bitrate
+};
+
+static const int pw_col_min_widths[PW_COLS] = {
+ 7, // entry number
+ 10, // title
+ 10, // artist
+ 4, // year
+ 10, // album
+ 10, // album artist
+ 2, // track
+ 10, // genre
+ 3, // queue position
+ 7, // length
+ 10, // path
+ 10, // file name
+ 10, // custom title
+ 3 // bitrate
+};
+
+static const bool pw_col_label[PW_COLS] = {
+ false, // entry number
+ true, // title
+ true, // artist
+ true, // year
+ true, // album
+ true, // album artist
+ false, // track
+ true, // genre
+ false, // queue position
+ false, // length
+ true, // path
+ true, // file name
+ true, // custom title
+ false // bitrate
+};
+
+typedef struct {
+ int list;
+ int popup_source, popup_pos;
+ bool popup_shown;
+} PlaylistWidgetData;
+
+static void set_int_from_tuple (GValue * value, const Tuple & tuple, Tuple::Field field)
+{
+ int i = tuple ? tuple.get_int (field) : 0;
+ if (i > 0)
+ g_value_take_string (value, g_strdup_printf ("%d", i));
+ else
+ g_value_set_string (value, "");
+}
+
+static void set_string_from_tuple (GValue * value, const Tuple & tuple, Tuple::Field field)
+{
+ String str = tuple ? tuple.get_str (field) : String ();
+ g_value_set_string (value, str);
+}
+
+static void set_queued (GValue * value, int list, int row)
+{
+ int q = aud_playlist_queue_find_entry (list, row);
+ if (q < 0)
+ g_value_set_string (value, "");
+ else
+ g_value_take_string (value, g_strdup_printf ("#%d", 1 + q));
+}
+
+static void set_length (GValue * value, const Tuple & tuple)
+{
+ int len = tuple.get_int (Tuple::Length);
+ if (len >= 0)
+ g_value_set_string (value, str_format_time (len));
+ else
+ g_value_set_string (value, "");
+}
+
+static void get_value (void * user, int row, int column, GValue * value)
+{
+ PlaylistWidgetData * data = (PlaylistWidgetData *) user;
+ g_return_if_fail (column >= 0 && column < pw_num_cols);
+ g_return_if_fail (row >= 0 && row < aud_playlist_entry_count (data->list));
+
+ column = pw_cols[column];
+
+ Tuple tuple;
+
+ switch (column)
+ {
+ case PW_COL_TITLE:
+ case PW_COL_ARTIST:
+ case PW_COL_ALBUM:
+ case PW_COL_YEAR:
+ case PW_COL_ALBUM_ARTIST:
+ case PW_COL_TRACK:
+ case PW_COL_GENRE:
+ case PW_COL_LENGTH:
+ case PW_COL_FILENAME:
+ case PW_COL_PATH:
+ case PW_COL_CUSTOM:
+ case PW_COL_BITRATE:
+ tuple = aud_playlist_entry_get_tuple (data->list, row, Playlist::Guess);
+ break;
+ }
+
+ switch (column)
+ {
+ case PW_COL_NUMBER:
+ g_value_set_int (value, 1 + row);
+ break;
+ case PW_COL_TITLE:
+ set_string_from_tuple (value, tuple, Tuple::Title);
+ break;
+ case PW_COL_ARTIST:
+ set_string_from_tuple (value, tuple, Tuple::Artist);
+ break;
+ case PW_COL_YEAR:
+ set_int_from_tuple (value, tuple, Tuple::Year);
+ break;
+ case PW_COL_ALBUM:
+ set_string_from_tuple (value, tuple, Tuple::Album);
+ break;
+ case PW_COL_ALBUM_ARTIST:
+ set_string_from_tuple (value, tuple, Tuple::AlbumArtist);
+ break;
+ case PW_COL_TRACK:
+ set_int_from_tuple (value, tuple, Tuple::Track);
+ break;
+ case PW_COL_GENRE:
+ set_string_from_tuple (value, tuple, Tuple::Genre);
+ break;
+ case PW_COL_QUEUED:
+ set_queued (value, data->list, row);
+ break;
+ case PW_COL_LENGTH:
+ set_length (value, tuple);
+ break;
+ case PW_COL_FILENAME:
+ set_string_from_tuple (value, tuple, Tuple::Basename);
+ break;
+ case PW_COL_PATH:
+ set_string_from_tuple (value, tuple, Tuple::Path);
+ break;
+ case PW_COL_CUSTOM:
+ set_string_from_tuple (value, tuple, Tuple::FormattedTitle);
+ break;
+ case PW_COL_BITRATE:
+ set_int_from_tuple (value, tuple, Tuple::Bitrate);
+ break;
+ }
+}
+
+static bool get_selected (void * user, int row)
+{
+ return aud_playlist_entry_get_selected (((PlaylistWidgetData *) user)->list,
+ row);
+}
+
+static void set_selected (void * user, int row, bool selected)
+{
+ aud_playlist_entry_set_selected (((PlaylistWidgetData *) user)->list, row,
+ selected);
+}
+
+static void select_all (void * user, bool selected)
+{
+ aud_playlist_select_all (((PlaylistWidgetData *) user)->list, selected);
+}
+
+static void focus_change (void * user, int row)
+{
+ aud_playlist_set_focus (((PlaylistWidgetData *) user)->list, row);
+}
+
+static void activate_row (void * user, int row)
+{
+ int list = ((PlaylistWidgetData *) user)->list;
+ aud_playlist_set_position (list, row);
+ aud_playlist_play (list);
+}
+
+static void right_click (void * user, GdkEventButton * event)
+{
+ popup_menu_rclick (event->button, event->time);
+}
+
+static void shift_rows (void * user, int row, int before)
+{
+ int list = ((PlaylistWidgetData *) user)->list;
+
+ /* Adjust the shift amount so that the selected entry closest to the
+ * destination ends up at the destination. */
+ if (before > row)
+ before -= playlist_count_selected_in_range (list, row, before - row);
+ else
+ before += playlist_count_selected_in_range (list, before, row - before);
+
+ aud_playlist_shift (list, row, before - row);
+}
+
+static gboolean popup_show (PlaylistWidgetData * data)
+{
+ audgui_infopopup_show (data->list, data->popup_pos);
+ data->popup_shown = true;
+
+ g_source_remove (data->popup_source);
+ data->popup_source = 0;
+ return false;
+}
+
+static void popup_hide (PlaylistWidgetData * data)
+{
+ if (data->popup_source)
+ {
+ g_source_remove (data->popup_source);
+ data->popup_source = 0;
+ }
+
+ if (data->popup_shown)
+ {
+ audgui_infopopup_hide ();
+ data->popup_shown = false;
+ }
+
+ data->popup_pos = -1;
+}
+
+static void popup_trigger (PlaylistWidgetData * data, int pos)
+{
+ popup_hide (data);
+
+ data->popup_pos = pos;
+ data->popup_source = g_timeout_add (aud_get_int (nullptr, "filepopup_delay") *
+ 100, (GSourceFunc) popup_show, data);
+}
+
+static void mouse_motion (void * user, GdkEventMotion * event, int row)
+{
+ PlaylistWidgetData * data = (PlaylistWidgetData *) user;
+
+ if (row < 0)
+ {
+ popup_hide (data);
+ return;
+ }
+
+ if (aud_get_bool (nullptr, "show_filepopup_for_tuple") && data->popup_pos != row)
+ popup_trigger (data, row);
+}
+
+static void mouse_leave (void * user, GdkEventMotion * event, int row)
+{
+ popup_hide ((PlaylistWidgetData *) user);
+}
+
+static Index<char> get_data (void * user)
+{
+ int playlist = ((PlaylistWidgetData *) user)->list;
+ return audgui_urilist_create_from_selected (playlist);
+}
+
+static void receive_data (void * user, int row, const char * data, int length)
+{
+ int playlist = ((PlaylistWidgetData *) user)->list;
+ audgui_urilist_insert (playlist, row, str_copy (data, length));
+}
+
+static const AudguiListCallbacks callbacks = {
+ get_value,
+ get_selected,
+ set_selected,
+ select_all,
+ activate_row,
+ right_click,
+ shift_rows,
+ "text/uri-list",
+ get_data,
+ receive_data,
+ mouse_motion,
+ mouse_leave,
+ focus_change
+};
+
+static gboolean search_cb (GtkTreeModel * model, int column, const char * search,
+ GtkTreeIter * iter, void * user)
+{
+ GtkTreePath * path = gtk_tree_model_get_path (model, iter);
+ g_return_val_if_fail (path, true);
+ int row = gtk_tree_path_get_indices (path)[0];
+ g_return_val_if_fail (row >= 0, true);
+ gtk_tree_path_free (path);
+
+ Index<String> keys = str_list_to_index (search, " ");
+
+ bool matched = false;
+
+ if (keys.len ())
+ {
+ int list = ((PlaylistWidgetData *) user)->list;
+ Tuple tuple = aud_playlist_entry_get_tuple (list, row);
+
+ String strings[3] = {
+ tuple.get_str (Tuple::Title),
+ tuple.get_str (Tuple::Artist),
+ tuple.get_str (Tuple::Album)
+ };
+
+ for (const String & s : strings)
+ {
+ if (! s)
+ continue;
+
+ auto is_match = [&] (const String & key)
+ { return (bool) strstr_nocase_utf8 (s, key); };
+
+ keys.remove_if (is_match);
+ }
+
+ matched = ! keys.len ();
+ }
+
+ return ! matched;
+}
+
+static void destroy_cb (PlaylistWidgetData * data)
+{
+ delete data;
+}
+
+GtkWidget * ui_playlist_widget_new (int playlist)
+{
+ PlaylistWidgetData * data = new PlaylistWidgetData;
+ data->list = playlist;
+ data->popup_source = 0;
+ data->popup_pos = -1;
+ data->popup_shown = false;
+
+ GtkWidget * list = audgui_list_new (& callbacks, data,
+ aud_playlist_entry_count (playlist));
+
+ gtk_tree_view_set_headers_visible ((GtkTreeView *) list,
+ aud_get_bool ("gtkui", "playlist_headers"));
+ gtk_tree_view_set_search_equal_func ((GtkTreeView *) list, search_cb, data,
+ nullptr);
+ g_signal_connect_swapped (list, "destroy", (GCallback) destroy_cb, data);
+
+ /* Disable type-to-search because it blocks CTRL-V, causing URI's to be
+ * pasted into the search box rather than added to the playlist. The search
+ * box can still be brought up with CTRL-F. */
+ gtk_tree_view_set_enable_search ((GtkTreeView *) list, false);
+
+ for (int i = 0; i < pw_num_cols; i ++)
+ {
+ int n = pw_cols[i];
+ audgui_list_add_column (list, pw_col_label[n] ? _(pw_col_names[n]) :
+ nullptr, i, pw_col_types[n], pw_col_min_widths[n]);
+ }
+
+ return list;
+}
+
+int ui_playlist_widget_get_playlist (GtkWidget * widget)
+{
+ PlaylistWidgetData * data = (PlaylistWidgetData *) audgui_list_get_user (widget);
+ g_return_val_if_fail (data, -1);
+ return data->list;
+}
+
+void ui_playlist_widget_set_playlist (GtkWidget * widget, int list)
+{
+ PlaylistWidgetData * data = (PlaylistWidgetData *) audgui_list_get_user (widget);
+ g_return_if_fail (data);
+ data->list = list;
+}
+
+void ui_playlist_widget_update (GtkWidget * widget, const Playlist::Update & update)
+{
+ PlaylistWidgetData * data = (PlaylistWidgetData *) audgui_list_get_user (widget);
+ g_return_if_fail (data);
+
+ int entries = aud_playlist_entry_count (data->list);
+ int changed = entries - update.before - update.after;
+
+ if (update.level == Playlist::Structure)
+ {
+ int old_entries = audgui_list_row_count (widget);
+ int removed = old_entries - update.before - update.after;
+
+ audgui_list_delete_rows (widget, update.before, removed);
+ audgui_list_insert_rows (widget, update.before, changed);
+
+ /* scroll to end of playlist if entries were added there
+ (but not if a newly added entry is playing) */
+ if (entries > old_entries && ! update.after &&
+ aud_playlist_get_focus (data->list) < old_entries)
+ aud_playlist_set_focus (data->list, entries - 1);
+
+ ui_playlist_widget_scroll (widget);
+ }
+ else if (update.level == Playlist::Metadata || update.queue_changed)
+ audgui_list_update_rows (widget, update.before, changed);
+
+ if (update.queue_changed)
+ {
+ for (int i = aud_playlist_queue_count (data->list); i --; )
+ {
+ int entry = aud_playlist_queue_get_entry (data->list, i);
+ if (entry < update.before || entry >= entries - update.after)
+ audgui_list_update_rows (widget, entry, 1);
+ }
+ }
+
+ audgui_list_update_selection (widget, update.before, changed);
+ audgui_list_set_focus (widget, aud_playlist_get_focus (data->list));
+}
+
+void ui_playlist_widget_scroll (GtkWidget * widget)
+{
+ PlaylistWidgetData * data = (PlaylistWidgetData *) audgui_list_get_user (widget);
+ g_return_if_fail (data);
+
+ int row = -1;
+
+ if (gtk_widget_get_realized (widget))
+ {
+ int x, y;
+ audgui_get_mouse_coords (widget, & x, & y);
+ row = audgui_list_row_at_point (widget, x, y);
+ }
+
+ /* Only update the info popup if it is already shown or about to be shown;
+ * this makes sure that it doesn't pop up when the Audacious window isn't
+ * even visible. */
+ if (row >= 0 && (data->popup_source || data->popup_shown))
+ popup_trigger (data, row);
+ else
+ popup_hide (data);
+}
diff --git a/src/gtkui/ui_playlist_widget.h b/src/gtkui/ui_playlist_widget.h
index 4ff48a9a03a8..9503d841dc30 100644
--- a/src/gtkui/ui_playlist_widget.h
+++ b/src/gtkui/ui_playlist_widget.h
@@ -21,31 +21,41 @@
#define UI_PLAYLIST_WIDGET_H
#include <gtk/gtk.h>
+#include <libaudcore/playlist.h>
GtkWidget * ui_playlist_widget_new (int playlist);
int ui_playlist_widget_get_playlist (GtkWidget * widget);
void ui_playlist_widget_set_playlist (GtkWidget * widget, int playlist);
-void ui_playlist_widget_update (GtkWidget * widget, int type, int at,
- int count);
+void ui_playlist_widget_update (GtkWidget * widget, const Playlist::Update & update);
void ui_playlist_widget_scroll (GtkWidget * widget);
-void ui_playlist_widget_get_column_widths (GtkWidget * widget, char * * widths,
- char * * expand);
-void ui_playlist_widget_set_column_widths (GtkWidget * widget,
- const char * widths, const char * expand);
-
-enum {PW_COL_NUMBER, PW_COL_TITLE, PW_COL_ARTIST, PW_COL_YEAR, PW_COL_ALBUM,
- PW_COL_TRACK, PW_COL_GENRE, PW_COL_QUEUED, PW_COL_LENGTH, PW_COL_PATH,
- PW_COL_FILENAME, PW_COL_CUSTOM, PW_COL_BITRATE, PW_COLS};
+enum {
+ PW_COL_NUMBER,
+ PW_COL_TITLE,
+ PW_COL_ARTIST,
+ PW_COL_YEAR,
+ PW_COL_ALBUM,
+ PW_COL_ALBUM_ARTIST,
+ PW_COL_TRACK,
+ PW_COL_GENRE,
+ PW_COL_QUEUED,
+ PW_COL_LENGTH,
+ PW_COL_PATH,
+ PW_COL_FILENAME,
+ PW_COL_CUSTOM,
+ PW_COL_BITRATE,
+ PW_COLS
+};
extern const char * const pw_col_names[PW_COLS];
extern int pw_num_cols;
extern int pw_cols[PW_COLS];
+extern int pw_col_widths[PW_COLS];
-void pw_col_init (void);
-void * pw_col_create_chooser (void);
-void pw_col_save (void);
-void pw_col_cleanup (void);
+void pw_col_init ();
+void * pw_col_create_chooser ();
+void pw_col_save ();
+void pw_col_cleanup ();
#endif
diff --git a/src/gtkui/ui_statusbar.c b/src/gtkui/ui_statusbar.c
deleted file mode 100644
index 747884dcb20e..000000000000
--- a/src/gtkui/ui_statusbar.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * ui_statusbar.c
- * Copyright 2010-2011 William Pitcock, MichaÅ Lipski, and John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <glib.h>
-#include <audacious/i18n.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <audacious/drct.h>
-#include <audacious/playlist.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui.h>
-
-#include "ui_statusbar.h"
-
-#define APPEND(b, ...) snprintf (b + strlen (b), sizeof b - strlen (b), __VA_ARGS__)
-
-static void ui_statusbar_update_playlist_length (void * unused, GtkWidget * label)
-{
- int playlist = aud_playlist_get_active ();
-
- char s1[16], s2[16];
- audgui_format_time (s1, sizeof s1, aud_playlist_get_selected_length (playlist));
- audgui_format_time (s2, sizeof s2, aud_playlist_get_total_length (playlist));
-
- SCONCAT3 (buf, s1, " / ", s2);
- gtk_label_set_text ((GtkLabel *) label, buf);
-}
-
-static void ui_statusbar_info_change (void * unused, GtkWidget * label)
-{
- /* may be called asynchronously */
- if (! aud_drct_get_playing ())
- return;
-
- int playlist = aud_playlist_get_playing ();
- Tuple * tuple = aud_playlist_entry_get_tuple (playlist,
- aud_playlist_get_position (playlist), FALSE);
- char * codec = tuple ? tuple_get_str (tuple, FIELD_CODEC) : NULL;
- if (tuple)
- tuple_unref (tuple);
-
- int bitrate, samplerate, channels;
- aud_drct_get_info (& bitrate, & samplerate, & channels);
-
- char buf[256];
- buf[0] = 0;
-
- if (codec)
- {
- APPEND (buf, "%s", codec);
- if (channels > 0 || samplerate > 0 || bitrate > 0)
- APPEND (buf, ", ");
- }
-
- str_unref (codec);
-
- if (channels > 0)
- {
- if (channels == 1)
- APPEND (buf, _("mono"));
- else if (channels == 2)
- APPEND (buf, _("stereo"));
- else
- APPEND (buf, ngettext ("%d channel", "%d channels", channels),
- channels);
-
- if (samplerate > 0 || bitrate > 0)
- APPEND (buf, ", ");
- }
-
- if (samplerate > 0)
- {
- APPEND (buf, "%d kHz", samplerate / 1000);
- if (bitrate > 0)
- APPEND (buf, ", ");
- }
-
- if (bitrate > 0)
- APPEND (buf, _("%d kbps"), bitrate / 1000);
-
- gtk_label_set_text ((GtkLabel *) label, buf);
-}
-
-static void ui_statusbar_playback_stop (void * unused, GtkWidget * label)
-{
- gtk_label_set_text ((GtkLabel *) label, NULL);
-}
-
-static void ui_statusbar_destroy_cb (GtkWidget * widget, void * data)
-{
- hook_dissociate ("playback ready", (HookFunction) ui_statusbar_info_change);
- hook_dissociate ("info change", (HookFunction) ui_statusbar_info_change);
- hook_dissociate ("playback stop", (HookFunction) ui_statusbar_playback_stop);
- hook_dissociate ("playlist activate", (HookFunction) ui_statusbar_update_playlist_length);
- hook_dissociate ("playlist update", (HookFunction) ui_statusbar_update_playlist_length);
-}
-
-GtkWidget * ui_statusbar_new (void)
-{
- GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
- GtkWidget * status = gtk_widget_new (GTK_TYPE_LABEL, "xalign", 0.0, NULL);
- GtkWidget * length = gtk_widget_new (GTK_TYPE_LABEL, "xalign", 1.0, NULL);
-
- gtk_label_set_ellipsize ((GtkLabel *) status, PANGO_ELLIPSIZE_END);
- gtk_box_pack_start ((GtkBox *) hbox, status, TRUE, TRUE, 5);
- gtk_box_pack_start ((GtkBox *) hbox, length, FALSE, FALSE, 5);
-
- ui_statusbar_update_playlist_length (NULL, length);
-
- hook_associate ("playback ready", (HookFunction) ui_statusbar_info_change, status);
- hook_associate ("info change", (HookFunction) ui_statusbar_info_change, status);
- hook_associate ("playback stop", (HookFunction) ui_statusbar_playback_stop, status);
- hook_associate ("playlist activate", (HookFunction) ui_statusbar_update_playlist_length, length);
- hook_associate ("playlist update", (HookFunction) ui_statusbar_update_playlist_length, length);
-
- g_signal_connect (hbox, "destroy", (GCallback) ui_statusbar_destroy_cb, NULL);
-
- if (aud_drct_get_playing () && aud_drct_get_ready ())
- ui_statusbar_info_change (NULL, status);
-
- return hbox;
-}
diff --git a/src/gtkui/ui_statusbar.cc b/src/gtkui/ui_statusbar.cc
new file mode 100644
index 000000000000..a888eed4ff26
--- /dev/null
+++ b/src/gtkui/ui_statusbar.cc
@@ -0,0 +1,163 @@
+/*
+ * ui_statusbar.c
+ * Copyright 2010-2011 William Pitcock, MichaÅ Lipski, and John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/mainloop.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/runtime.h>
+
+#include "ui_statusbar.h"
+
+static QueuedFunc clear_timeout;
+
+static void ui_statusbar_update_playlist_length (void *, void * label)
+{
+ int playlist = aud_playlist_get_active ();
+ StringBuf s1 = str_format_time (aud_playlist_get_selected_length (playlist));
+ StringBuf s2 = str_format_time (aud_playlist_get_total_length (playlist));
+ gtk_label_set_text ((GtkLabel *) label, str_concat ({s1, " / ", s2}));
+}
+
+static void ui_statusbar_info_change (void *, void * label)
+{
+ if (clear_timeout.running ())
+ return;
+
+ Tuple tuple = aud_drct_get_tuple ();
+ String codec = tuple.get_str (Tuple::Codec);
+
+ int bitrate, samplerate, channels;
+ aud_drct_get_info (bitrate, samplerate, channels);
+
+ StringBuf buf;
+
+ if (codec)
+ {
+ buf.insert (-1, codec);
+ if (channels > 0 || samplerate > 0 || bitrate > 0)
+ buf.insert (-1, ", ");
+ }
+
+ if (channels > 0)
+ {
+ if (channels == 1)
+ buf.insert (-1, _("mono"));
+ else if (channels == 2)
+ buf.insert (-1, _("stereo"));
+ else
+ buf.combine (str_printf (ngettext ("%d channel", "%d channels", channels), channels));
+
+ if (samplerate > 0 || bitrate > 0)
+ buf.insert (-1, ", ");
+ }
+
+ if (samplerate > 0)
+ {
+ buf.combine (str_printf ("%d kHz", samplerate / 1000));
+ if (bitrate > 0)
+ buf.insert (-1, ", ");
+ }
+
+ if (bitrate > 0)
+ buf.combine (str_printf (_("%d kbps"), bitrate / 1000));
+
+ gtk_label_set_text ((GtkLabel *) label, buf);
+}
+
+static void ui_statusbar_playback_stop (void *, void * label)
+{
+ if (clear_timeout.running ())
+ return;
+
+ gtk_label_set_text ((GtkLabel *) label, nullptr);
+}
+
+static void clear_message (void * label)
+{
+ clear_timeout.stop ();
+
+ if (aud_drct_get_ready ())
+ ui_statusbar_info_change (nullptr, label);
+ else
+ gtk_label_set_text ((GtkLabel *) label, nullptr);
+}
+
+static void no_advance_toggled (void *, void * label)
+{
+ if (aud_get_bool (nullptr, "no_playlist_advance"))
+ gtk_label_set_text ((GtkLabel *) label, _("Single mode."));
+ else
+ gtk_label_set_text ((GtkLabel *) label, _("Playlist mode."));
+
+ clear_timeout.start (1000, clear_message, label);
+}
+
+static void stop_after_song_toggled (void *, void * label)
+{
+ if (aud_get_bool (nullptr, "stop_after_current_song"))
+ gtk_label_set_text ((GtkLabel *) label, _("Stopping after song."));
+
+ clear_timeout.start (1000, clear_message, label);
+}
+
+static void ui_statusbar_destroy_cb ()
+{
+ clear_timeout.stop ();
+
+ hook_dissociate ("playback ready", ui_statusbar_info_change);
+ hook_dissociate ("info change", ui_statusbar_info_change);
+ hook_dissociate ("tuple change", ui_statusbar_info_change);
+ hook_dissociate ("playback stop", ui_statusbar_playback_stop);
+ hook_dissociate ("set no_playlist_advance", no_advance_toggled);
+ hook_dissociate ("set stop_after_current_song", stop_after_song_toggled);
+ hook_dissociate ("playlist activate", ui_statusbar_update_playlist_length);
+ hook_dissociate ("playlist update", ui_statusbar_update_playlist_length);
+}
+
+GtkWidget * ui_statusbar_new ()
+{
+ GtkWidget * hbox = gtk_hbox_new (false, 3);
+ GtkWidget * status = gtk_widget_new (GTK_TYPE_LABEL, "xalign", 0.0, nullptr);
+ GtkWidget * length = gtk_widget_new (GTK_TYPE_LABEL, "xalign", 1.0, nullptr);
+
+ gtk_label_set_ellipsize ((GtkLabel *) status, PANGO_ELLIPSIZE_END);
+ gtk_box_pack_start ((GtkBox *) hbox, status, true, true, 5);
+ gtk_box_pack_start ((GtkBox *) hbox, length, false, false, 5);
+
+ ui_statusbar_update_playlist_length (nullptr, length);
+
+ hook_associate ("playback ready", ui_statusbar_info_change, status);
+ hook_associate ("info change", ui_statusbar_info_change, status);
+ hook_associate ("tuple change", ui_statusbar_info_change, status);
+ hook_associate ("playback stop", ui_statusbar_playback_stop, status);
+ hook_associate ("set no_playlist_advance", no_advance_toggled, status);
+ hook_associate ("set stop_after_current_song", stop_after_song_toggled, status);
+ hook_associate ("playlist activate", ui_statusbar_update_playlist_length, length);
+ hook_associate ("playlist update", ui_statusbar_update_playlist_length, length);
+
+ g_signal_connect (hbox, "destroy", (GCallback) ui_statusbar_destroy_cb, nullptr);
+
+ if (aud_drct_get_ready ())
+ ui_statusbar_info_change (nullptr, status);
+
+ return hbox;
+}
diff --git a/src/gtkui/ui_statusbar.h b/src/gtkui/ui_statusbar.h
index b3217fac266b..1f92d0f3d8fd 100644
--- a/src/gtkui/ui_statusbar.h
+++ b/src/gtkui/ui_statusbar.h
@@ -22,6 +22,6 @@
#include <gtk/gtk.h>
-GtkWidget * ui_statusbar_new (void);
+GtkWidget * ui_statusbar_new ();
#endif
diff --git a/src/hotkey/Makefile b/src/hotkey/Makefile
index e977d8145a98..3765d51bd717 100644
--- a/src/hotkey/Makefile
+++ b/src/hotkey/Makefile
@@ -1,12 +1,13 @@
PLUGIN = hotkey${PLUGIN_SUFFIX}
-SRCS = plugin.c gui.c grab.c
+SRCS = plugin.cc gui.cc grab.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} -I../.. -I..
-LIBS += ${GLIB_LIBS} ${GTK_LIBS} -lX11
+LIBS += ${GLIB_LIBS} ${GTK_LIBS} -lX11 -laudgui
diff --git a/src/hotkey/grab.c b/src/hotkey/grab.c
deleted file mode 100644
index b7b4e9e3434d..000000000000
--- a/src/hotkey/grab.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * This file is part of audacious-hotkey plugin for audacious
- *
- * Copyright (c) 2007 - 2008 Sascha Hlusiak <contact at saschahlusiak.de>
- * Name: grab.c
- * Description: grab.c
- *
- * Part of this code is from itouch-ctrl plugin.
- * Authors of itouch-ctrl are listed below:
- *
- * Copyright (c) 2006 - 2007 Vladimir Paskov <vlado.paskov at gmail.com>
- *
- * Part of this code are from xmms-itouch plugin.
- * Authors of xmms-itouch are listed below:
- *
- * Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>
- * Bryn Davies <curious at ihug.com.au>
- * Jonathan A. Davis <davis at jdhouse.org>
- * Jeremy Tan <nsx at nsx.homeip.net>
- *
- * audacious-hotkey 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.
- *
- * audacious-hotkey 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 audacious-hotkey; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-
-#include "grab.h"
-#include "plugin.h"
-
-
-static gint grabbed = 0;
-static unsigned int numlock_mask = 0;
-static unsigned int scrolllock_mask = 0;
-static unsigned int capslock_mask = 0;
-
-
-/* Taken from xbindkeys */
-static void get_offending_modifiers (Display * dpy)
-{
- int i;
- XModifierKeymap *modmap;
- KeyCode nlock, slock;
-
- static int mask_table[8] = {
- ShiftMask, LockMask, ControlMask, Mod1Mask,
- Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
- };
-
- nlock = XKeysymToKeycode (dpy, XK_Num_Lock);
- slock = XKeysymToKeycode (dpy, XK_Scroll_Lock);
-
- /*
- * Find out the masks for the NumLock and ScrollLock modifiers,
- * so that we can bind the grabs for when they are enabled too.
- */
- modmap = XGetModifierMapping (dpy);
-
- if (modmap != NULL && modmap->max_keypermod > 0)
- {
- for (i = 0; i < 8 * modmap->max_keypermod; i++)
- {
- if (modmap->modifiermap[i] == nlock && nlock != 0)
- numlock_mask = mask_table[i / modmap->max_keypermod];
- else if (modmap->modifiermap[i] == slock && slock != 0)
- scrolllock_mask = mask_table[i / modmap->max_keypermod];
- }
- }
-
- capslock_mask = LockMask;
-
- if (modmap)
- XFreeModifiermap (modmap);
-}
-
-
-static int x11_error_handler (Display *dpy, XErrorEvent *error)
-{
- return 0;
-}
-
-/* grab required keys */
-static void grab_key(const HotkeyConfiguration *hotkey, Display *xdisplay, Window x_root_window)
-{
- unsigned int modifier = hotkey->mask & ~(numlock_mask | capslock_mask | scrolllock_mask);
-
- if (hotkey->key == 0) return;
-
- if (hotkey->type == TYPE_KEY)
- {
- XGrabKey (xdisplay, hotkey->key, modifier, x_root_window,
- False, GrabModeAsync, GrabModeAsync);
-
- if (modifier == AnyModifier)
- return;
-
- if (numlock_mask)
- XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask,
- x_root_window,
- False, GrabModeAsync, GrabModeAsync);
-
- if (capslock_mask)
- XGrabKey (xdisplay, hotkey->key, modifier | capslock_mask,
- x_root_window,
- False, GrabModeAsync, GrabModeAsync);
-
- if (scrolllock_mask)
- XGrabKey (xdisplay, hotkey->key, modifier | scrolllock_mask,
- x_root_window,
- False, GrabModeAsync, GrabModeAsync);
-
- if (numlock_mask && capslock_mask)
- XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask,
- x_root_window,
- False, GrabModeAsync, GrabModeAsync);
-
- if (numlock_mask && scrolllock_mask)
- XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask,
- x_root_window,
- False, GrabModeAsync, GrabModeAsync);
-
- if (capslock_mask && scrolllock_mask)
- XGrabKey (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask,
- x_root_window,
- False, GrabModeAsync, GrabModeAsync);
-
- if (numlock_mask && capslock_mask && scrolllock_mask)
- XGrabKey (xdisplay, hotkey->key,
- modifier | numlock_mask | capslock_mask | scrolllock_mask,
- x_root_window, False, GrabModeAsync,
- GrabModeAsync);
- }
- if (hotkey->type == TYPE_MOUSE)
- {
- XGrabButton (xdisplay, hotkey->key, modifier, x_root_window,
- False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
-
- if (modifier == AnyModifier)
- return;
-
- if (numlock_mask)
- XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask,
- x_root_window,
- False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
-
- if (capslock_mask)
- XGrabButton (xdisplay, hotkey->key, modifier | capslock_mask,
- x_root_window,
- False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
-
- if (scrolllock_mask)
- XGrabButton (xdisplay, hotkey->key, modifier | scrolllock_mask,
- x_root_window,
- False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
-
- if (numlock_mask && capslock_mask)
- XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask,
- x_root_window,
- False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
-
- if (numlock_mask && scrolllock_mask)
- XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask,
- x_root_window,
- False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
-
- if (capslock_mask && scrolllock_mask)
- XGrabButton (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask,
- x_root_window,
- False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
-
- if (numlock_mask && capslock_mask && scrolllock_mask)
- XGrabButton (xdisplay, hotkey->key,
- modifier | numlock_mask | capslock_mask | scrolllock_mask,
- x_root_window, False, ButtonPressMask, GrabModeAsync,
- GrabModeAsync, None, None);
- }
-}
-
-void grab_keys ( )
-{
- Display* xdisplay;
- int screen;
- PluginConfig* plugin_cfg = get_config();
- HotkeyConfiguration *hotkey;
-
- XErrorHandler old_handler = 0;
- xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
-
- if (grabbed) return;
-
-
- XSync(xdisplay, False);
- old_handler = XSetErrorHandler (x11_error_handler);
-
- get_offending_modifiers(xdisplay);
- hotkey = &(plugin_cfg->first);
- while (hotkey)
- {
- for (screen=0;screen<ScreenCount(xdisplay);screen++)
- {
- grab_key(hotkey, xdisplay, RootWindow(xdisplay, screen));
- }
- hotkey = hotkey->next;
- }
-
- XSync(xdisplay, False);
- XSetErrorHandler (old_handler);
-
- grabbed = 1;
-}
-
-
-
-/* grab required keys */
-static void ungrab_key(HotkeyConfiguration *hotkey, Display* xdisplay, Window x_root_window)
-{
- unsigned int modifier = hotkey->mask & ~(numlock_mask | capslock_mask | scrolllock_mask);
-
- if (hotkey->key == 0) return;
-
- if (hotkey->type == TYPE_KEY)
- {
- XUngrabKey (xdisplay, hotkey->key, modifier, x_root_window);
-
- if (modifier == AnyModifier)
- return;
-
- if (numlock_mask)
- XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask, x_root_window);
-
- if (capslock_mask)
- XUngrabKey (xdisplay, hotkey->key, modifier | capslock_mask, x_root_window);
-
- if (scrolllock_mask)
- XUngrabKey (xdisplay, hotkey->key, modifier | scrolllock_mask, x_root_window);
-
- if (numlock_mask && capslock_mask)
- XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask, x_root_window);
-
- if (numlock_mask && scrolllock_mask)
- XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask, x_root_window);
-
- if (capslock_mask && scrolllock_mask)
- XUngrabKey (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask, x_root_window);
-
- if (numlock_mask && capslock_mask && scrolllock_mask)
- XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window);
- }
- if (hotkey->type == TYPE_MOUSE)
- {
- XUngrabButton (xdisplay, hotkey->key, modifier, x_root_window);
-
- if (modifier == AnyModifier)
- return;
-
- if (numlock_mask)
- XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask, x_root_window);
-
- if (capslock_mask)
- XUngrabButton (xdisplay, hotkey->key, modifier | capslock_mask, x_root_window);
-
- if (scrolllock_mask)
- XUngrabButton (xdisplay, hotkey->key, modifier | scrolllock_mask, x_root_window);
-
- if (numlock_mask && capslock_mask)
- XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask, x_root_window);
-
- if (numlock_mask && scrolllock_mask)
- XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask, x_root_window);
-
- if (capslock_mask && scrolllock_mask)
- XUngrabButton (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask, x_root_window);
-
- if (numlock_mask && capslock_mask && scrolllock_mask)
- XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window);
- }
-}
-
-void ungrab_keys ( )
-{
- Display* xdisplay;
- int screen;
- PluginConfig* plugin_cfg = get_config();
- HotkeyConfiguration *hotkey;
-
- XErrorHandler old_handler = 0;
- xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
-
- if (!grabbed) return;
- if (!xdisplay) return;
-
- XSync(xdisplay, False);
- old_handler = XSetErrorHandler (x11_error_handler);
-
- get_offending_modifiers(xdisplay);
-
- hotkey = &(plugin_cfg->first);
- while (hotkey)
- {
- for (screen=0;screen<ScreenCount(xdisplay);screen++)
- {
- ungrab_key(hotkey, xdisplay, RootWindow(xdisplay, screen));
- }
- hotkey = hotkey->next;
- }
-
- XSync(xdisplay, False);
- XSetErrorHandler (old_handler);
-
- grabbed = 0;
-}
-
-
-static GdkFilterReturn
-gdk_filter(GdkXEvent *xevent,
- GdkEvent *event,
- gpointer data)
-{
- HotkeyConfiguration *hotkey;
- hotkey = &(get_config()->first);
- switch (((XEvent*)xevent)->type)
- {
- case KeyPress:
- {
- XKeyEvent *keyevent = (XKeyEvent*)xevent;
- while (hotkey)
- {
- if ((hotkey->key == keyevent->keycode) &&
- (hotkey->mask == (keyevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask))) &&
- (hotkey->type == TYPE_KEY))
- {
- if (handle_keyevent(hotkey->event))
- return GDK_FILTER_REMOVE;
- break;
- }
-
- hotkey = hotkey->next;
- }
- break;
- }
- case ButtonPress:
- {
- XButtonEvent *buttonevent = (XButtonEvent*)xevent;
- while (hotkey)
- {
- if ((hotkey->key == buttonevent->button) &&
- (hotkey->mask == (buttonevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask))) &&
- (hotkey->type == TYPE_MOUSE))
- {
- if (handle_keyevent(hotkey->event))
- return GDK_FILTER_REMOVE;
- break;
- }
-
- hotkey = hotkey->next;
- }
-
- break;
- }
- }
-
- return GDK_FILTER_CONTINUE;
-}
-
-gboolean setup_filter()
-{
- gdk_window_add_filter (gdk_screen_get_root_window
- (gdk_screen_get_default ()), gdk_filter, NULL);
-
- return TRUE;
-}
-
-void release_filter()
-{
- gdk_window_remove_filter (gdk_screen_get_root_window
- (gdk_screen_get_default ()), gdk_filter, NULL);
-}
diff --git a/src/hotkey/grab.cc b/src/hotkey/grab.cc
new file mode 100644
index 000000000000..252051f0e699
--- /dev/null
+++ b/src/hotkey/grab.cc
@@ -0,0 +1,388 @@
+/*
+ * This file is part of audacious-hotkey plugin for audacious
+ *
+ * Copyright (c) 2007 - 2008 Sascha Hlusiak <contact at saschahlusiak.de>
+ * Name: grab.c
+ * Description: grab.c
+ *
+ * Part of this code is from itouch-ctrl plugin.
+ * Authors of itouch-ctrl are listed below:
+ *
+ * Copyright (c) 2006 - 2007 Vladimir Paskov <vlado.paskov at gmail.com>
+ *
+ * Part of this code are from xmms-itouch plugin.
+ * Authors of xmms-itouch are listed below:
+ *
+ * Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>
+ * Bryn Davies <curious at ihug.com.au>
+ * Jonathan A. Davis <davis at jdhouse.org>
+ * Jeremy Tan <nsx at nsx.homeip.net>
+ *
+ * audacious-hotkey 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.
+ *
+ * audacious-hotkey 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 audacious-hotkey; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include "grab.h"
+#include "plugin.h"
+
+
+static int grabbed = 0;
+static unsigned int numlock_mask = 0;
+static unsigned int scrolllock_mask = 0;
+static unsigned int capslock_mask = 0;
+
+
+/* Taken from xbindkeys */
+static void get_offending_modifiers (Display * dpy)
+{
+ int i;
+ XModifierKeymap *modmap;
+ KeyCode nlock, slock;
+
+ static int mask_table[8] = {
+ ShiftMask, LockMask, ControlMask, Mod1Mask,
+ Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
+ };
+
+ nlock = XKeysymToKeycode (dpy, XK_Num_Lock);
+ slock = XKeysymToKeycode (dpy, XK_Scroll_Lock);
+
+ /*
+ * Find out the masks for the NumLock and ScrollLock modifiers,
+ * so that we can bind the grabs for when they are enabled too.
+ */
+ modmap = XGetModifierMapping (dpy);
+
+ if (modmap != nullptr && modmap->max_keypermod > 0)
+ {
+ for (i = 0; i < 8 * modmap->max_keypermod; i++)
+ {
+ if (modmap->modifiermap[i] == nlock && nlock != 0)
+ numlock_mask = mask_table[i / modmap->max_keypermod];
+ else if (modmap->modifiermap[i] == slock && slock != 0)
+ scrolllock_mask = mask_table[i / modmap->max_keypermod];
+ }
+ }
+
+ capslock_mask = LockMask;
+
+ if (modmap)
+ XFreeModifiermap (modmap);
+}
+
+
+static int x11_error_handler (Display *dpy, XErrorEvent *error)
+{
+ return 0;
+}
+
+/* grab required keys */
+static void grab_key(const HotkeyConfiguration *hotkey, Display *xdisplay, Window x_root_window)
+{
+ unsigned int modifier = hotkey->mask & ~(numlock_mask | capslock_mask | scrolllock_mask);
+
+ if (hotkey->key == 0) return;
+
+ if (hotkey->type == TYPE_KEY)
+ {
+ XGrabKey (xdisplay, hotkey->key, modifier, x_root_window,
+ False, GrabModeAsync, GrabModeAsync);
+
+ if (modifier == AnyModifier)
+ return;
+
+ if (numlock_mask)
+ XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask,
+ x_root_window,
+ False, GrabModeAsync, GrabModeAsync);
+
+ if (capslock_mask)
+ XGrabKey (xdisplay, hotkey->key, modifier | capslock_mask,
+ x_root_window,
+ False, GrabModeAsync, GrabModeAsync);
+
+ if (scrolllock_mask)
+ XGrabKey (xdisplay, hotkey->key, modifier | scrolllock_mask,
+ x_root_window,
+ False, GrabModeAsync, GrabModeAsync);
+
+ if (numlock_mask && capslock_mask)
+ XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask,
+ x_root_window,
+ False, GrabModeAsync, GrabModeAsync);
+
+ if (numlock_mask && scrolllock_mask)
+ XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask,
+ x_root_window,
+ False, GrabModeAsync, GrabModeAsync);
+
+ if (capslock_mask && scrolllock_mask)
+ XGrabKey (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask,
+ x_root_window,
+ False, GrabModeAsync, GrabModeAsync);
+
+ if (numlock_mask && capslock_mask && scrolllock_mask)
+ XGrabKey (xdisplay, hotkey->key,
+ modifier | numlock_mask | capslock_mask | scrolllock_mask,
+ x_root_window, False, GrabModeAsync,
+ GrabModeAsync);
+ }
+ if (hotkey->type == TYPE_MOUSE)
+ {
+ XGrabButton (xdisplay, hotkey->key, modifier, x_root_window,
+ False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
+
+ if (modifier == AnyModifier)
+ return;
+
+ if (numlock_mask)
+ XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask,
+ x_root_window,
+ False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
+
+ if (capslock_mask)
+ XGrabButton (xdisplay, hotkey->key, modifier | capslock_mask,
+ x_root_window,
+ False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
+
+ if (scrolllock_mask)
+ XGrabButton (xdisplay, hotkey->key, modifier | scrolllock_mask,
+ x_root_window,
+ False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
+
+ if (numlock_mask && capslock_mask)
+ XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask,
+ x_root_window,
+ False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
+
+ if (numlock_mask && scrolllock_mask)
+ XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask,
+ x_root_window,
+ False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
+
+ if (capslock_mask && scrolllock_mask)
+ XGrabButton (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask,
+ x_root_window,
+ False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
+
+ if (numlock_mask && capslock_mask && scrolllock_mask)
+ XGrabButton (xdisplay, hotkey->key,
+ modifier | numlock_mask | capslock_mask | scrolllock_mask,
+ x_root_window, False, ButtonPressMask, GrabModeAsync,
+ GrabModeAsync, None, None);
+ }
+}
+
+void grab_keys ( )
+{
+ Display* xdisplay;
+ int screen;
+ PluginConfig* plugin_cfg = get_config();
+ HotkeyConfiguration *hotkey;
+
+ XErrorHandler old_handler = 0;
+ xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
+
+ if (grabbed) return;
+
+
+ XSync(xdisplay, False);
+ old_handler = XSetErrorHandler (x11_error_handler);
+
+ get_offending_modifiers(xdisplay);
+ hotkey = &(plugin_cfg->first);
+ while (hotkey)
+ {
+ for (screen=0;screen<ScreenCount(xdisplay);screen++)
+ {
+ grab_key(hotkey, xdisplay, RootWindow(xdisplay, screen));
+ }
+ hotkey = hotkey->next;
+ }
+
+ XSync(xdisplay, False);
+ XSetErrorHandler (old_handler);
+
+ grabbed = 1;
+}
+
+
+
+/* grab required keys */
+static void ungrab_key(HotkeyConfiguration *hotkey, Display* xdisplay, Window x_root_window)
+{
+ unsigned int modifier = hotkey->mask & ~(numlock_mask | capslock_mask | scrolllock_mask);
+
+ if (hotkey->key == 0) return;
+
+ if (hotkey->type == TYPE_KEY)
+ {
+ XUngrabKey (xdisplay, hotkey->key, modifier, x_root_window);
+
+ if (modifier == AnyModifier)
+ return;
+
+ if (numlock_mask)
+ XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask, x_root_window);
+
+ if (capslock_mask)
+ XUngrabKey (xdisplay, hotkey->key, modifier | capslock_mask, x_root_window);
+
+ if (scrolllock_mask)
+ XUngrabKey (xdisplay, hotkey->key, modifier | scrolllock_mask, x_root_window);
+
+ if (numlock_mask && capslock_mask)
+ XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask, x_root_window);
+
+ if (numlock_mask && scrolllock_mask)
+ XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask, x_root_window);
+
+ if (capslock_mask && scrolllock_mask)
+ XUngrabKey (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask, x_root_window);
+
+ if (numlock_mask && capslock_mask && scrolllock_mask)
+ XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window);
+ }
+ if (hotkey->type == TYPE_MOUSE)
+ {
+ XUngrabButton (xdisplay, hotkey->key, modifier, x_root_window);
+
+ if (modifier == AnyModifier)
+ return;
+
+ if (numlock_mask)
+ XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask, x_root_window);
+
+ if (capslock_mask)
+ XUngrabButton (xdisplay, hotkey->key, modifier | capslock_mask, x_root_window);
+
+ if (scrolllock_mask)
+ XUngrabButton (xdisplay, hotkey->key, modifier | scrolllock_mask, x_root_window);
+
+ if (numlock_mask && capslock_mask)
+ XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask, x_root_window);
+
+ if (numlock_mask && scrolllock_mask)
+ XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask, x_root_window);
+
+ if (capslock_mask && scrolllock_mask)
+ XUngrabButton (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask, x_root_window);
+
+ if (numlock_mask && capslock_mask && scrolllock_mask)
+ XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window);
+ }
+}
+
+void ungrab_keys ( )
+{
+ Display* xdisplay;
+ int screen;
+ PluginConfig* plugin_cfg = get_config();
+ HotkeyConfiguration *hotkey;
+
+ XErrorHandler old_handler = 0;
+ xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
+
+ if (!grabbed) return;
+ if (!xdisplay) return;
+
+ XSync(xdisplay, False);
+ old_handler = XSetErrorHandler (x11_error_handler);
+
+ get_offending_modifiers(xdisplay);
+
+ hotkey = &(plugin_cfg->first);
+ while (hotkey)
+ {
+ for (screen=0;screen<ScreenCount(xdisplay);screen++)
+ {
+ ungrab_key(hotkey, xdisplay, RootWindow(xdisplay, screen));
+ }
+ hotkey = hotkey->next;
+ }
+
+ XSync(xdisplay, False);
+ XSetErrorHandler (old_handler);
+
+ grabbed = 0;
+}
+
+
+static GdkFilterReturn
+gdk_filter(GdkXEvent *xevent,
+ GdkEvent *event,
+ void * data)
+{
+ HotkeyConfiguration *hotkey;
+ hotkey = &(get_config()->first);
+ switch (((XEvent*)xevent)->type)
+ {
+ case KeyPress:
+ {
+ XKeyEvent *keyevent = (XKeyEvent*)xevent;
+ while (hotkey)
+ {
+ if ((hotkey->key == keyevent->keycode) &&
+ (hotkey->mask == (keyevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask))) &&
+ (hotkey->type == TYPE_KEY))
+ {
+ if (handle_keyevent(hotkey->event))
+ return GDK_FILTER_REMOVE;
+ break;
+ }
+
+ hotkey = hotkey->next;
+ }
+ break;
+ }
+ case ButtonPress:
+ {
+ XButtonEvent *buttonevent = (XButtonEvent*)xevent;
+ while (hotkey)
+ {
+ if ((hotkey->key == buttonevent->button) &&
+ (hotkey->mask == (buttonevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask))) &&
+ (hotkey->type == TYPE_MOUSE))
+ {
+ if (handle_keyevent(hotkey->event))
+ return GDK_FILTER_REMOVE;
+ break;
+ }
+
+ hotkey = hotkey->next;
+ }
+
+ break;
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+gboolean setup_filter()
+{
+ gdk_window_add_filter (gdk_screen_get_root_window
+ (gdk_screen_get_default ()), gdk_filter, nullptr);
+
+ return TRUE;
+}
+
+void release_filter()
+{
+ gdk_window_remove_filter (gdk_screen_get_root_window
+ (gdk_screen_get_default ()), gdk_filter, nullptr);
+}
diff --git a/src/hotkey/gui.c b/src/hotkey/gui.c
deleted file mode 100644
index acf133160984..000000000000
--- a/src/hotkey/gui.c
+++ /dev/null
@@ -1,650 +0,0 @@
-/*
- * This file is part of audacious-hotkey plugin for audacious
- *
- * Copyright (c) 2007 - 2008 Sascha Hlusiak <contact at saschahlusiak.de>
- * Name: gui.c
- * Description: gui.c
- *
- * Part of this code is from itouch-ctrl plugin.
- * Authors of itouch-ctrl are listed below:
- *
- * Copyright (c) 2006 - 2007 Vladimir Paskov <vlado.paskov at gmail.com>
- *
- * Part of this code are from xmms-itouch plugin.
- * Authors of xmms-itouch are listed below:
- *
- * Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>
- * Bryn Davies <curious at ihug.com.au>
- * Jonathan A. Davis <davis at jdhouse.org>
- * Jeremy Tan <nsx at nsx.homeip.net>
- *
- * audacious-hotkey 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.
- *
- * audacious-hotkey 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 audacious-hotkey; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-#include <gdk/gdkkeysyms-compat.h>
-
-#include <audacious/plugin.h>
-#include <audacious/i18n.h>
-#include <libaudgui/libaudgui.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include <X11/XKBlib.h>
-
-#include "plugin.h"
-#include "gui.h"
-#include "grab.h"
-
-typedef struct _KeyControls {
- GtkWidget *keytext;
- GtkWidget *grid;
- GtkWidget *button;
- GtkWidget *combobox;
-
- HotkeyConfiguration hotkey;
- struct _KeyControls *next, *prev, *first;
-} KeyControls;
-
-
-static void clear_keyboard (GtkWidget *widget, gpointer data);
-static void add_callback (GtkWidget *widget, gpointer data);
-static void cancel_callback (GtkWidget *widget, gpointer data);
-static void destroy_callback (GtkWidget *widget, gpointer data);
-static void ok_callback (GtkWidget *widget, gpointer data);
-
-
-static gchar* event_desc[EVENT_MAX] = {
- [EVENT_PREV_TRACK] = N_("Previous track"),
- [EVENT_PLAY] = N_("Play"),
- [EVENT_PAUSE] = N_("Pause/Resume"),
- [EVENT_STOP] = N_("Stop"),
- [EVENT_NEXT_TRACK] = N_("Next track"),
- [EVENT_FORWARD] = N_("Forward 5 seconds"),
- [EVENT_BACKWARD] = N_("Rewind 5 seconds"),
- [EVENT_MUTE] = N_("Mute"),
- [EVENT_VOL_UP] = N_("Volume up"),
- [EVENT_VOL_DOWN] = N_("Volume down"),
- [EVENT_JUMP_TO_FILE] = N_("Jump to file"),
- [EVENT_TOGGLE_WIN] = N_("Toggle player window(s)"),
- [EVENT_SHOW_AOSD] = N_("Show On-Screen-Display"),
- [EVENT_TOGGLE_REPEAT] = N_("Toggle repeat"),
- [EVENT_TOGGLE_SHUFFLE] = N_("Toggle shuffle"),
- [EVENT_TOGGLE_STOP] = N_("Toggle stop after current"),
- [EVENT_RAISE] = N_("Raise player window(s)")
-};
-
-
-static void set_keytext (GtkWidget *entry, gint key, gint mask, gint type)
-{
- gchar *text = NULL;
-
- if (key == 0 && mask == 0)
- {
- text = g_strdup(_("(none)"));
- } else {
- static char *modifier_string[] = { "Control", "Shift", "Alt", "Mod2", "Mod3", "Super", "Mod5" };
- static unsigned int modifiers[] = { ControlMask, ShiftMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask };
- gchar *strings[9];
- gchar *keytext = NULL;
- int i, j;
- if (type == TYPE_KEY)
- {
- KeySym keysym;
- keysym = XkbKeycodeToKeysym(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), key, 0, 0);
- if (keysym == 0 || keysym == NoSymbol)
- {
- keytext = g_strdup_printf("#%d", key);
- } else {
- keytext = g_strdup(XKeysymToString(keysym));
- }
- }
- if (type == TYPE_MOUSE)
- {
- keytext = g_strdup_printf("Button%d", key);
- }
-
- for (i = 0, j=0; j<7; j++)
- {
- if (mask & modifiers[j])
- strings[i++] = modifier_string[j];
- }
- if (key != 0) strings[i++] = keytext;
- strings[i] = NULL;
-
- text = g_strjoinv(" + ", strings);
- g_free(keytext);
- }
-
- gtk_entry_set_text(GTK_ENTRY(entry), text);
- gtk_editable_set_position(GTK_EDITABLE(entry), -1);
- if (text) g_free(text);
-}
-
-static gboolean
-on_entry_key_press_event(GtkWidget * widget,
- GdkEventKey * event,
- gpointer user_data)
-{
- KeyControls *controls = (KeyControls*) user_data;
- int is_mod;
- int mod;
-
- if (event->keyval == GDK_Tab) return FALSE;
- if (event->keyval == GDK_Escape && ((event->state & ~GDK_LOCK_MASK) == 0)) return FALSE;
- if (event->keyval == GDK_Return && ((event->state & ~GDK_LOCK_MASK) == 0)) return FALSE;
- if (event->keyval == GDK_ISO_Left_Tab)
- {
- set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type);
- return FALSE;
- }
- if (event->keyval == GDK_Up && ((event->state & ~GDK_LOCK_MASK) == 0)) return FALSE;
- if (event->keyval == GDK_Down && ((event->state & ~GDK_LOCK_MASK) == 0)) return FALSE;
-
- mod = 0;
- is_mod = 0;
-
- if ((event->state & GDK_CONTROL_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R))))
- mod |= ControlMask;
-
- if ((event->state & GDK_MOD1_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Alt_L || event->keyval == GDK_Alt_R))))
- mod |= Mod1Mask;
-
- if ((event->state & GDK_SHIFT_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R))))
- mod |= ShiftMask;
-
- if ((event->state & GDK_MOD5_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_ISO_Level3_Shift))))
- mod |= Mod5Mask;
-
- if ((event->state & GDK_MOD4_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Super_L || event->keyval == GDK_Super_R))))
- mod |= Mod4Mask;
-
- if (!is_mod) {
- controls->hotkey.key = event->hardware_keycode;
- controls->hotkey.mask = mod;
- controls->hotkey.type = TYPE_KEY;
- if (controls->next == NULL)
- add_callback (NULL, (gpointer) controls);
- else gtk_widget_grab_focus(GTK_WIDGET(controls->next->keytext));
- }
-
- set_keytext(controls->keytext, is_mod ? 0 : event->hardware_keycode, mod, TYPE_KEY);
- return TRUE;
-}
-
-static gboolean
-on_entry_key_release_event(GtkWidget * widget,
- GdkEventKey * event,
- gpointer user_data)
-{
- KeyControls *controls = (KeyControls*) user_data;
- if (!gtk_widget_is_focus(widget)) return FALSE;
- set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type);
-
- return TRUE;
-}
-
-static gboolean
-on_entry_button_press_event(GtkWidget * widget,
- GdkEventButton * event,
- gpointer user_data)
-{
- KeyControls *controls = (KeyControls*) user_data;
- int mod;
-
- if (!gtk_widget_is_focus(widget)) return FALSE;
-
- mod = 0;
- if (event->state & GDK_CONTROL_MASK)
- mod |= ControlMask;
-
- if (event->state & GDK_MOD1_MASK)
- mod |= Mod1Mask;
-
- if (event->state & GDK_SHIFT_MASK)
- mod |= ShiftMask;
-
- if (event->state & GDK_MOD5_MASK)
- mod |= Mod5Mask;
-
- if (event->state & GDK_MOD4_MASK)
- mod |= Mod4Mask;
-
- if ((event->button <= 3) && (mod == 0))
- {
- GtkWidget* dialog;
- GtkResponseType response;
- dialog = gtk_message_dialog_new (GTK_WINDOW(gtk_widget_get_toplevel(widget)),
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_YES_NO,
- _("It is not recommended to bind the primary mouse buttons without modificators.\n\n"
- "Do you want to continue?"));
- gtk_window_set_title(GTK_WINDOW(dialog), _("Binding mouse buttons"));
- response = gtk_dialog_run(GTK_DIALOG(dialog));
- gtk_widget_destroy (dialog);
- if (response != GTK_RESPONSE_YES) return TRUE;
- }
-
- controls->hotkey.key = event->button;
- controls->hotkey.mask = mod;
- controls->hotkey.type = TYPE_MOUSE;
- set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type);
- if (controls->next == NULL)
- add_callback (NULL, (gpointer) controls);
-
- return TRUE;
-}
-
-static gboolean
-on_entry_scroll_event(GtkWidget * widget,
- GdkEventScroll * event,
- gpointer user_data)
-{
- KeyControls *controls = (KeyControls*) user_data;
- int mod;
-
- if (!gtk_widget_is_focus(widget)) return FALSE;
-
- mod = 0;
- if (event->state & GDK_CONTROL_MASK)
- mod |= ControlMask;
-
- if (event->state & GDK_MOD1_MASK)
- mod |= Mod1Mask;
-
- if (event->state & GDK_SHIFT_MASK)
- mod |= ShiftMask;
-
- if (event->state & GDK_MOD5_MASK)
- mod |= Mod5Mask;
-
- if (event->state & GDK_MOD4_MASK)
- mod |= Mod4Mask;
-
- if (event->direction == GDK_SCROLL_UP)
- controls->hotkey.key = 4;
- else if (event->direction == GDK_SCROLL_DOWN)
- controls->hotkey.key = 5;
- else if (event->direction == GDK_SCROLL_LEFT)
- controls->hotkey.key = 6;
- else if (event->direction == GDK_SCROLL_RIGHT)
- controls->hotkey.key = 7;
- else return FALSE;
-
- controls->hotkey.mask = mod;
- controls->hotkey.type = TYPE_MOUSE;
- set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type);
- if (controls->next == NULL)
- add_callback (NULL, (gpointer) controls);
- return TRUE;
-}
-
-KeyControls* add_event_controls(KeyControls* list,
- GtkWidget *grid,
- int row,
- HotkeyConfiguration *hotkey)
-{
- KeyControls *controls;
- int i;
-
- controls = (KeyControls*) g_malloc(sizeof(KeyControls));
- controls->next = NULL;
- controls->prev = list;
- controls->first = list->first;
- controls->grid = grid;
- list->next = controls;
-
- if (hotkey)
- {
- controls->hotkey.key = hotkey->key;
- controls->hotkey.mask = hotkey->mask;
- controls->hotkey.type = hotkey->type;
- controls->hotkey.event = hotkey->event;
- if (controls->hotkey.key == 0)
- controls->hotkey.mask = 0;
- } else {
- controls->hotkey.key = 0;
- controls->hotkey.mask = 0;
- controls->hotkey.type = TYPE_KEY;
- controls->hotkey.event = 0;
- }
-
- controls->combobox = gtk_combo_box_text_new();
- gtk_widget_set_hexpand(controls->combobox, TRUE);
- for (i=0;i<EVENT_MAX;i++)
- {
- gtk_combo_box_text_append_text((GtkComboBoxText *) controls->combobox, _(event_desc[i]));
- }
- gtk_combo_box_set_active(GTK_COMBO_BOX(controls->combobox), controls->hotkey.event);
- gtk_grid_attach (GTK_GRID (grid), controls->combobox, 0, row, 1, 1);
-
-
- controls->keytext = gtk_entry_new ();
- gtk_widget_set_hexpand (controls->keytext, TRUE);
- gtk_grid_attach (GTK_GRID (grid), controls->keytext, 1, row, 1, 1);
- gtk_editable_set_editable(GTK_EDITABLE(controls->keytext), FALSE);
-
-
- set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type);
- g_signal_connect((gpointer)controls->keytext, "key_press_event",
- G_CALLBACK(on_entry_key_press_event), controls);
- g_signal_connect((gpointer)controls->keytext, "key_release_event",
- G_CALLBACK(on_entry_key_release_event), controls);
- g_signal_connect((gpointer)controls->keytext, "button_press_event",
- G_CALLBACK(on_entry_button_press_event), controls);
- g_signal_connect((gpointer)controls->keytext, "scroll_event",
- G_CALLBACK(on_entry_scroll_event), controls);
-
-
- controls->button = gtk_button_new();
- gtk_button_set_image (GTK_BUTTON (controls->button),
- gtk_image_new_from_icon_name ("edit-delete", GTK_ICON_SIZE_BUTTON));
- gtk_grid_attach (GTK_GRID (grid), controls->button, 2, row, 1, 1);
- g_signal_connect (G_OBJECT (controls->button), "clicked",
- G_CALLBACK (clear_keyboard), controls);
-
- gtk_widget_grab_focus(GTK_WIDGET(controls->keytext));
- return controls;
-}
-
-void show_configure ()
-{
- KeyControls *first_controls, *current_controls;
- GtkWidget *window;
- GtkWidget *main_vbox, *hbox;
- GtkWidget *alignment;
- GtkWidget *frame;
- GtkWidget *label;
- GtkWidget *image;
- GtkWidget *grid;
- GtkWidget *button_box, *button;
- PluginConfig* plugin_cfg;
- HotkeyConfiguration *hotkey, temphotkey;
- int i;
-
- load_config ( );
-
- plugin_cfg = get_config();
-
- ungrab_keys();
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW (window), _("Global Hotkey Plugin Configuration"));
- gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DIALOG);
- gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
- gtk_container_set_border_width (GTK_CONTAINER (window), 5);
-
- main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
- gtk_container_add (GTK_CONTAINER (window), main_vbox);
-
- alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
- gtk_box_pack_start (GTK_BOX (main_vbox), alignment, FALSE, TRUE, 0);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 4, 0, 0, 0);
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
- gtk_container_add (GTK_CONTAINER (alignment), hbox);
- image = gtk_image_new_from_icon_name ("dialog-information", GTK_ICON_SIZE_DIALOG);
- gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0);
- label = gtk_label_new (_("Press a key combination inside a text field.\nYou can also bind mouse buttons."));
- gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-
- label = gtk_label_new (NULL);
- gtk_label_set_markup (GTK_LABEL (label), _("Hotkeys:"));
- frame = gtk_frame_new (NULL);
- gtk_frame_set_label_widget (GTK_FRAME (frame), label);
- gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
- alignment = gtk_alignment_new (0, 0, 1, 0);
- gtk_container_add (GTK_CONTAINER (frame), alignment);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 3, 3, 3, 3);
-
- grid = gtk_grid_new ();
- gtk_grid_set_column_spacing (GTK_GRID (grid), 2);
- gtk_container_add (GTK_CONTAINER (alignment), grid);
-
- label = gtk_label_new (NULL);
- gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
- gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
- gtk_label_set_markup (GTK_LABEL (label),
- _("<b>Action:</b>"));
- gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
-
- label = gtk_label_new (NULL);
- gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
- gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
- gtk_label_set_markup (GTK_LABEL (label),
- _("<b>Key Binding:</b>"));
- gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
-
-
- hotkey = &(plugin_cfg->first);
- i = 1;
- first_controls = (KeyControls*) g_malloc(sizeof(KeyControls));
- first_controls->next = NULL;
- first_controls->prev = NULL;
- first_controls->grid = grid;
- first_controls->button = NULL;
- first_controls->combobox = NULL;
- first_controls->keytext = NULL;
- first_controls->first = first_controls;
- first_controls->hotkey.key = 0;
- first_controls->hotkey.mask = 0;
- first_controls->hotkey.event = 0;
- first_controls->hotkey.type = TYPE_KEY;
- current_controls = first_controls;
- if (hotkey -> key != 0)
- {
- while (hotkey)
- {
- current_controls = add_event_controls(current_controls, grid, i, hotkey);
- hotkey = hotkey->next;
- i++;
- }
- }
- temphotkey.key = 0;
- temphotkey.mask = 0;
- temphotkey.type = TYPE_KEY;
- if (current_controls != first_controls)
- temphotkey.event = current_controls->hotkey.event+1;
- else temphotkey.event = 0;
- if (temphotkey.event >= EVENT_MAX) temphotkey.event = 0;
- add_event_controls(current_controls, grid, i, &temphotkey);
-
-
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
-
- button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_box_pack_start (GTK_BOX (hbox), button_box, FALSE, TRUE, 0);
- gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box), GTK_BUTTONBOX_START);
- gtk_box_set_spacing (GTK_BOX (button_box), 4);
-
- button = audgui_button_new (_("_Add"), "list-add", NULL, NULL);
- gtk_container_add (GTK_CONTAINER (button_box), button);
- g_signal_connect (G_OBJECT (button), "clicked",
- G_CALLBACK (add_callback), first_controls);
-
- button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_box_pack_start (GTK_BOX (hbox), button_box, TRUE, TRUE, 0);
- gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box), GTK_BUTTONBOX_END);
- gtk_box_set_spacing (GTK_BOX (button_box), 4);
-
- button = audgui_button_new (_("_Cancel"), "process-stop", NULL, NULL);
- gtk_container_add (GTK_CONTAINER (button_box), button);
- g_signal_connect (G_OBJECT (button), "clicked",
- G_CALLBACK (cancel_callback), NULL);
-
- button = audgui_button_new (_("_Set"), "system-run", NULL, NULL);
- gtk_container_add (GTK_CONTAINER (button_box), button);
- g_signal_connect (G_OBJECT (button), "clicked",
- G_CALLBACK (ok_callback), first_controls);
-
- g_signal_connect (G_OBJECT (window), "destroy",
- G_CALLBACK (destroy_callback), first_controls);
-
- gtk_widget_show_all (GTK_WIDGET (window));
-}
-
-static void clear_keyboard (GtkWidget *widget, gpointer data)
-{
- KeyControls *controls= (KeyControls*)data;
-
- if ((controls->next == NULL) && (controls->prev->keytext == NULL))
- {
- controls->hotkey.key = 0;
- controls->hotkey.mask = 0;
- controls->hotkey.type = TYPE_KEY;
- set_keytext(controls->keytext, 0, 0, TYPE_KEY);
- gtk_combo_box_set_active( GTK_COMBO_BOX(controls->combobox), 0);
- return;
- }
-
- if (controls->prev)
- {
- KeyControls* c;
- GtkWidget* grid;
- int row;
-
- gtk_widget_destroy(GTK_WIDGET(controls->button));
- gtk_widget_destroy(GTK_WIDGET(controls->keytext));
- gtk_widget_destroy(GTK_WIDGET(controls->combobox));
-
- row=0;
- c = controls->first;
- while (c) {
- if (c == controls) break;
- row++;
- c = c->next;
- }
- c = controls->next;
- controls->prev->next = controls->next;
- if (controls->next)
- controls->next->prev = controls->prev;
- g_free(controls);
- if (c) grid = c->grid; else grid = NULL;
- while (c)
- {
- g_object_ref(c->combobox);
- g_object_ref(c->keytext);
- g_object_ref(c->button);
-
- gtk_container_remove( GTK_CONTAINER(c->grid) , c->combobox);
- gtk_container_remove( GTK_CONTAINER(c->grid) , c->keytext);
- gtk_container_remove( GTK_CONTAINER(c->grid) , c->button);
-
- gtk_grid_attach (GTK_GRID (c->grid), c->combobox, 0, row, 1, 1);
- gtk_grid_attach (GTK_GRID (c->grid), c->keytext, 1, row, 1, 1);
- gtk_grid_attach (GTK_GRID (c->grid), c->button, 2, row, 1, 1);
-
- g_object_unref(c->combobox);
- g_object_unref(c->keytext);
- g_object_unref(c->button);
-
- c = c->next;
- row++;
- }
- if (grid)
- gtk_widget_show_all (GTK_WIDGET (grid));
-
- return;
- }
-}
-
-void add_callback (GtkWidget *widget, gpointer data)
-{
- KeyControls* controls = (KeyControls*)data;
- HotkeyConfiguration temphotkey;
- int count;
- if (controls == NULL) return;
- if ((controls->next == NULL)&&(controls->hotkey.event+1 == EVENT_MAX)) return;
- controls = controls->first;
- if (controls == NULL) return;
- count = 1;
- while (controls->next) {
- controls = controls->next;
- count = count + 1;
- }
- temphotkey.key = 0;
- temphotkey.mask = 0;
- temphotkey.type = TYPE_KEY;
- temphotkey.event = controls->hotkey.event+1;
- if (temphotkey.event >= EVENT_MAX) temphotkey.event = 0;
- add_event_controls(controls, controls->grid, count, &temphotkey);
- gtk_widget_show_all (GTK_WIDGET (controls->grid));
-}
-
-void destroy_callback (GtkWidget *widget, gpointer data)
-{
- KeyControls* controls = (KeyControls*)data;
- if (is_loaded())
- {
- grab_keys ();
- }
- while (controls) {
- KeyControls *old;
- old = controls;
- controls = controls->next;
- g_free(old);
- }
-}
-
-void cancel_callback (GtkWidget *widget, gpointer data)
-{
- gtk_widget_destroy (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
-}
-
-void ok_callback (GtkWidget *widget, gpointer data)
-{
- KeyControls *controls = (KeyControls*)data;
- PluginConfig* plugin_cfg = get_config();
- HotkeyConfiguration *hotkey;
-
- hotkey = &(plugin_cfg->first);
- hotkey = hotkey->next;
- while (hotkey)
- {
- HotkeyConfiguration * old;
- old = hotkey;
- hotkey = hotkey->next;
- g_free(old);
- }
- plugin_cfg->first.next = NULL;
- plugin_cfg->first.key = 0;
- plugin_cfg->first.event = 0;
- plugin_cfg->first.mask = 0;
-
- hotkey = &(plugin_cfg->first);
- while (controls)
- {
- if (controls->hotkey.key) {
- if (hotkey->key) {
- hotkey->next = g_new(HotkeyConfiguration, 1);
- hotkey = hotkey->next;
- hotkey->next = NULL;
- }
- hotkey->key = controls->hotkey.key;
- hotkey->mask = controls->hotkey.mask;
- hotkey->event = gtk_combo_box_get_active( GTK_COMBO_BOX(controls->combobox) );
- hotkey->type = controls->hotkey.type;
- }
- controls = controls->next;
- }
-
- save_config ( );
-
- gtk_widget_destroy (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
-}
diff --git a/src/hotkey/gui.cc b/src/hotkey/gui.cc
new file mode 100644
index 000000000000..4f7c413de572
--- /dev/null
+++ b/src/hotkey/gui.cc
@@ -0,0 +1,631 @@
+/*
+ * This file is part of audacious-hotkey plugin for audacious
+ *
+ * Copyright (c) 2007 - 2008 Sascha Hlusiak <contact at saschahlusiak.de>
+ * Name: gui.c
+ * Description: gui.c
+ *
+ * Part of this code is from itouch-ctrl plugin.
+ * Authors of itouch-ctrl are listed below:
+ *
+ * Copyright (c) 2006 - 2007 Vladimir Paskov <vlado.paskov at gmail.com>
+ *
+ * Part of this code are from xmms-itouch plugin.
+ * Authors of xmms-itouch are listed below:
+ *
+ * Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>
+ * Bryn Davies <curious at ihug.com.au>
+ * Jonathan A. Davis <davis at jdhouse.org>
+ * Jeremy Tan <nsx at nsx.homeip.net>
+ *
+ * audacious-hotkey 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.
+ *
+ * audacious-hotkey 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 audacious-hotkey; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/preferences.h>
+
+#include <libaudgui/libaudgui-gtk.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms-compat.h>
+
+#include <X11/XKBlib.h>
+
+#include "plugin.h"
+#include "gui.h"
+#include "grab.h"
+
+typedef struct _KeyControls {
+ GtkWidget *keytext;
+ GtkWidget *grid;
+ GtkWidget *button;
+ GtkWidget *combobox;
+
+ HotkeyConfiguration hotkey;
+ struct _KeyControls *next, *prev, *first;
+} KeyControls;
+
+static KeyControls *first_controls;
+
+
+static void clear_keyboard (GtkWidget *widget, void * data);
+static void add_callback (GtkWidget *widget, void * data);
+static void destroy_callback ();
+static void ok_callback ();
+
+
+static const char * event_desc[EVENT_MAX] = {
+ [EVENT_PREV_TRACK] = N_("Previous track"),
+ [EVENT_PLAY] = N_("Play"),
+ [EVENT_PAUSE] = N_("Pause/Resume"),
+ [EVENT_STOP] = N_("Stop"),
+ [EVENT_NEXT_TRACK] = N_("Next track"),
+ [EVENT_FORWARD] = N_("Forward 5 seconds"),
+ [EVENT_BACKWARD] = N_("Rewind 5 seconds"),
+ [EVENT_MUTE] = N_("Mute"),
+ [EVENT_VOL_UP] = N_("Volume up"),
+ [EVENT_VOL_DOWN] = N_("Volume down"),
+ [EVENT_JUMP_TO_FILE] = N_("Jump to file"),
+ [EVENT_TOGGLE_WIN] = N_("Toggle player window(s)"),
+ [EVENT_SHOW_AOSD] = N_("Show On-Screen-Display"),
+ [EVENT_TOGGLE_REPEAT] = N_("Toggle repeat"),
+ [EVENT_TOGGLE_SHUFFLE] = N_("Toggle shuffle"),
+ [EVENT_TOGGLE_STOP] = N_("Toggle stop after current"),
+ [EVENT_RAISE] = N_("Raise player window(s)")
+};
+
+
+static void set_keytext (GtkWidget *entry, int key, int mask, int type)
+{
+ char *text = nullptr;
+
+ if (key == 0 && mask == 0)
+ {
+ text = g_strdup(_("(none)"));
+ } else {
+ static const char *modifier_string[] = { "Control", "Shift", "Alt", "Mod2", "Mod3", "Super", "Mod5" };
+ static const unsigned int modifiers[] = { ControlMask, ShiftMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask };
+ const char *strings[9];
+ char *keytext = nullptr;
+ int i, j;
+ if (type == TYPE_KEY)
+ {
+ KeySym keysym;
+ keysym = XkbKeycodeToKeysym(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), key, 0, 0);
+ if (keysym == 0 || keysym == NoSymbol)
+ {
+ keytext = g_strdup_printf("#%d", key);
+ } else {
+ keytext = g_strdup(XKeysymToString(keysym));
+ }
+ }
+ if (type == TYPE_MOUSE)
+ {
+ keytext = g_strdup_printf("Button%d", key);
+ }
+
+ for (i = 0, j=0; j<7; j++)
+ {
+ if (mask & modifiers[j])
+ strings[i++] = modifier_string[j];
+ }
+ if (key != 0) strings[i++] = keytext;
+ strings[i] = nullptr;
+
+ text = g_strjoinv(" + ", (char **)strings);
+ g_free(keytext);
+ }
+
+ gtk_entry_set_text(GTK_ENTRY(entry), text);
+ gtk_editable_set_position(GTK_EDITABLE(entry), -1);
+ if (text) g_free(text);
+}
+
+static gboolean
+on_entry_key_press_event(GtkWidget * widget,
+ GdkEventKey * event,
+ void * user_data)
+{
+ KeyControls *controls = (KeyControls*) user_data;
+ int is_mod;
+ int mod;
+
+ if (event->keyval == GDK_Tab) return FALSE;
+ if (event->keyval == GDK_Escape && ((event->state & ~GDK_LOCK_MASK) == 0)) return FALSE;
+ if (event->keyval == GDK_Return && ((event->state & ~GDK_LOCK_MASK) == 0)) return FALSE;
+ if (event->keyval == GDK_ISO_Left_Tab)
+ {
+ set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type);
+ return FALSE;
+ }
+ if (event->keyval == GDK_Up && ((event->state & ~GDK_LOCK_MASK) == 0)) return FALSE;
+ if (event->keyval == GDK_Down && ((event->state & ~GDK_LOCK_MASK) == 0)) return FALSE;
+
+ mod = 0;
+ is_mod = 0;
+
+ if ((event->state & GDK_CONTROL_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R))))
+ mod |= ControlMask;
+
+ if ((event->state & GDK_MOD1_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Alt_L || event->keyval == GDK_Alt_R))))
+ mod |= Mod1Mask;
+
+ if ((event->state & GDK_SHIFT_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R))))
+ mod |= ShiftMask;
+
+ if ((event->state & GDK_MOD5_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_ISO_Level3_Shift))))
+ mod |= Mod5Mask;
+
+ if ((event->state & GDK_MOD4_MASK) | (!is_mod && (is_mod = (event->keyval == GDK_Super_L || event->keyval == GDK_Super_R))))
+ mod |= Mod4Mask;
+
+ if (!is_mod) {
+ controls->hotkey.key = event->hardware_keycode;
+ controls->hotkey.mask = mod;
+ controls->hotkey.type = TYPE_KEY;
+ if (controls->next == nullptr)
+ add_callback (nullptr, (void *) controls);
+ else gtk_widget_grab_focus(GTK_WIDGET(controls->next->keytext));
+ }
+
+ set_keytext(controls->keytext, is_mod ? 0 : event->hardware_keycode, mod, TYPE_KEY);
+ return TRUE;
+}
+
+static gboolean
+on_entry_key_release_event(GtkWidget * widget,
+ GdkEventKey * event,
+ void * user_data)
+{
+ KeyControls *controls = (KeyControls*) user_data;
+ if (!gtk_widget_is_focus(widget)) return FALSE;
+ set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type);
+
+ return TRUE;
+}
+
+static gboolean
+on_entry_button_press_event(GtkWidget * widget,
+ GdkEventButton * event,
+ void * user_data)
+{
+ KeyControls *controls = (KeyControls*) user_data;
+ int mod;
+
+ if (!gtk_widget_is_focus(widget)) return FALSE;
+
+ mod = 0;
+ if (event->state & GDK_CONTROL_MASK)
+ mod |= ControlMask;
+
+ if (event->state & GDK_MOD1_MASK)
+ mod |= Mod1Mask;
+
+ if (event->state & GDK_SHIFT_MASK)
+ mod |= ShiftMask;
+
+ if (event->state & GDK_MOD5_MASK)
+ mod |= Mod5Mask;
+
+ if (event->state & GDK_MOD4_MASK)
+ mod |= Mod4Mask;
+
+ if ((event->button <= 3) && (mod == 0))
+ {
+ GtkWidget* dialog;
+ int response;
+ dialog = gtk_message_dialog_new (GTK_WINDOW(gtk_widget_get_toplevel(widget)),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_YES_NO,
+ _("It is not recommended to bind the primary mouse buttons without modificators.\n\n"
+ "Do you want to continue?"));
+ gtk_window_set_title(GTK_WINDOW(dialog), _("Binding mouse buttons"));
+ response = gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy (dialog);
+ if (response != GTK_RESPONSE_YES) return TRUE;
+ }
+
+ controls->hotkey.key = event->button;
+ controls->hotkey.mask = mod;
+ controls->hotkey.type = TYPE_MOUSE;
+ set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type);
+ if (controls->next == nullptr)
+ add_callback (nullptr, (void *) controls);
+
+ return TRUE;
+}
+
+static gboolean
+on_entry_scroll_event(GtkWidget * widget,
+ GdkEventScroll * event,
+ void * user_data)
+{
+ KeyControls *controls = (KeyControls*) user_data;
+ int mod;
+
+ if (!gtk_widget_is_focus(widget)) return FALSE;
+
+ mod = 0;
+ if (event->state & GDK_CONTROL_MASK)
+ mod |= ControlMask;
+
+ if (event->state & GDK_MOD1_MASK)
+ mod |= Mod1Mask;
+
+ if (event->state & GDK_SHIFT_MASK)
+ mod |= ShiftMask;
+
+ if (event->state & GDK_MOD5_MASK)
+ mod |= Mod5Mask;
+
+ if (event->state & GDK_MOD4_MASK)
+ mod |= Mod4Mask;
+
+ if (event->direction == GDK_SCROLL_UP)
+ controls->hotkey.key = 4;
+ else if (event->direction == GDK_SCROLL_DOWN)
+ controls->hotkey.key = 5;
+ else if (event->direction == GDK_SCROLL_LEFT)
+ controls->hotkey.key = 6;
+ else if (event->direction == GDK_SCROLL_RIGHT)
+ controls->hotkey.key = 7;
+ else return FALSE;
+
+ controls->hotkey.mask = mod;
+ controls->hotkey.type = TYPE_MOUSE;
+ set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type);
+ if (controls->next == nullptr)
+ add_callback (nullptr, (void *) controls);
+ return TRUE;
+}
+
+KeyControls* add_event_controls(KeyControls* list,
+ GtkWidget *grid,
+ int row,
+ HotkeyConfiguration *hotkey)
+{
+ KeyControls *controls;
+ int i;
+
+ controls = (KeyControls*) g_malloc(sizeof(KeyControls));
+ controls->next = nullptr;
+ controls->prev = list;
+ controls->first = list->first;
+ controls->grid = grid;
+ list->next = controls;
+
+ if (hotkey)
+ {
+ controls->hotkey.key = hotkey->key;
+ controls->hotkey.mask = hotkey->mask;
+ controls->hotkey.type = hotkey->type;
+ controls->hotkey.event = hotkey->event;
+ if (controls->hotkey.key == 0)
+ controls->hotkey.mask = 0;
+ } else {
+ controls->hotkey.key = 0;
+ controls->hotkey.mask = 0;
+ controls->hotkey.type = TYPE_KEY;
+ controls->hotkey.event = (EVENT) 0;
+ }
+
+ controls->combobox = gtk_combo_box_text_new();
+ for (i=0;i<EVENT_MAX;i++)
+ {
+ gtk_combo_box_text_append_text((GtkComboBoxText *) controls->combobox, _(event_desc[i]));
+ }
+ gtk_combo_box_set_active(GTK_COMBO_BOX(controls->combobox), controls->hotkey.event);
+ gtk_table_attach_defaults (GTK_TABLE (grid), controls->combobox, 0, 1, row, row + 1);
+
+
+ controls->keytext = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (grid), controls->keytext, 1, 2, row, row + 1);
+ gtk_editable_set_editable(GTK_EDITABLE(controls->keytext), FALSE);
+
+
+ set_keytext(controls->keytext, controls->hotkey.key, controls->hotkey.mask, controls->hotkey.type);
+ g_signal_connect((void *)controls->keytext, "key_press_event",
+ G_CALLBACK(on_entry_key_press_event), controls);
+ g_signal_connect((void *)controls->keytext, "key_release_event",
+ G_CALLBACK(on_entry_key_release_event), controls);
+ g_signal_connect((void *)controls->keytext, "button_press_event",
+ G_CALLBACK(on_entry_button_press_event), controls);
+ g_signal_connect((void *)controls->keytext, "scroll_event",
+ G_CALLBACK(on_entry_scroll_event), controls);
+
+
+ controls->button = gtk_button_new();
+ gtk_button_set_image (GTK_BUTTON (controls->button),
+ gtk_image_new_from_icon_name ("edit-delete", GTK_ICON_SIZE_BUTTON));
+ gtk_table_attach_defaults (GTK_TABLE (grid), controls->button, 2, 3, row, row + 1);
+ g_signal_connect (G_OBJECT (controls->button), "clicked",
+ G_CALLBACK (clear_keyboard), controls);
+
+ gtk_widget_grab_focus(GTK_WIDGET(controls->keytext));
+ return controls;
+}
+
+void *make_config_widget ()
+{
+ KeyControls *current_controls;
+ GtkWidget *main_vbox, *hbox;
+ GtkWidget *alignment;
+ GtkWidget *frame;
+ GtkWidget *label;
+ GtkWidget *image;
+ GtkWidget *grid;
+ GtkWidget *button_box, *button;
+ PluginConfig* plugin_cfg;
+ HotkeyConfiguration *hotkey, temphotkey;
+ int i;
+
+ load_config ( );
+
+ plugin_cfg = get_config();
+
+ ungrab_keys();
+
+ main_vbox = gtk_vbox_new (FALSE, 4);
+
+ alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_box_pack_start (GTK_BOX (main_vbox), alignment, FALSE, TRUE, 0);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 4, 0, 0, 0);
+ hbox = gtk_hbox_new (FALSE, 2);
+ gtk_container_add (GTK_CONTAINER (alignment), hbox);
+ image = gtk_image_new_from_icon_name ("dialog-information", GTK_ICON_SIZE_DIALOG);
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0);
+ label = gtk_label_new (_("Press a key combination inside a text field.\nYou can also bind mouse buttons."));
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ label = gtk_label_new (nullptr);
+ gtk_label_set_markup (GTK_LABEL (label), _("Hotkeys:"));
+ frame = gtk_frame_new (nullptr);
+ gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+ gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
+ alignment = gtk_alignment_new (0, 0, 1, 0);
+ gtk_container_add (GTK_CONTAINER (frame), alignment);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 3, 3, 3, 3);
+
+ grid = gtk_table_new (0, 0, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (grid), 2);
+ gtk_container_add (GTK_CONTAINER (alignment), grid);
+
+ label = gtk_label_new (nullptr);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
+ gtk_label_set_markup (GTK_LABEL (label),
+ _("<b>Action:</b>"));
+ gtk_table_attach_defaults (GTK_TABLE (grid), label, 0, 1, 0, 1);
+
+ label = gtk_label_new (nullptr);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
+ gtk_label_set_markup (GTK_LABEL (label),
+ _("<b>Key Binding:</b>"));
+ gtk_table_attach_defaults (GTK_TABLE (grid), label, 1, 2, 0, 1);
+
+
+ hotkey = &(plugin_cfg->first);
+ i = 1;
+ first_controls = (KeyControls*) g_malloc(sizeof(KeyControls));
+ first_controls->next = nullptr;
+ first_controls->prev = nullptr;
+ first_controls->grid = grid;
+ first_controls->button = nullptr;
+ first_controls->combobox = nullptr;
+ first_controls->keytext = nullptr;
+ first_controls->first = first_controls;
+ first_controls->hotkey.key = 0;
+ first_controls->hotkey.mask = 0;
+ first_controls->hotkey.event = (EVENT) 0;
+ first_controls->hotkey.type = TYPE_KEY;
+ current_controls = first_controls;
+ if (hotkey -> key != 0)
+ {
+ while (hotkey)
+ {
+ current_controls = add_event_controls(current_controls, grid, i, hotkey);
+ hotkey = hotkey->next;
+ i++;
+ }
+ }
+ temphotkey.key = 0;
+ temphotkey.mask = 0;
+ temphotkey.type = TYPE_KEY;
+ if (current_controls != first_controls)
+ temphotkey.event = (EVENT) (current_controls->hotkey.event + 1);
+ else
+ temphotkey.event = (EVENT) 0;
+ if (temphotkey.event >= EVENT_MAX)
+ temphotkey.event = (EVENT) 0;
+ add_event_controls(current_controls, grid, i, &temphotkey);
+
+
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
+
+ button_box = gtk_hbutton_box_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), button_box, FALSE, TRUE, 0);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box), GTK_BUTTONBOX_START);
+ gtk_box_set_spacing (GTK_BOX (button_box), 4);
+
+ button = audgui_button_new (_("_Add"), "list-add", nullptr, nullptr);
+ gtk_container_add (GTK_CONTAINER (button_box), button);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (add_callback), first_controls);
+
+ return main_vbox;
+}
+
+static void clear_keyboard (GtkWidget *widget, void * data)
+{
+ KeyControls *controls= (KeyControls*)data;
+
+ if ((controls->next == nullptr) && (controls->prev->keytext == nullptr))
+ {
+ controls->hotkey.key = 0;
+ controls->hotkey.mask = 0;
+ controls->hotkey.type = TYPE_KEY;
+ set_keytext(controls->keytext, 0, 0, TYPE_KEY);
+ gtk_combo_box_set_active( GTK_COMBO_BOX(controls->combobox), 0);
+ return;
+ }
+
+ if (controls->prev)
+ {
+ KeyControls* c;
+ GtkWidget* grid;
+ int row;
+
+ gtk_widget_destroy(GTK_WIDGET(controls->button));
+ gtk_widget_destroy(GTK_WIDGET(controls->keytext));
+ gtk_widget_destroy(GTK_WIDGET(controls->combobox));
+
+ row=0;
+ c = controls->first;
+ while (c) {
+ if (c == controls) break;
+ row++;
+ c = c->next;
+ }
+ c = controls->next;
+ controls->prev->next = controls->next;
+ if (controls->next)
+ controls->next->prev = controls->prev;
+ g_free(controls);
+ if (c) grid = c->grid; else grid = nullptr;
+ while (c)
+ {
+ g_object_ref(c->combobox);
+ g_object_ref(c->keytext);
+ g_object_ref(c->button);
+
+ gtk_container_remove( GTK_CONTAINER(c->grid) , c->combobox);
+ gtk_container_remove( GTK_CONTAINER(c->grid) , c->keytext);
+ gtk_container_remove( GTK_CONTAINER(c->grid) , c->button);
+
+ gtk_table_attach_defaults (GTK_TABLE (c->grid), c->combobox, 0, 1, row, row + 1);
+ gtk_table_attach_defaults (GTK_TABLE (c->grid), c->keytext, 1, 2, row, row + 1);
+ gtk_table_attach_defaults (GTK_TABLE (c->grid), c->button, 2, 3, row, row + 1);
+
+ g_object_unref(c->combobox);
+ g_object_unref(c->keytext);
+ g_object_unref(c->button);
+
+ c = c->next;
+ row++;
+ }
+ if (grid)
+ gtk_widget_show_all (GTK_WIDGET (grid));
+
+ return;
+ }
+}
+
+void add_callback (GtkWidget *widget, void * data)
+{
+ KeyControls* controls = (KeyControls*)data;
+ HotkeyConfiguration temphotkey;
+ int count;
+ if (controls == nullptr) return;
+ if ((controls->next == nullptr)&&(controls->hotkey.event+1 == EVENT_MAX)) return;
+ controls = controls->first;
+ if (controls == nullptr) return;
+ count = 1;
+ while (controls->next) {
+ controls = controls->next;
+ count = count + 1;
+ }
+ temphotkey.key = 0;
+ temphotkey.mask = 0;
+ temphotkey.type = TYPE_KEY;
+ temphotkey.event = (EVENT) (controls->hotkey.event + 1);
+ if (temphotkey.event >= EVENT_MAX)
+ temphotkey.event = (EVENT) 0;
+ add_event_controls(controls, controls->grid, count, &temphotkey);
+ gtk_widget_show_all (GTK_WIDGET (controls->grid));
+}
+
+void destroy_callback ()
+{
+ KeyControls* controls = first_controls;
+
+ grab_keys ();
+
+ while (controls) {
+ KeyControls *old;
+ old = controls;
+ controls = controls->next;
+ g_free(old);
+ }
+
+ first_controls = nullptr;
+}
+
+void ok_callback ()
+{
+ KeyControls *controls = first_controls;
+ PluginConfig* plugin_cfg = get_config();
+ HotkeyConfiguration *hotkey;
+
+ hotkey = &(plugin_cfg->first);
+ hotkey = hotkey->next;
+ while (hotkey)
+ {
+ HotkeyConfiguration * old;
+ old = hotkey;
+ hotkey = hotkey->next;
+ g_free(old);
+ }
+ plugin_cfg->first.next = nullptr;
+ plugin_cfg->first.key = 0;
+ plugin_cfg->first.event = (EVENT) 0;
+ plugin_cfg->first.mask = 0;
+
+ hotkey = &(plugin_cfg->first);
+ while (controls)
+ {
+ if (controls->hotkey.key) {
+ if (hotkey->key) {
+ hotkey->next = g_new(HotkeyConfiguration, 1);
+ hotkey = hotkey->next;
+ hotkey->next = nullptr;
+ }
+ hotkey->key = controls->hotkey.key;
+ hotkey->mask = controls->hotkey.mask;
+ hotkey->event = (EVENT) gtk_combo_box_get_active( GTK_COMBO_BOX(controls->combobox) );
+ hotkey->type = controls->hotkey.type;
+ }
+ controls = controls->next;
+ }
+
+ save_config ( );
+}
+
+
+static const PreferencesWidget hotkey_widgets[] = {
+ WidgetCustomGTK (make_config_widget)
+};
+
+const PluginPreferences hotkey_prefs = {
+ {hotkey_widgets},
+ nullptr, // init
+ ok_callback,
+ destroy_callback
+};
diff --git a/src/hotkey/gui.h b/src/hotkey/gui.h
index db40c381311e..78e6562d8b1a 100644
--- a/src/hotkey/gui.h
+++ b/src/hotkey/gui.h
@@ -1,6 +1,8 @@
#ifndef _GUI_H_INCLUDED_
#define _GUI_H_INCLUDED_
-void show_configure (void);
+struct PluginPreferences;
+
+extern const PluginPreferences hotkey_prefs;
#endif
diff --git a/src/hotkey/plugin.c b/src/hotkey/plugin.c
deleted file mode 100644
index 09b02523ae16..000000000000
--- a/src/hotkey/plugin.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * This file is part of audacious-hotkey plugin for audacious
- *
- * Copyright (c) 2007 - 2008 Sascha Hlusiak <contact at saschahlusiak.de>
- * Name: plugin.c
- * Description: plugin.c
- *
- * Part of this code is from itouch-ctrl plugin.
- * Authors of itouch-ctrl are listed below:
- *
- * Copyright (c) 2006 - 2007 Vladimir Paskov <vlado.paskov at gmail.com>
- *
- * Part of this code are from xmms-itouch plugin.
- * Authors of xmms-itouch are listed below:
- *
- * Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>
- * Bryn Davies <curious at ihug.com.au>
- * Jonathan A. Davis <davis at jdhouse.org>
- * Jeremy Tan <nsx at nsx.homeip.net>
- *
- * audacious-hotkey 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.
- *
- * audacious-hotkey 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 audacious-hotkey; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <X11/XF86keysym.h>
-
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-#include <gtk/gtk.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui.h>
-
-#include "plugin.h"
-#include "gui.h"
-#include "grab.h"
-
-
-/* func defs */
-static gboolean init (void);
-static void cleanup (void);
-
-
-/* global vars */
-static PluginConfig plugin_cfg;
-static gboolean loaded = FALSE;
-
-static const char about[] =
- N_("Global Hotkey Plugin\n"
- "Control the player with global key combinations or multimedia keys.\n\n"
- "Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>\n\n"
- "Contributers include:\n"
- "Copyright (C) 2006-2007 Vladimir Paskov <vlado.paskov at gmail.com>\n"
- "Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>,\n"
- " Bryn Davies <curious at ihug.com.au>,\n"
- " Jonathan A. Davis <davis at jdhouse.org>,\n"
- " Jeremy Tan <nsx at nsx.homeip.net>");
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("Global Hotkeys"),
- .domain = PACKAGE,
- .about_text = about,
- .init = init,
- .configure = show_configure,
- .cleanup = cleanup
-)
-
-PluginConfig* get_config(void)
-{
- return &plugin_cfg;
-}
-
-
-/*
- * plugin activated
- */
-static gboolean init (void)
-{
- if (! gtk_init_check (NULL, NULL))
- {
- fprintf (stderr, "hotkey: GTK+ initialization failed.\n");
- return FALSE;
- }
-
- setup_filter();
- load_config ( );
- grab_keys ( );
-
- loaded = TRUE;
- return TRUE;
-}
-
-/* handle keys */
-gboolean handle_keyevent (EVENT event)
-{
- gint current_volume, old_volume;
- static gint volume_static = 0;
- gboolean mute;
-
- /* get current volume */
- aud_drct_get_volume_main (¤t_volume);
- old_volume = current_volume;
- if (current_volume)
- {
- /* volume is not mute */
- mute = FALSE;
- } else {
- /* volume is mute */
- mute = TRUE;
- }
-
- /* mute the playback */
- if (event == EVENT_MUTE)
- {
- if (!mute)
- {
- volume_static = current_volume;
- aud_drct_set_volume_main (0);
- mute = TRUE;
- } else {
- aud_drct_set_volume_main (volume_static);
- mute = FALSE;
- }
- return TRUE;
- }
-
- /* decreace volume */
- if (event == EVENT_VOL_DOWN)
- {
- if (mute)
- {
- current_volume = old_volume;
- old_volume = 0;
- mute = FALSE;
- }
-
- if ((current_volume -= plugin_cfg.vol_decrement) < 0)
- {
- current_volume = 0;
- }
-
- if (current_volume != old_volume)
- {
- aud_drct_set_volume_main (current_volume);
- }
-
- old_volume = current_volume;
- return TRUE;
- }
-
- /* increase volume */
- if (event == EVENT_VOL_UP)
- {
- if (mute)
- {
- current_volume = old_volume;
- old_volume = 0;
- mute = FALSE;
- }
-
- if ((current_volume += plugin_cfg.vol_increment) > 100)
- {
- current_volume = 100;
- }
-
- if (current_volume != old_volume)
- {
- aud_drct_set_volume_main (current_volume);
- }
-
- old_volume = current_volume;
- return TRUE;
- }
-
- /* play */
- if (event == EVENT_PLAY)
- {
- aud_drct_play ();
- return TRUE;
- }
-
- /* pause */
- if (event == EVENT_PAUSE)
- {
- aud_drct_play_pause ();
- return TRUE;
- }
-
- /* stop */
- if (event == EVENT_STOP)
- {
- aud_drct_stop ();
- return TRUE;
- }
-
- /* prev track */
- if (event == EVENT_PREV_TRACK)
- {
- aud_drct_pl_prev ();
- return TRUE;
- }
-
- /* next track */
- if (event == EVENT_NEXT_TRACK)
- {
- aud_drct_pl_next ();
- return TRUE;
- }
-
- /* forward */
- if (event == EVENT_FORWARD)
- {
- aud_drct_seek (aud_drct_get_time () + 5000);
- return TRUE;
- }
-
- /* backward */
- if (event == EVENT_BACKWARD)
- {
- gint time = aud_drct_get_time ();
- if (time > 5000) time -= 5000; /* Jump 5s back */
- else time = 0;
- aud_drct_seek (time);
- return TRUE;
- }
-
- /* Open Jump-To-File dialog */
- if (event == EVENT_JUMP_TO_FILE && ! aud_headless_mode ())
- {
- audgui_jump_to_track ();
- return TRUE;
- }
-
- /* Toggle Windows */
- if (event == EVENT_TOGGLE_WIN && ! aud_headless_mode ())
- {
- aud_interface_show (! aud_interface_is_shown ());
- return TRUE;
- }
-
- /* Show OSD through AOSD plugin*/
- if (event == EVENT_SHOW_AOSD)
- {
- hook_call("aosd toggle", NULL);
- return TRUE;
- }
-
- if (event == EVENT_TOGGLE_REPEAT)
- {
- aud_set_bool (NULL, "repeat", ! aud_get_bool (NULL, "repeat"));
- return TRUE;
- }
-
- if (event == EVENT_TOGGLE_SHUFFLE)
- {
- aud_set_bool (NULL, "shuffle", ! aud_get_bool (NULL, "shuffle"));
- return TRUE;
- }
-
- if (event == EVENT_TOGGLE_STOP)
- {
- aud_set_bool (NULL, "stop_after_current_song", ! aud_get_bool (NULL, "stop_after_current_song"));
- return TRUE;
- }
-
- if (event == EVENT_RAISE)
- {
- aud_interface_show (TRUE);
- return TRUE;
- }
-
- return FALSE;
-}
-
-void add_hotkey(HotkeyConfiguration** pphotkey, KeySym keysym, gint mask, gint type, EVENT event)
-{
- KeyCode keycode;
- HotkeyConfiguration *photkey;
- if (keysym == 0) return;
- if (pphotkey == NULL) return;
- photkey = *pphotkey;
- if (photkey == NULL) return;
- keycode = XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), keysym);
- if (keycode == 0) return;
- if (photkey->key) {
- photkey->next = g_new(HotkeyConfiguration, 1);
- photkey = photkey->next;
- *pphotkey = photkey;
- photkey->next = NULL;
- }
- photkey->key = (gint)keycode;
- photkey->mask = mask;
- photkey->event = event;
- photkey->type = type;
-}
-
-void load_defaults (void)
-{
- HotkeyConfiguration* hotkey;
-
- hotkey = &(plugin_cfg.first);
-
- add_hotkey(&hotkey, XF86XK_AudioPrev, 0, TYPE_KEY, EVENT_PREV_TRACK);
- add_hotkey(&hotkey, XF86XK_AudioPlay, 0, TYPE_KEY, EVENT_PLAY);
- add_hotkey(&hotkey, XF86XK_AudioPause, 0, TYPE_KEY, EVENT_PAUSE);
- add_hotkey(&hotkey, XF86XK_AudioStop, 0, TYPE_KEY, EVENT_STOP);
- add_hotkey(&hotkey, XF86XK_AudioNext, 0, TYPE_KEY, EVENT_NEXT_TRACK);
-
-/* add_hotkey(&hotkey, XF86XK_AudioRewind, 0, TYPE_KEY, EVENT_BACKWARD); */
-
- add_hotkey(&hotkey, XF86XK_AudioMute, 0, TYPE_KEY, EVENT_MUTE);
- add_hotkey(&hotkey, XF86XK_AudioRaiseVolume, 0, TYPE_KEY, EVENT_VOL_UP);
- add_hotkey(&hotkey, XF86XK_AudioLowerVolume, 0, TYPE_KEY, EVENT_VOL_DOWN);
-
-/* add_hotkey(&hotkey, XF86XK_AudioMedia, 0, TYPE_KEY, EVENT_JUMP_TO_FILE);
- add_hotkey(&hotkey, XF86XK_Music, 0, TYPE_KEY, EVENT_TOGGLE_WIN); */
-}
-
-/* load plugin configuration */
-void load_config (void)
-{
- HotkeyConfiguration *hotkey;
- int i,max;
-
- /* default volume level */
- plugin_cfg.vol_increment = 4;
- plugin_cfg.vol_decrement = 4;
-
- hotkey = &(plugin_cfg.first);
- hotkey->next = NULL;
- hotkey->key = 0;
- hotkey->mask = 0;
- hotkey->event = 0;
- hotkey->type = TYPE_KEY;
-
- max = aud_get_int ("globalHotkey", "NumHotkeys");
- if (max == 0)
- load_defaults();
- else for (i=0; i<max; i++)
- {
- gchar *text = NULL;
-
- if (hotkey->key) {
- hotkey->next = g_new(HotkeyConfiguration, 1);
- hotkey = hotkey->next;
- hotkey->next = NULL;
- hotkey->key = 0;
- hotkey->mask = 0;
- hotkey->event = 0;
- hotkey->type = TYPE_KEY;
- }
- text = g_strdup_printf("Hotkey_%d_key", i);
- hotkey->key = aud_get_int ("globalHotkey", text);
- g_free(text);
-
- text = g_strdup_printf("Hotkey_%d_mask", i);
- hotkey->mask = aud_get_int ("globalHotkey", text);
- g_free(text);
-
- text = g_strdup_printf("Hotkey_%d_type", i);
- hotkey->type = aud_get_int ("globalHotkey", text);
- g_free(text);
-
- text = g_strdup_printf("Hotkey_%d_event", i);
- hotkey->event = aud_get_int ("globalHotkey", text);
- g_free(text);
- }
-}
-
-/* save plugin configuration */
-void save_config (void)
-{
- int max;
- HotkeyConfiguration *hotkey;
-
- hotkey = &(plugin_cfg.first);
- max = 0;
- while (hotkey) {
- gchar *text = NULL;
- if (hotkey->key) {
- text = g_strdup_printf("Hotkey_%d_key", max);
- aud_set_int ("globalHotkey", text, hotkey->key);
- g_free(text);
-
- text = g_strdup_printf("Hotkey_%d_mask", max);
- aud_set_int ("globalHotkey", text, hotkey->mask);
- g_free(text);
-
- text = g_strdup_printf("Hotkey_%d_type", max);
- aud_set_int ("globalHotkey", text, hotkey->type);
- g_free(text);
-
- text = g_strdup_printf("Hotkey_%d_event", max);
- aud_set_int ("globalHotkey", text, hotkey->event);
- g_free(text);
- max++;
- }
-
- hotkey = hotkey->next;
- }
-
- aud_set_int ("globalHotkey", "NumHotkeys", max);
-}
-
-static void cleanup (void)
-{
- HotkeyConfiguration* hotkey;
- if (!loaded) return;
- ungrab_keys ();
- release_filter();
- hotkey = &(plugin_cfg.first);
- hotkey = hotkey->next;
- while (hotkey)
- {
- HotkeyConfiguration * old;
- old = hotkey;
- hotkey = hotkey->next;
- g_free(old);
- }
- plugin_cfg.first.next = NULL;
- plugin_cfg.first.key = 0;
- plugin_cfg.first.event = 0;
- plugin_cfg.first.mask = 0;
- loaded = FALSE;
-}
-
-gboolean is_loaded (void)
-{
- return loaded;
-}
diff --git a/src/hotkey/plugin.cc b/src/hotkey/plugin.cc
new file mode 100644
index 000000000000..7c2cc230031a
--- /dev/null
+++ b/src/hotkey/plugin.cc
@@ -0,0 +1,446 @@
+/*
+ * This file is part of audacious-hotkey plugin for audacious
+ *
+ * Copyright (c) 2007 - 2008 Sascha Hlusiak <contact at saschahlusiak.de>
+ * Name: plugin.c
+ * Description: plugin.c
+ *
+ * Part of this code is from itouch-ctrl plugin.
+ * Authors of itouch-ctrl are listed below:
+ *
+ * Copyright (c) 2006 - 2007 Vladimir Paskov <vlado.paskov at gmail.com>
+ *
+ * Part of this code are from xmms-itouch plugin.
+ * Authors of xmms-itouch are listed below:
+ *
+ * Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>
+ * Bryn Davies <curious at ihug.com.au>
+ * Jonathan A. Davis <davis at jdhouse.org>
+ * Jeremy Tan <nsx at nsx.homeip.net>
+ *
+ * audacious-hotkey 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.
+ *
+ * audacious-hotkey 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 audacious-hotkey; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+
+#include <X11/XF86keysym.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+#include "plugin.h"
+#include "gui.h"
+#include "grab.h"
+
+class GlobalHotkeys : public GeneralPlugin
+{
+public:
+ static const char about[];
+
+ static constexpr PluginInfo info = {
+ N_("Global Hotkeys"),
+ PACKAGE,
+ about,
+ & hotkey_prefs
+ };
+
+ constexpr GlobalHotkeys () : GeneralPlugin (info, false) {}
+
+ bool init ();
+ void cleanup ();
+};
+
+EXPORT GlobalHotkeys aud_plugin_instance;
+
+/* global vars */
+static PluginConfig plugin_cfg;
+
+const char GlobalHotkeys::about[] =
+ N_("Global Hotkey Plugin\n"
+ "Control the player with global key combinations or multimedia keys.\n\n"
+ "Copyright (C) 2007-2008 Sascha Hlusiak <contact at saschahlusiak.de>\n\n"
+ "Contributers include:\n"
+ "Copyright (C) 2006-2007 Vladimir Paskov <vlado.paskov at gmail.com>\n"
+ "Copyright (C) 2000-2002 Ville Syrjälä <syrjala at sci.fi>,\n"
+ " Bryn Davies <curious at ihug.com.au>,\n"
+ " Jonathan A. Davis <davis at jdhouse.org>,\n"
+ " Jeremy Tan <nsx at nsx.homeip.net>");
+
+PluginConfig* get_config(void)
+{
+ return &plugin_cfg;
+}
+
+
+/*
+ * plugin activated
+ */
+bool GlobalHotkeys::init ()
+{
+ if (aud_get_mainloop_type () != MainloopType::GLib)
+ return false;
+
+ if (! gtk_init_check (nullptr, nullptr))
+ {
+ AUDERR ("GTK+ initialization failed.\n");
+ return false;
+ }
+
+ setup_filter();
+ load_config ( );
+ grab_keys ( );
+
+ return true;
+}
+
+/* handle keys */
+gboolean handle_keyevent (EVENT event)
+{
+ int current_volume, old_volume;
+ static int volume_static = 0;
+ gboolean mute;
+
+ /* get current volume */
+ current_volume = aud_drct_get_volume_main ();
+ old_volume = current_volume;
+ if (current_volume)
+ {
+ /* volume is not mute */
+ mute = FALSE;
+ } else {
+ /* volume is mute */
+ mute = TRUE;
+ }
+
+ /* mute the playback */
+ if (event == EVENT_MUTE)
+ {
+ if (!mute)
+ {
+ volume_static = current_volume;
+ aud_drct_set_volume_main (0);
+ mute = TRUE;
+ } else {
+ aud_drct_set_volume_main (volume_static);
+ mute = FALSE;
+ }
+ return TRUE;
+ }
+
+ /* decreace volume */
+ if (event == EVENT_VOL_DOWN)
+ {
+ if (mute)
+ {
+ current_volume = old_volume;
+ old_volume = 0;
+ mute = FALSE;
+ }
+
+ if ((current_volume -= plugin_cfg.vol_decrement) < 0)
+ {
+ current_volume = 0;
+ }
+
+ if (current_volume != old_volume)
+ {
+ aud_drct_set_volume_main (current_volume);
+ }
+
+ old_volume = current_volume;
+ return TRUE;
+ }
+
+ /* increase volume */
+ if (event == EVENT_VOL_UP)
+ {
+ if (mute)
+ {
+ current_volume = old_volume;
+ old_volume = 0;
+ mute = FALSE;
+ }
+
+ if ((current_volume += plugin_cfg.vol_increment) > 100)
+ {
+ current_volume = 100;
+ }
+
+ if (current_volume != old_volume)
+ {
+ aud_drct_set_volume_main (current_volume);
+ }
+
+ old_volume = current_volume;
+ return TRUE;
+ }
+
+ /* play */
+ if (event == EVENT_PLAY)
+ {
+ aud_drct_play ();
+ return TRUE;
+ }
+
+ /* pause */
+ if (event == EVENT_PAUSE)
+ {
+ aud_drct_play_pause ();
+ return TRUE;
+ }
+
+ /* stop */
+ if (event == EVENT_STOP)
+ {
+ aud_drct_stop ();
+ return TRUE;
+ }
+
+ /* prev track */
+ if (event == EVENT_PREV_TRACK)
+ {
+ aud_drct_pl_prev ();
+ return TRUE;
+ }
+
+ /* next track */
+ if (event == EVENT_NEXT_TRACK)
+ {
+ aud_drct_pl_next ();
+ return TRUE;
+ }
+
+ /* forward */
+ if (event == EVENT_FORWARD)
+ {
+ aud_drct_seek (aud_drct_get_time () + 5000);
+ return TRUE;
+ }
+
+ /* backward */
+ if (event == EVENT_BACKWARD)
+ {
+ int time = aud_drct_get_time ();
+ if (time > 5000) time -= 5000; /* Jump 5s back */
+ else time = 0;
+ aud_drct_seek (time);
+ return TRUE;
+ }
+
+ /* Open Jump-To-File dialog */
+ if (event == EVENT_JUMP_TO_FILE && ! aud_get_headless_mode ())
+ {
+ aud_ui_show_jump_to_song ();
+ return TRUE;
+ }
+
+ /* Toggle Windows */
+ if (event == EVENT_TOGGLE_WIN && ! aud_get_headless_mode ())
+ {
+ aud_ui_show (! aud_ui_is_shown ());
+ return TRUE;
+ }
+
+ /* Show OSD through AOSD plugin*/
+ if (event == EVENT_SHOW_AOSD)
+ {
+ hook_call("aosd toggle", nullptr);
+ return TRUE;
+ }
+
+ if (event == EVENT_TOGGLE_REPEAT)
+ {
+ aud_set_bool (nullptr, "repeat", ! aud_get_bool (nullptr, "repeat"));
+ return TRUE;
+ }
+
+ if (event == EVENT_TOGGLE_SHUFFLE)
+ {
+ aud_set_bool (nullptr, "shuffle", ! aud_get_bool (nullptr, "shuffle"));
+ return TRUE;
+ }
+
+ if (event == EVENT_TOGGLE_STOP)
+ {
+ aud_set_bool (nullptr, "stop_after_current_song", ! aud_get_bool (nullptr, "stop_after_current_song"));
+ return TRUE;
+ }
+
+ if (event == EVENT_RAISE)
+ {
+ aud_ui_show (TRUE);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void add_hotkey(HotkeyConfiguration** pphotkey, KeySym keysym, int mask, int type, EVENT event)
+{
+ KeyCode keycode;
+ HotkeyConfiguration *photkey;
+ if (keysym == 0) return;
+ if (pphotkey == nullptr) return;
+ photkey = *pphotkey;
+ if (photkey == nullptr) return;
+ keycode = XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), keysym);
+ if (keycode == 0) return;
+ if (photkey->key) {
+ photkey->next = g_new(HotkeyConfiguration, 1);
+ photkey = photkey->next;
+ *pphotkey = photkey;
+ photkey->next = nullptr;
+ }
+ photkey->key = (int)keycode;
+ photkey->mask = mask;
+ photkey->event = event;
+ photkey->type = type;
+}
+
+void load_defaults (void)
+{
+ HotkeyConfiguration* hotkey;
+
+ hotkey = &(plugin_cfg.first);
+
+ add_hotkey(&hotkey, XF86XK_AudioPrev, 0, TYPE_KEY, EVENT_PREV_TRACK);
+ add_hotkey(&hotkey, XF86XK_AudioPlay, 0, TYPE_KEY, EVENT_PLAY);
+ add_hotkey(&hotkey, XF86XK_AudioPause, 0, TYPE_KEY, EVENT_PAUSE);
+ add_hotkey(&hotkey, XF86XK_AudioStop, 0, TYPE_KEY, EVENT_STOP);
+ add_hotkey(&hotkey, XF86XK_AudioNext, 0, TYPE_KEY, EVENT_NEXT_TRACK);
+
+/* add_hotkey(&hotkey, XF86XK_AudioRewind, 0, TYPE_KEY, EVENT_BACKWARD); */
+
+ add_hotkey(&hotkey, XF86XK_AudioMute, 0, TYPE_KEY, EVENT_MUTE);
+ add_hotkey(&hotkey, XF86XK_AudioRaiseVolume, 0, TYPE_KEY, EVENT_VOL_UP);
+ add_hotkey(&hotkey, XF86XK_AudioLowerVolume, 0, TYPE_KEY, EVENT_VOL_DOWN);
+
+/* add_hotkey(&hotkey, XF86XK_AudioMedia, 0, TYPE_KEY, EVENT_JUMP_TO_FILE);
+ add_hotkey(&hotkey, XF86XK_Music, 0, TYPE_KEY, EVENT_TOGGLE_WIN); */
+}
+
+/* load plugin configuration */
+void load_config (void)
+{
+ HotkeyConfiguration *hotkey;
+ int i,max;
+
+ /* default volume level */
+ plugin_cfg.vol_increment = 4;
+ plugin_cfg.vol_decrement = 4;
+
+ hotkey = &(plugin_cfg.first);
+ hotkey->next = nullptr;
+ hotkey->key = 0;
+ hotkey->mask = 0;
+ hotkey->event = (EVENT) 0;
+ hotkey->type = TYPE_KEY;
+
+ max = aud_get_int ("globalHotkey", "NumHotkeys");
+ if (max == 0)
+ load_defaults();
+ else for (i=0; i<max; i++)
+ {
+ char *text = nullptr;
+
+ if (hotkey->key) {
+ hotkey->next = g_new(HotkeyConfiguration, 1);
+ hotkey = hotkey->next;
+ hotkey->next = nullptr;
+ hotkey->key = 0;
+ hotkey->mask = 0;
+ hotkey->event = (EVENT) 0;
+ hotkey->type = TYPE_KEY;
+ }
+ text = g_strdup_printf("Hotkey_%d_key", i);
+ hotkey->key = aud_get_int ("globalHotkey", text);
+ g_free(text);
+
+ text = g_strdup_printf("Hotkey_%d_mask", i);
+ hotkey->mask = aud_get_int ("globalHotkey", text);
+ g_free(text);
+
+ text = g_strdup_printf("Hotkey_%d_type", i);
+ hotkey->type = aud_get_int ("globalHotkey", text);
+ g_free(text);
+
+ text = g_strdup_printf("Hotkey_%d_event", i);
+ hotkey->event = (EVENT) aud_get_int ("globalHotkey", text);
+ g_free(text);
+ }
+}
+
+/* save plugin configuration */
+void save_config (void)
+{
+ int max;
+ HotkeyConfiguration *hotkey;
+
+ hotkey = &(plugin_cfg.first);
+ max = 0;
+ while (hotkey) {
+ char *text = nullptr;
+ if (hotkey->key) {
+ text = g_strdup_printf("Hotkey_%d_key", max);
+ aud_set_int ("globalHotkey", text, hotkey->key);
+ g_free(text);
+
+ text = g_strdup_printf("Hotkey_%d_mask", max);
+ aud_set_int ("globalHotkey", text, hotkey->mask);
+ g_free(text);
+
+ text = g_strdup_printf("Hotkey_%d_type", max);
+ aud_set_int ("globalHotkey", text, hotkey->type);
+ g_free(text);
+
+ text = g_strdup_printf("Hotkey_%d_event", max);
+ aud_set_int ("globalHotkey", text, hotkey->event);
+ g_free(text);
+ max++;
+ }
+
+ hotkey = hotkey->next;
+ }
+
+ aud_set_int ("globalHotkey", "NumHotkeys", max);
+}
+
+void GlobalHotkeys::cleanup ()
+{
+ HotkeyConfiguration* hotkey;
+ ungrab_keys ();
+ release_filter();
+ hotkey = &(plugin_cfg.first);
+ hotkey = hotkey->next;
+ while (hotkey)
+ {
+ HotkeyConfiguration * old;
+ old = hotkey;
+ hotkey = hotkey->next;
+ g_free(old);
+ }
+ plugin_cfg.first.next = nullptr;
+ plugin_cfg.first.key = 0;
+ plugin_cfg.first.event = (EVENT) 0;
+ plugin_cfg.first.mask = 0;
+}
diff --git a/src/hotkey/plugin.h b/src/hotkey/plugin.h
index abebde4b927d..673b9678cd80 100644
--- a/src/hotkey/plugin.h
+++ b/src/hotkey/plugin.h
@@ -33,15 +33,15 @@ typedef enum {
typedef struct _HotkeyConfiguration {
- gint key, mask;
- gint type;
+ unsigned key, mask;
+ unsigned type;
EVENT event;
struct _HotkeyConfiguration *next;
} HotkeyConfiguration;
typedef struct {
- gint vol_increment;
- gint vol_decrement;
+ int vol_increment;
+ int vol_decrement;
/* keyboard */
HotkeyConfiguration first;
@@ -52,7 +52,6 @@ typedef struct {
void load_config (void);
void save_config (void);
PluginConfig* get_config(void);
-gboolean is_loaded (void);
gboolean handle_keyevent(EVENT event);
#endif
diff --git a/src/jack-ng/Makefile b/src/jack-ng/Makefile
new file mode 100644
index 000000000000..f2f54913fac9
--- /dev/null
+++ b/src/jack-ng/Makefile
@@ -0,0 +1,13 @@
+PLUGIN = jack-ng${PLUGIN_SUFFIX}
+
+SRCS = jack-ng.cc
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+plugindir := ${plugindir}/${OUTPUT_PLUGIN_DIR}
+
+LD = ${CXX}
+CFLAGS += ${PLUGIN_CFLAGS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${JACK_CFLAGS} -I../..
+LIBS += ${JACK_LIBS}
diff --git a/src/jack-ng/jack-ng.cc b/src/jack-ng/jack-ng.cc
new file mode 100644
index 000000000000..656447550ca4
--- /dev/null
+++ b/src/jack-ng/jack-ng.cc
@@ -0,0 +1,402 @@
+/*
+ * JACK Output Plugin for Audacious
+ * Copyright 2014 John Lindgren
+ *
+ * Based on the SDL Output Plugin and the previous JACK Output Plugin.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/ringbuf.h>
+#include <libaudcore/runtime.h>
+
+#include <algorithm>
+
+#include <assert.h>
+#include <pthread.h>
+#include <sys/time.h>
+
+#include <jack/jack.h>
+
+static_assert(std::is_same<jack_default_audio_sample_t, float>::value,
+ "JACK must be compiled to use float samples");
+
+class JACKOutput : public OutputPlugin
+{
+public:
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("JACK Output"),
+ PACKAGE,
+ nullptr,
+ & prefs
+ };
+
+ constexpr JACKOutput (RingBuf<float> & buffer) :
+ OutputPlugin (info, 0),
+ m_buffer (buffer) {}
+
+ bool init ();
+
+ StereoVolume get_volume ();
+ void set_volume (StereoVolume v);
+
+ bool open_audio (int format, int rate, int channels);
+ void close_audio ();
+
+ void period_wait ();
+ int write_audio (const void * data, int size);
+ void drain ();
+
+ int get_delay ();
+
+ void pause (bool pause);
+ void flush ();
+
+private:
+ bool connect_ports (int channels);
+ void generate (jack_nframes_t frames);
+
+ static void error_cb (const char * error)
+ { AUDWARN ("%s\n", error); }
+ static int generate_cb (jack_nframes_t frames, void * obj)
+ { ((JACKOutput *) obj)->generate (frames); return 0; }
+
+ int m_rate = 0, m_channels = 0;
+ bool m_paused = false, m_prebuffer = false;
+
+ int m_last_write_frames = 0;
+ timeval m_last_write_time = timeval ();
+ bool m_rate_mismatch = false;
+
+ RingBuf<float> & m_buffer;
+
+ jack_client_t * m_client = nullptr;
+ jack_port_t * m_ports[AUD_MAX_CHANNELS] = {};
+
+ pthread_mutex_t m_mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_cond_t m_cond = PTHREAD_COND_INITIALIZER;
+};
+
+// must be separate in order for JACKOutput() to be constexpr
+static RingBuf<float> s_buffer;
+
+EXPORT JACKOutput aud_plugin_instance (s_buffer);
+
+const char * const JACKOutput::defaults[] = {
+ "auto_connect", "TRUE",
+ "volume_left", "100",
+ "volume_right", "100",
+ nullptr
+};
+
+const PreferencesWidget JACKOutput::widgets[] = {
+ WidgetCheck (N_("Automatically connect to output ports"),
+ WidgetBool ("jack", "auto_connect"))
+};
+
+const PluginPreferences JACKOutput::prefs = {{widgets}};
+
+bool JACKOutput::init ()
+{
+ aud_config_set_defaults ("jack", defaults);
+ return true;
+}
+
+void JACKOutput::set_volume (StereoVolume v)
+{
+ aud_set_int ("jack", "volume_left", v.left);
+ aud_set_int ("jack", "volume_right", v.right);
+}
+
+StereoVolume JACKOutput::get_volume ()
+{
+ return {aud_get_int ("jack", "volume_left"), aud_get_int ("jack", "volume_right")};
+}
+
+bool JACKOutput::connect_ports (int channels)
+{
+ bool success = false;
+ const char * * ports = nullptr;
+ int count = 0;
+
+ if (! (ports = jack_get_ports (m_client, nullptr, nullptr,
+ JackPortIsPhysical | JackPortIsInput)))
+ {
+ AUDERR ("jack_get_ports() failed\n");
+ goto fail;
+ }
+
+ while (ports[count])
+ count ++;
+
+ if (count < channels)
+ {
+ aud_ui_show_error (str_printf (_("Only %d JACK output ports were "
+ "found but %d are required."), count, channels));
+ goto fail;
+ }
+
+ for (int i = 0; i < channels; i ++)
+ {
+ if (jack_connect (m_client, jack_port_name (m_ports[i]), ports[i]) != 0)
+ {
+ aud_ui_show_error (str_printf (_("Failed to connect to JACK port %s."), ports[i]));
+ goto fail;
+ }
+ }
+
+ success = true;
+
+fail:
+ if (ports)
+ jack_free (ports);
+
+ return success;
+}
+
+bool JACKOutput::open_audio (int format, int rate, int channels)
+{
+ int buffer_time;
+
+ if (format != FMT_FLOAT)
+ {
+ aud_ui_show_error (_("JACK supports only floating-point audio. You "
+ "must change the output bit depth to floating-point in Audacious "
+ "settings."));
+ return false;
+ }
+
+ assert (rate > 0 && channels > 0 && channels < AUD_MAX_CHANNELS);
+ assert (! m_client);
+
+ jack_set_error_function (error_cb);
+
+ if (! (m_client = jack_client_open ("audacious", JackNoStartServer, nullptr)))
+ {
+ aud_ui_show_error (_("Failed to connect to the JACK server; is it running?"));
+ goto fail;
+ }
+
+ for (int i = 0; i < channels; i ++)
+ {
+ StringBuf name = str_printf ("out_%d", i);
+ if (! (m_ports[i] = jack_port_register (m_client, name,
+ JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)))
+ {
+ AUDERR ("jack_port_register() failed\n");
+ goto fail;
+ }
+ }
+
+ buffer_time = aud_get_int (nullptr, "output_buffer_size");
+ m_buffer.alloc (aud::rescale (buffer_time, 1000, rate) * channels);
+
+ m_rate = rate;
+ m_channels = channels;
+ m_paused = false;
+ m_prebuffer = true;
+
+ m_last_write_frames = 0;
+ m_last_write_time = timeval ();
+ m_rate_mismatch = false;
+
+ jack_set_process_callback (m_client, generate_cb, this);
+
+ if (jack_activate (m_client) != 0)
+ {
+ AUDERR ("jack_activate() failed\n");
+ goto fail;
+ }
+
+ if (aud_get_bool ("jack", "auto_connect"))
+ {
+ if (! connect_ports (channels))
+ goto fail;
+ }
+
+ return true;
+
+fail:
+ close_audio ();
+ return false;
+}
+
+void JACKOutput::close_audio ()
+{
+ if (m_client)
+ jack_client_close (m_client);
+
+ m_buffer.destroy ();
+
+ std::fill (m_ports, std::end (m_ports), nullptr);
+ m_client = nullptr;
+}
+
+void JACKOutput::generate (jack_nframes_t frames)
+{
+ pthread_mutex_lock (& m_mutex);
+
+ m_last_write_frames = 0;
+ gettimeofday (& m_last_write_time, nullptr);
+
+ float * out[AUD_MAX_CHANNELS];
+ for (int i = 0; i < m_channels; i ++)
+ out[i] = (float *) jack_port_get_buffer (m_ports[i], frames);
+
+ int jack_rate = jack_get_sample_rate (m_client);
+
+ if (jack_rate != m_rate)
+ {
+ if (! m_rate_mismatch)
+ {
+ aud_ui_show_error (str_printf (_("The JACK server requires a "
+ "sample rate of %d Hz, but Audacious is playing at %d Hz. Please "
+ "use the Sample Rate Converter effect to correct the mismatch."),
+ jack_rate, m_rate));
+ m_rate_mismatch = true;
+ }
+
+ goto silence;
+ }
+
+ m_rate_mismatch = false;
+
+ if (m_paused || m_prebuffer)
+ goto silence;
+
+ while (frames && m_buffer.len ())
+ {
+ int linear_samples = m_buffer.linear ();
+ assert (linear_samples % m_channels == 0);
+
+ int frames_to_copy = aud::min (frames, (jack_nframes_t) linear_samples / m_channels);
+
+ audio_amplify (& m_buffer[0], m_channels, frames_to_copy, get_volume ());
+ audio_deinterlace (& m_buffer[0], FMT_FLOAT, m_channels,
+ (void * const *) out, frames_to_copy);
+
+ m_last_write_frames += frames_to_copy;
+ m_buffer.discard (frames_to_copy * m_channels);
+
+ for (int i = 0; i < m_channels; i ++)
+ out[i] += frames_to_copy;
+
+ frames -= frames_to_copy;
+ }
+
+silence:
+ for (int i = 0; i < m_channels; i ++)
+ std::fill (out[i], out[i] + frames, 0.0);
+
+ pthread_cond_broadcast (& m_cond);
+ pthread_mutex_unlock (& m_mutex);
+}
+
+void JACKOutput::period_wait ()
+{
+ pthread_mutex_lock (& m_mutex);
+
+ while (! m_buffer.space ())
+ {
+ m_prebuffer = false;
+ pthread_cond_wait (& m_cond, & m_mutex);
+ }
+
+ pthread_mutex_unlock (& m_mutex);
+}
+
+int JACKOutput::write_audio (const void * data, int size)
+{
+ pthread_mutex_lock (& m_mutex);
+
+ int samples = size / sizeof (float);
+ assert (samples % m_channels == 0);
+
+ samples = aud::min (samples, m_buffer.space ());
+
+ m_buffer.copy_in ((const float *) data, samples);
+
+ if (m_buffer.len () >= m_buffer.size () / 4)
+ m_prebuffer = false;
+
+ pthread_mutex_unlock (& m_mutex);
+ return samples * sizeof (float);
+}
+
+void JACKOutput::drain ()
+{
+ pthread_mutex_lock (& m_mutex);
+
+ m_prebuffer = false;
+
+ while (m_buffer.len () || m_last_write_frames)
+ pthread_cond_wait (& m_cond, & m_mutex);
+
+ pthread_mutex_unlock (& m_mutex);
+}
+
+int JACKOutput::get_delay ()
+{
+ auto timediff = [] (const timeval & a, const timeval & b) -> int64_t
+ { return 1000 * (int64_t) (b.tv_sec - a.tv_sec) + (b.tv_usec - a.tv_usec) / 1000; };
+
+ pthread_mutex_lock (& m_mutex);
+
+ int delay = aud::rescale (m_buffer.len (), m_channels * m_rate, 1000);
+
+ if (m_last_write_frames)
+ {
+ timeval now;
+ gettimeofday (& now, nullptr);
+
+ int written = aud::rescale (m_last_write_frames, m_rate, 1000);
+ delay += aud::max (written - timediff (m_last_write_time, now), (int64_t) 0);
+ }
+
+ pthread_mutex_unlock (& m_mutex);
+ return delay;
+}
+
+void JACKOutput::pause (bool pause)
+{
+ pthread_mutex_lock (& m_mutex);
+ m_paused = pause;
+ pthread_cond_broadcast (& m_cond);
+ pthread_mutex_unlock (& m_mutex);
+}
+
+void JACKOutput::flush ()
+{
+ pthread_mutex_lock (& m_mutex);
+
+ m_buffer.discard ();
+
+ m_prebuffer = true;
+
+ m_last_write_frames = 0;
+ m_last_write_time = timeval ();
+
+ pthread_cond_broadcast (& m_cond);
+ pthread_mutex_unlock (& m_mutex);
+}
diff --git a/src/jack/Makefile b/src/jack/Makefile
deleted file mode 100644
index 2f313bfb63e8..000000000000
--- a/src/jack/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-PLUGIN = jackout${PLUGIN_SUFFIX}
-
-SRCS = jack.c \
- bio2jack.c
-
-include ../../buildsys.mk
-include ../../extra.mk
-
-plugindir := ${plugindir}/${OUTPUT_PLUGIN_DIR}
-
-CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS} ${JACK_LIBS} -lsamplerate -lm
diff --git a/src/jack/bio2jack.c b/src/jack/bio2jack.c
deleted file mode 100644
index f00b0a6e3698..000000000000
--- a/src/jack/bio2jack.c
+++ /dev/null
@@ -1,2652 +0,0 @@
-/*
- * Copyright 2003-2006 Chris Morgan <cmorgan at alum.wpi.edu>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* NOTE: All functions that take a jack_driver_t* do NOT lock the device, in order to get a */
-/* jack_driver_t* you must call getDriver() which will pthread_mutex_lock() */
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <math.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <jack/jack.h>
-#include <jack/ringbuffer.h>
-#include <pthread.h>
-#include <sys/time.h>
-#include <samplerate.h>
-
-#include <glib.h>
-
-#include "bio2jack.h"
-
-/* enable/disable TRACING through the JACK_Callback() function */
-/* this can sometimes be too much information */
-#define TRACE_CALLBACK 0
-
-/* set to 1 for verbose output */
-#define VERBOSE_OUTPUT 0
-
-/* set to 1 to enable debug messages */
-#define DEBUG_OUTPUT 0
-
-/* set to 1 to enable tracing */
-#define TRACE_ENABLE 0
-
-/* set to 1 to enable the function timers */
-#define TIMER_ENABLE 0
-
-/* set to 1 to enable tracing of getDriver() and releaseDriver() */
-#define TRACE_getReleaseDevice 0
-
-#define ENABLE_WARNINGS 0
-
-#define DEFAULT_RB_SIZE 4096
-
-#define OUTFILE stderr
-
-#if TIMER_ENABLE
-/* This seemingly construct makes timing arbitrary functions really easy
- all you have to do is place a 'TIMER("start\n")' at the beginning and
- a 'TIMER("stop\n")' at the end of any function and this does the rest
- (naturally you can place any printf-compliant text you like in the argument
- along with the associated values). */
-static struct timeval timer_now;
-#define TIMER(format,args...) gettimeofday(&timer_now,0); \
- fprintf(OUTFILE, "%ld.%06ld: %s::%s(%d) "format, timer_now.tv_sec, timer_now.tv_usec, __FILE__, __FUNCTION__, __LINE__, ##args)
-#else
-#define TIMER(...)
-#endif
-
-#if TRACE_ENABLE
-#define TRACE(format,args...) fprintf(OUTFILE, "%s::%s(%d) "format, __FILE__, __FUNCTION__, __LINE__,##args)
-#else
-#define TRACE(...)
-#endif
-
-#if DEBUG_OUTPUT
-#define DEBUG(format,args...) fprintf(OUTFILE, "%s::%s(%d) "format, __FILE__, __FUNCTION__, __LINE__,##args)
-#else
-#define DEBUG(...)
-#endif
-
-#if TRACE_CALLBACK
-#define CALLBACK_TRACE(format,args...) fprintf(OUTFILE, "%s::%s(%d) "format, __FILE__, __FUNCTION__, __LINE__,##args)
-#else
-#define CALLBACK_TRACE(...)
-#endif
-
-#if ENABLE_WARNINGS
-#define WARN(format,args...) fprintf(OUTFILE, "WARN: %s::%s(%d) "format, __FILE__,__FUNCTION__,__LINE__,##args)
-#else
-#define WARN(...)
-#endif
-
-#define ERR(format,args...) fprintf(OUTFILE, "ERR: %s::%s(%d) "format, __FILE__,__FUNCTION__,__LINE__,##args)
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#define max(a,b) (((a) < (b)) ? (b) : (a))
-
-#define MAX_OUTPUT_PORTS 10
-#define MAX_INPUT_PORTS 10
-
-#define SAMPLE_FMT_INTEGER 0 /* Regular integer samples */
-#define SAMPLE_FMT_PACKED_24B 1 /* 24 bit samples packed to 32 bit values */
-#define SAMPLE_FMT_FLOAT 2 /* 32 bit floating point samples */
-
-typedef struct jack_driver_s
-{
- bool allocated; /* whether or not this device has been allocated */
-
- int deviceID; /* id of this device */
- int clientCtr; /* to prevent overlapping client ids */
- long jack_sample_rate; /* jack samples(frames) per second */
-
- long client_sample_rate; /* client samples(frames) per second */
- double output_sample_rate_ratio; /* ratio between jack's output rate & ours */
- double input_sample_rate_ratio; /* ratio between our input rate & jack's */
-
- unsigned long num_input_channels; /* number of input channels(1 is mono, 2 stereo etc..) */
- unsigned long num_output_channels; /* number of output channels(1 is mono, 2 stereo etc..) */
-
- unsigned long bits_per_channel; /* number of bits per channel (8, 16, 24 or 32 supported) */
- int sample_format; /* special sample format or SAMPLE_FMT_INTEGER for signed native-endian integers using all bits_per_channel bit */
-
- unsigned long bytes_per_output_frame; /* (num_output_channels * bits_per_channel) / 8 */
- unsigned long bytes_per_input_frame; /* (num_input_channels * bits_per_channel) / 8 */
-
- unsigned long bytes_per_jack_output_frame; /* (num_output_channels * bits_per_channel) / 8 */
- unsigned long bytes_per_jack_input_frame; /* (num_input_channels * bits_per_channel) / 8 */
-
- long clientBytesInJack; /* number of INPUT bytes(from the client of bio2jack) we wrote to jack(not necessary the number of bytes we wrote to jack) */
- long jack_buffer_size; /* size of the buffer jack will pass in to the process callback */
-
- unsigned long callback_buffer1_size; /* number of bytes in the buffer allocated for processing data in JACK_Callback */
- char *callback_buffer1;
- unsigned long callback_buffer2_size; /* number of bytes in the buffer allocated for processing data in JACK_Callback */
- char *callback_buffer2;
-
- unsigned long rw_buffer1_size; /* number of bytes in the buffer allocated for processing data in JACK_(Read|Write) */
- char *rw_buffer1;
-
- struct timeval previousTime; /* time of last JACK_Callback() write to jack, allows for MS accurate bytes played */
-
- unsigned long written_client_bytes; /* input bytes we wrote to jack, not necessarily actual bytes we wrote to jack due to channel and other conversion */
- unsigned long played_client_bytes; /* input bytes that jack has played */
-
- unsigned long client_bytes; /* total bytes written by the client of bio2jack via JACK_Write() */
-
- jack_port_t *output_port[MAX_OUTPUT_PORTS]; /* output ports */
- jack_port_t *input_port[MAX_OUTPUT_PORTS]; /* input ports */
-
- jack_client_t *client; /* pointer to jack client */
-
- char **jack_port_name; /* user given strings for the port names, can be NULL */
- unsigned int jack_port_name_count; /* the number of port names given */
-
- unsigned long jack_output_port_flags; /* flags to be passed to jack when opening the output ports */
- unsigned long jack_input_port_flags; /* flags to be passed to jack when opening the output ports */
-
- jack_ringbuffer_t *pPlayPtr; /* the playback ringbuffer */
- jack_ringbuffer_t *pRecPtr; /* the recording ringbuffer */
-
- SRC_STATE *output_src; /* SRC object for the output stream */
- SRC_STATE *input_src; /* SRC object for the output stream */
-
- enum status_enum state; /* one of PLAYING, PAUSED, STOPPED, CLOSED, RESET etc */
-
- unsigned int volume[MAX_OUTPUT_PORTS]; /* percentage of sample value to preserve, 100 would be no attenuation */
- enum JACK_VOLUME_TYPE volumeEffectType; /* linear or dbAttenuation, if dbAttenuation volume is the number of dBs of
- attenuation to apply, 0 volume being no attenuation, full volume */
-
- long position_byte_offset; /* an offset that we will apply to returned position queries to achieve */
- /* the position that the user of the driver desires set */
-
- bool in_use; /* true if this device is currently in use */
-
- pthread_mutex_t mutex; /* mutex to lock this specific device */
-
- /* variables used for trying to restart the connection to jack */
- bool jackd_died; /* true if jackd has died and we should try to restart it */
- struct timeval last_reconnect_attempt;
-} jack_driver_t;
-
-
-static char *client_name; /* the name bio2jack will use when creating a new
- jack client. client_name_%deviceID% will be used */
-
-
-static bool do_sample_rate_conversion; /* whether the client has requested sample rate conversion,
- default to on for improved compatibility */
-
-/*
- Which SRC converter function we should use when doing sample rate conversion.
- Default to the fastest of the 'good quality' set.
- */
-static int preferred_src_converter = SRC_SINC_FASTEST;
-
-static bool init_done = 0; /* just to prevent clients from calling JACK_Init twice, that would be very bad */
-
-static enum JACK_PORT_CONNECTION_MODE port_connection_mode = CONNECT_ALL;
-
-/* enable/disable code that allows us to close a device without actually closing the jack device */
-/* this works around the issue where jack doesn't always close devices by the time the close function call returns */
-#define JACK_CLOSE_HACK 1
-
-typedef jack_default_audio_sample_t sample_t;
-typedef jack_nframes_t nframes_t;
-
-/* allocate devices for output */
-/* if you increase this past 10, you might want to update 'out_client_name = ... ' in JACK_OpenDevice */
-#define MAX_OUTDEVICES 10
-static jack_driver_t outDev[MAX_OUTDEVICES];
-
-static pthread_mutex_t device_mutex = PTHREAD_MUTEX_INITIALIZER; /* this is to lock the entire outDev array
- to make managing it in a threaded
- environment sane */
-
-#if JACK_CLOSE_HACK
-static void JACK_CloseDevice(jack_driver_t * drv, bool close_client);
-#else
-static void JACK_CloseDevice(jack_driver_t * drv);
-#endif
-
-
-/* Prototypes */
-static int JACK_OpenDevice(jack_driver_t * drv);
-static unsigned long JACK_GetBytesFreeSpaceFromDriver(jack_driver_t * drv);
-static void JACK_ResetFromDriver(jack_driver_t * drv);
-static long JACK_GetPositionFromDriver(jack_driver_t * drv,
- enum pos_enum position, int type);
-static void JACK_CleanupDriver(jack_driver_t * drv);
-
-
-/* Return the difference between two timeval structures in terms of milliseconds */
-long
-TimeValDifference(struct timeval *start, struct timeval *end)
-{
- double long ms; /* milliseconds value */
-
- ms = end->tv_sec - start->tv_sec; /* compute seconds difference */
- ms *= (double) 1000; /* convert to milliseconds */
-
- ms += (double) (end->tv_usec - start->tv_usec) / (double) 1000; /* add on microseconds difference */
-
- return (long) ms;
-}
-
-/* get a device and lock the devices mutex */
-/* */
-/* also attempt to reconnect to jack since this function is called from */
-/* most other bio2jack functions it provides a good point to attempt reconnection */
-/* */
-/* Ok, I know this looks complicated and it kind of is. The point is that when you're
- trying to trace mutexes it's more important to know *who* called us than just that
- we were called. This uses from pre-processor trickery so that the fprintf is actually
- placed in the function making the getDriver call. Thus, the __FUNCTION__ and __LINE__
- macros will actually reference our caller, rather than getDriver. The reason the
- fprintf call is passes as a parameter is because this macro has to still return a
- jack_driver_t* and we want to log both before *and* after the getDriver call for
- easier detection of blocked calls.
- */
-#if TRACE_getReleaseDevice
-#define getDriver(x) _getDriver(x,fprintf(OUTFILE, "%s::%s(%d) getting driver %d\n", __FILE__, __FUNCTION__, __LINE__,x)); TRACE("got driver %d\n",x);
-jack_driver_t *
-_getDriver(int deviceID, int ignored)
-{
- fflush(OUTFILE);
-#else
-jack_driver_t *
-getDriver(int deviceID)
-{
-#endif
- jack_driver_t *drv = &outDev[deviceID];
-
- pthread_mutex_lock(&drv->mutex);
-
- /* should we try to restart the jack server? */
- if(drv->jackd_died && drv->client == 0)
- {
- struct timeval now;
- gettimeofday(&now, 0);
-
- /* wait 250ms before trying again */
- if(TimeValDifference(&drv->last_reconnect_attempt, &now) >= 250)
- {
- JACK_OpenDevice(drv);
- drv->last_reconnect_attempt = now;
- }
- }
-
- return drv;
-}
-
-#if TRACE_getReleaseDevice
-#define tryGetDriver(x) _tryGetDriver(x,fprintf(OUTFILE, "%s::%s(%d) trying to get driver %d\n", __FILE__, __FUNCTION__, __LINE__,x)); TRACE("got driver %d\n",x);
-jack_driver_t *
-_tryGetDriver(int deviceID, int ignored)
-{
- fflush(OUTFILE);
-#else
-jack_driver_t *
-tryGetDriver(int deviceID)
-{
-#endif
- jack_driver_t *drv = &outDev[deviceID];
-
- int err;
- if((err = pthread_mutex_trylock(&drv->mutex)) == 0)
- return drv;
-
- if(err == EBUSY)
- {
- TRACE("driver %d is busy\n",deviceID);
- return 0;
- }
-
- ERR("lock returned an error\n");
- return 0;
-}
-
-
-/* release a device's mutex */
-/* */
-/* This macro is similar to the one for getDriver above, only simpler since we only
- really need to know when the lock was release for the sake of debugging.
-*/
-#if TRACE_getReleaseDevice
-#define releaseDriver(x) TRACE("releasing driver %d\n",x->deviceID); _releaseDriver(x);
-void
-_releaseDriver(jack_driver_t * drv)
-#else
-void
-releaseDriver(jack_driver_t * drv)
-#endif
-{
- /*
- #if TRACE_getReleaseDevice
- TRACE("deviceID == %d\n", drv->deviceID);
- #endif
- */
- pthread_mutex_unlock(&drv->mutex);
-}
-
-
-/* Return a string corresponding to the input state */
-char *
-DEBUGSTATE(enum status_enum state)
-{
- if(state == PLAYING)
- return "PLAYING";
- else if(state == PAUSED)
- return "PAUSED";
- else if(state == STOPPED)
- return "STOPPED";
- else if(state == CLOSED)
- return "CLOSED";
- else if(state == RESET)
- return "RESET";
- else
- return "unknown state";
-}
-
-#define SAMPLE_MAX_24BIT 8388608.0f
-#define SAMPLE_MAX_16BIT 32768.0f
-#define SAMPLE_MAX_8BIT 255.0f
-
-/* floating point volume routine */
-/* volume should be a value between 0.0 and 1.0 */
-static void
-float_volume_effect(sample_t * buf, unsigned long nsamples, float volume,
- int skip)
-{
- if(volume < 0)
- volume = 0;
- if(volume > 1.0)
- volume = 1.0;
-
- while(nsamples--)
- {
- *buf = (*buf) * volume;
- buf += skip;
- }
-}
-
-/* place one channel into a multi-channel stream */
-static inline void
-mux(sample_t * dst, sample_t * src, unsigned long nsamples,
- unsigned long dst_skip)
-{
- /* ALERT: signed sign-extension portability !!! */
- while(nsamples--)
- {
- *dst = *src;
- dst += dst_skip;
- src++;
- }
-}
-
-/* pull one channel out of a multi-channel stream */
-static void
-demux(sample_t * dst, sample_t * src, unsigned long nsamples,
- unsigned long src_skip)
-{
- /* ALERT: signed sign-extension portability !!! */
- while(nsamples--)
- {
- *dst = *src;
- dst++;
- src += src_skip;
- }
-}
-
-/* copy floating point samples */
-static inline void
-sample_move_float_float(sample_t * dst, float * src, unsigned long nsamples)
-{
- unsigned long i;
- for(i = 0; i < nsamples; i++)
- dst[i] = (sample_t) (src[i]);
-}
-
-/* convert from 32 bit samples to floating point */
-static inline void
-sample_move_int32_float(sample_t * dst, int32_t * src, unsigned long nsamples)
-{
- unsigned long i;
- for(i = 0; i < nsamples; i++)
- dst[i] = (sample_t) (src[i] >> 8) / SAMPLE_MAX_24BIT;
-}
-
-/* convert from 24 bit samples packed into 32 bits to floating point */
-static inline void
-sample_move_int24_float(sample_t * dst, int32_t * src, unsigned long nsamples)
-{
- unsigned long i;
- for(i = 0; i < nsamples; i++)
- dst[i] = (sample_t) (src[i]) / SAMPLE_MAX_24BIT;
-}
-
-/* convert from 16 bit to floating point */
-static inline void
-sample_move_short_float(sample_t * dst, short *src, unsigned long nsamples)
-{
- /* ALERT: signed sign-extension portability !!! */
- unsigned long i;
- for(i = 0; i < nsamples; i++)
- dst[i] = (sample_t) (src[i]) / SAMPLE_MAX_16BIT;
-}
-
-/* convert from floating point to 16 bit */
-static inline void
-sample_move_float_short(short *dst, sample_t * src, unsigned long nsamples)
-{
- /* ALERT: signed sign-extension portability !!! */
- unsigned long i;
- for(i = 0; i < nsamples; i++)
- dst[i] = (short) ((src[i]) * SAMPLE_MAX_16BIT);
-}
-
-/* convert from 8 bit to floating point */
-static inline void
-sample_move_char_float(sample_t * dst, unsigned char *src, unsigned long nsamples)
-{
- /* ALERT: signed sign-extension portability !!! */
- unsigned long i;
- for(i = 0; i < nsamples; i++)
- dst[i] = (sample_t) (src[i]) / SAMPLE_MAX_8BIT;
-}
-
-/* convert from floating point to 8 bit */
-static inline void
-sample_move_float_char(unsigned char *dst, sample_t * src, unsigned long nsamples)
-{
- /* ALERT: signed sign-extension portability !!! */
- unsigned long i;
- for(i = 0; i < nsamples; i++)
- dst[i] = (char) ((src[i]) * SAMPLE_MAX_8BIT);
-}
-
-/* fill dst buffer with nsamples worth of silence */
-static void inline
-sample_silence_float(sample_t * dst, unsigned long nsamples)
-{
- /* ALERT: signed sign-extension portability !!! */
- while(nsamples--)
- {
- *dst = 0;
- dst++;
- }
-}
-
-static bool inline
-ensure_buffer_size(char **buffer, unsigned long *cur_size,
- unsigned long needed_size)
-{
- DEBUG("current size = %lu, needed size = %lu\n", *cur_size, needed_size);
- if(*cur_size >= needed_size)
- return TRUE;
- DEBUG("reallocing\n");
- char *tmp = realloc(*buffer, needed_size);
- if(tmp)
- {
- *cur_size = needed_size;
- *buffer = tmp;
- return TRUE;
- }
- DEBUG("reallocing failed\n");
- return FALSE;
-}
-
-/******************************************************************
- * JACK_callback
- *
- * every time the jack server wants something from us it calls this
- * function, so we either deliver it some sound to play or deliver it nothing
- * to play
- */
-static int
-JACK_callback(nframes_t nframes, void *arg)
-{
- jack_driver_t *drv = (jack_driver_t *) arg;
-
- int i, src_error = 0;
-
- TIMER("start\n");
- gettimeofday(&drv->previousTime, 0); /* record the current time */
-
- CALLBACK_TRACE("nframes %ld, sizeof(sample_t) == %d\n", (long) nframes,
- sizeof(sample_t));
-
- if(!drv->client)
- ERR("client is closed, this is weird...\n");
-
- sample_t *out_buffer[MAX_OUTPUT_PORTS];
- /* retrieve the buffers for the output ports */
- for(i = 0; i < drv->num_output_channels; i++)
- out_buffer[i] = (sample_t *) jack_port_get_buffer(drv->output_port[i], nframes);
-
- sample_t *in_buffer[MAX_INPUT_PORTS];
- /* retrieve the buffers for the input ports */
- for(i = 0; i < drv->num_input_channels; i++)
- in_buffer[i] = (sample_t *) jack_port_get_buffer(drv->input_port[i], nframes);
-
- /* handle playing state */
- if(drv->state == PLAYING)
- {
- /* handle playback data, if any */
- if(drv->num_output_channels > 0)
- {
- unsigned long jackFramesAvailable = nframes; /* frames we have left to write to jack */
- unsigned long numFramesToWrite; /* num frames we are writing */
- size_t inputBytesAvailable = jack_ringbuffer_read_space(drv->pPlayPtr);
- unsigned long inputFramesAvailable; /* frames we have available */
-
- inputFramesAvailable = inputBytesAvailable / drv->bytes_per_jack_output_frame;
- size_t jackBytesAvailable = jackFramesAvailable * drv->bytes_per_jack_output_frame;
-
- long read = 0;
-
- CALLBACK_TRACE("playing... jackFramesAvailable = %ld inputFramesAvailable = %ld\n",
- jackFramesAvailable, inputFramesAvailable);
-
-#if JACK_CLOSE_HACK
- if(drv->in_use == FALSE)
- {
- /* output silence if nothing is being outputted */
- for(i = 0; i < drv->num_output_channels; i++)
- sample_silence_float(out_buffer[i], nframes);
-
- return -1;
- }
-#endif
-
- /* make sure our buffer is large enough for the data we are writing */
- /* ie. callback_buffer2_size < (bytes we already wrote + bytes we are going to write in this loop) */
- if(!ensure_buffer_size
- (&drv->callback_buffer2, &drv->callback_buffer2_size,
- jackBytesAvailable))
- {
- ERR("allocated %lu bytes, need %lu bytes\n",
- drv->callback_buffer2_size, (unsigned long)jackBytesAvailable);
- return -1;
- }
-
- /* do sample rate conversion if needed & requested */
- if(drv->output_src && drv->output_sample_rate_ratio != 1.0)
- {
- long bytes_needed_write = nframes * drv->bytes_per_jack_output_frame;
-
- /* make a very good guess at how many raw bytes we'll need to satisfy jack's request after conversion */
- long bytes_needed_read = min(inputBytesAvailable,
- (double) (bytes_needed_write +
- drv->
- output_sample_rate_ratio
- *
- drv->
- bytes_per_jack_output_frame)
- / drv->output_sample_rate_ratio);
- DEBUG("guessing that we need %ld bytes in and %ld out for rate conversion ratio = %f\n",
- bytes_needed_read, bytes_needed_write,
- drv->output_sample_rate_ratio);
-
- if(!ensure_buffer_size(&drv->callback_buffer1,
- &drv->callback_buffer1_size,
- bytes_needed_read))
- {
- ERR("could not realloc callback_buffer2!\n");
- return 1;
- }
- if(!ensure_buffer_size(&drv->callback_buffer2,
- &drv->callback_buffer2_size,
- bytes_needed_write))
- {
- ERR("could not realloc callback_buffer2!\n");
- return 1;
- }
-
- if(jackFramesAvailable && inputBytesAvailable > 0)
- {
- /* read in the data, but don't move the read pointer until we know how much SRC used */
- jack_ringbuffer_peek(drv->pPlayPtr, drv->callback_buffer1,
- bytes_needed_read);
-
- SRC_DATA srcdata;
- srcdata.data_in = (sample_t *) drv->callback_buffer1;
- srcdata.input_frames = bytes_needed_read / drv->bytes_per_jack_output_frame;
- srcdata.src_ratio = drv->output_sample_rate_ratio;
- srcdata.data_out = (sample_t *) drv->callback_buffer2;
- srcdata.output_frames = nframes;
- srcdata.end_of_input = 0; // it's a stream, it never ends
- DEBUG("input_frames = %ld, output_frames = %ld\n",
- srcdata.input_frames, srcdata.output_frames);
- /* convert the sample rate */
- src_error = src_process(drv->output_src, &srcdata);
- DEBUG("used = %ld, generated = %ld, error = %d: %s.\n",
- srcdata.input_frames_used, srcdata.output_frames_gen,
- src_error, src_strerror(src_error));
-
- if(src_error == 0)
- {
- /* now we can move the read pointer */
- jack_ringbuffer_read_advance(drv->pPlayPtr,
- srcdata.
- input_frames_used *
- drv->bytes_per_jack_output_frame);
- /* add on what we wrote */
- read = srcdata.input_frames_used * drv->bytes_per_output_frame;
- jackFramesAvailable -= srcdata.output_frames_gen; /* take away what was used */
- }
- }
- }
- else /* no resampling needed or requested */
- {
- /* read as much data from the buffer as is available */
- if(jackFramesAvailable && inputBytesAvailable > 0)
- {
- /* write as many bytes as we have space remaining, or as much as we have data to write */
- numFramesToWrite = min(jackFramesAvailable, inputFramesAvailable);
- jack_ringbuffer_read(drv->pPlayPtr, drv->callback_buffer2,
- jackBytesAvailable);
- /* add on what we wrote */
- read = numFramesToWrite * drv->bytes_per_output_frame;
- jackFramesAvailable -= numFramesToWrite; /* take away what was written */
- }
- }
-
- drv->written_client_bytes += read;
- drv->played_client_bytes += drv->clientBytesInJack; /* move forward by the previous bytes we wrote since those must have finished by now */
- drv->clientBytesInJack = read; /* record the input bytes we wrote to jack */
-
- /* see if we still have jackBytesLeft here, if we do that means that we
- ran out of wave data to play and had a buffer underrun, fill in
- the rest of the space with zero bytes so at least there is silence */
- if(jackFramesAvailable)
- {
- WARN("buffer underrun of %ld frames\n", jackFramesAvailable);
- for(i = 0; i < drv->num_output_channels; i++)
- sample_silence_float(out_buffer[i] +
- (nframes - jackFramesAvailable),
- jackFramesAvailable);
- }
-
- /* if we aren't converting or we are converting and src_error == 0 then we should */
- /* apply volume and demux */
- if(!(drv->output_src && drv->output_sample_rate_ratio != 1.0) || (src_error == 0))
- {
- /* apply volume */
- for(i = 0; i < drv->num_output_channels; i++)
- {
- if(drv->volumeEffectType == dbAttenuation)
- {
- /* assume the volume setting is dB of attenuation, a volume of 0 */
- /* is 0dB attenuation */
- float volume = powf(10.0, -((float) drv->volume[i]) / 20.0);
- float_volume_effect((sample_t *) drv->callback_buffer2 + i,
- (nframes - jackFramesAvailable), volume, drv->num_output_channels);
- } else
- {
- float_volume_effect((sample_t *) drv->callback_buffer2 + i, (nframes - jackFramesAvailable),
- ((float) drv->volume[i] / 100.0),
- drv->num_output_channels);
- }
- }
-
- /* demux the stream: we skip over the number of samples we have output channels as the channel data */
- /* is encoded like chan1,chan2,chan3,chan1,chan2,chan3... */
- for(i = 0; i < drv->num_output_channels; i++)
- {
- demux(out_buffer[i],
- (sample_t *) drv->callback_buffer2 + i,
- (nframes - jackFramesAvailable), drv->num_output_channels);
- }
- }
- }
-
- /* handle record data, if any */
- if(drv->num_input_channels > 0)
- {
- long jack_bytes = nframes * drv->bytes_per_jack_input_frame; /* how many bytes jack is feeding us */
-
- if(!ensure_buffer_size(&drv->callback_buffer1, &drv->callback_buffer1_size, jack_bytes))
- {
- ERR("allocated %lu bytes, need %ld bytes\n",
- drv->callback_buffer1_size, jack_bytes);
- return -1;
- }
-
- /* mux the invividual channels into one stream */
- for(i = 0; i < drv->num_input_channels; i++)
- {
- mux((sample_t *) drv->callback_buffer1 + i, in_buffer[i],
- nframes, drv->num_input_channels);
- }
-
- /* do sample rate conversion if needed & requested */
- if(drv->input_src && drv->input_sample_rate_ratio != 1.0)
- {
- /* make a very good guess at how many raw bytes we'll need to read all the data jack gave us */
- long bytes_needed_write = (double) (jack_bytes +
- drv->input_sample_rate_ratio *
- drv->bytes_per_jack_input_frame) *
- drv->input_sample_rate_ratio;
- DEBUG("guessing that we need %ld bytes in and %ld out for rate conversion ratio = %f\n",
- nframes * drv->bytes_per_jack_input_frame,
- bytes_needed_write, drv->input_sample_rate_ratio);
-
- if(!ensure_buffer_size(&drv->callback_buffer2,
- &drv->callback_buffer2_size,
- bytes_needed_write))
- {
- ERR("could not realloc callback_buffer2!\n");
- return 1;
- }
-
- SRC_DATA srcdata;
- srcdata.data_in = (sample_t *) drv->callback_buffer1;
- srcdata.input_frames = nframes;
- srcdata.src_ratio = drv->input_sample_rate_ratio;
- srcdata.data_out = (sample_t *) drv->callback_buffer2;
- srcdata.output_frames = drv->callback_buffer2_size / drv->bytes_per_jack_input_frame;
- srcdata.end_of_input = 0; // it's a stream, it never ends
- DEBUG("input_frames = %ld, output_frames = %ld\n",
- srcdata.input_frames, srcdata.output_frames);
- /* convert the sample rate */
- src_error = src_process(drv->input_src, &srcdata);
- DEBUG("used = %ld, generated = %ld, error = %d: %s.\n",
- srcdata.input_frames_used, srcdata.output_frames_gen,
- src_error, src_strerror(src_error));
-
- if(src_error == 0)
- {
- long write_space = jack_ringbuffer_write_space(drv->pRecPtr);
- long bytes_used = srcdata.output_frames_gen * drv->bytes_per_jack_input_frame;
- /* if there isn't enough room, make some. sure this discards data, but when dealing with input sources
- it seems like it's better to throw away old data than new */
- if(write_space < bytes_used)
- {
- /* the ringbuffer is designed such that only one thread should ever access each pointer.
- since calling read_advance here will be touching the read pointer which is also accessed
- by JACK_Read, we need to lock the mutex first for safety */
- jack_driver_t *d = tryGetDriver(drv->deviceID);
- if( d )
- {
- /* double check the write space after we've gained the lock, just
- in case JACK_Read was being called before we gained it */
- write_space = jack_ringbuffer_write_space(drv->pRecPtr);
- if(write_space < bytes_used)
- {
- /* hey, we warn about underruns, we might as well warn about overruns as well */
- WARN("buffer overrun of %ld bytes\n", jack_bytes - write_space);
- jack_ringbuffer_read_advance(drv->pRecPtr, bytes_used - write_space);
- }
-
- releaseDriver(drv);
- }
- }
-
- jack_ringbuffer_write(drv->pRecPtr, drv->callback_buffer2,
- bytes_used);
- }
- }
- else /* no resampling needed */
- {
- long write_space = jack_ringbuffer_write_space(drv->pRecPtr);
- /* if there isn't enough room, make some. sure this discards data, but when dealing with input sources
- it seems like it's better to throw away old data than new */
- if(write_space < jack_bytes)
- {
- /* the ringbuffer is designed such that only one thread should ever access each pointer.
- since calling read_advance here will be touching the read pointer which is also accessed
- by JACK_Read, we need to lock the mutex first for safety */
- jack_driver_t *d = tryGetDriver(drv->deviceID);
- if( d )
- {
- /* double check the write space after we've gained the lock, just
- in case JACK_Read was being called before we gained it */
- write_space = jack_ringbuffer_write_space(drv->pRecPtr);
- if(write_space < jack_bytes)
- {
- ERR("buffer overrun of %ld bytes\n", jack_bytes - write_space);
- jack_ringbuffer_read_advance(drv->pRecPtr, jack_bytes - write_space);
- }
- releaseDriver(drv);
- }
- }
-
- jack_ringbuffer_write(drv->pRecPtr, drv->callback_buffer1,
- jack_bytes);
- }
- }
- }
- else if(drv->state == PAUSED ||
- drv->state == STOPPED ||
- drv->state == CLOSED || drv->state == RESET)
- {
- CALLBACK_TRACE("%s, outputting silence\n", DEBUGSTATE(drv->state));
-
- /* output silence if nothing is being outputted */
- for(i = 0; i < drv->num_output_channels; i++)
- sample_silence_float(out_buffer[i], nframes);
-
- /* if we were told to reset then zero out some variables */
- /* and transition to STOPPED */
- if(drv->state == RESET)
- {
- drv->written_client_bytes = 0;
- drv->played_client_bytes = 0; /* number of the clients bytes that jack has played */
-
- drv->client_bytes = 0; /* bytes that the client wrote to use */
-
- drv->clientBytesInJack = 0; /* number of input bytes in jack(not necessary the number of bytes written to jack) */
-
- drv->position_byte_offset = 0;
-
- if(drv->pPlayPtr)
- jack_ringbuffer_reset(drv->pPlayPtr);
-
- if(drv->pRecPtr)
- jack_ringbuffer_reset(drv->pRecPtr);
-
- drv->state = STOPPED; /* transition to STOPPED */
- }
- }
-
- CALLBACK_TRACE("done\n");
- TIMER("finish\n");
-
- return 0;
-}
-
-
-/******************************************************************
- * JACK_bufsize
- *
- * Called whenever the jack server changes the the max number
- * of frames passed to JACK_callback
- */
-static int
-JACK_bufsize(nframes_t nframes, void *arg)
-{
- jack_driver_t *drv = (jack_driver_t *) arg;
- TRACE("the maximum buffer size is now %lu frames\n", (long) nframes);
-
- drv->jack_buffer_size = nframes;
-
- return 0;
-}
-
-/******************************************************************
- * JACK_srate
- */
-int
-JACK_srate(nframes_t nframes, void *arg)
-{
- jack_driver_t *drv = (jack_driver_t *) arg;
-
- drv->jack_sample_rate = (long) nframes;
-
- /* make sure to recalculate the ratios needed for proper sample rate conversion */
- drv->output_sample_rate_ratio = (double) drv->jack_sample_rate / (double) drv->client_sample_rate;
- if(drv->output_src) src_set_ratio(drv->output_src, drv->output_sample_rate_ratio);
-
- drv->input_sample_rate_ratio = (double) drv->client_sample_rate / (double) drv->jack_sample_rate;
- if(drv->input_src) src_set_ratio(drv->input_src, drv->input_sample_rate_ratio);
-
- TRACE("the sample rate is now %lu/sec\n", (long) nframes);
- return 0;
-}
-
-
-/******************************************************************
- * JACK_shutdown
- *
- * if this is called then jack shut down... handle this appropriately */
-void
-JACK_shutdown(void *arg)
-{
- jack_driver_t *drv = (jack_driver_t *) arg;
-
- TRACE("\n");
-
- getDriver(drv->deviceID);
-
- drv->client = 0; /* reset client */
- drv->jackd_died = TRUE;
-
- TRACE("jack shutdown, setting client to 0 and jackd_died to true, closing device\n");
-
-#if JACK_CLOSE_HACK
- JACK_CloseDevice(drv, TRUE);
-#else
- JACK_CloseDevice(drv);
-#endif
-
- TRACE("trying to reconnect right now\n");
- /* lets see if we can't reestablish the connection */
- if(JACK_OpenDevice(drv) != ERR_SUCCESS)
- {
- ERR("unable to reconnect with jack\n");
- }
-
- releaseDriver(drv);
-}
-
-
-/******************************************************************
- * JACK_Error
- *
- * Callback for jack errors
- */
-static void
-JACK_Error(const char *desc)
-{
- ERR("%s\n", desc);
-}
-
-
-/******************************************************************
- * JACK_OpenDevice
- *
- * RETURNS: ERR_SUCCESS upon success
- */
-static int
-JACK_OpenDevice(jack_driver_t * drv)
-{
- const char **ports;
- char *our_client_name = 0;
- int i, failed = 0;
-
- TRACE("creating jack client and setting up callbacks\n");
-
-#if JACK_CLOSE_HACK
- /* see if this device is already open */
- if(drv->client)
- {
- /* if this device is already in use then it is bad for us to be in here */
- if(drv->in_use)
- return ERR_OPENING_JACK;
-
- TRACE("using existing client\n");
- drv->in_use = TRUE;
- return ERR_SUCCESS;
- }
-#endif
-
- /* set up an error handler */
- jack_set_error_function(JACK_Error);
-
-
- /* build the client name */
- our_client_name = g_strdup_printf("%s_%d_%d%02d", client_name, getpid(),
- drv->deviceID, drv->clientCtr++);
-
- /* try to become a client of the JACK server */
- TRACE("client name '%s'\n", our_client_name);
- if((drv->client = jack_client_open(our_client_name, JackNullOption | JackNoStartServer, NULL)) == 0)
- {
- /* try once more */
- TRACE("trying once more to jack_client_new");
- if((drv->client = jack_client_open(our_client_name, JackNullOption | JackNoStartServer, NULL)) == 0)
- {
- ERR("jack server not running?\n");
- g_free(our_client_name);
- return ERR_OPENING_JACK;
- }
- }
-
- g_free(our_client_name);
-
- TRACE("setting up jack callbacks\n");
-
- /* JACK server to call `JACK_callback()' whenever
- there is work to be done. */
- jack_set_process_callback(drv->client, JACK_callback, drv);
-
- /* setup a buffer size callback */
- jack_set_buffer_size_callback(drv->client, JACK_bufsize, drv);
-
- /* tell the JACK server to call `srate()' whenever
- the sample rate of the system changes. */
- jack_set_sample_rate_callback(drv->client, JACK_srate, drv);
-
- /* tell the JACK server to call `jack_shutdown()' if
- it ever shuts down, either entirely, or if it
- just decides to stop calling us. */
- jack_on_shutdown(drv->client, JACK_shutdown, drv);
-
- /* display the current sample rate. once the client is activated
- (see below), you should rely on your own sample rate
- callback (see above) for this value. */
- drv->jack_sample_rate = jack_get_sample_rate(drv->client);
- drv->output_sample_rate_ratio = (double) drv->jack_sample_rate / (double) drv->client_sample_rate;
- drv->input_sample_rate_ratio = (double) drv->client_sample_rate / (double) drv->jack_sample_rate;
- TRACE("client sample rate: %lu, jack sample rate: %lu, output ratio = %f, input ratio = %f\n",
- drv->client_sample_rate, drv->jack_sample_rate,
- drv->output_sample_rate_ratio, drv->input_sample_rate_ratio);
-
- drv->jack_buffer_size = jack_get_buffer_size(drv->client);
-
- /* create the output ports */
- TRACE("creating output ports\n");
- for(i = 0; i < drv->num_output_channels; i++)
- {
- char portname[32];
- sprintf(portname, "out_%d", i);
- TRACE("port %d is named '%s'\n", i, portname);
- /* NOTE: Yes, this is supposed to be JackPortIsOutput since this is an output */
- /* port FROM bio2jack */
- drv->output_port[i] = jack_port_register(drv->client, portname,
- JACK_DEFAULT_AUDIO_TYPE,
- JackPortIsOutput, 0);
- }
-
- /* create the input ports */
- TRACE("creating input ports\n");
- for(i = 0; i < drv->num_input_channels; i++)
- {
- char portname[32];
- sprintf(portname, "in_%d", i);
- TRACE("port %d is named '%s'\n", i, portname);
- /* NOTE: Yes, this is supposed to be JackPortIsInput since this is an input */
- /* port TO bio2jack */
- drv->input_port[i] = jack_port_register(drv->client, portname,
- JACK_DEFAULT_AUDIO_TYPE,
- JackPortIsInput, 0);
- }
-
-#if JACK_CLOSE_HACK
- drv->in_use = TRUE;
-#endif
-
- /* tell the JACK server that we are ready to roll */
- TRACE("calling jack_activate()\n");
- if(jack_activate(drv->client))
- {
- ERR("cannot activate client\n");
- return ERR_OPENING_JACK;
- }
-
- /* if we have output channels and the port connection mode isn't CONNECT_NONE */
- /* then we should connect up some ports */
- if((drv->num_output_channels > 0) && (port_connection_mode != CONNECT_NONE))
- {
- /* determine how we are to acquire output port names */
- if((drv->jack_port_name_count == 0) || (drv->jack_port_name_count == 1))
- {
- if(drv->jack_port_name_count == 0)
- {
- TRACE("jack_get_ports() passing in NULL/NULL\n");
- ports = jack_get_ports(drv->client, NULL, NULL,
- drv->jack_output_port_flags);
- }
- else
- {
- TRACE("jack_get_ports() passing in port of '%s'\n",
- drv->jack_port_name[0]);
- ports = jack_get_ports(drv->client, drv->jack_port_name[0], NULL,
- drv->jack_output_port_flags);
- }
-
- /* display a trace of the output ports we found */
- int num_ports = 0;
- if(ports)
- {
- for(i = 0; ports[i]; i++)
- {
- TRACE("ports[%d] = '%s'\n", i, ports[i]);
- num_ports++;
- }
- }
-
- /* ensure that we found enough ports */
- if(!ports || (i < drv->num_output_channels))
- {
- TRACE("ERR: jack_get_ports() failed to find ports with jack port flags of 0x%lX'\n",
- drv->jack_output_port_flags);
-#if JACK_CLOSE_HACK
- JACK_CloseDevice(drv, TRUE);
-#else
- JACK_CloseDevice(drv);
-#endif
- return ERR_PORT_NOT_FOUND;
- }
-
- /* connect a port for each output channel. Note: you can't do this before
- the client is activated (this may change in the future). */
- for(i = 0; i < drv->num_output_channels; i++)
- {
- TRACE("jack_connect() to port %d('%p')\n", i, drv->output_port[i]);
- if(jack_connect(drv->client, jack_port_name(drv->output_port[i]), ports[i]))
- {
- ERR("cannot connect to output port %d('%s')\n", i, ports[i]);
- failed = 1;
- }
- }
-
- /* only if we are in CONNECT_ALL mode should we keep connecting ports up beyond */
- /* the minimum number of ports required for each output channel coming into bio2jack */
- if(port_connection_mode == CONNECT_ALL)
- {
- /* It's much cheaper and easier to let JACK do the processing required to
- connect 2 channels to 4 or 4 channels to 2 or any other combinations.
- This effectively eliminates the need for sample_move_d16_d16() */
- if(drv->num_output_channels < num_ports)
- {
- for(i = drv->num_output_channels; ports[i]; i++)
- {
- int n = i % drv->num_output_channels;
- TRACE("jack_connect() to port %d('%p')\n", i, drv->output_port[n]);
- if(jack_connect(drv->client, jack_port_name(drv->output_port[n]), ports[i]))
- {
- // non fatal
- ERR("cannot connect to output port %d('%s')\n", n, ports[i]);
- }
- }
- }
- else if(drv->num_output_channels > num_ports)
- {
- for(i = num_ports; i < drv->num_output_channels; i++)
- {
- int n = i % num_ports;
- TRACE("jack_connect() to port %d('%p')\n", i, drv->output_port[n]);
- if(jack_connect(drv->client, jack_port_name(drv->output_port[i]), ports[n]))
- {
- // non fatal
- ERR("cannot connect to output port %d('%s')\n", i, ports[n]);
- }
- }
- }
- }
-
- g_free(ports); /* free the returned array of ports */
- }
- else
- {
- for(i = 0; i < drv->jack_port_name_count; i++)
- {
- TRACE("jack_get_ports() portname %d of '%s\n", i,
- drv->jack_port_name[i]);
- ports = jack_get_ports(drv->client, drv->jack_port_name[i], NULL,
- drv->jack_output_port_flags);
-
- if(!ports)
- {
- ERR("jack_get_ports() failed to find ports with jack port flags of 0x%lX'\n",
- drv->jack_output_port_flags);
- return ERR_PORT_NOT_FOUND;
- }
-
- TRACE("ports[%d] = '%s'\n", 0, ports[0]); /* display a trace of the output port we found */
-
- /* connect the port */
- TRACE("jack_connect() to port %d('%p')\n", i, drv->output_port[i]);
- if(jack_connect(drv->client, jack_port_name(drv->output_port[i]), ports[0]))
- {
- ERR("cannot connect to output port %d('%s')\n", 0, ports[0]);
- failed = 1;
- }
- g_free(ports); /* free the returned array of ports */
- }
- }
- } /* if( drv->num_output_channels > 0 ) */
-
-
- if(drv->num_input_channels > 0)
- {
- /* determine how we are to acquire input port names */
- if((drv->jack_port_name_count == 0) || (drv->jack_port_name_count == 1))
- {
- if(drv->jack_port_name_count == 0)
- {
- TRACE("jack_get_ports() passing in NULL/NULL\n");
- ports = jack_get_ports(drv->client, NULL, NULL, drv->jack_input_port_flags);
- }
- else
- {
- TRACE("jack_get_ports() passing in port of '%s'\n",
- drv->jack_port_name[0]);
- ports = jack_get_ports(drv->client, drv->jack_port_name[0], NULL,
- drv->jack_input_port_flags);
- }
-
- /* display a trace of the input ports we found */
- int num_ports = 0;
- if(ports)
- {
- for(i = 0; ports[i]; i++)
- {
- TRACE("ports[%d] = '%s'\n", i, ports[i]);
- num_ports++;
- }
- }
-
- /* ensure that we found enough ports */
- if(!ports || (i < drv->num_input_channels))
- {
- TRACE("ERR: jack_get_ports() failed to find ports with jack port flags of 0x%lX'\n",
- drv->jack_input_port_flags);
-#if JACK_CLOSE_HACK
- JACK_CloseDevice(drv, TRUE);
-#else
- JACK_CloseDevice(drv);
-#endif
- return ERR_PORT_NOT_FOUND;
- }
-
- /* connect the ports. Note: you can't do this before
- the client is activated (this may change in the future). */
- for(i = 0; i < drv->num_input_channels; i++)
- {
- TRACE("jack_connect() to port %d('%p')\n", i, drv->input_port[i]);
- if(jack_connect(drv->client, ports[i], jack_port_name(drv->input_port[i])))
- {
- ERR("cannot connect to input port %d('%s')\n", i, ports[i]);
- failed = 1;
- }
- }
-
- /* It's much cheaper and easier to let JACK do the processing required to
- connect 2 channels to 4 or 4 channels to 2 or any other combinations.
- This effectively eliminates the need for sample_move_d16_d16() */
- if(drv->num_input_channels < num_ports)
- {
- for(i = drv->num_input_channels; ports[i]; i++)
- {
- int n = i % drv->num_input_channels;
- TRACE("jack_connect() to port %d('%p')\n", i, drv->input_port[n]);
- if(jack_connect(drv->client, ports[i], jack_port_name(drv->input_port[n])))
- {
- // non fatal
- ERR("cannot connect to input port %d('%s')\n", n, ports[i]);
- }
- }
- }
- else if(drv->num_input_channels > num_ports)
- {
- for(i = num_ports; i < drv->num_input_channels; i++)
- {
- int n = i % num_ports;
- TRACE("jack_connect() to port %d('%p')\n", i, drv->input_port[n]);
- if(jack_connect(drv->client, ports[n], jack_port_name(drv->input_port[i])))
- {
- // non fatal
- ERR("cannot connect to input port %d('%s')\n", i, ports[n]);
- }
- }
- }
-
- g_free(ports); /* free the returned array of ports */
- }
- else
- {
- for(i = 0; i < drv->jack_port_name_count; i++)
- {
- TRACE("jack_get_ports() portname %d of '%s\n", i,
- drv->jack_port_name[i]);
- ports = jack_get_ports(drv->client, drv->jack_port_name[i], NULL,
- drv->jack_input_port_flags);
-
- if(!ports)
- {
- ERR("jack_get_ports() failed to find ports with jack port flags of 0x%lX'\n",
- drv->jack_input_port_flags);
- return ERR_PORT_NOT_FOUND;
- }
-
- TRACE("ports[%d] = '%s'\n", 0, ports[0]); /* display a trace of the input port we found */
-
- /* connect the port */
- TRACE("jack_connect() to port %d('%p')\n", i, drv->input_port[i]);
- if(jack_connect(drv->client, jack_port_name(drv->input_port[i]), ports[0]))
- {
- ERR("cannot connect to input port %d('%s')\n", 0, ports[0]);
- failed = 1;
- }
- g_free(ports); /* free the returned array of ports */
- }
- }
- } /* if( drv->num_input_channels > 0 ) */
-
- /* if something failed we need to shut the client down and return 0 */
- if(failed)
- {
- TRACE("failed, closing and returning error\n");
-#if JACK_CLOSE_HACK
- JACK_CloseDevice(drv, TRUE);
-#else
- JACK_CloseDevice(drv);
-#endif
- return ERR_OPENING_JACK;
- }
-
- TRACE("success\n");
-
- drv->jackd_died = FALSE; /* clear out this flag so we don't keep attempting to restart things */
- drv->state = PLAYING; /* clients seem to behave much better with this on from the start, especially when recording */
-
- return ERR_SUCCESS; /* return success */
-}
-
-
-/******************************************************************
- * JACK_CloseDevice
- *
- * Close the connection to the server cleanly.
- * If close_client is TRUE we close the client for this device instead of
- * just marking the device as in_use(JACK_CLOSE_HACK only)
- */
-#if JACK_CLOSE_HACK
-static void
-JACK_CloseDevice(jack_driver_t * drv, bool close_client)
-#else
-static void
-JACK_CloseDevice(jack_driver_t * drv)
-#endif
-{
- unsigned int i;
-
-#if JACK_CLOSE_HACK
- if(close_client)
- {
-#endif
-
- TRACE("closing the jack client thread\n");
- if(drv->client)
- {
- TRACE("after jack_deactivate()\n");
- int errorCode = jack_client_close(drv->client);
- if(errorCode)
- ERR("jack_client_close() failed returning an error code of %d\n",
- errorCode);
- }
-
- /* reset client */
- drv->client = 0;
-
- /* free up the port strings */
- TRACE("freeing up %d port strings\n", drv->jack_port_name_count);
- if(drv->jack_port_name_count > 1)
- {
- for(i = 0; i < drv->jack_port_name_count; i++)
- g_free(drv->jack_port_name[i]);
- g_free(drv->jack_port_name);
- }
- JACK_CleanupDriver(drv);
-
- JACK_ResetFromDriver(drv);
-
-#if JACK_CLOSE_HACK
- } else
- {
- TRACE("setting in_use to FALSE\n");
- drv->in_use = FALSE;
-
- if(!drv->client)
- {
- TRACE("critical error, closing a device that has no client\n");
- }
- }
-#endif
-}
-
-
-
-
-/**************************************/
-/* External interface functions below */
-/**************************************/
-
-/* Clear out any buffered data, stop playing, zero out some variables */
-static void
-JACK_ResetFromDriver(jack_driver_t * drv)
-{
- TRACE("resetting drv->deviceID(%d)\n", drv->deviceID);
-
- /* NOTE: we use the RESET state so we don't need to worry about clearing out */
- /* variables that the callback modifies while the callback is running */
- /* we set the state to RESET and the callback clears the variables out for us */
- drv->state = RESET; /* tell the callback that we are to reset, the callback will transition this to STOPPED */
-}
-
-/* Clear out any buffered data, stop playing, zero out some variables */
-void
-JACK_Reset(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- TRACE("resetting deviceID(%d)\n", deviceID);
- JACK_ResetFromDriver(drv);
- releaseDriver(drv);
-}
-
-
-/*
- * open the audio device for writing to
- *
- * deviceID is set to the opened device
- * if client is non-zero and in_use is FALSE then just set in_use to TRUE
- *
- * return value is zero upon success, non-zero upon failure
- *
- * if ERR_RATE_MISMATCH (*rate) will be updated with the jack servers rate
- */
-int
-JACK_Open(int *deviceID, unsigned int bits_per_channel, int floating_point,
- unsigned long *rate, int channels)
-{
- /* we call through to JACK_OpenEx(), but default the input channels to 0 for better backwards
- compatibility with clients written before recording was available */
- return JACK_OpenEx(deviceID, bits_per_channel,
- floating_point, rate,
- 0, channels,
- NULL, 0, JackPortIsPhysical);
-}
-
-/*
- * see JACK_Open() for comments
- * NOTE: jack_port_name has three ways of being used:
- * - NULL - finds all ports with the given flags
- * - A single regex string used to retrieve all port names
- * - A series of port names, one for each output channel
- *
- * we set *deviceID
- */
-int
-JACK_OpenEx(int *deviceID, unsigned int bits_per_channel,
- int floating_point, unsigned long *rate,
- unsigned int input_channels, unsigned int output_channels,
- const char **jack_port_name,
- unsigned int jack_port_name_count, unsigned long jack_port_flags)
-{
- jack_driver_t *drv = 0;
- int sample_format = SAMPLE_FMT_INTEGER;
- unsigned int i;
- int retval;
-
- if(input_channels < 1 && output_channels < 1)
- {
- ERR("no input OR output channels, nothing to do\n");
- return ERR_OPENING_JACK;
- }
-
- switch (bits_per_channel)
- {
- case 8:
- case 16:
- case 32:
- break;
- case 24:
- bits_per_channel = 32;
- sample_format = SAMPLE_FMT_PACKED_24B;
- break;
- default:
- ERR("invalid bits_per_channel\n");
- return ERR_OPENING_JACK;
- }
-
- if (floating_point)
- {
- if (bits_per_channel != 32) {
- ERR("bits_per_channel must be 32 for floating point\n");
- return ERR_OPENING_JACK;
- }
- else
- {
- sample_format = SAMPLE_FMT_FLOAT;
- }
- }
-
- /* Lock the device_mutex and find one that's not allocated already.
- We'll keep this lock until we've either made use of it, or given up. */
- pthread_mutex_lock(&device_mutex);
-
- for(i = 0; i < MAX_OUTDEVICES; i++)
- {
- if(!outDev[i].allocated)
- {
- drv = &outDev[i];
- break;
- }
- }
-
- if(!drv)
- {
- ERR("no more devices available\n");
- pthread_mutex_unlock(&device_mutex);
- return ERR_OPENING_JACK;
- }
-
- /* We found an unallocated device, now lock it for extra saftey */
- getDriver(drv->deviceID);
-
- TRACE("bits_per_channel=%d rate=%ld, input_channels=%d, output_channels=%d\n",
- bits_per_channel, *rate, input_channels, output_channels);
-
- if(output_channels > MAX_OUTPUT_PORTS)
- {
- ERR("output_channels == %u, MAX_OUTPUT_PORTS == %u\n", output_channels,
- MAX_OUTPUT_PORTS);
- releaseDriver(drv);
- pthread_mutex_unlock(&device_mutex);
- return ERR_TOO_MANY_OUTPUT_CHANNELS;
- }
-
- if(input_channels > MAX_INPUT_PORTS)
- {
- ERR("input_channels == %u, MAX_INPUT_PORTS == %u\n", input_channels,
- MAX_INPUT_PORTS);
- releaseDriver(drv);
- pthread_mutex_unlock(&device_mutex);
- return ERR_TOO_MANY_INPUT_CHANNELS;
- }
-
- drv->jack_output_port_flags = jack_port_flags | JackPortIsInput; /* port must be input(ie we can put data into it), so mask this in */
- drv->jack_input_port_flags = jack_port_flags | JackPortIsOutput; /* port must be output(ie we can get data from it), so mask this in */
-
- /* check that we have the correct number of port names
- FIXME?: not sure how we should handle output ports vs input ports....
- */
- if((jack_port_name_count > 1)
- && ((jack_port_name_count < output_channels)
- || (jack_port_name_count < input_channels)))
- {
- ERR("specified individual port names but not enough, gave %u names, need %u\n",
- jack_port_name_count, output_channels);
- releaseDriver(drv);
- pthread_mutex_unlock(&device_mutex);
- return ERR_PORT_NAME_OUTPUT_CHANNEL_MISMATCH;
- } else
- {
- /* copy this data into the device information */
- drv->jack_port_name_count = jack_port_name_count;
-
- if(drv->jack_port_name_count != 0)
- {
- drv->jack_port_name = g_new(char *, drv->jack_port_name_count);
- for(i = 0; i < drv->jack_port_name_count; i++)
- {
- drv->jack_port_name[i] = g_strdup(jack_port_name[i]);
- TRACE("jack_port_name[%d] == '%s'\n", i, jack_port_name[i]);
- }
- } else
- {
- drv->jack_port_name = NULL;
- TRACE("jack_port_name = NULL\n");
- }
- }
-
- /* initialize some variables */
- drv->in_use = FALSE;
-
- JACK_ResetFromDriver(drv); /* flushes all queued buffers, sets status to STOPPED and resets some variables */
-
- /* drv->jack_sample_rate is set by JACK_OpenDevice() */
- drv->client_sample_rate = *rate;
- drv->bits_per_channel = bits_per_channel;
- drv->sample_format = sample_format;
- drv->num_input_channels = input_channels;
- drv->num_output_channels = output_channels;
- drv->bytes_per_input_frame = (drv->bits_per_channel * drv->num_input_channels) / 8;
- drv->bytes_per_output_frame = (drv->bits_per_channel * drv->num_output_channels) / 8;
- drv->bytes_per_jack_output_frame = sizeof(sample_t) * drv->num_output_channels;
- drv->bytes_per_jack_input_frame = sizeof(sample_t) * drv->num_input_channels;
-
- if(drv->num_output_channels > 0)
- {
- drv->pPlayPtr = jack_ringbuffer_create(drv->num_output_channels *
- drv->bytes_per_jack_output_frame *
- DEFAULT_RB_SIZE);
- }
-
- if(drv->num_input_channels > 0)
- {
- drv->pRecPtr = jack_ringbuffer_create(drv->num_input_channels *
- drv->bytes_per_jack_input_frame *
- DEFAULT_RB_SIZE);
- }
-
- DEBUG("bytes_per_output_frame == %ld\n", drv->bytes_per_output_frame);
- DEBUG("bytes_per_input_frame == %ld\n", drv->bytes_per_input_frame);
- DEBUG("bytes_per_jack_output_frame == %ld\n",
- drv->bytes_per_jack_output_frame);
- DEBUG("bytes_per_jack_input_frame == %ld\n",
- drv->bytes_per_jack_input_frame);
-
- /* go and open up the device */
- retval = JACK_OpenDevice(drv);
- if(retval != ERR_SUCCESS)
- {
- TRACE("error opening jack device\n");
- releaseDriver(drv);
- pthread_mutex_unlock(&device_mutex);
- return retval;
- }
- else
- {
- TRACE("succeeded opening jack device\n");
- }
-
- /* setup SRC objects just in case they'll be needed but only if requested */
- if(do_sample_rate_conversion)
- {
- int error;
- if(drv->num_output_channels > 0)
- {
- drv->output_src = src_new(preferred_src_converter, drv->num_output_channels, &error);
- if(error != 0)
- {
- src_delete(drv->output_src);
- drv->output_src = 0;
- ERR("Could not created SRC object for output stream %d: %s\n",
- error, src_strerror(error));
- }
- }
- if(drv->num_input_channels > 0)
- {
- drv->input_src = src_new(preferred_src_converter, drv->num_input_channels, &error);
- if(error != 0)
- {
- src_delete(drv->input_src);
- drv->input_src = 0;
- ERR("Could not created SRC object for input stream %d: %s\n",
- error, src_strerror(error));
- }
- }
- }
- else if((long) (*rate) != drv->jack_sample_rate)
- {
- TRACE("rate of %ld doesn't match jack sample rate of %ld, returning error\n",
- *rate, drv->jack_sample_rate);
- *rate = drv->jack_sample_rate;
-#if JACK_CLOSE_HACK
- JACK_CloseDevice(drv, TRUE);
-#else
- JACK_CloseDevice(drv);
-#endif
- releaseDriver(drv);
- pthread_mutex_unlock(&device_mutex);
- return ERR_RATE_MISMATCH;
- }
-
- drv->allocated = TRUE; /* record that we opened this device */
-
- DEBUG("sizeof(sample_t) == %d\n", sizeof(sample_t));
-
- *deviceID = drv->deviceID; /* set the deviceID for the caller */
- releaseDriver(drv);
- pthread_mutex_unlock(&device_mutex);
- return ERR_SUCCESS; /* success */
-}
-
-/* Close the jack device */
-//FIXME: add error handling in here at some point...
-/* NOTE: return 0 for success, non-zero for failure */
-int
-JACK_Close(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
-
- TRACE("deviceID(%d)\n", deviceID);
-
-#if JACK_CLOSE_HACK
- JACK_CloseDevice(drv, TRUE);
-#else
- JACK_CloseDevice(drv);
-#endif
-
- JACK_ResetFromDriver(drv); /* reset this device to a normal starting state */
-
- pthread_mutex_lock(&device_mutex);
-
- /* free buffer memory */
- drv->callback_buffer1_size = 0;
- if(drv->callback_buffer1) g_free(drv->callback_buffer1);
- drv->callback_buffer1 = 0;
-
- drv->callback_buffer2_size = 0;
- if(drv->callback_buffer2) g_free(drv->callback_buffer2);
- drv->callback_buffer2 = 0;
-
- drv->rw_buffer1_size = 0;
- if(drv->rw_buffer1) g_free(drv->rw_buffer1);
- drv->rw_buffer1 = 0;
-
- if(drv->pPlayPtr) jack_ringbuffer_free(drv->pPlayPtr);
- drv->pPlayPtr = 0;
-
- if(drv->pRecPtr) jack_ringbuffer_free(drv->pRecPtr);
- drv->pRecPtr = 0;
-
- /* free the SRC objects */
- if(drv->output_src) src_delete(drv->output_src);
- drv->output_src = 0;
-
- if(drv->input_src) src_delete(drv->input_src);
- drv->input_src = 0;
-
- drv->allocated = FALSE; /* release this device */
-
- pthread_mutex_unlock(&device_mutex);
-
- releaseDriver(drv);
-
- return 0;
-}
-
-/* If we haven't already taken in the max allowed data then create a wave header */
-/* to package the audio data and attach the wave header to the end of the */
-/* linked list of wave headers */
-/* These wave headers will be peeled off as they are played by the callback routine */
-/* Return value is the number of bytes written */
-/* NOTE: this function takes the length of data to be written bytes */
-long
-JACK_Write(int deviceID, unsigned char *data, unsigned long bytes)
-{
- jack_driver_t *drv = getDriver(deviceID);
-
- long frames_free, frames;
-
- TIMER("start\n");
-
- TRACE("deviceID(%d), bytes == %ld\n", deviceID, bytes);
-
- /* check and see that we have enough space for this audio */
- frames_free =
- jack_ringbuffer_write_space(drv->pPlayPtr) /
- drv->bytes_per_jack_output_frame;
- frames = bytes / drv->bytes_per_output_frame;
- TRACE("frames free == %ld, bytes = %lu\n", frames_free, bytes);
-
- TRACE("state = '%s'\n", DEBUGSTATE(drv->state));
- /* if we are currently STOPPED we should start playing now...
- do this before the check for bytes == 0 since some clients like
- to write 0 bytes the first time out */
- if(drv->state == STOPPED)
- {
- TRACE("currently STOPPED, transitioning to PLAYING\n");
- drv->state = PLAYING;
- }
-
- /* handle the case where the user calls this routine with 0 bytes */
- if(bytes == 0 || frames_free < 1)
- {
- TRACE("no room left\n");
- TIMER("finish (nothing to do, buffer is full)\n");
- releaseDriver(drv);
- return 0; /* indicate that we couldn't write any bytes */
- }
-
- frames = min(frames, frames_free);
- long jack_bytes = frames * drv->bytes_per_jack_output_frame;
- if(!ensure_buffer_size(&drv->rw_buffer1, &drv->rw_buffer1_size, jack_bytes))
- {
- ERR("couldn't allocate enough space for the buffer\n");
- releaseDriver(drv);
- return 0;
- }
- /* adjust bytes to be how many client bytes we're actually writing */
- bytes = frames * drv->bytes_per_output_frame;
-
- /* convert from client samples to jack samples
- we have to tell it how many samples there are, which is frames * channels */
- switch (drv->bits_per_channel)
- {
- case 8:
- sample_move_char_float((sample_t *) drv->rw_buffer1, (unsigned char *) data,
- frames * drv->num_output_channels);
- break;
- case 16:
- sample_move_short_float((sample_t *) drv->rw_buffer1, (short *) data,
- frames * drv->num_output_channels);
- break;
- case 32:
- if (drv->sample_format == SAMPLE_FMT_FLOAT)
- sample_move_float_float((sample_t *) drv->rw_buffer1, (float *) data,
- frames * drv->num_output_channels);
- else if (drv->sample_format == SAMPLE_FMT_PACKED_24B)
- sample_move_int24_float((sample_t *) drv->rw_buffer1, (int32_t *) data,
- frames * drv->num_output_channels);
- else
- sample_move_int32_float((sample_t *) drv->rw_buffer1, (int32_t *) data,
- frames * drv->num_output_channels);
- break;
- }
-
- DEBUG("ringbuffer read space = %d, write space = %d\n",
- jack_ringbuffer_read_space(drv->pPlayPtr),
- jack_ringbuffer_write_space(drv->pPlayPtr));
-
- jack_ringbuffer_write(drv->pPlayPtr, drv->rw_buffer1, jack_bytes);
- DEBUG("wrote %lu bytes, %lu jack_bytes\n", bytes, jack_bytes);
-
- DEBUG("ringbuffer read space = %d, write space = %d\n",
- jack_ringbuffer_read_space(drv->pPlayPtr),
- jack_ringbuffer_write_space(drv->pPlayPtr));
-
- drv->client_bytes += bytes; /* update client_bytes */
-
- TIMER("finish\n");
-
- DEBUG("returning bytes written of %ld\n", bytes);
-
- releaseDriver(drv);
- return bytes; /* return the number of bytes we wrote out */
-}
-
-long
-JACK_Read(int deviceID, unsigned char *data, unsigned long bytes)
-{
- jack_driver_t *drv = getDriver(deviceID);
-
- long frames_available, frames;
-
- TIMER("start\n");
-
- TRACE("deviceID(%d), bytes == %ld\n", deviceID, bytes);
-
- /* find out if there's any room to write this data */
- frames_available =
- jack_ringbuffer_read_space(drv->pRecPtr) /
- drv->bytes_per_jack_input_frame;
- frames = bytes / drv->bytes_per_input_frame;
- DEBUG("frames available = %ld, bytes = %lu\n", frames_available, bytes);
-
- TRACE("state = '%s'\n", DEBUGSTATE(drv->state));
- /* if we are currently STOPPED we should start recording now... */
- if(drv->state == STOPPED)
- {
- TRACE("currently STOPPED, transitioning to PLAYING\n");
- drv->state = PLAYING;
- }
-
- /* handle the case where the user calls this routine with 0 bytes */
- if(bytes == 0 || frames_available < 1)
- {
- TRACE("no bytes in buffer\n");
-
- TIMER("finish (nothing to do)\n");
- releaseDriver(drv);
- return 0;
- }
-
- frames = min(frames, frames_available);
- long jack_bytes = frames * drv->bytes_per_jack_input_frame;
- if(!ensure_buffer_size(&drv->rw_buffer1, &drv->rw_buffer1_size, jack_bytes))
- {
- ERR("couldn't allocate enough space for the buffer\n");
- releaseDriver(drv);
- return 0;
- }
-
- DEBUG("ringbuffer read space = %d, write space = %d\n",
- jack_ringbuffer_read_space(drv->pRecPtr),
- jack_ringbuffer_write_space(drv->pRecPtr));
-
- jack_ringbuffer_read(drv->pRecPtr, drv->rw_buffer1,
- frames * drv->bytes_per_jack_input_frame);
-
- DEBUG("ringbuffer read space = %d, write space = %d\n",
- jack_ringbuffer_read_space(drv->pRecPtr),
- jack_ringbuffer_write_space(drv->pRecPtr));
-
- int i;
- for(i = 0; i < drv->num_output_channels; i++)
- {
- /* apply volume to the floating value */
- if(drv->volumeEffectType == dbAttenuation)
- {
- /* assume the volume setting is dB of attenuation, a volume of 0 */
- /* is 0dB attenuation */
- float volume = powf(10.0, -((float) drv->volume[i]) / 20.0);
- float_volume_effect((sample_t *) drv->rw_buffer1 + i,
- frames, volume, drv->num_output_channels);
- } else
- {
- float_volume_effect((sample_t *) drv->rw_buffer1 + i, frames,
- ((float) drv->volume[i] / 100.0),
- drv->num_output_channels);
- }
- }
-
- /* convert from jack samples to client samples
- we have to tell it how many samples there are, which is frames * channels */
- switch (drv->bits_per_channel)
- {
- case 8:
- sample_move_float_char((unsigned char *) data, (sample_t *) drv->rw_buffer1,
- frames * drv->num_input_channels);
- break;
- case 16:
- sample_move_float_short((short *) data, (sample_t *) drv->rw_buffer1,
- frames * drv->num_input_channels);
- break;
- }
-
- TIMER("finish\n");
-
- long read_bytes = frames * drv->bytes_per_input_frame;
-
- DEBUG("returning bytes read of %ld\n", bytes);
-
- releaseDriver(drv);
- return read_bytes;
-}
-
-/* return ERR_SUCCESS for success */
-static int
-JACK_SetVolumeForChannelFromDriver(jack_driver_t * drv,
- unsigned int channel, unsigned int volume)
-{
- /* TODO?: maybe we should have different volume levels for input & output */
- /* ensure that we have the channel we are setting volume for */
- if(channel > (drv->num_output_channels - 1))
- return 1;
-
- if(volume > 100)
- volume = 100; /* check for values in excess of max */
-
- drv->volume[channel] = volume;
- return ERR_SUCCESS;
-}
-
-/* return ERR_SUCCESS for success */
-int
-JACK_SetVolumeForChannel(int deviceID, unsigned int channel,
- unsigned int volume)
-{
- jack_driver_t *drv = getDriver(deviceID);
- int retval = JACK_SetVolumeForChannelFromDriver(drv, channel, volume);
- releaseDriver(drv);
- return retval;
-}
-
-/* Set the volume */
-/* return 0 for success */
-/* NOTE: we check for invalid volume values */
-int
-JACK_SetAllVolume(int deviceID, unsigned int volume)
-{
- jack_driver_t *drv = getDriver(deviceID);
- unsigned int i;
-
- TRACE("deviceID(%d), setting volume of %d\n", deviceID, volume);
-
- for(i = 0; i < drv->num_output_channels; i++)
- {
- if(JACK_SetVolumeForChannelFromDriver(drv, i, volume) != ERR_SUCCESS)
- {
- releaseDriver(drv);
- return 1;
- }
- }
-
- releaseDriver(drv);
- return ERR_SUCCESS;
-}
-
-/* Return the current volume in the inputted pointers */
-/* NOTE: we check for null pointers being passed in just in case */
-void
-JACK_GetVolumeForChannel(int deviceID, unsigned int channel,
- unsigned int *volume)
-{
- jack_driver_t *drv = getDriver(deviceID);
-
- /* ensure that we have the channel we are getting volume for */
- if(channel > (drv->num_output_channels - 1))
- {
- ERR("asking for channel index %u but we only have %lu channels\n", channel, drv->num_output_channels);
- releaseDriver(drv);
- return;
- }
-
- if(volume)
- *volume = drv->volume[channel];
-
-#if VERBOSE_OUTPUT
- if(volume)
- {
- TRACE("deviceID(%d), returning volume of %d for channel %d\n",
- deviceID, *volume, channel);
- }
- else
- {
- TRACE("volume is null, can't dereference it\n");
- }
-#endif
-
- releaseDriver(drv);
-}
-
-
-/* linear means 0 volume is silence, 100 is full volume */
-/* dbAttenuation means 0 volume is 0dB attenuation */
-/* Bio2jack defaults to linear */
-enum JACK_VOLUME_TYPE
-JACK_SetVolumeEffectType(int deviceID, enum JACK_VOLUME_TYPE type)
-{
- enum JACK_VOLUME_TYPE retval;
- jack_driver_t *drv = getDriver(deviceID);
-
- TRACE("setting type of '%s'\n",
- (type == dbAttenuation ? "dbAttenuation" : "linear"));
-
- retval = drv->volumeEffectType;
- drv->volumeEffectType = type;
-
- releaseDriver(drv);
- return retval;
-}
-
-
-/* Controls the state of the playback(playing, paused, ...) */
-int
-JACK_SetState(int deviceID, enum status_enum state)
-{
- jack_driver_t *drv = getDriver(deviceID);
-
- switch (state)
- {
- case PAUSED:
- drv->state = PAUSED;
- break;
- case PLAYING:
- drv->state = PLAYING;
- break;
- case STOPPED:
- drv->state = STOPPED;
- break;
- default:
- TRACE("unknown state of %d\n", state);
- }
-
- TRACE("%s\n", DEBUGSTATE(drv->state));
-
- releaseDriver(drv);
- return 0;
-}
-
-/* Retrieve the current state of the device */
-enum status_enum
-JACK_GetState(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- enum status_enum return_val;
-
- return_val = drv->state;
- releaseDriver(drv);
-
- TRACE("deviceID(%d), returning current state of %s\n", deviceID,
- DEBUGSTATE(return_val));
- return return_val;
-}
-
-/* Retrieve the number of bytes per second we are outputting */
-unsigned long
-JACK_GetOutputBytesPerSecondFromDriver(jack_driver_t * drv)
-{
- unsigned long return_val;
-
- return_val = drv->bytes_per_output_frame * drv->client_sample_rate;
-
-#if VERBOSE_OUTPUT
- TRACE("deviceID(%d), return_val = %ld\n", drv->deviceID, return_val);
-#endif
-
- return return_val;
-}
-
-/* Retrieve the number of bytes per second we are outputting */
-unsigned long
-JACK_GetOutputBytesPerSecond(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- unsigned long return_val;
-
- return_val = JACK_GetOutputBytesPerSecondFromDriver(drv);
- releaseDriver(drv);
-
- return return_val;
-}
-
-/* Retrieve the number of input bytes(from jack) per second we are outputting
- to the user of bio2jack */
-static long
-JACK_GetInputBytesPerSecondFromDriver(jack_driver_t * drv)
-{
- long return_val;
-
- return_val = drv->bytes_per_input_frame * drv->client_sample_rate;
-#if VERBOSE_OUTPUT
- TRACE("drv->deviceID(%d), return_val = %ld\n", drv->deviceID, return_val);
-#endif
-
- return return_val;
-}
-
-/* Retrieve the number of input bytes(from jack) per second we are outputting
- to the user of bio2jack */
-unsigned long
-JACK_GetInputBytesPerSecond(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- long return_val = JACK_GetInputBytesPerSecondFromDriver(drv);
- releaseDriver(drv);
-
-#if VERBOSE_OUTPUT
- TRACE("deviceID(%d), return_val = %ld\n", deviceID, return_val);
-#endif
-
- return return_val;
-}
-
-/* Return the number of bytes we have buffered thus far for output */
-/* NOTE: convert from output bytes to input bytes in here */
-static long
-JACK_GetBytesStoredFromDriver(jack_driver_t * drv)
-{
- if(drv->pPlayPtr == 0 || drv->bytes_per_jack_output_frame == 0)
- return 0;
-
- /* leave at least one frame in the buffer at all times to prevent underruns */
- long return_val =
- jack_ringbuffer_read_space(drv->pPlayPtr) - drv->jack_buffer_size;
- if(return_val <= 0)
- {
- return_val = 0;
- } else
- {
- /* adjust from jack bytes to client bytes */
- return_val =
- return_val / drv->bytes_per_jack_output_frame *
- drv->bytes_per_output_frame;
- }
-
- return return_val;
-}
-
-/* An approximation of how many bytes we have to send out to jack */
-/* that is computed as if we were sending jack a continuous stream of */
-/* bytes rather than chunks during discrete callbacks. */
-/* Return the number of bytes we have buffered thus far for output */
-/* NOTE: convert from output bytes to input bytes in here */
-unsigned long
-JACK_GetBytesStored(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- long retval = JACK_GetBytesStoredFromDriver(drv);
- releaseDriver(drv);
- TRACE("deviceID(%d), retval = %ld\n", deviceID, retval);
- return retval;
-}
-
-static unsigned long
-JACK_GetBytesFreeSpaceFromDriver(jack_driver_t * drv)
-{
- if(drv->pPlayPtr == 0 || drv->bytes_per_jack_output_frame == 0)
- return 0;
-
- /* leave at least one frame in the buffer at all times to prevent underruns */
- long return_val = jack_ringbuffer_write_space(drv->pPlayPtr) - drv->jack_buffer_size;
- if(return_val <= 0)
- {
- return_val = 0;
- } else
- {
- /* adjust from jack bytes to client bytes */
- return_val =
- return_val / drv->bytes_per_jack_output_frame *
- drv->bytes_per_output_frame;
- }
-
- return return_val;
-}
-
-/* Return the number of bytes we can write to the device */
-unsigned long
-JACK_GetBytesFreeSpace(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- unsigned long return_val;
-
- return_val = JACK_GetBytesFreeSpaceFromDriver(drv);
- releaseDriver(drv);
-
- TRACE("deviceID(%d), retval == %ld\n", deviceID, return_val);
-
- return return_val;
-}
-
-/* bytes of space used in the input buffer */
-unsigned long
-JACK_GetBytesUsedSpace(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- long return_val;
-
- if(drv->pRecPtr == 0 || drv->bytes_per_jack_input_frame == 0)
- {
- return_val = 0;
- } else
- {
- /* adjust from jack bytes to client bytes */
- return_val =
- jack_ringbuffer_read_space(drv->pRecPtr) /
- drv->bytes_per_jack_input_frame * drv->bytes_per_input_frame;
- }
-
- releaseDriver(drv);
-
- if(return_val < 0)
- return_val = 0;
- TRACE("deviceID(%d), retval == %ld\n", deviceID, return_val);
-
- return return_val;
-}
-
-/* Get the current position of the driver, either in bytes or */
-/* in milliseconds */
-/* NOTE: this is position relative to input bytes, output bytes may differ greatly due to
- input vs. output channel count */
-static long
-JACK_GetPositionFromDriver(jack_driver_t * drv, enum pos_enum position,
- int type)
-{
- long return_val = 0;
- struct timeval now;
- long elapsedMS;
- double sec2msFactor = 1000;
-
-#if TRACE_ENABLE
- char *type_str = "UNKNOWN type";
-#endif
-
- /* if we are reset we should return a position of 0 */
- if(drv->state == RESET)
- {
- TRACE("we are currently RESET, returning 0\n");
- return 0;
- }
-
- if(type == WRITTEN)
- {
-#if TRACE_ENABLE
- type_str = "WRITTEN";
-#endif
- return_val = drv->client_bytes;
- } else if(type == WRITTEN_TO_JACK)
- {
-#if TRACE_ENABLE
- type_str = "WRITTEN_TO_JACK";
-#endif
- return_val = drv->written_client_bytes;
- } else if(type == PLAYED) /* account for the elapsed time for the played_bytes */
- {
-#if TRACE_ENABLE
- type_str = "PLAYED";
-#endif
- return_val = drv->played_client_bytes;
- gettimeofday(&now, 0);
-
- elapsedMS = TimeValDifference(&drv->previousTime, &now); /* find the elapsed milliseconds since last JACK_Callback() */
-
- TRACE("elapsedMS since last callback is '%ld'\n", elapsedMS);
-
- /* account for the bytes played since the last JACK_Callback() */
- /* NOTE: [Xms * (Bytes/Sec)] * (1 sec/1,000ms) */
- /* NOTE: don't do any compensation if no data has been sent to jack since the last callback */
- /* as this would result a bogus computed result */
- if(drv->clientBytesInJack != 0)
- {
- return_val += (long) ((double) elapsedMS *
- ((double) JACK_GetOutputBytesPerSecondFromDriver(drv) /
- sec2msFactor));
- } else
- {
- TRACE("clientBytesInJack == 0\n");
- }
- }
-
- /* add on the offset */
- return_val += drv->position_byte_offset;
-
- /* convert byte position to milliseconds value if necessary */
- if(position == MILLISECONDS)
- {
- if(JACK_GetOutputBytesPerSecondFromDriver(drv) != 0)
- {
- return_val = (long) (((double) return_val /
- (double) JACK_GetOutputBytesPerSecondFromDriver(drv)) *
- (double) sec2msFactor);
- } else
- {
- return_val = 0;
- }
- }
-
- TRACE("drv->deviceID(%d), type(%s), return_val = %ld\n", drv->deviceID,
- type_str, return_val);
-
- return return_val;
-}
-
-/* Get the current position of the driver, either in bytes or */
-/* in milliseconds */
-/* NOTE: this is position relative to input bytes, output bytes may differ greatly due to input vs. output channel count */
-long
-JACK_GetPosition(int deviceID, enum pos_enum position, int type)
-{
- jack_driver_t *drv = getDriver(deviceID);
- long retval = JACK_GetPositionFromDriver(drv, position, type);
- releaseDriver(drv);
- TRACE("retval == %ld\n", retval);
- return retval;
-}
-
-// Set position always applies to written bytes
-// NOTE: we must apply this instantly because if we pass this as a message
-// to the callback we risk the user sending us audio data in the mean time
-// and there is no need to send this as a message, we don't modify any
-// internal variables
-void
-JACK_SetPositionFromDriver(jack_driver_t * drv, enum pos_enum position,
- long value)
-{
- double sec2msFactor = 1000;
-#if TRACE_ENABLE
- long input_value = value;
-#endif
-
- /* convert the incoming value from milliseconds into bytes */
- if(position == MILLISECONDS)
- {
- value = (long) (((double) value *
- (double) JACK_GetOutputBytesPerSecondFromDriver(drv)) /
- sec2msFactor);
- }
-
- /* ensure that if the user asks for the position */
- /* they will at this instant get the correct position */
- drv->position_byte_offset = value - drv->client_bytes;
-
- TRACE("deviceID(%d) input_value of %ld %s, new value of %ld, setting position_byte_offset to %ld\n",
- drv->deviceID, input_value, (position == MILLISECONDS) ? "ms" : "bytes",
- value, drv->position_byte_offset);
-}
-
-// Set position always applies to written bytes
-// NOTE: we must apply this instantly because if we pass this as a message
-// to the callback we risk the user sending us audio data in the mean time
-// and there is no need to send this as a message, we don't modify any
-// internal variables
-void
-JACK_SetPosition(int deviceID, enum pos_enum position, long value)
-{
- jack_driver_t *drv = getDriver(deviceID);
- JACK_SetPositionFromDriver(drv, position, value);
- releaseDriver(drv);
-
- TRACE("deviceID(%d) value of %ld\n", drv->deviceID, value);
-}
-
-/* Return the number of bytes per frame, or (output_channels * bits_per_channel) / 8 */
-unsigned long
-JACK_GetBytesPerOutputFrame(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- long return_val = drv->bytes_per_output_frame;
- releaseDriver(drv);
- TRACE("deviceID(%d), return_val = %ld\n", deviceID, return_val);
- return return_val;
-}
-
-/* Return the number of bytes per frame, or (input_channels * bits_per_channel) / 8 */
-unsigned long
-JACK_GetBytesPerInputFrame(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- long return_val = drv->bytes_per_input_frame;
- releaseDriver(drv);
- TRACE("deviceID(%d), return_val = %ld\n", deviceID, return_val);
- return return_val;
-}
-
-/* Return the number of output bytes we buffer max */
-long
-JACK_GetMaxOutputBufferedBytes(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- long return_val;
-
- /* adjust from jack bytes to client bytes */
- if(drv->pPlayPtr == 0 || drv->bytes_per_jack_output_frame == 0)
- return_val = 0;
- else
- return_val =
- (jack_ringbuffer_read_space(drv->pPlayPtr) +
- jack_ringbuffer_write_space(drv->pPlayPtr)) /
- drv->bytes_per_jack_output_frame * drv->bytes_per_output_frame;
-
- releaseDriver(drv);
-
- TRACE("return_val = %ld\n", return_val);
-
- return return_val;
-}
-
-/* Return the number of input bytes we buffer max */
-long
-JACK_GetMaxInputBufferedBytes(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- long return_val;
-
- /* adjust from jack bytes to client bytes */
- if(drv->pRecPtr == 0 || drv->bytes_per_jack_input_frame == 0)
- return_val = 0;
- else
- return_val =
- (jack_ringbuffer_read_space(drv->pRecPtr) +
- jack_ringbuffer_write_space(drv->pRecPtr)) /
- drv->bytes_per_jack_input_frame * drv->bytes_per_input_frame;
-
- releaseDriver(drv);
-
- TRACE("return_val = %ld\n", return_val);
-
- return return_val;
-}
-
-/* Get the number of output channels */
-int
-JACK_GetNumOutputChannels(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- int return_val = drv->num_output_channels;
- releaseDriver(drv);
- TRACE("getting num_output_channels of %d\n", return_val);
- return return_val;
-}
-
-/* Get the number of input channels */
-int
-JACK_GetNumInputChannels(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- int return_val = drv->num_input_channels;
- releaseDriver(drv);
- TRACE("getting num_input_channels of %d\n", return_val);
- return return_val;
-}
-
-/* Get the number of samples per second, the sample rate */
-long
-JACK_GetSampleRate(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- int return_val = drv->client_sample_rate;
- releaseDriver(drv);
- TRACE("getting sample_rate of %d\n", return_val);
- return return_val;
-}
-
-void
-JACK_CleanupDriver(jack_driver_t * drv)
-{
- TRACE("\n");
- /* things that need to be reset both in JACK_Init & JACK_CloseDevice */
- drv->client = 0;
- drv->in_use = FALSE;
- drv->state = CLOSED;
- drv->jack_sample_rate = 0;
- drv->output_sample_rate_ratio = 1.0;
- drv->input_sample_rate_ratio = 1.0;
- drv->jackd_died = FALSE;
- gettimeofday(&drv->previousTime, 0); /* record the current time */
- gettimeofday(&drv->last_reconnect_attempt, 0);
-}
-
-/* Initialize the jack porting library to a clean state */
-void
-JACK_Init(void)
-{
- jack_driver_t *drv;
- int x, y;
-
- if(init_done)
- {
- TRACE("not initing twice\n");
- return;
- }
-
- init_done = 1;
-
- TRACE("\n");
-
- pthread_mutex_lock(&device_mutex);
-
- /* initialize the device structures */
- for(x = 0; x < MAX_OUTDEVICES; x++)
- {
- drv = &outDev[x];
-
- pthread_mutex_init(&drv->mutex, NULL);
-
- getDriver(x);
-
- memset(drv, 0, sizeof(jack_driver_t));
- drv->volumeEffectType = linear;
- drv->deviceID = x;
-
- for(y = 0; y < MAX_OUTPUT_PORTS; y++) /* make all volume 25% as a default */
- drv->volume[y] = 25;
-
- JACK_CleanupDriver(drv);
- JACK_ResetFromDriver(drv);
- releaseDriver(drv);
- }
-
- client_name = 0; /* initialize the name to null */
- do_sample_rate_conversion = TRUE; /* default to on */
- JACK_SetClientName("bio2jack");
-
- pthread_mutex_unlock(&device_mutex);
-
- TRACE("finished\n");
-}
-
-/* Get the latency, in frames, of jack */
-long
-JACK_GetJackOutputLatency(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- long return_val = 0;
-
- if(drv->client && drv->num_output_channels)
- {
- /* Disclaimer: I have no experience with JACK and don't know if this is
- * correct. -jlindgren */
- jack_latency_range_t range;
- jack_port_get_latency_range(drv->output_port[0], JackPlaybackLatency, & range);
- return_val = (range.min + range.max) / 2;
- }
-
- TRACE("got latency of %ld frames\n", return_val);
-
- releaseDriver(drv);
- return return_val;
-}
-
-/* bytes that jack requests during each callback */
-unsigned long
-JACK_GetJackBufferedBytes(int deviceID)
-{
- jack_driver_t *drv = getDriver(deviceID);
- long return_val;
-
- if(drv->bytes_per_jack_output_frame == 0)
- {
- return_val = 0;
- } else
- {
- /* adjust from jack bytes to client bytes */
- return_val =
- drv->jack_buffer_size / drv->bytes_per_jack_output_frame *
- drv->bytes_per_output_frame * drv->num_output_channels;
- }
-
- releaseDriver(drv);
- return return_val;
-}
-
-/* value = TRUE, perform sample rate conversion */
-void
-JACK_DoSampleRateConversion(bool value)
-{
- do_sample_rate_conversion = value;
-}
-
-/* FIXME: put the filename of the resample library header file with the decoders in here */
-/* consider mapping them in the bio2jack.h header file since its useless to the user unless */
-/* they can figure out wtf the settings on */
-void
-JACK_SetSampleRateConversionFunction(int converter)
-{
- preferred_src_converter = converter;
-}
-
-/* set the client name that will be reported to jack when we open a */
-/* connection via JACK_OpenDevice() */
-void
-JACK_SetClientName(char *name)
-{
- if(name)
- {
- if(client_name) g_free(client_name);
-
- client_name = g_strdup(name);
- }
-}
-
-void
-JACK_SetPortConnectionMode(enum JACK_PORT_CONNECTION_MODE mode)
-{
- port_connection_mode = mode;
-}
diff --git a/src/jack/bio2jack.h b/src/jack/bio2jack.h
deleted file mode 100644
index cbb3b16f3fc4..000000000000
--- a/src/jack/bio2jack.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2003-2004 Chris Morgan <cmorgan at alum.wpi.edu>
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _H_JACK_OUT_H
-#define _H_JACK_OUT_H
-
-#include <jack/jack.h>
-
-#ifdef __cplusplus
-extern "C" {
-#else
-#define bool long
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#define ERR_SUCCESS 0
-#define ERR_OPENING_JACK 1
-#define ERR_RATE_MISMATCH 2
-#define ERR_BYTES_PER_OUTPUT_FRAME_INVALID 3
-#define ERR_BYTES_PER_INPUT_FRAME_INVALID 4
-#define ERR_TOO_MANY_OUTPUT_CHANNELS 5
-#define ERR_PORT_NAME_OUTPUT_CHANNEL_MISMATCH 6
-#define ERR_PORT_NOT_FOUND 7
-#define ERR_TOO_MANY_INPUT_CHANNELS 8
-#define ERR_PORT_NAME_INPUT_CHANNEL_MISMATCH 9
-
-enum status_enum { PLAYING, PAUSED, STOPPED, CLOSED, RESET };
-enum pos_enum { BYTES, MILLISECONDS };
-
-#define PLAYED 1 /* played out of the speakers(estimated value but should be close */
-#define WRITTEN_TO_JACK 2 /* amount written out to jack */
-#define WRITTEN 3 /* amount written to the bio2jack device */
-
-/**********************/
-/* External functions */
-void JACK_Init(void); /* call this before any other bio2jack calls */
-void JACK_DoSampleRateConversion(bool value); /* whether the next device that's Open()d should do
- sample rate conversion if necessary */
-void JACK_SetSampleRateConversionFunction(int converter); /* which SRC converter function should be used
- for the next Open()d device */
-int JACK_Open(int *deviceID, unsigned int bits_per_channel, int floating_point,
- unsigned long *rate, int channels); /* Note: defaults to 0 input channels
- if you need input (record) use OpenEx
- instead */
-int JACK_OpenEx(int *deviceID, unsigned int bits_per_channel,
- int floating_point, unsigned long *rate,
- unsigned int input_channels, unsigned int output_channels,
- const char **jack_port_name, unsigned int jack_port_name_count,
- unsigned long jack_port_flags);
-int JACK_Close(int deviceID); /* return 0 for success */
-void JACK_Reset(int deviceID); /* free all buffered data and reset several values in the device */
-long JACK_Write(int deviceID, unsigned char *data, unsigned long bytes); /* returns the number of bytes written */
-long JACK_Read(int deviceID, unsigned char *data, unsigned long bytes); /* returns the number of bytes read */
-
-/* state setting values */
-/* set/get the written/played/buffered value based on a byte or millisecond input value */
-long JACK_GetPosition(int deviceID, enum pos_enum position, int type);
-void JACK_SetPosition(int deviceID, enum pos_enum position, long value);
-
-long JACK_GetJackLatency(int deviceID); /* deprectated, you probably want JACK_GetJackOutputLatency */
-long JACK_GetJackOutputLatency(int deviceID); /* return the output latency in frames */
-
-int JACK_SetState(int deviceID, enum status_enum state); /* playing, paused, stopped */
-enum status_enum JACK_GetState(int deviceID);
-
-long JACK_GetMaxOutputBufferedBytes(int deviceID);
-long JACK_GetMaxInputBufferedBytes(int deviceID);
-
-/* bytes that jack requests during each callback */
-unsigned long JACK_GetJackBufferedBytes(int deviceID);
-
-/* Properties of the jack driver */
-
-/* linear means 0 volume is silence, 100 is full volume */
-/* dbAttenuation means 0 volume is 0dB attenuation */
-/* Bio2jack defaults to linear */
-/* Note: volume controls only effect output channels for now */
-enum JACK_VOLUME_TYPE { linear, dbAttenuation };
-enum JACK_VOLUME_TYPE JACK_SetVolumeEffectType(int deviceID,
- enum JACK_VOLUME_TYPE type);
-
-int JACK_SetAllVolume(int deviceID, unsigned int volume); /* returns 0 on success */
-int JACK_SetVolumeForChannel(int deviceID, unsigned int channel, unsigned int volume);
-void JACK_GetVolumeForChannel(int deviceID, unsigned int channel, unsigned int *volume);
-
-
-unsigned long JACK_GetOutputBytesPerSecond(int deviceID); /* bytes_per_output_frame * sample_rate */
-unsigned long JACK_GetInputBytesPerSecond(int deviceID); /* bytes_per_input_frame * sample_rate */
-unsigned long JACK_GetBytesStored(int deviceID); /* bytes currently buffered in the output buffer */
-unsigned long JACK_GetBytesFreeSpace(int deviceID); /* bytes of free space in the output buffer */
-unsigned long JACK_GetBytesUsedSpace(int deviceID); /* bytes of space used in the input buffer */
-unsigned long JACK_GetBytesPerOutputFrame(int deviceID);
-unsigned long JACK_GetBytesPerInputFrame(int deviceID);
-
-/* Note: these will probably be removed in a future release */
-int JACK_GetNumInputChannels(int deviceID);
-int JACK_GetNumOutputChannels(int deviceID);
-
-long JACK_GetSampleRate(int deviceID); /* samples per second */
-
-void JACK_SetClientName(char *name); /* sets the name that bio2jack will use when
- creating a new jack client. name_%pid%_%deviceID%%counter%
- will be used
- NOTE: this defaults to name = bio2jack
- NOTE: we limit the size of the client name to
- jack_client_name_size() */
-
-enum JACK_PORT_CONNECTION_MODE
-{
- CONNECT_ALL, /* connect to all avaliable ports */
- CONNECT_OUTPUT, /* connect only to the ports we need for output */
- CONNECT_NONE /* don't connect to any ports */
-};
-
-/* set the mode for port connections */
-/* defaults to CONNECT_ALL */
-void JACK_SetPortConnectionMode(enum JACK_PORT_CONNECTION_MODE mode);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* #ifndef JACK_OUT_H */
diff --git a/src/jack/jack.c b/src/jack/jack.c
deleted file mode 100644
index b5c1b987b05b..000000000000
--- a/src/jack/jack.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/* xmms - jack output plugin
- * Copyright 2002 Chris Morgan<cmorgan at alum.wpi.edu>
- *
- * audacious port (2005-2006) by Giacomo Lozito from develia.org
- *
- * This code maps xmms calls into the jack translation library
- */
-
-#include <dlfcn.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-#include "bio2jack.h" /* includes for the bio2jack library */
-#include "jack.h"
-
-/* set to 1 for verbose output */
-#define VERBOSE_OUTPUT 0
-
-jackconfig jack_cfg;
-
-#define OUTFILE stderr
-
-#define TRACE(...) \
- if(jack_cfg.isTraceEnabled) { \
- fprintf(OUTFILE, "%s:", __FUNCTION__), \
- fprintf(OUTFILE, __VA_ARGS__), \
- fflush(OUTFILE); \
- }
-
-#define ERR(...) \
- if(jack_cfg.isTraceEnabled) { \
- fprintf(OUTFILE, "ERR: %s:", __FUNCTION__), \
- fprintf(OUTFILE, __VA_ARGS__), \
- fflush(OUTFILE); \
- }
-
-
-static int driver = 0; /* handle to the jack output device */
-
-typedef struct format_info {
- int format;
- long frequency;
- int channels;
- long bps;
-} format_info_t;
-
-static format_info_t input;
-static format_info_t effect;
-static format_info_t output;
-
-static bool_t output_opened; /* true if we have a connection to jack */
-static bool_t paused;
-
-
-/* Giacomo's note: removed the destructor from the original xmms-jack, cause
- destructors + thread join + NPTL currently leads to problems; solved this
- by adding a cleanup function callback for output plugins in Audacious, this
- is used to close the JACK connection and to perform a correct shutdown */
-static void jack_cleanup(void)
-{
- int errval;
- TRACE("cleanup\n");
-
- if((errval = JACK_Close(driver)))
- ERR("error closing device, errval of %d\n", errval);
-
- return;
-}
-
-
-/* Set the volume */
-static void jack_set_volume(int l, int r)
-{
- if(output.channels == 1)
- {
- TRACE("l(%d)\n", l);
- } else if(output.channels > 1)
- {
- TRACE("l(%d), r(%d)\n", l, r);
- }
-
- if(output.channels > 0) {
- JACK_SetVolumeForChannel(driver, 0, l);
- jack_cfg.volume_left = l;
- }
- if(output.channels > 1) {
- JACK_SetVolumeForChannel(driver, 1, r);
- jack_cfg.volume_right = r;
- }
-}
-
-
-/* Get the current volume setting */
-static void jack_get_volume(int *l, int *r)
-{
- unsigned int _l, _r;
-
- if(output.channels > 0)
- {
- JACK_GetVolumeForChannel(driver, 0, &_l);
- (*l) = _l;
- }
- if(output.channels > 1)
- {
- JACK_GetVolumeForChannel(driver, 1, &_r);
- (*r) = _r;
- }
-
-#if VERBOSE_OUTPUT
- if(output.channels == 1)
- TRACE("l(%d)\n", *l);
- else if(output.channels > 1)
- TRACE("l(%d), r(%d)\n", *l, *r);
-#endif
-}
-
-
-/* Return the current number of milliseconds of audio data that has */
-/* been played out of the audio device, not including the buffer */
-static int jack_get_output_time(void)
-{
- int return_val;
-
- /* don't try to get any values if the device is still closed */
- if(JACK_GetState(driver) == CLOSED)
- return_val = 0;
- else
- return_val = JACK_GetPosition(driver, MILLISECONDS, PLAYED); /* get played position in terms of milliseconds */
-
- TRACE("returning %d milliseconds\n", return_val);
- return return_val;
-}
-
-
-/* returns TRUE if we are currently playing */
-/* NOTE: this was confusing at first BUT, if the device is open and there */
-/* is no more audio to be played, then the device is NOT PLAYING */
-#if 0
-static int jack_playing(void)
-{
- int return_val;
-
- /* If we are playing see if we ACTUALLY have something to play */
- if(JACK_GetState(driver) == PLAYING)
- {
- /* If we have zero bytes stored, we are done playing */
- if(JACK_GetBytesStored(driver) == 0)
- return_val = FALSE;
- else
- return_val = TRUE;
- }
- else
- return_val = FALSE;
-
- TRACE("returning %d\n", return_val);
- return return_val;
-}
-#endif
-
-void jack_set_port_connection_mode()
-{
- /* setup the port connection mode that determines how bio2jack will connect ports */
- char * mode_str = aud_get_str ("jack", "port_connection_mode");
- enum JACK_PORT_CONNECTION_MODE mode;
-
- if(strcmp(mode_str, "CONNECT_ALL") == 0)
- mode = CONNECT_ALL;
- else if(strcmp(mode_str, "CONNECT_OUTPUT") == 0)
- mode = CONNECT_OUTPUT;
- else if(strcmp(mode_str, "CONNECT_NONE") == 0)
- mode = CONNECT_NONE;
- else
- {
- TRACE("Defaulting to CONNECT_ALL");
- mode = CONNECT_ALL;
- }
-
- JACK_SetPortConnectionMode(mode);
- str_unref (mode_str);
-}
-
-static const char * const jack_defaults[] = {
- "isTraceEnabled", "FALSE",
- "port_connection_mode", "CONNECT_ALL",
- "volume_left", "25",
- "volume_right", "25",
- NULL};
-
-static const ComboBoxElements mode_list[] = {
- {"CONNECT_ALL", N_("Connect to all available jack ports")},
- {"CONNECT_OUTPUT", N_("Connect only the output ports")},
- {"CONNECT_NONE", N_("Don't connect to any port")},
-};
-
-static const PreferencesWidget jack_widgets[] = {
- {WIDGET_COMBO_BOX, N_("Connection mode:"),
- .cfg_type = VALUE_STRING, .csect = "jack", .cname = "port_connection_mode",
- .data.combo = {mode_list, ARRAY_LEN (mode_list)}},
- {WIDGET_CHK_BTN, N_("Enable debug printing"),
- .cfg_type = VALUE_BOOLEAN, .csect = "jack", .cname = "isTraceEnabled"},
-};
-
-static const PluginPreferences jack_prefs = {
- .widgets = jack_widgets,
- .n_widgets = ARRAY_LEN (jack_widgets)
-};
-
-/* Initialize necessary things */
-static bool_t jack_init (void)
-{
- aud_config_set_defaults ("jack", jack_defaults);
-
- jack_cfg.isTraceEnabled = aud_get_bool ("jack", "isTraceEnabled");
- jack_cfg.volume_left = aud_get_int ("jack", "volume_left");
- jack_cfg.volume_right = aud_get_int ("jack", "volume_right");
-
- TRACE("initializing\n");
- JACK_Init(); /* initialize the driver */
-
- /* set the bio2jack name so users will see xmms-jack in their */
- /* jack client list */
- JACK_SetClientName("audacious-jack");
-
- /* set the port connection mode */
- jack_set_port_connection_mode();
-
- output_opened = FALSE;
-
- /* Always return OK, as we don't know about physical devices here */
- return TRUE;
-}
-
-
-/* Return the amount of data that can be written to the device */
-static int audacious_jack_free(void)
-{
- unsigned long return_val = JACK_GetBytesFreeSpace(driver);
- unsigned long tmp;
-
- /* adjust for frequency differences, otherwise xmms could send us */
- /* as much data as we have free, then we go to convert this to */
- /* the output frequency and won't have enough space, so adjust */
- /* by the ratio of the two */
- if(effect.frequency != output.frequency)
- {
- tmp = return_val;
- return_val = (return_val * effect.frequency) / output.frequency;
- TRACE("adjusting from %lu to %lu free bytes to compensate for frequency differences\n", tmp, return_val);
- }
-
- if(return_val > INT_MAX)
- {
- TRACE("Warning: return_val > INT_MAX\n");
- return_val = INT_MAX;
- }
-
- TRACE("free space of %lu bytes\n", return_val);
-
- return return_val;
-}
-
-
-/* Close the device */
-static void jack_close(void)
-{
- aud_set_int ("jack", "volume_left", jack_cfg.volume_left);
- aud_set_int ("jack", "volume_right", jack_cfg.volume_right);
-
- JACK_Reset(driver); /* flush buffers, reset position and set state to STOPPED */
- TRACE("resetting driver, not closing now, destructor will close for us\n");
-}
-
-
-/* Open the device up */
-static int jack_open(int fmt, int sample_rate, int num_channels)
-{
- int bits_per_sample;
- int floating_point = FALSE;
- int retval;
- unsigned long rate;
-
- TRACE("fmt == %d, sample_rate == %d, num_channels == %d\n",
- fmt, sample_rate, num_channels);
-
- if((fmt == FMT_U8) || (fmt == FMT_S8))
- {
- bits_per_sample = 8;
- } else if(fmt == FMT_S16_NE)
- {
- bits_per_sample = 16;
- } else if (fmt == FMT_S24_NE)
- {
- /* interpreted by bio2jack as 24 bit values packed to 32 bit samples */
- bits_per_sample = 24;
- } else if (fmt == FMT_S32_NE)
- {
- bits_per_sample = 32;
- } else if (fmt == FMT_FLOAT)
- {
- bits_per_sample = 32;
- floating_point = TRUE;
- } else {
- TRACE("sample format not supported\n");
- return 0;
- }
-
- /* record some useful information */
- input.format = fmt;
- input.frequency = sample_rate;
- input.bps = bits_per_sample * sample_rate * num_channels;
- input.channels = num_channels;
-
- /* setup the effect as matching the input format */
- effect.format = input.format;
- effect.frequency = input.frequency;
- effect.channels = input.channels;
- effect.bps = input.bps;
-
- /* if we are already opened then don't open again */
- if(output_opened)
- {
- /* if something has changed we should close and re-open the connect to jack */
- if((output.channels != input.channels) ||
- (output.frequency != input.frequency) ||
- (output.format != input.format))
- {
- TRACE("output.channels is %d, jack_open called with %d channels\n", output.channels, input.channels);
- TRACE("output.frequency is %ld, jack_open called with %ld\n", output.frequency, input.frequency);
- TRACE("output.format is %d, jack_open called with %d\n", output.format, input.format);
- jack_close();
- JACK_Close(driver);
- } else
- {
- TRACE("output_opened is TRUE and no options changed, not reopening\n");
- paused = FALSE;
- return 1;
- }
- }
-
- /* try to open the jack device with the requested rate at first */
- output.frequency = input.frequency;
- output.bps = input.bps;
- output.channels = input.channels;
- output.format = input.format;
-
- rate = output.frequency;
- retval = JACK_Open(&driver, bits_per_sample, floating_point, &rate, output.channels);
- output.frequency = rate; /* avoid compile warning as output.frequency differs in type
- from what JACK_Open() wants for the type of the rate parameter */
- if(retval == ERR_RATE_MISMATCH)
- {
- TRACE("set the resampling rate properly");
- return 0;
- } else if(retval != ERR_SUCCESS)
- {
- TRACE("failed to open jack with JACK_Open(), error %d\n", retval);
- return 0;
- }
-
- jack_set_volume(jack_cfg.volume_left, jack_cfg.volume_right); /* sets the volume to stored value */
- output_opened = TRUE;
- paused = FALSE;
-
- return 1;
-}
-
-
-/* write some audio out to the device */
-static void jack_write(void * ptr, int length)
-{
- long written;
-
- TRACE("starting length of %d\n", length);
-
- /* loop until we have written all the data out to the jack device */
- /* this is due to xmms' audio driver api */
- char *buf = (char*)ptr;
- while(length > 0)
- {
- TRACE("writing %d bytes\n", length);
- written = JACK_Write(driver, (unsigned char*)buf, length);
- length-=written;
- buf+=written;
- }
- TRACE("finished\n");
-}
-
-
-/* Flush any output currently buffered */
-/* and set the number of bytes written based on ms_offset_time, */
-/* the number of milliseconds of offset passed in */
-/* This is done so the driver itself keeps track of */
-/* current playing position of the mp3 */
-static void jack_flush(int ms_offset_time)
-{
- TRACE("setting values for ms_offset_time of %d\n", ms_offset_time);
-
- JACK_Reset(driver); /* flush buffers and set state to STOPPED */
-
- /* update the internal driver values to correspond to the input time given */
- JACK_SetPosition(driver, MILLISECONDS, ms_offset_time);
-
- if (paused)
- JACK_SetState(driver, PAUSED);
- else
- JACK_SetState(driver, PLAYING);
-}
-
-
-/* Pause the jack device */
-static void jack_pause (bool_t p)
-{
- TRACE("p == %d\n", p);
-
- paused = p;
-
- /* pause the device if p is non-zero, unpause the device if p is zero and */
- /* we are currently paused */
- if(p)
- JACK_SetState(driver, PAUSED);
- else if(JACK_GetState(driver) == PAUSED)
- JACK_SetState(driver, PLAYING);
-}
-
-static const char jack_about[] =
- N_("Based on xmms-jack, by Chris Morgan:\n"
- "http://xmms-jack.sourceforge.net/\n\n"
- "Ported to Audacious by Giacomo Lozito");
-
-AUD_OUTPUT_PLUGIN
-(
- .name = N_("JACK Output"),
- .domain = PACKAGE,
- .about_text = jack_about,
- .init = jack_init,
- .cleanup = jack_cleanup,
- .prefs = & jack_prefs,
- .get_volume = jack_get_volume,
- .set_volume = jack_set_volume,
- .open_audio = jack_open,
- .write_audio = jack_write,
- .close_audio = jack_close,
- .flush = jack_flush,
- .pause = jack_pause,
- .buffer_free = audacious_jack_free,
- .output_time = jack_get_output_time
-)
diff --git a/src/jack/jack.h b/src/jack/jack.h
deleted file mode 100644
index 17131ba0008a..000000000000
--- a/src/jack/jack.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _JACK_H
-#define _JACK_H
-
-#include <libaudcore/core.h>
-
-void jack_configure(void);
-
-typedef struct
-{
- bool_t isTraceEnabled; /* if true we will print debug information to the console */
- int volume_left, volume_right; /* for loading the stored volume setting */
-} jackconfig;
-
-void jack_set_port_connection_mode(); /* called by jack_init() and the 'ok' handler in configure.c */
-
-#endif /* #ifndef _JACK_H */
diff --git a/src/ladspa/Makefile b/src/ladspa/Makefile
index 797bfe664ea5..1bbf746e7730 100644
--- a/src/ladspa/Makefile
+++ b/src/ladspa/Makefile
@@ -1,15 +1,17 @@
PLUGIN = ladspa${PLUGIN_SUFFIX}
-SRCS = effect.c \
- loaded-list.c \
- plugin.c \
- plugin-list.c
+SRCS = effect.cc \
+ loaded-list.cc \
+ plugin.cc \
+ plugin-list.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
+LD = ${CXX}
+
CPPFLAGS += -I../.. ${GTK_CFLAGS} ${GMODULE_CFLAGS}
CFLAGS += ${PLUGIN_CFLAGS}
-LIBS += -lm ${GTK_LIBS} ${GMODULE_LIBS}
+LIBS += -lm ${GTK_LIBS} ${GMODULE_LIBS} -laudgui
diff --git a/src/ladspa/effect.c b/src/ladspa/effect.c
deleted file mode 100644
index 5d60c95d63e4..000000000000
--- a/src/ladspa/effect.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * LADSPA Host for Audacious
- * Copyright 2011 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <assert.h>
-#include <stdio.h>
-
-#include "ladspa.h"
-#include "plugin.h"
-
-static int ladspa_channels, ladspa_rate;
-
-static void start_plugin (LoadedPlugin * loaded)
-{
- if (loaded->active)
- return;
-
- loaded->active = 1;
-
- PluginData * plugin = loaded->plugin;
- const LADSPA_Descriptor * desc = plugin->desc;
-
- int ports = plugin->in_ports->len;
-
- if (ports == 0 || ports != plugin->out_ports->len)
- {
- fprintf (stderr, "Plugin has unusable port configuration: %s\n", desc->Name);
- return;
- }
-
- if (ladspa_channels % ports != 0)
- {
- fprintf (stderr, "Plugin cannot be used with %d channels: %s\n",
- ladspa_channels, desc->Name);
- return;
- }
-
- int instances = ladspa_channels / ports;
-
- loaded->instances = index_new ();
- loaded->in_bufs = g_malloc (sizeof (float *) * ladspa_channels);
- loaded->out_bufs = g_malloc (sizeof (float *) * ladspa_channels);
-
- for (int i = 0; i < instances; i ++)
- {
- LADSPA_Handle handle = desc->instantiate (desc, ladspa_rate);
- index_insert (loaded->instances, -1, handle);
-
- int controls = index_count (plugin->controls);
- for (int c = 0; c < controls; c ++)
- {
- ControlData * control = index_get (plugin->controls, c);
- desc->connect_port (handle, control->port, & loaded->values[c]);
- }
-
- for (int p = 0; p < ports; p ++)
- {
- int channel = ports * i + p;
-
- float * in = g_malloc (sizeof (float) * LADSPA_BUFLEN);
- loaded->in_bufs[channel] = in;
- int in_port = g_array_index (plugin->in_ports, int, p);
- desc->connect_port (handle, in_port, in);
-
- float * out = g_malloc (sizeof (float) * LADSPA_BUFLEN);
- loaded->out_bufs[channel] = out;
- int out_port = g_array_index (plugin->out_ports, int, p);
- desc->connect_port (handle, out_port, out);
- }
-
- if (desc->activate)
- desc->activate (handle);
- }
-}
-
-static void run_plugin (LoadedPlugin * loaded, float * data, int samples)
-{
- if (! loaded->instances)
- return;
-
- PluginData * plugin = loaded->plugin;
- const LADSPA_Descriptor * desc = plugin->desc;
-
- int ports = plugin->in_ports->len;
- int instances = index_count (loaded->instances);
- assert (ports * instances == ladspa_channels);
-
- while (samples / ladspa_channels > 0)
- {
- int frames = MIN (samples / ladspa_channels, LADSPA_BUFLEN);
-
- for (int i = 0; i < instances; i ++)
- {
- LADSPA_Handle * handle = index_get (loaded->instances, i);
-
- for (int p = 0; p < ports; p ++)
- {
- int channel = ports * i + p;
- float * get = data + channel;
- float * in = loaded->in_bufs[channel];
- float * in_end = in + frames;
-
- while (in < in_end)
- {
- * in ++ = * get;
- get += ladspa_channels;
- }
- }
-
- desc->run (handle, frames);
-
- for (int p = 0; p < ports; p ++)
- {
- int channel = ports * i + p;
- float * set = data + channel;
- float * out = loaded->out_bufs[channel];
- float * out_end = out + frames;
-
- while (out < out_end)
- {
- * set = * out ++;
- set += ladspa_channels;
- }
- }
- }
-
- data += ladspa_channels * frames;
- samples -= ladspa_channels * frames;
- }
-}
-
-static void flush_plugin (LoadedPlugin * loaded)
-{
- if (! loaded->instances)
- return;
-
- PluginData * plugin = loaded->plugin;
- const LADSPA_Descriptor * desc = plugin->desc;
-
- int instances = index_count (loaded->instances);
- for (int i = 0; i < instances; i ++)
- {
- LADSPA_Handle * handle = index_get (loaded->instances, i);
-
- if (desc->deactivate)
- desc->deactivate (handle);
- if (desc->activate)
- desc->activate (handle);
- }
-}
-
-void shutdown_plugin_locked (LoadedPlugin * loaded)
-{
- loaded->active = 0;
-
- if (! loaded->instances)
- return;
-
- PluginData * plugin = loaded->plugin;
- const LADSPA_Descriptor * desc = plugin->desc;
-
- int instances = index_count (loaded->instances);
- for (int i = 0; i < instances; i ++)
- {
- LADSPA_Handle * handle = index_get (loaded->instances, i);
-
- if (desc->deactivate)
- desc->deactivate (handle);
-
- desc->cleanup (handle);
- }
-
- for (int channel = 0; channel < ladspa_channels; channel ++)
- {
- g_free (loaded->in_bufs[channel]);
- g_free (loaded->out_bufs[channel]);
- }
-
- index_free (loaded->instances);
- loaded->instances = NULL;
- g_free (loaded->in_bufs);
- loaded->in_bufs = NULL;
- g_free (loaded->out_bufs);
- loaded->out_bufs = NULL;
-}
-
-void ladspa_start (int * channels, int * rate)
-{
- pthread_mutex_lock (& mutex);
-
- int count = index_count (loadeds);
- for (int i = 0; i < count; i ++)
- {
- LoadedPlugin * loaded = index_get (loadeds, i);
- shutdown_plugin_locked (loaded);
- }
-
- ladspa_channels = * channels;
- ladspa_rate = * rate;
-
- pthread_mutex_unlock (& mutex);
-}
-
-void ladspa_process (float * * data, int * samples)
-{
- pthread_mutex_lock (& mutex);
-
- int count = index_count (loadeds);
- for (int i = 0; i < count; i ++)
- {
- LoadedPlugin * loaded = index_get (loadeds, i);
- start_plugin (loaded);
- run_plugin (loaded, * data, * samples);
- }
-
- pthread_mutex_unlock (& mutex);
-}
-
-void ladspa_flush (void)
-{
- pthread_mutex_lock (& mutex);
-
- int count = index_count (loadeds);
- for (int i = 0; i < count; i ++)
- {
- LoadedPlugin * loaded = index_get (loadeds, i);
- flush_plugin (loaded);
- }
-
- pthread_mutex_unlock (& mutex);
-}
-
-void ladspa_finish (float * * data, int * samples)
-{
- pthread_mutex_lock (& mutex);
-
- int count = index_count (loadeds);
- for (int i = 0; i < count; i ++)
- {
- LoadedPlugin * loaded = index_get (loadeds, i);
- start_plugin (loaded);
- run_plugin (loaded, * data, * samples);
- shutdown_plugin_locked (loaded);
- }
-
- pthread_mutex_unlock (& mutex);
-}
diff --git a/src/ladspa/effect.cc b/src/ladspa/effect.cc
new file mode 100644
index 000000000000..ced1737018b1
--- /dev/null
+++ b/src/ladspa/effect.cc
@@ -0,0 +1,241 @@
+/*
+ * LADSPA Host for Audacious
+ * Copyright 2011 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <assert.h>
+
+#include "ladspa.h"
+#include "plugin.h"
+
+#include <libaudcore/runtime.h>
+
+static int ladspa_channels, ladspa_rate;
+
+static void start_plugin (LoadedPlugin & loaded)
+{
+ if (loaded.active)
+ return;
+
+ loaded.active = 1;
+
+ PluginData & plugin = loaded.plugin;
+ const LADSPA_Descriptor & desc = plugin.desc;
+
+ int ports = plugin.in_ports.len ();
+
+ if (ports == 0 || ports != plugin.out_ports.len ())
+ {
+ AUDERR ("Plugin has unusable port configuration: %s\n", desc.Name);
+ return;
+ }
+
+ if (ladspa_channels % ports != 0)
+ {
+ AUDERR ("Plugin cannot be used with %d channels: %s\n",
+ ladspa_channels, desc.Name);
+ return;
+ }
+
+ int instances = ladspa_channels / ports;
+
+ loaded.in_bufs.insert (0, ladspa_channels);
+ loaded.out_bufs.insert (0, ladspa_channels);
+
+ for (int i = 0; i < instances; i ++)
+ {
+ LADSPA_Handle handle = desc.instantiate (& desc, ladspa_rate);
+ loaded.instances.append (handle);
+
+ int controls = plugin.controls.len ();
+ for (int c = 0; c < controls; c ++)
+ desc.connect_port (handle, plugin.controls[c].port, & loaded.values[c]);
+
+ for (int p = 0; p < ports; p ++)
+ {
+ int channel = ports * i + p;
+
+ Index<float> & in = loaded.in_bufs[channel];
+ in.insert (0, LADSPA_BUFLEN);
+ desc.connect_port (handle, plugin.in_ports[p], in.begin ());
+
+ Index<float> & out = loaded.out_bufs[channel];
+ out.insert (0, LADSPA_BUFLEN);
+ desc.connect_port (handle, plugin.out_ports[p], out.begin ());
+ }
+
+ if (desc.activate)
+ desc.activate (handle);
+ }
+}
+
+static void run_plugin (LoadedPlugin & loaded, float * data, int samples)
+{
+ if (! loaded.instances.len ())
+ return;
+
+ PluginData & plugin = loaded.plugin;
+ const LADSPA_Descriptor & desc = plugin.desc;
+
+ int ports = plugin.in_ports.len ();
+ int instances = loaded.instances.len ();
+ assert (ports * instances == ladspa_channels);
+
+ while (samples / ladspa_channels > 0)
+ {
+ int frames = aud::min (samples / ladspa_channels, LADSPA_BUFLEN);
+
+ for (int i = 0; i < instances; i ++)
+ {
+ LADSPA_Handle handle = loaded.instances[i];
+
+ for (int p = 0; p < ports; p ++)
+ {
+ int channel = ports * i + p;
+ float * get = data + channel;
+ float * in = loaded.in_bufs[channel].begin ();
+ float * in_end = in + frames;
+
+ while (in < in_end)
+ {
+ * in ++ = * get;
+ get += ladspa_channels;
+ }
+ }
+
+ desc.run (handle, frames);
+
+ for (int p = 0; p < ports; p ++)
+ {
+ int channel = ports * i + p;
+ float * set = data + channel;
+ float * out = loaded.out_bufs[channel].begin ();
+ float * out_end = out + frames;
+
+ while (out < out_end)
+ {
+ * set = * out ++;
+ set += ladspa_channels;
+ }
+ }
+ }
+
+ data += ladspa_channels * frames;
+ samples -= ladspa_channels * frames;
+ }
+}
+
+static void flush_plugin (LoadedPlugin & loaded)
+{
+ if (! loaded.instances.len ())
+ return;
+
+ PluginData & plugin = loaded.plugin;
+ const LADSPA_Descriptor & desc = plugin.desc;
+
+ int instances = loaded.instances.len ();
+ for (int i = 0; i < instances; i ++)
+ {
+ LADSPA_Handle handle = loaded.instances[i];
+
+ if (desc.deactivate)
+ desc.deactivate (handle);
+ if (desc.activate)
+ desc.activate (handle);
+ }
+}
+
+void shutdown_plugin_locked (LoadedPlugin & loaded)
+{
+ loaded.active = 0;
+
+ if (! loaded.instances.len ())
+ return;
+
+ PluginData & plugin = loaded.plugin;
+ const LADSPA_Descriptor & desc = plugin.desc;
+
+ int instances = loaded.instances.len ();
+ for (int i = 0; i < instances; i ++)
+ {
+ LADSPA_Handle handle = loaded.instances[i];
+
+ if (desc.deactivate)
+ desc.deactivate (handle);
+
+ desc.cleanup (handle);
+ }
+
+ loaded.instances.clear ();
+ loaded.in_bufs.clear ();
+ loaded.out_bufs.clear ();
+}
+
+void LADSPAHost::start (int & channels, int & rate)
+{
+ pthread_mutex_lock (& mutex);
+
+ for (auto & loaded : loadeds)
+ shutdown_plugin_locked (* loaded);
+
+ ladspa_channels = channels;
+ ladspa_rate = rate;
+
+ pthread_mutex_unlock (& mutex);
+}
+
+Index<float> & LADSPAHost::process (Index<float> & data)
+{
+ pthread_mutex_lock (& mutex);
+
+ for (auto & loaded : loadeds)
+ {
+ start_plugin (* loaded);
+ run_plugin (* loaded, data.begin (), data.len ());
+ }
+
+ pthread_mutex_unlock (& mutex);
+ return data;
+}
+
+bool LADSPAHost::flush (bool force)
+{
+ pthread_mutex_lock (& mutex);
+
+ for (auto & loaded : loadeds)
+ flush_plugin (* loaded);
+
+ pthread_mutex_unlock (& mutex);
+ return true;
+}
+
+Index<float> & LADSPAHost::finish (Index<float> & data, bool end_of_playlist)
+{
+ pthread_mutex_lock (& mutex);
+
+ for (auto & loaded : loadeds)
+ {
+ start_plugin (* loaded);
+ run_plugin (* loaded, data.begin (), data.len ());
+
+ if (end_of_playlist)
+ shutdown_plugin_locked (* loaded);
+ }
+
+ pthread_mutex_unlock (& mutex);
+ return data;
+}
diff --git a/src/ladspa/ladspa.h b/src/ladspa/ladspa.h
index b1a9c4e59530..58e37ab7b7be 100644
--- a/src/ladspa/ladspa.h
+++ b/src/ladspa/ladspa.h
@@ -16,7 +16,7 @@
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
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA. */
#ifndef LADSPA_INCLUDED
@@ -356,7 +356,7 @@ typedef struct _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
+ concerned. It is valid to compare this to nullptr (0 for C++) but
otherwise the host should not attempt to interpret it. The plugin
may use it to reference internal instance data. */
@@ -393,7 +393,7 @@ typedef struct _LADSPA_Descriptor {
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. */
+ maker of the plugin. This can be an empty string but not nullptr. */
const char * Maker;
/* This member points to the null-terminated string indicating any
@@ -429,7 +429,7 @@ typedef struct _LADSPA_Descriptor {
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
+ must also be passed. This function must return nullptr if
instantiation fails.
Note that instance initialisation should generally occur in
@@ -475,7 +475,7 @@ typedef struct _LADSPA_Descriptor {
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
+ activate() to do then the plugin writer may provide a nullptr rather
than an empty function.
When present, hosts must call this function once before run() (or
@@ -516,7 +516,7 @@ typedef struct _LADSPA_Descriptor {
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,
+ this function pointer must be set to nullptr. When it is provided,
the function set_run_adding_gain() must be provided also. */
void (*run_adding)(LADSPA_Handle Instance,
unsigned long SampleCount);
@@ -529,13 +529,13 @@ typedef struct _LADSPA_Descriptor {
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. */
+ function pointer must be set to nullptr. */
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.
+ a nullptr 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
@@ -583,8 +583,8 @@ typedef struct _LADSPA_Descriptor {
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. */
+ returning nullptr, so the plugin count can be determined by checking
+ for the least index that results in nullptr being returned. */
const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index);
diff --git a/src/ladspa/loaded-list.c b/src/ladspa/loaded-list.c
deleted file mode 100644
index 89d65caa0fe5..000000000000
--- a/src/ladspa/loaded-list.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * LADSPA Host for Audacious
- * Copyright 2011 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <libaudgui/list.h>
-
-#include "plugin.h"
-
-static void get_value (void * user, int row, int column, GValue * value)
-{
- g_return_if_fail (row >= 0 && row < index_count (loadeds));
- g_return_if_fail (column == 0);
-
- LoadedPlugin * loaded = index_get (loadeds, row);
- g_value_set_string (value, loaded->plugin->desc->Name);
-}
-
-static int get_selected (void * user, int row)
-{
- g_return_val_if_fail (row >= 0 && row < index_count (loadeds), 0);
-
- LoadedPlugin * loaded = index_get (loadeds, row);
- return loaded->selected;
-}
-
-static void set_selected (void * user, int row, int selected)
-{
- g_return_if_fail (row >= 0 && row < index_count (loadeds));
-
- LoadedPlugin * loaded = index_get (loadeds, row);
- loaded->selected = selected;
-}
-
-static void select_all (void * user, int selected)
-{
- int count = index_count (loadeds);
- for (int i = 0; i < count; i ++)
- {
- LoadedPlugin * loaded = index_get (loadeds, i);
- loaded->selected = selected;
- }
-}
-
-static void shift_rows (void * user, int row, int before)
-{
- int rows = index_count (loadeds);
- g_return_if_fail (row >= 0 && row < rows);
- g_return_if_fail (before >= 0 && before <= rows);
-
- if (before == row)
- return;
-
- pthread_mutex_lock (& mutex);
-
- Index * move = index_new ();
- Index * others = index_new ();
-
- int begin, end;
- if (before < row)
- {
- begin = before;
- end = row + 1;
- while (end < rows && ((LoadedPlugin *) index_get (loadeds, end))->selected)
- end ++;
- }
- else
- {
- begin = row;
- while (begin > 0 && ((LoadedPlugin *) index_get (loadeds, begin - 1))->selected)
- begin --;
- end = before;
- }
-
- for (gint i = begin; i < end; i ++)
- {
- LoadedPlugin * loaded = index_get (loadeds, i);
- index_insert (loaded->selected ? move : others, -1, loaded);
- }
-
- if (before < row)
- {
- index_copy_insert (others, 0, move, -1, -1);
- index_free (others);
- }
- else
- {
- index_copy_insert (move, 0, others, -1, -1);
- index_free (move);
- move = others;
- }
-
- index_copy_set (move, 0, loadeds, begin, end - begin);
- index_free (move);
-
- pthread_mutex_unlock (& mutex);
-
- if (loaded_list)
- update_loaded_list (loaded_list);
-}
-
-static const AudguiListCallbacks callbacks = {
- .get_value = get_value,
- .get_selected = get_selected,
- .set_selected = set_selected,
- .select_all = select_all,
- .shift_rows = shift_rows};
-
-GtkWidget * create_loaded_list (void)
-{
- GtkWidget * list = audgui_list_new (& callbacks, NULL, index_count (loadeds));
- audgui_list_add_column (list, NULL, 0, G_TYPE_STRING, -1);
- gtk_tree_view_set_headers_visible ((GtkTreeView *) list, 0);
- return list;
-}
-
-void update_loaded_list (GtkWidget * list)
-{
- audgui_list_delete_rows (list, 0, audgui_list_row_count (list));
- audgui_list_insert_rows (list, 0, index_count (loadeds));
-}
diff --git a/src/ladspa/loaded-list.cc b/src/ladspa/loaded-list.cc
new file mode 100644
index 000000000000..2fae37ce1a9a
--- /dev/null
+++ b/src/ladspa/loaded-list.cc
@@ -0,0 +1,125 @@
+/*
+ * LADSPA Host for Audacious
+ * Copyright 2011 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <libaudgui/list.h>
+
+#include "plugin.h"
+
+static void get_value (void * user, int row, int column, GValue * value)
+{
+ g_return_if_fail (row >= 0 && row < loadeds.len ());
+ g_return_if_fail (column == 0);
+
+ g_value_set_string (value, loadeds[row]->plugin.desc.Name);
+}
+
+static bool get_selected (void * user, int row)
+{
+ g_return_val_if_fail (row >= 0 && row < loadeds.len (), 0);
+
+ return loadeds[row]->selected;
+}
+
+static void set_selected (void * user, int row, bool selected)
+{
+ g_return_if_fail (row >= 0 && row < loadeds.len ());
+
+ loadeds[row]->selected = selected;
+}
+
+static void select_all (void * user, bool selected)
+{
+ for (auto & loaded : loadeds)
+ loaded->selected = selected;
+}
+
+static void shift_rows (void * user, int row, int before)
+{
+ int rows = loadeds.len ();
+ g_return_if_fail (row >= 0 && row < rows);
+ g_return_if_fail (before >= 0 && before <= rows);
+
+ if (before == row)
+ return;
+
+ pthread_mutex_lock (& mutex);
+
+ Index<SmartPtr<LoadedPlugin>> move;
+ Index<SmartPtr<LoadedPlugin>> others;
+
+ int begin, end;
+ if (before < row)
+ {
+ begin = before;
+ end = row + 1;
+ while (end < rows && loadeds[end]->selected)
+ end ++;
+ }
+ else
+ {
+ begin = row;
+ while (begin > 0 && loadeds[begin - 1]->selected)
+ begin --;
+ end = before;
+ }
+
+ for (int i = begin; i < end; i ++)
+ {
+ if (loadeds[i]->selected)
+ move.append (std::move (loadeds[i]));
+ else
+ others.append (std::move (loadeds[i]));
+ }
+
+ if (before < row)
+ move.move_from (others, 0, -1, -1, true, true);
+ else
+ move.move_from (others, 0, 0, -1, true, true);
+
+ loadeds.move_from (move, 0, begin, end - begin, false, true);
+
+ pthread_mutex_unlock (& mutex);
+
+ if (loaded_list)
+ update_loaded_list (loaded_list);
+}
+
+static const AudguiListCallbacks callbacks = {
+ get_value,
+ get_selected,
+ set_selected,
+ select_all,
+ nullptr, // activate_row
+ nullptr, // right_click
+ shift_rows
+};
+
+GtkWidget * create_loaded_list ()
+{
+ GtkWidget * list = audgui_list_new (& callbacks, nullptr, loadeds.len ());
+ audgui_list_add_column (list, nullptr, 0, G_TYPE_STRING, -1);
+ gtk_tree_view_set_headers_visible ((GtkTreeView *) list, 0);
+ return list;
+}
+
+void update_loaded_list (GtkWidget * list)
+{
+ audgui_list_delete_rows (list, 0, audgui_list_row_count (list));
+ audgui_list_insert_rows (list, 0, loadeds.len ());
+}
diff --git a/src/ladspa/plugin-list.c b/src/ladspa/plugin-list.c
deleted file mode 100644
index 411bef958773..000000000000
--- a/src/ladspa/plugin-list.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * LADSPA Host for Audacious
- * Copyright 2011 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <libaudgui/list.h>
-
-#include "plugin.h"
-
-static void get_value (void * user, int row, int column, GValue * value)
-{
- g_return_if_fail (row >= 0 && row < index_count (plugins));
- g_return_if_fail (column == 0);
-
- PluginData * plugin = index_get (plugins, row);
- g_value_set_string (value, plugin->desc->Name);
-}
-
-static int get_selected (void * user, int row)
-{
- g_return_val_if_fail (row >= 0 && row < index_count (plugins), 0);
-
- PluginData * plugin = index_get (plugins, row);
- return plugin->selected;
-}
-
-static void set_selected (void * user, int row, int selected)
-{
- g_return_if_fail (row >= 0 && row < index_count (plugins));
-
- PluginData * plugin = index_get (plugins, row);
- plugin->selected = selected;
-}
-
-static void select_all (void * user, int selected)
-{
- int count = index_count (plugins);
- for (int i = 0; i < count; i ++)
- {
- PluginData * plugin = index_get (plugins, i);
- plugin->selected = selected;
- }
-}
-
-static const AudguiListCallbacks callbacks = {
- .get_value = get_value,
- .get_selected = get_selected,
- .set_selected = set_selected,
- .select_all = select_all};
-
-GtkWidget * create_plugin_list (void)
-{
- GtkWidget * list = audgui_list_new (& callbacks, NULL, index_count (plugins));
- audgui_list_add_column (list, NULL, 0, G_TYPE_STRING, -1);
- gtk_tree_view_set_headers_visible ((GtkTreeView *) list, 0);
- return list;
-}
-
-void update_plugin_list (GtkWidget * list)
-{
- audgui_list_delete_rows (list, 0, audgui_list_row_count (list));
- audgui_list_insert_rows (list, 0, index_count (plugins));
-}
diff --git a/src/ladspa/plugin-list.cc b/src/ladspa/plugin-list.cc
new file mode 100644
index 000000000000..eb4a0797c9b5
--- /dev/null
+++ b/src/ladspa/plugin-list.cc
@@ -0,0 +1,71 @@
+/*
+ * LADSPA Host for Audacious
+ * Copyright 2011 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <libaudgui/list.h>
+
+#include "plugin.h"
+
+static void get_value (void * user, int row, int column, GValue * value)
+{
+ g_return_if_fail (row >= 0 && row < plugins.len ());
+ g_return_if_fail (column == 0);
+
+ g_value_set_string (value, plugins[row]->desc.Name);
+}
+
+static bool get_selected (void * user, int row)
+{
+ g_return_val_if_fail (row >= 0 && row < plugins.len (), 0);
+
+ return plugins[row]->selected;
+}
+
+static void set_selected (void * user, int row, bool selected)
+{
+ g_return_if_fail (row >= 0 && row < plugins.len ());
+
+ plugins[row]->selected = selected;
+}
+
+static void select_all (void * user, bool selected)
+{
+ for (auto & plugin : plugins)
+ plugin->selected = selected;
+}
+
+static const AudguiListCallbacks callbacks = {
+ get_value,
+ get_selected,
+ set_selected,
+ select_all
+};
+
+GtkWidget * create_plugin_list ()
+{
+ GtkWidget * list = audgui_list_new (& callbacks, nullptr, plugins.len ());
+ audgui_list_add_column (list, nullptr, 0, G_TYPE_STRING, -1);
+ gtk_tree_view_set_headers_visible ((GtkTreeView *) list, 0);
+ return list;
+}
+
+void update_plugin_list (GtkWidget * list)
+{
+ audgui_list_delete_rows (list, 0, audgui_list_row_count (list));
+ audgui_list_insert_rows (list, 0, plugins.len ());
+}
diff --git a/src/ladspa/plugin.c b/src/ladspa/plugin.c
deleted file mode 100644
index 4776db19306a..000000000000
--- a/src/ladspa/plugin.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- * LADSPA Host for Audacious
- * Copyright 2011 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <errno.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <gmodule.h>
-#include <gtk/gtk.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "plugin.h"
-
-static const gchar * const ladspa_defaults[] = {
- "plugin_count", "0",
- NULL};
-
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-char * module_path;
-Index * modules; /* (void *) */
-Index * plugins; /* (PluginData *) */
-Index * loadeds; /* (LoadedPlugin *) */
-
-GtkWidget * config_win;
-GtkWidget * plugin_list;
-GtkWidget * loaded_list;
-
-static ControlData * parse_control (const LADSPA_Descriptor * desc, int port)
-{
- g_return_val_if_fail (desc->PortNames[port], NULL);
- const LADSPA_PortRangeHint * hint = & desc->PortRangeHints[port];
-
- ControlData * control = g_slice_new (ControlData);
- control->port = port;
- control->name = g_strdup (desc->PortNames[port]);
- control->is_toggle = LADSPA_IS_HINT_TOGGLED (hint->HintDescriptor) ? 1 : 0;
-
- control->min = LADSPA_IS_HINT_BOUNDED_BELOW (hint->HintDescriptor) ? hint->LowerBound :
- LADSPA_IS_HINT_BOUNDED_ABOVE (hint->HintDescriptor) ? hint->UpperBound - 100 : -100;
- control->max = LADSPA_IS_HINT_BOUNDED_ABOVE (hint->HintDescriptor) ? hint->UpperBound :
- LADSPA_IS_HINT_BOUNDED_BELOW (hint->HintDescriptor) ? hint->LowerBound + 100 : 100;
-
- if (LADSPA_IS_HINT_SAMPLE_RATE (hint->HintDescriptor))
- {
- control->min *= 96000;
- control->max *= 96000;
- }
-
- if (LADSPA_IS_HINT_DEFAULT_0 (hint->HintDescriptor))
- control->def = 0;
- else if (LADSPA_IS_HINT_DEFAULT_1 (hint->HintDescriptor))
- control->def = 1;
- else if (LADSPA_IS_HINT_DEFAULT_100 (hint->HintDescriptor))
- control->def = 100;
- else if (LADSPA_IS_HINT_DEFAULT_440 (hint->HintDescriptor))
- control->def = 440;
- else if (LADSPA_IS_HINT_DEFAULT_MINIMUM (hint->HintDescriptor))
- control->def = control->min;
- else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM (hint->HintDescriptor))
- control->def = control->max;
- else if (LADSPA_IS_HINT_DEFAULT_LOW (hint->HintDescriptor))
- {
- if (LADSPA_IS_HINT_LOGARITHMIC (hint->HintDescriptor))
- control->def = expf (0.75 * logf (control->min) + 0.25 * logf (control->max));
- else
- control->def = 0.75 * control->min + 0.25 * control->max;
- }
- else if (LADSPA_IS_HINT_DEFAULT_HIGH (hint->HintDescriptor))
- {
- if (LADSPA_IS_HINT_LOGARITHMIC (hint->HintDescriptor))
- control->def = expf (0.25 * logf (control->min) + 0.75 * logf (control->max));
- else
- control->def = 0.25 * control->min + 0.75 * control->max;
- }
- else
- {
- if (LADSPA_IS_HINT_LOGARITHMIC (hint->HintDescriptor))
- control->def = expf (0.5 * logf (control->min) + 0.5 * logf (control->max));
- else
- control->def = 0.5 * control->min + 0.5 * control->max;
- }
-
- return control;
-}
-
-static void free_control (ControlData * control)
-{
- g_free (control->name);
- g_slice_free (ControlData, control);
-}
-
-static PluginData * open_plugin (const char * path, const LADSPA_Descriptor * desc)
-{
- const char * slash = strrchr (path, G_DIR_SEPARATOR);
- g_return_val_if_fail (slash && slash[1], NULL);
- g_return_val_if_fail (desc->Label && desc->Name, NULL);
-
- PluginData * plugin = g_slice_new (PluginData);
- plugin->path = g_strdup (slash + 1);
- plugin->desc = desc;
- plugin->controls = index_new ();
- plugin->in_ports = g_array_new (0, 0, sizeof (int));
- plugin->out_ports = g_array_new (0, 0, sizeof (int));
- plugin->selected = 0;
-
- for (int i = 0; i < desc->PortCount; i ++)
- {
- if (LADSPA_IS_PORT_CONTROL (desc->PortDescriptors[i]))
- {
- ControlData * control = parse_control (desc, i);
- if (control)
- index_insert (plugin->controls, -1, control);
- }
- else if (LADSPA_IS_PORT_AUDIO (desc->PortDescriptors[i]) &&
- LADSPA_IS_PORT_INPUT (desc->PortDescriptors[i]))
- g_array_append_val (plugin->in_ports, i);
- else if (LADSPA_IS_PORT_AUDIO (desc->PortDescriptors[i]) &&
- LADSPA_IS_PORT_OUTPUT (desc->PortDescriptors[i]))
- g_array_append_val (plugin->out_ports, i);
- }
-
- return plugin;
-}
-
-static void close_plugin (PluginData * plugin)
-{
- g_free (plugin->path);
- index_free_full (plugin->controls, (IndexFreeFunc) free_control);
- g_array_free (plugin->in_ports, 1);
- g_array_free (plugin->out_ports, 1);
- g_slice_free (PluginData, plugin);
-}
-
-static void * open_module (const char * path)
-{
- GModule * handle = g_module_open (path, G_MODULE_BIND_LOCAL);
- if (! handle)
- {
- fprintf (stderr, "ladspa: Failed to open module %s: %s\n", path, g_module_error ());
- return NULL;
- }
-
- void * sym;
- if (! g_module_symbol (handle, "ladspa_descriptor", & sym))
- {
- fprintf (stderr, "ladspa: Not a valid LADSPA module: %s\n", path);
- g_module_close (handle);
- return NULL;
- }
-
- LADSPA_Descriptor_Function descfun = (LADSPA_Descriptor_Function) sym;
-
- const LADSPA_Descriptor * desc;
- for (int i = 0; (desc = descfun (i)); i ++)
- {
- PluginData * plugin = open_plugin (path, desc);
- if (plugin)
- index_insert (plugins, -1, plugin);
- }
-
- return handle;
-}
-
-static void open_modules_for_path (const char * path)
-{
- GDir * folder = g_dir_open (path, 0, NULL);
- if (! folder)
- {
- fprintf (stderr, "ladspa: Failed to read folder %s: %s\n", path, strerror (errno));
- return;
- }
-
- const char * name;
- while ((name = g_dir_read_name (folder)))
- {
- if (! str_has_suffix_nocase (name, G_MODULE_SUFFIX))
- continue;
-
- char * filename = filename_build (path, name);
- void * handle = open_module (filename);
-
- if (handle)
- index_insert (modules, -1, handle);
-
- str_unref (filename);
- }
-
- g_dir_close (folder);
-}
-
-static void open_modules_for_paths (const char * paths)
-{
- if (! paths || ! paths[0])
- return;
-
- char * * split = g_strsplit (paths, ":", -1);
-
- for (int i = 0; split[i]; i ++)
- open_modules_for_path (split[i]);
-
- g_strfreev (split);
-}
-
-static void open_modules (void)
-{
- open_modules_for_paths (getenv ("LADSPA_PATH"));
- open_modules_for_paths (module_path);
-}
-
-static void close_modules (void)
-{
- index_delete_full (plugins, 0, -1, (IndexFreeFunc) close_plugin);
- index_delete_full (modules, 0, -1, (IndexFreeFunc) g_module_close);
-}
-
-LoadedPlugin * enable_plugin_locked (PluginData * plugin)
-{
- LoadedPlugin * loaded = g_slice_new (LoadedPlugin);
- loaded->plugin = plugin;
- loaded->selected = 0;
-
- int count = index_count (plugin->controls);
- loaded->values = g_malloc (sizeof (float) * count);
-
- for (int i = 0; i < count; i ++)
- {
- ControlData * control = index_get (plugin->controls, i);
- loaded->values[i] = control->def;
- }
-
- loaded->active = 0;
- loaded->instances = NULL;
- loaded->in_bufs = NULL;
- loaded->out_bufs = NULL;
-
- loaded->settings_win = NULL;
-
- index_insert (loadeds, -1, loaded);
- return loaded;
-}
-
-void disable_plugin_locked (int i)
-{
- g_return_if_fail (i >= 0 && i < index_count (loadeds));
- LoadedPlugin * loaded = index_get (loadeds, i);
-
- if (loaded->settings_win)
- gtk_widget_destroy (loaded->settings_win);
-
- shutdown_plugin_locked (loaded);
-
- g_free (loaded->values);
- g_slice_free (LoadedPlugin, loaded);
- index_delete (loadeds, i, 1);
-}
-
-static PluginData * find_plugin (const char * path, const char * label)
-{
- int count = index_count (plugins);
- for (int i = 0; i < count; i ++)
- {
- PluginData * plugin = index_get (plugins, i);
- if (! strcmp (plugin->path, path) && ! strcmp (plugin->desc->Label, label))
- return plugin;
- }
-
- return NULL;
-}
-
-static void save_enabled_to_config (void)
-{
- int count = index_count (loadeds);
- int old_count = aud_get_int ("ladspa", "plugin_count");
- aud_set_int ("ladspa", "plugin_count", count);
-
- for (int i = 0; i < count; i ++)
- {
- LoadedPlugin * loaded = index_get (loadeds, 0);
- char key[32];
-
- snprintf (key, sizeof key, "plugin%d_path", i);
- aud_set_str ("ladspa", key, loaded->plugin->path);
-
- snprintf (key, sizeof key, "plugin%d_label", i);
- aud_set_str ("ladspa", key, loaded->plugin->desc->Label);
-
- snprintf (key, sizeof key, "plugin%d_controls", i);
-
- int ccount = index_count (loaded->plugin->controls);
- double temp[ccount];
-
- for (int ci = 0; ci < ccount; ci ++)
- temp[ci] = loaded->values[ci];
-
- char * controls = double_array_to_str (temp, ccount);
- aud_set_str ("ladspa", key, controls);
- str_unref (controls);
-
- disable_plugin_locked (0);
- }
-
- for (int i = count; i < old_count; i ++)
- {
- char key[32];
-
- snprintf (key, sizeof key, "plugin%d_path", i);
- aud_set_str ("ladspa", key, "");
-
- snprintf (key, sizeof key, "plugin%d_label", i);
- aud_set_str ("ladspa", key, "");
-
- snprintf (key, sizeof key, "plugin%d_controls", i);
- aud_set_str ("ladspa", key, "");
- }
-}
-
-static void load_enabled_from_config (void)
-{
- int count = aud_get_int ("ladspa", "plugin_count");
-
- for (int i = 0; i < count; i ++)
- {
- char key[32];
-
- snprintf (key, sizeof key, "plugin%d_path", i);
- char * path = aud_get_str ("ladspa", key);
-
- snprintf (key, sizeof key, "plugin%d_label", i);
- char * label = aud_get_str ("ladspa", key);
-
- PluginData * plugin = find_plugin (path, label);
- if (plugin)
- {
- LoadedPlugin * loaded = enable_plugin_locked (plugin);
-
- snprintf (key, sizeof key, "plugin%d_controls", i);
-
- int ccount = index_count (loaded->plugin->controls);
- double temp[ccount];
-
- char * controls = aud_get_str ("ladspa", key);
-
- if (str_to_double_array (controls, temp, ccount))
- {
- for (int ci = 0; ci < ccount; ci ++)
- loaded->values[ci] = temp[ci];
- }
- else
- {
- /* migrate from old config format */
- for (int ci = 0; ci < ccount; ci ++)
- {
- snprintf (key, sizeof key, "plugin%d_control%d", i, ci);
- loaded->values[ci] = aud_get_double ("ladspa", key);
- aud_set_str ("ladspa", key, "");
- }
- }
-
- str_unref (controls);
- }
-
- str_unref (path);
- str_unref (label);
- }
-}
-
-static int init (void)
-{
- pthread_mutex_lock (& mutex);
-
- modules = index_new ();
- plugins = index_new ();
- loadeds = index_new ();
-
- aud_config_set_defaults ("ladspa", ladspa_defaults);
-
- module_path = aud_get_str ("ladspa", "module_path");
-
- open_modules ();
- load_enabled_from_config ();
-
- pthread_mutex_unlock (& mutex);
- return 1;
-}
-
-static void cleanup (void)
-{
- if (config_win)
- gtk_widget_destroy (config_win);
-
- pthread_mutex_lock (& mutex);
-
- aud_set_str ("ladspa", "module_path", module_path);
- save_enabled_to_config ();
- close_modules ();
-
- index_free (modules);
- modules = NULL;
- index_free (plugins);
- plugins = NULL;
- index_free (loadeds);
- loadeds = NULL;
-
- str_unref (module_path);
- module_path = NULL;
-
- pthread_mutex_unlock (& mutex);
-}
-
-static void set_module_path (GtkEntry * entry)
-{
- pthread_mutex_lock (& mutex);
-
- save_enabled_to_config ();
- close_modules ();
-
- str_unref (module_path);
- module_path = str_get (gtk_entry_get_text (entry));
-
- open_modules ();
- load_enabled_from_config ();
-
- pthread_mutex_unlock (& mutex);
-
- if (plugin_list)
- update_plugin_list (plugin_list);
- if (loaded_list)
- update_loaded_list (loaded_list);
-}
-
-static void enable_selected (void)
-{
- pthread_mutex_lock (& mutex);
-
- int count = index_count (plugins);
- for (int i = 0; i < count; i ++)
- {
- PluginData * plugin = index_get (plugins, i);
- if (plugin->selected)
- enable_plugin_locked (plugin);
- }
-
- pthread_mutex_unlock (& mutex);
-
- if (loaded_list)
- update_loaded_list (loaded_list);
-}
-
-static void disable_selected (void)
-{
- pthread_mutex_lock (& mutex);
-
- int count = index_count (loadeds);
- int offset = 0;
- for (int i = 0; i < count; i ++)
- {
- LoadedPlugin * loaded = index_get (loadeds, i - offset);
- if (loaded->selected)
- {
- disable_plugin_locked (i - offset);
- offset ++;
- }
- }
-
- pthread_mutex_unlock (& mutex);
-
- if (loaded_list)
- update_loaded_list (loaded_list);
-}
-
-static void control_toggled (GtkToggleButton * toggle, float * value)
-{
- pthread_mutex_lock (& mutex);
- * value = gtk_toggle_button_get_active (toggle) ? 1 : 0;
- pthread_mutex_unlock (& mutex);
-}
-
-static void control_changed (GtkSpinButton * spin, float * value)
-{
- pthread_mutex_lock (& mutex);
- * value = gtk_spin_button_get_value (spin);
- pthread_mutex_unlock (& mutex);
-}
-
-static void configure_plugin (LoadedPlugin * loaded)
-{
- if (loaded->settings_win)
- {
- gtk_window_present ((GtkWindow *) loaded->settings_win);
- return;
- }
-
- PluginData * plugin = loaded->plugin;
- char buf[200];
-
- snprintf (buf, sizeof buf, _("%s Settings"), plugin->desc->Name);
- loaded->settings_win = gtk_dialog_new_with_buttons (buf, (GtkWindow *)
- config_win, GTK_DIALOG_DESTROY_WITH_PARENT, _("_Close"),
- GTK_RESPONSE_CLOSE, NULL);
- gtk_window_set_resizable ((GtkWindow *) loaded->settings_win, 0);
-
- GtkWidget * vbox = gtk_dialog_get_content_area ((GtkDialog *) loaded->settings_win);
-
- int count = index_count (plugin->controls);
- for (int i = 0; i < count; i ++)
- {
- ControlData * control = index_get (plugin->controls, i);
-
- GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start ((GtkBox *) vbox, hbox, 0, 0, 0);
-
- if (control->is_toggle)
- {
- GtkWidget * toggle = gtk_check_button_new_with_label (control->name);
- gtk_toggle_button_set_active ((GtkToggleButton *) toggle, (loaded->values[i] > 0) ? 1 : 0);
- gtk_box_pack_start ((GtkBox *) hbox, toggle, 0, 0, 0);
-
- g_signal_connect (toggle, "toggled", (GCallback) control_toggled, & loaded->values[i]);
- }
- else
- {
- snprintf (buf, sizeof buf, "%s:", control->name);
- GtkWidget * label = gtk_label_new (buf);
- gtk_box_pack_start ((GtkBox *) hbox, label, 0, 0, 0);
-
- GtkWidget * spin = gtk_spin_button_new_with_range (control->min, control->max, 0.01);
- gtk_spin_button_set_value ((GtkSpinButton *) spin, loaded->values[i]);
- gtk_box_pack_start ((GtkBox *) hbox, spin, 0, 0, 0);
-
- g_signal_connect (spin, "value-changed", (GCallback) control_changed, & loaded->values[i]);
- }
- }
-
- g_signal_connect (loaded->settings_win, "response", (GCallback) gtk_widget_destroy, NULL);
- g_signal_connect (loaded->settings_win, "destroy", (GCallback)
- gtk_widget_destroyed, & loaded->settings_win);
-
- gtk_widget_show_all (loaded->settings_win);
-}
-
-static void configure_selected (void)
-{
- pthread_mutex_lock (& mutex);
-
- int count = index_count (loadeds);
- for (int i = 0; i < count; i ++)
- {
- LoadedPlugin * loaded = index_get (loadeds, i);
- if (loaded->selected)
- configure_plugin (loaded);
- }
-
- pthread_mutex_unlock (& mutex);
-}
-
-static void configure (void)
-{
- if (config_win)
- {
- gtk_window_present ((GtkWindow *) config_win);
- return;
- }
-
- config_win = gtk_dialog_new_with_buttons (_("LADSPA Host Settings"), NULL,
- 0, _("_Close"), GTK_RESPONSE_CLOSE, NULL);
- gtk_window_set_default_size ((GtkWindow *) config_win, 480, 360);
-
- GtkWidget * vbox = gtk_dialog_get_content_area ((GtkDialog *) config_win);
-
- GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start ((GtkBox *) vbox, hbox, 0, 0, 0);
-
- GtkWidget * label = gtk_label_new (_("Module paths:"));
- gtk_box_pack_start ((GtkBox *) hbox, label, 0, 0, 0);
-
- label = gtk_label_new (0);
- gtk_label_set_markup ((GtkLabel *) label,
- _("<small>Separate multiple paths with a colon.\n"
- "These paths are searched in addition to LADSPA_PATH.\n"
- "After adding new paths, press Enter to scan for new plugins.</small>"));
- gtk_misc_set_padding ((GtkMisc *) label, 12, 6);
- gtk_misc_set_alignment ((GtkMisc *) label, 0, 0);
- gtk_box_pack_start ((GtkBox *) vbox, label, 0, 0, 0);
-
- GtkWidget * entry = gtk_entry_new ();
- gtk_box_pack_start ((GtkBox *) hbox, entry, 1, 1, 0);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start ((GtkBox *) vbox, hbox, 1, 1, 0);
-
- GtkWidget * vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_box_pack_start ((GtkBox *) hbox, vbox2, 1, 1, 0);
-
- label = gtk_label_new (_("Available plugins:"));
- gtk_box_pack_start ((GtkBox *) vbox2, label, 0, 0, 0);
-
- GtkWidget * scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled, GTK_SHADOW_IN);
- gtk_box_pack_start ((GtkBox *) vbox2, scrolled, 1, 1, 0);
-
- plugin_list = create_plugin_list ();
- gtk_container_add ((GtkContainer *) scrolled, plugin_list);
-
- GtkWidget * hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start ((GtkBox *) vbox2, hbox2, 0, 0, 0);
-
- GtkWidget * enable_button = gtk_button_new_with_label (_("Enable"));
- gtk_box_pack_end ((GtkBox *) hbox2, enable_button, 0, 0, 0);
-
- vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_box_pack_start ((GtkBox *) hbox, vbox2, 1, 1, 0);
-
- label = gtk_label_new (_("Enabled plugins:"));
- gtk_box_pack_start ((GtkBox *) vbox2, label, 0, 0, 0);
-
- scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled, GTK_SHADOW_IN);
- gtk_box_pack_start ((GtkBox *) vbox2, scrolled, 1, 1, 0);
-
- loaded_list = create_loaded_list ();
- gtk_container_add ((GtkContainer *) scrolled, loaded_list);
-
- hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start ((GtkBox *) vbox2, hbox2, 0, 0, 0);
-
- GtkWidget * disable_button = gtk_button_new_with_label (_("Disable"));
- gtk_box_pack_end ((GtkBox *) hbox2, disable_button, 0, 0, 0);
-
- GtkWidget * settings_button = gtk_button_new_with_label (_("Settings"));
- gtk_box_pack_end ((GtkBox *) hbox2, settings_button, 0, 0, 0);
-
- if (module_path)
- gtk_entry_set_text ((GtkEntry *) entry, module_path);
-
- g_signal_connect (config_win, "response", (GCallback) gtk_widget_destroy, NULL);
- g_signal_connect (config_win, "destroy", (GCallback) gtk_widget_destroyed, & config_win);
- g_signal_connect (entry, "activate", (GCallback) set_module_path, NULL);
- g_signal_connect (plugin_list, "destroy", (GCallback) gtk_widget_destroyed, & plugin_list);
- g_signal_connect (enable_button, "clicked", (GCallback) enable_selected, NULL);
- g_signal_connect (loaded_list, "destroy", (GCallback) gtk_widget_destroyed, & loaded_list);
- g_signal_connect (disable_button, "clicked", (GCallback) disable_selected, NULL);
- g_signal_connect (settings_button, "clicked", (GCallback) configure_selected, NULL);
-
- gtk_widget_show_all (config_win);
-}
-
-static const char about[] =
- N_("LADSPA Host for Audacious\n"
- "Copyright 2011 John Lindgren");
-
-AUD_EFFECT_PLUGIN
-(
- .name = N_("LADSPA Host"),
- .domain = PACKAGE,
- .about_text = about,
- .init = init,
- .cleanup = cleanup,
- .configure = configure,
- .start = ladspa_start,
- .process = ladspa_process,
- .flush = ladspa_flush,
- .finish = ladspa_finish,
- .preserves_format = 1,
-)
diff --git a/src/ladspa/plugin.cc b/src/ladspa/plugin.cc
new file mode 100644
index 000000000000..4b0e07ed1cfc
--- /dev/null
+++ b/src/ladspa/plugin.cc
@@ -0,0 +1,560 @@
+/*
+ * LADSPA Host for Audacious
+ * Copyright 2011 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <errno.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <algorithm>
+
+#include <gmodule.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/runtime.h>
+
+#include "plugin.h"
+
+const char * const LADSPAHost::defaults[] = {
+ "plugin_count", "0",
+ nullptr};
+
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+String module_path;
+Index<GModule *> modules;
+Index<SmartPtr<PluginData>> plugins;
+Index<SmartPtr<LoadedPlugin>> loadeds;
+
+GtkWidget * plugin_list;
+GtkWidget * loaded_list;
+
+static ControlData parse_control (const LADSPA_Descriptor & desc, int port)
+{
+ const LADSPA_PortRangeHint & hint = desc.PortRangeHints[port];
+
+ ControlData control;
+ control.port = port;
+ control.name = String (desc.PortNames[port]);
+ control.is_toggle = LADSPA_IS_HINT_TOGGLED (hint.HintDescriptor) ? 1 : 0;
+
+ control.min = LADSPA_IS_HINT_BOUNDED_BELOW (hint.HintDescriptor) ? hint.LowerBound :
+ LADSPA_IS_HINT_BOUNDED_ABOVE (hint.HintDescriptor) ? hint.UpperBound - 100 : -100;
+ control.max = LADSPA_IS_HINT_BOUNDED_ABOVE (hint.HintDescriptor) ? hint.UpperBound :
+ LADSPA_IS_HINT_BOUNDED_BELOW (hint.HintDescriptor) ? hint.LowerBound + 100 : 100;
+
+ if (LADSPA_IS_HINT_SAMPLE_RATE (hint.HintDescriptor))
+ {
+ control.min *= 96000;
+ control.max *= 96000;
+ }
+
+ if (LADSPA_IS_HINT_DEFAULT_0 (hint.HintDescriptor))
+ control.def = 0;
+ else if (LADSPA_IS_HINT_DEFAULT_1 (hint.HintDescriptor))
+ control.def = 1;
+ else if (LADSPA_IS_HINT_DEFAULT_100 (hint.HintDescriptor))
+ control.def = 100;
+ else if (LADSPA_IS_HINT_DEFAULT_440 (hint.HintDescriptor))
+ control.def = 440;
+ else if (LADSPA_IS_HINT_DEFAULT_MINIMUM (hint.HintDescriptor))
+ control.def = control.min;
+ else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM (hint.HintDescriptor))
+ control.def = control.max;
+ else if (LADSPA_IS_HINT_DEFAULT_LOW (hint.HintDescriptor))
+ {
+ if (LADSPA_IS_HINT_LOGARITHMIC (hint.HintDescriptor))
+ control.def = expf (0.75 * logf (control.min) + 0.25 * logf (control.max));
+ else
+ control.def = 0.75 * control.min + 0.25 * control.max;
+ }
+ else if (LADSPA_IS_HINT_DEFAULT_HIGH (hint.HintDescriptor))
+ {
+ if (LADSPA_IS_HINT_LOGARITHMIC (hint.HintDescriptor))
+ control.def = expf (0.25 * logf (control.min) + 0.75 * logf (control.max));
+ else
+ control.def = 0.25 * control.min + 0.75 * control.max;
+ }
+ else
+ {
+ if (LADSPA_IS_HINT_LOGARITHMIC (hint.HintDescriptor))
+ control.def = expf (0.5 * logf (control.min) + 0.5 * logf (control.max));
+ else
+ control.def = 0.5 * control.min + 0.5 * control.max;
+ }
+
+ return control;
+}
+
+static void open_plugin (const char * path, const LADSPA_Descriptor & desc)
+{
+ const char * slash = strrchr (path, G_DIR_SEPARATOR);
+ g_return_if_fail (slash && slash[1]);
+ g_return_if_fail (desc.Label && desc.Name);
+
+ PluginData & plugin = * plugins.append (SmartNew<PluginData> (slash + 1, desc));
+
+ for (unsigned i = 0; i < desc.PortCount; i ++)
+ {
+ if (LADSPA_IS_PORT_CONTROL (desc.PortDescriptors[i]))
+ plugin.controls.append (parse_control (desc, i));
+ else if (LADSPA_IS_PORT_AUDIO (desc.PortDescriptors[i]) &&
+ LADSPA_IS_PORT_INPUT (desc.PortDescriptors[i]))
+ plugin.in_ports.append (i);
+ else if (LADSPA_IS_PORT_AUDIO (desc.PortDescriptors[i]) &&
+ LADSPA_IS_PORT_OUTPUT (desc.PortDescriptors[i]))
+ plugin.out_ports.append (i);
+ }
+}
+
+static GModule * open_module (const char * path)
+{
+ GModule * handle = g_module_open (path, G_MODULE_BIND_LOCAL);
+ if (! handle)
+ {
+ AUDERR ("Failed to open module %s: %s\n", path, g_module_error ());
+ return nullptr;
+ }
+
+ void * sym;
+ if (! g_module_symbol (handle, "ladspa_descriptor", & sym))
+ {
+ AUDERR ("Not a valid LADSPA module: %s\n", path);
+ g_module_close (handle);
+ return nullptr;
+ }
+
+ LADSPA_Descriptor_Function descfun = (LADSPA_Descriptor_Function) sym;
+
+ const LADSPA_Descriptor * desc;
+ for (int i = 0; (desc = descfun (i)); i ++)
+ open_plugin (path, * desc);
+
+ return handle;
+}
+
+static void open_modules_for_path (const char * path)
+{
+ GDir * folder = g_dir_open (path, 0, nullptr);
+ if (! folder)
+ {
+ AUDERR ("Failed to read folder %s: %s\n", path, strerror (errno));
+ return;
+ }
+
+ const char * name;
+ while ((name = g_dir_read_name (folder)))
+ {
+ if (! str_has_suffix_nocase (name, G_MODULE_SUFFIX))
+ continue;
+
+ GModule * handle = open_module (filename_build ({path, name}));
+
+ if (handle)
+ modules.append (handle);
+ }
+
+ g_dir_close (folder);
+}
+
+static void open_modules_for_paths (const char * paths)
+{
+ if (! paths || ! paths[0])
+ return;
+
+ char * * split = g_strsplit (paths, ":", -1);
+
+ for (int i = 0; split[i]; i ++)
+ open_modules_for_path (split[i]);
+
+ g_strfreev (split);
+}
+
+static void open_modules ()
+{
+ open_modules_for_paths (getenv ("LADSPA_PATH"));
+ open_modules_for_paths (module_path);
+}
+
+static void close_modules ()
+{
+ plugins.clear ();
+
+ for (GModule * module : modules)
+ g_module_close (module);
+}
+
+LoadedPlugin & enable_plugin_locked (PluginData & plugin)
+{
+ LoadedPlugin & loaded = * loadeds.append (SmartNew<LoadedPlugin> (plugin));
+
+ for (auto & control : plugin.controls)
+ loaded.values.append (control.def);
+
+ return loaded;
+}
+
+void disable_plugin_locked (LoadedPlugin & loaded)
+{
+ if (loaded.settings_win)
+ gtk_widget_destroy (loaded.settings_win);
+
+ shutdown_plugin_locked (loaded);
+}
+
+static PluginData * find_plugin (const char * path, const char * label)
+{
+ for (auto & plugin : plugins)
+ {
+ if (! strcmp (plugin->path, path) && ! strcmp (plugin->desc.Label, label))
+ return plugin.get ();
+ }
+
+ return nullptr;
+}
+
+static void save_enabled_to_config ()
+{
+ int count = loadeds.len ();
+ int old_count = aud_get_int ("ladspa", "plugin_count");
+ aud_set_int ("ladspa", "plugin_count", count);
+
+ for (int i = 0; i < count; i ++)
+ {
+ LoadedPlugin & loaded = * loadeds[i];
+
+ aud_set_str ("ladspa", str_printf ("plugin%d_path", i), loaded.plugin.path);
+ aud_set_str ("ladspa", str_printf ("plugin%d_label", i), loaded.plugin.desc.Label);
+
+ Index<double> temp;
+ temp.insert (0, loaded.values.len ());
+ std::copy (loaded.values.begin (), loaded.values.end (), temp.begin ());
+
+ aud_set_str ("ladspa", str_printf ("plugin%d_controls", i),
+ double_array_to_str (temp.begin (), temp.len ()));
+
+ disable_plugin_locked (loaded);
+ }
+
+ loadeds.clear ();
+
+ for (int i = count; i < old_count; i ++)
+ {
+ aud_set_str ("ladspa", str_printf ("plugin%d_path", i), "");
+ aud_set_str ("ladspa", str_printf ("plugin%d_label", i), "");
+ aud_set_str ("ladspa", str_printf ("plugin%d_controls", i), "");
+ }
+}
+
+static void load_enabled_from_config ()
+{
+ int count = aud_get_int ("ladspa", "plugin_count");
+
+ for (int i = 0; i < count; i ++)
+ {
+ String path = aud_get_str ("ladspa", str_printf ("plugin%d_path", i));
+ String label = aud_get_str ("ladspa", str_printf ("plugin%d_label", i));
+
+ PluginData * plugin = find_plugin (path, label);
+ if (! plugin)
+ continue;
+
+ LoadedPlugin & loaded = enable_plugin_locked (* plugin);
+
+ String controls = aud_get_str ("ladspa", str_printf ("plugin%d_controls", i));
+
+ Index<double> temp;
+ temp.insert (0, loaded.values.len ());
+
+ if (str_to_double_array (controls, temp.begin (), temp.len ()))
+ std::copy (temp.begin (), temp.end (), loaded.values.begin ());
+ else
+ {
+ /* migrate from old config format */
+ for (int ci = 0; ci < temp.len (); ci ++)
+ {
+ StringBuf key = str_printf ("plugin%d_control%d", i, ci);
+ loaded.values[ci] = aud_get_double ("ladspa", key);
+ aud_set_str ("ladspa", key, "");
+ }
+ }
+ }
+}
+
+bool LADSPAHost::init ()
+{
+ pthread_mutex_lock (& mutex);
+
+ aud_config_set_defaults ("ladspa", defaults);
+
+ module_path = aud_get_str ("ladspa", "module_path");
+
+ open_modules ();
+ load_enabled_from_config ();
+
+ pthread_mutex_unlock (& mutex);
+ return true;
+}
+
+void LADSPAHost::cleanup ()
+{
+ pthread_mutex_lock (& mutex);
+
+ aud_set_str ("ladspa", "module_path", module_path);
+ save_enabled_to_config ();
+ close_modules ();
+
+ modules.clear ();
+ plugins.clear ();
+ loadeds.clear ();
+
+ module_path = String ();
+
+ pthread_mutex_unlock (& mutex);
+}
+
+static void set_module_path (GtkEntry * entry)
+{
+ pthread_mutex_lock (& mutex);
+
+ save_enabled_to_config ();
+ close_modules ();
+
+ module_path = String (gtk_entry_get_text (entry));
+
+ open_modules ();
+ load_enabled_from_config ();
+
+ pthread_mutex_unlock (& mutex);
+
+ if (plugin_list)
+ update_plugin_list (plugin_list);
+ if (loaded_list)
+ update_loaded_list (loaded_list);
+}
+
+static void enable_selected ()
+{
+ pthread_mutex_lock (& mutex);
+
+ for (auto & plugin : plugins)
+ {
+ if (plugin->selected)
+ enable_plugin_locked (* plugin);
+ }
+
+ pthread_mutex_unlock (& mutex);
+
+ if (loaded_list)
+ update_loaded_list (loaded_list);
+}
+
+static void disable_selected ()
+{
+ pthread_mutex_lock (& mutex);
+
+ for (int i = 0; i < loadeds.len (); i ++)
+ {
+ if (loadeds[i]->selected)
+ {
+ disable_plugin_locked (* loadeds[i]);
+ loadeds.remove (i, 1);
+ }
+ else
+ i ++;
+ }
+
+ pthread_mutex_unlock (& mutex);
+
+ if (loaded_list)
+ update_loaded_list (loaded_list);
+}
+
+static void control_toggled (GtkToggleButton * toggle, float * value)
+{
+ pthread_mutex_lock (& mutex);
+ * value = gtk_toggle_button_get_active (toggle) ? 1 : 0;
+ pthread_mutex_unlock (& mutex);
+}
+
+static void control_changed (GtkSpinButton * spin, float * value)
+{
+ pthread_mutex_lock (& mutex);
+ * value = gtk_spin_button_get_value (spin);
+ pthread_mutex_unlock (& mutex);
+}
+
+static void configure_plugin (LoadedPlugin & loaded)
+{
+ if (loaded.settings_win)
+ {
+ gtk_window_present ((GtkWindow *) loaded.settings_win);
+ return;
+ }
+
+ PluginData & plugin = loaded.plugin;
+
+ StringBuf title = str_printf (_("%s Settings"), plugin.desc.Name);
+ loaded.settings_win = gtk_dialog_new_with_buttons (title, nullptr,
+ (GtkDialogFlags) 0, _("_Close"), GTK_RESPONSE_CLOSE, nullptr);
+ gtk_window_set_resizable ((GtkWindow *) loaded.settings_win, 0);
+
+ GtkWidget * vbox = gtk_dialog_get_content_area ((GtkDialog *) loaded.settings_win);
+
+ int count = plugin.controls.len ();
+ for (int i = 0; i < count; i ++)
+ {
+ ControlData & control = plugin.controls[i];
+
+ GtkWidget * hbox = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start ((GtkBox *) vbox, hbox, 0, 0, 0);
+
+ if (control.is_toggle)
+ {
+ GtkWidget * toggle = gtk_check_button_new_with_label (control.name);
+ gtk_toggle_button_set_active ((GtkToggleButton *) toggle, (loaded.values[i] > 0) ? 1 : 0);
+ gtk_box_pack_start ((GtkBox *) hbox, toggle, 0, 0, 0);
+
+ g_signal_connect (toggle, "toggled", (GCallback) control_toggled, & loaded.values[i]);
+ }
+ else
+ {
+ GtkWidget * label = gtk_label_new (str_printf ("%s:", (const char *) control.name));
+ gtk_box_pack_start ((GtkBox *) hbox, label, 0, 0, 0);
+
+ GtkWidget * spin = gtk_spin_button_new_with_range (control.min, control.max, 0.01);
+ gtk_spin_button_set_value ((GtkSpinButton *) spin, loaded.values[i]);
+ gtk_box_pack_start ((GtkBox *) hbox, spin, 0, 0, 0);
+
+ g_signal_connect (spin, "value-changed", (GCallback) control_changed, & loaded.values[i]);
+ }
+ }
+
+ g_signal_connect (loaded.settings_win, "response", (GCallback) gtk_widget_destroy, nullptr);
+ g_signal_connect (loaded.settings_win, "destroy", (GCallback)
+ gtk_widget_destroyed, & loaded.settings_win);
+
+ gtk_widget_show_all (loaded.settings_win);
+}
+
+static void configure_selected ()
+{
+ pthread_mutex_lock (& mutex);
+
+ for (auto & loaded : loadeds)
+ {
+ if (loaded->selected)
+ configure_plugin (* loaded);
+ }
+
+ pthread_mutex_unlock (& mutex);
+}
+
+static void * make_config_widget ()
+{
+ GtkWidget * vbox = gtk_vbox_new (FALSE, 6);
+ gtk_widget_set_size_request (vbox, 480, 360);
+
+ GtkWidget * hbox = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start ((GtkBox *) vbox, hbox, 0, 0, 0);
+
+ GtkWidget * label = gtk_label_new (_("Module paths:"));
+ gtk_box_pack_start ((GtkBox *) hbox, label, 0, 0, 0);
+
+ label = gtk_label_new (0);
+ gtk_label_set_markup ((GtkLabel *) label,
+ _("<small>Separate multiple paths with a colon.\n"
+ "These paths are searched in addition to LADSPA_PATH.\n"
+ "After adding new paths, press Enter to scan for new plugins.</small>"));
+ gtk_misc_set_padding ((GtkMisc *) label, 12, 6);
+ gtk_misc_set_alignment ((GtkMisc *) label, 0, 0);
+ gtk_box_pack_start ((GtkBox *) vbox, label, 0, 0, 0);
+
+ GtkWidget * entry = gtk_entry_new ();
+ gtk_box_pack_start ((GtkBox *) hbox, entry, 1, 1, 0);
+
+ hbox = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start ((GtkBox *) vbox, hbox, 1, 1, 0);
+
+ GtkWidget * vbox2 = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start ((GtkBox *) hbox, vbox2, 1, 1, 0);
+
+ label = gtk_label_new (_("Available plugins:"));
+ gtk_box_pack_start ((GtkBox *) vbox2, label, 0, 0, 0);
+
+ GtkWidget * scrolled = gtk_scrolled_window_new (nullptr, nullptr);
+ gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled, GTK_SHADOW_IN);
+ gtk_box_pack_start ((GtkBox *) vbox2, scrolled, 1, 1, 0);
+
+ plugin_list = create_plugin_list ();
+ gtk_container_add ((GtkContainer *) scrolled, plugin_list);
+
+ GtkWidget * hbox2 = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start ((GtkBox *) vbox2, hbox2, 0, 0, 0);
+
+ GtkWidget * enable_button = gtk_button_new_with_label (_("Enable"));
+ gtk_box_pack_end ((GtkBox *) hbox2, enable_button, 0, 0, 0);
+
+ vbox2 = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start ((GtkBox *) hbox, vbox2, 1, 1, 0);
+
+ label = gtk_label_new (_("Enabled plugins:"));
+ gtk_box_pack_start ((GtkBox *) vbox2, label, 0, 0, 0);
+
+ scrolled = gtk_scrolled_window_new (nullptr, nullptr);
+ gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled, GTK_SHADOW_IN);
+ gtk_box_pack_start ((GtkBox *) vbox2, scrolled, 1, 1, 0);
+
+ loaded_list = create_loaded_list ();
+ gtk_container_add ((GtkContainer *) scrolled, loaded_list);
+
+ hbox2 = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start ((GtkBox *) vbox2, hbox2, 0, 0, 0);
+
+ GtkWidget * disable_button = gtk_button_new_with_label (_("Disable"));
+ gtk_box_pack_end ((GtkBox *) hbox2, disable_button, 0, 0, 0);
+
+ GtkWidget * settings_button = gtk_button_new_with_label (_("Settings"));
+ gtk_box_pack_end ((GtkBox *) hbox2, settings_button, 0, 0, 0);
+
+ if (module_path)
+ gtk_entry_set_text ((GtkEntry *) entry, module_path);
+
+ g_signal_connect (entry, "activate", (GCallback) set_module_path, nullptr);
+ g_signal_connect (plugin_list, "destroy", (GCallback) gtk_widget_destroyed, & plugin_list);
+ g_signal_connect (enable_button, "clicked", (GCallback) enable_selected, nullptr);
+ g_signal_connect (loaded_list, "destroy", (GCallback) gtk_widget_destroyed, & loaded_list);
+ g_signal_connect (disable_button, "clicked", (GCallback) disable_selected, nullptr);
+ g_signal_connect (settings_button, "clicked", (GCallback) configure_selected, nullptr);
+
+ return vbox;
+}
+
+const char LADSPAHost::about[] =
+ N_("LADSPA Host for Audacious\n"
+ "Copyright 2011 John Lindgren");
+
+const PreferencesWidget LADSPAHost::widgets[] = {
+ WidgetCustomGTK (make_config_widget)
+};
+
+const PluginPreferences LADSPAHost::prefs = {{widgets}};
+
+EXPORT LADSPAHost aud_plugin_instance;
diff --git a/src/ladspa/plugin.h b/src/ladspa/plugin.h
index cd242c1b343b..22c7ca0842be 100644
--- a/src/ladspa/plugin.h
+++ b/src/ladspa/plugin.h
@@ -22,36 +22,75 @@
#include <pthread.h>
#include <gtk/gtk.h>
-#include <libaudcore/index.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
#include "ladspa.h"
#define LADSPA_BUFLEN 1024
-typedef struct {
+struct PreferencesWidget;
+
+struct ControlData {
int port;
- char * name;
- char is_toggle;
+ String name;
+ bool is_toggle;
float min, max, def;
-} ControlData;
-
-typedef struct {
- char * path;
- const LADSPA_Descriptor * desc;
- Index * controls; /* (ControlData *) */
- GArray * in_ports, * out_ports; /* (int) */
- char selected;
-} PluginData;
-
-typedef struct {
- PluginData * plugin;
- float * values;
- char selected;
- char active;
- Index * instances; /* (LADSPA_Handle) */
- float * * in_bufs, * * out_bufs; /* (float *) */
- GtkWidget * settings_win;
-} LoadedPlugin;
+};
+
+struct PluginData
+{
+ String path;
+ const LADSPA_Descriptor & desc;
+ Index<ControlData> controls;
+ Index<int> in_ports, out_ports;
+ bool selected = false;
+
+ PluginData (const char * path, const LADSPA_Descriptor & desc) :
+ path (path),
+ desc (desc) {}
+};
+
+struct LoadedPlugin
+{
+ PluginData & plugin;
+ Index<float> values;
+ bool selected = false;
+ bool active = false;
+ Index<LADSPA_Handle> instances;
+ Index<Index<float>> in_bufs, out_bufs;
+ GtkWidget * settings_win = nullptr;
+
+ LoadedPlugin (PluginData & plugin) :
+ plugin (plugin) {}
+};
+
+class LADSPAHost : public EffectPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("LADSPA Host"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ constexpr LADSPAHost () : EffectPlugin (info, 0, true) {}
+
+ bool init ();
+ void cleanup ();
+
+ void start (int & channels, int & rate);
+ Index<float> & process (Index<float> & data);
+ bool flush (bool force);
+ Index<float> & finish (Index<float> & data, bool end_of_playlist);
+};
/* plugin.c */
@@ -60,36 +99,29 @@ typedef struct {
* audio thread is reading from them. */
extern pthread_mutex_t mutex;
-extern char * module_path;
-extern Index * modules; /* (GModule *) */
-extern Index * plugins; /* (PluginData *) */
-extern Index * loadeds; /* (LoadedPlugin *) */
+extern String module_path;
+extern Index<GModule *> modules;
+extern Index<SmartPtr<PluginData>> plugins;
+extern Index<SmartPtr<LoadedPlugin>> loadeds;
-extern GtkWidget * about_win;
-extern GtkWidget * config_win;
extern GtkWidget * plugin_list;
extern GtkWidget * loaded_list;
-LoadedPlugin * enable_plugin_locked (PluginData * plugin);
-void disable_plugin_locked (int i);
+LoadedPlugin & enable_plugin_locked (PluginData & plugin);
+void disable_plugin_locked (LoadedPlugin & loaded);
/* effect.c */
-void shutdown_plugin_locked (LoadedPlugin * loaded);
-
-void ladspa_start (gint * channels, gint * rate);
-void ladspa_process (gfloat * * data, gint * samples);
-void ladspa_flush (void);
-void ladspa_finish (gfloat * * data, gint * samples);
+void shutdown_plugin_locked (LoadedPlugin & loaded);
/* plugin-list.c */
-GtkWidget * create_plugin_list (void);
+GtkWidget * create_plugin_list ();
void update_plugin_list (GtkWidget * list);
/* loaded-list.c */
-GtkWidget * create_loaded_list (void);
+GtkWidget * create_loaded_list ();
void update_loaded_list (GtkWidget * list);
#endif
diff --git a/src/lirc/Makefile b/src/lirc/Makefile
index b40bcf1c3378..6ee32c7f4246 100644
--- a/src/lirc/Makefile
+++ b/src/lirc/Makefile
@@ -1,12 +1,13 @@
PLUGIN = lirc${PLUGIN_SUFFIX}
-SRCS = lirc.c
+SRCS = lirc.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
LIBS += ${GLIB_LIBS} -llirc_client
diff --git a/src/lirc/lirc.c b/src/lirc/lirc.c
deleted file mode 100644
index b4d1b0e4b89d..000000000000
--- a/src/lirc/lirc.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/* Audacious LIRC plugin - lirc.c
-
- Copyright (C) 2012 Joonas Harjumäki (jharjuma at gmail.com)
-
- Copyright (C) 2005 Audacious development team
-
- Copyright (c) 1998-1999 Carl van Schaik (carl at leg.uct.ac.za)
-
- Copyright (C) 2000 Christoph Bartelmus (xmms at bartelmus.de)
-
- some code was stolen from:
- IRman plugin for xmms by Charles Sielski (stray at teklabs.net)
-
- 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.
-*/
-
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <signal.h>
-#include <stdlib.h>
-
-#include <glib.h>
-#include <lirc/lirc_client.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-#include <libaudcore/hook.h>
-
-static gboolean lirc_input_callback (GIOChannel * source, GIOCondition condition, void * data);
-
-static const char * const lirc_defaults[] = {
- "enable_reconnect", "TRUE",
- "reconnect_timeout", "5",
- NULL};
-
-const char *plugin_name = "LIRC Plugin";
-
-int lirc_fd = -1;
-struct lirc_config *config = NULL;
-gint tracknr = 0;
-gint mute = 0; /* mute flag */
-gint mute_vol = 0; /* holds volume before mute */
-
-guint input_tag;
-
-char track_no[64];
-int track_no_pos;
-gint tid;
-
-void init_lirc (void)
-{
- int flags;
-
- if ((lirc_fd = lirc_init ("audacious", 1)) == -1)
- {
- fprintf (stderr, _("%s: could not init LIRC support\n"), plugin_name);
- return;
- }
- if (lirc_readconfig (NULL, &config, NULL) == -1)
- {
- lirc_deinit ();
- fprintf (stderr,
- _("%s: could not read LIRC config file\n"
- "%s: please read the documentation of LIRC\n"
- "%s: how to create a proper config file\n"),
- plugin_name, plugin_name, plugin_name);
- return;
- }
-
- input_tag =
- g_io_add_watch (g_io_channel_unix_new (lirc_fd), G_IO_IN,
- lirc_input_callback, NULL);
-
- fcntl (lirc_fd, F_SETOWN, getpid ());
- flags = fcntl (lirc_fd, F_GETFL, 0);
- if (flags != -1)
- {
- fcntl (lirc_fd, F_SETFL, flags | O_NONBLOCK);
- }
- fflush (stdout);
-}
-
-gboolean init (void)
-{
- aud_config_set_defaults ("lirc", lirc_defaults);
- init_lirc ();
- track_no_pos = 0;
- tid = 0;
- return TRUE;
-}
-
-gboolean reconnect_lirc (gpointer data)
-{
- fprintf (stderr, _("%s: trying to reconnect...\n"), plugin_name);
- init ();
- return (lirc_fd == -1);
-}
-
-void cleanup ()
-{
- if (config)
- {
- if (input_tag)
- g_source_remove (input_tag);
-
- config = NULL;
- }
- if (lirc_fd != -1)
- {
- lirc_deinit ();
- lirc_fd = -1;
- }
-}
-
-gboolean jump_to (gpointer data)
-{
- int playlist = aud_playlist_get_active ();
- aud_playlist_set_position (playlist, atoi (track_no) - 1);
- track_no_pos = 0;
- tid = 0;
- return FALSE;
-}
-
-static gboolean lirc_input_callback (GIOChannel * source, GIOCondition condition, void * data)
-{
- char *code;
- char *c;
- gint playlist_time, playlist_pos, output_time, v;
- int ret;
- char *ptr;
- gint balance;
-#if 0
- gboolean show_pl;
-#endif
- int n;
- gchar *utf8_title_markup;
-
- while ((ret = lirc_nextcode (&code)) == 0 && code != NULL)
- {
- while ((ret = lirc_code2char (config, code, &c)) == 0 && c != NULL)
- {
- if (g_ascii_strcasecmp ("PLAY", c) == 0)
- aud_drct_play ();
- else if (g_ascii_strcasecmp ("STOP", c) == 0)
- aud_drct_stop ();
- else if (g_ascii_strcasecmp ("PAUSE", c) == 0)
- aud_drct_pause ();
- else if (g_ascii_strcasecmp ("PLAYPAUSE", c) == 0)
- aud_drct_play_pause ();
- else if (g_ascii_strncasecmp ("NEXT", c, 4) == 0)
- {
- ptr = c + 4;
- while (g_ascii_isspace (*ptr))
- ptr++;
- n = atoi (ptr);
-
- if (n <= 0)
- n = 1;
- for (; n > 0; n--)
- {
- aud_drct_pl_next ();
- }
- }
- else if (g_ascii_strncasecmp ("PREV", c, 4) == 0)
- {
- ptr = c + 4;
- while (g_ascii_isspace (*ptr))
- ptr++;
- n = atoi (ptr);
-
- if (n <= 0)
- n = 1;
- for (; n > 0; n--)
- {
- aud_drct_pl_prev ();
- }
- }
- else if (g_ascii_strcasecmp ("SHUFFLE", c) == 0)
- aud_set_bool (NULL, "shuffle", ! aud_get_bool (NULL, "shuffle"));
- else if (g_ascii_strcasecmp ("REPEAT", c) == 0)
- aud_set_bool (NULL, "repeat", ! aud_get_bool (NULL, "repeat"));
- else if (g_ascii_strncasecmp ("FWD", c, 3) == 0)
- {
- ptr = c + 3;
- while (g_ascii_isspace (*ptr))
- ptr++;
- n = atoi (ptr) * 1000;
-
- if (n <= 0)
- n = 5000;
- output_time = aud_drct_get_time ();
-
- int playlist = aud_playlist_get_active ();
- playlist_pos = aud_playlist_get_position (playlist);
- playlist_time =
- aud_playlist_entry_get_length (playlist, playlist_pos,
- FALSE);
- if (playlist_time - output_time < n)
- output_time = playlist_time - n;
- aud_drct_seek (output_time + n);
- }
- else if (g_ascii_strncasecmp ("BWD", c, 3) == 0)
- {
- ptr = c + 3;
- while (g_ascii_isspace (*ptr))
- ptr++;
- n = atoi (ptr) * 1000;
-
- if (n <= 0)
- n = 5000;
- output_time = aud_drct_get_time ();
- if (output_time < n)
- output_time = n;
- aud_drct_seek (output_time - n);
- }
- else if (g_ascii_strncasecmp ("VOL_UP", c, 6) == 0)
- {
- ptr = c + 6;
- while (g_ascii_isspace (*ptr))
- ptr++;
- n = atoi (ptr);
- if (n <= 0)
- n = 5;
-
- aud_drct_get_volume_main (&v);
- if (v > (100 - n))
- v = 100 - n;
- aud_drct_set_volume_main (v + n);
- }
- else if (g_ascii_strncasecmp ("VOL_DOWN", c, 8) == 0)
- {
- ptr = c + 8;
- while (g_ascii_isspace (*ptr))
- ptr++;
- n = atoi (ptr);
- if (n <= 0)
- n = 5;
-
- aud_drct_get_volume_main (&v);
- if (v < n)
- v = n;
- aud_drct_set_volume_main (v - n);
- }
- else if (g_ascii_strcasecmp ("QUIT", c) == 0)
- {
- aud_drct_quit ();
- }
- else if (g_ascii_strcasecmp ("MUTE", c) == 0)
- {
- if (mute == 0)
- {
- mute = 1;
- /* store the master volume so
- we can restore it on unmute. */
- aud_drct_get_volume_main (&mute_vol);
- aud_drct_set_volume_main (0);
- }
- else
- {
- mute = 0;
- aud_drct_set_volume_main (mute_vol);
- }
- }
- else if (g_ascii_strncasecmp ("BAL_LEFT", c, 8) == 0)
- {
- ptr = c + 8;
- while (g_ascii_isspace (*ptr))
- ptr++;
- n = atoi (ptr);
- if (n <= 0)
- n = 5;
-
- aud_drct_get_volume_balance (&balance);
- balance -= n;
- if (balance < -100)
- balance = -100;
- aud_drct_set_volume_balance (balance);
- }
- else if (g_ascii_strncasecmp ("BAL_RIGHT", c, 9) == 0)
- {
- ptr = c + 9;
- while (g_ascii_isspace (*ptr))
- ptr++;
- n = atoi (ptr);
- if (n <= 0)
- n = 5;
-
- aud_drct_get_volume_balance (&balance);
- balance += n;
- if (balance > 100)
- balance = 100;
- aud_drct_set_volume_balance (balance);
- }
- else if (g_ascii_strcasecmp ("BAL_CENTER", c) == 0)
- {
- balance = 0;
- aud_drct_set_volume_balance (balance);
- }
- else if (g_ascii_strcasecmp ("LIST", c) == 0)
- {
-#if 0
- show_pl = aud_drct_pl_win_is_visible ();
- show_pl = (show_pl) ? 0 : 1;
- aud_drct_pl_win_toggle (show_pl);
-#endif
- }
- else if (g_ascii_strcasecmp ("PLAYLIST_CLEAR", c) == 0)
- {
- aud_drct_stop ();
- int playlist = aud_playlist_get_active ();
- aud_playlist_entry_delete (playlist, 0,
- aud_playlist_entry_count
- (playlist));
- }
- else if (g_ascii_strncasecmp ("PLAYLIST_ADD ", c, 13) == 0)
- {
- aud_drct_pl_add (c + 13, -1);
- }
- else if ((strlen (c) == 1) && ((*c >= '0') || (*c <= '9')))
- {
- if (track_no_pos < 63)
- {
- if (tid)
- g_source_remove (tid);
- track_no[track_no_pos++] = *c;
- track_no[track_no_pos] = 0;
- tid = g_timeout_add (1500, jump_to, NULL);
- utf8_title_markup = g_markup_printf_escaped ("%s", track_no);
- hook_call ("aosd toggle", utf8_title_markup);
- }
- }
- else
- {
- fprintf (stderr, _("%s: unknown command \"%s\"\n"),
- plugin_name, c);
- }
- }
- g_free (code);
- if (ret == -1)
- break;
- }
- if (ret == -1)
- {
- /* something went badly wrong */
- fprintf (stderr, _("%s: disconnected from LIRC\n"), plugin_name);
- cleanup ();
- if (aud_get_bool ("lirc", "enable_reconnect"))
- {
- int reconnect_timeout = aud_get_int ("lirc", "reconnect_timeout");
- fprintf (stderr,
- _("%s: will try reconnect every %d seconds...\n"),
- plugin_name, reconnect_timeout);
- g_timeout_add (1000 * reconnect_timeout, reconnect_lirc, NULL);
- }
- }
-
- return TRUE;
-}
-
-static const char about[] =
- N_("A simple plugin to control Audacious using the LIRC remote control daemon\n\n"
- "Adapted for Audacious by:\n"
- "Tony Vroon <chainsaw at gentoo.org>\n"
- "Joonas Harjumäki <jharjuma at gmail.com>\n\n"
- "Based on the XMMS LIRC plugin by:\n"
- "Carl van Schaik <carl at leg.uct.ac.za>\n"
- "Christoph Bartelmus <xmms at bartelmus.de>\n"
- "Andrew O. Shadoura <bugzilla at tut.by>\n\n"
- "For more information about LIRC, see http://lirc.org.");
-
-static const PreferencesWidget widgets[] = {
- {WIDGET_LABEL, N_("<b>Connection</b>")},
- {WIDGET_CHK_BTN, N_("Reconnect to LIRC server"),
- .cfg_type = VALUE_BOOLEAN, .csect = "lirc", .cname = "enable_reconnect"},
- {WIDGET_SPIN_BTN, N_("Wait before reconnecting:"), .child = TRUE,
- .cfg_type = VALUE_INT, .csect = "lirc", .cname = "reconnect_timeout",
- .data = {.spin_btn = {1, 120, 1, N_("seconds")}}}};
-
-static const PluginPreferences prefs = {
- .widgets = widgets,
- .n_widgets = ARRAY_LEN (widgets)};
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("LIRC Plugin"),
- .domain = PACKAGE,
- .about_text = about,
- .prefs = & prefs,
- .init = init,
- .cleanup = cleanup
-)
diff --git a/src/lirc/lirc.cc b/src/lirc/lirc.cc
new file mode 100644
index 000000000000..d0668df9d015
--- /dev/null
+++ b/src/lirc/lirc.cc
@@ -0,0 +1,401 @@
+/* Audacious LIRC plugin - lirc.c
+
+ Copyright (C) 2012 Joonas Harjumäki (jharjuma at gmail.com)
+
+ Copyright (C) 2005 Audacious development team
+
+ Copyright (c) 1998-1999 Carl van Schaik (carl at leg.uct.ac.za)
+
+ Copyright (C) 2000 Christoph Bartelmus (xmms at bartelmus.de)
+
+ some code was stolen from:
+ IRman plugin for xmms by Charles Sielski (stray at teklabs.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <stdlib.h>
+
+#include <glib.h>
+#include <lirc/lirc_client.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/hook.h>
+
+class LIRCPlugin : public GeneralPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("LIRC Plugin"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ constexpr LIRCPlugin () : GeneralPlugin (info, false) {}
+
+ bool init ();
+ void cleanup ();
+};
+
+EXPORT LIRCPlugin aud_plugin_instance;
+
+static gboolean lirc_input_callback (GIOChannel * source, GIOCondition condition, void * data);
+
+const char * const LIRCPlugin::defaults[] = {
+ "enable_reconnect", "TRUE",
+ "reconnect_timeout", "5",
+ nullptr};
+
+int lirc_fd = -1;
+struct lirc_config *config = nullptr;
+int tracknr = 0;
+int mute = 0; /* mute flag */
+int mute_vol = 0; /* holds volume before mute */
+
+unsigned input_tag;
+
+char track_no[64];
+int track_no_pos;
+int tid;
+
+void init_lirc (void)
+{
+ int flags;
+
+ if ((lirc_fd = lirc_init ((char *) "audacious", 1)) == -1)
+ {
+ AUDERR ("could not init LIRC support\n");
+ return;
+ }
+ if (lirc_readconfig (nullptr, &config, nullptr) == -1)
+ {
+ lirc_deinit ();
+ AUDERR ("could not read LIRC config file\n");
+ return;
+ }
+
+ input_tag =
+ g_io_add_watch (g_io_channel_unix_new (lirc_fd), G_IO_IN,
+ lirc_input_callback, nullptr);
+
+ fcntl (lirc_fd, F_SETOWN, getpid ());
+ flags = fcntl (lirc_fd, F_GETFL, 0);
+ if (flags != -1)
+ {
+ fcntl (lirc_fd, F_SETFL, flags | O_NONBLOCK);
+ }
+}
+
+bool LIRCPlugin::init ()
+{
+ aud_config_set_defaults ("lirc", defaults);
+ init_lirc ();
+ track_no_pos = 0;
+ tid = 0;
+ return true;
+}
+
+gboolean reconnect_lirc (void * data)
+{
+ AUDERR ("trying to reconnect...\n");
+ aud_plugin_instance.init ();
+ return (lirc_fd == -1);
+}
+
+void LIRCPlugin::cleanup ()
+{
+ if (config)
+ {
+ if (input_tag)
+ g_source_remove (input_tag);
+
+ config = nullptr;
+ }
+ if (lirc_fd != -1)
+ {
+ lirc_deinit ();
+ lirc_fd = -1;
+ }
+}
+
+gboolean jump_to (void * data)
+{
+ int playlist = aud_playlist_get_active ();
+ aud_playlist_set_position (playlist, atoi (track_no) - 1);
+ track_no_pos = 0;
+ tid = 0;
+ return false;
+}
+
+static gboolean lirc_input_callback (GIOChannel * source, GIOCondition condition, void * data)
+{
+ char *code;
+ char *c;
+ int output_time, v;
+ int ret;
+ char *ptr;
+ int balance;
+#if 0
+ gboolean show_pl;
+#endif
+ int n;
+ char *utf8_title_markup;
+
+ while ((ret = lirc_nextcode (&code)) == 0 && code != nullptr)
+ {
+ while ((ret = lirc_code2char (config, code, &c)) == 0 && c != nullptr)
+ {
+ if (g_ascii_strcasecmp ("PLAY", c) == 0)
+ aud_drct_play ();
+ else if (g_ascii_strcasecmp ("STOP", c) == 0)
+ aud_drct_stop ();
+ else if (g_ascii_strcasecmp ("PAUSE", c) == 0)
+ aud_drct_pause ();
+ else if (g_ascii_strcasecmp ("PLAYPAUSE", c) == 0)
+ aud_drct_play_pause ();
+ else if (g_ascii_strncasecmp ("NEXT", c, 4) == 0)
+ {
+ ptr = c + 4;
+ while (g_ascii_isspace (*ptr))
+ ptr++;
+ n = atoi (ptr);
+
+ if (n <= 0)
+ n = 1;
+ for (; n > 0; n--)
+ {
+ aud_drct_pl_next ();
+ }
+ }
+ else if (g_ascii_strncasecmp ("PREV", c, 4) == 0)
+ {
+ ptr = c + 4;
+ while (g_ascii_isspace (*ptr))
+ ptr++;
+ n = atoi (ptr);
+
+ if (n <= 0)
+ n = 1;
+ for (; n > 0; n--)
+ {
+ aud_drct_pl_prev ();
+ }
+ }
+ else if (g_ascii_strcasecmp ("SHUFFLE", c) == 0)
+ aud_set_bool (nullptr, "shuffle", ! aud_get_bool (nullptr, "shuffle"));
+ else if (g_ascii_strcasecmp ("REPEAT", c) == 0)
+ aud_set_bool (nullptr, "repeat", ! aud_get_bool (nullptr, "repeat"));
+ else if (g_ascii_strncasecmp ("FWD", c, 3) == 0)
+ {
+ ptr = c + 3;
+ while (g_ascii_isspace (*ptr))
+ ptr++;
+ n = atoi (ptr) * 1000;
+
+ if (n <= 0)
+ n = 5000;
+ output_time = aud_drct_get_time ();
+ aud_drct_seek (output_time + n);
+ }
+ else if (g_ascii_strncasecmp ("BWD", c, 3) == 0)
+ {
+ ptr = c + 3;
+ while (g_ascii_isspace (*ptr))
+ ptr++;
+ n = atoi (ptr) * 1000;
+
+ if (n <= 0)
+ n = 5000;
+ output_time = aud_drct_get_time ();
+ aud_drct_seek (output_time - n);
+ }
+ else if (g_ascii_strncasecmp ("VOL_UP", c, 6) == 0)
+ {
+ ptr = c + 6;
+ while (g_ascii_isspace (*ptr))
+ ptr++;
+ n = atoi (ptr);
+ if (n <= 0)
+ n = 5;
+
+ v = aud_drct_get_volume_main ();
+ if (v > (100 - n))
+ v = 100 - n;
+ aud_drct_set_volume_main (v + n);
+ }
+ else if (g_ascii_strncasecmp ("VOL_DOWN", c, 8) == 0)
+ {
+ ptr = c + 8;
+ while (g_ascii_isspace (*ptr))
+ ptr++;
+ n = atoi (ptr);
+ if (n <= 0)
+ n = 5;
+
+ v = aud_drct_get_volume_main ();
+ if (v < n)
+ v = n;
+ aud_drct_set_volume_main (v - n);
+ }
+ else if (g_ascii_strcasecmp ("QUIT", c) == 0)
+ {
+ aud_quit ();
+ }
+ else if (g_ascii_strcasecmp ("MUTE", c) == 0)
+ {
+ if (mute == 0)
+ {
+ mute = 1;
+ /* store the master volume so
+ we can restore it on unmute. */
+ mute_vol = aud_drct_get_volume_main ();
+ aud_drct_set_volume_main (0);
+ }
+ else
+ {
+ mute = 0;
+ aud_drct_set_volume_main (mute_vol);
+ }
+ }
+ else if (g_ascii_strncasecmp ("BAL_LEFT", c, 8) == 0)
+ {
+ ptr = c + 8;
+ while (g_ascii_isspace (*ptr))
+ ptr++;
+ n = atoi (ptr);
+ if (n <= 0)
+ n = 5;
+
+ balance = aud_drct_get_volume_balance ();
+ balance -= n;
+ if (balance < -100)
+ balance = -100;
+ aud_drct_set_volume_balance (balance);
+ }
+ else if (g_ascii_strncasecmp ("BAL_RIGHT", c, 9) == 0)
+ {
+ ptr = c + 9;
+ while (g_ascii_isspace (*ptr))
+ ptr++;
+ n = atoi (ptr);
+ if (n <= 0)
+ n = 5;
+
+ balance = aud_drct_get_volume_balance ();
+ balance += n;
+ if (balance > 100)
+ balance = 100;
+ aud_drct_set_volume_balance (balance);
+ }
+ else if (g_ascii_strcasecmp ("BAL_CENTER", c) == 0)
+ {
+ balance = 0;
+ aud_drct_set_volume_balance (balance);
+ }
+ else if (g_ascii_strcasecmp ("LIST", c) == 0)
+ {
+#if 0
+ show_pl = aud_drct_pl_win_is_visible ();
+ show_pl = (show_pl) ? 0 : 1;
+ aud_drct_pl_win_toggle (show_pl);
+#endif
+ }
+ else if (g_ascii_strcasecmp ("PLAYLIST_CLEAR", c) == 0)
+ {
+ aud_drct_stop ();
+ int playlist = aud_playlist_get_active ();
+ aud_playlist_entry_delete (playlist, 0,
+ aud_playlist_entry_count
+ (playlist));
+ }
+ else if (g_ascii_strncasecmp ("PLAYLIST_ADD ", c, 13) == 0)
+ {
+ aud_drct_pl_add (c + 13, -1);
+ }
+ else if ((strlen (c) == 1) && ((*c >= '0') || (*c <= '9')))
+ {
+ if (track_no_pos < 63)
+ {
+ if (tid)
+ g_source_remove (tid);
+ track_no[track_no_pos++] = *c;
+ track_no[track_no_pos] = 0;
+ tid = g_timeout_add (1500, jump_to, nullptr);
+ utf8_title_markup = g_markup_printf_escaped ("%s", track_no);
+ hook_call ("aosd toggle", utf8_title_markup);
+ }
+ }
+ else
+ {
+ AUDERR ("unknown command \"%s\"\n", c);
+ }
+ }
+ g_free (code);
+ if (ret == -1)
+ break;
+ }
+ if (ret == -1)
+ {
+ /* something went badly wrong */
+ AUDERR ("disconnected from LIRC\n");
+ aud_plugin_instance.cleanup ();
+ if (aud_get_bool ("lirc", "enable_reconnect"))
+ {
+ int reconnect_timeout = aud_get_int ("lirc", "reconnect_timeout");
+ AUDERR ("will try reconnect every %d seconds...\n", reconnect_timeout);
+ g_timeout_add (1000 * reconnect_timeout, reconnect_lirc, nullptr);
+ }
+ }
+
+ return true;
+}
+
+const char LIRCPlugin::about[] =
+ N_("A simple plugin to control Audacious using the LIRC remote control daemon\n\n"
+ "Adapted for Audacious by:\n"
+ "Tony Vroon <chainsaw at gentoo.org>\n"
+ "Joonas Harjumäki <jharjuma at gmail.com>\n\n"
+ "Based on the XMMS LIRC plugin by:\n"
+ "Carl van Schaik <carl at leg.uct.ac.za>\n"
+ "Christoph Bartelmus <xmms at bartelmus.de>\n"
+ "Andrew O. Shadoura <bugzilla at tut.by>\n\n"
+ "For more information about LIRC, see http://lirc.org.");
+
+const PreferencesWidget LIRCPlugin::widgets[] = {
+ WidgetLabel (N_("<b>Connection</b>")),
+ WidgetCheck (N_("Reconnect to LIRC server"),
+ WidgetBool ("lirc", "enable_reconnect")),
+ WidgetSpin (N_("Wait before reconnecting:"),
+ WidgetInt ("lirc", "reconnect_timeout"),
+ {1, 120, 1, N_("seconds")},
+ WIDGET_CHILD)
+};
+
+const PluginPreferences LIRCPlugin::prefs = {{widgets}};
diff --git a/src/lyricwiki-qt/Makefile b/src/lyricwiki-qt/Makefile
new file mode 100644
index 000000000000..a17bc66d7497
--- /dev/null
+++ b/src/lyricwiki-qt/Makefile
@@ -0,0 +1,14 @@
+PLUGIN = lyricwiki-qt${PLUGIN_SUFFIX}
+
+SRCS = lyricwiki.cc
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+
+LD = ${CXX}
+
+CFLAGS += ${PLUGIN_CFLAGS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${QT_CFLAGS} ${GLIB_CFLAGS} ${XML_CFLAGS} -I../..
+LIBS += ${QT_LIBS} ${GLIB_LIBS} ${XML_LIBS}
diff --git a/src/lyricwiki-qt/lyricwiki.cc b/src/lyricwiki-qt/lyricwiki.cc
new file mode 100644
index 000000000000..371909745f3d
--- /dev/null
+++ b/src/lyricwiki-qt/lyricwiki.cc
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2010, 2014 William Pitcock <nenolod at dereferenced.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+#include <string.h>
+
+#include <QTextCursor>
+#include <QTextDocument>
+#include <QTextEdit>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/xpath.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/plugins.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/vfs_async.h>
+#include <libaudcore/runtime.h>
+
+#include <libaudqt/libaudqt.h>
+
+typedef struct {
+ String filename; /* of song file */
+ String title, artist;
+ String uri; /* URI we are trying to retrieve */
+} LyricsState;
+
+static LyricsState state;
+
+class LyricWikiQt : public GeneralPlugin {
+public:
+ static constexpr PluginInfo info = {
+ N_("LyricWiki Plugin (Qt)"),
+ PACKAGE
+ };
+
+ constexpr LyricWikiQt() : GeneralPlugin (info, false) {}
+ void * get_qt_widget ();
+};
+
+EXPORT LyricWikiQt aud_plugin_instance;
+
+/*
+ * Suppress libxml warnings, because lyricwiki does not generate anything near
+ * valid HTML.
+ */
+static void libxml_error_handler(void *ctx, const char *msg, ...)
+{
+}
+
+/* g_free() returned text */
+static char *scrape_lyrics_from_lyricwiki_edit_page(const char *buf, int64_t len)
+{
+ xmlDocPtr doc;
+ char *ret = nullptr;
+
+ /*
+ * temporarily set our error-handling functor to our suppression function,
+ * but we have to set it back because other components of Audacious depend
+ * on libxml and we don't want to step on their code paths.
+ *
+ * unfortunately, libxml is anti-social and provides us with no way to get
+ * the previous error functor, so we just have to set it back to default after
+ * parsing and hope for the best.
+ */
+ xmlSetGenericErrorFunc(nullptr, libxml_error_handler);
+ doc = htmlReadMemory(buf, (int) len, nullptr, "utf-8", (HTML_PARSE_RECOVER | HTML_PARSE_NONET));
+ xmlSetGenericErrorFunc(nullptr, nullptr);
+
+ if (doc != nullptr)
+ {
+ xmlXPathContextPtr xpath_ctx = nullptr;
+ xmlXPathObjectPtr xpath_obj = nullptr;
+ xmlNodePtr node = nullptr;
+
+ xpath_ctx = xmlXPathNewContext(doc);
+ if (xpath_ctx == nullptr)
+ goto give_up;
+
+ xpath_obj = xmlXPathEvalExpression((xmlChar *) "//*[@id=\"wpTextbox1\"]", xpath_ctx);
+ if (xpath_obj == nullptr)
+ goto give_up;
+
+ if (!xpath_obj->nodesetval->nodeMax)
+ goto give_up;
+
+ node = xpath_obj->nodesetval->nodeTab[0];
+give_up:
+ if (xpath_obj != nullptr)
+ xmlXPathFreeObject(xpath_obj);
+
+ if (xpath_ctx != nullptr)
+ xmlXPathFreeContext(xpath_ctx);
+
+ if (node != nullptr)
+ {
+ xmlChar *lyric = xmlNodeGetContent(node);
+
+ if (lyric != nullptr)
+ {
+ GMatchInfo *match_info;
+ GRegex *reg;
+
+ reg = g_regex_new
+ ("<(lyrics?)>[[:space:]]*(.*?)[[:space:]]*</\\1>",
+ (GRegexCompileFlags) (G_REGEX_MULTILINE | G_REGEX_DOTALL),
+ (GRegexMatchFlags) 0, nullptr);
+ g_regex_match(reg, (char *) lyric, G_REGEX_MATCH_NEWLINE_ANY, &match_info);
+
+ ret = g_match_info_fetch(match_info, 2);
+ if (!g_utf8_collate(ret, "<!-- PUT LYRICS HERE (and delete this entire line) -->"))
+ {
+ g_free(ret);
+ ret = g_strdup(_("No lyrics available"));
+ }
+
+ g_regex_unref(reg);
+ }
+
+ xmlFree(lyric);
+ }
+
+ xmlFreeDoc(doc);
+ }
+
+ return ret;
+}
+
+static String scrape_uri_from_lyricwiki_search_result(const char *buf, int64_t len)
+{
+ xmlDocPtr doc;
+ String uri;
+
+ /*
+ * workaround buggy lyricwiki search output where it cuts the lyrics
+ * halfway through the UTF-8 symbol resulting in invalid XML.
+ */
+ GRegex *reg;
+
+ reg = g_regex_new ("<(lyrics?)>.*</\\1>", (GRegexCompileFlags)
+ (G_REGEX_MULTILINE | G_REGEX_DOTALL | G_REGEX_UNGREEDY),
+ (GRegexMatchFlags) 0, nullptr);
+ char *newbuf = g_regex_replace_literal(reg, buf, len, 0, "", G_REGEX_MATCH_NEWLINE_ANY, nullptr);
+ g_regex_unref(reg);
+
+ /*
+ * temporarily set our error-handling functor to our suppression function,
+ * but we have to set it back because other components of Audacious depend
+ * on libxml and we don't want to step on their code paths.
+ *
+ * unfortunately, libxml is anti-social and provides us with no way to get
+ * the previous error functor, so we just have to set it back to default after
+ * parsing and hope for the best.
+ */
+ xmlSetGenericErrorFunc(nullptr, libxml_error_handler);
+ doc = xmlParseMemory(newbuf, strlen(newbuf));
+ xmlSetGenericErrorFunc(nullptr, nullptr);
+
+ if (doc != nullptr)
+ {
+ xmlNodePtr root, cur;
+
+ root = xmlDocGetRootElement(doc);
+
+ for (cur = root->xmlChildrenNode; cur; cur = cur->next)
+ {
+ if (xmlStrEqual(cur->name, (xmlChar *) "url"))
+ {
+ xmlChar *lyric;
+ char *basename;
+
+ lyric = xmlNodeGetContent(cur);
+ basename = g_path_get_basename((char *) lyric);
+
+ uri = String (str_printf ("http://lyrics.wikia.com/index.php?"
+ "action=edit&title=%s", basename));
+
+ g_free(basename);
+ xmlFree(lyric);
+ }
+ }
+
+ xmlFreeDoc(doc);
+ }
+
+ g_free(newbuf);
+
+ return uri;
+}
+
+static void update_lyrics_window(const char *title, const char *artist, const char *lyrics);
+
+static void get_lyrics_step_3(const char *uri, const Index<char> &buf, void*)
+{
+ if (!state.uri || strcmp(state.uri, uri))
+ return;
+
+ if (!buf.len())
+ {
+ update_lyrics_window (_("Error"), nullptr,
+ str_printf (_("Unable to fetch %s"), uri));
+ return;
+ }
+
+ char *lyrics = scrape_lyrics_from_lyricwiki_edit_page(buf.begin(), buf.len());
+
+ if (!lyrics)
+ {
+ update_lyrics_window (_("Error"), nullptr,
+ str_printf (_("Unable to parse %s"), uri));
+ return;
+ }
+
+ update_lyrics_window(state.title, state.artist, lyrics);
+
+ g_free(lyrics);
+}
+
+static void get_lyrics_step_2(const char *uri1, const Index<char> &buf, void*)
+{
+ if (!state.uri || strcmp(state.uri, uri1))
+ return;
+
+ if (!buf.len())
+ {
+ update_lyrics_window (_("Error"), nullptr,
+ str_printf (_("Unable to fetch %s"), uri1));
+ return;
+ }
+
+ String uri = scrape_uri_from_lyricwiki_search_result(buf.begin(), buf.len());
+
+ if (!uri)
+ {
+ update_lyrics_window (_("Error"), nullptr,
+ str_printf (_("Unable to parse %s"), uri1));
+ return;
+ }
+
+ state.uri = uri;
+
+ update_lyrics_window(state.title, state.artist, _("Looking for lyrics ..."));
+ vfs_async_file_get_contents(uri, get_lyrics_step_3, nullptr);
+}
+
+static void get_lyrics_step_1(void)
+{
+ if(!state.artist || !state.title)
+ {
+ update_lyrics_window(_("Error"), nullptr, _("Missing song metadata"));
+ return;
+ }
+
+ StringBuf title_buf = str_encode_percent (state.title);
+ StringBuf artist_buf = str_encode_percent (state.artist);
+
+ state.uri = String (str_printf ("http://lyrics.wikia.com/api.php?"
+ "action=lyrics&artist=%s&song=%s&fmt=xml", (const char *) artist_buf,
+ (const char *) title_buf));
+
+ update_lyrics_window(state.title, state.artist, _("Connecting to lyrics.wikia.com ..."));
+ vfs_async_file_get_contents(state.uri, get_lyrics_step_2, nullptr);
+}
+
+static QTextEdit * textedit;
+
+static void update_lyrics_window(const char *title, const char *artist, const char *lyrics)
+{
+ QTextDocument doc;
+ QTextCursor cursor (& doc);
+
+ if (! textedit)
+ return;
+
+ cursor.insertHtml (QString ("<big>") + QString (title) + QString ("</big>"));
+
+ if (artist != nullptr)
+ {
+ cursor.insertHtml (QString ("<br><i>") + QString (artist) + QString ("</i>"));
+ }
+
+ cursor.insertHtml ("<br>");
+ cursor.insertText (lyrics);
+
+ AUDDBG ("update document <%p>\n", textedit);
+
+ textedit->setDocument (doc.clone ());
+}
+
+static void lyricwiki_playback_began(void)
+{
+ /* FIXME: cancel previous VFS requests (not possible with current API) */
+
+ state.filename = aud_drct_get_filename();
+
+ Tuple tuple = aud_drct_get_tuple();
+ state.title = tuple.get_str(Tuple::Title);
+ state.artist = tuple.get_str(Tuple::Artist);
+
+ state.uri = String ();
+
+ get_lyrics_step_1();
+}
+
+static void lw_cleanup (QObject * object = nullptr)
+{
+ state.filename = String ();
+ state.title = String ();
+ state.artist = String ();
+ state.uri = String ();
+
+ hook_dissociate ("tuple change", (HookFunction) lyricwiki_playback_began);
+ hook_dissociate ("playback ready", (HookFunction) lyricwiki_playback_began);
+
+ textedit = nullptr;
+}
+
+void * LyricWikiQt::get_qt_widget ()
+{
+ textedit = new QTextEdit;
+ textedit->setReadOnly (true);
+
+ hook_associate ("tuple change", (HookFunction) lyricwiki_playback_began, nullptr);
+ hook_associate ("playback ready", (HookFunction) lyricwiki_playback_began, nullptr);
+
+ if (aud_drct_get_ready ())
+ lyricwiki_playback_began ();
+
+ QObject::connect (textedit, &QObject::destroyed, lw_cleanup);
+
+ return textedit;
+}
diff --git a/src/lyricwiki/Makefile b/src/lyricwiki/Makefile
index 91cc27bd1efe..fe1381a93458 100644
--- a/src/lyricwiki/Makefile
+++ b/src/lyricwiki/Makefile
@@ -1,12 +1,14 @@
PLUGIN = lyricwiki${PLUGIN_SUFFIX}
-SRCS = lyricwiki.c
+SRCS = lyricwiki.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} ${XML_CFLAGS} -I../..
LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${XML_LIBS}
diff --git a/src/lyricwiki/lyricwiki.c b/src/lyricwiki/lyricwiki.c
deleted file mode 100644
index 0095b16ed941..000000000000
--- a/src/lyricwiki/lyricwiki.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (c) 2010 William Pitcock <nenolod at dereferenced.org>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <glib.h>
-#include <string.h>
-#include <gtk/gtk.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/HTMLparser.h>
-#include <libxml/xpath.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <audacious/plugin.h>
-#include <audacious/plugins.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudcore/vfs_async.h>
-
-/* all strings in this struct are pooled */
-typedef struct {
- char *filename; /* of song file */
- char *title, *artist;
- char *uri; /* URI we are trying to retrieve */
-} LyricsState;
-
-static LyricsState state;
-
-/*
- * Suppress libxml warnings, because lyricwiki does not generate anything near
- * valid HTML.
- */
-static void libxml_error_handler(void *ctx, const char *msg, ...)
-{
-}
-
-/* g_free() returned text */
-static char *scrape_lyrics_from_lyricwiki_edit_page(const char *buf, int64_t len)
-{
- xmlDocPtr doc;
- gchar *ret = NULL;
-
- /*
- * temporarily set our error-handling functor to our suppression function,
- * but we have to set it back because other components of Audacious depend
- * on libxml and we don't want to step on their code paths.
- *
- * unfortunately, libxml is anti-social and provides us with no way to get
- * the previous error functor, so we just have to set it back to default after
- * parsing and hope for the best.
- */
- xmlSetGenericErrorFunc(NULL, libxml_error_handler);
- doc = htmlReadMemory(buf, (int) len, NULL, "utf-8", (HTML_PARSE_RECOVER | HTML_PARSE_NONET));
- xmlSetGenericErrorFunc(NULL, NULL);
-
- if (doc != NULL)
- {
- xmlXPathContextPtr xpath_ctx = NULL;
- xmlXPathObjectPtr xpath_obj = NULL;
- xmlNodePtr node = NULL;
-
- xpath_ctx = xmlXPathNewContext(doc);
- if (xpath_ctx == NULL)
- goto give_up;
-
- xpath_obj = xmlXPathEvalExpression((xmlChar *) "//*[@id=\"wpTextbox1\"]", xpath_ctx);
- if (xpath_obj == NULL)
- goto give_up;
-
- if (!xpath_obj->nodesetval->nodeMax)
- goto give_up;
-
- node = xpath_obj->nodesetval->nodeTab[0];
-give_up:
- if (xpath_obj != NULL)
- xmlXPathFreeObject(xpath_obj);
-
- if (xpath_ctx != NULL)
- xmlXPathFreeContext(xpath_ctx);
-
- if (node != NULL)
- {
- xmlChar *lyric = xmlNodeGetContent(node);
-
- if (lyric != NULL)
- {
- GMatchInfo *match_info;
- GRegex *reg;
-
- reg = g_regex_new("<(lyrics?)>[[:space:]]*(.*?)[[:space:]]*</\\1>", (G_REGEX_MULTILINE | G_REGEX_DOTALL), 0, NULL);
- g_regex_match(reg, (gchar *) lyric, G_REGEX_MATCH_NEWLINE_ANY, &match_info);
-
- ret = g_match_info_fetch(match_info, 2);
- if (!g_utf8_collate(ret, "<!-- PUT LYRICS HERE (and delete this entire line) -->"))
- {
- g_free(ret);
- ret = g_strdup(_("No lyrics available"));
- }
-
- g_regex_unref(reg);
- }
-
- xmlFree(lyric);
- }
-
- xmlFreeDoc(doc);
- }
-
- return ret;
-}
-
-/* str_unref() returned string */
-static char *scrape_uri_from_lyricwiki_search_result(const char *buf, int64_t len)
-{
- xmlDocPtr doc;
- gchar *uri = NULL;
-
- /*
- * workaround buggy lyricwiki search output where it cuts the lyrics
- * halfway through the UTF-8 symbol resulting in invalid XML.
- */
- GRegex *reg;
-
- reg = g_regex_new("<(lyrics?)>.*</\\1>", (G_REGEX_MULTILINE | G_REGEX_DOTALL | G_REGEX_UNGREEDY), 0, NULL);
- gchar *newbuf = g_regex_replace_literal(reg, buf, len, 0, "", G_REGEX_MATCH_NEWLINE_ANY, NULL);
- g_regex_unref(reg);
-
- /*
- * temporarily set our error-handling functor to our suppression function,
- * but we have to set it back because other components of Audacious depend
- * on libxml and we don't want to step on their code paths.
- *
- * unfortunately, libxml is anti-social and provides us with no way to get
- * the previous error functor, so we just have to set it back to default after
- * parsing and hope for the best.
- */
- xmlSetGenericErrorFunc(NULL, libxml_error_handler);
- doc = xmlParseMemory(newbuf, strlen(newbuf));
- xmlSetGenericErrorFunc(NULL, NULL);
-
- if (doc != NULL)
- {
- xmlNodePtr root, cur;
-
- root = xmlDocGetRootElement(doc);
-
- for (cur = root->xmlChildrenNode; cur; cur = cur->next)
- {
- if (xmlStrEqual(cur->name, (xmlChar *) "url"))
- {
- xmlChar *lyric;
- gchar *basename;
-
- lyric = xmlNodeGetContent(cur);
- basename = g_path_get_basename((gchar *) lyric);
-
- uri = str_printf("http://lyrics.wikia.com/index.php?action=edit"
- "&title=%s", basename);
-
- g_free(basename);
- xmlFree(lyric);
- }
- }
-
- xmlFreeDoc(doc);
- }
-
- g_free(newbuf);
-
- return uri;
-}
-
-static void update_lyrics_window(const char *title, const char *artist, const char *lyrics);
-
-static bool_t get_lyrics_step_3(void *buf, int64_t len, void *requri)
-{
- if (!state.uri || strcmp(state.uri, requri))
- {
- g_free(buf);
- str_unref(requri);
- return FALSE;
- }
- str_unref(requri);
-
- if(!len)
- {
- SPRINTF(error, _("Unable to fetch %s"), state.uri);
- update_lyrics_window(_("Error"), NULL, error);
- g_free(buf);
- return FALSE;
- }
-
- char *lyrics = scrape_lyrics_from_lyricwiki_edit_page(buf, len);
-
- if(!lyrics)
- {
- SPRINTF(error, _("Unable to parse %s"), state.uri);
- update_lyrics_window(_("Error"), NULL, error);
- g_free(buf);
- return FALSE;
- }
-
- update_lyrics_window(state.title, state.artist, lyrics);
-
- g_free(lyrics);
- return TRUE;
-}
-
-static bool_t get_lyrics_step_2(void *buf, int64_t len, void *requri)
-{
- if (strcmp(state.uri, requri))
- {
- g_free(buf);
- str_unref(requri);
- return FALSE;
- }
- str_unref(requri);
-
- if(!len)
- {
- SPRINTF(error, _("Unable to fetch %s"), state.uri);
- update_lyrics_window(_("Error"), NULL, error);
- g_free(buf);
- return FALSE;
- }
-
- char *uri = scrape_uri_from_lyricwiki_search_result(buf, len);
-
- if(!uri)
- {
- SPRINTF(error, _("Unable to parse %s"), state.uri);
- update_lyrics_window(_("Error"), NULL, error);
- g_free(buf);
- return FALSE;
- }
-
- str_unref(state.uri);
- state.uri = uri;
-
- update_lyrics_window(state.title, state.artist, _("Looking for lyrics ..."));
- vfs_async_file_get_contents(uri, get_lyrics_step_3, str_ref(state.uri));
-
- g_free(buf);
- return TRUE;
-}
-
-static void get_lyrics_step_1(void)
-{
- if(!state.artist || !state.title)
- {
- update_lyrics_window(_("Error"), NULL, _("Missing song metadata"));
- return;
- }
-
- char title_buf[strlen(state.title) * 3 + 1];
- char artist_buf[strlen(state.artist) * 3 + 1];
- str_encode_percent(state.title, -1, title_buf);
- str_encode_percent(state.artist, -1, artist_buf);
-
- str_unref(state.uri);
- state.uri = str_printf("http://lyrics.wikia.com/api.php?action=lyrics&"
- "artist=%s&song=%s&fmt=xml", artist_buf, title_buf);
-
- update_lyrics_window(state.title, state.artist, _("Connecting to lyrics.wikia.com ..."));
- vfs_async_file_get_contents(state.uri, get_lyrics_step_2, str_ref(state.uri));
-}
-
-static GtkWidget *scrollview, *vbox;
-static GtkWidget *textview;
-static GtkTextBuffer *textbuffer;
-
-static GtkWidget *build_widget(void)
-{
- textview = gtk_text_view_new();
- gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE);
- gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview), FALSE);
- gtk_text_view_set_left_margin(GTK_TEXT_VIEW(textview), 4);
- gtk_text_view_set_right_margin(GTK_TEXT_VIEW(textview), 4);
- gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD);
- textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
-
- scrollview = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollview), GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollview), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
-
- gtk_container_add(GTK_CONTAINER(scrollview), textview);
-
- gtk_box_pack_start(GTK_BOX(vbox), scrollview, TRUE, TRUE, 0);
-
- gtk_widget_show(textview);
- gtk_widget_show(scrollview);
- gtk_widget_show(vbox);
-
- gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(textbuffer), "weight_bold", "weight", PANGO_WEIGHT_BOLD, NULL);
- gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(textbuffer), "size_x_large", "scale", PANGO_SCALE_X_LARGE, NULL);
- gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(textbuffer), "style_italic", "style", PANGO_STYLE_ITALIC, NULL);
-
- g_signal_connect (vbox, "destroy", (GCallback) gtk_widget_destroyed, & vbox);
- return vbox;
-}
-
-static void update_lyrics_window(const char *title, const char *artist, const char *lyrics)
-{
- GtkTextIter iter;
-
- if (textbuffer == NULL)
- return;
-
- gtk_text_buffer_set_text(GTK_TEXT_BUFFER(textbuffer), "", -1);
-
- gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(textbuffer), &iter);
-
- gtk_text_buffer_insert_with_tags_by_name(GTK_TEXT_BUFFER(textbuffer), &iter,
- title, -1, "weight_bold", "size_x_large", NULL);
-
- if (artist != NULL)
- {
- gtk_text_buffer_insert(GTK_TEXT_BUFFER(textbuffer), &iter, "\n", -1);
- gtk_text_buffer_insert_with_tags_by_name(GTK_TEXT_BUFFER(textbuffer),
- &iter, artist, -1, "style_italic", NULL);
- }
-
- gtk_text_buffer_insert(GTK_TEXT_BUFFER(textbuffer), &iter, "\n\n", -1);
- gtk_text_buffer_insert(GTK_TEXT_BUFFER(textbuffer), &iter, lyrics, -1);
-
- gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(textbuffer), &iter);
- gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(textview), &iter, 0, TRUE, 0, 0);
-}
-
-static void lyricwiki_playback_began(void)
-{
- if (!aud_drct_get_playing())
- return;
-
- /* FIXME: cancel previous VFS requests (not possible with current API) */
- str_unref(state.filename);
- str_unref(state.title);
- str_unref(state.artist);
- str_unref(state.uri);
-
- int playlist = aud_playlist_get_playing();
- int pos = aud_playlist_get_position(playlist);
-
- state.filename = aud_playlist_entry_get_filename(playlist, pos);
- aud_playlist_entry_describe(playlist, pos, &state.title, &state.artist, NULL, FALSE);
- state.uri = NULL;
-
- get_lyrics_step_1();
-}
-
-static gboolean init (void)
-{
- hook_associate("title change", (HookFunction) lyricwiki_playback_began, NULL);
- hook_associate("playback ready", (HookFunction) lyricwiki_playback_began, NULL);
-
- build_widget();
-
- lyricwiki_playback_began();
- return TRUE;
-}
-
-static void cleanup(void)
-{
- str_unref(state.filename);
- str_unref(state.title);
- str_unref(state.artist);
- str_unref(state.uri);
- state.filename = NULL;
- state.title = NULL;
- state.artist = NULL;
- state.uri = NULL;
-
- hook_dissociate("title change", (HookFunction) lyricwiki_playback_began);
- hook_dissociate("playback ready", (HookFunction) lyricwiki_playback_began);
-
- if (vbox)
- gtk_widget_destroy (vbox);
- textbuffer = NULL;
-}
-
-static void *get_widget(void)
-{
- if (! vbox)
- build_widget ();
- return vbox;
-}
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("LyricWiki Plugin"),
- .domain = PACKAGE,
- .init = init,
- .cleanup = cleanup,
- .get_widget = get_widget,
-)
diff --git a/src/lyricwiki/lyricwiki.cc b/src/lyricwiki/lyricwiki.cc
new file mode 100644
index 000000000000..ca7f9f83545a
--- /dev/null
+++ b/src/lyricwiki/lyricwiki.cc
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2010 William Pitcock <nenolod at dereferenced.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/xpath.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/plugins.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/vfs_async.h>
+
+class LyricWiki : public GeneralPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("LyricWiki Plugin"),
+ PACKAGE
+ };
+
+ constexpr LyricWiki () : GeneralPlugin (info, false) {}
+
+ void * get_gtk_widget ();
+};
+
+EXPORT LyricWiki aud_plugin_instance;
+
+typedef struct {
+ String filename; /* of song file */
+ String title, artist;
+ String uri; /* URI we are trying to retrieve */
+} LyricsState;
+
+static LyricsState state;
+
+/*
+ * Suppress libxml warnings, because lyricwiki does not generate anything near
+ * valid HTML.
+ */
+static void libxml_error_handler(void *ctx, const char *msg, ...)
+{
+}
+
+/* g_free() returned text */
+static char *scrape_lyrics_from_lyricwiki_edit_page(const char *buf, int64_t len)
+{
+ xmlDocPtr doc;
+ char *ret = nullptr;
+
+ /*
+ * temporarily set our error-handling functor to our suppression function,
+ * but we have to set it back because other components of Audacious depend
+ * on libxml and we don't want to step on their code paths.
+ *
+ * unfortunately, libxml is anti-social and provides us with no way to get
+ * the previous error functor, so we just have to set it back to default after
+ * parsing and hope for the best.
+ */
+ xmlSetGenericErrorFunc(nullptr, libxml_error_handler);
+ doc = htmlReadMemory(buf, (int) len, nullptr, "utf-8", (HTML_PARSE_RECOVER | HTML_PARSE_NONET));
+ xmlSetGenericErrorFunc(nullptr, nullptr);
+
+ if (doc != nullptr)
+ {
+ xmlXPathContextPtr xpath_ctx = nullptr;
+ xmlXPathObjectPtr xpath_obj = nullptr;
+ xmlNodePtr node = nullptr;
+
+ xpath_ctx = xmlXPathNewContext(doc);
+ if (xpath_ctx == nullptr)
+ goto give_up;
+
+ xpath_obj = xmlXPathEvalExpression((xmlChar *) "//*[@id=\"wpTextbox1\"]", xpath_ctx);
+ if (xpath_obj == nullptr)
+ goto give_up;
+
+ if (!xpath_obj->nodesetval->nodeMax)
+ goto give_up;
+
+ node = xpath_obj->nodesetval->nodeTab[0];
+give_up:
+ if (xpath_obj != nullptr)
+ xmlXPathFreeObject(xpath_obj);
+
+ if (xpath_ctx != nullptr)
+ xmlXPathFreeContext(xpath_ctx);
+
+ if (node != nullptr)
+ {
+ xmlChar *lyric = xmlNodeGetContent(node);
+
+ if (lyric != nullptr)
+ {
+ GMatchInfo *match_info;
+ GRegex *reg;
+
+ reg = g_regex_new
+ ("<(lyrics?)>[[:space:]]*(.*?)[[:space:]]*</\\1>",
+ (GRegexCompileFlags) (G_REGEX_MULTILINE | G_REGEX_DOTALL),
+ (GRegexMatchFlags) 0, nullptr);
+ g_regex_match(reg, (char *) lyric, G_REGEX_MATCH_NEWLINE_ANY, &match_info);
+
+ ret = g_match_info_fetch(match_info, 2);
+ if (!g_utf8_collate(ret, "<!-- PUT LYRICS HERE (and delete this entire line) -->"))
+ {
+ g_free(ret);
+ ret = g_strdup(_("No lyrics available"));
+ }
+
+ g_regex_unref(reg);
+ }
+
+ xmlFree(lyric);
+ }
+
+ xmlFreeDoc(doc);
+ }
+
+ return ret;
+}
+
+static String scrape_uri_from_lyricwiki_search_result(const char *buf, int64_t len)
+{
+ xmlDocPtr doc;
+ String uri;
+
+ /*
+ * workaround buggy lyricwiki search output where it cuts the lyrics
+ * halfway through the UTF-8 symbol resulting in invalid XML.
+ */
+ GRegex *reg;
+
+ reg = g_regex_new ("<(lyrics?)>.*</\\1>", (GRegexCompileFlags)
+ (G_REGEX_MULTILINE | G_REGEX_DOTALL | G_REGEX_UNGREEDY),
+ (GRegexMatchFlags) 0, nullptr);
+ char *newbuf = g_regex_replace_literal(reg, buf, len, 0, "", G_REGEX_MATCH_NEWLINE_ANY, nullptr);
+ g_regex_unref(reg);
+
+ /*
+ * temporarily set our error-handling functor to our suppression function,
+ * but we have to set it back because other components of Audacious depend
+ * on libxml and we don't want to step on their code paths.
+ *
+ * unfortunately, libxml is anti-social and provides us with no way to get
+ * the previous error functor, so we just have to set it back to default after
+ * parsing and hope for the best.
+ */
+ xmlSetGenericErrorFunc(nullptr, libxml_error_handler);
+ doc = xmlParseMemory(newbuf, strlen(newbuf));
+ xmlSetGenericErrorFunc(nullptr, nullptr);
+
+ if (doc != nullptr)
+ {
+ xmlNodePtr root, cur;
+
+ root = xmlDocGetRootElement(doc);
+
+ for (cur = root->xmlChildrenNode; cur; cur = cur->next)
+ {
+ if (xmlStrEqual(cur->name, (xmlChar *) "url"))
+ {
+ xmlChar *lyric;
+ char *basename;
+
+ lyric = xmlNodeGetContent(cur);
+ basename = g_path_get_basename((char *) lyric);
+
+ uri = String (str_printf ("http://lyrics.wikia.com/index.php?"
+ "action=edit&title=%s", basename));
+
+ g_free(basename);
+ xmlFree(lyric);
+ }
+ }
+
+ xmlFreeDoc(doc);
+ }
+
+ g_free(newbuf);
+
+ return uri;
+}
+
+static void update_lyrics_window(const char *title, const char *artist, const char *lyrics);
+
+static void get_lyrics_step_3(const char *uri, const Index<char> &buf, void*)
+{
+ if (!state.uri || strcmp(state.uri, uri))
+ return;
+
+ if (!buf.len())
+ {
+ update_lyrics_window (_("Error"), nullptr,
+ str_printf (_("Unable to fetch %s"), uri));
+ return;
+ }
+
+ char *lyrics = scrape_lyrics_from_lyricwiki_edit_page(buf.begin(), buf.len());
+
+ if (!lyrics)
+ {
+ update_lyrics_window (_("Error"), nullptr,
+ str_printf (_("Unable to parse %s"), uri));
+ return;
+ }
+
+ update_lyrics_window(state.title, state.artist, lyrics);
+
+ g_free(lyrics);
+}
+
+static void get_lyrics_step_2(const char *uri1, const Index<char> &buf, void*)
+{
+ if (!state.uri || strcmp(state.uri, uri1))
+ return;
+
+ if (!buf.len())
+ {
+ update_lyrics_window (_("Error"), nullptr,
+ str_printf (_("Unable to fetch %s"), uri1));
+ return;
+ }
+
+ String uri = scrape_uri_from_lyricwiki_search_result(buf.begin(), buf.len());
+
+ if (!uri)
+ {
+ update_lyrics_window (_("Error"), nullptr,
+ str_printf (_("Unable to parse %s"), uri1));
+ return;
+ }
+
+ state.uri = uri;
+
+ update_lyrics_window(state.title, state.artist, _("Looking for lyrics ..."));
+ vfs_async_file_get_contents(uri, get_lyrics_step_3, nullptr);
+}
+
+static void get_lyrics_step_1(void)
+{
+ if(!state.artist || !state.title)
+ {
+ update_lyrics_window(_("Error"), nullptr, _("Missing song metadata"));
+ return;
+ }
+
+ StringBuf title_buf = str_encode_percent (state.title);
+ StringBuf artist_buf = str_encode_percent (state.artist);
+
+ state.uri = String (str_printf ("http://lyrics.wikia.com/api.php?"
+ "action=lyrics&artist=%s&song=%s&fmt=xml", (const char *) artist_buf,
+ (const char *) title_buf));
+
+ update_lyrics_window(state.title, state.artist, _("Connecting to lyrics.wikia.com ..."));
+ vfs_async_file_get_contents(state.uri, get_lyrics_step_2, nullptr);
+}
+
+static GtkWidget *scrollview, *vbox;
+static GtkWidget *textview;
+static GtkTextBuffer *textbuffer;
+
+static GtkWidget *build_widget(void)
+{
+ textview = gtk_text_view_new();
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE);
+ gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview), FALSE);
+ gtk_text_view_set_left_margin(GTK_TEXT_VIEW(textview), 4);
+ gtk_text_view_set_right_margin(GTK_TEXT_VIEW(textview), 4);
+ gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD);
+ textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+
+ scrollview = gtk_scrolled_window_new(nullptr, nullptr);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollview), GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollview), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ vbox = gtk_vbox_new (FALSE, 10);
+
+ gtk_container_add(GTK_CONTAINER(scrollview), textview);
+
+ gtk_box_pack_start(GTK_BOX(vbox), scrollview, TRUE, TRUE, 0);
+
+ gtk_widget_show(textview);
+ gtk_widget_show(scrollview);
+ gtk_widget_show(vbox);
+
+ gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(textbuffer), "weight_bold", "weight", PANGO_WEIGHT_BOLD, nullptr);
+ gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(textbuffer), "size_x_large", "scale", PANGO_SCALE_X_LARGE, nullptr);
+ gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(textbuffer), "style_italic", "style", PANGO_STYLE_ITALIC, nullptr);
+
+ g_signal_connect (vbox, "destroy", (GCallback) gtk_widget_destroyed, & vbox);
+ return vbox;
+}
+
+static void update_lyrics_window(const char *title, const char *artist, const char *lyrics)
+{
+ GtkTextIter iter;
+
+ if (textbuffer == nullptr)
+ return;
+
+ gtk_text_buffer_set_text(GTK_TEXT_BUFFER(textbuffer), "", -1);
+
+ gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(textbuffer), &iter);
+
+ gtk_text_buffer_insert_with_tags_by_name(GTK_TEXT_BUFFER(textbuffer), &iter,
+ title, -1, "weight_bold", "size_x_large", nullptr);
+
+ if (artist != nullptr)
+ {
+ gtk_text_buffer_insert(GTK_TEXT_BUFFER(textbuffer), &iter, "\n", -1);
+ gtk_text_buffer_insert_with_tags_by_name(GTK_TEXT_BUFFER(textbuffer),
+ &iter, artist, -1, "style_italic", nullptr);
+ }
+
+ gtk_text_buffer_insert(GTK_TEXT_BUFFER(textbuffer), &iter, "\n\n", -1);
+ gtk_text_buffer_insert(GTK_TEXT_BUFFER(textbuffer), &iter, lyrics, -1);
+
+ gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(textbuffer), &iter);
+ gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(textview), &iter, 0, TRUE, 0, 0);
+}
+
+static void lyricwiki_playback_began(void)
+{
+ /* FIXME: cancel previous VFS requests (not possible with current API) */
+
+ state.filename = aud_drct_get_filename();
+
+ Tuple tuple = aud_drct_get_tuple();
+ state.title = tuple.get_str(Tuple::Title);
+ state.artist = tuple.get_str(Tuple::Artist);
+
+ state.uri = String ();
+
+ get_lyrics_step_1();
+}
+
+static void destroy_cb ()
+{
+ state.filename = String ();
+ state.title = String ();
+ state.artist = String ();
+ state.uri = String ();
+
+ hook_dissociate ("tuple change", (HookFunction) lyricwiki_playback_began);
+ hook_dissociate ("playback ready", (HookFunction) lyricwiki_playback_began);
+
+ textbuffer = nullptr;
+}
+
+void * LyricWiki::get_gtk_widget ()
+{
+ build_widget ();
+
+ hook_associate ("tuple change", (HookFunction) lyricwiki_playback_began, nullptr);
+ hook_associate ("playback ready", (HookFunction) lyricwiki_playback_began, nullptr);
+
+ if (aud_drct_get_ready ())
+ lyricwiki_playback_began ();
+
+ g_signal_connect (vbox, "destroy", destroy_cb, nullptr);
+
+ return vbox;
+}
diff --git a/src/m3u/Makefile b/src/m3u/Makefile
index 5e153a3e0a86..1ae9eee8d8c7 100644
--- a/src/m3u/Makefile
+++ b/src/m3u/Makefile
@@ -1,12 +1,13 @@
PLUGIN = m3u${PLUGIN_SUFFIX}
-SRCS = m3u.c
+SRCS = m3u.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${CONTAINER_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
diff --git a/src/m3u/m3u.c b/src/m3u/m3u.c
deleted file mode 100644
index a37fff9465c0..000000000000
--- a/src/m3u/m3u.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Audacious: A cross-platform multimedia player
- * Copyright (c) 2006-2010 William Pitcock, Tony Vroon, George Averill, Giacomo
- * Lozito, Derek Pomery and Yoshiki Yazawa, and John Lindgren.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-static void strip_char (char * text, char c)
-{
- char * set = text;
- char a;
-
- while ((a = * text ++))
- if (a != c)
- * set ++ = a;
-
- * set = 0;
-}
-
-static char * read_win_text (VFSFile * file)
-{
- void * raw = NULL;
- vfs_file_read_all (file, & raw, NULL);
- if (! raw)
- return NULL;
-
- strip_char (raw, '\r');
- return raw;
-}
-
-static char * split_line (char * line)
-{
- char * feed = strchr (line, '\n');
- if (! feed)
- return NULL;
-
- * feed = 0;
- return feed + 1;
-}
-
-static bool_t playlist_load_m3u (const char * path, VFSFile * file,
- char * * title, Index * filenames, Index * tuples)
-{
- char * text = read_win_text (file);
- if (! text)
- return FALSE;
-
- * title = NULL;
-
- char * parse = text;
-
- while (parse)
- {
- char * next = split_line (parse);
-
- while (* parse == ' ' || * parse == '\t')
- parse ++;
-
- if (! * parse)
- goto NEXT;
-
- if (* parse == '#')
- goto NEXT;
-
- char * s = aud_construct_uri (parse, path);
- if (s)
- index_insert (filenames, -1, s);
-
-NEXT:
- parse = next;
- }
-
- g_free (text);
- return TRUE;
-}
-
-static bool_t playlist_save_m3u (const char * path, VFSFile * file,
- const char * title, Index * filenames, Index * tuples)
-{
- int count = index_count (filenames);
-
- for (int i = 0; i < count; i ++)
- vfs_fprintf (file, "%s\n", (const char *) index_get (filenames, i));
-
- return TRUE;
-}
-
-static const char * const m3u_exts[] = {"m3u", "m3u8", NULL};
-
-AUD_PLAYLIST_PLUGIN
-(
- .name = N_("M3U Playlists"),
- .domain = PACKAGE,
- .extensions = m3u_exts,
- .load = playlist_load_m3u,
- .save = playlist_save_m3u
-)
diff --git a/src/m3u/m3u.cc b/src/m3u/m3u.cc
new file mode 100644
index 000000000000..0ce63af765b5
--- /dev/null
+++ b/src/m3u/m3u.cc
@@ -0,0 +1,117 @@
+/*
+ * Audacious: A cross-platform multimedia player
+ * Copyright (c) 2006-2010 William Pitcock, Tony Vroon, George Averill, Giacomo
+ * Lozito, Derek Pomery and Yoshiki Yazawa, and John Lindgren.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <string.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+
+static const char * const m3u_exts[] = {"m3u", "m3u8"};
+
+class M3ULoader : public PlaylistPlugin
+{
+public:
+ static constexpr PluginInfo info = {N_("M3U Playlists"), PACKAGE};
+
+ constexpr M3ULoader () : PlaylistPlugin (info, m3u_exts, true) {}
+
+ bool load (const char * filename, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items);
+ bool save (const char * filename, VFSFile & file, const char * title,
+ const Index<PlaylistAddItem> & items);
+};
+
+EXPORT M3ULoader aud_plugin_instance;
+
+static void strip_char (char * text, char c)
+{
+ char * set = text;
+ char a;
+
+ while ((a = * text ++))
+ if (a != c)
+ * set ++ = a;
+
+ * set = 0;
+}
+
+static Index<char> read_win_text (VFSFile & file)
+{
+ Index<char> raw = file.read_all ();
+ if (! raw.len ())
+ return raw;
+
+ raw.append (0); /* null-terminated */
+ strip_char (raw.begin (), '\r');
+ return raw;
+}
+
+static char * split_line (char * line)
+{
+ char * feed = strchr (line, '\n');
+ if (! feed)
+ return nullptr;
+
+ * feed = 0;
+ return feed + 1;
+}
+
+bool M3ULoader::load (const char * path, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items)
+{
+ Index<char> text = read_win_text (file);
+ if (! text.len ())
+ return false;
+
+ char * parse = text.begin ();
+
+ while (parse)
+ {
+ char * next = split_line (parse);
+
+ while (* parse == ' ' || * parse == '\t')
+ parse ++;
+
+ if (* parse && * parse != '#')
+ {
+ StringBuf s = uri_construct (parse, path);
+ if (s)
+ items.append (String (s));
+ }
+
+ parse = next;
+ }
+
+ return true;
+}
+
+bool M3ULoader::save (const char * path, VFSFile & file, const char * title,
+ const Index<PlaylistAddItem> & items)
+{
+ for (auto & item : items)
+ {
+ StringBuf line = str_concat ({item.filename, "\n"});
+ if (file.fwrite (line, 1, line.len ()) != line.len ())
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/mac-media-keys/MacMediaKeys.h b/src/mac-media-keys/MacMediaKeys.h
new file mode 100644
index 000000000000..d4fbce2f4215
--- /dev/null
+++ b/src/mac-media-keys/MacMediaKeys.h
@@ -0,0 +1,40 @@
+/*
+ * MacMediaKeys.h
+ * Copyright 2014 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#ifndef MAC_MEDIA_KEYS_H
+#define MAC_MEDIA_KEYS_H
+
+#import "SPMediaKeyTap.h"
+
+ at interface SPMediaKeyTapAppDelegate : NSObject <NSApplicationDelegate>
+ at end
+
+class MacMediaKeys
+{
+public:
+ MacMediaKeys ();
+ ~MacMediaKeys ();
+ SPMediaKeyTapAppDelegate * delegate;
+ SPMediaKeyTap * keyTap;
+
+private:
+ void run ();
+};
+
+#endif
diff --git a/src/mac-media-keys/MacMediaKeys.mm b/src/mac-media-keys/MacMediaKeys.mm
new file mode 100644
index 000000000000..444faff8f0c1
--- /dev/null
+++ b/src/mac-media-keys/MacMediaKeys.mm
@@ -0,0 +1,103 @@
+/*
+ * MacMediaKeys.mm
+ * Copyright 2014 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <thread>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+
+#import "MacMediaKeys.h"
+
+static MacMediaKeys * media;
+
+ at implementation SPMediaKeyTapAppDelegate
+- (void)mediaKeyTap:(SPMediaKeyTap *)keyTap receivedMediaKeyEvent:(NSEvent *)event;
+{
+ assert([event type] == NSSystemDefined && [event subtype] == SPSystemDefinedEventMediaKeys);
+
+ int keyCode = (([event data1] & 0xFFFF0000) >> 16);
+ int keyFlags = ([event data1] & 0x0000FFFF);
+ int keyState = (((keyFlags & 0xFF00) >> 8)) == 0xA;
+ // int keyRepeat = (keyFlags & 0x1);
+
+ if (keyState == 1)
+ {
+ switch (keyCode)
+ {
+ case NX_KEYTYPE_PLAY:
+ aud_drct_play_pause ();
+ return;
+
+ case NX_KEYTYPE_FAST:
+ case NX_KEYTYPE_NEXT:
+ aud_drct_pl_next ();
+ return;
+
+ case NX_KEYTYPE_REWIND:
+ case NX_KEYTYPE_PREVIOUS:
+ aud_drct_pl_prev ();
+ return;
+ }
+ }
+}
+ at end
+
+MacMediaKeys::MacMediaKeys ()
+{
+ std::thread thread (&MacMediaKeys::run, this);
+ thread.detach ();
+}
+
+MacMediaKeys::~MacMediaKeys ()
+{
+ [keyTap stopWatchingMediaKeys];
+}
+
+void MacMediaKeys::run ()
+{
+ // Register defaults for the whitelist of apps that want to use media keys
+ [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:
+ [SPMediaKeyTap defaultMediaKeyUserBundleIdentifiers], kMediaKeyUsingBundleIdentifiersDefaultsKey,
+ nil]];
+
+ delegate = [SPMediaKeyTapAppDelegate alloc];
+ keyTap = [[SPMediaKeyTap alloc] initWithDelegate: delegate];
+
+ if ([SPMediaKeyTap usesGlobalMediaKeyTap])
+ [keyTap startWatchingMediaKeys];
+}
+
+bool mac_media_keys_init ()
+{
+ media = new MacMediaKeys;
+ return true;
+}
+
+void mac_media_keys_cleanup ()
+{
+ delete media;
+}
+
+#define AUD_PLUGIN_NAME N_("Mac Media Keys")
+#define AUD_PLUGIN_INIT mac_media_keys_init
+#define AUD_PLUGIN_CLEANUP mac_media_keys_cleanup
+
+#define AUD_DECLARE_GENERAL
+#include <libaudcore/plugin-declare.h>
diff --git a/src/mac-media-keys/Makefile b/src/mac-media-keys/Makefile
new file mode 100644
index 000000000000..3aaeee9424e7
--- /dev/null
+++ b/src/mac-media-keys/Makefile
@@ -0,0 +1,16 @@
+PLUGIN = mac-media-keys${PLUGIN_SUFFIX}
+
+SRCS = MacMediaKeys.mm \
+ SPInvocationGrabbing.m \
+ SPMediaKeyTap.m
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+
+LD = ${OBJCXX}
+
+CFLAGS += ${PLUGIN_CFLAGS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
+LIBS += -framework AppKit
diff --git a/src/mac-media-keys/SPInvocationGrabbing.h b/src/mac-media-keys/SPInvocationGrabbing.h
new file mode 100644
index 000000000000..87dd23984994
--- /dev/null
+++ b/src/mac-media-keys/SPInvocationGrabbing.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (c) 2011, Joachim Bengtsson
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#import <Foundation/Foundation.h>
+
+ at interface SPInvocationGrabber : NSObject {
+ id _object;
+ NSInvocation *_invocation;
+ int frameCount;
+ char **frameStrings;
+ BOOL backgroundAfterForward;
+ BOOL onMainAfterForward;
+ BOOL waitUntilDone;
+}
+-(id)initWithObject:(id)obj;
+-(id)initWithObject:(id)obj stacktraceSaving:(BOOL)saveStack;
+ at property (readonly, retain, nonatomic) id object;
+ at property (readonly, retain, nonatomic) NSInvocation *invocation;
+ at property BOOL backgroundAfterForward;
+ at property BOOL onMainAfterForward;
+ at property BOOL waitUntilDone;
+-(void)invoke; // will release object and invocation
+-(void)printBacktrace;
+-(void)saveBacktrace;
+ at end
+
+ at interface NSObject (SPInvocationGrabbing)
+-(id)grab;
+-(id)invokeAfter:(NSTimeInterval)delta;
+-(id)nextRunloop;
+-(id)inBackground;
+-(id)onMainAsync:(BOOL)async;
+ at end
diff --git a/src/mac-media-keys/SPInvocationGrabbing.m b/src/mac-media-keys/SPInvocationGrabbing.m
new file mode 100644
index 000000000000..5b16d0091030
--- /dev/null
+++ b/src/mac-media-keys/SPInvocationGrabbing.m
@@ -0,0 +1,138 @@
+/*
+ Copyright (c) 2011, Joachim Bengtsson
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#import "SPInvocationGrabbing.h"
+#import <execinfo.h>
+
+#pragma mark Invocation grabbing
+ at interface SPInvocationGrabber ()
+ at property (readwrite, retain, nonatomic) id object;
+ at property (readwrite, retain, nonatomic) NSInvocation *invocation;
+
+ at end
+
+ at implementation SPInvocationGrabber
+- (id)initWithObject:(id)obj;
+{
+ return [self initWithObject:obj stacktraceSaving:YES];
+}
+
+-(id)initWithObject:(id)obj stacktraceSaving:(BOOL)saveStack;
+{
+ self.object = obj;
+
+ if(saveStack)
+ [self saveBacktrace];
+
+ return self;
+}
+-(void)dealloc;
+{
+ free(frameStrings);
+ self.object = nil;
+ self.invocation = nil;
+ [super dealloc];
+}
+ at synthesize invocation = _invocation, object = _object;
+
+ at synthesize backgroundAfterForward, onMainAfterForward, waitUntilDone;
+- (void)runInBackground;
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ @try {
+ [self invoke];
+ }
+ @finally {
+ [pool drain];
+ }
+}
+
+
+- (void)forwardInvocation:(NSInvocation *)anInvocation {
+ [anInvocation retainArguments];
+ anInvocation.target = _object;
+ self.invocation = anInvocation;
+
+ if(backgroundAfterForward)
+ [NSThread detachNewThreadSelector:@selector(runInBackground) toTarget:self withObject:nil];
+ else if(onMainAfterForward)
+ [self performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:waitUntilDone];
+}
+- (NSMethodSignature *)methodSignatureForSelector:(SEL)inSelector {
+ NSMethodSignature *signature = [super methodSignatureForSelector:inSelector];
+ if (signature == NULL)
+ signature = [_object methodSignatureForSelector:inSelector];
+
+ return signature;
+}
+
+- (void)invoke;
+{
+
+ @try {
+ [_invocation invoke];
+ }
+ @catch (NSException * e) {
+ NSLog(@"SPInvocationGrabber's target raised %@:\n\t%@\nInvocation was originally scheduled at:", e.name, e);
+ [self printBacktrace];
+ printf("\n");
+ [e raise];
+ }
+
+ self.invocation = nil;
+ self.object = nil;
+}
+
+-(void)saveBacktrace;
+{
+ void *backtraceFrames[128];
+ frameCount = backtrace(&backtraceFrames[0], 128);
+ frameStrings = backtrace_symbols(&backtraceFrames[0], frameCount);
+}
+-(void)printBacktrace;
+{
+ for(int x = 3; x < frameCount; x++) {
+ if(frameStrings[x] == NULL) { break; }
+ printf("%s\n", frameStrings[x]);
+ }
+}
+ at end
+
+ at implementation NSObject (SPInvocationGrabbing)
+-(id)grab;
+{
+ return [[[SPInvocationGrabber alloc] initWithObject:self] autorelease];
+}
+-(id)invokeAfter:(NSTimeInterval)delta;
+{
+ id grabber = [self grab];
+ [NSTimer scheduledTimerWithTimeInterval:delta target:grabber selector:@selector(invoke) userInfo:nil repeats:NO];
+ return grabber;
+}
+- (id)nextRunloop;
+{
+ return [self invokeAfter:0];
+}
+-(id)inBackground;
+{
+ SPInvocationGrabber *grabber = [self grab];
+ grabber.backgroundAfterForward = YES;
+ return grabber;
+}
+-(id)onMainAsync:(BOOL)async;
+{
+ SPInvocationGrabber *grabber = [self grab];
+ grabber.onMainAfterForward = YES;
+ grabber.waitUntilDone = !async;
+ return grabber;
+}
+
+ at end
diff --git a/src/mac-media-keys/SPMediaKeyTap.h b/src/mac-media-keys/SPMediaKeyTap.h
new file mode 100644
index 000000000000..61b98a12fe95
--- /dev/null
+++ b/src/mac-media-keys/SPMediaKeyTap.h
@@ -0,0 +1,54 @@
+/*
+ Copyright (c) 2011, Joachim Bengtsson
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <Cocoa/Cocoa.h>
+#import <IOKit/hidsystem/ev_keymap.h>
+#import <Carbon/Carbon.h>
+
+// http://overooped.com/post/2593597587/mediakeys
+
+#define SPSystemDefinedEventMediaKeys 8
+
+ at interface SPMediaKeyTap : NSObject {
+ EventHandlerRef _app_switching_ref;
+ EventHandlerRef _app_terminating_ref;
+ CFMachPortRef _eventPort;
+ CFRunLoopSourceRef _eventPortSource;
+ CFRunLoopRef _tapThreadRL;
+ BOOL _shouldInterceptMediaKeyEvents;
+ id _delegate;
+ // The app that is frontmost in this list owns media keys
+ NSMutableArray *_mediaKeyAppList;
+}
++ (NSArray*)defaultMediaKeyUserBundleIdentifiers;
+
+-(id)initWithDelegate:(id)delegate;
+
++(BOOL)usesGlobalMediaKeyTap;
+-(void)startWatchingMediaKeys;
+-(void)stopWatchingMediaKeys;
+-(void)handleAndReleaseMediaKeyEvent:(NSEvent *)event;
+ at end
+
+ at interface NSObject (SPMediaKeyTapDelegate)
+-(void)mediaKeyTap:(SPMediaKeyTap*)keyTap receivedMediaKeyEvent:(NSEvent*)event;
+ at end
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern NSString *kMediaKeyUsingBundleIdentifiersDefaultsKey;
+extern NSString *kIgnoreMediaKeysDefaultsKey;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/mac-media-keys/SPMediaKeyTap.m b/src/mac-media-keys/SPMediaKeyTap.m
new file mode 100644
index 000000000000..d3fb5740611f
--- /dev/null
+++ b/src/mac-media-keys/SPMediaKeyTap.m
@@ -0,0 +1,356 @@
+/*
+ Copyright (c) 2011, Joachim Bengtsson
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// Copyright (c) 2010 Spotify AB
+#import "SPMediaKeyTap.h"
+#import "SPInvocationGrabbing.h" // https://gist.github.com/511181, in submodule
+
+ at interface SPMediaKeyTap ()
+-(BOOL)shouldInterceptMediaKeyEvents;
+-(void)setShouldInterceptMediaKeyEvents:(BOOL)newSetting;
+-(void)startWatchingAppSwitching;
+-(void)stopWatchingAppSwitching;
+-(void)eventTapThread;
+ at end
+static SPMediaKeyTap *singleton = nil;
+
+static pascal OSStatus appSwitched (EventHandlerCallRef nextHandler, EventRef evt, void* userData);
+static pascal OSStatus appTerminated (EventHandlerCallRef nextHandler, EventRef evt, void* userData);
+static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon);
+
+
+// Inspired by http://gist.github.com/546311
+
+ at implementation SPMediaKeyTap
+
+#pragma mark -
+#pragma mark Setup and teardown
+-(id)initWithDelegate:(id)delegate;
+{
+ _delegate = delegate;
+ [self startWatchingAppSwitching];
+ singleton = self;
+ _mediaKeyAppList = [NSMutableArray new];
+ _tapThreadRL=nil;
+ _eventPort=nil;
+ _eventPortSource=nil;
+ return self;
+}
+-(void)dealloc;
+{
+ [self stopWatchingMediaKeys];
+ [self stopWatchingAppSwitching];
+ [_mediaKeyAppList release];
+ [super dealloc];
+}
+
+-(void)startWatchingAppSwitching;
+{
+ // Listen to "app switched" event, so that we don't intercept media keys if we
+ // weren't the last "media key listening" app to be active
+ EventTypeSpec eventType = { kEventClassApplication, kEventAppFrontSwitched };
+ OSStatus err = InstallApplicationEventHandler(NewEventHandlerUPP(appSwitched), 1, &eventType, self, &_app_switching_ref);
+ assert(err == noErr);
+
+ eventType.eventKind = kEventAppTerminated;
+ err = InstallApplicationEventHandler(NewEventHandlerUPP(appTerminated), 1, &eventType, self, &_app_terminating_ref);
+ assert(err == noErr);
+}
+-(void)stopWatchingAppSwitching;
+{
+ if(!_app_switching_ref) return;
+ RemoveEventHandler(_app_switching_ref);
+ _app_switching_ref = NULL;
+}
+
+-(void)startWatchingMediaKeys;{
+ // Prevent having multiple mediaKeys threads
+ [self stopWatchingMediaKeys];
+
+ [self setShouldInterceptMediaKeyEvents:YES];
+
+ // Add an event tap to intercept the system defined media key events
+ _eventPort = CGEventTapCreate(kCGSessionEventTap,
+ kCGHeadInsertEventTap,
+ kCGEventTapOptionDefault,
+ CGEventMaskBit(NX_SYSDEFINED),
+ tapEventCallback,
+ self);
+ assert(_eventPort != NULL);
+
+ _eventPortSource = CFMachPortCreateRunLoopSource(kCFAllocatorSystemDefault, _eventPort, 0);
+ assert(_eventPortSource != NULL);
+
+ // Let's do this in a separate thread so that a slow app doesn't lag the event tap
+ [NSThread detachNewThreadSelector:@selector(eventTapThread) toTarget:self withObject:nil];
+}
+-(void)stopWatchingMediaKeys;
+{
+ // TODO<nevyn>: Shut down thread, remove event tap port and source
+
+ if(_tapThreadRL){
+ CFRunLoopStop(_tapThreadRL);
+ _tapThreadRL=nil;
+ }
+
+ if(_eventPort){
+ CFMachPortInvalidate(_eventPort);
+ CFRelease(_eventPort);
+ _eventPort=nil;
+ }
+
+ if(_eventPortSource){
+ CFRelease(_eventPortSource);
+ _eventPortSource=nil;
+ }
+}
+
+#pragma mark -
+#pragma mark Accessors
+
++(BOOL)usesGlobalMediaKeyTap
+{
+#ifdef _DEBUG
+ // breaking in gdb with a key tap inserted sometimes locks up all mouse and keyboard input forever, forcing reboot
+ return NO;
+#else
+ // XXX(nevyn): MediaKey event tap doesn't work on 10.4, feel free to figure out why if you have the energy.
+ return
+ ![[NSUserDefaults standardUserDefaults] boolForKey:kIgnoreMediaKeysDefaultsKey]
+ && floor(NSAppKitVersionNumber) >= 949/*NSAppKitVersionNumber10_5*/;
+#endif
+}
+
++ (NSArray*)defaultMediaKeyUserBundleIdentifiers;
+{
+ return [NSArray arrayWithObjects:
+ [[NSBundle mainBundle] bundleIdentifier], // your app
+ @"com.spotify.client",
+ @"com.apple.iTunes",
+ @"com.apple.QuickTimePlayerX",
+ @"com.apple.quicktimeplayer",
+ @"com.apple.iWork.Keynote",
+ @"com.apple.iPhoto",
+ @"org.videolan.vlc",
+ @"com.apple.Aperture",
+ @"com.plexsquared.Plex",
+ @"com.soundcloud.desktop",
+ @"org.niltsh.MPlayerX",
+ @"com.ilabs.PandorasHelper",
+ @"com.mahasoftware.pandabar",
+ @"com.bitcartel.pandorajam",
+ @"org.clementine-player.clementine",
+ @"fm.last.Last.fm",
+ @"fm.last.Scrobbler",
+ @"com.beatport.BeatportPro",
+ @"com.Timenut.SongKey",
+ @"com.macromedia.fireworks", // the tap messes up their mouse input
+ @"at.justp.Theremin",
+ @"ru.ya.themblsha.YandexMusic",
+ @"com.jriver.MediaCenter18",
+ @"com.jriver.MediaCenter19",
+ @"com.jriver.MediaCenter20",
+ @"co.rackit.mate",
+ @"com.ttitt.b-music",
+ @"com.beardedspice.BeardedSpice",
+ @"com.plug.Plug",
+ @"com.netease.163music",
+ nil
+ ];
+}
+
+
+-(BOOL)shouldInterceptMediaKeyEvents;
+{
+ BOOL shouldIntercept = NO;
+ @synchronized(self) {
+ shouldIntercept = _shouldInterceptMediaKeyEvents;
+ }
+ return shouldIntercept;
+}
+
+-(void)pauseTapOnTapThread:(BOOL)yeahno;
+{
+ CGEventTapEnable(self->_eventPort, yeahno);
+}
+-(void)setShouldInterceptMediaKeyEvents:(BOOL)newSetting;
+{
+ BOOL oldSetting;
+ @synchronized(self) {
+ oldSetting = _shouldInterceptMediaKeyEvents;
+ _shouldInterceptMediaKeyEvents = newSetting;
+ }
+ if(_tapThreadRL && oldSetting != newSetting) {
+ id grab = [self grab];
+ [grab pauseTapOnTapThread:newSetting];
+ NSTimer *timer = [NSTimer timerWithTimeInterval:0 invocation:[grab invocation] repeats:NO];
+ CFRunLoopAddTimer(_tapThreadRL, (CFRunLoopTimerRef)timer, kCFRunLoopCommonModes);
+ }
+}
+
+#pragma mark
+#pragma mark -
+#pragma mark Event tap callbacks
+
+// Note: method called on background thread
+
+static CGEventRef tapEventCallback2(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
+{
+ SPMediaKeyTap *self = refcon;
+
+ if(type == kCGEventTapDisabledByTimeout) {
+ NSLog(@"Media key event tap was disabled by timeout");
+ CGEventTapEnable(self->_eventPort, TRUE);
+ return event;
+ } else if(type == kCGEventTapDisabledByUserInput) {
+ // Was disabled manually by -[pauseTapOnTapThread]
+ return event;
+ }
+ NSEvent *nsEvent = nil;
+ @try {
+ nsEvent = [NSEvent eventWithCGEvent:event];
+ }
+ @catch (NSException * e) {
+ NSLog(@"Strange CGEventType: %d: %@", type, e);
+ assert(0);
+ return event;
+ }
+
+ if (type != NX_SYSDEFINED || [nsEvent subtype] != SPSystemDefinedEventMediaKeys)
+ return event;
+
+ int keyCode = (([nsEvent data1] & 0xFFFF0000) >> 16);
+ if (keyCode != NX_KEYTYPE_PLAY && keyCode != NX_KEYTYPE_FAST && keyCode != NX_KEYTYPE_REWIND && keyCode != NX_KEYTYPE_PREVIOUS && keyCode != NX_KEYTYPE_NEXT)
+ return event;
+
+ if (![self shouldInterceptMediaKeyEvents])
+ return event;
+
+ [nsEvent retain]; // matched in handleAndReleaseMediaKeyEvent:
+ [self performSelectorOnMainThread:@selector(handleAndReleaseMediaKeyEvent:) withObject:nsEvent waitUntilDone:NO];
+
+ return NULL;
+}
+
+static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
+{
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+ CGEventRef ret = tapEventCallback2(proxy, type, event, refcon);
+ [pool drain];
+ return ret;
+}
+
+
+// event will have been retained in the other thread
+-(void)handleAndReleaseMediaKeyEvent:(NSEvent *)event {
+ [event autorelease];
+
+ [_delegate mediaKeyTap:self receivedMediaKeyEvent:event];
+}
+
+
+-(void)eventTapThread;
+{
+ _tapThreadRL = CFRunLoopGetCurrent();
+ CFRunLoopAddSource(_tapThreadRL, _eventPortSource, kCFRunLoopCommonModes);
+ CFRunLoopRun();
+}
+
+#pragma mark Task switching callbacks
+
+NSString *kMediaKeyUsingBundleIdentifiersDefaultsKey = @"SPApplicationsNeedingMediaKeys";
+NSString *kIgnoreMediaKeysDefaultsKey = @"SPIgnoreMediaKeys";
+
+
+
+-(void)mediaKeyAppListChanged;
+{
+ if([_mediaKeyAppList count] == 0) return;
+
+ /*NSLog(@"--");
+ int i = 0;
+ for (NSValue *psnv in _mediaKeyAppList) {
+ ProcessSerialNumber psn; [psnv getValue:&psn];
+ NSDictionary *processInfo = [(id)ProcessInformationCopyDictionary(
+ &psn,
+ kProcessDictionaryIncludeAllInformationMask
+ ) autorelease];
+ NSString *bundleIdentifier = [processInfo objectForKey:(id)kCFBundleIdentifierKey];
+ NSLog(@"%d: %@", i++, bundleIdentifier);
+ }*/
+
+ ProcessSerialNumber mySerial, topSerial;
+ GetCurrentProcess(&mySerial);
+ [[_mediaKeyAppList objectAtIndex:0] getValue:&topSerial];
+
+ Boolean same;
+ OSErr err = SameProcess(&mySerial, &topSerial, &same);
+ [self setShouldInterceptMediaKeyEvents:(err == noErr && same)];
+
+}
+-(void)appIsNowFrontmost:(ProcessSerialNumber)psn;
+{
+ NSValue *psnv = [NSValue valueWithBytes:&psn objCType:@encode(ProcessSerialNumber)];
+
+ NSDictionary *processInfo = [(id)ProcessInformationCopyDictionary(
+ &psn,
+ kProcessDictionaryIncludeAllInformationMask
+ ) autorelease];
+ NSString *bundleIdentifier = [processInfo objectForKey:(id)kCFBundleIdentifierKey];
+
+ NSArray *whitelistIdentifiers = [[NSUserDefaults standardUserDefaults] arrayForKey:kMediaKeyUsingBundleIdentifiersDefaultsKey];
+ if(![whitelistIdentifiers containsObject:bundleIdentifier]) return;
+
+ [_mediaKeyAppList removeObject:psnv];
+ [_mediaKeyAppList insertObject:psnv atIndex:0];
+ [self mediaKeyAppListChanged];
+}
+-(void)appTerminated:(ProcessSerialNumber)psn;
+{
+ NSValue *psnv = [NSValue valueWithBytes:&psn objCType:@encode(ProcessSerialNumber)];
+ [_mediaKeyAppList removeObject:psnv];
+ [self mediaKeyAppListChanged];
+}
+
+static pascal OSStatus appSwitched (EventHandlerCallRef nextHandler, EventRef evt, void* userData)
+{
+ SPMediaKeyTap *self = (id)userData;
+
+ ProcessSerialNumber newSerial;
+ GetFrontProcess(&newSerial);
+
+ [self appIsNowFrontmost:newSerial];
+
+ return CallNextEventHandler(nextHandler, evt);
+}
+
+static pascal OSStatus appTerminated (EventHandlerCallRef nextHandler, EventRef evt, void* userData)
+{
+ SPMediaKeyTap *self = (id)userData;
+
+ ProcessSerialNumber deadPSN;
+
+ GetEventParameter(
+ evt,
+ kEventParamProcessID,
+ typeProcessSerialNumber,
+ NULL,
+ sizeof(deadPSN),
+ NULL,
+ &deadPSN
+ );
+
+
+ [self appTerminated:deadPSN];
+ return CallNextEventHandler(nextHandler, evt);
+}
+
+ at end
diff --git a/src/metronom/Makefile b/src/metronom/Makefile
index da5b0a7b7dae..6c025d6752c2 100644
--- a/src/metronom/Makefile
+++ b/src/metronom/Makefile
@@ -1,11 +1,13 @@
PLUGIN = metronom${PLUGIN_SUFFIX}
-SRCS = metronom.c
+SRCS = metronom.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
diff --git a/src/metronom/metronom.c b/src/metronom/metronom.c
deleted file mode 100644
index c63219cf46fe..000000000000
--- a/src/metronom/metronom.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright 2000 Martin Strauss <mys at faveve.uni-stuttgart.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-#define MIN_BPM 1
-#define MAX_BPM 512
-#define TACT_ID_MAX 12
-#define TACT_FORM_MAX 8
-
-#define AUDIO_FREQ (44100)
-#define BUF_SAMPLES 512
-#define BUF_BYTES (BUF_SAMPLES * 2)
-#define MAX_AMPL 0x7fff
-
-typedef struct
-{
- int bpm;
- int num;
- int den;
- int id;
-} metronom_t;
-
-int tact_id[TACT_ID_MAX][2] = {
- {1, 1},
- {2, 2},
- {3, 2},
- {4, 2},
- {2, 4},
- {3, 4},
- {4, 4},
- {6, 4},
- {2, 8},
- {3, 8},
- {4, 8},
- {6, 8}
-};
-
-double tact_form[TACT_ID_MAX][TACT_FORM_MAX] = {
- {1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- {1.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- {1.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0},
- {1.0, 0.5, 0.6, 0.5, 0.0, 0.0, 0.0, 0.0},
- {1.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- {1.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0},
- {1.0, 0.5, 0.6, 0.5, 0.0, 0.0, 0.0, 0.0},
- {1.0, 0.5, 0.5, 0.6, 0.5, 0.5, 0.0, 0.0},
- {1.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- {1.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0},
- {1.0, 0.5, 0.6, 0.5, 0.0, 0.0, 0.0, 0.0},
- {1.0, 0.5, 0.5, 0.6, 0.5, 0.5, 0.0, 0.0}
-};
-
-static bool_t metronom_is_our_fd(const char * filename, VFSFile *fd)
-{
- if (!strncmp(filename, "tact://", 7))
- return TRUE;
- return FALSE;
-}
-
-static bool_t metronom_get_cp(const char *filename, metronom_t *pmetronom, char **str)
-{
- int count;
-
- count = sscanf(filename, "tact://%d*%d/%d",
- &pmetronom->bpm, &pmetronom->num, &pmetronom->den);
-
- if (count != 1 && count != 3)
- return FALSE;
-
- if (pmetronom->bpm < MIN_BPM || pmetronom->bpm > MAX_BPM)
- return FALSE;
-
- if (count == 1)
- {
- pmetronom->num = 1;
- pmetronom->den = 1;
- pmetronom->id = 0;
- }
- else
- {
- bool_t flag;
- int id;
-
- if (pmetronom->num == 0 || pmetronom->den == 0)
- return FALSE;
-
- flag = FALSE;
- for (id = 0; id < TACT_ID_MAX && !flag; id++)
- {
- if (pmetronom->num == tact_id[id][0] && pmetronom->den == tact_id[id][1])
- flag = TRUE;
- }
-
- if (!flag)
- return FALSE;
- else
- pmetronom->id = id;
- }
-
- if (str == NULL)
- return TRUE;
-
- if (pmetronom->num == 1 && pmetronom->den == 1)
- *str = str_printf (_("Tact generator: %d bpm"), pmetronom->bpm);
- else
- *str = str_printf (_("Tact generator: %d bpm %d/%d"), pmetronom->bpm, pmetronom->num, pmetronom->den);
-
- return TRUE;
-}
-
-static bool_t metronom_play (const char * filename, VFSFile * file)
-{
- metronom_t pmetronom;
- int16_t data[BUF_SAMPLES];
- int t = 0, tact, num;
- int datagoal = 0;
- int datamiddle = 0;
- int datacurrent = datamiddle;
- int datalast = datamiddle;
- int data_form[TACT_FORM_MAX];
-
- if (aud_input_open_audio(FMT_S16_NE, AUDIO_FREQ, 1) == 0)
- return FALSE;
-
- if (!metronom_get_cp(filename, &pmetronom, NULL))
- {
- fprintf (stderr, "Invalid metronom tact parameters in URI %s", filename);
- return FALSE;
- }
-
- aud_input_set_bitrate(sizeof(data[0]) * 8 * AUDIO_FREQ);
-
- tact = 60 * AUDIO_FREQ / pmetronom.bpm;
-
- /* prepare weighted amplitudes */
- for (num = 0; num < pmetronom.num; num++)
- {
- data_form[num] = MAX_AMPL * tact_form[pmetronom.id][num];
- }
-
- num = 0;
- while (!aud_input_check_stop())
- {
- int i;
-
- for (i = 0; i < BUF_SAMPLES; i++)
- {
- if (t == tact)
- {
- t = 0;
- datagoal = data_form[num];
- }
- else if (t == 10)
- {
- datagoal = -data_form[num];
- }
- else if (t == 25)
- {
- datagoal = data_form[num];
- /* circle through weighted amplitudes */
- num++;
- if (num >= pmetronom.num)
- num = 0;
- }
- /* makes curve a little bit smoother */
- data[i] = (datalast + datacurrent + datagoal) / 3;
- datalast = datacurrent;
- datacurrent = data[i];
- if (t > 35)
- datagoal = (datamiddle + 7 * datagoal) / 8;
- t++;
- }
-
- aud_input_write_audio(data, BUF_BYTES);
- }
-
- return TRUE;
-}
-
-static Tuple *metronom_probe_for_tuple(const char * filename, VFSFile *fd)
-{
- Tuple *tuple = tuple_new_from_filename(filename);
- metronom_t metronom;
- char *tmp = NULL;
-
- if (metronom_get_cp(filename, &metronom, &tmp))
- tuple_set_str(tuple, FIELD_TITLE, tmp);
-
- str_unref(tmp);
-
- return tuple;
-}
-
-static const char metronom_about[] =
- N_("A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n\n"
- "To use it, add a URL: tact://beats*num/den\n"
- "e.g. tact://77 to play 77 beats per minute\n"
- "or tact://60*3/4 to play 60 bpm in 3/4 tacts");
-
-static const char * const schemes[] = {"tact", NULL};
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("Tact Generator"),
- .domain = PACKAGE,
- .about_text = metronom_about,
- .schemes = schemes,
- .is_our_file_from_vfs = metronom_is_our_fd,
- .play = metronom_play,
- .probe_for_tuple = metronom_probe_for_tuple,
-)
diff --git a/src/metronom/metronom.cc b/src/metronom/metronom.cc
new file mode 100644
index 000000000000..0effeddbd838
--- /dev/null
+++ b/src/metronom/metronom.cc
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2000 Martin Strauss <mys at faveve.uni-stuttgart.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+#define MIN_BPM 1
+#define MAX_BPM 512
+#define TACT_ID_MAX 12
+#define TACT_FORM_MAX 8
+
+#define AUDIO_FREQ (44100)
+#define BUF_SAMPLES 512
+#define BUF_BYTES (BUF_SAMPLES * 2)
+#define MAX_AMPL 0x7fff
+
+class Metronome : public InputPlugin
+{
+public:
+ static const char about[];
+ static const char *const schemes[];
+
+ static constexpr PluginInfo info = {
+ N_("Tact Generator"),
+ PACKAGE,
+ about
+ };
+
+ static constexpr auto iinfo = InputInfo()
+ .with_schemes(schemes);
+
+ constexpr Metronome() : InputPlugin(info, iinfo) {}
+
+ bool is_our_file(const char *filename, VFSFile &);
+ Tuple read_tuple(const char *filename, VFSFile &);
+ bool play(const char *filename, VFSFile &);
+};
+
+EXPORT Metronome aud_plugin_instance;
+
+typedef struct
+{
+ int bpm;
+ int num;
+ int den;
+ int id;
+} metronom_t;
+
+int tact_id[TACT_ID_MAX][2] = {
+ {1, 1},
+ {2, 2},
+ {3, 2},
+ {4, 2},
+ {2, 4},
+ {3, 4},
+ {4, 4},
+ {6, 4},
+ {2, 8},
+ {3, 8},
+ {4, 8},
+ {6, 8}
+};
+
+double tact_form[TACT_ID_MAX][TACT_FORM_MAX] = {
+ {1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 0.5, 0.6, 0.5, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 0.5, 0.6, 0.5, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 0.5, 0.5, 0.6, 0.5, 0.5, 0.0, 0.0},
+ {1.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 0.5, 0.6, 0.5, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 0.5, 0.5, 0.6, 0.5, 0.5, 0.0, 0.0}
+};
+
+bool Metronome::is_our_file(const char *filename, VFSFile &)
+{
+ if (!strncmp(filename, "tact://", 7))
+ return true;
+ return false;
+}
+
+static bool metronom_get_cp(const char *filename, metronom_t *pmetronom, String & str)
+{
+ int count;
+
+ count = sscanf(filename, "tact://%d*%d/%d",
+ &pmetronom->bpm, &pmetronom->num, &pmetronom->den);
+
+ if (count != 1 && count != 3)
+ return false;
+
+ if (pmetronom->bpm < MIN_BPM || pmetronom->bpm > MAX_BPM)
+ return false;
+
+ if (count == 1)
+ {
+ pmetronom->num = 1;
+ pmetronom->den = 1;
+ pmetronom->id = 0;
+ }
+ else
+ {
+ bool flag;
+ int id;
+
+ if (pmetronom->num == 0 || pmetronom->den == 0)
+ return false;
+
+ flag = false;
+ for (id = 0; id < TACT_ID_MAX && !flag; id++)
+ {
+ if (pmetronom->num == tact_id[id][0] && pmetronom->den == tact_id[id][1])
+ flag = true;
+ }
+
+ if (!flag)
+ return false;
+ else
+ pmetronom->id = id;
+ }
+
+ if (pmetronom->num == 1 && pmetronom->den == 1)
+ str = String (str_printf (_("Tact generator: %d bpm"), pmetronom->bpm));
+ else
+ str = String (str_printf (_("Tact generator: %d bpm %d/%d"),
+ pmetronom->bpm, pmetronom->num, pmetronom->den));
+
+ return true;
+}
+
+bool Metronome::play (const char * filename, VFSFile &)
+{
+ metronom_t pmetronom;
+ int16_t data[BUF_SAMPLES];
+ int t = 0, tact, num;
+ int datagoal = 0;
+ int datamiddle = 0;
+ int datacurrent = datamiddle;
+ int datalast = datamiddle;
+ int data_form[TACT_FORM_MAX];
+ String desc;
+
+ set_stream_bitrate(sizeof(data[0]) * 8 * AUDIO_FREQ);
+ open_audio(FMT_S16_NE, AUDIO_FREQ, 1);
+
+ if (!metronom_get_cp(filename, &pmetronom, desc))
+ {
+ AUDERR ("Invalid metronom tact parameters in URI %s", filename);
+ return false;
+ }
+
+ tact = 60 * AUDIO_FREQ / pmetronom.bpm;
+
+ /* prepare weighted amplitudes */
+ for (num = 0; num < pmetronom.num; num++)
+ {
+ data_form[num] = MAX_AMPL * tact_form[pmetronom.id][num];
+ }
+
+ num = 0;
+ while (!check_stop())
+ {
+ int i;
+
+ for (i = 0; i < BUF_SAMPLES; i++)
+ {
+ if (t == tact)
+ {
+ t = 0;
+ datagoal = data_form[num];
+ }
+ else if (t == 10)
+ {
+ datagoal = -data_form[num];
+ }
+ else if (t == 25)
+ {
+ datagoal = data_form[num];
+ /* circle through weighted amplitudes */
+ num++;
+ if (num >= pmetronom.num)
+ num = 0;
+ }
+ /* makes curve a little bit smoother */
+ data[i] = (datalast + datacurrent + datagoal) / 3;
+ datalast = datacurrent;
+ datacurrent = data[i];
+ if (t > 35)
+ datagoal = (datamiddle + 7 * datagoal) / 8;
+ t++;
+ }
+
+ write_audio(data, BUF_BYTES);
+ }
+
+ return true;
+}
+
+Tuple Metronome::read_tuple(const char *filename, VFSFile &)
+{
+ Tuple tuple;
+ metronom_t metronom;
+ String desc;
+
+ tuple.set_filename (filename);
+ if (metronom_get_cp(filename, &metronom, desc))
+ tuple.set_str (Tuple::Title, desc);
+
+ return tuple;
+}
+
+const char Metronome::about[] =
+ N_("A Tact Generator by Martin Strauss <mys at faveve.uni-stuttgart.de>\n\n"
+ "To use it, add a URL: tact://beats*num/den\n"
+ "e.g. tact://77 to play 77 beats per minute\n"
+ "or tact://60*3/4 to play 60 bpm in 3/4 tacts");
+
+const char *const Metronome::schemes[] = {"tact", nullptr};
diff --git a/src/mixer/Makefile b/src/mixer/Makefile
index 38feed85403e..212a9db5d1cf 100644
--- a/src/mixer/Makefile
+++ b/src/mixer/Makefile
@@ -1,12 +1,12 @@
PLUGIN = mixer${PLUGIN_SUFFIX}
-SRCS = mixer.c
+SRCS = mixer.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
+LD = ${CXX}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
CFLAGS += ${PLUGIN_CFLAGS}
-LIBS += ${GLIB_LIBS}
diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c
deleted file mode 100644
index e77ea2cd515e..000000000000
--- a/src/mixer/mixer.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Channel Mixer Plugin for Audacious
- * Copyright 2011-2012 John Lindgren and MichaÅ Lipski
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-/* TODO: implement more surround converters */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-#define MAX_CHANNELS 8
-
-typedef void (* Converter) (float * * data, int * samples);
-
-static float * mixer_buf;
-
-static void mono_to_stereo (float * * data, int * samples)
-{
- int frames = * samples;
- float * get = * data;
- float * set = mixer_buf = g_renew (float, mixer_buf, 2 * frames);
-
- * data = mixer_buf;
- * samples = 2 * frames;
-
- while (frames --)
- {
- float val = * get ++;
- * set ++ = val;
- * set ++ = val;
- }
-}
-
-static void stereo_to_mono (float * * data, int * samples)
-{
- int frames = * samples / 2;
- float * get = * data;
- float * set = mixer_buf = g_renew (float, mixer_buf, frames);
-
- * data = mixer_buf;
- * samples = frames;
-
- while (frames --)
- {
- float val = * get ++;
- val += * get ++;
- * set ++ = val / 2;
- }
-}
-
-static void quadro_to_stereo (float * * data, int * samples)
-{
- int frames = * samples / 4;
- float * get = * data;
- float * set = mixer_buf = g_renew (float, mixer_buf, 2 * frames);
-
- * data = mixer_buf;
- * samples = 2 * frames;
-
- while (frames --)
- {
- float front_left = * get ++;
- float front_right = * get ++;
- float back_left = * get ++;
- float back_right = * get ++;
- * set ++ = front_left + (back_left * 0.7);
- * set ++ = front_right + (back_right * 0.7);
- }
-}
-
-static void surround_5p1_to_stereo (float * * data, int * samples)
-{
- int frames = * samples / 6;
- float * get = * data;
- float * set = mixer_buf = g_renew (float, mixer_buf, 2 * frames);
-
- * data = mixer_buf;
- * samples = 2 * frames;
-
- while (frames --)
- {
- float front_left = * get ++;
- float front_right = * get ++;
- float center = * get ++;
- float lfe = * get ++;
- float rear_left = * get ++;
- float rear_right = * get ++;
- * set ++ = front_left + (center * 0.5) + (lfe * 0.5) + (rear_left * 0.5);
- * set ++ = front_right + (center * 0.5) + (lfe * 0.5) + (rear_right * 0.5);
- }
-}
-
-static const Converter converters[MAX_CHANNELS + 1][MAX_CHANNELS + 1] = {
- [1][2] = mono_to_stereo,
- [2][1] = stereo_to_mono,
- [4][2] = quadro_to_stereo,
- [6][2] = surround_5p1_to_stereo};
-
-static int input_channels, output_channels;
-
-void mixer_start (int * channels, int * rate)
-{
- input_channels = * channels;
- output_channels = aud_get_int ("mixer", "channels");
- output_channels = CLAMP (output_channels, 1, MAX_CHANNELS);
-
- if (input_channels == output_channels)
- return;
-
- if (input_channels < 1 || input_channels > MAX_CHANNELS ||
- ! converters[input_channels][output_channels])
- {
- fprintf (stderr, "Converting %d to %d channels is not implemented.\n",
- input_channels, output_channels);
- return;
- }
-
- * channels = output_channels;
-}
-
-void mixer_process (float * * data, int * samples)
-{
- if (input_channels == output_channels)
- return;
-
- if (input_channels < 1 || input_channels > MAX_CHANNELS ||
- ! converters[input_channels][output_channels])
- return;
-
- converters[input_channels][output_channels] (data, samples);
-}
-
-static const char * const mixer_defaults[] = {
- "channels", "2",
- NULL};
-
-static bool_t mixer_init (void)
-{
- aud_config_set_defaults ("mixer", mixer_defaults);
- return TRUE;
-}
-
-static void mixer_cleanup (void)
-{
- g_free (mixer_buf);
- mixer_buf = 0;
-}
-
-static const char mixer_about[] =
- N_("Channel Mixer Plugin for Audacious\n"
- "Copyright 2011-2012 John Lindgren and MichaÅ Lipski");
-
-static const PreferencesWidget mixer_widgets[] = {
- {WIDGET_LABEL, N_("<b>Channel Mixer</b>")},
- {WIDGET_SPIN_BTN, N_("Output channels:"),
- .cfg_type = VALUE_INT, .csect = "mixer", .cname = "channels",
- .data = {.spin_btn = {1, MAX_CHANNELS, 1}}}};
-
-static const PluginPreferences mixer_prefs = {
- .widgets = mixer_widgets,
- .n_widgets = ARRAY_LEN (mixer_widgets)};
-
-AUD_EFFECT_PLUGIN
-(
- .name = N_("Channel Mixer"),
- .domain = PACKAGE,
- .about_text = mixer_about,
- .prefs = & mixer_prefs,
- .init = mixer_init,
- .cleanup = mixer_cleanup,
- .start = mixer_start,
- .process = mixer_process,
- .finish = mixer_process,
- .order = 2, /* must be before crossfade */
-)
diff --git a/src/mixer/mixer.cc b/src/mixer/mixer.cc
new file mode 100644
index 000000000000..9fe5728730ae
--- /dev/null
+++ b/src/mixer/mixer.cc
@@ -0,0 +1,212 @@
+/*
+ * Channel Mixer Plugin for Audacious
+ * Copyright 2011-2012 John Lindgren and MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+/* TODO: implement more surround converters */
+
+#include <stdlib.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+
+class ChannelMixer : public EffectPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Channel Mixer"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ /* order #2: must be before crossfade */
+ constexpr ChannelMixer () : EffectPlugin (info, 2, false) {}
+
+ bool init ();
+ void cleanup ();
+
+ void start (int & channels, int & rate);
+ Index<float> & process (Index<float> & data);
+};
+
+EXPORT ChannelMixer aud_plugin_instance;
+
+typedef Index<float> & (* Converter) (Index<float> & data);
+
+static Index<float> mixer_buf;
+
+static Index<float> & mono_to_stereo (Index<float> & data)
+{
+ int frames = data.len ();
+ mixer_buf.resize (2 * frames);
+
+ float * get = data.begin ();
+ float * set = mixer_buf.begin ();
+
+ while (frames --)
+ {
+ float val = * get ++;
+ * set ++ = val;
+ * set ++ = val;
+ }
+
+ return mixer_buf;
+}
+
+static Index<float> & stereo_to_mono (Index<float> & data)
+{
+ int frames = data.len () / 2;
+ mixer_buf.resize (frames);
+
+ float * get = data.begin ();
+ float * set = mixer_buf.begin ();
+
+ while (frames --)
+ {
+ float val = * get ++;
+ val += * get ++;
+ * set ++ = val / 2;
+ }
+
+ return mixer_buf;
+}
+
+static Index<float> & quadro_to_stereo (Index<float> & data)
+{
+ int frames = data.len () / 4;
+ mixer_buf.resize (2 * frames);
+
+ float * get = data.begin ();
+ float * set = mixer_buf.begin ();
+
+ while (frames --)
+ {
+ float front_left = * get ++;
+ float front_right = * get ++;
+ float back_left = * get ++;
+ float back_right = * get ++;
+ * set ++ = front_left + (back_left * 0.7);
+ * set ++ = front_right + (back_right * 0.7);
+ }
+
+ return mixer_buf;
+}
+
+static Index<float> & surround_5p1_to_stereo (Index<float> & data)
+{
+ int frames = data.len () / 6;
+ mixer_buf.resize (2 * frames);
+
+ float * get = data.begin ();
+ float * set = mixer_buf.begin ();
+
+ while (frames --)
+ {
+ float front_left = * get ++;
+ float front_right = * get ++;
+ float center = * get ++;
+ float lfe = * get ++;
+ float rear_left = * get ++;
+ float rear_right = * get ++;
+ * set ++ = front_left + (center * 0.5) + (lfe * 0.5) + (rear_left * 0.5);
+ * set ++ = front_right + (center * 0.5) + (lfe * 0.5) + (rear_right * 0.5);
+ }
+
+ return mixer_buf;
+}
+
+static Converter get_converter (int in, int out)
+{
+ if (in == 1 && out == 2)
+ return mono_to_stereo;
+ if (in == 2 && out == 1)
+ return stereo_to_mono;
+ if (in == 4 && out == 2)
+ return quadro_to_stereo;
+ if (in == 6 && out == 2)
+ return surround_5p1_to_stereo;
+
+ return nullptr;
+}
+
+static int input_channels, output_channels;
+
+void ChannelMixer::start (int & channels, int & rate)
+{
+ input_channels = channels;
+ output_channels = aud_get_int ("mixer", "channels");
+
+ if (input_channels == output_channels)
+ return;
+
+ if (! get_converter (input_channels, output_channels))
+ {
+ AUDERR ("Converting %d to %d channels is not implemented.\n",
+ input_channels, output_channels);
+ return;
+ }
+
+ channels = output_channels;
+}
+
+Index<float> & ChannelMixer::process (Index<float> & data)
+{
+ if (input_channels == output_channels)
+ return data;
+
+ Converter converter = get_converter (input_channels, output_channels);
+ if (converter)
+ return converter (data);
+
+ return data;
+}
+
+const char * const ChannelMixer::defaults[] = {
+ "channels", "2",
+ nullptr};
+
+bool ChannelMixer::init ()
+{
+ aud_config_set_defaults ("mixer", defaults);
+ return true;
+}
+
+void ChannelMixer::cleanup ()
+{
+ mixer_buf.clear ();
+}
+
+const char ChannelMixer::about[] =
+ N_("Channel Mixer Plugin for Audacious\n"
+ "Copyright 2011-2012 John Lindgren and MichaÅ Lipski");
+
+const PreferencesWidget ChannelMixer::widgets[] = {
+ WidgetLabel (N_("<b>Channel Mixer</b>")),
+ WidgetSpin (N_("Output channels:"),
+ WidgetInt ("mixer", "channels"),
+ {1, AUD_MAX_CHANNELS, 1})
+};
+
+const PluginPreferences ChannelMixer::prefs = {{widgets}};
diff --git a/src/mms/Makefile b/src/mms/Makefile
index daa2c4e1ca7d..9bba09fe6031 100644
--- a/src/mms/Makefile
+++ b/src/mms/Makefile
@@ -1,12 +1,14 @@
PLUGIN = mms${PLUGIN_SUFFIX}
-SRCS = mms.c
+SRCS = mms.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${TRANSPORT_PLUGIN_DIR}
+LD = ${CXX}
+
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${MMS_CFLAGS} -I../.. -Wall
CFLAGS += ${PLUGIN_CFLAGS}
LIBS += ${MMS_LIBS}
diff --git a/src/mms/mms.c b/src/mms/mms.c
deleted file mode 100644
index c57f35373b77..000000000000
--- a/src/mms/mms.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * MMS/MMSH Transport for Audacious
- * Copyright 2007-2013 William Pitcock and John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <libmms/mms.h>
-#include <libmms/mmsh.h>
-
-#include <audacious/debug.h>
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-
-typedef struct
-{
- mms_t * mms;
- mmsh_t * mmsh;
-}
-MMSHandle;
-
-static void * mms_vfs_fopen_impl (const char * path, const char * mode)
-{
- AUDDBG ("Opening %s.\n", path);
-
- MMSHandle * h = g_new0 (MMSHandle, 1);
-
- if (! (h->mmsh = mmsh_connect (NULL, NULL, path, 128 * 1024)))
- {
- AUDDBG ("Failed to connect with MMSH protocol; trying MMS.\n");
-
- if (! (h->mms = mms_connect (NULL, NULL, path, 128 * 1024)))
- {
- fprintf (stderr, "mms: Failed to open %s.\n", path);
- g_free (h);
- return NULL;
- }
- }
-
- return h;
-}
-
-static int mms_vfs_fclose_impl (VFSFile * file)
-{
- MMSHandle * h = (MMSHandle *) vfs_get_handle (file);
-
- if (h->mms)
- mms_close (h->mms);
- else
- mmsh_close (h->mmsh);
-
- g_free (h);
- return 0;
-}
-
-static int64_t mms_vfs_fread_impl (void * buf, int64_t size, int64_t count, VFSFile * file)
-{
- MMSHandle * h = vfs_get_handle (file);
- int64_t bytes_total = size * count;
- int64_t bytes_read = 0;
-
- while (bytes_read < bytes_total)
- {
- int64_t readsize;
-
- if (h->mms)
- readsize = mms_read (NULL, h->mms, (char *) buf + bytes_read, bytes_total - bytes_read);
- else
- readsize = mmsh_read (NULL, h->mmsh, (char *) buf + bytes_read, bytes_total - bytes_read);
-
- if (readsize < 0)
- fprintf (stderr, "mms: Read failed.\n");
-
- if (readsize <= 0)
- break;
-
- bytes_read += readsize;
- }
-
- return size ? bytes_read / size : 0;
-}
-
-static int64_t mms_vfs_fwrite_impl (const void * data, int64_t size, int64_t count, VFSFile * file)
-{
- fprintf (stderr, "mms: Writing is not supported.\n");
- return 0;
-}
-
-static int mms_vfs_fseek_impl (VFSFile * file, int64_t offset, int whence)
-{
- MMSHandle * h = vfs_get_handle (file);
-
- if (whence == SEEK_CUR)
- {
- if (h->mms)
- offset += mms_get_current_pos (h->mms);
- else
- offset += mmsh_get_current_pos (h->mmsh);
- }
- else if (whence == SEEK_END)
- {
- if (h->mms)
- offset += mms_get_length (h->mms);
- else
- offset += mmsh_get_length (h->mmsh);
- }
-
- int64_t ret;
-
- if (h->mms)
- ret = mms_seek (NULL, h->mms, offset, SEEK_SET);
- else
- ret = mmsh_seek (NULL, h->mmsh, offset, SEEK_SET);
-
- if (ret < 0 || ret != offset)
- {
- fprintf (stderr, "mms: Seek failed.\n");
- return -1;
- }
-
- return 0;
-}
-
-static int64_t mms_vfs_ftell_impl (VFSFile * file)
-{
- MMSHandle * h = vfs_get_handle (file);
-
- if (h->mms)
- return mms_get_current_pos (h->mms);
- else
- return mmsh_get_current_pos (h->mmsh);
-}
-
-static bool_t mms_vfs_feof_impl (VFSFile * file)
-{
- MMSHandle * h = vfs_get_handle (file);
-
- if (h->mms)
- return (mms_get_current_pos (h->mms) < mms_get_length (h->mms));
- else
- return (mmsh_get_current_pos (h->mmsh) < mmsh_get_length (h->mmsh));
-}
-
-static int mms_vfs_truncate_impl (VFSFile * file, int64_t size)
-{
- fprintf (stderr, "mms: Truncating is not supported.\n");
- return -1;
-}
-
-static int64_t mms_vfs_fsize_impl (VFSFile * file)
-{
- MMSHandle * h = vfs_get_handle (file);
-
- if (h->mms)
- return mms_get_length (h->mms);
- else
- return mmsh_get_length (h->mmsh);
-}
-
-static const char * const mms_schemes[] = {"mms", NULL};
-
-static VFSConstructor constructor =
-{
- .vfs_fopen_impl = mms_vfs_fopen_impl,
- .vfs_fclose_impl = mms_vfs_fclose_impl,
- .vfs_fread_impl = mms_vfs_fread_impl,
- .vfs_fwrite_impl = mms_vfs_fwrite_impl,
- .vfs_fseek_impl = mms_vfs_fseek_impl,
- .vfs_ftell_impl = mms_vfs_ftell_impl,
- .vfs_feof_impl = mms_vfs_feof_impl,
- .vfs_ftruncate_impl = mms_vfs_truncate_impl,
- .vfs_fsize_impl = mms_vfs_fsize_impl
-};
-
-AUD_TRANSPORT_PLUGIN
-(
- .name = N_("MMS Plugin"),
- .domain = PACKAGE,
- .schemes = mms_schemes,
- .vtable = & constructor
-)
diff --git a/src/mms/mms.cc b/src/mms/mms.cc
new file mode 100644
index 000000000000..983e1f587431
--- /dev/null
+++ b/src/mms/mms.cc
@@ -0,0 +1,196 @@
+/*
+ * MMS/MMSH Transport for Audacious
+ * Copyright 2007-2013 William Pitcock and John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libmms/mms.h>
+#include <libmms/mmsh.h>
+
+#include <libaudcore/runtime.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+
+static const char * const mms_schemes[] = {"mms"};
+
+class MMSTransport : public TransportPlugin
+{
+public:
+ static constexpr PluginInfo info = {N_("MMS Plugin"), PACKAGE};
+
+ constexpr MMSTransport () : TransportPlugin (info, mms_schemes) {}
+
+ VFSImpl * fopen (const char * path, const char * mode, String & error);
+};
+
+EXPORT MMSTransport aud_plugin_instance;
+
+class MMSFile : public VFSImpl
+{
+public:
+ MMSFile (const char * path, mms_t * mms, mmsh_t * mmsh) :
+ m_mms (mms),
+ m_mmsh (mmsh) {}
+
+ ~MMSFile ();
+
+ class OpenError {}; // exception
+
+ int64_t fread (void * ptr, int64_t size, int64_t nmemb);
+ int64_t fwrite (const void * ptr, int64_t size, int64_t nmemb);
+
+ int fseek (int64_t offset, VFSSeekType whence);
+ int64_t ftell ();
+ int64_t fsize ();
+ bool feof ();
+ int ftruncate (int64_t size);
+ int fflush ();
+
+private:
+ mms_t * m_mms;
+ mmsh_t * m_mmsh;
+};
+
+VFSImpl * MMSTransport::fopen (const char * path, const char * mode, String & error)
+{
+ mms_t * mms = nullptr;
+ mmsh_t * mmsh = nullptr;
+
+ if (! (mmsh = mmsh_connect (nullptr, nullptr, path, 128 * 1024)))
+ {
+ AUDDBG ("Failed to connect with MMSH protocol; trying MMS.\n");
+
+ if (! (mms = mms_connect (nullptr, nullptr, path, 128 * 1024)))
+ {
+ AUDERR ("Failed to open %s.\n", path);
+ error = String (_("Error connecting to MMS server"));
+ return nullptr;
+ }
+ }
+
+ return new MMSFile (path, mms, mmsh);
+}
+
+MMSFile::~MMSFile ()
+{
+ if (m_mms)
+ mms_close (m_mms);
+ else
+ mmsh_close (m_mmsh);
+}
+
+int64_t MMSFile::fread (void * buf, int64_t size, int64_t count)
+{
+ int64_t bytes_total = size * count;
+ int64_t bytes_read = 0;
+
+ while (bytes_read < bytes_total)
+ {
+ int64_t readsize;
+
+ if (m_mms)
+ readsize = mms_read (nullptr, m_mms, (char *) buf + bytes_read, bytes_total - bytes_read);
+ else
+ readsize = mmsh_read (nullptr, m_mmsh, (char *) buf + bytes_read, bytes_total - bytes_read);
+
+ if (readsize < 0)
+ AUDERR ("Read failed.\n");
+
+ if (readsize <= 0)
+ break;
+
+ bytes_read += readsize;
+ }
+
+ return size ? bytes_read / size : 0;
+}
+
+int64_t MMSFile::fwrite (const void * data, int64_t size, int64_t count)
+{
+ AUDERR ("Writing is not supported.\n");
+ return 0;
+}
+
+int MMSFile::fseek (int64_t offset, VFSSeekType whence)
+{
+ if (whence == VFS_SEEK_CUR)
+ {
+ if (m_mms)
+ offset += mms_get_current_pos (m_mms);
+ else
+ offset += mmsh_get_current_pos (m_mmsh);
+ }
+ else if (whence == VFS_SEEK_END)
+ {
+ if (m_mms)
+ offset += mms_get_length (m_mms);
+ else
+ offset += mmsh_get_length (m_mmsh);
+ }
+
+ int64_t ret;
+
+ if (m_mms)
+ ret = mms_seek (nullptr, m_mms, offset, SEEK_SET);
+ else
+ ret = mmsh_seek (nullptr, m_mmsh, offset, SEEK_SET);
+
+ if (ret < 0 || ret != offset)
+ {
+ AUDERR ("Seek failed.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int64_t MMSFile::ftell ()
+{
+ if (m_mms)
+ return mms_get_current_pos (m_mms);
+ else
+ return mmsh_get_current_pos (m_mmsh);
+}
+
+bool MMSFile::feof ()
+{
+ if (m_mms)
+ return (mms_get_current_pos (m_mms) < (int64_t) mms_get_length (m_mms));
+ else
+ return (mmsh_get_current_pos (m_mmsh) < (int64_t) mmsh_get_length (m_mmsh));
+}
+
+int MMSFile::ftruncate (int64_t size)
+{
+ AUDERR ("Truncating is not supported.\n");
+ return -1;
+}
+
+int64_t MMSFile::fsize ()
+{
+ if (m_mms)
+ return mms_get_length (m_mms);
+ else
+ return mmsh_get_length (m_mmsh);
+}
+
+int MMSFile::fflush ()
+{
+ return 0;
+}
diff --git a/src/modplug/Makefile b/src/modplug/Makefile
index 9036141213f2..560de5ff1c86 100644
--- a/src/modplug/Makefile
+++ b/src/modplug/Makefile
@@ -1,11 +1,10 @@
PLUGIN = modplug${PLUGIN_SUFFIX}
-SRCS = archive/arch_raw.cxx \
- archive/archive.cxx \
- archive/open.cxx \
- plugin.cxx \
- modplugbmp.cxx \
- plugin_main.c
+SRCS = archive/arch_raw.cc \
+ archive/archive.cc \
+ archive/open.cc \
+ modplugbmp.cc \
+ plugin_main.cc
include ../../buildsys.mk
include ../../extra.mk
@@ -15,5 +14,5 @@ plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CXXFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${MODPLUG_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS} ${MODPLUG_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${MODPLUG_CFLAGS} -I../..
+LIBS += ${MODPLUG_LIBS}
diff --git a/src/modplug/archive/arch_raw.cc b/src/modplug/archive/arch_raw.cc
new file mode 100644
index 000000000000..f275af5d4dca
--- /dev/null
+++ b/src/modplug/archive/arch_raw.cc
@@ -0,0 +1,49 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal at gauge3d.org>
+ *
+ * This source code is public domain.
+ */
+
+#include <cstdlib>
+
+#include "arch_raw.h"
+
+using namespace std;
+
+arch_Raw::arch_Raw(const string& aFileName)
+{
+ mFileDesc = VFSFile(aFileName.c_str(), "r");
+ if (!mFileDesc)
+ {
+ mSize = 0;
+ return;
+ }
+
+ mSize = mFileDesc.fsize ();
+ if (mSize <= 0)
+ {
+ mSize = 0;
+ return;
+ }
+
+ mMap = malloc(mSize);
+ if (mFileDesc.fread (mMap, 1, mSize) < mSize)
+ {
+ free(mMap);
+ mSize = 0;
+ return;
+ }
+}
+
+arch_Raw::~arch_Raw()
+{
+ if(mSize != 0)
+ {
+ free(mMap);
+ }
+}
+
+bool arch_Raw::ContainsMod(const string& aFileName)
+{
+ return IsOurFile(aFileName);
+}
diff --git a/src/modplug/archive/arch_raw.cxx b/src/modplug/archive/arch_raw.cxx
deleted file mode 100644
index 86b1b6b25790..000000000000
--- a/src/modplug/archive/arch_raw.cxx
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal at gauge3d.org>
- *
- * This source code is public domain.
- */
-
-#include <cstdlib>
-
-#include "arch_raw.h"
-
-using namespace std;
-
-arch_Raw::arch_Raw(const string& aFileName)
-{
- mFileDesc = vfs_fopen(aFileName.c_str(), "r");
- if (!mFileDesc)
- {
- mSize = 0;
- return;
- }
-
- mSize = vfs_fsize(mFileDesc);
- if (mSize <= 0)
- {
- vfs_fclose(mFileDesc);
- mSize = 0;
- return;
- }
-
- mMap = malloc(mSize);
- if (vfs_fread(mMap, 1, mSize, mFileDesc) < mSize)
- {
- free(mMap);
- vfs_fclose(mFileDesc);
- mSize = 0;
- return;
- }
-}
-
-arch_Raw::~arch_Raw()
-{
- if(mSize != 0)
- {
- free(mMap);
- vfs_fclose(mFileDesc);
- }
-}
-
-bool arch_Raw::ContainsMod(const string& aFileName)
-{
- return IsOurFile(aFileName);
-}
diff --git a/src/modplug/archive/arch_raw.h b/src/modplug/archive/arch_raw.h
index d9cae8dabf4d..4942c9baf8bb 100644
--- a/src/modplug/archive/arch_raw.h
+++ b/src/modplug/archive/arch_raw.h
@@ -9,13 +9,11 @@
#include "archive.h"
-extern "C" {
#include <libaudcore/vfs.h>
-}
class arch_Raw: public Archive
{
- VFSFile *mFileDesc;
+ VFSFile mFileDesc;
public:
arch_Raw(const std::string& aFileName);
diff --git a/src/modplug/archive/archive.cc b/src/modplug/archive/archive.cc
new file mode 100644
index 000000000000..4bc67101c37a
--- /dev/null
+++ b/src/modplug/archive/archive.cc
@@ -0,0 +1,78 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal at gauge3d.org>
+ *
+ * This source code is public domain.
+ */
+
+#include "archive.h"
+
+using namespace std;
+
+///* Open a read pipe */ File f;
+//f=popen("gzip -d compressed.file.name","r");
+///* Read some data in the usual manner, for example */
+//fscanf(f,"%d %f %f",name,&age,$id);
+///* Close the pipe */
+//pclose(f);
+
+Archive::~Archive()
+{
+}
+
+bool Archive::IsOurFile(const string& aFileName)
+{
+ string lExt;
+ uint32_t lPos;
+
+ lPos = aFileName.find_last_of('.');
+ if((int)lPos == -1)
+ return false;
+ lExt = aFileName.substr(lPos);
+ for(uint32_t i = 0; i < lExt.length(); i++)
+ lExt[i] = tolower(lExt[i]);
+
+ if (lExt == ".669")
+ return true;
+ if (lExt == ".amf")
+ return true;
+ if (lExt == ".ams")
+ return true;
+ if (lExt == ".dbm")
+ return true;
+ if (lExt == ".dbf")
+ return true;
+ if (lExt == ".dsm")
+ return true;
+ if (lExt == ".far")
+ return true;
+ if (lExt == ".it")
+ return true;
+ if (lExt == ".mdl")
+ return true;
+ if (lExt == ".med")
+ return true;
+ if (lExt == ".mod")
+ return true;
+ if (lExt == ".mtm")
+ return true;
+ if (lExt == ".okt")
+ return true;
+ if (lExt == ".ptm")
+ return true;
+ if (lExt == ".s3m")
+ return true;
+ if (lExt == ".stm")
+ return true;
+ if (lExt == ".ult")
+ return true;
+ if (lExt == ".umx") //Unreal rocks!
+ return true;
+ if (lExt == ".xm")
+ return true;
+ if (lExt == ".mt2")
+ return true;
+ if (lExt == ".psm")
+ return true;
+
+ return false;
+}
diff --git a/src/modplug/archive/archive.cxx b/src/modplug/archive/archive.cxx
deleted file mode 100644
index 4bc67101c37a..000000000000
--- a/src/modplug/archive/archive.cxx
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal at gauge3d.org>
- *
- * This source code is public domain.
- */
-
-#include "archive.h"
-
-using namespace std;
-
-///* Open a read pipe */ File f;
-//f=popen("gzip -d compressed.file.name","r");
-///* Read some data in the usual manner, for example */
-//fscanf(f,"%d %f %f",name,&age,$id);
-///* Close the pipe */
-//pclose(f);
-
-Archive::~Archive()
-{
-}
-
-bool Archive::IsOurFile(const string& aFileName)
-{
- string lExt;
- uint32_t lPos;
-
- lPos = aFileName.find_last_of('.');
- if((int)lPos == -1)
- return false;
- lExt = aFileName.substr(lPos);
- for(uint32_t i = 0; i < lExt.length(); i++)
- lExt[i] = tolower(lExt[i]);
-
- if (lExt == ".669")
- return true;
- if (lExt == ".amf")
- return true;
- if (lExt == ".ams")
- return true;
- if (lExt == ".dbm")
- return true;
- if (lExt == ".dbf")
- return true;
- if (lExt == ".dsm")
- return true;
- if (lExt == ".far")
- return true;
- if (lExt == ".it")
- return true;
- if (lExt == ".mdl")
- return true;
- if (lExt == ".med")
- return true;
- if (lExt == ".mod")
- return true;
- if (lExt == ".mtm")
- return true;
- if (lExt == ".okt")
- return true;
- if (lExt == ".ptm")
- return true;
- if (lExt == ".s3m")
- return true;
- if (lExt == ".stm")
- return true;
- if (lExt == ".ult")
- return true;
- if (lExt == ".umx") //Unreal rocks!
- return true;
- if (lExt == ".xm")
- return true;
- if (lExt == ".mt2")
- return true;
- if (lExt == ".psm")
- return true;
-
- return false;
-}
diff --git a/src/modplug/archive/open.cc b/src/modplug/archive/open.cc
new file mode 100644
index 000000000000..5d3492e50821
--- /dev/null
+++ b/src/modplug/archive/open.cc
@@ -0,0 +1,15 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal at gauge3d.org>
+ *
+ * This source code is public domain.
+ */
+
+#include "open.h"
+#include "arch_raw.h"
+
+using namespace std;
+
+Archive* OpenArchive(const string& aFileName) //aFilename is url --yaz
+{
+ return new arch_Raw(aFileName);
+}
diff --git a/src/modplug/archive/open.cxx b/src/modplug/archive/open.cxx
deleted file mode 100644
index 5d3492e50821..000000000000
--- a/src/modplug/archive/open.cxx
+++ /dev/null
@@ -1,15 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal at gauge3d.org>
- *
- * This source code is public domain.
- */
-
-#include "open.h"
-#include "arch_raw.h"
-
-using namespace std;
-
-Archive* OpenArchive(const string& aFileName) //aFilename is url --yaz
-{
- return new arch_Raw(aFileName);
-}
diff --git a/src/modplug/modplugbmp.cc b/src/modplug/modplugbmp.cc
new file mode 100644
index 000000000000..ae8d8b505f77
--- /dev/null
+++ b/src/modplug/modplugbmp.cc
@@ -0,0 +1,401 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal at gauge3d.org>
+ *
+ * This source code is public domain.
+ */
+
+#include "modplugbmp.h"
+
+#include <fstream>
+#include <stdint.h>
+#include <sys/types.h>
+#include <math.h>
+
+#include <libmodplug/stdafx.h>
+#include <libmodplug/sndfile.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+
+#include "archive/open.h"
+
+using namespace std;
+
+// ModplugXMMS member functions ===============================
+
+bool ModplugXMMS::init ()
+{
+ load_settings ();
+ apply_settings ();
+ return true;
+}
+
+bool ModplugXMMS::is_our_file (const char * filename, VFSFile & file)
+{
+ string lExt;
+ uint32_t lPos;
+ const int magicSize = 32;
+ char magic[magicSize];
+
+ if (file.fread (magic, 1, magicSize) < magicSize)
+ return false;
+ if (!memcmp(magic, UMX_MAGIC, 4))
+ return true;
+ if (!memcmp(magic, "Extended Module:", 16))
+ return true;
+ if (!memcmp(magic, M669_MAGIC, 2))
+ return true;
+ if (!memcmp(magic, IT_MAGIC, 4))
+ return true;
+ if (!memcmp(magic, MTM_MAGIC, 4))
+ return true;
+ if (!memcmp(magic, PSM_MAGIC, 4))
+ return true;
+
+ if (file.fseek (44, VFS_SEEK_SET))
+ return false;
+ if (file.fread (magic, 1, 4) < 4)
+ return false;
+ if (!memcmp(magic, S3M_MAGIC, 4))
+ return true;
+
+ if (file.fseek (1080, VFS_SEEK_SET))
+ return false;
+ if (file.fread (magic, 1, 4) < 4)
+ return false;
+
+ // Check for Fast Tracker multichannel modules (xCHN, xxCH)
+ if (magic[1] == 'C' && magic[2] == 'H' && magic[3] == 'N') {
+ if (magic[0] == '6' || magic[0] == '8')
+ return true;
+ }
+ if (magic[2] == 'C' && magic[3] == 'H' && magic[0] >= '0' && magic[0] <= '9'
+ && magic[1] >= '0' && magic[1] <= '9') {
+ int nch = (magic[0] - '0') * 10 + (magic[1] - '0');
+ if ((nch % 2 == 0) && nch >= 10)
+ return true;
+ }
+
+ // Check for Amiga MOD module formats
+ if(mModProps.mGrabAmigaMOD) {
+ if (!memcmp(magic, MOD_MAGIC_PROTRACKER4, 4))
+ return true;
+ if (!memcmp(magic, MOD_MAGIC_PROTRACKER4X, 4))
+ return true;
+ if (!memcmp(magic, MOD_MAGIC_NOISETRACKER, 4))
+ return true;
+ if (!memcmp(magic, MOD_MAGIC_STARTRACKER4, 4))
+ return true;
+ if (!memcmp(magic, MOD_MAGIC_STARTRACKER8, 4))
+ return true;
+ if (!memcmp(magic, MOD_MAGIC_STARTRACKER4X, 4))
+ return true;
+ if (!memcmp(magic, MOD_MAGIC_STARTRACKER8X, 4))
+ return true;
+ if (!memcmp(magic, MOD_MAGIC_FASTTRACKER4, 4))
+ return true;
+ if (!memcmp(magic, MOD_MAGIC_OKTALYZER8, 4))
+ return true;
+ if (!memcmp(magic, MOD_MAGIC_OKTALYZER8X, 4))
+ return true;
+ if (!memcmp(magic, MOD_MAGIC_TAKETRACKER16, 4))
+ return true;
+ if (!memcmp(magic, MOD_MAGIC_TAKETRACKER32, 4))
+ return true;
+ } /* end of if(mModProps.mGrabAmigaMOD) */
+
+ /* We didn't find the magic bytes, fall back to extension check */
+ string aFilename = filename;
+ lPos = aFilename.find_last_of('.');
+ if((int)lPos == -1)
+ return false;
+ lExt = aFilename.substr(lPos);
+ for(uint32_t i = 0; i < lExt.length(); i++)
+ lExt[i] = tolower(lExt[i]);
+
+ if (lExt == ".amf")
+ return true;
+ if (lExt == ".ams")
+ return true;
+ if (lExt == ".dbm")
+ return true;
+ if (lExt == ".dbf")
+ return true;
+ if (lExt == ".dmf")
+ return true;
+ if (lExt == ".dsm")
+ return true;
+ if (lExt == ".far")
+ return true;
+ if (lExt == ".mdl")
+ return true;
+ if (lExt == ".stm")
+ return true;
+ if (lExt == ".ult")
+ return true;
+ if (lExt == ".mt2")
+ return true;
+
+ return false;
+}
+
+void ModplugXMMS::PlayLoop()
+{
+ uint32_t lLength;
+
+ while (! check_stop ())
+ {
+ int seek_time = check_seek ();
+ if (seek_time != -1)
+ mSoundFile->SetCurrentPos (seek_time * (int64_t)
+ mSoundFile->GetMaxPosition () / (mSoundFile->GetSongTime () * 1000));
+
+ lLength = mSoundFile->Read (mBuffer, mBufSize);
+
+ if (! lLength)
+ break;
+
+ if(mModProps.mPreamp)
+ {
+ //apply preamp
+ if(mModProps.mBits == 16)
+ {
+ unsigned n = mBufSize >> 1;
+ for(unsigned i = 0; i < n; i++) {
+ short old = ((short*)mBuffer)[i];
+ ((short*)mBuffer)[i] *= (short int)mPreampFactor;
+ // detect overflow and clip!
+ if ((old & 0x8000) !=
+ (((short*)mBuffer)[i] & 0x8000))
+ ((short*)mBuffer)[i] = old | 0x7FFF;
+
+ }
+ }
+ else
+ {
+ for(unsigned i = 0; i < mBufSize; i++) {
+ unsigned char old = ((unsigned char*)mBuffer)[i];
+ ((unsigned char*)mBuffer)[i] *= (short int)mPreampFactor;
+ // detect overflow and clip!
+ if ((old & 0x80) !=
+ (((unsigned char*)mBuffer)[i] & 0x80))
+ ((unsigned char*)mBuffer)[i] = old | 0x7F;
+ }
+ }
+ }
+
+ write_audio (mBuffer, mBufSize);
+ }
+}
+
+bool ModplugXMMS::play (const char * filename, VFSFile & file)
+{
+ //open and mmap the file
+ mArchive = OpenArchive(filename);
+ if(mArchive->Size() == 0)
+ {
+ delete mArchive;
+ return false;
+ }
+
+ mSoundFile = new CSoundFile;
+
+ //find buftime to get approx. 512 samples/block
+ mBufTime = 512000 / mModProps.mFrequency + 1;
+
+ mBufSize = mBufTime;
+ mBufSize *= mModProps.mFrequency;
+ mBufSize /= 1000; //milliseconds
+ mBufSize *= mModProps.mChannels;
+ mBufSize *= mModProps.mBits / 8;
+
+ mBuffer = new unsigned char[mBufSize];
+
+ CSoundFile::SetWaveConfig
+ (
+ mModProps.mFrequency,
+ mModProps.mBits,
+ mModProps.mChannels
+ );
+ CSoundFile::SetWaveConfigEx
+ (
+ mModProps.mSurround,
+ !mModProps.mOversamp,
+ mModProps.mReverb,
+ true,
+ mModProps.mMegabass,
+ mModProps.mNoiseReduction,
+ false
+ );
+
+ // [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms]
+ if(mModProps.mReverb)
+ {
+ CSoundFile::SetReverbParameters
+ (
+ mModProps.mReverbDepth,
+ mModProps.mReverbDelay
+ );
+ }
+ // [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100]
+ if(mModProps.mMegabass)
+ {
+ CSoundFile::SetXBassParameters
+ (
+ mModProps.mBassAmount,
+ mModProps.mBassRange
+ );
+ }
+ // [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms]
+ if(mModProps.mSurround)
+ {
+ CSoundFile::SetSurroundParameters
+ (
+ mModProps.mSurroundDepth,
+ mModProps.mSurroundDelay
+ );
+ }
+ CSoundFile::SetResamplingMode(mModProps.mResamplingMode);
+ mSoundFile->SetRepeatCount(mModProps.mLoopCount);
+ mPreampFactor = exp(mModProps.mPreampLevel);
+
+ mSoundFile->Create
+ (
+ (unsigned char*)mArchive->Map(),
+ mArchive->Size()
+ );
+
+ Tuple ti = read_tuple (filename, file);
+ if (ti)
+ set_playback_tuple (std::move (ti));
+
+ set_stream_bitrate(mSoundFile->GetNumChannels() * 1000);
+
+ int fmt = (mModProps.mBits == 16) ? FMT_S16_NE : FMT_U8;
+ open_audio(fmt, mModProps.mFrequency, mModProps.mChannels);
+
+ PlayLoop();
+
+ delete[] mBuffer;
+ mBuffer = nullptr;
+ delete mSoundFile;
+ mSoundFile = nullptr;
+ delete mArchive;
+ mArchive = nullptr;
+
+ return true;
+}
+
+Tuple ModplugXMMS::read_tuple (const char * filename, VFSFile & file)
+{
+ CSoundFile* lSoundFile;
+ Archive* lArchive;
+ const char *tmps;
+
+ //open and mmap the file
+ lArchive = OpenArchive(filename);
+ if(lArchive->Size() == 0)
+ {
+ delete lArchive;
+ return Tuple ();
+ }
+
+ Tuple ti;
+ ti.set_filename (filename);
+
+ lSoundFile = new CSoundFile;
+ lSoundFile->Create((unsigned char*)lArchive->Map(), lArchive->Size());
+
+ switch(lSoundFile->GetType())
+ {
+ case MOD_TYPE_MOD: tmps = "ProTracker"; break;
+ case MOD_TYPE_S3M: tmps = "Scream Tracker 3"; break;
+ case MOD_TYPE_XM: tmps = "Fast Tracker 2"; break;
+ case MOD_TYPE_IT: tmps = "Impulse Tracker"; break;
+ case MOD_TYPE_MED: tmps = "OctaMed"; break;
+ case MOD_TYPE_MTM: tmps = "MultiTracker Module"; break;
+ case MOD_TYPE_669: tmps = "669 Composer / UNIS 669"; break;
+ case MOD_TYPE_ULT: tmps = "Ultra Tracker"; break;
+ case MOD_TYPE_STM: tmps = "Scream Tracker"; break;
+ case MOD_TYPE_FAR: tmps = "Farandole"; break;
+ case MOD_TYPE_AMF: tmps = "ASYLUM Music Format"; break;
+ case MOD_TYPE_AMS: tmps = "AMS module"; break;
+ case MOD_TYPE_DSM: tmps = "DSIK Internal Format"; break;
+ case MOD_TYPE_MDL: tmps = "DigiTracker"; break;
+ case MOD_TYPE_OKT: tmps = "Oktalyzer"; break;
+ case MOD_TYPE_DMF: tmps = "Delusion Digital Music Fileformat (X-Tracker)"; break;
+ case MOD_TYPE_PTM: tmps = "PolyTracker"; break;
+ case MOD_TYPE_DBM: tmps = "DigiBooster Pro"; break;
+ case MOD_TYPE_MT2: tmps = "MadTracker 2"; break;
+ case MOD_TYPE_AMF0: tmps = "AMF0"; break;
+ case MOD_TYPE_PSM: tmps = "Protracker Studio Module"; break;
+ default: tmps = "ModPlug unknown"; break;
+ }
+ ti.set_str (Tuple::Codec, tmps);
+ ti.set_str (Tuple::Quality, _("sequenced"));
+ ti.set_int (Tuple::Length, lSoundFile->GetSongTime() * 1000);
+
+ const char *tmps2 = lSoundFile->GetTitle();
+ // Chop any leading spaces off. They are annoying in the playlist.
+ while (tmps2[0] == ' ')
+ tmps2++;
+ if (tmps2[0])
+ ti.set_str(Tuple::Title, tmps2);
+
+ //unload the file
+ lSoundFile->Destroy();
+ delete lSoundFile;
+ delete lArchive;
+ return ti;
+}
+
+void ModplugXMMS::apply_settings ()
+{
+ // [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms]
+ if(mModProps.mReverb)
+ {
+ CSoundFile::SetReverbParameters
+ (
+ mModProps.mReverbDepth,
+ mModProps.mReverbDelay
+ );
+ }
+ // [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100]
+ if(mModProps.mMegabass)
+ {
+ CSoundFile::SetXBassParameters
+ (
+ mModProps.mBassAmount,
+ mModProps.mBassRange
+ );
+ }
+ else //modplug seems to ignore the SetWaveConfigEx() setting for bass boost
+ {
+ CSoundFile::SetXBassParameters
+ (
+ 0,
+ 0
+ );
+ }
+ // [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms]
+ if(mModProps.mSurround)
+ {
+ CSoundFile::SetSurroundParameters
+ (
+ mModProps.mSurroundDepth,
+ mModProps.mSurroundDelay
+ );
+ }
+ CSoundFile::SetWaveConfigEx
+ (
+ mModProps.mSurround,
+ !mModProps.mOversamp,
+ mModProps.mReverb,
+ true,
+ mModProps.mMegabass,
+ mModProps.mNoiseReduction,
+ false
+ );
+ CSoundFile::SetResamplingMode(mModProps.mResamplingMode);
+ mPreampFactor = exp(mModProps.mPreampLevel);
+}
diff --git a/src/modplug/modplugbmp.cxx b/src/modplug/modplugbmp.cxx
deleted file mode 100644
index 2e7eacd1a49c..000000000000
--- a/src/modplug/modplugbmp.cxx
+++ /dev/null
@@ -1,414 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal at gauge3d.org>
- *
- * This source code is public domain.
- */
-
-#include "modplugbmp.h"
-
-#include <fstream>
-#include <stdint.h>
-#include <sys/types.h>
-#include <math.h>
-
-#include <glib.h>
-
-#include <libmodplug/stdafx.h>
-#include <libmodplug/sndfile.h>
-
-extern "C" {
-#include <libaudcore/audstrings.h>
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-}
-
-#include "archive/open.h"
-
-using namespace std;
-
-// ModplugXMMS member functions ===============================
-
-ModplugXMMS::ModplugXMMS()
-{
- memset (this, 0, sizeof (* this));
- mSoundFile = new CSoundFile;
-}
-
-ModplugXMMS::~ModplugXMMS()
-{
- delete mSoundFile;
-}
-
-bool ModplugXMMS::CanPlayFileFromVFS(const string& aFilename, VFSFile *file)
-{
- string lExt;
- uint32_t lPos;
- const int magicSize = 32;
- char magic[magicSize];
-
- if (vfs_fread(magic, 1, magicSize, file) < magicSize)
- return false;
- if (!memcmp(magic, UMX_MAGIC, 4))
- return true;
- if (!memcmp(magic, "Extended Module:", 16))
- return true;
- if (!memcmp(magic, M669_MAGIC, 2))
- return true;
- if (!memcmp(magic, IT_MAGIC, 4))
- return true;
- if (!memcmp(magic, MTM_MAGIC, 4))
- return true;
- if (!memcmp(magic, PSM_MAGIC, 4))
- return true;
-
- if (vfs_fseek(file, 44, SEEK_SET))
- return false;
- if (vfs_fread(magic, 1, 4, file) < 4)
- return false;
- if (!memcmp(magic, S3M_MAGIC, 4))
- return true;
-
- if (vfs_fseek(file, 1080, SEEK_SET))
- return false;
- if (vfs_fread(magic, 1, 4, file) < 4)
- return false;
-
- // Check for Fast Tracker multichannel modules (xCHN, xxCH)
- if (magic[1] == 'C' && magic[2] == 'H' && magic[3] == 'N') {
- if (magic[0] == '6' || magic[0] == '8')
- return true;
- }
- if (magic[2] == 'C' && magic[3] == 'H' && g_ascii_isdigit(magic[0]) && g_ascii_isdigit(magic[1])) {
- int nch = (magic[0] - '0') * 10 + (magic[1] - '0');
- if ((nch % 2 == 0) && nch >= 10)
- return true;
- }
-
- // Check for Amiga MOD module formats
- if(mModProps.mGrabAmigaMOD) {
- if (!memcmp(magic, MOD_MAGIC_PROTRACKER4, 4))
- return true;
- if (!memcmp(magic, MOD_MAGIC_PROTRACKER4X, 4))
- return true;
- if (!memcmp(magic, MOD_MAGIC_NOISETRACKER, 4))
- return true;
- if (!memcmp(magic, MOD_MAGIC_STARTRACKER4, 4))
- return true;
- if (!memcmp(magic, MOD_MAGIC_STARTRACKER8, 4))
- return true;
- if (!memcmp(magic, MOD_MAGIC_STARTRACKER4X, 4))
- return true;
- if (!memcmp(magic, MOD_MAGIC_STARTRACKER8X, 4))
- return true;
- if (!memcmp(magic, MOD_MAGIC_FASTTRACKER4, 4))
- return true;
- if (!memcmp(magic, MOD_MAGIC_OKTALYZER8, 4))
- return true;
- if (!memcmp(magic, MOD_MAGIC_OKTALYZER8X, 4))
- return true;
- if (!memcmp(magic, MOD_MAGIC_TAKETRACKER16, 4))
- return true;
- if (!memcmp(magic, MOD_MAGIC_TAKETRACKER32, 4))
- return true;
- } /* end of if(mModProps.mGrabAmigaMOD) */
-
- /* We didn't find the magic bytes, fall back to extension check */
- lPos = aFilename.find_last_of('.');
- if((int)lPos == -1)
- return false;
- lExt = aFilename.substr(lPos);
- for(uint32_t i = 0; i < lExt.length(); i++)
- lExt[i] = tolower(lExt[i]);
-
- if (lExt == ".amf")
- return true;
- if (lExt == ".ams")
- return true;
- if (lExt == ".dbm")
- return true;
- if (lExt == ".dbf")
- return true;
- if (lExt == ".dmf")
- return true;
- if (lExt == ".dsm")
- return true;
- if (lExt == ".far")
- return true;
- if (lExt == ".mdl")
- return true;
- if (lExt == ".stm")
- return true;
- if (lExt == ".ult")
- return true;
- if (lExt == ".mt2")
- return true;
-
- return false;
-}
-
-void ModplugXMMS::PlayLoop()
-{
- uint32_t lLength;
-
- while (! aud_input_check_stop ())
- {
- int seek_time = aud_input_check_seek ();
- if (seek_time != -1)
- mSoundFile->SetCurrentPos (seek_time * (int64_t)
- mSoundFile->GetMaxPosition () / (mSoundFile->GetSongTime () * 1000));
-
- lLength = mSoundFile->Read (mBuffer, mBufSize);
-
- if (! lLength)
- break;
-
- if(mModProps.mPreamp)
- {
- //apply preamp
- if(mModProps.mBits == 16)
- {
- unsigned n = mBufSize >> 1;
- for(unsigned i = 0; i < n; i++) {
- short old = ((short*)mBuffer)[i];
- ((short*)mBuffer)[i] *= (short int)mPreampFactor;
- // detect overflow and clip!
- if ((old & 0x8000) !=
- (((short*)mBuffer)[i] & 0x8000))
- ((short*)mBuffer)[i] = old | 0x7FFF;
-
- }
- }
- else
- {
- for(unsigned i = 0; i < mBufSize; i++) {
- unsigned char old = ((unsigned char*)mBuffer)[i];
- ((unsigned char*)mBuffer)[i] *= (short int)mPreampFactor;
- // detect overflow and clip!
- if ((old & 0x80) !=
- (((unsigned char*)mBuffer)[i] & 0x80))
- ((unsigned char*)mBuffer)[i] = old | 0x7F;
- }
- }
- }
-
- aud_input_write_audio (mBuffer, mBufSize);
- }
-
- //Unload the file
- mSoundFile->Destroy();
- delete mArchive;
-
- if (mBuffer)
- {
- delete [] mBuffer;
- mBuffer = NULL;
- }
-}
-
-bool ModplugXMMS::PlayFile(const string& aFilename)
-{
- //open and mmap the file
- mArchive = OpenArchive(aFilename);
- if(mArchive->Size() == 0)
- {
- delete mArchive;
- return false;
- }
-
- if (mBuffer)
- delete [] mBuffer;
-
- //find buftime to get approx. 512 samples/block
- mBufTime = 512000 / mModProps.mFrequency + 1;
-
- mBufSize = mBufTime;
- mBufSize *= mModProps.mFrequency;
- mBufSize /= 1000; //milliseconds
- mBufSize *= mModProps.mChannels;
- mBufSize *= mModProps.mBits / 8;
-
- mBuffer = new unsigned char[mBufSize];
- if(!mBuffer)
- return false; //out of memory!
-
- CSoundFile::SetWaveConfig
- (
- mModProps.mFrequency,
- mModProps.mBits,
- mModProps.mChannels
- );
- CSoundFile::SetWaveConfigEx
- (
- mModProps.mSurround,
- !mModProps.mOversamp,
- mModProps.mReverb,
- true,
- mModProps.mMegabass,
- mModProps.mNoiseReduction,
- false
- );
-
- // [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms]
- if(mModProps.mReverb)
- {
- CSoundFile::SetReverbParameters
- (
- mModProps.mReverbDepth,
- mModProps.mReverbDelay
- );
- }
- // [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100]
- if(mModProps.mMegabass)
- {
- CSoundFile::SetXBassParameters
- (
- mModProps.mBassAmount,
- mModProps.mBassRange
- );
- }
- // [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms]
- if(mModProps.mSurround)
- {
- CSoundFile::SetSurroundParameters
- (
- mModProps.mSurroundDepth,
- mModProps.mSurroundDelay
- );
- }
- CSoundFile::SetResamplingMode(mModProps.mResamplingMode);
- mSoundFile->SetRepeatCount(mModProps.mLoopCount);
- mPreampFactor = exp(mModProps.mPreampLevel);
-
- mSoundFile->Create
- (
- (unsigned char*)mArchive->Map(),
- mArchive->Size()
- );
-
- Tuple* ti = GetSongTuple( aFilename );
- if ( ti ) {
- aud_input_set_tuple(ti);
- }
-
- aud_input_set_bitrate(mSoundFile->GetNumChannels() * 1000);
-
- int fmt = (mModProps.mBits == 16) ? FMT_S16_NE : FMT_U8;
- if (! aud_input_open_audio(fmt, mModProps.mFrequency, mModProps.mChannels))
- return false;
-
- PlayLoop();
-
- return true;
-}
-
-Tuple* ModplugXMMS::GetSongTuple(const string& aFilename)
-{
- CSoundFile* lSoundFile;
- Archive* lArchive;
- const char *tmps;
-
- //open and mmap the file
- lArchive = OpenArchive(aFilename);
- if(lArchive->Size() == 0)
- {
- delete lArchive;
- return NULL;
- }
-
- Tuple *ti = tuple_new_from_filename(aFilename.c_str());
- lSoundFile = new CSoundFile;
- lSoundFile->Create((unsigned char*)lArchive->Map(), lArchive->Size());
-
- switch(lSoundFile->GetType())
- {
- case MOD_TYPE_MOD: tmps = "ProTracker"; break;
- case MOD_TYPE_S3M: tmps = "Scream Tracker 3"; break;
- case MOD_TYPE_XM: tmps = "Fast Tracker 2"; break;
- case MOD_TYPE_IT: tmps = "Impulse Tracker"; break;
- case MOD_TYPE_MED: tmps = "OctaMed"; break;
- case MOD_TYPE_MTM: tmps = "MultiTracker Module"; break;
- case MOD_TYPE_669: tmps = "669 Composer / UNIS 669"; break;
- case MOD_TYPE_ULT: tmps = "Ultra Tracker"; break;
- case MOD_TYPE_STM: tmps = "Scream Tracker"; break;
- case MOD_TYPE_FAR: tmps = "Farandole"; break;
- case MOD_TYPE_AMF: tmps = "ASYLUM Music Format"; break;
- case MOD_TYPE_AMS: tmps = "AMS module"; break;
- case MOD_TYPE_DSM: tmps = "DSIK Internal Format"; break;
- case MOD_TYPE_MDL: tmps = "DigiTracker"; break;
- case MOD_TYPE_OKT: tmps = "Oktalyzer"; break;
- case MOD_TYPE_DMF: tmps = "Delusion Digital Music Fileformat (X-Tracker)"; break;
- case MOD_TYPE_PTM: tmps = "PolyTracker"; break;
- case MOD_TYPE_DBM: tmps = "DigiBooster Pro"; break;
- case MOD_TYPE_MT2: tmps = "MadTracker 2"; break;
- case MOD_TYPE_AMF0: tmps = "AMF0"; break;
- case MOD_TYPE_PSM: tmps = "Protracker Studio Module"; break;
- default: tmps = "ModPlug unknown"; break;
- }
- tuple_set_str(ti, FIELD_CODEC, tmps);
- tuple_set_str(ti, FIELD_QUALITY, _("sequenced"));
- tuple_set_int(ti, FIELD_LENGTH, lSoundFile->GetSongTime() * 1000);
-
- const char *tmps2 = lSoundFile->GetTitle();
- // Chop any leading spaces off. They are annoying in the playlist.
- while ( *tmps2 == ' ' ) tmps2++ ;
- tuple_set_str(ti, FIELD_TITLE, tmps2);
-
- //unload the file
- lSoundFile->Destroy();
- delete lSoundFile;
- delete lArchive;
- return ti;
-}
-
-void ModplugXMMS::SetModProps(const ModplugSettings& aModProps)
-{
- mModProps = aModProps;
-
- // [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms]
- if(mModProps.mReverb)
- {
- CSoundFile::SetReverbParameters
- (
- mModProps.mReverbDepth,
- mModProps.mReverbDelay
- );
- }
- // [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100]
- if(mModProps.mMegabass)
- {
- CSoundFile::SetXBassParameters
- (
- mModProps.mBassAmount,
- mModProps.mBassRange
- );
- }
- else //modplug seems to ignore the SetWaveConfigEx() setting for bass boost
- {
- CSoundFile::SetXBassParameters
- (
- 0,
- 0
- );
- }
- // [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms]
- if(mModProps.mSurround)
- {
- CSoundFile::SetSurroundParameters
- (
- mModProps.mSurroundDepth,
- mModProps.mSurroundDelay
- );
- }
- CSoundFile::SetWaveConfigEx
- (
- mModProps.mSurround,
- !mModProps.mOversamp,
- mModProps.mReverb,
- true,
- mModProps.mMegabass,
- mModProps.mNoiseReduction,
- false
- );
- CSoundFile::SetResamplingMode(mModProps.mResamplingMode);
- mPreampFactor = exp(mModProps.mPreampLevel);
-}
diff --git a/src/modplug/modplugbmp.h b/src/modplug/modplugbmp.h
index 63af9fc5a3c3..c2887ceb9865 100644
--- a/src/modplug/modplugbmp.h
+++ b/src/modplug/modplugbmp.h
@@ -7,11 +7,8 @@
#ifndef __MODPLUGXMMS_CMODPLUGXMMS_H_INCLUDED__
#define __MODPLUGXMMS_CMODPLUGXMMS_H_INCLUDED__
-#include <string>
-
-extern "C" {
-#include <audacious/plugin.h>
-}
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
#include "settings.h"
@@ -42,32 +39,49 @@ extern "C" {
class CSoundFile;
class Archive;
-class ModplugXMMS
+struct PreferencesWidget;
+
+class ModplugXMMS : public InputPlugin
{
public:
- ModplugXMMS();
- ~ModplugXMMS();
+ static const char * const exts[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
- bool CanPlayFileFromVFS(const std::string& aFilename, VFSFile *file);
+ static constexpr PluginInfo info = {
+ N_("ModPlug (Module Player)"),
+ PACKAGE,
+ nullptr,
+ & prefs
+ };
- bool PlayFile(const std::string& aFilename);
+ static constexpr auto iinfo = InputInfo (FlagSubtunes)
+ .with_exts (exts);
- Tuple* GetSongTuple(const std::string& aFilename);
+ constexpr ModplugXMMS () : InputPlugin (info, iinfo) {}
- void SetModProps(const ModplugSettings& aModProps);
+ bool init ();
+
+ bool is_our_file (const char * filename, VFSFile & file);
+ Tuple read_tuple (const char * filename, VFSFile & file);
+ bool play (const char * filename, VFSFile & file);
private:
- unsigned char* mBuffer;
- uint32_t mBufSize;
+ unsigned char * mBuffer = nullptr;
+ uint32_t mBufSize = 0;
+
+ ModplugSettings mModProps {};
- ModplugSettings mModProps;
+ uint32_t mBufTime = 0; // milliseconds
- uint32_t mBufTime; //milliseconds
+ CSoundFile * mSoundFile = nullptr;
+ Archive * mArchive = nullptr;
- CSoundFile* mSoundFile;
- Archive* mArchive;
+ float mPreampFactor = 0;
- float mPreampFactor;
+ void load_settings ();
+ void apply_settings ();
void PlayLoop();
};
diff --git a/src/modplug/plugin.cxx b/src/modplug/plugin.cxx
deleted file mode 100644
index a7a182f3db03..000000000000
--- a/src/modplug/plugin.cxx
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal at gauge3d.org>
- *
- * This source code is public domain.
- */
-
-#include "plugin.h"
-#include "modplugbmp.h"
-
-static ModplugXMMS gModplugXMMS;
-
-extern "C" {
-
-void InitSettings (const ModplugSettings * settings)
-{
- gModplugXMMS.SetModProps (* settings);
-}
-
-int CanPlayFileFromVFS(const char* aFilename, VFSFile *VFSFile)
-{
- if(gModplugXMMS.CanPlayFileFromVFS(aFilename, VFSFile))
- return 1;
- return 0;
-}
-
-bool_t PlayFile(const char * filename, VFSFile * file)
-{
- return gModplugXMMS.PlayFile(filename);
-}
-
-Tuple* GetSongTuple(const char* aFilename, VFSFile *fd)
-{
- return gModplugXMMS.GetSongTuple(aFilename);
-}
-
-} /* extern "C" */
diff --git a/src/modplug/plugin.h b/src/modplug/plugin.h
deleted file mode 100644
index e4b5698871f3..000000000000
--- a/src/modplug/plugin.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef MODPLUG_PLUGIN_H
-#define MODPLUG_PLUGIN_H
-
-#include "settings.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <audacious/plugin.h>
-
-void InitSettings (const ModplugSettings * settings);
-int CanPlayFileFromVFS (const char * filename, VFSFile * file);
-bool_t PlayFile (const char * filename, VFSFile * file);
-Tuple * GetSongTuple (const char * filename, VFSFile * file);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* MODPLUG_PLUGIN_H */
diff --git a/src/modplug/plugin_main.c b/src/modplug/plugin_main.c
deleted file mode 100644
index a24aafbcd3ab..000000000000
--- a/src/modplug/plugin_main.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Modplug Audacious Plugin
- *
- * Configuration GUI contributed in part by Vladimir Strakh.
- *
- * This source code is public domain.
- */
-
-#include "plugin.h"
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-#define MODPLUG_CFGID "modplug"
-
-static const char * fmts[] =
- { "amf", "ams", "dbm", "dbf", "dsm", "far", "mdl", "stm", "ult", "mt2",
- "mod", "s3m", "dmf", "umx", "it", "669", "xm", "mtm", "psm", "ft2",
- NULL };
-
-static const char * const modplug_defaults[] = {
- "Bits", "16",
- "Channels", "2",
- "ResamplingMode", "3", /* SRCMODE_POLYPHASE */
- "Frequency", "44100",
-
- "Reverb", "FALSE",
- "ReverbDepth", "30",
- "ReverbDelay", "100",
-
- "Megabass", "FALSE",
- "BassAmount", "40",
- "BassRange", "30",
-
- "Surround", "TRUE",
- "SurroundDepth", "20",
- "SurroundDelay", "20",
-
- "PreAmp", "FALSE",
- "PreAmpLevel", "0",
-
- "Oversampling", "TRUE",
- "NoiseReduction", "TRUE",
- "GrabAmigaMOD", "TRUE",
- "LoopCount", "0",
-
- NULL
-};
-
-static ModplugSettings modplug_settings;
-
-static const PreferencesWidget quality_widgets[] = {
- {WIDGET_LABEL, N_("<b>Resolution</b>")},
- {WIDGET_RADIO_BTN, N_("8-bit"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mBits, .data = {.radio_btn = {8}}},
- {WIDGET_RADIO_BTN, N_("16-bit"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mBits, .data = {.radio_btn = {16}}},
- {WIDGET_LABEL, N_("<b>Channels</b>")},
- {WIDGET_RADIO_BTN, N_("Mono"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mChannels, .data = {.radio_btn = {1}}},
- {WIDGET_RADIO_BTN, N_("Stereo"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mChannels, .data = {.radio_btn = {2}}},
- {WIDGET_LABEL, N_("<b>Resampling</b>")},
- {WIDGET_RADIO_BTN, N_("Nearest (fastest)"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mResamplingMode, .data = {.radio_btn = {0}}},
- {WIDGET_RADIO_BTN, N_("Linear (fast)"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mResamplingMode, .data = {.radio_btn = {1}}},
- {WIDGET_RADIO_BTN, N_("Spline (good)"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mResamplingMode, .data = {.radio_btn = {2}}},
- {WIDGET_RADIO_BTN, N_("Polyphase (best)"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mResamplingMode, .data = {.radio_btn = {3}}},
- {WIDGET_LABEL, N_("<b>Sampling rate</b>")},
- {WIDGET_RADIO_BTN, N_("22 kHz"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mFrequency, .data = {.radio_btn = {22050}}},
- {WIDGET_RADIO_BTN, N_("44 kHz"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mFrequency, .data = {.radio_btn = {44100}}},
- {WIDGET_RADIO_BTN, N_("48 kHz"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mFrequency, .data = {.radio_btn = {48000}}},
- {WIDGET_RADIO_BTN, N_("96 kHz"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mFrequency, .data = {.radio_btn = {96000}}}
-};
-
-static PreferencesWidget reverb_fields[] = {
- {WIDGET_SPIN_BTN, N_("Level:"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mReverbDepth, .data = {.spin_btn = {0, 100, 1, "%"}}},
- {WIDGET_SPIN_BTN, N_("Delay:"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mReverbDelay, .data = {.spin_btn = {40, 200, 1, N_("ms")}}}
-};
-
-static PreferencesWidget bass_fields[] = {
- {WIDGET_SPIN_BTN, N_("Level:"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mBassAmount, .data = {.spin_btn = {0, 100, 1, "%"}}},
- {WIDGET_SPIN_BTN, N_("Cutoff:"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mBassRange, .data = {.spin_btn = {10, 100, 1, N_("Hz")}}}
-};
-
-static PreferencesWidget surround_fields[] = {
- {WIDGET_SPIN_BTN, N_("Level:"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mSurroundDepth, .data = {.spin_btn = {0, 100, 1, "%"}}},
- {WIDGET_SPIN_BTN, N_("Delay:"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mSurroundDelay, .data = {.spin_btn = {5, 40, 1, N_("ms")}}}
-};
-
-static PreferencesWidget preamp_fields[] = {
- {WIDGET_SPIN_BTN, N_("Volume:"), .cfg_type = VALUE_FLOAT,
- .cfg = & modplug_settings.mPreampLevel, .data = {.spin_btn = {-3, 3, 0.1}}},
-};
-
-static const PreferencesWidget effects_widgets[] = {
- {WIDGET_LABEL, N_("<b>Reverb</b>")},
- {WIDGET_CHK_BTN, N_("Enable"), .cfg_type = VALUE_BOOLEAN,
- .cfg = & modplug_settings.mReverb},
- {WIDGET_TABLE, .child = TRUE, .data = {.table = {reverb_fields, ARRAY_LEN (reverb_fields)}}},
- {WIDGET_LABEL, N_("<b>Bass Boost</b>")},
- {WIDGET_CHK_BTN, N_("Enable"), .cfg_type = VALUE_BOOLEAN,
- .cfg = & modplug_settings.mMegabass },
- {WIDGET_TABLE, .child = TRUE, .data = {.table = {bass_fields, ARRAY_LEN (bass_fields)}}},
- {WIDGET_LABEL, N_("<b>Surround</b>")},
- {WIDGET_CHK_BTN, N_("Enable"), .cfg_type = VALUE_BOOLEAN,
- .cfg = & modplug_settings.mSurround },
- {WIDGET_TABLE, .child = TRUE, .data = {.table = {surround_fields, ARRAY_LEN (surround_fields)}}},
- {WIDGET_LABEL, N_("<b>Preamp</b>")},
- {WIDGET_CHK_BTN, N_("Enable"), .cfg_type = VALUE_BOOLEAN,
- .cfg = & modplug_settings.mPreamp },
- {WIDGET_TABLE, .child = TRUE, .data = {.table = {preamp_fields, ARRAY_LEN (preamp_fields)}}}
-};
-
-static const PreferencesWidget misc_widgets[] = {
- {WIDGET_LABEL, N_("<b>Miscellaneous</b>")},
- {WIDGET_CHK_BTN, N_("Oversample"), .cfg_type = VALUE_BOOLEAN,
- .cfg = & modplug_settings.mOversamp},
- {WIDGET_CHK_BTN, N_("Noise reduction"), .cfg_type = VALUE_BOOLEAN,
- .cfg = & modplug_settings.mNoiseReduction},
- {WIDGET_CHK_BTN, N_("Play Amiga MODs"), .cfg_type = VALUE_BOOLEAN,
- .cfg = & modplug_settings.mGrabAmigaMOD},
- {WIDGET_LABEL, N_("<b>Repeat</b>")},
- {WIDGET_SPIN_BTN, N_("Repeat count:"), .cfg_type = VALUE_INT,
- .cfg = & modplug_settings.mLoopCount, .data = {.spin_btn = {-1, 100, 1}}},
- {WIDGET_LABEL, N_("To repeat forever, set the repeat count to -1.")}
-};
-
-static const PreferencesWidget modplug_columns[] = {
- {WIDGET_BOX, .data = {.box = {quality_widgets, ARRAY_LEN (quality_widgets)}}},
- {WIDGET_SEPARATOR},
- {WIDGET_BOX, .data = {.box = {effects_widgets, ARRAY_LEN (effects_widgets)}}},
- {WIDGET_SEPARATOR},
- {WIDGET_BOX, .data = {.box = {misc_widgets, ARRAY_LEN (misc_widgets)}}}
-};
-
-static const PreferencesWidget modplug_widgets[] = {
- {WIDGET_BOX, .data = {.box = {modplug_columns, ARRAY_LEN (modplug_columns), .horizontal = TRUE}}}
-};
-
-static void modplug_settings_load ()
-{
- aud_config_set_defaults (MODPLUG_CFGID, modplug_defaults);
-
- modplug_settings.mBits = aud_get_int (MODPLUG_CFGID, "Bits");
- modplug_settings.mChannels = aud_get_int (MODPLUG_CFGID, "Channels");
- modplug_settings.mResamplingMode = aud_get_int (MODPLUG_CFGID, "ResamplingMode");
- modplug_settings.mFrequency = aud_get_int (MODPLUG_CFGID, "Frequency");
-
- modplug_settings.mReverb = aud_get_bool (MODPLUG_CFGID, "Reverb");
- modplug_settings.mReverbDepth = aud_get_int (MODPLUG_CFGID, "ReverbDepth");
- modplug_settings.mReverbDelay = aud_get_int (MODPLUG_CFGID, "ReverbDelay");
-
- modplug_settings.mMegabass = aud_get_bool (MODPLUG_CFGID, "Megabass");
- modplug_settings.mBassAmount = aud_get_int (MODPLUG_CFGID, "BassAmount");
- modplug_settings.mBassRange = aud_get_int (MODPLUG_CFGID, "BassRange");
-
- modplug_settings.mSurround = aud_get_bool (MODPLUG_CFGID, "Surround");
- modplug_settings.mSurroundDepth = aud_get_int (MODPLUG_CFGID, "SurroundDepth");
- modplug_settings.mSurroundDelay = aud_get_int (MODPLUG_CFGID, "SurroundDelay");
-
- modplug_settings.mPreamp = aud_get_bool (MODPLUG_CFGID, "PreAmp");
- modplug_settings.mPreampLevel = aud_get_double (MODPLUG_CFGID, "PreAmpLevel");
-
- modplug_settings.mOversamp = aud_get_bool (MODPLUG_CFGID, "Oversampling");
- modplug_settings.mNoiseReduction = aud_get_bool (MODPLUG_CFGID, "NoiseReduction");
- modplug_settings.mGrabAmigaMOD = aud_get_bool (MODPLUG_CFGID, "GrabAmigaMOD");
- modplug_settings.mLoopCount = aud_get_int (MODPLUG_CFGID, "LoopCount");
-}
-
-static void modplug_settings_save ()
-{
- aud_set_int (MODPLUG_CFGID, "Bits", modplug_settings.mBits);
- aud_set_int (MODPLUG_CFGID, "Channels", modplug_settings.mChannels);
- aud_set_int (MODPLUG_CFGID, "ResamplingMode", modplug_settings.mResamplingMode);
- aud_set_int (MODPLUG_CFGID, "Frequency", modplug_settings.mFrequency);
-
- aud_set_bool (MODPLUG_CFGID, "Reverb", modplug_settings.mReverb);
- aud_set_int (MODPLUG_CFGID, "ReverbDepth", modplug_settings.mReverbDepth);
- aud_set_int (MODPLUG_CFGID, "ReverbDelay", modplug_settings.mReverbDelay);
-
- aud_set_bool (MODPLUG_CFGID, "Megabass", modplug_settings.mMegabass);
- aud_set_int (MODPLUG_CFGID, "BassAmount", modplug_settings.mBassAmount);
- aud_set_int (MODPLUG_CFGID, "BassRange", modplug_settings.mBassRange);
-
- aud_set_bool (MODPLUG_CFGID, "Surround", modplug_settings.mSurround);
- aud_set_int (MODPLUG_CFGID, "SurroundDepth", modplug_settings.mSurroundDepth);
- aud_set_int (MODPLUG_CFGID, "SurroundDelay", modplug_settings.mSurroundDelay);
-
- aud_set_bool (MODPLUG_CFGID, "PreAmp", modplug_settings.mPreamp);
- aud_set_double (MODPLUG_CFGID, "PreAmpLevel", modplug_settings.mPreampLevel);
-
- aud_set_bool (MODPLUG_CFGID, "Oversampling", modplug_settings.mOversamp);
- aud_set_bool (MODPLUG_CFGID, "NoiseReduction", modplug_settings.mNoiseReduction);
- aud_set_bool (MODPLUG_CFGID, "GrabAmigaMOD", modplug_settings.mGrabAmigaMOD);
- aud_set_int (MODPLUG_CFGID, "LoopCount", modplug_settings.mLoopCount);
-}
-
-static bool_t modplug_init (void)
-{
- modplug_settings_load ();
- InitSettings (& modplug_settings);
- return TRUE;
-}
-
-static void modplug_settings_apply (void)
-{
- InitSettings (& modplug_settings);
- modplug_settings_save ();
-}
-
-static const PluginPreferences modplug_prefs = {
- .widgets = modplug_widgets,
- .n_widgets = ARRAY_LEN (modplug_widgets),
- .init = modplug_settings_load,
- .apply = modplug_settings_apply
-};
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("ModPlug (Module Player)"),
- .domain = PACKAGE,
- .prefs = &modplug_prefs,
- .init = modplug_init,
- .play = PlayFile,
- .probe_for_tuple = GetSongTuple,
- .is_our_file_from_vfs = CanPlayFileFromVFS,
- .extensions = fmts,
- .have_subtune = TRUE, // to exclude .zip etc which doesn't contain any mod file --yaz
-)
diff --git a/src/modplug/plugin_main.cc b/src/modplug/plugin_main.cc
new file mode 100644
index 000000000000..6d22ea4e2373
--- /dev/null
+++ b/src/modplug/plugin_main.cc
@@ -0,0 +1,158 @@
+/*
+ * Modplug Audacious Plugin
+ *
+ * Configuration GUI contributed in part by Vladimir Strakh.
+ *
+ * This source code is public domain.
+ */
+
+#include "modplugbmp.h"
+
+#include <libaudcore/runtime.h>
+#include <libaudcore/preferences.h>
+
+#define MODPLUG_CFGID "modplug"
+
+EXPORT ModplugXMMS aud_plugin_instance;
+
+const char * const ModplugXMMS::exts[] =
+ { "amf", "ams", "dbm", "dbf", "dsm", "far", "mdl", "stm", "ult", "mt2",
+ "mod", "s3m", "dmf", "umx", "it", "669", "xm", "mtm", "psm", "ft2",
+ nullptr };
+
+const char * const ModplugXMMS::defaults[] = {
+ "Bits", "16",
+ "Channels", "2",
+ "ResamplingMode", "3", /* SRCMODE_POLYPHASE */
+ "Frequency", "44100",
+
+ "Reverb", "FALSE",
+ "ReverbDepth", "30",
+ "ReverbDelay", "100",
+
+ "Megabass", "FALSE",
+ "BassAmount", "40",
+ "BassRange", "30",
+
+ "Surround", "TRUE",
+ "SurroundDepth", "20",
+ "SurroundDelay", "20",
+
+ "PreAmp", "FALSE",
+ "PreAmpLevel", "0",
+
+ "Oversampling", "TRUE",
+ "NoiseReduction", "TRUE",
+ "GrabAmigaMOD", "TRUE",
+ "LoopCount", "0",
+
+ nullptr
+};
+
+static const PreferencesWidget quality_widgets[] = {
+ WidgetLabel (N_("<b>Resolution</b>")),
+ WidgetRadio (N_("8-bit"), WidgetInt (MODPLUG_CFGID, "Bits"), {8}),
+ WidgetRadio (N_("16-bit"), WidgetInt (MODPLUG_CFGID, "Bits"), {16}),
+ WidgetLabel (N_("<b>Channels</b>")),
+ WidgetRadio (N_("Mono"), WidgetInt (MODPLUG_CFGID, "Channels"), {1}),
+ WidgetRadio (N_("Stereo"), WidgetInt (MODPLUG_CFGID, "Channels"), {2}),
+ WidgetLabel (N_("<b>Resampling</b>")),
+ WidgetRadio (N_("Nearest (fastest)"), WidgetInt (MODPLUG_CFGID, "ResamplingMode"), {0}),
+ WidgetRadio (N_("Linear (fast)"), WidgetInt (MODPLUG_CFGID, "ResamplingMode"), {1}),
+ WidgetRadio (N_("Spline (good)"), WidgetInt (MODPLUG_CFGID, "ResamplingMode"), {2}),
+ WidgetRadio (N_("Polyphase (best)"), WidgetInt (MODPLUG_CFGID, "ResamplingMode"), {3}),
+ WidgetLabel (N_("<b>Sample rate</b>")),
+ WidgetRadio (N_("22 kHz"), WidgetInt (MODPLUG_CFGID, "Frequency"), {22050}),
+ WidgetRadio (N_("44 kHz"), WidgetInt (MODPLUG_CFGID, "Frequency"), {44100}),
+ WidgetRadio (N_("48 kHz"), WidgetInt (MODPLUG_CFGID, "Frequency"), {48000}),
+ WidgetRadio (N_("96 kHz"), WidgetInt (MODPLUG_CFGID, "Frequency"), {96000})
+};
+
+static const PreferencesWidget reverb_fields[] = {
+ WidgetSpin (N_("Level:"), WidgetInt (MODPLUG_CFGID, "ReverbDepth"), {0, 100, 1, "%"}),
+ WidgetSpin (N_("Delay:"), WidgetInt (MODPLUG_CFGID, "ReverbDelay"), {40, 200, 1, N_("ms")})
+};
+
+static const PreferencesWidget bass_fields[] = {
+ WidgetSpin (N_("Level:"), WidgetInt (MODPLUG_CFGID, "BassAmount"), {0, 100, 1, "%"}),
+ WidgetSpin (N_("Cutoff:"), WidgetInt (MODPLUG_CFGID, "BassRange"), {10, 100, 1, N_("Hz")})
+};
+
+static const PreferencesWidget surround_fields[] = {
+ WidgetSpin (N_("Level:"), WidgetInt (MODPLUG_CFGID, "SurroundDepth"), {0, 100, 1, "%"}),
+ WidgetSpin (N_("Delay:"), WidgetInt (MODPLUG_CFGID, "SurroundDelay"), {5, 40, 1, N_("ms")})
+};
+
+static const PreferencesWidget preamp_fields[] = {
+ WidgetSpin (N_("Volume:"), WidgetFloat (MODPLUG_CFGID, "PreampLevel"), {-3, 3, 0.1}),
+};
+
+static const PreferencesWidget effects_widgets[] = {
+ WidgetLabel (N_("<b>Reverb</b>")),
+ WidgetCheck (N_("Enable"), WidgetBool (MODPLUG_CFGID, "Reverb")),
+ WidgetTable ({{reverb_fields}}, WIDGET_CHILD),
+ WidgetLabel (N_("<b>Bass Boost</b>")),
+ WidgetCheck (N_("Enable"), WidgetBool (MODPLUG_CFGID, "Megabass")),
+ WidgetTable ({{bass_fields}}, WIDGET_CHILD),
+ WidgetLabel (N_("<b>Surround</b>")),
+ WidgetCheck (N_("Enable"), WidgetBool (MODPLUG_CFGID, "Surround")),
+ WidgetTable ({{surround_fields}}, WIDGET_CHILD),
+ WidgetLabel (N_("<b>Preamp</b>")),
+ WidgetCheck (N_("Enable"), WidgetBool (MODPLUG_CFGID, "Preamp")),
+ WidgetTable ({{preamp_fields}}, WIDGET_CHILD)
+};
+
+static const PreferencesWidget misc_widgets[] = {
+ WidgetLabel (N_("<b>Miscellaneous</b>")),
+ WidgetCheck (N_("Oversample"), WidgetBool (MODPLUG_CFGID, "Oversamp")),
+ WidgetCheck (N_("Noise reduction"), WidgetBool (MODPLUG_CFGID, "NoiseReduction")),
+ WidgetCheck (N_("Play Amiga MODs"), WidgetBool (MODPLUG_CFGID, "GrabAmigaMOD")),
+ WidgetLabel (N_("<b>Repeat</b>")),
+ WidgetSpin (N_("Repeat count:"), WidgetInt (MODPLUG_CFGID, "LoopCount"), {-1, 100, 1}),
+ WidgetLabel (N_("To repeat forever, set the repeat count to -1."))
+};
+
+static const PreferencesWidget widget_columns[] = {
+ WidgetBox ({{quality_widgets}}),
+ WidgetSeparator (),
+ WidgetBox ({{effects_widgets}}),
+ WidgetSeparator (),
+ WidgetBox ({{misc_widgets}})
+};
+
+const PreferencesWidget ModplugXMMS::widgets[] = {
+ WidgetBox ({{widget_columns}, true}),
+ WidgetLabel (N_("These settings will take effect when Audacious is restarted."))
+};
+
+const PluginPreferences ModplugXMMS::prefs = {{widgets}};
+
+void ModplugXMMS::load_settings ()
+{
+ aud_config_set_defaults (MODPLUG_CFGID, defaults);
+
+ mModProps.mBits = aud_get_int (MODPLUG_CFGID, "Bits");
+ mModProps.mChannels = aud_get_int (MODPLUG_CFGID, "Channels");
+ mModProps.mResamplingMode = aud_get_int (MODPLUG_CFGID, "ResamplingMode");
+ mModProps.mFrequency = aud_get_int (MODPLUG_CFGID, "Frequency");
+
+ mModProps.mReverb = aud_get_bool (MODPLUG_CFGID, "Reverb");
+ mModProps.mReverbDepth = aud_get_int (MODPLUG_CFGID, "ReverbDepth");
+ mModProps.mReverbDelay = aud_get_int (MODPLUG_CFGID, "ReverbDelay");
+
+ mModProps.mMegabass = aud_get_bool (MODPLUG_CFGID, "Megabass");
+ mModProps.mBassAmount = aud_get_int (MODPLUG_CFGID, "BassAmount");
+ mModProps.mBassRange = aud_get_int (MODPLUG_CFGID, "BassRange");
+
+ mModProps.mSurround = aud_get_bool (MODPLUG_CFGID, "Surround");
+ mModProps.mSurroundDepth = aud_get_int (MODPLUG_CFGID, "SurroundDepth");
+ mModProps.mSurroundDelay = aud_get_int (MODPLUG_CFGID, "SurroundDelay");
+
+ mModProps.mPreamp = aud_get_bool (MODPLUG_CFGID, "PreAmp");
+ mModProps.mPreampLevel = aud_get_double (MODPLUG_CFGID, "PreAmpLevel");
+
+ mModProps.mOversamp = aud_get_bool (MODPLUG_CFGID, "Oversampling");
+ mModProps.mNoiseReduction = aud_get_bool (MODPLUG_CFGID, "NoiseReduction");
+ mModProps.mGrabAmigaMOD = aud_get_bool (MODPLUG_CFGID, "GrabAmigaMOD");
+ mModProps.mLoopCount = aud_get_int (MODPLUG_CFGID, "LoopCount");
+}
diff --git a/src/modplug/settings.h b/src/modplug/settings.h
index 4fa939a2cb16..58e9116d5407 100644
--- a/src/modplug/settings.h
+++ b/src/modplug/settings.h
@@ -1,41 +1,31 @@
#ifndef MODPLUG_SETTINGS_H
#define MODPLUG_SETTINGS_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <libaudcore/core.h>
-
typedef struct {
int mBits;
int mChannels;
int mResamplingMode;
int mFrequency;
- bool_t mReverb;
+ bool mReverb;
int mReverbDepth;
int mReverbDelay;
- bool_t mMegabass;
+ bool mMegabass;
int mBassAmount;
int mBassRange;
- bool_t mSurround;
+ bool mSurround;
int mSurroundDepth;
int mSurroundDelay;
- bool_t mPreamp;
- float mPreampLevel;
+ bool mPreamp;
+ double mPreampLevel;
- bool_t mOversamp;
- bool_t mNoiseReduction;
- bool_t mGrabAmigaMOD;
+ bool mOversamp;
+ bool mNoiseReduction;
+ bool mGrabAmigaMOD;
int mLoopCount;
} ModplugSettings;
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
#endif /* MODPLUG_SETTINGS_H */
diff --git a/src/mpg123/Makefile b/src/mpg123/Makefile
index 4b5b578a008b..85d5f392c299 100644
--- a/src/mpg123/Makefile
+++ b/src/mpg123/Makefile
@@ -1,12 +1,14 @@
PLUGIN = madplug${PLUGIN_SUFFIX}
-SRCS = mpg123.c
+SRCS = mpg123.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${MPG123_CFLAGS} -I../..
LIBS += ${MPG123_LIBS} -laudtag -lm
diff --git a/src/mpg123/mpg123.c b/src/mpg123/mpg123.c
deleted file mode 100644
index 636dc5d0f2ce..000000000000
--- a/src/mpg123/mpg123.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (c) 2010 William Pitcock <nenolod at dereferenced.org>.
- * Copyright (c) 2010-2011 John Lindgren <john.lindgren at tds.net>.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-
-#include <mpg123.h>
-
-#ifdef DEBUG_MPG123_IO
-# define MPG123_IODBG(...) AUDDBG(__VA_ARGS__)
-#else
-# define MPG123_IODBG(...) do { } while (0)
-#endif
-
-#include <libaudcore/audstrings.h>
-#include <audacious/debug.h>
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-#include <audacious/plugin.h>
-#include <audacious/audtag.h>
-
-/* Define to read all frame headers when calculating file length */
-/* #define FULL_SCAN */
-
-#define DECODE_OPTIONS (MPG123_QUIET | MPG123_GAPLESS | MPG123_SEEKBUFFER | MPG123_FUZZY)
-
-static ssize_t replace_read (void * file, void * buffer, size_t length)
-{
- return vfs_fread (buffer, 1, length, file);
-}
-
-static off_t replace_lseek (void * file, off_t to, int whence)
-{
- return (! vfs_fseek (file, to, whence)) ? vfs_ftell (file) : -1;
-}
-
-static off_t replace_lseek_dummy (void * file, off_t to, int whence)
-{
- return -1;
-}
-
-/** plugin glue **/
-static bool_t aud_mpg123_init (void)
-{
- AUDDBG("initializing mpg123 library\n");
- mpg123_init();
-
- return TRUE;
-}
-
-static void
-aud_mpg123_deinit(void)
-{
- AUDDBG("deinitializing mpg123 library\n");
- mpg123_exit();
-}
-
-static void set_format (mpg123_handle * dec)
-{
- static const int rates[] = {8000, 11025, 12000, 16000, 22050, 24000, 32000,
- 44100, 48000};
-
- mpg123_format_none (dec);
- for (int i = 0; i < ARRAY_LEN (rates); i ++)
- mpg123_format (dec, rates[i], MPG123_MONO | MPG123_STEREO,
- MPG123_ENC_FLOAT_32);
-}
-
-static void make_format_string (const struct mpg123_frameinfo * info, char *
- buf, int bsize)
-{
- static const char * vers[] = {"1", "2", "2.5"};
- snprintf (buf, bsize, "MPEG-%s layer %d", vers[info->version], info->layer);
-}
-
-static bool_t mpg123_probe_for_fd (const char * fname, VFSFile * file)
-{
- if (! file)
- return FALSE;
-
- /* MPG123 likes to grab WMA streams, so blacklist anything that starts with
- * mms://. If there are mms:// streams out there carrying MP3, they will
- * just have to play in ffaudio. --jlindgren */
- if (! strncmp (fname, "mms://", 6))
- return FALSE;
-
- bool_t is_streaming = vfs_is_streaming (file);
-
- /* Some MP3s begin with enormous ID3 tags, which fill up the whole probe
- * buffer and thus hide any MP3 content. As a workaround, assume that an
- * ID3 tag means an MP3 file. --jlindgren */
- if (! is_streaming)
- {
- char id3buf[3];
- if (vfs_fread (id3buf, 1, 3, file) != 3)
- return FALSE;
-
- if (! memcmp (id3buf, "ID3", 3))
- return TRUE;
-
- if (vfs_fseek (file, 0, SEEK_SET) < 0)
- return FALSE;
- }
-
- mpg123_handle * dec = mpg123_new (NULL, NULL);
- mpg123_param (dec, MPG123_ADD_FLAGS, DECODE_OPTIONS, 0);
-
- if (is_streaming)
- mpg123_replace_reader_handle (dec, replace_read, replace_lseek_dummy, NULL);
- else
- mpg123_replace_reader_handle (dec, replace_read, replace_lseek, NULL);
-
- set_format (dec);
-
- int res;
- if ((res = mpg123_open_handle (dec, file)) < 0)
- {
-ERR:
- AUDDBG ("Probe error: %s\n", mpg123_plain_strerror (res));
- mpg123_delete (dec);
- return FALSE;
- }
-
-#ifdef FULL_SCAN
- if (mpg123_scan (dec) < 0)
- goto ERR;
-#endif
-
-RETRY:;
- long rate;
- int chan, enc;
- if ((res = mpg123_getformat (dec, & rate, & chan, & enc)) < 0)
- goto ERR;
-
- struct mpg123_frameinfo info;
- if ((res = mpg123_info (dec, & info)) < 0)
- goto ERR;
-
- float out[chan * (rate / 10)];
- size_t done;
- while ((res = mpg123_read (dec, (void *) out, sizeof out, & done)) < 0)
- {
- if (res == MPG123_NEW_FORMAT)
- goto RETRY;
- goto ERR;
- }
-
- char str[32];
- make_format_string (& info, str, sizeof str);
- AUDDBG ("Accepted as %s: %s.\n", str, fname);
-
- mpg123_delete (dec);
- return TRUE;
-}
-
-static Tuple * mpg123_probe_for_tuple (const char * filename, VFSFile * file)
-{
- if (! file)
- return NULL;
-
- bool_t stream = vfs_is_streaming (file);
- mpg123_handle * decoder = mpg123_new (NULL, NULL);
- int result;
- long rate;
- int channels, encoding;
- struct mpg123_frameinfo info;
- char scratch[32];
-
- mpg123_param (decoder, MPG123_ADD_FLAGS, DECODE_OPTIONS, 0);
-
- if (stream)
- mpg123_replace_reader_handle (decoder, replace_read, replace_lseek_dummy, NULL);
- else
- mpg123_replace_reader_handle (decoder, replace_read, replace_lseek, NULL);
-
- if ((result = mpg123_open_handle (decoder, file)) < 0)
- goto ERR;
-
-#ifdef FULL_SCAN
- if (mpg123_scan (decoder) < 0)
- goto ERR;
-#endif
-
- if ((result = mpg123_getformat (decoder, & rate, & channels, & encoding)) < 0)
- goto ERR;
- if ((result = mpg123_info (decoder, & info)) < 0)
- goto ERR;
-
- Tuple * tuple = tuple_new_from_filename (filename);
- make_format_string (& info, scratch, sizeof scratch);
- tuple_set_str (tuple, FIELD_CODEC, scratch);
- snprintf (scratch, sizeof scratch, "%s, %d Hz", (channels == 2)
- ? _("Stereo") : (channels > 2) ? _("Surround") : _("Mono"), (int) rate);
- tuple_set_str (tuple, FIELD_QUALITY, scratch);
- tuple_set_int (tuple, FIELD_BITRATE, info.bitrate);
-
- if (! stream)
- {
- int64_t size = vfs_fsize (file);
- int64_t samples = mpg123_length (decoder);
- int length = (samples > 0 && rate > 0) ? samples * 1000 / rate : 0;
-
- if (length > 0)
- tuple_set_int (tuple, FIELD_LENGTH, length);
- if (size > 0 && length > 0)
- tuple_set_int (tuple, FIELD_BITRATE, 8 * size / length);
- }
-
- mpg123_delete (decoder);
-
- if (! stream && ! vfs_fseek (file, 0, SEEK_SET))
- tag_tuple_read (tuple, file);
-
- if (stream)
- tag_update_stream_metadata (tuple, file);
-
- return tuple;
-
-ERR:
- fprintf (stderr, "mpg123 probe error for %s: %s\n", filename, mpg123_plain_strerror (result));
- mpg123_delete (decoder);
- return NULL;
-}
-
-typedef struct {
- VFSFile *fd;
- mpg123_handle *decoder;
- long rate;
- int channels;
- int encoding;
- bool_t stream;
- Tuple *tu;
-} MPG123PlaybackContext;
-
-static void print_mpg123_error (const char * filename, mpg123_handle * decoder)
-{
- fprintf (stderr, "mpg123 error in %s: %s\n", filename, mpg123_strerror (decoder));
-}
-
-static bool_t mpg123_playback_worker (const char * filename, VFSFile * file)
-{
- bool_t error = FALSE;
- MPG123PlaybackContext ctx;
- int ret;
- int bitrate = 0, bitrate_sum = 0, bitrate_count = 0;
- int bitrate_updated = -1000; /* >= a second away from any position */
- struct mpg123_frameinfo fi;
- int error_count = 0;
-
- memset(&ctx, 0, sizeof(MPG123PlaybackContext));
- memset(&fi, 0, sizeof(struct mpg123_frameinfo));
-
- AUDDBG("playback worker started for %s\n", filename);
- ctx.fd = file;
-
- AUDDBG ("Checking for streaming ...\n");
- ctx.stream = vfs_is_streaming (file);
- ctx.tu = ctx.stream ? aud_input_get_tuple () : NULL;
-
- ctx.decoder = mpg123_new (NULL, NULL);
- mpg123_param (ctx.decoder, MPG123_ADD_FLAGS, DECODE_OPTIONS, 0);
-
- if (ctx.stream)
- mpg123_replace_reader_handle (ctx.decoder, replace_read, replace_lseek_dummy, NULL);
- else
- mpg123_replace_reader_handle (ctx.decoder, replace_read, replace_lseek, NULL);
-
- set_format (ctx.decoder);
-
- if (mpg123_open_handle (ctx.decoder, file) < 0)
- {
-OPEN_ERROR:
- print_mpg123_error (filename, ctx.decoder);
- error = TRUE;
- goto cleanup;
- }
-
- float outbuf[8192];
- size_t outbuf_size = 0;
-
-#ifdef FULL_SCAN
- if (mpg123_scan (ctx.decoder) < 0)
- goto OPEN_ERROR;
-#endif
-
-GET_FORMAT:
- if (mpg123_getformat (ctx.decoder, & ctx.rate, & ctx.channels,
- & ctx.encoding) < 0)
- goto OPEN_ERROR;
-
- while ((ret = mpg123_read (ctx.decoder, (void *) outbuf, sizeof outbuf,
- & outbuf_size)) < 0)
- {
- if (ret == MPG123_NEW_FORMAT)
- goto GET_FORMAT;
- goto OPEN_ERROR;
- }
-
- if (mpg123_info (ctx.decoder, & fi) < 0)
- goto OPEN_ERROR;
-
- bitrate = fi.bitrate * 1000;
- aud_input_set_bitrate (bitrate);
-
- if (! aud_input_open_audio (FMT_FLOAT, ctx.rate, ctx.channels))
- {
- error = TRUE;
- goto cleanup;
- }
-
- while (! aud_input_check_stop ())
- {
- int seek = aud_input_check_seek ();
-
- if (seek >= 0)
- {
- if (mpg123_seek (ctx.decoder, (int64_t) seek * ctx.rate / 1000, SEEK_SET) < 0)
- print_mpg123_error (filename, ctx.decoder);
-
- outbuf_size = 0;
- }
-
- mpg123_info(ctx.decoder, &fi);
- bitrate_sum += fi.bitrate;
- bitrate_count ++;
-
- if (bitrate_sum / bitrate_count != bitrate && abs
- (aud_input_written_time () - bitrate_updated) >= 1000)
- {
- aud_input_set_bitrate (bitrate_sum / bitrate_count * 1000);
- bitrate = bitrate_sum / bitrate_count;
- bitrate_sum = 0;
- bitrate_count = 0;
- bitrate_updated = aud_input_written_time ();
- }
-
- if (ctx.tu && tag_update_stream_metadata (ctx.tu, file))
- {
- tuple_ref (ctx.tu);
- aud_input_set_tuple (ctx.tu);
- }
-
- if (! outbuf_size && (ret = mpg123_read (ctx.decoder, (void *) outbuf,
- sizeof outbuf, & outbuf_size)) < 0)
- {
- if (ret == MPG123_DONE || ret == MPG123_ERR_READER)
- break;
-
- print_mpg123_error (filename, ctx.decoder);
-
- if (++ error_count >= 10)
- {
- error = TRUE;
- break;
- }
- }
- else
- {
- error_count = 0;
-
- aud_input_write_audio (outbuf, outbuf_size);
- outbuf_size = 0;
- }
- }
-
-cleanup:
- mpg123_delete(ctx.decoder);
- if (ctx.tu)
- tuple_unref (ctx.tu);
- return ! error;
-}
-
-static bool_t mpg123_write_tag (const char * filename, VFSFile * handle, const Tuple * tuple)
-{
- if (! handle)
- return FALSE;
-
- return tag_tuple_write (tuple, handle, TAG_TYPE_ID3V2);
-}
-
-static bool_t mpg123_get_image (const char * filename, VFSFile * handle,
- void * * data, int64_t * length)
-{
- if (! handle || vfs_is_streaming (handle))
- return FALSE;
-
- return tag_image_read (handle, data, length);
-}
-
-/** plugin description header **/
-static const char *mpg123_fmts[] = { "mp3", "mp2", "mp1", "bmu", NULL };
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("MPG123 Plugin"),
- .domain = PACKAGE,
- .init = aud_mpg123_init,
- .cleanup = aud_mpg123_deinit,
- .extensions = mpg123_fmts,
- .is_our_file_from_vfs = mpg123_probe_for_fd,
- .probe_for_tuple = mpg123_probe_for_tuple,
- .play = mpg123_playback_worker,
- .update_song_tuple = mpg123_write_tag,
- .get_song_image = mpg123_get_image,
-)
diff --git a/src/mpg123/mpg123.cc b/src/mpg123/mpg123.cc
new file mode 100644
index 000000000000..4807aec150c7
--- /dev/null
+++ b/src/mpg123/mpg123.cc
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2010 William Pitcock <nenolod at dereferenced.org>.
+ * Copyright (c) 2010-2011 John Lindgren <john.lindgren at tds.net>.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+#undef EXPORT
+#include <mpg123.h>
+
+// mpg123.h redefines EXPORT
+#undef EXPORT
+#include "config.h"
+
+#ifdef DEBUG_MPG123_IO
+# define MPG123_IODBG(...) AUDDBG(__VA_ARGS__)
+#else
+# define MPG123_IODBG(...) do { } while (0)
+#endif
+
+#define WANT_VFS_STDIO_COMPAT
+#include <libaudcore/audstrings.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <audacious/audtag.h>
+
+class MPG123Plugin : public InputPlugin
+{
+public:
+ static const char * const exts[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("MPG123 Plugin"),
+ PACKAGE,
+ nullptr,
+ & prefs
+ };
+
+ static constexpr auto iinfo = InputInfo (FlagWritesTag)
+ .with_exts (exts);
+
+ constexpr MPG123Plugin() : InputPlugin (info, iinfo) {}
+
+ bool init ();
+ void cleanup ();
+
+ bool is_our_file (const char * filename, VFSFile & file);
+ Tuple read_tuple (const char * filename, VFSFile & file);
+ Index<char> read_image (const char * filename, VFSFile & file);
+ bool write_tuple (const char * filename, VFSFile & file, const Tuple & tuple);
+ bool play (const char * filename, VFSFile & file);
+};
+
+EXPORT MPG123Plugin aud_plugin_instance;
+
+const char * const MPG123Plugin::defaults[] = {
+ "full_scan", "FALSE",
+ nullptr
+};
+
+const PreferencesWidget MPG123Plugin::widgets[] = {
+ WidgetLabel (N_("<b>Advanced</b>")),
+ WidgetCheck (N_("Use accurate length calculation (slow)"),
+ WidgetBool ("mpg123", "full_scan"))
+};
+
+const PluginPreferences MPG123Plugin::prefs = {{widgets}};
+
+#define DECODE_OPTIONS (MPG123_QUIET | MPG123_GAPLESS | MPG123_SEEKBUFFER | MPG123_FUZZY)
+
+static ssize_t replace_read (void * file, void * buffer, size_t length)
+{
+ return ((VFSFile *) file)->fread (buffer, 1, length);
+}
+
+static off_t replace_lseek (void * file, off_t to, int whence)
+{
+ if (((VFSFile *) file)->fseek (to, to_vfs_seek_type (whence)) < 0)
+ return -1;
+
+ return ((VFSFile *) file)->ftell ();
+}
+
+static off_t replace_lseek_dummy (void * file, off_t to, int whence)
+{
+ return -1;
+}
+
+bool MPG123Plugin::init ()
+{
+ aud_config_set_defaults ("mpg123", defaults);
+
+ AUDDBG("initializing mpg123 library\n");
+ mpg123_init();
+
+ return true;
+}
+
+void MPG123Plugin::cleanup ()
+{
+ AUDDBG("deinitializing mpg123 library\n");
+ mpg123_exit();
+}
+
+static void set_format (mpg123_handle * dec)
+{
+ mpg123_format_none (dec);
+
+ for (int rate : {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000})
+ mpg123_format (dec, rate, MPG123_MONO | MPG123_STEREO, MPG123_ENC_FLOAT_32);
+}
+
+static void make_format_string (const struct mpg123_frameinfo * info, char *
+ buf, int bsize)
+{
+ static const char * vers[] = {"1", "2", "2.5"};
+ snprintf (buf, bsize, "MPEG-%s layer %d", vers[info->version], info->layer);
+}
+
+bool MPG123Plugin::is_our_file (const char * fname, VFSFile & file)
+{
+ /* MPG123 likes to grab WMA streams, so blacklist anything that starts with
+ * mms://. If there are mms:// streams out there carrying MP3, they will
+ * just have to play in ffaudio. --jlindgren */
+ if (! strncmp (fname, "mms://", 6))
+ return false;
+
+ bool is_streaming = (file.fsize () < 0);
+
+ /* Some MP3s begin with enormous ID3 tags, which fill up the whole probe
+ * buffer and thus hide any MP3 content. As a workaround, assume that an
+ * ID3 tag means an MP3 file. --jlindgren */
+ if (! is_streaming)
+ {
+ char id3buf[3];
+ if (file.fread (id3buf, 1, 3) != 3)
+ return false;
+
+ if (! memcmp (id3buf, "ID3", 3))
+ return true;
+
+ if (file.fseek (0, VFS_SEEK_SET) < 0)
+ return false;
+ }
+
+ mpg123_handle * dec = mpg123_new (nullptr, nullptr);
+ mpg123_param (dec, MPG123_ADD_FLAGS, DECODE_OPTIONS, 0);
+
+ if (is_streaming)
+ mpg123_replace_reader_handle (dec, replace_read, replace_lseek_dummy, nullptr);
+ else
+ mpg123_replace_reader_handle (dec, replace_read, replace_lseek, nullptr);
+
+ set_format (dec);
+
+ int res;
+ if ((res = mpg123_open_handle (dec, & file)) < 0)
+ {
+ERR:
+ AUDDBG ("Probe error: %s\n", mpg123_plain_strerror (res));
+ mpg123_delete (dec);
+ return false;
+ }
+
+ if (! is_streaming && aud_get_bool ("mpg123", "full_scan") && mpg123_scan (dec) < 0)
+ goto ERR;
+
+RETRY:;
+ long rate;
+ int chan, enc;
+ if ((res = mpg123_getformat (dec, & rate, & chan, & enc)) < 0)
+ goto ERR;
+
+ struct mpg123_frameinfo info;
+ if ((res = mpg123_info (dec, & info)) < 0)
+ goto ERR;
+
+ float out[8192];
+ size_t done;
+ while ((res = mpg123_read (dec, (unsigned char *) out, sizeof out, & done)) < 0)
+ {
+ if (res == MPG123_NEW_FORMAT)
+ goto RETRY;
+ goto ERR;
+ }
+
+ char str[32];
+ make_format_string (& info, str, sizeof str);
+ AUDDBG ("Accepted as %s: %s.\n", str, fname);
+
+ mpg123_delete (dec);
+ return true;
+}
+
+Tuple MPG123Plugin::read_tuple (const char * filename, VFSFile & file)
+{
+ bool stream = (file.fsize () < 0);
+ mpg123_handle * decoder = mpg123_new (nullptr, nullptr);
+ int result;
+ long rate;
+ int channels, encoding;
+ struct mpg123_frameinfo info;
+ char scratch[32];
+
+ mpg123_param (decoder, MPG123_ADD_FLAGS, DECODE_OPTIONS, 0);
+
+ if (stream)
+ mpg123_replace_reader_handle (decoder, replace_read, replace_lseek_dummy, nullptr);
+ else
+ mpg123_replace_reader_handle (decoder, replace_read, replace_lseek, nullptr);
+
+ if ((result = mpg123_open_handle (decoder, & file)) < 0
+ || (! stream && aud_get_bool ("mpg123", "full_scan") && (result = mpg123_scan (decoder)) < 0)
+ || (result = mpg123_getformat (decoder, & rate, & channels, & encoding)) < 0
+ || (result = mpg123_info (decoder, & info)) < 0)
+ {
+ AUDERR ("mpg123 probe error for %s: %s\n", filename, mpg123_plain_strerror (result));
+ mpg123_delete (decoder);
+ return Tuple ();
+ }
+
+ Tuple tuple;
+ tuple.set_filename (filename);
+ make_format_string (& info, scratch, sizeof scratch);
+ tuple.set_str (Tuple::Codec, scratch);
+ snprintf (scratch, sizeof scratch, "%s, %d Hz", (channels == 2)
+ ? _("Stereo") : (channels > 2) ? _("Surround") : _("Mono"), (int) rate);
+ tuple.set_str (Tuple::Quality, scratch);
+ tuple.set_int (Tuple::Bitrate, info.bitrate);
+
+ if (! stream)
+ {
+ int64_t size = file.fsize ();
+ int64_t samples = mpg123_length (decoder);
+ int length = (samples > 0 && rate > 0) ? samples * 1000 / rate : 0;
+
+ if (length > 0)
+ tuple.set_int (Tuple::Length, length);
+ if (size > 0 && length > 0)
+ tuple.set_int (Tuple::Bitrate, 8 * size / length);
+ }
+
+ mpg123_delete (decoder);
+
+ if (! stream && ! file.fseek (0, VFS_SEEK_SET))
+ audtag::tuple_read (tuple, file);
+
+ if (stream)
+ tuple.fetch_stream_info (file);
+
+ return tuple;
+}
+
+typedef struct {
+ mpg123_handle *decoder;
+ long rate;
+ int channels;
+ int encoding;
+ bool stream;
+ Tuple tu;
+} MPG123PlaybackContext;
+
+static void print_mpg123_error (const char * filename, mpg123_handle * decoder)
+{
+ AUDERR ("mpg123 error in %s: %s\n", filename, mpg123_strerror (decoder));
+}
+
+bool MPG123Plugin::play (const char * filename, VFSFile & file)
+{
+ bool error = false;
+ MPG123PlaybackContext ctx;
+ int ret;
+ int bitrate = 0, bitrate_sum = 0, bitrate_count = 0;
+ struct mpg123_frameinfo fi;
+ int error_count = 0;
+
+ memset(&ctx, 0, sizeof(MPG123PlaybackContext));
+ memset(&fi, 0, sizeof(struct mpg123_frameinfo));
+
+ AUDDBG("playback worker started for %s\n", filename);
+
+ AUDDBG ("Checking for streaming ...\n");
+ ctx.stream = (file.fsize () < 0);
+ ctx.tu = ctx.stream ? get_playback_tuple () : Tuple ();
+
+ ctx.decoder = mpg123_new (nullptr, nullptr);
+ mpg123_param (ctx.decoder, MPG123_ADD_FLAGS, DECODE_OPTIONS, 0);
+
+ if (ctx.stream)
+ mpg123_replace_reader_handle (ctx.decoder, replace_read, replace_lseek_dummy, nullptr);
+ else
+ mpg123_replace_reader_handle (ctx.decoder, replace_read, replace_lseek, nullptr);
+
+ set_format (ctx.decoder);
+
+ float outbuf[8192];
+ size_t outbuf_size = 0;
+
+ if (mpg123_open_handle (ctx.decoder, & file) < 0)
+ {
+OPEN_ERROR:
+ print_mpg123_error (filename, ctx.decoder);
+ error = true;
+ goto cleanup;
+ }
+
+ if (! ctx.stream && aud_get_bool ("mpg123", "full_scan") && mpg123_scan (ctx.decoder) < 0)
+ goto OPEN_ERROR;
+
+GET_FORMAT:
+ if (mpg123_getformat (ctx.decoder, & ctx.rate, & ctx.channels,
+ & ctx.encoding) < 0)
+ goto OPEN_ERROR;
+
+ while ((ret = mpg123_read (ctx.decoder, (unsigned char *) outbuf,
+ sizeof outbuf, & outbuf_size)) < 0)
+ {
+ if (ret == MPG123_NEW_FORMAT)
+ goto GET_FORMAT;
+ goto OPEN_ERROR;
+ }
+
+ if (mpg123_info (ctx.decoder, & fi) < 0)
+ goto OPEN_ERROR;
+
+ bitrate = fi.bitrate * 1000;
+ set_stream_bitrate (bitrate);
+
+ if (ctx.tu && ctx.tu.fetch_stream_info (file))
+ set_playback_tuple (ctx.tu.ref ());
+
+ open_audio (FMT_FLOAT, ctx.rate, ctx.channels);
+
+ while (! check_stop ())
+ {
+ int seek = check_seek ();
+
+ if (seek >= 0)
+ {
+ if (mpg123_seek (ctx.decoder, (int64_t) seek * ctx.rate / 1000, SEEK_SET) < 0)
+ print_mpg123_error (filename, ctx.decoder);
+
+ outbuf_size = 0;
+ }
+
+ mpg123_info(ctx.decoder, &fi);
+ bitrate_sum += fi.bitrate;
+ bitrate_count ++;
+
+ if (bitrate_sum / bitrate_count != bitrate && bitrate_count >= 16)
+ {
+ set_stream_bitrate (bitrate_sum / bitrate_count * 1000);
+ bitrate = bitrate_sum / bitrate_count;
+ bitrate_sum = 0;
+ bitrate_count = 0;
+ }
+
+ if (ctx.tu && ctx.tu.fetch_stream_info (file))
+ set_playback_tuple (ctx.tu.ref ());
+
+ if (! outbuf_size && (ret = mpg123_read (ctx.decoder,
+ (unsigned char *) outbuf, sizeof outbuf, & outbuf_size)) < 0)
+ {
+ if (ret == MPG123_DONE || ret == MPG123_ERR_READER)
+ break;
+
+ print_mpg123_error (filename, ctx.decoder);
+
+ if (++ error_count >= 10)
+ {
+ error = true;
+ break;
+ }
+ }
+ else
+ {
+ error_count = 0;
+
+ write_audio (outbuf, outbuf_size);
+ outbuf_size = 0;
+ }
+ }
+
+cleanup:
+ mpg123_delete(ctx.decoder);
+ return ! error;
+}
+
+bool MPG123Plugin::write_tuple (const char * filename, VFSFile & file, const Tuple & tuple)
+{
+ if (file.fsize () < 0) // stream?
+ return false;
+
+ return audtag::tuple_write (tuple, file, audtag::TagType::ID3v2);
+}
+
+Index<char> MPG123Plugin::read_image (const char * filename, VFSFile & file)
+{
+ if (file.fsize () < 0) // stream?
+ return Index<char> ();
+
+ return audtag::image_read (file);
+}
+
+const char * const MPG123Plugin::exts[] = { "mp3", "mp2", "mp1", "bmu", nullptr };
diff --git a/src/mpris2/Makefile b/src/mpris2/Makefile
index 3ec652ff28c7..4b09753bdf9c 100644
--- a/src/mpris2/Makefile
+++ b/src/mpris2/Makefile
@@ -1,6 +1,6 @@
PLUGIN = mpris2${PLUGIN_SUFFIX}
-SRCS = object-core.c object-player.c plugin.c
+SRCS = object-core.c object-player.c plugin.cc
CLEAN = object-core.c object-core.h object-player.c object-player.h
include ../../buildsys.mk
@@ -8,6 +8,8 @@ include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
+
CPPFLAGS += -I../.. ${GLIB_CFLAGS} ${GIO_CFLAGS}
CFLAGS += ${PLUGIN_CFLAGS}
LIBS += -lm ${GLIB_LIBS} ${GIO_LIBS}
diff --git a/src/mpris2/plugin.c b/src/mpris2/plugin.c
deleted file mode 100644
index c237874b883f..000000000000
--- a/src/mpris2/plugin.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * MPRIS 2 Server for Audacious
- * Copyright 2011-2012 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <math.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <audacious/plugin.h>
-#include <libaudcore/hook.h>
-
-#include "object-core.h"
-#include "object-player.h"
-
-static GObject * object_core, * object_player;
-static char * last_title, * last_artist, * last_album, * last_file;
-static int last_length;
-static const char * image_file;
-static bool_t recheck_image;
-static int update_timer;
-
-static bool_t quit_cb (MprisMediaPlayer2 * object, GDBusMethodInvocation * call,
- void * unused)
-{
- aud_drct_quit ();
- mpris_media_player2_complete_quit (object, call);
- return TRUE;
-}
-
-static bool_t raise_cb (MprisMediaPlayer2 * object, GDBusMethodInvocation *
- call, void * unused)
-{
- aud_interface_show (TRUE);
- mpris_media_player2_complete_raise (object, call);
- return TRUE;
-}
-
-static void update_metadata (void * data, GObject * object)
-{
- char * title = NULL, * artist = NULL, * album = NULL, * file = NULL;
- int length = 0;
-
- int playlist = aud_playlist_get_playing ();
- int entry = (playlist >= 0) ? aud_playlist_get_position (playlist) : -1;
-
- if (entry >= 0)
- {
- aud_playlist_entry_describe (playlist, entry, & title, & artist, & album, TRUE);
- file = aud_playlist_entry_get_filename (playlist, entry);
- length = aud_playlist_entry_get_length (playlist, entry, TRUE);
- }
-
- if (str_equal (title, last_title) && str_equal (artist, last_artist) &&
- str_equal (album, last_album) && str_equal (file, last_file) && length ==
- last_length && ! recheck_image)
- {
- str_unref (title);
- str_unref (artist);
- str_unref (album);
- str_unref (file);
- return;
- }
-
- if (! str_equal (file, last_file) || recheck_image)
- {
- if (image_file)
- aud_art_unref (last_file);
- image_file = file ? aud_art_request_file (file) : NULL;
- recheck_image = FALSE;
- }
-
- str_unref (last_title);
- str_unref (last_artist);
- str_unref (last_album);
- str_unref (last_file);
- last_title = title;
- last_artist = artist;
- last_album = album;
- last_file = file;
- last_length = length;
-
- GVariant * elems[7];
- int nelems = 0;
-
- if (title)
- {
- GVariant * key = g_variant_new_string ("xesam:title");
- GVariant * str = g_variant_new_string (title);
- GVariant * var = g_variant_new_variant (str);
- elems[nelems ++] = g_variant_new_dict_entry (key, var);
- }
-
- if (artist)
- {
- GVariant * key = g_variant_new_string ("xesam:artist");
- GVariant * str = g_variant_new_string (artist);
- GVariant * array = g_variant_new_array (G_VARIANT_TYPE_STRING, & str, 1);
- GVariant * var = g_variant_new_variant (array);
- elems[nelems ++] = g_variant_new_dict_entry (key, var);
- }
-
- if (album)
- {
- GVariant * key = g_variant_new_string ("xesam:album");
- GVariant * str = g_variant_new_string (album);
- GVariant * var = g_variant_new_variant (str);
- elems[nelems ++] = g_variant_new_dict_entry (key, var);
- }
-
- if (file)
- {
- GVariant * key = g_variant_new_string ("xesam:url");
- GVariant * str = g_variant_new_string (file);
- GVariant * var = g_variant_new_variant (str);
- elems[nelems ++] = g_variant_new_dict_entry (key, var);
- }
-
- if (length > 0)
- {
- GVariant * key = g_variant_new_string ("mpris:length");
- GVariant * val = g_variant_new_int64 ((int64_t) length * 1000);
- GVariant * var = g_variant_new_variant (val);
- elems[nelems ++] = g_variant_new_dict_entry (key, var);
- }
-
- if (image_file)
- {
- GVariant * key = g_variant_new_string ("mpris:artUrl");
- GVariant * str = g_variant_new_string (image_file);
- GVariant * var = g_variant_new_variant (str);
- elems[nelems ++] = g_variant_new_dict_entry (key, var);
- }
-
- GVariant * key = g_variant_new_string ("mpris:trackid");
- GVariant * str = g_variant_new_string ("/org/mpris/MediaPlayer2/CurrentTrack");
- GVariant * var = g_variant_new_variant (str);
- elems[nelems ++] = g_variant_new_dict_entry (key, var);
-
- GVariant * array = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), elems, nelems);
- g_object_set (object, "metadata", array, NULL);
-}
-
-static void update_image (void * data, GObject * object)
-{
- recheck_image = TRUE;
- update_metadata (data, object);
-}
-
-static void volume_changed (GObject * object)
-{
- double vol;
- g_object_get (object, "volume", & vol, NULL);
- aud_drct_set_volume_main (round (vol * 100));
-}
-
-static bool_t update (GObject * object)
-{
- int64_t pos = 0;
- int vol = 0;
-
- if (aud_drct_get_playing () && aud_drct_get_ready ())
- pos = (int64_t) aud_drct_get_time () * 1000;
-
- aud_drct_get_volume_main (& vol);
-
- g_signal_handlers_block_by_func (object, (void *) volume_changed, NULL);
- g_object_set (object, "position", pos, "volume", (double) vol / 100, NULL);
- g_signal_handlers_unblock_by_func (object, (void *) volume_changed, NULL);
- return TRUE;
-}
-
-static void update_playback_status (void * data, GObject * object)
-{
- const char * status;
-
- if (aud_drct_get_playing ())
- status = aud_drct_get_paused () ? "Paused" : "Playing";
- else
- status = "Stopped";
-
- g_object_set (object, "playback-status", status, NULL);
- update (object);
-}
-
-static void emit_seek (void * data, GObject * object)
-{
- g_signal_emit_by_name (object, "seeked", (int64_t) aud_drct_get_time () * 1000);
-}
-
-static bool_t next_cb (MprisMediaPlayer2Player * object, GDBusMethodInvocation *
- call, void * unused)
-{
- aud_drct_pl_next ();
- mpris_media_player2_player_complete_next (object, call);
- return TRUE;
-}
-
-static bool_t pause_cb (MprisMediaPlayer2Player * object,
- GDBusMethodInvocation * call, void * unused)
-{
- if (aud_drct_get_playing () && ! aud_drct_get_paused ())
- aud_drct_pause ();
-
- mpris_media_player2_player_complete_pause (object, call);
- return TRUE;
-}
-
-static bool_t play_cb (MprisMediaPlayer2Player * object, GDBusMethodInvocation *
- call, void * unused)
-{
- aud_drct_play ();
- mpris_media_player2_player_complete_play (object, call);
- return TRUE;
-}
-
-static bool_t play_pause_cb (MprisMediaPlayer2Player * object,
- GDBusMethodInvocation * call, void * unused)
-{
- aud_drct_play_pause ();
- mpris_media_player2_player_complete_play_pause (object, call);
- return TRUE;
-}
-
-static bool_t previous_cb (MprisMediaPlayer2Player * object,
- GDBusMethodInvocation * call, void * unused)
-{
- aud_drct_pl_prev ();
- mpris_media_player2_player_complete_previous (object, call);
- return TRUE;
-}
-
-static bool_t seek_cb (MprisMediaPlayer2Player * object,
- GDBusMethodInvocation * call, int64_t offset, void * unused)
-{
- aud_drct_seek (aud_drct_get_time () + offset / 1000);
- mpris_media_player2_player_complete_seek (object, call);
- return TRUE;
-}
-
-static bool_t set_position_cb (MprisMediaPlayer2Player * object,
- GDBusMethodInvocation * call, const char * track, int64_t pos, void * unused)
-{
- if (aud_drct_get_playing ())
- aud_drct_seek (pos / 1000);
-
- mpris_media_player2_player_complete_set_position (object, call);
- return TRUE;
-}
-
-static bool_t stop_cb (MprisMediaPlayer2Player * object, GDBusMethodInvocation *
- call, void * unused)
-{
- if (aud_drct_get_playing ())
- aud_drct_stop ();
-
- mpris_media_player2_player_complete_stop (object, call);
- return TRUE;
-}
-
-void mpris2_cleanup (void)
-{
- hook_dissociate ("playback begin", (HookFunction) update_playback_status);
- hook_dissociate ("playback pause", (HookFunction) update_playback_status);
- hook_dissociate ("playback stop", (HookFunction) update_playback_status);
- hook_dissociate ("playback unpause", (HookFunction) update_playback_status);
-
- hook_dissociate ("playlist set playing", (HookFunction) update_metadata);
- hook_dissociate ("playlist position", (HookFunction) update_metadata);
- hook_dissociate ("playlist update", (HookFunction) update_metadata);
-
- hook_dissociate ("current art ready", (HookFunction) update_image);
-
- hook_dissociate ("playback ready", (HookFunction) emit_seek);
- hook_dissociate ("playback seek", (HookFunction) emit_seek);
-
- if (update_timer)
- {
- g_source_remove (update_timer);
- update_timer = 0;
- }
-
- g_object_unref (object_core);
- g_object_unref (object_player);
-
- if (image_file)
- {
- aud_art_unref (last_file);
- image_file = NULL;
- }
-
- str_unref (last_title);
- str_unref (last_artist);
- str_unref (last_album);
- str_unref (last_file);
- last_title = last_artist = last_album = last_file = NULL;
- last_length = 0;
-}
-
-bool_t mpris2_init (void)
-{
- GError * error = NULL;
- GDBusConnection * bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, & error);
-
- if (! bus)
- {
- fprintf (stderr, "mpris2: %s\n", error->message);
- g_error_free (error);
- return FALSE;
- }
-
- g_bus_own_name_on_connection (bus, "org.mpris.MediaPlayer2.audacious", 0,
- NULL, NULL, NULL, NULL);
-
- object_core = (GObject *) mpris_media_player2_skeleton_new ();
-
- g_object_set (object_core,
- "can-quit", TRUE,
- "can-raise", TRUE,
- "desktop-entry", "audacious",
- "identity", "Audacious",
- NULL);
-
- g_signal_connect (object_core, "handle-quit", (GCallback) quit_cb, NULL);
- g_signal_connect (object_core, "handle-raise", (GCallback) raise_cb, NULL);
-
- object_player = (GObject *) mpris_media_player2_player_skeleton_new ();
-
- g_object_set (object_player,
- "can-control", TRUE,
- "can-go-next", TRUE,
- "can-go-previous", TRUE,
- "can-pause", TRUE,
- "can-play", TRUE,
- "can-seek", TRUE,
- NULL);
-
- update_timer = g_timeout_add (250, (GSourceFunc) update, object_player);
- update_playback_status (NULL, object_player);
-
- if (aud_drct_get_playing () && aud_drct_get_ready ())
- emit_seek (NULL, object_player);
-
- hook_associate ("playback begin", (HookFunction) update_playback_status, object_player);
- hook_associate ("playback pause", (HookFunction) update_playback_status, object_player);
- hook_associate ("playback stop", (HookFunction) update_playback_status, object_player);
- hook_associate ("playback unpause", (HookFunction) update_playback_status, object_player);
-
- hook_associate ("playlist set playing", (HookFunction) update_metadata, object_player);
- hook_associate ("playlist position", (HookFunction) update_metadata, object_player);
- hook_associate ("playlist update", (HookFunction) update_metadata, object_player);
-
- hook_associate ("current art ready", (HookFunction) update_image, object_player);
-
- hook_associate ("playback ready", (HookFunction) emit_seek, object_player);
- hook_associate ("playback seek", (HookFunction) emit_seek, object_player);
-
- g_signal_connect (object_player, "handle-next", (GCallback) next_cb, NULL);
- g_signal_connect (object_player, "handle-pause", (GCallback) pause_cb, NULL);
- g_signal_connect (object_player, "handle-play", (GCallback) play_cb, NULL);
- g_signal_connect (object_player, "handle-play-pause", (GCallback) play_pause_cb, NULL);
- g_signal_connect (object_player, "handle-previous", (GCallback) previous_cb, NULL);
- g_signal_connect (object_player, "handle-seek", (GCallback) seek_cb, NULL);
- g_signal_connect (object_player, "handle-set-position", (GCallback) set_position_cb, NULL);
- g_signal_connect (object_player, "handle-stop", (GCallback) stop_cb, NULL);
-
- g_signal_connect (object_player, "notify::volume", (GCallback) volume_changed, NULL);
-
- if (! g_dbus_interface_skeleton_export ((GDBusInterfaceSkeleton *)
- object_core, bus, "/org/mpris/MediaPlayer2", & error) ||
- ! g_dbus_interface_skeleton_export ((GDBusInterfaceSkeleton *)
- object_player, bus, "/org/mpris/MediaPlayer2", & error))
- {
- mpris2_cleanup ();
- fprintf (stderr, "mpris2: %s\n", error->message);
- g_error_free (error);
- return FALSE;
- }
-
- return TRUE;
-}
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("MPRIS 2 Server"),
- .domain = PACKAGE,
- .enabled_by_default = TRUE,
- .init = mpris2_init,
- .cleanup = mpris2_cleanup
-)
diff --git a/src/mpris2/plugin.cc b/src/mpris2/plugin.cc
new file mode 100644
index 000000000000..95f592b66c45
--- /dev/null
+++ b/src/mpris2/plugin.cc
@@ -0,0 +1,413 @@
+/*
+ * MPRIS 2 Server for Audacious
+ * Copyright 2011-2012 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/probe.h>
+#include <libaudcore/runtime.h>
+
+#include "object-core.h"
+#include "object-player.h"
+
+class MPRIS2Plugin : public GeneralPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("MPRIS 2 Server"),
+ PACKAGE
+ };
+
+ constexpr MPRIS2Plugin () : GeneralPlugin (info, true) {}
+
+ bool init ();
+ void cleanup ();
+};
+
+EXPORT MPRIS2Plugin aud_plugin_instance;
+
+static GObject * object_core, * object_player;
+static String last_title, last_artist, last_album, last_file;
+static int last_length;
+static const char * image_file;
+static gboolean recheck_image;
+static int update_timer;
+
+static gboolean quit_cb (MprisMediaPlayer2 * object, GDBusMethodInvocation * call,
+ void * unused)
+{
+ aud_quit ();
+ mpris_media_player2_complete_quit (object, call);
+ return true;
+}
+
+static gboolean raise_cb (MprisMediaPlayer2 * object, GDBusMethodInvocation *
+ call, void * unused)
+{
+ aud_ui_show (true);
+ mpris_media_player2_complete_raise (object, call);
+ return true;
+}
+
+static void update_metadata (void * data, GObject * object)
+{
+ String title, artist, album, file;
+ int length = 0;
+
+ int playlist = aud_playlist_get_playing ();
+ int entry = (playlist >= 0) ? aud_playlist_get_position (playlist) : -1;
+
+ if (entry >= 0)
+ {
+ Tuple tuple = aud_playlist_entry_get_tuple (playlist, entry, Playlist::Guess);
+
+ title = tuple.get_str (Tuple::Title);
+ artist = tuple.get_str (Tuple::Artist);
+ album = tuple.get_str (Tuple::Album);
+ length = tuple.get_int (Tuple::Length);
+
+ file = aud_playlist_entry_get_filename (playlist, entry);
+ }
+
+ if (title == last_title && artist == last_artist && album == last_album
+ && file == last_file && length == last_length && ! recheck_image)
+ return;
+
+ if (file != last_file || recheck_image)
+ {
+ if (image_file)
+ aud_art_unref (last_file);
+ image_file = file ? aud_art_request_file (file) : nullptr;
+ recheck_image = false;
+ }
+
+ last_title = title;
+ last_artist = artist;
+ last_album = album;
+ last_file = file;
+ last_length = length;
+
+ GVariant * elems[7];
+ int nelems = 0;
+
+ if (title)
+ {
+ GVariant * key = g_variant_new_string ("xesam:title");
+ GVariant * str = g_variant_new_string (title);
+ GVariant * var = g_variant_new_variant (str);
+ elems[nelems ++] = g_variant_new_dict_entry (key, var);
+ }
+
+ if (artist)
+ {
+ GVariant * key = g_variant_new_string ("xesam:artist");
+ GVariant * str = g_variant_new_string (artist);
+ GVariant * array = g_variant_new_array (G_VARIANT_TYPE_STRING, & str, 1);
+ GVariant * var = g_variant_new_variant (array);
+ elems[nelems ++] = g_variant_new_dict_entry (key, var);
+ }
+
+ if (album)
+ {
+ GVariant * key = g_variant_new_string ("xesam:album");
+ GVariant * str = g_variant_new_string (album);
+ GVariant * var = g_variant_new_variant (str);
+ elems[nelems ++] = g_variant_new_dict_entry (key, var);
+ }
+
+ if (file)
+ {
+ GVariant * key = g_variant_new_string ("xesam:url");
+ GVariant * str = g_variant_new_string (file);
+ GVariant * var = g_variant_new_variant (str);
+ elems[nelems ++] = g_variant_new_dict_entry (key, var);
+ }
+
+ if (length > 0)
+ {
+ GVariant * key = g_variant_new_string ("mpris:length");
+ GVariant * val = g_variant_new_int64 ((int64_t) length * 1000);
+ GVariant * var = g_variant_new_variant (val);
+ elems[nelems ++] = g_variant_new_dict_entry (key, var);
+ }
+
+ if (image_file)
+ {
+ GVariant * key = g_variant_new_string ("mpris:artUrl");
+ GVariant * str = g_variant_new_string (image_file);
+ GVariant * var = g_variant_new_variant (str);
+ elems[nelems ++] = g_variant_new_dict_entry (key, var);
+ }
+
+ GVariant * key = g_variant_new_string ("mpris:trackid");
+ GVariant * str = g_variant_new_string ("/org/mpris/MediaPlayer2/CurrentTrack");
+ GVariant * var = g_variant_new_variant (str);
+ elems[nelems ++] = g_variant_new_dict_entry (key, var);
+
+ GVariant * array = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), elems, nelems);
+ g_object_set (object, "metadata", array, nullptr);
+}
+
+static void update_image (void * data, GObject * object)
+{
+ recheck_image = true;
+ update_metadata (data, object);
+}
+
+static void volume_changed (GObject * object)
+{
+ double vol;
+ g_object_get (object, "volume", & vol, nullptr);
+ aud_drct_set_volume_main (round (vol * 100));
+}
+
+static gboolean update (GObject * object)
+{
+ int64_t pos = 0;
+ int vol = 0;
+
+ if (aud_drct_get_playing () && aud_drct_get_ready ())
+ pos = (int64_t) aud_drct_get_time () * 1000;
+
+ vol = aud_drct_get_volume_main ();
+
+ g_signal_handlers_block_by_func (object, (void *) volume_changed, nullptr);
+ g_object_set (object, "position", pos, "volume", (double) vol / 100, nullptr);
+ g_signal_handlers_unblock_by_func (object, (void *) volume_changed, nullptr);
+ return true;
+}
+
+static void update_playback_status (void * data, GObject * object)
+{
+ const char * status;
+
+ if (aud_drct_get_playing ())
+ status = aud_drct_get_paused () ? "Paused" : "Playing";
+ else
+ status = "Stopped";
+
+ g_object_set (object, "playback-status", status, nullptr);
+ update (object);
+}
+
+static void emit_seek (void * data, GObject * object)
+{
+ g_signal_emit_by_name (object, "seeked", (int64_t) aud_drct_get_time () * 1000);
+}
+
+static gboolean next_cb (MprisMediaPlayer2Player * object, GDBusMethodInvocation *
+ call, void * unused)
+{
+ aud_drct_pl_next ();
+ mpris_media_player2_player_complete_next (object, call);
+ return true;
+}
+
+static gboolean pause_cb (MprisMediaPlayer2Player * object,
+ GDBusMethodInvocation * call, void * unused)
+{
+ if (aud_drct_get_playing () && ! aud_drct_get_paused ())
+ aud_drct_pause ();
+
+ mpris_media_player2_player_complete_pause (object, call);
+ return true;
+}
+
+static gboolean play_cb (MprisMediaPlayer2Player * object, GDBusMethodInvocation *
+ call, void * unused)
+{
+ aud_drct_play ();
+ mpris_media_player2_player_complete_play (object, call);
+ return true;
+}
+
+static gboolean play_pause_cb (MprisMediaPlayer2Player * object,
+ GDBusMethodInvocation * call, void * unused)
+{
+ aud_drct_play_pause ();
+ mpris_media_player2_player_complete_play_pause (object, call);
+ return true;
+}
+
+static gboolean previous_cb (MprisMediaPlayer2Player * object,
+ GDBusMethodInvocation * call, void * unused)
+{
+ aud_drct_pl_prev ();
+ mpris_media_player2_player_complete_previous (object, call);
+ return true;
+}
+
+static gboolean seek_cb (MprisMediaPlayer2Player * object,
+ GDBusMethodInvocation * call, int64_t offset, void * unused)
+{
+ aud_drct_seek (aud_drct_get_time () + offset / 1000);
+ mpris_media_player2_player_complete_seek (object, call);
+ return true;
+}
+
+static gboolean set_position_cb (MprisMediaPlayer2Player * object,
+ GDBusMethodInvocation * call, const char * track, int64_t pos, void * unused)
+{
+ if (aud_drct_get_playing ())
+ aud_drct_seek (pos / 1000);
+
+ mpris_media_player2_player_complete_set_position (object, call);
+ return true;
+}
+
+static gboolean stop_cb (MprisMediaPlayer2Player * object, GDBusMethodInvocation *
+ call, void * unused)
+{
+ if (aud_drct_get_playing ())
+ aud_drct_stop ();
+
+ mpris_media_player2_player_complete_stop (object, call);
+ return true;
+}
+
+void MPRIS2Plugin::cleanup ()
+{
+ hook_dissociate ("playback begin", (HookFunction) update_playback_status);
+ hook_dissociate ("playback pause", (HookFunction) update_playback_status);
+ hook_dissociate ("playback stop", (HookFunction) update_playback_status);
+ hook_dissociate ("playback unpause", (HookFunction) update_playback_status);
+
+ hook_dissociate ("playlist set playing", (HookFunction) update_metadata);
+ hook_dissociate ("playlist position", (HookFunction) update_metadata);
+ hook_dissociate ("playlist update", (HookFunction) update_metadata);
+
+ hook_dissociate ("current art ready", (HookFunction) update_image);
+
+ hook_dissociate ("playback ready", (HookFunction) emit_seek);
+ hook_dissociate ("playback seek", (HookFunction) emit_seek);
+
+ if (update_timer)
+ {
+ g_source_remove (update_timer);
+ update_timer = 0;
+ }
+
+ g_object_unref (object_core);
+ g_object_unref (object_player);
+
+ if (image_file)
+ {
+ aud_art_unref (last_file);
+ image_file = nullptr;
+ }
+
+ last_title = String ();
+ last_artist = String ();
+ last_album = String ();
+ last_file = String ();
+ last_length = 0;
+}
+
+bool MPRIS2Plugin::init ()
+{
+#if ! GLIB_CHECK_VERSION (2, 36, 0)
+ g_type_init ();
+#endif
+
+ GError * error = nullptr;
+ GDBusConnection * bus = g_bus_get_sync (G_BUS_TYPE_SESSION, nullptr, & error);
+
+ if (! bus)
+ {
+ AUDERR ("%s\n", error->message);
+ g_error_free (error);
+ return false;
+ }
+
+ g_bus_own_name_on_connection (bus, "org.mpris.MediaPlayer2.audacious",
+ (GBusNameOwnerFlags) 0, nullptr, nullptr, nullptr, nullptr);
+
+ object_core = (GObject *) mpris_media_player2_skeleton_new ();
+
+ g_object_set (object_core,
+ "can-quit", (gboolean) true,
+ "can-raise", (gboolean) true,
+ "desktop-entry", "audacious",
+ "identity", "Audacious",
+ nullptr);
+
+ g_signal_connect (object_core, "handle-quit", (GCallback) quit_cb, nullptr);
+ g_signal_connect (object_core, "handle-raise", (GCallback) raise_cb, nullptr);
+
+ object_player = (GObject *) mpris_media_player2_player_skeleton_new ();
+
+ g_object_set (object_player,
+ "can-control", (gboolean) true,
+ "can-go-next", (gboolean) true,
+ "can-go-previous", (gboolean) true,
+ "can-pause", (gboolean) true,
+ "can-play", (gboolean) true,
+ "can-seek", (gboolean) true,
+ nullptr);
+
+ update_timer = g_timeout_add (250, (GSourceFunc) update, object_player);
+ update_playback_status (nullptr, object_player);
+
+ if (aud_drct_get_playing () && aud_drct_get_ready ())
+ emit_seek (nullptr, object_player);
+
+ hook_associate ("playback begin", (HookFunction) update_playback_status, object_player);
+ hook_associate ("playback pause", (HookFunction) update_playback_status, object_player);
+ hook_associate ("playback stop", (HookFunction) update_playback_status, object_player);
+ hook_associate ("playback unpause", (HookFunction) update_playback_status, object_player);
+
+ hook_associate ("playlist set playing", (HookFunction) update_metadata, object_player);
+ hook_associate ("playlist position", (HookFunction) update_metadata, object_player);
+ hook_associate ("playlist update", (HookFunction) update_metadata, object_player);
+
+ hook_associate ("current art ready", (HookFunction) update_image, object_player);
+
+ hook_associate ("playback ready", (HookFunction) emit_seek, object_player);
+ hook_associate ("playback seek", (HookFunction) emit_seek, object_player);
+
+ g_signal_connect (object_player, "handle-next", (GCallback) next_cb, nullptr);
+ g_signal_connect (object_player, "handle-pause", (GCallback) pause_cb, nullptr);
+ g_signal_connect (object_player, "handle-play", (GCallback) play_cb, nullptr);
+ g_signal_connect (object_player, "handle-play-pause", (GCallback) play_pause_cb, nullptr);
+ g_signal_connect (object_player, "handle-previous", (GCallback) previous_cb, nullptr);
+ g_signal_connect (object_player, "handle-seek", (GCallback) seek_cb, nullptr);
+ g_signal_connect (object_player, "handle-set-position", (GCallback) set_position_cb, nullptr);
+ g_signal_connect (object_player, "handle-stop", (GCallback) stop_cb, nullptr);
+
+ g_signal_connect (object_player, "notify::volume", (GCallback) volume_changed, nullptr);
+
+ if (! g_dbus_interface_skeleton_export ((GDBusInterfaceSkeleton *)
+ object_core, bus, "/org/mpris/MediaPlayer2", & error) ||
+ ! g_dbus_interface_skeleton_export ((GDBusInterfaceSkeleton *)
+ object_player, bus, "/org/mpris/MediaPlayer2", & error))
+ {
+ cleanup ();
+ AUDERR ("%s\n", error->message);
+ g_error_free (error);
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/neon/Makefile b/src/neon/Makefile
index e4cdb421d485..d8ae392943f3 100644
--- a/src/neon/Makefile
+++ b/src/neon/Makefile
@@ -1,14 +1,15 @@
PLUGIN = neon${PLUGIN_SUFFIX}
-SRCS = neon.c \
- rb.c \
- cert_verification.c
+SRCS = neon.cc \
+ cert_verification.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${TRANSPORT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} ${NEON_CFLAGS} -I../..
-LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${NEON_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${NEON_CFLAGS} -I../..
+LIBS += ${GLIB_LIBS} ${NEON_LIBS}
diff --git a/src/neon/cert_verification.c b/src/neon/cert_verification.c
deleted file mode 100644
index 61f9ec525073..000000000000
--- a/src/neon/cert_verification.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Wget like SSL certificate validation from environmental variables.
- * Copyright (C) 2009 Jussi Judin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <ne_ssl.h>
-#include <ne_session.h>
-
-#include <libaudcore/core.h>
-
-#include "cert_verification.h"
-
-// Certificate validation handling.
-
-const int LENGTH_SHORTFORM_MAX = 127;
-const int LENGTH_INDEFINITE_VALUE = 128;
-const int LENGTH_LONGFORM_MASK = 0x7f;
-const int OCTET_BITS = 8;
-const int ASNTYPE_CODE_MASK = 0x1f;
-const int HASH_BYTES = 4;
-const uint32_t MAX_CERT_CHECKS = UINT32_MAX;
-
-enum AsnType
-{
- ASNTYPE_INTEGER = 2,
- ASNTYPE_SEQUENCE = 16,
- ASNTYPE_VARLEN_IDENTIFIER = 31
-};
-
-struct DerData
-{
- unsigned char * start;
- unsigned char * end;
- unsigned char * nextStart;
- unsigned char * bufferEnd;
- enum AsnType type;
-};
-
-/**
- * X.509 certificate has following structure defined in RFC5280:
- *
- * Certificate ::= SEQUENCE {
- * tbsCertificate TBSCertificate,
- * signatureAlgorithm AlgorithmIdentifier,
- * signatureValue BIT STRING }
- *
- * TBSCertificate ::= SEQUENCE {
- * version [0] EXPLICIT Version DEFAULT v1,
- * serialNumber CertificateSerialNumber,
- * signature AlgorithmIdentifier,
- * issuer Name,
- * validity Validity,
- * subject Name,
- * ...
- *
- * Version ::= INTEGER { v1(0), v2(1), v3(2) }
- * CertificateSerialNumber ::= INTEGER
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL }
- * Validity ::= SEQUENCE {
- * notBefore Time,
- * notAfter Time }
- * Time ::= CHOICE {
- * utcTime UTCTime,
- * generalTime GeneralizedTime }
- * Name ::= CHOICE { -- only one possibility for now --
- * rdnSequence RDNSequence }
- * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
- *
- * And we are only interested in subject field.
- */
-
-/**
- * Returns the tag number of DER data.
- */
-static bool_t der_read_tag_number (unsigned char * in_buffer,
- const unsigned char * in_bufferEnd, unsigned char * * out_lengthStart,
- enum AsnType * out_type)
-{
- if (in_bufferEnd - in_buffer < 2)
- return FALSE;
-
- unsigned char typeOctet = in_buffer[0];
- enum AsnType typeCode = typeOctet & ASNTYPE_CODE_MASK;
- int typeCodeLength = 1;
-
- // Variable length types are not supported.
- if (typeCode == ASNTYPE_VARLEN_IDENTIFIER)
- return FALSE;
-
- * out_type = typeCode;
- * out_lengthStart = in_buffer + typeCodeLength;
-
- return TRUE;
-}
-
-/**
- * Returns pointers that point to the content of DER data value when identifier
- * is not present.
- */
-static bool_t der_read_content_length (unsigned char * in_buffer,
- const unsigned char * in_bufferEnd, unsigned char * * out_start,
- unsigned char * * out_end, unsigned char * * out_nextStart)
-{
- if (in_bufferEnd - in_buffer < 1)
- return FALSE;
-
- unsigned char lengthDescription = in_buffer[0];
-
- if (lengthDescription <= LENGTH_SHORTFORM_MAX)
- {
- * out_start = in_buffer + 1;
- * out_end = * out_start + lengthDescription;
-
- if (in_bufferEnd < * out_end)
- return FALSE;
-
- * out_nextStart = * out_end;
- return TRUE;
- }
-
- if (lengthDescription == LENGTH_INDEFINITE_VALUE)
- {
- * out_start = in_buffer + 1;
- unsigned char * currentPos = in_buffer + 1;
-
- while (currentPos < in_bufferEnd - 1)
- {
- if (! currentPos[0] && ! currentPos[1])
- {
- * out_end = currentPos;
- * out_nextStart = * out_end + 1;
- return TRUE;
- }
- }
-
- return FALSE;
- }
-
- size_t lengthOctets = lengthDescription & LENGTH_LONGFORM_MASK;
-
- // We can't handle longer objects than size_t can represent.
- if (lengthOctets > sizeof (size_t))
- return FALSE;
-
- if (in_bufferEnd < in_buffer + 1 + lengthOctets)
- return FALSE;
-
- size_t contentLength = 0;
- size_t i = 0;
-
- for (i = 0; i < lengthOctets; i++)
- {
- contentLength <<= OCTET_BITS;
- contentLength |= in_buffer[i + 1];
- }
-
- * out_start = in_buffer + 1 + lengthOctets;
- * out_end = * out_start + contentLength;
-
- if (in_bufferEnd < * out_end)
- return FALSE;
-
- * out_nextStart = * out_end;
- return TRUE;
-}
-
-/**
- * Returns pointers that point to the content of DER data value.
- */
-static bool_t der_read_content (struct DerData * data, struct DerData * content)
-{
- unsigned char * lengthStart = NULL;
- bool_t typeOk = der_read_tag_number (data->start, data->bufferEnd,
- & lengthStart, & content->type);
-
- if (! typeOk)
- return FALSE;
-
- content->bufferEnd = data->bufferEnd;
- return der_read_content_length (lengthStart, data->bufferEnd,
- & content->start, & content->end, & content->nextStart);
-}
-
-/**
- * Returns pointers that point to next DER data value.
- */
-static bool_t der_read_next (struct DerData * currentContent, struct DerData * nextContent)
-{
- nextContent->start = currentContent->nextStart;
-
- unsigned char * lengthStart = NULL;
- bool_t typeOk = der_read_tag_number (currentContent->start,
- currentContent->bufferEnd, & lengthStart, & nextContent->type);
-
- if (! typeOk)
- return FALSE;
-
- unsigned char * nextContentStart = NULL;
- return der_read_content_length (lengthStart, currentContent->bufferEnd,
- & nextContentStart, & nextContent->end, & nextContent->nextStart);
-}
-
-/**
- * Returns certificate hash that can be used to certificate links generated
- * by c_rehash command.
- *
- * Certificate hash is just 4 first octets of MD5 sum of certificate subject id
- * DER format.
- *
- * @return TRUE if given certificate could be parsed by this, FALSE otherwise.
- */
-static bool_t cert_get_hash (const ne_ssl_certificate * cert, uint32_t * out_hash)
-{
- char * certPem = ne_ssl_cert_export (cert);
- g_return_val_if_fail (certPem != NULL, 1);
- size_t derLength = 0;
- unsigned char * certDer = g_base64_decode (certPem, &derLength);
- g_free (certPem);
- g_return_val_if_fail (certDer != NULL, 1);
-
- struct DerData data =
- {
- .start = certDer,
- .bufferEnd = (certDer + derLength)
- };
- struct DerData content;
-
- // Walk through certificate content until we reach subject field.
-
- // certificate
- g_return_val_if_fail (der_read_content (& data, & content), FALSE);
- g_return_val_if_fail (ASNTYPE_SEQUENCE == content.type, FALSE);
- // tbsCertificate
- g_return_val_if_fail (der_read_content (& content, & content), FALSE);
- g_return_val_if_fail (ASNTYPE_SEQUENCE == content.type, FALSE);
- // version + serialNumber
- g_return_val_if_fail (der_read_content (& content, & content), FALSE);
- g_return_val_if_fail (ASNTYPE_INTEGER == content.type, FALSE);
- // signature
- g_return_val_if_fail (der_read_next (& content, & content), FALSE);
- g_return_val_if_fail (ASNTYPE_SEQUENCE == content.type, FALSE);
- // issuer
- g_return_val_if_fail (der_read_next (& content, & content), FALSE);
- g_return_val_if_fail (ASNTYPE_SEQUENCE == content.type, FALSE);
- // validity
- g_return_val_if_fail (der_read_next (& content, & content), FALSE);
- g_return_val_if_fail (ASNTYPE_SEQUENCE == content.type, FALSE);
- // subject
- g_return_val_if_fail (der_read_next (& content, & content), FALSE);
- g_return_val_if_fail (ASNTYPE_SEQUENCE == content.type, FALSE);
-
- // Calculate MD5 sum of subject.
- unsigned char md5pword[16];
- size_t md5len = 16;
-
- GChecksum * state = g_checksum_new (G_CHECKSUM_MD5);
- g_checksum_update (state, content.start, content.nextStart - content.start);
- g_checksum_get_digest (state, md5pword, & md5len);
- g_checksum_free (state);
-
- uint32_t hash = 0;
-
- // Hash is reverse of four first bytes of MD5 checksum of DER encoded
- // subject ASN.1 field.
- for (int i = HASH_BYTES - 1; i >= 0; i --)
- {
- hash <<= OCTET_BITS;
- hash |= md5pword[i];
- }
-
- * out_hash = hash;
-
- g_free (certDer);
- return TRUE;
-}
-
-/**
- * Checks if given certificate is signed by given signer certificate.
- *
- * Goes up in certificate signer chain of certificate and compares if any one
- * of them is same as given signer.
- */
-static bool_t is_signer_of_cert (const ne_ssl_certificate * signer, const ne_ssl_certificate * cert)
-{
- const ne_ssl_certificate * certSigner = cert;
-
- while (certSigner != NULL)
- {
- if (ne_ssl_cert_cmp (signer, certSigner) == 0)
- return TRUE;
-
- certSigner = ne_ssl_cert_signedby (certSigner);
- }
-
- return FALSE;
-}
-
-/**
- * Checks if given file includes certificate that has signed given certificate.
- */
-static bool_t file_is_signer_of_cert (const char * filename, const ne_ssl_certificate * cert)
-{
- ne_ssl_certificate * signer = ne_ssl_cert_read (filename);
-
- if (signer != NULL)
- {
- bool_t signOk = is_signer_of_cert (signer, cert);
- ne_ssl_cert_free (signer);
-
- if (signOk)
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- * Checks if directory includes a file that can be signer of given certificate.
- */
-static bool_t validate_directory_certs (const char * directory,
- const ne_ssl_certificate * serverCert, uint32_t certHash)
-{
- // Search certificate names in ascending order and assume that all names
- // point to valid certificates.
- uint32_t certId = 0;
-
- while (certId < MAX_CERT_CHECKS)
- {
- // Construct certificate name.
- char certFilename[20] = {0};
- snprintf (certFilename, sizeof certFilename, "%08x.%d", certHash, certId);
- char * certPath = g_build_filename (directory, certFilename, NULL);
-
- bool_t signOk = file_is_signer_of_cert (certPath, serverCert);
- g_free (certPath);
-
- if (signOk)
- return TRUE;
-
- certId ++;
- }
-
- return FALSE;
-}
-
-/**
- * Checks if given certificate is valid certificate according to certificates
- * found from SSL_CERT_FILE or SSL_CERT_DIR environmental variables.
- */
-int neon_vfs_verify_environment_ssl_certs (void * userdata, int failures,
- const ne_ssl_certificate * serverCert)
-{
- // First check the certificate file, if we have one.
- const char * sslCertFile = g_getenv ("SSL_CERT_FILE");
-
- if (sslCertFile != NULL)
- {
- if (file_is_signer_of_cert (sslCertFile, serverCert))
- return failures & ~NE_SSL_UNTRUSTED;
- }
-
- // check if we have list of directories where certificates can be.
- const char * sslCertDirPaths = g_getenv ("SSL_CERT_DIR");
-
- if (sslCertDirPaths == NULL)
- return failures;
-
- uint32_t certHash = 0;
- g_return_val_if_fail (cert_get_hash (serverCert, & certHash), failures);
-
- char * sslCertDirPathsStart = g_strdup (sslCertDirPaths);
- char * sslCertDirPathsEnd = sslCertDirPathsStart + strlen (sslCertDirPathsStart);
- char * sslCertDir = sslCertDirPathsStart;
- char * dirnameStart = sslCertDir;
- char * dirnameEnd = dirnameStart;
-
- // Start going through all directories in SSL_CERT_DIR
- for (; dirnameEnd <= sslCertDirPathsEnd; dirnameEnd ++)
- {
- if (* dirnameEnd == G_SEARCHPATH_SEPARATOR || dirnameEnd == sslCertDirPathsEnd)
- {
- * dirnameEnd = 0;
-
- // Skip empty directories
- if (dirnameStart[0] == 0)
- {
- // Start next directory name after the inserted zero.
- dirnameStart = dirnameEnd + 1;
- continue;
- }
-
- if (validate_directory_certs (dirnameStart, serverCert, certHash))
- {
- g_free (sslCertDirPathsStart);
- return failures & ~NE_SSL_UNTRUSTED;
- }
-
- // Start next directory name after the inserted zero.
- dirnameStart = dirnameEnd + 1;
- }
- }
-
- g_free (sslCertDirPathsStart);
-
- return failures;
-}
diff --git a/src/neon/cert_verification.cc b/src/neon/cert_verification.cc
new file mode 100644
index 000000000000..8ffd9529960e
--- /dev/null
+++ b/src/neon/cert_verification.cc
@@ -0,0 +1,427 @@
+/*
+ * Wget like SSL certificate validation from environmental variables.
+ * Copyright (C) 2009 Jussi Judin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#define __STDC_LIMIT_MACROS
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <ne_ssl.h>
+#include <ne_session.h>
+
+#include <libaudcore/audstrings.h>
+
+#include "cert_verification.h"
+
+// Certificate validation handling.
+
+const int LENGTH_SHORTFORM_MAX = 127;
+const int LENGTH_INDEFINITE_VALUE = 128;
+const int LENGTH_LONGFORM_MASK = 0x7f;
+const int OCTET_BITS = 8;
+const int ASNTYPE_CODE_MASK = 0x1f;
+const int HASH_BYTES = 4;
+const uint32_t MAX_CERT_CHECKS = UINT32_MAX;
+
+enum AsnType
+{
+ ASNTYPE_INTEGER = 2,
+ ASNTYPE_SEQUENCE = 16,
+ ASNTYPE_VARLEN_IDENTIFIER = 31
+};
+
+struct DerData
+{
+ unsigned char * start;
+ unsigned char * end;
+ unsigned char * nextStart;
+ unsigned char * bufferEnd;
+ enum AsnType type;
+};
+
+/**
+ * X.509 certificate has following structure defined in RFC5280:
+ *
+ * Certificate ::= SEQUENCE {
+ * tbsCertificate TBSCertificate,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signatureValue BIT STRING }
+ *
+ * TBSCertificate ::= SEQUENCE {
+ * version [0] EXPLICIT Version DEFAULT v1,
+ * serialNumber CertificateSerialNumber,
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * validity Validity,
+ * subject Name,
+ * ...
+ *
+ * Version ::= INTEGER { v1(0), v2(1), v3(2) }
+ * CertificateSerialNumber ::= INTEGER
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL }
+ * Validity ::= SEQUENCE {
+ * notBefore Time,
+ * notAfter Time }
+ * Time ::= CHOICE {
+ * utcTime UTCTime,
+ * generalTime GeneralizedTime }
+ * Name ::= CHOICE { -- only one possibility for now --
+ * rdnSequence RDNSequence }
+ * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+ *
+ * And we are only interested in subject field.
+ */
+
+/**
+ * Returns the tag number of DER data.
+ */
+static bool der_read_tag_number (unsigned char * in_buffer,
+ const unsigned char * in_bufferEnd, unsigned char * * out_lengthStart,
+ enum AsnType * out_type)
+{
+ if (in_bufferEnd - in_buffer < 2)
+ return FALSE;
+
+ unsigned char typeOctet = in_buffer[0];
+ enum AsnType typeCode = (AsnType) (typeOctet & ASNTYPE_CODE_MASK);
+ int typeCodeLength = 1;
+
+ // Variable length types are not supported.
+ if (typeCode == ASNTYPE_VARLEN_IDENTIFIER)
+ return FALSE;
+
+ * out_type = typeCode;
+ * out_lengthStart = in_buffer + typeCodeLength;
+
+ return TRUE;
+}
+
+/**
+ * Returns pointers that point to the content of DER data value when identifier
+ * is not present.
+ */
+static bool der_read_content_length (unsigned char * in_buffer,
+ const unsigned char * in_bufferEnd, unsigned char * * out_start,
+ unsigned char * * out_end, unsigned char * * out_nextStart)
+{
+ if (in_bufferEnd - in_buffer < 1)
+ return FALSE;
+
+ unsigned char lengthDescription = in_buffer[0];
+
+ if (lengthDescription <= LENGTH_SHORTFORM_MAX)
+ {
+ * out_start = in_buffer + 1;
+ * out_end = * out_start + lengthDescription;
+
+ if (in_bufferEnd < * out_end)
+ return FALSE;
+
+ * out_nextStart = * out_end;
+ return TRUE;
+ }
+
+ if (lengthDescription == LENGTH_INDEFINITE_VALUE)
+ {
+ * out_start = in_buffer + 1;
+ unsigned char * currentPos = in_buffer + 1;
+
+ while (currentPos < in_bufferEnd - 1)
+ {
+ if (! currentPos[0] && ! currentPos[1])
+ {
+ * out_end = currentPos;
+ * out_nextStart = * out_end + 1;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+ }
+
+ size_t lengthOctets = lengthDescription & LENGTH_LONGFORM_MASK;
+
+ // We can't handle longer objects than size_t can represent.
+ if (lengthOctets > sizeof (size_t))
+ return FALSE;
+
+ if (in_bufferEnd < in_buffer + 1 + lengthOctets)
+ return FALSE;
+
+ size_t contentLength = 0;
+ size_t i = 0;
+
+ for (i = 0; i < lengthOctets; i++)
+ {
+ contentLength <<= OCTET_BITS;
+ contentLength |= in_buffer[i + 1];
+ }
+
+ * out_start = in_buffer + 1 + lengthOctets;
+ * out_end = * out_start + contentLength;
+
+ if (in_bufferEnd < * out_end)
+ return FALSE;
+
+ * out_nextStart = * out_end;
+ return TRUE;
+}
+
+/**
+ * Returns pointers that point to the content of DER data value.
+ */
+static bool der_read_content (struct DerData * data, struct DerData * content)
+{
+ unsigned char * lengthStart = nullptr;
+ bool typeOk = der_read_tag_number (data->start, data->bufferEnd,
+ & lengthStart, & content->type);
+
+ if (! typeOk)
+ return FALSE;
+
+ content->bufferEnd = data->bufferEnd;
+ return der_read_content_length (lengthStart, data->bufferEnd,
+ & content->start, & content->end, & content->nextStart);
+}
+
+/**
+ * Returns pointers that point to next DER data value.
+ */
+static bool der_read_next (struct DerData * currentContent, struct DerData * nextContent)
+{
+ nextContent->start = currentContent->nextStart;
+
+ unsigned char * lengthStart = nullptr;
+ bool typeOk = der_read_tag_number (currentContent->start,
+ currentContent->bufferEnd, & lengthStart, & nextContent->type);
+
+ if (! typeOk)
+ return FALSE;
+
+ unsigned char * nextContentStart = nullptr;
+ return der_read_content_length (lengthStart, currentContent->bufferEnd,
+ & nextContentStart, & nextContent->end, & nextContent->nextStart);
+}
+
+/**
+ * Returns certificate hash that can be used to certificate links generated
+ * by c_rehash command.
+ *
+ * Certificate hash is just 4 first octets of MD5 sum of certificate subject id
+ * DER format.
+ *
+ * @return TRUE if given certificate could be parsed by this, FALSE otherwise.
+ */
+static bool cert_get_hash (const ne_ssl_certificate * cert, uint32_t * out_hash)
+{
+ char * certPem = ne_ssl_cert_export (cert);
+ g_return_val_if_fail (certPem != nullptr, 1);
+ size_t derLength = 0;
+ unsigned char * certDer = g_base64_decode (certPem, &derLength);
+ g_free (certPem);
+ g_return_val_if_fail (certDer != nullptr, 1);
+
+ struct DerData data = {0};
+ struct DerData content = {0};
+
+ data.start = certDer;
+ data.bufferEnd = certDer + derLength;
+
+ // Walk through certificate content until we reach subject field.
+
+ // certificate
+ g_return_val_if_fail (der_read_content (& data, & content), FALSE);
+ g_return_val_if_fail (ASNTYPE_SEQUENCE == content.type, FALSE);
+ // tbsCertificate
+ g_return_val_if_fail (der_read_content (& content, & content), FALSE);
+ g_return_val_if_fail (ASNTYPE_SEQUENCE == content.type, FALSE);
+ // version + serialNumber
+ g_return_val_if_fail (der_read_content (& content, & content), FALSE);
+ g_return_val_if_fail (ASNTYPE_INTEGER == content.type, FALSE);
+ // signature
+ g_return_val_if_fail (der_read_next (& content, & content), FALSE);
+ g_return_val_if_fail (ASNTYPE_SEQUENCE == content.type, FALSE);
+ // issuer
+ g_return_val_if_fail (der_read_next (& content, & content), FALSE);
+ g_return_val_if_fail (ASNTYPE_SEQUENCE == content.type, FALSE);
+ // validity
+ g_return_val_if_fail (der_read_next (& content, & content), FALSE);
+ g_return_val_if_fail (ASNTYPE_SEQUENCE == content.type, FALSE);
+ // subject
+ g_return_val_if_fail (der_read_next (& content, & content), FALSE);
+ g_return_val_if_fail (ASNTYPE_SEQUENCE == content.type, FALSE);
+
+ // Calculate MD5 sum of subject.
+ unsigned char md5pword[16];
+ size_t md5len = 16;
+
+ GChecksum * state = g_checksum_new (G_CHECKSUM_MD5);
+ g_checksum_update (state, content.start, content.nextStart - content.start);
+ g_checksum_get_digest (state, md5pword, & md5len);
+ g_checksum_free (state);
+
+ uint32_t hash = 0;
+
+ // Hash is reverse of four first bytes of MD5 checksum of DER encoded
+ // subject ASN.1 field.
+ for (int i = HASH_BYTES - 1; i >= 0; i --)
+ {
+ hash <<= OCTET_BITS;
+ hash |= md5pword[i];
+ }
+
+ * out_hash = hash;
+
+ g_free (certDer);
+ return TRUE;
+}
+
+/**
+ * Checks if given certificate is signed by given signer certificate.
+ *
+ * Goes up in certificate signer chain of certificate and compares if any one
+ * of them is same as given signer.
+ */
+static bool is_signer_of_cert (const ne_ssl_certificate * signer, const ne_ssl_certificate * cert)
+{
+ const ne_ssl_certificate * certSigner = cert;
+
+ while (certSigner != nullptr)
+ {
+ if (ne_ssl_cert_cmp (signer, certSigner) == 0)
+ return TRUE;
+
+ certSigner = ne_ssl_cert_signedby (certSigner);
+ }
+
+ return FALSE;
+}
+
+/**
+ * Checks if given file includes certificate that has signed given certificate.
+ */
+static bool file_is_signer_of_cert (const char * filename, const ne_ssl_certificate * cert)
+{
+ ne_ssl_certificate * signer = ne_ssl_cert_read (filename);
+
+ if (signer != nullptr)
+ {
+ bool signOk = is_signer_of_cert (signer, cert);
+ ne_ssl_cert_free (signer);
+
+ if (signOk)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * Checks if directory includes a file that can be signer of given certificate.
+ */
+static bool validate_directory_certs (const char * directory,
+ const ne_ssl_certificate * serverCert, uint32_t certHash)
+{
+ // Search certificate names in ascending order and assume that all names
+ // point to valid certificates.
+ uint32_t certId = 0;
+
+ while (certId < MAX_CERT_CHECKS)
+ {
+ // Construct certificate name.
+ StringBuf certFilename = str_printf ("%08x.%d", certHash, certId);
+ char * certPath = g_build_filename (directory, (const char *) certFilename, nullptr);
+
+ bool signOk = file_is_signer_of_cert (certPath, serverCert);
+ g_free (certPath);
+
+ if (signOk)
+ return TRUE;
+
+ certId ++;
+ }
+
+ return FALSE;
+}
+
+/**
+ * Checks if given certificate is valid certificate according to certificates
+ * found from SSL_CERT_FILE or SSL_CERT_DIR environmental variables.
+ */
+int neon_vfs_verify_environment_ssl_certs (void * userdata, int failures,
+ const ne_ssl_certificate * serverCert)
+{
+ // First check the certificate file, if we have one.
+ const char * sslCertFile = g_getenv ("SSL_CERT_FILE");
+
+ if (sslCertFile != nullptr)
+ {
+ if (file_is_signer_of_cert (sslCertFile, serverCert))
+ return failures & ~NE_SSL_UNTRUSTED;
+ }
+
+ // check if we have list of directories where certificates can be.
+ const char * sslCertDirPaths = g_getenv ("SSL_CERT_DIR");
+
+ if (sslCertDirPaths == nullptr)
+ return failures;
+
+ uint32_t certHash = 0;
+ g_return_val_if_fail (cert_get_hash (serverCert, & certHash), failures);
+
+ char * sslCertDirPathsStart = g_strdup (sslCertDirPaths);
+ char * sslCertDirPathsEnd = sslCertDirPathsStart + strlen (sslCertDirPathsStart);
+ char * sslCertDir = sslCertDirPathsStart;
+ char * dirnameStart = sslCertDir;
+ char * dirnameEnd = dirnameStart;
+
+ // Start going through all directories in SSL_CERT_DIR
+ for (; dirnameEnd <= sslCertDirPathsEnd; dirnameEnd ++)
+ {
+ if (* dirnameEnd == G_SEARCHPATH_SEPARATOR || dirnameEnd == sslCertDirPathsEnd)
+ {
+ * dirnameEnd = 0;
+
+ // Skip empty directories
+ if (dirnameStart[0] == 0)
+ {
+ // Start next directory name after the inserted zero.
+ dirnameStart = dirnameEnd + 1;
+ continue;
+ }
+
+ if (validate_directory_certs (dirnameStart, serverCert, certHash))
+ {
+ g_free (sslCertDirPathsStart);
+ return failures & ~NE_SSL_UNTRUSTED;
+ }
+
+ // Start next directory name after the inserted zero.
+ dirnameStart = dirnameEnd + 1;
+ }
+ }
+
+ g_free (sslCertDirPathsStart);
+
+ return failures;
+}
diff --git a/src/neon/debug.h b/src/neon/debug.h
deleted file mode 100644
index a6b1c1a2661d..000000000000
--- a/src/neon/debug.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2005 Ralf Ertzinger
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-#ifndef DEBUG_H
-#define DEBUG_H
-
-#include <stdio.h>
-
-#define _ERROR(...) do { printf ("neon: " __VA_ARGS__); putchar ('\n'); } while (0)
-
-#ifdef NEON_DEBUG
-#define _DEBUG _ERROR
-#else
-#define _DEBUG(...)
-#endif
-
-#endif
diff --git a/src/neon/neon.c b/src/neon/neon.c
deleted file mode 100644
index fa7c12a522a1..000000000000
--- a/src/neon/neon.c
+++ /dev/null
@@ -1,1062 +0,0 @@
-/*
- * A neon HTTP input plugin for Audacious
- * Copyright (C) 2007 Ralf Ertzinger
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <inttypes.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <glib.h>
-
-#ifdef DEBUG
-#define NEON_DEBUG
-#endif
-
-#include "neon.h"
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-#include <ne_socket.h>
-#include <ne_utils.h>
-#include <ne_redirect.h>
-#include <ne_request.h>
-#include <ne_auth.h>
-
-#include "debug.h"
-#include "rb.h"
-#include "cert_verification.h"
-
-#define NEON_BUFSIZE (128u*1024u)
-#define NEON_NETBLKSIZE (4096u)
-#define NEON_ICY_BUFSIZE (4096)
-#define NEON_RETRY_COUNT 6
-
-static bool_t neon_plugin_init (void)
-{
- int ret = ne_sock_init ();
-
- if (ret != 0)
- {
- _ERROR ("Could not initialize neon library: %d\n", ret);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void neon_plugin_fini (void)
-{
- ne_sock_exit ();
-}
-
-static struct neon_handle * handle_init (void)
-{
- struct neon_handle * h = g_new0 (struct neon_handle, 1);
-
- pthread_mutex_init (& h->reader_status.mutex, NULL);
- pthread_cond_init (& h->reader_status.cond, NULL);
- h->reader_status.reading = FALSE;
- h->reader_status.status = NEON_READER_INIT;
-
- init_rb_with_lock (& h->rb, NEON_BUFSIZE, & h->reader_status.mutex);
-
- h->purl = g_new0 (ne_uri, 1);
- h->content_length = -1;
-
- return h;
-}
-
-static void handle_free (struct neon_handle * h)
-{
- ne_uri_free (h->purl);
- g_free (h->purl);
- destroy_rb (& h->rb);
-
- pthread_mutex_destroy (& h->reader_status.mutex);
- pthread_cond_destroy (& h->reader_status.cond);
-
- g_free (h->icy_metadata.stream_name);
- g_free (h->icy_metadata.stream_title);
- g_free (h->icy_metadata.stream_url);
- g_free (h->icy_metadata.stream_contenttype);
- g_free (h->url);
- g_free (h);
-}
-
-static bool_t neon_strcmp (const char * str, const char * cmp)
-{
- return ! g_ascii_strncasecmp (str, cmp, strlen (cmp));
-}
-
-static void add_icy (struct icy_metadata * m, char * name, char * value)
-{
- if (neon_strcmp (name, "StreamTitle"))
- {
- _DEBUG ("Found StreamTitle: %s", value);
- g_free (m->stream_title);
- m->stream_title = g_strdup (value);
- }
-
- if (neon_strcmp (name, "StreamUrl"))
- {
- _DEBUG ("Found StreamUrl: %s", value);
- g_free (m->stream_url);
- m->stream_url = g_strdup (value);
- }
-}
-
-static void parse_icy (struct icy_metadata * m, char * metadata, size_t len)
-{
- typedef enum
- {
- STATE_READ_NAME,
- STATE_WAIT_VALUE,
- STATE_READ_VALUE,
- STATE_WAIT_NAME,
- } TagReadState;
-
- TagReadState state = STATE_READ_NAME;
-
- char * p = metadata;
- char * tstart = metadata;
- size_t pos = 1;
-
- char name[NEON_ICY_BUFSIZE];
- char value[NEON_ICY_BUFSIZE];
-
- name[0] = 0;
- value[0] = 0;
-
- while (pos < len && p[0])
- {
- switch (state)
- {
- case STATE_READ_NAME:
-
- /* Reading tag name */
- if (p[0] == '=')
- {
- /* End of tag name. */
- p[0] = 0;
- g_strlcpy (name, tstart, NEON_ICY_BUFSIZE);
- _DEBUG ("Found tag name: %s", name);
- state = STATE_WAIT_VALUE;
- }
-
- break;
-
- case STATE_WAIT_VALUE:
-
- /* Waiting for start of value */
- if (p[0] == '\'')
- {
- /* Leading ' of value */
- tstart = p + 1;
- state = STATE_READ_VALUE;
- value[0] = 0;
- }
-
- break;
-
- case STATE_READ_VALUE:
-
- /* Reading value */
- if (p[0] == '\'' && p[1] == ';')
- {
- /* End of value */
- p[0] = 0;
- g_strlcpy (value, tstart, NEON_ICY_BUFSIZE);
- _DEBUG ("Found tag value: %s", value);
- add_icy (m, name, value);
- state = STATE_WAIT_NAME;
- }
-
- break;
-
- case STATE_WAIT_NAME:
-
- /* Waiting for next tag start */
- if (p[0] == ';')
- {
- /* Next tag name starts after this char */
- tstart = p + 1;
- state = STATE_READ_NAME;
- name[0] = 0;
- value[0] = 0;
- }
-
- break;
- }
-
- p ++;
- pos ++;
- }
-}
-
-static void kill_reader (struct neon_handle * h)
-{
- _DEBUG ("Signaling reader thread to terminate");
- pthread_mutex_lock (& h->reader_status.mutex);
- h->reader_status.reading = FALSE;
- pthread_cond_broadcast (& h->reader_status.cond);
- pthread_mutex_unlock (& h->reader_status.mutex);
-
- _DEBUG ("Waiting for reader thread to die...");
- pthread_join (h->reader, NULL);
- _DEBUG ("Reader thread has died");
-}
-
-static int server_auth_callback (void * userdata, const char * realm,
- int attempt, char * username, char * password)
-{
- struct neon_handle * h = userdata;
-
- if (! h->purl->userinfo || ! h->purl->userinfo[0])
- {
- _ERROR ("Authentication required, but no credentials set");
- return 1;
- }
-
- char * * authtok = g_strsplit (h->purl->userinfo, ":", 2);
-
- if (strlen (authtok[1]) > NE_ABUFSIZ - 1 || strlen (authtok[0]) > NE_ABUFSIZ - 1)
- {
- _ERROR ("Username/Password too long");
- g_strfreev (authtok);
- return 1;
- }
-
- g_strlcpy (username, authtok[0], NE_ABUFSIZ);
- g_strlcpy (password, authtok[1], NE_ABUFSIZ);
-
- _DEBUG ("Authenticating: Username: %s, Password: %s", username, password);
-
- g_strfreev (authtok);
-
- return attempt;
-}
-
-static void handle_headers (struct neon_handle * h)
-{
- const char * name;
- const char * value;
- void * cursor = NULL;
-
- _DEBUG ("Header responses:");
-
- while ((cursor = ne_response_header_iterate (h->request, cursor, & name, & value)))
- {
- _DEBUG ("HEADER: %s: %s", name, value);
-
- if (neon_strcmp (name, "accept-ranges"))
- {
- /* The server advertises range capability. we need "bytes" */
- if (strstr (value, "bytes"))
- {
- _DEBUG ("server can_ranges");
- h->can_ranges = TRUE;
- }
- }
- else if (neon_strcmp (name, "content-length"))
- {
- /* The server sent us the content length. Parse and store. */
- char * endptr;
- long len = strtol (value, & endptr, 10);
-
- if (value[0] && ! endptr[0] && len >= 0)
- {
- /* Valid data. */
- _DEBUG ("Content length as advertised by server: %ld", len);
- h->content_length = len;
- }
- else
- _ERROR ("Invalid content length header: %s", value);
- }
- else if (neon_strcmp (name, "content-type"))
- {
- /* The server sent us a content type. Save it for later */
- _DEBUG ("Content-Type: %s", value);
- g_free (h->icy_metadata.stream_contenttype);
- h->icy_metadata.stream_contenttype = g_strdup (value);
- }
- else if (neon_strcmp (name, "icy-metaint"))
- {
- /* The server sent us a ICY metaint header. Parse and store. */
- char * endptr;
- long len = strtol (value, & endptr, 10);
-
- if (value[0] && ! endptr[0] && len > 0)
- {
- /* Valid data */
- _DEBUG ("ICY MetaInt as advertised by server: %ld", len);
- h->icy_metaint = len;
- h->icy_metaleft = len;
- }
- else
- _ERROR ("Invalid ICY MetaInt header: %s", value);
- }
- else if (neon_strcmp (name, "icy-name"))
- {
- /* The server sent us a ICY name. Save it for later */
- _DEBUG ("ICY stream name: %s", value);
- g_free (h->icy_metadata.stream_name);
- h->icy_metadata.stream_name = g_strdup (value);
- }
- else if (neon_strcmp (name, "icy-br"))
- {
- /* The server sent us a bitrate. We might want to use it. */
- _DEBUG ("ICY bitrate: %d", atoi (value));
- h->icy_metadata.stream_bitrate = atoi (value);
- }
- }
-}
-
-static int neon_proxy_auth_cb (void * userdata, const char * realm, int attempt,
- char * username, char * password)
-{
- char * value = aud_get_str (NULL, "proxy_user");
- g_strlcpy (username, value, NE_ABUFSIZ);
- str_unref (value);
-
- value = aud_get_str (NULL, "proxy_pass");
- g_strlcpy (password, value, NE_ABUFSIZ);
- str_unref (value);
-
- return attempt;
-}
-
-static int open_request (struct neon_handle * handle, uint64_t startbyte)
-{
- int ret;
- const ne_status * status;
- ne_uri * rediruri;
-
- if (handle->purl->query && * (handle->purl->query))
- {
- SCONCAT3 (tmp, handle->purl->path, "?", handle->purl->query);
- handle->request = ne_request_create (handle->session, "GET", tmp);
- }
- else
- handle->request = ne_request_create (handle->session, "GET", handle->purl->path);
-
- if (startbyte > 0)
- ne_print_request_header (handle->request, "Range", "bytes=%"PRIu64"-", startbyte);
-
- ne_print_request_header (handle->request, "Icy-MetaData", "1");
-
- /* Try to connect to the server. */
- _DEBUG ("<%p> Connecting...", handle);
- ret = ne_begin_request (handle->request);
- status = ne_get_status (handle->request);
- _DEBUG ("<%p> Return: %d, Status: %d", handle, ret, status->code);
-
- if (ret == NE_OK)
- {
- switch (status->code)
- {
- case 401:
- /* Authorization required. Reconnect to authenticate */
- _DEBUG ("Reconnecting due to 401");
- ne_end_request (handle->request);
- ret = ne_begin_request (handle->request);
- break;
-
- case 301:
- case 302:
- case 303:
- case 307:
- /* Redirect encountered. Reconnect. */
- ne_end_request (handle->request);
- ret = NE_REDIRECT;
- break;
-
- case 407:
- /* Proxy auth required. Reconnect to authenticate */
- _DEBUG ("Reconnecting due to 407");
- ne_end_request (handle->request);
- ret = ne_begin_request (handle->request);
- break;
- }
- }
-
- switch (ret)
- {
- case NE_OK:
- if (status->code > 199 && status->code < 300)
- {
- /* URL opened OK */
- _DEBUG ("<%p> URL opened OK", handle);
- handle->content_start = startbyte;
- handle->pos = startbyte;
- handle_headers (handle);
- return 0;
- }
-
- break;
-
- case NE_REDIRECT:
- /* We hit a redirect. Handle it. */
- _DEBUG ("<%p> Redirect encountered", handle);
- handle->redircount += 1;
- rediruri = (ne_uri *) ne_redirect_location (handle->session);
- ne_request_destroy (handle->request);
- handle->request = NULL;
-
- if (! rediruri)
- {
- _ERROR ("<%p> Could not parse redirect response", (void *) handle);
- return -1;
- }
-
- ne_uri_free (handle->purl);
- ne_uri_copy (handle->purl, rediruri);
- return 1;
- }
-
- /* Something went wrong. */
- _ERROR ("<%p> Could not open URL: %d (%d)", (void *) handle, ret, status->code);
-
- if (ret)
- _ERROR ("<%p> neon error string: %s", (void *) handle, ne_get_error (handle->session));
-
- ne_request_destroy (handle->request);
- handle->request = NULL;
- return -1;
-}
-
-static int open_handle (struct neon_handle * handle, uint64_t startbyte)
-{
- int ret;
- char * proxy_host = NULL;
- int proxy_port = 0;
-
- bool_t use_proxy = aud_get_bool (NULL, "use_proxy");
- bool_t use_proxy_auth = aud_get_bool (NULL, "use_proxy_auth");
-
- if (use_proxy)
- {
- proxy_host = aud_get_str (NULL, "proxy_host");
- proxy_port = aud_get_int (NULL, "proxy_port");
- }
-
- handle->redircount = 0;
-
- _DEBUG ("<%p> Parsing URL", handle);
-
- if (ne_uri_parse (handle->url, handle->purl) != 0)
- {
- _ERROR ("<%p> Could not parse URL '%s'", (void *) handle, handle->url);
- return -1;
- }
-
- while (handle->redircount < 10)
- {
- if (! handle->purl->port)
- handle->purl->port = ne_uri_defaultport (handle->purl->scheme);
-
- _DEBUG ("<%p> Creating session to %s://%s:%d", handle,
- handle->purl->scheme, handle->purl->host, handle->purl->port);
- handle->session = ne_session_create (handle->purl->scheme,
- handle->purl->host, handle->purl->port);
- ne_redirect_register (handle->session);
- ne_add_server_auth (handle->session, NE_AUTH_BASIC, server_auth_callback, (void *) handle);
- ne_set_session_flag (handle->session, NE_SESSFLAG_ICYPROTO, 1);
- ne_set_session_flag (handle->session, NE_SESSFLAG_PERSIST, 0);
-
-#ifdef HAVE_NE_SET_CONNECT_TIMEOUT
- ne_set_connect_timeout (handle->session, 10);
-#endif
-
- ne_set_read_timeout (handle->session, 10);
- ne_set_useragent (handle->session, "Audacious/" PACKAGE_VERSION);
-
- if (use_proxy)
- {
- _DEBUG ("<%p> Using proxy: %s:%d", handle, proxy_host, proxy_port);
- ne_session_proxy (handle->session, proxy_host, proxy_port);
-
- if (use_proxy_auth)
- {
- _DEBUG ("<%p> Using proxy authentication", handle);
- ne_add_proxy_auth (handle->session, NE_AUTH_BASIC,
- neon_proxy_auth_cb, (void *) handle);
- }
- }
-
- if (! strcmp ("https", handle->purl->scheme))
- {
- ne_ssl_trust_default_ca (handle->session);
- ne_ssl_set_verify (handle->session,
- neon_vfs_verify_environment_ssl_certs, handle->session);
- }
-
- _DEBUG ("<%p> Creating request", handle);
- ret = open_request (handle, startbyte);
-
- if (! ret)
- {
- str_unref (proxy_host);
- return 0;
- }
-
- if (ret == -1)
- {
- ne_session_destroy (handle->session);
- handle->session = NULL;
- str_unref (proxy_host);
- return -1;
- }
-
- _DEBUG ("<%p> Following redirect...", handle);
- ne_session_destroy (handle->session);
- handle->session = NULL;
- }
-
- /* If we get here, our redirect count exceeded */
- _ERROR ("<%p> Redirect count exceeded for URL %s", (void *) handle, handle->url);
-
- str_unref (proxy_host);
- return 1;
-}
-
-typedef enum
-{
- FILL_BUFFER_SUCCESS,
- FILL_BUFFER_ERROR,
- FILL_BUFFER_EOF
-} FillBufferResult;
-
-static FillBufferResult fill_buffer (struct neon_handle * h)
-{
- int bsize = free_rb (& h->rb);
- int to_read = MIN (bsize, NEON_NETBLKSIZE);
-
- char buffer[NEON_NETBLKSIZE];
-
- bsize = ne_read_response_block (h->request, buffer, to_read);
-
- if (! bsize)
- {
- _DEBUG ("<%p> End of file encountered", h);
- return FILL_BUFFER_EOF;
- }
-
- if (bsize < 0)
- {
- _ERROR ("<%p> Error while reading from the network", (void *) h);
- ne_request_destroy (h->request);
- h->request = NULL;
- return FILL_BUFFER_ERROR;
- }
-
- _DEBUG ("<%p> Read %d bytes of %d", h, bsize, to_read);
-
- write_rb (& h->rb, buffer, bsize);
-
- return FILL_BUFFER_SUCCESS;
-}
-
-static void * reader_thread (void * data)
-{
- struct neon_handle * h = data;
-
- pthread_mutex_lock (& h->reader_status.mutex);
-
- while (h->reader_status.reading)
- {
- /* Hit the network only if we have more than NEON_NETBLKSIZE of free buffer */
- if (NEON_NETBLKSIZE < free_rb_locked (& h->rb))
- {
- pthread_mutex_unlock (& h->reader_status.mutex);
-
- FillBufferResult ret = fill_buffer (h);
-
- pthread_mutex_lock (& h->reader_status.mutex);
-
- /* Wake up main thread if it is waiting. */
- pthread_cond_broadcast (& h->reader_status.cond);
-
- if (ret == FILL_BUFFER_ERROR)
- {
- _ERROR ("<%p> Error while reading from the network. "
- "Terminating reader thread", (void *) h);
- h->reader_status.status = NEON_READER_ERROR;
- pthread_mutex_unlock (& h->reader_status.mutex);
- return NULL;
- }
- else if (ret == FILL_BUFFER_EOF)
- {
- _DEBUG ("<%p> EOF encountered while reading from the network. "
- "Terminating reader thread", (void *) h);
- h->reader_status.status = NEON_READER_EOF;
- pthread_mutex_unlock (& h->reader_status.mutex);
- return NULL;
- }
- }
- else
- {
- /* Not enough free space in the buffer.
- * Sleep until the main thread wakes us up. */
- pthread_cond_wait (& h->reader_status.cond, & h->reader_status.mutex);
- }
- }
-
- _DEBUG ("<%p> Reader thread terminating gracefully", h);
- h->reader_status.status = NEON_READER_TERM;
- pthread_mutex_unlock (& h->reader_status.mutex);
-
- return NULL;
-}
-
-void * neon_vfs_fopen_impl (const char * path, const char * mode)
-{
- struct neon_handle * handle = handle_init ();
-
- _DEBUG ("<%p> Trying to open '%s' with neon", (void *) handle, path);
-
- handle->url = g_strdup (path);
-
- if (open_handle (handle, 0) != 0)
- {
- _ERROR ("<%p> Could not open URL", (void *) handle);
- handle_free (handle);
- return NULL;
- }
-
- return handle;
-}
-
-int neon_vfs_fclose_impl (VFSFile * file)
-{
- struct neon_handle * h = vfs_get_handle (file);
-
- if (h->reader_status.reading)
- kill_reader (h);
-
- if (h->request)
- ne_request_destroy (h->request);
- if (h->session)
- ne_session_destroy (h->session);
-
- handle_free (h);
-
- return 0;
-}
-
-static int64_t neon_fread_real (void * ptr, int64_t size, int64_t nmemb, VFSFile * file)
-{
- struct neon_handle * h = vfs_get_handle (file);
-
- if (! h->request)
- {
- _ERROR ("<%p> No request to read from, seek gone wrong?", (void *) h);
- return 0;
- }
-
- if (! size || ! nmemb || h->eof)
- return 0;
-
- /* If the buffer is empty, wait for the reader thread to fill it. */
- pthread_mutex_lock (& h->reader_status.mutex);
-
- for (int retries = 0; retries < NEON_RETRY_COUNT; retries ++)
- {
- if (used_rb_locked (& h->rb) / size > 0 || ! h->reader_status.reading ||
- h->reader_status.status != NEON_READER_RUN)
- break;
-
- pthread_cond_broadcast (& h->reader_status.cond);
- pthread_cond_wait (& h->reader_status.cond, & h->reader_status.mutex);
- }
-
- pthread_mutex_unlock (& h->reader_status.mutex);
-
- if (! h->reader_status.reading)
- {
- if (h->reader_status.status != NEON_READER_EOF || h->content_length != -1)
- {
- /* There is no reader thread yet. Read the first bytes from
- * the network ourselves, and then fire up the reader thread
- * to keep the buffer filled up. */
- _DEBUG ("<%p> Doing initial buffer fill", h);
- FillBufferResult ret = fill_buffer (h);
-
- if (ret == FILL_BUFFER_ERROR)
- {
- _ERROR ("<%p> Error while reading from the network", (void *) h);
- return 0;
- }
-
- /* We have some data in the buffer now.
- * Start the reader thread if we did not reach EOF during
- * the initial fill */
- pthread_mutex_lock (& h->reader_status.mutex);
-
- if (ret == FILL_BUFFER_SUCCESS)
- {
- h->reader_status.reading = TRUE;
- _DEBUG ("<%p> Starting reader thread", h);
- pthread_create (& h->reader, NULL, reader_thread, h);
- h->reader_status.status = NEON_READER_RUN;
- }
- else if (ret == FILL_BUFFER_EOF)
- {
- _DEBUG ("<%p> No reader thread needed (stream has reached EOF during fill)", h);
- h->reader_status.reading = FALSE;
- h->reader_status.status = NEON_READER_EOF;
- }
-
- pthread_mutex_unlock (& h->reader_status.mutex);
- }
- }
- else
- {
- /* There already is a reader thread. Look if it is in good shape. */
- pthread_mutex_lock (& h->reader_status.mutex);
-
- switch (h->reader_status.status)
- {
- case NEON_READER_INIT:
- case NEON_READER_RUN:
- /* All is well, nothing to be done. */
- break;
-
- case NEON_READER_ERROR:
- /* A reader error happened. Log it, and treat it like an EOF
- * condition, by falling through to the NEON_READER_EOF codepath. */
- _DEBUG ("<%p> NEON_READER_ERROR happened. Terminating reader thread and marking EOF.", h);
- h->reader_status.status = NEON_READER_EOF;
- pthread_mutex_unlock (& h->reader_status.mutex);
-
- if (h->reader_status.reading)
- kill_reader (h);
-
- pthread_mutex_lock (& h->reader_status.mutex);
-
- case NEON_READER_EOF:
- /* If there still is data in the buffer, carry on.
- * If not, terminate the reader thread and return 0. */
- if (! used_rb_locked (& h->rb))
- {
- _DEBUG ("<%p> Reached end of stream", h);
- pthread_mutex_unlock (& h->reader_status.mutex);
-
- if (h->reader_status.reading)
- kill_reader (h);
-
- h->eof = TRUE;
- return 0;
- }
-
- break;
-
- case NEON_READER_TERM:
- /* The reader thread terminated gracefully, most likely on our own request.
- * We should not get here. */
- g_warn_if_reached ();
- pthread_mutex_unlock (& h->reader_status.mutex);
- return 0;
- }
-
- pthread_mutex_unlock (& h->reader_status.mutex);
- }
-
- /* Deliver data from the buffer */
- if (! used_rb (& h->rb))
- {
- /* The buffer is still empty, we can deliver no data! */
- _ERROR ("<%p> Buffer still underrun, fatal.", (void *) h);
- return 0;
- }
-
- int belem = used_rb (& h->rb) / size;
-
- if (h->icy_metaint)
- {
- if (! h->icy_metaleft)
- {
- /* The next data in the buffer is a ICY metadata announcement.
- * Get the length byte */
- unsigned char icy_metalen;
- read_rb (& h->rb, & icy_metalen, 1);
-
- /* We need enough data in the buffer to
- * a) Read the complete ICY metadata block
- * b) deliver at least one byte to the reader */
- _DEBUG ("<%p> Expecting %d bytes of ICY metadata", h, (icy_metalen*16));
-
- if (free_rb (& h->rb) - icy_metalen * 16 < size)
- {
- /* There is not enough data. We do not have much choice at this point,
- * so we'll deliver the metadata as normal data to the reader and
- * hope for the best. */
- _ERROR ("<%p> Buffer underrun when reading metadata. Expect "
- "audio degradation", (void *) h);
- h->icy_metaleft = h->icy_metaint + icy_metalen * 16;
- }
- else
- {
- /* Grab the metadata from the buffer and send it to the parser */
- char icy_metadata[NEON_ICY_BUFSIZE];
- read_rb (& h->rb, icy_metadata, icy_metalen * 16);
- parse_icy (& h->icy_metadata, icy_metadata, icy_metalen * 16);
- h->icy_metaleft = h->icy_metaint;
- }
- }
-
- /* The maximum number of bytes we can deliver is determined
- * by the number of bytes left until the next metadata announcement */
- belem = MIN (used_rb (& h->rb), h->icy_metaleft) / size;
- }
-
- nmemb = MIN (belem, nmemb);
- read_rb (& h->rb, ptr, nmemb * size);
-
- /* Signal the network thread to continue reading */
- pthread_mutex_lock (& h->reader_status.mutex);
-
- if (h->reader_status.status == NEON_READER_EOF)
- {
- if (! free_rb_locked (& h->rb))
- {
- _DEBUG ("<%p> stream EOF reached and buffer empty", h);
- h->eof = TRUE;
- }
- }
- else
- pthread_cond_broadcast (& h->reader_status.cond);
-
- pthread_mutex_unlock (& h->reader_status.mutex);
-
- h->pos += nmemb * size;
- h->icy_metaleft -= nmemb * size;
-
- return nmemb;
-}
-
-/* neon_fread_real will do only a partial read if the buffer underruns, so we
- * must call it repeatedly until we have read the full request. */
-int64_t neon_vfs_fread_impl (void * buffer, int64_t size, int64_t count, VFSFile * handle)
-{
- size_t total = 0, new;
-
- _DEBUG ("<%p> fread %d x %d", (void *) handle, (int) size, (int) count);
-
- while (count > 0 && (new = neon_fread_real (buffer, size, count, handle)) > 0)
- {
- buffer = (char *) buffer + size * new;
- total += new;
- count -= new;
- }
-
- _DEBUG ("<%p> fread = %d", (void *) handle, (int) total);
-
- return total;
-}
-
-int64_t neon_vfs_fwrite_impl (const void * ptr, int64_t size, int64_t nmemb, VFSFile * file)
-{
- _ERROR ("<%p> NOT IMPLEMENTED", (void *) vfs_get_handle (file));
-
- return 0;
-}
-
-int64_t neon_vfs_ftell_impl (VFSFile * file)
-{
- struct neon_handle * h = vfs_get_handle (file);
-
- _DEBUG ("<%p> Current file position: %ld", h, h->pos);
-
- return h->pos;
-}
-
-bool_t neon_vfs_feof_impl (VFSFile * file)
-{
- struct neon_handle * h = vfs_get_handle (file);
-
- _DEBUG ("<%p> EOF status: %s", h, h->eof ? "TRUE" : "FALSE");
-
- return h->eof;
-}
-
-int neon_vfs_truncate_impl (VFSFile * file, int64_t size)
-{
- _ERROR ("<%p> NOT IMPLEMENTED", (void *) vfs_get_handle (file));
-
- return 0;
-}
-
-int neon_vfs_fseek_impl (VFSFile * file, int64_t offset, int whence)
-{
- struct neon_handle * h = vfs_get_handle (file);
-
- _DEBUG ("<%p> Seek requested: offset %ld, whence %d", h, offset, whence);
-
- /* To seek to a non-zero offset, two things must be satisfied:
- * - the server must advertise a content-length
- * - the server must advertise accept-ranges: bytes */
- if ((whence != SEEK_SET || offset) && (h->content_length < 0 || ! h->can_ranges))
- {
- _DEBUG ("<%p> Can not seek due to server restrictions", h);
- return -1;
- }
-
- int64_t content_length = h->content_length + h->content_start;
- int64_t newpos;
-
- switch (whence)
- {
- case SEEK_SET:
- newpos = offset;
- break;
-
- case SEEK_CUR:
- newpos = h->pos + offset;
- break;
-
- case SEEK_END:
- if (offset == 0)
- {
- h->pos = content_length;
- h->eof = TRUE;
- return 0;
- }
-
- newpos = content_length + offset;
- break;
-
- default:
- _ERROR ("<%p> Invalid whence specified", (void *) h);
- return -1;
- }
-
- _DEBUG ("<%p> Position to seek to: %ld, current: %ld", h, newpos, h->pos);
-
- if (newpos < 0)
- {
- _ERROR ("<%p> Can not seek before start of stream", (void *) h);
- return -1;
- }
-
- if (newpos && newpos >= content_length)
- {
- _ERROR ("<%p> Can not seek beyond end of stream (%ld >= %ld)",
- (void *) h, (long) newpos, (long) content_length);
- return -1;
- }
-
- if (newpos == h->pos)
- return 0;
-
- /* To seek to the new position we have to
- * - stop the current reader thread, if there is one
- * - destroy the current request
- * - dump all data currently in the ringbuffer
- * - create a new request starting at newpos */
- if (h->reader_status.reading)
- kill_reader (h);
-
- if (h->request)
- {
- ne_request_destroy (h->request);
- h->request = NULL;
- }
-
- if (h->session)
- {
- ne_session_destroy (h->session);
- h->session = NULL;
- }
-
- reset_rb (& h->rb);
-
- if (open_handle (h, newpos) != 0)
- {
- _ERROR ("<%p> Error while creating new request!", (void *) h);
- return -1;
- }
-
- /* Things seem to have worked. The next read request will start
- * the reader thread again. */
- h->eof = FALSE;
-
- return 0;
-}
-
-char * neon_vfs_metadata_impl (VFSFile * file, const char * field)
-{
- struct neon_handle * h = vfs_get_handle (file);
-
- _DEBUG ("<%p> Field name: %s", h, field);
-
- if (! strcmp (field, "track-name") && h->icy_metadata.stream_title)
- return str_to_utf8 (h->icy_metadata.stream_title, -1);
-
- if (! strcmp (field, "stream-name") && h->icy_metadata.stream_name)
- return str_to_utf8 (h->icy_metadata.stream_name, -1);
-
- if (! strcmp (field, "content-type") && h->icy_metadata.stream_contenttype)
- return str_to_utf8 (h->icy_metadata.stream_contenttype, -1);
-
- if (! strcmp (field, "content-bitrate"))
- return int_to_str (h->icy_metadata.stream_bitrate * 1000);
-
- return NULL;
-}
-
-int64_t neon_vfs_fsize_impl (VFSFile * file)
-{
- struct neon_handle * h = vfs_get_handle (file);
-
- if (h->content_length < 0)
- {
- _DEBUG ("<%p> Unknown content length", h);
- return -1;
- }
-
- return h->content_start + h->content_length;
-}
-
-static const char * const neon_schemes[] = {"http", "https", NULL};
-
-static VFSConstructor constructor =
-{
- .vfs_fopen_impl = neon_vfs_fopen_impl,
- .vfs_fclose_impl = neon_vfs_fclose_impl,
- .vfs_fread_impl = neon_vfs_fread_impl,
- .vfs_fwrite_impl = neon_vfs_fwrite_impl,
- .vfs_fseek_impl = neon_vfs_fseek_impl,
- .vfs_ftell_impl = neon_vfs_ftell_impl,
- .vfs_feof_impl = neon_vfs_feof_impl,
- .vfs_ftruncate_impl = neon_vfs_truncate_impl,
- .vfs_fsize_impl = neon_vfs_fsize_impl,
- .vfs_get_metadata_impl = neon_vfs_metadata_impl
-};
-
-AUD_TRANSPORT_PLUGIN
-(
- .name = N_("Neon HTTP/HTTPS Plugin"),
- .domain = PACKAGE,
- .schemes = neon_schemes,
- .init = neon_plugin_init,
- .cleanup = neon_plugin_fini,
- .vtable = & constructor
-)
diff --git a/src/neon/neon.cc b/src/neon/neon.cc
new file mode 100644
index 000000000000..153eba6f4b3b
--- /dev/null
+++ b/src/neon/neon.cc
@@ -0,0 +1,1102 @@
+/*
+ * A neon HTTP input plugin for Audacious
+ * Copyright (C) 2007 Ralf Ertzinger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#include <pthread.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/ringbuf.h>
+#include <libaudcore/runtime.h>
+
+#include <ne_auth.h>
+#include <ne_session.h>
+#include <ne_socket.h>
+#include <ne_redirect.h>
+#include <ne_request.h>
+#include <ne_uri.h>
+#include <ne_utils.h>
+
+#include "cert_verification.h"
+
+#define NEON_NETBLKSIZE (4096)
+#define NEON_ICY_BUFSIZE (4096)
+#define NEON_RETRY_COUNT 6
+
+enum FillBufferResult {
+ FILL_BUFFER_SUCCESS,
+ FILL_BUFFER_ERROR,
+ FILL_BUFFER_EOF
+};
+
+enum neon_reader_t {
+ NEON_READER_INIT = 0,
+ NEON_READER_RUN = 1,
+ NEON_READER_ERROR,
+ NEON_READER_EOF,
+ NEON_READER_TERM
+};
+
+struct reader_status
+{
+ bool reading = false;
+ neon_reader_t status = NEON_READER_INIT;
+
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+
+ reader_status ()
+ {
+ pthread_mutex_init (& mutex, nullptr);
+ pthread_cond_init (& cond, nullptr);
+ }
+
+ ~reader_status ()
+ {
+ pthread_mutex_destroy (& mutex);
+ pthread_cond_destroy (& cond);
+ }
+};
+
+struct icy_metadata
+{
+ String stream_name;
+ String stream_title;
+ String stream_url;
+ String stream_contenttype;
+ int stream_bitrate = 0;
+};
+
+static const char * const neon_schemes[] = {"http", "https"};
+
+class NeonTransport : public TransportPlugin
+{
+public:
+ static constexpr PluginInfo info = {N_("Neon HTTP/HTTPS Plugin"), PACKAGE};
+
+ constexpr NeonTransport () : TransportPlugin (info, neon_schemes) {}
+
+ bool init ();
+ void cleanup ();
+
+ VFSImpl * fopen (const char * path, const char * mode, String & error);
+};
+
+EXPORT NeonTransport aud_plugin_instance;
+
+bool NeonTransport::init ()
+{
+ int ret = ne_sock_init ();
+
+ if (ret != 0)
+ {
+ AUDERR ("Could not initialize neon library: %d\n", ret);
+ return false;
+ }
+
+ return true;
+}
+
+void NeonTransport::cleanup ()
+{
+ ne_sock_exit ();
+}
+
+class NeonFile : public VFSImpl
+{
+public:
+ NeonFile (const char * url);
+ ~NeonFile ();
+
+ int open_handle (uint64_t startbyte, String * error = nullptr);
+
+protected:
+ int64_t fread (void * ptr, int64_t size, int64_t nmemb);
+ int fseek (int64_t offset, VFSSeekType whence);
+
+ int64_t ftell ();
+ int64_t fsize ();
+ bool feof ();
+
+ int64_t fwrite (const void * ptr, int64_t size, int64_t nmemb);
+ int ftruncate (int64_t length);
+ int fflush ();
+
+ String get_metadata (const char * field);
+
+private:
+ String m_url; /* The URL, as passed to us */
+ ne_uri m_purl = ne_uri (); /* The URL, parsed into a structure */
+
+ unsigned char m_redircount = 0; /* Redirect count for the opened URL */
+ long m_pos = 0; /* Current position in the stream (number of last byte delivered to the player) */
+ unsigned long m_content_start = 0; /* Start position in the stream */
+ long m_content_length = -1; /* Total content length, counting from content_start, if known. -1 if unknown */
+ bool m_can_ranges = false; /* true if the webserver advertised accept-range: bytes */
+ int64_t m_icy_metaint = 0; /* Interval in which the server will send metadata announcements. 0 if no announcments */
+ int64_t m_icy_metaleft = 0; /* Bytes left until the next metadata block */
+
+ bool m_eof = false;
+
+ RingBuf<char> m_rb; /* Ringbuffer for our data */
+ icy_metadata m_icy_metadata; /* Current ICY metadata */
+
+ ne_session * m_session = nullptr;
+ ne_request * m_request = nullptr;
+
+ pthread_t m_reader;
+ reader_status m_reader_status;
+
+ void kill_reader ();
+ int server_auth (const char * realm, int attempt, char * username, char * password);
+ void handle_headers ();
+ int open_request (uint64_t startbyte, String * error);
+ FillBufferResult fill_buffer ();
+ void reader ();
+ int64_t try_fread (void * ptr, int64_t size, int64_t nmemb);
+
+ static int server_auth_callback (void * data, const char * realm, int attempt,
+ char * username, char * password)
+ { return ((NeonFile *) data)->server_auth (realm, attempt, username, password); }
+
+ static void * reader_thread (void * data)
+ { ((NeonFile *) data)->reader (); return nullptr; }
+};
+
+NeonFile::NeonFile (const char * url) :
+ m_url (url)
+{
+ int buffer_kb = aud_get_int (nullptr, "net_buffer_kb");
+ m_rb.alloc (1024 * aud::clamp (buffer_kb, 16, 1024));
+}
+
+NeonFile::~NeonFile ()
+{
+ if (m_reader_status.reading)
+ kill_reader ();
+
+ if (m_request)
+ ne_request_destroy (m_request);
+ if (m_session)
+ ne_session_destroy (m_session);
+
+ ne_uri_free (& m_purl);
+}
+
+static bool neon_strcmp (const char * str, const char * cmp)
+{
+ return ! g_ascii_strncasecmp (str, cmp, strlen (cmp));
+}
+
+static void add_icy (struct icy_metadata * m, const char * name, const char * value)
+{
+ if (neon_strcmp (name, "StreamTitle"))
+ {
+ AUDDBG ("Found StreamTitle: %s\n", value);
+ m->stream_title = String (str_to_utf8 (value, -1));
+ }
+
+ if (neon_strcmp (name, "StreamUrl"))
+ {
+ AUDDBG ("Found StreamUrl: %s\n", value);
+ m->stream_url = String (str_to_utf8 (value, -1));
+ }
+}
+
+static void parse_icy (struct icy_metadata * m, char * metadata, size_t len)
+{
+ enum TagReadState
+ {
+ STATE_READ_NAME,
+ STATE_WAIT_VALUE,
+ STATE_READ_VALUE,
+ STATE_WAIT_NAME,
+ };
+
+ TagReadState state = STATE_READ_NAME;
+
+ char * p = metadata;
+ char * tstart = metadata;
+ size_t pos = 1;
+
+ char name[NEON_ICY_BUFSIZE];
+ char value[NEON_ICY_BUFSIZE];
+
+ name[0] = 0;
+ value[0] = 0;
+
+ while (pos < len && p[0])
+ {
+ switch (state)
+ {
+ case STATE_READ_NAME:
+
+ /* Reading tag name */
+ if (p[0] == '=')
+ {
+ /* End of tag name. */
+ p[0] = 0;
+ g_strlcpy (name, tstart, NEON_ICY_BUFSIZE);
+ AUDDBG ("Found tag name: %s\n", name);
+ state = STATE_WAIT_VALUE;
+ }
+
+ break;
+
+ case STATE_WAIT_VALUE:
+
+ /* Waiting for start of value */
+ if (p[0] == '\'')
+ {
+ /* Leading ' of value */
+ tstart = p + 1;
+ state = STATE_READ_VALUE;
+ value[0] = 0;
+ }
+
+ break;
+
+ case STATE_READ_VALUE:
+
+ /* Reading value */
+ if (p[0] == '\'' && p[1] == ';')
+ {
+ /* End of value */
+ p[0] = 0;
+ g_strlcpy (value, tstart, NEON_ICY_BUFSIZE);
+ AUDDBG ("Found tag value: %s\n", value);
+ add_icy (m, name, value);
+ state = STATE_WAIT_NAME;
+ }
+
+ break;
+
+ case STATE_WAIT_NAME:
+
+ /* Waiting for next tag start */
+ if (p[0] == ';')
+ {
+ /* Next tag name starts after this char */
+ tstart = p + 1;
+ state = STATE_READ_NAME;
+ name[0] = 0;
+ value[0] = 0;
+ }
+
+ break;
+ }
+
+ p ++;
+ pos ++;
+ }
+}
+
+void NeonFile::kill_reader ()
+{
+ AUDDBG ("Signaling reader thread to terminate\n");
+ pthread_mutex_lock (& m_reader_status.mutex);
+ m_reader_status.reading = false;
+ pthread_cond_broadcast (& m_reader_status.cond);
+ pthread_mutex_unlock (& m_reader_status.mutex);
+
+ AUDDBG ("Waiting for reader thread to die...\n");
+ pthread_join (m_reader, nullptr);
+ AUDDBG ("Reader thread has died\n");
+}
+
+int NeonFile::server_auth (const char * realm, int attempt, char * username, char * password)
+{
+ if (! m_purl.userinfo || ! m_purl.userinfo[0])
+ {
+ AUDERR ("Authentication required, but no credentials set\n");
+ return 1;
+ }
+
+ char * * authtok = g_strsplit (m_purl.userinfo, ":", 2);
+
+ if (strlen (authtok[1]) > NE_ABUFSIZ - 1 || strlen (authtok[0]) > NE_ABUFSIZ - 1)
+ {
+ AUDERR ("Username/Password too long\n");
+ g_strfreev (authtok);
+ return 1;
+ }
+
+ g_strlcpy (username, authtok[0], NE_ABUFSIZ);
+ g_strlcpy (password, authtok[1], NE_ABUFSIZ);
+
+ AUDDBG ("Authenticating: Username: %s, Password: %s\n", username, password);
+
+ g_strfreev (authtok);
+
+ return attempt;
+}
+
+void NeonFile::handle_headers ()
+{
+ const char * name;
+ const char * value;
+ void * cursor = nullptr;
+
+ AUDDBG ("Header responses:\n");
+
+ while ((cursor = ne_response_header_iterate (m_request, cursor, & name, & value)))
+ {
+ AUDDBG ("HEADER: %s: %s\n", name, value);
+
+ if (neon_strcmp (name, "accept-ranges"))
+ {
+ /* The server advertises range capability. we need "bytes" */
+ if (strstr (value, "bytes"))
+ {
+ AUDDBG ("server can_ranges\n");
+ m_can_ranges = true;
+ }
+ }
+ else if (neon_strcmp (name, "content-length"))
+ {
+ /* The server sent us the content length. Parse and store. */
+ char * endptr;
+ long len = strtol (value, & endptr, 10);
+
+ if (value[0] && ! endptr[0] && len >= 0)
+ {
+ /* Valid data. */
+ AUDDBG ("Content length as advertised by server: %ld\n", len);
+ m_content_length = len;
+ }
+ else
+ AUDERR ("Invalid content length header: %s\n", value);
+ }
+ else if (neon_strcmp (name, "content-type"))
+ {
+ /* The server sent us a content type. Save it for later */
+ AUDDBG ("Content-Type: %s\n", value);
+ m_icy_metadata.stream_contenttype = String (str_to_utf8 (value, -1));
+ }
+ else if (neon_strcmp (name, "icy-metaint"))
+ {
+ /* The server sent us a ICY metaint header. Parse and store. */
+ char * endptr;
+ long len = strtol (value, & endptr, 10);
+
+ if (value[0] && ! endptr[0] && len > 0)
+ {
+ /* Valid data */
+ AUDDBG ("ICY MetaInt as advertised by server: %ld\n", len);
+ m_icy_metaint = len;
+ m_icy_metaleft = len;
+ }
+ else
+ AUDERR ("Invalid ICY MetaInt header: %s\n", value);
+ }
+ else if (neon_strcmp (name, "icy-name"))
+ {
+ /* The server sent us a ICY name. Save it for later */
+ AUDDBG ("ICY stream name: %s\n", value);
+ m_icy_metadata.stream_name = String (value);
+ }
+ else if (neon_strcmp (name, "icy-br"))
+ {
+ /* The server sent us a bitrate. We might want to use it. */
+ AUDDBG ("ICY bitrate: %d\n", atoi (value));
+ m_icy_metadata.stream_bitrate = atoi (value);
+ }
+ }
+}
+
+static int neon_proxy_auth_cb (void * userdata, const char * realm, int attempt,
+ char * username, char * password)
+{
+ String value = aud_get_str (nullptr, "proxy_user");
+ g_strlcpy (username, value, NE_ABUFSIZ);
+
+ value = aud_get_str (nullptr, "proxy_pass");
+ g_strlcpy (password, value, NE_ABUFSIZ);
+
+ return attempt;
+}
+
+int NeonFile::open_request (uint64_t startbyte, String * error)
+{
+ int ret;
+ const ne_status * status;
+ ne_uri * rediruri;
+
+ if (m_purl.query && * (m_purl.query))
+ {
+ StringBuf tmp = str_concat ({m_purl.path, "?", m_purl.query});
+ m_request = ne_request_create (m_session, "GET", tmp);
+ }
+ else
+ m_request = ne_request_create (m_session, "GET", m_purl.path);
+
+ if (startbyte > 0)
+ ne_print_request_header (m_request, "Range", "bytes=%" PRIu64 "-", startbyte);
+
+ ne_print_request_header (m_request, "Icy-MetaData", "1");
+
+ /* Try to connect to the server. */
+ AUDDBG ("<%p> Connecting...\n", this);
+ ret = ne_begin_request (m_request);
+ status = ne_get_status (m_request);
+ AUDDBG ("<%p> Return: %d, Status: %d\n", this, ret, status->code);
+
+ if (ret == NE_OK)
+ {
+ switch (status->code)
+ {
+ case 401:
+ /* Authorization required. Reconnect to authenticate */
+ AUDDBG ("Reconnecting due to 401\n");
+ ne_end_request (m_request);
+ ret = ne_begin_request (m_request);
+ break;
+
+ case 301:
+ case 302:
+ case 303:
+ case 307:
+ /* Redirect encountered. Reconnect. */
+ ne_end_request (m_request);
+ ret = NE_REDIRECT;
+ break;
+
+ case 407:
+ /* Proxy auth required. Reconnect to authenticate */
+ AUDDBG ("Reconnecting due to 407\n");
+ ne_end_request (m_request);
+ ret = ne_begin_request (m_request);
+ break;
+ }
+ }
+
+ switch (ret)
+ {
+ case NE_OK:
+ if (status->code > 199 && status->code < 300)
+ {
+ /* URL opened OK */
+ AUDDBG ("<%p> URL opened OK\n", this);
+ m_content_start = startbyte;
+ m_pos = startbyte;
+ handle_headers ();
+ return 0;
+ }
+
+ break;
+
+ case NE_REDIRECT:
+ /* We hit a redirect. Handle it. */
+ AUDDBG ("<%p> Redirect encountered\n", this);
+ m_redircount += 1;
+ rediruri = (ne_uri *) ne_redirect_location (m_session);
+ ne_request_destroy (m_request);
+ m_request = nullptr;
+
+ if (! rediruri)
+ {
+ if (error)
+ * error = String (_("Error parsing redirect"));
+
+ AUDERR ("<%p> Could not parse redirect response\n", this);
+ return -1;
+ }
+
+ ne_uri_free (& m_purl);
+ ne_uri_copy (& m_purl, rediruri);
+ return 1;
+ }
+
+ /* Something went wrong. */
+ const char * ne_error = ne_get_error (m_session);
+ if (error)
+ * error = String (ne_error ? ne_error : _("Unknown HTTP error"));
+
+ AUDERR ("<%p> Could not open URL: %d (%d)\n", this, ret, status->code);
+
+ if (ne_error)
+ AUDERR ("<%p> neon error string: %s\n", this, ne_error);
+
+ ne_request_destroy (m_request);
+ m_request = nullptr;
+ return -1;
+}
+
+int NeonFile::open_handle (uint64_t startbyte, String * error)
+{
+ int ret;
+ String proxy_host;
+ int proxy_port = 0;
+
+ bool use_proxy = aud_get_bool (nullptr, "use_proxy");
+ bool use_proxy_auth = aud_get_bool (nullptr, "use_proxy_auth");
+
+ if (use_proxy)
+ {
+ proxy_host = aud_get_str (nullptr, "proxy_host");
+ proxy_port = aud_get_int (nullptr, "proxy_port");
+ }
+
+ m_redircount = 0;
+
+ AUDDBG ("<%p> Parsing URL\n", this);
+
+ if (ne_uri_parse (m_url, & m_purl) != 0)
+ {
+ if (error)
+ * error = String (_("Error parsing URL"));
+
+ AUDERR ("<%p> Could not parse URL '%s'\n", this, (const char *) m_url);
+ return -1;
+ }
+
+ while (m_redircount < 10)
+ {
+ if (! m_purl.port)
+ m_purl.port = ne_uri_defaultport (m_purl.scheme);
+
+ AUDDBG ("<%p> Creating session to %s://%s:%d\n", this,
+ m_purl.scheme, m_purl.host, m_purl.port);
+ m_session = ne_session_create (m_purl.scheme,
+ m_purl.host, m_purl.port);
+ ne_redirect_register (m_session);
+ ne_add_server_auth (m_session, NE_AUTH_BASIC, server_auth_callback, this);
+ ne_set_session_flag (m_session, NE_SESSFLAG_ICYPROTO, 1);
+ ne_set_session_flag (m_session, NE_SESSFLAG_PERSIST, 0);
+ ne_set_connect_timeout (m_session, 10);
+ ne_set_read_timeout (m_session, 10);
+ ne_set_useragent (m_session, "Audacious/" PACKAGE_VERSION);
+
+ if (use_proxy)
+ {
+ AUDDBG ("<%p> Using proxy: %s:%d\n", this, (const char *) proxy_host, proxy_port);
+ ne_session_proxy (m_session, proxy_host, proxy_port);
+
+ if (use_proxy_auth)
+ {
+ AUDDBG ("<%p> Using proxy authentication\n", this);
+ ne_add_proxy_auth (m_session, NE_AUTH_BASIC,
+ neon_proxy_auth_cb, (void *) this);
+ }
+ }
+
+ if (! strcmp ("https", m_purl.scheme))
+ {
+ ne_ssl_trust_default_ca (m_session);
+ ne_ssl_set_verify (m_session,
+ neon_vfs_verify_environment_ssl_certs, m_session);
+ }
+
+ AUDDBG ("<%p> Creating request\n", this);
+ ret = open_request (startbyte, error);
+
+ if (! ret)
+ return 0;
+
+ if (ret == -1)
+ {
+ ne_session_destroy (m_session);
+ m_session = nullptr;
+ return -1;
+ }
+
+ AUDDBG ("<%p> Following redirect...\n", this);
+ ne_session_destroy (m_session);
+ m_session = nullptr;
+ }
+
+ /* If we get here, our redirect count exceeded */
+ if (error)
+ * error = String (_("Too many redirects"));
+
+ AUDERR ("<%p> Redirect count exceeded for URL %s\n", this, (const char *) m_url);
+ return 1;
+}
+
+FillBufferResult NeonFile::fill_buffer ()
+{
+ char buffer[NEON_NETBLKSIZE];
+ int to_read;
+
+ pthread_mutex_lock (& m_reader_status.mutex);
+ to_read = aud::min (m_rb.space (), NEON_NETBLKSIZE);
+ pthread_mutex_unlock (& m_reader_status.mutex);
+
+ int bsize = ne_read_response_block (m_request, buffer, to_read);
+
+ if (! bsize)
+ {
+ AUDDBG ("<%p> End of file encountered\n", this);
+ return FILL_BUFFER_EOF;
+ }
+
+ if (bsize < 0)
+ {
+ AUDERR ("<%p> Error while reading from the network\n", this);
+ ne_request_destroy (m_request);
+ m_request = nullptr;
+ return FILL_BUFFER_ERROR;
+ }
+
+ AUDDBG ("<%p> Read %d bytes of %d\n", this, bsize, to_read);
+
+ pthread_mutex_lock (& m_reader_status.mutex);
+ m_rb.copy_in (buffer, bsize);
+ pthread_mutex_unlock (& m_reader_status.mutex);
+
+ return FILL_BUFFER_SUCCESS;
+}
+
+void NeonFile::reader ()
+{
+ pthread_mutex_lock (& m_reader_status.mutex);
+
+ while (m_reader_status.reading)
+ {
+ /* Hit the network only if we have more than NEON_NETBLKSIZE of free buffer */
+ if (m_rb.space () > NEON_NETBLKSIZE)
+ {
+ pthread_mutex_unlock (& m_reader_status.mutex);
+
+ FillBufferResult ret = fill_buffer ();
+
+ pthread_mutex_lock (& m_reader_status.mutex);
+
+ /* Wake up main thread if it is waiting. */
+ pthread_cond_broadcast (& m_reader_status.cond);
+
+ if (ret == FILL_BUFFER_ERROR)
+ {
+ AUDERR ("<%p> Error while reading from the network. "
+ "Terminating reader thread\n", this);
+ m_reader_status.status = NEON_READER_ERROR;
+ pthread_mutex_unlock (& m_reader_status.mutex);
+ return;
+ }
+ else if (ret == FILL_BUFFER_EOF)
+ {
+ AUDDBG ("<%p> EOF encountered while reading from the network. "
+ "Terminating reader thread\n", this);
+ m_reader_status.status = NEON_READER_EOF;
+ pthread_mutex_unlock (& m_reader_status.mutex);
+ return;
+ }
+ }
+ else
+ {
+ /* Not enough free space in the buffer.
+ * Sleep until the main thread wakes us up. */
+ pthread_cond_wait (& m_reader_status.cond, & m_reader_status.mutex);
+ }
+ }
+
+ AUDDBG ("<%p> Reader thread terminating gracefully\n", this);
+ m_reader_status.status = NEON_READER_TERM;
+ pthread_mutex_unlock (& m_reader_status.mutex);
+}
+
+VFSImpl * NeonTransport::fopen (const char * path, const char * mode, String & error)
+{
+ NeonFile * file = new NeonFile (path);
+
+ AUDDBG ("<%p> Trying to open '%s' with neon\n", file, path);
+
+ if (file->open_handle (0, & error) != 0)
+ {
+ AUDERR ("<%p> Could not open URL\n", file);
+ delete file;
+ return nullptr;
+ }
+
+ return file;
+}
+
+int64_t NeonFile::try_fread (void * ptr, int64_t size, int64_t nmemb)
+{
+ if (! m_request)
+ {
+ AUDERR ("<%p> No request to read from, seek gone wrong?\n", this);
+ return 0;
+ }
+
+ if (! size || ! nmemb || m_eof)
+ return 0;
+
+ /* If the buffer is empty, wait for the reader thread to fill it. */
+ pthread_mutex_lock (& m_reader_status.mutex);
+
+ for (int retries = 0; retries < NEON_RETRY_COUNT; retries ++)
+ {
+ if (m_rb.len () / size > 0 || ! m_reader_status.reading ||
+ m_reader_status.status != NEON_READER_RUN)
+ break;
+
+ pthread_cond_broadcast (& m_reader_status.cond);
+ pthread_cond_wait (& m_reader_status.cond, & m_reader_status.mutex);
+ }
+
+ pthread_mutex_unlock (& m_reader_status.mutex);
+
+ if (! m_reader_status.reading)
+ {
+ if (m_reader_status.status != NEON_READER_EOF || m_content_length != -1)
+ {
+ /* There is no reader thread yet. Read the first bytes from
+ * the network ourselves, and then fire up the reader thread
+ * to keep the buffer filled up. */
+ AUDDBG ("<%p> Doing initial buffer fill\n", this);
+ FillBufferResult ret = fill_buffer ();
+
+ if (ret == FILL_BUFFER_ERROR)
+ {
+ AUDERR ("<%p> Error while reading from the network\n", this);
+ return 0;
+ }
+
+ /* We have some data in the buffer now.
+ * Start the reader thread if we did not reach EOF during
+ * the initial fill */
+ pthread_mutex_lock (& m_reader_status.mutex);
+
+ if (ret == FILL_BUFFER_SUCCESS)
+ {
+ m_reader_status.reading = true;
+ AUDDBG ("<%p> Starting reader thread\n", this);
+ pthread_create (& m_reader, nullptr, reader_thread, this);
+ m_reader_status.status = NEON_READER_RUN;
+ }
+ else if (ret == FILL_BUFFER_EOF)
+ {
+ AUDDBG ("<%p> No reader thread needed (stream has reached EOF during fill)\n", this);
+ m_reader_status.reading = false;
+ m_reader_status.status = NEON_READER_EOF;
+ }
+
+ pthread_mutex_unlock (& m_reader_status.mutex);
+ }
+ }
+ else
+ {
+ /* There already is a reader thread. Look if it is in good shape. */
+ pthread_mutex_lock (& m_reader_status.mutex);
+
+ switch (m_reader_status.status)
+ {
+ case NEON_READER_INIT:
+ case NEON_READER_RUN:
+ /* All is well, nothing to be done. */
+ break;
+
+ case NEON_READER_ERROR:
+ /* A reader error happened. Log it, and treat it like an EOF
+ * condition, by falling through to the NEON_READER_EOF codepath. */
+ AUDDBG ("<%p> NEON_READER_ERROR happened. Terminating reader thread and marking EOF.\n", this);
+ m_reader_status.status = NEON_READER_EOF;
+ pthread_mutex_unlock (& m_reader_status.mutex);
+
+ if (m_reader_status.reading)
+ kill_reader ();
+
+ pthread_mutex_lock (& m_reader_status.mutex);
+
+ case NEON_READER_EOF:
+ /* If there still is data in the buffer, carry on.
+ * If not, terminate the reader thread and return 0. */
+ if (! m_rb.len ())
+ {
+ AUDDBG ("<%p> Reached end of stream\n", this);
+ pthread_mutex_unlock (& m_reader_status.mutex);
+
+ if (m_reader_status.reading)
+ kill_reader ();
+
+ m_eof = true;
+ return 0;
+ }
+
+ break;
+
+ case NEON_READER_TERM:
+ /* The reader thread terminated gracefully, most likely on our own request.
+ * We should not get here. */
+ g_warn_if_reached ();
+ pthread_mutex_unlock (& m_reader_status.mutex);
+ return 0;
+ }
+
+ pthread_mutex_unlock (& m_reader_status.mutex);
+ }
+
+ /* Deliver data from the buffer */
+ pthread_mutex_lock (& m_reader_status.mutex);
+
+ if (! m_rb.len ())
+ {
+ /* The buffer is still empty, we can deliver no data! */
+ AUDERR ("<%p> Buffer still underrun, fatal.\n", this);
+ pthread_mutex_unlock (& m_reader_status.mutex);
+ return 0;
+ }
+
+ int64_t belem = m_rb.len () / size;
+
+ if (m_icy_metaint)
+ {
+ if (! m_icy_metaleft)
+ {
+ /* The next data in the buffer is a ICY metadata announcement.
+ * Get the length byte */
+ unsigned char icy_metalen = m_rb.head ();
+ m_rb.pop ();
+
+ /* We need enough data in the buffer to
+ * a) Read the complete ICY metadata block
+ * b) deliver at least one byte to the reader */
+ AUDDBG ("<%p> Expecting %d bytes of ICY metadata\n", this, (icy_metalen*16));
+
+ if (m_rb.len () < icy_metalen * 16 + size)
+ {
+ /* There is not enough data. We do not have much choice at this point,
+ * so we'll deliver the metadata as normal data to the reader and
+ * hope for the best. */
+ AUDERR ("<%p> Buffer underrun when reading metadata. Expect "
+ "audio degradation\n", this);
+ m_icy_metaleft = m_icy_metaint + icy_metalen * 16;
+ }
+ else
+ {
+ /* Grab the metadata from the buffer and send it to the parser */
+ char icy_metadata[NEON_ICY_BUFSIZE];
+ m_rb.move_out (icy_metadata, icy_metalen * 16);
+ parse_icy (& m_icy_metadata, icy_metadata, icy_metalen * 16);
+ m_icy_metaleft = m_icy_metaint;
+ }
+ }
+
+ /* The maximum number of bytes we can deliver is determined
+ * by the number of bytes left until the next metadata announcement */
+ belem = aud::min ((int64_t) m_rb.len (), m_icy_metaleft) / size;
+ }
+
+ nmemb = aud::min (belem, nmemb);
+ m_rb.move_out ((char *) ptr, nmemb * size);
+
+ /* Signal the network thread to continue reading */
+ if (m_reader_status.status == NEON_READER_EOF)
+ {
+ if (! m_rb.len ())
+ {
+ AUDDBG ("<%p> stream EOF reached and buffer empty\n", this);
+ m_eof = true;
+ }
+ }
+ else
+ pthread_cond_broadcast (& m_reader_status.cond);
+
+ pthread_mutex_unlock (& m_reader_status.mutex);
+
+ m_pos += nmemb * size;
+ m_icy_metaleft -= nmemb * size;
+
+ return nmemb;
+}
+
+/* try_fread will do only a partial read if the buffer underruns, so we
+ * must call it repeatedly until we have read the full request. */
+int64_t NeonFile::fread (void * buffer, int64_t size, int64_t count)
+{
+ size_t total = 0, part;
+
+ AUDDBG ("<%p> fread %d x %d\n", this, (int) size, (int) count);
+
+ while (count > 0 && (part = try_fread (buffer, size, count)) > 0)
+ {
+ buffer = (char *) buffer + size * part;
+ total += part;
+ count -= part;
+ }
+
+ AUDDBG ("<%p> fread = %d\n", this, (int) total);
+
+ return total;
+}
+
+int64_t NeonFile::fwrite (const void * ptr, int64_t size, int64_t nmemb)
+{
+ AUDERR ("<%p> NOT IMPLEMENTED\n", this);
+
+ return 0;
+}
+
+int64_t NeonFile::ftell ()
+{
+ AUDDBG ("<%p> Current file position: %ld\n", this, m_pos);
+
+ return m_pos;
+}
+
+bool NeonFile::feof ()
+{
+ AUDDBG ("<%p> EOF status: %s\n", this, m_eof ? "true" : "false");
+
+ return m_eof;
+}
+
+int NeonFile::ftruncate (int64_t size)
+{
+ AUDERR ("<%p> NOT IMPLEMENTED\n", this);
+
+ return 0;
+}
+
+int NeonFile::fflush ()
+{
+ return 0; /* no-op */
+}
+
+int NeonFile::fseek (int64_t offset, VFSSeekType whence)
+{
+ AUDDBG ("<%p> Seek requested: offset %ld, whence %d\n", this, offset, whence);
+
+ /* To seek to a non-zero offset, two things must be satisfied:
+ * - the server must advertise a content-length
+ * - the server must advertise accept-ranges: bytes */
+ if ((whence != VFS_SEEK_SET || offset) && (m_content_length < 0 || ! m_can_ranges))
+ {
+ AUDDBG ("<%p> Can not seek due to server restrictions\n", this);
+ return -1;
+ }
+
+ int64_t content_length = m_content_length + m_content_start;
+ int64_t newpos;
+
+ switch (whence)
+ {
+ case VFS_SEEK_SET:
+ newpos = offset;
+ break;
+
+ case VFS_SEEK_CUR:
+ newpos = m_pos + offset;
+ break;
+
+ case VFS_SEEK_END:
+ if (offset == 0)
+ {
+ m_pos = content_length;
+ m_eof = true;
+ return 0;
+ }
+
+ newpos = content_length + offset;
+ break;
+
+ default:
+ AUDERR ("<%p> Invalid whence specified\n", this);
+ return -1;
+ }
+
+ AUDDBG ("<%p> Position to seek to: %ld, current: %ld\n", this, newpos, m_pos);
+
+ if (newpos < 0)
+ {
+ AUDERR ("<%p> Can not seek before start of stream\n", this);
+ return -1;
+ }
+
+ if (newpos && newpos >= content_length)
+ {
+ AUDERR ("<%p> Can not seek beyond end of stream (%ld >= %ld)\n",
+ this, (long) newpos, (long) content_length);
+ return -1;
+ }
+
+ if (newpos == m_pos)
+ return 0;
+
+ /* To seek to the new position we have to
+ * - stop the current reader thread, if there is one
+ * - destroy the current request
+ * - dump all data currently in the ringbuffer
+ * - create a new request starting at newpos */
+ if (m_reader_status.reading)
+ kill_reader ();
+
+ if (m_request)
+ {
+ ne_request_destroy (m_request);
+ m_request = nullptr;
+ }
+
+ if (m_session)
+ {
+ ne_session_destroy (m_session);
+ m_session = nullptr;
+ }
+
+ m_rb.discard ();
+
+ if (open_handle (newpos) != 0)
+ {
+ AUDERR ("<%p> Error while creating new request!\n", this);
+ return -1;
+ }
+
+ /* Things seem to have worked. The next read request will start
+ * the reader thread again. */
+ m_eof = false;
+
+ return 0;
+}
+
+String NeonFile::get_metadata (const char * field)
+{
+ AUDDBG ("<%p> Field name: %s\n", this, field);
+
+ if (! strcmp (field, "track-name") && m_icy_metadata.stream_title)
+ return m_icy_metadata.stream_title;
+
+ if (! strcmp (field, "stream-name") && m_icy_metadata.stream_name)
+ return m_icy_metadata.stream_name;
+
+ if (! strcmp (field, "content-type") && m_icy_metadata.stream_contenttype)
+ return m_icy_metadata.stream_contenttype;
+
+ if (! strcmp (field, "content-bitrate"))
+ return String (int_to_str (m_icy_metadata.stream_bitrate * 1000));
+
+ return String ();
+}
+
+int64_t NeonFile::fsize ()
+{
+ if (m_content_length < 0)
+ {
+ AUDDBG ("<%p> Unknown content length\n", this);
+ return -1;
+ }
+
+ return m_content_start + m_content_length;
+}
diff --git a/src/neon/neon.h b/src/neon/neon.h
deleted file mode 100644
index 02f178959911..000000000000
--- a/src/neon/neon.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * A neon HTTP input plugin for Audacious
- * Copyright (C) 2007 Ralf Ertzinger
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef _NEON_PLUGIN_H
-#define _NEON_PLUGIN_H
-
-#include <glib.h>
-#include <pthread.h>
-
-#include <libaudcore/vfs.h>
-#include <ne_session.h>
-#include <ne_request.h>
-#include <ne_uri.h>
-
-#include "rb.h"
-
-typedef enum
-{
- NEON_READER_INIT=0,
- NEON_READER_RUN=1,
- NEON_READER_ERROR,
- NEON_READER_EOF,
- NEON_READER_TERM
-} neon_reader_t;
-
-struct reader_status
-{
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- bool_t reading;
- neon_reader_t status;
-};
-
-struct icy_metadata
-{
- char * stream_name;
- char * stream_title;
- char * stream_url;
- char * stream_contenttype;
- int stream_bitrate;
-};
-
-struct neon_handle
-{
- char * url; /* The URL, as passed to us */
- ne_uri * purl; /* The URL, parsed into a structure */
- struct ringbuf rb; /* Ringbuffer for our data */
- unsigned char redircount; /* Redirect count for the opened URL */
- long pos; /* Current position in the stream (number of last byte delivered to the player) */
- gulong content_start; /* Start position in the stream */
- long content_length; /* Total content length, counting from content_start, if known. -1 if unknown */
- bool_t can_ranges; /* TRUE if the webserver advertised accept-range: bytes */
- gulong icy_metaint; /* Interval in which the server will send metadata announcements. 0 if no announcments */
- gulong icy_metaleft; /* Bytes left until the next metadata block */
- struct icy_metadata icy_metadata; /* Current ICY metadata */
- ne_session * session;
- ne_request * request;
- pthread_t reader;
- struct reader_status reader_status;
- bool_t eof;
-};
-
-#endif
diff --git a/src/neon/rb.c b/src/neon/rb.c
deleted file mode 100644
index 113bffb1aa96..000000000000
--- a/src/neon/rb.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/*
- * Ringbuffer implementation
- *
- * GPL
- */
-#include <assert.h>
-#include <string.h>
-#include <glib.h>
-
-#include "rb.h"
-
-/*
- * Reset a ringbuffer structure (i.e. discard all data inside of it)
- */
-void reset_rb (struct ringbuf * rb)
-{
- _RB_LOCK (rb->lock);
-
- rb->wp = rb->buf;
- rb->rp = rb->buf;
- rb->free = rb->size;
- rb->used = 0;
- rb->end = rb->buf + (rb->size - 1);
-
- _RB_UNLOCK (rb->lock);
-}
-
-/*
- * Initialize a ringbuffer structure (including memory allocation.
- * The mutex to be used is passed in the function call.
- * The mutex must not be held while calling this function.
- */
-void init_rb_with_lock (struct ringbuf * rb, unsigned size, rb_mutex_t * lock)
-{
- assert (size > 0);
-
- rb->lock = lock;
- rb->buf = g_malloc (size);
- rb->size = size;
- reset_rb (rb);
-}
-
-/*
- * Write size bytes at buf into the ringbuffer.
- */
-void write_rb (struct ringbuf * rb, void * buf, unsigned size)
-{
- _RB_LOCK (rb->lock);
-
- assert (size <= rb->free);
-
- int endfree = (rb->end - rb->wp) + 1;
-
- if (endfree < size)
- {
- /* There is enough space in the buffer, but not in one piece.
- * We need to split the copy into two parts. */
- memcpy (rb->wp, buf, endfree);
- memcpy (rb->buf, (char *) buf + endfree, size - endfree);
- rb->wp = rb->buf + (size-endfree);
- }
- else if (endfree > size)
- {
- /* There is more space than needed at the end */
- memcpy (rb->wp, buf, size);
- rb->wp += size;
- }
- else
- {
- /* There is exactly the space needed at the end.
- * We need to wrap around the read pointer. */
- memcpy (rb->wp, buf, size);
- rb->wp = rb->buf;
- }
-
- rb->free -= size;
- rb->used += size;
-
- _RB_UNLOCK (rb->lock);
-}
-
-/*
- * Read size byes from buffer into buf.
- * Return -1 on error (not enough data in buffer)
- */
-int read_rb (struct ringbuf * rb, void * buf, unsigned size)
-{
- _RB_LOCK (rb->lock);
- int ret = read_rb_locked (rb, buf, size);
- _RB_UNLOCK (rb->lock);
-
- return ret;
-}
-
-/*
- * Read size bytes from buffer into buf, assuming the buffer lock is already held.
- * Return -1 on error (not enough data in buffer)
- */
-int read_rb_locked (struct ringbuf * rb, void * buf, unsigned size)
-{
- if (rb->used < size)
- {
- /* Not enough bytes in buffer */
- return -1;
- }
-
- if (rb->rp < rb->wp)
- {
- /* Read pointer is behind write pointer, all the data is available in one chunk */
- memcpy (buf, rb->rp, size);
- rb->rp += size;
- }
- else
- {
- /* Read pointer is before write pointer */
- int endused = (rb->end - rb->rp) +1;
-
- if (size < endused)
- {
- /* Data is available in one chunk */
- memcpy (buf, rb->rp, size);
- rb->rp += size;
- }
- else
- {
- /* There is enough data in the buffer, but it is fragmented. */
- memcpy (buf, rb->rp, endused);
- memcpy ((char *) buf + endused, rb->buf, size - endused);
- rb->rp = rb->buf + (size-endused);
- }
- }
-
- rb->free += size;
- rb->used -= size;
-
- return 0;
-}
-
-/*
- * Return the amount of free space currently in the rb
- */
-unsigned free_rb (struct ringbuf * rb)
-{
- _RB_LOCK (rb->lock);
- unsigned f = free_rb_locked (rb);
- _RB_UNLOCK (rb->lock);
-
- return f;
-}
-
-/*
- * Return the amount of free space currently in the rb.
- * Assume the rb lock is already being held.
- */
-unsigned free_rb_locked (struct ringbuf * rb)
-{
- return rb->free;
-}
-
-/*
- * Return the amount of used space currently in the rb
- */
-unsigned used_rb (struct ringbuf * rb)
-{
- _RB_LOCK (rb->lock);
- unsigned u = used_rb_locked (rb);
- _RB_UNLOCK (rb->lock);
-
- return u;
-}
-
-/*
- * Return the amount of used space currently in the rb.
- * Assume the rb lock is already being held.
- */
-unsigned used_rb_locked (struct ringbuf * rb)
-{
- return rb->used;
-}
-
-/*
- * destroy a ringbuffer
- */
-void destroy_rb (struct ringbuf * rb)
-{
- g_free (rb->buf);
-}
diff --git a/src/neon/rb.h b/src/neon/rb.h
deleted file mode 100644
index 23512cd7d425..000000000000
--- a/src/neon/rb.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef _RB_H
-#define _RB_H
-
-#include <pthread.h>
-
-typedef pthread_mutex_t rb_mutex_t;
-
-#define _RB_LOCK(L) pthread_mutex_lock (L)
-#define _RB_UNLOCK(L) pthread_mutex_unlock (L)
-
-struct ringbuf
-{
- rb_mutex_t * lock;
- char * buf;
- char * end;
- char * wp;
- char * rp;
- unsigned free;
- unsigned used;
- unsigned size;
-};
-
-void init_rb_with_lock (struct ringbuf * rb, unsigned size, rb_mutex_t * lock);
-void write_rb (struct ringbuf * rb, void * buf, unsigned size);
-int read_rb (struct ringbuf * rb, void * buf, unsigned size);
-int read_rb_locked (struct ringbuf * rb, void * buf, unsigned size);
-void reset_rb (struct ringbuf * rb);
-unsigned free_rb (struct ringbuf * rb);
-unsigned free_rb_locked (struct ringbuf * rb);
-unsigned used_rb (struct ringbuf * rb);
-unsigned used_rb_locked (struct ringbuf * rb);
-void destroy_rb (struct ringbuf * rb);
-
-#endif
diff --git a/src/notify/Makefile b/src/notify/Makefile
index 36d2fbaebe7a..82f1476e8fc9 100644
--- a/src/notify/Makefile
+++ b/src/notify/Makefile
@@ -1,12 +1,14 @@
PLUGIN = notify${PLUGIN_SUFFIX}
-SRCS = event.c notify.c osd.c
+SRCS = event.cc notify.cc osd.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
+
CPPFLAGS += -I../.. ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${NOTIFY_CFLAGS}
CFLAGS += ${PLUGIN_CFLAGS}
-LIBS += ${GTK_LIBS} ${NOTIFY_LIBS}
+LIBS += ${GTK_LIBS} ${NOTIFY_LIBS} -laudgui
diff --git a/src/notify/event.c b/src/notify/event.c
deleted file mode 100644
index 9e613be3f9a9..000000000000
--- a/src/notify/event.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * event.c
- *
- * Copyright (C) 2010 Maximilian Bogner <max at mbogner.de>
- * Copyright (C) 2011-2013 John Lindgren and Jean-Alexandre Anglès d'Auriac
- *
- * 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 3 of the License,
- * or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "event.h"
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/playlist.h>
-#include <audacious/misc.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "osd.h"
-
-static char * last_title = NULL, * last_message = NULL; /* pooled */
-static GdkPixbuf * last_pixbuf = NULL;
-
-static void clear_cache (void)
-{
- str_unref (last_title);
- last_title = NULL;
- str_unref (last_message);
- last_message = NULL;
-
- if (last_pixbuf)
- {
- g_object_unref (last_pixbuf);
- last_pixbuf = NULL;
- }
-}
-
-static bool_t get_album_art (void)
-{
- if (last_pixbuf)
- return FALSE;
-
- last_pixbuf = audgui_pixbuf_request_current ();
- if (! last_pixbuf)
- return FALSE;
-
- audgui_pixbuf_scale_within (& last_pixbuf, 96);
- return TRUE;
-}
-
-static void show_stopped (void)
-{
- osd_show (_("Stopped"), _("Audacious is not playing."), "audacious", NULL);
-}
-
-static void show_playing (void)
-{
- if (last_title && last_message)
- osd_show (last_title, last_message, "audio-x-generic", last_pixbuf);
-}
-
-static void playback_update (void)
-{
- if (! aud_drct_get_playing () || ! aud_drct_get_ready ())
- return;
-
- int list = aud_playlist_get_playing ();
- int entry = aud_playlist_get_position (list);
-
- char * title, * artist, * album;
- aud_playlist_entry_describe (list, entry, & title, & artist, & album, FALSE);
-
- char * message;
- if (artist)
- {
- if (album)
- message = str_printf ("%s\n%s", artist, album);
- else
- message = str_ref (artist);
- }
- else if (album)
- message = str_ref (album);
- else
- message = str_get ("");
-
- str_unref (artist);
- str_unref (album);
-
- if (str_equal (title, last_title) && str_equal (message, last_message))
- {
- str_unref (title);
- str_unref (message);
- return;
- }
-
- str_unref (last_title);
- last_title = title;
- str_unref (last_message);
- last_message = message;
-
- get_album_art ();
- show_playing ();
-}
-
-static void art_ready (void)
-{
- if (aud_drct_get_playing () && get_album_art ())
- show_playing ();
-}
-
-static void playback_paused (void)
-{
- if (aud_get_bool ("notify", "resident"))
- show_playing ();
-}
-
-static void playback_stopped (void)
-{
- clear_cache ();
-
- if (aud_get_bool ("notify", "resident"))
- show_stopped ();
-}
-
-static void force_show (void)
-{
- if (aud_drct_get_playing ())
- show_playing ();
- else
- show_stopped ();
-}
-
-void event_init (void)
-{
- if (aud_drct_get_playing ())
- playback_update ();
- else
- playback_stopped ();
-
- hook_associate ("playback begin", (HookFunction) clear_cache, NULL);
- hook_associate ("playback ready", (HookFunction) playback_update, NULL);
- hook_associate ("playlist update", (HookFunction) playback_update, NULL);
- hook_associate ("current art ready", (HookFunction) art_ready, NULL);
- hook_associate ("playback pause", (HookFunction) playback_paused, NULL);
- hook_associate ("playback unpause", (HookFunction) playback_paused, NULL);
- hook_associate ("playback stop", (HookFunction) playback_stopped, NULL);
-
- hook_associate ("aosd toggle", (HookFunction) force_show, NULL);
-}
-
-void event_uninit (void)
-{
- hook_dissociate ("playback begin", (HookFunction) clear_cache);
- hook_dissociate ("playback ready", (HookFunction) playback_update);
- hook_dissociate ("playlist update", (HookFunction) playback_update);
- hook_dissociate ("current art ready", (HookFunction) art_ready);
- hook_dissociate ("playback pause", (HookFunction) playback_paused);
- hook_dissociate ("playback unpause", (HookFunction) playback_paused);
- hook_dissociate ("playback stop", (HookFunction) playback_stopped);
-
- hook_dissociate ("aosd toggle", (HookFunction) force_show);
-
- clear_cache ();
- osd_hide ();
-}
diff --git a/src/notify/event.cc b/src/notify/event.cc
new file mode 100644
index 000000000000..7134c87777e0
--- /dev/null
+++ b/src/notify/event.cc
@@ -0,0 +1,162 @@
+/*
+ * event.c
+ *
+ * Copyright (C) 2010 Maximilian Bogner <max at mbogner.de>
+ * Copyright (C) 2011-2013 John Lindgren and Jean-Alexandre Anglès d'Auriac
+ *
+ * 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 3 of the License,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "event.h"
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/hook.h>
+#include <libaudgui/libaudgui-gtk.h>
+
+#include "osd.h"
+
+static String last_title, last_message;
+static GdkPixbuf * last_pixbuf = nullptr;
+
+static void clear_cache (void)
+{
+ last_title = String ();
+ last_message = String ();
+
+ if (last_pixbuf)
+ {
+ g_object_unref (last_pixbuf);
+ last_pixbuf = nullptr;
+ }
+
+ osd_hide ();
+}
+
+static gboolean get_album_art (void)
+{
+ if (last_pixbuf)
+ return FALSE;
+
+ last_pixbuf = audgui_pixbuf_request_current ();
+ if (! last_pixbuf)
+ return FALSE;
+
+ audgui_pixbuf_scale_within (& last_pixbuf, 96);
+ return TRUE;
+}
+
+static void show_stopped (void)
+{
+ osd_show (_("Stopped"), _("Audacious is not playing."), "audacious", nullptr);
+}
+
+static void show_playing (void)
+{
+ if (last_title && last_message)
+ osd_show (last_title, last_message, "audio-x-generic", last_pixbuf);
+}
+
+static void playback_update (void)
+{
+ Tuple tuple = aud_drct_get_tuple ();
+ String title = tuple.get_str (Tuple::Title);
+ String artist = tuple.get_str (Tuple::Artist);
+ String album = tuple.get_str (Tuple::Album);
+
+ String message;
+ if (artist)
+ {
+ if (album && aud_get_bool ("notify", "album"))
+ message = String (str_printf ("%s\n%s", (const char *) artist, (const char *) album));
+ else
+ message = artist;
+ }
+ else if (album)
+ message = album;
+ else
+ message = String ("");
+
+ if (title == last_title && message == last_message)
+ return;
+
+ last_title = title;
+ last_message = message;
+
+ get_album_art ();
+ show_playing ();
+}
+
+static void art_ready (void)
+{
+ if (aud_drct_get_playing () && get_album_art ())
+ show_playing ();
+}
+
+static void playback_paused (void)
+{
+ if (aud_get_bool ("notify", "resident"))
+ show_playing ();
+}
+
+static void playback_stopped (void)
+{
+ clear_cache ();
+
+ if (aud_get_bool ("notify", "resident"))
+ show_stopped ();
+}
+
+static void force_show (void)
+{
+ if (aud_drct_get_playing ())
+ show_playing ();
+ else
+ show_stopped ();
+}
+
+void event_init (void)
+{
+ if (aud_drct_get_ready ())
+ playback_update ();
+ else
+ playback_stopped ();
+
+ hook_associate ("playback begin", (HookFunction) clear_cache, nullptr);
+ hook_associate ("playback ready", (HookFunction) playback_update, nullptr);
+ hook_associate ("tuple change", (HookFunction) playback_update, nullptr);
+ hook_associate ("current art ready", (HookFunction) art_ready, nullptr);
+ hook_associate ("playback pause", (HookFunction) playback_paused, nullptr);
+ hook_associate ("playback unpause", (HookFunction) playback_paused, nullptr);
+ hook_associate ("playback stop", (HookFunction) playback_stopped, nullptr);
+
+ hook_associate ("aosd toggle", (HookFunction) force_show, nullptr);
+}
+
+void event_uninit (void)
+{
+ hook_dissociate ("playback begin", (HookFunction) clear_cache);
+ hook_dissociate ("playback ready", (HookFunction) playback_update);
+ hook_dissociate ("tuple change", (HookFunction) playback_update);
+ hook_dissociate ("current art ready", (HookFunction) art_ready);
+ hook_dissociate ("playback pause", (HookFunction) playback_paused);
+ hook_dissociate ("playback unpause", (HookFunction) playback_paused);
+ hook_dissociate ("playback stop", (HookFunction) playback_stopped);
+
+ hook_dissociate ("aosd toggle", (HookFunction) force_show);
+
+ clear_cache ();
+}
diff --git a/src/notify/notify.c b/src/notify/notify.c
deleted file mode 100644
index 3b2193784eed..000000000000
--- a/src/notify/notify.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * notify.c
- *
- * Copyright (C) 2010 Maximilian Bogner <max at mbogner.de>
- * Copyright (C) 2013 John Lindgren and Jean-Alexandre Anglès d'Auriac
- *
- * 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 3 of the License,
- * or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-#include <libnotify/notify.h>
-
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-#include <audacious/misc.h>
-
-#include "event.h"
-
-static const char plugin_about[] =
- N_("Desktop Notifications Plugin for Audacious\n"
- "Copyright (C) 2010 Maximilian Bogner\n"
- "Copyright (C) 2011-2013 John Lindgren and Jean-Alexandre Anglès d'Auriac\n\n"
- "This plugin is free software: you can redistribute it and/or modify "
- "it under the terms of the GNU General Public License as published by "
- "the Free Software Foundation, either version 3 of the License, or "
- "(at your option) any later version.\n\n"
- "This plugin 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, see <http://www.gnu.org/licenses/>.");
-
-static const char * const notify_defaults[] = {
- "actions", "TRUE",
- "resident", "FALSE",
- NULL
-};
-
-static bool_t plugin_init (void)
-{
- aud_config_set_defaults ("notify", notify_defaults);
-
- if (! notify_init ("Audacious"))
- return FALSE;
-
- event_init();
- return TRUE;
-}
-
-static void plugin_cleanup (void)
-{
- event_uninit ();
- notify_uninit ();
-}
-
-static void plugin_reinit (void)
-{
- event_uninit ();
- event_init ();
-}
-
-static const PreferencesWidget prefs_widgets[] = {
- {WIDGET_CHK_BTN, N_("Show playback controls"),
- .cfg_type = VALUE_BOOLEAN, .csect = "notify", .cname = "actions",
- .callback = plugin_reinit},
- {WIDGET_CHK_BTN, N_("Always show notification"),
- .cfg_type = VALUE_BOOLEAN, .csect = "notify", .cname = "resident",
- .callback = plugin_reinit}
-};
-
-static const PluginPreferences plugin_prefs = {
- .widgets = prefs_widgets,
- .n_widgets = ARRAY_LEN (prefs_widgets)
-};
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("Desktop Notifications"),
- .domain = PACKAGE,
- .about_text = plugin_about,
- .prefs = & plugin_prefs,
- .init = plugin_init,
- .cleanup = plugin_cleanup
-)
diff --git a/src/notify/notify.cc b/src/notify/notify.cc
new file mode 100644
index 000000000000..ac37654d07d7
--- /dev/null
+++ b/src/notify/notify.cc
@@ -0,0 +1,118 @@
+/*
+ * notify.c
+ *
+ * Copyright (C) 2010 Maximilian Bogner <max at mbogner.de>
+ * Copyright (C) 2013 John Lindgren and Jean-Alexandre Anglès d'Auriac
+ *
+ * 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 3 of the License,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+
+#include <libnotify/notify.h>
+
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudgui/libaudgui.h>
+
+#include "event.h"
+
+class NotifyPlugin : public GeneralPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Desktop Notifications"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ constexpr NotifyPlugin () : GeneralPlugin (info, false) {}
+
+ bool init ();
+ void cleanup ();
+
+private:
+ static void reinit ();
+};
+
+EXPORT NotifyPlugin aud_plugin_instance;
+
+const char NotifyPlugin::about[] =
+ N_("Desktop Notifications Plugin for Audacious\n"
+ "Copyright (C) 2010 Maximilian Bogner\n"
+ "Copyright (C) 2011-2013 John Lindgren and Jean-Alexandre Anglès d'Auriac\n\n"
+ "This plugin is free software: you can redistribute it and/or modify "
+ "it under the terms of the GNU General Public License as published by "
+ "the Free Software Foundation, either version 3 of the License, or "
+ "(at your option) any later version.\n\n"
+ "This plugin 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, see <http://www.gnu.org/licenses/>.");
+
+const char * const NotifyPlugin::defaults[] = {
+ "actions", "TRUE",
+ "resident", "FALSE",
+ "album", "TRUE",
+ nullptr
+};
+
+bool NotifyPlugin::init ()
+{
+ if (aud_get_mainloop_type () != MainloopType::GLib)
+ return false;
+
+ aud_config_set_defaults ("notify", defaults);
+
+ if (! notify_init ("Audacious"))
+ return false;
+
+ audgui_init ();
+ event_init ();
+ return true;
+}
+
+void NotifyPlugin::cleanup ()
+{
+ event_uninit ();
+ audgui_cleanup ();
+ notify_uninit ();
+}
+
+void NotifyPlugin::reinit ()
+{
+ event_uninit ();
+ event_init ();
+}
+
+const PreferencesWidget NotifyPlugin::widgets[] = {
+ WidgetCheck (N_("Show playback controls"),
+ WidgetBool ("notify", "actions", reinit)),
+ WidgetCheck (N_("Always show notification"),
+ WidgetBool ("notify", "resident", reinit)),
+ WidgetCheck (N_("Include album name in notification"),
+ WidgetBool ("notify", "album", reinit))
+};
+
+const PluginPreferences NotifyPlugin::prefs = {{widgets}};
diff --git a/src/notify/osd.c b/src/notify/osd.c
deleted file mode 100644
index ca7448fc2f74..000000000000
--- a/src/notify/osd.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * osd.c
- *
- * Copyright (C) 2010 Maximilian Bogner <max at mbogner.de>
- * Copyright (C) 2013 John Lindgren and Jean-Alexandre Anglès d'Auriac
- *
- * 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 3 of the License,
- * or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "osd.h"
-
-#include <libnotify/notify.h>
-
-#include <audacious/i18n.h>
-#include <audacious/drct.h>
-#include <audacious/misc.h>
-
-static void show_cb (void)
-{
- aud_interface_show (TRUE);
-}
-
-static void osd_setup (NotifyNotification *notification)
-{
- bool_t resident = aud_get_bool ("notify", "resident");
-
- notify_notification_set_hint (notification, "desktop-entry",
- g_variant_new_string ("audacious"));
-
- notify_notification_set_hint (notification, "action-icons", g_variant_new_boolean (TRUE));
- notify_notification_set_hint (notification, "resident", g_variant_new_boolean (resident));
- notify_notification_set_hint (notification, "transient", g_variant_new_boolean (! resident));
-
- notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
- notify_notification_set_timeout (notification, resident ?
- NOTIFY_EXPIRES_NEVER : NOTIFY_EXPIRES_DEFAULT);
-}
-
-void osd_setup_buttons (NotifyNotification *notification)
-{
- notify_notification_clear_actions (notification);
-
- if (! aud_get_bool ("notify", "actions"))
- return;
-
- notify_notification_add_action (notification, "default", _("Show"),
- NOTIFY_ACTION_CALLBACK (show_cb), NULL, NULL);
-
- bool_t playing = aud_drct_get_playing ();
- bool_t paused = aud_drct_get_paused ();
-
- if (playing && ! paused)
- notify_notification_add_action (notification, "media-playback-pause",
- _("Pause"), NOTIFY_ACTION_CALLBACK (aud_drct_pause), NULL, NULL);
- else
- notify_notification_add_action (notification, "media-playback-start",
- _("Play"), NOTIFY_ACTION_CALLBACK (aud_drct_play), NULL, NULL);
-
- if (playing)
- notify_notification_add_action (notification, "media-skip-forward",
- _("Next"), NOTIFY_ACTION_CALLBACK (aud_drct_pl_next), NULL, NULL);
-}
-
-static NotifyNotification * notification = NULL;
-
-void osd_show (const char * title, const char * _message, const char * icon,
- GdkPixbuf * pixbuf)
-{
- char * message = g_markup_escape_text (_message, -1);
-
- if (pixbuf)
- icon = NULL;
-
- if (notification)
- notify_notification_update (notification, title, message, icon);
- else
- {
- notification = notify_notification_new (title, message, icon);
- osd_setup (notification);
- }
-
- if (pixbuf)
- notify_notification_set_image_from_pixbuf (notification, pixbuf);
-
- osd_setup_buttons (notification);
- notify_notification_show (notification, NULL);
-
- g_free (message);
-}
-
-void osd_hide (void)
-{
- if (! notification)
- return;
-
- notify_notification_close (notification, NULL);
- g_object_unref (notification);
- notification = NULL;
-}
diff --git a/src/notify/osd.cc b/src/notify/osd.cc
new file mode 100644
index 000000000000..d2ebfe24680a
--- /dev/null
+++ b/src/notify/osd.cc
@@ -0,0 +1,111 @@
+/*
+ * osd.c
+ *
+ * Copyright (C) 2010 Maximilian Bogner <max at mbogner.de>
+ * Copyright (C) 2013 John Lindgren and Jean-Alexandre Anglès d'Auriac
+ *
+ * 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 3 of the License,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "osd.h"
+
+#include <libnotify/notify.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/runtime.h>
+
+static void show_cb (void)
+{
+ aud_ui_show (TRUE);
+}
+
+static void osd_setup (NotifyNotification *notification)
+{
+ gboolean resident = aud_get_bool ("notify", "resident");
+
+ notify_notification_set_hint (notification, "desktop-entry",
+ g_variant_new_string ("audacious"));
+
+ notify_notification_set_hint (notification, "action-icons", g_variant_new_boolean (TRUE));
+ notify_notification_set_hint (notification, "resident", g_variant_new_boolean (resident));
+ notify_notification_set_hint (notification, "transient", g_variant_new_boolean (! resident));
+
+ notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
+ notify_notification_set_timeout (notification, resident ?
+ NOTIFY_EXPIRES_NEVER : NOTIFY_EXPIRES_DEFAULT);
+}
+
+void osd_setup_buttons (NotifyNotification *notification)
+{
+ notify_notification_clear_actions (notification);
+
+ if (! aud_get_bool ("notify", "actions"))
+ return;
+
+ notify_notification_add_action (notification, "default", _("Show"),
+ NOTIFY_ACTION_CALLBACK (show_cb), nullptr, nullptr);
+
+ gboolean playing = aud_drct_get_playing ();
+ gboolean paused = aud_drct_get_paused ();
+
+ if (playing && ! paused)
+ notify_notification_add_action (notification, "media-playback-pause",
+ _("Pause"), NOTIFY_ACTION_CALLBACK (aud_drct_pause), nullptr, nullptr);
+ else
+ notify_notification_add_action (notification, "media-playback-start",
+ _("Play"), NOTIFY_ACTION_CALLBACK (aud_drct_play), nullptr, nullptr);
+
+ if (playing)
+ notify_notification_add_action (notification, "media-skip-forward",
+ _("Next"), NOTIFY_ACTION_CALLBACK (aud_drct_pl_next), nullptr, nullptr);
+}
+
+static NotifyNotification * notification = nullptr;
+
+void osd_show (const char * title, const char * _message, const char * icon,
+ GdkPixbuf * pixbuf)
+{
+ char * message = g_markup_escape_text (_message, -1);
+
+ if (pixbuf)
+ icon = nullptr;
+
+ if (notification)
+ notify_notification_update (notification, title, message, icon);
+ else
+ {
+ notification = notify_notification_new (title, message, icon);
+ osd_setup (notification);
+ }
+
+ if (pixbuf)
+ notify_notification_set_image_from_pixbuf (notification, pixbuf);
+
+ osd_setup_buttons (notification);
+ notify_notification_show (notification, nullptr);
+
+ g_free (message);
+}
+
+void osd_hide (void)
+{
+ if (! notification)
+ return;
+
+ notify_notification_close (notification, nullptr);
+ g_object_unref (notification);
+ notification = nullptr;
+}
diff --git a/src/oss4/Makefile b/src/oss4/Makefile
index ff01addd4ed2..c0e83511d774 100644
--- a/src/oss4/Makefile
+++ b/src/oss4/Makefile
@@ -1,13 +1,15 @@
PLUGIN = oss4${PLUGIN_SUFFIX}
-SRCS = plugin.c \
- oss.c \
- utils.c
+SRCS = plugin.cc \
+ oss.cc \
+ utils.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${OUTPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${OSS_CFLAGS} -I../..
diff --git a/src/oss4/oss.c b/src/oss4/oss.c
deleted file mode 100644
index b8dd5961473a..000000000000
--- a/src/oss4/oss.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * oss.c
- * Copyright 2010-2012 MichaÅ Lipski
- *
- * I would like to thank people on #audacious, especially Tony Vroon and
- * John Lindgren and of course the authors of the previous OSS plugin.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include "oss.h"
-
-#include <libaudcore/audstrings.h>
-
-static const char * const oss_defaults[] = {
- "device", DEFAULT_DSP,
- "use_alt_device", "FALSE",
- "alt_device", DEFAULT_DSP,
- "save_volume", "TRUE",
- "volume", "12850", /* 0x3232 */
- "cookedmode", "TRUE",
- "exclusive", "FALSE",
- NULL};
-
-oss_data_t *oss_data;
-static int64_t oss_time; /* microseconds */
-static bool_t oss_paused;
-static int oss_paused_time;
-static int oss_delay; /* miliseconds */
-static bool_t oss_ioctl_vol = FALSE;
-
-bool_t oss_init(void)
-{
- AUDDBG("Init.\n");
-
- aud_config_set_defaults("oss4", oss_defaults);
- oss_data = (oss_data_t *) malloc(sizeof(oss_data_t));
- oss_data->fd = -1;
-
- return oss_hardware_present();
-}
-
-void oss_cleanup(void)
-{
- AUDDBG("Cleanup.\n");
-
- free(oss_data);
-}
-
-static bool_t set_format(int format, int rate, int channels)
-{
- int param;
-
- AUDDBG("Audio format: %s, sample rate: %dHz, number of channels: %d.\n", oss_format_to_text(format), rate, channels);
-
- /* Enable/disable format conversions made by the OSS software */
- param = aud_get_bool("oss4", "cookedmode");
- CHECK(ioctl, oss_data->fd, SNDCTL_DSP_COOKEDMODE, ¶m);
-
- AUDDBG("%s format conversions made by the OSS software.\n", param ? "Enabled" : "Disabled");
-
- param = format;
- CHECK_NOISY(ioctl, oss_data->fd, SNDCTL_DSP_SETFMT, ¶m);
- CHECK_VAL(param == format, ERROR_NOISY, "Selected audio format is not supported by the device.\n");
-
- param = rate;
- CHECK_NOISY(ioctl, oss_data->fd, SNDCTL_DSP_SPEED, ¶m);
- CHECK_VAL(param >= rate * 9 / 10 && param <= rate * 11 / 10, ERROR_NOISY,
- "Selected sample rate is not supported by the device.\n");
-
- param = channels;
- CHECK_NOISY(ioctl, oss_data->fd, SNDCTL_DSP_CHANNELS, ¶m);
- CHECK_VAL(param == channels, ERROR_NOISY, "Selected number of channels is not supported by the device.\n");
-
- oss_data->format = format;
- oss_data->rate = rate;
- oss_data->channels = channels;
- oss_data->bits_per_sample = oss_format_to_bits(oss_data->format);
-
- return TRUE;
-
-FAILED:
- return FALSE;
-}
-
-static int open_device(void)
-{
- int res = -1;
- int flags = O_WRONLY;
- char *device = aud_get_str("oss4", "device");
- char *alt_device = aud_get_str("oss4", "alt_device");
-
- if (aud_get_bool("oss4", "exclusive"))
- {
- AUDDBG("Enabled exclusive mode.\n");
- flags |= O_EXCL;
- }
-
- if (aud_get_bool("oss4", "use_alt_device") && alt_device != NULL)
- res = open(alt_device, flags);
- else if (device != NULL)
- res = open(device, flags);
- else
- res = open(DEFAULT_DSP, flags);
-
- str_unref(device);
- str_unref(alt_device);
-
- return res;
-}
-
-static void close_device(void)
-{
- close(oss_data->fd);
- oss_data->fd = -1;
-}
-
-int oss_open_audio(int aud_format, int rate, int channels)
-{
- AUDDBG("Opening audio.\n");
-
- int format;
- int vol_left, vol_right;
- audio_buf_info buf_info;
-
- CHECK_NOISY(oss_data->fd = open_device);
-
- format = oss_convert_aud_format(aud_format);
-
- if (!set_format(format, rate, channels))
- goto FAILED;
-
- CHECK_NOISY(ioctl, oss_data->fd, SNDCTL_DSP_GETOSPACE, &buf_info);
-
- AUDDBG("Buffer information, fragstotal: %d, fragsize: %d, bytes: %d.\n",
- buf_info.fragstotal,
- buf_info.fragsize,
- buf_info.bytes);
-
- oss_time = 0;
- oss_paused = FALSE;
- oss_paused_time = 0;
- oss_delay = oss_bytes_to_frames(buf_info.fragstotal * buf_info.fragsize) * 1000 / oss_data->rate;
- oss_ioctl_vol = TRUE;
-
- AUDDBG("Internal OSS buffer size: %dms.\n", oss_delay);
-
- if (aud_get_bool("oss4", "save_volume"))
- {
- vol_right = (aud_get_int("oss4", "volume") & 0xFF00) >> 8;
- vol_left = (aud_get_int("oss4", "volume") & 0x00FF);
- oss_set_volume(vol_left, vol_right);
- }
-
- return 1;
-
-FAILED:
- close_device();
- return 0;
-}
-
-void oss_close_audio(void)
-{
- AUDDBG ("Closing audio.\n");
-
- close_device();
-}
-
-void oss_write_audio(void *data, int length)
-{
- int written = 0, start = 0;
-
- while (length > 0)
- {
- written = write(oss_data->fd, (char *) data + start, length);
-
- if (written < 0)
- {
- DESCRIBE_ERROR;
- return;
- }
-
- length -= written;
- start += written;
- oss_time += (int64_t) oss_bytes_to_frames(written) * 1000000 / oss_data->rate;
- }
-}
-
-void oss_drain(void)
-{
- AUDDBG("Drain.\n");
-
- if (ioctl(oss_data->fd, SNDCTL_DSP_SYNC, NULL) == -1)
- DESCRIBE_ERROR;
-}
-
-int oss_buffer_free(void)
-{
- audio_buf_info buf_info;
-
- if (oss_paused)
- return 0;
-
- CHECK(ioctl, oss_data->fd, SNDCTL_DSP_GETOSPACE, &buf_info);
-
- return MAX(0, buf_info.fragments - 1) * buf_info.fragsize;
-
-FAILED:
- return 0;
-}
-
-static int real_output_time()
-{
- int time = 0;
-
- time = (oss_time - (int64_t) (oss_delay * 1000)) / 1000;
- return time;
-}
-
-int oss_output_time(void)
-{
- int time = 0;
-
- if (oss_paused)
- time = oss_paused_time;
- else
- time = real_output_time();
- return time;
-}
-
-void oss_flush(int time)
-{
- AUDDBG("Flush.\n");
-
- CHECK(ioctl, oss_data->fd, SNDCTL_DSP_RESET, NULL);
-
-FAILED:
- oss_time = (int64_t) time * 1000;
- oss_paused_time = time;
-}
-
-void oss_pause(bool_t pause)
-{
- AUDDBG("%sause.\n", pause ? "P" : "Unp");
-
- if (pause)
- {
- oss_paused_time = real_output_time();
- CHECK(ioctl, oss_data->fd, SNDCTL_DSP_SILENCE, NULL);
- }
- else
- CHECK(ioctl, oss_data->fd, SNDCTL_DSP_SKIP, NULL);
-
-FAILED:
- oss_paused = pause;
-}
-
-void oss_get_volume(int *left, int *right)
-{
- *left = *right = 0;
-
- int vol;
-
- if (oss_data->fd == -1 || !oss_ioctl_vol)
- {
- if (aud_get_int("oss4", "save_volume"))
- {
- *right = (aud_get_int("oss4", "volume") & 0xFF00) >> 8;
- *left = (aud_get_int("oss4", "volume") & 0x00FF);
- }
- return;
- }
-
- CHECK(ioctl, oss_data->fd, SNDCTL_DSP_GETPLAYVOL, &vol);
-
- *right = (vol & 0xFF00) >> 8;
- *left = (vol & 0x00FF);
- aud_set_int("oss4", "volume", vol);
-
- return;
-
-FAILED:
- if (errno == EINVAL)
- oss_ioctl_vol = FALSE;
-}
-
-void oss_set_volume(int left, int right)
-{
- int vol = (right << 8) | left;
-
- if (aud_get_int("oss4", "save_volume"))
- aud_set_int("oss4", "volume", vol);
-
- if (oss_data->fd == -1 || !oss_ioctl_vol)
- return;
-
- CHECK(ioctl, oss_data->fd, SNDCTL_DSP_SETPLAYVOL, &vol);
-
- return;
-
-FAILED:
- if (errno == EINVAL)
- oss_ioctl_vol = FALSE;
-}
diff --git a/src/oss4/oss.cc b/src/oss4/oss.cc
new file mode 100644
index 000000000000..923449d7cfd8
--- /dev/null
+++ b/src/oss4/oss.cc
@@ -0,0 +1,365 @@
+/*
+ * oss.c
+ * Copyright 2010-2012 MichaÅ Lipski
+ *
+ * I would like to thank people on #audacious, especially Tony Vroon and
+ * John Lindgren and of course the authors of the previous OSS plugin.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include "oss.h"
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/runtime.h>
+
+#include <poll.h>
+
+constexpr StereoVolume to_stereo_volume(int vol)
+ { return {vol & 0x00ff, vol >> 8}; }
+constexpr int from_stereo_volume(StereoVolume v)
+ { return v.left | (v.right << 8); }
+
+const char * const OSSPlugin::defaults[] = {
+ "device", DEFAULT_DSP,
+ "use_alt_device", "FALSE",
+ "alt_device", DEFAULT_DSP,
+ "save_volume", "TRUE",
+ "volume", aud::numeric_string<0x3232>::str,
+ "cookedmode", "TRUE",
+ "exclusive", "FALSE",
+ nullptr};
+
+static int poll_pipe[2];
+static pollfd poll_handles[2];
+
+bool OSSPlugin::init()
+{
+ AUDDBG("Init.\n");
+
+ aud_config_set_defaults("oss4", defaults);
+
+ return oss_hardware_present();
+}
+
+bool OSSPlugin::set_format(int format, int rate, int channels)
+{
+ int param;
+
+ AUDDBG("Audio format: %s, sample rate: %dHz, number of channels: %d.\n", oss_format_to_text(format), rate, channels);
+
+#ifdef SNDCTL_DSP_COOKEDMODE
+ /* Enable/disable format conversions made by the OSS software */
+ param = aud_get_bool("oss4", "cookedmode");
+ CHECK(ioctl, m_fd, SNDCTL_DSP_COOKEDMODE, ¶m);
+
+ AUDDBG("%s format conversions made by the OSS software.\n", param ? "Enabled" : "Disabled");
+#endif
+
+ param = format;
+ CHECK_NOISY(ioctl, m_fd, SNDCTL_DSP_SETFMT, ¶m);
+ CHECK_VAL(param == format, ERROR_NOISY, "Selected audio format is not supported by the device.\n");
+
+ param = rate;
+ CHECK_NOISY(ioctl, m_fd, SNDCTL_DSP_SPEED, ¶m);
+ CHECK_VAL(param >= rate * 9 / 10 && param <= rate * 11 / 10, ERROR_NOISY,
+ "Selected sample rate is not supported by the device.\n");
+
+ param = channels;
+ CHECK_NOISY(ioctl, m_fd, SNDCTL_DSP_CHANNELS, ¶m);
+ CHECK_VAL(param == channels, ERROR_NOISY, "Selected number of channels is not supported by the device.\n");
+
+ m_format = format;
+ m_rate = rate;
+ m_channels = channels;
+ m_bytes_per_sample = oss_format_to_bytes(m_format);
+
+ return true;
+
+FAILED:
+ return false;
+}
+
+static int log2(int x)
+{
+ int y = 0;
+
+ while((x >>= 1))
+ y++;
+
+ return y;
+}
+
+bool OSSPlugin::set_buffer()
+{
+ int milliseconds = aud_get_int(nullptr, "output_buffer_size");
+ int bytes = frames_to_bytes(aud::rescale(milliseconds, 1000, m_rate));
+ int fragorder = aud::clamp(log2(bytes / 4), 9, 15);
+ int numfrags = aud::clamp(aud::rdiv(bytes, 1 << fragorder), 4, 32767);
+
+ int param = (numfrags << 16) | fragorder;
+ CHECK_NOISY(ioctl, m_fd, SNDCTL_DSP_SETFRAGMENT, ¶m);
+
+ return true;
+
+FAILED:
+ return false;
+}
+
+static int open_device()
+{
+ int res = -1;
+ int flags = O_WRONLY | O_NONBLOCK;
+ String device = aud_get_str("oss4", "device");
+ String alt_device = aud_get_str("oss4", "alt_device");
+
+ if (aud_get_bool("oss4", "exclusive"))
+ {
+ AUDDBG("Enabled exclusive mode.\n");
+ flags |= O_EXCL;
+ }
+
+ if (aud_get_bool("oss4", "use_alt_device") && alt_device != nullptr)
+ res = open(alt_device, flags);
+ else if (device != nullptr)
+ res = open(device, flags);
+ else
+ res = open(DEFAULT_DSP, flags);
+
+ return res;
+}
+
+static void close_device(int &fd)
+{
+ close(fd);
+ fd = -1;
+}
+
+static bool poll_setup(int fd)
+{
+ if (pipe(poll_pipe))
+ {
+ AUDERR("Failed to create pipe: %s.\n", strerror(errno));
+ return false;
+ }
+
+ if (fcntl(poll_pipe[0], F_SETFL, O_NONBLOCK))
+ {
+ AUDERR("Failed to set O_NONBLOCK on pipe: %s.\n", strerror(errno));
+ close(poll_pipe[0]);
+ close(poll_pipe[1]);
+ return false;
+ }
+
+ poll_handles[0].fd = poll_pipe[0];
+ poll_handles[0].events = POLLIN;
+ poll_handles[1].fd = fd;
+ poll_handles[1].events = POLLOUT;
+
+ return true;
+}
+
+static void poll_sleep()
+{
+ if (poll(poll_handles, 2, -1) < 0)
+ {
+ AUDERR("Failed to poll: %s.\n", strerror(errno));
+ return;
+ }
+
+ if (poll_handles[0].revents & POLLIN)
+ {
+ char c;
+ while (read(poll_pipe[0], &c, 1) == 1)
+ ;
+ }
+}
+
+static void poll_wake()
+{
+ const char c = 0;
+ if (write(poll_pipe[1], &c, 1) < 0)
+ AUDERR("Failed to write to pipe: %s.\n", strerror(errno));
+}
+
+static void poll_cleanup()
+{
+ close(poll_pipe[0]);
+ close(poll_pipe[1]);
+}
+
+bool OSSPlugin::open_audio(int aud_format, int rate, int channels)
+{
+ AUDDBG("Opening audio.\n");
+
+ int format;
+ audio_buf_info buf_info;
+
+ CHECK_NOISY(m_fd = open_device);
+
+ if (!poll_setup(m_fd))
+ goto CLOSE;
+
+ format = oss_convert_aud_format(aud_format);
+
+ if (!set_format(format, rate, channels))
+ goto FAILED;
+
+ if (!set_buffer())
+ goto FAILED;
+
+ memset(&buf_info, 0, sizeof buf_info);
+ CHECK_NOISY(ioctl, m_fd, SNDCTL_DSP_GETOSPACE, &buf_info);
+
+ AUDINFO("Buffer information, fragstotal: %d, fragsize: %d, bytes: %d.\n",
+ buf_info.fragstotal,
+ buf_info.fragsize,
+ buf_info.bytes);
+
+ m_paused = false;
+ m_ioctl_vol = true;
+
+ if (aud_get_bool("oss4", "save_volume"))
+ set_volume(to_stereo_volume(aud_get_int("oss4", "volume")));
+
+ return true;
+
+FAILED:
+ poll_cleanup();
+CLOSE:
+ close_device(m_fd);
+ return false;
+}
+
+void OSSPlugin::close_audio()
+{
+ AUDDBG("Closing audio.\n");
+
+ poll_cleanup();
+ close_device(m_fd);
+}
+
+int OSSPlugin::write_audio(const void *data, int length)
+{
+ if (m_paused)
+ return 0;
+
+ int written = write(m_fd, data, length);
+
+ if (written < 0)
+ {
+ if (errno != EAGAIN)
+ DESCRIBE_ERROR;
+
+ return 0;
+ }
+
+ return written;
+}
+
+void OSSPlugin::period_wait()
+{
+ poll_sleep();
+}
+
+void OSSPlugin::drain()
+{
+ AUDDBG("Drain.\n");
+
+ if (ioctl(m_fd, SNDCTL_DSP_SYNC, nullptr) == -1)
+ DESCRIBE_ERROR;
+}
+
+int OSSPlugin::get_delay()
+{
+ int delay_bytes = 0;
+ CHECK(ioctl, m_fd, SNDCTL_DSP_GETODELAY, &delay_bytes);
+
+FAILED:
+ return aud::rescale<int64_t>(bytes_to_frames(delay_bytes), m_rate, 1000);
+}
+
+void OSSPlugin::flush()
+{
+ AUDDBG("Flush.\n");
+
+ CHECK(ioctl, m_fd, SNDCTL_DSP_RESET, nullptr);
+
+FAILED:
+ poll_wake();
+}
+
+void OSSPlugin::pause(bool pause)
+{
+ AUDDBG("%sause.\n", pause ? "P" : "Unp");
+
+#ifdef SNDCTL_DSP_SILENCE
+ if (pause)
+ CHECK(ioctl, m_fd, SNDCTL_DSP_SILENCE, nullptr);
+ else
+ CHECK(ioctl, m_fd, SNDCTL_DSP_SKIP, nullptr);
+
+FAILED:
+#endif
+ m_paused = pause;
+}
+
+StereoVolume OSSPlugin::get_volume()
+{
+#ifdef SNDCTL_DSP_GETPLAYVOL
+ int vol = 0;
+
+ if (m_fd == -1 || !m_ioctl_vol)
+ {
+ if (aud_get_bool("oss4", "save_volume"))
+ return to_stereo_volume(aud_get_int("oss4", "volume"));
+
+ goto FAILED;
+ }
+
+ CHECK(ioctl, m_fd, SNDCTL_DSP_GETPLAYVOL, &vol);
+
+ aud_set_int("oss4", "volume", vol);
+
+ return to_stereo_volume(vol);
+
+FAILED:
+ if (errno == EINVAL)
+ m_ioctl_vol = false;
+#endif
+
+ return to_stereo_volume(0);
+}
+
+void OSSPlugin::set_volume(StereoVolume v)
+{
+#ifdef SNDCTL_DSP_SETPLAYVOL
+ int vol = from_stereo_volume(v);
+
+ if (aud_get_bool("oss4", "save_volume"))
+ aud_set_int("oss4", "volume", vol);
+
+ if (m_fd == -1 || !m_ioctl_vol)
+ return;
+
+ CHECK(ioctl, m_fd, SNDCTL_DSP_SETPLAYVOL, &vol);
+
+ return;
+
+FAILED:
+ if (errno == EINVAL)
+ m_ioctl_vol = false;
+#endif
+}
diff --git a/src/oss4/oss.h b/src/oss4/oss.h
index 5e198b540800..4de81109829f 100644
--- a/src/oss4/oss.h
+++ b/src/oss4/oss.h
@@ -23,7 +23,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
-#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
@@ -34,21 +33,16 @@
#include <soundcard.h>
#endif
-#include <audacious/plugin.h>
-#include <audacious/i18n.h>
-#include <audacious/debug.h>
-#include <audacious/misc.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
-#define ERROR(...) \
-do { \
- fprintf(stderr, "OSS4 %s:%d [%s]: ", __FILE__, __LINE__, __FUNCTION__); \
- fprintf(stderr, __VA_ARGS__); \
-} while (0)
+#define ERROR AUDERR
#define ERROR_NOISY(...) \
do { \
- SPRINTF(oss_error_buf, "OSS4 error: "__VA_ARGS__); \
- aud_interface_show_error(oss_error_buf); \
+ aud_ui_show_error(str_printf("OSS4 error: " __VA_ARGS__)); \
ERROR(__VA_ARGS__); \
} while (0) \
@@ -84,43 +78,81 @@ do { \
#define DEFAULT_MIXER "/dev/mixer"
#define DEFAULT_DSP "/dev/dsp"
-typedef struct
+struct PreferencesWidget;
+
+class OSSPlugin : public OutputPlugin
{
- int fd;
- int format;
- int rate;
- int channels;
- int bits_per_sample;
-} oss_data_t;
-
-extern oss_data_t *oss_data;
-
-/* oss.c */
-bool_t oss_init(void);
-void oss_cleanup(void);
-int oss_open_audio(int aud_format, int rate, int channels);
-void oss_close_audio(void);
-void oss_write_audio(void *data, int length);
-void oss_drain(void);
-int oss_buffer_free(void);
-int oss_output_time(void);
-void oss_flush(int time);
-void oss_pause(bool_t pause);
-void oss_get_volume(int *left, int *right);
-void oss_set_volume(int left, int right);
-
-/* configure.c */
-void oss_configure(void);
+public:
+ static const char about[];
+ static const char *const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+#ifdef SNDCTL_SYSINFO
+ N_("OSS4 Output"),
+#else
+ N_("OSS3 Output"),
+#endif
+ PACKAGE,
+ about,
+ &prefs
+ };
+
+ // OSS4 is preferred over ALSA (priority 5).
+ // ALSA is preferred over OSS3.
+#ifdef SNDCTL_SYSINFO
+ constexpr OSSPlugin() : OutputPlugin(info, 6) {}
+#else
+ constexpr OSSPlugin() : OutputPlugin(info, 4) {}
+#endif
+
+ bool init();
+
+ StereoVolume get_volume();
+ void set_volume(StereoVolume v);
+
+ bool open_audio(int aud_format, int rate, int chans);
+ void close_audio();
+
+ void period_wait();
+ int write_audio(const void *data, int size);
+ void drain();
+
+ int get_delay();
+
+ void pause(bool pause);
+ void flush();
+
+private:
+ bool set_format(int format, int rate, int channels);
+ bool set_buffer();
+
+ int frames_to_bytes(int frames) const
+ { return frames * (m_bytes_per_sample * m_channels); }
+ int bytes_to_frames(int bytes) const
+ { return bytes / (m_bytes_per_sample * m_channels); }
+
+ int m_fd = -1;
+ int m_format = 0;
+ int m_rate = 0;
+ int m_channels = 0;
+ int m_bytes_per_sample = 0;
+
+ bool m_paused = false;
+ bool m_ioctl_vol = false;
+};
/* utils.c */
int oss_convert_aud_format(int aud_format);
-char *oss_format_to_text(int format);
-int oss_format_to_bits(int format);
-int oss_frames_to_bytes(int frames);
-int oss_bytes_to_frames(int bytes);
-int oss_calc_bitrate(void);
-char *oss_describe_error(void);
+const char *oss_format_to_text(int format);
+int oss_format_to_bytes(int format);
+const char *oss_describe_error();
+
+#ifdef SNDCTL_SYSINFO
int oss_probe_for_adev(oss_sysinfo *sysinfo);
-bool_t oss_hardware_present(void);
+#endif
+
+bool oss_hardware_present();
#endif
diff --git a/src/oss4/plugin.c b/src/oss4/plugin.c
deleted file mode 100644
index aa99e6043e0d..000000000000
--- a/src/oss4/plugin.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * plugin.c
- * Copyright 2010-2012 MichaÅ Lipski
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include "oss.h"
-
-#include <audacious/preferences.h>
-#include <libaudcore/audstrings.h>
-
-static void combo_init(ComboBoxElements ** elements, int * n_elements)
-{
- oss_sysinfo sysinfo;
- int mixerfd;
-
- CHECK_NOISY(mixerfd = open, DEFAULT_MIXER, O_RDWR);
- CHECK(ioctl, mixerfd, SNDCTL_SYSINFO, &sysinfo);
- CHECK_NOISY(oss_probe_for_adev, &sysinfo);
-
- * elements = (ComboBoxElements *) malloc((sysinfo.numaudios + 1) * sizeof(ComboBoxElements));
- * n_elements = 1;
- ComboBoxElements * tmp = * elements;
-
- tmp->label = N_("1. Default device");
- tmp->value = DEFAULT_DSP;
-
- for (int i = 0; i < sysinfo.numaudios; i++)
- {
- oss_audioinfo ainfo;
- ainfo.dev = i;
-
- CHECK(ioctl, mixerfd, SNDCTL_AUDIOINFO, &ainfo);
-
- if (ainfo.caps & PCM_CAP_OUTPUT)
- {
- tmp++;
- (* n_elements) ++;
- SPRINTF(str, "%d. %s", * n_elements, ainfo.name);
- tmp->label = strdup(str);
- tmp->value = strdup(ainfo.devnode);
- }
- else
- continue;
- }
-
-FAILED:
- close(mixerfd);
-}
-
-static void combo_cleanup(ComboBoxElements * elements, int n_elements)
-{
- /* first elements were allocated statically */
- for (int i = 1; i < n_elements; i++)
- {
- free(elements[i].value);
- free((char *) elements[i].label);
- }
-
- free(elements);
-}
-
-static PreferencesWidget oss_widgets[] = {
- {WIDGET_COMBO_BOX, N_("Audio device:"),
- .cfg_type = VALUE_STRING, .csect = "oss4", .cname = "device"},
- {WIDGET_CHK_BTN, N_("Use alternate device:"),
- .cfg_type = VALUE_BOOLEAN, .csect = "oss4", .cname = "use_alt_device"},
- {WIDGET_ENTRY,
- .cfg_type = VALUE_STRING, .csect = "oss4", .cname = "alt_device", .child = TRUE},
- {WIDGET_CHK_BTN, N_("Save volume between sessions."),
- .cfg_type = VALUE_BOOLEAN, .csect = "oss4", .cname = "save_volume"},
- {WIDGET_CHK_BTN, N_("Enable format conversions made by the OSS software."),
- .cfg_type = VALUE_BOOLEAN, .csect = "oss4", .cname = "cookedmode"},
- {WIDGET_CHK_BTN, N_("Enable exclusive mode to prevent virtual mixing."),
- .cfg_type = VALUE_BOOLEAN, .csect = "oss4", .cname = "exclusive"},
-};
-
-static void prefs_init()
-{
- combo_init((ComboBoxElements **) &oss_widgets[0].data.combo.elements,
- &oss_widgets[0].data.combo.n_elements);
-}
-
-static void prefs_cleanup()
-{
- combo_cleanup((ComboBoxElements *) oss_widgets[0].data.combo.elements,
- oss_widgets[0].data.combo.n_elements);
-}
-
-static const PluginPreferences oss_prefs = {
- .widgets = oss_widgets,
- .n_widgets = ARRAY_LEN(oss_widgets),
- .init = prefs_init,
- .cleanup = prefs_cleanup};
-
-static const char oss_about[] =
- N_("OSS4 Output Plugin for Audacious\n"
- "Copyright 2010-2012 MichaÅ Lipski\n\n"
- "I would like to thank people on #audacious, especially Tony Vroon and "
- "John Lindgren and of course the authors of the previous OSS plugin.");
-
-AUD_OUTPUT_PLUGIN
-(
- .name = N_("OSS4 Output"),
- .domain = PACKAGE,
- .probe_priority = 5,
- .init = oss_init,
- .cleanup = oss_cleanup,
- .open_audio = oss_open_audio,
- .close_audio = oss_close_audio,
- .write_audio = oss_write_audio,
- .drain = oss_drain,
- .buffer_free = oss_buffer_free,
- .output_time = oss_output_time,
- .flush = oss_flush,
- .pause = oss_pause,
- .set_volume = oss_set_volume,
- .get_volume = oss_get_volume,
- .about_text = oss_about,
- .prefs = &oss_prefs
-)
diff --git a/src/oss4/plugin.cc b/src/oss4/plugin.cc
new file mode 100644
index 000000000000..dd02694fe9b7
--- /dev/null
+++ b/src/oss4/plugin.cc
@@ -0,0 +1,103 @@
+/*
+ * plugin.c
+ * Copyright 2010-2012 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include "oss.h"
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/preferences.h>
+
+EXPORT OSSPlugin aud_plugin_instance;
+
+static Index<ComboItem> oss_elements;
+
+static void combo_init()
+{
+ int mixerfd;
+
+ CHECK_NOISY(mixerfd = open, DEFAULT_MIXER, O_RDWR);
+
+ oss_elements.append(ComboItem(strdup(N_("Default device")), strdup(DEFAULT_DSP)));
+
+#ifdef SNDCTL_SYSINFO
+ oss_sysinfo sysinfo;
+ memset(&sysinfo, 0, sizeof sysinfo);
+ CHECK(ioctl, mixerfd, SNDCTL_SYSINFO, &sysinfo);
+ CHECK_NOISY(oss_probe_for_adev, &sysinfo);
+
+ for (int i = 0; i < sysinfo.numaudios; i++)
+ {
+ oss_audioinfo ainfo;
+ memset(&ainfo, 0, sizeof ainfo);
+ ainfo.dev = i;
+
+ CHECK(ioctl, mixerfd, SNDCTL_AUDIOINFO, &ainfo);
+
+ if (ainfo.caps & PCM_CAP_OUTPUT)
+ oss_elements.append(ComboItem(strdup(ainfo.name), strdup(ainfo.devnode)));
+ }
+#endif
+
+FAILED:
+ close(mixerfd);
+}
+
+ArrayRef<ComboItem> combo_fill()
+{
+ return {oss_elements.begin(), oss_elements.len()};
+}
+
+static void combo_cleanup()
+{
+ for (ComboItem & elem : oss_elements)
+ {
+ free((char *)elem.label);
+ free((char *)elem.str);
+ }
+
+ oss_elements.clear();
+}
+
+const PreferencesWidget OSSPlugin::widgets[] = {
+ WidgetCombo(N_("Audio device:"),
+ WidgetString ("oss4", "device"),
+ {0, combo_fill}),
+ WidgetCheck(N_("Use alternate device:"),
+ WidgetBool ("oss4", "use_alt_device")),
+ WidgetEntry(0, WidgetString ("oss4", "alt_device"),
+ {}, WIDGET_CHILD),
+ WidgetCheck(N_("Save volume between sessions."),
+ WidgetBool ("oss4", "save_volume")),
+ WidgetCheck(N_("Enable format conversions made by the OSS software."),
+ WidgetBool ("oss4", "cookedmode")),
+ WidgetCheck(N_("Enable exclusive mode to prevent virtual mixing."),
+ WidgetBool ("oss4", "exclusive"))
+};
+
+const PluginPreferences OSSPlugin::prefs = {
+ {widgets},
+ combo_init,
+ nullptr, // apply
+ combo_cleanup
+};
+
+const char OSSPlugin::about[] =
+ N_("OSS4 Output Plugin for Audacious\n"
+ "Copyright 2010-2012 MichaÅ Lipski\n\n"
+ "I would like to thank people on #audacious, especially Tony Vroon and "
+ "John Lindgren and of course the authors of the previous OSS plugin.");
diff --git a/src/oss4/utils.c b/src/oss4/utils.c
deleted file mode 100644
index affd321dd8aa..000000000000
--- a/src/oss4/utils.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * utils.c
- * Copyright 2010-2011 MichaÅ Lipski
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include "oss.h"
-
-#include <libaudcore/audstrings.h>
-
-char *oss_format_to_text(int format)
-{
- const struct
- {
- int format;
- char *format_text;
- }
- table[] =
- {
-#ifdef AFMT_FLOAT
- {AFMT_FLOAT, "AFMT_FLOAT"},
-#endif
- {AFMT_S8, "AFMT_S8"},
- {AFMT_U8, "AFMT_U8"},
- {AFMT_S16_LE, "AFMT_S16_LE"},
- {AFMT_S16_BE, "AFMT_S16_BE"},
- {AFMT_U16_LE, "AFMT_U16_LE"},
- {AFMT_U16_BE, "AFMT_U16_BE"},
- {AFMT_S24_LE, "AFMT_S24_LE"},
- {AFMT_S24_BE, "AFMT_S24_BE"},
- {AFMT_S32_LE, "AFMT_S32_LE"},
- {AFMT_S32_BE, "AFMT_S32_BE"},
- };
-
- int count;
-
- for (count = 0; count < ARRAY_LEN(table); count++)
- {
- if (table[count].format == format)
- {
- return table[count].format_text;
- }
- }
-
- return "FMT_UNKNOWN";
-}
-
-int oss_convert_aud_format(int aud_format)
-{
- const struct
- {
- int aud_format;
- int format;
- }
- table[] =
- {
-#ifdef AFMT_FLOAT
- {FMT_FLOAT, AFMT_FLOAT},
-#endif
- {FMT_S8, AFMT_S8},
- {FMT_U8, AFMT_U8},
- {FMT_S16_LE, AFMT_S16_LE},
- {FMT_S16_BE, AFMT_S16_BE},
- {FMT_U16_LE, AFMT_U16_LE},
- {FMT_U16_BE, AFMT_U16_BE},
- {FMT_S24_LE, AFMT_S24_LE},
- {FMT_S24_BE, AFMT_S24_BE},
- {FMT_S32_LE, AFMT_S32_LE},
- {FMT_S32_BE, AFMT_S32_BE},
- };
-
- int count;
-
- for (count = 0; count < ARRAY_LEN(table); count++)
- {
- if (table[count].aud_format == aud_format)
- {
- return table[count].format;
- }
- }
-
- return -1;
-}
-
-int oss_format_to_bits(int format)
-{
- char bits;
-
- switch (format)
- {
- case AFMT_U8:
- case AFMT_S8:
- bits = 8;
- break;
- case AFMT_S16_LE:
- case AFMT_S16_BE:
- case AFMT_U16_LE:
- case AFMT_U16_BE:
- bits = 16;
- break;
- case AFMT_S24_LE:
- case AFMT_S24_BE:
- case AFMT_S32_LE:
- case AFMT_S32_BE:
- bits = 32;
- break;
-#ifdef AFMT_FLOAT
- case AFMT_FLOAT:
- bits = sizeof(float) * 8;
- break;
-#endif
- default:
- bits = 8;
- }
-
- return bits;
-}
-
-int oss_frames_to_bytes(int frames)
-{
- return frames * oss_data->bits_per_sample * oss_data->channels / 8;
-}
-
-int oss_bytes_to_frames(int bytes)
-{
- return bytes * 8 / oss_data->channels / oss_data->bits_per_sample;
-}
-
-int oss_calc_bitrate(void)
-{
- return (oss_data->rate * oss_data->channels * oss_data->bits_per_sample) >> 3;
-}
-
-char *oss_describe_error(void)
-{
- const struct
- {
- int error;
- char *text;
- }
- table[] =
- {
- {EINVAL, "The ioctl call is not supported by current OSS version."},
- {EACCES, "You do not have permissions to access the device."},
- {EBUSY, "The device is busy. There is some other application using it."},
- {ENXIO, "OSS has not detected any supported sound hardware in your system."},
- {ENODEV, "The device file was found in /dev but OSS is not loaded. You need to "
- "load it by executing the soundon command."},
- {ENOSPC, "Your system cannot allocate memory for the device buffers. Reboot your "
- "machine and try again."},
- {ENOENT, "The device file is missing from /dev. Perhaps you have not installed "
- "and started Open Sound System yet."},
- };
-
- int count;
- for (count = 0; count < ARRAY_LEN(table); count++)
- {
- if (table[count].error == errno)
- return table[count].text;
- }
-
- return strerror(errno);
-}
-
-int oss_probe_for_adev(oss_sysinfo *sysinfo)
-{
- int num;
- if ((num = sysinfo->numaudios) < 1)
- {
- errno = ENXIO;
- return -1;
- }
-
- return num;
-}
-
-bool_t oss_hardware_present(void)
-{
- int mixerfd;
- oss_sysinfo sysinfo;
-
- CHECK_NOISY(mixerfd = open, DEFAULT_MIXER, O_RDWR, 0);
- CHECK(ioctl, mixerfd, SNDCTL_SYSINFO, &sysinfo);
- CHECK_NOISY(oss_probe_for_adev, &sysinfo);
-
- close(mixerfd);
- return TRUE;
-
-FAILED:
- close(mixerfd);
- return FALSE;
-}
diff --git a/src/oss4/utils.cc b/src/oss4/utils.cc
new file mode 100644
index 000000000000..22fd78ab7cd5
--- /dev/null
+++ b/src/oss4/utils.cc
@@ -0,0 +1,204 @@
+/*
+ * utils.c
+ * Copyright 2010-2011 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include "oss.h"
+
+#include <libaudcore/audstrings.h>
+
+const char *oss_format_to_text(int format)
+{
+ static const struct
+ {
+ int format;
+ const char *format_text;
+ }
+ table[] =
+ {
+#ifdef AFMT_FLOAT
+ {AFMT_FLOAT, "AFMT_FLOAT"},
+#endif
+ {AFMT_S8, "AFMT_S8"},
+ {AFMT_U8, "AFMT_U8"},
+ {AFMT_S16_LE, "AFMT_S16_LE"},
+ {AFMT_S16_BE, "AFMT_S16_BE"},
+ {AFMT_U16_LE, "AFMT_U16_LE"},
+ {AFMT_U16_BE, "AFMT_U16_BE"},
+#ifdef AFMT_S24_LE
+ {AFMT_S24_LE, "AFMT_S24_LE"},
+ {AFMT_S24_BE, "AFMT_S24_BE"},
+#endif
+#ifdef AFMT_S32_LE
+ {AFMT_S32_LE, "AFMT_S32_LE"},
+ {AFMT_S32_BE, "AFMT_S32_BE"},
+#endif
+ };
+
+ for (auto & conv : table)
+ {
+ if (conv.format == format)
+ return conv.format_text;
+ }
+
+ return "FMT_UNKNOWN";
+}
+
+int oss_convert_aud_format(int aud_format)
+{
+ const struct
+ {
+ int aud_format;
+ int format;
+ }
+ table[] =
+ {
+#ifdef AFMT_FLOAT
+ {FMT_FLOAT, AFMT_FLOAT},
+#endif
+ {FMT_S8, AFMT_S8},
+ {FMT_U8, AFMT_U8},
+ {FMT_S16_LE, AFMT_S16_LE},
+ {FMT_S16_BE, AFMT_S16_BE},
+ {FMT_U16_LE, AFMT_U16_LE},
+ {FMT_U16_BE, AFMT_U16_BE},
+#ifdef AFMT_S24_LE
+ {FMT_S24_LE, AFMT_S24_LE},
+ {FMT_S24_BE, AFMT_S24_BE},
+#endif
+#ifdef AFMT_S32_LE
+ {FMT_S32_LE, AFMT_S32_LE},
+ {FMT_S32_BE, AFMT_S32_BE},
+#endif
+ };
+
+ int count;
+
+ for (count = 0; count < aud::n_elems(table); count++)
+ {
+ if (table[count].aud_format == aud_format)
+ {
+ return table[count].format;
+ }
+ }
+
+ return -1;
+}
+
+int oss_format_to_bytes(int format)
+{
+ int bytes = 1;
+
+ switch (format)
+ {
+ case AFMT_U8:
+ case AFMT_S8:
+ bytes = 1;
+ break;
+ case AFMT_S16_LE:
+ case AFMT_S16_BE:
+ case AFMT_U16_LE:
+ case AFMT_U16_BE:
+ bytes = 2;
+ break;
+#ifdef AFMT_S24_LE
+ case AFMT_S24_LE:
+ case AFMT_S24_BE:
+ bytes = 4;
+ break;
+#endif
+#ifdef AFMT_S32_LE
+ case AFMT_S32_LE:
+ case AFMT_S32_BE:
+ bytes = 4;
+ break;
+#endif
+#ifdef AFMT_FLOAT
+ case AFMT_FLOAT:
+ bytes = sizeof(float);
+ break;
+#endif
+ }
+
+ return bytes;
+}
+
+const char *oss_describe_error()
+{
+ const struct
+ {
+ int error;
+ const char *text;
+ }
+ table[] =
+ {
+ {EINVAL, "The ioctl call is not supported by current OSS version."},
+ {EACCES, "You do not have permissions to access the device."},
+ {EBUSY, "The device is busy. There is some other application using it."},
+ {ENXIO, "OSS has not detected any supported sound hardware in your system."},
+ {ENODEV, "The device file was found in /dev but OSS is not loaded. You need to "
+ "load it by executing the soundon command."},
+ {ENOSPC, "Your system cannot allocate memory for the device buffers. Reboot your "
+ "machine and try again."},
+ {ENOENT, "The device file is missing from /dev. Perhaps you have not installed "
+ "and started Open Sound System yet."},
+ };
+
+ int count;
+ for (count = 0; count < aud::n_elems(table); count++)
+ {
+ if (table[count].error == errno)
+ return table[count].text;
+ }
+
+ return strerror(errno);
+}
+
+#ifdef SNDCTL_SYSINFO
+int oss_probe_for_adev(oss_sysinfo *sysinfo)
+{
+ int num;
+ if ((num = sysinfo->numaudios) < 1)
+ {
+ errno = ENXIO;
+ return -1;
+ }
+
+ return num;
+}
+#endif
+
+bool oss_hardware_present()
+{
+ int mixerfd;
+
+ CHECK_NOISY(mixerfd = open, DEFAULT_MIXER, O_RDWR, 0);
+
+#ifdef SNDCTL_SYSINFO
+ oss_sysinfo sysinfo;
+ memset(&sysinfo, 0, sizeof sysinfo);
+ CHECK(ioctl, mixerfd, SNDCTL_SYSINFO, &sysinfo);
+ CHECK_NOISY(oss_probe_for_adev, &sysinfo);
+#endif
+
+ close(mixerfd);
+ return true;
+
+FAILED:
+ close(mixerfd);
+ return false;
+}
diff --git a/src/playlist-manager/Makefile b/src/playlist-manager/Makefile
new file mode 100644
index 000000000000..2be43667c9bb
--- /dev/null
+++ b/src/playlist-manager/Makefile
@@ -0,0 +1,13 @@
+PLUGIN = playlist-manager${PLUGIN_SUFFIX}
+
+SRCS = playlist-manager.cc
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+
+LD = ${CXX}
+CPPFLAGS += -I../.. ${GTK_CFLAGS}
+CFLAGS += ${PLUGIN_CFLAGS}
+LIBS += ${GTK_LIBS} -laudgui
diff --git a/src/playlist-manager/playlist-manager.cc b/src/playlist-manager/playlist-manager.cc
new file mode 100644
index 000000000000..a006aacd6d23
--- /dev/null
+++ b/src/playlist-manager/playlist-manager.cc
@@ -0,0 +1,271 @@
+/*
+ * Playlist Manager Plugin for Audacious
+ * Copyright 2006-2014 Giacomo Lozito, John Lindgren, and Thomas Lange
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+#include <libaudgui/libaudgui.h>
+#include <libaudgui/libaudgui-gtk.h>
+#include <libaudgui/list.h>
+
+#include <string.h>
+
+class PlaylistManager : public GeneralPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("Playlist Manager"),
+ PACKAGE
+ };
+
+ constexpr PlaylistManager () : GeneralPlugin (info, false) {}
+
+ void * get_gtk_widget ();
+ int take_message (const char * code, const void * data, int size);
+};
+
+EXPORT PlaylistManager aud_plugin_instance;
+
+static GtkWidget * focus_widget;
+
+static void activate_row (void * user, int row);
+
+static void rename_cb (void * unused)
+{
+ audgui_show_playlist_rename (aud_playlist_get_active ());
+}
+
+static void new_cb (void * unused)
+{
+ aud_playlist_insert (aud_playlist_get_active () + 1);
+ aud_playlist_set_active (aud_playlist_get_active () + 1);
+}
+
+static void delete_cb (void * unused)
+{
+ audgui_confirm_playlist_delete (aud_playlist_get_active ());
+}
+
+static void get_value (void * user, int row, int column, GValue * value)
+{
+ switch (column)
+ {
+ case 0:
+ {
+ g_value_set_string (value, aud_playlist_get_title (row));
+ break;
+ }
+ case 1:
+ g_value_set_int (value, aud_playlist_entry_count (row));
+ break;
+ }
+}
+
+static bool get_selected (void * user, int row)
+{
+ return (row == aud_playlist_get_active ());
+}
+
+static void set_selected (void * user, int row, bool selected)
+{
+ if (selected)
+ aud_playlist_set_active (row);
+}
+
+static void select_all (void * user, bool selected)
+{
+}
+
+static void activate_row (void * user, int row)
+{
+ aud_playlist_set_active (row);
+ aud_playlist_play (row);
+}
+
+static void shift_rows (void * user, int row, int before)
+{
+ if (before < row)
+ aud_playlist_reorder (row, before, 1);
+ else if (before - 1 > row)
+ aud_playlist_reorder (row, before - 1, 1);
+}
+
+static const AudguiListCallbacks callbacks = {
+ get_value,
+ get_selected,
+ set_selected,
+ select_all,
+ activate_row,
+ nullptr, // right_click
+ shift_rows
+};
+
+static gboolean search_cb (GtkTreeModel * model, int column, const char * key,
+ GtkTreeIter * iter, void * user)
+{
+ GtkTreePath * path = gtk_tree_model_get_path (model, iter);
+ g_return_val_if_fail (path, true);
+ int row = gtk_tree_path_get_indices (path)[0];
+ gtk_tree_path_free (path);
+
+ String title = aud_playlist_get_title (row);
+ g_return_val_if_fail (title, true);
+
+ Index<String> keys = str_list_to_index (key, " ");
+
+ if (! keys.len ())
+ return true; /* not matched */
+
+ for (const String & key : keys)
+ {
+ if (! strstr_nocase_utf8 (title, key))
+ return true; /* not matched */
+ }
+
+ return false; /* matched */
+}
+
+static gboolean position_changed = false;
+static gboolean playlist_activated = false;
+
+static void update_hook (void * data, void * list_)
+{
+ auto level = aud::from_ptr<Playlist::UpdateLevel> (data);
+ GtkWidget * list = (GtkWidget *) list_;
+ int rows = aud_playlist_count ();
+
+ if (level == Playlist::Structure)
+ {
+ int old_rows = audgui_list_row_count (list);
+
+ if (rows < old_rows)
+ audgui_list_delete_rows (list, rows, old_rows - rows);
+ else if (rows > old_rows)
+ audgui_list_insert_rows (list, old_rows, rows - old_rows);
+
+ position_changed = true;
+ playlist_activated = true;
+ }
+
+ if (level >= Playlist::Metadata)
+ audgui_list_update_rows (list, 0, rows);
+
+ if (playlist_activated)
+ {
+ audgui_list_set_focus (list, aud_playlist_get_active ());
+ audgui_list_update_selection (list, 0, rows);
+ playlist_activated = false;
+ }
+
+ if (position_changed)
+ {
+ audgui_list_set_highlight (list, aud_playlist_get_playing ());
+ position_changed = false;
+ }
+}
+
+static void activate_hook (void * data, void * list_)
+{
+ GtkWidget * list = (GtkWidget *) list_;
+
+ if (aud_playlist_update_pending ())
+ playlist_activated = true;
+ else
+ {
+ audgui_list_set_focus (list, aud_playlist_get_active ());
+ audgui_list_update_selection (list, 0, aud_playlist_count ());
+ }
+}
+
+static void position_hook (void * data, void * list_)
+{
+ GtkWidget * list = (GtkWidget *) list_;
+
+ if (aud_playlist_update_pending ())
+ position_changed = true;
+ else
+ audgui_list_set_highlight (list, aud_playlist_get_playing ());
+}
+
+static void destroy_cb (GtkWidget * window)
+{
+ hook_dissociate ("playlist update", update_hook);
+ hook_dissociate ("playlist activate", activate_hook);
+ hook_dissociate ("playlist set playing", position_hook);
+
+ focus_widget = nullptr;
+}
+
+void * PlaylistManager::get_gtk_widget ()
+{
+ GtkWidget * playman_vbox = gtk_vbox_new (false, 6);
+
+ /* ListView */
+ GtkWidget * playman_pl_lv = audgui_list_new (& callbacks, nullptr, aud_playlist_count ());
+ audgui_list_add_column (playman_pl_lv, _("Title"), 0, G_TYPE_STRING, -1);
+ audgui_list_add_column (playman_pl_lv, _("Entries"), 1, G_TYPE_INT, 7);
+ audgui_list_set_highlight (playman_pl_lv, aud_playlist_get_playing ());
+ gtk_tree_view_set_search_equal_func ((GtkTreeView *) playman_pl_lv,
+ search_cb, nullptr, nullptr);
+ hook_associate ("playlist update", update_hook, playman_pl_lv);
+ hook_associate ("playlist activate", activate_hook, playman_pl_lv);
+ hook_associate ("playlist set playing", position_hook, playman_pl_lv);
+
+ GtkWidget * playman_pl_lv_sw = gtk_scrolled_window_new (nullptr, nullptr);
+ gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) playman_pl_lv_sw,
+ GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy ((GtkScrolledWindow *) playman_pl_lv_sw,
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add ((GtkContainer *) playman_pl_lv_sw, playman_pl_lv);
+ gtk_box_pack_start ((GtkBox *) playman_vbox, playman_pl_lv_sw, true, true, 0);
+
+ /* ButtonBox */
+ GtkWidget * playman_button_hbox = gtk_hbox_new (false, 6);
+ GtkWidget * new_button = audgui_button_new (_("_New"), "document-new", new_cb, nullptr);
+ GtkWidget * delete_button = audgui_button_new (_("_Remove"), "edit-delete", delete_cb, nullptr);
+ GtkWidget * rename_button = audgui_button_new (_("Ren_ame"), "insert-text", rename_cb, nullptr);
+
+ gtk_box_pack_start ((GtkBox *) playman_button_hbox, new_button, false, false, 0);
+ gtk_box_pack_start ((GtkBox *) playman_button_hbox, delete_button, false, false, 0);
+ gtk_box_pack_end ((GtkBox *) playman_button_hbox, rename_button, false, false, 0);
+ gtk_box_pack_start ((GtkBox *) playman_vbox, playman_button_hbox, false, false, 0);
+
+ focus_widget = playman_pl_lv;
+
+ g_signal_connect (playman_vbox, "destroy", (GCallback) destroy_cb, nullptr);
+
+ return playman_vbox;
+}
+
+int PlaylistManager::take_message (const char * code, const void * data, int size)
+{
+ if (! strcmp (code, "grab focus"))
+ {
+ if (focus_widget)
+ gtk_widget_grab_focus (focus_widget);
+
+ return 0;
+ }
+
+ return -1;
+}
diff --git a/src/pls/Makefile b/src/pls/Makefile
index 420a9acffbac..5dc3e6955a87 100644
--- a/src/pls/Makefile
+++ b/src/pls/Makefile
@@ -1,11 +1,11 @@
PLUGIN = pls${PLUGIN_SUFFIX}
-SRCS = pls.c
+SRCS = pls.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${CONTAINER_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
diff --git a/src/pls/pls.c b/src/pls/pls.c
deleted file mode 100644
index 2cf7ed44ede8..000000000000
--- a/src/pls/pls.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Audacious: A cross-platform multimedia player
- * Copyright (c) 2006 William Pitcock, Tony Vroon, George Averill,
- * Giacomo Lozito, Derek Pomery and Yoshiki Yazawa.
- * Copyright (c) 2011-2013 John Lindgren
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/inifile.h>
-
-typedef struct {
- const char * filename;
- bool_t valid_heading;
- Index * filenames;
-} PLSLoadState;
-
-void pls_handle_heading (const char * heading, void * data)
-{
- PLSLoadState * state = data;
-
- state->valid_heading = ! g_ascii_strcasecmp (heading, "playlist");
-}
-
-void pls_handle_entry (const char * key, const char * value, void * data)
-{
- PLSLoadState * state = data;
-
- if (! state->valid_heading || g_ascii_strncasecmp (key, "file", 4))
- return;
-
- char * uri = aud_construct_uri (value, state->filename);
- if (uri)
- index_insert (state->filenames, -1, uri);
-}
-
-static bool_t playlist_load_pls (const char * filename, VFSFile * file,
- char * * title, Index * filenames, Index * tuples)
-{
- PLSLoadState state = {
- .filename = filename,
- .valid_heading = FALSE,
- .filenames = filenames
- };
-
- inifile_parse (file, pls_handle_heading, pls_handle_entry, & state);
-
- return (index_count (filenames) != 0);
-}
-
-static bool_t playlist_save_pls (const char * filename, VFSFile * file,
- const char * title, Index * filenames, Index * tuples)
-{
- int entries = index_count (filenames);
-
- vfs_fprintf (file, "[playlist]\n");
- vfs_fprintf (file, "NumberOfEntries=%d\n", entries);
-
- for (int count = 0; count < entries; count ++)
- {
- const char * filename = index_get (filenames, count);
- char * fn;
-
- if (! strncmp (filename, "file://", 7))
- fn = uri_to_filename (filename);
- else
- fn = str_ref (filename);
-
- vfs_fprintf (file, "File%d=%s\n", 1 + count, fn);
- str_unref (fn);
- }
-
- return TRUE;
-}
-
-static const char * const pls_exts[] = {"pls", NULL};
-
-AUD_PLAYLIST_PLUGIN
-(
- .name = N_("PLS Playlists"),
- .domain = PACKAGE,
- .extensions = pls_exts,
- .load = playlist_load_pls,
- .save = playlist_save_pls
-)
diff --git a/src/pls/pls.cc b/src/pls/pls.cc
new file mode 100644
index 000000000000..409545384cfd
--- /dev/null
+++ b/src/pls/pls.cc
@@ -0,0 +1,100 @@
+/*
+ * Audacious: A cross-platform multimedia player
+ * Copyright (c) 2006 William Pitcock, Tony Vroon, George Averill,
+ * Giacomo Lozito, Derek Pomery and Yoshiki Yazawa.
+ * Copyright (c) 2011-2013 John Lindgren
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/inifile.h>
+
+static const char * const pls_exts[] = {"pls"};
+
+class PLSLoader : public PlaylistPlugin
+{
+public:
+ static constexpr PluginInfo info = {N_("PLS Playlists"), PACKAGE};
+
+ constexpr PLSLoader () : PlaylistPlugin (info, pls_exts, true) {}
+
+ bool load (const char * filename, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items);
+ bool save (const char * filename, VFSFile & file, const char * title,
+ const Index<PlaylistAddItem> & items);
+};
+
+EXPORT PLSLoader aud_plugin_instance;
+
+class PLSParser : public IniParser
+{
+public:
+ PLSParser (const char * filename, Index<PlaylistAddItem> & items) :
+ filename (filename),
+ items (items),
+ valid_heading (false) {}
+
+private:
+ const char * filename;
+ Index<PlaylistAddItem> & items;
+ bool valid_heading;
+
+ void handle_heading (const char * heading)
+ { valid_heading = ! strcmp_nocase (heading, "playlist"); }
+
+ void handle_entry (const char * key, const char * value)
+ {
+ if (! valid_heading || strcmp_nocase (key, "file", 4))
+ return;
+
+ StringBuf uri = uri_construct (value, filename);
+ if (uri)
+ items.append (String (uri));
+ }
+};
+
+bool PLSLoader::load (const char * filename, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items)
+{
+ PLSParser (filename, items).parse (file);
+ return (items.len () > 0);
+}
+
+bool PLSLoader::save (const char * filename, VFSFile & file, const char * title,
+ const Index<PlaylistAddItem> & items)
+{
+ int entries = items.len ();
+
+ StringBuf header = str_printf ("[playlist]\nNumberOfEntries=%d\n", entries);
+ if (file.fwrite (header, 1, header.len ()) != header.len ())
+ return false;
+
+ for (int count = 0; count < entries; count ++)
+ {
+ const char * uri = items[count].filename;
+ StringBuf local = uri_to_filename (uri);
+ StringBuf line = str_printf ("File%d=%s\n", 1 + count, local ? local : uri);
+ if (file.fwrite (line, 1, line.len ()) != line.len ())
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/psf/Makefile b/src/psf/Makefile
index 4984a7667d48..0c93a1202917 100644
--- a/src/psf/Makefile
+++ b/src/psf/Makefile
@@ -1,22 +1,24 @@
PLUGIN = psf2${PLUGIN_SUFFIX}
-SRCS = corlett.c \
- plugin.c \
- psx.c \
- psx_hw.c \
- eng_psf.c \
- eng_psf2.c \
- eng_spx.c \
- peops/spu.c \
- peops2/dma.c \
- peops2/registers.c \
- peops2/spu.c \
+SRCS = corlett.cc \
+ plugin.cc \
+ psx.cc \
+ psx_hw.cc \
+ eng_psf.cc \
+ eng_psf2.cc \
+ eng_spx.cc \
+ peops/spu.cc \
+ peops2/dma.cc \
+ peops2/registers.cc \
+ peops2/spu.cc \
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
-CFLAGS += ${PLUGIN_CFLAGS} -O0
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../.. -Ispu/ -I.
-LIBS += -lz ${GLIB_LIBS}
+LD = ${CXX}
+
+CXXFLAGS += ${PLUGIN_CFLAGS} -Wno-sign-compare
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../.. -Ispu/ -I.
+LIBS += -lz
diff --git a/src/psf/ao.h b/src/psf/ao.h
index 377c784e2ee8..3b89b5173b50 100644
--- a/src/psf/ao.h
+++ b/src/psf/ao.h
@@ -9,6 +9,10 @@
#include <stdint.h>
+#define WANT_AUD_BSWAP
+#include <libaudcore/audio.h>
+#include <libaudcore/index.h>
+
#define AO_SUCCESS 1
#define AO_FAIL 0
#define AO_FAIL_DECOMPRESSION -1
@@ -16,14 +20,6 @@
#define MAX_DISP_INFO_LENGTH 256
#define AUDIO_RATE (44100)
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
enum
{
COMMAND_NONE = 0,
@@ -37,6 +33,6 @@ enum
COMMAND_JUMP
};
-int ao_get_lib(char *filename, uint8_t **buffer, uint64_t *length);
+Index<char> ao_get_lib(char *filename);
#endif // AO_H
diff --git a/src/psf/corlett.c b/src/psf/corlett.c
deleted file mode 100644
index eaac91d415e6..000000000000
--- a/src/psf/corlett.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Audio Overload SDK - generic PSF loader
- *
- * Copyright (c) 2007 R. Belmont and Richard Bannister.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the names of R. Belmont and Richard Bannister nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// corlett.c
-
-// Decodes file format designed by Neill Corlett (PSF, QSF, ...)
-
-/*
- - First 3 bytes: ASCII signature: "PSF" (case sensitive)
-
-- Next 1 byte: Version byte
- The version byte is used to determine the type of PSF file. It does NOT
- affect the basic structure of the file in any way.
-
- Currently accepted version bytes are:
- 0x01: Playstation (PSF1)
- 0x02: Playstation 2 (PSF2)
- 0x11: Saturn (SSF) [TENTATIVE]
- 0x12: Dreamcast (DSF) [TENTATIVE]
- 0x21: Nintendo 64 (USF) [RESERVED]
- 0x41: Capcom QSound (QSF)
-
-- Next 4 bytes: Size of reserved area (R), little-endian unsigned long
-
-- Next 4 bytes: Compressed program length (N), little-endian unsigned long
- This is the length of the program data _after_ compression.
-
-- Next 4 bytes: Compressed program CRC-32, little-endian unsigned long
- This is the CRC-32 of the program data _after_ compression. Filling in
- this value is mandatory, as a PSF file may be regarded as corrupt if it
- does not match.
-
-- Next R bytes: Reserved area.
- May be empty if R is 0 bytes.
-
-- Next N bytes: Compressed program, in zlib compress() format.
- May be empty if N is 0 bytes.
-
-The following data is optional and may be omitted:
-
-- Next 5 bytes: ASCII signature: "[TAG]" (case sensitive)
- If these 5 bytes do not match, then the remainder of the file may be
- regarded as invalid and discarded.
-
-- Remainder of file: Uncompressed ASCII tag data.
-*/
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-#include <zlib.h>
-
-#include "ao.h"
-#include "corlett.h"
-
-#define LE32(x) GUINT32_FROM_LE(x)
-
-#define DECOMP_MAX_SIZE ((32 * 1024 * 1024) + 12)
-
-int corlett_decode(uint8_t *input, uint32_t input_len, uint8_t **output, uint64_t *size, corlett_t **c)
-{
- uint32_t *buf;
- uint32_t res_area, comp_crc, actual_crc;
- uint8_t *decomp_dat, *tag_dec;
- uLongf decomp_length, comp_length;
-
- // 32-bit pointer to data
- buf = (uint32_t *)input;
-
- // Check we have a PSF format file.
- if ((input[0] != 'P') || (input[1] != 'S') || (input[2] != 'F'))
- {
- return AO_FAIL;
- }
-
- // Get our values
- res_area = LE32(buf[1]);
- comp_length = LE32(buf[2]);
- comp_crc = LE32(buf[3]);
-
- if (comp_length > 0)
- {
- // Check length
- if (input_len < comp_length + 16)
- return AO_FAIL;
-
- // Check CRC is correct
- actual_crc = crc32(0, (unsigned char *)&buf[4+(res_area/4)], comp_length);
- if (actual_crc != comp_crc)
- return AO_FAIL;
-
- // Decompress data if any
- decomp_dat = malloc(DECOMP_MAX_SIZE);
- decomp_length = DECOMP_MAX_SIZE;
- if (uncompress(decomp_dat, &decomp_length, (unsigned char *)&buf[4+(res_area/4)], comp_length) != Z_OK)
- {
- free(decomp_dat);
- return AO_FAIL;
- }
-
- // Resize memory buffer to what we actually need
- decomp_dat = realloc(decomp_dat, (size_t)decomp_length + 1);
- }
- else
- {
- decomp_dat = NULL;
- decomp_length = 0;
- }
-
- // Make structure
- *c = malloc(sizeof(corlett_t));
- if (!(*c))
- {
- free(decomp_dat);
- return AO_FAIL;
- }
- memset(*c, 0, sizeof(corlett_t));
- strcpy((*c)->inf_title, "n/a");
- strcpy((*c)->inf_copy, "n/a");
- strcpy((*c)->inf_artist, "n/a");
- strcpy((*c)->inf_game, "n/a");
- strcpy((*c)->inf_year, "n/a");
- strcpy((*c)->inf_length, "n/a");
- strcpy((*c)->inf_fade, "n/a");
-
- // set reserved section pointer
- (*c)->res_section = &buf[4];
- (*c)->res_size = res_area;
-
- // Return it
- if (output != NULL && size != NULL)
- {
- *output = decomp_dat;
- *size = decomp_length;
- }
- else
- free(decomp_dat);
-
- // Next check for tags
- input_len -= (comp_length + 16 + res_area);
- if (input_len < 5)
- return AO_SUCCESS;
-
-// printf("\n\nNew corlett: input len %d\n", input_len);
-
- tag_dec = input + (comp_length + res_area + 16);
- if ((tag_dec[0] == '[') && (tag_dec[1] == 'T') && (tag_dec[2] == 'A') && (tag_dec[3] == 'G') && (tag_dec[4] == ']'))
- {
- int l, num_tags, data;
-
- // Tags found!
- tag_dec += 5;
- input_len -= 5;
-
- data = FALSE;
- num_tags = 0;
- l = 0;
- while (input_len && (num_tags < MAX_UNKNOWN_TAGS))
- {
- if (data)
- {
- if ((*tag_dec == 0xA) || (*tag_dec == 0x00))
- {
- (*c)->tag_data[num_tags][l] = 0;
- data = FALSE;
- num_tags++;
- l = 0;
- }
- else
- {
- (*c)->tag_data[num_tags][l++] = *tag_dec;
- }
- }
- else
- {
- if (*tag_dec == '=')
- {
- (*c)->tag_name[num_tags][l] = 0;
- l = 0;
- data = TRUE;
- }
- else
- {
- (*c)->tag_name[num_tags][l++] = *tag_dec;
- }
- }
-
- tag_dec++;
- input_len--;
- }
-
-
- // Now, process that tag array into what we expect
- for (num_tags = 0; num_tags < MAX_UNKNOWN_TAGS; num_tags++)
- {
- // See if tag belongs in one of the special fields we have
- if (!g_ascii_strcasecmp((*c)->tag_name[num_tags], "_lib"))
- {
- strcpy((*c)->lib, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib2", 5))
- {
- strcpy((*c)->libaux[0], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib3", 5))
- {
- strcpy((*c)->libaux[1], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib4", 5))
- {
- strcpy((*c)->libaux[2], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib5", 5))
- {
- strcpy((*c)->libaux[3], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib6", 5))
- {
- strcpy((*c)->libaux[4], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib7", 5))
- {
- strcpy((*c)->libaux[5], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib8", 5))
- {
- strcpy((*c)->libaux[6], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib9", 5))
- {
- strcpy((*c)->libaux[7], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_refresh", 8))
- {
- strcpy((*c)->inf_refresh, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "title", 5))
- {
- strcpy((*c)->inf_title, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "copyright", 9))
- {
- strcpy((*c)->inf_copy, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "artist", 6))
- {
- strcpy((*c)->inf_artist, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "game", 4))
- {
- strcpy((*c)->inf_game, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "year", 4))
- {
- strcpy((*c)->inf_year, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "length", 6))
- {
- strcpy((*c)->inf_length, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "fade", 4))
- {
- strcpy((*c)->inf_fade, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- }
- }
-
- // Bingo
- return AO_SUCCESS;
-}
-
-uint32_t psfTimeToMS(char *str)
-{
- int x, c=0;
- uint32_t acc=0;
- char s[100];
-
- strncpy(s,str,100);
- s[99]=0;
-
- for (x=strlen(s); x>=0; x--)
- {
- if (s[x]=='.' || s[x]==',')
- {
- acc=atoi(s+x+1);
- s[x]=0;
- }
- else if (s[x]==':')
- {
- if(c==0)
- {
- acc+=atoi(s+x+1)*10;
- }
- else if(c==1)
- {
- acc+=atoi(s+x+(x?1:0))*10*60;
- }
-
- c++;
- s[x]=0;
- }
- else if (x==0)
- {
- if(c==0)
- {
- acc+=atoi(s+x)*10;
- }
- else if(c==1)
- {
- acc+=atoi(s+x)*10*60;
- }
- else if(c==2)
- {
- acc+=atoi(s+x)*10*60*60;
- }
- }
- }
-
- acc*=100;
- return(acc);
-}
-
diff --git a/src/psf/corlett.cc b/src/psf/corlett.cc
new file mode 100644
index 000000000000..4089c901a938
--- /dev/null
+++ b/src/psf/corlett.cc
@@ -0,0 +1,390 @@
+/*
+ * Audio Overload SDK - generic PSF loader
+ *
+ * Copyright (c) 2007 R. Belmont and Richard Bannister.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the names of R. Belmont and Richard Bannister nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// corlett.c
+
+// Decodes file format designed by Neill Corlett (PSF, QSF, ...)
+
+/*
+ - First 3 bytes: ASCII signature: "PSF" (case sensitive)
+
+- Next 1 byte: Version byte
+ The version byte is used to determine the type of PSF file. It does NOT
+ affect the basic structure of the file in any way.
+
+ Currently accepted version bytes are:
+ 0x01: Playstation (PSF1)
+ 0x02: Playstation 2 (PSF2)
+ 0x11: Saturn (SSF) [TENTATIVE]
+ 0x12: Dreamcast (DSF) [TENTATIVE]
+ 0x21: Nintendo 64 (USF) [RESERVED]
+ 0x41: Capcom QSound (QSF)
+
+- Next 4 bytes: Size of reserved area (R), little-endian unsigned long
+
+- Next 4 bytes: Compressed program length (N), little-endian unsigned long
+ This is the length of the program data _after_ compression.
+
+- Next 4 bytes: Compressed program CRC-32, little-endian unsigned long
+ This is the CRC-32 of the program data _after_ compression. Filling in
+ this value is mandatory, as a PSF file may be regarded as corrupt if it
+ does not match.
+
+- Next R bytes: Reserved area.
+ May be empty if R is 0 bytes.
+
+- Next N bytes: Compressed program, in zlib compress() format.
+ May be empty if N is 0 bytes.
+
+The following data is optional and may be omitted:
+
+- Next 5 bytes: ASCII signature: "[TAG]" (case sensitive)
+ If these 5 bytes do not match, then the remainder of the file may be
+ regarded as invalid and discarded.
+
+- Remainder of file: Uncompressed ASCII tag data.
+*/
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <zlib.h>
+
+#include <libaudcore/audstrings.h>
+
+#include "ao.h"
+#include "corlett.h"
+
+#define LE32(x) FROM_LE32(x)
+
+#define DECOMP_MAX_SIZE ((32 * 1024 * 1024) + 12)
+
+int corlett_decode(uint8_t *input, uint32_t input_len, uint8_t **output, uint64_t *size, corlett_t **c)
+{
+ uint32_t *buf;
+ uint32_t res_area, comp_crc, actual_crc;
+ uint8_t *decomp_dat, *tag_dec;
+ uLongf decomp_length, comp_length;
+
+ // 32-bit pointer to data
+ buf = (uint32_t *)input;
+
+ // Check we have a PSF format file.
+ if ((input[0] != 'P') || (input[1] != 'S') || (input[2] != 'F'))
+ {
+ return AO_FAIL;
+ }
+
+ // Get our values
+ res_area = LE32(buf[1]);
+ comp_length = LE32(buf[2]);
+ comp_crc = LE32(buf[3]);
+
+ if (comp_length > 0)
+ {
+ // Check length
+ if (input_len < comp_length + 16)
+ return AO_FAIL;
+
+ // Check CRC is correct
+ actual_crc = crc32(0, (unsigned char *)&buf[4+(res_area/4)], comp_length);
+ if (actual_crc != comp_crc)
+ return AO_FAIL;
+
+ // Decompress data if any
+ decomp_dat = (uint8_t *) malloc(DECOMP_MAX_SIZE);
+ decomp_length = DECOMP_MAX_SIZE;
+ if (uncompress(decomp_dat, &decomp_length, (unsigned char *)&buf[4+(res_area/4)], comp_length) != Z_OK)
+ {
+ free(decomp_dat);
+ return AO_FAIL;
+ }
+
+ // Resize memory buffer to what we actually need
+ decomp_dat = (uint8_t *) realloc(decomp_dat, (size_t)decomp_length + 1);
+ }
+ else
+ {
+ decomp_dat = nullptr;
+ decomp_length = 0;
+ }
+
+ // Make structure
+ *c = (corlett_t *) malloc(sizeof(corlett_t));
+ if (!(*c))
+ {
+ free(decomp_dat);
+ return AO_FAIL;
+ }
+ memset(*c, 0, sizeof(corlett_t));
+ strcpy((*c)->inf_title, "n/a");
+ strcpy((*c)->inf_copy, "n/a");
+ strcpy((*c)->inf_artist, "n/a");
+ strcpy((*c)->inf_game, "n/a");
+ strcpy((*c)->inf_year, "n/a");
+ strcpy((*c)->inf_length, "n/a");
+ strcpy((*c)->inf_fade, "n/a");
+
+ // set reserved section pointer
+ (*c)->res_section = &buf[4];
+ (*c)->res_size = res_area;
+
+ // Return it
+ if (output != nullptr && size != nullptr)
+ {
+ *output = decomp_dat;
+ *size = decomp_length;
+ }
+ else
+ free(decomp_dat);
+
+ // Next check for tags
+ input_len -= (comp_length + 16 + res_area);
+ if (input_len < 5)
+ return AO_SUCCESS;
+
+// printf("\n\nNew corlett: input len %d\n", input_len);
+
+ tag_dec = input + (comp_length + res_area + 16);
+ if ((tag_dec[0] == '[') && (tag_dec[1] == 'T') && (tag_dec[2] == 'A') && (tag_dec[3] == 'G') && (tag_dec[4] == ']'))
+ {
+ int l, num_tags, data;
+
+ // Tags found!
+ tag_dec += 5;
+ input_len -= 5;
+
+ data = false;
+ num_tags = 0;
+ l = 0;
+ while (input_len && (num_tags < MAX_UNKNOWN_TAGS))
+ {
+ if (data)
+ {
+ if ((*tag_dec == 0xA) || (*tag_dec == 0x00))
+ {
+ (*c)->tag_data[num_tags][l] = 0;
+ data = false;
+ num_tags++;
+ l = 0;
+ }
+ else
+ {
+ (*c)->tag_data[num_tags][l++] = *tag_dec;
+ }
+ }
+ else
+ {
+ if (*tag_dec == '=')
+ {
+ (*c)->tag_name[num_tags][l] = 0;
+ l = 0;
+ data = true;
+ }
+ else
+ {
+ (*c)->tag_name[num_tags][l++] = *tag_dec;
+ }
+ }
+
+ tag_dec++;
+ input_len--;
+ }
+
+
+ // Now, process that tag array into what we expect
+ for (num_tags = 0; num_tags < MAX_UNKNOWN_TAGS; num_tags++)
+ {
+ // See if tag belongs in one of the special fields we have
+ if (!strcmp_nocase((*c)->tag_name[num_tags], "_lib"))
+ {
+ strcpy((*c)->lib, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib2", 5))
+ {
+ strcpy((*c)->libaux[0], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib3", 5))
+ {
+ strcpy((*c)->libaux[1], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib4", 5))
+ {
+ strcpy((*c)->libaux[2], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib5", 5))
+ {
+ strcpy((*c)->libaux[3], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib6", 5))
+ {
+ strcpy((*c)->libaux[4], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib7", 5))
+ {
+ strcpy((*c)->libaux[5], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib8", 5))
+ {
+ strcpy((*c)->libaux[6], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib9", 5))
+ {
+ strcpy((*c)->libaux[7], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_refresh", 8))
+ {
+ strcpy((*c)->inf_refresh, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "title", 5))
+ {
+ strcpy((*c)->inf_title, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "copyright", 9))
+ {
+ strcpy((*c)->inf_copy, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "artist", 6))
+ {
+ strcpy((*c)->inf_artist, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "game", 4))
+ {
+ strcpy((*c)->inf_game, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "year", 4))
+ {
+ strcpy((*c)->inf_year, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "length", 6))
+ {
+ strcpy((*c)->inf_length, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "fade", 4))
+ {
+ strcpy((*c)->inf_fade, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ }
+ }
+
+ // Bingo
+ return AO_SUCCESS;
+}
+
+uint32_t psfTimeToMS(char *str)
+{
+ int x, c=0;
+ uint32_t acc=0;
+ char s[100];
+
+ strncpy(s,str,100);
+ s[99]=0;
+
+ for (x=strlen(s); x>=0; x--)
+ {
+ if (s[x]=='.' || s[x]==',')
+ {
+ acc=atoi(s+x+1);
+ s[x]=0;
+ }
+ else if (s[x]==':')
+ {
+ if(c==0)
+ {
+ acc+=atoi(s+x+1)*10;
+ }
+ else if(c==1)
+ {
+ acc+=atoi(s+x+(x?1:0))*10*60;
+ }
+
+ c++;
+ s[x]=0;
+ }
+ else if (x==0)
+ {
+ if(c==0)
+ {
+ acc+=atoi(s+x)*10;
+ }
+ else if(c==1)
+ {
+ acc+=atoi(s+x)*10*60;
+ }
+ else if(c==2)
+ {
+ acc+=atoi(s+x)*10*60*60;
+ }
+ }
+ }
+
+ acc*=100;
+ return(acc);
+}
+
diff --git a/src/psf/cpuintrf.h b/src/psf/cpuintrf.h
index 69035ddfd45e..8678e29a98ef 100644
--- a/src/psf/cpuintrf.h
+++ b/src/psf/cpuintrf.h
@@ -10,7 +10,7 @@
#define CLEAR_LINE 0 /* clear (a fired, held or pulsed) line */
#define ASSERT_LINE 1 /* assert an interrupt immediately */
-#define HOLD_LINE 2 /* hold interrupt line until enable is TRUE */
+#define HOLD_LINE 2 /* hold interrupt line until enable is true */
#define PULSE_LINE 3 /* pulse interrupt line for one instruction */
#define MAX_REGS 64 /* maximum number of register of any CPU */
@@ -650,7 +650,7 @@ enum
CPUINFO_PTR_CPU_SPECIFIC = 0x18000, /* R/W: CPU-specific values start here */
- /* --- the following bits of info are returned as NULL-terminated strings --- */
+ /* --- the following bits of info are returned as nullptr-terminated strings --- */
CPUINFO_STR_FIRST = 0x20000,
CPUINFO_STR_NAME = CPUINFO_STR_FIRST, /* R/O: name of the CPU */
diff --git a/src/psf/eng_protos.h b/src/psf/eng_protos.h
index a5b4eaf4641e..d3488eb44895 100644
--- a/src/psf/eng_protos.h
+++ b/src/psf/eng_protos.h
@@ -1,20 +1,20 @@
-#include <audacious/plugin.h>
+#include <libaudcore/plugin.h>
int32_t psf2_start(uint8_t *, uint32_t length);
-int32_t psf2_execute(void);
+int32_t psf2_execute(void (*update)(const void *, int));
int32_t psf2_stop(void);
int32_t psf2_command(int32_t, int32_t);
int32_t psf2_fill_info(Tuple *);
int psf2_seek(uint32_t);
int32_t psf_start(uint8_t *buffer, uint32_t length);
-int32_t psf_execute(void);
+int32_t psf_execute(void (*update)(const void *, int));
int psf_seek(uint32_t);
int32_t psf_stop(void);
int32_t spx_start(uint8_t *buffer, uint32_t length);
-int32_t spx_execute(void);
+int32_t spx_execute(void (*update)(const void *, int));
int spx_seek(uint32_t);
int32_t spx_stop(void);
-extern bool_t stop_flag;
+extern bool stop_flag;
diff --git a/src/psf/eng_psf.c b/src/psf/eng_psf.c
deleted file mode 100644
index caa607a69abb..000000000000
--- a/src/psf/eng_psf.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- Audio Overload SDK - PSF file format engine
-
- Copyright (c) 2007 R. Belmont and Richard Bannister.
-
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include "ao.h"
-#include "eng_protos.h"
-#include "cpuintrf.h"
-#include "psx.h"
-
-#include "peops/stdafx.h"
-#include "peops/externals.h"
-#include "peops/regs.h"
-#include "peops/registers.h"
-#include "peops/spu.h"
-
-#include "corlett.h"
-
-#define DEBUG_LOADER (0)
-
-#define LE32(x) GUINT32_FROM_LE(x)
-
-static corlett_t *c = NULL;
-static char psfby[256];
-int psf_refresh = -1;
-
-
-// main RAM
-extern uint32_t psx_ram[((2*1024*1024)/4)+4];
-extern uint32_t psx_scratch[0x400];
-extern uint32_t initial_ram[((2*1024*1024)/4)+4];
-extern uint32_t initial_scratch[0x400];
-static uint32_t initialPC, initialGP, initialSP;
-
-extern void mips_init( void );
-extern void mips_reset( void *param );
-extern int mips_execute( int cycles );
-extern void mips_set_info(uint32_t state, union cpuinfo *info);
-extern void psx_hw_init(void);
-extern void psx_hw_slice(void);
-extern void psx_hw_frame(void);
-extern void setlength(int32_t stop, int32_t fade);
-
-int32_t psf_start(uint8_t *buffer, uint32_t length)
-{
- uint8_t *file, *lib_decoded, *lib_raw_file, *alib_decoded;
- uint32_t offset, plength, PC, SP, GP, lengthMS, fadeMS;
- uint64_t file_len, lib_len, lib_raw_length, alib_len;
- corlett_t *lib;
- int i;
- union cpuinfo mipsinfo;
-
- // clear PSX work RAM before we start scribbling in it
- memset(psx_ram, 0, 2*1024*1024);
-
-// printf("Length = %d\n", length);
-
- // Decode the current GSF
- if (corlett_decode(buffer, length, &file, &file_len, &c) != AO_SUCCESS)
- {
- return AO_FAIL;
- }
-
-// printf("file_len %d reserve %d\n", file_len, c->res_size);
-
- // check for PSX EXE signature
- if (strncmp((char *)file, "PS-X EXE", 8))
- {
- return AO_FAIL;
- }
-
- #if DEBUG_LOADER
- offset = file[0x18] | file[0x19]<<8 | file[0x1a]<<16 | file[0x1b]<<24;
- printf("Text section start: %x\n", offset);
- offset = file[0x1c] | file[0x1d]<<8 | file[0x1e]<<16 | file[0x1f]<<24;
- printf("Text section size: %x\n", offset);
- printf("Region: [%s]\n", &file[0x4c]);
- printf("refresh: [%s]\n", c->inf_refresh);
- #endif
-
- if (c->inf_refresh[0] == '5')
- {
- psf_refresh = 50;
- }
- if (c->inf_refresh[0] == '6')
- {
- psf_refresh = 60;
- }
-
- PC = file[0x10] | file[0x11]<<8 | file[0x12]<<16 | file[0x13]<<24;
- GP = file[0x14] | file[0x15]<<8 | file[0x16]<<16 | file[0x17]<<24;
- SP = file[0x30] | file[0x31]<<8 | file[0x32]<<16 | file[0x33]<<24;
-
- #if DEBUG_LOADER
- printf("Top level: PC %x GP %x SP %x\n", PC, GP, SP);
- #endif
-
- // Get the library file, if any
- if (c->lib[0] != 0)
- {
- uint64_t tmp_length;
-
- #if DEBUG_LOADER
- printf("Loading library: %s\n", c->lib);
- #endif
- if (ao_get_lib(c->lib, &lib_raw_file, &tmp_length) != AO_SUCCESS)
- {
- return AO_FAIL;
- }
- lib_raw_length = tmp_length;
-
- if (lib_raw_file == NULL)
- return AO_FAIL;
-
- if (corlett_decode(lib_raw_file, lib_raw_length, &lib_decoded, &lib_len, &lib) != AO_SUCCESS)
- {
- free(lib_raw_file);
- return AO_FAIL;
- }
-
- // Free up raw file
- free(lib_raw_file);
-
- if (strncmp((char *)lib_decoded, "PS-X EXE", 8))
- {
- printf("Major error! PSF was OK, but referenced library is not!\n");
- free(lib);
- return AO_FAIL;
- }
-
- #if DEBUG_LOADER
- offset = lib_decoded[0x18] | lib_decoded[0x19]<<8 | lib_decoded[0x1a]<<16 | lib_decoded[0x1b]<<24;
- printf("Text section start: %x\n", offset);
- offset = lib_decoded[0x1c] | lib_decoded[0x1d]<<8 | lib_decoded[0x1e]<<16 | lib_decoded[0x1f]<<24;
- printf("Text section size: %x\n", offset);
- printf("Region: [%s]\n", &lib_decoded[0x4c]);
- printf("refresh: [%s]\n", lib->inf_refresh);
- #endif
-
- // if the original file had no refresh tag, give the lib a shot
- if (psf_refresh == -1)
- {
- if (lib->inf_refresh[0] == '5')
- {
- psf_refresh = 50;
- }
- if (lib->inf_refresh[0] == '6')
- {
- psf_refresh = 60;
- }
- }
-
- PC = lib_decoded[0x10] | lib_decoded[0x11]<<8 | lib_decoded[0x12]<<16 | lib_decoded[0x13]<<24;
- GP = lib_decoded[0x14] | lib_decoded[0x15]<<8 | lib_decoded[0x16]<<16 | lib_decoded[0x17]<<24;
- SP = lib_decoded[0x30] | lib_decoded[0x31]<<8 | lib_decoded[0x32]<<16 | lib_decoded[0x33]<<24;
-
- #if DEBUG_LOADER
- printf("Library: PC %x GP %x SP %x\n", PC, GP, SP);
- #endif
-
- // now patch the file into RAM
- offset = lib_decoded[0x18] | lib_decoded[0x19]<<8 | lib_decoded[0x1a]<<16 | lib_decoded[0x1b]<<24;
- offset &= 0x3fffffff; // kill any MIPS cache segment indicators
-
- /* valid PS-X EXE image must be at least 2048 bytes, plength section may be wrong on
- * shite rips... --nenolod */
- if (lib_len < 2048)
- plength = 0;
- else
- plength = lib_len - 2048;
-
- #if DEBUG_LOADER
- printf("library offset: %x plength: %d\n", offset, plength);
- #endif
- memcpy(&psx_ram[offset/4], lib_decoded + 2048, plength);
-
- // Dispose the corlett structure for the lib - we don't use it
- free(lib);
- }
-
- // now patch the main file into RAM OVER the libraries (but not the aux lib)
- offset = file[0x18] | file[0x19]<<8 | file[0x1a]<<16 | file[0x1b]<<24;
- offset &= 0x3fffffff; // kill any MIPS cache segment indicators
-
- if (file_len < 2048)
- plength = 0;
- else
- plength = file_len - 2048;
-
- memcpy(&psx_ram[offset/4], file + 2048, plength);
-
- // load any auxiliary libraries now
- for (i = 0; i < 8; i++)
- {
- if (c->libaux[i][0] != 0)
- {
- uint64_t tmp_length;
-
- #if DEBUG_LOADER
- printf("Loading aux library: %s\n", c->libaux[i]);
- #endif
-
- if (ao_get_lib(c->libaux[i], &lib_raw_file, &tmp_length) != AO_SUCCESS)
- {
- return AO_FAIL;
- }
- lib_raw_length = tmp_length;
-
- if (lib_raw_file == NULL)
- return AO_FAIL;
-
- if (corlett_decode(lib_raw_file, lib_raw_length, &alib_decoded, &alib_len, &lib) != AO_SUCCESS)
- {
- free(lib_raw_file);
- return AO_FAIL;
- }
-
- // Free up raw file
- free(lib_raw_file);
-
- if (strncmp((char *)alib_decoded, "PS-X EXE", 8))
- {
- printf("Major error! PSF was OK, but referenced library is not!\n");
- free(lib);
- return AO_FAIL;
- }
-
- #if DEBUG_LOADER
- offset = alib_decoded[0x18] | alib_decoded[0x19]<<8 | alib_decoded[0x1a]<<16 | alib_decoded[0x1b]<<24;
- printf("Text section start: %x\n", offset);
- offset = alib_decoded[0x1c] | alib_decoded[0x1d]<<8 | alib_decoded[0x1e]<<16 | alib_decoded[0x1f]<<24;
- printf("Text section size: %x\n", offset);
- printf("Region: [%s]\n", &alib_decoded[0x4c]);
- #endif
-
- // now patch the file into RAM
- offset = alib_decoded[0x18] | alib_decoded[0x19]<<8 | alib_decoded[0x1a]<<16 | alib_decoded[0x1b]<<24;
- offset &= 0x3fffffff; // kill any MIPS cache segment indicators
-
- if (alib_len < 2048)
- plength = 0;
- else
- plength = alib_len - 2048;
-
- memcpy(&psx_ram[offset/4], alib_decoded + 2048, plength);
-
- // Dispose the corlett structure for the lib - we don't use it
- free(lib);
- }
- }
-
- free(file);
-// free(lib_decoded);
-
- // Finally, set psfby tag
- strcpy(psfby, "n/a");
- if (c)
- {
- int i;
- for (i = 0; i < MAX_UNKNOWN_TAGS; i++)
- {
- if (!g_ascii_strcasecmp(c->tag_name[i], "psfby"))
- strcpy(psfby, c->tag_data[i]);
- }
- }
-
- mips_init();
- mips_reset(NULL);
-
- // set the initial PC, SP, GP
- #if DEBUG_LOADER
- printf("Initial PC %x, GP %x, SP %x\n", PC, GP, SP);
- printf("Refresh = %d\n", psf_refresh);
- #endif
- mipsinfo.i = PC;
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
-
- // set some reasonable default for the stack
- if (SP == 0)
- {
- SP = 0x801fff00;
- }
-
- mipsinfo.i = SP;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R29, &mipsinfo);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R30, &mipsinfo);
-
- mipsinfo.i = GP;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R28, &mipsinfo);
-
- #if DEBUG_LOADER && 1
- {
- FILE *f;
-
- f = fopen("psxram.bin", "wb");
- fwrite(psx_ram, 2*1024*1024, 1, f);
- fclose(f);
- }
- #endif
-
- psx_hw_init();
- SPUinit();
- SPUopen();
-
- lengthMS = psfTimeToMS(c->inf_length);
- fadeMS = psfTimeToMS(c->inf_fade);
-
- #if DEBUG_LOADER
- printf("length %d fade %d\n", lengthMS, fadeMS);
- #endif
-
- if (lengthMS == 0)
- {
- lengthMS = ~0;
- }
-
- setlength(lengthMS, fadeMS);
-
- // patch illegal Chocobo Dungeon 2 code - CaitSith2 put a jump in the delay slot from a BNE
- // and rely on Highly Experimental's buggy-ass CPU to rescue them. Verified on real hardware
- // that the initial code is wrong.
- if (c->inf_game)
- {
- if (!strcmp(c->inf_game, "Chocobo Dungeon 2"))
- {
- if (psx_ram[0xbc090/4] == LE32(0x0802f040))
- {
- psx_ram[0xbc090/4] = LE32(0);
- psx_ram[0xbc094/4] = LE32(0x0802f040);
- psx_ram[0xbc098/4] = LE32(0);
- }
- }
- }
-
-// psx_ram[0x118b8/4] = LE32(0); // crash 2 hack
-
- // backup the initial state for restart
- memcpy(initial_ram, psx_ram, 2*1024*1024);
- memcpy(initial_scratch, psx_scratch, 0x400);
- initialPC = PC;
- initialGP = GP;
- initialSP = SP;
-
- mips_execute(5000);
-
- return AO_SUCCESS;
-}
-
-int32_t psf_execute(void)
-{
- int i;
-
- while (!stop_flag) {
- for (i = 0; i < 44100 / 60; i++) {
- psx_hw_slice();
- SPUasync(384);
- }
-
- psx_hw_frame();
- }
-
- return AO_SUCCESS;
-}
-
-int32_t psf_stop(void)
-{
- SPUclose();
- free(c);
-
- return AO_SUCCESS;
-}
diff --git a/src/psf/eng_psf.cc b/src/psf/eng_psf.cc
new file mode 100644
index 000000000000..61cc70319ec1
--- /dev/null
+++ b/src/psf/eng_psf.cc
@@ -0,0 +1,372 @@
+/*
+ Audio Overload SDK - PSF file format engine
+
+ Copyright (c) 2007 R. Belmont and Richard Bannister.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <libaudcore/audstrings.h>
+
+#include "ao.h"
+#include "eng_protos.h"
+#include "cpuintrf.h"
+#include "psx.h"
+
+#include "peops/stdafx.h"
+#include "peops/externals.h"
+#include "peops/regs.h"
+#include "peops/registers.h"
+#include "peops/spu.h"
+
+#include "corlett.h"
+
+#define DEBUG_LOADER (0)
+
+#define LE32(x) FROM_LE32(x)
+
+static corlett_t *c = nullptr;
+static char psfby[256];
+int psf_refresh = -1;
+
+
+// main RAM
+extern uint32_t psx_ram[((2*1024*1024)/4)+4];
+extern uint32_t psx_scratch[0x400];
+extern uint32_t initial_ram[((2*1024*1024)/4)+4];
+extern uint32_t initial_scratch[0x400];
+static uint32_t initialPC, initialGP, initialSP;
+
+extern void mips_init( void );
+extern void mips_reset( void *param );
+extern int mips_execute( int cycles );
+extern void mips_set_info(uint32_t state, union cpuinfo *info);
+extern void psx_hw_init(void);
+extern void psx_hw_slice(void);
+extern void psx_hw_frame(void);
+extern void setlength(int32_t stop, int32_t fade);
+
+int32_t psf_start(uint8_t *buffer, uint32_t length)
+{
+ uint8_t *file, *lib_decoded, *alib_decoded;
+ uint32_t offset, plength, PC, SP, GP, lengthMS, fadeMS;
+ uint64_t file_len, lib_len, alib_len;
+ corlett_t *lib;
+ int i;
+ union cpuinfo mipsinfo;
+
+ // clear PSX work RAM before we start scribbling in it
+ memset(psx_ram, 0, 2*1024*1024);
+
+// printf("Length = %d\n", length);
+
+ // Decode the current GSF
+ if (corlett_decode(buffer, length, &file, &file_len, &c) != AO_SUCCESS)
+ {
+ return AO_FAIL;
+ }
+
+// printf("file_len %d reserve %d\n", file_len, c->res_size);
+
+ // check for PSX EXE signature
+ if (strncmp((char *)file, "PS-X EXE", 8))
+ {
+ return AO_FAIL;
+ }
+
+ #if DEBUG_LOADER
+ offset = file[0x18] | file[0x19]<<8 | file[0x1a]<<16 | file[0x1b]<<24;
+ printf("Text section start: %x\n", offset);
+ offset = file[0x1c] | file[0x1d]<<8 | file[0x1e]<<16 | file[0x1f]<<24;
+ printf("Text section size: %x\n", offset);
+ printf("Region: [%s]\n", &file[0x4c]);
+ printf("refresh: [%s]\n", c->inf_refresh);
+ #endif
+
+ if (c->inf_refresh[0] == '5')
+ {
+ psf_refresh = 50;
+ }
+ if (c->inf_refresh[0] == '6')
+ {
+ psf_refresh = 60;
+ }
+
+ PC = file[0x10] | file[0x11]<<8 | file[0x12]<<16 | file[0x13]<<24;
+ GP = file[0x14] | file[0x15]<<8 | file[0x16]<<16 | file[0x17]<<24;
+ SP = file[0x30] | file[0x31]<<8 | file[0x32]<<16 | file[0x33]<<24;
+
+ #if DEBUG_LOADER
+ printf("Top level: PC %x GP %x SP %x\n", PC, GP, SP);
+ #endif
+
+ // Get the library file, if any
+ if (c->lib[0] != 0)
+ {
+ #if DEBUG_LOADER
+ printf("Loading library: %s\n", c->lib);
+ #endif
+
+ Index<char> buf = ao_get_lib(c->lib);
+
+ if (!buf.len())
+ return AO_FAIL;
+
+ if (corlett_decode((uint8_t *)buf.begin(), buf.len(), &lib_decoded, &lib_len, &lib) != AO_SUCCESS)
+ return AO_FAIL;
+
+ if (strncmp((char *)lib_decoded, "PS-X EXE", 8))
+ {
+ printf("Major error! PSF was OK, but referenced library is not!\n");
+ free(lib);
+ return AO_FAIL;
+ }
+
+ #if DEBUG_LOADER
+ offset = lib_decoded[0x18] | lib_decoded[0x19]<<8 | lib_decoded[0x1a]<<16 | lib_decoded[0x1b]<<24;
+ printf("Text section start: %x\n", offset);
+ offset = lib_decoded[0x1c] | lib_decoded[0x1d]<<8 | lib_decoded[0x1e]<<16 | lib_decoded[0x1f]<<24;
+ printf("Text section size: %x\n", offset);
+ printf("Region: [%s]\n", &lib_decoded[0x4c]);
+ printf("refresh: [%s]\n", lib->inf_refresh);
+ #endif
+
+ // if the original file had no refresh tag, give the lib a shot
+ if (psf_refresh == -1)
+ {
+ if (lib->inf_refresh[0] == '5')
+ {
+ psf_refresh = 50;
+ }
+ if (lib->inf_refresh[0] == '6')
+ {
+ psf_refresh = 60;
+ }
+ }
+
+ PC = lib_decoded[0x10] | lib_decoded[0x11]<<8 | lib_decoded[0x12]<<16 | lib_decoded[0x13]<<24;
+ GP = lib_decoded[0x14] | lib_decoded[0x15]<<8 | lib_decoded[0x16]<<16 | lib_decoded[0x17]<<24;
+ SP = lib_decoded[0x30] | lib_decoded[0x31]<<8 | lib_decoded[0x32]<<16 | lib_decoded[0x33]<<24;
+
+ #if DEBUG_LOADER
+ printf("Library: PC %x GP %x SP %x\n", PC, GP, SP);
+ #endif
+
+ // now patch the file into RAM
+ offset = lib_decoded[0x18] | lib_decoded[0x19]<<8 | lib_decoded[0x1a]<<16 | lib_decoded[0x1b]<<24;
+ offset &= 0x3fffffff; // kill any MIPS cache segment indicators
+
+ /* valid PS-X EXE image must be at least 2048 bytes, plength section may be wrong on
+ * shite rips... --nenolod */
+ if (lib_len < 2048)
+ plength = 0;
+ else
+ plength = lib_len - 2048;
+
+ #if DEBUG_LOADER
+ printf("library offset: %x plength: %d\n", offset, plength);
+ #endif
+ memcpy(&psx_ram[offset/4], lib_decoded + 2048, plength);
+
+ // Dispose the corlett structure for the lib - we don't use it
+ free(lib);
+ }
+
+ // now patch the main file into RAM OVER the libraries (but not the aux lib)
+ offset = file[0x18] | file[0x19]<<8 | file[0x1a]<<16 | file[0x1b]<<24;
+ offset &= 0x3fffffff; // kill any MIPS cache segment indicators
+
+ if (file_len < 2048)
+ plength = 0;
+ else
+ plength = file_len - 2048;
+
+ memcpy(&psx_ram[offset/4], file + 2048, plength);
+
+ // load any auxiliary libraries now
+ for (i = 0; i < 8; i++)
+ {
+ if (c->libaux[i][0] != 0)
+ {
+ #if DEBUG_LOADER
+ printf("Loading aux library: %s\n", c->libaux[i]);
+ #endif
+
+ Index<char> buf = ao_get_lib(c->libaux[i]);
+
+ if (!buf.len())
+ return AO_FAIL;
+
+ if (corlett_decode((uint8_t *)buf.begin(), buf.len(), &alib_decoded, &alib_len, &lib) != AO_SUCCESS)
+ return AO_FAIL;
+
+ if (strncmp((char *)alib_decoded, "PS-X EXE", 8))
+ {
+ printf("Major error! PSF was OK, but referenced library is not!\n");
+ free(lib);
+ return AO_FAIL;
+ }
+
+ #if DEBUG_LOADER
+ offset = alib_decoded[0x18] | alib_decoded[0x19]<<8 | alib_decoded[0x1a]<<16 | alib_decoded[0x1b]<<24;
+ printf("Text section start: %x\n", offset);
+ offset = alib_decoded[0x1c] | alib_decoded[0x1d]<<8 | alib_decoded[0x1e]<<16 | alib_decoded[0x1f]<<24;
+ printf("Text section size: %x\n", offset);
+ printf("Region: [%s]\n", &alib_decoded[0x4c]);
+ #endif
+
+ // now patch the file into RAM
+ offset = alib_decoded[0x18] | alib_decoded[0x19]<<8 | alib_decoded[0x1a]<<16 | alib_decoded[0x1b]<<24;
+ offset &= 0x3fffffff; // kill any MIPS cache segment indicators
+
+ if (alib_len < 2048)
+ plength = 0;
+ else
+ plength = alib_len - 2048;
+
+ memcpy(&psx_ram[offset/4], alib_decoded + 2048, plength);
+
+ // Dispose the corlett structure for the lib - we don't use it
+ free(lib);
+ }
+ }
+
+ free(file);
+// free(lib_decoded);
+
+ // Finally, set psfby tag
+ strcpy(psfby, "n/a");
+ if (c)
+ {
+ int i;
+ for (i = 0; i < MAX_UNKNOWN_TAGS; i++)
+ {
+ if (!strcmp_nocase(c->tag_name[i], "psfby"))
+ strcpy(psfby, c->tag_data[i]);
+ }
+ }
+
+ mips_init();
+ mips_reset(nullptr);
+
+ // set the initial PC, SP, GP
+ #if DEBUG_LOADER
+ printf("Initial PC %x, GP %x, SP %x\n", PC, GP, SP);
+ printf("Refresh = %d\n", psf_refresh);
+ #endif
+ mipsinfo.i = PC;
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+
+ // set some reasonable default for the stack
+ if (SP == 0)
+ {
+ SP = 0x801fff00;
+ }
+
+ mipsinfo.i = SP;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R29, &mipsinfo);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R30, &mipsinfo);
+
+ mipsinfo.i = GP;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R28, &mipsinfo);
+
+ #if DEBUG_LOADER && 1
+ {
+ FILE *f;
+
+ f = fopen("psxram.bin", "wb");
+ fwrite(psx_ram, 2*1024*1024, 1, f);
+ fclose(f);
+ }
+ #endif
+
+ psx_hw_init();
+ SPUinit();
+ SPUopen();
+
+ lengthMS = psfTimeToMS(c->inf_length);
+ fadeMS = psfTimeToMS(c->inf_fade);
+
+ #if DEBUG_LOADER
+ printf("length %d fade %d\n", lengthMS, fadeMS);
+ #endif
+
+ if (lengthMS == 0)
+ {
+ lengthMS = ~0;
+ }
+
+ setlength(lengthMS, fadeMS);
+
+ // patch illegal Chocobo Dungeon 2 code - CaitSith2 put a jump in the delay slot from a BNE
+ // and rely on Highly Experimental's buggy-ass CPU to rescue them. Verified on real hardware
+ // that the initial code is wrong.
+ if (!strcmp(c->inf_game, "Chocobo Dungeon 2"))
+ {
+ if (psx_ram[0xbc090/4] == LE32(0x0802f040))
+ {
+ psx_ram[0xbc090/4] = LE32(0);
+ psx_ram[0xbc094/4] = LE32(0x0802f040);
+ psx_ram[0xbc098/4] = LE32(0);
+ }
+ }
+
+// psx_ram[0x118b8/4] = LE32(0); // crash 2 hack
+
+ // backup the initial state for restart
+ memcpy(initial_ram, psx_ram, 2*1024*1024);
+ memcpy(initial_scratch, psx_scratch, 0x400);
+ initialPC = PC;
+ initialGP = GP;
+ initialSP = SP;
+
+ mips_execute(5000);
+
+ return AO_SUCCESS;
+}
+
+int32_t psf_execute(void (*update)(const void *, int))
+{
+ int i;
+
+ while (!stop_flag) {
+ for (i = 0; i < 44100 / 60; i++) {
+ psx_hw_slice();
+ SPUasync(384, update);
+ }
+
+ psx_hw_frame();
+ }
+
+ return AO_SUCCESS;
+}
+
+int32_t psf_stop(void)
+{
+ SPUclose();
+ free(c);
+
+ return AO_SUCCESS;
+}
diff --git a/src/psf/eng_psf2.c b/src/psf/eng_psf2.c
deleted file mode 100644
index d30bff64e4d8..000000000000
--- a/src/psf/eng_psf2.c
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- Audio Overload SDK - PSF2 file format engine
-
- Copyright (c) 2007-2008 R. Belmont and Richard Bannister.
-
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-//
-// Audio Overload
-// Emulated music player
-//
-// (C) 2000-2008 Richard F. Bannister
-//
-
-//
-// eng_psf2.c
-//
-// References:
-// psf_format.txt v1.6 by Neill Corlett (filesystem and decompression info)
-// Intel ELF format specs ELF.PS (general ELF parsing info)
-// http://ps2dev.org/kb.x?T=457 (IRX relocation and inter-module call info)
-// http://ps2dev.org/ (the whole site - lots of IOP info)
-// spu2regs.txt (comes with SexyPSF source: IOP hardware info)
-// 64-bit ELF Object File Specification: http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf (MIPS ELF relocation types)
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-#include <zlib.h>
-
-#include "ao.h"
-#include "eng_protos.h"
-#include "cpuintrf.h"
-#include "psx.h"
-
-#include "peops2/stdafx.h"
-#include "peops2/externals.h"
-#include "peops2/regs.h"
-#include "peops2/registers.h"
-#include "peops2/spu.h"
-
-#include "corlett.h"
-
-#define DEBUG_LOADER (0)
-#define MAX_FS (32) // maximum # of filesystems (libs and subdirectories)
-
-// ELF relocation helpers
-#define ELF32_R_SYM(val) ((val) >> 8)
-#define ELF32_R_TYPE(val) ((val) & 0xff)
-
-#define LE32(x) GUINT32_FROM_LE(x)
-
-static corlett_t *c = NULL;
-
-// main RAM
-extern uint32_t psx_ram[(2*1024*1024)/4];
-extern uint32_t initial_ram[(2*1024*1024)/4];
-static uint32_t initialPC, initialSP;
-static uint32_t loadAddr, lengthMS, fadeMS;
-
-static uint8_t *filesys[MAX_FS];
-static uint8_t *lib_raw_file;
-static uint32_t fssize[MAX_FS];
-static int num_fs;
-
-extern void mips_init( void );
-extern void mips_reset( void *param );
-extern int mips_execute( int cycles );
-extern void mips_set_info(uint32_t state, union cpuinfo *info);
-extern void psx_hw_init(void);
-extern void ps2_hw_slice(void);
-extern void ps2_hw_frame(void);
-extern void setlength2(int32_t stop, int32_t fade);
-
-static void do_iopmod(uint8_t *start, uint32_t offset)
-{
- #if DEBUG_LOADER
- uint32_t nameoffs, saddr, heap, tsize, dsize, bsize, vers2;
-
- nameoffs = start[offset] | start[offset+1]<<8 | start[offset+2]<<16 | start[offset+3]<<24;
-
- saddr = start[offset+4] | start[offset+5]<<8 | start[offset+6]<<16 | start[offset+7]<<24;
- heap = start[offset+8] | start[offset+9]<<8 | start[offset+10]<<16 | start[offset+11]<<24;
- tsize = start[offset+12] | start[offset+13]<<8 | start[offset+14]<<16 | start[offset+15]<<24;
- dsize = start[offset+16] | start[offset+17]<<8 | start[offset+18]<<16 | start[offset+19]<<24;
- bsize = start[offset+20] | start[offset+21]<<8 | start[offset+22]<<16 | start[offset+23]<<24;
- vers2 = start[offset+24] | start[offset+25]<<8;
-
-// printf("nameoffs %08x saddr %08x heap %08x tsize %08x dsize %08x bsize %08x\n", nameoffs, saddr, heap, tsize, dsize, bsize);
- printf("vers: %04x name [%s]\n", vers2, &start[offset+26]);
- #endif
-}
-
-uint32_t psf2_load_elf(uint8_t *start, uint32_t len)
-{
- uint32_t entry, shoff, shentsize, shnum;
- uint32_t type, addr, offset, size, shent;
-// uint32_t phoff, phentsize, phnum, shstrndx, name, flags;
- uint32_t totallen;
- int i, rec;
-// FILE *f;
-
- if (loadAddr & 3)
- {
- loadAddr &= ~3;
- loadAddr += 4;
- }
-
- #if DEBUG_LOADER
- printf("psf2_load_elf: starting at %08x\n", loadAddr | 0x80000000);
- #endif
-
- if ((start[0] != 0x7f) || (start[1] != 'E') || (start[2] != 'L') || (start[3] != 'F'))
- {
- printf("Not an ELF file\n");
- return 0xffffffff;
- }
-
- entry = start[24] | start[25]<<8 | start[26]<<16 | start[27]<<24; // 0x18
-// phoff = start[28] | start[29]<<8 | start[30]<<16 | start[31]<<24; // 0x1c
- shoff = start[32] | start[33]<<8 | start[34]<<16 | start[35]<<24; // 0x20
-
-// printf("Entry: %08x phoff %08x shoff %08x\n", entry, phoff, shoff);
-
-// phentsize = start[42] | start[43]<<8; // 0x2a
-// phnum = start[44] | start[45]<<8; // 0x2c
- shentsize = start[46] | start[47]<<8; // 0x2e
- shnum = start[48] | start[49]<<8; // 0x30
-// shstrndx = start[50] | start[51]<<8; // 0x32
-
-// printf("phentsize %08x phnum %d shentsize %08x shnum %d shstrndx %d\n", phentsize, phnum, shentsize, shnum, shstrndx);
-
- // process ELF sections
- shent = shoff;
- totallen = 0;
- for (i = 0; i < shnum; i++)
- {
-// name = start[shent] | start[shent+1]<<8 | start[shent+2]<<16 | start[shent+3]<<24;
- type = start[shent+4] | start[shent+5]<<8 | start[shent+6]<<16 | start[shent+7]<<24;
-// flags = start[shent+8] | start[shent+9]<<8 | start[shent+10]<<16 | start[shent+11]<<24;
- addr = start[shent+12] | start[shent+13]<<8 | start[shent+14]<<16 | start[shent+15]<<24;
- offset = start[shent+16] | start[shent+17]<<8 | start[shent+18]<<16 | start[shent+19]<<24;
- size = start[shent+20] | start[shent+21]<<8 | start[shent+22]<<16 | start[shent+23]<<24;
-
-// printf("Section %02d: name %08x [%s] type %08x flags %08x addr %08x offset %08x size %08x\n", i, name, &start[secname(start, shstrndx, shoff, shentsize, name)], type, flags, addr, offset, size);
-
- switch (type)
- {
- case 0: // section table header - do nothing
- break;
-
- case 1: // PROGBITS: copy data to destination
- memcpy(&psx_ram[(loadAddr + addr)/4], &start[offset], size);
- totallen += size;
- break;
-
- case 2: // SYMTAB: ignore
- break;
-
- case 3: // STRTAB: ignore
- break;
-
- case 8: // NOBITS: BSS region, zero out destination
- memset(&psx_ram[(loadAddr + addr)/4], 0, size);
- totallen += size;
- break;
-
- case 9: // REL: short relocation data
- for (rec = 0; rec < (size/8); rec++)
- {
- uint32_t offs, info, target, temp, val, vallo;
- static uint32_t hi16offs = 0, hi16target = 0;
-
- offs = start[offset+(rec*8)] | start[offset+1+(rec*8)]<<8 | start[offset+2+(rec*8)]<<16 | start[offset+3+(rec*8)]<<24;
- info = start[offset+4+(rec*8)] | start[offset+5+(rec*8)]<<8 | start[offset+6+(rec*8)]<<16 | start[offset+7+(rec*8)]<<24;
- target = LE32(psx_ram[(loadAddr+offs)/4]);
-
-// printf("[%04d] offs %08x type %02x info %08x => %08x\n", rec, offs, ELF32_R_TYPE(info), ELF32_R_SYM(info), target);
-
- switch (ELF32_R_TYPE(info))
- {
- case 2: // R_MIPS_32
- target += loadAddr;
-// target |= 0x80000000;
- break;
-
- case 4: // R_MIPS_26
- temp = (target & 0x03ffffff);
- target &= 0xfc000000;
- temp += (loadAddr>>2);
- target |= temp;
- break;
-
- case 5: // R_MIPS_HI16
- hi16offs = offs;
- hi16target = target;
- break;
-
- case 6: // R_MIPS_LO16
- vallo = ((target & 0xffff) ^ 0x8000) - 0x8000;
-
- val = ((hi16target & 0xffff) << 16) + vallo;
- val += loadAddr;
-// val |= 0x80000000;
-
- /* Account for the sign extension that will happen in the low bits. */
- val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
-
- hi16target = (hi16target & ~0xffff) | val;
-
- /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
- val = loadAddr + vallo;
- target = (target & ~0xffff) | (val & 0xffff);
-
- psx_ram[(loadAddr+hi16offs)/4] = LE32(hi16target);
- break;
-
- default:
- printf("FATAL: Unknown MIPS ELF relocation!\n");
- return 0xffffffff;
- break;
- }
-
- psx_ram[(loadAddr+offs)/4] = LE32(target);
- }
- break;
-
- case 0x70000080: // .iopmod
- do_iopmod(start, offset);
- break;
-
- default:
- #if DEBUG_LOADER
- printf("Unhandled ELF section type %d\n", type);
- #endif
- break;
- }
-
- shent += shentsize;
- }
-
- entry += loadAddr;
- entry |= 0x80000000;
- loadAddr += totallen;
-
- #if DEBUG_LOADER
- printf("psf2_load_elf: entry PC %08x\n", entry);
- #endif
- return entry;
-}
-
-static uint32_t load_file_ex(uint8_t *top, uint8_t *start, uint32_t len, char *file, uint8_t *buf, uint32_t buflen)
-{
- int32_t numfiles, i, j;
- uint8_t *cptr;
- uint32_t offs, uncomp, bsize, cofs, uofs;
- uint32_t X;
- uLongf dlength;
- int uerr;
- char matchname[512], *remainder;
-
- // strip out to only the directory name
- i = 0;
- while ((file[i] != '/') && (file[i] != '\\') && (file[i] != '\0'))
- {
- matchname[i] = file[i];
- i++;
- }
- matchname[i] = '\0';
- remainder = &file[i+1];
-
- cptr = start + 4;
-
- numfiles = start[0] | start[1]<<8 | start[2]<<16 | start[3]<<24;
-
- for (i = 0; i < numfiles; i++)
- {
- offs = cptr[36] | cptr[37]<<8 | cptr[38]<<16 | cptr[39]<<24;
- uncomp = cptr[40] | cptr[41]<<8 | cptr[42]<<16 | cptr[43]<<24;
- bsize = cptr[44] | cptr[45]<<8 | cptr[46]<<16 | cptr[47]<<24;
-
- #if DEBUG_LOADER
- printf("[%s vs %s]: ofs %08x uncomp %08x bsize %08x\n", cptr, matchname, offs, uncomp, bsize);
- #endif
-
- if (!g_ascii_strcasecmp((char *)cptr, matchname))
- {
- if ((uncomp == 0) && (bsize == 0))
- {
- #if DEBUG_LOADER
- printf("Drilling into subdirectory [%s] with [%s] at offset %x\n", matchname, remainder, offs);
- #endif
- return load_file_ex(top, &top[offs], len-offs, remainder, buf, buflen);
- }
-
- X = (uncomp + bsize - 1) / bsize;
-
- cofs = offs + (X*4);
- uofs = 0;
- for (j = 0; j < X; j++)
- {
- uint32_t usize;
-
- usize = top[offs+(j*4)] | top[offs+1+(j*4)]<<8 | top[offs+2+(j*4)]<<16 | top[offs+3+(j*4)]<<24;
-
- dlength = buflen - uofs;
-
- uerr = uncompress(&buf[uofs], &dlength, &top[cofs], usize);
- if (uerr != Z_OK)
- {
- printf("Decompress fail: %lx %d!\n", dlength, uerr);
- return 0xffffffff;
- }
-
- cofs += usize;
- uofs += dlength;
- }
-
- return uncomp;
- }
- else
- {
- cptr += 48;
- }
- }
-
- return 0xffffffff;
-}
-
-static uint32_t load_file(int fs, char *file, uint8_t *buf, uint32_t buflen)
-{
- return load_file_ex(filesys[fs], filesys[fs], fssize[fs], file, buf, buflen);
-}
-
-#if 0
-static dump_files(int fs, uint8_t *buf, uint32_t buflen)
-{
- int32_t numfiles, i, j;
- uint8_t *cptr;
- uint32_t offs, uncomp, bsize, cofs, uofs;
- uint32_t X;
- uLongf dlength;
- int uerr;
- uint8_t *start;
- uint32_t len;
- FILE *f;
- char tfn[128];
-
- printf("Dumping FS %d\n", fs);
-
- start = filesys[fs];
- len = fssize[fs];
-
- cptr = start + 4;
-
- numfiles = start[0] | start[1]<<8 | start[2]<<16 | start[3]<<24;
-
- for (i = 0; i < numfiles; i++)
- {
- offs = cptr[36] | cptr[37]<<8 | cptr[38]<<16 | cptr[39]<<24;
- uncomp = cptr[40] | cptr[41]<<8 | cptr[42]<<16 | cptr[43]<<24;
- bsize = cptr[44] | cptr[45]<<8 | cptr[46]<<16 | cptr[47]<<24;
-
- if (bsize > 0)
- {
- X = (uncomp + bsize - 1) / bsize;
-
- printf("[dump %s]: ofs %08x uncomp %08x bsize %08x\n", cptr, offs, uncomp, bsize);
-
- cofs = offs + (X*4);
- uofs = 0;
- for (j = 0; j < X; j++)
- {
- uint32_t usize;
-
- usize = start[offs+(j*4)] | start[offs+1+(j*4)]<<8 | start[offs+2+(j*4)]<<16 | start[offs+3+(j*4)]<<24;
-
- dlength = buflen - uofs;
-
- uerr = uncompress(&buf[uofs], &dlength, &start[cofs], usize);
- if (uerr != Z_OK)
- {
- printf("Decompress fail: %x %d!\n", dlength, uerr);
- return 0xffffffff;
- }
-
- cofs += usize;
- uofs += dlength;
- }
-
- sprintf(tfn, "iopfiles/%s", cptr);
- f = fopen(tfn, "wb");
- fwrite(buf, uncomp, 1, f);
- fclose(f);
- }
- else
- {
- printf("[subdir %s]: ofs %08x uncomp %08x bsize %08x\n", cptr, offs, uncomp, bsize);
- }
-
- cptr += 48;
- }
-
- return 0xffffffff;
-}
-#endif
-
-// find a file on our filesystems
-uint32_t psf2_load_file(char *file, uint8_t *buf, uint32_t buflen)
-{
- int i;
- uint32_t flen;
-
- for (i = 0; i < num_fs; i++)
- {
- flen = load_file(i, file, buf, buflen);
- if (flen != 0xffffffff)
- {
- return flen;
- }
- }
-
- return 0xffffffff;
-}
-
-int32_t psf2_start(uint8_t *buffer, uint32_t length)
-{
- uint8_t *file, *lib_decoded;
- uint32_t irx_len;
- uint64_t file_len, lib_raw_length, lib_len;
- uint8_t *buf;
- union cpuinfo mipsinfo;
- corlett_t *lib;
-
- loadAddr = 0x23f00; // this value makes allocations work out similarly to how they would
- // in Highly Experimental (as per Shadow Hearts' hard-coded assumptions)
-
- // clear IOP work RAM before we start scribbling in it
- memset(psx_ram, 0, 2*1024*1024);
-
- // Decode the current PSF2
- if (corlett_decode(buffer, length, &file, &file_len, &c) != AO_SUCCESS)
- {
- return AO_FAIL;
- }
-
- if (file_len > 0)
- printf ("ERROR: PSF2 can't have a program section! ps %lx\n", (unsigned long) file_len);
-
- #if DEBUG_LOADER
- printf("FS section: size %x\n", c->res_size);
- #endif
-
- num_fs = 1;
- filesys[0] = (uint8_t *)c->res_section;
- fssize[0] = c->res_size;
-
- // Get the library file, if any
- if (c->lib[0] != 0)
- {
- uint64_t tmp_length;
-
- #if DEBUG_LOADER
- printf("Loading library: %s\n", c->lib);
- #endif
- if (ao_get_lib(c->lib, &lib_raw_file, &tmp_length) != AO_SUCCESS)
- {
- return AO_FAIL;
- }
- lib_raw_length = tmp_length;
-
- if (lib_raw_file == NULL)
- return AO_FAIL;
-
- if (corlett_decode(lib_raw_file, lib_raw_length, &lib_decoded, &lib_len, &lib) != AO_SUCCESS)
- {
- free(lib_raw_file);
- return AO_FAIL;
- }
-
- #if DEBUG_LOADER
- printf("Lib FS section: size %x bytes\n", lib->res_size);
- #endif
-
- num_fs++;
- filesys[1] = (uint8_t *)lib->res_section;
- fssize[1] = lib->res_size;
- }
-
- // dump all files
- #if 0
- buf = (uint8_t *)malloc(16*1024*1024);
- dump_files(0, buf, 16*1024*1024);
- if (c->lib[0] != 0)
- dump_files(1, buf, 16*1024*1024);
- free(buf);
- #endif
-
- // load psf2.irx, which kicks everything off
- buf = (uint8_t *)malloc(512*1024);
- irx_len = psf2_load_file("psf2.irx", buf, 512*1024);
-
- if (irx_len != 0xffffffff)
- {
- initialPC = psf2_load_elf(buf, irx_len);
- initialSP = 0x801ffff0;
- }
- free(buf);
-
- if (initialPC == 0xffffffff)
- {
- return AO_FAIL;
- }
-
- lengthMS = psfTimeToMS(c->inf_length);
- fadeMS = psfTimeToMS(c->inf_fade);
- if (lengthMS == 0)
- {
- lengthMS = ~0;
- }
- setlength2(lengthMS, fadeMS);
-
- mips_init();
- mips_reset(NULL);
-
- mipsinfo.i = initialPC;
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
-
- mipsinfo.i = initialSP;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R29, &mipsinfo);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R30, &mipsinfo);
-
- // set RA
- mipsinfo.i = 0x80000000;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
-
- // set A0 & A1 to point to "aofile:/"
- mipsinfo.i = 2; // argc
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
-
- mipsinfo.i = 0x80000004; // argv
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R5, &mipsinfo);
- psx_ram[1] = LE32(0x80000008);
-
- buf = (uint8_t *)&psx_ram[2];
- strcpy((char *)buf, "aofile:/");
-
- psx_ram[0] = LE32(FUNCT_HLECALL);
-
- // back up initial RAM image to quickly restart songs
- memcpy(initial_ram, psx_ram, 2*1024*1024);
-
- psx_hw_init();
- SPU2init();
- SPU2open(NULL);
-
- return AO_SUCCESS;
-}
-
-int32_t psf2_execute(void)
-{
- int i;
-
- while (!stop_flag)
- {
- for (i = 0; i < 44100 / 60; i++)
- {
- SPU2async(1);
- ps2_hw_slice();
- }
-
- ps2_hw_frame();
- }
-
- return AO_SUCCESS;
-}
-
-int32_t psf2_stop(void)
-{
- SPU2close();
- if (c->lib[0] != 0)
- {
- free(lib_raw_file);
- }
- free(c);
-
- return AO_SUCCESS;
-}
-
-int32_t psf2_command(int32_t command, int32_t parameter)
-{
- union cpuinfo mipsinfo;
- uint32_t lengthMS, fadeMS;
-
- switch (command)
- {
- case COMMAND_RESTART:
- SPU2close();
-
- memcpy(psx_ram, initial_ram, 2*1024*1024);
-
- mips_init();
- mips_reset(NULL);
- psx_hw_init();
- SPU2init();
- SPU2open(NULL);
-
- mipsinfo.i = initialPC;
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
-
- mipsinfo.i = initialSP;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R29, &mipsinfo);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R30, &mipsinfo);
-
- // set RA
- mipsinfo.i = 0x80000000;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
-
- // set A0 & A1 to point to "aofile:/"
- mipsinfo.i = 2; // argc
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
-
- mipsinfo.i = 0x80000004; // argv
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R5, &mipsinfo);
-
- psx_hw_init();
-
- lengthMS = psfTimeToMS(c->inf_length);
- fadeMS = psfTimeToMS(c->inf_fade);
- if (lengthMS == 0)
- {
- lengthMS = ~0;
- }
- setlength2(lengthMS, fadeMS);
-
- return AO_SUCCESS;
-
- }
- return AO_FAIL;
-}
-
-uint32_t psf2_get_loadaddr(void)
-{
- return loadAddr;
-}
-
-void psf2_set_loadaddr(uint32_t new)
-{
- loadAddr = new;
-}
diff --git a/src/psf/eng_psf2.cc b/src/psf/eng_psf2.cc
new file mode 100644
index 000000000000..ed1dde0cb04b
--- /dev/null
+++ b/src/psf/eng_psf2.cc
@@ -0,0 +1,662 @@
+/*
+ Audio Overload SDK - PSF2 file format engine
+
+ Copyright (c) 2007-2008 R. Belmont and Richard Bannister.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+//
+// Audio Overload
+// Emulated music player
+//
+// (C) 2000-2008 Richard F. Bannister
+//
+
+//
+// eng_psf2.c
+//
+// References:
+// psf_format.txt v1.6 by Neill Corlett (filesystem and decompression info)
+// Intel ELF format specs ELF.PS (general ELF parsing info)
+// http://ps2dev.org/kb.x?T=457 (IRX relocation and inter-module call info)
+// http://ps2dev.org/ (the whole site - lots of IOP info)
+// spu2regs.txt (comes with SexyPSF source: IOP hardware info)
+// 64-bit ELF Object File Specification: http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf (MIPS ELF relocation types)
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <zlib.h>
+#include <libaudcore/audstrings.h>
+
+#include "ao.h"
+#include "eng_protos.h"
+#include "cpuintrf.h"
+#include "psx.h"
+
+#include "peops2/stdafx.h"
+#include "peops2/externals.h"
+#include "peops2/regs.h"
+#include "peops2/registers.h"
+#include "peops2/spu.h"
+
+#include "corlett.h"
+
+#define DEBUG_LOADER (0)
+#define MAX_FS (32) // maximum # of filesystems (libs and subdirectories)
+
+// ELF relocation helpers
+#define ELF32_R_SYM(val) ((val) >> 8)
+#define ELF32_R_TYPE(val) ((val) & 0xff)
+
+#define LE32(x) FROM_LE32(x)
+
+static corlett_t *c = nullptr;
+
+// main RAM
+extern uint32_t psx_ram[(2*1024*1024)/4];
+extern uint32_t initial_ram[(2*1024*1024)/4];
+static uint32_t initialPC, initialSP;
+static uint32_t loadAddr, lengthMS, fadeMS;
+
+static uint8_t *filesys[MAX_FS];
+static Index<char> lib_raw_file;
+static uint32_t fssize[MAX_FS];
+static int num_fs;
+
+extern void mips_init( void );
+extern void mips_reset( void *param );
+extern int mips_execute( int cycles );
+extern void mips_set_info(uint32_t state, union cpuinfo *info);
+extern void psx_hw_init(void);
+extern void ps2_hw_slice(void);
+extern void ps2_hw_frame(void);
+extern void setlength2(int32_t stop, int32_t fade);
+
+static void do_iopmod(uint8_t *start, uint32_t offset)
+{
+ #if DEBUG_LOADER
+ uint32_t nameoffs, saddr, heap, tsize, dsize, bsize, vers2;
+
+ nameoffs = start[offset] | start[offset+1]<<8 | start[offset+2]<<16 | start[offset+3]<<24;
+
+ saddr = start[offset+4] | start[offset+5]<<8 | start[offset+6]<<16 | start[offset+7]<<24;
+ heap = start[offset+8] | start[offset+9]<<8 | start[offset+10]<<16 | start[offset+11]<<24;
+ tsize = start[offset+12] | start[offset+13]<<8 | start[offset+14]<<16 | start[offset+15]<<24;
+ dsize = start[offset+16] | start[offset+17]<<8 | start[offset+18]<<16 | start[offset+19]<<24;
+ bsize = start[offset+20] | start[offset+21]<<8 | start[offset+22]<<16 | start[offset+23]<<24;
+ vers2 = start[offset+24] | start[offset+25]<<8;
+
+// printf("nameoffs %08x saddr %08x heap %08x tsize %08x dsize %08x bsize %08x\n", nameoffs, saddr, heap, tsize, dsize, bsize);
+ printf("vers: %04x name [%s]\n", vers2, &start[offset+26]);
+ #endif
+}
+
+uint32_t psf2_load_elf(uint8_t *start, uint32_t len)
+{
+ uint32_t entry, shoff, shentsize, shnum;
+ uint32_t type, addr, offset, size, shent;
+// uint32_t phoff, phentsize, phnum, shstrndx, name, flags;
+ uint32_t totallen;
+ int i, rec;
+// FILE *f;
+
+ if (loadAddr & 3)
+ {
+ loadAddr &= ~3;
+ loadAddr += 4;
+ }
+
+ #if DEBUG_LOADER
+ printf("psf2_load_elf: starting at %08x\n", loadAddr | 0x80000000);
+ #endif
+
+ if ((start[0] != 0x7f) || (start[1] != 'E') || (start[2] != 'L') || (start[3] != 'F'))
+ {
+ printf("Not an ELF file\n");
+ return 0xffffffff;
+ }
+
+ entry = start[24] | start[25]<<8 | start[26]<<16 | start[27]<<24; // 0x18
+// phoff = start[28] | start[29]<<8 | start[30]<<16 | start[31]<<24; // 0x1c
+ shoff = start[32] | start[33]<<8 | start[34]<<16 | start[35]<<24; // 0x20
+
+// printf("Entry: %08x phoff %08x shoff %08x\n", entry, phoff, shoff);
+
+// phentsize = start[42] | start[43]<<8; // 0x2a
+// phnum = start[44] | start[45]<<8; // 0x2c
+ shentsize = start[46] | start[47]<<8; // 0x2e
+ shnum = start[48] | start[49]<<8; // 0x30
+// shstrndx = start[50] | start[51]<<8; // 0x32
+
+// printf("phentsize %08x phnum %d shentsize %08x shnum %d shstrndx %d\n", phentsize, phnum, shentsize, shnum, shstrndx);
+
+ // process ELF sections
+ shent = shoff;
+ totallen = 0;
+ for (i = 0; i < shnum; i++)
+ {
+// name = start[shent] | start[shent+1]<<8 | start[shent+2]<<16 | start[shent+3]<<24;
+ type = start[shent+4] | start[shent+5]<<8 | start[shent+6]<<16 | start[shent+7]<<24;
+// flags = start[shent+8] | start[shent+9]<<8 | start[shent+10]<<16 | start[shent+11]<<24;
+ addr = start[shent+12] | start[shent+13]<<8 | start[shent+14]<<16 | start[shent+15]<<24;
+ offset = start[shent+16] | start[shent+17]<<8 | start[shent+18]<<16 | start[shent+19]<<24;
+ size = start[shent+20] | start[shent+21]<<8 | start[shent+22]<<16 | start[shent+23]<<24;
+
+// printf("Section %02d: name %08x [%s] type %08x flags %08x addr %08x offset %08x size %08x\n", i, name, &start[secname(start, shstrndx, shoff, shentsize, name)], type, flags, addr, offset, size);
+
+ switch (type)
+ {
+ case 0: // section table header - do nothing
+ break;
+
+ case 1: // PROGBITS: copy data to destination
+ memcpy(&psx_ram[(loadAddr + addr)/4], &start[offset], size);
+ totallen += size;
+ break;
+
+ case 2: // SYMTAB: ignore
+ break;
+
+ case 3: // STRTAB: ignore
+ break;
+
+ case 8: // NOBITS: BSS region, zero out destination
+ memset(&psx_ram[(loadAddr + addr)/4], 0, size);
+ totallen += size;
+ break;
+
+ case 9: // REL: short relocation data
+ for (rec = 0; rec < (size/8); rec++)
+ {
+ uint32_t offs, info, target, temp, val, vallo;
+ static uint32_t hi16offs = 0, hi16target = 0;
+
+ offs = start[offset+(rec*8)] | start[offset+1+(rec*8)]<<8 | start[offset+2+(rec*8)]<<16 | start[offset+3+(rec*8)]<<24;
+ info = start[offset+4+(rec*8)] | start[offset+5+(rec*8)]<<8 | start[offset+6+(rec*8)]<<16 | start[offset+7+(rec*8)]<<24;
+ target = LE32(psx_ram[(loadAddr+offs)/4]);
+
+// printf("[%04d] offs %08x type %02x info %08x => %08x\n", rec, offs, ELF32_R_TYPE(info), ELF32_R_SYM(info), target);
+
+ switch (ELF32_R_TYPE(info))
+ {
+ case 2: // R_MIPS_32
+ target += loadAddr;
+// target |= 0x80000000;
+ break;
+
+ case 4: // R_MIPS_26
+ temp = (target & 0x03ffffff);
+ target &= 0xfc000000;
+ temp += (loadAddr>>2);
+ target |= temp;
+ break;
+
+ case 5: // R_MIPS_HI16
+ hi16offs = offs;
+ hi16target = target;
+ break;
+
+ case 6: // R_MIPS_LO16
+ vallo = ((target & 0xffff) ^ 0x8000) - 0x8000;
+
+ val = ((hi16target & 0xffff) << 16) + vallo;
+ val += loadAddr;
+// val |= 0x80000000;
+
+ /* Account for the sign extension that will happen in the low bits. */
+ val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
+
+ hi16target = (hi16target & ~0xffff) | val;
+
+ /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
+ val = loadAddr + vallo;
+ target = (target & ~0xffff) | (val & 0xffff);
+
+ psx_ram[(loadAddr+hi16offs)/4] = LE32(hi16target);
+ break;
+
+ default:
+ printf("FATAL: Unknown MIPS ELF relocation!\n");
+ return 0xffffffff;
+ break;
+ }
+
+ psx_ram[(loadAddr+offs)/4] = LE32(target);
+ }
+ break;
+
+ case 0x70000080: // .iopmod
+ do_iopmod(start, offset);
+ break;
+
+ default:
+ #if DEBUG_LOADER
+ printf("Unhandled ELF section type %d\n", type);
+ #endif
+ break;
+ }
+
+ shent += shentsize;
+ }
+
+ entry += loadAddr;
+ entry |= 0x80000000;
+ loadAddr += totallen;
+
+ #if DEBUG_LOADER
+ printf("psf2_load_elf: entry PC %08x\n", entry);
+ #endif
+ return entry;
+}
+
+static uint32_t load_file_ex(uint8_t *top, uint8_t *start, uint32_t len, const char *file, uint8_t *buf, uint32_t buflen)
+{
+ int32_t numfiles, i, j;
+ uint8_t *cptr;
+ uint32_t offs, uncomp, bsize, cofs, uofs;
+ uint32_t X;
+ uLongf dlength;
+ int uerr;
+ char matchname[512];
+ const char *remainder;
+
+ // strip out to only the directory name
+ i = 0;
+ while ((file[i] != '/') && (file[i] != '\\') && (file[i] != '\0'))
+ {
+ matchname[i] = file[i];
+ i++;
+ }
+ matchname[i] = '\0';
+ remainder = &file[i+1];
+
+ cptr = start + 4;
+
+ numfiles = start[0] | start[1]<<8 | start[2]<<16 | start[3]<<24;
+
+ for (i = 0; i < numfiles; i++)
+ {
+ offs = cptr[36] | cptr[37]<<8 | cptr[38]<<16 | cptr[39]<<24;
+ uncomp = cptr[40] | cptr[41]<<8 | cptr[42]<<16 | cptr[43]<<24;
+ bsize = cptr[44] | cptr[45]<<8 | cptr[46]<<16 | cptr[47]<<24;
+
+ #if DEBUG_LOADER
+ printf("[%s vs %s]: ofs %08x uncomp %08x bsize %08x\n", cptr, matchname, offs, uncomp, bsize);
+ #endif
+
+ if (!strcmp_nocase((char *)cptr, matchname))
+ {
+ if ((uncomp == 0) && (bsize == 0))
+ {
+ #if DEBUG_LOADER
+ printf("Drilling into subdirectory [%s] with [%s] at offset %x\n", matchname, remainder, offs);
+ #endif
+ return load_file_ex(top, &top[offs], len-offs, remainder, buf, buflen);
+ }
+
+ X = (uncomp + bsize - 1) / bsize;
+
+ cofs = offs + (X*4);
+ uofs = 0;
+ for (j = 0; j < X; j++)
+ {
+ uint32_t usize;
+
+ usize = top[offs+(j*4)] | top[offs+1+(j*4)]<<8 | top[offs+2+(j*4)]<<16 | top[offs+3+(j*4)]<<24;
+
+ dlength = buflen - uofs;
+
+ uerr = uncompress(&buf[uofs], &dlength, &top[cofs], usize);
+ if (uerr != Z_OK)
+ {
+ printf("Decompress fail: %lx %d!\n", dlength, uerr);
+ return 0xffffffff;
+ }
+
+ cofs += usize;
+ uofs += dlength;
+ }
+
+ return uncomp;
+ }
+ else
+ {
+ cptr += 48;
+ }
+ }
+
+ return 0xffffffff;
+}
+
+static uint32_t load_file(int fs, const char *file, uint8_t *buf, uint32_t buflen)
+{
+ return load_file_ex(filesys[fs], filesys[fs], fssize[fs], file, buf, buflen);
+}
+
+#if 0
+static dump_files(int fs, uint8_t *buf, uint32_t buflen)
+{
+ int32_t numfiles, i, j;
+ uint8_t *cptr;
+ uint32_t offs, uncomp, bsize, cofs, uofs;
+ uint32_t X;
+ uLongf dlength;
+ int uerr;
+ uint8_t *start;
+ uint32_t len;
+ FILE *f;
+ char tfn[128];
+
+ printf("Dumping FS %d\n", fs);
+
+ start = filesys[fs];
+ len = fssize[fs];
+
+ cptr = start + 4;
+
+ numfiles = start[0] | start[1]<<8 | start[2]<<16 | start[3]<<24;
+
+ for (i = 0; i < numfiles; i++)
+ {
+ offs = cptr[36] | cptr[37]<<8 | cptr[38]<<16 | cptr[39]<<24;
+ uncomp = cptr[40] | cptr[41]<<8 | cptr[42]<<16 | cptr[43]<<24;
+ bsize = cptr[44] | cptr[45]<<8 | cptr[46]<<16 | cptr[47]<<24;
+
+ if (bsize > 0)
+ {
+ X = (uncomp + bsize - 1) / bsize;
+
+ printf("[dump %s]: ofs %08x uncomp %08x bsize %08x\n", cptr, offs, uncomp, bsize);
+
+ cofs = offs + (X*4);
+ uofs = 0;
+ for (j = 0; j < X; j++)
+ {
+ uint32_t usize;
+
+ usize = start[offs+(j*4)] | start[offs+1+(j*4)]<<8 | start[offs+2+(j*4)]<<16 | start[offs+3+(j*4)]<<24;
+
+ dlength = buflen - uofs;
+
+ uerr = uncompress(&buf[uofs], &dlength, &start[cofs], usize);
+ if (uerr != Z_OK)
+ {
+ printf("Decompress fail: %x %d!\n", dlength, uerr);
+ return 0xffffffff;
+ }
+
+ cofs += usize;
+ uofs += dlength;
+ }
+
+ sprintf(tfn, "iopfiles/%s", cptr);
+ f = fopen(tfn, "wb");
+ fwrite(buf, uncomp, 1, f);
+ fclose(f);
+ }
+ else
+ {
+ printf("[subdir %s]: ofs %08x uncomp %08x bsize %08x\n", cptr, offs, uncomp, bsize);
+ }
+
+ cptr += 48;
+ }
+
+ return 0xffffffff;
+}
+#endif
+
+// find a file on our filesystems
+uint32_t psf2_load_file(const char *file, uint8_t *buf, uint32_t buflen)
+{
+ int i;
+ uint32_t flen;
+
+ for (i = 0; i < num_fs; i++)
+ {
+ flen = load_file(i, file, buf, buflen);
+ if (flen != 0xffffffff)
+ {
+ return flen;
+ }
+ }
+
+ return 0xffffffff;
+}
+
+int32_t psf2_start(uint8_t *buffer, uint32_t length)
+{
+ uint8_t *file, *lib_decoded;
+ uint32_t irx_len;
+ uint64_t file_len, lib_len;
+ uint8_t *buf;
+ union cpuinfo mipsinfo;
+ corlett_t *lib;
+
+ loadAddr = 0x23f00; // this value makes allocations work out similarly to how they would
+ // in Highly Experimental (as per Shadow Hearts' hard-coded assumptions)
+
+ // clear IOP work RAM before we start scribbling in it
+ memset(psx_ram, 0, 2*1024*1024);
+
+ // Decode the current PSF2
+ if (corlett_decode(buffer, length, &file, &file_len, &c) != AO_SUCCESS)
+ {
+ return AO_FAIL;
+ }
+
+ if (file_len > 0)
+ printf ("ERROR: PSF2 can't have a program section! ps %lx\n", (unsigned long) file_len);
+
+ #if DEBUG_LOADER
+ printf("FS section: size %x\n", c->res_size);
+ #endif
+
+ num_fs = 1;
+ filesys[0] = (uint8_t *)c->res_section;
+ fssize[0] = c->res_size;
+
+ // Get the library file, if any
+ if (c->lib[0] != 0)
+ {
+ #if DEBUG_LOADER
+ printf("Loading library: %s\n", c->lib);
+ #endif
+
+ lib_raw_file = ao_get_lib(c->lib);
+
+ if (!lib_raw_file.len())
+ return AO_FAIL;
+
+ if (corlett_decode((uint8_t *)lib_raw_file.begin(), lib_raw_file.len(),
+ &lib_decoded, &lib_len, &lib) != AO_SUCCESS)
+ return AO_FAIL;
+
+ #if DEBUG_LOADER
+ printf("Lib FS section: size %x bytes\n", lib->res_size);
+ #endif
+
+ num_fs++;
+ filesys[1] = (uint8_t *)lib->res_section;
+ fssize[1] = lib->res_size;
+ }
+
+ // dump all files
+ #if 0
+ buf = (uint8_t *)malloc(16*1024*1024);
+ dump_files(0, buf, 16*1024*1024);
+ if (c->lib[0] != 0)
+ dump_files(1, buf, 16*1024*1024);
+ free(buf);
+ #endif
+
+ // load psf2.irx, which kicks everything off
+ buf = (uint8_t *)malloc(512*1024);
+ irx_len = psf2_load_file("psf2.irx", buf, 512*1024);
+
+ if (irx_len != 0xffffffff)
+ {
+ initialPC = psf2_load_elf(buf, irx_len);
+ initialSP = 0x801ffff0;
+ }
+ free(buf);
+
+ if (initialPC == 0xffffffff)
+ {
+ return AO_FAIL;
+ }
+
+ lengthMS = psfTimeToMS(c->inf_length);
+ fadeMS = psfTimeToMS(c->inf_fade);
+ if (lengthMS == 0)
+ {
+ lengthMS = ~0;
+ }
+ setlength2(lengthMS, fadeMS);
+
+ mips_init();
+ mips_reset(nullptr);
+
+ mipsinfo.i = initialPC;
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+
+ mipsinfo.i = initialSP;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R29, &mipsinfo);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R30, &mipsinfo);
+
+ // set RA
+ mipsinfo.i = 0x80000000;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+
+ // set A0 & A1 to point to "aofile:/"
+ mipsinfo.i = 2; // argc
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
+
+ mipsinfo.i = 0x80000004; // argv
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R5, &mipsinfo);
+ psx_ram[1] = LE32(0x80000008);
+
+ buf = (uint8_t *)&psx_ram[2];
+ strcpy((char *)buf, "aofile:/");
+
+ psx_ram[0] = LE32(FUNCT_HLECALL);
+
+ // back up initial RAM image to quickly restart songs
+ memcpy(initial_ram, psx_ram, 2*1024*1024);
+
+ psx_hw_init();
+ SPU2init();
+ SPU2open(nullptr);
+
+ return AO_SUCCESS;
+}
+
+int32_t psf2_execute(void (*update)(const void *, int))
+{
+ int i;
+
+ while (!stop_flag)
+ {
+ for (i = 0; i < 44100 / 60; i++)
+ {
+ SPU2async(update);
+ ps2_hw_slice();
+ }
+
+ ps2_hw_frame();
+ }
+
+ return AO_SUCCESS;
+}
+
+int32_t psf2_stop(void)
+{
+ SPU2close();
+ lib_raw_file.clear();
+ free(c);
+
+ return AO_SUCCESS;
+}
+
+int32_t psf2_command(int32_t command, int32_t parameter)
+{
+ union cpuinfo mipsinfo;
+ uint32_t lengthMS, fadeMS;
+
+ switch (command)
+ {
+ case COMMAND_RESTART:
+ SPU2close();
+
+ memcpy(psx_ram, initial_ram, 2*1024*1024);
+
+ mips_init();
+ mips_reset(nullptr);
+ psx_hw_init();
+ SPU2init();
+ SPU2open(nullptr);
+
+ mipsinfo.i = initialPC;
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+
+ mipsinfo.i = initialSP;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R29, &mipsinfo);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R30, &mipsinfo);
+
+ // set RA
+ mipsinfo.i = 0x80000000;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+
+ // set A0 & A1 to point to "aofile:/"
+ mipsinfo.i = 2; // argc
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
+
+ mipsinfo.i = 0x80000004; // argv
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R5, &mipsinfo);
+
+ psx_hw_init();
+
+ lengthMS = psfTimeToMS(c->inf_length);
+ fadeMS = psfTimeToMS(c->inf_fade);
+ if (lengthMS == 0)
+ {
+ lengthMS = ~0;
+ }
+ setlength2(lengthMS, fadeMS);
+
+ return AO_SUCCESS;
+
+ }
+ return AO_FAIL;
+}
+
+uint32_t psf2_get_loadaddr(void)
+{
+ return loadAddr;
+}
+
+void psf2_set_loadaddr(uint32_t addr)
+{
+ loadAddr = addr;
+}
diff --git a/src/psf/eng_spx.c b/src/psf/eng_spx.c
deleted file mode 100644
index 1d8293b4c20a..000000000000
--- a/src/psf/eng_spx.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- Audio Overload SDK - SPU file format engine
-
- Copyright (c) 2007 R. Belmont and Richard Bannister.
-
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-//
-// eng_spu.c
-//
-// Note: support for old-format files is not tested and may not work. All the rips I could find
-// are in the newer format. Also, CDDA and XA commands do not work - I've not found a rip using them.
-//
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "ao.h"
-#include "eng_protos.h"
-#include "cpuintrf.h"
-#include "psx.h"
-
-#include "peops/stdafx.h"
-#include "peops/externals.h"
-#include "peops/regs.h"
-#include "peops/registers.h"
-#include "peops/spu.h"
-
-extern int SPUinit(void);
-extern int SPUopen(void);
-extern int SPUclose(void);
-extern void SPUinjectRAMImage(unsigned short *source);
-
-extern void setlength(int32_t stop, int32_t fade);
-
-static uint8_t *start_of_file, *song_ptr;
-static uint32_t cur_tick, cur_event, num_events, next_tick, end_tick;
-static int old_fmt;
-static char name[128], song[128], company[128];
-
-int32_t spx_start(uint8_t *buffer, uint32_t length)
-{
- int i;
- uint16_t reg;
-
- if (strncmp((char *)buffer, "SPU", 3) && strncmp((char *)buffer, "SPX", 3))
- {
- return AO_FAIL;
- }
-
- start_of_file = buffer;
-
- SPUinit();
- SPUopen();
- setlength(~0, 0);
-
- // upload the SPU RAM image
- SPUinjectRAMImage((unsigned short *)&buffer[0]);
-
- // apply the register image
- for (i = 0; i < 512; i += 2)
- {
- reg = buffer[0x80000+i] | buffer[0x80000+i+1]<<8;
-
- SPUwriteRegister((i/2)+0x1f801c00, reg);
- }
-
- old_fmt = 1;
-
- if ((buffer[0x80200] != 0x44) || (buffer[0x80201] != 0xac) || (buffer[0x80202] != 0x00) || (buffer[0x80203] != 0x00))
- {
- old_fmt = 0;
- }
-
- if (old_fmt)
- {
- num_events = buffer[0x80204] | buffer[0x80205]<<8 | buffer[0x80206]<<16 | buffer[0x80207]<<24;
-
- if (((num_events * 12) + 0x80208) > length)
- {
- old_fmt = 0;
- }
- else
- {
- cur_tick = 0;
- }
- }
-
- if (!old_fmt)
- {
- end_tick = buffer[0x80200] | buffer[0x80201]<<8 | buffer[0x80202]<<16 | buffer[0x80203]<<24;
- cur_tick = buffer[0x80204] | buffer[0x80205]<<8 | buffer[0x80206]<<16 | buffer[0x80207]<<24;
- next_tick = cur_tick;
- }
-
- song_ptr = &buffer[0x80208];
- cur_event = 0;
-
- strncpy((char *)&buffer[4], name, 128);
- strncpy((char *)&buffer[0x44], song, 128);
- strncpy((char *)&buffer[0x84], company, 128);
-
- return AO_SUCCESS;
-}
-
-extern int SPUasync(uint32_t cycles);
-static void spx_tick(void)
-{
- uint32_t time, reg, size;
- uint16_t rdata;
- uint8_t opcode;
-
- if (old_fmt)
- {
- time = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
-
- while ((time == cur_tick) && (cur_event < num_events))
- {
- reg = song_ptr[4] | song_ptr[5]<<8 | song_ptr[6]<<16 | song_ptr[7]<<24;
- rdata = song_ptr[8] | song_ptr[9]<<8;
-
- SPUwriteRegister(reg, rdata);
-
- cur_event++;
- song_ptr += 12;
-
- time = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
- }
- }
- else
- {
- if (cur_tick < end_tick)
- {
- while (cur_tick == next_tick)
- {
- opcode = song_ptr[0];
- song_ptr++;
-
- switch (opcode)
- {
- case 0: // write register
- reg = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
- rdata = song_ptr[4] | song_ptr[5]<<8;
-
- SPUwriteRegister(reg, rdata);
-
- next_tick = song_ptr[6] | song_ptr[7]<<8 | song_ptr[8]<<16 | song_ptr[9]<<24;
- song_ptr += 10;
- break;
-
- case 1: // read register
- reg = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
- SPUreadRegister(reg);
- next_tick = song_ptr[4] | song_ptr[5]<<8 | song_ptr[6]<<16 | song_ptr[7]<<24;
- song_ptr += 8;
- break;
-
- case 2: // dma write
- size = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
- song_ptr += (4 + size);
- next_tick = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
- song_ptr += 4;
- break;
-
- case 3: // dma read
- next_tick = song_ptr[4] | song_ptr[5]<<8 | song_ptr[6]<<16 | song_ptr[7]<<24;
- song_ptr += 8;
- break;
-
- case 4: // xa play
- song_ptr += (32 + 16384);
- next_tick = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
- song_ptr += 4;
- break;
-
- case 5: // cdda play
- size = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
- song_ptr += (4 + size);
- next_tick = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
- song_ptr += 4;
- break;
-
- default:
- printf("Unknown opcode %d\n", opcode);
- exit(-1);
- break;
- }
- }
- }
- }
-
- cur_tick++;
-}
-
-int32_t spx_execute(void)
-{
- int i, run = 1;
-
- while (!stop_flag)
- {
- if (old_fmt && (cur_event >= num_events))
- run = 0;
- else if (cur_tick >= end_tick)
- run = 0;
-
- if (run)
- {
- for (i = 0; i < 44100 / 60; i++)
- {
- spx_tick();
- SPUasync(384);
- }
- }
- }
-
- return AO_SUCCESS;
-}
-
-int32_t spx_stop(void)
-{
- SPUclose();
-
- return AO_SUCCESS;
-}
diff --git a/src/psf/eng_spx.cc b/src/psf/eng_spx.cc
new file mode 100644
index 000000000000..4c4397f7b25c
--- /dev/null
+++ b/src/psf/eng_spx.cc
@@ -0,0 +1,243 @@
+/*
+ Audio Overload SDK - SPU file format engine
+
+ Copyright (c) 2007 R. Belmont and Richard Bannister.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+//
+// eng_spu.c
+//
+// Note: support for old-format files is not tested and may not work. All the rips I could find
+// are in the newer format. Also, CDDA and XA commands do not work - I've not found a rip using them.
+//
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "ao.h"
+#include "eng_protos.h"
+#include "cpuintrf.h"
+#include "psx.h"
+
+#include "peops/stdafx.h"
+#include "peops/externals.h"
+#include "peops/regs.h"
+#include "peops/registers.h"
+#include "peops/spu.h"
+
+extern int SPUinit(void);
+extern int SPUopen(void);
+extern int SPUclose(void);
+extern void SPUinjectRAMImage(unsigned short *source);
+
+extern void setlength(int32_t stop, int32_t fade);
+
+static uint8_t *start_of_file, *song_ptr;
+static uint32_t cur_tick, cur_event, num_events, next_tick, end_tick;
+static int old_fmt;
+static char name[128], song[128], company[128];
+
+int32_t spx_start(uint8_t *buffer, uint32_t length)
+{
+ int i;
+ uint16_t reg;
+
+ if (strncmp((char *)buffer, "SPU", 3) && strncmp((char *)buffer, "SPX", 3))
+ {
+ return AO_FAIL;
+ }
+
+ start_of_file = buffer;
+
+ SPUinit();
+ SPUopen();
+ setlength(~0, 0);
+
+ // upload the SPU RAM image
+ SPUinjectRAMImage((unsigned short *)&buffer[0]);
+
+ // apply the register image
+ for (i = 0; i < 512; i += 2)
+ {
+ reg = buffer[0x80000+i] | buffer[0x80000+i+1]<<8;
+
+ SPUwriteRegister((i/2)+0x1f801c00, reg);
+ }
+
+ old_fmt = 1;
+
+ if ((buffer[0x80200] != 0x44) || (buffer[0x80201] != 0xac) || (buffer[0x80202] != 0x00) || (buffer[0x80203] != 0x00))
+ {
+ old_fmt = 0;
+ }
+
+ if (old_fmt)
+ {
+ num_events = buffer[0x80204] | buffer[0x80205]<<8 | buffer[0x80206]<<16 | buffer[0x80207]<<24;
+
+ if (((num_events * 12) + 0x80208) > length)
+ {
+ old_fmt = 0;
+ }
+ else
+ {
+ cur_tick = 0;
+ }
+ }
+
+ if (!old_fmt)
+ {
+ end_tick = buffer[0x80200] | buffer[0x80201]<<8 | buffer[0x80202]<<16 | buffer[0x80203]<<24;
+ cur_tick = buffer[0x80204] | buffer[0x80205]<<8 | buffer[0x80206]<<16 | buffer[0x80207]<<24;
+ next_tick = cur_tick;
+ }
+
+ song_ptr = &buffer[0x80208];
+ cur_event = 0;
+
+ strncpy((char *)&buffer[4], name, 128);
+ strncpy((char *)&buffer[0x44], song, 128);
+ strncpy((char *)&buffer[0x84], company, 128);
+
+ return AO_SUCCESS;
+}
+
+static void spx_tick(void)
+{
+ uint32_t time, reg, size;
+ uint16_t rdata;
+ uint8_t opcode;
+
+ if (old_fmt)
+ {
+ time = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
+
+ while ((time == cur_tick) && (cur_event < num_events))
+ {
+ reg = song_ptr[4] | song_ptr[5]<<8 | song_ptr[6]<<16 | song_ptr[7]<<24;
+ rdata = song_ptr[8] | song_ptr[9]<<8;
+
+ SPUwriteRegister(reg, rdata);
+
+ cur_event++;
+ song_ptr += 12;
+
+ time = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
+ }
+ }
+ else
+ {
+ if (cur_tick < end_tick)
+ {
+ while (cur_tick == next_tick)
+ {
+ opcode = song_ptr[0];
+ song_ptr++;
+
+ switch (opcode)
+ {
+ case 0: // write register
+ reg = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
+ rdata = song_ptr[4] | song_ptr[5]<<8;
+
+ SPUwriteRegister(reg, rdata);
+
+ next_tick = song_ptr[6] | song_ptr[7]<<8 | song_ptr[8]<<16 | song_ptr[9]<<24;
+ song_ptr += 10;
+ break;
+
+ case 1: // read register
+ reg = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
+ SPUreadRegister(reg);
+ next_tick = song_ptr[4] | song_ptr[5]<<8 | song_ptr[6]<<16 | song_ptr[7]<<24;
+ song_ptr += 8;
+ break;
+
+ case 2: // dma write
+ size = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
+ song_ptr += (4 + size);
+ next_tick = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
+ song_ptr += 4;
+ break;
+
+ case 3: // dma read
+ next_tick = song_ptr[4] | song_ptr[5]<<8 | song_ptr[6]<<16 | song_ptr[7]<<24;
+ song_ptr += 8;
+ break;
+
+ case 4: // xa play
+ song_ptr += (32 + 16384);
+ next_tick = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
+ song_ptr += 4;
+ break;
+
+ case 5: // cdda play
+ size = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
+ song_ptr += (4 + size);
+ next_tick = song_ptr[0] | song_ptr[1]<<8 | song_ptr[2]<<16 | song_ptr[3]<<24;
+ song_ptr += 4;
+ break;
+
+ default:
+ printf("Unknown opcode %d\n", opcode);
+ exit(-1);
+ break;
+ }
+ }
+ }
+ }
+
+ cur_tick++;
+}
+
+int32_t spx_execute(void (*update)(const void *, int))
+{
+ int i, run = 1;
+
+ while (!stop_flag)
+ {
+ if (old_fmt && (cur_event >= num_events))
+ run = 0;
+ else if (cur_tick >= end_tick)
+ run = 0;
+
+ if (run)
+ {
+ for (i = 0; i < 44100 / 60; i++)
+ {
+ spx_tick();
+ SPUasync(384, update);
+ }
+ }
+ }
+
+ return AO_SUCCESS;
+}
+
+int32_t spx_stop(void)
+{
+ SPUclose();
+
+ return AO_SUCCESS;
+}
diff --git a/src/psf/peops/License.txt b/src/psf/peops/License.txt
index e51338c2caa9..dc9e742f60fe 100644
--- a/src/psf/peops/License.txt
+++ b/src/psf/peops/License.txt
@@ -4,7 +4,8 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
diff --git a/src/psf/peops/adsr.c b/src/psf/peops/adsr.c
deleted file mode 100644
index d9deca5a7632..000000000000
--- a/src/psf/peops/adsr.c
+++ /dev/null
@@ -1,618 +0,0 @@
-/***************************************************************************
- adsr.c - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove at addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-//*************************************************************************//
-// History of changes:
-//
-// 2003/01/06 - Pete
-// - added Neill's ADSR timings
-//
-// 2002/05/15 - Pete
-// - generic cleanup for the Peops release
-//
-//*************************************************************************//
-
-#define _IN_ADSR
-
-// will be included from spu.c
-#ifdef _IN_SPU
-
-////////////////////////////////////////////////////////////////////////
-// ADSR func
-////////////////////////////////////////////////////////////////////////
-
-static u32 RateTable[160];
-
-static void InitADSR(void) // INIT ADSR
-{
- u32 r,rs,rd;int i;
-
- memset(RateTable,0,sizeof(u32)*160); // build the rate table according to Neill's rules (see at bottom of file)
-
- r=3;rs=1;rd=0;
-
- for(i=32;i<160;i++) // we start at pos 32 with the real values... everything before is 0
- {
- if(r<0x3FFFFFFF)
- {
- r+=rs;
- rd++;if(rd==5) {rd=1;rs*=2;}
- }
- if(r>0x3FFFFFFF) r=0x3FFFFFFF;
-
- RateTable[i]=r;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void StartADSR(int ch) // MIX ADSR
-{
- s_chan[ch].ADSRX.lVolume=1; // and init some adsr vars
- s_chan[ch].ADSRX.State=0;
- s_chan[ch].ADSRX.EnvelopeVol=0;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline int MixADSR(int ch) // MIX ADSR
-{
- static const int sexytable[8]=
- {0,4,6,8,9,10,11,12};
-
- if(s_chan[ch].bStop) // should be stopped:
- { // do release
- if(s_chan[ch].ADSRX.ReleaseModeExp)
- {
- s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18+32+sexytable[(s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7]];
- }
- else
- {
- s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x0C + 32];
- }
-
- if(s_chan[ch].ADSRX.EnvelopeVol<0)
- {
- s_chan[ch].ADSRX.EnvelopeVol=0;
- s_chan[ch].bOn=0;
- s_chan[ch].bNoise=0;
- }
-
- s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
- return s_chan[ch].ADSRX.lVolume;
- }
- else // not stopped yet?
- {
- if(s_chan[ch].ADSRX.State==0) // -> attack
- {
- if(s_chan[ch].ADSRX.AttackModeExp)
- {
- if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
- else
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x18 + 32];
- }
- else
- {
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
- }
-
- if(s_chan[ch].ADSRX.EnvelopeVol<0)
- {
- s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
- s_chan[ch].ADSRX.State=1;
- }
-
- s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
- return s_chan[ch].ADSRX.lVolume;
- }
- //--------------------------------------------------//
- if(s_chan[ch].ADSRX.State==1) // -> decay
- {
- s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+32+sexytable[(s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7]];
-
- if(s_chan[ch].ADSRX.EnvelopeVol<0) s_chan[ch].ADSRX.EnvelopeVol=0;
- if(((s_chan[ch].ADSRX.EnvelopeVol>>27)&0xF) <= s_chan[ch].ADSRX.SustainLevel)
- {
- s_chan[ch].ADSRX.State=2;
- }
-
- s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
- return s_chan[ch].ADSRX.lVolume;
- }
- //--------------------------------------------------//
- if(s_chan[ch].ADSRX.State==2) // -> sustain
- {
- if(s_chan[ch].ADSRX.SustainIncrease)
- {
- if(s_chan[ch].ADSRX.SustainModeExp)
- {
- if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
- else
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x18 + 32];
- }
- else
- {
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
- }
-
- if(s_chan[ch].ADSRX.EnvelopeVol<0)
- {
- s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
- }
- }
- else
- {
- if(s_chan[ch].ADSRX.SustainModeExp)
- s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B+32+sexytable[(s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7]];
- else
- s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x0F + 32];
-
- if(s_chan[ch].ADSRX.EnvelopeVol<0)
- {
- s_chan[ch].ADSRX.EnvelopeVol=0;
- }
- }
- s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
- return s_chan[ch].ADSRX.lVolume;
- }
- }
- return 0;
-}
-
-#endif
-
-/*
-James Higgs ADSR investigations:
-
-PSX SPU Envelope Timings
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-First, here is an extract from doomed's SPU doc, which explains the basics
-of the SPU "volume envelope":
-
-*** doomed doc extract start ***
-
---------------------------------------------------------------------------
-Voices.
---------------------------------------------------------------------------
-The SPU has 24 hardware voices. These voices can be used to reproduce sample
-data, noise or can be used as frequency modulator on the next voice.
-Each voice has it's own programmable ADSR envelope filter. The main volume
-can be programmed independently for left and right output.
-
-The ADSR envelope filter works as follows:
-Ar = Attack rate, which specifies the speed at which the volume increases
- from zero to it's maximum value, as soon as the note on is given. The
- slope can be set to lineair or exponential.
-Dr = Decay rate specifies the speed at which the volume decreases to the
- sustain level. Decay is always decreasing exponentially.
-Sl = Sustain level, base level from which sustain starts.
-Sr = Sustain rate is the rate at which the volume of the sustained note
- increases or decreases. This can be either lineair or exponential.
-Rr = Release rate is the rate at which the volume of the note decreases
- as soon as the note off is given.
-
- lvl |
- ^ | /\Dr __
- Sl _| _ / _ \__--- \
- | / ---__ \ Rr
- | /Ar Sr \ \
- | / \\
- |/___________________\________
- ->time
-
-The overal volume can also be set to sweep up or down lineairly or
-exponentially from it's current value. This can be done seperately
-for left and right.
-
-Relevant SPU registers:
--------------------------------------------------------------
-$1f801xx8 Attack/Decay/Sustain level
-bit |0f|0e 0d 0c 0b 0a 09 08|07 06 05 04|03 02 01 00|
-desc.|Am| Ar |Dr |Sl |
-
-Am 0 Attack mode Linear
- 1 Exponential
-
-Ar 0-7f attack rate
-Dr 0-f decay rate
-Sl 0-f sustain level
--------------------------------------------------------------
-$1f801xxa Sustain rate, Release Rate.
-bit |0f|0e|0d|0c 0b 0a 09 08 07 06|05|04 03 02 01 00|
-desc.|Sm|Sd| 0| Sr |Rm|Rr |
-
-Sm 0 sustain rate mode linear
- 1 exponential
-Sd 0 sustain rate mode increase
- 1 decrease
-Sr 0-7f Sustain Rate
-Rm 0 Linear decrease
- 1 Exponential decrease
-Rr 0-1f Release Rate
-
-Note: decay mode is always Expontial decrease, and thus cannot
-be set.
--------------------------------------------------------------
-$1f801xxc Current ADSR volume
-bit |0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00|
-desc.|ADSRvol |
-
-ADSRvol Returns the current envelope volume when
- read.
--- James' Note: return range: 0 -> 32767
-
-*** doomed doc extract end ***
-
-By using a small PSX proggie to visualise the envelope as it was played,
-the following results for envelope timing were obtained:
-
-1. Attack rate value (linear mode)
-
- Attack value range: 0 -> 127
-
- Value | 48 | 52 | 56 | 60 | 64 | 68 | 72 | | 80 |
- -----------------------------------------------------------------
- Frames | 11 | 21 | 42 | 84 | 169| 338| 676| |2890|
-
- Note: frames is no. of PAL frames to reach full volume (100%
- amplitude)
-
- Hmm, noticing that the time taken to reach full volume doubles
- every time we add 4 to our attack value, we know the equation is
- of form:
- frames = k * 2 ^ (value / 4)
-
- (You may ponder about envelope generator hardware at this point,
- or maybe not... :)
-
- By substituting some stuff and running some checks, we get:
-
- k = 0.00257 (close enuf)
-
- therefore,
- frames = 0.00257 * 2 ^ (value / 4)
- If you just happen to be writing an emulator, then you can probably
- use an equation like:
-
- %volume_increase_per_tick = 1 / frames
-
-
- ------------------------------------
- Pete:
- ms=((1<<(value>>2))*514)/10000
- ------------------------------------
-
-2. Decay rate value (only has log mode)
-
- Decay value range: 0 -> 15
-
- Value | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
- ------------------------------------------------
- frames | | | | | 6 | 12 | 24 | 47 |
-
- Note: frames here is no. of PAL frames to decay to 50% volume.
-
- formula: frames = k * 2 ^ (value)
-
- Substituting, we get: k = 0.00146
-
- Further info on logarithmic nature:
- frames to decay to sustain level 3 = 3 * frames to decay to
- sustain level 9
-
- Also no. of frames to 25% volume = roughly 1.85 * no. of frames to
- 50% volume.
-
- Frag it - just use linear approx.
-
- ------------------------------------
- Pete:
- ms=((1<<value)*292)/10000
- ------------------------------------
-
-
-3. Sustain rate value (linear mode)
-
- Sustain rate range: 0 -> 127
-
- Value | 48 | 52 | 56 | 60 | 64 | 68 | 72 |
- -------------------------------------------
- frames | 9 | 19 | 37 | 74 | 147| 293| 587|
-
- Here, frames = no. of PAL frames for volume amplitude to go from 100%
- to 0% (or vice-versa).
-
- Same formula as for attack value, just a different value for k:
-
- k = 0.00225
-
- ie: frames = 0.00225 * 2 ^ (value / 4)
-
- For emulation purposes:
-
- %volume_increase_or_decrease_per_tick = 1 / frames
-
- ------------------------------------
- Pete:
- ms=((1<<(value>>2))*450)/10000
- ------------------------------------
-
-
-4. Release rate (linear mode)
-
- Release rate range: 0 -> 31
-
- Value | 13 | 14 | 15 | 16 | 17 |
- ---------------------------------------------------------------
- frames | 18 | 36 | 73 | 146| 292|
-
- Here, frames = no. of PAL frames to decay from 100% vol to 0% vol
- after "note-off" is triggered.
-
- Formula: frames = k * 2 ^ (value)
-
- And so: k = 0.00223
-
- ------------------------------------
- Pete:
- ms=((1<<value)*446)/10000
- ------------------------------------
-
-
-Other notes:
-
-Log stuff not figured out. You may get some clues from the "Decay rate"
-stuff above. For emu purposes it may not be important - use linear
-approx.
-
-To get timings in millisecs, multiply frames by 20.
-
-
-
-- James Higgs 17/6/2000
-james7780 at yahoo.com
-
-//---------------------------------------------------------------
-
-OLD adsr mixing according to james' rules... has to be called
-every one millisecond
-
-
- i32 v,v2,lT,l1,l2,l3;
-
- if(s_chan[ch].bStop) // psx wants to stop? -> release phase
- {
- if(s_chan[ch].ADSR.ReleaseVal!=0) // -> release not 0: do release (if 0: stop right now)
- {
- if(!s_chan[ch].ADSR.ReleaseVol) // --> release just started? set up the release stuff
- {
- s_chan[ch].ADSR.ReleaseStartTime=s_chan[ch].ADSR.lTime;
- s_chan[ch].ADSR.ReleaseVol=s_chan[ch].ADSR.lVolume;
- s_chan[ch].ADSR.ReleaseTime = // --> calc how long does it take to reach the wanted sus level
- (s_chan[ch].ADSR.ReleaseTime*
- s_chan[ch].ADSR.ReleaseVol)/1024;
- }
- // -> NO release exp mode used (yet)
- v=s_chan[ch].ADSR.ReleaseVol; // -> get last volume
- lT=s_chan[ch].ADSR.lTime- // -> how much time is past?
- s_chan[ch].ADSR.ReleaseStartTime;
- l1=s_chan[ch].ADSR.ReleaseTime;
-
- if(lT<l1) // -> we still have to release
- {
- v=v-((v*lT)/l1); // --> calc new volume
- }
- else // -> release is over: now really stop that sample
- {v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;}
- }
- else // -> release IS 0: release at once
- {
- v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;
- }
- }
- else
- {//--------------------------------------------------// not in release phase:
- v=1024;
- lT=s_chan[ch].ADSR.lTime;
- l1=s_chan[ch].ADSR.AttackTime;
-
- if(lT<l1) // attack
- { // no exp mode used (yet)
-// if(s_chan[ch].ADSR.AttackModeExp)
-// {
-// v=(v*lT)/l1;
-// }
-// else
- {
- v=(v*lT)/l1;
- }
- if(v==0) v=1;
- }
- else // decay
- { // should be exp, but who cares? ;)
- l2=s_chan[ch].ADSR.DecayTime;
- v2=s_chan[ch].ADSR.SustainLevel;
-
- lT-=l1;
- if(lT<l2)
- {
- v-=(((v-v2)*lT)/l2);
- }
- else // sustain
- { // no exp mode used (yet)
- l3=s_chan[ch].ADSR.SustainTime;
- lT-=l2;
- if(s_chan[ch].ADSR.SustainModeDec>0)
- {
- if(l3!=0) v2+=((v-v2)*lT)/l3;
- else v2=v;
- }
- else
- {
- if(l3!=0) v2-=(v2*lT)/l3;
- else v2=v;
- }
-
- if(v2>v) v2=v;
- if(v2<=0) {v2=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;}
-
- v=v2;
- }
- }
- }
-
- //----------------------------------------------------//
- // ok, done for this channel, so increase time
-
- s_chan[ch].ADSR.lTime+=1; // 1 = 1.020408f ms;
-
- if(v>1024) v=1024; // adjust volume
- if(v<0) v=0;
- s_chan[ch].ADSR.lVolume=v; // store act volume
-
- return v; // return the volume factor
-*/
-
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-
-/*
------------------------------------------------------------------------------
-Neill Corlett
-Playstation SPU envelope timing notes
------------------------------------------------------------------------------
-
-This is preliminary. This may be wrong. But the model described herein fits
-all of my experimental data, and it's just simple enough to sound right.
-
-ADSR envelope level ranges from 0x00000000 to 0x7FFFFFFF internally.
-The value returned by channel reg 0xC is (envelope_level>>16).
-
-Each sample, an increment or decrement value will be added to or
-subtracted from this envelope level.
-
-Create the rate log table. The values double every 4 entries.
- entry #0 = 4
-
- 4, 5, 6, 7,
- 8,10,12,14,
- 16,20,24,28, ...
-
- entry #40 = 4096...
- entry #44 = 8192...
- entry #48 = 16384...
- entry #52 = 32768...
- entry #56 = 65536...
-
-increments and decrements are in terms of ratelogtable[n]
-n may exceed the table bounds (plan on n being between -32 and 127).
-table values are all clipped between 0x00000000 and 0x3FFFFFFF
-
-when you "voice on", the envelope is always fully reset.
-(yes, it may click. the real thing does this too.)
-
-envelope level begins at zero.
-
-each state happens for at least 1 cycle
-(transitions are not instantaneous)
-this may result in some oddness: if the decay rate is uberfast, it will cut
-the envelope from full down to half in one sample, potentially skipping over
-the sustain level
-
-ATTACK
-------
-- if the envelope level has overflowed past the max, clip to 0x7FFFFFFF and
- proceed to DECAY.
-
-Linear attack mode:
-- line extends upward to 0x7FFFFFFF
-- increment per sample is ratelogtable[(Ar^0x7F)-0x10]
-
-Logarithmic attack mode:
-if envelope_level < 0x60000000:
- - line extends upward to 0x60000000
- - increment per sample is ratelogtable[(Ar^0x7F)-0x10]
-else:
- - line extends upward to 0x7FFFFFFF
- - increment per sample is ratelogtable[(Ar^0x7F)-0x18]
-
-DECAY
------
-- if ((envelope_level>>27)&0xF) <= Sl, proceed to SUSTAIN.
- Do not clip to the sustain level.
-- current line ends at (envelope_level & 0x07FFFFFF)
-- decrement per sample depends on (envelope_level>>28)&0x7
- 0: ratelogtable[(4*(Dr^0x1F))-0x18+0]
- 1: ratelogtable[(4*(Dr^0x1F))-0x18+4]
- 2: ratelogtable[(4*(Dr^0x1F))-0x18+6]
- 3: ratelogtable[(4*(Dr^0x1F))-0x18+8]
- 4: ratelogtable[(4*(Dr^0x1F))-0x18+9]
- 5: ratelogtable[(4*(Dr^0x1F))-0x18+10]
- 6: ratelogtable[(4*(Dr^0x1F))-0x18+11]
- 7: ratelogtable[(4*(Dr^0x1F))-0x18+12]
- (note that this is the same as the release rate formula, except that
- decay rates 10-1F aren't possible... those would be slower in theory)
-
-SUSTAIN
--------
-- no terminating condition except for voice off
-- Sd=0 (increase) behavior is identical to ATTACK for both log and linear.
-- Sd=1 (decrease) behavior:
-Linear sustain decrease:
-- line extends to 0x00000000
-- decrement per sample is ratelogtable[(Sr^0x7F)-0x0F]
-Logarithmic sustain decrease:
-- current line ends at (envelope_level & 0x07FFFFFF)
-- decrement per sample depends on (envelope_level>>28)&0x7
- 0: ratelogtable[(Sr^0x7F)-0x1B+0]
- 1: ratelogtable[(Sr^0x7F)-0x1B+4]
- 2: ratelogtable[(Sr^0x7F)-0x1B+6]
- 3: ratelogtable[(Sr^0x7F)-0x1B+8]
- 4: ratelogtable[(Sr^0x7F)-0x1B+9]
- 5: ratelogtable[(Sr^0x7F)-0x1B+10]
- 6: ratelogtable[(Sr^0x7F)-0x1B+11]
- 7: ratelogtable[(Sr^0x7F)-0x1B+12]
-
-RELEASE
--------
-- if the envelope level has overflowed to negative, clip to 0 and QUIT.
-
-Linear release mode:
-- line extends to 0x00000000
-- decrement per sample is ratelogtable[(4*(Rr^0x1F))-0x0C]
-
-Logarithmic release mode:
-- line extends to (envelope_level & 0x0FFFFFFF)
-- decrement per sample depends on (envelope_level>>28)&0x7
- 0: ratelogtable[(4*(Rr^0x1F))-0x18+0]
- 1: ratelogtable[(4*(Rr^0x1F))-0x18+4]
- 2: ratelogtable[(4*(Rr^0x1F))-0x18+6]
- 3: ratelogtable[(4*(Rr^0x1F))-0x18+8]
- 4: ratelogtable[(4*(Rr^0x1F))-0x18+9]
- 5: ratelogtable[(4*(Rr^0x1F))-0x18+10]
- 6: ratelogtable[(4*(Rr^0x1F))-0x18+11]
- 7: ratelogtable[(4*(Rr^0x1F))-0x18+12]
-
------------------------------------------------------------------------------
-*/
diff --git a/src/psf/peops/adsr.cc b/src/psf/peops/adsr.cc
new file mode 100644
index 000000000000..d9deca5a7632
--- /dev/null
+++ b/src/psf/peops/adsr.cc
@@ -0,0 +1,618 @@
+/***************************************************************************
+ adsr.c - description
+ -------------------
+ begin : Wed May 15 2002
+ copyright : (C) 2002 by Pete Bernert
+ email : BlackDove at addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+//*************************************************************************//
+// History of changes:
+//
+// 2003/01/06 - Pete
+// - added Neill's ADSR timings
+//
+// 2002/05/15 - Pete
+// - generic cleanup for the Peops release
+//
+//*************************************************************************//
+
+#define _IN_ADSR
+
+// will be included from spu.c
+#ifdef _IN_SPU
+
+////////////////////////////////////////////////////////////////////////
+// ADSR func
+////////////////////////////////////////////////////////////////////////
+
+static u32 RateTable[160];
+
+static void InitADSR(void) // INIT ADSR
+{
+ u32 r,rs,rd;int i;
+
+ memset(RateTable,0,sizeof(u32)*160); // build the rate table according to Neill's rules (see at bottom of file)
+
+ r=3;rs=1;rd=0;
+
+ for(i=32;i<160;i++) // we start at pos 32 with the real values... everything before is 0
+ {
+ if(r<0x3FFFFFFF)
+ {
+ r+=rs;
+ rd++;if(rd==5) {rd=1;rs*=2;}
+ }
+ if(r>0x3FFFFFFF) r=0x3FFFFFFF;
+
+ RateTable[i]=r;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+static inline void StartADSR(int ch) // MIX ADSR
+{
+ s_chan[ch].ADSRX.lVolume=1; // and init some adsr vars
+ s_chan[ch].ADSRX.State=0;
+ s_chan[ch].ADSRX.EnvelopeVol=0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+static inline int MixADSR(int ch) // MIX ADSR
+{
+ static const int sexytable[8]=
+ {0,4,6,8,9,10,11,12};
+
+ if(s_chan[ch].bStop) // should be stopped:
+ { // do release
+ if(s_chan[ch].ADSRX.ReleaseModeExp)
+ {
+ s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18+32+sexytable[(s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7]];
+ }
+ else
+ {
+ s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x0C + 32];
+ }
+
+ if(s_chan[ch].ADSRX.EnvelopeVol<0)
+ {
+ s_chan[ch].ADSRX.EnvelopeVol=0;
+ s_chan[ch].bOn=0;
+ s_chan[ch].bNoise=0;
+ }
+
+ s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
+ return s_chan[ch].ADSRX.lVolume;
+ }
+ else // not stopped yet?
+ {
+ if(s_chan[ch].ADSRX.State==0) // -> attack
+ {
+ if(s_chan[ch].ADSRX.AttackModeExp)
+ {
+ if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
+ s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
+ else
+ s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x18 + 32];
+ }
+ else
+ {
+ s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
+ }
+
+ if(s_chan[ch].ADSRX.EnvelopeVol<0)
+ {
+ s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
+ s_chan[ch].ADSRX.State=1;
+ }
+
+ s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
+ return s_chan[ch].ADSRX.lVolume;
+ }
+ //--------------------------------------------------//
+ if(s_chan[ch].ADSRX.State==1) // -> decay
+ {
+ s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+32+sexytable[(s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7]];
+
+ if(s_chan[ch].ADSRX.EnvelopeVol<0) s_chan[ch].ADSRX.EnvelopeVol=0;
+ if(((s_chan[ch].ADSRX.EnvelopeVol>>27)&0xF) <= s_chan[ch].ADSRX.SustainLevel)
+ {
+ s_chan[ch].ADSRX.State=2;
+ }
+
+ s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
+ return s_chan[ch].ADSRX.lVolume;
+ }
+ //--------------------------------------------------//
+ if(s_chan[ch].ADSRX.State==2) // -> sustain
+ {
+ if(s_chan[ch].ADSRX.SustainIncrease)
+ {
+ if(s_chan[ch].ADSRX.SustainModeExp)
+ {
+ if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
+ s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
+ else
+ s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x18 + 32];
+ }
+ else
+ {
+ s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
+ }
+
+ if(s_chan[ch].ADSRX.EnvelopeVol<0)
+ {
+ s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
+ }
+ }
+ else
+ {
+ if(s_chan[ch].ADSRX.SustainModeExp)
+ s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B+32+sexytable[(s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7]];
+ else
+ s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x0F + 32];
+
+ if(s_chan[ch].ADSRX.EnvelopeVol<0)
+ {
+ s_chan[ch].ADSRX.EnvelopeVol=0;
+ }
+ }
+ s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
+ return s_chan[ch].ADSRX.lVolume;
+ }
+ }
+ return 0;
+}
+
+#endif
+
+/*
+James Higgs ADSR investigations:
+
+PSX SPU Envelope Timings
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+First, here is an extract from doomed's SPU doc, which explains the basics
+of the SPU "volume envelope":
+
+*** doomed doc extract start ***
+
+--------------------------------------------------------------------------
+Voices.
+--------------------------------------------------------------------------
+The SPU has 24 hardware voices. These voices can be used to reproduce sample
+data, noise or can be used as frequency modulator on the next voice.
+Each voice has it's own programmable ADSR envelope filter. The main volume
+can be programmed independently for left and right output.
+
+The ADSR envelope filter works as follows:
+Ar = Attack rate, which specifies the speed at which the volume increases
+ from zero to it's maximum value, as soon as the note on is given. The
+ slope can be set to lineair or exponential.
+Dr = Decay rate specifies the speed at which the volume decreases to the
+ sustain level. Decay is always decreasing exponentially.
+Sl = Sustain level, base level from which sustain starts.
+Sr = Sustain rate is the rate at which the volume of the sustained note
+ increases or decreases. This can be either lineair or exponential.
+Rr = Release rate is the rate at which the volume of the note decreases
+ as soon as the note off is given.
+
+ lvl |
+ ^ | /\Dr __
+ Sl _| _ / _ \__--- \
+ | / ---__ \ Rr
+ | /Ar Sr \ \
+ | / \\
+ |/___________________\________
+ ->time
+
+The overal volume can also be set to sweep up or down lineairly or
+exponentially from it's current value. This can be done seperately
+for left and right.
+
+Relevant SPU registers:
+-------------------------------------------------------------
+$1f801xx8 Attack/Decay/Sustain level
+bit |0f|0e 0d 0c 0b 0a 09 08|07 06 05 04|03 02 01 00|
+desc.|Am| Ar |Dr |Sl |
+
+Am 0 Attack mode Linear
+ 1 Exponential
+
+Ar 0-7f attack rate
+Dr 0-f decay rate
+Sl 0-f sustain level
+-------------------------------------------------------------
+$1f801xxa Sustain rate, Release Rate.
+bit |0f|0e|0d|0c 0b 0a 09 08 07 06|05|04 03 02 01 00|
+desc.|Sm|Sd| 0| Sr |Rm|Rr |
+
+Sm 0 sustain rate mode linear
+ 1 exponential
+Sd 0 sustain rate mode increase
+ 1 decrease
+Sr 0-7f Sustain Rate
+Rm 0 Linear decrease
+ 1 Exponential decrease
+Rr 0-1f Release Rate
+
+Note: decay mode is always Expontial decrease, and thus cannot
+be set.
+-------------------------------------------------------------
+$1f801xxc Current ADSR volume
+bit |0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00|
+desc.|ADSRvol |
+
+ADSRvol Returns the current envelope volume when
+ read.
+-- James' Note: return range: 0 -> 32767
+
+*** doomed doc extract end ***
+
+By using a small PSX proggie to visualise the envelope as it was played,
+the following results for envelope timing were obtained:
+
+1. Attack rate value (linear mode)
+
+ Attack value range: 0 -> 127
+
+ Value | 48 | 52 | 56 | 60 | 64 | 68 | 72 | | 80 |
+ -----------------------------------------------------------------
+ Frames | 11 | 21 | 42 | 84 | 169| 338| 676| |2890|
+
+ Note: frames is no. of PAL frames to reach full volume (100%
+ amplitude)
+
+ Hmm, noticing that the time taken to reach full volume doubles
+ every time we add 4 to our attack value, we know the equation is
+ of form:
+ frames = k * 2 ^ (value / 4)
+
+ (You may ponder about envelope generator hardware at this point,
+ or maybe not... :)
+
+ By substituting some stuff and running some checks, we get:
+
+ k = 0.00257 (close enuf)
+
+ therefore,
+ frames = 0.00257 * 2 ^ (value / 4)
+ If you just happen to be writing an emulator, then you can probably
+ use an equation like:
+
+ %volume_increase_per_tick = 1 / frames
+
+
+ ------------------------------------
+ Pete:
+ ms=((1<<(value>>2))*514)/10000
+ ------------------------------------
+
+2. Decay rate value (only has log mode)
+
+ Decay value range: 0 -> 15
+
+ Value | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
+ ------------------------------------------------
+ frames | | | | | 6 | 12 | 24 | 47 |
+
+ Note: frames here is no. of PAL frames to decay to 50% volume.
+
+ formula: frames = k * 2 ^ (value)
+
+ Substituting, we get: k = 0.00146
+
+ Further info on logarithmic nature:
+ frames to decay to sustain level 3 = 3 * frames to decay to
+ sustain level 9
+
+ Also no. of frames to 25% volume = roughly 1.85 * no. of frames to
+ 50% volume.
+
+ Frag it - just use linear approx.
+
+ ------------------------------------
+ Pete:
+ ms=((1<<value)*292)/10000
+ ------------------------------------
+
+
+3. Sustain rate value (linear mode)
+
+ Sustain rate range: 0 -> 127
+
+ Value | 48 | 52 | 56 | 60 | 64 | 68 | 72 |
+ -------------------------------------------
+ frames | 9 | 19 | 37 | 74 | 147| 293| 587|
+
+ Here, frames = no. of PAL frames for volume amplitude to go from 100%
+ to 0% (or vice-versa).
+
+ Same formula as for attack value, just a different value for k:
+
+ k = 0.00225
+
+ ie: frames = 0.00225 * 2 ^ (value / 4)
+
+ For emulation purposes:
+
+ %volume_increase_or_decrease_per_tick = 1 / frames
+
+ ------------------------------------
+ Pete:
+ ms=((1<<(value>>2))*450)/10000
+ ------------------------------------
+
+
+4. Release rate (linear mode)
+
+ Release rate range: 0 -> 31
+
+ Value | 13 | 14 | 15 | 16 | 17 |
+ ---------------------------------------------------------------
+ frames | 18 | 36 | 73 | 146| 292|
+
+ Here, frames = no. of PAL frames to decay from 100% vol to 0% vol
+ after "note-off" is triggered.
+
+ Formula: frames = k * 2 ^ (value)
+
+ And so: k = 0.00223
+
+ ------------------------------------
+ Pete:
+ ms=((1<<value)*446)/10000
+ ------------------------------------
+
+
+Other notes:
+
+Log stuff not figured out. You may get some clues from the "Decay rate"
+stuff above. For emu purposes it may not be important - use linear
+approx.
+
+To get timings in millisecs, multiply frames by 20.
+
+
+
+- James Higgs 17/6/2000
+james7780 at yahoo.com
+
+//---------------------------------------------------------------
+
+OLD adsr mixing according to james' rules... has to be called
+every one millisecond
+
+
+ i32 v,v2,lT,l1,l2,l3;
+
+ if(s_chan[ch].bStop) // psx wants to stop? -> release phase
+ {
+ if(s_chan[ch].ADSR.ReleaseVal!=0) // -> release not 0: do release (if 0: stop right now)
+ {
+ if(!s_chan[ch].ADSR.ReleaseVol) // --> release just started? set up the release stuff
+ {
+ s_chan[ch].ADSR.ReleaseStartTime=s_chan[ch].ADSR.lTime;
+ s_chan[ch].ADSR.ReleaseVol=s_chan[ch].ADSR.lVolume;
+ s_chan[ch].ADSR.ReleaseTime = // --> calc how long does it take to reach the wanted sus level
+ (s_chan[ch].ADSR.ReleaseTime*
+ s_chan[ch].ADSR.ReleaseVol)/1024;
+ }
+ // -> NO release exp mode used (yet)
+ v=s_chan[ch].ADSR.ReleaseVol; // -> get last volume
+ lT=s_chan[ch].ADSR.lTime- // -> how much time is past?
+ s_chan[ch].ADSR.ReleaseStartTime;
+ l1=s_chan[ch].ADSR.ReleaseTime;
+
+ if(lT<l1) // -> we still have to release
+ {
+ v=v-((v*lT)/l1); // --> calc new volume
+ }
+ else // -> release is over: now really stop that sample
+ {v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;}
+ }
+ else // -> release IS 0: release at once
+ {
+ v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;
+ }
+ }
+ else
+ {//--------------------------------------------------// not in release phase:
+ v=1024;
+ lT=s_chan[ch].ADSR.lTime;
+ l1=s_chan[ch].ADSR.AttackTime;
+
+ if(lT<l1) // attack
+ { // no exp mode used (yet)
+// if(s_chan[ch].ADSR.AttackModeExp)
+// {
+// v=(v*lT)/l1;
+// }
+// else
+ {
+ v=(v*lT)/l1;
+ }
+ if(v==0) v=1;
+ }
+ else // decay
+ { // should be exp, but who cares? ;)
+ l2=s_chan[ch].ADSR.DecayTime;
+ v2=s_chan[ch].ADSR.SustainLevel;
+
+ lT-=l1;
+ if(lT<l2)
+ {
+ v-=(((v-v2)*lT)/l2);
+ }
+ else // sustain
+ { // no exp mode used (yet)
+ l3=s_chan[ch].ADSR.SustainTime;
+ lT-=l2;
+ if(s_chan[ch].ADSR.SustainModeDec>0)
+ {
+ if(l3!=0) v2+=((v-v2)*lT)/l3;
+ else v2=v;
+ }
+ else
+ {
+ if(l3!=0) v2-=(v2*lT)/l3;
+ else v2=v;
+ }
+
+ if(v2>v) v2=v;
+ if(v2<=0) {v2=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;}
+
+ v=v2;
+ }
+ }
+ }
+
+ //----------------------------------------------------//
+ // ok, done for this channel, so increase time
+
+ s_chan[ch].ADSR.lTime+=1; // 1 = 1.020408f ms;
+
+ if(v>1024) v=1024; // adjust volume
+ if(v<0) v=0;
+ s_chan[ch].ADSR.lVolume=v; // store act volume
+
+ return v; // return the volume factor
+*/
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+
+/*
+-----------------------------------------------------------------------------
+Neill Corlett
+Playstation SPU envelope timing notes
+-----------------------------------------------------------------------------
+
+This is preliminary. This may be wrong. But the model described herein fits
+all of my experimental data, and it's just simple enough to sound right.
+
+ADSR envelope level ranges from 0x00000000 to 0x7FFFFFFF internally.
+The value returned by channel reg 0xC is (envelope_level>>16).
+
+Each sample, an increment or decrement value will be added to or
+subtracted from this envelope level.
+
+Create the rate log table. The values double every 4 entries.
+ entry #0 = 4
+
+ 4, 5, 6, 7,
+ 8,10,12,14,
+ 16,20,24,28, ...
+
+ entry #40 = 4096...
+ entry #44 = 8192...
+ entry #48 = 16384...
+ entry #52 = 32768...
+ entry #56 = 65536...
+
+increments and decrements are in terms of ratelogtable[n]
+n may exceed the table bounds (plan on n being between -32 and 127).
+table values are all clipped between 0x00000000 and 0x3FFFFFFF
+
+when you "voice on", the envelope is always fully reset.
+(yes, it may click. the real thing does this too.)
+
+envelope level begins at zero.
+
+each state happens for at least 1 cycle
+(transitions are not instantaneous)
+this may result in some oddness: if the decay rate is uberfast, it will cut
+the envelope from full down to half in one sample, potentially skipping over
+the sustain level
+
+ATTACK
+------
+- if the envelope level has overflowed past the max, clip to 0x7FFFFFFF and
+ proceed to DECAY.
+
+Linear attack mode:
+- line extends upward to 0x7FFFFFFF
+- increment per sample is ratelogtable[(Ar^0x7F)-0x10]
+
+Logarithmic attack mode:
+if envelope_level < 0x60000000:
+ - line extends upward to 0x60000000
+ - increment per sample is ratelogtable[(Ar^0x7F)-0x10]
+else:
+ - line extends upward to 0x7FFFFFFF
+ - increment per sample is ratelogtable[(Ar^0x7F)-0x18]
+
+DECAY
+-----
+- if ((envelope_level>>27)&0xF) <= Sl, proceed to SUSTAIN.
+ Do not clip to the sustain level.
+- current line ends at (envelope_level & 0x07FFFFFF)
+- decrement per sample depends on (envelope_level>>28)&0x7
+ 0: ratelogtable[(4*(Dr^0x1F))-0x18+0]
+ 1: ratelogtable[(4*(Dr^0x1F))-0x18+4]
+ 2: ratelogtable[(4*(Dr^0x1F))-0x18+6]
+ 3: ratelogtable[(4*(Dr^0x1F))-0x18+8]
+ 4: ratelogtable[(4*(Dr^0x1F))-0x18+9]
+ 5: ratelogtable[(4*(Dr^0x1F))-0x18+10]
+ 6: ratelogtable[(4*(Dr^0x1F))-0x18+11]
+ 7: ratelogtable[(4*(Dr^0x1F))-0x18+12]
+ (note that this is the same as the release rate formula, except that
+ decay rates 10-1F aren't possible... those would be slower in theory)
+
+SUSTAIN
+-------
+- no terminating condition except for voice off
+- Sd=0 (increase) behavior is identical to ATTACK for both log and linear.
+- Sd=1 (decrease) behavior:
+Linear sustain decrease:
+- line extends to 0x00000000
+- decrement per sample is ratelogtable[(Sr^0x7F)-0x0F]
+Logarithmic sustain decrease:
+- current line ends at (envelope_level & 0x07FFFFFF)
+- decrement per sample depends on (envelope_level>>28)&0x7
+ 0: ratelogtable[(Sr^0x7F)-0x1B+0]
+ 1: ratelogtable[(Sr^0x7F)-0x1B+4]
+ 2: ratelogtable[(Sr^0x7F)-0x1B+6]
+ 3: ratelogtable[(Sr^0x7F)-0x1B+8]
+ 4: ratelogtable[(Sr^0x7F)-0x1B+9]
+ 5: ratelogtable[(Sr^0x7F)-0x1B+10]
+ 6: ratelogtable[(Sr^0x7F)-0x1B+11]
+ 7: ratelogtable[(Sr^0x7F)-0x1B+12]
+
+RELEASE
+-------
+- if the envelope level has overflowed to negative, clip to 0 and QUIT.
+
+Linear release mode:
+- line extends to 0x00000000
+- decrement per sample is ratelogtable[(4*(Rr^0x1F))-0x0C]
+
+Logarithmic release mode:
+- line extends to (envelope_level & 0x0FFFFFFF)
+- decrement per sample depends on (envelope_level>>28)&0x7
+ 0: ratelogtable[(4*(Rr^0x1F))-0x18+0]
+ 1: ratelogtable[(4*(Rr^0x1F))-0x18+4]
+ 2: ratelogtable[(4*(Rr^0x1F))-0x18+6]
+ 3: ratelogtable[(4*(Rr^0x1F))-0x18+8]
+ 4: ratelogtable[(4*(Rr^0x1F))-0x18+9]
+ 5: ratelogtable[(4*(Rr^0x1F))-0x18+10]
+ 6: ratelogtable[(4*(Rr^0x1F))-0x18+11]
+ 7: ratelogtable[(4*(Rr^0x1F))-0x18+12]
+
+-----------------------------------------------------------------------------
+*/
diff --git a/src/psf/peops/dma.c b/src/psf/peops/dma.c
deleted file mode 100644
index 24994a0de2ff..000000000000
--- a/src/psf/peops/dma.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/***************************************************************************
- dma.c - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove at addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-//*************************************************************************//
-// History of changes:
-//
-// 2002/05/15 - Pete
-// - generic cleanup for the Peops release
-//
-//*************************************************************************//
-
-#include "../peops/stdafx.h"
-
-#define _IN_DMA
-
-extern uint32_t psx_ram[(2*1024*1024)/4];
-
-//#include "externals.h"
-////////////////////////////////////////////////////////////////////////
-// READ DMA (many values)
-////////////////////////////////////////////////////////////////////////
-
-void SPUreadDMAMem(u32 usPSXMem,int iSize)
-{
- int i;
- u16 *ram16 = (u16 *)&psx_ram[0];
-
- for(i=0;i<iSize;i++)
- {
- ram16[usPSXMem>>1]=spuMem[spuAddr>>1]; // spu addr got by writeregister
- usPSXMem+=2;
- spuAddr+=2; // inc spu addr
- if(spuAddr>0x7ffff) spuAddr=0; // wrap
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-// to investigate: do sound data updates by writedma affect spu
-// irqs? Will an irq be triggered, if new data is written to
-// the memory irq address?
-
-////////////////////////////////////////////////////////////////////////
-// WRITE DMA (many values)
-////////////////////////////////////////////////////////////////////////
-
-void SPUwriteDMAMem(u32 usPSXMem,int iSize)
-{
- int i;
- u16 *ram16 = (u16 *)&psx_ram[0];
-
- for(i=0;i<iSize;i++)
- {
-// printf("main RAM %x => SPU %x\n", usPSXMem, spuAddr);
- spuMem[spuAddr>>1] = ram16[usPSXMem>>1];
- usPSXMem+=2; // spu addr got by writeregister
- spuAddr+=2; // inc spu addr
- if(spuAddr>0x7ffff) spuAddr=0; // wrap
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
diff --git a/src/psf/peops/dma.cc b/src/psf/peops/dma.cc
new file mode 100644
index 000000000000..24994a0de2ff
--- /dev/null
+++ b/src/psf/peops/dma.cc
@@ -0,0 +1,80 @@
+/***************************************************************************
+ dma.c - description
+ -------------------
+ begin : Wed May 15 2002
+ copyright : (C) 2002 by Pete Bernert
+ email : BlackDove at addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+//*************************************************************************//
+// History of changes:
+//
+// 2002/05/15 - Pete
+// - generic cleanup for the Peops release
+//
+//*************************************************************************//
+
+#include "../peops/stdafx.h"
+
+#define _IN_DMA
+
+extern uint32_t psx_ram[(2*1024*1024)/4];
+
+//#include "externals.h"
+////////////////////////////////////////////////////////////////////////
+// READ DMA (many values)
+////////////////////////////////////////////////////////////////////////
+
+void SPUreadDMAMem(u32 usPSXMem,int iSize)
+{
+ int i;
+ u16 *ram16 = (u16 *)&psx_ram[0];
+
+ for(i=0;i<iSize;i++)
+ {
+ ram16[usPSXMem>>1]=spuMem[spuAddr>>1]; // spu addr got by writeregister
+ usPSXMem+=2;
+ spuAddr+=2; // inc spu addr
+ if(spuAddr>0x7ffff) spuAddr=0; // wrap
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+// to investigate: do sound data updates by writedma affect spu
+// irqs? Will an irq be triggered, if new data is written to
+// the memory irq address?
+
+////////////////////////////////////////////////////////////////////////
+// WRITE DMA (many values)
+////////////////////////////////////////////////////////////////////////
+
+void SPUwriteDMAMem(u32 usPSXMem,int iSize)
+{
+ int i;
+ u16 *ram16 = (u16 *)&psx_ram[0];
+
+ for(i=0;i<iSize;i++)
+ {
+// printf("main RAM %x => SPU %x\n", usPSXMem, spuAddr);
+ spuMem[spuAddr>>1] = ram16[usPSXMem>>1];
+ usPSXMem+=2; // spu addr got by writeregister
+ spuAddr+=2; // inc spu addr
+ if(spuAddr>0x7ffff) spuAddr=0; // wrap
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/psf/peops/registers.c b/src/psf/peops/registers.c
deleted file mode 100644
index bcafc8c07938..000000000000
--- a/src/psf/peops/registers.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/***************************************************************************
- registers.c - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove at addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-/* ChangeLog
-
- February 8, 2004 - xodnizel
- - Fixed setting of reverb volume. Just typecast val("u16") to s16.
- Also adjusted the normal channel volume to be one less than what it was before when the
- "phase invert" bit is set. I'm assuming it's just in two's complement.
-
- 2003/02/09 - kode54
- - removed &0x3fff from reverb volume registers, fixes a few games,
- hopefully won't be breaking anything
-
- 2003/01/19 - Pete
- - added Neill's reverb
-
- 2003/01/06 - Pete
- - added Neill's ADSR timings
-
- 2002/05/15 - Pete
- - generic cleanup for the Peops release
-
-*/
-
-#include "stdafx.h"
-
-#define _IN_REGISTERS
-
-#include "../peops/externals.h"
-#include "../peops/registers.h"
-#include "../peops/regs.h"
-
-static void SoundOn(int start,int end,u16 val);
-static void SoundOff(int start,int end,u16 val);
-static void FModOn(int start,int end,u16 val);
-static void NoiseOn(int start,int end,u16 val);
-static void SetVolumeLR(int right, u8 ch,s16 vol);
-static void SetPitch(int ch,u16 val);
-
-////////////////////////////////////////////////////////////////////////
-// WRITE REGISTERS: called by main emu
-////////////////////////////////////////////////////////////////////////
-
-void SPUwriteRegister(u32 reg, u16 val)
-{
- const u32 r=reg&0xfff;
- regArea[(r-0xc00)>>1] = val;
-
-// printf("SPUwrite: r %x val %x\n", r, val);
-
- if(r>=0x0c00 && r<0x0d80) // some channel info?
- {
- int ch=(r>>4)-0xc0; // calc channel
-
- //if(ch==20) printf("%08x: %04x\n",reg,val);
-
- switch(r&0x0f)
- {
- //------------------------------------------------// r volume
- case 0:
- SetVolumeLR(0,(u8)ch,val);
- break;
- //------------------------------------------------// l volume
- case 2:
- SetVolumeLR(1,(u8)ch,val);
- break;
- //------------------------------------------------// pitch
- case 4:
- SetPitch(ch,val);
- break;
- //------------------------------------------------// start
- case 6:
- s_chan[ch].pStart=spuMemC+((u32) val<<3);
- break;
- //------------------------------------------------// level with pre-calcs
- case 8:
- {
- const u32 lval=val; // DEBUG CHECK
- //---------------------------------------------//
- s_chan[ch].ADSRX.AttackModeExp=(lval&0x8000)?1:0;
- s_chan[ch].ADSRX.AttackRate=(lval>>8) & 0x007f;
- s_chan[ch].ADSRX.DecayRate=(lval>>4) & 0x000f;
- s_chan[ch].ADSRX.SustainLevel=lval & 0x000f;
- //---------------------------------------------//
- }
- break;
- //------------------------------------------------// adsr times with pre-calcs
- case 10:
- {
- const u32 lval=val; // DEBUG CHECK
-
- //----------------------------------------------//
- s_chan[ch].ADSRX.SustainModeExp = (lval&0x8000)?1:0;
- s_chan[ch].ADSRX.SustainIncrease= (lval&0x4000)?0:1;
- s_chan[ch].ADSRX.SustainRate = (lval>>6) & 0x007f;
- s_chan[ch].ADSRX.ReleaseModeExp = (lval&0x0020)?1:0;
- s_chan[ch].ADSRX.ReleaseRate = lval & 0x001f;
- //----------------------------------------------//
- }
- break;
- //------------------------------------------------// adsr volume... mmm have to investigate this
- //case 0xC:
- // break;
- //------------------------------------------------//
- case 0xE: // loop?
- s_chan[ch].pLoop=spuMemC+((u32) val<<3);
- s_chan[ch].bIgnoreLoop=1;
- break;
- //------------------------------------------------//
- }
- return;
- }
-
- switch(r)
- {
- //-------------------------------------------------//
- case H_SPUaddr:
- spuAddr = (u32) val<<3;
- break;
- //-------------------------------------------------//
- case H_SPUdata:
- spuMem[spuAddr>>1] = BFLIP16(val);
- spuAddr+=2;
- if(spuAddr>0x7ffff) spuAddr=0;
- break;
- //-------------------------------------------------//
- case H_SPUctrl:
- spuCtrl=val;
- break;
- //-------------------------------------------------//
- case H_SPUstat:
- spuStat=val & 0xf800;
- break;
- //-------------------------------------------------//
- case H_SPUReverbAddr:
- if(val==0xFFFF || val<=0x200)
- {rvb.StartAddr=rvb.CurrAddr=0;}
- else
- {
- const s32 iv=(u32)val<<2;
- if(rvb.StartAddr!=iv)
- {
- rvb.StartAddr=(u32)val<<2;
- rvb.CurrAddr=rvb.StartAddr;
- }
- }
- break;
- //-------------------------------------------------//
- case H_SPUirqAddr:
- spuIrq = val;
- pSpuIrq=spuMemC+((u32) val<<3);
- break;
- //-------------------------------------------------//
- /* Volume settings appear to be at least 15-bit unsigned in this case.
- Definitely NOT 15-bit signed. Probably 16-bit signed, so s16 type cast.
- Check out "Chrono Cross: Shadow's End Forest"
- */
- case H_SPUrvolL:
- rvb.VolLeft=(s16)val;
- //printf("%d\n",val);
- break;
- //-------------------------------------------------//
- case H_SPUrvolR:
- rvb.VolRight=(s16)val;
- //printf("%d\n",val);
- break;
- //-------------------------------------------------//
-
-/*
- case H_ExtLeft:
- //auxprintf("EL %d\n",val);
- break;
- //-------------------------------------------------//
- case H_ExtRight:
- //auxprintf("ER %d\n",val);
- break;
- //-------------------------------------------------//
- case H_SPUmvolL:
- //auxprintf("ML %d\n",val);
- break;
- //-------------------------------------------------//
- case H_SPUmvolR:
- //auxprintf("MR %d\n",val);
- break;
- //-------------------------------------------------//
- case H_SPUMute1:
- //printf("M0 %04x\n",val);
- break;
- //-------------------------------------------------//
- case H_SPUMute2:
- // printf("M1 %04x\n",val);
- break;
-*/
- //-------------------------------------------------//
- case H_SPUon1:
- SoundOn(0,16,val);
- break;
- //-------------------------------------------------//
- case H_SPUon2:
- // printf("Boop: %08x: %04x\n",reg,val);
- SoundOn(16,24,val);
- break;
- //-------------------------------------------------//
- case H_SPUoff1:
- SoundOff(0,16,val);
- break;
- //-------------------------------------------------//
- case H_SPUoff2:
- SoundOff(16,24,val);
- // printf("Boop: %08x: %04x\n",reg,val);
- break;
- //-------------------------------------------------//
- case H_FMod1:
- FModOn(0,16,val);
- break;
- //-------------------------------------------------//
- case H_FMod2:
- FModOn(16,24,val);
- break;
- //-------------------------------------------------//
- case H_Noise1:
- NoiseOn(0,16,val);
- break;
- //-------------------------------------------------//
- case H_Noise2:
- NoiseOn(16,24,val);
- break;
- //-------------------------------------------------//
- case H_RVBon1:
- rvb.Enabled&=~0xFFFF;
- rvb.Enabled|=val;
- break;
-
- //-------------------------------------------------//
- case H_RVBon2:
- rvb.Enabled&=0xFFFF;
- rvb.Enabled|=val<<16;
- break;
-
- //-------------------------------------------------//
- case H_Reverb+0:
- rvb.FB_SRC_A=val;
- break;
-
- case H_Reverb+2 : rvb.FB_SRC_B=(s16)val; break;
- case H_Reverb+4 : rvb.IIR_ALPHA=(s16)val; break;
- case H_Reverb+6 : rvb.ACC_COEF_A=(s16)val; break;
- case H_Reverb+8 : rvb.ACC_COEF_B=(s16)val; break;
- case H_Reverb+10 : rvb.ACC_COEF_C=(s16)val; break;
- case H_Reverb+12 : rvb.ACC_COEF_D=(s16)val; break;
- case H_Reverb+14 : rvb.IIR_COEF=(s16)val; break;
- case H_Reverb+16 : rvb.FB_ALPHA=(s16)val; break;
- case H_Reverb+18 : rvb.FB_X=(s16)val; break;
- case H_Reverb+20 : rvb.IIR_DEST_A0=(s16)val; break;
- case H_Reverb+22 : rvb.IIR_DEST_A1=(s16)val; break;
- case H_Reverb+24 : rvb.ACC_SRC_A0=(s16)val; break;
- case H_Reverb+26 : rvb.ACC_SRC_A1=(s16)val; break;
- case H_Reverb+28 : rvb.ACC_SRC_B0=(s16)val; break;
- case H_Reverb+30 : rvb.ACC_SRC_B1=(s16)val; break;
- case H_Reverb+32 : rvb.IIR_SRC_A0=(s16)val; break;
- case H_Reverb+34 : rvb.IIR_SRC_A1=(s16)val; break;
- case H_Reverb+36 : rvb.IIR_DEST_B0=(s16)val; break;
- case H_Reverb+38 : rvb.IIR_DEST_B1=(s16)val; break;
- case H_Reverb+40 : rvb.ACC_SRC_C0=(s16)val; break;
- case H_Reverb+42 : rvb.ACC_SRC_C1=(s16)val; break;
- case H_Reverb+44 : rvb.ACC_SRC_D0=(s16)val; break;
- case H_Reverb+46 : rvb.ACC_SRC_D1=(s16)val; break;
- case H_Reverb+48 : rvb.IIR_SRC_B1=(s16)val; break;
- case H_Reverb+50 : rvb.IIR_SRC_B0=(s16)val; break;
- case H_Reverb+52 : rvb.MIX_DEST_A0=(s16)val; break;
- case H_Reverb+54 : rvb.MIX_DEST_A1=(s16)val; break;
- case H_Reverb+56 : rvb.MIX_DEST_B0=(s16)val; break;
- case H_Reverb+58 : rvb.MIX_DEST_B1=(s16)val; break;
- case H_Reverb+60 : rvb.IN_COEF_L=(s16)val; break;
- case H_Reverb+62 : rvb.IN_COEF_R=(s16)val; break;
- }
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// READ REGISTER: called by main emu
-////////////////////////////////////////////////////////////////////////
-
-u16 SPUreadRegister(u32 reg)
-{
- const u32 r=reg&0xfff;
-
- if(r>=0x0c00 && r<0x0d80)
- {
- switch(r&0x0f)
- {
- case 0xC: // get adsr vol
- {
- const int ch=(r>>4)-0xc0;
- if(s_chan[ch].bNew) return 1; // we are started, but not processed? return 1
- if(s_chan[ch].ADSRX.lVolume && // same here... we haven't decoded one sample yet, so no envelope yet. return 1 as well
- !s_chan[ch].ADSRX.EnvelopeVol)
- return 1;
- return (u16)(s_chan[ch].ADSRX.EnvelopeVol>>16);
- }
-
- case 0xE: // get loop address
- {
- const int ch=(r>>4)-0xc0;
- if(s_chan[ch].pLoop==NULL) return 0;
- return (u16)((s_chan[ch].pLoop-spuMemC)>>3);
- }
- }
- }
-
- switch(r)
- {
- case H_SPUctrl:
- return spuCtrl;
-
- case H_SPUstat:
- return spuStat;
-
- case H_SPUaddr:
- return (u16)(spuAddr>>3);
-
- case H_SPUdata:
- {
- u16 s=BFLIP16(spuMem[spuAddr>>1]);
- spuAddr+=2;
- if(spuAddr>0x7ffff) spuAddr=0;
- return s;
- }
-
- case H_SPUirqAddr:
- return spuIrq;
-
- //case H_SPUIsOn1:
- // return IsSoundOn(0,16);
-
- //case H_SPUIsOn2:
- // return IsSoundOn(16,24);
-
- }
-
- return regArea[(r-0xc00)>>1];
-}
-
-////////////////////////////////////////////////////////////////////////
-// SOUND ON register write
-////////////////////////////////////////////////////////////////////////
-
-static void SoundOn(int start,int end,u16 val) // SOUND ON PSX COMAND
-{
- int ch;
-
- for(ch=start;ch<end;ch++,val>>=1) // loop channels
- {
- if((val&1) && s_chan[ch].pStart) // mmm... start has to be set before key on !?!
- {
- s_chan[ch].bIgnoreLoop=0;
- s_chan[ch].bNew=1;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// SOUND OFF register write
-////////////////////////////////////////////////////////////////////////
-
-static void SoundOff(int start,int end,u16 val) // SOUND OFF PSX COMMAND
-{
- int ch;
- for(ch=start;ch<end;ch++,val>>=1) // loop channels
- {
- if(val&1) // && s_chan[i].bOn) mmm...
- {
- s_chan[ch].bStop=1;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// FMOD register write
-////////////////////////////////////////////////////////////////////////
-
-static void FModOn(int start,int end,u16 val) // FMOD ON PSX COMMAND
-{
- int ch;
-
- for(ch=start;ch<end;ch++,val>>=1) // loop channels
- {
- if(val&1) // -> fmod on/off
- {
- if(ch>0)
- {
- s_chan[ch].bFMod=1; // --> sound channel
- s_chan[ch-1].bFMod=2; // --> freq channel
- }
- }
- else
- {
- s_chan[ch].bFMod=0; // --> turn off fmod
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// NOISE register write
-////////////////////////////////////////////////////////////////////////
-
-static void NoiseOn(int start,int end,u16 val) // NOISE ON PSX COMMAND
-{
- int ch;
-
- for(ch=start;ch<end;ch++,val>>=1) // loop channels
- {
- if(val&1) // -> noise on/off
- {
- s_chan[ch].bNoise=1;
- }
- else
- {
- s_chan[ch].bNoise=0;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// LEFT VOLUME register write
-////////////////////////////////////////////////////////////////////////
-
-// please note: sweep is wrong.
-
-static void SetVolumeLR(int right, u8 ch,s16 vol) // LEFT VOLUME
-{
- //if(vol&0xc000)
- //printf("%d %08x\n",right,vol);
- if(right)
- s_chan[ch].iRightVolRaw=vol;
- else
- s_chan[ch].iLeftVolRaw=vol;
-
- if(vol&0x8000) // sweep?
- {
- s16 sInc=1; // -> sweep up?
- if(vol&0x2000) sInc=-1; // -> or down?
- if(vol&0x1000) vol^=0xffff; // -> mmm... phase inverted? have to investigate this
- vol=((vol&0x7f)+1)/2; // -> sweep: 0..127 -> 0..64
- vol+=vol/(2*sInc); // -> HACK: we don't sweep right now, so we just raise/lower the volume by the half!
- vol*=128;
- vol&=0x3fff;
- //puts("Sweep");
- }
- else // no sweep:
- {
- if(vol&0x4000)
- vol=(vol&0x3FFF)-0x4000;
- else
- vol&=0x3FFF;
-
- //if(vol&0x4000) // -> mmm... phase inverted? have to investigate this
- // vol=0-(0x3fff-(vol&0x3fff));
- //else
- // vol&=0x3fff;
- }
- if(right)
- s_chan[ch].iRightVolume=vol;
- else
- s_chan[ch].iLeftVolume=vol; // store volume
-}
-
-////////////////////////////////////////////////////////////////////////
-// PITCH register write
-////////////////////////////////////////////////////////////////////////
-
-static void SetPitch(int ch,u16 val) // SET PITCH
-{
- int NP;
- if(val>0x3fff) NP=0x3fff; // get pitch val
- else NP=val;
-
- s_chan[ch].iRawPitch=NP;
-
- NP=(44100L*NP)/4096L; // calc frequency
- if(NP<1) NP=1; // some security
- s_chan[ch].iActFreq=NP; // store frequency
-}
diff --git a/src/psf/peops/registers.cc b/src/psf/peops/registers.cc
new file mode 100644
index 000000000000..0651a838475f
--- /dev/null
+++ b/src/psf/peops/registers.cc
@@ -0,0 +1,499 @@
+/***************************************************************************
+ registers.c - description
+ -------------------
+ begin : Wed May 15 2002
+ copyright : (C) 2002 by Pete Bernert
+ email : BlackDove at addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+/* ChangeLog
+
+ February 8, 2004 - xodnizel
+ - Fixed setting of reverb volume. Just typecast val("u16") to s16.
+ Also adjusted the normal channel volume to be one less than what it was before when the
+ "phase invert" bit is set. I'm assuming it's just in two's complement.
+
+ 2003/02/09 - kode54
+ - removed &0x3fff from reverb volume registers, fixes a few games,
+ hopefully won't be breaking anything
+
+ 2003/01/19 - Pete
+ - added Neill's reverb
+
+ 2003/01/06 - Pete
+ - added Neill's ADSR timings
+
+ 2002/05/15 - Pete
+ - generic cleanup for the Peops release
+
+*/
+
+#include "stdafx.h"
+
+#define _IN_REGISTERS
+
+#include "../peops/externals.h"
+#include "../peops/registers.h"
+#include "../peops/regs.h"
+
+static void SoundOn(int start,int end,u16 val);
+static void SoundOff(int start,int end,u16 val);
+static void FModOn(int start,int end,u16 val);
+static void NoiseOn(int start,int end,u16 val);
+static void SetVolumeLR(int right, u8 ch,s16 vol);
+static void SetPitch(int ch,u16 val);
+
+////////////////////////////////////////////////////////////////////////
+// WRITE REGISTERS: called by main emu
+////////////////////////////////////////////////////////////////////////
+
+void SPUwriteRegister(u32 reg, u16 val)
+{
+ const u32 r=reg&0xfff;
+ regArea[(r-0xc00)>>1] = val;
+
+// printf("SPUwrite: r %x val %x\n", r, val);
+
+ if(r>=0x0c00 && r<0x0d80) // some channel info?
+ {
+ int ch=(r>>4)-0xc0; // calc channel
+
+ //if(ch==20) printf("%08x: %04x\n",reg,val);
+
+ switch(r&0x0f)
+ {
+ //------------------------------------------------// r volume
+ case 0:
+ SetVolumeLR(0,(u8)ch,val);
+ break;
+ //------------------------------------------------// l volume
+ case 2:
+ SetVolumeLR(1,(u8)ch,val);
+ break;
+ //------------------------------------------------// pitch
+ case 4:
+ SetPitch(ch,val);
+ break;
+ //------------------------------------------------// start
+ case 6:
+ s_chan[ch].pStart=spuMemC+((u32) val<<3);
+ break;
+ //------------------------------------------------// level with pre-calcs
+ case 8:
+ {
+ const u32 lval=val; // DEBUG CHECK
+ //---------------------------------------------//
+ s_chan[ch].ADSRX.AttackModeExp=(lval&0x8000)?1:0;
+ s_chan[ch].ADSRX.AttackRate=(lval>>8) & 0x007f;
+ s_chan[ch].ADSRX.DecayRate=(lval>>4) & 0x000f;
+ s_chan[ch].ADSRX.SustainLevel=lval & 0x000f;
+ //---------------------------------------------//
+ }
+ break;
+ //------------------------------------------------// adsr times with pre-calcs
+ case 10:
+ {
+ const u32 lval=val; // DEBUG CHECK
+
+ //----------------------------------------------//
+ s_chan[ch].ADSRX.SustainModeExp = (lval&0x8000)?1:0;
+ s_chan[ch].ADSRX.SustainIncrease= (lval&0x4000)?0:1;
+ s_chan[ch].ADSRX.SustainRate = (lval>>6) & 0x007f;
+ s_chan[ch].ADSRX.ReleaseModeExp = (lval&0x0020)?1:0;
+ s_chan[ch].ADSRX.ReleaseRate = lval & 0x001f;
+ //----------------------------------------------//
+ }
+ break;
+ //------------------------------------------------// adsr volume... mmm have to investigate this
+ //case 0xC:
+ // break;
+ //------------------------------------------------//
+ case 0xE: // loop?
+ s_chan[ch].pLoop=spuMemC+((u32) val<<3);
+ s_chan[ch].bIgnoreLoop=1;
+ break;
+ //------------------------------------------------//
+ }
+ return;
+ }
+
+ switch(r)
+ {
+ //-------------------------------------------------//
+ case H_SPUaddr:
+ spuAddr = (u32) val<<3;
+ break;
+ //-------------------------------------------------//
+ case H_SPUdata:
+ spuMem[spuAddr>>1] = BFLIP16(val);
+ spuAddr+=2;
+ if(spuAddr>0x7ffff) spuAddr=0;
+ break;
+ //-------------------------------------------------//
+ case H_SPUctrl:
+ spuCtrl=val;
+ break;
+ //-------------------------------------------------//
+ case H_SPUstat:
+ spuStat=val & 0xf800;
+ break;
+ //-------------------------------------------------//
+ case H_SPUReverbAddr:
+ if(val==0xFFFF || val<=0x200)
+ {rvb.StartAddr=rvb.CurrAddr=0;}
+ else
+ {
+ const s32 iv=(u32)val<<2;
+ if(rvb.StartAddr!=iv)
+ {
+ rvb.StartAddr=(u32)val<<2;
+ rvb.CurrAddr=rvb.StartAddr;
+ }
+ }
+ break;
+ //-------------------------------------------------//
+ case H_SPUirqAddr:
+ spuIrq = val;
+ pSpuIrq=spuMemC+((u32) val<<3);
+ break;
+ //-------------------------------------------------//
+ /* Volume settings appear to be at least 15-bit unsigned in this case.
+ Definitely NOT 15-bit signed. Probably 16-bit signed, so s16 type cast.
+ Check out "Chrono Cross: Shadow's End Forest"
+ */
+ case H_SPUrvolL:
+ rvb.VolLeft=(s16)val;
+ //printf("%d\n",val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUrvolR:
+ rvb.VolRight=(s16)val;
+ //printf("%d\n",val);
+ break;
+ //-------------------------------------------------//
+
+/*
+ case H_ExtLeft:
+ //auxprintf("EL %d\n",val);
+ break;
+ //-------------------------------------------------//
+ case H_ExtRight:
+ //auxprintf("ER %d\n",val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUmvolL:
+ //auxprintf("ML %d\n",val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUmvolR:
+ //auxprintf("MR %d\n",val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUMute1:
+ //printf("M0 %04x\n",val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUMute2:
+ // printf("M1 %04x\n",val);
+ break;
+*/
+ //-------------------------------------------------//
+ case H_SPUon1:
+ SoundOn(0,16,val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUon2:
+ // printf("Boop: %08x: %04x\n",reg,val);
+ SoundOn(16,24,val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUoff1:
+ SoundOff(0,16,val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUoff2:
+ SoundOff(16,24,val);
+ // printf("Boop: %08x: %04x\n",reg,val);
+ break;
+ //-------------------------------------------------//
+ case H_FMod1:
+ FModOn(0,16,val);
+ break;
+ //-------------------------------------------------//
+ case H_FMod2:
+ FModOn(16,24,val);
+ break;
+ //-------------------------------------------------//
+ case H_Noise1:
+ NoiseOn(0,16,val);
+ break;
+ //-------------------------------------------------//
+ case H_Noise2:
+ NoiseOn(16,24,val);
+ break;
+ //-------------------------------------------------//
+ case H_RVBon1:
+ rvb.Enabled&=~0xFFFF;
+ rvb.Enabled|=val;
+ break;
+
+ //-------------------------------------------------//
+ case H_RVBon2:
+ rvb.Enabled&=0xFFFF;
+ rvb.Enabled|=val<<16;
+ break;
+
+ //-------------------------------------------------//
+ case H_Reverb+0:
+ rvb.FB_SRC_A=val;
+ break;
+
+ case H_Reverb+2 : rvb.FB_SRC_B=(s16)val; break;
+ case H_Reverb+4 : rvb.IIR_ALPHA=(s16)val; break;
+ case H_Reverb+6 : rvb.ACC_COEF_A=(s16)val; break;
+ case H_Reverb+8 : rvb.ACC_COEF_B=(s16)val; break;
+ case H_Reverb+10 : rvb.ACC_COEF_C=(s16)val; break;
+ case H_Reverb+12 : rvb.ACC_COEF_D=(s16)val; break;
+ case H_Reverb+14 : rvb.IIR_COEF=(s16)val; break;
+ case H_Reverb+16 : rvb.FB_ALPHA=(s16)val; break;
+ case H_Reverb+18 : rvb.FB_X=(s16)val; break;
+ case H_Reverb+20 : rvb.IIR_DEST_A0=(s16)val; break;
+ case H_Reverb+22 : rvb.IIR_DEST_A1=(s16)val; break;
+ case H_Reverb+24 : rvb.ACC_SRC_A0=(s16)val; break;
+ case H_Reverb+26 : rvb.ACC_SRC_A1=(s16)val; break;
+ case H_Reverb+28 : rvb.ACC_SRC_B0=(s16)val; break;
+ case H_Reverb+30 : rvb.ACC_SRC_B1=(s16)val; break;
+ case H_Reverb+32 : rvb.IIR_SRC_A0=(s16)val; break;
+ case H_Reverb+34 : rvb.IIR_SRC_A1=(s16)val; break;
+ case H_Reverb+36 : rvb.IIR_DEST_B0=(s16)val; break;
+ case H_Reverb+38 : rvb.IIR_DEST_B1=(s16)val; break;
+ case H_Reverb+40 : rvb.ACC_SRC_C0=(s16)val; break;
+ case H_Reverb+42 : rvb.ACC_SRC_C1=(s16)val; break;
+ case H_Reverb+44 : rvb.ACC_SRC_D0=(s16)val; break;
+ case H_Reverb+46 : rvb.ACC_SRC_D1=(s16)val; break;
+ case H_Reverb+48 : rvb.IIR_SRC_B1=(s16)val; break;
+ case H_Reverb+50 : rvb.IIR_SRC_B0=(s16)val; break;
+ case H_Reverb+52 : rvb.MIX_DEST_A0=(s16)val; break;
+ case H_Reverb+54 : rvb.MIX_DEST_A1=(s16)val; break;
+ case H_Reverb+56 : rvb.MIX_DEST_B0=(s16)val; break;
+ case H_Reverb+58 : rvb.MIX_DEST_B1=(s16)val; break;
+ case H_Reverb+60 : rvb.IN_COEF_L=(s16)val; break;
+ case H_Reverb+62 : rvb.IN_COEF_R=(s16)val; break;
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// READ REGISTER: called by main emu
+////////////////////////////////////////////////////////////////////////
+
+u16 SPUreadRegister(u32 reg)
+{
+ const u32 r=reg&0xfff;
+
+ if(r>=0x0c00 && r<0x0d80)
+ {
+ switch(r&0x0f)
+ {
+ case 0xC: // get adsr vol
+ {
+ const int ch=(r>>4)-0xc0;
+ if(s_chan[ch].bNew) return 1; // we are started, but not processed? return 1
+ if(s_chan[ch].ADSRX.lVolume && // same here... we haven't decoded one sample yet, so no envelope yet. return 1 as well
+ !s_chan[ch].ADSRX.EnvelopeVol)
+ return 1;
+ return (u16)(s_chan[ch].ADSRX.EnvelopeVol>>16);
+ }
+
+ case 0xE: // get loop address
+ {
+ const int ch=(r>>4)-0xc0;
+ if(s_chan[ch].pLoop==nullptr) return 0;
+ return (u16)((s_chan[ch].pLoop-spuMemC)>>3);
+ }
+ }
+ }
+
+ switch(r)
+ {
+ case H_SPUctrl:
+ return spuCtrl;
+
+ case H_SPUstat:
+ return spuStat;
+
+ case H_SPUaddr:
+ return (u16)(spuAddr>>3);
+
+ case H_SPUdata:
+ {
+ u16 s=BFLIP16(spuMem[spuAddr>>1]);
+ spuAddr+=2;
+ if(spuAddr>0x7ffff) spuAddr=0;
+ return s;
+ }
+
+ case H_SPUirqAddr:
+ return spuIrq;
+
+ //case H_SPUIsOn1:
+ // return IsSoundOn(0,16);
+
+ //case H_SPUIsOn2:
+ // return IsSoundOn(16,24);
+
+ }
+
+ return regArea[(r-0xc00)>>1];
+}
+
+////////////////////////////////////////////////////////////////////////
+// SOUND ON register write
+////////////////////////////////////////////////////////////////////////
+
+static void SoundOn(int start,int end,u16 val) // SOUND ON PSX COMAND
+{
+ int ch;
+
+ for(ch=start;ch<end;ch++,val>>=1) // loop channels
+ {
+ if((val&1) && s_chan[ch].pStart) // mmm... start has to be set before key on !?!
+ {
+ s_chan[ch].bIgnoreLoop=0;
+ s_chan[ch].bNew=1;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// SOUND OFF register write
+////////////////////////////////////////////////////////////////////////
+
+static void SoundOff(int start,int end,u16 val) // SOUND OFF PSX COMMAND
+{
+ int ch;
+ for(ch=start;ch<end;ch++,val>>=1) // loop channels
+ {
+ if(val&1) // && s_chan[i].bOn) mmm...
+ {
+ s_chan[ch].bStop=1;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// FMOD register write
+////////////////////////////////////////////////////////////////////////
+
+static void FModOn(int start,int end,u16 val) // FMOD ON PSX COMMAND
+{
+ int ch;
+
+ for(ch=start;ch<end;ch++,val>>=1) // loop channels
+ {
+ if(val&1) // -> fmod on/off
+ {
+ if(ch>0)
+ {
+ s_chan[ch].bFMod=1; // --> sound channel
+ s_chan[ch-1].bFMod=2; // --> freq channel
+ }
+ }
+ else
+ {
+ s_chan[ch].bFMod=0; // --> turn off fmod
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// NOISE register write
+////////////////////////////////////////////////////////////////////////
+
+static void NoiseOn(int start,int end,u16 val) // NOISE ON PSX COMMAND
+{
+ int ch;
+
+ for(ch=start;ch<end;ch++,val>>=1) // loop channels
+ {
+ if(val&1) // -> noise on/off
+ {
+ s_chan[ch].bNoise=1;
+ }
+ else
+ {
+ s_chan[ch].bNoise=0;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// LEFT VOLUME register write
+////////////////////////////////////////////////////////////////////////
+
+// please note: sweep is wrong.
+
+static void SetVolumeLR(int right, u8 ch,s16 vol) // LEFT VOLUME
+{
+ //if(vol&0xc000)
+ //printf("%d %08x\n",right,vol);
+ if(right)
+ s_chan[ch].iRightVolRaw=vol;
+ else
+ s_chan[ch].iLeftVolRaw=vol;
+
+ if(vol&0x8000) // sweep?
+ {
+ s16 sInc=1; // -> sweep up?
+ if(vol&0x2000) sInc=-1; // -> or down?
+ if(vol&0x1000) vol^=0xffff; // -> mmm... phase inverted? have to investigate this
+ vol=((vol&0x7f)+1)/2; // -> sweep: 0..127 -> 0..64
+ vol+=vol/(2*sInc); // -> HACK: we don't sweep right now, so we just raise/lower the volume by the half!
+ vol*=128;
+ vol&=0x3fff;
+ //puts("Sweep");
+ }
+ else // no sweep:
+ {
+ if(vol&0x4000)
+ vol=(vol&0x3FFF)-0x4000;
+ else
+ vol&=0x3FFF;
+
+ //if(vol&0x4000) // -> mmm... phase inverted? have to investigate this
+ // vol=0-(0x3fff-(vol&0x3fff));
+ //else
+ // vol&=0x3fff;
+ }
+ if(right)
+ s_chan[ch].iRightVolume=vol;
+ else
+ s_chan[ch].iLeftVolume=vol; // store volume
+}
+
+////////////////////////////////////////////////////////////////////////
+// PITCH register write
+////////////////////////////////////////////////////////////////////////
+
+static void SetPitch(int ch,u16 val) // SET PITCH
+{
+ int NP;
+ if(val>0x3fff) NP=0x3fff; // get pitch val
+ else NP=val;
+
+ s_chan[ch].iRawPitch=NP;
+
+ NP=(44100L*NP)/4096L; // calc frequency
+ if(NP<1) NP=1; // some security
+ s_chan[ch].iActFreq=NP; // store frequency
+}
diff --git a/src/psf/peops/reverb.c b/src/psf/peops/reverb.c
deleted file mode 100644
index 681d56c55fbf..000000000000
--- a/src/psf/peops/reverb.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/***************************************************************************
- reverb.c - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove at addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-//*************************************************************************//
-// History of changes:
-//
-// 2003/03/17 - xodnizel
-// - Implemented Neill's 44.1Khz-22050Hz downsampling data
-// I also need to check if the ~4 sample delay doesn't screw any sounds
-// up by making things too out of phase. It could be fixed easily(elsewhere).
-//
-// 2003/01/19 - Pete
-// - added Neill's reverb (see at the end of file)
-//
-// 2002/12/26 - Pete
-// - adjusted reverb handling
-//
-// 2002/08/14 - Pete
-// - added extra reverb
-//
-// 2002/05/15 - Pete
-// - generic cleanup for the Peops release
-//
-//*************************************************************************//
-
-#define _IN_REVERB
-
-// will be included from spu.c
-#ifdef _IN_SPU
-
-////////////////////////////////////////////////////////////////////////
-// globals
-////////////////////////////////////////////////////////////////////////
-
-// REVERB info and timing vars...
-
-////////////////////////////////////////////////////////////////////////
-
-static inline s64 g_buffer(int iOff) // get_buffer content helper: takes care about wraps
-{
- s16 * p=(s16 *)spuMem;
- iOff=(iOff*4)+rvb.CurrAddr;
- while(iOff>0x3FFFF) iOff=rvb.StartAddr+(iOff-0x40000);
- while(iOff<rvb.StartAddr) iOff=0x3ffff-(rvb.StartAddr-iOff);
- return (int)(s16)BFLIP16(*(p+iOff));
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void s_buffer(int iOff,int iVal) // set_buffer content helper: takes care about wraps and clipping
-{
- s16 * p=(s16 *)spuMem;
- iOff=(iOff*4)+rvb.CurrAddr;
- while(iOff>0x3FFFF) iOff=rvb.StartAddr+(iOff-0x40000);
- while(iOff<rvb.StartAddr) iOff=0x3ffff-(rvb.StartAddr-iOff);
- if(iVal<-32768L) iVal=-32768L;
- if(iVal>32767L) iVal=32767L;
- *(p+iOff)=(s16)BFLIP16((s16)iVal);
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void s_buffer1(int iOff,int iVal) // set_buffer (+1 sample) content helper: takes care about wraps and clipping
-{
- s16 * p=(s16 *)spuMem;
- iOff=(iOff*4)+rvb.CurrAddr+1;
- while(iOff>0x3FFFF) iOff=rvb.StartAddr+(iOff-0x40000);
- while(iOff<rvb.StartAddr) iOff=0x3ffff-(rvb.StartAddr-iOff);
- if(iVal<-32768L) iVal=-32768L;if(iVal>32767L) iVal=32767L;
- *(p+iOff)=(s16)BFLIP16((s16)iVal);
-}
-
-static inline void MixREVERBLeftRight(s32 *oleft, s32 *oright, s32 inleft, s32 inright)
-{
- static s32 downbuf[2][8];
- static s32 upbuf[2][8];
- static int dbpos=0,ubpos=0;
- static s32 downcoeffs[8]={ /* Symmetry is sexy. */
- 1283,5344,10895,15243,
- 15243,10895,5344,1283
- };
- int x;
-
- if(!rvb.StartAddr) // reverb is off
- {
- rvb.iRVBLeft=rvb.iRVBRight=0;
- return;
- }
-
- //if(inleft<-32767 || inleft>32767) printf("%d\n",inleft);
- //if(inright<-32767 || inright>32767) printf("%d\n",inright);
- downbuf[0][dbpos]=inleft;
- downbuf[1][dbpos]=inright;
- dbpos=(dbpos+1)&7;
-
- if(dbpos&1) // we work on every second left value: downsample to 22 khz
- {
- if(spuCtrl&0x80) // -> reverb on? oki
- {
- int ACC0,ACC1,FB_A0,FB_A1,FB_B0,FB_B1;
- s32 INPUT_SAMPLE_L=0;
- s32 INPUT_SAMPLE_R=0;
-
- for(x=0;x<8;x++)
- {
- INPUT_SAMPLE_L+=(downbuf[0][(dbpos+x)&7]*downcoeffs[x])>>8; /* Lose insignificant
- digits to prevent
- overflow(check this) */
- INPUT_SAMPLE_R+=(downbuf[1][(dbpos+x)&7]*downcoeffs[x])>>8;
- }
-
- INPUT_SAMPLE_L>>=(16-8);
- INPUT_SAMPLE_R>>=(16-8);
- {
- const s64 IIR_INPUT_A0 = ((g_buffer(rvb.IIR_SRC_A0) * rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_L * rvb.IN_COEF_L)>>15);
- const s64 IIR_INPUT_A1 = ((g_buffer(rvb.IIR_SRC_A1) * rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_R * rvb.IN_COEF_R)>>15);
- const s64 IIR_INPUT_B0 = ((g_buffer(rvb.IIR_SRC_B0) * rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_L * rvb.IN_COEF_L)>>15);
- const s64 IIR_INPUT_B1 = ((g_buffer(rvb.IIR_SRC_B1) * rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_R * rvb.IN_COEF_R)>>15);
- const s64 IIR_A0 = ((IIR_INPUT_A0 * rvb.IIR_ALPHA)>>15) + ((g_buffer(rvb.IIR_DEST_A0) * (32768L - rvb.IIR_ALPHA))>>15);
- const s64 IIR_A1 = ((IIR_INPUT_A1 * rvb.IIR_ALPHA)>>15) + ((g_buffer(rvb.IIR_DEST_A1) * (32768L - rvb.IIR_ALPHA))>>15);
- const s64 IIR_B0 = ((IIR_INPUT_B0 * rvb.IIR_ALPHA)>>15) + ((g_buffer(rvb.IIR_DEST_B0) * (32768L - rvb.IIR_ALPHA))>>15);
- const s64 IIR_B1 = ((IIR_INPUT_B1 * rvb.IIR_ALPHA)>>15) + ((g_buffer(rvb.IIR_DEST_B1) * (32768L - rvb.IIR_ALPHA))>>15);
-
- s_buffer1(rvb.IIR_DEST_A0, IIR_A0);
- s_buffer1(rvb.IIR_DEST_A1, IIR_A1);
- s_buffer1(rvb.IIR_DEST_B0, IIR_B0);
- s_buffer1(rvb.IIR_DEST_B1, IIR_B1);
-
- ACC0 = ((g_buffer(rvb.ACC_SRC_A0) * rvb.ACC_COEF_A)>>15) +
- ((g_buffer(rvb.ACC_SRC_B0) * rvb.ACC_COEF_B)>>15) +
- ((g_buffer(rvb.ACC_SRC_C0) * rvb.ACC_COEF_C)>>15) +
- ((g_buffer(rvb.ACC_SRC_D0) * rvb.ACC_COEF_D)>>15);
- ACC1 = ((g_buffer(rvb.ACC_SRC_A1) * rvb.ACC_COEF_A)>>15) +
- ((g_buffer(rvb.ACC_SRC_B1) * rvb.ACC_COEF_B)>>15) +
- ((g_buffer(rvb.ACC_SRC_C1) * rvb.ACC_COEF_C)>>15) +
- ((g_buffer(rvb.ACC_SRC_D1) * rvb.ACC_COEF_D)>>15);
-
- FB_A0 = g_buffer(rvb.MIX_DEST_A0 - rvb.FB_SRC_A);
- FB_A1 = g_buffer(rvb.MIX_DEST_A1 - rvb.FB_SRC_A);
- FB_B0 = g_buffer(rvb.MIX_DEST_B0 - rvb.FB_SRC_B);
- FB_B1 = g_buffer(rvb.MIX_DEST_B1 - rvb.FB_SRC_B);
-
- s_buffer(rvb.MIX_DEST_A0, ACC0 - ((FB_A0 * rvb.FB_ALPHA)>>15));
- s_buffer(rvb.MIX_DEST_A1, ACC1 - ((FB_A1 * rvb.FB_ALPHA)>>15));
-
- s_buffer(rvb.MIX_DEST_B0, ((rvb.FB_ALPHA * ACC0)>>15) - ((FB_A0 * (int)(rvb.FB_ALPHA^0xFFFF8000))>>15) - ((FB_B0 * rvb.FB_X)>>15));
- s_buffer(rvb.MIX_DEST_B1, ((rvb.FB_ALPHA * ACC1)>>15) - ((FB_A1 * (int)(rvb.FB_ALPHA^0xFFFF8000))>>15) - ((FB_B1 * rvb.FB_X)>>15));
-
- rvb.iRVBLeft = (g_buffer(rvb.MIX_DEST_A0)+g_buffer(rvb.MIX_DEST_B0))/3;
- rvb.iRVBRight = (g_buffer(rvb.MIX_DEST_A1)+g_buffer(rvb.MIX_DEST_B1))/3;
-
- rvb.iRVBLeft = ((s64)rvb.iRVBLeft * rvb.VolLeft) >> 14;
- rvb.iRVBRight = ((s64)rvb.iRVBRight * rvb.VolRight) >> 14;
-
- upbuf[0][ubpos]=rvb.iRVBLeft;
- upbuf[1][ubpos]=rvb.iRVBRight;
- ubpos=(ubpos+1)&7;
- } // Bracket hack(et).
- }
- else // -> reverb off
- {
- rvb.iRVBLeft=rvb.iRVBRight=0;
- return;
- }
- rvb.CurrAddr++;
- if(rvb.CurrAddr>0x3ffff) rvb.CurrAddr=rvb.StartAddr;
- }
- else
- {
- upbuf[0][ubpos]=0;
- upbuf[1][ubpos]=0;
- ubpos=(ubpos+1)&7;
- }
- {
- s32 retl=0,retr=0;
- for(x=0;x<8;x++)
- {
- retl+=(upbuf[0][(ubpos+x)&7]*downcoeffs[x])>>8;
- retr+=(upbuf[1][(ubpos+x)&7]*downcoeffs[x])>>8;
- }
- retl>>=(16-8-1); /* -1 To adjust for the null padding. */
- retr>>=(16-8-1);
-
- *oleft+=retl;
- *oright+=retr;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-#endif
-
-/*
------------------------------------------------------------------------------
-PSX reverb hardware notes
-by Neill Corlett
------------------------------------------------------------------------------
-
-Yadda yadda disclaimer yadda probably not perfect yadda well it's okay anyway
-yadda yadda.
-
------------------------------------------------------------------------------
-
-Basics
-------
-
-- The reverb buffer is 22khz 16-bit mono PCM.
-- It starts at the reverb address given by 1DA2, extends to
- the end of sound RAM, and wraps back to the 1DA2 address.
-
-Setting the address at 1DA2 resets the current reverb work address.
-
-This work address ALWAYS increments every 1/22050 sec., regardless of
-whether reverb is enabled (bit 7 of 1DAA set).
-
-And the contents of the reverb buffer ALWAYS play, scaled by the
-"reverberation depth left/right" volumes (1D84/1D86).
-(which, by the way, appear to be scaled so 3FFF=approx. 1.0, 4000=-1.0)
-
------------------------------------------------------------------------------
-
-Register names
---------------
-
-These are probably not their real names.
-These are probably not even correct names.
-We will use them anyway, because we can.
-
-1DC0: FB_SRC_A (offset)
-1DC2: FB_SRC_B (offset)
-1DC4: IIR_ALPHA (coef.)
-1DC6: ACC_COEF_A (coef.)
-1DC8: ACC_COEF_B (coef.)
-1DCA: ACC_COEF_C (coef.)
-1DCC: ACC_COEF_D (coef.)
-1DCE: IIR_COEF (coef.)
-1DD0: FB_ALPHA (coef.)
-1DD2: FB_X (coef.)
-1DD4: IIR_DEST_A0 (offset)
-1DD6: IIR_DEST_A1 (offset)
-1DD8: ACC_SRC_A0 (offset)
-1DDA: ACC_SRC_A1 (offset)
-1DDC: ACC_SRC_B0 (offset)
-1DDE: ACC_SRC_B1 (offset)
-1DE0: IIR_SRC_A0 (offset)
-1DE2: IIR_SRC_A1 (offset)
-1DE4: IIR_DEST_B0 (offset)
-1DE6: IIR_DEST_B1 (offset)
-1DE8: ACC_SRC_C0 (offset)
-1DEA: ACC_SRC_C1 (offset)
-1DEC: ACC_SRC_D0 (offset)
-1DEE: ACC_SRC_D1 (offset)
-1DF0: IIR_SRC_B1 (offset)
-1DF2: IIR_SRC_B0 (offset)
-1DF4: MIX_DEST_A0 (offset)
-1DF6: MIX_DEST_A1 (offset)
-1DF8: MIX_DEST_B0 (offset)
-1DFA: MIX_DEST_B1 (offset)
-1DFC: IN_COEF_L (coef.)
-1DFE: IN_COEF_R (coef.)
-
-The coefficients are signed fractional values.
--32768 would be -1.0
- 32768 would be 1.0 (if it were possible... the highest is of course 32767)
-
-The offsets are (byte/8) offsets into the reverb buffer.
-i.e. you multiply them by 8, you get byte offsets.
-You can also think of them as (samples/4) offsets.
-They appear to be signed. They can be negative.
-None of the documented presets make them negative, though.
-
-Yes, 1DF0 and 1DF2 appear to be backwards. Not a typo.
-
------------------------------------------------------------------------------
-
-What it does
-------------
-
-We take all reverb sources:
-- regular channels that have the reverb bit on
-- cd and external sources, if their reverb bits are on
-and mix them into one stereo 44100hz signal.
-
-Lowpass/downsample that to 22050hz. The PSX uses a proper bandlimiting
-algorithm here, but I haven't figured out the hysterically exact specifics.
-I use an 8-tap filter with these coefficients, which are nice but probably
-not the real ones:
-
-0.037828187894
-0.157538631280
-0.321159685278
-0.449322115345
-0.449322115345
-0.321159685278
-0.157538631280
-0.037828187894
-
-So we have two input samples (INPUT_SAMPLE_L, INPUT_SAMPLE_R) every 22050hz.
-
-* IN MY EMULATION, I divide these by 2 to make it clip less.
- (and of course the L/R output coefficients are adjusted to compensate)
- The real thing appears to not do this.
-
-At every 22050hz tick:
-- If the reverb bit is enabled (bit 7 of 1DAA), execute the reverb
- steady-state algorithm described below
-- AFTERWARDS, retrieve the "wet out" L and R samples from the reverb buffer
- (This part may not be exactly right and I guessed at the coefs. TODO: check later.)
- L is: 0.333 * (buffer[MIX_DEST_A0] + buffer[MIX_DEST_B0])
- R is: 0.333 * (buffer[MIX_DEST_A1] + buffer[MIX_DEST_B1])
-- Advance the current buffer position by 1 sample
-
-The wet out L and R are then upsampled to 44100hz and played at the
-"reverberation depth left/right" (1D84/1D86) volume, independent of the main
-volume.
-
------------------------------------------------------------------------------
-
-Reverb steady-state
--------------------
-
-The reverb steady-state algorithm is fairly clever, and of course by
-"clever" I mean "batshit insane".
-
-buffer[x] is relative to the current buffer position, not the beginning of
-the buffer. Note that all buffer offsets must wrap around so they're
-contained within the reverb work area.
-
-Clipping is performed at the end... maybe also sooner, but definitely at
-the end.
-
-IIR_INPUT_A0 = buffer[IIR_SRC_A0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
-IIR_INPUT_A1 = buffer[IIR_SRC_A1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
-IIR_INPUT_B0 = buffer[IIR_SRC_B0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
-IIR_INPUT_B1 = buffer[IIR_SRC_B1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
-
-IIR_A0 = IIR_INPUT_A0 * IIR_ALPHA + buffer[IIR_DEST_A0] * (1.0 - IIR_ALPHA);
-IIR_A1 = IIR_INPUT_A1 * IIR_ALPHA + buffer[IIR_DEST_A1] * (1.0 - IIR_ALPHA);
-IIR_B0 = IIR_INPUT_B0 * IIR_ALPHA + buffer[IIR_DEST_B0] * (1.0 - IIR_ALPHA);
-IIR_B1 = IIR_INPUT_B1 * IIR_ALPHA + buffer[IIR_DEST_B1] * (1.0 - IIR_ALPHA);
-
-buffer[IIR_DEST_A0 + 1sample] = IIR_A0;
-buffer[IIR_DEST_A1 + 1sample] = IIR_A1;
-buffer[IIR_DEST_B0 + 1sample] = IIR_B0;
-buffer[IIR_DEST_B1 + 1sample] = IIR_B1;
-
-ACC0 = buffer[ACC_SRC_A0] * ACC_COEF_A +
- buffer[ACC_SRC_B0] * ACC_COEF_B +
- buffer[ACC_SRC_C0] * ACC_COEF_C +
- buffer[ACC_SRC_D0] * ACC_COEF_D;
-ACC1 = buffer[ACC_SRC_A1] * ACC_COEF_A +
- buffer[ACC_SRC_B1] * ACC_COEF_B +
- buffer[ACC_SRC_C1] * ACC_COEF_C +
- buffer[ACC_SRC_D1] * ACC_COEF_D;
-
-FB_A0 = buffer[MIX_DEST_A0 - FB_SRC_A];
-FB_A1 = buffer[MIX_DEST_A1 - FB_SRC_A];
-FB_B0 = buffer[MIX_DEST_B0 - FB_SRC_B];
-FB_B1 = buffer[MIX_DEST_B1 - FB_SRC_B];
-
-buffer[MIX_DEST_A0] = ACC0 - FB_A0 * FB_ALPHA;
-buffer[MIX_DEST_A1] = ACC1 - FB_A1 * FB_ALPHA;
-buffer[MIX_DEST_B0] = (FB_ALPHA * ACC0) - FB_A0 * (FB_ALPHA^0x8000) - FB_B0 * FB_X;
-buffer[MIX_DEST_B1] = (FB_ALPHA * ACC1) - FB_A1 * (FB_ALPHA^0x8000) - FB_B1 * FB_X;
-
------------------------------------------------------------------------------
-*/
-
diff --git a/src/psf/peops/reverb.cc b/src/psf/peops/reverb.cc
new file mode 100644
index 000000000000..681d56c55fbf
--- /dev/null
+++ b/src/psf/peops/reverb.cc
@@ -0,0 +1,383 @@
+/***************************************************************************
+ reverb.c - description
+ -------------------
+ begin : Wed May 15 2002
+ copyright : (C) 2002 by Pete Bernert
+ email : BlackDove at addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+//*************************************************************************//
+// History of changes:
+//
+// 2003/03/17 - xodnizel
+// - Implemented Neill's 44.1Khz-22050Hz downsampling data
+// I also need to check if the ~4 sample delay doesn't screw any sounds
+// up by making things too out of phase. It could be fixed easily(elsewhere).
+//
+// 2003/01/19 - Pete
+// - added Neill's reverb (see at the end of file)
+//
+// 2002/12/26 - Pete
+// - adjusted reverb handling
+//
+// 2002/08/14 - Pete
+// - added extra reverb
+//
+// 2002/05/15 - Pete
+// - generic cleanup for the Peops release
+//
+//*************************************************************************//
+
+#define _IN_REVERB
+
+// will be included from spu.c
+#ifdef _IN_SPU
+
+////////////////////////////////////////////////////////////////////////
+// globals
+////////////////////////////////////////////////////////////////////////
+
+// REVERB info and timing vars...
+
+////////////////////////////////////////////////////////////////////////
+
+static inline s64 g_buffer(int iOff) // get_buffer content helper: takes care about wraps
+{
+ s16 * p=(s16 *)spuMem;
+ iOff=(iOff*4)+rvb.CurrAddr;
+ while(iOff>0x3FFFF) iOff=rvb.StartAddr+(iOff-0x40000);
+ while(iOff<rvb.StartAddr) iOff=0x3ffff-(rvb.StartAddr-iOff);
+ return (int)(s16)BFLIP16(*(p+iOff));
+}
+
+////////////////////////////////////////////////////////////////////////
+
+static inline void s_buffer(int iOff,int iVal) // set_buffer content helper: takes care about wraps and clipping
+{
+ s16 * p=(s16 *)spuMem;
+ iOff=(iOff*4)+rvb.CurrAddr;
+ while(iOff>0x3FFFF) iOff=rvb.StartAddr+(iOff-0x40000);
+ while(iOff<rvb.StartAddr) iOff=0x3ffff-(rvb.StartAddr-iOff);
+ if(iVal<-32768L) iVal=-32768L;
+ if(iVal>32767L) iVal=32767L;
+ *(p+iOff)=(s16)BFLIP16((s16)iVal);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+static inline void s_buffer1(int iOff,int iVal) // set_buffer (+1 sample) content helper: takes care about wraps and clipping
+{
+ s16 * p=(s16 *)spuMem;
+ iOff=(iOff*4)+rvb.CurrAddr+1;
+ while(iOff>0x3FFFF) iOff=rvb.StartAddr+(iOff-0x40000);
+ while(iOff<rvb.StartAddr) iOff=0x3ffff-(rvb.StartAddr-iOff);
+ if(iVal<-32768L) iVal=-32768L;if(iVal>32767L) iVal=32767L;
+ *(p+iOff)=(s16)BFLIP16((s16)iVal);
+}
+
+static inline void MixREVERBLeftRight(s32 *oleft, s32 *oright, s32 inleft, s32 inright)
+{
+ static s32 downbuf[2][8];
+ static s32 upbuf[2][8];
+ static int dbpos=0,ubpos=0;
+ static s32 downcoeffs[8]={ /* Symmetry is sexy. */
+ 1283,5344,10895,15243,
+ 15243,10895,5344,1283
+ };
+ int x;
+
+ if(!rvb.StartAddr) // reverb is off
+ {
+ rvb.iRVBLeft=rvb.iRVBRight=0;
+ return;
+ }
+
+ //if(inleft<-32767 || inleft>32767) printf("%d\n",inleft);
+ //if(inright<-32767 || inright>32767) printf("%d\n",inright);
+ downbuf[0][dbpos]=inleft;
+ downbuf[1][dbpos]=inright;
+ dbpos=(dbpos+1)&7;
+
+ if(dbpos&1) // we work on every second left value: downsample to 22 khz
+ {
+ if(spuCtrl&0x80) // -> reverb on? oki
+ {
+ int ACC0,ACC1,FB_A0,FB_A1,FB_B0,FB_B1;
+ s32 INPUT_SAMPLE_L=0;
+ s32 INPUT_SAMPLE_R=0;
+
+ for(x=0;x<8;x++)
+ {
+ INPUT_SAMPLE_L+=(downbuf[0][(dbpos+x)&7]*downcoeffs[x])>>8; /* Lose insignificant
+ digits to prevent
+ overflow(check this) */
+ INPUT_SAMPLE_R+=(downbuf[1][(dbpos+x)&7]*downcoeffs[x])>>8;
+ }
+
+ INPUT_SAMPLE_L>>=(16-8);
+ INPUT_SAMPLE_R>>=(16-8);
+ {
+ const s64 IIR_INPUT_A0 = ((g_buffer(rvb.IIR_SRC_A0) * rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_L * rvb.IN_COEF_L)>>15);
+ const s64 IIR_INPUT_A1 = ((g_buffer(rvb.IIR_SRC_A1) * rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_R * rvb.IN_COEF_R)>>15);
+ const s64 IIR_INPUT_B0 = ((g_buffer(rvb.IIR_SRC_B0) * rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_L * rvb.IN_COEF_L)>>15);
+ const s64 IIR_INPUT_B1 = ((g_buffer(rvb.IIR_SRC_B1) * rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_R * rvb.IN_COEF_R)>>15);
+ const s64 IIR_A0 = ((IIR_INPUT_A0 * rvb.IIR_ALPHA)>>15) + ((g_buffer(rvb.IIR_DEST_A0) * (32768L - rvb.IIR_ALPHA))>>15);
+ const s64 IIR_A1 = ((IIR_INPUT_A1 * rvb.IIR_ALPHA)>>15) + ((g_buffer(rvb.IIR_DEST_A1) * (32768L - rvb.IIR_ALPHA))>>15);
+ const s64 IIR_B0 = ((IIR_INPUT_B0 * rvb.IIR_ALPHA)>>15) + ((g_buffer(rvb.IIR_DEST_B0) * (32768L - rvb.IIR_ALPHA))>>15);
+ const s64 IIR_B1 = ((IIR_INPUT_B1 * rvb.IIR_ALPHA)>>15) + ((g_buffer(rvb.IIR_DEST_B1) * (32768L - rvb.IIR_ALPHA))>>15);
+
+ s_buffer1(rvb.IIR_DEST_A0, IIR_A0);
+ s_buffer1(rvb.IIR_DEST_A1, IIR_A1);
+ s_buffer1(rvb.IIR_DEST_B0, IIR_B0);
+ s_buffer1(rvb.IIR_DEST_B1, IIR_B1);
+
+ ACC0 = ((g_buffer(rvb.ACC_SRC_A0) * rvb.ACC_COEF_A)>>15) +
+ ((g_buffer(rvb.ACC_SRC_B0) * rvb.ACC_COEF_B)>>15) +
+ ((g_buffer(rvb.ACC_SRC_C0) * rvb.ACC_COEF_C)>>15) +
+ ((g_buffer(rvb.ACC_SRC_D0) * rvb.ACC_COEF_D)>>15);
+ ACC1 = ((g_buffer(rvb.ACC_SRC_A1) * rvb.ACC_COEF_A)>>15) +
+ ((g_buffer(rvb.ACC_SRC_B1) * rvb.ACC_COEF_B)>>15) +
+ ((g_buffer(rvb.ACC_SRC_C1) * rvb.ACC_COEF_C)>>15) +
+ ((g_buffer(rvb.ACC_SRC_D1) * rvb.ACC_COEF_D)>>15);
+
+ FB_A0 = g_buffer(rvb.MIX_DEST_A0 - rvb.FB_SRC_A);
+ FB_A1 = g_buffer(rvb.MIX_DEST_A1 - rvb.FB_SRC_A);
+ FB_B0 = g_buffer(rvb.MIX_DEST_B0 - rvb.FB_SRC_B);
+ FB_B1 = g_buffer(rvb.MIX_DEST_B1 - rvb.FB_SRC_B);
+
+ s_buffer(rvb.MIX_DEST_A0, ACC0 - ((FB_A0 * rvb.FB_ALPHA)>>15));
+ s_buffer(rvb.MIX_DEST_A1, ACC1 - ((FB_A1 * rvb.FB_ALPHA)>>15));
+
+ s_buffer(rvb.MIX_DEST_B0, ((rvb.FB_ALPHA * ACC0)>>15) - ((FB_A0 * (int)(rvb.FB_ALPHA^0xFFFF8000))>>15) - ((FB_B0 * rvb.FB_X)>>15));
+ s_buffer(rvb.MIX_DEST_B1, ((rvb.FB_ALPHA * ACC1)>>15) - ((FB_A1 * (int)(rvb.FB_ALPHA^0xFFFF8000))>>15) - ((FB_B1 * rvb.FB_X)>>15));
+
+ rvb.iRVBLeft = (g_buffer(rvb.MIX_DEST_A0)+g_buffer(rvb.MIX_DEST_B0))/3;
+ rvb.iRVBRight = (g_buffer(rvb.MIX_DEST_A1)+g_buffer(rvb.MIX_DEST_B1))/3;
+
+ rvb.iRVBLeft = ((s64)rvb.iRVBLeft * rvb.VolLeft) >> 14;
+ rvb.iRVBRight = ((s64)rvb.iRVBRight * rvb.VolRight) >> 14;
+
+ upbuf[0][ubpos]=rvb.iRVBLeft;
+ upbuf[1][ubpos]=rvb.iRVBRight;
+ ubpos=(ubpos+1)&7;
+ } // Bracket hack(et).
+ }
+ else // -> reverb off
+ {
+ rvb.iRVBLeft=rvb.iRVBRight=0;
+ return;
+ }
+ rvb.CurrAddr++;
+ if(rvb.CurrAddr>0x3ffff) rvb.CurrAddr=rvb.StartAddr;
+ }
+ else
+ {
+ upbuf[0][ubpos]=0;
+ upbuf[1][ubpos]=0;
+ ubpos=(ubpos+1)&7;
+ }
+ {
+ s32 retl=0,retr=0;
+ for(x=0;x<8;x++)
+ {
+ retl+=(upbuf[0][(ubpos+x)&7]*downcoeffs[x])>>8;
+ retr+=(upbuf[1][(ubpos+x)&7]*downcoeffs[x])>>8;
+ }
+ retl>>=(16-8-1); /* -1 To adjust for the null padding. */
+ retr>>=(16-8-1);
+
+ *oleft+=retl;
+ *oright+=retr;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
+/*
+-----------------------------------------------------------------------------
+PSX reverb hardware notes
+by Neill Corlett
+-----------------------------------------------------------------------------
+
+Yadda yadda disclaimer yadda probably not perfect yadda well it's okay anyway
+yadda yadda.
+
+-----------------------------------------------------------------------------
+
+Basics
+------
+
+- The reverb buffer is 22khz 16-bit mono PCM.
+- It starts at the reverb address given by 1DA2, extends to
+ the end of sound RAM, and wraps back to the 1DA2 address.
+
+Setting the address at 1DA2 resets the current reverb work address.
+
+This work address ALWAYS increments every 1/22050 sec., regardless of
+whether reverb is enabled (bit 7 of 1DAA set).
+
+And the contents of the reverb buffer ALWAYS play, scaled by the
+"reverberation depth left/right" volumes (1D84/1D86).
+(which, by the way, appear to be scaled so 3FFF=approx. 1.0, 4000=-1.0)
+
+-----------------------------------------------------------------------------
+
+Register names
+--------------
+
+These are probably not their real names.
+These are probably not even correct names.
+We will use them anyway, because we can.
+
+1DC0: FB_SRC_A (offset)
+1DC2: FB_SRC_B (offset)
+1DC4: IIR_ALPHA (coef.)
+1DC6: ACC_COEF_A (coef.)
+1DC8: ACC_COEF_B (coef.)
+1DCA: ACC_COEF_C (coef.)
+1DCC: ACC_COEF_D (coef.)
+1DCE: IIR_COEF (coef.)
+1DD0: FB_ALPHA (coef.)
+1DD2: FB_X (coef.)
+1DD4: IIR_DEST_A0 (offset)
+1DD6: IIR_DEST_A1 (offset)
+1DD8: ACC_SRC_A0 (offset)
+1DDA: ACC_SRC_A1 (offset)
+1DDC: ACC_SRC_B0 (offset)
+1DDE: ACC_SRC_B1 (offset)
+1DE0: IIR_SRC_A0 (offset)
+1DE2: IIR_SRC_A1 (offset)
+1DE4: IIR_DEST_B0 (offset)
+1DE6: IIR_DEST_B1 (offset)
+1DE8: ACC_SRC_C0 (offset)
+1DEA: ACC_SRC_C1 (offset)
+1DEC: ACC_SRC_D0 (offset)
+1DEE: ACC_SRC_D1 (offset)
+1DF0: IIR_SRC_B1 (offset)
+1DF2: IIR_SRC_B0 (offset)
+1DF4: MIX_DEST_A0 (offset)
+1DF6: MIX_DEST_A1 (offset)
+1DF8: MIX_DEST_B0 (offset)
+1DFA: MIX_DEST_B1 (offset)
+1DFC: IN_COEF_L (coef.)
+1DFE: IN_COEF_R (coef.)
+
+The coefficients are signed fractional values.
+-32768 would be -1.0
+ 32768 would be 1.0 (if it were possible... the highest is of course 32767)
+
+The offsets are (byte/8) offsets into the reverb buffer.
+i.e. you multiply them by 8, you get byte offsets.
+You can also think of them as (samples/4) offsets.
+They appear to be signed. They can be negative.
+None of the documented presets make them negative, though.
+
+Yes, 1DF0 and 1DF2 appear to be backwards. Not a typo.
+
+-----------------------------------------------------------------------------
+
+What it does
+------------
+
+We take all reverb sources:
+- regular channels that have the reverb bit on
+- cd and external sources, if their reverb bits are on
+and mix them into one stereo 44100hz signal.
+
+Lowpass/downsample that to 22050hz. The PSX uses a proper bandlimiting
+algorithm here, but I haven't figured out the hysterically exact specifics.
+I use an 8-tap filter with these coefficients, which are nice but probably
+not the real ones:
+
+0.037828187894
+0.157538631280
+0.321159685278
+0.449322115345
+0.449322115345
+0.321159685278
+0.157538631280
+0.037828187894
+
+So we have two input samples (INPUT_SAMPLE_L, INPUT_SAMPLE_R) every 22050hz.
+
+* IN MY EMULATION, I divide these by 2 to make it clip less.
+ (and of course the L/R output coefficients are adjusted to compensate)
+ The real thing appears to not do this.
+
+At every 22050hz tick:
+- If the reverb bit is enabled (bit 7 of 1DAA), execute the reverb
+ steady-state algorithm described below
+- AFTERWARDS, retrieve the "wet out" L and R samples from the reverb buffer
+ (This part may not be exactly right and I guessed at the coefs. TODO: check later.)
+ L is: 0.333 * (buffer[MIX_DEST_A0] + buffer[MIX_DEST_B0])
+ R is: 0.333 * (buffer[MIX_DEST_A1] + buffer[MIX_DEST_B1])
+- Advance the current buffer position by 1 sample
+
+The wet out L and R are then upsampled to 44100hz and played at the
+"reverberation depth left/right" (1D84/1D86) volume, independent of the main
+volume.
+
+-----------------------------------------------------------------------------
+
+Reverb steady-state
+-------------------
+
+The reverb steady-state algorithm is fairly clever, and of course by
+"clever" I mean "batshit insane".
+
+buffer[x] is relative to the current buffer position, not the beginning of
+the buffer. Note that all buffer offsets must wrap around so they're
+contained within the reverb work area.
+
+Clipping is performed at the end... maybe also sooner, but definitely at
+the end.
+
+IIR_INPUT_A0 = buffer[IIR_SRC_A0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
+IIR_INPUT_A1 = buffer[IIR_SRC_A1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
+IIR_INPUT_B0 = buffer[IIR_SRC_B0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
+IIR_INPUT_B1 = buffer[IIR_SRC_B1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
+
+IIR_A0 = IIR_INPUT_A0 * IIR_ALPHA + buffer[IIR_DEST_A0] * (1.0 - IIR_ALPHA);
+IIR_A1 = IIR_INPUT_A1 * IIR_ALPHA + buffer[IIR_DEST_A1] * (1.0 - IIR_ALPHA);
+IIR_B0 = IIR_INPUT_B0 * IIR_ALPHA + buffer[IIR_DEST_B0] * (1.0 - IIR_ALPHA);
+IIR_B1 = IIR_INPUT_B1 * IIR_ALPHA + buffer[IIR_DEST_B1] * (1.0 - IIR_ALPHA);
+
+buffer[IIR_DEST_A0 + 1sample] = IIR_A0;
+buffer[IIR_DEST_A1 + 1sample] = IIR_A1;
+buffer[IIR_DEST_B0 + 1sample] = IIR_B0;
+buffer[IIR_DEST_B1 + 1sample] = IIR_B1;
+
+ACC0 = buffer[ACC_SRC_A0] * ACC_COEF_A +
+ buffer[ACC_SRC_B0] * ACC_COEF_B +
+ buffer[ACC_SRC_C0] * ACC_COEF_C +
+ buffer[ACC_SRC_D0] * ACC_COEF_D;
+ACC1 = buffer[ACC_SRC_A1] * ACC_COEF_A +
+ buffer[ACC_SRC_B1] * ACC_COEF_B +
+ buffer[ACC_SRC_C1] * ACC_COEF_C +
+ buffer[ACC_SRC_D1] * ACC_COEF_D;
+
+FB_A0 = buffer[MIX_DEST_A0 - FB_SRC_A];
+FB_A1 = buffer[MIX_DEST_A1 - FB_SRC_A];
+FB_B0 = buffer[MIX_DEST_B0 - FB_SRC_B];
+FB_B1 = buffer[MIX_DEST_B1 - FB_SRC_B];
+
+buffer[MIX_DEST_A0] = ACC0 - FB_A0 * FB_ALPHA;
+buffer[MIX_DEST_A1] = ACC1 - FB_A1 * FB_ALPHA;
+buffer[MIX_DEST_B0] = (FB_ALPHA * ACC0) - FB_A0 * (FB_ALPHA^0x8000) - FB_B0 * FB_X;
+buffer[MIX_DEST_B1] = (FB_ALPHA * ACC1) - FB_A1 * (FB_ALPHA^0x8000) - FB_B1 * FB_X;
+
+-----------------------------------------------------------------------------
+*/
+
diff --git a/src/psf/peops/spu.c b/src/psf/peops/spu.c
deleted file mode 100644
index 0d6f7a638771..000000000000
--- a/src/psf/peops/spu.c
+++ /dev/null
@@ -1,673 +0,0 @@
-/***************************************************************************
- spu.c - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove at addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-//*************************************************************************//
-// History of changes:
-//
-// 2003/03/01 - linuzappz
-// - libraryName changes using ALSA
-//
-// 2003/02/28 - Pete
-// - added option for type of interpolation
-// - adjusted spu irqs again (Thousant Arms, Valkyrie Profile)
-// - added MONO support for MSWindows DirectSound
-//
-// 2003/02/20 - kode54
-// - amended interpolation code, goto GOON could skip initialization of gpos and cause segfault
-//
-// 2003/02/19 - kode54
-// - moved SPU IRQ handler and changed sample flag processing
-//
-// 2003/02/18 - kode54
-// - moved ADSR calculation outside of the sample decode loop, somehow I doubt that
-// ADSR timing is relative to the frequency at which a sample is played... I guess
-// this remains to be seen, and I don't know whether ADSR is applied to noise channels...
-//
-// 2003/02/09 - kode54
-// - one-shot samples now process the end block before stopping
-// - in light of removing fmod hack, now processing ADSR on frequency channel as well
-//
-// 2003/02/08 - kode54
-// - replaced easy interpolation with gaussian
-// - removed fmod averaging hack
-// - changed .sinc to be updated from .iRawPitch, no idea why it wasn't done this way already (<- Pete: because I sometimes fail to see the obvious, haharhar :)
-//
-// 2003/02/08 - linuzappz
-// - small bugfix for one usleep that was 1 instead of 1000
-// - added iDisStereo for no stereo (Linux)
-//
-// 2003/01/22 - Pete
-// - added easy interpolation & small noise adjustments
-//
-// 2003/01/19 - Pete
-// - added Neill's reverb
-//
-// 2003/01/12 - Pete
-// - added recording window handlers
-//
-// 2003/01/06 - Pete
-// - added Neill's ADSR timings
-//
-// 2002/12/28 - Pete
-// - adjusted spu irq handling, fmod handling and loop handling
-//
-// 2002/08/14 - Pete
-// - added extra reverb
-//
-// 2002/06/08 - linuzappz
-// - SPUupdate changed for SPUasync
-//
-// 2002/05/15 - Pete
-// - generic cleanup for the Peops release
-//
-//*************************************************************************//
-
-#define _IN_SPU
-
-#include "../peops/stdafx.h"
-#include "../peops/externals.h"
-#include "../peops/regs.h"
-#include "../peops/registers.h"
-#include "../peops/spu.h"
-
-// Enable experimental silence skipping
-// Currently it is too aggressive, destroying the rhythm of some songs
-// See http://redmine.audacious-media-player.org/issues/201
-// #define ENABLE_SILENCE_SKIPPING
-
-void SPUirq(void) ;
-
-//#include "PsxMem.h"
-//#include "driver.h"
-
-////////////////////////////////////////////////////////////////////////
-// globals
-////////////////////////////////////////////////////////////////////////
-
-// psx buffer / addresses
-
-static u16 regArea[0x200];
-static u16 spuMem[256*1024];
-static u8 * spuMemC;
-static u8 * pSpuIrq=0;
-static u8 * pSpuBuffer;
-
-// user settings
-static int iVolume;
-
-// MAIN infos struct for each channel
-
-static SPUCHAN s_chan[MAXCHAN+1]; // channel + 1 infos (1 is security for fmod handling)
-static REVERBInfo rvb;
-
-static u32 dwNoiseVal=1; // global noise generator
-
-static u16 spuCtrl=0; // some vars to store psx reg infos
-static u16 spuStat=0;
-static u16 spuIrq=0;
-static u32 spuAddr=0xffffffff; // address into spu mem
-static int bSPUIsOpen=0;
-
-static const int f[5][2] = {
- { 0, 0 },
- { 60, 0 },
- { 115, -52 },
- { 98, -55 },
- { 122, -60 } };
-s16 * pS;
-static s32 ttemp;
-
-extern void psf2_update(unsigned char *samples, long lBytes);
-
-////////////////////////////////////////////////////////////////////////
-// CODE AREA
-////////////////////////////////////////////////////////////////////////
-
-// dirty inline func includes
-
-#include "../peops/reverb.c"
-#include "../peops/adsr.c"
-
-// Try this to increase speed.
-#include "../peops/registers.c"
-#include "../peops/dma.c"
-
-////////////////////////////////////////////////////////////////////////
-// helpers for so-called "gauss interpolation"
-
-#define gval0 (((int *)(&s_chan[ch].SB[29]))[gpos])
-#define gval(x) (((int *)(&s_chan[ch].SB[29]))[(gpos+x)&3])
-
-#include "gauss_i.h"
-
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-// START SOUND... called by main thread to setup a new sound on a channel
-////////////////////////////////////////////////////////////////////////
-
-static inline void StartSound(int ch)
-{
- StartADSR(ch);
-
- s_chan[ch].pCurr=s_chan[ch].pStart; // set sample start
-
- s_chan[ch].s_1=0; // init mixing vars
- s_chan[ch].s_2=0;
- s_chan[ch].iSBPos=28;
-
- s_chan[ch].bNew=0; // init channel flags
- s_chan[ch].bStop=0;
- s_chan[ch].bOn=1;
-
- s_chan[ch].SB[29]=0; // init our interpolation helpers
- s_chan[ch].SB[30]=0;
-
- s_chan[ch].spos=0x40000L;s_chan[ch].SB[28]=0; // -> start with more decoding
-}
-
-////////////////////////////////////////////////////////////////////////
-// MAIN SPU FUNCTION
-// here is the main job handler... thread, timer or direct func call
-// basically the whole sound processing is done in this fat func!
-////////////////////////////////////////////////////////////////////////
-
-static u32 sampcount;
-static u32 decaybegin;
-static u32 decayend;
-
-static u32 seektime;
-int psf_seek(u32 t)
-{
- seektime=t*441/10;
- if(seektime>sampcount) return(1);
- return(0);
-}
-
-// Counting to 65536 results in full volume offage.
-void setlength(s32 stop, s32 fade)
-{
- if(stop==~0)
- {
- decaybegin=~0;
- }
- else
- {
- stop=(stop*441)/10;
- fade=(fade*441)/10;
-
- decaybegin=stop;
- decayend=stop+fade;
- }
-}
-
-#define CLIP(_x) {if(_x>32767) _x=32767; if(_x<-32767) _x=-32767;}
-int SPUasync(u32 cycles)
-{
- int volmul=iVolume;
- static s32 dosampies;
- s32 temp;
-
- ttemp+=cycles;
- dosampies=ttemp/384;
- if(!dosampies) return(1);
- ttemp-=dosampies*384;
- temp=dosampies;
-
- while(temp)
- {
- s32 revLeft=0, revRight=0;
- s32 sl=0, sr=0;
- int ch,fa;
-
- temp--;
- //--------------------------------------------------//
- //- main channel loop -//
- //--------------------------------------------------//
- {
- for(ch=0;ch<MAXCHAN;ch++) // loop em all.
- {
- if(s_chan[ch].bNew) StartSound(ch); // start new sound
- if(!s_chan[ch].bOn) continue; // channel not playing? next
-
-
- if(s_chan[ch].iActFreq!=s_chan[ch].iUsedFreq) // new psx frequency?
- {
- s_chan[ch].iUsedFreq=s_chan[ch].iActFreq; // -> take it and calc steps
- s_chan[ch].sinc=s_chan[ch].iRawPitch<<4;
- if(!s_chan[ch].sinc) s_chan[ch].sinc=1;
- }
-
- while(s_chan[ch].spos>=0x10000L)
- {
- if(s_chan[ch].iSBPos==28) // 28 reached?
- {
- int predict_nr,shift_factor,flags,d,s;
- u8* start;unsigned int nSample;
- int s_1,s_2;
-
- start=s_chan[ch].pCurr; // set up the current pos
-
- if (start == (u8*)-1) // special "stop" sign
- {
- s_chan[ch].bOn=0; // -> turn everything off
- s_chan[ch].ADSRX.lVolume=0;
- s_chan[ch].ADSRX.EnvelopeVol=0;
- goto ENDX; // -> and done for this channel
- }
-
- s_chan[ch].iSBPos=0; // Reset buffer play index.
-
- //////////////////////////////////////////// spu irq handler here? mmm... do it later
-
- s_1=s_chan[ch].s_1;
- s_2=s_chan[ch].s_2;
-
- predict_nr=(int)*start;start++;
- shift_factor=predict_nr&0xf;
- predict_nr >>= 4;
- flags=(int)*start;start++;
-
- // -------------------------------------- //
- // Decode new samples into s_chan[ch].SB[0 through 27]
- for (nSample=0;nSample<28;start++)
- {
- d=(int)*start;
- s=((d&0xf)<<12);
- if(s&0x8000) s|=0xffff0000;
-
- fa=(s >> shift_factor);
- fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6);
- s_2=s_1;s_1=fa;
- s=((d & 0xf0) << 8);
-
- s_chan[ch].SB[nSample++]=fa;
-
- if(s&0x8000) s|=0xffff0000;
- fa=(s>>shift_factor);
- fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6);
- s_2=s_1;s_1=fa;
-
- s_chan[ch].SB[nSample++]=fa;
- }
-
- //////////////////////////////////////////// irq check
-
- if(spuCtrl&0x40) // irq active?
- {
- if((pSpuIrq > start-16 && // irq address reached?
- pSpuIrq <= start) ||
- ((flags&1) && // special: irq on looping addr, when stop/loop flag is set
- (pSpuIrq > s_chan[ch].pLoop-16 &&
- pSpuIrq <= s_chan[ch].pLoop)))
- {
- //extern s32 spuirqvoodoo;
- s_chan[ch].iIrqDone=1; // -> debug flag
- SPUirq();
- //puts("IRQ");
- //if(spuirqvoodoo!=-1)
- //{
- // spuirqvoodoo=temp*384;
- // temp=0;
- //}
- }
- }
-
- //////////////////////////////////////////// flag handler
-
- if((flags&4) && (!s_chan[ch].bIgnoreLoop))
- s_chan[ch].pLoop=start-16; // loop adress
-
- if(flags&1) // 1: stop/loop
- {
- // We play this block out first...
- //if(!(flags&2)) // 1+2: do loop... otherwise: stop
- if(flags!=3 || s_chan[ch].pLoop==NULL) // PETE: if we don't check exactly for 3, loop hang ups will happen (DQ4, for example)
- { // and checking if pLoop is set avoids crashes, yeah
- start = (u8*)-1;
- }
- else
- {
- start = s_chan[ch].pLoop;
- }
- }
-
- s_chan[ch].pCurr=start; // store values for next cycle
- s_chan[ch].s_1=s_1;
- s_chan[ch].s_2=s_2;
-
- ////////////////////////////////////////////
- }
-
- fa=s_chan[ch].SB[s_chan[ch].iSBPos++]; // get sample data
-
- if((spuCtrl&0x4000)==0) fa=0; // muted?
- else CLIP(fa);
-
- {
- int gpos;
- gpos = s_chan[ch].SB[28];
- gval0 = fa;
- gpos = (gpos+1) & 3;
- s_chan[ch].SB[28] = gpos;
- }
- s_chan[ch].spos -= 0x10000L;
- }
-
- ////////////////////////////////////////////////
- // noise handler... just produces some noise data
- // surely wrong... and no noise frequency (spuCtrl&0x3f00) will be used...
- // and sometimes the noise will be used as fmod modulation... pfff
-
- if(s_chan[ch].bNoise)
- {
- //puts("Noise");
- if((dwNoiseVal<<=1)&0x80000000L)
- {
- dwNoiseVal^=0x0040001L;
- fa=((dwNoiseVal>>2)&0x7fff);
- fa=-fa;
- }
- else fa=(dwNoiseVal>>2)&0x7fff;
-
- // mmm... depending on the noise freq we allow bigger/smaller changes to the previous val
- fa=s_chan[ch].iOldNoise+((fa-s_chan[ch].iOldNoise)/((0x001f-((spuCtrl&0x3f00)>>9))+1));
- if(fa>32767L) fa=32767L;
- if(fa<-32767L) fa=-32767L;
- s_chan[ch].iOldNoise=fa;
-
- } //----------------------------------------
- else // NO NOISE (NORMAL SAMPLE DATA) HERE
- {
- int vl, vr, gpos;
- vl = (s_chan[ch].spos >> 6) & ~3;
- gpos = s_chan[ch].SB[28];
- vr=(gauss[vl]*gval0)>>9;
- vr+=(gauss[vl+1]*gval(1))>>9;
- vr+=(gauss[vl+2]*gval(2))>>9;
- vr+=(gauss[vl+3]*gval(3))>>9;
- fa = vr>>2;
- }
-
- s_chan[ch].sval = (MixADSR(ch) * fa)>>10; // / 1023; // add adsr
- if(s_chan[ch].bFMod==2) // fmod freq channel
- {
- int NP=s_chan[ch+1].iRawPitch;
- NP=((32768L+s_chan[ch].sval)*NP)>>15; ///32768L;
-
- if(NP>0x3fff) NP=0x3fff;
- if(NP<0x1) NP=0x1;
-
- // mmmm... if I do this, all is screwed
- // s_chan[ch+1].iRawPitch=NP;
-
- NP=(44100L*NP)/(4096L); // calc frequency
-
- s_chan[ch+1].iActFreq=NP;
- s_chan[ch+1].iUsedFreq=NP;
- s_chan[ch+1].sinc=(((NP/10)<<16)/4410);
- if(!s_chan[ch+1].sinc) s_chan[ch+1].sinc=1;
-
- // mmmm... set up freq decoding positions?
- // s_chan[ch+1].iSBPos=28;
- // s_chan[ch+1].spos=0x10000L;
- }
- else
- {
- //////////////////////////////////////////////
- // ok, left/right sound volume (psx volume goes from 0 ... 0x3fff)
- int tmpl,tmpr;
-
- if (1) //ao_channel_enable[ch+PSF_1]) {
- {
- tmpl=(s_chan[ch].sval*s_chan[ch].iLeftVolume)>>14;
- tmpr=(s_chan[ch].sval*s_chan[ch].iRightVolume)>>14;
- } else {
- tmpl = 0;
- tmpr = 0;
- }
- sl+=tmpl;
- sr+=tmpr;
-
- if(((rvb.Enabled>>ch)&1) && (spuCtrl&0x80))
- {
- revLeft+=tmpl;
- revRight+=tmpr;
- }
- }
-
- s_chan[ch].spos += s_chan[ch].sinc;
- ENDX: ;
- }
- }
-
- ///////////////////////////////////////////////////////
- // mix all channels (including reverb) into one buffer
- MixREVERBLeftRight(&sl,&sr,revLeft,revRight);
-// printf("sampcount %d decaybegin %d decayend %d\n", sampcount, decaybegin, decayend);
- if(sampcount>=decaybegin)
- {
- s32 dmul;
- if(decaybegin!=~0) // Is anyone REALLY going to be playing a song
- // for 13 hours?
- {
- if(sampcount>=decayend)
- {
- psf2_update(NULL, 0);
- return(0);
- }
- dmul=256-(256*(sampcount-decaybegin)/(decayend-decaybegin));
- sl=(sl*dmul)>>8;
- sr=(sr*dmul)>>8;
- }
- }
-
- sampcount++;
- sl=(sl*volmul)>>8;
- sr=(sr*volmul)>>8;
-
- //{
- // static double asl=0;
- // static double asr=0;
-
- // asl+=(sl-asl)/5;
- // asr+=(sl-asr)/5;
-
- //sl-=asl;
- //sr-=asr;
-
- // if(sl>32767 || sl < -32767) printf("Left: %d, %f\n",sl,asl);
- // if(sr>32767 || sr < -32767) printf("Right: %d, %f\n",sl,asl);
- //}
-
- if(sl>32767) sl=32767; if(sl<-32767) sl=-32767;
- if(sr>32767) sr=32767; if(sr<-32767) sr=-32767;
-
- *pS++=sl;
- *pS++=sr;
- }
-
- if (seektime != 0 && sampcount < seektime)
- {
- pS=(short *)pSpuBuffer;
- }
- else if ((((unsigned char *)pS)-((unsigned char *)pSpuBuffer)) == (735*4))
- {
-#ifdef ENABLE_SILENCE_SKIPPING
- short *pSilenceIter = (short *)pSpuBuffer;
- int iSilenceCount = 0;
-
- for (; pSilenceIter < pS; pSilenceIter++)
- {
- if (*pSilenceIter == 0)
- iSilenceCount++;
-
- if (iSilenceCount > 20)
- break;
- }
-
- if (iSilenceCount < 20)
-#endif
- psf2_update((u8*)pSpuBuffer,(u8*)pS-(u8*)pSpuBuffer);
-
- pS=(short *)pSpuBuffer;
- }
-
- return(1);
-}
-
-#ifdef TIMEO
-static u64 begintime;
-static u64 gettime64(void)
-{
- struct timeval tv;
- u64 ret;
-
- gettimeofday(&tv,0);
- ret=tv.tv_sec;
- ret*=1000000;
- ret+=tv.tv_usec;
- return(ret);
-}
-#endif
-////////////////////////////////////////////////////////////////////////
-// INIT/EXIT STUFF
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-// SPUINIT: this func will be called first by the main emu
-////////////////////////////////////////////////////////////////////////
-
-int SPUinit(void)
-{
- spuMemC=(u8*)spuMem; // just small setup
- memset((void *)s_chan,0,MAXCHAN*sizeof(SPUCHAN));
- memset((void *)&rvb,0,sizeof(REVERBInfo));
- memset(regArea,0,sizeof(regArea));
- memset(spuMem,0,sizeof(spuMem));
- InitADSR();
- sampcount=ttemp=0;
- #ifdef TIMEO
- begintime=gettime64();
- #endif
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// SETUPSTREAMS: init most of the spu buffers
-////////////////////////////////////////////////////////////////////////
-
-void SetupStreams(void)
-{
- int i;
-
- pSpuBuffer=(u8*)malloc(32768); // alloc mixing buffer
- pS=(s16 *)pSpuBuffer;
-
- for(i=0;i<MAXCHAN;i++) // loop sound channels
- {
- s_chan[i].ADSRX.SustainLevel = 1024; // -> init sustain
- s_chan[i].iIrqDone=0;
- s_chan[i].pLoop=spuMemC;
- s_chan[i].pStart=spuMemC;
- s_chan[i].pCurr=spuMemC;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// REMOVESTREAMS: free most buffer
-////////////////////////////////////////////////////////////////////////
-
-void RemoveStreams(void)
-{
- free(pSpuBuffer); // free mixing buffer
- pSpuBuffer=NULL;
-
- #ifdef TIMEO
- {
- u64 tmp;
- tmp=gettime64();
- tmp-=begintime;
- if(tmp)
- tmp=(u64)sampcount*1000000/tmp;
- printf("%lld samples per second\n",tmp);
- }
- #endif
-}
-
-
-////////////////////////////////////////////////////////////////////////
-// SPUOPEN: called by main emu after init
-////////////////////////////////////////////////////////////////////////
-
-int SPUopen(void)
-{
- if(bSPUIsOpen) return 0; // security for some stupid main emus
- spuIrq=0;
-
- spuStat=spuCtrl=0;
- spuAddr=0xffffffff;
- dwNoiseVal=1;
-
- spuMemC=(u8*)spuMem;
- memset((void *)s_chan,0,(MAXCHAN+1)*sizeof(SPUCHAN));
- pSpuIrq=0;
-
- iVolume=255; //85;
- SetupStreams(); // prepare streaming
-
- bSPUIsOpen=1;
-
- return 1;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-// SPUCLOSE: called before shutdown
-////////////////////////////////////////////////////////////////////////
-
-int SPUclose(void)
-{
- if(!bSPUIsOpen) return 0; // some security
-
- bSPUIsOpen=0; // no more open
-
- RemoveStreams(); // no more streaming
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// SPUSHUTDOWN: called by main emu on final exit
-////////////////////////////////////////////////////////////////////////
-
-int SPUshutdown(void)
-{
- return 0;
-}
-
-void SPUinjectRAMImage(u16 *pIncoming)
-{
- int i;
-
- for (i = 0; i < (256*1024); i++)
- {
- spuMem[i] = pIncoming[i];
- }
-}
diff --git a/src/psf/peops/spu.cc b/src/psf/peops/spu.cc
new file mode 100644
index 000000000000..1e79cbc62eae
--- /dev/null
+++ b/src/psf/peops/spu.cc
@@ -0,0 +1,671 @@
+/***************************************************************************
+ spu.c - description
+ -------------------
+ begin : Wed May 15 2002
+ copyright : (C) 2002 by Pete Bernert
+ email : BlackDove at addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+//*************************************************************************//
+// History of changes:
+//
+// 2003/03/01 - linuzappz
+// - libraryName changes using ALSA
+//
+// 2003/02/28 - Pete
+// - added option for type of interpolation
+// - adjusted spu irqs again (Thousant Arms, Valkyrie Profile)
+// - added MONO support for MSWindows DirectSound
+//
+// 2003/02/20 - kode54
+// - amended interpolation code, goto GOON could skip initialization of gpos and cause segfault
+//
+// 2003/02/19 - kode54
+// - moved SPU IRQ handler and changed sample flag processing
+//
+// 2003/02/18 - kode54
+// - moved ADSR calculation outside of the sample decode loop, somehow I doubt that
+// ADSR timing is relative to the frequency at which a sample is played... I guess
+// this remains to be seen, and I don't know whether ADSR is applied to noise channels...
+//
+// 2003/02/09 - kode54
+// - one-shot samples now process the end block before stopping
+// - in light of removing fmod hack, now processing ADSR on frequency channel as well
+//
+// 2003/02/08 - kode54
+// - replaced easy interpolation with gaussian
+// - removed fmod averaging hack
+// - changed .sinc to be updated from .iRawPitch, no idea why it wasn't done this way already (<- Pete: because I sometimes fail to see the obvious, haharhar :)
+//
+// 2003/02/08 - linuzappz
+// - small bugfix for one usleep that was 1 instead of 1000
+// - added iDisStereo for no stereo (Linux)
+//
+// 2003/01/22 - Pete
+// - added easy interpolation & small noise adjustments
+//
+// 2003/01/19 - Pete
+// - added Neill's reverb
+//
+// 2003/01/12 - Pete
+// - added recording window handlers
+//
+// 2003/01/06 - Pete
+// - added Neill's ADSR timings
+//
+// 2002/12/28 - Pete
+// - adjusted spu irq handling, fmod handling and loop handling
+//
+// 2002/08/14 - Pete
+// - added extra reverb
+//
+// 2002/06/08 - linuzappz
+// - SPUupdate changed for SPUasync
+//
+// 2002/05/15 - Pete
+// - generic cleanup for the Peops release
+//
+//*************************************************************************//
+
+#define _IN_SPU
+
+#include "../peops/stdafx.h"
+#include "../peops/externals.h"
+#include "../peops/regs.h"
+#include "../peops/registers.h"
+#include "../peops/spu.h"
+
+// Enable experimental silence skipping
+// Currently it is too aggressive, destroying the rhythm of some songs
+// See http://redmine.audacious-media-player.org/issues/201
+// #define ENABLE_SILENCE_SKIPPING
+
+void SPUirq(void) ;
+
+//#include "PsxMem.h"
+//#include "driver.h"
+
+////////////////////////////////////////////////////////////////////////
+// globals
+////////////////////////////////////////////////////////////////////////
+
+// psx buffer / addresses
+
+static u16 regArea[0x200];
+static u16 spuMem[256*1024];
+static u8 * spuMemC;
+static u8 * pSpuIrq=0;
+static u8 * pSpuBuffer;
+
+// user settings
+static int iVolume;
+
+// MAIN infos struct for each channel
+
+static SPUCHAN s_chan[MAXCHAN+1]; // channel + 1 infos (1 is security for fmod handling)
+static REVERBInfo rvb;
+
+static u32 dwNoiseVal=1; // global noise generator
+
+static u16 spuCtrl=0; // some vars to store psx reg infos
+static u16 spuStat=0;
+static u16 spuIrq=0;
+static u32 spuAddr=0xffffffff; // address into spu mem
+static int bSPUIsOpen=0;
+
+static const int f[5][2] = {
+ { 0, 0 },
+ { 60, 0 },
+ { 115, -52 },
+ { 98, -55 },
+ { 122, -60 } };
+static s16 * pS;
+static s32 ttemp;
+
+////////////////////////////////////////////////////////////////////////
+// CODE AREA
+////////////////////////////////////////////////////////////////////////
+
+// dirty inline func includes
+
+#include "../peops/reverb.cc"
+#include "../peops/adsr.cc"
+
+// Try this to increase speed.
+#include "../peops/registers.cc"
+#include "../peops/dma.cc"
+
+////////////////////////////////////////////////////////////////////////
+// helpers for so-called "gauss interpolation"
+
+#define gval0 (((int *)(&s_chan[ch].SB[29]))[gpos])
+#define gval(x) (((int *)(&s_chan[ch].SB[29]))[(gpos+x)&3])
+
+#include "gauss_i.h"
+
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// START SOUND... called by main thread to setup a new sound on a channel
+////////////////////////////////////////////////////////////////////////
+
+static inline void StartSound(int ch)
+{
+ StartADSR(ch);
+
+ s_chan[ch].pCurr=s_chan[ch].pStart; // set sample start
+
+ s_chan[ch].s_1=0; // init mixing vars
+ s_chan[ch].s_2=0;
+ s_chan[ch].iSBPos=28;
+
+ s_chan[ch].bNew=0; // init channel flags
+ s_chan[ch].bStop=0;
+ s_chan[ch].bOn=1;
+
+ s_chan[ch].SB[29]=0; // init our interpolation helpers
+ s_chan[ch].SB[30]=0;
+
+ s_chan[ch].spos=0x40000L;s_chan[ch].SB[28]=0; // -> start with more decoding
+}
+
+////////////////////////////////////////////////////////////////////////
+// MAIN SPU FUNCTION
+// here is the main job handler... thread, timer or direct func call
+// basically the whole sound processing is done in this fat func!
+////////////////////////////////////////////////////////////////////////
+
+static u32 sampcount;
+static u32 decaybegin;
+static u32 decayend;
+
+static u32 seektime;
+int psf_seek(u32 t)
+{
+ seektime=t*441/10;
+ if(seektime>sampcount) return(1);
+ return(0);
+}
+
+// Counting to 65536 results in full volume offage.
+void setlength(s32 stop, s32 fade)
+{
+ if(stop==~0)
+ {
+ decaybegin=~0;
+ }
+ else
+ {
+ stop=(stop*441)/10;
+ fade=(fade*441)/10;
+
+ decaybegin=stop;
+ decayend=stop+fade;
+ }
+}
+
+#define CLIP(_x) {if(_x>32767) _x=32767; if(_x<-32767) _x=-32767;}
+int SPUasync(u32 cycles, void (*update)(const void *, int))
+{
+ int volmul=iVolume;
+ static s32 dosampies;
+ s32 temp;
+
+ ttemp+=cycles;
+ dosampies=ttemp/384;
+ if(!dosampies) return(1);
+ ttemp-=dosampies*384;
+ temp=dosampies;
+
+ while(temp)
+ {
+ s32 revLeft=0, revRight=0;
+ s32 sl=0, sr=0;
+ int ch,fa;
+
+ temp--;
+ //--------------------------------------------------//
+ //- main channel loop -//
+ //--------------------------------------------------//
+ {
+ for(ch=0;ch<MAXCHAN;ch++) // loop em all.
+ {
+ if(s_chan[ch].bNew) StartSound(ch); // start new sound
+ if(!s_chan[ch].bOn) continue; // channel not playing? next
+
+
+ if(s_chan[ch].iActFreq!=s_chan[ch].iUsedFreq) // new psx frequency?
+ {
+ s_chan[ch].iUsedFreq=s_chan[ch].iActFreq; // -> take it and calc steps
+ s_chan[ch].sinc=s_chan[ch].iRawPitch<<4;
+ if(!s_chan[ch].sinc) s_chan[ch].sinc=1;
+ }
+
+ while(s_chan[ch].spos>=0x10000L)
+ {
+ if(s_chan[ch].iSBPos==28) // 28 reached?
+ {
+ int predict_nr,shift_factor,flags,d,s;
+ u8* start;unsigned int nSample;
+ int s_1,s_2;
+
+ start=s_chan[ch].pCurr; // set up the current pos
+
+ if (start == (u8*)-1) // special "stop" sign
+ {
+ s_chan[ch].bOn=0; // -> turn everything off
+ s_chan[ch].ADSRX.lVolume=0;
+ s_chan[ch].ADSRX.EnvelopeVol=0;
+ goto ENDX; // -> and done for this channel
+ }
+
+ s_chan[ch].iSBPos=0; // Reset buffer play index.
+
+ //////////////////////////////////////////// spu irq handler here? mmm... do it later
+
+ s_1=s_chan[ch].s_1;
+ s_2=s_chan[ch].s_2;
+
+ predict_nr=(int)*start;start++;
+ shift_factor=predict_nr&0xf;
+ predict_nr >>= 4;
+ flags=(int)*start;start++;
+
+ // -------------------------------------- //
+ // Decode new samples into s_chan[ch].SB[0 through 27]
+ for (nSample=0;nSample<28;start++)
+ {
+ d=(int)*start;
+ s=((d&0xf)<<12);
+ if(s&0x8000) s|=0xffff0000;
+
+ fa=(s >> shift_factor);
+ fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6);
+ s_2=s_1;s_1=fa;
+ s=((d & 0xf0) << 8);
+
+ s_chan[ch].SB[nSample++]=fa;
+
+ if(s&0x8000) s|=0xffff0000;
+ fa=(s>>shift_factor);
+ fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6);
+ s_2=s_1;s_1=fa;
+
+ s_chan[ch].SB[nSample++]=fa;
+ }
+
+ //////////////////////////////////////////// irq check
+
+ if(spuCtrl&0x40) // irq active?
+ {
+ if((pSpuIrq > start-16 && // irq address reached?
+ pSpuIrq <= start) ||
+ ((flags&1) && // special: irq on looping addr, when stop/loop flag is set
+ (pSpuIrq > s_chan[ch].pLoop-16 &&
+ pSpuIrq <= s_chan[ch].pLoop)))
+ {
+ //extern s32 spuirqvoodoo;
+ s_chan[ch].iIrqDone=1; // -> debug flag
+ SPUirq();
+ //puts("IRQ");
+ //if(spuirqvoodoo!=-1)
+ //{
+ // spuirqvoodoo=temp*384;
+ // temp=0;
+ //}
+ }
+ }
+
+ //////////////////////////////////////////// flag handler
+
+ if((flags&4) && (!s_chan[ch].bIgnoreLoop))
+ s_chan[ch].pLoop=start-16; // loop adress
+
+ if(flags&1) // 1: stop/loop
+ {
+ // We play this block out first...
+ //if(!(flags&2)) // 1+2: do loop... otherwise: stop
+ if(flags!=3 || s_chan[ch].pLoop==nullptr) // PETE: if we don't check exactly for 3, loop hang ups will happen (DQ4, for example)
+ { // and checking if pLoop is set avoids crashes, yeah
+ start = (u8*)-1;
+ }
+ else
+ {
+ start = s_chan[ch].pLoop;
+ }
+ }
+
+ s_chan[ch].pCurr=start; // store values for next cycle
+ s_chan[ch].s_1=s_1;
+ s_chan[ch].s_2=s_2;
+
+ ////////////////////////////////////////////
+ }
+
+ fa=s_chan[ch].SB[s_chan[ch].iSBPos++]; // get sample data
+
+ if((spuCtrl&0x4000)==0) fa=0; // muted?
+ else CLIP(fa);
+
+ {
+ int gpos;
+ gpos = s_chan[ch].SB[28];
+ gval0 = fa;
+ gpos = (gpos+1) & 3;
+ s_chan[ch].SB[28] = gpos;
+ }
+ s_chan[ch].spos -= 0x10000L;
+ }
+
+ ////////////////////////////////////////////////
+ // noise handler... just produces some noise data
+ // surely wrong... and no noise frequency (spuCtrl&0x3f00) will be used...
+ // and sometimes the noise will be used as fmod modulation... pfff
+
+ if(s_chan[ch].bNoise)
+ {
+ //puts("Noise");
+ if((dwNoiseVal<<=1)&0x80000000L)
+ {
+ dwNoiseVal^=0x0040001L;
+ fa=((dwNoiseVal>>2)&0x7fff);
+ fa=-fa;
+ }
+ else fa=(dwNoiseVal>>2)&0x7fff;
+
+ // mmm... depending on the noise freq we allow bigger/smaller changes to the previous val
+ fa=s_chan[ch].iOldNoise+((fa-s_chan[ch].iOldNoise)/((0x001f-((spuCtrl&0x3f00)>>9))+1));
+ if(fa>32767L) fa=32767L;
+ if(fa<-32767L) fa=-32767L;
+ s_chan[ch].iOldNoise=fa;
+
+ } //----------------------------------------
+ else // NO NOISE (NORMAL SAMPLE DATA) HERE
+ {
+ int vl, vr, gpos;
+ vl = (s_chan[ch].spos >> 6) & ~3;
+ gpos = s_chan[ch].SB[28];
+ vr=(gauss[vl]*gval0)>>9;
+ vr+=(gauss[vl+1]*gval(1))>>9;
+ vr+=(gauss[vl+2]*gval(2))>>9;
+ vr+=(gauss[vl+3]*gval(3))>>9;
+ fa = vr>>2;
+ }
+
+ s_chan[ch].sval = (MixADSR(ch) * fa)>>10; // / 1023; // add adsr
+ if(s_chan[ch].bFMod==2) // fmod freq channel
+ {
+ int NP=s_chan[ch+1].iRawPitch;
+ NP=((32768L+s_chan[ch].sval)*NP)>>15; ///32768L;
+
+ if(NP>0x3fff) NP=0x3fff;
+ if(NP<0x1) NP=0x1;
+
+ // mmmm... if I do this, all is screwed
+ // s_chan[ch+1].iRawPitch=NP;
+
+ NP=(44100L*NP)/(4096L); // calc frequency
+
+ s_chan[ch+1].iActFreq=NP;
+ s_chan[ch+1].iUsedFreq=NP;
+ s_chan[ch+1].sinc=(((NP/10)<<16)/4410);
+ if(!s_chan[ch+1].sinc) s_chan[ch+1].sinc=1;
+
+ // mmmm... set up freq decoding positions?
+ // s_chan[ch+1].iSBPos=28;
+ // s_chan[ch+1].spos=0x10000L;
+ }
+ else
+ {
+ //////////////////////////////////////////////
+ // ok, left/right sound volume (psx volume goes from 0 ... 0x3fff)
+ int tmpl,tmpr;
+
+ if (1) //ao_channel_enable[ch+PSF_1]) {
+ {
+ tmpl=(s_chan[ch].sval*s_chan[ch].iLeftVolume)>>14;
+ tmpr=(s_chan[ch].sval*s_chan[ch].iRightVolume)>>14;
+ } else {
+ tmpl = 0;
+ tmpr = 0;
+ }
+ sl+=tmpl;
+ sr+=tmpr;
+
+ if(((rvb.Enabled>>ch)&1) && (spuCtrl&0x80))
+ {
+ revLeft+=tmpl;
+ revRight+=tmpr;
+ }
+ }
+
+ s_chan[ch].spos += s_chan[ch].sinc;
+ ENDX: ;
+ }
+ }
+
+ ///////////////////////////////////////////////////////
+ // mix all channels (including reverb) into one buffer
+ MixREVERBLeftRight(&sl,&sr,revLeft,revRight);
+// printf("sampcount %d decaybegin %d decayend %d\n", sampcount, decaybegin, decayend);
+ if(sampcount>=decaybegin)
+ {
+ s32 dmul;
+ if(decaybegin!=~0) // Is anyone REALLY going to be playing a song
+ // for 13 hours?
+ {
+ if(sampcount>=decayend)
+ {
+ update(nullptr, 0);
+ return(0);
+ }
+ dmul=256-(256*(sampcount-decaybegin)/(decayend-decaybegin));
+ sl=(sl*dmul)>>8;
+ sr=(sr*dmul)>>8;
+ }
+ }
+
+ sampcount++;
+ sl=(sl*volmul)>>8;
+ sr=(sr*volmul)>>8;
+
+ //{
+ // static double asl=0;
+ // static double asr=0;
+
+ // asl+=(sl-asl)/5;
+ // asr+=(sl-asr)/5;
+
+ //sl-=asl;
+ //sr-=asr;
+
+ // if(sl>32767 || sl < -32767) printf("Left: %d, %f\n",sl,asl);
+ // if(sr>32767 || sr < -32767) printf("Right: %d, %f\n",sl,asl);
+ //}
+
+ if(sl>32767) sl=32767; if(sl<-32767) sl=-32767;
+ if(sr>32767) sr=32767; if(sr<-32767) sr=-32767;
+
+ *pS++=sl;
+ *pS++=sr;
+ }
+
+ if (seektime != 0 && sampcount < seektime)
+ {
+ pS=(short *)pSpuBuffer;
+ }
+ else if ((((unsigned char *)pS)-((unsigned char *)pSpuBuffer)) == (735*4))
+ {
+#ifdef ENABLE_SILENCE_SKIPPING
+ short *pSilenceIter = (short *)pSpuBuffer;
+ int iSilenceCount = 0;
+
+ for (; pSilenceIter < pS; pSilenceIter++)
+ {
+ if (*pSilenceIter == 0)
+ iSilenceCount++;
+
+ if (iSilenceCount > 20)
+ break;
+ }
+
+ if (iSilenceCount < 20)
+#endif
+ update((u8*)pSpuBuffer,(u8*)pS-(u8*)pSpuBuffer);
+
+ pS=(short *)pSpuBuffer;
+ }
+
+ return(1);
+}
+
+#ifdef TIMEO
+static u64 begintime;
+static u64 gettime64(void)
+{
+ struct timeval tv;
+ u64 ret;
+
+ gettimeofday(&tv,0);
+ ret=tv.tv_sec;
+ ret*=1000000;
+ ret+=tv.tv_usec;
+ return(ret);
+}
+#endif
+////////////////////////////////////////////////////////////////////////
+// INIT/EXIT STUFF
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// SPUINIT: this func will be called first by the main emu
+////////////////////////////////////////////////////////////////////////
+
+int SPUinit(void)
+{
+ spuMemC=(u8*)spuMem; // just small setup
+ memset((void *)s_chan,0,MAXCHAN*sizeof(SPUCHAN));
+ memset((void *)&rvb,0,sizeof(REVERBInfo));
+ memset(regArea,0,sizeof(regArea));
+ memset(spuMem,0,sizeof(spuMem));
+ InitADSR();
+ sampcount=ttemp=0;
+ #ifdef TIMEO
+ begintime=gettime64();
+ #endif
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// SETUPSTREAMS: init most of the spu buffers
+////////////////////////////////////////////////////////////////////////
+
+void SetupStreams(void)
+{
+ int i;
+
+ pSpuBuffer=(u8*)malloc(32768); // alloc mixing buffer
+ pS=(s16 *)pSpuBuffer;
+
+ for(i=0;i<MAXCHAN;i++) // loop sound channels
+ {
+ s_chan[i].ADSRX.SustainLevel = 1024; // -> init sustain
+ s_chan[i].iIrqDone=0;
+ s_chan[i].pLoop=spuMemC;
+ s_chan[i].pStart=spuMemC;
+ s_chan[i].pCurr=spuMemC;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// REMOVESTREAMS: free most buffer
+////////////////////////////////////////////////////////////////////////
+
+void RemoveStreams(void)
+{
+ free(pSpuBuffer); // free mixing buffer
+ pSpuBuffer=nullptr;
+
+ #ifdef TIMEO
+ {
+ u64 tmp;
+ tmp=gettime64();
+ tmp-=begintime;
+ if(tmp)
+ tmp=(u64)sampcount*1000000/tmp;
+ printf("%lld samples per second\n",tmp);
+ }
+ #endif
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// SPUOPEN: called by main emu after init
+////////////////////////////////////////////////////////////////////////
+
+int SPUopen(void)
+{
+ if(bSPUIsOpen) return 0; // security for some stupid main emus
+ spuIrq=0;
+
+ spuStat=spuCtrl=0;
+ spuAddr=0xffffffff;
+ dwNoiseVal=1;
+
+ spuMemC=(u8*)spuMem;
+ memset((void *)s_chan,0,(MAXCHAN+1)*sizeof(SPUCHAN));
+ pSpuIrq=0;
+
+ iVolume=255; //85;
+ SetupStreams(); // prepare streaming
+
+ bSPUIsOpen=1;
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// SPUCLOSE: called before shutdown
+////////////////////////////////////////////////////////////////////////
+
+int SPUclose(void)
+{
+ if(!bSPUIsOpen) return 0; // some security
+
+ bSPUIsOpen=0; // no more open
+
+ RemoveStreams(); // no more streaming
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// SPUSHUTDOWN: called by main emu on final exit
+////////////////////////////////////////////////////////////////////////
+
+int SPUshutdown(void)
+{
+ return 0;
+}
+
+void SPUinjectRAMImage(u16 *pIncoming)
+{
+ int i;
+
+ for (i = 0; i < (256*1024); i++)
+ {
+ spuMem[i] = pIncoming[i];
+ }
+}
diff --git a/src/psf/peops/spu.h b/src/psf/peops/spu.h
index 3c2cee4143e3..647a7780495f 100644
--- a/src/psf/peops/spu.h
+++ b/src/psf/peops/spu.h
@@ -26,7 +26,7 @@
void sexyd_update(unsigned char* pSound,long lBytes);
-int SPUasync(u32 cycles);
+int SPUasync(u32 cycles, void (*update)(const void *, int));
void SPU_flushboot(void);
int SPUinit(void);
int SPUopen(void);
diff --git a/src/psf/peops2/License.txt b/src/psf/peops2/License.txt
index e51338c2caa9..e1e8495a4f3c 100644
--- a/src/psf/peops2/License.txt
+++ b/src/psf/peops2/License.txt
@@ -4,7 +4,8 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
diff --git a/src/psf/peops2/adsr.c b/src/psf/peops2/adsr.c
deleted file mode 100644
index 57547ffefdc8..000000000000
--- a/src/psf/peops2/adsr.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/***************************************************************************
- adsr.c - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove at addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-//*************************************************************************//
-// History of changes:
-//
-// 2003/05/14 - xodnizel
-// - removed stopping of reverb on sample end
-//
-// 2003/01/06 - Pete
-// - added Neill's ADSR timings
-//
-// 2002/05/15 - Pete
-// - generic cleanup for the Peops release
-//
-//*************************************************************************//
-
-#include "stdafx.h"
-
-#define _IN_ADSR
-
-// will be included from spu.c
-#ifdef _IN_SPU
-
-////////////////////////////////////////////////////////////////////////
-// ADSR func
-////////////////////////////////////////////////////////////////////////
-
-unsigned long RateTable[160];
-
-void InitADSR(void) // INIT ADSR
-{
- unsigned long r,rs,rd;int i;
-
- memset(RateTable,0,sizeof(unsigned long)*160); // build the rate table according to Neill's rules (see at bottom of file)
-
- r=3;rs=1;rd=0;
-
- for(i=32;i<160;i++) // we start at pos 32 with the real values... everything before is 0
- {
- if(r<0x3FFFFFFF)
- {
- r+=rs;
- rd++;if(rd==5) {rd=1;rs*=2;}
- }
- if(r>0x3FFFFFFF) r=0x3FFFFFFF;
-
- RateTable[i]=r;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void StartADSR(int ch) // MIX ADSR
-{
- s_chan[ch].ADSRX.lVolume=1; // and init some adsr vars
- s_chan[ch].ADSRX.State=0;
- s_chan[ch].ADSRX.EnvelopeVol=0;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-int MixADSR(int ch) // MIX ADSR
-{
- if(s_chan[ch].bStop) // should be stopped:
- { // do release
- if(s_chan[ch].ADSRX.ReleaseModeExp)
- {
- switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
- {
- case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +0 + 32]; break;
- case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +4 + 32]; break;
- case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +6 + 32]; break;
- case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +8 + 32]; break;
- case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +9 + 32]; break;
- case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +10+ 32]; break;
- case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +11+ 32]; break;
- case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +12+ 32]; break;
- }
- }
- else
- {
- s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x0C + 32];
- }
-
- if(s_chan[ch].ADSRX.EnvelopeVol<0)
- {
- s_chan[ch].ADSRX.EnvelopeVol=0;
- s_chan[ch].bOn=0;
- //s_chan[ch].bReverb=0;
- //s_chan[ch].bNoise=0;
- }
-
- s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
- return s_chan[ch].ADSRX.lVolume;
- }
- else // not stopped yet?
- {
- if(s_chan[ch].ADSRX.State==0) // -> attack
- {
- if(s_chan[ch].ADSRX.AttackModeExp)
- {
- if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
- else
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x18 + 32];
- }
- else
- {
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
- }
-
- if(s_chan[ch].ADSRX.EnvelopeVol<0)
- {
- s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
- s_chan[ch].ADSRX.State=1;
- }
-
- s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
- return s_chan[ch].ADSRX.lVolume;
- }
- //--------------------------------------------------//
- if(s_chan[ch].ADSRX.State==1) // -> decay
- {
- switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
- {
- case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+0 + 32]; break;
- case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+4 + 32]; break;
- case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+6 + 32]; break;
- case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+8 + 32]; break;
- case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+9 + 32]; break;
- case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+10+ 32]; break;
- case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+11+ 32]; break;
- case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+12+ 32]; break;
- }
-
- if(s_chan[ch].ADSRX.EnvelopeVol<0) s_chan[ch].ADSRX.EnvelopeVol=0;
- if(((s_chan[ch].ADSRX.EnvelopeVol>>27)&0xF) <= s_chan[ch].ADSRX.SustainLevel)
- {
- s_chan[ch].ADSRX.State=2;
- }
-
- s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
- return s_chan[ch].ADSRX.lVolume;
- }
- //--------------------------------------------------//
- if(s_chan[ch].ADSRX.State==2) // -> sustain
- {
- if(s_chan[ch].ADSRX.SustainIncrease)
- {
- if(s_chan[ch].ADSRX.SustainModeExp)
- {
- if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
- else
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x18 + 32];
- }
- else
- {
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
- }
-
- if(s_chan[ch].ADSRX.EnvelopeVol<0)
- {
- s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
- }
- }
- else
- {
- if(s_chan[ch].ADSRX.SustainModeExp)
- {
- switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
- {
- case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +0 + 32];break;
- case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +4 + 32];break;
- case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +6 + 32];break;
- case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +8 + 32];break;
- case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +9 + 32];break;
- case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +10+ 32];break;
- case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +11+ 32];break;
- case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +12+ 32];break;
- }
- }
- else
- {
- s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x0F + 32];
- }
-
- if(s_chan[ch].ADSRX.EnvelopeVol<0)
- {
- s_chan[ch].ADSRX.EnvelopeVol=0;
- }
- }
- s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
- return s_chan[ch].ADSRX.lVolume;
- }
- }
- return 0;
-}
-
-#endif
-
-/*
-James Higgs ADSR investigations:
-
-PSX SPU Envelope Timings
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-First, here is an extract from doomed's SPU doc, which explains the basics
-of the SPU "volume envelope":
-
-*** doomed doc extract start ***
-
---------------------------------------------------------------------------
-Voices.
---------------------------------------------------------------------------
-The SPU has 24 hardware voices. These voices can be used to reproduce sample
-data, noise or can be used as frequency modulator on the next voice.
-Each voice has it's own programmable ADSR envelope filter. The main volume
-can be programmed independently for left and right output.
-
-The ADSR envelope filter works as follows:
-Ar = Attack rate, which specifies the speed at which the volume increases
- from zero to it's maximum value, as soon as the note on is given. The
- slope can be set to lineair or exponential.
-Dr = Decay rate specifies the speed at which the volume decreases to the
- sustain level. Decay is always decreasing exponentially.
-Sl = Sustain level, base level from which sustain starts.
-Sr = Sustain rate is the rate at which the volume of the sustained note
- increases or decreases. This can be either lineair or exponential.
-Rr = Release rate is the rate at which the volume of the note decreases
- as soon as the note off is given.
-
- lvl |
- ^ | /\Dr __
- Sl _| _ / _ \__--- \
- | / ---__ \ Rr
- | /Ar Sr \ \
- | / \\
- |/___________________\________
- ->time
-
-The overal volume can also be set to sweep up or down lineairly or
-exponentially from it's current value. This can be done seperately
-for left and right.
-
-Relevant SPU registers:
--------------------------------------------------------------
-$1f801xx8 Attack/Decay/Sustain level
-bit |0f|0e 0d 0c 0b 0a 09 08|07 06 05 04|03 02 01 00|
-desc.|Am| Ar |Dr |Sl |
-
-Am 0 Attack mode Linear
- 1 Exponential
-
-Ar 0-7f attack rate
-Dr 0-f decay rate
-Sl 0-f sustain level
--------------------------------------------------------------
-$1f801xxa Sustain rate, Release Rate.
-bit |0f|0e|0d|0c 0b 0a 09 08 07 06|05|04 03 02 01 00|
-desc.|Sm|Sd| 0| Sr |Rm|Rr |
-
-Sm 0 sustain rate mode linear
- 1 exponential
-Sd 0 sustain rate mode increase
- 1 decrease
-Sr 0-7f Sustain Rate
-Rm 0 Linear decrease
- 1 Exponential decrease
-Rr 0-1f Release Rate
-
-Note: decay mode is always Expontial decrease, and thus cannot
-be set.
--------------------------------------------------------------
-$1f801xxc Current ADSR volume
-bit |0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00|
-desc.|ADSRvol |
-
-ADSRvol Returns the current envelope volume when
- read.
--- James' Note: return range: 0 -> 32767
-
-*** doomed doc extract end ***
-
-By using a small PSX proggie to visualise the envelope as it was played,
-the following results for envelope timing were obtained:
-
-1. Attack rate value (linear mode)
-
- Attack value range: 0 -> 127
-
- Value | 48 | 52 | 56 | 60 | 64 | 68 | 72 | | 80 |
- -----------------------------------------------------------------
- Frames | 11 | 21 | 42 | 84 | 169| 338| 676| |2890|
-
- Note: frames is no. of PAL frames to reach full volume (100%
- amplitude)
-
- Hmm, noticing that the time taken to reach full volume doubles
- every time we add 4 to our attack value, we know the equation is
- of form:
- frames = k * 2 ^ (value / 4)
-
- (You may ponder about envelope generator hardware at this point,
- or maybe not... :)
-
- By substituting some stuff and running some checks, we get:
-
- k = 0.00257 (close enuf)
-
- therefore,
- frames = 0.00257 * 2 ^ (value / 4)
- If you just happen to be writing an emulator, then you can probably
- use an equation like:
-
- %volume_increase_per_tick = 1 / frames
-
-
- ------------------------------------
- Pete:
- ms=((1<<(value>>2))*514)/10000
- ------------------------------------
-
-2. Decay rate value (only has log mode)
-
- Decay value range: 0 -> 15
-
- Value | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
- ------------------------------------------------
- frames | | | | | 6 | 12 | 24 | 47 |
-
- Note: frames here is no. of PAL frames to decay to 50% volume.
-
- formula: frames = k * 2 ^ (value)
-
- Substituting, we get: k = 0.00146
-
- Further info on logarithmic nature:
- frames to decay to sustain level 3 = 3 * frames to decay to
- sustain level 9
-
- Also no. of frames to 25% volume = roughly 1.85 * no. of frames to
- 50% volume.
-
- Frag it - just use linear approx.
-
- ------------------------------------
- Pete:
- ms=((1<<value)*292)/10000
- ------------------------------------
-
-
-3. Sustain rate value (linear mode)
-
- Sustain rate range: 0 -> 127
-
- Value | 48 | 52 | 56 | 60 | 64 | 68 | 72 |
- -------------------------------------------
- frames | 9 | 19 | 37 | 74 | 147| 293| 587|
-
- Here, frames = no. of PAL frames for volume amplitude to go from 100%
- to 0% (or vice-versa).
-
- Same formula as for attack value, just a different value for k:
-
- k = 0.00225
-
- ie: frames = 0.00225 * 2 ^ (value / 4)
-
- For emulation purposes:
-
- %volume_increase_or_decrease_per_tick = 1 / frames
-
- ------------------------------------
- Pete:
- ms=((1<<(value>>2))*450)/10000
- ------------------------------------
-
-
-4. Release rate (linear mode)
-
- Release rate range: 0 -> 31
-
- Value | 13 | 14 | 15 | 16 | 17 |
- ---------------------------------------------------------------
- frames | 18 | 36 | 73 | 146| 292|
-
- Here, frames = no. of PAL frames to decay from 100% vol to 0% vol
- after "note-off" is triggered.
-
- Formula: frames = k * 2 ^ (value)
-
- And so: k = 0.00223
-
- ------------------------------------
- Pete:
- ms=((1<<value)*446)/10000
- ------------------------------------
-
-
-Other notes:
-
-Log stuff not figured out. You may get some clues from the "Decay rate"
-stuff above. For emu purposes it may not be important - use linear
-approx.
-
-To get timings in millisecs, multiply frames by 20.
-
-
-
-- James Higgs 17/6/2000
-james7780 at yahoo.com
-
-//---------------------------------------------------------------
-
-OLD adsr mixing according to james' rules... has to be called
-every one millisecond
-
-
- long v,v2,lT,l1,l2,l3;
-
- if(s_chan[ch].bStop) // psx wants to stop? -> release phase
- {
- if(s_chan[ch].ADSR.ReleaseVal!=0) // -> release not 0: do release (if 0: stop right now)
- {
- if(!s_chan[ch].ADSR.ReleaseVol) // --> release just started? set up the release stuff
- {
- s_chan[ch].ADSR.ReleaseStartTime=s_chan[ch].ADSR.lTime;
- s_chan[ch].ADSR.ReleaseVol=s_chan[ch].ADSR.lVolume;
- s_chan[ch].ADSR.ReleaseTime = // --> calc how long does it take to reach the wanted sus level
- (s_chan[ch].ADSR.ReleaseTime*
- s_chan[ch].ADSR.ReleaseVol)/1024;
- }
- // -> NO release exp mode used (yet)
- v=s_chan[ch].ADSR.ReleaseVol; // -> get last volume
- lT=s_chan[ch].ADSR.lTime- // -> how much time is past?
- s_chan[ch].ADSR.ReleaseStartTime;
- l1=s_chan[ch].ADSR.ReleaseTime;
-
- if(lT<l1) // -> we still have to release
- {
- v=v-((v*lT)/l1); // --> calc new volume
- }
- else // -> release is over: now really stop that sample
- {v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;}
- }
- else // -> release IS 0: release at once
- {
- v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;
- }
- }
- else
- {//--------------------------------------------------// not in release phase:
- v=1024;
- lT=s_chan[ch].ADSR.lTime;
- l1=s_chan[ch].ADSR.AttackTime;
-
- if(lT<l1) // attack
- { // no exp mode used (yet)
-// if(s_chan[ch].ADSR.AttackModeExp)
-// {
-// v=(v*lT)/l1;
-// }
-// else
- {
- v=(v*lT)/l1;
- }
- if(v==0) v=1;
- }
- else // decay
- { // should be exp, but who cares? ;)
- l2=s_chan[ch].ADSR.DecayTime;
- v2=s_chan[ch].ADSR.SustainLevel;
-
- lT-=l1;
- if(lT<l2)
- {
- v-=(((v-v2)*lT)/l2);
- }
- else // sustain
- { // no exp mode used (yet)
- l3=s_chan[ch].ADSR.SustainTime;
- lT-=l2;
- if(s_chan[ch].ADSR.SustainModeDec>0)
- {
- if(l3!=0) v2+=((v-v2)*lT)/l3;
- else v2=v;
- }
- else
- {
- if(l3!=0) v2-=(v2*lT)/l3;
- else v2=v;
- }
-
- if(v2>v) v2=v;
- if(v2<=0) {v2=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;}
-
- v=v2;
- }
- }
- }
-
- //----------------------------------------------------//
- // ok, done for this channel, so increase time
-
- s_chan[ch].ADSR.lTime+=1; // 1 = 1.020408f ms;
-
- if(v>1024) v=1024; // adjust volume
- if(v<0) v=0;
- s_chan[ch].ADSR.lVolume=v; // store act volume
-
- return v; // return the volume factor
-*/
-
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-
-/*
------------------------------------------------------------------------------
-Neill Corlett
-Playstation SPU envelope timing notes
------------------------------------------------------------------------------
-
-This is preliminary. This may be wrong. But the model described herein fits
-all of my experimental data, and it's just simple enough to sound right.
-
-ADSR envelope level ranges from 0x00000000 to 0x7FFFFFFF internally.
-The value returned by channel reg 0xC is (envelope_level>>16).
-
-Each sample, an increment or decrement value will be added to or
-subtracted from this envelope level.
-
-Create the rate log table. The values double every 4 entries.
- entry #0 = 4
-
- 4, 5, 6, 7,
- 8,10,12,14,
- 16,20,24,28, ...
-
- entry #40 = 4096...
- entry #44 = 8192...
- entry #48 = 16384...
- entry #52 = 32768...
- entry #56 = 65536...
-
-increments and decrements are in terms of ratelogtable[n]
-n may exceed the table bounds (plan on n being between -32 and 127).
-table values are all clipped between 0x00000000 and 0x3FFFFFFF
-
-when you "voice on", the envelope is always fully reset.
-(yes, it may click. the real thing does this too.)
-
-envelope level begins at zero.
-
-each state happens for at least 1 cycle
-(transitions are not instantaneous)
-this may result in some oddness: if the decay rate is uberfast, it will cut
-the envelope from full down to half in one sample, potentially skipping over
-the sustain level
-
-ATTACK
-------
-- if the envelope level has overflowed past the max, clip to 0x7FFFFFFF and
- proceed to DECAY.
-
-Linear attack mode:
-- line extends upward to 0x7FFFFFFF
-- increment per sample is ratelogtable[(Ar^0x7F)-0x10]
-
-Logarithmic attack mode:
-if envelope_level < 0x60000000:
- - line extends upward to 0x60000000
- - increment per sample is ratelogtable[(Ar^0x7F)-0x10]
-else:
- - line extends upward to 0x7FFFFFFF
- - increment per sample is ratelogtable[(Ar^0x7F)-0x18]
-
-DECAY
------
-- if ((envelope_level>>27)&0xF) <= Sl, proceed to SUSTAIN.
- Do not clip to the sustain level.
-- current line ends at (envelope_level & 0x07FFFFFF)
-- decrement per sample depends on (envelope_level>>28)&0x7
- 0: ratelogtable[(4*(Dr^0x1F))-0x18+0]
- 1: ratelogtable[(4*(Dr^0x1F))-0x18+4]
- 2: ratelogtable[(4*(Dr^0x1F))-0x18+6]
- 3: ratelogtable[(4*(Dr^0x1F))-0x18+8]
- 4: ratelogtable[(4*(Dr^0x1F))-0x18+9]
- 5: ratelogtable[(4*(Dr^0x1F))-0x18+10]
- 6: ratelogtable[(4*(Dr^0x1F))-0x18+11]
- 7: ratelogtable[(4*(Dr^0x1F))-0x18+12]
- (note that this is the same as the release rate formula, except that
- decay rates 10-1F aren't possible... those would be slower in theory)
-
-SUSTAIN
--------
-- no terminating condition except for voice off
-- Sd=0 (increase) behavior is identical to ATTACK for both log and linear.
-- Sd=1 (decrease) behavior:
-Linear sustain decrease:
-- line extends to 0x00000000
-- decrement per sample is ratelogtable[(Sr^0x7F)-0x0F]
-Logarithmic sustain decrease:
-- current line ends at (envelope_level & 0x07FFFFFF)
-- decrement per sample depends on (envelope_level>>28)&0x7
- 0: ratelogtable[(Sr^0x7F)-0x1B+0]
- 1: ratelogtable[(Sr^0x7F)-0x1B+4]
- 2: ratelogtable[(Sr^0x7F)-0x1B+6]
- 3: ratelogtable[(Sr^0x7F)-0x1B+8]
- 4: ratelogtable[(Sr^0x7F)-0x1B+9]
- 5: ratelogtable[(Sr^0x7F)-0x1B+10]
- 6: ratelogtable[(Sr^0x7F)-0x1B+11]
- 7: ratelogtable[(Sr^0x7F)-0x1B+12]
-
-RELEASE
--------
-- if the envelope level has overflowed to negative, clip to 0 and QUIT.
-
-Linear release mode:
-- line extends to 0x00000000
-- decrement per sample is ratelogtable[(4*(Rr^0x1F))-0x0C]
-
-Logarithmic release mode:
-- line extends to (envelope_level & 0x0FFFFFFF)
-- decrement per sample depends on (envelope_level>>28)&0x7
- 0: ratelogtable[(4*(Rr^0x1F))-0x18+0]
- 1: ratelogtable[(4*(Rr^0x1F))-0x18+4]
- 2: ratelogtable[(4*(Rr^0x1F))-0x18+6]
- 3: ratelogtable[(4*(Rr^0x1F))-0x18+8]
- 4: ratelogtable[(4*(Rr^0x1F))-0x18+9]
- 5: ratelogtable[(4*(Rr^0x1F))-0x18+10]
- 6: ratelogtable[(4*(Rr^0x1F))-0x18+11]
- 7: ratelogtable[(4*(Rr^0x1F))-0x18+12]
-
------------------------------------------------------------------------------
-*/
-
diff --git a/src/psf/peops2/adsr.cc b/src/psf/peops2/adsr.cc
new file mode 100644
index 000000000000..57547ffefdc8
--- /dev/null
+++ b/src/psf/peops2/adsr.cc
@@ -0,0 +1,656 @@
+/***************************************************************************
+ adsr.c - description
+ -------------------
+ begin : Wed May 15 2002
+ copyright : (C) 2002 by Pete Bernert
+ email : BlackDove at addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+//*************************************************************************//
+// History of changes:
+//
+// 2003/05/14 - xodnizel
+// - removed stopping of reverb on sample end
+//
+// 2003/01/06 - Pete
+// - added Neill's ADSR timings
+//
+// 2002/05/15 - Pete
+// - generic cleanup for the Peops release
+//
+//*************************************************************************//
+
+#include "stdafx.h"
+
+#define _IN_ADSR
+
+// will be included from spu.c
+#ifdef _IN_SPU
+
+////////////////////////////////////////////////////////////////////////
+// ADSR func
+////////////////////////////////////////////////////////////////////////
+
+unsigned long RateTable[160];
+
+void InitADSR(void) // INIT ADSR
+{
+ unsigned long r,rs,rd;int i;
+
+ memset(RateTable,0,sizeof(unsigned long)*160); // build the rate table according to Neill's rules (see at bottom of file)
+
+ r=3;rs=1;rd=0;
+
+ for(i=32;i<160;i++) // we start at pos 32 with the real values... everything before is 0
+ {
+ if(r<0x3FFFFFFF)
+ {
+ r+=rs;
+ rd++;if(rd==5) {rd=1;rs*=2;}
+ }
+ if(r>0x3FFFFFFF) r=0x3FFFFFFF;
+
+ RateTable[i]=r;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void StartADSR(int ch) // MIX ADSR
+{
+ s_chan[ch].ADSRX.lVolume=1; // and init some adsr vars
+ s_chan[ch].ADSRX.State=0;
+ s_chan[ch].ADSRX.EnvelopeVol=0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+int MixADSR(int ch) // MIX ADSR
+{
+ if(s_chan[ch].bStop) // should be stopped:
+ { // do release
+ if(s_chan[ch].ADSRX.ReleaseModeExp)
+ {
+ switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
+ {
+ case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +0 + 32]; break;
+ case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +4 + 32]; break;
+ case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +6 + 32]; break;
+ case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +8 + 32]; break;
+ case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +9 + 32]; break;
+ case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +10+ 32]; break;
+ case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +11+ 32]; break;
+ case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +12+ 32]; break;
+ }
+ }
+ else
+ {
+ s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x0C + 32];
+ }
+
+ if(s_chan[ch].ADSRX.EnvelopeVol<0)
+ {
+ s_chan[ch].ADSRX.EnvelopeVol=0;
+ s_chan[ch].bOn=0;
+ //s_chan[ch].bReverb=0;
+ //s_chan[ch].bNoise=0;
+ }
+
+ s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
+ return s_chan[ch].ADSRX.lVolume;
+ }
+ else // not stopped yet?
+ {
+ if(s_chan[ch].ADSRX.State==0) // -> attack
+ {
+ if(s_chan[ch].ADSRX.AttackModeExp)
+ {
+ if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
+ s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
+ else
+ s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x18 + 32];
+ }
+ else
+ {
+ s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
+ }
+
+ if(s_chan[ch].ADSRX.EnvelopeVol<0)
+ {
+ s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
+ s_chan[ch].ADSRX.State=1;
+ }
+
+ s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
+ return s_chan[ch].ADSRX.lVolume;
+ }
+ //--------------------------------------------------//
+ if(s_chan[ch].ADSRX.State==1) // -> decay
+ {
+ switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
+ {
+ case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+0 + 32]; break;
+ case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+4 + 32]; break;
+ case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+6 + 32]; break;
+ case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+8 + 32]; break;
+ case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+9 + 32]; break;
+ case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+10+ 32]; break;
+ case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+11+ 32]; break;
+ case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+12+ 32]; break;
+ }
+
+ if(s_chan[ch].ADSRX.EnvelopeVol<0) s_chan[ch].ADSRX.EnvelopeVol=0;
+ if(((s_chan[ch].ADSRX.EnvelopeVol>>27)&0xF) <= s_chan[ch].ADSRX.SustainLevel)
+ {
+ s_chan[ch].ADSRX.State=2;
+ }
+
+ s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
+ return s_chan[ch].ADSRX.lVolume;
+ }
+ //--------------------------------------------------//
+ if(s_chan[ch].ADSRX.State==2) // -> sustain
+ {
+ if(s_chan[ch].ADSRX.SustainIncrease)
+ {
+ if(s_chan[ch].ADSRX.SustainModeExp)
+ {
+ if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
+ s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
+ else
+ s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x18 + 32];
+ }
+ else
+ {
+ s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
+ }
+
+ if(s_chan[ch].ADSRX.EnvelopeVol<0)
+ {
+ s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
+ }
+ }
+ else
+ {
+ if(s_chan[ch].ADSRX.SustainModeExp)
+ {
+ switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
+ {
+ case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +0 + 32];break;
+ case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +4 + 32];break;
+ case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +6 + 32];break;
+ case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +8 + 32];break;
+ case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +9 + 32];break;
+ case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +10+ 32];break;
+ case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +11+ 32];break;
+ case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +12+ 32];break;
+ }
+ }
+ else
+ {
+ s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x0F + 32];
+ }
+
+ if(s_chan[ch].ADSRX.EnvelopeVol<0)
+ {
+ s_chan[ch].ADSRX.EnvelopeVol=0;
+ }
+ }
+ s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
+ return s_chan[ch].ADSRX.lVolume;
+ }
+ }
+ return 0;
+}
+
+#endif
+
+/*
+James Higgs ADSR investigations:
+
+PSX SPU Envelope Timings
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+First, here is an extract from doomed's SPU doc, which explains the basics
+of the SPU "volume envelope":
+
+*** doomed doc extract start ***
+
+--------------------------------------------------------------------------
+Voices.
+--------------------------------------------------------------------------
+The SPU has 24 hardware voices. These voices can be used to reproduce sample
+data, noise or can be used as frequency modulator on the next voice.
+Each voice has it's own programmable ADSR envelope filter. The main volume
+can be programmed independently for left and right output.
+
+The ADSR envelope filter works as follows:
+Ar = Attack rate, which specifies the speed at which the volume increases
+ from zero to it's maximum value, as soon as the note on is given. The
+ slope can be set to lineair or exponential.
+Dr = Decay rate specifies the speed at which the volume decreases to the
+ sustain level. Decay is always decreasing exponentially.
+Sl = Sustain level, base level from which sustain starts.
+Sr = Sustain rate is the rate at which the volume of the sustained note
+ increases or decreases. This can be either lineair or exponential.
+Rr = Release rate is the rate at which the volume of the note decreases
+ as soon as the note off is given.
+
+ lvl |
+ ^ | /\Dr __
+ Sl _| _ / _ \__--- \
+ | / ---__ \ Rr
+ | /Ar Sr \ \
+ | / \\
+ |/___________________\________
+ ->time
+
+The overal volume can also be set to sweep up or down lineairly or
+exponentially from it's current value. This can be done seperately
+for left and right.
+
+Relevant SPU registers:
+-------------------------------------------------------------
+$1f801xx8 Attack/Decay/Sustain level
+bit |0f|0e 0d 0c 0b 0a 09 08|07 06 05 04|03 02 01 00|
+desc.|Am| Ar |Dr |Sl |
+
+Am 0 Attack mode Linear
+ 1 Exponential
+
+Ar 0-7f attack rate
+Dr 0-f decay rate
+Sl 0-f sustain level
+-------------------------------------------------------------
+$1f801xxa Sustain rate, Release Rate.
+bit |0f|0e|0d|0c 0b 0a 09 08 07 06|05|04 03 02 01 00|
+desc.|Sm|Sd| 0| Sr |Rm|Rr |
+
+Sm 0 sustain rate mode linear
+ 1 exponential
+Sd 0 sustain rate mode increase
+ 1 decrease
+Sr 0-7f Sustain Rate
+Rm 0 Linear decrease
+ 1 Exponential decrease
+Rr 0-1f Release Rate
+
+Note: decay mode is always Expontial decrease, and thus cannot
+be set.
+-------------------------------------------------------------
+$1f801xxc Current ADSR volume
+bit |0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00|
+desc.|ADSRvol |
+
+ADSRvol Returns the current envelope volume when
+ read.
+-- James' Note: return range: 0 -> 32767
+
+*** doomed doc extract end ***
+
+By using a small PSX proggie to visualise the envelope as it was played,
+the following results for envelope timing were obtained:
+
+1. Attack rate value (linear mode)
+
+ Attack value range: 0 -> 127
+
+ Value | 48 | 52 | 56 | 60 | 64 | 68 | 72 | | 80 |
+ -----------------------------------------------------------------
+ Frames | 11 | 21 | 42 | 84 | 169| 338| 676| |2890|
+
+ Note: frames is no. of PAL frames to reach full volume (100%
+ amplitude)
+
+ Hmm, noticing that the time taken to reach full volume doubles
+ every time we add 4 to our attack value, we know the equation is
+ of form:
+ frames = k * 2 ^ (value / 4)
+
+ (You may ponder about envelope generator hardware at this point,
+ or maybe not... :)
+
+ By substituting some stuff and running some checks, we get:
+
+ k = 0.00257 (close enuf)
+
+ therefore,
+ frames = 0.00257 * 2 ^ (value / 4)
+ If you just happen to be writing an emulator, then you can probably
+ use an equation like:
+
+ %volume_increase_per_tick = 1 / frames
+
+
+ ------------------------------------
+ Pete:
+ ms=((1<<(value>>2))*514)/10000
+ ------------------------------------
+
+2. Decay rate value (only has log mode)
+
+ Decay value range: 0 -> 15
+
+ Value | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
+ ------------------------------------------------
+ frames | | | | | 6 | 12 | 24 | 47 |
+
+ Note: frames here is no. of PAL frames to decay to 50% volume.
+
+ formula: frames = k * 2 ^ (value)
+
+ Substituting, we get: k = 0.00146
+
+ Further info on logarithmic nature:
+ frames to decay to sustain level 3 = 3 * frames to decay to
+ sustain level 9
+
+ Also no. of frames to 25% volume = roughly 1.85 * no. of frames to
+ 50% volume.
+
+ Frag it - just use linear approx.
+
+ ------------------------------------
+ Pete:
+ ms=((1<<value)*292)/10000
+ ------------------------------------
+
+
+3. Sustain rate value (linear mode)
+
+ Sustain rate range: 0 -> 127
+
+ Value | 48 | 52 | 56 | 60 | 64 | 68 | 72 |
+ -------------------------------------------
+ frames | 9 | 19 | 37 | 74 | 147| 293| 587|
+
+ Here, frames = no. of PAL frames for volume amplitude to go from 100%
+ to 0% (or vice-versa).
+
+ Same formula as for attack value, just a different value for k:
+
+ k = 0.00225
+
+ ie: frames = 0.00225 * 2 ^ (value / 4)
+
+ For emulation purposes:
+
+ %volume_increase_or_decrease_per_tick = 1 / frames
+
+ ------------------------------------
+ Pete:
+ ms=((1<<(value>>2))*450)/10000
+ ------------------------------------
+
+
+4. Release rate (linear mode)
+
+ Release rate range: 0 -> 31
+
+ Value | 13 | 14 | 15 | 16 | 17 |
+ ---------------------------------------------------------------
+ frames | 18 | 36 | 73 | 146| 292|
+
+ Here, frames = no. of PAL frames to decay from 100% vol to 0% vol
+ after "note-off" is triggered.
+
+ Formula: frames = k * 2 ^ (value)
+
+ And so: k = 0.00223
+
+ ------------------------------------
+ Pete:
+ ms=((1<<value)*446)/10000
+ ------------------------------------
+
+
+Other notes:
+
+Log stuff not figured out. You may get some clues from the "Decay rate"
+stuff above. For emu purposes it may not be important - use linear
+approx.
+
+To get timings in millisecs, multiply frames by 20.
+
+
+
+- James Higgs 17/6/2000
+james7780 at yahoo.com
+
+//---------------------------------------------------------------
+
+OLD adsr mixing according to james' rules... has to be called
+every one millisecond
+
+
+ long v,v2,lT,l1,l2,l3;
+
+ if(s_chan[ch].bStop) // psx wants to stop? -> release phase
+ {
+ if(s_chan[ch].ADSR.ReleaseVal!=0) // -> release not 0: do release (if 0: stop right now)
+ {
+ if(!s_chan[ch].ADSR.ReleaseVol) // --> release just started? set up the release stuff
+ {
+ s_chan[ch].ADSR.ReleaseStartTime=s_chan[ch].ADSR.lTime;
+ s_chan[ch].ADSR.ReleaseVol=s_chan[ch].ADSR.lVolume;
+ s_chan[ch].ADSR.ReleaseTime = // --> calc how long does it take to reach the wanted sus level
+ (s_chan[ch].ADSR.ReleaseTime*
+ s_chan[ch].ADSR.ReleaseVol)/1024;
+ }
+ // -> NO release exp mode used (yet)
+ v=s_chan[ch].ADSR.ReleaseVol; // -> get last volume
+ lT=s_chan[ch].ADSR.lTime- // -> how much time is past?
+ s_chan[ch].ADSR.ReleaseStartTime;
+ l1=s_chan[ch].ADSR.ReleaseTime;
+
+ if(lT<l1) // -> we still have to release
+ {
+ v=v-((v*lT)/l1); // --> calc new volume
+ }
+ else // -> release is over: now really stop that sample
+ {v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;}
+ }
+ else // -> release IS 0: release at once
+ {
+ v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;
+ }
+ }
+ else
+ {//--------------------------------------------------// not in release phase:
+ v=1024;
+ lT=s_chan[ch].ADSR.lTime;
+ l1=s_chan[ch].ADSR.AttackTime;
+
+ if(lT<l1) // attack
+ { // no exp mode used (yet)
+// if(s_chan[ch].ADSR.AttackModeExp)
+// {
+// v=(v*lT)/l1;
+// }
+// else
+ {
+ v=(v*lT)/l1;
+ }
+ if(v==0) v=1;
+ }
+ else // decay
+ { // should be exp, but who cares? ;)
+ l2=s_chan[ch].ADSR.DecayTime;
+ v2=s_chan[ch].ADSR.SustainLevel;
+
+ lT-=l1;
+ if(lT<l2)
+ {
+ v-=(((v-v2)*lT)/l2);
+ }
+ else // sustain
+ { // no exp mode used (yet)
+ l3=s_chan[ch].ADSR.SustainTime;
+ lT-=l2;
+ if(s_chan[ch].ADSR.SustainModeDec>0)
+ {
+ if(l3!=0) v2+=((v-v2)*lT)/l3;
+ else v2=v;
+ }
+ else
+ {
+ if(l3!=0) v2-=(v2*lT)/l3;
+ else v2=v;
+ }
+
+ if(v2>v) v2=v;
+ if(v2<=0) {v2=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;}
+
+ v=v2;
+ }
+ }
+ }
+
+ //----------------------------------------------------//
+ // ok, done for this channel, so increase time
+
+ s_chan[ch].ADSR.lTime+=1; // 1 = 1.020408f ms;
+
+ if(v>1024) v=1024; // adjust volume
+ if(v<0) v=0;
+ s_chan[ch].ADSR.lVolume=v; // store act volume
+
+ return v; // return the volume factor
+*/
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+
+/*
+-----------------------------------------------------------------------------
+Neill Corlett
+Playstation SPU envelope timing notes
+-----------------------------------------------------------------------------
+
+This is preliminary. This may be wrong. But the model described herein fits
+all of my experimental data, and it's just simple enough to sound right.
+
+ADSR envelope level ranges from 0x00000000 to 0x7FFFFFFF internally.
+The value returned by channel reg 0xC is (envelope_level>>16).
+
+Each sample, an increment or decrement value will be added to or
+subtracted from this envelope level.
+
+Create the rate log table. The values double every 4 entries.
+ entry #0 = 4
+
+ 4, 5, 6, 7,
+ 8,10,12,14,
+ 16,20,24,28, ...
+
+ entry #40 = 4096...
+ entry #44 = 8192...
+ entry #48 = 16384...
+ entry #52 = 32768...
+ entry #56 = 65536...
+
+increments and decrements are in terms of ratelogtable[n]
+n may exceed the table bounds (plan on n being between -32 and 127).
+table values are all clipped between 0x00000000 and 0x3FFFFFFF
+
+when you "voice on", the envelope is always fully reset.
+(yes, it may click. the real thing does this too.)
+
+envelope level begins at zero.
+
+each state happens for at least 1 cycle
+(transitions are not instantaneous)
+this may result in some oddness: if the decay rate is uberfast, it will cut
+the envelope from full down to half in one sample, potentially skipping over
+the sustain level
+
+ATTACK
+------
+- if the envelope level has overflowed past the max, clip to 0x7FFFFFFF and
+ proceed to DECAY.
+
+Linear attack mode:
+- line extends upward to 0x7FFFFFFF
+- increment per sample is ratelogtable[(Ar^0x7F)-0x10]
+
+Logarithmic attack mode:
+if envelope_level < 0x60000000:
+ - line extends upward to 0x60000000
+ - increment per sample is ratelogtable[(Ar^0x7F)-0x10]
+else:
+ - line extends upward to 0x7FFFFFFF
+ - increment per sample is ratelogtable[(Ar^0x7F)-0x18]
+
+DECAY
+-----
+- if ((envelope_level>>27)&0xF) <= Sl, proceed to SUSTAIN.
+ Do not clip to the sustain level.
+- current line ends at (envelope_level & 0x07FFFFFF)
+- decrement per sample depends on (envelope_level>>28)&0x7
+ 0: ratelogtable[(4*(Dr^0x1F))-0x18+0]
+ 1: ratelogtable[(4*(Dr^0x1F))-0x18+4]
+ 2: ratelogtable[(4*(Dr^0x1F))-0x18+6]
+ 3: ratelogtable[(4*(Dr^0x1F))-0x18+8]
+ 4: ratelogtable[(4*(Dr^0x1F))-0x18+9]
+ 5: ratelogtable[(4*(Dr^0x1F))-0x18+10]
+ 6: ratelogtable[(4*(Dr^0x1F))-0x18+11]
+ 7: ratelogtable[(4*(Dr^0x1F))-0x18+12]
+ (note that this is the same as the release rate formula, except that
+ decay rates 10-1F aren't possible... those would be slower in theory)
+
+SUSTAIN
+-------
+- no terminating condition except for voice off
+- Sd=0 (increase) behavior is identical to ATTACK for both log and linear.
+- Sd=1 (decrease) behavior:
+Linear sustain decrease:
+- line extends to 0x00000000
+- decrement per sample is ratelogtable[(Sr^0x7F)-0x0F]
+Logarithmic sustain decrease:
+- current line ends at (envelope_level & 0x07FFFFFF)
+- decrement per sample depends on (envelope_level>>28)&0x7
+ 0: ratelogtable[(Sr^0x7F)-0x1B+0]
+ 1: ratelogtable[(Sr^0x7F)-0x1B+4]
+ 2: ratelogtable[(Sr^0x7F)-0x1B+6]
+ 3: ratelogtable[(Sr^0x7F)-0x1B+8]
+ 4: ratelogtable[(Sr^0x7F)-0x1B+9]
+ 5: ratelogtable[(Sr^0x7F)-0x1B+10]
+ 6: ratelogtable[(Sr^0x7F)-0x1B+11]
+ 7: ratelogtable[(Sr^0x7F)-0x1B+12]
+
+RELEASE
+-------
+- if the envelope level has overflowed to negative, clip to 0 and QUIT.
+
+Linear release mode:
+- line extends to 0x00000000
+- decrement per sample is ratelogtable[(4*(Rr^0x1F))-0x0C]
+
+Logarithmic release mode:
+- line extends to (envelope_level & 0x0FFFFFFF)
+- decrement per sample depends on (envelope_level>>28)&0x7
+ 0: ratelogtable[(4*(Rr^0x1F))-0x18+0]
+ 1: ratelogtable[(4*(Rr^0x1F))-0x18+4]
+ 2: ratelogtable[(4*(Rr^0x1F))-0x18+6]
+ 3: ratelogtable[(4*(Rr^0x1F))-0x18+8]
+ 4: ratelogtable[(4*(Rr^0x1F))-0x18+9]
+ 5: ratelogtable[(4*(Rr^0x1F))-0x18+10]
+ 6: ratelogtable[(4*(Rr^0x1F))-0x18+11]
+ 7: ratelogtable[(4*(Rr^0x1F))-0x18+12]
+
+-----------------------------------------------------------------------------
+*/
+
diff --git a/src/psf/peops2/dma.c b/src/psf/peops2/dma.c
deleted file mode 100644
index 62278cd30fb5..000000000000
--- a/src/psf/peops2/dma.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/***************************************************************************
- dma.c - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove at addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-//*************************************************************************//
-// History of changes:
-//
-// 2004/04/04 - Pete
-// - changed plugin to emulate PS2 spu
-//
-// 2002/05/15 - Pete
-// - generic cleanup for the Peops release
-//
-//*************************************************************************//
-
-#include "../peops2/stdafx.h"
-
-#define _IN_DMA
-
-#include "../peops2/externals.h"
-#include "../peops2/registers.h"
-//#include "debug.h"
-
-extern uint32_t psx_ram[(2*1024*1024)/4];
-
-////////////////////////////////////////////////////////////////////////
-// READ DMA (many values)
-////////////////////////////////////////////////////////////////////////
-
-EXPORT_GCC void CALLBACK SPU2readDMA4Mem(u32 usPSXMem,int iSize)
-{
- int i;
- u16 *ram16 = (u16 *)&psx_ram[0];
-
- for(i=0;i<iSize;i++)
- {
- ram16[usPSXMem>>1]=spuMem[spuAddr2[0]]; // spu addr 0 got by writeregister
- usPSXMem+=2;
- spuAddr2[0]++; // inc spu addr
- if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; // wrap
- }
-
- spuAddr2[0]+=0x20; //?????
-
-
- iSpuAsyncWait=0;
-
- // got from J.F. and Kanodin... is it needed?
- regArea[(PS2_C0_ADMAS)>>1]=0; // Auto DMA complete
- spuStat2[0]=0x80; // DMA complete
-}
-
-EXPORT_GCC void CALLBACK SPU2readDMA7Mem(u32 usPSXMem,int iSize)
-{
- int i;
- u16 *ram16 = (u16 *)&psx_ram[0];
-
- for(i=0;i<iSize;i++)
- {
- ram16[usPSXMem>>1]=spuMem[spuAddr2[1]]; // spu addr 1 got by writeregister
- usPSXMem+=2;
- spuAddr2[1]++; // inc spu addr
- if(spuAddr2[1]>0xfffff) spuAddr2[1]=0; // wrap
- }
-
- spuAddr2[1]+=0x20; //?????
-
- iSpuAsyncWait=0;
-
- // got from J.F. and Kanodin... is it needed?
- regArea[(PS2_C1_ADMAS)>>1]=0; // Auto DMA complete
- spuStat2[1]=0x80; // DMA complete
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-// to investigate: do sound data updates by writedma affect spu
-// irqs? Will an irq be triggered, if new data is written to
-// the memory irq address?
-
-////////////////////////////////////////////////////////////////////////
-// WRITE DMA (many values)
-////////////////////////////////////////////////////////////////////////
-
-EXPORT_GCC void CALLBACK SPU2writeDMA4Mem(u32 usPSXMem,int iSize)
-{
- int i;
- u16 *ram16 = (u16 *)&psx_ram[0];
-
- for(i=0;i<iSize;i++)
- {
- spuMem[spuAddr2[0]] = ram16[usPSXMem>>1]; // spu addr 0 got by writeregister
- usPSXMem+=2;
- spuAddr2[0]++; // inc spu addr
- if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; // wrap
- }
-
- iSpuAsyncWait=0;
-
- // got from J.F. and Kanodin... is it needed?
- spuStat2[0]=0x80; // DMA complete
-}
-
-EXPORT_GCC void CALLBACK SPU2writeDMA7Mem(u32 usPSXMem,int iSize)
-{
- int i;
- u16 *ram16 = (u16 *)&psx_ram[0];
-
- for(i=0;i<iSize;i++)
- {
- spuMem[spuAddr2[1]] = ram16[usPSXMem>>1]; // spu addr 1 got by writeregister
- spuAddr2[1]++; // inc spu addr
- if(spuAddr2[1]>0xfffff) spuAddr2[1]=0; // wrap
- }
-
- iSpuAsyncWait=0;
-
- // got from J.F. and Kanodin... is it needed?
- spuStat2[1]=0x80; // DMA complete
-}
-
-////////////////////////////////////////////////////////////////////////
-// INTERRUPTS
-////////////////////////////////////////////////////////////////////////
-
-void InterruptDMA4(void)
-{
-// taken from linuzappz NULL spu2
-// spu2Rs16(CORE0_ATTR)&= ~0x30;
-// spu2Rs16(REG__1B0) = 0;
-// spu2Rs16(SPU2_STATX_WRDY_M)|= 0x80;
-
- spuCtrl2[0]&=~0x30;
- regArea[(PS2_C0_ADMAS)>>1]=0;
- spuStat2[0]|=0x80;
-}
-
-EXPORT_GCC void CALLBACK SPU2interruptDMA4(void)
-{
- InterruptDMA4();
-}
-
-void InterruptDMA7(void)
-{
-// taken from linuzappz NULL spu2
-// spu2Rs16(CORE1_ATTR)&= ~0x30;
-// spu2Rs16(REG__5B0) = 0;
-// spu2Rs16(SPU2_STATX_DREQ)|= 0x80;
-
- spuCtrl2[1]&=~0x30;
- regArea[(PS2_C1_ADMAS)>>1]=0;
- spuStat2[1]|=0x80;
-}
-
-EXPORT_GCC void CALLBACK SPU2interruptDMA7(void)
-{
- InterruptDMA7();
-}
-
diff --git a/src/psf/peops2/dma.cc b/src/psf/peops2/dma.cc
new file mode 100644
index 000000000000..ef24be7b377b
--- /dev/null
+++ b/src/psf/peops2/dma.cc
@@ -0,0 +1,175 @@
+/***************************************************************************
+ dma.c - description
+ -------------------
+ begin : Wed May 15 2002
+ copyright : (C) 2002 by Pete Bernert
+ email : BlackDove at addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+//*************************************************************************//
+// History of changes:
+//
+// 2004/04/04 - Pete
+// - changed plugin to emulate PS2 spu
+//
+// 2002/05/15 - Pete
+// - generic cleanup for the Peops release
+//
+//*************************************************************************//
+
+#include "../peops2/stdafx.h"
+
+#define _IN_DMA
+
+#include "../peops2/externals.h"
+#include "../peops2/registers.h"
+//#include "debug.h"
+
+extern uint32_t psx_ram[(2*1024*1024)/4];
+
+////////////////////////////////////////////////////////////////////////
+// READ DMA (many values)
+////////////////////////////////////////////////////////////////////////
+
+EXPORT_GCC void CALLBACK SPU2readDMA4Mem(u32 usPSXMem,int iSize)
+{
+ int i;
+ u16 *ram16 = (u16 *)&psx_ram[0];
+
+ for(i=0;i<iSize;i++)
+ {
+ ram16[usPSXMem>>1]=spuMem[spuAddr2[0]]; // spu addr 0 got by writeregister
+ usPSXMem+=2;
+ spuAddr2[0]++; // inc spu addr
+ if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; // wrap
+ }
+
+ spuAddr2[0]+=0x20; //?????
+
+
+ iSpuAsyncWait=0;
+
+ // got from J.F. and Kanodin... is it needed?
+ regArea[(PS2_C0_ADMAS)>>1]=0; // Auto DMA complete
+ spuStat2[0]=0x80; // DMA complete
+}
+
+EXPORT_GCC void CALLBACK SPU2readDMA7Mem(u32 usPSXMem,int iSize)
+{
+ int i;
+ u16 *ram16 = (u16 *)&psx_ram[0];
+
+ for(i=0;i<iSize;i++)
+ {
+ ram16[usPSXMem>>1]=spuMem[spuAddr2[1]]; // spu addr 1 got by writeregister
+ usPSXMem+=2;
+ spuAddr2[1]++; // inc spu addr
+ if(spuAddr2[1]>0xfffff) spuAddr2[1]=0; // wrap
+ }
+
+ spuAddr2[1]+=0x20; //?????
+
+ iSpuAsyncWait=0;
+
+ // got from J.F. and Kanodin... is it needed?
+ regArea[(PS2_C1_ADMAS)>>1]=0; // Auto DMA complete
+ spuStat2[1]=0x80; // DMA complete
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+// to investigate: do sound data updates by writedma affect spu
+// irqs? Will an irq be triggered, if new data is written to
+// the memory irq address?
+
+////////////////////////////////////////////////////////////////////////
+// WRITE DMA (many values)
+////////////////////////////////////////////////////////////////////////
+
+EXPORT_GCC void CALLBACK SPU2writeDMA4Mem(u32 usPSXMem,int iSize)
+{
+ int i;
+ u16 *ram16 = (u16 *)&psx_ram[0];
+
+ for(i=0;i<iSize;i++)
+ {
+ spuMem[spuAddr2[0]] = ram16[usPSXMem>>1]; // spu addr 0 got by writeregister
+ usPSXMem+=2;
+ spuAddr2[0]++; // inc spu addr
+ if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; // wrap
+ }
+
+ iSpuAsyncWait=0;
+
+ // got from J.F. and Kanodin... is it needed?
+ spuStat2[0]=0x80; // DMA complete
+}
+
+EXPORT_GCC void CALLBACK SPU2writeDMA7Mem(u32 usPSXMem,int iSize)
+{
+ int i;
+ u16 *ram16 = (u16 *)&psx_ram[0];
+
+ for(i=0;i<iSize;i++)
+ {
+ spuMem[spuAddr2[1]] = ram16[usPSXMem>>1]; // spu addr 1 got by writeregister
+ spuAddr2[1]++; // inc spu addr
+ if(spuAddr2[1]>0xfffff) spuAddr2[1]=0; // wrap
+ }
+
+ iSpuAsyncWait=0;
+
+ // got from J.F. and Kanodin... is it needed?
+ spuStat2[1]=0x80; // DMA complete
+}
+
+////////////////////////////////////////////////////////////////////////
+// INTERRUPTS
+////////////////////////////////////////////////////////////////////////
+
+void InterruptDMA4(void)
+{
+// taken from linuzappz nullptr spu2
+// spu2Rs16(CORE0_ATTR)&= ~0x30;
+// spu2Rs16(REG__1B0) = 0;
+// spu2Rs16(SPU2_STATX_WRDY_M)|= 0x80;
+
+ spuCtrl2[0]&=~0x30;
+ regArea[(PS2_C0_ADMAS)>>1]=0;
+ spuStat2[0]|=0x80;
+}
+
+EXPORT_GCC void CALLBACK SPU2interruptDMA4(void)
+{
+ InterruptDMA4();
+}
+
+void InterruptDMA7(void)
+{
+// taken from linuzappz nullptr spu2
+// spu2Rs16(CORE1_ATTR)&= ~0x30;
+// spu2Rs16(REG__5B0) = 0;
+// spu2Rs16(SPU2_STATX_DREQ)|= 0x80;
+
+ spuCtrl2[1]&=~0x30;
+ regArea[(PS2_C1_ADMAS)>>1]=0;
+ spuStat2[1]|=0x80;
+}
+
+EXPORT_GCC void CALLBACK SPU2interruptDMA7(void)
+{
+ InterruptDMA7();
+}
+
diff --git a/src/psf/peops2/registers.c b/src/psf/peops2/registers.c
deleted file mode 100644
index bad9e1d36c57..000000000000
--- a/src/psf/peops2/registers.c
+++ /dev/null
@@ -1,1343 +0,0 @@
-/***************************************************************************
- registers.c - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove at addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-//*************************************************************************//
-// History of changes:
-//
-// 2004/04/04 - Pete
-// - changed plugin to emulate PS2 spu
-//
-// 2003/02/09 - kode54
-// - removed &0x3fff from reverb volume registers, fixes a few games,
-// hopefully won't be breaking anything
-//
-// 2003/01/19 - Pete
-// - added Neill's reverb
-//
-// 2003/01/06 - Pete
-// - added Neill's ADSR timings
-//
-// 2002/05/15 - Pete
-// - generic cleanup for the Peops release
-//
-//*************************************************************************//
-
-#include "stdafx.h"
-
-#define _IN_REGISTERS
-
-#include "../peops2/externals.h"
-#include "../peops2/registers.h"
-#include "../peops2/regs.h"
-#include "../peops2/reverb.h"
-
-/*
-// adsr time values (in ms) by James Higgs ... see the end of
-// the adsr.c source for details
-
-#define ATTACK_MS 514L
-#define DECAYHALF_MS 292L
-#define DECAY_MS 584L
-#define SUSTAIN_MS 450L
-#define RELEASE_MS 446L
-*/
-
-// we have a timebase of 1.020408f ms, not 1 ms... so adjust adsr defines
-#define ATTACK_MS 494L
-#define DECAYHALF_MS 286L
-#define DECAY_MS 572L
-#define SUSTAIN_MS 441L
-#define RELEASE_MS 437L
-
-// Prototypes
-void SetVolumeL(unsigned char ch,short vol);
-void SetVolumeR(unsigned char ch,short vol);
-void ReverbOn(int start,int end,unsigned short val,int iRight);
-void SetReverbAddr(int core);
-void VolumeOn(int start,int end,unsigned short val,int iRight);
-
-////////////////////////////////////////////////////////////////////////
-// WRITE REGISTERS: called by main emu
-////////////////////////////////////////////////////////////////////////
-
-EXPORT_GCC void CALLBACK SPU2write(unsigned long reg, unsigned short val)
-{
- long r=reg&0xffff;
-
- regArea[r>>1] = val;
-
-// printf("SPU2: %04x to %08x\n", val, reg);
-
- if((r>=0x0000 && r<0x0180)||(r>=0x0400 && r<0x0580)) // some channel info?
- {
- int ch=(r>>4)&0x1f;
- if(r>=0x400) ch+=24;
-
- switch(r&0x0f)
- {
- //------------------------------------------------// r volume
- case 0:
- SetVolumeL((unsigned char)ch,val);
- break;
- //------------------------------------------------// l volume
- case 2:
- SetVolumeR((unsigned char)ch,val);
- break;
- //------------------------------------------------// pitch
- case 4:
- SetPitch(ch,val);
- break;
- //------------------------------------------------// level with pre-calcs
- case 6:
- {
- const unsigned long lval=val;unsigned long lx;
- //---------------------------------------------//
- s_chan[ch].ADSRX.AttackModeExp=(lval&0x8000)?1:0;
- s_chan[ch].ADSRX.AttackRate=(lval>>8) & 0x007f;
- s_chan[ch].ADSRX.DecayRate=(lval>>4) & 0x000f;
- s_chan[ch].ADSRX.SustainLevel=lval & 0x000f;
- //---------------------------------------------//
- if(!iDebugMode) break;
- //---------------------------------------------// stuff below is only for debug mode
-
- s_chan[ch].ADSR.AttackModeExp=(lval&0x8000)?1:0; //0x007f
-
- lx=(((lval>>8) & 0x007f)>>2); // attack time to run from 0 to 100% volume
- lx = (lx < 31) ? lx : 31; // no overflow on shift!
- if(lx)
- {
- lx = (1<<lx);
- if(lx<2147483) lx=(lx*ATTACK_MS)/10000L; // another overflow check
- else lx=(lx/10000L)*ATTACK_MS;
- if(!lx) lx=1;
- }
- s_chan[ch].ADSR.AttackTime=lx;
-
- s_chan[ch].ADSR.SustainLevel= // our adsr vol runs from 0 to 1024, so scale the sustain level
- (1024*((lval) & 0x000f))/15;
-
- lx=(lval>>4) & 0x000f; // decay:
- if(lx) // our const decay value is time it takes from 100% to 0% of volume
- {
- lx = ((1<<(lx))*DECAY_MS)/10000L;
- if(!lx) lx=1;
- }
- s_chan[ch].ADSR.DecayTime = // so calc how long does it take to run from 100% to the wanted sus level
- (lx*(1024-s_chan[ch].ADSR.SustainLevel))/1024;
- }
- break;
- //------------------------------------------------// adsr times with pre-calcs
- case 8:
- {
- const unsigned long lval=val;unsigned long lx;
-
- //----------------------------------------------//
- s_chan[ch].ADSRX.SustainModeExp = (lval&0x8000)?1:0;
- s_chan[ch].ADSRX.SustainIncrease= (lval&0x4000)?0:1;
- s_chan[ch].ADSRX.SustainRate = (lval>>6) & 0x007f;
- s_chan[ch].ADSRX.ReleaseModeExp = (lval&0x0020)?1:0;
- s_chan[ch].ADSRX.ReleaseRate = lval & 0x001f;
- //----------------------------------------------//
- if(!iDebugMode) break;
- //----------------------------------------------// stuff below is only for debug mode
-
- s_chan[ch].ADSR.SustainModeExp = (lval&0x8000)?1:0;
- s_chan[ch].ADSR.ReleaseModeExp = (lval&0x0020)?1:0;
-
- lx=((((lval>>6) & 0x007f)>>2)); // sustain time... often very high
- lx = (lx < 31) ? lx : 31; // values are used to hold the volume
- if(lx) // until a sound stop occurs
- { // the highest value we reach (due to
- lx = (1<<lx); // overflow checking) is:
- if(lx<2147483) lx=(lx*SUSTAIN_MS)/10000L; // 94704 seconds = 1578 minutes = 26 hours...
- else lx=(lx/10000L)*SUSTAIN_MS; // should be enuff... if the stop doesn't
- if(!lx) lx=1; // come in this time span, I don't care :)
- }
- s_chan[ch].ADSR.SustainTime = lx;
-
- lx=(lval & 0x001f);
- s_chan[ch].ADSR.ReleaseVal =lx;
- if(lx) // release time from 100% to 0%
- { // note: the release time will be
- lx = (1<<lx); // adjusted when a stop is coming,
- if(lx<2147483) lx=(lx*RELEASE_MS)/10000L; // so at this time the adsr vol will
- else lx=(lx/10000L)*RELEASE_MS; // run from (current volume) to 0%
- if(!lx) lx=1;
- }
- s_chan[ch].ADSR.ReleaseTime=lx;
-
- if(lval & 0x4000) // add/dec flag
- s_chan[ch].ADSR.SustainModeDec=-1;
- else s_chan[ch].ADSR.SustainModeDec=1;
- }
- break;
- //------------------------------------------------//
- }
-
- iSpuAsyncWait=0;
-
- return;
- }
-
- if((r>=0x01c0 && r<0x02E0)||(r>=0x05c0 && r<0x06E0)) // some channel info?
- {
- int ch=0;
- if(r>=0x400) {ch=24;r-=0x400;}
-
- ch+=(r-0x1c0)/12;
- r-=(ch%24)*12;
- switch(r)
- {
- //------------------------------------------------//
- case 0x1C0:
- s_chan[ch].iStartAdr=(((unsigned long)val&0xf)<<16)|(s_chan[ch].iStartAdr&0xFFFF);
- s_chan[ch].pStart=spuMemC+(s_chan[ch].iStartAdr<<1);
- break;
- case 0x1C2:
- s_chan[ch].iStartAdr=(s_chan[ch].iStartAdr & 0xF0000) | (val & 0xFFFF);
- s_chan[ch].pStart=spuMemC+(s_chan[ch].iStartAdr<<1);
- break;
- //------------------------------------------------//
- case 0x1C4:
- s_chan[ch].iLoopAdr=(((unsigned long)val&0xf)<<16)|(s_chan[ch].iLoopAdr&0xFFFF);
- s_chan[ch].pLoop=spuMemC+(s_chan[ch].iLoopAdr<<1);
- s_chan[ch].bIgnoreLoop=1;
- break;
- case 0x1C6:
- s_chan[ch].iLoopAdr=(s_chan[ch].iLoopAdr & 0xF0000) | (val & 0xFFFF);
- s_chan[ch].pLoop=spuMemC+(s_chan[ch].iLoopAdr<<1);
- s_chan[ch].bIgnoreLoop=1;
- break;
- //------------------------------------------------//
- case 0x1C8:
- // unused... check if it gets written as well
- s_chan[ch].iNextAdr=(((unsigned long)val&0xf)<<16)|(s_chan[ch].iNextAdr&0xFFFF);
- break;
- case 0x1CA:
- // unused... check if it gets written as well
- s_chan[ch].iNextAdr=(s_chan[ch].iNextAdr & 0xF0000) | (val & 0xFFFF);
- break;
- //------------------------------------------------//
- }
-
- iSpuAsyncWait=0;
-
- return;
- }
-
- switch(r)
- {
- //-------------------------------------------------//
- case PS2_C0_SPUaddr_Hi:
- spuAddr2[0] = (((unsigned long)val&0xf)<<16)|(spuAddr2[0]&0xFFFF);
- break;
- //-------------------------------------------------//
- case PS2_C0_SPUaddr_Lo:
- spuAddr2[0] = (spuAddr2[0] & 0xF0000) | (val & 0xFFFF);
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUaddr_Hi:
- spuAddr2[1] = (((unsigned long)val&0xf)<<16)|(spuAddr2[1]&0xFFFF);
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUaddr_Lo:
- spuAddr2[1] = (spuAddr2[1] & 0xF0000) | (val & 0xFFFF);
- break;
- //-------------------------------------------------//
- case PS2_C0_SPUdata:
- spuMem[spuAddr2[0]] = val;
- spuAddr2[0]++;
- if(spuAddr2[0]>0xfffff) spuAddr2[0]=0;
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUdata:
- spuMem[spuAddr2[1]] = val;
- spuAddr2[1]++;
- if(spuAddr2[1]>0xfffff) spuAddr2[1]=0;
- break;
- //-------------------------------------------------//
- case PS2_C0_ATTR:
- spuCtrl2[0]=val;
- break;
- //-------------------------------------------------//
- case PS2_C1_ATTR:
- spuCtrl2[1]=val;
- break;
- //-------------------------------------------------//
- case PS2_C0_SPUstat:
- spuStat2[0]=val;
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUstat:
- spuStat2[1]=val;
- break;
- //-------------------------------------------------//
- case PS2_C0_ReverbAddr_Hi:
- spuRvbAddr2[0] = (((unsigned long)val&0xf)<<16)|(spuRvbAddr2[0]&0xFFFF);
- SetReverbAddr(0);
- break;
- //-------------------------------------------------//
- case PS2_C0_ReverbAddr_Lo:
- spuRvbAddr2[0] = (spuRvbAddr2[0] & 0xF0000) | (val & 0xFFFF);
- SetReverbAddr(0);
- break;
- //-------------------------------------------------//
- case PS2_C0_ReverbAEnd_Hi:
- spuRvbAEnd2[0] = (((unsigned long)val&0xf)<<16)|(/*spuRvbAEnd2[0]&*/0xFFFF);
- rvb[0].EndAddr=spuRvbAEnd2[0];
- break;
- //-------------------------------------------------//
- case PS2_C1_ReverbAEnd_Hi:
- spuRvbAEnd2[1] = (((unsigned long)val&0xf)<<16)|(/*spuRvbAEnd2[1]&*/0xFFFF);
- rvb[1].EndAddr=spuRvbAEnd2[1];
- break;
- //-------------------------------------------------//
- case PS2_C1_ReverbAddr_Hi:
- spuRvbAddr2[1] = (((unsigned long)val&0xf)<<16)|(spuRvbAddr2[1]&0xFFFF);
- SetReverbAddr(1);
- break;
- //-------------------------------------------------//
- case PS2_C1_ReverbAddr_Lo:
- spuRvbAddr2[1] = (spuRvbAddr2[1] & 0xF0000) | (val & 0xFFFF);
- SetReverbAddr(1);
- break;
- //-------------------------------------------------//
- case PS2_C0_SPUirqAddr_Hi:
- spuIrq2[0] = (((unsigned long)val&0xf)<<16)|(spuIrq2[0]&0xFFFF);
- pSpuIrq[0]=spuMemC+(spuIrq2[0]<<1);
- break;
- //-------------------------------------------------//
- case PS2_C0_SPUirqAddr_Lo:
- spuIrq2[0] = (spuIrq2[0] & 0xF0000) | (val & 0xFFFF);
- pSpuIrq[0]=spuMemC+(spuIrq2[0]<<1);
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUirqAddr_Hi:
- spuIrq2[1] = (((unsigned long)val&0xf)<<16)|(spuIrq2[1]&0xFFFF);
- pSpuIrq[1]=spuMemC+(spuIrq2[1]<<1);
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUirqAddr_Lo:
- spuIrq2[1] = (spuIrq2[1] & 0xF0000) | (val & 0xFFFF);
- pSpuIrq[1]=spuMemC+(spuIrq2[1]<<1);
- break;
- //-------------------------------------------------//
- case PS2_C0_SPUrvolL:
- rvb[0].VolLeft=val;
- break;
- //-------------------------------------------------//
- case PS2_C0_SPUrvolR:
- rvb[0].VolRight=val;
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUrvolL:
- rvb[1].VolLeft=val;
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUrvolR:
- rvb[1].VolRight=val;
- break;
- //-------------------------------------------------//
- case PS2_C0_SPUon1:
- SoundOn(0,16,val);
- break;
- //-------------------------------------------------//
- case PS2_C0_SPUon2:
- SoundOn(16,24,val);
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUon1:
- SoundOn(24,40,val);
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUon2:
- SoundOn(40,48,val);
- break;
- //-------------------------------------------------//
- case PS2_C0_SPUoff1:
- SoundOff(0,16,val);
- break;
- //-------------------------------------------------//
- case PS2_C0_SPUoff2:
- SoundOff(16,24,val);
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUoff1:
- SoundOff(24,40,val);
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUoff2:
- SoundOff(40,48,val);
- break;
- //-------------------------------------------------//
- case PS2_C0_SPUend1:
- case PS2_C0_SPUend2:
- if(val) dwEndChannel2[0]=0;
- break;
- //-------------------------------------------------//
- case PS2_C1_SPUend1:
- case PS2_C1_SPUend2:
- if(val) dwEndChannel2[1]=0;
- break;
- //-------------------------------------------------//
- case PS2_C0_FMod1:
- FModOn(0,16,val);
- break;
- //-------------------------------------------------//
- case PS2_C0_FMod2:
- FModOn(16,24,val);
- break;
- //-------------------------------------------------//
- case PS2_C1_FMod1:
- FModOn(24,40,val);
- break;
- //-------------------------------------------------//
- case PS2_C1_FMod2:
- FModOn(40,48,val);
- break;
- //-------------------------------------------------//
- case PS2_C0_Noise1:
- NoiseOn(0,16,val);
- break;
- //-------------------------------------------------//
- case PS2_C0_Noise2:
- NoiseOn(16,24,val);
- break;
- //-------------------------------------------------//
- case PS2_C1_Noise1:
- NoiseOn(24,40,val);
- break;
- //-------------------------------------------------//
- case PS2_C1_Noise2:
- NoiseOn(40,48,val);
- break;
- //-------------------------------------------------//
- case PS2_C0_DryL1:
- VolumeOn(0,16,val,0);
- break;
- //-------------------------------------------------//
- case PS2_C0_DryL2:
- VolumeOn(16,24,val,0);
- break;
- //-------------------------------------------------//
- case PS2_C1_DryL1:
- VolumeOn(24,40,val,0);
- break;
- //-------------------------------------------------//
- case PS2_C1_DryL2:
- VolumeOn(40,48,val,0);
- break;
- //-------------------------------------------------//
- case PS2_C0_DryR1:
- VolumeOn(0,16,val,1);
- break;
- //-------------------------------------------------//
- case PS2_C0_DryR2:
- VolumeOn(16,24,val,1);
- break;
- //-------------------------------------------------//
- case PS2_C1_DryR1:
- VolumeOn(24,40,val,1);
- break;
- //-------------------------------------------------//
- case PS2_C1_DryR2:
- VolumeOn(40,48,val,1);
- break;
- //-------------------------------------------------//
- case PS2_C0_RVBon1_L:
- ReverbOn(0,16,val,0);
- break;
- //-------------------------------------------------//
- case PS2_C0_RVBon2_L:
- ReverbOn(16,24,val,0);
- break;
- //-------------------------------------------------//
- case PS2_C1_RVBon1_L:
- ReverbOn(24,40,val,0);
- break;
- //-------------------------------------------------//
- case PS2_C1_RVBon2_L:
- ReverbOn(40,48,val,0);
- break;
- //-------------------------------------------------//
- case PS2_C0_RVBon1_R:
- ReverbOn(0,16,val,1);
- break;
- //-------------------------------------------------//
- case PS2_C0_RVBon2_R:
- ReverbOn(16,24,val,1);
- break;
- //-------------------------------------------------//
- case PS2_C1_RVBon1_R:
- ReverbOn(24,40,val,1);
- break;
- //-------------------------------------------------//
- case PS2_C1_RVBon2_R:
- ReverbOn(40,48,val,1);
- break;
- //-------------------------------------------------//
- case PS2_C0_Reverb+0:
- rvb[0].FB_SRC_A=(((unsigned long)val&0xf)<<16)|(rvb[0].FB_SRC_A&0xFFFF);
- break;
- case PS2_C0_Reverb+2:
- rvb[0].FB_SRC_A=(rvb[0].FB_SRC_A & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+4:
- rvb[0].FB_SRC_B=(((unsigned long)val&0xf)<<16)|(rvb[0].FB_SRC_B&0xFFFF);
- break;
- case PS2_C0_Reverb+6:
- rvb[0].FB_SRC_B=(rvb[0].FB_SRC_B & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+8:
- rvb[0].IIR_DEST_A0=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_DEST_A0&0xFFFF);
- break;
- case PS2_C0_Reverb+10:
- rvb[0].IIR_DEST_A0=(rvb[0].IIR_DEST_A0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+12:
- rvb[0].IIR_DEST_A1=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_DEST_A1&0xFFFF);
- break;
- case PS2_C0_Reverb+14:
- rvb[0].IIR_DEST_A1=(rvb[0].IIR_DEST_A1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+16:
- rvb[0].ACC_SRC_A0=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_A0&0xFFFF);
- break;
- case PS2_C0_Reverb+18:
- rvb[0].ACC_SRC_A0=(rvb[0].ACC_SRC_A0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+20:
- rvb[0].ACC_SRC_A1=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_A1&0xFFFF);
- break;
- case PS2_C0_Reverb+22:
- rvb[0].ACC_SRC_A1=(rvb[0].ACC_SRC_A1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+24:
- rvb[0].ACC_SRC_B0=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_B0&0xFFFF);
- break;
- case PS2_C0_Reverb+26:
- rvb[0].ACC_SRC_B0=(rvb[0].ACC_SRC_B0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+28:
- rvb[0].ACC_SRC_B1=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_B1&0xFFFF);
- break;
- case PS2_C0_Reverb+30:
- rvb[0].ACC_SRC_B1=(rvb[0].ACC_SRC_B1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+32:
- rvb[0].IIR_SRC_A0=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_SRC_A0&0xFFFF);
- break;
- case PS2_C0_Reverb+34:
- rvb[0].IIR_SRC_A0=(rvb[0].IIR_SRC_A0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+36:
- rvb[0].IIR_SRC_A1=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_SRC_A1&0xFFFF);
- break;
- case PS2_C0_Reverb+38:
- rvb[0].IIR_SRC_A1=(rvb[0].IIR_SRC_A1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+40:
- rvb[0].IIR_DEST_B0=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_DEST_B0&0xFFFF);
- break;
- case PS2_C0_Reverb+42:
- rvb[0].IIR_DEST_B0=(rvb[0].IIR_DEST_B0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+44:
- rvb[0].IIR_DEST_B1=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_DEST_B1&0xFFFF);
- break;
- case PS2_C0_Reverb+46:
- rvb[0].IIR_DEST_B1=(rvb[0].IIR_DEST_B1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+48:
- rvb[0].ACC_SRC_C0=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_C0&0xFFFF);
- break;
- case PS2_C0_Reverb+50:
- rvb[0].ACC_SRC_C0=(rvb[0].ACC_SRC_C0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+52:
- rvb[0].ACC_SRC_C1=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_C1&0xFFFF);
- break;
- case PS2_C0_Reverb+54:
- rvb[0].ACC_SRC_C1=(rvb[0].ACC_SRC_C1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+56:
- rvb[0].ACC_SRC_D0=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_D0&0xFFFF);
- break;
- case PS2_C0_Reverb+58:
- rvb[0].ACC_SRC_D0=(rvb[0].ACC_SRC_D0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+60:
- rvb[0].ACC_SRC_D1=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_D1&0xFFFF);
- break;
- case PS2_C0_Reverb+62:
- rvb[0].ACC_SRC_D1=(rvb[0].ACC_SRC_D1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+64:
- rvb[0].IIR_SRC_B1=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_SRC_B1&0xFFFF);
- break;
- case PS2_C0_Reverb+66:
- rvb[0].IIR_SRC_B1=(rvb[0].IIR_SRC_B1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+68:
- rvb[0].IIR_SRC_B0=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_SRC_B0&0xFFFF);
- break;
- case PS2_C0_Reverb+70:
- rvb[0].IIR_SRC_B0=(rvb[0].IIR_SRC_B0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+72:
- rvb[0].MIX_DEST_A0=(((unsigned long)val&0xf)<<16)|(rvb[0].MIX_DEST_A0&0xFFFF);
- break;
- case PS2_C0_Reverb+74:
- rvb[0].MIX_DEST_A0=(rvb[0].MIX_DEST_A0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+76:
- rvb[0].MIX_DEST_A1=(((unsigned long)val&0xf)<<16)|(rvb[0].MIX_DEST_A1&0xFFFF);
- break;
- case PS2_C0_Reverb+78:
- rvb[0].MIX_DEST_A1=(rvb[0].MIX_DEST_A1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+80:
- rvb[0].MIX_DEST_B0=(((unsigned long)val&0xf)<<16)|(rvb[0].MIX_DEST_B0&0xFFFF);
- break;
- case PS2_C0_Reverb+82:
- rvb[0].MIX_DEST_B0=(rvb[0].MIX_DEST_B0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_Reverb+84:
- rvb[0].MIX_DEST_B1=(((unsigned long)val&0xf)<<16)|(rvb[0].MIX_DEST_B1&0xFFFF);
- break;
- case PS2_C0_Reverb+86:
- rvb[0].MIX_DEST_B1=(rvb[0].MIX_DEST_B1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C0_ReverbX+0: rvb[0].IIR_ALPHA=(short)val; break;
- case PS2_C0_ReverbX+2: rvb[0].ACC_COEF_A=(short)val; break;
- case PS2_C0_ReverbX+4: rvb[0].ACC_COEF_B=(short)val; break;
- case PS2_C0_ReverbX+6: rvb[0].ACC_COEF_C=(short)val; break;
- case PS2_C0_ReverbX+8: rvb[0].ACC_COEF_D=(short)val; break;
- case PS2_C0_ReverbX+10: rvb[0].IIR_COEF=(short)val; break;
- case PS2_C0_ReverbX+12: rvb[0].FB_ALPHA=(short)val; break;
- case PS2_C0_ReverbX+14: rvb[0].FB_X=(short)val; break;
- case PS2_C0_ReverbX+16: rvb[0].IN_COEF_L=(short)val; break;
- case PS2_C0_ReverbX+18: rvb[0].IN_COEF_R=(short)val; break;
- //-------------------------------------------------//
- case PS2_C1_Reverb+0:
- rvb[1].FB_SRC_A=(((unsigned long)val&0xf)<<16)|(rvb[1].FB_SRC_A&0xFFFF);
- break;
- case PS2_C1_Reverb+2:
- rvb[1].FB_SRC_A=(rvb[1].FB_SRC_A & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+4:
- rvb[1].FB_SRC_B=(((unsigned long)val&0xf)<<16)|(rvb[1].FB_SRC_B&0xFFFF);
- break;
- case PS2_C1_Reverb+6:
- rvb[1].FB_SRC_B=(rvb[1].FB_SRC_B & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+8:
- rvb[1].IIR_DEST_A0=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_DEST_A0&0xFFFF);
- break;
- case PS2_C1_Reverb+10:
- rvb[1].IIR_DEST_A0=(rvb[1].IIR_DEST_A0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+12:
- rvb[1].IIR_DEST_A1=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_DEST_A1&0xFFFF);
- break;
- case PS2_C1_Reverb+14:
- rvb[1].IIR_DEST_A1=(rvb[1].IIR_DEST_A1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+16:
- rvb[1].ACC_SRC_A0=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_A0&0xFFFF);
- break;
- case PS2_C1_Reverb+18:
- rvb[1].ACC_SRC_A0=(rvb[1].ACC_SRC_A0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+20:
- rvb[1].ACC_SRC_A1=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_A1&0xFFFF);
- break;
- case PS2_C1_Reverb+22:
- rvb[1].ACC_SRC_A1=(rvb[1].ACC_SRC_A1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+24:
- rvb[1].ACC_SRC_B0=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_B0&0xFFFF);
- break;
- case PS2_C1_Reverb+26:
- rvb[1].ACC_SRC_B0=(rvb[1].ACC_SRC_B0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+28:
- rvb[1].ACC_SRC_B1=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_B1&0xFFFF);
- break;
- case PS2_C1_Reverb+30:
- rvb[1].ACC_SRC_B1=(rvb[1].ACC_SRC_B1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+32:
- rvb[1].IIR_SRC_A0=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_SRC_A0&0xFFFF);
- break;
- case PS2_C1_Reverb+34:
- rvb[1].IIR_SRC_A0=(rvb[1].IIR_SRC_A0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+36:
- rvb[1].IIR_SRC_A1=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_SRC_A1&0xFFFF);
- break;
- case PS2_C1_Reverb+38:
- rvb[1].IIR_SRC_A1=(rvb[1].IIR_SRC_A1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+40:
- rvb[1].IIR_DEST_B0=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_DEST_B0&0xFFFF);
- break;
- case PS2_C1_Reverb+42:
- rvb[1].IIR_DEST_B0=(rvb[1].IIR_DEST_B0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+44:
- rvb[1].IIR_DEST_B1=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_DEST_B1&0xFFFF);
- break;
- case PS2_C1_Reverb+46:
- rvb[1].IIR_DEST_B1=(rvb[1].IIR_DEST_B1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+48:
- rvb[1].ACC_SRC_C0=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_C0&0xFFFF);
- break;
- case PS2_C1_Reverb+50:
- rvb[1].ACC_SRC_C0=(rvb[1].ACC_SRC_C0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+52:
- rvb[1].ACC_SRC_C1=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_C1&0xFFFF);
- break;
- case PS2_C1_Reverb+54:
- rvb[1].ACC_SRC_C1=(rvb[1].ACC_SRC_C1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+56:
- rvb[1].ACC_SRC_D0=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_D0&0xFFFF);
- break;
- case PS2_C1_Reverb+58:
- rvb[1].ACC_SRC_D0=(rvb[1].ACC_SRC_D0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+60:
- rvb[1].ACC_SRC_D1=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_D1&0xFFFF);
- break;
- case PS2_C1_Reverb+62:
- rvb[1].ACC_SRC_D1=(rvb[1].ACC_SRC_D1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+64:
- rvb[1].IIR_SRC_B1=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_SRC_B1&0xFFFF);
- break;
- case PS2_C1_Reverb+66:
- rvb[1].IIR_SRC_B1=(rvb[1].IIR_SRC_B1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+68:
- rvb[1].IIR_SRC_B0=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_SRC_B0&0xFFFF);
- break;
- case PS2_C1_Reverb+70:
- rvb[1].IIR_SRC_B0=(rvb[1].IIR_SRC_B0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+72:
- rvb[1].MIX_DEST_A0=(((unsigned long)val&0xf)<<16)|(rvb[1].MIX_DEST_A0&0xFFFF);
- break;
- case PS2_C1_Reverb+74:
- rvb[1].MIX_DEST_A0=(rvb[1].MIX_DEST_A0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+76:
- rvb[1].MIX_DEST_A1=(((unsigned long)val&0xf)<<16)|(rvb[1].MIX_DEST_A1&0xFFFF);
- break;
- case PS2_C1_Reverb+78:
- rvb[1].MIX_DEST_A1=(rvb[1].MIX_DEST_A1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+80:
- rvb[1].MIX_DEST_B0=(((unsigned long)val&0xf)<<16)|(rvb[1].MIX_DEST_B0&0xFFFF);
- break;
- case PS2_C1_Reverb+82:
- rvb[1].MIX_DEST_B0=(rvb[1].MIX_DEST_B0 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_Reverb+84:
- rvb[1].MIX_DEST_B1=(((unsigned long)val&0xf)<<16)|(rvb[1].MIX_DEST_B1&0xFFFF);
- break;
- case PS2_C1_Reverb+86:
- rvb[1].MIX_DEST_B1=(rvb[1].MIX_DEST_B1 & 0xF0000) | ((val) & 0xFFFF);
- break;
- case PS2_C1_ReverbX+0: rvb[1].IIR_ALPHA=(short)val; break;
- case PS2_C1_ReverbX+2: rvb[1].ACC_COEF_A=(short)val; break;
- case PS2_C1_ReverbX+4: rvb[1].ACC_COEF_B=(short)val; break;
- case PS2_C1_ReverbX+6: rvb[1].ACC_COEF_C=(short)val; break;
- case PS2_C1_ReverbX+8: rvb[1].ACC_COEF_D=(short)val; break;
- case PS2_C1_ReverbX+10: rvb[1].IIR_COEF=(short)val; break;
- case PS2_C1_ReverbX+12: rvb[1].FB_ALPHA=(short)val; break;
- case PS2_C1_ReverbX+14: rvb[1].FB_X=(short)val; break;
- case PS2_C1_ReverbX+16: rvb[1].IN_COEF_L=(short)val; break;
- case PS2_C1_ReverbX+18: rvb[1].IN_COEF_R=(short)val; break;
- }
-
- iSpuAsyncWait=0;
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// READ REGISTER: called by main emu
-////////////////////////////////////////////////////////////////////////
-
-EXPORT_GCC unsigned short CALLBACK SPU2read(unsigned long reg)
-{
- long r=reg&0xffff;
-
-#ifdef _WINDOWS
-// if(iDebugMode==1) logprintf("R_REG %X\r\n",reg&0xFFFF);
-#endif
-
- iSpuAsyncWait=0;
-
- if((r>=0x0000 && r<0x0180)||(r>=0x0400 && r<0x0580)) // some channel info?
- {
- switch(r&0x0f)
- {
- //------------------------------------------------// env value
- case 10:
- {
- int ch=(r>>4)&0x1f;
- if(r>=0x400) ch+=24;
- if(s_chan[ch].bNew) return 1; // we are started, but not processed? return 1
- if(s_chan[ch].ADSRX.lVolume && // same here... we haven't decoded one sample yet, so no envelope yet. return 1 as well
- !s_chan[ch].ADSRX.EnvelopeVol)
- return 1;
- return (unsigned short)(s_chan[ch].ADSRX.EnvelopeVol>>16);
- }break;
- }
- }
-
- if((r>=0x01c0 && r<0x02E0)||(r>=0x05c0 && r<0x06E0)) // some channel info?
- {
- int ch=0;unsigned long rx=r;
- if(rx>=0x400) {ch=24;rx-=0x400;}
-
- ch+=(rx-0x1c0)/12;
- rx-=(ch%24)*12;
-
- switch(rx)
- {
- //------------------------------------------------//
- case 0x1C4:
- return (((s_chan[ch].pLoop-spuMemC)>>17)&0xF);
- break;
- case 0x1C6:
- return (((s_chan[ch].pLoop-spuMemC)>>1)&0xFFFF);
- break;
- //------------------------------------------------//
- case 0x1C8:
- return (((s_chan[ch].pCurr-spuMemC)>>17)&0xF);
- break;
- case 0x1CA:
- return (((s_chan[ch].pCurr-spuMemC)>>1)&0xFFFF);
- break;
- //------------------------------------------------//
- }
- }
-
- switch(r)
- {
- //--------------------------------------------------//
- case PS2_C0_SPUend1:
- return (unsigned short)((dwEndChannel2[0]&0xFFFF));
- case PS2_C0_SPUend2:
- return (unsigned short)((dwEndChannel2[0]>>16));
- //--------------------------------------------------//
- case PS2_C1_SPUend1:
- return (unsigned short)((dwEndChannel2[1]&0xFFFF));
- case PS2_C1_SPUend2:
- return (unsigned short)((dwEndChannel2[1]>>16));
- //--------------------------------------------------//
- case PS2_C0_ATTR:
- return spuCtrl2[0];
- break;
- //--------------------------------------------------//
- case PS2_C1_ATTR:
- return spuCtrl2[1];
- break;
- //--------------------------------------------------//
- case PS2_C0_SPUstat:
- return spuStat2[0];
- break;
- //--------------------------------------------------//
- case PS2_C1_SPUstat:
- return spuStat2[1];
- break;
- //--------------------------------------------------//
- case PS2_C0_SPUdata:
- {
- unsigned short s=spuMem[spuAddr2[0]];
- spuAddr2[0]++;
- if(spuAddr2[0]>0xfffff) spuAddr2[0]=0;
- return s;
- }
- //--------------------------------------------------//
- case PS2_C1_SPUdata:
- {
- unsigned short s=spuMem[spuAddr2[1]];
- spuAddr2[1]++;
- if(spuAddr2[1]>0xfffff) spuAddr2[1]=0;
- return s;
- }
- //--------------------------------------------------//
- case PS2_C0_SPUaddr_Hi:
- return (unsigned short)((spuAddr2[0]>>16)&0xF);
- break;
- case PS2_C0_SPUaddr_Lo:
- return (unsigned short)((spuAddr2[0]&0xFFFF));
- break;
- //--------------------------------------------------//
- case PS2_C1_SPUaddr_Hi:
- return (unsigned short)((spuAddr2[1]>>16)&0xF);
- break;
- case PS2_C1_SPUaddr_Lo:
- return (unsigned short)((spuAddr2[1]&0xFFFF));
- break;
- //--------------------------------------------------//
- }
-
- return regArea[r>>1];
-}
-
-EXPORT_GCC void CALLBACK SPU2writePS1Port(unsigned long reg, unsigned short val)
-{
- const u32 r=reg&0xfff;
-
- if(r>=0xc00 && r<0xd80) // channel info
- {
- SPU2write(r-0xc00, val);
- return;
- }
-
- switch(r)
- {
- //-------------------------------------------------//
- case H_SPUaddr:
- spuAddr2[0] = (u32) val<<2;
- break;
- //-------------------------------------------------//
- case H_SPUdata:
- spuMem[spuAddr2[0]] = BFLIP16(val);
- spuAddr2[0]++;
- if(spuAddr2[0]>0xfffff) spuAddr2[0]=0;
- break;
- //-------------------------------------------------//
- case H_SPUctrl:
-// spuCtrl=val;
- break;
- //-------------------------------------------------//
- case H_SPUstat:
- spuStat2[0]=val & 0xf800;
- break;
- //-------------------------------------------------//
- case H_SPUReverbAddr:
- spuRvbAddr2[0] = val;
- SetReverbAddr(0);
- break;
- //-------------------------------------------------//
- case H_SPUirqAddr:
- spuIrq2[0] = val<<2;
- pSpuIrq[0]=spuMemC+((u32) val<<1);
- break;
- //-------------------------------------------------//
- /* Volume settings appear to be at least 15-bit unsigned in this case.
- Definitely NOT 15-bit signed. Probably 16-bit signed, so s16 type cast.
- Check out "Chrono Cross: Shadow's End Forest"
- */
- case H_SPUrvolL:
- rvb[0].VolLeft=(s16)val;
- //printf("%d\n",val);
- break;
- //-------------------------------------------------//
- case H_SPUrvolR:
- rvb[0].VolRight=(s16)val;
- //printf("%d\n",val);
- break;
- //-------------------------------------------------//
-
-/*
- case H_ExtLeft:
- //auxprintf("EL %d\n",val);
- break;
- //-------------------------------------------------//
- case H_ExtRight:
- //auxprintf("ER %d\n",val);
- break;
- //-------------------------------------------------//
- case H_SPUmvolL:
- //auxprintf("ML %d\n",val);
- break;
- //-------------------------------------------------//
- case H_SPUmvolR:
- //auxprintf("MR %d\n",val);
- break;
- //-------------------------------------------------//
- case H_SPUMute1:
- //printf("M0 %04x\n",val);
- break;
- //-------------------------------------------------//
- case H_SPUMute2:
- // printf("M1 %04x\n",val);
- break;
-*/
- //-------------------------------------------------//
- case H_SPUon1:
- SoundOn(0,16,val);
- break;
- //-------------------------------------------------//
- case H_SPUon2:
- //printf("Boop: %08x: %04x\n",reg,val);
- SoundOn(16,24,val);
- break;
- //-------------------------------------------------//
- case H_SPUoff1:
- SoundOff(0,16,val);
- break;
- //-------------------------------------------------//
- case H_SPUoff2:
- SoundOff(16,24,val);
- // printf("Boop: %08x: %04x\n",reg,val);
- break;
- //-------------------------------------------------//
- case H_FMod1:
- FModOn(0,16,val);
- break;
- //-------------------------------------------------//
- case H_FMod2:
- FModOn(16,24,val);
- break;
- //-------------------------------------------------//
- case H_Noise1:
- NoiseOn(0,16,val);
- break;
- //-------------------------------------------------//
- case H_Noise2:
- NoiseOn(16,24,val);
- break;
- //-------------------------------------------------//
- case H_RVBon1:
- ReverbOn(0,16,val,0);
- break;
-
- //-------------------------------------------------//
- case H_RVBon2:
- ReverbOn(16,24,val,0);
- break;
-
- //-------------------------------------------------//
- case H_Reverb+0:
- rvb[0].FB_SRC_A=val;
- break;
-
- case H_Reverb+2 : rvb[0].FB_SRC_B=(s16)val; break;
- case H_Reverb+4 : rvb[0].IIR_ALPHA=(s16)val; break;
- case H_Reverb+6 : rvb[0].ACC_COEF_A=(s16)val; break;
- case H_Reverb+8 : rvb[0].ACC_COEF_B=(s16)val; break;
- case H_Reverb+10 : rvb[0].ACC_COEF_C=(s16)val; break;
- case H_Reverb+12 : rvb[0].ACC_COEF_D=(s16)val; break;
- case H_Reverb+14 : rvb[0].IIR_COEF=(s16)val; break;
- case H_Reverb+16 : rvb[0].FB_ALPHA=(s16)val; break;
- case H_Reverb+18 : rvb[0].FB_X=(s16)val; break;
- case H_Reverb+20 : rvb[0].IIR_DEST_A0=(s16)val; break;
- case H_Reverb+22 : rvb[0].IIR_DEST_A1=(s16)val; break;
- case H_Reverb+24 : rvb[0].ACC_SRC_A0=(s16)val; break;
- case H_Reverb+26 : rvb[0].ACC_SRC_A1=(s16)val; break;
- case H_Reverb+28 : rvb[0].ACC_SRC_B0=(s16)val; break;
- case H_Reverb+30 : rvb[0].ACC_SRC_B1=(s16)val; break;
- case H_Reverb+32 : rvb[0].IIR_SRC_A0=(s16)val; break;
- case H_Reverb+34 : rvb[0].IIR_SRC_A1=(s16)val; break;
- case H_Reverb+36 : rvb[0].IIR_DEST_B0=(s16)val; break;
- case H_Reverb+38 : rvb[0].IIR_DEST_B1=(s16)val; break;
- case H_Reverb+40 : rvb[0].ACC_SRC_C0=(s16)val; break;
- case H_Reverb+42 : rvb[0].ACC_SRC_C1=(s16)val; break;
- case H_Reverb+44 : rvb[0].ACC_SRC_D0=(s16)val; break;
- case H_Reverb+46 : rvb[0].ACC_SRC_D1=(s16)val; break;
- case H_Reverb+48 : rvb[0].IIR_SRC_B1=(s16)val; break;
- case H_Reverb+50 : rvb[0].IIR_SRC_B0=(s16)val; break;
- case H_Reverb+52 : rvb[0].MIX_DEST_A0=(s16)val; break;
- case H_Reverb+54 : rvb[0].MIX_DEST_A1=(s16)val; break;
- case H_Reverb+56 : rvb[0].MIX_DEST_B0=(s16)val; break;
- case H_Reverb+58 : rvb[0].MIX_DEST_B1=(s16)val; break;
- case H_Reverb+60 : rvb[0].IN_COEF_L=(s16)val; break;
- case H_Reverb+62 : rvb[0].IN_COEF_R=(s16)val; break;
- }
-}
-
-EXPORT_GCC unsigned short CALLBACK SPU2readPS1Port(unsigned long reg)
-{
- const u32 r=reg&0xfff;
-
- if(r>=0x0c00 && r<0x0d80)
- {
- return SPU2read(r-0xc00);
- }
-
- switch(r)
- {
-// case H_SPUctrl:
-// return spuCtrl;
- break;
-
- case H_SPUstat:
- return spuStat2[0];
- break;
-
- case H_SPUaddr:
- return (u16)(spuAddr2[0]>>2);
- break;
-
- case H_SPUdata:
- {
- u16 s=BFLIP16(spuMem[spuAddr2[0]]);
- spuAddr2[0]++;
- if(spuAddr2[0]>0xfffff) spuAddr2[0]=0;
- return s;
- }
- break;
-
- case H_SPUirqAddr:
- return spuIrq2[0]>>2;
- break;
- }
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// SOUND ON register write
-////////////////////////////////////////////////////////////////////////
-
-void SoundOn(int start,int end,unsigned short val) // SOUND ON PSX COMAND
-{
- int ch;
-
- for(ch=start;ch<end;ch++,val>>=1) // loop channels
- {
- if((val&1) && s_chan[ch].pStart) // mmm... start has to be set before key on !?!
- {
- s_chan[ch].bIgnoreLoop=0;
- s_chan[ch].bNew=1;
- dwNewChannel2[ch/24]|=(1<<(ch%24)); // bitfield for faster testing
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// SOUND OFF register write
-////////////////////////////////////////////////////////////////////////
-
-void SoundOff(int start,int end,unsigned short val) // SOUND OFF PSX COMMAND
-{
- int ch;
- for(ch=start;ch<end;ch++,val>>=1) // loop channels
- {
- if(val&1) // && s_chan[i].bOn) mmm...
- {
- s_chan[ch].bStop=1;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// FMOD register write
-////////////////////////////////////////////////////////////////////////
-
-void FModOn(int start,int end,unsigned short val) // FMOD ON PSX COMMAND
-{
- int ch;
-
- for(ch=start;ch<end;ch++,val>>=1) // loop channels
- {
- if(val&1) // -> fmod on/off
- {
- if(ch>0)
- {
- s_chan[ch].bFMod=1; // --> sound channel
- s_chan[ch-1].bFMod=2; // --> freq channel
- }
- }
- else
- {
- s_chan[ch].bFMod=0; // --> turn off fmod
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// NOISE register write
-////////////////////////////////////////////////////////////////////////
-
-void NoiseOn(int start,int end,unsigned short val) // NOISE ON PSX COMMAND
-{
- int ch;
-
- for(ch=start;ch<end;ch++,val>>=1) // loop channels
- {
- if(val&1) // -> noise on/off
- {
- s_chan[ch].bNoise=1;
- }
- else
- {
- s_chan[ch].bNoise=0;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// LEFT VOLUME register write
-////////////////////////////////////////////////////////////////////////
-
-// please note: sweep and phase invert are wrong... but I've never seen
-// them used
-
-void SetVolumeL(unsigned char ch,short vol) // LEFT VOLUME
-{
- s_chan[ch].iLeftVolRaw=vol;
-
- if(vol&0x8000) // sweep?
- {
- short sInc=1; // -> sweep up?
- if(vol&0x2000) sInc=-1; // -> or down?
- if(vol&0x1000) vol^=0xffff; // -> mmm... phase inverted? have to investigate this
- vol=((vol&0x7f)+1)/2; // -> sweep: 0..127 -> 0..64
- vol+=vol/(2*sInc); // -> HACK: we don't sweep right now, so we just raise/lower the volume by the half!
- vol*=128;
- }
- else // no sweep:
- {
- if(vol&0x4000) // -> mmm... phase inverted? have to investigate this
- //vol^=0xffff;
- vol=0x3fff-(vol&0x3fff);
- }
-
- vol&=0x3fff;
- s_chan[ch].iLeftVolume=vol; // store volume
-}
-
-////////////////////////////////////////////////////////////////////////
-// RIGHT VOLUME register write
-////////////////////////////////////////////////////////////////////////
-
-void SetVolumeR(unsigned char ch,short vol) // RIGHT VOLUME
-{
- s_chan[ch].iRightVolRaw=vol;
-
- if(vol&0x8000) // comments... see above :)
- {
- short sInc=1;
- if(vol&0x2000) sInc=-1;
- if(vol&0x1000) vol^=0xffff;
- vol=((vol&0x7f)+1)/2;
- vol+=vol/(2*sInc);
- vol*=128;
- }
- else
- {
- if(vol&0x4000) //vol=vol^=0xffff;
- vol=0x3fff-(vol&0x3fff);
- }
-
- vol&=0x3fff;
- s_chan[ch].iRightVolume=vol;
-}
-
-////////////////////////////////////////////////////////////////////////
-// PITCH register write
-////////////////////////////////////////////////////////////////////////
-
-void SetPitch(int ch,unsigned short val) // SET PITCH
-{
- int NP;
- double intr;
-
- if(val>0x3fff) NP=0x3fff; // get pitch val
- else NP=val;
-
- intr = (double)48000.0f / (double)44100.0f * (double)NP;
- NP = (uint32_t)intr;
-
- s_chan[ch].iRawPitch=NP;
-
- NP=(44100L*NP)/4096L; // calc frequency
-
- if(NP<1) NP=1; // some security
- s_chan[ch].iActFreq=NP; // store frequency
-}
-
-////////////////////////////////////////////////////////////////////////
-// REVERB register write
-////////////////////////////////////////////////////////////////////////
-
-void ReverbOn(int start,int end,unsigned short val,int iRight) // REVERB ON PSX COMMAND
-{
- int ch;
-
- for(ch=start;ch<end;ch++,val>>=1) // loop channels
- {
- if(val&1) // -> reverb on/off
- {
- if(iRight) s_chan[ch].bReverbR=1;
- else s_chan[ch].bReverbL=1;
- }
- else
- {
- if(iRight) s_chan[ch].bReverbR=0;
- else s_chan[ch].bReverbL=0;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// REVERB START register write
-////////////////////////////////////////////////////////////////////////
-
-void SetReverbAddr(int core)
-{
- long val=spuRvbAddr2[core];
-
- if(rvb[core].StartAddr!=val)
- {
- if(val<=0x27ff)
- {
- rvb[core].StartAddr=rvb[core].CurrAddr=0;
- }
- else
- {
- rvb[core].StartAddr=val;
- rvb[core].CurrAddr=rvb[core].StartAddr;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// DRY LEFT/RIGHT per voice switches
-////////////////////////////////////////////////////////////////////////
-
-void VolumeOn(int start,int end,unsigned short val,int iRight) // VOLUME ON PSX COMMAND
-{
- int ch;
-
- for(ch=start;ch<end;ch++,val>>=1) // loop channels
- {
- if(val&1) // -> reverb on/off
- {
- if(iRight) s_chan[ch].bVolumeR=1;
- else s_chan[ch].bVolumeL=1;
- }
- else
- {
- if(iRight) s_chan[ch].bVolumeR=0;
- else s_chan[ch].bVolumeL=0;
- }
- }
-}
-
-
diff --git a/src/psf/peops2/registers.cc b/src/psf/peops2/registers.cc
new file mode 100644
index 000000000000..bad9e1d36c57
--- /dev/null
+++ b/src/psf/peops2/registers.cc
@@ -0,0 +1,1343 @@
+/***************************************************************************
+ registers.c - description
+ -------------------
+ begin : Wed May 15 2002
+ copyright : (C) 2002 by Pete Bernert
+ email : BlackDove at addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+//*************************************************************************//
+// History of changes:
+//
+// 2004/04/04 - Pete
+// - changed plugin to emulate PS2 spu
+//
+// 2003/02/09 - kode54
+// - removed &0x3fff from reverb volume registers, fixes a few games,
+// hopefully won't be breaking anything
+//
+// 2003/01/19 - Pete
+// - added Neill's reverb
+//
+// 2003/01/06 - Pete
+// - added Neill's ADSR timings
+//
+// 2002/05/15 - Pete
+// - generic cleanup for the Peops release
+//
+//*************************************************************************//
+
+#include "stdafx.h"
+
+#define _IN_REGISTERS
+
+#include "../peops2/externals.h"
+#include "../peops2/registers.h"
+#include "../peops2/regs.h"
+#include "../peops2/reverb.h"
+
+/*
+// adsr time values (in ms) by James Higgs ... see the end of
+// the adsr.c source for details
+
+#define ATTACK_MS 514L
+#define DECAYHALF_MS 292L
+#define DECAY_MS 584L
+#define SUSTAIN_MS 450L
+#define RELEASE_MS 446L
+*/
+
+// we have a timebase of 1.020408f ms, not 1 ms... so adjust adsr defines
+#define ATTACK_MS 494L
+#define DECAYHALF_MS 286L
+#define DECAY_MS 572L
+#define SUSTAIN_MS 441L
+#define RELEASE_MS 437L
+
+// Prototypes
+void SetVolumeL(unsigned char ch,short vol);
+void SetVolumeR(unsigned char ch,short vol);
+void ReverbOn(int start,int end,unsigned short val,int iRight);
+void SetReverbAddr(int core);
+void VolumeOn(int start,int end,unsigned short val,int iRight);
+
+////////////////////////////////////////////////////////////////////////
+// WRITE REGISTERS: called by main emu
+////////////////////////////////////////////////////////////////////////
+
+EXPORT_GCC void CALLBACK SPU2write(unsigned long reg, unsigned short val)
+{
+ long r=reg&0xffff;
+
+ regArea[r>>1] = val;
+
+// printf("SPU2: %04x to %08x\n", val, reg);
+
+ if((r>=0x0000 && r<0x0180)||(r>=0x0400 && r<0x0580)) // some channel info?
+ {
+ int ch=(r>>4)&0x1f;
+ if(r>=0x400) ch+=24;
+
+ switch(r&0x0f)
+ {
+ //------------------------------------------------// r volume
+ case 0:
+ SetVolumeL((unsigned char)ch,val);
+ break;
+ //------------------------------------------------// l volume
+ case 2:
+ SetVolumeR((unsigned char)ch,val);
+ break;
+ //------------------------------------------------// pitch
+ case 4:
+ SetPitch(ch,val);
+ break;
+ //------------------------------------------------// level with pre-calcs
+ case 6:
+ {
+ const unsigned long lval=val;unsigned long lx;
+ //---------------------------------------------//
+ s_chan[ch].ADSRX.AttackModeExp=(lval&0x8000)?1:0;
+ s_chan[ch].ADSRX.AttackRate=(lval>>8) & 0x007f;
+ s_chan[ch].ADSRX.DecayRate=(lval>>4) & 0x000f;
+ s_chan[ch].ADSRX.SustainLevel=lval & 0x000f;
+ //---------------------------------------------//
+ if(!iDebugMode) break;
+ //---------------------------------------------// stuff below is only for debug mode
+
+ s_chan[ch].ADSR.AttackModeExp=(lval&0x8000)?1:0; //0x007f
+
+ lx=(((lval>>8) & 0x007f)>>2); // attack time to run from 0 to 100% volume
+ lx = (lx < 31) ? lx : 31; // no overflow on shift!
+ if(lx)
+ {
+ lx = (1<<lx);
+ if(lx<2147483) lx=(lx*ATTACK_MS)/10000L; // another overflow check
+ else lx=(lx/10000L)*ATTACK_MS;
+ if(!lx) lx=1;
+ }
+ s_chan[ch].ADSR.AttackTime=lx;
+
+ s_chan[ch].ADSR.SustainLevel= // our adsr vol runs from 0 to 1024, so scale the sustain level
+ (1024*((lval) & 0x000f))/15;
+
+ lx=(lval>>4) & 0x000f; // decay:
+ if(lx) // our const decay value is time it takes from 100% to 0% of volume
+ {
+ lx = ((1<<(lx))*DECAY_MS)/10000L;
+ if(!lx) lx=1;
+ }
+ s_chan[ch].ADSR.DecayTime = // so calc how long does it take to run from 100% to the wanted sus level
+ (lx*(1024-s_chan[ch].ADSR.SustainLevel))/1024;
+ }
+ break;
+ //------------------------------------------------// adsr times with pre-calcs
+ case 8:
+ {
+ const unsigned long lval=val;unsigned long lx;
+
+ //----------------------------------------------//
+ s_chan[ch].ADSRX.SustainModeExp = (lval&0x8000)?1:0;
+ s_chan[ch].ADSRX.SustainIncrease= (lval&0x4000)?0:1;
+ s_chan[ch].ADSRX.SustainRate = (lval>>6) & 0x007f;
+ s_chan[ch].ADSRX.ReleaseModeExp = (lval&0x0020)?1:0;
+ s_chan[ch].ADSRX.ReleaseRate = lval & 0x001f;
+ //----------------------------------------------//
+ if(!iDebugMode) break;
+ //----------------------------------------------// stuff below is only for debug mode
+
+ s_chan[ch].ADSR.SustainModeExp = (lval&0x8000)?1:0;
+ s_chan[ch].ADSR.ReleaseModeExp = (lval&0x0020)?1:0;
+
+ lx=((((lval>>6) & 0x007f)>>2)); // sustain time... often very high
+ lx = (lx < 31) ? lx : 31; // values are used to hold the volume
+ if(lx) // until a sound stop occurs
+ { // the highest value we reach (due to
+ lx = (1<<lx); // overflow checking) is:
+ if(lx<2147483) lx=(lx*SUSTAIN_MS)/10000L; // 94704 seconds = 1578 minutes = 26 hours...
+ else lx=(lx/10000L)*SUSTAIN_MS; // should be enuff... if the stop doesn't
+ if(!lx) lx=1; // come in this time span, I don't care :)
+ }
+ s_chan[ch].ADSR.SustainTime = lx;
+
+ lx=(lval & 0x001f);
+ s_chan[ch].ADSR.ReleaseVal =lx;
+ if(lx) // release time from 100% to 0%
+ { // note: the release time will be
+ lx = (1<<lx); // adjusted when a stop is coming,
+ if(lx<2147483) lx=(lx*RELEASE_MS)/10000L; // so at this time the adsr vol will
+ else lx=(lx/10000L)*RELEASE_MS; // run from (current volume) to 0%
+ if(!lx) lx=1;
+ }
+ s_chan[ch].ADSR.ReleaseTime=lx;
+
+ if(lval & 0x4000) // add/dec flag
+ s_chan[ch].ADSR.SustainModeDec=-1;
+ else s_chan[ch].ADSR.SustainModeDec=1;
+ }
+ break;
+ //------------------------------------------------//
+ }
+
+ iSpuAsyncWait=0;
+
+ return;
+ }
+
+ if((r>=0x01c0 && r<0x02E0)||(r>=0x05c0 && r<0x06E0)) // some channel info?
+ {
+ int ch=0;
+ if(r>=0x400) {ch=24;r-=0x400;}
+
+ ch+=(r-0x1c0)/12;
+ r-=(ch%24)*12;
+ switch(r)
+ {
+ //------------------------------------------------//
+ case 0x1C0:
+ s_chan[ch].iStartAdr=(((unsigned long)val&0xf)<<16)|(s_chan[ch].iStartAdr&0xFFFF);
+ s_chan[ch].pStart=spuMemC+(s_chan[ch].iStartAdr<<1);
+ break;
+ case 0x1C2:
+ s_chan[ch].iStartAdr=(s_chan[ch].iStartAdr & 0xF0000) | (val & 0xFFFF);
+ s_chan[ch].pStart=spuMemC+(s_chan[ch].iStartAdr<<1);
+ break;
+ //------------------------------------------------//
+ case 0x1C4:
+ s_chan[ch].iLoopAdr=(((unsigned long)val&0xf)<<16)|(s_chan[ch].iLoopAdr&0xFFFF);
+ s_chan[ch].pLoop=spuMemC+(s_chan[ch].iLoopAdr<<1);
+ s_chan[ch].bIgnoreLoop=1;
+ break;
+ case 0x1C6:
+ s_chan[ch].iLoopAdr=(s_chan[ch].iLoopAdr & 0xF0000) | (val & 0xFFFF);
+ s_chan[ch].pLoop=spuMemC+(s_chan[ch].iLoopAdr<<1);
+ s_chan[ch].bIgnoreLoop=1;
+ break;
+ //------------------------------------------------//
+ case 0x1C8:
+ // unused... check if it gets written as well
+ s_chan[ch].iNextAdr=(((unsigned long)val&0xf)<<16)|(s_chan[ch].iNextAdr&0xFFFF);
+ break;
+ case 0x1CA:
+ // unused... check if it gets written as well
+ s_chan[ch].iNextAdr=(s_chan[ch].iNextAdr & 0xF0000) | (val & 0xFFFF);
+ break;
+ //------------------------------------------------//
+ }
+
+ iSpuAsyncWait=0;
+
+ return;
+ }
+
+ switch(r)
+ {
+ //-------------------------------------------------//
+ case PS2_C0_SPUaddr_Hi:
+ spuAddr2[0] = (((unsigned long)val&0xf)<<16)|(spuAddr2[0]&0xFFFF);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_SPUaddr_Lo:
+ spuAddr2[0] = (spuAddr2[0] & 0xF0000) | (val & 0xFFFF);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUaddr_Hi:
+ spuAddr2[1] = (((unsigned long)val&0xf)<<16)|(spuAddr2[1]&0xFFFF);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUaddr_Lo:
+ spuAddr2[1] = (spuAddr2[1] & 0xF0000) | (val & 0xFFFF);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_SPUdata:
+ spuMem[spuAddr2[0]] = val;
+ spuAddr2[0]++;
+ if(spuAddr2[0]>0xfffff) spuAddr2[0]=0;
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUdata:
+ spuMem[spuAddr2[1]] = val;
+ spuAddr2[1]++;
+ if(spuAddr2[1]>0xfffff) spuAddr2[1]=0;
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_ATTR:
+ spuCtrl2[0]=val;
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_ATTR:
+ spuCtrl2[1]=val;
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_SPUstat:
+ spuStat2[0]=val;
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUstat:
+ spuStat2[1]=val;
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_ReverbAddr_Hi:
+ spuRvbAddr2[0] = (((unsigned long)val&0xf)<<16)|(spuRvbAddr2[0]&0xFFFF);
+ SetReverbAddr(0);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_ReverbAddr_Lo:
+ spuRvbAddr2[0] = (spuRvbAddr2[0] & 0xF0000) | (val & 0xFFFF);
+ SetReverbAddr(0);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_ReverbAEnd_Hi:
+ spuRvbAEnd2[0] = (((unsigned long)val&0xf)<<16)|(/*spuRvbAEnd2[0]&*/0xFFFF);
+ rvb[0].EndAddr=spuRvbAEnd2[0];
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_ReverbAEnd_Hi:
+ spuRvbAEnd2[1] = (((unsigned long)val&0xf)<<16)|(/*spuRvbAEnd2[1]&*/0xFFFF);
+ rvb[1].EndAddr=spuRvbAEnd2[1];
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_ReverbAddr_Hi:
+ spuRvbAddr2[1] = (((unsigned long)val&0xf)<<16)|(spuRvbAddr2[1]&0xFFFF);
+ SetReverbAddr(1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_ReverbAddr_Lo:
+ spuRvbAddr2[1] = (spuRvbAddr2[1] & 0xF0000) | (val & 0xFFFF);
+ SetReverbAddr(1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_SPUirqAddr_Hi:
+ spuIrq2[0] = (((unsigned long)val&0xf)<<16)|(spuIrq2[0]&0xFFFF);
+ pSpuIrq[0]=spuMemC+(spuIrq2[0]<<1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_SPUirqAddr_Lo:
+ spuIrq2[0] = (spuIrq2[0] & 0xF0000) | (val & 0xFFFF);
+ pSpuIrq[0]=spuMemC+(spuIrq2[0]<<1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUirqAddr_Hi:
+ spuIrq2[1] = (((unsigned long)val&0xf)<<16)|(spuIrq2[1]&0xFFFF);
+ pSpuIrq[1]=spuMemC+(spuIrq2[1]<<1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUirqAddr_Lo:
+ spuIrq2[1] = (spuIrq2[1] & 0xF0000) | (val & 0xFFFF);
+ pSpuIrq[1]=spuMemC+(spuIrq2[1]<<1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_SPUrvolL:
+ rvb[0].VolLeft=val;
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_SPUrvolR:
+ rvb[0].VolRight=val;
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUrvolL:
+ rvb[1].VolLeft=val;
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUrvolR:
+ rvb[1].VolRight=val;
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_SPUon1:
+ SoundOn(0,16,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_SPUon2:
+ SoundOn(16,24,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUon1:
+ SoundOn(24,40,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUon2:
+ SoundOn(40,48,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_SPUoff1:
+ SoundOff(0,16,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_SPUoff2:
+ SoundOff(16,24,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUoff1:
+ SoundOff(24,40,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUoff2:
+ SoundOff(40,48,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_SPUend1:
+ case PS2_C0_SPUend2:
+ if(val) dwEndChannel2[0]=0;
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_SPUend1:
+ case PS2_C1_SPUend2:
+ if(val) dwEndChannel2[1]=0;
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_FMod1:
+ FModOn(0,16,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_FMod2:
+ FModOn(16,24,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_FMod1:
+ FModOn(24,40,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_FMod2:
+ FModOn(40,48,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_Noise1:
+ NoiseOn(0,16,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_Noise2:
+ NoiseOn(16,24,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_Noise1:
+ NoiseOn(24,40,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_Noise2:
+ NoiseOn(40,48,val);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_DryL1:
+ VolumeOn(0,16,val,0);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_DryL2:
+ VolumeOn(16,24,val,0);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_DryL1:
+ VolumeOn(24,40,val,0);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_DryL2:
+ VolumeOn(40,48,val,0);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_DryR1:
+ VolumeOn(0,16,val,1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_DryR2:
+ VolumeOn(16,24,val,1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_DryR1:
+ VolumeOn(24,40,val,1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_DryR2:
+ VolumeOn(40,48,val,1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_RVBon1_L:
+ ReverbOn(0,16,val,0);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_RVBon2_L:
+ ReverbOn(16,24,val,0);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_RVBon1_L:
+ ReverbOn(24,40,val,0);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_RVBon2_L:
+ ReverbOn(40,48,val,0);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_RVBon1_R:
+ ReverbOn(0,16,val,1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_RVBon2_R:
+ ReverbOn(16,24,val,1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_RVBon1_R:
+ ReverbOn(24,40,val,1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C1_RVBon2_R:
+ ReverbOn(40,48,val,1);
+ break;
+ //-------------------------------------------------//
+ case PS2_C0_Reverb+0:
+ rvb[0].FB_SRC_A=(((unsigned long)val&0xf)<<16)|(rvb[0].FB_SRC_A&0xFFFF);
+ break;
+ case PS2_C0_Reverb+2:
+ rvb[0].FB_SRC_A=(rvb[0].FB_SRC_A & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+4:
+ rvb[0].FB_SRC_B=(((unsigned long)val&0xf)<<16)|(rvb[0].FB_SRC_B&0xFFFF);
+ break;
+ case PS2_C0_Reverb+6:
+ rvb[0].FB_SRC_B=(rvb[0].FB_SRC_B & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+8:
+ rvb[0].IIR_DEST_A0=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_DEST_A0&0xFFFF);
+ break;
+ case PS2_C0_Reverb+10:
+ rvb[0].IIR_DEST_A0=(rvb[0].IIR_DEST_A0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+12:
+ rvb[0].IIR_DEST_A1=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_DEST_A1&0xFFFF);
+ break;
+ case PS2_C0_Reverb+14:
+ rvb[0].IIR_DEST_A1=(rvb[0].IIR_DEST_A1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+16:
+ rvb[0].ACC_SRC_A0=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_A0&0xFFFF);
+ break;
+ case PS2_C0_Reverb+18:
+ rvb[0].ACC_SRC_A0=(rvb[0].ACC_SRC_A0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+20:
+ rvb[0].ACC_SRC_A1=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_A1&0xFFFF);
+ break;
+ case PS2_C0_Reverb+22:
+ rvb[0].ACC_SRC_A1=(rvb[0].ACC_SRC_A1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+24:
+ rvb[0].ACC_SRC_B0=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_B0&0xFFFF);
+ break;
+ case PS2_C0_Reverb+26:
+ rvb[0].ACC_SRC_B0=(rvb[0].ACC_SRC_B0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+28:
+ rvb[0].ACC_SRC_B1=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_B1&0xFFFF);
+ break;
+ case PS2_C0_Reverb+30:
+ rvb[0].ACC_SRC_B1=(rvb[0].ACC_SRC_B1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+32:
+ rvb[0].IIR_SRC_A0=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_SRC_A0&0xFFFF);
+ break;
+ case PS2_C0_Reverb+34:
+ rvb[0].IIR_SRC_A0=(rvb[0].IIR_SRC_A0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+36:
+ rvb[0].IIR_SRC_A1=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_SRC_A1&0xFFFF);
+ break;
+ case PS2_C0_Reverb+38:
+ rvb[0].IIR_SRC_A1=(rvb[0].IIR_SRC_A1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+40:
+ rvb[0].IIR_DEST_B0=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_DEST_B0&0xFFFF);
+ break;
+ case PS2_C0_Reverb+42:
+ rvb[0].IIR_DEST_B0=(rvb[0].IIR_DEST_B0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+44:
+ rvb[0].IIR_DEST_B1=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_DEST_B1&0xFFFF);
+ break;
+ case PS2_C0_Reverb+46:
+ rvb[0].IIR_DEST_B1=(rvb[0].IIR_DEST_B1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+48:
+ rvb[0].ACC_SRC_C0=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_C0&0xFFFF);
+ break;
+ case PS2_C0_Reverb+50:
+ rvb[0].ACC_SRC_C0=(rvb[0].ACC_SRC_C0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+52:
+ rvb[0].ACC_SRC_C1=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_C1&0xFFFF);
+ break;
+ case PS2_C0_Reverb+54:
+ rvb[0].ACC_SRC_C1=(rvb[0].ACC_SRC_C1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+56:
+ rvb[0].ACC_SRC_D0=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_D0&0xFFFF);
+ break;
+ case PS2_C0_Reverb+58:
+ rvb[0].ACC_SRC_D0=(rvb[0].ACC_SRC_D0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+60:
+ rvb[0].ACC_SRC_D1=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_D1&0xFFFF);
+ break;
+ case PS2_C0_Reverb+62:
+ rvb[0].ACC_SRC_D1=(rvb[0].ACC_SRC_D1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+64:
+ rvb[0].IIR_SRC_B1=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_SRC_B1&0xFFFF);
+ break;
+ case PS2_C0_Reverb+66:
+ rvb[0].IIR_SRC_B1=(rvb[0].IIR_SRC_B1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+68:
+ rvb[0].IIR_SRC_B0=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_SRC_B0&0xFFFF);
+ break;
+ case PS2_C0_Reverb+70:
+ rvb[0].IIR_SRC_B0=(rvb[0].IIR_SRC_B0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+72:
+ rvb[0].MIX_DEST_A0=(((unsigned long)val&0xf)<<16)|(rvb[0].MIX_DEST_A0&0xFFFF);
+ break;
+ case PS2_C0_Reverb+74:
+ rvb[0].MIX_DEST_A0=(rvb[0].MIX_DEST_A0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+76:
+ rvb[0].MIX_DEST_A1=(((unsigned long)val&0xf)<<16)|(rvb[0].MIX_DEST_A1&0xFFFF);
+ break;
+ case PS2_C0_Reverb+78:
+ rvb[0].MIX_DEST_A1=(rvb[0].MIX_DEST_A1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+80:
+ rvb[0].MIX_DEST_B0=(((unsigned long)val&0xf)<<16)|(rvb[0].MIX_DEST_B0&0xFFFF);
+ break;
+ case PS2_C0_Reverb+82:
+ rvb[0].MIX_DEST_B0=(rvb[0].MIX_DEST_B0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_Reverb+84:
+ rvb[0].MIX_DEST_B1=(((unsigned long)val&0xf)<<16)|(rvb[0].MIX_DEST_B1&0xFFFF);
+ break;
+ case PS2_C0_Reverb+86:
+ rvb[0].MIX_DEST_B1=(rvb[0].MIX_DEST_B1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C0_ReverbX+0: rvb[0].IIR_ALPHA=(short)val; break;
+ case PS2_C0_ReverbX+2: rvb[0].ACC_COEF_A=(short)val; break;
+ case PS2_C0_ReverbX+4: rvb[0].ACC_COEF_B=(short)val; break;
+ case PS2_C0_ReverbX+6: rvb[0].ACC_COEF_C=(short)val; break;
+ case PS2_C0_ReverbX+8: rvb[0].ACC_COEF_D=(short)val; break;
+ case PS2_C0_ReverbX+10: rvb[0].IIR_COEF=(short)val; break;
+ case PS2_C0_ReverbX+12: rvb[0].FB_ALPHA=(short)val; break;
+ case PS2_C0_ReverbX+14: rvb[0].FB_X=(short)val; break;
+ case PS2_C0_ReverbX+16: rvb[0].IN_COEF_L=(short)val; break;
+ case PS2_C0_ReverbX+18: rvb[0].IN_COEF_R=(short)val; break;
+ //-------------------------------------------------//
+ case PS2_C1_Reverb+0:
+ rvb[1].FB_SRC_A=(((unsigned long)val&0xf)<<16)|(rvb[1].FB_SRC_A&0xFFFF);
+ break;
+ case PS2_C1_Reverb+2:
+ rvb[1].FB_SRC_A=(rvb[1].FB_SRC_A & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+4:
+ rvb[1].FB_SRC_B=(((unsigned long)val&0xf)<<16)|(rvb[1].FB_SRC_B&0xFFFF);
+ break;
+ case PS2_C1_Reverb+6:
+ rvb[1].FB_SRC_B=(rvb[1].FB_SRC_B & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+8:
+ rvb[1].IIR_DEST_A0=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_DEST_A0&0xFFFF);
+ break;
+ case PS2_C1_Reverb+10:
+ rvb[1].IIR_DEST_A0=(rvb[1].IIR_DEST_A0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+12:
+ rvb[1].IIR_DEST_A1=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_DEST_A1&0xFFFF);
+ break;
+ case PS2_C1_Reverb+14:
+ rvb[1].IIR_DEST_A1=(rvb[1].IIR_DEST_A1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+16:
+ rvb[1].ACC_SRC_A0=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_A0&0xFFFF);
+ break;
+ case PS2_C1_Reverb+18:
+ rvb[1].ACC_SRC_A0=(rvb[1].ACC_SRC_A0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+20:
+ rvb[1].ACC_SRC_A1=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_A1&0xFFFF);
+ break;
+ case PS2_C1_Reverb+22:
+ rvb[1].ACC_SRC_A1=(rvb[1].ACC_SRC_A1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+24:
+ rvb[1].ACC_SRC_B0=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_B0&0xFFFF);
+ break;
+ case PS2_C1_Reverb+26:
+ rvb[1].ACC_SRC_B0=(rvb[1].ACC_SRC_B0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+28:
+ rvb[1].ACC_SRC_B1=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_B1&0xFFFF);
+ break;
+ case PS2_C1_Reverb+30:
+ rvb[1].ACC_SRC_B1=(rvb[1].ACC_SRC_B1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+32:
+ rvb[1].IIR_SRC_A0=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_SRC_A0&0xFFFF);
+ break;
+ case PS2_C1_Reverb+34:
+ rvb[1].IIR_SRC_A0=(rvb[1].IIR_SRC_A0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+36:
+ rvb[1].IIR_SRC_A1=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_SRC_A1&0xFFFF);
+ break;
+ case PS2_C1_Reverb+38:
+ rvb[1].IIR_SRC_A1=(rvb[1].IIR_SRC_A1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+40:
+ rvb[1].IIR_DEST_B0=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_DEST_B0&0xFFFF);
+ break;
+ case PS2_C1_Reverb+42:
+ rvb[1].IIR_DEST_B0=(rvb[1].IIR_DEST_B0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+44:
+ rvb[1].IIR_DEST_B1=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_DEST_B1&0xFFFF);
+ break;
+ case PS2_C1_Reverb+46:
+ rvb[1].IIR_DEST_B1=(rvb[1].IIR_DEST_B1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+48:
+ rvb[1].ACC_SRC_C0=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_C0&0xFFFF);
+ break;
+ case PS2_C1_Reverb+50:
+ rvb[1].ACC_SRC_C0=(rvb[1].ACC_SRC_C0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+52:
+ rvb[1].ACC_SRC_C1=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_C1&0xFFFF);
+ break;
+ case PS2_C1_Reverb+54:
+ rvb[1].ACC_SRC_C1=(rvb[1].ACC_SRC_C1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+56:
+ rvb[1].ACC_SRC_D0=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_D0&0xFFFF);
+ break;
+ case PS2_C1_Reverb+58:
+ rvb[1].ACC_SRC_D0=(rvb[1].ACC_SRC_D0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+60:
+ rvb[1].ACC_SRC_D1=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_D1&0xFFFF);
+ break;
+ case PS2_C1_Reverb+62:
+ rvb[1].ACC_SRC_D1=(rvb[1].ACC_SRC_D1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+64:
+ rvb[1].IIR_SRC_B1=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_SRC_B1&0xFFFF);
+ break;
+ case PS2_C1_Reverb+66:
+ rvb[1].IIR_SRC_B1=(rvb[1].IIR_SRC_B1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+68:
+ rvb[1].IIR_SRC_B0=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_SRC_B0&0xFFFF);
+ break;
+ case PS2_C1_Reverb+70:
+ rvb[1].IIR_SRC_B0=(rvb[1].IIR_SRC_B0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+72:
+ rvb[1].MIX_DEST_A0=(((unsigned long)val&0xf)<<16)|(rvb[1].MIX_DEST_A0&0xFFFF);
+ break;
+ case PS2_C1_Reverb+74:
+ rvb[1].MIX_DEST_A0=(rvb[1].MIX_DEST_A0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+76:
+ rvb[1].MIX_DEST_A1=(((unsigned long)val&0xf)<<16)|(rvb[1].MIX_DEST_A1&0xFFFF);
+ break;
+ case PS2_C1_Reverb+78:
+ rvb[1].MIX_DEST_A1=(rvb[1].MIX_DEST_A1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+80:
+ rvb[1].MIX_DEST_B0=(((unsigned long)val&0xf)<<16)|(rvb[1].MIX_DEST_B0&0xFFFF);
+ break;
+ case PS2_C1_Reverb+82:
+ rvb[1].MIX_DEST_B0=(rvb[1].MIX_DEST_B0 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_Reverb+84:
+ rvb[1].MIX_DEST_B1=(((unsigned long)val&0xf)<<16)|(rvb[1].MIX_DEST_B1&0xFFFF);
+ break;
+ case PS2_C1_Reverb+86:
+ rvb[1].MIX_DEST_B1=(rvb[1].MIX_DEST_B1 & 0xF0000) | ((val) & 0xFFFF);
+ break;
+ case PS2_C1_ReverbX+0: rvb[1].IIR_ALPHA=(short)val; break;
+ case PS2_C1_ReverbX+2: rvb[1].ACC_COEF_A=(short)val; break;
+ case PS2_C1_ReverbX+4: rvb[1].ACC_COEF_B=(short)val; break;
+ case PS2_C1_ReverbX+6: rvb[1].ACC_COEF_C=(short)val; break;
+ case PS2_C1_ReverbX+8: rvb[1].ACC_COEF_D=(short)val; break;
+ case PS2_C1_ReverbX+10: rvb[1].IIR_COEF=(short)val; break;
+ case PS2_C1_ReverbX+12: rvb[1].FB_ALPHA=(short)val; break;
+ case PS2_C1_ReverbX+14: rvb[1].FB_X=(short)val; break;
+ case PS2_C1_ReverbX+16: rvb[1].IN_COEF_L=(short)val; break;
+ case PS2_C1_ReverbX+18: rvb[1].IN_COEF_R=(short)val; break;
+ }
+
+ iSpuAsyncWait=0;
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// READ REGISTER: called by main emu
+////////////////////////////////////////////////////////////////////////
+
+EXPORT_GCC unsigned short CALLBACK SPU2read(unsigned long reg)
+{
+ long r=reg&0xffff;
+
+#ifdef _WINDOWS
+// if(iDebugMode==1) logprintf("R_REG %X\r\n",reg&0xFFFF);
+#endif
+
+ iSpuAsyncWait=0;
+
+ if((r>=0x0000 && r<0x0180)||(r>=0x0400 && r<0x0580)) // some channel info?
+ {
+ switch(r&0x0f)
+ {
+ //------------------------------------------------// env value
+ case 10:
+ {
+ int ch=(r>>4)&0x1f;
+ if(r>=0x400) ch+=24;
+ if(s_chan[ch].bNew) return 1; // we are started, but not processed? return 1
+ if(s_chan[ch].ADSRX.lVolume && // same here... we haven't decoded one sample yet, so no envelope yet. return 1 as well
+ !s_chan[ch].ADSRX.EnvelopeVol)
+ return 1;
+ return (unsigned short)(s_chan[ch].ADSRX.EnvelopeVol>>16);
+ }break;
+ }
+ }
+
+ if((r>=0x01c0 && r<0x02E0)||(r>=0x05c0 && r<0x06E0)) // some channel info?
+ {
+ int ch=0;unsigned long rx=r;
+ if(rx>=0x400) {ch=24;rx-=0x400;}
+
+ ch+=(rx-0x1c0)/12;
+ rx-=(ch%24)*12;
+
+ switch(rx)
+ {
+ //------------------------------------------------//
+ case 0x1C4:
+ return (((s_chan[ch].pLoop-spuMemC)>>17)&0xF);
+ break;
+ case 0x1C6:
+ return (((s_chan[ch].pLoop-spuMemC)>>1)&0xFFFF);
+ break;
+ //------------------------------------------------//
+ case 0x1C8:
+ return (((s_chan[ch].pCurr-spuMemC)>>17)&0xF);
+ break;
+ case 0x1CA:
+ return (((s_chan[ch].pCurr-spuMemC)>>1)&0xFFFF);
+ break;
+ //------------------------------------------------//
+ }
+ }
+
+ switch(r)
+ {
+ //--------------------------------------------------//
+ case PS2_C0_SPUend1:
+ return (unsigned short)((dwEndChannel2[0]&0xFFFF));
+ case PS2_C0_SPUend2:
+ return (unsigned short)((dwEndChannel2[0]>>16));
+ //--------------------------------------------------//
+ case PS2_C1_SPUend1:
+ return (unsigned short)((dwEndChannel2[1]&0xFFFF));
+ case PS2_C1_SPUend2:
+ return (unsigned short)((dwEndChannel2[1]>>16));
+ //--------------------------------------------------//
+ case PS2_C0_ATTR:
+ return spuCtrl2[0];
+ break;
+ //--------------------------------------------------//
+ case PS2_C1_ATTR:
+ return spuCtrl2[1];
+ break;
+ //--------------------------------------------------//
+ case PS2_C0_SPUstat:
+ return spuStat2[0];
+ break;
+ //--------------------------------------------------//
+ case PS2_C1_SPUstat:
+ return spuStat2[1];
+ break;
+ //--------------------------------------------------//
+ case PS2_C0_SPUdata:
+ {
+ unsigned short s=spuMem[spuAddr2[0]];
+ spuAddr2[0]++;
+ if(spuAddr2[0]>0xfffff) spuAddr2[0]=0;
+ return s;
+ }
+ //--------------------------------------------------//
+ case PS2_C1_SPUdata:
+ {
+ unsigned short s=spuMem[spuAddr2[1]];
+ spuAddr2[1]++;
+ if(spuAddr2[1]>0xfffff) spuAddr2[1]=0;
+ return s;
+ }
+ //--------------------------------------------------//
+ case PS2_C0_SPUaddr_Hi:
+ return (unsigned short)((spuAddr2[0]>>16)&0xF);
+ break;
+ case PS2_C0_SPUaddr_Lo:
+ return (unsigned short)((spuAddr2[0]&0xFFFF));
+ break;
+ //--------------------------------------------------//
+ case PS2_C1_SPUaddr_Hi:
+ return (unsigned short)((spuAddr2[1]>>16)&0xF);
+ break;
+ case PS2_C1_SPUaddr_Lo:
+ return (unsigned short)((spuAddr2[1]&0xFFFF));
+ break;
+ //--------------------------------------------------//
+ }
+
+ return regArea[r>>1];
+}
+
+EXPORT_GCC void CALLBACK SPU2writePS1Port(unsigned long reg, unsigned short val)
+{
+ const u32 r=reg&0xfff;
+
+ if(r>=0xc00 && r<0xd80) // channel info
+ {
+ SPU2write(r-0xc00, val);
+ return;
+ }
+
+ switch(r)
+ {
+ //-------------------------------------------------//
+ case H_SPUaddr:
+ spuAddr2[0] = (u32) val<<2;
+ break;
+ //-------------------------------------------------//
+ case H_SPUdata:
+ spuMem[spuAddr2[0]] = BFLIP16(val);
+ spuAddr2[0]++;
+ if(spuAddr2[0]>0xfffff) spuAddr2[0]=0;
+ break;
+ //-------------------------------------------------//
+ case H_SPUctrl:
+// spuCtrl=val;
+ break;
+ //-------------------------------------------------//
+ case H_SPUstat:
+ spuStat2[0]=val & 0xf800;
+ break;
+ //-------------------------------------------------//
+ case H_SPUReverbAddr:
+ spuRvbAddr2[0] = val;
+ SetReverbAddr(0);
+ break;
+ //-------------------------------------------------//
+ case H_SPUirqAddr:
+ spuIrq2[0] = val<<2;
+ pSpuIrq[0]=spuMemC+((u32) val<<1);
+ break;
+ //-------------------------------------------------//
+ /* Volume settings appear to be at least 15-bit unsigned in this case.
+ Definitely NOT 15-bit signed. Probably 16-bit signed, so s16 type cast.
+ Check out "Chrono Cross: Shadow's End Forest"
+ */
+ case H_SPUrvolL:
+ rvb[0].VolLeft=(s16)val;
+ //printf("%d\n",val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUrvolR:
+ rvb[0].VolRight=(s16)val;
+ //printf("%d\n",val);
+ break;
+ //-------------------------------------------------//
+
+/*
+ case H_ExtLeft:
+ //auxprintf("EL %d\n",val);
+ break;
+ //-------------------------------------------------//
+ case H_ExtRight:
+ //auxprintf("ER %d\n",val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUmvolL:
+ //auxprintf("ML %d\n",val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUmvolR:
+ //auxprintf("MR %d\n",val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUMute1:
+ //printf("M0 %04x\n",val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUMute2:
+ // printf("M1 %04x\n",val);
+ break;
+*/
+ //-------------------------------------------------//
+ case H_SPUon1:
+ SoundOn(0,16,val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUon2:
+ //printf("Boop: %08x: %04x\n",reg,val);
+ SoundOn(16,24,val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUoff1:
+ SoundOff(0,16,val);
+ break;
+ //-------------------------------------------------//
+ case H_SPUoff2:
+ SoundOff(16,24,val);
+ // printf("Boop: %08x: %04x\n",reg,val);
+ break;
+ //-------------------------------------------------//
+ case H_FMod1:
+ FModOn(0,16,val);
+ break;
+ //-------------------------------------------------//
+ case H_FMod2:
+ FModOn(16,24,val);
+ break;
+ //-------------------------------------------------//
+ case H_Noise1:
+ NoiseOn(0,16,val);
+ break;
+ //-------------------------------------------------//
+ case H_Noise2:
+ NoiseOn(16,24,val);
+ break;
+ //-------------------------------------------------//
+ case H_RVBon1:
+ ReverbOn(0,16,val,0);
+ break;
+
+ //-------------------------------------------------//
+ case H_RVBon2:
+ ReverbOn(16,24,val,0);
+ break;
+
+ //-------------------------------------------------//
+ case H_Reverb+0:
+ rvb[0].FB_SRC_A=val;
+ break;
+
+ case H_Reverb+2 : rvb[0].FB_SRC_B=(s16)val; break;
+ case H_Reverb+4 : rvb[0].IIR_ALPHA=(s16)val; break;
+ case H_Reverb+6 : rvb[0].ACC_COEF_A=(s16)val; break;
+ case H_Reverb+8 : rvb[0].ACC_COEF_B=(s16)val; break;
+ case H_Reverb+10 : rvb[0].ACC_COEF_C=(s16)val; break;
+ case H_Reverb+12 : rvb[0].ACC_COEF_D=(s16)val; break;
+ case H_Reverb+14 : rvb[0].IIR_COEF=(s16)val; break;
+ case H_Reverb+16 : rvb[0].FB_ALPHA=(s16)val; break;
+ case H_Reverb+18 : rvb[0].FB_X=(s16)val; break;
+ case H_Reverb+20 : rvb[0].IIR_DEST_A0=(s16)val; break;
+ case H_Reverb+22 : rvb[0].IIR_DEST_A1=(s16)val; break;
+ case H_Reverb+24 : rvb[0].ACC_SRC_A0=(s16)val; break;
+ case H_Reverb+26 : rvb[0].ACC_SRC_A1=(s16)val; break;
+ case H_Reverb+28 : rvb[0].ACC_SRC_B0=(s16)val; break;
+ case H_Reverb+30 : rvb[0].ACC_SRC_B1=(s16)val; break;
+ case H_Reverb+32 : rvb[0].IIR_SRC_A0=(s16)val; break;
+ case H_Reverb+34 : rvb[0].IIR_SRC_A1=(s16)val; break;
+ case H_Reverb+36 : rvb[0].IIR_DEST_B0=(s16)val; break;
+ case H_Reverb+38 : rvb[0].IIR_DEST_B1=(s16)val; break;
+ case H_Reverb+40 : rvb[0].ACC_SRC_C0=(s16)val; break;
+ case H_Reverb+42 : rvb[0].ACC_SRC_C1=(s16)val; break;
+ case H_Reverb+44 : rvb[0].ACC_SRC_D0=(s16)val; break;
+ case H_Reverb+46 : rvb[0].ACC_SRC_D1=(s16)val; break;
+ case H_Reverb+48 : rvb[0].IIR_SRC_B1=(s16)val; break;
+ case H_Reverb+50 : rvb[0].IIR_SRC_B0=(s16)val; break;
+ case H_Reverb+52 : rvb[0].MIX_DEST_A0=(s16)val; break;
+ case H_Reverb+54 : rvb[0].MIX_DEST_A1=(s16)val; break;
+ case H_Reverb+56 : rvb[0].MIX_DEST_B0=(s16)val; break;
+ case H_Reverb+58 : rvb[0].MIX_DEST_B1=(s16)val; break;
+ case H_Reverb+60 : rvb[0].IN_COEF_L=(s16)val; break;
+ case H_Reverb+62 : rvb[0].IN_COEF_R=(s16)val; break;
+ }
+}
+
+EXPORT_GCC unsigned short CALLBACK SPU2readPS1Port(unsigned long reg)
+{
+ const u32 r=reg&0xfff;
+
+ if(r>=0x0c00 && r<0x0d80)
+ {
+ return SPU2read(r-0xc00);
+ }
+
+ switch(r)
+ {
+// case H_SPUctrl:
+// return spuCtrl;
+ break;
+
+ case H_SPUstat:
+ return spuStat2[0];
+ break;
+
+ case H_SPUaddr:
+ return (u16)(spuAddr2[0]>>2);
+ break;
+
+ case H_SPUdata:
+ {
+ u16 s=BFLIP16(spuMem[spuAddr2[0]]);
+ spuAddr2[0]++;
+ if(spuAddr2[0]>0xfffff) spuAddr2[0]=0;
+ return s;
+ }
+ break;
+
+ case H_SPUirqAddr:
+ return spuIrq2[0]>>2;
+ break;
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// SOUND ON register write
+////////////////////////////////////////////////////////////////////////
+
+void SoundOn(int start,int end,unsigned short val) // SOUND ON PSX COMAND
+{
+ int ch;
+
+ for(ch=start;ch<end;ch++,val>>=1) // loop channels
+ {
+ if((val&1) && s_chan[ch].pStart) // mmm... start has to be set before key on !?!
+ {
+ s_chan[ch].bIgnoreLoop=0;
+ s_chan[ch].bNew=1;
+ dwNewChannel2[ch/24]|=(1<<(ch%24)); // bitfield for faster testing
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// SOUND OFF register write
+////////////////////////////////////////////////////////////////////////
+
+void SoundOff(int start,int end,unsigned short val) // SOUND OFF PSX COMMAND
+{
+ int ch;
+ for(ch=start;ch<end;ch++,val>>=1) // loop channels
+ {
+ if(val&1) // && s_chan[i].bOn) mmm...
+ {
+ s_chan[ch].bStop=1;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// FMOD register write
+////////////////////////////////////////////////////////////////////////
+
+void FModOn(int start,int end,unsigned short val) // FMOD ON PSX COMMAND
+{
+ int ch;
+
+ for(ch=start;ch<end;ch++,val>>=1) // loop channels
+ {
+ if(val&1) // -> fmod on/off
+ {
+ if(ch>0)
+ {
+ s_chan[ch].bFMod=1; // --> sound channel
+ s_chan[ch-1].bFMod=2; // --> freq channel
+ }
+ }
+ else
+ {
+ s_chan[ch].bFMod=0; // --> turn off fmod
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// NOISE register write
+////////////////////////////////////////////////////////////////////////
+
+void NoiseOn(int start,int end,unsigned short val) // NOISE ON PSX COMMAND
+{
+ int ch;
+
+ for(ch=start;ch<end;ch++,val>>=1) // loop channels
+ {
+ if(val&1) // -> noise on/off
+ {
+ s_chan[ch].bNoise=1;
+ }
+ else
+ {
+ s_chan[ch].bNoise=0;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// LEFT VOLUME register write
+////////////////////////////////////////////////////////////////////////
+
+// please note: sweep and phase invert are wrong... but I've never seen
+// them used
+
+void SetVolumeL(unsigned char ch,short vol) // LEFT VOLUME
+{
+ s_chan[ch].iLeftVolRaw=vol;
+
+ if(vol&0x8000) // sweep?
+ {
+ short sInc=1; // -> sweep up?
+ if(vol&0x2000) sInc=-1; // -> or down?
+ if(vol&0x1000) vol^=0xffff; // -> mmm... phase inverted? have to investigate this
+ vol=((vol&0x7f)+1)/2; // -> sweep: 0..127 -> 0..64
+ vol+=vol/(2*sInc); // -> HACK: we don't sweep right now, so we just raise/lower the volume by the half!
+ vol*=128;
+ }
+ else // no sweep:
+ {
+ if(vol&0x4000) // -> mmm... phase inverted? have to investigate this
+ //vol^=0xffff;
+ vol=0x3fff-(vol&0x3fff);
+ }
+
+ vol&=0x3fff;
+ s_chan[ch].iLeftVolume=vol; // store volume
+}
+
+////////////////////////////////////////////////////////////////////////
+// RIGHT VOLUME register write
+////////////////////////////////////////////////////////////////////////
+
+void SetVolumeR(unsigned char ch,short vol) // RIGHT VOLUME
+{
+ s_chan[ch].iRightVolRaw=vol;
+
+ if(vol&0x8000) // comments... see above :)
+ {
+ short sInc=1;
+ if(vol&0x2000) sInc=-1;
+ if(vol&0x1000) vol^=0xffff;
+ vol=((vol&0x7f)+1)/2;
+ vol+=vol/(2*sInc);
+ vol*=128;
+ }
+ else
+ {
+ if(vol&0x4000) //vol=vol^=0xffff;
+ vol=0x3fff-(vol&0x3fff);
+ }
+
+ vol&=0x3fff;
+ s_chan[ch].iRightVolume=vol;
+}
+
+////////////////////////////////////////////////////////////////////////
+// PITCH register write
+////////////////////////////////////////////////////////////////////////
+
+void SetPitch(int ch,unsigned short val) // SET PITCH
+{
+ int NP;
+ double intr;
+
+ if(val>0x3fff) NP=0x3fff; // get pitch val
+ else NP=val;
+
+ intr = (double)48000.0f / (double)44100.0f * (double)NP;
+ NP = (uint32_t)intr;
+
+ s_chan[ch].iRawPitch=NP;
+
+ NP=(44100L*NP)/4096L; // calc frequency
+
+ if(NP<1) NP=1; // some security
+ s_chan[ch].iActFreq=NP; // store frequency
+}
+
+////////////////////////////////////////////////////////////////////////
+// REVERB register write
+////////////////////////////////////////////////////////////////////////
+
+void ReverbOn(int start,int end,unsigned short val,int iRight) // REVERB ON PSX COMMAND
+{
+ int ch;
+
+ for(ch=start;ch<end;ch++,val>>=1) // loop channels
+ {
+ if(val&1) // -> reverb on/off
+ {
+ if(iRight) s_chan[ch].bReverbR=1;
+ else s_chan[ch].bReverbL=1;
+ }
+ else
+ {
+ if(iRight) s_chan[ch].bReverbR=0;
+ else s_chan[ch].bReverbL=0;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// REVERB START register write
+////////////////////////////////////////////////////////////////////////
+
+void SetReverbAddr(int core)
+{
+ long val=spuRvbAddr2[core];
+
+ if(rvb[core].StartAddr!=val)
+ {
+ if(val<=0x27ff)
+ {
+ rvb[core].StartAddr=rvb[core].CurrAddr=0;
+ }
+ else
+ {
+ rvb[core].StartAddr=val;
+ rvb[core].CurrAddr=rvb[core].StartAddr;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// DRY LEFT/RIGHT per voice switches
+////////////////////////////////////////////////////////////////////////
+
+void VolumeOn(int start,int end,unsigned short val,int iRight) // VOLUME ON PSX COMMAND
+{
+ int ch;
+
+ for(ch=start;ch<end;ch++,val>>=1) // loop channels
+ {
+ if(val&1) // -> reverb on/off
+ {
+ if(iRight) s_chan[ch].bVolumeR=1;
+ else s_chan[ch].bVolumeL=1;
+ }
+ else
+ {
+ if(iRight) s_chan[ch].bVolumeR=0;
+ else s_chan[ch].bVolumeL=0;
+ }
+ }
+}
+
+
diff --git a/src/psf/peops2/reverb.c b/src/psf/peops2/reverb.c
deleted file mode 100644
index 068dc9575a3a..000000000000
--- a/src/psf/peops2/reverb.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/***************************************************************************
- reverb.c - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove at addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-//*************************************************************************//
-// History of changes:
-//
-// 2004/04/04 - Pete
-// - changed to SPU2 functionality
-//
-// 2003/01/19 - Pete
-// - added Neill's reverb (see at the end of file)
-//
-// 2002/12/26 - Pete
-// - adjusted reverb handling
-//
-// 2002/08/14 - Pete
-// - added extra reverb
-//
-// 2002/05/15 - Pete
-// - generic cleanup for the Peops release
-//
-//*************************************************************************//
-
-#include "stdafx.h"
-
-#define _IN_REVERB
-
-// will be included from spu.c
-#ifdef _IN_SPU
-
-////////////////////////////////////////////////////////////////////////
-// globals
-////////////////////////////////////////////////////////////////////////
-
-// REVERB info and timing vars...
-
-int * sRVBPlay[2];
-int * sRVBEnd[2];
-int * sRVBStart[2];
-
-////////////////////////////////////////////////////////////////////////
-// START REVERB
-////////////////////////////////////////////////////////////////////////
-
-void StartREVERB(int ch)
-{
- int core=ch/24;
-
- if((s_chan[ch].bReverbL || s_chan[ch].bReverbR) && (spuCtrl2[core]&0x80)) // reverb possible?
- {
- if(iUseReverb==1) s_chan[ch].bRVBActive=1;
- }
- else s_chan[ch].bRVBActive=0; // else -> no reverb
-}
-
-////////////////////////////////////////////////////////////////////////
-// HELPER FOR NEILL'S REVERB: re-inits our reverb mixing buf
-////////////////////////////////////////////////////////////////////////
-
-static inline void InitREVERB(void)
-{
- if(iUseReverb==1)
- {
- memset(sRVBStart[0],0,NSSIZE*2*4);
- memset(sRVBStart[1],0,NSSIZE*2*4);
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// STORE REVERB
-////////////////////////////////////////////////////////////////////////
-
-void StoreREVERB(int ch,int ns)
-{
- int core=ch/24;
-
- if(iUseReverb==0) return;
- else
- if(iUseReverb==1) // -------------------------------- // Neil's reverb
- {
- const int iRxl=(s_chan[ch].sval*s_chan[ch].iLeftVolume*s_chan[ch].bReverbL)/0x4000;
- const int iRxr=(s_chan[ch].sval*s_chan[ch].iRightVolume*s_chan[ch].bReverbR)/0x4000;
-
- ns<<=1;
-
- *(sRVBStart[core]+ns) +=iRxl; // -> we mix all active reverb channels into an extra buffer
- *(sRVBStart[core]+ns+1)+=iRxr;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline int g_buffer(int iOff,int core) // get_buffer content helper: takes care about wraps
-{
- short * p=(short *)spuMem;
- iOff=(iOff)+rvb[core].CurrAddr;
- while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
- while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
- return (int)*(p+iOff);
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void s_buffer(int iOff,int iVal,int core) // set_buffer content helper: takes care about wraps and clipping
-{
- short * p=(short *)spuMem;
- iOff=(iOff)+rvb[core].CurrAddr;
- while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
- while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
- if(iVal<-32768L) iVal=-32768L;if(iVal>32767L) iVal=32767L;
- *(p+iOff)=(short)iVal;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void s_buffer1(int iOff,int iVal,int core) // set_buffer (+1 sample) content helper: takes care about wraps and clipping
-{
- short * p=(short *)spuMem;
- iOff=(iOff)+rvb[core].CurrAddr+1;
- while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
- while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
- if(iVal<-32768L) iVal=-32768L;if(iVal>32767L) iVal=32767L;
- *(p+iOff)=(short)iVal;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-int MixREVERBLeft(int ns,int core)
-{
- if(iUseReverb==1)
- {
- if(!rvb[core].StartAddr || !rvb[core].EndAddr ||
- rvb[core].StartAddr>=rvb[core].EndAddr) // reverb is off
- {
- rvb[core].iLastRVBLeft=rvb[core].iLastRVBRight=rvb[core].iRVBLeft=rvb[core].iRVBRight=0;
- return 0;
- }
-
- rvb[core].iCnt++;
-
- if(rvb[core].iCnt&1) // we work on every second left value: downsample to 22 khz
- {
- if((spuCtrl2[core]&0x80)) // -> reverb on? oki
- {
- int ACC0,ACC1,FB_A0,FB_A1,FB_B0,FB_B1;
-
- const int INPUT_SAMPLE_L=*(sRVBStart[core]+(ns<<1));
- const int INPUT_SAMPLE_R=*(sRVBStart[core]+(ns<<1)+1);
-
- const int IIR_INPUT_A0 = (g_buffer(rvb[core].IIR_SRC_A0,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_L * rvb[core].IN_COEF_L)/32768L;
- const int IIR_INPUT_A1 = (g_buffer(rvb[core].IIR_SRC_A1,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_R * rvb[core].IN_COEF_R)/32768L;
- const int IIR_INPUT_B0 = (g_buffer(rvb[core].IIR_SRC_B0,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_L * rvb[core].IN_COEF_L)/32768L;
- const int IIR_INPUT_B1 = (g_buffer(rvb[core].IIR_SRC_B1,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_R * rvb[core].IN_COEF_R)/32768L;
-
- const int IIR_A0 = (IIR_INPUT_A0 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_A0,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
- const int IIR_A1 = (IIR_INPUT_A1 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_A1,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
- const int IIR_B0 = (IIR_INPUT_B0 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_B0,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
- const int IIR_B1 = (IIR_INPUT_B1 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_B1,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
-
- s_buffer1(rvb[core].IIR_DEST_A0, IIR_A0,core);
- s_buffer1(rvb[core].IIR_DEST_A1, IIR_A1,core);
- s_buffer1(rvb[core].IIR_DEST_B0, IIR_B0,core);
- s_buffer1(rvb[core].IIR_DEST_B1, IIR_B1,core);
-
- ACC0 = (g_buffer(rvb[core].ACC_SRC_A0,core) * rvb[core].ACC_COEF_A)/32768L +
- (g_buffer(rvb[core].ACC_SRC_B0,core) * rvb[core].ACC_COEF_B)/32768L +
- (g_buffer(rvb[core].ACC_SRC_C0,core) * rvb[core].ACC_COEF_C)/32768L +
- (g_buffer(rvb[core].ACC_SRC_D0,core) * rvb[core].ACC_COEF_D)/32768L;
- ACC1 = (g_buffer(rvb[core].ACC_SRC_A1,core) * rvb[core].ACC_COEF_A)/32768L +
- (g_buffer(rvb[core].ACC_SRC_B1,core) * rvb[core].ACC_COEF_B)/32768L +
- (g_buffer(rvb[core].ACC_SRC_C1,core) * rvb[core].ACC_COEF_C)/32768L +
- (g_buffer(rvb[core].ACC_SRC_D1,core) * rvb[core].ACC_COEF_D)/32768L;
-
- FB_A0 = g_buffer(rvb[core].MIX_DEST_A0 - rvb[core].FB_SRC_A,core);
- FB_A1 = g_buffer(rvb[core].MIX_DEST_A1 - rvb[core].FB_SRC_A,core);
- FB_B0 = g_buffer(rvb[core].MIX_DEST_B0 - rvb[core].FB_SRC_B,core);
- FB_B1 = g_buffer(rvb[core].MIX_DEST_B1 - rvb[core].FB_SRC_B,core);
-
- s_buffer(rvb[core].MIX_DEST_A0, ACC0 - (FB_A0 * rvb[core].FB_ALPHA)/32768L,core);
- s_buffer(rvb[core].MIX_DEST_A1, ACC1 - (FB_A1 * rvb[core].FB_ALPHA)/32768L,core);
-
- s_buffer(rvb[core].MIX_DEST_B0, (rvb[core].FB_ALPHA * ACC0)/32768L - (FB_A0 * (int)(rvb[core].FB_ALPHA^0xFFFF8000))/32768L - (FB_B0 * rvb[core].FB_X)/32768L,core);
- s_buffer(rvb[core].MIX_DEST_B1, (rvb[core].FB_ALPHA * ACC1)/32768L - (FB_A1 * (int)(rvb[core].FB_ALPHA^0xFFFF8000))/32768L - (FB_B1 * rvb[core].FB_X)/32768L,core);
-
- rvb[core].iLastRVBLeft = rvb[core].iRVBLeft;
- rvb[core].iLastRVBRight = rvb[core].iRVBRight;
-
- rvb[core].iRVBLeft = (g_buffer(rvb[core].MIX_DEST_A0,core)+g_buffer(rvb[core].MIX_DEST_B0,core))/3;
- rvb[core].iRVBRight = (g_buffer(rvb[core].MIX_DEST_A1,core)+g_buffer(rvb[core].MIX_DEST_B1,core))/3;
-
- rvb[core].iRVBLeft = (rvb[core].iRVBLeft * rvb[core].VolLeft) / 0x4000;
- rvb[core].iRVBRight = (rvb[core].iRVBRight * rvb[core].VolRight) / 0x4000;
-
- rvb[core].CurrAddr++;
- if(rvb[core].CurrAddr>rvb[core].EndAddr) rvb[core].CurrAddr=rvb[core].StartAddr;
-
- return rvb[core].iLastRVBLeft+(rvb[core].iRVBLeft-rvb[core].iLastRVBLeft)/2;
- }
- else // -> reverb off
- {
- rvb[core].iLastRVBLeft=rvb[core].iLastRVBRight=rvb[core].iRVBLeft=rvb[core].iRVBRight=0;
- }
-
- rvb[core].CurrAddr++;
- if(rvb[core].CurrAddr>rvb[core].EndAddr) rvb[core].CurrAddr=rvb[core].StartAddr;
- }
-
- return rvb[core].iLastRVBLeft;
- }
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-int MixREVERBRight(int core)
-{
- if(iUseReverb==1) // Neill's reverb:
- {
- int i=rvb[core].iLastRVBRight+(rvb[core].iRVBRight-rvb[core].iLastRVBRight)/2;
- rvb[core].iLastRVBRight=rvb[core].iRVBRight;
- return i; // -> just return the last right reverb val (little bit scaled by the previous right val)
- }
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-#endif
-
-/*
------------------------------------------------------------------------------
-PSX reverb hardware notes
-by Neill Corlett
------------------------------------------------------------------------------
-
-Yadda yadda disclaimer yadda probably not perfect yadda well it's okay anyway
-yadda yadda.
-
------------------------------------------------------------------------------
-
-Basics
-------
-
-- The reverb buffer is 22khz 16-bit mono PCM.
-- It starts at the reverb address given by 1DA2, extends to
- the end of sound RAM, and wraps back to the 1DA2 address.
-
-Setting the address at 1DA2 resets the current reverb work address.
-
-This work address ALWAYS increments every 1/22050 sec., regardless of
-whether reverb is enabled (bit 7 of 1DAA set).
-
-And the contents of the reverb buffer ALWAYS play, scaled by the
-"reverberation depth left/right" volumes (1D84/1D86).
-(which, by the way, appear to be scaled so 3FFF=approx. 1.0, 4000=-1.0)
-
------------------------------------------------------------------------------
-
-Register names
---------------
-
-These are probably not their real names.
-These are probably not even correct names.
-We will use them anyway, because we can.
-
-1DC0: FB_SRC_A (offset)
-1DC2: FB_SRC_B (offset)
-1DC4: IIR_ALPHA (coef.)
-1DC6: ACC_COEF_A (coef.)
-1DC8: ACC_COEF_B (coef.)
-1DCA: ACC_COEF_C (coef.)
-1DCC: ACC_COEF_D (coef.)
-1DCE: IIR_COEF (coef.)
-1DD0: FB_ALPHA (coef.)
-1DD2: FB_X (coef.)
-1DD4: IIR_DEST_A0 (offset)
-1DD6: IIR_DEST_A1 (offset)
-1DD8: ACC_SRC_A0 (offset)
-1DDA: ACC_SRC_A1 (offset)
-1DDC: ACC_SRC_B0 (offset)
-1DDE: ACC_SRC_B1 (offset)
-1DE0: IIR_SRC_A0 (offset)
-1DE2: IIR_SRC_A1 (offset)
-1DE4: IIR_DEST_B0 (offset)
-1DE6: IIR_DEST_B1 (offset)
-1DE8: ACC_SRC_C0 (offset)
-1DEA: ACC_SRC_C1 (offset)
-1DEC: ACC_SRC_D0 (offset)
-1DEE: ACC_SRC_D1 (offset)
-1DF0: IIR_SRC_B1 (offset)
-1DF2: IIR_SRC_B0 (offset)
-1DF4: MIX_DEST_A0 (offset)
-1DF6: MIX_DEST_A1 (offset)
-1DF8: MIX_DEST_B0 (offset)
-1DFA: MIX_DEST_B1 (offset)
-1DFC: IN_COEF_L (coef.)
-1DFE: IN_COEF_R (coef.)
-
-The coefficients are signed fractional values.
--32768 would be -1.0
- 32768 would be 1.0 (if it were possible... the highest is of course 32767)
-
-The offsets are (byte/8) offsets into the reverb buffer.
-i.e. you multiply them by 8, you get byte offsets.
-You can also think of them as (samples/4) offsets.
-They appear to be signed. They can be negative.
-None of the documented presets make them negative, though.
-
-Yes, 1DF0 and 1DF2 appear to be backwards. Not a typo.
-
------------------------------------------------------------------------------
-
-What it does
-------------
-
-We take all reverb sources:
-- regular channels that have the reverb bit on
-- cd and external sources, if their reverb bits are on
-and mix them into one stereo 44100hz signal.
-
-Lowpass/downsample that to 22050hz. The PSX uses a proper bandlimiting
-algorithm here, but I haven't figured out the hysterically exact specifics.
-I use an 8-tap filter with these coefficients, which are nice but probably
-not the real ones:
-
-0.037828187894
-0.157538631280
-0.321159685278
-0.449322115345
-0.449322115345
-0.321159685278
-0.157538631280
-0.037828187894
-
-So we have two input samples (INPUT_SAMPLE_L, INPUT_SAMPLE_R) every 22050hz.
-
-* IN MY EMULATION, I divide these by 2 to make it clip less.
- (and of course the L/R output coefficients are adjusted to compensate)
- The real thing appears to not do this.
-
-At every 22050hz tick:
-- If the reverb bit is enabled (bit 7 of 1DAA), execute the reverb
- steady-state algorithm described below
-- AFTERWARDS, retrieve the "wet out" L and R samples from the reverb buffer
- (This part may not be exactly right and I guessed at the coefs. TODO: check later.)
- L is: 0.333 * (buffer[MIX_DEST_A0] + buffer[MIX_DEST_B0])
- R is: 0.333 * (buffer[MIX_DEST_A1] + buffer[MIX_DEST_B1])
-- Advance the current buffer position by 1 sample
-
-The wet out L and R are then upsampled to 44100hz and played at the
-"reverberation depth left/right" (1D84/1D86) volume, independent of the main
-volume.
-
------------------------------------------------------------------------------
-
-Reverb steady-state
--------------------
-
-The reverb steady-state algorithm is fairly clever, and of course by
-"clever" I mean "batshit insane".
-
-buffer[x] is relative to the current buffer position, not the beginning of
-the buffer. Note that all buffer offsets must wrap around so they're
-contained within the reverb work area.
-
-Clipping is performed at the end... maybe also sooner, but definitely at
-the end.
-
-IIR_INPUT_A0 = buffer[IIR_SRC_A0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
-IIR_INPUT_A1 = buffer[IIR_SRC_A1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
-IIR_INPUT_B0 = buffer[IIR_SRC_B0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
-IIR_INPUT_B1 = buffer[IIR_SRC_B1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
-
-IIR_A0 = IIR_INPUT_A0 * IIR_ALPHA + buffer[IIR_DEST_A0] * (1.0 - IIR_ALPHA);
-IIR_A1 = IIR_INPUT_A1 * IIR_ALPHA + buffer[IIR_DEST_A1] * (1.0 - IIR_ALPHA);
-IIR_B0 = IIR_INPUT_B0 * IIR_ALPHA + buffer[IIR_DEST_B0] * (1.0 - IIR_ALPHA);
-IIR_B1 = IIR_INPUT_B1 * IIR_ALPHA + buffer[IIR_DEST_B1] * (1.0 - IIR_ALPHA);
-
-buffer[IIR_DEST_A0 + 1sample] = IIR_A0;
-buffer[IIR_DEST_A1 + 1sample] = IIR_A1;
-buffer[IIR_DEST_B0 + 1sample] = IIR_B0;
-buffer[IIR_DEST_B1 + 1sample] = IIR_B1;
-
-ACC0 = buffer[ACC_SRC_A0] * ACC_COEF_A +
- buffer[ACC_SRC_B0] * ACC_COEF_B +
- buffer[ACC_SRC_C0] * ACC_COEF_C +
- buffer[ACC_SRC_D0] * ACC_COEF_D;
-ACC1 = buffer[ACC_SRC_A1] * ACC_COEF_A +
- buffer[ACC_SRC_B1] * ACC_COEF_B +
- buffer[ACC_SRC_C1] * ACC_COEF_C +
- buffer[ACC_SRC_D1] * ACC_COEF_D;
-
-FB_A0 = buffer[MIX_DEST_A0 - FB_SRC_A];
-FB_A1 = buffer[MIX_DEST_A1 - FB_SRC_A];
-FB_B0 = buffer[MIX_DEST_B0 - FB_SRC_B];
-FB_B1 = buffer[MIX_DEST_B1 - FB_SRC_B];
-
-buffer[MIX_DEST_A0] = ACC0 - FB_A0 * FB_ALPHA;
-buffer[MIX_DEST_A1] = ACC1 - FB_A1 * FB_ALPHA;
-buffer[MIX_DEST_B0] = (FB_ALPHA * ACC0) - FB_A0 * (FB_ALPHA^0x8000) - FB_B0 * FB_X;
-buffer[MIX_DEST_B1] = (FB_ALPHA * ACC1) - FB_A1 * (FB_ALPHA^0x8000) - FB_B1 * FB_X;
-
------------------------------------------------------------------------------
-*/
-
diff --git a/src/psf/peops2/reverb.cc b/src/psf/peops2/reverb.cc
new file mode 100644
index 000000000000..068dc9575a3a
--- /dev/null
+++ b/src/psf/peops2/reverb.cc
@@ -0,0 +1,420 @@
+/***************************************************************************
+ reverb.c - description
+ -------------------
+ begin : Wed May 15 2002
+ copyright : (C) 2002 by Pete Bernert
+ email : BlackDove at addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+//*************************************************************************//
+// History of changes:
+//
+// 2004/04/04 - Pete
+// - changed to SPU2 functionality
+//
+// 2003/01/19 - Pete
+// - added Neill's reverb (see at the end of file)
+//
+// 2002/12/26 - Pete
+// - adjusted reverb handling
+//
+// 2002/08/14 - Pete
+// - added extra reverb
+//
+// 2002/05/15 - Pete
+// - generic cleanup for the Peops release
+//
+//*************************************************************************//
+
+#include "stdafx.h"
+
+#define _IN_REVERB
+
+// will be included from spu.c
+#ifdef _IN_SPU
+
+////////////////////////////////////////////////////////////////////////
+// globals
+////////////////////////////////////////////////////////////////////////
+
+// REVERB info and timing vars...
+
+int * sRVBPlay[2];
+int * sRVBEnd[2];
+int * sRVBStart[2];
+
+////////////////////////////////////////////////////////////////////////
+// START REVERB
+////////////////////////////////////////////////////////////////////////
+
+void StartREVERB(int ch)
+{
+ int core=ch/24;
+
+ if((s_chan[ch].bReverbL || s_chan[ch].bReverbR) && (spuCtrl2[core]&0x80)) // reverb possible?
+ {
+ if(iUseReverb==1) s_chan[ch].bRVBActive=1;
+ }
+ else s_chan[ch].bRVBActive=0; // else -> no reverb
+}
+
+////////////////////////////////////////////////////////////////////////
+// HELPER FOR NEILL'S REVERB: re-inits our reverb mixing buf
+////////////////////////////////////////////////////////////////////////
+
+static inline void InitREVERB(void)
+{
+ if(iUseReverb==1)
+ {
+ memset(sRVBStart[0],0,NSSIZE*2*4);
+ memset(sRVBStart[1],0,NSSIZE*2*4);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// STORE REVERB
+////////////////////////////////////////////////////////////////////////
+
+void StoreREVERB(int ch,int ns)
+{
+ int core=ch/24;
+
+ if(iUseReverb==0) return;
+ else
+ if(iUseReverb==1) // -------------------------------- // Neil's reverb
+ {
+ const int iRxl=(s_chan[ch].sval*s_chan[ch].iLeftVolume*s_chan[ch].bReverbL)/0x4000;
+ const int iRxr=(s_chan[ch].sval*s_chan[ch].iRightVolume*s_chan[ch].bReverbR)/0x4000;
+
+ ns<<=1;
+
+ *(sRVBStart[core]+ns) +=iRxl; // -> we mix all active reverb channels into an extra buffer
+ *(sRVBStart[core]+ns+1)+=iRxr;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+static inline int g_buffer(int iOff,int core) // get_buffer content helper: takes care about wraps
+{
+ short * p=(short *)spuMem;
+ iOff=(iOff)+rvb[core].CurrAddr;
+ while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
+ while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
+ return (int)*(p+iOff);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+static inline void s_buffer(int iOff,int iVal,int core) // set_buffer content helper: takes care about wraps and clipping
+{
+ short * p=(short *)spuMem;
+ iOff=(iOff)+rvb[core].CurrAddr;
+ while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
+ while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
+ if(iVal<-32768L) iVal=-32768L;if(iVal>32767L) iVal=32767L;
+ *(p+iOff)=(short)iVal;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+static inline void s_buffer1(int iOff,int iVal,int core) // set_buffer (+1 sample) content helper: takes care about wraps and clipping
+{
+ short * p=(short *)spuMem;
+ iOff=(iOff)+rvb[core].CurrAddr+1;
+ while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
+ while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
+ if(iVal<-32768L) iVal=-32768L;if(iVal>32767L) iVal=32767L;
+ *(p+iOff)=(short)iVal;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+int MixREVERBLeft(int ns,int core)
+{
+ if(iUseReverb==1)
+ {
+ if(!rvb[core].StartAddr || !rvb[core].EndAddr ||
+ rvb[core].StartAddr>=rvb[core].EndAddr) // reverb is off
+ {
+ rvb[core].iLastRVBLeft=rvb[core].iLastRVBRight=rvb[core].iRVBLeft=rvb[core].iRVBRight=0;
+ return 0;
+ }
+
+ rvb[core].iCnt++;
+
+ if(rvb[core].iCnt&1) // we work on every second left value: downsample to 22 khz
+ {
+ if((spuCtrl2[core]&0x80)) // -> reverb on? oki
+ {
+ int ACC0,ACC1,FB_A0,FB_A1,FB_B0,FB_B1;
+
+ const int INPUT_SAMPLE_L=*(sRVBStart[core]+(ns<<1));
+ const int INPUT_SAMPLE_R=*(sRVBStart[core]+(ns<<1)+1);
+
+ const int IIR_INPUT_A0 = (g_buffer(rvb[core].IIR_SRC_A0,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_L * rvb[core].IN_COEF_L)/32768L;
+ const int IIR_INPUT_A1 = (g_buffer(rvb[core].IIR_SRC_A1,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_R * rvb[core].IN_COEF_R)/32768L;
+ const int IIR_INPUT_B0 = (g_buffer(rvb[core].IIR_SRC_B0,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_L * rvb[core].IN_COEF_L)/32768L;
+ const int IIR_INPUT_B1 = (g_buffer(rvb[core].IIR_SRC_B1,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_R * rvb[core].IN_COEF_R)/32768L;
+
+ const int IIR_A0 = (IIR_INPUT_A0 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_A0,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
+ const int IIR_A1 = (IIR_INPUT_A1 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_A1,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
+ const int IIR_B0 = (IIR_INPUT_B0 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_B0,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
+ const int IIR_B1 = (IIR_INPUT_B1 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_B1,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
+
+ s_buffer1(rvb[core].IIR_DEST_A0, IIR_A0,core);
+ s_buffer1(rvb[core].IIR_DEST_A1, IIR_A1,core);
+ s_buffer1(rvb[core].IIR_DEST_B0, IIR_B0,core);
+ s_buffer1(rvb[core].IIR_DEST_B1, IIR_B1,core);
+
+ ACC0 = (g_buffer(rvb[core].ACC_SRC_A0,core) * rvb[core].ACC_COEF_A)/32768L +
+ (g_buffer(rvb[core].ACC_SRC_B0,core) * rvb[core].ACC_COEF_B)/32768L +
+ (g_buffer(rvb[core].ACC_SRC_C0,core) * rvb[core].ACC_COEF_C)/32768L +
+ (g_buffer(rvb[core].ACC_SRC_D0,core) * rvb[core].ACC_COEF_D)/32768L;
+ ACC1 = (g_buffer(rvb[core].ACC_SRC_A1,core) * rvb[core].ACC_COEF_A)/32768L +
+ (g_buffer(rvb[core].ACC_SRC_B1,core) * rvb[core].ACC_COEF_B)/32768L +
+ (g_buffer(rvb[core].ACC_SRC_C1,core) * rvb[core].ACC_COEF_C)/32768L +
+ (g_buffer(rvb[core].ACC_SRC_D1,core) * rvb[core].ACC_COEF_D)/32768L;
+
+ FB_A0 = g_buffer(rvb[core].MIX_DEST_A0 - rvb[core].FB_SRC_A,core);
+ FB_A1 = g_buffer(rvb[core].MIX_DEST_A1 - rvb[core].FB_SRC_A,core);
+ FB_B0 = g_buffer(rvb[core].MIX_DEST_B0 - rvb[core].FB_SRC_B,core);
+ FB_B1 = g_buffer(rvb[core].MIX_DEST_B1 - rvb[core].FB_SRC_B,core);
+
+ s_buffer(rvb[core].MIX_DEST_A0, ACC0 - (FB_A0 * rvb[core].FB_ALPHA)/32768L,core);
+ s_buffer(rvb[core].MIX_DEST_A1, ACC1 - (FB_A1 * rvb[core].FB_ALPHA)/32768L,core);
+
+ s_buffer(rvb[core].MIX_DEST_B0, (rvb[core].FB_ALPHA * ACC0)/32768L - (FB_A0 * (int)(rvb[core].FB_ALPHA^0xFFFF8000))/32768L - (FB_B0 * rvb[core].FB_X)/32768L,core);
+ s_buffer(rvb[core].MIX_DEST_B1, (rvb[core].FB_ALPHA * ACC1)/32768L - (FB_A1 * (int)(rvb[core].FB_ALPHA^0xFFFF8000))/32768L - (FB_B1 * rvb[core].FB_X)/32768L,core);
+
+ rvb[core].iLastRVBLeft = rvb[core].iRVBLeft;
+ rvb[core].iLastRVBRight = rvb[core].iRVBRight;
+
+ rvb[core].iRVBLeft = (g_buffer(rvb[core].MIX_DEST_A0,core)+g_buffer(rvb[core].MIX_DEST_B0,core))/3;
+ rvb[core].iRVBRight = (g_buffer(rvb[core].MIX_DEST_A1,core)+g_buffer(rvb[core].MIX_DEST_B1,core))/3;
+
+ rvb[core].iRVBLeft = (rvb[core].iRVBLeft * rvb[core].VolLeft) / 0x4000;
+ rvb[core].iRVBRight = (rvb[core].iRVBRight * rvb[core].VolRight) / 0x4000;
+
+ rvb[core].CurrAddr++;
+ if(rvb[core].CurrAddr>rvb[core].EndAddr) rvb[core].CurrAddr=rvb[core].StartAddr;
+
+ return rvb[core].iLastRVBLeft+(rvb[core].iRVBLeft-rvb[core].iLastRVBLeft)/2;
+ }
+ else // -> reverb off
+ {
+ rvb[core].iLastRVBLeft=rvb[core].iLastRVBRight=rvb[core].iRVBLeft=rvb[core].iRVBRight=0;
+ }
+
+ rvb[core].CurrAddr++;
+ if(rvb[core].CurrAddr>rvb[core].EndAddr) rvb[core].CurrAddr=rvb[core].StartAddr;
+ }
+
+ return rvb[core].iLastRVBLeft;
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+int MixREVERBRight(int core)
+{
+ if(iUseReverb==1) // Neill's reverb:
+ {
+ int i=rvb[core].iLastRVBRight+(rvb[core].iRVBRight-rvb[core].iLastRVBRight)/2;
+ rvb[core].iLastRVBRight=rvb[core].iRVBRight;
+ return i; // -> just return the last right reverb val (little bit scaled by the previous right val)
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
+/*
+-----------------------------------------------------------------------------
+PSX reverb hardware notes
+by Neill Corlett
+-----------------------------------------------------------------------------
+
+Yadda yadda disclaimer yadda probably not perfect yadda well it's okay anyway
+yadda yadda.
+
+-----------------------------------------------------------------------------
+
+Basics
+------
+
+- The reverb buffer is 22khz 16-bit mono PCM.
+- It starts at the reverb address given by 1DA2, extends to
+ the end of sound RAM, and wraps back to the 1DA2 address.
+
+Setting the address at 1DA2 resets the current reverb work address.
+
+This work address ALWAYS increments every 1/22050 sec., regardless of
+whether reverb is enabled (bit 7 of 1DAA set).
+
+And the contents of the reverb buffer ALWAYS play, scaled by the
+"reverberation depth left/right" volumes (1D84/1D86).
+(which, by the way, appear to be scaled so 3FFF=approx. 1.0, 4000=-1.0)
+
+-----------------------------------------------------------------------------
+
+Register names
+--------------
+
+These are probably not their real names.
+These are probably not even correct names.
+We will use them anyway, because we can.
+
+1DC0: FB_SRC_A (offset)
+1DC2: FB_SRC_B (offset)
+1DC4: IIR_ALPHA (coef.)
+1DC6: ACC_COEF_A (coef.)
+1DC8: ACC_COEF_B (coef.)
+1DCA: ACC_COEF_C (coef.)
+1DCC: ACC_COEF_D (coef.)
+1DCE: IIR_COEF (coef.)
+1DD0: FB_ALPHA (coef.)
+1DD2: FB_X (coef.)
+1DD4: IIR_DEST_A0 (offset)
+1DD6: IIR_DEST_A1 (offset)
+1DD8: ACC_SRC_A0 (offset)
+1DDA: ACC_SRC_A1 (offset)
+1DDC: ACC_SRC_B0 (offset)
+1DDE: ACC_SRC_B1 (offset)
+1DE0: IIR_SRC_A0 (offset)
+1DE2: IIR_SRC_A1 (offset)
+1DE4: IIR_DEST_B0 (offset)
+1DE6: IIR_DEST_B1 (offset)
+1DE8: ACC_SRC_C0 (offset)
+1DEA: ACC_SRC_C1 (offset)
+1DEC: ACC_SRC_D0 (offset)
+1DEE: ACC_SRC_D1 (offset)
+1DF0: IIR_SRC_B1 (offset)
+1DF2: IIR_SRC_B0 (offset)
+1DF4: MIX_DEST_A0 (offset)
+1DF6: MIX_DEST_A1 (offset)
+1DF8: MIX_DEST_B0 (offset)
+1DFA: MIX_DEST_B1 (offset)
+1DFC: IN_COEF_L (coef.)
+1DFE: IN_COEF_R (coef.)
+
+The coefficients are signed fractional values.
+-32768 would be -1.0
+ 32768 would be 1.0 (if it were possible... the highest is of course 32767)
+
+The offsets are (byte/8) offsets into the reverb buffer.
+i.e. you multiply them by 8, you get byte offsets.
+You can also think of them as (samples/4) offsets.
+They appear to be signed. They can be negative.
+None of the documented presets make them negative, though.
+
+Yes, 1DF0 and 1DF2 appear to be backwards. Not a typo.
+
+-----------------------------------------------------------------------------
+
+What it does
+------------
+
+We take all reverb sources:
+- regular channels that have the reverb bit on
+- cd and external sources, if their reverb bits are on
+and mix them into one stereo 44100hz signal.
+
+Lowpass/downsample that to 22050hz. The PSX uses a proper bandlimiting
+algorithm here, but I haven't figured out the hysterically exact specifics.
+I use an 8-tap filter with these coefficients, which are nice but probably
+not the real ones:
+
+0.037828187894
+0.157538631280
+0.321159685278
+0.449322115345
+0.449322115345
+0.321159685278
+0.157538631280
+0.037828187894
+
+So we have two input samples (INPUT_SAMPLE_L, INPUT_SAMPLE_R) every 22050hz.
+
+* IN MY EMULATION, I divide these by 2 to make it clip less.
+ (and of course the L/R output coefficients are adjusted to compensate)
+ The real thing appears to not do this.
+
+At every 22050hz tick:
+- If the reverb bit is enabled (bit 7 of 1DAA), execute the reverb
+ steady-state algorithm described below
+- AFTERWARDS, retrieve the "wet out" L and R samples from the reverb buffer
+ (This part may not be exactly right and I guessed at the coefs. TODO: check later.)
+ L is: 0.333 * (buffer[MIX_DEST_A0] + buffer[MIX_DEST_B0])
+ R is: 0.333 * (buffer[MIX_DEST_A1] + buffer[MIX_DEST_B1])
+- Advance the current buffer position by 1 sample
+
+The wet out L and R are then upsampled to 44100hz and played at the
+"reverberation depth left/right" (1D84/1D86) volume, independent of the main
+volume.
+
+-----------------------------------------------------------------------------
+
+Reverb steady-state
+-------------------
+
+The reverb steady-state algorithm is fairly clever, and of course by
+"clever" I mean "batshit insane".
+
+buffer[x] is relative to the current buffer position, not the beginning of
+the buffer. Note that all buffer offsets must wrap around so they're
+contained within the reverb work area.
+
+Clipping is performed at the end... maybe also sooner, but definitely at
+the end.
+
+IIR_INPUT_A0 = buffer[IIR_SRC_A0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
+IIR_INPUT_A1 = buffer[IIR_SRC_A1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
+IIR_INPUT_B0 = buffer[IIR_SRC_B0] * IIR_COEF + INPUT_SAMPLE_L * IN_COEF_L;
+IIR_INPUT_B1 = buffer[IIR_SRC_B1] * IIR_COEF + INPUT_SAMPLE_R * IN_COEF_R;
+
+IIR_A0 = IIR_INPUT_A0 * IIR_ALPHA + buffer[IIR_DEST_A0] * (1.0 - IIR_ALPHA);
+IIR_A1 = IIR_INPUT_A1 * IIR_ALPHA + buffer[IIR_DEST_A1] * (1.0 - IIR_ALPHA);
+IIR_B0 = IIR_INPUT_B0 * IIR_ALPHA + buffer[IIR_DEST_B0] * (1.0 - IIR_ALPHA);
+IIR_B1 = IIR_INPUT_B1 * IIR_ALPHA + buffer[IIR_DEST_B1] * (1.0 - IIR_ALPHA);
+
+buffer[IIR_DEST_A0 + 1sample] = IIR_A0;
+buffer[IIR_DEST_A1 + 1sample] = IIR_A1;
+buffer[IIR_DEST_B0 + 1sample] = IIR_B0;
+buffer[IIR_DEST_B1 + 1sample] = IIR_B1;
+
+ACC0 = buffer[ACC_SRC_A0] * ACC_COEF_A +
+ buffer[ACC_SRC_B0] * ACC_COEF_B +
+ buffer[ACC_SRC_C0] * ACC_COEF_C +
+ buffer[ACC_SRC_D0] * ACC_COEF_D;
+ACC1 = buffer[ACC_SRC_A1] * ACC_COEF_A +
+ buffer[ACC_SRC_B1] * ACC_COEF_B +
+ buffer[ACC_SRC_C1] * ACC_COEF_C +
+ buffer[ACC_SRC_D1] * ACC_COEF_D;
+
+FB_A0 = buffer[MIX_DEST_A0 - FB_SRC_A];
+FB_A1 = buffer[MIX_DEST_A1 - FB_SRC_A];
+FB_B0 = buffer[MIX_DEST_B0 - FB_SRC_B];
+FB_B1 = buffer[MIX_DEST_B1 - FB_SRC_B];
+
+buffer[MIX_DEST_A0] = ACC0 - FB_A0 * FB_ALPHA;
+buffer[MIX_DEST_A1] = ACC1 - FB_A1 * FB_ALPHA;
+buffer[MIX_DEST_B0] = (FB_ALPHA * ACC0) - FB_A0 * (FB_ALPHA^0x8000) - FB_B0 * FB_X;
+buffer[MIX_DEST_B1] = (FB_ALPHA * ACC1) - FB_A1 * (FB_ALPHA^0x8000) - FB_B1 * FB_X;
+
+-----------------------------------------------------------------------------
+*/
+
diff --git a/src/psf/peops2/spu.c b/src/psf/peops2/spu.c
deleted file mode 100644
index 958d5c0dfb22..000000000000
--- a/src/psf/peops2/spu.c
+++ /dev/null
@@ -1,1036 +0,0 @@
-/***************************************************************************
- spu.c - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove at addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-//*************************************************************************//
-// History of changes:
-//
-// 2005/08/29 - Pete
-// - changed to 48Khz output
-//
-// 2004/12/25 - Pete
-// - inc'd version for pcsx2-0.7
-//
-// 2004/04/18 - Pete
-// - changed all kind of things in the plugin
-//
-// 2004/04/04 - Pete
-// - changed plugin to emulate PS2 spu
-//
-// 2003/04/07 - Eric
-// - adjusted cubic interpolation algorithm
-//
-// 2003/03/16 - Eric
-// - added cubic interpolation
-//
-// 2003/03/01 - linuzappz
-// - libraryName changes using ALSA
-//
-// 2003/02/28 - Pete
-// - added option for type of interpolation
-// - adjusted spu irqs again (Thousant Arms, Valkyrie Profile)
-// - added MONO support for MSWindows DirectSound
-//
-// 2003/02/20 - kode54
-// - amended interpolation code, goto GOON could skip initialization of gpos and cause segfault
-//
-// 2003/02/19 - kode54
-// - moved SPU IRQ handler and changed sample flag processing
-//
-// 2003/02/18 - kode54
-// - moved ADSR calculation outside of the sample decode loop, somehow I doubt that
-// ADSR timing is relative to the frequency at which a sample is played... I guess
-// this remains to be seen, and I don't know whether ADSR is applied to noise channels...
-//
-// 2003/02/09 - kode54
-// - one-shot samples now process the end block before stopping
-// - in light of removing fmod hack, now processing ADSR on frequency channel as well
-//
-// 2003/02/08 - kode54
-// - replaced easy interpolation with gaussian
-// - removed fmod averaging hack
-// - changed .sinc to be updated from .iRawPitch, no idea why it wasn't done this way already (<- Pete: because I sometimes fail to see the obvious, haharhar :)
-//
-// 2003/02/08 - linuzappz
-// - small bugfix for one usleep that was 1 instead of 1000
-// - added iDisStereo for no stereo (Linux)
-//
-// 2003/01/22 - Pete
-// - added easy interpolation & small noise adjustments
-//
-// 2003/01/19 - Pete
-// - added Neill's reverb
-//
-// 2003/01/12 - Pete
-// - added recording window handlers
-//
-// 2003/01/06 - Pete
-// - added Neill's ADSR timings
-//
-// 2002/12/28 - Pete
-// - adjusted spu irq handling, fmod handling and loop handling
-//
-// 2002/08/14 - Pete
-// - added extra reverb
-//
-// 2002/06/08 - linuzappz
-// - SPUupdate changed for SPUasync
-//
-// 2002/05/15 - Pete
-// - generic cleanup for the Peops release
-//
-//*************************************************************************//
-
-#include "stdafx.h"
-
-#define _IN_SPU
-
-#include "../peops2/externals.h"
-#include "../peops2/regs.h"
-#include "../peops2/dma.h"
-
-////////////////////////////////////////////////////////////////////////
-// globals
-////////////////////////////////////////////////////////////////////////
-
-// psx buffer / addresses
-
-unsigned short regArea[32*1024];
-unsigned short spuMem[1*1024*1024];
-unsigned char * spuMemC;
-unsigned char * pSpuIrq[2];
-unsigned char * pSpuBuffer;
-
-// user settings
-
-int iUseXA=0;
-int iXAPitch=1;
-int iUseTimer=2;
-int iSPUIRQWait=1;
-int iDebugMode=0;
-int iRecordMode=0;
-int iUseReverb=1;
-int iUseInterpolation=2;
-
-// MAIN infos struct for each channel
-
-SPUCHAN s_chan[MAXCHAN+1]; // channel + 1 infos (1 is security for fmod handling)
-REVERBInfo rvb[2];
-
-unsigned long dwNoiseVal=1; // global noise generator
-
-unsigned short spuCtrl2[2]; // some vars to store psx reg infos
-unsigned short spuStat2[2];
-unsigned long spuIrq2[2];
-unsigned long spuAddr2[2]; // address into spu mem
-unsigned long spuRvbAddr2[2];
-unsigned long spuRvbAEnd2[2];
-int bEndThread=0; // thread handlers
-int bThreadEnded=0;
-int bSpuInit=0;
-int bSPUIsOpen=0;
-
-unsigned long dwNewChannel2[2]; // flags for faster testing, if new channel starts
-unsigned long dwEndChannel2[2];
-
-// UNUSED IN PS2 YET
-void (CALLBACK *irqCallback)(void)=0; // func of main emu, called on spu irq
-void (CALLBACK *cddavCallback)(unsigned short,unsigned short)=0;
-
-// certain globals (were local before, but with the new timeproc I need em global)
-
-const int f[5][2] = { { 0, 0 },
- { 60, 0 },
- { 115, -52 },
- { 98, -55 },
- { 122, -60 } };
-int SSumR[NSSIZE];
-int SSumL[NSSIZE];
-int iCycle=0;
-short * pS;
-
-static int lastch=-1; // last channel processed on spu irq in timer mode
-static int iSecureStart=0; // secure start counter
-
-extern void psf2_update(unsigned char *samples, long lBytes, void *data);
-
-////////////////////////////////////////////////////////////////////////
-// CODE AREA
-////////////////////////////////////////////////////////////////////////
-
-// dirty inline func includes
-
-#include "reverb.c"
-#include "adsr.c"
-
-////////////////////////////////////////////////////////////////////////
-// helpers for simple interpolation
-
-//
-// easy interpolation on upsampling, no special filter, just "Pete's common sense" tm
-//
-// instead of having n equal sample values in a row like:
-// ____
-// |____
-//
-// we compare the current delta change with the next delta change.
-//
-// if curr_delta is positive,
-//
-// - and next delta is smaller (or changing direction):
-// \.
-// -__
-//
-// - and next delta significant (at least twice) bigger:
-// --_
-// \.
-//
-// - and next delta is nearly same:
-// \.
-// \.
-//
-//
-// if curr_delta is negative,
-//
-// - and next delta is smaller (or changing direction):
-// _--
-// /
-//
-// - and next delta significant (at least twice) bigger:
-// /
-// __-
-//
-// - and next delta is nearly same:
-// /
-// /
-//
-
-
-static inline void InterpolateUp(int ch)
-{
- if(s_chan[ch].SB[32]==1) // flag == 1? calc step and set flag... and don't change the value in this pass
- {
- const int id1=s_chan[ch].SB[30]-s_chan[ch].SB[29]; // curr delta to next val
- const int id2=s_chan[ch].SB[31]-s_chan[ch].SB[30]; // and next delta to next-next val :)
-
- s_chan[ch].SB[32]=0;
-
- if(id1>0) // curr delta positive
- {
- if(id2<id1)
- {s_chan[ch].SB[28]=id1;s_chan[ch].SB[32]=2;}
- else
- if(id2<(id1<<1))
- s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x10000L;
- else
- s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x20000L;
- }
- else // curr delta negative
- {
- if(id2>id1)
- {s_chan[ch].SB[28]=id1;s_chan[ch].SB[32]=2;}
- else
- if(id2>(id1<<1))
- s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x10000L;
- else
- s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x20000L;
- }
- }
- else
- if(s_chan[ch].SB[32]==2) // flag 1: calc step and set flag... and don't change the value in this pass
- {
- s_chan[ch].SB[32]=0;
-
- s_chan[ch].SB[28]=(s_chan[ch].SB[28]*s_chan[ch].sinc)/0x20000L;
- if(s_chan[ch].sinc<=0x8000)
- s_chan[ch].SB[29]=s_chan[ch].SB[30]-(s_chan[ch].SB[28]*((0x10000/s_chan[ch].sinc)-1));
- else s_chan[ch].SB[29]+=s_chan[ch].SB[28];
- }
- else // no flags? add bigger val (if possible), calc smaller step, set flag1
- s_chan[ch].SB[29]+=s_chan[ch].SB[28];
-}
-
-//
-// even easier interpolation on downsampling, also no special filter, again just "Pete's common sense" tm
-//
-
-static inline void InterpolateDown(int ch)
-{
- if(s_chan[ch].sinc>=0x20000L) // we would skip at least one val?
- {
- s_chan[ch].SB[29]+=(s_chan[ch].SB[30]-s_chan[ch].SB[29])/2; // add easy weight
- if(s_chan[ch].sinc>=0x30000L) // we would skip even more vals?
- s_chan[ch].SB[29]+=(s_chan[ch].SB[31]-s_chan[ch].SB[30])/2;// add additional next weight
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// helpers for gauss interpolation
-
-#define gval0 (((short*)(&s_chan[ch].SB[29]))[gpos])
-#define gval(x) (((short*)(&s_chan[ch].SB[29]))[(gpos+x)&3])
-
-#include "gauss_i.h"
-
-////////////////////////////////////////////////////////////////////////
-
-//#include "xa.c"
-
-////////////////////////////////////////////////////////////////////////
-// START SOUND... called by main thread to setup a new sound on a channel
-////////////////////////////////////////////////////////////////////////
-
-static inline void StartSound(int ch)
-{
- dwNewChannel2[ch/24]&=~(1<<(ch%24)); // clear new channel bit
- dwEndChannel2[ch/24]&=~(1<<(ch%24)); // clear end channel bit
-
- StartADSR(ch);
- StartREVERB(ch);
-
- s_chan[ch].pCurr=s_chan[ch].pStart; // set sample start
-
- s_chan[ch].s_1=0; // init mixing vars
- s_chan[ch].s_2=0;
- s_chan[ch].iSBPos=28;
-
- s_chan[ch].bNew=0; // init channel flags
- s_chan[ch].bStop=0;
- s_chan[ch].bOn=1;
-
- s_chan[ch].SB[29]=0; // init our interpolation helpers
- s_chan[ch].SB[30]=0;
-
- if(iUseInterpolation>=2) // gauss interpolation?
- {s_chan[ch].spos=0x30000L;s_chan[ch].SB[28]=0;} // -> start with more decoding
- else {s_chan[ch].spos=0x10000L;s_chan[ch].SB[31]=0;} // -> no/simple interpolation starts with one 44100 decoding
-}
-
-////////////////////////////////////////////////////////////////////////
-// MAIN SPU FUNCTION
-// here is the main job handler... thread, timer or direct func call
-// basically the whole sound processing is done in this fat func!
-////////////////////////////////////////////////////////////////////////
-
-static u32 sampcount;
-static u32 decaybegin;
-static u32 decayend;
-
-static u32 seektime;
-int psf2_seek(u32 t)
-{
- seektime=t*441/10;
- if(seektime>sampcount) return(1);
- return(0);
-}
-
-// Counting to 65536 results in full volume offage.
-void setlength2(s32 stop, s32 fade)
-{
- seektime = 0;
- if(stop==~0)
- {
- decaybegin=~0;
- }
- else
- {
- stop=(stop*441)/10;
- fade=(fade*441)/10;
-
- decaybegin=stop;
- decayend=stop+fade;
- }
-}
-// 5 ms waiting phase, if buffer is full and no new sound has to get started
-// .. can be made smaller (smallest val: 1 ms), but bigger waits give
-// better performance
-
-#define PAUSE_W 5
-#define PAUSE_L 5000
-
-////////////////////////////////////////////////////////////////////////
-
-int iSpuAsyncWait=0;
-
-static void *MAINThread(int samp2run, void *data)
-{
- int s_1,s_2,fa;
- unsigned char * start;unsigned int nSample;
- int ch,predict_nr,shift_factor,flags,d,d2,s;
- int gpos,bIRQReturn=0;
-
-// while(!bEndThread) // until we are shutting down
- {
- //--------------------------------------------------//
- // ok, at the beginning we are looking if there is
- // enuff free place in the dsound/oss buffer to
- // fill in new data, or if there is a new channel to start.
- // if not, we wait (thread) or return (timer/spuasync)
- // until enuff free place is available/a new channel gets
- // started
-
- if(dwNewChannel2[0] || dwNewChannel2[1]) // new channel should start immedately?
- { // (at least one bit 0 ... MAXCHANNEL is set?)
- iSecureStart++; // -> set iSecure
- if(iSecureStart>5) iSecureStart=0; // (if it is set 5 times - that means on 5 tries a new samples has been started - in a row, we will reset it, to give the sound update a chance)
- }
- else iSecureStart=0; // 0: no new channel should start
-
-/* if (!iSecureStart)
- {
- iSecureStart=0; // reset secure
- return;
- }*/
-
-#if 0
- while(!iSecureStart && !bEndThread) // && // no new start? no thread end?
-// (SoundGetBytesBuffered()>TESTSIZE)) // and still enuff data in sound buffer?
- {
- iSecureStart=0; // reset secure
-
- if(iUseTimer) return 0; // linux no-thread mode? bye
-
- if(dwNewChannel2[0] || dwNewChannel2[1])
- iSecureStart=1; // if a new channel kicks in (or, of course, sound buffer runs low), we will leave the loop
- }
-#endif
-
- //--------------------------------------------------// continue from irq handling in timer mode?
-
- if(lastch>=0) // will be -1 if no continue is pending
- {
- ch=lastch; lastch=-1; // -> setup all kind of vars to continue
- goto GOON; // -> directly jump to the continue point
- }
-
- //--------------------------------------------------//
- //- main channel loop -//
- //--------------------------------------------------//
- {
- for(ch=0;ch<MAXCHAN;ch++) // loop em all... we will collect 1 ms of sound of each playing channel
- {
- if(s_chan[ch].bNew) StartSound(ch); // start new sound
- if(!s_chan[ch].bOn) continue; // channel not playing? next
-
- if(s_chan[ch].iActFreq!=s_chan[ch].iUsedFreq) // new psx frequency?
- {
- s_chan[ch].iUsedFreq=s_chan[ch].iActFreq; // -> take it and calc steps
- s_chan[ch].sinc=s_chan[ch].iRawPitch<<4;
- if(!s_chan[ch].sinc) s_chan[ch].sinc=1;
- if(iUseInterpolation==1) s_chan[ch].SB[32]=1; // -> freq change in simle imterpolation mode: set flag
- }
-// ns=0;
-// while(ns<NSSIZE) // loop until 1 ms of data is reached
- {
- while(s_chan[ch].spos>=0x10000L)
- {
- if(s_chan[ch].iSBPos==28) // 28 reached?
- {
- start=s_chan[ch].pCurr; // set up the current pos
-
- if (start == (unsigned char*)-1) // special "stop" sign
- {
- s_chan[ch].bOn=0; // -> turn everything off
- s_chan[ch].ADSRX.lVolume=0;
- s_chan[ch].ADSRX.EnvelopeVol=0;
- goto ENDX; // -> and done for this channel
- }
-
- s_chan[ch].iSBPos=0;
-
- //////////////////////////////////////////// spu irq handler here? mmm... do it later
-
- s_1=s_chan[ch].s_1;
- s_2=s_chan[ch].s_2;
-
- predict_nr=(int)*start;start++;
- shift_factor=predict_nr&0xf;
- predict_nr >>= 4;
- flags=(int)*start;start++;
-
- // -------------------------------------- //
-
- for (nSample=0;nSample<28;start++)
- {
- d=(int)*start;
- s=((d&0xf)<<12);
- if(s&0x8000) s|=0xffff0000;
-
- fa=(s >> shift_factor);
- fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6);
- s_2=s_1;s_1=fa;
- s=((d & 0xf0) << 8);
-
- s_chan[ch].SB[nSample++]=fa;
-
- if(s&0x8000) s|=0xffff0000;
- fa=(s>>shift_factor);
- fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6);
- s_2=s_1;s_1=fa;
-
- s_chan[ch].SB[nSample++]=fa;
- }
-
- //////////////////////////////////////////// irq check
-
- if(spuCtrl2[ch/24]&0x40) // some irq active?
- {
- if((pSpuIrq[ch/24] > start-16 && // irq address reached?
- pSpuIrq[ch/24] <= start) ||
- ((flags&1) && // special: irq on looping addr, when stop/loop flag is set
- (pSpuIrq[ch/24] > s_chan[ch].pLoop-16 &&
- pSpuIrq[ch/24] <= s_chan[ch].pLoop)))
- {
- s_chan[ch].iIrqDone=1; // -> debug flag
-
- if(irqCallback) irqCallback(); // -> call main emu (not supported in SPU2 right now)
- else
- {
- if(ch<24) InterruptDMA4(); // -> let's see what is happening if we call our irqs instead ;)
- else InterruptDMA7();
- }
-
- if(iSPUIRQWait) // -> option: wait after irq for main emu
- {
- iSpuAsyncWait=1;
- bIRQReturn=1;
- }
- }
- }
-
- //////////////////////////////////////////// flag handler
-
- if((flags&4) && (!s_chan[ch].bIgnoreLoop))
- s_chan[ch].pLoop=start-16; // loop adress
-
- if(flags&1) // 1: stop/loop
- {
- dwEndChannel2[ch/24]|=(1<<(ch%24));
-
- // We play this block out first...
- //if(!(flags&2)|| s_chan[ch].pLoop==NULL)
- // 1+2: do loop... otherwise: stop
- if(flags!=3 || s_chan[ch].pLoop==NULL) // PETE: if we don't check exactly for 3, loop hang ups will happen (DQ4, for example)
- { // and checking if pLoop is set avoids crashes, yeah
- start = (unsigned char*)-1;
- }
- else
- {
- start = s_chan[ch].pLoop;
- }
- }
-
- s_chan[ch].pCurr=start; // store values for next cycle
- s_chan[ch].s_1=s_1;
- s_chan[ch].s_2=s_2;
-
- ////////////////////////////////////////////
-
- if(bIRQReturn) // special return for "spu irq - wait for cpu action"
- {
- bIRQReturn=0;
- {
- lastch=ch;
-// lastns=ns; // changemeback
-
- return NULL;
- }
- }
-
- ////////////////////////////////////////////
-
-GOON: ;
-
- }
-
- fa=s_chan[ch].SB[s_chan[ch].iSBPos++]; // get sample data
-
-// if((spuCtrl2[ch/24]&0x4000)==0) fa=0; // muted?
-// else // else adjust
- {
- if(fa>32767L) fa=32767L;
- if(fa<-32767L) fa=-32767L;
- }
-
- if(iUseInterpolation>=2) // gauss/cubic interpolation
- {
- gpos = s_chan[ch].SB[28];
- gval0 = fa;
- gpos = (gpos+1) & 3;
- s_chan[ch].SB[28] = gpos;
- }
- else
- if(iUseInterpolation==1) // simple interpolation
- {
- s_chan[ch].SB[28] = 0;
- s_chan[ch].SB[29] = s_chan[ch].SB[30]; // -> helpers for simple linear interpolation: delay real val for two slots, and calc the two deltas, for a 'look at the future behaviour'
- s_chan[ch].SB[30] = s_chan[ch].SB[31];
- s_chan[ch].SB[31] = fa;
- s_chan[ch].SB[32] = 1; // -> flag: calc new interolation
- }
- else s_chan[ch].SB[29]=fa; // no interpolation
-
- s_chan[ch].spos -= 0x10000L;
- }
-
- ////////////////////////////////////////////////
- // noise handler... just produces some noise data
- // surely wrong... and no noise frequency (spuCtrl&0x3f00) will be used...
- // and sometimes the noise will be used as fmod modulation... pfff
-
- if(s_chan[ch].bNoise)
- {
- if((dwNoiseVal<<=1)&0x80000000L)
- {
- dwNoiseVal^=0x0040001L;
- fa=((dwNoiseVal>>2)&0x7fff);
- fa=-fa;
- }
- else fa=(dwNoiseVal>>2)&0x7fff;
-
- // mmm... depending on the noise freq we allow bigger/smaller changes to the previous val
- fa=s_chan[ch].iOldNoise+((fa-s_chan[ch].iOldNoise)/((0x001f-((spuCtrl2[ch/24]&0x3f00)>>9))+1));
- if(fa>32767L) fa=32767L;
- if(fa<-32767L) fa=-32767L;
- s_chan[ch].iOldNoise=fa;
-
- if(iUseInterpolation<2) // no gauss/cubic interpolation?
- s_chan[ch].SB[29] = fa; // -> store noise val in "current sample" slot
- } //----------------------------------------
- else // NO NOISE (NORMAL SAMPLE DATA) HERE
- {//------------------------------------------//
- if(iUseInterpolation==3) // cubic interpolation
- {
- long xd;
- xd = ((s_chan[ch].spos) >> 1)+1;
- gpos = s_chan[ch].SB[28];
-
- fa = gval(3) - 3*gval(2) + 3*gval(1) - gval0;
- fa *= (xd - (2<<15)) / 6;
- fa >>= 15;
- fa += gval(2) - gval(1) - gval(1) + gval0;
- fa *= (xd - (1<<15)) >> 1;
- fa >>= 15;
- fa += gval(1) - gval0;
- fa *= xd;
- fa >>= 15;
- fa = fa + gval0;
- }
- //------------------------------------------//
- else
- if(iUseInterpolation==2) // gauss interpolation
- {
- int vl, vr;
- vl = (s_chan[ch].spos >> 6) & ~3;
- gpos = s_chan[ch].SB[28];
- vr=(gauss[vl]*gval0)&~2047;
- vr+=(gauss[vl+1]*gval(1))&~2047;
- vr+=(gauss[vl+2]*gval(2))&~2047;
- vr+=(gauss[vl+3]*gval(3))&~2047;
- fa = vr>>11;
-/*
- vr=(gauss[vl]*gval0)>>9;
- vr+=(gauss[vl+1]*gval(1))>>9;
- vr+=(gauss[vl+2]*gval(2))>>9;
- vr+=(gauss[vl+3]*gval(3))>>9;
- fa = vr>>2;
-*/
- }
- //------------------------------------------//
- else
- if(iUseInterpolation==1) // simple interpolation
- {
- if(s_chan[ch].sinc<0x10000L) // -> upsampling?
- InterpolateUp(ch); // --> interpolate up
- else InterpolateDown(ch); // --> else down
- fa=s_chan[ch].SB[29];
- }
- //------------------------------------------//
- else fa=s_chan[ch].SB[29]; // no interpolation
- }
-
- s_chan[ch].sval = (MixADSR(ch) * fa) / 1023; // add adsr
-
- if(s_chan[ch].bFMod==2) // fmod freq channel
- {
- int NP=s_chan[ch+1].iRawPitch;
- double intr;
-
- NP=((32768L+s_chan[ch].sval)*NP)/32768L; // mmm... I still need to adjust that to 1/48 khz... we will wait for the first game/demo using it to decide how to do it :)
-
- if(NP>0x3fff) NP=0x3fff;
- if(NP<0x1) NP=0x1;
-
- intr = (double)48000.0f / (double)44100.0f * (double)NP;
- NP = (uint32_t)intr;
-
- NP=(44100L*NP)/(4096L); // calc frequency
-
- s_chan[ch+1].iActFreq=NP;
- s_chan[ch+1].iUsedFreq=NP;
- s_chan[ch+1].sinc=(((NP/10)<<16)/4410);
- if(!s_chan[ch+1].sinc) s_chan[ch+1].sinc=1;
- if(iUseInterpolation==1) // freq change in sipmle interpolation mode
- s_chan[ch+1].SB[32]=1;
-
-// mmmm... set up freq decoding positions?
-// s_chan[ch+1].iSBPos=28;
-// s_chan[ch+1].spos=0x10000L;
- }
- else
- {
- //////////////////////////////////////////////
- // ok, left/right sound volume (psx volume goes from 0 ... 0x3fff)
-
- if(s_chan[ch].iMute)
- s_chan[ch].sval=0; // debug mute
- else
- {
- if(s_chan[ch].bVolumeL)
- SSumL[0]+=(s_chan[ch].sval*s_chan[ch].iLeftVolume)/0x4000L;
- if(s_chan[ch].bVolumeR)
- SSumR[0]+=(s_chan[ch].sval*s_chan[ch].iRightVolume)/0x4000L;
- }
-
- //////////////////////////////////////////////
- // now let us store sound data for reverb
-
- if(s_chan[ch].bRVBActive) StoreREVERB(ch,0);
- }
-
- ////////////////////////////////////////////////
- // ok, go on until 1 ms data of this channel is collected
-
- s_chan[ch].spos += s_chan[ch].sinc;
-
- }
-ENDX: ;
- }
- }
-
- //---------------------------------------------------//
- //- here we have another 1 ms of sound data
- //---------------------------------------------------//
-
- ///////////////////////////////////////////////////////
- // mix all channels (including reverb) into one buffer
-
- SSumL[0]+=MixREVERBLeft(0,0);
- SSumL[0]+=MixREVERBLeft(0,1);
- SSumR[0]+=MixREVERBRight(0);
- SSumR[0]+=MixREVERBRight(1);
-
- d=SSumL[0];SSumL[0]=0;
- d2=SSumR[0];SSumR[0]=0;
-
- if(d<-32767) d=-32767;if(d>32767) d=32767;
- if(d2<-32767) d2=-32767;if(d2>32767) d2=32767;
-
- if(sampcount>=decaybegin)
- {
- s32 dmul;
- if(decaybegin!=~0) // Is anyone REALLY going to be playing a song
- // for 13 hours?
- {
- if(sampcount>=decayend)
- {
- psf2_update(NULL, 0, data);
- return(0);
- }
-
- dmul=256-(256*(sampcount-decaybegin)/(decayend-decaybegin));
- d=(d*dmul)>>8;
- d2=(d2*dmul)>>8;
- }
- }
- sampcount++;
-
- *pS++=d;
- *pS++=d2;
-
- InitREVERB();
-
- //////////////////////////////////////////////////////
- // feed the sound
- // wanna have around 1/60 sec (16.666 ms) updates
- if (seektime != 0 && sampcount < seektime)
- {
- pS=(short *)pSpuBuffer;
- }
- else if ((((unsigned char *)pS)-((unsigned char *)pSpuBuffer)) == (735*4))
- {
- short *pSilenceIter = (short *)pSpuBuffer;
- int iSilenceCount = 0;
-
- for (; pSilenceIter < pS; pSilenceIter++)
- {
- if (*pSilenceIter == 0)
- iSilenceCount++;
-
- if (iSilenceCount > 20)
- break;
- }
-
- if (iSilenceCount < 20)
- psf2_update((u8*)pSpuBuffer,(u8*)pS-(u8*)pSpuBuffer, data);
-
- pS=(short *)pSpuBuffer;
- }
- }
-
- // end of big main loop...
-
- bThreadEnded=1;
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-// SPU ASYNC... even newer epsxe func
-// 1 time every 'cycle' cycles... harhar
-////////////////////////////////////////////////////////////////////////
-
-EXPORT_GCC void CALLBACK SPU2async(unsigned long cycle, void *data)
-{
- if(iSpuAsyncWait)
- {
- iSpuAsyncWait++;
- if(iSpuAsyncWait<=64) return;
- iSpuAsyncWait=0;
- }
- MAINThread(0, data); // -> linux high-compat mode
-}
-
-////////////////////////////////////////////////////////////////////////
-// INIT/EXIT STUFF
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-// SPUINIT: this func will be called first by the main emu
-////////////////////////////////////////////////////////////////////////
-
-
-EXPORT_GCC long CALLBACK SPU2init(void)
-{
- spuMemC=(unsigned char *)spuMem; // just small setup
- memset((void *)s_chan,0,MAXCHAN*sizeof(SPUCHAN));
- memset(rvb,0,2*sizeof(REVERBInfo));
-
- sampcount = 0;
-
- InitADSR();
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// SETUPTIMER: init of certain buffers and threads/timers
-////////////////////////////////////////////////////////////////////////
-
-static void SetupTimer(void)
-{
- memset(SSumR,0,NSSIZE*sizeof(int)); // init some mixing buffers
- memset(SSumL,0,NSSIZE*sizeof(int));
- pS=(short *)pSpuBuffer; // setup soundbuffer pointer
-
- bEndThread=0; // init thread vars
- bThreadEnded=0;
- bSpuInit=1; // flag: we are inited
-}
-
-////////////////////////////////////////////////////////////////////////
-// REMOVETIMER: kill threads/timers
-////////////////////////////////////////////////////////////////////////
-
-static void RemoveTimer(void)
-{
- bEndThread=1; // raise flag to end thread
- bThreadEnded=0; // no more spu is running
- bSpuInit=0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// SETUPSTREAMS: init most of the spu buffers
-////////////////////////////////////////////////////////////////////////
-
-static void SetupStreams(void)
-{
- int i;
-
- pSpuBuffer=(unsigned char *)malloc(32768); // alloc mixing buffer
-
- i=NSSIZE*2;
-
- sRVBStart[0] = (int *)malloc(i*4); // alloc reverb buffer
- memset(sRVBStart[0],0,i*4);
- sRVBEnd[0] = sRVBStart[0] + i;
- sRVBPlay[0] = sRVBStart[0];
- sRVBStart[1] = (int *)malloc(i*4); // alloc reverb buffer
- memset(sRVBStart[1],0,i*4);
- sRVBEnd[1] = sRVBStart[1] + i;
- sRVBPlay[1] = sRVBStart[1];
-
- for(i=0;i<MAXCHAN;i++) // loop sound channels
- {
-// we don't use mutex sync... not needed, would only
-// slow us down:
-// s_chan[i].hMutex=CreateMutex(NULL,FALSE,NULL);
- s_chan[i].ADSRX.SustainLevel = 1024; // -> init sustain
- s_chan[i].iMute=0;
- s_chan[i].iIrqDone=0;
- s_chan[i].pLoop=spuMemC;
- s_chan[i].pStart=spuMemC;
- s_chan[i].pCurr=spuMemC;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// REMOVESTREAMS: free most buffer
-////////////////////////////////////////////////////////////////////////
-
-static void RemoveStreams(void)
-{
- free(pSpuBuffer); // free mixing buffer
- pSpuBuffer=NULL;
- free(sRVBStart[0]); // free reverb buffer
- sRVBStart[0]=0;
- free(sRVBStart[1]); // free reverb buffer
- sRVBStart[1]=0;
-
-/*
- int i;
- for(i=0;i<MAXCHAN;i++)
- {
- WaitForSingleObject(s_chan[i].hMutex,2000);
- ReleaseMutex(s_chan[i].hMutex);
- if(s_chan[i].hMutex)
- {CloseHandle(s_chan[i].hMutex);s_chan[i].hMutex=0;}
- }
-*/
-}
-
-
-////////////////////////////////////////////////////////////////////////
-// SPUOPEN: called by main emu after init
-////////////////////////////////////////////////////////////////////////
-
-EXPORT_GCC long CALLBACK SPU2open(void *pDsp)
-{
- if(bSPUIsOpen) return 0; // security for some stupid main emus
-
- iUseXA=0; // just small setup
- bEndThread=0;
- bThreadEnded=0;
- spuMemC=(unsigned char *)spuMem;
- memset((void *)s_chan,0,(MAXCHAN+1)*sizeof(SPUCHAN));
- pSpuIrq[0]=0;
- pSpuIrq[1]=0;
- iSPUIRQWait=1;
- dwNewChannel2[0]=0;
- dwNewChannel2[1]=0;
- dwEndChannel2[0]=0;
- dwEndChannel2[1]=0;
- spuCtrl2[0]=0;
- spuCtrl2[1]=0;
- spuStat2[0]=0;
- spuStat2[1]=0;
- spuIrq2[0]=0;
- spuIrq2[1]=0;
- spuAddr2[0]=0xffffffff;
- spuAddr2[1]=0xffffffff;
- spuRvbAddr2[0]=0;
- spuRvbAddr2[1]=0;
- spuRvbAEnd2[0]=0;
- spuRvbAEnd2[1]=0;
-
-// ReadConfig(); // read user stuff
-
-// SetupSound(); // setup midas (before init!)
-
- SetupStreams(); // prepare streaming
-
- SetupTimer(); // timer for feeding data
-
- bSPUIsOpen=1;
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-// SPUCLOSE: called before shutdown
-////////////////////////////////////////////////////////////////////////
-
-EXPORT_GCC void CALLBACK SPU2close(void)
-{
- if(!bSPUIsOpen) return; // some security
-
- bSPUIsOpen=0; // no more open
-
- RemoveTimer(); // no more feeding
-
-// RemoveSound(); // no more sound handling
-
- RemoveStreams(); // no more streaming
-}
-
-////////////////////////////////////////////////////////////////////////
-// SPUSHUTDOWN: called by main emu on final exit
-////////////////////////////////////////////////////////////////////////
-
-EXPORT_GCC void CALLBACK SPU2shutdown(void)
-{
- return;
-}
-
-////////////////////////////////////////////////////////////////////////
-// SPUTEST: we don't test, we are always fine ;)
-////////////////////////////////////////////////////////////////////////
-
-EXPORT_GCC long CALLBACK SPU2test(void)
-{
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// SETUP CALLBACKS
-// this functions will be called once,
-// passes a callback that should be called on SPU-IRQ/cdda volume change
-////////////////////////////////////////////////////////////////////////
-
-// not used yet
-EXPORT_GCC void CALLBACK SPU2irqCallback(void (CALLBACK *callback)(void))
-{
- irqCallback = callback;
-}
-
-// not used yet
-EXPORT_GCC void CALLBACK SPU2registerCallback(void (CALLBACK *callback)(void))
-{
- irqCallback = callback;
-}
-
-// not used yet
-EXPORT_GCC void CALLBACK SPU2registerCDDAVolume(void (CALLBACK *CDDAVcallback)(unsigned short,unsigned short))
-{
- cddavCallback = CDDAVcallback;
-}
diff --git a/src/psf/peops2/spu.cc b/src/psf/peops2/spu.cc
new file mode 100644
index 000000000000..b5d0b3bdbad5
--- /dev/null
+++ b/src/psf/peops2/spu.cc
@@ -0,0 +1,1034 @@
+/***************************************************************************
+ spu.c - description
+ -------------------
+ begin : Wed May 15 2002
+ copyright : (C) 2002 by Pete Bernert
+ email : BlackDove at addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+//*************************************************************************//
+// History of changes:
+//
+// 2005/08/29 - Pete
+// - changed to 48Khz output
+//
+// 2004/12/25 - Pete
+// - inc'd version for pcsx2-0.7
+//
+// 2004/04/18 - Pete
+// - changed all kind of things in the plugin
+//
+// 2004/04/04 - Pete
+// - changed plugin to emulate PS2 spu
+//
+// 2003/04/07 - Eric
+// - adjusted cubic interpolation algorithm
+//
+// 2003/03/16 - Eric
+// - added cubic interpolation
+//
+// 2003/03/01 - linuzappz
+// - libraryName changes using ALSA
+//
+// 2003/02/28 - Pete
+// - added option for type of interpolation
+// - adjusted spu irqs again (Thousant Arms, Valkyrie Profile)
+// - added MONO support for MSWindows DirectSound
+//
+// 2003/02/20 - kode54
+// - amended interpolation code, goto GOON could skip initialization of gpos and cause segfault
+//
+// 2003/02/19 - kode54
+// - moved SPU IRQ handler and changed sample flag processing
+//
+// 2003/02/18 - kode54
+// - moved ADSR calculation outside of the sample decode loop, somehow I doubt that
+// ADSR timing is relative to the frequency at which a sample is played... I guess
+// this remains to be seen, and I don't know whether ADSR is applied to noise channels...
+//
+// 2003/02/09 - kode54
+// - one-shot samples now process the end block before stopping
+// - in light of removing fmod hack, now processing ADSR on frequency channel as well
+//
+// 2003/02/08 - kode54
+// - replaced easy interpolation with gaussian
+// - removed fmod averaging hack
+// - changed .sinc to be updated from .iRawPitch, no idea why it wasn't done this way already (<- Pete: because I sometimes fail to see the obvious, haharhar :)
+//
+// 2003/02/08 - linuzappz
+// - small bugfix for one usleep that was 1 instead of 1000
+// - added iDisStereo for no stereo (Linux)
+//
+// 2003/01/22 - Pete
+// - added easy interpolation & small noise adjustments
+//
+// 2003/01/19 - Pete
+// - added Neill's reverb
+//
+// 2003/01/12 - Pete
+// - added recording window handlers
+//
+// 2003/01/06 - Pete
+// - added Neill's ADSR timings
+//
+// 2002/12/28 - Pete
+// - adjusted spu irq handling, fmod handling and loop handling
+//
+// 2002/08/14 - Pete
+// - added extra reverb
+//
+// 2002/06/08 - linuzappz
+// - SPUupdate changed for SPUasync
+//
+// 2002/05/15 - Pete
+// - generic cleanup for the Peops release
+//
+//*************************************************************************//
+
+#include "stdafx.h"
+
+#define _IN_SPU
+
+#include "../peops2/externals.h"
+#include "../peops2/regs.h"
+#include "../peops2/dma.h"
+
+////////////////////////////////////////////////////////////////////////
+// globals
+////////////////////////////////////////////////////////////////////////
+
+// psx buffer / addresses
+
+unsigned short regArea[32*1024];
+unsigned short spuMem[1*1024*1024];
+unsigned char * spuMemC;
+unsigned char * pSpuIrq[2];
+unsigned char * pSpuBuffer;
+
+// user settings
+
+int iUseXA=0;
+int iXAPitch=1;
+int iUseTimer=2;
+int iSPUIRQWait=1;
+int iDebugMode=0;
+int iRecordMode=0;
+int iUseReverb=1;
+int iUseInterpolation=2;
+
+// MAIN infos struct for each channel
+
+SPUCHAN s_chan[MAXCHAN+1]; // channel + 1 infos (1 is security for fmod handling)
+REVERBInfo rvb[2];
+
+unsigned long dwNoiseVal=1; // global noise generator
+
+unsigned short spuCtrl2[2]; // some vars to store psx reg infos
+unsigned short spuStat2[2];
+unsigned long spuIrq2[2];
+unsigned long spuAddr2[2]; // address into spu mem
+unsigned long spuRvbAddr2[2];
+unsigned long spuRvbAEnd2[2];
+int bEndThread=0; // thread handlers
+int bThreadEnded=0;
+int bSpuInit=0;
+int bSPUIsOpen=0;
+
+unsigned long dwNewChannel2[2]; // flags for faster testing, if new channel starts
+unsigned long dwEndChannel2[2];
+
+// UNUSED IN PS2 YET
+void (CALLBACK *irqCallback)(void)=0; // func of main emu, called on spu irq
+void (CALLBACK *cddavCallback)(unsigned short,unsigned short)=0;
+
+// certain globals (were local before, but with the new timeproc I need em global)
+
+const int f[5][2] = { { 0, 0 },
+ { 60, 0 },
+ { 115, -52 },
+ { 98, -55 },
+ { 122, -60 } };
+int SSumR[NSSIZE];
+int SSumL[NSSIZE];
+int iCycle=0;
+short * pS;
+
+static int lastch=-1; // last channel processed on spu irq in timer mode
+static int iSecureStart=0; // secure start counter
+
+////////////////////////////////////////////////////////////////////////
+// CODE AREA
+////////////////////////////////////////////////////////////////////////
+
+// dirty inline func includes
+
+#include "reverb.cc"
+#include "adsr.cc"
+
+////////////////////////////////////////////////////////////////////////
+// helpers for simple interpolation
+
+//
+// easy interpolation on upsampling, no special filter, just "Pete's common sense" tm
+//
+// instead of having n equal sample values in a row like:
+// ____
+// |____
+//
+// we compare the current delta change with the next delta change.
+//
+// if curr_delta is positive,
+//
+// - and next delta is smaller (or changing direction):
+// \.
+// -__
+//
+// - and next delta significant (at least twice) bigger:
+// --_
+// \.
+//
+// - and next delta is nearly same:
+// \.
+// \.
+//
+//
+// if curr_delta is negative,
+//
+// - and next delta is smaller (or changing direction):
+// _--
+// /
+//
+// - and next delta significant (at least twice) bigger:
+// /
+// __-
+//
+// - and next delta is nearly same:
+// /
+// /
+//
+
+
+static inline void InterpolateUp(int ch)
+{
+ if(s_chan[ch].SB[32]==1) // flag == 1? calc step and set flag... and don't change the value in this pass
+ {
+ const int id1=s_chan[ch].SB[30]-s_chan[ch].SB[29]; // curr delta to next val
+ const int id2=s_chan[ch].SB[31]-s_chan[ch].SB[30]; // and next delta to next-next val :)
+
+ s_chan[ch].SB[32]=0;
+
+ if(id1>0) // curr delta positive
+ {
+ if(id2<id1)
+ {s_chan[ch].SB[28]=id1;s_chan[ch].SB[32]=2;}
+ else
+ if(id2<(id1<<1))
+ s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x10000L;
+ else
+ s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x20000L;
+ }
+ else // curr delta negative
+ {
+ if(id2>id1)
+ {s_chan[ch].SB[28]=id1;s_chan[ch].SB[32]=2;}
+ else
+ if(id2>(id1<<1))
+ s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x10000L;
+ else
+ s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x20000L;
+ }
+ }
+ else
+ if(s_chan[ch].SB[32]==2) // flag 1: calc step and set flag... and don't change the value in this pass
+ {
+ s_chan[ch].SB[32]=0;
+
+ s_chan[ch].SB[28]=(s_chan[ch].SB[28]*s_chan[ch].sinc)/0x20000L;
+ if(s_chan[ch].sinc<=0x8000)
+ s_chan[ch].SB[29]=s_chan[ch].SB[30]-(s_chan[ch].SB[28]*((0x10000/s_chan[ch].sinc)-1));
+ else s_chan[ch].SB[29]+=s_chan[ch].SB[28];
+ }
+ else // no flags? add bigger val (if possible), calc smaller step, set flag1
+ s_chan[ch].SB[29]+=s_chan[ch].SB[28];
+}
+
+//
+// even easier interpolation on downsampling, also no special filter, again just "Pete's common sense" tm
+//
+
+static inline void InterpolateDown(int ch)
+{
+ if(s_chan[ch].sinc>=0x20000L) // we would skip at least one val?
+ {
+ s_chan[ch].SB[29]+=(s_chan[ch].SB[30]-s_chan[ch].SB[29])/2; // add easy weight
+ if(s_chan[ch].sinc>=0x30000L) // we would skip even more vals?
+ s_chan[ch].SB[29]+=(s_chan[ch].SB[31]-s_chan[ch].SB[30])/2;// add additional next weight
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// helpers for gauss interpolation
+
+#define gval0 (((short*)(&s_chan[ch].SB[29]))[gpos])
+#define gval(x) (((short*)(&s_chan[ch].SB[29]))[(gpos+x)&3])
+
+#include "gauss_i.h"
+
+////////////////////////////////////////////////////////////////////////
+
+//#include "xa.c"
+
+////////////////////////////////////////////////////////////////////////
+// START SOUND... called by main thread to setup a new sound on a channel
+////////////////////////////////////////////////////////////////////////
+
+static inline void StartSound(int ch)
+{
+ dwNewChannel2[ch/24]&=~(1<<(ch%24)); // clear new channel bit
+ dwEndChannel2[ch/24]&=~(1<<(ch%24)); // clear end channel bit
+
+ StartADSR(ch);
+ StartREVERB(ch);
+
+ s_chan[ch].pCurr=s_chan[ch].pStart; // set sample start
+
+ s_chan[ch].s_1=0; // init mixing vars
+ s_chan[ch].s_2=0;
+ s_chan[ch].iSBPos=28;
+
+ s_chan[ch].bNew=0; // init channel flags
+ s_chan[ch].bStop=0;
+ s_chan[ch].bOn=1;
+
+ s_chan[ch].SB[29]=0; // init our interpolation helpers
+ s_chan[ch].SB[30]=0;
+
+ if(iUseInterpolation>=2) // gauss interpolation?
+ {s_chan[ch].spos=0x30000L;s_chan[ch].SB[28]=0;} // -> start with more decoding
+ else {s_chan[ch].spos=0x10000L;s_chan[ch].SB[31]=0;} // -> no/simple interpolation starts with one 44100 decoding
+}
+
+////////////////////////////////////////////////////////////////////////
+// MAIN SPU FUNCTION
+// here is the main job handler... thread, timer or direct func call
+// basically the whole sound processing is done in this fat func!
+////////////////////////////////////////////////////////////////////////
+
+static u32 sampcount;
+static u32 decaybegin;
+static u32 decayend;
+
+static u32 seektime;
+int psf2_seek(u32 t)
+{
+ seektime=t*441/10;
+ if(seektime>sampcount) return(1);
+ return(0);
+}
+
+// Counting to 65536 results in full volume offage.
+void setlength2(s32 stop, s32 fade)
+{
+ seektime = 0;
+ if(stop==~0)
+ {
+ decaybegin=~0;
+ }
+ else
+ {
+ stop=(stop*441)/10;
+ fade=(fade*441)/10;
+
+ decaybegin=stop;
+ decayend=stop+fade;
+ }
+}
+// 5 ms waiting phase, if buffer is full and no new sound has to get started
+// .. can be made smaller (smallest val: 1 ms), but bigger waits give
+// better performance
+
+#define PAUSE_W 5
+#define PAUSE_L 5000
+
+////////////////////////////////////////////////////////////////////////
+
+int iSpuAsyncWait=0;
+
+static void *MAINThread(void (*update)(const void *, int))
+{
+ int s_1,s_2,fa;
+ unsigned char * start;unsigned int nSample;
+ int ch,predict_nr,shift_factor,flags,d,d2,s;
+ int gpos,bIRQReturn=0;
+
+// while(!bEndThread) // until we are shutting down
+ {
+ //--------------------------------------------------//
+ // ok, at the beginning we are looking if there is
+ // enuff free place in the dsound/oss buffer to
+ // fill in new data, or if there is a new channel to start.
+ // if not, we wait (thread) or return (timer/spuasync)
+ // until enuff free place is available/a new channel gets
+ // started
+
+ if(dwNewChannel2[0] || dwNewChannel2[1]) // new channel should start immedately?
+ { // (at least one bit 0 ... MAXCHANNEL is set?)
+ iSecureStart++; // -> set iSecure
+ if(iSecureStart>5) iSecureStart=0; // (if it is set 5 times - that means on 5 tries a new samples has been started - in a row, we will reset it, to give the sound update a chance)
+ }
+ else iSecureStart=0; // 0: no new channel should start
+
+/* if (!iSecureStart)
+ {
+ iSecureStart=0; // reset secure
+ return;
+ }*/
+
+#if 0
+ while(!iSecureStart && !bEndThread) // && // no new start? no thread end?
+// (SoundGetBytesBuffered()>TESTSIZE)) // and still enuff data in sound buffer?
+ {
+ iSecureStart=0; // reset secure
+
+ if(iUseTimer) return 0; // linux no-thread mode? bye
+
+ if(dwNewChannel2[0] || dwNewChannel2[1])
+ iSecureStart=1; // if a new channel kicks in (or, of course, sound buffer runs low), we will leave the loop
+ }
+#endif
+
+ //--------------------------------------------------// continue from irq handling in timer mode?
+
+ if(lastch>=0) // will be -1 if no continue is pending
+ {
+ ch=lastch; lastch=-1; // -> setup all kind of vars to continue
+ goto GOON; // -> directly jump to the continue point
+ }
+
+ //--------------------------------------------------//
+ //- main channel loop -//
+ //--------------------------------------------------//
+ {
+ for(ch=0;ch<MAXCHAN;ch++) // loop em all... we will collect 1 ms of sound of each playing channel
+ {
+ if(s_chan[ch].bNew) StartSound(ch); // start new sound
+ if(!s_chan[ch].bOn) continue; // channel not playing? next
+
+ if(s_chan[ch].iActFreq!=s_chan[ch].iUsedFreq) // new psx frequency?
+ {
+ s_chan[ch].iUsedFreq=s_chan[ch].iActFreq; // -> take it and calc steps
+ s_chan[ch].sinc=s_chan[ch].iRawPitch<<4;
+ if(!s_chan[ch].sinc) s_chan[ch].sinc=1;
+ if(iUseInterpolation==1) s_chan[ch].SB[32]=1; // -> freq change in simle imterpolation mode: set flag
+ }
+// ns=0;
+// while(ns<NSSIZE) // loop until 1 ms of data is reached
+ {
+ while(s_chan[ch].spos>=0x10000L)
+ {
+ if(s_chan[ch].iSBPos==28) // 28 reached?
+ {
+ start=s_chan[ch].pCurr; // set up the current pos
+
+ if (start == (unsigned char*)-1) // special "stop" sign
+ {
+ s_chan[ch].bOn=0; // -> turn everything off
+ s_chan[ch].ADSRX.lVolume=0;
+ s_chan[ch].ADSRX.EnvelopeVol=0;
+ goto ENDX; // -> and done for this channel
+ }
+
+ s_chan[ch].iSBPos=0;
+
+ //////////////////////////////////////////// spu irq handler here? mmm... do it later
+
+ s_1=s_chan[ch].s_1;
+ s_2=s_chan[ch].s_2;
+
+ predict_nr=(int)*start;start++;
+ shift_factor=predict_nr&0xf;
+ predict_nr >>= 4;
+ flags=(int)*start;start++;
+
+ // -------------------------------------- //
+
+ for (nSample=0;nSample<28;start++)
+ {
+ d=(int)*start;
+ s=((d&0xf)<<12);
+ if(s&0x8000) s|=0xffff0000;
+
+ fa=(s >> shift_factor);
+ fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6);
+ s_2=s_1;s_1=fa;
+ s=((d & 0xf0) << 8);
+
+ s_chan[ch].SB[nSample++]=fa;
+
+ if(s&0x8000) s|=0xffff0000;
+ fa=(s>>shift_factor);
+ fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6);
+ s_2=s_1;s_1=fa;
+
+ s_chan[ch].SB[nSample++]=fa;
+ }
+
+ //////////////////////////////////////////// irq check
+
+ if(spuCtrl2[ch/24]&0x40) // some irq active?
+ {
+ if((pSpuIrq[ch/24] > start-16 && // irq address reached?
+ pSpuIrq[ch/24] <= start) ||
+ ((flags&1) && // special: irq on looping addr, when stop/loop flag is set
+ (pSpuIrq[ch/24] > s_chan[ch].pLoop-16 &&
+ pSpuIrq[ch/24] <= s_chan[ch].pLoop)))
+ {
+ s_chan[ch].iIrqDone=1; // -> debug flag
+
+ if(irqCallback) irqCallback(); // -> call main emu (not supported in SPU2 right now)
+ else
+ {
+ if(ch<24) InterruptDMA4(); // -> let's see what is happening if we call our irqs instead ;)
+ else InterruptDMA7();
+ }
+
+ if(iSPUIRQWait) // -> option: wait after irq for main emu
+ {
+ iSpuAsyncWait=1;
+ bIRQReturn=1;
+ }
+ }
+ }
+
+ //////////////////////////////////////////// flag handler
+
+ if((flags&4) && (!s_chan[ch].bIgnoreLoop))
+ s_chan[ch].pLoop=start-16; // loop adress
+
+ if(flags&1) // 1: stop/loop
+ {
+ dwEndChannel2[ch/24]|=(1<<(ch%24));
+
+ // We play this block out first...
+ //if(!(flags&2)|| s_chan[ch].pLoop==nullptr)
+ // 1+2: do loop... otherwise: stop
+ if(flags!=3 || s_chan[ch].pLoop==nullptr) // PETE: if we don't check exactly for 3, loop hang ups will happen (DQ4, for example)
+ { // and checking if pLoop is set avoids crashes, yeah
+ start = (unsigned char*)-1;
+ }
+ else
+ {
+ start = s_chan[ch].pLoop;
+ }
+ }
+
+ s_chan[ch].pCurr=start; // store values for next cycle
+ s_chan[ch].s_1=s_1;
+ s_chan[ch].s_2=s_2;
+
+ ////////////////////////////////////////////
+
+ if(bIRQReturn) // special return for "spu irq - wait for cpu action"
+ {
+ bIRQReturn=0;
+ {
+ lastch=ch;
+// lastns=ns; // changemeback
+
+ return nullptr;
+ }
+ }
+
+ ////////////////////////////////////////////
+
+GOON: ;
+
+ }
+
+ fa=s_chan[ch].SB[s_chan[ch].iSBPos++]; // get sample data
+
+// if((spuCtrl2[ch/24]&0x4000)==0) fa=0; // muted?
+// else // else adjust
+ {
+ if(fa>32767L) fa=32767L;
+ if(fa<-32767L) fa=-32767L;
+ }
+
+ if(iUseInterpolation>=2) // gauss/cubic interpolation
+ {
+ gpos = s_chan[ch].SB[28];
+ gval0 = fa;
+ gpos = (gpos+1) & 3;
+ s_chan[ch].SB[28] = gpos;
+ }
+ else
+ if(iUseInterpolation==1) // simple interpolation
+ {
+ s_chan[ch].SB[28] = 0;
+ s_chan[ch].SB[29] = s_chan[ch].SB[30]; // -> helpers for simple linear interpolation: delay real val for two slots, and calc the two deltas, for a 'look at the future behaviour'
+ s_chan[ch].SB[30] = s_chan[ch].SB[31];
+ s_chan[ch].SB[31] = fa;
+ s_chan[ch].SB[32] = 1; // -> flag: calc new interolation
+ }
+ else s_chan[ch].SB[29]=fa; // no interpolation
+
+ s_chan[ch].spos -= 0x10000L;
+ }
+
+ ////////////////////////////////////////////////
+ // noise handler... just produces some noise data
+ // surely wrong... and no noise frequency (spuCtrl&0x3f00) will be used...
+ // and sometimes the noise will be used as fmod modulation... pfff
+
+ if(s_chan[ch].bNoise)
+ {
+ if((dwNoiseVal<<=1)&0x80000000L)
+ {
+ dwNoiseVal^=0x0040001L;
+ fa=((dwNoiseVal>>2)&0x7fff);
+ fa=-fa;
+ }
+ else fa=(dwNoiseVal>>2)&0x7fff;
+
+ // mmm... depending on the noise freq we allow bigger/smaller changes to the previous val
+ fa=s_chan[ch].iOldNoise+((fa-s_chan[ch].iOldNoise)/((0x001f-((spuCtrl2[ch/24]&0x3f00)>>9))+1));
+ if(fa>32767L) fa=32767L;
+ if(fa<-32767L) fa=-32767L;
+ s_chan[ch].iOldNoise=fa;
+
+ if(iUseInterpolation<2) // no gauss/cubic interpolation?
+ s_chan[ch].SB[29] = fa; // -> store noise val in "current sample" slot
+ } //----------------------------------------
+ else // NO NOISE (NORMAL SAMPLE DATA) HERE
+ {//------------------------------------------//
+ if(iUseInterpolation==3) // cubic interpolation
+ {
+ long xd;
+ xd = ((s_chan[ch].spos) >> 1)+1;
+ gpos = s_chan[ch].SB[28];
+
+ fa = gval(3) - 3*gval(2) + 3*gval(1) - gval0;
+ fa *= (xd - (2<<15)) / 6;
+ fa >>= 15;
+ fa += gval(2) - gval(1) - gval(1) + gval0;
+ fa *= (xd - (1<<15)) >> 1;
+ fa >>= 15;
+ fa += gval(1) - gval0;
+ fa *= xd;
+ fa >>= 15;
+ fa = fa + gval0;
+ }
+ //------------------------------------------//
+ else
+ if(iUseInterpolation==2) // gauss interpolation
+ {
+ int vl, vr;
+ vl = (s_chan[ch].spos >> 6) & ~3;
+ gpos = s_chan[ch].SB[28];
+ vr=(gauss[vl]*gval0)&~2047;
+ vr+=(gauss[vl+1]*gval(1))&~2047;
+ vr+=(gauss[vl+2]*gval(2))&~2047;
+ vr+=(gauss[vl+3]*gval(3))&~2047;
+ fa = vr>>11;
+/*
+ vr=(gauss[vl]*gval0)>>9;
+ vr+=(gauss[vl+1]*gval(1))>>9;
+ vr+=(gauss[vl+2]*gval(2))>>9;
+ vr+=(gauss[vl+3]*gval(3))>>9;
+ fa = vr>>2;
+*/
+ }
+ //------------------------------------------//
+ else
+ if(iUseInterpolation==1) // simple interpolation
+ {
+ if(s_chan[ch].sinc<0x10000L) // -> upsampling?
+ InterpolateUp(ch); // --> interpolate up
+ else InterpolateDown(ch); // --> else down
+ fa=s_chan[ch].SB[29];
+ }
+ //------------------------------------------//
+ else fa=s_chan[ch].SB[29]; // no interpolation
+ }
+
+ s_chan[ch].sval = (MixADSR(ch) * fa) / 1023; // add adsr
+
+ if(s_chan[ch].bFMod==2) // fmod freq channel
+ {
+ int NP=s_chan[ch+1].iRawPitch;
+ double intr;
+
+ NP=((32768L+s_chan[ch].sval)*NP)/32768L; // mmm... I still need to adjust that to 1/48 khz... we will wait for the first game/demo using it to decide how to do it :)
+
+ if(NP>0x3fff) NP=0x3fff;
+ if(NP<0x1) NP=0x1;
+
+ intr = (double)48000.0f / (double)44100.0f * (double)NP;
+ NP = (uint32_t)intr;
+
+ NP=(44100L*NP)/(4096L); // calc frequency
+
+ s_chan[ch+1].iActFreq=NP;
+ s_chan[ch+1].iUsedFreq=NP;
+ s_chan[ch+1].sinc=(((NP/10)<<16)/4410);
+ if(!s_chan[ch+1].sinc) s_chan[ch+1].sinc=1;
+ if(iUseInterpolation==1) // freq change in sipmle interpolation mode
+ s_chan[ch+1].SB[32]=1;
+
+// mmmm... set up freq decoding positions?
+// s_chan[ch+1].iSBPos=28;
+// s_chan[ch+1].spos=0x10000L;
+ }
+ else
+ {
+ //////////////////////////////////////////////
+ // ok, left/right sound volume (psx volume goes from 0 ... 0x3fff)
+
+ if(s_chan[ch].iMute)
+ s_chan[ch].sval=0; // debug mute
+ else
+ {
+ if(s_chan[ch].bVolumeL)
+ SSumL[0]+=(s_chan[ch].sval*s_chan[ch].iLeftVolume)/0x4000L;
+ if(s_chan[ch].bVolumeR)
+ SSumR[0]+=(s_chan[ch].sval*s_chan[ch].iRightVolume)/0x4000L;
+ }
+
+ //////////////////////////////////////////////
+ // now let us store sound data for reverb
+
+ if(s_chan[ch].bRVBActive) StoreREVERB(ch,0);
+ }
+
+ ////////////////////////////////////////////////
+ // ok, go on until 1 ms data of this channel is collected
+
+ s_chan[ch].spos += s_chan[ch].sinc;
+
+ }
+ENDX: ;
+ }
+ }
+
+ //---------------------------------------------------//
+ //- here we have another 1 ms of sound data
+ //---------------------------------------------------//
+
+ ///////////////////////////////////////////////////////
+ // mix all channels (including reverb) into one buffer
+
+ SSumL[0]+=MixREVERBLeft(0,0);
+ SSumL[0]+=MixREVERBLeft(0,1);
+ SSumR[0]+=MixREVERBRight(0);
+ SSumR[0]+=MixREVERBRight(1);
+
+ d=SSumL[0];SSumL[0]=0;
+ d2=SSumR[0];SSumR[0]=0;
+
+ if(d<-32767) d=-32767;if(d>32767) d=32767;
+ if(d2<-32767) d2=-32767;if(d2>32767) d2=32767;
+
+ if(sampcount>=decaybegin)
+ {
+ s32 dmul;
+ if(decaybegin!=~0) // Is anyone REALLY going to be playing a song
+ // for 13 hours?
+ {
+ if(sampcount>=decayend)
+ {
+ update(nullptr, 0);
+ return(0);
+ }
+
+ dmul=256-(256*(sampcount-decaybegin)/(decayend-decaybegin));
+ d=(d*dmul)>>8;
+ d2=(d2*dmul)>>8;
+ }
+ }
+ sampcount++;
+
+ *pS++=d;
+ *pS++=d2;
+
+ InitREVERB();
+
+ //////////////////////////////////////////////////////
+ // feed the sound
+ // wanna have around 1/60 sec (16.666 ms) updates
+ if(seektime != 0 && sampcount < seektime)
+ {
+ pS=(short *)pSpuBuffer;
+ }
+ else if((((u8*)pS)-((u8*)pSpuBuffer)) == (735*4))
+ {
+ short *pSilenceIter = (short *)pSpuBuffer;
+ int iSilenceCount = 0;
+
+ for(; pSilenceIter < pS; pSilenceIter++)
+ {
+ if(*pSilenceIter == 0)
+ iSilenceCount++;
+
+ if(iSilenceCount > 20)
+ break;
+ }
+
+ if(iSilenceCount < 20)
+ update((u8*)pSpuBuffer,(u8*)pS-(u8*)pSpuBuffer);
+
+ pS=(short *)pSpuBuffer;
+ }
+ }
+
+ // end of big main loop...
+
+ bThreadEnded=1;
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// SPU ASYNC... even newer epsxe func
+// 1 time every 'cycle' cycles... harhar
+////////////////////////////////////////////////////////////////////////
+
+EXPORT_GCC void CALLBACK SPU2async(void (*update)(const void *, int))
+{
+ if(iSpuAsyncWait)
+ {
+ iSpuAsyncWait++;
+ if(iSpuAsyncWait<=64) return;
+ iSpuAsyncWait=0;
+ }
+ MAINThread(update); // -> linux high-compat mode
+}
+
+////////////////////////////////////////////////////////////////////////
+// INIT/EXIT STUFF
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// SPUINIT: this func will be called first by the main emu
+////////////////////////////////////////////////////////////////////////
+
+
+EXPORT_GCC long CALLBACK SPU2init(void)
+{
+ spuMemC=(unsigned char *)spuMem; // just small setup
+ memset((void *)s_chan,0,MAXCHAN*sizeof(SPUCHAN));
+ memset(rvb,0,2*sizeof(REVERBInfo));
+
+ sampcount = 0;
+
+ InitADSR();
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// SETUPTIMER: init of certain buffers and threads/timers
+////////////////////////////////////////////////////////////////////////
+
+static void SetupTimer(void)
+{
+ memset(SSumR,0,NSSIZE*sizeof(int)); // init some mixing buffers
+ memset(SSumL,0,NSSIZE*sizeof(int));
+ pS=(short *)pSpuBuffer; // setup soundbuffer pointer
+
+ bEndThread=0; // init thread vars
+ bThreadEnded=0;
+ bSpuInit=1; // flag: we are inited
+}
+
+////////////////////////////////////////////////////////////////////////
+// REMOVETIMER: kill threads/timers
+////////////////////////////////////////////////////////////////////////
+
+static void RemoveTimer(void)
+{
+ bEndThread=1; // raise flag to end thread
+ bThreadEnded=0; // no more spu is running
+ bSpuInit=0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// SETUPSTREAMS: init most of the spu buffers
+////////////////////////////////////////////////////////////////////////
+
+static void SetupStreams(void)
+{
+ int i;
+
+ pSpuBuffer=(unsigned char *)malloc(32768); // alloc mixing buffer
+
+ i=NSSIZE*2;
+
+ sRVBStart[0] = (int *)malloc(i*4); // alloc reverb buffer
+ memset(sRVBStart[0],0,i*4);
+ sRVBEnd[0] = sRVBStart[0] + i;
+ sRVBPlay[0] = sRVBStart[0];
+ sRVBStart[1] = (int *)malloc(i*4); // alloc reverb buffer
+ memset(sRVBStart[1],0,i*4);
+ sRVBEnd[1] = sRVBStart[1] + i;
+ sRVBPlay[1] = sRVBStart[1];
+
+ for(i=0;i<MAXCHAN;i++) // loop sound channels
+ {
+// we don't use mutex sync... not needed, would only
+// slow us down:
+// s_chan[i].hMutex=CreateMutex(nullptr,false,nullptr);
+ s_chan[i].ADSRX.SustainLevel = 1024; // -> init sustain
+ s_chan[i].iMute=0;
+ s_chan[i].iIrqDone=0;
+ s_chan[i].pLoop=spuMemC;
+ s_chan[i].pStart=spuMemC;
+ s_chan[i].pCurr=spuMemC;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// REMOVESTREAMS: free most buffer
+////////////////////////////////////////////////////////////////////////
+
+static void RemoveStreams(void)
+{
+ free(pSpuBuffer); // free mixing buffer
+ pSpuBuffer=nullptr;
+ free(sRVBStart[0]); // free reverb buffer
+ sRVBStart[0]=0;
+ free(sRVBStart[1]); // free reverb buffer
+ sRVBStart[1]=0;
+
+/*
+ int i;
+ for(i=0;i<MAXCHAN;i++)
+ {
+ WaitForSingleObject(s_chan[i].hMutex,2000);
+ ReleaseMutex(s_chan[i].hMutex);
+ if(s_chan[i].hMutex)
+ {CloseHandle(s_chan[i].hMutex);s_chan[i].hMutex=0;}
+ }
+*/
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// SPUOPEN: called by main emu after init
+////////////////////////////////////////////////////////////////////////
+
+EXPORT_GCC long CALLBACK SPU2open(void *pDsp)
+{
+ if(bSPUIsOpen) return 0; // security for some stupid main emus
+
+ iUseXA=0; // just small setup
+ bEndThread=0;
+ bThreadEnded=0;
+ spuMemC=(unsigned char *)spuMem;
+ memset((void *)s_chan,0,(MAXCHAN+1)*sizeof(SPUCHAN));
+ pSpuIrq[0]=0;
+ pSpuIrq[1]=0;
+ iSPUIRQWait=1;
+ dwNewChannel2[0]=0;
+ dwNewChannel2[1]=0;
+ dwEndChannel2[0]=0;
+ dwEndChannel2[1]=0;
+ spuCtrl2[0]=0;
+ spuCtrl2[1]=0;
+ spuStat2[0]=0;
+ spuStat2[1]=0;
+ spuIrq2[0]=0;
+ spuIrq2[1]=0;
+ spuAddr2[0]=0xffffffff;
+ spuAddr2[1]=0xffffffff;
+ spuRvbAddr2[0]=0;
+ spuRvbAddr2[1]=0;
+ spuRvbAEnd2[0]=0;
+ spuRvbAEnd2[1]=0;
+
+// ReadConfig(); // read user stuff
+
+// SetupSound(); // setup midas (before init!)
+
+ SetupStreams(); // prepare streaming
+
+ SetupTimer(); // timer for feeding data
+
+ bSPUIsOpen=1;
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// SPUCLOSE: called before shutdown
+////////////////////////////////////////////////////////////////////////
+
+EXPORT_GCC void CALLBACK SPU2close(void)
+{
+ if(!bSPUIsOpen) return; // some security
+
+ bSPUIsOpen=0; // no more open
+
+ RemoveTimer(); // no more feeding
+
+// RemoveSound(); // no more sound handling
+
+ RemoveStreams(); // no more streaming
+}
+
+////////////////////////////////////////////////////////////////////////
+// SPUSHUTDOWN: called by main emu on final exit
+////////////////////////////////////////////////////////////////////////
+
+EXPORT_GCC void CALLBACK SPU2shutdown(void)
+{
+ return;
+}
+
+////////////////////////////////////////////////////////////////////////
+// SPUTEST: we don't test, we are always fine ;)
+////////////////////////////////////////////////////////////////////////
+
+EXPORT_GCC long CALLBACK SPU2test(void)
+{
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// SETUP CALLBACKS
+// this functions will be called once,
+// passes a callback that should be called on SPU-IRQ/cdda volume change
+////////////////////////////////////////////////////////////////////////
+
+// not used yet
+EXPORT_GCC void CALLBACK SPU2irqCallback(void (CALLBACK *callback)(void))
+{
+ irqCallback = callback;
+}
+
+// not used yet
+EXPORT_GCC void CALLBACK SPU2registerCallback(void (CALLBACK *callback)(void))
+{
+ irqCallback = callback;
+}
+
+// not used yet
+EXPORT_GCC void CALLBACK SPU2registerCDDAVolume(void (CALLBACK *CDDAVcallback)(unsigned short,unsigned short))
+{
+ cddavCallback = CDDAVcallback;
+}
diff --git a/src/psf/peops2/spu.h b/src/psf/peops2/spu.h
index 94615d378134..30b4fb1b4b41 100644
--- a/src/psf/peops2/spu.h
+++ b/src/psf/peops2/spu.h
@@ -34,6 +34,6 @@ EXPORT_GCC void CALLBACK SPU2playADPCMchannel(xa_decode_t *xap);
EXPORT_GCC long CALLBACK SPU2init(void);
EXPORT_GCC long CALLBACK SPU2open(void *pDsp);
-EXPORT_GCC void CALLBACK SPU2async(unsigned long cycle);
+EXPORT_GCC void CALLBACK SPU2async(void (*update)(const void *, int));
EXPORT_GCC void CALLBACK SPU2close(void);
EXPORT_GCC int CALLBACK psf2_seek(u32 t);
diff --git a/src/psf/peops2/xa.c b/src/psf/peops2/xa.c
deleted file mode 100644
index ea48cdf83227..000000000000
--- a/src/psf/peops2/xa.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/***************************************************************************
- xa.c - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove at addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-//*************************************************************************//
-// History of changes:
-//
-// 2003/02/18 - kode54
-// - added gaussian interpolation
-//
-// 2002/05/15 - Pete
-// - generic cleanup for the Peops release
-//
-//*************************************************************************//
-
-#include "stdafx.h"
-
-#define _IN_XA
-
-// will be included from spu.c
-#ifdef _IN_SPU
-
-////////////////////////////////////////////////////////////////////////
-// XA GLOBALS
-////////////////////////////////////////////////////////////////////////
-
-xa_decode_t * xapGlobal=0;
-
-unsigned long * XAFeed = NULL;
-unsigned long * XAPlay = NULL;
-unsigned long * XAStart = NULL;
-unsigned long * XAEnd = NULL;
-
-unsigned long XARepeat = 0;
-unsigned long XALastVal = 0;
-
-int iLeftXAVol = 32767;
-int iRightXAVol = 32767;
-
-static int gauss_ptr = 0;
-static int gauss_window[8] = {0, 0, 0, 0, 0, 0, 0, 0};
-
-#define gvall0 gauss_window[gauss_ptr]
-#define gvall(x) gauss_window[(gauss_ptr+x)&3]
-#define gvalr0 gauss_window[4+gauss_ptr]
-#define gvalr(x) gauss_window[4+((gauss_ptr+x)&3)]
-
-////////////////////////////////////////////////////////////////////////
-// MIX XA
-////////////////////////////////////////////////////////////////////////
-
-inline void MixXA(void)
-{
- int ns;
-
- for(ns=0;ns<NSSIZE && XAPlay!=XAFeed;ns++)
- {
- XALastVal=*XAPlay++;
- if(XAPlay==XAEnd) XAPlay=XAStart;
- SSumL[ns]+=(((short)(XALastVal&0xffff)) * iLeftXAVol)/32767;
- SSumR[ns]+=(((short)((XALastVal>>16)&0xffff)) * iRightXAVol)/32767;
- }
-
- if(XAPlay==XAFeed && XARepeat)
- {
- XARepeat--;
- for(;ns<NSSIZE;ns++)
- {
- SSumL[ns]+=(((short)(XALastVal&0xffff)) * iLeftXAVol)/32767;
- SSumR[ns]+=(((short)((XALastVal>>16)&0xffff)) * iRightXAVol)/32767;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// FEED XA
-////////////////////////////////////////////////////////////////////////
-
-inline void FeedXA(xa_decode_t *xap)
-{
- int sinc,spos,i,iSize,iPlace,vl,vr;
-
- if(!bSPUIsOpen) return;
-
- xapGlobal = xap; // store info for save states
- XARepeat = 100; // set up repeat
-
- iSize=((44100*xap->nsamples)/xap->freq); // get size
- if(!iSize) return; // none? bye
-
- if(XAFeed<XAPlay) iPlace=XAPlay-XAFeed; // how much space in my buf?
- else iPlace=(XAEnd-XAFeed) + (XAPlay-XAStart);
-
- if(iPlace==0) return; // no place at all
-
- //----------------------------------------------------//
- if(iXAPitch) // pitch change option?
- {
- static DWORD dwLT=0;
- static DWORD dwFPS=0;
- static int iFPSCnt=0;
- static int iLastSize=0;
- static DWORD dwL1=0;
- DWORD dw=timeGetTime(),dw1,dw2;
-
- iPlace=iSize;
-
- dwFPS+=dw-dwLT;iFPSCnt++;
-
- dwLT=dw;
-
- if(iFPSCnt>=10)
- {
- if(!dwFPS) dwFPS=1;
- dw1=1000000/dwFPS;
- if(dw1>=(dwL1-100) && dw1<=(dwL1+100)) dw1=dwL1;
- else dwL1=dw1;
- dw2=(xap->freq*100/xap->nsamples);
- if((!dw1)||((dw2+100)>=dw1)) iLastSize=0;
- else
- {
- iLastSize=iSize*dw2/dw1;
- if(iLastSize>iPlace) iLastSize=iPlace;
- iSize=iLastSize;
- }
- iFPSCnt=0;dwFPS=0;
- }
- else
- {
- if(iLastSize) iSize=iLastSize;
- }
- }
- //----------------------------------------------------//
-
- spos=0x10000L;
- sinc = (xap->nsamples << 16) / iSize; // calc freq by num / size
-
- if(xap->stereo)
- {
- unsigned long * pS=(unsigned long *)xap->pcm;
- unsigned long l=0;
-
- if(iXAPitch)
- {
- long l1,l2;short s;
- for(i=0;i<iSize;i++)
- {
- if(iUseInterpolation==2)
- {
- while(spos>=0x10000L)
- {
- l = *pS++;
- gauss_window[gauss_ptr] = (short)LOWWORD(l);
- gauss_window[4+gauss_ptr] = (short)HIGHWORD(l);
- gauss_ptr = (gauss_ptr+1) & 3;
- spos -= 0x10000L;
- }
- vl = (spos >> 6) & ~3;
- vr=(gauss[vl]*gvall0)&~2047;
- vr+=(gauss[vl+1]*gvall(1))&~2047;
- vr+=(gauss[vl+2]*gvall(2))&~2047;
- vr+=(gauss[vl+3]*gvall(3))&~2047;
- l= (vr >> 11) & 0xffff;
- vr=(gauss[vl]*gvalr0)&~2047;
- vr+=(gauss[vl+1]*gvalr(1))&~2047;
- vr+=(gauss[vl+2]*gvalr(2))&~2047;
- vr+=(gauss[vl+3]*gvalr(3))&~2047;
- l |= vr << 5;
- }
- else
- {
- while(spos>=0x10000L)
- {
- l = *pS++;
- spos -= 0x10000L;
- }
- }
-
- s=(short)LOWWORD(l);
- l1=s;
- l1=(l1*iPlace)/iSize;
- if(l1<-32767) l1=-32767;
- if(l1> 32767) l1=32767;
- s=(short)HIGHWORD(l);
- l2=s;
- l2=(l2*iPlace)/iSize;
- if(l2<-32767) l2=-32767;
- if(l2> 32767) l2=32767;
- l=(l1&0xffff)|(l2<<16);
-
- *XAFeed++=l;
-
- if(XAFeed==XAEnd) XAFeed=XAStart;
- if(XAFeed==XAPlay)
- {
- if(XAPlay!=XAStart) XAFeed=XAPlay-1;
- break;
- }
-
- spos += sinc;
- }
- }
- else
- {
- for(i=0;i<iSize;i++)
- {
- if(iUseInterpolation==2)
- {
- while(spos>=0x10000L)
- {
- l = *pS++;
- gauss_window[gauss_ptr] = (short)LOWWORD(l);
- gauss_window[4+gauss_ptr] = (short)HIGHWORD(l);
- gauss_ptr = (gauss_ptr+1) & 3;
- spos -= 0x10000L;
- }
- vl = (spos >> 6) & ~3;
- vr=(gauss[vl]*gvall0)&~2047;
- vr+=(gauss[vl+1]*gvall(1))&~2047;
- vr+=(gauss[vl+2]*gvall(2))&~2047;
- vr+=(gauss[vl+3]*gvall(3))&~2047;
- l= (vr >> 11) & 0xffff;
- vr=(gauss[vl]*gvalr0)&~2047;
- vr+=(gauss[vl+1]*gvalr(1))&~2047;
- vr+=(gauss[vl+2]*gvalr(2))&~2047;
- vr+=(gauss[vl+3]*gvalr(3))&~2047;
- l |= vr << 5;
- }
- else
- {
- while(spos>=0x10000L)
- {
- l = *pS++;
- spos -= 0x10000L;
- }
- }
-
- *XAFeed++=l;
-
- if(XAFeed==XAEnd) XAFeed=XAStart;
- if(XAFeed==XAPlay)
- {
- if(XAPlay!=XAStart) XAFeed=XAPlay-1;
- break;
- }
-
- spos += sinc;
- }
- }
- }
- else
- {
- unsigned short * pS=(unsigned short *)xap->pcm;
- unsigned long l;short s=0;
-
- if(iXAPitch)
- {
- long l1;
- for(i=0;i<iSize;i++)
- {
- if(iUseInterpolation==2)
- {
- while(spos>=0x10000L)
- {
- gauss_window[gauss_ptr] = (short)*pS++;
- gauss_ptr = (gauss_ptr+1) & 3;
- spos -= 0x10000L;
- }
- vl = (spos >> 6) & ~3;
- vr=(gauss[vl]*gvall0)&~2047;
- vr+=(gauss[vl+1]*gvall(1))&~2047;
- vr+=(gauss[vl+2]*gvall(2))&~2047;
- vr+=(gauss[vl+3]*gvall(3))&~2047;
- l1=s= vr >> 11;
- l1 &= 0xffff;
- }
- else
- {
- while(spos>=0x10000L)
- {
- s = *pS++;
- spos -= 0x10000L;
- }
- l1=s;
- }
-
- l1=(l1*iPlace)/iSize;
- if(l1<-32767) l1=-32767;
- if(l1> 32767) l1=32767;
- l=(l1&0xffff)|(l1<<16);
- *XAFeed++=l;
-
- if(XAFeed==XAEnd) XAFeed=XAStart;
- if(XAFeed==XAPlay)
- {
- if(XAPlay!=XAStart) XAFeed=XAPlay-1;
- break;
- }
-
- spos += sinc;
- }
- }
- else
- {
- for(i=0;i<iSize;i++)
- {
- if(iUseInterpolation==2)
- {
- while(spos>=0x10000L)
- {
- gauss_window[gauss_ptr] = (short)*pS++;
- gauss_ptr = (gauss_ptr+1) & 3;
- spos -= 0x10000L;
- }
- vl = (spos >> 6) & ~3;
- vr=(gauss[vl]*gvall0)&~2047;
- vr+=(gauss[vl+1]*gvall(1))&~2047;
- vr+=(gauss[vl+2]*gvall(2))&~2047;
- vr+=(gauss[vl+3]*gvall(3))&~2047;
- l=s= vr >> 11;
- l &= 0xffff;
- }
- else
- {
- while(spos>=0x10000L)
- {
- s = *pS++;
- spos -= 0x10000L;
- }
- l=s;
- }
-
- *XAFeed++=(l|(l<<16));
-
- if(XAFeed==XAEnd) XAFeed=XAStart;
- if(XAFeed==XAPlay)
- {
- if(XAPlay!=XAStart) XAFeed=XAPlay-1;
- break;
- }
-
- spos += sinc;
- }
- }
- }
-}
-
-#endif
-
diff --git a/src/psf/peops2/xa.cc b/src/psf/peops2/xa.cc
new file mode 100644
index 000000000000..4d0ba317bc45
--- /dev/null
+++ b/src/psf/peops2/xa.cc
@@ -0,0 +1,363 @@
+/***************************************************************************
+ xa.c - description
+ -------------------
+ begin : Wed May 15 2002
+ copyright : (C) 2002 by Pete Bernert
+ email : BlackDove at addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+//*************************************************************************//
+// History of changes:
+//
+// 2003/02/18 - kode54
+// - added gaussian interpolation
+//
+// 2002/05/15 - Pete
+// - generic cleanup for the Peops release
+//
+//*************************************************************************//
+
+#include "stdafx.h"
+
+#define _IN_XA
+
+// will be included from spu.c
+#ifdef _IN_SPU
+
+////////////////////////////////////////////////////////////////////////
+// XA GLOBALS
+////////////////////////////////////////////////////////////////////////
+
+xa_decode_t * xapGlobal=0;
+
+unsigned long * XAFeed = nullptr;
+unsigned long * XAPlay = nullptr;
+unsigned long * XAStart = nullptr;
+unsigned long * XAEnd = nullptr;
+
+unsigned long XARepeat = 0;
+unsigned long XALastVal = 0;
+
+int iLeftXAVol = 32767;
+int iRightXAVol = 32767;
+
+static int gauss_ptr = 0;
+static int gauss_window[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+#define gvall0 gauss_window[gauss_ptr]
+#define gvall(x) gauss_window[(gauss_ptr+x)&3]
+#define gvalr0 gauss_window[4+gauss_ptr]
+#define gvalr(x) gauss_window[4+((gauss_ptr+x)&3)]
+
+////////////////////////////////////////////////////////////////////////
+// MIX XA
+////////////////////////////////////////////////////////////////////////
+
+inline void MixXA(void)
+{
+ int ns;
+
+ for(ns=0;ns<NSSIZE && XAPlay!=XAFeed;ns++)
+ {
+ XALastVal=*XAPlay++;
+ if(XAPlay==XAEnd) XAPlay=XAStart;
+ SSumL[ns]+=(((short)(XALastVal&0xffff)) * iLeftXAVol)/32767;
+ SSumR[ns]+=(((short)((XALastVal>>16)&0xffff)) * iRightXAVol)/32767;
+ }
+
+ if(XAPlay==XAFeed && XARepeat)
+ {
+ XARepeat--;
+ for(;ns<NSSIZE;ns++)
+ {
+ SSumL[ns]+=(((short)(XALastVal&0xffff)) * iLeftXAVol)/32767;
+ SSumR[ns]+=(((short)((XALastVal>>16)&0xffff)) * iRightXAVol)/32767;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// FEED XA
+////////////////////////////////////////////////////////////////////////
+
+inline void FeedXA(xa_decode_t *xap)
+{
+ int sinc,spos,i,iSize,iPlace,vl,vr;
+
+ if(!bSPUIsOpen) return;
+
+ xapGlobal = xap; // store info for save states
+ XARepeat = 100; // set up repeat
+
+ iSize=((44100*xap->nsamples)/xap->freq); // get size
+ if(!iSize) return; // none? bye
+
+ if(XAFeed<XAPlay) iPlace=XAPlay-XAFeed; // how much space in my buf?
+ else iPlace=(XAEnd-XAFeed) + (XAPlay-XAStart);
+
+ if(iPlace==0) return; // no place at all
+
+ //----------------------------------------------------//
+ if(iXAPitch) // pitch change option?
+ {
+ static DWORD dwLT=0;
+ static DWORD dwFPS=0;
+ static int iFPSCnt=0;
+ static int iLastSize=0;
+ static DWORD dwL1=0;
+ DWORD dw=timeGetTime(),dw1,dw2;
+
+ iPlace=iSize;
+
+ dwFPS+=dw-dwLT;iFPSCnt++;
+
+ dwLT=dw;
+
+ if(iFPSCnt>=10)
+ {
+ if(!dwFPS) dwFPS=1;
+ dw1=1000000/dwFPS;
+ if(dw1>=(dwL1-100) && dw1<=(dwL1+100)) dw1=dwL1;
+ else dwL1=dw1;
+ dw2=(xap->freq*100/xap->nsamples);
+ if((!dw1)||((dw2+100)>=dw1)) iLastSize=0;
+ else
+ {
+ iLastSize=iSize*dw2/dw1;
+ if(iLastSize>iPlace) iLastSize=iPlace;
+ iSize=iLastSize;
+ }
+ iFPSCnt=0;dwFPS=0;
+ }
+ else
+ {
+ if(iLastSize) iSize=iLastSize;
+ }
+ }
+ //----------------------------------------------------//
+
+ spos=0x10000L;
+ sinc = (xap->nsamples << 16) / iSize; // calc freq by num / size
+
+ if(xap->stereo)
+ {
+ unsigned long * pS=(unsigned long *)xap->pcm;
+ unsigned long l=0;
+
+ if(iXAPitch)
+ {
+ long l1,l2;short s;
+ for(i=0;i<iSize;i++)
+ {
+ if(iUseInterpolation==2)
+ {
+ while(spos>=0x10000L)
+ {
+ l = *pS++;
+ gauss_window[gauss_ptr] = (short)LOWWORD(l);
+ gauss_window[4+gauss_ptr] = (short)HIGHWORD(l);
+ gauss_ptr = (gauss_ptr+1) & 3;
+ spos -= 0x10000L;
+ }
+ vl = (spos >> 6) & ~3;
+ vr=(gauss[vl]*gvall0)&~2047;
+ vr+=(gauss[vl+1]*gvall(1))&~2047;
+ vr+=(gauss[vl+2]*gvall(2))&~2047;
+ vr+=(gauss[vl+3]*gvall(3))&~2047;
+ l= (vr >> 11) & 0xffff;
+ vr=(gauss[vl]*gvalr0)&~2047;
+ vr+=(gauss[vl+1]*gvalr(1))&~2047;
+ vr+=(gauss[vl+2]*gvalr(2))&~2047;
+ vr+=(gauss[vl+3]*gvalr(3))&~2047;
+ l |= vr << 5;
+ }
+ else
+ {
+ while(spos>=0x10000L)
+ {
+ l = *pS++;
+ spos -= 0x10000L;
+ }
+ }
+
+ s=(short)LOWWORD(l);
+ l1=s;
+ l1=(l1*iPlace)/iSize;
+ if(l1<-32767) l1=-32767;
+ if(l1> 32767) l1=32767;
+ s=(short)HIGHWORD(l);
+ l2=s;
+ l2=(l2*iPlace)/iSize;
+ if(l2<-32767) l2=-32767;
+ if(l2> 32767) l2=32767;
+ l=(l1&0xffff)|(l2<<16);
+
+ *XAFeed++=l;
+
+ if(XAFeed==XAEnd) XAFeed=XAStart;
+ if(XAFeed==XAPlay)
+ {
+ if(XAPlay!=XAStart) XAFeed=XAPlay-1;
+ break;
+ }
+
+ spos += sinc;
+ }
+ }
+ else
+ {
+ for(i=0;i<iSize;i++)
+ {
+ if(iUseInterpolation==2)
+ {
+ while(spos>=0x10000L)
+ {
+ l = *pS++;
+ gauss_window[gauss_ptr] = (short)LOWWORD(l);
+ gauss_window[4+gauss_ptr] = (short)HIGHWORD(l);
+ gauss_ptr = (gauss_ptr+1) & 3;
+ spos -= 0x10000L;
+ }
+ vl = (spos >> 6) & ~3;
+ vr=(gauss[vl]*gvall0)&~2047;
+ vr+=(gauss[vl+1]*gvall(1))&~2047;
+ vr+=(gauss[vl+2]*gvall(2))&~2047;
+ vr+=(gauss[vl+3]*gvall(3))&~2047;
+ l= (vr >> 11) & 0xffff;
+ vr=(gauss[vl]*gvalr0)&~2047;
+ vr+=(gauss[vl+1]*gvalr(1))&~2047;
+ vr+=(gauss[vl+2]*gvalr(2))&~2047;
+ vr+=(gauss[vl+3]*gvalr(3))&~2047;
+ l |= vr << 5;
+ }
+ else
+ {
+ while(spos>=0x10000L)
+ {
+ l = *pS++;
+ spos -= 0x10000L;
+ }
+ }
+
+ *XAFeed++=l;
+
+ if(XAFeed==XAEnd) XAFeed=XAStart;
+ if(XAFeed==XAPlay)
+ {
+ if(XAPlay!=XAStart) XAFeed=XAPlay-1;
+ break;
+ }
+
+ spos += sinc;
+ }
+ }
+ }
+ else
+ {
+ unsigned short * pS=(unsigned short *)xap->pcm;
+ unsigned long l;short s=0;
+
+ if(iXAPitch)
+ {
+ long l1;
+ for(i=0;i<iSize;i++)
+ {
+ if(iUseInterpolation==2)
+ {
+ while(spos>=0x10000L)
+ {
+ gauss_window[gauss_ptr] = (short)*pS++;
+ gauss_ptr = (gauss_ptr+1) & 3;
+ spos -= 0x10000L;
+ }
+ vl = (spos >> 6) & ~3;
+ vr=(gauss[vl]*gvall0)&~2047;
+ vr+=(gauss[vl+1]*gvall(1))&~2047;
+ vr+=(gauss[vl+2]*gvall(2))&~2047;
+ vr+=(gauss[vl+3]*gvall(3))&~2047;
+ l1=s= vr >> 11;
+ l1 &= 0xffff;
+ }
+ else
+ {
+ while(spos>=0x10000L)
+ {
+ s = *pS++;
+ spos -= 0x10000L;
+ }
+ l1=s;
+ }
+
+ l1=(l1*iPlace)/iSize;
+ if(l1<-32767) l1=-32767;
+ if(l1> 32767) l1=32767;
+ l=(l1&0xffff)|(l1<<16);
+ *XAFeed++=l;
+
+ if(XAFeed==XAEnd) XAFeed=XAStart;
+ if(XAFeed==XAPlay)
+ {
+ if(XAPlay!=XAStart) XAFeed=XAPlay-1;
+ break;
+ }
+
+ spos += sinc;
+ }
+ }
+ else
+ {
+ for(i=0;i<iSize;i++)
+ {
+ if(iUseInterpolation==2)
+ {
+ while(spos>=0x10000L)
+ {
+ gauss_window[gauss_ptr] = (short)*pS++;
+ gauss_ptr = (gauss_ptr+1) & 3;
+ spos -= 0x10000L;
+ }
+ vl = (spos >> 6) & ~3;
+ vr=(gauss[vl]*gvall0)&~2047;
+ vr+=(gauss[vl+1]*gvall(1))&~2047;
+ vr+=(gauss[vl+2]*gvall(2))&~2047;
+ vr+=(gauss[vl+3]*gvall(3))&~2047;
+ l=s= vr >> 11;
+ l &= 0xffff;
+ }
+ else
+ {
+ while(spos>=0x10000L)
+ {
+ s = *pS++;
+ spos -= 0x10000L;
+ }
+ l=s;
+ }
+
+ *XAFeed++=(l|(l<<16));
+
+ if(XAFeed==XAEnd) XAFeed=XAStart;
+ if(XAFeed==XAPlay)
+ {
+ if(XAPlay!=XAStart) XAFeed=XAPlay-1;
+ break;
+ }
+
+ spos += sinc;
+ }
+ }
+ }
+}
+
+#endif
+
diff --git a/src/psf/plugin.c b/src/psf/plugin.c
deleted file mode 100644
index 88e7499f91d8..000000000000
--- a/src/psf/plugin.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- Audio Overload SDK - main driver. for demonstration only, not user friendly!
-
- Copyright (c) 2007-2008 R. Belmont and Richard Bannister.
-
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-#include "ao.h"
-#include "corlett.h"
-#include "eng_protos.h"
-
-typedef enum {
- ENG_NONE = 0,
- ENG_PSF1,
- ENG_PSF2,
- ENG_SPX,
- ENG_COUNT
-} PSFEngine;
-
-typedef struct {
- int32_t (*start)(uint8_t *buffer, uint32_t length);
- int32_t (*stop)(void);
- int32_t (*seek)(uint32_t);
- int32_t (*execute)(void);
-} PSFEngineFunctors;
-
-static PSFEngineFunctors psf_functor_map[ENG_COUNT] = {
- {NULL, NULL, NULL, NULL},
- {psf_start, psf_stop, psf_seek, psf_execute},
- {psf2_start, psf2_stop, psf2_seek, psf2_execute},
- {spx_start, spx_stop, psf_seek, spx_execute},
-};
-
-static PSFEngineFunctors *f;
-static const char *dirpath;
-
-bool_t stop_flag = FALSE;
-
-static PSFEngine psf_probe(uint8_t *buffer)
-{
- if (!memcmp(buffer, "PSF\x01", 4))
- return ENG_PSF1;
-
- if (!memcmp(buffer, "PSF\x02", 4))
- return ENG_PSF2;
-
- if (!memcmp(buffer, "SPU", 3))
- return ENG_SPX;
-
- if (!memcmp(buffer, "SPX", 3))
- return ENG_SPX;
-
- return ENG_NONE;
-}
-
-/* ao_get_lib: called to load secondary files */
-int ao_get_lib(char *filename, uint8_t **buffer, uint64_t *length)
-{
- void *filebuf;
- int64_t size;
-
- SPRINTF(path2, "%s/%s", dirpath, filename);
- vfs_file_get_contents(path2, &filebuf, &size);
-
- *buffer = filebuf;
- *length = (uint64_t)size;
-
- return AO_SUCCESS;
-}
-
-Tuple *psf2_tuple(const char *filename, VFSFile *file)
-{
- Tuple *t;
- corlett_t *c;
- void *buf;
- int64_t sz;
-
- vfs_file_get_contents (filename, & buf, & sz);
-
- if (!buf)
- return NULL;
-
- if (corlett_decode(buf, sz, NULL, NULL, &c) != AO_SUCCESS)
- return NULL;
-
- t = tuple_new_from_filename(filename);
-
- tuple_set_int(t, FIELD_LENGTH, c->inf_length ? psfTimeToMS(c->inf_length) + psfTimeToMS(c->inf_fade) : -1);
- tuple_set_str(t, FIELD_ARTIST, c->inf_artist);
- tuple_set_str(t, FIELD_ALBUM, c->inf_game);
- tuple_set_str(t, FIELD_TITLE, c->inf_title);
- tuple_set_str(t, FIELD_COPYRIGHT, c->inf_copy);
- tuple_set_str(t, FIELD_QUALITY, _("sequenced"));
- tuple_set_str(t, FIELD_CODEC, "PlayStation 1/2 Audio");
-
- free(c);
- free(buf);
-
- return t;
-}
-
-static bool_t psf2_play(const char * filename, VFSFile * file)
-{
- void *buffer;
- int64_t size;
- PSFEngine eng;
- bool_t error = FALSE;
-
- const char * slash = strrchr (filename, '/');
- if (! slash)
- return FALSE;
-
- SNCOPY (dirbuf, filename, slash + 1 - filename);
- dirpath = dirbuf;
-
- vfs_file_get_contents (filename, & buffer, & size);
-
- eng = psf_probe(buffer);
- if (eng == ENG_NONE || eng == ENG_COUNT)
- {
- free(buffer);
- return FALSE;
- }
-
- f = &psf_functor_map[eng];
- if (f->start(buffer, size) != AO_SUCCESS)
- {
- free(buffer);
- return FALSE;
- }
-
- aud_input_open_audio(FMT_S16_NE, 44100, 2);
-
- aud_input_set_bitrate(44100*2*2*8);
-
- stop_flag = FALSE;
-
- f->execute();
- f->stop();
-
- f = NULL;
- dirpath = NULL;
- free(buffer);
-
- return ! error;
-}
-
-void psf2_update(unsigned char *buffer, long count)
-{
- if (! buffer || aud_input_check_stop ())
- {
- stop_flag = TRUE;
- return;
- }
-
- int seek = aud_input_check_seek ();
-
- if (seek >= 0)
- {
- f->seek (seek);
- return;
- }
-
- aud_input_write_audio (buffer, count);
-}
-
-int psf2_is_our_fd(const char *filename, VFSFile *file)
-{
- uint8_t magic[4];
- if (vfs_fread(magic, 1, 4, file) < 4)
- return FALSE;
-
- return (psf_probe(magic) != ENG_NONE);
-}
-
-static const char *psf2_fmts[] = { "psf", "minipsf", "psf2", "minipsf2", "spu", "spx", NULL };
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("OpenPSF PSF1/PSF2 Decoder"),
- .domain = PACKAGE,
- .play = psf2_play,
- .probe_for_tuple = psf2_tuple,
- .is_our_file_from_vfs = psf2_is_our_fd,
- .extensions = psf2_fmts,
-)
diff --git a/src/psf/plugin.cc b/src/psf/plugin.cc
new file mode 100644
index 000000000000..1975d76568f3
--- /dev/null
+++ b/src/psf/plugin.cc
@@ -0,0 +1,215 @@
+/*
+ Audio Overload SDK - main driver. for demonstration only, not user friendly!
+
+ Copyright (c) 2007-2008 R. Belmont and Richard Bannister.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/audstrings.h>
+
+#include "ao.h"
+#include "corlett.h"
+#include "eng_protos.h"
+
+class PSFPlugin : public InputPlugin
+{
+public:
+ static const char *const exts[];
+
+ static constexpr PluginInfo info = {
+ N_("OpenPSF PSF1/PSF2 Decoder"),
+ PACKAGE
+ };
+
+ static constexpr auto iinfo = InputInfo()
+ .with_exts(exts);
+
+ constexpr PSFPlugin() : InputPlugin(info, iinfo) {}
+
+ bool is_our_file(const char *filename, VFSFile &file);
+ Tuple read_tuple(const char *filename, VFSFile &file);
+ bool play(const char *filename, VFSFile &file);
+
+protected:
+ static void update(const void *data, int bytes);
+};
+
+EXPORT PSFPlugin aud_plugin_instance;
+
+typedef enum {
+ ENG_NONE = 0,
+ ENG_PSF1,
+ ENG_PSF2,
+ ENG_SPX,
+ ENG_COUNT
+} PSFEngine;
+
+typedef struct {
+ int32_t (*start)(uint8_t *buffer, uint32_t length);
+ int32_t (*stop)(void);
+ int32_t (*seek)(uint32_t);
+ int32_t (*execute)(void (*update)(const void *, int));
+} PSFEngineFunctors;
+
+static PSFEngineFunctors psf_functor_map[ENG_COUNT] = {
+ {nullptr, nullptr, nullptr, nullptr},
+ {psf_start, psf_stop, psf_seek, psf_execute},
+ {psf2_start, psf2_stop, psf2_seek, psf2_execute},
+ {spx_start, spx_stop, psf_seek, spx_execute},
+};
+
+static PSFEngineFunctors *f;
+static String dirpath;
+
+bool stop_flag = false;
+
+static PSFEngine psf_probe(const char *buf, int len)
+{
+ if (len < 4)
+ return ENG_NONE;
+
+ if (!memcmp(buf, "PSF\x01", 4))
+ return ENG_PSF1;
+
+ if (!memcmp(buf, "PSF\x02", 4))
+ return ENG_PSF2;
+
+ if (!memcmp(buf, "SPU", 3))
+ return ENG_SPX;
+
+ if (!memcmp(buf, "SPX", 3))
+ return ENG_SPX;
+
+ return ENG_NONE;
+}
+
+/* ao_get_lib: called to load secondary files */
+Index<char> ao_get_lib(char *filename)
+{
+ VFSFile file(filename_build({dirpath, filename}), "r");
+ return file ? file.read_all() : Index<char>();
+}
+
+Tuple PSFPlugin::read_tuple(const char *filename, VFSFile &file)
+{
+ Tuple t;
+ corlett_t *c;
+
+ Index<char> buf = file.read_all ();
+
+ if (!buf.len())
+ return t;
+
+ if (corlett_decode((uint8_t *)buf.begin(), buf.len(), nullptr, nullptr, &c) != AO_SUCCESS)
+ return t;
+
+ t.set_filename (filename);
+
+ t.set_int (Tuple::Length, psfTimeToMS(c->inf_length) + psfTimeToMS(c->inf_fade));
+ t.set_str (Tuple::Artist, c->inf_artist);
+ t.set_str (Tuple::Album, c->inf_game);
+ t.set_str (Tuple::Title, c->inf_title);
+ t.set_str (Tuple::Copyright, c->inf_copy);
+ t.set_str (Tuple::Quality, _("sequenced"));
+ t.set_str (Tuple::Codec, "PlayStation 1/2 Audio");
+
+ free(c);
+
+ return t;
+}
+
+bool PSFPlugin::play(const char *filename, VFSFile &file)
+{
+ bool error = false;
+
+ const char * slash = strrchr (filename, '/');
+ if (! slash)
+ return false;
+
+ dirpath = String (str_copy (filename, slash + 1 - filename));
+
+ Index<char> buf = file.read_all ();
+
+ PSFEngine eng = psf_probe(buf.begin(), buf.len());
+ if (eng == ENG_NONE || eng == ENG_COUNT)
+ {
+ error = true;
+ goto cleanup;
+ }
+
+ f = &psf_functor_map[eng];
+ if (f->start((uint8_t *)buf.begin(), buf.len()) != AO_SUCCESS)
+ {
+ error = true;
+ goto cleanup;
+ }
+
+ set_stream_bitrate(44100*2*2*8);
+ open_audio(FMT_S16_NE, 44100, 2);
+
+ stop_flag = false;
+
+ f->execute(update);
+ f->stop();
+
+cleanup:
+ f = nullptr;
+ dirpath = String ();
+
+ return ! error;
+}
+
+void PSFPlugin::update(const void *data, int bytes)
+{
+ if (!data || check_stop())
+ {
+ stop_flag = true;
+ return;
+ }
+
+ int seek = check_seek();
+
+ if (seek >= 0)
+ {
+ f->seek(seek);
+ return;
+ }
+
+ write_audio(data, bytes);
+}
+
+bool PSFPlugin::is_our_file(const char *filename, VFSFile &file)
+{
+ char magic[4];
+ if (file.fread (magic, 1, 4) < 4)
+ return false;
+
+ return (psf_probe(magic, 4) != ENG_NONE);
+}
+
+const char *const PSFPlugin::exts[] = { "psf", "minipsf", "psf2", "minipsf2", "spu", "spx", nullptr };
diff --git a/src/psf/psx.c b/src/psf/psx.c
deleted file mode 100644
index 9b2efe48984c..000000000000
--- a/src/psf/psx.c
+++ /dev/null
@@ -1,3005 +0,0 @@
-/*
- * Sony CXD8530AQ/CXD8530BQ/CXD8530CQ/CXD8661R
- *
- * PSX CPU emulator for the MAME project written by smf
- * Thanks to Farfetch'd for information on the delay slot bug
- *
- * The PSX CPU is a custom r3000a with a built in
- * geometry transform engine, no mmu & no data cache.
- *
- * There is a stall circuit for load delays, but
- * it doesn't work if the load occurs in a branch
- * delay slot.
- *
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include "ao.h"
-#include "cpuintrf.h"
-#include "psx.h"
-
-#define EXC_INT ( 0 )
-#define EXC_ADEL ( 4 )
-#define EXC_ADES ( 5 )
-#define EXC_SYS ( 8 )
-#define EXC_BP ( 9 )
-#define EXC_RI ( 10 )
-#define EXC_CPU ( 11 )
-#define EXC_OVF ( 12 )
-
-#define CP0_RANDOM ( 1 )
-#define CP0_BADVADDR ( 8 )
-#define CP0_SR ( 12 )
-#define CP0_CAUSE ( 13 )
-#define CP0_EPC ( 14 )
-#define CP0_PRID ( 15 )
-
-#define SR_IEC ( 1L << 0 )
-#define SR_KUC ( 1L << 1 )
-#define SR_ISC ( 1L << 16 )
-#define SR_SWC ( 1L << 17 )
-#define SR_TS ( 1L << 21 )
-#define SR_BEV ( 1L << 22 )
-#define SR_RE ( 1L << 25 )
-#define SR_CU0 ( 1L << 28 )
-#define SR_CU1 ( 1L << 29 )
-#define SR_CU2 ( 1L << 30 )
-#define SR_CU3 ( 1L << 31 )
-
-#define CAUSE_EXC ( 31L << 2 )
-#define CAUSE_IP ( 255L << 8 )
-#define CAUSE_IP2 ( 1L << 10 )
-#define CAUSE_IP3 ( 1L << 11 )
-#define CAUSE_IP4 ( 1L << 12 )
-#define CAUSE_IP5 ( 1L << 13 )
-#define CAUSE_IP6 ( 1L << 14 )
-#define CAUSE_IP7 ( 1L << 15 )
-#define CAUSE_CE ( 3L << 28 )
-#define CAUSE_CE0 ( 0L << 28 )
-#define CAUSE_CE1 ( 1L << 28 )
-#define CAUSE_CE2 ( 2L << 28 )
-#define CAUSE_BD ( 1L << 31 )
-
-extern void psx_bios_hle(uint32_t pc);
-extern void psx_iop_call(uint32_t pc, uint32_t callnum);
-extern uint8_t program_read_byte_32le(offs_t address);
-extern uint16_t program_read_word_32le(offs_t address);
-extern uint32_t program_read_dword_32le(offs_t address);
-extern void program_write_byte_32le(offs_t address, uint8_t data);
-extern void program_write_word_32le(offs_t address, uint16_t data);
-extern void program_write_dword_32le(offs_t address, uint32_t data);
-
-static uint8_t mips_reg_layout[] =
-{
- MIPS_PC, -1,
- MIPS_DELAYV, MIPS_DELAYR, -1,
- MIPS_HI, MIPS_LO, -1,
- -1,
- MIPS_R0, MIPS_R1, -1,
- MIPS_R2, MIPS_R3, -1,
- MIPS_R4, MIPS_R5, -1,
- MIPS_R6, MIPS_R7, -1,
- MIPS_R8, MIPS_R9, -1,
- MIPS_R10, MIPS_R11, -1,
- MIPS_R12, MIPS_R13, -1,
- MIPS_R14, MIPS_R15, -1,
- MIPS_R16, MIPS_R17, -1,
- MIPS_R18, MIPS_R19, -1,
- MIPS_R20, MIPS_R21, -1,
- MIPS_R22, MIPS_R23, -1,
- MIPS_R24, MIPS_R25, -1,
- MIPS_R26, MIPS_R27, -1,
- MIPS_R28, MIPS_R29, -1,
- MIPS_R30, MIPS_R31, -1,
- -1,
- MIPS_CP0R0, MIPS_CP0R1, -1,
- MIPS_CP0R2, MIPS_CP0R3, -1,
- MIPS_CP0R4, MIPS_CP0R5, -1,
- MIPS_CP0R6, MIPS_CP0R7, -1,
- MIPS_CP0R8, MIPS_CP0R9, -1,
- MIPS_CP0R10, MIPS_CP0R11, -1,
- MIPS_CP0R12, MIPS_CP0R13, -1,
- MIPS_CP0R14, MIPS_CP0R15, -1,
- MIPS_CP0R16, MIPS_CP0R17, -1,
- MIPS_CP0R18, MIPS_CP0R19, -1,
- MIPS_CP0R20, MIPS_CP0R21, -1,
- MIPS_CP0R22, MIPS_CP0R23, -1,
- MIPS_CP0R24, MIPS_CP0R25, -1,
- MIPS_CP0R26, MIPS_CP0R27, -1,
- MIPS_CP0R28, MIPS_CP0R29, -1,
- MIPS_CP0R30, MIPS_CP0R31, -1,
- -1,
- MIPS_CP2DR0, MIPS_CP2DR1, -1,
- MIPS_CP2DR2, MIPS_CP2DR3, -1,
- MIPS_CP2DR4, MIPS_CP2DR5, -1,
- MIPS_CP2DR6, MIPS_CP2DR7, -1,
- MIPS_CP2DR8, MIPS_CP2DR9, -1,
- MIPS_CP2DR10, MIPS_CP2DR11, -1,
- MIPS_CP2DR12, MIPS_CP2DR13, -1,
- MIPS_CP2DR14, MIPS_CP2DR15, -1,
- MIPS_CP2DR16, MIPS_CP2DR17, -1,
- MIPS_CP2DR18, MIPS_CP2DR19, -1,
- MIPS_CP2DR20, MIPS_CP2DR21, -1,
- MIPS_CP2DR22, MIPS_CP2DR23, -1,
- MIPS_CP2DR24, MIPS_CP2DR25, -1,
- MIPS_CP2DR26, MIPS_CP2DR27, -1,
- MIPS_CP2DR28, MIPS_CP2DR29, -1,
- MIPS_CP2DR30, MIPS_CP2DR31, -1,
- -1,
- MIPS_CP2CR0, MIPS_CP2CR1, -1,
- MIPS_CP2CR2, MIPS_CP2CR3, -1,
- MIPS_CP2CR4, MIPS_CP2CR5, -1,
- MIPS_CP2CR6, MIPS_CP2CR7, -1,
- MIPS_CP2CR8, MIPS_CP2CR9, -1,
- MIPS_CP2CR10, MIPS_CP2CR11, -1,
- MIPS_CP2CR12, MIPS_CP2CR13, -1,
- MIPS_CP2CR14, MIPS_CP2CR15, -1,
- MIPS_CP2CR16, MIPS_CP2CR17, -1,
- MIPS_CP2CR18, MIPS_CP2CR19, -1,
- MIPS_CP2CR20, MIPS_CP2CR21, -1,
- MIPS_CP2CR22, MIPS_CP2CR23, -1,
- MIPS_CP2CR24, MIPS_CP2CR25, -1,
- MIPS_CP2CR26, MIPS_CP2CR27, -1,
- MIPS_CP2CR28, MIPS_CP2CR29, -1,
- MIPS_CP2CR30, MIPS_CP2CR31,
- 0
-};
-
-static uint8_t mips_win_layout[] = {
- 45, 0,35,13, /* register window (top right) */
- 0, 0,44,13, /* disassembler window (left, upper) */
- 0,14,44, 8, /* memory #1 window (left, middle) */
- 45,14,35, 8, /* memory #2 window (lower) */
- 0,23,80, 1 /* command line window (bottom rows) */
-};
-
-#define REGPC ( 32 )
-
-typedef struct
-{
- uint32_t op;
- uint32_t pc;
- uint32_t prevpc;
- uint32_t delayv;
- uint32_t delayr;
- uint32_t hi;
- uint32_t lo;
- uint32_t r[ 32 ];
- uint32_t cp0r[ 32 ];
- PAIR cp2cr[ 32 ];
- PAIR cp2dr[ 32 ];
- int (*irq_callback)(int irqline);
-} mips_cpu_context;
-
-static mips_cpu_context mipscpu;
-
-static int mips_ICount = 0;
-
-static uint32_t mips_mtc0_writemask[]=
-{
- 0xffffffff, /* INDEX */
- 0x00000000, /* RANDOM */
- 0xffffff00, /* ENTRYLO */
- 0x00000000,
- 0xffe00000, /* CONTEXT */
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000, /* BADVADDR */
- 0x00000000,
- 0xffffffc0, /* ENTRYHI */
- 0x00000000,
- 0xf27fff3f, /* SR */
- 0x00000300, /* CAUSE */
- 0x00000000, /* EPC */
- 0x00000000, /* PRID */
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000000
-};
-
-#if 1
-void GTELOG(const char *a,...)
-{
- va_list va;
- char s_text[ 1024 ];
- va_start( va, a );
- vsprintf( s_text, a, va );
- va_end( va );
- logerror( "%08x: GTE: %08x %s\n", mipscpu.pc, INS_COFUN( mipscpu.op ), s_text );
-}
-#else
-static inline void GTELOG(const char *a, ...) {}
-#endif
-
-static uint32_t getcp2dr( int n_reg );
-static void setcp2dr( int n_reg, uint32_t n_value );
-static uint32_t getcp2cr( int n_reg );
-static void setcp2cr( int n_reg, uint32_t n_value );
-static void docop2( int gteop );
-static void mips_exception( int exception );
-
-void mips_stop( void )
-{
-#ifdef MAME_DEBUG
- extern int debug_key_pressed;
- debug_key_pressed = 1;
- CALL_MAME_DEBUG;
-#endif
-}
-
-static inline void mips_set_cp0r( int reg, uint32_t value )
-{
- mipscpu.cp0r[ reg ] = value;
- if( reg == CP0_SR || reg == CP0_CAUSE )
- {
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_IEC ) != 0 && ( mipscpu.cp0r[ CP0_SR ] & mipscpu.cp0r[ CP0_CAUSE ] & CAUSE_IP ) != 0 )
- {
- mips_exception( EXC_INT );
- }
- else if( mipscpu.delayr != REGPC && ( mipscpu.pc & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, mipscpu.pc );
- }
- }
-}
-
-static inline void mips_commit_delayed_load( void )
-{
- if( mipscpu.delayr != 0 )
- {
- mipscpu.r[ mipscpu.delayr ] = mipscpu.delayv;
- mipscpu.delayr = 0;
- mipscpu.delayv = 0;
- }
-}
-
-static inline void mips_delayed_branch( uint32_t n_adr )
-{
- if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- mips_commit_delayed_load();
- mipscpu.delayr = REGPC;
- mipscpu.delayv = n_adr;
- mipscpu.pc += 4;
- }
-}
-
-static inline void mips_set_pc( unsigned val )
-{
- mipscpu.pc = val;
- change_pc( val );
- mipscpu.delayr = 0;
- mipscpu.delayv = 0;
-}
-
-static inline void mips_advance_pc( void )
-{
- if( mipscpu.delayr == REGPC )
- {
- mips_set_pc( mipscpu.delayv );
- }
- else
- {
- mips_commit_delayed_load();
- mipscpu.pc += 4;
- }
-}
-
-static inline void mips_load( uint32_t n_r, uint32_t n_v )
-{
- mips_advance_pc();
- if( n_r != 0 )
- {
- mipscpu.r[ n_r ] = n_v;
- }
-}
-
-static inline void mips_delayed_load( uint32_t n_r, uint32_t n_v )
-{
- if( mipscpu.delayr == REGPC )
- {
- mips_set_pc( mipscpu.delayv );
- mipscpu.delayr = n_r;
- mipscpu.delayv = n_v;
- }
- else
- {
- mips_commit_delayed_load();
- mipscpu.pc += 4;
- if( n_r != 0 )
- {
- mipscpu.r[ n_r ] = n_v;
- }
- }
-}
-
-static void mips_exception( int exception )
-{
- mips_set_cp0r( CP0_SR, ( mipscpu.cp0r[ CP0_SR ] & ~0x3f ) | ( ( mipscpu.cp0r[ CP0_SR ] << 2 ) & 0x3f ) );
- if( mipscpu.delayr == REGPC )
- {
- mips_set_cp0r( CP0_EPC, mipscpu.pc - 4 );
- mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_EXC ) | CAUSE_BD | ( exception << 2 ) );
- }
- else
- {
- mips_commit_delayed_load();
- mips_set_cp0r( CP0_EPC, mipscpu.pc );
- mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~( CAUSE_EXC | CAUSE_BD ) ) | ( exception << 2 ) );
- }
- if( mipscpu.cp0r[ CP0_SR ] & SR_BEV )
- {
- mips_set_pc( 0xbfc00180 );
- }
- else
- {
- mips_set_pc( 0x80000080 );
- }
-}
-
-void mips_init( void )
-{
-#if 0
- int cpu = cpu_getactivecpu();
-
- state_save_register_UINT32( "psxcpu", cpu, "op", &mipscpu.op, 1 );
- state_save_register_UINT32( "psxcpu", cpu, "pc", &mipscpu.pc, 1 );
- state_save_register_UINT32( "psxcpu", cpu, "delayv", &mipscpu.delayv, 1 );
- state_save_register_UINT32( "psxcpu", cpu, "delayr", &mipscpu.delayr, 1 );
- state_save_register_UINT32( "psxcpu", cpu, "hi", &mipscpu.hi, 1 );
- state_save_register_UINT32( "psxcpu", cpu, "lo", &mipscpu.lo, 1 );
- state_save_register_UINT32( "psxcpu", cpu, "r", &mipscpu.r[ 0 ], 32 );
- state_save_register_UINT32( "psxcpu", cpu, "cp0r", &mipscpu.cp0r[ 0 ], 32 );
- state_save_register_UINT32( "psxcpu", cpu, "cp2cr", &mipscpu.cp2cr[ 0 ].d, 32 );
- state_save_register_UINT32( "psxcpu", cpu, "cp2dr", &mipscpu.cp2dr[ 0 ].d, 32 );
-#endif
-}
-
-void mips_reset( void *param )
-{
- mips_set_cp0r( CP0_SR, ( mipscpu.cp0r[ CP0_SR ] & ~( SR_TS | SR_SWC | SR_KUC | SR_IEC ) ) | SR_BEV );
- mips_set_cp0r( CP0_RANDOM, 63 ); /* todo: */
- mips_set_cp0r( CP0_PRID, 0x00000200 ); /* todo: */
- mips_set_pc( 0xbfc00000 );
- mipscpu.prevpc = 0xffffffff;
-}
-
-static void mips_exit( void )
-{
-}
-
-void mips_shorten_frame(void)
-{
- mips_ICount = 0;
-}
-
-void psx_hw_runcounters(void);
-
-int psxcpu_verbose = 0;
-
-int mips_execute( int cycles )
-{
- uint32_t n_res;
-
- mips_ICount = cycles;
- do
- {
-// CALL_MAME_DEBUG;
-
-// psx_hw_runcounters();
-
- mipscpu.op = cpu_readop32( mipscpu.pc );
-
-#if 0
- while (mipscpu.prevpc == mipscpu.pc)
- {
- psx_hw_runcounters();
- mips_ICount--;
-
- if (mips_ICount == 0) return cycles;
- }
-#endif
-
- // if we're not in a delay slot, update
- // if we're in a delay slot and the delay instruction is not NOP, update
- if (( mipscpu.delayr == 0 ) || ((mipscpu.delayr != 0) && (mipscpu.op != 0)))
- {
- mipscpu.prevpc = mipscpu.pc;
- }
-#if 0
- if (1) //psxcpu_verbose)
- {
- printf("[%08x: %08x] [SP %08x RA %08x V0 %08x V1 %08x A0 %08x S0 %08x S1 %08x]\n", mipscpu.pc, mipscpu.op, mipscpu.r[29], mipscpu.r[31], mipscpu.r[2], mipscpu.r[3], mipscpu.r[4], mipscpu.r[ 16 ], mipscpu.r[ 17 ]);
-// psxcpu_verbose--;
- }
-#endif
- switch( INS_OP( mipscpu.op ) )
- {
- case OP_SPECIAL:
- switch( INS_FUNCT( mipscpu.op ) )
- {
- case FUNCT_HLECALL:
-// printf("HLECALL, PC = %08x\n", mipscpu.pc);
- psx_bios_hle(mipscpu.pc);
- break;
- case FUNCT_SLL:
- mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] << INS_SHAMT( mipscpu.op ) );
- break;
- case FUNCT_SRL:
- mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] >> INS_SHAMT( mipscpu.op ) );
- break;
- case FUNCT_SRA:
- mips_load( INS_RD( mipscpu.op ), (int32_t)mipscpu.r[ INS_RT( mipscpu.op ) ] >> INS_SHAMT( mipscpu.op ) );
- break;
- case FUNCT_SLLV:
- mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] << ( mipscpu.r[ INS_RS( mipscpu.op ) ] & 31 ) );
- break;
- case FUNCT_SRLV:
- mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] >> ( mipscpu.r[ INS_RS( mipscpu.op ) ] & 31 ) );
- break;
- case FUNCT_SRAV:
- mips_load( INS_RD( mipscpu.op ), (int32_t)mipscpu.r[ INS_RT( mipscpu.op ) ] >> ( mipscpu.r[ INS_RS( mipscpu.op ) ] & 31 ) );
- break;
- case FUNCT_JR:
- if( INS_RD( mipscpu.op ) != 0 )
- {
- mips_exception( EXC_RI );
- }
- else
- {
- mips_delayed_branch( mipscpu.r[ INS_RS( mipscpu.op ) ] );
- }
- break;
- case FUNCT_JALR:
- n_res = mipscpu.pc + 8;
- mips_delayed_branch( mipscpu.r[ INS_RS( mipscpu.op ) ] );
- if( INS_RD( mipscpu.op ) != 0 )
- {
- mipscpu.r[ INS_RD( mipscpu.op ) ] = n_res;
- }
- break;
- case FUNCT_SYSCALL:
- mips_exception( EXC_SYS );
- break;
- case FUNCT_BREAK:
- printf("BREAK!\n");
- exit(-1);
-// mips_exception( EXC_BP );
- mips_advance_pc();
- break;
- case FUNCT_MFHI:
- mips_load( INS_RD( mipscpu.op ), mipscpu.hi );
- break;
- case FUNCT_MTHI:
- if( INS_RD( mipscpu.op ) != 0 )
- {
- mips_exception( EXC_RI );
- }
- else
- {
- mips_advance_pc();
- mipscpu.hi = mipscpu.r[ INS_RS( mipscpu.op ) ];
- }
- break;
- case FUNCT_MFLO:
- mips_load( INS_RD( mipscpu.op ), mipscpu.lo );
- break;
- case FUNCT_MTLO:
- if( INS_RD( mipscpu.op ) != 0 )
- {
- mips_exception( EXC_RI );
- }
- else
- {
- mips_advance_pc();
- mipscpu.lo = mipscpu.r[ INS_RS( mipscpu.op ) ];
- }
- break;
- case FUNCT_MULT:
- if( INS_RD( mipscpu.op ) != 0 )
- {
- mips_exception( EXC_RI );
- }
- else
- {
- int64_t n_res64;
- n_res64 = MUL_64_32_32( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ], (int32_t)mipscpu.r[ INS_RT( mipscpu.op ) ] );
- mips_advance_pc();
- mipscpu.lo = LO32_32_64( n_res64 );
- mipscpu.hi = HI32_32_64( n_res64 );
- }
- break;
- case FUNCT_MULTU:
- if( INS_RD( mipscpu.op ) != 0 )
- {
- mips_exception( EXC_RI );
- }
- else
- {
- uint64_t n_res64;
- n_res64 = MUL_U64_U32_U32( mipscpu.r[ INS_RS( mipscpu.op ) ], mipscpu.r[ INS_RT( mipscpu.op ) ] );
- mips_advance_pc();
- mipscpu.lo = LO32_U32_U64( n_res64 );
- mipscpu.hi = HI32_U32_U64( n_res64 );
- }
- break;
- case FUNCT_DIV:
- if( INS_RD( mipscpu.op ) != 0 )
- {
- mips_exception( EXC_RI );
- }
- else
- {
- uint32_t n_div;
- uint32_t n_mod;
- if( mipscpu.r[ INS_RT( mipscpu.op ) ] != 0 )
- {
- n_div = (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] / (int32_t)mipscpu.r[ INS_RT( mipscpu.op ) ];
- n_mod = (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] % (int32_t)mipscpu.r[ INS_RT( mipscpu.op ) ];
- mips_advance_pc();
- mipscpu.lo = n_div;
- mipscpu.hi = n_mod;
- }
- else
- {
- mips_advance_pc();
- }
- }
- break;
- case FUNCT_DIVU:
- if( INS_RD( mipscpu.op ) != 0 )
- {
- mips_exception( EXC_RI );
- }
- else
- {
- uint32_t n_div;
- uint32_t n_mod;
- if( mipscpu.r[ INS_RT( mipscpu.op ) ] != 0 )
- {
- n_div = mipscpu.r[ INS_RS( mipscpu.op ) ] / mipscpu.r[ INS_RT( mipscpu.op ) ];
- n_mod = mipscpu.r[ INS_RS( mipscpu.op ) ] % mipscpu.r[ INS_RT( mipscpu.op ) ];
- mips_advance_pc();
- mipscpu.lo = n_div;
- mipscpu.hi = n_mod;
- }
- else
- {
- mips_advance_pc();
- }
- }
- break;
- case FUNCT_ADD:
- {
- n_res = mipscpu.r[ INS_RS( mipscpu.op ) ] + mipscpu.r[ INS_RT( mipscpu.op ) ];
- if( (int32_t)( ~( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ mipscpu.r[ INS_RT( mipscpu.op ) ] ) & ( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ n_res ) ) < 0 )
- {
- mips_exception( EXC_OVF );
- }
- else
- {
- mips_load( INS_RD( mipscpu.op ), n_res );
- }
- }
- break;
- case FUNCT_ADDU:
- mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] + mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- case FUNCT_SUB:
- n_res = mipscpu.r[ INS_RS( mipscpu.op ) ] - mipscpu.r[ INS_RT( mipscpu.op ) ];
- if( (int32_t)( ( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ mipscpu.r[ INS_RT( mipscpu.op ) ] ) & ( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ n_res ) ) < 0 )
- {
- mips_exception( EXC_OVF );
- }
- else
- {
- mips_load( INS_RD( mipscpu.op ), n_res );
- }
- break;
- case FUNCT_SUBU:
- mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] - mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- case FUNCT_AND:
- mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] & mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- case FUNCT_OR:
- mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] | mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- case FUNCT_XOR:
- mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] ^ mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- case FUNCT_NOR:
- mips_load( INS_RD( mipscpu.op ), ~( mipscpu.r[ INS_RS( mipscpu.op ) ] | mipscpu.r[ INS_RT( mipscpu.op ) ] ) );
- break;
- case FUNCT_SLT:
- mips_load( INS_RD( mipscpu.op ), (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] < (int32_t)mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- case FUNCT_SLTU:
- mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] < mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- default:
- mips_exception( EXC_RI );
- break;
- }
- break;
- case OP_REGIMM:
- switch( INS_RT( mipscpu.op ) )
- {
- case RT_BLTZ:
- if( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] < 0 )
- {
- mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
- }
- else
- {
- mips_advance_pc();
- }
- break;
- case RT_BGEZ:
- if( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] >= 0 )
- {
- mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
- }
- else
- {
- mips_advance_pc();
- }
- break;
- case RT_BLTZAL:
- n_res = mipscpu.pc + 8;
- if( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] < 0 )
- {
- mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
- }
- else
- {
- mips_advance_pc();
- }
- mipscpu.r[ 31 ] = n_res;
- break;
- case RT_BGEZAL:
- n_res = mipscpu.pc + 8;
- if( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] >= 0 )
- {
- mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
- }
- else
- {
- mips_advance_pc();
- }
- mipscpu.r[ 31 ] = n_res;
- break;
- }
- break;
- case OP_J:
- mips_delayed_branch( ( ( mipscpu.pc + 4 ) & 0xf0000000 ) + ( INS_TARGET( mipscpu.op ) << 2 ) );
- break;
- case OP_JAL:
- n_res = mipscpu.pc + 8;
- mips_delayed_branch( ( ( mipscpu.pc + 4 ) & 0xf0000000 ) + ( INS_TARGET( mipscpu.op ) << 2 ) );
- mipscpu.r[ 31 ] = n_res;
- break;
- case OP_BEQ:
- if( mipscpu.r[ INS_RS( mipscpu.op ) ] == mipscpu.r[ INS_RT( mipscpu.op ) ] )
- {
- mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
- }
- else
- {
- mips_advance_pc();
- }
- break;
- case OP_BNE:
- if( mipscpu.r[ INS_RS( mipscpu.op ) ] != mipscpu.r[ INS_RT( mipscpu.op ) ] )
- {
- mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
- }
- else
- {
- mips_advance_pc();
- }
- break;
- case OP_BLEZ:
- if( INS_RT( mipscpu.op ) != 0 )
- {
- mips_exception( EXC_RI );
- }
- else if( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] <= 0 )
- {
- mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
- }
- else
- {
- mips_advance_pc();
- }
- break;
- case OP_BGTZ:
- if( INS_RT( mipscpu.op ) != 0 )
- {
- mips_exception( EXC_RI );
- }
- else if( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] > 0 )
- {
- mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
- }
- else
- {
- mips_advance_pc();
- }
- break;
- case OP_ADDI:
- {
- uint32_t n_imm;
- n_imm = MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- n_res = mipscpu.r[ INS_RS( mipscpu.op ) ] + n_imm;
- if( (int32_t)( ~( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ n_imm ) & ( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ n_res ) ) < 0 )
- {
- mips_exception( EXC_OVF );
- }
- else
- {
- mips_load( INS_RT( mipscpu.op ), n_res );
- }
- }
- break;
- case OP_ADDIU:
- if (INS_RT( mipscpu.op ) == 0)
- {
- psx_iop_call(mipscpu.pc, INS_IMMEDIATE(mipscpu.op));
- mips_advance_pc();
- }
- else
- {
- mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) );
- }
- break;
- case OP_SLTI:
- mips_load( INS_RT( mipscpu.op ), (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] < MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) );
- break;
- case OP_SLTIU:
- mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] < (uint32_t)MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) );
- break;
- case OP_ANDI:
- mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] & INS_IMMEDIATE( mipscpu.op ) );
- break;
- case OP_ORI:
- mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] | INS_IMMEDIATE( mipscpu.op ) );
- break;
- case OP_XORI:
- mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] ^ INS_IMMEDIATE( mipscpu.op ) );
- break;
- case OP_LUI:
- mips_load( INS_RT( mipscpu.op ), INS_IMMEDIATE( mipscpu.op ) << 16 );
- break;
- case OP_COP0:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) != 0 && ( mipscpu.cp0r[ CP0_SR ] & SR_CU0 ) == 0 )
- {
- mips_exception( EXC_CPU );
- mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE0 );
- }
- else
- {
- switch( INS_RS( mipscpu.op ) )
- {
- case RS_MFC:
- mips_delayed_load( INS_RT( mipscpu.op ), mipscpu.cp0r[ INS_RD( mipscpu.op ) ] );
- break;
- case RS_CFC:
- /* todo: */
- logerror( "%08x: COP0 CFC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- case RS_MTC:
- n_res = ( mipscpu.cp0r[ INS_RD( mipscpu.op ) ] & ~mips_mtc0_writemask[ INS_RD( mipscpu.op ) ] ) |
- ( mipscpu.r[ INS_RT( mipscpu.op ) ] & mips_mtc0_writemask[ INS_RD( mipscpu.op ) ] );
- mips_advance_pc();
- mips_set_cp0r( INS_RD( mipscpu.op ), n_res );
- break;
- case RS_CTC:
- /* todo: */
- logerror( "%08x: COP0 CTC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- case RS_BC:
- switch( INS_RT( mipscpu.op ) )
- {
- case RT_BCF:
- /* todo: */
- logerror( "%08x: COP0 BCF not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- case RT_BCT:
- /* todo: */
- logerror( "%08x: COP0 BCT not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- default:
- /* todo: */
- logerror( "%08x: COP0 unknown command %08x\n", mipscpu.pc, mipscpu.op );
- mips_stop();
- mips_advance_pc();
- break;
- }
- break;
- default:
- switch( INS_CO( mipscpu.op ) )
- {
- case 1:
- switch( INS_CF( mipscpu.op ) )
- {
- case CF_RFE:
- mips_advance_pc();
- mips_set_cp0r( CP0_SR, ( mipscpu.cp0r[ CP0_SR ] & ~0xf ) | ( ( mipscpu.cp0r[ CP0_SR ] >> 2 ) & 0xf ) );
- break;
- default:
- /* todo: */
- logerror( "%08x: COP0 unknown command %08x\n", mipscpu.pc, mipscpu.op );
- mips_stop();
- mips_advance_pc();
- break;
- }
- break;
- default:
- /* todo: */
- logerror( "%08x: COP0 unknown command %08x\n", mipscpu.pc, mipscpu.op );
- mips_stop();
- mips_advance_pc();
- break;
- }
- break;
- }
- }
- break;
- case OP_COP1:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_CU1 ) == 0 )
- {
- mips_exception( EXC_CPU );
- mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE1 );
- }
- else
- {
- switch( INS_RS( mipscpu.op ) )
- {
- case RS_MFC:
- /* todo: */
- logerror( "%08x: COP1 BCT not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- case RS_CFC:
- /* todo: */
- logerror( "%08x: COP1 CFC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- case RS_MTC:
- /* todo: */
- logerror( "%08x: COP1 MTC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- case RS_CTC:
- /* todo: */
- logerror( "%08x: COP1 CTC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- case RS_BC:
- switch( INS_RT( mipscpu.op ) )
- {
- case RT_BCF:
- /* todo: */
- logerror( "%08x: COP1 BCF not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- case RT_BCT:
- /* todo: */
- logerror( "%08x: COP1 BCT not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- default:
- /* todo: */
- logerror( "%08x: COP1 unknown command %08x\n", mipscpu.pc, mipscpu.op );
- mips_stop();
- mips_advance_pc();
- break;
- }
- break;
- default:
- switch( INS_CO( mipscpu.op ) )
- {
- case 1:
- /* todo: */
- logerror( "%08x: COP1 unknown command %08x\n", mipscpu.pc, mipscpu.op );
- mips_stop();
- mips_advance_pc();
- break;
- default:
- /* todo: */
- logerror( "%08x: COP1 unknown command %08x\n", mipscpu.pc, mipscpu.op );
- mips_stop();
- mips_advance_pc();
- break;
- }
- break;
- }
- }
- break;
- case OP_COP2:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_CU2 ) == 0 )
- {
- mips_exception( EXC_CPU );
- mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE2 );
- }
- else
- {
- switch( INS_RS( mipscpu.op ) )
- {
- case RS_MFC:
- mips_delayed_load( INS_RT( mipscpu.op ), getcp2dr( INS_RD( mipscpu.op ) ) );
- break;
- case RS_CFC:
- mips_delayed_load( INS_RT( mipscpu.op ), getcp2cr( INS_RD( mipscpu.op ) ) );
- break;
- case RS_MTC:
- setcp2dr( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] );
- mips_advance_pc();
- break;
- case RS_CTC:
- setcp2cr( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] );
- mips_advance_pc();
- break;
- case RS_BC:
- switch( INS_RT( mipscpu.op ) )
- {
- case RT_BCF:
- /* todo: */
- logerror( "%08x: COP2 BCF not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- case RT_BCT:
- /* todo: */
- logerror( "%08x: COP2 BCT not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- default:
- /* todo: */
- logerror( "%08x: COP2 unknown command %08x\n", mipscpu.pc, mipscpu.op );
- mips_stop();
- mips_advance_pc();
- break;
- }
- break;
- default:
- switch( INS_CO( mipscpu.op ) )
- {
- case 1:
- docop2( INS_COFUN( mipscpu.op ) );
- mips_advance_pc();
- break;
- default:
- /* todo: */
- logerror( "%08x: COP2 unknown command %08x\n", mipscpu.pc, mipscpu.op );
- mips_stop();
- mips_advance_pc();
- break;
- }
- break;
- }
- }
- break;
- case OP_LB:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- logerror( "%08x: LB SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- mips_delayed_load( INS_RT( mipscpu.op ), MIPS_BYTE_EXTEND( program_read_byte_32le( n_adr ^ 3 ) ) );
- }
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- mips_delayed_load( INS_RT( mipscpu.op ), MIPS_BYTE_EXTEND( program_read_byte_32le( n_adr ) ) );
- }
- }
- break;
- case OP_LH:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- logerror( "%08x: LH SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- mips_delayed_load( INS_RT( mipscpu.op ), MIPS_WORD_EXTEND( program_read_word_32le( n_adr ^ 2 ) ) );
- }
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- mips_delayed_load( INS_RT( mipscpu.op ), MIPS_WORD_EXTEND( program_read_word_32le( n_adr ) ) );
- }
- }
- break;
- case OP_LWL:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- logerror( "%08x: LWL SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- switch( n_adr & 3 )
- {
- case 0:
- n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x00ffffff ) | ( (uint32_t)program_read_byte_32le( n_adr + 3 ) << 24 );
- break;
- case 1:
- n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x0000ffff ) | ( (uint32_t)program_read_word_32le( n_adr + 1 ) << 16 );
- break;
- case 2:
- n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x000000ff ) | ( (uint32_t)program_read_byte_32le( n_adr - 1 ) << 8 ) | ( (uint32_t)program_read_word_32le( n_adr ) << 16 );
- break;
- default:
- n_res = program_read_dword_32le( n_adr - 3 );
- break;
- }
- mips_delayed_load( INS_RT( mipscpu.op ), n_res );
- }
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- switch( n_adr & 3 )
- {
- case 0:
- n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x00ffffff ) | ( (uint32_t)program_read_byte_32le( n_adr ) << 24 );
- break;
- case 1:
- n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x0000ffff ) | ( (uint32_t)program_read_word_32le( n_adr - 1 ) << 16 );
- break;
- case 2:
- n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x000000ff ) | ( (uint32_t)program_read_word_32le( n_adr - 2 ) << 8 ) | ( (uint32_t)program_read_byte_32le( n_adr ) << 24 );
- break;
- default:
- n_res = program_read_dword_32le( n_adr - 3 );
- break;
- }
- mips_delayed_load( INS_RT( mipscpu.op ), n_res );
- }
- }
- break;
- case OP_LW:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- logerror( "%08x: LW SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
-#if 0
- if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
- {
- printf("ADEL\n");
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
-#endif
- {
- mips_delayed_load( INS_RT( mipscpu.op ), program_read_dword_32le( n_adr ) );
- }
- }
- break;
- case OP_LBU:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- logerror( "%08x: LBU SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- mips_delayed_load( INS_RT( mipscpu.op ), program_read_byte_32le( n_adr ^ 3 ) );
- }
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- mips_delayed_load( INS_RT( mipscpu.op ), program_read_byte_32le( n_adr ) );
- }
- }
- break;
- case OP_LHU:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- logerror( "%08x: LHU SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- mips_delayed_load( INS_RT( mipscpu.op ), program_read_word_32le( n_adr ^ 2 ) );
- }
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- mips_delayed_load( INS_RT( mipscpu.op ), program_read_word_32le( n_adr ) );
- }
- }
- break;
- case OP_LWR:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- logerror( "%08x: LWR SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- switch( n_adr & 3 )
- {
- case 3:
- n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xffffff00 ) | program_read_byte_32le( n_adr - 3 );
- break;
- case 2:
- n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xffff0000 ) | program_read_word_32le( n_adr - 2 );
- break;
- case 1:
- n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xff000000 ) | program_read_word_32le( n_adr - 1 ) | ( (uint32_t)program_read_byte_32le( n_adr + 1 ) << 16 );
- break;
- default:
- n_res = program_read_dword_32le( n_adr );
- break;
- }
- mips_delayed_load( INS_RT( mipscpu.op ), n_res );
- }
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- switch( n_adr & 3 )
- {
- case 3:
- n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xffffff00 ) | program_read_byte_32le( n_adr );
- break;
- case 2:
- n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xffff0000 ) | program_read_word_32le( n_adr );
- break;
- case 1:
- n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xff000000 ) | program_read_byte_32le( n_adr ) | ( (uint32_t)program_read_word_32le( n_adr + 1 ) << 8 );
- break;
- default:
- n_res = program_read_dword_32le( n_adr );
- break;
- }
- mips_delayed_load( INS_RT( mipscpu.op ), n_res );
- }
- }
- break;
- case OP_SB:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- logerror( "%08x: SB SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- mips_exception( EXC_ADES );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- program_write_byte_32le( n_adr ^ 3, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- mips_advance_pc();
- }
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- mips_exception( EXC_ADES );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- program_write_byte_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- mips_advance_pc();
- }
- }
- break;
- case OP_SH:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- logerror( "%08x: SH SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
- {
- mips_exception( EXC_ADES );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- program_write_word_32le( n_adr ^ 2, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- mips_advance_pc();
- }
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
- {
- mips_exception( EXC_ADES );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- program_write_word_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- mips_advance_pc();
- }
- }
- break;
- case OP_SWL:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- printf("SR_ISC not supported\n");
- logerror( "%08x: SWL SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- printf("permission violation?\n");
- mips_exception( EXC_ADES );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- switch( n_adr & 3 )
- {
- case 0:
- program_write_byte_32le( n_adr + 3, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 24 );
- break;
- case 1:
- program_write_word_32le( n_adr + 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 16 );
- break;
- case 2:
- program_write_byte_32le( n_adr - 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 8 );
- program_write_word_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 16 );
- break;
- case 3:
- program_write_dword_32le( n_adr - 3, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- }
- mips_advance_pc();
- }
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- printf("permission violation 2\n");
- mips_exception( EXC_ADES );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- switch( n_adr & 3 )
- {
- case 0:
- program_write_byte_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 24 );
- break;
- case 1:
- program_write_word_32le( n_adr - 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 16 );
- break;
- case 2:
- program_write_word_32le( n_adr - 2, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 8 );
- program_write_byte_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 24 );
- break;
- case 3:
- program_write_dword_32le( n_adr - 3, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- }
- mips_advance_pc();
- }
- }
- break;
- case OP_SW:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
-/* used by bootstrap
- logerror( "%08x: SW SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
-*/
- mips_advance_pc();
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if(0) // ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
- {
- mips_exception( EXC_ADES );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- program_write_dword_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- mips_advance_pc();
- }
- }
- break;
- case OP_SWR:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- logerror( "%08x: SWR SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- mips_exception( EXC_ADES );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- switch( n_adr & 3 )
- {
- case 0:
- program_write_dword_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- case 1:
- program_write_word_32le( n_adr - 1, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- program_write_byte_32le( n_adr + 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 16 );
- break;
- case 2:
- program_write_word_32le( n_adr - 2, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- case 3:
- program_write_byte_32le( n_adr - 3, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- }
- mips_advance_pc();
- }
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
- {
- mips_exception( EXC_ADES );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- switch( n_adr & 3 )
- {
- case 0:
- program_write_dword_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- case 1:
- program_write_byte_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- program_write_word_32le( n_adr + 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 8 );
- break;
- case 2:
- program_write_word_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- case 3:
- program_write_byte_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
- break;
- }
- mips_advance_pc();
- }
- }
- break;
- case OP_LWC1:
- /* todo: */
- logerror( "%08x: COP1 LWC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- case OP_LWC2:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_CU2 ) == 0 )
- {
- mips_exception( EXC_CPU );
- mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE2 );
- }
- else if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- logerror( "%08x: LWC2 SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
- {
- mips_exception( EXC_ADEL );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- /* todo: delay? */
- setcp2dr( INS_RT( mipscpu.op ), program_read_dword_32le( n_adr ) );
- mips_advance_pc();
- }
- }
- break;
- case OP_SWC1:
- /* todo: */
- logerror( "%08x: COP1 SWC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- break;
- case OP_SWC2:
- if( ( mipscpu.cp0r[ CP0_SR ] & SR_CU2 ) == 0 )
- {
- mips_exception( EXC_CPU );
- mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE2 );
- }
- else if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
- {
- /* todo: */
- logerror( "%08x: SWC2 SR_ISC not supported\n", mipscpu.pc );
- mips_stop();
- mips_advance_pc();
- }
- else
- {
- uint32_t n_adr;
- n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
- if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
- {
- mips_exception( EXC_ADES );
- mips_set_cp0r( CP0_BADVADDR, n_adr );
- }
- else
- {
- program_write_dword_32le( n_adr, getcp2dr( INS_RT( mipscpu.op ) ) );
- mips_advance_pc();
- }
- }
- break;
- default:
- printf( "%08x: unknown opcode %08x (prev %08x, RA %08x)\n", mipscpu.pc, mipscpu.op, mipscpu.prevpc, mipscpu.r[31] );
- mips_stop();
- mips_exception( EXC_RI );
- break;
- }
- mips_ICount--;
- } while( mips_ICount > 0 );
-
- return cycles - mips_ICount;
-}
-
-static void mips_get_context( void *dst )
-{
- if( dst )
- {
- *(mips_cpu_context *)dst = mipscpu;
- }
-}
-
-static void mips_set_context( void *src )
-{
- if( src )
- {
- mipscpu = *(mips_cpu_context *)src;
- change_pc( mipscpu.pc );
- }
-}
-
-static void set_irq_line( int irqline, int state )
-{
- uint32_t ip;
-
- switch( irqline )
- {
- case MIPS_IRQ0:
- ip = CAUSE_IP2;
- break;
- case MIPS_IRQ1:
- ip = CAUSE_IP3;
- break;
- case MIPS_IRQ2:
- ip = CAUSE_IP4;
- break;
- case MIPS_IRQ3:
- ip = CAUSE_IP5;
- break;
- case MIPS_IRQ4:
- ip = CAUSE_IP6;
- break;
- case MIPS_IRQ5:
- ip = CAUSE_IP7;
- break;
- default:
- return;
- }
-
- switch( state )
- {
- case CLEAR_LINE:
- mips_set_cp0r( CP0_CAUSE, mipscpu.cp0r[ CP0_CAUSE ] & ~ip );
- break;
- case ASSERT_LINE:
- mips_set_cp0r( CP0_CAUSE, mipscpu.cp0r[ CP0_CAUSE ] |= ip );
- if( mipscpu.irq_callback )
- {
- /* HOLD_LINE interrupts are not supported by the architecture.
- By acknowledging the interupt here they are treated like PULSE_LINE
- interrupts, so if the interrupt isn't enabled it will be ignored.
- There is also a problem with PULSE_LINE interrupts as the interrupt
- pending bits aren't latched the emulated code won't know what caused
- the interrupt. */
- (*mipscpu.irq_callback)( irqline );
- }
- break;
- }
-}
-
-/****************************************************************************
- * Return a formatted string for a register
- ****************************************************************************/
-
-offs_t mips_dasm( char *buffer, offs_t pc )
-{
- offs_t ret;
- change_pc( pc );
-#ifdef MAME_DEBUG
- ret = DasmMIPS( buffer, pc );
-#else
- sprintf( buffer, "$%08x", cpu_readop32( pc ) );
- ret = 4;
-#endif
- change_pc( mipscpu.pc );
- return ret;
-}
-
-/* preliminary gte code */
-
-#define VXY0 ( mipscpu.cp2dr[ 0 ].d )
-#define VX0 ( mipscpu.cp2dr[ 0 ].w.l )
-#define VY0 ( mipscpu.cp2dr[ 0 ].w.h )
-#define VZ0 ( mipscpu.cp2dr[ 1 ].w.l )
-#define VXY1 ( mipscpu.cp2dr[ 2 ].d )
-#define VX1 ( mipscpu.cp2dr[ 2 ].w.l )
-#define VY1 ( mipscpu.cp2dr[ 2 ].w.h )
-#define VZ1 ( mipscpu.cp2dr[ 3 ].w.l )
-#define VXY2 ( mipscpu.cp2dr[ 4 ].d )
-#define VX2 ( mipscpu.cp2dr[ 4 ].w.l )
-#define VY2 ( mipscpu.cp2dr[ 4 ].w.h )
-#define VZ2 ( mipscpu.cp2dr[ 5 ].w.l )
-#define RGB ( mipscpu.cp2dr[ 6 ].d )
-#define R ( mipscpu.cp2dr[ 6 ].b.l )
-#define G ( mipscpu.cp2dr[ 6 ].b.h )
-#define B ( mipscpu.cp2dr[ 6 ].b.h2 )
-#define CODE ( mipscpu.cp2dr[ 6 ].b.h3 )
-#define OTZ ( mipscpu.cp2dr[ 7 ].w.l )
-#define IR0 ( mipscpu.cp2dr[ 8 ].d )
-#define IR1 ( mipscpu.cp2dr[ 9 ].d )
-#define IR2 ( mipscpu.cp2dr[ 10 ].d )
-#define IR3 ( mipscpu.cp2dr[ 11 ].d )
-#define SXY0 ( mipscpu.cp2dr[ 12 ].d )
-#define SX0 ( mipscpu.cp2dr[ 12 ].w.l )
-#define SY0 ( mipscpu.cp2dr[ 12 ].w.h )
-#define SXY1 ( mipscpu.cp2dr[ 13 ].d )
-#define SX1 ( mipscpu.cp2dr[ 13 ].w.l )
-#define SY1 ( mipscpu.cp2dr[ 13 ].w.h )
-#define SXY2 ( mipscpu.cp2dr[ 14 ].d )
-#define SX2 ( mipscpu.cp2dr[ 14 ].w.l )
-#define SY2 ( mipscpu.cp2dr[ 14 ].w.h )
-#define SXYP ( mipscpu.cp2dr[ 15 ].d )
-#define SXP ( mipscpu.cp2dr[ 15 ].w.l )
-#define SYP ( mipscpu.cp2dr[ 15 ].w.h )
-#define SZ0 ( mipscpu.cp2dr[ 16 ].w.l )
-#define SZ1 ( mipscpu.cp2dr[ 17 ].w.l )
-#define SZ2 ( mipscpu.cp2dr[ 18 ].w.l )
-#define SZ3 ( mipscpu.cp2dr[ 19 ].w.l )
-#define RGB0 ( mipscpu.cp2dr[ 20 ].d )
-#define R0 ( mipscpu.cp2dr[ 20 ].b.l )
-#define G0 ( mipscpu.cp2dr[ 20 ].b.h )
-#define B0 ( mipscpu.cp2dr[ 20 ].b.h2 )
-#define CD0 ( mipscpu.cp2dr[ 20 ].b.h3 )
-#define RGB1 ( mipscpu.cp2dr[ 21 ].d )
-#define R1 ( mipscpu.cp2dr[ 21 ].b.l )
-#define G1 ( mipscpu.cp2dr[ 21 ].b.h )
-#define B1 ( mipscpu.cp2dr[ 21 ].b.h2 )
-#define CD1 ( mipscpu.cp2dr[ 21 ].b.h3 )
-#define RGB2 ( mipscpu.cp2dr[ 22 ].d )
-#define R2 ( mipscpu.cp2dr[ 22 ].b.l )
-#define G2 ( mipscpu.cp2dr[ 22 ].b.h )
-#define B2 ( mipscpu.cp2dr[ 22 ].b.h2 )
-#define CD2 ( mipscpu.cp2dr[ 22 ].b.h3 )
-#define RES1 ( mipscpu.cp2dr[ 23 ].d )
-#define MAC0 ( mipscpu.cp2dr[ 24 ].d )
-#define MAC1 ( mipscpu.cp2dr[ 25 ].d )
-#define MAC2 ( mipscpu.cp2dr[ 26 ].d )
-#define MAC3 ( mipscpu.cp2dr[ 27 ].d )
-#define IRGB ( mipscpu.cp2dr[ 28 ].d )
-#define ORGB ( mipscpu.cp2dr[ 29 ].d )
-#define LZCS ( mipscpu.cp2dr[ 30 ].d )
-#define LZCR ( mipscpu.cp2dr[ 31 ].d )
-
-#define D1 ( mipscpu.cp2cr[ 0 ].d )
-#define R11 ( mipscpu.cp2cr[ 0 ].w.l )
-#define R12 ( mipscpu.cp2cr[ 0 ].w.h )
-#define R13 ( mipscpu.cp2cr[ 1 ].w.l )
-#define R21 ( mipscpu.cp2cr[ 1 ].w.h )
-#define D2 ( mipscpu.cp2cr[ 2 ].d )
-#define R22 ( mipscpu.cp2cr[ 2 ].w.l )
-#define R23 ( mipscpu.cp2cr[ 2 ].w.h )
-#define R31 ( mipscpu.cp2cr[ 3 ].w.l )
-#define R32 ( mipscpu.cp2cr[ 3 ].w.h )
-#define D3 ( mipscpu.cp2cr[ 4 ].d )
-#define R33 ( mipscpu.cp2cr[ 4 ].w.l )
-#define TRX ( mipscpu.cp2cr[ 5 ].d )
-#define TRY ( mipscpu.cp2cr[ 6 ].d )
-#define TRZ ( mipscpu.cp2cr[ 7 ].d )
-#define L11 ( mipscpu.cp2cr[ 8 ].w.l )
-#define L12 ( mipscpu.cp2cr[ 8 ].w.h )
-#define L13 ( mipscpu.cp2cr[ 9 ].w.l )
-#define L21 ( mipscpu.cp2cr[ 9 ].w.h )
-#define L22 ( mipscpu.cp2cr[ 10 ].w.l )
-#define L23 ( mipscpu.cp2cr[ 10 ].w.h )
-#define L31 ( mipscpu.cp2cr[ 11 ].w.l )
-#define L32 ( mipscpu.cp2cr[ 11 ].w.h )
-#define L33 ( mipscpu.cp2cr[ 12 ].w.l )
-#define RBK ( mipscpu.cp2cr[ 13 ].d )
-#define GBK ( mipscpu.cp2cr[ 14 ].d )
-#define BBK ( mipscpu.cp2cr[ 15 ].d )
-#define LR1 ( mipscpu.cp2cr[ 16 ].w.l )
-#define LR2 ( mipscpu.cp2cr[ 16 ].w.h )
-#define LR3 ( mipscpu.cp2cr[ 17 ].w.l )
-#define LG1 ( mipscpu.cp2cr[ 17 ].w.h )
-#define LG2 ( mipscpu.cp2cr[ 18 ].w.l )
-#define LG3 ( mipscpu.cp2cr[ 18 ].w.h )
-#define LB1 ( mipscpu.cp2cr[ 19 ].w.l )
-#define LB2 ( mipscpu.cp2cr[ 19 ].w.h )
-#define LB3 ( mipscpu.cp2cr[ 20 ].w.l )
-#define RFC ( mipscpu.cp2cr[ 21 ].d )
-#define GFC ( mipscpu.cp2cr[ 22 ].d )
-#define BFC ( mipscpu.cp2cr[ 23 ].d )
-#define OFX ( mipscpu.cp2cr[ 24 ].d )
-#define OFY ( mipscpu.cp2cr[ 25 ].d )
-#define H ( mipscpu.cp2cr[ 26 ].w.l )
-#define DQA ( mipscpu.cp2cr[ 27 ].w.l )
-#define DQB ( mipscpu.cp2cr[ 28 ].d )
-#define ZSF3 ( mipscpu.cp2cr[ 29 ].w.l )
-#define ZSF4 ( mipscpu.cp2cr[ 30 ].w.l )
-#define FLAG ( mipscpu.cp2cr[ 31 ].d )
-
-static uint32_t getcp2dr( int n_reg )
-{
- if( n_reg == 1 || n_reg == 3 || n_reg == 5 || n_reg == 8 || n_reg == 9 || n_reg == 10 || n_reg == 11 )
- {
- mipscpu.cp2dr[ n_reg ].d = (int32_t)(int16_t)mipscpu.cp2dr[ n_reg ].d;
- }
- else if( n_reg == 17 || n_reg == 18 || n_reg == 19 )
- {
- mipscpu.cp2dr[ n_reg ].d = (uint32_t)(uint16_t)mipscpu.cp2dr[ n_reg ].d;
- }
- else if( n_reg == 29 )
- {
- ORGB = ( ( IR1 >> 7 ) & 0x1f ) | ( ( IR2 >> 2 ) & 0x3e0 ) | ( ( IR3 << 3 ) & 0x7c00 );
- }
- GTELOG( "get CP2DR%u=%08x", n_reg, mipscpu.cp2dr[ n_reg ].d );
- return mipscpu.cp2dr[ n_reg ].d;
-}
-
-static void setcp2dr( int n_reg, uint32_t n_value )
-{
- GTELOG( "set CP2DR%u=%08x", n_reg, n_value );
- mipscpu.cp2dr[ n_reg ].d = n_value;
-
- if( n_reg == 15 )
- {
- SXY0 = SXY1;
- SXY1 = SXY2;
- SXY2 = SXYP;
- }
- else if( n_reg == 28 )
- {
- IR1 = ( IRGB & 0x1f ) << 4;
- IR2 = ( IRGB & 0x3e0 ) >> 1;
- IR3 = ( IRGB & 0x7c00 ) >> 6;
- }
- else if( n_reg == 30 )
- {
- uint32_t n_lzcs = LZCS;
- uint32_t n_lzcr = 0;
-
- if( ( n_lzcs & 0x80000000 ) == 0 )
- {
- n_lzcs = ~n_lzcs;
- }
- while( ( n_lzcs & 0x80000000 ) != 0 )
- {
- n_lzcr++;
- n_lzcs <<= 1;
- }
- LZCR = n_lzcr;
- }
-}
-
-static uint32_t getcp2cr( int n_reg )
-{
- GTELOG( "get CP2CR%u=%08x", n_reg, mipscpu.cp2cr[ n_reg ].d );
- return mipscpu.cp2cr[ n_reg ].d;
-}
-
-static void setcp2cr( int n_reg, uint32_t n_value )
-{
- GTELOG( "set CP2CR%u=%08x", n_reg, n_value );
- mipscpu.cp2cr[ n_reg ].d = n_value;
-}
-
-static inline int32_t LIM( int32_t n_value, int32_t n_max, int32_t n_min, uint32_t n_flag )
-{
- if( n_value > n_max )
- {
- FLAG |= n_flag;
- return n_max;
- }
- else if( n_value < n_min )
- {
- FLAG |= n_flag;
- return n_min;
- }
- return n_value;
-}
-
-static inline int64_t BOUNDS( int64_t n_value, int64_t n_max, int n_maxflag, int64_t n_min, int n_minflag )
-{
- if( n_value > n_max )
- {
- FLAG |= n_maxflag;
- }
- else if( n_value < n_min )
- {
- FLAG |= n_minflag;
- }
- return n_value;
-}
-
-#define A1( a ) BOUNDS( ( a ), 0x7fffffff, 30, -(int64_t)0x80000000, ( 1 << 27 ) )
-#define A2( a ) BOUNDS( ( a ), 0x7fffffff, 29, -(int64_t)0x80000000, ( 1 << 26 ) )
-#define A3( a ) BOUNDS( ( a ), 0x7fffffff, 28, -(int64_t)0x80000000, ( 1 << 25 ) )
-#define Lm_B1( a, l ) LIM( ( a ), 0x7fff, -0x8000 * !l, ( 1 << 31 ) | ( 1 << 24 ) )
-#define Lm_B2( a, l ) LIM( ( a ), 0x7fff, -0x8000 * !l, ( 1 << 31 ) | ( 1 << 23 ) )
-#define Lm_B3( a, l ) LIM( ( a ), 0x7fff, -0x8000 * !l, ( 1 << 22 ) )
-#define Lm_C1( a ) LIM( ( a ), 0x00ff, 0x0000, ( 1 << 21 ) )
-#define Lm_C2( a ) LIM( ( a ), 0x00ff, 0x0000, ( 1 << 20 ) )
-#define Lm_C3( a ) LIM( ( a ), 0x00ff, 0x0000, ( 1 << 19 ) )
-#define Lm_D( a ) LIM( ( a ), 0xffff, 0x0000, ( 1 << 31 ) | ( 1 << 18 ) )
-
-static inline uint32_t Lm_E( uint32_t n_z )
-{
- if( n_z <= H / 2 )
- {
- n_z = H / 2;
- FLAG |= ( 1 << 31 ) | ( 1 << 17 );
- }
- if( n_z == 0 )
- {
- n_z = 1;
- }
- return n_z;
-}
-
-#define F( a ) BOUNDS( ( a ), 0x7fffffff, ( 1 << 31 ) | ( 1 << 16 ), -(int64_t)0x80000000, ( 1 << 31 ) | ( 1 << 15 ) )
-#define Lm_G1( a ) LIM( ( a ), 0x3ff, -0x400, ( 1 << 31 ) | ( 1 << 14 ) )
-#define Lm_G2( a ) LIM( ( a ), 0x3ff, -0x400, ( 1 << 31 ) | ( 1 << 13 ) )
-#define Lm_H( a ) LIM( ( a ), 0xfff, 0x000, ( 1 << 12 ) )
-
-static void docop2( int gteop )
-{
- int n_sf;
- int n_v;
- int n_lm;
- int n_pass;
- uint16_t n_v1;
- uint16_t n_v2;
- uint16_t n_v3;
- const uint16_t **p_n_mx;
- const uint32_t **p_n_cv;
- static const uint16_t n_zm = 0;
- static const uint32_t n_zc = 0;
- static const uint16_t *p_n_vx[] = { &VX0, &VX1, &VX2 };
- static const uint16_t *p_n_vy[] = { &VY0, &VY1, &VY2 };
- static const uint16_t *p_n_vz[] = { &VZ0, &VZ1, &VZ2 };
- static const uint16_t *p_n_rm[] = { &R11, &R12, &R13, &R21, &R22, &R23, &R31, &R32, &R33 };
- static const uint16_t *p_n_lm[] = { &L11, &L12, &L13, &L21, &L22, &L23, &L31, &L32, &L33 };
- static const uint16_t *p_n_cm[] = { &LR1, &LR2, &LR3, &LG1, &LG2, &LG3, &LB1, &LB2, &LB3 };
- static const uint16_t *p_n_zm[] = { &n_zm, &n_zm, &n_zm, &n_zm, &n_zm, &n_zm, &n_zm, &n_zm, &n_zm };
- static const uint16_t **p_p_n_mx[] = { p_n_rm, p_n_lm, p_n_cm, p_n_zm };
- static const uint32_t *p_n_tr[] = { &TRX, &TRY, &TRZ };
- static const uint32_t *p_n_bk[] = { &RBK, &GBK, &BBK };
- static const uint32_t *p_n_fc[] = { &RFC, &GFC, &BFC };
- static const uint32_t *p_n_zc[] = { &n_zc, &n_zc, &n_zc };
- static const uint32_t **p_p_n_cv[] = { p_n_tr, p_n_bk, p_n_fc, p_n_zc };
-
- switch( GTE_FUNCT( gteop ) )
- {
- case 0x01:
- if( gteop == 0x0180001 )
- {
- GTELOG( "RTPS" );
- FLAG = 0;
-
- MAC1 = A1( ( ( (int64_t)(int32_t)TRX << 12 ) + ( (int16_t)R11 * (int16_t)VX0 ) + ( (int16_t)R12 * (int16_t)VY0 ) + ( (int16_t)R13 * (int16_t)VZ0 ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)(int32_t)TRY << 12 ) + ( (int16_t)R21 * (int16_t)VX0 ) + ( (int16_t)R22 * (int16_t)VY0 ) + ( (int16_t)R23 * (int16_t)VZ0 ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)(int32_t)TRZ << 12 ) + ( (int16_t)R31 * (int16_t)VX0 ) + ( (int16_t)R32 * (int16_t)VY0 ) + ( (int16_t)R33 * (int16_t)VZ0 ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 0 );
- IR2 = Lm_B2( (int32_t)MAC2, 0 );
- IR3 = Lm_B3( (int32_t)MAC3, 0 );
- SZ0 = SZ1;
- SZ1 = SZ2;
- SZ2 = SZ3;
- SZ3 = Lm_D( (int32_t)MAC3 );
- SXY0 = SXY1;
- SXY1 = SXY2;
- SX2 = Lm_G1( F( (int64_t)(int32_t)OFX + ( (int64_t)(int16_t)IR1 * ( ( (uint32_t)H << 16 ) / Lm_E( SZ3 ) ) ) ) >> 16 );
- SY2 = Lm_G2( F( (int64_t)(int32_t)OFY + ( (int64_t)(int16_t)IR2 * ( ( (uint32_t)H << 16 ) / Lm_E( SZ3 ) ) ) ) >> 16 );
- MAC0 = F( (int64_t)(int32_t)DQB + ( (int64_t)(int16_t)DQA * ( ( (uint32_t)H << 16 ) / Lm_E( SZ3 ) ) ) );
- IR0 = Lm_H( (int32_t)MAC0 >> 12 );
- return;
- }
- break;
- case 0x06:
- if( gteop == 0x0400006 ||
- gteop == 0x1400006 ||
- gteop == 0x0155cc6 )
- {
- GTELOG( "NCLIP" );
- FLAG = 0;
-
- MAC0 = F( ( (int64_t)(int16_t)SX0 * (int16_t)SY1 ) + ( (int16_t)SX1 * (int16_t)SY2 ) + ( (int16_t)SX2 * (int16_t)SY0 ) - ( (int16_t)SX0 * (int16_t)SY2 ) - ( (int16_t)SX1 * (int16_t)SY0 ) - ( (int16_t)SX2 * (int16_t)SY1 ) );
- return;
- }
- break;
- case 0x0c:
- if( GTE_OP( gteop ) == 0x17 )
- {
- GTELOG( "OP" );
- n_sf = 12 * GTE_SF( gteop );
- FLAG = 0;
-
- MAC1 = A1( ( ( (int64_t)(int32_t)D2 * (int16_t)IR3 ) - ( (int64_t)(int32_t)D3 * (int16_t)IR2 ) ) >> n_sf );
- MAC2 = A2( ( ( (int64_t)(int32_t)D3 * (int16_t)IR1 ) - ( (int64_t)(int32_t)D1 * (int16_t)IR3 ) ) >> n_sf );
- MAC3 = A3( ( ( (int64_t)(int32_t)D1 * (int16_t)IR2 ) - ( (int64_t)(int32_t)D2 * (int16_t)IR1 ) ) >> n_sf );
- IR1 = Lm_B1( (int32_t)MAC1, 0 );
- IR2 = Lm_B2( (int32_t)MAC2, 0 );
- IR3 = Lm_B3( (int32_t)MAC3, 0 );
- return;
- }
- break;
- case 0x10:
- if( gteop == 0x0780010 )
- {
- GTELOG( "DPCS" );
- FLAG = 0;
-
- MAC1 = A1( ( ( (int64_t)R << 16 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)RFC - ( R << 4 ), 0 ) ) ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)G << 16 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)GFC - ( G << 4 ), 0 ) ) ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)B << 16 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)BFC - ( B << 4 ), 0 ) ) ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 0 );
- IR2 = Lm_B2( (int32_t)MAC2, 0 );
- IR3 = Lm_B3( (int32_t)MAC3, 0 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 >> 4 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 >> 4 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 >> 4 );
- return;
- }
- break;
- case 0x11:
- if( gteop == 0x0980011 )
- {
- GTELOG( "INTPL" );
- FLAG = 0;
-
- MAC1 = A1( ( ( (int64_t)(int16_t)IR1 << 12 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)RFC - (int16_t)IR1, 0 ) ) ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)(int16_t)IR2 << 12 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)GFC - (int16_t)IR2, 0 ) ) ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)(int16_t)IR3 << 12 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)BFC - (int16_t)IR3, 0 ) ) ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 0 );
- IR2 = Lm_B2( (int32_t)MAC2, 0 );
- IR3 = Lm_B3( (int32_t)MAC3, 0 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 );
- return;
- }
- break;
- case 0x12:
- if( GTE_OP( gteop ) == 0x04 )
- {
- GTELOG( "MVMVA" );
- n_sf = 12 * GTE_SF( gteop );
- p_n_mx = p_p_n_mx[ GTE_MX( gteop ) ];
- n_v = GTE_V( gteop );
- if( n_v < 3 )
- {
- n_v1 = *p_n_vx[ n_v ];
- n_v2 = *p_n_vy[ n_v ];
- n_v3 = *p_n_vz[ n_v ];
- }
- else
- {
- n_v1 = IR1;
- n_v2 = IR2;
- n_v3 = IR3;
- }
- p_n_cv = p_p_n_cv[ GTE_CV( gteop ) ];
- n_lm = GTE_LM( gteop );
- FLAG = 0;
-
- MAC1 = A1( ( ( (int64_t)(int32_t)*p_n_cv[ 0 ] << 12 ) + ( (int16_t)*p_n_mx[ 0 ] * (int16_t)n_v1 ) + ( (int16_t)*p_n_mx[ 1 ] * (int16_t)n_v2 ) + ( (int16_t)*p_n_mx[ 2 ] * (int16_t)n_v3 ) ) >> n_sf );
- MAC2 = A2( ( ( (int64_t)(int32_t)*p_n_cv[ 1 ] << 12 ) + ( (int16_t)*p_n_mx[ 3 ] * (int16_t)n_v1 ) + ( (int16_t)*p_n_mx[ 4 ] * (int16_t)n_v2 ) + ( (int16_t)*p_n_mx[ 5 ] * (int16_t)n_v3 ) ) >> n_sf );
- MAC3 = A3( ( ( (int64_t)(int32_t)*p_n_cv[ 2 ] << 12 ) + ( (int16_t)*p_n_mx[ 6 ] * (int16_t)n_v1 ) + ( (int16_t)*p_n_mx[ 7 ] * (int16_t)n_v2 ) + ( (int16_t)*p_n_mx[ 8 ] * (int16_t)n_v3 ) ) >> n_sf );
-
- IR1 = Lm_B1( (int32_t)MAC1, n_lm );
- IR2 = Lm_B2( (int32_t)MAC2, n_lm );
- IR3 = Lm_B3( (int32_t)MAC3, n_lm );
- return;
- }
- break;
- case 0x13:
- if( gteop == 0x0e80413 )
- {
- GTELOG( "NCDS" );
- FLAG = 0;
-
- MAC1 = A1( ( ( (int64_t)(int16_t)L11 * (int16_t)VX0 ) + ( (int16_t)L12 * (int16_t)VY0 ) + ( (int16_t)L13 * (int16_t)VZ0 ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)(int16_t)L21 * (int16_t)VX0 ) + ( (int16_t)L22 * (int16_t)VY0 ) + ( (int16_t)L23 * (int16_t)VZ0 ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)(int16_t)L31 * (int16_t)VX0 ) + ( (int16_t)L32 * (int16_t)VY0 ) + ( (int16_t)L33 * (int16_t)VZ0 ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- MAC1 = A1( ( ( ( (int64_t)R << 4 ) * (int16_t)IR1 ) + ( (int16_t)IR0 * Lm_B1( (int32_t)RFC - ( ( R * (int16_t)IR1 ) >> 8 ), 0 ) ) ) >> 12 );
- MAC2 = A2( ( ( ( (int64_t)G << 4 ) * (int16_t)IR2 ) + ( (int16_t)IR0 * Lm_B2( (int32_t)GFC - ( ( G * (int16_t)IR2 ) >> 8 ), 0 ) ) ) >> 12 );
- MAC3 = A3( ( ( ( (int64_t)B << 4 ) * (int16_t)IR3 ) + ( (int16_t)IR0 * Lm_B3( (int32_t)BFC - ( ( B * (int16_t)IR3 ) >> 8 ), 0 ) ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 >> 4 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 >> 4 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 >> 4 );
- return;
- }
- break;
- case 0x14:
- if( gteop == 0x1280414 )
- {
- GTELOG( "CDP" );
- FLAG = 0;
-
- MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
- IR1 = Lm_B1( MAC1, 1 );
- IR2 = Lm_B2( MAC2, 1 );
- IR3 = Lm_B3( MAC3, 1 );
- MAC1 = A1( ( ( ( (int64_t)R << 4 ) * (int16_t)IR1 ) + ( (int16_t)IR0 * Lm_B1( (int32_t)RFC - ( ( R * (int16_t)IR1 ) >> 8 ), 0 ) ) ) >> 12 );
- MAC2 = A2( ( ( ( (int64_t)G << 4 ) * (int16_t)IR2 ) + ( (int16_t)IR0 * Lm_B2( (int32_t)GFC - ( ( G * (int16_t)IR2 ) >> 8 ), 0 ) ) ) >> 12 );
- MAC3 = A3( ( ( ( (int64_t)B << 4 ) * (int16_t)IR3 ) + ( (int16_t)IR0 * Lm_B3( (int32_t)BFC - ( ( B * (int16_t)IR3 ) >> 8 ), 0 ) ) ) >> 12 );
- IR1 = Lm_B1( MAC1, 1 );
- IR2 = Lm_B2( MAC2, 1 );
- IR3 = Lm_B3( MAC3, 1 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 >> 4 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 >> 4 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 >> 4 );
- return;
- }
- break;
- case 0x16:
- if( gteop == 0x0f80416 )
- {
- GTELOG( "NCDT" );
- FLAG = 0;
-
- for( n_v = 0; n_v < 3; n_v++ )
- {
- MAC1 = A1( ( ( (int64_t)(int16_t)L11 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L12 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L13 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)(int16_t)L21 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L22 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L23 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)(int16_t)L31 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L32 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L33 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- MAC1 = A1( ( ( ( (int64_t)R << 4 ) * (int16_t)IR1 ) + ( (int16_t)IR0 * Lm_B1( (int32_t)RFC - ( ( R * (int16_t)IR1 ) >> 8 ), 0 ) ) ) >> 12 );
- MAC2 = A2( ( ( ( (int64_t)G << 4 ) * (int16_t)IR2 ) + ( (int16_t)IR0 * Lm_B2( (int32_t)GFC - ( ( G * (int16_t)IR2 ) >> 8 ), 0 ) ) ) >> 12 );
- MAC3 = A3( ( ( ( (int64_t)B << 4 ) * (int16_t)IR3 ) + ( (int16_t)IR0 * Lm_B3( (int32_t)BFC - ( ( B * (int16_t)IR3 ) >> 8 ), 0 ) ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 >> 4 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 >> 4 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 >> 4 );
- }
- return;
- }
- break;
- case 0x1b:
- if( gteop == 0x108041b )
- {
- GTELOG( "NCCS" );
- FLAG = 0;
-
- MAC1 = A1( ( ( (int64_t)(int16_t)L11 * (int16_t)VX0 ) + ( (int16_t)L12 * (int16_t)VY0 ) + ( (int16_t)L13 * (int16_t)VZ0 ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)(int16_t)L21 * (int16_t)VX0 ) + ( (int16_t)L22 * (int16_t)VY0 ) + ( (int16_t)L23 * (int16_t)VZ0 ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)(int16_t)L31 * (int16_t)VX0 ) + ( (int16_t)L32 * (int16_t)VY0 ) + ( (int16_t)L33 * (int16_t)VZ0 ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- MAC1 = A1( ( (int64_t)R * (int16_t)IR1 ) >> 8 );
- MAC2 = A2( ( (int64_t)G * (int16_t)IR2 ) >> 8 );
- MAC3 = A3( ( (int64_t)B * (int16_t)IR3 ) >> 8 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 >> 4 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 >> 4 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 >> 4 );
- return;
- }
- break;
- case 0x1c:
- if( gteop == 0x138041c )
- {
- GTELOG( "CC" );
- FLAG = 0;
-
- MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
- IR1 = Lm_B1( MAC1, 1 );
- IR2 = Lm_B2( MAC2, 1 );
- IR3 = Lm_B3( MAC3, 1 );
- MAC1 = A1( ( (int64_t)R * (int16_t)IR1 ) >> 8 );
- MAC2 = A2( ( (int64_t)G * (int16_t)IR2 ) >> 8 );
- MAC3 = A3( ( (int64_t)B * (int16_t)IR3 ) >> 8 );
- IR1 = Lm_B1( MAC1, 1 );
- IR2 = Lm_B2( MAC2, 1 );
- IR3 = Lm_B3( MAC3, 1 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 >> 4 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 >> 4 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 >> 4 );
- return;
- }
- break;
- case 0x1e:
- if( gteop == 0x0c8041e )
- {
- GTELOG( "NCS" );
- FLAG = 0;
-
- MAC1 = A1( ( ( (int64_t)(int16_t)L11 * (int16_t)VX0 ) + ( (int16_t)L12 * (int16_t)VY0 ) + ( (int16_t)L13 * (int16_t)VZ0 ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)(int16_t)L21 * (int16_t)VX0 ) + ( (int16_t)L22 * (int16_t)VY0 ) + ( (int16_t)L23 * (int16_t)VZ0 ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)(int16_t)L31 * (int16_t)VX0 ) + ( (int16_t)L32 * (int16_t)VY0 ) + ( (int16_t)L33 * (int16_t)VZ0 ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 >> 4 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 >> 4 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 >> 4 );
- return;
- }
- break;
- case 0x20:
- if( gteop == 0x0d80420 )
- {
- GTELOG( "NCT" );
- FLAG = 0;
-
- for( n_v = 0; n_v < 3; n_v++ )
- {
- MAC1 = A1( ( ( (int64_t)(int16_t)L11 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L12 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L13 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)(int16_t)L21 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L22 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L23 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)(int16_t)L31 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L32 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L33 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 >> 4 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 >> 4 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 >> 4 );
- }
- return;
- }
- break;
- case 0x28:
- if( GTE_OP( gteop ) == 0x0a && GTE_LM( gteop ) == 1 )
- {
- GTELOG( "SQR" );
- n_sf = 12 * GTE_SF( gteop );
- FLAG = 0;
-
- MAC1 = A1( ( (int64_t)(int16_t)IR1 * (int16_t)IR1 ) >> n_sf );
- MAC2 = A2( ( (int64_t)(int16_t)IR2 * (int16_t)IR2 ) >> n_sf );
- MAC3 = A3( ( (int64_t)(int16_t)IR3 * (int16_t)IR3 ) >> n_sf );
- IR1 = Lm_B1( MAC1, 1 );
- IR2 = Lm_B2( MAC2, 1 );
- IR3 = Lm_B3( MAC3, 1 );
- return;
- }
- break;
- // DCPL 0x29
- case 0x2a:
- if( gteop == 0x0f8002a )
- {
- GTELOG( "DPCT" );
- FLAG = 0;
-
- for( n_pass = 0; n_pass < 3; n_pass++ )
- {
- MAC1 = A1( ( ( (int64_t)R0 << 16 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)RFC - ( R0 << 4 ), 0 ) ) ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)G0 << 16 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)GFC - ( G0 << 4 ), 0 ) ) ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)B0 << 16 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)BFC - ( B0 << 4 ), 0 ) ) ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 0 );
- IR2 = Lm_B2( (int32_t)MAC2, 0 );
- IR3 = Lm_B3( (int32_t)MAC3, 0 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 >> 4 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 >> 4 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 >> 4 );
- }
- return;
- }
- break;
- case 0x2d:
- if( gteop == 0x158002d )
- {
- GTELOG( "AVSZ3" );
- FLAG = 0;
-
- MAC0 = F( ( (int64_t)(int16_t)ZSF3 * SZ1 ) + ( (int16_t)ZSF3 * SZ2 ) + ( (int16_t)ZSF3 * SZ3 ) );
- OTZ = Lm_D( (int32_t)MAC0 >> 12 );
- return;
- }
- break;
- case 0x2e:
- if( gteop == 0x168002e )
- {
- GTELOG( "AVSZ4" );
- FLAG = 0;
-
- MAC0 = F( ( (int64_t)(int16_t)ZSF4 * SZ0 ) + ( (int16_t)ZSF4 * SZ1 ) + ( (int16_t)ZSF4 * SZ2 ) + ( (int16_t)ZSF4 * SZ3 ) );
- OTZ = Lm_D( (int32_t)MAC0 >> 12 );
- return;
- }
- break;
- case 0x30:
- if( gteop == 0x0280030 )
- {
- GTELOG( "RTPT" );
- FLAG = 0;
-
- for( n_v = 0; n_v < 3; n_v++ )
- {
- MAC1 = A1( ( ( (int64_t)(int32_t)TRX << 12 ) + ( (int16_t)R11 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)R12 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)R13 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)(int32_t)TRY << 12 ) + ( (int16_t)R21 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)R22 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)R23 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)(int32_t)TRZ << 12 ) + ( (int16_t)R31 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)R32 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)R33 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 0 );
- IR2 = Lm_B2( (int32_t)MAC2, 0 );
- IR3 = Lm_B3( (int32_t)MAC3, 0 );
- SZ0 = SZ1;
- SZ1 = SZ2;
- SZ2 = SZ3;
- SZ3 = Lm_D( (int32_t)MAC3 );
- SXY0 = SXY1;
- SXY1 = SXY2;
- SX2 = Lm_G1( F( ( (int64_t)(int32_t)OFX + ( (int64_t)(int16_t)IR1 * ( ( (uint32_t)H << 16 ) / Lm_E( SZ3 ) ) ) ) >> 16 ) );
- SY2 = Lm_G2( F( ( (int64_t)(int32_t)OFY + ( (int64_t)(int16_t)IR2 * ( ( (uint32_t)H << 16 ) / Lm_E( SZ3 ) ) ) ) >> 16 ) );
- MAC0 = F( (int64_t)(int32_t)DQB + ( (int64_t)(int16_t)DQA * ( ( (uint32_t)H << 16 ) / Lm_E( SZ3 ) ) ) );
- IR0 = Lm_H( (int32_t)MAC0 >> 12 );
- }
- return;
- }
- break;
- case 0x3d:
- if( GTE_OP( gteop ) == 0x09 ||
- GTE_OP( gteop ) == 0x19 )
- {
- GTELOG( "GPF" );
- n_sf = 12 * GTE_SF( gteop );
- FLAG = 0;
-
- MAC1 = A1( ( (int64_t)(int16_t)IR0 * (int16_t)IR1 ) >> n_sf );
- MAC2 = A2( ( (int64_t)(int16_t)IR0 * (int16_t)IR2 ) >> n_sf );
- MAC3 = A3( ( (int64_t)(int16_t)IR0 * (int16_t)IR3 ) >> n_sf );
- IR1 = Lm_B1( (int32_t)MAC1, 0 );
- IR2 = Lm_B2( (int32_t)MAC2, 0 );
- IR3 = Lm_B3( (int32_t)MAC3, 0 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 >> 4 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 >> 4 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 >> 4 );
- return;
- }
- break;
- case 0x3e:
- if( GTE_OP( gteop ) == 0x1a )
- {
- GTELOG( "GPL" );
- n_sf = 12 * GTE_SF( gteop );
- FLAG = 0;
-
- MAC1 = A1( ( ( (int64_t)(int32_t)MAC1 << n_sf ) + ( (int16_t)IR0 * (int16_t)IR1 ) ) >> n_sf );
- MAC2 = A2( ( ( (int64_t)(int32_t)MAC2 << n_sf ) + ( (int16_t)IR0 * (int16_t)IR2 ) ) >> n_sf );
- MAC3 = A3( ( ( (int64_t)(int32_t)MAC3 << n_sf ) + ( (int16_t)IR0 * (int16_t)IR3 ) ) >> n_sf );
- IR1 = Lm_B1( (int32_t)MAC1, 0 );
- IR2 = Lm_B2( (int32_t)MAC2, 0 );
- IR3 = Lm_B3( (int32_t)MAC3, 0 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 >> 4 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 >> 4 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 >> 4 );
- return;
- }
- break;
- case 0x3f:
- if( gteop == 0x108043f ||
- gteop == 0x118043f )
- {
- GTELOG( "NCCT" );
- FLAG = 0;
-
- for( n_v = 0; n_v < 3; n_v++ )
- {
- MAC1 = A1( ( ( (int64_t)(int16_t)L11 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L12 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L13 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)(int16_t)L21 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L22 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L23 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)(int16_t)L31 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L32 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L33 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
- MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
- MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- MAC1 = A1( ( (int64_t)R * (int16_t)IR1 ) >> 8 );
- MAC2 = A2( ( (int64_t)G * (int16_t)IR2 ) >> 8 );
- MAC3 = A3( ( (int64_t)B * (int16_t)IR3 ) >> 8 );
- IR1 = Lm_B1( (int32_t)MAC1, 1 );
- IR2 = Lm_B2( (int32_t)MAC2, 1 );
- IR3 = Lm_B3( (int32_t)MAC3, 1 );
- CD0 = CD1;
- CD1 = CD2;
- CD2 = CODE;
- R0 = R1;
- R1 = R2;
- R2 = Lm_C1( (int32_t)MAC1 >> 4 );
- G0 = G1;
- G1 = G2;
- G2 = Lm_C2( (int32_t)MAC2 >> 4 );
- B0 = B1;
- B1 = B2;
- B2 = Lm_C3( (int32_t)MAC3 >> 4 );
- }
- return;
- }
- break;
- }
-// usrintf_showmessage_secs( 1, "unknown GTE op %08x", gteop );
- logerror( "%08x: unknown GTE op %08x\n", mipscpu.pc, gteop );
- mips_stop();
-}
-
-/**************************************************************************
- * Generic set_info
- **************************************************************************/
-
-void mips_set_info(uint32_t state, union cpuinfo *info)
-{
- switch (state)
- {
- /* --- the following bits of info are set as 64-bit signed integers --- */
- case CPUINFO_INT_INPUT_STATE + MIPS_IRQ0: set_irq_line(MIPS_IRQ0, info->i); break;
- case CPUINFO_INT_INPUT_STATE + MIPS_IRQ1: set_irq_line(MIPS_IRQ1, info->i); break;
- case CPUINFO_INT_INPUT_STATE + MIPS_IRQ2: set_irq_line(MIPS_IRQ2, info->i); break;
- case CPUINFO_INT_INPUT_STATE + MIPS_IRQ3: set_irq_line(MIPS_IRQ3, info->i); break;
- case CPUINFO_INT_INPUT_STATE + MIPS_IRQ4: set_irq_line(MIPS_IRQ4, info->i); break;
- case CPUINFO_INT_INPUT_STATE + MIPS_IRQ5: set_irq_line(MIPS_IRQ5, info->i); break;
-
- case CPUINFO_INT_PC: mips_set_pc( info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_PC: mips_set_pc( info->i ); break;
- case CPUINFO_INT_SP: /* no stack */ break;
- case CPUINFO_INT_REGISTER + MIPS_DELAYV: mipscpu.delayv = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_DELAYR: if( info->i <= REGPC ) mipscpu.delayr = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_HI: mipscpu.hi = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_LO: mipscpu.lo = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R0: mipscpu.r[ 0 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R1: mipscpu.r[ 1 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R2: mipscpu.r[ 2 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R3: mipscpu.r[ 3 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R4: mipscpu.r[ 4 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R5: mipscpu.r[ 5 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R6: mipscpu.r[ 6 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R7: mipscpu.r[ 7 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R8: mipscpu.r[ 8 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R9: mipscpu.r[ 9 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R10: mipscpu.r[ 10 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R11: mipscpu.r[ 11 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R12: mipscpu.r[ 12 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R13: mipscpu.r[ 13 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R14: mipscpu.r[ 14 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R15: mipscpu.r[ 15 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R16: mipscpu.r[ 16 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R17: mipscpu.r[ 17 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R18: mipscpu.r[ 18 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R19: mipscpu.r[ 19 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R20: mipscpu.r[ 20 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R21: mipscpu.r[ 21 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R22: mipscpu.r[ 22 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R23: mipscpu.r[ 23 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R24: mipscpu.r[ 24 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R25: mipscpu.r[ 25 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R26: mipscpu.r[ 26 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R27: mipscpu.r[ 27 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R28: mipscpu.r[ 28 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R29: mipscpu.r[ 29 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R30: mipscpu.r[ 30 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_R31: mipscpu.r[ 31 ] = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R0: mips_set_cp0r( 0, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R1: mips_set_cp0r( 1, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R2: mips_set_cp0r( 2, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R3: mips_set_cp0r( 3, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R4: mips_set_cp0r( 4, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R5: mips_set_cp0r( 5, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R6: mips_set_cp0r( 6, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R7: mips_set_cp0r( 7, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R8: mips_set_cp0r( 8, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R9: mips_set_cp0r( 9, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R10: mips_set_cp0r( 10, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R11: mips_set_cp0r( 11, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R12: mips_set_cp0r( 12, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R13: mips_set_cp0r( 13, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R14: mips_set_cp0r( 14, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R15: mips_set_cp0r( 15, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R16: mips_set_cp0r( 16, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R17: mips_set_cp0r( 17, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R18: mips_set_cp0r( 18, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R19: mips_set_cp0r( 19, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R20: mips_set_cp0r( 20, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R21: mips_set_cp0r( 21, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R22: mips_set_cp0r( 22, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R23: mips_set_cp0r( 23, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R24: mips_set_cp0r( 24, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R25: mips_set_cp0r( 25, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R26: mips_set_cp0r( 26, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R27: mips_set_cp0r( 27, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R28: mips_set_cp0r( 28, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R29: mips_set_cp0r( 29, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R30: mips_set_cp0r( 30, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R31: mips_set_cp0r( 31, info->i ); break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR0: mipscpu.cp2dr[ 0 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR1: mipscpu.cp2dr[ 1 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR2: mipscpu.cp2dr[ 2 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR3: mipscpu.cp2dr[ 3 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR4: mipscpu.cp2dr[ 4 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR5: mipscpu.cp2dr[ 5 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR6: mipscpu.cp2dr[ 6 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR7: mipscpu.cp2dr[ 7 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR8: mipscpu.cp2dr[ 8 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR9: mipscpu.cp2dr[ 9 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR10: mipscpu.cp2dr[ 10 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR11: mipscpu.cp2dr[ 11 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR12: mipscpu.cp2dr[ 12 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR13: mipscpu.cp2dr[ 13 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR14: mipscpu.cp2dr[ 14 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR15: mipscpu.cp2dr[ 15 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR16: mipscpu.cp2dr[ 16 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR17: mipscpu.cp2dr[ 17 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR18: mipscpu.cp2dr[ 18 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR19: mipscpu.cp2dr[ 19 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR20: mipscpu.cp2dr[ 20 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR21: mipscpu.cp2dr[ 21 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR22: mipscpu.cp2dr[ 22 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR23: mipscpu.cp2dr[ 23 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR24: mipscpu.cp2dr[ 24 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR25: mipscpu.cp2dr[ 25 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR26: mipscpu.cp2dr[ 26 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR27: mipscpu.cp2dr[ 27 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR28: mipscpu.cp2dr[ 28 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR29: mipscpu.cp2dr[ 29 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR30: mipscpu.cp2dr[ 30 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR31: mipscpu.cp2dr[ 31 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR0: mipscpu.cp2cr[ 0 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR1: mipscpu.cp2cr[ 1 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR2: mipscpu.cp2cr[ 2 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR3: mipscpu.cp2cr[ 3 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR4: mipscpu.cp2cr[ 4 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR5: mipscpu.cp2cr[ 5 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR6: mipscpu.cp2cr[ 6 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR7: mipscpu.cp2cr[ 7 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR8: mipscpu.cp2cr[ 8 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR9: mipscpu.cp2cr[ 9 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR10: mipscpu.cp2cr[ 10 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR11: mipscpu.cp2cr[ 11 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR12: mipscpu.cp2cr[ 12 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR13: mipscpu.cp2cr[ 13 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR14: mipscpu.cp2cr[ 14 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR15: mipscpu.cp2cr[ 15 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR16: mipscpu.cp2cr[ 16 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR17: mipscpu.cp2cr[ 17 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR18: mipscpu.cp2cr[ 18 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR19: mipscpu.cp2cr[ 19 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR20: mipscpu.cp2cr[ 20 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR21: mipscpu.cp2cr[ 21 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR22: mipscpu.cp2cr[ 22 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR23: mipscpu.cp2cr[ 23 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR24: mipscpu.cp2cr[ 24 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR25: mipscpu.cp2cr[ 25 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR26: mipscpu.cp2cr[ 26 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR27: mipscpu.cp2cr[ 27 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR28: mipscpu.cp2cr[ 28 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR29: mipscpu.cp2cr[ 29 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR30: mipscpu.cp2cr[ 30 ].d = info->i; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR31: mipscpu.cp2cr[ 31 ].d = info->i; break;
-
- /* --- the following bits of info are set as pointers to data or functions --- */
- case CPUINFO_PTR_IRQ_CALLBACK: mipscpu.irq_callback = info->irqcallback; break;
- }
-}
-
-
-
-/**************************************************************************
- * Generic get_info
- **************************************************************************/
-
-void mips_get_info(uint32_t state, union cpuinfo *info)
-{
- switch (state)
- {
- /* --- the following bits of info are returned as 64-bit signed integers --- */
- case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(mipscpu); break;
- case CPUINFO_INT_INPUT_LINES: info->i = 6; break;
- case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
- case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break;
- case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
- case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 4; break;
- case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break;
- case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
- case CPUINFO_INT_MAX_CYCLES: info->i = 40; break;
-
- case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break;
- case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break;
- case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break;
- case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
- case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
-
- case CPUINFO_INT_INPUT_STATE + MIPS_IRQ0: info->i = (mipscpu.cp0r[ CP0_CAUSE ] & 0x400) ? ASSERT_LINE : CLEAR_LINE; break;
- case CPUINFO_INT_INPUT_STATE + MIPS_IRQ1: info->i = (mipscpu.cp0r[ CP0_CAUSE ] & 0x800) ? ASSERT_LINE : CLEAR_LINE; break;
- case CPUINFO_INT_INPUT_STATE + MIPS_IRQ2: info->i = (mipscpu.cp0r[ CP0_CAUSE ] & 0x1000) ? ASSERT_LINE : CLEAR_LINE; break;
- case CPUINFO_INT_INPUT_STATE + MIPS_IRQ3: info->i = (mipscpu.cp0r[ CP0_CAUSE ] & 0x2000) ? ASSERT_LINE : CLEAR_LINE; break;
- case CPUINFO_INT_INPUT_STATE + MIPS_IRQ4: info->i = (mipscpu.cp0r[ CP0_CAUSE ] & 0x4000) ? ASSERT_LINE : CLEAR_LINE; break;
- case CPUINFO_INT_INPUT_STATE + MIPS_IRQ5: info->i = (mipscpu.cp0r[ CP0_CAUSE ] & 0x8000) ? ASSERT_LINE : CLEAR_LINE; break;
-
- case CPUINFO_INT_PREVIOUSPC: /* not implemented */ break;
-
- case CPUINFO_INT_PC: info->i = mipscpu.pc; break;
- case CPUINFO_INT_REGISTER + MIPS_PC: info->i = mipscpu.pc; break;
- case CPUINFO_INT_SP:
- /* because there is no hardware stack and the pipeline causes the cpu to execute the
- instruction after a subroutine call before the subroutine is executed there is little
- chance of cmd_step_over() in mamedbg.c working. */
- info->i = 0; break;
- case CPUINFO_INT_REGISTER + MIPS_DELAYV: info->i = mipscpu.delayv; break;
- case CPUINFO_INT_REGISTER + MIPS_DELAYR: info->i = mipscpu.delayr; break;
- case CPUINFO_INT_REGISTER + MIPS_HI: info->i = mipscpu.hi; break;
- case CPUINFO_INT_REGISTER + MIPS_LO: info->i = mipscpu.lo; break;
- case CPUINFO_INT_REGISTER + MIPS_R0: info->i = mipscpu.r[ 0 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R1: info->i = mipscpu.r[ 1 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R2: info->i = mipscpu.r[ 2 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R3: info->i = mipscpu.r[ 3 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R4: info->i = mipscpu.r[ 4 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R5: info->i = mipscpu.r[ 5 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R6: info->i = mipscpu.r[ 6 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R7: info->i = mipscpu.r[ 7 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R8: info->i = mipscpu.r[ 8 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R9: info->i = mipscpu.r[ 9 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R10: info->i = mipscpu.r[ 10 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R11: info->i = mipscpu.r[ 11 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R12: info->i = mipscpu.r[ 12 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R13: info->i = mipscpu.r[ 13 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R14: info->i = mipscpu.r[ 14 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R15: info->i = mipscpu.r[ 15 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R16: info->i = mipscpu.r[ 16 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R17: info->i = mipscpu.r[ 17 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R18: info->i = mipscpu.r[ 18 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R19: info->i = mipscpu.r[ 19 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R20: info->i = mipscpu.r[ 20 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R21: info->i = mipscpu.r[ 21 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R22: info->i = mipscpu.r[ 22 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R23: info->i = mipscpu.r[ 23 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R24: info->i = mipscpu.r[ 24 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R25: info->i = mipscpu.r[ 25 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R26: info->i = mipscpu.r[ 26 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R27: info->i = mipscpu.r[ 27 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R28: info->i = mipscpu.r[ 28 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R29: info->i = mipscpu.r[ 29 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R30: info->i = mipscpu.r[ 30 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_R31: info->i = mipscpu.r[ 31 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R0: info->i = mipscpu.cp0r[ 0 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R1: info->i = mipscpu.cp0r[ 1 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R2: info->i = mipscpu.cp0r[ 2 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R3: info->i = mipscpu.cp0r[ 3 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R4: info->i = mipscpu.cp0r[ 4 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R5: info->i = mipscpu.cp0r[ 5 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R6: info->i = mipscpu.cp0r[ 6 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R7: info->i = mipscpu.cp0r[ 7 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R8: info->i = mipscpu.cp0r[ 8 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R9: info->i = mipscpu.cp0r[ 9 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R10: info->i = mipscpu.cp0r[ 10 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R11: info->i = mipscpu.cp0r[ 11 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R12: info->i = mipscpu.cp0r[ 12 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R13: info->i = mipscpu.cp0r[ 13 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R14: info->i = mipscpu.cp0r[ 14 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R15: info->i = mipscpu.cp0r[ 15 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R16: info->i = mipscpu.cp0r[ 16 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R17: info->i = mipscpu.cp0r[ 17 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R18: info->i = mipscpu.cp0r[ 18 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R19: info->i = mipscpu.cp0r[ 19 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R20: info->i = mipscpu.cp0r[ 20 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R21: info->i = mipscpu.cp0r[ 21 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R22: info->i = mipscpu.cp0r[ 22 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R23: info->i = mipscpu.cp0r[ 23 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R24: info->i = mipscpu.cp0r[ 24 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R25: info->i = mipscpu.cp0r[ 25 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R26: info->i = mipscpu.cp0r[ 26 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R27: info->i = mipscpu.cp0r[ 27 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R28: info->i = mipscpu.cp0r[ 28 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R29: info->i = mipscpu.cp0r[ 29 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R30: info->i = mipscpu.cp0r[ 30 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP0R31: info->i = mipscpu.cp0r[ 31 ]; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR0: info->i = mipscpu.cp2dr[ 0 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR1: info->i = mipscpu.cp2dr[ 1 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR2: info->i = mipscpu.cp2dr[ 2 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR3: info->i = mipscpu.cp2dr[ 3 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR4: info->i = mipscpu.cp2dr[ 4 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR5: info->i = mipscpu.cp2dr[ 5 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR6: info->i = mipscpu.cp2dr[ 6 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR7: info->i = mipscpu.cp2dr[ 7 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR8: info->i = mipscpu.cp2dr[ 8 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR9: info->i = mipscpu.cp2dr[ 9 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR10: info->i = mipscpu.cp2dr[ 10 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR11: info->i = mipscpu.cp2dr[ 11 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR12: info->i = mipscpu.cp2dr[ 12 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR13: info->i = mipscpu.cp2dr[ 13 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR14: info->i = mipscpu.cp2dr[ 14 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR15: info->i = mipscpu.cp2dr[ 15 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR16: info->i = mipscpu.cp2dr[ 16 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR17: info->i = mipscpu.cp2dr[ 17 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR18: info->i = mipscpu.cp2dr[ 18 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR19: info->i = mipscpu.cp2dr[ 19 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR20: info->i = mipscpu.cp2dr[ 20 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR21: info->i = mipscpu.cp2dr[ 21 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR22: info->i = mipscpu.cp2dr[ 22 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR23: info->i = mipscpu.cp2dr[ 23 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR24: info->i = mipscpu.cp2dr[ 24 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR25: info->i = mipscpu.cp2dr[ 25 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR26: info->i = mipscpu.cp2dr[ 26 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR27: info->i = mipscpu.cp2dr[ 27 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR28: info->i = mipscpu.cp2dr[ 28 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR29: info->i = mipscpu.cp2dr[ 29 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR30: info->i = mipscpu.cp2dr[ 30 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2DR31: info->i = mipscpu.cp2dr[ 31 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR0: info->i = mipscpu.cp2cr[ 0 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR1: info->i = mipscpu.cp2cr[ 1 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR2: info->i = mipscpu.cp2cr[ 2 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR3: info->i = mipscpu.cp2cr[ 3 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR4: info->i = mipscpu.cp2cr[ 4 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR5: info->i = mipscpu.cp2cr[ 5 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR6: info->i = mipscpu.cp2cr[ 6 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR7: info->i = mipscpu.cp2cr[ 7 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR8: info->i = mipscpu.cp2cr[ 8 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR9: info->i = mipscpu.cp2cr[ 9 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR10: info->i = mipscpu.cp2cr[ 10 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR11: info->i = mipscpu.cp2cr[ 11 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR12: info->i = mipscpu.cp2cr[ 12 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR13: info->i = mipscpu.cp2cr[ 13 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR14: info->i = mipscpu.cp2cr[ 14 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR15: info->i = mipscpu.cp2cr[ 15 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR16: info->i = mipscpu.cp2cr[ 16 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR17: info->i = mipscpu.cp2cr[ 17 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR18: info->i = mipscpu.cp2cr[ 18 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR19: info->i = mipscpu.cp2cr[ 19 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR20: info->i = mipscpu.cp2cr[ 20 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR21: info->i = mipscpu.cp2cr[ 21 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR22: info->i = mipscpu.cp2cr[ 22 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR23: info->i = mipscpu.cp2cr[ 23 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR24: info->i = mipscpu.cp2cr[ 24 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR25: info->i = mipscpu.cp2cr[ 25 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR26: info->i = mipscpu.cp2cr[ 26 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR27: info->i = mipscpu.cp2cr[ 27 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR28: info->i = mipscpu.cp2cr[ 28 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR29: info->i = mipscpu.cp2cr[ 29 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR30: info->i = mipscpu.cp2cr[ 30 ].d; break;
- case CPUINFO_INT_REGISTER + MIPS_CP2CR31: info->i = mipscpu.cp2cr[ 31 ].d; break;
-
- /* --- the following bits of info are returned as pointers to data or functions --- */
- case CPUINFO_PTR_SET_INFO: info->setinfo = mips_set_info; break;
- case CPUINFO_PTR_GET_CONTEXT: info->getcontext = mips_get_context; break;
- case CPUINFO_PTR_SET_CONTEXT: info->setcontext = mips_set_context; break;
- case CPUINFO_PTR_INIT: info->init = mips_init; break;
- case CPUINFO_PTR_RESET: info->reset = mips_reset; break;
- case CPUINFO_PTR_EXIT: info->exit = mips_exit; break;
- case CPUINFO_PTR_EXECUTE: info->execute = mips_execute; break;
- case CPUINFO_PTR_BURN: info->burn = NULL; break;
- case CPUINFO_PTR_DISASSEMBLE: info->disassemble = mips_dasm; break;
- case CPUINFO_PTR_IRQ_CALLBACK: info->irqcallback = mipscpu.irq_callback; break;
- case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &mips_ICount; break;
- case CPUINFO_PTR_REGISTER_LAYOUT: info->p = mips_reg_layout; break;
- case CPUINFO_PTR_WINDOW_LAYOUT: info->p = mips_win_layout; break;
- }
-}
-
-uint32_t mips_get_cause(void)
-{
- return mipscpu.cp0r[ CP0_CAUSE ];
-}
-
-uint32_t mips_get_status(void)
-{
- return mipscpu.cp0r[ CP0_SR ];
-}
-
-void mips_set_status(uint32_t status)
-{
- mipscpu.cp0r[ CP0_SR ] = status;
-}
-
-uint32_t mips_get_ePC(void)
-{
- return mipscpu.cp0r[ CP0_EPC ];
-}
-
-int mips_get_icount(void)
-{
- return mips_ICount;
-}
-
-void mips_set_icount(int count)
-{
- mips_ICount = count;
-}
-
-
-#if (HAS_PSXCPU)
-/**************************************************************************
- * CPU-specific set_info
- **************************************************************************/
-
-void psxcpu_get_info(uint32_t state, union cpuinfo *info)
-{
- switch (state)
- {
- /* --- the following bits of info are returned as NULL-terminated strings --- */
-// case CPUINFO_STR_NAME: strcpy(info->s = cpuintrf_temp_str(), "PSX CPU"); break;
-
- default:
- mips_get_info(state, info);
- break;
- }
-}
-#endif
diff --git a/src/psf/psx.cc b/src/psf/psx.cc
new file mode 100644
index 000000000000..d4b44ec73e61
--- /dev/null
+++ b/src/psf/psx.cc
@@ -0,0 +1,3005 @@
+/*
+ * Sony CXD8530AQ/CXD8530BQ/CXD8530CQ/CXD8661R
+ *
+ * PSX CPU emulator for the MAME project written by smf
+ * Thanks to Farfetch'd for information on the delay slot bug
+ *
+ * The PSX CPU is a custom r3000a with a built in
+ * geometry transform engine, no mmu & no data cache.
+ *
+ * There is a stall circuit for load delays, but
+ * it doesn't work if the load occurs in a branch
+ * delay slot.
+ *
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "ao.h"
+#include "cpuintrf.h"
+#include "psx.h"
+
+#define EXC_INT ( 0 )
+#define EXC_ADEL ( 4 )
+#define EXC_ADES ( 5 )
+#define EXC_SYS ( 8 )
+#define EXC_BP ( 9 )
+#define EXC_RI ( 10 )
+#define EXC_CPU ( 11 )
+#define EXC_OVF ( 12 )
+
+#define CP0_RANDOM ( 1 )
+#define CP0_BADVADDR ( 8 )
+#define CP0_SR ( 12 )
+#define CP0_CAUSE ( 13 )
+#define CP0_EPC ( 14 )
+#define CP0_PRID ( 15 )
+
+#define SR_IEC ( 1L << 0 )
+#define SR_KUC ( 1L << 1 )
+#define SR_ISC ( 1L << 16 )
+#define SR_SWC ( 1L << 17 )
+#define SR_TS ( 1L << 21 )
+#define SR_BEV ( 1L << 22 )
+#define SR_RE ( 1L << 25 )
+#define SR_CU0 ( 1L << 28 )
+#define SR_CU1 ( 1L << 29 )
+#define SR_CU2 ( 1L << 30 )
+#define SR_CU3 ( 1L << 31 )
+
+#define CAUSE_EXC ( 31L << 2 )
+#define CAUSE_IP ( 255L << 8 )
+#define CAUSE_IP2 ( 1L << 10 )
+#define CAUSE_IP3 ( 1L << 11 )
+#define CAUSE_IP4 ( 1L << 12 )
+#define CAUSE_IP5 ( 1L << 13 )
+#define CAUSE_IP6 ( 1L << 14 )
+#define CAUSE_IP7 ( 1L << 15 )
+#define CAUSE_CE ( 3L << 28 )
+#define CAUSE_CE0 ( 0L << 28 )
+#define CAUSE_CE1 ( 1L << 28 )
+#define CAUSE_CE2 ( 2L << 28 )
+#define CAUSE_BD ( 1L << 31 )
+
+extern void psx_bios_hle(uint32_t pc);
+extern void psx_iop_call(uint32_t pc, uint32_t callnum);
+extern uint8_t program_read_byte_32le(offs_t address);
+extern uint16_t program_read_word_32le(offs_t address);
+extern uint32_t program_read_dword_32le(offs_t address);
+extern void program_write_byte_32le(offs_t address, uint8_t data);
+extern void program_write_word_32le(offs_t address, uint16_t data);
+extern void program_write_dword_32le(offs_t address, uint32_t data);
+
+static uint8_t mips_reg_layout[] =
+{
+ MIPS_PC, 0xFF,
+ MIPS_DELAYV, MIPS_DELAYR, 0xFF,
+ MIPS_HI, MIPS_LO, 0xFF,
+ 0xFF,
+ MIPS_R0, MIPS_R1, 0xFF,
+ MIPS_R2, MIPS_R3, 0xFF,
+ MIPS_R4, MIPS_R5, 0xFF,
+ MIPS_R6, MIPS_R7, 0xFF,
+ MIPS_R8, MIPS_R9, 0xFF,
+ MIPS_R10, MIPS_R11, 0xFF,
+ MIPS_R12, MIPS_R13, 0xFF,
+ MIPS_R14, MIPS_R15, 0xFF,
+ MIPS_R16, MIPS_R17, 0xFF,
+ MIPS_R18, MIPS_R19, 0xFF,
+ MIPS_R20, MIPS_R21, 0xFF,
+ MIPS_R22, MIPS_R23, 0xFF,
+ MIPS_R24, MIPS_R25, 0xFF,
+ MIPS_R26, MIPS_R27, 0xFF,
+ MIPS_R28, MIPS_R29, 0xFF,
+ MIPS_R30, MIPS_R31, 0xFF,
+ 0xFF,
+ MIPS_CP0R0, MIPS_CP0R1, 0xFF,
+ MIPS_CP0R2, MIPS_CP0R3, 0xFF,
+ MIPS_CP0R4, MIPS_CP0R5, 0xFF,
+ MIPS_CP0R6, MIPS_CP0R7, 0xFF,
+ MIPS_CP0R8, MIPS_CP0R9, 0xFF,
+ MIPS_CP0R10, MIPS_CP0R11, 0xFF,
+ MIPS_CP0R12, MIPS_CP0R13, 0xFF,
+ MIPS_CP0R14, MIPS_CP0R15, 0xFF,
+ MIPS_CP0R16, MIPS_CP0R17, 0xFF,
+ MIPS_CP0R18, MIPS_CP0R19, 0xFF,
+ MIPS_CP0R20, MIPS_CP0R21, 0xFF,
+ MIPS_CP0R22, MIPS_CP0R23, 0xFF,
+ MIPS_CP0R24, MIPS_CP0R25, 0xFF,
+ MIPS_CP0R26, MIPS_CP0R27, 0xFF,
+ MIPS_CP0R28, MIPS_CP0R29, 0xFF,
+ MIPS_CP0R30, MIPS_CP0R31, 0xFF,
+ 0xFF,
+ MIPS_CP2DR0, MIPS_CP2DR1, 0xFF,
+ MIPS_CP2DR2, MIPS_CP2DR3, 0xFF,
+ MIPS_CP2DR4, MIPS_CP2DR5, 0xFF,
+ MIPS_CP2DR6, MIPS_CP2DR7, 0xFF,
+ MIPS_CP2DR8, MIPS_CP2DR9, 0xFF,
+ MIPS_CP2DR10, MIPS_CP2DR11, 0xFF,
+ MIPS_CP2DR12, MIPS_CP2DR13, 0xFF,
+ MIPS_CP2DR14, MIPS_CP2DR15, 0xFF,
+ MIPS_CP2DR16, MIPS_CP2DR17, 0xFF,
+ MIPS_CP2DR18, MIPS_CP2DR19, 0xFF,
+ MIPS_CP2DR20, MIPS_CP2DR21, 0xFF,
+ MIPS_CP2DR22, MIPS_CP2DR23, 0xFF,
+ MIPS_CP2DR24, MIPS_CP2DR25, 0xFF,
+ MIPS_CP2DR26, MIPS_CP2DR27, 0xFF,
+ MIPS_CP2DR28, MIPS_CP2DR29, 0xFF,
+ MIPS_CP2DR30, MIPS_CP2DR31, 0xFF,
+ 0xFF,
+ MIPS_CP2CR0, MIPS_CP2CR1, 0xFF,
+ MIPS_CP2CR2, MIPS_CP2CR3, 0xFF,
+ MIPS_CP2CR4, MIPS_CP2CR5, 0xFF,
+ MIPS_CP2CR6, MIPS_CP2CR7, 0xFF,
+ MIPS_CP2CR8, MIPS_CP2CR9, 0xFF,
+ MIPS_CP2CR10, MIPS_CP2CR11, 0xFF,
+ MIPS_CP2CR12, MIPS_CP2CR13, 0xFF,
+ MIPS_CP2CR14, MIPS_CP2CR15, 0xFF,
+ MIPS_CP2CR16, MIPS_CP2CR17, 0xFF,
+ MIPS_CP2CR18, MIPS_CP2CR19, 0xFF,
+ MIPS_CP2CR20, MIPS_CP2CR21, 0xFF,
+ MIPS_CP2CR22, MIPS_CP2CR23, 0xFF,
+ MIPS_CP2CR24, MIPS_CP2CR25, 0xFF,
+ MIPS_CP2CR26, MIPS_CP2CR27, 0xFF,
+ MIPS_CP2CR28, MIPS_CP2CR29, 0xFF,
+ MIPS_CP2CR30, MIPS_CP2CR31,
+ 0
+};
+
+static uint8_t mips_win_layout[] = {
+ 45, 0,35,13, /* register window (top right) */
+ 0, 0,44,13, /* disassembler window (left, upper) */
+ 0,14,44, 8, /* memory #1 window (left, middle) */
+ 45,14,35, 8, /* memory #2 window (lower) */
+ 0,23,80, 1 /* command line window (bottom rows) */
+};
+
+#define REGPC ( 32 )
+
+typedef struct
+{
+ uint32_t op;
+ uint32_t pc;
+ uint32_t prevpc;
+ uint32_t delayv;
+ uint32_t delayr;
+ uint32_t hi;
+ uint32_t lo;
+ uint32_t r[ 32 ];
+ uint32_t cp0r[ 32 ];
+ PAIR cp2cr[ 32 ];
+ PAIR cp2dr[ 32 ];
+ int (*irq_callback)(int irqline);
+} mips_cpu_context;
+
+static mips_cpu_context mipscpu;
+
+static int mips_ICount = 0;
+
+static uint32_t mips_mtc0_writemask[]=
+{
+ 0xffffffff, /* INDEX */
+ 0x00000000, /* RANDOM */
+ 0xffffff00, /* ENTRYLO */
+ 0x00000000,
+ 0xffe00000, /* CONTEXT */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000, /* BADVADDR */
+ 0x00000000,
+ 0xffffffc0, /* ENTRYHI */
+ 0x00000000,
+ 0xf27fff3f, /* SR */
+ 0x00000300, /* CAUSE */
+ 0x00000000, /* EPC */
+ 0x00000000, /* PRID */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+
+#if 1
+void GTELOG(const char *a,...)
+{
+ va_list va;
+ char s_text[ 1024 ];
+ va_start( va, a );
+ vsprintf( s_text, a, va );
+ va_end( va );
+ logerror( "%08x: GTE: %08x %s\n", mipscpu.pc, INS_COFUN( mipscpu.op ), s_text );
+}
+#else
+static inline void GTELOG(const char *a, ...) {}
+#endif
+
+static uint32_t getcp2dr( int n_reg );
+static void setcp2dr( int n_reg, uint32_t n_value );
+static uint32_t getcp2cr( int n_reg );
+static void setcp2cr( int n_reg, uint32_t n_value );
+static void docop2( int gteop );
+static void mips_exception( int exception );
+
+void mips_stop( void )
+{
+#ifdef MAME_DEBUG
+ extern int debug_key_pressed;
+ debug_key_pressed = 1;
+ CALL_MAME_DEBUG;
+#endif
+}
+
+static inline void mips_set_cp0r( int reg, uint32_t value )
+{
+ mipscpu.cp0r[ reg ] = value;
+ if( reg == CP0_SR || reg == CP0_CAUSE )
+ {
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_IEC ) != 0 && ( mipscpu.cp0r[ CP0_SR ] & mipscpu.cp0r[ CP0_CAUSE ] & CAUSE_IP ) != 0 )
+ {
+ mips_exception( EXC_INT );
+ }
+ else if( mipscpu.delayr != REGPC && ( mipscpu.pc & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, mipscpu.pc );
+ }
+ }
+}
+
+static inline void mips_commit_delayed_load( void )
+{
+ if( mipscpu.delayr != 0 )
+ {
+ mipscpu.r[ mipscpu.delayr ] = mipscpu.delayv;
+ mipscpu.delayr = 0;
+ mipscpu.delayv = 0;
+ }
+}
+
+static inline void mips_delayed_branch( uint32_t n_adr )
+{
+ if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ mips_commit_delayed_load();
+ mipscpu.delayr = REGPC;
+ mipscpu.delayv = n_adr;
+ mipscpu.pc += 4;
+ }
+}
+
+static inline void mips_set_pc( unsigned val )
+{
+ mipscpu.pc = val;
+ change_pc( val );
+ mipscpu.delayr = 0;
+ mipscpu.delayv = 0;
+}
+
+static inline void mips_advance_pc( void )
+{
+ if( mipscpu.delayr == REGPC )
+ {
+ mips_set_pc( mipscpu.delayv );
+ }
+ else
+ {
+ mips_commit_delayed_load();
+ mipscpu.pc += 4;
+ }
+}
+
+static inline void mips_load( uint32_t n_r, uint32_t n_v )
+{
+ mips_advance_pc();
+ if( n_r != 0 )
+ {
+ mipscpu.r[ n_r ] = n_v;
+ }
+}
+
+static inline void mips_delayed_load( uint32_t n_r, uint32_t n_v )
+{
+ if( mipscpu.delayr == REGPC )
+ {
+ mips_set_pc( mipscpu.delayv );
+ mipscpu.delayr = n_r;
+ mipscpu.delayv = n_v;
+ }
+ else
+ {
+ mips_commit_delayed_load();
+ mipscpu.pc += 4;
+ if( n_r != 0 )
+ {
+ mipscpu.r[ n_r ] = n_v;
+ }
+ }
+}
+
+static void mips_exception( int exception )
+{
+ mips_set_cp0r( CP0_SR, ( mipscpu.cp0r[ CP0_SR ] & ~0x3f ) | ( ( mipscpu.cp0r[ CP0_SR ] << 2 ) & 0x3f ) );
+ if( mipscpu.delayr == REGPC )
+ {
+ mips_set_cp0r( CP0_EPC, mipscpu.pc - 4 );
+ mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_EXC ) | CAUSE_BD | ( exception << 2 ) );
+ }
+ else
+ {
+ mips_commit_delayed_load();
+ mips_set_cp0r( CP0_EPC, mipscpu.pc );
+ mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~( CAUSE_EXC | CAUSE_BD ) ) | ( exception << 2 ) );
+ }
+ if( mipscpu.cp0r[ CP0_SR ] & SR_BEV )
+ {
+ mips_set_pc( 0xbfc00180 );
+ }
+ else
+ {
+ mips_set_pc( 0x80000080 );
+ }
+}
+
+void mips_init( void )
+{
+#if 0
+ int cpu = cpu_getactivecpu();
+
+ state_save_register_UINT32( "psxcpu", cpu, "op", &mipscpu.op, 1 );
+ state_save_register_UINT32( "psxcpu", cpu, "pc", &mipscpu.pc, 1 );
+ state_save_register_UINT32( "psxcpu", cpu, "delayv", &mipscpu.delayv, 1 );
+ state_save_register_UINT32( "psxcpu", cpu, "delayr", &mipscpu.delayr, 1 );
+ state_save_register_UINT32( "psxcpu", cpu, "hi", &mipscpu.hi, 1 );
+ state_save_register_UINT32( "psxcpu", cpu, "lo", &mipscpu.lo, 1 );
+ state_save_register_UINT32( "psxcpu", cpu, "r", &mipscpu.r[ 0 ], 32 );
+ state_save_register_UINT32( "psxcpu", cpu, "cp0r", &mipscpu.cp0r[ 0 ], 32 );
+ state_save_register_UINT32( "psxcpu", cpu, "cp2cr", &mipscpu.cp2cr[ 0 ].d, 32 );
+ state_save_register_UINT32( "psxcpu", cpu, "cp2dr", &mipscpu.cp2dr[ 0 ].d, 32 );
+#endif
+}
+
+void mips_reset( void *param )
+{
+ mips_set_cp0r( CP0_SR, ( mipscpu.cp0r[ CP0_SR ] & ~( SR_TS | SR_SWC | SR_KUC | SR_IEC ) ) | SR_BEV );
+ mips_set_cp0r( CP0_RANDOM, 63 ); /* todo: */
+ mips_set_cp0r( CP0_PRID, 0x00000200 ); /* todo: */
+ mips_set_pc( 0xbfc00000 );
+ mipscpu.prevpc = 0xffffffff;
+}
+
+static void mips_exit( void )
+{
+}
+
+void mips_shorten_frame(void)
+{
+ mips_ICount = 0;
+}
+
+void psx_hw_runcounters(void);
+
+int psxcpu_verbose = 0;
+
+int mips_execute( int cycles )
+{
+ uint32_t n_res;
+
+ mips_ICount = cycles;
+ do
+ {
+// CALL_MAME_DEBUG;
+
+// psx_hw_runcounters();
+
+ mipscpu.op = cpu_readop32( mipscpu.pc );
+
+#if 0
+ while (mipscpu.prevpc == mipscpu.pc)
+ {
+ psx_hw_runcounters();
+ mips_ICount--;
+
+ if (mips_ICount == 0) return cycles;
+ }
+#endif
+
+ // if we're not in a delay slot, update
+ // if we're in a delay slot and the delay instruction is not NOP, update
+ if (( mipscpu.delayr == 0 ) || ((mipscpu.delayr != 0) && (mipscpu.op != 0)))
+ {
+ mipscpu.prevpc = mipscpu.pc;
+ }
+#if 0
+ if (1) //psxcpu_verbose)
+ {
+ printf("[%08x: %08x] [SP %08x RA %08x V0 %08x V1 %08x A0 %08x S0 %08x S1 %08x]\n", mipscpu.pc, mipscpu.op, mipscpu.r[29], mipscpu.r[31], mipscpu.r[2], mipscpu.r[3], mipscpu.r[4], mipscpu.r[ 16 ], mipscpu.r[ 17 ]);
+// psxcpu_verbose--;
+ }
+#endif
+ switch( INS_OP( mipscpu.op ) )
+ {
+ case OP_SPECIAL:
+ switch( INS_FUNCT( mipscpu.op ) )
+ {
+ case FUNCT_HLECALL:
+// printf("HLECALL, PC = %08x\n", mipscpu.pc);
+ psx_bios_hle(mipscpu.pc);
+ break;
+ case FUNCT_SLL:
+ mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] << INS_SHAMT( mipscpu.op ) );
+ break;
+ case FUNCT_SRL:
+ mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] >> INS_SHAMT( mipscpu.op ) );
+ break;
+ case FUNCT_SRA:
+ mips_load( INS_RD( mipscpu.op ), (int32_t)mipscpu.r[ INS_RT( mipscpu.op ) ] >> INS_SHAMT( mipscpu.op ) );
+ break;
+ case FUNCT_SLLV:
+ mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] << ( mipscpu.r[ INS_RS( mipscpu.op ) ] & 31 ) );
+ break;
+ case FUNCT_SRLV:
+ mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] >> ( mipscpu.r[ INS_RS( mipscpu.op ) ] & 31 ) );
+ break;
+ case FUNCT_SRAV:
+ mips_load( INS_RD( mipscpu.op ), (int32_t)mipscpu.r[ INS_RT( mipscpu.op ) ] >> ( mipscpu.r[ INS_RS( mipscpu.op ) ] & 31 ) );
+ break;
+ case FUNCT_JR:
+ if( INS_RD( mipscpu.op ) != 0 )
+ {
+ mips_exception( EXC_RI );
+ }
+ else
+ {
+ mips_delayed_branch( mipscpu.r[ INS_RS( mipscpu.op ) ] );
+ }
+ break;
+ case FUNCT_JALR:
+ n_res = mipscpu.pc + 8;
+ mips_delayed_branch( mipscpu.r[ INS_RS( mipscpu.op ) ] );
+ if( INS_RD( mipscpu.op ) != 0 )
+ {
+ mipscpu.r[ INS_RD( mipscpu.op ) ] = n_res;
+ }
+ break;
+ case FUNCT_SYSCALL:
+ mips_exception( EXC_SYS );
+ break;
+ case FUNCT_BREAK:
+ printf("BREAK!\n");
+ exit(-1);
+// mips_exception( EXC_BP );
+ mips_advance_pc();
+ break;
+ case FUNCT_MFHI:
+ mips_load( INS_RD( mipscpu.op ), mipscpu.hi );
+ break;
+ case FUNCT_MTHI:
+ if( INS_RD( mipscpu.op ) != 0 )
+ {
+ mips_exception( EXC_RI );
+ }
+ else
+ {
+ mips_advance_pc();
+ mipscpu.hi = mipscpu.r[ INS_RS( mipscpu.op ) ];
+ }
+ break;
+ case FUNCT_MFLO:
+ mips_load( INS_RD( mipscpu.op ), mipscpu.lo );
+ break;
+ case FUNCT_MTLO:
+ if( INS_RD( mipscpu.op ) != 0 )
+ {
+ mips_exception( EXC_RI );
+ }
+ else
+ {
+ mips_advance_pc();
+ mipscpu.lo = mipscpu.r[ INS_RS( mipscpu.op ) ];
+ }
+ break;
+ case FUNCT_MULT:
+ if( INS_RD( mipscpu.op ) != 0 )
+ {
+ mips_exception( EXC_RI );
+ }
+ else
+ {
+ int64_t n_res64;
+ n_res64 = MUL_64_32_32( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ], (int32_t)mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ mips_advance_pc();
+ mipscpu.lo = LO32_32_64( n_res64 );
+ mipscpu.hi = HI32_32_64( n_res64 );
+ }
+ break;
+ case FUNCT_MULTU:
+ if( INS_RD( mipscpu.op ) != 0 )
+ {
+ mips_exception( EXC_RI );
+ }
+ else
+ {
+ uint64_t n_res64;
+ n_res64 = MUL_U64_U32_U32( mipscpu.r[ INS_RS( mipscpu.op ) ], mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ mips_advance_pc();
+ mipscpu.lo = LO32_U32_U64( n_res64 );
+ mipscpu.hi = HI32_U32_U64( n_res64 );
+ }
+ break;
+ case FUNCT_DIV:
+ if( INS_RD( mipscpu.op ) != 0 )
+ {
+ mips_exception( EXC_RI );
+ }
+ else
+ {
+ uint32_t n_div;
+ uint32_t n_mod;
+ if( mipscpu.r[ INS_RT( mipscpu.op ) ] != 0 )
+ {
+ n_div = (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] / (int32_t)mipscpu.r[ INS_RT( mipscpu.op ) ];
+ n_mod = (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] % (int32_t)mipscpu.r[ INS_RT( mipscpu.op ) ];
+ mips_advance_pc();
+ mipscpu.lo = n_div;
+ mipscpu.hi = n_mod;
+ }
+ else
+ {
+ mips_advance_pc();
+ }
+ }
+ break;
+ case FUNCT_DIVU:
+ if( INS_RD( mipscpu.op ) != 0 )
+ {
+ mips_exception( EXC_RI );
+ }
+ else
+ {
+ uint32_t n_div;
+ uint32_t n_mod;
+ if( mipscpu.r[ INS_RT( mipscpu.op ) ] != 0 )
+ {
+ n_div = mipscpu.r[ INS_RS( mipscpu.op ) ] / mipscpu.r[ INS_RT( mipscpu.op ) ];
+ n_mod = mipscpu.r[ INS_RS( mipscpu.op ) ] % mipscpu.r[ INS_RT( mipscpu.op ) ];
+ mips_advance_pc();
+ mipscpu.lo = n_div;
+ mipscpu.hi = n_mod;
+ }
+ else
+ {
+ mips_advance_pc();
+ }
+ }
+ break;
+ case FUNCT_ADD:
+ {
+ n_res = mipscpu.r[ INS_RS( mipscpu.op ) ] + mipscpu.r[ INS_RT( mipscpu.op ) ];
+ if( (int32_t)( ~( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ mipscpu.r[ INS_RT( mipscpu.op ) ] ) & ( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ n_res ) ) < 0 )
+ {
+ mips_exception( EXC_OVF );
+ }
+ else
+ {
+ mips_load( INS_RD( mipscpu.op ), n_res );
+ }
+ }
+ break;
+ case FUNCT_ADDU:
+ mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] + mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ case FUNCT_SUB:
+ n_res = mipscpu.r[ INS_RS( mipscpu.op ) ] - mipscpu.r[ INS_RT( mipscpu.op ) ];
+ if( (int32_t)( ( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ mipscpu.r[ INS_RT( mipscpu.op ) ] ) & ( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ n_res ) ) < 0 )
+ {
+ mips_exception( EXC_OVF );
+ }
+ else
+ {
+ mips_load( INS_RD( mipscpu.op ), n_res );
+ }
+ break;
+ case FUNCT_SUBU:
+ mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] - mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ case FUNCT_AND:
+ mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] & mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ case FUNCT_OR:
+ mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] | mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ case FUNCT_XOR:
+ mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] ^ mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ case FUNCT_NOR:
+ mips_load( INS_RD( mipscpu.op ), ~( mipscpu.r[ INS_RS( mipscpu.op ) ] | mipscpu.r[ INS_RT( mipscpu.op ) ] ) );
+ break;
+ case FUNCT_SLT:
+ mips_load( INS_RD( mipscpu.op ), (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] < (int32_t)mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ case FUNCT_SLTU:
+ mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] < mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ default:
+ mips_exception( EXC_RI );
+ break;
+ }
+ break;
+ case OP_REGIMM:
+ switch( INS_RT( mipscpu.op ) )
+ {
+ case RT_BLTZ:
+ if( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] < 0 )
+ {
+ mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
+ }
+ else
+ {
+ mips_advance_pc();
+ }
+ break;
+ case RT_BGEZ:
+ if( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] >= 0 )
+ {
+ mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
+ }
+ else
+ {
+ mips_advance_pc();
+ }
+ break;
+ case RT_BLTZAL:
+ n_res = mipscpu.pc + 8;
+ if( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] < 0 )
+ {
+ mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
+ }
+ else
+ {
+ mips_advance_pc();
+ }
+ mipscpu.r[ 31 ] = n_res;
+ break;
+ case RT_BGEZAL:
+ n_res = mipscpu.pc + 8;
+ if( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] >= 0 )
+ {
+ mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
+ }
+ else
+ {
+ mips_advance_pc();
+ }
+ mipscpu.r[ 31 ] = n_res;
+ break;
+ }
+ break;
+ case OP_J:
+ mips_delayed_branch( ( ( mipscpu.pc + 4 ) & 0xf0000000 ) + ( INS_TARGET( mipscpu.op ) << 2 ) );
+ break;
+ case OP_JAL:
+ n_res = mipscpu.pc + 8;
+ mips_delayed_branch( ( ( mipscpu.pc + 4 ) & 0xf0000000 ) + ( INS_TARGET( mipscpu.op ) << 2 ) );
+ mipscpu.r[ 31 ] = n_res;
+ break;
+ case OP_BEQ:
+ if( mipscpu.r[ INS_RS( mipscpu.op ) ] == mipscpu.r[ INS_RT( mipscpu.op ) ] )
+ {
+ mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
+ }
+ else
+ {
+ mips_advance_pc();
+ }
+ break;
+ case OP_BNE:
+ if( mipscpu.r[ INS_RS( mipscpu.op ) ] != mipscpu.r[ INS_RT( mipscpu.op ) ] )
+ {
+ mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
+ }
+ else
+ {
+ mips_advance_pc();
+ }
+ break;
+ case OP_BLEZ:
+ if( INS_RT( mipscpu.op ) != 0 )
+ {
+ mips_exception( EXC_RI );
+ }
+ else if( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] <= 0 )
+ {
+ mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
+ }
+ else
+ {
+ mips_advance_pc();
+ }
+ break;
+ case OP_BGTZ:
+ if( INS_RT( mipscpu.op ) != 0 )
+ {
+ mips_exception( EXC_RI );
+ }
+ else if( (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] > 0 )
+ {
+ mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
+ }
+ else
+ {
+ mips_advance_pc();
+ }
+ break;
+ case OP_ADDI:
+ {
+ uint32_t n_imm;
+ n_imm = MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ n_res = mipscpu.r[ INS_RS( mipscpu.op ) ] + n_imm;
+ if( (int32_t)( ~( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ n_imm ) & ( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ n_res ) ) < 0 )
+ {
+ mips_exception( EXC_OVF );
+ }
+ else
+ {
+ mips_load( INS_RT( mipscpu.op ), n_res );
+ }
+ }
+ break;
+ case OP_ADDIU:
+ if (INS_RT( mipscpu.op ) == 0)
+ {
+ psx_iop_call(mipscpu.pc, INS_IMMEDIATE(mipscpu.op));
+ mips_advance_pc();
+ }
+ else
+ {
+ mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) );
+ }
+ break;
+ case OP_SLTI:
+ mips_load( INS_RT( mipscpu.op ), (int32_t)mipscpu.r[ INS_RS( mipscpu.op ) ] < MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) );
+ break;
+ case OP_SLTIU:
+ mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] < (uint32_t)MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) );
+ break;
+ case OP_ANDI:
+ mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] & INS_IMMEDIATE( mipscpu.op ) );
+ break;
+ case OP_ORI:
+ mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] | INS_IMMEDIATE( mipscpu.op ) );
+ break;
+ case OP_XORI:
+ mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] ^ INS_IMMEDIATE( mipscpu.op ) );
+ break;
+ case OP_LUI:
+ mips_load( INS_RT( mipscpu.op ), INS_IMMEDIATE( mipscpu.op ) << 16 );
+ break;
+ case OP_COP0:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) != 0 && ( mipscpu.cp0r[ CP0_SR ] & SR_CU0 ) == 0 )
+ {
+ mips_exception( EXC_CPU );
+ mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE0 );
+ }
+ else
+ {
+ switch( INS_RS( mipscpu.op ) )
+ {
+ case RS_MFC:
+ mips_delayed_load( INS_RT( mipscpu.op ), mipscpu.cp0r[ INS_RD( mipscpu.op ) ] );
+ break;
+ case RS_CFC:
+ /* todo: */
+ logerror( "%08x: COP0 CFC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ case RS_MTC:
+ n_res = ( mipscpu.cp0r[ INS_RD( mipscpu.op ) ] & ~mips_mtc0_writemask[ INS_RD( mipscpu.op ) ] ) |
+ ( mipscpu.r[ INS_RT( mipscpu.op ) ] & mips_mtc0_writemask[ INS_RD( mipscpu.op ) ] );
+ mips_advance_pc();
+ mips_set_cp0r( INS_RD( mipscpu.op ), n_res );
+ break;
+ case RS_CTC:
+ /* todo: */
+ logerror( "%08x: COP0 CTC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ case RS_BC:
+ switch( INS_RT( mipscpu.op ) )
+ {
+ case RT_BCF:
+ /* todo: */
+ logerror( "%08x: COP0 BCF not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ case RT_BCT:
+ /* todo: */
+ logerror( "%08x: COP0 BCT not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ default:
+ /* todo: */
+ logerror( "%08x: COP0 unknown command %08x\n", mipscpu.pc, mipscpu.op );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ }
+ break;
+ default:
+ switch( INS_CO( mipscpu.op ) )
+ {
+ case 1:
+ switch( INS_CF( mipscpu.op ) )
+ {
+ case CF_RFE:
+ mips_advance_pc();
+ mips_set_cp0r( CP0_SR, ( mipscpu.cp0r[ CP0_SR ] & ~0xf ) | ( ( mipscpu.cp0r[ CP0_SR ] >> 2 ) & 0xf ) );
+ break;
+ default:
+ /* todo: */
+ logerror( "%08x: COP0 unknown command %08x\n", mipscpu.pc, mipscpu.op );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ }
+ break;
+ default:
+ /* todo: */
+ logerror( "%08x: COP0 unknown command %08x\n", mipscpu.pc, mipscpu.op );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ case OP_COP1:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_CU1 ) == 0 )
+ {
+ mips_exception( EXC_CPU );
+ mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE1 );
+ }
+ else
+ {
+ switch( INS_RS( mipscpu.op ) )
+ {
+ case RS_MFC:
+ /* todo: */
+ logerror( "%08x: COP1 BCT not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ case RS_CFC:
+ /* todo: */
+ logerror( "%08x: COP1 CFC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ case RS_MTC:
+ /* todo: */
+ logerror( "%08x: COP1 MTC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ case RS_CTC:
+ /* todo: */
+ logerror( "%08x: COP1 CTC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ case RS_BC:
+ switch( INS_RT( mipscpu.op ) )
+ {
+ case RT_BCF:
+ /* todo: */
+ logerror( "%08x: COP1 BCF not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ case RT_BCT:
+ /* todo: */
+ logerror( "%08x: COP1 BCT not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ default:
+ /* todo: */
+ logerror( "%08x: COP1 unknown command %08x\n", mipscpu.pc, mipscpu.op );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ }
+ break;
+ default:
+ switch( INS_CO( mipscpu.op ) )
+ {
+ case 1:
+ /* todo: */
+ logerror( "%08x: COP1 unknown command %08x\n", mipscpu.pc, mipscpu.op );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ default:
+ /* todo: */
+ logerror( "%08x: COP1 unknown command %08x\n", mipscpu.pc, mipscpu.op );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ case OP_COP2:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_CU2 ) == 0 )
+ {
+ mips_exception( EXC_CPU );
+ mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE2 );
+ }
+ else
+ {
+ switch( INS_RS( mipscpu.op ) )
+ {
+ case RS_MFC:
+ mips_delayed_load( INS_RT( mipscpu.op ), getcp2dr( INS_RD( mipscpu.op ) ) );
+ break;
+ case RS_CFC:
+ mips_delayed_load( INS_RT( mipscpu.op ), getcp2cr( INS_RD( mipscpu.op ) ) );
+ break;
+ case RS_MTC:
+ setcp2dr( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ mips_advance_pc();
+ break;
+ case RS_CTC:
+ setcp2cr( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ mips_advance_pc();
+ break;
+ case RS_BC:
+ switch( INS_RT( mipscpu.op ) )
+ {
+ case RT_BCF:
+ /* todo: */
+ logerror( "%08x: COP2 BCF not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ case RT_BCT:
+ /* todo: */
+ logerror( "%08x: COP2 BCT not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ default:
+ /* todo: */
+ logerror( "%08x: COP2 unknown command %08x\n", mipscpu.pc, mipscpu.op );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ }
+ break;
+ default:
+ switch( INS_CO( mipscpu.op ) )
+ {
+ case 1:
+ docop2( INS_COFUN( mipscpu.op ) );
+ mips_advance_pc();
+ break;
+ default:
+ /* todo: */
+ logerror( "%08x: COP2 unknown command %08x\n", mipscpu.pc, mipscpu.op );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ case OP_LB:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ logerror( "%08x: LB SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ mips_delayed_load( INS_RT( mipscpu.op ), MIPS_BYTE_EXTEND( program_read_byte_32le( n_adr ^ 3 ) ) );
+ }
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ mips_delayed_load( INS_RT( mipscpu.op ), MIPS_BYTE_EXTEND( program_read_byte_32le( n_adr ) ) );
+ }
+ }
+ break;
+ case OP_LH:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ logerror( "%08x: LH SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ mips_delayed_load( INS_RT( mipscpu.op ), MIPS_WORD_EXTEND( program_read_word_32le( n_adr ^ 2 ) ) );
+ }
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ mips_delayed_load( INS_RT( mipscpu.op ), MIPS_WORD_EXTEND( program_read_word_32le( n_adr ) ) );
+ }
+ }
+ break;
+ case OP_LWL:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ logerror( "%08x: LWL SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ switch( n_adr & 3 )
+ {
+ case 0:
+ n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x00ffffff ) | ( (uint32_t)program_read_byte_32le( n_adr + 3 ) << 24 );
+ break;
+ case 1:
+ n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x0000ffff ) | ( (uint32_t)program_read_word_32le( n_adr + 1 ) << 16 );
+ break;
+ case 2:
+ n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x000000ff ) | ( (uint32_t)program_read_byte_32le( n_adr - 1 ) << 8 ) | ( (uint32_t)program_read_word_32le( n_adr ) << 16 );
+ break;
+ default:
+ n_res = program_read_dword_32le( n_adr - 3 );
+ break;
+ }
+ mips_delayed_load( INS_RT( mipscpu.op ), n_res );
+ }
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ switch( n_adr & 3 )
+ {
+ case 0:
+ n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x00ffffff ) | ( (uint32_t)program_read_byte_32le( n_adr ) << 24 );
+ break;
+ case 1:
+ n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x0000ffff ) | ( (uint32_t)program_read_word_32le( n_adr - 1 ) << 16 );
+ break;
+ case 2:
+ n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x000000ff ) | ( (uint32_t)program_read_word_32le( n_adr - 2 ) << 8 ) | ( (uint32_t)program_read_byte_32le( n_adr ) << 24 );
+ break;
+ default:
+ n_res = program_read_dword_32le( n_adr - 3 );
+ break;
+ }
+ mips_delayed_load( INS_RT( mipscpu.op ), n_res );
+ }
+ }
+ break;
+ case OP_LW:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ logerror( "%08x: LW SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+#if 0
+ if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
+ {
+ printf("ADEL\n");
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+#endif
+ {
+ mips_delayed_load( INS_RT( mipscpu.op ), program_read_dword_32le( n_adr ) );
+ }
+ }
+ break;
+ case OP_LBU:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ logerror( "%08x: LBU SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ mips_delayed_load( INS_RT( mipscpu.op ), program_read_byte_32le( n_adr ^ 3 ) );
+ }
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ mips_delayed_load( INS_RT( mipscpu.op ), program_read_byte_32le( n_adr ) );
+ }
+ }
+ break;
+ case OP_LHU:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ logerror( "%08x: LHU SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ mips_delayed_load( INS_RT( mipscpu.op ), program_read_word_32le( n_adr ^ 2 ) );
+ }
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ mips_delayed_load( INS_RT( mipscpu.op ), program_read_word_32le( n_adr ) );
+ }
+ }
+ break;
+ case OP_LWR:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ logerror( "%08x: LWR SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ switch( n_adr & 3 )
+ {
+ case 3:
+ n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xffffff00 ) | program_read_byte_32le( n_adr - 3 );
+ break;
+ case 2:
+ n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xffff0000 ) | program_read_word_32le( n_adr - 2 );
+ break;
+ case 1:
+ n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xff000000 ) | program_read_word_32le( n_adr - 1 ) | ( (uint32_t)program_read_byte_32le( n_adr + 1 ) << 16 );
+ break;
+ default:
+ n_res = program_read_dword_32le( n_adr );
+ break;
+ }
+ mips_delayed_load( INS_RT( mipscpu.op ), n_res );
+ }
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ switch( n_adr & 3 )
+ {
+ case 3:
+ n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xffffff00 ) | program_read_byte_32le( n_adr );
+ break;
+ case 2:
+ n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xffff0000 ) | program_read_word_32le( n_adr );
+ break;
+ case 1:
+ n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xff000000 ) | program_read_byte_32le( n_adr ) | ( (uint32_t)program_read_word_32le( n_adr + 1 ) << 8 );
+ break;
+ default:
+ n_res = program_read_dword_32le( n_adr );
+ break;
+ }
+ mips_delayed_load( INS_RT( mipscpu.op ), n_res );
+ }
+ }
+ break;
+ case OP_SB:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ logerror( "%08x: SB SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ mips_exception( EXC_ADES );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ program_write_byte_32le( n_adr ^ 3, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ mips_advance_pc();
+ }
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ mips_exception( EXC_ADES );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ program_write_byte_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ mips_advance_pc();
+ }
+ }
+ break;
+ case OP_SH:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ logerror( "%08x: SH SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
+ {
+ mips_exception( EXC_ADES );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ program_write_word_32le( n_adr ^ 2, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ mips_advance_pc();
+ }
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
+ {
+ mips_exception( EXC_ADES );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ program_write_word_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ mips_advance_pc();
+ }
+ }
+ break;
+ case OP_SWL:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ printf("SR_ISC not supported\n");
+ logerror( "%08x: SWL SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ printf("permission violation?\n");
+ mips_exception( EXC_ADES );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ switch( n_adr & 3 )
+ {
+ case 0:
+ program_write_byte_32le( n_adr + 3, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 24 );
+ break;
+ case 1:
+ program_write_word_32le( n_adr + 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 16 );
+ break;
+ case 2:
+ program_write_byte_32le( n_adr - 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 8 );
+ program_write_word_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 16 );
+ break;
+ case 3:
+ program_write_dword_32le( n_adr - 3, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ }
+ mips_advance_pc();
+ }
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ printf("permission violation 2\n");
+ mips_exception( EXC_ADES );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ switch( n_adr & 3 )
+ {
+ case 0:
+ program_write_byte_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 24 );
+ break;
+ case 1:
+ program_write_word_32le( n_adr - 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 16 );
+ break;
+ case 2:
+ program_write_word_32le( n_adr - 2, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 8 );
+ program_write_byte_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 24 );
+ break;
+ case 3:
+ program_write_dword_32le( n_adr - 3, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ }
+ mips_advance_pc();
+ }
+ }
+ break;
+ case OP_SW:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+/* used by bootstrap
+ logerror( "%08x: SW SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+*/
+ mips_advance_pc();
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if(0) // ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
+ {
+ mips_exception( EXC_ADES );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ program_write_dword_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ mips_advance_pc();
+ }
+ }
+ break;
+ case OP_SWR:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ logerror( "%08x: SWR SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ mips_exception( EXC_ADES );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ switch( n_adr & 3 )
+ {
+ case 0:
+ program_write_dword_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ case 1:
+ program_write_word_32le( n_adr - 1, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ program_write_byte_32le( n_adr + 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 16 );
+ break;
+ case 2:
+ program_write_word_32le( n_adr - 2, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ case 3:
+ program_write_byte_32le( n_adr - 3, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ }
+ mips_advance_pc();
+ }
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
+ {
+ mips_exception( EXC_ADES );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ switch( n_adr & 3 )
+ {
+ case 0:
+ program_write_dword_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ case 1:
+ program_write_byte_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ program_write_word_32le( n_adr + 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 8 );
+ break;
+ case 2:
+ program_write_word_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ case 3:
+ program_write_byte_32le( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
+ break;
+ }
+ mips_advance_pc();
+ }
+ }
+ break;
+ case OP_LWC1:
+ /* todo: */
+ logerror( "%08x: COP1 LWC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ case OP_LWC2:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_CU2 ) == 0 )
+ {
+ mips_exception( EXC_CPU );
+ mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE2 );
+ }
+ else if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ logerror( "%08x: LWC2 SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
+ {
+ mips_exception( EXC_ADEL );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ /* todo: delay? */
+ setcp2dr( INS_RT( mipscpu.op ), program_read_dword_32le( n_adr ) );
+ mips_advance_pc();
+ }
+ }
+ break;
+ case OP_SWC1:
+ /* todo: */
+ logerror( "%08x: COP1 SWC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ break;
+ case OP_SWC2:
+ if( ( mipscpu.cp0r[ CP0_SR ] & SR_CU2 ) == 0 )
+ {
+ mips_exception( EXC_CPU );
+ mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE2 );
+ }
+ else if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
+ {
+ /* todo: */
+ logerror( "%08x: SWC2 SR_ISC not supported\n", mipscpu.pc );
+ mips_stop();
+ mips_advance_pc();
+ }
+ else
+ {
+ uint32_t n_adr;
+ n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
+ if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
+ {
+ mips_exception( EXC_ADES );
+ mips_set_cp0r( CP0_BADVADDR, n_adr );
+ }
+ else
+ {
+ program_write_dword_32le( n_adr, getcp2dr( INS_RT( mipscpu.op ) ) );
+ mips_advance_pc();
+ }
+ }
+ break;
+ default:
+ printf( "%08x: unknown opcode %08x (prev %08x, RA %08x)\n", mipscpu.pc, mipscpu.op, mipscpu.prevpc, mipscpu.r[31] );
+ mips_stop();
+ mips_exception( EXC_RI );
+ break;
+ }
+ mips_ICount--;
+ } while( mips_ICount > 0 );
+
+ return cycles - mips_ICount;
+}
+
+static void mips_get_context( void *dst )
+{
+ if( dst )
+ {
+ *(mips_cpu_context *)dst = mipscpu;
+ }
+}
+
+static void mips_set_context( void *src )
+{
+ if( src )
+ {
+ mipscpu = *(mips_cpu_context *)src;
+ change_pc( mipscpu.pc );
+ }
+}
+
+static void set_irq_line( int irqline, int state )
+{
+ uint32_t ip;
+
+ switch( irqline )
+ {
+ case MIPS_IRQ0:
+ ip = CAUSE_IP2;
+ break;
+ case MIPS_IRQ1:
+ ip = CAUSE_IP3;
+ break;
+ case MIPS_IRQ2:
+ ip = CAUSE_IP4;
+ break;
+ case MIPS_IRQ3:
+ ip = CAUSE_IP5;
+ break;
+ case MIPS_IRQ4:
+ ip = CAUSE_IP6;
+ break;
+ case MIPS_IRQ5:
+ ip = CAUSE_IP7;
+ break;
+ default:
+ return;
+ }
+
+ switch( state )
+ {
+ case CLEAR_LINE:
+ mips_set_cp0r( CP0_CAUSE, mipscpu.cp0r[ CP0_CAUSE ] & ~ip );
+ break;
+ case ASSERT_LINE:
+ mips_set_cp0r( CP0_CAUSE, mipscpu.cp0r[ CP0_CAUSE ] |= ip );
+ if( mipscpu.irq_callback )
+ {
+ /* HOLD_LINE interrupts are not supported by the architecture.
+ By acknowledging the interupt here they are treated like PULSE_LINE
+ interrupts, so if the interrupt isn't enabled it will be ignored.
+ There is also a problem with PULSE_LINE interrupts as the interrupt
+ pending bits aren't latched the emulated code won't know what caused
+ the interrupt. */
+ (*mipscpu.irq_callback)( irqline );
+ }
+ break;
+ }
+}
+
+/****************************************************************************
+ * Return a formatted string for a register
+ ****************************************************************************/
+
+offs_t mips_dasm( char *buffer, offs_t pc )
+{
+ offs_t ret;
+ change_pc( pc );
+#ifdef MAME_DEBUG
+ ret = DasmMIPS( buffer, pc );
+#else
+ sprintf( buffer, "$%08x", cpu_readop32( pc ) );
+ ret = 4;
+#endif
+ change_pc( mipscpu.pc );
+ return ret;
+}
+
+/* preliminary gte code */
+
+#define VXY0 ( mipscpu.cp2dr[ 0 ].d )
+#define VX0 ( mipscpu.cp2dr[ 0 ].w.l )
+#define VY0 ( mipscpu.cp2dr[ 0 ].w.h )
+#define VZ0 ( mipscpu.cp2dr[ 1 ].w.l )
+#define VXY1 ( mipscpu.cp2dr[ 2 ].d )
+#define VX1 ( mipscpu.cp2dr[ 2 ].w.l )
+#define VY1 ( mipscpu.cp2dr[ 2 ].w.h )
+#define VZ1 ( mipscpu.cp2dr[ 3 ].w.l )
+#define VXY2 ( mipscpu.cp2dr[ 4 ].d )
+#define VX2 ( mipscpu.cp2dr[ 4 ].w.l )
+#define VY2 ( mipscpu.cp2dr[ 4 ].w.h )
+#define VZ2 ( mipscpu.cp2dr[ 5 ].w.l )
+#define RGB ( mipscpu.cp2dr[ 6 ].d )
+#define R ( mipscpu.cp2dr[ 6 ].b.l )
+#define G ( mipscpu.cp2dr[ 6 ].b.h )
+#define B ( mipscpu.cp2dr[ 6 ].b.h2 )
+#define CODE ( mipscpu.cp2dr[ 6 ].b.h3 )
+#define OTZ ( mipscpu.cp2dr[ 7 ].w.l )
+#define IR0 ( mipscpu.cp2dr[ 8 ].d )
+#define IR1 ( mipscpu.cp2dr[ 9 ].d )
+#define IR2 ( mipscpu.cp2dr[ 10 ].d )
+#define IR3 ( mipscpu.cp2dr[ 11 ].d )
+#define SXY0 ( mipscpu.cp2dr[ 12 ].d )
+#define SX0 ( mipscpu.cp2dr[ 12 ].w.l )
+#define SY0 ( mipscpu.cp2dr[ 12 ].w.h )
+#define SXY1 ( mipscpu.cp2dr[ 13 ].d )
+#define SX1 ( mipscpu.cp2dr[ 13 ].w.l )
+#define SY1 ( mipscpu.cp2dr[ 13 ].w.h )
+#define SXY2 ( mipscpu.cp2dr[ 14 ].d )
+#define SX2 ( mipscpu.cp2dr[ 14 ].w.l )
+#define SY2 ( mipscpu.cp2dr[ 14 ].w.h )
+#define SXYP ( mipscpu.cp2dr[ 15 ].d )
+#define SXP ( mipscpu.cp2dr[ 15 ].w.l )
+#define SYP ( mipscpu.cp2dr[ 15 ].w.h )
+#define SZ0 ( mipscpu.cp2dr[ 16 ].w.l )
+#define SZ1 ( mipscpu.cp2dr[ 17 ].w.l )
+#define SZ2 ( mipscpu.cp2dr[ 18 ].w.l )
+#define SZ3 ( mipscpu.cp2dr[ 19 ].w.l )
+#define RGB0 ( mipscpu.cp2dr[ 20 ].d )
+#define R0 ( mipscpu.cp2dr[ 20 ].b.l )
+#define G0 ( mipscpu.cp2dr[ 20 ].b.h )
+#define B0 ( mipscpu.cp2dr[ 20 ].b.h2 )
+#define CD0 ( mipscpu.cp2dr[ 20 ].b.h3 )
+#define RGB1 ( mipscpu.cp2dr[ 21 ].d )
+#define R1 ( mipscpu.cp2dr[ 21 ].b.l )
+#define G1 ( mipscpu.cp2dr[ 21 ].b.h )
+#define B1 ( mipscpu.cp2dr[ 21 ].b.h2 )
+#define CD1 ( mipscpu.cp2dr[ 21 ].b.h3 )
+#define RGB2 ( mipscpu.cp2dr[ 22 ].d )
+#define R2 ( mipscpu.cp2dr[ 22 ].b.l )
+#define G2 ( mipscpu.cp2dr[ 22 ].b.h )
+#define B2 ( mipscpu.cp2dr[ 22 ].b.h2 )
+#define CD2 ( mipscpu.cp2dr[ 22 ].b.h3 )
+#define RES1 ( mipscpu.cp2dr[ 23 ].d )
+#define MAC0 ( mipscpu.cp2dr[ 24 ].d )
+#define MAC1 ( mipscpu.cp2dr[ 25 ].d )
+#define MAC2 ( mipscpu.cp2dr[ 26 ].d )
+#define MAC3 ( mipscpu.cp2dr[ 27 ].d )
+#define IRGB ( mipscpu.cp2dr[ 28 ].d )
+#define ORGB ( mipscpu.cp2dr[ 29 ].d )
+#define LZCS ( mipscpu.cp2dr[ 30 ].d )
+#define LZCR ( mipscpu.cp2dr[ 31 ].d )
+
+#define D1 ( mipscpu.cp2cr[ 0 ].d )
+#define R11 ( mipscpu.cp2cr[ 0 ].w.l )
+#define R12 ( mipscpu.cp2cr[ 0 ].w.h )
+#define R13 ( mipscpu.cp2cr[ 1 ].w.l )
+#define R21 ( mipscpu.cp2cr[ 1 ].w.h )
+#define D2 ( mipscpu.cp2cr[ 2 ].d )
+#define R22 ( mipscpu.cp2cr[ 2 ].w.l )
+#define R23 ( mipscpu.cp2cr[ 2 ].w.h )
+#define R31 ( mipscpu.cp2cr[ 3 ].w.l )
+#define R32 ( mipscpu.cp2cr[ 3 ].w.h )
+#define D3 ( mipscpu.cp2cr[ 4 ].d )
+#define R33 ( mipscpu.cp2cr[ 4 ].w.l )
+#define TRX ( mipscpu.cp2cr[ 5 ].d )
+#define TRY ( mipscpu.cp2cr[ 6 ].d )
+#define TRZ ( mipscpu.cp2cr[ 7 ].d )
+#define L11 ( mipscpu.cp2cr[ 8 ].w.l )
+#define L12 ( mipscpu.cp2cr[ 8 ].w.h )
+#define L13 ( mipscpu.cp2cr[ 9 ].w.l )
+#define L21 ( mipscpu.cp2cr[ 9 ].w.h )
+#define L22 ( mipscpu.cp2cr[ 10 ].w.l )
+#define L23 ( mipscpu.cp2cr[ 10 ].w.h )
+#define L31 ( mipscpu.cp2cr[ 11 ].w.l )
+#define L32 ( mipscpu.cp2cr[ 11 ].w.h )
+#define L33 ( mipscpu.cp2cr[ 12 ].w.l )
+#define RBK ( mipscpu.cp2cr[ 13 ].d )
+#define GBK ( mipscpu.cp2cr[ 14 ].d )
+#define BBK ( mipscpu.cp2cr[ 15 ].d )
+#define LR1 ( mipscpu.cp2cr[ 16 ].w.l )
+#define LR2 ( mipscpu.cp2cr[ 16 ].w.h )
+#define LR3 ( mipscpu.cp2cr[ 17 ].w.l )
+#define LG1 ( mipscpu.cp2cr[ 17 ].w.h )
+#define LG2 ( mipscpu.cp2cr[ 18 ].w.l )
+#define LG3 ( mipscpu.cp2cr[ 18 ].w.h )
+#define LB1 ( mipscpu.cp2cr[ 19 ].w.l )
+#define LB2 ( mipscpu.cp2cr[ 19 ].w.h )
+#define LB3 ( mipscpu.cp2cr[ 20 ].w.l )
+#define RFC ( mipscpu.cp2cr[ 21 ].d )
+#define GFC ( mipscpu.cp2cr[ 22 ].d )
+#define BFC ( mipscpu.cp2cr[ 23 ].d )
+#define OFX ( mipscpu.cp2cr[ 24 ].d )
+#define OFY ( mipscpu.cp2cr[ 25 ].d )
+#define H ( mipscpu.cp2cr[ 26 ].w.l )
+#define DQA ( mipscpu.cp2cr[ 27 ].w.l )
+#define DQB ( mipscpu.cp2cr[ 28 ].d )
+#define ZSF3 ( mipscpu.cp2cr[ 29 ].w.l )
+#define ZSF4 ( mipscpu.cp2cr[ 30 ].w.l )
+#define FLAG ( mipscpu.cp2cr[ 31 ].d )
+
+static uint32_t getcp2dr( int n_reg )
+{
+ if( n_reg == 1 || n_reg == 3 || n_reg == 5 || n_reg == 8 || n_reg == 9 || n_reg == 10 || n_reg == 11 )
+ {
+ mipscpu.cp2dr[ n_reg ].d = (int32_t)(int16_t)mipscpu.cp2dr[ n_reg ].d;
+ }
+ else if( n_reg == 17 || n_reg == 18 || n_reg == 19 )
+ {
+ mipscpu.cp2dr[ n_reg ].d = (uint32_t)(uint16_t)mipscpu.cp2dr[ n_reg ].d;
+ }
+ else if( n_reg == 29 )
+ {
+ ORGB = ( ( IR1 >> 7 ) & 0x1f ) | ( ( IR2 >> 2 ) & 0x3e0 ) | ( ( IR3 << 3 ) & 0x7c00 );
+ }
+ GTELOG( "get CP2DR%u=%08x", n_reg, mipscpu.cp2dr[ n_reg ].d );
+ return mipscpu.cp2dr[ n_reg ].d;
+}
+
+static void setcp2dr( int n_reg, uint32_t n_value )
+{
+ GTELOG( "set CP2DR%u=%08x", n_reg, n_value );
+ mipscpu.cp2dr[ n_reg ].d = n_value;
+
+ if( n_reg == 15 )
+ {
+ SXY0 = SXY1;
+ SXY1 = SXY2;
+ SXY2 = SXYP;
+ }
+ else if( n_reg == 28 )
+ {
+ IR1 = ( IRGB & 0x1f ) << 4;
+ IR2 = ( IRGB & 0x3e0 ) >> 1;
+ IR3 = ( IRGB & 0x7c00 ) >> 6;
+ }
+ else if( n_reg == 30 )
+ {
+ uint32_t n_lzcs = LZCS;
+ uint32_t n_lzcr = 0;
+
+ if( ( n_lzcs & 0x80000000 ) == 0 )
+ {
+ n_lzcs = ~n_lzcs;
+ }
+ while( ( n_lzcs & 0x80000000 ) != 0 )
+ {
+ n_lzcr++;
+ n_lzcs <<= 1;
+ }
+ LZCR = n_lzcr;
+ }
+}
+
+static uint32_t getcp2cr( int n_reg )
+{
+ GTELOG( "get CP2CR%u=%08x", n_reg, mipscpu.cp2cr[ n_reg ].d );
+ return mipscpu.cp2cr[ n_reg ].d;
+}
+
+static void setcp2cr( int n_reg, uint32_t n_value )
+{
+ GTELOG( "set CP2CR%u=%08x", n_reg, n_value );
+ mipscpu.cp2cr[ n_reg ].d = n_value;
+}
+
+static inline int32_t LIM( int32_t n_value, int32_t n_max, int32_t n_min, uint32_t n_flag )
+{
+ if( n_value > n_max )
+ {
+ FLAG |= n_flag;
+ return n_max;
+ }
+ else if( n_value < n_min )
+ {
+ FLAG |= n_flag;
+ return n_min;
+ }
+ return n_value;
+}
+
+static inline int64_t BOUNDS( int64_t n_value, int64_t n_max, int n_maxflag, int64_t n_min, int n_minflag )
+{
+ if( n_value > n_max )
+ {
+ FLAG |= n_maxflag;
+ }
+ else if( n_value < n_min )
+ {
+ FLAG |= n_minflag;
+ }
+ return n_value;
+}
+
+#define A1( a ) BOUNDS( ( a ), 0x7fffffff, 30, -(int64_t)0x80000000, ( 1 << 27 ) )
+#define A2( a ) BOUNDS( ( a ), 0x7fffffff, 29, -(int64_t)0x80000000, ( 1 << 26 ) )
+#define A3( a ) BOUNDS( ( a ), 0x7fffffff, 28, -(int64_t)0x80000000, ( 1 << 25 ) )
+#define Lm_B1( a, l ) LIM( ( a ), 0x7fff, -0x8000 * !l, ( 1 << 31 ) | ( 1 << 24 ) )
+#define Lm_B2( a, l ) LIM( ( a ), 0x7fff, -0x8000 * !l, ( 1 << 31 ) | ( 1 << 23 ) )
+#define Lm_B3( a, l ) LIM( ( a ), 0x7fff, -0x8000 * !l, ( 1 << 22 ) )
+#define Lm_C1( a ) LIM( ( a ), 0x00ff, 0x0000, ( 1 << 21 ) )
+#define Lm_C2( a ) LIM( ( a ), 0x00ff, 0x0000, ( 1 << 20 ) )
+#define Lm_C3( a ) LIM( ( a ), 0x00ff, 0x0000, ( 1 << 19 ) )
+#define Lm_D( a ) LIM( ( a ), 0xffff, 0x0000, ( 1 << 31 ) | ( 1 << 18 ) )
+
+static inline uint32_t Lm_E( uint32_t n_z )
+{
+ if( n_z <= H / 2 )
+ {
+ n_z = H / 2;
+ FLAG |= ( 1 << 31 ) | ( 1 << 17 );
+ }
+ if( n_z == 0 )
+ {
+ n_z = 1;
+ }
+ return n_z;
+}
+
+#define F( a ) BOUNDS( ( a ), 0x7fffffff, ( 1 << 31 ) | ( 1 << 16 ), -(int64_t)0x80000000, ( 1 << 31 ) | ( 1 << 15 ) )
+#define Lm_G1( a ) LIM( ( a ), 0x3ff, -0x400, ( 1 << 31 ) | ( 1 << 14 ) )
+#define Lm_G2( a ) LIM( ( a ), 0x3ff, -0x400, ( 1 << 31 ) | ( 1 << 13 ) )
+#define Lm_H( a ) LIM( ( a ), 0xfff, 0x000, ( 1 << 12 ) )
+
+static void docop2( int gteop )
+{
+ int n_sf;
+ int n_v;
+ int n_lm;
+ int n_pass;
+ uint16_t n_v1;
+ uint16_t n_v2;
+ uint16_t n_v3;
+ const uint16_t **p_n_mx;
+ const uint32_t **p_n_cv;
+ static const uint16_t n_zm = 0;
+ static const uint32_t n_zc = 0;
+ static const uint16_t *p_n_vx[] = { &VX0, &VX1, &VX2 };
+ static const uint16_t *p_n_vy[] = { &VY0, &VY1, &VY2 };
+ static const uint16_t *p_n_vz[] = { &VZ0, &VZ1, &VZ2 };
+ static const uint16_t *p_n_rm[] = { &R11, &R12, &R13, &R21, &R22, &R23, &R31, &R32, &R33 };
+ static const uint16_t *p_n_lm[] = { &L11, &L12, &L13, &L21, &L22, &L23, &L31, &L32, &L33 };
+ static const uint16_t *p_n_cm[] = { &LR1, &LR2, &LR3, &LG1, &LG2, &LG3, &LB1, &LB2, &LB3 };
+ static const uint16_t *p_n_zm[] = { &n_zm, &n_zm, &n_zm, &n_zm, &n_zm, &n_zm, &n_zm, &n_zm, &n_zm };
+ static const uint16_t **p_p_n_mx[] = { p_n_rm, p_n_lm, p_n_cm, p_n_zm };
+ static const uint32_t *p_n_tr[] = { &TRX, &TRY, &TRZ };
+ static const uint32_t *p_n_bk[] = { &RBK, &GBK, &BBK };
+ static const uint32_t *p_n_fc[] = { &RFC, &GFC, &BFC };
+ static const uint32_t *p_n_zc[] = { &n_zc, &n_zc, &n_zc };
+ static const uint32_t **p_p_n_cv[] = { p_n_tr, p_n_bk, p_n_fc, p_n_zc };
+
+ switch( GTE_FUNCT( gteop ) )
+ {
+ case 0x01:
+ if( gteop == 0x0180001 )
+ {
+ GTELOG( "RTPS" );
+ FLAG = 0;
+
+ MAC1 = A1( ( ( (int64_t)(int32_t)TRX << 12 ) + ( (int16_t)R11 * (int16_t)VX0 ) + ( (int16_t)R12 * (int16_t)VY0 ) + ( (int16_t)R13 * (int16_t)VZ0 ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)(int32_t)TRY << 12 ) + ( (int16_t)R21 * (int16_t)VX0 ) + ( (int16_t)R22 * (int16_t)VY0 ) + ( (int16_t)R23 * (int16_t)VZ0 ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)(int32_t)TRZ << 12 ) + ( (int16_t)R31 * (int16_t)VX0 ) + ( (int16_t)R32 * (int16_t)VY0 ) + ( (int16_t)R33 * (int16_t)VZ0 ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 0 );
+ IR2 = Lm_B2( (int32_t)MAC2, 0 );
+ IR3 = Lm_B3( (int32_t)MAC3, 0 );
+ SZ0 = SZ1;
+ SZ1 = SZ2;
+ SZ2 = SZ3;
+ SZ3 = Lm_D( (int32_t)MAC3 );
+ SXY0 = SXY1;
+ SXY1 = SXY2;
+ SX2 = Lm_G1( F( (int64_t)(int32_t)OFX + ( (int64_t)(int16_t)IR1 * ( ( (uint32_t)H << 16 ) / Lm_E( SZ3 ) ) ) ) >> 16 );
+ SY2 = Lm_G2( F( (int64_t)(int32_t)OFY + ( (int64_t)(int16_t)IR2 * ( ( (uint32_t)H << 16 ) / Lm_E( SZ3 ) ) ) ) >> 16 );
+ MAC0 = F( (int64_t)(int32_t)DQB + ( (int64_t)(int16_t)DQA * ( ( (uint32_t)H << 16 ) / Lm_E( SZ3 ) ) ) );
+ IR0 = Lm_H( (int32_t)MAC0 >> 12 );
+ return;
+ }
+ break;
+ case 0x06:
+ if( gteop == 0x0400006 ||
+ gteop == 0x1400006 ||
+ gteop == 0x0155cc6 )
+ {
+ GTELOG( "NCLIP" );
+ FLAG = 0;
+
+ MAC0 = F( ( (int64_t)(int16_t)SX0 * (int16_t)SY1 ) + ( (int16_t)SX1 * (int16_t)SY2 ) + ( (int16_t)SX2 * (int16_t)SY0 ) - ( (int16_t)SX0 * (int16_t)SY2 ) - ( (int16_t)SX1 * (int16_t)SY0 ) - ( (int16_t)SX2 * (int16_t)SY1 ) );
+ return;
+ }
+ break;
+ case 0x0c:
+ if( GTE_OP( gteop ) == 0x17 )
+ {
+ GTELOG( "OP" );
+ n_sf = 12 * GTE_SF( gteop );
+ FLAG = 0;
+
+ MAC1 = A1( ( ( (int64_t)(int32_t)D2 * (int16_t)IR3 ) - ( (int64_t)(int32_t)D3 * (int16_t)IR2 ) ) >> n_sf );
+ MAC2 = A2( ( ( (int64_t)(int32_t)D3 * (int16_t)IR1 ) - ( (int64_t)(int32_t)D1 * (int16_t)IR3 ) ) >> n_sf );
+ MAC3 = A3( ( ( (int64_t)(int32_t)D1 * (int16_t)IR2 ) - ( (int64_t)(int32_t)D2 * (int16_t)IR1 ) ) >> n_sf );
+ IR1 = Lm_B1( (int32_t)MAC1, 0 );
+ IR2 = Lm_B2( (int32_t)MAC2, 0 );
+ IR3 = Lm_B3( (int32_t)MAC3, 0 );
+ return;
+ }
+ break;
+ case 0x10:
+ if( gteop == 0x0780010 )
+ {
+ GTELOG( "DPCS" );
+ FLAG = 0;
+
+ MAC1 = A1( ( ( (int64_t)R << 16 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)RFC - ( R << 4 ), 0 ) ) ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)G << 16 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)GFC - ( G << 4 ), 0 ) ) ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)B << 16 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)BFC - ( B << 4 ), 0 ) ) ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 0 );
+ IR2 = Lm_B2( (int32_t)MAC2, 0 );
+ IR3 = Lm_B3( (int32_t)MAC3, 0 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 >> 4 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 >> 4 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 >> 4 );
+ return;
+ }
+ break;
+ case 0x11:
+ if( gteop == 0x0980011 )
+ {
+ GTELOG( "INTPL" );
+ FLAG = 0;
+
+ MAC1 = A1( ( ( (int64_t)(int16_t)IR1 << 12 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)RFC - (int16_t)IR1, 0 ) ) ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)(int16_t)IR2 << 12 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)GFC - (int16_t)IR2, 0 ) ) ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)(int16_t)IR3 << 12 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)BFC - (int16_t)IR3, 0 ) ) ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 0 );
+ IR2 = Lm_B2( (int32_t)MAC2, 0 );
+ IR3 = Lm_B3( (int32_t)MAC3, 0 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 );
+ return;
+ }
+ break;
+ case 0x12:
+ if( GTE_OP( gteop ) == 0x04 )
+ {
+ GTELOG( "MVMVA" );
+ n_sf = 12 * GTE_SF( gteop );
+ p_n_mx = p_p_n_mx[ GTE_MX( gteop ) ];
+ n_v = GTE_V( gteop );
+ if( n_v < 3 )
+ {
+ n_v1 = *p_n_vx[ n_v ];
+ n_v2 = *p_n_vy[ n_v ];
+ n_v3 = *p_n_vz[ n_v ];
+ }
+ else
+ {
+ n_v1 = IR1;
+ n_v2 = IR2;
+ n_v3 = IR3;
+ }
+ p_n_cv = p_p_n_cv[ GTE_CV( gteop ) ];
+ n_lm = GTE_LM( gteop );
+ FLAG = 0;
+
+ MAC1 = A1( ( ( (int64_t)(int32_t)*p_n_cv[ 0 ] << 12 ) + ( (int16_t)*p_n_mx[ 0 ] * (int16_t)n_v1 ) + ( (int16_t)*p_n_mx[ 1 ] * (int16_t)n_v2 ) + ( (int16_t)*p_n_mx[ 2 ] * (int16_t)n_v3 ) ) >> n_sf );
+ MAC2 = A2( ( ( (int64_t)(int32_t)*p_n_cv[ 1 ] << 12 ) + ( (int16_t)*p_n_mx[ 3 ] * (int16_t)n_v1 ) + ( (int16_t)*p_n_mx[ 4 ] * (int16_t)n_v2 ) + ( (int16_t)*p_n_mx[ 5 ] * (int16_t)n_v3 ) ) >> n_sf );
+ MAC3 = A3( ( ( (int64_t)(int32_t)*p_n_cv[ 2 ] << 12 ) + ( (int16_t)*p_n_mx[ 6 ] * (int16_t)n_v1 ) + ( (int16_t)*p_n_mx[ 7 ] * (int16_t)n_v2 ) + ( (int16_t)*p_n_mx[ 8 ] * (int16_t)n_v3 ) ) >> n_sf );
+
+ IR1 = Lm_B1( (int32_t)MAC1, n_lm );
+ IR2 = Lm_B2( (int32_t)MAC2, n_lm );
+ IR3 = Lm_B3( (int32_t)MAC3, n_lm );
+ return;
+ }
+ break;
+ case 0x13:
+ if( gteop == 0x0e80413 )
+ {
+ GTELOG( "NCDS" );
+ FLAG = 0;
+
+ MAC1 = A1( ( ( (int64_t)(int16_t)L11 * (int16_t)VX0 ) + ( (int16_t)L12 * (int16_t)VY0 ) + ( (int16_t)L13 * (int16_t)VZ0 ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)(int16_t)L21 * (int16_t)VX0 ) + ( (int16_t)L22 * (int16_t)VY0 ) + ( (int16_t)L23 * (int16_t)VZ0 ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)(int16_t)L31 * (int16_t)VX0 ) + ( (int16_t)L32 * (int16_t)VY0 ) + ( (int16_t)L33 * (int16_t)VZ0 ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ MAC1 = A1( ( ( ( (int64_t)R << 4 ) * (int16_t)IR1 ) + ( (int16_t)IR0 * Lm_B1( (int32_t)RFC - ( ( R * (int16_t)IR1 ) >> 8 ), 0 ) ) ) >> 12 );
+ MAC2 = A2( ( ( ( (int64_t)G << 4 ) * (int16_t)IR2 ) + ( (int16_t)IR0 * Lm_B2( (int32_t)GFC - ( ( G * (int16_t)IR2 ) >> 8 ), 0 ) ) ) >> 12 );
+ MAC3 = A3( ( ( ( (int64_t)B << 4 ) * (int16_t)IR3 ) + ( (int16_t)IR0 * Lm_B3( (int32_t)BFC - ( ( B * (int16_t)IR3 ) >> 8 ), 0 ) ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 >> 4 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 >> 4 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 >> 4 );
+ return;
+ }
+ break;
+ case 0x14:
+ if( gteop == 0x1280414 )
+ {
+ GTELOG( "CDP" );
+ FLAG = 0;
+
+ MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
+ IR1 = Lm_B1( MAC1, 1 );
+ IR2 = Lm_B2( MAC2, 1 );
+ IR3 = Lm_B3( MAC3, 1 );
+ MAC1 = A1( ( ( ( (int64_t)R << 4 ) * (int16_t)IR1 ) + ( (int16_t)IR0 * Lm_B1( (int32_t)RFC - ( ( R * (int16_t)IR1 ) >> 8 ), 0 ) ) ) >> 12 );
+ MAC2 = A2( ( ( ( (int64_t)G << 4 ) * (int16_t)IR2 ) + ( (int16_t)IR0 * Lm_B2( (int32_t)GFC - ( ( G * (int16_t)IR2 ) >> 8 ), 0 ) ) ) >> 12 );
+ MAC3 = A3( ( ( ( (int64_t)B << 4 ) * (int16_t)IR3 ) + ( (int16_t)IR0 * Lm_B3( (int32_t)BFC - ( ( B * (int16_t)IR3 ) >> 8 ), 0 ) ) ) >> 12 );
+ IR1 = Lm_B1( MAC1, 1 );
+ IR2 = Lm_B2( MAC2, 1 );
+ IR3 = Lm_B3( MAC3, 1 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 >> 4 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 >> 4 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 >> 4 );
+ return;
+ }
+ break;
+ case 0x16:
+ if( gteop == 0x0f80416 )
+ {
+ GTELOG( "NCDT" );
+ FLAG = 0;
+
+ for( n_v = 0; n_v < 3; n_v++ )
+ {
+ MAC1 = A1( ( ( (int64_t)(int16_t)L11 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L12 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L13 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)(int16_t)L21 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L22 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L23 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)(int16_t)L31 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L32 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L33 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ MAC1 = A1( ( ( ( (int64_t)R << 4 ) * (int16_t)IR1 ) + ( (int16_t)IR0 * Lm_B1( (int32_t)RFC - ( ( R * (int16_t)IR1 ) >> 8 ), 0 ) ) ) >> 12 );
+ MAC2 = A2( ( ( ( (int64_t)G << 4 ) * (int16_t)IR2 ) + ( (int16_t)IR0 * Lm_B2( (int32_t)GFC - ( ( G * (int16_t)IR2 ) >> 8 ), 0 ) ) ) >> 12 );
+ MAC3 = A3( ( ( ( (int64_t)B << 4 ) * (int16_t)IR3 ) + ( (int16_t)IR0 * Lm_B3( (int32_t)BFC - ( ( B * (int16_t)IR3 ) >> 8 ), 0 ) ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 >> 4 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 >> 4 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 >> 4 );
+ }
+ return;
+ }
+ break;
+ case 0x1b:
+ if( gteop == 0x108041b )
+ {
+ GTELOG( "NCCS" );
+ FLAG = 0;
+
+ MAC1 = A1( ( ( (int64_t)(int16_t)L11 * (int16_t)VX0 ) + ( (int16_t)L12 * (int16_t)VY0 ) + ( (int16_t)L13 * (int16_t)VZ0 ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)(int16_t)L21 * (int16_t)VX0 ) + ( (int16_t)L22 * (int16_t)VY0 ) + ( (int16_t)L23 * (int16_t)VZ0 ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)(int16_t)L31 * (int16_t)VX0 ) + ( (int16_t)L32 * (int16_t)VY0 ) + ( (int16_t)L33 * (int16_t)VZ0 ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ MAC1 = A1( ( (int64_t)R * (int16_t)IR1 ) >> 8 );
+ MAC2 = A2( ( (int64_t)G * (int16_t)IR2 ) >> 8 );
+ MAC3 = A3( ( (int64_t)B * (int16_t)IR3 ) >> 8 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 >> 4 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 >> 4 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 >> 4 );
+ return;
+ }
+ break;
+ case 0x1c:
+ if( gteop == 0x138041c )
+ {
+ GTELOG( "CC" );
+ FLAG = 0;
+
+ MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
+ IR1 = Lm_B1( MAC1, 1 );
+ IR2 = Lm_B2( MAC2, 1 );
+ IR3 = Lm_B3( MAC3, 1 );
+ MAC1 = A1( ( (int64_t)R * (int16_t)IR1 ) >> 8 );
+ MAC2 = A2( ( (int64_t)G * (int16_t)IR2 ) >> 8 );
+ MAC3 = A3( ( (int64_t)B * (int16_t)IR3 ) >> 8 );
+ IR1 = Lm_B1( MAC1, 1 );
+ IR2 = Lm_B2( MAC2, 1 );
+ IR3 = Lm_B3( MAC3, 1 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 >> 4 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 >> 4 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 >> 4 );
+ return;
+ }
+ break;
+ case 0x1e:
+ if( gteop == 0x0c8041e )
+ {
+ GTELOG( "NCS" );
+ FLAG = 0;
+
+ MAC1 = A1( ( ( (int64_t)(int16_t)L11 * (int16_t)VX0 ) + ( (int16_t)L12 * (int16_t)VY0 ) + ( (int16_t)L13 * (int16_t)VZ0 ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)(int16_t)L21 * (int16_t)VX0 ) + ( (int16_t)L22 * (int16_t)VY0 ) + ( (int16_t)L23 * (int16_t)VZ0 ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)(int16_t)L31 * (int16_t)VX0 ) + ( (int16_t)L32 * (int16_t)VY0 ) + ( (int16_t)L33 * (int16_t)VZ0 ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 >> 4 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 >> 4 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 >> 4 );
+ return;
+ }
+ break;
+ case 0x20:
+ if( gteop == 0x0d80420 )
+ {
+ GTELOG( "NCT" );
+ FLAG = 0;
+
+ for( n_v = 0; n_v < 3; n_v++ )
+ {
+ MAC1 = A1( ( ( (int64_t)(int16_t)L11 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L12 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L13 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)(int16_t)L21 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L22 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L23 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)(int16_t)L31 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L32 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L33 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 >> 4 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 >> 4 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 >> 4 );
+ }
+ return;
+ }
+ break;
+ case 0x28:
+ if( GTE_OP( gteop ) == 0x0a && GTE_LM( gteop ) == 1 )
+ {
+ GTELOG( "SQR" );
+ n_sf = 12 * GTE_SF( gteop );
+ FLAG = 0;
+
+ MAC1 = A1( ( (int64_t)(int16_t)IR1 * (int16_t)IR1 ) >> n_sf );
+ MAC2 = A2( ( (int64_t)(int16_t)IR2 * (int16_t)IR2 ) >> n_sf );
+ MAC3 = A3( ( (int64_t)(int16_t)IR3 * (int16_t)IR3 ) >> n_sf );
+ IR1 = Lm_B1( MAC1, 1 );
+ IR2 = Lm_B2( MAC2, 1 );
+ IR3 = Lm_B3( MAC3, 1 );
+ return;
+ }
+ break;
+ // DCPL 0x29
+ case 0x2a:
+ if( gteop == 0x0f8002a )
+ {
+ GTELOG( "DPCT" );
+ FLAG = 0;
+
+ for( n_pass = 0; n_pass < 3; n_pass++ )
+ {
+ MAC1 = A1( ( ( (int64_t)R0 << 16 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)RFC - ( R0 << 4 ), 0 ) ) ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)G0 << 16 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)GFC - ( G0 << 4 ), 0 ) ) ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)B0 << 16 ) + ( (int64_t)(int16_t)IR0 * ( Lm_B1( (int32_t)BFC - ( B0 << 4 ), 0 ) ) ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 0 );
+ IR2 = Lm_B2( (int32_t)MAC2, 0 );
+ IR3 = Lm_B3( (int32_t)MAC3, 0 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 >> 4 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 >> 4 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 >> 4 );
+ }
+ return;
+ }
+ break;
+ case 0x2d:
+ if( gteop == 0x158002d )
+ {
+ GTELOG( "AVSZ3" );
+ FLAG = 0;
+
+ MAC0 = F( ( (int64_t)(int16_t)ZSF3 * SZ1 ) + ( (int16_t)ZSF3 * SZ2 ) + ( (int16_t)ZSF3 * SZ3 ) );
+ OTZ = Lm_D( (int32_t)MAC0 >> 12 );
+ return;
+ }
+ break;
+ case 0x2e:
+ if( gteop == 0x168002e )
+ {
+ GTELOG( "AVSZ4" );
+ FLAG = 0;
+
+ MAC0 = F( ( (int64_t)(int16_t)ZSF4 * SZ0 ) + ( (int16_t)ZSF4 * SZ1 ) + ( (int16_t)ZSF4 * SZ2 ) + ( (int16_t)ZSF4 * SZ3 ) );
+ OTZ = Lm_D( (int32_t)MAC0 >> 12 );
+ return;
+ }
+ break;
+ case 0x30:
+ if( gteop == 0x0280030 )
+ {
+ GTELOG( "RTPT" );
+ FLAG = 0;
+
+ for( n_v = 0; n_v < 3; n_v++ )
+ {
+ MAC1 = A1( ( ( (int64_t)(int32_t)TRX << 12 ) + ( (int16_t)R11 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)R12 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)R13 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)(int32_t)TRY << 12 ) + ( (int16_t)R21 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)R22 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)R23 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)(int32_t)TRZ << 12 ) + ( (int16_t)R31 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)R32 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)R33 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 0 );
+ IR2 = Lm_B2( (int32_t)MAC2, 0 );
+ IR3 = Lm_B3( (int32_t)MAC3, 0 );
+ SZ0 = SZ1;
+ SZ1 = SZ2;
+ SZ2 = SZ3;
+ SZ3 = Lm_D( (int32_t)MAC3 );
+ SXY0 = SXY1;
+ SXY1 = SXY2;
+ SX2 = Lm_G1( F( ( (int64_t)(int32_t)OFX + ( (int64_t)(int16_t)IR1 * ( ( (uint32_t)H << 16 ) / Lm_E( SZ3 ) ) ) ) >> 16 ) );
+ SY2 = Lm_G2( F( ( (int64_t)(int32_t)OFY + ( (int64_t)(int16_t)IR2 * ( ( (uint32_t)H << 16 ) / Lm_E( SZ3 ) ) ) ) >> 16 ) );
+ MAC0 = F( (int64_t)(int32_t)DQB + ( (int64_t)(int16_t)DQA * ( ( (uint32_t)H << 16 ) / Lm_E( SZ3 ) ) ) );
+ IR0 = Lm_H( (int32_t)MAC0 >> 12 );
+ }
+ return;
+ }
+ break;
+ case 0x3d:
+ if( GTE_OP( gteop ) == 0x09 ||
+ GTE_OP( gteop ) == 0x19 )
+ {
+ GTELOG( "GPF" );
+ n_sf = 12 * GTE_SF( gteop );
+ FLAG = 0;
+
+ MAC1 = A1( ( (int64_t)(int16_t)IR0 * (int16_t)IR1 ) >> n_sf );
+ MAC2 = A2( ( (int64_t)(int16_t)IR0 * (int16_t)IR2 ) >> n_sf );
+ MAC3 = A3( ( (int64_t)(int16_t)IR0 * (int16_t)IR3 ) >> n_sf );
+ IR1 = Lm_B1( (int32_t)MAC1, 0 );
+ IR2 = Lm_B2( (int32_t)MAC2, 0 );
+ IR3 = Lm_B3( (int32_t)MAC3, 0 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 >> 4 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 >> 4 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 >> 4 );
+ return;
+ }
+ break;
+ case 0x3e:
+ if( GTE_OP( gteop ) == 0x1a )
+ {
+ GTELOG( "GPL" );
+ n_sf = 12 * GTE_SF( gteop );
+ FLAG = 0;
+
+ MAC1 = A1( ( ( (int64_t)(int32_t)MAC1 << n_sf ) + ( (int16_t)IR0 * (int16_t)IR1 ) ) >> n_sf );
+ MAC2 = A2( ( ( (int64_t)(int32_t)MAC2 << n_sf ) + ( (int16_t)IR0 * (int16_t)IR2 ) ) >> n_sf );
+ MAC3 = A3( ( ( (int64_t)(int32_t)MAC3 << n_sf ) + ( (int16_t)IR0 * (int16_t)IR3 ) ) >> n_sf );
+ IR1 = Lm_B1( (int32_t)MAC1, 0 );
+ IR2 = Lm_B2( (int32_t)MAC2, 0 );
+ IR3 = Lm_B3( (int32_t)MAC3, 0 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 >> 4 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 >> 4 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 >> 4 );
+ return;
+ }
+ break;
+ case 0x3f:
+ if( gteop == 0x108043f ||
+ gteop == 0x118043f )
+ {
+ GTELOG( "NCCT" );
+ FLAG = 0;
+
+ for( n_v = 0; n_v < 3; n_v++ )
+ {
+ MAC1 = A1( ( ( (int64_t)(int16_t)L11 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L12 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L13 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)(int16_t)L21 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L22 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L23 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)(int16_t)L31 * (int16_t)*p_n_vx[ n_v ] ) + ( (int16_t)L32 * (int16_t)*p_n_vy[ n_v ] ) + ( (int16_t)L33 * (int16_t)*p_n_vz[ n_v ] ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ MAC1 = A1( ( ( (int64_t)RBK << 12 ) + ( (int16_t)LR1 * (int16_t)IR1 ) + ( (int16_t)LR2 * (int16_t)IR2 ) + ( (int16_t)LR3 * (int16_t)IR3 ) ) >> 12 );
+ MAC2 = A2( ( ( (int64_t)GBK << 12 ) + ( (int16_t)LG1 * (int16_t)IR1 ) + ( (int16_t)LG2 * (int16_t)IR2 ) + ( (int16_t)LG3 * (int16_t)IR3 ) ) >> 12 );
+ MAC3 = A3( ( ( (int64_t)BBK << 12 ) + ( (int16_t)LB1 * (int16_t)IR1 ) + ( (int16_t)LB2 * (int16_t)IR2 ) + ( (int16_t)LB3 * (int16_t)IR3 ) ) >> 12 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ MAC1 = A1( ( (int64_t)R * (int16_t)IR1 ) >> 8 );
+ MAC2 = A2( ( (int64_t)G * (int16_t)IR2 ) >> 8 );
+ MAC3 = A3( ( (int64_t)B * (int16_t)IR3 ) >> 8 );
+ IR1 = Lm_B1( (int32_t)MAC1, 1 );
+ IR2 = Lm_B2( (int32_t)MAC2, 1 );
+ IR3 = Lm_B3( (int32_t)MAC3, 1 );
+ CD0 = CD1;
+ CD1 = CD2;
+ CD2 = CODE;
+ R0 = R1;
+ R1 = R2;
+ R2 = Lm_C1( (int32_t)MAC1 >> 4 );
+ G0 = G1;
+ G1 = G2;
+ G2 = Lm_C2( (int32_t)MAC2 >> 4 );
+ B0 = B1;
+ B1 = B2;
+ B2 = Lm_C3( (int32_t)MAC3 >> 4 );
+ }
+ return;
+ }
+ break;
+ }
+// usrintf_showmessage_secs( 1, "unknown GTE op %08x", gteop );
+ logerror( "%08x: unknown GTE op %08x\n", mipscpu.pc, gteop );
+ mips_stop();
+}
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+void mips_set_info(uint32_t state, union cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_INPUT_STATE + MIPS_IRQ0: set_irq_line(MIPS_IRQ0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + MIPS_IRQ1: set_irq_line(MIPS_IRQ1, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + MIPS_IRQ2: set_irq_line(MIPS_IRQ2, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + MIPS_IRQ3: set_irq_line(MIPS_IRQ3, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + MIPS_IRQ4: set_irq_line(MIPS_IRQ4, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + MIPS_IRQ5: set_irq_line(MIPS_IRQ5, info->i); break;
+
+ case CPUINFO_INT_PC: mips_set_pc( info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_PC: mips_set_pc( info->i ); break;
+ case CPUINFO_INT_SP: /* no stack */ break;
+ case CPUINFO_INT_REGISTER + MIPS_DELAYV: mipscpu.delayv = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_DELAYR: if( info->i <= REGPC ) mipscpu.delayr = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_HI: mipscpu.hi = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_LO: mipscpu.lo = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R0: mipscpu.r[ 0 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R1: mipscpu.r[ 1 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R2: mipscpu.r[ 2 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R3: mipscpu.r[ 3 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R4: mipscpu.r[ 4 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R5: mipscpu.r[ 5 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R6: mipscpu.r[ 6 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R7: mipscpu.r[ 7 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R8: mipscpu.r[ 8 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R9: mipscpu.r[ 9 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R10: mipscpu.r[ 10 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R11: mipscpu.r[ 11 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R12: mipscpu.r[ 12 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R13: mipscpu.r[ 13 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R14: mipscpu.r[ 14 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R15: mipscpu.r[ 15 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R16: mipscpu.r[ 16 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R17: mipscpu.r[ 17 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R18: mipscpu.r[ 18 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R19: mipscpu.r[ 19 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R20: mipscpu.r[ 20 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R21: mipscpu.r[ 21 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R22: mipscpu.r[ 22 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R23: mipscpu.r[ 23 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R24: mipscpu.r[ 24 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R25: mipscpu.r[ 25 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R26: mipscpu.r[ 26 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R27: mipscpu.r[ 27 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R28: mipscpu.r[ 28 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R29: mipscpu.r[ 29 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R30: mipscpu.r[ 30 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_R31: mipscpu.r[ 31 ] = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R0: mips_set_cp0r( 0, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R1: mips_set_cp0r( 1, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R2: mips_set_cp0r( 2, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R3: mips_set_cp0r( 3, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R4: mips_set_cp0r( 4, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R5: mips_set_cp0r( 5, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R6: mips_set_cp0r( 6, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R7: mips_set_cp0r( 7, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R8: mips_set_cp0r( 8, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R9: mips_set_cp0r( 9, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R10: mips_set_cp0r( 10, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R11: mips_set_cp0r( 11, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R12: mips_set_cp0r( 12, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R13: mips_set_cp0r( 13, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R14: mips_set_cp0r( 14, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R15: mips_set_cp0r( 15, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R16: mips_set_cp0r( 16, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R17: mips_set_cp0r( 17, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R18: mips_set_cp0r( 18, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R19: mips_set_cp0r( 19, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R20: mips_set_cp0r( 20, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R21: mips_set_cp0r( 21, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R22: mips_set_cp0r( 22, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R23: mips_set_cp0r( 23, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R24: mips_set_cp0r( 24, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R25: mips_set_cp0r( 25, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R26: mips_set_cp0r( 26, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R27: mips_set_cp0r( 27, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R28: mips_set_cp0r( 28, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R29: mips_set_cp0r( 29, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R30: mips_set_cp0r( 30, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R31: mips_set_cp0r( 31, info->i ); break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR0: mipscpu.cp2dr[ 0 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR1: mipscpu.cp2dr[ 1 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR2: mipscpu.cp2dr[ 2 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR3: mipscpu.cp2dr[ 3 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR4: mipscpu.cp2dr[ 4 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR5: mipscpu.cp2dr[ 5 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR6: mipscpu.cp2dr[ 6 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR7: mipscpu.cp2dr[ 7 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR8: mipscpu.cp2dr[ 8 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR9: mipscpu.cp2dr[ 9 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR10: mipscpu.cp2dr[ 10 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR11: mipscpu.cp2dr[ 11 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR12: mipscpu.cp2dr[ 12 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR13: mipscpu.cp2dr[ 13 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR14: mipscpu.cp2dr[ 14 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR15: mipscpu.cp2dr[ 15 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR16: mipscpu.cp2dr[ 16 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR17: mipscpu.cp2dr[ 17 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR18: mipscpu.cp2dr[ 18 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR19: mipscpu.cp2dr[ 19 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR20: mipscpu.cp2dr[ 20 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR21: mipscpu.cp2dr[ 21 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR22: mipscpu.cp2dr[ 22 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR23: mipscpu.cp2dr[ 23 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR24: mipscpu.cp2dr[ 24 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR25: mipscpu.cp2dr[ 25 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR26: mipscpu.cp2dr[ 26 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR27: mipscpu.cp2dr[ 27 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR28: mipscpu.cp2dr[ 28 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR29: mipscpu.cp2dr[ 29 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR30: mipscpu.cp2dr[ 30 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR31: mipscpu.cp2dr[ 31 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR0: mipscpu.cp2cr[ 0 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR1: mipscpu.cp2cr[ 1 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR2: mipscpu.cp2cr[ 2 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR3: mipscpu.cp2cr[ 3 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR4: mipscpu.cp2cr[ 4 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR5: mipscpu.cp2cr[ 5 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR6: mipscpu.cp2cr[ 6 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR7: mipscpu.cp2cr[ 7 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR8: mipscpu.cp2cr[ 8 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR9: mipscpu.cp2cr[ 9 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR10: mipscpu.cp2cr[ 10 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR11: mipscpu.cp2cr[ 11 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR12: mipscpu.cp2cr[ 12 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR13: mipscpu.cp2cr[ 13 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR14: mipscpu.cp2cr[ 14 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR15: mipscpu.cp2cr[ 15 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR16: mipscpu.cp2cr[ 16 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR17: mipscpu.cp2cr[ 17 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR18: mipscpu.cp2cr[ 18 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR19: mipscpu.cp2cr[ 19 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR20: mipscpu.cp2cr[ 20 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR21: mipscpu.cp2cr[ 21 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR22: mipscpu.cp2cr[ 22 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR23: mipscpu.cp2cr[ 23 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR24: mipscpu.cp2cr[ 24 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR25: mipscpu.cp2cr[ 25 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR26: mipscpu.cp2cr[ 26 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR27: mipscpu.cp2cr[ 27 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR28: mipscpu.cp2cr[ 28 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR29: mipscpu.cp2cr[ 29 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR30: mipscpu.cp2cr[ 30 ].d = info->i; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR31: mipscpu.cp2cr[ 31 ].d = info->i; break;
+
+ /* --- the following bits of info are set as pointers to data or functions --- */
+ case CPUINFO_PTR_IRQ_CALLBACK: mipscpu.irq_callback = info->irqcallback; break;
+ }
+}
+
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+void mips_get_info(uint32_t state, union cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(mipscpu); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 6; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
+ case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 4; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 40; break;
+
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
+
+ case CPUINFO_INT_INPUT_STATE + MIPS_IRQ0: info->i = (mipscpu.cp0r[ CP0_CAUSE ] & 0x400) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + MIPS_IRQ1: info->i = (mipscpu.cp0r[ CP0_CAUSE ] & 0x800) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + MIPS_IRQ2: info->i = (mipscpu.cp0r[ CP0_CAUSE ] & 0x1000) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + MIPS_IRQ3: info->i = (mipscpu.cp0r[ CP0_CAUSE ] & 0x2000) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + MIPS_IRQ4: info->i = (mipscpu.cp0r[ CP0_CAUSE ] & 0x4000) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + MIPS_IRQ5: info->i = (mipscpu.cp0r[ CP0_CAUSE ] & 0x8000) ? ASSERT_LINE : CLEAR_LINE; break;
+
+ case CPUINFO_INT_PREVIOUSPC: /* not implemented */ break;
+
+ case CPUINFO_INT_PC: info->i = mipscpu.pc; break;
+ case CPUINFO_INT_REGISTER + MIPS_PC: info->i = mipscpu.pc; break;
+ case CPUINFO_INT_SP:
+ /* because there is no hardware stack and the pipeline causes the cpu to execute the
+ instruction after a subroutine call before the subroutine is executed there is little
+ chance of cmd_step_over() in mamedbg.c working. */
+ info->i = 0; break;
+ case CPUINFO_INT_REGISTER + MIPS_DELAYV: info->i = mipscpu.delayv; break;
+ case CPUINFO_INT_REGISTER + MIPS_DELAYR: info->i = mipscpu.delayr; break;
+ case CPUINFO_INT_REGISTER + MIPS_HI: info->i = mipscpu.hi; break;
+ case CPUINFO_INT_REGISTER + MIPS_LO: info->i = mipscpu.lo; break;
+ case CPUINFO_INT_REGISTER + MIPS_R0: info->i = mipscpu.r[ 0 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R1: info->i = mipscpu.r[ 1 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R2: info->i = mipscpu.r[ 2 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R3: info->i = mipscpu.r[ 3 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R4: info->i = mipscpu.r[ 4 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R5: info->i = mipscpu.r[ 5 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R6: info->i = mipscpu.r[ 6 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R7: info->i = mipscpu.r[ 7 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R8: info->i = mipscpu.r[ 8 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R9: info->i = mipscpu.r[ 9 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R10: info->i = mipscpu.r[ 10 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R11: info->i = mipscpu.r[ 11 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R12: info->i = mipscpu.r[ 12 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R13: info->i = mipscpu.r[ 13 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R14: info->i = mipscpu.r[ 14 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R15: info->i = mipscpu.r[ 15 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R16: info->i = mipscpu.r[ 16 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R17: info->i = mipscpu.r[ 17 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R18: info->i = mipscpu.r[ 18 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R19: info->i = mipscpu.r[ 19 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R20: info->i = mipscpu.r[ 20 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R21: info->i = mipscpu.r[ 21 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R22: info->i = mipscpu.r[ 22 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R23: info->i = mipscpu.r[ 23 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R24: info->i = mipscpu.r[ 24 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R25: info->i = mipscpu.r[ 25 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R26: info->i = mipscpu.r[ 26 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R27: info->i = mipscpu.r[ 27 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R28: info->i = mipscpu.r[ 28 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R29: info->i = mipscpu.r[ 29 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R30: info->i = mipscpu.r[ 30 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_R31: info->i = mipscpu.r[ 31 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R0: info->i = mipscpu.cp0r[ 0 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R1: info->i = mipscpu.cp0r[ 1 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R2: info->i = mipscpu.cp0r[ 2 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R3: info->i = mipscpu.cp0r[ 3 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R4: info->i = mipscpu.cp0r[ 4 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R5: info->i = mipscpu.cp0r[ 5 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R6: info->i = mipscpu.cp0r[ 6 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R7: info->i = mipscpu.cp0r[ 7 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R8: info->i = mipscpu.cp0r[ 8 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R9: info->i = mipscpu.cp0r[ 9 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R10: info->i = mipscpu.cp0r[ 10 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R11: info->i = mipscpu.cp0r[ 11 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R12: info->i = mipscpu.cp0r[ 12 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R13: info->i = mipscpu.cp0r[ 13 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R14: info->i = mipscpu.cp0r[ 14 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R15: info->i = mipscpu.cp0r[ 15 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R16: info->i = mipscpu.cp0r[ 16 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R17: info->i = mipscpu.cp0r[ 17 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R18: info->i = mipscpu.cp0r[ 18 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R19: info->i = mipscpu.cp0r[ 19 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R20: info->i = mipscpu.cp0r[ 20 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R21: info->i = mipscpu.cp0r[ 21 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R22: info->i = mipscpu.cp0r[ 22 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R23: info->i = mipscpu.cp0r[ 23 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R24: info->i = mipscpu.cp0r[ 24 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R25: info->i = mipscpu.cp0r[ 25 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R26: info->i = mipscpu.cp0r[ 26 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R27: info->i = mipscpu.cp0r[ 27 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R28: info->i = mipscpu.cp0r[ 28 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R29: info->i = mipscpu.cp0r[ 29 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R30: info->i = mipscpu.cp0r[ 30 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP0R31: info->i = mipscpu.cp0r[ 31 ]; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR0: info->i = mipscpu.cp2dr[ 0 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR1: info->i = mipscpu.cp2dr[ 1 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR2: info->i = mipscpu.cp2dr[ 2 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR3: info->i = mipscpu.cp2dr[ 3 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR4: info->i = mipscpu.cp2dr[ 4 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR5: info->i = mipscpu.cp2dr[ 5 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR6: info->i = mipscpu.cp2dr[ 6 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR7: info->i = mipscpu.cp2dr[ 7 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR8: info->i = mipscpu.cp2dr[ 8 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR9: info->i = mipscpu.cp2dr[ 9 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR10: info->i = mipscpu.cp2dr[ 10 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR11: info->i = mipscpu.cp2dr[ 11 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR12: info->i = mipscpu.cp2dr[ 12 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR13: info->i = mipscpu.cp2dr[ 13 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR14: info->i = mipscpu.cp2dr[ 14 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR15: info->i = mipscpu.cp2dr[ 15 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR16: info->i = mipscpu.cp2dr[ 16 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR17: info->i = mipscpu.cp2dr[ 17 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR18: info->i = mipscpu.cp2dr[ 18 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR19: info->i = mipscpu.cp2dr[ 19 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR20: info->i = mipscpu.cp2dr[ 20 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR21: info->i = mipscpu.cp2dr[ 21 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR22: info->i = mipscpu.cp2dr[ 22 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR23: info->i = mipscpu.cp2dr[ 23 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR24: info->i = mipscpu.cp2dr[ 24 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR25: info->i = mipscpu.cp2dr[ 25 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR26: info->i = mipscpu.cp2dr[ 26 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR27: info->i = mipscpu.cp2dr[ 27 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR28: info->i = mipscpu.cp2dr[ 28 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR29: info->i = mipscpu.cp2dr[ 29 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR30: info->i = mipscpu.cp2dr[ 30 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2DR31: info->i = mipscpu.cp2dr[ 31 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR0: info->i = mipscpu.cp2cr[ 0 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR1: info->i = mipscpu.cp2cr[ 1 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR2: info->i = mipscpu.cp2cr[ 2 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR3: info->i = mipscpu.cp2cr[ 3 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR4: info->i = mipscpu.cp2cr[ 4 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR5: info->i = mipscpu.cp2cr[ 5 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR6: info->i = mipscpu.cp2cr[ 6 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR7: info->i = mipscpu.cp2cr[ 7 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR8: info->i = mipscpu.cp2cr[ 8 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR9: info->i = mipscpu.cp2cr[ 9 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR10: info->i = mipscpu.cp2cr[ 10 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR11: info->i = mipscpu.cp2cr[ 11 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR12: info->i = mipscpu.cp2cr[ 12 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR13: info->i = mipscpu.cp2cr[ 13 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR14: info->i = mipscpu.cp2cr[ 14 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR15: info->i = mipscpu.cp2cr[ 15 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR16: info->i = mipscpu.cp2cr[ 16 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR17: info->i = mipscpu.cp2cr[ 17 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR18: info->i = mipscpu.cp2cr[ 18 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR19: info->i = mipscpu.cp2cr[ 19 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR20: info->i = mipscpu.cp2cr[ 20 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR21: info->i = mipscpu.cp2cr[ 21 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR22: info->i = mipscpu.cp2cr[ 22 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR23: info->i = mipscpu.cp2cr[ 23 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR24: info->i = mipscpu.cp2cr[ 24 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR25: info->i = mipscpu.cp2cr[ 25 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR26: info->i = mipscpu.cp2cr[ 26 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR27: info->i = mipscpu.cp2cr[ 27 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR28: info->i = mipscpu.cp2cr[ 28 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR29: info->i = mipscpu.cp2cr[ 29 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR30: info->i = mipscpu.cp2cr[ 30 ].d; break;
+ case CPUINFO_INT_REGISTER + MIPS_CP2CR31: info->i = mipscpu.cp2cr[ 31 ].d; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_SET_INFO: info->setinfo = mips_set_info; break;
+ case CPUINFO_PTR_GET_CONTEXT: info->getcontext = mips_get_context; break;
+ case CPUINFO_PTR_SET_CONTEXT: info->setcontext = mips_set_context; break;
+ case CPUINFO_PTR_INIT: info->init = mips_init; break;
+ case CPUINFO_PTR_RESET: info->reset = mips_reset; break;
+ case CPUINFO_PTR_EXIT: info->exit = mips_exit; break;
+ case CPUINFO_PTR_EXECUTE: info->execute = mips_execute; break;
+ case CPUINFO_PTR_BURN: info->burn = nullptr; break;
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = mips_dasm; break;
+ case CPUINFO_PTR_IRQ_CALLBACK: info->irqcallback = mipscpu.irq_callback; break;
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &mips_ICount; break;
+ case CPUINFO_PTR_REGISTER_LAYOUT: info->p = mips_reg_layout; break;
+ case CPUINFO_PTR_WINDOW_LAYOUT: info->p = mips_win_layout; break;
+ }
+}
+
+uint32_t mips_get_cause(void)
+{
+ return mipscpu.cp0r[ CP0_CAUSE ];
+}
+
+uint32_t mips_get_status(void)
+{
+ return mipscpu.cp0r[ CP0_SR ];
+}
+
+void mips_set_status(uint32_t status)
+{
+ mipscpu.cp0r[ CP0_SR ] = status;
+}
+
+uint32_t mips_get_ePC(void)
+{
+ return mipscpu.cp0r[ CP0_EPC ];
+}
+
+int mips_get_icount(void)
+{
+ return mips_ICount;
+}
+
+void mips_set_icount(int count)
+{
+ mips_ICount = count;
+}
+
+
+#if (HAS_PSXCPU)
+/**************************************************************************
+ * CPU-specific set_info
+ **************************************************************************/
+
+void psxcpu_get_info(uint32_t state, union cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as nullptr-terminated strings --- */
+// case CPUINFO_STR_NAME: strcpy(info->s = cpuintrf_temp_str(), "PSX CPU"); break;
+
+ default:
+ mips_get_info(state, info);
+ break;
+ }
+}
+#endif
diff --git a/src/psf/psx_hw.c b/src/psf/psx_hw.c
deleted file mode 100644
index 9fdfd6d1b47a..000000000000
--- a/src/psf/psx_hw.c
+++ /dev/null
@@ -1,3543 +0,0 @@
-/*
- Audio Overload SDK - PSX and IOP hardware emulation
-
- Copyright (c) 2007 R. Belmont and Richard Bannister.
-
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*
- psx_hw.c - Minimal PSX/IOP hardware glue/emulation/whatever
-
- supported: main RAM (2 MB, mirrored to fill an 8 MB space like on real HW)
- DMA channel 4 (SPURAM) in both directions (including completion IRQ)
- VBL IRQ
- Root counters 2 and 3 including completion events and IRQs
- Some BIOS services including exception handling (via HLE)
- HLE emulation of IOP operating system, including multithreading
- SPU(2), SPU(2)RAM (via PEOpS)
-
-
-
- Special notes:
- PSF1
- - Chocobo's Dungeon 2 contains an illegal code sequence (patched)
-
- PSF2
- - Shadow Hearts assumes that the wave buffer alloc will go to 0x80060000 and the sequence buffer to 0x80170000.
- Our memory management doesn't work out that way, so we have to (wait for it) cheese it.
-*/
-
-#include <stdio.h>
-#include <glib.h>
-
-#include "ao.h"
-#include "cpuintrf.h"
-#include "psx.h"
-
-#define DEBUG_HLE_BIOS (0) // debug PS1 HLE BIOS
-#define DEBUG_SPU (0) // debug PS1 SPU read/write
-#define DEBUG_SPU2 (0) // debug PS2 SPU read/write
-#define DEBUG_HLE_IOP (0) // debug PS2 IOP OS calls
-#define DEBUG_UNK_RW (0) // debug unknown reads/writes
-#define DEBUG_THREADING (0) // debug PS2 IOP threading
-
-#define LE32(x) GUINT32_FROM_LE(x)
-
-extern void mips_get_info(uint32_t state, union cpuinfo *info);
-extern void mips_set_info(uint32_t state, union cpuinfo *info);
-extern int psxcpu_verbose;
-extern uint16_t SPUreadRegister(uint32_t reg);
-extern void SPUwriteRegister(uint32_t reg, uint16_t val);
-extern void SPUwriteDMAMem(uint32_t usPSXMem,int iSize);
-extern void SPUreadDMAMem(uint32_t usPSXMem,int iSize);
-extern void mips_shorten_frame(void);
-extern int mips_execute( int cycles );
-extern uint32_t psf2_load_file(char *file, uint8_t *buf, uint32_t buflen);
-extern uint32_t psf2_load_elf(uint8_t *start, uint32_t len);
-void psx_hw_runcounters(void);
-int mips_get_icount(void);
-void mips_set_icount(int count);
-
-extern int psf_refresh;
-
-// SPU2
-extern void SPU2write(unsigned long reg, unsigned short val);
-extern unsigned short SPU2read(unsigned long reg);
-extern void SPU2readDMA4Mem(uint32_t usPSXMem,int iSize);
-extern void SPU2writeDMA4Mem(uint32_t usPSXMem,int iSize);
-extern void SPU2readDMA7Mem(uint32_t usPSXMem,int iSize);
-extern void SPU2writeDMA7Mem(uint32_t usPSXMem,int iSize);
-extern void SPU2interruptDMA4(void);
-extern void SPU2interruptDMA7(void);
-
-#define MAX_FILE_SLOTS (32)
-
-static volatile int softcall_target = 0;
-static int filestat[MAX_FILE_SLOTS];
-static uint8_t *filedata[MAX_FILE_SLOTS];
-static uint32_t filesize[MAX_FILE_SLOTS], filepos[MAX_FILE_SLOTS];
-uint32_t psf2_get_loadaddr(void);
-void psf2_set_loadaddr(uint32_t new);
-static void call_irq_routine(uint32_t routine, uint32_t parameter);
-static int intr_susp = 0;
-
-static uint64_t sys_time;
-static int timerexp = 0;
-
-typedef struct
-{
- char name[10];
- uint32_t dispatch;
-} ExternLibEntries;
-
-static int32_t iNumLibs;
-static ExternLibEntries reglibs[32];
-
-typedef struct
-{
- uint32_t type;
- uint32_t value;
- uint32_t param;
- int inUse;
-} EventFlag;
-
-static int32_t iNumFlags;
-static EventFlag evflags[32];
-
-typedef struct
-{
- uint32_t attr;
- uint32_t option;
- int32_t init;
- int32_t current;
- int32_t max;
- int32_t threadsWaiting;
- int32_t inuse;
-} Semaphore;
-
-#define SEMA_MAX (64)
-
-static int32_t iNumSema;
-static Semaphore semaphores[SEMA_MAX];
-
-// thread states
-enum
-{
- TS_RUNNING = 0, // now running
- TS_READY, // ready to run
- TS_WAITEVFLAG, // waiting on an event flag
- TS_WAITSEMA, // waiting on a semaphore
- TS_WAITDELAY, // waiting on a time delay
- TS_SLEEPING, // sleeping
- TS_CREATED, // newly created, hasn't run yet
-
- TS_MAXSTATE
-};
-
-typedef struct
-{
- int32_t iState; // state of thread
-
- uint32_t flags; // flags
- uint32_t routine; // start of code for the thread
- uint32_t stackloc; // stack location in IOP RAM
- uint32_t stacksize; // stack size
- uint32_t refCon; // user value passed in at CreateThread time
-
- uint32_t waitparm; // what we're waiting on if in one the TS_WAIT* states
-
- uint32_t save_regs[37]; // CPU registers belonging to this thread
-} Thread;
-
-static int32_t iNumThreads, iCurThread;
-static Thread threads[32];
-
-#if DEBUG_THREADING
-static char *_ThreadStateNames[TS_MAXSTATE] = { "RUNNING", "READY", "WAITEVFLAG", "WAITSEMA", "WAITDELAY", "SLEEPING", "CREATED" };
-#endif
-
-#if DEBUG_HLE_IOP
-static char *seek_types[3] = { "SEEK_SET", "SEEK_CUR", "SEEK_END" };
-#endif
-
-typedef struct
-{
- int32_t iActive;
- uint32_t count;
- uint32_t target;
- uint32_t source;
- uint32_t prescale;
- uint32_t handler;
- uint32_t hparam;
- uint32_t mode;
-} IOPTimer;
-
-static IOPTimer iop_timers[8];
-static int32_t iNumTimers;
-
-typedef struct
-{
- uint32_t count;
- uint32_t mode;
- uint32_t target;
- uint32_t sysclock;
- uint32_t interrupt;
-} Counter;
-
-static Counter root_cnts[4]; // 4 of the bastards
-
-#define CLOCK_DIV (8) // 33 MHz / this = what we run the R3000 at to keep the CPU usage not insane
-
-// counter modes
-#define RC_EN (0x0001) // halt
-#define RC_RESET (0x0008) // automatically wrap
-#define RC_IQ1 (0x0010) // IRQ when target reached
-#define RC_IQ2 (0x0040) // IRQ when target reached (pSX treats same as IQ1?)
-#define RC_CLC (0x0100) // counter uses direct system clock
-#define RC_DIV8 (0x0200) // (counter 2 only) system clock/8
-
-typedef struct
-{
- uint32_t desc;
- int32_t status;
- int32_t mode;
- uint32_t fhandler;
-} EvtCtrlBlk[32];
-
-static EvtCtrlBlk *Event;
-static EvtCtrlBlk *CounterEvent;
-
-// Sony event states
-#define EvStUNUSED 0x0000
-#define EvStWAIT 0x1000
-#define EvStACTIVE 0x2000
-#define EvStALREADY 0x4000
-
-// Sony event modes
-#define EvMdINTR 0x1000
-#define EvMdNOINTR 0x2000
-
-// PSX main RAM
-uint32_t psx_ram[(2*1024*1024)/4];
-uint32_t psx_scratch[0x400];
-// backup image to restart songs
-uint32_t initial_ram[(2*1024*1024)/4];
-uint32_t initial_scratch[0x400];
-
-static uint32_t spu_delay, dma_icr, irq_data, irq_mask, dma_timer, WAI;
-static uint32_t dma4_madr, dma4_bcr, dma4_chcr, dma4_delay;
-static uint32_t dma7_madr, dma7_bcr, dma7_chcr, dma7_delay;
-static uint32_t dma4_cb, dma7_cb, dma4_fval, dma4_flag, dma7_fval, dma7_flag;
-static uint32_t irq9_cb, irq9_fval, irq9_flag;
-
-// take a snapshot of the CPU state for a thread
-static void FreezeThread(int32_t iThread, int flag)
-{
- int i;
- union cpuinfo mipsinfo;
-
- #if DEBUG_THREADING
-// printf("IOP: FreezeThread(%d)\n", iThread);
- #endif
-
- for (i = 0; i < 32; i++)
- {
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R0 + i, &mipsinfo);
- threads[iThread].save_regs[i] = mipsinfo.i;
- }
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
- threads[iThread].save_regs[32] = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
- threads[iThread].save_regs[33] = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_DELAYV, &mipsinfo);
- threads[iThread].save_regs[35] = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_DELAYR, &mipsinfo);
- threads[iThread].save_regs[36] = mipsinfo.i;
-
-
- // if a thread is freezing itself due to a IOP syscall, we must save the RA as the PC
- // to come back to or else the syscall will recurse
- if (flag)
- {
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- }
- else
- {
- mips_get_info(CPUINFO_INT_PC, &mipsinfo);
- }
- threads[iThread].save_regs[34] = mipsinfo.i;
-
- #if DEBUG_THREADING
- {
- char buffer[256];
-
- DasmMIPS(buffer, mipsinfo.i, &psx_ram[(mipsinfo.i & 0x7fffffff)/4]);
-
- printf("IOP: FreezeThread(%d) => %08x [%s]\n", iThread, threads[iThread].save_regs[34], buffer);
- }
- #endif
-
- // if thread was running, now it's ready
- if (threads[iThread].iState == TS_RUNNING)
- {
- threads[iThread].iState = TS_READY;
- }
-}
-
-// restore the CPU state from a thread's snapshot
-static void ThawThread(int32_t iThread)
-{
- int i;
- union cpuinfo mipsinfo;
-
- // the first time a thread is put on the CPU,
- // some special setup is required
- if (threads[iThread].iState == TS_CREATED)
- {
- // PC = starting routine
- threads[iThread].save_regs[34] = threads[iThread].routine-4; // compensate for weird delay slot effects
- // SP = thread's stack area
- threads[iThread].save_regs[29] = (threads[iThread].stackloc + threads[iThread].stacksize) - 16;
- threads[iThread].save_regs[29] |= 0x80000000;
-
- threads[iThread].save_regs[35] = threads[iThread].save_regs[36] = 0;
-
- #if DEBUG_THREADING
-// printf("IOP: Initial setup for thread %d => PC %x SP %x\n", iThread, threads[iThread].save_regs[34]+4, threads[iThread].save_regs[29]);
- #endif
- }
-
- #if DEBUG_THREADING
- {
- char buffer[256];
-
- mips_get_info(CPUINFO_INT_PC, &mipsinfo);
- DasmMIPS(buffer, mipsinfo.i, &psx_ram[(mipsinfo.i & 0x7fffffff)/4]);
-
- printf("IOP: ThawThread(%d) => %08x [%s] (wake %d)\n", iThread, threads[iThread].save_regs[34], buffer, wakecount);
- }
- #endif
-
- for (i = 0; i < 32; i++)
- {
- mipsinfo.i = threads[iThread].save_regs[i];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R0 + i, &mipsinfo);
- }
-
- mipsinfo.i = threads[iThread].save_regs[32];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
- mipsinfo.i = threads[iThread].save_regs[33];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
- mipsinfo.i = threads[iThread].save_regs[34];
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
- mipsinfo.i = threads[iThread].save_regs[35];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_DELAYV, &mipsinfo);
- mipsinfo.i = threads[iThread].save_regs[36];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_DELAYR, &mipsinfo);
-
- threads[iThread].iState = TS_RUNNING;
-}
-
-// find a new thread to run
-static void ps2_reschedule(void)
-{
- int i, starti, iNextThread;
-
- iNextThread = -1;
-
- // see if any thread other than the current one is ready to run
- i = iCurThread+1;
- if (i >= iNumThreads)
- {
- i = 0;
- }
-
- starti = i;
-
- // starting with the next thread after this one,
- // see who wants to run
- while (i < iNumThreads)
- {
- if (i != iCurThread)
- {
- if (threads[i].iState == TS_READY)
- {
- iNextThread = i;
- break;
- }
- }
-
- i++;
- }
-
- // if we started above thread 0 and didn't pick one,
- // go around and try from zero
- if ((starti > 0) && (iNextThread == -1))
- {
- for (i = 0; i < iNumThreads; i++)
- {
- if (i != iCurThread)
- {
- if (threads[i].iState == TS_READY)
- {
- iNextThread = i;
- break;
- }
- }
- }
- }
-
- if (iNextThread != -1)
- {
- #if DEBUG_THREADING
- for (i = 0; i < iNumThreads; i++)
- {
- printf("Thread %02d: %s\n", i, _ThreadStateNames[threads[i].iState]);
- }
- #endif
-
- if (iCurThread != -1)
- {
- FreezeThread(iCurThread, 0);
- }
- ThawThread(iNextThread);
- iCurThread = iNextThread;
- threads[iCurThread].iState = TS_RUNNING;
- }
- else
- {
- // no thread to switch to, is the current one still running?
- if (iCurThread != -1)
- {
- if (threads[iCurThread].iState != TS_RUNNING)
- {
- #if DEBUG_THREADING
- printf("IOP: no threads to run\n");
-
- for (i = 0; i < iNumThreads; i++)
- {
- printf("Thread %02d: %s\n", i, _ThreadStateNames[threads[i].iState]);
- }
- #endif
-
- mips_shorten_frame(); // kill the CPU
- iCurThread = -1; // no threads are active
- }
- }
- else
- {
- mips_shorten_frame(); // kill the CPU
- iCurThread = -1; // no threads are active
- }
- }
-}
-
-static void psx_irq_update(void)
-{
- union cpuinfo mipsinfo;
-
- if ((irq_data & irq_mask) != 0)
- { // assert the line
- WAI = 0;
- mipsinfo.i = ASSERT_LINE;
- mips_set_info( CPUINFO_INT_INPUT_STATE + MIPS_IRQ0, &mipsinfo );
- }
- else
- {
- // clear the line
- mipsinfo.i = CLEAR_LINE;
- mips_set_info( CPUINFO_INT_INPUT_STATE + MIPS_IRQ0, &mipsinfo );
- }
-}
-
-void psx_irq_set(uint32_t irq)
-{
- irq_data |= irq;
-
- psx_irq_update();
-}
-
-static uint32_t gpu_stat = 0;
-
-uint32_t psx_hw_read(offs_t offset, uint32_t mem_mask)
-{
- if (offset >= 0x00000000 && offset <= 0x007fffff)
- {
- offset &= 0x1fffff;
- return LE32(psx_ram[offset>>2]);
- }
-
- if (offset >= 0x80000000 && offset <= 0x807fffff)
- {
- offset &= 0x1fffff;
- return LE32(psx_ram[offset>>2]);
- }
-
- if (offset == 0xbfc00180 || offset == 0xbfc00184) // exception vector
- {
- return FUNCT_HLECALL;
- }
-
- if (offset == 0x1f801014)
- {
- return spu_delay;
- }
-
- if (offset == 0xbf801014)
- {
- return spu_delay;
- }
-
- if (offset == 0x1f801814)
- {
- gpu_stat ^= 0xffffffff;
- return gpu_stat;
- }
-
- if (offset >= 0x1f801c00 && offset <= 0x1f801dff)
- {
- if ((mem_mask == 0xffff0000) || (mem_mask == 0xffffff00))
- {
- #if DEBUG_SPU
- printf("SPU: readRegister(%x)\n", offset);
- #endif
- return SPUreadRegister(offset) & ~mem_mask;
- }
- else if (mem_mask == 0x0000ffff)
- {
- #if DEBUG_SPU
- printf("SPU: readRegister(%x)\n", offset);
- #endif
- return SPUreadRegister(offset)<<16;
- }
- else printf("SPU: read unknown mask %08x\n", mem_mask);
- }
-
- if (offset >= 0xbf900000 && offset <= 0xbf9007ff)
- {
- if ((mem_mask == 0xffff0000) || (mem_mask == 0xffffff00))
- {
- return SPU2read(offset) & ~mem_mask;
- }
- else if (mem_mask == 0x0000ffff)
- {
- return SPU2read(offset)<<16;
- }
- else if (mem_mask == 0)
- {
- return SPU2read(offset) | SPU2read(offset+2)<<16;
- }
- else printf("SPU2: read unknown mask %08x\n", mem_mask);
- }
-
- if (offset >= 0x1f801100 && offset <= 0x1f801128)
- {
- int cnt = (offset>>4) & 0xf;
-
- switch (offset & 0xf)
- {
- case 0:
-// printf("RC: read counter %d count = %x\n", cnt, root_cnts[cnt].count);
- return root_cnts[cnt].count;
- break;
- case 4:
-// printf("RC: read counter %d mode\n", cnt);
- return root_cnts[cnt].mode;
- break;
- case 8:
-// printf("RC: read counter %d target\n", cnt);
- return root_cnts[cnt].target;
- break;
- }
-
- return 0;
- }
-
- if (offset == 0x1f8010f4)
- {
- return dma_icr;
- }
- else if (offset == 0x1f801070)
- {
-// printf("Read IRQ_data %x (mask %08x)\n", irq_data, mem_mask);
- return irq_data;
- }
- else if (offset == 0x1f801074)
- {
- return irq_mask;
- }
-
-/* if (offset == 0xbf801508)
- {
- return dma7_bcr;
- }*/
-
- if (offset == 0xbf920344)
- {
- return 0x80808080;
- }
-
- #if DEBUG_UNK_RW
- {
- union cpuinfo mipsinfo;
-
- mips_get_info(CPUINFO_INT_PC, &mipsinfo);
- printf("Unknown read: %08x, mask %08x (PC=%x)\n", offset&~3, mem_mask, mipsinfo.i);
- }
- #endif
- return 0;
-}
-
-static void psx_dma4(uint32_t madr, uint32_t bcr, uint32_t chcr)
-{
- if (chcr == 0x01000201) // cpu to SPU
- {
- #if DEBUG_SPU
- printf("DMA4: RAM %08x to SPU\n", madr);
- #endif
- bcr = (bcr>>16) * (bcr & 0xffff) * 2;
- SPUwriteDMAMem(madr&0x1fffff, bcr);
- }
- else
- {
- #if DEBUG_SPU
- printf("DMA4: SPU to RAM %08x\n", madr);
- #endif
- bcr = (bcr>>16) * (bcr & 0xffff) * 2;
- SPUreadDMAMem(madr&0x1fffff, bcr);
- }
-}
-
-static void ps2_dma4(uint32_t madr, uint32_t bcr, uint32_t chcr)
-{
- if (chcr == 0x01000201) // cpu to SPU2
- {
- #if DEBUG_HLE_IOP
- printf("DMA4: RAM %08x to SPU2\n", madr);
- #endif
- bcr = (bcr>>16) * (bcr & 0xffff) * 4;
- SPU2writeDMA4Mem(madr&0x1fffff, bcr);
- }
- else
- {
- #if DEBUG_HLE_IOP
- printf("DMA4: SPU2 to RAM %08x\n", madr);
- #endif
- bcr = (bcr>>16) * (bcr & 0xffff) * 4;
- SPU2readDMA4Mem(madr&0x1fffff, bcr);
- }
-
- dma4_delay = 80;
-}
-
-static void ps2_dma7(uint32_t madr, uint32_t bcr, uint32_t chcr)
-{
- if ((chcr == 0x01000201) || (chcr == 0x00100010) || (chcr == 0x000f0010) || (chcr == 0x00010010)) // cpu to SPU2
- {
- #if DEBUG_HLE_IOP
- printf("DMA7: RAM %08x to SPU2\n", madr);
- #endif
- bcr = (bcr>>16) * (bcr & 0xffff) * 4;
- SPU2writeDMA7Mem(madr&0x1fffff, bcr);
- }
- else
- {
- #if DEBUG_HLE_IOP
- printf("DMA7: SPU2 to RAM %08x\n", madr);
- #endif
- bcr = (bcr>>16) * (bcr & 0xffff) * 4;
-// SPU2readDMA7Mem(madr&0x1fffff, bcr);
- }
-
- dma7_delay = 80;
-}
-
-void psx_hw_write(offs_t offset, uint32_t data, uint32_t mem_mask)
-{
- union cpuinfo mipsinfo;
-
- if (offset >= 0x00000000 && offset <= 0x007fffff)
- {
- offset &= 0x1fffff;
-// if (offset < 0x10000) printf("Write %x to kernel @ %x\n", data, offset);
-
- mips_get_info(CPUINFO_INT_PC, &mipsinfo);
-
- psx_ram[offset>>2] &= LE32(mem_mask);
- psx_ram[offset>>2] |= LE32(data);
- return;
- }
-
- if (offset >= 0x80000000 && offset <= 0x807fffff)
- {
- offset &= 0x1fffff;
-// if (offset < 0x10000) printf("Write %x to kernel @ %x\n", data, offset);
- mips_get_info(CPUINFO_INT_PC, &mipsinfo);
- psx_ram[offset>>2] &= LE32(mem_mask);
- psx_ram[offset>>2] |= LE32(data);
- return;
- }
-
- if (offset == 0x1f801014 || offset == 0xbf801014)
- {
- spu_delay &= mem_mask;
- spu_delay |= data;
- return;
- }
-
- if (offset >= 0x1f801c00 && offset <= 0x1f801dff)
- {
- if (mem_mask == 0xffff0000)
- {
- SPUwriteRegister(offset, data);
- return;
- }
- else if (mem_mask == 0x0000ffff)
- {
- SPUwriteRegister(offset, data>>16);
- return;
- }
- else printf("SPU: write unknown mask %08x\n", mem_mask);
- }
-
- if (offset >= 0xbf900000 && offset <= 0xbf9007ff)
- {
- if (mem_mask == 0xffff0000)
- {
- SPU2write(offset, data);
- return;
- }
- else if (mem_mask == 0x0000ffff)
- {
- SPU2write(offset, data>>16);
- return;
- }
- else if (mem_mask == 0)
- {
- SPU2write(offset, data & 0xffff);
- SPU2write(offset+2, data>>16);
- return;
- }
- else printf("SPU2: write unknown mask %08x\n", mem_mask);
- }
-
- if (offset >= 0x1f801100 && offset <= 0x1f801128)
- {
- int cnt = (offset>>4) & 0xf;
-
- switch (offset & 0xf)
- {
- case 0:
- root_cnts[cnt].count = data;
-// printf("RC: counter %d count = %x\n", cnt, data);
- break;
- case 4:
- root_cnts[cnt].mode = data;
-// printf("RC: counter %d mode = %x\n", cnt, data);
- break;
- case 8:
- root_cnts[cnt].target = data;
-// printf("RC: counter %d target = %x\n", cnt, data);
- break;
- }
-
- return;
- }
-
- // DMA4
- if (offset == 0x1f8010c0)
- {
- dma4_madr = data;
- return;
- }
- else if (offset == 0x1f8010c4)
- {
- dma4_bcr = data;
- return;
- }
- else if (offset == 0x1f8010c8)
- {
- dma4_chcr = data;
- psx_dma4(dma4_madr, dma4_bcr, dma4_chcr);
-
- if (dma_icr & (1 << (16+4)))
- {
- dma_timer = 3;
- }
- return;
- }
- else if (offset == 0x1f8010f4)
- {
- dma_icr = ( dma_icr & mem_mask ) |
- ( ~mem_mask & 0x80000000 & dma_icr) |
- ( ~data & ~mem_mask & 0x7f000000 & dma_icr) |
- ( data & ~mem_mask & 0x00ffffff);
-
- if ((dma_icr & 0x7f000000) != 0)
- {
- dma_icr &= ~0x80000000;
- }
-
- return;
- }
- else if (offset == 0x1f801070)
- {
- irq_data = (irq_data & mem_mask) | (irq_data & irq_mask & data);
- psx_irq_update();
- return;
- }
- else if (offset == 0x1f801074)
- {
- irq_mask &= mem_mask;
- irq_mask |= data;
- psx_irq_update();
- return;
- }
-
- // PS2 DMA4
- if (offset == 0xbf8010c0)
- {
- dma4_madr = data;
- return;
- }
- else if (offset == 0xbf8010c8)
- {
- dma4_chcr = data;
- ps2_dma4(dma4_madr, dma4_bcr, dma4_chcr);
-
- if (dma_icr & (1 << (16+4)))
- {
- dma_timer = 3;
- }
- return;
- }
-
- if (offset == 0xbf8010c4 || offset == 0xbf8010c6)
- {
- dma4_bcr &= mem_mask;
- dma4_bcr |= data;
- return;
- }
-
- // PS2 DMA7
- if (offset == 0xbf801500)
- {
- dma7_madr = data;
- return;
- }
- else if (offset == 0xbf801504)
- {
- dma7_chcr = data;
- ps2_dma7(dma7_madr, dma7_bcr, dma7_chcr);
- return;
- }
-
- if (offset == 0xbf801508 || offset == 0xbf80150a)
- {
- dma7_bcr &= mem_mask;
- dma7_bcr |= data;
- return;
- }
-
- #if DEBUG_UNK_RW
- {
- union cpuinfo mipsinfo;
-
- mips_get_info(CPUINFO_INT_PC, &mipsinfo);
- printf("Unknown write: %08x to %08x, mask %08x (PC=%x)\n", data, offset&~3, mem_mask, mipsinfo.i);
- }
- #endif
-}
-
-// called per sample, 1/44100th of a second (768 clock cycles)
-void psx_hw_slice(void)
-{
- psx_hw_runcounters();
-
- if (!WAI)
- mips_execute(768/CLOCK_DIV);
-
- if (dma_timer)
- {
- dma_timer--;
- if (dma_timer == 0)
- {
- dma_icr |= (1 << (24+4));
- psx_irq_set(0x0008);
- }
- }
-}
-
-void ps2_hw_slice(void)
-{
- int i = 0;
-
- timerexp = 0;
- psx_hw_runcounters();
-
- if (iCurThread != -1)
- {
- mips_execute(836/CLOCK_DIV);
- }
- else // no thread, don't run CPU, just update counters
- {
- if (timerexp)
- {
- ps2_reschedule();
-
- if (iCurThread != -1)
- {
- mips_execute((836/CLOCK_DIV)-i);
- i = (836/CLOCK_DIV);
- }
- }
- }
-}
-
-static int fcnt = 0;
-
-void psx_hw_frame(void)
-{
- if (psf_refresh == 50)
- {
- fcnt++;;
-
- if (fcnt < 6)
- {
- psx_irq_set(1);
- }
- else
- {
- fcnt = 0;
- }
- }
- else // NTSC
- {
- psx_irq_set(1);
- }
-}
-
-void ps2_hw_frame(void)
-{
- ps2_reschedule();
-}
-
-// BIOS HLE
-
-// heap block struct offsets
-enum
-{
- BLK_STAT = 0,
- BLK_SIZE = 4,
- BLK_FD = 8,
- BLK_BK = 12
-};
-
-static uint32_t heap_addr, entry_int = 0;
-
-extern uint32_t mips_get_cause(void);
-extern uint32_t mips_get_status(void);
-extern void mips_set_status(uint32_t status);
-extern uint32_t mips_get_ePC(void);
-
-static uint32_t irq_regs[37];
-
-static int irq_mutex = 0;
-
-static void call_irq_routine(uint32_t routine, uint32_t parameter)
-{
- int j, oldICount;
- union cpuinfo mipsinfo;
-
- if (!irq_mutex)
- {
- irq_mutex = 1;
- }
- else
- {
- printf("IOP: ERROR! IRQ reentry!\n");
- return;
- }
-
- // save regs for IRQ
- for (j = 0; j < 32; j++)
- {
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R0 + j, &mipsinfo);
- irq_regs[j] = mipsinfo.i;
- }
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
- irq_regs[32] = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
- irq_regs[33] = mipsinfo.i;
- mips_get_info(CPUINFO_INT_PC, &mipsinfo);
- irq_regs[34] = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_DELAYV, &mipsinfo);
- irq_regs[35] = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_DELAYR, &mipsinfo);
- irq_regs[36] = mipsinfo.i;
-
- // PC = timer handler routine
- mipsinfo.i = routine;
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
-
- // parameter in a0
- mipsinfo.i = parameter;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
-
- // RA = a trap address we can set
- mipsinfo.i = 0x80001000;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
-
- // make sure we're set
- psx_ram[0x1000/4] = LE32(FUNCT_HLECALL);
-
- softcall_target = 0;
- oldICount = mips_get_icount();
- while (!softcall_target)
- {
- mips_execute(10);
- }
- mips_set_icount(oldICount);
-
- // restore IRQ regs
- for (j = 0; j < 32; j++)
- {
- mipsinfo.i = irq_regs[j];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R0 + j, &mipsinfo);
- }
-
- mipsinfo.i = irq_regs[32];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
- mipsinfo.i = irq_regs[33];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
- mipsinfo.i = irq_regs[34];
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
- mipsinfo.i = irq_regs[35];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_DELAYV, &mipsinfo);
- mipsinfo.i = irq_regs[36];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_DELAYR, &mipsinfo);
-
- irq_mutex = 0;
-}
-
-void psx_bios_exception(uint32_t pc)
-{
- uint32_t a0, status;
- union cpuinfo mipsinfo;
- int i, oldICount;
-
-// printf("bios_exception: cause %x\n", mips_get_cause() & 0x3c);
-
- // get a0
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
- a0 = mipsinfo.i;
-
- switch (mips_get_cause() & 0x3c)
- {
- case 0: // IRQ
-// printf("IRQ: %x, mask %x\n", irq_data, irq_mask);
- // save all regs
- for (i = 0; i < 32; i++)
- {
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R0 + i, &mipsinfo);
- irq_regs[i] = mipsinfo.i;
- }
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
- irq_regs[32] = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
- irq_regs[33] = mipsinfo.i;
-
- // check BIOS-driven interrupts
- if (irq_data & 1) // VSync
- {
- if (CounterEvent[3][1].status == LE32(EvStACTIVE))
- {
- // run the handler
- mipsinfo.i = LE32(CounterEvent[3][1].fhandler);
-// printf("Cause = %x, ePC = %x\n", mips_get_cause(), mips_get_ePC());
-// printf("VBL running handler @ %x\n", mipsinfo.i);
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
- mipsinfo.i = 0x80001000;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
-
- // make sure we're set
- psx_ram[0x1000/4] = LE32(FUNCT_HLECALL);
-
- softcall_target = 0;
- oldICount = mips_get_icount();
- while (!softcall_target)
- {
- mips_execute(10);
- }
- mips_set_icount(oldICount);
-
-// printf("Exiting softcall handler\n");
-
- irq_data &= ~1; // clear the VBL IRQ if we handled it
- }
- }
- else if (irq_data & 0x70) // root counters
- {
- for (i = 0; i < 4; i++)
- {
- if (irq_data & (1 << (i+4)))
- {
- if (CounterEvent[i][1].status == LE32(EvStACTIVE))
- {
- // run the handler
- mipsinfo.i = LE32(CounterEvent[i][1].fhandler);
-// printf("Cause = %x, ePC = %x\n", mips_get_cause(), mips_get_ePC());
-// printf("Counter %d running handler @ %x\n", i, mipsinfo.i);
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
- mipsinfo.i = 0x80001000;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
-
- // make sure we're set
- psx_ram[0x1000/4] = LE32(FUNCT_HLECALL);
-
- softcall_target = 0;
- oldICount = mips_get_icount();
- while (!softcall_target)
- {
- mips_execute(10);
- }
- mips_set_icount(oldICount);
-
-// printf("Exiting softcall handler\n");
- irq_data &= ~(1 << (i+4));
- }
- else
- {
-// printf("CEvt %d not active\n", i);
- }
- }
- }
- }
-
- if (entry_int)
- {
- psx_hw_write(0x1f801070, 0xffffffff, 0);
-
- a0 = entry_int;
-
-// printf("taking entry_int\n");
-
- // RA (and PC)
- mipsinfo.i = LE32(psx_ram[((a0&0x1fffff)+0)/4]);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
- // SP
- mipsinfo.i = LE32(psx_ram[((a0&0x1fffff)+4)/4]);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R29, &mipsinfo);
- // FP
- mipsinfo.i = LE32(psx_ram[((a0&0x1fffff)+8)/4]);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R30, &mipsinfo);
-
- // S0-S7 are next
- for (i = 0; i < 8; i++)
- {
- mipsinfo.i = LE32(psx_ram[((a0&0x1fffff)+12+(i*4))/4]);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R16 + i, &mipsinfo);
- }
-
- // GP
- mipsinfo.i = LE32(psx_ram[((a0&0x1fffff)+44)/4]);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R28, &mipsinfo);
-
- // v0 = 1
- mipsinfo.i = 1;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- else
- {
- psx_hw_write(0x1f801070, 0, 0xffff0000);
-
- // note: the entry_int won't be bailing us out here, so do it ourselves
- for (i = 0; i < 32; i++)
- {
- mipsinfo.i = irq_regs[i];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R0 + i, &mipsinfo);
- }
-
- mipsinfo.i = irq_regs[32];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
- mipsinfo.i = irq_regs[33];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
- mipsinfo.i = mips_get_ePC();
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
-
- status = mips_get_status();
- status = (status & 0xfffffff0) | ((status & 0x3c)>>2);
- mips_set_status(status);
- }
- break;
-
- case 0x20: // syscall
- // syscall always farks with the status, so get it now
- status = mips_get_status();
-
- switch (a0)
- {
- case 1: // EnterCritical
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: EnterCritical\n");
- #endif
- status &= ~0x0404;
- break;
-
- case 2: // ExitCritical
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: ExitCritical\n");
- #endif
- status |= 0x0404;
- break;
-
- default:
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: Unknown syscall %x\n", a0);
- #endif
- break;
- }
-
- // PC = ePC + 4
- mipsinfo.i = mips_get_ePC() + 4;
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
-
- // and update the status accordingly
- status = (status & 0xfffffff0) | ((status & 0x3c)>>2);
- mips_set_status(status);
- break;
-
- default:
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: Unknown exception %x\n", mips_get_cause());
- #endif
- break;
- }
-}
-
-static uint32_t calc_ev(uint32_t a0)
-{
- uint32_t ev;
-
- ev = (a0 >> 24) & 0xf;
- if (ev == 0xf)
- {
- ev = 0x5;
- }
- ev *= 32;
- ev += (a0 & 0x1f);
-
- return ev;
-}
-
-static uint32_t calc_spec(uint32_t a1)
-{
- uint32_t spec = 0;
- int i;
-
- if (a1 == 0x301)
- {
- spec = 16;
- }
- else if (a1 == 0x302)
- {
- spec = 17;
- }
- else
- {
- for (i = 0; i < 16; i++)
- {
- if (a1 & (1<<i))
- {
- spec = i;
- break;
- }
- }
- }
-
- return spec;
-}
-
-void psx_hw_init(void)
-{
- timerexp = 0;
-
- memset(filestat, 0, sizeof(filestat));
- memset(filedata, 0, sizeof(filedata));
-
- dma4_cb = dma7_cb = 0;
-
- sys_time = 0;
-
- // clear registered libraries table
- memset(reglibs, 0, sizeof(reglibs));
- iNumLibs = 0;
-
- memset(evflags, 0, sizeof(evflags));
- iNumFlags = 0;
-
- memset(threads, 0, sizeof(threads));
- iNumThreads = 1; // we always have at least one thread
-
- memset(semaphores, 0, sizeof(semaphores));
- iNumSema = 0;
-
- // set the initial thread to "RUNNING"
- threads[0].iState = TS_RUNNING;
- iCurThread = 0;
-
- memset(iop_timers, 0, sizeof(iop_timers));
- iNumTimers = 0;
-
- // set PS1 BIOS HLE breakpoints
- psx_ram[0xa0/4] = LE32(FUNCT_HLECALL);
- psx_ram[0xb0/4] = LE32(FUNCT_HLECALL);
- psx_ram[0xc0/4] = LE32(FUNCT_HLECALL);
-
- Event = (EvtCtrlBlk *)&psx_ram[0x1000/4];
- CounterEvent = (Event + (32*2));
-
- dma_icr = 0;
- spu_delay = 0;
- irq_data = 0;
- irq_mask = 0;
- softcall_target = 0;
- gpu_stat = 0;
- dma4_madr = dma4_bcr = dma4_chcr = 0;
- heap_addr = 0;
- entry_int = 0;
-
- WAI = 0;
-
- root_cnts[0].mode = RC_EN;
- root_cnts[1].mode = RC_EN;
- root_cnts[2].mode = RC_EN;
- root_cnts[0].sysclock = 0;
- root_cnts[1].sysclock = 0;
- root_cnts[2].sysclock = 0;
-
- root_cnts[3].mode = (RC_RESET | RC_IQ1 | RC_IQ2);
- root_cnts[3].sysclock = 0;
- root_cnts[3].target = 1;
- root_cnts[3].interrupt = 1;
-}
-
-void psx_bios_hle(uint32_t pc)
-{
- uint32_t subcall, status;
- union cpuinfo mipsinfo;
- uint32_t a0, a1, a2, a3;
- int i;
-
- if ((pc == 0) || (pc == 0x80000000)) // IOP "null" state
- {
- #if DEBUG_HLE_IOP
- printf("IOP 'null' state\n");
- #endif
-// ao_song_done = 1;
- return;
- }
-
- if (pc == 0xbfc00180 || pc == 0xbfc00184) // exception, not BIOS call
- {
- psx_bios_exception(pc);
- return;
- }
-
- if (pc == 0x80001000)
- {
-// printf("hit softcall target\n");
- softcall_target = 1;
- return;
- }
-
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R9, &mipsinfo);
-
- subcall = mipsinfo.i & 0xff;
-
- // most calls have a0/a1 as parameters, so prefetch them
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
- a0 = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R5, &mipsinfo);
- a1 = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R6, &mipsinfo);
- a2 = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R7, &mipsinfo);
- a3 = mipsinfo.i;
-
-// mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
-// printf("HLEBIOS: return is %08x\n", mipsinfo.i);
-
- switch (pc)
- {
- case 0xa0: // a0 syscalls
- switch (subcall)
- {
- case 0x13: // setjmp
- // RA
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- psx_ram[((a0&0x1fffff)+0)/4] = LE32(mipsinfo.i);
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: setjmp(%08x) => PC %08x\n", a0, mipsinfo.i);
- #endif
- // SP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R29, &mipsinfo);
- psx_ram[((a0&0x1fffff)+4)/4] = LE32(mipsinfo.i);
- // FP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R30, &mipsinfo);
- psx_ram[((a0&0x1fffff)+8)/4] = LE32(mipsinfo.i);
-
- // S0-S7 are next
- for (i = 0; i < 8; i++)
- {
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R16 + i, &mipsinfo);
- psx_ram[((a0&0x1fffff)+12+(i*4))/4] = LE32(mipsinfo.i);
- }
-
- // GP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R28, &mipsinfo);
- psx_ram[((a0&0x1fffff)+44)/4] = LE32(mipsinfo.i);
-
- // v0 = 0
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 0x18: // strncmp
- {
- uint8_t *dst, *src;
-
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: strncmp(%08x, %08x, %d)\n", a0, a1, a2);
- #endif
-
- dst = (uint8_t *)psx_ram;
- src = (uint8_t *)psx_ram;
- dst += (a0 & 0x1fffff);
- src += (a1 & 0x1fffff);
-
- // v0 = result
- mipsinfo.i = strncmp((char *)dst, (char *)src, a2);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 0x19: // strcpy
- {
- uint8_t *dst, *src;
-
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: strcpy(%08x, %08x)\n", a0, a1);
- #endif
-
- dst = (uint8_t *)psx_ram;
- src = (uint8_t *)psx_ram;
- dst += (a0 & 0x1fffff);
- src += (a1 & 0x1fffff);
-
- while (*src)
- {
- *dst = *src;
- dst++;
- src++;
- }
-
- // v0 = a0
- mipsinfo.i = a0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 0x28: // bzero
- {
- uint8_t *dst;
-
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: bzero(%08x, %08x)\n", a0, a1);
- #endif
-
- dst = (uint8_t *)psx_ram;
- dst += (a0 & 0x1fffff);
- memset(dst, 0, a1);
- }
- break;
-
- case 0x2a: // memcpy
- {
- uint8_t *dst, *src;
-
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: memcpy(%08x, %08x, %08x)\n", a0, a1, a2);
- #endif
-
- dst = (uint8_t *)psx_ram;
- src = (uint8_t *)psx_ram;
- dst += (a0 & 0x1fffff);
- src += (a1 & 0x1fffff);
-
- while (a2)
- {
- *dst = *src;
- dst++;
- src++;
- a2--;
- }
-
- // v0 = a0
- mipsinfo.i = a0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 0x2b: // memset
- {
- uint8_t *dst;
-
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: memset(%08x, %08x, %08x)\n", a0, a1, a2);
- #endif
-
- dst = (uint8_t *)psx_ram;
- dst += (a0 & 0x1fffff);
-
- while (a2)
- {
- *dst = a1;
- dst++;
- a2--;
- }
-
- // v0 = a0
- mipsinfo.i = a0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 0x2f: // rand
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: rand\n");
- #endif
-
- // v0 = result
- mipsinfo.i = 1 + (int)(32767.0*rand()/(RAND_MAX+1.0));
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 0x30: // srand
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: srand(%x)\n", a0);
- #endif
- srand(a0);
- break;
-
- case 0x33: // malloc
- {
- uint32_t chunk, fd;
-
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: malloc(%x)\n", a0);
- #endif
-
- chunk = heap_addr;
-
- // find a free block that's big enough
- while ((a0 > LE32(psx_ram[(chunk+BLK_SIZE)/4])) ||
- (LE32(psx_ram[(chunk+BLK_STAT)/4]) == 1))
- {
- chunk = LE32(psx_ram[(chunk+BLK_FD)]);
- }
-
- // split free block
- fd = chunk + 16 + a0; // free block starts after block record and allocation size
- psx_ram[(fd+BLK_STAT)/4] = psx_ram[(chunk+BLK_STAT)/4];
- psx_ram[(fd+BLK_SIZE)/4] = LE32(LE32(psx_ram[(chunk+BLK_SIZE)/4]) - a0);
- psx_ram[(fd+BLK_FD)/4] = psx_ram[(chunk+BLK_FD)/4];
- psx_ram[(fd+BLK_BK)/4] = chunk;
-
- psx_ram[(chunk+BLK_STAT)/4] = LE32(1);
- psx_ram[(chunk+BLK_SIZE)/4] = LE32(a0);
- psx_ram[(chunk+BLK_FD)/4] = LE32(fd);
-
- mipsinfo.i = chunk + 16;
- mipsinfo.i |= 0x80000000;
- #if DEBUG_HLE_BIOS
- printf("== %08x\n", mipsinfo.i);
- #endif
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 0x39: // InitHeap
- // heap address in A0, length in A1
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: InitHeap(%08x, %08x)\n", a0, a1);
- #endif
-
- heap_addr = a0 & 0x3fffffff;
-
- psx_ram[(heap_addr+BLK_STAT)/4] = LE32(0);
- psx_ram[(heap_addr+BLK_FD)/4] = LE32(0);
- psx_ram[(heap_addr+BLK_BK)/4] = LE32(0);
-
- // if heap size out of range, clamp it
- if (((a0 & 0x1fffff) + a1) >= 2*1024*1024)
- {
- psx_ram[(heap_addr+BLK_SIZE)/4] = LE32(0x1ffffc - (a0 & 0x1fffff));
- }
- else
- {
- psx_ram[(heap_addr+BLK_SIZE)/4] = LE32(a1);
- }
- break;
-
- case 0x3f: // printf
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: printf(%08x) = %s\n", a0, &psx_ram[(a0&0x1fffff)/4]);
- #endif
- break;
-
- case 0x72: //__96_remove
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: __96_remove\n");
- #endif
- break;
-
- default:
- #if DEBUG_HLE_BIOS
- printf("Unknown BIOS A0 call = %x\n", subcall);
- #endif
- break;
- }
- break;
-
- case 0xb0: // b0 syscalls
- switch (subcall)
- {
- case 0x07: // DeliverEvent
- {
- int ev, spec;
-
-
- ev = calc_ev(a0);
- spec = calc_spec(a1);
-
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: DeliverEvent(ev %d, spec %d)\n", ev, spec);
- #endif
-
- if (Event[ev][spec].status != LE32(EvStACTIVE))
- {
- #if DEBUG_HLE_BIOS
- printf("event not active\n");
- #endif
- return;
- }
-
- // if interrupt mode, do the call
- if (Event[ev][spec].mode == LE32(EvMdINTR))
- {
- #if DEBUG_HLE_BIOS
- printf("INTR type, need to call handler %x\n", LE32(Event[ev][spec].fhandler));
- #endif
- }
- else
- {
- Event[ev][spec].status = LE32(EvStALREADY);
- }
- }
- break;
-
- case 0x08: // OpenEvent
- {
- int ev, spec;
-
- ev = calc_ev(a0);
- spec = calc_spec(a1);
-
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: OpenEvent(%08x, %08x, %08x, %08x) = ev %d spec %d\n", a0, a1, a2, a3, ev, spec);
- if (ev >= 64 && ev <= 68)
- {
- printf("HLEBIOS: event %d maps to root counter %d\n", ev, ev-64);
- }
- #endif
-
- Event[ev][spec].status = LE32(EvStWAIT);
- Event[ev][spec].mode = LE32(a2);
- Event[ev][spec].fhandler = LE32(a3);
-
- // v0 = ev | spec<<8;
- mipsinfo.i = ev | (spec<<8);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 0x0a: // WaitEvent
- {
- int ev, spec;
-
- ev = a0 & 0xff;
- spec = (a0 >> 8) & 0xff;
-
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: WaitEvent(ev %d spec %d) PC=%x\n", ev, spec, mipsinfo.i);
- #endif
-
- Event[ev][spec].status = LE32(EvStACTIVE);
-
- // v0 = 1
- mipsinfo.i = 1;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
-
- WAI = 1;
- mips_shorten_frame();
- }
- break;
-
- case 0x0b: // TestEvent
- {
- int ev, spec;
-
- ev = a0 & 0xff;
- spec = (a0 >> 8) & 0xff;
-
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: TestEvent(ev %d spec %d)\n", ev, spec);
- #endif
-
- // v0 = (is event ready?)
- if (Event[ev][spec].status == LE32(EvStALREADY))
- {
- Event[ev][spec].status = LE32(EvStACTIVE);
- mipsinfo.i = 1;
- }
- else
- {
- mipsinfo.i = 0;
- }
-
- WAI = 1;
-
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
-
- // it looks like this sets v1 to something non-zero too
- // (code in Crash 2 & 3 actually relies on that behavior)
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R3, &mipsinfo);
- }
- break;
-
- case 0x0c: // EnableEvent
- {
- int ev, spec;
-
- ev = a0 & 0xff;
- spec = (a0 >> 8) & 0xff;
-
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: EnableEvent(ev %d spec %d)\n", ev, spec);
- #endif
-
- Event[ev][spec].status = LE32(EvStACTIVE);
-
- // v0 = 1
- mipsinfo.i = 1;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 0x0d: // DisableEvent
- {
- int ev, spec;
-
- ev = a0 & 0xff;
- spec = (a0 >> 8) & 0xff;
-
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: DisableEvent(ev %d spec %d)\n", ev, spec);
- #endif
-
- Event[ev][spec].status = LE32(EvStWAIT);
-
- // v0 = 1
- mipsinfo.i = 1;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 0x17: // ReturnFromException
- for (i = 0; i < 32; i++)
- {
- mipsinfo.i = irq_regs[i];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R0 + i, &mipsinfo);
- }
-
- mipsinfo.i = irq_regs[32];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
- mipsinfo.i = irq_regs[33];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
- mipsinfo.i = mips_get_ePC();
-// printf("ReturnFromException: IRQ state %x\n", irq_data & irq_mask);
-// printf("HLEBIOS: ReturnFromException, cause = %08x, PC = %08x\n", mips_get_cause(), mipsinfo.i);
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
-
- status = mips_get_status();
- status = (status & 0xfffffff0) | ((status & 0x3c)>>2);
- mips_set_status(status);
- return; // force return to avoid PC=RA below
- break;
-
- case 0x19: // HookEntryInt
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: HookEntryInt(%08x)\n", a0);
- #endif
- entry_int = a0;
- break;
-
- case 0x3f: // puts
-// printf("HLEBIOS: puts\n");
- break;
-
- case 0x5b: // ChangeClearPAD
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: ChangeClearPAD\n");
- #endif
- break;
-
- default:
- #if DEBUG_HLE_BIOS
- printf("Unknown BIOS B0 call = %x\n", subcall);
- #endif
- break;
- }
- break;
-
- case 0xc0: // c0 syscalls
- switch (subcall)
- {
- case 0xa: // ChangeClearRCnt
- #if DEBUG_HLE_BIOS
- printf("HLEBIOS: ChangeClearRCnt(%08x, %08x)\n", a0, a1);
- #endif
-
- // v0 = (a0*4)+0x8600
- mipsinfo.i = LE32(psx_ram[((a0<<2) + 0x8600)/4]);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
-
- // (a0*4)+0x8600 = a1;
- psx_ram[((a0<<2) + 0x8600)/4] = LE32(a1);
- break;
-
- default:
- #if DEBUG_HLE_BIOS
- printf("Unknown BIOS C0 call = %x\n", subcall);
- #endif
- break;
- }
- break;
- }
-
- // PC = RA
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
-}
-
-// root counters
-
-void psx_hw_runcounters(void)
-{
- int i;
-
- // don't process any IRQ sources when interrupts are suspended
- if (!intr_susp)
- {
- if (dma4_delay)
- {
- dma4_delay--;
-
- if (dma4_delay == 0)
- {
- SPU2interruptDMA4();
-
- if (dma4_cb)
- {
- call_irq_routine(dma4_cb, dma4_flag);
- }
- }
- }
-
- if (dma7_delay)
- {
- dma7_delay--;
-
- if (dma7_delay == 0)
- {
- SPU2interruptDMA7();
-
- if (dma7_cb)
- {
- call_irq_routine(dma7_cb, dma7_flag);
- }
- }
- }
-
- for (i = 0; i < iNumThreads; i++)
- {
- if (threads[i].iState == TS_WAITDELAY)
- {
- if (threads[i].waitparm > CLOCK_DIV)
- {
- threads[i].waitparm -= CLOCK_DIV;
- }
- else // time's up
- {
- threads[i].waitparm = 0;
- threads[i].iState = TS_READY;
-
- timerexp = 1;
-
- ps2_reschedule();
- }
- }
- }
-
- sys_time += 836;
-
- if (iNumTimers > 0)
- {
- for (i = 0; i < iNumTimers; i++)
- {
- if (iop_timers[i].iActive > 0)
- {
- iop_timers[i].count += 836;
- if (iop_timers[i].count >= iop_timers[i].target)
- {
- iop_timers[i].count -= iop_timers[i].target;
-
- // printf("Timer %d: handler = %08x, param = %08x\n", i, iop_timers[i].handler, iop_timers[i].hparam);
- call_irq_routine(iop_timers[i].handler, iop_timers[i].hparam);
-
- timerexp = 1;
- }
- }
- }
- }
- }
-
-// PS1 root counters
- for (i = 0; i < 4; i++)
- {
- if ((!(root_cnts[i].mode & RC_EN)) && (root_cnts[i].mode != 0))
- {
- if (root_cnts[i].mode & RC_DIV8)
- {
- root_cnts[i].count += 768/8;
- }
- else
- {
- root_cnts[i].count += 768;
- }
-
- if (root_cnts[i].count >= root_cnts[i].target)
- {
- if (!(root_cnts[i].mode & RC_RESET))
- {
- root_cnts[i].mode |= RC_EN;
- }
- else
- {
- root_cnts[i].count %= root_cnts[i].target;
- }
-
- psx_irq_set(1<<(4+i));
- }
- }
- }
-}
-
-// PEOpS callbacks
-
-void SPUirq(void)
-{
-// psx_irq_set(0x200);
-}
-
-// PSXCPU callbacks
-
-uint8_t program_read_byte_32le(offs_t address)
-{
- switch (address & 0x3)
- {
- case 0:
- return psx_hw_read(address, 0xffffff00);
- break;
- case 1:
- return psx_hw_read(address, 0xffff00ff)>>8;
- break;
- case 2:
- return psx_hw_read(address, 0xff00ffff)>>16;
- break;
- case 3:
- return psx_hw_read(address, 0x00ffffff)>>24;
- break;
- }
-
- return psx_hw_read(address, 0xffffff00);
-}
-
-uint16_t program_read_word_32le(offs_t address)
-{
- if (address & 2)
- return psx_hw_read(address, 0x0000ffff)>>16;
-
- return psx_hw_read(address, 0xffff0000);
-}
-
-uint32_t program_read_dword_32le(offs_t address)
-{
- return psx_hw_read(address, 0);
-}
-
-void program_write_byte_32le(offs_t address, uint8_t data)
-{
- switch (address & 0x3)
- {
- case 0:
- psx_hw_write(address, data, 0xffffff00);
- break;
- case 1:
- psx_hw_write(address, data<<8, 0xffff00ff);
- break;
- case 2:
- psx_hw_write(address, data<<16, 0xff00ffff);
- break;
- case 3:
- psx_hw_write(address, data<<24, 0x00ffffff);
- break;
- }
-}
-
-void program_write_word_32le(offs_t address, uint16_t data)
-{
- if (address & 2)
- {
- psx_hw_write(address, data<<16, 0x0000ffff);
- return;
- }
-
- psx_hw_write(address, data, 0xffff0000);
-}
-
-void program_write_dword_32le(offs_t address, uint32_t data)
-{
- psx_hw_write(address, data, 0);
-}
-
-// sprintf replacement
-static void iop_sprintf(char *out, char *fmt, uint32_t pstart)
-{
- char temp[64], tfmt[64];
- char *cf, *pstr;
- union cpuinfo mipsinfo;
- int curparm, fp, isnum;
-
- curparm = pstart;
- cf = fmt;
-
- while (*cf != '\0')
- {
- if (*cf != '%')
- {
- if (*cf == 27)
- {
- *out++ = '[';
- *out++ = 'E';
- *out++ = 'S';
- *out++ = 'C';
- *out = ']';
- }
- else
- {
- *out = *cf;
- }
- out++;
- cf++;
- }
- else // got format
- {
- cf++;
-
- tfmt[0] = '%';
- fp = 1;
- while (((*cf >= '0') && (*cf <= '9')) || (*cf == '.'))
- {
- tfmt[fp] = *cf;
- fp++;
- cf++;
- }
-
- tfmt[fp] = *cf;
- tfmt[fp+1] = '\0';
-
- isnum = 0;
- switch (*cf)
- {
- case 'x':
- case 'X':
- case 'd':
- case 'D':
- case 'c':
- case 'C':
- case 'u':
- case 'U':
- isnum = 1;
- break;
- }
-
-// printf("]]] temp format: [%s] [%d]\n", tfmt, isnum);
-
- if (isnum)
- {
- mips_get_info(curparm, &mipsinfo);
-// printf("parameter %d = %x\n", curparm-pstart, mipsinfo.i);
- curparm++;
- sprintf(temp, tfmt, (int32_t)mipsinfo.i);
- }
- else
- {
- mips_get_info(curparm, &mipsinfo);
- curparm++;
-
- pstr = (char *)psx_ram;
- pstr += (mipsinfo.i & 0x1fffff);
-
- sprintf(temp, tfmt, pstr);
- }
-
- pstr = &temp[0];
- while (*pstr != '\0')
- {
- *out = *pstr;
- out++;
- pstr++;
- }
-
- cf++;
- }
- }
-
- *out = '\0';
-}
-
-// PS2 IOP callbacks
-void psx_iop_call(uint32_t pc, uint32_t callnum)
-{
- uint32_t scan;
- char *mname, *str1, name[9], out[512];
- uint32_t a0, a1, a2, a3;
- union cpuinfo mipsinfo;
- int i;
-
-// printf("IOP call @ %08x\n", pc);
-
- // prefetch parameters
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
- a0 = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R5, &mipsinfo);
- a1 = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R6, &mipsinfo);
- a2 = mipsinfo.i;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R7, &mipsinfo);
- a3 = mipsinfo.i;
-
- scan = (pc&0x0fffffff)/4;
- while ((psx_ram[scan] != LE32(0x41e00000)) && (scan >= (0x10000/4)))
- {
- scan--;
- }
-
- if (psx_ram[scan] != LE32(0x41e00000))
- {
- printf("FATAL ERROR: couldn't find IOP link signature\n");
- return;
- }
-
- scan += 3; // skip zero and version
- memcpy(name, &psx_ram[scan], 8);
- name[8] = '\0';
-
-// printf("IOP: call module [%s] service %d (PC=%08x)\n", name, callnum, pc);
-
- if (!strcmp(name, "stdio"))
- {
- switch (callnum)
- {
- case 4: // printf
- mname = (char *)psx_ram;
- mname += a0 & 0x1fffff;
- mname += (a0 & 3);
-
- iop_sprintf(out, mname, CPUINFO_INT_REGISTER + MIPS_R5); // a1 is first parm
-
- /* if (out[strlen(out)-1] != '\n')
- {
- strcat(out, "\n");
- }*/
-
- #if DEBUG_HLE_IOP
- printf("%s", out);
- #endif
- break;
-
- default:
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- break;
- }
- }
- else if (!strcmp(name, "sifman"))
- {
- switch (callnum)
- {
- case 5: // sceSifInit
- #if DEBUG_HLE_IOP
- printf("IOP: sceSifInit()\n");
- #endif
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 7: // sceSifSetDma
- #if DEBUG_HLE_IOP
- printf("IOP: sceSifSetDma(%08x %08x)\n", a0, a1);
- #endif
-
- mipsinfo.i = 1; // nonzero = success
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 8: // sceSifDmaStat
- #if DEBUG_HLE_IOP
- printf("IOP: sceSifDmaStat(%08x)\n", a0);
- #endif
-
- mipsinfo.i = -1; // dma completed
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 29: // sceSifCheckInit
- #if DEBUG_HLE_IOP
- printf("IOP: sceSifCheckInit()\n");
- #endif
-
- mipsinfo.i = 1;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- default:
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- break;
- }
- }
- else if (!strcmp(name, "thbase"))
- {
- uint32_t newAlloc;
-
- switch (callnum)
- {
- case 4: // CreateThread
- #if DEBUG_THREADING
- printf("IOP: CreateThread(%08x)\n", a0);
- #endif
- a0 &= 0x1fffff;
- a0 /= 4;
- #if DEBUG_THREADING
- printf(" : flags %x routine %08x pri %x stacksize %d refCon %08x\n",
- psx_ram[a0], psx_ram[a0+1], psx_ram[a0+2], psx_ram[a0+3], psx_ram[a0+4]);
- #endif
-
- newAlloc = psf2_get_loadaddr();
- // force 16-byte alignment
- if (newAlloc & 0xf)
- {
- newAlloc &= ~0xf;
- newAlloc += 16;
- }
- psf2_set_loadaddr(newAlloc + LE32(psx_ram[a0+3]));
-
- threads[iNumThreads].iState = TS_CREATED;
- threads[iNumThreads].stackloc = newAlloc;
- threads[iNumThreads].flags = LE32(psx_ram[a0]);
- threads[iNumThreads].routine = LE32(psx_ram[a0+2]);
- threads[iNumThreads].stacksize = LE32(psx_ram[a0+3]);
- threads[iNumThreads].refCon = LE32(psx_ram[a0+4]);
-
- mipsinfo.i = iNumThreads;
- iNumThreads++;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 6: // StartThread
- #if DEBUG_THREADING
- printf("IOP: StartThread(%d %d)\n", a0, a1);
- #endif
-
- FreezeThread(iCurThread, 1);
- ThawThread(a0);
- iCurThread = a0;
- break;
-
- case 20:// GetThreadID
- #if DEBUG_THREADING
- printf("IOP: GetThreadId()\n");
- #endif
-
- mipsinfo.i = iCurThread;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 24:// SleepThread
- #if DEBUG_THREADING
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- printf("IOP: SleepThread() [curThread %d, PC=%x]\n", iCurThread, mipsinfo.i);
- #endif
-
- FreezeThread(iCurThread, 1);
- threads[iCurThread].iState = TS_SLEEPING;
- iCurThread = -1;
-
- ps2_reschedule();
- break;
-
- case 25:// WakeupThread
- #if DEBUG_THREADING
- printf("IOP: WakeupThread(%d)\n", a0);
- #endif
-
- // set thread to "ready to go"
- threads[a0].iState = TS_READY;
- break;
-
- case 26:// iWakeupThread
- #if DEBUG_THREADING
- printf("IOP: iWakeupThread(%d)\n", a0);
- #endif
-
- // set thread to "ready to go" if it's not running
- if (threads[a0].iState != TS_RUNNING)
- {
- threads[a0].iState = TS_READY;
- }
- break;
-
- case 33:// DelayThread
- {
- double dTicks;
-
- #if DEBUG_THREADING
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- printf("IOP: DelayThread(%d) (PC=%x) [curthread = %d]\n", a0, mipsinfo.i, iCurThread);
- #endif
-
- if (a0 < 100)
- {
- a0 = 100;
- }
- dTicks = (double)a0;
-
- FreezeThread(iCurThread, 1);
- threads[iCurThread].iState = TS_WAITDELAY;
- dTicks /= (double)1000000.0;
- dTicks *= (double)36864000.0; // 768*48000 = IOP native-mode clock rate
- threads[iCurThread].waitparm = (uint32_t)dTicks;
- iCurThread = -1;
-
- ps2_reschedule();
- }
- break;
-
- case 34://GetSystemTime
- #if DEBUG_HLE_IOP
- printf("IOP: GetSystemTime(%x)\n", a0);
- #endif
-
- a0 &= 0x1fffff;
- a0 /= 4;
-
- psx_ram[a0] = LE32(sys_time & 0xffffffff); // low
- psx_ram[a0+1] = LE32(sys_time >> 32); // high
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 39:// USec2SysClock
- {
- uint64_t dTicks = (uint64_t)a0;
- uint32_t hi, lo;
-
- #if DEBUG_HLE_IOP
- printf("IOP: USec2SysClock(%d %08x)\n", a0, a1);
- #endif
-
- dTicks *= (uint64_t)36864000;
- dTicks /= (uint64_t)1000000;
-
- hi = dTicks>>32;
- lo = dTicks & 0xffffffff;
-
- psx_ram[((a1 & 0x1fffff)/4)] = LE32(lo);
- psx_ram[((a1 & 0x1fffff)/4)+1] = LE32(hi);
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 40://SysClock2USec
- {
- uint64_t temp;
- uint32_t seconds, usec;
-
- #if DEBUG_HLE_IOP
- printf("IOP: SysClock2USec(%08x %08x %08x)\n", a0, a1, a2);
- #endif
-
- a0 &= 0x1fffff;
- a1 &= 0x1fffff;
- a2 &= 0x1fffff;
- a0 /= 4;
- a1 /= 4;
- a2 /= 4;
-
- temp = LE32(psx_ram[a0]);
- temp |= (uint64_t)LE32(psx_ram[a0+1])<<32;
-
- temp *= (uint64_t)1000000;
- temp /= (uint64_t)36864000;
-
- // temp now is USec
- seconds = (temp / 1000000) & 0xffffffff;
- usec = (temp % 1000000) & 0xffffffff;
-
- psx_ram[a1] = LE32(seconds);
- psx_ram[a2] = LE32(usec);
- }
- break;
-
- default:
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- break;
- }
- }
- else if (!strcmp(name, "thevent"))
- {
- switch (callnum)
- {
- case 4: // CreateEventFlag
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- #if DEBUG_HLE_IOP
- printf("IOP: CreateEventFlag(%08x) (PC=%x)\n", a0, mipsinfo.i);
- #endif
-
- a0 &= 0x1fffff;
- a0 /= 4;
-
- evflags[iNumFlags].type = LE32(psx_ram[a0]);
- evflags[iNumFlags].value = LE32(psx_ram[a0+1]);
- evflags[iNumFlags].param = LE32(psx_ram[a0+2]);
- evflags[iNumFlags].inUse = 1;
-
- #if DEBUG_HLE_IOP
- printf(" Flag %02d: type %d init %08x param %08x\n", iNumFlags, evflags[iNumFlags].type, evflags[iNumFlags].value, evflags[iNumFlags].param);
- #endif
-
- mipsinfo.i = iNumFlags+1;
- iNumFlags++;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 6: // SetEventFlag
- a0--;
- #if DEBUG_HLE_IOP
- printf("IOP: SetEventFlag(%d %08x)\n", a0, a1);
- #endif
-
- evflags[a0].value |= a1;
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 7: // iSetEventFlag
- a0--;
- #if DEBUG_HLE_IOP
- printf("IOP: iSetEventFlag(%08x %08x)\n", a0, a1);
- #endif
-
- evflags[a0].value |= a1;
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
-
- for (i=0; i < iNumThreads; i++)
- {
- if ((threads[i].iState == TS_WAITEVFLAG) && (threads[i].waitparm == a0))
- {
- threads[i].iState = TS_READY;
- }
- }
- break;
-
- case 8: // ClearEventFlag
- a0--;
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- #if DEBUG_HLE_IOP
- printf("IOP: ClearEventFlag(%d %08x) (PC=%x)\n", a0, a1, mipsinfo.i);
- #endif
-
- evflags[a0].value &= a1;
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 9: // iClearEventFlag
- a0--;
- #if DEBUG_HLE_IOP
- printf("IOP: iClearEventFlag(%d %08x)\n", a0, a1);
- #endif
-
- evflags[a0].value &= a1;
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 10:// WaitEventFlag
- a0--;
- #if DEBUG_HLE_IOP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- printf("IOP: WaitEventFlag(%d %08x %d %08x PC=%x)\n", a0, a1, a2, a3, mipsinfo.i);
- #endif
-
- // if we're not set, freeze this thread
- if (!(evflags[a0].value & a1))
- {
- FreezeThread(iCurThread, 1);
- threads[iCurThread].iState = TS_WAITEVFLAG;
- threads[iCurThread].waitparm = a0;
- iCurThread = -1;
-
- ps2_reschedule();
- }
- else
- {
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- default:
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- break;
- }
- }
- else if (!strcmp(name, "thsemap"))
- {
- int foundthread;
-
- switch (callnum)
- {
- case 4: // CreateSema
- #if DEBUG_HLE_IOP
- printf("IOP: CreateSema(%08x)\n", a0);
- #endif
-
- mipsinfo.i = -1;
- for (i = 0; i < SEMA_MAX; i++)
- {
- if (!semaphores[i].inuse)
- {
- mipsinfo.i = i;
- break;
- }
- }
-
- if (mipsinfo.i == -1)
- {
- printf("IOP: out of semaphores!\n");
- }
-
- a0 &= 0x7fffffff;
- a0 /= 4;
-
-// printf("Sema %d Parms: %08x %08x %08x %08x\n", mipsinfo.i, psx_ram[a0], psx_ram[a0+1], psx_ram[a0+2], psx_ram[a0+3]);
-
- if (mipsinfo.i != -1)
- {
- semaphores[mipsinfo.i].attr = LE32(psx_ram[a0]);
- semaphores[mipsinfo.i].option = LE32(psx_ram[a0+1]);
- semaphores[mipsinfo.i].init = LE32(psx_ram[a0+2]);
- semaphores[mipsinfo.i].max = LE32(psx_ram[a0+3]);
-
- semaphores[mipsinfo.i].current = semaphores[mipsinfo.i].init;
-
- semaphores[mipsinfo.i].inuse = 1;
- }
-
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 6: // SignalSema
- #if DEBUG_HLE_IOP
- printf("IOP: SignalSema(%d) (current %d)\n", a0, semaphores[a0].current);
- #endif
-
- foundthread = 0;
- for (i=0; i < iNumThreads; i++)
- {
- if ((threads[i].iState == TS_WAITSEMA) && (threads[i].waitparm == a0))
- {
- threads[i].iState = TS_READY;
- semaphores[a0].threadsWaiting--;
- foundthread = 1;
- break;
- }
- }
-
- mipsinfo.i = 0;
-
- if (!foundthread)
- {
- if (semaphores[a0].current < semaphores[a0].max)
- {
- semaphores[a0].current++;
- }
- else
- {
- mipsinfo.i = -420; // semaphore overflow
- }
- }
-
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 7: // iSignalSema
- #if DEBUG_HLE_IOP
- printf("IOP: iSignalSema(%d)\n", a0);
- #endif
-
- foundthread = 0;
- for (i=0; i < iNumThreads; i++)
- {
- if ((threads[i].iState == TS_WAITSEMA) && (threads[i].waitparm == a0))
- {
- threads[i].iState = TS_READY;
- semaphores[a0].threadsWaiting--;
- foundthread = 1;
- break;
- }
- }
-
- mipsinfo.i = 0;
-
- if (!foundthread)
- {
- if (semaphores[a0].current < semaphores[a0].max)
- {
- semaphores[a0].current++;
- }
- else
- {
- mipsinfo.i = -420; // semaphore overflow
- }
- }
-
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 8: // WaitSema
- #if DEBUG_HLE_IOP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- printf("IOP: WaitSema(%d) (cnt %d) (th %d) (PC=%x)\n", a0, iCurThread, semaphores[a0].current, mipsinfo.i);
- #endif
-
- if (semaphores[a0].current > 0)
- {
- semaphores[a0].current--;
- }
- else
- {
- FreezeThread(iCurThread, 1);
- threads[iCurThread].iState = TS_WAITSEMA;
- threads[iCurThread].waitparm = a0;
- ps2_reschedule();
- }
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- default:
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- break;
- }
- }
- else if (!strcmp(name, "timrman"))
- {
- switch (callnum)
- {
- case 4: // AllocHardTimer
- #if DEBUG_HLE_IOP
- printf("IOP: AllocHardTimer(%d %d %d)\n", a0, a1, a2);
- #endif
- // source, size, prescale
-
- if (a1 != 32)
- {
- printf("IOP: AllocHardTimer doesn't support 16-bit timers!\n");
- }
-
- iop_timers[iNumTimers].source = a0;
- iop_timers[iNumTimers].prescale = a2;
-
- mipsinfo.i = iNumTimers+1;
- iNumTimers++;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 6: // FreeHardTimer
- #if DEBUG_HLE_IOP
- printf("IOP: FreeHardTimer(%d)\n", a0);
- #endif
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 10:// GetTimerCounter
- mipsinfo.i = iop_timers[a0-1].count;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 20: // SetTimerHandler
- #if DEBUG_HLE_IOP
- printf("IOP: SetTimerHandler(%d %d %08x %08x)\n", a0, a1, a2, a3);
- #endif
- // id, compare, handler, common (last is param for handler)
-
- iop_timers[a0-1].target = a1;
- iop_timers[a0-1].handler = a2;
- iop_timers[a0-1].hparam = a3;
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 22: // SetupHardTimer
- #if DEBUG_HLE_IOP
- printf("IOP: SetupHardTimer(%d %d %d %d)\n", a0, a1, a2, a3);
- #endif
- // id, source, mode, prescale
-
- iop_timers[a0-1].source = a1;
- iop_timers[a0-1].mode = a2;
- iop_timers[a0-1].prescale = a3;
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 23: // StartHardTimer
- #if DEBUG_HLE_IOP
- printf("IOP: StartHardTimer(%d)\n", a0);
- #endif
-
- iop_timers[a0-1].iActive = 1;
- iop_timers[a0-1].count = 0;
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 24: // StopHardTimer
- #if DEBUG_HLE_IOP
- printf("IOP: StopHardTimer(%d)\n", a0);
- #endif
-
- iop_timers[a0-1].iActive = 0;
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- default:
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- break;
- }
- }
- else if (!strcmp(name, "sysclib"))
- {
- switch (callnum)
- {
- case 12: // memcpy
- {
- uint8_t *dst, *src;
-
- #if DEBUG_HLE_IOP
- printf("IOP: memcpy(%08x, %08x, %d)\n", a0, a1, a2);
- #endif
-
- dst = (uint8_t *)&psx_ram[(a0&0x1fffff)/4];
- src = (uint8_t *)&psx_ram[(a1&0x1fffff)/4];
- // get exact byte alignment
- dst += a0 % 4;
- src += a1 % 4;
-
- while (a2)
- {
- *dst = *src;
- dst++;
- src++;
- a2--;
- }
-
- // v0 = a0
- mipsinfo.i = a0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 13: // memmove
- {
- uint8_t *dst, *src;
-
- #if DEBUG_HLE_IOP
- printf("IOP: memmove(%08x, %08x, %d)\n", a0, a1, a2);
- #endif
-
- dst = (uint8_t *)&psx_ram[(a0&0x1fffff)/4];
- src = (uint8_t *)&psx_ram[(a1&0x1fffff)/4];
- // get exact byte alignment
- dst += a0 % 4;
- src += a1 % 4;
-
- dst += a2 - 1;
- src += a2 - 1;
-
- while (a2)
- {
- *dst = *src;
- dst--;
- src--;
- a2--;
- }
-
- // v0 = a0
- mipsinfo.i = a0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 14: // memset
- {
- uint8_t *dst;
-
- #if DEBUG_HLE_IOP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- printf("IOP: memset(%08x, %02x, %d) [PC=%x]\n", a0, a1, a2, mipsinfo.i);
- #endif
-
- dst = (uint8_t *)&psx_ram[(a0&0x1fffff)/4];
- dst += (a0 & 3);
-
- memset(dst, a1, a2);
- }
- break;
-
- case 17: // bzero
- {
- uint8_t *dst;
-
- #if DEBUG_HLE_IOP
- printf("IOP: bzero(%08x, %08x)\n", a0, a1);
- #endif
-
- dst = (uint8_t *)&psx_ram[(a0&0x1fffff)/4];
- dst += (a0 & 3);
- memset(dst, 0, a1);
- }
- break;
-
- case 19: // sprintf
- mname = (char *)psx_ram;
- str1 = (char *)psx_ram;
- mname += a0 & 0x1fffff;
- str1 += a1 & 0x1fffff;
-
- #if DEBUG_HLE_IOP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- printf("IOP: sprintf(%08x, %s, ...) [PC=%08x]\n", a0, str1, (uint32_t)mipsinfo.i);
- printf("%x %x %x %x\n", a0, a1, a2, a3);
- #endif
-
- iop_sprintf(mname, str1, CPUINFO_INT_REGISTER + MIPS_R6); // a2 is first parameter
-
- #if DEBUG_HLE_IOP
- printf(" = [%s]\n", mname);
- #endif
- break;
-
- case 23: // strcpy
- {
- uint8_t *dst, *src;
-
- #if DEBUG_HLE_IOP
- printf("IOP: strcpy(%08x, %08x)\n", a0, a1);
- #endif
-
- dst = (uint8_t *)&psx_ram[(a0&0x1fffff)/4];
- src = (uint8_t *)&psx_ram[(a1&0x1fffff)/4];
- // get exact byte alignment
- dst += a0 % 4;
- src += a1 % 4;
-
- while (*src != '\0')
- {
- *dst = *src;
- dst++;
- src++;
- }
- *dst = '\0';
-
- // v0 = a0
- mipsinfo.i = a0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 27: // strlen
- {
- char *dst;
-
- #if DEBUG_HLE_IOP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- printf("IOP: strlen(%08x) [PC=%x]\n", a0, mipsinfo.i);
- #endif
-
- dst = (char *)&psx_ram[(a0&0x1fffff)/4];
- dst += (a0 & 3);
- mipsinfo.i = strlen(dst);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
- case 30: // strncpy
- {
- char *dst, *src;
-
- #if DEBUG_HLE_IOP
- printf("IOP: strncpy(%08x, %08x, %d)\n", a0, a1, a2);
- #endif
-
- dst = (char *)&psx_ram[(a0&0x1fffff)/4];
- src = (char *)&psx_ram[(a1&0x1fffff)/4];
- // get exact byte alignment
- dst += a0 % 4;
- src += a1 % 4;
-
- while ((*src != '\0') && (a2 > 0))
- {
- *dst = *src;
- dst++;
- src++;
- a2--;
- }
- *dst = '\0';
-
- // v0 = a0
- mipsinfo.i = a0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- }
- break;
-
-
- case 36: // strtol
- mname = (char *)&psx_ram[(a0 & 0x1fffff)/4];
- mname += (a0 & 3);
-
- if (a1)
- {
- printf("IOP: Unhandled strtol with non-NULL second parm\n");
- }
-
- mipsinfo.i = strtol(mname, NULL, a2);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- default:
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- break;
- }
- }
- else if (!strcmp(name, "intrman"))
- {
- switch (callnum)
- {
- case 4: // RegisterIntrHandler
- #if DEBUG_HLE_IOP
- printf("IOP: RegisterIntrHandler(%d %08x %08x %08x)\n", a0, a1, a2, a3);
- #endif
-
- if (a0 == 9)
- {
- irq9_fval = a1;
- irq9_cb = a2;
- irq9_flag = a3;
- }
-
- // DMA4?
- if (a0 == 36)
- {
- dma4_fval = a1;
- dma4_cb = a2;
- dma4_flag = a3;
- }
-
- // DMA7?
- if (a0 == 40)
- {
- dma7_fval = a1;
- dma7_cb = a2;
- dma7_flag = a3;
- }
- break;
-
- case 5: // ReleaseIntrHandler
- #if DEBUG_HLE_IOP
- printf("IOP: ReleaseIntrHandler(%d)\n", a0);
- #endif
- break;
-
- case 6: // EnableIntr
- #if DEBUG_HLE_IOP
- printf("IOP: EnableIntr(%d)\n", a0);
- #endif
- break;
-
- case 7: // DisableIntr
- #if DEBUG_HLE_IOP
- printf("IOP: DisableIntr(%d)\n", a0);
- #endif
- break;
-
- case 8: // CpuDisableIntr
- #if DEBUG_HLE_IOP
- printf("IOP: CpuDisableIntr(%d)\n", a0);
- #endif
- break;
-
- case 9: // CpuEnableIntr
- #if DEBUG_HLE_IOP
- printf("IOP: CpuEnableIntr(%d)\n", a0);
- #endif
- break;
-
- case 17: // CpuSuspendIntr
- #if DEBUG_HLE_IOP
- printf("IOP: CpuSuspendIntr\n");
- #endif
-
- // if already suspended, return an error code
- if (intr_susp)
- {
- mipsinfo.i = -102;
- }
- else
- {
- mipsinfo.i = 0;
- }
- intr_susp = 1;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 18: // CpuResumeIntr
- #if DEBUG_HLE_IOP
- printf("IOP: CpuResumeIntr\n");
- #endif
- intr_susp = 0;
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 23: // QueryIntrContext
- #if DEBUG_HLE_IOP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- printf("IOP: QueryIntrContext(PC=%x)\n", mipsinfo.i);
- #endif
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- default:
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- break;
- }
- }
- else if (!strcmp(name, "loadcore"))
- {
- switch (callnum)
- {
- case 5: // FlushDcache
- #if DEBUG_HLE_IOP
- printf("IOP: FlushDcache()\n");
- #endif
- break;
-
- case 6: // RegisterLibraryEntries
- a0 &= 0x1fffff;
- #if DEBUG_HLE_IOP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- printf("IOP: RegisterLibraryEntries(%08x) (PC=%x)\n", a0, mipsinfo.i);
- #endif
-
- if (psx_ram[a0/4] == LE32(0x41c00000))
- {
- a0 += 3*4;
- memcpy(®libs[iNumLibs].name, &psx_ram[a0/4], 8);
- reglibs[iNumLibs].name[8] = '\0';
- #if DEBUG_HLE_IOP
- printf("Lib name [%s]\n", ®libs[iNumLibs].name);
- #endif
- a0 += 2*4;
- reglibs[iNumLibs].dispatch = a0;
- iNumLibs++;
- }
- else
- {
- printf("ERROR: Entry table signature missing\n");
-
- }
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- default:
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- break;
- }
- }
- else if (!strcmp(name, "sysmem"))
- {
- uint32_t newAlloc;
-
- switch (callnum)
- {
- case 4: // AllocMemory
- newAlloc = psf2_get_loadaddr();
- // make sure we're 16-byte aligned
- if (newAlloc & 15)
- {
- newAlloc &= ~15;
- newAlloc += 16;
- }
-
- if (a1 & 15)
- {
- a1 &= ~15;
- a1 += 16;
- }
-
- psf2_set_loadaddr(newAlloc + a1);
-
- #if DEBUG_HLE_IOP
- printf("IOP: AllocMemory(%d, %d, %x) = %08x\n", a0, a1, a2, newAlloc|0x80000000);
- #endif
-
- mipsinfo.i = newAlloc; // | 0x80000000;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 5: // FreeMemory
- #if DEBUG_HLE_IOP
- printf("IOP: FreeMemory(%x)\n", a0);
- #endif
- break;
-
- case 7: // QueryMaxFreeMemSize
- #if DEBUG_HLE_IOP
- printf("IOP: QueryMaxFreeMemSize\n");
- #endif
-
- mipsinfo.i = (2*1024*1024) - psf2_get_loadaddr();
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 8: // QueryTotalFreeMemSize
- #if DEBUG_HLE_IOP
- printf("IOP: QueryTotalFreeMemSize\n");
- #endif
-
- mipsinfo.i = (2*1024*1024) - psf2_get_loadaddr();
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 14: // Kprintf
- mname = (char *)psx_ram;
- mname += a0 & 0x1fffff;
- mname += (a0 & 3);
-
- iop_sprintf(out, mname, CPUINFO_INT_REGISTER + MIPS_R5); // a1 is first parm
-
- if (out[strlen(out)-1] != '\n')
- {
- strcat(out, "\n");
- }
-
- // filter out ESC characters
- {
- int ch;
-
- for (ch = 0; ch < strlen(out); ch++)
- {
- if (out[ch] == 27)
- {
- out[ch] = ']';
- }
- }
- }
-
- #if DEBUG_HLE_IOP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- printf("KTTY: %s [PC=%x]\n", out, mipsinfo.i);
- #endif
- break;
-
- default:
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- break;
- }
- }
- else if (!strcmp(name, "modload"))
- {
- uint8_t *tempmem;
- uint32_t newAlloc;
-
- switch (callnum)
- {
- case 7: // LoadStartModule
- mname = (char *)&psx_ram[(a0 & 0x1fffff)/4];
- mname += 8;
- str1 = (char *)&psx_ram[(a2 & 0x1fffff)/4];
- #if DEBUG_HLE_IOP
- printf("LoadStartModule: %s\n", mname);
- #endif
-
- // get 2k for our parameters
- newAlloc = psf2_get_loadaddr();
- // force 16-byte alignment
- if (newAlloc & 0xf)
- {
- newAlloc &= ~0xf;
- newAlloc += 16;
- }
- psf2_set_loadaddr(newAlloc + 2048);
-
- tempmem = (uint8_t *)malloc(2*1024*1024);
- if (psf2_load_file(mname, tempmem, 2*1024*1024) != 0xffffffff)
- {
- uint32_t start;
- int i;
-
- start = psf2_load_elf(tempmem, 2*1024*1024);
-
- if (start != 0xffffffff)
- {
- uint32_t args[20], numargs = 1, argofs;
- uint8_t *argwalk = (uint8_t *)psx_ram;
-
- argwalk += (a2 & 0x1fffff);
-
- args[0] = a0; // program name is argc[0]
-
- argofs = 0;
-
- if (a1 > 0)
- {
- args[numargs] = a2;
- numargs++;
-
- while (a1)
- {
- if ((*argwalk == 0) && (a1 > 1))
- {
- args[numargs] = a2 + argofs + 1;
- numargs++;
- }
- argwalk++;
- argofs++;
- a1--;
- }
- }
-
- for (i = 0; i < numargs; i++)
- {
- #if DEBUG_HLE_IOP
-// printf("Arg %d: %08x [%s]\n", i, args[i], &argbase[args[i]-a2]);
- #endif
- psx_ram[(newAlloc/4)+i] = LE32(args[i]);
- }
-
- // set argv and argc
- mipsinfo.i = numargs;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
- mipsinfo.i = 0x80000000 | newAlloc;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R5, &mipsinfo);
-
- // leave RA alone, PC = module start
- // (NOTE: we get called in the delay slot!)
- mipsinfo.i = start - 4;
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
- }
- }
- free(tempmem);
- break;
-
- default:
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- break;
- }
-
- }
- else if (!strcmp(name, "ioman"))
- {
- switch (callnum)
- {
- case 4: // open
- {
- int i, slot2use;
-
- slot2use = -1;
- for (i = 0; i < MAX_FILE_SLOTS; i++)
- {
- if (filestat[i] == 0)
- {
- slot2use = i;
- break;
- }
- }
-
- if (slot2use == -1)
- {
- printf("IOP: out of file slots!\n");
- mipsinfo.i = 0xffffffff;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- return;
- }
-
- mname = (char *)psx_ram;
- mname += (a0 & 0x1fffff);
-
- if (!strncmp(mname, "aofile:", 7))
- {
- mname += 8;
- }
- else if (!strncmp(mname, "hefile:", 7))
- {
- mname += 8;
- }
- else if (!strncmp(mname, "host0:", 6))
- {
- mname += 7;
- }
-
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- #if DEBUG_HLE_IOP
- printf("IOP: open(\"%s\") (PC=%08x)\n", mname, mipsinfo.i);
- #endif
-
- filedata[slot2use] = malloc(6*1024*1024);
- filesize[slot2use] = psf2_load_file(mname, filedata[slot2use], 6*1024*1024);
- filepos[slot2use] = 0;
- filestat[slot2use] = 1;
-
- if (filesize[slot2use] == 0xffffffff)
- {
- mipsinfo.i = filesize[slot2use];
- }
- else
- {
- mipsinfo.i = slot2use;
- }
- }
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 5: // close
- #if DEBUG_HLE_IOP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- printf("IOP: close(%d) (PC=%08x)\n", a0, mipsinfo.i);
- #endif
- free(filedata[a0]);
- filedata[a0] = (uint8_t *)NULL;
- filepos[a0] = 0;
- filesize[a0] = 0;
- filestat[a0] = 0;
- break;
-
- case 6: // read
- #if DEBUG_HLE_IOP
- printf("IOP: read(%x %x %d) [pos %d size %d]\n", a0, a1, a2, filepos[a0], filesize[a0]);
- #endif
-
- if (filepos[a0] >= filesize[a0])
- {
- mipsinfo.i = 0;
- }
- else
- {
- uint8_t *rp;
-
- if ((filepos[a0] + a2) > filesize[a0])
- {
- a2 = filesize[a0] - filepos[a0];
- }
-
- rp = (uint8_t *)psx_ram;
- rp += (a1 & 0x1fffff);
- memcpy(rp, &filedata[a0][filepos[a0]], a2);
-
- filepos[a0] += a2;
- mipsinfo.i = a2;
- }
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 8: // lseek
- #if DEBUG_HLE_IOP
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- printf("IOP: lseek(%d, %d, %s) (PC=%08x)\n", a0, a1, seek_types[a2], mipsinfo.i);
- #endif
-
- switch (a2)
- {
- case 0: // SEEK_SET
- if (a1 <= filesize[a0])
- {
- filepos[a0] = a1;
- }
- break;
- case 1: // SEEK_CUR
- if ((a1 + filepos[a0]) < filesize[a0])
- {
- filepos[a0] += a1;
- }
- break;
- case 2: // SEEK_END
- filepos[a0] = filesize[a0] - a1;
- break;
- }
-
- mipsinfo.i = filepos[a0];
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 20: // AddDrv
- #if DEBUG_HLE_IOP
- printf("IOP: AddDrv(%x)\n", a0);
- #endif
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- case 21: // DelDrv
- #if DEBUG_HLE_IOP
- printf("IOP: DelDrv(%x)\n", a0);
- #endif
-
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
- break;
-
- default:
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- }
- }
- else
- {
- int lib;
-
- if (iNumLibs > 0)
- {
- for (lib = 0; lib < iNumLibs; lib++)
- {
- if (!strcmp(name, reglibs[lib].name))
- {
- #if DEBUG_HLE_IOP
- uint32_t PC;
-
- mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
- PC = mipsinfo.i;
- #endif
-
- // zap the delay slot handling
- mipsinfo.i = 0;
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_DELAYV, &mipsinfo);
- mips_set_info(CPUINFO_INT_REGISTER + MIPS_DELAYR, &mipsinfo);
-
- mipsinfo.i = LE32(psx_ram[(reglibs[lib].dispatch/4) + callnum]);
-
- // (NOTE: we get called in the delay slot!)
- #if DEBUG_HLE_IOP
- printf("IOP: Calling %s (%d) service %d => %08x (parms %08x %08x %08x %08x) (PC=%x)\n",
- reglibs[lib].name,
- lib,
- callnum,
- (uint32_t)mipsinfo.i,
- a0, a1, a2, a3, PC);
- #endif
-
- #if 0
- if (!strcmp(reglibs[lib].name, "ssd"))
- {
- if (callnum == 37)
- {
- psxcpu_verbose = 4096;
- }
- }
- #endif
-
- mipsinfo.i -= 4;
- mips_set_info(CPUINFO_INT_PC, &mipsinfo);
-
- return;
- }
- }
- }
-
- printf("IOP: Unhandled service %d for module %s\n", callnum, name);
- }
-}
-
diff --git a/src/psf/psx_hw.cc b/src/psf/psx_hw.cc
new file mode 100644
index 000000000000..94de88d6fb8d
--- /dev/null
+++ b/src/psf/psx_hw.cc
@@ -0,0 +1,3542 @@
+/*
+ Audio Overload SDK - PSX and IOP hardware emulation
+
+ Copyright (c) 2007 R. Belmont and Richard Bannister.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ psx_hw.c - Minimal PSX/IOP hardware glue/emulation/whatever
+
+ supported: main RAM (2 MB, mirrored to fill an 8 MB space like on real HW)
+ DMA channel 4 (SPURAM) in both directions (including completion IRQ)
+ VBL IRQ
+ Root counters 2 and 3 including completion events and IRQs
+ Some BIOS services including exception handling (via HLE)
+ HLE emulation of IOP operating system, including multithreading
+ SPU(2), SPU(2)RAM (via PEOpS)
+
+
+
+ Special notes:
+ PSF1
+ - Chocobo's Dungeon 2 contains an illegal code sequence (patched)
+
+ PSF2
+ - Shadow Hearts assumes that the wave buffer alloc will go to 0x80060000 and the sequence buffer to 0x80170000.
+ Our memory management doesn't work out that way, so we have to (wait for it) cheese it.
+*/
+
+#include <stdio.h>
+
+#include "ao.h"
+#include "cpuintrf.h"
+#include "psx.h"
+
+#define DEBUG_HLE_BIOS (0) // debug PS1 HLE BIOS
+#define DEBUG_SPU (0) // debug PS1 SPU read/write
+#define DEBUG_SPU2 (0) // debug PS2 SPU read/write
+#define DEBUG_HLE_IOP (0) // debug PS2 IOP OS calls
+#define DEBUG_UNK_RW (0) // debug unknown reads/writes
+#define DEBUG_THREADING (0) // debug PS2 IOP threading
+
+#define LE32(x) FROM_LE32(x)
+
+extern void mips_get_info(uint32_t state, union cpuinfo *info);
+extern void mips_set_info(uint32_t state, union cpuinfo *info);
+extern int psxcpu_verbose;
+extern uint16_t SPUreadRegister(uint32_t reg);
+extern void SPUwriteRegister(uint32_t reg, uint16_t val);
+extern void SPUwriteDMAMem(uint32_t usPSXMem,int iSize);
+extern void SPUreadDMAMem(uint32_t usPSXMem,int iSize);
+extern void mips_shorten_frame(void);
+extern int mips_execute( int cycles );
+extern uint32_t psf2_load_file(const char *file, uint8_t *buf, uint32_t buflen);
+extern uint32_t psf2_load_elf(uint8_t *start, uint32_t len);
+void psx_hw_runcounters(void);
+int mips_get_icount(void);
+void mips_set_icount(int count);
+
+extern int psf_refresh;
+
+// SPU2
+extern void SPU2write(unsigned long reg, unsigned short val);
+extern unsigned short SPU2read(unsigned long reg);
+extern void SPU2readDMA4Mem(uint32_t usPSXMem,int iSize);
+extern void SPU2writeDMA4Mem(uint32_t usPSXMem,int iSize);
+extern void SPU2readDMA7Mem(uint32_t usPSXMem,int iSize);
+extern void SPU2writeDMA7Mem(uint32_t usPSXMem,int iSize);
+extern void SPU2interruptDMA4(void);
+extern void SPU2interruptDMA7(void);
+
+#define MAX_FILE_SLOTS (32)
+
+static volatile int softcall_target = 0;
+static int filestat[MAX_FILE_SLOTS];
+static uint8_t *filedata[MAX_FILE_SLOTS];
+static uint32_t filesize[MAX_FILE_SLOTS], filepos[MAX_FILE_SLOTS];
+uint32_t psf2_get_loadaddr(void);
+void psf2_set_loadaddr(uint32_t addr);
+static void call_irq_routine(uint32_t routine, uint32_t parameter);
+static int intr_susp = 0;
+
+static uint64_t sys_time;
+static int timerexp = 0;
+
+typedef struct
+{
+ char name[10];
+ uint32_t dispatch;
+} ExternLibEntries;
+
+static int32_t iNumLibs;
+static ExternLibEntries reglibs[32];
+
+typedef struct
+{
+ uint32_t type;
+ uint32_t value;
+ uint32_t param;
+ int inUse;
+} EventFlag;
+
+static int32_t iNumFlags;
+static EventFlag evflags[32];
+
+typedef struct
+{
+ uint32_t attr;
+ uint32_t option;
+ int32_t init;
+ int32_t current;
+ int32_t max;
+ int32_t threadsWaiting;
+ int32_t inuse;
+} Semaphore;
+
+#define SEMA_MAX (64)
+
+static int32_t iNumSema;
+static Semaphore semaphores[SEMA_MAX];
+
+// thread states
+enum
+{
+ TS_RUNNING = 0, // now running
+ TS_READY, // ready to run
+ TS_WAITEVFLAG, // waiting on an event flag
+ TS_WAITSEMA, // waiting on a semaphore
+ TS_WAITDELAY, // waiting on a time delay
+ TS_SLEEPING, // sleeping
+ TS_CREATED, // newly created, hasn't run yet
+
+ TS_MAXSTATE
+};
+
+typedef struct
+{
+ int32_t iState; // state of thread
+
+ uint32_t flags; // flags
+ uint32_t routine; // start of code for the thread
+ uint32_t stackloc; // stack location in IOP RAM
+ uint32_t stacksize; // stack size
+ uint32_t refCon; // user value passed in at CreateThread time
+
+ uint32_t waitparm; // what we're waiting on if in one the TS_WAIT* states
+
+ uint32_t save_regs[37]; // CPU registers belonging to this thread
+} Thread;
+
+static int32_t iNumThreads, iCurThread;
+static Thread threads[32];
+
+#if DEBUG_THREADING
+static char *_ThreadStateNames[TS_MAXSTATE] = { "RUNNING", "READY", "WAITEVFLAG", "WAITSEMA", "WAITDELAY", "SLEEPING", "CREATED" };
+#endif
+
+#if DEBUG_HLE_IOP
+static char *seek_types[3] = { "SEEK_SET", "SEEK_CUR", "SEEK_END" };
+#endif
+
+typedef struct
+{
+ int32_t iActive;
+ uint32_t count;
+ uint32_t target;
+ uint32_t source;
+ uint32_t prescale;
+ uint32_t handler;
+ uint32_t hparam;
+ uint32_t mode;
+} IOPTimer;
+
+static IOPTimer iop_timers[8];
+static int32_t iNumTimers;
+
+typedef struct
+{
+ uint32_t count;
+ uint32_t mode;
+ uint32_t target;
+ uint32_t sysclock;
+ uint32_t interrupt;
+} Counter;
+
+static Counter root_cnts[4]; // 4 of the bastards
+
+#define CLOCK_DIV (8) // 33 MHz / this = what we run the R3000 at to keep the CPU usage not insane
+
+// counter modes
+#define RC_EN (0x0001) // halt
+#define RC_RESET (0x0008) // automatically wrap
+#define RC_IQ1 (0x0010) // IRQ when target reached
+#define RC_IQ2 (0x0040) // IRQ when target reached (pSX treats same as IQ1?)
+#define RC_CLC (0x0100) // counter uses direct system clock
+#define RC_DIV8 (0x0200) // (counter 2 only) system clock/8
+
+typedef struct
+{
+ uint32_t desc;
+ int32_t status;
+ int32_t mode;
+ uint32_t fhandler;
+} EvtCtrlBlk[32];
+
+static EvtCtrlBlk *Event;
+static EvtCtrlBlk *CounterEvent;
+
+// Sony event states
+#define EvStUNUSED 0x0000
+#define EvStWAIT 0x1000
+#define EvStACTIVE 0x2000
+#define EvStALREADY 0x4000
+
+// Sony event modes
+#define EvMdINTR 0x1000
+#define EvMdNOINTR 0x2000
+
+// PSX main RAM
+uint32_t psx_ram[(2*1024*1024)/4];
+uint32_t psx_scratch[0x400];
+// backup image to restart songs
+uint32_t initial_ram[(2*1024*1024)/4];
+uint32_t initial_scratch[0x400];
+
+static uint32_t spu_delay, dma_icr, irq_data, irq_mask, dma_timer, WAI;
+static uint32_t dma4_madr, dma4_bcr, dma4_chcr, dma4_delay;
+static uint32_t dma7_madr, dma7_bcr, dma7_chcr, dma7_delay;
+static uint32_t dma4_cb, dma7_cb, dma4_fval, dma4_flag, dma7_fval, dma7_flag;
+static uint32_t irq9_cb, irq9_fval, irq9_flag;
+
+// take a snapshot of the CPU state for a thread
+static void FreezeThread(int32_t iThread, int flag)
+{
+ int i;
+ union cpuinfo mipsinfo;
+
+ #if DEBUG_THREADING
+// printf("IOP: FreezeThread(%d)\n", iThread);
+ #endif
+
+ for (i = 0; i < 32; i++)
+ {
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R0 + i, &mipsinfo);
+ threads[iThread].save_regs[i] = mipsinfo.i;
+ }
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
+ threads[iThread].save_regs[32] = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
+ threads[iThread].save_regs[33] = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_DELAYV, &mipsinfo);
+ threads[iThread].save_regs[35] = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_DELAYR, &mipsinfo);
+ threads[iThread].save_regs[36] = mipsinfo.i;
+
+
+ // if a thread is freezing itself due to a IOP syscall, we must save the RA as the PC
+ // to come back to or else the syscall will recurse
+ if (flag)
+ {
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ }
+ else
+ {
+ mips_get_info(CPUINFO_INT_PC, &mipsinfo);
+ }
+ threads[iThread].save_regs[34] = mipsinfo.i;
+
+ #if DEBUG_THREADING
+ {
+ char buffer[256];
+
+ DasmMIPS(buffer, mipsinfo.i, &psx_ram[(mipsinfo.i & 0x7fffffff)/4]);
+
+ printf("IOP: FreezeThread(%d) => %08x [%s]\n", iThread, threads[iThread].save_regs[34], buffer);
+ }
+ #endif
+
+ // if thread was running, now it's ready
+ if (threads[iThread].iState == TS_RUNNING)
+ {
+ threads[iThread].iState = TS_READY;
+ }
+}
+
+// restore the CPU state from a thread's snapshot
+static void ThawThread(int32_t iThread)
+{
+ int i;
+ union cpuinfo mipsinfo;
+
+ // the first time a thread is put on the CPU,
+ // some special setup is required
+ if (threads[iThread].iState == TS_CREATED)
+ {
+ // PC = starting routine
+ threads[iThread].save_regs[34] = threads[iThread].routine-4; // compensate for weird delay slot effects
+ // SP = thread's stack area
+ threads[iThread].save_regs[29] = (threads[iThread].stackloc + threads[iThread].stacksize) - 16;
+ threads[iThread].save_regs[29] |= 0x80000000;
+
+ threads[iThread].save_regs[35] = threads[iThread].save_regs[36] = 0;
+
+ #if DEBUG_THREADING
+// printf("IOP: Initial setup for thread %d => PC %x SP %x\n", iThread, threads[iThread].save_regs[34]+4, threads[iThread].save_regs[29]);
+ #endif
+ }
+
+ #if DEBUG_THREADING
+ {
+ char buffer[256];
+
+ mips_get_info(CPUINFO_INT_PC, &mipsinfo);
+ DasmMIPS(buffer, mipsinfo.i, &psx_ram[(mipsinfo.i & 0x7fffffff)/4]);
+
+ printf("IOP: ThawThread(%d) => %08x [%s] (wake %d)\n", iThread, threads[iThread].save_regs[34], buffer, wakecount);
+ }
+ #endif
+
+ for (i = 0; i < 32; i++)
+ {
+ mipsinfo.i = threads[iThread].save_regs[i];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R0 + i, &mipsinfo);
+ }
+
+ mipsinfo.i = threads[iThread].save_regs[32];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
+ mipsinfo.i = threads[iThread].save_regs[33];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
+ mipsinfo.i = threads[iThread].save_regs[34];
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+ mipsinfo.i = threads[iThread].save_regs[35];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_DELAYV, &mipsinfo);
+ mipsinfo.i = threads[iThread].save_regs[36];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_DELAYR, &mipsinfo);
+
+ threads[iThread].iState = TS_RUNNING;
+}
+
+// find a new thread to run
+static void ps2_reschedule(void)
+{
+ int i, starti, iNextThread;
+
+ iNextThread = -1;
+
+ // see if any thread other than the current one is ready to run
+ i = iCurThread+1;
+ if (i >= iNumThreads)
+ {
+ i = 0;
+ }
+
+ starti = i;
+
+ // starting with the next thread after this one,
+ // see who wants to run
+ while (i < iNumThreads)
+ {
+ if (i != iCurThread)
+ {
+ if (threads[i].iState == TS_READY)
+ {
+ iNextThread = i;
+ break;
+ }
+ }
+
+ i++;
+ }
+
+ // if we started above thread 0 and didn't pick one,
+ // go around and try from zero
+ if ((starti > 0) && (iNextThread == -1))
+ {
+ for (i = 0; i < iNumThreads; i++)
+ {
+ if (i != iCurThread)
+ {
+ if (threads[i].iState == TS_READY)
+ {
+ iNextThread = i;
+ break;
+ }
+ }
+ }
+ }
+
+ if (iNextThread != -1)
+ {
+ #if DEBUG_THREADING
+ for (i = 0; i < iNumThreads; i++)
+ {
+ printf("Thread %02d: %s\n", i, _ThreadStateNames[threads[i].iState]);
+ }
+ #endif
+
+ if (iCurThread != -1)
+ {
+ FreezeThread(iCurThread, 0);
+ }
+ ThawThread(iNextThread);
+ iCurThread = iNextThread;
+ threads[iCurThread].iState = TS_RUNNING;
+ }
+ else
+ {
+ // no thread to switch to, is the current one still running?
+ if (iCurThread != -1)
+ {
+ if (threads[iCurThread].iState != TS_RUNNING)
+ {
+ #if DEBUG_THREADING
+ printf("IOP: no threads to run\n");
+
+ for (i = 0; i < iNumThreads; i++)
+ {
+ printf("Thread %02d: %s\n", i, _ThreadStateNames[threads[i].iState]);
+ }
+ #endif
+
+ mips_shorten_frame(); // kill the CPU
+ iCurThread = -1; // no threads are active
+ }
+ }
+ else
+ {
+ mips_shorten_frame(); // kill the CPU
+ iCurThread = -1; // no threads are active
+ }
+ }
+}
+
+static void psx_irq_update(void)
+{
+ union cpuinfo mipsinfo;
+
+ if ((irq_data & irq_mask) != 0)
+ { // assert the line
+ WAI = 0;
+ mipsinfo.i = ASSERT_LINE;
+ mips_set_info( CPUINFO_INT_INPUT_STATE + MIPS_IRQ0, &mipsinfo );
+ }
+ else
+ {
+ // clear the line
+ mipsinfo.i = CLEAR_LINE;
+ mips_set_info( CPUINFO_INT_INPUT_STATE + MIPS_IRQ0, &mipsinfo );
+ }
+}
+
+void psx_irq_set(uint32_t irq)
+{
+ irq_data |= irq;
+
+ psx_irq_update();
+}
+
+static uint32_t gpu_stat = 0;
+
+uint32_t psx_hw_read(offs_t offset, uint32_t mem_mask)
+{
+ if (offset >= 0x00000000 && offset <= 0x007fffff)
+ {
+ offset &= 0x1fffff;
+ return LE32(psx_ram[offset>>2]);
+ }
+
+ if (offset >= 0x80000000 && offset <= 0x807fffff)
+ {
+ offset &= 0x1fffff;
+ return LE32(psx_ram[offset>>2]);
+ }
+
+ if (offset == 0xbfc00180 || offset == 0xbfc00184) // exception vector
+ {
+ return FUNCT_HLECALL;
+ }
+
+ if (offset == 0x1f801014)
+ {
+ return spu_delay;
+ }
+
+ if (offset == 0xbf801014)
+ {
+ return spu_delay;
+ }
+
+ if (offset == 0x1f801814)
+ {
+ gpu_stat ^= 0xffffffff;
+ return gpu_stat;
+ }
+
+ if (offset >= 0x1f801c00 && offset <= 0x1f801dff)
+ {
+ if ((mem_mask == 0xffff0000) || (mem_mask == 0xffffff00))
+ {
+ #if DEBUG_SPU
+ printf("SPU: readRegister(%x)\n", offset);
+ #endif
+ return SPUreadRegister(offset) & ~mem_mask;
+ }
+ else if (mem_mask == 0x0000ffff)
+ {
+ #if DEBUG_SPU
+ printf("SPU: readRegister(%x)\n", offset);
+ #endif
+ return SPUreadRegister(offset)<<16;
+ }
+ else printf("SPU: read unknown mask %08x\n", mem_mask);
+ }
+
+ if (offset >= 0xbf900000 && offset <= 0xbf9007ff)
+ {
+ if ((mem_mask == 0xffff0000) || (mem_mask == 0xffffff00))
+ {
+ return SPU2read(offset) & ~mem_mask;
+ }
+ else if (mem_mask == 0x0000ffff)
+ {
+ return SPU2read(offset)<<16;
+ }
+ else if (mem_mask == 0)
+ {
+ return SPU2read(offset) | SPU2read(offset+2)<<16;
+ }
+ else printf("SPU2: read unknown mask %08x\n", mem_mask);
+ }
+
+ if (offset >= 0x1f801100 && offset <= 0x1f801128)
+ {
+ int cnt = (offset>>4) & 0xf;
+
+ switch (offset & 0xf)
+ {
+ case 0:
+// printf("RC: read counter %d count = %x\n", cnt, root_cnts[cnt].count);
+ return root_cnts[cnt].count;
+ break;
+ case 4:
+// printf("RC: read counter %d mode\n", cnt);
+ return root_cnts[cnt].mode;
+ break;
+ case 8:
+// printf("RC: read counter %d target\n", cnt);
+ return root_cnts[cnt].target;
+ break;
+ }
+
+ return 0;
+ }
+
+ if (offset == 0x1f8010f4)
+ {
+ return dma_icr;
+ }
+ else if (offset == 0x1f801070)
+ {
+// printf("Read IRQ_data %x (mask %08x)\n", irq_data, mem_mask);
+ return irq_data;
+ }
+ else if (offset == 0x1f801074)
+ {
+ return irq_mask;
+ }
+
+/* if (offset == 0xbf801508)
+ {
+ return dma7_bcr;
+ }*/
+
+ if (offset == 0xbf920344)
+ {
+ return 0x80808080;
+ }
+
+ #if DEBUG_UNK_RW
+ {
+ union cpuinfo mipsinfo;
+
+ mips_get_info(CPUINFO_INT_PC, &mipsinfo);
+ printf("Unknown read: %08x, mask %08x (PC=%x)\n", offset&~3, mem_mask, mipsinfo.i);
+ }
+ #endif
+ return 0;
+}
+
+static void psx_dma4(uint32_t madr, uint32_t bcr, uint32_t chcr)
+{
+ if (chcr == 0x01000201) // cpu to SPU
+ {
+ #if DEBUG_SPU
+ printf("DMA4: RAM %08x to SPU\n", madr);
+ #endif
+ bcr = (bcr>>16) * (bcr & 0xffff) * 2;
+ SPUwriteDMAMem(madr&0x1fffff, bcr);
+ }
+ else
+ {
+ #if DEBUG_SPU
+ printf("DMA4: SPU to RAM %08x\n", madr);
+ #endif
+ bcr = (bcr>>16) * (bcr & 0xffff) * 2;
+ SPUreadDMAMem(madr&0x1fffff, bcr);
+ }
+}
+
+static void ps2_dma4(uint32_t madr, uint32_t bcr, uint32_t chcr)
+{
+ if (chcr == 0x01000201) // cpu to SPU2
+ {
+ #if DEBUG_HLE_IOP
+ printf("DMA4: RAM %08x to SPU2\n", madr);
+ #endif
+ bcr = (bcr>>16) * (bcr & 0xffff) * 4;
+ SPU2writeDMA4Mem(madr&0x1fffff, bcr);
+ }
+ else
+ {
+ #if DEBUG_HLE_IOP
+ printf("DMA4: SPU2 to RAM %08x\n", madr);
+ #endif
+ bcr = (bcr>>16) * (bcr & 0xffff) * 4;
+ SPU2readDMA4Mem(madr&0x1fffff, bcr);
+ }
+
+ dma4_delay = 80;
+}
+
+static void ps2_dma7(uint32_t madr, uint32_t bcr, uint32_t chcr)
+{
+ if ((chcr == 0x01000201) || (chcr == 0x00100010) || (chcr == 0x000f0010) || (chcr == 0x00010010)) // cpu to SPU2
+ {
+ #if DEBUG_HLE_IOP
+ printf("DMA7: RAM %08x to SPU2\n", madr);
+ #endif
+ bcr = (bcr>>16) * (bcr & 0xffff) * 4;
+ SPU2writeDMA7Mem(madr&0x1fffff, bcr);
+ }
+ else
+ {
+ #if DEBUG_HLE_IOP
+ printf("DMA7: SPU2 to RAM %08x\n", madr);
+ #endif
+ bcr = (bcr>>16) * (bcr & 0xffff) * 4;
+// SPU2readDMA7Mem(madr&0x1fffff, bcr);
+ }
+
+ dma7_delay = 80;
+}
+
+void psx_hw_write(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ union cpuinfo mipsinfo;
+
+ if (offset >= 0x00000000 && offset <= 0x007fffff)
+ {
+ offset &= 0x1fffff;
+// if (offset < 0x10000) printf("Write %x to kernel @ %x\n", data, offset);
+
+ mips_get_info(CPUINFO_INT_PC, &mipsinfo);
+
+ psx_ram[offset>>2] &= LE32(mem_mask);
+ psx_ram[offset>>2] |= LE32(data);
+ return;
+ }
+
+ if (offset >= 0x80000000 && offset <= 0x807fffff)
+ {
+ offset &= 0x1fffff;
+// if (offset < 0x10000) printf("Write %x to kernel @ %x\n", data, offset);
+ mips_get_info(CPUINFO_INT_PC, &mipsinfo);
+ psx_ram[offset>>2] &= LE32(mem_mask);
+ psx_ram[offset>>2] |= LE32(data);
+ return;
+ }
+
+ if (offset == 0x1f801014 || offset == 0xbf801014)
+ {
+ spu_delay &= mem_mask;
+ spu_delay |= data;
+ return;
+ }
+
+ if (offset >= 0x1f801c00 && offset <= 0x1f801dff)
+ {
+ if (mem_mask == 0xffff0000)
+ {
+ SPUwriteRegister(offset, data);
+ return;
+ }
+ else if (mem_mask == 0x0000ffff)
+ {
+ SPUwriteRegister(offset, data>>16);
+ return;
+ }
+ else printf("SPU: write unknown mask %08x\n", mem_mask);
+ }
+
+ if (offset >= 0xbf900000 && offset <= 0xbf9007ff)
+ {
+ if (mem_mask == 0xffff0000)
+ {
+ SPU2write(offset, data);
+ return;
+ }
+ else if (mem_mask == 0x0000ffff)
+ {
+ SPU2write(offset, data>>16);
+ return;
+ }
+ else if (mem_mask == 0)
+ {
+ SPU2write(offset, data & 0xffff);
+ SPU2write(offset+2, data>>16);
+ return;
+ }
+ else printf("SPU2: write unknown mask %08x\n", mem_mask);
+ }
+
+ if (offset >= 0x1f801100 && offset <= 0x1f801128)
+ {
+ int cnt = (offset>>4) & 0xf;
+
+ switch (offset & 0xf)
+ {
+ case 0:
+ root_cnts[cnt].count = data;
+// printf("RC: counter %d count = %x\n", cnt, data);
+ break;
+ case 4:
+ root_cnts[cnt].mode = data;
+// printf("RC: counter %d mode = %x\n", cnt, data);
+ break;
+ case 8:
+ root_cnts[cnt].target = data;
+// printf("RC: counter %d target = %x\n", cnt, data);
+ break;
+ }
+
+ return;
+ }
+
+ // DMA4
+ if (offset == 0x1f8010c0)
+ {
+ dma4_madr = data;
+ return;
+ }
+ else if (offset == 0x1f8010c4)
+ {
+ dma4_bcr = data;
+ return;
+ }
+ else if (offset == 0x1f8010c8)
+ {
+ dma4_chcr = data;
+ psx_dma4(dma4_madr, dma4_bcr, dma4_chcr);
+
+ if (dma_icr & (1 << (16+4)))
+ {
+ dma_timer = 3;
+ }
+ return;
+ }
+ else if (offset == 0x1f8010f4)
+ {
+ dma_icr = ( dma_icr & mem_mask ) |
+ ( ~mem_mask & 0x80000000 & dma_icr) |
+ ( ~data & ~mem_mask & 0x7f000000 & dma_icr) |
+ ( data & ~mem_mask & 0x00ffffff);
+
+ if ((dma_icr & 0x7f000000) != 0)
+ {
+ dma_icr &= ~0x80000000;
+ }
+
+ return;
+ }
+ else if (offset == 0x1f801070)
+ {
+ irq_data = (irq_data & mem_mask) | (irq_data & irq_mask & data);
+ psx_irq_update();
+ return;
+ }
+ else if (offset == 0x1f801074)
+ {
+ irq_mask &= mem_mask;
+ irq_mask |= data;
+ psx_irq_update();
+ return;
+ }
+
+ // PS2 DMA4
+ if (offset == 0xbf8010c0)
+ {
+ dma4_madr = data;
+ return;
+ }
+ else if (offset == 0xbf8010c8)
+ {
+ dma4_chcr = data;
+ ps2_dma4(dma4_madr, dma4_bcr, dma4_chcr);
+
+ if (dma_icr & (1 << (16+4)))
+ {
+ dma_timer = 3;
+ }
+ return;
+ }
+
+ if (offset == 0xbf8010c4 || offset == 0xbf8010c6)
+ {
+ dma4_bcr &= mem_mask;
+ dma4_bcr |= data;
+ return;
+ }
+
+ // PS2 DMA7
+ if (offset == 0xbf801500)
+ {
+ dma7_madr = data;
+ return;
+ }
+ else if (offset == 0xbf801504)
+ {
+ dma7_chcr = data;
+ ps2_dma7(dma7_madr, dma7_bcr, dma7_chcr);
+ return;
+ }
+
+ if (offset == 0xbf801508 || offset == 0xbf80150a)
+ {
+ dma7_bcr &= mem_mask;
+ dma7_bcr |= data;
+ return;
+ }
+
+ #if DEBUG_UNK_RW
+ {
+ union cpuinfo mipsinfo;
+
+ mips_get_info(CPUINFO_INT_PC, &mipsinfo);
+ printf("Unknown write: %08x to %08x, mask %08x (PC=%x)\n", data, offset&~3, mem_mask, mipsinfo.i);
+ }
+ #endif
+}
+
+// called per sample, 1/44100th of a second (768 clock cycles)
+void psx_hw_slice(void)
+{
+ psx_hw_runcounters();
+
+ if (!WAI)
+ mips_execute(768/CLOCK_DIV);
+
+ if (dma_timer)
+ {
+ dma_timer--;
+ if (dma_timer == 0)
+ {
+ dma_icr |= (1 << (24+4));
+ psx_irq_set(0x0008);
+ }
+ }
+}
+
+void ps2_hw_slice(void)
+{
+ int i = 0;
+
+ timerexp = 0;
+ psx_hw_runcounters();
+
+ if (iCurThread != -1)
+ {
+ mips_execute(836/CLOCK_DIV);
+ }
+ else // no thread, don't run CPU, just update counters
+ {
+ if (timerexp)
+ {
+ ps2_reschedule();
+
+ if (iCurThread != -1)
+ {
+ mips_execute((836/CLOCK_DIV)-i);
+ i = (836/CLOCK_DIV);
+ }
+ }
+ }
+}
+
+static int fcnt = 0;
+
+void psx_hw_frame(void)
+{
+ if (psf_refresh == 50)
+ {
+ fcnt++;;
+
+ if (fcnt < 6)
+ {
+ psx_irq_set(1);
+ }
+ else
+ {
+ fcnt = 0;
+ }
+ }
+ else // NTSC
+ {
+ psx_irq_set(1);
+ }
+}
+
+void ps2_hw_frame(void)
+{
+ ps2_reschedule();
+}
+
+// BIOS HLE
+
+// heap block struct offsets
+enum
+{
+ BLK_STAT = 0,
+ BLK_SIZE = 4,
+ BLK_FD = 8,
+ BLK_BK = 12
+};
+
+static uint32_t heap_addr, entry_int = 0;
+
+extern uint32_t mips_get_cause(void);
+extern uint32_t mips_get_status(void);
+extern void mips_set_status(uint32_t status);
+extern uint32_t mips_get_ePC(void);
+
+static uint32_t irq_regs[37];
+
+static int irq_mutex = 0;
+
+static void call_irq_routine(uint32_t routine, uint32_t parameter)
+{
+ int j, oldICount;
+ union cpuinfo mipsinfo;
+
+ if (!irq_mutex)
+ {
+ irq_mutex = 1;
+ }
+ else
+ {
+ printf("IOP: ERROR! IRQ reentry!\n");
+ return;
+ }
+
+ // save regs for IRQ
+ for (j = 0; j < 32; j++)
+ {
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R0 + j, &mipsinfo);
+ irq_regs[j] = mipsinfo.i;
+ }
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
+ irq_regs[32] = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
+ irq_regs[33] = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_PC, &mipsinfo);
+ irq_regs[34] = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_DELAYV, &mipsinfo);
+ irq_regs[35] = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_DELAYR, &mipsinfo);
+ irq_regs[36] = mipsinfo.i;
+
+ // PC = timer handler routine
+ mipsinfo.i = routine;
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+
+ // parameter in a0
+ mipsinfo.i = parameter;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
+
+ // RA = a trap address we can set
+ mipsinfo.i = 0x80001000;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+
+ // make sure we're set
+ psx_ram[0x1000/4] = LE32(FUNCT_HLECALL);
+
+ softcall_target = 0;
+ oldICount = mips_get_icount();
+ while (!softcall_target)
+ {
+ mips_execute(10);
+ }
+ mips_set_icount(oldICount);
+
+ // restore IRQ regs
+ for (j = 0; j < 32; j++)
+ {
+ mipsinfo.i = irq_regs[j];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R0 + j, &mipsinfo);
+ }
+
+ mipsinfo.i = irq_regs[32];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
+ mipsinfo.i = irq_regs[33];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
+ mipsinfo.i = irq_regs[34];
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+ mipsinfo.i = irq_regs[35];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_DELAYV, &mipsinfo);
+ mipsinfo.i = irq_regs[36];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_DELAYR, &mipsinfo);
+
+ irq_mutex = 0;
+}
+
+void psx_bios_exception(uint32_t pc)
+{
+ uint32_t a0, status;
+ union cpuinfo mipsinfo;
+ int i, oldICount;
+
+// printf("bios_exception: cause %x\n", mips_get_cause() & 0x3c);
+
+ // get a0
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
+ a0 = mipsinfo.i;
+
+ switch (mips_get_cause() & 0x3c)
+ {
+ case 0: // IRQ
+// printf("IRQ: %x, mask %x\n", irq_data, irq_mask);
+ // save all regs
+ for (i = 0; i < 32; i++)
+ {
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R0 + i, &mipsinfo);
+ irq_regs[i] = mipsinfo.i;
+ }
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
+ irq_regs[32] = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
+ irq_regs[33] = mipsinfo.i;
+
+ // check BIOS-driven interrupts
+ if (irq_data & 1) // VSync
+ {
+ if (CounterEvent[3][1].status == LE32(EvStACTIVE))
+ {
+ // run the handler
+ mipsinfo.i = LE32(CounterEvent[3][1].fhandler);
+// printf("Cause = %x, ePC = %x\n", mips_get_cause(), mips_get_ePC());
+// printf("VBL running handler @ %x\n", mipsinfo.i);
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+ mipsinfo.i = 0x80001000;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+
+ // make sure we're set
+ psx_ram[0x1000/4] = LE32(FUNCT_HLECALL);
+
+ softcall_target = 0;
+ oldICount = mips_get_icount();
+ while (!softcall_target)
+ {
+ mips_execute(10);
+ }
+ mips_set_icount(oldICount);
+
+// printf("Exiting softcall handler\n");
+
+ irq_data &= ~1; // clear the VBL IRQ if we handled it
+ }
+ }
+ else if (irq_data & 0x70) // root counters
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if (irq_data & (1 << (i+4)))
+ {
+ if (CounterEvent[i][1].status == LE32(EvStACTIVE))
+ {
+ // run the handler
+ mipsinfo.i = LE32(CounterEvent[i][1].fhandler);
+// printf("Cause = %x, ePC = %x\n", mips_get_cause(), mips_get_ePC());
+// printf("Counter %d running handler @ %x\n", i, mipsinfo.i);
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+ mipsinfo.i = 0x80001000;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+
+ // make sure we're set
+ psx_ram[0x1000/4] = LE32(FUNCT_HLECALL);
+
+ softcall_target = 0;
+ oldICount = mips_get_icount();
+ while (!softcall_target)
+ {
+ mips_execute(10);
+ }
+ mips_set_icount(oldICount);
+
+// printf("Exiting softcall handler\n");
+ irq_data &= ~(1 << (i+4));
+ }
+ else
+ {
+// printf("CEvt %d not active\n", i);
+ }
+ }
+ }
+ }
+
+ if (entry_int)
+ {
+ psx_hw_write(0x1f801070, 0xffffffff, 0);
+
+ a0 = entry_int;
+
+// printf("taking entry_int\n");
+
+ // RA (and PC)
+ mipsinfo.i = LE32(psx_ram[((a0&0x1fffff)+0)/4]);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+ // SP
+ mipsinfo.i = LE32(psx_ram[((a0&0x1fffff)+4)/4]);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R29, &mipsinfo);
+ // FP
+ mipsinfo.i = LE32(psx_ram[((a0&0x1fffff)+8)/4]);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R30, &mipsinfo);
+
+ // S0-S7 are next
+ for (i = 0; i < 8; i++)
+ {
+ mipsinfo.i = LE32(psx_ram[((a0&0x1fffff)+12+(i*4))/4]);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R16 + i, &mipsinfo);
+ }
+
+ // GP
+ mipsinfo.i = LE32(psx_ram[((a0&0x1fffff)+44)/4]);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R28, &mipsinfo);
+
+ // v0 = 1
+ mipsinfo.i = 1;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ else
+ {
+ psx_hw_write(0x1f801070, 0, 0xffff0000);
+
+ // note: the entry_int won't be bailing us out here, so do it ourselves
+ for (i = 0; i < 32; i++)
+ {
+ mipsinfo.i = irq_regs[i];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R0 + i, &mipsinfo);
+ }
+
+ mipsinfo.i = irq_regs[32];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
+ mipsinfo.i = irq_regs[33];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
+ mipsinfo.i = mips_get_ePC();
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+
+ status = mips_get_status();
+ status = (status & 0xfffffff0) | ((status & 0x3c)>>2);
+ mips_set_status(status);
+ }
+ break;
+
+ case 0x20: // syscall
+ // syscall always farks with the status, so get it now
+ status = mips_get_status();
+
+ switch (a0)
+ {
+ case 1: // EnterCritical
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: EnterCritical\n");
+ #endif
+ status &= ~0x0404;
+ break;
+
+ case 2: // ExitCritical
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: ExitCritical\n");
+ #endif
+ status |= 0x0404;
+ break;
+
+ default:
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: Unknown syscall %x\n", a0);
+ #endif
+ break;
+ }
+
+ // PC = ePC + 4
+ mipsinfo.i = mips_get_ePC() + 4;
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+
+ // and update the status accordingly
+ status = (status & 0xfffffff0) | ((status & 0x3c)>>2);
+ mips_set_status(status);
+ break;
+
+ default:
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: Unknown exception %x\n", mips_get_cause());
+ #endif
+ break;
+ }
+}
+
+static uint32_t calc_ev(uint32_t a0)
+{
+ uint32_t ev;
+
+ ev = (a0 >> 24) & 0xf;
+ if (ev == 0xf)
+ {
+ ev = 0x5;
+ }
+ ev *= 32;
+ ev += (a0 & 0x1f);
+
+ return ev;
+}
+
+static uint32_t calc_spec(uint32_t a1)
+{
+ uint32_t spec = 0;
+ int i;
+
+ if (a1 == 0x301)
+ {
+ spec = 16;
+ }
+ else if (a1 == 0x302)
+ {
+ spec = 17;
+ }
+ else
+ {
+ for (i = 0; i < 16; i++)
+ {
+ if (a1 & (1<<i))
+ {
+ spec = i;
+ break;
+ }
+ }
+ }
+
+ return spec;
+}
+
+void psx_hw_init(void)
+{
+ timerexp = 0;
+
+ memset(filestat, 0, sizeof(filestat));
+ memset(filedata, 0, sizeof(filedata));
+
+ dma4_cb = dma7_cb = 0;
+
+ sys_time = 0;
+
+ // clear registered libraries table
+ memset(reglibs, 0, sizeof(reglibs));
+ iNumLibs = 0;
+
+ memset(evflags, 0, sizeof(evflags));
+ iNumFlags = 0;
+
+ memset(threads, 0, sizeof(threads));
+ iNumThreads = 1; // we always have at least one thread
+
+ memset(semaphores, 0, sizeof(semaphores));
+ iNumSema = 0;
+
+ // set the initial thread to "RUNNING"
+ threads[0].iState = TS_RUNNING;
+ iCurThread = 0;
+
+ memset(iop_timers, 0, sizeof(iop_timers));
+ iNumTimers = 0;
+
+ // set PS1 BIOS HLE breakpoints
+ psx_ram[0xa0/4] = LE32(FUNCT_HLECALL);
+ psx_ram[0xb0/4] = LE32(FUNCT_HLECALL);
+ psx_ram[0xc0/4] = LE32(FUNCT_HLECALL);
+
+ Event = (EvtCtrlBlk *)&psx_ram[0x1000/4];
+ CounterEvent = (Event + (32*2));
+
+ dma_icr = 0;
+ spu_delay = 0;
+ irq_data = 0;
+ irq_mask = 0;
+ softcall_target = 0;
+ gpu_stat = 0;
+ dma4_madr = dma4_bcr = dma4_chcr = 0;
+ heap_addr = 0;
+ entry_int = 0;
+
+ WAI = 0;
+
+ root_cnts[0].mode = RC_EN;
+ root_cnts[1].mode = RC_EN;
+ root_cnts[2].mode = RC_EN;
+ root_cnts[0].sysclock = 0;
+ root_cnts[1].sysclock = 0;
+ root_cnts[2].sysclock = 0;
+
+ root_cnts[3].mode = (RC_RESET | RC_IQ1 | RC_IQ2);
+ root_cnts[3].sysclock = 0;
+ root_cnts[3].target = 1;
+ root_cnts[3].interrupt = 1;
+}
+
+void psx_bios_hle(uint32_t pc)
+{
+ uint32_t subcall, status;
+ union cpuinfo mipsinfo;
+ uint32_t a0, a1, a2, a3;
+ int i;
+
+ if ((pc == 0) || (pc == 0x80000000)) // IOP "null" state
+ {
+ #if DEBUG_HLE_IOP
+ printf("IOP 'null' state\n");
+ #endif
+// ao_song_done = 1;
+ return;
+ }
+
+ if (pc == 0xbfc00180 || pc == 0xbfc00184) // exception, not BIOS call
+ {
+ psx_bios_exception(pc);
+ return;
+ }
+
+ if (pc == 0x80001000)
+ {
+// printf("hit softcall target\n");
+ softcall_target = 1;
+ return;
+ }
+
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R9, &mipsinfo);
+
+ subcall = mipsinfo.i & 0xff;
+
+ // most calls have a0/a1 as parameters, so prefetch them
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
+ a0 = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R5, &mipsinfo);
+ a1 = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R6, &mipsinfo);
+ a2 = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R7, &mipsinfo);
+ a3 = mipsinfo.i;
+
+// mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+// printf("HLEBIOS: return is %08x\n", mipsinfo.i);
+
+ switch (pc)
+ {
+ case 0xa0: // a0 syscalls
+ switch (subcall)
+ {
+ case 0x13: // setjmp
+ // RA
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ psx_ram[((a0&0x1fffff)+0)/4] = LE32(mipsinfo.i);
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: setjmp(%08x) => PC %08x\n", a0, mipsinfo.i);
+ #endif
+ // SP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R29, &mipsinfo);
+ psx_ram[((a0&0x1fffff)+4)/4] = LE32(mipsinfo.i);
+ // FP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R30, &mipsinfo);
+ psx_ram[((a0&0x1fffff)+8)/4] = LE32(mipsinfo.i);
+
+ // S0-S7 are next
+ for (i = 0; i < 8; i++)
+ {
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R16 + i, &mipsinfo);
+ psx_ram[((a0&0x1fffff)+12+(i*4))/4] = LE32(mipsinfo.i);
+ }
+
+ // GP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R28, &mipsinfo);
+ psx_ram[((a0&0x1fffff)+44)/4] = LE32(mipsinfo.i);
+
+ // v0 = 0
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 0x18: // strncmp
+ {
+ uint8_t *dst, *src;
+
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: strncmp(%08x, %08x, %d)\n", a0, a1, a2);
+ #endif
+
+ dst = (uint8_t *)psx_ram;
+ src = (uint8_t *)psx_ram;
+ dst += (a0 & 0x1fffff);
+ src += (a1 & 0x1fffff);
+
+ // v0 = result
+ mipsinfo.i = strncmp((char *)dst, (char *)src, a2);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 0x19: // strcpy
+ {
+ uint8_t *dst, *src;
+
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: strcpy(%08x, %08x)\n", a0, a1);
+ #endif
+
+ dst = (uint8_t *)psx_ram;
+ src = (uint8_t *)psx_ram;
+ dst += (a0 & 0x1fffff);
+ src += (a1 & 0x1fffff);
+
+ while (*src)
+ {
+ *dst = *src;
+ dst++;
+ src++;
+ }
+
+ // v0 = a0
+ mipsinfo.i = a0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 0x28: // bzero
+ {
+ uint8_t *dst;
+
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: bzero(%08x, %08x)\n", a0, a1);
+ #endif
+
+ dst = (uint8_t *)psx_ram;
+ dst += (a0 & 0x1fffff);
+ memset(dst, 0, a1);
+ }
+ break;
+
+ case 0x2a: // memcpy
+ {
+ uint8_t *dst, *src;
+
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: memcpy(%08x, %08x, %08x)\n", a0, a1, a2);
+ #endif
+
+ dst = (uint8_t *)psx_ram;
+ src = (uint8_t *)psx_ram;
+ dst += (a0 & 0x1fffff);
+ src += (a1 & 0x1fffff);
+
+ while (a2)
+ {
+ *dst = *src;
+ dst++;
+ src++;
+ a2--;
+ }
+
+ // v0 = a0
+ mipsinfo.i = a0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 0x2b: // memset
+ {
+ uint8_t *dst;
+
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: memset(%08x, %08x, %08x)\n", a0, a1, a2);
+ #endif
+
+ dst = (uint8_t *)psx_ram;
+ dst += (a0 & 0x1fffff);
+
+ while (a2)
+ {
+ *dst = a1;
+ dst++;
+ a2--;
+ }
+
+ // v0 = a0
+ mipsinfo.i = a0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 0x2f: // rand
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: rand\n");
+ #endif
+
+ // v0 = result
+ mipsinfo.i = 1 + (int)(32767.0*rand()/(RAND_MAX+1.0));
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 0x30: // srand
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: srand(%x)\n", a0);
+ #endif
+ srand(a0);
+ break;
+
+ case 0x33: // malloc
+ {
+ uint32_t chunk, fd;
+
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: malloc(%x)\n", a0);
+ #endif
+
+ chunk = heap_addr;
+
+ // find a free block that's big enough
+ while ((a0 > LE32(psx_ram[(chunk+BLK_SIZE)/4])) ||
+ (LE32(psx_ram[(chunk+BLK_STAT)/4]) == 1))
+ {
+ chunk = LE32(psx_ram[(chunk+BLK_FD)]);
+ }
+
+ // split free block
+ fd = chunk + 16 + a0; // free block starts after block record and allocation size
+ psx_ram[(fd+BLK_STAT)/4] = psx_ram[(chunk+BLK_STAT)/4];
+ psx_ram[(fd+BLK_SIZE)/4] = LE32(LE32(psx_ram[(chunk+BLK_SIZE)/4]) - a0);
+ psx_ram[(fd+BLK_FD)/4] = psx_ram[(chunk+BLK_FD)/4];
+ psx_ram[(fd+BLK_BK)/4] = chunk;
+
+ psx_ram[(chunk+BLK_STAT)/4] = LE32(1);
+ psx_ram[(chunk+BLK_SIZE)/4] = LE32(a0);
+ psx_ram[(chunk+BLK_FD)/4] = LE32(fd);
+
+ mipsinfo.i = chunk + 16;
+ mipsinfo.i |= 0x80000000;
+ #if DEBUG_HLE_BIOS
+ printf("== %08x\n", mipsinfo.i);
+ #endif
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 0x39: // InitHeap
+ // heap address in A0, length in A1
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: InitHeap(%08x, %08x)\n", a0, a1);
+ #endif
+
+ heap_addr = a0 & 0x3fffffff;
+
+ psx_ram[(heap_addr+BLK_STAT)/4] = LE32(0);
+ psx_ram[(heap_addr+BLK_FD)/4] = LE32(0);
+ psx_ram[(heap_addr+BLK_BK)/4] = LE32(0);
+
+ // if heap size out of range, clamp it
+ if (((a0 & 0x1fffff) + a1) >= 2*1024*1024)
+ {
+ psx_ram[(heap_addr+BLK_SIZE)/4] = LE32(0x1ffffc - (a0 & 0x1fffff));
+ }
+ else
+ {
+ psx_ram[(heap_addr+BLK_SIZE)/4] = LE32(a1);
+ }
+ break;
+
+ case 0x3f: // printf
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: printf(%08x) = %s\n", a0, &psx_ram[(a0&0x1fffff)/4]);
+ #endif
+ break;
+
+ case 0x72: //__96_remove
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: __96_remove\n");
+ #endif
+ break;
+
+ default:
+ #if DEBUG_HLE_BIOS
+ printf("Unknown BIOS A0 call = %x\n", subcall);
+ #endif
+ break;
+ }
+ break;
+
+ case 0xb0: // b0 syscalls
+ switch (subcall)
+ {
+ case 0x07: // DeliverEvent
+ {
+ int ev, spec;
+
+
+ ev = calc_ev(a0);
+ spec = calc_spec(a1);
+
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: DeliverEvent(ev %d, spec %d)\n", ev, spec);
+ #endif
+
+ if (Event[ev][spec].status != LE32(EvStACTIVE))
+ {
+ #if DEBUG_HLE_BIOS
+ printf("event not active\n");
+ #endif
+ return;
+ }
+
+ // if interrupt mode, do the call
+ if (Event[ev][spec].mode == LE32(EvMdINTR))
+ {
+ #if DEBUG_HLE_BIOS
+ printf("INTR type, need to call handler %x\n", LE32(Event[ev][spec].fhandler));
+ #endif
+ }
+ else
+ {
+ Event[ev][spec].status = LE32(EvStALREADY);
+ }
+ }
+ break;
+
+ case 0x08: // OpenEvent
+ {
+ int ev, spec;
+
+ ev = calc_ev(a0);
+ spec = calc_spec(a1);
+
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: OpenEvent(%08x, %08x, %08x, %08x) = ev %d spec %d\n", a0, a1, a2, a3, ev, spec);
+ if (ev >= 64 && ev <= 68)
+ {
+ printf("HLEBIOS: event %d maps to root counter %d\n", ev, ev-64);
+ }
+ #endif
+
+ Event[ev][spec].status = LE32(EvStWAIT);
+ Event[ev][spec].mode = LE32(a2);
+ Event[ev][spec].fhandler = LE32(a3);
+
+ // v0 = ev | spec<<8;
+ mipsinfo.i = ev | (spec<<8);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 0x0a: // WaitEvent
+ {
+ int ev, spec;
+
+ ev = a0 & 0xff;
+ spec = (a0 >> 8) & 0xff;
+
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: WaitEvent(ev %d spec %d) PC=%x\n", ev, spec, mipsinfo.i);
+ #endif
+
+ Event[ev][spec].status = LE32(EvStACTIVE);
+
+ // v0 = 1
+ mipsinfo.i = 1;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+
+ WAI = 1;
+ mips_shorten_frame();
+ }
+ break;
+
+ case 0x0b: // TestEvent
+ {
+ int ev, spec;
+
+ ev = a0 & 0xff;
+ spec = (a0 >> 8) & 0xff;
+
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: TestEvent(ev %d spec %d)\n", ev, spec);
+ #endif
+
+ // v0 = (is event ready?)
+ if (Event[ev][spec].status == LE32(EvStALREADY))
+ {
+ Event[ev][spec].status = LE32(EvStACTIVE);
+ mipsinfo.i = 1;
+ }
+ else
+ {
+ mipsinfo.i = 0;
+ }
+
+ WAI = 1;
+
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+
+ // it looks like this sets v1 to something non-zero too
+ // (code in Crash 2 & 3 actually relies on that behavior)
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R3, &mipsinfo);
+ }
+ break;
+
+ case 0x0c: // EnableEvent
+ {
+ int ev, spec;
+
+ ev = a0 & 0xff;
+ spec = (a0 >> 8) & 0xff;
+
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: EnableEvent(ev %d spec %d)\n", ev, spec);
+ #endif
+
+ Event[ev][spec].status = LE32(EvStACTIVE);
+
+ // v0 = 1
+ mipsinfo.i = 1;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 0x0d: // DisableEvent
+ {
+ int ev, spec;
+
+ ev = a0 & 0xff;
+ spec = (a0 >> 8) & 0xff;
+
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: DisableEvent(ev %d spec %d)\n", ev, spec);
+ #endif
+
+ Event[ev][spec].status = LE32(EvStWAIT);
+
+ // v0 = 1
+ mipsinfo.i = 1;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 0x17: // ReturnFromException
+ for (i = 0; i < 32; i++)
+ {
+ mipsinfo.i = irq_regs[i];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R0 + i, &mipsinfo);
+ }
+
+ mipsinfo.i = irq_regs[32];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_HI, &mipsinfo);
+ mipsinfo.i = irq_regs[33];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_LO, &mipsinfo);
+ mipsinfo.i = mips_get_ePC();
+// printf("ReturnFromException: IRQ state %x\n", irq_data & irq_mask);
+// printf("HLEBIOS: ReturnFromException, cause = %08x, PC = %08x\n", mips_get_cause(), mipsinfo.i);
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+
+ status = mips_get_status();
+ status = (status & 0xfffffff0) | ((status & 0x3c)>>2);
+ mips_set_status(status);
+ return; // force return to avoid PC=RA below
+ break;
+
+ case 0x19: // HookEntryInt
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: HookEntryInt(%08x)\n", a0);
+ #endif
+ entry_int = a0;
+ break;
+
+ case 0x3f: // puts
+// printf("HLEBIOS: puts\n");
+ break;
+
+ case 0x5b: // ChangeClearPAD
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: ChangeClearPAD\n");
+ #endif
+ break;
+
+ default:
+ #if DEBUG_HLE_BIOS
+ printf("Unknown BIOS B0 call = %x\n", subcall);
+ #endif
+ break;
+ }
+ break;
+
+ case 0xc0: // c0 syscalls
+ switch (subcall)
+ {
+ case 0xa: // ChangeClearRCnt
+ #if DEBUG_HLE_BIOS
+ printf("HLEBIOS: ChangeClearRCnt(%08x, %08x)\n", a0, a1);
+ #endif
+
+ // v0 = (a0*4)+0x8600
+ mipsinfo.i = LE32(psx_ram[((a0<<2) + 0x8600)/4]);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+
+ // (a0*4)+0x8600 = a1;
+ psx_ram[((a0<<2) + 0x8600)/4] = LE32(a1);
+ break;
+
+ default:
+ #if DEBUG_HLE_BIOS
+ printf("Unknown BIOS C0 call = %x\n", subcall);
+ #endif
+ break;
+ }
+ break;
+ }
+
+ // PC = RA
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+}
+
+// root counters
+
+void psx_hw_runcounters(void)
+{
+ int i;
+
+ // don't process any IRQ sources when interrupts are suspended
+ if (!intr_susp)
+ {
+ if (dma4_delay)
+ {
+ dma4_delay--;
+
+ if (dma4_delay == 0)
+ {
+ SPU2interruptDMA4();
+
+ if (dma4_cb)
+ {
+ call_irq_routine(dma4_cb, dma4_flag);
+ }
+ }
+ }
+
+ if (dma7_delay)
+ {
+ dma7_delay--;
+
+ if (dma7_delay == 0)
+ {
+ SPU2interruptDMA7();
+
+ if (dma7_cb)
+ {
+ call_irq_routine(dma7_cb, dma7_flag);
+ }
+ }
+ }
+
+ for (i = 0; i < iNumThreads; i++)
+ {
+ if (threads[i].iState == TS_WAITDELAY)
+ {
+ if (threads[i].waitparm > CLOCK_DIV)
+ {
+ threads[i].waitparm -= CLOCK_DIV;
+ }
+ else // time's up
+ {
+ threads[i].waitparm = 0;
+ threads[i].iState = TS_READY;
+
+ timerexp = 1;
+
+ ps2_reschedule();
+ }
+ }
+ }
+
+ sys_time += 836;
+
+ if (iNumTimers > 0)
+ {
+ for (i = 0; i < iNumTimers; i++)
+ {
+ if (iop_timers[i].iActive > 0)
+ {
+ iop_timers[i].count += 836;
+ if (iop_timers[i].count >= iop_timers[i].target)
+ {
+ iop_timers[i].count -= iop_timers[i].target;
+
+ // printf("Timer %d: handler = %08x, param = %08x\n", i, iop_timers[i].handler, iop_timers[i].hparam);
+ call_irq_routine(iop_timers[i].handler, iop_timers[i].hparam);
+
+ timerexp = 1;
+ }
+ }
+ }
+ }
+ }
+
+// PS1 root counters
+ for (i = 0; i < 4; i++)
+ {
+ if ((!(root_cnts[i].mode & RC_EN)) && (root_cnts[i].mode != 0))
+ {
+ if (root_cnts[i].mode & RC_DIV8)
+ {
+ root_cnts[i].count += 768/8;
+ }
+ else
+ {
+ root_cnts[i].count += 768;
+ }
+
+ if (root_cnts[i].count >= root_cnts[i].target)
+ {
+ if (!(root_cnts[i].mode & RC_RESET))
+ {
+ root_cnts[i].mode |= RC_EN;
+ }
+ else
+ {
+ root_cnts[i].count %= root_cnts[i].target;
+ }
+
+ psx_irq_set(1<<(4+i));
+ }
+ }
+ }
+}
+
+// PEOpS callbacks
+
+void SPUirq(void)
+{
+// psx_irq_set(0x200);
+}
+
+// PSXCPU callbacks
+
+uint8_t program_read_byte_32le(offs_t address)
+{
+ switch (address & 0x3)
+ {
+ case 0:
+ return psx_hw_read(address, 0xffffff00);
+ break;
+ case 1:
+ return psx_hw_read(address, 0xffff00ff)>>8;
+ break;
+ case 2:
+ return psx_hw_read(address, 0xff00ffff)>>16;
+ break;
+ case 3:
+ return psx_hw_read(address, 0x00ffffff)>>24;
+ break;
+ }
+
+ return psx_hw_read(address, 0xffffff00);
+}
+
+uint16_t program_read_word_32le(offs_t address)
+{
+ if (address & 2)
+ return psx_hw_read(address, 0x0000ffff)>>16;
+
+ return psx_hw_read(address, 0xffff0000);
+}
+
+uint32_t program_read_dword_32le(offs_t address)
+{
+ return psx_hw_read(address, 0);
+}
+
+void program_write_byte_32le(offs_t address, uint8_t data)
+{
+ switch (address & 0x3)
+ {
+ case 0:
+ psx_hw_write(address, data, 0xffffff00);
+ break;
+ case 1:
+ psx_hw_write(address, data<<8, 0xffff00ff);
+ break;
+ case 2:
+ psx_hw_write(address, data<<16, 0xff00ffff);
+ break;
+ case 3:
+ psx_hw_write(address, data<<24, 0x00ffffff);
+ break;
+ }
+}
+
+void program_write_word_32le(offs_t address, uint16_t data)
+{
+ if (address & 2)
+ {
+ psx_hw_write(address, data<<16, 0x0000ffff);
+ return;
+ }
+
+ psx_hw_write(address, data, 0xffff0000);
+}
+
+void program_write_dword_32le(offs_t address, uint32_t data)
+{
+ psx_hw_write(address, data, 0);
+}
+
+// sprintf replacement
+static void iop_sprintf(char *out, char *fmt, uint32_t pstart)
+{
+ char temp[64], tfmt[64];
+ char *cf, *pstr;
+ union cpuinfo mipsinfo;
+ int curparm, fp, isnum;
+
+ curparm = pstart;
+ cf = fmt;
+
+ while (*cf != '\0')
+ {
+ if (*cf != '%')
+ {
+ if (*cf == 27)
+ {
+ *out++ = '[';
+ *out++ = 'E';
+ *out++ = 'S';
+ *out++ = 'C';
+ *out = ']';
+ }
+ else
+ {
+ *out = *cf;
+ }
+ out++;
+ cf++;
+ }
+ else // got format
+ {
+ cf++;
+
+ tfmt[0] = '%';
+ fp = 1;
+ while (((*cf >= '0') && (*cf <= '9')) || (*cf == '.'))
+ {
+ tfmt[fp] = *cf;
+ fp++;
+ cf++;
+ }
+
+ tfmt[fp] = *cf;
+ tfmt[fp+1] = '\0';
+
+ isnum = 0;
+ switch (*cf)
+ {
+ case 'x':
+ case 'X':
+ case 'd':
+ case 'D':
+ case 'c':
+ case 'C':
+ case 'u':
+ case 'U':
+ isnum = 1;
+ break;
+ }
+
+// printf("]]] temp format: [%s] [%d]\n", tfmt, isnum);
+
+ if (isnum)
+ {
+ mips_get_info(curparm, &mipsinfo);
+// printf("parameter %d = %x\n", curparm-pstart, mipsinfo.i);
+ curparm++;
+ sprintf(temp, tfmt, (int32_t)mipsinfo.i);
+ }
+ else
+ {
+ mips_get_info(curparm, &mipsinfo);
+ curparm++;
+
+ pstr = (char *)psx_ram;
+ pstr += (mipsinfo.i & 0x1fffff);
+
+ sprintf(temp, tfmt, pstr);
+ }
+
+ pstr = &temp[0];
+ while (*pstr != '\0')
+ {
+ *out = *pstr;
+ out++;
+ pstr++;
+ }
+
+ cf++;
+ }
+ }
+
+ *out = '\0';
+}
+
+// PS2 IOP callbacks
+void psx_iop_call(uint32_t pc, uint32_t callnum)
+{
+ uint32_t scan;
+ char *mname, *str1, name[9], out[512];
+ uint32_t a0, a1, a2, a3;
+ union cpuinfo mipsinfo;
+ int i;
+
+// printf("IOP call @ %08x\n", pc);
+
+ // prefetch parameters
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
+ a0 = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R5, &mipsinfo);
+ a1 = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R6, &mipsinfo);
+ a2 = mipsinfo.i;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R7, &mipsinfo);
+ a3 = mipsinfo.i;
+
+ scan = (pc&0x0fffffff)/4;
+ while ((psx_ram[scan] != LE32(0x41e00000)) && (scan >= (0x10000/4)))
+ {
+ scan--;
+ }
+
+ if (psx_ram[scan] != LE32(0x41e00000))
+ {
+ printf("FATAL ERROR: couldn't find IOP link signature\n");
+ return;
+ }
+
+ scan += 3; // skip zero and version
+ memcpy(name, &psx_ram[scan], 8);
+ name[8] = '\0';
+
+// printf("IOP: call module [%s] service %d (PC=%08x)\n", name, callnum, pc);
+
+ if (!strcmp(name, "stdio"))
+ {
+ switch (callnum)
+ {
+ case 4: // printf
+ mname = (char *)psx_ram;
+ mname += a0 & 0x1fffff;
+ mname += (a0 & 3);
+
+ iop_sprintf(out, mname, CPUINFO_INT_REGISTER + MIPS_R5); // a1 is first parm
+
+ /* if (out[strlen(out)-1] != '\n')
+ {
+ strcat(out, "\n");
+ }*/
+
+ #if DEBUG_HLE_IOP
+ printf("%s", out);
+ #endif
+ break;
+
+ default:
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ break;
+ }
+ }
+ else if (!strcmp(name, "sifman"))
+ {
+ switch (callnum)
+ {
+ case 5: // sceSifInit
+ #if DEBUG_HLE_IOP
+ printf("IOP: sceSifInit()\n");
+ #endif
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 7: // sceSifSetDma
+ #if DEBUG_HLE_IOP
+ printf("IOP: sceSifSetDma(%08x %08x)\n", a0, a1);
+ #endif
+
+ mipsinfo.i = 1; // nonzero = success
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 8: // sceSifDmaStat
+ #if DEBUG_HLE_IOP
+ printf("IOP: sceSifDmaStat(%08x)\n", a0);
+ #endif
+
+ mipsinfo.i = -1; // dma completed
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 29: // sceSifCheckInit
+ #if DEBUG_HLE_IOP
+ printf("IOP: sceSifCheckInit()\n");
+ #endif
+
+ mipsinfo.i = 1;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ default:
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ break;
+ }
+ }
+ else if (!strcmp(name, "thbase"))
+ {
+ uint32_t newAlloc;
+
+ switch (callnum)
+ {
+ case 4: // CreateThread
+ #if DEBUG_THREADING
+ printf("IOP: CreateThread(%08x)\n", a0);
+ #endif
+ a0 &= 0x1fffff;
+ a0 /= 4;
+ #if DEBUG_THREADING
+ printf(" : flags %x routine %08x pri %x stacksize %d refCon %08x\n",
+ psx_ram[a0], psx_ram[a0+1], psx_ram[a0+2], psx_ram[a0+3], psx_ram[a0+4]);
+ #endif
+
+ newAlloc = psf2_get_loadaddr();
+ // force 16-byte alignment
+ if (newAlloc & 0xf)
+ {
+ newAlloc &= ~0xf;
+ newAlloc += 16;
+ }
+ psf2_set_loadaddr(newAlloc + LE32(psx_ram[a0+3]));
+
+ threads[iNumThreads].iState = TS_CREATED;
+ threads[iNumThreads].stackloc = newAlloc;
+ threads[iNumThreads].flags = LE32(psx_ram[a0]);
+ threads[iNumThreads].routine = LE32(psx_ram[a0+2]);
+ threads[iNumThreads].stacksize = LE32(psx_ram[a0+3]);
+ threads[iNumThreads].refCon = LE32(psx_ram[a0+4]);
+
+ mipsinfo.i = iNumThreads;
+ iNumThreads++;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 6: // StartThread
+ #if DEBUG_THREADING
+ printf("IOP: StartThread(%d %d)\n", a0, a1);
+ #endif
+
+ FreezeThread(iCurThread, 1);
+ ThawThread(a0);
+ iCurThread = a0;
+ break;
+
+ case 20:// GetThreadID
+ #if DEBUG_THREADING
+ printf("IOP: GetThreadId()\n");
+ #endif
+
+ mipsinfo.i = iCurThread;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 24:// SleepThread
+ #if DEBUG_THREADING
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ printf("IOP: SleepThread() [curThread %d, PC=%x]\n", iCurThread, mipsinfo.i);
+ #endif
+
+ FreezeThread(iCurThread, 1);
+ threads[iCurThread].iState = TS_SLEEPING;
+ iCurThread = -1;
+
+ ps2_reschedule();
+ break;
+
+ case 25:// WakeupThread
+ #if DEBUG_THREADING
+ printf("IOP: WakeupThread(%d)\n", a0);
+ #endif
+
+ // set thread to "ready to go"
+ threads[a0].iState = TS_READY;
+ break;
+
+ case 26:// iWakeupThread
+ #if DEBUG_THREADING
+ printf("IOP: iWakeupThread(%d)\n", a0);
+ #endif
+
+ // set thread to "ready to go" if it's not running
+ if (threads[a0].iState != TS_RUNNING)
+ {
+ threads[a0].iState = TS_READY;
+ }
+ break;
+
+ case 33:// DelayThread
+ {
+ double dTicks;
+
+ #if DEBUG_THREADING
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ printf("IOP: DelayThread(%d) (PC=%x) [curthread = %d]\n", a0, mipsinfo.i, iCurThread);
+ #endif
+
+ if (a0 < 100)
+ {
+ a0 = 100;
+ }
+ dTicks = (double)a0;
+
+ FreezeThread(iCurThread, 1);
+ threads[iCurThread].iState = TS_WAITDELAY;
+ dTicks /= (double)1000000.0;
+ dTicks *= (double)36864000.0; // 768*48000 = IOP native-mode clock rate
+ threads[iCurThread].waitparm = (uint32_t)dTicks;
+ iCurThread = -1;
+
+ ps2_reschedule();
+ }
+ break;
+
+ case 34://GetSystemTime
+ #if DEBUG_HLE_IOP
+ printf("IOP: GetSystemTime(%x)\n", a0);
+ #endif
+
+ a0 &= 0x1fffff;
+ a0 /= 4;
+
+ psx_ram[a0] = LE32(sys_time & 0xffffffff); // low
+ psx_ram[a0+1] = LE32(sys_time >> 32); // high
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 39:// USec2SysClock
+ {
+ uint64_t dTicks = (uint64_t)a0;
+ uint32_t hi, lo;
+
+ #if DEBUG_HLE_IOP
+ printf("IOP: USec2SysClock(%d %08x)\n", a0, a1);
+ #endif
+
+ dTicks *= (uint64_t)36864000;
+ dTicks /= (uint64_t)1000000;
+
+ hi = dTicks>>32;
+ lo = dTicks & 0xffffffff;
+
+ psx_ram[((a1 & 0x1fffff)/4)] = LE32(lo);
+ psx_ram[((a1 & 0x1fffff)/4)+1] = LE32(hi);
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 40://SysClock2USec
+ {
+ uint64_t temp;
+ uint32_t seconds, usec;
+
+ #if DEBUG_HLE_IOP
+ printf("IOP: SysClock2USec(%08x %08x %08x)\n", a0, a1, a2);
+ #endif
+
+ a0 &= 0x1fffff;
+ a1 &= 0x1fffff;
+ a2 &= 0x1fffff;
+ a0 /= 4;
+ a1 /= 4;
+ a2 /= 4;
+
+ temp = LE32(psx_ram[a0]);
+ temp |= (uint64_t)LE32(psx_ram[a0+1])<<32;
+
+ temp *= (uint64_t)1000000;
+ temp /= (uint64_t)36864000;
+
+ // temp now is USec
+ seconds = (temp / 1000000) & 0xffffffff;
+ usec = (temp % 1000000) & 0xffffffff;
+
+ psx_ram[a1] = LE32(seconds);
+ psx_ram[a2] = LE32(usec);
+ }
+ break;
+
+ default:
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ break;
+ }
+ }
+ else if (!strcmp(name, "thevent"))
+ {
+ switch (callnum)
+ {
+ case 4: // CreateEventFlag
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ #if DEBUG_HLE_IOP
+ printf("IOP: CreateEventFlag(%08x) (PC=%x)\n", a0, mipsinfo.i);
+ #endif
+
+ a0 &= 0x1fffff;
+ a0 /= 4;
+
+ evflags[iNumFlags].type = LE32(psx_ram[a0]);
+ evflags[iNumFlags].value = LE32(psx_ram[a0+1]);
+ evflags[iNumFlags].param = LE32(psx_ram[a0+2]);
+ evflags[iNumFlags].inUse = 1;
+
+ #if DEBUG_HLE_IOP
+ printf(" Flag %02d: type %d init %08x param %08x\n", iNumFlags, evflags[iNumFlags].type, evflags[iNumFlags].value, evflags[iNumFlags].param);
+ #endif
+
+ mipsinfo.i = iNumFlags+1;
+ iNumFlags++;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 6: // SetEventFlag
+ a0--;
+ #if DEBUG_HLE_IOP
+ printf("IOP: SetEventFlag(%d %08x)\n", a0, a1);
+ #endif
+
+ evflags[a0].value |= a1;
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 7: // iSetEventFlag
+ a0--;
+ #if DEBUG_HLE_IOP
+ printf("IOP: iSetEventFlag(%08x %08x)\n", a0, a1);
+ #endif
+
+ evflags[a0].value |= a1;
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+
+ for (i=0; i < iNumThreads; i++)
+ {
+ if ((threads[i].iState == TS_WAITEVFLAG) && (threads[i].waitparm == a0))
+ {
+ threads[i].iState = TS_READY;
+ }
+ }
+ break;
+
+ case 8: // ClearEventFlag
+ a0--;
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ #if DEBUG_HLE_IOP
+ printf("IOP: ClearEventFlag(%d %08x) (PC=%x)\n", a0, a1, mipsinfo.i);
+ #endif
+
+ evflags[a0].value &= a1;
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 9: // iClearEventFlag
+ a0--;
+ #if DEBUG_HLE_IOP
+ printf("IOP: iClearEventFlag(%d %08x)\n", a0, a1);
+ #endif
+
+ evflags[a0].value &= a1;
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 10:// WaitEventFlag
+ a0--;
+ #if DEBUG_HLE_IOP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ printf("IOP: WaitEventFlag(%d %08x %d %08x PC=%x)\n", a0, a1, a2, a3, mipsinfo.i);
+ #endif
+
+ // if we're not set, freeze this thread
+ if (!(evflags[a0].value & a1))
+ {
+ FreezeThread(iCurThread, 1);
+ threads[iCurThread].iState = TS_WAITEVFLAG;
+ threads[iCurThread].waitparm = a0;
+ iCurThread = -1;
+
+ ps2_reschedule();
+ }
+ else
+ {
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ default:
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ break;
+ }
+ }
+ else if (!strcmp(name, "thsemap"))
+ {
+ int foundthread;
+
+ switch (callnum)
+ {
+ case 4: // CreateSema
+ #if DEBUG_HLE_IOP
+ printf("IOP: CreateSema(%08x)\n", a0);
+ #endif
+
+ mipsinfo.i = -1;
+ for (i = 0; i < SEMA_MAX; i++)
+ {
+ if (!semaphores[i].inuse)
+ {
+ mipsinfo.i = i;
+ break;
+ }
+ }
+
+ if (mipsinfo.i == -1)
+ {
+ printf("IOP: out of semaphores!\n");
+ }
+
+ a0 &= 0x7fffffff;
+ a0 /= 4;
+
+// printf("Sema %d Parms: %08x %08x %08x %08x\n", mipsinfo.i, psx_ram[a0], psx_ram[a0+1], psx_ram[a0+2], psx_ram[a0+3]);
+
+ if (mipsinfo.i != -1)
+ {
+ semaphores[mipsinfo.i].attr = LE32(psx_ram[a0]);
+ semaphores[mipsinfo.i].option = LE32(psx_ram[a0+1]);
+ semaphores[mipsinfo.i].init = LE32(psx_ram[a0+2]);
+ semaphores[mipsinfo.i].max = LE32(psx_ram[a0+3]);
+
+ semaphores[mipsinfo.i].current = semaphores[mipsinfo.i].init;
+
+ semaphores[mipsinfo.i].inuse = 1;
+ }
+
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 6: // SignalSema
+ #if DEBUG_HLE_IOP
+ printf("IOP: SignalSema(%d) (current %d)\n", a0, semaphores[a0].current);
+ #endif
+
+ foundthread = 0;
+ for (i=0; i < iNumThreads; i++)
+ {
+ if ((threads[i].iState == TS_WAITSEMA) && (threads[i].waitparm == a0))
+ {
+ threads[i].iState = TS_READY;
+ semaphores[a0].threadsWaiting--;
+ foundthread = 1;
+ break;
+ }
+ }
+
+ mipsinfo.i = 0;
+
+ if (!foundthread)
+ {
+ if (semaphores[a0].current < semaphores[a0].max)
+ {
+ semaphores[a0].current++;
+ }
+ else
+ {
+ mipsinfo.i = -420; // semaphore overflow
+ }
+ }
+
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 7: // iSignalSema
+ #if DEBUG_HLE_IOP
+ printf("IOP: iSignalSema(%d)\n", a0);
+ #endif
+
+ foundthread = 0;
+ for (i=0; i < iNumThreads; i++)
+ {
+ if ((threads[i].iState == TS_WAITSEMA) && (threads[i].waitparm == a0))
+ {
+ threads[i].iState = TS_READY;
+ semaphores[a0].threadsWaiting--;
+ foundthread = 1;
+ break;
+ }
+ }
+
+ mipsinfo.i = 0;
+
+ if (!foundthread)
+ {
+ if (semaphores[a0].current < semaphores[a0].max)
+ {
+ semaphores[a0].current++;
+ }
+ else
+ {
+ mipsinfo.i = -420; // semaphore overflow
+ }
+ }
+
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 8: // WaitSema
+ #if DEBUG_HLE_IOP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ printf("IOP: WaitSema(%d) (cnt %d) (th %d) (PC=%x)\n", a0, iCurThread, semaphores[a0].current, mipsinfo.i);
+ #endif
+
+ if (semaphores[a0].current > 0)
+ {
+ semaphores[a0].current--;
+ }
+ else
+ {
+ FreezeThread(iCurThread, 1);
+ threads[iCurThread].iState = TS_WAITSEMA;
+ threads[iCurThread].waitparm = a0;
+ ps2_reschedule();
+ }
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ default:
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ break;
+ }
+ }
+ else if (!strcmp(name, "timrman"))
+ {
+ switch (callnum)
+ {
+ case 4: // AllocHardTimer
+ #if DEBUG_HLE_IOP
+ printf("IOP: AllocHardTimer(%d %d %d)\n", a0, a1, a2);
+ #endif
+ // source, size, prescale
+
+ if (a1 != 32)
+ {
+ printf("IOP: AllocHardTimer doesn't support 16-bit timers!\n");
+ }
+
+ iop_timers[iNumTimers].source = a0;
+ iop_timers[iNumTimers].prescale = a2;
+
+ mipsinfo.i = iNumTimers+1;
+ iNumTimers++;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 6: // FreeHardTimer
+ #if DEBUG_HLE_IOP
+ printf("IOP: FreeHardTimer(%d)\n", a0);
+ #endif
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 10:// GetTimerCounter
+ mipsinfo.i = iop_timers[a0-1].count;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 20: // SetTimerHandler
+ #if DEBUG_HLE_IOP
+ printf("IOP: SetTimerHandler(%d %d %08x %08x)\n", a0, a1, a2, a3);
+ #endif
+ // id, compare, handler, common (last is param for handler)
+
+ iop_timers[a0-1].target = a1;
+ iop_timers[a0-1].handler = a2;
+ iop_timers[a0-1].hparam = a3;
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 22: // SetupHardTimer
+ #if DEBUG_HLE_IOP
+ printf("IOP: SetupHardTimer(%d %d %d %d)\n", a0, a1, a2, a3);
+ #endif
+ // id, source, mode, prescale
+
+ iop_timers[a0-1].source = a1;
+ iop_timers[a0-1].mode = a2;
+ iop_timers[a0-1].prescale = a3;
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 23: // StartHardTimer
+ #if DEBUG_HLE_IOP
+ printf("IOP: StartHardTimer(%d)\n", a0);
+ #endif
+
+ iop_timers[a0-1].iActive = 1;
+ iop_timers[a0-1].count = 0;
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 24: // StopHardTimer
+ #if DEBUG_HLE_IOP
+ printf("IOP: StopHardTimer(%d)\n", a0);
+ #endif
+
+ iop_timers[a0-1].iActive = 0;
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ default:
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ break;
+ }
+ }
+ else if (!strcmp(name, "sysclib"))
+ {
+ switch (callnum)
+ {
+ case 12: // memcpy
+ {
+ uint8_t *dst, *src;
+
+ #if DEBUG_HLE_IOP
+ printf("IOP: memcpy(%08x, %08x, %d)\n", a0, a1, a2);
+ #endif
+
+ dst = (uint8_t *)&psx_ram[(a0&0x1fffff)/4];
+ src = (uint8_t *)&psx_ram[(a1&0x1fffff)/4];
+ // get exact byte alignment
+ dst += a0 % 4;
+ src += a1 % 4;
+
+ while (a2)
+ {
+ *dst = *src;
+ dst++;
+ src++;
+ a2--;
+ }
+
+ // v0 = a0
+ mipsinfo.i = a0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 13: // memmove
+ {
+ uint8_t *dst, *src;
+
+ #if DEBUG_HLE_IOP
+ printf("IOP: memmove(%08x, %08x, %d)\n", a0, a1, a2);
+ #endif
+
+ dst = (uint8_t *)&psx_ram[(a0&0x1fffff)/4];
+ src = (uint8_t *)&psx_ram[(a1&0x1fffff)/4];
+ // get exact byte alignment
+ dst += a0 % 4;
+ src += a1 % 4;
+
+ dst += a2 - 1;
+ src += a2 - 1;
+
+ while (a2)
+ {
+ *dst = *src;
+ dst--;
+ src--;
+ a2--;
+ }
+
+ // v0 = a0
+ mipsinfo.i = a0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 14: // memset
+ {
+ uint8_t *dst;
+
+ #if DEBUG_HLE_IOP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ printf("IOP: memset(%08x, %02x, %d) [PC=%x]\n", a0, a1, a2, mipsinfo.i);
+ #endif
+
+ dst = (uint8_t *)&psx_ram[(a0&0x1fffff)/4];
+ dst += (a0 & 3);
+
+ memset(dst, a1, a2);
+ }
+ break;
+
+ case 17: // bzero
+ {
+ uint8_t *dst;
+
+ #if DEBUG_HLE_IOP
+ printf("IOP: bzero(%08x, %08x)\n", a0, a1);
+ #endif
+
+ dst = (uint8_t *)&psx_ram[(a0&0x1fffff)/4];
+ dst += (a0 & 3);
+ memset(dst, 0, a1);
+ }
+ break;
+
+ case 19: // sprintf
+ mname = (char *)psx_ram;
+ str1 = (char *)psx_ram;
+ mname += a0 & 0x1fffff;
+ str1 += a1 & 0x1fffff;
+
+ #if DEBUG_HLE_IOP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ printf("IOP: sprintf(%08x, %s, ...) [PC=%08x]\n", a0, str1, (uint32_t)mipsinfo.i);
+ printf("%x %x %x %x\n", a0, a1, a2, a3);
+ #endif
+
+ iop_sprintf(mname, str1, CPUINFO_INT_REGISTER + MIPS_R6); // a2 is first parameter
+
+ #if DEBUG_HLE_IOP
+ printf(" = [%s]\n", mname);
+ #endif
+ break;
+
+ case 23: // strcpy
+ {
+ uint8_t *dst, *src;
+
+ #if DEBUG_HLE_IOP
+ printf("IOP: strcpy(%08x, %08x)\n", a0, a1);
+ #endif
+
+ dst = (uint8_t *)&psx_ram[(a0&0x1fffff)/4];
+ src = (uint8_t *)&psx_ram[(a1&0x1fffff)/4];
+ // get exact byte alignment
+ dst += a0 % 4;
+ src += a1 % 4;
+
+ while (*src != '\0')
+ {
+ *dst = *src;
+ dst++;
+ src++;
+ }
+ *dst = '\0';
+
+ // v0 = a0
+ mipsinfo.i = a0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 27: // strlen
+ {
+ char *dst;
+
+ #if DEBUG_HLE_IOP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ printf("IOP: strlen(%08x) [PC=%x]\n", a0, mipsinfo.i);
+ #endif
+
+ dst = (char *)&psx_ram[(a0&0x1fffff)/4];
+ dst += (a0 & 3);
+ mipsinfo.i = strlen(dst);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+ case 30: // strncpy
+ {
+ char *dst, *src;
+
+ #if DEBUG_HLE_IOP
+ printf("IOP: strncpy(%08x, %08x, %d)\n", a0, a1, a2);
+ #endif
+
+ dst = (char *)&psx_ram[(a0&0x1fffff)/4];
+ src = (char *)&psx_ram[(a1&0x1fffff)/4];
+ // get exact byte alignment
+ dst += a0 % 4;
+ src += a1 % 4;
+
+ while ((*src != '\0') && (a2 > 0))
+ {
+ *dst = *src;
+ dst++;
+ src++;
+ a2--;
+ }
+ *dst = '\0';
+
+ // v0 = a0
+ mipsinfo.i = a0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ }
+ break;
+
+
+ case 36: // strtol
+ mname = (char *)&psx_ram[(a0 & 0x1fffff)/4];
+ mname += (a0 & 3);
+
+ if (a1)
+ {
+ printf("IOP: Unhandled strtol with non-nullptr second parm\n");
+ }
+
+ mipsinfo.i = strtol(mname, nullptr, a2);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ default:
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ break;
+ }
+ }
+ else if (!strcmp(name, "intrman"))
+ {
+ switch (callnum)
+ {
+ case 4: // RegisterIntrHandler
+ #if DEBUG_HLE_IOP
+ printf("IOP: RegisterIntrHandler(%d %08x %08x %08x)\n", a0, a1, a2, a3);
+ #endif
+
+ if (a0 == 9)
+ {
+ irq9_fval = a1;
+ irq9_cb = a2;
+ irq9_flag = a3;
+ }
+
+ // DMA4?
+ if (a0 == 36)
+ {
+ dma4_fval = a1;
+ dma4_cb = a2;
+ dma4_flag = a3;
+ }
+
+ // DMA7?
+ if (a0 == 40)
+ {
+ dma7_fval = a1;
+ dma7_cb = a2;
+ dma7_flag = a3;
+ }
+ break;
+
+ case 5: // ReleaseIntrHandler
+ #if DEBUG_HLE_IOP
+ printf("IOP: ReleaseIntrHandler(%d)\n", a0);
+ #endif
+ break;
+
+ case 6: // EnableIntr
+ #if DEBUG_HLE_IOP
+ printf("IOP: EnableIntr(%d)\n", a0);
+ #endif
+ break;
+
+ case 7: // DisableIntr
+ #if DEBUG_HLE_IOP
+ printf("IOP: DisableIntr(%d)\n", a0);
+ #endif
+ break;
+
+ case 8: // CpuDisableIntr
+ #if DEBUG_HLE_IOP
+ printf("IOP: CpuDisableIntr(%d)\n", a0);
+ #endif
+ break;
+
+ case 9: // CpuEnableIntr
+ #if DEBUG_HLE_IOP
+ printf("IOP: CpuEnableIntr(%d)\n", a0);
+ #endif
+ break;
+
+ case 17: // CpuSuspendIntr
+ #if DEBUG_HLE_IOP
+ printf("IOP: CpuSuspendIntr\n");
+ #endif
+
+ // if already suspended, return an error code
+ if (intr_susp)
+ {
+ mipsinfo.i = -102;
+ }
+ else
+ {
+ mipsinfo.i = 0;
+ }
+ intr_susp = 1;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 18: // CpuResumeIntr
+ #if DEBUG_HLE_IOP
+ printf("IOP: CpuResumeIntr\n");
+ #endif
+ intr_susp = 0;
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 23: // QueryIntrContext
+ #if DEBUG_HLE_IOP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ printf("IOP: QueryIntrContext(PC=%x)\n", mipsinfo.i);
+ #endif
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ default:
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ break;
+ }
+ }
+ else if (!strcmp(name, "loadcore"))
+ {
+ switch (callnum)
+ {
+ case 5: // FlushDcache
+ #if DEBUG_HLE_IOP
+ printf("IOP: FlushDcache()\n");
+ #endif
+ break;
+
+ case 6: // RegisterLibraryEntries
+ a0 &= 0x1fffff;
+ #if DEBUG_HLE_IOP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ printf("IOP: RegisterLibraryEntries(%08x) (PC=%x)\n", a0, mipsinfo.i);
+ #endif
+
+ if (psx_ram[a0/4] == LE32(0x41c00000))
+ {
+ a0 += 3*4;
+ memcpy(®libs[iNumLibs].name, &psx_ram[a0/4], 8);
+ reglibs[iNumLibs].name[8] = '\0';
+ #if DEBUG_HLE_IOP
+ printf("Lib name [%s]\n", ®libs[iNumLibs].name);
+ #endif
+ a0 += 2*4;
+ reglibs[iNumLibs].dispatch = a0;
+ iNumLibs++;
+ }
+ else
+ {
+ printf("ERROR: Entry table signature missing\n");
+
+ }
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ default:
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ break;
+ }
+ }
+ else if (!strcmp(name, "sysmem"))
+ {
+ uint32_t newAlloc;
+
+ switch (callnum)
+ {
+ case 4: // AllocMemory
+ newAlloc = psf2_get_loadaddr();
+ // make sure we're 16-byte aligned
+ if (newAlloc & 15)
+ {
+ newAlloc &= ~15;
+ newAlloc += 16;
+ }
+
+ if (a1 & 15)
+ {
+ a1 &= ~15;
+ a1 += 16;
+ }
+
+ psf2_set_loadaddr(newAlloc + a1);
+
+ #if DEBUG_HLE_IOP
+ printf("IOP: AllocMemory(%d, %d, %x) = %08x\n", a0, a1, a2, newAlloc|0x80000000);
+ #endif
+
+ mipsinfo.i = newAlloc; // | 0x80000000;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 5: // FreeMemory
+ #if DEBUG_HLE_IOP
+ printf("IOP: FreeMemory(%x)\n", a0);
+ #endif
+ break;
+
+ case 7: // QueryMaxFreeMemSize
+ #if DEBUG_HLE_IOP
+ printf("IOP: QueryMaxFreeMemSize\n");
+ #endif
+
+ mipsinfo.i = (2*1024*1024) - psf2_get_loadaddr();
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 8: // QueryTotalFreeMemSize
+ #if DEBUG_HLE_IOP
+ printf("IOP: QueryTotalFreeMemSize\n");
+ #endif
+
+ mipsinfo.i = (2*1024*1024) - psf2_get_loadaddr();
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 14: // Kprintf
+ mname = (char *)psx_ram;
+ mname += a0 & 0x1fffff;
+ mname += (a0 & 3);
+
+ iop_sprintf(out, mname, CPUINFO_INT_REGISTER + MIPS_R5); // a1 is first parm
+
+ if (out[strlen(out)-1] != '\n')
+ {
+ strcat(out, "\n");
+ }
+
+ // filter out ESC characters
+ {
+ int ch;
+
+ for (ch = 0; ch < strlen(out); ch++)
+ {
+ if (out[ch] == 27)
+ {
+ out[ch] = ']';
+ }
+ }
+ }
+
+ #if DEBUG_HLE_IOP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ printf("KTTY: %s [PC=%x]\n", out, mipsinfo.i);
+ #endif
+ break;
+
+ default:
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ break;
+ }
+ }
+ else if (!strcmp(name, "modload"))
+ {
+ uint8_t *tempmem;
+ uint32_t newAlloc;
+
+ switch (callnum)
+ {
+ case 7: // LoadStartModule
+ mname = (char *)&psx_ram[(a0 & 0x1fffff)/4];
+ mname += 8;
+ str1 = (char *)&psx_ram[(a2 & 0x1fffff)/4];
+ #if DEBUG_HLE_IOP
+ printf("LoadStartModule: %s\n", mname);
+ #endif
+
+ // get 2k for our parameters
+ newAlloc = psf2_get_loadaddr();
+ // force 16-byte alignment
+ if (newAlloc & 0xf)
+ {
+ newAlloc &= ~0xf;
+ newAlloc += 16;
+ }
+ psf2_set_loadaddr(newAlloc + 2048);
+
+ tempmem = (uint8_t *)malloc(2*1024*1024);
+ if (psf2_load_file(mname, tempmem, 2*1024*1024) != 0xffffffff)
+ {
+ uint32_t start;
+ int i;
+
+ start = psf2_load_elf(tempmem, 2*1024*1024);
+
+ if (start != 0xffffffff)
+ {
+ uint32_t args[20], numargs = 1, argofs;
+ uint8_t *argwalk = (uint8_t *)psx_ram;
+
+ argwalk += (a2 & 0x1fffff);
+
+ args[0] = a0; // program name is argc[0]
+
+ argofs = 0;
+
+ if (a1 > 0)
+ {
+ args[numargs] = a2;
+ numargs++;
+
+ while (a1)
+ {
+ if ((*argwalk == 0) && (a1 > 1))
+ {
+ args[numargs] = a2 + argofs + 1;
+ numargs++;
+ }
+ argwalk++;
+ argofs++;
+ a1--;
+ }
+ }
+
+ for (i = 0; i < numargs; i++)
+ {
+ #if DEBUG_HLE_IOP
+// printf("Arg %d: %08x [%s]\n", i, args[i], &argbase[args[i]-a2]);
+ #endif
+ psx_ram[(newAlloc/4)+i] = LE32(args[i]);
+ }
+
+ // set argv and argc
+ mipsinfo.i = numargs;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R4, &mipsinfo);
+ mipsinfo.i = 0x80000000 | newAlloc;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R5, &mipsinfo);
+
+ // leave RA alone, PC = module start
+ // (NOTE: we get called in the delay slot!)
+ mipsinfo.i = start - 4;
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+ }
+ }
+ free(tempmem);
+ break;
+
+ default:
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ break;
+ }
+
+ }
+ else if (!strcmp(name, "ioman"))
+ {
+ switch (callnum)
+ {
+ case 4: // open
+ {
+ int i, slot2use;
+
+ slot2use = -1;
+ for (i = 0; i < MAX_FILE_SLOTS; i++)
+ {
+ if (filestat[i] == 0)
+ {
+ slot2use = i;
+ break;
+ }
+ }
+
+ if (slot2use == -1)
+ {
+ printf("IOP: out of file slots!\n");
+ mipsinfo.i = 0xffffffff;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ return;
+ }
+
+ mname = (char *)psx_ram;
+ mname += (a0 & 0x1fffff);
+
+ if (!strncmp(mname, "aofile:", 7))
+ {
+ mname += 8;
+ }
+ else if (!strncmp(mname, "hefile:", 7))
+ {
+ mname += 8;
+ }
+ else if (!strncmp(mname, "host0:", 6))
+ {
+ mname += 7;
+ }
+
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ #if DEBUG_HLE_IOP
+ printf("IOP: open(\"%s\") (PC=%08x)\n", mname, mipsinfo.i);
+ #endif
+
+ filedata[slot2use] = (uint8_t *) malloc(6*1024*1024);
+ filesize[slot2use] = psf2_load_file(mname, filedata[slot2use], 6*1024*1024);
+ filepos[slot2use] = 0;
+ filestat[slot2use] = 1;
+
+ if (filesize[slot2use] == 0xffffffff)
+ {
+ mipsinfo.i = filesize[slot2use];
+ }
+ else
+ {
+ mipsinfo.i = slot2use;
+ }
+ }
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 5: // close
+ #if DEBUG_HLE_IOP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ printf("IOP: close(%d) (PC=%08x)\n", a0, mipsinfo.i);
+ #endif
+ free(filedata[a0]);
+ filedata[a0] = (uint8_t *)nullptr;
+ filepos[a0] = 0;
+ filesize[a0] = 0;
+ filestat[a0] = 0;
+ break;
+
+ case 6: // read
+ #if DEBUG_HLE_IOP
+ printf("IOP: read(%x %x %d) [pos %d size %d]\n", a0, a1, a2, filepos[a0], filesize[a0]);
+ #endif
+
+ if (filepos[a0] >= filesize[a0])
+ {
+ mipsinfo.i = 0;
+ }
+ else
+ {
+ uint8_t *rp;
+
+ if ((filepos[a0] + a2) > filesize[a0])
+ {
+ a2 = filesize[a0] - filepos[a0];
+ }
+
+ rp = (uint8_t *)psx_ram;
+ rp += (a1 & 0x1fffff);
+ memcpy(rp, &filedata[a0][filepos[a0]], a2);
+
+ filepos[a0] += a2;
+ mipsinfo.i = a2;
+ }
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 8: // lseek
+ #if DEBUG_HLE_IOP
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ printf("IOP: lseek(%d, %d, %s) (PC=%08x)\n", a0, a1, seek_types[a2], mipsinfo.i);
+ #endif
+
+ switch (a2)
+ {
+ case 0: // SEEK_SET
+ if (a1 <= filesize[a0])
+ {
+ filepos[a0] = a1;
+ }
+ break;
+ case 1: // SEEK_CUR
+ if ((a1 + filepos[a0]) < filesize[a0])
+ {
+ filepos[a0] += a1;
+ }
+ break;
+ case 2: // SEEK_END
+ filepos[a0] = filesize[a0] - a1;
+ break;
+ }
+
+ mipsinfo.i = filepos[a0];
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 20: // AddDrv
+ #if DEBUG_HLE_IOP
+ printf("IOP: AddDrv(%x)\n", a0);
+ #endif
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ case 21: // DelDrv
+ #if DEBUG_HLE_IOP
+ printf("IOP: DelDrv(%x)\n", a0);
+ #endif
+
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_R2, &mipsinfo);
+ break;
+
+ default:
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ }
+ }
+ else
+ {
+ int lib;
+
+ if (iNumLibs > 0)
+ {
+ for (lib = 0; lib < iNumLibs; lib++)
+ {
+ if (!strcmp(name, reglibs[lib].name))
+ {
+ #if DEBUG_HLE_IOP
+ uint32_t PC;
+
+ mips_get_info(CPUINFO_INT_REGISTER + MIPS_R31, &mipsinfo);
+ PC = mipsinfo.i;
+ #endif
+
+ // zap the delay slot handling
+ mipsinfo.i = 0;
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_DELAYV, &mipsinfo);
+ mips_set_info(CPUINFO_INT_REGISTER + MIPS_DELAYR, &mipsinfo);
+
+ mipsinfo.i = LE32(psx_ram[(reglibs[lib].dispatch/4) + callnum]);
+
+ // (NOTE: we get called in the delay slot!)
+ #if DEBUG_HLE_IOP
+ printf("IOP: Calling %s (%d) service %d => %08x (parms %08x %08x %08x %08x) (PC=%x)\n",
+ reglibs[lib].name,
+ lib,
+ callnum,
+ (uint32_t)mipsinfo.i,
+ a0, a1, a2, a3, PC);
+ #endif
+
+ #if 0
+ if (!strcmp(reglibs[lib].name, "ssd"))
+ {
+ if (callnum == 37)
+ {
+ psxcpu_verbose = 4096;
+ }
+ }
+ #endif
+
+ mipsinfo.i -= 4;
+ mips_set_info(CPUINFO_INT_PC, &mipsinfo);
+
+ return;
+ }
+ }
+ }
+
+ printf("IOP: Unhandled service %d for module %s\n", callnum, name);
+ }
+}
+
diff --git a/src/pulse_audio/Makefile b/src/pulse_audio/Makefile
index ff029982d57e..831fc89f1ee8 100644
--- a/src/pulse_audio/Makefile
+++ b/src/pulse_audio/Makefile
@@ -1,12 +1,13 @@
PLUGIN = pulse_audio${PLUGIN_SUFFIX}
-SRCS = pulse_audio.c
+SRCS = pulse_audio.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${OUTPUT_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
LIBS += -lpulse
diff --git a/src/pulse_audio/pulse_audio.c b/src/pulse_audio/pulse_audio.c
deleted file mode 100644
index 3fc4e05edee1..000000000000
--- a/src/pulse_audio/pulse_audio.c
+++ /dev/null
@@ -1,677 +0,0 @@
-/***
- This file is part of xmms-pulse.
-
- xmms-pulse 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.
-
- xmms-pulse 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 xmms-pulse; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
- USA.
-***/
-
-#include <stdio.h>
-#include <assert.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-
-#include <pulse/pulseaudio.h>
-
-#include <audacious/debug.h>
-#include <audacious/drct.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/i18n.h>
-
-#define ERROR(...) do {fprintf (stderr, "pulseaudio: " __VA_ARGS__); putchar ('\n');} while (0)
-
-static pa_context *context = NULL;
-static pa_stream *stream = NULL;
-static pa_threaded_mainloop *mainloop = NULL;
-
-static pa_cvolume volume;
-static int volume_valid = 0;
-
-static int do_trigger = 0;
-static int64_t written;
-static int flush_time;
-static int bytes_per_second;
-
-static int connected = 0;
-
-static pa_time_event *volume_time_event = NULL;
-
-#define CHECK_DEAD_GOTO(label, warn) do { \
-if (!mainloop || \
- !context || pa_context_get_state(context) != PA_CONTEXT_READY || \
- !stream || pa_stream_get_state(stream) != PA_STREAM_READY) { \
- if (warn) \
- AUDDBG("Connection died: %s", context ? pa_strerror(pa_context_errno(context)) : "NULL"); \
- goto label; \
- } \
-} while(0);
-
-#define CHECK_CONNECTED(retval) \
-do { \
- if (!connected) return retval; \
-} while (0);
-
-static void info_cb(struct pa_context *c, const struct pa_sink_input_info *i, int is_last, void *userdata) {
- assert(c);
-
- if (!i)
- return;
-
- volume = i->volume;
- volume_valid = 1;
-}
-
-static void subscribe_cb(struct pa_context *c, enum pa_subscription_event_type t, uint32_t index, void *userdata) {
- pa_operation *o;
-
- assert(c);
-
- if (!stream ||
- index != pa_stream_get_index(stream) ||
- (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE) &&
- t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW)))
- return;
-
- if (!(o = pa_context_get_sink_input_info(c, index, info_cb, NULL))) {
- AUDDBG("pa_context_get_sink_input_info() failed: %s", pa_strerror(pa_context_errno(c)));
- return;
- }
-
- pa_operation_unref(o);
-}
-
-static void context_state_cb(pa_context *c, void *userdata) {
- assert(c);
-
- switch (pa_context_get_state(c)) {
- case PA_CONTEXT_READY:
- case PA_CONTEXT_TERMINATED:
- case PA_CONTEXT_FAILED:
- pa_threaded_mainloop_signal(mainloop, 0);
- break;
-
- case PA_CONTEXT_UNCONNECTED:
- case PA_CONTEXT_CONNECTING:
- case PA_CONTEXT_AUTHORIZING:
- case PA_CONTEXT_SETTING_NAME:
- break;
- }
-}
-
-static void stream_state_cb(pa_stream *s, void * userdata) {
- assert(s);
-
- switch (pa_stream_get_state(s)) {
-
- case PA_STREAM_READY:
- case PA_STREAM_FAILED:
- case PA_STREAM_TERMINATED:
- pa_threaded_mainloop_signal(mainloop, 0);
- break;
-
- case PA_STREAM_UNCONNECTED:
- case PA_STREAM_CREATING:
- break;
- }
-}
-
-static void stream_success_cb(pa_stream *s, int success, void *userdata) {
- assert(s);
-
- if (userdata)
- *(int*) userdata = success;
-
- pa_threaded_mainloop_signal(mainloop, 0);
-}
-
-static void context_success_cb(pa_context *c, int success, void *userdata) {
- assert(c);
-
- if (userdata)
- *(int*) userdata = success;
-
- pa_threaded_mainloop_signal(mainloop, 0);
-}
-
-static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
- assert(s);
-
- pa_threaded_mainloop_signal(mainloop, 0);
-}
-
-static void stream_latency_update_cb(pa_stream *s, void *userdata) {
- assert(s);
-
- pa_threaded_mainloop_signal(mainloop, 0);
-}
-
-static void pulse_get_volume (int * l, int * r)
-{
- * l = * r = 0;
-
- if (! connected || ! volume_valid)
- return;
-
- pa_threaded_mainloop_lock (mainloop);
- CHECK_DEAD_GOTO (fail, 1);
-
- if (volume.channels == 2)
- {
- * l = (volume.values[0] * 100 + PA_VOLUME_NORM / 2) / PA_VOLUME_NORM;
- * r = (volume.values[1] * 100 + PA_VOLUME_NORM / 2) / PA_VOLUME_NORM;
- }
- else
- * l = * r = (pa_cvolume_avg (& volume) * 100 + PA_VOLUME_NORM / 2) /
- PA_VOLUME_NORM;
-
-fail:
- pa_threaded_mainloop_unlock (mainloop);
-}
-
-static void volume_time_cb(pa_mainloop_api *api, pa_time_event *e, const struct timeval *tv, void *userdata) {
- pa_operation *o;
-
- if (!(o = pa_context_set_sink_input_volume(context, pa_stream_get_index(stream), &volume, NULL, NULL)))
- AUDDBG("pa_context_set_sink_input_volume() failed: %s", pa_strerror(pa_context_errno(context)));
- else
- pa_operation_unref(o);
-
- /* We don't wait for completion of this command */
-
- api->time_free(volume_time_event);
- volume_time_event = NULL;
-}
-
-static void pulse_set_volume(int l, int r) {
-
- if (! connected)
- return;
-
- pa_threaded_mainloop_lock (mainloop);
- CHECK_DEAD_GOTO (fail, 1);
-
- /* sanitize output volumes. */
- l = CLAMP(l, 0, 100);
- r = CLAMP(r, 0, 100);
-
- if (!volume_valid || volume.channels != 1) {
- volume.values[0] = ((pa_volume_t) l * PA_VOLUME_NORM + 50) / 100;
- volume.values[1] = ((pa_volume_t) r * PA_VOLUME_NORM + 50) / 100;
- volume.channels = 2;
- } else {
- volume.values[0] = ((pa_volume_t) MAX (l, r) * PA_VOLUME_NORM + 50) / 100;
- volume.channels = 1;
- }
-
- volume_valid = 1;
-
- if (connected && !volume_time_event) {
- struct timeval tv;
- pa_mainloop_api *api = pa_threaded_mainloop_get_api(mainloop);
- volume_time_event = api->time_new(api, pa_timeval_add(pa_gettimeofday(&tv), 100000), volume_time_cb, NULL);
- }
-
-fail:
- if (connected)
- pa_threaded_mainloop_unlock(mainloop);
-}
-
-static void pulse_pause (bool_t b)
-{
- pa_operation *o = NULL;
- int success = 0;
-
- CHECK_CONNECTED();
-
- pa_threaded_mainloop_lock(mainloop);
- CHECK_DEAD_GOTO(fail, 1);
-
- if (!(o = pa_stream_cork(stream, b, stream_success_cb, &success))) {
- AUDDBG("pa_stream_cork() failed: %s", pa_strerror(pa_context_errno(context)));
- goto fail;
- }
-
- while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
- CHECK_DEAD_GOTO(fail, 1);
- pa_threaded_mainloop_wait(mainloop);
- }
-
- if (!success)
- AUDDBG("pa_stream_cork() failed: %s", pa_strerror(pa_context_errno(context)));
-
-fail:
-
- if (o)
- pa_operation_unref(o);
-
- pa_threaded_mainloop_unlock(mainloop);
-}
-
-static int pulse_free(void) {
- size_t l = 0;
- pa_operation *o = NULL;
-
- CHECK_CONNECTED(0);
-
- pa_threaded_mainloop_lock(mainloop);
- CHECK_DEAD_GOTO(fail, 1);
-
- if ((l = pa_stream_writable_size(stream)) == (size_t) -1) {
- AUDDBG("pa_stream_writable_size() failed: %s", pa_strerror(pa_context_errno(context)));
- l = 0;
- goto fail;
- }
-
- /* If this function is called twice with no pulse_write() call in
- * between this means we should trigger the playback */
- if (do_trigger) {
- int success = 0;
-
- if (!(o = pa_stream_trigger(stream, stream_success_cb, &success))) {
- AUDDBG("pa_stream_trigger() failed: %s", pa_strerror(pa_context_errno(context)));
- goto fail;
- }
-
- while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
- CHECK_DEAD_GOTO(fail, 1);
- pa_threaded_mainloop_wait(mainloop);
- }
-
- if (!success)
- AUDDBG("pa_stream_trigger() failed: %s", pa_strerror(pa_context_errno(context)));
- }
-
-fail:
- if (o)
- pa_operation_unref(o);
-
- pa_threaded_mainloop_unlock(mainloop);
-
- do_trigger = !!l;
- return (int) l;
-}
-
-static int pulse_get_output_time (void)
-{
- int time = 0;
-
- CHECK_CONNECTED(0);
-
- pa_threaded_mainloop_lock(mainloop);
-
- time = written * (int64_t) 1000 / bytes_per_second;
-
- pa_usec_t usec;
- int neg;
- if (pa_stream_get_latency (stream, & usec, & neg) == PA_OK)
- time -= usec / 1000;
-
- /* fix for AUDPLUG-308: pa_stream_get_latency() still returns positive even
- * immediately after a flush; fix the result so that we don't return less
- * than the flush time */
- if (time < flush_time)
- time = flush_time;
-
- pa_threaded_mainloop_unlock(mainloop);
-
- return time;
-}
-
-static void pulse_drain(void) {
- pa_operation *o = NULL;
- int success = 0;
-
- CHECK_CONNECTED();
-
- pa_threaded_mainloop_lock(mainloop);
- CHECK_DEAD_GOTO(fail, 0);
-
- if (!(o = pa_stream_drain(stream, stream_success_cb, &success))) {
- AUDDBG("pa_stream_drain() failed: %s", pa_strerror(pa_context_errno(context)));
- goto fail;
- }
-
- while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
- CHECK_DEAD_GOTO(fail, 1);
- pa_threaded_mainloop_wait(mainloop);
- }
-
- if (!success)
- AUDDBG("pa_stream_drain() failed: %s", pa_strerror(pa_context_errno(context)));
-
-fail:
- if (o)
- pa_operation_unref(o);
-
- pa_threaded_mainloop_unlock(mainloop);
-}
-
-static void pulse_flush(int time) {
- pa_operation *o = NULL;
- int success = 0;
-
- CHECK_CONNECTED();
-
- pa_threaded_mainloop_lock(mainloop);
- CHECK_DEAD_GOTO(fail, 1);
-
- written = time * (int64_t) bytes_per_second / 1000;
- flush_time = time;
-
- if (!(o = pa_stream_flush(stream, stream_success_cb, &success))) {
- AUDDBG("pa_stream_flush() failed: %s", pa_strerror(pa_context_errno(context)));
- goto fail;
- }
-
- while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
- CHECK_DEAD_GOTO(fail, 1);
- pa_threaded_mainloop_wait(mainloop);
- }
-
- if (!success)
- AUDDBG("pa_stream_flush() failed: %s", pa_strerror(pa_context_errno(context)));
-
-fail:
- if (o)
- pa_operation_unref(o);
-
- pa_threaded_mainloop_unlock(mainloop);
-}
-
-static void pulse_write(void* ptr, int length) {
- int writeoffs, remain, writable;
-
- CHECK_CONNECTED();
-
- pa_threaded_mainloop_lock(mainloop);
- CHECK_DEAD_GOTO(fail, 1);
-
- /* break large fragments into smaller fragments. --nenolod */
- for (writeoffs = 0, remain = length;
- writeoffs < length;
- writeoffs += writable, remain -= writable)
- {
- void * pptr = (char *) ptr + writeoffs;
-
- writable = length - writeoffs;
- size_t fragsize = pa_stream_writable_size(stream);
-
- /* don't write more than what PA is willing to handle right now. */
- if (writable > fragsize)
- writable = fragsize;
-
- if (pa_stream_write(stream, pptr, writable, NULL, PA_SEEK_RELATIVE, 0) < 0) {
- AUDDBG("pa_stream_write() failed: %s", pa_strerror(pa_context_errno(context)));
- goto fail;
- }
- }
-
- do_trigger = 0;
- written += length;
-
-fail:
- pa_threaded_mainloop_unlock(mainloop);
-}
-
-static void pulse_close(void)
-{
- connected = 0;
-
- if (mainloop)
- pa_threaded_mainloop_stop(mainloop);
-
- if (stream) {
- pa_stream_disconnect(stream);
- pa_stream_unref(stream);
- stream = NULL;
- }
-
- if (context) {
- pa_context_disconnect(context);
- pa_context_unref(context);
- context = NULL;
- }
-
- if (mainloop) {
- pa_threaded_mainloop_free(mainloop);
- mainloop = NULL;
- }
-
- volume_time_event = NULL;
- volume_valid = 0;
-}
-
-static int pulse_open(int fmt, int rate, int nch) {
- pa_sample_spec ss;
- pa_operation *o = NULL;
- int success;
-
- assert(!mainloop);
- assert(!context);
- assert(!stream);
- assert(!connected);
-
- switch(fmt)
- {
- case FMT_U8:
- ss.format = PA_SAMPLE_U8;
- break;
- case FMT_S16_LE:
- ss.format = PA_SAMPLE_S16LE;
- break;
- case FMT_S16_BE:
- ss.format = PA_SAMPLE_S16BE;
- break;
-
-#ifdef PA_SAMPLE_S24_32LE
- case FMT_S24_LE:
- ss.format = PA_SAMPLE_S24_32LE;
- break;
- case FMT_S24_BE:
- ss.format = PA_SAMPLE_S24_32BE;
- break;
-#endif
-
-#ifdef PA_SAMPLE_S32LE
- case FMT_S32_LE:
- ss.format = PA_SAMPLE_S32LE;
- break;
- case FMT_S32_BE:
- ss.format = PA_SAMPLE_S32BE;
- break;
-#endif
-
- case FMT_FLOAT:
- ss.format = PA_SAMPLE_FLOAT32NE;
- break;
- default:
- return FALSE;
- }
- ss.rate = rate;
- ss.channels = nch;
-
- if (!pa_sample_spec_valid(&ss))
- return FALSE;
-
- if (!(mainloop = pa_threaded_mainloop_new())) {
- ERROR ("Failed to allocate main loop");
- goto fail;
- }
-
- pa_threaded_mainloop_lock(mainloop);
-
- if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), "Audacious"))) {
- ERROR ("Failed to allocate context");
- goto unlock_and_fail;
- }
-
- pa_context_set_state_callback(context, context_state_cb, NULL);
- pa_context_set_subscribe_callback(context, subscribe_cb, NULL);
-
- if (pa_context_connect(context, NULL, 0, NULL) < 0) {
- ERROR ("Failed to connect to server: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- if (pa_threaded_mainloop_start(mainloop) < 0) {
- ERROR ("Failed to start main loop");
- goto unlock_and_fail;
- }
-
- /* Wait until the context is ready */
- pa_threaded_mainloop_wait(mainloop);
-
- if (pa_context_get_state(context) != PA_CONTEXT_READY) {
- ERROR ("Failed to connect to server: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- if (!(stream = pa_stream_new(context, "Audacious", &ss, NULL))) {
- ERROR ("Failed to create stream: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- pa_stream_set_state_callback(stream, stream_state_cb, NULL);
- pa_stream_set_write_callback(stream, stream_request_cb, NULL);
- pa_stream_set_latency_update_callback(stream, stream_latency_update_cb, NULL);
-
- /* Connect stream with sink and default volume */
- /* Buffer struct */
-
- int aud_buffer = aud_get_int(NULL, "output_buffer_size");
- size_t buffer_size = pa_usec_to_bytes(aud_buffer, &ss) * 1000;
- pa_buffer_attr buffer = {(uint32_t) -1, buffer_size, (uint32_t) -1, (uint32_t) -1, buffer_size};
-
- if (pa_stream_connect_playback(stream, NULL, &buffer, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL) < 0) {
- ERROR ("Failed to connect stream: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
-
- /* Wait until the stream is ready */
- pa_threaded_mainloop_wait(mainloop);
-
- if (pa_stream_get_state(stream) != PA_STREAM_READY) {
- ERROR ("Failed to connect stream: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- /* Now subscribe to events */
- if (!(o = pa_context_subscribe(context, PA_SUBSCRIPTION_MASK_SINK_INPUT, context_success_cb, &success))) {
- ERROR ("pa_context_subscribe() failed: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- success = 0;
- while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
- CHECK_DEAD_GOTO(fail, 1);
- pa_threaded_mainloop_wait(mainloop);
- }
-
- if (!success) {
- ERROR ("pa_context_subscribe() failed: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- pa_operation_unref(o);
-
- /* Now request the initial stream info */
- if (!(o = pa_context_get_sink_input_info(context, pa_stream_get_index(stream), info_cb, NULL))) {
- ERROR ("pa_context_get_sink_input_info() failed: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
- CHECK_DEAD_GOTO(fail, 1);
- pa_threaded_mainloop_wait(mainloop);
- }
-
- if (!volume_valid) {
- ERROR ("pa_context_get_sink_input_info() failed: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
- pa_operation_unref(o);
-
- do_trigger = 0;
- written = 0;
- flush_time = 0;
- bytes_per_second = FMT_SIZEOF (fmt) * nch * rate;
- connected = 1;
- volume_time_event = NULL;
-
- pa_threaded_mainloop_unlock(mainloop);
-
- return TRUE;
-
-unlock_and_fail:
-
- if (o)
- pa_operation_unref(o);
-
- pa_threaded_mainloop_unlock(mainloop);
-
-fail:
-
- pulse_close();
-
- return FALSE;
-}
-
-static bool_t pulse_init (void)
-{
- if (! pulse_open (FMT_S16_NE, 44100, 2))
- return FALSE;
-
- pulse_close ();
- return TRUE;
-}
-
-static const char pulse_about[] =
- N_("Audacious PulseAudio Output Plugin\n\n"
- "This program is free software; you can redistribute it and/or modify\n"
- "it under the terms of the GNU General Public License as published by\n"
- "the Free Software Foundation; either version 2 of the License, or\n"
- "(at your option) any later version.\n"
- "\n"
- "This program is distributed in the hope that it will be useful,\n"
- "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
- "GNU General Public License for more details.\n"
- "\n"
- "You should have received a copy of the GNU General Public License\n"
- "along with this program; if not, write to the Free Software\n"
- "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
- "USA.");
-
-AUD_OUTPUT_PLUGIN
-(
- .name = N_("PulseAudio Output"),
- .domain = PACKAGE,
- .about_text = pulse_about,
- .probe_priority = 8,
- .init = pulse_init,
- .get_volume = pulse_get_volume,
- .set_volume = pulse_set_volume,
- .open_audio = pulse_open,
- .write_audio = pulse_write,
- .close_audio = pulse_close,
- .flush = pulse_flush,
- .pause = pulse_pause,
- .buffer_free = pulse_free,
- .drain = pulse_drain,
- .output_time = pulse_get_output_time
-)
diff --git a/src/pulse_audio/pulse_audio.cc b/src/pulse_audio/pulse_audio.cc
new file mode 100644
index 000000000000..4e828e8fb51a
--- /dev/null
+++ b/src/pulse_audio/pulse_audio.cc
@@ -0,0 +1,625 @@
+/***
+ This file is part of xmms-pulse.
+
+ xmms-pulse 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.
+
+ xmms-pulse 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 xmms-pulse; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA.
+***/
+
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include <pulse/pulseaudio.h>
+
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/i18n.h>
+
+class PulseOutput : public OutputPlugin
+{
+public:
+ static const char about[];
+
+ static constexpr PluginInfo info = {
+ N_("PulseAudio Output"),
+ PACKAGE,
+ about
+ };
+
+ constexpr PulseOutput () : OutputPlugin (info, 8) {}
+
+ bool init ();
+
+ StereoVolume get_volume ();
+ void set_volume (StereoVolume v);
+
+ bool open_audio (int fmt, int rate, int nch);
+ void close_audio ();
+
+ void period_wait ();
+ int write_audio (const void * ptr, int length);
+ void drain ();
+
+ int get_delay ();
+
+ void pause (bool pause);
+ void flush ();
+};
+
+EXPORT PulseOutput aud_plugin_instance;
+
+static pa_context *context = nullptr;
+static pa_stream *stream = nullptr;
+static pa_threaded_mainloop *mainloop = nullptr;
+
+static pa_cvolume volume;
+static bool volume_valid = false;
+
+static bool connected = false;
+
+#define CHECK_DEAD_GOTO(label, warn) do { \
+if (!mainloop || \
+ !context || pa_context_get_state(context) != PA_CONTEXT_READY || \
+ !stream || pa_stream_get_state(stream) != PA_STREAM_READY) { \
+ if (warn) \
+ AUDDBG("Connection died: %s\n", context ? pa_strerror(pa_context_errno(context)) : "nullptr"); \
+ goto label; \
+ } \
+} while(0);
+
+#define CHECK_CONNECTED(retval) \
+do { \
+ if (!connected) return retval; \
+} while (0);
+
+static void info_cb(struct pa_context *c, const struct pa_sink_input_info *i, int is_last, void *userdata) {
+ assert(c);
+
+ if (!i)
+ return;
+
+ volume = i->volume;
+ volume_valid = true;
+}
+
+static void subscribe_cb(struct pa_context *c, enum pa_subscription_event_type t, uint32_t index, void *userdata) {
+ pa_operation *o;
+
+ assert(c);
+
+ if (!stream ||
+ index != pa_stream_get_index(stream) ||
+ (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE) &&
+ t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW)))
+ return;
+
+ if (!(o = pa_context_get_sink_input_info(c, index, info_cb, nullptr))) {
+ AUDDBG("pa_context_get_sink_input_info() failed: %s\n", pa_strerror(pa_context_errno(c)));
+ return;
+ }
+
+ pa_operation_unref(o);
+}
+
+static void context_state_cb(pa_context *c, void *userdata) {
+ assert(c);
+
+ switch (pa_context_get_state(c)) {
+ case PA_CONTEXT_READY:
+ case PA_CONTEXT_TERMINATED:
+ case PA_CONTEXT_FAILED:
+ pa_threaded_mainloop_signal(mainloop, 0);
+ break;
+
+ case PA_CONTEXT_UNCONNECTED:
+ case PA_CONTEXT_CONNECTING:
+ case PA_CONTEXT_AUTHORIZING:
+ case PA_CONTEXT_SETTING_NAME:
+ break;
+ }
+}
+
+static void stream_state_cb(pa_stream *s, void * userdata) {
+ assert(s);
+
+ switch (pa_stream_get_state(s)) {
+
+ case PA_STREAM_READY:
+ case PA_STREAM_FAILED:
+ case PA_STREAM_TERMINATED:
+ pa_threaded_mainloop_signal(mainloop, 0);
+ break;
+
+ case PA_STREAM_UNCONNECTED:
+ case PA_STREAM_CREATING:
+ break;
+ }
+}
+
+static void stream_success_cb(pa_stream *s, int success, void *userdata) {
+ assert(s);
+
+ if (userdata)
+ *(int*) userdata = success;
+
+ pa_threaded_mainloop_signal(mainloop, 0);
+}
+
+static void context_success_cb(pa_context *c, int success, void *userdata) {
+ assert(c);
+
+ if (userdata)
+ *(int*) userdata = success;
+
+ pa_threaded_mainloop_signal(mainloop, 0);
+}
+
+static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
+ assert(s);
+
+ pa_threaded_mainloop_signal(mainloop, 0);
+}
+
+static void stream_latency_update_cb(pa_stream *s, void *userdata) {
+ assert(s);
+
+ pa_threaded_mainloop_signal(mainloop, 0);
+}
+
+StereoVolume PulseOutput::get_volume ()
+{
+ StereoVolume v = {0, 0};
+
+ if (! connected || ! volume_valid)
+ return v;
+
+ pa_threaded_mainloop_lock (mainloop);
+ CHECK_DEAD_GOTO (fail, 1);
+
+ if (volume.channels == 2)
+ {
+ v.left = aud::rescale<int> (volume.values[0], PA_VOLUME_NORM, 100);
+ v.right = aud::rescale<int> (volume.values[1], PA_VOLUME_NORM, 100);
+ }
+ else
+ v.left = v.right = aud::rescale<int> (pa_cvolume_avg (& volume), PA_VOLUME_NORM, 100);
+
+fail:
+ pa_threaded_mainloop_unlock (mainloop);
+ return v;
+}
+
+void PulseOutput::set_volume (StereoVolume v)
+{
+ pa_operation * o;
+
+ if (! connected)
+ return;
+
+ pa_threaded_mainloop_lock (mainloop);
+ CHECK_DEAD_GOTO (fail, 1);
+
+ if (! volume_valid || volume.channels != 1)
+ {
+ volume.values[0] = aud::rescale<int> (v.left, 100, PA_VOLUME_NORM);
+ volume.values[1] = aud::rescale<int> (v.right, 100, PA_VOLUME_NORM);
+ volume.channels = 2;
+ }
+ else
+ {
+ volume.values[0] = aud::rescale<int> (aud::max (v.left, v.right), 100, PA_VOLUME_NORM);
+ volume.channels = 1;
+ }
+
+ volume_valid = true;
+
+ if (! (o = pa_context_set_sink_input_volume (context, pa_stream_get_index
+ (stream), & volume, nullptr, nullptr)))
+ AUDDBG ("pa_context_set_sink_input_volume() failed: %s\n", pa_strerror
+ (pa_context_errno (context)));
+ else
+ pa_operation_unref(o);
+
+fail:
+ pa_threaded_mainloop_unlock (mainloop);
+}
+
+void PulseOutput::pause (bool pause)
+{
+ pa_operation *o = nullptr;
+ int success = 0;
+
+ CHECK_CONNECTED();
+
+ pa_threaded_mainloop_lock(mainloop);
+ CHECK_DEAD_GOTO(fail, 1);
+
+ if (!(o = pa_stream_cork(stream, pause, stream_success_cb, &success))) {
+ AUDDBG("pa_stream_cork() failed: %s\n", pa_strerror(pa_context_errno(context)));
+ goto fail;
+ }
+
+ while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
+ CHECK_DEAD_GOTO(fail, 1);
+ pa_threaded_mainloop_wait(mainloop);
+ }
+
+ if (!success)
+ AUDDBG("pa_stream_cork() failed: %s\n", pa_strerror(pa_context_errno(context)));
+
+fail:
+
+ if (o)
+ pa_operation_unref(o);
+
+ pa_threaded_mainloop_unlock(mainloop);
+}
+
+int PulseOutput::get_delay ()
+{
+ int delay = 0;
+
+ CHECK_CONNECTED(0);
+
+ pa_threaded_mainloop_lock(mainloop);
+
+ pa_usec_t usec;
+ int neg;
+ if (pa_stream_get_latency (stream, & usec, & neg) == PA_OK)
+ delay = usec / 1000;
+
+ pa_threaded_mainloop_unlock(mainloop);
+
+ return delay;
+}
+
+void PulseOutput::drain ()
+{
+ pa_operation *o = nullptr;
+ int success = 0;
+
+ CHECK_CONNECTED();
+
+ pa_threaded_mainloop_lock(mainloop);
+ CHECK_DEAD_GOTO(fail, 0);
+
+ if (!(o = pa_stream_drain(stream, stream_success_cb, &success))) {
+ AUDDBG("pa_stream_drain() failed: %s\n", pa_strerror(pa_context_errno(context)));
+ goto fail;
+ }
+
+ while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
+ CHECK_DEAD_GOTO(fail, 1);
+ pa_threaded_mainloop_wait(mainloop);
+ }
+
+ if (!success)
+ AUDDBG("pa_stream_drain() failed: %s\n", pa_strerror(pa_context_errno(context)));
+
+fail:
+ if (o)
+ pa_operation_unref(o);
+
+ pa_threaded_mainloop_unlock(mainloop);
+}
+
+void PulseOutput::flush ()
+{
+ pa_operation *o = nullptr;
+ int success = 0;
+
+ CHECK_CONNECTED();
+
+ pa_threaded_mainloop_lock(mainloop);
+ CHECK_DEAD_GOTO(fail, 1);
+
+ if (!(o = pa_stream_flush(stream, stream_success_cb, &success))) {
+ AUDDBG("pa_stream_flush() failed: %s\n", pa_strerror(pa_context_errno(context)));
+ goto fail;
+ }
+
+ while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
+ CHECK_DEAD_GOTO(fail, 1);
+ pa_threaded_mainloop_wait(mainloop);
+ }
+
+ if (!success)
+ AUDDBG("pa_stream_flush() failed: %s\n", pa_strerror(pa_context_errno(context)));
+
+fail:
+ if (o)
+ pa_operation_unref(o);
+
+ pa_threaded_mainloop_unlock(mainloop);
+}
+
+void PulseOutput::period_wait ()
+{
+ pa_operation * o = nullptr;
+ int success = 0;
+
+ CHECK_CONNECTED ();
+
+ pa_threaded_mainloop_lock (mainloop);
+ CHECK_DEAD_GOTO (fail, 1);
+
+ if (! (o = pa_stream_trigger (stream, stream_success_cb, & success)))
+ {
+ AUDDBG ("pa_stream_trigger() failed: %s\n", pa_strerror (pa_context_errno (context)));
+ goto fail;
+ }
+
+ while (pa_operation_get_state (o) != PA_OPERATION_DONE)
+ {
+ CHECK_DEAD_GOTO (fail, 1);
+ pa_threaded_mainloop_wait (mainloop);
+ }
+
+ if (! success)
+ AUDDBG ("pa_stream_trigger() failed: %s\n", pa_strerror (pa_context_errno (context)));
+
+ while (! pa_stream_writable_size (stream))
+ {
+ CHECK_DEAD_GOTO (fail, 1);
+ pa_threaded_mainloop_wait (mainloop);
+ }
+
+fail:
+ if (o)
+ pa_operation_unref(o);
+
+ pa_threaded_mainloop_unlock (mainloop);
+}
+
+int PulseOutput::write_audio (const void * ptr, int length)
+{
+ CHECK_CONNECTED(0);
+
+ int ret = 0;
+ pa_threaded_mainloop_lock(mainloop);
+ CHECK_DEAD_GOTO(fail, 1);
+
+ length = aud::min ((size_t) length, pa_stream_writable_size (stream));
+
+ if (pa_stream_write (stream, ptr, length, nullptr, 0, PA_SEEK_RELATIVE) < 0)
+ {
+ AUDDBG ("pa_stream_write() failed: %s\n", pa_strerror (pa_context_errno (context)));
+ goto fail;
+ }
+
+ ret = length;
+
+fail:
+ pa_threaded_mainloop_unlock(mainloop);
+ return ret;
+}
+
+void PulseOutput::close_audio ()
+{
+ connected = false;
+
+ if (mainloop)
+ pa_threaded_mainloop_stop(mainloop);
+
+ if (stream) {
+ pa_stream_disconnect(stream);
+ pa_stream_unref(stream);
+ stream = nullptr;
+ }
+
+ if (context) {
+ pa_context_disconnect(context);
+ pa_context_unref(context);
+ context = nullptr;
+ }
+
+ if (mainloop) {
+ pa_threaded_mainloop_free(mainloop);
+ mainloop = nullptr;
+ }
+
+ volume_valid = false;
+}
+
+static pa_sample_format_t to_pulse_format (int aformat)
+{
+ switch (aformat)
+ {
+ case FMT_U8: return PA_SAMPLE_U8;
+ case FMT_S16_LE: return PA_SAMPLE_S16LE;
+ case FMT_S16_BE: return PA_SAMPLE_S16BE;
+#ifdef PA_SAMPLE_S24_32LE
+ case FMT_S24_LE: return PA_SAMPLE_S24_32LE;
+ case FMT_S24_BE: return PA_SAMPLE_S24_32BE;
+#endif
+#ifdef PA_SAMPLE_S32LE
+ case FMT_S32_LE: return PA_SAMPLE_S32LE;
+ case FMT_S32_BE: return PA_SAMPLE_S32BE;
+#endif
+ case FMT_FLOAT: return PA_SAMPLE_FLOAT32NE;
+ default: return PA_SAMPLE_INVALID;
+ }
+}
+
+bool PulseOutput::open_audio (int fmt, int rate, int nch)
+{
+ pa_sample_spec ss;
+
+ assert(!mainloop);
+ assert(!context);
+ assert(!stream);
+ assert(!connected);
+
+ ss.format = to_pulse_format (fmt);
+ if (ss.format == PA_SAMPLE_INVALID)
+ return false;
+
+ ss.rate = rate;
+ ss.channels = nch;
+
+ if (!pa_sample_spec_valid(&ss))
+ return false;
+
+ if (!(mainloop = pa_threaded_mainloop_new())) {
+ AUDERR ("Failed to allocate main loop\n");
+ return false;
+ }
+
+ pa_threaded_mainloop_lock(mainloop);
+
+ if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), "Audacious"))) {
+ AUDERR ("Failed to allocate context\n");
+ goto FAIL1;
+ }
+
+ pa_context_set_state_callback(context, context_state_cb, nullptr);
+ pa_context_set_subscribe_callback(context, subscribe_cb, nullptr);
+
+ if (pa_context_connect(context, nullptr, (pa_context_flags_t) 0, nullptr) < 0) {
+ AUDERR ("Failed to connect to server: %s\n", pa_strerror(pa_context_errno(context)));
+ goto FAIL1;
+ }
+
+ if (pa_threaded_mainloop_start(mainloop) < 0) {
+ AUDERR ("Failed to start main loop\n");
+ goto FAIL1;
+ }
+
+ /* Wait until the context is ready */
+ pa_threaded_mainloop_wait(mainloop);
+
+ if (pa_context_get_state(context) != PA_CONTEXT_READY) {
+ AUDERR ("Failed to connect to server: %s\n", pa_strerror(pa_context_errno(context)));
+ goto FAIL1;
+ }
+
+ if (!(stream = pa_stream_new(context, "Audacious", &ss, nullptr))) {
+ AUDERR ("Failed to create stream: %s\n", pa_strerror(pa_context_errno(context)));
+
+FAIL1:
+ pa_threaded_mainloop_unlock (mainloop);
+ close_audio ();
+ return false;
+ }
+
+ pa_stream_set_state_callback(stream, stream_state_cb, nullptr);
+ pa_stream_set_write_callback(stream, stream_request_cb, nullptr);
+ pa_stream_set_latency_update_callback(stream, stream_latency_update_cb, nullptr);
+
+ /* Connect stream with sink and default volume */
+ /* Buffer struct */
+
+ int aud_buffer = aud_get_int(nullptr, "output_buffer_size");
+ size_t buffer_size = pa_usec_to_bytes(aud_buffer, &ss) * 1000;
+ pa_buffer_attr buffer = {(uint32_t) -1, (uint32_t) buffer_size,
+ (uint32_t) -1, (uint32_t) -1, (uint32_t) buffer_size};
+
+ pa_operation *o = nullptr;
+ int success;
+
+ if (pa_stream_connect_playback (stream, nullptr, & buffer, (pa_stream_flags_t)
+ (PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE), nullptr, nullptr) < 0)
+ {
+ AUDERR ("Failed to connect stream: %s\n", pa_strerror(pa_context_errno(context)));
+ goto FAIL2;
+ }
+
+
+ /* Wait until the stream is ready */
+ pa_threaded_mainloop_wait(mainloop);
+
+ if (pa_stream_get_state(stream) != PA_STREAM_READY) {
+ AUDERR ("Failed to connect stream: %s\n", pa_strerror(pa_context_errno(context)));
+ goto FAIL2;
+ }
+
+ /* Now subscribe to events */
+ if (!(o = pa_context_subscribe(context, PA_SUBSCRIPTION_MASK_SINK_INPUT, context_success_cb, &success))) {
+ AUDERR ("pa_context_subscribe() failed: %s\n", pa_strerror(pa_context_errno(context)));
+ goto FAIL2;
+ }
+
+ success = 0;
+ while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
+ CHECK_DEAD_GOTO(FAIL2, 1);
+ pa_threaded_mainloop_wait(mainloop);
+ }
+
+ if (!success) {
+ AUDERR ("pa_context_subscribe() failed: %s\n", pa_strerror(pa_context_errno(context)));
+ goto FAIL2;
+ }
+
+ pa_operation_unref(o);
+
+ /* Now request the initial stream info */
+ if (!(o = pa_context_get_sink_input_info(context, pa_stream_get_index(stream), info_cb, nullptr))) {
+ AUDERR ("pa_context_get_sink_input_info() failed: %s\n", pa_strerror(pa_context_errno(context)));
+ goto FAIL2;
+ }
+
+ while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
+ CHECK_DEAD_GOTO(FAIL2, 1);
+ pa_threaded_mainloop_wait(mainloop);
+ }
+
+ if (!volume_valid) {
+ AUDERR ("pa_context_get_sink_input_info() failed: %s\n", pa_strerror(pa_context_errno(context)));
+ goto FAIL2;
+ }
+ pa_operation_unref(o);
+
+ connected = true;
+
+ pa_threaded_mainloop_unlock(mainloop);
+
+ return true;
+
+FAIL2:
+ if (o)
+ pa_operation_unref(o);
+
+ pa_threaded_mainloop_unlock(mainloop);
+ close_audio ();
+ return false;
+}
+
+bool PulseOutput::init ()
+{
+ if (! open_audio (FMT_S16_NE, 44100, 2))
+ return false;
+
+ close_audio ();
+ return true;
+}
+
+const char PulseOutput::about[] =
+ N_("Audacious PulseAudio Output Plugin\n\n"
+ "This program is free software; you can redistribute it and/or modify\n"
+ "it under the terms of the GNU General Public License as published by\n"
+ "the Free Software Foundation; either version 2 of the License, or\n"
+ "(at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
+ "USA.");
diff --git a/src/qtaudio/Makefile b/src/qtaudio/Makefile
new file mode 100644
index 000000000000..1020965fd528
--- /dev/null
+++ b/src/qtaudio/Makefile
@@ -0,0 +1,13 @@
+PLUGIN = qtaudio${PLUGIN_SUFFIX}
+
+SRCS = qtaudio.cc
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+plugindir := ${plugindir}/${OUTPUT_PLUGIN_DIR}
+
+LD = ${CXX}
+CPPFLAGS += -I../.. ${QTMULTIMEDIA_CFLAGS}
+CXXFLAGS += ${GLIB_CFLAGS} ${PLUGIN_CFLAGS}
+LIBS += -lm ${GLIB_LIBS} ${QTMULTIMEDIA_LIBS}
diff --git a/src/qtaudio/qtaudio.cc b/src/qtaudio/qtaudio.cc
new file mode 100644
index 000000000000..40df5583debf
--- /dev/null
+++ b/src/qtaudio/qtaudio.cc
@@ -0,0 +1,302 @@
+/*
+ * QtMultimedia Audio Output Plugin for Audacious
+ * Copyright 2014 William Pitcock
+ *
+ * Based on:
+ * SDL Output Plugin for Audacious
+ * Copyright 2010 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <math.h>
+#include <pthread.h>
+#include <sys/time.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+#include <QAudioOutput>
+
+#define VOLUME_RANGE 40 /* decibels */
+
+#define error(...) do { \
+ aud_ui_show_error (str_printf ("QtAudio error: " __VA_ARGS__)); \
+} while (0)
+
+class QtAudio : public OutputPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+
+ static constexpr PluginInfo info = {
+ N_("QtMultimedia Output"),
+ PACKAGE,
+ about
+ };
+
+ constexpr QtAudio () : OutputPlugin (info, 1) {}
+
+ bool init ();
+
+ StereoVolume get_volume ();
+ void set_volume (StereoVolume v);
+
+ bool open_audio (int aud_format, int rate, int chan);
+ void close_audio ();
+
+ void period_wait ();
+ int write_audio (const void * data, int size);
+ void drain ();
+
+ int get_delay ();
+
+ void pause (bool pause);
+ void flush ();
+};
+
+EXPORT QtAudio aud_plugin_instance;
+
+const char QtAudio::about[] =
+ N_("QtMultimedia Audio Output Plugin for Audacious\n"
+ "Copyright 2014 William Pitcock\n\n"
+ "Based on SDL Output Plugin for Audacious\n"
+ "Copyright 2010 John Lindgren");
+
+const char * const QtAudio::defaults[] = {
+ "vol_left", "100",
+ "vol_right", "100",
+ nullptr};
+
+static const timespec fifty_ms = {0, 50000000};
+
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+
+static int bytes_per_sec;
+static bool paused;
+static int last_buffered, delay_estimate;
+static timeval last_system_time;
+
+static QAudioOutput * output_instance = nullptr;
+static QIODevice * buffer_instance = nullptr;
+
+struct FormatDescriptionMap {
+ int aud_format;
+
+ unsigned int sample_size;
+ enum QAudioFormat::SampleType sample_type;
+ enum QAudioFormat::Endian endian;
+};
+static struct FormatDescriptionMap FormatMap[] = {
+ {FMT_S16_LE, 16, QAudioFormat::SignedInt, QAudioFormat::LittleEndian},
+ {FMT_S16_BE, 16, QAudioFormat::SignedInt, QAudioFormat::BigEndian},
+ {FMT_U16_LE, 16, QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian},
+ {FMT_U16_BE, 16, QAudioFormat::UnSignedInt, QAudioFormat::BigEndian},
+ {FMT_S32_LE, 32, QAudioFormat::SignedInt, QAudioFormat::LittleEndian},
+ {FMT_S32_BE, 32, QAudioFormat::SignedInt, QAudioFormat::BigEndian},
+ {FMT_U32_LE, 32, QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian},
+ {FMT_U32_BE, 32, QAudioFormat::UnSignedInt, QAudioFormat::BigEndian},
+ {FMT_FLOAT, 32, QAudioFormat::Float, QAudioFormat::LittleEndian},
+};
+
+bool QtAudio::init ()
+{
+ aud_config_set_defaults ("qtaudio", defaults);
+ return true;
+}
+
+StereoVolume QtAudio::get_volume ()
+{
+ return {aud_get_int ("qtaudio", "vol_left"), aud_get_int ("qtaudio", "vol_right")};
+}
+
+void QtAudio::set_volume (StereoVolume v)
+{
+ int vol_max = aud::max (v.left, v.right);
+
+ aud_set_int ("qtaudio", "vol_left", v.left);
+ aud_set_int ("qtaudio", "vol_right", v.right);
+
+ if (output_instance)
+ {
+ float factor = (vol_max == 0) ? 0.0 : powf (10, (float) VOLUME_RANGE * (vol_max - 100) / 100 / 20);
+
+ output_instance->setVolume (factor);
+ }
+}
+
+bool QtAudio::open_audio (int format, int rate, int chan)
+{
+ struct FormatDescriptionMap * m = nullptr;
+
+ for (struct FormatDescriptionMap it : FormatMap)
+ {
+ if (it.aud_format == format)
+ {
+ m = & it;
+ break;
+ }
+ }
+
+ if (! m)
+ {
+ error ("The requested audio format %d is unsupported.\n", format);
+ return false;
+ }
+
+ AUDDBG ("Opening audio for %d channels, %d Hz.\n", chan, rate);
+
+ bytes_per_sec = FMT_SIZEOF (format) * chan * rate;
+
+ int buffer_ms = aud_get_int (nullptr, "output_buffer_size");
+ int buffer_size = FMT_SIZEOF (format) * chan * aud::rescale (buffer_ms, 1000, rate);
+
+ paused = false;
+ last_buffered = 0;
+ delay_estimate = 0;
+
+ gettimeofday (& last_system_time, nullptr);
+
+ QAudioFormat fmt;
+ fmt.setSampleRate (rate);
+ fmt.setChannelCount (chan);
+ fmt.setSampleSize (m->sample_size);
+ fmt.setCodec ("audio/pcm");
+ fmt.setByteOrder (m->endian);
+ fmt.setSampleType (m->sample_type);
+
+ QAudioDeviceInfo info (QAudioDeviceInfo::defaultOutputDevice ());
+ if (! info.isFormatSupported (fmt))
+ {
+ error ("Format not supported by backend.\n");
+ return false;
+ }
+
+ output_instance = new QAudioOutput (fmt, nullptr);
+ output_instance->setBufferSize (buffer_size);
+ buffer_instance = output_instance->start ();
+
+ set_volume (get_volume ());
+
+ return true;
+}
+
+void QtAudio::close_audio ()
+{
+ AUDDBG ("Closing audio.\n");
+
+ output_instance->stop ();
+
+ delete output_instance;
+ output_instance = nullptr;
+}
+
+void QtAudio::period_wait ()
+{
+ pthread_mutex_lock (& mutex);
+
+ while (output_instance->bytesFree () < output_instance->periodSize ())
+ pthread_cond_timedwait (& cond, & mutex, & fifty_ms);
+
+ pthread_mutex_unlock (& mutex);
+}
+
+int QtAudio::write_audio (const void * data, int len)
+{
+ pthread_mutex_lock (& mutex);
+
+ len = aud::min (len, output_instance->bytesFree ());
+ buffer_instance->write ((const char *) data, len);
+ last_buffered += len;
+
+ pthread_mutex_unlock (& mutex);
+ return len;
+}
+
+void QtAudio::drain ()
+{
+ AUDDBG ("Draining.\n");
+ pthread_mutex_lock (& mutex);
+
+ while (output_instance->bytesFree () < output_instance->bufferSize ())
+ pthread_cond_timedwait (& cond, & mutex, & fifty_ms);
+
+ pthread_mutex_unlock (& mutex);
+}
+
+int QtAudio::get_delay ()
+{
+ auto timediff = [] (const timeval & a, const timeval & b) -> int64_t
+ { return 1000 * (int64_t) (b.tv_sec - a.tv_sec) + (b.tv_usec - a.tv_usec) / 1000; };
+
+ pthread_mutex_lock (& mutex);
+
+ int buffered = output_instance->bufferSize () - output_instance->bytesFree ();
+ int delay = aud::rescale (buffered, bytes_per_sec, 1000);
+
+ timeval now;
+ gettimeofday (& now, nullptr);
+
+ if (buffered == last_buffered && ! paused)
+ delay += aud::max (delay_estimate - timediff (last_system_time, now), (int64_t) 0);
+ else
+ {
+ delay_estimate = aud::rescale (last_buffered - buffered, bytes_per_sec, 1000);
+ delay += delay_estimate;
+ last_buffered = buffered;
+ last_system_time = now;
+ }
+
+ pthread_mutex_unlock (& mutex);
+ return delay;
+}
+
+void QtAudio::pause (bool pause)
+{
+ AUDDBG ("%sause.\n", pause ? "P" : "Unp");
+ pthread_mutex_lock (& mutex);
+
+ if (pause)
+ output_instance->suspend ();
+ else
+ output_instance->resume ();
+
+ paused = pause;
+
+ pthread_cond_broadcast (& cond); /* wake up period wait */
+ pthread_mutex_unlock (& mutex);
+}
+
+void QtAudio::flush ()
+{
+ AUDDBG ("Seek requested; discarding buffer.\n");
+ pthread_mutex_lock (& mutex);
+
+ last_buffered = 0;
+ delay_estimate = 0;
+
+ gettimeofday (& last_system_time, nullptr);
+
+ output_instance->reset ();
+ buffer_instance = output_instance->start ();
+
+ pthread_cond_broadcast (& cond); /* wake up period wait */
+ pthread_mutex_unlock (& mutex);
+}
diff --git a/src/qtui/Makefile b/src/qtui/Makefile
new file mode 100644
index 000000000000..058123190307
--- /dev/null
+++ b/src/qtui/Makefile
@@ -0,0 +1,107 @@
+PLUGIN = qtui${PLUGIN_SUFFIX}
+
+SRCS = qtui.cc \
+ dialog_windows.cc \
+ main_window.cc \
+ main_window_actions.cc \
+ playlist.cc \
+ playlist_model.cc \
+ playlist_tabs.cc \
+ filter_input.cc \
+ info_bar.cc \
+ status_bar.cc \
+ tool_bar.cc \
+ time_slider.cc
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+# These overrides variables in buildsys.mk and so must come after it.
+PACKAGE_NAME = audacious
+
+CUSTOM_ICONS=no
+ifeq ($(HAVE_MSWINDOWS),yes)
+CUSTOM_ICONS=yes
+endif
+ifeq ($(HAVE_DARWIN),yes)
+CUSTOM_ICONS=yes
+endif
+
+ifeq ($(CUSTOM_ICONS),yes)
+DATA = QtUi/16/audio-volume-high.png \
+ QtUi/16/audio-volume-low.png \
+ QtUi/16/audio-volume-medium.png \
+ QtUi/16/audio-volume-muted.png \
+ QtUi/16/audio-volume-off.png \
+ QtUi/16/document-open.png \
+ QtUi/16/edit-find.png \
+ QtUi/16/list-add.png \
+ QtUi/16/media-playback-pause.png \
+ QtUi/16/media-playback-start.png \
+ QtUi/16/media-playback-stop.png \
+ QtUi/16/media-playlist-repeat.png \
+ QtUi/16/media-playlist-shuffle.png \
+ QtUi/16/media-skip-backward.png \
+ QtUi/16/media-skip-forward.png \
+ QtUi/22/audio-volume-high.png \
+ QtUi/22/audio-volume-low.png \
+ QtUi/22/audio-volume-medium.png \
+ QtUi/22/audio-volume-muted.png \
+ QtUi/22/audio-volume-off.png \
+ QtUi/22/document-open.png \
+ QtUi/22/edit-find.png \
+ QtUi/22/list-add.png \
+ QtUi/22/media-playback-pause.png \
+ QtUi/22/media-playback-start.png \
+ QtUi/22/media-playback-stop.png \
+ QtUi/22/media-playlist-repeat.png \
+ QtUi/22/media-playlist-shuffle.png \
+ QtUi/22/media-skip-backward.png \
+ QtUi/22/media-skip-forward.png \
+ QtUi/32/audio-volume-high.png \
+ QtUi/32/audio-volume-low.png \
+ QtUi/32/audio-volume-medium.png \
+ QtUi/32/audio-volume-muted.png \
+ QtUi/32/audio-volume-off.png \
+ QtUi/32/document-open.png \
+ QtUi/32/edit-find.png \
+ QtUi/32/list-add.png \
+ QtUi/32/media-playback-pause.png \
+ QtUi/32/media-playback-start.png \
+ QtUi/32/media-playback-stop.png \
+ QtUi/32/media-playlist-repeat.png \
+ QtUi/32/media-playlist-shuffle.png \
+ QtUi/32/media-skip-backward.png \
+ QtUi/32/media-skip-forward.png \
+ QtUi/44/audio-volume-high.png \
+ QtUi/44/audio-volume-low.png \
+ QtUi/44/audio-volume-medium.png \
+ QtUi/44/audio-volume-muted.png \
+ QtUi/44/audio-volume-off.png \
+ QtUi/44/document-open.png \
+ QtUi/44/edit-find.png \
+ QtUi/44/list-add.png \
+ QtUi/44/media-playback-pause.png \
+ QtUi/44/media-playback-start.png \
+ QtUi/44/media-playback-stop.png \
+ QtUi/44/media-playlist-repeat.png \
+ QtUi/44/media-playlist-shuffle.png \
+ QtUi/44/media-skip-backward.png \
+ QtUi/44/media-skip-forward.png \
+ QtUi/AUTHORS \
+ QtUi/index.theme
+endif
+
+plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+
+LD = ${CXX}
+
+CFLAGS += ${PLUGIN_CFLAGS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../.. ${QT_CFLAGS}
+LIBS += ${QT_LIBS} -laudqt
+
+%.moc: %.h
+ moc $< -o $@
+
+rc_%.cc: %.qrc
+ rcc $< -o $@
diff --git a/src/qtui/QtUi/16/audio-volume-high.png b/src/qtui/QtUi/16/audio-volume-high.png
new file mode 100644
index 0000000000000000000000000000000000000000..7b0a4de4b81c7d100cce57d2cffe0e75b296d539
GIT binary patch
literal 709
zcmV;$0y_PPP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10zyedK~y-6rBgv`6HyTU=DlQ>5VxsF*T#ktNzjlIFab#;;-!b8
zLJx%y^im1l1P?{9#FJw17nn=0g&xF1NGTK#;<3H7Cb|$vY0(NzYnF6r5^Kqh2eYLu
z9x8n>@R%9C`QH1!A!f#Tj`)vWT3K1STCdkHpU5)vS%R4PilQhbUDw|*v)8Hpi-8M(
z=lEp9Fowh7 at WWUv_I+n(=YA%WxeY*`W<bpBNvG3y{eJ&TX4aUQ8jVIE6bj`4RI}Oa
zGfmSL-EQ}LW*%VXzW}Cb4#(s1$H8FmIT3x9QWlwcz%UHIqA10QiHR4wuD_E~E>2EP
zP6PN<EEcahPw+&e(MPMRt4}sJH`B~)5|If2nx+Y#&!;RbEZi9z8~fPpc0FFNcN;*v
zP$)zk6 at --XCxCANegLqDXdeIqfq*$WI{Lx3?XIe-y8!l@&88%x_QuA>007km04|s7
z0DyJ$YeX&QUaeMJ0Cqc_&H;dZRaN(h=%BB!@0Y{Cjzl6>55Vd%XahjGT)wovz8)VO
z9NenaY8QnNEh(kfw(ZXN`1m$}-vU6VR4Ub$mX^wMb8}yOK3_u!u at 3-32udcCwOlUu
zwNk0v2nK^&Yiny4q?Da(HoFbrgjpmr_Zx<hE))uxo>}Pd at GzB1rJf2QUeC_XK9Ewr
zO(YUC%&Z^Dcq-hE#*RNs)4Vx9KR-1zG?Z6W_0{t7^1a@`Gh10$mUVq(WMn3v&rdOP
rzf(Ia0GL at co6TFy96p|>^RDwBx-66N2i7`600000NkvXXu0mjfo`^D@
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/audio-volume-low.png b/src/qtui/QtUi/16/audio-volume-low.png
new file mode 100644
index 0000000000000000000000000000000000000000..629da844f8e8d2c6ac8c61ed86accf7ff762c5dc
GIT binary patch
literal 577
zcmV-H0>1r;P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10lrB@K~y-6rISI6Qc)Dgf9Jl(kUh$3pk7Z}xHG|EpwL-ct!5>R
zNegN3%2jK>gkQvEf%FMn2!@)VF)@<qV{|Oio~K3ckxfPnbKt<`aL(`i at 1J``Rk=!-
z%QTC~U;UQ?00$zH{2#yuu3y+JBH{u8 at K8jYT>t at M#bWW9=XtMzn}AHGQ?FDiWq`-P
zDX<0}ZEq9b_aEf*`RBgx?~g{Km&TYOaIM$t-N<Az^<*;n)^*+9csx!410XFTmZ}B@
zh^5o%SFKj7G8_(%RdpsJGe8{2G4XhOuix(<6$*t}sA?IijYn57mSuebJ_4VBxrm$t
zBoc{fE|+_=*=&L!2qIq$pb@|Zux<N0FyAt58J)Y`?h=@|uKOb_{qb-Nut}v-^AIo(
z6?_F~x7+)J!QjAk-IK*)u?-O5EK=~T(P#{s&E}oSWMV3n%Kg=9bq=UyStgs!ekhmA
zC$(BF9xiY~$k{KPYLvFB-tKfd$Mt&sg{nHLYS!!ZlWMh^1&)Bbz*FEbnv)%WVGp<k
zeBScJ0QbW5fOo38j6Ap)tL@=X<pvl7G2neP4D3|!&kzw4!hYAT`kj9QTCux+y503g
P00000NkvXXu0mjfU_Abd
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/audio-volume-medium.png b/src/qtui/QtUi/16/audio-volume-medium.png
new file mode 100644
index 0000000000000000000000000000000000000000..eb1bc0d071fde6cfb53d253c7499324a29864ed0
GIT binary patch
literal 632
zcmV-;0*C#HP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10rg2lK~y-6rISBvQ(+Xwf9HLZ8#JvK?-0^b$}MzA7BMcliQp0k
z36e!xoph+;AUG<-)z8pRP$<-?5QO01M<^y5Xh at _;ooW+OlKwFy$LWUn2etITGo1H%
z&X4mBM^u%IlsQjWM1ITvFTen^kx1l*h%EgJ5C!7XnP#);FE1}Y&FAxRAT1&je;Qzb
z`0DEF?fLon7r+(3bi3V!VzKz3-EKcQJw5e3&jYwNnNn5hcDsHilX>j>{!0=0V6EL&
z)nv2TTyPv`yHqN at N+c3*thH~~*46^xE?`v^16)q0(+_uccAo9+?X9S4M?^XRGcz;B
zbzP at YsoW|Q3hzgw(Iv-mVt at c{xVEv at egnP$Ux6bL=>yEo%^e0o at NPUFk7BXd0nlqS
z8i{B$$~1sTByt8Eg%XiL_{H7b-2rfLa&mG8^cNQwCte5`r&6h-UjWAd^?KcFx7(Ry
zGP&PswXPat20;)EhQlF1F9aM{DwWUGYPGhpvGLJ$-9uwcAHZ5`ve|5_TrPjA*X!4P
z-`}s*YTp430jO%IsH%F6Mq_1tef_?w&Z?>z4u>~$x!iMO%<HYKt$VKP-T`vq+%zDR
zqpFFi-gG*h?B?d?qf)6<0E$5TZ-76^^m;uH$N@{!o}A|zMZ~D;_@}pvp7RgD=?&!o
S-m|3u0000<MNUMnLSTYlr5QT_
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/audio-volume-muted.png b/src/qtui/QtUi/16/audio-volume-muted.png
new file mode 100644
index 0000000000000000000000000000000000000000..f3e3c647d2090bc75f8cf58a365fd89984914e07
GIT binary patch
literal 527
zcmV+q0`UEbP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10gOpRK~y-6rINpk6Hyd}zk9>N7Be<m*ozBxyNH#RB7&@T(Za?~
zK}5n#>SXM6#zNLY()a at w#1Skk{TBqcvsgtY0XwmnV54u2MV62aBSby$ig(|8-#z!f
zYm)dM`QKa~jYeyL{WGAh>%F2V?kvV^l at iLb>{L~C#mp|7*|iYDcE8_0Xmyb1`DRfR
zR~M61RdvJ6UIQ;BeRuaKM;v5X=5ZWflC%Ll1jb2{oG#0<GairkfLFjh;Fp=bkn~_W
zogNzu20t7iilV!c-U82njU{L2fcs{)3v4w_^AYI8alAb*!OV`g)!yxPgPDzhlOcr9
z0Pem9G)>c-Y3;$XB-zsbNY|Yi?rYoQ!+*aCd~x>^03n2*Gb8?f4oK5<SJDMZ*MV<9
zv%vWPq`+-p-`!6Ep|0zFXqkgN&o|xuY?36;VKxJk$>f%#N0Kg@*;C*kNs{xefHq}W
zwjM>%4zOcpT{GM2^?ILH1{^{>ilTRt-lS>zczz&h<ux1**Cp9vY-I<3(r?5S)ttN7
R08an_002ovPDHLkV1l9H<iY>|
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/audio-volume-off.png b/src/qtui/QtUi/16/audio-volume-off.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5378493529e54a7671c8289f81e5623a34c2b5b
GIT binary patch
literal 495
zcmV<L0TBL)P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10c=S`K~y-6rIWo%13?spzcagn8b!2F5sX?0(ITL+u~!HvR*OD>
zbqZf2uagG|zCs#75Y%YQHi2F8gApBz%;FkXBzWOAGjqRt?wJ``Yxz%@Ne)Z;aeg8I
zuqSEjFMtQkj&+u#Rp1 at ik(A2<2$&9n;5eVpUyVW5fdk+Lcms;bh7Ztcwesb1`6P;>
z#b&d4VT`#4W+e at PeV_$&fdX&`>`L;iweLPKQ!14%+wJz5lh~2eNp)WW7F=Nw=sC3u
zK*s>a^Slsv1fGFdQWwCE?)U-70fW at o)&WK%_`d%N#3|Ey8RjPO?co^UqfjWs4iGy9
zeFrkY2G9p)QUC!_qF_*~)o$zc`cfE%rc$Y_4Tr;Ss!0Sq0o$%Y&OsvFoavlzG#Wv*
zT0OVc&benUU=uh6mVqPSFsV_-UzlR#e3<gY04pxnfNN`QFY#bJ-qOWR<p<DqKHMb5
lK&FCULy~c at ueJYv=T8-Ij+dLsYa##u002ovPDHLkV1g)+$hQCh
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/document-open.png b/src/qtui/QtUi/16/document-open.png
new file mode 100644
index 0000000000000000000000000000000000000000..2139547d213398c690ce174c863453e82021279e
GIT binary patch
literal 585
zcmV-P0=E5$P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10mey0K~y-6l~X;7+dvR~yI#p~!p6zPAGiu>R5+wpYcQlq;UWQd
zZVj&U8}bKC3X{TW-K0q&+{Y<`1FD>uBUKQG4hIa5&L^!Wg-42_<nr-gSZQ|V&70j>
zK}29E0A>Cr01>Z$1`&aX&U(GxQ_HeumSxQ<mCCE>boz*h>bIE1c at V6iUaeMVTI&Y$
z3LykZDG$Yh$K&zFah#Wn#o`Tsy#fH=_sfI9-~)g=|Dc#Qo6Upea#?d6XD^7zY`5Fb
zgCKYY;P}^`PmrxvYaRr_3kARc at D0FaK0+xKH=E5c at 7r#-wJ3_txW_#JQ}NF=lVs?2
zyYD>DdkY{*tB%Lxhm*<VaV`fct%lRJWmvD*R{-7v*t5%6tycHaIL<i{NGao at 0`{Tc
z(`j6~|6c^AX(qoVFbv}t0`~ocQmK?FNcSaxq|@nKb8ndmA(C4NA^;KRBnrU6b=}Xy
z;jq5j?IZw<Mx&b6S^&5Upqh3S$FT$uxvm at b`~3?52a$VBWt?W>ywPYp3B&Ndl(Jb6
z at l`4H#rOT!wrzjR&VX at XOXl<WrRRCE*7{Si4aaeAY}?L;F0UXD6F`g4sE80hW&_^=
XSC7)qWU`e500000NkvXXu0mjf5?ljK
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/edit-find.png b/src/qtui/QtUi/16/edit-find.png
new file mode 100644
index 0000000000000000000000000000000000000000..267657225804ae635996f799bf4f0e0d124ce7e2
GIT binary patch
literal 643
zcmV-}0(||6P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10su)wK~y-6osvz65^)&DpT9GXvxALao0*6-VnOK8r9~t!;YqN<
z%btQg1R;cnD59%3BQ_|MrGs4zL9mkt4|)iUE)pJ+p=6i6WkV8#u#8OG+o7GsHKmUS
z9{wM^{NR0`mk|+`hyx%1FadmDR$$4t at D|GDvZ^S`J-6HaBpePuC>D#C0f;LJL}YnQ
zRn^;!u_1t6o6V*H*kz1;P!#1p5jp2-k8NF8KA*n=U=Rw0UX at Cvhm*<VMx|1 at 8;wR^
z0(hUvWUdhrw+bN1vb+u8O|@FxBqH(X-`?-{GaSdg7De$n5xG_Yys|9s1OkB<M094M
z$P<gjwmFV#5Yg#HfHlNJkH_;>*Y#7Hra2Z98I4A6K at h$G_$@LEU?dWWJtAV+Z1y?;
zF916LS2CGQo2KbiRdop9U=hF{owHi4_I5ZNUeq)#BM3q&7!1DCbv<qvh9AHr5{Z1m
zul+b7Hn&JNUDvM`3WbeUt98yWjCGFVzNORYea6_2PN#E8lBCb=cKc~6mD;!3nFm-p
zKby at ijK^cA-|s(=Bx%nyO{dT2+ni3PE{DTG-EOyZ3|Y1uOT1RE*KhJX{|LY{Q51K2
zy<TKK#=o(z(P(V(JYNLxI3ADRA|m_006;|R&1Q2em&@H53<euSv~&i4k_W(903QJy
d{tw`UegbQ#eeY_WZX^Hz002ovPDHLkV1l5)2q^#n
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/list-add.png b/src/qtui/QtUi/16/list-add.png
new file mode 100644
index 0000000000000000000000000000000000000000..4ae4c7d6dab49048d6e654b75043559f97763ff3
GIT binary patch
literal 463
zcmV;=0WkiFP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10Zd6mK~y-6rISHQ!%z^0zqDy%Q>d7geNZS05qHIIgq|R0=mlK$
zAl-H6(#v!i?6wO<Xvr(hLM&Q|QN~T8FWR8cfq at z3pa0Fzys<=teXO!qH(-|$Yppx;
z`Md$(`~HhkY6<)vS44Js)APJB5CM_rd1DcAcVSB<xURbZG@!HiPYD*#$YRH~?RQ`c
zkj0LHea+=q`4*xm>hyZOs~oY}Y>tv7IR$VW=dRUiJ?6F9Y<8`bS`;Q&uh$209A6r*
zB>4nMl62!ZJ~Oa4N~xlRdc7{dszmD6Ofqbdpxti2jYgx}JfBXdhhZ2V1N8g-)nG7q
zGO=H5#!9Lp(#_ltf?x<tfJqPpLlN<fdNuDex9|ZxWN}k#eV&i5wSEScKcy5T{3_UX
z%J&-6GMrU%OqDcEFGS=7z_P6STCEnc<13dD{M+`v#!sWowyTVD1m^$%002ovPDHLk
FV1mF1#F792
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/media-playback-pause.png b/src/qtui/QtUi/16/media-playback-pause.png
new file mode 100644
index 0000000000000000000000000000000000000000..993d3fad541ec8474384a57fec1393f870cd32e2
GIT binary patch
literal 380
zcmeAS at N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<Z~8yL>4nJ
za0!Ai<Bf}ULO?;u64!{5;QX|b^2DN4hVt at qz0ADq;^f4FRK5J7^x5xhq=1Tkdb&7<
zSoCh4ywR`4L7;7atE%)9Q4OB=2^mwv5B!MR(;i~iu+1byWLmg at 7FXA9)%L0zI%zxa
ztTjB6nP&X|jQMYI<!6;?-W9W#F;*^I#*lb#etNBXLJ{L46JPn;+xD`a`22@=fzIjb
z28+J(&`?|E_H2f$CTHhf`^C6m-Rts(b+6|!v?W%s#>Fr!nPPi^*(Gp`$+v0S-r4K_
z*k`XRJtZi9S<MC$a|aGX##=l(47r*6nfk6BoBWq~@!!p?=Reo!usCkmlmJxVRe81P
z;+%%$K#|{tGSLkxo at xy`r=uDSc)lOtQqq&T%quYCdqz>lr{hV-S$_oQ>^qh(5EQdU
T*2-QE7zhlWu6{1-oD!M<u_=$V
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/media-playback-start.png b/src/qtui/QtUi/16/media-playback-start.png
new file mode 100644
index 0000000000000000000000000000000000000000..687781f2528eca784d8c21036e4dd3bb975e2407
GIT binary patch
literal 437
zcmV;m0ZRUfP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10WwKMK~y-6&67b(0#Ou&zc)_JVi-f5c7jCfK%_uuA-L-&)GD{S
z at dpI%TG%>fl|RQ;Nf06k1%b at cAX03CP8*BKu~OW0;H=)cANSpNpOM5mvev3z0N9vL
zr+L6znjk6eE!TCgeBW<{VVIY+Id`6L0^oVxIdEr;xh at uqr;@fMSw8_1Gcd+Pz(~?t
zx7%$vjuX^swL>7i%nV4SQV}o)UVt!)qI3`h7ujs~tkdc20?x01SqGDtpMl|MG}<ed
z%a`qT`v5SXd3yoib=JW*6$*tx5Cnr#sq_eZEl&avy8-~d?~hxp)<d;gy#;Q7D4tIM
zEX#_3iEZ2O^?H5SY&P#RnM?<Gn$H5sXUyetCzVR2(eL+<CGD)b2X3#|JCd|7$^NTY
f66W81rj_*pj=A;oOL!k`00000NkvXXu0mjf4_vc-
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/media-playback-stop.png b/src/qtui/QtUi/16/media-playback-stop.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec322be27fb045f2a42021c745104cb1065e10c3
GIT binary patch
literal 327
zcmeAS at N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<Z~8yL>4nJ
za0!Ai<Bf}ULO?;u64!{5;QX|b^2DN4hVt at qz0ADq;^f4FRK5J7^x5xhq=1T!c)B=-
zSoAKv?9bKYAaeZU`p at kLnJXIe1od`1 at AxPrciNhz@j{f1Gl%191;<l47e!PrN1VCM
z`{!P}`G+`@K4nGKrd^Dtm8az|Fz(pNFfsM!s#U9&uDABR92+ at pw)!W&6T8-l=iXjd
z>u}kGJ>fM|$KxL?GPMn7_q<}h5Eb9JnSX<%xk8IX!#VaFJ<=0`&iN%6=N*tR<_7XO
z{xt<<l`+jOWO5D^iJkYnT7H6x=ka7|#tyaPOBf$BH^}X%Vg9%7LG~VIJ~i9AgQp~I
Qfc|0dboFyt=akR{0C{P4#sB~S
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/media-playlist-repeat.png b/src/qtui/QtUi/16/media-playlist-repeat.png
new file mode 100644
index 0000000000000000000000000000000000000000..5a5e6d6130dab997d49af977079b25367e457284
GIT binary patch
literal 555
zcmV+`0 at VG9P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10jNntK~y-6rIRse6LA#Ae}By#O%F at 89wgy}4B^0<4xx(>*CS*I
z?zf0*K=*8&DuR<^Aa%RlY=Ml;W`|;i3fW4MgP0RMn%11 at bGg<wrnQg<Z}@+F-^a)M
zzo$fmW$NBiY9KN9RtvEC`VCyhzDj;rDwSSzyWQ>E)cJh=pw(*a13v&%JOe$QPS<?j
ze+ at +cNuZ@tsZYb<@EtI{NU#<J!KPstN1o?>&gF99B4w}Fd*Hh6%OD6gfi>VeB7%sR
znx^g9w!JGN>oK;d*KOP0)iiBSL`)I6_6w(@(dZ{|eoOrGm~(moTs1gTN=<JN8ufa8
z3)qM`Xa5)|r6yq*TE6c;0!-jOpbZ9tCzfTstyZf$<MDVU3`0vPHJLY<IF551MbT;|
zllf>E#tvYW%jI%5oBh!5_n*yXGv74L_fZtBI*xM;OyKVxoHQDZL(lUPolfUlGMNm4
zX{}aE=(_%;*=#=6b$wQ;RC>i?@t5nmhrkKI{FFCD<f(|{L`22C)o!<66$*tnBJw=u
tTx!%Ek0}WhfUm%{9l5K)jkWYO{sAJ*+2eg$!SMh9002ovPDHLkV1gwt_7MO8
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/media-playlist-shuffle.png b/src/qtui/QtUi/16/media-playlist-shuffle.png
new file mode 100644
index 0000000000000000000000000000000000000000..a7a88a0acc72d48a37215dd4b9879ed6e4e386ba
GIT binary patch
literal 652
zcmV;70(1R|P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10trb(K~y-6y^}#`QUM&szqhBpJ=8trrS7Rnhm{w>65gSU!*&=3
zkwjf2 at G^#%h#1sO4?-OjLhu-PTv)5=#gpt%bns>&1QkZ3De5riA)Cvu%ZeQuYz+Fr
z|Mc;F at c-ZwNa8HaoXLHffYE5A0&oHlPa7Zsn9F9f3r3^yMJyIu2B7>^NeUz#BsG%r
zBvq0olEzZ0<aan6k7ZeYZZerR0lWwB(QGz9EtN`sl7az%>~uQU`u+YgfM2pKH<y-{
zUh2BuNvG3KNY1LN`b`wYNw?eG1F+}ydgX4n8wBtPB&BFH8g;wfcU>;meNhzGL!r<e
zgTe4hmgUV#rLsyg+-NkeD~ht7&*$%v)JcjY0g at m&OVUDeZaf|@*zNX50Lr;sZk41$
z61`sUV!z*yk+dCpKoT<m42eYIimvN7gTdf!o6YucFc|pb@%ZbFjSZz%tGNJJip8SE
z=ks05WHJ{3SpRe=kTkp9?v-}C9R at J<csyT|$>f*C#l`JNBywvyom#9`>t{g_eh!C2
zRS*Q1$K!chuh*Yxnzn5KFs at ds?+y+QzDtrc4Fm!^06qZtv9+~jNu^Tr&1O^G-`_U^
z*d at 6uNz%D;xvVFX$sHX1=N~7LyhQS9tJS)pD9VFEp|CQUOu~m6gp+Qe)9IWid0Er6
mHvoD^J2+9mas0nA9mj7(JQ8SpT_6+y0000<MNUMnLSTZhk{q7^
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/media-skip-backward.png b/src/qtui/QtUi/16/media-skip-backward.png
new file mode 100644
index 0000000000000000000000000000000000000000..25023bcdd38e2d86ffd3ce50f62a940843dfea0d
GIT binary patch
literal 545
zcmV++0^a?JP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10iH=jK~y-6&67W9T2UCq&%IyXQ=z{6X$^wG!RTNX!A<Dm>X1Q)
zA|xSnFiWN)6arm4M9A(M$1H(BX@*KcM};6Q*2Sd-sZm-<viPT`%exXnrX)ko_~SbV
z?m1jV5|5F7l=~?IGyn&{i+gT-0Ms4kHC_|2>^RO*Fc^G)E5ui+RN}E%Y!ASq%RJR;
zbv+u5?gLl>0FVU9fQX#<{r*FeuZF|nS|}9ypp?3>ZTpzyD#>6Z5_zYTYKX`g$pA?#
z%-^E*NJOrZ$>e6M)!LrTW<CG|5xGpK)9HG>{&qT at E&=$fwf=2<%AGM_+xEd^GFf-K
z7y>Z+3V at dY1_1s6fMr=f$K&xw0GIO>lu|dTRH{)Z6h4W_0Kf>qC?1c0D;A5VUaz-r
zm{RKI?g|i*>u$IEt6VOBZnxWCGnvc}0Ha>7*DsYy=bcXHOFp0fuC at LnBG>ahOo`!e
zcrTGiydmk36q1Qrt+tcP<?<v~NGg&W&1Q2eo6YW;5>3DY$=4*4?xEoxk{cwgTg-Bq
jhvdA(2kZI#g$L_D!DG<srKPYb00000NkvXXu0mjfm$vMu
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/16/media-skip-forward.png b/src/qtui/QtUi/16/media-skip-forward.png
new file mode 100644
index 0000000000000000000000000000000000000000..bb517e7410d630c173da31244f68032d6e69b836
GIT binary patch
literal 543
zcmV+)0^t3LP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000UR000UR0oc(#5&!@I8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10h~!hK~y-6%~LT*TTv7}?_K|IEGCc|<V$FVkU+8|I0iGh2ysgW
z35C)rIygxd5l0uZxMq={ql-|?)Zma+h=T?*_@{<YlTy;!<%e)w{tqfn>fo8)JNMqh
zyXWu}NxTO7Rnu=NpaA%u)Slx2;3I&UrvkxPEVj{TG@<}ZmkY$>@%37*mH_a<8 at 4QK
zD-a0m1Na00APJHo5&5o^I*&%9n<VE*&YGrqsFb=0hr>Jlet({1(C_!}iO4a at 5J^l;
zo}%@y at pwFK+xDtq7|Ypg_CQ4Xj^hlv-R_EISxc!@>PSTXX|0EoJ>3{XrfF`EMx)OU
zRto|64PgAhlUV?N4a2x`9A_86V3LAT>OX)XfT7RlyDgW?C&^^;(&I#AP%4$`nM~%~
z?R{h-MC49u{ij$gUUfR1AC*d_-s|;l0St4w+;zL%KC4!%r?zeX6p_10CZ37;eEwUj
z)%rp*K~j+n77B%8v)TMgGDT98^rzG5)kq|==9%aTm?V=Vr`$W-bHc58oFchEa?$Jc
hOnfok&tG^k?g2Sa(1fQ!_s9SM002ovPDHLkV1ka7 at bUlv
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/audio-volume-high.png b/src/qtui/QtUi/22/audio-volume-high.png
new file mode 100644
index 0000000000000000000000000000000000000000..c1c00fa5c97f7af376d34ff2c8f5f2f1784ecac7
GIT binary patch
literal 976
zcmV;>126oEP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H115HUpK~y-6wUkXvV^tW2pZ4C~QsieK4ArV|DL4ov!G(rECIn=x
zKqhH|Ng<iAn3bIbHzcekY}AE2LtLnl2nmY{6E`L<YD|PMnrawu!T^oc^4BnPjbfdt
zQ0|m|E~ZSHio}8VChu9C^PT6MyywRvBK#k+o^iekoI8$l7O)Cbb#`|40M37mipXiK
zh)8u&QPDWC<@ft9i%4;9&1s;ji0DH at L$5V8HGKfwv0AP3 at p$|~cEJ<Ds)#%<B5o0R
zDyQEnB6 at Lg@y8a6B^nBau2fc5ehJ(zD=T|nL|n&#Eh3_cNTG<hOG`^XR21b~5vk7I
z>D1KJ%jM<eUjVlY3kyG=n3#AIxCtzcj*ec;G9H7AmzS4c3<Ls~0)fD#f`Wn at z)!%k
zh+H_ at X-P@RM~b4{oSU1wYO~p9fgk(&`mQxJG<*Wgx?Ha7B2u0UuCZFJ-vhs7y#&ky
z^I5PO3Wb_AP5Ta5YHVzL*XQ%S1AJ3aQSo+1N5^&GE4$r3B_hv>2v)!X*fN>S9`JM4
zzXE$%0~~t2-rbRrk<WnLSS;q$bv**?CzHu at Znt{_I7p|{1%NI89w%~OdwF1h-+Vq_
z6nJ2oW=T&^&o+=UP4j$rclS16W-=Kyd%qtwS>-~GRX7~p1Cpw$Cgbt=0g!Sy9LcS%
ztu$cTY_^9-wNC;r8yg#I1|HPa)oqQBkLy6Hrlw{)7z|berpx8}6G$ILA;3dj*NqdR
zP-kXlo?c&He+fu-b#-lSY-~IO?AO-T?(FRBIDrFQ*Auy5fZtbFS63pD$Vwy<S at HY*
zu{`jh-|xRaI5>E#rKKg_-rjy-7)CRY>h0~lmq;Wk0kgHWH4glh8^wKx!*Qd&zP=Pt
zrl+T0 at pwE33kwS>kODHm=H%pL)G&<ls;a8jMdV(8fB)TRG+MI1zh9{+N at 8GOU>!&T
zCqC(mBI3(?(u#<@;Prana=Bb1Yinz7sH*xY at ZRw7@HG*sIjXgs;-lAqS7Wi*`L?#U
z2E#CH9*@UZTwGkzG;J0*%+2^oWCCBi-R at gXr*qeCxBn3g2IHEh{cr?5DT at DMEuBtZ
y4u`{6MWi-={4`PI$MP(&$)f{)th0juReu8njd&mQ=-5&K0000<MNUMnLSTYj0=aeo
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/audio-volume-low.png b/src/qtui/QtUi/22/audio-volume-low.png
new file mode 100644
index 0000000000000000000000000000000000000000..9f3d0f19097c014678e3d0787eaffe508017ea68
GIT binary patch
literal 741
zcmV<B0vi2^P)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10%A!-K~y-6)s;a at 8&MR6zdIeH5izk?Dk^D|Xc`oBQ(8=SLKaiR
zzu>OWy_9b3Z*bwd0T-!pFDTvF76XEXO0lh0O*d^rLqroZVspEgXBnbmE4t`~3y*oj
z$2n)XcSKdWj<T+WdKF+1312x_MD7A3BGPhYU=axdH%t$Ui2M!M1|mQ&;8$Y-jUo~U
z9s*lH8E6Ay=YcJt5oiV?;c)nwZQHXzySZ-w?qo8V!M?t}2+#y1fOmib{UXxjR|e3!
zzP{cyGc(f#kWQx`SF6<_zy$)vZg(gYdRi`*2bY$Xo;Z#Zab33?$OAu(fDT{>098d*
zdo9b#8Ead>8n6s3t7^Zh1{N0=hXR4XTVSoTv-7#*I3vIq5I4%lfcu7rWg at U^wOR$(
zH2njpm<BjbrBbEI$;p>Mu~;m2CzHvlxeEb%=G=T%#w8!j-zQZVA0Ph=>>nK+wK|UD
z`oJY~K9w<bkh4lwR#qy&fo<Cd7rgsV;PCYH^boKgi^cK_3k!|rdC8~-IEe=fr~${(
zX!JYhN6|1pKYx3BdwUo-7#$tm&E;|@w)cGCKjOq}x6t9?;iG&$-vTf-H5JTevmF4c
z`U3a@^h``lq&7A->`W%}A(2P~T-UXLH$Xpd3wW=pJN_v4g27-m9*>6sYi at 4t-oU_s
zySln+8+*sVZaSUbEEEcD$z&1({c0Sy;|<BTdd2nC06YM00<ZAK7Q8_Tibxc17?yz%
zys`hNs-G?bUsxj2jJHdA at IK&c^}#N^-Bh)L=inExrgaK0tr)<p$~ILkp1S+*{&~Lv
X0qE-cHwY<f00000NkvXXu0mjfJk~T5
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/audio-volume-medium.png b/src/qtui/QtUi/22/audio-volume-medium.png
new file mode 100644
index 0000000000000000000000000000000000000000..c4d0b3bbc613b9f0e4667051c78b331ccccc410e
GIT binary patch
literal 877
zcmV-z1CsoSP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10_sUbK~y-6)s at dn+h-idU(YxBev=eUY_J`AaM8GG&A~7t!LrG~
zs>D(P0reDUZ at GB%A82<LJZ%LJqL)c}>dix4on5h#(G9J{X7NXrEg4&BG1w&4e0uPk
zk!EqFr9Jcm at 5|@;JTKnQhv)e`N<{b=p?wtUhX5<38a^c03OEhJxCmTQO4Yq9Sk=fG
zK+E{}crX+SodYa at Un%uwt%%f;E+U_ch*w0M6?v<OwAI(w-%?7YCMPF*o12?Mz*XRj
zN=7A26A`<J)QO1K<#K&zu~>c<kydlv5RtaIxw(Mb?Y;y2X0zFD&(6+%sq6Yx;0j=`
z2D{eQ)-J|kvCFYo?6Tc%j{{GDH4(XBo}kU?bbfEKSne+^EnU}j{T}dZPfyP^pU*d7
zy7p9pm56vXO?wEWO+5mZfn^iySXfx-HVoqd at TjY+>)UWRd=vPwv9a++Bog_`1P9At
z&1}A<R4N?;znl6CI5Y+DYH)Dy#l*zK55Tjnt*y^I9#0Z at nakxG{C<DItUFWdRy?nO
z9aez>{tk!3Dd3=3EILD>&>oO47K`Tw1_lb6rYXQ)F1A)|tc28zm6er4AZN8&bNl=I
z1t9NmIC8aW-v!(-H8s@@9JIH$Kb at YQ_5k_T*4Dkn#YLl3DhZG;7i+*VaP0ATvYg%u
zJsyvr-`?K#1G)bG{@tCOohIO=*X#Wwkx1C8&1rxD|7>h*Y$TJ($H`>!@#yI2Ru%Yo
zWMm{4jYfY727~*3eSL*&Hroy4hlhtVo12^E-e#*?@!a8X#5+1V&H~!}{CvRY^A!?_
zgcT^7+MSu1NoTX!hL)C=ArZ-pjg9@;+1YuJN~K(;!Au#fPMOC#&<nVMyTCz3zHMk|
zXmEXf-M+fInhFF0`AjCG1Dhi9<X^%mv*Q0`6Om9losLE#k#9J87+;r7mUWurw}lS4
zbzN^dIy!0weiD&4uHE~BPd1;7%CjQ!>_2Ot+ at JRv6DqEwcVOeD00000NkvXXu0mjf
D)H$8;
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/audio-volume-muted.png b/src/qtui/QtUi/22/audio-volume-muted.png
new file mode 100644
index 0000000000000000000000000000000000000000..d6b909f3567842276b272647c2c6b565299b138f
GIT binary patch
literal 663
zcmV;I0%-k-P)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10u)I^K~y-6wUxh%6G0S!zqhjlJ(DZ!yh1!I&N_E+c51Yg!#_ZT
zLri5PCK3yUH6lXJEC~r>rD7$R<{AqtqlJP7MG!>r7b*M$OweTA%-BpICQ<KV@?hbc
znYZ6Q9=mVF7{e^WnTd58;!>%!GIepWSiGjSe!8)-u{1Stp-|ZCIL<C$r&8)(tyWY2
zEiM*|S6tV9-syC103U$WX0v&5OJd*mFZ;g#V0gb$smwc$lK>VXkw^hp2Q=W7%jG@&
zJhu<|e11nX8r^4?IeWuMr6O`D5{aw_LGVUIP8wrwi%1<vXsu5Gw|=WQ8jZdN-q~wJ
zn$PFwMC1%`xZCX}fSdLx0W<)#*2l-S;=rHU0^oVxci;kmh^!f7o>`8INW=2}apHf5
zQmSroS!?~$a$IZOu)HvlI0ynYW_#>R*lxu~ExvMHxBta8L}c0W*Ky*vf0I_L)p?)*
zAR-TegO(d25(hBGd>j$SVzIbVYEdb*2;3PKr&6hJB61(7i^wBm%vmdYY>ZhMcpxzF
z9w(E at pTHNpJnj4bXW+=7Jd??sFO^EWjWL@*47lq!PN20;0Aa7!+wAAcB=gw!{R*(=
zy6$QihEIScz{_T{S4Ud0oycah=af>3FbpqQ>5F!|eSI)z;^~%7r$33v9Pp#p>z(pE
xFPw at Ppw((6MdVm6mwP{aHc^ka5;Obf{Q`fwwwCUvV>SQ)002ovPDHLkV1o9%BkBME
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/audio-volume-off.png b/src/qtui/QtUi/22/audio-volume-off.png
new file mode 100644
index 0000000000000000000000000000000000000000..f5a7bf1c380d2c8bbdf11d37f8cf827c9b33ab0b
GIT binary patch
literal 604
zcmV-i0;BzjP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10oh4JK~y-6)s;bO6HySyf8!==TT)C+L=jC`5lum;6a-m3_%(9&
zbNDfG@#HCod;-bUUUF&=ZHR@^r7G0Y+Ei?5#O`?5+2ye{G?w(>z~jBg&ilRp%+Ah=
zs&XB6<65Y*0E<X@=3o(N0-=bMW(F3KdBC&rTts9Vum{`+9svt~fj$LZ0o%X{PyrrK
z0t?^+^FX~^F25}ni|>HjIcNc>0dv3-uns8jL`3FNzk<z+{eJ&pyWOq>bi3U*<MDVI
z7`uv1X%$!lUIPz+UEt6zy9Y!rxEhAx`#6rPw*LWq%PIAMx+$#zI~INo7}<O`5BB3Y
zJ^_xHV5)j9A_HK>l<nH1Tfi4vXVDd$v!h8+#||CX$XRdL`a+HYPNx7*ZT||sWAibP
zesLob)c|LyV_I&%f*{y4czys`nJw9N-vJ*x;LJY-9}I`XK@>%UD2g^)t=3K+tg63(
zuOxZi2ZHphb4gZ7X)1pDzTa&$8YRH%bUH7a&E{FJ*SqP4r>dJG;sY=2>}Mb*DK!Q5
zvIr;iV-E;Pa{7T>{zc>&Ny&XQzY_3CRktn!Uuq(<K+;PBk{7tD4(!U^O;t}xB0C4x
qG^g;&iUF)uR#f%-g=hcWKkpAiG?H|_X+xd>0000<MNUMnLSTX>b^PoA
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/document-open.png b/src/qtui/QtUi/22/document-open.png
new file mode 100644
index 0000000000000000000000000000000000000000..eba48d7d34ce753430c8065ac71d55552b63bb86
GIT binary patch
literal 604
zcmV-i0;BzjP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10oh4JK~y-6?UgZa(?Ar*f9E;{`67ZuEU^QFBUqSWVPxvS#E$q7
zR$?V#V&Y4{#Lx+`w<|~$C|SBNv>+vwqBJ&1?D#R%uAHmWSg`V!PIqVh-%n4^@9va{
zU`QGJD~2kv3u^~(fg6S=27UsIEv&T!ieR@^tG!Q>q_t+S?V~u3Usr%ez%O70pt4dZ
z;DJ)=Gq5y*c7a=4z{^IXu|Jti-T<e?j1?dv@^%YglUBeF;3i-JX%4>Yy6&s-c>IE^
zHLj{fv)TMO8jaoor%FT=aNn}54<fPz(!T^-N~zs6O<w}Xm!%Mq^M8N>AR-I0b}e?r
z?@a-N!QhkUc`Nh#a5&s)wOY^1Vv6ATCa~vu2f%mMdsTU!_Yiot4Sd}Jm}gM)6wWur
zRRv$C|KMt1aU3U%qR1{YRRuealaT#jD_cx`-#^h>N14$aaMAeY$iWM(b>#d032+Wb
ze!JPgW8e``%QH|)-3Dm4+XuZ~Z)B$0>2%zFzyB0KM8?1o at C8Vf@q(zre6L=w?}cHw
z13cm4<}x)04z<>+*=)8C9OtDlYbu3#8U(>vx7)oFhT&le6acODDhPrzU|NXB%($r1
q@{}kBz5!o>qzd at bv&}%sgZl>>VYj3Gy>NU00000<MNUMnLSTZ_P6~Pe
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/edit-find.png b/src/qtui/QtUi/22/edit-find.png
new file mode 100644
index 0000000000000000000000000000000000000000..f9bc25ee02b2b3dae825bf486e0061d6cab3bc1b
GIT binary patch
literal 887
zcmV--1Bm>IP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10`y5lK~y-6wUkdtTUiu`zc+cjMoC^`BV*$$!GfEC7H1O?x~SLz
zg|U?pvu_8wQkgFLHl=PvH`SqwL>F$RSj3GB!_0sinbI!mAdEV;*bdtC|3eJ6ubHBK
z$;;`&Oi3j%ZJGYyEbif)@1A?lJy#JCzJ$~=eg&ujs(?cU-&<e at cnMUjrWCjes0)X~
z=hNwQtLwTE0FTG>q_(#9re#^b0GowP%1cCwt;#gbQ>v=o1|9<sfO`dd06bPz^|oo6
zr$nTBU+xE{6y341ySv-q_xmSuxm-992s|Gc82F>Bt1AOAJ3Ffn4Gp#0wrzMko~`Ze
z?F+iDrvSH7#WjXuTn3hOUH{#(taBoALPP>0qKinAWm)G#q0q0ul3^HEM5Lx%#l?$y
zP1CLew+06XFNw&}5(&oW=;%+tEltyIl!-w^_^PP*L-~CEFyOSbwEP34OB`^kt*vbt
zaI)EK2++#)t{AKYgTWoZSy))G*?V&PrL3&1yagOpRbO+!vnvMg>bm|Aa3&`wj|0IH
z at xhUiktV=tY-~&e*^dG5ba!_ at 1e}eHjqitthmQeapc?Q3N5;p;BWr7GX91_Dr{^w^
zDF^=GxdGAU=H~9j#l;3iQI13+k>5HyJC`&~%O#V^Z&Rt%4<fP&WasAQuD7?h-vQoK
z0t0y0*VoU)VzH*><>d%a5BLh3{tLYL at A!Vd|5Y>^y)!>Q|7XFUI|vLAbY1uK#Kc7X
z^z?Lab#?WyrfIHW7;pOf`?oqeI&!9I>QhrwQJ~i6^ZlL4WUc|vis7Zeuy^<001ZH>
zkdR?-tT$(7W?Eyh*ms54I$hVF+P0klp1y}4H17x4@!sCvi@?tXn+gO1S4HHQh^YGq
z<WqD%kx1O_>+5?2IKUIzw(CNn(2qbJl>d(_DF at t)$K!}der#;)Yv55npZBr%?S3}+
zJv@;}C|<AEO(v7o at pwE1yn^!0`xL3bN#H2(7jPet{{vi7pWD2OdIyU_zNp~1f;9jD
N002ovPDHLkV1gD5qkRAX
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/list-add.png b/src/qtui/QtUi/22/list-add.png
new file mode 100644
index 0000000000000000000000000000000000000000..637da1ecaef206064242193c1cf0d2aa4b47cc56
GIT binary patch
literal 462
zcmV;<0WtoGP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10ZU0lK~y-6wUxn2#4r$s|FmwU3nho1Ttshz2f=soF~ytD;Hiig
z!GkyTT56%$maZKS+m+dAn#4l~LYZmi>)&K1QAC6#ELwyL;3ROK62A90L%?SMG7&QX
zKAl-a<Ql7 at C~g3J at j*maL=?Mny^7N`9RPe=UdiP-GA}qu5(3cp=7oS`rY0Vr?aaJ`
z5r7{T_#D960_iNVOW_}FC<iM5>nMsIi0D+PdFKSB)T8jbVHoa42H6xtDfLQ3QuR*w
zZz9J?j%|$_0D~p&vTX>s!~a`-vIiVY0NS!FpLyIEgUx1h%af|AdJ&u*_LcM3>QeEC
z*7}}*xM`XT0M~qy*7^zi3g9JH&nZ5r=3Tbx`@Y4rj at uC=H+2>~v9a at Pb?medFtRM0
zloLEhrw`ocdA_adx)N~%(ZbSH;MKIqK_3K?w%DEb3%gyDyR-<wcK`qY07*qoM6N<$
Eg2-~h4gdfE
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/media-playback-pause.png b/src/qtui/QtUi/22/media-playback-pause.png
new file mode 100644
index 0000000000000000000000000000000000000000..0b061de23dd1d432529281a744a0c426982f158a
GIT binary patch
literal 279
zcmeAS at N?(olHy`uVBq!ia0vp^Vj#@H1|*Mc$*~4fEX7WqAsj$Z!;#Vf<Z~8yL>2?p
zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4<ivthz5Jr|+3#$mfQqJgx;Tbd
z^uC?y$aTnp$2ES*<?0GS{`=h?-{lr;V=lbh_jX2yv#iUD`z&z}&Q5SuTIJO{XH`UY
zmvlR~fRWkRtB>?QZ#lv=r}v)4b+gBUJDwGJ%QU#T>@p3x%H44I at T<h|JxlbT%-$o+
z-}>kKqiV(f5j8zZPbFMWU9Y!c3=GYelxO6TtIXRcQmA+0-PV_#<<I~7U1r`aW~b at A
SweB|1eGHzielF{r5}E)Lf at g~W
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/media-playback-start.png b/src/qtui/QtUi/22/media-playback-start.png
new file mode 100644
index 0000000000000000000000000000000000000000..a292db2389fa885728ce92acd74d9073738581d8
GIT binary patch
literal 555
zcmV+`0 at VG9P)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10jNntK~y-6&6T}tQ&AYkf9HBbs=0wk1Aag#L2;1~%+N`PLT0B7
z8A1keZKe(m4%vhtWXhs&{{ab--Mt at 6QAz_DZX^}@m4XPRDKvc?q#&1jZ*N*EzVIwB
z=lz|R!}D;AByOUt8=*#k&2_<cNdEya2aJJVR{;lYYynOpk#Otv`g0%$Bxfc|^2?I+
z1n2|b9mo0D>-C;Vx+m#Y!1+K$f!BczVA~k8mCxr_Bt4Rpi35&u#RND34ki5 at 4u`L7
z+x}3gR9*lJ!0lPz_;2uqj)9%&beiaPyYEt|)LYkep91#@F at OmOhy^@0#=MWX^sX^x
zE|<%F8Vm-XlgZ>hKKI1k*sonlJEPI)WuZ`b1I!0)cNOr&ah$_etJUrI`(J<~|8Q79
z08WFNmSvq+t5vVl=^SJ-nQy>X;A|G~#NQ~DN at Le`_lm`$#~(X}rZN^do6VlI+wI+2
ztu_W$fgcfbmx51i+dgkJ8vD&=^EjPOZvtDu^fD+Ap1g9oyzF`2Ye`Fz?!=Aqg at Swx
t at DNx8)_}cO8~Q2?eC_(@Kgj<J{tX};CnN1hVy6HA002ovPDHLkV1iA2?tuUR
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/media-playback-stop.png b/src/qtui/QtUi/22/media-playback-stop.png
new file mode 100644
index 0000000000000000000000000000000000000000..2684c825338ee2f6cfb04455061cb81c1db57638
GIT binary patch
literal 252
zcmeAS at N?(olHy`uVBq!ia0vp^Vj#@H1|*Mc$*~4fEX7WqAsj$Z!;#Vf<Z~8yL>2?p
zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4<ivthz5Jr|+3#$mfQl+TT^vI!
zdf#5%$kkxL!*ap8 at ZFp1KR*8JeDETs#7g|-f?fdw=Y{6ez6IuaXmAQjI$iOoFgf?K
zB(C<_15SscLy`x+u?jmV?W_p#{QP&@pF69Pz8=^b@!_IOjoZP!U6bNmPrkPoYtYFo
px03AVbWd(>={ft#HUCz$uQ&sX(yoP4jUbmYc)I$ztaD0e0svP6TV4PF
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/media-playlist-repeat.png b/src/qtui/QtUi/22/media-playlist-repeat.png
new file mode 100644
index 0000000000000000000000000000000000000000..89ac023d3f85a3766a514aed27033bbc86392b2b
GIT binary patch
literal 676
zcmV;V0$crwP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10wGC6K~y-6)s??%6JZ#~Ki68`+(`^ER>Ua&7%DmyC8!_ at C1W8Z
zE)sAEt_HFPr(|jVfeszAOHIgd*&7jpgBe_{M!aHBX$B>CfyBq5S9`rAZ7O8&fro?V
zecsRezTfA0I88*Dh0V=`I!o}W332U&oDn_!;2>}oP$vZUfnDI|!BHan9?a!(D at v(N
zU<ddyrSB-EHgmb$iiiaFd77syt{8?<ux<MuV2^v=1k(Ur*Y#$v*Lwkch65=yK-so^
z6X+%qiAK3x{umC2kA!!-T`iNzT(8w?58b`WW&M>w6OkpL0c=^8wJIWp8$Zeo%d%F1
zEubMHOKyCmcs4*Z8r_~!4%^Lj{0n|?-~A4c0eWrd**6h9a`FT_4V?2_U}T?v@*Kda
z*Xstb!04bX02i~_>|LeQ8eq7&&IsIFyg(qZ4s3)%p*7Pqm)&Aqa at QlxX7g4g5-9+$
zftRLfE{8&)HDDtU2&{XHcc_n3snp|YwR#P>07QX#5qS#qW3kwyR;%@7I2<~_SKv2r
zhrMCyB$LTcl}hCmzCH%nEf$L(bX}Kfwff7p?Y8%2>2&(4Wm)e#osL(&H at dD5lF8(^
zd_KR;-dF=1x-q~aa2vSnIn)F!;D+Nku|lD6rc^4O9}EWbB4Pmp;0y2$`0m%(@7^Ks
z#+8UXXt&$X;_>)%SJSz14F8R%wMF1Q at D}KdOZZptvG)J{n*IPY*j%L_dER;e0000<
KMNUMnLSTa6yDA|7
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/media-playlist-shuffle.png b/src/qtui/QtUi/22/media-playlist-shuffle.png
new file mode 100644
index 0000000000000000000000000000000000000000..d52fb65e32d6849dc913af1b9b2b4f7e194aec8f
GIT binary patch
literal 793
zcmV+!1LpjRP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10+vZcK~y-6)s;_3RACgwf8V@${+VV{m_c(A46H#S9L7ZpE!rf4
z4WXDY3k`-gO=T;Iaak)DIXi{IO{;>OO%N4W>MC=hKa3lb!i5o5O3`Q=>9lBGyv(8!
z7acg8_wK##-gD3UJ|l_kfM;8(Zf9Zd7ILeBa^M}Xy7A?|cI*KvY}>w;OePNlVZi<&
zLXtz{BAYNEsa8_Gq==*l at CsNA1OitkCMFI@3Oe~tQmqqQWPR~jpcq)w-Q9iM>-F9>
z#>@k6ihK$@1Lln}vkeUm=OpcxgcmS?&lofAOks at qWZU-3csxFu&1PpC8yk=2^Z9<D
z04xJ<H%PNuSy}lZkx10Kr7*>@#$B8Oa(=&mIFU#kGsZjy?zgnGWF{vk&r3Qj=`=8I
zS=OCoGI_C3D4dkk at LMTTsnn6`>gv9+v9XwCS@(e3&CSi1CB-F$BzYu7nwpw2`FuVl
z>5!yS_fFi)@wgb26!H80!@#X at I6ShnwA5A9+=<^O>4c=Z&6e%htrpnpu)V$gaCv$8
zg+igQ$F}Xa*=+VvM at L5m5aOG6J%A}KE$!;->#P5j-5iY{yEp~hv at C06baeDgTU*;X
zVBF{PUG41bjJxc19heG*LYJner}w+<W+WM4pD`xod at L9YevU??A2XTEhiEkVJe^L*
zhK7druCK3G0X4vmV(4_S`><tMzE~`FBbUoP0A70m0c(=xT!X9u?|~=4(%|6WT5oUf
zdVhca;>^s<&Xtvwk_~oyQB_r?o}Qk%@0N8Po5rmWKcfa{a_NjQCR9>V at +F;4FAoe1
ztd*6O<$yV0(_i;b=#dm at ZEZcfu&{7yGrPGv{#)z<4gwGPcEbIDtrY$({=XY!+X{aL
X%R$j%*P>b>00000NkvXXu0mjfwQy>&
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/media-skip-backward.png b/src/qtui/QtUi/22/media-skip-backward.png
new file mode 100644
index 0000000000000000000000000000000000000000..443d538f5329fbe163c51de3e63314d0079ebf7a
GIT binary patch
literal 537
zcmV+!0_OdRP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10hUQbK~y-6-IT#<T0s<szmZtHk=jKNDwOPUUm=BTghC}HF5Cto
zo7;8wTC&oOui&a#l(y@>f)de?wiH|_h$c|7vQP{Of&SgxX-0D!1siB{VBpMrXMTn=
z=Nu!6yRg`usNM@<6RxFg#ql2lsn9<MPG at 2t0&Bn}@NFKmFE&8R7}GGuG=Np-<sPtJ
zC={N><MB74NEADmVv>+#B>6xaXiM at XJ&=^C)oNRw=e-36z?TJ>ku;SGfQfaQ&8DBv
z=l90r at e4^8z|gWzr{m{xxkwh3<KM!*?{D|}{oSy6M!-)Sa2s>YgaHQFFve8E^C!R=
za20Xqk4(~Qpa*ES+$O-JUa!APr_(2P at 2=aJD-<al1i|rOFgPleN}oK>`|e&2g5Y>G
z8g<I$^5<DLR~R@;CX?^0)oOb<9DXepi at jJZ_QSG7BJrV8sk9>4R9 at V2+XwdDvXS&i
z((`V&`!bu&zFL&o&$FMh6Z#*y*?AdY6KHX>^D at 9w;LtKx7_K{N=^;H^$A4|=|Nry&
b-xvM`?VJJQf+Zss00000NkvXXu0mjf^bziC
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/22/media-skip-forward.png b/src/qtui/QtUi/22/media-skip-forward.png
new file mode 100644
index 0000000000000000000000000000000000000000..58736abe1d2c6c3825c51b5e1f9f071c5ecff29d
GIT binary patch
literal 469
zcmV;`0V at 89P)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10a8gsK~y-6?UX%B!(bFf&y9@|C at 6t66c>k93jP6c>eNx_+POc#
zJ+n}-gIkBLe$D;@ry?yaC^~frh^UByL+$8wFqOAyHCej#feRPTo0Gg>5mjXou at +)o
zip^w<-UA%q4H(D9<$yKdeGbb5*{B}@&oKSP8 at 6qqRIAkrunDXhY~8l)(?3{NL^>kU
zF<t<wI;kRX3xtm2oHZJaJyp%A>PiaM1A3}jocQA6tEl=Sa__qCQMcROQPu4<%oK}p
zL5d=BY)sJtToKVip>RGN4l7AaRS$q6Fe5%>Ha6e`k4a2bgNZnP+&<&wdEP_2-M&c4
zrlvGk>^ROx5Ck`2820P+`XD9yO(rh3EbFUQtGzUv&5`f>cfbJHN at DRfni7}G<)>Dw
zH7=D(A#lylflp-f#OCJZfZgb!*VwrKSRUAq`b(mlC(HlwQaqDy-2~c0z04P^00000
LNkvXXu0mjfzFEe^
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/audio-volume-high.png b/src/qtui/QtUi/32/audio-volume-high.png
new file mode 100644
index 0000000000000000000000000000000000000000..477a168bcb143c27f489ed0a7f2e84d15f49549c
GIT binary patch
literal 1687
zcmV;I259+-P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11{6s|K~z|U#g}VLROuPVf9K4NGwT53!iXp=9Twt+LeZtOio{D|
zB<iYcs<Cv_q#rjl{a|`YL+l5Qmt@<7C`QHThbDe%^h4Ebl~%W2p)&PS<J5}nj>|=s
z%M2Li%wcBE(+`}XQwnys#rRL2<RtIq`9J^XIq&nniiq$gp}tY?fc-V@?F4+l1TX}c
zGfjG33OIqq&CSjJ&d$ySz`|K)ipX4>T}1r*_wQe$D9T@*PUi&?DHoBvndZ;6bDM}1
z4Gj$~RaNyK at EqvN&CNYxk(f7q&0MCy4iud^b7rB_>6Dt9nv1|FFcOVMKU}+ZZ4HnQ
zDE~_eydttlMCOZ#GE3woM~@y2sH*zV=kxtiL_S)!Y*`C%4|r&^*=|@Wc)v~x6cH&D
zk at B58cYa`P at b(PO7hkz@<y#rDhxhK?`<)jrUVL9w)!zeu0z&2G<v$XUQV~&KML at C4
zE+WN4Lqkj5ZuePWu%x8qXChKEt>8*JIy$~7BIS8`dFQQ&AK7fSo3U7IOJif>&w<;(
z9h=Q|%?iRZ69Fw9ZQ5?!xKZhFI6eiw079Ck{n{F{Pm}$Ab#?U*pFDZ;v8HLCr6czF
ze4mVsjWuRvWqk@<2majL+*~Ij3#SuMMdaNrTef_dlaq7I<MFh4Jf1dHRc`~&tPMLo
z9?vHh0f&g>pFVy1+p4MtfzK6130=Q_ee=G3`+f at C1a2yd(iMxvY65}4uYf-QpA{4o
z{6a+DP1jQTB+L$lLas}fF6{@jj2hK}K0p8zMTupMnN?L)y36H?=(?T|5v{(yzHxkf
z{5LHvEyE)tBOVcP?AWoRxTdD&FP)v86+ki)iTIg309`;l{TsT at pFckz7_%ZyTOSYy
z48TxTHJL#mvU26h#Knsje+$Hbk$5~_2s|q*D|^o55j++Q2H&fztLp}mKr)$3I;`~$
z$T*4%3k!8%IPGi}%Oqd|eH%7x2o)C>_X2U#G}YGD*0+j^io!qwh$j*W*T#(-qZXlr
zX_{_pz5U+^cs!oee{pUoijqknouZ!7($eSFcjWBZvt at q2Kdr!oX__go*K4|5t}!4f
zBDQPSu4!ok)4SmWufVhvq>&1T!!Mak6+WMDxUa8IP4DG$xuTYGX-g at JGIbhG5wP3s
zVnsSDW>CNl5Dtg^mI89{;KAsoO`B at c1S%>j^iU||Fbv}@AgO7Zv2NYE35(4CMZgBU
z-O$ibo=T<Mz-U21!PxTU%k at YkvY5#lV9Amt#;H at M7Fc_m`T6;y8EQ<`fKgjpo6644
z9_1A^Ff9f1gTbKt!i5VzVDiGDuV25u&oB%<9*_Hg37gH9*tTuk;MJ>F-?0=)=H%pz
zSnCs+3XFNZ-qhvGm!Gw at wP}W7C;)fw-ktaK>C@~C1rnJGbai!UPNy at h>-xCY>x~^d
zcC4?uy1LFZO#vqSe*eVg&71po at 811EI^s2J*7P#@2N?j0{OeNc237;5SS?f6b=kgs
z`@Ht{b}v9_Y3bwc?(Qz&@0NO{0|NuAYinzBPM$nD8i_=DcJ12LBqC1$Iehr=KkDo2
zZ&z1W|3pMa0D17>L3?FoWf16}P9P13ML-3Xo2I#<sj10+;>3x(*4EaCO-)UYfv477
zC-A<m>q|9F>&eQ>YA_5V2 at D4UfstFcZhc-<RJ5eOzrPq5ud1qw-oJnUcR&bunVEu2
zWXgO`Rn_t1$B(Z*a^%RD4u>NKL^H-GfIFI|8SU-uiBu|O0{w2cJ9+NhxkyV(%lN>+
zKqU|c*t2I(FAxF7r_wru0yAL&P-aE`C01|9fD<U`?d^Sk)v8r_2M!!~xpnK-XNwjs
z`mV0)QD9=liWSjdF!-3s)*Sh|1ilJfz^Z68TArJmJ6upuP%$ttPz3Y>($UfJJP-)n
zw1Sv&I+yPP1Gtl$o11*}=uvENaIgXR8z6 at c9U2G(0$-5PS*I|^w_-%ZDI(>eQ0OC{
z&-dfT#>S6D<a;8rV5a$VnSxAY0d+k+J>T&8d<m!1`9~&y-T%PrB9JEW9+O4e%`8u|
h*Gb?j;f=qJ{|OQ5Y^*b5<%$3R002ovPDHLkV1jB6Cn5j<
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/audio-volume-low.png b/src/qtui/QtUi/32/audio-volume-low.png
new file mode 100644
index 0000000000000000000000000000000000000000..bef96654b9d9a7f7f1d46e6471e75f2569042866
GIT binary patch
literal 1279
zcmV<b1OWSqP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11bj(EK~z|U-Iq;FR96&$zcb8?%rHEeL4HIr#aF2_V20GD%`mk_
z+jM1O*tqZ7RAS<eMUyUEwi|5F1u<#Z)PzN$iH1efhSpeNK~N?Jv7KtsX+an(^9F{Q
z+r at j2T!){k at h9;lZ*lKC_nhyZbKg1liBgK!DW2Er{f!3 at k!>QfrH_{eAR^m<P9Xlu
z0YpTA4}cJ`TSVS|WdI`LQ}(BIPn+H^BH`x+5FiXR13R4Yrp|$ch_ooB?f`c+8?omB
z at Bq7jx)Uc(bN~^cwoJzdG^A3gS|9;z2cjZU1>68u9KDE$G(HVL1>gnzK=b_ke05b-
z)fbm8UFvUXY3TwCP1g at JU%Pg#J{pbI#^Z6nW}^cr0 at IrQy0f4I1cBXv3G4;l8XX<o
zzH{f!uX4HEN5EVrlWEi7{J`$s-rl;-&dzV!+uJ|6c=6)>P$=Y<)(Fr7`~ei4xv+>-
zZUj&P>^gSr*!wj#HQk0`oG}dJ%;Cd_`wE3ZD{vop<n?+pj=lhq{{H?Q-QC^aluD(V
zsi~>YCnhF>r%s*vTeEK}rAmN4_e2`R=>_3bD%BK=#l8aq+ItIl2q*x<Fn-KtvjadH
zFviEn8xI{i^tEMKAs`S81}B%6mcEQcBKsB=7TnGK>_qoHXPi+={Z<}<ZG(e at 5#SLp
zqdl`g9#{sJJs!`h2DfnV;K9}5;o<Lr9Pluo&o==yH#b|FULCNgje~jw*3LjvQ<DYE
zyUsRwbbwXh!O^2fQ+xL8`3uOGN+nNkZ*MpnjpjAIN at uM;UJp=RU0wVi=gT6Z1K{lZ
zo at ttYVyA0iU|?WhB9V9kz&Qu*=jaoW3iqYA%-{-JNLdP8DW=ouf3Z_VeSQ7>RyNkz
zTqE&%70(`l06;pO-isZ9+}X2d7q4Eus)sr6bVRpC6qHiMHNP7GY${~{UZA$CtE;tG
zECzvWV`Jl^wzf7al}bf)0L{5OUKfFtWHMPa3?sW$1j<rSJ3c-h7#bS-444C~BS((R
z0=e1QS^cE{gWXG9$>{)Y1hV09xZ%o`D>D}^TnH>LFAKo+>(@im)6;9ES40Zh+KREU
zv4G$2Pg|C?6b^@T=gys*?dj>MnVXw)8<wS%%8H1ot<#IrS|I|viF}A%js?K7EOq?&
z at zBV~NEpC0&8geBZ;xRYA^<a!$t04=<o5ID&u2~3ymjEffttsUAG-iI9NkZ`n-;)`
zQfe&?`d5$ze!$L`0G>b~5W9T&^1CNbp3L?2_3b!)`t*{cyMkREXBrwB>Lw>A_Xh%j
z2l05kQgc41l=|J-z3Y5YcU~TWjl=`I10)KCg3ssk-2o=b!srKLH*em2(B9r21FEo_
z&rjIJ>SGOHOeuB$SpaaNQ4h3Yx7Lia`}K-;r%M92lv4LZqyzgR1MpBO^~<_7FZ#zs
zMEpvr6({uWEl2^QN~y(i{TF^GbevaU-zi*4ZRGr=05}ju;8*OTb5|)fvzhJ-Pr(z$
pMS?)yX-2Oe;A!N|{x^IY`47WCzTnR2N|gWr002ovPDHLkV1m5CRh$3-
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/audio-volume-medium.png b/src/qtui/QtUi/32/audio-volume-medium.png
new file mode 100644
index 0000000000000000000000000000000000000000..943ae7d91b931f09a56c7bd324725635ad29c2b9
GIT binary patch
literal 1475
zcmV;!1w8tRP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11wcteK~z|U-B({sQ)d+aeYbxux20VxEkkA*X;Z}14T&=tJHsds
zC at 92Ceb~dyViXJ{B%8_N!=9EIUG`uiE=m?2NO)Sp!_-aXg-jpJgh&=6L1C;8i=9BB
zq}<!y_MScTUb%MV&oYdOCpk&e?>p!GzTY|Dcg|%*gx4wDYmNTK17M8tjImW?yfOfc
zF&@Ak09C8)Gj4EP9)LTMNTdZps1!x95I`YgY>|k@^BHU;13Z8&Jv}|8ilR7<A3rX0
z9LLnPO2(KouN4ukrHqJNMD#8Zy-h at 1o;^Gf`7U0(Si^DL?=F|?J0hxRXlSSha8T7?
zKL2Y4HxQABh$@a8IdYJQDpU};!OL&my0wGjxcdN}00<vDc5Htn64~Z<yASF>l&lAU
zk%&y1<C&S6Z5E5A55V*C^71c<$d`NayLa!tM?@7am#ZJZeE<&(2E(11nVD at J9UVa(
zfDcy#P^g_&)7!Uizi%>`egW_ofKfpZdet>PhxU=`>gtZMv9VKvAPfTd4ZvtoQPH>Y
zc)Zf>b~o!l6zBnHMQ8-D`M`k#yBrQjr`>KpZMWM`*VfivmSwpDz%+ok(P)gS`xyXN
zPft%#XJ_a4ilR71Mn>AB(P;S0nKM5FNCB9go0|&(Kp+rE=*q4{UxV5;bc~LUny+8K
z{xtwWw=M#R03ZNhj4kQbGF4SoBG2<NQ50n&687!e_emm=`0>Jp3$t@`b2cI}9X@<G
z(A3m4H8?nEQSFKW{HZz77%=zu_iq9a2QZ=22mlE{5<rsUxU>$y?9QD#GuN(N`w74j
zfH_H$N&!sx{r)E^3-RIM;SWNgkjV4A7R#dZvHT8{mX?YDX0>1|s2+d};8`dX8Z9d;
zdkR2O6ou>R>auz~p0K(u$+FD*{r;5MY}R5G<ON`}*)nScPcp{z0Dx?YrhGo%6ZLnj
zudmPV^?Ef1Qi`HvY&M%>wOTW(jfpX4&>ZAG#VM>JIVsR26Ap(Lkxdnfi;HI?kqD>x
z;(304HJ>j47>!0!Pr9PyVL$+Ya5(HmmH|3 at _UwE^L&Gi&!1nFi#l^)%E|EwWkWHaX
zL>e3a3xE;8rbCAgRb(<53xI`^l9G5J5D;Ur*cN1K0F{-M$;rt{lO#!6P)YAotASK7
z7|hu1_64j`134)u8Xg`lxO(;KX8>jZh;?;!kz_I{N|ICzAZ0KZ<mTq)=QnQL5M)`_
zW<UK^e!;+k)9Ea}dGqE(cXzjtOePrs+`D(L at bTlvb{zw<&ek+EG$feK=CCM=38&M!
zbm`KiNOg7fUPVy|K+5a&rWzX?r_Y~1U#PSD`z2O&L#Y$l0b&cXFC9ctq?VSJ!hwMS
zCjj_-zK7%E<3q?c91egt8jaQjgTc41T)DCki^Zmn9zEJlL}LKx+_`g;?d|QqmX(!x
zW3iYPXMl*7(~zh23aVO(XjdkaInmbEb_&2(U0q!*YA-OT`>jOu(bCdVD-kvEJpTiL
z%K*Nqsj2xQolbvz^5n at qSndORbDNQ#fqY^Buob{=S(Z&Elj#ot50LE*ng{@P3=9k;
z8yg$j(&_Y5i^Y<D^ytwv$8jTpK;RwS>4%7D`lSf#97sxtXfF|MUSS|9Afl~PQ&XRM
zJf6>cdwWk1QEh#FeI3>qNY-NDzlZ=}_x$|4-{Ek~wzjrTcXxLeY3BrRhlu|5C~YJF
z4MbHm8hz&Rcq(LB=GFfn6469HgN+8T?3ghtvbX9v5sj?4?^OX%L0AAtM5MeH0PB%A
d``d6m@()L~deYJD*L(l~002ovPDHLkV1g8MnezYu
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/audio-volume-muted.png b/src/qtui/QtUi/32/audio-volume-muted.png
new file mode 100644
index 0000000000000000000000000000000000000000..279df120f5a3c631f288a04dfdc673df1aba4caa
GIT binary patch
literal 1093
zcmV-L1iJf)P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11Hwr}K~z|U-B(>`990zl&dgm~<KTvbYN$o<hvI`jRHIS!P4Nd5
zs^U{s6lD7#+a@!+2|ma$2nn0LGZR at Uk}8VYr+`=l^AKxZilC{!_#kSDkXncZ<8Cqu
z$u2v`mpj|bcDvn3exTpW%suCP_xt9|+&eSG%-BsByQ+TO8z>fweWg-q&#oAdQr==1
z#_Yz%#^jD0 at I22j3}YI=Jw)`nlyYRp3=|55wClPI;8YSLqERX3z_uF*!>~sPF)O9a
z+O{14_%zWWBH4;Vo$dpLLLogeGO`SyCBgH&F3Ymc0ysoOYee*b5aLp`TAc^b3joY~
zIG4+v)_K?Lz|_=~DW&{S2vH7#;DuH-rBZ2+>$+>q{I?S7isSf`rKP2ah(;S%OY}}N
zx2*vw<xL9<3#W<bs0uybToZ<2Ppww_-uL}yOw)V|Kv|`puq^BN%F4<K0RO7kBje-a
z`*pr(5*#3+Bg}k*a{L&8`;&YUPcSht(H+O}w*U?S_^4W~-kVCLvdsLsD#^L7JK_8O
zHvo<RAk#Dt12}O-2PP*cQvkjOkR_s{>Z%*!tx%~{)&V3N%>g0AsBPO{09aJ9{l4!%
z2;eJ?_N+cf!$74{=_R6l?F5_Qy6$=$$FJe?gZZ2~o=a+&`6(j$L8IN-(!l>kKA-;?
zz;9}J$Jp3dFMzp*fMFc4ENf9SdE1s6P-qAWAs!+ky#sxjOr{24Nrk#S&+FQ11C4nM
z!`RdZ##R}4R2|tg%{gZ7PZC75s2=bh6)L-~yS8Np!Z7RyaF-gM9~>Mk19&*eGxNoA
zxqK at CQlX1FzhNMqPX7bo(k8`kjN>?2^B|&Wb=t3$%?Kg%7tx<B4P-Kz8WBCs%<mCV
zfrttKer#tz2w`c%3#nA<-5>~F1<<DqEjW(z6EnZ4)lKVjw0#+Qp10SstWyA9QWKuE
zZ9Aja6pO_^BKnSqj at Rq;Urp2e1wgk-AB&>sq*{h)09>!vZyz2W{_Bbkw1Vrp>roWF
z0^ofWI at 4T}&*v9cS6BNT$C(jAe5{F|aUACZ%d*~9;s9_?7r$l)bcA7e_t4PL`K#qi
zrP9sSYIP34K>!sZy02ENEej#$ad`#2>^RPsI<MnZ&`ulxvf1o%y<UG3z&sHhvu*o=
z5F*sX&o+y1%0MSj?H#af`!nD79RP2tR1Cmw#p(DKYzAt1{sFb`GxKmRmn-g=0RRYs
z;2<;40+?|e=Z&k?ZQFl=ZQH+_ruldjMVWSW+tz_jaee<Ac7p!^0Oe*k%1PfJ00000
LNkvXXu0mjfw<q-w
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/audio-volume-off.png b/src/qtui/QtUi/32/audio-volume-off.png
new file mode 100644
index 0000000000000000000000000000000000000000..25a9b3a59aed1e4a38567e91c0ee0b4ec5248450
GIT binary patch
literal 1036
zcmV+n1oQieP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11BppQK~z|U-Iq>SpYfe}6wPHMOvVNFtL8QWA+qNWtAyl&G5u
zb<+hOfe*k3VA(}CEW4}PHCwVmVqxe*ZBV61Rn-XkP^i^}xJ}Z?QA5qOW1lYWTr++^
zXi9>VBVFA)=bk&~H)qbAnJY8nG$nSb-d}kDNhwK3`gmagl2X9Cz}1%yAW6VG!0W&T
zNta$4fTW~_OY5$uo{*ILKL7*3IUw^a=fJe2i)OY1+=*TRSDptz&hg0N;^O5X2=c(t
zA<pB#G%yIfC20V-1=O6$8A<1l10Z+Bfqc1K9!jUvA1^H}U7wts{1E60rKFgdHGsgW
z;=mNp0DkpMyK=z?cn!z{m)$j9EEb1HM at K)YR;$y%!`<E8tL~e)=R65qlQazc0Mw%q
z0~djkr^`v|_W=^#s7GdJXW!o3-29-~Y$gGMAed-2n?pbuutXy9r)S at qbHcDs0bde^
zz2NM|&1^@~ePG1t&O4|!fXw#xcB)t`egyc0Rp1_A&fz~D5o~x-><1>y>_<sgfE3U#
zY0wQI0yx_Xpl at Ym<qYr`*yRw3#bQtWwwX00eGk0nbq-J=OkRNDjy}_V9}xige7*|&
zb(nJ}PdgQ6_E^#r!lILw)Yk#f&p~oV?QVcfCe!FJ>=H>`08T0n0K$Bz_zqp9YCs>5
zloWTX<^aG+jU%LU3VgPszB@`<0EtAxc>V}vz2^$y@{45O?TCG at U5`e8A^?)Igryo_
z&&=vh*8=dIN9~qGOQ<$8Gt<asvlR!?^Xi-eSAGkg>b|@C01s%do^4AxiooBwT&}*c
zv9Ytfyqv1lY64haU(al9Z4G)3>$FSUd#(aMNxDE-0|2USm5ld*Yy&W$R45dFDHIBq
zqK<<g*q at u5+gn>(8v;nD({;}tGpk9uL3r at E<@%fS`oHbw|E#C`!w2y9f&lme_#F5Y
z_$-x5eYd*0`eb2Y;T{mo&(H5UyH*mJSpa-(W)BF<anikdXlB0=CS;_mm|0s6=o!ay
z5pGP^N~Kb4Y;5dz;3n{>%TP)XR>T3q&F3q^!u7rfaMR4n{{<kDbA+MYBCPAZX~Ugv
z2Kd>`?n;^h-f*uUnc25p-<<T1iKIT48{-_Df(-b^%qpGsCw?Y$&f~zFo_f2N^A`f(
zAR538!lHA>%x)iMd*V~j*141h_RXw$DgeikSNq at aIPx!bVLy-9XCBA^0000<MNUMn
GLSTZ;mf<=8
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/document-open.png b/src/qtui/QtUi/32/document-open.png
new file mode 100644
index 0000000000000000000000000000000000000000..55eb33862a1445d4bce0fe53b99752648c373223
GIT binary patch
literal 1053
zcmV+&1mgRNP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11DZ)hK~z|U#g|P;D_0c9fAf)Od=GhODCneMeYMa?Do at ZZx{%av
zy3>sd#jURF&RutJBZ!;s#AS5hLfp%fQi>Hzq?>4<EvfxLYZJ|rm at j8Cw~LviV>*cw
zF}yz<n3;R;Isf^eb7#(#gb=(-s4mYGpd0YJj0qrbTU!V`1Nx7Tk2`mEc6#b34-5>H
z78Vw=Ko)r0LL3vQxD7~kDR_T;eEf at eJpNh;(d9B<1OkEmLZR?=3&E=>0XMd}5>SD`
zKp^nCR4RRDvvz~e at At=BiL59}VQ_HpyF?=K2KWmoID_6pC=~iNm&-kG<V*;m8iw&f
zD+F|17pJGEA5BkBpYQJO-T`OTF{c7D at Dd0EeXRuWh#c?}Rw{nOD(IR5641Z8y87P6
z#>SVru7`yX(o;s4BuP{%mBiB0($@0wvW}GsQB~j>p!s~hZw$lu7`S`N;12jzRZZ%;
z{uOWz+*TFnip65xhGA&HpV;!W0g_=DS}Ydpo}Zu3Itj>ES64pZng;vz32|-5lEJYH
z`uh6HSOxMRdV6~_BO at c{&E{NQUUr?FoP6jqq}#E$N1!_Bg}~n4-VdXrqfM1EO_QOa
zAtjYcg__N)5l~fCcqJf&_yzbG$TXPJA<OcBq9`xjeA=-9I}Z-%UhM4bEDaQa+Xj{g
zau*jD`364zBU8Ol6veXw_FONhxcPLhe^d>4g(OMFLq6L|fCdV<5@@9eokjE*0?zgI
z3K$+8dx9iMm4|$`RRKj&Tx+120`IH_gr;dimgPIsG at tA@?6wPJSr(e63G9xm`XMSu
zA`uadMl*Q$5Iv#@YZi at 0Gm%I{U^OT;1#&=fdwcus`ucile}DgfE&0*WQCB{nR~(O2
zpi%4Qw-u<RU~FtGKQ%Q~T3lQ#+3`wnza{enuYh4(&II9bxFeZN1^{MfXX9I2TYofr
z^~1x%j>*Z%&x^%k03eY_Tn!Ho>%fmd61(T9Z_BGhUO4UpKyOb^&v-VQePO at Zr?M;;
z>K8g;nr5dEA_ZIlY;JCTKQ}k`J60=JL;cSPtaj`lhy4xQPE1VHPD4V7RHafeo0$;e
z8mqw}7!2w&GcyICTp!HsXy!&pUs+ixrqk)$gM)+TK-#tkp=nxqZEY>*^Z5*{Kjl5R
zrN9lHz$oy^&CQKjE|)!T)nG6v$+DaQzQs<*V+eqCXzd3=_O(}BW1RzvZiB55Xbb)Y
XjAF5IM?1)o00000NkvXXu0mjf19Q|&
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/edit-find.png b/src/qtui/QtUi/32/edit-find.png
new file mode 100644
index 0000000000000000000000000000000000000000..0d2f4bbe81a562da20b0b1663e15797492bfcb14
GIT binary patch
literal 1469
zcmV;u1w#6XP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11v*JYK~z|U#g|)56lWC2f5Yqzmng98A|O;2Db`R0Ni9LeHZ>&n
zqEV|nXoyK4v|8UxX|RS%@kP_5O*FhUO%oFh2 at j?w)P%+ui?R=Ginf>{ur62GWdpLx
zF1yR=!_2lD%FPS*pG-0{XU_NizyCSkIo~KE!v6`wGkmK6X27D~hkzh3v)lw$0Cs(H
z#>U1}x7%$fDJco*_AuZFCSEpy1byOF#l^+tU0q$f!r`!UW at aV>P!&aaWHcJx85tS3
z-EMa?kOVveBG1G?MCQ6oB9eRg^5xBDv$+`<1xA1Yzzy^P{lG9VYA_gXoH}*t9T8b4
zA}i(@bIxl%L-wIVhjuB7avvB3x`0lg(_*o-CnY8Q9D4 at -(8;)qi;F)IkvtJGya<7m
zU@%yqs_HGE8~9CC)sCvFs<WM)ou7%wF%dcD at pwLMXlSTOOia81{0iJx6s4=FscDOd
ztXV1nW!5${0&5)(N0ry>{TP_ETCL;PuV4SMtgLK8m*1zy*#@i~8X8L8x^?R|x7)oA
zu$WAy-cTs?IWPnSo;3$ju3fuUq|4e4v|qSzp;|=VpC`6P5!rU{-o4{yv$;+8xxat^
z{*Oc?{dq#Ly1cx+61WZAEGQ`WPDDNwk)#C%F^R~#M~)n60B!=e91cgFo(qc-NSGyv
z#qD-y08>CDKR^GWo(Bs_ISq6d6&3aCp_!hTn8*ZFJ){dFz78mW$zrjrL at O@XY&H*C
z#aj%a!otG-m|sFdLd<8;Iv=lq0FezFHu%w25@~B|v$C{mX}oyxqB-VgHk<v=LjWMS
ze*OC4*g#`rV{ho+SQi*W1rqPvxl<VP%gV}nqEEhPpO{S`bl|{&QB_sLKxAraDu4Ix
z-LC@<eWKY=fb{0(=H!u)k+K+pqeqWEK+BuOTkWi at OcasLm6etCz!jiHQIxhzmoAm)
zS-ncndV{_*UJC|;1s03t2cQ+Wl9QA3jfm_J5$p5pf+=9Asi~<uEiKItOo>SN at ZrPX
zZrr%>Js=%e3pjzyg9i^5TCLWvgTbH^7y}{|6%`|BP3h^PtB3zoLeRqU=GCiL%l7Ww
z`_|0NjEWY5)rz7_84QL2RaJwbP$)-4l7VrwCKUy++wFs+qod#J@=pTZm~E*9KufxE
zm&^6qzJ2 at F4Gs>bpdCa~bz6eI!pFdbs;V>5XjDPViDZ+>6iH1@{j;W~=BJY<Pd?HK
zhUc0{t*fh>>wOp)&dSQNoj7qK90&x)eLi2r at Arq$dVv=hPfbnr9Y22jK}$=^!|Lkl
zArbMnx3{N6qtVPjAW+!a+PXau2>f1AQ6az+=GYbUDG);fPzaO&=HcOC?%utt*zI;n
zOG_g=J6q5SRS#h7>+4(NbUNRT^IfedinXSurm?ZHv41Wl79;SFQa~n<4a6$tw5~)q
zT8vi#`I|Ov`k=G3Gd0dPLsiw4wY9ZhojG%6Xf}zZ5?BfpAh)--cSmVysnhHAu86Z`
zs;auOzP|qK>C>l&<4MfkhA#pE2Aodk1DDG+;BYu5(F+sciAJO2wY9ZhoI7_e9ZgM*
z^-EMB1`|-$)6-K>T3YJx`Fxf*TaK!#=13&+CE9s%@?|Oz!!*#ImzVdK%jFue+wD*I
zSBYM;+5C8VdfI at l{&EnAk at zJyH@Bywqr+>n*`CHoG&D50OePa(Rd-oJ5Dz1;-Q)4(
zoj-qG-MMpTWY3;G6F?i<&&;wD0PQ at n1+AWp12@qAGk8 at 5Vo;f*C%j4mb7HxYaLM=^
XM}uER0?C>t00000NkvXXu0mjfn|H1Q
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/list-add.png b/src/qtui/QtUi/32/list-add.png
new file mode 100644
index 0000000000000000000000000000000000000000..4661fd21bf9e08e01c79f0a1e7b1e6b390660671
GIT binary patch
literal 581
zcmV-L0=oT)P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10m4Z{K~z|U?Uyl2!$1_re;2J<DN<{3u(MESS8?=nluq>n6}QrF
z;?mv4!9~!a4uUp9vBsS59FjtMUecy&ir^mt$-BFEKVI_gy(nW0tCY9W-TwiA^_=q+
zum^0UjK2c at ZvyN9wQje&JDE&oqF1R at K02L_4`^V#s6&-A3+g~kDRl{K&NxzPEFx#X
zQ+zF?yb+kn2evKS%QB9Z1$YMD9k#*%!uU!`7YU#p0QU2 at 04i7?S*&tmv$P1<-^Nq{
zj_hy&RDt~zCsVlqrqAUBsI5n=bHbH|2mOA((Qdad(snn-JUYytQmUS|rq}D8w_2?s
z at Q}1SUxA32Ip>20><M1h8WC|0Isux^<{NOAMUbM at HL=gd0AekbR(X{LuvA+8IRIA{
z>;etoByCZtR65dHZzXNjYIQOijczjb8URCJlr*{`;1kvTYsc6oupuIcSP=@tFa++2
z4jj8qK$L!8dIcANAu22b$5<VxiO4BdHx&dy0NhegISzp}%T`=5@;pzA$gdWoc?$X3
z&=y*bT>yndAOP at v|JepG#=IxzEULUssUj-Z$MJnq8n_~7Tb>u-$F=f5qkn);3e257
TI1kcK00000NkvXXu0mjfoFMM@
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/media-playback-pause.png b/src/qtui/QtUi/32/media-playback-pause.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e427fd9477d9c3d8612080a8aab3b58ae3b9df7
GIT binary patch
literal 527
zcmeAS at N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmSQK*5Dp-y;YjHK@;M7UB8wRq
zM3g|7v7gud1W-`2#5JNMI6tkVJh3R1p}f3YFEcN at I61K(RWH9NefB#WDFz0{9#0p?
zkcif|)BU{;JBYOJU!u5n%PXY--B^vhuGJNdPG@!ZG_il;y0=Jgmw3!hVV2z+78och
zUHMb^Fye5^tSK!Mlxk=HIq`e%8S~1S2FWU(PLmVOtbXw&NHeVAwfX(RF<D{4uI<N!
zndCzm`Wl<({0WMCE7Q*qcbe&o&H3Fk&Zb?@T6F*Y{j<+MM>jkysMs2zqZfL<!e-x0
zzvbUU8F&<3%y|w6n+mctPQGT<FR+MPqLNvpj=Asgo`o|VmtU^*%)bBKST1t5bSpz!
z;*mdJt3;P&x^<naNXboYVEJ+BPQS?7&m#YxuVy&XwT}J3w%lCq29Jx9{cF~;ZP==t
zu{CPrqSuTkDk~mJdpJ*Ho3QzUuA!*I^PlXi7u?O8p4SLcwvKgLs%zJ}<*dsxr$Iz?
zS1;JuZ%`O({>kQjtZ$Fo;?VQzlTQ{INTk at Td+p|+*AiG at V99ijA$)Q*o7_ at 6c0ZGO
z><>EU$OZ~B98mmK`%wME?uP{pw!O!nr~B_PGh<v~DrGPJhCzz`2b=EI<!)*ZpK|~s
OkHOQ`&t;ucLK6UC4cB)7
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/media-playback-start.png b/src/qtui/QtUi/32/media-playback-start.png
new file mode 100644
index 0000000000000000000000000000000000000000..8bd1ea84ede04f9a0e7dfff156996b4b2d19593c
GIT binary patch
literal 805
zcmV+=1KRwFP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10-{MoK~z|U?U%btTVWW+f62+koTQkvm^PP^PDKJzXa_4wMd;F^
zf?aBc;NXy<qfR17Hy1NmBzVCw|A4z4+Y%@(lv1clYz*FNXpD)Gldr=`AXuAo%%yhl
zg?BsWdw%D6-t)p|5JGU3WxP`LYXBVp7QhGG((!Cd06G$h#LY6mJ>bT_1~83{jXg1&
z&C8>sqd~v}+y$&nBM?H=>OfCVPYBos(ssLjH6D*Y6hhn=Lb!zxlE(X*t(mLcZa)F`
zfume5_cRm=#RGxB3&4pQOM4>*XaX1v1_7J_Szt#9p(K;ZS0<Bbd2n#>0dN}#0Jc^E
zlz?KnPk{sAhoUGQYiny!S(c|47Z=^AvvCJ7H5;JfKy~MV9Uz_0=O0HRkyXFn|1z7+
zR$_4hhE at Vp`WLVzgg8#6Qel_N6&n~Bcm#By#v(TiV6j-LBe<wffj!{6qA2qE`ub~|
z%{Cp4M!kR^@B-$#0W=&qAImndStt~`CMPG~cs!m^I-PDu-5)InsE*~E5aJ+{$vmH#
znR$k~xGvPvoLEVcO67xfm(gex!^6XGW3kwQ+wI;34uMi#0A&Y?dc}jm;O@%G%64~m
zcM<psBv9kIu=E0GI^c9VPiALlHzJWp5l8{=QHQf;X#!ZS)|wGWk|f5*$G7I@=8hc>
zM;7=1YygVZ*}4E~MbO*ZyT7!w^s}?G^9=X`d;|)5gmnWLjmAGB at Or(u`T6<1k&zJr
zBvI`?yo|7Jfa<@Xt*uR&n3&j|nwl!fvV4SU_ZEMd at TLG%hHz+T=xAYKq2TlR&VbLr
zCob`K)C(Z``udb`IK0!}-){gmQNKFVsBonW8W$4>(1p6w-=VJBrru<<005-2Xx%wC
j3eeK}?=L3T04=ZIN1jl7h at u%#00000NkvXXu0mjfdBk9y
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/media-playback-stop.png b/src/qtui/QtUi/32/media-playback-stop.png
new file mode 100644
index 0000000000000000000000000000000000000000..a7a7911da8fcf72574e2a5b2f4c60350b750771a
GIT binary patch
literal 388
zcmeAS at N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmSQK*5Dp-y;YjHK@;M7UB8wRq
zM3g|7v7gud1W-`2#5JNMI6tkVJh3R1p}f3YFEcN at I61K(RWH9NefB#WDFy~cMo$;V
zkcif|*A4p)83?pKtWOfiyd;pjF;=Q?gZhb?7Od`%IZQh2Ocr+Z1a3Q^YH>)|M8qdM
z^V#J4BHMZ%cch9gyS%@_pFu|`ooP+lEaN>~0t*<Y88g}x)Ua+~nid+G+n#tMLv4C$
z<%{2S>{D!ZbcV20ysvlW=w*AbcmI-elNp}h;rwxtA*tVnL14%8<trDk#^^F`mt-*K
zJz&Q4e2!Jq4Q2iV?Jf!1Ta*^vYXou{N?8KeGp)#5puttjve8}6!R3nJ5xJWTw>dV%
z9om+wAA5bS>E+kE{PwY{d^F5#uwQVEp at Hwl=O>=im>AZ~?8{um^x=!xa)x~U&-Dkz
c6Zn3xhg3xtRUJs(0Sqw)Pgg&ebxsLQ06aO5lK=n!
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/media-playlist-repeat.png b/src/qtui/QtUi/32/media-playlist-repeat.png
new file mode 100644
index 0000000000000000000000000000000000000000..45ee8e33ed24694590b112851c29c59a519b7097
GIT binary patch
literal 1109
zcmV-b1giUqP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11JX%EK~z|U?U&C>9A_BEKQrUZZrrR(YS&`dtg%RJu+vLY+8B^Z
zx)+y1J at i%(FOtiid-Gr~n}0z)3GTTps0S%6EFqy3OSLL-8&)<Nv9elCVrGBLygkf2
zVf~$r7JJAS26pCs-|zF8=Y4qISw#rJMM}NU=<fjj4*+#<Fn-#c(^QdHO#tr!R{-sd
z!9Cf)Hn8<304+d$TU*;V>+9=xY};-;OJq&c3eC;U4|2KOk3c=JT0O2D=mS at Pu;1^$
zUn~~yNOI>a0JwFg`Fy?ymSuepY~p4EIGllyX_|M7#o|q1Ljs(Kv|_P%(=^Sy^Yio5
z#{sB-k<aHpk(7?6Y2{cf_GoZ$aJ8YKp(dE!-Cb>DWTa(gX66gqwsoK+y?>IioPz)w
zfNk3rPz31e>iTVZdU^?1_ny at tUteF}^X~5Mx=bc>tIFGpbqK&6(X<yp2_PPiKL&mV
z{;Dy!r}lU}Ze%i<PpiE5=@5XbsuiFNu(-JR%!7GLm83_x%KKyhMNw>T!S?pHb#S~^
zNsn at s_sIabmG3P$^I0uD%2nPc11O48L8e_*)mnRig4;!dxJ9c-k5ZNQJ{@%!c^N3z
zn1KLr4QTA?>G at nj_^L8c=7<a&0;sBi^3u}MhkyZG0(6evG98Ejk^cVvk9A$YpUGqf
zyg}*Vz0ipO0zlVwZwpG<Y&Mokr9!|}pbhv4X!clvM&MdHoo)(+LifhU$A>GGN~o@`
zZVn)oN(HmoY|QhM-mhc9;j^GU9*^Iinwq*T?;C-ue!qW7Rn<~cQ`6&IE;j`{1Hypb
z(b4f$Hk<uc2%!Uc;2%|09m6m#S(bGJcnTB%dV6~xPEJlfq^hqR+=5rhWU>$l1YXLt
zZ2)=8vZ8x?dmV*Bp+(MX9vT{o8iw)1^78U`LWlzJJ8lavJC37UmKBvi8$dY_2)s-t
zlLg?_aa#beX`1F%I-PzJ4u^MT>Q;e2fZ0GGupsA^hKGmsL?V$527`})72K-#itV{v
zvkH{L;qY!coql4P=9Ywft%F+ta2fd0ah%A)!h%>^TT{FNP1F94#bSQ~IUovj?d<H-
zClU$&#Kgo0j^ii*kw|23Y;0^({uZ5`or<ceYrrqSzIJ>R0JznD9k;sctDYC+n?0BJ
zKHwH`V|I2{9T*sBn46mmwzjtJuB@!&aX-ag0BgW9M}3+JA<pA^UkLHFZQJ)oM at I*v
z(deKM;<^yx@@Z?2%fQ=61=@knN~IEpVf>0)8|9N0ohN`NA8to{3hbRW`M&_DNf-Xd
b<Q>4jAQjda4<CX-00000NkvXXu0mjftj7R;
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/media-playlist-shuffle.png b/src/qtui/QtUi/32/media-playlist-shuffle.png
new file mode 100644
index 0000000000000000000000000000000000000000..401f6f9a3b12a7d56f56667b5074fc4abfe2f147
GIT binary patch
literal 1464
zcmV;p1xNacP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11vN=TK~z|U?U!9lQ)d{*f8{_ArC(4ORSJlFnP5i3HZhAcQ=A#N
z8FYY2hfB8I7!!<m<1UOhOuSi^EO@~U8R`YoCB2z^#NbGJv9RDw##fiotgV7D#ab&L
zZK3Vi#W`hX6*o6^-uO at 6q)DIiKL6+cJn#QKM<YoRFA^y)H2X^e&xwElyaHqanioO9
zGB!45jYJ~3z-GYkx6zU$J?oWMTU*<dl9F<xuCA_8lB9A;l5CPBY1fN?S_L#f24Def
zKp~(ro6U>yc-%HHFwmKik at 5NY^XKz`O+XGwZPBQFAPo?c62yTB5L+jC24Dr!TrOAI
z@#Dw0&dtr`00aU7)9mc*M}QVEXf&Eoetv$p+wJ~V6vb8GF0iO3pjRq*9HPJia9<&l
z16U3oJXq1&+uItAMoWNHRs1S&Po<I`FbIO+tE;Q~;>wjPlYkFcNj#)KckZ0!#EBCf
zNr^+EDEh2c>%{fz*L$<GvrWJfV9L$S{d9hQ-mWBj2&^cI0Z0nz1R_9Ck|fL0(o)mP
z%8Fa7)rx8Ynn)y~iN#|2Bm&0e<>frD*Za2BYHes}XlTED`SP#D#l`jW^YcxLl%e$W
z^rf=0vYT01Ss{R6Fql3%I=WT8(UvV+rY>H*I9gp at y`&IcKrLHAK|utVT~B{Nh{xmc
z#>U3k-Me>JdA;6GfLlOx$BrH2eSLjXX0v%M*y(g?ckS9$3Sc&y182^h8EI*0SpaSV
zKLQUDu?Yg<0|yQ)UAlDXGj&#v$CK9I-=8-;Jp6t`L&G<sD8`*mXDcuVgv-mzeNLxy
zQV;|eFr`SHJ2W)3Nf3m0>~{N&&d$!e27 at 7>B)+M%XAOxV)Bq+RJ*o0kK)<lCkYY3%
z<2s%0R5%<i1Ri8&W(FrFCWdV`+Yi8`YU7PVLqi2QIXQ1sR#t|Aao}g<S$PBr1tcJd
z+#5C00Lf at H8cIq^>cZi0889sfLfqkS{A9D)T)<3HRk50ynkX<0{DR!7b(6!NR;&ez
zfU=}j1Q<$7OW*Z)JRbsHAae5L$s08_HJ)R~j-?^{eulcJ=H})NMx(K|r>DovV+<%+
z0rS<XSIu_2y;=R|>guX46bco`VzFGn4TQFD-+ue-*|WEci;F9KKHmq6i;HdD-Q5}>
zgnSf5olX~7TwJU=eE9HJr%#`DxLmFQQ4~$63 at DjE%GA`9E)WR3l|(QGECXXeq`JEL
z&fwtSOiN44ve)Z<516 at d;linF*RFlHckkY at s;a6WKrk2-fKf at 3Hh4T9yI!x~SzllO
zwZq{^Rrb59kX;)>Yj1DwhW-2Zf4rVdSy@@(_V)IfqeqXf0;3LxBmc;eBRl<mzof{!
z8TlGcAVC^rd*1|PnM|hPuCA`0rlzKc$nA_K2xQO9%;XIW4D3`Vwpc9jZQHg<g at uJ0
zWaAh{_KMf$=H_0t+wCT&)0v|vX+$1ckX`V8QXQE<aYaSNt;xyBFOi4$VS<1F<O6Re
zJ+uP&fjfXFAsh10Rs$9N{r#H3!NJs#k&$%2-=7K)i9}L-KA(Cpv0AO+j*brhp+kox
z;CtXVKvLg^{{;oW>&Pcztp(%b<MGPMN-Ka?tBtp|w))%J+9XjFA0VqZjdFBTAKmj`
zVOm*<*DxKB>2|v_0n45}dltI7x>k#dilV@%vecK<Qxixa2K=u4-l)}THGO at 3_xA1E
zCm`GJFpruX at YffTX9W?c0Ln>{`~M;UvctyzF^cE+UGPN7pC^GQ#!CV(oWLJB3Qz8m
So>W2r0000<MNUMnLSTYu6tGPI
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/media-skip-backward.png b/src/qtui/QtUi/32/media-skip-backward.png
new file mode 100644
index 0000000000000000000000000000000000000000..95e8ec7e7ecd8bc198a3d86926015506fd724d76
GIT binary patch
literal 1099
zcmV-R1ho5!P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11IS54K~z|U?UqkWV^tK!fA7)q3W%1%)EN^Q2P-sfCXvLbA+o65
zNlA!dLvTS at AR1!Wv0_8ggcTdZf(7Z0#Y8iTnz-Ok0!A`eqmmGDnt?JyH3Cv*D9{3z
z>*C#)lt&A*5*M80=H=b at -S2$&oO928nv{~OH2q4wUkkVv at P82Cu)V*ehGoaVwt5ya
z4R9--XF%=(UoQd%un!zqllc+Q0dFJ{c`FbIv<3o!){&8sJ3vhl!b;#Z;Ku0aXdQ5~
z2(ApM1#T+btuub5l-6)cDeDcx_!`&(wt~Unr&7w=JPcAwmzt|@X=(Y;;c)!mcDp~9
zQodosIi-}ZNGa?4`}^N7EiL`lFpT?B%6jz;Ddo8o;B-3Ia=F~=03MHLGyju{MrAY_
z^+u!7&khd{-vf>f!}!h?$!fqoIXU at 4XJ=<`CX at L9puD{N8 at s=A0(4!^0DAysWo0?c
zJl6nK3kwUbNF>soPN!R?lqJC5K-T4QJypxyK=t0<o--H>wr^}~bV at 19fHbi0a5#1@
z6 at XcASpZGbPB9C|sH>}MO(v5cNhvFVT_6KUg%e7sx2dV=-NnVlkA)DofTv2N%;UaT
zKuJl-396cPT|W(lLXGqD^F2a{TIF~ZIL%+9X`1Nm?Y$j~#XdPYI=ZXGtpX<nxX+lD
zcN;o^J06dxEuBs`sRdF9;m1tLR-qjzTviBiR|(&=B51d&s;VD%c6Po3)-0}b5zsX4
z#3B$vc!30Y=eCduA*z6N%wAB`6!#fB*9kREJ61c%_4W0A-_X#oV!am|ZEbDy&CSg}
zU4~QK7Yk5%$^zNO#>UN+m6b>1<KuC!*Sl at a+lR;F*`Ax5OHEBpJ at EN_sbaW7HBcx5
zRuSfAXJ?Z at yt})5>+$2q4+jSamn$kN_Ut>0$KzYTgK#+fXCjeU9~&E6s;;h17l^=f
zr@&HtidlSL8iuhrG&J-qnM@|Sy1G_%T|cyNx~>b%I++A!dwP1(sZ?rhU|=BOa=G>`
z+;gSC;c(amfLXD>0QYKYYJQK!VwvUT<wv1V=r1L}+Sw`a5ct9{jQH^IaAtjdeXXOT
z<B6{8hl;zX00|Hb2D5&@f7kE#@A`Z`VZ$E)bHIJS- at h?4GjlLKJ^dsc4j<WYN5Id(
zJ+IfBn3$NzE-fu>w70kK=lg=QeE{G#@FwPs1 at Ig22XL;1Vs^e)fwwU`-mjSHDr7f+
zcYqQg4y1|+(14dQuTX%0xa4eOMzNG4&Bw;=Qn;cK_|NUif61-|Tno4s at GqW*zSg91
RTWkOT002ovPDHLkV1lr3{I382
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/32/media-skip-forward.png b/src/qtui/QtUi/32/media-skip-forward.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e73ff24755dcf3fe5050c42321decded15e0261
GIT binary patch
literal 1108
zcmV-a1grarP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000ys000ys0gnww$N&HU8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11JOxDK~z|U?UqkSV^<W1zxOA;L`Q29C*uqq9c|Q*ECx#pt&)Yh
zC{zoXB1kuaMWhUZBHf7#p}Gl3ppAus(00*nTdB~6AlTB(Ft%Mx3!$ZCrjCk^lQ_ni
z#F#g?i at XOhd1_a+3lH4IyZLg?@1A?ky;l-KaGoZgYxD~N7Xtnd0 at RZ4D&P{Z4`fdH
zpAD!6a=^hUoC3Iu;t1d=@Z1DSGf*FmMsEPufonz}EAvF7(H4Vg0PH7l?zy=+uix*#
z<@ft<_4W0=30yr!2qDZN2_afFP5Zi{qT;*p@$qgUM2isOvJgTk;t)bK)z;R2tg7md
zy}iBf3L#pB5Lbl|wi51IAP~3>JO&<Xn)a>1N+wfQ1B#+-<#M^3kx1l=>gwtb7Z(>_
z25taOKr%T^(>C+@{Pm@!rB5m=D?gf<nR&(FE*EFk<#O!++rYNXW=oXDD-)oqY7%$^
zqz(=a-U@|6Uo|u|yq8X=uNVO?0od*Kr@$t#oylZgpPHKb-0gPXj>Tg2Kod|4NDhbN
z5J&@QS(eM{#i|RAfGqF?cp!wxuCK4Z?{qpBIyyRn7_}iul5TK&z(XO#UNV_{r?a#3
z%jV|h5a0o-BuRQ<a9P9m at dcMoD2kE?4vVI;z!P29-LY6~O4GFaLqkKK8UjkWq!7ZH
zNF+W`RrT#)F!-6n;n+7h!}l?hif%&*XmPn*p;Ri>VUZaqRJ#Yz6h*nO>-tI6Z=+BP
z)rz9TbzPSLoKELY$z<{y;7<xIS)Kt&lJdrCtjtV#jjroXAax3t1}b%3e+k$r at _o$8
zYCw{tBMK=yaRh_Gd!bP1hqJi0wzl}_=;-(6x8eJA0meRMt%ld at -B?~;zPq}*y5VxU
zc2D9w9?$N=!opfS9{;Poy?w`=x2l1YwxGDUaJ${lXJ=>EM at B~Sz!s2LTU%=_<*KTx
zauX91e@{+M9%`DF0{&Q8S*ZnHE%JS)0J9CT+wJ<;*x2Uu^mI<sw0+<XkN}!wSvK1c
zS(e4%;NVs`9M06$)n$QSfZu_7MNw)@&T0$F1gNTdB+GJUU|?W35{VpoJf0lzEAShj
zo184mc_7=>)s>o`pMU1_`Cb at 7f2MFr0iY;~c at Che>e&MN`}>~_4-Y>I1OfnY;2suT
z(bLnD3x~t&-QC?X at Bp|=;ifxgUawd8`Fwi-jg5_Eex#CD at fF|=V+An^EoWs;;57=z
z@*N6wVP!Qy0Jv#<Zvkt-#z_L8aEO$p%EJCFS4rVb0EIWkZt;&+0{&Aw_b1tffC~W^
a0{#JdQI`->UloD?0000<MNUMnLSTX%z5FWx
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/audio-volume-high.png b/src/qtui/QtUi/44/audio-volume-high.png
new file mode 100644
index 0000000000000000000000000000000000000000..78775077a23e727f98f9510e159183583c0c2adc
GIT binary patch
literal 2413
zcmV-z36l1SP)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H12<k~hK~z|U)tOsN9Oo6se=`d#w`IL}HVd{xz)8RcyTOhGGO<Y-
zXhVXarUKP!A5c=oSasqD*GZb^2q&`oP~{;~Ejf1j(8R4(9LEodDvK7U!L+f1Lwrfh
z-R8Ci_A=mQ*`59RFf(RYgJY;->LVR#F5h?NKj-|<ne%-k2_blpL|$nCOO*!>aKZ{d
zKND~PVPFCXecuFW1v#vs12!cF3<9%vo3v7t$TXCcl$3)71qCk{Sk?lzyUr9s+;7bg
zLgWh}@>5e&|BOzB;p*z at I^+7oLI`QG`S%-anh at eqAw<5z;rJtP6X*kmBuV=2;K762
z4bbkzY}`){I{}Y*lAD`bH#j)BTL=*XB*0~}*#>+*--`~1Ljwj_fY1L6ho$9!RTO3S
z+i$=9P=9}aXG257DL at 0Fz@(;Wj}#RZ)fu*x1uZQjtf at kXM~u)tVw~R-XB`g5VPL{$
zvvrJ&jQltfiR>vTC^!aOF!UQqlCGRPcW$#WCnetAQa!v1SO?gRb31xw+ZP$13_Jwj
zbUOE|s#*t3YnqmumzTFUAt9mv<jIp?CM6}!7 at iIZA(Ebd{`r at T`R;gwO9AXQAD)$!
z^`az6pXTT1SF?EdoInmB4-O6{OifK~0fK-Zn4FoJ*}iq_*0mcpY#6Jnt7|s^Yk<$^
z^VPin{`;$p7oP8o1wtqZA(Dj<=@wlhgvbvDgB#M)(vAXNz-zPF+KtdX7H7k0(xAM&
z{Fg$A{I<5Xx|EcZPl5A>UXf+_-_z66#lyqHdy<lp{to=h&~I{ba(-vnSbaB2IDqwr
zXVzFWy`!VUt|-dyr>Cc at 02LV3G|kL<*%GY`j0DTb$T-l}*7k?0s;VtJcI-%d_uY3-
zq9<4s2*zSDWz(ijmD$<Z13P!_{L*sIH#$06YS>G+0<@O3G;}`F+}!Lrb?Ve(<_%5L
z=<MwLwWeu#Mp&neTS-EQ2IIIJogV7}$?0_N4+evEKtz(H@$T;KJ?q!6-<+G9TRbo@
zP;Ab(*=$qMX!JLqeDcXpYHMqE-UcQ~tJ>S!8%s+|!|1g-0`r?61;FF+G<v<>UvcLr
zQlJ<5Tb65)xG{D>s;{rl4+euZ=zLX$5K3`z at r%J=@UKUX9I;haR&FxJM>S1T-h1yo
zM^jT%ufyR8sH&O{AcP3N{PN3XUw{2|tKnrI%!N?`k^pYryjg=z{^>X!1_B01t6C)l
zXeUmb_^z<9um%0II}3PKRsCsmb91<&qQaM*oqe6T at T-Ro9V)lkY~Iq+(r=kdK6P+#
zu+WTz`2Z_m$#^pj=m&1Z>C^&X;{glwgiQPV^Utq1oz4*h at GW5SqmMo+0(#2I$}U>~
zPkFuGLLl(O6Hkm=07s(HsQGca&4h)@+D-KSboL%KUR1#Aa=H2&8XCT}jGG)98hR8^
zpL_1P5z7nDYMKTh5)%`>7Qk9G8cn_zz at bGvxtJ~_D$w)flTUh$mk$Fow{G3a1Vm0w
zPJlTNM>S2e17u}o1>yjw#sgkx#jzNOrN|5rD=jUZ*T6&~5f?yFQIXF83qULuO9m(`
zEHnX|*G<4Sbjpf_07n<Nwk+}ad}h)CAW2dPAQTEsS)U`zas*&{dU_`A`5JNZLwPtE
z;Egxl$gu)mvt~^Xz&r1}<FW#CyWM_(<HwIXtspZqGbfG1D0)KwV1UyBdV6~d(fJEN
zSy`D6;Nr!L4_g6yJRTL`+O=zLD`1buV}77+k6j4xT^E7(AQ?dV*|TTufk5DKV9dNx
zT3YG at 7#J8>hs7~2mn#6^^Z6WBz!@1C!NmXzL#5TLR|h60CQPy~Rb-5guDZJVB~8<0
z3<o46B#5f2s^G-Lgw5~w=b|Sj0OjT7BLI_=lUY{4Znt|n9<W)~glYKIS6>~HWqFq6
zm9=z0uC1-zpsMOt=9W3Ljg5`hHg4SL+p}lS<3 at dr0?~wogh*3UQ&3e^IS>eJ#8TF_
zZQEu>XD)Fq%}+XdXZBQIUtiMs^XKO+fts6}U7ekstKwZMgg9axcB7Y{JXKZYl9H00
zSFc`80m#Y8QM<dl144+7jEsx};cz&F(UWZ7zJ2oS*|YzA_St7Wt*x!~=$~`!c6(%O
zZ0u8~)7b;`nqIbYcnY0wgL!#*kLBg%%>!0bQ!`m#Uq5sD^y%Bpx-84FIQ$V{!r^e_
zUb=M2*Vxz?{P4pMU8hf<_9Z4J4i^^}mxaS&1-N8R*t>V{O<?@Og$q9eCJpcM%rno7
zIi1b`I(6=#ged`_75E!)#-iu!c6;FCk3SCW+qZAX02X=r>8B@*c`-vVJTxH7^5_R2
zd=P7GZ5`XZd2{&9H{YD?>gxKr5s4 at e-LhrN_^w^Md`FKSO$i2r`4(`|UAuPqjTbO0
z1+cWOsw`j|;5mHwaO|zO-pV+3?3llzqM{8wyf@;;E5K8Lr?<EFVnIQ{Z==zu23#`-
zbaZqKmz0!rxm>PVzu&(W7zId6OPlTQ at Bd0sl#A$%*li9kWlc8<`~w)=y?eKO{rdH(
zii(N=bA58WjH5^EqTB5bBqt{iVDauNue>r^Qc~hSaNt0q-|ycFj9?_&Yp=a_Ls67b
z^uA_ZnO)9CN(!(E*a&<D^f14vj~4|{VzJnd>g($>TUuH&D=RC5pMCaOBpeQZ<#M^2
z!r^cNFa(gDogM1y>l?P)?O&j;G-j;Ema~x(0{#R13F!JBu%LU|C(H8ei4!Np>#x5)
z-qO+%k!AVDx^?Sb2#3RK(dncC+Mz>-#_e|dAo^-$Cf?Zn+^V{r1HeR4QBmgQ%a?zF
z9wil^q at +Y`Z*QNJW%&#AQg%n1aKHD5Gl3FdAT>30Unmr^0oMVtva)8ny1D|2qFe>8
zuy9`7_x<5X;7dU3>FN1PMMXsyprxj!&Yn4Q#;+(!5Z$xmiy2s{9r!HZsc<-~)YR12
z_V3>xsj8}q0PX0N<c>brl$HEtum;$UPLn9Q=P&a;-Qr3D27SM72l~h13jgOnWtJrm
f+<&?U4)A{g0ry!NS73kt00000NkvXXu0mjf*?)`6
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/audio-volume-low.png b/src/qtui/QtUi/44/audio-volume-low.png
new file mode 100644
index 0000000000000000000000000000000000000000..032e10a07f7e4f65e7c0048bcd9906f52b64b188
GIT binary patch
literal 1729
zcmV;y20r<TP)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H120lqdK~z|U?U`R_ROuDKf9IMwCdQ1(q)z_mbkpocO&aNL%nZ1S
zs1QV1aUu4lh1l-150--TO_1 at ah2o=75PVQXD2SA;6a|fKjhl6Lp(NG(vFj$;{4rx@
zOyXp`bNX=a#Os%dnIwd;;DL`j_xrwc at 9&=PeCM8XM^u#`lUQpFuvB>uyxQ^}c&Q>H
zyF?_I at BB3d7Li8ar@$v7Qksv>ngNT*cHn33X#vn8BI_5^TT2U18Rx}7%VJ6^0baKp
zB at w9=k at c$jJ<w+imy5{Ocj+$&cq8xuPzTfkCHX44Zt!zpw}@CkH!x~U+u at Gol%)cf
z12sU_*9w7ZplE^l#Xtb?xv=$ae*kDwColLG$ar*$c;nkE0uBNd0F{-MzY&oy>+9=}
zx??}dF+Tuo1p=v5>Vw9{##&=MBq9~6Is*(CV;_k~VZOi?&a#(!S`FY&CX-f4Ny#5Z
zMn=8>O8Wczf9dLM0K|X|0PNqtf49%)(`(nRJ*%p!@>&vLr+a(?q&@uwI0jl2*pK6z
zH9)1OZG7<Hfv=*X;*V2PQ-^^h at PlpJ-iu~8;T&vfY3c9p-o5+h*4EZvG&D4%&!0a(
zY+07~!8VIXwW_9p?+lj8T)^T<FE;^I0MTePc;m*653>WdZ4-;dzOZe(7Dxau-J$iW
zdcyskUDjFvzu*76L?ZDykQR~gSS<GIUAuP8hQr~|!-o&OKL1=*|0yEnz^9&m8~9RH
z-&&Od&+iI=U at +J|Iy(9*=7%i>#(-&0U)q>c1kl#jR-Z^DJ_B9=NmZ at byLa!YL?ZF0
zvuDqaA3uIPluoC!mMVAsH4dZzpWD9<XK##nZ(w-_3jxN)#y)eOZpvswz@!W5ZC-f^
z==JN at A2&2K{1tc(%mSmyWU at 6HjRub#IWoO%+cvMB06{lmj2PD|H_qpP=X_aJZQv>J
zz0qFgfHi?Lz&Nn6qobqS at AnV8z|+9Q)vH$<0a{vG5{6!ddz>`-H!K9~l`)*9na#7A
z5(mc1%F3ReIC0{?o_Q04gM)Pdt*xyyhECR}Uo8iChTN81sO6HEKwoon^C-^4r+`<}
z)6?Yu_4W0y7XVunxWMdq2gFk36_ANUBLBm)3h8vZ44|&AF75OAtW+wMjQ}eGHlKdk
z5|78Tn+^aGF<oKFvRW420C48anGhb}>gwt~fWE%ILXUOfjb%-XnigL*;1YoT{{99W
z{{>*ro;`7Z$B!SI_gxWiuARRWDFce`-Mi<ToSgg!Pi&1uB5{B_ckY<kUDj1h;FNJb
z7bWJFClCnadO749CD!4_)T2j_{?@i_3pcD46cnTmA3mG_=;-L!Way2%NB;s3G7s3!
z-u%?5Q-hXe%`Ovo6ClTq9ovyiCO-kPQDU~ez5U6~ojc>VZrv&x931r4ZVHTuh%i4x
zn=paB$xkUxhV<#cz`**ht}bs at MKl^Mi^XD_%?qgNU)-MqI2H~ilSwNa4j=F7=_vvT
zg+j^R-rmW=!oq(?B9Sefot?#=ON^`Pzj7o$uYtdt$&VNx1IvMrfe(2*za^DQX<J)c
z at y(kzv#(Js%gWfcec3(jcW)8|wq`P!-R<q|>#kh6QugT4qaT`@nuac4zC3dB<jJj>
zOvZcDuT*u|E&08b#*nIZnFca}!P$uAIGZOc#lZGVCbRkU>C at JQ3m3Kk95`^`#qHa-
z|Aw=yz3vg5G&P*bWUB7pzyEsQzJ0HHdV0P&c<^9oczD?RcAZew`)+xE5H|sH<!e<P
z%m+A^hzk(`f)_7d%$z%SuJqESOD_%`I&>Fjb38M2s(>&MoSB*Vy1BVI(B0i_es}0l
z)p!o;rh$K`>b#d&zQ9=txX>Z@{5cTAsTSsiAe?wyGc+{xtfr=BJ5G(4m3~$IkBAfl
z2Y5TL=~mU=TmVZ21}C#>0(Jo3;M8N&@6-U?DDW{(`85i3x<g at Li)ZQ#aNFE$D*>L<
z<&Dqgr{F;E0G_DoYY}O{sUf}c$o<HYQ*yoO@|7h&sasWa1Bl2r=EF|B3l`S)+nQMw
z&j4R7rnHv8T{zVZIPtqvRda3Jw`3(gykc>`p|t={Rn;s&bL+hS+iR8OJ at 9JFj}G|%
X;^%Y6HZiuY00000NkvXXu0mjfidsvF
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/audio-volume-medium.png b/src/qtui/QtUi/44/audio-volume-medium.png
new file mode 100644
index 0000000000000000000000000000000000000000..a9b18455ec8c1b420859e8895aab4227d7904fdb
GIT binary patch
literal 2072
zcmV+z2<P{SP)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H12bD=gK~z|U?U`LnRNEDRzcVvBaFxMPxC30A3RYCS7Q_e%RZIj6
z3B_D{(U6)*?lmbU{w1x6p~m=N2*&iGYT|>5sXmF(*lKvNNmCWPsq{t*A^x=TBV6!j
zfEnh at 48t&UX7}No!Q*jMpjC1cSF(~}pSAb?&f06Qy*5V at Lhxe}(`*AwS3UuMX!!&@
zU6CZ|XObj2rfNT{z>*}b0)7G%NRnimN}rDnYzLMA4yV)kC6KMPTYz<vB+Y%_03Q=L
z4M+v%0?BoCbvCQjs-OQeVBPx$nJKUY%$bIL8ejuRNlE!lV`JmzhYuefuBoZ<n at lE2
zXSYz2q|A3tJcE<YhUzIZpa8>w_Z{}10}B9bHrqj;&-b<2Z0_pp?EE%6J3CTdUY>pX
z_HB#KJ_!6>2oe2%0H>nHp;4Xz{y6Q)fCC^oIr+D;EPt&5SrZZxT7$vh at 9*EgpRjrJ
z=A~}8JEH6NNC?pt4`8YxApsdN*tE2?ZzM^&k&}~CsXb4L(<dzk+uz at B@%#O202vqs
z+~ecp>kA4BHWU;Tj8|4x8dqqUBuVi at P6%OCix4772w~T$QwWhG%kqkO^XB~tZ~-o}
z+58V7M2 at Cr-56=H_L7p4Ukf2}T3TARCMG7{0Pbn}$Ye78Q<miweSLko>FMcT0aZH9
zjKlVZhZmuynsn6Vk7+_%Tbnf{CFKu+K%fHf0WTCq(I@;^96Hc8n9XK8*wWJS$BK%I
zH5)c;n0M;bslNabP334bnv$27_e-bK8QHXHlhMm*@f at s=;RUE0gocI&$Mx&ie;RwB
zC<^WE?Yk63$wFP$SiH^^LTuB1_o0T46DDJJD-f0>X}GJaYj<{b_Ua`|mgM*K_2tL<
zo6Tl_Boe7>YHG6W+_^I&91h2T6ySz&^XYfzA^?ZOQR{NKcA#bfy$E0k7}K?d4K|4Y
z)z#HGvMg7j#;Z>Vk&>UE|BWomm(QI$XD%x%`%<%yD2kGD=FFJ|yLRpJrl+S%{r&wh
zU^D9KzSK_;3yC=~z at ed`D(&q827QK_zQP98iyz?1l`H?r&CUHYFak^fE}zf$i-v}V
zP-$tYCp|s=2VRAS at 5G4{C046d<mKfVGtEN7-;=<Tu`Gm8fTzHKLH%)Hjlf~R1I)W~
z=gy<#<mBfX at EG83YHC^qbQc#FKhy#HT`pHHKyGes$S_{Q+ko{l1cbDSrlLj}20V7V
z{pq%C+y1Sya}N#<E(Lt$<>k+HFFc_r3ILgznaWIngT(jb+termHH&nwUAxw$y?h85
z9~&E62neUs>E)G&BZ{I}0TwS_95x))Zvb124R3*%u8afGqN1WcbgK{!hwT8XR;}`A
zumD7((FB03tgKLCVxlP!2*f-+CE!S$wi$`X<B4rL03=BY0tACWzkVK*$uwmreJBqn
z0314W$cYX(BO{|5;P~<5c67k0si~s?y}iBGU@)l9yW<}NSOVq)^z`)PqQ)-(#l^)Q
zfR2ui#d=_e!{Gzy>+7>bqfvb|HYMPAJAXQ|5U{qkwpzVj?=p0Wzo at 9lqk(0jbBx_?
z_W}$I3>Xh9W15=;o?M1SixzoDMn*oHA*@9Mrn0i~TSZY!Xb!MgETW>KLLM0zF^`Up
zE<xwLl9H0=01qENG;Xq>ae`P{3!|QH?Ay0*&}1 at AFtfB~1Eeimwyf~^d<CfW#RM=>
zTU+~N<;s<w-Me=$i$o#`XerHNv4rdD>f}%;Bz1Ij%r}hZHUjI5A3N&V{qx at 5-nsYg
z-P7ko8X6kx?d|Ogi~|TE&S^jUP(A#G&*w8078ZW>`0?XJ0H at RG>+0(A3L)BTHrv5a
zC=^7iN!G7l?`~~vz1`H*G`3^MjtpH4M}WV+tN8Jt))YTvWo0eR%F22Ttg5QYU0q#0
z-rU?gS*)8(CgU|G00feflF}YLc;Kn6t(7lcyl8K3ZuZQXGv`@;etvN%6iNXe#5(NR
zvu6kxzIyel!?598 at vce6lg<US0 at r}sI{n^iwR*2zyB6HPfBzs_IBeXwaYWZQ79P)l
zmnM_x#f1wOqBn2ee7Sn{>QH at s{X}PH=dXY+&3lnGYt{_c)YN#oySt at Zw{9gFSY8-m
zVd{4}3HSo_8tyoI_H6Xnv17LL=g*IpmX@|?u)T5Y*8+~7o}P~7%a{Ky5{W3llbBIk
zTidh3!otq&+qciXeEG6Ie#5}ugb;5WVl%mfu0t!*QOm~;)M{?bU at M{C^|F0FpEn~T
zW0&9WAJ<^myLa#K>C>m(ckkYPSXNe+6$k|M%l|)LLSr%nv;gg>Dd!3BJPs_pD){@8
zl9KRxz29%$x^)nUl$DjaPo6xfgu~(P0|ySI8DN7z&)WcI at _&iRz8ch2>@t9L(P-3B
zUtced962J*pFe+~rluxv>Cz=*?EXs#G4LUPrz5ZJ0bu0l(W3*6jg6_gI~;&p2=U!J
z2l|NLI3(12V?OXGIXQW;EX%37=Ru%V2=T^o{MsP1^-)HWBok1Gx{)KmcR~pHz5QnM
zE0PAi4tOerc=<kim}TIZ$gF=dn67*R{?PKH1O6{ru7ozcj!z>10000<MNUMnLSTZK
CPw6TE
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/audio-volume-muted.png b/src/qtui/QtUi/44/audio-volume-muted.png
new file mode 100644
index 0000000000000000000000000000000000000000..636583f0cb37225375b145f8dd0db5b6a733eb93
GIT binary patch
literal 1412
zcmV-~1$+95P)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11p!G!K~z|U?O9!n)KnDyPG^|iY`dDMNPvvU3lGL<6xIlcJfI00
ze*y+25jXx2d@(T7b{7%}m&Sx2x$Uw}SP~53LE{?`2}p>BD7Xm{_d)c*7haagst<@x
zn{0NbJ-!Tj_tKr&L1!l<e95Hkch5QfdUAVu?j2%g+)gmsEudN45!`Cr5!@_%-#;j&
zd~v$=)Xpjq1i=6^7XXwE!&qJ{7JqEy)3yvtDR<Vy0zh|?BqvIx((FclZ4*pHmo at 6a
zN~LlX0M+xGalul`&81Rlw&OUT0NAIFG4qNb2wtz}KcjP4O1YDW1b}nh-QCZOjg7^Y
zWt{}@oMLt*48ui2i1D--GnQdREC4(mhT#DrL_$RG0#L=}Ez2sTgaB}h8J1EOh^U{4
zHrlrRMI(F9^Rkv at od@uw$}{sS*LBbOzAphd%Fth#OlCo$P`IwgYAVB?=NUl|l!#~m
zz+7hD+{nlG{T?AiHA#{+0Iq1mdjXJP7`p)csqlBjahzJ4r!Cm?ye`YKjx+On3jJ(7
zA1UQd0K-8LJl5CO_bY%6>NpWC34-9&VzGFQnLk#?nEB<jn5k1D2!cgPl02>jw*mC%
zwvOYZmLYA<UJApoM+h<D`~C?4YWB`Kj<Yfdf at RD+tng77hWF_&UpD1NeMGdEi0anE
zdXQ2+tcV4GM at -Y)0bn~bZzm#E at bZCyfqTm3@&(JXeg|-WjW<oxTm|5i8vCXxK}1C~
zDBg|Wy6#UzbXbeKb#QQSj_bOY0H~kf3^PA3gh&9KoFvXLR_L+Q=J4GABK8KV)oPK5
zMinX>$8iq;F!M3hmYG-8PDfNeNs{?`+?Lhh{{H?lGk>Phi)+WPHU5Fx at v2G^(L6nF
zOFtaUd{Mhz0sw|#T-8kH*W*>RRB$Gfxu{W#0id(9Qx`T504kMADzBoYf-9BE|K6yy
zI>S$B)Cd4XQKY}vR{>zwtXX<S^^CVxFcD1>%*-PIkj-XOg~f54`XDM=CU|IQ$YSR8
z8a)C4Ns_G8_)!2b45RrBYqj&1F+M)NAHYI|inH15_qFr2+C9Gl0A`-l4gmN?kDHd^
zJ(%2|HVrA|Qf7WfqxTgGg)!gv9|G{G!dE9ICQf;tX8?FfbztUi8w$2<`=DVM^NDEb
zjUO{F18{b_f}<$<4!{wGx)g??001J|rI~-TZQHg#y1KfS;@>_30KzDWzSLvi)cgQI
zu~@tY;DX8>I&^4txm-RB;0=Y2)BJ at HiRXD6Ez1Ic4Mfyi>(rhCptp at fwFg<N at u$<4
zNz;DmHf`EeaU7?YnLkkI^HbRiA(Ai*H!|~T+qQog92}ej;8WFxh=v`<IktQE?t6(y
zpF+pe;x=6+T-V*f%x?p at Oho(Y*$N>N*LBa9N~Ml!wfZ at L1$sCD=;-L!4&ZKuzn;tG
zP9X&|vTF7`&oE8%2od%Eb7P|Ywrv-slnaUIX8<|HWvk;jAEw2ckyW!0B8j5tEh4(n
zy`9eI^RDN41`!>AB9 at 3o!!Z14s#r6&%ojo=`Fy??z at A(#w|?Eab+Kuhdog)W0s!8h
zYEJ at a<7QwG1aC64TKYgl!?ta&05GMfw(YGk^BVP<h(<G+%qyrP7HFg3FbrP<aHe)y
zCZZR%Y}xW#Bfqxp4||^1X`1Fy!!Qoowtcd(N1FxT3flgcL9 at 6cxYfAr1pf{7MCJ6)
S!Y(iX0000<MNUMnLSTY^wvIOd
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/audio-volume-off.png b/src/qtui/QtUi/44/audio-volume-off.png
new file mode 100644
index 0000000000000000000000000000000000000000..bfc2f8069cc755a67c0881977a85f81859bf1973
GIT binary patch
literal 1318
zcmV+>1=;$EP)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11fxkrK~z|U?U}nzTt^g#zq4j}7~8yGc1)gr1jmVmOodV;UD8HK
zNtMD%L5D;|6^WW6{{U5rv>>IiB0(Y-Q4)ilNH&%Uj_nWvhQ)ww9^Pe7ikZvK&b{md
z0xL`Wq|x0wcV_N)&pmVI%w17cUM0m!4N$C(fDc+nz{N^L-WQRULfe-VSVS%XuLGST
za;lI%B?A_b3&30Uv<&DHk at 9@~N@?L2-uZE$D_^HW2NsbxMWkF+XMq{-a=nPWmaG3>
zfXjhq%<F6gDhlmr-QYdos))pZDd36M?4rFEsbYaoU?xc|#_vu6XYKDoV9(pr2H>)q
zyx<QY?KG_-<J<cJt^-a3(%jtqm55yL=;-*wj?t6{RwCN8i%6rYZUBFI*UpJZyii~P
zDlyg!N(<1GNF<I`S66?%xVZQwP(3|8{h94knFF at gTJkqw!@K;hJx&8jr at qYIGcWK-
z;BBBCW6hw{jE|33wY9Z<v%bFmG4KqSPo+}91c|hUb%SmZsZrG};Fi~<Rzyy#Y7%(t
zU2BaR)AhY7pben6x3_(4Y^=j=I5RWz#rF1gJFo&gx7EAmrk>AU5s at 3Jnh=o%vaR<9
zFbB+Ij1{O^L}IGy`gay^13*(#)3v3grOydlUx7tn-Kk3wArU$0z=D~a=Ye~+xWM(+
zU!MY7WTMV7jNdP~W4ln50EtB6Qy_&2>~5I at RxPAkLQ>UdgkSMHB2uBMYrvZOd_ar!
z^98R at y+5{V;h4Qy3V2A4*Il6QU at TPSfYn;4d5qNqH3G93gSZM!=BOyKh<P<H3oMbc
z5B`r=U1N_+UVZRToB4pF0=^%5_M at lXd96L}2DT^QNWa{pR=o4T!dqVbzJOE3a~+-z
z+QPNoc`&K`gekDBZ&BakB?I0KY)`<u&irB|B4xlCuR8GQ2CqJt=svLT>setf4bafg
zutIoo$W?aJCCn}&kdm=*o7Xl7b2VOlC}O$5n*aj?1CQhJ_~w3qMWhasK)ISx)lIu>
zyNiYb3pNGyGqmN<*v_}LN_&&;<>lr0)YR0 at g>*WteSLj(larH;{s5{vY=7Q&fCcyf
zliY(@if^cDT12|Y&cv2f^=A>O2fCg56mZ>7e#HA2SPfhSF5s<#$z)P{dU`5GM at M(8
z5R1jq+uPgU`oJFa84J4>0R?bVRsXeHes`xar>YZP+tAYd0{98|4*1?FKgQ$n)sc~r
zm;L?ykFf60+1VMqvQX@{$;|J-FBY}}==7Q`Ti9|kZzIsWKV}qgpl6t5Bq;ZQAAp6S
zp`qCD at bGMFYwPOZ;9!t-MK0%Rv}8AxU1V~GKzHr&9NC+IB;m{r2)jf+od7<>Y(&9?
zsR`f_Il`fJk1K$?g at 2%`cSPhk at DbU@n^M(3qsA(B*Zdq918!ridLQ^Z7cA_!$89p%
z+Y{ifeUQr@#|H3Vx3P+~@V;aLF9Or5ni7!?vbRM5x9mrjNag*W at PEo$dI~^9&Ju=Q
z&IJpl{kG=siZ_6p`8t&ncmlJ#0TUK~wVwiV>QH?+bn{HOd#I|BVJy_==x?tB))DYQ
c>y-ok4>Sg>YArqq6951J07*qoM6N<$f|tm7c>n+a
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/document-open.png b/src/qtui/QtUi/44/document-open.png
new file mode 100644
index 0000000000000000000000000000000000000000..dd3928c058260058227a1a2b657d7d735e4bacea
GIT binary patch
literal 1038
zcmV+p1o8WcP)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11B*#SK~z|U?U~JM6iFC|pH2;C6T^;}9U{Svta_1z-a{Y<VJ^YN
zgPs&*=?p=^gEtTMzo8eeg3yq_UOWUm?Lt6rLe}-Lc$p{?6F<jECSyLF>1hwutu>vR
z>5oY^#?1o-(=}CZ{pzi^s;RdP&-2(zWMZ`Giuk{=9YW&LO7H<72lNmvxCT^#_rQ)X
zm!S!X1HduBNNB4HyrDDEk*lTia1JoW#>P(1&COkJG#ba+84yCu=kxiSv$L~*1AQrl
z2Go%guL5hj209O)1iFL}e?*B5$Ye54Yqi>yPLygW1Mk9>VZmKU!5D_|06EKggy9Tu
zka!!oErwyd%4V~(<#PG9U$qE)3=3>U1=v6eZdW#dRb>2iR6NfcSYBTKJ(tT}^)(y{
ziwb+C0l0whJnvSU$?O!t#(kmaX(BARo8+g%cGBk;7kCNu0zV*E5onI#Zs2IKSnM7j
zAHTS?v~=Ee-Jkzs!2k#$UJeWl+ at G15xi>mGx{egT5f*#|_;F}x=+eT%!nNHH8fI{C
z at Xq4m;xw>=43#FqCjgPjWbV4Idl(r{pLRv5e0lW=A<Ff7{W3B{=HY7$cL4&xb=@rR
zb{9md)PXhEb^HBifz;U0ot-Pl8GQ>Zhbwe~KWgfBi!CoLo#3c9o0h4msXr~tT2Inv
zdV0ENVq)UABz=NSr at oSJCNU7;dEWgr{S3o67h(5?|FcMo7*6G3;0aIyo)f(X1n>*c
z51dUhh)!_Y4Ode7$GwG=l8(2X9!^W5 at wU^$Y5D(oc+Uym4~Yo&J-pNGdw8e$zC9e|
zC4$@lBO at baqH__tl9rY>eJxG;)I`cAfNk5AZ$+ at L1(a*PD)<9Hp-@<L9Ot!Znib at 7
z#VrBB{i|IOO8YIgOw+75j`O-uD6INz-Up4txwW5wVc=AhTMWZ!N+WrmcQ2|>3p*D=
zcGP>^KYr1A801XmfXB$oXl(NN{I7|Ww(nB`9s-Y0#DYHEsuG at 1a8uag8Q@H8rOo`M
zJ}4_yL~{{{^Zi0CwZMpJn&E_ViR3i(QEYxW6~d&+>23l&wr#IZPEPhJ^^a57YQnbd
z;MTp_s!f!Kb$kG at EUW4`PD$hG#F(bJ<~UBtvaG5)hK{HhZbj_VBq2|Me^HLHFlhyY
z%;OFN$AN5GBR(s at Go;vRyM~<zR!I|DDzQIKcKjhF>42T`88S(UPN?p;EdT%j07*qo
IM6N<$f~g(dPXGV_
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/edit-find.png b/src/qtui/QtUi/44/edit-find.png
new file mode 100644
index 0000000000000000000000000000000000000000..4bb3155406b0e89202323165080180278686363a
GIT binary patch
literal 2105
zcmV-92*&q`P)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H12ewH>K~z|U?U`*%RM{EFe|KhpnSo(=XRL_qvf>saXj`j9jG9tS
z#Ku64QGzR^YGbmPZemE<#1BoHG-{jJM2$&(!$q?(t{?0NV))Q%>#pwB?kXD)M8*K(
z;N at j;aF_vRPCuM8?&!_{S6$gAeUh6@&dYQD_kW+a^Nc2h;D1R>vkkzgSYC2p0+0mQ
zl at 7BS4+4{b4;TdkuL|%*(F~eIB9MUuJQE231He;*xMIpo0b2kUl2PjG>*rj$bZME#
z<N0AA5Lgfl26F+-W^;E!Lc%?l%hgs{S^4?Fg9jg}{XW2hWdAz{Yz2M*Sh~BrEk#8|
z?~ja({E~0XAeIE3PUpvW?%X+&o0~hS!1e+DS3)d=nCh_#Ar=TB3d+mND>Y5~0(gvM
zs|Roc_kcF_+*4ycYRzL!)4nJ#FRv6r6ewK@)0{cwGZn)YAQ!M?Wo6asy1oM$ReVUB
zobJ<TNSn6<q0G$8vyUG?K83XF?iuWl2`ZMj0L!XXt5)c`{vI*{3;`1W85tRmHf-2%
zd*#ZN!)w;8c^VfNr!_Y>+pk~0p4QaVv`E+W9AHGfpi|fN?JHKSXuome#&sYQ`K1g?
zEQS+-x#!QHPpPi1{;Lqe4m<&brfH#yii&Fu4Gs5`l9Hls4g><!*4Dm#;lhR0!C=sg
zWII{YwDF at ykN#@Uo;^drLtY|!!~#4YNJvgj-skmt%K#lf(=>7J+_{gpZQJHmhjjq`
z$j}u8vVd&hUBG_v;>Dz`Tens!&;XfMtM${dv9aGHneR0UIGSN62q6mg?c28o=mI_i
zJ^?=2xN+m3g%G=i5I<868Ou5BLWs3Oh+Q=`HGd56SGwGX4jn2{4rqEEPL~E`<mcyC
zc6D`aQB0DWnmXWiyRSH%&i?>+m_9ru081t&CYI*s=dbSR>B&*!j=a3QkKAteCEyX@
zH9~N-TEY&X>v}%YZi7H@?b@|%PN(xe at L&dDK}LhlxVX5kii(Q%upZ#+{{H^OYE7aM
zu(1GJ00MzPO2i?-qN1WcWH|B}(Ek*8ux#0~{zzSZzki;Zk2eZ9T39m!Xqx6w2LMn~
zQt|*9JB<`H0f4fyvTjY&CWR218V?x-8kSgb*laeNM~V1kZnyi1`e~#j)c|x|A40yo
z24FIo2GqP^;L#4B1VSk(DfgAa5D+?i`0zqCKhsJLWF5lp-Mimb&K&|miHV6{t9irO
zE*4-hfByVFBJ8fOudh(eI}GSg0_f=IC{}udK+xrKg%ieWVb}*yTwMH|qj<gEMU9P(
zNk}u931}OTa_iQugyG at gqDWn3Wo7r&no*;Gqs8HPAg`sRC4cGCrSAoU!8kRZYPDJ)
zj*X4|0m)21v16zmRf{+rj^B)qjxJW~iI0!>4h#%jayT5V$i!sGETS<y4)_- at UOc*M
z*RD^Ah at XDHzj)rfc@=8k9AGYxjI`@`B=asH2e1?t7XEy6bhH#04C|??s%m#Q9K-5m
zUyBWctPO^b962(QnVETC9Tot3dwYAUZ8qEQjvqgsf;0~ovi8VRFOl5T)RgFOI6i1=
zYx^~_F7|~1*VWYxA!`#u87?eS)x&dv;+B?{>?KQ<l!ii~_=xdzP1AgdiHSF}v$MNO
zN=iCxHrwRYt5*v=9#6j4>s=;<a4JylNTsJvow`_CTid2y!Ve4+5$|6Guo-v<Sb6N&
zG5g-Vdy6CNIR*9EW9$tfuR{YbPGn?cbm_YOQN&OX$@r5O*BS*3(l(2LAGNl&vT4(%
zw>mpJGu500NJToB9hnq->KP$+MtoP(v~i2YqNk^)x8A&Y^Mbnb=}5Mxl<Bfo0QeI4
zvaql))ZX6iuB)qSwb^WbHRnNk`d2^;a35KL`LeRIhWGE^-!e2b^jUXz_vZ%=9Jp;Z
zo5z76Aw=@T#6-Tw<N3wHg$sY%+1Y79-a=BR18k%(kqeXp$rBS3T)TG7bougS>y;~4
z(gJ~i#o=%SQc_YTv$C=#wrttr-Mo2o&}4d^j|B at B%<JszOhZN#E8qmOtyXJmdwctV
znJ{g%kzxaW3=}YZrR4?MfxAfd-deYA-A|gEn{!`Smj>ipt=6x4dwc(so}M1I>8PNM
z_SVLLe*tHJzah<~Umehgtd;KqO~85J-^gq>0`#t5zy7)G$u|yn&+qpy%E`(3U~q8I
z%oOHfl;M{ZGcryW?cBLD at 8rpo^P;TD0N%0N?YBK1&tDu4M~Em)zp3tJ5P7X1IC0{{
zSWQh$H{WKuAL#J;d_^vo>wT}+Ya$BMZ?fI$McxH_PM<#Quc at hd7zMNkX!rSi#dGG&
z*%JZU7FP16Od?X8z$zeT$BrEdXV0F^in1mfC`e07`^VtmU?UMNf!Szij{yG!dK(%V
z{M)y0kLHMdz+F|A0)#W{taaeSp!?38IWt~WRTXZ;L_QBoOH1z{9rjt9b~gVq7y+)C
zOs0n)e)!>db#?W#5)=s9Y&L&mV`C4pE_qhj&GvsBVbFaI4Goj^_4Na3X=(oD%a;$e
zwYBNFxw+x)efSPID^3?pl7ZF8(lsnW;P1#}^voo_FMvUYuAd?kj2GF5`&P5?`viDK
jGTSz6SpE<AyO#d~ug=8CPTfJX00000NkvXXu0mjf-#qZr
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/list-add.png b/src/qtui/QtUi/44/list-add.png
new file mode 100644
index 0000000000000000000000000000000000000000..7b2ee79ee8881a605c88551aac59dffaeee017f8
GIT binary patch
literal 696
zcmV;p0!RIcP)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10yRlQK~z|U?U})fQ!x~Vzr=f6u%a-GL*10pr8}W(- at s=mKADT+
z6S(&gTq~u at z`)GN9j+C%T6+^0Hv_Y1axy0ESm_6s7Vhc!|DL2LNw2cjvQOx{HgH=G
zhPTb$87?yAQSJ(1atP%x{0MlAJX$ND0=}h)rA`SAoJ8j7xL9c<f}~cs3#jRI`fxIt
zybc8#V_rDD4)E)51yc<xfaP*|&suwwm at A4bKe~RuzXIwUxg at d}?smHd_>m)*M6R|5
zu+EsvOHRX0##~<hy9z7XHsqrOD2l=oU*S+bXcrjoo;PIp0d1p?9fjBmKZ(fm8PAFs
zGIK24-z1cS!fD^iu*MCY*7}vT_E->UfYVTbQtFM61Eo}DjCtv_H5)ceF%^v2Cn)k%
zSkw{?YpvfmP16^`EVAK`5n2~gOiYEpyDOEL9Ab=USSi)8qaN$Dg2Ys~VMnW2j83fK
zom7}ihS%)Qu&CoRY}|*7*=+W~7!&NVbzQ6Rc>F9BGoR1jNoKUxKi%6ko<nP>!dJk_
za5$87SS%J|TN{l=VjhQe+8YTOUeGR&OZ*MJ0~}RVRRT{1Bi9wa0)Bg93~)|hE=zN`
z0nP&V?*qE7>rP0- at x{HKafgRc0LrqAS?RKHIB{&7Lxs0Zs$mPz>-FqlF!-9mkBCZq
z#-V``Z9jf4#J;5+g--+ynK6PX7~m5BLU5B6?cp-1La7zLiS*_FnLo6z$zn)i at 1AiS
e3~!sgGyDhfO_n!%eYH>k0000<MNUMnLSTXv!7+CL
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/media-playback-pause.png b/src/qtui/QtUi/44/media-playback-pause.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b2cc00f7a736b9de2b7f3e1282af22466b52b10
GIT binary patch
literal 402
zcmeAS at N?(olHy`uVBq!ia0vp^Iv~u!1|;QLq8Nb`OR<w at 2nP_<aHMnq`J4qFk;M!Q
z((6H(F-~ft3{X(A#5JNMI6tkVJh3R1p}f3YFEcN at I61K(RWH9NefB#WDFy~ceoq(2
zkcif|GY$O?I|wj5pTKM);&Q6EqIRE?wD~fFLmM<}6c;AsU*8p+Qt96HCh3WEY>xPA
z6{R(u?bYlRoe!?L6l8~q-?99A{LkedOm?4t3UAQ<p==PzY;%zP!POUhKYt_ at u)b)V
z{PfVZ=tYO+xQkb)iYYKw_smYe`|$bw)yqq+xCmDM4o?0Y9QSy!$fLdOjCE4KwY;0|
zOM}R>{$HHpRhzVbXwByMm-l9MPExz_4QH0{520p)GV4wG1!E3|cRt|S=e0*w>xUMI
zw~?*?jPNWKrM>Bli}fpem9CvUf5gUbQ(e5oj=t4iF>ayD>Xj__7na=dY5ceFrNIU1
in({Dn`97#WYS at BT#^-)}DCrLjKL$@%KbLh*2~7a=(w+DK
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/media-playback-start.png b/src/qtui/QtUi/44/media-playback-start.png
new file mode 100644
index 0000000000000000000000000000000000000000..790ea71f2e51260b063f694cce19445d8c8f23b5
GIT binary patch
literal 1091
zcmV-J1ibr+P)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11Hef{K~z|U?U`RlTUQ*%KPP|ZO>K%ZX0=4KZWQN(I1uqUAo!{v
zz6n0;B~R`xAk4vV$Uq<F#w0AnK_3QVI2r6wANpcOmyIz7WwQxwMN5rVi=9 at lXAi$*
z>sq(m+}xP1_=N-Eo_o&y+~4_~-|u%%l-8R6lU(%%s8r{`wbn}y?6EP%QF$u3_Yx2)
z{@w$&0Ml`zGEx at 9ngXr@?x(Ju00rP7aAvX5>hgLh!g{^l<ml+=o5isqpbao;gLjIw
z)>fKVYkf^?eGPa3Yy<*<)Y8(@+okJT>&seekHz_HH>)n;1zrbGN_`7l06a>m-S+nO
z&vUulH>LMS++>Fuxrv<}{}{3Ip4R$8KA(Tr<ME`1hKAlke7zZn0s-eR|CSx#W8etc
zY at 5KoX_{9T7Z*PX1OgMORO%A4B3Fvd>liK8qr}rL at x>|qekAO9l~Vhyt*zJB*4DoA
z`~4bmjU8Yci7Zvgu7#g%`@lL-&|3S~*Vo?(1Olm8EY^*<NfY8GjV}stsqFxFfj!eS
zudJ-BOdE#r{_N~*GZGpv0}*6JY{`yGd}?uSKe7S+N~wczIQ(@cllii(t?jtj{}9QR
z6}gEW;EyYL0B{j_6>z)V?)yDGJ)f<vu6|$aGZE-rtCKnH5~sCoU=1jkrrDgyWZr9N
zX!szJNW6w*&oGiLU$OFVI~M-P@~b^BKLThdrJgi3HGQ|dynMZ at tLsUze-kOJ90mTc
z3gD71BH&)7RH3`Odm)?6-az7e?!N|BQeKvHT>h4_+D0~AC>RX7hlhuwzzr({>jjL@
z=R1nW<2R?KruGcuuVSxIZd_e}W3gC%VPRo25{ZD+Ccgl8fP->l?Eu^U%7{cF+sR}y
zH!v`8Qk>^DkVO)XC7p?d4Z}E0BoenLCMN!Hxm*gk5Bvb!qr${dYhXP%ICyt{etx&5
zr3Iws_!+nb9NKtx?SMNvI(E|O^k!dQA4s_R9r%$lakiWs2X1U^Je;1Mz88<jOTNAV
z+(eQ>)#asQz%G|dkByCO%*@Oj1cN~ZJOX|KenTwmh#ZL$y}i9V>2!Lxv$NBMz}-S%
z_p9W4PE}br6bc>A&CP9%jEtz_r8~&-KcGe*p|*g1KHtgs`1sc3<fJwXLm_cAi_`&*
zWWs+_#lZdj{e@&Qc@&LCT}Wv970FbOorXJ2l^j*Qfz;12WVh!Ls}?xJqbjQw)<{?i
zBmS91{Pl%B4E)C!&d{RI%FZWJUH`>-=}+M6u5;j8>m0b&`V)Puv}jM$6chje002ov
JPDHLkV1m2h1hN1C
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/media-playback-stop.png b/src/qtui/QtUi/44/media-playback-stop.png
new file mode 100644
index 0000000000000000000000000000000000000000..d16291b851be1af4b20cf28083d011a45b134cb4
GIT binary patch
literal 350
zcmeAS at N?(olHy`uVBq!ia0vp^Iv~u!1|;QLq8Nb`OR<w at 2nP_<aHMnq`J4qFk;M!Q
z((6H(F-~ft3{X(A#5JNMI6tkVJh3R1p}f3YFEcN at I61K(RWH9NefB#WDWIa;o-U3d
z5v^};?&WJT5NUh3eTC1uS63^(-s_s&yqGz#kJ;ju{FB2|=9njD&r<ij{7~Rb&#bI}
zyc%Z at zLHt9&gz3%ajb-WYVEm2G9TnD7-!G7cxm;3%_gb4Xx$M;Td at VKeJfp83g<P*
zI&eHRVt$pKR+i>q?y}DPovhlnlar=4tT%FXRDH1ACvZaZ)wNQ8CTVg-edV;S at Zt;G
zp0&X~JGf|r75nPX;ZAd#uP!}cd)Q@}>E_=|^ZJfhD5ifZmNpOiE*a{|&HCTs%H(r5
q+ZtV^SFO&ody`Pg7Zxu2gSWobgeiKz&v&3V89ZJ6T-G at yGywo>E`+xL
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/media-playlist-repeat.png b/src/qtui/QtUi/44/media-playlist-repeat.png
new file mode 100644
index 0000000000000000000000000000000000000000..558e68d15bf5c8b6a11c226a5d1b28053e3c6e22
GIT binary patch
literal 1339
zcmV-B1;qM^P)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11h`2=K~z|U?U`RlTUQ*%KljEo&C-amcD8k6YgblVd=Q;l8fYIj
z0--(@K`3lKmf=btH89e>6b4e*`aTAG7=0CyO&B&bWtJ=v2J0BMbx!B(GLq_ct;xMP
zdpI}l=6VwoYa9i?a3MMOch2u~e&=`oC5jM&mr3gX4N$B0f$Ob(;Ckz&18%6%zFr+H
zRBN~$unPzPUcf_rfj5A4AOjfX43!EShYx6__EC6I>A(u`kJHO?z&@Z2ps%m*Tr!z_
z-!P1mLWstC5GsnY>T<arcXf4rIWsf!y;;2E1nmUu0^R@`0)fDAHk%z_?<QxVsj2Bs
zCX at Lb8R=iKrH9jS2Y`lPFxZ>TW-kLdKm+pBFga?J3b=t+vf1qAU@$lnkH;UFENQEu
zQ-og!yl%JqGhNqD0c&-FEGK_ML&ID?pZ^Fs34gP`bc(PCz%Yzf<ctNt<#Org&!10>
zjEp=Ahr`czgKTng^5D&zH{ZH{|Nc9MVH8<1rteJ_tLzb0fl~mAqTE6D5P%C8E<Ct<
z_wK{p0JZDl#fxWRu~@IA$SZ^xFh9>>NySP_mWCzaBaz4)unhbF{Ju-9Z9rEf5^=|3
zu`Zi$M^yseuzm at JLJPn{B<yZYz9qmL3WY$f3PtJ8=9Pi%l@@o-wXGH%{5h%;uzh>1
z=W4O$;LlODM7Z91;Rx>o0}68YI%Ix-TC2ak1oi>1BDdh8+G_Pz=}@EFo}J1K97n>r
zhlht>^LRX;nD1P*`l}lF(xpph%yOSuulSUc0yG0}0*4Zb#DSKUmJe><zWr$~mut5g
znr&AFT=lXxJv|*pZXCyKb~$7&T6d?C;qUJ54yID6D?*5XX+Q7Kc2&!oJwgTZp}Dzv
z6-$pbO*`%L`L6f(_qW^X95CU)HvHGFU2F4rJRc{M$q&uL{}S*c at E1UTe}B8r=ew?H
z+G(pV({~9^QBD!w0K6R?9qCvscHC0_RMWKXiHV7BMNu{jg%DRvXg_ciP!fs6fp9oH
zkWQ!HGks)`hw;trUQv{<ENwr*k_H_e9mO+n$?>2Z at H*g)L?X-g?%g|5C=`lxE68DM
zMGm=LM**d$r{`QMl^Qe*BVan5!*WcusDQiztsoES0zg$&5s5^WEi5H+nlu?e4~0U{
zMn^{<sj8Ys_CAk1t<3^)%TuDk!NC)ajg10W0FuC;Y at JZLS$EcKGY{yhs^&*WM<0bk
zp=YMemX21sgq{Vu;_*1qXw*MDJL^xU(+BN_tE;PD`2GF@@CP#b?`oPxG#Yi^x^?TA
zuIny)9lKguTAp`ycCJOE(Y0VOh}qGfsPYnOh3*C3MlMn1^c^xnPmq)DEYJyf=jZ3e
z(9qDK>FMdi_DVvC1&6i- at C)$333fYRkPG_>pdC1j{6WR8Z;-?Ox24RF?CeRvH9kHr
zu3o*`ytK5mSzicYy#%ZySB{^N9pBLpDNb_A`ErMO1-ZQS0Y^4AHpGn^H`KAQvBSAs
zP8C9YZQ4CSj!;#q6?i8qNt4CJMPq1a$TKxH^{x57<j%I8_5!%5k~Bf)z79ODrIEb^
xhX2x}2S~AXOW(eM{eO|_tbO2mYah7Y`WI4t&Qp4(1E2r^002ovPDHLkV1n<WZr}g_
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/media-playlist-shuffle.png b/src/qtui/QtUi/44/media-playlist-shuffle.png
new file mode 100644
index 0000000000000000000000000000000000000000..39e8c02914241e9038b5d7e51a9d3db7bb303243
GIT binary patch
literal 1806
zcmV+p2l4ocP)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H128&5VK~z|U?U-*&RM{EEe`hW;1LMrF%%CiYs4TJ at jZBPaXju})
zV%9cIwAS#2WCLlsZMUR~iI}*?#MSfz at q_7Nm$o4^X~afj+-M^1mbEeIC at vC6kYHNb
zZNOy(2b4cD16)o&oIC9>-WkVkfNa8(oMh(SIq!My`|o+ at 3MnPuC0Lf4z^h`J at Iqsm
z at IoVL3C?r^s{jc+14fO{2|+ADTU!rUBfif7L%?Jrn- at DJEEr_1R_h-tD=Tx2 at 2i0<
z=0Auzq?C)bEK*9VlrmpRnGcKrk6kX;A8y^cRbX7-Af at z3DMc(h3zZTY-~f`1WhW|{
zLWoa|-)KUJKz at GyN4>qhEynGbX=0WVmKZBhxPWy)CXfcC#MnOxJORd~l&KFMJovzB
zwSHVxRTa*0(=>_nume at Swira_fN3CPtZ_h(xUT^js4l?HojbR5c6Po!F){I$uIuZi
zl+Gx7kE8awP?4B*yWLl>UAy-Cl9G}js)KxOJm5US>*A0#gAN3Mr^bP60Ndrumz@<A
z6^Ey$rgi`#&i=1Wt|bF*AV~-j*tl`y$KBoCpP?M}75uLcTf$_85TBb_7eb6_nl_M<
zlJe!YZQK6V+S=NMibyKT3%2s|@;5JDy!cxw<!h)Y1dYR{Q4x9>CQzPqIh{_qfB*iq
zFYqutYyt8NVxJ{oSf-?;_)ncW^-)bt%@csSy1JFMwYBvI*{7(Kd1YvtHd9ei;Xilo
z+<?R30BFS|B_ato#Il8oh!rE>JRZ;GKp at a?`}S>nNlD4?bY0Iv<>o9vUS3|`i4!O8
zmzI_Wv$C at 0c~}Th9(_PTK|#;?^XGduZQ7&*Q$Q!sgX$W9xirt1T#LRwYPDL2ySuyp
z1W;O9dek605GK2C- at Y#{UAok7vBYdJ|F!4wcmj2Gb?sGERg<XN=mYLz5~VQVa0jqS
zDSvHd{lbL{E1H{|Gj80t at q<t(ly~IFk^0QcOnt+K4L=M9gM~mpDrecedGkYq>{FDN
z{*B6M4JFM0Kh`vDwz9Ia{p{JZ!$$arfi~a~vF3{i6>&%@*M*fR)(QrLZyr8;_-!d=
z{=tI>cL*W6fWHHu0H1ih-aiix4*pU~`6DUiN)xrqmr~|$-MaNmcX#*uQp#UQDc_Y+
z`V1wEtC(g=7b}KIsFvda2m}IJMn=XNUDwkLk6^W0XKvoS`H$k_;vwL+;q_>|VR*U}
z75<077bIAu|Mz&Ao16QduIsNG2kHPPPo8WqE-oGi?xRv59-aXI1jb0L<pJ}(=|G7`
zUW~O4 at PtAkv1-+-cgM!YcA}bj5SZD$dw1{AqesV{KY!jcI5;>5yoQqI=<_rHyWRfN
z>gsAQuQ;tGtaPVOpH9DW<;okKot^t;XJ^-=dgBnl>eZ{C_V)JnI-Sl39*^gpP$-l(
zIXQX8*cw0$>T^UCoe<)$z^vEn{j{Z}rMa-Ma2i!;0pbkxW_`H%B at ZcqZw$gX9FCCR
z at 4xT!`MxPCDsr~9wfzPVsi~=-_xJZVx?C>Pa0?+mM9H~b2r;^4%a*^~yLZoT+<v8L
zO^>mHs2R2g)uv|LZufXgOG}T>=bNmns|(z{d-rFkLVNh^*|QxUkLSaZl9Iyu`ugb9
z0F}dCK);mI)zQ)ME4$tP!J$Kk!l at B=T8s4X`(_ at Af;@2Gz at vtShOxA?v{|5|si|pg
zb#-;c#KgoS<2RW=P8=I;5ucNRwWz$GO;1m6y?*`r#fUVCE6qPQv+nhJrwR%R#*2!I
zf_wMwo!-8EJ1DUUD^gxpS65zHSy}e*@NkN;%?)G&D|oS>{JaPcs+N*9O&cvNEWB{%
z&Yd<)rnN|=`&S&VgdtHfd<Rt|Nx%x9&zIBJ*EdjIU7g(2)bu(kg+>yv7se1ORkGb~
zx4XQ&d_D6cVLHIS6T{e)LGB4EL<7w4pBhROz7HgKbac#Jy?Qmt at Auo=+uNNZBO?jT
z+BTa_uc at gSI)424T)b&560wvn(dM28d=J$DVh->^h>YlKyLRmwZES1|=H%p9h%v1#
z<e$(?RHd&3(ouyKN!Szqyk^asP(wq**q%LmG+r{TE#`}qu*!vn<0m$oZSL5yW23dT
zwHCYGE=XWnTg+Eg^HQp;tZclov2i*(J6j`0_|32suc~rUj#}Jl?OR|F^*Z1&ifHU%
w-2_YF;ctcS-235W!V8UM!V8UM!V8W60Ge1syrm5y!vFvP07*qoM6N<$g3Xz4{Qv*}
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/media-skip-backward.png b/src/qtui/QtUi/44/media-skip-backward.png
new file mode 100644
index 0000000000000000000000000000000000000000..f79995027abb9d989cea544324a57762a3da2e27
GIT binary patch
literal 996
zcmV<A0~`E_P)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H117S%-K~z|U?U>6;R8btqKXXSLof5HV0vpq2(ZXfc$`&GuJ4vEd
zf=s%p1lMkSfcQTMlL)R#2!bBs!i_@&VGl?&l^MZi(w;VvHRFt@#l0ir^*+wr97>ok
z{1)>&_jAwpckb^#&bWjS93?6L+CaW48ZNYoh6}Bt;X>=k87?u&yR^vFZh^f>$;j{t
z;0)l_<x{{%U|Zt63UCsrL at jjlusD~&tNA=oYI4F9ux2r#OPlNz`wLD3k;CBhJ*;HS
zx?HYjxuK08Ghnhh4%7lZz}?Z&QD0hGdRH4OIW$fPksFE-;(`$30_x at 8i)>yyCYSLD
zA^h3#k&%%r<>lq~fDH%SeLK$VrUQ6yF_x|V6zZj9Zf>ruy}doSwY7B>C_`<ZA9mdQ
z{Jf{7rRAmsw+EYP$0V-+Raz(jfk2>rZEdYf2vLQ4vwQ)59ug;QIAxNrMY}PYnwlEI
z;qa|YCQ}Ot;2V&@_z~!olQwL&!tUPQ-kMM-bUT?$Uet04ZPK*G`P_YdeP_qU#_lAO
z$%Z^QX~PFrcxq~@qNk at Pm`EgAH1;R(8Tf5AiBm3L!~0g)@AqGi$K%(85XZH#4J>XB
z6D}>wIWfF%g=4YU4b&d{0DML5JzF{D%#=?{d_sLDOZVGfa)z?{THDEu(b3U|6%`d<
z^m)5*$~iHd%8ma1{_XYk_1E3q-EZA)_b>gpSvcjK7}i((uClT+6$*tCtE;OoTU%Qr
zHY;?1TV7s%)z;P~%jIoYUvUh04n*qe>cq^<%-3)@{HDIXe#2yi4sd}$V0U_YT9(V(
zuu;WnU>0}+Y&14DvaqnQIXOAGR9#*D-GDLTKIFmWW!S9ZUDOYwN1BQ6ot>RxWo0Ek
zG&B_PdcE5=+~Zs>5{blyhlisUoU~!PiqpU{@Bnz>^?H8|4i4@{qtRF}7>p~5l9b^*
z9?$QAfq_gk8jW>zb;T?=Tf<U41tfua&A^h+=gW+bkEa(G7vs&%&7UQ?MW4@?nV6W!
z*l|W%q&n1{MYAqHi`*9JG;j&1(SFY&w?#S)Tn7ABoY9-^BkFcVuk0q&N<uqk8aM|u
zpkCfhN$#l~XSBju>D%SM-R5WYUl`Qu$o=zEG+byE4HsHP!-ZDSaG`bN4F3UHd|X=~
S7^GML0000<MNUMnLSTXqLDS9v
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/44/media-skip-forward.png b/src/qtui/QtUi/44/media-skip-forward.png
new file mode 100644
index 0000000000000000000000000000000000000000..76c7a2339800ddc4163273448e33eadaa340eec2
GIT binary patch
literal 940
zcmV;d15^BoP)<h;3K|Lk000e1NJLTq001li001lq1^@s69)wx}00004b3#c}2nYxW
zd<bNS00009a7bBm000}W000}W0bUxB8~^|S8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H111U*FK~z|U?U=n!Q&AX)pVNX+qydeTqy{AwJCGO#Lt=shkg#eP
z+#oP9p^HPqPN0w&Clb==s!`(LKVZUQ{2<0baWNLDSP&~n<fDAO4(AqYxovMtZ<OTz
zk~dAy?Q_oWyyxqlDiPs0$@Q-d6e`EC-Es`uEyu9katzz8GLy1OpdJul6<D)a*9pLf
zPC}tv9pK3*-vpL{?es!rax^z&z)9enQ9&-9LwB}N?ksRJ%d>T0A-%wCN>l)pmzUq~
z?(S|jzBd4VbT+c-M3I~aKq>V+J<^~3B at xMtCJ_muv$N>&cpeQ84__6Lpom-)kvb7^
zTi_lS!5xIbHD&%jm*MxoJP-$>wY9Z(XJ%$D85La+ky9d~O31xQk8Fl>?GnF?MiYR0
zb#?VdYisL+Kp=1paHAK>d7#<?_b?C$T+hSpWQ3`58QwNx1&9GFBI1okqc_XS%I>wd
zw_irjO+R|BsvKN(G#VYW$fcrS!|A<EqPLiNU~O-2uVH$6dZe<la&&NTFtw|w5^_h%
zaC&T at x0%ntdNP at 8nV6WEsHv&BH8nNmEiq>*vwgS;a4Dtk<mgOFUf>K+u9RB$`~6QA
z78b6Qf)kP3z&`NNs^L)!4TB!i(}n>T at Szl(hzyw-HanVA$~r72ilgVM&u-4 at qRSgz
zuQxF=GV-*9T)~FT7SEw at yWN`u0|W13vDn+8p`ncua;C~PC9?K1rLL~7SR at ijG&VLW
zqmd}kQUv$O3YX7t)?PL at H~)x4B1>&;ZSZGdECPFWa8?Z;%CO(>-xwPki}&>Oq_&nX
zz)SSPX+lr2LtK4*{bo2Ej`#QX?-#-qYWSeXRaI5Hp-^Zk6bkKDR8%PRvHJ>`L%-;k
zlq=Toj?3lR at 9XPJgu~$-pU<a&E%e*eEP5ETa=pF1-^a(tcMIW;WVoZFBQZHSxfu)w
z-9{s`Mx$G~DlC at 6VusC5y3|#t6FqEmzzg7Kp1O+VQdgwTjPhrgT#?K&yof$|;=pU*
zYn}#=$}Jn8`x)iyY0nO1mf`<e$L at a#$FSXU4BIWou-$SD+bzei-TDoZ&uVJav4JrF
O0000<MNUMnLSTZ2mafbI
literal 0
HcmV?d00001
diff --git a/src/qtui/QtUi/AUTHORS b/src/qtui/QtUi/AUTHORS
new file mode 100644
index 000000000000..39aba5554ac5
--- /dev/null
+++ b/src/qtui/QtUi/AUTHORS
@@ -0,0 +1,3 @@
+Faience is designed and developed by Matthieu James <matthieu.james at gmail.com>.
+
+Faience icons are all licensed under the GPL.
diff --git a/src/qtui/QtUi/index.theme b/src/qtui/QtUi/index.theme
new file mode 100644
index 000000000000..01f09ef0a91e
--- /dev/null
+++ b/src/qtui/QtUi/index.theme
@@ -0,0 +1,17 @@
+[Icon Theme]
+Name=QtUi
+Comment=Theme for Audacious Qt Interface plugin, includes icons from Faience theme by Matthieu James
+Inherits=default
+Directories=16,22
+
+[16]
+Size=16
+
+[22]
+Size=22
+
+[32]
+Size=32
+
+[44]
+Size=44
diff --git a/src/qtui/dialog_windows.cc b/src/qtui/dialog_windows.cc
new file mode 100644
index 000000000000..b5575e57e34f
--- /dev/null
+++ b/src/qtui/dialog_windows.cc
@@ -0,0 +1,68 @@
+/*
+ * dialog_windows.cc
+ * Copyright 2014 John Lindgren and MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include "dialog_windows.h"
+
+#include <QMessageBox>
+#include <libaudcore/i18n.h>
+
+void DialogWindows::create_progress ()
+{
+ if (! m_progress)
+ {
+ m_progress = new QMessageBox (m_parent);
+ m_progress->setIcon (QMessageBox::Information);
+ m_progress->setText (_("Working ..."));
+ m_progress->setStandardButtons (QMessageBox::NoButton);
+ m_progress->setWindowModality (Qt::WindowModal);
+ }
+}
+
+void DialogWindows::show_error (const char * message)
+{
+ if (! m_error)
+ {
+ m_error = new QMessageBox (m_parent);
+ m_error->setIcon (QMessageBox::Warning);
+ m_error->setWindowModality (Qt::WindowModal);
+ }
+
+ m_error->setText (message);
+ m_error->show ();
+}
+
+void DialogWindows::show_progress (const char * message)
+{
+ create_progress ();
+ m_progress->setInformativeText (message);
+ m_progress->show ();
+}
+
+void DialogWindows::show_progress_2 (const char * message)
+{
+ create_progress ();
+ m_progress->setText (message);
+ m_progress->show ();
+}
+
+void DialogWindows::hide_progress ()
+{
+ if (m_progress)
+ m_progress->hide ();
+}
diff --git a/src/qtui/dialog_windows.h b/src/qtui/dialog_windows.h
new file mode 100644
index 000000000000..d226bc833b50
--- /dev/null
+++ b/src/qtui/dialog_windows.h
@@ -0,0 +1,53 @@
+/*
+ * dialog_windows.h
+ * Copyright 2014 John Lindgren and MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#ifndef DIALOG_WINDOWS_H
+#define DIALOG_WINDOWS_H
+
+#include <libaudcore/hook.h>
+
+class QMessageBox;
+class QWidget;
+
+class DialogWindows
+{
+public:
+ DialogWindows (QWidget * parent) :
+ m_parent (parent) {}
+
+private:
+ QWidget * m_parent;
+ QMessageBox * m_progress = nullptr;
+ QMessageBox * m_error = nullptr;
+
+ void create_progress ();
+ void show_error (const char * message);
+ void show_progress (const char * message);
+ void show_progress_2 (const char * message);
+ void hide_progress ();
+
+ const HookReceiver<DialogWindows, const char *>
+ show_hook1 {"ui show progress", this, & DialogWindows::show_progress},
+ show_hook2 {"ui show progress 2", this, & DialogWindows::show_progress_2},
+ show_hook3 {"ui show error", this, & DialogWindows::show_error};
+ const HookReceiver<DialogWindows>
+ hide_hook {"ui hide progress", this, & DialogWindows::hide_progress};
+};
+
+#endif // DIALOG_WINDOWS_H
diff --git a/src/qtui/filter_input.cc b/src/qtui/filter_input.cc
new file mode 100644
index 000000000000..e1977b554280
--- /dev/null
+++ b/src/qtui/filter_input.cc
@@ -0,0 +1,56 @@
+/*
+ * filter_input.cc
+ * Copyright 2014 Daniel (dmilith) Dettlaff
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <libaudcore/i18n.h>
+
+#include "filter_input.h"
+
+#include <QKeyEvent>
+
+FilterInput::FilterInput (QWidget * parent) : QLineEdit (parent)
+{
+#ifdef Q_OS_MAC
+ setStyleSheet (
+ "QLineEdit {"
+ " padding: 2px 4px;"
+ " border: 1px solid silver;"
+ " border-radius: 10px;"
+ " margin-right: 5px;"
+ "}"
+ "QLineEdit:focus {"
+ " border: 1px solid gray;"
+ "}"
+ );
+#endif
+
+ setAttribute (Qt::WA_MacShowFocusRect, false);
+ setClearButtonEnabled (true);
+ setPlaceholderText (_("Search"));
+}
+
+void FilterInput::keyPressEvent (QKeyEvent * e)
+{
+ if (e->key () == Qt::Key_Enter or e->key () == Qt::Key_Return)
+ {
+ e->ignore ();
+ focusNextChild ();
+ }
+ else
+ QLineEdit::keyPressEvent (e);
+}
diff --git a/src/qtui/filter_input.h b/src/qtui/filter_input.h
new file mode 100644
index 000000000000..41559a200407
--- /dev/null
+++ b/src/qtui/filter_input.h
@@ -0,0 +1,34 @@
+/*
+ * filter_input.h
+ * Copyright 2014 Daniel (dmilith) Dettlaff
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#ifndef FILTER_INPUT_WIDGET_H
+#define FILTER_INPUT_WIDGET_H
+
+#include <QLineEdit>
+
+class FilterInput : public QLineEdit
+{
+public:
+ FilterInput (QWidget * parent = nullptr);
+
+protected:
+ virtual void keyPressEvent (QKeyEvent * e); /* override default handler */
+};
+
+#endif
diff --git a/src/qtui/info_bar.cc b/src/qtui/info_bar.cc
new file mode 100644
index 000000000000..b62517fad7ca
--- /dev/null
+++ b/src/qtui/info_bar.cc
@@ -0,0 +1,211 @@
+/*
+ * info_bar.cc
+ * Copyright 2014 William Pitcock
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <cmath>
+
+#include "info_bar.h"
+
+#include <libaudcore/hook.h>
+#include <libaudcore/index.h>
+#include <libaudcore/objects.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/tuple.h>
+#include <libaudcore/drct.h>
+#include <libaudqt/libaudqt.h>
+
+#include <QGraphicsItem>
+#include <QGraphicsPixmapItem>
+#include <QFont>
+
+VisItem::VisItem (QGraphicsItem * parent) :
+ QGraphicsItem (parent),
+ Visualizer (Freq)
+{
+ aud_visualizer_add (this);
+}
+
+VisItem::~VisItem ()
+{
+ aud_visualizer_remove (this);
+}
+
+QRectF VisItem::boundingRect () const
+{
+ return QRectF (0.0, 0.0, InfoBar::VisWidth, InfoBar::Height);
+}
+
+void VisItem::paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
+{
+ QColor c = Qt::blue;
+
+ painter->fillRect (boundingRect (), QColor (0, 0, 0, 0));
+ painter->setPen (QPen (c, 1, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin));
+
+ for (int i = 0; i < InfoBar::VisBands; i++)
+ {
+ int x = InfoBar::Spacing + 8 * i;
+ int q = InfoBar::IconSize - m_bars[i];
+ int t = -(InfoBar::IconSize - q);
+
+ painter->fillRect (x, InfoBar::IconSize, 6, t, c);
+ }
+}
+
+void VisItem::render_freq (const float * freq)
+{
+ /* xscale[i] = pow (256, i / VIS_BANDS) - 0.5; */
+ const float xscale[InfoBar::VisBands + 1] = {0.5, 1.09, 2.02, 3.5, 5.85, 9.58,
+ 15.5, 24.9, 39.82, 63.5, 101.09, 160.77, 255.5};
+
+ for (int i = 0; i < InfoBar::VisBands; i ++)
+ {
+ int a = ceilf (xscale[i]);
+ int b = floorf (xscale[i + 1]);
+ float n = 0;
+
+ if (b < a)
+ n += freq[b] * (xscale[i + 1] - xscale[i]);
+ else
+ {
+ if (a > 0)
+ n += freq[a - 1] * (a - xscale[i]);
+ for (; a < b; a ++)
+ n += freq[a];
+ if (b < 256)
+ n += freq[b] * (xscale[i + 1] - b);
+ }
+
+ /* 40 dB range */
+ int x = 40 + 20 * log10f (n);
+ x = aud::clamp (x, 0, 40);
+
+ m_bars[i] -= aud::max (0, InfoBar::VisFalloff - m_delay[i]);
+
+ if (m_delay[i])
+ m_delay[i] --;
+
+ if (x > m_bars[i])
+ {
+ m_bars[i] = x;
+ m_delay[i] = InfoBar::VisDelay;
+ }
+ }
+
+ update ();
+}
+
+void VisItem::clear ()
+{
+ memset (m_bars, 0, sizeof m_bars);
+ memset (m_delay, 0, sizeof m_delay);
+
+ update ();
+}
+
+void AlbumArtItem::update_cb ()
+{
+ setPixmap (audqt::art_request_current (InfoBar::IconSize, InfoBar::IconSize));
+}
+
+InfoBar::InfoBar (QWidget * parent) : QGraphicsView (parent),
+ m_scene (new QGraphicsScene (this)),
+ m_art (new AlbumArtItem),
+ m_title_text (new QGraphicsTextItem),
+ m_album_text (new QGraphicsTextItem),
+ m_artist_text (new QGraphicsTextItem)
+#ifdef XXX_NOTYET
+ m_vis (new VisItem)
+#endif
+{
+ setAlignment (Qt::AlignLeft | Qt::AlignTop);
+ setScene (m_scene);
+ setFixedHeight (InfoBar::Height);
+ setCacheMode (QGraphicsView::CacheBackground);
+
+ m_scene->addItem (m_art);
+ m_scene->addItem (m_title_text);
+ m_scene->addItem (m_album_text);
+ m_scene->addItem (m_artist_text);
+#ifdef XXX_NOTYET
+ m_scene->addItem (m_vis);
+#endif
+
+ m_title_text->setDefaultTextColor (QColor (255, 255, 255));
+ m_artist_text->setDefaultTextColor (QColor (255, 255, 255));
+ m_album_text->setDefaultTextColor (QColor (179, 179, 179));
+
+ QFont f = m_title_text->font ();
+ f.setPointSize (18);
+ m_title_text->setFont (f);
+
+ f = m_artist_text->font ();
+ f.setPointSize (9);
+ m_artist_text->setFont (f);
+
+ f = m_album_text->font ();
+ f.setPointSize (9);
+ m_album_text->setFont (f);
+}
+
+QSize InfoBar::minimumSizeHint () const
+{
+ return QSize (InfoBar::IconSize + (2 * InfoBar::Spacing), InfoBar::Height);
+}
+
+void InfoBar::resizeEvent (QResizeEvent * event)
+{
+ QGraphicsView::resizeEvent (event);
+
+ QRect rect = contentsRect ();
+ setSceneRect (rect);
+
+ QLinearGradient gradient (0, 0, 0, rect.height ());
+ gradient.setStops ({
+ {0, QColor (64, 64, 64)},
+ {0.499, QColor (38, 38, 38)},
+ {0.5, QColor (26, 26, 26)},
+ {1, QColor (0, 0, 0)}
+ });
+ m_scene->setBackgroundBrush (gradient);
+
+ m_art->setPos (InfoBar::Spacing, InfoBar::Spacing);
+
+ qreal x = InfoBar::IconSize + (InfoBar::Spacing * 1.5);
+ qreal y = InfoBar::Spacing / 2;
+ m_title_text->setPos (x, y);
+ m_artist_text->setPos (x, y + (InfoBar::IconSize / 2));
+ m_album_text->setPos (x, y + ((InfoBar::IconSize * 3) / 4));
+
+#ifdef XXX_NOTYET
+ m_vis->setPos ((rect.width () - InfoBar::VisWidth) - (InfoBar::Spacing * 2), 0);
+#endif
+}
+
+void InfoBar::update_metadata_cb ()
+{
+ Tuple tuple = aud_drct_get_tuple ();
+ String title = tuple.get_str (Tuple::Title);
+ String artist = tuple.get_str (Tuple::Artist);
+ String album = tuple.get_str (Tuple::Album);
+
+ m_title_text->setPlainText (QString ((const char *) title));
+ m_artist_text->setPlainText (QString ((const char *) artist));
+ m_album_text->setPlainText (QString ((const char *) album));
+}
diff --git a/src/qtui/info_bar.h b/src/qtui/info_bar.h
new file mode 100644
index 000000000000..f8cabbc23951
--- /dev/null
+++ b/src/qtui/info_bar.h
@@ -0,0 +1,96 @@
+/*
+ * info_bar.h
+ * Copyright 2014 William Pitcock
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <QWidget>
+#include <QPainter>
+#include <QGraphicsView>
+#include <QGraphicsPixmapItem>
+#include <QGraphicsTextItem>
+
+#include <libaudcore/hook.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/visualizer.h>
+
+#ifndef INFO_BAR_H
+#define INFO_BAR_H
+
+class VisItem : public QGraphicsItem, public Visualizer {
+public:
+ VisItem (QGraphicsItem * parent = nullptr);
+ ~VisItem ();
+
+ QRectF boundingRect () const;
+ void paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr);
+
+private:
+ void render_freq (const float * freq);
+ void clear ();
+
+ char m_bars[12];
+ char m_delay[12];
+};
+
+class AlbumArtItem : public QGraphicsPixmapItem {
+private:
+ void update_cb ();
+
+ const HookReceiver<AlbumArtItem>
+ hook1 {"playback ready", this, & AlbumArtItem::update_cb},
+ hook2 {"playback stop", this, & AlbumArtItem::update_cb},
+ hook3 {"current art ready", this, & AlbumArtItem::update_cb};
+};
+
+class InfoBar : public QGraphicsView {
+public:
+ InfoBar (QWidget * parent = nullptr);
+
+ static constexpr int Spacing = 8;
+ static constexpr int IconSize = 64;
+ static constexpr int Height = IconSize + (2 * Spacing);
+
+ static constexpr int VisBands = 12;
+ static constexpr int VisWidth = (8 * VisBands) + Spacing;
+ static constexpr int VisCenter = (IconSize * 5 / 8 + Spacing);
+ static constexpr int VisDelay = 2;
+ static constexpr int VisFalloff = 2;
+
+ QSize minimumSizeHint () const;
+ void resizeEvent (QResizeEvent *);
+
+private:
+ QGraphicsScene * m_scene;
+ AlbumArtItem * m_art;
+
+ QGraphicsTextItem * m_title_text;
+ QGraphicsTextItem * m_album_text;
+ QGraphicsTextItem * m_artist_text;
+
+#ifdef XXX_NOTYET
+ VisItem * m_vis;
+#endif
+
+ void update_metadata_cb ();
+
+ const HookReceiver<InfoBar>
+ hook1 {"tuple change", this, & InfoBar::update_metadata_cb},
+ hook2 {"playback ready", this, & InfoBar::update_metadata_cb},
+ hook3 {"playback stop", this, & InfoBar::update_metadata_cb};
+};
+
+#endif
diff --git a/src/qtui/main_window.cc b/src/qtui/main_window.cc
new file mode 100644
index 000000000000..f0ccfc7612d1
--- /dev/null
+++ b/src/qtui/main_window.cc
@@ -0,0 +1,317 @@
+/*
+ * main_window.cc
+ * Copyright 2014 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include "main_window.h"
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/plugins.h>
+
+#include <libaudqt/libaudqt.h>
+#include <libaudqt/volumebutton.h>
+
+#include "filter_input.h"
+#include "playlist.h"
+#include "time_slider.h"
+#include "status_bar.h"
+#include "playlist_tabs.h"
+#include "tool_bar.h"
+
+#include <QApplication>
+#include <QDockWidget>
+#include <QAction>
+#include <QSettings>
+
+MainWindow::MainWindow () :
+ m_dialogs (this),
+ filterInput (new FilterInput (this)),
+ playlistTabs (new PlaylistTabs (this)),
+ infoBar (new InfoBar (this)),
+ centralWidget (new QWidget (this)),
+ centralLayout (new QVBoxLayout (centralWidget))
+{
+#if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
+ QIcon::setThemeName ("QtUi");
+
+ QStringList paths = QIcon::themeSearchPaths ();
+ paths.prepend (aud_get_path (AudPath::DataDir));
+ QIcon::setThemeSearchPaths (paths);
+#else
+ QApplication::setWindowIcon (QIcon::fromTheme ("audacious"));
+#endif
+
+ auto slider = new TimeSlider (this);
+
+ const ToolBarItem items[] = {
+ ToolBarAction ("document-open", N_("Open Files"), N_("Open Files"),
+ [] () { audqt::fileopener_show (audqt::FileMode::Open); }),
+ ToolBarAction ("list-add", N_("Add Files"), N_("Add Files"),
+ [] () { audqt::fileopener_show (audqt::FileMode::Add); }),
+ ToolBarSeparator (),
+ ToolBarAction ("media-playback-play", N_("Play"), N_("Play"), aud_drct_play_pause, & toolButtonPlayPause),
+ ToolBarAction ("media-playback-stop", N_("Stop"), N_("Stop"), aud_drct_stop),
+ ToolBarAction ("media-skip-backward", N_("Previous"), N_("Previous"), aud_drct_pl_prev),
+ ToolBarAction ("media-skip-forward", N_("Next"), N_("Next"), aud_drct_pl_next),
+ ToolBarSeparator (),
+ ToolBarCustom (slider),
+ ToolBarCustom (slider->label ()),
+ ToolBarSeparator (),
+ ToolBarAction ("media-playlist-repeat", N_("Repeat"), N_("Repeat"),
+ [] (bool on) { aud_set_bool (nullptr, "repeat", on); }, & toolButtonRepeat),
+ ToolBarAction ("media-playlist-shuffle", N_("Shuffle"), N_("Shuffle"),
+ [] (bool on) { aud_set_bool (nullptr, "shuffle", on); }, & toolButtonShuffle),
+ ToolBarCustom (new audqt::VolumeButton (this)),
+ ToolBarCustom (filterInput),
+ };
+
+ addToolBar (Qt::TopToolBarArea, new ToolBar (this, items));
+
+ setUnifiedTitleAndToolBarOnMac (true);
+
+ updateToggles ();
+
+ setStatusBar (new StatusBar (this));
+ setCentralWidget (centralWidget);
+
+ centralLayout->addWidget (playlistTabs);
+ centralLayout->addWidget (infoBar);
+
+ centralLayout->setContentsMargins (0, 0, 0, 0);
+ centralLayout->setSpacing (4);
+
+ connect (filterInput, &QLineEdit::textChanged, playlistTabs, &PlaylistTabs::filterTrigger);
+
+ setupActions ();
+ add_dock_plugins ();
+
+ buffering_timer.setSingleShot (true);
+ connect (& buffering_timer, & QTimer::timeout, this, & MainWindow::show_buffering);
+
+ if (aud_drct_get_playing ())
+ {
+ playback_begin_cb ();
+ if (aud_drct_get_ready ())
+ playback_ready_cb ();
+ }
+ else
+ playback_stop_cb ();
+
+ title_change_cb ();
+
+ readSettings ();
+}
+
+MainWindow::~MainWindow ()
+{
+ remove_dock_plugins ();
+}
+
+void MainWindow::closeEvent (QCloseEvent * e)
+{
+ QSettings settings ("audacious", "QtUi");
+ settings.setValue ("geometry", saveGeometry());
+ settings.setValue ("windowState", saveState());
+
+ aud_quit ();
+ e->ignore ();
+}
+
+void MainWindow::readSettings ()
+{
+ QSettings settings ("audacious", "QtUi");
+ restoreGeometry (settings.value ("geometry").toByteArray());
+ restoreState (settings.value ("windowState").toByteArray());
+}
+
+void MainWindow::keyPressEvent (QKeyEvent * e)
+{
+ switch (e->modifiers ())
+ {
+ case Qt::ControlModifier:
+ switch (e->key ())
+ {
+ case Qt::Key_F:
+ filterInput->setFocus ();
+ break;
+ }
+ break;
+ }
+
+ QMainWindow::keyPressEvent (e);
+}
+
+void MainWindow::updateToggles ()
+{
+ toolButtonRepeat->setChecked (aud_get_bool (nullptr, "repeat"));
+ toolButtonShuffle->setChecked (aud_get_bool (nullptr, "shuffle"));
+}
+
+void MainWindow::update_play_pause ()
+{
+ if (! aud_drct_get_playing () || aud_drct_get_paused ())
+ {
+ toolButtonPlayPause->setIcon (QIcon::fromTheme ("media-playback-start"));
+ toolButtonPlayPause->setText (_("Play"));
+ toolButtonPlayPause->setToolTip (_("Play"));
+ }
+ else
+ {
+ toolButtonPlayPause->setIcon (QIcon::fromTheme ("media-playback-pause"));
+ toolButtonPlayPause->setText (_("Pause"));
+ toolButtonPlayPause->setToolTip (_("Pause"));
+ }
+}
+
+void MainWindow::show_buffering ()
+{
+ if (aud_drct_get_playing () && ! aud_drct_get_ready ())
+ setWindowTitle (_("Buffering ..."));
+}
+
+void MainWindow::title_change_cb ()
+{
+ auto title = aud_drct_get_title ();
+ if (title)
+ setWindowTitle (QString (title) + QString (" - Audacious"));
+}
+
+void MainWindow::playback_begin_cb ()
+{
+ update_play_pause ();
+
+ int last_list = aud_playlist_by_unique_id (playing_id);
+ auto last_widget = playlistTabs->playlistWidget (last_list);
+ if (last_widget)
+ last_widget->updatePlaybackIndicator ();
+
+ int list = aud_playlist_get_playing ();
+ auto widget = playlistTabs->playlistWidget (list);
+ if (widget)
+ widget->scrollToCurrent ();
+ if (widget && widget != last_widget)
+ widget->updatePlaybackIndicator ();
+
+ playing_id = aud_playlist_get_unique_id (list);
+
+ buffering_timer.start (250);
+}
+
+void MainWindow::playback_ready_cb ()
+{
+ title_change_cb ();
+}
+
+void MainWindow::pause_cb ()
+{
+ update_play_pause ();
+
+ int list = aud_playlist_by_unique_id (playing_id);
+ auto widget = playlistTabs->playlistWidget (list);
+ if (widget)
+ widget->updatePlaybackIndicator ();
+}
+
+void MainWindow::playback_stop_cb ()
+{
+ setWindowTitle ("Audacious");
+ update_play_pause ();
+
+ int last_list = aud_playlist_by_unique_id (playing_id);
+ auto last_widget = playlistTabs->playlistWidget (last_list);
+ if (last_widget)
+ last_widget->updatePlaybackIndicator ();
+
+ playing_id = -1;
+}
+
+void MainWindow::update_toggles_cb ()
+{
+ updateToggles ();
+}
+
+struct DockWidget {
+ QDockWidget * w;
+ PluginHandle * pl;
+};
+
+void MainWindow::add_dock_plugin_cb (PluginHandle * plugin)
+{
+ QWidget * widget = (QWidget *) aud_plugin_get_qt_widget (plugin);
+
+ if (widget)
+ {
+ widget->resize (320, 240);
+
+ auto w = new QDockWidget;
+ w->setWindowTitle (aud_plugin_get_name (plugin));
+ w->setObjectName (aud_plugin_get_basename (plugin));
+ w->setWidget (widget);
+ addDockWidget (Qt::LeftDockWidgetArea, w);
+
+ dock_widgets.append (w, plugin);
+ }
+}
+
+void MainWindow::remove_dock_plugin_cb (PluginHandle * plugin)
+{
+ auto remove_cb = [&] (DockWidget & dw)
+ {
+ if (dw.pl != plugin)
+ return false;
+
+ removeDockWidget (dw.w);
+
+ delete dw.w;
+ return true;
+ };
+
+ dock_widgets.remove_if (remove_cb);
+}
+
+void MainWindow::add_dock_plugins ()
+{
+ for (PluginHandle * plugin : aud_plugin_list (PluginType::General))
+ {
+ if (aud_plugin_get_enabled (plugin))
+ add_dock_plugin_cb (plugin);
+ }
+
+ for (PluginHandle * plugin : aud_plugin_list (PluginType::Vis))
+ {
+ if (aud_plugin_get_enabled (plugin))
+ add_dock_plugin_cb (plugin);
+ }
+}
+
+void MainWindow::remove_dock_plugins ()
+{
+ for (PluginHandle * plugin : aud_plugin_list (PluginType::General))
+ {
+ if (aud_plugin_get_enabled (plugin))
+ remove_dock_plugin_cb (plugin);
+ }
+
+ for (PluginHandle * plugin : aud_plugin_list (PluginType::Vis))
+ {
+ if (aud_plugin_get_enabled (plugin))
+ remove_dock_plugin_cb (plugin);
+ }
+}
diff --git a/src/qtui/main_window.h b/src/qtui/main_window.h
new file mode 100644
index 000000000000..0c486eb3b0bc
--- /dev/null
+++ b/src/qtui/main_window.h
@@ -0,0 +1,103 @@
+/*
+ * main_window.h
+ * Copyright 2014 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#ifndef MAIN_WINDOW_H
+#define MAIN_WINDOW_H
+
+#include <libaudcore/hook.h>
+#include <libaudcore/index.h>
+#include <libaudcore/objects.h>
+
+#include "dialog_windows.h"
+#include "info_bar.h"
+
+#include <QMainWindow>
+#include <QTimer>
+#include <QVBoxLayout>
+
+class FilterInput;
+class PlaylistTabs;
+class PluginHandle;
+
+struct DockWidget;
+
+class MainWindow : public QMainWindow
+{
+public:
+ MainWindow ();
+ ~MainWindow ();
+
+private:
+ DialogWindows m_dialogs;
+ FilterInput * filterInput;
+ PlaylistTabs * playlistTabs;
+ InfoBar * infoBar;
+ QWidget * centralWidget;
+ QVBoxLayout * centralLayout;
+
+ QAction * toolButtonPlayPause;
+ QAction * toolButtonRepeat;
+ QAction * toolButtonShuffle;
+
+ QTimer buffering_timer;
+
+ void closeEvent (QCloseEvent * e);
+ void keyPressEvent (QKeyEvent * e);
+
+ void updateToggles ();
+ void setupActions ();
+ void readSettings ();
+
+ void update_play_pause ();
+ void show_buffering ();
+
+ void add_dock_plugins ();
+ void remove_dock_plugins ();
+
+ void title_change_cb ();
+ void playback_begin_cb ();
+ void playback_ready_cb ();
+ void pause_cb ();
+ void playback_stop_cb ();
+ void update_toggles_cb ();
+
+ void add_dock_plugin_cb (PluginHandle * plugin);
+ void remove_dock_plugin_cb (PluginHandle * plugin);
+
+ const HookReceiver<MainWindow>
+ hook1 {"title change", this, & MainWindow::title_change_cb},
+ hook2 {"playback begin", this, & MainWindow::playback_begin_cb},
+ hook3 {"playback ready", this, & MainWindow::playback_ready_cb},
+ hook4 {"playback pause", this, & MainWindow::pause_cb},
+ hook5 {"playback unpause", this, & MainWindow::pause_cb},
+ hook6 {"playback stop", this, & MainWindow::playback_stop_cb},
+ hook7 {"set repeat", this, & MainWindow::update_toggles_cb},
+ hook8 {"set shuffle", this, & MainWindow::update_toggles_cb},
+ hook9 {"set no_playlist_advance", this, & MainWindow::update_toggles_cb},
+ hook10 {"set stop_after_current_song", this, & MainWindow::update_toggles_cb};
+
+ const HookReceiver<MainWindow, PluginHandle *>
+ plugin_hook1 {"dock plugin enabled", this, & MainWindow::add_dock_plugin_cb},
+ plugin_hook2 {"dock plugin disabled", this, & MainWindow::remove_dock_plugin_cb};
+
+ Index<DockWidget> dock_widgets;
+ int playing_id = -1;
+};
+
+#endif
diff --git a/src/qtui/main_window_actions.cc b/src/qtui/main_window_actions.cc
new file mode 100644
index 000000000000..6e63257a03fb
--- /dev/null
+++ b/src/qtui/main_window_actions.cc
@@ -0,0 +1,197 @@
+/*
+ * main_window_actions.cc
+ * Copyright 2014 MichaÅ Lipski and William Pitcock
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include "main_window.h"
+
+#include <QMenuBar>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/plugins.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/playlist.h>
+
+#include <libaudqt/libaudqt.h>
+#include <libaudqt/menu.h>
+
+static QMenu * services_menu () { return audqt::menu_get_by_id (AudMenuID::Main); }
+
+static void open_files () { audqt::fileopener_show (audqt::FileMode::Open); }
+static void add_files () { audqt::fileopener_show (audqt::FileMode::Add); }
+static void open_folder () { audqt::fileopener_show (audqt::FileMode::OpenFolder); }
+static void add_folder () { audqt::fileopener_show (audqt::FileMode::AddFolder); }
+
+static void rm_dupes_title () { aud_playlist_remove_duplicates_by_scheme (aud_playlist_get_active (), Playlist::Title); }
+static void rm_dupes_filename () { aud_playlist_remove_duplicates_by_scheme (aud_playlist_get_active (), Playlist::Filename); }
+static void rm_dupes_path () { aud_playlist_remove_duplicates_by_scheme (aud_playlist_get_active (), Playlist::Path); }
+
+static void sort_track () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Track); }
+static void sort_title () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Title); }
+static void sort_artist () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Artist); }
+static void sort_album () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Album); }
+static void sort_album_artist () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::AlbumArtist); }
+static void sort_date () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Date); }
+static void sort_genre () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Genre); }
+static void sort_length () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Length); }
+static void sort_path () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Path); }
+static void sort_custom_title () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::FormattedTitle); }
+static void sort_reverse () { aud_playlist_reverse (aud_playlist_get_active ()); }
+static void sort_random () { aud_playlist_randomize (aud_playlist_get_active ()); }
+
+static void sort_sel_track () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Track); }
+static void sort_sel_title () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Title); }
+static void sort_sel_artist () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Artist); }
+static void sort_sel_album () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Album); }
+static void sort_sel_album_artist () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::AlbumArtist); }
+static void sort_sel_date () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Date); }
+static void sort_sel_genre () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Genre); }
+static void sort_sel_length () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Length); }
+static void sort_sel_path () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::Path); }
+static void sort_sel_custom_title () { aud_playlist_sort_by_scheme (aud_playlist_get_active (), Playlist::FormattedTitle); }
+static void sort_sel_reverse () { aud_playlist_reverse (aud_playlist_get_active ()); }
+static void sort_sel_random () { aud_playlist_randomize (aud_playlist_get_active ()); }
+
+static void pl_new ()
+{
+ aud_playlist_insert (-1);
+ aud_playlist_set_active (aud_playlist_count () - 1);
+}
+
+static void pl_play () { aud_playlist_play (aud_playlist_get_active ()); }
+static void pl_refresh () { aud_playlist_rescan (aud_playlist_get_active ()); }
+static void pl_remove_failed () { aud_playlist_remove_failed (aud_playlist_get_active ()); }
+static void pl_close () { audqt::playlist_confirm_delete (aud_playlist_get_active ()); }
+
+static void volume_up () { aud_drct_set_volume_main (aud_drct_get_volume_main () + 5); }
+static void volume_down () { aud_drct_set_volume_main (aud_drct_get_volume_main () - 5); }
+
+static void configure_effects () { audqt::prefswin_show_plugin_page (PluginType::Effect); }
+
+void MainWindow::setupActions ()
+{
+ static constexpr audqt::MenuItem file_items[] = {
+ audqt::MenuCommand ({N_("_Open Files ..."), "document-open", "Ctrl+O"}, open_files),
+ audqt::MenuCommand ({N_("_Open Folder ..."), "document-open"}, open_folder),
+ audqt::MenuCommand ({N_("_Add Files ..."), "list-add", "Ctrl+Shift+O"}, add_files),
+ audqt::MenuCommand ({N_("_Add Folder ..."), "list-add"}, add_folder),
+ audqt::MenuSep (),
+ audqt::MenuCommand ({N_("A_bout ..."), "help-about"}, aud_ui_show_about_window),
+ audqt::MenuCommand ({N_("_Settings ..."), "preferences-system"}, aud_ui_show_prefs_window),
+ audqt::MenuSep (),
+ audqt::MenuCommand ({N_("_Log Inspector ...")}, audqt::log_inspector_show),
+ audqt::MenuSep (),
+ audqt::MenuCommand ({N_("_Quit"), "application-exit", "Ctrl+Q"}, aud_quit)
+ };
+
+ static constexpr audqt::MenuItem playback_items[] = {
+ audqt::MenuCommand ({N_("_Play"), "media-playback-start", "Ctrl+Return"}, aud_drct_play),
+ audqt::MenuCommand ({N_("Paus_e"), "media-playback-pause", "Ctrl+,"}, aud_drct_pause),
+ audqt::MenuCommand ({N_("_Stop"), "media-playback-stop", "Ctrl+."}, aud_drct_stop),
+ audqt::MenuCommand ({N_("Pre_vious"), "media-skip-backward", "Alt+Up"}, aud_drct_pl_prev),
+ audqt::MenuCommand ({N_("_Next"), "media-skip-forward", "Alt+Down"}, aud_drct_pl_next),
+ audqt::MenuSep (),
+ audqt::MenuToggle ({N_("_Repeat"), nullptr, "Ctrl+R"}, {nullptr, "repeat", "set repeat"}),
+ audqt::MenuToggle ({N_("S_huffle"), nullptr, "Ctrl+S"}, {nullptr, "shuffle", "set shuffle"}),
+ audqt::MenuToggle ({N_("N_o Playlist Advance"), nullptr, "Ctrl+N"}, {nullptr, "no_playlist_advance", "set no_playlist_advance"}),
+ audqt::MenuToggle ({N_("Stop A_fter This Song"), nullptr, "Ctrl+M"}, {nullptr, "stop_after_current_song", "set stop_after_current_song"}),
+ audqt::MenuSep (),
+ audqt::MenuCommand ({N_("Song _Info ..."), "dialog-information", "Ctrl+I"}, audqt::infowin_show_current)
+ };
+
+ static constexpr audqt::MenuItem dupe_items[] = {
+ audqt::MenuCommand ({N_("By _Title")}, rm_dupes_title),
+ audqt::MenuCommand ({N_("By _File Name")}, rm_dupes_filename),
+ audqt::MenuCommand ({N_("By File _Path")}, rm_dupes_path),
+ };
+
+ static constexpr audqt::MenuItem sort_items[] = {
+ audqt::MenuCommand ({N_("By Track _Number")}, sort_track),
+ audqt::MenuCommand ({N_("By _Title")}, sort_title),
+ audqt::MenuCommand ({N_("By _Artist")}, sort_artist),
+ audqt::MenuCommand ({N_("By Al_bum")}, sort_album),
+ audqt::MenuCommand ({N_("By Albu_m Artist")}, sort_album_artist),
+ audqt::MenuCommand ({N_("By Release _Date")}, sort_date),
+ audqt::MenuCommand ({N_("By _Genre")}, sort_genre),
+ audqt::MenuCommand ({N_("By _Length")}, sort_length),
+ audqt::MenuCommand ({N_("By _File Path")}, sort_path),
+ audqt::MenuCommand ({N_("By _Custom Title")}, sort_custom_title),
+ audqt::MenuSep (),
+ audqt::MenuCommand ({N_("R_everse Order"), "view-sort-descending"}, sort_reverse),
+ audqt::MenuCommand ({N_("_Random Order")}, sort_random)
+ };
+
+ static constexpr audqt::MenuItem sort_selected_items[] = {
+ audqt::MenuCommand ({N_("By Track _Number")}, sort_sel_track),
+ audqt::MenuCommand ({N_("By _Title")}, sort_sel_title),
+ audqt::MenuCommand ({N_("By _Artist")}, sort_sel_artist),
+ audqt::MenuCommand ({N_("By Al_bum")}, sort_sel_album),
+ audqt::MenuCommand ({N_("By Albu_m Artist")}, sort_sel_album_artist),
+ audqt::MenuCommand ({N_("By Release _Date")}, sort_sel_date),
+ audqt::MenuCommand ({N_("By _Genre")}, sort_sel_genre),
+ audqt::MenuCommand ({N_("By _Length")}, sort_sel_length),
+ audqt::MenuCommand ({N_("By _File Path")}, sort_sel_path),
+ audqt::MenuCommand ({N_("By _Custom Title")}, sort_sel_custom_title),
+ audqt::MenuSep (),
+ audqt::MenuCommand ({N_("R_everse Order"), "view-sort-descending"}, sort_sel_reverse),
+ audqt::MenuCommand ({N_("_Random Order")}, sort_sel_random)
+ };
+
+ static constexpr audqt::MenuItem playlist_items[] = {
+ audqt::MenuCommand ({N_("_Play/Resume"), "media-playback-start", "Shift+Return"}, pl_play),
+ audqt::MenuCommand ({N_("_Refresh"), "view-refresh", "F5"}, pl_refresh),
+ audqt::MenuSep (),
+ audqt::MenuSub ({N_("_Sort"), "view-sort-ascending"}, sort_items),
+ audqt::MenuSub ({N_("Sort Se_lected"), "view-sort-ascending"}, sort_selected_items),
+ audqt::MenuSub ({N_("Remove _Duplicates"), "edit-copy"}, dupe_items),
+ audqt::MenuCommand ({N_("Remove _Unavailable Files"), "dialog-warning"}, pl_remove_failed),
+ audqt::MenuSep (),
+ audqt::MenuCommand ({N_("_New"), "document-new", "Ctrl+T"}, pl_new),
+ //audqt::MenuCommand ({N_("Ren_ame ..."), "insert-text", "F2"}, TODO),
+ audqt::MenuCommand ({N_("Remo_ve"), "edit-delete", "Ctrl+W"}, pl_close),
+ audqt::MenuSep (),
+ //audqt::MenuCommand ({N_("_Import ..."), "document-open"}, TODO),
+ //audqt::MenuCommand ({N_("_Export ..."), "document-save"}, TODO),
+ audqt::MenuSep (),
+ //audqt::MenuCommand ({N_("Playlist _Manager ..."), "audio-x-generic", "Ctrl+P"}, TODO),
+ audqt::MenuCommand ({N_("_Queue Manager ..."), nullptr, "Ctrl+U"}, audqt::queue_manager_show)
+ };
+
+ static constexpr audqt::MenuItem output_items[] = {
+ audqt::MenuCommand ({N_("Volume _Up"), "audio-volume-high", "Ctrl++"}, volume_up),
+ audqt::MenuCommand ({N_("Volume _Down"), "audio-volume-low", "Ctrl+-"}, volume_down),
+ audqt::MenuSep (),
+ audqt::MenuCommand ({N_("_Equalizer"), "multimedia-volume-control", "Ctrl+E"}, audqt::equalizer_show),
+ audqt::MenuSep (),
+ audqt::MenuCommand ({N_("E_ffects ...")}, configure_effects)
+ };
+
+ static constexpr audqt::MenuItem main_items[] = {
+ audqt::MenuSub ({N_("_File")}, file_items),
+ audqt::MenuSub ({N_("_Playback")}, playback_items),
+ audqt::MenuSub ({N_("P_laylist")}, playlist_items),
+ audqt::MenuSub ({N_("_Services")}, services_menu),
+ audqt::MenuSub ({N_("_Output")}, output_items),
+ };
+
+ setMenuBar (audqt::menubar_build (main_items, this));
+}
diff --git a/src/qtui/playlist.cc b/src/qtui/playlist.cc
new file mode 100644
index 000000000000..232336e851f0
--- /dev/null
+++ b/src/qtui/playlist.cc
@@ -0,0 +1,287 @@
+/*
+ * playlist.cc
+ * Copyright 2014 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <QKeyEvent>
+#include <QSortFilterProxyModel>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/playlist.h>
+
+#include "playlist.h"
+#include "playlist_model.h"
+
+PlaylistWidget::PlaylistWidget (QTreeView * parent, int uniqueId) : QTreeView (parent)
+{
+ model = new PlaylistModel (nullptr, uniqueId);
+
+ /* setting up filtering model */
+ proxyModel = new QSortFilterProxyModel (this);
+ proxyModel->setSourceModel (model);
+ proxyModel->setFilterKeyColumn (-1); /* filter by all columns */
+
+ setModel (proxyModel);
+ setAlternatingRowColors (true);
+ setAttribute (Qt::WA_MacShowFocusRect, false);
+ setIndentation (0);
+ setUniformRowHeights (true);
+ setFrameShape (QFrame::NoFrame);
+ setSelectionMode (ExtendedSelection);
+ setColumnWidth (PL_COL_NOW_PLAYING, 25);
+ setColumnWidth (PL_COL_TITLE, 300);
+ setColumnWidth (PL_COL_ARTIST, 150);
+ setColumnWidth (PL_COL_ALBUM, 200);
+ resizeColumnToContents (PL_COL_QUEUED);
+ resizeColumnToContents (PL_COL_LENGTH);
+ scrollToCurrent ();
+}
+
+void PlaylistWidget::setFilter (const QString & text)
+{
+ proxyModel->setFilterRegExp (QRegExp (text, Qt::CaseInsensitive, QRegExp::FixedString));
+}
+
+PlaylistWidget::~PlaylistWidget ()
+{
+ delete model;
+ delete proxyModel;
+}
+
+QModelIndex PlaylistWidget::rowToIndex (int row)
+{
+ if (row < 0)
+ return QModelIndex ();
+
+ return proxyModel->mapFromSource (model->index (row));
+}
+
+int PlaylistWidget::indexToRow (const QModelIndex & index)
+{
+ if (! index.isValid ())
+ return -1;
+
+ return proxyModel->mapToSource (index).row ();
+}
+
+void PlaylistWidget::keyPressEvent (QKeyEvent * e)
+{
+ switch (e->modifiers ())
+ {
+ case Qt::NoModifier:
+ switch (e->key ())
+ {
+ case Qt::Key_Escape:
+ scrollToCurrent ();
+ break;
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ playCurrentIndex ();
+ break;
+ case Qt::Key_Right:
+ aud_drct_seek (aud_drct_get_time () + 5000);
+ break;
+ case Qt::Key_Left:
+ aud_drct_seek (aud_drct_get_time () - 5000);
+ break;
+ case Qt::Key_Space:
+ aud_drct_play_pause ();
+ break;
+ case Qt::Key_Delete:
+ deleteCurrentSelection ();
+ break;
+ case Qt::Key_Z:
+ aud_drct_pl_prev ();
+ return;
+ case Qt::Key_X:
+ aud_drct_play ();
+ return;
+ case Qt::Key_C:
+ aud_drct_pause ();
+ return;
+ case Qt::Key_V:
+ aud_drct_stop ();
+ return;
+ case Qt::Key_B:
+ aud_drct_pl_next ();
+ return;
+ case Qt::Key_Q:
+ toggleQueue ();
+ return;
+ }
+ break;
+ }
+
+ QTreeView::keyPressEvent (e);
+}
+
+void PlaylistWidget::mouseDoubleClickEvent (QMouseEvent * event)
+{
+ if (event->button () == Qt::LeftButton)
+ playCurrentIndex ();
+}
+
+void PlaylistWidget::currentChanged (const QModelIndex & current, const QModelIndex & previous)
+{
+ QTreeView::currentChanged (current, previous);
+
+ if (! inUpdate)
+ aud_playlist_set_focus (playlist (), indexToRow (current));
+}
+
+void PlaylistWidget::selectionChanged (const QItemSelection & selected,
+ const QItemSelection & deselected)
+{
+ QTreeView::selectionChanged (selected, deselected);
+
+ if (! inUpdate)
+ {
+ int list = playlist ();
+
+ for (const QModelIndex & idx : selected.indexes ())
+ aud_playlist_entry_set_selected (list, indexToRow (idx), true);
+ for (const QModelIndex & idx : deselected.indexes ())
+ aud_playlist_entry_set_selected (list, indexToRow (idx), false);
+ }
+}
+
+int PlaylistWidget::playlist () const
+{
+ return model->playlist ();
+}
+
+int PlaylistWidget::uniqueId () const
+{
+ return model->uniqueId ();
+}
+
+void PlaylistWidget::scrollToCurrent ()
+{
+ int list = playlist ();
+ int entry = aud_playlist_get_position (list);
+
+ aud_playlist_select_all (list, false);
+ aud_playlist_entry_set_selected (list, entry, true);
+ aud_playlist_set_focus (list, entry);
+
+ // a playlist update should have been queued, unless the playlist is empty
+ if (aud_playlist_update_pending (list))
+ scrollQueued = true;
+}
+
+void PlaylistWidget::updatePlaybackIndicator ()
+{
+ int list = playlist ();
+
+ if (aud_playlist_update_pending (list))
+ needIndicatorUpdate = true;
+ else if (currentPos >= 0)
+ model->updateRows (currentPos, 1);
+}
+
+void PlaylistWidget::update (const Playlist::Update & update)
+{
+ inUpdate = true;
+
+ int list = playlist ();
+ int entries = aud_playlist_entry_count (list);
+ int changed = entries - update.before - update.after;
+
+ if (update.level == Playlist::Structure)
+ {
+ int old_entries = model->rowCount ();
+ int removed = old_entries - update.before - update.after;
+
+ if (currentPos >= old_entries - update.after)
+ currentPos += entries - old_entries;
+ else if (currentPos >= update.before)
+ currentPos = -1;
+
+ model->removeRows (update.before, removed);
+ model->insertRows (update.before, changed);
+ }
+ else if (update.level == Playlist::Metadata || update.queue_changed)
+ model->updateRows (update.before, changed);
+
+ if (update.queue_changed)
+ {
+ for (int i = aud_playlist_queue_count (list); i --; )
+ {
+ int entry = aud_playlist_queue_get_entry (list, i);
+ if (entry < update.before || entry >= entries - update.after)
+ model->updateRows (entry, 1);
+ }
+ }
+
+ int pos = aud_playlist_get_position (list);
+
+ if (needIndicatorUpdate || pos != currentPos)
+ {
+ if (currentPos >= 0)
+ model->updateRows (currentPos, 1);
+ if (pos >= 0 && pos != currentPos)
+ model->updateRows (pos, 1);
+
+ currentPos = pos;
+ needIndicatorUpdate = false;
+ }
+
+ auto sel = selectionModel ();
+
+ for (int row = update.before; row < entries - update.after; row ++)
+ {
+ if (aud_playlist_entry_get_selected (list, row))
+ sel->select (rowToIndex (row), sel->Select | sel->Rows);
+ else
+ sel->select (rowToIndex (row), sel->Deselect | sel->Rows);
+ }
+
+ auto current = rowToIndex (aud_playlist_get_focus (list));
+ sel->setCurrentIndex (current, sel->NoUpdate);
+
+ if (scrollQueued)
+ {
+ scrollTo (current);
+ scrollQueued = false;
+ }
+
+ inUpdate = false;
+}
+
+void PlaylistWidget::playCurrentIndex ()
+{
+ aud_playlist_set_position (playlist (), indexToRow (currentIndex ()));
+ aud_playlist_play (playlist ());
+}
+
+void PlaylistWidget::deleteCurrentSelection ()
+{
+ aud_playlist_delete_selected (playlist ());
+}
+
+void PlaylistWidget::toggleQueue ()
+{
+ int row = indexToRow (currentIndex ());
+ int at = aud_playlist_queue_find_entry (playlist (), row);
+
+ if (at < 0)
+ aud_playlist_queue_insert (playlist (), -1, row);
+ else
+ aud_playlist_queue_delete (playlist (), at, 1);
+}
diff --git a/src/qtui/playlist.h b/src/qtui/playlist.h
new file mode 100644
index 000000000000..a6bf16157257
--- /dev/null
+++ b/src/qtui/playlist.h
@@ -0,0 +1,63 @@
+/*
+ * playlist.h
+ * Copyright 2014 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#ifndef PLAYLIST_H
+#define PLAYLIST_H
+
+#include <QTreeView>
+#include <libaudcore/playlist.h>
+
+#include "playlist_model.h"
+#include "filter_input.h"
+
+class QSortFilterProxyModel;
+
+class PlaylistWidget : public QTreeView
+{
+public:
+ PlaylistWidget (QTreeView * parent = nullptr, int uniqueId = -1);
+ ~PlaylistWidget ();
+ void scrollToCurrent ();
+ void updatePlaybackIndicator ();
+ void update (const Playlist::Update & update);
+ void playCurrentIndex ();
+ void deleteCurrentSelection ();
+ void setFilter (const QString &text);
+ void toggleQueue ();
+ int playlist () const;
+ int uniqueId () const;
+
+private:
+ PlaylistModel * model;
+ QSortFilterProxyModel * proxyModel;
+ int currentPos = -1;
+ bool inUpdate = false;
+ bool needIndicatorUpdate = false;
+ bool scrollQueued = false;
+
+ QModelIndex rowToIndex (int row);
+ int indexToRow (const QModelIndex & index);
+
+ void keyPressEvent (QKeyEvent * e); /* override default handler */
+ void mouseDoubleClickEvent (QMouseEvent * event);
+ void currentChanged (const QModelIndex & current, const QModelIndex & previous);
+ void selectionChanged (const QItemSelection & selected, const QItemSelection & deselected);
+};
+
+#endif
diff --git a/src/qtui/playlist_model.cc b/src/qtui/playlist_model.cc
new file mode 100644
index 000000000000..98613eabebb3
--- /dev/null
+++ b/src/qtui/playlist_model.cc
@@ -0,0 +1,181 @@
+/*
+ * playlist_model.cc
+ * Copyright 2014 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <QApplication>
+#include <QIcon>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/tuple.h>
+
+#include "playlist_model.h"
+
+static inline QPixmap get_icon (const char * name)
+{
+ qreal r = qApp->devicePixelRatio ();
+ QPixmap pm = QIcon::fromTheme (name).pixmap (16 * r);
+ pm.setDevicePixelRatio (r);
+ return pm;
+}
+
+PlaylistModel::PlaylistModel (QObject * parent, int id) : QAbstractListModel (parent),
+ m_uniqueId (id)
+{
+ m_rows = aud_playlist_entry_count (playlist ());
+}
+
+PlaylistModel::~PlaylistModel ()
+{
+
+}
+
+int PlaylistModel::rowCount (const QModelIndex & parent) const
+{
+ return m_rows;
+}
+
+int PlaylistModel::columnCount (const QModelIndex & parent) const
+{
+ return PL_COLS;
+}
+
+QVariant PlaylistModel::data (const QModelIndex &index, int role) const
+{
+ String title, artist, album;
+ Tuple tuple;
+
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ switch (index.column ())
+ {
+ case PL_COL_TITLE:
+ case PL_COL_ARTIST:
+ case PL_COL_ALBUM:
+ case PL_COL_LENGTH:
+ tuple = aud_playlist_entry_get_tuple (playlist (), index.row (), Playlist::Guess);
+ break;
+ }
+
+ switch (index.column ())
+ {
+ case PL_COL_TITLE:
+ return QString (tuple.get_str (Tuple::Title));
+ case PL_COL_ARTIST:
+ return QString (tuple.get_str (Tuple::Artist));
+ case PL_COL_ALBUM:
+ return QString (tuple.get_str (Tuple::Album));
+ case PL_COL_QUEUED:
+ return getQueued (index.row ());
+ case PL_COL_LENGTH:
+ return QString (str_format_time (tuple.get_int (Tuple::Length)));
+ }
+
+ case Qt::TextAlignmentRole:
+ switch (index.column ())
+ {
+ case PL_COL_LENGTH:
+ return Qt::AlignRight;
+ }
+
+ case Qt::DecorationRole:
+ if (index.column () == 0 && index.row () == aud_playlist_get_position (playlist ()))
+ {
+ if (aud_playlist_get_playing () == playlist ())
+ if (aud_drct_get_paused ())
+ return get_icon ("media-playback-pause");
+ else
+ return get_icon ("media-playback-start");
+ else
+ return get_icon ("media-playback-stop");
+ }
+ }
+ return QVariant ();
+}
+
+QVariant PlaylistModel::headerData (int section, Qt::Orientation orientation, int role) const
+{
+ if (role == Qt::DisplayRole)
+ {
+ if (orientation == Qt::Horizontal)
+ {
+ switch (section)
+ {
+ case PL_COL_TITLE:
+ return QString (_("Title"));
+ case PL_COL_ARTIST:
+ return QString (_("Artist"));
+ case PL_COL_ALBUM:
+ return QString (_("Album"));
+ case PL_COL_QUEUED:
+ return QString ();
+ case PL_COL_LENGTH:
+ return QString ();
+ }
+ }
+ }
+ return QVariant ();
+}
+
+int PlaylistModel::playlist () const
+{
+ return aud_playlist_by_unique_id (m_uniqueId);
+}
+
+int PlaylistModel::uniqueId () const
+{
+ return m_uniqueId;
+}
+
+bool PlaylistModel::insertRows (int row, int count, const QModelIndex & parent)
+{
+ int last = row + count - 1;
+ beginInsertRows (parent, row, last);
+ m_rows = aud_playlist_entry_count (playlist ());
+ endInsertRows ();
+ return true;
+}
+
+bool PlaylistModel::removeRows (int row, int count, const QModelIndex & parent)
+{
+ int last = row + count - 1;
+ beginRemoveRows (parent, row, last);
+ m_rows = aud_playlist_entry_count (playlist ());
+ endRemoveRows ();
+ return true;
+}
+
+void PlaylistModel::updateRows (int row, int count)
+{
+ int bottom = row + count - 1;
+ auto topLeft = createIndex (row, 0);
+ auto bottomRight = createIndex (bottom, columnCount () - 1);
+ emit dataChanged (topLeft, bottomRight);
+}
+
+QString PlaylistModel::getQueued (int row) const
+{
+ int at = aud_playlist_queue_find_entry (playlist (), row);
+ if (at < 0)
+ return QString ("");
+ else
+ return QString ("#%1").arg (at + 1);
+}
diff --git a/src/qtui/playlist_model.h b/src/qtui/playlist_model.h
new file mode 100644
index 000000000000..6c31f4125e2a
--- /dev/null
+++ b/src/qtui/playlist_model.h
@@ -0,0 +1,54 @@
+/*
+ * playlist_model.h
+ * Copyright 2014 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#ifndef PLAYLIST_MODEL_H
+#define PLAYLIST_MODEL_H
+
+#include <QAbstractListModel>
+
+enum {
+ PL_COL_NOW_PLAYING,
+ PL_COL_TITLE,
+ PL_COL_ARTIST,
+ PL_COL_ALBUM,
+ PL_COL_QUEUED,
+ PL_COL_LENGTH,
+ PL_COLS
+};
+
+class PlaylistModel : public QAbstractListModel
+{
+public:
+ PlaylistModel (QObject * parent = nullptr, int id = -1);
+ ~PlaylistModel ();
+ int rowCount (const QModelIndex & parent = QModelIndex ()) const;
+ int columnCount (const QModelIndex & parent = QModelIndex ()) const;
+ QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
+ QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ bool insertRows (int row, int count, const QModelIndex & parent = QModelIndex ());
+ bool removeRows (int row, int count, const QModelIndex & parent = QModelIndex ());
+ void updateRows (int row, int count);
+ QString getQueued (int row) const;
+ int playlist () const;
+ int uniqueId () const;
+ int m_uniqueId;
+ int m_rows;
+};
+
+#endif
diff --git a/src/qtui/playlist_tabs.cc b/src/qtui/playlist_tabs.cc
new file mode 100644
index 000000000000..f82e76a2127d
--- /dev/null
+++ b/src/qtui/playlist_tabs.cc
@@ -0,0 +1,239 @@
+/*
+ * playlist_tabs.cc
+ * Copyright 2014 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include "playlist.h"
+#include "playlist_tabs.h"
+
+#include <QKeyEvent>
+#include <QLineEdit>
+
+#include <libaudcore/playlist.h>
+#include <libaudcore/runtime.h>
+
+#include <libaudqt/libaudqt.h>
+
+PlaylistTabs::PlaylistTabs (QWidget * parent) :
+ QTabWidget (parent),
+ m_leftbtn (nullptr),
+ m_tabbar (new PlaylistTabBar (this))
+{
+ installEventFilter (this);
+
+ // set up tab bar
+ m_tabbar->setFocusPolicy (Qt::NoFocus);
+ setTabBar (m_tabbar);
+
+ populatePlaylists ();
+ setCurrentIndex (aud_playlist_get_active ());
+
+ connect (this, &QTabWidget::currentChanged, this, &PlaylistTabs::currentChangedTrigger);
+}
+
+PlaylistTabs::~PlaylistTabs ()
+{
+ // TODO: cleanup playlists
+}
+
+void PlaylistTabs::maybeCreateTab (int count_, int uniq_id)
+{
+ int tabs = count ();
+
+ for (int i = 0; i < tabs; i++)
+ {
+ PlaylistWidget * playlistWidget = (PlaylistWidget *) widget (i);
+ if (uniq_id == playlistWidget->uniqueId())
+ return;
+ }
+
+ auto playlistWidget = new PlaylistWidget (0, uniq_id);
+ addTab ((QWidget *) playlistWidget, QString (aud_playlist_get_title (count_)));
+}
+
+void PlaylistTabs::cullPlaylists ()
+{
+ int tabs = count ();
+
+ for (int i = 0; i < tabs; i++)
+ {
+ PlaylistWidget * playlistWidget = (PlaylistWidget *) widget (i);
+
+ if (playlistWidget == nullptr || playlistWidget->playlist() < 0)
+ {
+ removeTab(i);
+ delete playlistWidget;
+ }
+ else
+ setTabText(i, QString (aud_playlist_get_title (playlistWidget->playlist())));
+ }
+}
+
+void PlaylistTabs::populatePlaylists ()
+{
+ int playlists = aud_playlist_count ();
+
+ for (int count = 0; count < playlists; count++)
+ maybeCreateTab(count, aud_playlist_get_unique_id (count));
+
+ cullPlaylists();
+}
+
+PlaylistWidget * PlaylistTabs::playlistWidget (int num)
+{
+ return (PlaylistWidget *) widget (num);
+}
+
+void PlaylistTabs::filterTrigger (const QString &text)
+{
+ ((PlaylistWidget *) currentWidget ())->setFilter (text);
+}
+
+void PlaylistTabs::currentChangedTrigger (int idx)
+{
+ cancelRename ();
+ aud_playlist_set_active (idx);
+}
+
+QLineEdit * PlaylistTabs::getTabEdit (int idx)
+{
+ return dynamic_cast<QLineEdit *> (m_tabbar->tabButton (idx, QTabBar::LeftSide));
+}
+
+void PlaylistTabs::setupTab (int idx, QWidget * button, const QString & text, QWidget * * oldp)
+{
+ QWidget * old = m_tabbar->tabButton (idx, QTabBar::LeftSide);
+ m_tabbar->setTabButton (idx, QTabBar::LeftSide, button);
+ setTabText (idx, text);
+
+ if (oldp)
+ * oldp = old;
+ else
+ {
+ old->setParent (nullptr);
+ old->deleteLater ();
+ }
+}
+
+void PlaylistTabs::tabEditedTrigger ()
+{
+ int idx = currentIndex ();
+ if (idx < 0)
+ return;
+
+ QLineEdit * edit = getTabEdit (idx);
+ if (! edit)
+ return;
+
+ QString title = edit->text ();
+ aud_playlist_set_title (idx, title.toUtf8 ());
+
+ setupTab (idx, m_leftbtn, title, nullptr);
+ m_leftbtn = nullptr;
+}
+
+void PlaylistTabs::editTab (int idx)
+{
+ QLineEdit * edit = new QLineEdit (tabText (idx));
+
+ connect (edit, & QLineEdit::returnPressed, this, & PlaylistTabs::tabEditedTrigger);
+
+ setupTab (idx, edit, QString (), & m_leftbtn);
+
+ edit->selectAll ();
+ edit->setFocus ();
+}
+
+bool PlaylistTabs::eventFilter (QObject * obj, QEvent * e)
+{
+ if (e->type() == QEvent::KeyPress)
+ {
+ QKeyEvent *ke = (QKeyEvent *) e;
+
+ if (ke->key() == Qt::Key_Escape)
+ {
+ cancelRename ();
+ return true;
+ }
+ }
+
+ return QTabWidget::eventFilter(obj, e);
+}
+
+void PlaylistTabs::cancelRename ()
+{
+ for (int i = 0; i < count (); i ++)
+ {
+ QLineEdit * edit = getTabEdit (i);
+ if (! edit)
+ continue;
+
+ setupTab (i, m_leftbtn, (const char *) aud_playlist_get_title (i), nullptr);
+ m_leftbtn = nullptr;
+ }
+}
+
+void PlaylistTabs::playlist_update_cb (Playlist::UpdateLevel global_level)
+{
+ if (global_level == Playlist::Structure)
+ populatePlaylists ();
+
+ int lists = aud_playlist_count ();
+ for (int list = 0; list < lists; list ++)
+ {
+ auto update = aud_playlist_update_detail (list);
+ if (update.level)
+ playlistWidget (list)->update (update);
+ }
+}
+
+void PlaylistTabs::playlist_position_cb (int list)
+{
+ auto widget = playlistWidget (list);
+ if (widget)
+ widget->scrollToCurrent ();
+}
+
+PlaylistTabBar::PlaylistTabBar (QWidget * parent) : QTabBar (parent)
+{
+ setDocumentMode (true);
+ setTabsClosable (true);
+
+ connect (this, &QTabBar::tabCloseRequested, this, &PlaylistTabBar::handleCloseRequest);
+}
+
+void PlaylistTabBar::mouseDoubleClickEvent (QMouseEvent *e)
+{
+ PlaylistTabs *p = (PlaylistTabs *) parent();
+
+ int idx = tabAt (e->pos());
+ if (idx < 0)
+ return;
+
+ p->editTab (idx);
+}
+
+void PlaylistTabBar::handleCloseRequest (int idx)
+{
+ PlaylistTabs *p = (PlaylistTabs *) parent ();
+ PlaylistWidget *pl = (PlaylistWidget *) p->widget (idx);
+
+ if (! pl)
+ return;
+
+ audqt::playlist_confirm_delete (pl->playlist ());
+}
diff --git a/src/qtui/playlist_tabs.h b/src/qtui/playlist_tabs.h
new file mode 100644
index 000000000000..f9384a90ee56
--- /dev/null
+++ b/src/qtui/playlist_tabs.h
@@ -0,0 +1,82 @@
+/*
+ * playlist_tabs.h
+ * Copyright 2014 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#ifndef PLAYLIST_TABS_H
+#define PLAYLIST_TABS_H
+
+#include <QTabWidget>
+
+#include <libaudcore/hook.h>
+#include <libaudcore/playlist.h>
+
+#include "playlist.h"
+#include "filter_input.h"
+
+class PlaylistTabBar;
+class PlaylistWidget;
+class QLineEdit;
+
+class PlaylistTabs : public QTabWidget
+{
+public:
+ PlaylistTabs (QWidget * parent = nullptr);
+ ~PlaylistTabs ();
+
+ PlaylistWidget * playlistWidget (int num);
+
+ void editTab (int idx);
+ void filterTrigger (const QString &text);
+ void currentChangedTrigger (int idx);
+ void tabEditedTrigger ();
+
+protected:
+ bool eventFilter (QObject * obj, QEvent *e);
+
+private:
+ QWidget *m_leftbtn;
+ PlaylistTabBar *m_tabbar;
+
+ QLineEdit * getTabEdit (int idx);
+ void setupTab (int idx, QWidget * button, const QString & text, QWidget * * oldp);
+
+ void populatePlaylists ();
+ void maybeCreateTab (int count_, int uniq_id);
+ void cullPlaylists ();
+ void cancelRename ();
+
+ void playlist_update_cb (Playlist::UpdateLevel global_level);
+ void playlist_position_cb (int list);
+
+ const HookReceiver<PlaylistTabs, Playlist::UpdateLevel>
+ update_hook {"playlist update", this, & PlaylistTabs::playlist_update_cb};
+ const HookReceiver<PlaylistTabs, int>
+ position_hook {"playlist position", this, & PlaylistTabs::playlist_position_cb};
+};
+
+class PlaylistTabBar : public QTabBar
+{
+public:
+ PlaylistTabBar (QWidget * parent = nullptr);
+ void handleCloseRequest (int idx);
+
+protected:
+ void mouseDoubleClickEvent (QMouseEvent *e);
+};
+
+#endif
diff --git a/src/qtui/qtui.cc b/src/qtui/qtui.cc
new file mode 100644
index 000000000000..24c86c11d81f
--- /dev/null
+++ b/src/qtui/qtui.cc
@@ -0,0 +1,83 @@
+/*
+ * qtui.cc
+ * Copyright 2014 MichaÅ Lipski
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <QApplication>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+#include <libaudqt/libaudqt.h>
+#include <libaudqt/iface.h>
+
+#include "main_window.h"
+
+static char app_name[] = "audacious";
+static int dummy_argc = 1;
+static char * dummy_argv[] = {app_name, nullptr};
+
+class QtUI : public audqt::QtIfacePlugin
+{
+private:
+ QApplication * qapp = nullptr;
+ MainWindow * window = nullptr;
+
+public:
+ constexpr QtUI () : audqt::QtIfacePlugin ({N_("Qt Interface"), PACKAGE}) {}
+
+ bool init ()
+ {
+ if (aud_get_mainloop_type () != MainloopType::Qt)
+ return false;
+
+ qapp = new QApplication (dummy_argc, dummy_argv);
+ qapp->setAttribute(Qt::AA_UseHighDpiPixmaps);
+ window = new MainWindow;
+
+ return true;
+ }
+
+ void cleanup ()
+ {
+ delete window;
+ window = nullptr;
+
+ audqt::cleanup ();
+
+ delete qapp;
+ qapp = nullptr;
+ }
+
+ void run ()
+ {
+ qapp->exec ();
+ }
+
+ void show (bool show)
+ {
+ window->setVisible (show);
+ }
+
+ void quit ()
+ {
+ qapp->quit();
+ }
+};
+
+EXPORT QtUI aud_plugin_instance;
diff --git a/src/qtui/status_bar.cc b/src/qtui/status_bar.cc
new file mode 100644
index 000000000000..3856ffac2548
--- /dev/null
+++ b/src/qtui/status_bar.cc
@@ -0,0 +1,99 @@
+/*
+ * status_bar.cc
+ * Copyright 2014 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include "status_bar.h"
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/playlist.h>
+
+StatusBar::StatusBar (QWidget * parent) :
+ QStatusBar (parent),
+ codec_label (new QLabel (this)),
+ length_label (new QLabel (this))
+{
+ setStyleSheet ("QStatusBar { background: transparent; } QStatusBar::item { border: none; }");
+
+ addWidget (codec_label);
+ addPermanentWidget (length_label);
+
+ update_codec ();
+ update_length ();
+}
+
+void StatusBar::update_codec ()
+{
+ if (! aud_drct_get_ready ())
+ {
+ codec_label->hide ();
+ return;
+ }
+
+ Tuple tuple = aud_drct_get_tuple ();
+ String codec = tuple.get_str (Tuple::Codec);
+
+ int bitrate, samplerate, channels;
+ aud_drct_get_info (bitrate, samplerate, channels);
+
+ StringBuf buf (0);
+
+ if (codec)
+ {
+ buf.insert (-1, codec);
+ if (channels > 0 || samplerate > 0 || bitrate > 0)
+ buf.insert (-1, ", ");
+ }
+
+ if (channels > 0)
+ {
+ if (channels == 1)
+ buf.insert (-1, _("mono"));
+ else if (channels == 2)
+ buf.insert (-1, _("stereo"));
+ else
+ buf.combine (str_printf (ngettext ("%d channel", "%d channels", channels), channels));
+
+ if (samplerate > 0 || bitrate > 0)
+ buf.insert (-1, ", ");
+ }
+
+ if (samplerate > 0)
+ {
+ buf.combine (str_printf ("%d kHz", samplerate / 1000));
+ if (bitrate > 0)
+ buf.insert (-1, ", ");
+ }
+
+ if (bitrate > 0)
+ buf.combine (str_printf (_("%d kbps"), bitrate / 1000));
+
+ codec_label->setText ((const char *) buf);
+ codec_label->show ();
+}
+
+void StatusBar::update_length ()
+{
+ int playlist = aud_playlist_get_active ();
+
+ StringBuf s1 = str_format_time (aud_playlist_get_selected_length (playlist));
+ StringBuf s2 = str_format_time (aud_playlist_get_total_length (playlist));
+
+ length_label->setText ((const char *) str_concat ({s1, " / ", s2}));
+}
diff --git a/src/qtui/status_bar.h b/src/qtui/status_bar.h
new file mode 100644
index 000000000000..1cdece5c7a9d
--- /dev/null
+++ b/src/qtui/status_bar.h
@@ -0,0 +1,49 @@
+/*
+ * status_bar.h
+ * Copyright 2014 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#ifndef STATUS_BAR_H
+#define STATUS_BAR_H
+
+#include <QLabel>
+#include <QStatusBar>
+
+#include <libaudcore/hook.h>
+
+class StatusBar : public QStatusBar
+{
+public:
+ StatusBar (QWidget * parent);
+
+private:
+ QLabel * codec_label;
+ QLabel * length_label;
+
+ void update_codec ();
+ void update_length ();
+
+ const HookReceiver<StatusBar>
+ hook1 {"playlist activate", this, & StatusBar::update_length},
+ hook2 {"playlist update", this, & StatusBar::update_length},
+ hook3 {"playback ready", this, & StatusBar::update_codec},
+ hook4 {"playback stop", this, & StatusBar::update_codec},
+ hook5 {"info change", this, & StatusBar::update_codec},
+ hook6 {"tuple change", this, & StatusBar::update_codec};
+};
+
+#endif // STATUS_BAR_H
diff --git a/src/qtui/time_slider.cc b/src/qtui/time_slider.cc
new file mode 100644
index 000000000000..dee7d47380a3
--- /dev/null
+++ b/src/qtui/time_slider.cc
@@ -0,0 +1,121 @@
+/*
+ * time_slider.cc
+ * Copyright 2014 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include "time_slider.h"
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+
+TimeSlider::TimeSlider (QWidget * parent) :
+ QSlider (Qt::Horizontal, parent),
+ m_label (new QLabel (parent))
+{
+ setFocusPolicy (Qt::NoFocus);
+ setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ m_label->setContentsMargins (4, 0, 4, 0);
+ m_label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::MinimumExpanding);
+
+ connect (& m_timer, & QTimer::timeout, this, & TimeSlider::update);
+ connect (this, & QSlider::valueChanged, this, & TimeSlider::moved);
+ connect (this, & QSlider::sliderPressed, this, & TimeSlider::pressed);
+ connect (this, & QSlider::sliderReleased, this, & TimeSlider::released);
+
+ start_stop ();
+}
+
+TimeSlider::~TimeSlider () {}
+
+void TimeSlider::set_label (int time, int length)
+{
+ QString text;
+
+ if (length > 0)
+ text = str_concat ({str_format_time (time), " / ", str_format_time (length)});
+ else
+ text = str_format_time (time);
+
+ m_label->setText (text);
+}
+
+void TimeSlider::start_stop ()
+{
+ bool ready = aud_drct_get_ready ();
+ bool paused = aud_drct_get_paused ();
+
+ setEnabled (ready);
+ m_label->setEnabled (ready);
+
+ if (ready)
+ {
+ if (! isSliderDown ())
+ update ();
+ }
+ else
+ {
+ setRange (0, 0);
+ m_label->setText ("0:00 / 0:00");
+ }
+
+ if (ready && ! paused && ! isSliderDown ())
+ m_timer.start (250);
+ else
+ m_timer.stop ();
+}
+
+void TimeSlider::update ()
+{
+ int time = aud_drct_get_time ();
+ int length = aud_drct_get_length ();
+
+ setRange (0, length);
+ setValue (time);
+
+ set_label (time, length);
+}
+
+void TimeSlider::moved (int value)
+{
+ set_label (value, aud_drct_get_length ());
+}
+
+void TimeSlider::pressed ()
+{
+ m_timer.stop ();
+}
+
+void TimeSlider::released ()
+{
+ aud_drct_seek (value ());
+ set_label (value (), aud_drct_get_length ());
+
+ if (! aud_drct_get_paused ())
+ m_timer.start (250);
+}
+
+void TimeSlider::mousePressEvent (QMouseEvent * event)
+{
+ if (event->button () == Qt::LeftButton)
+ {
+ setValue (QStyle::sliderValueFromPosition (minimum (), maximum (), event->x (), width ()));
+ event->accept ();
+ }
+
+ QSlider::mousePressEvent (event);
+}
diff --git a/src/qtui/time_slider.h b/src/qtui/time_slider.h
new file mode 100644
index 000000000000..f0a82bfd6594
--- /dev/null
+++ b/src/qtui/time_slider.h
@@ -0,0 +1,61 @@
+/*
+ * time_slider.h
+ * Copyright 2014 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#ifndef TIME_SLIDER_H
+#define TIME_SLIDER_H
+
+#include <QLabel>
+#include <QSlider>
+#include <QTimer>
+#include <QStyle>
+#include <QMouseEvent>
+
+#include <libaudcore/hook.h>
+
+class TimeSlider : public QSlider
+{
+public:
+ TimeSlider (QWidget * parent);
+ ~TimeSlider ();
+
+ QLabel * label ()
+ { return m_label; }
+
+private:
+ void set_label (int time, int length);
+
+ void start_stop ();
+ void update ();
+ void moved (int value);
+ void pressed ();
+ void released ();
+
+ void mousePressEvent (QMouseEvent * event);
+
+ QTimer m_timer;
+ QLabel * m_label;
+
+ const HookReceiver<TimeSlider>
+ hook1 {"playback ready", this, & TimeSlider::start_stop},
+ hook2 {"playback pause", this, & TimeSlider::start_stop},
+ hook3 {"playback unpause", this, & TimeSlider::start_stop},
+ hook4 {"playback stop", this, & TimeSlider::start_stop};
+};
+
+#endif // TIME_SLIDER_H
diff --git a/src/qtui/tool_bar.cc b/src/qtui/tool_bar.cc
new file mode 100644
index 000000000000..1d67ff00e816
--- /dev/null
+++ b/src/qtui/tool_bar.cc
@@ -0,0 +1,65 @@
+/*
+ * tool_bar.cc
+ * Copyright 2014 William Pitcock
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include "tool_bar.h"
+
+#include <QAction>
+#include <QIcon>
+
+#include <libaudcore/runtime.h>
+#include <libaudqt/libaudqt.h>
+
+ToolBar::ToolBar (QWidget * parent, ArrayRef<ToolBarItem> items)
+ : QToolBar (parent)
+{
+ setContextMenuPolicy (Qt::PreventContextMenu);
+ setMovable (false);
+ setIconSize (QSize (22, 22));
+ setObjectName ("MainToolBar");
+
+ for (const ToolBarItem & item : items)
+ {
+ if (item.widget)
+ addWidget (item.widget);
+ else if (item.sep)
+ addSeparator ();
+ else if (item.icon_name)
+ {
+ QAction * a = new QAction (QIcon::fromTheme (item.icon_name),
+ audqt::translate_str (item.name), this);
+
+ if (item.tooltip_text)
+ a->setToolTip (audqt::translate_str (item.tooltip_text));
+
+ if (item.callback)
+ connect (a, &QAction::triggered, item.callback);
+
+ if (item.toggled)
+ {
+ a->setCheckable (true);
+ connect (a, &QAction::toggled, item.toggled);
+ }
+
+ addAction (a);
+
+ if (item.action_ptr)
+ * item.action_ptr = a;
+ }
+ }
+}
diff --git a/src/qtui/tool_bar.h b/src/qtui/tool_bar.h
new file mode 100644
index 000000000000..31d31263dcac
--- /dev/null
+++ b/src/qtui/tool_bar.h
@@ -0,0 +1,63 @@
+/*
+ * tool_bar.h
+ * Copyright 2014 William Pitcock
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#ifndef TOOL_BAR_H
+#define TOOL_BAR_H
+
+#include <QToolBar>
+
+#include <libaudcore/objects.h>
+
+struct ToolBarItem
+{
+ const char * icon_name;
+ const char * name;
+ const char * tooltip_text;
+
+ void (* callback) ();
+ void (* toggled) (bool on);
+
+ QWidget * widget;
+
+ bool sep;
+
+ QAction * * action_ptr;
+};
+
+class ToolBar : public QToolBar
+{
+public:
+ ToolBar (QWidget * parent, ArrayRef<ToolBarItem> items);
+};
+
+constexpr ToolBarItem ToolBarAction (const char * icon_name, const char * name, const char * tooltip_text,
+ void (* callback) (), QAction * * action_ptr = nullptr)
+ { return { icon_name, name, tooltip_text, callback, nullptr, nullptr, false, action_ptr }; }
+
+constexpr ToolBarItem ToolBarAction (const char * icon_name, const char * name, const char * tooltip_text,
+ void (* toggled) (bool), QAction * * action_ptr = nullptr)
+ { return { icon_name, name, tooltip_text, nullptr, toggled, nullptr, false, action_ptr }; }
+
+constexpr ToolBarItem ToolBarCustom (QWidget * item)
+ { return { nullptr, nullptr, nullptr, nullptr, nullptr, item }; }
+
+constexpr ToolBarItem ToolBarSeparator ()
+ { return { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, true }; }
+
+#endif
diff --git a/src/resample/Makefile b/src/resample/Makefile
index b0cde15079c8..1cba05df253b 100644
--- a/src/resample/Makefile
+++ b/src/resample/Makefile
@@ -1,12 +1,14 @@
PLUGIN = resample${PLUGIN_SUFFIX}
-SRCS = resample.c
+SRCS = resample.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS} -lsamplerate
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
+LIBS += -lsamplerate
diff --git a/src/resample/resample.c b/src/resample/resample.c
deleted file mode 100644
index 5830362c0787..000000000000
--- a/src/resample/resample.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Sample Rate Converter Plugin for Audacious
- * Copyright 2010-2012 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include <samplerate.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-#include <libaudcore/audstrings.h>
-
-#define MIN_RATE 8000
-#define MAX_RATE 192000
-#define RATE_STEP 50
-
-#define RESAMPLE_ERROR(e) fprintf (stderr, "resample: %s\n", src_strerror (e))
-
-static const char * const resample_defaults[] = {
- "method", "2", /* SRC_SINC_FASTEST */
- "default-rate", "44100",
- "use-mappings", "FALSE",
- "8000", "48000",
- "16000", "48000",
- "22050", "44100",
- "44100", "44100",
- "48000", "48000",
- "96000", "96000",
- "192000", "96000",
- NULL};
-
-static SRC_STATE * state;
-static int stored_channels;
-static double ratio;
-static float * buffer;
-static int buffer_samples;
-
-bool_t resample_init (void)
-{
- aud_config_set_defaults ("resample", resample_defaults);
- return TRUE;
-}
-
-void resample_cleanup (void)
-{
- if (state)
- {
- src_delete (state);
- state = NULL;
- }
-
- g_free (buffer);
- buffer = NULL;
- buffer_samples = 0;
-}
-
-void resample_start (int * channels, int * rate)
-{
- if (state)
- {
- src_delete (state);
- state = NULL;
- }
-
- int new_rate = 0;
-
- if (aud_get_bool ("resample", "use-mappings"))
- {
- char rate_s[16];
- str_itoa (* rate, rate_s, sizeof rate_s);
- new_rate = aud_get_int ("resample", rate_s);
- }
-
- if (! new_rate)
- new_rate = aud_get_int ("resample", "default-rate");
-
- new_rate = CLAMP (new_rate, MIN_RATE, MAX_RATE);
-
- if (new_rate == * rate)
- return;
-
- int method = aud_get_int ("resample", "method");
- int error;
-
- if ((state = src_new (method, * channels, & error)) == NULL)
- {
- RESAMPLE_ERROR (error);
- return;
- }
-
- stored_channels = * channels;
- ratio = (double) new_rate / * rate;
- * rate = new_rate;
-}
-
-void do_resample (float * * data, int * samples, bool_t finish)
-{
- if (! state || ! * samples)
- return;
-
- if (buffer_samples < (int) (* samples * ratio) + 256)
- {
- buffer_samples = (int) (* samples * ratio) + 256;
- buffer = g_renew (float, buffer, buffer_samples);
- }
-
- SRC_DATA d = {
- .data_in = * data,
- .input_frames = * samples / stored_channels,
- .data_out = buffer,
- .output_frames = buffer_samples / stored_channels,
- .src_ratio = ratio,
- .end_of_input = finish};
-
- int error;
- if ((error = src_process (state, & d)))
- {
- RESAMPLE_ERROR (error);
- return;
- }
-
- * data = buffer;
- * samples = stored_channels * d.output_frames_gen;
-}
-
-void resample_process (float * * data, int * samples)
-{
- do_resample (data, samples, FALSE);
-}
-
-void resample_flush (void)
-{
- int error;
- if (state && (error = src_reset (state)))
- RESAMPLE_ERROR (error);
-}
-
-void resample_finish (float * * data, int * samples)
-{
- do_resample (data, samples, TRUE);
- resample_flush ();
-}
-
-static const char resample_about[] =
- N_("Sample Rate Converter Plugin for Audacious\n"
- "Copyright 2010-2012 John Lindgren");
-
-static const ComboBoxElements method_list[] = {
- {"3", N_("Skip/repeat samples")}, /* SRC_ZERO_ORDER_HOLD */
- {"4", N_("Linear interpolation")}, /* SRC_LINEAR */
- {"2", N_("Fast sinc interpolation")}, /* SRC_SINC_FASTEST */
- {"1", N_("Medium sinc interpolation")}, /* SRC_SINC_MEDIUM_QUALITY */
- {"0", N_("Best sinc interpolation")}}; /* SRC_SINC_BEST_QUALITY */
-
-static const PreferencesWidget resample_widgets[] = {
- {WIDGET_LABEL, N_("<b>Conversion</b>")},
- {WIDGET_COMBO_BOX, N_("Method:"),
- .cfg_type = VALUE_STRING, .csect = "resample", .cname = "method",
- .data = {.combo = {method_list, ARRAY_LEN (method_list)}}},
- {WIDGET_SPIN_BTN, N_("Rate:"),
- .cfg_type = VALUE_INT, .csect = "resample", .cname = "default-rate",
- .data = {.spin_btn = {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")}}},
- {WIDGET_LABEL, N_("<b>Rate Mappings</b>")},
- {WIDGET_CHK_BTN, N_("Use rate mappings"),
- .cfg_type = VALUE_BOOLEAN, .csect = "resample", .cname = "use-mappings"},
- {WIDGET_SPIN_BTN, N_("8 kHz:"), .child = TRUE,
- .cfg_type = VALUE_INT, .csect = "resample", .cname = "8000",
- .data = {.spin_btn = {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")}}},
- {WIDGET_SPIN_BTN, N_("16 kHz:"), .child = TRUE,
- .cfg_type = VALUE_INT, .csect = "resample", .cname = "16000",
- .data = {.spin_btn = {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")}}},
- {WIDGET_SPIN_BTN, N_("22.05 kHz:"), .child = TRUE,
- .cfg_type = VALUE_INT, .csect = "resample", .cname = "22050",
- .data = {.spin_btn = {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")}}},
- {WIDGET_SPIN_BTN, N_("44.1 kHz:"), .child = TRUE,
- .cfg_type = VALUE_INT, .csect = "resample", .cname = "44100",
- .data = {.spin_btn = {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")}}},
- {WIDGET_SPIN_BTN, N_("48 kHz:"), .child = TRUE,
- .cfg_type = VALUE_INT, .csect = "resample", .cname = "48000",
- .data = {.spin_btn = {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")}}},
- {WIDGET_SPIN_BTN, N_("96 kHz:"), .child = TRUE,
- .cfg_type = VALUE_INT, .csect = "resample", .cname = "96000",
- .data = {.spin_btn = {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")}}},
- {WIDGET_SPIN_BTN, N_("192 kHz:"), .child = TRUE,
- .cfg_type = VALUE_INT, .csect = "resample", .cname = "192000",
- .data = {.spin_btn = {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")}}}};
-
-static const PluginPreferences resample_prefs = {
- .widgets = resample_widgets,
- .n_widgets = ARRAY_LEN (resample_widgets)};
-
-AUD_EFFECT_PLUGIN
-(
- .name = N_("Sample Rate Converter"),
- .domain = PACKAGE,
- .about_text = resample_about,
- .prefs = & resample_prefs,
- .init = resample_init,
- .cleanup = resample_cleanup,
- .start = resample_start,
- .process = resample_process,
- .flush = resample_flush,
- .finish = resample_finish,
- .order = 2 /* must be before crossfade */
-)
diff --git a/src/resample/resample.cc b/src/resample/resample.cc
new file mode 100644
index 000000000000..ac08630de233
--- /dev/null
+++ b/src/resample/resample.cc
@@ -0,0 +1,247 @@
+/*
+ * Sample Rate Converter Plugin for Audacious
+ * Copyright 2010-2012 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <samplerate.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/audstrings.h>
+
+#define MIN_RATE 8000
+#define MAX_RATE 192000
+#define RATE_STEP 50
+
+#define RESAMPLE_ERROR(e) AUDERR ("%s\n", src_strerror (e))
+
+class Resampler : public EffectPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Sample Rate Converter"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ /* order #2: must be before crossfade */
+ constexpr Resampler () : EffectPlugin (info, 2, false) {}
+
+ bool init ();
+ void cleanup ();
+
+ void start (int & channels, int & rate);
+ bool flush (bool force);
+
+ Index<float> & process (Index<float> & data)
+ { return resample (data, false); }
+ Index<float> & finish (Index<float> & data, bool end_of_playlist)
+ { return resample (data, true); }
+
+private:
+ Index<float> & resample (Index<float> & data, bool finish);
+};
+
+EXPORT Resampler aud_plugin_instance;
+
+const char * const Resampler::defaults[] = {
+ "method", aud::numeric_string<SRC_SINC_FASTEST>::str,
+ "default-rate", "44100",
+ "use-mappings", "FALSE",
+ "8000", "48000",
+ "16000", "48000",
+ "22050", "44100",
+ "32000", "48000",
+ "44100", "44100",
+ "48000", "48000",
+ "88200", "44100",
+ "96000", "48000",
+ "176400", "44100",
+ "192000", "48000",
+ nullptr};
+
+static SRC_STATE * state;
+static int stored_channels;
+static double ratio;
+static Index<float> buffer;
+
+bool Resampler::init ()
+{
+ aud_config_set_defaults ("resample", defaults);
+ return true;
+}
+
+void Resampler::cleanup ()
+{
+ if (state)
+ {
+ src_delete (state);
+ state = nullptr;
+ }
+
+ buffer.clear ();
+}
+
+void Resampler::start (int & channels, int & rate)
+{
+ if (state)
+ {
+ src_delete (state);
+ state = nullptr;
+ }
+
+ int new_rate = 0;
+
+ if (aud_get_bool ("resample", "use-mappings"))
+ new_rate = aud_get_int ("resample", int_to_str (rate));
+
+ if (! new_rate)
+ new_rate = aud_get_int ("resample", "default-rate");
+
+ new_rate = aud::clamp (new_rate, MIN_RATE, MAX_RATE);
+
+ if (new_rate == rate)
+ return;
+
+ int method = aud_get_int ("resample", "method");
+ int error;
+
+ if ((state = src_new (method, channels, & error)) == nullptr)
+ {
+ RESAMPLE_ERROR (error);
+ return;
+ }
+
+ stored_channels = channels;
+ ratio = (double) new_rate / rate;
+ rate = new_rate;
+}
+
+Index<float> & Resampler::resample (Index<float> & data, bool finish)
+{
+ if (! state || ! data.len ())
+ return data;
+
+ buffer.resize ((int) (data.len () * ratio) + 256);
+
+ SRC_DATA d = SRC_DATA ();
+
+ d.data_in = data.begin ();
+ d.input_frames = data.len () / stored_channels;
+ d.data_out = buffer.begin ();
+ d.output_frames = buffer.len () / stored_channels;
+ d.src_ratio = ratio;
+ d.end_of_input = finish;
+
+ int error;
+ if ((error = src_process (state, & d)))
+ {
+ RESAMPLE_ERROR (error);
+ return data;
+ }
+
+ buffer.resize (stored_channels * d.output_frames_gen);
+
+ if (finish)
+ flush (true);
+
+ return buffer;
+}
+
+bool Resampler::flush (bool force)
+{
+ int error;
+ if (state && (error = src_reset (state)))
+ RESAMPLE_ERROR (error);
+
+ return true;
+}
+
+const char Resampler::about[] =
+ N_("Sample Rate Converter Plugin for Audacious\n"
+ "Copyright 2010-2012 John Lindgren");
+
+static const ComboItem method_list[] = {
+ ComboItem(N_("Skip/repeat samples"), SRC_ZERO_ORDER_HOLD),
+ ComboItem(N_("Linear interpolation"), SRC_LINEAR),
+ ComboItem(N_("Fast sinc interpolation"), SRC_SINC_FASTEST),
+ ComboItem(N_("Medium sinc interpolation"), SRC_SINC_MEDIUM_QUALITY),
+ ComboItem(N_("Best sinc interpolation"), SRC_SINC_BEST_QUALITY)
+};
+
+const PreferencesWidget Resampler::widgets[] = {
+ WidgetLabel (N_("<b>Conversion</b>")),
+ WidgetCombo (N_("Method:"),
+ WidgetInt ("resample", "method"),
+ {{method_list}}),
+ WidgetSpin (N_("Rate:"),
+ WidgetInt ("resample", "default-rate"),
+ {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")}),
+ WidgetLabel (N_("<b>Rate Mappings</b>")),
+ WidgetCheck (N_("Use rate mappings"),
+ WidgetBool ("resample", "use-mappings")),
+ WidgetSpin (N_("8 kHz:"),
+ WidgetInt ("resample", "8000"),
+ {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")},
+ WIDGET_CHILD),
+ WidgetSpin (N_("16 kHz:"),
+ WidgetInt ("resample", "16000"),
+ {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")},
+ WIDGET_CHILD),
+ WidgetSpin (N_("22.05 kHz:"),
+ WidgetInt ("resample", "22050"),
+ {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")},
+ WIDGET_CHILD),
+ WidgetSpin (N_("32.0 kHz:"),
+ WidgetInt ("resample", "32000"),
+ {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")},
+ WIDGET_CHILD),
+ WidgetSpin (N_("44.1 kHz:"),
+ WidgetInt ("resample", "44100"),
+ {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")},
+ WIDGET_CHILD),
+ WidgetSpin (N_("48 kHz:"),
+ WidgetInt ("resample", "48000"),
+ {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")},
+ WIDGET_CHILD),
+ WidgetSpin (N_("88.2 kHz:"),
+ WidgetInt ("resample", "88200"),
+ {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")},
+ WIDGET_CHILD),
+ WidgetSpin (N_("96 kHz:"),
+ WidgetInt ("resample", "96000"),
+ {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")},
+ WIDGET_CHILD),
+ WidgetSpin (N_("176.4 kHz:"),
+ WidgetInt ("resample", "176400"),
+ {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")},
+ WIDGET_CHILD),
+ WidgetSpin (N_("192 kHz:"),
+ WidgetInt ("resample", "192000"),
+ {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")},
+ WIDGET_CHILD)
+};
+
+const PluginPreferences Resampler::prefs = {{widgets}};
diff --git a/src/scrobbler2/Makefile b/src/scrobbler2/Makefile
index a2f8fd6ea719..3bede4e57a2f 100644
--- a/src/scrobbler2/Makefile
+++ b/src/scrobbler2/Makefile
@@ -1,9 +1,9 @@
PLUGIN = scrobbler${PLUGIN_SUFFIX}
-SRCS = scrobbler.c \
- scrobbler_communication.c \
- scrobbler_xml_parsing.c \
- config_window.c
+SRCS = scrobbler.cc \
+ scrobbler_communication.cc \
+ scrobbler_xml_parsing.cc \
+ config_window.cc
include ../../buildsys.mk
@@ -13,6 +13,8 @@ PACKAGE_NAME = audacious
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS} -Wall
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} ${CURL_CFLAGS} ${XML_CFLAGS} -I../..
LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${CURL_LIBS} ${XML_LIBS}
diff --git a/src/scrobbler2/config_window.c b/src/scrobbler2/config_window.c
deleted file mode 100644
index 075ca58f271c..000000000000
--- a/src/scrobbler2/config_window.c
+++ /dev/null
@@ -1,234 +0,0 @@
-
-//external includes
-#include <gdk/gdk.h>
-//plugin includes
-#include "scrobbler.h"
-
-
-//shared variables
-bool_t permission_check_requested = FALSE;
-bool_t invalidate_session_requested = FALSE;
-enum permission perm_result = PERMISSION_UNKNOWN;
-gchar *username = NULL; /* pooled */
-
-
-//static (private) variables
-static GtkWidget *button;
-static GtkWidget *revoke_button;
-static GtkWidget *permission_status_icon;
-static GtkWidget *permission_status_label;
-
-static GtkWidget *details_label_first;
-static GtkWidget *url_button;
-static GtkWidget *details_label_second;
-
-static GtkWidget *additional_details_icon;
-static GtkWidget *additional_details_label;
-
-
-static gboolean permission_checker_thread (gpointer data) {
- if (permission_check_requested == TRUE) {
- //the answer hasn't arrived yet
- return TRUE;
-
- } else {
- //the answer has arrived
- g_assert(perm_result != PERMISSION_UNKNOWN);
-
- if (perm_result == PERMISSION_ALLOWED) {
- gtk_image_set_from_icon_name(GTK_IMAGE(permission_status_icon), "face-smile", GTK_ICON_SIZE_SMALL_TOOLBAR);
-
- gchar *markup = g_markup_printf_escaped(_("OK. Scrobbling for user: %s"), username);
-
- gtk_label_set_markup(GTK_LABEL(permission_status_label), markup);
- gtk_widget_set_sensitive(revoke_button, TRUE);
- g_free(markup);
-
- } else if (perm_result == PERMISSION_DENIED) {
-
- gtk_image_set_from_icon_name(GTK_IMAGE(permission_status_icon), "dialog-error", GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_image_set_from_icon_name(GTK_IMAGE(additional_details_icon), "dialog-information", GTK_ICON_SIZE_SMALL_TOOLBAR);
-
-
- gtk_label_set_label(GTK_LABEL(permission_status_label), _("Permission Denied"));
-
- gtk_label_set_markup(GTK_LABEL(details_label_first), _("Access the following link to allow Audacious to scrobble your plays:"));
-
- gchar *url = g_markup_printf_escaped("http://www.last.fm/api/auth/?api_key=%s&token=%s", SCROBBLER_API_KEY, request_token);
-
- gtk_link_button_set_uri(GTK_LINK_BUTTON(url_button), url);
- gtk_button_set_label(GTK_BUTTON(url_button), url);
- gtk_widget_show(url_button);
- g_free(url);
-
- gtk_label_set_markup(GTK_LABEL(details_label_second), _("Keep this window open and click 'Check Permission' again.\n"));
-
- gtk_label_set_label(GTK_LABEL(additional_details_label),
- _("Don't worry. Your scrobbles are saved on your computer.\n"
- "They will be submitted as soon as Audacious is allowed to do so."));
-
- } else if (perm_result == PERMISSION_NONET) {
- gtk_image_set_from_icon_name(GTK_IMAGE(permission_status_icon), "dialog-warning", GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_image_set_from_icon_name(GTK_IMAGE(additional_details_icon), "dialog-information", GTK_ICON_SIZE_SMALL_TOOLBAR);
-
-
- gtk_label_set_label(GTK_LABEL(permission_status_label), _("Network Problem."));
- gtk_label_set_label(GTK_LABEL(details_label_first), _("There was a problem contacting Last.fm. Please try again later."));
- gtk_label_set_label(GTK_LABEL(additional_details_label),
- _("Don't worry. Your scrobbles are saved on your computer.\n"
- "They will be submitted as soon as Audacious is allowed to do so."));
- }
-
- perm_result = PERMISSION_UNKNOWN;
- gtk_widget_set_sensitive(button, TRUE);
-
- return FALSE;
- }
-}
-
-
-static void cleanup_window() {
- gtk_widget_set_sensitive(button, FALSE);
- gtk_widget_set_sensitive(revoke_button, FALSE);
-
- gtk_image_clear(GTK_IMAGE(permission_status_icon));
- gtk_image_clear(GTK_IMAGE(additional_details_icon));
-
- gtk_label_set_label(GTK_LABEL(permission_status_label), (""));
- gtk_label_set_label(GTK_LABEL(details_label_first), "");
- gtk_widget_hide(url_button);
- gtk_label_set_label(GTK_LABEL(details_label_second), "");
- gtk_label_set_label(GTK_LABEL(additional_details_label), "");
-}
-
-static void permission_checker (GtkButton *button12, gpointer data) {
- cleanup_window();
-
- gtk_image_set_from_icon_name(GTK_IMAGE(permission_status_icon), "system-run", GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_label_set_label(GTK_LABEL(permission_status_label), _("Checking..."));
-
- //This will make the communication thread check the permission
- //and set the current status on the perm_result enum
- permission_check_requested = TRUE;
-
- //This is only to accelerate the check.
- //If scrobbles are being made, they are stopped for the request to be done sooner.
- scrobbling_enabled = FALSE;
-
- //Wake up the communication thread in case it's waiting for track plays
- pthread_mutex_lock(&communication_mutex);
- pthread_cond_signal(&communication_signal);
- pthread_mutex_unlock(&communication_mutex);
-
- //The button is clicked. Wait for the permission check to be done.
- gdk_threads_add_timeout_seconds(1, permission_checker_thread, data);
-}
-
-static void revoke_permissions (GtkButton *revoke_button2, gpointer data) {
- cleanup_window();
-
- pthread_mutex_lock(&communication_mutex);
- invalidate_session_requested = TRUE;
-
- scrobbling_enabled = FALSE;
- pthread_cond_signal(&communication_signal);
- pthread_mutex_unlock(&communication_mutex);
-
- gtk_widget_set_sensitive(button, TRUE);
-}
-
-/*
- ,---config_box---------------------.
- | |
- |,-permission_box----------------. |
- || ,-buttons_box--. | |
- || |button | perm_status | |
- || |revoke_button | | |
- || `--------------' | |
- |`-------------------------------' |
- | |
- |,-details_box------------------. |
- ||details_label_first | |
- ||url_button | |
- ||details_label_second | |
- |`------------------------------' |
- | |
- |,-additional_details_box--------. |
- ||_______________________________| |
- |__________________________________|
-
- */
-static void *config_status_checker () {
- GtkWidget *config_box;
- GtkWidget *permission_box;
- GtkWidget *buttons_box;
- GtkWidget *details_box;
- GtkWidget *additional_details_box;
-
- config_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 15);
- permission_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- buttons_box = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
- details_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- additional_details_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 7);
-
- button = gtk_button_new_with_mnemonic(_("C_heck Permission"));
- revoke_button = gtk_button_new_with_mnemonic(_("_Revoke Permission"));
- gtk_widget_set_sensitive(revoke_button, FALSE);
-
- permission_status_icon = gtk_image_new();
- permission_status_label = gtk_label_new("");
-
- details_label_first = gtk_label_new ("");
- url_button = gtk_link_button_new("");
- details_label_second = gtk_label_new("");
- gtk_widget_set_halign(details_label_first, GTK_ALIGN_CENTER);
- gtk_widget_set_halign(url_button, GTK_ALIGN_CENTER);
- gtk_widget_set_halign(details_label_second, GTK_ALIGN_CENTER);
-
-// gtk_label_set_use_markup(GTK_LABEL(details_label), TRUE);
-
- additional_details_icon = gtk_image_new();
- additional_details_label = gtk_label_new("");
-
-
- g_signal_connect (button, "clicked", G_CALLBACK (permission_checker), NULL);
- g_signal_connect (revoke_button, "clicked", G_CALLBACK (revoke_permissions), NULL);
-
- gtk_box_pack_start(GTK_BOX(permission_box), buttons_box, FALSE, FALSE, 20);
- gtk_box_pack_start(GTK_BOX(permission_box), permission_status_icon, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(permission_box), permission_status_label, FALSE, FALSE, 5);
-
- gtk_box_pack_start(GTK_BOX(buttons_box), button, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(buttons_box), revoke_button, FALSE, FALSE, 0);
-
- gtk_box_pack_start(GTK_BOX(details_box), details_label_first, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(details_box), url_button, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(details_box), details_label_second, FALSE, FALSE, 0);
-
- gtk_box_pack_start(GTK_BOX(additional_details_box), additional_details_icon, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(additional_details_box), additional_details_label, FALSE, FALSE, 0);
-
- gtk_box_pack_start(GTK_BOX(config_box), permission_box, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(config_box), details_box, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(config_box), additional_details_box, FALSE, FALSE, 0);
-
- return config_box;
-}
-
-
-static const PreferencesWidget config_contents[] = {
- {
- .type = WIDGET_LABEL,
- .label = N_("You need to allow Audacious to scrobble tracks to your Last.fm account.\n"),
- .data = { .label = {.single_line = TRUE} }
- },
- {
- .type = WIDGET_CUSTOM,
- .data = { .populate = config_status_checker }
- }
-};
-
-const PluginPreferences configuration = {
- .widgets = config_contents,
- .n_widgets = ARRAY_LEN(config_contents)
-};
diff --git a/src/scrobbler2/config_window.cc b/src/scrobbler2/config_window.cc
new file mode 100644
index 000000000000..c122f625ad1b
--- /dev/null
+++ b/src/scrobbler2/config_window.cc
@@ -0,0 +1,224 @@
+
+//external includes
+#include <gdk/gdk.h>
+//plugin includes
+#include "scrobbler.h"
+
+
+//shared variables
+gboolean permission_check_requested = FALSE;
+gboolean invalidate_session_requested = FALSE;
+enum permission perm_result = PERMISSION_UNKNOWN;
+String username;
+
+
+//static (private) variables
+static GtkWidget *button;
+static GtkWidget *revoke_button;
+static GtkWidget *permission_status_icon;
+static GtkWidget *permission_status_label;
+
+static GtkWidget *details_label_first;
+static GtkWidget *url_button;
+static GtkWidget *details_label_second;
+
+static GtkWidget *additional_details_icon;
+static GtkWidget *additional_details_label;
+
+
+static gboolean permission_checker_thread (void * data) {
+ if (permission_check_requested == TRUE) {
+ //the answer hasn't arrived yet
+ return TRUE;
+
+ } else {
+ //the answer has arrived
+ g_assert(perm_result != PERMISSION_UNKNOWN);
+
+ if (perm_result == PERMISSION_ALLOWED) {
+ gtk_image_set_from_icon_name(GTK_IMAGE(permission_status_icon), "face-smile", GTK_ICON_SIZE_SMALL_TOOLBAR);
+
+ char *markup = g_markup_printf_escaped(_("OK. Scrobbling for user: %s"),
+ (const char *)username);
+
+ gtk_label_set_markup(GTK_LABEL(permission_status_label), markup);
+ gtk_widget_set_sensitive(revoke_button, TRUE);
+ g_free(markup);
+
+ } else if (perm_result == PERMISSION_DENIED) {
+
+ gtk_image_set_from_icon_name(GTK_IMAGE(permission_status_icon), "dialog-error", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_image_set_from_icon_name(GTK_IMAGE(additional_details_icon), "dialog-information", GTK_ICON_SIZE_SMALL_TOOLBAR);
+
+
+ gtk_label_set_label(GTK_LABEL(permission_status_label), _("Permission Denied"));
+
+ gtk_label_set_markup(GTK_LABEL(details_label_first), _("Access the following link to allow Audacious to scrobble your plays:"));
+
+ char *url = g_markup_printf_escaped("http://www.last.fm/api/auth/?api_key=%s&token=%s",
+ SCROBBLER_API_KEY, (const char *)request_token);
+
+ gtk_link_button_set_uri(GTK_LINK_BUTTON(url_button), url);
+ gtk_button_set_label(GTK_BUTTON(url_button), url);
+ gtk_widget_show(url_button);
+ g_free(url);
+
+ gtk_label_set_markup(GTK_LABEL(details_label_second), _("Keep this window open and click 'Check Permission' again.\n"));
+
+ gtk_label_set_label(GTK_LABEL(additional_details_label),
+ _("Don't worry. Your scrobbles are saved on your computer.\n"
+ "They will be submitted as soon as Audacious is allowed to do so."));
+
+ } else if (perm_result == PERMISSION_NONET) {
+ gtk_image_set_from_icon_name(GTK_IMAGE(permission_status_icon), "dialog-warning", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_image_set_from_icon_name(GTK_IMAGE(additional_details_icon), "dialog-information", GTK_ICON_SIZE_SMALL_TOOLBAR);
+
+
+ gtk_label_set_label(GTK_LABEL(permission_status_label), _("Network Problem."));
+ gtk_label_set_label(GTK_LABEL(details_label_first), _("There was a problem contacting Last.fm. Please try again later."));
+ gtk_label_set_label(GTK_LABEL(additional_details_label),
+ _("Don't worry. Your scrobbles are saved on your computer.\n"
+ "They will be submitted as soon as Audacious is allowed to do so."));
+ }
+
+ perm_result = PERMISSION_UNKNOWN;
+ gtk_widget_set_sensitive(button, TRUE);
+
+ return FALSE;
+ }
+}
+
+
+static void cleanup_window() {
+ gtk_widget_set_sensitive(button, FALSE);
+ gtk_widget_set_sensitive(revoke_button, FALSE);
+
+ gtk_image_clear(GTK_IMAGE(permission_status_icon));
+ gtk_image_clear(GTK_IMAGE(additional_details_icon));
+
+ gtk_label_set_label(GTK_LABEL(permission_status_label), (""));
+ gtk_label_set_label(GTK_LABEL(details_label_first), "");
+ gtk_widget_hide(url_button);
+ gtk_label_set_label(GTK_LABEL(details_label_second), "");
+ gtk_label_set_label(GTK_LABEL(additional_details_label), "");
+}
+
+static void permission_checker (GtkButton *button12, void * data) {
+ cleanup_window();
+
+ gtk_image_set_from_icon_name(GTK_IMAGE(permission_status_icon), "system-run", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_label_set_label(GTK_LABEL(permission_status_label), _("Checking..."));
+
+ //This will make the communication thread check the permission
+ //and set the current status on the perm_result enum
+ permission_check_requested = TRUE;
+
+ //This is only to accelerate the check.
+ //If scrobbles are being made, they are stopped for the request to be done sooner.
+ scrobbling_enabled = FALSE;
+
+ //Wake up the communication thread in case it's waiting for track plays
+ pthread_mutex_lock(&communication_mutex);
+ pthread_cond_signal(&communication_signal);
+ pthread_mutex_unlock(&communication_mutex);
+
+ //The button is clicked. Wait for the permission check to be done.
+ gdk_threads_add_timeout_seconds(1, permission_checker_thread, data);
+}
+
+static void revoke_permissions (GtkButton *revoke_button2, void * data) {
+ cleanup_window();
+
+ pthread_mutex_lock(&communication_mutex);
+ invalidate_session_requested = TRUE;
+
+ scrobbling_enabled = FALSE;
+ pthread_cond_signal(&communication_signal);
+ pthread_mutex_unlock(&communication_mutex);
+
+ gtk_widget_set_sensitive(button, TRUE);
+}
+
+/*
+ ,---config_box---------------------.
+ | |
+ |,-permission_box----------------. |
+ || ,-buttons_box--. | |
+ || |button | perm_status | |
+ || |revoke_button | | |
+ || `--------------' | |
+ |`-------------------------------' |
+ | |
+ |,-details_box------------------. |
+ ||details_label_first | |
+ ||url_button | |
+ ||details_label_second | |
+ |`------------------------------' |
+ | |
+ |,-additional_details_box--------. |
+ ||_______________________________| |
+ |__________________________________|
+
+ */
+static void *config_status_checker () {
+ GtkWidget *config_box;
+ GtkWidget *permission_box;
+ GtkWidget *buttons_box;
+ GtkWidget *details_box;
+ GtkWidget *additional_details_box;
+
+ config_box = gtk_vbox_new (FALSE, 15);
+ permission_box = gtk_hbox_new (FALSE, 0);
+ buttons_box = gtk_vbutton_box_new ();
+ details_box = gtk_vbox_new (FALSE, 0);
+ additional_details_box = gtk_hbox_new (FALSE, 7);
+
+ button = gtk_button_new_with_mnemonic(_("C_heck Permission"));
+ revoke_button = gtk_button_new_with_mnemonic(_("_Revoke Permission"));
+ gtk_widget_set_sensitive(revoke_button, FALSE);
+
+ permission_status_icon = gtk_image_new();
+ permission_status_label = gtk_label_new("");
+
+ details_label_first = gtk_label_new ("");
+ url_button = gtk_link_button_new("");
+ details_label_second = gtk_label_new("");
+
+ gtk_widget_hide(url_button);
+ gtk_widget_set_no_show_all(url_button, TRUE);
+
+ additional_details_icon = gtk_image_new();
+ additional_details_label = gtk_label_new("");
+
+
+ g_signal_connect (button, "clicked", G_CALLBACK (permission_checker), nullptr);
+ g_signal_connect (revoke_button, "clicked", G_CALLBACK (revoke_permissions), nullptr);
+
+ gtk_box_pack_start(GTK_BOX(permission_box), buttons_box, FALSE, FALSE, 20);
+ gtk_box_pack_start(GTK_BOX(permission_box), permission_status_icon, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(permission_box), permission_status_label, FALSE, FALSE, 5);
+
+ gtk_box_pack_start(GTK_BOX(buttons_box), button, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(buttons_box), revoke_button, FALSE, FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(details_box), details_label_first, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(details_box), url_button, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(details_box), details_label_second, FALSE, FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(additional_details_box), additional_details_icon, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(additional_details_box), additional_details_label, FALSE, FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(config_box), permission_box, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(config_box), details_box, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(config_box), additional_details_box, FALSE, FALSE, 0);
+
+ return config_box;
+}
+
+
+static const PreferencesWidget config_contents[] = {
+ WidgetLabel (N_("You need to allow Audacious to scrobble tracks to your Last.fm account.\n")),
+ WidgetCustomGTK (config_status_checker)
+};
+
+const PluginPreferences configuration = {{config_contents}};
diff --git a/src/scrobbler2/scrobbler.c b/src/scrobbler2/scrobbler.c
deleted file mode 100644
index 527468897deb..000000000000
--- a/src/scrobbler2/scrobbler.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Scrobbler Plugin v2.0 for Audacious by Pitxyoki
- *
- * Copyright 2012-2013 LuÃs Picciochi Oliveira <Pitxyoki at Gmail.com>
- *
- * This plugin is part of the Audacious Media Player.
- * It is licensed under the GNU General Public License, version 3.
- */
-
-#include <glib/gstdio.h>
-
-//audacious includes
-#include <audacious/plugin.h>
-#include <audacious/drct.h>
-#include <audacious/playlist.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-
-
-//plugin includes
-#include "scrobbler.h"
-
-
-//shared variables
-bool_t scrobbler_running = TRUE;
-bool_t migrate_config_requested = FALSE;
-bool_t now_playing_requested = FALSE;
-Tuple *now_playing_track = NULL;
-
-pthread_mutex_t communication_mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t communication_signal = PTHREAD_COND_INITIALIZER;
-pthread_mutex_t log_access_mutex = PTHREAD_MUTEX_INITIALIZER;
-gchar *session_key = NULL; /* pooled */
-gchar *request_token = NULL; /* pooled */
-
-
-//static (private) variables
-static Tuple * playing_track = NULL;
-//all times are in microseconds
-static gint64 timestamp = 0;
-static gint64 play_started_at = 0;
-static gint64 pause_started_at = 0;
-static gint64 time_until_scrobble = 0;
-static guint queue_function_ID = 0;
-
-static pthread_t communicator;
-
-static void cleanup_current_track(void) {
-
- timestamp = 0;
- play_started_at = 0;
- pause_started_at = 0;
- time_until_scrobble = 0;
- if (queue_function_ID != 0) {
- gboolean success = g_source_remove(queue_function_ID);
- queue_function_ID = 0;
- if (!success) {
- AUDDBG("BUG: No success on g_source_remove!\n");
- }
- }
- if (playing_track != NULL) {
- tuple_unref(playing_track);
- playing_track = NULL;
- }
-}
-
-char *clean_string(char *string) {
- if (!string)
- return str_get("");
-
- SCOPY(temp, string);
- str_replace_char(temp, '\t', ' ');
- str_unref(string);
- return str_get(temp);
-}
-
-static gboolean queue_track_to_scrobble (gpointer data) {
- AUDDBG("The playing track is going to be ENQUEUED!\n.");
-
- char *queuepath = g_strconcat(aud_get_path(AUD_PATH_USER_DIR),"/scrobbler.log", NULL);
-
- char *artist = clean_string(tuple_get_str(playing_track, FIELD_ARTIST));
- char *title = clean_string(tuple_get_str(playing_track, FIELD_TITLE));
- char *album = clean_string(tuple_get_str(playing_track, FIELD_ALBUM));
-
- int track = tuple_get_int(playing_track, FIELD_TRACK_NUMBER);
- int length = tuple_get_int(playing_track, FIELD_LENGTH);
-
- //artist, title and length are required for a successful scrobble
- if (artist[0] && title[0] && length > 0) {
- char *track_str = (track > 0) ? int_to_str(track) : str_get("");
-
- pthread_mutex_lock(&log_access_mutex);
- FILE *f = g_fopen(queuepath, "a");
-
- if (f == NULL) {
- perror("fopen");
- } else {
- //This isn't exactly the scrobbler.log format because the header
- //is missing, but we're sticking to it anyway...
- //See http://www.audioscrobbler.net/wiki/Portable_Player_Logging
- if (fprintf(f, "%s\t%s\t%s\t%s\t%i\tL\t%"G_GINT64_FORMAT"\n",
- artist, album, title, track_str, length / 1000, timestamp) < 0) {
- perror("fprintf");
- } else {
- pthread_mutex_lock(&communication_mutex);
- pthread_cond_signal(&communication_signal);
- pthread_mutex_unlock(&communication_mutex);
- }
- fclose(f);
- }
- pthread_mutex_unlock(&log_access_mutex);
-
- str_unref(track_str);
- }
- g_free(queuepath);
- str_unref(artist);
- str_unref(title);
- str_unref(album);
-
- cleanup_current_track();
- return FALSE;
-}
-
-
-static void stopped (void *hook_data, void *user_data) {
- // Called when pressing STOP and when the playlist ends.
- cleanup_current_track();
-}
-
-static void ended (void *hook_data, void *user_data) {
- //Called when when a track finishes playing.
-
- //TODO: hic sunt race conditions
- if (playing_track != NULL && (g_get_monotonic_time() > (play_started_at + 30*G_USEC_PER_SEC)) ) {
- //This is an odd situation when the track's real length doesn't correspond to the length reported by the player.
- //If we are at the end of the track, it is longer than 30 seconds and it wasn't scrobbled, we scrobble it by then.
-
- if (queue_function_ID != 0) {
- gboolean success = g_source_remove(queue_function_ID);
- queue_function_ID = 0;
- if (!success) {
- AUDDBG("BUG or race condition: Could not remove source.\n");
- } else {
- queue_track_to_scrobble(NULL);
- }
- }
- }
-
- cleanup_current_track();
-}
-
-static void ready (void *hook_data, void *user_data) {
- cleanup_current_track();
-
- Tuple *current_track = aud_playlist_entry_get_tuple(aud_playlist_get_playing(), aud_playlist_get_position(aud_playlist_get_playing()), FALSE);
-
- int duration_seconds = tuple_get_int(current_track, FIELD_LENGTH) / 1000;
- if (duration_seconds <= 30) {
- tuple_unref(current_track);
- return;
- }
-
- pthread_mutex_lock(&communication_mutex);
- now_playing_track = tuple_ref(current_track);
- now_playing_requested = TRUE;
- pthread_cond_signal(&communication_signal);
- pthread_mutex_unlock(&communication_mutex);
-
- time_until_scrobble = (((gint64)duration_seconds)*G_USEC_PER_SEC) / 2;
- if (time_until_scrobble > 4*60*G_USEC_PER_SEC) {
- time_until_scrobble = 4*60*G_USEC_PER_SEC;
- }
- timestamp = g_get_real_time() / G_USEC_PER_SEC;
- play_started_at = g_get_monotonic_time();
- playing_track = current_track;
-
- queue_function_ID = g_timeout_add_seconds(time_until_scrobble / G_USEC_PER_SEC, (GSourceFunc) queue_track_to_scrobble, NULL);
-
-}
-
-static void paused (void *hook_data, void *user_data) {
- if (playing_track == NULL) {
- //This happens when audacious is started in paused mode
- return;
- }
-
- gboolean success = g_source_remove(queue_function_ID);
- queue_function_ID = 0;
- if (!success) {
- AUDDBG("BUG: Could not remove source.\n");
- return;
- }
-
- pause_started_at = g_get_monotonic_time();
-}
-
-static void unpaused (void *hook_data, void *user_data) {
-
- if (playing_track == NULL
- || pause_started_at == 0) { //TODO: audacious was started with a paused track.
- return;
- }
- time_until_scrobble = time_until_scrobble - (pause_started_at - play_started_at);
-
- queue_function_ID = g_timeout_add_seconds(time_until_scrobble / G_USEC_PER_SEC, (GSourceFunc) queue_track_to_scrobble, NULL);
-
- pause_started_at = 0;
- play_started_at = g_get_monotonic_time();
-}
-
-
-
-static bool_t scrobbler_init (void) {
- // Initialize libXML and check potential ABI mismatches between
- // the version it was compiled for and the actual libXML in use
- LIBXML_TEST_VERSION
-
- if (scrobbler_communication_init() == FALSE) {
- aud_interface_show_error(_("The Scrobbler plugin could not be started.\n"
- "There might be a problem with your installation."));
- return FALSE;
- }
-
- session_key = aud_get_str("scrobbler", "session_key");
- if (!session_key[0])
- scrobbling_enabled = FALSE;
-
- //TODO: Remove this after we are "sure" that noone is using the old scrobbler (from audacious < 3.4)
- //By Debian's standard, this will probably be by 2020 or so
- //Migration from the old scrobbler config
- if (!session_key[0]) {
- //We haven't been configured yet
-
- char *migrated = aud_get_str("scrobbler", "migrated");
- if (strcmp(migrated, "true") != 0) {
- //We haven't been migrated yet
-
- char *oldpass = aud_get_str("audioscrobbler","password");
- if (oldpass[0]) {
-
- char *olduser = aud_get_str("audioscrobbler","username");
- if (olduser[0]) {
- //And the old scrobbler was configured
-
- scrobbling_enabled = FALSE;
- migrate_config_requested = TRUE;
- }
- str_unref(olduser);
- }
- str_unref(oldpass);
- }
- str_unref(migrated);
- }
-
-
-
- pthread_create(&communicator, NULL, scrobbling_thread, NULL);
-
- hook_associate("playback stop", (HookFunction) stopped, NULL);
- hook_associate("playback end", (HookFunction) ended, NULL);
- hook_associate("playback ready", (HookFunction) ready, NULL);
- hook_associate("playback pause", (HookFunction) paused, NULL);
- hook_associate("playback unpause", (HookFunction) unpaused, NULL);
- return TRUE;
-}
-
-static void scrobbler_cleanup (void) {
-
- hook_dissociate("playback stop", (HookFunction) stopped);
- hook_dissociate("playback end", (HookFunction) ended);
- hook_dissociate("playback ready", (HookFunction) ready);
- hook_dissociate("playback pause", (HookFunction) paused);
- hook_dissociate("playback unpause", (HookFunction) unpaused);
-
- cleanup_current_track();
-
- scrobbling_enabled = FALSE;
- scrobbler_running = FALSE;
- pthread_mutex_lock(&communication_mutex);
- pthread_cond_signal(&communication_signal);
- pthread_mutex_unlock(&communication_mutex);
-
- pthread_join(communicator, NULL);
-
- str_unref(request_token);
- str_unref(session_key);
- str_unref(username);
- request_token = NULL;
- session_key = NULL;
- username = NULL;
- scrobbler_running = TRUE;
-}
-
-static const char scrobbler_about[] =
- N_("Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n\n"
- "Copyright © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com>\n\n"
- "Thanks to John Lindgren for giving me a hand at the beginning of this project.\n\n");
-
-
-AUD_GENERAL_PLUGIN (
- .name = N_("Scrobbler 2.0"),
- .domain = PACKAGE,
- .about_text = scrobbler_about,
- .init = scrobbler_init,
- .cleanup = scrobbler_cleanup,
- .prefs = &configuration //see config_window.c
-)
diff --git a/src/scrobbler2/scrobbler.cc b/src/scrobbler2/scrobbler.cc
new file mode 100644
index 000000000000..f930b68cd15d
--- /dev/null
+++ b/src/scrobbler2/scrobbler.cc
@@ -0,0 +1,291 @@
+/*
+ * Scrobbler Plugin v2.0 for Audacious by Pitxyoki
+ *
+ * Copyright 2012-2013 LuÃs Picciochi Oliveira <Pitxyoki at Gmail.com>
+ *
+ * This plugin is part of the Audacious Media Player.
+ * It is licensed under the GNU General Public License, version 3.
+ */
+
+#include <glib/gstdio.h>
+
+//audacious includes
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+
+
+//plugin includes
+#include "scrobbler.h"
+
+class Scrobbler : public GeneralPlugin
+{
+public:
+ static const char about[];
+
+ static constexpr PluginInfo info = {
+ N_("Scrobbler 2.0"),
+ PACKAGE,
+ about,
+ & configuration
+ };
+
+ constexpr Scrobbler () : GeneralPlugin (info, false) {}
+
+ bool init ();
+ void cleanup ();
+};
+
+EXPORT Scrobbler aud_plugin_instance;
+
+//shared variables
+gboolean scrobbler_running = TRUE;
+gboolean migrate_config_requested = FALSE;
+gboolean now_playing_requested = FALSE;
+Tuple now_playing_track;
+
+pthread_mutex_t communication_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t communication_signal = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t log_access_mutex = PTHREAD_MUTEX_INITIALIZER;
+String session_key;
+String request_token;
+
+
+//static (private) variables
+static Tuple playing_track;
+//all times are in microseconds
+static int64_t timestamp = 0;
+static int64_t play_started_at = 0;
+static int64_t pause_started_at = 0;
+static int64_t time_until_scrobble = 0;
+static unsigned queue_function_ID = 0;
+
+static pthread_t communicator;
+
+static void cleanup_current_track(void) {
+
+ timestamp = 0;
+ play_started_at = 0;
+ pause_started_at = 0;
+ time_until_scrobble = 0;
+ if (queue_function_ID != 0) {
+ gboolean success = g_source_remove(queue_function_ID);
+ queue_function_ID = 0;
+ if (!success) {
+ AUDDBG("BUG: No success on g_source_remove!\n");
+ }
+ }
+ playing_track = Tuple ();
+}
+
+StringBuf clean_string (const char *string) {
+ StringBuf temp = str_copy (string ? string : "");
+ str_replace_char (temp, '\t', ' ');
+ return temp;
+}
+
+static gboolean queue_track_to_scrobble (void * data) {
+ AUDDBG("The playing track is going to be ENQUEUED!\n.");
+
+ char *queuepath = g_strconcat(aud_get_path(AudPath::UserDir),"/scrobbler.log", nullptr);
+
+ StringBuf artist = clean_string (playing_track.get_str (Tuple::Artist));
+ StringBuf title = clean_string (playing_track.get_str (Tuple::Title));
+ StringBuf album = clean_string (playing_track.get_str (Tuple::Album));
+
+ int track = playing_track.get_int (Tuple::Track);
+ int length = playing_track.get_int (Tuple::Length);
+
+ //artist, title and length are required for a successful scrobble
+ if (artist[0] && title[0] && length > 0) {
+ StringBuf track_str = (track > 0) ? int_to_str (track) : StringBuf (0);
+
+ pthread_mutex_lock(&log_access_mutex);
+ FILE *f = g_fopen(queuepath, "a");
+
+ if (f == nullptr) {
+ perror("fopen");
+ } else {
+ //This isn't exactly the scrobbler.log format because the header
+ //is missing, but we're sticking to it anyway...
+ //See http://www.audioscrobbler.net/wiki/Portable_Player_Logging
+ if (fprintf(f, "%s\t%s\t%s\t%s\t%i\tL\t%" G_GINT64_FORMAT "\n",
+ (const char *)artist, (const char *)album, (const char *)title,
+ (const char *)track_str, length / 1000, timestamp) < 0) {
+ perror("fprintf");
+ } else {
+ pthread_mutex_lock(&communication_mutex);
+ pthread_cond_signal(&communication_signal);
+ pthread_mutex_unlock(&communication_mutex);
+ }
+ fclose(f);
+ }
+ pthread_mutex_unlock(&log_access_mutex);
+ }
+ g_free(queuepath);
+ cleanup_current_track();
+ return FALSE;
+}
+
+
+static void stopped (void *hook_data, void *user_data) {
+ // Called when pressing STOP and when the playlist ends.
+ cleanup_current_track();
+}
+
+static void ended (void *hook_data, void *user_data) {
+ //Called when when a track finishes playing.
+
+ //TODO: hic sunt race conditions
+ if (playing_track && (g_get_monotonic_time() > (play_started_at + 30*G_USEC_PER_SEC)) ) {
+ //This is an odd situation when the track's real length doesn't correspond to the length reported by the player.
+ //If we are at the end of the track, it is longer than 30 seconds and it wasn't scrobbled, we scrobble it by then.
+
+ if (queue_function_ID != 0) {
+ gboolean success = g_source_remove(queue_function_ID);
+ queue_function_ID = 0;
+ if (!success) {
+ AUDDBG("BUG or race condition: Could not remove source.\n");
+ } else {
+ queue_track_to_scrobble(nullptr);
+ }
+ }
+ }
+
+ cleanup_current_track();
+}
+
+static void ready (void *hook_data, void *user_data) {
+ cleanup_current_track();
+
+ Tuple current_track = aud_drct_get_tuple();
+
+ int duration_seconds = current_track.get_int (Tuple::Length) / 1000;
+ if (duration_seconds <= 30)
+ return;
+
+ pthread_mutex_lock(&communication_mutex);
+ now_playing_track = current_track.ref ();
+ now_playing_requested = TRUE;
+ pthread_cond_signal(&communication_signal);
+ pthread_mutex_unlock(&communication_mutex);
+
+ time_until_scrobble = (((int64_t)duration_seconds)*G_USEC_PER_SEC) / 2;
+ if (time_until_scrobble > 4*60*G_USEC_PER_SEC) {
+ time_until_scrobble = 4*60*G_USEC_PER_SEC;
+ }
+ timestamp = g_get_real_time() / G_USEC_PER_SEC;
+ play_started_at = g_get_monotonic_time();
+ playing_track = std::move (current_track);
+
+ queue_function_ID = g_timeout_add_seconds(time_until_scrobble / G_USEC_PER_SEC, (GSourceFunc) queue_track_to_scrobble, nullptr);
+
+}
+
+static void paused (void *hook_data, void *user_data) {
+ if (! playing_track) {
+ //This happens when audacious is started in paused mode
+ return;
+ }
+
+ gboolean success = g_source_remove(queue_function_ID);
+ queue_function_ID = 0;
+ if (!success) {
+ AUDDBG("BUG: Could not remove source.\n");
+ return;
+ }
+
+ pause_started_at = g_get_monotonic_time();
+}
+
+static void unpaused (void *hook_data, void *user_data) {
+
+ if (! playing_track
+ || pause_started_at == 0) { //TODO: audacious was started with a paused track.
+ return;
+ }
+ time_until_scrobble = time_until_scrobble - (pause_started_at - play_started_at);
+
+ queue_function_ID = g_timeout_add_seconds(time_until_scrobble / G_USEC_PER_SEC, (GSourceFunc) queue_track_to_scrobble, nullptr);
+
+ pause_started_at = 0;
+ play_started_at = g_get_monotonic_time();
+}
+
+bool Scrobbler::init ()
+{
+ // Initialize libXML and check potential ABI mismatches between
+ // the version it was compiled for and the actual libXML in use
+ LIBXML_TEST_VERSION
+
+ if (scrobbler_communication_init() == FALSE) {
+ aud_ui_show_error(_("The Scrobbler plugin could not be started.\n"
+ "There might be a problem with your installation."));
+ return FALSE;
+ }
+
+ session_key = aud_get_str("scrobbler", "session_key");
+ if (!session_key[0])
+ scrobbling_enabled = FALSE;
+
+ //TODO: Remove this after we are "sure" that noone is using the old scrobbler (from audacious < 3.4)
+ //By Debian's standard, this will probably be by 2020 or so
+ //Migration from the old scrobbler config
+ if (!session_key[0]) {
+ //We haven't been configured yet
+
+ String migrated = aud_get_str("scrobbler", "migrated");
+ if (strcmp(migrated, "true") != 0) {
+ //We haven't been migrated yet
+
+ String oldpass = aud_get_str("audioscrobbler","password");
+ String olduser = aud_get_str("audioscrobbler","username");
+ if (oldpass[0] && olduser[0]) {
+ //And the old scrobbler was configured
+
+ scrobbling_enabled = FALSE;
+ migrate_config_requested = TRUE;
+ }
+ }
+ }
+
+ pthread_create(&communicator, nullptr, scrobbling_thread, nullptr);
+
+ hook_associate("playback stop", (HookFunction) stopped, nullptr);
+ hook_associate("playback end", (HookFunction) ended, nullptr);
+ hook_associate("playback ready", (HookFunction) ready, nullptr);
+ hook_associate("playback pause", (HookFunction) paused, nullptr);
+ hook_associate("playback unpause", (HookFunction) unpaused, nullptr);
+ return TRUE;
+}
+
+void Scrobbler::cleanup ()
+{
+ hook_dissociate("playback stop", (HookFunction) stopped);
+ hook_dissociate("playback end", (HookFunction) ended);
+ hook_dissociate("playback ready", (HookFunction) ready);
+ hook_dissociate("playback pause", (HookFunction) paused);
+ hook_dissociate("playback unpause", (HookFunction) unpaused);
+
+ cleanup_current_track();
+
+ scrobbling_enabled = FALSE;
+ scrobbler_running = FALSE;
+ pthread_mutex_lock(&communication_mutex);
+ pthread_cond_signal(&communication_signal);
+ pthread_mutex_unlock(&communication_mutex);
+
+ pthread_join(communicator, nullptr);
+
+ request_token = String();
+ session_key = String();
+ username = String();
+ scrobbler_running = TRUE;
+}
+
+const char Scrobbler::about[] =
+ N_("Audacious Scrobbler Plugin 2.0 by Pitxyoki,\n\n"
+ "Copyright © 2012-2013 LuÃs M. Picciochi Oliveira <Pitxyoki at Gmail.com>\n\n"
+ "Thanks to John Lindgren for giving me a hand at the beginning of this project.\n\n");
diff --git a/src/scrobbler2/scrobbler.h b/src/scrobbler2/scrobbler.h
index 9e162ec133d7..aa7db765cdc1 100644
--- a/src/scrobbler2/scrobbler.h
+++ b/src/scrobbler2/scrobbler.h
@@ -18,10 +18,10 @@
#include <gtk/gtk.h>
//audacious includes
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/debug.h>
-#include <audacious/preferences.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/tuple.h>
#define SCROBBLER_API_KEY "4b4f73bda181868353f9b438604adf52"
#define SCROBBLER_SHARED_SECRET "716cc0a784bb62835de5bd674e65eb57"
@@ -37,8 +37,8 @@ extern enum permission {
PERMISSION_NONET
} perm_result;
-extern bool_t scrobbler_running;
-extern bool_t scrobbling_enabled;
+extern gboolean scrobbler_running;
+extern gboolean scrobbling_enabled;
//used to tell the scrobbling thread that there's something to do:
@@ -55,41 +55,41 @@ extern pthread_mutex_t log_access_mutex;
*/
//TRUE when a permission check is being requested
-extern bool_t permission_check_requested;
-extern bool_t invalidate_session_requested;
+extern gboolean permission_check_requested;
+extern gboolean invalidate_session_requested;
//Migrate the settings from the old scrobbler
-extern bool_t migrate_config_requested;
+extern gboolean migrate_config_requested;
//Send "now playing"
-extern bool_t now_playing_requested;
-extern Tuple *now_playing_track;
+extern gboolean now_playing_requested;
+extern Tuple now_playing_track;
//scrobbler_communication.c
-extern bool_t scrobbler_communication_init();
-extern gpointer scrobbling_thread(gpointer data);
+extern gboolean scrobbler_communication_init();
+extern void * scrobbling_thread(void * data);
/* Internal stuff */
//Data sent to the XML parser
-extern gchar *received_data;
+extern char *received_data;
extern size_t received_data_size;
//Data filled by the XML parser
-extern gchar *request_token; /* pooled */
-extern gchar *session_key; /* pooled */
-extern gchar *username; /* pooled */
+extern String request_token;
+extern String session_key;
+extern String username;
//scrobbler_xml_parsing.c
-extern bool_t read_authentication_test_result(char **error_code, char **error_detail);
-extern bool_t read_token(char **error_code, char **error_detail);
-extern bool_t read_session_key(char **error_code, char **error_detail);
-extern bool_t read_scrobble_result(char **error_code, char **error_detail, bool_t *ignored, char **ignored_code);
+extern gboolean read_authentication_test_result(String &error_code, String &error_detail);
+extern gboolean read_token(String &error_code, String &error_detail);
+extern gboolean read_session_key(String &error_code, String &error_detail);
+extern gboolean read_scrobble_result(String &error_code, String &error_detail, gboolean *ignored, String &ignored_code);
//scrobbler.c
-extern char *clean_string(char *string);
+extern StringBuf clean_string(const char *string);
#endif /* SCROBBLER_H_ */
diff --git a/src/scrobbler2/scrobbler_communication.c b/src/scrobbler2/scrobbler_communication.c
deleted file mode 100644
index 381fefaa30fd..000000000000
--- a/src/scrobbler2/scrobbler_communication.c
+++ /dev/null
@@ -1,789 +0,0 @@
-
-//external includes
-#include <stdarg.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <curl/curl.h>
-
-#include <libaudcore/audstrings.h>
-
-//plugin includes
-#include "scrobbler.h"
-
-typedef struct {
- gchar *paramName;
- gchar *argument;
-} API_Parameter;
-
-static CURL *curlHandle = NULL; //global handle holding cURL options
-
-bool_t scrobbling_enabled = TRUE;
-
-//shared variables
-gchar *received_data = NULL; //Holds the result of the last request made to last.fm
-size_t received_data_size = 0; //Holds the size of the received_data buffer
-
-
-
-// The cURL callback function to store the received data from the last.fm servers.
-static size_t result_callback (void *buffer, size_t size, size_t nmemb, void *userp) {
-
- const size_t len = size*nmemb;
-
- gchar *temp_data = realloc(received_data, received_data_size + len + 1);
-
- if (temp_data == NULL) {
- return 0;
- } else {
- received_data = temp_data;
- }
-
- memcpy(received_data + received_data_size, buffer, len);
-
- received_data_size += len;
-
- return len;
-}
-
-static int scrobbler_compare_API_Parameters(const void *a, const void *b) {
- return g_strcmp0(((const API_Parameter *) a)->paramName, ((const API_Parameter *) b)->paramName);
-}
-
-static char *scrobbler_get_signature(int nparams, API_Parameter *parameters) {
- qsort(parameters, nparams, sizeof(API_Parameter), scrobbler_compare_API_Parameters);
-
- char *all_params = NULL;
- gchar *result = NULL;
- gchar *api_sig = NULL;
- size_t api_sig_length = strlen(SCROBBLER_SHARED_SECRET);
-
- for (gint i = 0; i < nparams; i++) {
- api_sig_length += strlen(parameters[i].paramName) + strlen(parameters[i].argument);
- }
- all_params = g_new0(gchar, api_sig_length);
-
- for (int i = 0; i < nparams; i++) {
- strcat(all_params, parameters[i].paramName);
- strcat(all_params, parameters[i].argument);
- }
-
- api_sig = g_strconcat(all_params, SCROBBLER_SHARED_SECRET, NULL);
- g_free(all_params);
-
-
- result = g_compute_checksum_for_string(G_CHECKSUM_MD5, api_sig, -1);
- g_free(api_sig);
- return result;
-}
-
-
-
-
-/*
- * n_args should count with the given authentication parameters
- * At most 2: api_key, session_key.
- * api_sig (checksum) is always included, be it necessary or not
- * Example usage:
- * create_message_to_lastfm("track.scrobble", 5
- * "artist", "Artist Name", "track", "Track Name", "timestamp", time(NULL),
- * "api_key", SCROBBLER_API_KEY, "sk", session_key);
- *
- * Returns NULL if an error occurrs
- */
-static gchar *create_message_to_lastfm (char *method_name, int n_args, ...) {
- //TODO: Improve this f-ugly mess.
- gchar *result = NULL;
-
- //parameters to be sent to the get_signature() function
- API_Parameter signable_params[n_args+1];
- signable_params[0].paramName = g_strdup("method");
- signable_params[0].argument = g_strdup(method_name);
-
- size_t msg_size = 2; // First '=' and final '\0'
- msg_size = msg_size + strlen("method") + strlen(method_name);
-
- va_list vl;
- va_start(vl, n_args);
- for (int i = 0; i < n_args; i++) {
-
- signable_params[i+1].paramName = g_strdup(va_arg(vl, gchar *));
- signable_params[i+1].argument = g_strdup(va_arg(vl, gchar *));
-
- msg_size += strlen( signable_params[i+1].paramName );
- msg_size += strlen( signable_params[i+1].argument );
- msg_size += 2; //Counting '&' and '='
- }
- va_end(vl);
-
- gchar *aux;
- result = g_strconcat("method=", method_name, NULL);
- char *escaped_argument;
-
- for (int i = 0; i < n_args; i++) {
- escaped_argument = curl_easy_escape(curlHandle, signable_params[i+1].argument, 0);
-
- aux = g_strdup_printf("%s&%s=%s", result, signable_params[i+1].paramName, escaped_argument);
- g_free(result);
- curl_free(escaped_argument);
- result = aux;
- }
-
- gchar *api_sig = scrobbler_get_signature(n_args+1, signable_params);
-
- aux = g_strdup_printf("%s&api_sig=%s", result, api_sig);
- result = aux;
-
- AUDDBG("FINAL message: %s.\n", result);
- g_free(api_sig);
- for (int i = 0; i < n_args+1; i++) {
- g_free(signable_params[i].paramName);
- g_free(signable_params[i].argument);
- }
-
- return result;
-}
-
-
-static bool_t send_message_to_lastfm(gchar *data) {
- AUDDBG("This message will be sent to last.fm:\n%s\n%%%%End of message%%%%\n", data);//Enter?\n", data);
- curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDS, data);
- CURLcode curl_requests_result = curl_easy_perform(curlHandle);
-
- if (curl_requests_result != CURLE_OK) {
- AUDDBG("Could not communicate with last.fm: %s.\n", curl_easy_strerror(curl_requests_result));
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-//returns:
-// FALSE if there was a network problem
-// TRUE otherwise (request_token must be checked)
-static bool_t scrobbler_request_token() {
- gchar *tokenmsg = create_message_to_lastfm("auth.getToken",
- 1,
- "api_key", SCROBBLER_API_KEY
- );
-
- if (send_message_to_lastfm(tokenmsg) == FALSE) {
- AUDDBG("Could not send token request to last.fm.\n");
- g_free(tokenmsg);
- return FALSE;
- }
-
- bool_t success = TRUE;
- gchar *error_code = NULL;
- gchar *error_detail = NULL;
-
- if (read_token(&error_code, &error_detail) == FALSE) {
- success = FALSE;
- if (error_code != NULL && g_strcmp0(error_code, "8")) {
- //error code 8: There was an error granting the request token. Please try again later
- str_unref(request_token);
- request_token = NULL;
- }
- }
-
- str_unref(error_code);
- str_unref(error_detail);
- return success;
-}
-
-
-static bool_t update_session_key() {
- bool_t result = TRUE;
- gchar *error_code = NULL;
- gchar *error_detail = NULL;
-
- if (read_session_key(&error_code, &error_detail) == FALSE) {
- if (error_code != NULL && (
- g_strcmp0(error_code, "4") == 0 || //invalid token
- g_strcmp0(error_code, "14") == 0 || //token not authorized
- g_strcmp0(error_code, "15") == 0 //token expired
- )) {
- AUDDBG("error code CAUGHT: %s\n", error_code);
- str_unref(session_key);
- session_key = NULL;
- result = TRUE;
- } else {
- result= FALSE;
- }
- }
-
- aud_set_str("scrobbler", "session_key", session_key ? session_key : "");
-
- str_unref(error_code);
- str_unref(error_detail);
- return result;
-}
-
-//returns:
-// FALSE if there was a network problem
-// TRUE otherwise (session_key must be checked)
-static bool_t scrobbler_request_session() {
-
- gchar *sessionmsg = create_message_to_lastfm("auth.getSession",
- 2,
- "token", request_token,
- "api_key", SCROBBLER_API_KEY);
-
- if (send_message_to_lastfm(sessionmsg) == FALSE) {
- g_free(sessionmsg);
- return FALSE;
- }
-
- g_free(sessionmsg);
- //the token can only be sent once
- str_unref(request_token);
- request_token = NULL;
-
- return update_session_key();
-}
-
-
-
-//returns:
-// FALSE if there was a network problem.
-// TRUE otherwise (scrobbling_enabled must be checked)
-//sets scrobbling_enabled to TRUE if the session is OK
-//sets session_key to NULL if it is invalid
-static bool_t scrobbler_test_connection() {
-
- if (!session_key || !session_key[0]) {
- scrobbling_enabled = FALSE;
- return TRUE;
- }
-
-
- gchar *testmsg = create_message_to_lastfm("user.getRecommendedArtists",
- 3,
- "limit", "1",
- "api_key", SCROBBLER_API_KEY,
- "sk", session_key
- );
- bool_t success = send_message_to_lastfm(testmsg);
- g_free(testmsg);
- if (success == FALSE) {
- AUDDBG("Network problems. Will not scrobble any tracks.\n");
- scrobbling_enabled = FALSE;
- if (permission_check_requested) {
- perm_result = PERMISSION_NONET;
- }
- return FALSE;
- }
-
- gchar *error_code = NULL;
- gchar *error_detail = NULL;
-
- if (read_authentication_test_result(&error_code, &error_detail) == FALSE) {
- AUDDBG("Error code: %s. Detail: %s.\n", error_code, error_detail);
- if (error_code != NULL && (
- g_strcmp0(error_code, "4") == 0 || //error code 4: Authentication Failed - You do not have permissions to access the service
- g_strcmp0(error_code, "9") == 0 //error code 9: Invalid session key - Please re-authenticate
- )) {
- str_unref(session_key);
- session_key = NULL;
- aud_set_str("scrobbler", "session_key", "");
- scrobbling_enabled = FALSE;
- } else {
- //network problem.
- scrobbling_enabled = FALSE;
- AUDDBG("Connection NOT OK. Scrobbling disabled\n");
- success = FALSE;
- }
- } else {
- //THIS IS THE ONLY PLACE WHERE SCROBBLING IS SET TO ENABLED IN RUN-TIME
- scrobbling_enabled = TRUE;
- AUDDBG("Connection OK. Scrobbling enabled.\n");
- }
-
- str_unref(error_code);
- str_unref(error_detail);
- return success;
-}
-
-//called from scrobbler_init() @ scrobbler.c
-bool_t scrobbler_communication_init() {
- CURLcode curl_requests_result = curl_global_init(CURL_GLOBAL_DEFAULT);
- if (curl_requests_result != CURLE_OK) {
- AUDDBG("Could not initialize libCURL: %s.\n", curl_easy_strerror(curl_requests_result));
- return FALSE;
- }
-
- curlHandle = curl_easy_init();
- if (curlHandle == NULL) {
- AUDDBG("Could not initialize libCURL.\n");
- return FALSE;
- }
-
- curl_requests_result = curl_easy_setopt(curlHandle, CURLOPT_URL, SCROBBLER_URL);
- if (curl_requests_result != CURLE_OK) {
- AUDDBG("Could not define scrobbler destination URL: %s.\n", curl_easy_strerror(curl_requests_result));
- return FALSE;
- }
-
- curl_requests_result = curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, result_callback);
- if (curl_requests_result != CURLE_OK) {
- AUDDBG("Could not register scrobbler callback function: %s.\n", curl_easy_strerror(curl_requests_result));
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void set_timestamp_to_current(gchar **line) {
- //line[0] line[1] line[2] line[3] line[4] line[5] line[6] line[7]
- //artist album title number length "L" timestamp NULL
-
- gchar **splitted_line = g_strsplit(*line, "\t", 0);
- g_free(splitted_line[6]);
- splitted_line[6] = g_strdup_printf("%"G_GINT64_FORMAT"", g_get_real_time() / G_USEC_PER_SEC);
- AUDDBG("splitted line's timestamp is now: %s.\n", splitted_line[6]);
- g_free(*line);
- (*line) = g_strjoinv("\t", splitted_line);
-}
-
-static void delete_lines_from_scrobble_log (GSList **lines_to_remove_ptr, GSList **lines_to_retry_ptr, gchar *queuepath) {
- GSList *lines_to_remove = *lines_to_remove_ptr;
- GSList *lines_to_retry = *lines_to_retry_ptr;
- gchar *contents = NULL;
- gchar **lines = NULL;
- gchar **finallines = g_malloc_n(1, sizeof(gchar *));
- int n_finallines;
-
- if (lines_to_remove != NULL) {
- lines_to_remove = g_slist_reverse(lines_to_remove);
- }
- if (lines_to_retry != NULL) {
- lines_to_retry = g_slist_reverse(lines_to_retry);
- }
-
-
- pthread_mutex_lock(&log_access_mutex);
-
- gboolean success = g_file_get_contents(queuepath, &contents, NULL, NULL);
- if (!success) {
- AUDDBG("Could not read scrobbler.log contents.\n");
- } else {
- lines = g_strsplit(contents, "\n", 0);
-
- n_finallines = 0;
- for (int i = 0 ; lines[i] != NULL && strlen(lines[i]) > 0; i++) {
- if (lines_to_remove != NULL && *((int *) (lines_to_remove->data)) == i) {
- //this line is to remove
- lines_to_remove = g_slist_next(lines_to_remove);
- } else {
- //keep this line
- AUDDBG("Going to keep line %i\n", i);
- if (lines_to_retry != NULL && *((int *) (lines_to_retry->data)) == i) {
- lines_to_retry = g_slist_next(lines_to_retry);
- //this line will be retried with a zero timestamp
- AUDDBG("Going to zero this line.\n");
- AUDDBG("Line before: %s.\n", lines[i]);
- set_timestamp_to_current(&(lines[i]));
- AUDDBG("Line after: %s.\n", lines[i]);
-
- } else {
- AUDDBG("not zeroing this line\n");
- }
- n_finallines++;
- finallines = g_realloc_n(finallines, n_finallines, sizeof(gchar *));
- finallines[n_finallines-1] = g_strdup(lines[i]);
- }
- }
-
- finallines = g_realloc_n(finallines, n_finallines+2, sizeof(gchar *));
- finallines[n_finallines] = g_strdup("");
- finallines[n_finallines+1] = NULL;
- g_free(contents);
- contents = g_strjoinv("\n", finallines);
- success = g_file_set_contents(queuepath, contents, -1, NULL);
- if (!success) {
- AUDDBG("Could not write to scrobbler.log!\n");
- }
-
- }
-
- pthread_mutex_unlock(&log_access_mutex);
-
-
- g_strfreev(finallines);
- g_strfreev(lines);
- g_free(contents);
-}
-
-static void save_line_to_remove(GSList **lines_to_remove, int linenumber) {
- int *rem = g_malloc(sizeof(int));
- *rem = linenumber;
- (*lines_to_remove) = g_slist_prepend((*lines_to_remove), rem);
-}
-
-static void scrobble_cached_queue() {
-
- gchar *queuepath = g_build_filename(aud_get_path(AUD_PATH_USER_DIR),"scrobbler.log", NULL);
- gchar *contents = NULL;
- gboolean success;
- gchar **lines = NULL;
- gchar **line;
- gchar *scrobblemsg;
- GSList *lines_to_remove = NULL; //lines to remove because they were scrobbled (or ignored, and will not be retried)
- GSList *lines_to_retry = NULL; //lines to retry later because they were too old TODO: or "daily scrobble limit reached"
-
- pthread_mutex_lock(&log_access_mutex);
- success = g_file_get_contents(queuepath, &contents, NULL, NULL);
- pthread_mutex_unlock(&log_access_mutex);
- if (!success) {
- AUDDBG("Couldn't access the queue file.\n");
- } else {
-
- lines = g_strsplit(contents, "\n", 0);
-
- for (int i = 0; lines[i] != NULL && strlen(lines[i]) > 0 && scrobbling_enabled; i++) {
- line = g_strsplit(lines[i], "\t", 0);
-
- //line[0] line[1] line[2] line[3] line[4] line[5] line[6] line[7]
- //artist album title number length "L" timestamp NULL
-
- if (line[0] && line[2] && (strcmp(line[5], "L") == 0) && line[6] && (line[7] == NULL)) {
- scrobblemsg = create_message_to_lastfm("track.scrobble",
- 8,
- "artist", line[0],
- "album", line[1],
- "track", line[2],
- "trackNumber", line[3],
- "duration", line[4],
- "timestamp", line[6],
- "api_key", SCROBBLER_API_KEY,
- "sk", session_key);
- if (send_message_to_lastfm(scrobblemsg) == TRUE) {
- char *error_code = NULL;
- char *error_detail = NULL;
- bool_t ignored = FALSE;
- char *ignored_code = NULL;
-
- if (read_scrobble_result(&error_code, &error_detail, &ignored, &ignored_code) == TRUE) {
- AUDDBG("SCROBBLE OK. Error code: %s. Error detail: %s\n", error_code, error_detail);
- AUDDBG("SCROBBLE OK. ignored: %i.\n", ignored);
- AUDDBG("SCROBBLE OK. ignored code: %s.\n", ignored_code);
- if (ignored == TRUE && g_strcmp0(ignored_code, "3") == 0) { //3: Timestamp was too old
- AUDDBG("SCROBBLE IGNORED!!! %i, detail: %s\n", ignored, ignored_code);
- save_line_to_remove(&lines_to_retry, i);
- } else if (ignored == TRUE && g_strcmp0(ignored_code, "") == 0) { //5: Daily scrobble limit reached
- //TODO: a track might not be scrobbled due to "daily scrobble limit exeeded".
- //This message comes on the ignoredMessage attribute, inside the XML of the response.
- //We are not dealing with this case currently and are losing that scrobble.
- //TODO
-
- } else {
- AUDDBG("Not ignored. Carrying on...\n");
- save_line_to_remove(&lines_to_remove, i);
- }
- } else {
- AUDDBG("SCROBBLE NOT OK. Error code: %s. Error detail: %s.\n", error_code, error_detail);
-
- if (error_code == NULL) { //net error(?) or the answer from last.fm was not well read
- //scrobble to be retried
- }
- else if (g_strcmp0(error_code, "11") == 0 ||
- g_strcmp0(error_code, "16") == 0){
- //error code 11: Service Offline - This service is temporarily offline. Try again later.
- //error code 16: The service is temporarily unavailable, please try again.
- //scrobble to be retried
- }
- else if (g_strcmp0(error_code, "9") == 0) {
- //Bad Session. Reauth.
- scrobbling_enabled = FALSE;
- str_unref(session_key);
- session_key = NULL;
- aud_set_str("scrobbler", "session_key", "");
- }
- else {
- save_line_to_remove(&lines_to_remove, i);
- }
- }
-
- str_unref(error_code);
- str_unref(error_detail);
- str_unref(ignored_code);
- } else {
- AUDDBG("Could not scrobble a track on the queue. Network problem?\n");
- //scrobble to be retried
- scrobbling_enabled = FALSE;
- }
-
- g_free(scrobblemsg);
- //TODO: Avoid spamming last.fm --- It's not as simple as just adding a wait here:
- //If audacious is closed while we're on this loop, tracks might be re-scrobbled.
- //This shall be doable if we only pick one track at a time from the scrobbler.log
- } else {
- AUDDBG("Unscrobbable line.\n");
- //leave entry on the cache file
- }
- g_strfreev(line);
- }//for
-
-
- delete_lines_from_scrobble_log(&lines_to_remove, &lines_to_retry, queuepath);
-
- if (lines_to_remove != NULL) {
- g_slist_free_full(lines_to_remove, g_free);
- }
- if (lines_to_retry != NULL) {
- g_slist_free_full(lines_to_retry, g_free);
- }
-
- g_strfreev(lines);
- }
-
- g_free(contents);
- g_free(queuepath);
-}
-
-
-static void send_now_playing() {
-
- gchar *error_code = NULL;
- gchar *error_detail = NULL;
- bool_t ignored = FALSE;
- gchar *ignored_code = NULL;
- /*
- * now_playing_track can be set to something else while we this method is
- * running. Creating a local variable avoids to get data for different tracks,
- * while now_playing_track was updated concurrently.
- */
- Tuple *curr_track = now_playing_track;
-
- char *artist = clean_string(tuple_get_str(curr_track, FIELD_ARTIST));
- char *title = clean_string(tuple_get_str(curr_track, FIELD_TITLE));
- char *album = clean_string(tuple_get_str(curr_track, FIELD_ALBUM));
-
- int track = tuple_get_int(curr_track, FIELD_TRACK_NUMBER);
- int length = tuple_get_int(curr_track, FIELD_LENGTH);
-
- tuple_unref(curr_track);
-
- if (artist[0] && title[0] && length > 0) {
- char *track_str = (track > 0) ? int_to_str(track) : str_get("");
- char *length_str = int_to_str(length / 1000);
-
- gchar *playingmsg = create_message_to_lastfm("track.updateNowPlaying",
- 7,
- "artist", artist,
- "album", album,
- "track", title,
- "trackNumber", track_str,
- "duration", length_str,
- "api_key", SCROBBLER_API_KEY,
- "sk", session_key);
-
- bool_t success = send_message_to_lastfm(playingmsg);
- g_free(playingmsg);
-
- str_unref(track_str);
- str_unref(length_str);
-
- if (success == FALSE) {
- AUDDBG("Network problems. Could not send \"now playing\" to last.fm\n");
- scrobbling_enabled = FALSE;
- } else if (read_scrobble_result(&error_code, &error_detail, &ignored, &ignored_code) == TRUE) {
- //see scrobble_cached_queue()
- AUDDBG("NOW PLAYING OK.\n");
- } else {
- AUDDBG("NOW PLAYING NOT OK. Error code: %s. Error detail: %s.\n", error_code, error_detail);
- //From the API: Now Playing requests that fail should not be retried.
-
- if (g_strcmp0(error_code, "9") == 0) {
- //Bad Session. Reauth.
- //We don't really care about any other errors.
- scrobbling_enabled = FALSE;
- str_unref(session_key);
- session_key = NULL;
- aud_set_str("scrobbler", "session_key", "");
- }
-
- }
- //We don't care if the now playing was not accepted, no need to read the result from the server.
-
- }
-
- str_unref(artist);
- str_unref(title);
- str_unref(album);
-
- str_unref(error_code);
- str_unref(error_detail);
- str_unref(ignored_code);
-}
-
-static void treat_permission_check_request() {
- if (!session_key || !session_key[0]) {
- perm_result = PERMISSION_DENIED;
-
- if (!request_token || !request_token[0]) {
- if (scrobbler_request_token() == FALSE || !request_token || !request_token[0]) {
- perm_result = PERMISSION_NONET;
- } //else PERMISSION_DENIED
-
- } else if (scrobbler_request_session() == FALSE) {
- perm_result = PERMISSION_NONET;
-
- } else if (!session_key || !session_key[0]) {
- //This means we had a token, a session was requested now,
- //but the token was not accepted or expired.
- //Ask for a new token now.
- if (scrobbler_request_token() == FALSE || !request_token || !request_token[0]) {
- perm_result = PERMISSION_NONET;
- } //else PERMISSION_DENIED
- }
- }
- if (session_key && session_key[0]) {
- if (scrobbler_test_connection() == FALSE) {
- perm_result = PERMISSION_NONET;
-
- if (!session_key || !session_key[0]) {
- if (scrobbler_request_token() != FALSE && request_token && request_token[0]) {
- perm_result = PERMISSION_DENIED;
- } //else PERMISSION_NONET
- }
-
- } else {
- if (scrobbling_enabled) {
- perm_result = PERMISSION_ALLOWED;
- } else {
- /* This means that we have a session key but couldn't make
- * an authenticated call with it. This happens when:
- * a) the user revoked the permission to Audacious on his
- * last.fm account OR
- * b) something might be wrong on last.fm's side (?) OR
- * c) the user fiddled with the audacious config file and
- * the key is now invalid
- */
- if (scrobbler_request_token() != FALSE && request_token && request_token[0]) {
- perm_result = PERMISSION_DENIED;
- } else {
- perm_result = PERMISSION_NONET;
- }
- }
- }
- } //session_key == NULL || strlen(session_key) == 0
-}
-
-// This is a sister function of scrobbler_request_session, using the getMobileSession
-//API call, for migrating from the old config
-//returns:
-// FALSE if there was a network problem OR a session_key was not obtained
-// TRUE if a new session_key was obtained
-static bool_t treat_migrate_config() {
-
- char *password = aud_get_str("audioscrobbler","password");
- if (!password[0]) {
- str_unref(password);
- return FALSE;
- }
-
- char *username = aud_get_str("audioscrobbler","username");
- if (!username[0]) {
- str_unref(password);
- str_unref(username);
- return FALSE;
- }
-
- gchar *checksumThis = g_strdup_printf("%s%s", username, password);
- gchar *authToken = g_compute_checksum_for_string(G_CHECKSUM_MD5, checksumThis, -1);
-
- gchar *sessionmsg = create_message_to_lastfm("auth.getMobileSession",
- 3,
- "authToken", authToken,
- "username", username,
- "api_key", SCROBBLER_API_KEY);
- str_unref(username);
- str_unref(password);
- g_free(checksumThis);
- g_free(authToken);
-
- if (send_message_to_lastfm(sessionmsg) == FALSE) {
- g_free(sessionmsg);
- return FALSE;
- }
-
- g_free(sessionmsg);
-
- if (!update_session_key())
- return FALSE;
-
- return (session_key && session_key[0]);
-}
-
-
-//Scrobbling will only be enabled after the first connection test passed
-gpointer scrobbling_thread (gpointer input_data) {
-
- while (scrobbler_running) {
-
- if (migrate_config_requested) {
- if (treat_migrate_config() == FALSE) {
- aud_interface_show_error(_("Audacious is now using an improved version of the Last.fm Scrobbler.\nPlease check the Preferences for the Scrobbler plugin."));
- }
- aud_set_str("scrobbler", "migrated", "true");
- migrate_config_requested = FALSE;
-
- } else if (permission_check_requested) {
- treat_permission_check_request();
- permission_check_requested = FALSE;
-
- } else if (invalidate_session_requested) {
- str_unref(session_key);
- session_key = NULL;
- aud_set_str("scrobbler", "session_key", "");
- invalidate_session_requested = FALSE;
-
- } else if (now_playing_requested) {
- if (scrobbling_enabled) {
- send_now_playing();
- }
- now_playing_requested = FALSE;
-
- } else {
- if (scrobbling_enabled) {
- scrobble_cached_queue();
- }
- //scrobbling may be disabled at this point if communication errors occur
-
- pthread_mutex_lock(&communication_mutex);
- if (scrobbling_enabled) {
- pthread_cond_wait(&communication_signal, &communication_mutex);
- pthread_mutex_unlock(&communication_mutex);
- }
- else {
- //We don't want to wait until receiving a signal to retry
- //if submitting the cache failed due to network problems
- pthread_mutex_unlock(&communication_mutex);
-
- if (scrobbler_test_connection() == FALSE || !scrobbling_enabled) {
- struct timeval curtime;
- struct timespec timeout;
- pthread_mutex_lock(&communication_mutex);
- gettimeofday(&curtime, NULL);
- timeout.tv_sec = curtime.tv_sec + 7;
- timeout.tv_nsec = curtime.tv_usec * 1000;
- pthread_cond_timedwait(&communication_signal, &communication_mutex, &timeout);
- pthread_mutex_unlock(&communication_mutex);
- }
- }
- }
- }//while(scrobbler_running)
-
- //reset all vars to their initial values
- g_free(received_data);
- received_data = NULL;
- received_data_size = 0;
-
- curl_easy_cleanup(curlHandle);
- curlHandle = NULL;
-
- scrobbling_enabled = TRUE;
- return NULL;
-}
-
diff --git a/src/scrobbler2/scrobbler_communication.cc b/src/scrobbler2/scrobbler_communication.cc
new file mode 100644
index 000000000000..4e4d54903db3
--- /dev/null
+++ b/src/scrobbler2/scrobbler_communication.cc
@@ -0,0 +1,703 @@
+
+//external includes
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <curl/curl.h>
+
+#include <glib.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/interface.h>
+
+//plugin includes
+#include "scrobbler.h"
+
+typedef struct {
+ String paramName;
+ String argument;
+} API_Parameter;
+
+static CURL *curlHandle = nullptr; //global handle holding cURL options
+
+gboolean scrobbling_enabled = TRUE;
+
+//shared variables
+char *received_data = nullptr; //Holds the result of the last request made to last.fm
+size_t received_data_size = 0; //Holds the size of the received_data buffer
+
+
+
+// The cURL callback function to store the received data from the last.fm servers.
+static size_t result_callback (void *buffer, size_t size, size_t nmemb, void *userp) {
+
+ const size_t len = size*nmemb;
+
+ char *temp_data = g_renew(char, received_data, received_data_size + len + 1);
+
+ if (temp_data == nullptr) {
+ return 0;
+ } else {
+ received_data = temp_data;
+ }
+
+ memcpy(received_data + received_data_size, buffer, len);
+
+ received_data_size += len;
+
+ return len;
+}
+
+static int param_compare (const API_Parameter & a, const API_Parameter & b, void *)
+{
+ return g_strcmp0 (a.paramName, b.paramName);
+}
+
+static char * scrobbler_get_signature (Index<API_Parameter> & params)
+{
+ params.sort (param_compare, nullptr);
+
+ StringBuf buf (0);
+
+ for (const API_Parameter & param : params)
+ {
+ buf.insert (-1, param.paramName);
+ buf.insert (-1, param.argument);
+ }
+
+ buf.insert (-1, SCROBBLER_SHARED_SECRET);
+
+ return g_compute_checksum_for_string (G_CHECKSUM_MD5, buf, -1);
+}
+
+/*
+ * n_args should count with the given authentication parameters
+ * At most 2: api_key, session_key.
+ * api_sig (checksum) is always included, be it necessary or not
+ * Example usage:
+ * create_message_to_lastfm("track.scrobble", 5
+ * "artist", "Artist Name", "track", "Track Name", "timestamp", time(nullptr),
+ * "api_key", SCROBBLER_API_KEY, "sk", session_key);
+ *
+ * Returns nullptr if an error occurrs
+ */
+static String create_message_to_lastfm (const char * method_name, int n_args, ...)
+{
+ Index<API_Parameter> params;
+ params.append (String ("method"), String (method_name));
+
+ StringBuf buf = str_concat ({"method=", method_name});
+
+ va_list vl;
+ va_start (vl, n_args);
+
+ for (int i = 0; i < n_args; i ++)
+ {
+ const char * name = va_arg (vl, const char *);
+ const char * arg = va_arg (vl, const char *);
+
+ params.append (String (name), String (arg));
+
+ char * esc = curl_easy_escape (curlHandle, arg, 0);
+ buf.insert (-1, "&");
+ buf.insert (-1, name);
+ buf.insert (-1, "=");
+ buf.insert (-1, esc);
+ curl_free (esc);
+ }
+
+ va_end (vl);
+
+ char * api_sig = scrobbler_get_signature (params);
+ buf.insert (-1, "&api_sig=");
+ buf.insert (-1, api_sig);
+ g_free (api_sig);
+
+ AUDDBG ("FINAL message: %s.\n", (const char *) buf);
+
+ return String (buf);
+}
+
+static gboolean send_message_to_lastfm (const char * data)
+{
+ AUDDBG("This message will be sent to last.fm:\n%s\n%%%%End of message%%%%\n", data);//Enter?\n", data);
+ curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDS, data);
+ CURLcode curl_requests_result = curl_easy_perform(curlHandle);
+
+ if (curl_requests_result != CURLE_OK) {
+ AUDDBG("Could not communicate with last.fm: %s.\n", curl_easy_strerror(curl_requests_result));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+//returns:
+// FALSE if there was a network problem
+// TRUE otherwise (request_token must be checked)
+static gboolean scrobbler_request_token ()
+{
+ String tokenmsg = create_message_to_lastfm ("auth.getToken", 1, "api_key", SCROBBLER_API_KEY);
+
+ if (send_message_to_lastfm(tokenmsg) == FALSE) {
+ AUDDBG("Could not send token request to last.fm.\n");
+ return FALSE;
+ }
+
+ gboolean success = TRUE;
+ String error_code;
+ String error_detail;
+
+ if (read_token(error_code, error_detail) == FALSE) {
+ success = FALSE;
+ if (error_code != nullptr && g_strcmp0(error_code, "8")) {
+ //error code 8: There was an error granting the request token. Please try again later
+ request_token = String();
+ }
+ }
+
+ return success;
+}
+
+
+static gboolean update_session_key() {
+ gboolean result = TRUE;
+ String error_code;
+ String error_detail;
+
+ if (read_session_key(error_code, error_detail) == FALSE) {
+ if (error_code != nullptr && (
+ g_strcmp0(error_code, "4") == 0 || //invalid token
+ g_strcmp0(error_code, "14") == 0 || //token not authorized
+ g_strcmp0(error_code, "15") == 0 //token expired
+ )) {
+ AUDDBG("error code CAUGHT: %s\n", (const char *)error_code);
+ session_key = String();
+ result = TRUE;
+ } else {
+ result= FALSE;
+ }
+ }
+
+ aud_set_str("scrobbler", "session_key", session_key ? session_key : "");
+
+ return result;
+}
+
+//returns:
+// FALSE if there was a network problem
+// TRUE otherwise (session_key must be checked)
+static gboolean scrobbler_request_session ()
+{
+ String sessionmsg = create_message_to_lastfm ("auth.getSession", 2,
+ "token", (const char *) request_token, "api_key", SCROBBLER_API_KEY);
+
+ if (send_message_to_lastfm(sessionmsg) == FALSE)
+ return FALSE;
+
+ //the token can only be sent once
+ request_token = String();
+
+ return update_session_key();
+}
+
+//returns:
+// FALSE if there was a network problem.
+// TRUE otherwise (scrobbling_enabled must be checked)
+//sets scrobbling_enabled to TRUE if the session is OK
+//sets session_key to nullptr if it is invalid
+static gboolean scrobbler_test_connection() {
+
+ if (!session_key || !session_key[0]) {
+ scrobbling_enabled = FALSE;
+ return TRUE;
+ }
+
+ String testmsg = create_message_to_lastfm ("user.getRecommendedArtists", 3,
+ "limit", "1", "api_key", SCROBBLER_API_KEY,
+ "sk", (const char *) session_key);
+
+ gboolean success = send_message_to_lastfm(testmsg);
+
+ if (success == FALSE) {
+ AUDDBG("Network problems. Will not scrobble any tracks.\n");
+ scrobbling_enabled = FALSE;
+ if (permission_check_requested) {
+ perm_result = PERMISSION_NONET;
+ }
+ return FALSE;
+ }
+
+ String error_code;
+ String error_detail;
+
+ if (read_authentication_test_result(error_code, error_detail) == FALSE) {
+ AUDDBG("Error code: %s. Detail: %s.\n", (const char *)error_code,
+ (const char *)error_detail);
+ if (error_code != nullptr && (
+ g_strcmp0(error_code, "4") == 0 || //error code 4: Authentication Failed - You do not have permissions to access the service
+ g_strcmp0(error_code, "9") == 0 //error code 9: Invalid session key - Please re-authenticate
+ )) {
+ session_key = String();
+ aud_set_str("scrobbler", "session_key", "");
+ scrobbling_enabled = FALSE;
+ } else {
+ //network problem.
+ scrobbling_enabled = FALSE;
+ AUDDBG("Connection NOT OK. Scrobbling disabled\n");
+ success = FALSE;
+ }
+ } else {
+ //THIS IS THE ONLY PLACE WHERE SCROBBLING IS SET TO ENABLED IN RUN-TIME
+ scrobbling_enabled = TRUE;
+ AUDDBG("Connection OK. Scrobbling enabled.\n");
+ }
+
+ return success;
+}
+
+//called from scrobbler_init() @ scrobbler.c
+gboolean scrobbler_communication_init() {
+ CURLcode curl_requests_result = curl_global_init(CURL_GLOBAL_DEFAULT);
+ if (curl_requests_result != CURLE_OK) {
+ AUDDBG("Could not initialize libCURL: %s.\n", curl_easy_strerror(curl_requests_result));
+ return FALSE;
+ }
+
+ curlHandle = curl_easy_init();
+ if (curlHandle == nullptr) {
+ AUDDBG("Could not initialize libCURL.\n");
+ return FALSE;
+ }
+
+ curl_requests_result = curl_easy_setopt(curlHandle, CURLOPT_URL, SCROBBLER_URL);
+ if (curl_requests_result != CURLE_OK) {
+ AUDDBG("Could not define scrobbler destination URL: %s.\n", curl_easy_strerror(curl_requests_result));
+ return FALSE;
+ }
+
+ curl_requests_result = curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, result_callback);
+ if (curl_requests_result != CURLE_OK) {
+ AUDDBG("Could not register scrobbler callback function: %s.\n", curl_easy_strerror(curl_requests_result));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void set_timestamp_to_current(char **line) {
+ //line[0] line[1] line[2] line[3] line[4] line[5] line[6] line[7]
+ //artist album title number length "L" timestamp nullptr
+
+ char **splitted_line = g_strsplit(*line, "\t", 0);
+ g_free(splitted_line[6]);
+ splitted_line[6] = g_strdup_printf("%" G_GINT64_FORMAT, g_get_real_time() / G_USEC_PER_SEC);
+ AUDDBG("splitted line's timestamp is now: %s.\n", splitted_line[6]);
+ g_free(*line);
+ (*line) = g_strjoinv("\t", splitted_line);
+}
+
+static void delete_lines_from_scrobble_log (GSList **lines_to_remove_ptr, GSList **lines_to_retry_ptr, char *queuepath) {
+ GSList *lines_to_remove = *lines_to_remove_ptr;
+ GSList *lines_to_retry = *lines_to_retry_ptr;
+ char *contents = nullptr;
+ char **lines = nullptr;
+ char **finallines = g_new (char *, 1);
+ int n_finallines;
+
+ if (lines_to_remove != nullptr) {
+ lines_to_remove = g_slist_reverse(lines_to_remove);
+ }
+ if (lines_to_retry != nullptr) {
+ lines_to_retry = g_slist_reverse(lines_to_retry);
+ }
+
+
+ pthread_mutex_lock(&log_access_mutex);
+
+ gboolean success = g_file_get_contents(queuepath, &contents, nullptr, nullptr);
+ if (!success) {
+ AUDDBG("Could not read scrobbler.log contents.\n");
+ } else {
+ lines = g_strsplit(contents, "\n", 0);
+
+ n_finallines = 0;
+ for (int i = 0 ; lines[i] != nullptr && strlen(lines[i]) > 0; i++) {
+ if (lines_to_remove != nullptr && *((int *) (lines_to_remove->data)) == i) {
+ //this line is to remove
+ lines_to_remove = g_slist_next(lines_to_remove);
+ } else {
+ //keep this line
+ AUDDBG("Going to keep line %i\n", i);
+ if (lines_to_retry != nullptr && *((int *) (lines_to_retry->data)) == i) {
+ lines_to_retry = g_slist_next(lines_to_retry);
+ //this line will be retried with a zero timestamp
+ AUDDBG("Going to zero this line.\n");
+ AUDDBG("Line before: %s.\n", lines[i]);
+ set_timestamp_to_current(&(lines[i]));
+ AUDDBG("Line after: %s.\n", lines[i]);
+
+ } else {
+ AUDDBG("not zeroing this line\n");
+ }
+ n_finallines++;
+ finallines = g_renew (char *, finallines, n_finallines);
+ finallines[n_finallines-1] = g_strdup(lines[i]);
+ }
+ }
+
+ finallines = g_renew (char *, finallines, n_finallines + 2);
+ finallines[n_finallines] = g_strdup("");
+ finallines[n_finallines+1] = nullptr;
+ g_free(contents);
+ contents = g_strjoinv("\n", finallines);
+ success = g_file_set_contents(queuepath, contents, -1, nullptr);
+ if (!success) {
+ AUDDBG("Could not write to scrobbler.log!\n");
+ }
+
+ }
+
+ pthread_mutex_unlock(&log_access_mutex);
+
+
+ g_strfreev(finallines);
+ g_strfreev(lines);
+ g_free(contents);
+}
+
+static void save_line_to_remove(GSList **lines_to_remove, int linenumber) {
+ int *rem = g_new (int, 1);
+ *rem = linenumber;
+ (*lines_to_remove) = g_slist_prepend((*lines_to_remove), rem);
+}
+
+static void scrobble_cached_queue() {
+
+ char *queuepath = g_build_filename(aud_get_path(AudPath::UserDir),"scrobbler.log", nullptr);
+ char *contents = nullptr;
+ gboolean success;
+ char **lines = nullptr;
+ char **line;
+ GSList *lines_to_remove = nullptr; //lines to remove because they were scrobbled (or ignored, and will not be retried)
+ GSList *lines_to_retry = nullptr; //lines to retry later because they were too old TODO: or "daily scrobble limit reached"
+
+ pthread_mutex_lock(&log_access_mutex);
+ success = g_file_get_contents(queuepath, &contents, nullptr, nullptr);
+ pthread_mutex_unlock(&log_access_mutex);
+ if (!success) {
+ AUDDBG("Couldn't access the queue file.\n");
+ } else {
+
+ lines = g_strsplit(contents, "\n", 0);
+
+ for (int i = 0; lines[i] != nullptr && strlen(lines[i]) > 0 && scrobbling_enabled; i++) {
+ line = g_strsplit(lines[i], "\t", 0);
+
+ //line[0] line[1] line[2] line[3] line[4] line[5] line[6] line[7]
+ //artist album title number length "L" timestamp nullptr
+
+ if (line[0] && line[2] && (strcmp(line[5], "L") == 0) && line[6] && (line[7] == nullptr))
+ {
+ String scrobblemsg = create_message_to_lastfm ("track.scrobble",
+ 8, "artist", line[0], "album", line[1], "track", line[2],
+ "trackNumber", line[3], "duration", line[4],
+ "timestamp", line[6], "api_key", SCROBBLER_API_KEY,
+ "sk", (const char *) session_key);
+
+ if (send_message_to_lastfm(scrobblemsg) == TRUE) {
+ String error_code;
+ String error_detail;
+ gboolean ignored = FALSE;
+ String ignored_code;
+
+ if (read_scrobble_result(error_code, error_detail, &ignored, ignored_code) == TRUE) {
+ AUDDBG("SCROBBLE OK. Error code: %s. Error detail: %s\n",
+ (const char *)error_code, (const char *)error_detail);
+ AUDDBG("SCROBBLE OK. ignored: %i.\n", ignored);
+ AUDDBG("SCROBBLE OK. ignored code: %s.\n",
+ (const char *)ignored_code);
+ if (ignored == TRUE && g_strcmp0(ignored_code, "3") == 0) { //3: Timestamp was too old
+ AUDDBG("SCROBBLE IGNORED!!! %i, detail: %s\n",
+ ignored, (const char *)ignored_code);
+ save_line_to_remove(&lines_to_retry, i);
+ } else if (ignored == TRUE && g_strcmp0(ignored_code, "") == 0) { //5: Daily scrobble limit reached
+ //TODO: a track might not be scrobbled due to "daily scrobble limit exeeded".
+ //This message comes on the ignoredMessage attribute, inside the XML of the response.
+ //We are not dealing with this case currently and are losing that scrobble.
+ //TODO
+
+ } else {
+ AUDDBG("Not ignored. Carrying on...\n");
+ save_line_to_remove(&lines_to_remove, i);
+ }
+ } else {
+ AUDDBG("SCROBBLE NOT OK. Error code: %s. Error detail: %s.\n",
+ (const char *)error_code, (const char *)error_detail);
+
+ if (! error_code) { //net error(?) or the answer from last.fm was not well read
+ //scrobble to be retried
+ }
+ else if (g_strcmp0(error_code, "11") == 0 ||
+ g_strcmp0(error_code, "16") == 0){
+ //error code 11: Service Offline - This service is temporarily offline. Try again later.
+ //error code 16: The service is temporarily unavailable, please try again.
+ //scrobble to be retried
+ }
+ else if (g_strcmp0(error_code, "9") == 0) {
+ //Bad Session. Reauth.
+ scrobbling_enabled = FALSE;
+ session_key = String();
+ aud_set_str("scrobbler", "session_key", "");
+ }
+ else {
+ save_line_to_remove(&lines_to_remove, i);
+ }
+ }
+ } else {
+ AUDDBG("Could not scrobble a track on the queue. Network problem?\n");
+ //scrobble to be retried
+ scrobbling_enabled = FALSE;
+ }
+
+ //TODO: Avoid spamming last.fm --- It's not as simple as just adding a wait here:
+ //If audacious is closed while we're on this loop, tracks might be re-scrobbled.
+ //This shall be doable if we only pick one track at a time from the scrobbler.log
+ } else {
+ AUDDBG("Unscrobbable line.\n");
+ //leave entry on the cache file
+ }
+ g_strfreev(line);
+ }//for
+
+
+ delete_lines_from_scrobble_log(&lines_to_remove, &lines_to_retry, queuepath);
+
+ if (lines_to_remove != nullptr) {
+ g_slist_free_full(lines_to_remove, g_free);
+ }
+ if (lines_to_retry != nullptr) {
+ g_slist_free_full(lines_to_retry, g_free);
+ }
+
+ g_strfreev(lines);
+ }
+
+ g_free(contents);
+ g_free(queuepath);
+}
+
+
+static void send_now_playing() {
+
+ String error_code;
+ String error_detail;
+ gboolean ignored = FALSE;
+ String ignored_code;
+ /*
+ * now_playing_track can be set to something else while we this method is
+ * running. Creating a local variable avoids to get data for different tracks,
+ * while now_playing_track was updated concurrently.
+ *
+ * FIXME: Make this actually thread-safe.
+ */
+ Tuple curr_track = now_playing_track.ref ();
+
+ StringBuf artist = clean_string (curr_track.get_str (Tuple::Artist));
+ StringBuf title = clean_string (curr_track.get_str (Tuple::Title));
+ StringBuf album = clean_string (curr_track.get_str (Tuple::Album));
+
+ int track = curr_track.get_int (Tuple::Track);
+ int length = curr_track.get_int (Tuple::Length);
+
+ if (artist[0] && title[0] && length > 0) {
+ StringBuf track_str = (track > 0) ? int_to_str (track) : StringBuf (0);
+ StringBuf length_str = int_to_str (length / 1000);
+
+ String playingmsg = create_message_to_lastfm ("track.updateNowPlaying", 7,
+ "artist", (const char *) artist, "album", (const char *) album,
+ "track", (const char *) title, "trackNumber", (const char *) track_str,
+ "duration", (const char *) length_str, "api_key", SCROBBLER_API_KEY,
+ "sk", (const char *) session_key);
+
+ gboolean success = send_message_to_lastfm(playingmsg);
+
+ if (success == FALSE) {
+ AUDDBG("Network problems. Could not send \"now playing\" to last.fm\n");
+ scrobbling_enabled = FALSE;
+ } else if (read_scrobble_result(error_code, error_detail, &ignored, ignored_code) == TRUE) {
+ //see scrobble_cached_queue()
+ AUDDBG("NOW PLAYING OK.\n");
+ } else {
+ AUDDBG("NOW PLAYING NOT OK. Error code: %s. Error detail: %s.\n",
+ (const char *)error_code, (const char *)error_detail);
+ //From the API: Now Playing requests that fail should not be retried.
+
+ if (g_strcmp0(error_code, "9") == 0) {
+ //Bad Session. Reauth.
+ //We don't really care about any other errors.
+ scrobbling_enabled = FALSE;
+ session_key = String();
+ aud_set_str("scrobbler", "session_key", "");
+ }
+
+ }
+ //We don't care if the now playing was not accepted, no need to read the result from the server.
+
+ }
+}
+
+static void treat_permission_check_request() {
+ if (!session_key || !session_key[0]) {
+ perm_result = PERMISSION_DENIED;
+
+ if (!request_token || !request_token[0]) {
+ if (scrobbler_request_token() == FALSE || !request_token || !request_token[0]) {
+ perm_result = PERMISSION_NONET;
+ } //else PERMISSION_DENIED
+
+ } else if (scrobbler_request_session() == FALSE) {
+ perm_result = PERMISSION_NONET;
+
+ } else if (!session_key || !session_key[0]) {
+ //This means we had a token, a session was requested now,
+ //but the token was not accepted or expired.
+ //Ask for a new token now.
+ if (scrobbler_request_token() == FALSE || !request_token || !request_token[0]) {
+ perm_result = PERMISSION_NONET;
+ } //else PERMISSION_DENIED
+ }
+ }
+ if (session_key && session_key[0]) {
+ if (scrobbler_test_connection() == FALSE) {
+ perm_result = PERMISSION_NONET;
+
+ if (!session_key || !session_key[0]) {
+ if (scrobbler_request_token() != FALSE && request_token && request_token[0]) {
+ perm_result = PERMISSION_DENIED;
+ } //else PERMISSION_NONET
+ }
+
+ } else {
+ if (scrobbling_enabled) {
+ perm_result = PERMISSION_ALLOWED;
+ } else {
+ /* This means that we have a session key but couldn't make
+ * an authenticated call with it. This happens when:
+ * a) the user revoked the permission to Audacious on his
+ * last.fm account OR
+ * b) something might be wrong on last.fm's side (?) OR
+ * c) the user fiddled with the audacious config file and
+ * the key is now invalid
+ */
+ if (scrobbler_request_token() != FALSE && request_token && request_token[0]) {
+ perm_result = PERMISSION_DENIED;
+ } else {
+ perm_result = PERMISSION_NONET;
+ }
+ }
+ }
+ } //session_key == nullptr || strlen(session_key) == 0
+}
+
+// This is a sister function of scrobbler_request_session, using the getMobileSession
+//API call, for migrating from the old config
+//returns:
+// FALSE if there was a network problem OR a session_key was not obtained
+// TRUE if a new session_key was obtained
+static gboolean treat_migrate_config() {
+
+ String password = aud_get_str("audioscrobbler","password");
+ String username = aud_get_str("audioscrobbler","username");
+ if (!password[0] || !username[0])
+ return FALSE;
+
+ char *checksumThis = g_strdup_printf("%s%s", (const char *)username, (const char *)password);
+ char *authToken = g_compute_checksum_for_string(G_CHECKSUM_MD5, checksumThis, -1);
+
+ String sessionmsg = create_message_to_lastfm ("auth.getMobileSession", 3,
+ "authToken", authToken, "username", (const char *) username,
+ "api_key", SCROBBLER_API_KEY);
+
+ g_free(checksumThis);
+ g_free(authToken);
+
+ if (send_message_to_lastfm(sessionmsg) == FALSE)
+ return FALSE;
+
+ if (!update_session_key())
+ return FALSE;
+
+ return (session_key && session_key[0]);
+}
+
+
+//Scrobbling will only be enabled after the first connection test passed
+void * scrobbling_thread (void * input_data) {
+
+ while (scrobbler_running) {
+
+ if (migrate_config_requested) {
+ if (treat_migrate_config() == FALSE) {
+ aud_ui_show_error(_("Audacious is now using an improved version of the Last.fm Scrobbler.\nPlease check the Preferences for the Scrobbler plugin."));
+ }
+ aud_set_str("scrobbler", "migrated", "true");
+ migrate_config_requested = FALSE;
+
+ } else if (permission_check_requested) {
+ treat_permission_check_request();
+ permission_check_requested = FALSE;
+
+ } else if (invalidate_session_requested) {
+ session_key = String();
+ aud_set_str("scrobbler", "session_key", "");
+ invalidate_session_requested = FALSE;
+
+ } else if (now_playing_requested) {
+ if (scrobbling_enabled) {
+ send_now_playing();
+ }
+ now_playing_requested = FALSE;
+
+ } else {
+ if (scrobbling_enabled) {
+ scrobble_cached_queue();
+ }
+ //scrobbling may be disabled at this point if communication errors occur
+
+ pthread_mutex_lock(&communication_mutex);
+ if (scrobbling_enabled) {
+ pthread_cond_wait(&communication_signal, &communication_mutex);
+ pthread_mutex_unlock(&communication_mutex);
+ }
+ else {
+ //We don't want to wait until receiving a signal to retry
+ //if submitting the cache failed due to network problems
+ pthread_mutex_unlock(&communication_mutex);
+
+ if (scrobbler_test_connection() == FALSE || !scrobbling_enabled) {
+ struct timeval curtime;
+ struct timespec timeout;
+ pthread_mutex_lock(&communication_mutex);
+ gettimeofday(&curtime, nullptr);
+ timeout.tv_sec = curtime.tv_sec + 7;
+ timeout.tv_nsec = curtime.tv_usec * 1000;
+ pthread_cond_timedwait(&communication_signal, &communication_mutex, &timeout);
+ pthread_mutex_unlock(&communication_mutex);
+ }
+ }
+ }
+ }//while(scrobbler_running)
+
+ //reset all vars to their initial values
+ g_free(received_data);
+ received_data = nullptr;
+ received_data_size = 0;
+
+ curl_easy_cleanup(curlHandle);
+ curlHandle = nullptr;
+
+ scrobbling_enabled = TRUE;
+ return nullptr;
+}
+
diff --git a/src/scrobbler2/scrobbler_xml_parsing.c b/src/scrobbler2/scrobbler_xml_parsing.c
deleted file mode 100644
index 750676dbf3e9..000000000000
--- a/src/scrobbler2/scrobbler_xml_parsing.c
+++ /dev/null
@@ -1,322 +0,0 @@
-
-//plugin includes
-#include "scrobbler.h"
-
-//static (private) variables
-static xmlDocPtr doc = NULL;
-static xmlXPathContextPtr context = NULL;
-
-static bool_t prepare_data () {
- received_data[received_data_size] = '\0';
- AUDDBG("Data received from last.fm:\n%s\n%%%%End of data%%%%\n", received_data);
-
- doc = xmlParseMemory(received_data, received_data_size+1);
- received_data_size = 0;
- if (doc == NULL) {
- AUDDBG("Document not parsed successfully.\n");
- return FALSE;
- }
-
- context = xmlXPathNewContext(doc);
- if (context == NULL) {
- AUDDBG("Error in xmlXPathNewContext\n");
- xmlFreeDoc(doc);
- doc = NULL;
- return FALSE;
- }
- return TRUE;
-}
-
-static void clean_data() {
- xmlXPathFreeContext(context);
- xmlFreeDoc(doc);
- context = NULL;
- doc = NULL;
-}
-
-
-//returns:
-// NULL if an error occurs or the attribute was not found
-// the attribute's value if it was found
-static char *get_attribute_value (const char *node_expression, const char *attribute) {
- if (doc == NULL || context == NULL) {
- AUDDBG("Response from last.fm not parsed successfully. Did you call prepare_data?\n");
- return NULL;
- }
-
- xmlXPathObjectPtr statusObj = xmlXPathEvalExpression((xmlChar *) node_expression, context);
- if (statusObj == NULL) {
- AUDDBG ("Error in xmlXPathEvalExpression.\n");
- return NULL;
- }
- if (xmlXPathNodeSetIsEmpty(statusObj->nodesetval)) {
- AUDDBG("No result.\n");
- xmlXPathFreeObject(statusObj);
- return NULL;
- }
-
- xmlChar *prop = xmlGetProp(statusObj->nodesetval->nodeTab[0], (xmlChar *) attribute);
-
- char *result = NULL;
- if (prop && prop[0])
- result = str_get((char *) prop);
-
- xmlXPathFreeObject(statusObj);
- xmlFree(prop);
-
- AUDDBG("RESULT FOR THIS FUNCTION: %s.\n", result);
- return result;
-}
-
-//returns:
-// NULL if an error occurs or the node was not found
-static char *get_node_string (const char *node_expression) {
- if (doc == NULL || context == NULL) {
- AUDDBG("Response from last.fm not parsed successfully. Did you call prepare_data?\n");
- return NULL;
- }
-
- xmlXPathObjectPtr statusObj = xmlXPathEvalExpression((xmlChar *) node_expression, context);
- if (statusObj == NULL) {
- AUDDBG ("Error in xmlXPathEvalExpression.\n");
- return NULL;
- }
- if (xmlXPathNodeSetIsEmpty(statusObj->nodesetval)) {
- AUDDBG("No result.\n");
- xmlXPathFreeObject(statusObj);
- return NULL;
- }
-
- xmlChar *string = xmlNodeListGetString(doc, statusObj->nodesetval->nodeTab[0]->children, 1);
-
- char *result = NULL;
- if (string && string[0])
- result = str_get((char *) string);
-
- xmlXPathFreeObject(statusObj);
- xmlFree(string);
-
- AUDDBG("RESULT FOR THIS FUNCTION: %s.\n", result);
- return result;
-}
-
-
-//returns:
-// NULL if an error occurs
-// "true" if the the command succeeded
-// "false" if an error occurred. error_code and error_detail should be checked in this case
-static char *check_status (char **error_code, char **error_detail) {
- (*error_code) = NULL;
- (*error_detail) = NULL;
-
- char *status = get_attribute_value("/lfm[@status]", "status");
- if (!status) {
- AUDDBG("last.fm not answering according to the API.\n");
- return NULL;
- }
-
- AUDDBG ("status is %s.\n", status);
- if (strcmp(status, "ok")) {
-
- (*error_code) = get_attribute_value("/lfm/error[@code]", "code");
- if (!(*error_code)) {
- AUDDBG("Weird API answer. Last.fm says status is %s but there is no error code?\n", status);
- str_unref(status);
- status = NULL;
- } else {
- (*error_detail) = get_node_string("/lfm/error");
- }
- }
-
- AUDDBG("check_status results: return: %s. error_code: %s. error_detail: %s.\n", status, (*error_code), (*error_detail));
- return status;
-}
-
-/*
- * Returns:
- * * TRUE if the scrobble was successful
- * * with ignored = TRUE if it was ignored
- * * ignored_code_out must be checked
- * * with ignored = FALSE if it was scrobbled OK
- * * FALSE if the scrobble was unsuccessful
- * * error_code_out and error_detail_out must be checked:
- * * They are NULL if an API communication error occur
- */
-bool_t read_scrobble_result(char **error_code, char **error_detail, bool_t *ignored, char **ignored_code) {
-
- *error_code = NULL;
- *error_detail = NULL;
- *ignored = FALSE;
- *ignored_code = NULL;
-
- bool_t result = TRUE;
-
- if (!prepare_data()) {
- AUDDBG("Could not read received data from last.fm. What's up?\n");
- return FALSE;
- }
-
- char *status = check_status(error_code, error_detail);
-
- if (!status) {
- AUDDBG("Status was NULL. Invalid API answer.\n");
- clean_data();
- return FALSE;
- }
-
- if (!strcmp(status, "failed")) {
- AUDDBG("Error code: %s. Detail: %s.\n", *error_code, *error_detail);
- result = FALSE;
-
- } else {
- //TODO: We are assuming that only one track is scrobbled per request! This will have to be
- //re-done to support multiple tracks being scrobbled in batch
- char *ignored_scrobble = get_attribute_value("/lfm/scrobbles[@ignored]", "ignored");
-
- if (ignored_scrobble && strcmp(ignored_scrobble, "0")) {
- //The track was ignored
- //TODO: this assumes ignored_scrobble == 1!!!
- *ignored = TRUE;
- *ignored_code = get_attribute_value("/lfm/scrobbles/scrobble/ignoredMessage[@code]", "code");
- }
-
- str_unref(ignored_scrobble);
-
- AUDDBG("ignored? %i, ignored_code: %s\n", *ignored, *ignored_code);
- }
-
- str_unref(status);
-
- clean_data();
- return result;
-}
-
-//returns
-//FALSE if there was an error with the connection
-bool_t read_authentication_test_result (char **error_code, char **error_detail) {
-
- *error_code = NULL;
- *error_detail = NULL;
-
- bool_t result = TRUE;
-
- if (!prepare_data()) {
- AUDDBG("Could not read received data from last.fm. What's up?\n");
- return FALSE;
- }
-
- char *status = check_status(error_code, error_detail);
-
- if (!status) {
- AUDDBG("Status was NULL. Invalid API answer.\n");
- clean_data();
- return FALSE;
- }
-
- if (!strcmp(status, "failed")) {
- result = FALSE;
-
- } else {
- str_unref(username);
- username = get_attribute_value("/lfm/recommendations[@user]", "user");
- if (!username) {
- AUDDBG("last.fm not answering according to the API.\n");
- result = FALSE;
- }
- }
-
- str_unref(status);
-
- clean_data();
- return result;
-}
-
-
-
-bool_t read_token (char **error_code, char **error_detail) {
-
- *error_code = NULL;
- *error_detail = NULL;
-
- bool_t result = TRUE;
-
- if (!prepare_data()) {
- AUDDBG("Could not read received data from last.fm. What's up?\n");
- return FALSE;
- }
-
- char *status = check_status(error_code, error_detail);
-
- if (!status) {
- AUDDBG("Status was NULL. Invalid API answer.\n");
- clean_data();
- return FALSE;
- }
-
- if (!strcmp(status, "failed")) {
- AUDDBG("Error code: %s. Detail: %s.\n", *error_code, *error_detail);
- result = FALSE;
- }
- else {
- str_unref(request_token);
- request_token = get_node_string("/lfm/token");
-
- if (!request_token || !request_token[0]) {
- AUDDBG("Could not read the received token. Something's wrong with the API?\n");
- result = FALSE;
- }
- else {
- AUDDBG("This is the token: %s.\nNice? Nice.\n", request_token);
- }
- }
-
- str_unref(status);
-
- clean_data();
- return result;
-}
-
-
-
-bool_t read_session_key(char **error_code, char **error_detail) {
-
- *error_code = NULL;
- *error_detail = NULL;
-
- bool_t result = TRUE;
-
- if (!prepare_data()) {
- AUDDBG("Could not read received data from last.fm. What's up?\n");
- return FALSE;
- }
-
- char *status = check_status(error_code, error_detail);
-
- if (!status) {
- AUDDBG("Status was NULL or empty. Invalid API answer.\n");
- clean_data();
- return FALSE;
- }
-
- if (!strcmp(status, "failed")) {
- AUDDBG("Error code: %s. Detail: %s.\n", *error_code, *error_detail);
- result = FALSE;
-
- } else {
- str_unref(session_key);
- session_key = get_node_string("/lfm/session/key");
-
- if (!session_key || !session_key[0]) {
- AUDDBG("Could not read the received session key. Something's wrong with the API?\n");
- result = FALSE;
- } else {
- AUDDBG("This is the session key: %s.\n", session_key);
- }
- }
-
- str_unref(status);
-
- clean_data();
- return result;
-}
-
diff --git a/src/scrobbler2/scrobbler_xml_parsing.cc b/src/scrobbler2/scrobbler_xml_parsing.cc
new file mode 100644
index 000000000000..b1ea05b2b9a2
--- /dev/null
+++ b/src/scrobbler2/scrobbler_xml_parsing.cc
@@ -0,0 +1,300 @@
+
+//plugin includes
+#include "scrobbler.h"
+
+//static (private) variables
+static xmlDocPtr doc = nullptr;
+static xmlXPathContextPtr context = nullptr;
+
+static gboolean prepare_data () {
+ received_data[received_data_size] = '\0';
+ AUDDBG("Data received from last.fm:\n%s\n%%%%End of data%%%%\n", received_data);
+
+ doc = xmlParseMemory(received_data, received_data_size+1);
+ received_data_size = 0;
+ if (doc == nullptr) {
+ AUDDBG("Document not parsed successfully.\n");
+ return FALSE;
+ }
+
+ context = xmlXPathNewContext(doc);
+ if (context == nullptr) {
+ AUDDBG("Error in xmlXPathNewContext\n");
+ xmlFreeDoc(doc);
+ doc = nullptr;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void clean_data() {
+ xmlXPathFreeContext(context);
+ xmlFreeDoc(doc);
+ context = nullptr;
+ doc = nullptr;
+}
+
+
+//returns:
+// nullptr if an error occurs or the attribute was not found
+// the attribute's value if it was found
+static String get_attribute_value (const char *node_expression, const char *attribute) {
+ if (doc == nullptr || context == nullptr) {
+ AUDDBG("Response from last.fm not parsed successfully. Did you call prepare_data?\n");
+ return String();
+ }
+
+ xmlXPathObjectPtr statusObj = xmlXPathEvalExpression((xmlChar *) node_expression, context);
+ if (statusObj == nullptr) {
+ AUDDBG ("Error in xmlXPathEvalExpression.\n");
+ return String();
+ }
+ if (xmlXPathNodeSetIsEmpty(statusObj->nodesetval)) {
+ AUDDBG("No result.\n");
+ xmlXPathFreeObject(statusObj);
+ return String();
+ }
+
+ xmlChar *prop = xmlGetProp(statusObj->nodesetval->nodeTab[0], (xmlChar *) attribute);
+
+ String result;
+ if (prop && prop[0])
+ result = String((const char *)prop);
+
+ xmlXPathFreeObject(statusObj);
+ xmlFree(prop);
+
+ AUDDBG("RESULT FOR THIS FUNCTION: %s.\n", (const char *)result);
+ return result;
+}
+
+//returns:
+// nullptr if an error occurs or the node was not found
+static String get_node_string (const char *node_expression) {
+ if (doc == nullptr || context == nullptr) {
+ AUDDBG("Response from last.fm not parsed successfully. Did you call prepare_data?\n");
+ return String();
+ }
+
+ xmlXPathObjectPtr statusObj = xmlXPathEvalExpression((xmlChar *) node_expression, context);
+ if (statusObj == nullptr) {
+ AUDDBG ("Error in xmlXPathEvalExpression.\n");
+ return String();
+ }
+ if (xmlXPathNodeSetIsEmpty(statusObj->nodesetval)) {
+ AUDDBG("No result.\n");
+ xmlXPathFreeObject(statusObj);
+ return String();
+ }
+
+ xmlChar *string = xmlNodeListGetString(doc, statusObj->nodesetval->nodeTab[0]->children, 1);
+
+ String result;
+ if (string && string[0])
+ result = String((const char *) string);
+
+ xmlXPathFreeObject(statusObj);
+ xmlFree(string);
+
+ AUDDBG("RESULT FOR THIS FUNCTION: %s.\n", (const char *)result);
+ return result;
+}
+
+
+//returns:
+// nullptr if an error occurs
+// "true" if the the command succeeded
+// "false" if an error occurred. error_code and error_detail should be checked in this case
+static String check_status (String &error_code, String &error_detail) {
+
+ String status = get_attribute_value("/lfm[@status]", "status");
+ if (!status) {
+ AUDDBG("last.fm not answering according to the API.\n");
+ return String();
+ }
+
+ AUDDBG ("status is %s.\n", (const char *)status);
+ if (strcmp(status, "ok")) {
+
+ error_code = get_attribute_value("/lfm/error[@code]", "code");
+ if (!(*error_code)) {
+ AUDDBG("Weird API answer. Last.fm says status is %s but there is no error code?\n",
+ (const char *)status);
+ status = String();
+ } else {
+ error_detail = get_node_string("/lfm/error");
+ }
+ }
+
+ AUDDBG("check_status results: return: %s. error_code: %s. error_detail: %s.\n",
+ (const char *)status, (const char *)error_code, (const char *)error_detail);
+ return status;
+}
+
+/*
+ * Returns:
+ * * TRUE if the scrobble was successful
+ * * with ignored = TRUE if it was ignored
+ * * ignored_code_out must be checked
+ * * with ignored = FALSE if it was scrobbled OK
+ * * FALSE if the scrobble was unsuccessful
+ * * error_code_out and error_detail_out must be checked:
+ * * They are nullptr if an API communication error occur
+ */
+gboolean read_scrobble_result(String &error_code, String &error_detail,
+ gboolean *ignored, String &ignored_code) {
+
+ *ignored = FALSE;
+
+ gboolean result = TRUE;
+
+ if (!prepare_data()) {
+ AUDDBG("Could not read received data from last.fm. What's up?\n");
+ return FALSE;
+ }
+
+ String status = check_status(error_code, error_detail);
+
+ if (!status) {
+ AUDDBG("Status was nullptr. Invalid API answer.\n");
+ clean_data();
+ return FALSE;
+ }
+
+ if (!strcmp(status, "failed")) {
+ AUDDBG("Error code: %s. Detail: %s.\n", (const char *)error_code,
+ (const char *)error_detail);
+ result = FALSE;
+
+ } else {
+ //TODO: We are assuming that only one track is scrobbled per request! This will have to be
+ //re-done to support multiple tracks being scrobbled in batch
+ String ignored_scrobble = get_attribute_value("/lfm/scrobbles[@ignored]", "ignored");
+
+ if (ignored_scrobble && strcmp(ignored_scrobble, "0")) {
+ //The track was ignored
+ //TODO: this assumes ignored_scrobble == 1!!!
+ *ignored = TRUE;
+ ignored_code = get_attribute_value("/lfm/scrobbles/scrobble/ignoredMessage[@code]", "code");
+ }
+
+ AUDDBG("ignored? %i, ignored_code: %s\n", *ignored, (const char *)ignored_code);
+ }
+
+ clean_data();
+ return result;
+}
+
+//returns
+//FALSE if there was an error with the connection
+gboolean read_authentication_test_result (String &error_code, String &error_detail) {
+
+ gboolean result = TRUE;
+
+ if (!prepare_data()) {
+ AUDDBG("Could not read received data from last.fm. What's up?\n");
+ return FALSE;
+ }
+
+ String status = check_status(error_code, error_detail);
+
+ if (!status) {
+ AUDDBG("Status was nullptr. Invalid API answer.\n");
+ clean_data();
+ return FALSE;
+ }
+
+ if (!strcmp(status, "failed")) {
+ result = FALSE;
+
+ } else {
+ username = get_attribute_value("/lfm/recommendations[@user]", "user");
+ if (!username) {
+ AUDDBG("last.fm not answering according to the API.\n");
+ result = FALSE;
+ }
+ }
+
+ clean_data();
+ return result;
+}
+
+
+
+gboolean read_token (String &error_code, String &error_detail) {
+
+ gboolean result = TRUE;
+
+ if (!prepare_data()) {
+ AUDDBG("Could not read received data from last.fm. What's up?\n");
+ return FALSE;
+ }
+
+ String status = check_status(error_code, error_detail);
+
+ if (!status) {
+ AUDDBG("Status was nullptr. Invalid API answer.\n");
+ clean_data();
+ return FALSE;
+ }
+
+ if (!strcmp(status, "failed")) {
+ AUDDBG("Error code: %s. Detail: %s.\n", (const char *)error_code,
+ (const char *)error_detail);
+ result = FALSE;
+ }
+ else {
+ request_token = get_node_string("/lfm/token");
+
+ if (!request_token || !request_token[0]) {
+ AUDDBG("Could not read the received token. Something's wrong with the API?\n");
+ result = FALSE;
+ }
+ else {
+ AUDDBG("This is the token: %s.\nNice? Nice.\n", (const char *)request_token);
+ }
+ }
+
+ clean_data();
+ return result;
+}
+
+
+
+gboolean read_session_key(String &error_code, String &error_detail) {
+
+ gboolean result = TRUE;
+
+ if (!prepare_data()) {
+ AUDDBG("Could not read received data from last.fm. What's up?\n");
+ return FALSE;
+ }
+
+ String status = check_status(error_code, error_detail);
+
+ if (!status) {
+ AUDDBG("Status was nullptr or empty. Invalid API answer.\n");
+ clean_data();
+ return FALSE;
+ }
+
+ if (!strcmp(status, "failed")) {
+ AUDDBG("Error code: %s. Detail: %s.\n", (const char *)error_code,
+ (const char *)error_detail);
+ result = FALSE;
+
+ } else {
+ session_key = get_node_string("/lfm/session/key");
+
+ if (!session_key || !session_key[0]) {
+ AUDDBG("Could not read the received session key. Something's wrong with the API?\n");
+ result = FALSE;
+ } else {
+ AUDDBG("This is the session key: %s.\n", (const char *)session_key);
+ }
+ }
+
+ clean_data();
+ return result;
+}
+
diff --git a/src/sdlout/Makefile b/src/sdlout/Makefile
index 7243d2e51f03..c59c97c4fee2 100644
--- a/src/sdlout/Makefile
+++ b/src/sdlout/Makefile
@@ -1,13 +1,13 @@
PLUGIN = sdlout${PLUGIN_SUFFIX}
-SRCS = sdlout.c \
- plugin.c \
+SRCS = sdlout.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${OUTPUT_PLUGIN_DIR}
+LD = ${CXX}
CPPFLAGS += -I../.. ${SDL_CFLAGS}
-CFLAGS += ${GLIB_CFLAGS} ${PLUGIN_CFLAGS}
-LIBS += -lm ${GLIB_LIBS} ${SDL_LIBS}
+CXXFLAGS += ${PLUGIN_CFLAGS}
+LIBS += -lm ${SDL_LIBS}
diff --git a/src/sdlout/plugin.c b/src/sdlout/plugin.c
deleted file mode 100644
index 785d7490fda9..000000000000
--- a/src/sdlout/plugin.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * SDL Output Plugin for Audacious
- * Copyright 2010 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-
-#include "sdlout.h"
-
-static const char sdlout_about[] =
- N_("SDL Output Plugin for Audacious\n"
- "Copyright 2010 John Lindgren");
-
-AUD_OUTPUT_PLUGIN
-(
- .name = N_("SDL Output"),
- .domain = PACKAGE,
- .about_text = sdlout_about,
- .init = sdlout_init,
- .cleanup = sdlout_cleanup,
- .probe_priority = 1,
- .get_volume = sdlout_get_volume,
- .set_volume = sdlout_set_volume,
- .open_audio = sdlout_open_audio,
- .close_audio = sdlout_close_audio,
- .buffer_free = sdlout_buffer_free,
- .period_wait = sdlout_period_wait,
- .write_audio = sdlout_write_audio,
- .drain = sdlout_drain,
- .output_time = sdlout_output_time,
- .pause = sdlout_pause,
- .flush = sdlout_flush
-)
diff --git a/src/sdlout/sdlout.c b/src/sdlout/sdlout.c
deleted file mode 100644
index cfc4b519472f..000000000000
--- a/src/sdlout/sdlout.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * SDL Output Plugin for Audacious
- * Copyright 2010 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <assert.h>
-#include <math.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <sys/time.h>
-
-#include <glib.h>
-
-#include <SDL.h>
-#include <SDL_audio.h>
-
-#include <audacious/debug.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-#include "sdlout.h"
-
-#define VOLUME_RANGE 40 /* decibels */
-
-#define sdlout_error(...) do { \
- SPRINTF (sdlout_error_buf, "SDL error: " __VA_ARGS__); \
- aud_interface_show_error (sdlout_error_buf); \
-} while (0)
-
-static const char * const sdl_defaults[] = {
- "vol_left", "100",
- "vol_right", "100",
- NULL};
-
-static pthread_mutex_t sdlout_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t sdlout_cond = PTHREAD_COND_INITIALIZER;
-
-static volatile int vol_left, vol_right;
-
-static int sdlout_chan, sdlout_rate;
-
-static unsigned char * buffer;
-static int buffer_size, buffer_data_start, buffer_data_len;
-
-static int64_t frames_written;
-static char prebuffer_flag, paused_flag;
-
-static int block_delay;
-static struct timeval block_time;
-
-int sdlout_init (void)
-{
- aud_config_set_defaults ("sdlout", sdl_defaults);
-
- vol_left = aud_get_int ("sdlout", "vol_left");
- vol_right = aud_get_int ("sdlout", "vol_right");
-
- if (SDL_Init (SDL_INIT_AUDIO) < 0)
- {
- fprintf (stderr, "Failed to init SDL: %s.\n", SDL_GetError ());
- return 0;
- }
-
- return 1;
-}
-
-void sdlout_cleanup (void)
-{
- SDL_Quit ();
-}
-
-void sdlout_get_volume (int * left, int * right)
-{
- * left = vol_left;
- * right = vol_right;
-}
-
-void sdlout_set_volume (int left, int right)
-{
- vol_left = left;
- vol_right = right;
-
- aud_set_int ("sdlout", "vol_left", left);
- aud_set_int ("sdlout", "vol_right", right);
-}
-
-static void apply_mono_volume (unsigned char * data, int len)
-{
- int vol = MAX (vol_left, vol_right);
- int factor = (vol == 0) ? 0 : powf (10, (float) VOLUME_RANGE * (vol - 100)
- / 100 / 20) * 65536;
-
- int16_t * i = (int16_t *) data;
- int16_t * end = (int16_t *) (data + len);
-
- while (i < end)
- {
- * i = ((int) * i * factor) >> 16;
- i ++;
- }
-}
-
-static void apply_stereo_volume (unsigned char * data, int len)
-{
- int factor_left = (vol_left == 0) ? 0 : powf (10, (float) VOLUME_RANGE *
- (vol_left - 100) / 100 / 20) * 65536;
- int factor_right = (vol_right == 0) ? 0 : powf (10, (float) VOLUME_RANGE *
- (vol_right - 100) / 100 / 20) * 65536;
-
- int16_t * i = (int16_t *) data;
- int16_t * end = (int16_t *) (data + len);
-
- while (i < end)
- {
- * i = ((int) * i * factor_left) >> 16;
- i ++;
- * i = ((int) * i * factor_right) >> 16;
- i ++;
- }
-}
-
-static void callback (void * user, unsigned char * buf, int len)
-{
- pthread_mutex_lock (& sdlout_mutex);
-
- int copy = MIN (len, buffer_data_len);
- int part = buffer_size - buffer_data_start;
-
- if (copy <= part)
- {
- memcpy (buf, buffer + buffer_data_start, copy);
- buffer_data_start += copy;
- }
- else
- {
- memcpy (buf, buffer + buffer_data_start, part);
- memcpy (buf + part, buffer, copy - part);
- buffer_data_start = copy - part;
- }
-
- buffer_data_len -= copy;
-
- if (sdlout_chan == 2)
- apply_stereo_volume (buf, copy);
- else
- apply_mono_volume (buf, copy);
-
- if (copy < len)
- memset (buf + copy, 0, len - copy);
-
- /* At this moment, we know that there is a delay of (at least) the block of
- * data just written. We save the block size and the current time for
- * estimating the delay later on. */
- block_delay = copy / (2 * sdlout_chan) * 1000 / sdlout_rate;
- gettimeofday (& block_time, NULL);
-
- pthread_cond_broadcast (& sdlout_cond);
- pthread_mutex_unlock (& sdlout_mutex);
-}
-
-int sdlout_open_audio (int format, int rate, int chan)
-{
- if (format != FMT_S16_NE)
- {
- sdlout_error ("Only signed 16-bit, native endian audio is supported.\n");
- return 0;
- }
-
- AUDDBG ("Opening audio for %d channels, %d Hz.\n", chan, rate);
-
- sdlout_chan = chan;
- sdlout_rate = rate;
-
- buffer_size = 2 * chan * (aud_get_int (NULL, "output_buffer_size") * rate / 1000);
- buffer = g_malloc (buffer_size);
- buffer_data_start = 0;
- buffer_data_len = 0;
-
- frames_written = 0;
- prebuffer_flag = 1;
- paused_flag = 0;
-
- SDL_AudioSpec spec = {
- .freq = rate,
- .format = AUDIO_S16,
- .channels = chan,
- .samples = 4096,
- .callback = callback,
- .userdata = NULL};
-
- if (SDL_OpenAudio (& spec, NULL) < 0)
- {
- sdlout_error ("Failed to open audio stream: %s.\n", SDL_GetError ());
- g_free (buffer);
- buffer = NULL;
- return 0;
- }
-
- return 1;
-}
-
-void sdlout_close_audio (void)
-{
- AUDDBG ("Closing audio.\n");
- SDL_CloseAudio ();
- g_free (buffer);
- buffer = NULL;
-}
-
-int sdlout_buffer_free (void)
-{
- pthread_mutex_lock (& sdlout_mutex);
- int space = buffer_size - buffer_data_len;
- pthread_mutex_unlock (& sdlout_mutex);
- return space;
-}
-
-static void check_started (void)
-{
- if (! prebuffer_flag)
- return;
-
- AUDDBG ("Starting playback.\n");
- prebuffer_flag = 0;
- block_delay = 0;
- SDL_PauseAudio (0);
-}
-
-void sdlout_period_wait (void)
-{
- pthread_mutex_lock (& sdlout_mutex);
-
- while (buffer_data_len == buffer_size)
- {
- if (! paused_flag)
- check_started ();
-
- pthread_cond_wait (& sdlout_cond, & sdlout_mutex);
- }
-
- pthread_mutex_unlock (& sdlout_mutex);
-}
-
-void sdlout_write_audio (void * data, int len)
-{
- pthread_mutex_lock (& sdlout_mutex);
-
- assert (len <= buffer_size - buffer_data_len);
-
- int start = (buffer_data_start + buffer_data_len) % buffer_size;
-
- if (len <= buffer_size - start)
- memcpy (buffer + start, data, len);
- else
- {
- int part = buffer_size - start;
- memcpy (buffer + start, data, part);
- memcpy (buffer, (char *) data + part, len - part);
- }
-
- buffer_data_len += len;
- frames_written += len / (2 * sdlout_chan);
-
- pthread_mutex_unlock (& sdlout_mutex);
-}
-
-void sdlout_drain (void)
-{
- AUDDBG ("Draining.\n");
- pthread_mutex_lock (& sdlout_mutex);
-
- check_started ();
-
- while (buffer_data_len)
- pthread_cond_wait (& sdlout_cond, & sdlout_mutex);
-
- pthread_mutex_unlock (& sdlout_mutex);
-}
-
-int sdlout_output_time (void)
-{
- pthread_mutex_lock (& sdlout_mutex);
-
- int out = (int64_t) (frames_written - buffer_data_len / (2 * sdlout_chan))
- * 1000 / sdlout_rate;
-
- /* Estimate the additional delay of the last block written. */
- if (! prebuffer_flag && ! paused_flag && block_delay)
- {
- struct timeval cur;
- gettimeofday (& cur, NULL);
-
- int elapsed = 1000 * (cur.tv_sec - block_time.tv_sec) + (cur.tv_usec -
- block_time.tv_usec) / 1000;
-
- if (elapsed < block_delay)
- out -= block_delay - elapsed;
- }
-
- pthread_mutex_unlock (& sdlout_mutex);
- return out;
-}
-
-void sdlout_pause (int pause)
-{
- AUDDBG ("%sause.\n", pause ? "P" : "Unp");
- pthread_mutex_lock (& sdlout_mutex);
-
- paused_flag = pause;
-
- if (! prebuffer_flag)
- SDL_PauseAudio (pause);
-
- pthread_cond_broadcast (& sdlout_cond); /* wake up period wait */
- pthread_mutex_unlock (& sdlout_mutex);
-}
-
-void sdlout_flush (int time)
-{
- AUDDBG ("Seek requested; discarding buffer.\n");
- pthread_mutex_lock (& sdlout_mutex);
-
- buffer_data_start = 0;
- buffer_data_len = 0;
-
- frames_written = (int64_t) time * sdlout_rate / 1000;
- prebuffer_flag = 1;
-
- pthread_cond_broadcast (& sdlout_cond); /* wake up period wait */
- pthread_mutex_unlock (& sdlout_mutex);
-}
diff --git a/src/sdlout/sdlout.cc b/src/sdlout/sdlout.cc
new file mode 100644
index 000000000000..cc3b379d864a
--- /dev/null
+++ b/src/sdlout/sdlout.cc
@@ -0,0 +1,335 @@
+/*
+ * SDL Output Plugin for Audacious
+ * Copyright 2010 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <math.h>
+#include <pthread.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <SDL.h>
+#include <SDL_audio.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/ringbuf.h>
+#include <libaudcore/runtime.h>
+
+#define VOLUME_RANGE 40 /* decibels */
+
+#define sdlout_error(...) do { \
+ aud_ui_show_error (str_printf ("SDL error: " __VA_ARGS__)); \
+} while (0)
+
+class SDLOutput : public OutputPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+
+ static constexpr PluginInfo info = {
+ N_("SDL Output"),
+ PACKAGE,
+ about
+ };
+
+ constexpr SDLOutput () : OutputPlugin (info, 1) {}
+
+ bool init ();
+ void cleanup ();
+
+ StereoVolume get_volume ();
+ void set_volume (StereoVolume v);
+
+ bool open_audio (int aud_format, int rate, int chans);
+ void close_audio ();
+
+ void period_wait ();
+ int write_audio (const void * data, int size);
+ void drain ();
+
+ int get_delay ();
+
+ void pause (bool pause);
+ void flush ();
+};
+
+EXPORT SDLOutput aud_plugin_instance;
+
+const char SDLOutput::about[] =
+ N_("SDL Output Plugin for Audacious\n"
+ "Copyright 2010 John Lindgren");
+
+const char * const SDLOutput::defaults[] = {
+ "vol_left", "100",
+ "vol_right", "100",
+ nullptr};
+
+static pthread_mutex_t sdlout_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t sdlout_cond = PTHREAD_COND_INITIALIZER;
+
+static volatile int vol_left, vol_right;
+
+static int sdlout_chan, sdlout_rate;
+
+static RingBuf<unsigned char> buffer;
+
+static bool prebuffer_flag, paused_flag;
+
+static int block_delay;
+static struct timeval block_time;
+
+bool SDLOutput::init ()
+{
+ aud_config_set_defaults ("sdlout", defaults);
+
+ vol_left = aud_get_int ("sdlout", "vol_left");
+ vol_right = aud_get_int ("sdlout", "vol_right");
+
+ if (SDL_Init (SDL_INIT_AUDIO) < 0)
+ {
+ AUDERR ("Failed to init SDL: %s.\n", SDL_GetError ());
+ return false;
+ }
+
+ return true;
+}
+
+void SDLOutput::cleanup ()
+{
+ SDL_Quit ();
+}
+
+StereoVolume SDLOutput::get_volume ()
+{
+ return {vol_left, vol_right};
+}
+
+void SDLOutput::set_volume (StereoVolume v)
+{
+ vol_left = v.left;
+ vol_right = v.right;
+
+ aud_set_int ("sdlout", "vol_left", v.left);
+ aud_set_int ("sdlout", "vol_right", v.right);
+}
+
+static void apply_mono_volume (unsigned char * data, int len)
+{
+ int vol = aud::max (vol_left, vol_right);
+ int factor = (vol == 0) ? 0 : powf (10, (float) VOLUME_RANGE * (vol - 100)
+ / 100 / 20) * 65536;
+
+ int16_t * i = (int16_t *) data;
+ int16_t * end = (int16_t *) (data + len);
+
+ while (i < end)
+ {
+ * i = ((int) * i * factor) >> 16;
+ i ++;
+ }
+}
+
+static void apply_stereo_volume (unsigned char * data, int len)
+{
+ int factor_left = (vol_left == 0) ? 0 : powf (10, (float) VOLUME_RANGE *
+ (vol_left - 100) / 100 / 20) * 65536;
+ int factor_right = (vol_right == 0) ? 0 : powf (10, (float) VOLUME_RANGE *
+ (vol_right - 100) / 100 / 20) * 65536;
+
+ int16_t * i = (int16_t *) data;
+ int16_t * end = (int16_t *) (data + len);
+
+ while (i < end)
+ {
+ * i = ((int) * i * factor_left) >> 16;
+ i ++;
+ * i = ((int) * i * factor_right) >> 16;
+ i ++;
+ }
+}
+
+static void callback (void * user, unsigned char * buf, int len)
+{
+ pthread_mutex_lock (& sdlout_mutex);
+
+ int copy = aud::min (len, buffer.len ());
+ buffer.move_out (buf, copy);
+
+ if (sdlout_chan == 2)
+ apply_stereo_volume (buf, copy);
+ else
+ apply_mono_volume (buf, copy);
+
+ if (copy < len)
+ memset (buf + copy, 0, len - copy);
+
+ /* At this moment, we know that there is a delay of (at least) the block of
+ * data just written. We save the block size and the current time for
+ * estimating the delay later on. */
+ block_delay = aud::rescale (copy / (2 * sdlout_chan), sdlout_rate, 1000);
+ gettimeofday (& block_time, nullptr);
+
+ pthread_cond_broadcast (& sdlout_cond);
+ pthread_mutex_unlock (& sdlout_mutex);
+}
+
+bool SDLOutput::open_audio (int format, int rate, int chan)
+{
+ if (format != FMT_S16_NE)
+ {
+ sdlout_error ("Only signed 16-bit, native endian audio is supported.\n");
+ return false;
+ }
+
+ AUDDBG ("Opening audio for %d channels, %d Hz.\n", chan, rate);
+
+ sdlout_chan = chan;
+ sdlout_rate = rate;
+
+ int buffer_ms = aud_get_int (nullptr, "output_buffer_size");
+ buffer.alloc (2 * chan * aud::rescale (buffer_ms, 1000, rate));
+
+ prebuffer_flag = true;
+ paused_flag = false;
+
+ SDL_AudioSpec spec = {0};
+
+ spec.freq = rate;
+ spec.format = AUDIO_S16;
+ spec.channels = chan;
+ spec.samples = 4096;
+ spec.callback = callback;
+
+ if (SDL_OpenAudio (& spec, nullptr) < 0)
+ {
+ sdlout_error ("Failed to open audio stream: %s.\n", SDL_GetError ());
+ buffer.destroy ();
+ return false;
+ }
+
+ return true;
+}
+
+void SDLOutput::close_audio ()
+{
+ AUDDBG ("Closing audio.\n");
+ SDL_CloseAudio ();
+ buffer.destroy ();
+}
+
+static void check_started ()
+{
+ if (! prebuffer_flag)
+ return;
+
+ AUDDBG ("Starting playback.\n");
+ prebuffer_flag = false;
+ block_delay = 0;
+ SDL_PauseAudio (0);
+}
+
+void SDLOutput::period_wait ()
+{
+ pthread_mutex_lock (& sdlout_mutex);
+
+ while (! buffer.space ())
+ {
+ if (! paused_flag)
+ check_started ();
+
+ pthread_cond_wait (& sdlout_cond, & sdlout_mutex);
+ }
+
+ pthread_mutex_unlock (& sdlout_mutex);
+}
+
+int SDLOutput::write_audio (const void * data, int len)
+{
+ pthread_mutex_lock (& sdlout_mutex);
+
+ len = aud::min (len, buffer.space ());
+ buffer.copy_in ((const unsigned char *) data, len);
+
+ pthread_mutex_unlock (& sdlout_mutex);
+ return len;
+}
+
+void SDLOutput::drain ()
+{
+ AUDDBG ("Draining.\n");
+ pthread_mutex_lock (& sdlout_mutex);
+
+ check_started ();
+
+ while (buffer.len ())
+ pthread_cond_wait (& sdlout_cond, & sdlout_mutex);
+
+ pthread_mutex_unlock (& sdlout_mutex);
+}
+
+int SDLOutput::get_delay ()
+{
+ auto timediff = [] (const timeval & a, const timeval & b) -> int64_t
+ { return 1000 * (int64_t) (b.tv_sec - a.tv_sec) + (b.tv_usec - a.tv_usec) / 1000; };
+
+ pthread_mutex_lock (& sdlout_mutex);
+
+ int delay = aud::rescale (buffer.len (), 2 * sdlout_chan * sdlout_rate, 1000);
+
+ /* Estimate the additional delay of the last block written. */
+ if (! prebuffer_flag && ! paused_flag && block_delay)
+ {
+ struct timeval cur;
+ gettimeofday (& cur, nullptr);
+
+ delay += aud::max (block_delay - timediff (block_time, cur), (int64_t) 0);
+ }
+
+ pthread_mutex_unlock (& sdlout_mutex);
+ return delay;
+}
+
+void SDLOutput::pause (bool pause)
+{
+ AUDDBG ("%sause.\n", pause ? "P" : "Unp");
+ pthread_mutex_lock (& sdlout_mutex);
+
+ paused_flag = pause;
+
+ if (! prebuffer_flag)
+ SDL_PauseAudio (pause);
+
+ pthread_cond_broadcast (& sdlout_cond); /* wake up period wait */
+ pthread_mutex_unlock (& sdlout_mutex);
+}
+
+void SDLOutput::flush ()
+{
+ AUDDBG ("Seek requested; discarding buffer.\n");
+ pthread_mutex_lock (& sdlout_mutex);
+
+ buffer.discard ();
+
+ prebuffer_flag = true;
+
+ pthread_cond_broadcast (& sdlout_cond); /* wake up period wait */
+ pthread_mutex_unlock (& sdlout_mutex);
+}
diff --git a/src/sdlout/sdlout.h b/src/sdlout/sdlout.h
deleted file mode 100644
index f33b2ffcb38c..000000000000
--- a/src/sdlout/sdlout.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SDL Output Plugin for Audacious
- * Copyright 2010 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#ifndef AUDACIOUS_SDLOUT_H
-#define AUDACIOUS_SDLOUT_H
-
-/* sdlout.c */
-int sdlout_init (void);
-void sdlout_cleanup (void);
-void sdlout_get_volume (int * left, int * right);
-void sdlout_set_volume (int left, int right);
-int sdlout_open_audio (int format, int rate, int chan);
-void sdlout_close_audio (void);
-int sdlout_buffer_free (void);
-void sdlout_period_wait (void);
-void sdlout_write_audio (void * data, int len);
-void sdlout_drain (void);
-int sdlout_output_time (void);
-void sdlout_pause (int pause);
-void sdlout_flush (int time);
-
-#endif
diff --git a/src/search-tool/Makefile b/src/search-tool/Makefile
index 66cc384d9b83..976158e72d4d 100644
--- a/src/search-tool/Makefile
+++ b/src/search-tool/Makefile
@@ -1,12 +1,14 @@
PLUGIN = search-tool${PLUGIN_SUFFIX}
-SRCS = search-tool.c
+SRCS = search-tool.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
+
CPPFLAGS += -I../.. ${GTK_CFLAGS}
CFLAGS += ${PLUGIN_CFLAGS}
-LIBS += ${GTK_LIBS}
+LIBS += ${GTK_LIBS} -laudgui
diff --git a/src/search-tool/search-tool.c b/src/search-tool/search-tool.c
deleted file mode 100644
index 494453ebab92..000000000000
--- a/src/search-tool/search-tool.c
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * search-tool.c
- * Copyright 2011-2012 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <errno.h>
-#include <string.h>
-
-#include <gtk/gtk.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/list.h>
-#include <libaudgui/menu.h>
-
-#define MAX_RESULTS 100
-#define SEARCH_DELAY 300
-
-enum {ARTIST, ALBUM, TITLE, FIELDS};
-
-typedef struct item {
- int field;
- char * name, * folded;
- struct item * parent;
- GHashTable * children;
- GArray * matches;
-} Item;
-
-typedef struct {
- Index * items[FIELDS];
- int mask;
-} SearchState;
-
-static int playlist_id;
-static Index * search_terms;
-
-static GHashTable * added_table;
-static GHashTable * database;
-static Index * items;
-static GArray * selection;
-
-static bool_t adding;
-static int search_source;
-
-static GtkWidget * entry, * help_label, * wait_label, * scrolled, * results_list;
-
-static void item_free (Item * item);
-
-static Item * item_new (int field, char * name, Item * parent)
-{
- Item * item = g_slice_new (Item);
- item->field = field;
- item->name = name;
- item->folded = str_tolower_utf8 (name);
- item->parent = parent;
- item->matches = g_array_new (FALSE, FALSE, sizeof (int));
-
- if (field == TITLE)
- item->children = NULL;
- else
- item->children = g_hash_table_new_full ((GHashFunc) str_hash,
- (GEqualFunc) str_equal, NULL, (GDestroyNotify) item_free);
-
- return item;
-}
-
-static void item_free (Item * item)
-{
- if (item->children)
- g_hash_table_destroy (item->children);
-
- str_unref (item->name);
- str_unref (item->folded);
- g_array_free (item->matches, TRUE);
- g_slice_free (Item, item);
-}
-
-static void find_playlist (void)
-{
- playlist_id = -1;
-
- for (int p = 0; playlist_id < 0 && p < aud_playlist_count (); p ++)
- {
- char * title = aud_playlist_get_title (p);
-
- if (! strcmp (title, _("Library")))
- playlist_id = aud_playlist_get_unique_id (p);
-
- str_unref (title);
- }
-}
-
-static int create_playlist (void)
-{
- int list = aud_playlist_get_blank ();
- aud_playlist_set_title (list, _("Library"));
- aud_playlist_set_active (list);
- playlist_id = aud_playlist_get_unique_id (list);
- return list;
-}
-
-static int get_playlist (bool_t require_added, bool_t require_scanned)
-{
- if (playlist_id < 0)
- return -1;
-
- int list = aud_playlist_by_unique_id (playlist_id);
-
- if (list < 0)
- {
- playlist_id = -1;
- return -1;
- }
-
- if (require_added && aud_playlist_add_in_progress (list))
- return -1;
- if (require_scanned && aud_playlist_scan_in_progress (list))
- return -1;
-
- return list;
-}
-
-static void set_search_phrase (const char * phrase)
-{
- char * folded = str_tolower_utf8 (phrase);
- index_free_full (search_terms, (IndexFreeFunc) str_unref);
- search_terms = str_list_to_index (folded, " ");
- str_unref (folded);
-}
-
-static char * get_path (void)
-{
- char * path = aud_get_str ("search-tool", "path");
- if (g_file_test (path, G_FILE_TEST_EXISTS))
- return path;
-
- str_unref (path);
-
- path = filename_build (g_get_home_dir (), "Music");
- if (g_file_test (path, G_FILE_TEST_EXISTS))
- return path;
-
- str_unref (path);
-
- return str_get (g_get_home_dir ());
-}
-
-static void destroy_added_table (void)
-{
- if (added_table)
- {
- g_hash_table_destroy (added_table);
- added_table = NULL;
- }
-}
-
-static void destroy_database (void)
-{
- if (items)
- index_delete (items, 0, index_count (items));
-
- if (database)
- {
- g_hash_table_destroy (database);
- database = NULL;
- }
-}
-
-static void create_database (int list)
-{
- destroy_database ();
-
- database = g_hash_table_new_full ((GHashFunc) str_hash, (GEqualFunc)
- str_equal, NULL, (GDestroyNotify) item_free);
-
- int entries = aud_playlist_entry_count (list);
-
- for (int e = 0; e < entries; e ++)
- {
- char * title, * artist, * album;
- Item * artist_item, * album_item, * title_item;
-
- aud_playlist_entry_describe (list, e, & title, & artist, & album, TRUE);
-
- if (! title)
- {
- str_unref (artist);
- str_unref (album);
- continue;
- }
-
- if (! artist)
- artist = str_get (_("Unknown Artist"));
- if (! album)
- album = str_get (_("Unknown Album"));
-
- artist_item = g_hash_table_lookup (database, artist);
-
- if (! artist_item)
- {
- /* item_new() takes ownership of reference to artist */
- artist_item = item_new (ARTIST, artist, NULL);
- g_hash_table_insert (database, artist, artist_item);
- }
- else
- str_unref (artist);
-
- g_array_append_val (artist_item->matches, e);
-
- album_item = g_hash_table_lookup (artist_item->children, album);
-
- if (! album_item)
- {
- /* item_new() takes ownership of reference to album */
- album_item = item_new (ALBUM, album, artist_item);
- g_hash_table_insert (artist_item->children, album, album_item);
- }
- else
- str_unref (album);
-
- g_array_append_val (album_item->matches, e);
-
- title_item = g_hash_table_lookup (album_item->children, title);
-
- if (! title_item)
- {
- /* item_new() takes ownership of reference to title */
- title_item = item_new (TITLE, title, album_item);
- g_hash_table_insert (album_item->children, title, title_item);
- }
- else
- str_unref (title);
-
- g_array_append_val (title_item->matches, e);
- }
-}
-
-static void search_cb (void * key, void * _item, void * _state)
-{
- Item * item = _item;
- SearchState * state = _state;
-
- if (index_count (state->items[item->field]) > MAX_RESULTS)
- return;
-
- int oldmask = state->mask;
- int count = index_count (search_terms);
-
- for (int t = 0, bit = 1; t < count; t ++, bit <<= 1)
- {
- if (! (state->mask & bit))
- continue; /* skip term if it is already found */
-
- if (strstr (item->folded, index_get (search_terms, t)))
- state->mask &= ~bit; /* we found it */
- else if (! item->children)
- break; /* quit early if there are no children to search */
- }
-
- if (! state->mask)
- index_insert (state->items[item->field], -1, item);
-
- if (item->children)
- g_hash_table_foreach (item->children, search_cb, state);
-
- state->mask = oldmask;
-}
-
-static int item_compare (const void * _a, const void * _b)
-{
- const Item * a = _a, * b = _b;
- return str_compare (a->name, b->name);
-}
-
-static void do_search (void)
-{
- index_delete (items, 0, index_count (items));
-
- if (! database)
- return;
-
- SearchState state;
-
- for (int f = 0; f < FIELDS; f ++)
- state.items[f] = index_new ();
-
- /* effectively limits number of search terms to 32 */
- state.mask = (1 << index_count (search_terms)) - 1;
-
- g_hash_table_foreach (database, search_cb, & state);
-
- int total = 0;
-
- for (int f = 0; f < FIELDS; f ++)
- {
- int count = index_count (state.items[f]);
- if (count > MAX_RESULTS - total)
- count = MAX_RESULTS - total;
-
- if (count)
- {
- index_sort (state.items[f], item_compare);
- index_copy_insert (state.items[f], 0, items, -1, count);
- total += count;
- }
-
- index_free (state.items[f]);
- }
-
- g_array_set_size (selection, total);
- memset (selection->data, 0, selection->len);
- if (selection->len > 0)
- selection->data[0] = 1;
-}
-
-static bool_t filter_cb (const char * filename, void * unused)
-{
- return added_table && ! g_hash_table_contains (added_table, filename);
-}
-
-static void begin_add (const char * path)
-{
- int list = get_playlist (FALSE, FALSE);
-
- if (list < 0)
- list = create_playlist ();
-
- aud_set_str ("search-tool", "path", path);
-
- char * uri = filename_to_uri (path);
- g_return_if_fail (uri);
-
- if (! g_str_has_suffix (uri, "/"))
- {
- SCONCAT2 (temp, uri, "/");
- str_unref (uri);
- uri = str_get (temp);
- }
-
- destroy_added_table ();
-
- added_table = g_hash_table_new_full ((GHashFunc) str_hash, (GEqualFunc)
- str_equal, (GDestroyNotify) str_unref, NULL);
-
- int entries = aud_playlist_entry_count (list);
-
- for (int entry = 0; entry < entries; entry ++)
- {
- char * filename = aud_playlist_entry_get_filename (list, entry);
-
- if (g_str_has_prefix (filename, uri) && ! g_hash_table_contains (added_table, filename))
- {
- aud_playlist_entry_set_selected (list, entry, FALSE);
- g_hash_table_insert (added_table, filename, NULL);
- }
- else
- {
- aud_playlist_entry_set_selected (list, entry, TRUE);
- str_unref (filename);
- }
- }
-
- aud_playlist_delete_selected (list);
- aud_playlist_remove_failed (list);
-
- Index * add = index_new ();
- index_insert (add, -1, uri);
- aud_playlist_entry_insert_filtered (list, -1, add, NULL, filter_cb, NULL, FALSE);
-
- adding = TRUE;
-}
-
-static void show_hide_widgets (void)
-{
- if (! help_label || ! wait_label || ! scrolled)
- return;
-
- if (playlist_id < 0)
- {
- gtk_widget_hide (wait_label);
- gtk_widget_hide (scrolled);
- gtk_widget_show (help_label);
- }
- else
- {
- gtk_widget_hide (help_label);
-
- if (database)
- {
- gtk_widget_hide (wait_label);
- gtk_widget_show (scrolled);
- }
- else
- {
- gtk_widget_hide (scrolled);
- gtk_widget_show (wait_label);
- }
- }
-}
-
-static int search_timeout (void * unused)
-{
- do_search ();
-
- if (results_list)
- {
- audgui_list_delete_rows (results_list, 0, audgui_list_row_count (results_list));
- audgui_list_insert_rows (results_list, 0, index_count (items));
- }
-
- if (search_source)
- {
- g_source_remove (search_source);
- search_source = 0;
- }
-
- return FALSE;
-}
-
-static void schedule_search (void)
-{
- if (search_source)
- g_source_remove (search_source);
-
- search_source = g_timeout_add (SEARCH_DELAY, search_timeout, NULL);
-}
-
-static void update_database (void)
-{
- int list = get_playlist (TRUE, TRUE);
-
- if (list >= 0)
- {
- create_database (list);
- schedule_search ();
- }
- else
- destroy_database ();
-
- if (results_list)
- audgui_list_delete_rows (results_list, 0, audgui_list_row_count (results_list));
-
- show_hide_widgets ();
-}
-
-static void add_complete_cb (void * unused, void * unused2)
-{
- if (adding)
- {
- int list = get_playlist (TRUE, FALSE);
-
- if (list >= 0 && ! aud_playlist_add_in_progress (list))
- {
- adding = FALSE;
- destroy_added_table ();
- aud_playlist_sort_by_scheme (list, PLAYLIST_SORT_PATH);
- }
- }
-
- if (! database && ! aud_playlist_update_pending ())
- update_database ();
-}
-
-static void scan_complete_cb (void * unused, void * unused2)
-{
- if (! database && ! aud_playlist_update_pending ())
- update_database ();
-}
-
-static void playlist_update_cb (void * data, void * unused)
-{
- if (! database)
- update_database ();
- else
- {
- int list = get_playlist (TRUE, TRUE);
- int at, count;
-
- if (list < 0 || aud_playlist_updated_range (list, & at, & count) >=
- PLAYLIST_UPDATE_METADATA)
- update_database ();
- }
-}
-
-static bool_t search_init (void)
-{
- find_playlist ();
-
- search_terms = index_new ();
- items = index_new ();
- selection = g_array_new (FALSE, FALSE, 1);
-
- update_database ();
-
- hook_associate ("playlist add complete", add_complete_cb, NULL);
- hook_associate ("playlist scan complete", scan_complete_cb, NULL);
- hook_associate ("playlist update", playlist_update_cb, NULL);
-
- return TRUE;
-}
-
-static void search_cleanup (void)
-{
- hook_dissociate ("playlist add complete", add_complete_cb);
- hook_dissociate ("playlist scan complete", scan_complete_cb);
- hook_dissociate ("playlist update", playlist_update_cb);
-
- if (search_source)
- {
- g_source_remove (search_source);
- search_source = 0;
- }
-
- index_free_full (search_terms, (IndexFreeFunc) str_unref);
- search_terms = NULL;
-
- index_free (items);
- items = NULL;
- g_array_free (selection, TRUE);
- selection = NULL;
-
- destroy_added_table ();
- destroy_database ();
-}
-
-static void do_add (bool_t play, char * * title)
-{
- int list = aud_playlist_by_unique_id (playlist_id);
- int n_items = index_count (items);
- int n_selected = 0;
-
- Index * filenames = index_new ();
- Index * tuples = index_new ();
-
- for (int i = 0; i < n_items; i ++)
- {
- if (! selection->data[i])
- continue;
-
- Item * item = index_get (items, i);
-
- for (int m = 0; m < item->matches->len; m ++)
- {
- int entry = g_array_index (item->matches, int, m);
- index_insert (filenames, -1, aud_playlist_entry_get_filename (list, entry));
- index_insert (tuples, -1, aud_playlist_entry_get_tuple (list, entry, TRUE));
- }
-
- n_selected ++;
- if (title && n_selected == 1)
- * title = item->name;
- }
-
- if (title && n_selected != 1)
- * title = NULL;
-
- aud_playlist_entry_insert_batch (aud_playlist_get_active (), -1, filenames,
- tuples, play);
-}
-
-static void action_play (void)
-{
- int list = aud_playlist_get_temporary ();
- aud_playlist_set_active (list);
-
- if (aud_get_bool (NULL, "clear_playlist"))
- aud_playlist_entry_delete (list, 0, aud_playlist_entry_count (list));
- else
- aud_playlist_queue_delete (list, 0, aud_playlist_queue_count (list));
-
- do_add (TRUE, NULL);
-}
-
-static void action_create_playlist (void)
-{
- char * title;
-
- aud_playlist_insert (-1);
- aud_playlist_set_active (aud_playlist_count () - 1);
- do_add (FALSE, & title);
-
- if (title)
- aud_playlist_set_title (aud_playlist_count () - 1, title);
-}
-
-static void action_add_to_playlist (void)
-{
- if (aud_playlist_by_unique_id (playlist_id) == aud_playlist_get_active ())
- return;
-
- do_add (FALSE, NULL);
-}
-
-static void list_get_value (void * user, int row, int column, GValue * value)
-{
- g_return_if_fail (items && row >= 0 && row < index_count (items));
-
- Item * item = index_get (items, row);
- char * string = NULL;
-
- switch (item->field)
- {
- int albums;
- char scratch[128];
-
- case TITLE:
- string = g_strdup_printf (_("%s\n on %s by %s"), item->name,
- item->parent->name, item->parent->parent->name);
- break;
-
- case ARTIST:
- albums = g_hash_table_size (item->children);
- snprintf (scratch, sizeof scratch, dngettext (PACKAGE, "%d album",
- "%d albums", albums), albums);
- string = g_strdup_printf (dngettext (PACKAGE, "%s\n %s, %d song",
- "%s\n %s, %d songs", item->matches->len), item->name, scratch,
- item->matches->len);
- break;
-
- case ALBUM:
- string = g_strdup_printf (dngettext (PACKAGE, "%s\n %d song by %s",
- "%s\n %d songs by %s", item->matches->len), item->name,
- item->matches->len, item->parent->name);
- break;
- }
-
- g_value_take_string (value, string);
-}
-
-static bool_t list_get_selected (void * user, int row)
-{
- g_return_val_if_fail (selection && row >= 0 && row < selection->len, FALSE);
- return selection->data[row];
-}
-
-static void list_set_selected (void * user, int row, bool_t selected)
-{
- g_return_if_fail (selection && row >= 0 && row < selection->len);
- selection->data[row] = selected;
-}
-
-static void list_select_all (void * user, bool_t selected)
-{
- g_return_if_fail (selection);
- memset (selection->data, selected, selection->len);
-}
-
-static void list_activate_row (void * user, int row)
-{
- action_play ();
-}
-
-static void list_right_click (void * user, GdkEventButton * event)
-{
- static const AudguiMenuItem items[] = {
- {N_("_Play"), "media-playback-start", .func = action_play},
- {N_("_Create Playlist"), "document-new", .func = action_create_playlist},
- {N_("_Add to Playlist"), "list-add", .func = action_add_to_playlist}
- };
-
- GtkWidget * menu = gtk_menu_new ();
- audgui_menu_init (menu, items, ARRAY_LEN (items), NULL);
- gtk_menu_popup ((GtkMenu *) menu, NULL, NULL, NULL, NULL, event->button, event->time);
-}
-
-static const AudguiListCallbacks list_callbacks = {
- .get_value = list_get_value,
- .get_selected = list_get_selected,
- .set_selected = list_set_selected,
- .select_all = list_select_all,
- .activate_row = list_activate_row,
- .right_click = list_right_click};
-
-static void entry_cb (GtkEntry * entry, void * unused)
-{
- set_search_phrase (gtk_entry_get_text ((GtkEntry *) entry));
- schedule_search ();
-}
-
-static void refresh_cb (GtkButton * button, GtkWidget * chooser)
-{
- char * path = gtk_file_chooser_get_filename ((GtkFileChooser *) chooser);
- begin_add (path);
- g_free (path);
-
- update_database ();
-}
-
-static void * search_get_widget (void)
-{
- GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-
- entry = gtk_entry_new ();
- gtk_entry_set_icon_from_icon_name ((GtkEntry *) entry, GTK_ENTRY_ICON_PRIMARY, "edit-find");
- gtk_entry_set_placeholder_text ((GtkEntry *) entry, _("Search library"));
- g_signal_connect (entry, "destroy", (GCallback) gtk_widget_destroyed, & entry);
- gtk_box_pack_start ((GtkBox *) vbox, entry, FALSE, FALSE, 0);
-
- help_label = gtk_label_new (_("To import your music library into "
- "Audacious, choose a folder and then click the \"refresh\" icon."));
- gtk_widget_set_size_request (help_label, 194, -1);
- gtk_label_set_line_wrap ((GtkLabel *) help_label, TRUE);
- g_signal_connect (help_label, "destroy", (GCallback) gtk_widget_destroyed, & help_label);
- gtk_widget_set_no_show_all (help_label, TRUE);
- gtk_box_pack_start ((GtkBox *) vbox, help_label, TRUE, FALSE, 0);
-
- wait_label = gtk_label_new (_("Please wait ..."));
- g_signal_connect (wait_label, "destroy", (GCallback) gtk_widget_destroyed, & wait_label);
- gtk_widget_set_no_show_all (wait_label, TRUE);
- gtk_box_pack_start ((GtkBox *) vbox, wait_label, TRUE, FALSE, 0);
-
- scrolled = gtk_scrolled_window_new (NULL, NULL);
- g_signal_connect (scrolled, "destroy", (GCallback) gtk_widget_destroyed, & scrolled);
- gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled, GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrolled,
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_widget_set_no_show_all (scrolled, TRUE);
- gtk_box_pack_start ((GtkBox *) vbox, scrolled, TRUE, TRUE, 0);
-
- results_list = audgui_list_new (& list_callbacks, NULL, items ? index_count (items) : 0);
- g_signal_connect (results_list, "destroy", (GCallback) gtk_widget_destroyed, & results_list);
- gtk_tree_view_set_headers_visible ((GtkTreeView *) results_list, FALSE);
- audgui_list_add_column (results_list, NULL, 0, G_TYPE_STRING, -1);
- gtk_container_add ((GtkContainer *) scrolled, results_list);
-
- GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_end ((GtkBox *) vbox, hbox, FALSE, FALSE, 0);
-
- GtkWidget * chooser = gtk_file_chooser_button_new (_("Choose Folder"),
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
- gtk_box_pack_start ((GtkBox *) hbox, chooser, TRUE, TRUE, 0);
-
- char * path = get_path ();
- gtk_file_chooser_set_filename ((GtkFileChooser *) chooser, path);
- str_unref (path);
-
- GtkWidget * button = gtk_button_new ();
- gtk_container_add ((GtkContainer *) button, gtk_image_new_from_icon_name
- ("view-refresh", GTK_ICON_SIZE_BUTTON));
- gtk_button_set_relief ((GtkButton *) button, GTK_RELIEF_NONE);
- gtk_box_pack_start ((GtkBox *) hbox, button, FALSE, FALSE, 0);
-
- g_signal_connect (entry, "changed", (GCallback) entry_cb, NULL);
- g_signal_connect (entry, "activate", (GCallback) action_play, NULL);
- g_signal_connect (button, "clicked", (GCallback) refresh_cb, chooser);
-
- gtk_widget_show_all (vbox);
- gtk_widget_show (results_list);
- show_hide_widgets ();
-
- return vbox;
-}
-
-int search_take_message (const char * code, const void * data, int size)
-{
- if (! strcmp (code, "grab focus"))
- {
- if (entry)
- gtk_widget_grab_focus (entry);
- return 0;
- }
-
- return EINVAL;
-}
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("Search Tool"),
- .domain = PACKAGE,
- .init = search_init,
- .cleanup = search_cleanup,
- .get_widget = search_get_widget,
- .take_message = search_take_message
-)
diff --git a/src/search-tool/search-tool.cc b/src/search-tool/search-tool.cc
new file mode 100644
index 000000000000..f04ed2024c7a
--- /dev/null
+++ b/src/search-tool/search-tool.cc
@@ -0,0 +1,759 @@
+/*
+ * search-tool.c
+ * Copyright 2011-2012 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/multihash.h>
+#include <libaudcore/runtime.h>
+#include <libaudgui/list.h>
+#include <libaudgui/menu.h>
+
+#define MAX_RESULTS 20
+#define SEARCH_DELAY 300
+
+class SearchTool : public GeneralPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("Search Tool"),
+ PACKAGE
+ };
+
+ constexpr SearchTool () : GeneralPlugin (info, false) {}
+
+ void * get_gtk_widget ();
+ int take_message (const char * code, const void * data, int size);
+};
+
+EXPORT SearchTool aud_plugin_instance;
+
+enum class SearchField {
+ Genre,
+ Artist,
+ Album,
+ Title,
+ count
+};
+
+struct Key
+{
+ SearchField field;
+ String name;
+
+ bool operator== (const Key & b) const
+ { return field == b.field && name == b.name; }
+ unsigned hash () const
+ { return (unsigned) field + name.hash (); }
+};
+
+struct Item
+{
+ SearchField field;
+ String name, folded;
+ Item * parent;
+ SimpleHash<Key, Item> children;
+ Index<int> matches;
+
+ Item (SearchField field, const String & name, Item * parent) :
+ field (field),
+ name (name),
+ folded (str_tolower_utf8 (name)),
+ parent (parent) {}
+
+ Item (Item &&) = default;
+ Item & operator= (Item &&) = default;
+};
+
+struct SearchState {
+ Index<const Item *> items;
+ int mask;
+};
+
+static int playlist_id;
+static Index<String> search_terms;
+
+static SimpleHash<String, bool> added_table;
+static SimpleHash<Key, Item> database;
+static bool database_valid;
+static Index<const Item *> items;
+static int hidden_items;
+static Index<bool> selection;
+
+static gboolean adding;
+static int search_source;
+
+static GtkWidget * entry, * help_label, * wait_label, * scrolled, * results_list, * stats_label;
+
+static void find_playlist ()
+{
+ playlist_id = -1;
+
+ for (int p = 0; playlist_id < 0 && p < aud_playlist_count (); p ++)
+ {
+ String title = aud_playlist_get_title (p);
+ if (! strcmp (title, _("Library")))
+ playlist_id = aud_playlist_get_unique_id (p);
+ }
+}
+
+static int create_playlist ()
+{
+ int list = aud_playlist_get_blank ();
+ aud_playlist_set_title (list, _("Library"));
+ aud_playlist_set_active (list);
+ playlist_id = aud_playlist_get_unique_id (list);
+ return list;
+}
+
+static int get_playlist (gboolean require_added, gboolean require_scanned)
+{
+ if (playlist_id < 0)
+ return -1;
+
+ int list = aud_playlist_by_unique_id (playlist_id);
+
+ if (list < 0)
+ {
+ playlist_id = -1;
+ return -1;
+ }
+
+ if (require_added && aud_playlist_add_in_progress (list))
+ return -1;
+ if (require_scanned && aud_playlist_scan_in_progress (list))
+ return -1;
+
+ return list;
+}
+
+static void set_search_phrase (const char * phrase)
+{
+ search_terms = str_list_to_index (str_tolower_utf8 (phrase), " ");
+}
+
+static String get_path ()
+{
+ String path1 = aud_get_str ("search-tool", "path");
+ if (g_file_test (path1, G_FILE_TEST_EXISTS))
+ return path1;
+
+ StringBuf path2 = filename_build ({g_get_home_dir (), "Music"});
+ if (g_file_test (path2, G_FILE_TEST_EXISTS))
+ return String (path2);
+
+ return String (g_get_home_dir ());
+}
+
+static void destroy_database ()
+{
+ items.clear ();
+ hidden_items = 0;
+ database.clear ();
+ database_valid = false;
+}
+
+static void create_database (int list)
+{
+ destroy_database ();
+
+ int entries = aud_playlist_entry_count (list);
+
+ for (int e = 0; e < entries; e ++)
+ {
+ Tuple tuple = aud_playlist_entry_get_tuple (list, e, Playlist::Guess);
+
+ aud::array<SearchField, String> fields;
+ fields[SearchField::Genre] = tuple.get_str (Tuple::Genre);
+ fields[SearchField::Artist] = tuple.get_str (Tuple::Artist);
+ fields[SearchField::Album] = tuple.get_str (Tuple::Album);
+ fields[SearchField::Title] = tuple.get_str (Tuple::Title);
+
+ Item * parent = nullptr;
+ SimpleHash<Key, Item> * hash = & database;
+
+ for (auto f : aud::range<SearchField> ())
+ {
+ if (fields[f])
+ {
+ Key key = {f, fields[f]};
+ Item * item = hash->lookup (key);
+
+ if (! item)
+ item = hash->add (key, Item (f, fields[f], parent));
+
+ item->matches.append (e);
+
+ /* genre is outside the normal hierarchy */
+ if (f != SearchField::Genre)
+ {
+ parent = item;
+ hash = & item->children;
+ }
+ }
+ }
+ }
+
+ database_valid = true;
+}
+
+static void search_cb (const Key & key, Item & item, void * _state)
+{
+ SearchState * state = (SearchState *) _state;
+
+ int oldmask = state->mask;
+ int count = search_terms.len ();
+
+ for (int t = 0, bit = 1; t < count; t ++, bit <<= 1)
+ {
+ if (! (state->mask & bit))
+ continue; /* skip term if it is already found */
+
+ if (strstr (item.folded, search_terms[t]))
+ state->mask &= ~bit; /* we found it */
+ else if (! item.children.n_items ())
+ break; /* quit early if there are no children to search */
+ }
+
+ /* adding an item with exactly one child is redundant, so avoid it */
+ if (! state->mask && item.children.n_items () != 1)
+ state->items.append (& item);
+
+ item.children.iterate (search_cb, state);
+
+ state->mask = oldmask;
+}
+
+static int item_compare (const Item * const & a, const Item * const & b, void *)
+{
+ if (a->field < b->field)
+ return -1;
+ if (a->field > b->field)
+ return 1;
+
+ int val = str_compare (a->name, b->name);
+ if (val)
+ return val;
+
+ if (a->parent)
+ return b->parent ? item_compare (a->parent, b->parent, nullptr) : 1;
+ else
+ return b->parent ? -1 : 0;
+}
+
+static int item_compare_pass1 (const Item * const & a, const Item * const & b, void *)
+{
+ if (a->matches.len () > b->matches.len ())
+ return -1;
+ if (a->matches.len () < b->matches.len ())
+ return 1;
+
+ return item_compare (a, b, nullptr);
+}
+
+static void do_search ()
+{
+ items.clear ();
+ hidden_items = 0;
+
+ if (! database_valid)
+ return;
+
+ SearchState state;
+
+ /* effectively limits number of search terms to 32 */
+ state.mask = (1 << search_terms.len ()) - 1;
+
+ database.iterate (search_cb, & state);
+
+ items = std::move (state.items);
+
+ /* first sort by number of songs per item */
+ items.sort (item_compare_pass1, nullptr);
+
+ /* limit to items with most songs */
+ if (items.len () > MAX_RESULTS)
+ {
+ hidden_items = items.len () - MAX_RESULTS;
+ items.remove (MAX_RESULTS, -1);
+ }
+
+ /* sort by item type, then item name */
+ items.sort (item_compare, nullptr);
+
+ selection.remove (0, -1);
+ selection.insert (0, items.len ());
+ if (items.len ())
+ selection[0] = true;
+}
+
+static bool filter_cb (const char * filename, void * unused)
+{
+ return ! added_table.lookup (String (filename));
+}
+
+static void begin_add (const char * path)
+{
+ int list = get_playlist (false, false);
+
+ if (list < 0)
+ list = create_playlist ();
+
+ aud_set_str ("search-tool", "path", path);
+
+ StringBuf uri = filename_to_uri (path);
+ g_return_if_fail (uri);
+
+ if (! g_str_has_suffix (uri, "/"))
+ uri.insert (-1, "/");
+
+ added_table.clear ();
+
+ int entries = aud_playlist_entry_count (list);
+
+ for (int entry = 0; entry < entries; entry ++)
+ {
+ String filename = aud_playlist_entry_get_filename (list, entry);
+
+ if (g_str_has_prefix (filename, uri) && ! added_table.lookup (filename))
+ {
+ aud_playlist_entry_set_selected (list, entry, false);
+ added_table.add (filename, true);
+ }
+ else
+ aud_playlist_entry_set_selected (list, entry, true);
+ }
+
+ aud_playlist_delete_selected (list);
+ aud_playlist_remove_failed (list);
+
+ Index<PlaylistAddItem> add;
+ add.append (String (uri));
+ aud_playlist_entry_insert_filtered (list, -1, std::move (add), filter_cb, nullptr, false);
+
+ adding = true;
+}
+
+static void show_hide_widgets ()
+{
+ if (playlist_id < 0)
+ {
+ gtk_widget_hide (wait_label);
+ gtk_widget_hide (scrolled);
+ gtk_widget_hide (stats_label);
+ gtk_widget_show (help_label);
+ }
+ else
+ {
+ gtk_widget_hide (help_label);
+
+ if (database_valid)
+ {
+ gtk_widget_hide (wait_label);
+ gtk_widget_show (scrolled);
+ gtk_widget_show (stats_label);
+ }
+ else
+ {
+ gtk_widget_hide (scrolled);
+ gtk_widget_hide (stats_label);
+ gtk_widget_show (wait_label);
+ }
+ }
+}
+
+static int search_timeout (void * unused = nullptr)
+{
+ do_search ();
+
+ audgui_list_delete_rows (results_list, 0, audgui_list_row_count (results_list));
+ audgui_list_insert_rows (results_list, 0, items.len ());
+
+ int total = items.len () + hidden_items;
+ StringBuf stats = str_printf (dngettext (PACKAGE, "%d result",
+ "%d results", total), total);
+
+ if (hidden_items)
+ {
+ stats.insert (-1, " ");
+ stats.combine (str_printf (dngettext (PACKAGE, "(%d hidden)",
+ "(%d hidden)", hidden_items), hidden_items));
+ }
+
+ gtk_label_set_text ((GtkLabel *) stats_label, stats);
+
+ if (search_source)
+ {
+ g_source_remove (search_source);
+ search_source = 0;
+ }
+
+ return false;
+}
+
+static void schedule_search ()
+{
+ if (search_source)
+ g_source_remove (search_source);
+
+ search_source = g_timeout_add (SEARCH_DELAY, search_timeout, nullptr);
+}
+
+static void update_database ()
+{
+ int list = get_playlist (true, true);
+
+ if (list >= 0)
+ {
+ create_database (list);
+ search_timeout ();
+ }
+ else
+ {
+ destroy_database ();
+ audgui_list_delete_rows (results_list, 0, audgui_list_row_count (results_list));
+ gtk_label_set_text ((GtkLabel *) stats_label, "");
+ }
+
+ show_hide_widgets ();
+}
+
+static void add_complete_cb (void * unused, void * unused2)
+{
+ int list = get_playlist (true, false);
+ if (list < 0)
+ return;
+
+ if (adding)
+ {
+ adding = false;
+ added_table.clear ();
+ aud_playlist_sort_by_scheme (list, Playlist::Path);
+ }
+
+ if (! database_valid && ! aud_playlist_update_pending (list))
+ update_database ();
+}
+
+static void scan_complete_cb (void * unused, void * unused2)
+{
+ int list = get_playlist (true, true);
+ if (list < 0)
+ return;
+
+ if (! database_valid && ! aud_playlist_update_pending (list))
+ update_database ();
+}
+
+static void playlist_update_cb (void * data, void * unused)
+{
+ if (! database_valid)
+ update_database ();
+ else
+ {
+ int list = get_playlist (true, true);
+ if (list < 0 || aud_playlist_update_detail (list).level >= Playlist::Metadata)
+ update_database ();
+ }
+}
+
+static void search_init ()
+{
+ find_playlist ();
+
+ update_database ();
+
+ hook_associate ("playlist add complete", add_complete_cb, nullptr);
+ hook_associate ("playlist scan complete", scan_complete_cb, nullptr);
+ hook_associate ("playlist update", playlist_update_cb, nullptr);
+}
+
+static void search_cleanup ()
+{
+ hook_dissociate ("playlist add complete", add_complete_cb);
+ hook_dissociate ("playlist scan complete", scan_complete_cb);
+ hook_dissociate ("playlist update", playlist_update_cb);
+
+ if (search_source)
+ {
+ g_source_remove (search_source);
+ search_source = 0;
+ }
+
+ search_terms.clear ();
+ items.clear ();
+ selection.clear ();
+
+ added_table.clear ();
+ destroy_database ();
+}
+
+static void do_add (gboolean play, String & title)
+{
+ if (search_source)
+ search_timeout ();
+
+ int list = aud_playlist_by_unique_id (playlist_id);
+ int n_items = items.len ();
+ int n_selected = 0;
+
+ Index<PlaylistAddItem> add;
+
+ for (int i = 0; i < n_items; i ++)
+ {
+ if (! selection[i])
+ continue;
+
+ const Item * item = items[i];
+
+ for (int entry : item->matches)
+ {
+ add.append (
+ aud_playlist_entry_get_filename (list, entry),
+ aud_playlist_entry_get_tuple (list, entry, Playlist::Guess)
+ );
+ }
+
+ n_selected ++;
+ if (n_selected == 1)
+ title = item->name;
+ }
+
+ if (n_selected != 1)
+ title = String ();
+
+ aud_playlist_entry_insert_batch (aud_playlist_get_active (), -1, std::move (add), play);
+}
+
+static void action_play ()
+{
+ int list = aud_playlist_get_temporary ();
+ aud_playlist_set_active (list);
+
+ if (aud_get_bool (nullptr, "clear_playlist"))
+ aud_playlist_entry_delete (list, 0, aud_playlist_entry_count (list));
+ else
+ aud_playlist_queue_delete (list, 0, aud_playlist_queue_count (list));
+
+ String title;
+ do_add (true, title);
+}
+
+static void action_create_playlist ()
+{
+ aud_playlist_insert (-1);
+ aud_playlist_set_active (aud_playlist_count () - 1);
+
+ String title;
+ do_add (false, title);
+
+ if (title)
+ aud_playlist_set_title (aud_playlist_count () - 1, title);
+}
+
+static void action_add_to_playlist ()
+{
+ if (aud_playlist_by_unique_id (playlist_id) == aud_playlist_get_active ())
+ return;
+
+ String title;
+ do_add (false, title);
+}
+
+static void list_get_value (void * user, int row, int column, GValue * value)
+{
+ g_return_if_fail (row >= 0 && row < items.len ());
+
+ const Item * item = items[row];
+ StringBuf string = str_concat ({item->name, "\n"});
+
+ if (item->field != SearchField::Title)
+ {
+ string.insert (-1, " ");
+ string.combine (str_printf (dngettext (PACKAGE, "%d song", "%d songs",
+ item->matches.len ()), item->matches.len ()));
+ }
+
+ if (item->field == SearchField::Genre)
+ {
+ string.insert (-1, " ");
+ string.insert (-1, _("of this genre"));
+ }
+
+ while ((item = item->parent))
+ {
+ string.insert (-1, " ");
+ string.insert (-1, (item->field == SearchField::Album) ? _("on") : _("by"));
+ string.insert (-1, " ");
+ string.insert (-1, item->name);
+ }
+
+ g_value_set_string (value, string);
+}
+
+static bool list_get_selected (void * user, int row)
+{
+ g_return_val_if_fail (row >= 0 && row < selection.len (), false);
+ return selection[row];
+}
+
+static void list_set_selected (void * user, int row, bool selected)
+{
+ g_return_if_fail (row >= 0 && row < selection.len ());
+ selection[row] = selected;
+}
+
+static void list_select_all (void * user, bool selected)
+{
+ for (bool & s : selection)
+ s = selected;
+}
+
+static void list_activate_row (void * user, int row)
+{
+ action_play ();
+}
+
+static void list_right_click (void * user, GdkEventButton * event)
+{
+ static const AudguiMenuItem items[] = {
+ MenuCommand (N_("_Play"), "media-playback-start",
+ 0, (GdkModifierType) 0, action_play),
+ MenuCommand (N_("_Create Playlist"), "document-new",
+ 0, (GdkModifierType) 0, action_create_playlist),
+ MenuCommand (N_("_Add to Playlist"), "list-add",
+ 0, (GdkModifierType) 0, action_add_to_playlist)
+ };
+
+ GtkWidget * menu = gtk_menu_new ();
+ audgui_menu_init (menu, {items}, nullptr);
+ gtk_menu_popup ((GtkMenu *) menu, nullptr, nullptr, nullptr, nullptr, event->button, event->time);
+}
+
+static const AudguiListCallbacks list_callbacks = {
+ list_get_value,
+ list_get_selected,
+ list_set_selected,
+ list_select_all,
+ list_activate_row,
+ list_right_click
+};
+
+static void entry_cb (GtkEntry * entry, void * unused)
+{
+ set_search_phrase (gtk_entry_get_text ((GtkEntry *) entry));
+ schedule_search ();
+}
+
+static void refresh_cb (GtkButton * button, GtkWidget * chooser)
+{
+ char * path = gtk_file_chooser_get_filename ((GtkFileChooser *) chooser);
+ begin_add (path);
+ g_free (path);
+
+ update_database ();
+}
+
+void * SearchTool::get_gtk_widget ()
+{
+ GtkWidget * vbox = gtk_vbox_new (FALSE, 6);
+
+ entry = gtk_entry_new ();
+ gtk_entry_set_icon_from_icon_name ((GtkEntry *) entry, GTK_ENTRY_ICON_PRIMARY, "edit-find");
+ (void) _("Search library"); // translated string is used in GTK3 branch
+ g_signal_connect (entry, "destroy", (GCallback) gtk_widget_destroyed, & entry);
+ gtk_box_pack_start ((GtkBox *) vbox, entry, FALSE, FALSE, 0);
+
+ help_label = gtk_label_new (_("To import your music library into "
+ "Audacious, choose a folder and then click the \"refresh\" icon."));
+ gtk_widget_set_size_request (help_label, 194, -1);
+ gtk_label_set_line_wrap ((GtkLabel *) help_label, TRUE);
+ g_signal_connect (help_label, "destroy", (GCallback) gtk_widget_destroyed, & help_label);
+ gtk_widget_set_no_show_all (help_label, TRUE);
+ gtk_box_pack_start ((GtkBox *) vbox, help_label, TRUE, FALSE, 0);
+
+ wait_label = gtk_label_new (_("Please wait ..."));
+ g_signal_connect (wait_label, "destroy", (GCallback) gtk_widget_destroyed, & wait_label);
+ gtk_widget_set_no_show_all (wait_label, TRUE);
+ gtk_box_pack_start ((GtkBox *) vbox, wait_label, TRUE, FALSE, 0);
+
+ scrolled = gtk_scrolled_window_new (nullptr, nullptr);
+ g_signal_connect (scrolled, "destroy", (GCallback) gtk_widget_destroyed, & scrolled);
+ gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled, GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrolled,
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_widget_set_no_show_all (scrolled, TRUE);
+ gtk_box_pack_start ((GtkBox *) vbox, scrolled, TRUE, TRUE, 0);
+
+ results_list = audgui_list_new (& list_callbacks, nullptr, items.len ());
+ g_signal_connect (results_list, "destroy", (GCallback) gtk_widget_destroyed, & results_list);
+ gtk_tree_view_set_headers_visible ((GtkTreeView *) results_list, FALSE);
+ audgui_list_add_column (results_list, nullptr, 0, G_TYPE_STRING, -1);
+ gtk_container_add ((GtkContainer *) scrolled, results_list);
+
+ stats_label = gtk_label_new ("");
+ g_signal_connect (stats_label, "destroy", (GCallback) gtk_widget_destroyed, & stats_label);
+ gtk_widget_set_no_show_all (stats_label, TRUE);
+ gtk_box_pack_start ((GtkBox *) vbox, stats_label, FALSE, FALSE, 0);
+
+ GtkWidget * hbox = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_end ((GtkBox *) vbox, hbox, FALSE, FALSE, 0);
+
+ GtkWidget * chooser = gtk_file_chooser_button_new (_("Choose Folder"),
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+ gtk_box_pack_start ((GtkBox *) hbox, chooser, TRUE, TRUE, 0);
+
+ gtk_file_chooser_set_filename ((GtkFileChooser *) chooser, get_path ());
+
+ GtkWidget * button = gtk_button_new ();
+ gtk_container_add ((GtkContainer *) button, gtk_image_new_from_icon_name
+ ("view-refresh", GTK_ICON_SIZE_BUTTON));
+ gtk_button_set_relief ((GtkButton *) button, GTK_RELIEF_NONE);
+ gtk_box_pack_start ((GtkBox *) hbox, button, FALSE, FALSE, 0);
+
+ search_init ();
+
+ g_signal_connect (vbox, "destroy", (GCallback) search_cleanup, nullptr);
+ g_signal_connect (entry, "changed", (GCallback) entry_cb, nullptr);
+ g_signal_connect (entry, "activate", (GCallback) action_play, nullptr);
+ g_signal_connect (button, "clicked", (GCallback) refresh_cb, chooser);
+
+ gtk_widget_show_all (vbox);
+ gtk_widget_show (results_list);
+ show_hide_widgets ();
+
+ return vbox;
+}
+
+int SearchTool::take_message (const char * code, const void * data, int size)
+{
+ if (! strcmp (code, "grab focus"))
+ {
+ if (entry)
+ gtk_widget_grab_focus (entry);
+ return 0;
+ }
+
+ return -1;
+}
diff --git a/src/sid/Makefile b/src/sid/Makefile
index e72b545ba571..d3f8e9ecef19 100644
--- a/src/sid/Makefile
+++ b/src/sid/Makefile
@@ -1,13 +1,8 @@
PLUGIN = sid${PLUGIN_SUFFIX}
-SRCS = xs_support.c \
- xs_config.c \
- xs_length.c \
- xs_md5.c \
- xs_stil.c \
+SRCS = xs_config.cc \
xs_sidplay2.cc \
- xs_slsup.c \
- xmms-sid.c
+ xmms-sid.cc
include ../../buildsys.mk
include ../../extra.mk
@@ -17,5 +12,5 @@ plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CXXFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} -DSIDDATADIR="\"$(datadir)/\"" -I../.. ${SIDPLAYFP_CFLAGS} ${GLIB_CFLAGS}
-LIBS += -lm ${SIDPLAYFP_LIBS} ${GLIB_LIBS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -DSIDDATADIR="\"$(datadir)/\"" -I../.. ${SIDPLAYFP_CFLAGS}
+LIBS += -lm ${SIDPLAYFP_LIBS}
diff --git a/src/sid/xmms-sid.c b/src/sid/xmms-sid.c
deleted file mode 100644
index 50ce3d16d815..000000000000
--- a/src/sid/xmms-sid.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
-
- Main source file
-
- Programmed and designed by Matti 'ccr' Hamalainen <ccr at tnsp.org>
- (C) Copyright 1999-2009 Tecnic Software productions (TNSP)
-
- 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 along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libaudcore/audstrings.h>
-#include <audacious/input.h>
-#include <audacious/plugin.h>
-
-#include "xs_sidplay2.h"
-
-
-/*
- * Global variables
- */
-xs_status_t xs_status;
-pthread_mutex_t xs_status_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static void xs_get_song_tuple_info(Tuple *pResult, xs_tuneinfo_t *pInfo, int subTune);
-
-/*
- * Initialization functions
- */
-bool_t xs_init(void)
-{
- bool_t success;
-
- /* Initialize and get configuration */
- xs_init_configuration();
-
- pthread_mutex_lock(&xs_status_mutex);
- pthread_mutex_lock(&xs_cfg_mutex);
-
- /* Initialize status and sanitize configuration */
- memset(&xs_status, 0, sizeof(xs_status));
-
- if (xs_cfg.audioFrequency < 8000)
- xs_cfg.audioFrequency = 8000;
-
- xs_status.audioFrequency = xs_cfg.audioFrequency;
- xs_status.audioChannels = xs_cfg.audioChannels;
-
- /* Try to initialize emulator engine */
- success = xs_sidplayfp_init(&xs_status);
-
- /* Get settings back, in case the chosen emulator backend changed them */
- xs_cfg.audioFrequency = xs_status.audioFrequency;
- xs_cfg.audioChannels = xs_status.audioChannels;
-
- pthread_mutex_unlock(&xs_status_mutex);
- pthread_mutex_unlock(&xs_cfg_mutex);
-
- if (! success)
- return FALSE;
-
- /* Initialize song-length database */
- xs_songlen_close();
- if (xs_cfg.songlenDBEnable && (xs_songlen_init() != 0)) {
- xs_error("Error initializing song-length database!\n");
- }
-
- /* Initialize STIL database */
- xs_stil_close();
- if (xs_cfg.stilDBEnable && (xs_stil_init() != 0)) {
- xs_error("Error initializing STIL database!\n");
- }
-
- return TRUE;
-}
-
-
-/*
- * Shut down XMMS-SID
- */
-void xs_close(void)
-{
- xs_tuneinfo_free(xs_status.tuneInfo);
- xs_status.tuneInfo = NULL;
-
- xs_sidplayfp_delete (& xs_status);
- xs_sidplayfp_close (& xs_status);
-
- xs_songlen_close();
- xs_stil_close();
-}
-
-
-/*
- * Start playing the given file
- */
-bool_t xs_play_file(const char *filename, VFSFile *file)
-{
- xs_tuneinfo_t *tmpTune;
- int audioBufSize, bufRemaining, tmpLength, subTune = -1;
- char *audioBuffer = NULL, *oversampleBuffer = NULL;
- Tuple *tmpTuple;
-
- uri_parse (filename, NULL, NULL, NULL, & subTune);
-
- /* Get tune information */
- pthread_mutex_lock(&xs_status_mutex);
-
- if (! (xs_status.tuneInfo = xs_sidplayfp_getinfo (filename)))
- {
- pthread_mutex_unlock(&xs_status_mutex);
- return FALSE;
- }
-
- /* Initialize the tune */
- if (! xs_sidplayfp_load (& xs_status, filename))
- {
- pthread_mutex_unlock(&xs_status_mutex);
- xs_tuneinfo_free(xs_status.tuneInfo);
- xs_status.tuneInfo = NULL;
- return FALSE;
- }
-
- bool_t error = FALSE;
-
- /* Set general status information */
- tmpTune = xs_status.tuneInfo;
-
- if (subTune < 1 || subTune > xs_status.tuneInfo->nsubTunes)
- xs_status.currSong = xs_status.tuneInfo->startTune;
- else
- xs_status.currSong = subTune;
-
- int channels = xs_status.audioChannels;
-
- /* Allocate audio buffer */
- audioBufSize = xs_status.audioFrequency * channels * FMT_SIZEOF (FMT_S16_NE);
- if (audioBufSize < 512) audioBufSize = 512;
-
- audioBuffer = (char *) malloc(audioBufSize);
- if (audioBuffer == NULL) {
- xs_error("Couldn't allocate memory for audio data buffer!\n");
- pthread_mutex_unlock(&xs_status_mutex);
- goto xs_err_exit;
- }
-
- /* Check minimum playtime */
- tmpLength = tmpTune->subTunes[xs_status.currSong - 1].tuneLength;
- if (xs_cfg.playMinTimeEnable && (tmpLength >= 0)) {
- if (tmpLength < xs_cfg.playMinTime)
- tmpLength = xs_cfg.playMinTime;
- }
-
- /* Initialize song */
- if (!xs_sidplayfp_initsong(&xs_status)) {
- xs_error("Couldn't initialize SID-tune '%s' (sub-tune #%i)!\n",
- tmpTune->sidFilename, xs_status.currSong);
- pthread_mutex_unlock(&xs_status_mutex);
- goto xs_err_exit;
- }
-
- /* Open the audio output */
- if (!aud_input_open_audio(FMT_S16_NE, xs_status.audioFrequency, channels))
- {
- xs_error("Couldn't open audio output (fmt=%x, freq=%i, nchan=%i)!\n",
- FMT_S16_NE,
- xs_status.audioFrequency,
- channels);
-
- pthread_mutex_unlock(&xs_status_mutex);
- goto xs_err_exit;
- }
-
- /* Set song information for current subtune */
- xs_sidplayfp_updateinfo(&xs_status);
- tmpTuple = tuple_new_from_filename(tmpTune->sidFilename);
- xs_get_song_tuple_info(tmpTuple, tmpTune, xs_status.currSong);
-
- pthread_mutex_unlock(&xs_status_mutex);
-
- aud_input_set_tuple(tmpTuple);
-
- while (! aud_input_check_stop ())
- {
- bufRemaining = xs_sidplayfp_fillbuffer(&xs_status, audioBuffer, audioBufSize);
-
- aud_input_write_audio (audioBuffer, bufRemaining);
-
- /* Check if we have played enough */
- if (xs_cfg.playMaxTimeEnable) {
- if (xs_cfg.playMaxTimeUnknown) {
- if (tmpLength < 0 &&
- aud_input_written_time() >= xs_cfg.playMaxTime * 1000)
- break;
- } else {
- if (aud_input_written_time() >= xs_cfg.playMaxTime * 1000)
- break;
- }
- }
-
- if (tmpLength >= 0) {
- if (aud_input_written_time() >= tmpLength * 1000)
- break;
- }
- }
-
-DONE:
- free(audioBuffer);
- free(oversampleBuffer);
-
- /* Set playing status to false (stopped), thus when
- * XMMS next calls xs_get_time(), it can return appropriate
- * value "not playing" status and XMMS knows to move to
- * next entry in the playlist .. or whatever it wishes.
- */
- pthread_mutex_lock(&xs_status_mutex);
-
- /* Free tune information */
- xs_sidplayfp_delete(&xs_status);
- xs_tuneinfo_free(xs_status.tuneInfo);
- xs_status.tuneInfo = NULL;
- pthread_mutex_unlock(&xs_status_mutex);
-
- /* Exit the playing thread */
- return ! error;
-
-xs_err_exit:
- error = TRUE;
- goto DONE;
-}
-
-
-/*
- * Return song information Tuple
- */
-static void xs_get_song_tuple_info(Tuple *tuple, xs_tuneinfo_t *info, int subTune)
-{
- tuple_set_str(tuple, FIELD_TITLE, info->sidName);
- tuple_set_str(tuple, FIELD_ARTIST, info->sidComposer);
- tuple_set_str(tuple, FIELD_COPYRIGHT, info->sidCopyright);
- tuple_set_str(tuple, FIELD_CODEC, info->sidFormat);
-
-#if 0
- switch (info->sidModel) {
- case XS_SIDMODEL_6581: tmpStr = "6581"; break;
- case XS_SIDMODEL_8580: tmpStr = "8580"; break;
- case XS_SIDMODEL_ANY: tmpStr = "ANY"; break;
- default: tmpStr = "?"; break;
- }
- tuple_set_str(tuple, -1, "sid-model", tmpStr);
-#endif
-
- /* Get sub-tune information, if available */
- if (subTune < 0 || info->startTune > info->nsubTunes)
- subTune = info->startTune;
-
- if (subTune > 0 && subTune <= info->nsubTunes) {
- int tmpInt = info->subTunes[subTune - 1].tuneLength;
- tuple_set_int(tuple, FIELD_LENGTH, (tmpInt < 0) ? -1 : tmpInt * 1000);
-
-#if 0
- tmpInt = info->subTunes[subTune - 1].tuneSpeed;
- if (tmpInt > 0) {
- switch (tmpInt) {
- case XS_CLOCK_PAL: tmpStr = "PAL"; break;
- case XS_CLOCK_NTSC: tmpStr = "NTSC"; break;
- case XS_CLOCK_ANY: tmpStr = "ANY"; break;
- case XS_CLOCK_VBI: tmpStr = "VBI"; break;
- case XS_CLOCK_CIA: tmpStr = "CIA"; break;
- default:
- snprintf(tmpStr2, sizeof(tmpStr2), "%dHz", tmpInt);
- tmpStr = tmpStr2;
- break;
- }
- } else
- tmpStr = "?";
-
- tuple_set_str(tuple, -1, "sid-speed", tmpStr);
-#endif
- } else
- subTune = 1;
-
- tuple_set_int(tuple, FIELD_SUBSONG_NUM, info->nsubTunes);
- tuple_set_int(tuple, FIELD_SUBSONG_ID, subTune);
- tuple_set_int(tuple, FIELD_TRACK_NUMBER, subTune);
-}
-
-
-static void xs_fill_subtunes(Tuple *tuple, xs_tuneinfo_t *info)
-{
- int count, found;
- int subtunes[info->nsubTunes];
-
- for (found = count = 0; count < info->nsubTunes; count++) {
- if (count + 1 == info->startTune || !xs_cfg.subAutoMinOnly ||
- info->subTunes[count].tuneLength < 0 ||
- info->subTunes[count].tuneLength >= xs_cfg.subAutoMinTime)
- subtunes[found ++] = count + 1;
- }
-
- tuple_set_subtunes (tuple, found, subtunes);
-}
-
-Tuple * xs_probe_for_tuple(const char *filename, VFSFile *fd)
-{
- Tuple *tuple;
- xs_tuneinfo_t *info;
- int tune = -1;
-
- pthread_mutex_lock(&xs_status_mutex);
- if (!xs_sidplayfp_probe(fd)) {
- pthread_mutex_unlock(&xs_status_mutex);
- return NULL;
- }
- pthread_mutex_unlock(&xs_status_mutex);
-
- /* Get information from URL */
- tuple = tuple_new_from_filename (filename);
- tune = tuple_get_int (tuple, FIELD_SUBSONG_NUM);
-
- /* Get tune information from emulation engine */
- pthread_mutex_lock(&xs_status_mutex);
- info = xs_sidplayfp_getinfo (filename);
- pthread_mutex_unlock(&xs_status_mutex);
-
- if (info == NULL)
- return tuple;
-
- xs_get_song_tuple_info(tuple, info, tune);
-
- if (xs_cfg.subAutoEnable && info->nsubTunes > 1 && ! tune)
- xs_fill_subtunes(tuple, info);
-
- xs_tuneinfo_free(info);
-
- return tuple;
-}
-
-/*
- * Plugin header
- */
-static const char *xs_sid_fmts[] = { "sid", "psid", NULL };
-
-AUD_INPUT_PLUGIN
-(
- .name = "SID Player", /* Plugin description */
- .domain = PACKAGE,
- .init = xs_init, /* Initialization */
- .cleanup = xs_close, /* Cleanup */
- .play = xs_play_file, /* Play given file */
- .probe_for_tuple = xs_probe_for_tuple,
-
- .extensions = xs_sid_fmts, /* File ext assist */
- .have_subtune = TRUE,
-
- /* medium priority (slow to initialize) */
- .priority = 5,
-)
diff --git a/src/sid/xmms-sid.cc b/src/sid/xmms-sid.cc
new file mode 100644
index 000000000000..f1f59e96f028
--- /dev/null
+++ b/src/sid/xmms-sid.cc
@@ -0,0 +1,326 @@
+/*
+ XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
+
+ Main source file
+
+ Programmed and designed by Matti 'ccr' Hamalainen <ccr at tnsp.org>
+ (C) Copyright 1999-2009 Tecnic Software productions (TNSP)
+
+ 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 along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <assert.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+#include "xs_config.h"
+#include "xs_sidplay2.h"
+
+class SIDPlugin : public InputPlugin
+{
+public:
+ static const char *const exts[];
+
+ static constexpr PluginInfo info = {
+ N_("SID Player"),
+ PACKAGE,
+ nullptr,
+ & sid_prefs
+ };
+
+ static constexpr auto iinfo = InputInfo(FlagSubtunes)
+ .with_priority(5) /* medium priority (slow to initialize) */
+ .with_exts(exts);
+
+ constexpr SIDPlugin() : InputPlugin(info, iinfo) {}
+
+ bool delayed_init();
+ void cleanup();
+
+ bool is_our_file(const char *filename, VFSFile &file);
+ Tuple read_tuple(const char *filename, VFSFile &file);
+ bool play(const char *filename, VFSFile &file);
+
+private:
+ pthread_mutex_t m_init_mutex = PTHREAD_MUTEX_INITIALIZER;
+ bool m_initialized = false;
+ bool m_init_failed = false;
+};
+
+EXPORT SIDPlugin aud_plugin_instance;
+
+static void xs_get_song_tuple_info(Tuple &pResult, const xs_tuneinfo_t &info, int subTune);
+
+/*
+ * Initialization functions
+ */
+bool SIDPlugin::delayed_init()
+{
+ pthread_mutex_lock(&m_init_mutex);
+
+ if (!m_initialized && !m_init_failed)
+ {
+ /* Initialize and get configuration */
+ xs_init_configuration();
+
+ /* Try to initialize emulator engine */
+ m_initialized = xs_sidplayfp_init();
+ if (!m_initialized)
+ m_init_failed = true;
+ }
+
+ pthread_mutex_unlock(&m_init_mutex);
+ return m_initialized;
+}
+
+
+/*
+ * Shut down XMMS-SID
+ */
+void SIDPlugin::cleanup()
+{
+ if (m_initialized)
+ {
+ xs_sidplayfp_close();
+ m_initialized = false;
+ }
+
+ m_init_failed = false;
+}
+
+
+/*
+ * Check whether this is a SID file
+ */
+bool SIDPlugin::is_our_file(const char *filename, VFSFile &file)
+{
+ char buf[4];
+ if (file.fread (buf, 1, 4) != 4)
+ return false;
+
+ // does not require xs_sidplayfp_init()
+ return xs_sidplayfp_probe(buf, 4);
+}
+
+
+/*
+ * Start playing the given file
+ */
+bool SIDPlugin::play(const char *filename, VFSFile &file)
+{
+ if (!delayed_init())
+ return false;
+
+ /* Load file */
+ Index<char> buf = file.read_all ();
+ if (!xs_sidplayfp_probe(buf.begin(), buf.len()))
+ return false;
+
+ /* Get tune information */
+ xs_tuneinfo_t info;
+ if (!xs_sidplayfp_getinfo(info, filename, buf.begin(), buf.len()))
+ return false;
+
+ /* Initialize the tune */
+ if (!xs_sidplayfp_load(buf.begin(), buf.len()))
+ return false;
+
+ /* Set general status information */
+ int subTune = -1;
+ uri_parse(filename, nullptr, nullptr, nullptr, &subTune);
+
+ if (subTune < 1 || subTune > info.nsubTunes)
+ subTune = info.startTune;
+
+ /* Check minimum playtime */
+ int tmpLength = info.subTunes[subTune - 1].tuneLength;
+ if (xs_cfg.playMinTimeEnable && (tmpLength >= 0)) {
+ if (tmpLength < xs_cfg.playMinTime)
+ tmpLength = xs_cfg.playMinTime;
+ }
+
+ /* Initialize song */
+ if (!xs_sidplayfp_initsong(subTune)) {
+ AUDERR("Couldn't initialize SID-tune '%s' (sub-tune #%i)!\n",
+ (const char *) info.sidFilename, subTune);
+ return false;
+ }
+
+ /* Set song information for current subtune */
+ xs_sidplayfp_updateinfo(info, subTune);
+
+ Tuple tmpTuple;
+ tmpTuple.set_filename(info.sidFilename);
+ xs_get_song_tuple_info(tmpTuple, info, subTune);
+ set_playback_tuple(std::move(tmpTuple));
+
+ /* Open the audio output */
+ open_audio(FMT_S16_NE, xs_cfg.audioFrequency, xs_cfg.audioChannels);
+
+ /* Allocate audio buffer */
+ int audioBufSize = xs_cfg.audioFrequency * xs_cfg.audioChannels * 2;
+ if (audioBufSize < 512)
+ audioBufSize = 512;
+
+ char *audioBuffer = new char[audioBufSize];
+ int64_t bytes_played = 0;
+
+ while (! check_stop ())
+ {
+ if (check_seek () >= 0)
+ AUDWARN ("Seeking is not implemented, ignoring.\n");
+
+ int bufRemaining = xs_sidplayfp_fillbuffer(audioBuffer, audioBufSize);
+
+ write_audio (audioBuffer, bufRemaining);
+ bytes_played += bufRemaining;
+
+ /* Check if we have played enough */
+ int time_played = aud::rescale<int64_t> (bytes_played,
+ xs_cfg.audioFrequency * xs_cfg.audioChannels * 2, 1000);
+
+ if (xs_cfg.playMaxTimeEnable) {
+ if (xs_cfg.playMaxTimeUnknown) {
+ if (tmpLength < 0 &&
+ time_played >= xs_cfg.playMaxTime * 1000)
+ break;
+ } else {
+ if (time_played >= xs_cfg.playMaxTime * 1000)
+ break;
+ }
+ }
+
+ if (tmpLength >= 0) {
+ if (time_played >= tmpLength * 1000)
+ break;
+ }
+ }
+
+ delete[] audioBuffer;
+
+ return true;
+}
+
+
+/*
+ * Return song information Tuple
+ */
+static void xs_get_song_tuple_info(Tuple &tuple, const xs_tuneinfo_t &info, int subTune)
+{
+ tuple.set_str (Tuple::Title, info.sidName);
+ tuple.set_str (Tuple::Artist, info.sidComposer);
+ tuple.set_str (Tuple::Copyright, info.sidCopyright);
+ tuple.set_str (Tuple::Codec, info.sidFormat);
+
+#if 0
+ switch (info.sidModel) {
+ case XS_SIDMODEL_6581: tmpStr = "6581"; break;
+ case XS_SIDMODEL_8580: tmpStr = "8580"; break;
+ case XS_SIDMODEL_ANY: tmpStr = "ANY"; break;
+ default: tmpStr = "?"; break;
+ }
+ tuple_set_str(tuple, -1, "sid-model", tmpStr);
+#endif
+
+ /* Get sub-tune information, if available */
+ if (subTune < 0 || info.startTune > info.nsubTunes)
+ subTune = info.startTune;
+
+ if (subTune > 0 && subTune <= info.nsubTunes) {
+ int tmpInt = info.subTunes[subTune - 1].tuneLength;
+ tuple.set_int (Tuple::Length, (tmpInt < 0) ? -1 : tmpInt * 1000);
+
+#if 0
+ tmpInt = info.subTunes[subTune - 1].tuneSpeed;
+ if (tmpInt > 0) {
+ switch (tmpInt) {
+ case XS_CLOCK_PAL: tmpStr = "PAL"; break;
+ case XS_CLOCK_NTSC: tmpStr = "NTSC"; break;
+ case XS_CLOCK_ANY: tmpStr = "ANY"; break;
+ case XS_CLOCK_VBI: tmpStr = "VBI"; break;
+ case XS_CLOCK_CIA: tmpStr = "CIA"; break;
+ default:
+ snprintf(tmpStr2, sizeof(tmpStr2), "%dHz", tmpInt);
+ tmpStr = tmpStr2;
+ break;
+ }
+ } else
+ tmpStr = "?";
+
+ tuple_set_str(tuple, -1, "sid-speed", tmpStr);
+#endif
+ } else
+ subTune = 1;
+
+ tuple.set_int (Tuple::NumSubtunes, info.nsubTunes);
+ tuple.set_int (Tuple::Subtune, subTune);
+ tuple.set_int (Tuple::Track, subTune);
+}
+
+
+static void xs_fill_subtunes(Tuple &tuple, const xs_tuneinfo_t &info)
+{
+ Index<int> subtunes;
+
+ for (int count = 0; count < info.nsubTunes; count++) {
+ if (count + 1 == info.startTune || !xs_cfg.subAutoMinOnly ||
+ info.subTunes[count].tuneLength < 0 ||
+ info.subTunes[count].tuneLength >= xs_cfg.subAutoMinTime)
+ subtunes.append (count + 1);
+ }
+
+ tuple.set_subtunes (subtunes.len (), subtunes.begin ());
+}
+
+Tuple SIDPlugin::read_tuple(const char *filename, VFSFile &file)
+{
+ Tuple tuple;
+
+ if (!delayed_init())
+ return tuple;
+
+ xs_tuneinfo_t info;
+ int tune = -1;
+
+ Index<char> buf = file.read_all ();
+ if (!xs_sidplayfp_probe(buf.begin(), buf.len()))
+ return tuple;
+
+ /* Get information from URL */
+ tuple.set_filename (filename);
+ tune = tuple.get_int (Tuple::Subtune);
+
+ /* Get tune information from emulation engine */
+ if (!xs_sidplayfp_getinfo(info, filename, buf.begin(), buf.len()))
+ return tuple;
+
+ xs_get_song_tuple_info(tuple, info, tune);
+
+ if (xs_cfg.subAutoEnable && info.nsubTunes > 1 && tune < 0)
+ xs_fill_subtunes(tuple, info);
+
+ return tuple;
+}
+
+/*
+ * Plugin header
+ */
+const char *const SIDPlugin::exts[] = { "sid", "psid", nullptr };
diff --git a/src/sid/xmms-sid.h b/src/sid/xmms-sid.h
index 0093055478c9..13553ee74db5 100644
--- a/src/sid/xmms-sid.h
+++ b/src/sid/xmms-sid.h
@@ -23,48 +23,29 @@
#ifndef XMMS_SID_H
#define XMMS_SID_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <libaudcore/core.h>
+#include <libaudcore/index.h>
+#include <libaudcore/objects.h>
/*
* Some constants and defines
*/
-/* Size for some small buffers (always static variables) */
-#define XS_BUF_SIZE (2048)
-
/* Default audio rendering frequency in Hz
*/
#define XS_AUDIO_FREQ (44100)
-/* Size of data buffer used for SID-tune MD5 hash calculation.
- * If this is too small, the computed hash will be incorrect.
- * Largest SID files I've seen are ~70kB. */
-#define XS_SIDBUF_SIZE (128*1024)
-
/* Plugin-wide typedefs
*/
typedef struct {
- int tuneSpeed, tuneLength;
- bool_t tunePlayed;
+ int tuneSpeed = -1;
+ int tuneLength = -1;
} xs_subtuneinfo_t;
typedef struct {
- char *sidFilename, *sidName, *sidComposer, *sidCopyright, *sidFormat;
+ String sidFilename, sidName, sidComposer, sidCopyright, sidFormat;
int loadAddr, initAddr, playAddr, dataFileLen, sidModel;
int nsubTunes, startTune;
- xs_subtuneinfo_t *subTunes;
+ Index<xs_subtuneinfo_t> subTunes;
} xs_tuneinfo_t;
-/* Plugin function prototypes
- */
-#define xs_verror(fmt, args) vfprintf(stderr, fmt, args)
-#define xs_error(...) fprintf(stderr, __VA_ARGS__)
-
-#ifdef __cplusplus
-}
-#endif
#endif /* XMMS_SID_H */
diff --git a/src/sid/xs_config.c b/src/sid/xs_config.c
deleted file mode 100644
index 1e663b437938..000000000000
--- a/src/sid/xs_config.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
-
- Configuration dialog
-
- Programmed and designed by Matti 'ccr' Hamalainen <ccr at tnsp.org>
- (C) Copyright 1999-2009 Tecnic Software productions (TNSP)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "xs_config.h"
-
-#include <string.h>
-
-#include "xmms-sid.h"
-#include "xs_support.h"
-
-/*
- * Configuration specific stuff
- */
-pthread_mutex_t xs_cfg_mutex = PTHREAD_MUTEX_INITIALIZER;
-struct xs_cfg_t xs_cfg;
-
-/* Reset/initialize the configuration
- */
-void xs_init_configuration(void)
-{
- /* Lock configuration mutex */
- pthread_mutex_lock(&xs_cfg_mutex);
-
- memset(&xs_cfg, 0, sizeof(xs_cfg));
-
- /* Initialize values with sensible defaults */
- xs_cfg.audioChannels = XS_CHN_STEREO;
- xs_cfg.audioFrequency = XS_AUDIO_FREQ;
-
- xs_cfg.mos8580 = FALSE;
- xs_cfg.forceModel = FALSE;
-
- /* Filter values */
- xs_cfg.emulateFilters = TRUE;
-
- xs_cfg.clockSpeed = XS_CLOCK_PAL;
- xs_cfg.forceSpeed = FALSE;
-
- xs_cfg.playMaxTimeEnable = FALSE;
- xs_cfg.playMaxTimeUnknown = FALSE;
- xs_cfg.playMaxTime = 150;
-
- xs_cfg.playMinTimeEnable = FALSE;
- xs_cfg.playMinTime = 15;
-
- xs_cfg.songlenDBEnable = FALSE;
- xs_pstrcpy(&xs_cfg.songlenDBPath, "~/C64Music/DOCUMENTS/Songlengths.txt");
-
- xs_cfg.stilDBEnable = FALSE;
- xs_pstrcpy(&xs_cfg.stilDBPath, "~/C64Music/DOCUMENTS/STIL.txt");
- xs_pstrcpy(&xs_cfg.hvscPath, "~/C64Music");
-
- xs_cfg.subAutoEnable = TRUE;
- xs_cfg.subAutoMinOnly = TRUE;
- xs_cfg.subAutoMinTime = 15;
-
- /* Unlock the configuration */
- pthread_mutex_unlock(&xs_cfg_mutex);
-}
diff --git a/src/sid/xs_config.cc b/src/sid/xs_config.cc
new file mode 100644
index 000000000000..f91062210458
--- /dev/null
+++ b/src/sid/xs_config.cc
@@ -0,0 +1,140 @@
+/*
+ XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
+
+ Configuration dialog
+
+ Programmed and designed by Matti 'ccr' Hamalainen <ccr at tnsp.org>
+ (C) Copyright 1999-2009 Tecnic Software productions (TNSP)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "xmms-sid.h"
+#include "xs_config.h"
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/runtime.h>
+
+/*
+ * Configuration specific stuff
+ */
+struct xs_cfg_t xs_cfg;
+
+static constexpr const char * const defaults[] = {
+ "audioChannels", aud::numeric_string<XS_CHN_STEREO>::str,
+ "audioFrequency", aud::numeric_string<XS_AUDIO_FREQ>::str,
+ "mos8580", "FALSE",
+ "forceModel", "FALSE",
+ "emulateFilters", "TRUE",
+ "clockSpeed", aud::numeric_string<XS_CLOCK_PAL>::str,
+ "forceSpeed", "FALSE",
+ "playMaxTimeEnable", "FALSE",
+ "playMaxTimeUnknown", "FALSE",
+ "playMaxTime", "150",
+ "playMinTimeEnable", "FALSE",
+ "playMinTime", "15",
+ "subAutoEnable", "TRUE",
+ "subAutoMinOnly", "TRUE",
+ "subAutoMinTime", "15",
+ nullptr
+};
+
+static constexpr ComboItem clock_speeds[] = {
+ {"NTSC", XS_CLOCK_NTSC},
+ {"PAL", XS_CLOCK_PAL}
+};
+
+static constexpr PreferencesWidget widgets[] = {
+ WidgetLabel(N_("<b>Output</b>")),
+ WidgetSpin(N_("Channels:"),
+ WidgetInt("sid", "audioChannels"),
+ {1, 2, 1}),
+ WidgetSpin(N_("Sample rate:"),
+ WidgetInt("sid", "audioFrequency"),
+ {8000, 96000, 25, N_("Hz")}),
+ WidgetLabel(N_("<b>Emulation</b>")),
+ WidgetCheck(N_("Emulate MOS 8580 (default: MOS 6581)"),
+ WidgetBool("sid", "mos8580")),
+ WidgetCheck(N_("Do not automatically select chip model"),
+ WidgetBool("sid", "forceModel")),
+ WidgetCheck(N_("Emulate filter"),
+ WidgetBool("sid", "emulateFilters")),
+ WidgetCombo(N_("Clock speed:"),
+ WidgetInt("sid", "clockSpeed"),
+ {{clock_speeds}}),
+ WidgetCheck(N_("Do not automatically select clock speed"),
+ WidgetBool("sid", "forceSpeed")),
+ WidgetLabel(N_("<b>Playback time</b>")),
+ WidgetCheck(N_("Set maximum playback time:"),
+ WidgetBool("sid", "playMaxTimeEnable")),
+ WidgetSpin(nullptr,
+ WidgetInt("sid", "playMaxTime"),
+ {5, 3600, 5, N_("seconds")},
+ WIDGET_CHILD),
+ WidgetCheck(N_("Use only when song length is unknown"),
+ WidgetBool("sid", "playMaxTimeUnknown"),
+ WIDGET_CHILD),
+ WidgetCheck(N_("Set minimum playback time:"),
+ WidgetBool("sid", "playMinTimeEnable")),
+ WidgetSpin(nullptr,
+ WidgetInt("sid", "playMinTime"),
+ {5, 3600, 5, N_("seconds")},
+ WIDGET_CHILD),
+ WidgetLabel(N_("<b>Subtunes</b>")),
+ WidgetCheck(N_("Enable subtunes"),
+ WidgetBool("sid", "subAutoEnable")),
+ WidgetCheck(N_("Ignore subtunes shorter than:"),
+ WidgetBool("sid", "subAutoMinOnly")),
+ WidgetSpin(nullptr,
+ WidgetInt("sid", "subAutoMinTime"),
+ {5, 3600, 5, N_("seconds")},
+ WIDGET_CHILD),
+ WidgetLabel(N_("<b>Note</b>")),
+ WidgetLabel(N_("These settings will take effect when Audacious is restarted."))
+};
+
+const PluginPreferences sid_prefs = {{widgets}};
+
+/* Reset/initialize the configuration
+ */
+void xs_init_configuration(void)
+{
+ aud_config_set_defaults("sid", defaults);
+
+ /* Initialize values with sensible defaults */
+ xs_cfg.audioChannels = aud_get_int("sid", "audioChannels");
+ xs_cfg.audioFrequency = aud_get_int("sid", "audioFrequency");
+
+ xs_cfg.mos8580 = aud_get_bool("sid", "mos8580");
+ xs_cfg.forceModel = aud_get_bool("sid", "forceModel");
+
+ /* Filter values */
+ xs_cfg.emulateFilters = aud_get_bool("sid", "emulateFilters");
+
+ xs_cfg.clockSpeed = aud_get_int("sid", "clockSpeed");
+ xs_cfg.forceSpeed = aud_get_bool("sid", "forceSpeed");
+
+ xs_cfg.playMaxTimeEnable = aud_get_bool("sid", "playMaxTimeEnable");
+ xs_cfg.playMaxTimeUnknown = aud_get_bool("sid", "playMaxTimeUnknown");
+ xs_cfg.playMaxTime = aud_get_int("sid", "playMaxTime");
+
+ xs_cfg.playMinTimeEnable = aud_get_bool("sid", "playMinTimeEnable");
+ xs_cfg.playMinTime = aud_get_int("sid", "playMinTime");
+
+ xs_cfg.subAutoEnable = aud_get_bool("sid", "subAutoEnable");
+ xs_cfg.subAutoMinOnly = aud_get_bool("sid", "subAutoMinOnly");
+ xs_cfg.subAutoMinTime = aud_get_int("sid", "subAutoMinTime");
+}
diff --git a/src/sid/xs_config.h b/src/sid/xs_config.h
index d4b8a92f0c8f..6570b1ce4f28 100644
--- a/src/sid/xs_config.h
+++ b/src/sid/xs_config.h
@@ -1,14 +1,6 @@
#ifndef XS_CONFIG_H
#define XS_CONFIG_H
-#include <pthread.h>
-#include <libaudcore/core.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
/* Configuration structure
*/
enum XS_CHANNELS {
@@ -40,42 +32,33 @@ extern struct xs_cfg_t {
int audioFrequency;
/* Emulation settings */
- bool_t mos8580; /* TRUE = 8580, FALSE = 6581 */
- bool_t forceModel;
+ bool mos8580; /* true = 8580, false = 6581 */
+ bool forceModel;
int clockSpeed; /* PAL (50Hz) or NTSC (60Hz) */
- bool_t forceSpeed; /* TRUE = force to given clockspeed */
+ bool forceSpeed; /* true = force to given clockspeed */
- bool_t emulateFilters;
+ bool emulateFilters;
/* Playing settings */
- bool_t playMaxTimeEnable,
+ bool playMaxTimeEnable,
playMaxTimeUnknown; /* Use max-time only when song-length is unknown */
int playMaxTime; /* MAX playtime in seconds */
- bool_t playMinTimeEnable;
+ bool playMinTimeEnable;
int playMinTime; /* MIN playtime in seconds */
- bool_t songlenDBEnable;
- char *songlenDBPath; /* Path to Songlengths.txt */
-
/* Miscellaneous settings */
- bool_t stilDBEnable;
- char *stilDBPath; /* Path to STIL.txt */
- char *hvscPath; /* Path-prefix for HVSC */
-
- bool_t subAutoEnable,
+ bool subAutoEnable,
subAutoMinOnly;
int subAutoMinTime;
} xs_cfg;
-extern pthread_mutex_t xs_cfg_mutex;
-
/* Functions
*/
void xs_init_configuration(void);
-#ifdef __cplusplus
-}
-#endif
+struct PluginPreferences;
+extern const PluginPreferences sid_prefs;
+
#endif /* XS_CONFIG_H */
diff --git a/src/sid/xs_length.c b/src/sid/xs_length.c
deleted file mode 100644
index 327786d664da..000000000000
--- a/src/sid/xs_length.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
-
- Get song length from SLDB for PSID/RSID files
-
- Programmed and designed by Matti 'ccr' Hamalainen <ccr at tnsp.org>
- (C) Copyright 1999-2009 Tecnic Software productions (TNSP)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-#include "xs_length.h"
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "xmms-sid.h"
-#include "xs_support.h"
-
-/* Free memory allocated for given SLDB node
- */
-static void xs_sldb_node_free(sldb_node_t *node)
-{
- if (node) {
- /* Nothing much to do here ... */
- free(node->lengths);
- free(node);
- }
-}
-
-
-/* Insert given node to db linked list
- */
-static void xs_sldb_node_insert(xs_sldb_t *db, sldb_node_t *node)
-{
- assert(db);
-
- if (db->nodes) {
- /* The first node's prev points to last node */
- node->prev = db->nodes->prev; /* New node's prev = Previous last node */
- db->nodes->prev->next = node; /* Previous last node's next = New node */
- db->nodes->prev = node; /* New last node = New node */
- node->next = NULL; /* But next is NULL! */
- } else {
- db->nodes = node; /* First node ... */
- node->prev = node; /* ... it's also last */
- node->next = NULL; /* But next is NULL! */
- }
-}
-
-
-/* Parse a time-entry in SLDB format
- */
-static int xs_sldb_gettime(char *str, size_t *pos)
-{
- int result, tmp;
-
- /* Check if it starts with a digit */
- if (g_ascii_isdigit(str[*pos])) {
- /* Get minutes-field */
- result = 0;
- while (g_ascii_isdigit(str[*pos]))
- result = (result * 10) + (str[(*pos)++] - '0');
-
- result *= 60;
-
- /* Check the field separator char */
- if (str[*pos] == ':') {
- /* Get seconds-field */
- (*pos)++;
- tmp = 0;
- while (g_ascii_isdigit(str[*pos])) {
- tmp = (tmp * 10) + (str[(*pos)++] - '0');
- }
-
- result += tmp;
- } else
- result = -2;
- } else
- result = -1;
-
- /* Ignore and skip the possible attributes */
- while (str[*pos] && !g_ascii_isspace(str[*pos]))
- (*pos)++;
-
- return result;
-}
-
-
-/* Parse one SLDB definition line, return SLDB node
- */
-sldb_node_t * xs_sldb_read_entry(char *inLine)
-{
- size_t linePos;
- int i;
- bool_t isOK;
- sldb_node_t *tmnode;
-
- /* Allocate new node */
- tmnode = (sldb_node_t *) malloc(sizeof(sldb_node_t));
- if (!tmnode) {
- xs_error("Error allocating new node. Fatal error.\n");
- return NULL;
- }
- memset(tmnode, 0, sizeof(sldb_node_t));
-
- /* Get hash value */
- linePos = 0;
- for (i = 0; i < XS_MD5HASH_LENGTH; i++, linePos += 2) {
- unsigned tmpu;
- sscanf(&inLine[linePos], "%2x", &tmpu);
- tmnode->md5Hash[i] = tmpu;
- }
-
- /* Get playtimes */
- if (inLine[linePos] != 0) {
- if (inLine[linePos] != '=') {
- xs_error("'=' expected on column #%d.\n", (int)linePos);
- xs_sldb_node_free(tmnode);
- return NULL;
- } else {
- size_t tmpLen, savePos;
-
- /* First playtime is after '=' */
- savePos = ++linePos;
- tmpLen = strlen(inLine);
-
- /* Get number of sub-tune lengths */
- isOK = TRUE;
- while ((linePos < tmpLen) && isOK) {
- xs_findnext(inLine, &linePos);
-
- if (xs_sldb_gettime(inLine, &linePos) >= 0)
- tmnode->nlengths++;
- else
- isOK = FALSE;
- }
-
- /* Allocate memory for lengths */
- if (tmnode->nlengths > 0) {
- tmnode->lengths = (int *) malloc(tmnode->nlengths * sizeof(int));
- if (!tmnode->lengths) {
- xs_error("Could not allocate memory for node.\n");
- xs_sldb_node_free(tmnode);
- return NULL;
- }
- memset(tmnode->lengths, 0, tmnode->nlengths * sizeof(int));
- } else {
- xs_sldb_node_free(tmnode);
- return NULL;
- }
-
- /* Read lengths in */
- i = 0;
- linePos = savePos;
- isOK = TRUE;
- while ((linePos < tmpLen) && (i < tmnode->nlengths) && isOK) {
- int l;
-
- xs_findnext(inLine, &linePos);
-
- l = xs_sldb_gettime(inLine, &linePos);
- if (l >= 0)
- tmnode->lengths[i] = l;
- else
- isOK = FALSE;
-
- i++;
- }
-
- if (!isOK) {
- xs_sldb_node_free(tmnode);
- return NULL;
- } else
- return tmnode;
- }
- }
-
- xs_sldb_node_free(tmnode);
- return NULL;
-}
-
-
-/* Read database to memory
- */
-int xs_sldb_read(xs_sldb_t *db, const char *dbFilename)
-{
- FILE *inFile;
- char inLine[XS_BUF_SIZE];
- size_t lineNum;
- sldb_node_t *tmnode;
- assert(db);
-
- /* Try to open the file */
- if ((inFile = fopen(dbFilename, "r")) == NULL) {
- xs_error("Could not open SongLengthDB '%s'\n", dbFilename);
- return -1;
- }
-
- /* Read and parse the data */
- lineNum = 0;
-
- while (fgets(inLine, XS_BUF_SIZE, inFile) != NULL) {
- size_t linePos = 0;
- lineNum++;
-
- xs_findnext(inLine, &linePos);
-
- /* Check if it is datafield */
- if (g_ascii_isxdigit(inLine[linePos])) {
- /* Check the length of the hash */
- int hashLen;
- for (hashLen = 0; inLine[linePos] && g_ascii_isxdigit(inLine[linePos]); hashLen++, linePos++);
-
- if (hashLen != XS_MD5HASH_LENGTH_CH) {
- xs_error("Invalid MD5-hash in SongLengthDB file '%s' line #%d!\n",
- dbFilename, (int)lineNum);
- } else {
- /* Parse and add node to db */
- if ((tmnode = xs_sldb_read_entry(inLine)) != NULL) {
- xs_sldb_node_insert(db, tmnode);
- } else {
- xs_error("Invalid entry in SongLengthDB file '%s' line #%d!\n",
- dbFilename, (int)lineNum);
- }
- }
- } else if ((inLine[linePos] != ';') && (inLine[linePos] != '[') && (inLine[linePos] != 0)) {
- xs_error("Invalid line in SongLengthDB file '%s' line #%d\n",
- dbFilename, (int)lineNum);
- }
-
- }
-
- /* Close the file */
- fclose(inFile);
-
- return 0;
-}
-
-
-/* Compare two given MD5-hashes.
- * Return: 0 if equal
- * negative if testHash1 < testHash2
- * positive if testHash1 > testHash2
- */
-static int xs_sldb_cmphash(xs_md5hash_t testHash1, xs_md5hash_t testHash2)
-{
- int i, d;
-
- /* Compute difference of hashes */
- for (i = 0, d = 0; (i < XS_MD5HASH_LENGTH) && !d; i++)
- d = (testHash1[i] - testHash2[i]);
-
- return d;
-}
-
-
-/* Compare two nodes
- */
-static int xs_sldb_cmp(const void *node1, const void *node2)
-{
- /* We assume here that we never ever get NULL-pointers or similar */
- return xs_sldb_cmphash(
- (*(sldb_node_t **) node1)->md5Hash,
- (*(sldb_node_t **) node2)->md5Hash);
-}
-
-
-/* (Re)create index
- */
-int xs_sldb_index(xs_sldb_t * db)
-{
- sldb_node_t *pCurr;
- size_t i;
- assert(db);
-
- /* Free old index */
- if (db->pindex) {
- free(db->pindex);
- db->pindex = NULL;
- }
-
- /* Get size of db */
- pCurr = db->nodes;
- db->n = 0;
- while (pCurr) {
- db->n++;
- pCurr = pCurr->next;
- }
-
- /* Check number of nodes */
- if (db->n > 0) {
- /* Allocate memory for index-table */
- db->pindex = (sldb_node_t **) malloc(sizeof(sldb_node_t *) * db->n);
- if (!db->pindex)
- return -1;
-
- /* Get node-pointers to table */
- i = 0;
- pCurr = db->nodes;
- while (pCurr && (i < db->n)) {
- db->pindex[i++] = pCurr;
- pCurr = pCurr->next;
- }
-
- /* Sort the indexes */
- qsort(db->pindex, db->n, sizeof(sldb_node_t *), xs_sldb_cmp);
- }
-
- return 0;
-}
-
-
-/* Free a given song-length database
- */
-void xs_sldb_free(xs_sldb_t * db)
-{
- sldb_node_t *pCurr, *next;
-
- if (!db)
- return;
-
- /* Free the memory allocated for nodes */
- pCurr = db->nodes;
- while (pCurr) {
- next = pCurr->next;
- xs_sldb_node_free(pCurr);
- pCurr = next;
- }
-
- db->nodes = NULL;
-
- /* Free memory allocated for index */
- if (db->pindex) {
- free(db->pindex);
- db->pindex = NULL;
- }
-
- /* Free structure */
- db->n = 0;
- free(db);
-}
-
-
-/* Compute md5hash of given SID-file
- */
-typedef struct {
- char magicID[4]; /* "PSID" / "RSID" magic identifier */
- uint16_t version, /* Version number */
- dataOffset, /* Start of actual c64 data in file */
- loadAddress, /* Loading address */
- initAddress, /* Initialization address */
- playAddress, /* Play one frame */
- nSongs, /* Number of subsongs */
- startSong; /* Default starting song */
- uint32_t speed; /* Speed */
- char sidName[32]; /* Descriptive text-fields, ASCIIZ */
- char sidAuthor[32];
- char sidCopyright[32];
-} psidv1_header_t;
-
-
-typedef struct {
- uint16_t flags; /* Flags */
- uint8_t startPage, pageLength;
- uint16_t reserved;
-} psidv2_header_t;
-
-
-static int xs_get_sid_hash(const char *filename, xs_md5hash_t hash)
-{
- VFSFile *inFile;
- xs_md5state_t inState;
- psidv1_header_t psidH;
- psidv2_header_t psidH2;
- uint8_t *songData;
- uint8_t ib8[2], i8;
- int index, result;
-
- /* Try to open the file */
- if ((inFile = vfs_fopen(filename, "rb")) == NULL)
- return -1;
-
- /* Read PSID header in */
- if (vfs_fread(psidH.magicID, 1, sizeof psidH.magicID, inFile) < sizeof psidH.magicID) {
- vfs_fclose(inFile);
- return -1;
- }
-
- if (strncmp(psidH.magicID, "PSID", 4) && strncmp(psidH.magicID, "RSID", 4)) {
- vfs_fclose(inFile);
- xs_error("Not a PSID or RSID file '%s'\n", filename);
- return -2;
- }
-
- psidH.version = xs_fread_be16(inFile);
- psidH.dataOffset = xs_fread_be16(inFile);
- psidH.loadAddress = xs_fread_be16(inFile);
- psidH.initAddress = xs_fread_be16(inFile);
- psidH.playAddress = xs_fread_be16(inFile);
- psidH.nSongs = xs_fread_be16(inFile);
- psidH.startSong = xs_fread_be16(inFile);
- psidH.speed = xs_fread_be32(inFile);
-
- if (vfs_fread(psidH.sidName, 1, sizeof psidH.sidName, inFile) < sizeof psidH.sidName
- || vfs_fread(psidH.sidAuthor, 1, sizeof psidH.sidAuthor, inFile) < sizeof psidH.sidAuthor
- || vfs_fread(psidH.sidCopyright, 1, sizeof psidH.sidCopyright, inFile) < sizeof psidH.sidCopyright) {
- vfs_fclose(inFile);
- xs_error("Error reading SID file header from '%s'\n", filename);
- return -4;
- }
-
- /* Check if we need to load PSIDv2NG header ... */
- psidH2.flags = 0; /* Just silence a stupid gcc warning */
-
- if (psidH.version == 2) {
- /* Yes, we need to */
- psidH2.flags = xs_fread_be16(inFile);
- psidH2.startPage = vfs_getc(inFile);
- psidH2.pageLength = vfs_getc(inFile);
- psidH2.reserved = xs_fread_be16(inFile);
- }
-
- /* Allocate buffer */
- songData = (uint8_t *) malloc(XS_SIDBUF_SIZE * sizeof(uint8_t));
- if (!songData) {
- vfs_fclose(inFile);
- xs_error("Error allocating temp data buffer for file '%s'\n", filename);
- return -3;
- }
-
- /* Read data to buffer */
- result = vfs_fread(songData, sizeof(uint8_t), XS_SIDBUF_SIZE, inFile);
- vfs_fclose(inFile);
-
- /* Initialize and start MD5-hash calculation */
- xs_md5_init(&inState);
-
- if (psidH.loadAddress == 0) {
- /* Strip load address (2 first bytes) */
- xs_md5_append(&inState, &songData[2], result - 2);
- } else {
- /* Append "as is" */
- xs_md5_append(&inState, songData, result);
- }
-
- /* Free buffer */
- free(songData);
-
- /* Append header data to hash */
-#define XSADDHASH(QDATAB) do { \
- ib8[0] = (QDATAB & 0xff); \
- ib8[1] = (QDATAB >> 8); \
- xs_md5_append(&inState, (uint8_t *) &ib8, sizeof(ib8)); \
- } while (0)
-
- XSADDHASH(psidH.initAddress);
- XSADDHASH(psidH.playAddress);
- XSADDHASH(psidH.nSongs);
-#undef XSADDHASH
-
- /* Append song speed data to hash */
- i8 = 0;
- for (index = 0; (index < psidH.nSongs) && (index < 32); index++) {
- i8 = (psidH.speed & (1 << index)) ? 60 : 0;
- xs_md5_append(&inState, &i8, sizeof(i8));
- }
-
- /* Rest of songs (more than 32) */
- for (index = 32; index < psidH.nSongs; index++) {
- xs_md5_append(&inState, &i8, sizeof(i8));
- }
-
- /* PSIDv2NG specific */
- if (psidH.version == 2) {
- /* SEE SIDPLAY HEADERS FOR INFO */
- i8 = (psidH2.flags >> 2) & 3;
- if (i8 == 2)
- xs_md5_append(&inState, &i8, sizeof(i8));
- }
-
- /* Calculate the hash */
- xs_md5_finish(&inState, hash);
-
- return 0;
-}
-
-
-/* Get node from db index via binary search
- */
-sldb_node_t *xs_sldb_get(xs_sldb_t *db, const char *filename)
-{
- sldb_node_t keyItem, *key, **item;
-
- /* Check the database pointers */
- if (!db || !db->nodes || !db->pindex)
- return NULL;
-
- /* Get the hash and then look up from db */
- if (xs_get_sid_hash(filename, keyItem.md5Hash) == 0) {
- key = &keyItem;
- item = bsearch(&key, db->pindex, db->n,
- sizeof(db->pindex[0]), xs_sldb_cmp);
-
- if (item)
- return *item;
- else
- return NULL;
- } else
- return NULL;
-}
-
-
diff --git a/src/sid/xs_length.h b/src/sid/xs_length.h
deleted file mode 100644
index a5798e3c09db..000000000000
--- a/src/sid/xs_length.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef XS_LENGTH_H
-#define XS_LENGTH_H
-
-#include <sys/types.h>
-
-#include "xs_md5.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Types
- */
-typedef struct _sldb_node_t {
- xs_md5hash_t md5Hash; /* 128-bit MD5 hash-digest */
- int nlengths; /* Number of lengths */
- int *lengths; /* Lengths in seconds */
- struct _sldb_node_t *prev, *next;
-} sldb_node_t;
-
-
-typedef struct {
- sldb_node_t *nodes,
- **pindex;
- size_t n;
-} xs_sldb_t;
-
-
-/* Functions
- */
-int xs_sldb_read(xs_sldb_t *, const char *);
-int xs_sldb_index(xs_sldb_t *);
-void xs_sldb_free(xs_sldb_t *);
-sldb_node_t * xs_sldb_get(xs_sldb_t *, const char *);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* XS_LENGTH_H */
diff --git a/src/sid/xs_md5.c b/src/sid/xs_md5.c
deleted file mode 100644
index 26beec231eda..000000000000
--- a/src/sid/xs_md5.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Wrapper for GLib MD5 implementation */
-/* John Lindgren, March 31, 2012 */
-/* Public domain */
-
-#include <glib.h>
-
-#include "xs_md5.h"
-
-void xs_md5_init (xs_md5state_t * state)
-{
- state->priv = g_checksum_new (G_CHECKSUM_MD5);
-}
-
-void xs_md5_append (xs_md5state_t * state, const void * data, int length)
-{
- g_checksum_update (state->priv, data, length);
-}
-
-void xs_md5_finish (xs_md5state_t * state, xs_md5hash_t hash)
-{
- size_t length = XS_MD5HASH_LENGTH;
- g_checksum_get_digest (state->priv, hash, & length);
- g_checksum_free (state->priv);
- state->priv = NULL;
-}
diff --git a/src/sid/xs_md5.h b/src/sid/xs_md5.h
deleted file mode 100644
index d480e68d3e85..000000000000
--- a/src/sid/xs_md5.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Wrapper for GLib MD5 implementation */
-/* John Lindgren, March 31, 2012 */
-/* Public domain */
-
-#ifndef XS_MD5_H
-#define XS_MD5_H
-
-#define XS_MD5HASH_LENGTH 16
-#define XS_MD5HASH_LENGTH_CH 32
-
-typedef struct {
- void * priv;
-} xs_md5state_t;
-
-typedef unsigned char xs_md5hash_t[XS_MD5HASH_LENGTH];
-
-void xs_md5_init (xs_md5state_t * state);
-void xs_md5_append (xs_md5state_t * state, const void * data, int length);
-void xs_md5_finish (xs_md5state_t * state, xs_md5hash_t hash);
-
-#endif
diff --git a/src/sid/xs_player.h b/src/sid/xs_player.h
deleted file mode 100644
index 9b3a2adc7bf8..000000000000
--- a/src/sid/xs_player.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef XS_PLAYER_H
-#define XS_PLAYER_H
-
-#include "xmms-sid.h"
-#include "xs_config.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct xs_status_t {
- int audioFrequency, /* Audio settings */
- audioChannels;
- void *sidEngine; /* SID-emulation internal engine data */
- int currSong; /* Current sub-tune */
-
- xs_tuneinfo_t *tuneInfo;
-} xs_status_t;
-
-
-/* Global variables
- */
-extern xs_status_t xs_status;
-extern pthread_mutex_t xs_status_mutex;
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* XS_PLAYER_H */
diff --git a/src/sid/xs_sidplay2.cc b/src/sid/xs_sidplay2.cc
index 647901d846ed..1564fe670542 100644
--- a/src/sid/xs_sidplay2.cc
+++ b/src/sid/xs_sidplay2.cc
@@ -24,10 +24,10 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "xs_config.h"
#include "xs_sidplay2.h"
-#include <assert.h>
-#include <stdlib.h>
+#include <pthread.h>
#include <string.h>
#include <sidplayfp/sidplayfp.h>
@@ -37,373 +37,254 @@
#include <sidplayfp/SidTuneInfo.h>
#include <sidplayfp/builders/residfp.h>
-class xs_sidplayfp_t {
-public:
+#include <libaudcore/runtime.h>
+#include <libaudcore/vfs.h>
+
+struct SidState {
sidplayfp *currEng;
sidbuilder *currBuilder;
- SidConfig currConfig;
SidTune *currTune;
- void *buf;
- int64_t bufSize;
- xs_sidplayfp_t(void);
- virtual ~xs_sidplayfp_t(void) { ; }
+ SidDatabase database;
+ bool database_loaded = false;
+ pthread_mutex_t database_mutex = PTHREAD_MUTEX_INITIALIZER;
};
+static SidState state;
-xs_sidplayfp_t::xs_sidplayfp_t(void)
-:currEng(NULL)
-{
- buf = NULL;
- bufSize = 0;
- currTune = NULL;
- currBuilder = NULL;
-}
-
-
-/* We need to 'export' all this pseudo-C++ crap */
-extern "C" {
/* Check if we can play the given file
*/
-bool_t xs_sidplayfp_probe(VFSFile *f)
+bool xs_sidplayfp_probe(const void *buf, int64_t bufSize)
{
- char tmpBuf[5];
-
- if (f == NULL) return FALSE;
+ if (bufSize < 4)
+ return false;
- if (vfs_fread(tmpBuf, sizeof(char), 4, f) != 4)
- return FALSE;
-
- if (!strncmp(tmpBuf, "PSID", 4) || !strncmp(tmpBuf, "RSID", 4))
- return TRUE;
- else
- return FALSE;
+ return !memcmp(buf, "PSID", 4) || !memcmp(buf, "RSID", 4);
}
/* Initialize SIDPlayFP
*/
-bool_t xs_sidplayfp_init(xs_status_t * status)
+bool xs_sidplayfp_init()
{
- xs_sidplayfp_t *engine;
- assert(status != NULL);
-
- /* Allocate internal structures */
- engine = new xs_sidplayfp_t();
- status->sidEngine = engine;
- if (!engine) return FALSE;
-
/* Initialize the engine */
- engine->currEng = new sidplayfp;
- if (!engine->currEng) {
- xs_error("[SIDPlayFP] Could not initialize emulation engine.\n");
- return FALSE;
- }
+ state.currEng = new sidplayfp;
/* Get current configuration */
- engine->currConfig = engine->currEng->config();
+ SidConfig config = state.currEng->config();
/* Configure channels and stuff */
- switch (status->audioChannels)
+ switch (xs_cfg.audioChannels)
{
case XS_CHN_STEREO:
- engine->currConfig.playback = SidConfig::STEREO;
+ config.playback = SidConfig::STEREO;
break;
case XS_CHN_MONO:
- engine->currConfig.playback = SidConfig::MONO;
+ config.playback = SidConfig::MONO;
break;
}
/* Audio parameters sanity checking and setup */
- engine->currConfig.frequency = status->audioFrequency;
+ config.frequency = xs_cfg.audioFrequency;
/* Initialize builder object */
- ReSIDfpBuilder *rs = new ReSIDfpBuilder("ReSIDfp builder");
- engine->currBuilder = (sidbuilder *) rs;
+ state.currBuilder = new ReSIDfpBuilder("ReSIDfp builder");
/* Builder object created, initialize it */
- engine->currBuilder->create(engine->currEng->info().maxsids());
- if (!engine->currBuilder->getStatus()) {
- xs_error("reSID->create() failed.\n");
- return FALSE;
+ state.currBuilder->create(state.currEng->info().maxsids());
+ if (!state.currBuilder->getStatus()) {
+ AUDERR("reSID->create() failed.\n");
+ return false;
}
- engine->currBuilder->filter(xs_cfg.emulateFilters);
- if (!engine->currBuilder->getStatus()) {
- xs_error("reSID->filter(%d) failed.\n", xs_cfg.emulateFilters);
- return FALSE;
+ state.currBuilder->filter(xs_cfg.emulateFilters);
+ if (!state.currBuilder->getStatus()) {
+ AUDERR("reSID->filter(%d) failed.\n", xs_cfg.emulateFilters);
+ return false;
}
- engine->currConfig.sidEmulation = engine->currBuilder;
+ config.sidEmulation = state.currBuilder;
/* Clockspeed settings */
switch (xs_cfg.clockSpeed) {
case XS_CLOCK_NTSC:
- engine->currConfig.defaultC64Model = SidConfig::NTSC;
+ config.defaultC64Model = SidConfig::NTSC;
break;
default:
- xs_error("[SIDPlayFP] Invalid clockSpeed=%d, falling back to PAL.\n",
+ AUDERR("[SIDPlayFP] Invalid clockSpeed=%d, falling back to PAL.\n",
xs_cfg.clockSpeed);
case XS_CLOCK_PAL:
- engine->currConfig.defaultC64Model = SidConfig::PAL;
+ config.defaultC64Model = SidConfig::PAL;
xs_cfg.clockSpeed = XS_CLOCK_PAL;
break;
}
+ config.forceC64Model = xs_cfg.forceSpeed;
+
/* Configure rest of the emulation */
if (xs_cfg.mos8580)
- engine->currConfig.defaultSidModel = SidConfig::MOS8580;
+ config.defaultSidModel = SidConfig::MOS8580;
else
- engine->currConfig.defaultSidModel = SidConfig::MOS6581;
+ config.defaultSidModel = SidConfig::MOS6581;
- engine->currConfig.forceSidModel = xs_cfg.forceModel;
+ config.forceSidModel = xs_cfg.forceModel;
/* Now set the emulator configuration */
- if (!engine->currEng->config(engine->currConfig)) {
- xs_error("[SIDPlayFP] Emulator engine configuration failed!\n");
- return FALSE;
+ if (!state.currEng->config(config)) {
+ AUDERR("[SIDPlayFP] Emulator engine configuration failed!\n");
+ return false;
}
- /* Create the sidtune */
- engine->currTune = new SidTune(0);
- if (!engine->currTune) {
- xs_error("[SIDPlayFP] Could not initialize SIDTune object.\n");
- return FALSE;
+ /* Load ROMs */
+ VFSFile kernal_file("file://" SIDDATADIR "sidplayfp/kernal", "r");
+ VFSFile basic_file("file://" SIDDATADIR "sidplayfp/basic", "r");
+ VFSFile chargen_file("file://" SIDDATADIR "sidplayfp/chargen", "r");
+
+ if (kernal_file && basic_file && chargen_file)
+ {
+ Index<char> kernal = kernal_file.read_all();
+ Index<char> basic = basic_file.read_all();
+ Index<char> chargen = chargen_file.read_all();
+
+ if (kernal.len() == 8192 && basic.len() == 8192 && chargen.len() == 4096)
+ state.currEng->setRoms((uint8_t*)kernal.begin(), (uint8_t*)basic.begin(), (uint8_t*)chargen.begin());
}
- return TRUE;
+ /* Load song length database */
+ state.database_loaded = state.database.open(SIDDATADIR "sidplayfp/Songlengths.txt");
+
+ /* Create the sidtune */
+ state.currTune = new SidTune(0);
+
+ return true;
}
/* Close SIDPlayFP engine
*/
-void xs_sidplayfp_close(xs_status_t * status)
+void xs_sidplayfp_close()
{
- xs_sidplayfp_t *engine;
- assert(status != NULL);
-
- engine = (xs_sidplayfp_t *) status->sidEngine;
-
/* Free internals */
- if (engine->currBuilder) {
- delete engine->currBuilder;
- engine->currBuilder = NULL;
+ if (state.currBuilder) {
+ delete state.currBuilder;
+ state.currBuilder = nullptr;
}
- if (engine->currEng) {
- delete engine->currEng;
- engine->currEng = NULL;
+ if (state.currEng) {
+ delete state.currEng;
+ state.currEng = nullptr;
}
- if (engine->currTune) {
- delete engine->currTune;
- engine->currTune = NULL;
+ if (state.currTune) {
+ delete state.currTune;
+ state.currTune = nullptr;
}
- xs_sidplayfp_delete(status);
-
- delete engine;
- status->sidEngine = NULL;
+ if (state.database_loaded)
+ state.database.close();
}
/* Initialize current song and sub-tune
*/
-bool_t xs_sidplayfp_initsong(xs_status_t * status)
+bool xs_sidplayfp_initsong(int subtune)
{
- xs_sidplayfp_t *engine;
- assert(status != NULL);
-
- engine = (xs_sidplayfp_t *) status->sidEngine;
- if (engine == NULL) return FALSE;
-
- if (!engine->currTune->selectSong(status->currSong)) {
- xs_error("[SIDPlayFP] currTune->selectSong() failed\n");
- return FALSE;
+ if (!state.currTune->selectSong(subtune)) {
+ AUDERR("[SIDPlayFP] currTune->selectSong() failed\n");
+ return false;
}
- if (!engine->currEng->load(engine->currTune)) {
- xs_error("[SIDPlayFP] currEng->load() failed\n");
- return FALSE;
+ if (!state.currEng->load(state.currTune)) {
+ AUDERR("[SIDPlayFP] currEng->load() failed\n");
+ return false;
}
- return TRUE;
+ return true;
}
/* Emulate and render audio data to given buffer
*/
-unsigned xs_sidplayfp_fillbuffer(xs_status_t * status, char * audioBuffer, unsigned audioBufSize)
+unsigned xs_sidplayfp_fillbuffer(char * audioBuffer, unsigned audioBufSize)
{
- xs_sidplayfp_t *engine;
- assert(status != NULL);
-
- engine = (xs_sidplayfp_t *) status->sidEngine;
- if (!engine) return 0;
-
- return engine->currEng->play((short *)audioBuffer, audioBufSize / 2) * 2;
+ return state.currEng->play((short *)audioBuffer, audioBufSize / 2) * 2;
}
/* Load a given SID-tune file
*/
-bool_t xs_sidplayfp_load(xs_status_t * status, const char * pcFilename)
+bool xs_sidplayfp_load(const void *buf, int64_t bufSize)
{
- /* This is safe, since xmms-sid.c always calls us with xs_status locked */
- static int loaded_roms = 0;
-
- xs_sidplayfp_t *engine;
- assert(status != NULL);
-
- engine = (xs_sidplayfp_t *) status->sidEngine;
- if (!engine) return FALSE;
-
- /* In xs_sidplayfp_init aud-vfs is not initialized yet, so try to load
- the optional rom files on the first xs_sidplayfp_load call. */
- if (!loaded_roms) {
- int64_t size = 0;
- void *kernal = NULL, *basic = NULL, *chargen = NULL;
-
- vfs_file_get_contents("file://" SIDDATADIR "sidplayfp/kernal", &kernal, &size);
- if (size != 8192) {
- free(kernal);
- kernal = NULL;
- }
-
- vfs_file_get_contents("file://" SIDDATADIR "sidplayfp/basic", &basic, &size);
- if(size != 8192) {
- free(basic);
- basic = NULL;
- }
-
- vfs_file_get_contents("file://" SIDDATADIR "sidplayfp/chargen", &chargen, &size);
- if(size != 4096) {
- free(chargen);
- chargen = NULL;
- }
-
- engine->currEng->setRoms((uint8_t*)kernal, (uint8_t*)basic, (uint8_t*)chargen);
- free(kernal);
- free(basic);
- free(chargen);
- loaded_roms = 1;
- }
-
/* Try to get the tune */
- vfs_file_get_contents(pcFilename, &engine->buf, &engine->bufSize);
- if(!engine->bufSize) {
- free(engine->buf);
- engine->buf = NULL;
- return FALSE;
- }
-
- engine->currTune->read((uint8_t*)engine->buf, engine->bufSize);
+ state.currTune->read((const uint8_t*)buf, bufSize);
- return engine->currTune->getStatus();
+ return state.currTune->getStatus();
}
-/* Delete INTERNAL information
- */
-void xs_sidplayfp_delete(xs_status_t * status)
+bool xs_sidplayfp_getinfo(xs_tuneinfo_t &ti, const char *filename, const void *buf, int64_t bufSize)
{
- xs_sidplayfp_t *engine;
- assert(status != NULL);
+ /* Check if the tune exists and is readable */
+ SidTune myTune((const uint8_t*)buf, bufSize);
- engine = (xs_sidplayfp_t *) status->sidEngine;
- if (engine == NULL) return;
+ if (!myTune.getStatus())
+ return false;
- free(engine->buf);
- engine->buf = NULL;
- engine->bufSize = 0;
-}
+ /* Get general tune information */
+ const SidTuneInfo *myInfo = myTune.getInfo();
+ /* Allocate tuneinfo structure and set information */
+ ti.sidFilename = String (filename);
-xs_tuneinfo_t* xs_sidplayfp_getinfo(const char *sidFilename)
-{
- /* This is safe, since xmms-sid.c always calls us with xs_status locked */
- static int got_db = -1;
- static SidDatabase database;
+ ti.sidName = String (myInfo->infoString(0));
+ ti.sidComposer = String (myInfo->infoString(1));
+ ti.sidCopyright = String (myInfo->infoString(2));
- xs_tuneinfo_t *result;
- const SidTuneInfo *myInfo;
- SidTune *myTune;
- void *buf = NULL;
- int64_t bufSize = 0;
+ ti.nsubTunes = myInfo->songs();
+ ti.startTune = myInfo->startSong();
- /* Load file */
- vfs_file_get_contents(sidFilename, &buf, &bufSize);
+ ti.loadAddr = myInfo->loadAddr();
+ ti.initAddr = myInfo->initAddr();
+ ti.playAddr = myInfo->playAddr();
+ ti.dataFileLen = myInfo->dataFileLen();
+ ti.sidFormat = String (myInfo->formatString());
- /* Check if the tune exists and is readable */
- if (!bufSize || !(myTune = new SidTune((uint8_t*)buf, bufSize))) {
- free(buf);
- return NULL;
- }
- free(buf);
+ ti.sidModel = myInfo->sidModel1();
- if (!myTune->getStatus()) {
- delete myTune;
- return NULL;
- }
+ /* Fill in subtune information */
+ ti.subTunes.insert(0, ti.nsubTunes);
- /* Get general tune information */
- myInfo = myTune->getInfo();
+ if (state.database_loaded)
+ {
+ pthread_mutex_lock(&state.database_mutex);
- /* Allocate tuneinfo structure and set information */
- result = xs_tuneinfo_new(sidFilename,
- myInfo->songs(), myInfo->startSong(),
- myInfo->infoString(0), myInfo->infoString(1), myInfo->infoString(2),
- myInfo->loadAddr(), myInfo->initAddr(), myInfo->playAddr(),
- myInfo->dataFileLen(), myInfo->formatString(), myInfo->sidModel1());
-
- for (int i = 0; i < result->nsubTunes; i++) {
- if (result->subTunes[i].tuneLength >= 0)
- continue;
-
- if (got_db == -1)
- got_db = database.open(SIDDATADIR "sidplayfp/Songlengths.txt");
-
- if (got_db) {
- myTune->selectSong(i + 1);
- result->subTunes[i].tuneLength = database.length(*myTune);
+ for (int i = 0; i < ti.nsubTunes; i++)
+ {
+ myTune.selectSong(i + 1);
+ ti.subTunes[i].tuneLength = state.database.length(myTune);
}
- }
- delete myTune;
+ pthread_mutex_unlock(&state.database_mutex);
+ }
- return result;
+ return true;
}
-bool_t xs_sidplayfp_updateinfo(xs_status_t *myStatus)
+bool xs_sidplayfp_updateinfo(xs_tuneinfo_t &ti, int subtune)
{
- const SidTuneInfo *myInfo;
- SidTune *myTune;
- xs_sidplayfp_t *myEngine;
- xs_tuneinfo_t *i;
-
- /* Check if we have required structures initialized */
- if (!myStatus || !myStatus->tuneInfo || !myStatus->sidEngine)
- return FALSE;
-
- myEngine = (xs_sidplayfp_t *) myStatus->sidEngine;
- myTune = myEngine->currTune;
- if (!myTune)
- return FALSE;
-
/* Get currently playing tune information */
- myInfo = myTune->getInfo();
+ const SidTuneInfo *myInfo = state.currTune->getInfo();
/* NOTICE! Here we assume that libSIDPlay[12] headers define
* SIDTUNE_SIDMODEL_* similarly to our enums in xs_config.h ...
*/
- i = myStatus->tuneInfo;
- i->sidModel = myInfo->sidModel1();
+ ti.sidModel = myInfo->sidModel1();
- if ((myStatus->currSong > 0) && (myStatus->currSong <= i->nsubTunes)) {
+ if ((subtune > 0) && (subtune <= ti.nsubTunes)) {
int tmpSpeed = -1;
switch (myInfo->clockSpeed()) {
@@ -428,15 +309,14 @@ bool_t xs_sidplayfp_updateinfo(xs_status_t *myStatus)
tmpSpeed = myInfo->songSpeed();
break;
}
+ break;
default:
tmpSpeed = myInfo->clockSpeed();
break;
}
- i->subTunes[myStatus->currSong - 1].tuneSpeed = tmpSpeed;
+ ti.subTunes[subtune - 1].tuneSpeed = tmpSpeed;
}
- return TRUE;
+ return true;
}
-
-} /* extern "C" */
diff --git a/src/sid/xs_sidplay2.h b/src/sid/xs_sidplay2.h
index bff3904479b1..9e0dac8957b5 100644
--- a/src/sid/xs_sidplay2.h
+++ b/src/sid/xs_sidplay2.h
@@ -1,25 +1,17 @@
#ifndef XS_SIDPLAYFP_H
#define XS_SIDPLAYFP_H
-#include "xs_player.h"
-#include "xs_support.h"
-#include "xs_slsup.h"
+#include "xmms-sid.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <stdint.h>
-bool_t xs_sidplayfp_probe(VFSFile *);
-void xs_sidplayfp_close(xs_status_t *);
-bool_t xs_sidplayfp_init(xs_status_t *);
-bool_t xs_sidplayfp_initsong(xs_status_t *);
-unsigned xs_sidplayfp_fillbuffer(xs_status_t *, char *, unsigned);
-bool_t xs_sidplayfp_load(xs_status_t *, const char *);
-void xs_sidplayfp_delete(xs_status_t *);
-xs_tuneinfo_t* xs_sidplayfp_getinfo(const char *);
-bool_t xs_sidplayfp_updateinfo(xs_status_t *);
+bool xs_sidplayfp_probe(const void *buf, int64_t bufSize);
+void xs_sidplayfp_close();
+bool xs_sidplayfp_init();
+bool xs_sidplayfp_initsong(int subtune);
+unsigned xs_sidplayfp_fillbuffer(char *, unsigned);
+bool xs_sidplayfp_load(const void *buf, int64_t bufSize);
+bool xs_sidplayfp_getinfo(xs_tuneinfo_t &ti, const char *filename, const void *buf, int64_t bufSize);
+bool xs_sidplayfp_updateinfo(xs_tuneinfo_t &ti, int subtune);
-#ifdef __cplusplus
-}
-#endif
#endif /* XS_SIDPLAYFP_H */
diff --git a/src/sid/xs_slsup.c b/src/sid/xs_slsup.c
deleted file mode 100644
index 595715483250..000000000000
--- a/src/sid/xs_slsup.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
-
- File information window
-
- Programmed and designed by Matti 'ccr' Hamalainen <ccr at tnsp.org>
- (C) Copyright 1999-2007 Tecnic Software productions (TNSP)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "xs_slsup.h"
-
-#include <glib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "xs_config.h"
-
-
-static xs_sldb_t *xs_sldb_db = NULL;
-pthread_mutex_t xs_sldb_db_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static xs_stildb_t *xs_stildb_db = NULL;
-pthread_mutex_t xs_stildb_db_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-
-/* STIL-database handling
- */
-int xs_stil_init(void)
-{
- pthread_mutex_lock(&xs_cfg_mutex);
-
- if (!xs_cfg.stilDBPath) {
- pthread_mutex_unlock(&xs_cfg_mutex);
- return -1;
- }
-
- pthread_mutex_lock(&xs_stildb_db_mutex);
-
- /* Check if already initialized */
- if (xs_stildb_db)
- xs_stildb_free(xs_stildb_db);
-
- /* Allocate database */
- xs_stildb_db = (xs_stildb_t *) g_malloc0(sizeof(xs_stildb_t));
- if (!xs_stildb_db) {
- pthread_mutex_unlock(&xs_cfg_mutex);
- pthread_mutex_unlock(&xs_stildb_db_mutex);
- return -2;
- }
-
- /* Read the database */
- if (xs_stildb_read(xs_stildb_db, xs_cfg.stilDBPath) != 0) {
- xs_stildb_free(xs_stildb_db);
- xs_stildb_db = NULL;
- pthread_mutex_unlock(&xs_cfg_mutex);
- pthread_mutex_unlock(&xs_stildb_db_mutex);
- return -3;
- }
-
- /* Create index */
- if (xs_stildb_index(xs_stildb_db) != 0) {
- xs_stildb_free(xs_stildb_db);
- xs_stildb_db = NULL;
- pthread_mutex_unlock(&xs_cfg_mutex);
- pthread_mutex_unlock(&xs_stildb_db_mutex);
- return -4;
- }
-
- pthread_mutex_unlock(&xs_cfg_mutex);
- pthread_mutex_unlock(&xs_stildb_db_mutex);
- return 0;
-}
-
-
-void xs_stil_close(void)
-{
- pthread_mutex_lock(&xs_stildb_db_mutex);
- xs_stildb_free(xs_stildb_db);
- xs_stildb_db = NULL;
- pthread_mutex_unlock(&xs_stildb_db_mutex);
-}
-
-
-stil_node_t *xs_stil_get(char *filename)
-{
- stil_node_t *result;
- char *tmpFilename;
-
- pthread_mutex_lock(&xs_stildb_db_mutex);
- pthread_mutex_lock(&xs_cfg_mutex);
-
- if (xs_cfg.stilDBEnable && xs_stildb_db) {
- if (xs_cfg.hvscPath) {
- /* Remove postfixed directory separator from HVSC-path */
- tmpFilename = strrchr(xs_cfg.hvscPath, '/');
- if (tmpFilename && (tmpFilename[1] == 0))
- tmpFilename[0] = 0;
-
- /* Remove HVSC location-prefix from filename */
- tmpFilename = strstr(filename, xs_cfg.hvscPath);
- if (tmpFilename)
- tmpFilename += strlen(xs_cfg.hvscPath);
- else
- tmpFilename = filename;
- } else
- tmpFilename = filename;
-
- result = xs_stildb_get_node(xs_stildb_db, tmpFilename);
- } else
- result = NULL;
-
- pthread_mutex_unlock(&xs_stildb_db_mutex);
- pthread_mutex_unlock(&xs_cfg_mutex);
-
- return result;
-}
-
-
-/* Song length database handling glue
- */
-int xs_songlen_init(void)
-{
- pthread_mutex_lock(&xs_cfg_mutex);
-
- if (!xs_cfg.songlenDBPath) {
- pthread_mutex_unlock(&xs_cfg_mutex);
- return -1;
- }
-
- pthread_mutex_lock(&xs_sldb_db_mutex);
-
- /* Check if already initialized */
- if (xs_sldb_db)
- xs_sldb_free(xs_sldb_db);
-
- /* Allocate database */
- xs_sldb_db = (xs_sldb_t *) g_malloc0(sizeof(xs_sldb_t));
- if (!xs_sldb_db) {
- pthread_mutex_unlock(&xs_cfg_mutex);
- pthread_mutex_unlock(&xs_sldb_db_mutex);
- return -2;
- }
-
- /* Read the database */
- if (xs_sldb_read(xs_sldb_db, xs_cfg.songlenDBPath) != 0) {
- xs_sldb_free(xs_sldb_db);
- xs_sldb_db = NULL;
- pthread_mutex_unlock(&xs_cfg_mutex);
- pthread_mutex_unlock(&xs_sldb_db_mutex);
- return -3;
- }
-
- /* Create index */
- if (xs_sldb_index(xs_sldb_db) != 0) {
- xs_sldb_free(xs_sldb_db);
- xs_sldb_db = NULL;
- pthread_mutex_unlock(&xs_cfg_mutex);
- pthread_mutex_unlock(&xs_sldb_db_mutex);
- return -4;
- }
-
- pthread_mutex_unlock(&xs_cfg_mutex);
- pthread_mutex_unlock(&xs_sldb_db_mutex);
- return 0;
-}
-
-
-void xs_songlen_close(void)
-{
- pthread_mutex_lock(&xs_sldb_db_mutex);
- xs_sldb_free(xs_sldb_db);
- xs_sldb_db = NULL;
- pthread_mutex_unlock(&xs_sldb_db_mutex);
-}
-
-
-sldb_node_t *xs_songlen_get(const char * filename)
-{
- sldb_node_t *result;
-
- pthread_mutex_lock(&xs_sldb_db_mutex);
-
- if (xs_cfg.songlenDBEnable && xs_sldb_db)
- result = xs_sldb_get(xs_sldb_db, filename);
- else
- result = NULL;
-
- pthread_mutex_unlock(&xs_sldb_db_mutex);
-
- return result;
-}
-
-
-/* Allocate a new tune information structure
- */
-xs_tuneinfo_t *xs_tuneinfo_new(const char * filename,
- int nsubTunes, int startTune, const char * sidName,
- const char * sidComposer, const char * sidCopyright,
- int loadAddr, int initAddr, int playAddr,
- int dataFileLen, const char *sidFormat, int sidModel)
-{
- xs_tuneinfo_t *result;
- sldb_node_t *tmpLength;
- int i;
-
- /* Allocate structure */
- result = (xs_tuneinfo_t *) g_malloc0(sizeof(xs_tuneinfo_t));
-
- result->sidFilename = str_get (filename);
-
- /* Allocate space for subtune information */
- result->subTunes = g_malloc0(sizeof(xs_subtuneinfo_t) * (nsubTunes + 1));
-
- result->sidName = str_get (sidName);
- result->sidComposer = str_get (sidComposer);
- result->sidCopyright = str_get (sidCopyright);
-
- result->nsubTunes = nsubTunes;
- result->startTune = startTune;
-
- result->loadAddr = loadAddr;
- result->initAddr = initAddr;
- result->playAddr = playAddr;
- result->dataFileLen = dataFileLen;
- result->sidFormat = str_get (sidFormat);
-
- result->sidModel = sidModel;
-
- /* Get length information (NOTE: Do not free this!) */
- tmpLength = xs_songlen_get(filename);
-
- /* Fill in sub-tune information */
- for (i = 0; i < result->nsubTunes; i++) {
- if (tmpLength && (i < tmpLength->nlengths))
- result->subTunes[i].tuneLength = tmpLength->lengths[i];
- else
- result->subTunes[i].tuneLength = -1;
-
- result->subTunes[i].tuneSpeed = -1;
- }
-
- return result;
-}
-
-
-/* Free given tune information structure
- */
-void xs_tuneinfo_free(xs_tuneinfo_t * tune)
-{
- if (!tune) return;
-
- g_free(tune->subTunes);
- str_unref (tune->sidFilename);
- str_unref (tune->sidName);
- str_unref (tune->sidComposer);
- str_unref (tune->sidCopyright);
- str_unref (tune->sidFormat);
- g_free(tune);
-}
diff --git a/src/sid/xs_slsup.h b/src/sid/xs_slsup.h
deleted file mode 100644
index 01e0a0eed9e1..000000000000
--- a/src/sid/xs_slsup.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef XS_SLSUP_H
-#define XS_SLSUP_H
-
-#include "xmms-sid.h"
-#include "xs_stil.h"
-#include "xs_length.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int xs_stil_init(void);
-void xs_stil_close(void);
-stil_node_t *xs_stil_get(char *filename);
-
-int xs_songlen_init(void);
-void xs_songlen_close(void);
-sldb_node_t *xs_songlen_get(const char *filename);
-
-xs_tuneinfo_t *xs_tuneinfo_new(const char *pcFilename, int nsubTunes,
- int startTune, const char *sidName, const char *sidComposer,
- const char *sidCopyright, int loadAddr, int initAddr, int playAddr,
- int dataFileLen, const char *sidFormat, int sidModel);
-void xs_tuneinfo_free(xs_tuneinfo_t *tune);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* XS_SLSUP_H */
diff --git a/src/sid/xs_stil.c b/src/sid/xs_stil.c
deleted file mode 100644
index 3938473409ef..000000000000
--- a/src/sid/xs_stil.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
-
- STIL-database handling functions
-
- Programmed and designed by Matti 'ccr' Hamalainen <ccr at tnsp.org>
- (C) Copyright 1999-2009 Tecnic Software productions (TNSP)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-#include "xs_stil.h"
-
-#include <assert.h>
-#include <glib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "xmms-sid.h"
-#include "xs_support.h"
-
-/* Database handling functions
- */
-static bool_t xs_stildb_node_realloc(stil_node_t *node, int nsubTunes)
-{
- if (node == NULL) return FALSE;
-
- /* Re-allocate subTune structure if needed */
- if (nsubTunes > node->nsubTunes) {
- int clearIndex, clearLength;
-
- node->subTunes =
- (stil_subnode_t **) realloc(node->subTunes,
- (nsubTunes + 1) * sizeof(stil_subnode_t **));
-
- if (!node->subTunes) {
- xs_error("SubTune pointer structure realloc failed.\n");
- return FALSE;
- }
-
- /* Clear the newly allocated memory */
- if (node->nsubTunes == 0) {
- clearIndex = 0;
- clearLength = nsubTunes + 1;
- } else {
- clearIndex = node->nsubTunes + 1;
- clearLength = (nsubTunes - clearIndex + 1);
- }
- memset(&(node->subTunes[clearIndex]), 0, clearLength * sizeof(stil_subnode_t **));
-
- node->nsubTunes = nsubTunes;
- }
-
- /* Allocate memory for subTune */
- if (!node->subTunes[nsubTunes]) {
- node->subTunes[nsubTunes] = malloc(sizeof(stil_subnode_t));
-
- if (node->subTunes[nsubTunes] == NULL) {
- xs_error("SubTune structure malloc failed!\n");
- return FALSE;
- }
- memset(node->subTunes[nsubTunes], 0, sizeof(stil_subnode_t));
- }
-
- return TRUE;
-}
-
-
-static void xs_stildb_node_free(stil_node_t *node)
-{
- int i;
- stil_subnode_t *subnode;
-
- if (node == NULL) return;
-
- /* Free subtune information */
- for (i = 0; i <= node->nsubTunes; i++) {
- subnode = node->subTunes[i];
- if (subnode) {
- free(subnode->name);
- free(subnode->author);
- free(subnode->info);
- free(subnode->title);
- free(subnode);
- }
- }
- free(node->subTunes);
- free(node->filename);
- free(node);
-}
-
-
-static stil_node_t *xs_stildb_node_new(char *filename)
-{
- stil_node_t *result;
-
-//fprintf(stderr, "LL: %s\n", filename);
-
- /* Allocate memory for new node */
- if ((result = malloc(sizeof(stil_node_t))) == NULL)
- return NULL;
- memset(result, 0, sizeof(stil_node_t));
-
- /* Allocate filename and initial space for one subtune */
- result->filename = g_strdup(filename);
- if (result->filename == NULL || !xs_stildb_node_realloc(result, 1)) {
- xs_stildb_node_free(result);
- return NULL;
- }
-
- return result;
-}
-
-
-/* Insert given node to db linked list
- */
-static void xs_stildb_node_insert(xs_stildb_t *db, stil_node_t *node)
-{
- assert(db != NULL);
-
- if (db->nodes != NULL) {
- /* The first node's pPrev points to last node */
- node->prev = db->nodes->prev; /* New node's prev = Previous last node */
- db->nodes->prev->next = node; /* Previous last node's next = New node */
- db->nodes->prev = node; /* New last node = New node */
- node->next = NULL; /* But next is NULL! */
- } else {
- db->nodes = node; /* First node ... */
- node->prev = node; /* ... it's also last */
- node->next = NULL; /* But next is NULL! */
- }
-}
-
-
-/* Read database (additively) to given db-structure
- */
-#define XS_STILDB_MULTI \
- if (multi) { \
- multi = FALSE; \
- xs_pstrcat(&(node->subTunes[subEntry]->info), "\n"); \
- }
-
-static void XS_STILDB_ERR(int linenum, char *line, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- xs_verror(fmt, ap);
- va_end(ap);
-
- xs_error("#%d: '%s'\n", linenum, line);
-}
-
-int xs_stildb_read(xs_stildb_t *db, char *filename)
-{
- FILE *f;
- char line[XS_BUF_SIZE + 16]; /* Since we add some chars here and there */
- stil_node_t *node;
- bool_t error, multi;
- int lineNum, subEntry;
- assert(db != NULL);
-
- /* Try to open the file */
- if ((f = fopen(filename, "r")) == NULL) {
- xs_error("Could not open STILDB '%s'\n", filename);
- return -1;
- }
-
- /* Read and parse the data */
- lineNum = 0;
- error = FALSE;
- multi = FALSE;
- node = NULL;
- subEntry = 0;
-
- while (!error && fgets(line, XS_BUF_SIZE, f) != NULL) {
- size_t linePos = 0, eolPos = 0;
- line[XS_BUF_SIZE] = 0;
- xs_findeol(line, &eolPos);
- line[eolPos] = 0;
- lineNum++;
-
- switch (line[0]) {
- case '/':
- /* Check if we are already parsing entry */
- multi = FALSE;
- if (node != NULL) {
- XS_STILDB_ERR(lineNum, line,
- "New entry found before end of current ('%s')!\n",
- node->filename);
- xs_stildb_node_free(node);
- node = NULL;
- }
-
- /* A new node */
- subEntry = 0;
- if ((node = xs_stildb_node_new(line)) == NULL) {
- XS_STILDB_ERR(lineNum, line,
- "Could not allocate new STILdb-node!\n");
- error = TRUE;
- }
- break;
-
- case '(':
- /* A new sub-entry */
- multi = FALSE;
- linePos++;
- if (line[linePos] == '#') {
- linePos++;
- if (g_ascii_isdigit(line[linePos])) {
- size_t savePos = linePos;
- xs_findnum(line, &linePos);
- line[linePos] = 0;
- subEntry = atol(&line[savePos]);
-
- /* Sanity check */
- if (subEntry < 1) {
- char *tmp = node != NULL ? node->filename : NULL;
- XS_STILDB_ERR(lineNum, line,
- "Number of subEntry (%d) for '%s' is invalid\n",
- subEntry, tmp);
- subEntry = 0;
- }
- } else {
- XS_STILDB_ERR(lineNum, line,
- "Syntax error, expected subEntry number.\n");
- subEntry = 0;
- }
- } else {
- XS_STILDB_ERR(lineNum, line,
- "Syntax error, expected '#' before subEntry number.\n");
- subEntry = 0;
- }
-
- break;
-
- case 0:
- case '#':
- case '\n':
- case '\r':
- /* End of entry/field */
- multi = FALSE;
- if (node != NULL) {
- xs_stildb_node_insert(db, node);
- node = NULL;
- }
- break;
-
- default:
- /* Check if we are parsing an entry */
- xs_findnext(line, &linePos);
-
- if (node == NULL) {
- XS_STILDB_ERR(lineNum, line,
- "Entry data encountered outside of entry or syntax error!\n");
- break;
- }
-
- if (!xs_stildb_node_realloc(node, subEntry)) {
- XS_STILDB_ERR(lineNum, line,
- "Could not (re)allocate memory for subEntries!\n");
- error = TRUE;
- break;
- }
-
- /* Some other type */
- if (strncmp(line, " NAME:", 8) == 0) {
- XS_STILDB_MULTI;
- free(node->subTunes[subEntry]->name);
- node->subTunes[subEntry]->name = g_strdup(&line[9]);
- } else if (strncmp(line, " TITLE:", 8) == 0) {
- XS_STILDB_MULTI;
- multi = TRUE;
- if (!node->subTunes[subEntry]->title)
- node->subTunes[subEntry]->title = g_strdup(&line[9]);
- xs_pstrcat(&(node->subTunes[subEntry]->info), &line[2]);
- } else if (strncmp(line, " AUTHOR:", 8) == 0) {
- XS_STILDB_MULTI;
- free(node->subTunes[subEntry]->author);
- node->subTunes[subEntry]->author = g_strdup(&line[9]);
- } else if (strncmp(line, " ARTIST:", 8) == 0) {
- XS_STILDB_MULTI;
- multi = TRUE;
- xs_pstrcat(&(node->subTunes[subEntry]->info), &line[1]);
- } else if (strncmp(line, "COMMENT:", 8) == 0) {
- XS_STILDB_MULTI;
- multi = TRUE;
- xs_pstrcat(&(node->subTunes[subEntry]->info), line);
- } else {
- if (multi) {
- xs_pstrcat(&(node->subTunes[subEntry]->info), " ");
- xs_pstrcat(&(node->subTunes[subEntry]->info), &line[linePos]);
- } else {
- XS_STILDB_ERR(lineNum, line,
- "Entry continuation found when multi == FALSE.\n");
- }
- }
- break;
- }
- } /* while */
-
- /* Check if there is one remaining node */
- if (node != NULL)
- xs_stildb_node_insert(db, node);
-
- /* Close the file */
- fclose(f);
-
- return 0;
-}
-
-
-/* Compare two nodes
- */
-static int xs_stildb_cmp(const void *node1, const void *node2)
-{
- /* We assume here that we never ever get NULL-pointers or similar */
- return strcmp(
- (*(stil_node_t **) node1)->filename,
- (*(stil_node_t **) node2)->filename);
-}
-
-
-/* (Re)create index
- */
-int xs_stildb_index(xs_stildb_t *db)
-{
- stil_node_t *curr;
- size_t i;
-
- /* Free old index */
- if (db->pindex) {
- free(db->pindex);
- db->pindex = NULL;
- }
-
- /* Get size of db */
- curr = db->nodes;
- db->n = 0;
- while (curr) {
- db->n++;
- curr = curr->next;
- }
-
- /* Check number of nodes */
- if (db->n > 0) {
- /* Allocate memory for index-table */
- db->pindex = (stil_node_t **) malloc(sizeof(stil_node_t *) * db->n);
- if (!db->pindex)
- return -1;
-
- /* Get node-pointers to table */
- i = 0;
- curr = db->nodes;
- while (curr && (i < db->n)) {
- db->pindex[i++] = curr;
- curr = curr->next;
- }
-
- /* Sort the indexes */
- qsort(db->pindex, db->n, sizeof(stil_node_t *), xs_stildb_cmp);
- }
-
- return 0;
-}
-
-
-/* Free a given STIL database
- */
-void xs_stildb_free(xs_stildb_t *db)
-{
- stil_node_t *curr, *next;
-
- if (!db)
- return;
-
- /* Free the memory allocated for nodes */
- curr = db->nodes;
- while (curr) {
- next = curr->next;
- xs_stildb_node_free(curr);
- curr = next;
- }
-
- db->nodes = NULL;
-
- /* Free memory allocated for index */
- if (db->pindex) {
- free(db->pindex);
- db->pindex = NULL;
- }
-
- /* Free structure */
- db->n = 0;
- free(db);
-}
-
-
-/* Get STIL information node from database
- */
-stil_node_t *xs_stildb_get_node(xs_stildb_t *db, char *filename)
-{
- stil_node_t keyItem, *key, **item;
-
- /* Check the database pointers */
- if (!db || !db->nodes || !db->pindex)
- return NULL;
-
- /* Look-up index using binary search */
- keyItem.filename = filename;
- key = &keyItem;
- item = bsearch(&key, db->pindex, db->n, sizeof(stil_node_t *), xs_stildb_cmp);
- if (item)
- return *item;
- else
- return NULL;
-}
diff --git a/src/sid/xs_stil.h b/src/sid/xs_stil.h
deleted file mode 100644
index 7ff61184bc23..000000000000
--- a/src/sid/xs_stil.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef XS_STIL_H
-#define XS_STIL_H
-
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Types
- */
-typedef struct {
- char *name, *author, *title, *info;
-} stil_subnode_t;
-
-
-typedef struct _stil_node_t {
- char *filename;
- int nsubTunes;
- stil_subnode_t **subTunes;
- struct _stil_node_t *prev, *next;
-} stil_node_t;
-
-
-typedef struct {
- stil_node_t *nodes, **pindex;
- size_t n;
-} xs_stildb_t;
-
-
-/* Functions
- */
-int xs_stildb_read(xs_stildb_t *, char *);
-int xs_stildb_index(xs_stildb_t *);
-void xs_stildb_free(xs_stildb_t *);
-stil_node_t *xs_stildb_get_node(xs_stildb_t *, char *);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* XS_STIL_H */
diff --git a/src/sid/xs_support.c b/src/sid/xs_support.c
deleted file mode 100644
index 82b56d5a9b7b..000000000000
--- a/src/sid/xs_support.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS)
-
- Miscellaneous support functions
-
- Programmed and designed by Matti 'ccr' Hamalainen <ccr at tnsp.org>
- (C) Copyright 1999-2007 Tecnic Software productions (TNSP)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "xs_support.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-uint16_t xs_fread_be16(VFSFile *f)
-{
- uint16_t val;
- if (vfs_fread (& val, 1, sizeof val, f) != sizeof val)
- return 0;
-
- return GUINT16_FROM_BE (val);
-}
-
-
-uint32_t xs_fread_be32(VFSFile *f)
-{
- uint32_t val;
- if (vfs_fread (& val, 1, sizeof val, f) != sizeof val)
- return 0;
-
- return GUINT32_FROM_BE (val);
-}
-
-
-/* Copy a given string over in *result.
- */
-int xs_pstrcpy(char **result, const char *str)
-{
- /* Check the string pointers */
- if (!result || !str)
- return -1;
-
- /* Allocate memory for destination */
- if (*result)
- free(*result);
- *result = (char *) malloc(strlen(str) + 1);
- if (!*result)
- return -2;
-
- /* Copy to the destination */
- strcpy(*result, str);
-
- return 0;
-}
-
-
-/* Concatenates a given string into string pointed by *result.
- */
-int xs_pstrcat(char **result, const char *str)
-{
- /* Check the string pointers */
- if (!result || !str)
- return -1;
-
- if (*result != NULL) {
- *result = (char *) realloc(*result, strlen(*result) + strlen(str) + 1);
- if (*result == NULL)
- return -1;
- strcat(*result, str);
- } else {
- *result = (char *) malloc(strlen(str) + 1);
- if (*result == NULL)
- return -1;
- strcpy(*result, str);
- }
-
- return 0;
-}
-
-
-void xs_findnext(const char *str, size_t *pos)
-{
- while (str[*pos] && g_ascii_isspace(str[*pos]))
- (*pos)++;
-}
-
-
-void xs_findeol(const char *str, size_t *pos)
-{
- while (str[*pos] && (str[*pos] != '\n') && (str[*pos] != '\r'))
- (*pos)++;
-}
-
-
-void xs_findnum(const char *str, size_t *pos)
-{
- while (str[*pos] && g_ascii_isdigit(str[*pos]))
- (*pos)++;
-}
-
diff --git a/src/sid/xs_support.h b/src/sid/xs_support.h
deleted file mode 100644
index 8af27a1beda9..000000000000
--- a/src/sid/xs_support.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef XS_SUPPORT_H
-#define XS_SUPPORT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/types.h>
-#include <libaudcore/vfs.h>
-
-/* VFS replacement functions
- */
-uint16_t xs_fread_be16(VFSFile *);
-uint32_t xs_fread_be32(VFSFile *);
-
-
-/* Misc functions
- */
-int xs_pstrcpy(char **, const char *);
-int xs_pstrcat(char **, const char *);
-void xs_findnext(const char *, size_t *);
-void xs_findeol(const char *, size_t *);
-void xs_findnum(const char *, size_t *);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* XS_SUPPORT_H */
diff --git a/src/silence-removal/Makefile b/src/silence-removal/Makefile
new file mode 100644
index 000000000000..f11da3a331e0
--- /dev/null
+++ b/src/silence-removal/Makefile
@@ -0,0 +1,13 @@
+PLUGIN = silence-removal${PLUGIN_SUFFIX}
+
+SRCS = silence-removal.cc
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
+
+LD = ${CXX}
+CFLAGS += ${PLUGIN_CFLAGS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
+LIBS += -lm
diff --git a/src/silence-removal/silence-removal.cc b/src/silence-removal/silence-removal.cc
new file mode 100644
index 000000000000..4cc3a7523854
--- /dev/null
+++ b/src/silence-removal/silence-removal.cc
@@ -0,0 +1,192 @@
+/*
+ * Silence Removal Plugin for Audacious
+ * Copyright 2014 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/ringbuf.h>
+#include <libaudcore/runtime.h>
+
+#include <math.h>
+
+#define MAX_BUFFER_SECS 10
+
+class SilenceRemoval : public EffectPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Silence Removal"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ constexpr SilenceRemoval () : EffectPlugin (info, 0, true) {}
+
+ bool init ();
+ void cleanup ();
+
+ void start (int & channels, int & rate);
+ Index<float> & process (Index<float> & data);
+ bool flush (bool force);
+};
+
+EXPORT SilenceRemoval aud_plugin_instance;
+
+const char SilenceRemoval::about[] =
+ N_("Silence Removal Plugin for Audacious\n"
+ "Copyright 2014 John Lindgren");
+
+const char * const SilenceRemoval::defaults[] = {
+ "threshold", "-40",
+ nullptr
+};
+
+const PreferencesWidget SilenceRemoval::widgets[] = {
+ WidgetLabel (N_("<b>Silence Removal</b>")),
+ WidgetSpin (N_("Threshold:"),
+ WidgetInt ("silence-removal", "threshold"),
+ {-60, -20, 1, N_("dB")})
+};
+
+const PluginPreferences SilenceRemoval::prefs = {{widgets}};
+
+static RingBuf<float> buffer;
+static Index<float> output;
+static int current_channels;
+static bool initial_silence;
+
+bool SilenceRemoval::init ()
+{
+ aud_config_set_defaults ("silence-removal", defaults);
+ return true;
+}
+
+void SilenceRemoval::cleanup ()
+{
+ buffer.destroy ();
+ output.clear ();
+}
+
+void SilenceRemoval::start (int & channels, int & rate)
+{
+ buffer.discard ();
+ buffer.alloc (channels * rate * MAX_BUFFER_SECS);
+ output.resize (0);
+
+ current_channels = channels;
+ initial_silence = true;
+}
+
+static float * align_to_frame (float * begin, float * sample, bool align_to_end)
+{
+ if (! sample)
+ return nullptr;
+
+ int offset = sample - begin;
+ if (align_to_end)
+ offset += current_channels;
+
+ return begin + (offset - offset % current_channels);
+}
+
+static void buffer_with_overflow (const float * data, int len)
+{
+ int max = buffer.size ();
+
+ if (len > max)
+ {
+ buffer.move_out (output, -1, -1);
+ output.insert (data, -1, len - max);
+ buffer.copy_in (data + len - max, max);
+ }
+ else
+ {
+ int cur = buffer.len ();
+ if (cur + len > max)
+ buffer.move_out (output, -1, cur + len - max);
+
+ buffer.copy_in (data, len);
+ }
+}
+
+Index<float> & SilenceRemoval::process (Index<float> & data)
+{
+ const int threshold_db = aud_get_int ("silence-removal", "threshold");
+ const float threshold = powf (10.0f, threshold_db / 20.0f);
+
+ float * first_sample = nullptr;
+ float * last_sample = nullptr;
+
+ for (float & sample : data)
+ {
+ if (sample > threshold || sample < -threshold)
+ {
+ if (! first_sample)
+ first_sample = & sample;
+
+ last_sample = & sample;
+ }
+ }
+
+ first_sample = align_to_frame (data.begin (), first_sample, false);
+ last_sample = align_to_frame (data.begin (), last_sample, true);
+
+ output.resize (0);
+
+ if (first_sample)
+ {
+ /* do not skip leading silence if non-silence has been seen */
+ if (! initial_silence)
+ first_sample = data.begin ();
+
+ initial_silence = false;
+
+ /* copy any saved silence from previous call */
+ buffer.move_out (output, -1, -1);
+
+ /* copy non-silent portion */
+ output.insert (first_sample, -1, last_sample - first_sample);
+
+ /* save trailing silence */
+ buffer_with_overflow (last_sample, data.end () - last_sample);
+ }
+ else
+ {
+ /* if non-silence has been seen, save entire silent chunk */
+ if (! initial_silence)
+ buffer_with_overflow (data.begin (), data.len ());
+ }
+
+ return output;
+}
+
+bool SilenceRemoval::flush (bool force)
+{
+ buffer.discard ();
+ output.resize (0);
+
+ initial_silence = true;
+ return true;
+}
diff --git a/src/skins/Makefile b/src/skins/Makefile
index 4496b9d89b4b..14710d5b3b68 100644
--- a/src/skins/Makefile
+++ b/src/skins/Makefile
@@ -1,36 +1,37 @@
PLUGIN = skins${PLUGIN_SUFFIX}
-SRCS = drag-handle.c \
- menus.c \
- plugin.c \
- preset-browser.c \
- preset-list.c \
- skins_cfg.c \
- surface.c \
- ui_skin.c \
- ui_skin_load_ini.c \
- ui_skinned_window.c \
- ui_dock.c \
- util.c \
- ui_vis.c \
- ui_svis.c \
- ui_skinned_menurow.c \
- ui_skinned_button.c \
- ui_skinned_textbox.c \
- ui_skinned_playstatus.c \
- ui_skinned_monostereo.c \
- ui_skinned_number.c \
- ui_skinned_horizontal_slider.c \
- ui_skinned_equalizer_graph.c \
- ui_skinned_equalizer_slider.c \
- ui_skinned_playlist.c \
- ui_skinned_playlist_slider.c \
- ui_main.c \
- ui_equalizer.c \
- ui_playlist.c \
- ui_main_evlisteners.c \
- ui_skinselector.c \
- view.c
+SRCS = drag-handle.cc \
+ menus.cc \
+ plugin.cc \
+ plugin-window.cc \
+ preset-browser.cc \
+ preset-list.cc \
+ skins_cfg.cc \
+ surface.cc \
+ ui_skin.cc \
+ ui_skin_load_ini.cc \
+ ui_skinned_window.cc \
+ ui_dock.cc \
+ util.cc \
+ ui_vis.cc \
+ ui_svis.cc \
+ ui_skinned_menurow.cc \
+ ui_skinned_button.cc \
+ ui_skinned_textbox.cc \
+ ui_skinned_playstatus.cc \
+ ui_skinned_monostereo.cc \
+ ui_skinned_number.cc \
+ ui_skinned_horizontal_slider.cc \
+ ui_skinned_equalizer_graph.cc \
+ ui_skinned_equalizer_slider.cc \
+ ui_skinned_playlist.cc \
+ ui_skinned_playlist_slider.cc \
+ ui_main.cc \
+ ui_equalizer.cc \
+ ui_playlist.cc \
+ ui_main_evlisteners.cc \
+ ui_skinselector.cc \
+ view.cc
include ../../buildsys.mk
include ../../extra.mk
@@ -159,6 +160,8 @@ DATA = Skins/Classic/balance.png \
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
+
CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../.. ${GTK_CFLAGS}
CFLAGS += ${PLUGIN_CFLAGS}
-LIBS += -lm ${GTK_LIBS}
+LIBS += -lm ${GTK_LIBS} -laudgui
diff --git a/src/skins/actions-mainwin.h b/src/skins/actions-mainwin.h
index 2566e2f1ad94..cad103bffaf0 100644
--- a/src/skins/actions-mainwin.h
+++ b/src/skins/actions-mainwin.h
@@ -24,5 +24,7 @@ void action_ab_clear(void);
void action_ab_set(void);
void action_play_file(void);
void action_play_location(void);
+void action_playlist_manager(void);
+void action_search_tool(void);
#endif /* SKINS_ACTIONS_MAINWIN_H */
diff --git a/src/skins/actions-playlist.h b/src/skins/actions-playlist.h
index 255513e22a10..2afd481ed047 100644
--- a/src/skins/actions-playlist.h
+++ b/src/skins/actions-playlist.h
@@ -56,18 +56,26 @@ void action_playlist_reverse_list(void);
void action_playlist_sort_by_title(void);
void action_playlist_sort_by_album(void);
void action_playlist_sort_by_artist(void);
+void action_playlist_sort_by_album_artist(void);
+void action_playlist_sort_by_length(void);
+void action_playlist_sort_by_genre(void);
void action_playlist_sort_by_filename(void);
void action_playlist_sort_by_full_path(void);
void action_playlist_sort_by_date(void);
void action_playlist_sort_by_track_number(void);
+void action_playlist_sort_by_custom_title(void);
void action_playlist_sort_selected_by_title(void);
void action_playlist_sort_selected_by_album(void);
void action_playlist_sort_selected_by_artist(void);
+void action_playlist_sort_selected_by_album_artist(void);
+void action_playlist_sort_selected_by_length(void);
+void action_playlist_sort_selected_by_genre(void);
void action_playlist_sort_selected_by_filename(void);
void action_playlist_sort_selected_by_full_path(void);
void action_playlist_sort_selected_by_date(void);
void action_playlist_sort_selected_by_track_number(void);
+void action_playlist_sort_selected_by_custom_title(void);
void action_playlist_track_info(void);
void action_queue_toggle(void);
diff --git a/src/skins/dnd.h b/src/skins/dnd.h
index e7618ce0e4c6..1d1a634c9ae7 100644
--- a/src/skins/dnd.h
+++ b/src/skins/dnd.h
@@ -39,17 +39,18 @@ enum {
/* Drag data format listing for gtk_drag_dest_set() */
static const GtkTargetEntry drop_types[] = {
- {"text/plain", 0, DROP_PLAINTEXT},
- {"text/uri-list", 0, DROP_URLENCODED},
- {"STRING", 0, DROP_STRING},
- {"interface/x-winamp-skin", 0, DROP_SKIN},
- {"application/x-font-ttf", 0, DROP_FONT},
+ {(char *) "text/plain", 0, DROP_PLAINTEXT},
+ {(char *) "text/uri-list", 0, DROP_URLENCODED},
+ {(char *) "STRING", 0, DROP_STRING},
+ {(char *) "interface/x-winamp-skin", 0, DROP_SKIN},
+ {(char *) "application/x-font-ttf", 0, DROP_FONT},
};
static inline void drag_dest_set (GtkWidget * widget)
{
- gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
- drop_types, ARRAY_LEN (drop_types), GDK_ACTION_COPY | GDK_ACTION_MOVE);
+ gtk_drag_dest_set (widget, (GtkDestDefaults) (GTK_DEST_DEFAULT_MOTION |
+ GTK_DEST_DEFAULT_DROP), drop_types, aud::n_elems (drop_types),
+ (GdkDragAction) (GDK_ACTION_COPY | GDK_ACTION_MOVE));
}
#endif /* SKINS_DND_H */
diff --git a/src/skins/drag-handle.c b/src/skins/drag-handle.c
deleted file mode 100644
index 7dfb8776e592..000000000000
--- a/src/skins/drag-handle.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * drag-handle.c
- * Copyright 2011 John Lindgren
- *
- * This file is part of Audacious.
- *
- * Audacious 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, version 2 or version 3 of the License.
- *
- * Audacious 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
- * Audacious. If not, see <http://www.gnu.org/licenses/>.
- *
- * The Audacious team does not consider modular code linking to Audacious or
- * using our public API to be a derived work.
- */
-
-#include "drag-handle.h"
-
-typedef struct {
- gboolean held;
- gint x_origin, y_origin;
- void (* press) (void);
- void (* drag) (gint x_offset, gint y_offset);
-} DHandleData;
-
-static gboolean handle_button_press (GtkWidget * handle, GdkEventButton * event)
-{
- DHandleData * data = g_object_get_data ((GObject *) handle, "dhandledata");
- g_return_val_if_fail (data, FALSE);
-
- if (event->button != 1)
- return FALSE;
-
- data->held = TRUE;
- data->x_origin = event->x_root;
- data->y_origin = event->y_root;
-
- if (data->press)
- data->press ();
-
- return TRUE;
-}
-
-static gboolean handle_button_release (GtkWidget * handle, GdkEventButton *
- event)
-{
- DHandleData * data = g_object_get_data ((GObject *) handle, "dhandledata");
- g_return_val_if_fail (data, FALSE);
-
- if (event->button != 1)
- return FALSE;
-
- data->held = FALSE;
- return TRUE;
-}
-
-static gboolean handle_motion (GtkWidget * handle, GdkEventMotion * event)
-{
- DHandleData * data = g_object_get_data ((GObject *) handle, "dhandledata");
- g_return_val_if_fail (data, FALSE);
-
- if (! data->held)
- return TRUE;
-
- if (data->drag)
- data->drag (event->x_root - data->x_origin, event->y_root -
- data->y_origin);
-
- return TRUE;
-}
-
-static void handle_destroy (GtkWidget * handle)
-{
- g_free (g_object_get_data ((GObject *) handle, "dhandledata"));
-}
-
-GtkWidget * drag_handle_new (gint w, gint h, void (* press) (void), void
- (* drag) (gint x, gint y))
-{
- GtkWidget * handle = gtk_event_box_new ();
- gtk_event_box_set_visible_window ((GtkEventBox *) handle, FALSE);
- gtk_widget_set_size_request (handle, w, h);
- gtk_widget_add_events (handle, GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
-
- g_signal_connect (handle, "button-press-event", (GCallback)
- handle_button_press, NULL);
- g_signal_connect (handle, "button-release-event", (GCallback)
- handle_button_release, NULL);
- g_signal_connect (handle, "motion-notify-event", (GCallback) handle_motion,
- NULL);
- g_signal_connect (handle, "destroy", (GCallback) handle_destroy, NULL);
-
- DHandleData * data = g_malloc0 (sizeof (DHandleData));
- data->press = press;
- data->drag = drag;
- g_object_set_data ((GObject *) handle, "dhandledata", data);
-
- return handle;
-}
diff --git a/src/skins/drag-handle.cc b/src/skins/drag-handle.cc
new file mode 100644
index 000000000000..9f08895c7ce6
--- /dev/null
+++ b/src/skins/drag-handle.cc
@@ -0,0 +1,106 @@
+/*
+ * drag-handle.c
+ * Copyright 2011 John Lindgren
+ *
+ * This file is part of Audacious.
+ *
+ * Audacious 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, version 2 or version 3 of the License.
+ *
+ * Audacious 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
+ * Audacious. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The Audacious team does not consider modular code linking to Audacious or
+ * using our public API to be a derived work.
+ */
+
+#include "drag-handle.h"
+#include "skins_cfg.h"
+
+typedef struct {
+ gboolean held;
+ int x_origin, y_origin;
+ void (* press) (void);
+ void (* drag) (int x_offset, int y_offset);
+} DHandleData;
+
+static gboolean handle_button_press (GtkWidget * handle, GdkEventButton * event)
+{
+ DHandleData * data = (DHandleData *) g_object_get_data ((GObject *) handle, "dhandledata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (event->button != 1)
+ return FALSE;
+
+ data->held = TRUE;
+ data->x_origin = event->x_root;
+ data->y_origin = event->y_root;
+
+ if (data->press)
+ data->press ();
+
+ return TRUE;
+}
+
+static gboolean handle_button_release (GtkWidget * handle, GdkEventButton *
+ event)
+{
+ DHandleData * data = (DHandleData *) g_object_get_data ((GObject *) handle, "dhandledata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (event->button != 1)
+ return FALSE;
+
+ data->held = FALSE;
+ return TRUE;
+}
+
+static gboolean handle_motion (GtkWidget * handle, GdkEventMotion * event)
+{
+ DHandleData * data = (DHandleData *) g_object_get_data ((GObject *) handle, "dhandledata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (! data->held)
+ return TRUE;
+
+ if (data->drag)
+ data->drag ((event->x_root - data->x_origin) / config.scale,
+ (event->y_root - data->y_origin) / config.scale);
+
+ return TRUE;
+}
+
+static void handle_destroy (GtkWidget * handle)
+{
+ g_free (g_object_get_data ((GObject *) handle, "dhandledata"));
+}
+
+GtkWidget * drag_handle_new (int w, int h, void (* press) (void), void
+ (* drag) (int x, int y))
+{
+ GtkWidget * handle = gtk_event_box_new ();
+ gtk_event_box_set_visible_window ((GtkEventBox *) handle, FALSE);
+ gtk_widget_set_size_request (handle, w * config.scale, h * config.scale);
+ gtk_widget_add_events (handle, GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
+
+ g_signal_connect (handle, "button-press-event", (GCallback)
+ handle_button_press, nullptr);
+ g_signal_connect (handle, "button-release-event", (GCallback)
+ handle_button_release, nullptr);
+ g_signal_connect (handle, "motion-notify-event", (GCallback) handle_motion,
+ nullptr);
+ g_signal_connect (handle, "destroy", (GCallback) handle_destroy, nullptr);
+
+ DHandleData * data = g_new0 (DHandleData, 1);
+ data->press = press;
+ data->drag = drag;
+ g_object_set_data ((GObject *) handle, "dhandledata", data);
+
+ return handle;
+}
diff --git a/src/skins/drag-handle.h b/src/skins/drag-handle.h
index 0907b7896fe3..a8ba6df43b78 100644
--- a/src/skins/drag-handle.h
+++ b/src/skins/drag-handle.h
@@ -24,7 +24,7 @@
#include <gtk/gtk.h>
-GtkWidget * drag_handle_new (gint w, gint h, void (* press) (void), void
- (* drag) (gint x, gint y));
+GtkWidget * drag_handle_new (int w, int h, void (* press) (void), void
+ (* drag) (int x, int y));
#endif
diff --git a/src/skins/draw-compat.h b/src/skins/draw-compat.h
index 4c7a44cb860c..d17890b53bfc 100644
--- a/src/skins/draw-compat.h
+++ b/src/skins/draw-compat.h
@@ -27,17 +27,24 @@
static void widget_realized (GtkWidget * w)
{
GdkWindow * window = gtk_widget_get_window (w);
- gdk_window_set_background_pattern (window, NULL);
+ gdk_window_set_back_pixmap (window, nullptr, FALSE);
}
-#define DRAW_SIGNAL "draw"
-#define DRAW_FUNC_BEGIN(n) static gboolean n (GtkWidget * wid, cairo_t * cr) { \
- g_return_val_if_fail (wid && cr, FALSE);
-#define DRAW_FUNC_END return FALSE; }
+#define DRAW_SIGNAL "expose-event"
+#define DRAW_FUNC_BEGIN(n) static int n (GtkWidget * wid, GdkEventExpose * ev) { \
+ cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (wid));
+#define DRAW_FUNC_END cairo_destroy (cr); \
+ return TRUE; }
+
+/* We set None as the background pixmap in order to avoid flickering. Setting
+ * a blank GtkStyle prevents GTK 2.x from overriding this. */
#define DRAW_CONNECT(w,f) do { \
- g_signal_connect (w, "realize", (GCallback) widget_realized, NULL); \
- g_signal_connect (w, DRAW_SIGNAL, (GCallback) f, NULL); \
+ GtkStyle * style = gtk_style_new (); \
+ gtk_widget_set_style (w, style); \
+ g_object_unref (style); \
+ g_signal_connect (w, "realize", (GCallback) widget_realized, nullptr); \
+ g_signal_connect (w, DRAW_SIGNAL, (GCallback) f, nullptr); \
} while (0);
#endif
diff --git a/src/skins/menus.c b/src/skins/menus.c
deleted file mode 100644
index 0e83d45296ce..000000000000
--- a/src/skins/menus.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * menus.c
- * Copyright 2010-2014 John Lindgren
- *
- * This file is part of Audacious.
- *
- * Audacious 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, version 2 or version 3 of the License.
- *
- * Audacious 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
- * Audacious. If not, see <http://www.gnu.org/licenses/>.
- *
- * The Audacious team does not consider modular code linking to Audacious or
- * using our public API to be a derived work.
- */
-
-#include "menus.h"
-
-#include <gdk/gdkkeysyms.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <libaudgui/libaudgui.h>
-#include <libaudgui/menu.h>
-
-#include "actions-mainwin.h"
-#include "actions-playlist.h"
-#include "preset-browser.h"
-#include "preset-list.h"
-#include "view.h"
-
-#define SHIFT GDK_SHIFT_MASK
-#define CTRL GDK_CONTROL_MASK
-#define ALT GDK_MOD1_MASK
-
-static GtkWidget * menus[UI_MENUS];
-static GtkAccelGroup * accel;
-
-/* note: playback, playlist, and view menus must be created before main menu */
-static GtkWidget * get_menu_playback (void) {return menus[UI_MENU_PLAYBACK]; }
-static GtkWidget * get_menu_playlist (void) {return menus[UI_MENU_PLAYLIST]; }
-static GtkWidget * get_menu_view (void) {return menus[UI_MENU_VIEW]; }
-
-static GtkWidget * get_plugin_menu_main (void) {return aud_get_plugin_menu (AUD_MENU_MAIN); }
-static GtkWidget * get_plugin_menu_playlist (void) {return aud_get_plugin_menu (AUD_MENU_PLAYLIST); }
-static GtkWidget * get_plugin_menu_playlist_add (void) {return aud_get_plugin_menu (AUD_MENU_PLAYLIST_ADD); }
-static GtkWidget * get_plugin_menu_playlist_remove (void) {return aud_get_plugin_menu (AUD_MENU_PLAYLIST_REMOVE); }
-
-static const AudguiMenuItem main_items[] = {
- {N_("Open Files ..."), "document-open", 'l', .func = action_play_file},
- {N_("Open URL ..."), "folder-remote", 'l', CTRL, .func = action_play_location},
- {.sep = TRUE},
- {N_("Playback"), .get_sub = get_menu_playback},
- {N_("Playlist"), .get_sub = get_menu_playlist},
- {N_("View"), .get_sub = get_menu_view},
- {.sep = TRUE},
- {N_("Services"), .get_sub = get_plugin_menu_main},
- {.sep = TRUE},
- {N_("About ..."), "help-about", .func = audgui_show_about_window},
- {N_("Settings ..."), "preferences-system", 'p', CTRL, .func = aud_show_prefs_window},
- {N_("Quit"), "application-exit", 'q', CTRL, .func = aud_drct_quit}
-};
-
-static const AudguiMenuItem playback_items[] = {
- {N_("Song Info ..."), "dialog-information", 'i', .func = audgui_infowin_show_current},
- {.sep = TRUE},
- {N_("Repeat"), NULL, 'r', .cname = "repeat", .hook = "set repeat"},
- {N_("Shuffle"), NULL, 's', .cname = "shuffle", .hook = "set shuffle"},
- {N_("No Playlist Advance"), NULL, 'n', CTRL, .cname = "no_playlist_advance", .hook = "set no_playlist_advance"},
- {N_("Stop After This Song"), NULL, 'm', CTRL, .cname = "stop_after_current_song", .hook = "set stop_after_current_song"},
- {.sep = TRUE},
- {N_("Play"), "media-playback-start", 'x', .func = aud_drct_play},
- {N_("Pause"), "media-playback-pause", 'c', .func = aud_drct_pause},
- {N_("Stop"), "media-playback-stop", 'v', .func = aud_drct_stop},
- {N_("Previous"), "media-skip-backward", 'z', .func = aud_drct_pl_prev},
- {N_("Next"), "media-skip-forward", 'b', .func = aud_drct_pl_next},
- {.sep = TRUE},
- {N_("Set A-B Repeat"), NULL, 'a', .func = action_ab_set},
- {N_("Clear A-B Repeat"), NULL, 'a', SHIFT, .func = action_ab_clear},
- {.sep = TRUE},
- {N_("Jump to Song ..."), "go-jump", 'j',.func = audgui_jump_to_track},
- {N_("Jump to Time ..."), "go-jump", 'j', CTRL, .func = audgui_jump_to_time}
-};
-
-static const AudguiMenuItem playlist_items[] = {
- {N_("Play This Playlist"), "media-playback-start", GDK_KEY_Return, SHIFT, .func = action_playlist_play},
- {.sep = TRUE},
- {N_("New Playlist"), "document-new", 'n', SHIFT, .func = action_playlist_new},
- {N_("Rename Playlist ..."), "insert-text", GDK_KEY_F2, .func = action_playlist_rename},
- {N_("Remove Playlist"), "edit-delete", 'd', SHIFT, .func = action_playlist_delete},
- {.sep = TRUE},
- {N_("Previous Playlist"), "media-skip-backward", GDK_KEY_Tab, SHIFT, .func = action_playlist_prev},
- {N_("Next Playlist"), "media-skip-forward", GDK_KEY_Tab, .func = action_playlist_next},
- {.sep = TRUE},
- {N_("Import Playlist ..."), "document-open", 'o', .func = audgui_import_playlist},
- {N_("Export Playlist ..."), "document-save", 's', SHIFT, .func = audgui_export_playlist},
- {.sep = TRUE},
- {N_("Playlist Manager ..."), "audio-x-generic", 'p', .func = audgui_playlist_manager},
- {N_("Queue Manager ..."), NULL, 'u', CTRL, .func = audgui_queue_manager_show},
- {.sep = TRUE},
- {N_("Refresh Playlist"), "view-refresh", GDK_KEY_F5, .func = action_playlist_refresh_list}
-};
-
-static const AudguiMenuItem view_items[] = {
- {N_("Show Playlist Editor"), NULL, 'e', ALT, .csect = "skins", "playlist_visible",
- .hook = "skins set playlist_visible", .func = view_apply_show_playlist},
- {N_("Show Equalizer"), NULL, 'g', ALT, .csect = "skins", "equalizer_visible",
- .hook = "skins set equalizer_visible", .func = view_apply_show_equalizer},
- {.sep = TRUE},
- {N_("Show Remaining Time"), NULL, 'r', CTRL, .csect = "skins", "show_remaining_time",
- .hook = "skins set show_remaining_time", .func = view_apply_show_remaining},
- {.sep = TRUE},
- {N_("Always on Top"), NULL, 'o', CTRL, .csect = "skins", "always_on_top",
- .hook = "skins set always_on_top", .func = view_apply_on_top},
- {N_("On All Workspaces"), NULL, 's', CTRL, .csect = "skins", "sticky",
- .hook = "skins set sticky", .func = view_apply_sticky},
- {.sep = TRUE},
- {N_("Roll Up Player"), NULL, 'w', CTRL, .csect = "skins", "player_shaded",
- .hook = "skins set player_shaded", .func = view_apply_player_shaded},
- {N_("Roll Up Playlist Editor"), NULL, 'w', SHIFT | CTRL, .csect = "skins", "playlist_shaded",
- .hook = "skins set playlist_shaded", .func = view_apply_playlist_shaded},
- {N_("Roll Up Equalizer"), NULL, 'w', CTRL | ALT, .csect = "skins", "equalizer_shaded",
- .hook = "skins set equalizer_shaded", .func = view_apply_equalizer_shaded}
-};
-
-static const AudguiMenuItem playlist_add_items[] = {
- {N_("Services"), .get_sub = get_plugin_menu_playlist_add},
- {.sep = TRUE},
- {N_("Add URL ..."), "folder-remote", 'h', CTRL, .func = action_playlist_add_url},
- {N_("Add Files ..."), "list-add", 'f', .func = action_playlist_add_files}
-};
-
-static const AudguiMenuItem dupe_items[] = {
- {N_("By Title"), .func = action_playlist_remove_dupes_by_title},
- {N_("By Filename"), .func = action_playlist_remove_dupes_by_filename},
- {N_("By File Path"), .func = action_playlist_remove_dupes_by_full_path}
-};
-
-static const AudguiMenuItem playlist_remove_items[] = {
- {N_("Services"), .get_sub = get_plugin_menu_playlist_remove},
- {.sep = TRUE},
- {N_("Remove All"), "edit-delete", .func = action_playlist_remove_all},
- {N_("Clear Queue"), "edit-clear", 'q', SHIFT, .func = action_playlist_clear_queue},
- {.sep = TRUE},
- {N_("Remove Unavailable Files"), "dialog-warning", .func = action_playlist_remove_unavailable},
- {N_("Remove Duplicates"), "edit-copy", .items = dupe_items, ARRAY_LEN (dupe_items)},
- {.sep = TRUE},
- {N_("Remove Unselected"), "list-remove", .func = action_playlist_remove_unselected},
- {N_("Remove Selected"), "list-remove", GDK_KEY_Delete, .func = action_playlist_remove_selected}
-};
-
-static const AudguiMenuItem playlist_select_items[] = {
- {N_("Search and Select"), "edit-find", 'f', CTRL, .func = action_playlist_search_and_select},
- {.sep = TRUE},
- {N_("Invert Selection"), .func = action_playlist_invert_selection},
- {N_("Select None"), NULL, 'a', SHIFT | CTRL, .func = action_playlist_select_none},
- {N_("Select All"), "edit-select-all", 'a', CTRL, .func = action_playlist_select_all},
-};
-
-static const AudguiMenuItem sort_items[] = {
- {N_("By Title"), .func = action_playlist_sort_by_title},
- {N_("By Album"), .func = action_playlist_sort_by_album},
- {N_("By Artist"), .func = action_playlist_sort_by_artist},
- {N_("By Filename"), .func = action_playlist_sort_by_filename},
- {N_("By File Path"), .func = action_playlist_sort_by_full_path},
- {N_("By Release Date"), .func = action_playlist_sort_by_date},
- {N_("By Track Number"), .func = action_playlist_sort_by_track_number}
-};
-
-static const AudguiMenuItem sort_selected_items[] = {
- {N_("By Title"), .func = action_playlist_sort_selected_by_title},
- {N_("By Album"), .func = action_playlist_sort_selected_by_album},
- {N_("By Artist"), .func = action_playlist_sort_selected_by_artist},
- {N_("By Filename"), .func = action_playlist_sort_selected_by_filename},
- {N_("By File Path"), .func = action_playlist_sort_selected_by_full_path},
- {N_("By Release Date"), .func = action_playlist_sort_selected_by_date},
- {N_("By Track Number"), .func = action_playlist_sort_selected_by_track_number}
-};
-
-static const AudguiMenuItem playlist_sort_items[] = {
- {N_("Randomize List"), NULL, 'r', SHIFT | CTRL, .func = action_playlist_randomize_list},
- {N_("Reverse List"), "view-sort-descending", .func = action_playlist_reverse_list},
- {.sep = TRUE},
- {N_("Sort Selected"), "view-sort-ascending", .items = sort_selected_items, ARRAY_LEN (sort_selected_items)},
- {N_("Sort List"), "view-sort-ascending", .items = sort_items, ARRAY_LEN (sort_items)}
-};
-
-static const AudguiMenuItem playlist_context_items[] = {
- {N_("Song Info ..."), "dialog-information", 'i', ALT, .func = action_playlist_track_info},
- {.sep = TRUE},
- {N_("Cut"), "edit-cut", 'x', CTRL, .func = action_playlist_cut},
- {N_("Copy"), "edit-copy", 'c', CTRL, .func = action_playlist_copy},
- {N_("Paste"), "edit-paste", 'v', CTRL, .func = action_playlist_paste},
- {.sep = TRUE},
- {N_("Queue/Unqueue"), NULL, 'q', .func = action_queue_toggle},
- {.sep = TRUE},
- {N_("Services"), .get_sub = get_plugin_menu_playlist}
-};
-
-static const AudguiMenuItem eq_preset_items[] = {
- {N_("Load Preset ..."), "document-open", .func = eq_preset_load},
- {N_("Load Auto Preset ..."), .func = eq_preset_load_auto},
- {N_("Load Default"), .func = eq_preset_load_default},
- {N_("Load Preset File ..."), .func = eq_preset_load_file},
- {N_("Load EQF File ..."), .func = eq_preset_load_eqf},
- {.sep = TRUE},
- {N_("Save Preset ..."), "document-save", .func = eq_preset_save},
- {N_("Save Auto Preset ..."), .func = eq_preset_save_auto},
- {N_("Save Default"), .func = eq_preset_save_default},
- {N_("Save Preset File ..."), .func = eq_preset_save_file},
- {N_("Save EQF File ..."), .func = eq_preset_save_eqf},
- {.sep = TRUE},
- {N_("Delete Preset ..."), "edit-delete", .func = eq_preset_delete},
- {N_("Delete Auto Preset ..."), .func = eq_preset_delete_auto},
- {.sep = TRUE},
- {N_("Import Winamp Presets ..."), "document-open", .func = eq_preset_import_winamp},
- {.sep = TRUE},
- {N_("Reset to Zero"), "edit-clear", .func = eq_preset_set_zero}
-};
-
-void menu_init (void)
-{
- static const struct {
- const AudguiMenuItem * items;
- int n_items;
- } table[] = {
- {main_items, ARRAY_LEN (main_items)},
- {playback_items, ARRAY_LEN (playback_items)},
- {playlist_items, ARRAY_LEN (playlist_items)},
- {view_items, ARRAY_LEN (view_items)},
- {playlist_add_items, ARRAY_LEN (playlist_add_items)},
- {playlist_remove_items, ARRAY_LEN (playlist_remove_items)},
- {playlist_select_items, ARRAY_LEN (playlist_select_items)},
- {playlist_sort_items, ARRAY_LEN (playlist_sort_items)},
- {playlist_context_items, ARRAY_LEN (playlist_context_items)},
- {eq_preset_items, ARRAY_LEN (eq_preset_items)}
- };
-
- accel = gtk_accel_group_new ();
-
- for (int i = UI_MENUS; i --; )
- {
- menus[i] = gtk_menu_new ();
- audgui_menu_init (menus[i], table[i].items, table[i].n_items, accel);
- g_signal_connect (menus[i], "destroy", (GCallback) gtk_widget_destroyed, & menus[i]);
- }
-}
-
-void menu_cleanup (void)
-{
- for (int i = 0; i < UI_MENUS; i ++)
- {
- if (menus[i])
- gtk_widget_destroy (menus[i]);
- }
-
- g_object_unref (accel);
- accel = NULL;
-}
-
-GtkAccelGroup * menu_get_accel_group (void)
-{
- return accel;
-}
-
-static void get_monitor_geometry (GdkScreen * screen, gint x, gint y, GdkRectangle * geom)
-{
- int monitors = gdk_screen_get_n_monitors (screen);
-
- for (int i = 0; i < monitors; i ++)
- {
- gdk_screen_get_monitor_geometry (screen, i, geom);
-
- if (x >= geom->x && x < geom->x + geom->width && y >= geom->y && y < geom->y + geom->height)
- return;
- }
-
- /* fall back to entire screen */
- geom->x = 0;
- geom->y = 0;
- geom->width = gdk_screen_get_width (screen);
- geom->height = gdk_screen_get_height (screen);
-}
-
-typedef struct {
- int x, y;
- bool_t leftward, upward;
-} MenuPosition;
-
-static void position_menu (GtkMenu * menu, int * x, int * y, bool_t * push_in, void * data)
-{
- const MenuPosition * pos = data;
-
- GdkRectangle geom;
- get_monitor_geometry (gtk_widget_get_screen ((GtkWidget *) menu), pos->x, pos->y, & geom);
-
- GtkRequisition request;
- gtk_widget_get_preferred_size ((GtkWidget *) menu, NULL, & request);
-
- if (pos->leftward)
- * x = MAX (pos->x - request.width, geom.x);
- else
- * x = MIN (pos->x, geom.x + geom.width - request.width);
-
- if (pos->upward)
- * y = MAX (pos->y - request.height, geom.y);
- else
- * y = MIN (pos->y, geom.y + geom.height - request.height);
-}
-
-void menu_popup (int id, int x, int y, bool_t leftward, bool_t upward,
- int button, int time)
-{
- const MenuPosition pos = {x, y, leftward, upward};
- gtk_menu_popup ((GtkMenu *) menus[id], NULL, NULL, position_menu, (void *) & pos, button, time);
-}
diff --git a/src/skins/menus.cc b/src/skins/menus.cc
new file mode 100644
index 000000000000..66925e963ecd
--- /dev/null
+++ b/src/skins/menus.cc
@@ -0,0 +1,311 @@
+/*
+ * menus.c
+ * Copyright 2010-2014 John Lindgren
+ *
+ * This file is part of Audacious.
+ *
+ * Audacious 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, version 2 or version 3 of the License.
+ *
+ * Audacious 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
+ * Audacious. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The Audacious team does not consider modular code linking to Audacious or
+ * using our public API to be a derived work.
+ */
+
+#include "menus.h"
+
+#include <gdk/gdkkeysyms.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/runtime.h>
+#include <libaudgui/libaudgui.h>
+#include <libaudgui/libaudgui-gtk.h>
+#include <libaudgui/menu.h>
+
+#include "actions-mainwin.h"
+#include "actions-playlist.h"
+#include "preset-browser.h"
+#include "preset-list.h"
+#include "view.h"
+
+#define SHIFT GDK_SHIFT_MASK
+#define CTRL GDK_CONTROL_MASK
+#define ALT GDK_MOD1_MASK
+
+#define SHIFT_CTRL (GdkModifierType) (SHIFT | CTRL)
+#define CTRL_ALT (GdkModifierType) (CTRL | ALT)
+#define NO_MOD (GdkModifierType) 0
+
+#define NO_KEY 0, NO_MOD
+
+static GtkWidget * menus[UI_MENUS];
+static GtkAccelGroup * accel;
+
+/* note: playback, playlist, and view menus must be created before main menu */
+static GtkWidget * get_menu_playback (void) {return menus[UI_MENU_PLAYBACK]; }
+static GtkWidget * get_menu_playlist (void) {return menus[UI_MENU_PLAYLIST]; }
+static GtkWidget * get_menu_view (void) {return menus[UI_MENU_VIEW]; }
+
+static GtkWidget * get_plugin_menu_main (void) {return audgui_get_plugin_menu (AudMenuID::Main); }
+static GtkWidget * get_plugin_menu_playlist (void) {return audgui_get_plugin_menu (AudMenuID::Playlist); }
+static GtkWidget * get_plugin_menu_playlist_add (void) {return audgui_get_plugin_menu (AudMenuID::PlaylistAdd); }
+static GtkWidget * get_plugin_menu_playlist_remove (void) {return audgui_get_plugin_menu (AudMenuID::PlaylistRemove); }
+
+static const AudguiMenuItem main_items[] = {
+ MenuCommand (N_("Open Files ..."), "document-open", 'l', NO_MOD, action_play_file),
+ MenuCommand (N_("Open URL ..."), "folder-remote", 'l', CTRL, action_play_location),
+ MenuCommand (N_("Search Library"), "edit-find", 'y', NO_MOD, action_search_tool),
+ MenuSep (),
+ MenuSub (N_("Playback"), nullptr, get_menu_playback),
+ MenuSub (N_("Playlist"), nullptr, get_menu_playlist),
+ MenuSub (N_("View"), nullptr, get_menu_view),
+ MenuSep (),
+ MenuSub (N_("Services"), nullptr, get_plugin_menu_main),
+ MenuSep (),
+ MenuCommand (N_("About ..."), "help-about", NO_KEY, audgui_show_about_window),
+ MenuCommand (N_("Settings ..."), "preferences-system", 'p', CTRL, audgui_show_prefs_window),
+ MenuCommand (N_("Quit"), "application-exit", 'q', CTRL, aud_quit)
+};
+
+static const AudguiMenuItem playback_items[] = {
+ MenuCommand (N_("Song Info ..."), "dialog-information", 'i', NO_MOD, audgui_infowin_show_current),
+ MenuSep (),
+ MenuToggle (N_("Repeat"), nullptr, 'r', NO_MOD, nullptr, "repeat", nullptr, "set repeat"),
+ MenuToggle (N_("Shuffle"), nullptr, 's', NO_MOD, nullptr, "shuffle", nullptr, "set shuffle"),
+ MenuToggle (N_("No Playlist Advance"), nullptr, 'n', CTRL, nullptr, "no_playlist_advance", nullptr, "set no_playlist_advance"),
+ MenuToggle (N_("Stop After This Song"), nullptr, 'm', CTRL, nullptr, "stop_after_current_song", nullptr, "set stop_after_current_song"),
+ MenuSep (),
+ MenuCommand (N_("Play"), "media-playback-start", 'x', NO_MOD, aud_drct_play),
+ MenuCommand (N_("Pause"), "media-playback-pause", 'c', NO_MOD, aud_drct_pause),
+ MenuCommand (N_("Stop"), "media-playback-stop", 'v', NO_MOD, aud_drct_stop),
+ MenuCommand (N_("Previous"), "media-skip-backward", 'z', NO_MOD, aud_drct_pl_prev),
+ MenuCommand (N_("Next"), "media-skip-forward", 'b', NO_MOD, aud_drct_pl_next),
+ MenuSep (),
+ MenuCommand (N_("Set A-B Repeat"), nullptr, 'a', NO_MOD, action_ab_set),
+ MenuCommand (N_("Clear A-B Repeat"), nullptr, 'a', SHIFT, action_ab_clear),
+ MenuSep (),
+ MenuCommand (N_("Jump to Song ..."), "go-jump", 'j', NO_MOD, audgui_jump_to_track),
+ MenuCommand (N_("Jump to Time ..."), "go-jump", 'j', CTRL, audgui_jump_to_time)
+};
+
+static const AudguiMenuItem playlist_items[] = {
+ MenuCommand (N_("Play/Resume"), "media-playback-start", GDK_KEY_Return, SHIFT, action_playlist_play),
+ MenuSep (),
+ MenuCommand (N_("New Playlist"), "document-new", 'n', SHIFT, action_playlist_new),
+ MenuCommand (N_("Rename Playlist ..."), "insert-text", GDK_KEY_F2, NO_MOD, action_playlist_rename),
+ MenuCommand (N_("Remove Playlist"), "edit-delete", 'd', SHIFT, action_playlist_delete),
+ MenuSep (),
+ MenuCommand (N_("Previous Playlist"), "media-skip-backward", GDK_KEY_Tab, SHIFT, action_playlist_prev),
+ MenuCommand (N_("Next Playlist"), "media-skip-forward", GDK_KEY_Tab, NO_MOD, action_playlist_next),
+ MenuSep (),
+ MenuCommand (N_("Import Playlist ..."), "document-open", 'o', NO_MOD, audgui_import_playlist),
+ MenuCommand (N_("Export Playlist ..."), "document-save", 's', SHIFT, audgui_export_playlist),
+ MenuSep (),
+ MenuCommand (N_("Playlist Manager ..."), "audio-x-generic", 'p', NO_MOD, action_playlist_manager),
+ MenuCommand (N_("Queue Manager ..."), nullptr, 'u', CTRL, audgui_queue_manager_show),
+ MenuSep (),
+ MenuCommand (N_("Refresh Playlist"), "view-refresh", GDK_KEY_F5, NO_MOD, action_playlist_refresh_list)
+};
+
+static const AudguiMenuItem view_items[] = {
+ MenuToggle (N_("Show Playlist Editor"), nullptr, 'e', ALT, "skins", "playlist_visible", view_apply_show_playlist, "skins set playlist_visible"),
+ MenuToggle (N_("Show Equalizer"), nullptr, 'g', ALT, "skins", "equalizer_visible", view_apply_show_equalizer, "skins set equalizer_visible"),
+ MenuSep (),
+ MenuToggle (N_("Show Remaining Time"), nullptr, 'r', CTRL, "skins", "show_remaining_time", view_apply_show_remaining, "skins set show_remaining_time"),
+ MenuSep (),
+ MenuToggle (N_("Always on Top"), nullptr, 'o', CTRL, "skins", "always_on_top", view_apply_on_top, "skins set always_on_top"),
+ MenuToggle (N_("On All Workspaces"), nullptr, 's', CTRL, "skins", "sticky", view_apply_sticky, "skins set sticky"),
+ MenuSep (),
+ MenuToggle (N_("Roll Up Player"), nullptr, 'w', CTRL, "skins", "player_shaded", view_apply_player_shaded, "skins set player_shaded"),
+ MenuToggle (N_("Roll Up Playlist Editor"), nullptr, 'w', SHIFT_CTRL, "skins", "playlist_shaded", view_apply_playlist_shaded, "skins set playlist_shaded"),
+ MenuToggle (N_("Roll Up Equalizer"), nullptr, 'w', CTRL_ALT, "skins", "equalizer_shaded", view_apply_equalizer_shaded, "skins set equalizer_shaded"),
+ MenuSep (),
+ MenuToggle (N_("Double Size"), nullptr, 'd', CTRL, "skins", "double_size", view_apply_double_size, "skins set double_size")
+};
+
+static const AudguiMenuItem playlist_add_items[] = {
+ MenuSub (N_("Services"), nullptr, get_plugin_menu_playlist_add),
+ MenuSep (),
+ MenuCommand (N_("Add URL ..."), "folder-remote", 'h', CTRL, action_playlist_add_url),
+ MenuCommand (N_("Add Files ..."), "list-add", 'f', NO_MOD, action_playlist_add_files)
+};
+
+static const AudguiMenuItem dupe_items[] = {
+ MenuCommand (N_("By Title"), nullptr, NO_KEY, action_playlist_remove_dupes_by_title),
+ MenuCommand (N_("By File Name"), nullptr, NO_KEY, action_playlist_remove_dupes_by_filename),
+ MenuCommand (N_("By File Path"), nullptr, NO_KEY, action_playlist_remove_dupes_by_full_path)
+};
+
+static const AudguiMenuItem playlist_remove_items[] = {
+ MenuSub (N_("Services"), nullptr, get_plugin_menu_playlist_remove),
+ MenuSep (),
+ MenuCommand (N_("Remove All"), "edit-delete", NO_KEY, action_playlist_remove_all),
+ MenuCommand (N_("Clear Queue"), "edit-clear", 'q', SHIFT, action_playlist_clear_queue),
+ MenuSep (),
+ MenuCommand (N_("Remove Unavailable Files"), "dialog-warning", NO_KEY, action_playlist_remove_unavailable),
+ MenuSub (N_("Remove Duplicates"), "edit-copy", {dupe_items}),
+ MenuSep (),
+ MenuCommand (N_("Remove Unselected"), "list-remove", NO_KEY, action_playlist_remove_unselected),
+ MenuCommand (N_("Remove Selected"), "list-remove", GDK_KEY_Delete, NO_MOD, action_playlist_remove_selected)
+};
+
+static const AudguiMenuItem playlist_select_items[] = {
+ MenuCommand (N_("Search and Select"), "edit-find", 'f', CTRL, action_playlist_search_and_select),
+ MenuSep (),
+ MenuCommand (N_("Invert Selection"), nullptr, NO_KEY, action_playlist_invert_selection),
+ MenuCommand (N_("Select None"), nullptr, 'a', SHIFT_CTRL, action_playlist_select_none),
+ MenuCommand (N_("Select All"), "edit-select-all", 'a', CTRL, action_playlist_select_all),
+};
+
+static const AudguiMenuItem sort_items[] = {
+ MenuCommand (N_("By Track Number"), nullptr, NO_KEY, action_playlist_sort_by_track_number),
+ MenuCommand (N_("By Title"), nullptr, NO_KEY, action_playlist_sort_by_title),
+ MenuCommand (N_("By Artist"), nullptr, NO_KEY, action_playlist_sort_by_artist),
+ MenuCommand (N_("By Album"), nullptr, NO_KEY, action_playlist_sort_by_album),
+ MenuCommand (N_("By Album Artist"), nullptr, NO_KEY, action_playlist_sort_by_album_artist),
+ MenuCommand (N_("By Release Date"), nullptr, NO_KEY, action_playlist_sort_by_date),
+ MenuCommand (N_("By Genre"), nullptr, NO_KEY, action_playlist_sort_by_genre),
+ MenuCommand (N_("By Length"), nullptr, NO_KEY, action_playlist_sort_by_length),
+ MenuCommand (N_("By File Name"), nullptr, NO_KEY, action_playlist_sort_by_filename),
+ MenuCommand (N_("By File Path"), nullptr, NO_KEY, action_playlist_sort_by_full_path),
+ MenuCommand (N_("By Custom Title"), nullptr, NO_KEY, action_playlist_sort_by_custom_title)
+};
+
+static const AudguiMenuItem sort_selected_items[] = {
+ MenuCommand (N_("By Track Number"), nullptr, NO_KEY, action_playlist_sort_selected_by_track_number),
+ MenuCommand (N_("By Title"), nullptr, NO_KEY, action_playlist_sort_selected_by_title),
+ MenuCommand (N_("By Artist"), nullptr, NO_KEY, action_playlist_sort_selected_by_artist),
+ MenuCommand (N_("By Album"), nullptr, NO_KEY, action_playlist_sort_selected_by_album),
+ MenuCommand (N_("By Album Artist"), nullptr, NO_KEY, action_playlist_sort_selected_by_album_artist),
+ MenuCommand (N_("By Genre"), nullptr, NO_KEY, action_playlist_sort_selected_by_genre),
+ MenuCommand (N_("By Release Date"), nullptr, NO_KEY, action_playlist_sort_selected_by_date),
+ MenuCommand (N_("By Length"), nullptr, NO_KEY, action_playlist_sort_selected_by_length),
+ MenuCommand (N_("By File Name"), nullptr, NO_KEY, action_playlist_sort_selected_by_filename),
+ MenuCommand (N_("By File Path"), nullptr, NO_KEY, action_playlist_sort_selected_by_full_path),
+ MenuCommand (N_("By Custom Title"), nullptr, NO_KEY, action_playlist_sort_selected_by_custom_title)
+};
+
+static const AudguiMenuItem playlist_sort_items[] = {
+ MenuCommand (N_("Randomize List"), nullptr, 'r', SHIFT_CTRL, action_playlist_randomize_list),
+ MenuCommand (N_("Reverse List"), "view-sort-descending", NO_KEY, action_playlist_reverse_list),
+ MenuSep (),
+ MenuSub (N_("Sort Selected"), "view-sort-ascending", {sort_selected_items}),
+ MenuSub (N_("Sort List"), "view-sort-ascending", {sort_items})
+};
+
+static const AudguiMenuItem playlist_context_items[] = {
+ MenuCommand (N_("Song Info ..."), "dialog-information", 'i', ALT, action_playlist_track_info),
+ MenuSep (),
+ MenuCommand (N_("Cut"), "edit-cut", 'x', CTRL, action_playlist_cut),
+ MenuCommand (N_("Copy"), "edit-copy", 'c', CTRL, action_playlist_copy),
+ MenuCommand (N_("Paste"), "edit-paste", 'v', CTRL, action_playlist_paste),
+ MenuSep (),
+ MenuCommand (N_("Queue/Unqueue"), nullptr, 'q', NO_MOD, action_queue_toggle),
+ MenuSep (),
+ MenuSub (N_("Services"), nullptr, get_plugin_menu_playlist)
+};
+
+static const AudguiMenuItem eq_preset_items[] = {
+ MenuCommand (N_("Load Preset ..."), "document-open", NO_KEY, eq_preset_load),
+ MenuCommand (N_("Load Auto Preset ..."), nullptr, NO_KEY, eq_preset_load_auto),
+ MenuCommand (N_("Load Default"), nullptr, NO_KEY, eq_preset_load_default),
+ MenuCommand (N_("Load Preset File ..."), nullptr, NO_KEY, eq_preset_load_file),
+ MenuCommand (N_("Load EQF File ..."), nullptr, NO_KEY, eq_preset_load_eqf),
+ MenuSep (),
+ MenuCommand (N_("Save Preset ..."), "document-save", NO_KEY, eq_preset_save),
+ MenuCommand (N_("Save Auto Preset ..."), nullptr, NO_KEY, eq_preset_save_auto),
+ MenuCommand (N_("Save Default"), nullptr, NO_KEY, eq_preset_save_default),
+ MenuCommand (N_("Save Preset File ..."), nullptr, NO_KEY, eq_preset_save_file),
+ MenuCommand (N_("Save EQF File ..."), nullptr, NO_KEY, eq_preset_save_eqf),
+ MenuSep (),
+ MenuCommand (N_("Delete Preset ..."), "edit-delete", NO_KEY, eq_preset_delete),
+ MenuCommand (N_("Delete Auto Preset ..."), nullptr, NO_KEY, eq_preset_delete_auto),
+ MenuSep (),
+ MenuCommand (N_("Import Winamp Presets ..."), "document-open", NO_KEY, eq_preset_import_winamp),
+ MenuSep (),
+ MenuCommand (N_("Reset to Zero"), "edit-clear", NO_KEY, eq_preset_set_zero)
+};
+
+void menu_init (void)
+{
+ static const ArrayRef<AudguiMenuItem> table[] = {
+ {main_items},
+ {playback_items},
+ {playlist_items},
+ {view_items},
+ {playlist_add_items},
+ {playlist_remove_items},
+ {playlist_select_items},
+ {playlist_sort_items},
+ {playlist_context_items},
+ {eq_preset_items}
+ };
+
+ accel = gtk_accel_group_new ();
+
+ for (int i = UI_MENUS; i --; )
+ {
+ menus[i] = gtk_menu_new ();
+ audgui_menu_init (menus[i], table[i], accel);
+ g_signal_connect (menus[i], "destroy", (GCallback) gtk_widget_destroyed, & menus[i]);
+ }
+}
+
+void menu_cleanup (void)
+{
+ for (int i = 0; i < UI_MENUS; i ++)
+ {
+ if (menus[i])
+ gtk_widget_destroy (menus[i]);
+ }
+
+ g_object_unref (accel);
+ accel = nullptr;
+}
+
+GtkAccelGroup * menu_get_accel_group (void)
+{
+ return accel;
+}
+
+typedef struct {
+ int x, y;
+ gboolean leftward, upward;
+} MenuPosition;
+
+static void position_menu (GtkMenu * menu, int * x, int * y, gboolean * push_in, void * data)
+{
+ const MenuPosition * pos = (MenuPosition *) data;
+
+ GdkRectangle geom;
+ audgui_get_monitor_geometry (gtk_widget_get_screen ((GtkWidget *) menu), pos->x, pos->y, & geom);
+
+ GtkRequisition request;
+ gtk_widget_size_request ((GtkWidget *) menu, & request);
+
+ if (pos->leftward)
+ * x = aud::max (pos->x - request.width, geom.x);
+ else
+ * x = aud::min (pos->x, geom.x + geom.width - request.width);
+
+ if (pos->upward)
+ * y = aud::max (pos->y - request.height, geom.y);
+ else
+ * y = aud::min (pos->y, geom.y + geom.height - request.height);
+}
+
+void menu_popup (int id, int x, int y, gboolean leftward, gboolean upward,
+ int button, int time)
+{
+ const MenuPosition pos = {x, y, leftward, upward};
+ gtk_menu_popup ((GtkMenu *) menus[id], nullptr, nullptr, position_menu, (void *) & pos, button, time);
+}
diff --git a/src/skins/menus.h b/src/skins/menus.h
index fea57657ea3f..bbd211a0c761 100644
--- a/src/skins/menus.h
+++ b/src/skins/menus.h
@@ -23,7 +23,6 @@
#define SKINS_MENUS_H
#include <gtk/gtk.h>
-#include <libaudcore/core.h>
enum
{
@@ -44,6 +43,6 @@ void menu_init ();
void menu_cleanup ();
GtkAccelGroup * menu_get_accel_group (void);
-void menu_popup (int id, int x, int y, bool_t leftward, bool_t upward, int button, int time);
+void menu_popup (int id, int x, int y, gboolean leftward, gboolean upward, int button, int time);
#endif /* SKINS_MENUS_H */
diff --git a/src/skins/plugin-window.cc b/src/skins/plugin-window.cc
new file mode 100644
index 000000000000..afb4b0025513
--- /dev/null
+++ b/src/skins/plugin-window.cc
@@ -0,0 +1,175 @@
+/*
+ * plugin-window.c
+ * Copyright 2014 John Lindgren
+ *
+ * This file is part of Audacious.
+ *
+ * Audacious 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, version 2 or version 3 of the License.
+ *
+ * Audacious 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
+ * Audacious. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The Audacious team does not consider modular code linking to Audacious or
+ * using our public API to be a derived work.
+ */
+
+/* TODO (someday): implement proper docking for plugin windows */
+
+#include "plugin-window.h"
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/plugins.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/runtime.h>
+
+static GList * windows;
+
+static gboolean delete_cb (GtkWidget * window, GdkEvent * event, PluginHandle * plugin)
+{
+ aud_plugin_enable (plugin, false);
+ return true;
+}
+
+static gboolean escape_cb (GtkWidget * widget, GdkEventKey * event, PluginHandle * plugin)
+{
+ if (event->keyval != GDK_KEY_Escape)
+ return false;
+
+ aud_plugin_enable (plugin, false);
+ return true;
+}
+
+static void add_dock_plugin (PluginHandle * plugin, void * unused)
+{
+ GtkWidget * widget = (GtkWidget *) aud_plugin_get_gtk_widget (plugin);
+
+ if (widget)
+ {
+ GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title ((GtkWindow *) window, aud_plugin_get_name (plugin));
+ gtk_container_add ((GtkContainer *) window, widget);
+
+ g_object_set_data ((GObject *) window, "skins-plugin-id", plugin);
+ g_signal_connect (window, "delete-event", (GCallback) delete_cb, plugin);
+ g_signal_connect (widget, "key-press-event", (GCallback) escape_cb, plugin);
+
+ windows = g_list_prepend (windows, window);
+
+ const char * basename = aud_plugin_get_basename (plugin);
+ String pos_str = aud_get_str ("skins-layout", basename);
+ int pos[4];
+
+ if (pos_str && str_to_int_array (pos_str, pos, aud::n_elems (pos)))
+ {
+ gtk_window_set_default_size ((GtkWindow *) window, pos[2], pos[3]);
+ gtk_window_move ((GtkWindow *) window, pos[0], pos[1]);
+ }
+ else
+ gtk_window_set_default_size ((GtkWindow *) window, 300, 200);
+
+ if (aud_ui_is_shown ())
+ gtk_widget_show_all (window);
+ }
+}
+
+static void save_window_size (GtkWidget * window)
+{
+ auto plugin = (PluginHandle *) g_object_get_data ((GObject *) window, "skins-plugin-id");
+
+ if (! plugin || ! gtk_widget_get_visible (window))
+ return;
+
+ int pos[4];
+ gtk_window_get_position ((GtkWindow *) window, & pos[0], & pos[1]);
+ gtk_window_get_size ((GtkWindow *) window, & pos[2], & pos[3]);
+
+ const char * basename = aud_plugin_get_basename (plugin);
+ StringBuf pos_str = int_array_to_str (pos, aud::n_elems (pos));
+ aud_set_str ("skins-layout", basename, pos_str);
+}
+
+static int find_cb (GtkWidget * window, PluginHandle * plugin)
+{
+ return (g_object_get_data ((GObject *) window, "skins-plugin-id") != plugin);
+}
+
+static void remove_dock_plugin (PluginHandle * plugin, void * unused)
+{
+ GList * node = g_list_find_custom (windows, plugin, (GCompareFunc) find_cb);
+
+ if (node)
+ {
+ save_window_size ((GtkWidget *) node->data);
+ gtk_widget_destroy ((GtkWidget *) node->data);
+ windows = g_list_delete_link (windows, node);
+ }
+}
+
+void create_plugin_windows (void)
+{
+ for (PluginHandle * plugin : aud_plugin_list (PluginType::General))
+ {
+ if (aud_plugin_get_enabled (plugin))
+ add_dock_plugin (plugin, nullptr);
+ }
+
+ for (PluginHandle * plugin : aud_plugin_list (PluginType::Vis))
+ {
+ if (aud_plugin_get_enabled (plugin))
+ add_dock_plugin (plugin, nullptr);
+ }
+
+ hook_associate ("dock plugin enabled", (HookFunction) add_dock_plugin, nullptr);
+ hook_associate ("dock plugin disabled", (HookFunction) remove_dock_plugin, nullptr);
+}
+
+void show_plugin_windows (void)
+{
+ g_list_foreach (windows, (GFunc) gtk_widget_show_all, nullptr);
+}
+
+void focus_plugin_window (PluginHandle * plugin)
+{
+ GList * node = g_list_find_custom (windows, plugin, (GCompareFunc) find_cb);
+ if (node)
+ gtk_window_present ((GtkWindow *) node->data);
+
+ aud_plugin_send_message (plugin, "grab focus", nullptr, 0);
+}
+
+void hide_plugin_windows (void)
+{
+ g_list_foreach (windows, (GFunc) save_window_size, nullptr);
+ g_list_foreach (windows, (GFunc) gtk_widget_hide, nullptr);
+}
+
+void destroy_plugin_windows (void)
+{
+ for (PluginHandle * plugin : aud_plugin_list (PluginType::General))
+ {
+ if (aud_plugin_get_enabled (plugin))
+ remove_dock_plugin (plugin, nullptr);
+ }
+
+ for (PluginHandle * plugin : aud_plugin_list (PluginType::Vis))
+ {
+ if (aud_plugin_get_enabled (plugin))
+ remove_dock_plugin (plugin, nullptr);
+ }
+
+ hook_dissociate ("dock plugin enabled", (HookFunction) add_dock_plugin);
+ hook_dissociate ("dock plugin disabled", (HookFunction) remove_dock_plugin);
+
+ g_warn_if_fail (! windows);
+}
diff --git a/src/skins/plugin-window.h b/src/skins/plugin-window.h
new file mode 100644
index 000000000000..33598939ce94
--- /dev/null
+++ b/src/skins/plugin-window.h
@@ -0,0 +1,33 @@
+/*
+ * plugin-window.h
+ * Copyright 2014 John Lindgren
+ *
+ * This file is part of Audacious.
+ *
+ * Audacious 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, version 2 or version 3 of the License.
+ *
+ * Audacious 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
+ * Audacious. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The Audacious team does not consider modular code linking to Audacious or
+ * using our public API to be a derived work.
+ */
+
+#ifndef SKINS_PLUGIN_WINDOW_H
+#define SKINS_PLUGIN_WINDOW_H
+
+class PluginHandle;
+
+void create_plugin_windows (void);
+void show_plugin_windows (void);
+void focus_plugin_window (PluginHandle * plugin);
+void hide_plugin_windows (void);
+void destroy_plugin_windows (void);
+
+#endif /* SKINS_PLUGIN_WINDOW_H */
diff --git a/src/skins/plugin.c b/src/skins/plugin.c
deleted file mode 100644
index d7701f4aa03d..000000000000
--- a/src/skins/plugin.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2008 Tomasz MoÅ
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <stdlib.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui.h>
-
-#include "menus.h"
-#include "plugin.h"
-#include "preset-browser.h"
-#include "preset-list.h"
-#include "skins_cfg.h"
-#include "ui_equalizer.h"
-#include "ui_main.h"
-#include "ui_main_evlisteners.h"
-#include "ui_playlist.h"
-#include "ui_skin.h"
-#include "view.h"
-
-gchar * skins_paths[SKINS_PATH_COUNT];
-
-static gboolean skins_init (void);
-static void skins_cleanup (void);
-
-AUD_IFACE_PLUGIN
-(
- .name = N_("Winamp Classic Interface"),
- .domain = PACKAGE,
- .init = skins_init,
- .cleanup = skins_cleanup,
- .prefs = & skins_prefs,
- .show = view_show_player
-)
-
-static gint update_source;
-
-static void skins_free_paths(void) {
- int i;
-
- for (i = 0; i < SKINS_PATH_COUNT; i++) {
- g_free(skins_paths[i]);
- skins_paths[i] = NULL;
- }
-}
-
-static void skins_init_paths() {
- char *xdg_data_home;
- char *xdg_cache_home;
-
- xdg_data_home = (getenv("XDG_DATA_HOME") == NULL
- ? g_build_filename(g_get_home_dir(), ".local", "share", NULL)
- : g_strdup(getenv("XDG_DATA_HOME")));
- xdg_cache_home = (getenv("XDG_CACHE_HOME") == NULL
- ? g_build_filename(g_get_home_dir(), ".cache", NULL)
- : g_strdup(getenv("XDG_CACHE_HOME")));
-
- skins_paths[SKINS_PATH_USER_SKIN_DIR] =
- g_build_filename(xdg_data_home, "audacious", "Skins", NULL);
- skins_paths[SKINS_PATH_SKIN_THUMB_DIR] =
- g_build_filename(xdg_cache_home, "audacious", "thumbs", NULL);
-
- g_free(xdg_data_home);
- g_free(xdg_cache_home);
-}
-
-static gboolean update_cb (void * unused)
-{
- mainwin_update_song_info ();
- return TRUE;
-}
-
-static gboolean skins_init (void)
-{
- skins_init_paths();
- skins_cfg_load();
-
- menu_init ();
-
- char * skin = aud_get_str ("skins", "skin");
- init_skins (skin);
- str_unref (skin);
-
- view_apply_on_top ();
- view_apply_sticky ();
-
- if (aud_drct_get_playing ())
- {
- ui_main_evlistener_playback_begin (NULL, NULL);
- if (aud_drct_get_paused ())
- ui_main_evlistener_playback_pause (NULL, NULL);
- }
- else
- mainwin_update_song_info ();
-
- update_source = g_timeout_add (250, update_cb, NULL);
-
- return TRUE;
-}
-
-static void skins_cleanup (void)
-{
- mainwin_unhook ();
- playlistwin_unhook ();
- g_source_remove (update_source);
-
- skins_cfg_save();
-
- cleanup_skins();
- skins_free_paths();
-
- eq_preset_browser_cleanup ();
- eq_preset_list_cleanup ();
-
- menu_cleanup ();
-}
-
-bool_t handle_window_close (void)
-{
- bool_t handled = FALSE;
- hook_call ("window close", & handled);
-
- if (! handled)
- aud_drct_quit ();
-
- return TRUE;
-}
diff --git a/src/skins/plugin.cc b/src/skins/plugin.cc
new file mode 100644
index 000000000000..fc7f60cff5cd
--- /dev/null
+++ b/src/skins/plugin.cc
@@ -0,0 +1,202 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2008 Tomasz MoÅ
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <stdlib.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/hook.h>
+#include <libaudgui/libaudgui.h>
+
+#include "menus.h"
+#include "plugin.h"
+#include "plugin-window.h"
+#include "preset-browser.h"
+#include "preset-list.h"
+#include "skins_cfg.h"
+#include "ui_equalizer.h"
+#include "ui_main.h"
+#include "ui_main_evlisteners.h"
+#include "ui_playlist.h"
+#include "ui_skin.h"
+#include "view.h"
+
+class SkinnedUI : public IfacePlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("Winamp Classic Interface"),
+ PACKAGE,
+ nullptr,
+ & skins_prefs
+ };
+
+ constexpr SkinnedUI () : IfacePlugin (info) {}
+
+ bool init ();
+ void cleanup ();
+
+ void run ()
+ { gtk_main (); }
+ void quit ()
+ { gtk_main_quit (); }
+
+ void show (bool show)
+ { view_show_player (show); }
+
+ void show_about_window ()
+ { audgui_show_about_window (); }
+ void hide_about_window ()
+ { audgui_hide_about_window (); }
+ void show_filebrowser (bool open)
+ { audgui_run_filebrowser (open); }
+ void hide_filebrowser ()
+ { audgui_hide_filebrowser (); }
+ void show_jump_to_song ()
+ { audgui_jump_to_track (); }
+ void hide_jump_to_song ()
+ { audgui_jump_to_track_hide (); }
+ void show_prefs_window ()
+ { audgui_show_prefs_window (); }
+ void hide_prefs_window ()
+ { audgui_hide_prefs_window (); }
+ void plugin_menu_add (AudMenuID id, void func (), const char * name, const char * icon)
+ { audgui_plugin_menu_add (id, func, name, icon); }
+ void plugin_menu_remove (AudMenuID id, void func ())
+ { audgui_plugin_menu_remove (id, func); }
+};
+
+EXPORT SkinnedUI aud_plugin_instance;
+
+char * skins_paths[SKINS_PATH_COUNT];
+
+static int update_source;
+
+static void skins_free_paths(void) {
+ int i;
+
+ for (i = 0; i < SKINS_PATH_COUNT; i++) {
+ g_free(skins_paths[i]);
+ skins_paths[i] = nullptr;
+ }
+}
+
+static void skins_init_paths ()
+{
+ const char * xdg_data_home = g_get_user_data_dir ();
+ const char * xdg_cache_home = g_get_user_cache_dir ();
+
+ skins_paths[SKINS_PATH_USER_SKIN_DIR] =
+ g_build_filename(xdg_data_home, "audacious", "Skins", nullptr);
+ skins_paths[SKINS_PATH_SKIN_THUMB_DIR] =
+ g_build_filename(xdg_cache_home, "audacious", "thumbs", nullptr);
+}
+
+static gboolean update_cb (void *)
+{
+ mainwin_update_song_info ();
+ return G_SOURCE_CONTINUE;
+}
+
+static void skins_init_main (void)
+{
+ init_skins (aud_get_str ("skins", "skin"));
+
+ view_apply_on_top ();
+ view_apply_sticky ();
+
+ if (aud_drct_get_playing ())
+ {
+ ui_main_evlistener_playback_begin (nullptr, nullptr);
+ if (aud_drct_get_paused ())
+ ui_main_evlistener_playback_pause (nullptr, nullptr);
+ }
+ else
+ mainwin_update_song_info ();
+
+ update_source = g_timeout_add (250, update_cb, nullptr);
+}
+
+bool SkinnedUI::init ()
+{
+ if (aud_get_mainloop_type () != MainloopType::GLib)
+ return false;
+
+ audgui_init ();
+
+ skins_cfg_load ();
+ skins_init_paths ();
+
+ menu_init ();
+ skins_init_main ();
+
+ create_plugin_windows ();
+
+ return true;
+}
+
+static void skins_cleanup_main (void)
+{
+ mainwin_unhook ();
+ playlistwin_unhook ();
+ g_source_remove (update_source);
+
+ cleanup_skins ();
+
+ eq_preset_browser_cleanup ();
+ eq_preset_list_cleanup ();
+}
+
+void SkinnedUI::cleanup ()
+{
+ skins_cfg_save ();
+
+ destroy_plugin_windows ();
+
+ skins_cleanup_main ();
+ menu_cleanup ();
+
+ skins_free_paths ();
+
+ audgui_cleanup ();
+}
+
+void skins_restart (void)
+{
+ skins_cleanup_main ();
+ skins_init_main ();
+
+ if (aud_ui_is_shown ())
+ view_show_player (true);
+}
+
+gboolean handle_window_close (void)
+{
+ gboolean handled = FALSE;
+ hook_call ("window close", & handled);
+
+ if (! handled)
+ aud_quit ();
+
+ return TRUE;
+}
diff --git a/src/skins/plugin.h b/src/skins/plugin.h
index 58c7cc06e0bb..9f94c83508fd 100644
--- a/src/skins/plugin.h
+++ b/src/skins/plugin.h
@@ -21,7 +21,7 @@
#ifndef PLUGIN_SKINS_H
#define PLUGIN_SKINS_H
-#include <libaudcore/core.h>
+#include <glib.h>
enum {
SKINS_PATH_USER_SKIN_DIR,
@@ -31,6 +31,8 @@ enum {
extern char * skins_paths[];
-bool_t handle_window_close (void);
+void skins_restart (void);
+
+gboolean handle_window_close (void);
#endif
diff --git a/src/skins/preset-browser.c b/src/skins/preset-browser.c
deleted file mode 100644
index 83c4cc802f56..000000000000
--- a/src/skins/preset-browser.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * preset-browser.c
- * Copyright 2014 John Lindgren
- *
- * This file is part of Audacious.
- *
- * Audacious 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, version 2 or version 3 of the License.
- *
- * Audacious 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
- * Audacious. If not, see <http://www.gnu.org/licenses/>.
- *
- * The Audacious team does not consider modular code linking to Audacious or
- * using our public API to be a derived work.
- */
-
-#include "preset-browser.h"
-
-#include <gtk/gtk.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <libaudcore/audstrings.h>
-
-#include "ui_equalizer.h"
-
-typedef void (* FilebrowserCallback) (const char * filename);
-
-static GtkWidget * preset_browser;
-
-static void browser_response (GtkWidget * dialog, int response, void * data)
-{
- if (response == GTK_RESPONSE_ACCEPT)
- {
- char * filename = gtk_file_chooser_get_uri ((GtkFileChooser *) dialog);
- ((FilebrowserCallback) data) (filename);
- g_free (filename);
- }
-
- gtk_widget_destroy (dialog);
-}
-
-static void show_preset_browser (const char * title, bool_t save,
- const char * default_filename, FilebrowserCallback callback)
-{
- if (preset_browser)
- gtk_widget_destroy (preset_browser);
-
- preset_browser = gtk_file_chooser_dialog_new (title, NULL, save ?
- GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN, _("Cancel"),
- GTK_RESPONSE_CANCEL, save ? _("Save") : _("Load"), GTK_RESPONSE_ACCEPT,
- NULL);
-
- if (default_filename)
- gtk_file_chooser_set_current_name ((GtkFileChooser *) preset_browser, default_filename);
-
- g_signal_connect (preset_browser, "response", (GCallback) browser_response, callback);
- g_signal_connect (preset_browser, "destroy", (GCallback)
- gtk_widget_destroyed, & preset_browser);
-
- gtk_window_present ((GtkWindow *) preset_browser);
-}
-
-static void do_load_file (const char * filename)
-{
- EqualizerPreset * preset = aud_load_preset_file (filename);
- if (! preset)
- return;
-
- equalizerwin_apply_preset (preset);
- aud_equalizer_preset_free (preset);
-}
-
-void eq_preset_load_file (void)
-{
- show_preset_browser (_("Load Preset File"), FALSE, NULL, do_load_file);
-}
-
-static void do_load_eqf (const char * filename)
-{
- VFSFile * file = vfs_fopen (filename, "r");
- if (! file)
- return;
-
- Index * presets = aud_import_winamp_presets (file);
-
- if (presets)
- {
- if (index_count (presets) >= 1)
- equalizerwin_apply_preset (index_get (presets, 0));
-
- index_free_full (presets, (IndexFreeFunc) aud_equalizer_preset_free);
- }
-
- vfs_fclose (file);
-}
-
-void eq_preset_load_eqf (void)
-{
- show_preset_browser (_("Load EQF File"), FALSE, NULL, do_load_eqf);
-}
-
-static void do_save_file (const char * filename)
-{
- EqualizerPreset * preset = aud_equalizer_preset_new ("");
- equalizerwin_update_preset (preset);
- aud_save_preset_file (preset, filename);
- aud_equalizer_preset_free (preset);
-}
-
-void eq_preset_save_file (void)
-{
- char * title = aud_drct_get_title ();
- char * name = title ? str_printf ("%s.%s", title, EQUALIZER_DEFAULT_PRESET_EXT) : NULL;
-
- show_preset_browser (_("Save Preset File"), TRUE, name, do_save_file);
-
- str_unref (title);
- str_unref (name);
-}
-
-static void do_save_eqf (const char * filename)
-{
- VFSFile * file = vfs_fopen (filename, "w");
- if (! file)
- return;
-
- EqualizerPreset * preset = aud_equalizer_preset_new ("Preset1");
- equalizerwin_update_preset (preset);
- aud_export_winamp_preset (preset, file);
- aud_equalizer_preset_free (preset);
-
- vfs_fclose (file);
-}
-
-void eq_preset_save_eqf (void)
-{
- show_preset_browser (_("Save EQF File"), TRUE, NULL, do_save_eqf);
-}
-
-static void do_import_winamp (const char * filename)
-{
- VFSFile * file = vfs_fopen (filename, "r");
- if (! file)
- return;
-
- Index * list = aud_import_winamp_presets (file);
- if (list)
- equalizerwin_import_presets (list);
-
- vfs_fclose (file);
-}
-
-void eq_preset_import_winamp (void)
-{
- show_preset_browser (_("Import Winamp Presets"), FALSE, NULL, do_import_winamp);
-}
-
-void eq_preset_browser_cleanup (void)
-{
- if (preset_browser)
- gtk_widget_destroy (preset_browser);
-}
diff --git a/src/skins/preset-browser.cc b/src/skins/preset-browser.cc
new file mode 100644
index 000000000000..538b95ec1c1d
--- /dev/null
+++ b/src/skins/preset-browser.cc
@@ -0,0 +1,158 @@
+/*
+ * preset-browser.c
+ * Copyright 2014 John Lindgren
+ *
+ * This file is part of Audacious.
+ *
+ * Audacious 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, version 2 or version 3 of the License.
+ *
+ * Audacious 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
+ * Audacious. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The Audacious team does not consider modular code linking to Audacious or
+ * using our public API to be a derived work.
+ */
+
+#include "preset-browser.h"
+
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/vfs.h>
+
+#include "ui_equalizer.h"
+
+typedef void (* FilebrowserCallback) (const char * filename);
+
+static GtkWidget * preset_browser;
+
+static void browser_response (GtkWidget * dialog, int response, void * data)
+{
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ char * filename = gtk_file_chooser_get_uri ((GtkFileChooser *) dialog);
+ ((FilebrowserCallback) data) (filename);
+ g_free (filename);
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+static void show_preset_browser (const char * title, gboolean save,
+ const char * default_filename, FilebrowserCallback callback)
+{
+ if (preset_browser)
+ gtk_widget_destroy (preset_browser);
+
+ preset_browser = gtk_file_chooser_dialog_new (title, nullptr, save ?
+ GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN, _("Cancel"),
+ GTK_RESPONSE_CANCEL, save ? _("Save") : _("Load"), GTK_RESPONSE_ACCEPT,
+ nullptr);
+
+ if (default_filename)
+ gtk_file_chooser_set_current_name ((GtkFileChooser *) preset_browser, default_filename);
+
+ g_signal_connect (preset_browser, "response", (GCallback) browser_response, (void *) callback);
+ g_signal_connect (preset_browser, "destroy", (GCallback)
+ gtk_widget_destroyed, & preset_browser);
+
+ gtk_window_present ((GtkWindow *) preset_browser);
+}
+
+static void do_load_file (const char * filename)
+{
+ EqualizerPreset preset;
+
+ VFSFile file (filename, "r");
+ if (! file || ! aud_load_preset_file (preset, file))
+ return;
+
+ equalizerwin_apply_preset (preset);
+}
+
+void eq_preset_load_file (void)
+{
+ show_preset_browser (_("Load Preset File"), FALSE, nullptr, do_load_file);
+}
+
+static void do_load_eqf (const char * filename)
+{
+ VFSFile file (filename, "r");
+ if (! file)
+ return;
+
+ Index<EqualizerPreset> presets = aud_import_winamp_presets (file);
+
+ if (presets.len ())
+ equalizerwin_apply_preset (presets[0]);
+}
+
+void eq_preset_load_eqf (void)
+{
+ show_preset_browser (_("Load EQF File"), FALSE, nullptr, do_load_eqf);
+}
+
+static void do_save_file (const char * filename)
+{
+ EqualizerPreset preset;
+ equalizerwin_update_preset (preset);
+
+ VFSFile file (filename, "w");
+ if (file)
+ aud_save_preset_file (preset, file);
+}
+
+void eq_preset_save_file (void)
+{
+ String title = aud_drct_get_title ();
+ StringBuf name = title ? str_printf ("%s.%s", (const char *) title,
+ EQUALIZER_DEFAULT_PRESET_EXT) : StringBuf ();
+
+ show_preset_browser (_("Save Preset File"), TRUE, name, do_save_file);
+}
+
+static void do_save_eqf (const char * filename)
+{
+ VFSFile file (filename, "w");
+ if (! file)
+ return;
+
+ EqualizerPreset preset = EqualizerPreset ();
+ preset.name = String ("Preset1");
+
+ equalizerwin_update_preset (preset);
+ aud_export_winamp_preset (preset, file);
+}
+
+void eq_preset_save_eqf (void)
+{
+ show_preset_browser (_("Save EQF File"), TRUE, nullptr, do_save_eqf);
+}
+
+static void do_import_winamp (const char * filename)
+{
+ VFSFile file (filename, "r");
+ if (! file)
+ return;
+
+ equalizerwin_import_presets (aud_import_winamp_presets (file));
+}
+
+void eq_preset_import_winamp (void)
+{
+ show_preset_browser (_("Import Winamp Presets"), FALSE, nullptr, do_import_winamp);
+}
+
+void eq_preset_browser_cleanup (void)
+{
+ if (preset_browser)
+ gtk_widget_destroy (preset_browser);
+}
diff --git a/src/skins/preset-list.c b/src/skins/preset-list.c
deleted file mode 100644
index 025761b4d7b7..000000000000
--- a/src/skins/preset-list.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/* Audacious - Cross-platform multimedia player
- * Copyright (C) 2005-2014 Audacious development team.
- *
- * Based on BMP:
- * Copyright (C) 2003-2004 BMP development team.
- *
- * Based on XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "preset-list.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "ui_equalizer.h"
-
-static GtkWidget *equalizerwin_load_window = NULL;
-static GtkWidget *equalizerwin_load_auto_window = NULL;
-static GtkWidget *equalizerwin_save_window = NULL;
-static GtkWidget *equalizerwin_save_entry = NULL;
-static GtkWidget *equalizerwin_save_auto_window = NULL;
-static GtkWidget *equalizerwin_save_auto_entry = NULL;
-static GtkWidget *equalizerwin_delete_window = NULL;
-static GtkWidget *equalizerwin_delete_auto_window = NULL;
-
-static void
-equalizerwin_delete_selected_presets(GtkTreeView *view, gchar *filename)
-{
- gchar *text;
-
- GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
- GtkTreeModel *model = gtk_tree_view_get_model(view);
-
- /*
- * first we are making a list of the selected rows, then we convert this
- * list into a list of GtkTreeRowReferences, so that when you delete an
- * item you can still access the other items
- * finally we iterate through all GtkTreeRowReferences, convert them to
- * GtkTreeIters and delete those one after the other
- */
-
- GList *list = gtk_tree_selection_get_selected_rows(selection, &model);
- GList *rrefs = NULL;
- GList *litr;
-
- for (litr = list; litr; litr = litr->next)
- {
- GtkTreePath *path = litr->data;
- rrefs = g_list_append(rrefs, gtk_tree_row_reference_new(model, path));
- }
-
- for (litr = rrefs; litr; litr = litr->next)
- {
- GtkTreeRowReference *ref = litr->data;
- GtkTreePath *path = gtk_tree_row_reference_get_path(ref);
- GtkTreeIter iter;
- gtk_tree_model_get_iter(model, &iter, path);
-
- gtk_tree_model_get(model, &iter, 0, &text, -1);
-
- if (!strcmp(filename, "eq.preset"))
- equalizerwin_delete_preset (equalizer_presets, text, filename);
- else if (!strcmp(filename, "eq.auto_preset"))
- equalizerwin_delete_preset (equalizer_auto_presets, text, filename);
-
- gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
- }
-}
-
-static void
-equalizerwin_save_ok(GtkWidget * widget, gpointer data)
-{
- const gchar *text;
-
- text = gtk_entry_get_text(GTK_ENTRY(equalizerwin_save_entry));
-
- if (text[0])
- equalizerwin_save_preset (equalizer_presets, text, "eq.preset");
-
- gtk_widget_destroy(equalizerwin_save_window);
-}
-
-static void
-equalizerwin_save_select(GtkTreeView *treeview, GtkTreePath *path,
- GtkTreeViewColumn *col, gpointer data)
-{
- gchar *text;
-
- GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- if (selection)
- {
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- {
- gtk_tree_model_get(model, &iter, 0, &text, -1);
- gtk_entry_set_text(GTK_ENTRY(equalizerwin_save_entry), text);
- equalizerwin_save_ok(NULL, NULL);
-
- g_free(text);
- }
- }
-}
-
-static void
-equalizerwin_load_ok(GtkWidget *widget, gpointer data)
-{
- gchar *text;
-
- GtkTreeView* view = GTK_TREE_VIEW(data);
- GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- if (selection)
- {
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- {
- gtk_tree_model_get(model, &iter, 0, &text, -1);
- equalizerwin_load_preset(equalizer_presets, text);
-
- g_free(text);
- }
- }
- gtk_widget_destroy(equalizerwin_load_window);
-}
-
-static void
-equalizerwin_load_select(GtkTreeView *treeview, GtkTreePath *path,
- GtkTreeViewColumn *col, gpointer data)
-{
- equalizerwin_load_ok(NULL, treeview);
-}
-
-static void
-equalizerwin_delete_delete(GtkWidget *widget, gpointer data)
-{
- equalizerwin_delete_selected_presets(GTK_TREE_VIEW(data), "eq.preset");
-}
-
-static void
-equalizerwin_save_auto_ok(GtkWidget *widget, gpointer data)
-{
- const gchar *text;
-
- text = gtk_entry_get_text(GTK_ENTRY(equalizerwin_save_auto_entry));
-
- if (text[0])
- equalizerwin_save_preset (equalizer_auto_presets, text, "eq.auto_preset");
-
- gtk_widget_destroy(equalizerwin_save_auto_window);
-}
-
-static void
-equalizerwin_save_auto_select(GtkTreeView *treeview, GtkTreePath *path,
- GtkTreeViewColumn *col, gpointer data)
-{
- gchar *text;
-
- GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- if (selection)
- {
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- {
- gtk_tree_model_get(model, &iter, 0, &text, -1);
- gtk_entry_set_text(GTK_ENTRY(equalizerwin_save_auto_entry), text);
- equalizerwin_save_auto_ok(NULL, NULL);
-
- g_free(text);
- }
- }
-}
-
-static void
-equalizerwin_load_auto_ok(GtkWidget *widget, gpointer data)
-{
- gchar *text;
-
- GtkTreeView *view = GTK_TREE_VIEW(data);
- GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- if (selection)
- {
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- {
- gtk_tree_model_get(model, &iter, 0, &text, -1);
- equalizerwin_load_preset(equalizer_auto_presets, text);
-
- g_free(text);
- }
- }
- gtk_widget_destroy(equalizerwin_load_auto_window);
-}
-
-static void
-equalizerwin_load_auto_select(GtkTreeView *treeview, GtkTreePath *path,
- GtkTreeViewColumn *col, gpointer data)
-{
- equalizerwin_load_auto_ok(NULL, treeview);
-}
-
-static void
-equalizerwin_delete_auto_delete(GtkWidget *widget, gpointer data)
-{
- equalizerwin_delete_selected_presets(GTK_TREE_VIEW(data), "eq.auto_preset");
-}
-
-static GtkWidget * equalizerwin_create_list_window (Index * preset_list,
- const gchar *title,
- GtkWidget **window,
- GtkSelectionMode sel_mode,
- GtkWidget **entry,
- GtkWidget *button_action,
- GCallback action_func,
- GCallback select_row_func)
-{
- GtkWidget *vbox, *scrolled_window, *bbox, *view;
- GtkWidget *button_cancel;
-
- GtkListStore *store;
- GtkTreeIter iter;
- GtkTreeModel *model;
- GtkCellRenderer *renderer;
- GtkTreeSelection *selection;
- GtkTreeSortable *sortable;
-
- *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(*window), title);
- gtk_window_set_type_hint(GTK_WINDOW(*window), GDK_WINDOW_TYPE_HINT_DIALOG);
- gtk_window_set_default_size(GTK_WINDOW(*window), 350, 300);
- gtk_container_set_border_width(GTK_CONTAINER(*window), 10);
- gtk_window_set_transient_for(GTK_WINDOW(*window),
- GTK_WINDOW(equalizerwin));
- g_signal_connect(*window, "destroy",
- G_CALLBACK(gtk_widget_destroyed), window);
-
- audgui_destroy_on_escape (* window);
-
- vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
- gtk_container_add(GTK_CONTAINER(*window), vbox);
-
- scrolled_window = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled_window, GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
-
- /* fill the store with the names of all available presets */
- store = gtk_list_store_new(1, G_TYPE_STRING);
- for (int p = 0; p < index_count (preset_list); p ++)
- {
- EqualizerPreset * preset = index_get (preset_list, p);
- gtk_list_store_append(store, &iter);
- gtk_list_store_set (store, & iter, 0, preset->name, -1);
- }
- model = GTK_TREE_MODEL(store);
-
- sortable = GTK_TREE_SORTABLE(store);
- gtk_tree_sortable_set_sort_column_id(sortable, 0, GTK_SORT_ASCENDING);
-
- view = gtk_tree_view_new();
- renderer = gtk_cell_renderer_text_new();
- gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1,
- _("Presets"), renderer,
- "text", 0, NULL);
- gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
- g_object_unref(model);
-
- selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
- gtk_tree_selection_set_mode(selection, sel_mode);
-
- gtk_container_add(GTK_CONTAINER(scrolled_window), view);
- gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
-
- if (entry) {
- *entry = gtk_entry_new();
- g_signal_connect(*entry, "activate", action_func, NULL);
- gtk_box_pack_start(GTK_BOX(vbox), *entry, FALSE, FALSE, 0);
- }
-
- bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
- gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
- gtk_box_set_spacing(GTK_BOX(bbox), 5);
- gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
-
- button_cancel = audgui_button_new (_("Cancel"), "process-stop", NULL, NULL);
- g_signal_connect_swapped (button_cancel, "clicked", (GCallback)
- gtk_widget_destroy, * window);
- gtk_box_pack_start(GTK_BOX(bbox), button_cancel, TRUE, TRUE, 0);
-
- g_signal_connect(button_action, "clicked", G_CALLBACK(action_func), view);
- gtk_widget_set_can_default (button_action, TRUE);
-
- if (select_row_func)
- g_signal_connect(view, "row-activated", G_CALLBACK(select_row_func), NULL);
-
- gtk_box_pack_start(GTK_BOX(bbox), button_action, TRUE, TRUE, 0);
-
- gtk_widget_grab_default(button_action);
-
- gtk_widget_show_all(*window);
-
- return *window;
-}
-
-void eq_preset_load (void)
-{
- if (equalizerwin_load_window) {
- gtk_window_present(GTK_WINDOW(equalizerwin_load_window));
- return;
- }
-
- equalizerwin_create_list_window(equalizer_presets,
- _("Load preset"),
- &equalizerwin_load_window,
- GTK_SELECTION_SINGLE, NULL,
- audgui_button_new (_("Load"), "document-open", NULL, NULL),
- G_CALLBACK(equalizerwin_load_ok),
- G_CALLBACK(equalizerwin_load_select));
-}
-
-void eq_preset_load_auto (void)
-{
- if (equalizerwin_load_auto_window) {
- gtk_window_present(GTK_WINDOW(equalizerwin_load_auto_window));
- return;
- }
-
- equalizerwin_create_list_window(equalizer_auto_presets,
- _("Load auto-preset"),
- &equalizerwin_load_auto_window,
- GTK_SELECTION_SINGLE, NULL,
- audgui_button_new (_("Load"), "document-open", NULL, NULL),
- G_CALLBACK(equalizerwin_load_auto_ok),
- G_CALLBACK(equalizerwin_load_auto_select));
-}
-
-void eq_preset_save (void)
-{
- if (equalizerwin_save_window) {
- gtk_window_present(GTK_WINDOW(equalizerwin_save_window));
- return;
- }
-
- equalizerwin_create_list_window(equalizer_presets,
- _("Save preset"),
- &equalizerwin_save_window,
- GTK_SELECTION_SINGLE,
- &equalizerwin_save_entry,
- audgui_button_new (_("Save"), "document-save", NULL, NULL),
- G_CALLBACK(equalizerwin_save_ok),
- G_CALLBACK(equalizerwin_save_select));
-}
-
-void eq_preset_save_auto (void)
-{
- if (equalizerwin_save_auto_window)
- gtk_window_present(GTK_WINDOW(equalizerwin_save_auto_window));
- else
- equalizerwin_create_list_window(equalizer_auto_presets,
- _("Save auto-preset"),
- &equalizerwin_save_auto_window,
- GTK_SELECTION_SINGLE,
- &equalizerwin_save_auto_entry,
- audgui_button_new (_("Save"), "document-save", NULL, NULL),
- G_CALLBACK(equalizerwin_save_auto_ok),
- G_CALLBACK(equalizerwin_save_auto_select));
-
- char * name = aud_drct_get_filename ();
-
- if (name != NULL)
- {
- char * base = g_path_get_basename (name);
- gtk_entry_set_text ((GtkEntry *) equalizerwin_save_auto_entry, base);
- g_free (base);
- str_unref (name);
- }
-}
-
-void eq_preset_delete (void)
-{
- if (equalizerwin_delete_window) {
- gtk_window_present(GTK_WINDOW(equalizerwin_delete_window));
- return;
- }
-
- equalizerwin_create_list_window(equalizer_presets,
- _("Delete preset"),
- &equalizerwin_delete_window,
- GTK_SELECTION_MULTIPLE, NULL,
- audgui_button_new (_("Delete"), "edit-delete", NULL, NULL),
- G_CALLBACK(equalizerwin_delete_delete),
- NULL);
-}
-
-void eq_preset_delete_auto (void)
-{
- if (equalizerwin_delete_auto_window) {
- gtk_window_present(GTK_WINDOW(equalizerwin_delete_auto_window));
- return;
- }
-
- equalizerwin_create_list_window(equalizer_auto_presets,
- _("Delete auto-preset"),
- &equalizerwin_delete_auto_window,
- GTK_SELECTION_MULTIPLE, NULL,
- audgui_button_new (_("Delete"), "edit-delete", NULL, NULL),
- G_CALLBACK(equalizerwin_delete_auto_delete),
- NULL);
-}
-
-void eq_preset_load_default (void)
-{
- if (! equalizerwin_load_preset (equalizer_presets, _("Default")))
- eq_preset_set_zero ();
-}
-
-void eq_preset_save_default (void)
-{
- equalizerwin_save_preset (equalizer_presets, _("Default"), "eq.preset");
-}
-
-void eq_preset_set_zero (void)
-{
- const EqualizerPreset zero = {0};
- equalizerwin_apply_preset (& zero);
-}
-
-void eq_preset_list_cleanup (void)
-{
- if (equalizerwin_load_window)
- gtk_widget_destroy (equalizerwin_load_window);
- if (equalizerwin_load_auto_window)
- gtk_widget_destroy (equalizerwin_load_auto_window);
- if (equalizerwin_save_window)
- gtk_widget_destroy (equalizerwin_save_window);
- if (equalizerwin_save_auto_window)
- gtk_widget_destroy (equalizerwin_save_auto_window);
- if (equalizerwin_delete_window)
- gtk_widget_destroy (equalizerwin_delete_window);
- if (equalizerwin_delete_auto_window)
- gtk_widget_destroy (equalizerwin_delete_auto_window);
-}
diff --git a/src/skins/preset-list.cc b/src/skins/preset-list.cc
new file mode 100644
index 000000000000..1b602645e063
--- /dev/null
+++ b/src/skins/preset-list.cc
@@ -0,0 +1,462 @@
+/* Audacious - Cross-platform multimedia player
+ * Copyright (C) 2005-2014 Audacious development team.
+ *
+ * Based on BMP:
+ * Copyright (C) 2003-2004 BMP development team.
+ *
+ * Based on XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "preset-list.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudgui/libaudgui-gtk.h>
+
+#include "ui_equalizer.h"
+
+static GtkWidget *equalizerwin_load_window = nullptr;
+static GtkWidget *equalizerwin_load_auto_window = nullptr;
+static GtkWidget *equalizerwin_save_window = nullptr;
+static GtkWidget *equalizerwin_save_entry = nullptr;
+static GtkWidget *equalizerwin_save_auto_window = nullptr;
+static GtkWidget *equalizerwin_save_auto_entry = nullptr;
+static GtkWidget *equalizerwin_delete_window = nullptr;
+static GtkWidget *equalizerwin_delete_auto_window = nullptr;
+
+static void
+equalizerwin_delete_selected_presets(GtkTreeView *view, const char *filename)
+{
+ char *text;
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
+ GtkTreeModel *model = gtk_tree_view_get_model(view);
+
+ /*
+ * first we are making a list of the selected rows, then we convert this
+ * list into a list of GtkTreeRowReferences, so that when you delete an
+ * item you can still access the other items
+ * finally we iterate through all GtkTreeRowReferences, convert them to
+ * GtkTreeIters and delete those one after the other
+ */
+
+ GList *list = gtk_tree_selection_get_selected_rows(selection, &model);
+ GList *rrefs = nullptr;
+ GList *litr;
+
+ for (litr = list; litr; litr = litr->next)
+ {
+ GtkTreePath *path = (GtkTreePath *) litr->data;
+ rrefs = g_list_append(rrefs, gtk_tree_row_reference_new(model, path));
+ }
+
+ for (litr = rrefs; litr; litr = litr->next)
+ {
+ GtkTreeRowReference *ref = (GtkTreeRowReference *) litr->data;
+ GtkTreePath *path = gtk_tree_row_reference_get_path(ref);
+ GtkTreeIter iter;
+ gtk_tree_model_get_iter(model, &iter, path);
+ gtk_tree_path_free(path);
+
+ gtk_tree_model_get(model, &iter, 0, &text, -1);
+
+ if (!strcmp(filename, "eq.preset"))
+ equalizerwin_delete_preset (equalizer_presets, text, filename);
+ else if (!strcmp(filename, "eq.auto_preset"))
+ equalizerwin_delete_preset (equalizer_auto_presets, text, filename);
+
+ gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
+ }
+}
+
+static void
+equalizerwin_save_ok(GtkWidget * widget, void * data)
+{
+ const char *text;
+
+ text = gtk_entry_get_text(GTK_ENTRY(equalizerwin_save_entry));
+
+ if (text[0])
+ equalizerwin_save_preset (equalizer_presets, text, "eq.preset");
+
+ gtk_widget_destroy(equalizerwin_save_window);
+}
+
+static void
+equalizerwin_save_select(GtkTreeView *treeview, GtkTreePath *path,
+ GtkTreeViewColumn *col, void * data)
+{
+ char *text;
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ if (selection)
+ {
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ {
+ gtk_tree_model_get(model, &iter, 0, &text, -1);
+ gtk_entry_set_text(GTK_ENTRY(equalizerwin_save_entry), text);
+ equalizerwin_save_ok(nullptr, nullptr);
+
+ g_free(text);
+ }
+ }
+}
+
+static void
+equalizerwin_load_ok(GtkWidget *widget, void * data)
+{
+ char *text;
+
+ GtkTreeView* view = GTK_TREE_VIEW(data);
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ if (selection)
+ {
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ {
+ gtk_tree_model_get(model, &iter, 0, &text, -1);
+ equalizerwin_load_preset(equalizer_presets, text);
+
+ g_free(text);
+ }
+ }
+ gtk_widget_destroy(equalizerwin_load_window);
+}
+
+static void
+equalizerwin_load_select(GtkTreeView *treeview, GtkTreePath *path,
+ GtkTreeViewColumn *col, void * data)
+{
+ equalizerwin_load_ok(nullptr, treeview);
+}
+
+static void
+equalizerwin_delete_delete(GtkWidget *widget, void * data)
+{
+ equalizerwin_delete_selected_presets(GTK_TREE_VIEW(data), "eq.preset");
+}
+
+static void
+equalizerwin_save_auto_ok(GtkWidget *widget, void * data)
+{
+ const char *text;
+
+ text = gtk_entry_get_text(GTK_ENTRY(equalizerwin_save_auto_entry));
+
+ if (text[0])
+ equalizerwin_save_preset (equalizer_auto_presets, text, "eq.auto_preset");
+
+ gtk_widget_destroy(equalizerwin_save_auto_window);
+}
+
+static void
+equalizerwin_save_auto_select(GtkTreeView *treeview, GtkTreePath *path,
+ GtkTreeViewColumn *col, void * data)
+{
+ char *text;
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ if (selection)
+ {
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ {
+ gtk_tree_model_get(model, &iter, 0, &text, -1);
+ gtk_entry_set_text(GTK_ENTRY(equalizerwin_save_auto_entry), text);
+ equalizerwin_save_auto_ok(nullptr, nullptr);
+
+ g_free(text);
+ }
+ }
+}
+
+static void
+equalizerwin_load_auto_ok(GtkWidget *widget, void * data)
+{
+ char *text;
+
+ GtkTreeView *view = GTK_TREE_VIEW(data);
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ if (selection)
+ {
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ {
+ gtk_tree_model_get(model, &iter, 0, &text, -1);
+ equalizerwin_load_preset(equalizer_auto_presets, text);
+
+ g_free(text);
+ }
+ }
+ gtk_widget_destroy(equalizerwin_load_auto_window);
+}
+
+static void
+equalizerwin_load_auto_select(GtkTreeView *treeview, GtkTreePath *path,
+ GtkTreeViewColumn *col, void * data)
+{
+ equalizerwin_load_auto_ok(nullptr, treeview);
+}
+
+static void
+equalizerwin_delete_auto_delete(GtkWidget *widget, void * data)
+{
+ equalizerwin_delete_selected_presets(GTK_TREE_VIEW(data), "eq.auto_preset");
+}
+
+static GtkWidget * equalizerwin_create_list_window
+ (const Index<EqualizerPreset> & preset_list, const char * title,
+ GtkWidget * * window, GtkSelectionMode sel_mode, GtkWidget * * entry,
+ GtkWidget * button_action, GCallback action_func, GCallback select_row_func)
+{
+ GtkWidget *vbox, *scrolled_window, *bbox, *view;
+ GtkWidget *button_cancel;
+
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ GtkCellRenderer *renderer;
+ GtkTreeSelection *selection;
+ GtkTreeSortable *sortable;
+
+ *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(*window), title);
+ gtk_window_set_type_hint(GTK_WINDOW(*window), GDK_WINDOW_TYPE_HINT_DIALOG);
+ gtk_window_set_default_size(GTK_WINDOW(*window), 350, 300);
+ gtk_container_set_border_width(GTK_CONTAINER(*window), 10);
+ gtk_window_set_transient_for(GTK_WINDOW(*window),
+ GTK_WINDOW(equalizerwin));
+ g_signal_connect(*window, "destroy",
+ G_CALLBACK(gtk_widget_destroyed), window);
+
+ audgui_destroy_on_escape (* window);
+
+ vbox = gtk_vbox_new (FALSE, 10);
+ gtk_container_add(GTK_CONTAINER(*window), vbox);
+
+ scrolled_window = gtk_scrolled_window_new(nullptr, nullptr);
+ gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled_window, GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+
+ /* fill the store with the names of all available presets */
+ store = gtk_list_store_new(1, G_TYPE_STRING);
+ for (const EqualizerPreset & preset : preset_list)
+ {
+ gtk_list_store_append (store, & iter);
+ gtk_list_store_set (store, & iter, 0, (const char *) preset.name, -1);
+ }
+ model = GTK_TREE_MODEL(store);
+
+ sortable = GTK_TREE_SORTABLE(store);
+ gtk_tree_sortable_set_sort_column_id(sortable, 0, GTK_SORT_ASCENDING);
+
+ view = gtk_tree_view_new();
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1,
+ _("Presets"), renderer,
+ "text", 0, nullptr);
+ gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
+ g_object_unref(model);
+
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+ gtk_tree_selection_set_mode(selection, sel_mode);
+
+ gtk_container_add(GTK_CONTAINER(scrolled_window), view);
+ gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
+
+ if (entry) {
+ *entry = gtk_entry_new();
+ g_signal_connect(*entry, "activate", action_func, nullptr);
+ gtk_box_pack_start(GTK_BOX(vbox), *entry, FALSE, FALSE, 0);
+ }
+
+ bbox = gtk_hbutton_box_new();
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing(GTK_BOX(bbox), 5);
+ gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
+
+ button_cancel = audgui_button_new (_("Cancel"), "process-stop", nullptr, nullptr);
+ g_signal_connect_swapped (button_cancel, "clicked", (GCallback)
+ gtk_widget_destroy, * window);
+ gtk_box_pack_start(GTK_BOX(bbox), button_cancel, TRUE, TRUE, 0);
+
+ g_signal_connect(button_action, "clicked", G_CALLBACK(action_func), view);
+ gtk_widget_set_can_default (button_action, TRUE);
+
+ if (select_row_func)
+ g_signal_connect(view, "row-activated", G_CALLBACK(select_row_func), nullptr);
+
+ gtk_box_pack_start(GTK_BOX(bbox), button_action, TRUE, TRUE, 0);
+
+ gtk_widget_grab_default(button_action);
+
+ gtk_widget_show_all(*window);
+
+ return *window;
+}
+
+void eq_preset_load (void)
+{
+ if (equalizerwin_load_window) {
+ gtk_window_present(GTK_WINDOW(equalizerwin_load_window));
+ return;
+ }
+
+ equalizerwin_create_list_window(equalizer_presets,
+ _("Load preset"),
+ &equalizerwin_load_window,
+ GTK_SELECTION_SINGLE, nullptr,
+ audgui_button_new (_("Load"), "document-open", nullptr, nullptr),
+ G_CALLBACK(equalizerwin_load_ok),
+ G_CALLBACK(equalizerwin_load_select));
+}
+
+void eq_preset_load_auto (void)
+{
+ if (equalizerwin_load_auto_window) {
+ gtk_window_present(GTK_WINDOW(equalizerwin_load_auto_window));
+ return;
+ }
+
+ equalizerwin_create_list_window(equalizer_auto_presets,
+ _("Load auto-preset"),
+ &equalizerwin_load_auto_window,
+ GTK_SELECTION_SINGLE, nullptr,
+ audgui_button_new (_("Load"), "document-open", nullptr, nullptr),
+ G_CALLBACK(equalizerwin_load_auto_ok),
+ G_CALLBACK(equalizerwin_load_auto_select));
+}
+
+void eq_preset_save (void)
+{
+ if (equalizerwin_save_window) {
+ gtk_window_present(GTK_WINDOW(equalizerwin_save_window));
+ return;
+ }
+
+ equalizerwin_create_list_window(equalizer_presets,
+ _("Save preset"),
+ &equalizerwin_save_window,
+ GTK_SELECTION_SINGLE,
+ &equalizerwin_save_entry,
+ audgui_button_new (_("Save"), "document-save", nullptr, nullptr),
+ G_CALLBACK(equalizerwin_save_ok),
+ G_CALLBACK(equalizerwin_save_select));
+}
+
+void eq_preset_save_auto (void)
+{
+ if (equalizerwin_save_auto_window)
+ gtk_window_present(GTK_WINDOW(equalizerwin_save_auto_window));
+ else
+ equalizerwin_create_list_window(equalizer_auto_presets,
+ _("Save auto-preset"),
+ &equalizerwin_save_auto_window,
+ GTK_SELECTION_SINGLE,
+ &equalizerwin_save_auto_entry,
+ audgui_button_new (_("Save"), "document-save", nullptr, nullptr),
+ G_CALLBACK(equalizerwin_save_auto_ok),
+ G_CALLBACK(equalizerwin_save_auto_select));
+
+ String name = aud_drct_get_filename ();
+
+ if (name != nullptr)
+ {
+ char * base = g_path_get_basename (name);
+ gtk_entry_set_text ((GtkEntry *) equalizerwin_save_auto_entry, base);
+ g_free (base);
+ }
+}
+
+void eq_preset_delete (void)
+{
+ if (equalizerwin_delete_window) {
+ gtk_window_present(GTK_WINDOW(equalizerwin_delete_window));
+ return;
+ }
+
+ equalizerwin_create_list_window(equalizer_presets,
+ _("Delete preset"),
+ &equalizerwin_delete_window,
+ GTK_SELECTION_MULTIPLE, nullptr,
+ audgui_button_new (_("Delete"), "edit-delete", nullptr, nullptr),
+ G_CALLBACK(equalizerwin_delete_delete),
+ nullptr);
+}
+
+void eq_preset_delete_auto (void)
+{
+ if (equalizerwin_delete_auto_window) {
+ gtk_window_present(GTK_WINDOW(equalizerwin_delete_auto_window));
+ return;
+ }
+
+ equalizerwin_create_list_window(equalizer_auto_presets,
+ _("Delete auto-preset"),
+ &equalizerwin_delete_auto_window,
+ GTK_SELECTION_MULTIPLE, nullptr,
+ audgui_button_new (_("Delete"), "edit-delete", nullptr, nullptr),
+ G_CALLBACK(equalizerwin_delete_auto_delete),
+ nullptr);
+}
+
+void eq_preset_load_default (void)
+{
+ if (! equalizerwin_load_preset (equalizer_presets, _("Default")))
+ eq_preset_set_zero ();
+}
+
+void eq_preset_save_default (void)
+{
+ equalizerwin_save_preset (equalizer_presets, _("Default"), "eq.preset");
+}
+
+void eq_preset_set_zero (void)
+{
+ equalizerwin_apply_preset (EqualizerPreset ());
+}
+
+void eq_preset_list_cleanup (void)
+{
+ if (equalizerwin_load_window)
+ gtk_widget_destroy (equalizerwin_load_window);
+ if (equalizerwin_load_auto_window)
+ gtk_widget_destroy (equalizerwin_load_auto_window);
+ if (equalizerwin_save_window)
+ gtk_widget_destroy (equalizerwin_save_window);
+ if (equalizerwin_save_auto_window)
+ gtk_widget_destroy (equalizerwin_save_auto_window);
+ if (equalizerwin_delete_window)
+ gtk_widget_destroy (equalizerwin_delete_window);
+ if (equalizerwin_delete_auto_window)
+ gtk_widget_destroy (equalizerwin_delete_auto_window);
+}
diff --git a/src/skins/skins_cfg.c b/src/skins/skins_cfg.c
deleted file mode 100644
index 3dd2d8119f3e..000000000000
--- a/src/skins/skins_cfg.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2008 Tomasz MoÅ
- * Copyright (c) 2011 John Lindgren
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <string.h>
-#include <gtk/gtk.h>
-
-#include <audacious/debug.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/preferences.h>
-#include <libaudcore/audstrings.h>
-
-#include "dnd.h"
-#include "skins_cfg.h"
-#include "ui_equalizer.h"
-#include "ui_main.h"
-#include "ui_main_evlisteners.h"
-#include "ui_playlist.h"
-#include "ui_skin.h"
-#include "ui_skinned_playlist.h"
-#include "ui_skinned_textbox.h"
-#include "ui_skinselector.h"
-#include "ui_vis.h"
-#include "util.h"
-
-static const gchar * const skins_defaults[] = {
- /* general */
- "autoscroll_songname", "TRUE",
- "mainwin_font", "Sans Bold 9",
- "mainwin_use_bitmapfont", "TRUE",
- "playlist_font", "Sans Bold 8",
- "show_remaining_time", "FALSE",
- "twoway_scroll", "FALSE",
-
- /* visualizer */
- "analyzer_falloff", "3", /* FALLOFF_FAST */
- "analyzer_mode", "0", /* ANALYZER_NORMAL */
- "analyzer_peaks", "TRUE",
- "analyzer_type", "1", /* ANALYZER_BARS */
- "peaks_falloff", "1", /* FALLOFF_SLOW */
- "scope_mode", "0", /* SCOPE_DOT */
- "vis_type", "0", /* VIS_ANALYZER */
- "voiceprint_mode", "0", /* VOICEPRINT_NORMAL */
- "vu_mode", "1", /* VU_SMOOTH */
-
- /* windows */
- "always_on_top", "FALSE",
- "equalizer_shaded", "FALSE",
- "equalizer_visible", "FALSE",
- "equalizer_x", "20",
- "equalizer_y", "136",
- "player_shaded", "FALSE",
- "player_x", "20",
- "player_y", "20",
- "playlist_shaded", "FALSE",
- "playlist_visible", "FALSE",
- "playlist_x", "295",
- "playlist_y", "20",
- "playlist_width", "275",
- "playlist_height", "232",
- "sticky", "FALSE",
- NULL};
-
-skins_cfg_t config;
-
-static GtkWidget * skin_view;
-
-typedef struct skins_cfg_boolent_t {
- const gchar * name;
- gboolean * ptr;
-} skins_cfg_boolent;
-
-static const skins_cfg_boolent skins_boolents[] = {
- /* general */
- {"autoscroll_songname", & config.autoscroll},
- {"mainwin_use_bitmapfont", & config.mainwin_use_bitmapfont},
- {"twoway_scroll", & config.twoway_scroll},
-
- /* visualizer */
- {"analyzer_peaks", & config.analyzer_peaks}};
-
-typedef struct skins_cfg_nument_t {
- const gchar * name;
- gint * ptr;
-} skins_cfg_nument;
-
-static const skins_cfg_nument skins_numents[] = {
- /* visualizer */
- {"analyzer_falloff", & config.analyzer_falloff},
- {"analyzer_mode", & config.analyzer_mode},
- {"analyzer_type", & config.analyzer_type},
- {"peaks_falloff", & config.peaks_falloff},
- {"scope_mode", & config.scope_mode},
- {"vis_type", & config.vis_type},
- {"voiceprint_mode", & config.voiceprint_mode},
- {"vu_mode", & config.vu_mode},
-
- /* windows */
- {"equalizer_x", & config.equalizer_x},
- {"equalizer_y", & config.equalizer_y},
- {"player_x", & config.player_x},
- {"player_y", & config.player_y},
- {"playlist_x", & config.playlist_x},
- {"playlist_y", & config.playlist_y},
- {"playlist_width", & config.playlist_width},
- {"playlist_height", & config.playlist_height}};
-
-typedef struct skins_cfg_strent_t {
- const gchar * name;
- gchar * * ptr;
-} skins_cfg_strent;
-
-void skins_cfg_load (void)
-{
- aud_config_set_defaults ("skins", skins_defaults);
-
- for (gint i = 0; i < ARRAY_LEN (skins_boolents); i ++)
- * skins_boolents[i].ptr = aud_get_bool ("skins", skins_boolents[i].name);
-
- for (gint i = 0; i < ARRAY_LEN (skins_numents); i ++)
- * skins_numents[i].ptr = aud_get_int ("skins", skins_numents[i].name);
-}
-
-void skins_cfg_save (void)
-{
- for (gint i = 0; i < ARRAY_LEN (skins_boolents); i ++)
- aud_set_bool ("skins", skins_boolents[i].name, * skins_boolents[i].ptr);
-
- for (gint i = 0; i < ARRAY_LEN (skins_numents); i ++)
- aud_set_int ("skins", skins_numents[i].name, * skins_numents[i].ptr);
-}
-
-static void
-mainwin_font_set_cb()
-{
- char * font = aud_get_str ("skins", "mainwin_font");
- textbox_set_font (mainwin_info, config.mainwin_use_bitmapfont ? NULL : font);
- str_unref (font);
-}
-
-static void
-playlist_font_set_cb()
-{
- char * font = aud_get_str ("skins", "playlist_font");
- ui_skinned_playlist_set_font (playlistwin_list, font);
- str_unref (font);
-}
-
-static void autoscroll_set_cb (void)
-{
- textbox_set_scroll (mainwin_info, config.autoscroll);
- textbox_set_scroll (playlistwin_sinfo, config.autoscroll);
-}
-
-static void vis_reset_cb (void)
-{
- ui_vis_clear_data (mainwin_vis);
- ui_svis_clear_data (mainwin_svis);
- start_stop_visual (FALSE);
-}
-
-static PreferencesWidget font_table_elements[] = {
- {WIDGET_FONT_BTN, N_("_Player:"),
- .cfg_type = VALUE_STRING, .csect = "skins", .cname = "mainwin_font",
- .callback = mainwin_font_set_cb, .data = {.font_btn = {N_("Select main player window font:")}}},
- {WIDGET_FONT_BTN, N_("_Playlist:"),
- .cfg_type = VALUE_STRING, .csect = "skins", .cname = "playlist_font",
- .callback = playlist_font_set_cb, .data = {.font_btn = {N_("Select playlist font:")}}}};
-
-static void * create_skin_view (void);
-
-static const PreferencesWidget skins_widgets_general[] = {
- {WIDGET_LABEL, N_("<b>Skin</b>")},
- {WIDGET_CUSTOM, .data.populate = create_skin_view},
- {WIDGET_LABEL, N_("<b>Fonts</b>")},
- {WIDGET_TABLE, .child = TRUE,
- .data.table = {font_table_elements, ARRAY_LEN (font_table_elements)}},
- {WIDGET_CHK_BTN, N_("Use bitmap fonts (supports ASCII only)"),
- .cfg_type = VALUE_BOOLEAN, .cfg = & config.mainwin_use_bitmapfont, .callback = mainwin_font_set_cb},
- {WIDGET_CHK_BTN, N_("Scroll song title"),
- .cfg_type = VALUE_BOOLEAN, .cfg = & config.autoscroll, .callback = autoscroll_set_cb},
- {WIDGET_CHK_BTN, N_("Scroll song title in both directions"),
- .cfg_type = VALUE_BOOLEAN, .cfg = & config.twoway_scroll, .callback = autoscroll_set_cb}
-};
-
-static ComboBoxElements vis_mode_elements[] = {
- {GINT_TO_POINTER (VIS_ANALYZER), N_("Analyzer")},
- {GINT_TO_POINTER (VIS_SCOPE), N_("Scope")},
- {GINT_TO_POINTER (VIS_VOICEPRINT), N_("Voiceprint / VU meter")},
- {GINT_TO_POINTER (VIS_OFF), N_("Off")}
-};
-
-static ComboBoxElements analyzer_mode_elements[] = {
- {GINT_TO_POINTER (ANALYZER_NORMAL), N_("Normal")},
- {GINT_TO_POINTER (ANALYZER_FIRE), N_("Fire")},
- {GINT_TO_POINTER (ANALYZER_VLINES), N_("Vertical lines")}
-};
-
-static ComboBoxElements analyzer_type_elements[] = {
- {GINT_TO_POINTER (ANALYZER_LINES), N_("Lines")},
- {GINT_TO_POINTER (ANALYZER_BARS), N_("Bars")}
-};
-
-static ComboBoxElements falloff_elements[] = {
- {GINT_TO_POINTER (FALLOFF_SLOWEST), N_("Slowest")},
- {GINT_TO_POINTER (FALLOFF_SLOW), N_("Slow")},
- {GINT_TO_POINTER (FALLOFF_MEDIUM), N_("Medium")},
- {GINT_TO_POINTER (FALLOFF_FAST), N_("Fast")},
- {GINT_TO_POINTER (FALLOFF_FASTEST), N_("Fastest")}
-};
-
-static ComboBoxElements scope_mode_elements[] = {
- {GINT_TO_POINTER (SCOPE_DOT), N_("Dots")},
- {GINT_TO_POINTER (SCOPE_LINE), N_("Line")},
- {GINT_TO_POINTER (SCOPE_SOLID), N_("Solid")}
-};
-
-static ComboBoxElements voiceprint_mode_elements[] = {
- {GINT_TO_POINTER (VOICEPRINT_NORMAL), N_("Normal")},
- {GINT_TO_POINTER (VOICEPRINT_FIRE), N_("Fire")},
- {GINT_TO_POINTER (VOICEPRINT_ICE), N_("Ice")}
-};
-
-static ComboBoxElements vu_mode_elements[] = {
- {GINT_TO_POINTER (VU_NORMAL), N_("Normal")},
- {GINT_TO_POINTER (VU_SMOOTH), N_("Smooth")}
-};
-
-static const PreferencesWidget skins_widgets_vis[] = {
- {WIDGET_LABEL, N_("<b>Type</b>")},
- {WIDGET_COMBO_BOX, N_("Visualization type:"),
- .cfg_type = VALUE_INT, .cfg = & config.vis_type, .callback = vis_reset_cb,
- .data.combo = {vis_mode_elements, ARRAY_LEN (vis_mode_elements)}},
- {WIDGET_LABEL, N_("<b>Analyzer</b>")},
- {WIDGET_CHK_BTN, N_("Show peaks"),
- .cfg_type = VALUE_BOOLEAN, .cfg = & config.analyzer_peaks, .callback = vis_reset_cb},
- {WIDGET_COMBO_BOX, N_("Coloring:"),
- .cfg_type = VALUE_INT, .cfg = & config.analyzer_mode, .callback = vis_reset_cb,
- .data.combo = {analyzer_mode_elements, ARRAY_LEN (analyzer_mode_elements)}},
- {WIDGET_COMBO_BOX, N_("Style:"),
- .cfg_type = VALUE_INT, .cfg = & config.analyzer_type, .callback = vis_reset_cb,
- .data.combo = {analyzer_type_elements, ARRAY_LEN (analyzer_type_elements)}},
- {WIDGET_COMBO_BOX, N_("Falloff:"),
- .cfg_type = VALUE_INT, .cfg = & config.analyzer_falloff, .callback = vis_reset_cb,
- .data.combo = {falloff_elements, ARRAY_LEN (falloff_elements)}},
- {WIDGET_COMBO_BOX, N_("Peak falloff:"),
- .cfg_type = VALUE_INT, .cfg = & config.peaks_falloff, .callback = vis_reset_cb,
- .data.combo = {falloff_elements, ARRAY_LEN (falloff_elements)}},
- {WIDGET_LABEL, N_("<b>Miscellaneous</b>")},
- {WIDGET_COMBO_BOX, N_("Scope Style:"),
- .cfg_type = VALUE_INT, .cfg = & config.scope_mode, .callback = vis_reset_cb,
- .data.combo = {scope_mode_elements, ARRAY_LEN (scope_mode_elements)}},
- {WIDGET_COMBO_BOX, N_("Voiceprint Coloring:"),
- .cfg_type = VALUE_INT, .cfg = & config.voiceprint_mode, .callback = vis_reset_cb,
- .data.combo = {voiceprint_mode_elements, ARRAY_LEN (voiceprint_mode_elements)}},
- {WIDGET_COMBO_BOX, N_("VU Meter Style:"),
- .cfg_type = VALUE_INT, .cfg = & config.vu_mode, .callback = vis_reset_cb,
- .data.combo = {vu_mode_elements, ARRAY_LEN (vu_mode_elements)}}
-};
-
-static const NotebookTab skins_notebook_tabs[] = {
- {N_("General"), skins_widgets_general, ARRAY_LEN (skins_widgets_general)},
- {N_("Visualization"), skins_widgets_vis, ARRAY_LEN (skins_widgets_vis)}
-};
-
-static const PreferencesWidget skins_widgets[] = {
- {WIDGET_NOTEBOOK, .data.notebook = {skins_notebook_tabs, ARRAY_LEN (skins_notebook_tabs)}}
-};
-
-const PluginPreferences skins_prefs = {
- .widgets = skins_widgets,
- .n_widgets = ARRAY_LEN (skins_widgets)
-};
-
-void
-on_skin_view_drag_data_received(GtkWidget * widget,
- GdkDragContext * context,
- gint x, gint y,
- GtkSelectionData * selection_data,
- guint info, guint time,
- gpointer user_data)
-{
- const gchar * data = (const gchar *) gtk_selection_data_get_data (selection_data);
- g_return_if_fail (data);
-
- const gchar * end = strchr (data, '\r');
- if (! end) end = strchr (data, '\n');
- if (! end) end = data + strlen (data);
-
- char * path = str_nget (data, end - data);
-
- if (strstr (path, "://"))
- {
- char * path2 = uri_to_filename (path);
- if (path2)
- {
- str_unref (path);
- path = path2;
- }
- }
-
- if (file_is_archive(path))
- {
- if (! active_skin_load (path))
- goto DONE;
-
- skin_install_skin(path);
-
- if (skin_view)
- skin_view_update ((GtkTreeView *) skin_view);
- }
-
-DONE:
- str_unref (path);
-}
-
-static void * create_skin_view (void)
-{
- GtkWidget * scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrolled,
- GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
- gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled, GTK_SHADOW_IN);
- gtk_widget_set_size_request (scrolled, -1, 160);
-
- skin_view = gtk_tree_view_new ();
- skin_view_realize ((GtkTreeView *) skin_view);
- skin_view_update ((GtkTreeView *) skin_view);
- gtk_container_add ((GtkContainer *) scrolled, skin_view);
-
- drag_dest_set (skin_view);
-
- g_signal_connect (skin_view, "drag-data-received",
- (GCallback) on_skin_view_drag_data_received, NULL);
- g_signal_connect (skin_view, "destroy", (GCallback) gtk_widget_destroyed, & skin_view);
-
- return scrolled;
-}
diff --git a/src/skins/skins_cfg.cc b/src/skins/skins_cfg.cc
new file mode 100644
index 000000000000..253800063ffd
--- /dev/null
+++ b/src/skins/skins_cfg.cc
@@ -0,0 +1,342 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2008 Tomasz MoÅ
+ * Copyright (c) 2011 John Lindgren
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/audstrings.h>
+
+#include "dnd.h"
+#include "skins_cfg.h"
+#include "ui_equalizer.h"
+#include "ui_main.h"
+#include "ui_main_evlisteners.h"
+#include "ui_playlist.h"
+#include "ui_skin.h"
+#include "ui_skinned_playlist.h"
+#include "ui_skinned_textbox.h"
+#include "ui_skinselector.h"
+#include "ui_vis.h"
+#include "util.h"
+
+static const char * const skins_defaults[] = {
+ /* general */
+ "autoscroll_songname", "TRUE",
+ "mainwin_font", "Sans Bold 9",
+ "mainwin_use_bitmapfont", "TRUE",
+ "playlist_font", "Sans Bold 8",
+ "show_remaining_time", "FALSE",
+ "twoway_scroll", "FALSE",
+
+ /* visualizer */
+ "analyzer_falloff", "3", /* FALLOFF_FAST */
+ "analyzer_mode", "0", /* ANALYZER_NORMAL */
+ "analyzer_peaks", "TRUE",
+ "analyzer_type", "1", /* ANALYZER_BARS */
+ "peaks_falloff", "1", /* FALLOFF_SLOW */
+ "scope_mode", "0", /* SCOPE_DOT */
+ "vis_type", "0", /* VIS_ANALYZER */
+ "voiceprint_mode", "0", /* VOICEPRINT_NORMAL */
+ "vu_mode", "1", /* VU_SMOOTH */
+
+ /* windows */
+ "always_on_top", "FALSE",
+ "double_size", "FALSE",
+ "equalizer_shaded", "FALSE",
+ "equalizer_visible", "FALSE",
+ "equalizer_x", "20",
+ "equalizer_y", "136",
+ "player_shaded", "FALSE",
+ "player_x", "20",
+ "player_y", "20",
+ "playlist_shaded", "FALSE",
+ "playlist_visible", "FALSE",
+ "playlist_x", "295",
+ "playlist_y", "20",
+ "playlist_width", "275",
+ "playlist_height", "232",
+ "sticky", "FALSE",
+ nullptr};
+
+skins_cfg_t config;
+
+static GtkWidget * skin_view;
+
+static const struct skins_cfg_boolent_t {
+ const char * name;
+ bool * ptr;
+} skins_boolents[] =
+{
+ /* general */
+ {"autoscroll_songname", & config.autoscroll},
+ {"mainwin_use_bitmapfont", & config.mainwin_use_bitmapfont},
+ {"twoway_scroll", & config.twoway_scroll},
+
+ /* visualizer */
+ {"analyzer_peaks", & config.analyzer_peaks}
+};
+
+static const struct {
+ const char * name;
+ int * ptr;
+} skins_numents[] =
+{
+ /* visualizer */
+ {"analyzer_falloff", & config.analyzer_falloff},
+ {"analyzer_mode", & config.analyzer_mode},
+ {"analyzer_type", & config.analyzer_type},
+ {"peaks_falloff", & config.peaks_falloff},
+ {"scope_mode", & config.scope_mode},
+ {"vis_type", & config.vis_type},
+ {"voiceprint_mode", & config.voiceprint_mode},
+ {"vu_mode", & config.vu_mode},
+
+ /* windows */
+ {"equalizer_x", & config.equalizer_x},
+ {"equalizer_y", & config.equalizer_y},
+ {"player_x", & config.player_x},
+ {"player_y", & config.player_y},
+ {"playlist_x", & config.playlist_x},
+ {"playlist_y", & config.playlist_y},
+ {"playlist_width", & config.playlist_width},
+ {"playlist_height", & config.playlist_height}
+};
+
+void skins_cfg_load (void)
+{
+ aud_config_set_defaults ("skins", skins_defaults);
+
+ for (auto & boolent : skins_boolents)
+ * boolent.ptr = aud_get_bool ("skins", boolent.name);
+
+ for (auto & nument : skins_numents)
+ * nument.ptr = aud_get_int ("skins", nument.name);
+
+ config.scale = aud_get_bool ("skins", "double_size") ? 2 : 1;
+}
+
+void skins_cfg_save (void)
+{
+ for (auto & boolent : skins_boolents)
+ aud_set_bool ("skins", boolent.name, * boolent.ptr);
+
+ for (auto & nument : skins_numents)
+ aud_set_int ("skins", nument.name, * nument.ptr);
+}
+
+static void
+mainwin_font_set_cb()
+{
+ String font = aud_get_str ("skins", "mainwin_font");
+ textbox_set_font (mainwin_info, config.mainwin_use_bitmapfont ? nullptr : (const char *) font);
+}
+
+static void
+playlist_font_set_cb()
+{
+ String font = aud_get_str ("skins", "playlist_font");
+ ui_skinned_playlist_set_font (playlistwin_list, font);
+}
+
+static void autoscroll_set_cb (void)
+{
+ textbox_set_scroll (mainwin_info, config.autoscroll);
+ textbox_set_scroll (playlistwin_sinfo, config.autoscroll);
+}
+
+static void vis_reset_cb (void)
+{
+ ui_vis_clear_data (mainwin_vis);
+ ui_svis_clear_data (mainwin_svis);
+ start_stop_visual (FALSE);
+}
+
+static const PreferencesWidget font_table_elements[] = {
+ WidgetFonts (N_("Player:"),
+ WidgetString ("skins", "mainwin_font", mainwin_font_set_cb),
+ {N_("Select main player window font:")}),
+ WidgetFonts (N_("Playlist:"),
+ WidgetString ("skins", "playlist_font", playlist_font_set_cb),
+ {N_("Select playlist font:")})
+};
+
+static void * create_skin_view (void);
+
+static const PreferencesWidget skins_widgets_general[] = {
+ WidgetLabel (N_("<b>Skin</b>")),
+ WidgetCustomGTK (create_skin_view),
+ WidgetLabel (N_("<b>Fonts</b>")),
+ WidgetTable ({{font_table_elements}},
+ WIDGET_CHILD),
+ WidgetCheck (N_("Use bitmap fonts (supports ASCII only)"),
+ WidgetBool (config.mainwin_use_bitmapfont, mainwin_font_set_cb)),
+ WidgetCheck (N_("Scroll song title"),
+ WidgetBool (config.autoscroll, autoscroll_set_cb)),
+ WidgetCheck (N_("Scroll song title in both directions"),
+ WidgetBool (config.twoway_scroll, autoscroll_set_cb))
+};
+
+static ComboItem vis_mode_elements[] = {
+ ComboItem (N_("Analyzer"), VIS_ANALYZER),
+ ComboItem (N_("Scope"), VIS_SCOPE),
+ ComboItem (N_("Voiceprint / VU meter"), VIS_VOICEPRINT),
+ ComboItem (N_("Off"), VIS_OFF)
+};
+
+static ComboItem analyzer_mode_elements[] = {
+ ComboItem (N_("Normal"), ANALYZER_NORMAL),
+ ComboItem (N_("Fire"), ANALYZER_FIRE),
+ ComboItem (N_("Vertical lines"), ANALYZER_VLINES)
+};
+
+static ComboItem analyzer_type_elements[] = {
+ ComboItem (N_("Lines"), ANALYZER_LINES),
+ ComboItem (N_("Bars"), ANALYZER_BARS)
+};
+
+static ComboItem falloff_elements[] = {
+ ComboItem (N_("Slowest"), FALLOFF_SLOWEST),
+ ComboItem (N_("Slow"), FALLOFF_SLOW),
+ ComboItem (N_("Medium"), FALLOFF_MEDIUM),
+ ComboItem (N_("Fast"), FALLOFF_FAST),
+ ComboItem (N_("Fastest"), FALLOFF_FASTEST)
+};
+
+static ComboItem scope_mode_elements[] = {
+ ComboItem (N_("Dots"), SCOPE_DOT),
+ ComboItem (N_("Line"), SCOPE_LINE),
+ ComboItem (N_("Solid"), SCOPE_SOLID)
+};
+
+static ComboItem voiceprint_mode_elements[] = {
+ ComboItem (N_("Normal"), VOICEPRINT_NORMAL),
+ ComboItem (N_("Fire"), VOICEPRINT_FIRE),
+ ComboItem (N_("Ice"), VOICEPRINT_ICE)
+};
+
+static ComboItem vu_mode_elements[] = {
+ ComboItem (N_("Normal"), VU_NORMAL),
+ ComboItem (N_("Smooth"), VU_SMOOTH)
+};
+
+static const PreferencesWidget skins_widgets_vis[] = {
+ WidgetLabel (N_("<b>Type</b>")),
+ WidgetCombo (N_("Visualization type:"),
+ WidgetInt (config.vis_type, vis_reset_cb),
+ {{vis_mode_elements}}),
+ WidgetLabel (N_("<b>Analyzer</b>")),
+ WidgetCheck (N_("Show peaks"),
+ WidgetBool (config.analyzer_peaks, vis_reset_cb)),
+ WidgetCombo (N_("Coloring:"),
+ WidgetInt (config.analyzer_mode, vis_reset_cb),
+ {{analyzer_mode_elements}}),
+ WidgetCombo (N_("Style:"),
+ WidgetInt (config.analyzer_type, vis_reset_cb),
+ {{analyzer_type_elements}}),
+ WidgetCombo (N_("Falloff:"),
+ WidgetInt (config.analyzer_falloff, vis_reset_cb),
+ {{falloff_elements}}),
+ WidgetCombo (N_("Peak falloff:"),
+ WidgetInt (config.peaks_falloff, vis_reset_cb),
+ {{falloff_elements}}),
+ WidgetLabel (N_("<b>Miscellaneous</b>")),
+ WidgetCombo (N_("Scope Style:"),
+ WidgetInt (config.scope_mode, vis_reset_cb),
+ {{scope_mode_elements}}),
+ WidgetCombo (N_("Voiceprint Coloring:"),
+ WidgetInt (config.voiceprint_mode, vis_reset_cb),
+ {{voiceprint_mode_elements}}),
+ WidgetCombo (N_("VU Meter Style:"),
+ WidgetInt (config.vu_mode, vis_reset_cb),
+ {{vu_mode_elements}})
+};
+
+static const NotebookTab skins_notebook_tabs[] = {
+ {N_("General"), {skins_widgets_general}},
+ {N_("Visualization"), {skins_widgets_vis}}
+};
+
+static const PreferencesWidget skins_widgets[] = {
+ WidgetNotebook ({{skins_notebook_tabs}})
+};
+
+const PluginPreferences skins_prefs = {{skins_widgets}};
+
+void
+on_skin_view_drag_data_received(GtkWidget * widget,
+ GdkDragContext * context,
+ int x, int y,
+ GtkSelectionData * selection_data,
+ unsigned info, unsigned time,
+ void * user_data)
+{
+ const char * data = (const char *) gtk_selection_data_get_data (selection_data);
+ g_return_if_fail (data);
+
+ const char * end = strchr (data, '\r');
+ if (! end) end = strchr (data, '\n');
+ if (! end) end = data + strlen (data);
+
+ StringBuf path = str_copy (data, end - data);
+
+ if (strstr (path, "://"))
+ {
+ StringBuf path2 = uri_to_filename (path);
+ if (path2)
+ path.steal (std::move (path2));
+ }
+
+ if (file_is_archive(path))
+ {
+ if (! active_skin_load (path))
+ return;
+
+ skin_install_skin(path);
+
+ if (skin_view)
+ skin_view_update ((GtkTreeView *) skin_view);
+ }
+}
+
+static void * create_skin_view (void)
+{
+ GtkWidget * scrolled = gtk_scrolled_window_new (nullptr, nullptr);
+ gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrolled,
+ GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+ gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled, GTK_SHADOW_IN);
+ gtk_widget_set_size_request (scrolled, -1, 160);
+
+ skin_view = gtk_tree_view_new ();
+ skin_view_realize ((GtkTreeView *) skin_view);
+ skin_view_update ((GtkTreeView *) skin_view);
+ gtk_container_add ((GtkContainer *) scrolled, skin_view);
+
+ drag_dest_set (skin_view);
+
+ g_signal_connect (skin_view, "drag-data-received",
+ (GCallback) on_skin_view_drag_data_received, nullptr);
+ g_signal_connect (skin_view, "destroy", (GCallback) gtk_widget_destroyed, & skin_view);
+
+ return scrolled;
+}
diff --git a/src/skins/skins_cfg.h b/src/skins/skins_cfg.h
index 45be875d9d4a..efa8fa71004a 100644
--- a/src/skins/skins_cfg.h
+++ b/src/skins/skins_cfg.h
@@ -23,23 +23,24 @@
#include <gtk/gtk.h>
-#include <audacious/types.h>
+struct PluginPreferences;
typedef struct {
- gint player_x, player_y;
- gint equalizer_x, equalizer_y;
- gint playlist_x, playlist_y;
- gint playlist_width, playlist_height;
- gboolean autoscroll;
- gboolean analyzer_peaks;
- gboolean twoway_scroll;
- gint vis_type;
- gint analyzer_mode, analyzer_type;
- gint scope_mode;
- gint voiceprint_mode;
- gint vu_mode;
- gint analyzer_falloff, peaks_falloff;
- gboolean mainwin_use_bitmapfont;
+ int player_x, player_y;
+ int equalizer_x, equalizer_y;
+ int playlist_x, playlist_y;
+ int playlist_width, playlist_height;
+ int scale;
+ bool autoscroll;
+ bool analyzer_peaks;
+ bool twoway_scroll;
+ int vis_type;
+ int analyzer_mode, analyzer_type;
+ int scope_mode;
+ int voiceprint_mode;
+ int vu_mode;
+ int analyzer_falloff, peaks_falloff;
+ bool mainwin_use_bitmapfont;
} skins_cfg_t;
extern skins_cfg_t config;
@@ -49,10 +50,10 @@ void skins_cfg_save();
void on_skin_view_drag_data_received(GtkWidget * widget,
GdkDragContext * context,
- gint x, gint y,
+ int x, int y,
GtkSelectionData * selection_data,
- guint info, guint time,
- gpointer user_data);
+ unsigned info, unsigned time,
+ void * user_data);
extern const PluginPreferences skins_prefs;
diff --git a/src/skins/surface.c b/src/skins/surface.c
deleted file mode 100644
index f26544ce3100..000000000000
--- a/src/skins/surface.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * surface.c
- * Copyright 2011 John Lindgren
- *
- * This file is part of Audacious.
- *
- * Audacious 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, version 2 or version 3 of the License.
- *
- * Audacious 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
- * Audacious. If not, see <http://www.gnu.org/licenses/>.
- *
- * The Audacious team does not consider modular code linking to Audacious or
- * using our public API to be a derived work.
- */
-
-#include <gdk/gdk.h>
-
-#include "surface.h"
-
-cairo_surface_t * surface_new (int w, int h)
-{
- return cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
-}
-
-cairo_surface_t * surface_new_from_file (const gchar * name)
-{
- GError * error = NULL;
- GdkPixbuf * p = gdk_pixbuf_new_from_file (name, & error);
- if (error) {
- fprintf (stderr, "Error loading %s: %s.\n", name, error->message);
- g_error_free (error);
- }
- if (! p)
- return NULL;
-
- cairo_surface_t * surface = surface_new (gdk_pixbuf_get_width (p),
- gdk_pixbuf_get_height (p));
- cairo_t * cr = cairo_create (surface);
-
- gdk_cairo_set_source_pixbuf (cr, p, 0, 0);
- cairo_paint (cr);
-
- cairo_destroy (cr);
- g_object_unref (p);
- return surface;
-}
-
-guint32 surface_get_pixel (cairo_surface_t * s, gint x, gint y)
-{
- if (x < 0 || x >= cairo_image_surface_get_width (s) ||
- y < 0 || y >= cairo_image_surface_get_height (s))
- return 0;
-
- return * ((guint32 *) (cairo_image_surface_get_data (s) +
- cairo_image_surface_get_stride (s) * y) + x) & 0xffffff;
-}
-
-void surface_copy_rect (cairo_surface_t * a, gint ax, gint ay, gint w, gint h,
- cairo_surface_t * b, gint bx, gint by)
-{
- cairo_t * cr = cairo_create (b);
- cairo_set_source_surface (cr, a, bx - ax, by - ay);
- cairo_rectangle (cr, bx, by, w, h);
- cairo_fill (cr);
- cairo_destroy (cr);
-}
diff --git a/src/skins/surface.cc b/src/skins/surface.cc
new file mode 100644
index 000000000000..c71dd694b246
--- /dev/null
+++ b/src/skins/surface.cc
@@ -0,0 +1,74 @@
+/*
+ * surface.c
+ * Copyright 2011 John Lindgren
+ *
+ * This file is part of Audacious.
+ *
+ * Audacious 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, version 2 or version 3 of the License.
+ *
+ * Audacious 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
+ * Audacious. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The Audacious team does not consider modular code linking to Audacious or
+ * using our public API to be a derived work.
+ */
+
+#include <gdk/gdk.h>
+
+#include "surface.h"
+
+#include <libaudcore/runtime.h>
+
+cairo_surface_t * surface_new (int w, int h)
+{
+ return cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
+}
+
+cairo_surface_t * surface_new_from_file (const char * name)
+{
+ GError * error = nullptr;
+ GdkPixbuf * p = gdk_pixbuf_new_from_file (name, & error);
+ if (error) {
+ AUDERR ("Error loading %s: %s.\n", name, error->message);
+ g_error_free (error);
+ }
+ if (! p)
+ return nullptr;
+
+ cairo_surface_t * surface = surface_new (gdk_pixbuf_get_width (p),
+ gdk_pixbuf_get_height (p));
+ cairo_t * cr = cairo_create (surface);
+
+ gdk_cairo_set_source_pixbuf (cr, p, 0, 0);
+ cairo_paint (cr);
+
+ cairo_destroy (cr);
+ g_object_unref (p);
+ return surface;
+}
+
+uint32_t surface_get_pixel (cairo_surface_t * s, int x, int y)
+{
+ if (x < 0 || x >= cairo_image_surface_get_width (s) ||
+ y < 0 || y >= cairo_image_surface_get_height (s))
+ return 0;
+
+ return * ((uint32_t *) (cairo_image_surface_get_data (s) +
+ cairo_image_surface_get_stride (s) * y) + x) & 0xffffff;
+}
+
+void surface_copy_rect (cairo_surface_t * a, int ax, int ay, int w, int h,
+ cairo_surface_t * b, int bx, int by)
+{
+ cairo_t * cr = cairo_create (b);
+ cairo_set_source_surface (cr, a, bx - ax, by - ay);
+ cairo_rectangle (cr, bx, by, w, h);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+}
diff --git a/src/skins/surface.h b/src/skins/surface.h
index d725c8e89b0c..c0343398f249 100644
--- a/src/skins/surface.h
+++ b/src/skins/surface.h
@@ -22,13 +22,13 @@
#ifndef SKINS_SURFACE_H
#define SKINS_SURFACE_H
-#include <glib.h>
+#include <stdint.h>
#include <cairo.h>
-cairo_surface_t * surface_new (gint w, gint h);
-cairo_surface_t * surface_new_from_file (const gchar * name);
-guint32 surface_get_pixel (cairo_surface_t * s, gint x, gint y);
-void surface_copy_rect (cairo_surface_t * a, gint ax, gint ay, gint w, gint h,
- cairo_surface_t * b, gint bx, gint by);
+cairo_surface_t * surface_new (int w, int h);
+cairo_surface_t * surface_new_from_file (const char * name);
+uint32_t surface_get_pixel (cairo_surface_t * s, int x, int y);
+void surface_copy_rect (cairo_surface_t * a, int ax, int ay, int w, int h,
+ cairo_surface_t * b, int bx, int by);
#endif
diff --git a/src/skins/ui_dock.c b/src/skins/ui_dock.c
deleted file mode 100644
index c3eb0a337f87..000000000000
--- a/src/skins/ui_dock.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * ui_dock.c
- * Copyright 2011 John Lindgren
- *
- * This file is part of Audacious.
- *
- * Audacious 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, version 2 or version 3 of the License.
- *
- * Audacious 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
- * Audacious. If not, see <http://www.gnu.org/licenses/>.
- *
- * The Audacious team does not consider modular code linking to Audacious or
- * using our public API to be a derived work.
- */
-
-/*
- * Rough outline
- * =============
- *
- * When moving a window:
- * 1. If this is the main window, find (recursively) the windows docked to it.
- * 2. Adjust the offsets to snap to another window (not docked) or a screen edge.
- * 3. Move the docked windows by the same offsets.
- *
- * When resizing a window:
- * 1. Find (recursively) the windows docked to the bottom edge of this one.
- * If we are making the window shorter, exclude windows that are docked to
- * the bottom of another window (not docked) to avoid overlap.
- * 2. Move the docked windows by the difference in window height.
- * 3. Repeat the process for windows docked to the right edge of this one.
- */
-
-#include <stdlib.h>
-
-#include "ui_dock.h"
-
-#define SNAP_DISTANCE 10
-
-enum {
- DOCK_TYPE_LEFT = 1 << 0,
- DOCK_TYPE_RIGHT = 1 << 1,
- DOCK_TYPE_TOP = 1 << 2,
- DOCK_TYPE_BOTTOM = 1 << 3
-};
-
-#define DOCK_TYPE_ANY (DOCK_TYPE_LEFT | DOCK_TYPE_RIGHT | DOCK_TYPE_TOP | DOCK_TYPE_BOTTOM)
-
-typedef struct {
- GtkWidget * window;
- gint * x, * y;
- gint w, h;
- gboolean main;
- gboolean docked;
-} DockWindow;
-
-static GSList * windows;
-static gint last_x, last_y;
-
-static inline gint least_abs (gint a, gint b)
-{
- return (abs (a) < abs (b)) ? a : b;
-}
-
-static DockWindow * find_window (GSList * list, GtkWidget * window)
-{
- for (GSList * node = list; node; node = node->next)
- {
- DockWindow * dw = node->data;
- if (dw->window == window)
- return dw;
- }
-
- return NULL;
-}
-
-void dock_add_window (GtkWidget * window, gint * x, gint * y, gint w, gint h,
- gboolean main)
-{
- DockWindow * dw = g_slice_new0 (DockWindow);
- dw->window = window;
- dw->x = x;
- dw->y = y;
- dw->w = w;
- dw->h = h;
- dw->main = main;
-
- windows = g_slist_prepend (windows, dw);
-}
-
-void dock_remove_window (GtkWidget * window)
-{
- DockWindow * dw = find_window (windows, window);
- g_return_if_fail (dw);
-
- windows = g_slist_remove (windows, dw);
- g_slice_free (DockWindow, dw);
-}
-
-static void dock_sync (void)
-{
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- gtk_window_get_position ((GtkWindow *) dw->window, dw->x, dw->y);
- }
-}
-
-static void clear_docked (void)
-{
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- dw->docked = FALSE;
- }
-}
-
-static gboolean is_docked (DockWindow * dw, DockWindow * base, gint type)
-{
- if ((type & DOCK_TYPE_LEFT) && * dw->x + dw->w == * base->x)
- return TRUE;
- if ((type & DOCK_TYPE_RIGHT) && * dw->x == * base->x + base->w)
- return TRUE;
- if ((type & DOCK_TYPE_TOP) && * dw->y + dw->h == * base->y)
- return TRUE;
- if ((type & DOCK_TYPE_BOTTOM) && * dw->y == * base->y + base->h)
- return TRUE;
-
- return FALSE;
-}
-
-static void find_docked (DockWindow * base, gint type)
-{
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- if (dw->docked || dw == base)
- continue;
-
- dw->docked = is_docked (dw, base, type);
- if (dw->docked)
- find_docked (dw, type);
- }
-}
-
-static void invert_docked (void)
-{
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- dw->docked = ! dw->docked;
- }
-}
-
-void dock_set_size (GtkWidget * window, gint w, gint h)
-{
- DockWindow * base = find_window (windows, window);
- g_return_if_fail (base);
-
- dock_sync ();
-
- if (h != base->h)
- {
- /* 1. Find the windows docked below this one. */
-
- clear_docked ();
- find_docked (base, DOCK_TYPE_BOTTOM);
-
- if (h < base->h)
- {
- /* 2. This part is tricky. By flipping the docked flag on all the
- windows, we consider the windows not docked to this one as a
- docked group. We then add (recursively) any other windows
- docked to these ones (i.e. the windows docked to these *and*
- to the one being shortened). The one being shortened must be
- excluded from the search. Since at this point it is marked as
- docked, it is excluded automatically. Finally, flipping the
- docked flag back again leaves us with only the windows docked
- to the one being shortened and not to any others. */
-
- invert_docked ();
-
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- if (! dw->docked || dw == base)
- continue;
-
- find_docked (dw, DOCK_TYPE_BOTTOM);
- }
-
- invert_docked ();
- }
-
- /* 3. Move the docked windows by the difference in height. */
-
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- if (! dw->docked)
- continue;
-
- * dw->y += h - base->h;
- gtk_window_move ((GtkWindow *) dw->window, * dw->x, * dw->y);
- }
- }
-
- if (w != base->w)
- {
- /* 4. Repeat the process for the windows docked to the right. */
-
- clear_docked ();
- find_docked (base, DOCK_TYPE_RIGHT);
-
- if (w < base->w)
- {
- invert_docked ();
-
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- if (! dw->docked || dw == base)
- continue;
-
- find_docked (dw, DOCK_TYPE_RIGHT);
- }
-
- invert_docked ();
- }
-
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- if (! dw->docked)
- continue;
-
- * dw->x += w - base->w;
- gtk_window_move ((GtkWindow *) dw->window, * dw->x, * dw->y);
- }
- }
-
- /* 5. Set the window size. (The actual resize is done by the caller.) */
-
- base->w = w;
- base->h = h;
-}
-
-void dock_move_start (GtkWidget * window, gint x, gint y)
-{
- DockWindow * dw = find_window (windows, window);
- g_return_if_fail (dw);
-
- dock_sync ();
-
- last_x = x;
- last_y = y;
-
- /* 1. If this is the main window, find the windows docked to it. */
-
- clear_docked ();
- dw->docked = TRUE;
- if (dw->main)
- find_docked (dw, DOCK_TYPE_ANY);
-}
-
-void dock_move (gint x, gint y)
-{
- gint hori, vert;
-
- if (x == last_x && y == last_y)
- return;
-
- /* 2. Nominally move all the windows in the group the requested distance,
- and update the reference point. */
-
- hori = x - last_x;
- vert = y - last_y;
-
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- if (! dw->docked)
- continue;
-
- * dw->x += hori;
- * dw->y += vert;
- }
-
- last_x = x;
- last_y = y;
-
-
- /* 3. Find the least snap distance we must move so that
- (a) a window in the group is touching a screen edge or
- (b) a window in the group is touching a window not in the group. */
-
- hori = SNAP_DISTANCE + 1;
- vert = SNAP_DISTANCE + 1;
-
- GdkScreen * screen = gdk_screen_get_default ();
- gint monitors = gdk_screen_get_n_monitors (screen);
-
- for (gint m = 0; m < monitors; m ++)
- {
- GdkRectangle rect;
- gdk_screen_get_monitor_geometry (screen, m, & rect);
-
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- if (! dw->docked)
- continue;
-
- /* We only test half the combinations here, as it is not very
- helpful to have e.g. the right edge of a window touching the left
- edge of a monitor (think about it). */
-
- hori = least_abs (hori, rect.x - * dw->x);
- hori = least_abs (hori, (rect.x + rect.width) - (* dw->x + dw->w));
- vert = least_abs (vert, rect.y - * dw->y);
- vert = least_abs (vert, (rect.y + rect.height) - (* dw->y + dw->h));
- }
- }
-
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- if (! dw->docked)
- continue;
-
- for (GSList * node2 = windows; node2; node2 = node2->next)
- {
- DockWindow * dw2 = node2->data;
- if (dw2->docked)
- continue;
-
- hori = least_abs (hori, * dw2->x - * dw->x);
- hori = least_abs (hori, * dw2->x - (* dw->x + dw->w));
- hori = least_abs (hori, (* dw2->x + dw2->w) - * dw->x);
- hori = least_abs (hori, (* dw2->x + dw2->w) - (* dw->x + dw->w));
- vert = least_abs (vert, * dw2->y - * dw->y);
- vert = least_abs (vert, * dw2->y - (* dw->y + dw->h));
- vert = least_abs (vert, (* dw2->y + dw2->h) - * dw->y);
- vert = least_abs (vert, (* dw2->y + dw2->h) - (* dw->y + dw->h));
- }
- }
-
- /* 4. If the snap distances are within range, nominally move all the windows
- in the group, and update the reference point again. */
-
- if (abs (hori) > SNAP_DISTANCE)
- hori = 0;
- if (abs (vert) > SNAP_DISTANCE)
- vert = 0;
-
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- if (! dw->docked)
- continue;
-
- * dw->x += hori;
- * dw->y += vert;
- }
-
- last_x += hori;
- last_y += vert;
-
- /* 5. Really move the windows. */
-
- for (GSList * node = windows; node; node = node->next)
- {
- DockWindow * dw = node->data;
- if (! dw->docked)
- continue;
-
- gtk_window_move ((GtkWindow *) dw->window, * dw->x, * dw->y);
- }
-}
diff --git a/src/skins/ui_dock.cc b/src/skins/ui_dock.cc
new file mode 100644
index 000000000000..dfa302c05462
--- /dev/null
+++ b/src/skins/ui_dock.cc
@@ -0,0 +1,384 @@
+/*
+ * ui_dock.c
+ * Copyright 2011 John Lindgren
+ *
+ * This file is part of Audacious.
+ *
+ * Audacious 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, version 2 or version 3 of the License.
+ *
+ * Audacious 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
+ * Audacious. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The Audacious team does not consider modular code linking to Audacious or
+ * using our public API to be a derived work.
+ */
+
+/*
+ * Rough outline
+ * =============
+ *
+ * When moving a window:
+ * 1. If this is the main window, find (recursively) the windows docked to it.
+ * 2. Adjust the offsets to snap to another window (not docked) or a screen edge.
+ * 3. Move the docked windows by the same offsets.
+ *
+ * When resizing a window:
+ * 1. Find (recursively) the windows docked to the bottom edge of this one.
+ * If we are making the window shorter, exclude windows that are docked to
+ * the bottom of another window (not docked) to avoid overlap.
+ * 2. Move the docked windows by the difference in window height.
+ * 3. Repeat the process for windows docked to the right edge of this one.
+ */
+
+#include <stdlib.h>
+
+#include "ui_dock.h"
+
+#define SNAP_DISTANCE 10
+
+enum {
+ DOCK_TYPE_LEFT = 1 << 0,
+ DOCK_TYPE_RIGHT = 1 << 1,
+ DOCK_TYPE_TOP = 1 << 2,
+ DOCK_TYPE_BOTTOM = 1 << 3
+};
+
+#define DOCK_TYPE_ANY (DOCK_TYPE_LEFT | DOCK_TYPE_RIGHT | DOCK_TYPE_TOP | DOCK_TYPE_BOTTOM)
+
+typedef struct {
+ GtkWidget * window;
+ int * x, * y;
+ int w, h;
+ gboolean main;
+ gboolean docked;
+} DockWindow;
+
+static GSList * windows;
+static int last_x, last_y;
+
+static inline int least_abs (int a, int b)
+{
+ return (abs (a) < abs (b)) ? a : b;
+}
+
+static DockWindow * find_window (GSList * list, GtkWidget * window)
+{
+ for (GSList * node = list; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ if (dw->window == window)
+ return dw;
+ }
+
+ return nullptr;
+}
+
+void dock_add_window (GtkWidget * window, int * x, int * y, int w, int h,
+ gboolean main)
+{
+ DockWindow * dw = g_slice_new0 (DockWindow);
+ dw->window = window;
+ dw->x = x;
+ dw->y = y;
+ dw->w = w;
+ dw->h = h;
+ dw->main = main;
+
+ windows = g_slist_prepend (windows, dw);
+}
+
+void dock_remove_window (GtkWidget * window)
+{
+ DockWindow * dw = find_window (windows, window);
+ g_return_if_fail (dw);
+
+ windows = g_slist_remove (windows, dw);
+ g_slice_free (DockWindow, dw);
+}
+
+static void dock_sync (void)
+{
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ gtk_window_get_position ((GtkWindow *) dw->window, dw->x, dw->y);
+ }
+}
+
+static void clear_docked (void)
+{
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ dw->docked = FALSE;
+ }
+}
+
+static gboolean is_docked (DockWindow * dw, DockWindow * base, int type)
+{
+ if ((type & DOCK_TYPE_LEFT) && * dw->x + dw->w == * base->x)
+ return TRUE;
+ if ((type & DOCK_TYPE_RIGHT) && * dw->x == * base->x + base->w)
+ return TRUE;
+ if ((type & DOCK_TYPE_TOP) && * dw->y + dw->h == * base->y)
+ return TRUE;
+ if ((type & DOCK_TYPE_BOTTOM) && * dw->y == * base->y + base->h)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void find_docked (DockWindow * base, int type)
+{
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ if (dw->docked || dw == base)
+ continue;
+
+ dw->docked = is_docked (dw, base, type);
+ if (dw->docked)
+ find_docked (dw, type);
+ }
+}
+
+static void invert_docked (void)
+{
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ dw->docked = ! dw->docked;
+ }
+}
+
+void dock_set_size (GtkWidget * window, int w, int h)
+{
+ DockWindow * base = find_window (windows, window);
+ g_return_if_fail (base);
+
+ dock_sync ();
+
+ if (h != base->h)
+ {
+ /* 1. Find the windows docked below this one. */
+
+ clear_docked ();
+ find_docked (base, DOCK_TYPE_BOTTOM);
+
+ if (h < base->h)
+ {
+ /* 2. This part is tricky. By flipping the docked flag on all the
+ windows, we consider the windows not docked to this one as a
+ docked group. We then add (recursively) any other windows
+ docked to these ones (i.e. the windows docked to these *and*
+ to the one being shortened). The one being shortened must be
+ excluded from the search. Since at this point it is marked as
+ docked, it is excluded automatically. Finally, flipping the
+ docked flag back again leaves us with only the windows docked
+ to the one being shortened and not to any others. */
+
+ invert_docked ();
+
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ if (! dw->docked || dw == base)
+ continue;
+
+ find_docked (dw, DOCK_TYPE_BOTTOM);
+ }
+
+ invert_docked ();
+ }
+
+ /* 3. Move the docked windows by the difference in height. */
+
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ if (! dw->docked)
+ continue;
+
+ * dw->y += h - base->h;
+ gtk_window_move ((GtkWindow *) dw->window, * dw->x, * dw->y);
+ }
+ }
+
+ if (w != base->w)
+ {
+ /* 4. Repeat the process for the windows docked to the right. */
+
+ clear_docked ();
+ find_docked (base, DOCK_TYPE_RIGHT);
+
+ if (w < base->w)
+ {
+ invert_docked ();
+
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ if (! dw->docked || dw == base)
+ continue;
+
+ find_docked (dw, DOCK_TYPE_RIGHT);
+ }
+
+ invert_docked ();
+ }
+
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ if (! dw->docked)
+ continue;
+
+ * dw->x += w - base->w;
+ gtk_window_move ((GtkWindow *) dw->window, * dw->x, * dw->y);
+ }
+ }
+
+ /* 5. Set the window size. (The actual resize is done by the caller.) */
+
+ base->w = w;
+ base->h = h;
+}
+
+void dock_move_start (GtkWidget * window, int x, int y)
+{
+ DockWindow * dw = find_window (windows, window);
+ g_return_if_fail (dw);
+
+ dock_sync ();
+
+ last_x = x;
+ last_y = y;
+
+ /* 1. If this is the main window, find the windows docked to it. */
+
+ clear_docked ();
+ dw->docked = TRUE;
+ if (dw->main)
+ find_docked (dw, DOCK_TYPE_ANY);
+}
+
+void dock_move (int x, int y)
+{
+ int hori, vert;
+
+ if (x == last_x && y == last_y)
+ return;
+
+ /* 2. Nominally move all the windows in the group the requested distance,
+ and update the reference point. */
+
+ hori = x - last_x;
+ vert = y - last_y;
+
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ if (! dw->docked)
+ continue;
+
+ * dw->x += hori;
+ * dw->y += vert;
+ }
+
+ last_x = x;
+ last_y = y;
+
+
+ /* 3. Find the least snap distance we must move so that
+ (a) a window in the group is touching a screen edge or
+ (b) a window in the group is touching a window not in the group. */
+
+ hori = SNAP_DISTANCE + 1;
+ vert = SNAP_DISTANCE + 1;
+
+ GdkScreen * screen = gdk_screen_get_default ();
+ int monitors = gdk_screen_get_n_monitors (screen);
+
+ for (int m = 0; m < monitors; m ++)
+ {
+ GdkRectangle rect;
+ gdk_screen_get_monitor_geometry (screen, m, & rect);
+
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ if (! dw->docked)
+ continue;
+
+ /* We only test half the combinations here, as it is not very
+ helpful to have e.g. the right edge of a window touching the left
+ edge of a monitor (think about it). */
+
+ hori = least_abs (hori, rect.x - * dw->x);
+ hori = least_abs (hori, (rect.x + rect.width) - (* dw->x + dw->w));
+ vert = least_abs (vert, rect.y - * dw->y);
+ vert = least_abs (vert, (rect.y + rect.height) - (* dw->y + dw->h));
+ }
+ }
+
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ if (! dw->docked)
+ continue;
+
+ for (GSList * node2 = windows; node2; node2 = node2->next)
+ {
+ DockWindow * dw2 = (DockWindow *) node2->data;
+ if (dw2->docked)
+ continue;
+
+ hori = least_abs (hori, * dw2->x - * dw->x);
+ hori = least_abs (hori, * dw2->x - (* dw->x + dw->w));
+ hori = least_abs (hori, (* dw2->x + dw2->w) - * dw->x);
+ hori = least_abs (hori, (* dw2->x + dw2->w) - (* dw->x + dw->w));
+ vert = least_abs (vert, * dw2->y - * dw->y);
+ vert = least_abs (vert, * dw2->y - (* dw->y + dw->h));
+ vert = least_abs (vert, (* dw2->y + dw2->h) - * dw->y);
+ vert = least_abs (vert, (* dw2->y + dw2->h) - (* dw->y + dw->h));
+ }
+ }
+
+ /* 4. If the snap distances are within range, nominally move all the windows
+ in the group, and update the reference point again. */
+
+ if (abs (hori) > SNAP_DISTANCE)
+ hori = 0;
+ if (abs (vert) > SNAP_DISTANCE)
+ vert = 0;
+
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ if (! dw->docked)
+ continue;
+
+ * dw->x += hori;
+ * dw->y += vert;
+ }
+
+ last_x += hori;
+ last_y += vert;
+
+ /* 5. Really move the windows. */
+
+ for (GSList * node = windows; node; node = node->next)
+ {
+ DockWindow * dw = (DockWindow *) node->data;
+ if (! dw->docked)
+ continue;
+
+ gtk_window_move ((GtkWindow *) dw->window, * dw->x, * dw->y);
+ }
+}
diff --git a/src/skins/ui_dock.h b/src/skins/ui_dock.h
index 2bccaf4f1c42..da9c7b631d32 100644
--- a/src/skins/ui_dock.h
+++ b/src/skins/ui_dock.h
@@ -24,13 +24,13 @@
#include <gtk/gtk.h>
-void dock_add_window (GtkWidget * window, gint * x, gint * y, gint w, gint h,
+void dock_add_window (GtkWidget * window, int * x, int * y, int w, int h,
gboolean main);
void dock_remove_window (GtkWidget * window);
-void dock_set_size (GtkWidget * window, gint w, gint h);
+void dock_set_size (GtkWidget * window, int w, int h);
-void dock_move_start (GtkWidget * window, gint x, gint y);
-void dock_move (gint x, gint y);
+void dock_move_start (GtkWidget * window, int x, int y);
+void dock_move (int x, int y);
#endif
diff --git a/src/skins/ui_equalizer.c b/src/skins/ui_equalizer.c
deleted file mode 100644
index 4f4757131e36..000000000000
--- a/src/skins/ui_equalizer.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/* Audacious - Cross-platform multimedia player
- * Copyright (C) 2005-2014 Audacious development team.
- *
- * Based on BMP:
- * Copyright (C) 2003-2004 BMP development team.
- *
- * Based on XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <string.h>
-#include <gtk/gtk.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "menus.h"
-#include "plugin.h"
-#include "preset-list.h"
-#include "skins_cfg.h"
-#include "ui_equalizer.h"
-#include "ui_main.h"
-#include "ui_skinned_button.h"
-#include "ui_skinned_equalizer_graph.h"
-#include "ui_skinned_equalizer_slider.h"
-#include "ui_skinned_horizontal_slider.h"
-#include "ui_skinned_window.h"
-#include "util.h"
-#include "view.h"
-
-static gfloat equalizerwin_get_preamp (void);
-static gfloat equalizerwin_get_band (gint band);
-static void equalizerwin_set_preamp (gfloat preamp);
-static void equalizerwin_set_band (gint band, gfloat value);
-
-static void position_cb (void * data, void * user_data);
-
-GtkWidget *equalizerwin;
-static GtkWidget *equalizerwin_graph;
-
-static GtkWidget *equalizerwin_on, *equalizerwin_auto;
-
-static GtkWidget *equalizerwin_close, *equalizerwin_shade;
-static GtkWidget *equalizerwin_shaded_close, *equalizerwin_shaded_shade;
-static GtkWidget *equalizerwin_presets;
-static GtkWidget *equalizerwin_preamp,*equalizerwin_bands[10];
-static GtkWidget *equalizerwin_volume, *equalizerwin_balance;
-
-Index * equalizer_presets, * equalizer_auto_presets;
-
-void equalizerwin_set_shape (void)
-{
- int id = aud_get_bool ("skins", "equalizer_shaded") ? SKIN_MASK_EQ_SHADE : SKIN_MASK_EQ;
- gtk_widget_shape_combine_region (equalizerwin, active_skin->masks[id]);
-}
-
-static void
-equalizerwin_shade_toggle(void)
-{
- view_set_equalizer_shaded (! aud_get_bool ("skins", "equalizer_shaded"));
-}
-
-void
-equalizerwin_eq_changed(void)
-{
- aud_set_double (NULL, "equalizer_preamp", equalizerwin_get_preamp ());
-
- double bands[AUD_EQUALIZER_NBANDS];
- for (gint i = 0; i < AUD_EQUALIZER_NBANDS; i ++)
- bands[i] = equalizerwin_get_band (i);
-
- aud_eq_set_bands (bands);
-}
-
-void equalizerwin_apply_preset (const EqualizerPreset * preset)
-{
- equalizerwin_set_preamp (preset->preamp);
- for (int i = 0; i < AUD_EQUALIZER_NBANDS; i ++)
- equalizerwin_set_band (i, preset->bands[i]);
-}
-
-void equalizerwin_update_preset (EqualizerPreset * preset)
-{
- preset->preamp = equalizerwin_get_preamp ();
- for (int i = 0; i < AUD_EQUALIZER_NBANDS; i ++)
- preset->bands[i] = equalizerwin_get_band (i);
-}
-
-void equalizerwin_import_presets (Index * presets)
-{
- index_copy_insert (presets, 0, equalizer_presets, -1, -1);
- index_free (presets);
-
- aud_equalizer_write_presets (equalizer_presets, "eq.preset");
-}
-
-static void eq_on_cb (GtkWidget * button, GdkEventButton * event)
- {aud_set_bool (NULL, "equalizer_active", button_get_active (button)); }
-static void eq_auto_cb (GtkWidget * button, GdkEventButton * event)
- {aud_set_bool (NULL, "equalizer_autoload", button_get_active (equalizerwin_auto)); }
-
-static void update_from_config (void * unused1, void * unused2)
-{
- button_set_active (equalizerwin_on, aud_get_bool (NULL, "equalizer_active"));
- eq_slider_set_val (equalizerwin_preamp, aud_get_double (NULL, "equalizer_preamp"));
-
- gdouble bands[AUD_EQUALIZER_NBANDS];
- aud_eq_get_bands (bands);
-
- for (gint i = 0; i < AUD_EQUALIZER_NBANDS; i ++)
- eq_slider_set_val (equalizerwin_bands[i], bands[i]);
-
- eq_graph_update (equalizerwin_graph);
-}
-
-static void eq_presets_cb (GtkWidget * button, GdkEventButton * event)
-{
- menu_popup (UI_MENU_EQUALIZER_PRESET, event->x_root, event->y_root, FALSE,
- FALSE, event->button, event->time);
-}
-
-static gboolean
-equalizerwin_press(GtkWidget * widget, GdkEventButton * event,
- gpointer callback_data)
-{
- if (event->button == 1 && event->type == GDK_2BUTTON_PRESS &&
- event->window == gtk_widget_get_window (widget) && event->y < 14)
- {
- equalizerwin_shade_toggle ();
- return TRUE;
- }
-
- if (event->button == 3)
- {
- menu_popup (UI_MENU_MAIN, event->x_root, event->y_root, FALSE, FALSE,
- event->button, event->time);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-equalizerwin_close_cb(void)
-{
- view_set_show_equalizer (FALSE);
-}
-
-static void eqwin_volume_set_knob (void)
-{
- gint pos = hslider_get_pos (equalizerwin_volume);
-
- gint x;
- if (pos < 32)
- x = 1;
- else if (pos < 63)
- x = 4;
- else
- x = 7;
-
- hslider_set_knob (equalizerwin_volume, x, 30, x, 30);
-}
-
-void equalizerwin_set_volume_slider (gint percent)
-{
- hslider_set_pos (equalizerwin_volume, (percent * 94 + 50) / 100);
- eqwin_volume_set_knob ();
-}
-
-static void eqwin_volume_motion_cb (void)
-{
- eqwin_volume_set_knob ();
- gint pos = hslider_get_pos (equalizerwin_volume);
- gint v = (pos * 100 + 47) / 94;
-
- mainwin_adjust_volume_motion(v);
- mainwin_set_volume_slider(v);
-}
-
-static void eqwin_volume_release_cb (void)
-{
- eqwin_volume_set_knob ();
- mainwin_adjust_volume_release();
-}
-
-static void eqwin_balance_set_knob (void)
-{
- gint pos = hslider_get_pos (equalizerwin_balance);
-
- gint x;
- if (pos < 13)
- x = 11;
- else if (pos < 26)
- x = 14;
- else
- x = 17;
-
- hslider_set_knob (equalizerwin_balance, x, 30, x, 30);
-}
-
-void equalizerwin_set_balance_slider (gint percent)
-{
- if (percent > 0)
- hslider_set_pos (equalizerwin_balance, 19 + (percent * 19 + 50) / 100);
- else
- hslider_set_pos (equalizerwin_balance, 19 + (percent * 19 - 50) / 100);
-
- eqwin_balance_set_knob ();
-}
-
-static void eqwin_balance_motion_cb (void)
-{
- eqwin_balance_set_knob ();
- gint pos = hslider_get_pos (equalizerwin_balance);
- pos = MIN(pos, 38); /* The skin uses a even number of pixels
- for the balance-slider *sigh* */
- gint b;
- if (pos > 19)
- b = ((pos - 19) * 100 + 9) / 19;
- else
- b = ((pos - 19) * 100 - 9) / 19;
-
- mainwin_adjust_balance_motion(b);
- mainwin_set_balance_slider(b);
-}
-
-static void eqwin_balance_release_cb (void)
-{
- eqwin_balance_set_knob ();
- mainwin_adjust_balance_release();
-}
-
-static void
-equalizerwin_create_widgets(void)
-{
- equalizerwin_on = button_new_toggle (25, 12, 10, 119, 128, 119, 69, 119, 187, 119, SKIN_EQMAIN, SKIN_EQMAIN);
- window_put_widget (equalizerwin, FALSE, equalizerwin_on, 14, 18);
- button_set_active (equalizerwin_on, aud_get_bool (NULL, "equalizer_active"));
- button_on_release (equalizerwin_on, eq_on_cb);
-
- equalizerwin_auto = button_new_toggle (33, 12, 35, 119, 153, 119, 94, 119, 212, 119, SKIN_EQMAIN, SKIN_EQMAIN);
- window_put_widget (equalizerwin, FALSE, equalizerwin_auto, 39, 18);
- button_set_active (equalizerwin_auto, aud_get_bool (NULL, "equalizer_autoload"));
- button_on_release (equalizerwin_auto, eq_auto_cb);
-
- equalizerwin_presets = button_new (44, 12, 224, 164, 224, 176, SKIN_EQMAIN, SKIN_EQMAIN);
- window_put_widget (equalizerwin, FALSE, equalizerwin_presets, 217, 18);
- button_on_release (equalizerwin_presets, eq_presets_cb);
-
- equalizerwin_close = button_new (9, 9, 0, 116, 0, 125, SKIN_EQMAIN, SKIN_EQMAIN);
- window_put_widget (equalizerwin, FALSE, equalizerwin_close, 264, 3);
- button_on_release (equalizerwin_close, (ButtonCB) equalizerwin_close_cb);
-
- equalizerwin_shade = button_new (9, 9, 254, 137, 1, 38, SKIN_EQMAIN, SKIN_EQ_EX);
- window_put_widget (equalizerwin, FALSE, equalizerwin_shade, 254, 3);
- button_on_release (equalizerwin_shade, (ButtonCB) equalizerwin_shade_toggle);
-
- equalizerwin_shaded_close = button_new (9, 9, 11, 38, 11, 47, SKIN_EQ_EX, SKIN_EQ_EX);
- window_put_widget (equalizerwin, TRUE, equalizerwin_shaded_close, 264, 3);
- button_on_release (equalizerwin_shaded_close, (ButtonCB) equalizerwin_close_cb);
-
- equalizerwin_shaded_shade = button_new (9, 9, 254, 3, 1, 47, SKIN_EQ_EX, SKIN_EQ_EX);
- window_put_widget (equalizerwin, TRUE, equalizerwin_shaded_shade, 254, 3);
- button_on_release (equalizerwin_shaded_shade, (ButtonCB) equalizerwin_shade_toggle);
-
- equalizerwin_graph = eq_graph_new ();
- window_put_widget (equalizerwin, FALSE, equalizerwin_graph, 86, 17);
-
- equalizerwin_preamp = eq_slider_new (_("Preamp"));
- window_put_widget (equalizerwin, FALSE, equalizerwin_preamp, 21, 38);
- eq_slider_set_val (equalizerwin_preamp, aud_get_double (NULL, "equalizer_preamp"));
-
- const gchar * const bandnames[AUD_EQUALIZER_NBANDS] = {N_("31 Hz"),
- N_("63 Hz"), N_("125 Hz"), N_("250 Hz"), N_("500 Hz"), N_("1 kHz"),
- N_("2 kHz"), N_("4 kHz"), N_("8 kHz"), N_("16 kHz")};
- gdouble bands[AUD_EQUALIZER_NBANDS];
- aud_eq_get_bands (bands);
-
- for (gint i = 0; i < AUD_EQUALIZER_NBANDS; i ++)
- {
- equalizerwin_bands[i] = eq_slider_new (_(bandnames[i]));
- window_put_widget (equalizerwin, FALSE, equalizerwin_bands[i], 78 + 18 * i, 38);
- eq_slider_set_val (equalizerwin_bands[i], bands[i]);
- }
-
- equalizerwin_volume = hslider_new (0, 94, SKIN_EQ_EX, 97, 8, 61, 4, 3, 7, 1, 30, 1, 30);
- window_put_widget (equalizerwin, TRUE, equalizerwin_volume, 61, 4);
- hslider_on_motion (equalizerwin_volume, eqwin_volume_motion_cb);
- hslider_on_release (equalizerwin_volume, eqwin_volume_release_cb);
-
- equalizerwin_balance = hslider_new (0, 39, SKIN_EQ_EX, 42, 8, 164, 4, 3, 7, 11, 30, 11, 30);
- window_put_widget (equalizerwin, TRUE, equalizerwin_balance, 164, 4);
- hslider_on_motion (equalizerwin_balance, eqwin_balance_motion_cb);
- hslider_on_release (equalizerwin_balance, eqwin_balance_release_cb);
-}
-
-static void eq_win_draw (GtkWidget * window, cairo_t * cr)
-{
- bool_t shaded = aud_get_bool ("skins", "equalizer_shaded");
-
- skin_draw_pixbuf (cr, SKIN_EQMAIN, 0, 0, 0, 0, 275, shaded ? 14 : 116);
-
- if (shaded)
- skin_draw_pixbuf (cr, SKIN_EQ_EX, 0, 0, 0, 0, 275, 14);
- else
- skin_draw_pixbuf (cr, SKIN_EQMAIN, 0, 134, 0, 0, 275, 14);
-}
-
-static void
-equalizerwin_create_window(void)
-{
- bool_t shaded = aud_get_bool ("skins", "equalizer_shaded");
-
- equalizerwin = window_new (& config.equalizer_x, & config.equalizer_y, 275,
- shaded ? 14 : 116, FALSE, shaded, eq_win_draw);
-
- gtk_window_set_title(GTK_WINDOW(equalizerwin), _("Audacious Equalizer"));
-
- /* this will hide only mainwin. it's annoying! yaz */
- gtk_window_set_transient_for(GTK_WINDOW(equalizerwin),
- GTK_WINDOW(mainwin));
- gtk_window_set_skip_taskbar_hint(GTK_WINDOW(equalizerwin), TRUE);
-
- gtk_widget_set_app_paintable(equalizerwin, TRUE);
-
- g_signal_connect (equalizerwin, "delete-event", (GCallback) handle_window_close, NULL);
- g_signal_connect (equalizerwin, "button-press-event", (GCallback) equalizerwin_press, NULL);
- g_signal_connect (equalizerwin, "key-press-event", (GCallback) mainwin_keypress, NULL);
-}
-
-static void equalizerwin_destroyed (void)
-{
- hook_dissociate ("set equalizer_active", (HookFunction) update_from_config);
- hook_dissociate ("set equalizer_bands", (HookFunction) update_from_config);
- hook_dissociate ("set equalizer_preamp", (HookFunction) update_from_config);
-
- hook_dissociate ("playlist position", position_cb);
-
- index_free_full (equalizer_presets, (IndexFreeFunc) aud_equalizer_preset_free);
- index_free_full (equalizer_auto_presets, (IndexFreeFunc) aud_equalizer_preset_free);
- equalizer_presets = NULL;
- equalizer_auto_presets = NULL;
-}
-
-void
-equalizerwin_create(void)
-{
- equalizer_presets = aud_equalizer_read_presets("eq.preset");
- equalizer_auto_presets = aud_equalizer_read_presets("eq.auto_preset");
-
- if (! equalizer_presets)
- equalizer_presets = index_new ();
- if (! equalizer_auto_presets)
- equalizer_auto_presets = index_new ();
-
- equalizerwin_create_window();
-
- gtk_window_add_accel_group ((GtkWindow *) equalizerwin, menu_get_accel_group ());
-
- equalizerwin_create_widgets();
- window_show_all (equalizerwin);
-
- g_signal_connect (equalizerwin, "destroy", (GCallback) equalizerwin_destroyed, NULL);
-
- hook_associate ("set equalizer_active", (HookFunction) update_from_config, NULL);
- hook_associate ("set equalizer_bands", (HookFunction) update_from_config, NULL);
- hook_associate ("set equalizer_preamp", (HookFunction) update_from_config, NULL);
-
- int playlist = aud_playlist_get_playing ();
-
- /* Load preset for the first song. FIXME: Doing this at interface load is
- really too late as the song may already be started. Really, this stuff
- shouldn't be in the interface plugin at all but in core. -jlindgren */
- if (playlist != -1)
- position_cb (GINT_TO_POINTER (playlist), NULL);
-
- hook_associate ("playlist position", position_cb, NULL);
-}
-
-static int equalizerwin_find_preset (Index * list, const char * name)
-{
- for (int p = 0; p < index_count (list); p ++)
- {
- EqualizerPreset * preset = index_get (list, p);
- if (!g_ascii_strcasecmp(preset->name, name))
- return p;
- }
-
- return -1;
-}
-
-bool_t equalizerwin_load_preset (Index * list, const char * name)
-{
- int p = equalizerwin_find_preset (list, name);
- if (p < 0)
- return FALSE;
-
- equalizerwin_apply_preset (index_get (list, p));
- return TRUE;
-}
-
-void equalizerwin_save_preset (Index * list, const char * name, const char * filename)
-{
- int p = equalizerwin_find_preset (list, name);
- EqualizerPreset * preset = (p >= 0) ? index_get (list, p) : NULL;
-
- if (! preset)
- {
- preset = aud_equalizer_preset_new (name);
- index_insert (list, -1, preset);
- }
-
- equalizerwin_update_preset (preset);
-
- aud_equalizer_write_presets (list, filename);
-}
-
-void equalizerwin_delete_preset (Index * list, const char * name, const char * filename)
-{
- int p = equalizerwin_find_preset (list, name);
- if (p < 0)
- return;
-
- index_delete_full (list, p, 1, (IndexFreeFunc) aud_equalizer_preset_free);
-
- aud_equalizer_write_presets (list, filename);
-}
-
-static gboolean equalizerwin_read_aud_preset (const gchar * file)
-{
- EqualizerPreset * preset = aud_load_preset_file (file);
-
- if (preset == NULL)
- return FALSE;
-
- equalizerwin_apply_preset (preset);
- aud_equalizer_preset_free (preset);
- return TRUE;
-}
-
-static void equalizerwin_set_preamp (gfloat preamp)
-{
- eq_slider_set_val (equalizerwin_preamp, preamp);
- equalizerwin_eq_changed();
-}
-
-static void equalizerwin_set_band (gint band, gfloat value)
-{
- g_return_if_fail(band >= 0 && band < AUD_EQUALIZER_NBANDS);
- eq_slider_set_val (equalizerwin_bands[band], value);
- equalizerwin_eq_changed();
-}
-
-static gfloat equalizerwin_get_preamp (void)
-{
- return eq_slider_get_val (equalizerwin_preamp);
-}
-
-static gfloat equalizerwin_get_band (gint band)
-{
- g_return_val_if_fail(band >= 0 && band < AUD_EQUALIZER_NBANDS, 0.0);
- return eq_slider_get_val (equalizerwin_bands[band]);
-}
-
-static void load_auto_preset (const gchar * filename)
-{
- gchar * ext = EQUALIZER_DEFAULT_PRESET_EXT;
- gchar * eq_file = g_strconcat (filename, ".", ext, NULL);
- gboolean success = equalizerwin_read_aud_preset (eq_file);
- g_free (eq_file);
-
- if (success)
- return;
-
- gchar * deffile = EQUALIZER_DEFAULT_DIR_PRESET;
- gchar * folder = g_path_get_dirname (filename);
- eq_file = g_build_filename (folder, deffile, NULL);
- success = equalizerwin_read_aud_preset (eq_file);
-
- g_free (folder);
- g_free (eq_file);
-
- if (success)
- return;
-
- gchar * base = g_path_get_basename (filename);
-
- if (! equalizerwin_load_preset (equalizer_auto_presets, base))
- eq_preset_load_default ();
-
- g_free (base);
-}
-
-static void position_cb (void * data, void * user_data)
-{
- gint playlist = GPOINTER_TO_INT (data);
- gint position = aud_playlist_get_position (playlist);
-
- if (! aud_get_bool (NULL, "equalizer_autoload") || playlist !=
- aud_playlist_get_playing () || position == -1)
- return;
-
- gchar * filename = aud_playlist_entry_get_filename (playlist, position);
- load_auto_preset (filename);
- str_unref (filename);
-}
diff --git a/src/skins/ui_equalizer.cc b/src/skins/ui_equalizer.cc
new file mode 100644
index 000000000000..9cb2edfcdd0f
--- /dev/null
+++ b/src/skins/ui_equalizer.cc
@@ -0,0 +1,498 @@
+/* Audacious - Cross-platform multimedia player
+ * Copyright (C) 2005-2014 Audacious development team.
+ *
+ * Based on BMP:
+ * Copyright (C) 2003-2004 BMP development team.
+ *
+ * Based on XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudgui/libaudgui-gtk.h>
+
+#include "menus.h"
+#include "plugin.h"
+#include "preset-list.h"
+#include "skins_cfg.h"
+#include "ui_equalizer.h"
+#include "ui_main.h"
+#include "ui_skinned_button.h"
+#include "ui_skinned_equalizer_graph.h"
+#include "ui_skinned_equalizer_slider.h"
+#include "ui_skinned_horizontal_slider.h"
+#include "ui_skinned_window.h"
+#include "util.h"
+#include "view.h"
+
+static float equalizerwin_get_preamp (void);
+static float equalizerwin_get_band (int band);
+static void equalizerwin_set_preamp (float preamp);
+static void equalizerwin_set_band (int band, float value);
+
+static void playback_begin_cb (void *, void *);
+
+GtkWidget *equalizerwin;
+GtkWidget *equalizerwin_graph;
+
+static GtkWidget *equalizerwin_on, *equalizerwin_auto;
+
+static GtkWidget *equalizerwin_close, *equalizerwin_shade;
+static GtkWidget *equalizerwin_shaded_close, *equalizerwin_shaded_shade;
+static GtkWidget *equalizerwin_presets;
+static GtkWidget *equalizerwin_preamp,*equalizerwin_bands[10];
+static GtkWidget *equalizerwin_volume, *equalizerwin_balance;
+
+Index<EqualizerPreset> equalizer_presets, equalizer_auto_presets;
+
+static void
+equalizerwin_shade_toggle(void)
+{
+ view_set_equalizer_shaded (! aud_get_bool ("skins", "equalizer_shaded"));
+}
+
+void
+equalizerwin_eq_changed(void)
+{
+ aud_set_double (nullptr, "equalizer_preamp", equalizerwin_get_preamp ());
+
+ double bands[AUD_EQ_NBANDS];
+ for (int i = 0; i < AUD_EQ_NBANDS; i ++)
+ bands[i] = equalizerwin_get_band (i);
+
+ aud_eq_set_bands (bands);
+}
+
+void equalizerwin_apply_preset (const EqualizerPreset & preset)
+{
+ equalizerwin_set_preamp (preset.preamp);
+ for (int i = 0; i < AUD_EQ_NBANDS; i ++)
+ equalizerwin_set_band (i, preset.bands[i]);
+}
+
+void equalizerwin_update_preset (EqualizerPreset & preset)
+{
+ preset.preamp = equalizerwin_get_preamp ();
+ for (int i = 0; i < AUD_EQ_NBANDS; i ++)
+ preset.bands[i] = equalizerwin_get_band (i);
+}
+
+void equalizerwin_import_presets (Index<EqualizerPreset> && presets)
+{
+ equalizer_presets.move_from (presets, 0, -1, -1, true, true);
+ aud_eq_write_presets (equalizer_presets, "eq.preset");
+}
+
+static void eq_on_cb (GtkWidget * button, GdkEventButton * event)
+ {aud_set_bool (nullptr, "equalizer_active", button_get_active (button)); }
+static void eq_auto_cb (GtkWidget * button, GdkEventButton * event)
+ {aud_set_bool (nullptr, "equalizer_autoload", button_get_active (equalizerwin_auto)); }
+
+static void update_from_config (void * unused1, void * unused2)
+{
+ button_set_active (equalizerwin_on, aud_get_bool (nullptr, "equalizer_active"));
+ eq_slider_set_val (equalizerwin_preamp, aud_get_double (nullptr, "equalizer_preamp"));
+
+ double bands[AUD_EQ_NBANDS];
+ aud_eq_get_bands (bands);
+
+ for (int i = 0; i < AUD_EQ_NBANDS; i ++)
+ eq_slider_set_val (equalizerwin_bands[i], bands[i]);
+
+ eq_graph_update (equalizerwin_graph);
+}
+
+static void eq_presets_cb (GtkWidget * button, GdkEventButton * event)
+{
+ menu_popup (UI_MENU_EQUALIZER_PRESET, event->x_root, event->y_root, FALSE,
+ FALSE, event->button, event->time);
+}
+
+static gboolean
+equalizerwin_press(GtkWidget * widget, GdkEventButton * event,
+ void * callback_data)
+{
+ if (event->button == 1 && event->type == GDK_2BUTTON_PRESS &&
+ event->window == gtk_widget_get_window (widget) &&
+ event->y < 14 * config.scale)
+ {
+ equalizerwin_shade_toggle ();
+ return TRUE;
+ }
+
+ if (event->button == 3)
+ {
+ menu_popup (UI_MENU_MAIN, event->x_root, event->y_root, FALSE, FALSE,
+ event->button, event->time);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+equalizerwin_close_cb(void)
+{
+ view_set_show_equalizer (FALSE);
+}
+
+static void eqwin_volume_set_knob (void)
+{
+ int pos = hslider_get_pos (equalizerwin_volume);
+
+ int x;
+ if (pos < 32)
+ x = 1;
+ else if (pos < 63)
+ x = 4;
+ else
+ x = 7;
+
+ hslider_set_knob (equalizerwin_volume, x, 30, x, 30);
+}
+
+void equalizerwin_set_volume_slider (int percent)
+{
+ hslider_set_pos (equalizerwin_volume, (percent * 94 + 50) / 100);
+ eqwin_volume_set_knob ();
+}
+
+static void eqwin_volume_motion_cb (void)
+{
+ eqwin_volume_set_knob ();
+ int pos = hslider_get_pos (equalizerwin_volume);
+ int v = (pos * 100 + 47) / 94;
+
+ mainwin_adjust_volume_motion(v);
+ mainwin_set_volume_slider(v);
+}
+
+static void eqwin_volume_release_cb (void)
+{
+ eqwin_volume_set_knob ();
+ mainwin_adjust_volume_release();
+}
+
+static void eqwin_balance_set_knob (void)
+{
+ int pos = hslider_get_pos (equalizerwin_balance);
+
+ int x;
+ if (pos < 13)
+ x = 11;
+ else if (pos < 26)
+ x = 14;
+ else
+ x = 17;
+
+ hslider_set_knob (equalizerwin_balance, x, 30, x, 30);
+}
+
+void equalizerwin_set_balance_slider (int percent)
+{
+ if (percent > 0)
+ hslider_set_pos (equalizerwin_balance, 19 + (percent * 19 + 50) / 100);
+ else
+ hslider_set_pos (equalizerwin_balance, 19 + (percent * 19 - 50) / 100);
+
+ eqwin_balance_set_knob ();
+}
+
+static void eqwin_balance_motion_cb (void)
+{
+ eqwin_balance_set_knob ();
+ int pos = hslider_get_pos (equalizerwin_balance);
+ pos = aud::min(pos, 38); /* The skin uses a even number of pixels
+ for the balance-slider *sigh* */
+ int b;
+ if (pos > 19)
+ b = ((pos - 19) * 100 + 9) / 19;
+ else
+ b = ((pos - 19) * 100 - 9) / 19;
+
+ mainwin_adjust_balance_motion(b);
+ mainwin_set_balance_slider(b);
+}
+
+static void eqwin_balance_release_cb (void)
+{
+ eqwin_balance_set_knob ();
+ mainwin_adjust_balance_release();
+}
+
+static void
+equalizerwin_create_widgets(void)
+{
+ equalizerwin_on = button_new_toggle (25, 12, 10, 119, 128, 119, 69, 119, 187, 119, SKIN_EQMAIN, SKIN_EQMAIN);
+ window_put_widget (equalizerwin, FALSE, equalizerwin_on, 14, 18);
+ button_set_active (equalizerwin_on, aud_get_bool (nullptr, "equalizer_active"));
+ button_on_release (equalizerwin_on, eq_on_cb);
+
+ equalizerwin_auto = button_new_toggle (33, 12, 35, 119, 153, 119, 94, 119, 212, 119, SKIN_EQMAIN, SKIN_EQMAIN);
+ window_put_widget (equalizerwin, FALSE, equalizerwin_auto, 39, 18);
+ button_set_active (equalizerwin_auto, aud_get_bool (nullptr, "equalizer_autoload"));
+ button_on_release (equalizerwin_auto, eq_auto_cb);
+
+ equalizerwin_presets = button_new (44, 12, 224, 164, 224, 176, SKIN_EQMAIN, SKIN_EQMAIN);
+ window_put_widget (equalizerwin, FALSE, equalizerwin_presets, 217, 18);
+ button_on_release (equalizerwin_presets, eq_presets_cb);
+
+ equalizerwin_close = button_new (9, 9, 0, 116, 0, 125, SKIN_EQMAIN, SKIN_EQMAIN);
+ window_put_widget (equalizerwin, FALSE, equalizerwin_close, 264, 3);
+ button_on_release (equalizerwin_close, (ButtonCB) equalizerwin_close_cb);
+
+ equalizerwin_shade = button_new (9, 9, 254, 137, 1, 38, SKIN_EQMAIN, SKIN_EQ_EX);
+ window_put_widget (equalizerwin, FALSE, equalizerwin_shade, 254, 3);
+ button_on_release (equalizerwin_shade, (ButtonCB) equalizerwin_shade_toggle);
+
+ equalizerwin_shaded_close = button_new (9, 9, 11, 38, 11, 47, SKIN_EQ_EX, SKIN_EQ_EX);
+ window_put_widget (equalizerwin, TRUE, equalizerwin_shaded_close, 264, 3);
+ button_on_release (equalizerwin_shaded_close, (ButtonCB) equalizerwin_close_cb);
+
+ equalizerwin_shaded_shade = button_new (9, 9, 254, 3, 1, 47, SKIN_EQ_EX, SKIN_EQ_EX);
+ window_put_widget (equalizerwin, TRUE, equalizerwin_shaded_shade, 254, 3);
+ button_on_release (equalizerwin_shaded_shade, (ButtonCB) equalizerwin_shade_toggle);
+
+ equalizerwin_graph = eq_graph_new ();
+ gtk_widget_set_no_show_all (equalizerwin_graph, TRUE); // shown or hidden in skin_load()
+ window_put_widget (equalizerwin, FALSE, equalizerwin_graph, 86, 17);
+
+ equalizerwin_preamp = eq_slider_new (_("Preamp"));
+ window_put_widget (equalizerwin, FALSE, equalizerwin_preamp, 21, 38);
+ eq_slider_set_val (equalizerwin_preamp, aud_get_double (nullptr, "equalizer_preamp"));
+
+ const char * const bandnames[AUD_EQ_NBANDS] = {N_("31 Hz"),
+ N_("63 Hz"), N_("125 Hz"), N_("250 Hz"), N_("500 Hz"), N_("1 kHz"),
+ N_("2 kHz"), N_("4 kHz"), N_("8 kHz"), N_("16 kHz")};
+ double bands[AUD_EQ_NBANDS];
+ aud_eq_get_bands (bands);
+
+ for (int i = 0; i < AUD_EQ_NBANDS; i ++)
+ {
+ equalizerwin_bands[i] = eq_slider_new (_(bandnames[i]));
+ window_put_widget (equalizerwin, FALSE, equalizerwin_bands[i], 78 + 18 * i, 38);
+ eq_slider_set_val (equalizerwin_bands[i], bands[i]);
+ }
+
+ equalizerwin_volume = hslider_new (0, 94, SKIN_EQ_EX, 97, 8, 61, 4, 3, 7, 1, 30, 1, 30);
+ window_put_widget (equalizerwin, TRUE, equalizerwin_volume, 61, 4);
+ hslider_on_motion (equalizerwin_volume, eqwin_volume_motion_cb);
+ hslider_on_release (equalizerwin_volume, eqwin_volume_release_cb);
+
+ equalizerwin_balance = hslider_new (0, 39, SKIN_EQ_EX, 42, 8, 164, 4, 3, 7, 11, 30, 11, 30);
+ window_put_widget (equalizerwin, TRUE, equalizerwin_balance, 164, 4);
+ hslider_on_motion (equalizerwin_balance, eqwin_balance_motion_cb);
+ hslider_on_release (equalizerwin_balance, eqwin_balance_release_cb);
+}
+
+static void eq_win_draw (GtkWidget * window, cairo_t * cr)
+{
+ gboolean shaded = aud_get_bool ("skins", "equalizer_shaded");
+
+ skin_draw_pixbuf (cr, SKIN_EQMAIN, 0, 0, 0, 0, 275, shaded ? 14 : 116);
+
+ if (shaded)
+ skin_draw_pixbuf (cr, SKIN_EQ_EX, 0, 0, 0, 0, 275, 14);
+ else
+ skin_draw_pixbuf (cr, SKIN_EQMAIN, 0, 134, 0, 0, 275, 14);
+}
+
+static void
+equalizerwin_create_window(void)
+{
+ gboolean shaded = aud_get_bool ("skins", "equalizer_shaded");
+
+ equalizerwin = window_new (& config.equalizer_x, & config.equalizer_y, 275,
+ shaded ? 14 : 116, FALSE, shaded, eq_win_draw);
+
+ gtk_window_set_title(GTK_WINDOW(equalizerwin), _("Audacious Equalizer"));
+
+ /* this will hide only mainwin. it's annoying! yaz */
+ gtk_window_set_transient_for(GTK_WINDOW(equalizerwin),
+ GTK_WINDOW(mainwin));
+ gtk_window_set_skip_pager_hint(GTK_WINDOW(equalizerwin), TRUE);
+ gtk_window_set_skip_taskbar_hint(GTK_WINDOW(equalizerwin), TRUE);
+
+ gtk_widget_set_app_paintable(equalizerwin, TRUE);
+
+ g_signal_connect (equalizerwin, "delete-event", (GCallback) handle_window_close, nullptr);
+ g_signal_connect (equalizerwin, "button-press-event", (GCallback) equalizerwin_press, nullptr);
+ g_signal_connect (equalizerwin, "key-press-event", (GCallback) mainwin_keypress, nullptr);
+}
+
+static void equalizerwin_destroyed (void)
+{
+ hook_dissociate ("set equalizer_active", (HookFunction) update_from_config);
+ hook_dissociate ("set equalizer_bands", (HookFunction) update_from_config);
+ hook_dissociate ("set equalizer_preamp", (HookFunction) update_from_config);
+
+ hook_dissociate ("playback begin", playback_begin_cb);
+
+ equalizer_presets.clear ();
+ equalizer_auto_presets.clear ();
+}
+
+void
+equalizerwin_create(void)
+{
+ equalizer_presets = aud_eq_read_presets("eq.preset");
+ equalizer_auto_presets = aud_eq_read_presets("eq.auto_preset");
+
+ equalizerwin_create_window();
+
+ gtk_window_add_accel_group ((GtkWindow *) equalizerwin, menu_get_accel_group ());
+
+ equalizerwin_create_widgets();
+ window_show_all (equalizerwin);
+
+ g_signal_connect (equalizerwin, "destroy", (GCallback) equalizerwin_destroyed, nullptr);
+
+ hook_associate ("set equalizer_active", (HookFunction) update_from_config, nullptr);
+ hook_associate ("set equalizer_bands", (HookFunction) update_from_config, nullptr);
+ hook_associate ("set equalizer_preamp", (HookFunction) update_from_config, nullptr);
+
+ /* Load preset for the first song. FIXME: Doing this at interface load is
+ really too late as the song may already be started. Really, this stuff
+ shouldn't be in the interface plugin at all but in core. -jlindgren */
+ if (aud_drct_get_playing ())
+ playback_begin_cb (nullptr, nullptr);
+
+ hook_associate ("playback begin", playback_begin_cb, nullptr);
+}
+
+static int equalizerwin_find_preset (Index<EqualizerPreset> & list, const char * name)
+{
+ for (int p = 0; p < list.len (); p ++)
+ {
+ if (! g_ascii_strcasecmp (list[p].name, name))
+ return p;
+ }
+
+ return -1;
+}
+
+gboolean equalizerwin_load_preset (Index<EqualizerPreset> & list, const char * name)
+{
+ int p = equalizerwin_find_preset (list, name);
+ if (p < 0)
+ return FALSE;
+
+ equalizerwin_apply_preset (list[p]);
+ return TRUE;
+}
+
+void equalizerwin_save_preset (Index<EqualizerPreset> & list, const char * name, const char * filename)
+{
+ int p = equalizerwin_find_preset (list, name);
+
+ if (p < 0)
+ {
+ list.append (String (name));
+ p = list.len () - 1;
+ }
+
+ equalizerwin_update_preset (list[p]);
+
+ aud_eq_write_presets (list, filename);
+}
+
+void equalizerwin_delete_preset (Index<EqualizerPreset> & list, const char * name, const char * filename)
+{
+ int p = equalizerwin_find_preset (list, name);
+ if (p < 0)
+ return;
+
+ list.remove (p, 1);
+ aud_eq_write_presets (list, filename);
+}
+
+static gboolean equalizerwin_read_aud_preset (const char * filename)
+{
+ EqualizerPreset preset;
+
+ VFSFile file (filename, "r");
+ if (! file || ! aud_load_preset_file (preset, file))
+ return FALSE;
+
+ equalizerwin_apply_preset (preset);
+ return TRUE;
+}
+
+static void equalizerwin_set_preamp (float preamp)
+{
+ eq_slider_set_val (equalizerwin_preamp, preamp);
+ equalizerwin_eq_changed();
+}
+
+static void equalizerwin_set_band (int band, float value)
+{
+ g_return_if_fail(band >= 0 && band < AUD_EQ_NBANDS);
+ eq_slider_set_val (equalizerwin_bands[band], value);
+ equalizerwin_eq_changed();
+}
+
+static float equalizerwin_get_preamp (void)
+{
+ return eq_slider_get_val (equalizerwin_preamp);
+}
+
+static float equalizerwin_get_band (int band)
+{
+ g_return_val_if_fail(band >= 0 && band < AUD_EQ_NBANDS, 0.0);
+ return eq_slider_get_val (equalizerwin_bands[band]);
+}
+
+static void load_auto_preset (const char * filename)
+{
+ char * eq_file = g_strconcat (filename, ".", EQUALIZER_DEFAULT_PRESET_EXT, nullptr);
+ gboolean success = equalizerwin_read_aud_preset (eq_file);
+ g_free (eq_file);
+
+ if (success)
+ return;
+
+ char * folder = g_path_get_dirname (filename);
+ eq_file = g_build_filename (folder, EQUALIZER_DEFAULT_DIR_PRESET, nullptr);
+ success = equalizerwin_read_aud_preset (eq_file);
+
+ g_free (folder);
+ g_free (eq_file);
+
+ if (success)
+ return;
+
+ char * base = g_path_get_basename (filename);
+
+ if (! equalizerwin_load_preset (equalizer_auto_presets, base))
+ eq_preset_load_default ();
+
+ g_free (base);
+}
+
+static void playback_begin_cb (void *, void *)
+{
+ if (aud_get_bool (nullptr, "equalizer_autoload"))
+ load_auto_preset (aud_drct_get_filename ());
+}
diff --git a/src/skins/ui_equalizer.h b/src/skins/ui_equalizer.h
index 39e185625ebc..07b40e5252f6 100644
--- a/src/skins/ui_equalizer.h
+++ b/src/skins/ui_equalizer.h
@@ -28,28 +28,27 @@
#include <gtk/gtk.h>
-#include <audacious/types.h>
-#include <libaudcore/index.h>
+#include <libaudcore/equalizer.h>
#define EQUALIZER_DEFAULT_DIR_PRESET "dir_default.preset"
#define EQUALIZER_DEFAULT_PRESET_EXT "preset"
-void equalizerwin_set_shape (void);
void equalizerwin_create(void);
-void equalizerwin_set_volume_slider(gint percent);
-void equalizerwin_set_balance_slider(gint percent);
+void equalizerwin_set_volume_slider(int percent);
+void equalizerwin_set_balance_slider(int percent);
void equalizerwin_eq_changed(void);
-void equalizerwin_apply_preset (const EqualizerPreset * preset);
-void equalizerwin_update_preset (EqualizerPreset * preset);
-void equalizerwin_import_presets (Index * presets);
+void equalizerwin_apply_preset (const EqualizerPreset & preset);
+void equalizerwin_update_preset (EqualizerPreset & preset);
+void equalizerwin_import_presets (Index<EqualizerPreset> && presets);
extern GtkWidget *equalizerwin;
+extern GtkWidget *equalizerwin_graph;
-extern Index * equalizer_presets, * equalizer_auto_presets;
+extern Index<EqualizerPreset> equalizer_presets, equalizer_auto_presets;
-bool_t equalizerwin_load_preset (Index * list, const char * name);
-void equalizerwin_save_preset (Index * list, const char * name, const char * filename);
-void equalizerwin_delete_preset (Index * list, const char * name, const char * filename);
+gboolean equalizerwin_load_preset (Index<EqualizerPreset> & list, const char * name);
+void equalizerwin_save_preset (Index<EqualizerPreset> & list, const char * name, const char * filename);
+void equalizerwin_delete_preset (Index<EqualizerPreset> & list, const char * name, const char * filename);
#endif /* SKINS_UI_EQUALIZER_H */
diff --git a/src/skins/ui_main.c b/src/skins/ui_main.c
deleted file mode 100644
index 8126eef36afe..000000000000
--- a/src/skins/ui_main.c
+++ /dev/null
@@ -1,1297 +0,0 @@
-/* Audacious - Cross-platform multimedia player
- * Copyright (C) 2005-2011 Audacious development team.
- *
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- *
- * Based on XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <libaudcore/audstrings.h>
-#include <libaudgui/libaudgui.h>
-
-#include "actions-mainwin.h"
-#include "actions-playlist.h"
-#include "dnd.h"
-#include "menus.h"
-#include "plugin.h"
-#include "skins_cfg.h"
-#include "ui_equalizer.h"
-#include "ui_main.h"
-#include "ui_main_evlisteners.h"
-#include "ui_playlist.h"
-#include "ui_skinned_button.h"
-#include "ui_skinned_horizontal_slider.h"
-#include "ui_skinned_menurow.h"
-#include "ui_skinned_monostereo.h"
-#include "ui_skinned_number.h"
-#include "ui_skinned_playlist.h"
-#include "ui_skinned_playstatus.h"
-#include "ui_skinned_textbox.h"
-#include "ui_skinned_window.h"
-#include "ui_vis.h"
-#include "util.h"
-#include "view.h"
-
-#define SEEK_THRESHOLD 200 /* milliseconds */
-#define SEEK_TIMEOUT 100 /* milliseconds */
-#define SEEK_SPEED 50 /* milliseconds per pixel */
-
-GtkWidget *mainwin = NULL;
-
-static gint balance;
-static gint seek_source = 0, seek_start, seek_time;
-
-static GtkWidget *mainwin_menubtn, *mainwin_minimize, *mainwin_shade, *mainwin_close;
-static GtkWidget *mainwin_shaded_menubtn, *mainwin_shaded_minimize, *mainwin_shaded_shade, *mainwin_shaded_close;
-
-static GtkWidget *mainwin_rew, *mainwin_fwd;
-static GtkWidget *mainwin_eject;
-static GtkWidget *mainwin_play, *mainwin_pause, *mainwin_stop;
-
-GtkWidget *mainwin_shuffle, *mainwin_repeat;
-GtkWidget *mainwin_eq, *mainwin_pl;
-
-GtkWidget *mainwin_info;
-GtkWidget *mainwin_stime_min, *mainwin_stime_sec;
-
-static GtkWidget *mainwin_rate_text, *mainwin_freq_text, *mainwin_othertext;
-
-GtkWidget *mainwin_playstatus;
-
-GtkWidget *mainwin_minus_num, *mainwin_10min_num, *mainwin_min_num;
-GtkWidget *mainwin_10sec_num, *mainwin_sec_num;
-
-GtkWidget *mainwin_vis;
-GtkWidget *mainwin_svis;
-
-GtkWidget *mainwin_sposition = NULL;
-
-GtkWidget *mainwin_menurow;
-static GtkWidget *mainwin_volume, *mainwin_balance;
-GtkWidget *mainwin_position;
-
-static GtkWidget *mainwin_monostereo;
-static GtkWidget *mainwin_srew, *mainwin_splay, *mainwin_spause;
-static GtkWidget *mainwin_sstop, *mainwin_sfwd, *mainwin_seject, *mainwin_about;
-
-static gboolean mainwin_info_text_locked = FALSE;
-static guint mainwin_volume_release_timeout = 0;
-
-static void mainwin_position_motion_cb (void);
-static void mainwin_position_release_cb (void);
-static void mainwin_set_volume_diff (gint diff);
-
-static void format_time (gchar buf[7], gint time, gint length)
-{
- bool_t zero = aud_get_bool (NULL, "leading_zero");
- bool_t remaining = aud_get_bool ("skins", "show_remaining_time");
-
- if (remaining && length > 0)
- {
- time = (length - time) / 1000;
-
- if (time < 60)
- snprintf (buf, 7, zero ? "-00:%02d" : " -0:%02d", time);
- else if (time < 6000)
- snprintf (buf, 7, zero ? "%03d:%02d" : "%3d:%02d", -time / 60, time % 60);
- else
- snprintf (buf, 7, "%3d:%02d", -time / 3600, time / 60 % 60);
- }
- else
- {
- time /= 1000;
-
- if (time < 6000)
- snprintf (buf, 7, zero ? " %02d:%02d" : " %2d:%02d", time / 60, time % 60);
- else if (time < 60000)
- snprintf (buf, 7, "%3d:%02d", time / 60, time % 60);
- else
- snprintf (buf, 7, "%3d:%02d", time / 3600, time / 60 % 60);
- }
-}
-
-void mainwin_set_shape (void)
-{
- int id = aud_get_bool ("skins", "player_shaded") ? SKIN_MASK_MAIN_SHADE : SKIN_MASK_MAIN;
- gtk_widget_shape_combine_region (mainwin, active_skin->masks[id]);
-}
-
-static void
-mainwin_menubtn_cb(void)
-{
- gint x, y;
- gtk_window_get_position(GTK_WINDOW(mainwin), &x, &y);
- menu_popup (UI_MENU_MAIN, x + 6, y + MAINWIN_SHADED_HEIGHT, FALSE, FALSE, 1, GDK_CURRENT_TIME);
-}
-
-static void mainwin_minimize_cb (void)
-{
- if (!mainwin)
- return;
-
- gtk_window_iconify(GTK_WINDOW(mainwin));
-}
-
-static void
-mainwin_shade_toggle(void)
-{
- view_set_player_shaded (! aud_get_bool ("skins", "player_shaded"));
-}
-
-static gchar *mainwin_tb_old_text = NULL;
-
-static void mainwin_lock_info_text (const gchar * text)
-{
- if (mainwin_info_text_locked != TRUE)
- mainwin_tb_old_text = g_strdup
- (active_skin->properties.mainwin_othertext_is_status ?
- textbox_get_text (mainwin_othertext) : textbox_get_text (mainwin_info));
-
- mainwin_info_text_locked = TRUE;
- if (active_skin->properties.mainwin_othertext_is_status)
- textbox_set_text (mainwin_othertext, text);
- else
- textbox_set_text (mainwin_info, text);
-}
-
-static void mainwin_release_info_text (void)
-{
- mainwin_info_text_locked = FALSE;
-
- if (mainwin_tb_old_text != NULL)
- {
- if (active_skin->properties.mainwin_othertext_is_status)
- textbox_set_text (mainwin_othertext, mainwin_tb_old_text);
- else
- textbox_set_text (mainwin_info, mainwin_tb_old_text);
- g_free(mainwin_tb_old_text);
- mainwin_tb_old_text = NULL;
- }
-}
-
-static void mainwin_set_info_text (const gchar * text)
-{
- if (mainwin_info_text_locked)
- {
- g_free (mainwin_tb_old_text);
- mainwin_tb_old_text = g_strdup (text);
- }
- else
- textbox_set_text (mainwin_info, text);
-}
-
-static gint status_message_source = 0;
-
-static gboolean clear_status_message (void * unused)
-{
- mainwin_release_info_text ();
- status_message_source = 0;
- return FALSE;
-}
-
-void mainwin_show_status_message (const gchar * message)
-{
- if (status_message_source)
- g_source_remove (status_message_source);
-
- mainwin_lock_info_text (message);
- status_message_source = g_timeout_add (1000, clear_status_message, NULL);
-}
-
-static gchar *
-make_mainwin_title(const gchar * title)
-{
- if (title != NULL)
- return g_strdup_printf(_("%s - Audacious"), title);
- else
- return g_strdup(_("Audacious"));
-}
-
-void
-mainwin_set_song_title(const gchar * title)
-{
- gchar *mainwin_title_text = make_mainwin_title(title);
- gtk_window_set_title(GTK_WINDOW(mainwin), mainwin_title_text);
- g_free(mainwin_title_text);
-
- mainwin_set_info_text (title ? title : "");
-}
-
-static void setup_widget (GtkWidget * widget, gint x, gint y, gboolean show)
-{
- /* leave no-show-all widgets alone (they are shown/hidden elsewhere) */
- if (! gtk_widget_get_no_show_all (widget))
- {
- int width, height;
-
- /* use get_size_request(), not get_preferred_size() */
- /* get_preferred_size() will return 0x0 for hidden widgets */
- gtk_widget_get_size_request (widget, & width, & height);
-
- /* hide widgets that are outside the window boundary */
- if (x < 0 || x + width > active_skin->properties.mainwin_width ||
- y < 0 || y + height > active_skin->properties.mainwin_height)
- show = FALSE;
-
- gtk_widget_set_visible (widget, show);
- }
-
- window_move_widget (mainwin, FALSE, widget, x, y);
-}
-
-void mainwin_refresh_hints (void)
-{
- const SkinProperties * p = & active_skin->properties;
-
- gtk_widget_set_visible (mainwin_menurow, p->mainwin_menurow_visible);
- gtk_widget_set_visible (mainwin_rate_text, p->mainwin_streaminfo_visible);
- gtk_widget_set_visible (mainwin_freq_text, p->mainwin_streaminfo_visible);
- gtk_widget_set_visible (mainwin_monostereo, p->mainwin_streaminfo_visible);
-
- textbox_set_width (mainwin_info, p->mainwin_text_width);
-
- setup_widget (mainwin_vis, p->mainwin_vis_x, p->mainwin_vis_y, p->mainwin_vis_visible);
- setup_widget (mainwin_info, p->mainwin_text_x, p->mainwin_text_y, p->mainwin_text_visible);
- setup_widget (mainwin_othertext, p->mainwin_infobar_x, p->mainwin_infobar_y, p->mainwin_othertext_visible);
-
- setup_widget (mainwin_minus_num, p->mainwin_number_0_x, p->mainwin_number_0_y, TRUE);
- setup_widget (mainwin_10min_num, p->mainwin_number_1_x, p->mainwin_number_1_y, TRUE);
- setup_widget (mainwin_min_num, p->mainwin_number_2_x, p->mainwin_number_2_y, TRUE);
- setup_widget (mainwin_10sec_num, p->mainwin_number_3_x, p->mainwin_number_3_y, TRUE);
- setup_widget (mainwin_sec_num, p->mainwin_number_4_x, p->mainwin_number_4_y, TRUE);
- setup_widget (mainwin_position, p->mainwin_position_x, p->mainwin_position_y, TRUE);
-
- setup_widget (mainwin_playstatus, p->mainwin_playstatus_x, p->mainwin_playstatus_y, TRUE);
- setup_widget (mainwin_volume, p->mainwin_volume_x, p->mainwin_volume_y, TRUE);
- setup_widget (mainwin_balance, p->mainwin_balance_x, p->mainwin_balance_y, TRUE);
- setup_widget (mainwin_rew, p->mainwin_previous_x, p->mainwin_previous_y, TRUE);
- setup_widget (mainwin_play, p->mainwin_play_x, p->mainwin_play_y, TRUE);
- setup_widget (mainwin_pause, p->mainwin_pause_x, p->mainwin_pause_y, TRUE);
- setup_widget (mainwin_stop, p->mainwin_stop_x, p->mainwin_stop_y, TRUE);
- setup_widget (mainwin_fwd, p->mainwin_next_x, p->mainwin_next_y, TRUE);
- setup_widget (mainwin_eject, p->mainwin_eject_x, p->mainwin_eject_y, TRUE);
- setup_widget (mainwin_eq, p->mainwin_eqbutton_x, p->mainwin_eqbutton_y, TRUE);
- setup_widget (mainwin_pl, p->mainwin_plbutton_x, p->mainwin_plbutton_y, TRUE);
- setup_widget (mainwin_shuffle, p->mainwin_shuffle_x, p->mainwin_shuffle_y, TRUE);
- setup_widget (mainwin_repeat, p->mainwin_repeat_x, p->mainwin_repeat_y, TRUE);
- setup_widget (mainwin_about, p->mainwin_about_x, p->mainwin_about_y, TRUE);
- setup_widget (mainwin_minimize, p->mainwin_minimize_x, p->mainwin_minimize_y, TRUE);
- setup_widget (mainwin_shade, p->mainwin_shade_x, p->mainwin_shade_y, TRUE);
- setup_widget (mainwin_close, p->mainwin_close_x, p->mainwin_close_y, TRUE);
-
- if (aud_get_bool ("skins", "player_shaded"))
- window_set_size (mainwin, MAINWIN_SHADED_WIDTH, MAINWIN_SHADED_HEIGHT);
- else
- window_set_size (mainwin, p->mainwin_width, p->mainwin_height);
-}
-
-/* note that the song info is not translated since it is displayed using
- * the skinned bitmap font, which supports only the English alphabet */
-void mainwin_set_song_info (gint bitrate, gint samplerate, gint channels)
-{
- gchar scratch[32];
- gint length;
-
- if (bitrate > 0)
- {
- if (bitrate < 1000000)
- snprintf (scratch, sizeof scratch, "%3d", bitrate / 1000);
- else
- snprintf (scratch, sizeof scratch, "%2dH", bitrate / 100000);
-
- textbox_set_text (mainwin_rate_text, scratch);
- }
- else
- textbox_set_text (mainwin_rate_text, "");
-
- if (samplerate > 0)
- {
- snprintf (scratch, sizeof scratch, "%2d", samplerate / 1000);
- textbox_set_text (mainwin_freq_text, scratch);
- }
- else
- textbox_set_text (mainwin_freq_text, "");
-
- ui_skinned_monostereo_set_num_channels (mainwin_monostereo, channels);
-
- if (bitrate > 0)
- snprintf (scratch, sizeof scratch, "%d kbps", bitrate / 1000);
- else
- scratch[0] = 0;
-
- if (samplerate > 0)
- {
- length = strlen (scratch);
- snprintf (scratch + length, sizeof scratch - length, "%s%d kHz", length ?
- ", " : "", samplerate / 1000);
- }
-
- if (channels > 0)
- {
- length = strlen (scratch);
- snprintf (scratch + length, sizeof scratch - length, "%s%s", length ?
- ", " : "", channels > 2 ? "surround" : channels > 1 ? "stereo" : "mono");
- }
-
- textbox_set_text (mainwin_othertext, scratch);
-}
-
-void
-mainwin_clear_song_info(void)
-{
- mainwin_set_song_title (NULL);
-
- ui_vis_clear_data (mainwin_vis);
- ui_svis_clear_data (mainwin_svis);
-
- gtk_widget_hide (mainwin_minus_num);
- gtk_widget_hide (mainwin_10min_num);
- gtk_widget_hide (mainwin_min_num);
- gtk_widget_hide (mainwin_10sec_num);
- gtk_widget_hide (mainwin_sec_num);
- gtk_widget_hide (mainwin_stime_min);
- gtk_widget_hide (mainwin_stime_sec);
- gtk_widget_hide (mainwin_position);
- gtk_widget_hide (mainwin_sposition);
-
- hslider_set_pressed (mainwin_position, FALSE);
- hslider_set_pressed (mainwin_sposition, FALSE);
-
- /* clear sampling parameter displays */
- textbox_set_text (mainwin_rate_text, " ");
- textbox_set_text (mainwin_freq_text, " ");
- ui_skinned_monostereo_set_num_channels(mainwin_monostereo, 0);
- textbox_set_text (mainwin_othertext, "");
-
- if (mainwin_playstatus != NULL)
- ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_STOP);
-
- playlistwin_hide_timer();
-}
-
-void
-mainwin_disable_seekbar(void)
-{
- if (!mainwin)
- return;
-
- gtk_widget_hide(mainwin_position);
- gtk_widget_hide(mainwin_sposition);
-}
-
-static void mainwin_scrolled (GtkWidget * widget, GdkEventScroll * event, void *
- unused)
-{
- switch (event->direction) {
- case GDK_SCROLL_UP:
- mainwin_set_volume_diff (5);
- break;
- case GDK_SCROLL_DOWN:
- mainwin_set_volume_diff (-5);
- break;
- case GDK_SCROLL_LEFT:
- aud_drct_seek (aud_drct_get_time () - 5000);
- break;
- case GDK_SCROLL_RIGHT:
- aud_drct_seek (aud_drct_get_time () + 5000);
- break;
- default:
- break;
- }
-}
-
-static gboolean
-mainwin_mouse_button_press(GtkWidget * widget,
- GdkEventButton * event,
- gpointer callback_data)
-{
- if (event->button == 1 && event->type == GDK_2BUTTON_PRESS &&
- event->window == gtk_widget_get_window (widget) && event->y < 14)
- {
- mainwin_shade_toggle ();
- return TRUE;
- }
-
- if (event->button == 3)
- {
- menu_popup (UI_MENU_MAIN, event->x_root, event->y_root, FALSE, FALSE,
- event->button, event->time);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void mainwin_playback_rpress (GtkWidget * button, GdkEventButton * event)
-{
- menu_popup (UI_MENU_PLAYBACK, event->x_root, event->y_root, FALSE, FALSE,
- event->button, event->time);
-}
-
-gboolean mainwin_keypress (GtkWidget * widget, GdkEventKey * event,
- void * unused)
-{
- if (ui_skinned_playlist_key (playlistwin_list, event))
- return 1;
-
- switch (event->keyval)
- {
- case GDK_KEY_minus:
- mainwin_set_volume_diff (-5);
- break;
- case GDK_KEY_plus:
- mainwin_set_volume_diff (5);
- break;
- case GDK_KEY_Left:
- case GDK_KEY_KP_Left:
- case GDK_KEY_KP_7:
- aud_drct_seek (aud_drct_get_time () - 5000);
- break;
- case GDK_KEY_Right:
- case GDK_KEY_KP_Right:
- case GDK_KEY_KP_9:
- aud_drct_seek (aud_drct_get_time () + 5000);
- break;
- case GDK_KEY_KP_4:
- aud_drct_pl_prev ();
- break;
- case GDK_KEY_KP_6:
- aud_drct_pl_next ();
- break;
- case GDK_KEY_KP_Insert:
- audgui_jump_to_track ();
- break;
- case GDK_KEY_space:
- aud_drct_pause();
- break;
- case GDK_KEY_Tab: /* GtkUIManager does not handle tab, apparently. */
- if (event->state & GDK_SHIFT_MASK)
- action_playlist_prev ();
- else
- action_playlist_next ();
-
- break;
- case GDK_KEY_ISO_Left_Tab:
- action_playlist_prev ();
- break;
- default:
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*
- * Rewritten 09/13/06:
- *
- * Remove all of this flaky iter/sourcelist/strsplit stuff.
- * All we care about is the filepath.
- *
- * We can figure this out and easily pass it to g_filename_from_uri().
- * - nenolod
- */
-void
-mainwin_drag_data_received(GtkWidget * widget,
- GdkDragContext * context,
- gint x,
- gint y,
- GtkSelectionData * selection_data,
- guint info,
- guint time,
- gpointer user_data)
-{
- g_return_if_fail(selection_data != NULL);
-
- const gchar * data = (const gchar *) gtk_selection_data_get_data
- (selection_data);
- g_return_if_fail (data);
-
- if (str_has_prefix_nocase (data, "file:///"))
- {
- if (str_has_suffix_nocase (data, ".wsz\r\n") || str_has_suffix_nocase
- (data, ".zip\r\n"))
- {
- on_skin_view_drag_data_received (0, context, x, y, selection_data, info, time, 0);
- return;
- }
- }
-
- audgui_urilist_open (data);
-}
-
-static gint time_now (void)
-{
- struct timeval tv;
- gettimeofday (& tv, NULL);
- return (tv.tv_sec % (24 * 3600) * 1000 + tv.tv_usec / 1000);
-}
-
-static gint time_diff (gint a, gint b)
-{
- if (a > 18 * 3600 * 1000 && b < 6 * 3600 * 1000) /* detect midnight */
- b += 24 * 3600 * 1000;
- return (b > a) ? b - a : 0;
-}
-
-static gboolean seek_timeout (void * rewind)
-{
- if (! aud_drct_get_playing ())
- {
- seek_source = 0;
- return FALSE;
- }
-
- gint held = time_diff (seek_time, time_now ());
- if (held < SEEK_THRESHOLD)
- return TRUE;
-
- gint position;
- if (GPOINTER_TO_INT (rewind))
- position = seek_start - held / SEEK_SPEED;
- else
- position = seek_start + held / SEEK_SPEED;
-
- position = CLAMP (position, 0, 219);
- hslider_set_pos (mainwin_position, position);
- mainwin_position_motion_cb ();
-
- return TRUE;
-}
-
-static gboolean seek_press (GtkWidget * widget, GdkEventButton * event,
- gboolean rewind)
-{
- if (event->button != 1 || seek_source)
- return FALSE;
-
- seek_start = hslider_get_pos (mainwin_position);
- seek_time = time_now ();
- seek_source = g_timeout_add (SEEK_TIMEOUT, seek_timeout, GINT_TO_POINTER
- (rewind));
- return FALSE;
-}
-
-static gboolean seek_release (GtkWidget * widget, GdkEventButton * event,
- gboolean rewind)
-{
- if (event->button != 1 || ! seek_source)
- return FALSE;
-
- if (! aud_drct_get_playing () || time_diff (seek_time, time_now ()) <
- SEEK_THRESHOLD)
- {
- if (rewind)
- aud_drct_pl_prev ();
- else
- aud_drct_pl_next ();
- }
- else
- mainwin_position_release_cb ();
-
- g_source_remove (seek_source);
- seek_source = 0;
- return FALSE;
-}
-
-static void mainwin_rew_press (GtkWidget * button, GdkEventButton * event)
- {seek_press (button, event, TRUE); }
-static void mainwin_rew_release (GtkWidget * button, GdkEventButton * event)
- {seek_release (button, event, TRUE); }
-static void mainwin_fwd_press (GtkWidget * button, GdkEventButton * event)
- {seek_press (button, event, FALSE); }
-static void mainwin_fwd_release (GtkWidget * button, GdkEventButton * event)
- {seek_release (button, event, FALSE); }
-
-static void mainwin_shuffle_cb (GtkWidget * button, GdkEventButton * event)
- {aud_set_bool (NULL, "shuffle", button_get_active (button)); }
-static void mainwin_repeat_cb (GtkWidget * button, GdkEventButton * event)
- {aud_set_bool (NULL, "repeat", button_get_active (button)); }
-static void mainwin_eq_cb (GtkWidget * button, GdkEventButton * event)
- {view_set_show_equalizer (button_get_active (button)); }
-static void mainwin_pl_cb (GtkWidget * button, GdkEventButton * event)
- {view_set_show_playlist (button_get_active (button)); }
-
-static void mainwin_spos_set_knob (void)
-{
- gint pos = hslider_get_pos (mainwin_sposition);
-
- gint x;
- if (pos < 6)
- x = 17;
- else if (pos < 9)
- x = 20;
- else
- x = 23;
-
- hslider_set_knob (mainwin_sposition, x, 36, x, 36);
-}
-
-static void mainwin_spos_motion_cb (void)
-{
- mainwin_spos_set_knob ();
-
- gint pos = hslider_get_pos (mainwin_sposition);
- gint length = aud_drct_get_length ();
- gint time = (pos - 1) * length / 12;
-
- gchar buf[7];
- format_time (buf, time, length);
-
- textbox_set_text (mainwin_stime_min, buf);
- textbox_set_text (mainwin_stime_sec, buf + 4);
-}
-
-static void mainwin_spos_release_cb (void)
-{
- mainwin_spos_set_knob ();
-
- gint pos = hslider_get_pos (mainwin_sposition);
- aud_drct_seek (aud_drct_get_length () * (pos - 1) / 12);
-}
-
-static void mainwin_position_motion_cb (void)
-{
- gint length = aud_drct_get_length () / 1000;
- gint pos = hslider_get_pos (mainwin_position);
- gint time = pos * length / 219;
-
- gchar * seek_msg = g_strdup_printf (_("Seek to %d:%-2.2d / %d:%-2.2d"), time
- / 60, time % 60, length / 60, length % 60);
- mainwin_lock_info_text(seek_msg);
- g_free(seek_msg);
-}
-
-static void mainwin_position_release_cb (void)
-{
- gint length = aud_drct_get_length ();
- gint pos = hslider_get_pos (mainwin_position);
- gint time = (gint64) pos * length / 219;
-
- aud_drct_seek(time);
- mainwin_release_info_text();
-}
-
-void
-mainwin_adjust_volume_motion(gint v)
-{
- gchar *volume_msg;
-
- volume_msg = g_strdup_printf(_("Volume: %d%%"), v);
- mainwin_lock_info_text(volume_msg);
- g_free(volume_msg);
-
- aud_drct_set_volume_main (v);
- aud_drct_set_volume_balance (balance);
-}
-
-void
-mainwin_adjust_volume_release(void)
-{
- mainwin_release_info_text();
-}
-
-void
-mainwin_adjust_balance_motion(gint b)
-{
- gchar *balance_msg;
-
- balance = b;
- aud_drct_set_volume_balance (b);
-
- if (b < 0)
- balance_msg = g_strdup_printf(_("Balance: %d%% left"), -b);
- else if (b == 0)
- balance_msg = g_strdup_printf(_("Balance: center"));
- else
- balance_msg = g_strdup_printf(_("Balance: %d%% right"), b);
-
- mainwin_lock_info_text(balance_msg);
- g_free(balance_msg);
-}
-
-void
-mainwin_adjust_balance_release(void)
-{
- mainwin_release_info_text();
-}
-
-static void mainwin_volume_set_frame (void)
-{
- gint pos = hslider_get_pos (mainwin_volume);
- gint frame = (pos * 27 + 25) / 51;
- hslider_set_frame (mainwin_volume, 0, 15 * frame);
-}
-
-void mainwin_set_volume_slider (gint percent)
-{
- hslider_set_pos (mainwin_volume, (percent * 51 + 50) / 100);
- mainwin_volume_set_frame ();
-}
-
-static void mainwin_volume_motion_cb (void)
-{
- mainwin_volume_set_frame ();
- gint pos = hslider_get_pos (mainwin_volume);
- gint vol = (pos * 100 + 25) / 51;
-
- mainwin_adjust_volume_motion(vol);
- equalizerwin_set_volume_slider(vol);
-}
-
-static void mainwin_volume_release_cb (void)
-{
- mainwin_volume_set_frame ();
- mainwin_adjust_volume_release();
-}
-
-static void mainwin_balance_set_frame (void)
-{
- gint pos = hslider_get_pos (mainwin_balance);
- gint frame = (abs (pos - 12) * 27 + 6) / 12;
- hslider_set_frame (mainwin_balance, 9, 15 * frame);
-}
-
-void mainwin_set_balance_slider (gint percent)
-{
- if (percent > 0)
- hslider_set_pos (mainwin_balance, 12 + (percent * 12 + 50) / 100);
- else
- hslider_set_pos (mainwin_balance, 12 + (percent * 12 - 50) / 100);
-
- mainwin_balance_set_frame ();
-}
-
-static void mainwin_balance_motion_cb (void)
-{
- mainwin_balance_set_frame ();
- gint pos = hslider_get_pos (mainwin_balance);
-
- gint bal;
- if (pos > 12)
- bal = ((pos - 12) * 100 + 6) / 12;
- else
- bal = ((pos - 12) * 100 - 6) / 12;
-
- mainwin_adjust_balance_motion(bal);
- equalizerwin_set_balance_slider(bal);
-}
-
-static void mainwin_balance_release_cb (void)
-{
- mainwin_balance_set_frame ();
- mainwin_adjust_volume_release();
-}
-
-static void mainwin_set_volume_diff (gint diff)
-{
- gint vol;
-
- aud_drct_get_volume_main (& vol);
- vol = CLAMP (vol + diff, 0, 100);
- mainwin_adjust_volume_motion(vol);
- mainwin_set_volume_slider(vol);
- equalizerwin_set_volume_slider(vol);
-
- if (mainwin_volume_release_timeout)
- g_source_remove(mainwin_volume_release_timeout);
- mainwin_volume_release_timeout =
- g_timeout_add(700, (GSourceFunc)(mainwin_volume_release_cb), NULL);
-}
-
-void mainwin_mr_change (MenuRowItem i)
-{
- switch (i) {
- case MENUROW_OPTIONS:
- mainwin_lock_info_text(_("Options Menu"));
- break;
- case MENUROW_ALWAYS:
- if (aud_get_bool ("skins", "always_on_top"))
- mainwin_lock_info_text(_("Disable 'Always On Top'"));
- else
- mainwin_lock_info_text(_("Enable 'Always On Top'"));
- break;
- case MENUROW_FILEINFOBOX:
- mainwin_lock_info_text(_("File Info Box"));
- break;
- default:
- break;
- }
-}
-
-void mainwin_mr_release (MenuRowItem i, GdkEventButton * event)
-{
- switch (i) {
- case MENUROW_OPTIONS:
- menu_popup (UI_MENU_VIEW, event->x_root, event->y_root, FALSE, FALSE, 1, event->time);
- break;
- case MENUROW_ALWAYS:
- view_set_on_top (! aud_get_bool ("skins", "always_on_top"));
- break;
- case MENUROW_FILEINFOBOX:
- audgui_infowin_show_current ();
- break;
- default:
- break;
- }
-
- mainwin_release_info_text();
-}
-
-gboolean
-change_timer_mode_cb(GtkWidget *widget, GdkEventButton *event)
-{
- if (event->button == 1)
- view_set_show_remaining (! aud_get_bool ("skins", "show_remaining_time"));
- else if (event->button == 3)
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean mainwin_info_button_press (GtkWidget * widget, GdkEventButton *
- event)
-{
- if (event->type == GDK_BUTTON_PRESS && event->button == 3)
- {
- menu_popup (UI_MENU_PLAYBACK, event->x_root, event->y_root, FALSE,
- FALSE, event->button, event->time);
- return TRUE;
- }
-
- if (event->type == GDK_2BUTTON_PRESS && event->button == 1)
- {
- audgui_infowin_show_current ();
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-mainwin_create_widgets(void)
-{
- mainwin_menubtn = button_new (9, 9, 0, 0, 0, 9, SKIN_TITLEBAR, SKIN_TITLEBAR);
- window_put_widget (mainwin, FALSE, mainwin_menubtn, 6, 3);
- button_on_release (mainwin_menubtn, (ButtonCB) mainwin_menubtn_cb);
-
- mainwin_minimize = button_new (9, 9, 9, 0, 9, 9, SKIN_TITLEBAR, SKIN_TITLEBAR);
- window_put_widget (mainwin, FALSE, mainwin_minimize, 244, 3);
- button_on_release (mainwin_minimize, (ButtonCB) mainwin_minimize_cb);
-
- mainwin_shade = button_new (9, 9, 0, 18, 9, 18, SKIN_TITLEBAR, SKIN_TITLEBAR);
- window_put_widget (mainwin, FALSE, mainwin_shade, 254, 3);
- button_on_release (mainwin_shade, (ButtonCB) mainwin_shade_toggle);
-
- mainwin_close = button_new (9, 9, 18, 0, 18, 9, SKIN_TITLEBAR, SKIN_TITLEBAR);
- window_put_widget (mainwin, FALSE, mainwin_close, 264, 3);
- button_on_release (mainwin_close, (ButtonCB) handle_window_close);
-
- mainwin_rew = button_new (23, 18, 0, 0, 0, 18, SKIN_CBUTTONS, SKIN_CBUTTONS);
- window_put_widget (mainwin, FALSE, mainwin_rew, 16, 88);
- button_on_press (mainwin_rew, mainwin_rew_press);
- button_on_release (mainwin_rew, mainwin_rew_release);
- button_on_rpress (mainwin_rew, mainwin_playback_rpress);
-
- mainwin_fwd = button_new (22, 18, 92, 0, 92, 18, SKIN_CBUTTONS, SKIN_CBUTTONS);
- window_put_widget (mainwin, FALSE, mainwin_fwd, 108, 88);
- button_on_press (mainwin_fwd, mainwin_fwd_press);
- button_on_release (mainwin_fwd, mainwin_fwd_release);
- button_on_rpress (mainwin_fwd, mainwin_playback_rpress);
-
- mainwin_play = button_new (23, 18, 23, 0, 23, 18, SKIN_CBUTTONS, SKIN_CBUTTONS);
- window_put_widget (mainwin, FALSE, mainwin_play, 39, 88);
- button_on_release (mainwin_play, (ButtonCB) aud_drct_play);
- button_on_rpress (mainwin_play, mainwin_playback_rpress);
-
- mainwin_pause = button_new (23, 18, 46, 0, 46, 18, SKIN_CBUTTONS, SKIN_CBUTTONS);
- window_put_widget (mainwin, FALSE, mainwin_pause, 62, 88);
- button_on_release (mainwin_pause, (ButtonCB) aud_drct_pause);
- button_on_rpress (mainwin_pause, mainwin_playback_rpress);
-
- mainwin_stop = button_new (23, 18, 69, 0, 69, 18, SKIN_CBUTTONS, SKIN_CBUTTONS);
- window_put_widget (mainwin, FALSE, mainwin_stop, 85, 88);
- button_on_release (mainwin_stop, (ButtonCB) aud_drct_stop);
- button_on_rpress (mainwin_stop, mainwin_playback_rpress);
-
- mainwin_eject = button_new (22, 16, 114, 0, 114, 16, SKIN_CBUTTONS, SKIN_CBUTTONS);
- window_put_widget (mainwin, FALSE, mainwin_eject, 136, 89);
- button_on_release (mainwin_eject, (ButtonCB) action_play_file);
-
- mainwin_shuffle = button_new_toggle (46, 15, 28, 0, 28, 15, 28, 30, 28, 45, SKIN_SHUFREP, SKIN_SHUFREP);
- window_put_widget (mainwin, FALSE, mainwin_shuffle, 164, 89);
- button_set_active (mainwin_shuffle, aud_get_bool (NULL, "shuffle"));
- button_on_release (mainwin_shuffle, mainwin_shuffle_cb);
-
- mainwin_repeat = button_new_toggle (28, 15, 0, 0, 0, 15, 0, 30, 0, 45, SKIN_SHUFREP, SKIN_SHUFREP);
- window_put_widget (mainwin, FALSE, mainwin_repeat, 210, 89);
- button_set_active (mainwin_repeat, aud_get_bool (NULL, "repeat"));
- button_on_release (mainwin_repeat, mainwin_repeat_cb);
-
- mainwin_eq = button_new_toggle (23, 12, 0, 61, 46, 61, 0, 73, 46, 73, SKIN_SHUFREP, SKIN_SHUFREP);
- window_put_widget (mainwin, FALSE, mainwin_eq, 219, 58);
- button_on_release (mainwin_eq, mainwin_eq_cb);
-
- mainwin_pl = button_new_toggle (23, 12, 23, 61, 69, 61, 23, 73, 69, 73, SKIN_SHUFREP, SKIN_SHUFREP);
- window_put_widget (mainwin, FALSE, mainwin_pl, 242, 58);
- button_on_release (mainwin_pl, mainwin_pl_cb);
-
- char * font = aud_get_str ("skins", "mainwin_font");
- mainwin_info = textbox_new (153, "", config.mainwin_use_bitmapfont ? NULL :
- font, config.autoscroll);
- str_unref (font);
-
- window_put_widget (mainwin, FALSE, mainwin_info, 112, 27);
- g_signal_connect (mainwin_info, "button-press-event", (GCallback)
- mainwin_info_button_press, NULL);
-
- mainwin_othertext = textbox_new (153, "", NULL, FALSE);
- window_put_widget (mainwin, FALSE, mainwin_othertext, 112, 43);
-
- mainwin_rate_text = textbox_new (15, "", NULL, FALSE);
- window_put_widget (mainwin, FALSE, mainwin_rate_text, 111, 43);
-
- mainwin_freq_text = textbox_new (10, "", NULL, FALSE);
- window_put_widget (mainwin, FALSE, mainwin_freq_text, 156, 43);
-
- mainwin_menurow = ui_skinned_menurow_new ();
- window_put_widget (mainwin, FALSE, mainwin_menurow, 10, 22);
-
- mainwin_volume = hslider_new (0, 51, SKIN_VOLUME, 68, 13, 0, 0, 14, 11, 15, 422, 0, 422);
- window_put_widget (mainwin, FALSE, mainwin_volume, 107, 57);
- hslider_on_motion (mainwin_volume, mainwin_volume_motion_cb);
- hslider_on_release (mainwin_volume, mainwin_volume_release_cb);
-
- mainwin_balance = hslider_new (0, 24, SKIN_BALANCE, 38, 13, 9, 0, 14, 11, 15, 422, 0, 422);
- window_put_widget (mainwin, FALSE, mainwin_balance, 177, 57);
- hslider_on_motion (mainwin_balance, mainwin_balance_motion_cb);
- hslider_on_release (mainwin_balance, mainwin_balance_release_cb);
-
- mainwin_monostereo = ui_skinned_monostereo_new ();
- window_put_widget (mainwin, FALSE, mainwin_monostereo, 212, 41);
-
- mainwin_playstatus = ui_skinned_playstatus_new ();
- window_put_widget (mainwin, FALSE, mainwin_playstatus, 24, 28);
-
- mainwin_minus_num = ui_skinned_number_new ();
- window_put_widget (mainwin, FALSE, mainwin_minus_num, 36, 26);
- g_signal_connect(mainwin_minus_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
- mainwin_10min_num = ui_skinned_number_new ();
- window_put_widget (mainwin, FALSE, mainwin_10min_num, 48, 26);
- g_signal_connect(mainwin_10min_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
- mainwin_min_num = ui_skinned_number_new ();
- window_put_widget (mainwin, FALSE, mainwin_min_num, 60, 26);
- g_signal_connect(mainwin_min_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
- mainwin_10sec_num = ui_skinned_number_new ();
- window_put_widget (mainwin, FALSE, mainwin_10sec_num, 78, 26);
- g_signal_connect(mainwin_10sec_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
- mainwin_sec_num = ui_skinned_number_new ();
- window_put_widget (mainwin, FALSE, mainwin_sec_num, 90, 26);
- g_signal_connect(mainwin_sec_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
- mainwin_about = button_new_small (20, 25);
- window_put_widget (mainwin, FALSE, mainwin_about, 247, 83);
- button_on_release (mainwin_about, (ButtonCB) audgui_show_about_window);
-
- mainwin_vis = ui_vis_new ();
- window_put_widget (mainwin, FALSE, mainwin_vis, 24, 43);
-
- mainwin_position = hslider_new (0, 219, SKIN_POSBAR, 248, 10, 0, 0, 29, 10, 248, 0, 278, 0);
- window_put_widget (mainwin, FALSE, mainwin_position, 16, 72);
- hslider_on_motion (mainwin_position, mainwin_position_motion_cb);
- hslider_on_release (mainwin_position, mainwin_position_release_cb);
-
- /* shaded */
-
- mainwin_shaded_menubtn = button_new (9, 9, 0, 0, 0, 9, SKIN_TITLEBAR, SKIN_TITLEBAR);
- window_put_widget (mainwin, TRUE, mainwin_shaded_menubtn, 6, 3);
- button_on_release (mainwin_shaded_menubtn, (ButtonCB) mainwin_menubtn_cb);
-
- mainwin_shaded_minimize = button_new (9, 9, 9, 0, 9, 9, SKIN_TITLEBAR, SKIN_TITLEBAR);
- window_put_widget (mainwin, TRUE, mainwin_shaded_minimize, 244, 3);
- button_on_release (mainwin_shaded_minimize, (ButtonCB) mainwin_minimize_cb);
-
- mainwin_shaded_shade = button_new (9, 9, 0, 27, 9, 27, SKIN_TITLEBAR, SKIN_TITLEBAR);
- window_put_widget (mainwin, TRUE, mainwin_shaded_shade, 254, 3);
- button_on_release (mainwin_shaded_shade, (ButtonCB) mainwin_shade_toggle);
-
- mainwin_shaded_close = button_new (9, 9, 18, 0, 18, 9, SKIN_TITLEBAR, SKIN_TITLEBAR);
- window_put_widget (mainwin, TRUE, mainwin_shaded_close, 264, 3);
- button_on_release (mainwin_shaded_close, (ButtonCB) handle_window_close);
-
- mainwin_srew = button_new_small (8, 7);
- window_put_widget (mainwin, TRUE, mainwin_srew, 169, 4);
- button_on_release (mainwin_srew, (ButtonCB) aud_drct_pl_prev);
-
- mainwin_splay = button_new_small (10, 7);
- window_put_widget (mainwin, TRUE, mainwin_splay, 177, 4);
- button_on_release (mainwin_splay, (ButtonCB) aud_drct_play);
-
- mainwin_spause = button_new_small (10, 7);
- window_put_widget (mainwin, TRUE, mainwin_spause, 187, 4);
- button_on_release (mainwin_spause, (ButtonCB) aud_drct_pause);
-
- mainwin_sstop = button_new_small (9, 7);
- window_put_widget (mainwin, TRUE, mainwin_sstop, 197, 4);
- button_on_release (mainwin_sstop, (ButtonCB) aud_drct_stop);
-
- mainwin_sfwd = button_new_small (8, 7);
- window_put_widget (mainwin, TRUE, mainwin_sfwd, 206, 4);
- button_on_release (mainwin_sfwd, (ButtonCB) aud_drct_pl_next);
-
- mainwin_seject = button_new_small (9, 7);
- window_put_widget (mainwin, TRUE, mainwin_seject, 216, 4);
- button_on_release (mainwin_seject, (ButtonCB) action_play_file);
-
- mainwin_svis = ui_svis_new ();
- window_put_widget (mainwin, TRUE, mainwin_svis, 79, 5);
-
- mainwin_sposition = hslider_new (1, 13, SKIN_TITLEBAR, 17, 7, 0, 36, 3, 7, 17, 36, 17, 36);
- window_put_widget (mainwin, TRUE, mainwin_sposition, 226, 4);
- hslider_on_motion (mainwin_sposition, mainwin_spos_motion_cb);
- hslider_on_release (mainwin_sposition, mainwin_spos_release_cb);
-
- mainwin_stime_min = textbox_new (15, "", NULL, FALSE);
- window_put_widget (mainwin, TRUE, mainwin_stime_min, 130, 4);
-
- mainwin_stime_sec = textbox_new (10, "", NULL, FALSE);
- window_put_widget (mainwin, TRUE, mainwin_stime_sec, 147, 4);
-
- g_signal_connect(mainwin_stime_min, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
- g_signal_connect(mainwin_stime_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-}
-
-static void show_widgets (void)
-{
- gtk_widget_set_no_show_all (mainwin_minus_num, TRUE);
- gtk_widget_set_no_show_all (mainwin_10min_num, TRUE);
- gtk_widget_set_no_show_all (mainwin_min_num, TRUE);
- gtk_widget_set_no_show_all (mainwin_10sec_num, TRUE);
- gtk_widget_set_no_show_all (mainwin_sec_num, TRUE);
- gtk_widget_set_no_show_all (mainwin_stime_min, TRUE);
- gtk_widget_set_no_show_all (mainwin_stime_sec, TRUE);
- gtk_widget_set_no_show_all (mainwin_position, TRUE);
- gtk_widget_set_no_show_all (mainwin_sposition, TRUE);
-
- window_set_shaded (mainwin, aud_get_bool ("skins", "player_shaded"));
- window_show_all (mainwin);
-}
-
-static gboolean state_cb (GtkWidget * widget, GdkEventWindowState * event,
- void * unused)
-{
- if (event->changed_mask & GDK_WINDOW_STATE_STICKY)
- view_set_sticky (!! (event->new_window_state & GDK_WINDOW_STATE_STICKY));
-
- if (event->changed_mask & GDK_WINDOW_STATE_ABOVE)
- view_set_on_top (!! (event->new_window_state & GDK_WINDOW_STATE_ABOVE));
-
- return TRUE;
-}
-
-static void mainwin_draw (GtkWidget * window, cairo_t * cr)
-{
- bool_t shaded = aud_get_bool ("skins", "player_shaded");
- int width = shaded ? MAINWIN_SHADED_WIDTH : active_skin->properties.mainwin_width;
- int height = shaded ? MAINWIN_SHADED_HEIGHT : active_skin->properties.mainwin_height;
-
- skin_draw_pixbuf (cr, SKIN_MAIN, 0, 0, 0, 0, width, height);
- skin_draw_mainwin_titlebar (cr, shaded, TRUE);
-}
-
-static void
-mainwin_create_window(void)
-{
- bool_t shaded = aud_get_bool ("skins", "player_shaded");
- int width = shaded ? MAINWIN_SHADED_WIDTH : active_skin->properties.mainwin_width;
- int height = shaded ? MAINWIN_SHADED_HEIGHT : active_skin->properties.mainwin_height;
-
- mainwin = window_new (& config.player_x, & config.player_y, width, height,
- TRUE, shaded, mainwin_draw);
-
- gtk_window_set_title(GTK_WINDOW(mainwin), _("Audacious"));
-
- g_signal_connect(mainwin, "button_press_event",
- G_CALLBACK(mainwin_mouse_button_press), NULL);
- g_signal_connect(mainwin, "scroll_event",
- G_CALLBACK(mainwin_scrolled), NULL);
-
- drag_dest_set(mainwin);
- g_signal_connect ((GObject *) mainwin, "drag-data-received", (GCallback)
- mainwin_drag_data_received, 0);
-
- g_signal_connect(mainwin, "key_press_event",
- G_CALLBACK(mainwin_keypress), NULL);
-
- ui_main_evlistener_init();
-
- g_signal_connect ((GObject *) mainwin, "window-state-event", (GCallback) state_cb, NULL);
- g_signal_connect ((GObject *) mainwin, "delete-event", (GCallback) handle_window_close, NULL);
-}
-
-void mainwin_unhook (void)
-{
- if (seek_source != 0)
- {
- g_source_remove (seek_source);
- seek_source = 0;
- }
-
- ui_main_evlistener_dissociate ();
- start_stop_visual (TRUE);
-}
-
-void
-mainwin_create(void)
-{
- mainwin_create_window();
-
- gtk_window_add_accel_group ((GtkWindow *) mainwin, menu_get_accel_group ());
-
- mainwin_create_widgets();
- show_widgets ();
-}
-
-static void mainwin_update_volume (void)
-{
- gint volume, balance;
-
- aud_drct_get_volume_main (& volume);
- aud_drct_get_volume_balance (& balance);
- mainwin_set_volume_slider (volume);
- mainwin_set_balance_slider (balance);
- equalizerwin_set_volume_slider (volume);
- equalizerwin_set_balance_slider (balance);
-}
-
-static void mainwin_update_time_display (gint time, gint length)
-{
- gchar scratch[7];
- format_time (scratch, time, length);
-
- ui_skinned_number_set (mainwin_minus_num, scratch[0]);
- ui_skinned_number_set (mainwin_10min_num, scratch[1]);
- ui_skinned_number_set (mainwin_min_num, scratch[2]);
- ui_skinned_number_set (mainwin_10sec_num, scratch[4]);
- ui_skinned_number_set (mainwin_sec_num, scratch[5]);
-
- if (! hslider_get_pressed (mainwin_sposition))
- {
- textbox_set_text (mainwin_stime_min, scratch);
- textbox_set_text (mainwin_stime_sec, scratch + 4);
- }
-
- playlistwin_set_time (scratch, scratch + 4);
-}
-
-static void mainwin_update_time_slider (gint time, gint length)
-{
- gtk_widget_set_visible (mainwin_position, length > 0);
- gtk_widget_set_visible (mainwin_sposition, length > 0);
-
- if (length > 0 && seek_source == 0)
- {
- if (time < length)
- {
- hslider_set_pos (mainwin_position, time * (gint64) 219 / length);
- hslider_set_pos (mainwin_sposition, 1 + time * (gint64) 12 / length);
- }
- else
- {
- hslider_set_pos (mainwin_position, 219);
- hslider_set_pos (mainwin_sposition, 13);
- }
-
- mainwin_spos_set_knob ();
- }
-}
-
-void mainwin_update_song_info (void)
-{
- mainwin_update_volume ();
-
- if (! aud_drct_get_playing ())
- return;
-
- gint time = 0, length = 0;
- if (aud_drct_get_ready ())
- {
- time = aud_drct_get_time ();
- length = aud_drct_get_length ();
- }
-
- mainwin_update_time_display (time, length);
- mainwin_update_time_slider (time, length);
-}
-
-/* actionentries actions */
-
-void action_play_file (void)
-{
- audgui_run_filebrowser(TRUE); /* TRUE = PLAY_BUTTON */
-}
-
-void action_play_location (void)
-{
- audgui_show_add_url_window (TRUE);
-}
-
-void action_ab_set (void)
-{
- if (aud_drct_get_length () > 0)
- {
- int a, b;
- aud_drct_get_ab_repeat (& a, & b);
-
- if (a < 0 || b >= 0)
- {
- a = aud_drct_get_time ();
- b = -1;
- mainwin_show_status_message (_("Repeat point A set."));
- }
- else
- {
- b = aud_drct_get_time ();
- mainwin_show_status_message (_("Repeat point B set."));
- }
-
- aud_drct_set_ab_repeat (a, b);
- }
-}
-
-void action_ab_clear (void)
-{
- mainwin_show_status_message (_("Repeat points cleared."));
- aud_drct_set_ab_repeat (-1, -1);
-}
diff --git a/src/skins/ui_main.cc b/src/skins/ui_main.cc
new file mode 100644
index 000000000000..bd878038270f
--- /dev/null
+++ b/src/skins/ui_main.cc
@@ -0,0 +1,1352 @@
+/* Audacious - Cross-platform multimedia player
+ * Copyright (C) 2005-2011 Audacious development team.
+ *
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ *
+ * Based on XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugins.h>
+#include <libaudcore/runtime.h>
+#include <libaudgui/libaudgui.h>
+
+#include "actions-mainwin.h"
+#include "actions-playlist.h"
+#include "dnd.h"
+#include "menus.h"
+#include "plugin.h"
+#include "plugin-window.h"
+#include "skins_cfg.h"
+#include "ui_equalizer.h"
+#include "ui_main.h"
+#include "ui_main_evlisteners.h"
+#include "ui_playlist.h"
+#include "ui_skinned_button.h"
+#include "ui_skinned_horizontal_slider.h"
+#include "ui_skinned_menurow.h"
+#include "ui_skinned_monostereo.h"
+#include "ui_skinned_number.h"
+#include "ui_skinned_playlist.h"
+#include "ui_skinned_playstatus.h"
+#include "ui_skinned_textbox.h"
+#include "ui_skinned_window.h"
+#include "ui_vis.h"
+#include "util.h"
+#include "view.h"
+
+#define SEEK_THRESHOLD 200 /* milliseconds */
+#define SEEK_TIMEOUT 100 /* milliseconds */
+#define SEEK_SPEED 50 /* milliseconds per pixel */
+
+GtkWidget *mainwin = nullptr;
+
+static int balance;
+static int seek_source = 0, seek_start, seek_time;
+
+static bool mainwin_info_text_locked = false;
+static String mainwin_tb_old_text;
+
+static int status_message_source = 0;
+static int mainwin_volume_release_timeout = 0;
+
+static GtkWidget *mainwin_menubtn, *mainwin_minimize, *mainwin_shade, *mainwin_close;
+static GtkWidget *mainwin_shaded_menubtn, *mainwin_shaded_minimize, *mainwin_shaded_shade, *mainwin_shaded_close;
+
+static GtkWidget *mainwin_rew, *mainwin_fwd;
+static GtkWidget *mainwin_eject;
+static GtkWidget *mainwin_play, *mainwin_pause, *mainwin_stop;
+
+GtkWidget *mainwin_shuffle, *mainwin_repeat;
+GtkWidget *mainwin_eq, *mainwin_pl;
+
+GtkWidget *mainwin_info;
+GtkWidget *mainwin_stime_min, *mainwin_stime_sec;
+
+static GtkWidget *mainwin_rate_text, *mainwin_freq_text, *mainwin_othertext;
+
+GtkWidget *mainwin_playstatus;
+
+GtkWidget *mainwin_minus_num, *mainwin_10min_num, *mainwin_min_num;
+GtkWidget *mainwin_10sec_num, *mainwin_sec_num;
+
+GtkWidget *mainwin_vis;
+GtkWidget *mainwin_svis;
+
+GtkWidget *mainwin_sposition = nullptr;
+
+GtkWidget *mainwin_menurow;
+static GtkWidget *mainwin_volume, *mainwin_balance;
+GtkWidget *mainwin_position;
+
+static GtkWidget *mainwin_monostereo;
+static GtkWidget *mainwin_srew, *mainwin_splay, *mainwin_spause;
+static GtkWidget *mainwin_sstop, *mainwin_sfwd, *mainwin_seject, *mainwin_about;
+
+static void mainwin_position_motion_cb (void);
+static void mainwin_position_release_cb (void);
+static void mainwin_set_volume_diff (int diff);
+
+static void format_time (char buf[7], int time, int length)
+{
+ gboolean zero = aud_get_bool (nullptr, "leading_zero");
+ gboolean remaining = aud_get_bool ("skins", "show_remaining_time");
+
+ if (remaining && length > 0)
+ {
+ time = (length - time) / 1000;
+
+ if (time < 60)
+ snprintf (buf, 7, zero ? "-00:%02d" : " -0:%02d", time);
+ else if (time < 6000)
+ snprintf (buf, 7, zero ? "%03d:%02d" : "%3d:%02d", -time / 60, time % 60);
+ else
+ snprintf (buf, 7, "%3d:%02d", -time / 3600, time / 60 % 60);
+ }
+ else
+ {
+ time /= 1000;
+
+ if (time < 6000)
+ snprintf (buf, 7, zero ? " %02d:%02d" : " %2d:%02d", time / 60, time % 60);
+ else if (time < 60000)
+ snprintf (buf, 7, "%3d:%02d", time / 60, time % 60);
+ else
+ snprintf (buf, 7, "%3d:%02d", time / 3600, time / 60 % 60);
+ }
+}
+
+static void
+mainwin_menubtn_cb(void)
+{
+ int x, y;
+ gtk_window_get_position(GTK_WINDOW(mainwin), &x, &y);
+ menu_popup (UI_MENU_MAIN, x + 6 * config.scale,
+ y + MAINWIN_SHADED_HEIGHT * config.scale, FALSE, FALSE, 1, GDK_CURRENT_TIME);
+}
+
+static void mainwin_minimize_cb (void)
+{
+ if (!mainwin)
+ return;
+
+ gtk_window_iconify(GTK_WINDOW(mainwin));
+}
+
+static void
+mainwin_shade_toggle(void)
+{
+ view_set_player_shaded (! aud_get_bool ("skins", "player_shaded"));
+}
+
+static void mainwin_lock_info_text (const char * text)
+{
+ GtkWidget * textbox =
+ active_skin->properties.mainwin_othertext_is_status ?
+ mainwin_othertext : mainwin_info;
+
+ if (! mainwin_info_text_locked)
+ mainwin_tb_old_text = String (textbox_get_text (textbox));
+
+ mainwin_info_text_locked = true;
+ textbox_set_text (textbox, text);
+}
+
+static void mainwin_release_info_text (void)
+{
+ if (! mainwin_info_text_locked)
+ return;
+
+ if (active_skin->properties.mainwin_othertext_is_status)
+ textbox_set_text (mainwin_othertext, mainwin_tb_old_text);
+ else
+ textbox_set_text (mainwin_info, mainwin_tb_old_text);
+
+ mainwin_info_text_locked = false;
+ mainwin_tb_old_text = String ();
+}
+
+static void mainwin_set_info_text (const char * text)
+{
+ if (mainwin_info_text_locked && ! active_skin->properties.mainwin_othertext_is_status)
+ mainwin_tb_old_text = String (text);
+ else
+ textbox_set_text (mainwin_info, text);
+}
+
+static void mainwin_set_othertext (const char * text)
+{
+ if (mainwin_info_text_locked && active_skin->properties.mainwin_othertext_is_status)
+ mainwin_tb_old_text = String (text);
+ else
+ textbox_set_text (mainwin_othertext, text);
+}
+
+static gboolean clear_status_message (void *)
+{
+ mainwin_release_info_text ();
+ status_message_source = 0;
+ return G_SOURCE_REMOVE;
+}
+
+void mainwin_show_status_message (const char * message)
+{
+ if (status_message_source)
+ g_source_remove (status_message_source);
+
+ mainwin_lock_info_text (message);
+ status_message_source = g_timeout_add (1000, clear_status_message, nullptr);
+}
+
+static char *
+make_mainwin_title(const char * title)
+{
+ if (title != nullptr)
+ return g_strdup_printf(_("%s - Audacious"), title);
+ else
+ return g_strdup(_("Audacious"));
+}
+
+void
+mainwin_set_song_title(const char * title)
+{
+ char *mainwin_title_text = make_mainwin_title(title);
+ gtk_window_set_title(GTK_WINDOW(mainwin), mainwin_title_text);
+ g_free(mainwin_title_text);
+
+ mainwin_set_info_text (title ? title : "");
+}
+
+static void setup_widget (GtkWidget * widget, int x, int y, gboolean show)
+{
+ /* leave no-show-all widgets alone (they are shown/hidden elsewhere) */
+ if (! gtk_widget_get_no_show_all (widget))
+ {
+ int width, height;
+
+ /* use get_size_request(), not get_preferred_size() */
+ /* get_preferred_size() will return 0x0 for hidden widgets */
+ gtk_widget_get_size_request (widget, & width, & height);
+
+ width /= config.scale;
+ height /= config.scale;
+
+ /* hide widgets that are outside the window boundary */
+ if (x < 0 || x + width > active_skin->properties.mainwin_width ||
+ y < 0 || y + height > active_skin->properties.mainwin_height)
+ show = FALSE;
+
+ gtk_widget_set_visible (widget, show);
+ }
+
+ window_move_widget (mainwin, FALSE, widget, x, y);
+}
+
+void mainwin_refresh_hints (void)
+{
+ const SkinProperties * p = & active_skin->properties;
+
+ gtk_widget_set_visible (mainwin_menurow, p->mainwin_menurow_visible);
+ gtk_widget_set_visible (mainwin_rate_text, p->mainwin_streaminfo_visible);
+ gtk_widget_set_visible (mainwin_freq_text, p->mainwin_streaminfo_visible);
+ gtk_widget_set_visible (mainwin_monostereo, p->mainwin_streaminfo_visible);
+
+ textbox_set_width (mainwin_info, p->mainwin_text_width);
+
+ setup_widget (mainwin_vis, p->mainwin_vis_x, p->mainwin_vis_y, p->mainwin_vis_visible);
+ setup_widget (mainwin_info, p->mainwin_text_x, p->mainwin_text_y, p->mainwin_text_visible);
+ setup_widget (mainwin_othertext, p->mainwin_infobar_x, p->mainwin_infobar_y, p->mainwin_othertext_visible);
+
+ setup_widget (mainwin_minus_num, p->mainwin_number_0_x, p->mainwin_number_0_y, TRUE);
+ setup_widget (mainwin_10min_num, p->mainwin_number_1_x, p->mainwin_number_1_y, TRUE);
+ setup_widget (mainwin_min_num, p->mainwin_number_2_x, p->mainwin_number_2_y, TRUE);
+ setup_widget (mainwin_10sec_num, p->mainwin_number_3_x, p->mainwin_number_3_y, TRUE);
+ setup_widget (mainwin_sec_num, p->mainwin_number_4_x, p->mainwin_number_4_y, TRUE);
+ setup_widget (mainwin_position, p->mainwin_position_x, p->mainwin_position_y, TRUE);
+
+ setup_widget (mainwin_playstatus, p->mainwin_playstatus_x, p->mainwin_playstatus_y, TRUE);
+ setup_widget (mainwin_volume, p->mainwin_volume_x, p->mainwin_volume_y, TRUE);
+ setup_widget (mainwin_balance, p->mainwin_balance_x, p->mainwin_balance_y, TRUE);
+ setup_widget (mainwin_rew, p->mainwin_previous_x, p->mainwin_previous_y, TRUE);
+ setup_widget (mainwin_play, p->mainwin_play_x, p->mainwin_play_y, TRUE);
+ setup_widget (mainwin_pause, p->mainwin_pause_x, p->mainwin_pause_y, TRUE);
+ setup_widget (mainwin_stop, p->mainwin_stop_x, p->mainwin_stop_y, TRUE);
+ setup_widget (mainwin_fwd, p->mainwin_next_x, p->mainwin_next_y, TRUE);
+ setup_widget (mainwin_eject, p->mainwin_eject_x, p->mainwin_eject_y, TRUE);
+ setup_widget (mainwin_eq, p->mainwin_eqbutton_x, p->mainwin_eqbutton_y, TRUE);
+ setup_widget (mainwin_pl, p->mainwin_plbutton_x, p->mainwin_plbutton_y, TRUE);
+ setup_widget (mainwin_shuffle, p->mainwin_shuffle_x, p->mainwin_shuffle_y, TRUE);
+ setup_widget (mainwin_repeat, p->mainwin_repeat_x, p->mainwin_repeat_y, TRUE);
+ setup_widget (mainwin_about, p->mainwin_about_x, p->mainwin_about_y, TRUE);
+ setup_widget (mainwin_minimize, p->mainwin_minimize_x, p->mainwin_minimize_y, TRUE);
+ setup_widget (mainwin_shade, p->mainwin_shade_x, p->mainwin_shade_y, TRUE);
+ setup_widget (mainwin_close, p->mainwin_close_x, p->mainwin_close_y, TRUE);
+
+ if (aud_get_bool ("skins", "player_shaded"))
+ window_set_size (mainwin, MAINWIN_SHADED_WIDTH, MAINWIN_SHADED_HEIGHT);
+ else
+ window_set_size (mainwin, p->mainwin_width, p->mainwin_height);
+}
+
+/* note that the song info is not translated since it is displayed using
+ * the skinned bitmap font, which supports only the English alphabet */
+void mainwin_set_song_info (int bitrate, int samplerate, int channels)
+{
+ char scratch[32];
+ int length;
+
+ if (bitrate > 0)
+ {
+ if (bitrate < 1000000)
+ snprintf (scratch, sizeof scratch, "%3d", bitrate / 1000);
+ else
+ snprintf (scratch, sizeof scratch, "%2dH", bitrate / 100000);
+
+ textbox_set_text (mainwin_rate_text, scratch);
+ }
+ else
+ textbox_set_text (mainwin_rate_text, "");
+
+ if (samplerate > 0)
+ {
+ snprintf (scratch, sizeof scratch, "%2d", samplerate / 1000);
+ textbox_set_text (mainwin_freq_text, scratch);
+ }
+ else
+ textbox_set_text (mainwin_freq_text, "");
+
+ ui_skinned_monostereo_set_num_channels (mainwin_monostereo, channels);
+
+ if (bitrate > 0)
+ snprintf (scratch, sizeof scratch, "%d kbps", bitrate / 1000);
+ else
+ scratch[0] = 0;
+
+ if (samplerate > 0)
+ {
+ length = strlen (scratch);
+ snprintf (scratch + length, sizeof scratch - length, "%s%d kHz", length ?
+ ", " : "", samplerate / 1000);
+ }
+
+ if (channels > 0)
+ {
+ length = strlen (scratch);
+ snprintf (scratch + length, sizeof scratch - length, "%s%s", length ?
+ ", " : "", channels > 2 ? "surround" : channels > 1 ? "stereo" : "mono");
+ }
+
+ mainwin_set_othertext (scratch);
+}
+
+void
+mainwin_clear_song_info(void)
+{
+ mainwin_set_song_title (nullptr);
+
+ ui_vis_clear_data (mainwin_vis);
+ ui_svis_clear_data (mainwin_svis);
+
+ gtk_widget_hide (mainwin_minus_num);
+ gtk_widget_hide (mainwin_10min_num);
+ gtk_widget_hide (mainwin_min_num);
+ gtk_widget_hide (mainwin_10sec_num);
+ gtk_widget_hide (mainwin_sec_num);
+ gtk_widget_hide (mainwin_stime_min);
+ gtk_widget_hide (mainwin_stime_sec);
+ gtk_widget_hide (mainwin_position);
+ gtk_widget_hide (mainwin_sposition);
+
+ hslider_set_pressed (mainwin_position, FALSE);
+ hslider_set_pressed (mainwin_sposition, FALSE);
+
+ /* clear sampling parameter displays */
+ textbox_set_text (mainwin_rate_text, " ");
+ textbox_set_text (mainwin_freq_text, " ");
+ ui_skinned_monostereo_set_num_channels(mainwin_monostereo, 0);
+ mainwin_set_othertext ("");
+
+ if (mainwin_playstatus != nullptr)
+ ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_STOP);
+
+ playlistwin_hide_timer();
+}
+
+void
+mainwin_disable_seekbar(void)
+{
+ if (!mainwin)
+ return;
+
+ gtk_widget_hide(mainwin_position);
+ gtk_widget_hide(mainwin_sposition);
+}
+
+static void mainwin_scrolled (GtkWidget * widget, GdkEventScroll * event, void *
+ unused)
+{
+ switch (event->direction) {
+ case GDK_SCROLL_UP:
+ mainwin_set_volume_diff (5);
+ break;
+ case GDK_SCROLL_DOWN:
+ mainwin_set_volume_diff (-5);
+ break;
+ case GDK_SCROLL_LEFT:
+ aud_drct_seek (aud_drct_get_time () - 5000);
+ break;
+ case GDK_SCROLL_RIGHT:
+ aud_drct_seek (aud_drct_get_time () + 5000);
+ break;
+ default:
+ break;
+ }
+}
+
+static gboolean
+mainwin_mouse_button_press(GtkWidget * widget,
+ GdkEventButton * event,
+ void * callback_data)
+{
+ if (event->button == 1 && event->type == GDK_2BUTTON_PRESS &&
+ event->window == gtk_widget_get_window (widget)&&
+ event->y < 14 * config.scale)
+ {
+ mainwin_shade_toggle ();
+ return TRUE;
+ }
+
+ if (event->button == 3)
+ {
+ menu_popup (UI_MENU_MAIN, event->x_root, event->y_root, FALSE, FALSE,
+ event->button, event->time);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void mainwin_playback_rpress (GtkWidget * button, GdkEventButton * event)
+{
+ menu_popup (UI_MENU_PLAYBACK, event->x_root, event->y_root, FALSE, FALSE,
+ event->button, event->time);
+}
+
+gboolean mainwin_keypress (GtkWidget * widget, GdkEventKey * event,
+ void * unused)
+{
+ if (ui_skinned_playlist_key (playlistwin_list, event))
+ return 1;
+
+ switch (event->keyval)
+ {
+ case GDK_KEY_minus:
+ mainwin_set_volume_diff (-5);
+ break;
+ case GDK_KEY_plus:
+ mainwin_set_volume_diff (5);
+ break;
+ case GDK_KEY_Left:
+ case GDK_KEY_KP_Left:
+ case GDK_KEY_KP_7:
+ aud_drct_seek (aud_drct_get_time () - 5000);
+ break;
+ case GDK_KEY_Right:
+ case GDK_KEY_KP_Right:
+ case GDK_KEY_KP_9:
+ aud_drct_seek (aud_drct_get_time () + 5000);
+ break;
+ case GDK_KEY_KP_4:
+ aud_drct_pl_prev ();
+ break;
+ case GDK_KEY_KP_6:
+ aud_drct_pl_next ();
+ break;
+ case GDK_KEY_KP_Insert:
+ audgui_jump_to_track ();
+ break;
+ case GDK_KEY_space:
+ aud_drct_pause();
+ break;
+ case GDK_KEY_Tab: /* GtkUIManager does not handle tab, apparently. */
+ if (event->state & GDK_SHIFT_MASK)
+ action_playlist_prev ();
+ else
+ action_playlist_next ();
+
+ break;
+ case GDK_KEY_ISO_Left_Tab:
+ action_playlist_prev ();
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Rewritten 09/13/06:
+ *
+ * Remove all of this flaky iter/sourcelist/strsplit stuff.
+ * All we care about is the filepath.
+ *
+ * We can figure this out and easily pass it to g_filename_from_uri().
+ * - nenolod
+ */
+void
+mainwin_drag_data_received(GtkWidget * widget,
+ GdkDragContext * context,
+ int x,
+ int y,
+ GtkSelectionData * selection_data,
+ unsigned info,
+ unsigned time,
+ void * user_data)
+{
+ g_return_if_fail(selection_data != nullptr);
+
+ const char * data = (const char *) gtk_selection_data_get_data
+ (selection_data);
+ g_return_if_fail (data);
+
+ if (str_has_prefix_nocase (data, "file:///"))
+ {
+ if (str_has_suffix_nocase (data, ".wsz\r\n") || str_has_suffix_nocase
+ (data, ".zip\r\n"))
+ {
+ on_skin_view_drag_data_received (0, context, x, y, selection_data, info, time, 0);
+ return;
+ }
+ }
+
+ audgui_urilist_open (data);
+}
+
+static int time_now (void)
+{
+ struct timeval tv;
+ gettimeofday (& tv, nullptr);
+ return (tv.tv_sec % (24 * 3600) * 1000 + tv.tv_usec / 1000);
+}
+
+static int time_diff (int a, int b)
+{
+ if (a > 18 * 3600 * 1000 && b < 6 * 3600 * 1000) /* detect midnight */
+ b += 24 * 3600 * 1000;
+ return (b > a) ? b - a : 0;
+}
+
+static gboolean seek_timeout (void * rewind)
+{
+ if (! aud_drct_get_playing ())
+ {
+ seek_source = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+ int held = time_diff (seek_time, time_now ());
+ if (held < SEEK_THRESHOLD)
+ return G_SOURCE_CONTINUE;
+
+ int position;
+ if (GPOINTER_TO_INT (rewind))
+ position = seek_start - held / SEEK_SPEED;
+ else
+ position = seek_start + held / SEEK_SPEED;
+
+ position = aud::clamp (position, 0, 219);
+ hslider_set_pos (mainwin_position, position);
+ mainwin_position_motion_cb ();
+
+ return G_SOURCE_CONTINUE;
+}
+
+static gboolean seek_press (GtkWidget * widget, GdkEventButton * event,
+ gboolean rewind)
+{
+ if (event->button != 1 || seek_source)
+ return FALSE;
+
+ seek_start = hslider_get_pos (mainwin_position);
+ seek_time = time_now ();
+ seek_source = g_timeout_add (SEEK_TIMEOUT, seek_timeout, GINT_TO_POINTER (rewind));
+ return FALSE;
+}
+
+static gboolean seek_release (GtkWidget * widget, GdkEventButton * event,
+ gboolean rewind)
+{
+ if (event->button != 1 || ! seek_source)
+ return FALSE;
+
+ if (! aud_drct_get_playing () || time_diff (seek_time, time_now ()) <
+ SEEK_THRESHOLD)
+ {
+ if (rewind)
+ aud_drct_pl_prev ();
+ else
+ aud_drct_pl_next ();
+ }
+ else
+ mainwin_position_release_cb ();
+
+ g_source_remove (seek_source);
+ seek_source = 0;
+ return FALSE;
+}
+
+static void mainwin_rew_press (GtkWidget * button, GdkEventButton * event)
+ {seek_press (button, event, TRUE); }
+static void mainwin_rew_release (GtkWidget * button, GdkEventButton * event)
+ {seek_release (button, event, TRUE); }
+static void mainwin_fwd_press (GtkWidget * button, GdkEventButton * event)
+ {seek_press (button, event, FALSE); }
+static void mainwin_fwd_release (GtkWidget * button, GdkEventButton * event)
+ {seek_release (button, event, FALSE); }
+
+static void mainwin_shuffle_cb (GtkWidget * button, GdkEventButton * event)
+ {aud_set_bool (nullptr, "shuffle", button_get_active (button)); }
+static void mainwin_repeat_cb (GtkWidget * button, GdkEventButton * event)
+ {aud_set_bool (nullptr, "repeat", button_get_active (button)); }
+static void mainwin_eq_cb (GtkWidget * button, GdkEventButton * event)
+ {view_set_show_equalizer (button_get_active (button)); }
+static void mainwin_pl_cb (GtkWidget * button, GdkEventButton * event)
+ {view_set_show_playlist (button_get_active (button)); }
+
+static void mainwin_spos_set_knob (void)
+{
+ int pos = hslider_get_pos (mainwin_sposition);
+
+ int x;
+ if (pos < 6)
+ x = 17;
+ else if (pos < 9)
+ x = 20;
+ else
+ x = 23;
+
+ hslider_set_knob (mainwin_sposition, x, 36, x, 36);
+}
+
+static void mainwin_spos_motion_cb (void)
+{
+ mainwin_spos_set_knob ();
+
+ int pos = hslider_get_pos (mainwin_sposition);
+ int length = aud_drct_get_length ();
+ int time = (pos - 1) * length / 12;
+
+ char buf[7];
+ format_time (buf, time, length);
+
+ textbox_set_text (mainwin_stime_min, buf);
+ textbox_set_text (mainwin_stime_sec, buf + 4);
+}
+
+static void mainwin_spos_release_cb (void)
+{
+ mainwin_spos_set_knob ();
+
+ int pos = hslider_get_pos (mainwin_sposition);
+ aud_drct_seek (aud_drct_get_length () * (pos - 1) / 12);
+}
+
+static void mainwin_position_motion_cb (void)
+{
+ int length = aud_drct_get_length () / 1000;
+ int pos = hslider_get_pos (mainwin_position);
+ int time = pos * length / 219;
+
+ char * seek_msg = g_strdup_printf (_("Seek to %d:%-2.2d / %d:%-2.2d"), time
+ / 60, time % 60, length / 60, length % 60);
+ mainwin_lock_info_text(seek_msg);
+ g_free(seek_msg);
+}
+
+static void mainwin_position_release_cb (void)
+{
+ int length = aud_drct_get_length ();
+ int pos = hslider_get_pos (mainwin_position);
+ int time = (int64_t) pos * length / 219;
+
+ aud_drct_seek(time);
+ mainwin_release_info_text();
+}
+
+void
+mainwin_adjust_volume_motion(int v)
+{
+ char *volume_msg;
+
+ volume_msg = g_strdup_printf(_("Volume: %d%%"), v);
+ mainwin_lock_info_text(volume_msg);
+ g_free(volume_msg);
+
+ aud_drct_set_volume_main (v);
+ aud_drct_set_volume_balance (balance);
+}
+
+void
+mainwin_adjust_volume_release(void)
+{
+ mainwin_release_info_text();
+}
+
+void
+mainwin_adjust_balance_motion(int b)
+{
+ char *balance_msg;
+
+ balance = b;
+ aud_drct_set_volume_balance (b);
+
+ if (b < 0)
+ balance_msg = g_strdup_printf(_("Balance: %d%% left"), -b);
+ else if (b == 0)
+ balance_msg = g_strdup_printf(_("Balance: center"));
+ else
+ balance_msg = g_strdup_printf(_("Balance: %d%% right"), b);
+
+ mainwin_lock_info_text(balance_msg);
+ g_free(balance_msg);
+}
+
+void
+mainwin_adjust_balance_release(void)
+{
+ mainwin_release_info_text();
+}
+
+static void mainwin_volume_set_frame (void)
+{
+ int pos = hslider_get_pos (mainwin_volume);
+ int frame = (pos * 27 + 25) / 51;
+ hslider_set_frame (mainwin_volume, 0, 15 * frame);
+}
+
+void mainwin_set_volume_slider (int percent)
+{
+ hslider_set_pos (mainwin_volume, (percent * 51 + 50) / 100);
+ mainwin_volume_set_frame ();
+}
+
+static void mainwin_volume_motion_cb (void)
+{
+ mainwin_volume_set_frame ();
+ int pos = hslider_get_pos (mainwin_volume);
+ int vol = (pos * 100 + 25) / 51;
+
+ mainwin_adjust_volume_motion(vol);
+ equalizerwin_set_volume_slider(vol);
+}
+
+static void mainwin_volume_release_cb (void)
+{
+ mainwin_volume_set_frame ();
+ mainwin_adjust_volume_release();
+}
+
+static gboolean mainwin_volume_timeout_cb (void *)
+{
+ mainwin_volume_release_cb ();
+ mainwin_volume_release_timeout = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static void mainwin_balance_set_frame (void)
+{
+ int pos = hslider_get_pos (mainwin_balance);
+ int frame = (abs (pos - 12) * 27 + 6) / 12;
+ hslider_set_frame (mainwin_balance, 9, 15 * frame);
+}
+
+void mainwin_set_balance_slider (int percent)
+{
+ if (percent > 0)
+ hslider_set_pos (mainwin_balance, 12 + (percent * 12 + 50) / 100);
+ else
+ hslider_set_pos (mainwin_balance, 12 + (percent * 12 - 50) / 100);
+
+ mainwin_balance_set_frame ();
+}
+
+static void mainwin_balance_motion_cb (void)
+{
+ mainwin_balance_set_frame ();
+ int pos = hslider_get_pos (mainwin_balance);
+
+ int bal;
+ if (pos > 12)
+ bal = ((pos - 12) * 100 + 6) / 12;
+ else
+ bal = ((pos - 12) * 100 - 6) / 12;
+
+ mainwin_adjust_balance_motion(bal);
+ equalizerwin_set_balance_slider(bal);
+}
+
+static void mainwin_balance_release_cb (void)
+{
+ mainwin_balance_set_frame ();
+ mainwin_adjust_volume_release();
+}
+
+static void mainwin_set_volume_diff (int diff)
+{
+ int vol = aud_drct_get_volume_main ();
+
+ vol = aud::clamp (vol + diff, 0, 100);
+ mainwin_adjust_volume_motion(vol);
+ mainwin_set_volume_slider(vol);
+ equalizerwin_set_volume_slider(vol);
+
+ if (mainwin_volume_release_timeout)
+ g_source_remove(mainwin_volume_release_timeout);
+ mainwin_volume_release_timeout =
+ g_timeout_add(700, mainwin_volume_timeout_cb, nullptr);
+}
+
+void mainwin_mr_change (MenuRowItem i)
+{
+ switch (i)
+ {
+ case MENUROW_OPTIONS:
+ mainwin_lock_info_text (_("Options Menu"));
+ break;
+ case MENUROW_ALWAYS:
+ if (aud_get_bool ("skins", "always_on_top"))
+ mainwin_lock_info_text (_("Disable 'Always On Top'"));
+ else
+ mainwin_lock_info_text (_("Enable 'Always On Top'"));
+ break;
+ case MENUROW_FILEINFOBOX:
+ mainwin_lock_info_text (_("File Info Box"));
+ break;
+ case MENUROW_SCALE:
+ mainwin_lock_info_text (_("Double Size"));
+ break;
+ case MENUROW_VISUALIZATION:
+ mainwin_lock_info_text (_("Visualizations"));
+ break;
+ default:
+ break;
+ }
+}
+
+void mainwin_mr_release (MenuRowItem i, GdkEventButton * event)
+{
+ switch (i)
+ {
+ case MENUROW_OPTIONS:
+ menu_popup (UI_MENU_VIEW, event->x_root, event->y_root, FALSE, FALSE, 1, event->time);
+ break;
+ case MENUROW_ALWAYS:
+ view_set_on_top (! aud_get_bool ("skins", "always_on_top"));
+ break;
+ case MENUROW_FILEINFOBOX:
+ audgui_infowin_show_current ();
+ break;
+ case MENUROW_SCALE:
+ view_set_double_size (! aud_get_bool ("skins", "double_size"));
+ break;
+ case MENUROW_VISUALIZATION:
+ audgui_show_prefs_for_plugin_type (PluginType::Vis);
+ break;
+ default:
+ break;
+ }
+
+ mainwin_release_info_text();
+}
+
+gboolean
+change_timer_mode_cb(GtkWidget *widget, GdkEventButton *event)
+{
+ if (event->button == 1)
+ view_set_show_remaining (! aud_get_bool ("skins", "show_remaining_time"));
+ else if (event->button == 3)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean mainwin_info_button_press (GtkWidget * widget, GdkEventButton *
+ event)
+{
+ if (event->type == GDK_BUTTON_PRESS && event->button == 3)
+ {
+ menu_popup (UI_MENU_PLAYBACK, event->x_root, event->y_root, FALSE,
+ FALSE, event->button, event->time);
+ return TRUE;
+ }
+
+ if (event->type == GDK_2BUTTON_PRESS && event->button == 1)
+ {
+ audgui_infowin_show_current ();
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+mainwin_create_widgets(void)
+{
+ mainwin_menubtn = button_new (9, 9, 0, 0, 0, 9, SKIN_TITLEBAR, SKIN_TITLEBAR);
+ window_put_widget (mainwin, FALSE, mainwin_menubtn, 6, 3);
+ button_on_release (mainwin_menubtn, (ButtonCB) mainwin_menubtn_cb);
+
+ mainwin_minimize = button_new (9, 9, 9, 0, 9, 9, SKIN_TITLEBAR, SKIN_TITLEBAR);
+ window_put_widget (mainwin, FALSE, mainwin_minimize, 244, 3);
+ button_on_release (mainwin_minimize, (ButtonCB) mainwin_minimize_cb);
+
+ mainwin_shade = button_new (9, 9, 0, 18, 9, 18, SKIN_TITLEBAR, SKIN_TITLEBAR);
+ window_put_widget (mainwin, FALSE, mainwin_shade, 254, 3);
+ button_on_release (mainwin_shade, (ButtonCB) mainwin_shade_toggle);
+
+ mainwin_close = button_new (9, 9, 18, 0, 18, 9, SKIN_TITLEBAR, SKIN_TITLEBAR);
+ window_put_widget (mainwin, FALSE, mainwin_close, 264, 3);
+ button_on_release (mainwin_close, (ButtonCB) handle_window_close);
+
+ mainwin_rew = button_new (23, 18, 0, 0, 0, 18, SKIN_CBUTTONS, SKIN_CBUTTONS);
+ window_put_widget (mainwin, FALSE, mainwin_rew, 16, 88);
+ button_on_press (mainwin_rew, mainwin_rew_press);
+ button_on_release (mainwin_rew, mainwin_rew_release);
+ button_on_rpress (mainwin_rew, mainwin_playback_rpress);
+
+ mainwin_fwd = button_new (22, 18, 92, 0, 92, 18, SKIN_CBUTTONS, SKIN_CBUTTONS);
+ window_put_widget (mainwin, FALSE, mainwin_fwd, 108, 88);
+ button_on_press (mainwin_fwd, mainwin_fwd_press);
+ button_on_release (mainwin_fwd, mainwin_fwd_release);
+ button_on_rpress (mainwin_fwd, mainwin_playback_rpress);
+
+ mainwin_play = button_new (23, 18, 23, 0, 23, 18, SKIN_CBUTTONS, SKIN_CBUTTONS);
+ window_put_widget (mainwin, FALSE, mainwin_play, 39, 88);
+ button_on_release (mainwin_play, (ButtonCB) aud_drct_play);
+ button_on_rpress (mainwin_play, mainwin_playback_rpress);
+
+ mainwin_pause = button_new (23, 18, 46, 0, 46, 18, SKIN_CBUTTONS, SKIN_CBUTTONS);
+ window_put_widget (mainwin, FALSE, mainwin_pause, 62, 88);
+ button_on_release (mainwin_pause, (ButtonCB) aud_drct_pause);
+ button_on_rpress (mainwin_pause, mainwin_playback_rpress);
+
+ mainwin_stop = button_new (23, 18, 69, 0, 69, 18, SKIN_CBUTTONS, SKIN_CBUTTONS);
+ window_put_widget (mainwin, FALSE, mainwin_stop, 85, 88);
+ button_on_release (mainwin_stop, (ButtonCB) aud_drct_stop);
+ button_on_rpress (mainwin_stop, mainwin_playback_rpress);
+
+ mainwin_eject = button_new (22, 16, 114, 0, 114, 16, SKIN_CBUTTONS, SKIN_CBUTTONS);
+ window_put_widget (mainwin, FALSE, mainwin_eject, 136, 89);
+ button_on_release (mainwin_eject, (ButtonCB) action_play_file);
+
+ mainwin_shuffle = button_new_toggle (46, 15, 28, 0, 28, 15, 28, 30, 28, 45, SKIN_SHUFREP, SKIN_SHUFREP);
+ window_put_widget (mainwin, FALSE, mainwin_shuffle, 164, 89);
+ button_set_active (mainwin_shuffle, aud_get_bool (nullptr, "shuffle"));
+ button_on_release (mainwin_shuffle, mainwin_shuffle_cb);
+
+ mainwin_repeat = button_new_toggle (28, 15, 0, 0, 0, 15, 0, 30, 0, 45, SKIN_SHUFREP, SKIN_SHUFREP);
+ window_put_widget (mainwin, FALSE, mainwin_repeat, 210, 89);
+ button_set_active (mainwin_repeat, aud_get_bool (nullptr, "repeat"));
+ button_on_release (mainwin_repeat, mainwin_repeat_cb);
+
+ mainwin_eq = button_new_toggle (23, 12, 0, 61, 46, 61, 0, 73, 46, 73, SKIN_SHUFREP, SKIN_SHUFREP);
+ window_put_widget (mainwin, FALSE, mainwin_eq, 219, 58);
+ button_on_release (mainwin_eq, mainwin_eq_cb);
+
+ mainwin_pl = button_new_toggle (23, 12, 23, 61, 69, 61, 23, 73, 69, 73, SKIN_SHUFREP, SKIN_SHUFREP);
+ window_put_widget (mainwin, FALSE, mainwin_pl, 242, 58);
+ button_on_release (mainwin_pl, mainwin_pl_cb);
+
+ String font = aud_get_str ("skins", "mainwin_font");
+ mainwin_info = textbox_new (153, "", config.mainwin_use_bitmapfont ? nullptr :
+ (const char *) font, config.autoscroll);
+
+ window_put_widget (mainwin, FALSE, mainwin_info, 112, 27);
+ g_signal_connect (mainwin_info, "button-press-event", (GCallback)
+ mainwin_info_button_press, nullptr);
+
+ mainwin_othertext = textbox_new (153, "", nullptr, FALSE);
+ window_put_widget (mainwin, FALSE, mainwin_othertext, 112, 43);
+
+ mainwin_rate_text = textbox_new (15, "", nullptr, FALSE);
+ window_put_widget (mainwin, FALSE, mainwin_rate_text, 111, 43);
+
+ mainwin_freq_text = textbox_new (10, "", nullptr, FALSE);
+ window_put_widget (mainwin, FALSE, mainwin_freq_text, 156, 43);
+
+ mainwin_menurow = ui_skinned_menurow_new ();
+ window_put_widget (mainwin, FALSE, mainwin_menurow, 10, 22);
+
+ mainwin_volume = hslider_new (0, 51, SKIN_VOLUME, 68, 13, 0, 0, 14, 11, 15, 422, 0, 422);
+ window_put_widget (mainwin, FALSE, mainwin_volume, 107, 57);
+ hslider_on_motion (mainwin_volume, mainwin_volume_motion_cb);
+ hslider_on_release (mainwin_volume, mainwin_volume_release_cb);
+
+ mainwin_balance = hslider_new (0, 24, SKIN_BALANCE, 38, 13, 9, 0, 14, 11, 15, 422, 0, 422);
+ window_put_widget (mainwin, FALSE, mainwin_balance, 177, 57);
+ hslider_on_motion (mainwin_balance, mainwin_balance_motion_cb);
+ hslider_on_release (mainwin_balance, mainwin_balance_release_cb);
+
+ mainwin_monostereo = ui_skinned_monostereo_new ();
+ window_put_widget (mainwin, FALSE, mainwin_monostereo, 212, 41);
+
+ mainwin_playstatus = ui_skinned_playstatus_new ();
+ window_put_widget (mainwin, FALSE, mainwin_playstatus, 24, 28);
+
+ mainwin_minus_num = ui_skinned_number_new ();
+ window_put_widget (mainwin, FALSE, mainwin_minus_num, 36, 26);
+ g_signal_connect(mainwin_minus_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), nullptr);
+
+ mainwin_10min_num = ui_skinned_number_new ();
+ window_put_widget (mainwin, FALSE, mainwin_10min_num, 48, 26);
+ g_signal_connect(mainwin_10min_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), nullptr);
+
+ mainwin_min_num = ui_skinned_number_new ();
+ window_put_widget (mainwin, FALSE, mainwin_min_num, 60, 26);
+ g_signal_connect(mainwin_min_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), nullptr);
+
+ mainwin_10sec_num = ui_skinned_number_new ();
+ window_put_widget (mainwin, FALSE, mainwin_10sec_num, 78, 26);
+ g_signal_connect(mainwin_10sec_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), nullptr);
+
+ mainwin_sec_num = ui_skinned_number_new ();
+ window_put_widget (mainwin, FALSE, mainwin_sec_num, 90, 26);
+ g_signal_connect(mainwin_sec_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), nullptr);
+
+ mainwin_about = button_new_small (20, 25);
+ window_put_widget (mainwin, FALSE, mainwin_about, 247, 83);
+ button_on_release (mainwin_about, (ButtonCB) audgui_show_about_window);
+
+ mainwin_vis = ui_vis_new ();
+ window_put_widget (mainwin, FALSE, mainwin_vis, 24, 43);
+
+ mainwin_position = hslider_new (0, 219, SKIN_POSBAR, 248, 10, 0, 0, 29, 10, 248, 0, 278, 0);
+ window_put_widget (mainwin, FALSE, mainwin_position, 16, 72);
+ hslider_on_motion (mainwin_position, mainwin_position_motion_cb);
+ hslider_on_release (mainwin_position, mainwin_position_release_cb);
+
+ /* shaded */
+
+ mainwin_shaded_menubtn = button_new (9, 9, 0, 0, 0, 9, SKIN_TITLEBAR, SKIN_TITLEBAR);
+ window_put_widget (mainwin, TRUE, mainwin_shaded_menubtn, 6, 3);
+ button_on_release (mainwin_shaded_menubtn, (ButtonCB) mainwin_menubtn_cb);
+
+ mainwin_shaded_minimize = button_new (9, 9, 9, 0, 9, 9, SKIN_TITLEBAR, SKIN_TITLEBAR);
+ window_put_widget (mainwin, TRUE, mainwin_shaded_minimize, 244, 3);
+ button_on_release (mainwin_shaded_minimize, (ButtonCB) mainwin_minimize_cb);
+
+ mainwin_shaded_shade = button_new (9, 9, 0, 27, 9, 27, SKIN_TITLEBAR, SKIN_TITLEBAR);
+ window_put_widget (mainwin, TRUE, mainwin_shaded_shade, 254, 3);
+ button_on_release (mainwin_shaded_shade, (ButtonCB) mainwin_shade_toggle);
+
+ mainwin_shaded_close = button_new (9, 9, 18, 0, 18, 9, SKIN_TITLEBAR, SKIN_TITLEBAR);
+ window_put_widget (mainwin, TRUE, mainwin_shaded_close, 264, 3);
+ button_on_release (mainwin_shaded_close, (ButtonCB) handle_window_close);
+
+ mainwin_srew = button_new_small (8, 7);
+ window_put_widget (mainwin, TRUE, mainwin_srew, 169, 4);
+ button_on_release (mainwin_srew, (ButtonCB) aud_drct_pl_prev);
+
+ mainwin_splay = button_new_small (10, 7);
+ window_put_widget (mainwin, TRUE, mainwin_splay, 177, 4);
+ button_on_release (mainwin_splay, (ButtonCB) aud_drct_play);
+
+ mainwin_spause = button_new_small (10, 7);
+ window_put_widget (mainwin, TRUE, mainwin_spause, 187, 4);
+ button_on_release (mainwin_spause, (ButtonCB) aud_drct_pause);
+
+ mainwin_sstop = button_new_small (9, 7);
+ window_put_widget (mainwin, TRUE, mainwin_sstop, 197, 4);
+ button_on_release (mainwin_sstop, (ButtonCB) aud_drct_stop);
+
+ mainwin_sfwd = button_new_small (8, 7);
+ window_put_widget (mainwin, TRUE, mainwin_sfwd, 206, 4);
+ button_on_release (mainwin_sfwd, (ButtonCB) aud_drct_pl_next);
+
+ mainwin_seject = button_new_small (9, 7);
+ window_put_widget (mainwin, TRUE, mainwin_seject, 216, 4);
+ button_on_release (mainwin_seject, (ButtonCB) action_play_file);
+
+ mainwin_svis = ui_svis_new ();
+ window_put_widget (mainwin, TRUE, mainwin_svis, 79, 5);
+
+ mainwin_sposition = hslider_new (1, 13, SKIN_TITLEBAR, 17, 7, 0, 36, 3, 7, 17, 36, 17, 36);
+ window_put_widget (mainwin, TRUE, mainwin_sposition, 226, 4);
+ hslider_on_motion (mainwin_sposition, mainwin_spos_motion_cb);
+ hslider_on_release (mainwin_sposition, mainwin_spos_release_cb);
+
+ mainwin_stime_min = textbox_new (15, "", nullptr, FALSE);
+ window_put_widget (mainwin, TRUE, mainwin_stime_min, 130, 4);
+
+ mainwin_stime_sec = textbox_new (10, "", nullptr, FALSE);
+ window_put_widget (mainwin, TRUE, mainwin_stime_sec, 147, 4);
+
+ g_signal_connect(mainwin_stime_min, "button-press-event", G_CALLBACK(change_timer_mode_cb), nullptr);
+ g_signal_connect(mainwin_stime_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), nullptr);
+}
+
+static void show_widgets (void)
+{
+ gtk_widget_set_no_show_all (mainwin_minus_num, TRUE);
+ gtk_widget_set_no_show_all (mainwin_10min_num, TRUE);
+ gtk_widget_set_no_show_all (mainwin_min_num, TRUE);
+ gtk_widget_set_no_show_all (mainwin_10sec_num, TRUE);
+ gtk_widget_set_no_show_all (mainwin_sec_num, TRUE);
+ gtk_widget_set_no_show_all (mainwin_stime_min, TRUE);
+ gtk_widget_set_no_show_all (mainwin_stime_sec, TRUE);
+ gtk_widget_set_no_show_all (mainwin_position, TRUE);
+ gtk_widget_set_no_show_all (mainwin_sposition, TRUE);
+
+ window_set_shaded (mainwin, aud_get_bool ("skins", "player_shaded"));
+ window_show_all (mainwin);
+}
+
+static gboolean state_cb (GtkWidget * widget, GdkEventWindowState * event,
+ void * unused)
+{
+ if (event->changed_mask & GDK_WINDOW_STATE_STICKY)
+ view_set_sticky (!! (event->new_window_state & GDK_WINDOW_STATE_STICKY));
+
+ if (event->changed_mask & GDK_WINDOW_STATE_ABOVE)
+ view_set_on_top (!! (event->new_window_state & GDK_WINDOW_STATE_ABOVE));
+
+ return TRUE;
+}
+
+static void mainwin_draw (GtkWidget * window, cairo_t * cr)
+{
+ gboolean shaded = aud_get_bool ("skins", "player_shaded");
+ int width = shaded ? MAINWIN_SHADED_WIDTH : active_skin->properties.mainwin_width;
+ int height = shaded ? MAINWIN_SHADED_HEIGHT : active_skin->properties.mainwin_height;
+
+ skin_draw_pixbuf (cr, SKIN_MAIN, 0, 0, 0, 0, width, height);
+ skin_draw_mainwin_titlebar (cr, shaded, TRUE);
+}
+
+static void
+mainwin_create_window(void)
+{
+ gboolean shaded = aud_get_bool ("skins", "player_shaded");
+ int width = shaded ? MAINWIN_SHADED_WIDTH : active_skin->properties.mainwin_width;
+ int height = shaded ? MAINWIN_SHADED_HEIGHT : active_skin->properties.mainwin_height;
+
+ mainwin = window_new (& config.player_x, & config.player_y, width, height,
+ TRUE, shaded, mainwin_draw);
+
+ gtk_window_set_title(GTK_WINDOW(mainwin), _("Audacious"));
+
+ g_signal_connect(mainwin, "button_press_event",
+ G_CALLBACK(mainwin_mouse_button_press), nullptr);
+ g_signal_connect(mainwin, "scroll_event",
+ G_CALLBACK(mainwin_scrolled), nullptr);
+
+ drag_dest_set(mainwin);
+ g_signal_connect ((GObject *) mainwin, "drag-data-received", (GCallback)
+ mainwin_drag_data_received, 0);
+
+ g_signal_connect(mainwin, "key_press_event",
+ G_CALLBACK(mainwin_keypress), nullptr);
+
+ ui_main_evlistener_init();
+
+ g_signal_connect ((GObject *) mainwin, "window-state-event", (GCallback) state_cb, nullptr);
+ g_signal_connect ((GObject *) mainwin, "delete-event", (GCallback) handle_window_close, nullptr);
+}
+
+void mainwin_unhook (void)
+{
+ if (seek_source)
+ {
+ g_source_remove (seek_source);
+ seek_source = 0;
+ }
+
+ if (status_message_source)
+ {
+ g_source_remove (status_message_source);
+ status_message_source = 0;
+ }
+
+ if (mainwin_volume_release_timeout)
+ {
+ g_source_remove (mainwin_volume_release_timeout);
+ mainwin_volume_release_timeout = 0;
+ }
+
+ ui_main_evlistener_dissociate ();
+ start_stop_visual (TRUE);
+
+ mainwin_info_text_locked = false;
+ mainwin_tb_old_text = String ();
+}
+
+void
+mainwin_create(void)
+{
+ mainwin_create_window();
+
+ gtk_window_add_accel_group ((GtkWindow *) mainwin, menu_get_accel_group ());
+
+ mainwin_create_widgets();
+ show_widgets ();
+}
+
+static void mainwin_update_volume (void)
+{
+ int volume = aud_drct_get_volume_main ();
+ int balance = aud_drct_get_volume_balance ();
+
+ mainwin_set_volume_slider (volume);
+ mainwin_set_balance_slider (balance);
+ equalizerwin_set_volume_slider (volume);
+ equalizerwin_set_balance_slider (balance);
+}
+
+static void mainwin_update_time_display (int time, int length)
+{
+ char scratch[7];
+ format_time (scratch, time, length);
+
+ ui_skinned_number_set (mainwin_minus_num, scratch[0]);
+ ui_skinned_number_set (mainwin_10min_num, scratch[1]);
+ ui_skinned_number_set (mainwin_min_num, scratch[2]);
+ ui_skinned_number_set (mainwin_10sec_num, scratch[4]);
+ ui_skinned_number_set (mainwin_sec_num, scratch[5]);
+
+ if (! hslider_get_pressed (mainwin_sposition))
+ {
+ textbox_set_text (mainwin_stime_min, scratch);
+ textbox_set_text (mainwin_stime_sec, scratch + 4);
+ }
+
+ playlistwin_set_time (scratch, scratch + 4);
+}
+
+static void mainwin_update_time_slider (int time, int length)
+{
+ gtk_widget_set_visible (mainwin_position, length > 0);
+ gtk_widget_set_visible (mainwin_sposition, length > 0);
+
+ if (length > 0 && seek_source == 0)
+ {
+ if (time < length)
+ {
+ hslider_set_pos (mainwin_position, time * (int64_t) 219 / length);
+ hslider_set_pos (mainwin_sposition, 1 + time * (int64_t) 12 / length);
+ }
+ else
+ {
+ hslider_set_pos (mainwin_position, 219);
+ hslider_set_pos (mainwin_sposition, 13);
+ }
+
+ mainwin_spos_set_knob ();
+ }
+}
+
+void mainwin_update_song_info (void)
+{
+ mainwin_update_volume ();
+
+ if (! aud_drct_get_playing ())
+ return;
+
+ int time = 0, length = 0;
+ if (aud_drct_get_ready ())
+ {
+ time = aud_drct_get_time ();
+ length = aud_drct_get_length ();
+ }
+
+ mainwin_update_time_display (time, length);
+ mainwin_update_time_slider (time, length);
+}
+
+/* actionentries actions */
+
+void action_play_file (void)
+{
+ audgui_run_filebrowser(TRUE); /* TRUE = PLAY_BUTTON */
+}
+
+void action_play_location (void)
+{
+ audgui_show_add_url_window (TRUE);
+}
+
+void action_playlist_manager (void)
+{
+ PluginHandle * manager = aud_plugin_lookup_basename ("playlist-manager");
+ if (manager)
+ {
+ aud_plugin_enable (manager, true);
+ focus_plugin_window (manager);
+ }
+}
+
+void action_search_tool (void)
+{
+ PluginHandle * search = aud_plugin_lookup_basename ("search-tool");
+ if (search)
+ {
+ aud_plugin_enable (search, true);
+ focus_plugin_window (search);
+ }
+}
+
+void action_ab_set (void)
+{
+ if (aud_drct_get_length () > 0)
+ {
+ int a, b;
+ aud_drct_get_ab_repeat (a, b);
+
+ if (a < 0 || b >= 0)
+ {
+ a = aud_drct_get_time ();
+ b = -1;
+ mainwin_show_status_message (_("Repeat point A set."));
+ }
+ else
+ {
+ b = aud_drct_get_time ();
+ mainwin_show_status_message (_("Repeat point B set."));
+ }
+
+ aud_drct_set_ab_repeat (a, b);
+ }
+}
+
+void action_ab_clear (void)
+{
+ mainwin_show_status_message (_("Repeat points cleared."));
+ aud_drct_set_ab_repeat (-1, -1);
+}
diff --git a/src/skins/ui_main.h b/src/skins/ui_main.h
index ab34404dd7dd..e194eeecc361 100644
--- a/src/skins/ui_main.h
+++ b/src/skins/ui_main.h
@@ -26,9 +26,9 @@
#include <gtk/gtk.h>
/* yes, main window size is fixed */
-#define MAINWIN_WIDTH (gint)275
-#define MAINWIN_HEIGHT (gint)116
-#define MAINWIN_TITLEBAR_HEIGHT (gint)14
+#define MAINWIN_WIDTH (int)275
+#define MAINWIN_HEIGHT (int)116
+#define MAINWIN_TITLEBAR_HEIGHT (int)14
#define MAINWIN_SHADED_WIDTH MAINWIN_WIDTH
#define MAINWIN_SHADED_HEIGHT MAINWIN_TITLEBAR_HEIGHT
@@ -54,33 +54,31 @@ extern GtkWidget *mainwin_position, *mainwin_sposition;
void mainwin_create(void);
void mainwin_unhook (void);
-void mainwin_adjust_volume_motion(gint v);
+void mainwin_adjust_volume_motion(int v);
void mainwin_adjust_volume_release(void);
-void mainwin_adjust_balance_motion(gint b);
+void mainwin_adjust_balance_motion(int b);
void mainwin_adjust_balance_release(void);
-void mainwin_set_volume_slider(gint percent);
-void mainwin_set_balance_slider(gint percent);
+void mainwin_set_volume_slider(int percent);
+void mainwin_set_balance_slider(int percent);
void mainwin_refresh_hints(void);
-void mainwin_set_song_title (const gchar * title);
-void mainwin_set_song_info(gint rate, gint freq, gint nch);
+void mainwin_set_song_title (const char * title);
+void mainwin_set_song_info(int rate, int freq, int nch);
void mainwin_clear_song_info(void);
-void mainwin_set_shape (void);
-
void mainwin_disable_seekbar(void);
void mainwin_update_song_info (void);
-void mainwin_show_status_message (const gchar * message);
+void mainwin_show_status_message (const char * message);
void mainwin_drag_data_received(GtkWidget * widget,
GdkDragContext * context,
- gint x,
- gint y,
+ int x,
+ int y,
GtkSelectionData * selection_data,
- guint info,
- guint time,
- gpointer user_data);
+ unsigned info,
+ unsigned time,
+ void * user_data);
gboolean change_timer_mode_cb(GtkWidget *widget, GdkEventButton *event);
diff --git a/src/skins/ui_main_evlisteners.c b/src/skins/ui_main_evlisteners.c
deleted file mode 100644
index c7d5b2e41b2d..000000000000
--- a/src/skins/ui_main_evlisteners.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Audacious
- * Copyright (c) 2006-2007 Audacious development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <math.h>
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <libaudcore/hook.h>
-
-#include "skins_cfg.h"
-#include "ui_main.h"
-#include "ui_main_evlisteners.h"
-#include "ui_skin.h"
-#include "ui_skinned_button.h"
-#include "ui_skinned_playstatus.h"
-#include "ui_vis.h"
-#include "util.h"
-
-static void title_change (void)
-{
- if (aud_drct_get_ready ())
- {
- gchar * title = aud_drct_get_title ();
- mainwin_set_song_title (title);
- str_unref (title);
- }
- else
- mainwin_set_song_title ("Buffering ...");
-}
-
-static void info_change (void)
-{
- gint bitrate = 0, samplerate = 0, channels = 0;
-
- if (aud_drct_get_ready ())
- aud_drct_get_info (& bitrate, & samplerate, & channels);
-
- mainwin_set_song_info (bitrate, samplerate, channels);
-}
-
-static void
-ui_main_evlistener_hide_seekbar(gpointer hook_data, gpointer user_data)
-{
- mainwin_disable_seekbar();
-}
-
-void ui_main_evlistener_playback_begin (void * hook_data, void * user_data)
-{
- mainwin_disable_seekbar();
- mainwin_update_song_info();
-
- gtk_widget_show (mainwin_stime_min);
- gtk_widget_show (mainwin_stime_sec);
- gtk_widget_show (mainwin_minus_num);
- gtk_widget_show (mainwin_10min_num);
- gtk_widget_show (mainwin_min_num);
- gtk_widget_show (mainwin_10sec_num);
- gtk_widget_show (mainwin_sec_num);
-
- if (aud_drct_get_ready () && aud_drct_get_length () > 0)
- {
- gtk_widget_show (mainwin_position);
- gtk_widget_show (mainwin_sposition);
- }
-
- ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PLAY);
-
- title_change ();
- info_change ();
-}
-
-static void
-ui_main_evlistener_playback_stop(gpointer hook_data, gpointer user_data)
-{
- mainwin_clear_song_info ();
-}
-
-static void repeat_toggled (void * data, void * user)
-{
- button_set_active (mainwin_repeat, aud_get_bool (NULL, "repeat"));
-}
-
-static void shuffle_toggled (void * data, void * user)
-{
- button_set_active (mainwin_shuffle, aud_get_bool (NULL, "shuffle"));
-}
-
-static void no_advance_toggled (void * data, void * user)
-{
- if (aud_get_bool (NULL, "no_playlist_advance"))
- mainwin_show_status_message (_("Single mode."));
- else
- mainwin_show_status_message (_("Playlist mode."));
-}
-
-static void stop_after_song_toggled (void * hook_data, void * user_data)
-{
- if (aud_get_bool (NULL, "stop_after_current_song"))
- mainwin_show_status_message (_("Stopping after song."));
-}
-
-void ui_main_evlistener_playback_pause (void * hook_data, void * user_data)
-{
- ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PAUSE);
-}
-
-static void
-ui_main_evlistener_playback_unpause(gpointer hook_data, gpointer user_data)
-{
- ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PLAY);
-}
-
-static void vis_clear_cb (void)
-{
- ui_vis_clear_data (mainwin_vis);
- ui_svis_clear_data (mainwin_svis);
-}
-
-static void render_mono_pcm (const gfloat * pcm)
-{
- guchar data[512];
-
- if (config.vis_type != VIS_SCOPE)
- return;
-
- for (gint i = 0; i < 75; i ++)
- {
- /* the signal is amplified by 2x */
- /* output values are in the range 0 to 16 */
- gint val = 8 + roundf (16 * pcm[i * 512 / 75]);
- data[i] = CLAMP (val, 0, 16);
- }
-
- if (aud_get_bool ("skins", "player_shaded"))
- ui_svis_timeout_func (mainwin_svis, data);
- else
- ui_vis_timeout_func (mainwin_vis, data);
-}
-
-/* calculate peak dB level, where 1 is 0 dB */
-static gfloat calc_peak_level (const gfloat * pcm, gint step)
-{
- gfloat peak = 0.0001; /* must be > 0, or level = -inf */
-
- for (gint i = 0; i < 512; i ++)
- {
- peak = MAX (peak, * pcm);
- pcm += step;
- }
-
- return 20 * log10 (peak);
-}
-
-static void render_multi_pcm (const gfloat * pcm, gint channels)
-{
- /* "VU meter" */
- if (config.vis_type != VIS_VOICEPRINT || ! aud_get_bool ("skins", "player_shaded"))
- return;
-
- guchar data[512];
-
- gint level = 38 + calc_peak_level (pcm, channels);
- data[0] = CLAMP (level, 0, 38);
-
- if (channels >= 2)
- {
- level = 38 + calc_peak_level (pcm + 1, channels);
- data[1] = CLAMP (level, 0, 38);
- }
- else
- data[1] = data[0];
-
- ui_svis_timeout_func (mainwin_svis, data);
-}
-
-/* convert linear frequency graph to logarithmic one */
-static void make_log_graph (const gfloat * freq, gint bands, gint db_range, gint
- int_range, guchar * graph)
-{
- static gint last_bands = 0;
- static gfloat * xscale = NULL;
-
- /* conversion table for the x-axis */
- if (bands != last_bands)
- {
- xscale = g_realloc (xscale, sizeof (gfloat) * (bands + 1));
- for (int i = 0; i <= bands; i ++)
- xscale[i] = powf (256, (float) i / bands) - 0.5f;
-
- last_bands = bands;
- }
-
- for (gint i = 0; i < bands; i ++)
- {
- /* sum up values in freq array between xscale[i] and xscale[i + 1],
- including fractional parts */
- gint a = ceilf (xscale[i]);
- gint b = floorf (xscale[i + 1]);
- gfloat sum = 0;
-
- if (b < a)
- sum += freq[b] * (xscale[i + 1] - xscale[i]);
- else
- {
- if (a > 0)
- sum += freq[a - 1] * (a - xscale[i]);
- for (; a < b; a ++)
- sum += freq[a];
- if (b < 256)
- sum += freq[b] * (xscale[i + 1] - b);
- }
-
- /* fudge factor to make the graph have the same overall height as a
- 12-band one no matter how many bands there are */
- sum *= (gfloat) bands / 12;
-
- /* convert to dB */
- gfloat val = 20 * log10f (sum);
-
- /* scale (-db_range, 0.0) to (0.0, int_range) */
- val = (1 + val / db_range) * int_range;
-
- graph[i] = CLAMP (val, 0, int_range);
- }
-}
-
-static void render_freq (const gfloat * freq)
-{
- bool_t shaded = aud_get_bool ("skins", "player_shaded");
-
- guchar data[512];
-
- if (config.vis_type == VIS_ANALYZER)
- {
- if (config.analyzer_type == ANALYZER_BARS)
- {
- if (shaded)
- make_log_graph (freq, 13, 40, 8, data);
- else
- make_log_graph (freq, 19, 40, 16, data);
- }
- else
- {
- if (shaded)
- make_log_graph (freq, 37, 40, 8, data);
- else
- make_log_graph (freq, 75, 40, 16, data);
- }
- }
- else if (config.vis_type == VIS_VOICEPRINT && ! shaded)
- make_log_graph (freq, 17, 40, 255, data);
- else
- return;
-
- if (shaded)
- ui_svis_timeout_func (mainwin_svis, data);
- else
- ui_vis_timeout_func (mainwin_vis, data);
-}
-
-void
-ui_main_evlistener_init(void)
-{
- hook_associate("hide seekbar", ui_main_evlistener_hide_seekbar, NULL);
- hook_associate("playback begin", ui_main_evlistener_playback_begin, NULL);
- hook_associate("playback ready", ui_main_evlistener_playback_begin, NULL);
- hook_associate("playback stop", ui_main_evlistener_playback_stop, NULL);
- hook_associate("playback pause", ui_main_evlistener_playback_pause, NULL);
- hook_associate("playback unpause", ui_main_evlistener_playback_unpause, NULL);
- hook_associate ("title change", (HookFunction) title_change, NULL);
- hook_associate ("info change", (HookFunction) info_change, NULL);
-
- hook_associate("playback seek", (HookFunction) mainwin_update_song_info, NULL);
-
- hook_associate ("set repeat", repeat_toggled, NULL);
- hook_associate ("set shuffle", shuffle_toggled, NULL);
- hook_associate ("set no_playlist_advance", no_advance_toggled, NULL);
- hook_associate ("set stop_after_current_song", stop_after_song_toggled, NULL);
-}
-
-void
-ui_main_evlistener_dissociate(void)
-{
- hook_dissociate("hide seekbar", ui_main_evlistener_hide_seekbar);
- hook_dissociate("playback begin", ui_main_evlistener_playback_begin);
- hook_dissociate("playback ready", ui_main_evlistener_playback_begin);
- hook_dissociate("playback stop", ui_main_evlistener_playback_stop);
- hook_dissociate("playback pause", ui_main_evlistener_playback_pause);
- hook_dissociate("playback unpause", ui_main_evlistener_playback_unpause);
- hook_dissociate ("title change", (HookFunction) title_change);
- hook_dissociate ("info change", (HookFunction) info_change);
-
- hook_dissociate("playback seek", (HookFunction) mainwin_update_song_info);
-
- hook_dissociate ("set repeat", repeat_toggled);
- hook_dissociate ("set shuffle", shuffle_toggled);
- hook_dissociate ("set no_playlist_advance", no_advance_toggled);
- hook_dissociate ("set stop_after_current_song", stop_after_song_toggled);
-}
-
-void start_stop_visual (gboolean exiting)
-{
- static char started = 0;
-
- if (config.vis_type != VIS_OFF && ! exiting && gtk_widget_get_visible (mainwin))
- {
- if (! started)
- {
- aud_vis_func_add (AUD_VIS_TYPE_CLEAR, (VisFunc) vis_clear_cb);
- aud_vis_func_add (AUD_VIS_TYPE_MONO_PCM, (VisFunc) render_mono_pcm);
- aud_vis_func_add (AUD_VIS_TYPE_MULTI_PCM, (VisFunc) render_multi_pcm);
- aud_vis_func_add (AUD_VIS_TYPE_FREQ, (VisFunc) render_freq);
- started = 1;
- }
- }
- else
- {
- if (started)
- {
- aud_vis_func_remove ((VisFunc) vis_clear_cb);
- aud_vis_func_remove ((VisFunc) render_mono_pcm);
- aud_vis_func_remove ((VisFunc) render_multi_pcm);
- aud_vis_func_remove ((VisFunc) render_freq);
- started = 0;
- }
- }
-}
diff --git a/src/skins/ui_main_evlisteners.cc b/src/skins/ui_main_evlisteners.cc
new file mode 100644
index 000000000000..564400b1a0d2
--- /dev/null
+++ b/src/skins/ui_main_evlisteners.cc
@@ -0,0 +1,346 @@
+/*
+ * Audacious
+ * Copyright (c) 2006-2007 Audacious development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <math.h>
+
+#include <libaudcore/drct.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/runtime.h>
+
+#include "skins_cfg.h"
+#include "ui_main.h"
+#include "ui_main_evlisteners.h"
+#include "ui_skin.h"
+#include "ui_skinned_button.h"
+#include "ui_skinned_playstatus.h"
+#include "ui_vis.h"
+#include "util.h"
+
+static void title_change (void)
+{
+ if (aud_drct_get_ready ())
+ mainwin_set_song_title (aud_drct_get_title ());
+ else
+ mainwin_set_song_title ("Buffering ...");
+}
+
+static void info_change (void)
+{
+ int bitrate, samplerate, channels;
+ aud_drct_get_info (bitrate, samplerate, channels);
+ mainwin_set_song_info (bitrate, samplerate, channels);
+}
+
+static void
+ui_main_evlistener_hide_seekbar(void * hook_data, void * user_data)
+{
+ mainwin_disable_seekbar();
+}
+
+void ui_main_evlistener_playback_begin (void * hook_data, void * user_data)
+{
+ mainwin_disable_seekbar();
+ mainwin_update_song_info();
+
+ gtk_widget_show (mainwin_stime_min);
+ gtk_widget_show (mainwin_stime_sec);
+ gtk_widget_show (mainwin_minus_num);
+ gtk_widget_show (mainwin_10min_num);
+ gtk_widget_show (mainwin_min_num);
+ gtk_widget_show (mainwin_10sec_num);
+ gtk_widget_show (mainwin_sec_num);
+
+ if (aud_drct_get_ready () && aud_drct_get_length () > 0)
+ {
+ gtk_widget_show (mainwin_position);
+ gtk_widget_show (mainwin_sposition);
+ }
+
+ ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PLAY);
+
+ title_change ();
+ info_change ();
+}
+
+static void
+ui_main_evlistener_playback_stop(void * hook_data, void * user_data)
+{
+ mainwin_clear_song_info ();
+}
+
+static void repeat_toggled (void * data, void * user)
+{
+ button_set_active (mainwin_repeat, aud_get_bool (nullptr, "repeat"));
+}
+
+static void shuffle_toggled (void * data, void * user)
+{
+ button_set_active (mainwin_shuffle, aud_get_bool (nullptr, "shuffle"));
+}
+
+static void no_advance_toggled (void * data, void * user)
+{
+ if (aud_get_bool (nullptr, "no_playlist_advance"))
+ mainwin_show_status_message (_("Single mode."));
+ else
+ mainwin_show_status_message (_("Playlist mode."));
+}
+
+static void stop_after_song_toggled (void * hook_data, void * user_data)
+{
+ if (aud_get_bool (nullptr, "stop_after_current_song"))
+ mainwin_show_status_message (_("Stopping after song."));
+}
+
+void ui_main_evlistener_playback_pause (void * hook_data, void * user_data)
+{
+ ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PAUSE);
+}
+
+static void
+ui_main_evlistener_playback_unpause(void * hook_data, void * user_data)
+{
+ ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PLAY);
+}
+
+class VisCallbacks : public Visualizer
+{
+public:
+ constexpr VisCallbacks () :
+ Visualizer (MonoPCM | MultiPCM | Freq) {}
+
+ void clear ();
+ void render_mono_pcm (const float * pcm);
+ void render_multi_pcm (const float * pcm, int channels);
+ void render_freq (const float * freq);
+};
+
+void VisCallbacks::clear ()
+{
+ ui_vis_clear_data (mainwin_vis);
+ ui_svis_clear_data (mainwin_svis);
+}
+
+void VisCallbacks::render_mono_pcm (const float * pcm)
+{
+ unsigned char data[512];
+
+ if (config.vis_type != VIS_SCOPE)
+ return;
+
+ for (int i = 0; i < 75; i ++)
+ {
+ /* the signal is amplified by 2x */
+ /* output values are in the range 0 to 16 */
+ int val = 8 + roundf (16 * pcm[i * 512 / 75]);
+ data[i] = aud::clamp (val, 0, 16);
+ }
+
+ if (aud_get_bool ("skins", "player_shaded"))
+ ui_svis_timeout_func (mainwin_svis, data);
+ else
+ ui_vis_timeout_func (mainwin_vis, data);
+}
+
+/* calculate peak dB level, where 1 is 0 dB */
+static float calc_peak_level (const float * pcm, int step)
+{
+ float peak = 0.0001; /* must be > 0, or level = -inf */
+
+ for (int i = 0; i < 512; i ++)
+ {
+ peak = aud::max (peak, * pcm);
+ pcm += step;
+ }
+
+ return 20 * log10 (peak);
+}
+
+void VisCallbacks::render_multi_pcm (const float * pcm, int channels)
+{
+ /* "VU meter" */
+ if (config.vis_type != VIS_VOICEPRINT || ! aud_get_bool ("skins", "player_shaded"))
+ return;
+
+ unsigned char data[512];
+
+ int level = 38 + calc_peak_level (pcm, channels);
+ data[0] = aud::clamp (level, 0, 38);
+
+ if (channels >= 2)
+ {
+ level = 38 + calc_peak_level (pcm + 1, channels);
+ data[1] = aud::clamp (level, 0, 38);
+ }
+ else
+ data[1] = data[0];
+
+ ui_svis_timeout_func (mainwin_svis, data);
+}
+
+/* convert linear frequency graph to logarithmic one */
+static void make_log_graph (const float * freq, int bands, int db_range, int
+ int_range, unsigned char * graph)
+{
+ static int last_bands = 0;
+ static float * xscale = nullptr;
+
+ /* conversion table for the x-axis */
+ if (bands != last_bands)
+ {
+ xscale = g_renew (float, xscale, bands + 1);
+ for (int i = 0; i <= bands; i ++)
+ xscale[i] = powf (256, (float) i / bands) - 0.5f;
+
+ last_bands = bands;
+ }
+
+ for (int i = 0; i < bands; i ++)
+ {
+ /* sum up values in freq array between xscale[i] and xscale[i + 1],
+ including fractional parts */
+ int a = ceilf (xscale[i]);
+ int b = floorf (xscale[i + 1]);
+ float sum = 0;
+
+ if (b < a)
+ sum += freq[b] * (xscale[i + 1] - xscale[i]);
+ else
+ {
+ if (a > 0)
+ sum += freq[a - 1] * (a - xscale[i]);
+ for (; a < b; a ++)
+ sum += freq[a];
+ if (b < 256)
+ sum += freq[b] * (xscale[i + 1] - b);
+ }
+
+ /* fudge factor to make the graph have the same overall height as a
+ 12-band one no matter how many bands there are */
+ sum *= (float) bands / 12;
+
+ /* convert to dB */
+ float val = 20 * log10f (sum);
+
+ /* scale (-db_range, 0.0) to (0.0, int_range) */
+ val = (1 + val / db_range) * int_range;
+
+ graph[i] = aud::clamp ((int) val, 0, int_range);
+ }
+}
+
+void VisCallbacks::render_freq (const float * freq)
+{
+ bool shaded = aud_get_bool ("skins", "player_shaded");
+
+ unsigned char data[512];
+
+ if (config.vis_type == VIS_ANALYZER)
+ {
+ if (config.analyzer_type == ANALYZER_BARS)
+ {
+ if (shaded)
+ make_log_graph (freq, 13, 40, 8, data);
+ else
+ make_log_graph (freq, 19, 40, 16, data);
+ }
+ else
+ {
+ if (shaded)
+ make_log_graph (freq, 37, 40, 8, data);
+ else
+ make_log_graph (freq, 75, 40, 16, data);
+ }
+ }
+ else if (config.vis_type == VIS_VOICEPRINT && ! shaded)
+ make_log_graph (freq, 17, 40, 255, data);
+ else
+ return;
+
+ if (shaded)
+ ui_svis_timeout_func (mainwin_svis, data);
+ else
+ ui_vis_timeout_func (mainwin_vis, data);
+}
+
+void
+ui_main_evlistener_init(void)
+{
+ hook_associate("hide seekbar", ui_main_evlistener_hide_seekbar, nullptr);
+ hook_associate("playback begin", ui_main_evlistener_playback_begin, nullptr);
+ hook_associate("playback ready", ui_main_evlistener_playback_begin, nullptr);
+ hook_associate("playback stop", ui_main_evlistener_playback_stop, nullptr);
+ hook_associate("playback pause", ui_main_evlistener_playback_pause, nullptr);
+ hook_associate("playback unpause", ui_main_evlistener_playback_unpause, nullptr);
+ hook_associate ("title change", (HookFunction) title_change, nullptr);
+ hook_associate ("info change", (HookFunction) info_change, nullptr);
+
+ hook_associate("playback seek", (HookFunction) mainwin_update_song_info, nullptr);
+
+ hook_associate ("set repeat", repeat_toggled, nullptr);
+ hook_associate ("set shuffle", shuffle_toggled, nullptr);
+ hook_associate ("set no_playlist_advance", no_advance_toggled, nullptr);
+ hook_associate ("set stop_after_current_song", stop_after_song_toggled, nullptr);
+}
+
+void
+ui_main_evlistener_dissociate(void)
+{
+ hook_dissociate("hide seekbar", ui_main_evlistener_hide_seekbar);
+ hook_dissociate("playback begin", ui_main_evlistener_playback_begin);
+ hook_dissociate("playback ready", ui_main_evlistener_playback_begin);
+ hook_dissociate("playback stop", ui_main_evlistener_playback_stop);
+ hook_dissociate("playback pause", ui_main_evlistener_playback_pause);
+ hook_dissociate("playback unpause", ui_main_evlistener_playback_unpause);
+ hook_dissociate ("title change", (HookFunction) title_change);
+ hook_dissociate ("info change", (HookFunction) info_change);
+
+ hook_dissociate("playback seek", (HookFunction) mainwin_update_song_info);
+
+ hook_dissociate ("set repeat", repeat_toggled);
+ hook_dissociate ("set shuffle", shuffle_toggled);
+ hook_dissociate ("set no_playlist_advance", no_advance_toggled);
+ hook_dissociate ("set stop_after_current_song", stop_after_song_toggled);
+}
+
+void start_stop_visual (gboolean exiting)
+{
+ static VisCallbacks callbacks;
+ static bool started = false;
+
+ if (config.vis_type != VIS_OFF && ! exiting && gtk_widget_get_visible (mainwin))
+ {
+ if (! started)
+ {
+ aud_visualizer_add (& callbacks);
+ started = true;
+ }
+ }
+ else
+ {
+ if (started)
+ {
+ aud_visualizer_remove (& callbacks);
+ started = false;
+ }
+ }
+}
diff --git a/src/skins/ui_playlist.c b/src/skins/ui_playlist.c
deleted file mode 100644
index 4bb64b4f6b4e..000000000000
--- a/src/skins/ui_playlist.c
+++ /dev/null
@@ -1,1124 +0,0 @@
-/* Audacious - Cross-platform multimedia player
- * Copyright (C) 2005-2011 Audacious development team.
- *
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- *
- * Based on XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <inttypes.h>
-#include <string.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-#include <audacious/debug.h>
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui.h>
-
-#include "actions-mainwin.h"
-#include "dnd.h"
-#include "drag-handle.h"
-#include "menus.h"
-#include "plugin.h"
-#include "skins_cfg.h"
-#include "ui_main.h"
-#include "ui_playlist.h"
-#include "ui_skinned_button.h"
-#include "ui_skinned_playlist.h"
-#include "ui_skinned_playlist_slider.h"
-#include "ui_skinned_textbox.h"
-#include "ui_skinned_window.h"
-#include "view.h"
-
-#define PLAYLISTWIN_MIN_WIDTH MAINWIN_WIDTH
-#define PLAYLISTWIN_MIN_HEIGHT MAINWIN_HEIGHT
-#define PLAYLISTWIN_WIDTH_SNAP 25
-#define PLAYLISTWIN_HEIGHT_SNAP 29
-#define PLAYLISTWIN_SHADED_HEIGHT MAINWIN_SHADED_HEIGHT
-
-#define APPEND(b, ...) snprintf (b + strlen (b), sizeof b - strlen (b), __VA_ARGS__)
-
-gint active_playlist = -1, active_length = 0;
-gchar * active_title = NULL;
-
-GtkWidget * playlistwin, * playlistwin_list, * playlistwin_sinfo;
-
-static GtkWidget *playlistwin_shade, *playlistwin_close;
-static GtkWidget *playlistwin_shaded_shade, *playlistwin_shaded_close;
-
-static GtkWidget *playlistwin_slider;
-static GtkWidget *playlistwin_time_min, *playlistwin_time_sec;
-static GtkWidget *playlistwin_info;
-static GtkWidget *playlistwin_srew, *playlistwin_splay;
-static GtkWidget *playlistwin_spause, *playlistwin_sstop;
-static GtkWidget *playlistwin_sfwd, *playlistwin_seject;
-static GtkWidget *playlistwin_sscroll_up, *playlistwin_sscroll_down;
-static GtkWidget * resize_handle, * sresize_handle;
-static GtkWidget * button_add, * button_sub, * button_sel, * button_misc,
- * button_list;
-
-static void playlistwin_select_search_cbt_cb(GtkWidget *called_cbt,
- gpointer other_cbt);
-static gboolean playlistwin_select_search_kp_cb(GtkWidget *entry,
- GdkEventKey *event,
- gpointer searchdlg_win);
-
-static gint resize_base_width, resize_base_height;
-static int drop_position;
-static gboolean song_changed;
-
-static void playlistwin_update_info (void)
-{
- char s1[16], s2[16];
- audgui_format_time (s1, sizeof s1, aud_playlist_get_selected_length (active_playlist));
- audgui_format_time (s2, sizeof s2, aud_playlist_get_total_length (active_playlist));
-
- SCONCAT3 (buf, s1, "/", s2);
- textbox_set_text (playlistwin_info, buf);
-}
-
-static void update_rollup_text (void)
-{
- gint playlist = aud_playlist_get_active ();
- gint entry = aud_playlist_get_position (playlist);
- gchar scratch[512];
-
- scratch[0] = 0;
-
- if (entry > -1)
- {
- gint length = aud_playlist_entry_get_length (playlist, entry, TRUE);
-
- if (aud_get_bool (NULL, "show_numbers_in_pl"))
- APPEND (scratch, "%d. ", 1 + entry);
-
- gchar * title = aud_playlist_entry_get_title (playlist, entry, TRUE);
- APPEND (scratch, "%s", title);
- str_unref (title);
-
- if (length > 0)
- {
- char buf[16];
- audgui_format_time (buf, sizeof buf, length);
- APPEND (scratch, " (%s)", buf);
- }
- }
-
- textbox_set_text (playlistwin_sinfo, scratch);
-}
-
-static void real_update (void)
-{
- ui_skinned_playlist_update (playlistwin_list);
- playlistwin_update_info ();
- update_rollup_text ();
-}
-
-void playlistwin_update (void)
-{
- if (! aud_playlist_update_pending ())
- real_update ();
-}
-
-static void
-playlistwin_shade_toggle(void)
-{
- view_set_playlist_shaded (! aud_get_bool ("skins", "playlist_shaded"));
-}
-
-static void playlistwin_scroll (gboolean up)
-{
- gint rows, first;
-
- ui_skinned_playlist_row_info (playlistwin_list, & rows, & first);
- ui_skinned_playlist_scroll_to (playlistwin_list, first + (up ? -1 : 1) *
- rows / 3);
-}
-
-static void playlistwin_scroll_up_pushed (void)
-{
- playlistwin_scroll (TRUE);
-}
-
-static void playlistwin_scroll_down_pushed (void)
-{
- playlistwin_scroll (FALSE);
-}
-
-static void
-playlistwin_select_all(void)
-{
- aud_playlist_select_all (active_playlist, 1);
-}
-
-static void
-playlistwin_select_none(void)
-{
- aud_playlist_select_all (active_playlist, 0);
-}
-
-static void copy_selected_to_new (gint playlist)
-{
- gint entries = aud_playlist_entry_count (playlist);
- gint new = aud_playlist_count ();
- Index * filenames = index_new ();
- Index * tuples = index_new ();
- gint entry;
-
- aud_playlist_insert (new);
-
- for (entry = 0; entry < entries; entry ++)
- {
- if (aud_playlist_entry_get_selected (playlist, entry))
- {
- index_insert (filenames, -1, aud_playlist_entry_get_filename (playlist, entry));
- index_insert (tuples, -1, aud_playlist_entry_get_tuple (playlist, entry, TRUE));
- }
- }
-
- aud_playlist_entry_insert_batch (new, 0, filenames, tuples, FALSE);
- aud_playlist_set_active (new);
-}
-
-static void
-playlistwin_select_search(void)
-{
- GtkWidget *searchdlg_win, *searchdlg_grid;
- GtkWidget *searchdlg_hbox, *searchdlg_logo, *searchdlg_helptext;
- GtkWidget *searchdlg_entry_title, *searchdlg_label_title;
- GtkWidget *searchdlg_entry_album, *searchdlg_label_album;
- GtkWidget *searchdlg_entry_file_name, *searchdlg_label_file_name;
- GtkWidget *searchdlg_entry_performer, *searchdlg_label_performer;
- GtkWidget *searchdlg_checkbt_clearprevsel;
- GtkWidget *searchdlg_checkbt_newplaylist;
- GtkWidget *searchdlg_checkbt_autoenqueue;
- gint result;
-
- /* create dialog */
- searchdlg_win = gtk_dialog_new_with_buttons(
- _("Search entries in active playlist") , GTK_WINDOW(mainwin) ,
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT ,
- _("Cancel") , GTK_RESPONSE_REJECT , _("Search") , GTK_RESPONSE_ACCEPT , NULL );
-
- /* help text and logo */
- searchdlg_hbox = gtk_box_new( GTK_ORIENTATION_HORIZONTAL , 4 );
- searchdlg_logo = gtk_image_new_from_icon_name( "edit-find" , GTK_ICON_SIZE_DIALOG );
- searchdlg_helptext = gtk_label_new( _("Select entries in playlist by filling one or more "
- "fields. Fields use regular expressions syntax, case-insensitive. If you don't know how "
- "regular expressions work, simply insert a literal portion of what you're searching for.") );
- gtk_label_set_line_wrap( GTK_LABEL(searchdlg_helptext) , TRUE );
- gtk_box_pack_start( GTK_BOX(searchdlg_hbox) , searchdlg_logo , FALSE , FALSE , 0 );
- gtk_box_pack_start( GTK_BOX(searchdlg_hbox) , searchdlg_helptext , FALSE , FALSE , 0 );
-
- /* title */
- searchdlg_label_title = gtk_label_new( _("Title: ") );
- searchdlg_entry_title = gtk_entry_new();
- gtk_widget_set_hexpand( searchdlg_entry_title , TRUE );
- gtk_widget_set_halign( searchdlg_label_title , GTK_ALIGN_START );
- g_signal_connect( searchdlg_entry_title , "key-press-event" ,
- G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
-
- /* album */
- searchdlg_label_album= gtk_label_new( _("Album: ") );
- searchdlg_entry_album= gtk_entry_new();
- gtk_widget_set_hexpand( searchdlg_entry_album , TRUE );
- gtk_widget_set_halign( searchdlg_label_album , GTK_ALIGN_START );
- g_signal_connect( searchdlg_entry_album , "key-press-event" ,
- G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
-
- /* artist */
- searchdlg_label_performer = gtk_label_new( _("Artist: ") );
- searchdlg_entry_performer = gtk_entry_new();
- gtk_widget_set_hexpand( searchdlg_entry_performer , TRUE );
- gtk_widget_set_halign( searchdlg_label_performer , GTK_ALIGN_START );
- g_signal_connect( searchdlg_entry_performer , "key-press-event" ,
- G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
-
- /* file name */
- searchdlg_label_file_name = gtk_label_new( _("Filename: ") );
- searchdlg_entry_file_name = gtk_entry_new();
- gtk_widget_set_hexpand( searchdlg_entry_file_name , TRUE );
- gtk_widget_set_halign( searchdlg_label_file_name , GTK_ALIGN_START );
- g_signal_connect( searchdlg_entry_file_name , "key-press-event" ,
- G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
-
- /* some options that control behaviour */
- searchdlg_checkbt_clearprevsel = gtk_check_button_new_with_label(
- _("Clear previous selection before searching") );
- gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel) , TRUE );
- searchdlg_checkbt_autoenqueue = gtk_check_button_new_with_label(
- _("Automatically toggle queue for matching entries") );
- gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_autoenqueue) , FALSE );
- searchdlg_checkbt_newplaylist = gtk_check_button_new_with_label(
- _("Create a new playlist with matching entries") );
- gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_newplaylist) , FALSE );
- g_signal_connect( searchdlg_checkbt_autoenqueue , "clicked" ,
- G_CALLBACK(playlistwin_select_search_cbt_cb) , searchdlg_checkbt_newplaylist );
- g_signal_connect( searchdlg_checkbt_newplaylist , "clicked" ,
- G_CALLBACK(playlistwin_select_search_cbt_cb) , searchdlg_checkbt_autoenqueue );
-
- /* place fields in searchdlg_grid */
- searchdlg_grid = gtk_grid_new();
- gtk_grid_set_row_spacing( GTK_GRID(searchdlg_grid) , 2 );
- gtk_widget_set_margin_bottom( searchdlg_hbox , 8 );
- gtk_widget_set_margin_top( searchdlg_checkbt_clearprevsel , 8 );
- gtk_grid_attach( GTK_GRID(searchdlg_grid) , searchdlg_hbox , 0 , 0 , 2 , 1 );
- gtk_grid_attach( GTK_GRID(searchdlg_grid) , searchdlg_label_title , 0 , 1 , 1 , 1 );
- gtk_grid_attach( GTK_GRID(searchdlg_grid) , searchdlg_entry_title , 1 , 1 , 1 , 1 );
- gtk_grid_attach( GTK_GRID(searchdlg_grid) , searchdlg_label_album , 0 , 2 , 1 , 1 );
- gtk_grid_attach( GTK_GRID(searchdlg_grid) , searchdlg_entry_album , 1 , 2 , 1 , 1 );
- gtk_grid_attach( GTK_GRID(searchdlg_grid) , searchdlg_label_performer , 0 , 3 , 1 , 1 );
- gtk_grid_attach( GTK_GRID(searchdlg_grid) , searchdlg_entry_performer , 1 , 3 , 1 , 1 );
- gtk_grid_attach( GTK_GRID(searchdlg_grid) , searchdlg_label_file_name , 0 , 4 , 1 , 1 );
- gtk_grid_attach( GTK_GRID(searchdlg_grid) , searchdlg_entry_file_name , 1 , 4 , 1 , 1 );
- gtk_grid_attach( GTK_GRID(searchdlg_grid) , searchdlg_checkbt_clearprevsel , 0 , 5 , 2 , 1 );
- gtk_grid_attach( GTK_GRID(searchdlg_grid) , searchdlg_checkbt_autoenqueue , 0 , 6 , 2 , 1 );
- gtk_grid_attach( GTK_GRID(searchdlg_grid) , searchdlg_checkbt_newplaylist , 0 , 7 , 2 , 1 );
-
- gtk_container_set_border_width( GTK_CONTAINER(searchdlg_grid) , 5 );
- gtk_container_add ( GTK_CONTAINER(gtk_dialog_get_content_area
- (GTK_DIALOG(searchdlg_win))) , searchdlg_grid );
- gtk_widget_show_all( searchdlg_win );
- result = gtk_dialog_run( GTK_DIALOG(searchdlg_win) );
-
- switch(result)
- {
- case GTK_RESPONSE_ACCEPT:
- {
- /* create a TitleInput tuple with user search data */
- Tuple *tuple = tuple_new();
- gchar *searchdata = NULL;
-
- searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_title) );
- AUDDBG("title=\"%s\"\n", searchdata);
- tuple_set_str(tuple, FIELD_TITLE, searchdata);
-
- searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_album) );
- AUDDBG("album=\"%s\"\n", searchdata);
- tuple_set_str(tuple, FIELD_ALBUM, searchdata);
-
- searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_performer) );
- AUDDBG("performer=\"%s\"\n", searchdata);
- tuple_set_str(tuple, FIELD_ARTIST, searchdata);
-
- searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_file_name) );
- AUDDBG("filename=\"%s\"\n", searchdata);
- tuple_set_str(tuple, FIELD_FILE_NAME, searchdata);
-
- /* check if previous selection should be cleared before searching */
- if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel)) == TRUE )
- playlistwin_select_none();
-
- aud_playlist_select_by_patterns (active_playlist, tuple);
- tuple_unref (tuple);
-
- /* check if a new playlist should be created after searching */
- if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_newplaylist)) == TRUE )
- copy_selected_to_new (active_playlist);
- else
- {
- /* set focus on the first entry found */
- gint entries = aud_playlist_entry_count (active_playlist);
- gint count;
-
- for (count = 0; count < entries; count ++)
- {
- if (aud_playlist_entry_get_selected (active_playlist, count))
- {
- ui_skinned_playlist_set_focused (playlistwin_list, count);
- break;
- }
- }
-
- /* check if matched entries should be queued */
- if (gtk_toggle_button_get_active ((GtkToggleButton *)
- searchdlg_checkbt_autoenqueue))
- aud_playlist_queue_insert_selected (active_playlist, -1);
- }
-
- playlistwin_update ();
- break;
- }
- default:
- break;
- }
- /* done here :) */
- gtk_widget_destroy( searchdlg_win );
-}
-
-static void playlistwin_inverse_selection (void)
-{
- gint entries = aud_playlist_entry_count (active_playlist);
- gint entry;
-
- for (entry = 0; entry < entries; entry ++)
- aud_playlist_entry_set_selected (active_playlist, entry,
- ! aud_playlist_entry_get_selected (active_playlist, entry));
-}
-
-/* note: height is ignored if the window is shaded */
-static void playlistwin_resize (gint w, gint h)
-{
- gint tx, ty;
-
- g_return_if_fail(w > 0 && h > 0);
-
- tx = (w - PLAYLISTWIN_MIN_WIDTH) / PLAYLISTWIN_WIDTH_SNAP;
- tx = (tx * PLAYLISTWIN_WIDTH_SNAP) + PLAYLISTWIN_MIN_WIDTH;
- if (tx < PLAYLISTWIN_MIN_WIDTH)
- tx = PLAYLISTWIN_MIN_WIDTH;
-
- if (! aud_get_bool ("skins", "playlist_shaded"))
- {
- ty = (h - PLAYLISTWIN_MIN_HEIGHT) / PLAYLISTWIN_HEIGHT_SNAP;
- ty = (ty * PLAYLISTWIN_HEIGHT_SNAP) + PLAYLISTWIN_MIN_HEIGHT;
- if (ty < PLAYLISTWIN_MIN_HEIGHT)
- ty = PLAYLISTWIN_MIN_HEIGHT;
- }
- else
- ty = config.playlist_height;
-
- if (tx == config.playlist_width && ty == config.playlist_height)
- return;
-
- config.playlist_width = w = tx;
- config.playlist_height = h = ty;
-
- ui_skinned_playlist_resize (playlistwin_list, w - 31, h - 58);
- window_move_widget (playlistwin, FALSE, playlistwin_slider, w - 15, 20);
- ui_skinned_playlist_slider_resize (playlistwin_slider, h - 58);
-
- window_move_widget (playlistwin, TRUE, playlistwin_shaded_shade, w - 21, 3);
- window_move_widget (playlistwin, TRUE, playlistwin_shaded_close, w - 11, 3);
- window_move_widget (playlistwin, FALSE, playlistwin_shade, w - 21, 3);
- window_move_widget (playlistwin, FALSE, playlistwin_close, w - 11, 3);
-
- window_move_widget (playlistwin, FALSE, playlistwin_time_min, w - 82, h - 15);
- window_move_widget (playlistwin, FALSE, playlistwin_time_sec, w - 64, h - 15);
- window_move_widget (playlistwin, FALSE, playlistwin_info, w - 143, h - 28);
-
- window_move_widget (playlistwin, FALSE, playlistwin_srew, w - 144, h - 16);
- window_move_widget (playlistwin, FALSE, playlistwin_splay, w - 138, h - 16);
- window_move_widget (playlistwin, FALSE, playlistwin_spause, w - 128, h - 16);
- window_move_widget (playlistwin, FALSE, playlistwin_sstop, w - 118, h - 16);
- window_move_widget (playlistwin, FALSE, playlistwin_sfwd, w - 109, h - 16);
- window_move_widget (playlistwin, FALSE, playlistwin_seject, w - 100, h - 16);
- window_move_widget (playlistwin, FALSE, playlistwin_sscroll_up, w - 14, h - 35);
- window_move_widget (playlistwin, FALSE, playlistwin_sscroll_down, w - 14, h - 30);
-
- window_move_widget (playlistwin, FALSE, resize_handle, w - 20, h - 20);
- window_move_widget (playlistwin, TRUE, sresize_handle, w - 31, 0);
-
- textbox_set_width (playlistwin_sinfo, w - 35);
-
- window_move_widget (playlistwin, FALSE, button_add, 12, h - 29);
- window_move_widget (playlistwin, FALSE, button_sub, 40, h - 29);
- window_move_widget (playlistwin, FALSE, button_sel, 68, h - 29);
- window_move_widget (playlistwin, FALSE, button_misc, 100, h - 29);
- window_move_widget (playlistwin, FALSE, button_list, w - 46, h - 29);
-}
-
-static void
-playlistwin_fileinfo(void)
-{
- audgui_infowin_show (active_playlist, aud_playlist_get_focus (active_playlist));
-}
-
-static void
-playlistwin_scrolled(GtkWidget * widget,
- GdkEventScroll * event,
- gpointer callback_data)
-{
- switch (event->direction)
- {
- case GDK_SCROLL_DOWN:
- playlistwin_scroll (FALSE);
- break;
- case GDK_SCROLL_UP:
- playlistwin_scroll (TRUE);
- break;
- default:
- break;
- }
-}
-
-static gboolean
-playlistwin_press(GtkWidget * widget,
- GdkEventButton * event,
- gpointer callback_data)
-{
- if (event->button == 1 && event->type == GDK_2BUTTON_PRESS &&
- event->window == gtk_widget_get_window (widget) && event->y < 14)
- playlistwin_shade_toggle();
- else if (event->button == 3)
- menu_popup (UI_MENU_PLAYLIST, event->x_root, event->y_root, FALSE, FALSE, 3, event->time);
-
- return TRUE;
-}
-
-void
-playlistwin_hide_timer(void)
-{
- textbox_set_text (playlistwin_time_min, " ");
- textbox_set_text (playlistwin_time_sec, " ");
-}
-
-void playlistwin_set_time (const gchar * minutes, const gchar * seconds)
-{
- textbox_set_text (playlistwin_time_min, minutes);
- textbox_set_text (playlistwin_time_sec, seconds);
-}
-
-static void drag_motion (GtkWidget * widget, GdkDragContext * context, gint x,
- gint y, guint time, void * unused)
-{
- if (! aud_get_bool ("skins", "playlist_shaded"))
- ui_skinned_playlist_hover (playlistwin_list, x - 12, y - 20);
-}
-
-static void drag_leave (GtkWidget * widget, GdkDragContext * context, guint time,
- void * unused)
-{
- if (! aud_get_bool ("skins", "playlist_shaded"))
- ui_skinned_playlist_hover_end (playlistwin_list);
-}
-
-static void drag_drop (GtkWidget * widget, GdkDragContext * context, gint x,
- gint y, guint time, void * unused)
-{
- if (aud_get_bool ("skins", "playlist_shaded"))
- drop_position = -1;
- else
- {
- ui_skinned_playlist_hover (playlistwin_list, x - 12, y - 20);
- drop_position = ui_skinned_playlist_hover_end (playlistwin_list);
- }
-}
-
-static void drag_data_received (GtkWidget * widget, GdkDragContext * context,
- gint x, gint y, GtkSelectionData * data, guint info, guint time, void * unused)
-{
- audgui_urilist_insert (active_playlist, drop_position, (const gchar *)
- gtk_selection_data_get_data (data));
- drop_position = -1;
-}
-
-static void playlistwin_hide (void)
-{
- view_set_show_playlist (FALSE);
-}
-
-static void resize_press (void)
-{
- resize_base_width = config.playlist_width;
- resize_base_height = config.playlist_height;
-}
-
-static void resize_drag (gint x_offset, gint y_offset)
-{
- bool_t shaded = aud_get_bool ("skins", "playlist_shaded");
-
- /* compromise between rounding and truncating; this has no real
- * justification at all other than it "looks about right". */
- playlistwin_resize (resize_base_width + x_offset + PLAYLISTWIN_WIDTH_SNAP /
- 3, resize_base_height + y_offset + PLAYLISTWIN_HEIGHT_SNAP / 3);
- window_set_size (playlistwin, config.playlist_width, shaded ?
- PLAYLISTWIN_SHADED_HEIGHT : config.playlist_height);
-}
-
-static void button_add_cb (GtkWidget * button, GdkEventButton * event)
-{
- gint xpos, ypos;
- gtk_window_get_position ((GtkWindow *) playlistwin, & xpos, & ypos);
- menu_popup (UI_MENU_PLAYLIST_ADD, xpos + 12, ypos + config.playlist_height -
- 8, FALSE, TRUE, event->button, event->time);
-}
-
-static void button_sub_cb (GtkWidget * button, GdkEventButton * event)
-{
- gint xpos, ypos;
- gtk_window_get_position ((GtkWindow *) playlistwin, & xpos, & ypos);
- menu_popup (UI_MENU_PLAYLIST_REMOVE, xpos + 40, ypos +
- config.playlist_height - 8, FALSE, TRUE, event->button, event->time);
-}
-
-static void button_sel_cb (GtkWidget * button, GdkEventButton * event)
-{
- gint xpos, ypos;
- gtk_window_get_position ((GtkWindow *) playlistwin, & xpos, & ypos);
- menu_popup (UI_MENU_PLAYLIST_SELECT, xpos + 68, ypos +
- config.playlist_height - 8, FALSE, TRUE, event->button, event->time);
-}
-
-static void button_misc_cb (GtkWidget * button, GdkEventButton * event)
-{
- gint xpos, ypos;
- gtk_window_get_position ((GtkWindow *) playlistwin, & xpos, & ypos);
- menu_popup (UI_MENU_PLAYLIST_SORT, xpos + 100, ypos + config.playlist_height
- - 8, FALSE, TRUE, event->button, event->time);
-}
-
-static void button_list_cb (GtkWidget * button, GdkEventButton * event)
-{
- gint xpos, ypos;
- gtk_window_get_position ((GtkWindow *) playlistwin, & xpos, & ypos);
- menu_popup (UI_MENU_PLAYLIST, xpos + config.playlist_width - 12, ypos +
- config.playlist_height - 8, TRUE, TRUE, event->button, event->time);
-}
-
-static void
-playlistwin_create_widgets(void)
-{
- gint w = config.playlist_width, h = config.playlist_height;
-
- playlistwin_sinfo = textbox_new (w - 35, "", NULL, config.autoscroll);
- window_put_widget (playlistwin, TRUE, playlistwin_sinfo, 4, 4);
-
- playlistwin_shaded_shade = button_new (9, 9, 128, 45, 150, 42, SKIN_PLEDIT, SKIN_PLEDIT);
- window_put_widget (playlistwin, TRUE, playlistwin_shaded_shade, w - 21, 3);
- button_on_release (playlistwin_shaded_shade, (ButtonCB) playlistwin_shade_toggle);
-
- playlistwin_shaded_close = button_new (9, 9, 138, 45, 52, 42, SKIN_PLEDIT, SKIN_PLEDIT);
- window_put_widget (playlistwin, TRUE, playlistwin_shaded_close, w - 11, 3);
- button_on_release (playlistwin_shaded_close, (ButtonCB) playlistwin_hide);
-
- playlistwin_shade = button_new (9, 9, 157, 3, 62, 42, SKIN_PLEDIT, SKIN_PLEDIT);
- window_put_widget (playlistwin, FALSE, playlistwin_shade, w - 21, 3);
- button_on_release (playlistwin_shade, (ButtonCB) playlistwin_shade_toggle);
-
- playlistwin_close = button_new (9, 9, 167, 3, 52, 42, SKIN_PLEDIT, SKIN_PLEDIT);
- window_put_widget (playlistwin, FALSE, playlistwin_close, w - 11, 3);
- button_on_release (playlistwin_close, (ButtonCB) playlistwin_hide);
-
- char * font = aud_get_str ("skins", "playlist_font");
- playlistwin_list = ui_skinned_playlist_new (w - 31, h - 58, font);
- window_put_widget (playlistwin, FALSE, playlistwin_list, 12, 20);
- str_unref (font);
-
- /* playlist list box slider */
- playlistwin_slider = ui_skinned_playlist_slider_new (playlistwin_list, h - 58);
- window_put_widget (playlistwin, FALSE, playlistwin_slider, w - 15, 20);
- ui_skinned_playlist_set_slider (playlistwin_list, playlistwin_slider);
-
- playlistwin_time_min = textbox_new (15, "", NULL, FALSE);
- window_put_widget (playlistwin, FALSE, playlistwin_time_min, w - 82, h - 15);
-
- playlistwin_time_sec = textbox_new (10, "", NULL, FALSE);
- window_put_widget (playlistwin, FALSE, playlistwin_time_sec, w - 64, h - 15);
-
- g_signal_connect(playlistwin_time_min, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
- g_signal_connect(playlistwin_time_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
- playlistwin_info = textbox_new (90, "", NULL, FALSE);
- window_put_widget (playlistwin, FALSE, playlistwin_info, w - 143, h - 28);
-
- /* mini play control buttons at right bottom corner */
-
- playlistwin_srew = button_new_small (8, 7);
- window_put_widget (playlistwin, FALSE, playlistwin_srew, w - 144, h - 16);
- button_on_release (playlistwin_srew, (ButtonCB) aud_drct_pl_prev);
-
- playlistwin_splay = button_new_small (10, 7);
- window_put_widget (playlistwin, FALSE, playlistwin_splay, w - 138, h - 16);
- button_on_release (playlistwin_splay, (ButtonCB) aud_drct_play);
-
- playlistwin_spause = button_new_small (10, 7);
- window_put_widget (playlistwin, FALSE, playlistwin_spause, w - 128, h - 16);
- button_on_release (playlistwin_spause, (ButtonCB) aud_drct_pause);
-
- playlistwin_sstop = button_new_small (9, 7);
- window_put_widget (playlistwin, FALSE, playlistwin_sstop, w - 118, h - 16);
- button_on_release (playlistwin_sstop, (ButtonCB) aud_drct_stop);
-
- playlistwin_sfwd = button_new_small (8, 7);
- window_put_widget (playlistwin, FALSE, playlistwin_sfwd, w - 109, h - 16);
- button_on_release (playlistwin_sfwd, (ButtonCB) aud_drct_pl_next);
-
- playlistwin_seject = button_new_small (9, 7);
- window_put_widget (playlistwin, FALSE, playlistwin_seject, w - 100, h - 16);
- button_on_release (playlistwin_seject, (ButtonCB) action_play_file);
-
- playlistwin_sscroll_up = button_new_small (8, 5);
- window_put_widget (playlistwin, FALSE, playlistwin_sscroll_up, w - 14, h - 35);
- button_on_release (playlistwin_sscroll_up, (ButtonCB) playlistwin_scroll_up_pushed);
-
- playlistwin_sscroll_down = button_new_small (8, 5);
- window_put_widget (playlistwin, FALSE, playlistwin_sscroll_down, w - 14, h - 30);
- button_on_release (playlistwin_sscroll_down, (ButtonCB) playlistwin_scroll_down_pushed);
-
- /* resize handles */
-
- resize_handle = drag_handle_new (20, 20, resize_press, resize_drag);
- window_put_widget (playlistwin, FALSE, resize_handle, w - 20, h - 20);
-
- sresize_handle = drag_handle_new (9, PLAYLISTWIN_SHADED_HEIGHT, resize_press, resize_drag);
- window_put_widget (playlistwin, TRUE, sresize_handle, w - 31, 0);
-
- /* lower button row */
-
- button_add = button_new_small (25, 18);
- window_put_widget (playlistwin, FALSE, button_add, 12, h - 29);
- button_on_press (button_add, button_add_cb);
-
- button_sub = button_new_small (25, 18);
- window_put_widget (playlistwin, FALSE, button_sub, 40, h - 29);
- button_on_press (button_sub, button_sub_cb);
-
- button_sel = button_new_small (25, 18);
- window_put_widget (playlistwin, FALSE, button_sel, 68, h - 29);
- button_on_press (button_sel, button_sel_cb);
-
- button_misc = button_new_small (25, 18);
- window_put_widget (playlistwin, FALSE, button_misc, 100, h - 29);
- button_on_press (button_misc, button_misc_cb);
-
- button_list = button_new_small (23, 18);
- window_put_widget (playlistwin, FALSE, button_list, w - 46, h - 29);
- button_on_press (button_list, button_list_cb);
-}
-
-static void pl_win_draw (GtkWidget * window, cairo_t * cr)
-{
- if (aud_get_bool ("skins", "playlist_shaded"))
- skin_draw_playlistwin_shaded (cr, config.playlist_width, TRUE);
- else
- skin_draw_playlistwin_frame (cr, config.playlist_width,
- config.playlist_height, TRUE);
-}
-
-static void
-playlistwin_create_window(void)
-{
- bool_t shaded = aud_get_bool ("skins", "playlist_shaded");
-
- playlistwin = window_new (& config.playlist_x, & config.playlist_y,
- config.playlist_width, shaded ? PLAYLISTWIN_SHADED_HEIGHT :
- config.playlist_height, FALSE, shaded, pl_win_draw);
-
- gtk_window_set_title(GTK_WINDOW(playlistwin), _("Audacious Playlist Editor"));
-
- gtk_window_set_transient_for(GTK_WINDOW(playlistwin),
- GTK_WINDOW(mainwin));
- gtk_window_set_skip_taskbar_hint(GTK_WINDOW(playlistwin), TRUE);
-
- gtk_widget_add_events(playlistwin, GDK_POINTER_MOTION_MASK |
- GDK_FOCUS_CHANGE_MASK | GDK_BUTTON_MOTION_MASK |
- GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
- GDK_SCROLL_MASK | GDK_VISIBILITY_NOTIFY_MASK);
-
- g_signal_connect (playlistwin, "delete-event", (GCallback) handle_window_close, NULL);
- g_signal_connect (playlistwin, "button-press-event", (GCallback) playlistwin_press, NULL);
- g_signal_connect (playlistwin, "scroll-event", (GCallback) playlistwin_scrolled, NULL);
- g_signal_connect (playlistwin, "key-press-event", (GCallback) mainwin_keypress, NULL);
-
- drag_dest_set (playlistwin);
- drop_position = -1;
-
- g_signal_connect (playlistwin, "drag-motion", (GCallback) drag_motion, NULL);
- g_signal_connect (playlistwin, "drag-leave", (GCallback) drag_leave, NULL);
- g_signal_connect (playlistwin, "drag-drop", (GCallback) drag_drop, NULL);
- g_signal_connect (playlistwin, "drag-data-received", (GCallback) drag_data_received, NULL);
-}
-
-static void get_title (void)
-{
- gint playlists = aud_playlist_count ();
-
- g_free (active_title);
-
- if (playlists > 1)
- {
- gchar * title = aud_playlist_get_title (active_playlist);
- active_title = g_strdup_printf (_("%s (%d of %d)"), title, 1 +
- active_playlist, playlists);
- str_unref (title);
- }
- else
- active_title = NULL;
-}
-
-static void update_cb (void * unused, void * another)
-{
- gint old = active_playlist;
-
- active_playlist = aud_playlist_get_active ();
- active_length = aud_playlist_entry_count (active_playlist);
- get_title ();
-
- if (active_playlist != old)
- {
- ui_skinned_playlist_scroll_to (playlistwin_list, 0);
- song_changed = TRUE;
- }
-
- if (song_changed)
- {
- ui_skinned_playlist_set_focused (playlistwin_list,
- aud_playlist_get_position (active_playlist));
- song_changed = FALSE;
- }
-
- real_update ();
-}
-
-static void follow_cb (void * data, void * another)
-{
- gint list = GPOINTER_TO_INT (data);
- aud_playlist_select_all (list, FALSE);
-
- gint row = aud_playlist_get_position (list);
- if (row >= 0)
- aud_playlist_entry_set_selected (list, row, TRUE);
-
- if (list == active_playlist)
- song_changed = TRUE;
-}
-
-void
-playlistwin_create(void)
-{
- active_playlist = aud_playlist_get_active ();
- active_length = aud_playlist_entry_count (active_playlist);
- active_title = NULL;
- get_title ();
-
- playlistwin_create_window();
-
- playlistwin_create_widgets();
- window_show_all (playlistwin);
-
- gtk_window_add_accel_group ((GtkWindow *) playlistwin, menu_get_accel_group ());
-
- aud_playlist_select_all (active_playlist, FALSE);
-
- gint row = aud_playlist_get_position (active_playlist);
- if (row >= 0)
- aud_playlist_entry_set_selected (active_playlist, row, TRUE);
-
- ui_skinned_playlist_set_focused (playlistwin_list, row);
-
- song_changed = FALSE;
-
- hook_associate ("playlist position", follow_cb, NULL);
- hook_associate ("playlist activate", update_cb, NULL);
- hook_associate ("playlist update", update_cb, NULL);
-}
-
-void playlistwin_unhook (void)
-{
- hook_dissociate ("playlist position", follow_cb);
- hook_dissociate ("playlist activate", update_cb);
- hook_dissociate ("playlist update", update_cb);
- g_free (active_title);
- active_title = NULL;
-}
-
-void action_playlist_track_info(void)
-{
- playlistwin_fileinfo();
-}
-
-void action_queue_toggle (void)
-{
- gint focus = aud_playlist_get_focus (active_playlist);
- if (focus == -1)
- return;
-
- gint at = aud_playlist_queue_find_entry (active_playlist, focus);
-
- if (at == -1)
- aud_playlist_queue_insert_selected (active_playlist, -1);
- else
- aud_playlist_queue_delete (active_playlist, at, 1);
-}
-
-void action_playlist_sort_by_track_number (void)
-{
- aud_playlist_sort_by_scheme (active_playlist, PLAYLIST_SORT_TRACK);
-}
-
-void action_playlist_sort_by_title (void)
-{
- aud_playlist_sort_by_scheme (active_playlist, PLAYLIST_SORT_TITLE);
-}
-
-void action_playlist_sort_by_album (void)
-{
- aud_playlist_sort_by_scheme (active_playlist, PLAYLIST_SORT_ALBUM);
-}
-
-void action_playlist_sort_by_artist (void)
-{
- aud_playlist_sort_by_scheme (active_playlist, PLAYLIST_SORT_ARTIST);
-}
-
-void action_playlist_sort_by_full_path (void)
-{
- aud_playlist_sort_by_scheme (active_playlist, PLAYLIST_SORT_PATH);
-}
-
-void action_playlist_sort_by_date (void)
-{
- aud_playlist_sort_by_scheme (active_playlist, PLAYLIST_SORT_DATE);
-}
-
-void action_playlist_sort_by_filename (void)
-{
- aud_playlist_sort_by_scheme (active_playlist, PLAYLIST_SORT_FILENAME);
-}
-
-void action_playlist_sort_selected_by_track_number (void)
-{
- aud_playlist_sort_selected_by_scheme (active_playlist, PLAYLIST_SORT_TRACK);
-}
-
-void action_playlist_sort_selected_by_title (void)
-{
- aud_playlist_sort_selected_by_scheme (active_playlist, PLAYLIST_SORT_TITLE);
-}
-
-void action_playlist_sort_selected_by_album (void)
-{
- aud_playlist_sort_selected_by_scheme (active_playlist, PLAYLIST_SORT_ALBUM);
-}
-
-void action_playlist_sort_selected_by_artist (void)
-{
- aud_playlist_sort_selected_by_scheme (active_playlist, PLAYLIST_SORT_ARTIST);
-}
-
-void action_playlist_sort_selected_by_full_path (void)
-{
- aud_playlist_sort_selected_by_scheme (active_playlist, PLAYLIST_SORT_PATH);
-}
-
-void action_playlist_sort_selected_by_date (void)
-{
- aud_playlist_sort_selected_by_scheme (active_playlist, PLAYLIST_SORT_DATE);
-}
-
-void action_playlist_sort_selected_by_filename (void)
-{
- aud_playlist_sort_selected_by_scheme (active_playlist, PLAYLIST_SORT_FILENAME);
-}
-
-void action_playlist_randomize_list (void)
-{
- aud_playlist_randomize (active_playlist);
-}
-
-void action_playlist_reverse_list (void)
-{
- aud_playlist_reverse (active_playlist);
-}
-
-void action_playlist_clear_queue (void)
-{
- aud_playlist_queue_delete (active_playlist, 0, aud_playlist_queue_count
- (active_playlist));
-}
-
-void action_playlist_remove_unavailable (void)
-{
- aud_playlist_remove_failed (active_playlist);
-}
-
-void action_playlist_remove_dupes_by_title (void)
-{
- aud_playlist_remove_duplicates_by_scheme (active_playlist,
- PLAYLIST_SORT_TITLE);
-}
-
-void action_playlist_remove_dupes_by_filename (void)
-{
- aud_playlist_remove_duplicates_by_scheme (active_playlist,
- PLAYLIST_SORT_FILENAME);
-}
-
-void action_playlist_remove_dupes_by_full_path (void)
-{
- aud_playlist_remove_duplicates_by_scheme (active_playlist,
- PLAYLIST_SORT_PATH);
-}
-
-void action_playlist_remove_all (void)
-{
- aud_playlist_entry_delete (active_playlist, 0, aud_playlist_entry_count
- (active_playlist));
-}
-
-void action_playlist_remove_selected (void)
-{
- aud_playlist_delete_selected (active_playlist);
-}
-
-void action_playlist_remove_unselected (void)
-{
- playlistwin_inverse_selection ();
- aud_playlist_delete_selected (active_playlist);
- aud_playlist_select_all (active_playlist, TRUE);
-}
-
-void action_playlist_copy (void)
-{
- GtkClipboard * clip = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- gchar * list = audgui_urilist_create_from_selected (active_playlist);
-
- if (list == NULL)
- return;
-
- gtk_clipboard_set_text (clip, list, -1);
- g_free (list);
-}
-
-void action_playlist_cut (void)
-{
- action_playlist_copy ();
- action_playlist_remove_selected ();
-}
-
-void action_playlist_paste (void)
-{
- GtkClipboard * clip = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- gchar * list = gtk_clipboard_wait_for_text (clip);
-
- if (list == NULL)
- return;
-
- audgui_urilist_insert (active_playlist,
- aud_playlist_get_focus (active_playlist), list);
- g_free (list);
-}
-
-void
-action_playlist_add_files(void)
-{
- audgui_run_filebrowser(FALSE); /* FALSE = NO_PLAY_BUTTON */
-}
-
-void
-action_playlist_add_url(void)
-{
- audgui_show_add_url_window (FALSE);
-}
-
-void action_playlist_play (void)
-{
- aud_drct_play_playlist (aud_playlist_get_active ());
-}
-
-void action_playlist_new (void)
-{
- gint playlist = aud_playlist_count ();
-
- aud_playlist_insert (playlist);
- aud_playlist_set_active (playlist);
-}
-
-void action_playlist_prev (void)
-{
- if (active_playlist > 0)
- aud_playlist_set_active (active_playlist - 1);
- else
- {
- gint count = aud_playlist_count ();
- if (count > 1)
- aud_playlist_set_active (count - 1);
- }
-}
-
-void action_playlist_next (void)
-{
- gint count = aud_playlist_count ();
-
- if (active_playlist + 1 < count)
- aud_playlist_set_active (active_playlist + 1);
- else if (count > 1)
- aud_playlist_set_active (0);
-}
-
-void action_playlist_rename (void)
-{
- audgui_show_playlist_rename (active_playlist);
-}
-
-void action_playlist_delete (void)
-{
- audgui_confirm_playlist_delete (active_playlist);
-}
-
-void
-action_playlist_refresh_list(void)
-{
- aud_playlist_rescan (active_playlist);
-}
-
-void
-action_playlist_search_and_select(void)
-{
- playlistwin_select_search();
-}
-
-void
-action_playlist_invert_selection(void)
-{
- playlistwin_inverse_selection();
-}
-
-void
-action_playlist_select_none(void)
-{
- playlistwin_select_none();
-}
-
-void
-action_playlist_select_all(void)
-{
- playlistwin_select_all();
-}
-
-
-static void
-playlistwin_select_search_cbt_cb(GtkWidget *called_cbt, gpointer other_cbt)
-{
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(called_cbt)) == TRUE)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(other_cbt), FALSE);
- return;
-}
-
-static gboolean
-playlistwin_select_search_kp_cb(GtkWidget *entry, GdkEventKey *event,
- gpointer searchdlg_win)
-{
- switch (event->keyval)
- {
- case GDK_KEY_Return:
- gtk_dialog_response(GTK_DIALOG(searchdlg_win), GTK_RESPONSE_ACCEPT);
- return TRUE;
- default:
- return FALSE;
- }
-}
diff --git a/src/skins/ui_playlist.cc b/src/skins/ui_playlist.cc
new file mode 100644
index 000000000000..1eccd21d2da5
--- /dev/null
+++ b/src/skins/ui_playlist.cc
@@ -0,0 +1,1163 @@
+/* Audacious - Cross-platform multimedia player
+ * Copyright (C) 2005-2011 Audacious development team.
+ *
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ *
+ * Based on XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <inttypes.h>
+#include <string.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/tuple.h>
+#include <libaudgui/libaudgui.h>
+
+#include "actions-mainwin.h"
+#include "dnd.h"
+#include "drag-handle.h"
+#include "menus.h"
+#include "plugin.h"
+#include "skins_cfg.h"
+#include "ui_main.h"
+#include "ui_playlist.h"
+#include "ui_skinned_button.h"
+#include "ui_skinned_playlist.h"
+#include "ui_skinned_playlist_slider.h"
+#include "ui_skinned_textbox.h"
+#include "ui_skinned_window.h"
+#include "view.h"
+
+#define PLAYLISTWIN_MIN_WIDTH MAINWIN_WIDTH
+#define PLAYLISTWIN_MIN_HEIGHT MAINWIN_HEIGHT
+#define PLAYLISTWIN_WIDTH_SNAP 25
+#define PLAYLISTWIN_HEIGHT_SNAP 29
+#define PLAYLISTWIN_SHADED_HEIGHT MAINWIN_SHADED_HEIGHT
+
+#define APPEND(b, ...) snprintf (b + strlen (b), sizeof b - strlen (b), __VA_ARGS__)
+
+int active_playlist = -1, active_length = 0;
+char * active_title = nullptr;
+
+GtkWidget * playlistwin, * playlistwin_list, * playlistwin_sinfo;
+
+static GtkWidget *playlistwin_shade, *playlistwin_close;
+static GtkWidget *playlistwin_shaded_shade, *playlistwin_shaded_close;
+
+static GtkWidget *playlistwin_slider;
+static GtkWidget *playlistwin_time_min, *playlistwin_time_sec;
+static GtkWidget *playlistwin_info;
+static GtkWidget *playlistwin_srew, *playlistwin_splay;
+static GtkWidget *playlistwin_spause, *playlistwin_sstop;
+static GtkWidget *playlistwin_sfwd, *playlistwin_seject;
+static GtkWidget *playlistwin_sscroll_up, *playlistwin_sscroll_down;
+static GtkWidget * resize_handle, * sresize_handle;
+static GtkWidget * button_add, * button_sub, * button_sel, * button_misc,
+ * button_list;
+
+static void playlistwin_select_search_cbt_cb(GtkWidget *called_cbt,
+ void * other_cbt);
+static gboolean playlistwin_select_search_kp_cb(GtkWidget *entry,
+ GdkEventKey *event,
+ void * searchdlg_win);
+
+static int resize_base_width, resize_base_height;
+static int drop_position;
+static gboolean song_changed;
+
+static void playlistwin_update_info (void)
+{
+ StringBuf s1 = str_format_time (aud_playlist_get_selected_length (active_playlist));
+ StringBuf s2 = str_format_time (aud_playlist_get_total_length (active_playlist));
+ textbox_set_text (playlistwin_info, str_concat ({s1, "/", s2}));
+}
+
+static void update_rollup_text (void)
+{
+ int playlist = aud_playlist_get_active ();
+ int entry = aud_playlist_get_position (playlist);
+ Tuple tuple = aud_playlist_entry_get_tuple (playlist, entry, Playlist::Guess);
+ char scratch[512];
+
+ scratch[0] = 0;
+
+ if (entry > -1)
+ {
+ String title = tuple.get_str (Tuple::FormattedTitle);
+ int length = tuple.get_int (Tuple::Length);
+
+ if (aud_get_bool (nullptr, "show_numbers_in_pl"))
+ APPEND (scratch, "%d. ", 1 + entry);
+
+ APPEND (scratch, "%s", (const char *) title);
+
+ if (length >= 0)
+ {
+ StringBuf buf = str_format_time (length);
+ APPEND (scratch, " (%s)", (const char *) buf);
+ }
+ }
+
+ textbox_set_text (playlistwin_sinfo, scratch);
+}
+
+static void real_update (void)
+{
+ ui_skinned_playlist_update (playlistwin_list);
+ playlistwin_update_info ();
+ update_rollup_text ();
+}
+
+void playlistwin_update (void)
+{
+ if (! aud_playlist_update_pending ())
+ real_update ();
+}
+
+static void
+playlistwin_shade_toggle(void)
+{
+ view_set_playlist_shaded (! aud_get_bool ("skins", "playlist_shaded"));
+}
+
+static void playlistwin_scroll (gboolean up)
+{
+ int rows, first;
+
+ ui_skinned_playlist_row_info (playlistwin_list, & rows, & first);
+ ui_skinned_playlist_scroll_to (playlistwin_list, first + (up ? -1 : 1) *
+ rows / 3);
+}
+
+static void playlistwin_scroll_up_pushed (void)
+{
+ playlistwin_scroll (TRUE);
+}
+
+static void playlistwin_scroll_down_pushed (void)
+{
+ playlistwin_scroll (FALSE);
+}
+
+static void
+playlistwin_select_all(void)
+{
+ aud_playlist_select_all (active_playlist, 1);
+}
+
+static void
+playlistwin_select_none(void)
+{
+ aud_playlist_select_all (active_playlist, 0);
+}
+
+static void copy_selected_to_new (int playlist)
+{
+ int entries = aud_playlist_entry_count (playlist);
+ int new_list = aud_playlist_count ();
+ Index<PlaylistAddItem> items;
+ int entry;
+
+ aud_playlist_insert (new_list);
+
+ for (entry = 0; entry < entries; entry ++)
+ {
+ if (aud_playlist_entry_get_selected (playlist, entry))
+ {
+ items.append (
+ aud_playlist_entry_get_filename (playlist, entry),
+ aud_playlist_entry_get_tuple (playlist, entry, Playlist::Guess)
+ );
+ }
+ }
+
+ aud_playlist_entry_insert_batch (new_list, 0, std::move (items), FALSE);
+ aud_playlist_set_active (new_list);
+}
+
+static void
+playlistwin_select_search(void)
+{
+ GtkWidget *searchdlg_win, *searchdlg_grid;
+ GtkWidget *searchdlg_hbox, *searchdlg_logo, *searchdlg_helptext;
+ GtkWidget *searchdlg_entry_title, *searchdlg_label_title;
+ GtkWidget *searchdlg_entry_album, *searchdlg_label_album;
+ GtkWidget *searchdlg_entry_file_name, *searchdlg_label_file_name;
+ GtkWidget *searchdlg_entry_performer, *searchdlg_label_performer;
+ GtkWidget *searchdlg_checkbt_clearprevsel;
+ GtkWidget *searchdlg_checkbt_newplaylist;
+ GtkWidget *searchdlg_checkbt_autoenqueue;
+ int result;
+
+ /* create dialog */
+ searchdlg_win = gtk_dialog_new_with_buttons(
+ _("Search entries in active playlist") , GTK_WINDOW(mainwin) ,
+ (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
+ _("Cancel") , GTK_RESPONSE_REJECT , _("Search") , GTK_RESPONSE_ACCEPT , nullptr );
+
+ /* help text and logo */
+ searchdlg_hbox = gtk_hbox_new (FALSE, 6);
+ searchdlg_logo = gtk_image_new_from_icon_name( "edit-find" , GTK_ICON_SIZE_DIALOG );
+ searchdlg_helptext = gtk_label_new( _("Select entries in playlist by filling one or more "
+ "fields. Fields use regular expressions syntax, case-insensitive. If you don't know how "
+ "regular expressions work, simply insert a literal portion of what you're searching for.") );
+ gtk_label_set_line_wrap( GTK_LABEL(searchdlg_helptext) , TRUE );
+ gtk_box_pack_start( GTK_BOX(searchdlg_hbox) , searchdlg_logo , FALSE , FALSE , 0 );
+ gtk_box_pack_start( GTK_BOX(searchdlg_hbox) , searchdlg_helptext , FALSE , FALSE , 0 );
+
+ /* title */
+ searchdlg_label_title = gtk_label_new( _("Title:") );
+ gtk_misc_set_alignment ((GtkMisc *) searchdlg_label_title, 1, 0.5);
+ searchdlg_entry_title = gtk_entry_new();
+ g_signal_connect( searchdlg_entry_title , "key-press-event" ,
+ G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
+
+ /* album */
+ searchdlg_label_album= gtk_label_new( _("Album:") );
+ gtk_misc_set_alignment ((GtkMisc *) searchdlg_label_album, 1, 0.5);
+ searchdlg_entry_album= gtk_entry_new();
+ g_signal_connect( searchdlg_entry_album , "key-press-event" ,
+ G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
+
+ /* artist */
+ searchdlg_label_performer = gtk_label_new( _("Artist:") );
+ gtk_misc_set_alignment ((GtkMisc *) searchdlg_label_performer, 1, 0.5);
+ searchdlg_entry_performer = gtk_entry_new();
+ g_signal_connect( searchdlg_entry_performer , "key-press-event" ,
+ G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
+
+ /* file name */
+ searchdlg_label_file_name = gtk_label_new( _("File Name:") );
+ gtk_misc_set_alignment ((GtkMisc *) searchdlg_label_file_name, 1, 0.5);
+ searchdlg_entry_file_name = gtk_entry_new();
+ g_signal_connect( searchdlg_entry_file_name , "key-press-event" ,
+ G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
+
+ /* some options that control behaviour */
+ searchdlg_checkbt_clearprevsel = gtk_check_button_new_with_label(
+ _("Clear previous selection before searching") );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel) , TRUE );
+ searchdlg_checkbt_autoenqueue = gtk_check_button_new_with_label(
+ _("Automatically toggle queue for matching entries") );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_autoenqueue) , FALSE );
+ searchdlg_checkbt_newplaylist = gtk_check_button_new_with_label(
+ _("Create a new playlist with matching entries") );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_newplaylist) , FALSE );
+ g_signal_connect( searchdlg_checkbt_autoenqueue , "clicked" ,
+ G_CALLBACK(playlistwin_select_search_cbt_cb) , searchdlg_checkbt_newplaylist );
+ g_signal_connect( searchdlg_checkbt_newplaylist , "clicked" ,
+ G_CALLBACK(playlistwin_select_search_cbt_cb) , searchdlg_checkbt_autoenqueue );
+
+ /* place fields in searchdlg_grid */
+ searchdlg_grid = gtk_table_new (0, 0, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (searchdlg_grid), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (searchdlg_grid), 6);
+ gtk_table_attach_defaults (GTK_TABLE (searchdlg_grid), searchdlg_hbox, 0, 2, 0, 1);
+ gtk_table_attach (GTK_TABLE (searchdlg_grid), searchdlg_label_title, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (searchdlg_grid), searchdlg_entry_title, 1, 2, 1, 2);
+ gtk_table_attach (GTK_TABLE (searchdlg_grid), searchdlg_label_album, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (searchdlg_grid), searchdlg_entry_album, 1, 2, 2, 3);
+ gtk_table_attach (GTK_TABLE (searchdlg_grid), searchdlg_label_performer, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (searchdlg_grid), searchdlg_entry_performer, 1, 2, 3, 4);
+ gtk_table_attach (GTK_TABLE (searchdlg_grid), searchdlg_label_file_name, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (searchdlg_grid), searchdlg_entry_file_name, 1, 2, 4, 5);
+ gtk_table_attach_defaults (GTK_TABLE (searchdlg_grid), searchdlg_checkbt_clearprevsel, 0, 2, 5, 6);
+ gtk_table_attach_defaults (GTK_TABLE (searchdlg_grid), searchdlg_checkbt_autoenqueue, 0, 2, 6, 7);
+ gtk_table_attach_defaults (GTK_TABLE (searchdlg_grid), searchdlg_checkbt_newplaylist, 0, 2, 7, 8);
+
+ gtk_container_set_border_width( GTK_CONTAINER(searchdlg_grid) , 5 );
+ gtk_container_add ( GTK_CONTAINER(gtk_dialog_get_content_area
+ (GTK_DIALOG(searchdlg_win))) , searchdlg_grid );
+ gtk_widget_show_all( searchdlg_win );
+ result = gtk_dialog_run( GTK_DIALOG(searchdlg_win) );
+
+ switch(result)
+ {
+ case GTK_RESPONSE_ACCEPT:
+ {
+ /* create a TitleInput tuple with user search data */
+ Tuple tuple;
+ char *searchdata = nullptr;
+
+ searchdata = (char*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_title) );
+ AUDDBG("title=\"%s\"\n", searchdata);
+ tuple.set_str (Tuple::Title, searchdata);
+
+ searchdata = (char*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_album) );
+ AUDDBG("album=\"%s\"\n", searchdata);
+ tuple.set_str (Tuple::Album, searchdata);
+
+ searchdata = (char*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_performer) );
+ AUDDBG("performer=\"%s\"\n", searchdata);
+ tuple.set_str (Tuple::Artist, searchdata);
+
+ searchdata = (char*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_file_name) );
+ AUDDBG("filename=\"%s\"\n", searchdata);
+ tuple.set_str (Tuple::Basename, searchdata);
+
+ /* check if previous selection should be cleared before searching */
+ if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel)) == TRUE )
+ playlistwin_select_none();
+
+ aud_playlist_select_by_patterns (active_playlist, tuple);
+
+ /* check if a new playlist should be created after searching */
+ if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_newplaylist)) == TRUE )
+ copy_selected_to_new (active_playlist);
+ else
+ {
+ /* set focus on the first entry found */
+ int entries = aud_playlist_entry_count (active_playlist);
+ int count;
+
+ for (count = 0; count < entries; count ++)
+ {
+ if (aud_playlist_entry_get_selected (active_playlist, count))
+ {
+ ui_skinned_playlist_set_focused (playlistwin_list, count);
+ break;
+ }
+ }
+
+ /* check if matched entries should be queued */
+ if (gtk_toggle_button_get_active ((GtkToggleButton *)
+ searchdlg_checkbt_autoenqueue))
+ aud_playlist_queue_insert_selected (active_playlist, -1);
+ }
+
+ playlistwin_update ();
+ break;
+ }
+ default:
+ break;
+ }
+ /* done here :) */
+ gtk_widget_destroy( searchdlg_win );
+}
+
+static void playlistwin_inverse_selection (void)
+{
+ int entries = aud_playlist_entry_count (active_playlist);
+ int entry;
+
+ for (entry = 0; entry < entries; entry ++)
+ aud_playlist_entry_set_selected (active_playlist, entry,
+ ! aud_playlist_entry_get_selected (active_playlist, entry));
+}
+
+/* note: height is ignored if the window is shaded */
+static void playlistwin_resize (int w, int h)
+{
+ int tx, ty;
+
+ g_return_if_fail(w > 0 && h > 0);
+
+ tx = (w - PLAYLISTWIN_MIN_WIDTH) / PLAYLISTWIN_WIDTH_SNAP;
+ tx = (tx * PLAYLISTWIN_WIDTH_SNAP) + PLAYLISTWIN_MIN_WIDTH;
+ if (tx < PLAYLISTWIN_MIN_WIDTH)
+ tx = PLAYLISTWIN_MIN_WIDTH;
+
+ if (! aud_get_bool ("skins", "playlist_shaded"))
+ {
+ ty = (h - PLAYLISTWIN_MIN_HEIGHT) / PLAYLISTWIN_HEIGHT_SNAP;
+ ty = (ty * PLAYLISTWIN_HEIGHT_SNAP) + PLAYLISTWIN_MIN_HEIGHT;
+ if (ty < PLAYLISTWIN_MIN_HEIGHT)
+ ty = PLAYLISTWIN_MIN_HEIGHT;
+ }
+ else
+ ty = config.playlist_height;
+
+ if (tx == config.playlist_width && ty == config.playlist_height)
+ return;
+
+ config.playlist_width = w = tx;
+ config.playlist_height = h = ty;
+
+ ui_skinned_playlist_resize (playlistwin_list, w - 31, h - 58);
+ window_move_widget (playlistwin, FALSE, playlistwin_slider, w - 15, 20);
+ ui_skinned_playlist_slider_resize (playlistwin_slider, h - 58);
+
+ window_move_widget (playlistwin, TRUE, playlistwin_shaded_shade, w - 21, 3);
+ window_move_widget (playlistwin, TRUE, playlistwin_shaded_close, w - 11, 3);
+ window_move_widget (playlistwin, FALSE, playlistwin_shade, w - 21, 3);
+ window_move_widget (playlistwin, FALSE, playlistwin_close, w - 11, 3);
+
+ window_move_widget (playlistwin, FALSE, playlistwin_time_min, w - 82, h - 15);
+ window_move_widget (playlistwin, FALSE, playlistwin_time_sec, w - 64, h - 15);
+ window_move_widget (playlistwin, FALSE, playlistwin_info, w - 143, h - 28);
+
+ window_move_widget (playlistwin, FALSE, playlistwin_srew, w - 144, h - 16);
+ window_move_widget (playlistwin, FALSE, playlistwin_splay, w - 138, h - 16);
+ window_move_widget (playlistwin, FALSE, playlistwin_spause, w - 128, h - 16);
+ window_move_widget (playlistwin, FALSE, playlistwin_sstop, w - 118, h - 16);
+ window_move_widget (playlistwin, FALSE, playlistwin_sfwd, w - 109, h - 16);
+ window_move_widget (playlistwin, FALSE, playlistwin_seject, w - 100, h - 16);
+ window_move_widget (playlistwin, FALSE, playlistwin_sscroll_up, w - 14, h - 35);
+ window_move_widget (playlistwin, FALSE, playlistwin_sscroll_down, w - 14, h - 30);
+
+ window_move_widget (playlistwin, FALSE, resize_handle, w - 20, h - 20);
+ window_move_widget (playlistwin, TRUE, sresize_handle, w - 31, 0);
+
+ textbox_set_width (playlistwin_sinfo, w - 35);
+
+ window_move_widget (playlistwin, FALSE, button_add, 12, h - 29);
+ window_move_widget (playlistwin, FALSE, button_sub, 40, h - 29);
+ window_move_widget (playlistwin, FALSE, button_sel, 68, h - 29);
+ window_move_widget (playlistwin, FALSE, button_misc, 100, h - 29);
+ window_move_widget (playlistwin, FALSE, button_list, w - 46, h - 29);
+}
+
+static void
+playlistwin_fileinfo(void)
+{
+ audgui_infowin_show (active_playlist, aud_playlist_get_focus (active_playlist));
+}
+
+static void
+playlistwin_scrolled(GtkWidget * widget,
+ GdkEventScroll * event,
+ void * callback_data)
+{
+ switch (event->direction)
+ {
+ case GDK_SCROLL_DOWN:
+ playlistwin_scroll (FALSE);
+ break;
+ case GDK_SCROLL_UP:
+ playlistwin_scroll (TRUE);
+ break;
+ default:
+ break;
+ }
+}
+
+static gboolean
+playlistwin_press(GtkWidget * widget,
+ GdkEventButton * event,
+ void * callback_data)
+{
+ if (event->button == 1 && event->type == GDK_2BUTTON_PRESS &&
+ event->window == gtk_widget_get_window (widget) && event->y < 14)
+ playlistwin_shade_toggle();
+ else if (event->button == 3)
+ menu_popup (UI_MENU_PLAYLIST, event->x_root, event->y_root, FALSE, FALSE, 3, event->time);
+
+ return TRUE;
+}
+
+void
+playlistwin_hide_timer(void)
+{
+ textbox_set_text (playlistwin_time_min, " ");
+ textbox_set_text (playlistwin_time_sec, " ");
+}
+
+void playlistwin_set_time (const char * minutes, const char * seconds)
+{
+ textbox_set_text (playlistwin_time_min, minutes);
+ textbox_set_text (playlistwin_time_sec, seconds);
+}
+
+static void drag_motion (GtkWidget * widget, GdkDragContext * context, int x,
+ int y, unsigned time, void * unused)
+{
+ if (! aud_get_bool ("skins", "playlist_shaded"))
+ ui_skinned_playlist_hover (playlistwin_list, x - 12, y - 20);
+}
+
+static void drag_leave (GtkWidget * widget, GdkDragContext * context, unsigned time,
+ void * unused)
+{
+ if (! aud_get_bool ("skins", "playlist_shaded"))
+ ui_skinned_playlist_hover_end (playlistwin_list);
+}
+
+static void drag_drop (GtkWidget * widget, GdkDragContext * context, int x,
+ int y, unsigned time, void * unused)
+{
+ if (aud_get_bool ("skins", "playlist_shaded"))
+ drop_position = -1;
+ else
+ {
+ ui_skinned_playlist_hover (playlistwin_list, x - 12, y - 20);
+ drop_position = ui_skinned_playlist_hover_end (playlistwin_list);
+ }
+}
+
+static void drag_data_received (GtkWidget * widget, GdkDragContext * context,
+ int x, int y, GtkSelectionData * data, unsigned info, unsigned time, void * unused)
+{
+ audgui_urilist_insert (active_playlist, drop_position, (const char *)
+ gtk_selection_data_get_data (data));
+ drop_position = -1;
+}
+
+static void playlistwin_hide (void)
+{
+ view_set_show_playlist (FALSE);
+}
+
+static void resize_press (void)
+{
+ resize_base_width = config.playlist_width;
+ resize_base_height = config.playlist_height;
+}
+
+static void resize_drag (int x_offset, int y_offset)
+{
+ gboolean shaded = aud_get_bool ("skins", "playlist_shaded");
+
+ /* compromise between rounding and truncating; this has no real
+ * justification at all other than it "looks about right". */
+ playlistwin_resize (resize_base_width + x_offset + PLAYLISTWIN_WIDTH_SNAP /
+ 3, resize_base_height + y_offset + PLAYLISTWIN_HEIGHT_SNAP / 3);
+ window_set_size (playlistwin, config.playlist_width, shaded ?
+ PLAYLISTWIN_SHADED_HEIGHT : config.playlist_height);
+}
+
+static void button_add_cb (GtkWidget * button, GdkEventButton * event)
+{
+ int xpos, ypos;
+ gtk_window_get_position ((GtkWindow *) playlistwin, & xpos, & ypos);
+ menu_popup (UI_MENU_PLAYLIST_ADD, xpos + 12 * config.scale,
+ ypos + (config.playlist_height - 8) * config.scale, FALSE, TRUE,
+ event->button, event->time);
+}
+
+static void button_sub_cb (GtkWidget * button, GdkEventButton * event)
+{
+ int xpos, ypos;
+ gtk_window_get_position ((GtkWindow *) playlistwin, & xpos, & ypos);
+ menu_popup (UI_MENU_PLAYLIST_REMOVE, xpos + 40 * config.scale,
+ ypos + (config.playlist_height - 8) * config.scale, FALSE, TRUE,
+ event->button, event->time);
+}
+
+static void button_sel_cb (GtkWidget * button, GdkEventButton * event)
+{
+ int xpos, ypos;
+ gtk_window_get_position ((GtkWindow *) playlistwin, & xpos, & ypos);
+ menu_popup (UI_MENU_PLAYLIST_SELECT, xpos + 68 * config.scale,
+ ypos + (config.playlist_height - 8) * config.scale, FALSE, TRUE,
+ event->button, event->time);
+}
+
+static void button_misc_cb (GtkWidget * button, GdkEventButton * event)
+{
+ int xpos, ypos;
+ gtk_window_get_position ((GtkWindow *) playlistwin, & xpos, & ypos);
+ menu_popup (UI_MENU_PLAYLIST_SORT, xpos + 100 * config.scale,
+ ypos + (config.playlist_height - 8) * config.scale, FALSE, TRUE,
+ event->button, event->time);
+}
+
+static void button_list_cb (GtkWidget * button, GdkEventButton * event)
+{
+ int xpos, ypos;
+ gtk_window_get_position ((GtkWindow *) playlistwin, & xpos, & ypos);
+ menu_popup (UI_MENU_PLAYLIST,
+ xpos + (config.playlist_width - 12) * config.scale,
+ ypos + (config.playlist_height - 8) * config.scale, TRUE, TRUE,
+ event->button, event->time);
+}
+
+static void
+playlistwin_create_widgets(void)
+{
+ int w = config.playlist_width, h = config.playlist_height;
+
+ playlistwin_sinfo = textbox_new (w - 35, "", nullptr, config.autoscroll);
+ window_put_widget (playlistwin, TRUE, playlistwin_sinfo, 4, 4);
+
+ playlistwin_shaded_shade = button_new (9, 9, 128, 45, 150, 42, SKIN_PLEDIT, SKIN_PLEDIT);
+ window_put_widget (playlistwin, TRUE, playlistwin_shaded_shade, w - 21, 3);
+ button_on_release (playlistwin_shaded_shade, (ButtonCB) playlistwin_shade_toggle);
+
+ playlistwin_shaded_close = button_new (9, 9, 138, 45, 52, 42, SKIN_PLEDIT, SKIN_PLEDIT);
+ window_put_widget (playlistwin, TRUE, playlistwin_shaded_close, w - 11, 3);
+ button_on_release (playlistwin_shaded_close, (ButtonCB) playlistwin_hide);
+
+ playlistwin_shade = button_new (9, 9, 157, 3, 62, 42, SKIN_PLEDIT, SKIN_PLEDIT);
+ window_put_widget (playlistwin, FALSE, playlistwin_shade, w - 21, 3);
+ button_on_release (playlistwin_shade, (ButtonCB) playlistwin_shade_toggle);
+
+ playlistwin_close = button_new (9, 9, 167, 3, 52, 42, SKIN_PLEDIT, SKIN_PLEDIT);
+ window_put_widget (playlistwin, FALSE, playlistwin_close, w - 11, 3);
+ button_on_release (playlistwin_close, (ButtonCB) playlistwin_hide);
+
+ String font = aud_get_str ("skins", "playlist_font");
+ playlistwin_list = ui_skinned_playlist_new (w - 31, h - 58, font);
+ window_put_widget (playlistwin, FALSE, playlistwin_list, 12, 20);
+
+ /* playlist list box slider */
+ playlistwin_slider = ui_skinned_playlist_slider_new (playlistwin_list, h - 58);
+ window_put_widget (playlistwin, FALSE, playlistwin_slider, w - 15, 20);
+ ui_skinned_playlist_set_slider (playlistwin_list, playlistwin_slider);
+
+ playlistwin_time_min = textbox_new (15, "", nullptr, FALSE);
+ window_put_widget (playlistwin, FALSE, playlistwin_time_min, w - 82, h - 15);
+
+ playlistwin_time_sec = textbox_new (10, "", nullptr, FALSE);
+ window_put_widget (playlistwin, FALSE, playlistwin_time_sec, w - 64, h - 15);
+
+ g_signal_connect(playlistwin_time_min, "button-press-event", G_CALLBACK(change_timer_mode_cb), nullptr);
+ g_signal_connect(playlistwin_time_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), nullptr);
+
+ playlistwin_info = textbox_new (90, "", nullptr, FALSE);
+ window_put_widget (playlistwin, FALSE, playlistwin_info, w - 143, h - 28);
+
+ /* mini play control buttons at right bottom corner */
+
+ playlistwin_srew = button_new_small (8, 7);
+ window_put_widget (playlistwin, FALSE, playlistwin_srew, w - 144, h - 16);
+ button_on_release (playlistwin_srew, (ButtonCB) aud_drct_pl_prev);
+
+ playlistwin_splay = button_new_small (10, 7);
+ window_put_widget (playlistwin, FALSE, playlistwin_splay, w - 138, h - 16);
+ button_on_release (playlistwin_splay, (ButtonCB) aud_drct_play);
+
+ playlistwin_spause = button_new_small (10, 7);
+ window_put_widget (playlistwin, FALSE, playlistwin_spause, w - 128, h - 16);
+ button_on_release (playlistwin_spause, (ButtonCB) aud_drct_pause);
+
+ playlistwin_sstop = button_new_small (9, 7);
+ window_put_widget (playlistwin, FALSE, playlistwin_sstop, w - 118, h - 16);
+ button_on_release (playlistwin_sstop, (ButtonCB) aud_drct_stop);
+
+ playlistwin_sfwd = button_new_small (8, 7);
+ window_put_widget (playlistwin, FALSE, playlistwin_sfwd, w - 109, h - 16);
+ button_on_release (playlistwin_sfwd, (ButtonCB) aud_drct_pl_next);
+
+ playlistwin_seject = button_new_small (9, 7);
+ window_put_widget (playlistwin, FALSE, playlistwin_seject, w - 100, h - 16);
+ button_on_release (playlistwin_seject, (ButtonCB) action_play_file);
+
+ playlistwin_sscroll_up = button_new_small (8, 5);
+ window_put_widget (playlistwin, FALSE, playlistwin_sscroll_up, w - 14, h - 35);
+ button_on_release (playlistwin_sscroll_up, (ButtonCB) playlistwin_scroll_up_pushed);
+
+ playlistwin_sscroll_down = button_new_small (8, 5);
+ window_put_widget (playlistwin, FALSE, playlistwin_sscroll_down, w - 14, h - 30);
+ button_on_release (playlistwin_sscroll_down, (ButtonCB) playlistwin_scroll_down_pushed);
+
+ /* resize handles */
+
+ resize_handle = drag_handle_new (20, 20, resize_press, resize_drag);
+ window_put_widget (playlistwin, FALSE, resize_handle, w - 20, h - 20);
+
+ sresize_handle = drag_handle_new (9, PLAYLISTWIN_SHADED_HEIGHT, resize_press, resize_drag);
+ window_put_widget (playlistwin, TRUE, sresize_handle, w - 31, 0);
+
+ /* lower button row */
+
+ button_add = button_new_small (25, 18);
+ window_put_widget (playlistwin, FALSE, button_add, 12, h - 29);
+ button_on_press (button_add, button_add_cb);
+
+ button_sub = button_new_small (25, 18);
+ window_put_widget (playlistwin, FALSE, button_sub, 40, h - 29);
+ button_on_press (button_sub, button_sub_cb);
+
+ button_sel = button_new_small (25, 18);
+ window_put_widget (playlistwin, FALSE, button_sel, 68, h - 29);
+ button_on_press (button_sel, button_sel_cb);
+
+ button_misc = button_new_small (25, 18);
+ window_put_widget (playlistwin, FALSE, button_misc, 100, h - 29);
+ button_on_press (button_misc, button_misc_cb);
+
+ button_list = button_new_small (23, 18);
+ window_put_widget (playlistwin, FALSE, button_list, w - 46, h - 29);
+ button_on_press (button_list, button_list_cb);
+}
+
+static void pl_win_draw (GtkWidget * window, cairo_t * cr)
+{
+ if (aud_get_bool ("skins", "playlist_shaded"))
+ skin_draw_playlistwin_shaded (cr, config.playlist_width, TRUE);
+ else
+ skin_draw_playlistwin_frame (cr, config.playlist_width,
+ config.playlist_height, TRUE);
+}
+
+static void
+playlistwin_create_window(void)
+{
+ gboolean shaded = aud_get_bool ("skins", "playlist_shaded");
+
+ playlistwin = window_new (& config.playlist_x, & config.playlist_y,
+ config.playlist_width, shaded ? PLAYLISTWIN_SHADED_HEIGHT :
+ config.playlist_height, FALSE, shaded, pl_win_draw);
+
+ gtk_window_set_title(GTK_WINDOW(playlistwin), _("Audacious Playlist Editor"));
+
+ gtk_window_set_transient_for(GTK_WINDOW(playlistwin),
+ GTK_WINDOW(mainwin));
+ gtk_window_set_skip_pager_hint(GTK_WINDOW(playlistwin), TRUE);
+ gtk_window_set_skip_taskbar_hint(GTK_WINDOW(playlistwin), TRUE);
+
+ gtk_widget_add_events(playlistwin, GDK_POINTER_MOTION_MASK |
+ GDK_FOCUS_CHANGE_MASK | GDK_BUTTON_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_SCROLL_MASK | GDK_VISIBILITY_NOTIFY_MASK);
+
+ g_signal_connect (playlistwin, "delete-event", (GCallback) handle_window_close, nullptr);
+ g_signal_connect (playlistwin, "button-press-event", (GCallback) playlistwin_press, nullptr);
+ g_signal_connect (playlistwin, "scroll-event", (GCallback) playlistwin_scrolled, nullptr);
+ g_signal_connect (playlistwin, "key-press-event", (GCallback) mainwin_keypress, nullptr);
+
+ drag_dest_set (playlistwin);
+ drop_position = -1;
+
+ g_signal_connect (playlistwin, "drag-motion", (GCallback) drag_motion, nullptr);
+ g_signal_connect (playlistwin, "drag-leave", (GCallback) drag_leave, nullptr);
+ g_signal_connect (playlistwin, "drag-drop", (GCallback) drag_drop, nullptr);
+ g_signal_connect (playlistwin, "drag-data-received", (GCallback) drag_data_received, nullptr);
+}
+
+static void get_title (void)
+{
+ int playlists = aud_playlist_count ();
+
+ g_free (active_title);
+
+ if (playlists > 1)
+ {
+ String title = aud_playlist_get_title (active_playlist);
+ active_title = g_strdup_printf (_("%s (%d of %d)"),
+ (const char *) title, 1 + active_playlist, playlists);
+ }
+ else
+ active_title = nullptr;
+}
+
+static void update_cb (void * unused, void * another)
+{
+ int old = active_playlist;
+
+ active_playlist = aud_playlist_get_active ();
+ active_length = aud_playlist_entry_count (active_playlist);
+ get_title ();
+
+ if (active_playlist != old)
+ {
+ ui_skinned_playlist_scroll_to (playlistwin_list, 0);
+ song_changed = TRUE;
+ }
+
+ if (song_changed)
+ {
+ ui_skinned_playlist_set_focused (playlistwin_list,
+ aud_playlist_get_position (active_playlist));
+ song_changed = FALSE;
+ }
+
+ real_update ();
+}
+
+static void follow_cb (void * data, void * another)
+{
+ int list = aud::from_ptr<int> (data);
+ aud_playlist_select_all (list, FALSE);
+
+ int row = aud_playlist_get_position (list);
+ if (row >= 0)
+ aud_playlist_entry_set_selected (list, row, TRUE);
+
+ if (list == active_playlist)
+ song_changed = TRUE;
+}
+
+void
+playlistwin_create(void)
+{
+ active_playlist = aud_playlist_get_active ();
+ active_length = aud_playlist_entry_count (active_playlist);
+ active_title = nullptr;
+ get_title ();
+
+ playlistwin_create_window();
+
+ playlistwin_create_widgets();
+ window_show_all (playlistwin);
+
+ gtk_window_add_accel_group ((GtkWindow *) playlistwin, menu_get_accel_group ());
+
+ aud_playlist_select_all (active_playlist, FALSE);
+
+ int row = aud_playlist_get_position (active_playlist);
+ if (row >= 0)
+ aud_playlist_entry_set_selected (active_playlist, row, TRUE);
+
+ ui_skinned_playlist_set_focused (playlistwin_list, row);
+
+ song_changed = FALSE;
+
+ hook_associate ("playlist position", follow_cb, nullptr);
+ hook_associate ("playlist activate", update_cb, nullptr);
+ hook_associate ("playlist update", update_cb, nullptr);
+}
+
+void playlistwin_unhook (void)
+{
+ hook_dissociate ("playlist position", follow_cb);
+ hook_dissociate ("playlist activate", update_cb);
+ hook_dissociate ("playlist update", update_cb);
+ g_free (active_title);
+ active_title = nullptr;
+}
+
+void action_playlist_track_info(void)
+{
+ playlistwin_fileinfo();
+}
+
+void action_queue_toggle (void)
+{
+ int focus = aud_playlist_get_focus (active_playlist);
+ if (focus == -1)
+ return;
+
+ /* make sure focused row is selected */
+ if (! aud_playlist_entry_get_selected (active_playlist, focus))
+ {
+ aud_playlist_select_all (active_playlist, false);
+ aud_playlist_entry_set_selected (active_playlist, focus, true);
+ }
+
+ int at = aud_playlist_queue_find_entry (active_playlist, focus);
+
+ if (at == -1)
+ aud_playlist_queue_insert_selected (active_playlist, -1);
+ else
+ aud_playlist_queue_delete_selected (active_playlist);
+}
+
+void action_playlist_sort_by_track_number (void)
+{
+ aud_playlist_sort_by_scheme (active_playlist, Playlist::Track);
+}
+
+void action_playlist_sort_by_title (void)
+{
+ aud_playlist_sort_by_scheme (active_playlist, Playlist::Title);
+}
+
+void action_playlist_sort_by_album (void)
+{
+ aud_playlist_sort_by_scheme (active_playlist, Playlist::Album);
+}
+
+void action_playlist_sort_by_artist (void)
+{
+ aud_playlist_sort_by_scheme (active_playlist, Playlist::Artist);
+}
+
+void action_playlist_sort_by_album_artist (void)
+{
+ aud_playlist_sort_by_scheme (active_playlist, Playlist::AlbumArtist);
+}
+
+void action_playlist_sort_by_full_path (void)
+{
+ aud_playlist_sort_by_scheme (active_playlist, Playlist::Path);
+}
+
+void action_playlist_sort_by_date (void)
+{
+ aud_playlist_sort_by_scheme (active_playlist, Playlist::Date);
+}
+
+void action_playlist_sort_by_length (void)
+{
+ aud_playlist_sort_by_scheme (active_playlist, Playlist::Length);
+}
+
+void action_playlist_sort_by_genre (void)
+{
+ aud_playlist_sort_by_scheme (active_playlist, Playlist::Genre);
+}
+
+void action_playlist_sort_by_filename (void)
+{
+ aud_playlist_sort_by_scheme (active_playlist, Playlist::Filename);
+}
+
+void action_playlist_sort_by_custom_title (void)
+{
+ aud_playlist_sort_by_scheme (active_playlist, Playlist::FormattedTitle);
+}
+
+void action_playlist_sort_selected_by_track_number (void)
+{
+ aud_playlist_sort_selected_by_scheme (active_playlist, Playlist::Track);
+}
+
+void action_playlist_sort_selected_by_title (void)
+{
+ aud_playlist_sort_selected_by_scheme (active_playlist, Playlist::Title);
+}
+
+void action_playlist_sort_selected_by_album (void)
+{
+ aud_playlist_sort_selected_by_scheme (active_playlist, Playlist::Album);
+}
+
+void action_playlist_sort_selected_by_artist (void)
+{
+ aud_playlist_sort_selected_by_scheme (active_playlist, Playlist::Artist);
+}
+
+void action_playlist_sort_selected_by_album_artist (void)
+{
+ aud_playlist_sort_selected_by_scheme (active_playlist, Playlist::AlbumArtist);
+}
+
+void action_playlist_sort_selected_by_length (void)
+{
+ aud_playlist_sort_selected_by_scheme (active_playlist, Playlist::Length);
+}
+
+void action_playlist_sort_selected_by_genre (void)
+{
+ aud_playlist_sort_selected_by_scheme (active_playlist, Playlist::Genre);
+}
+
+void action_playlist_sort_selected_by_full_path (void)
+{
+ aud_playlist_sort_selected_by_scheme (active_playlist, Playlist::Path);
+}
+
+void action_playlist_sort_selected_by_date (void)
+{
+ aud_playlist_sort_selected_by_scheme (active_playlist, Playlist::Date);
+}
+
+void action_playlist_sort_selected_by_filename (void)
+{
+ aud_playlist_sort_selected_by_scheme (active_playlist, Playlist::Filename);
+}
+
+void action_playlist_sort_selected_by_custom_title (void)
+{
+ aud_playlist_sort_selected_by_scheme (active_playlist, Playlist::FormattedTitle);
+}
+
+void action_playlist_randomize_list (void)
+{
+ aud_playlist_randomize (active_playlist);
+}
+
+void action_playlist_reverse_list (void)
+{
+ aud_playlist_reverse (active_playlist);
+}
+
+void action_playlist_clear_queue (void)
+{
+ aud_playlist_queue_delete (active_playlist, 0, aud_playlist_queue_count
+ (active_playlist));
+}
+
+void action_playlist_remove_unavailable (void)
+{
+ aud_playlist_remove_failed (active_playlist);
+}
+
+void action_playlist_remove_dupes_by_title (void)
+{
+ aud_playlist_remove_duplicates_by_scheme (active_playlist, Playlist::Title);
+}
+
+void action_playlist_remove_dupes_by_filename (void)
+{
+ aud_playlist_remove_duplicates_by_scheme (active_playlist, Playlist::Filename);
+}
+
+void action_playlist_remove_dupes_by_full_path (void)
+{
+ aud_playlist_remove_duplicates_by_scheme (active_playlist, Playlist::Path);
+}
+
+void action_playlist_remove_all (void)
+{
+ aud_playlist_entry_delete (active_playlist, 0, aud_playlist_entry_count
+ (active_playlist));
+}
+
+void action_playlist_remove_selected (void)
+{
+ aud_playlist_delete_selected (active_playlist);
+}
+
+void action_playlist_remove_unselected (void)
+{
+ playlistwin_inverse_selection ();
+ aud_playlist_delete_selected (active_playlist);
+ aud_playlist_select_all (active_playlist, TRUE);
+}
+
+void action_playlist_copy (void)
+{
+ GtkClipboard * clip = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ Index<char> list = audgui_urilist_create_from_selected (active_playlist);
+
+ if (! list.len ())
+ return;
+
+ gtk_clipboard_set_text (clip, list.begin (), list.len ());
+}
+
+void action_playlist_cut (void)
+{
+ action_playlist_copy ();
+ action_playlist_remove_selected ();
+}
+
+void action_playlist_paste (void)
+{
+ GtkClipboard * clip = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ char * list = gtk_clipboard_wait_for_text (clip);
+
+ if (list == nullptr)
+ return;
+
+ audgui_urilist_insert (active_playlist,
+ aud_playlist_get_focus (active_playlist), list);
+ g_free (list);
+}
+
+void
+action_playlist_add_files(void)
+{
+ audgui_run_filebrowser(FALSE); /* FALSE = NO_PLAY_BUTTON */
+}
+
+void
+action_playlist_add_url(void)
+{
+ audgui_show_add_url_window (FALSE);
+}
+
+void action_playlist_play (void)
+{
+ aud_playlist_play (aud_playlist_get_active ());
+}
+
+void action_playlist_new (void)
+{
+ int playlist = aud_playlist_count ();
+
+ aud_playlist_insert (playlist);
+ aud_playlist_set_active (playlist);
+}
+
+void action_playlist_prev (void)
+{
+ if (active_playlist > 0)
+ aud_playlist_set_active (active_playlist - 1);
+ else
+ {
+ int count = aud_playlist_count ();
+ if (count > 1)
+ aud_playlist_set_active (count - 1);
+ }
+}
+
+void action_playlist_next (void)
+{
+ int count = aud_playlist_count ();
+
+ if (active_playlist + 1 < count)
+ aud_playlist_set_active (active_playlist + 1);
+ else if (count > 1)
+ aud_playlist_set_active (0);
+}
+
+void action_playlist_rename (void)
+{
+ audgui_show_playlist_rename (active_playlist);
+}
+
+void action_playlist_delete (void)
+{
+ audgui_confirm_playlist_delete (active_playlist);
+}
+
+void
+action_playlist_refresh_list(void)
+{
+ aud_playlist_rescan (active_playlist);
+}
+
+void
+action_playlist_search_and_select(void)
+{
+ playlistwin_select_search();
+}
+
+void
+action_playlist_invert_selection(void)
+{
+ playlistwin_inverse_selection();
+}
+
+void
+action_playlist_select_none(void)
+{
+ playlistwin_select_none();
+}
+
+void
+action_playlist_select_all(void)
+{
+ playlistwin_select_all();
+}
+
+
+static void
+playlistwin_select_search_cbt_cb(GtkWidget *called_cbt, void * other_cbt)
+{
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(called_cbt)) == TRUE)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(other_cbt), FALSE);
+ return;
+}
+
+static gboolean
+playlistwin_select_search_kp_cb(GtkWidget *entry, GdkEventKey *event,
+ void * searchdlg_win)
+{
+ switch (event->keyval)
+ {
+ case GDK_KEY_Return:
+ gtk_dialog_response(GTK_DIALOG(searchdlg_win), GTK_RESPONSE_ACCEPT);
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
diff --git a/src/skins/ui_playlist.h b/src/skins/ui_playlist.h
index 64e3a6af28cd..8d5754a3eea5 100644
--- a/src/skins/ui_playlist.h
+++ b/src/skins/ui_playlist.h
@@ -29,10 +29,10 @@ void playlistwin_update (void);
void playlistwin_create(void);
void playlistwin_unhook (void);
void playlistwin_hide_timer(void);
-void playlistwin_set_time (const gchar * minutes, const gchar * seconds);
+void playlistwin_set_time (const char * minutes, const char * seconds);
-extern gint active_playlist, active_length;
-extern gchar * active_title;
+extern int active_playlist, active_length;
+extern char * active_title;
extern GtkWidget * playlistwin, * playlistwin_list, * playlistwin_sinfo;
#endif /* SKINS_UI_PLAYLIST_H */
diff --git a/src/skins/ui_skin.c b/src/skins/ui_skin.c
deleted file mode 100644
index ec2373c3b0b9..000000000000
--- a/src/skins/ui_skin.c
+++ /dev/null
@@ -1,821 +0,0 @@
-/* Audacious
- * Copyright (C) 2005-2011 Audacious development team.
- *
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- *
- * Based on XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#include <gtk/gtk.h>
-
-#include <audacious/debug.h>
-#include <audacious/misc.h>
-
-#include "plugin.h"
-#include "skins_cfg.h"
-#include "surface.h"
-#include "ui_equalizer.h"
-#include "ui_main.h"
-#include "ui_playlist.h"
-#include "ui_skin.h"
-#include "ui_skinned_number.h"
-#include "ui_skinned_playstatus.h"
-#include "ui_skinned_textbox.h"
-#include "ui_skinned_window.h"
-#include "ui_skinselector.h"
-#include "ui_vis.h"
-#include "util.h"
-
-#define EXTENSION_TARGETS 7
-
-static gchar *ext_targets[EXTENSION_TARGETS] =
-{ "bmp", "xpm", "png", "svg", "gif", "jpg", "jpeg" };
-
-struct _SkinPixmapIdMapping {
- SkinPixmapId id;
- const gchar *name;
- const gchar *alt_name;
- gint width, height;
-};
-
-typedef struct _SkinPixmapIdMapping SkinPixmapIdMapping;
-
-static gboolean skin_load (Skin * skin, const gchar * path);
-
-Skin *active_skin = NULL;
-
-static SkinPixmapIdMapping skin_pixmap_id_map[] = {
- {SKIN_MAIN, "main", NULL, 0, 0},
- {SKIN_CBUTTONS, "cbuttons", NULL, 0, 0},
- {SKIN_SHUFREP, "shufrep", NULL, 0, 0},
- {SKIN_TEXT, "text", NULL, 0, 0},
- {SKIN_TITLEBAR, "titlebar", NULL, 0, 0},
- {SKIN_VOLUME, "volume", NULL, 0, 0},
- {SKIN_BALANCE, "balance", "volume", 0, 0},
- {SKIN_MONOSTEREO, "monoster", NULL, 0, 0},
- {SKIN_PLAYPAUSE, "playpaus", NULL, 0, 0},
- {SKIN_NUMBERS, "nums_ex", "numbers", 0, 0},
- {SKIN_POSBAR, "posbar", NULL, 0, 0},
- {SKIN_EQMAIN, "eqmain", NULL, 0, 0},
- {SKIN_PLEDIT, "pledit", NULL, 0, 0},
- {SKIN_EQ_EX, "eq_ex", NULL, 0, 0}
-};
-
-static guint skin_pixmap_id_map_size = ARRAY_LEN(skin_pixmap_id_map);
-
-static const guint32 default_vis_colors[24] = {
- COLOR (9, 34, 53),
- COLOR (10, 18, 26),
- COLOR (0, 54, 108),
- COLOR (0, 58, 116),
- COLOR (0, 62, 124),
- COLOR (0, 66, 132),
- COLOR (0, 70, 140),
- COLOR (0, 74, 148),
- COLOR (0, 78, 156),
- COLOR (0, 82, 164),
- COLOR (0, 86, 172),
- COLOR (0, 92, 184),
- COLOR (0, 98, 196),
- COLOR (0, 104, 208),
- COLOR (0, 110, 220),
- COLOR (0, 116, 232),
- COLOR (0, 122, 244),
- COLOR (0, 128, 255),
- COLOR (0, 128, 255),
- COLOR (0, 104, 208),
- COLOR (0, 80, 160),
- COLOR (0, 56, 112),
- COLOR (0, 32, 64),
- COLOR (200, 200, 200)
-};
-
-gboolean active_skin_load (const gchar * path)
-{
- AUDDBG("%s\n", path);
- g_return_val_if_fail(active_skin != NULL, FALSE);
-
- if (!skin_load(active_skin, path)) {
- AUDDBG("loading failed\n");
- return FALSE;
- }
-
- mainwin_refresh_hints ();
- textbox_update_all ();
- ui_vis_set_colors ();
- gtk_widget_queue_draw (mainwin);
- gtk_widget_queue_draw (equalizerwin);
- gtk_widget_queue_draw (playlistwin);
-
- aud_set_str ("skins", "skin", path);
-
- return TRUE;
-}
-
-static Skin *
-skin_new(void)
-{
- Skin *skin;
- skin = g_new0(Skin, 1);
- return skin;
-}
-
-/**
- * Frees the data associated for skin.
- *
- * Does not free skin itself or lock variable so that the skin can immediately
- * populated with new skin data if needed.
- */
-static void
-skin_free(Skin * skin)
-{
- gint i;
-
- g_return_if_fail(skin != NULL);
-
- for (i = 0; i < SKIN_PIXMAP_COUNT; i++)
- {
- if (skin->pixmaps[i])
- {
- cairo_surface_destroy (skin->pixmaps[i]);
- skin->pixmaps[i] = NULL;
- }
- }
-
- for (i = 0; i < SKIN_MASK_COUNT; i++) {
- if (skin->masks[i])
- cairo_region_destroy (skin->masks[i]);
- skin->masks[i] = NULL;
- }
-
- g_free(skin->path);
- skin->path = NULL;
-}
-
-static void
-skin_destroy(Skin * skin)
-{
- g_return_if_fail(skin != NULL);
- skin_free(skin);
- g_free(skin);
-}
-
-static const SkinPixmapIdMapping *
-skin_pixmap_id_lookup(guint id)
-{
- guint i;
-
- for (i = 0; i < skin_pixmap_id_map_size; i++) {
- if (id == skin_pixmap_id_map[i].id) {
- return &skin_pixmap_id_map[i];
- }
- }
-
- return NULL;
-}
-
-static gchar * skin_pixmap_locate (const gchar * dirname, gchar * * basenames)
-{
- gchar * filename = NULL;
- gint i;
-
- for (i = 0; basenames[i] != NULL; i ++)
- {
- if ((filename = find_file_case_path (dirname, basenames[i])) != NULL)
- break;
- }
-
- return filename;
-}
-
-/**
- * Creates possible file names for a pixmap.
- *
- * Basically this makes list of all possible file names that pixmap data
- * can be found from by using the static ext_targets variable to get all
- * possible extensions that pixmap file might have.
- */
-static gchar **
-skin_pixmap_create_basenames(const SkinPixmapIdMapping * pixmap_id_mapping)
-{
- gchar **basenames = g_malloc0(sizeof(gchar*) * (EXTENSION_TARGETS * 2 + 1));
- gint i, y;
-
- // Create list of all possible image formats that can be loaded
- for (i = 0, y = 0; i < EXTENSION_TARGETS; i++, y++)
- {
- basenames[y] =
- g_strdup_printf("%s.%s", pixmap_id_mapping->name, ext_targets[i]);
-
- if (pixmap_id_mapping->alt_name)
- basenames[++y] =
- g_strdup_printf("%s.%s", pixmap_id_mapping->alt_name,
- ext_targets[i]);
- }
-
- return basenames;
-}
-
-/**
- * Frees the data allocated by skin_pixmap_create_basenames
- */
-static void
-skin_pixmap_free_basenames(gchar ** basenames)
-{
- int i;
- for (i = 0; basenames[i] != NULL; i++)
- {
- g_free(basenames[i]);
- basenames[i] = NULL;
- }
- g_free(basenames);
-}
-
-/**
- * Locates a pixmap file for skin.
- */
-static gchar *
-skin_pixmap_locate_basenames(const Skin * skin,
- const SkinPixmapIdMapping * pixmap_id_mapping,
- const gchar * path_p)
-{
- gchar *filename = NULL;
- const gchar *path = path_p ? path_p : skin->path;
- gchar **basenames = skin_pixmap_create_basenames(pixmap_id_mapping);
-
- filename = skin_pixmap_locate(path, basenames);
-
- skin_pixmap_free_basenames(basenames);
-
- if (! filename)
- fprintf (stderr, "Skin does not contain a \"%s\" pixmap.\n",
- pixmap_id_mapping->name);
-
- return filename;
-}
-
-
-static gboolean
-skin_load_pixmap_id(Skin * skin, SkinPixmapId id, const gchar * path_p)
-{
- const SkinPixmapIdMapping *pixmap_id_mapping;
- gchar *filename;
-
- g_return_val_if_fail(skin != NULL, FALSE);
- g_return_val_if_fail(id < SKIN_PIXMAP_COUNT, FALSE);
- g_return_val_if_fail(! skin->pixmaps[id], FALSE);
-
- pixmap_id_mapping = skin_pixmap_id_lookup(id);
- g_return_val_if_fail(pixmap_id_mapping != NULL, FALSE);
-
- filename = skin_pixmap_locate_basenames(skin, pixmap_id_mapping, path_p);
-
- if (filename == NULL)
- return FALSE;
-
- skin->pixmaps[id] = surface_new_from_file (filename);
-
- g_free (filename);
- return skin->pixmaps[id] ? TRUE : FALSE;
-}
-
-static gint color_diff (guint32 a, guint32 b)
-{
- return abs (COLOR_R (a) - COLOR_R (b)) + abs (COLOR_G (a) - COLOR_G (b)) +
- abs (COLOR_B (a) - COLOR_B (b));
-}
-
-static void skin_get_textcolors (Skin * skin, cairo_surface_t * s)
-{
- /*
- * Try to extract reasonable background and foreground colors
- * from the font pixmap
- */
-
- /* Get a pixel from the middle of the space character */
- skin->colors[SKIN_TEXTBG] = surface_get_pixel (s, 152, 3);
-
- gint max_d = -1;
- for (gint y = 0; y < 6; y ++)
- {
- for (gint x = 1; x < 150; x ++)
- {
- gint c = surface_get_pixel (s, x, y);
- gint d = color_diff (skin->colors[SKIN_TEXTBG], c);
- if (d > max_d)
- {
- skin->colors[SKIN_TEXTFG] = c;
- max_d = d;
- }
- }
- }
-}
-
-gboolean
-init_skins(const gchar * path)
-{
- active_skin = skin_new();
-
- active_skin->properties = skin_default_hints;
-
- /* create the windows if they haven't been created yet, needed for bootstrapping */
- if (mainwin == NULL)
- {
- mainwin_create();
- equalizerwin_create();
- playlistwin_create();
- }
-
- if (! path || ! active_skin_load (path))
- {
- if (path != NULL)
- AUDDBG("Unable to load skin (%s), trying default...\n", path);
- else
- AUDDBG("Skin not defined: trying default...\n");
-
- /* can't load configured skin, retry with default */
- gchar * def = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "Skins"
- G_DIR_SEPARATOR_S "Default", aud_get_path (AUD_PATH_DATA_DIR));
-
- if (! active_skin_load (def))
- {
- AUDDBG ("Unable to load default skin (%s)! Giving up.\n", def);
- g_free (def);
- return FALSE;
- }
-
- g_free (def);
- }
-
- return TRUE;
-}
-
-void cleanup_skins()
-{
- skin_destroy(active_skin);
- active_skin = NULL;
-
- gtk_widget_destroy (mainwin);
- mainwin = NULL;
- gtk_widget_destroy (playlistwin);
- playlistwin = NULL;
- gtk_widget_destroy (equalizerwin);
- equalizerwin = NULL;
-}
-
-static void skin_load_viscolor (Skin * skin, const gchar * path)
-{
- memcpy (skin->vis_colors, default_vis_colors, sizeof skin->vis_colors);
-
- VFSFile * file = open_local_file_nocase (path, "viscolor.txt");
- if (! file)
- return;
-
- void * buffer = NULL;
- vfs_file_read_all (file, & buffer, NULL);
- vfs_fclose (file);
-
- char * string = buffer;
-
- for (int line = 0; string && line < 24; line ++)
- {
- char * next = text_parse_line (string);
- GArray * array = string_to_garray (string);
-
- if (array->len >= 3)
- skin->vis_colors[line] = COLOR (g_array_index (array, gint, 0),
- g_array_index (array, gint, 1), g_array_index (array, gint, 2));
-
- g_array_free (array, TRUE);
- string = next;
- }
-
- g_free (buffer);
-}
-
-static void
-skin_numbers_generate_dash(Skin * skin)
-{
- g_return_if_fail(skin != NULL);
-
- cairo_surface_t * old = skin->pixmaps[SKIN_NUMBERS];
- if (! old || cairo_image_surface_get_width (old) < 99)
- return;
-
- gint h = cairo_image_surface_get_height (old);
- cairo_surface_t * new = surface_new (108, h);
-
- surface_copy_rect (old, 0, 0, 99, h, new, 0, 0);
- surface_copy_rect (old, 90, 0, 9, h, new, 99, 0);
- surface_copy_rect (old, 20, 6, 5, 1, new, 101, 6);
-
- cairo_surface_destroy (old);
- skin->pixmaps[SKIN_NUMBERS] = new;
-}
-
-static gboolean
-skin_load_pixmaps(Skin * skin, const gchar * path)
-{
- AUDDBG("Loading pixmaps in %s\n", path);
-
- for (gint i = 0; i < SKIN_PIXMAP_COUNT; i++)
- if (! skin_load_pixmap_id (skin, i, path))
- return FALSE;
-
- if (skin->pixmaps[SKIN_TEXT])
- skin_get_textcolors (skin, skin->pixmaps[SKIN_TEXT]);
-
- if (skin->pixmaps[SKIN_NUMBERS] && cairo_image_surface_get_width
- (skin->pixmaps[SKIN_NUMBERS]) < 108)
- skin_numbers_generate_dash (skin);
-
- skin_load_pl_colors (skin, path);
- skin_load_masks (skin, path);
- skin_load_viscolor (skin, path);
-
- return TRUE;
-}
-
-/**
- * Checks if all pixmap files exist that skin needs.
- */
-static gboolean
-skin_check_pixmaps(const Skin * skin, const gchar * skin_path)
-{
- guint i;
- for (i = 0; i < SKIN_PIXMAP_COUNT; i++)
- {
- gchar *filename = skin_pixmap_locate_basenames(skin,
- skin_pixmap_id_lookup(i),
- skin_path);
- if (!filename)
- return FALSE;
- g_free(filename);
- }
- return TRUE;
-}
-
-static gboolean
-skin_load_nolock(Skin * skin, const gchar * path, gboolean force)
-{
- gchar *newpath, *skin_path;
- int archive = 0;
-
- AUDDBG("Attempt to load skin \"%s\"\n", path);
-
- g_return_val_if_fail(skin != NULL, FALSE);
- g_return_val_if_fail(path != NULL, FALSE);
-
- if (! g_file_test (path, G_FILE_TEST_EXISTS))
- return FALSE;
-
- if(force) AUDDBG("reloading forced!\n");
- if (!force && skin->path && !strcmp(skin->path, path)) {
- AUDDBG("skin %s already loaded\n", path);
- return FALSE;
- }
-
- if (file_is_archive(path)) {
- AUDDBG("Attempt to load archive\n");
- if (!(skin_path = archive_decompress(path))) {
- AUDDBG("Unable to extract skin archive (%s)\n", path);
- return FALSE;
- }
- archive = 1;
- } else {
- skin_path = g_strdup(path);
- }
-
- // Check if skin path has all necessary files.
- if (!skin_check_pixmaps(skin, skin_path)) {
- if(archive) del_directory(skin_path);
- AUDDBG("Skin path (%s) doesn't have all wanted pixmaps\n", skin_path);
- g_free(skin_path);
- return FALSE;
- }
-
- // skin_free() frees skin->path and variable path can actually be skin->path
- // and we want to get the path before possibly freeing it.
- newpath = g_strdup(path);
- skin_free(skin);
- skin->path = newpath;
-
- skin_load_hints (skin, skin_path);
-
- if (!skin_load_pixmaps(skin, skin_path)) {
- if(archive) del_directory(skin_path);
- g_free(skin_path);
- AUDDBG("Skin loading failed\n");
- return FALSE;
- }
-
- if(archive) del_directory(skin_path);
- g_free(skin_path);
-
- mainwin_set_shape ();
- equalizerwin_set_shape ();
-
- return TRUE;
-}
-
-void skin_install_skin (const gchar * path)
-{
-#ifdef S_IRGRP
- const mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
-#else
- const mode_t mode = S_IRWXU;
-#endif
-
- if (g_mkdir_with_parents (skins_paths[SKINS_PATH_USER_SKIN_DIR], mode) < 0)
- {
- fprintf (stderr, "Failed to create %s: %s\n",
- skins_paths[SKINS_PATH_USER_SKIN_DIR], strerror (errno));
- return;
- }
-
- GError * err = 0;
- gchar * data;
- gsize len;
-
- if (! g_file_get_contents (path, & data, & len, & err))
- {
- fprintf (stderr, "Failed to read %s: %s\n", path, err->message);
- g_error_free (err);
- return;
- }
-
- gchar * base = g_path_get_basename (path);
- gchar * target = g_build_filename (skins_paths[SKINS_PATH_USER_SKIN_DIR], base, NULL);
-
- if (! g_file_set_contents (target, data, len, & err))
- {
- fprintf (stderr, "Failed to write %s: %s\n", path, err->message);
- g_error_free (err);
- g_free (data);
- g_free (base);
- g_free (target);
- return;
- }
-
- g_free (data);
- g_free (base);
- g_free (target);
-}
-
-static gboolean skin_load (Skin * skin, const gchar * path)
-{
- gboolean ret;
-
- g_return_val_if_fail(skin != NULL, FALSE);
-
- if (!path)
- return FALSE;
-
- ret = skin_load_nolock(skin, path, FALSE);
-
- if(!ret) {
- AUDDBG("loading failed\n");
- return FALSE; /* don't try to update anything if loading failed --asphyx */
- }
-
- if (skin->pixmaps[SKIN_NUMBERS])
- {
- gint h = cairo_image_surface_get_height (skin->pixmaps[SKIN_NUMBERS]);
- ui_skinned_number_set_size (mainwin_minus_num, 9, h);
- ui_skinned_number_set_size (mainwin_10min_num, 9, h);
- ui_skinned_number_set_size (mainwin_min_num, 9, h);
- ui_skinned_number_set_size (mainwin_10sec_num, 9, h);
- ui_skinned_number_set_size (mainwin_sec_num, 9, h);
- }
-
- if (skin->pixmaps[SKIN_PLAYPAUSE])
- ui_skinned_playstatus_set_size (mainwin_playstatus, 11,
- cairo_image_surface_get_height (skin->pixmaps[SKIN_PLAYPAUSE]));
-
- return TRUE;
-}
-
-void skin_draw_pixbuf (cairo_t * cr, SkinPixmapId id, gint xsrc, gint ysrc, gint
- xdest, gint ydest, gint width, gint height)
-{
- if (! active_skin->pixmaps[id])
- return;
-
- cairo_set_source_surface (cr, active_skin->pixmaps[id], xdest - xsrc,
- ydest - ysrc);
- cairo_rectangle (cr, xdest, ydest, width, height);
- cairo_fill (cr);
-}
-
-void skin_get_eq_spline_colors (Skin * skin, guint32 colors[19])
-{
- if (! skin->pixmaps[SKIN_EQMAIN])
- {
- memset (colors, 0, sizeof (guint32) * 19);
- return;
- }
-
- for (gint i = 0; i < 19; i ++)
- colors[i] = surface_get_pixel (skin->pixmaps[SKIN_EQMAIN], 115, i + 294);
-}
-
-static void skin_draw_playlistwin_frame_top (cairo_t * cr, gint width, gint
- height, gboolean focus)
-{
- /* The title bar skin consists of 2 sets of 4 images, 1 set
- * for focused state and the other for unfocused. The 4 images
- * are:
- *
- * a. right corner (25,20)
- * b. left corner (25,20)
- * c. tiler (25,20)
- * d. title (100,20)
- *
- * min allowed width = 100+25+25 = 150
- */
-
- gint i, y, c;
-
- /* get y offset of the pixmap set to use */
- if (focus)
- y = 0;
- else
- y = 21;
-
- /* left corner */
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 0, y, 0, 0, 25, 20);
-
- /* titlebar title */
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 26, y, (width - 100) / 2, 0, 100, 20);
-
- /* titlebar right corner */
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 153, y, width - 25, 0, 25, 20);
-
- /* tile draw the remaining frame */
-
- /* compute tile count */
- c = (width - (100 + 25 + 25)) / 25;
-
- for (i = 0; i < c / 2; i++) {
- /* left of title */
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 127, y, 25 + i * 25, 0, 25, 20);
-
- /* right of title */
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 127, y, (width + 100) / 2 + i * 25,
- 0, 25, 20);
- }
-
- if (c & 1) {
- /* Odd tile count, so one remaining to draw. Here we split
- * it into two and draw half on either side of the title */
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 127, y, ((c / 2) * 25) + 25, 0, 12,
- 20);
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 127, y, (width / 2) + ((c / 2) * 25)
- + 50, 0, 13, 20);
- }
-}
-
-static void skin_draw_playlistwin_frame_bottom (cairo_t * cr, gint width, gint
- height, gboolean focus)
-{
- /* The bottom frame skin consists of 1 set of 4 images. The 4
- * images are:
- *
- * a. left corner with menu buttons (125,38)
- * b. visualization window (75,38)
- * c. right corner with play buttons (150,38)
- * d. frame tile (25,38)
- *
- * (min allowed width = 125+150+25=300
- */
-
- gint i, c;
-
- /* bottom left corner (menu buttons) */
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 0, 72, 0, height - 38, 125, 38);
-
- c = (width - 275) / 25;
-
- /* draw visualization window, if width allows */
- if (c >= 3) {
- c -= 3;
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 205, 0, width - (150 + 75), height -
- 38, 75, 38);
- }
-
- /* Bottom right corner (playbuttons etc) */
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 126, 72, width - 150, height - 38, 150,
- 38);
-
- /* Tile draw the remaining undrawn portions */
- for (i = 0; i < c; i++)
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 179, 0, 125 + i * 25, height - 38,
- 25, 38);
-}
-
-static void skin_draw_playlistwin_frame_sides (cairo_t * cr, gint width, gint
- height, gboolean focus)
-{
- /* The side frames consist of 2 tile images. 1 for the left, 1 for
- * the right.
- * a. left (12,29)
- * b. right (19,29)
- */
-
- gint i;
-
- /* frame sides */
- for (i = 0; i < (height - (20 + 38)) / 29; i++) {
- /* left */
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 0, 42, 0, 20 + i * 29, 12, 29);
-
- /* right */
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 32, 42, width - 19, 20 + i * 29, 19,
- 29);
- }
-}
-
-void skin_draw_playlistwin_frame (cairo_t * cr, gint width, gint height,
- gboolean focus)
-{
- skin_draw_playlistwin_frame_top (cr, width, height, focus);
- skin_draw_playlistwin_frame_bottom (cr, width, height, focus);
- skin_draw_playlistwin_frame_sides (cr, width, height, focus);
-}
-
-void skin_draw_playlistwin_shaded (cairo_t * cr, gint width, gboolean focus)
-{
- /* The shade mode titlebar skin consists of 4 images:
- * a) left corner offset (72,42) size (25,14)
- * b) right corner, focused offset (99,57) size (50,14)
- * c) right corner, unfocused offset (99,42) size (50,14)
- * d) bar tile offset (72,57) size (25,14)
- */
-
- gint i;
-
- /* left corner */
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 72, 42, 0, 0, 25, 14);
-
- /* bar tile */
- for (i = 0; i < (width - 75) / 25; i++)
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 72, 57, (i * 25) + 25, 0, 25, 14);
-
- /* right corner */
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 99, focus ? 42 : 57, width - 50, 0, 50,
- 14);
-}
-
-void skin_draw_mainwin_titlebar (cairo_t * cr, gboolean shaded, gboolean focus)
-{
- /* The titlebar skin consists of 2 sets of 2 images, one for for
- * shaded and the other for unshaded mode, giving a total of 4.
- * The images are exactly 275x14 pixels, aligned and arranged
- * vertically on each other in the pixmap in the following order:
- *
- * a) unshaded, focused offset (27, 0)
- * b) unshaded, unfocused offset (27, 15)
- * c) shaded, focused offset (27, 29)
- * d) shaded, unfocused offset (27, 42)
- */
-
- gint y_offset;
-
- if (shaded) {
- if (focus)
- y_offset = 29;
- else
- y_offset = 42;
- }
- else {
- if (focus)
- y_offset = 0;
- else
- y_offset = 15;
- }
-
- skin_draw_pixbuf (cr, SKIN_TITLEBAR, 27, y_offset, 0, 0,
- active_skin->properties.mainwin_width, MAINWIN_TITLEBAR_HEIGHT);
-}
diff --git a/src/skins/ui_skin.cc b/src/skins/ui_skin.cc
new file mode 100644
index 000000000000..d85811447022
--- /dev/null
+++ b/src/skins/ui_skin.cc
@@ -0,0 +1,809 @@
+/* Audacious
+ * Copyright (C) 2005-2011 Audacious development team.
+ *
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ *
+ * Based on XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <gtk/gtk.h>
+
+#include <libaudcore/runtime.h>
+#include <libaudcore/runtime.h>
+
+#include "plugin.h"
+#include "skins_cfg.h"
+#include "surface.h"
+#include "ui_equalizer.h"
+#include "ui_main.h"
+#include "ui_playlist.h"
+#include "ui_skin.h"
+#include "ui_skinned_number.h"
+#include "ui_skinned_playstatus.h"
+#include "ui_skinned_textbox.h"
+#include "ui_skinned_window.h"
+#include "ui_skinselector.h"
+#include "ui_vis.h"
+#include "util.h"
+
+#define EXTENSION_TARGETS 7
+
+static const char *ext_targets[EXTENSION_TARGETS] =
+{ "bmp", "xpm", "png", "svg", "gif", "jpg", "jpeg" };
+
+struct _SkinPixmapIdMapping {
+ SkinPixmapId id;
+ const char *name;
+ const char *alt_name;
+ int width, height;
+};
+
+typedef struct _SkinPixmapIdMapping SkinPixmapIdMapping;
+
+static gboolean skin_load (Skin * skin, const char * path);
+
+Skin *active_skin = nullptr;
+
+static SkinPixmapIdMapping skin_pixmap_id_map[] = {
+ {SKIN_MAIN, "main", nullptr, 0, 0},
+ {SKIN_CBUTTONS, "cbuttons", nullptr, 0, 0},
+ {SKIN_SHUFREP, "shufrep", nullptr, 0, 0},
+ {SKIN_TEXT, "text", nullptr, 0, 0},
+ {SKIN_TITLEBAR, "titlebar", nullptr, 0, 0},
+ {SKIN_VOLUME, "volume", nullptr, 0, 0},
+ {SKIN_BALANCE, "balance", "volume", 0, 0},
+ {SKIN_MONOSTEREO, "monoster", nullptr, 0, 0},
+ {SKIN_PLAYPAUSE, "playpaus", nullptr, 0, 0},
+ {SKIN_NUMBERS, "nums_ex", "numbers", 0, 0},
+ {SKIN_POSBAR, "posbar", nullptr, 0, 0},
+ {SKIN_EQMAIN, "eqmain", nullptr, 0, 0},
+ {SKIN_PLEDIT, "pledit", nullptr, 0, 0},
+ {SKIN_EQ_EX, "eq_ex", nullptr, 0, 0}
+};
+
+static const uint32_t default_vis_colors[24] = {
+ COLOR (9, 34, 53),
+ COLOR (10, 18, 26),
+ COLOR (0, 54, 108),
+ COLOR (0, 58, 116),
+ COLOR (0, 62, 124),
+ COLOR (0, 66, 132),
+ COLOR (0, 70, 140),
+ COLOR (0, 74, 148),
+ COLOR (0, 78, 156),
+ COLOR (0, 82, 164),
+ COLOR (0, 86, 172),
+ COLOR (0, 92, 184),
+ COLOR (0, 98, 196),
+ COLOR (0, 104, 208),
+ COLOR (0, 110, 220),
+ COLOR (0, 116, 232),
+ COLOR (0, 122, 244),
+ COLOR (0, 128, 255),
+ COLOR (0, 128, 255),
+ COLOR (0, 104, 208),
+ COLOR (0, 80, 160),
+ COLOR (0, 56, 112),
+ COLOR (0, 32, 64),
+ COLOR (200, 200, 200)
+};
+
+gboolean active_skin_load (const char * path)
+{
+ AUDDBG("%s\n", path);
+ g_return_val_if_fail(active_skin != nullptr, FALSE);
+
+ if (!skin_load(active_skin, path)) {
+ AUDDBG("loading failed\n");
+ return FALSE;
+ }
+
+ mainwin_refresh_hints ();
+ textbox_update_all ();
+ ui_vis_set_colors ();
+ gtk_widget_queue_draw (mainwin);
+ gtk_widget_queue_draw (equalizerwin);
+ gtk_widget_queue_draw (playlistwin);
+
+ aud_set_str ("skins", "skin", path);
+
+ return TRUE;
+}
+
+static Skin *
+skin_new(void)
+{
+ Skin *skin;
+ skin = g_new0(Skin, 1);
+ return skin;
+}
+
+/**
+ * Frees the data associated for skin.
+ *
+ * Does not free skin itself or lock variable so that the skin can immediately
+ * populated with new skin data if needed.
+ */
+static void
+skin_free(Skin * skin)
+{
+ int i;
+
+ g_return_if_fail(skin != nullptr);
+
+ for (i = 0; i < SKIN_PIXMAP_COUNT; i++)
+ {
+ if (skin->pixmaps[i])
+ {
+ cairo_surface_destroy (skin->pixmaps[i]);
+ skin->pixmaps[i] = nullptr;
+ }
+ }
+
+ g_free(skin->path);
+ skin->path = nullptr;
+}
+
+static void
+skin_destroy(Skin * skin)
+{
+ g_return_if_fail(skin != nullptr);
+ skin_free(skin);
+ g_free(skin);
+}
+
+static const SkinPixmapIdMapping *
+skin_pixmap_id_lookup(unsigned id)
+{
+ for (auto & info : skin_pixmap_id_map)
+ {
+ if (info.id == id)
+ return & info;
+ }
+
+ return nullptr;
+}
+
+static char * skin_pixmap_locate (const char * dirname, char * * basenames)
+{
+ char * filename = nullptr;
+ int i;
+
+ for (i = 0; basenames[i] != nullptr; i ++)
+ {
+ if ((filename = find_file_case_path (dirname, basenames[i])) != nullptr)
+ break;
+ }
+
+ return filename;
+}
+
+/**
+ * Creates possible file names for a pixmap.
+ *
+ * Basically this makes list of all possible file names that pixmap data
+ * can be found from by using the static ext_targets variable to get all
+ * possible extensions that pixmap file might have.
+ */
+static char **
+skin_pixmap_create_basenames(const SkinPixmapIdMapping * pixmap_id_mapping)
+{
+ char **basenames = g_new0 (char *, EXTENSION_TARGETS * 2 + 1);
+ int i, y;
+
+ // Create list of all possible image formats that can be loaded
+ for (i = 0, y = 0; i < EXTENSION_TARGETS; i++, y++)
+ {
+ basenames[y] =
+ g_strdup_printf("%s.%s", pixmap_id_mapping->name, ext_targets[i]);
+
+ if (pixmap_id_mapping->alt_name)
+ basenames[++y] =
+ g_strdup_printf("%s.%s", pixmap_id_mapping->alt_name,
+ ext_targets[i]);
+ }
+
+ return basenames;
+}
+
+/**
+ * Frees the data allocated by skin_pixmap_create_basenames
+ */
+static void
+skin_pixmap_free_basenames(char ** basenames)
+{
+ int i;
+ for (i = 0; basenames[i] != nullptr; i++)
+ {
+ g_free(basenames[i]);
+ basenames[i] = nullptr;
+ }
+ g_free(basenames);
+}
+
+/**
+ * Locates a pixmap file for skin.
+ */
+static char *
+skin_pixmap_locate_basenames(const Skin * skin,
+ const SkinPixmapIdMapping * pixmap_id_mapping,
+ const char * path_p)
+{
+ char *filename = nullptr;
+ const char *path = path_p ? path_p : skin->path;
+ char **basenames = skin_pixmap_create_basenames(pixmap_id_mapping);
+
+ filename = skin_pixmap_locate(path, basenames);
+
+ skin_pixmap_free_basenames(basenames);
+
+ if (! filename)
+ AUDERR ("Skin does not contain a \"%s\" pixmap.\n",
+ pixmap_id_mapping->name);
+
+ return filename;
+}
+
+
+static gboolean
+skin_load_pixmap_id(Skin * skin, SkinPixmapId id, const char * path_p)
+{
+ const SkinPixmapIdMapping *pixmap_id_mapping;
+ char *filename;
+
+ g_return_val_if_fail(skin != nullptr, FALSE);
+ g_return_val_if_fail(id < SKIN_PIXMAP_COUNT, FALSE);
+ g_return_val_if_fail(! skin->pixmaps[id], FALSE);
+
+ pixmap_id_mapping = skin_pixmap_id_lookup(id);
+ g_return_val_if_fail(pixmap_id_mapping != nullptr, FALSE);
+
+ filename = skin_pixmap_locate_basenames(skin, pixmap_id_mapping, path_p);
+
+ if (filename == nullptr)
+ return FALSE;
+
+ skin->pixmaps[id] = surface_new_from_file (filename);
+
+ g_free (filename);
+ return skin->pixmaps[id] ? TRUE : FALSE;
+}
+
+static int color_diff (uint32_t a, uint32_t b)
+{
+ return abs (COLOR_R (a) - COLOR_R (b)) + abs (COLOR_G (a) - COLOR_G (b)) +
+ abs (COLOR_B (a) - COLOR_B (b));
+}
+
+static void skin_get_textcolors (Skin * skin, cairo_surface_t * s)
+{
+ /*
+ * Try to extract reasonable background and foreground colors
+ * from the font pixmap
+ */
+
+ /* Get a pixel from the middle of the space character */
+ skin->colors[SKIN_TEXTBG] = surface_get_pixel (s, 152, 3);
+
+ int max_d = -1;
+ for (int y = 0; y < 6; y ++)
+ {
+ for (int x = 1; x < 150; x ++)
+ {
+ int c = surface_get_pixel (s, x, y);
+ int d = color_diff (skin->colors[SKIN_TEXTBG], c);
+ if (d > max_d)
+ {
+ skin->colors[SKIN_TEXTFG] = c;
+ max_d = d;
+ }
+ }
+ }
+}
+
+gboolean
+init_skins(const char * path)
+{
+ active_skin = skin_new();
+
+ active_skin->properties = skin_default_hints;
+
+ /* create the windows if they haven't been created yet, needed for bootstrapping */
+ if (mainwin == nullptr)
+ {
+ mainwin_create();
+ equalizerwin_create();
+ playlistwin_create();
+ }
+
+ if (! path || ! active_skin_load (path))
+ {
+ if (path != nullptr)
+ AUDDBG("Unable to load skin (%s), trying default...\n", path);
+ else
+ AUDDBG("Skin not defined: trying default...\n");
+
+ /* can't load configured skin, retry with default */
+ char * def = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "Skins"
+ G_DIR_SEPARATOR_S "Default", aud_get_path (AudPath::DataDir));
+
+ if (! active_skin_load (def))
+ {
+ AUDDBG ("Unable to load default skin (%s)! Giving up.\n", def);
+ g_free (def);
+ return FALSE;
+ }
+
+ g_free (def);
+ }
+
+ return TRUE;
+}
+
+void cleanup_skins()
+{
+ skin_destroy(active_skin);
+ active_skin = nullptr;
+
+ gtk_widget_destroy (mainwin);
+ mainwin = nullptr;
+ gtk_widget_destroy (playlistwin);
+ playlistwin = nullptr;
+ gtk_widget_destroy (equalizerwin);
+ equalizerwin = nullptr;
+}
+
+static void skin_load_viscolor (Skin * skin, const char * path)
+{
+ memcpy (skin->vis_colors, default_vis_colors, sizeof skin->vis_colors);
+
+ VFSFile file = open_local_file_nocase (path, "viscolor.txt");
+ if (! file)
+ return;
+
+ Index<char> buffer = file.read_all ();
+ buffer.append (0); /* null-terminated */
+
+ char * string = buffer.begin ();
+
+ for (int line = 0; string && line < 24; line ++)
+ {
+ char * next = text_parse_line (string);
+ GArray * array = string_to_garray (string);
+
+ if (array->len >= 3)
+ skin->vis_colors[line] = COLOR (g_array_index (array, int, 0),
+ g_array_index (array, int, 1), g_array_index (array, int, 2));
+
+ g_array_free (array, TRUE);
+ string = next;
+ }
+}
+
+static void
+skin_numbers_generate_dash(Skin * skin)
+{
+ g_return_if_fail(skin != nullptr);
+
+ cairo_surface_t * old = skin->pixmaps[SKIN_NUMBERS];
+ if (! old || cairo_image_surface_get_width (old) < 99)
+ return;
+
+ int h = cairo_image_surface_get_height (old);
+ cairo_surface_t * surface = surface_new (108, h);
+
+ surface_copy_rect (old, 0, 0, 99, h, surface, 0, 0);
+ surface_copy_rect (old, 90, 0, 9, h, surface, 99, 0);
+ surface_copy_rect (old, 20, 6, 5, 1, surface, 101, 6);
+
+ cairo_surface_destroy (old);
+ skin->pixmaps[SKIN_NUMBERS] = surface;
+}
+
+static gboolean
+skin_load_pixmaps(Skin * skin, const char * path)
+{
+ AUDDBG("Loading pixmaps in %s\n", path);
+
+ for (int i = 0; i < SKIN_PIXMAP_COUNT; i++)
+ if (! skin_load_pixmap_id (skin, (SkinPixmapId) i, path))
+ return FALSE;
+
+ if (skin->pixmaps[SKIN_TEXT])
+ skin_get_textcolors (skin, skin->pixmaps[SKIN_TEXT]);
+
+ if (skin->pixmaps[SKIN_NUMBERS] && cairo_image_surface_get_width
+ (skin->pixmaps[SKIN_NUMBERS]) < 108)
+ skin_numbers_generate_dash (skin);
+
+ skin_load_pl_colors (skin, path);
+ skin_load_viscolor (skin, path);
+
+ return TRUE;
+}
+
+/**
+ * Checks if all pixmap files exist that skin needs.
+ */
+static gboolean
+skin_check_pixmaps(const Skin * skin, const char * skin_path)
+{
+ unsigned i;
+ for (i = 0; i < SKIN_PIXMAP_COUNT; i++)
+ {
+ char *filename = skin_pixmap_locate_basenames(skin,
+ skin_pixmap_id_lookup(i),
+ skin_path);
+ if (!filename)
+ return FALSE;
+ g_free(filename);
+ }
+ return TRUE;
+}
+
+static gboolean
+skin_load_nolock(Skin * skin, const char * path, gboolean force)
+{
+ char *newpath, *skin_path;
+ int archive = 0;
+
+ AUDDBG("Attempt to load skin \"%s\"\n", path);
+
+ g_return_val_if_fail(skin != nullptr, FALSE);
+ g_return_val_if_fail(path != nullptr, FALSE);
+
+ if (! g_file_test (path, G_FILE_TEST_EXISTS))
+ return FALSE;
+
+ if(force) AUDDBG("reloading forced!\n");
+ if (!force && skin->path && !strcmp(skin->path, path)) {
+ AUDDBG("skin %s already loaded\n", path);
+ return FALSE;
+ }
+
+ if (file_is_archive(path)) {
+ AUDDBG("Attempt to load archive\n");
+ if (!(skin_path = archive_decompress(path))) {
+ AUDDBG("Unable to extract skin archive (%s)\n", path);
+ return FALSE;
+ }
+ archive = 1;
+ } else {
+ skin_path = g_strdup(path);
+ }
+
+ // Check if skin path has all necessary files.
+ if (!skin_check_pixmaps(skin, skin_path)) {
+ if(archive) del_directory(skin_path);
+ AUDDBG("Skin path (%s) doesn't have all wanted pixmaps\n", skin_path);
+ g_free(skin_path);
+ return FALSE;
+ }
+
+ // skin_free() frees skin->path and variable path can actually be skin->path
+ // and we want to get the path before possibly freeing it.
+ newpath = g_strdup(path);
+ skin_free(skin);
+ skin->path = newpath;
+
+ skin_load_hints (skin, skin_path);
+
+ if (!skin_load_pixmaps(skin, skin_path)) {
+ if(archive) del_directory(skin_path);
+ g_free(skin_path);
+ AUDDBG("Skin loading failed\n");
+ return FALSE;
+ }
+
+ GdkRegion * masks[SKIN_MASK_COUNT];
+ skin_load_masks (skin, skin_path, masks);
+ window_set_shapes (mainwin, masks[SKIN_MASK_MAIN], masks[SKIN_MASK_MAIN_SHADE]);
+ window_set_shapes (equalizerwin, masks[SKIN_MASK_EQ], masks[SKIN_MASK_EQ_SHADE]);
+
+ if(archive) del_directory(skin_path);
+ g_free(skin_path);
+
+ return TRUE;
+}
+
+void skin_install_skin (const char * path)
+{
+ GError * err = 0;
+ char * data;
+ size_t len;
+
+ if (! g_file_get_contents (path, & data, & len, & err))
+ {
+ AUDERR ("Failed to read %s: %s\n", path, err->message);
+ g_error_free (err);
+ return;
+ }
+
+ make_directory (skins_paths[SKINS_PATH_USER_SKIN_DIR]);
+
+ char * base = g_path_get_basename (path);
+ char * target = g_build_filename (skins_paths[SKINS_PATH_USER_SKIN_DIR], base, nullptr);
+
+ if (! g_file_set_contents (target, data, len, & err))
+ {
+ AUDERR ("Failed to write %s: %s\n", path, err->message);
+ g_error_free (err);
+ g_free (data);
+ g_free (base);
+ g_free (target);
+ return;
+ }
+
+ g_free (data);
+ g_free (base);
+ g_free (target);
+}
+
+static gboolean skin_load (Skin * skin, const char * path)
+{
+ gboolean ret;
+
+ g_return_val_if_fail(skin != nullptr, FALSE);
+
+ if (!path)
+ return FALSE;
+
+ ret = skin_load_nolock(skin, path, FALSE);
+
+ if(!ret) {
+ AUDDBG("loading failed\n");
+ return FALSE; /* don't try to update anything if loading failed --asphyx */
+ }
+
+ if (skin->pixmaps[SKIN_NUMBERS])
+ {
+ int h = cairo_image_surface_get_height (skin->pixmaps[SKIN_NUMBERS]);
+ ui_skinned_number_set_size (mainwin_minus_num, 9, h);
+ ui_skinned_number_set_size (mainwin_10min_num, 9, h);
+ ui_skinned_number_set_size (mainwin_min_num, 9, h);
+ ui_skinned_number_set_size (mainwin_10sec_num, 9, h);
+ ui_skinned_number_set_size (mainwin_sec_num, 9, h);
+ }
+
+ if (skin->pixmaps[SKIN_PLAYPAUSE])
+ ui_skinned_playstatus_set_size (mainwin_playstatus, 11,
+ cairo_image_surface_get_height (skin->pixmaps[SKIN_PLAYPAUSE]));
+
+ // hide the menurow if it is not present in the skin
+ if (cairo_image_surface_get_width (skin->pixmaps[SKIN_TITLEBAR]) < 344)
+ skin->properties.mainwin_menurow_visible = false;
+
+ // hide the equalizer graph if we have a short eqmain.bmp
+ gtk_widget_set_visible (equalizerwin_graph,
+ cairo_image_surface_get_height (skin->pixmaps[SKIN_EQMAIN]) >= 315);
+
+ return TRUE;
+}
+
+void skin_draw_pixbuf (cairo_t * cr, SkinPixmapId id, int xsrc, int ysrc, int
+ xdest, int ydest, int width, int height)
+{
+ if (! active_skin->pixmaps[id])
+ return;
+
+ cairo_save (cr);
+ cairo_scale (cr, config.scale, config.scale);
+ cairo_set_source_surface (cr, active_skin->pixmaps[id], xdest - xsrc, ydest - ysrc);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_rectangle (cr, xdest, ydest, width, height);
+ cairo_fill (cr);
+ cairo_restore (cr);
+}
+
+void skin_get_eq_spline_colors (Skin * skin, uint32_t colors[19])
+{
+ if (! skin->pixmaps[SKIN_EQMAIN])
+ {
+ memset (colors, 0, sizeof (uint32_t) * 19);
+ return;
+ }
+
+ for (int i = 0; i < 19; i ++)
+ colors[i] = surface_get_pixel (skin->pixmaps[SKIN_EQMAIN], 115, i + 294);
+}
+
+static void skin_draw_playlistwin_frame_top (cairo_t * cr, int width, int
+ height, gboolean focus)
+{
+ /* The title bar skin consists of 2 sets of 4 images, 1 set
+ * for focused state and the other for unfocused. The 4 images
+ * are:
+ *
+ * a. right corner (25,20)
+ * b. left corner (25,20)
+ * c. tiler (25,20)
+ * d. title (100,20)
+ *
+ * min allowed width = 100+25+25 = 150
+ */
+
+ int i, y, c;
+
+ /* get y offset of the pixmap set to use */
+ if (focus)
+ y = 0;
+ else
+ y = 21;
+
+ /* left corner */
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 0, y, 0, 0, 25, 20);
+
+ /* titlebar title */
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 26, y, (width - 100) / 2, 0, 100, 20);
+
+ /* titlebar right corner */
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 153, y, width - 25, 0, 25, 20);
+
+ /* tile draw the remaining frame */
+
+ /* compute tile count */
+ c = (width - (100 + 25 + 25)) / 25;
+
+ for (i = 0; i < c / 2; i++) {
+ /* left of title */
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 127, y, 25 + i * 25, 0, 25, 20);
+
+ /* right of title */
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 127, y, (width + 100) / 2 + i * 25,
+ 0, 25, 20);
+ }
+
+ if (c & 1) {
+ /* Odd tile count, so one remaining to draw. Here we split
+ * it into two and draw half on either side of the title */
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 127, y, ((c / 2) * 25) + 25, 0, 12,
+ 20);
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 127, y, (width / 2) + ((c / 2) * 25)
+ + 50, 0, 13, 20);
+ }
+}
+
+static void skin_draw_playlistwin_frame_bottom (cairo_t * cr, int width, int
+ height, gboolean focus)
+{
+ /* The bottom frame skin consists of 1 set of 4 images. The 4
+ * images are:
+ *
+ * a. left corner with menu buttons (125,38)
+ * b. visualization window (75,38)
+ * c. right corner with play buttons (150,38)
+ * d. frame tile (25,38)
+ *
+ * (min allowed width = 125+150+25=300
+ */
+
+ int i, c;
+
+ /* bottom left corner (menu buttons) */
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 0, 72, 0, height - 38, 125, 38);
+
+ c = (width - 275) / 25;
+
+ /* draw visualization window, if width allows */
+ if (c >= 3) {
+ c -= 3;
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 205, 0, width - (150 + 75), height -
+ 38, 75, 38);
+ }
+
+ /* Bottom right corner (playbuttons etc) */
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 126, 72, width - 150, height - 38, 150,
+ 38);
+
+ /* Tile draw the remaining undrawn portions */
+ for (i = 0; i < c; i++)
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 179, 0, 125 + i * 25, height - 38,
+ 25, 38);
+}
+
+static void skin_draw_playlistwin_frame_sides (cairo_t * cr, int width, int
+ height, gboolean focus)
+{
+ /* The side frames consist of 2 tile images. 1 for the left, 1 for
+ * the right.
+ * a. left (12,29)
+ * b. right (19,29)
+ */
+
+ int i;
+
+ /* frame sides */
+ for (i = 0; i < (height - (20 + 38)) / 29; i++) {
+ /* left */
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 0, 42, 0, 20 + i * 29, 12, 29);
+
+ /* right */
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 32, 42, width - 19, 20 + i * 29, 19,
+ 29);
+ }
+}
+
+void skin_draw_playlistwin_frame (cairo_t * cr, int width, int height,
+ gboolean focus)
+{
+ skin_draw_playlistwin_frame_top (cr, width, height, focus);
+ skin_draw_playlistwin_frame_bottom (cr, width, height, focus);
+ skin_draw_playlistwin_frame_sides (cr, width, height, focus);
+}
+
+void skin_draw_playlistwin_shaded (cairo_t * cr, int width, gboolean focus)
+{
+ /* The shade mode titlebar skin consists of 4 images:
+ * a) left corner offset (72,42) size (25,14)
+ * b) right corner, focused offset (99,57) size (50,14)
+ * c) right corner, unfocused offset (99,42) size (50,14)
+ * d) bar tile offset (72,57) size (25,14)
+ */
+
+ int i;
+
+ /* left corner */
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 72, 42, 0, 0, 25, 14);
+
+ /* bar tile */
+ for (i = 0; i < (width - 75) / 25; i++)
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 72, 57, (i * 25) + 25, 0, 25, 14);
+
+ /* right corner */
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 99, focus ? 42 : 57, width - 50, 0, 50,
+ 14);
+}
+
+void skin_draw_mainwin_titlebar (cairo_t * cr, gboolean shaded, gboolean focus)
+{
+ /* The titlebar skin consists of 2 sets of 2 images, one for for
+ * shaded and the other for unshaded mode, giving a total of 4.
+ * The images are exactly 275x14 pixels, aligned and arranged
+ * vertically on each other in the pixmap in the following order:
+ *
+ * a) unshaded, focused offset (27, 0)
+ * b) unshaded, unfocused offset (27, 15)
+ * c) shaded, focused offset (27, 29)
+ * d) shaded, unfocused offset (27, 42)
+ */
+
+ int y_offset;
+
+ if (shaded) {
+ if (focus)
+ y_offset = 29;
+ else
+ y_offset = 42;
+ }
+ else {
+ if (focus)
+ y_offset = 0;
+ else
+ y_offset = 15;
+ }
+
+ skin_draw_pixbuf (cr, SKIN_TITLEBAR, 27, y_offset, 0, 0,
+ active_skin->properties.mainwin_width, MAINWIN_TITLEBAR_HEIGHT);
+}
diff --git a/src/skins/ui_skin.h b/src/skins/ui_skin.h
index 447709fa904b..acc64c874372 100644
--- a/src/skins/ui_skin.h
+++ b/src/skins/ui_skin.h
@@ -26,12 +26,13 @@
#ifndef SKIN_H
#define SKIN_H
+#include <stdint.h>
#include <gtk/gtk.h>
-#define COLOR(r,g,b) (((guint32) (r) << 16) | ((guint32) (g) << 8) | (guint32) (b))
-#define COLOR_R(c) ((gint) (((c) & 0xff0000) >> 16))
-#define COLOR_G(c) ((gint) (((c) & 0xff00) >> 8))
-#define COLOR_B(c) ((gint) ((c) & 0xff))
+#define COLOR(r,g,b) (((uint32_t) (r) << 16) | ((uint32_t) (g) << 8) | (uint32_t) (b))
+#define COLOR_R(c) ((int) (((c) & 0xff0000) >> 16))
+#define COLOR_G(c) ((int) (((c) & 0xff00) >> 8))
+#define COLOR_B(c) ((int) ((c) & 0xff))
typedef enum {
SKIN_MAIN = 0,
@@ -69,138 +70,137 @@ typedef enum {
SKIN_COLOR_COUNT
} SkinColorId;
-typedef struct {
+struct SkinProperties {
/* Vis properties */
- gint mainwin_vis_x;
- gint mainwin_vis_y;
- gboolean mainwin_vis_visible;
+ int mainwin_vis_x = 24;
+ int mainwin_vis_y = 43;
+ int mainwin_vis_visible = true;
/* Text properties */
- gint mainwin_text_x;
- gint mainwin_text_y;
- gint mainwin_text_width;
- gboolean mainwin_text_visible;
+ int mainwin_text_x = 112;
+ int mainwin_text_y = 27;
+ int mainwin_text_width = 153;
+ int mainwin_text_visible = true;
/* Infobar properties */
- gint mainwin_infobar_x;
- gint mainwin_infobar_y;
- gboolean mainwin_othertext_visible;
+ int mainwin_infobar_x = 112;
+ int mainwin_infobar_y = 43;
+ int mainwin_othertext_visible = false;
- gint mainwin_number_0_x;
- gint mainwin_number_0_y;
+ int mainwin_number_0_x = 36;
+ int mainwin_number_0_y = 26;
- gint mainwin_number_1_x;
- gint mainwin_number_1_y;
+ int mainwin_number_1_x = 48;
+ int mainwin_number_1_y = 26;
- gint mainwin_number_2_x;
- gint mainwin_number_2_y;
+ int mainwin_number_2_x = 60;
+ int mainwin_number_2_y = 26;
- gint mainwin_number_3_x;
- gint mainwin_number_3_y;
+ int mainwin_number_3_x = 78;
+ int mainwin_number_3_y = 26;
- gint mainwin_number_4_x;
- gint mainwin_number_4_y;
+ int mainwin_number_4_x = 90;
+ int mainwin_number_4_y = 26;
- gint mainwin_playstatus_x;
- gint mainwin_playstatus_y;
+ int mainwin_playstatus_x = 24;
+ int mainwin_playstatus_y = 28;
- gint mainwin_volume_x;
- gint mainwin_volume_y;
+ int mainwin_volume_x = 107;
+ int mainwin_volume_y = 57;
- gint mainwin_balance_x;
- gint mainwin_balance_y;
+ int mainwin_balance_x = 177;
+ int mainwin_balance_y = 57;
- gint mainwin_position_x;
- gint mainwin_position_y;
+ int mainwin_position_x = 16;
+ int mainwin_position_y = 72;
- gint mainwin_previous_x;
- gint mainwin_previous_y;
+ int mainwin_previous_x = 16;
+ int mainwin_previous_y = 88;
- gint mainwin_play_x;
- gint mainwin_play_y;
+ int mainwin_play_x = 39;
+ int mainwin_play_y = 88;
- gint mainwin_pause_x;
- gint mainwin_pause_y;
+ int mainwin_pause_x = 62;
+ int mainwin_pause_y = 88;
- gint mainwin_stop_x;
- gint mainwin_stop_y;
+ int mainwin_stop_x = 85;
+ int mainwin_stop_y = 88;
- gint mainwin_next_x;
- gint mainwin_next_y;
+ int mainwin_next_x = 108;
+ int mainwin_next_y = 88;
- gint mainwin_eject_x;
- gint mainwin_eject_y;
+ int mainwin_eject_x = 136;
+ int mainwin_eject_y = 89;
- gint mainwin_eqbutton_x;
- gint mainwin_eqbutton_y;
+ int mainwin_eqbutton_x = 219;
+ int mainwin_eqbutton_y = 58;
- gint mainwin_plbutton_x;
- gint mainwin_plbutton_y;
+ int mainwin_plbutton_x = 242;
+ int mainwin_plbutton_y = 58;
- gint mainwin_shuffle_x;
- gint mainwin_shuffle_y;
+ int mainwin_shuffle_x = 164;
+ int mainwin_shuffle_y = 89;
- gint mainwin_repeat_x;
- gint mainwin_repeat_y;
+ int mainwin_repeat_x = 210;
+ int mainwin_repeat_y = 89;
- gint mainwin_about_x;
- gint mainwin_about_y;
+ int mainwin_about_x = 247;
+ int mainwin_about_y = 83;
- gint mainwin_minimize_x;
- gint mainwin_minimize_y;
+ int mainwin_minimize_x = 244;
+ int mainwin_minimize_y = 3;
- gint mainwin_shade_x;
- gint mainwin_shade_y;
+ int mainwin_shade_x = 254;
+ int mainwin_shade_y = 3;
- gint mainwin_close_x;
- gint mainwin_close_y;
+ int mainwin_close_x = 264;
+ int mainwin_close_y = 3;
- gint mainwin_width;
- gint mainwin_height;
+ int mainwin_width = 275;
+ int mainwin_height = 116;
- gboolean mainwin_menurow_visible;
- gboolean mainwin_streaminfo_visible;
- gboolean mainwin_othertext_is_status;
+ int mainwin_menurow_visible = true;
+ int mainwin_streaminfo_visible = true;
+ int mainwin_othertext_is_status = false;
- gint textbox_bitmap_font_width;
- gint textbox_bitmap_font_height;
-} SkinProperties;
+ int textbox_bitmap_font_width = 5;
+ int textbox_bitmap_font_height = 6;
+};
extern const SkinProperties skin_default_hints;
typedef struct {
- gchar *path;
+ char *path;
cairo_surface_t * pixmaps[SKIN_PIXMAP_COUNT];
- guint32 colors[SKIN_COLOR_COUNT];
- guint32 vis_colors[24];
- cairo_region_t * masks[SKIN_MASK_COUNT];
+ uint32_t colors[SKIN_COLOR_COUNT];
+ uint32_t vis_colors[24];
SkinProperties properties;
} Skin;
extern Skin * active_skin;
-gboolean init_skins(const gchar * path);
+gboolean init_skins(const char * path);
void cleanup_skins(void);
-gboolean active_skin_load(const gchar * path);
+gboolean active_skin_load(const char * path);
-void skin_draw_pixbuf (cairo_t * cr, SkinPixmapId id, gint xsrc, gint ysrc,
- gint xdest, gint ydest, gint width, gint height);
+void skin_draw_pixbuf (cairo_t * cr, SkinPixmapId id, int xsrc, int ysrc,
+ int xdest, int ydest, int width, int height);
-void skin_get_eq_spline_colors(Skin * skin, guint32 colors[19]);
-void skin_install_skin(const gchar * path);
+void skin_get_eq_spline_colors(Skin * skin, uint32_t colors[19]);
+void skin_install_skin(const char * path);
-void skin_draw_playlistwin_shaded (cairo_t * cr, gint width, gboolean focus);
-void skin_draw_playlistwin_frame (cairo_t * cr, gint width, gint height,
+void skin_draw_playlistwin_shaded (cairo_t * cr, int width, gboolean focus);
+void skin_draw_playlistwin_frame (cairo_t * cr, int width, int height,
gboolean focus);
void skin_draw_mainwin_titlebar (cairo_t * cr, gboolean shaded, gboolean focus);
/* ui_skin_load_ini.c */
void skin_load_hints (Skin * skin, const char * path);
void skin_load_pl_colors (Skin * skin, const char * path);
-void skin_load_masks (Skin * skin, const char * path);
+void skin_load_masks (Skin * skin, const char * path, GdkRegion * masks[SKIN_MASK_COUNT]);
-static inline void set_cairo_color (cairo_t * cr, guint32 c)
+static inline void set_cairo_color (cairo_t * cr, uint32_t c)
{
cairo_set_source_rgb (cr, COLOR_R(c) / 255.0, COLOR_G(c) / 255.0, COLOR_B(c)
/ 255.0);
diff --git a/src/skins/ui_skin_load_ini.c b/src/skins/ui_skin_load_ini.c
deleted file mode 100644
index ed4f26d61e78..000000000000
--- a/src/skins/ui_skin_load_ini.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Audacious
- * Copyright 2011-2013 Audacious development team
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <stdlib.h>
-
-#include <libaudcore/inifile.h>
-
-#include "ui_skin.h"
-#include "util.h"
-
-/*
- * skin.hints parsing
- */
-
-typedef struct {
- const char * name;
- int * value_ptr;
-} HintPair;
-
-typedef struct {
- bool_t valid_heading;
-} HintsLoadState;
-
-const SkinProperties skin_default_hints = {
- .mainwin_vis_x = 24,
- .mainwin_vis_y = 43,
- .mainwin_vis_visible = TRUE,
-
- .mainwin_text_x = 112,
- .mainwin_text_y = 27,
- .mainwin_text_width = 153,
- .mainwin_text_visible = TRUE,
-
- .mainwin_infobar_x = 112,
- .mainwin_infobar_y = 43,
- .mainwin_othertext_visible = FALSE,
-
- .mainwin_number_0_x = 36,
- .mainwin_number_0_y = 26,
-
- .mainwin_number_1_x = 48,
- .mainwin_number_1_y = 26,
-
- .mainwin_number_2_x = 60,
- .mainwin_number_2_y = 26,
-
- .mainwin_number_3_x = 78,
- .mainwin_number_3_y = 26,
-
- .mainwin_number_4_x = 90,
- .mainwin_number_4_y = 26,
-
- .mainwin_playstatus_x = 24,
- .mainwin_playstatus_y = 28,
-
- .mainwin_volume_x = 107,
- .mainwin_volume_y = 57,
-
- .mainwin_balance_x = 177,
- .mainwin_balance_y = 57,
-
- .mainwin_position_x = 16,
- .mainwin_position_y = 72,
-
- .mainwin_previous_x = 16,
- .mainwin_previous_y = 88,
-
- .mainwin_play_x = 39,
- .mainwin_play_y = 88,
-
- .mainwin_pause_x = 62,
- .mainwin_pause_y = 88,
-
- .mainwin_stop_x = 85,
- .mainwin_stop_y = 88,
-
- .mainwin_next_x = 108,
- .mainwin_next_y = 88,
-
- .mainwin_eject_x = 136,
- .mainwin_eject_y = 89,
-
- .mainwin_eqbutton_x = 219,
- .mainwin_eqbutton_y = 58,
-
- .mainwin_plbutton_x = 242,
- .mainwin_plbutton_y = 58,
-
- .mainwin_shuffle_x = 164,
- .mainwin_shuffle_y = 89,
-
- .mainwin_repeat_x = 210,
- .mainwin_repeat_y = 89,
-
- .mainwin_about_x = 247,
- .mainwin_about_y = 83,
-
- .mainwin_minimize_x = 244,
- .mainwin_minimize_y = 3,
-
- .mainwin_shade_x = 254,
- .mainwin_shade_y = 3,
-
- .mainwin_close_x = 264,
- .mainwin_close_y = 3,
-
- .mainwin_width = 275,
- .mainwin_height = 116,
-
- .mainwin_menurow_visible = TRUE,
- .mainwin_streaminfo_visible = TRUE,
- .mainwin_othertext_is_status = FALSE,
-
- .textbox_bitmap_font_width = 5,
- .textbox_bitmap_font_height = 6
-};
-
-/* so we can use static addresses in the table below */
-static SkinProperties static_hints;
-
-/* in alphabetical order to allow binary search */
-static const HintPair hint_pairs[] = {
- {"mainwinaboutx", & static_hints.mainwin_about_x},
- {"mainwinabouty", & static_hints.mainwin_about_y},
- {"mainwinbalancex", & static_hints.mainwin_balance_x},
- {"mainwinbalancey", & static_hints.mainwin_balance_y},
- {"mainwinclosex", & static_hints.mainwin_close_x},
- {"mainwinclosey", & static_hints.mainwin_close_y},
- {"mainwinejectx", & static_hints.mainwin_eject_x},
- {"mainwinejecty", & static_hints.mainwin_eject_y},
- {"mainwineqbuttonx", & static_hints.mainwin_eqbutton_x},
- {"mainwineqbuttony", & static_hints.mainwin_eqbutton_y},
- {"mainwinheight", & static_hints.mainwin_height},
- {"mainwininfobarx", & static_hints.mainwin_infobar_x},
- {"mainwininfobary", & static_hints.mainwin_infobar_y},
- {"mainwinmenurowvisible", & static_hints.mainwin_menurow_visible},
- {"mainwinminimizex", & static_hints.mainwin_minimize_x},
- {"mainwinminimizey", & static_hints.mainwin_minimize_y},
- {"mainwinnextx", & static_hints.mainwin_next_x},
- {"mainwinnexty", & static_hints.mainwin_next_y},
- {"mainwinnumber0x", & static_hints.mainwin_number_0_x},
- {"mainwinnumber0y", & static_hints.mainwin_number_0_y},
- {"mainwinnumber1x", & static_hints.mainwin_number_1_x},
- {"mainwinnumber1y", & static_hints.mainwin_number_1_y},
- {"mainwinnumber2x", & static_hints.mainwin_number_2_x},
- {"mainwinnumber2y", & static_hints.mainwin_number_2_y},
- {"mainwinnumber3x", & static_hints.mainwin_number_3_x},
- {"mainwinnumber3y", & static_hints.mainwin_number_3_y},
- {"mainwinnumber4x", & static_hints.mainwin_number_4_x},
- {"mainwinnumber4y", & static_hints.mainwin_number_4_y},
- {"mainwinothertextisstatus", & static_hints.mainwin_othertext_is_status},
- {"mainwinothertextvisible", & static_hints.mainwin_othertext_visible},
- {"mainwinpausex", & static_hints.mainwin_pause_x},
- {"mainwinpausey", & static_hints.mainwin_pause_y},
- {"mainwinplaystatusx", & static_hints.mainwin_playstatus_x},
- {"mainwinplaystatusy", & static_hints.mainwin_playstatus_y},
- {"mainwinplayx", & static_hints.mainwin_play_x},
- {"mainwinplayy", & static_hints.mainwin_play_y},
- {"mainwinplbuttonx", & static_hints.mainwin_plbutton_x},
- {"mainwinplbuttony", & static_hints.mainwin_plbutton_y},
- {"mainwinpositionx", & static_hints.mainwin_position_x},
- {"mainwinpositiony", & static_hints.mainwin_position_y},
- {"mainwinpreviousx", & static_hints.mainwin_previous_x},
- {"mainwinpreviousy", & static_hints.mainwin_previous_y},
- {"mainwinrepeatx", & static_hints.mainwin_repeat_x},
- {"mainwinrepeaty", & static_hints.mainwin_repeat_y},
- {"mainwinshadex", & static_hints.mainwin_shade_x},
- {"mainwinshadey", & static_hints.mainwin_shade_y},
- {"mainwinshufflex", & static_hints.mainwin_shuffle_x},
- {"mainwinshuffley", & static_hints.mainwin_shuffle_y},
- {"mainwinstopx", & static_hints.mainwin_stop_x},
- {"mainwinstopy", & static_hints.mainwin_stop_y},
- {"mainwinstreaminfovisible", & static_hints.mainwin_streaminfo_visible},
- {"mainwintextvisible", & static_hints.mainwin_text_visible},
- {"mainwintextwidth", & static_hints.mainwin_text_width},
- {"mainwintextx", & static_hints.mainwin_text_x},
- {"mainwintexty", & static_hints.mainwin_text_y},
- {"mainwinvisvisible", & static_hints.mainwin_vis_visible},
- {"mainwinvisx", & static_hints.mainwin_vis_x},
- {"mainwinvisy", & static_hints.mainwin_vis_y},
- {"mainwinvolumex", & static_hints.mainwin_volume_x},
- {"mainwinvolumey", & static_hints.mainwin_volume_y},
- {"mainwinwidth", & static_hints.mainwin_width},
- {"textboxbitmapfontheight", & static_hints.textbox_bitmap_font_height},
- {"textboxbitmapfontwidth", & static_hints.textbox_bitmap_font_width},
-};
-
-static int hint_pair_compare (const void * a, const void * b)
-{
- return g_ascii_strcasecmp (((const HintPair *) a)->name, ((const HintPair *) b)->name);
-}
-
-static void hints_handle_heading (const char * heading, void * data)
-{
- HintsLoadState * state = data;
-
- state->valid_heading = ! g_ascii_strcasecmp (heading, "skin");
-}
-
-static void hints_handle_entry (const char * key, const char * value, void * data)
-{
- HintsLoadState * state = data;
-
- if (! state->valid_heading)
- return;
-
- HintPair key_pair = {.name = key};
- HintPair * pair = bsearch (& key_pair, hint_pairs,
- ARRAY_LEN (hint_pairs), sizeof (HintPair), hint_pair_compare);
-
- if (pair)
- * pair->value_ptr = atoi (value);
-}
-
-void skin_load_hints (Skin * skin, const char * path)
-{
- static_hints = skin_default_hints;
-
- HintsLoadState state = {.valid_heading = FALSE};
-
- VFSFile * file = open_local_file_nocase (path, "skin.hints");
-
- if (file)
- {
- inifile_parse (file, hints_handle_heading, hints_handle_entry, & state);
- vfs_fclose (file);
- }
-
- skin->properties = static_hints;
-}
-
-/*
- * pledit.txt parsing
- */
-
-typedef struct {
- bool_t valid_heading;
- Skin * skin;
-} PLColorsLoadState;
-
-static void pl_colors_handle_heading (const char * heading, void * data)
-{
- PLColorsLoadState * state = data;
-
- state->valid_heading = ! g_ascii_strcasecmp (heading, "text");
-}
-
-static uint32_t convert_color_string (const char * str)
-{
- if (* str == '#')
- str ++;
-
- return strtol (str, NULL, 16);
-}
-
-static void pl_colors_handle_entry (const char * key, const char * value, void * data)
-{
- PLColorsLoadState * state = data;
-
- if (! state->valid_heading)
- return;
-
- if (! g_ascii_strcasecmp (key, "normal"))
- state->skin->colors[SKIN_PLEDIT_NORMAL] = convert_color_string (value);
- else if (! g_ascii_strcasecmp (key, "current"))
- state->skin->colors[SKIN_PLEDIT_CURRENT] = convert_color_string (value);
- else if (! g_ascii_strcasecmp (key, "normalbg"))
- state->skin->colors[SKIN_PLEDIT_NORMALBG] = convert_color_string (value);
- else if (! g_ascii_strcasecmp (key, "selectedbg"))
- state->skin->colors[SKIN_PLEDIT_SELECTEDBG] = convert_color_string (value);
-}
-
-void skin_load_pl_colors (Skin * skin, const char * path)
-{
- skin->colors[SKIN_PLEDIT_NORMAL] = 0x2499ff;
- skin->colors[SKIN_PLEDIT_CURRENT] = 0xffeeff;
- skin->colors[SKIN_PLEDIT_NORMALBG] = 0x0a120a;
- skin->colors[SKIN_PLEDIT_SELECTEDBG] = 0x0a124a;
-
- PLColorsLoadState state = {
- .valid_heading = FALSE,
- .skin = skin
- };
-
- VFSFile * file = open_local_file_nocase (path, "pledit.txt");
-
- if (file)
- {
- inifile_parse (file, pl_colors_handle_heading, pl_colors_handle_entry, & state);
- vfs_fclose (file);
- }
-}
-
-/*
- * region.txt parsing
- */
-
-typedef struct {
- SkinMaskId current_id;
- GArray * numpoints[SKIN_MASK_COUNT];
- GArray * pointlist[SKIN_MASK_COUNT];
-} MaskLoadState;
-
-static void mask_handle_heading (const char * heading, void * data)
-{
- MaskLoadState * state = data;
-
- if (! g_ascii_strcasecmp (heading, "normal"))
- state->current_id = SKIN_MASK_MAIN;
- else if (! g_ascii_strcasecmp (heading, "windowshade"))
- state->current_id = SKIN_MASK_MAIN_SHADE;
- else if (! g_ascii_strcasecmp (heading, "equalizer"))
- state->current_id = SKIN_MASK_EQ;
- else if (! g_ascii_strcasecmp (heading, "equalizerws"))
- state->current_id = SKIN_MASK_EQ_SHADE;
- else
- state->current_id = -1;
-}
-
-static void mask_handle_entry (const char * key, const char * value, void * data)
-{
- MaskLoadState * state = data;
- SkinMaskId id = state->current_id;
-
- if (id == -1)
- return;
-
- if (! g_ascii_strcasecmp (key, "numpoints"))
- {
- if (! state->numpoints[id])
- state->numpoints[id] = string_to_garray (value);
- }
- else if (! g_ascii_strcasecmp (key, "pointlist"))
- {
- if (! state->pointlist[id])
- state->pointlist[id] = string_to_garray (value);
- }
-}
-
-static cairo_region_t * skin_create_mask (const GArray * num,
- const GArray * point, int width, int height)
-{
- if (! num || ! point)
- {
- cairo_rectangle_int_t rect = {0, 0, width, height};
- return cairo_region_create_rectangle (& rect);
- }
-
- cairo_region_t * mask = cairo_region_create ();
- gboolean created_mask = FALSE;
-
- int j = 0;
- for (int i = 0; i < num->len; i ++)
- {
- int n_points = g_array_index (num, int, i);
- if (n_points <= 0 || j + 2 * n_points > point->len)
- break;
-
- GdkPoint gpoints[n_points];
- for (int k = 0; k < n_points; k ++)
- {
- gpoints[k].x = g_array_index (point, int, j + k * 2);
- gpoints[k].y = g_array_index (point, int, j + k * 2 + 1);
- }
-
- int xmin = width, ymin = height, xmax = 0, ymax = 0;
- for (int k = 0; k < n_points; k ++)
- {
- xmin = MIN (xmin, gpoints[k].x);
- ymin = MIN (ymin, gpoints[k].y);
- xmax = MAX (xmax, gpoints[k].x);
- ymax = MAX (ymax, gpoints[k].y);
- }
-
- if (xmax > xmin && ymax > ymin)
- {
- cairo_rectangle_int_t rect = {xmin, ymin, xmax - xmin, ymax - ymin};
- cairo_region_union_rectangle (mask, & rect);
- }
-
- created_mask = TRUE;
- j += n_points * 2;
- }
-
- if (! created_mask)
- {
- cairo_rectangle_int_t rect = {0, 0, width, height};
- cairo_region_union_rectangle (mask, & rect);
- }
-
- return mask;
-}
-
-void skin_load_masks (Skin * skin, const char * path)
-{
- int sizes[SKIN_MASK_COUNT][2] = {
- {skin->properties.mainwin_width, skin->properties.mainwin_height},
- {275, 16},
- {275, 116},
- {275, 16}
- };
-
- MaskLoadState state = {.current_id = -1};
-
- VFSFile * file = open_local_file_nocase (path, "region.txt");
-
- if (file)
- {
- inifile_parse (file, mask_handle_heading, mask_handle_entry, & state);
- vfs_fclose (file);
- }
-
- for (SkinMaskId id = 0; id < SKIN_MASK_COUNT; id ++)
- {
- skin->masks[id] = skin_create_mask (state.numpoints[id],
- state.pointlist[id], sizes[id][0], sizes[id][1]);
-
- if (state.numpoints[id])
- g_array_free (state.numpoints[id], TRUE);
- if (state.pointlist[id])
- g_array_free (state.pointlist[id], TRUE);
- }
-}
diff --git a/src/skins/ui_skin_load_ini.cc b/src/skins/ui_skin_load_ini.cc
new file mode 100644
index 000000000000..ae49764b9316
--- /dev/null
+++ b/src/skins/ui_skin_load_ini.cc
@@ -0,0 +1,315 @@
+/*
+ * Audacious
+ * Copyright 2011-2013 Audacious development team
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <stdlib.h>
+
+#include <libaudcore/inifile.h>
+
+#include "skins_cfg.h"
+#include "ui_skin.h"
+#include "util.h"
+
+/*
+ * skin.hints parsing
+ */
+
+typedef struct {
+ const char * name;
+ int * value_ptr;
+} HintPair;
+
+const SkinProperties skin_default_hints = SkinProperties ();
+
+/* so we can use static addresses in the table below */
+static SkinProperties static_hints;
+
+/* in alphabetical order to allow binary search */
+static const HintPair hint_pairs[] = {
+ {"mainwinaboutx", & static_hints.mainwin_about_x},
+ {"mainwinabouty", & static_hints.mainwin_about_y},
+ {"mainwinbalancex", & static_hints.mainwin_balance_x},
+ {"mainwinbalancey", & static_hints.mainwin_balance_y},
+ {"mainwinclosex", & static_hints.mainwin_close_x},
+ {"mainwinclosey", & static_hints.mainwin_close_y},
+ {"mainwinejectx", & static_hints.mainwin_eject_x},
+ {"mainwinejecty", & static_hints.mainwin_eject_y},
+ {"mainwineqbuttonx", & static_hints.mainwin_eqbutton_x},
+ {"mainwineqbuttony", & static_hints.mainwin_eqbutton_y},
+ {"mainwinheight", & static_hints.mainwin_height},
+ {"mainwininfobarx", & static_hints.mainwin_infobar_x},
+ {"mainwininfobary", & static_hints.mainwin_infobar_y},
+ {"mainwinmenurowvisible", & static_hints.mainwin_menurow_visible},
+ {"mainwinminimizex", & static_hints.mainwin_minimize_x},
+ {"mainwinminimizey", & static_hints.mainwin_minimize_y},
+ {"mainwinnextx", & static_hints.mainwin_next_x},
+ {"mainwinnexty", & static_hints.mainwin_next_y},
+ {"mainwinnumber0x", & static_hints.mainwin_number_0_x},
+ {"mainwinnumber0y", & static_hints.mainwin_number_0_y},
+ {"mainwinnumber1x", & static_hints.mainwin_number_1_x},
+ {"mainwinnumber1y", & static_hints.mainwin_number_1_y},
+ {"mainwinnumber2x", & static_hints.mainwin_number_2_x},
+ {"mainwinnumber2y", & static_hints.mainwin_number_2_y},
+ {"mainwinnumber3x", & static_hints.mainwin_number_3_x},
+ {"mainwinnumber3y", & static_hints.mainwin_number_3_y},
+ {"mainwinnumber4x", & static_hints.mainwin_number_4_x},
+ {"mainwinnumber4y", & static_hints.mainwin_number_4_y},
+ {"mainwinothertextisstatus", & static_hints.mainwin_othertext_is_status},
+ {"mainwinothertextvisible", & static_hints.mainwin_othertext_visible},
+ {"mainwinpausex", & static_hints.mainwin_pause_x},
+ {"mainwinpausey", & static_hints.mainwin_pause_y},
+ {"mainwinplaystatusx", & static_hints.mainwin_playstatus_x},
+ {"mainwinplaystatusy", & static_hints.mainwin_playstatus_y},
+ {"mainwinplayx", & static_hints.mainwin_play_x},
+ {"mainwinplayy", & static_hints.mainwin_play_y},
+ {"mainwinplbuttonx", & static_hints.mainwin_plbutton_x},
+ {"mainwinplbuttony", & static_hints.mainwin_plbutton_y},
+ {"mainwinpositionx", & static_hints.mainwin_position_x},
+ {"mainwinpositiony", & static_hints.mainwin_position_y},
+ {"mainwinpreviousx", & static_hints.mainwin_previous_x},
+ {"mainwinpreviousy", & static_hints.mainwin_previous_y},
+ {"mainwinrepeatx", & static_hints.mainwin_repeat_x},
+ {"mainwinrepeaty", & static_hints.mainwin_repeat_y},
+ {"mainwinshadex", & static_hints.mainwin_shade_x},
+ {"mainwinshadey", & static_hints.mainwin_shade_y},
+ {"mainwinshufflex", & static_hints.mainwin_shuffle_x},
+ {"mainwinshuffley", & static_hints.mainwin_shuffle_y},
+ {"mainwinstopx", & static_hints.mainwin_stop_x},
+ {"mainwinstopy", & static_hints.mainwin_stop_y},
+ {"mainwinstreaminfovisible", & static_hints.mainwin_streaminfo_visible},
+ {"mainwintextvisible", & static_hints.mainwin_text_visible},
+ {"mainwintextwidth", & static_hints.mainwin_text_width},
+ {"mainwintextx", & static_hints.mainwin_text_x},
+ {"mainwintexty", & static_hints.mainwin_text_y},
+ {"mainwinvisvisible", & static_hints.mainwin_vis_visible},
+ {"mainwinvisx", & static_hints.mainwin_vis_x},
+ {"mainwinvisy", & static_hints.mainwin_vis_y},
+ {"mainwinvolumex", & static_hints.mainwin_volume_x},
+ {"mainwinvolumey", & static_hints.mainwin_volume_y},
+ {"mainwinwidth", & static_hints.mainwin_width},
+ {"textboxbitmapfontheight", & static_hints.textbox_bitmap_font_height},
+ {"textboxbitmapfontwidth", & static_hints.textbox_bitmap_font_width},
+};
+
+static int hint_pair_compare (const void * key, const void * pair)
+{
+ return g_ascii_strcasecmp ((const char *) key, ((const HintPair *) pair)->name);
+}
+
+class HintsParser : public IniParser
+{
+private:
+ bool valid_heading = false;
+
+ void handle_heading (const char * heading)
+ { valid_heading = ! g_ascii_strcasecmp (heading, "skin"); }
+
+ void handle_entry (const char * key, const char * value)
+ {
+ if (! valid_heading)
+ return;
+
+ HintPair * pair = (HintPair *) bsearch (key, hint_pairs,
+ aud::n_elems (hint_pairs), sizeof (HintPair), hint_pair_compare);
+
+ if (pair)
+ * pair->value_ptr = atoi (value);
+ }
+};
+
+void skin_load_hints (Skin * skin, const char * path)
+{
+ static_hints = skin_default_hints;
+
+ VFSFile file = open_local_file_nocase (path, "skin.hints");
+ if (file)
+ HintsParser ().parse (file);
+
+ skin->properties = static_hints;
+}
+
+/*
+ * pledit.txt parsing
+ */
+
+class PLColorsParser : public IniParser
+{
+public:
+ PLColorsParser (Skin & skin) :
+ skin (skin),
+ valid_heading (false) {}
+
+private:
+ Skin & skin;
+ bool valid_heading;
+
+ void handle_heading (const char * heading)
+ { valid_heading = ! g_ascii_strcasecmp (heading, "text"); }
+
+ void handle_entry (const char * key, const char * value)
+ {
+ if (! valid_heading)
+ return;
+
+ if (value[0] == '#')
+ value ++;
+
+ uint32_t color = strtol (value, nullptr, 16);
+
+ if (! g_ascii_strcasecmp (key, "normal"))
+ skin.colors[SKIN_PLEDIT_NORMAL] = color;
+ else if (! g_ascii_strcasecmp (key, "current"))
+ skin.colors[SKIN_PLEDIT_CURRENT] = color;
+ else if (! g_ascii_strcasecmp (key, "normalbg"))
+ skin.colors[SKIN_PLEDIT_NORMALBG] = color;
+ else if (! g_ascii_strcasecmp (key, "selectedbg"))
+ skin.colors[SKIN_PLEDIT_SELECTEDBG] = color;
+ }
+};
+
+void skin_load_pl_colors (Skin * skin, const char * path)
+{
+ skin->colors[SKIN_PLEDIT_NORMAL] = 0x2499ff;
+ skin->colors[SKIN_PLEDIT_CURRENT] = 0xffeeff;
+ skin->colors[SKIN_PLEDIT_NORMALBG] = 0x0a120a;
+ skin->colors[SKIN_PLEDIT_SELECTEDBG] = 0x0a124a;
+
+ VFSFile file = open_local_file_nocase (path, "pledit.txt");
+ if (file)
+ PLColorsParser (* skin).parse (file);
+}
+
+/*
+ * region.txt parsing
+ */
+
+class MaskParser : public IniParser
+{
+public:
+ GArray * numpoints[SKIN_MASK_COUNT] {};
+ GArray * pointlist[SKIN_MASK_COUNT] {};
+
+ ~MaskParser ()
+ {
+ for (GArray * array : numpoints)
+ if (array) g_array_free (array, true);
+ for (GArray * array : pointlist)
+ if (array) g_array_free (array, true);
+ }
+
+private:
+ SkinMaskId current_id = SkinMaskId (-1);
+
+ void handle_heading (const char * heading)
+ {
+ if (! g_ascii_strcasecmp (heading, "normal"))
+ current_id = SKIN_MASK_MAIN;
+ else if (! g_ascii_strcasecmp (heading, "windowshade"))
+ current_id = SKIN_MASK_MAIN_SHADE;
+ else if (! g_ascii_strcasecmp (heading, "equalizer"))
+ current_id = SKIN_MASK_EQ;
+ else if (! g_ascii_strcasecmp (heading, "equalizerws"))
+ current_id = SKIN_MASK_EQ_SHADE;
+ else
+ current_id = (SkinMaskId) -1;
+ }
+
+ void handle_entry (const char * key, const char * value)
+ {
+ if (current_id == (SkinMaskId) -1)
+ return;
+
+ if (! g_ascii_strcasecmp (key, "numpoints"))
+ {
+ if (! numpoints[current_id])
+ numpoints[current_id] = string_to_garray (value);
+ }
+ else if (! g_ascii_strcasecmp (key, "pointlist"))
+ {
+ if (! pointlist[current_id])
+ pointlist[current_id] = string_to_garray (value);
+ }
+ }
+};
+
+static GdkRegion * skin_create_mask (const GArray * num,
+ const GArray * point, int width, int height)
+{
+ if (! num || ! point)
+ return nullptr;
+
+ width *= config.scale;
+ height *= config.scale;
+
+ GdkRegion * mask = nullptr;
+
+ unsigned j = 0;
+ for (unsigned i = 0; i < num->len; i ++)
+ {
+ int n_points = g_array_index (num, int, i);
+ if (n_points <= 0 || j + 2 * n_points > point->len)
+ break;
+
+ int xmin = width, ymin = height, xmax = 0, ymax = 0;
+
+ for (int k = 0; k < n_points; k ++)
+ {
+ int x = g_array_index (point, int, j + k * 2) * config.scale;
+ int y = g_array_index (point, int, j + k * 2 + 1) * config.scale;
+
+ xmin = aud::min (xmin, x);
+ ymin = aud::min (ymin, y);
+ xmax = aud::max (xmax, x);
+ ymax = aud::max (ymax, y);
+ }
+
+ if (xmax > xmin && ymax > ymin)
+ {
+ GdkRectangle rect = {xmin, ymin, xmax - xmin, ymax - ymin};
+
+ if (mask)
+ gdk_region_union_with_rect (mask, & rect);
+ else
+ mask = gdk_region_rectangle (& rect);
+ }
+
+ j += n_points * 2;
+ }
+
+ return mask;
+}
+
+void skin_load_masks (Skin * skin, const char * path, GdkRegion * masks[SKIN_MASK_COUNT])
+{
+ int sizes[SKIN_MASK_COUNT][2] = {
+ {skin->properties.mainwin_width, skin->properties.mainwin_height},
+ {275, 16},
+ {275, 116},
+ {275, 16}
+ };
+
+ MaskParser parser;
+ VFSFile file = open_local_file_nocase (path, "region.txt");
+ if (file)
+ parser.parse (file);
+
+ for (int id = 0; id < SKIN_MASK_COUNT; id ++)
+ masks[id] = skin_create_mask (parser.numpoints[id],
+ parser.pointlist[id], sizes[id][0], sizes[id][1]);
+}
diff --git a/src/skins/ui_skinned_button.c b/src/skins/ui_skinned_button.c
deleted file mode 100644
index cb423068deba..000000000000
--- a/src/skins/ui_skinned_button.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz MoÅ
- * Copyright (c) 2011 John Lindgren
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "draw-compat.h"
-#include "ui_skinned_button.h"
-
-enum {BUTTON_TYPE_NORMAL, BUTTON_TYPE_TOGGLE, BUTTON_TYPE_SMALL};
-
-typedef struct {
- gint type;
- gint w, h;
- gint nx, ny, px, py;
- gint pnx, pny, ppx, ppy;
- SkinPixmapId si1, si2;
- gboolean pressed, rpressed, active;
- ButtonCB on_press, on_release, on_rpress, on_rrelease;
-} ButtonData;
-
-DRAW_FUNC_BEGIN (button_draw)
- ButtonData * data = g_object_get_data ((GObject *) wid, "buttondata");
- g_return_val_if_fail (data, FALSE);
-
- switch (data->type)
- {
- case BUTTON_TYPE_NORMAL:
- if (data->pressed)
- skin_draw_pixbuf (cr, data->si2, data->px, data->py, 0, 0, data->w, data->h);
- else
- skin_draw_pixbuf (cr, data->si1, data->nx, data->ny, 0, 0, data->w, data->h);
- break;
- case BUTTON_TYPE_TOGGLE:
- if (data->active)
- {
- if (data->pressed)
- skin_draw_pixbuf (cr, data->si2, data->ppx, data->ppy, 0, 0, data->w, data->h);
- else
- skin_draw_pixbuf (cr, data->si1, data->pnx, data->pny, 0, 0, data->w, data->h);
- }
- else
- {
- if (data->pressed)
- skin_draw_pixbuf (cr, data->si2, data->px, data->py, 0, 0, data->w, data->h);
- else
- skin_draw_pixbuf (cr, data->si1, data->nx, data->ny, 0, 0, data->w, data->h);
- }
- break;
- }
-DRAW_FUNC_END
-
-static gboolean button_press (GtkWidget * button, GdkEventButton * event)
-{
- ButtonData * data = g_object_get_data ((GObject *) button, "buttondata");
- g_return_val_if_fail (data, FALSE);
-
- /* pass events through to the parent widget only if neither the press nor
- * release signals are connected; sending one and not the other causes
- * problems (in particular with dragging windows around) */
- if (event->button == 1 && (data->on_press || data->on_release))
- {
- data->pressed = TRUE;
- if (data->on_press)
- data->on_press (button, event);
- }
- else if (event->button == 3 && (data->on_rpress || data->on_rrelease))
- {
- data->rpressed = TRUE;
- if (data->on_rpress)
- data->on_rpress (button, event);
- }
- else
- return FALSE;
-
- if (data->type != BUTTON_TYPE_SMALL)
- gtk_widget_queue_draw (button);
-
- return TRUE;
-}
-
-static gboolean button_release (GtkWidget * button, GdkEventButton * event)
-{
- ButtonData * data = g_object_get_data ((GObject *) button, "buttondata");
- g_return_val_if_fail (data, FALSE);
-
- if (event->button == 1 && (data->on_press || data->on_release))
- {
- if (! data->pressed)
- return TRUE;
-
- data->pressed = FALSE;
- if (data->type == BUTTON_TYPE_TOGGLE)
- data->active = ! data->active;
- if (data->on_release)
- data->on_release (button, event);
- }
- else if (event->button == 3 && (data->on_rpress || data->on_rrelease))
- {
- if (! data->rpressed)
- return TRUE;
-
- data->rpressed = FALSE;
- if (data->on_rrelease)
- data->on_rrelease (button, event);
- }
- else
- return FALSE;
-
- if (data->type != BUTTON_TYPE_SMALL)
- gtk_widget_queue_draw (button);
-
- return TRUE;
-}
-
-static void button_destroy (GtkWidget * button)
-{
- g_free (g_object_get_data ((GObject *) button, "buttondata"));
-}
-
-static GtkWidget * button_new_base (gint type, gint w, gint h)
-{
- GtkWidget * button;
-
- if (type == BUTTON_TYPE_SMALL)
- {
- button = gtk_event_box_new ();
- gtk_event_box_set_visible_window ((GtkEventBox *) button, FALSE);
- }
- else
- button = gtk_drawing_area_new ();
-
- gtk_widget_set_size_request (button, w, h);
- gtk_widget_add_events (button, GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK);
-
- if (type != BUTTON_TYPE_SMALL)
- DRAW_CONNECT (button, button_draw);
-
- g_signal_connect (button, "button-press-event", (GCallback) button_press,
- NULL);
- g_signal_connect (button, "button-release-event", (GCallback)
- button_release, NULL);
- g_signal_connect (button, "destroy", (GCallback) button_destroy, NULL);
-
- ButtonData * data = g_malloc0 (sizeof (ButtonData));
- data->type = type;
- data->w = w;
- data->h = h;
- g_object_set_data ((GObject *) button, "buttondata", data);
-
- return button;
-}
-
-GtkWidget * button_new (gint w, gint h, gint nx, gint ny, gint px, gint py,
- SkinPixmapId si1, SkinPixmapId si2)
-{
- GtkWidget * button = button_new_base (BUTTON_TYPE_NORMAL, w, h);
- ButtonData * data = g_object_get_data ((GObject *) button, "buttondata");
- g_return_val_if_fail (data, NULL);
-
- data->nx = nx;
- data->ny = ny;
- data->px = px;
- data->py = py;
- data->si1 = si1;
- data->si2 = si2;
-
- return button;
-}
-
-GtkWidget * button_new_toggle (gint w, gint h, gint nx, gint ny, gint px, gint
- py, gint pnx, gint pny, gint ppx, gint ppy, SkinPixmapId si1, SkinPixmapId si2)
-{
- GtkWidget * button = button_new_base (BUTTON_TYPE_TOGGLE, w, h);
- ButtonData * data = g_object_get_data ((GObject *) button, "buttondata");
- g_return_val_if_fail (data, NULL);
-
- data->nx = nx;
- data->ny = ny;
- data->px = px;
- data->py = py;
- data->pnx = pnx;
- data->pny = pny;
- data->ppx = ppx;
- data->ppy = ppy;
- data->si1 = si1;
- data->si2 = si2;
-
- return button;
-}
-
-GtkWidget * button_new_small (gint w, gint h)
-{
- return button_new_base (BUTTON_TYPE_SMALL, w, h);
-}
-
-void button_on_press (GtkWidget * button, ButtonCB callback)
-{
- ButtonData * data = g_object_get_data ((GObject *) button, "buttondata");
- g_return_if_fail (data);
-
- data->on_press = callback;
-}
-
-void button_on_release (GtkWidget * button, ButtonCB callback)
-{
- ButtonData * data = g_object_get_data ((GObject *) button, "buttondata");
- g_return_if_fail (data);
-
- data->on_release = callback;
-}
-
-void button_on_rpress (GtkWidget * button, ButtonCB callback)
-{
- ButtonData * data = g_object_get_data ((GObject *) button, "buttondata");
- g_return_if_fail (data);
-
- data->on_rpress = callback;
-}
-
-void button_on_rrelease (GtkWidget * button, ButtonCB callback)
-{
- ButtonData * data = g_object_get_data ((GObject *) button, "buttondata");
- g_return_if_fail (data);
-
- data->on_rrelease = callback;
-}
-
-gboolean button_get_active (GtkWidget * button)
-{
- ButtonData * data = g_object_get_data ((GObject *) button, "buttondata");
- g_return_val_if_fail (data && data->type == BUTTON_TYPE_TOGGLE, FALSE);
-
- return data->active;
-}
-
-void button_set_active (GtkWidget * button, gboolean active)
-{
- ButtonData * data = g_object_get_data ((GObject *) button, "buttondata");
- g_return_if_fail (data && data->type == BUTTON_TYPE_TOGGLE);
-
- if (data->active == active)
- return;
-
- data->active = active;
- gtk_widget_queue_draw (button);
-}
diff --git a/src/skins/ui_skinned_button.cc b/src/skins/ui_skinned_button.cc
new file mode 100644
index 000000000000..93f33cfdce62
--- /dev/null
+++ b/src/skins/ui_skinned_button.cc
@@ -0,0 +1,264 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz MoÅ
+ * Copyright (c) 2011 John Lindgren
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "ui_skinned_button.h"
+
+enum {BUTTON_TYPE_NORMAL, BUTTON_TYPE_TOGGLE, BUTTON_TYPE_SMALL};
+
+typedef struct {
+ int type;
+ int w, h;
+ int nx, ny, px, py;
+ int pnx, pny, ppx, ppy;
+ SkinPixmapId si1, si2;
+ gboolean pressed, rpressed, active;
+ ButtonCB on_press, on_release, on_rpress, on_rrelease;
+} ButtonData;
+
+DRAW_FUNC_BEGIN (button_draw)
+ ButtonData * data = (ButtonData *) g_object_get_data ((GObject *) wid, "buttondata");
+ g_return_val_if_fail (data, FALSE);
+
+ switch (data->type)
+ {
+ case BUTTON_TYPE_NORMAL:
+ if (data->pressed)
+ skin_draw_pixbuf (cr, data->si2, data->px, data->py, 0, 0, data->w, data->h);
+ else
+ skin_draw_pixbuf (cr, data->si1, data->nx, data->ny, 0, 0, data->w, data->h);
+ break;
+ case BUTTON_TYPE_TOGGLE:
+ if (data->active)
+ {
+ if (data->pressed)
+ skin_draw_pixbuf (cr, data->si2, data->ppx, data->ppy, 0, 0, data->w, data->h);
+ else
+ skin_draw_pixbuf (cr, data->si1, data->pnx, data->pny, 0, 0, data->w, data->h);
+ }
+ else
+ {
+ if (data->pressed)
+ skin_draw_pixbuf (cr, data->si2, data->px, data->py, 0, 0, data->w, data->h);
+ else
+ skin_draw_pixbuf (cr, data->si1, data->nx, data->ny, 0, 0, data->w, data->h);
+ }
+ break;
+ }
+DRAW_FUNC_END
+
+static gboolean button_press (GtkWidget * button, GdkEventButton * event)
+{
+ ButtonData * data = (ButtonData *) g_object_get_data ((GObject *) button, "buttondata");
+ g_return_val_if_fail (data, FALSE);
+
+ /* pass events through to the parent widget only if neither the press nor
+ * release signals are connected; sending one and not the other causes
+ * problems (in particular with dragging windows around) */
+ if (event->button == 1 && (data->on_press || data->on_release))
+ {
+ data->pressed = TRUE;
+ if (data->on_press)
+ data->on_press (button, event);
+ }
+ else if (event->button == 3 && (data->on_rpress || data->on_rrelease))
+ {
+ data->rpressed = TRUE;
+ if (data->on_rpress)
+ data->on_rpress (button, event);
+ }
+ else
+ return FALSE;
+
+ if (data->type != BUTTON_TYPE_SMALL)
+ gtk_widget_queue_draw (button);
+
+ return TRUE;
+}
+
+static gboolean button_release (GtkWidget * button, GdkEventButton * event)
+{
+ ButtonData * data = (ButtonData *) g_object_get_data ((GObject *) button, "buttondata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (event->button == 1 && (data->on_press || data->on_release))
+ {
+ if (! data->pressed)
+ return TRUE;
+
+ data->pressed = FALSE;
+ if (data->type == BUTTON_TYPE_TOGGLE)
+ data->active = ! data->active;
+ if (data->on_release)
+ data->on_release (button, event);
+ }
+ else if (event->button == 3 && (data->on_rpress || data->on_rrelease))
+ {
+ if (! data->rpressed)
+ return TRUE;
+
+ data->rpressed = FALSE;
+ if (data->on_rrelease)
+ data->on_rrelease (button, event);
+ }
+ else
+ return FALSE;
+
+ if (data->type != BUTTON_TYPE_SMALL)
+ gtk_widget_queue_draw (button);
+
+ return TRUE;
+}
+
+static void button_destroy (GtkWidget * button)
+{
+ g_free (g_object_get_data ((GObject *) button, "buttondata"));
+}
+
+static GtkWidget * button_new_base (int type, int w, int h)
+{
+ GtkWidget * button;
+
+ if (type == BUTTON_TYPE_SMALL)
+ {
+ button = gtk_event_box_new ();
+ gtk_event_box_set_visible_window ((GtkEventBox *) button, FALSE);
+ }
+ else
+ button = gtk_drawing_area_new ();
+
+ gtk_widget_set_size_request (button, w * config.scale, h * config.scale);
+ gtk_widget_add_events (button, GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK);
+
+ if (type != BUTTON_TYPE_SMALL)
+ DRAW_CONNECT (button, button_draw);
+
+ g_signal_connect (button, "button-press-event", (GCallback) button_press,
+ nullptr);
+ g_signal_connect (button, "button-release-event", (GCallback)
+ button_release, nullptr);
+ g_signal_connect (button, "destroy", (GCallback) button_destroy, nullptr);
+
+ ButtonData * data = g_new0 (ButtonData, 1);
+ data->type = type;
+ data->w = w;
+ data->h = h;
+ g_object_set_data ((GObject *) button, "buttondata", data);
+
+ return button;
+}
+
+GtkWidget * button_new (int w, int h, int nx, int ny, int px, int py,
+ SkinPixmapId si1, SkinPixmapId si2)
+{
+ GtkWidget * button = button_new_base (BUTTON_TYPE_NORMAL, w, h);
+ ButtonData * data = (ButtonData *) g_object_get_data ((GObject *) button, "buttondata");
+ g_return_val_if_fail (data, nullptr);
+
+ data->nx = nx;
+ data->ny = ny;
+ data->px = px;
+ data->py = py;
+ data->si1 = si1;
+ data->si2 = si2;
+
+ return button;
+}
+
+GtkWidget * button_new_toggle (int w, int h, int nx, int ny, int px, int
+ py, int pnx, int pny, int ppx, int ppy, SkinPixmapId si1, SkinPixmapId si2)
+{
+ GtkWidget * button = button_new_base (BUTTON_TYPE_TOGGLE, w, h);
+ ButtonData * data = (ButtonData *) g_object_get_data ((GObject *) button, "buttondata");
+ g_return_val_if_fail (data, nullptr);
+
+ data->nx = nx;
+ data->ny = ny;
+ data->px = px;
+ data->py = py;
+ data->pnx = pnx;
+ data->pny = pny;
+ data->ppx = ppx;
+ data->ppy = ppy;
+ data->si1 = si1;
+ data->si2 = si2;
+
+ return button;
+}
+
+GtkWidget * button_new_small (int w, int h)
+{
+ return button_new_base (BUTTON_TYPE_SMALL, w, h);
+}
+
+void button_on_press (GtkWidget * button, ButtonCB callback)
+{
+ ButtonData * data = (ButtonData *) g_object_get_data ((GObject *) button, "buttondata");
+ g_return_if_fail (data);
+
+ data->on_press = callback;
+}
+
+void button_on_release (GtkWidget * button, ButtonCB callback)
+{
+ ButtonData * data = (ButtonData *) g_object_get_data ((GObject *) button, "buttondata");
+ g_return_if_fail (data);
+
+ data->on_release = callback;
+}
+
+void button_on_rpress (GtkWidget * button, ButtonCB callback)
+{
+ ButtonData * data = (ButtonData *) g_object_get_data ((GObject *) button, "buttondata");
+ g_return_if_fail (data);
+
+ data->on_rpress = callback;
+}
+
+void button_on_rrelease (GtkWidget * button, ButtonCB callback)
+{
+ ButtonData * data = (ButtonData *) g_object_get_data ((GObject *) button, "buttondata");
+ g_return_if_fail (data);
+
+ data->on_rrelease = callback;
+}
+
+gboolean button_get_active (GtkWidget * button)
+{
+ ButtonData * data = (ButtonData *) g_object_get_data ((GObject *) button, "buttondata");
+ g_return_val_if_fail (data && data->type == BUTTON_TYPE_TOGGLE, FALSE);
+
+ return data->active;
+}
+
+void button_set_active (GtkWidget * button, gboolean active)
+{
+ ButtonData * data = (ButtonData *) g_object_get_data ((GObject *) button, "buttondata");
+ g_return_if_fail (data && data->type == BUTTON_TYPE_TOGGLE);
+
+ if (data->active == active)
+ return;
+
+ data->active = active;
+ gtk_widget_queue_draw (button);
+}
diff --git a/src/skins/ui_skinned_button.h b/src/skins/ui_skinned_button.h
index 8b992a5e68a1..47c0093e2449 100644
--- a/src/skins/ui_skinned_button.h
+++ b/src/skins/ui_skinned_button.h
@@ -28,12 +28,12 @@
typedef void (* ButtonCB) (GtkWidget * button, GdkEventButton * event);
-GtkWidget * button_new (gint w, gint h, gint nx, gint ny, gint px,
- gint py, SkinPixmapId si1, SkinPixmapId si2);
-GtkWidget * button_new_toggle (gint w, gint h, gint nx, gint ny,
- gint px, gint py, gint pnx, gint pny, gint ppx, gint ppy, SkinPixmapId si1,
+GtkWidget * button_new (int w, int h, int nx, int ny, int px,
+ int py, SkinPixmapId si1, SkinPixmapId si2);
+GtkWidget * button_new_toggle (int w, int h, int nx, int ny,
+ int px, int py, int pnx, int pny, int ppx, int ppy, SkinPixmapId si1,
SkinPixmapId si2);
-GtkWidget * button_new_small (gint w, gint h);
+GtkWidget * button_new_small (int w, int h);
void button_on_press (GtkWidget * button, ButtonCB callback);
void button_on_release (GtkWidget * button, ButtonCB callback);
diff --git a/src/skins/ui_skinned_equalizer_graph.c b/src/skins/ui_skinned_equalizer_graph.c
deleted file mode 100644
index 3b338ad5608e..000000000000
--- a/src/skins/ui_skinned_equalizer_graph.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz MoÅ
- * Copyright (c) 2011 John Lindgren
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; If not, see <http://www.gnu.org/licenses>.
- */
-
-#include <audacious/misc.h>
-
-#include "draw-compat.h"
-#include "ui_skin.h"
-#include "ui_skinned_equalizer_graph.h"
-
-static void init_spline (const gdouble * x, const gdouble * y, gint n, gdouble * y2)
-{
- gint i, k;
- gdouble p, qn, sig, un, *u;
-
- u = (gdouble *) g_malloc(n * sizeof(gdouble));
-
- y2[0] = u[0] = 0.0;
-
- for (i = 1; i < n - 1; i++) {
- sig = ((gdouble) x[i] - x[i - 1]) / ((gdouble) x[i + 1] - x[i - 1]);
- p = sig * y2[i - 1] + 2.0;
- y2[i] = (sig - 1.0) / p;
- u[i] =
- (((gdouble) y[i + 1] - y[i]) / (x[i + 1] - x[i])) -
- (((gdouble) y[i] - y[i - 1]) / (x[i] - x[i - 1]));
- u[i] = (6.0 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p;
- }
- qn = un = 0.0;
-
- y2[n - 1] = (un - qn * u[n - 2]) / (qn * y2[n - 2] + 1.0);
- for (k = n - 2; k >= 0; k--)
- y2[k] = y2[k] * y2[k + 1] + u[k];
- g_free(u);
-}
-
-gdouble eval_spline (const gdouble * xa, const gdouble * ya, const gdouble * y2a,
- gint n, gdouble x)
-{
- gint klo, khi, k;
- gdouble h, b, a;
-
- klo = 0;
- khi = n - 1;
- while (khi - klo > 1) {
- k = (khi + klo) >> 1;
- if (xa[k] > x)
- khi = k;
- else
- klo = k;
- }
- h = xa[khi] - xa[klo];
- a = (xa[khi] - x) / h;
- b = (x - xa[klo]) / h;
- return (a * ya[klo] + b * ya[khi] +
- ((a * a * a - a) * y2a[klo] +
- (b * b * b - b) * y2a[khi]) * (h * h) / 6.0);
-}
-
-DRAW_FUNC_BEGIN (eq_graph_draw)
- static const gdouble x[10] = {0, 11, 23, 35, 47, 59, 71, 83, 97, 109};
-
- skin_draw_pixbuf (cr, SKIN_EQMAIN, 0, 294, 0, 0, 113, 19);
- skin_draw_pixbuf (cr, SKIN_EQMAIN, 0, 314, 0, 9 + (aud_get_double (NULL,
- "equalizer_preamp") * 9 + EQUALIZER_MAX_GAIN / 2) / EQUALIZER_MAX_GAIN, 113, 1);
-
- guint32 cols[19];
- skin_get_eq_spline_colors(active_skin, cols);
-
- gdouble bands[AUD_EQUALIZER_NBANDS];
- aud_eq_get_bands (bands);
-
- gdouble yf[10];
- init_spline (x, bands, 10, yf);
-
- /* now draw a pixelated line with vector graphics ... -- jlindgren */
- gint py = 0;
- for (gint i = 0; i < 109; i ++)
- {
- gint y = 9.5 - eval_spline (x, bands, yf, 10, i) * 9 / EQUALIZER_MAX_GAIN;
- y = CLAMP (y, 0, 18);
-
- if (!i)
- py = y;
-
- gint ymin, ymax;
-
- if (y > py)
- {
- ymin = py + 1;
- ymax = y;
- }
- else if (y < py)
- {
- ymin = y;
- ymax = py - 1;
- }
- else
- ymin = ymax = y;
-
- py = y;
-
- for (y = ymin; y <= ymax; y++)
- {
- cairo_rectangle (cr, i + 2, y, 1, 1);
- set_cairo_color (cr, cols[y]);
- cairo_fill (cr);
- }
- }
-DRAW_FUNC_END
-
-GtkWidget * eq_graph_new (void)
-{
- GtkWidget * graph = gtk_drawing_area_new ();
- gtk_widget_set_size_request (graph, 113, 19);
- DRAW_CONNECT (graph, eq_graph_draw);
- return graph;
-}
-
-void eq_graph_update (GtkWidget * graph)
-{
- gtk_widget_queue_draw (graph);
-}
diff --git a/src/skins/ui_skinned_equalizer_graph.cc b/src/skins/ui_skinned_equalizer_graph.cc
new file mode 100644
index 000000000000..42b22d2bf67b
--- /dev/null
+++ b/src/skins/ui_skinned_equalizer_graph.cc
@@ -0,0 +1,147 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz MoÅ
+ * Copyright (c) 2011 John Lindgren
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see <http://www.gnu.org/licenses>.
+ */
+
+#include <libaudcore/equalizer.h>
+#include <libaudcore/runtime.h>
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "ui_skin.h"
+#include "ui_skinned_equalizer_graph.h"
+
+static void init_spline (const double * x, const double * y, int n, double * y2)
+{
+ int i, k;
+ double p, qn, sig, un, *u;
+
+ u = (double *) g_malloc(n * sizeof(double));
+
+ y2[0] = u[0] = 0.0;
+
+ for (i = 1; i < n - 1; i++) {
+ sig = ((double) x[i] - x[i - 1]) / ((double) x[i + 1] - x[i - 1]);
+ p = sig * y2[i - 1] + 2.0;
+ y2[i] = (sig - 1.0) / p;
+ u[i] =
+ (((double) y[i + 1] - y[i]) / (x[i + 1] - x[i])) -
+ (((double) y[i] - y[i - 1]) / (x[i] - x[i - 1]));
+ u[i] = (6.0 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p;
+ }
+ qn = un = 0.0;
+
+ y2[n - 1] = (un - qn * u[n - 2]) / (qn * y2[n - 2] + 1.0);
+ for (k = n - 2; k >= 0; k--)
+ y2[k] = y2[k] * y2[k + 1] + u[k];
+ g_free(u);
+}
+
+double eval_spline (const double * xa, const double * ya, const double * y2a,
+ int n, double x)
+{
+ int klo, khi, k;
+ double h, b, a;
+
+ klo = 0;
+ khi = n - 1;
+ while (khi - klo > 1) {
+ k = (khi + klo) >> 1;
+ if (xa[k] > x)
+ khi = k;
+ else
+ klo = k;
+ }
+ h = xa[khi] - xa[klo];
+ a = (xa[khi] - x) / h;
+ b = (x - xa[klo]) / h;
+ return (a * ya[klo] + b * ya[khi] +
+ ((a * a * a - a) * y2a[klo] +
+ (b * b * b - b) * y2a[khi]) * (h * h) / 6.0);
+}
+
+DRAW_FUNC_BEGIN (eq_graph_draw)
+ static const double x[10] = {0, 11, 23, 35, 47, 59, 71, 83, 97, 109};
+
+ skin_draw_pixbuf (cr, SKIN_EQMAIN, 0, 294, 0, 0, 113, 19);
+ skin_draw_pixbuf (cr, SKIN_EQMAIN, 0, 314, 0, 9 + (aud_get_double (nullptr,
+ "equalizer_preamp") * 9 + AUD_EQ_MAX_GAIN / 2) / AUD_EQ_MAX_GAIN, 113, 1);
+
+ cairo_scale (cr, config.scale, config.scale);
+
+ uint32_t cols[19];
+ skin_get_eq_spline_colors(active_skin, cols);
+
+ double bands[AUD_EQ_NBANDS];
+ aud_eq_get_bands (bands);
+
+ double yf[10];
+ init_spline (x, bands, 10, yf);
+
+ /* now draw a pixelated line with vector graphics ... -- jlindgren */
+ int py = 0;
+ for (int i = 0; i < 109; i ++)
+ {
+ int y = 9.5 - eval_spline (x, bands, yf, 10, i) * 9 / AUD_EQ_MAX_GAIN;
+ y = aud::clamp (y, 0, 18);
+
+ if (!i)
+ py = y;
+
+ int ymin, ymax;
+
+ if (y > py)
+ {
+ ymin = py + 1;
+ ymax = y;
+ }
+ else if (y < py)
+ {
+ ymin = y;
+ ymax = py - 1;
+ }
+ else
+ ymin = ymax = y;
+
+ py = y;
+
+ for (y = ymin; y <= ymax; y++)
+ {
+ cairo_rectangle (cr, i + 2, y, 1, 1);
+ set_cairo_color (cr, cols[y]);
+ cairo_fill (cr);
+ }
+ }
+DRAW_FUNC_END
+
+GtkWidget * eq_graph_new (void)
+{
+ GtkWidget * graph = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (graph, 113 * config.scale, 19 * config.scale);
+ DRAW_CONNECT (graph, eq_graph_draw);
+ return graph;
+}
+
+void eq_graph_update (GtkWidget * graph)
+{
+ gtk_widget_queue_draw (graph);
+}
diff --git a/src/skins/ui_skinned_equalizer_slider.c b/src/skins/ui_skinned_equalizer_slider.c
deleted file mode 100644
index 82ebcbd90c1b..000000000000
--- a/src/skins/ui_skinned_equalizer_slider.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz MoÅ
- * Copyright (c) 2011 John Lindgren
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; If not, see <http://www.gnu.org/licenses>.
- */
-
-#include <audacious/i18n.h>
-#include <audacious/types.h>
-
-#include "draw-compat.h"
-#include "ui_equalizer.h"
-#include "ui_main.h"
-#include "ui_skin.h"
-#include "ui_skinned_equalizer_slider.h"
-
-typedef struct {
- gchar * name;
- gint pos;
- gfloat val;
- gboolean pressed;
-} EqSliderData;
-
-DRAW_FUNC_BEGIN (eq_slider_draw)
- EqSliderData * data = g_object_get_data ((GObject *) wid, "eqsliderdata");
- g_return_val_if_fail (data, FALSE);
-
- gint frame = 27 - data->pos * 27 / 50;
- if (frame < 14)
- skin_draw_pixbuf (cr, SKIN_EQMAIN, 13 + 15 * frame, 164, 0, 0, 14, 63);
- else
- skin_draw_pixbuf (cr, SKIN_EQMAIN, 13 + 15 * (frame - 14), 229, 0, 0,
- 14, 63);
-
- if (data->pressed)
- skin_draw_pixbuf (cr, SKIN_EQMAIN, 0, 176, 1, data->pos, 11, 11);
- else
- skin_draw_pixbuf (cr, SKIN_EQMAIN, 0, 164, 1, data->pos, 11, 11);
-DRAW_FUNC_END
-
-static void eq_slider_moved (EqSliderData * data, gint pos)
-{
- data->pos = CLAMP (pos, 0, 50);
- if (data->pos == 24 || data->pos == 26)
- data->pos = 25;
-
- data->val = (gfloat) (25 - data->pos) * EQUALIZER_MAX_GAIN / 25;
-
- equalizerwin_eq_changed ();
-
- gchar buf[100];
- snprintf (buf, sizeof buf, "%s: %+.1f dB", data->name, data->val);
- mainwin_show_status_message (buf);
-}
-
-static gboolean eq_slider_button_press (GtkWidget * slider, GdkEventButton *
- event)
-{
- EqSliderData * data = g_object_get_data ((GObject *) slider, "eqsliderdata");
- g_return_val_if_fail (data, FALSE);
-
- if (event->button != 1)
- return FALSE;
-
- data->pressed = TRUE;
-
- eq_slider_moved (data, event->y - 5);
- gtk_widget_queue_draw (slider);
- return TRUE;
-}
-
-static gboolean eq_slider_button_release (GtkWidget * slider, GdkEventButton *
- event)
-{
- EqSliderData * data = g_object_get_data ((GObject *) slider, "eqsliderdata");
- g_return_val_if_fail (data, FALSE);
-
- if (event->button != 1)
- return FALSE;
-
- if (! data->pressed)
- return TRUE;
-
- data->pressed = FALSE;
-
- eq_slider_moved (data, event->y - 5);
- gtk_widget_queue_draw (slider);
- return TRUE;
-}
-
-static gboolean eq_slider_motion (GtkWidget * slider, GdkEventMotion * event)
-{
- EqSliderData * data = g_object_get_data ((GObject *) slider, "eqsliderdata");
- g_return_val_if_fail (data, FALSE);
-
- if (! data->pressed)
- return TRUE;
-
- eq_slider_moved (data, event->y - 5);
- gtk_widget_queue_draw (slider);
- return TRUE;
-}
-
-static gboolean eq_slider_scroll (GtkWidget * slider, GdkEventScroll * event)
-{
- EqSliderData * data = g_object_get_data ((GObject *) slider, "eqsliderdata");
- g_return_val_if_fail (data, FALSE);
-
- if (event->direction == GDK_SCROLL_UP)
- eq_slider_moved (data, data->pos - 2);
- else
- eq_slider_moved (data, data->pos + 2);
-
- gtk_widget_queue_draw (slider);
- return TRUE;
-}
-
-void eq_slider_set_val (GtkWidget * slider, gfloat val)
-{
- EqSliderData * data = g_object_get_data ((GObject *) slider, "eqsliderdata");
- g_return_if_fail (data);
-
- if (data->pressed)
- return;
-
- data->val = val;
- data->pos = 25 - (gint) (val * 25 / EQUALIZER_MAX_GAIN);
- data->pos = CLAMP (data->pos, 0, 50);
-
- gtk_widget_queue_draw (slider);
-}
-
-gfloat eq_slider_get_val (GtkWidget * slider)
-{
- EqSliderData * data = g_object_get_data ((GObject *) slider, "eqsliderdata");
- g_return_val_if_fail (data, 0);
-
- return data->val;
-}
-
-static void eq_slider_destroy (GtkWidget * slider)
-{
- EqSliderData * data = g_object_get_data ((GObject *) slider, "eqsliderdata");
- g_return_if_fail (data);
-
- g_free (data->name);
- g_free (data);
-}
-
-GtkWidget * eq_slider_new (const gchar * name)
-{
- GtkWidget * slider = gtk_drawing_area_new ();
- gtk_widget_set_size_request (slider, 14, 63);
- gtk_widget_add_events (slider, GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK);
-
- DRAW_CONNECT (slider, eq_slider_draw);
-
- g_signal_connect (slider, "button-press-event", (GCallback)
- eq_slider_button_press, NULL);
- g_signal_connect (slider, "button-release-event", (GCallback)
- eq_slider_button_release, NULL);
- g_signal_connect (slider, "motion-notify-event", (GCallback)
- eq_slider_motion, NULL);
- g_signal_connect (slider, "scroll-event", (GCallback) eq_slider_scroll,
- NULL);
- g_signal_connect (slider, "destroy", (GCallback) eq_slider_destroy, NULL);
-
- EqSliderData * data = g_malloc0 (sizeof (EqSliderData));
- data->name = g_strdup (name);
- g_object_set_data ((GObject *) slider, "eqsliderdata", data);
-
- return slider;
-}
diff --git a/src/skins/ui_skinned_equalizer_slider.cc b/src/skins/ui_skinned_equalizer_slider.cc
new file mode 100644
index 000000000000..69fffab0b2d0
--- /dev/null
+++ b/src/skins/ui_skinned_equalizer_slider.cc
@@ -0,0 +1,191 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz MoÅ
+ * Copyright (c) 2011 John Lindgren
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see <http://www.gnu.org/licenses>.
+ */
+
+#include <libaudcore/i18n.h>
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "ui_equalizer.h"
+#include "ui_main.h"
+#include "ui_skin.h"
+#include "ui_skinned_equalizer_slider.h"
+
+typedef struct {
+ char * name;
+ int pos;
+ float val;
+ gboolean pressed;
+} EqSliderData;
+
+DRAW_FUNC_BEGIN (eq_slider_draw)
+ EqSliderData * data = (EqSliderData *) g_object_get_data ((GObject *) wid, "eqsliderdata");
+ g_return_val_if_fail (data, FALSE);
+
+ int frame = 27 - data->pos * 27 / 50;
+ if (frame < 14)
+ skin_draw_pixbuf (cr, SKIN_EQMAIN, 13 + 15 * frame, 164, 0, 0, 14, 63);
+ else
+ skin_draw_pixbuf (cr, SKIN_EQMAIN, 13 + 15 * (frame - 14), 229, 0, 0,
+ 14, 63);
+
+ if (data->pressed)
+ skin_draw_pixbuf (cr, SKIN_EQMAIN, 0, 176, 1, data->pos, 11, 11);
+ else
+ skin_draw_pixbuf (cr, SKIN_EQMAIN, 0, 164, 1, data->pos, 11, 11);
+DRAW_FUNC_END
+
+static void eq_slider_moved (EqSliderData * data, int pos)
+{
+ data->pos = aud::clamp (pos, 0, 50);
+ if (data->pos == 24 || data->pos == 26)
+ data->pos = 25;
+
+ data->val = (float) (25 - data->pos) * AUD_EQ_MAX_GAIN / 25;
+
+ equalizerwin_eq_changed ();
+
+ char buf[100];
+ snprintf (buf, sizeof buf, "%s: %+.1f dB", data->name, data->val);
+ mainwin_show_status_message (buf);
+}
+
+static gboolean eq_slider_button_press (GtkWidget * slider, GdkEventButton *
+ event)
+{
+ EqSliderData * data = (EqSliderData *) g_object_get_data ((GObject *) slider, "eqsliderdata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (event->button != 1)
+ return FALSE;
+
+ data->pressed = TRUE;
+
+ eq_slider_moved (data, event->y / config.scale - 5);
+ gtk_widget_queue_draw (slider);
+ return TRUE;
+}
+
+static gboolean eq_slider_button_release (GtkWidget * slider, GdkEventButton *
+ event)
+{
+ EqSliderData * data = (EqSliderData *) g_object_get_data ((GObject *) slider, "eqsliderdata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (event->button != 1)
+ return FALSE;
+
+ if (! data->pressed)
+ return TRUE;
+
+ data->pressed = FALSE;
+
+ eq_slider_moved (data, event->y / config.scale - 5);
+ gtk_widget_queue_draw (slider);
+ return TRUE;
+}
+
+static gboolean eq_slider_motion (GtkWidget * slider, GdkEventMotion * event)
+{
+ EqSliderData * data = (EqSliderData *) g_object_get_data ((GObject *) slider, "eqsliderdata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (! data->pressed)
+ return TRUE;
+
+ eq_slider_moved (data, event->y / config.scale - 5);
+ gtk_widget_queue_draw (slider);
+ return TRUE;
+}
+
+static gboolean eq_slider_scroll (GtkWidget * slider, GdkEventScroll * event)
+{
+ EqSliderData * data = (EqSliderData *) g_object_get_data ((GObject *) slider, "eqsliderdata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (event->direction == GDK_SCROLL_UP)
+ eq_slider_moved (data, data->pos - 2);
+ else
+ eq_slider_moved (data, data->pos + 2);
+
+ gtk_widget_queue_draw (slider);
+ return TRUE;
+}
+
+void eq_slider_set_val (GtkWidget * slider, float val)
+{
+ EqSliderData * data = (EqSliderData *) g_object_get_data ((GObject *) slider, "eqsliderdata");
+ g_return_if_fail (data);
+
+ if (data->pressed)
+ return;
+
+ data->val = val;
+ data->pos = 25 - (int) (val * 25 / AUD_EQ_MAX_GAIN);
+ data->pos = aud::clamp (data->pos, 0, 50);
+
+ gtk_widget_queue_draw (slider);
+}
+
+float eq_slider_get_val (GtkWidget * slider)
+{
+ EqSliderData * data = (EqSliderData *) g_object_get_data ((GObject *) slider, "eqsliderdata");
+ g_return_val_if_fail (data, 0);
+
+ return data->val;
+}
+
+static void eq_slider_destroy (GtkWidget * slider)
+{
+ EqSliderData * data = (EqSliderData *) g_object_get_data ((GObject *) slider, "eqsliderdata");
+ g_return_if_fail (data);
+
+ g_free (data->name);
+ g_free (data);
+}
+
+GtkWidget * eq_slider_new (const char * name)
+{
+ GtkWidget * slider = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (slider, 14 * config.scale, 63 * config.scale);
+ gtk_widget_add_events (slider, GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK);
+
+ DRAW_CONNECT (slider, eq_slider_draw);
+
+ g_signal_connect (slider, "button-press-event", (GCallback)
+ eq_slider_button_press, nullptr);
+ g_signal_connect (slider, "button-release-event", (GCallback)
+ eq_slider_button_release, nullptr);
+ g_signal_connect (slider, "motion-notify-event", (GCallback)
+ eq_slider_motion, nullptr);
+ g_signal_connect (slider, "scroll-event", (GCallback) eq_slider_scroll,
+ nullptr);
+ g_signal_connect (slider, "destroy", (GCallback) eq_slider_destroy, nullptr);
+
+ EqSliderData * data = g_new0 (EqSliderData, 1);
+ data->name = g_strdup (name);
+ g_object_set_data ((GObject *) slider, "eqsliderdata", data);
+
+ return slider;
+}
diff --git a/src/skins/ui_skinned_equalizer_slider.h b/src/skins/ui_skinned_equalizer_slider.h
index 0a1207186c29..bca392a50a44 100644
--- a/src/skins/ui_skinned_equalizer_slider.h
+++ b/src/skins/ui_skinned_equalizer_slider.h
@@ -27,8 +27,8 @@
#include <gtk/gtk.h>
-GtkWidget * eq_slider_new (const gchar * name);
-void eq_slider_set_val (GtkWidget * widget, gfloat val);
-gfloat eq_slider_get_val (GtkWidget * widget);
+GtkWidget * eq_slider_new (const char * name);
+void eq_slider_set_val (GtkWidget * widget, float val);
+float eq_slider_get_val (GtkWidget * widget);
#endif
diff --git a/src/skins/ui_skinned_horizontal_slider.c b/src/skins/ui_skinned_horizontal_slider.c
deleted file mode 100644
index d806f15cf6e1..000000000000
--- a/src/skins/ui_skinned_horizontal_slider.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz MoÅ
- * Copyright (c) 2011 John Lindgren
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "draw-compat.h"
-#include "ui_skin.h"
-#include "ui_skinned_horizontal_slider.h"
-
-typedef struct {
- gint min, max, pos;
- gboolean pressed;
- SkinPixmapId si;
- gint w, h;
- gint fx, fy;
- gint kw, kh;
- gint knx, kny, kpx, kpy;
- void (* on_motion) (void);
- void (* on_release) (void);
-} HSliderData;
-
-DRAW_FUNC_BEGIN (hslider_draw)
- HSliderData * data = g_object_get_data ((GObject *) wid, "hsliderdata");
- g_return_val_if_fail (data, FALSE);
-
- skin_draw_pixbuf (cr, data->si, data->fx, data->fy, 0, 0, data->w, data->h);
-
- if (data->pressed)
- skin_draw_pixbuf (cr, data->si, data->kpx, data->kpy, data->pos,
- (data->h - data->kh) / 2, data->kw, data->kh);
- else
- skin_draw_pixbuf (cr, data->si, data->knx, data->kny, data->pos,
- (data->h - data->kh) / 2, data->kw, data->kh);
-DRAW_FUNC_END
-
-static gboolean hslider_button_press (GtkWidget * hslider, GdkEventButton *
- event)
-{
- HSliderData * data = g_object_get_data ((GObject *) hslider, "hsliderdata");
- g_return_val_if_fail (data, FALSE);
-
- if (event->button != 1)
- return FALSE;
-
- data->pressed = TRUE;
- data->pos = event->x - data->kw / 2;
- data->pos = CLAMP (data->pos, data->min, data->max);
-
- if (data->on_motion)
- data->on_motion ();
-
- gtk_widget_queue_draw (hslider);
- return TRUE;
-}
-
-static gboolean hslider_button_release (GtkWidget * hslider, GdkEventButton *
- event)
-{
- HSliderData * data = g_object_get_data ((GObject *) hslider, "hsliderdata");
- g_return_val_if_fail (data, FALSE);
-
- if (event->button != 1)
- return FALSE;
-
- if (! data->pressed)
- return TRUE;
-
- data->pressed = FALSE;
- data->pos = event->x - data->kw / 2;
- data->pos = CLAMP (data->pos, data->min, data->max);
-
- if (data->on_release)
- data->on_release ();
-
- gtk_widget_queue_draw (hslider);
- return TRUE;
-}
-
-static gboolean hslider_motion_notify (GtkWidget * hslider, GdkEventMotion *
- event)
-{
- HSliderData * data = g_object_get_data ((GObject *) hslider, "hsliderdata");
- g_return_val_if_fail (data, FALSE);
-
- if (! data->pressed)
- return TRUE;
-
- data->pressed = TRUE;
- data->pos = event->x - data->kw / 2;
- data->pos = CLAMP (data->pos, data->min, data->max);
-
- if (data->on_motion)
- data->on_motion ();
-
- gtk_widget_queue_draw (hslider);
- return TRUE;
-}
-
-static void hslider_destroy (GtkWidget * hslider)
-{
- g_free (g_object_get_data ((GObject *) hslider, "hsliderdata"));
-}
-
-GtkWidget * hslider_new (gint min, gint max, SkinPixmapId si, gint w, gint h,
- gint fx, gint fy, gint kw, gint kh, gint knx, gint kny, gint kpx, gint kpy)
-{
- GtkWidget * hslider = gtk_drawing_area_new ();
- gtk_widget_set_size_request (hslider, w, h);
- gtk_widget_add_events (hslider, GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
-
- DRAW_CONNECT (hslider, hslider_draw);
-
- g_signal_connect (hslider, "button-press-event", (GCallback)
- hslider_button_press, NULL);
- g_signal_connect (hslider, "button-release-event", (GCallback)
- hslider_button_release, NULL);
- g_signal_connect (hslider, "motion-notify-event", (GCallback)
- hslider_motion_notify, NULL);
- g_signal_connect (hslider, "destroy", (GCallback) hslider_destroy, NULL);
-
- HSliderData * data = g_malloc0 (sizeof (HSliderData));
- data->min = min;
- data->max = max;
- data->pos = min;
- data->si = si;
- data->w = w;
- data->h = h;
- data->fx = fx;
- data->fy = fy;
- data->kw = kw;
- data->kh = kh;
- data->knx = knx;
- data->kny = kny;
- data->kpx = kpx;
- data->kpy = kpy;
- g_object_set_data ((GObject *) hslider, "hsliderdata", data);
-
- return hslider;
-}
-
-void hslider_set_frame (GtkWidget * hslider, gint fx, gint fy)
-{
- HSliderData * data = g_object_get_data ((GObject *) hslider, "hsliderdata");
- g_return_if_fail (data);
-
- data->fx = fx;
- data->fy = fy;
- gtk_widget_queue_draw (hslider);
-}
-
-void hslider_set_knob (GtkWidget * hslider, gint knx, gint kny, gint kpx, gint
- kpy)
-{
- HSliderData * data = g_object_get_data ((GObject *) hslider, "hsliderdata");
- g_return_if_fail (data);
-
- data->knx = knx;
- data->kny = kny;
- data->kpx = kpx;
- data->kpy = kpy;
- gtk_widget_queue_draw (hslider);
-}
-
-gint hslider_get_pos (GtkWidget * hslider)
-{
- HSliderData * data = g_object_get_data ((GObject *) hslider, "hsliderdata");
- g_return_val_if_fail (data, 0);
-
- return data->pos;
-}
-
-void hslider_set_pos (GtkWidget * hslider, gint pos)
-{
- HSliderData * data = g_object_get_data ((GObject *) hslider, "hsliderdata");
- g_return_if_fail (data);
-
- if (data->pressed)
- return;
-
- data->pos = CLAMP (pos, data->min, data->max);
- gtk_widget_queue_draw (hslider);
-}
-
-gboolean hslider_get_pressed (GtkWidget * hslider)
-{
- HSliderData * data = g_object_get_data ((GObject *) hslider, "hsliderdata");
- g_return_val_if_fail (data, FALSE);
-
- return data->pressed;
-}
-
-void hslider_set_pressed (GtkWidget * hslider, gboolean pressed)
-{
- HSliderData * data = g_object_get_data ((GObject *) hslider, "hsliderdata");
- g_return_if_fail (data);
-
- data->pressed = pressed;
- gtk_widget_queue_draw (hslider);
-}
-
-void hslider_on_motion (GtkWidget * hslider, void (* callback) (void))
-{
- HSliderData * data = g_object_get_data ((GObject *) hslider, "hsliderdata");
- g_return_if_fail (data);
-
- data->on_motion = callback;
-}
-
-void hslider_on_release (GtkWidget * hslider, void (* callback) (void))
-{
- HSliderData * data = g_object_get_data ((GObject *) hslider, "hsliderdata");
- g_return_if_fail (data);
-
- data->on_release = callback;
-}
diff --git a/src/skins/ui_skinned_horizontal_slider.cc b/src/skins/ui_skinned_horizontal_slider.cc
new file mode 100644
index 000000000000..8e523048dd8c
--- /dev/null
+++ b/src/skins/ui_skinned_horizontal_slider.cc
@@ -0,0 +1,241 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz MoÅ
+ * Copyright (c) 2011 John Lindgren
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <libaudcore/objects.h>
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "ui_skin.h"
+#include "ui_skinned_horizontal_slider.h"
+
+typedef struct {
+ int min, max, pos;
+ gboolean pressed;
+ SkinPixmapId si;
+ int w, h;
+ int fx, fy;
+ int kw, kh;
+ int knx, kny, kpx, kpy;
+ void (* on_motion) (void);
+ void (* on_release) (void);
+} HSliderData;
+
+DRAW_FUNC_BEGIN (hslider_draw)
+ HSliderData * data = (HSliderData *) g_object_get_data ((GObject *) wid, "hsliderdata");
+ g_return_val_if_fail (data, FALSE);
+
+ skin_draw_pixbuf (cr, data->si, data->fx, data->fy, 0, 0, data->w, data->h);
+
+ if (data->pressed)
+ skin_draw_pixbuf (cr, data->si, data->kpx, data->kpy, data->pos,
+ (data->h - data->kh) / 2, data->kw, data->kh);
+ else
+ skin_draw_pixbuf (cr, data->si, data->knx, data->kny, data->pos,
+ (data->h - data->kh) / 2, data->kw, data->kh);
+DRAW_FUNC_END
+
+static gboolean hslider_button_press (GtkWidget * hslider, GdkEventButton *
+ event)
+{
+ HSliderData * data = (HSliderData *) g_object_get_data ((GObject *) hslider, "hsliderdata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (event->button != 1)
+ return FALSE;
+
+ data->pressed = TRUE;
+ data->pos = event->x / config.scale - data->kw / 2;
+ data->pos = aud::clamp (data->pos, data->min, data->max);
+
+ if (data->on_motion)
+ data->on_motion ();
+
+ gtk_widget_queue_draw (hslider);
+ return TRUE;
+}
+
+static gboolean hslider_button_release (GtkWidget * hslider, GdkEventButton *
+ event)
+{
+ HSliderData * data = (HSliderData *) g_object_get_data ((GObject *) hslider, "hsliderdata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (event->button != 1)
+ return FALSE;
+
+ if (! data->pressed)
+ return TRUE;
+
+ data->pressed = FALSE;
+ data->pos = event->x / config.scale - data->kw / 2;
+ data->pos = aud::clamp (data->pos, data->min, data->max);
+
+ if (data->on_release)
+ data->on_release ();
+
+ gtk_widget_queue_draw (hslider);
+ return TRUE;
+}
+
+static gboolean hslider_motion_notify (GtkWidget * hslider, GdkEventMotion *
+ event)
+{
+ HSliderData * data = (HSliderData *) g_object_get_data ((GObject *) hslider, "hsliderdata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (! data->pressed)
+ return TRUE;
+
+ data->pressed = TRUE;
+ data->pos = event->x / config.scale - data->kw / 2;
+ data->pos = aud::clamp (data->pos, data->min, data->max);
+
+ if (data->on_motion)
+ data->on_motion ();
+
+ gtk_widget_queue_draw (hslider);
+ return TRUE;
+}
+
+static void hslider_destroy (GtkWidget * hslider)
+{
+ g_free (g_object_get_data ((GObject *) hslider, "hsliderdata"));
+}
+
+GtkWidget * hslider_new (int min, int max, SkinPixmapId si, int w, int h,
+ int fx, int fy, int kw, int kh, int knx, int kny, int kpx, int kpy)
+{
+ GtkWidget * hslider = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (hslider, w * config.scale, h * config.scale);
+ gtk_widget_add_events (hslider, GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
+
+ DRAW_CONNECT (hslider, hslider_draw);
+
+ g_signal_connect (hslider, "button-press-event", (GCallback)
+ hslider_button_press, nullptr);
+ g_signal_connect (hslider, "button-release-event", (GCallback)
+ hslider_button_release, nullptr);
+ g_signal_connect (hslider, "motion-notify-event", (GCallback)
+ hslider_motion_notify, nullptr);
+ g_signal_connect (hslider, "destroy", (GCallback) hslider_destroy, nullptr);
+
+ HSliderData * data = g_new0 (HSliderData, 1);
+ data->min = min;
+ data->max = max;
+ data->pos = min;
+ data->si = si;
+ data->w = w;
+ data->h = h;
+ data->fx = fx;
+ data->fy = fy;
+ data->kw = kw;
+ data->kh = kh;
+ data->knx = knx;
+ data->kny = kny;
+ data->kpx = kpx;
+ data->kpy = kpy;
+ g_object_set_data ((GObject *) hslider, "hsliderdata", data);
+
+ return hslider;
+}
+
+void hslider_set_frame (GtkWidget * hslider, int fx, int fy)
+{
+ HSliderData * data = (HSliderData *) g_object_get_data ((GObject *) hslider, "hsliderdata");
+ g_return_if_fail (data);
+
+ data->fx = fx;
+ data->fy = fy;
+ gtk_widget_queue_draw (hslider);
+}
+
+void hslider_set_knob (GtkWidget * hslider, int knx, int kny, int kpx, int
+ kpy)
+{
+ HSliderData * data = (HSliderData *) g_object_get_data ((GObject *) hslider, "hsliderdata");
+ g_return_if_fail (data);
+
+ data->knx = knx;
+ data->kny = kny;
+ data->kpx = kpx;
+ data->kpy = kpy;
+ gtk_widget_queue_draw (hslider);
+}
+
+int hslider_get_pos (GtkWidget * hslider)
+{
+ HSliderData * data = (HSliderData *) g_object_get_data ((GObject *) hslider, "hsliderdata");
+ g_return_val_if_fail (data, 0);
+
+ return data->pos;
+}
+
+void hslider_set_pos (GtkWidget * hslider, int pos)
+{
+ HSliderData * data = (HSliderData *) g_object_get_data ((GObject *) hslider, "hsliderdata");
+ g_return_if_fail (data);
+
+ if (data->pressed)
+ return;
+
+ data->pos = aud::clamp (pos, data->min, data->max);
+ gtk_widget_queue_draw (hslider);
+}
+
+gboolean hslider_get_pressed (GtkWidget * hslider)
+{
+ HSliderData * data = (HSliderData *) g_object_get_data ((GObject *) hslider, "hsliderdata");
+ g_return_val_if_fail (data, FALSE);
+
+ return data->pressed;
+}
+
+void hslider_set_pressed (GtkWidget * hslider, gboolean pressed)
+{
+ HSliderData * data = (HSliderData *) g_object_get_data ((GObject *) hslider, "hsliderdata");
+ g_return_if_fail (data);
+
+ data->pressed = pressed;
+ gtk_widget_queue_draw (hslider);
+}
+
+void hslider_on_motion (GtkWidget * hslider, void (* callback) (void))
+{
+ HSliderData * data = (HSliderData *) g_object_get_data ((GObject *) hslider, "hsliderdata");
+ g_return_if_fail (data);
+
+ data->on_motion = callback;
+}
+
+void hslider_on_release (GtkWidget * hslider, void (* callback) (void))
+{
+ HSliderData * data = (HSliderData *) g_object_get_data ((GObject *) hslider, "hsliderdata");
+ g_return_if_fail (data);
+
+ data->on_release = callback;
+}
diff --git a/src/skins/ui_skinned_horizontal_slider.h b/src/skins/ui_skinned_horizontal_slider.h
index 9be02363b44f..866885610f75 100644
--- a/src/skins/ui_skinned_horizontal_slider.h
+++ b/src/skins/ui_skinned_horizontal_slider.h
@@ -30,13 +30,13 @@
#include <gtk/gtk.h>
-GtkWidget * hslider_new (gint min, gint max, SkinPixmapId si, gint w, gint h,
- gint fx, gint fy, gint kw, gint kh, gint knx, gint kny, gint kpx, gint kpy);
-void hslider_set_frame (GtkWidget * hslider, gint fx, gint fy);
-void hslider_set_knob (GtkWidget * hslider, gint knx, gint kny, gint kpx, gint
+GtkWidget * hslider_new (int min, int max, SkinPixmapId si, int w, int h,
+ int fx, int fy, int kw, int kh, int knx, int kny, int kpx, int kpy);
+void hslider_set_frame (GtkWidget * hslider, int fx, int fy);
+void hslider_set_knob (GtkWidget * hslider, int knx, int kny, int kpx, int
kpy);
-gint hslider_get_pos (GtkWidget * hslider);
-void hslider_set_pos (GtkWidget * hslider, gint pos);
+int hslider_get_pos (GtkWidget * hslider);
+void hslider_set_pos (GtkWidget * hslider, int pos);
gboolean hslider_get_pressed (GtkWidget * hslider);
void hslider_set_pressed (GtkWidget * hslider, gboolean pressed);
void hslider_on_motion (GtkWidget * hslider, void (* callback) (void));
diff --git a/src/skins/ui_skinned_menurow.c b/src/skins/ui_skinned_menurow.c
deleted file mode 100644
index a3e9f1504510..000000000000
--- a/src/skins/ui_skinned_menurow.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz MoÅ
- * Copyright (c) 2011 John Lindgren
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <audacious/misc.h>
-
-#include "draw-compat.h"
-#include "skins_cfg.h"
-#include "ui_skin.h"
-#include "ui_skinned_menurow.h"
-
-static struct {
- MenuRowItem selected;
- gboolean pushed;
-} mr;
-
-DRAW_FUNC_BEGIN (menurow_draw)
- if (mr.selected == MENUROW_NONE)
- {
- if (mr.pushed)
- skin_draw_pixbuf (cr, SKIN_TITLEBAR, 304, 0, 0, 0, 8, 43);
- else
- skin_draw_pixbuf (cr, SKIN_TITLEBAR, 312, 0, 0, 0, 8, 43);
- }
- else
- skin_draw_pixbuf (cr, SKIN_TITLEBAR, 304 + 8 * (mr.selected - 1), 44, 0,
- 0, 8, 43);
-
- if (mr.pushed)
- {
- if (aud_get_bool ("skins", "always_on_top"))
- skin_draw_pixbuf (cr, SKIN_TITLEBAR, 312, 54, 0, 10, 8, 8);
-#if 0
- if (config.scaled)
- skin_draw_pixbuf (cr, SKIN_TITLEBAR, 328, 70, 0, 26, 8, 8);
-#endif
- }
-DRAW_FUNC_END
-
-static MenuRowItem menurow_find_selected (gint x, gint y)
-{
- if (x >= 0 && x < 8)
- {
- if (y >= 0 && y < 10)
- return MENUROW_OPTIONS;
- if (y >= 10 && y < 18)
- return MENUROW_ALWAYS;
- if (y >= 18 && y < 26)
- return MENUROW_FILEINFOBOX;
- if (y >= 26 && y < 34)
- return MENUROW_SCALE;
- if (y >= 34 && y < 43)
- return MENUROW_VISUALIZATION;
- }
-
- return MENUROW_NONE;
-}
-
-static gboolean menurow_button_press (GtkWidget * widget, GdkEventButton * event)
-{
- if (event->button != 1)
- return FALSE;
-
- mr.pushed = TRUE;
- mr.selected = menurow_find_selected (event->x, event->y);
-
- mainwin_mr_change (mr.selected);
-
- gtk_widget_queue_draw (widget);
- return TRUE;
-}
-
-static gboolean menurow_button_release (GtkWidget * widget, GdkEventButton *
- event)
-{
- if (event->button != 1)
- return FALSE;
-
- if (! mr.pushed)
- return TRUE;
-
- mainwin_mr_release (mr.selected, event);
-
- mr.pushed = FALSE;
- mr.selected = MENUROW_NONE;
-
- gtk_widget_queue_draw (widget);
- return TRUE;
-}
-
-static gboolean menurow_motion_notify (GtkWidget * widget, GdkEventMotion *
- event)
-{
- if (! mr.pushed)
- return TRUE;
-
- mr.selected = menurow_find_selected (event->x, event->y);
-
- mainwin_mr_change (mr.selected);
-
- gtk_widget_queue_draw (widget);
- return TRUE;
-}
-
-GtkWidget * ui_skinned_menurow_new (void)
-{
- GtkWidget * wid = gtk_drawing_area_new ();
- gtk_widget_set_size_request (wid, 8, 43);
- gtk_widget_add_events (wid, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- | GDK_POINTER_MOTION_MASK);
-
- DRAW_CONNECT (wid, menurow_draw);
- g_signal_connect (wid, "button-press-event", (GCallback)
- menurow_button_press, NULL);
- g_signal_connect (wid, "button-release-event", (GCallback)
- menurow_button_release, NULL);
- g_signal_connect (wid, "motion-notify-event", (GCallback)
- menurow_motion_notify, NULL);
-
- return wid;
-}
-
-void ui_skinned_menurow_update (GtkWidget * menurow)
-{
- gtk_widget_queue_draw (menurow);
-}
diff --git a/src/skins/ui_skinned_menurow.cc b/src/skins/ui_skinned_menurow.cc
new file mode 100644
index 000000000000..ebd722d08507
--- /dev/null
+++ b/src/skins/ui_skinned_menurow.cc
@@ -0,0 +1,147 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz MoÅ
+ * Copyright (c) 2011 John Lindgren
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <libaudcore/runtime.h>
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "ui_skin.h"
+#include "ui_skinned_menurow.h"
+
+static struct {
+ MenuRowItem selected;
+ gboolean pushed;
+} mr;
+
+DRAW_FUNC_BEGIN (menurow_draw)
+ if (mr.selected == MENUROW_NONE)
+ {
+ if (mr.pushed)
+ skin_draw_pixbuf (cr, SKIN_TITLEBAR, 304, 0, 0, 0, 8, 43);
+ else
+ skin_draw_pixbuf (cr, SKIN_TITLEBAR, 312, 0, 0, 0, 8, 43);
+ }
+ else
+ skin_draw_pixbuf (cr, SKIN_TITLEBAR, 304 + 8 * (mr.selected - 1), 44, 0,
+ 0, 8, 43);
+
+ if (mr.pushed)
+ {
+ if (aud_get_bool ("skins", "always_on_top"))
+ skin_draw_pixbuf (cr, SKIN_TITLEBAR, 312, 54, 0, 10, 8, 8);
+ if (aud_get_bool ("skins", "double_size"))
+ skin_draw_pixbuf (cr, SKIN_TITLEBAR, 328, 70, 0, 26, 8, 8);
+ }
+DRAW_FUNC_END
+
+static MenuRowItem menurow_find_selected (int x, int y)
+{
+ if (x >= 0 && x < 8)
+ {
+ if (y >= 0 && y < 10)
+ return MENUROW_OPTIONS;
+ if (y >= 10 && y < 18)
+ return MENUROW_ALWAYS;
+ if (y >= 18 && y < 26)
+ return MENUROW_FILEINFOBOX;
+ if (y >= 26 && y < 34)
+ return MENUROW_SCALE;
+ if (y >= 34 && y < 43)
+ return MENUROW_VISUALIZATION;
+ }
+
+ return MENUROW_NONE;
+}
+
+static gboolean menurow_button_press (GtkWidget * widget, GdkEventButton * event)
+{
+ if (event->button != 1)
+ return FALSE;
+
+ mr.pushed = TRUE;
+ mr.selected = menurow_find_selected (event->x / config.scale, event->y / config.scale);
+
+ mainwin_mr_change (mr.selected);
+
+ gtk_widget_queue_draw (widget);
+ return TRUE;
+}
+
+static gboolean menurow_button_release (GtkWidget * widget, GdkEventButton *
+ event)
+{
+ if (event->button != 1)
+ return FALSE;
+
+ if (! mr.pushed)
+ return TRUE;
+
+ mainwin_mr_release (mr.selected, event);
+
+ mr.pushed = FALSE;
+ mr.selected = MENUROW_NONE;
+
+ gtk_widget_queue_draw (widget);
+ return TRUE;
+}
+
+static gboolean menurow_motion_notify (GtkWidget * widget, GdkEventMotion *
+ event)
+{
+ if (! mr.pushed)
+ return TRUE;
+
+ mr.selected = menurow_find_selected (event->x / config.scale, event->y / config.scale);
+
+ mainwin_mr_change (mr.selected);
+
+ gtk_widget_queue_draw (widget);
+ return TRUE;
+}
+
+GtkWidget * ui_skinned_menurow_new (void)
+{
+ GtkWidget * wid = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (wid, 8 * config.scale, 43 * config.scale);
+ gtk_widget_add_events (wid, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ | GDK_POINTER_MOTION_MASK);
+
+ DRAW_CONNECT (wid, menurow_draw);
+ g_signal_connect (wid, "button-press-event", (GCallback)
+ menurow_button_press, nullptr);
+ g_signal_connect (wid, "button-release-event", (GCallback)
+ menurow_button_release, nullptr);
+ g_signal_connect (wid, "motion-notify-event", (GCallback)
+ menurow_motion_notify, nullptr);
+
+ return wid;
+}
+
+void ui_skinned_menurow_update (GtkWidget * menurow)
+{
+ gtk_widget_queue_draw (menurow);
+}
diff --git a/src/skins/ui_skinned_monostereo.c b/src/skins/ui_skinned_monostereo.c
deleted file mode 100644
index 9410358b2233..000000000000
--- a/src/skins/ui_skinned_monostereo.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz MoÅ
- * Copyright (c) 2011 John Lindgren
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "draw-compat.h"
-#include "ui_skin.h"
-#include "ui_skinned_monostereo.h"
-
-static gint monostereo_num_channels;
-
-DRAW_FUNC_BEGIN (monostereo_draw)
- switch (monostereo_num_channels)
- {
- case -1:
- case 0:
- skin_draw_pixbuf (cr, SKIN_MONOSTEREO, 29, 12, 0, 0, 27, 12);
- skin_draw_pixbuf (cr, SKIN_MONOSTEREO, 0, 12, 27, 0, 29, 12);
- break;
- case 1:
- skin_draw_pixbuf (cr, SKIN_MONOSTEREO, 29, 0, 0, 0, 27, 12);
- skin_draw_pixbuf (cr, SKIN_MONOSTEREO, 0, 12, 27, 0, 29, 12);
- break;
- default:
- skin_draw_pixbuf (cr, SKIN_MONOSTEREO, 29, 12, 0, 0, 27, 12);
- skin_draw_pixbuf (cr, SKIN_MONOSTEREO, 0, 0, 27, 0, 29, 12);
- break;
- }
-DRAW_FUNC_END
-
-GtkWidget * ui_skinned_monostereo_new (void)
-{
- GtkWidget * monostereo = gtk_drawing_area_new ();
- gtk_widget_set_size_request (monostereo, 56, 12);
- DRAW_CONNECT (monostereo, monostereo_draw);
- return monostereo;
-}
-
-void ui_skinned_monostereo_set_num_channels (GtkWidget * monostereo, gint nch)
-{
- monostereo_num_channels = nch;
- gtk_widget_queue_draw (monostereo);
-}
diff --git a/src/skins/ui_skinned_monostereo.cc b/src/skins/ui_skinned_monostereo.cc
new file mode 100644
index 000000000000..60d5397792ac
--- /dev/null
+++ b/src/skins/ui_skinned_monostereo.cc
@@ -0,0 +1,66 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz MoÅ
+ * Copyright (c) 2011 John Lindgren
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "ui_skin.h"
+#include "ui_skinned_monostereo.h"
+
+static int monostereo_num_channels;
+
+DRAW_FUNC_BEGIN (monostereo_draw)
+ switch (monostereo_num_channels)
+ {
+ case -1:
+ case 0:
+ skin_draw_pixbuf (cr, SKIN_MONOSTEREO, 29, 12, 0, 0, 27, 12);
+ skin_draw_pixbuf (cr, SKIN_MONOSTEREO, 0, 12, 27, 0, 29, 12);
+ break;
+ case 1:
+ skin_draw_pixbuf (cr, SKIN_MONOSTEREO, 29, 0, 0, 0, 27, 12);
+ skin_draw_pixbuf (cr, SKIN_MONOSTEREO, 0, 12, 27, 0, 29, 12);
+ break;
+ default:
+ skin_draw_pixbuf (cr, SKIN_MONOSTEREO, 29, 12, 0, 0, 27, 12);
+ skin_draw_pixbuf (cr, SKIN_MONOSTEREO, 0, 0, 27, 0, 29, 12);
+ break;
+ }
+DRAW_FUNC_END
+
+GtkWidget * ui_skinned_monostereo_new (void)
+{
+ GtkWidget * monostereo = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (monostereo, 56 * config.scale, 12 * config.scale);
+ DRAW_CONNECT (monostereo, monostereo_draw);
+ return monostereo;
+}
+
+void ui_skinned_monostereo_set_num_channels (GtkWidget * monostereo, int nch)
+{
+ monostereo_num_channels = nch;
+ gtk_widget_queue_draw (monostereo);
+}
diff --git a/src/skins/ui_skinned_monostereo.h b/src/skins/ui_skinned_monostereo.h
index 5867126426db..4cb41536fc69 100644
--- a/src/skins/ui_skinned_monostereo.h
+++ b/src/skins/ui_skinned_monostereo.h
@@ -31,6 +31,6 @@
#include <gtk/gtk.h>
GtkWidget * ui_skinned_monostereo_new (void);
-void ui_skinned_monostereo_set_num_channels(GtkWidget *widget, gint nch);
+void ui_skinned_monostereo_set_num_channels(GtkWidget *widget, int nch);
#endif
diff --git a/src/skins/ui_skinned_number.c b/src/skins/ui_skinned_number.c
deleted file mode 100644
index 10157f2b4dc5..000000000000
--- a/src/skins/ui_skinned_number.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz MoÅ
- * Copyright (c) 2011 John Lindgren
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "draw-compat.h"
-#include "ui_skin.h"
-#include "ui_skinned_number.h"
-
-typedef struct {
- gint w, h;
- gint num;
-} NumberData;
-
-DRAW_FUNC_BEGIN (number_draw)
- NumberData * data = g_object_get_data ((GObject *) wid, "numberdata");
- g_return_val_if_fail (data, FALSE);
-
- skin_draw_pixbuf (cr, SKIN_NUMBERS, data->num * 9, 0, 0, 0, data->w, data->h);
-DRAW_FUNC_END
-
-static void number_destroy (GtkWidget * number)
-{
- g_free (g_object_get_data ((GObject *) number, "numberdata"));
-}
-
-GtkWidget * ui_skinned_number_new (void)
-{
- GtkWidget * number = gtk_drawing_area_new ();
- gtk_widget_set_size_request (number, 9, 13);
-
- gtk_widget_add_events (number, GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK);
-
- DRAW_CONNECT (number, number_draw);
- g_signal_connect (number, "destroy", (GCallback) number_destroy, NULL);
-
- NumberData * data = g_malloc0 (sizeof (NumberData));
- data->w = 9;
- data->h = 13;
- g_object_set_data ((GObject *) number, "numberdata", data);
-
- return number;
-}
-
-void ui_skinned_number_set (GtkWidget * number, gchar c)
-{
- NumberData * data = g_object_get_data ((GObject *) number, "numberdata");
- g_return_if_fail (data);
-
- gint value = (c >= '0' && c <= '9') ? c - '0' : (c == '-') ? 11 : 10;
-
- if (data->num == value)
- return;
-
- data->num = value;
- gtk_widget_queue_draw (number);
-}
-
-void ui_skinned_number_set_size (GtkWidget * number, gint width, gint height)
-{
- NumberData * data = g_object_get_data ((GObject *) number, "numberdata");
- g_return_if_fail (data);
-
- data->w = width;
- data->h = height;
-
- gtk_widget_set_size_request (number, width, height);
- gtk_widget_queue_draw (number);
-}
diff --git a/src/skins/ui_skinned_number.cc b/src/skins/ui_skinned_number.cc
new file mode 100644
index 000000000000..53977ccdb399
--- /dev/null
+++ b/src/skins/ui_skinned_number.cc
@@ -0,0 +1,93 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz MoÅ
+ * Copyright (c) 2011 John Lindgren
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "ui_skin.h"
+#include "ui_skinned_number.h"
+
+typedef struct {
+ int w, h;
+ int num;
+} NumberData;
+
+DRAW_FUNC_BEGIN (number_draw)
+ NumberData * data = (NumberData *) g_object_get_data ((GObject *) wid, "numberdata");
+ g_return_val_if_fail (data, FALSE);
+
+ skin_draw_pixbuf (cr, SKIN_NUMBERS, data->num * 9, 0, 0, 0, data->w, data->h);
+DRAW_FUNC_END
+
+static void number_destroy (GtkWidget * number)
+{
+ g_free (g_object_get_data ((GObject *) number, "numberdata"));
+}
+
+GtkWidget * ui_skinned_number_new (void)
+{
+ GtkWidget * number = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (number, 9 * config.scale, 13 * config.scale);
+
+ gtk_widget_add_events (number, GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK);
+
+ DRAW_CONNECT (number, number_draw);
+ g_signal_connect (number, "destroy", (GCallback) number_destroy, nullptr);
+
+ NumberData * data = g_new0 (NumberData, 1);
+ data->w = 9;
+ data->h = 13;
+ g_object_set_data ((GObject *) number, "numberdata", data);
+
+ return number;
+}
+
+void ui_skinned_number_set (GtkWidget * number, char c)
+{
+ NumberData * data = (NumberData *) g_object_get_data ((GObject *) number, "numberdata");
+ g_return_if_fail (data);
+
+ int value = (c >= '0' && c <= '9') ? c - '0' : (c == '-') ? 11 : 10;
+
+ if (data->num == value)
+ return;
+
+ data->num = value;
+ gtk_widget_queue_draw (number);
+}
+
+void ui_skinned_number_set_size (GtkWidget * number, int width, int height)
+{
+ NumberData * data = (NumberData *) g_object_get_data ((GObject *) number, "numberdata");
+ g_return_if_fail (data);
+
+ data->w = width;
+ data->h = height;
+
+ gtk_widget_set_size_request (number, width * config.scale, height * config.scale);
+ gtk_widget_queue_draw (number);
+}
diff --git a/src/skins/ui_skinned_number.h b/src/skins/ui_skinned_number.h
index 4c82630cb410..3ddde4a3e1cc 100644
--- a/src/skins/ui_skinned_number.h
+++ b/src/skins/ui_skinned_number.h
@@ -25,7 +25,7 @@
#include <gtk/gtk.h>
GtkWidget * ui_skinned_number_new ();
-void ui_skinned_number_set (GtkWidget * widget, gchar c);
-void ui_skinned_number_set_size(GtkWidget *widget, gint width, gint height);
+void ui_skinned_number_set (GtkWidget * widget, char c);
+void ui_skinned_number_set_size(GtkWidget *widget, int width, int height);
#endif
diff --git a/src/skins/ui_skinned_playlist.c b/src/skins/ui_skinned_playlist.c
deleted file mode 100644
index 99fa24b65c3f..000000000000
--- a/src/skins/ui_skinned_playlist.c
+++ /dev/null
@@ -1,948 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz MoÅ
- * Copyright (c) 2008 William Pitcock
- * Copyright (c) 2009-2011 John Lindgren
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- *
- * XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <gdk/gdkkeysyms.h>
-
-#include "draw-compat.h"
-#include "menus.h"
-#include "skins_cfg.h"
-#include "ui_playlist.h"
-#include "ui_skin.h"
-#include "ui_skinned_playlist.h"
-#include "ui_skinned_playlist_slider.h"
-
-#include <audacious/drct.h>
-#include <audacious/misc.h>
-#include <audacious/playlist.h>
-#include <libaudgui/libaudgui.h>
-
-enum {DRAG_SELECT = 1, DRAG_MOVE};
-
-typedef struct {
- GtkWidget * slider;
- PangoFontDescription * font;
- gint width, height, row_height, offset, rows, first, scroll, scroll_source,
- hover, drag;
- gint popup_pos, popup_source;
- gboolean popup_shown;
-} PlaylistData;
-
-static gboolean playlist_button_press (GtkWidget * list, GdkEventButton * event);
-static gboolean playlist_button_release (GtkWidget * list, GdkEventButton *
- event);
-static gboolean playlist_motion (GtkWidget * list, GdkEventMotion * event);
-static gboolean playlist_leave (GtkWidget * list, GdkEventCrossing * event);
-
-static void popup_trigger (GtkWidget * list, PlaylistData * data, gint pos);
-static void popup_hide (GtkWidget * list, PlaylistData * data);
-
-static void calc_layout (PlaylistData * data)
-{
- data->rows = data->height / data->row_height;
-
- if (data->rows && active_title)
- {
- data->offset = data->row_height;
- data->rows --;
- }
- else
- data->offset = 0;
-
- if (data->first + data->rows > active_length)
- data->first = active_length - data->rows;
- if (data->first < 0)
- data->first = 0;
-}
-
-static gint calc_position (PlaylistData * data, gint y)
-{
- if (y < data->offset)
- return -1;
-
- gint position = data->first + (y - data->offset) / data->row_height;
-
- if (position >= data->first + data->rows || position >= active_length)
- return active_length;
-
- return position;
-}
-
-static gint adjust_position (PlaylistData * data, gboolean relative, gint
- position)
-{
- if (active_length == 0)
- return -1;
-
- if (relative)
- {
- gint focus = aud_playlist_get_focus (active_playlist);
- if (focus == -1)
- return 0;
-
- position += focus;
- }
-
- if (position < 0)
- return 0;
- if (position >= active_length)
- return active_length - 1;
-
- return position;
-}
-
-static void cancel_all (GtkWidget * list, PlaylistData * data)
-{
- data->drag = FALSE;
-
- if (data->scroll)
- {
- data->scroll = 0;
- g_source_remove (data->scroll_source);
- }
-
- if (data->hover != -1)
- {
- data->hover = -1;
- gtk_widget_queue_draw (list);
- }
-
- popup_hide (list, data);
-}
-
-DRAW_FUNC_BEGIN (playlist_draw)
- PlaylistData * data = g_object_get_data ((GObject *) wid, "playlistdata");
- g_return_val_if_fail (data, FALSE);
-
- gint active_entry = aud_playlist_get_position (active_playlist);
- gint left = 3, right = 3;
- PangoLayout * layout;
- gint width;
-
- /* background */
-
- set_cairo_color (cr, active_skin->colors[SKIN_PLEDIT_NORMALBG]);
- cairo_paint (cr);
-
- /* playlist title */
-
- if (data->offset)
- {
- layout = gtk_widget_create_pango_layout (wid, active_title);
- pango_layout_set_font_description (layout, data->font);
- pango_layout_set_width (layout, PANGO_SCALE * (data->width - left -
- right));
- pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
- pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_MIDDLE);
-
- cairo_move_to (cr, left, 0);
- set_cairo_color (cr, active_skin->colors[SKIN_PLEDIT_NORMAL]);
- pango_cairo_show_layout (cr, layout);
- g_object_unref (layout);
- }
-
- /* selection highlight */
-
- for (gint i = data->first; i < data->first + data->rows && i <
- active_length; i ++)
- {
- if (! aud_playlist_entry_get_selected (active_playlist, i))
- continue;
-
- cairo_rectangle (cr, 0, data->offset + data->row_height * (i -
- data->first), data->width, data->row_height);
- set_cairo_color (cr, active_skin->colors[SKIN_PLEDIT_SELECTEDBG]);
- cairo_fill (cr);
- }
-
- /* entry numbers */
-
- if (aud_get_bool (NULL, "show_numbers_in_pl"))
- {
- width = 0;
-
- for (gint i = data->first; i < data->first + data->rows && i <
- active_length; i ++)
- {
- gchar buf[16];
- snprintf (buf, sizeof buf, "%d.", 1 + i);
-
- layout = gtk_widget_create_pango_layout (wid, buf);
- pango_layout_set_font_description (layout, data->font);
-
- PangoRectangle rect;
- pango_layout_get_pixel_extents (layout, NULL, & rect);
- width = MAX (width, rect.width);
-
- cairo_move_to (cr, left, data->offset + data->row_height * (i -
- data->first));
- set_cairo_color (cr, active_skin->colors[(i == active_entry) ?
- SKIN_PLEDIT_CURRENT : SKIN_PLEDIT_NORMAL]);
- pango_cairo_show_layout (cr, layout);
- g_object_unref (layout);
- }
-
- left += width + 4;
- }
-
- /* entry lengths */
-
- width = 0;
-
- for (gint i = data->first; i < data->first + data->rows && i <
- active_length; i ++)
- {
- int len = aud_playlist_entry_get_length (active_playlist, i, TRUE);
- if (len <= 0)
- continue;
-
- char buf[16];
- audgui_format_time (buf, sizeof buf, len);
-
- layout = gtk_widget_create_pango_layout (wid, buf);
- pango_layout_set_font_description (layout, data->font);
-
- PangoRectangle rect;
- pango_layout_get_pixel_extents (layout, NULL, & rect);
- width = MAX (width, rect.width);
-
- cairo_move_to (cr, data->width - right - rect.width, data->offset +
- data->row_height * (i - data->first));
- set_cairo_color (cr, active_skin->colors[(i == active_entry) ?
- SKIN_PLEDIT_CURRENT : SKIN_PLEDIT_NORMAL]);
- pango_cairo_show_layout (cr, layout);
- g_object_unref (layout);
- }
-
- right += width + 6;
-
- /* queue positions */
-
- if (aud_playlist_queue_count (active_playlist))
- {
- width = 0;
-
- for (gint i = data->first; i < data->first + data->rows && i <
- active_length; i ++)
- {
- gint pos = aud_playlist_queue_find_entry (active_playlist, i);
- if (pos < 0)
- continue;
-
- gchar buf[16];
- snprintf (buf, sizeof buf, "(#%d)", 1 + pos);
-
- layout = gtk_widget_create_pango_layout (wid, buf);
- pango_layout_set_font_description (layout, data->font);
-
- PangoRectangle rect;
- pango_layout_get_pixel_extents (layout, NULL, & rect);
- width = MAX (width, rect.width);
-
- cairo_move_to (cr, data->width - right - rect.width, data->offset +
- data->row_height * (i - data->first));
- set_cairo_color (cr, active_skin->colors[(i == active_entry) ?
- SKIN_PLEDIT_CURRENT : SKIN_PLEDIT_NORMAL]);
- pango_cairo_show_layout (cr, layout);
- g_object_unref (layout);
- }
-
- right += width + 6;
- }
-
- /* titles */
-
- for (gint i = data->first; i < data->first + data->rows && i <
- active_length; i ++)
- {
- gchar * title = aud_playlist_entry_get_title (active_playlist, i, TRUE);
-
- layout = gtk_widget_create_pango_layout (wid, title);
- pango_layout_set_font_description (layout, data->font);
- pango_layout_set_width (layout, PANGO_SCALE * (data->width - left -
- right));
- pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
-
- str_unref (title);
-
- cairo_move_to (cr, left, data->offset + data->row_height * (i -
- data->first));
- set_cairo_color (cr, active_skin->colors[(i == active_entry) ?
- SKIN_PLEDIT_CURRENT : SKIN_PLEDIT_NORMAL]);
- pango_cairo_show_layout (cr, layout);
- g_object_unref (layout);
- }
-
- /* focus rectangle */
-
- gint focus = aud_playlist_get_focus (active_playlist);
- if (focus >= data->first && focus <= data->first + data->rows - 1)
- {
- cairo_new_path (cr);
- cairo_set_line_width (cr, 1);
- cairo_rectangle (cr, 0.5, data->offset + data->row_height * (focus -
- data->first) + 0.5, data->width - 1, data->row_height - 1);
- set_cairo_color (cr, active_skin->colors[SKIN_PLEDIT_NORMAL]);
- cairo_stroke (cr);
- }
-
- /* hover line */
-
- if (data->hover >= data->first && data->hover <= data->first + data->rows)
- {
- cairo_new_path (cr);
- cairo_set_line_width (cr, 2);
- cairo_move_to (cr, 0, data->offset + data->row_height * (data->hover -
- data->first));
- cairo_rel_line_to (cr, data->width, 0);
- set_cairo_color (cr, active_skin->colors[SKIN_PLEDIT_NORMAL]);
- cairo_stroke (cr);
- }
-DRAW_FUNC_END
-
-static void playlist_destroy (GtkWidget * list)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_if_fail (data);
-
- cancel_all (list, data);
-
- pango_font_description_free (data->font);
- g_free (data);
-}
-
-GtkWidget * ui_skinned_playlist_new (gint width, gint height, const gchar * font)
-{
- GtkWidget * list = gtk_drawing_area_new ();
- gtk_widget_set_size_request (list, width, height);
- gtk_widget_add_events (list, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK);
-
- DRAW_CONNECT (list, playlist_draw);
- g_signal_connect (list, "button-press-event", (GCallback)
- playlist_button_press, NULL);
- g_signal_connect (list, "button-release-event", (GCallback)
- playlist_button_release, NULL);
- g_signal_connect (list, "leave-notify-event", (GCallback) playlist_leave,
- NULL);
- g_signal_connect (list, "motion-notify-event", (GCallback) playlist_motion,
- NULL);
- g_signal_connect (list, "destroy", (GCallback) playlist_destroy, NULL);
-
- PlaylistData * data = g_malloc0 (sizeof (PlaylistData));
- data->width = width;
- data->height = height;
- data->hover = -1;
- data->popup_pos = -1;
- g_object_set_data ((GObject *) list, "playlistdata", data);
-
- ui_skinned_playlist_set_font (list, font);
-
- return list;
-}
-
-void ui_skinned_playlist_set_slider (GtkWidget * list, GtkWidget * slider)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_if_fail (data);
-
- data->slider = slider;
-}
-
-void ui_skinned_playlist_resize (GtkWidget * list, gint width, gint height)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_if_fail (data);
-
- gtk_widget_set_size_request (list, width, height);
-
- data->width = width;
- data->height = height;
-
- calc_layout (data);
- gtk_widget_queue_draw (list);
-
- if (data->slider)
- ui_skinned_playlist_slider_update (data->slider);
-}
-
-void ui_skinned_playlist_set_font (GtkWidget * list, const gchar * font)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_if_fail (data);
-
- pango_font_description_free (data->font);
- data->font = pango_font_description_from_string (font);
-
- PangoLayout * layout = gtk_widget_create_pango_layout (list, "A");
- pango_layout_set_font_description (layout, data->font);
-
- PangoRectangle rect;
- pango_layout_get_pixel_extents (layout, NULL, & rect);
-
- /* make sure row_height is non-zero; we divide by it */
- data->row_height = MAX (rect.height, 1);
-
- g_object_unref (layout);
-
- calc_layout (data);
- gtk_widget_queue_draw (list);
-
- if (data->slider)
- ui_skinned_playlist_slider_update (data->slider);
-}
-
-void ui_skinned_playlist_update (GtkWidget * list)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_if_fail (data);
-
- calc_layout (data);
-
- gtk_widget_queue_draw (list);
-
- if (data->slider != NULL)
- ui_skinned_playlist_slider_update (data->slider);
-}
-
-static void scroll_to (PlaylistData * data, gint position)
-{
- if (position < data->first || position >= data->first + data->rows)
- data->first = position - data->rows / 2;
-
- calc_layout (data);
-}
-
-static void select_single (PlaylistData * data, gboolean relative, gint position)
-{
- position = adjust_position (data, relative, position);
-
- if (position == -1)
- return;
-
- aud_playlist_select_all (active_playlist, FALSE);
- aud_playlist_entry_set_selected (active_playlist, position, TRUE);
- aud_playlist_set_focus (active_playlist, position);
- scroll_to (data, position);
-}
-
-static void select_extend (PlaylistData * data, gboolean relative, gint position)
-{
- position = adjust_position (data, relative, position);
-
- if (position == -1)
- return;
-
- gint count = adjust_position (data, TRUE, 0);
- gint sign = (position > count) ? 1 : -1;
-
- for (; count != position; count += sign)
- aud_playlist_entry_set_selected (active_playlist, count,
- ! aud_playlist_entry_get_selected (active_playlist, count + sign));
-
- aud_playlist_entry_set_selected (active_playlist, position, TRUE);
- aud_playlist_set_focus (active_playlist, position);
- scroll_to (data, position);
-}
-
-static void select_slide (PlaylistData * data, gboolean relative, gint position)
-{
- position = adjust_position (data, relative, position);
-
- if (position == -1)
- return;
-
- aud_playlist_set_focus (active_playlist, position);
- scroll_to (data, position);
-}
-
-static void select_toggle (PlaylistData * data, gboolean relative, gint position)
-{
- position = adjust_position (data, relative, position);
-
- if (position == -1)
- return;
-
- aud_playlist_entry_set_selected (active_playlist, position,
- ! aud_playlist_entry_get_selected (active_playlist, position));
- aud_playlist_set_focus (active_playlist, position);
- scroll_to (data, position);
-}
-
-static void select_move (PlaylistData * data, gboolean relative, gint position)
-{
- gint focus = aud_playlist_get_focus (active_playlist);
- position = adjust_position (data, relative, position);
-
- if (focus == -1 || position == -1 || position == focus)
- return;
-
- focus += aud_playlist_shift (active_playlist, focus, position - focus);
- scroll_to (data, focus);
-}
-
-static void delete_selected (PlaylistData * data)
-{
- aud_playlist_delete_selected (active_playlist);
-
- active_length = aud_playlist_entry_count (active_playlist);
- gint focus = aud_playlist_get_focus (active_playlist);
-
- if (focus != -1)
- {
- aud_playlist_entry_set_selected (active_playlist, focus, TRUE);
- scroll_to (data, focus);
- }
-}
-
-gboolean ui_skinned_playlist_key (GtkWidget * list, GdkEventKey * event)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_val_if_fail (data, FALSE);
-
- cancel_all (list, data);
-
- switch (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK))
- {
- case 0:
- switch (event->keyval)
- {
- case GDK_KEY_Up:
- select_single (data, TRUE, -1);
- break;
- case GDK_KEY_Down:
- select_single (data, TRUE, 1);
- break;
- case GDK_KEY_Page_Up:
- select_single (data, TRUE, - data->rows);
- break;
- case GDK_KEY_Page_Down:
- select_single (data, TRUE, data->rows);
- break;
- case GDK_KEY_Home:
- select_single (data, FALSE, 0);
- break;
- case GDK_KEY_End:
- select_single (data, FALSE, active_length - 1);
- break;
- case GDK_KEY_Return:
- select_single (data, TRUE, 0);
- aud_playlist_set_position (active_playlist,
- aud_playlist_get_focus (active_playlist));
- aud_drct_play_playlist (active_playlist);
- break;
- case GDK_KEY_Escape:
- select_single (data, FALSE, aud_playlist_get_position
- (active_playlist));
- break;
- case GDK_KEY_Delete:
- delete_selected (data);
- break;
- default:
- return FALSE;
- }
- break;
- case GDK_SHIFT_MASK:
- switch (event->keyval)
- {
- case GDK_KEY_Up:
- select_extend (data, TRUE, -1);
- break;
- case GDK_KEY_Down:
- select_extend (data, TRUE, 1);
- break;
- case GDK_KEY_Page_Up:
- select_extend (data, TRUE, -data->rows);
- break;
- case GDK_KEY_Page_Down:
- select_extend (data, TRUE, data->rows);
- break;
- case GDK_KEY_Home:
- select_extend (data, FALSE, 0);
- break;
- case GDK_KEY_End:
- select_extend (data, FALSE, active_length - 1);
- break;
- default:
- return FALSE;
- }
- break;
- case GDK_CONTROL_MASK:
- switch (event->keyval)
- {
- case GDK_KEY_space:
- select_toggle (data, TRUE, 0);
- break;
- case GDK_KEY_Up:
- select_slide (data, TRUE, -1);
- break;
- case GDK_KEY_Down:
- select_slide (data, TRUE, 1);
- break;
- case GDK_KEY_Page_Up:
- select_slide (data, TRUE, -data->rows);
- break;
- case GDK_KEY_Page_Down:
- select_slide (data, TRUE, data->rows);
- break;
- case GDK_KEY_Home:
- select_slide (data, FALSE, 0);
- break;
- case GDK_KEY_End:
- select_slide (data, FALSE, active_length - 1);
- break;
- default:
- return FALSE;
- }
- break;
- case GDK_MOD1_MASK:
- switch (event->keyval)
- {
- case GDK_KEY_Up:
- select_move (data, TRUE, -1);
- break;
- case GDK_KEY_Down:
- select_move (data, TRUE, 1);
- break;
- case GDK_KEY_Page_Up:
- select_move (data, TRUE, -data->rows);
- break;
- case GDK_KEY_Page_Down:
- select_move (data, TRUE, data->rows);
- break;
- case GDK_KEY_Home:
- select_move (data, FALSE, 0);
- break;
- case GDK_KEY_End:
- select_move (data, FALSE, active_length - 1);
- break;
- default:
- return FALSE;
- }
- break;
- default:
- return FALSE;
- }
-
- playlistwin_update ();
- return TRUE;
-}
-
-void ui_skinned_playlist_row_info (GtkWidget * list, gint * rows, gint * first)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_if_fail (data);
-
- * rows = data->rows;
- * first = data->first;
-}
-
-void ui_skinned_playlist_scroll_to (GtkWidget * list, gint row)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_if_fail (data);
-
- cancel_all (list, data);
- data->first = row;
- calc_layout (data);
-
- gtk_widget_queue_draw (list);
-
- if (data->slider)
- ui_skinned_playlist_slider_update (data->slider);
-}
-
-void ui_skinned_playlist_set_focused (GtkWidget * list, gint row)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_if_fail (data);
-
- cancel_all (list, data);
- aud_playlist_set_focus (active_playlist, row);
- scroll_to (data, row);
-
- gtk_widget_queue_draw (list);
-}
-
-void ui_skinned_playlist_hover (GtkWidget * list, gint x, gint y)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_if_fail (data);
-
- gint new;
-
- if (y < data->offset)
- new = data->first;
- else if (y > data->offset + data->row_height * data->rows)
- new = data->first + data->rows;
- else
- new = data->first + (y - data->offset + data->row_height / 2) /
- data->row_height;
-
- if (new > active_length)
- new = active_length;
-
- if (new != data->hover)
- {
- data->hover = new;
- gtk_widget_queue_draw (list);
- }
-}
-
-gint ui_skinned_playlist_hover_end (GtkWidget * list)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_val_if_fail (data, -1);
-
- gint temp = data->hover;
- data->hover = -1;
-
- gtk_widget_queue_draw (list);
- return temp;
-}
-
-static gboolean playlist_button_press (GtkWidget * list, GdkEventButton * event)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_val_if_fail (data, FALSE);
-
- gint position = calc_position (data, event->y);
- gint state = event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK |
- GDK_MOD1_MASK);
-
- cancel_all (list, data);
-
- switch (event->type)
- {
- case GDK_BUTTON_PRESS:
- switch (event->button)
- {
- case 1:
- if (position == -1 || position == active_length)
- return TRUE;
-
- switch (state)
- {
- case 0:
- if (aud_playlist_entry_get_selected (active_playlist, position))
- select_slide (data, FALSE, position);
- else
- select_single (data, FALSE, position);
-
- data->drag = DRAG_MOVE;
- break;
- case GDK_SHIFT_MASK:
- select_extend (data, FALSE, position);
- data->drag = DRAG_SELECT;
- break;
- case GDK_CONTROL_MASK:
- select_toggle (data, FALSE, position);
- data->drag = DRAG_SELECT;
- break;
- default:
- return TRUE;
- }
-
- break;
- case 3:
- if (state)
- return TRUE;
-
- if (position != -1 && position != active_length)
- {
- if (aud_playlist_entry_get_selected (active_playlist, position))
- select_slide (data, FALSE, position);
- else
- select_single (data, FALSE, position);
- }
-
- menu_popup ((position == -1) ? UI_MENU_PLAYLIST :
- UI_MENU_PLAYLIST_CONTEXT, event->x_root, event->y_root, FALSE,
- FALSE, 3, event->time);
- break;
- default:
- return FALSE;
- }
-
- break;
- case GDK_2BUTTON_PRESS:
- if (event->button != 1 || state || position == active_length)
- return TRUE;
-
- if (position != -1)
- aud_playlist_set_position (active_playlist, position);
-
- aud_drct_play_playlist (active_playlist);
- break;
- default:
- return TRUE;
- }
-
- playlistwin_update ();
- return TRUE;
-}
-
-static gboolean playlist_button_release (GtkWidget * list, GdkEventButton *
- event)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_val_if_fail (data, FALSE);
-
- cancel_all (list, data);
- return TRUE;
-}
-
-static gboolean scroll_cb (PlaylistData * data)
-{
- gint position = adjust_position (data, TRUE, data->scroll);
-
- if (position == -1)
- return TRUE;
-
- switch (data->drag)
- {
- case DRAG_SELECT:
- select_extend (data, FALSE, position);
- break;
- case DRAG_MOVE:
- select_move (data, FALSE, position);
- break;
- }
-
- playlistwin_update ();
- return TRUE;
-}
-
-static gboolean playlist_motion (GtkWidget * list, GdkEventMotion * event)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_val_if_fail (data, FALSE);
-
- gint position = calc_position (data, event->y);
- gint new_scroll;
-
- if (data->drag)
- {
- if (position == -1 || position == active_length)
- {
- new_scroll = (position == -1 ? -1 : 1);
-
- if (data->scroll != new_scroll)
- {
- if (data->scroll)
- g_source_remove (data->scroll_source);
-
- data->scroll = new_scroll;
- data->scroll_source = g_timeout_add (100, (GSourceFunc)
- scroll_cb, data);
- }
- }
- else
- {
- if (data->scroll)
- {
- data->scroll = 0;
- g_source_remove (data->scroll_source);
- }
-
- switch (data->drag)
- {
- case DRAG_SELECT:
- select_extend (data, FALSE, position);
- break;
- case DRAG_MOVE:
- select_move (data, FALSE, position);
- break;
- }
-
- playlistwin_update ();
- }
- }
- else
- {
- if (position == -1 || position == active_length)
- cancel_all (list, data);
- else if (aud_get_bool (NULL, "show_filepopup_for_tuple") && data->popup_pos != position)
- {
- cancel_all (list, data);
- popup_trigger (list, data, position);
- }
- }
-
- return TRUE;
-}
-
-static gboolean playlist_leave (GtkWidget * list, GdkEventCrossing * event)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_val_if_fail (data, FALSE);
-
- if (! data->drag)
- cancel_all (list, data);
-
- return TRUE;
-}
-
-static gboolean popup_show (GtkWidget * list)
-{
- PlaylistData * data = g_object_get_data ((GObject *) list, "playlistdata");
- g_return_val_if_fail (data, FALSE);
-
- audgui_infopopup_show (active_playlist, data->popup_pos);
- data->popup_shown = TRUE;
-
- g_source_remove (data->popup_source);
- data->popup_source = 0;
- return FALSE;
-}
-
-static void popup_trigger (GtkWidget * list, PlaylistData * data, gint pos)
-{
- popup_hide (list, data);
-
- data->popup_pos = pos;
- data->popup_source = g_timeout_add (aud_get_int (NULL, "filepopup_delay") *
- 100, (GSourceFunc) popup_show, list);
-}
-
-static void popup_hide (GtkWidget * list, PlaylistData * data)
-{
- if (data->popup_source)
- {
- g_source_remove (data->popup_source);
- data->popup_source = 0;
- }
-
- if (data->popup_shown)
- {
- audgui_infopopup_hide ();
- data->popup_shown = FALSE;
- }
-
- data->popup_pos = -1;
-}
diff --git a/src/skins/ui_skinned_playlist.cc b/src/skins/ui_skinned_playlist.cc
new file mode 100644
index 000000000000..3408356d3109
--- /dev/null
+++ b/src/skins/ui_skinned_playlist.cc
@@ -0,0 +1,945 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz MoÅ
+ * Copyright (c) 2008 William Pitcock
+ * Copyright (c) 2009-2011 John Lindgren
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ *
+ * XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <gdk/gdkkeysyms.h>
+
+#include "draw-compat.h"
+#include "menus.h"
+#include "skins_cfg.h"
+#include "ui_playlist.h"
+#include "ui_skin.h"
+#include "ui_skinned_playlist.h"
+#include "ui_skinned_playlist_slider.h"
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/playlist.h>
+#include <libaudgui/libaudgui.h>
+
+enum {DRAG_SELECT = 1, DRAG_MOVE};
+
+typedef struct {
+ GtkWidget * slider;
+ PangoFontDescription * font;
+ int width, height, row_height, offset, rows, first, scroll, scroll_source,
+ hover, drag;
+ int popup_pos, popup_source;
+ gboolean popup_shown;
+} PlaylistData;
+
+static gboolean playlist_button_press (GtkWidget * list, GdkEventButton * event);
+static gboolean playlist_button_release (GtkWidget * list, GdkEventButton *
+ event);
+static gboolean playlist_motion (GtkWidget * list, GdkEventMotion * event);
+static gboolean playlist_leave (GtkWidget * list, GdkEventCrossing * event);
+
+static void popup_trigger (GtkWidget * list, PlaylistData * data, int pos);
+static void popup_hide (GtkWidget * list, PlaylistData * data);
+
+static void calc_layout (PlaylistData * data)
+{
+ data->rows = data->height / data->row_height;
+
+ if (data->rows && active_title)
+ {
+ data->offset = data->row_height;
+ data->rows --;
+ }
+ else
+ data->offset = 0;
+
+ if (data->first + data->rows > active_length)
+ data->first = active_length - data->rows;
+ if (data->first < 0)
+ data->first = 0;
+}
+
+static int calc_position (PlaylistData * data, int y)
+{
+ if (y < data->offset)
+ return -1;
+
+ int position = data->first + (y - data->offset) / data->row_height;
+
+ if (position >= data->first + data->rows || position >= active_length)
+ return active_length;
+
+ return position;
+}
+
+static int adjust_position (PlaylistData * data, gboolean relative, int
+ position)
+{
+ if (active_length == 0)
+ return -1;
+
+ if (relative)
+ {
+ int focus = aud_playlist_get_focus (active_playlist);
+ if (focus == -1)
+ return 0;
+
+ position += focus;
+ }
+
+ if (position < 0)
+ return 0;
+ if (position >= active_length)
+ return active_length - 1;
+
+ return position;
+}
+
+static void cancel_all (GtkWidget * list, PlaylistData * data)
+{
+ data->drag = FALSE;
+
+ if (data->scroll)
+ {
+ data->scroll = 0;
+ g_source_remove (data->scroll_source);
+ }
+
+ if (data->hover != -1)
+ {
+ data->hover = -1;
+ gtk_widget_queue_draw (list);
+ }
+
+ popup_hide (list, data);
+}
+
+DRAW_FUNC_BEGIN (playlist_draw)
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) wid, "playlistdata");
+ g_return_val_if_fail (data, FALSE);
+
+ int active_entry = aud_playlist_get_position (active_playlist);
+ int left = 3, right = 3;
+ PangoLayout * layout;
+ int width;
+
+ /* background */
+
+ set_cairo_color (cr, active_skin->colors[SKIN_PLEDIT_NORMALBG]);
+ cairo_paint (cr);
+
+ /* playlist title */
+
+ if (data->offset)
+ {
+ layout = gtk_widget_create_pango_layout (wid, active_title);
+ pango_layout_set_font_description (layout, data->font);
+ pango_layout_set_width (layout, PANGO_SCALE * (data->width - left -
+ right));
+ pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
+ pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_MIDDLE);
+
+ cairo_move_to (cr, left, 0);
+ set_cairo_color (cr, active_skin->colors[SKIN_PLEDIT_NORMAL]);
+ pango_cairo_show_layout (cr, layout);
+ g_object_unref (layout);
+ }
+
+ /* selection highlight */
+
+ for (int i = data->first; i < data->first + data->rows && i <
+ active_length; i ++)
+ {
+ if (! aud_playlist_entry_get_selected (active_playlist, i))
+ continue;
+
+ cairo_rectangle (cr, 0, data->offset + data->row_height * (i -
+ data->first), data->width, data->row_height);
+ set_cairo_color (cr, active_skin->colors[SKIN_PLEDIT_SELECTEDBG]);
+ cairo_fill (cr);
+ }
+
+ /* entry numbers */
+
+ if (aud_get_bool (nullptr, "show_numbers_in_pl"))
+ {
+ width = 0;
+
+ for (int i = data->first; i < data->first + data->rows && i <
+ active_length; i ++)
+ {
+ char buf[16];
+ snprintf (buf, sizeof buf, "%d.", 1 + i);
+
+ layout = gtk_widget_create_pango_layout (wid, buf);
+ pango_layout_set_font_description (layout, data->font);
+
+ PangoRectangle rect;
+ pango_layout_get_pixel_extents (layout, nullptr, & rect);
+ width = aud::max (width, rect.width);
+
+ cairo_move_to (cr, left, data->offset + data->row_height * (i -
+ data->first));
+ set_cairo_color (cr, active_skin->colors[(i == active_entry) ?
+ SKIN_PLEDIT_CURRENT : SKIN_PLEDIT_NORMAL]);
+ pango_cairo_show_layout (cr, layout);
+ g_object_unref (layout);
+ }
+
+ left += width + 4;
+ }
+
+ /* entry lengths */
+
+ width = 0;
+
+ for (int i = data->first; i < data->first + data->rows && i <
+ active_length; i ++)
+ {
+ Tuple tuple = aud_playlist_entry_get_tuple (active_playlist, i, Playlist::Guess);
+ int len = tuple.get_int (Tuple::Length);
+ if (len < 0)
+ continue;
+
+ layout = gtk_widget_create_pango_layout (wid, str_format_time (len));
+ pango_layout_set_font_description (layout, data->font);
+
+ PangoRectangle rect;
+ pango_layout_get_pixel_extents (layout, nullptr, & rect);
+ width = aud::max (width, rect.width);
+
+ cairo_move_to (cr, data->width - right - rect.width, data->offset +
+ data->row_height * (i - data->first));
+ set_cairo_color (cr, active_skin->colors[(i == active_entry) ?
+ SKIN_PLEDIT_CURRENT : SKIN_PLEDIT_NORMAL]);
+ pango_cairo_show_layout (cr, layout);
+ g_object_unref (layout);
+ }
+
+ right += width + 6;
+
+ /* queue positions */
+
+ if (aud_playlist_queue_count (active_playlist))
+ {
+ width = 0;
+
+ for (int i = data->first; i < data->first + data->rows && i <
+ active_length; i ++)
+ {
+ int pos = aud_playlist_queue_find_entry (active_playlist, i);
+ if (pos < 0)
+ continue;
+
+ char buf[16];
+ snprintf (buf, sizeof buf, "(#%d)", 1 + pos);
+
+ layout = gtk_widget_create_pango_layout (wid, buf);
+ pango_layout_set_font_description (layout, data->font);
+
+ PangoRectangle rect;
+ pango_layout_get_pixel_extents (layout, nullptr, & rect);
+ width = aud::max (width, rect.width);
+
+ cairo_move_to (cr, data->width - right - rect.width, data->offset +
+ data->row_height * (i - data->first));
+ set_cairo_color (cr, active_skin->colors[(i == active_entry) ?
+ SKIN_PLEDIT_CURRENT : SKIN_PLEDIT_NORMAL]);
+ pango_cairo_show_layout (cr, layout);
+ g_object_unref (layout);
+ }
+
+ right += width + 6;
+ }
+
+ /* titles */
+
+ for (int i = data->first; i < data->first + data->rows && i <
+ active_length; i ++)
+ {
+ Tuple tuple = aud_playlist_entry_get_tuple (active_playlist, i, Playlist::Guess);
+ String title = tuple.get_str (Tuple::FormattedTitle);
+
+ layout = gtk_widget_create_pango_layout (wid, title);
+ pango_layout_set_font_description (layout, data->font);
+ pango_layout_set_width (layout, PANGO_SCALE * (data->width - left -
+ right));
+ pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
+
+ cairo_move_to (cr, left, data->offset + data->row_height * (i -
+ data->first));
+ set_cairo_color (cr, active_skin->colors[(i == active_entry) ?
+ SKIN_PLEDIT_CURRENT : SKIN_PLEDIT_NORMAL]);
+ pango_cairo_show_layout (cr, layout);
+ g_object_unref (layout);
+ }
+
+ /* focus rectangle */
+
+ int focus = aud_playlist_get_focus (active_playlist);
+ if (focus >= data->first && focus <= data->first + data->rows - 1)
+ {
+ cairo_new_path (cr);
+ cairo_set_line_width (cr, 1);
+ cairo_rectangle (cr, 0.5, data->offset + data->row_height * (focus -
+ data->first) + 0.5, data->width - 1, data->row_height - 1);
+ set_cairo_color (cr, active_skin->colors[SKIN_PLEDIT_NORMAL]);
+ cairo_stroke (cr);
+ }
+
+ /* hover line */
+
+ if (data->hover >= data->first && data->hover <= data->first + data->rows)
+ {
+ cairo_new_path (cr);
+ cairo_set_line_width (cr, 2);
+ cairo_move_to (cr, 0, data->offset + data->row_height * (data->hover -
+ data->first));
+ cairo_rel_line_to (cr, data->width, 0);
+ set_cairo_color (cr, active_skin->colors[SKIN_PLEDIT_NORMAL]);
+ cairo_stroke (cr);
+ }
+DRAW_FUNC_END
+
+static void playlist_destroy (GtkWidget * list)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_if_fail (data);
+
+ cancel_all (list, data);
+
+ pango_font_description_free (data->font);
+ g_free (data);
+}
+
+GtkWidget * ui_skinned_playlist_new (int width, int height, const char * font)
+{
+ GtkWidget * list = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (list, width * config.scale, height * config.scale);
+ gtk_widget_add_events (list, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK);
+
+ DRAW_CONNECT (list, playlist_draw);
+ g_signal_connect (list, "button-press-event", (GCallback)
+ playlist_button_press, nullptr);
+ g_signal_connect (list, "button-release-event", (GCallback)
+ playlist_button_release, nullptr);
+ g_signal_connect (list, "leave-notify-event", (GCallback) playlist_leave,
+ nullptr);
+ g_signal_connect (list, "motion-notify-event", (GCallback) playlist_motion,
+ nullptr);
+ g_signal_connect (list, "destroy", (GCallback) playlist_destroy, nullptr);
+
+ PlaylistData * data = g_new0 (PlaylistData, 1);
+ data->width = width * config.scale;
+ data->height = height * config.scale;
+ data->hover = -1;
+ data->popup_pos = -1;
+ g_object_set_data ((GObject *) list, "playlistdata", data);
+
+ ui_skinned_playlist_set_font (list, font);
+
+ return list;
+}
+
+void ui_skinned_playlist_set_slider (GtkWidget * list, GtkWidget * slider)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_if_fail (data);
+
+ data->slider = slider;
+}
+
+void ui_skinned_playlist_resize (GtkWidget * list, int width, int height)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_if_fail (data);
+
+ gtk_widget_set_size_request (list, width * config.scale, height * config.scale);
+
+ data->width = width * config.scale;
+ data->height = height * config.scale;
+
+ calc_layout (data);
+ gtk_widget_queue_draw (list);
+
+ if (data->slider)
+ ui_skinned_playlist_slider_update (data->slider);
+}
+
+void ui_skinned_playlist_set_font (GtkWidget * list, const char * font)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_if_fail (data);
+
+ pango_font_description_free (data->font);
+ data->font = pango_font_description_from_string (font);
+
+ PangoLayout * layout = gtk_widget_create_pango_layout (list, "A");
+ pango_layout_set_font_description (layout, data->font);
+
+ PangoRectangle rect;
+ pango_layout_get_pixel_extents (layout, nullptr, & rect);
+
+ /* make sure row_height is non-zero; we divide by it */
+ data->row_height = aud::max (rect.height, 1);
+
+ g_object_unref (layout);
+
+ calc_layout (data);
+ gtk_widget_queue_draw (list);
+
+ if (data->slider)
+ ui_skinned_playlist_slider_update (data->slider);
+}
+
+void ui_skinned_playlist_update (GtkWidget * list)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_if_fail (data);
+
+ calc_layout (data);
+
+ gtk_widget_queue_draw (list);
+
+ if (data->slider != nullptr)
+ ui_skinned_playlist_slider_update (data->slider);
+}
+
+static void scroll_to (PlaylistData * data, int position)
+{
+ if (position < data->first || position >= data->first + data->rows)
+ data->first = position - data->rows / 2;
+
+ calc_layout (data);
+}
+
+static void select_single (PlaylistData * data, gboolean relative, int position)
+{
+ position = adjust_position (data, relative, position);
+
+ if (position == -1)
+ return;
+
+ aud_playlist_select_all (active_playlist, FALSE);
+ aud_playlist_entry_set_selected (active_playlist, position, TRUE);
+ aud_playlist_set_focus (active_playlist, position);
+ scroll_to (data, position);
+}
+
+static void select_extend (PlaylistData * data, gboolean relative, int position)
+{
+ position = adjust_position (data, relative, position);
+
+ if (position == -1)
+ return;
+
+ int count = adjust_position (data, TRUE, 0);
+ int sign = (position > count) ? 1 : -1;
+
+ for (; count != position; count += sign)
+ aud_playlist_entry_set_selected (active_playlist, count,
+ ! aud_playlist_entry_get_selected (active_playlist, count + sign));
+
+ aud_playlist_entry_set_selected (active_playlist, position, TRUE);
+ aud_playlist_set_focus (active_playlist, position);
+ scroll_to (data, position);
+}
+
+static void select_slide (PlaylistData * data, gboolean relative, int position)
+{
+ position = adjust_position (data, relative, position);
+
+ if (position == -1)
+ return;
+
+ aud_playlist_set_focus (active_playlist, position);
+ scroll_to (data, position);
+}
+
+static void select_toggle (PlaylistData * data, gboolean relative, int position)
+{
+ position = adjust_position (data, relative, position);
+
+ if (position == -1)
+ return;
+
+ aud_playlist_entry_set_selected (active_playlist, position,
+ ! aud_playlist_entry_get_selected (active_playlist, position));
+ aud_playlist_set_focus (active_playlist, position);
+ scroll_to (data, position);
+}
+
+static void select_move (PlaylistData * data, gboolean relative, int position)
+{
+ int focus = aud_playlist_get_focus (active_playlist);
+ position = adjust_position (data, relative, position);
+
+ if (focus == -1 || position == -1 || position == focus)
+ return;
+
+ focus += aud_playlist_shift (active_playlist, focus, position - focus);
+ scroll_to (data, focus);
+}
+
+static void delete_selected (PlaylistData * data)
+{
+ aud_playlist_delete_selected (active_playlist);
+
+ active_length = aud_playlist_entry_count (active_playlist);
+ int focus = aud_playlist_get_focus (active_playlist);
+
+ if (focus != -1)
+ {
+ aud_playlist_entry_set_selected (active_playlist, focus, TRUE);
+ scroll_to (data, focus);
+ }
+}
+
+gboolean ui_skinned_playlist_key (GtkWidget * list, GdkEventKey * event)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_val_if_fail (data, FALSE);
+
+ cancel_all (list, data);
+
+ switch (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK))
+ {
+ case 0:
+ switch (event->keyval)
+ {
+ case GDK_KEY_Up:
+ select_single (data, TRUE, -1);
+ break;
+ case GDK_KEY_Down:
+ select_single (data, TRUE, 1);
+ break;
+ case GDK_KEY_Page_Up:
+ select_single (data, TRUE, - data->rows);
+ break;
+ case GDK_KEY_Page_Down:
+ select_single (data, TRUE, data->rows);
+ break;
+ case GDK_KEY_Home:
+ select_single (data, FALSE, 0);
+ break;
+ case GDK_KEY_End:
+ select_single (data, FALSE, active_length - 1);
+ break;
+ case GDK_KEY_Return:
+ select_single (data, TRUE, 0);
+ aud_playlist_set_position (active_playlist,
+ aud_playlist_get_focus (active_playlist));
+ aud_playlist_play (active_playlist);
+ break;
+ case GDK_KEY_Escape:
+ select_single (data, FALSE, aud_playlist_get_position
+ (active_playlist));
+ break;
+ case GDK_KEY_Delete:
+ delete_selected (data);
+ break;
+ default:
+ return FALSE;
+ }
+ break;
+ case GDK_SHIFT_MASK:
+ switch (event->keyval)
+ {
+ case GDK_KEY_Up:
+ select_extend (data, TRUE, -1);
+ break;
+ case GDK_KEY_Down:
+ select_extend (data, TRUE, 1);
+ break;
+ case GDK_KEY_Page_Up:
+ select_extend (data, TRUE, -data->rows);
+ break;
+ case GDK_KEY_Page_Down:
+ select_extend (data, TRUE, data->rows);
+ break;
+ case GDK_KEY_Home:
+ select_extend (data, FALSE, 0);
+ break;
+ case GDK_KEY_End:
+ select_extend (data, FALSE, active_length - 1);
+ break;
+ default:
+ return FALSE;
+ }
+ break;
+ case GDK_CONTROL_MASK:
+ switch (event->keyval)
+ {
+ case GDK_KEY_space:
+ select_toggle (data, TRUE, 0);
+ break;
+ case GDK_KEY_Up:
+ select_slide (data, TRUE, -1);
+ break;
+ case GDK_KEY_Down:
+ select_slide (data, TRUE, 1);
+ break;
+ case GDK_KEY_Page_Up:
+ select_slide (data, TRUE, -data->rows);
+ break;
+ case GDK_KEY_Page_Down:
+ select_slide (data, TRUE, data->rows);
+ break;
+ case GDK_KEY_Home:
+ select_slide (data, FALSE, 0);
+ break;
+ case GDK_KEY_End:
+ select_slide (data, FALSE, active_length - 1);
+ break;
+ default:
+ return FALSE;
+ }
+ break;
+ case GDK_MOD1_MASK:
+ switch (event->keyval)
+ {
+ case GDK_KEY_Up:
+ select_move (data, TRUE, -1);
+ break;
+ case GDK_KEY_Down:
+ select_move (data, TRUE, 1);
+ break;
+ case GDK_KEY_Page_Up:
+ select_move (data, TRUE, -data->rows);
+ break;
+ case GDK_KEY_Page_Down:
+ select_move (data, TRUE, data->rows);
+ break;
+ case GDK_KEY_Home:
+ select_move (data, FALSE, 0);
+ break;
+ case GDK_KEY_End:
+ select_move (data, FALSE, active_length - 1);
+ break;
+ default:
+ return FALSE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+
+ playlistwin_update ();
+ return TRUE;
+}
+
+void ui_skinned_playlist_row_info (GtkWidget * list, int * rows, int * first)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_if_fail (data);
+
+ * rows = data->rows;
+ * first = data->first;
+}
+
+void ui_skinned_playlist_scroll_to (GtkWidget * list, int row)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_if_fail (data);
+
+ cancel_all (list, data);
+ data->first = row;
+ calc_layout (data);
+
+ gtk_widget_queue_draw (list);
+
+ if (data->slider)
+ ui_skinned_playlist_slider_update (data->slider);
+}
+
+void ui_skinned_playlist_set_focused (GtkWidget * list, int row)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_if_fail (data);
+
+ cancel_all (list, data);
+ aud_playlist_set_focus (active_playlist, row);
+ scroll_to (data, row);
+
+ gtk_widget_queue_draw (list);
+}
+
+void ui_skinned_playlist_hover (GtkWidget * list, int x, int y)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_if_fail (data);
+
+ int row;
+
+ if (y < data->offset)
+ row = data->first;
+ else if (y > data->offset + data->row_height * data->rows)
+ row = data->first + data->rows;
+ else
+ row = data->first + (y - data->offset + data->row_height / 2) /
+ data->row_height;
+
+ if (row > active_length)
+ row = active_length;
+
+ if (row != data->hover)
+ {
+ data->hover = row;
+ gtk_widget_queue_draw (list);
+ }
+}
+
+int ui_skinned_playlist_hover_end (GtkWidget * list)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_val_if_fail (data, -1);
+
+ int temp = data->hover;
+ data->hover = -1;
+
+ gtk_widget_queue_draw (list);
+ return temp;
+}
+
+static gboolean playlist_button_press (GtkWidget * list, GdkEventButton * event)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_val_if_fail (data, FALSE);
+
+ int position = calc_position (data, event->y);
+ int state = event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK |
+ GDK_MOD1_MASK);
+
+ cancel_all (list, data);
+
+ switch (event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ switch (event->button)
+ {
+ case 1:
+ if (position == -1 || position == active_length)
+ return TRUE;
+
+ switch (state)
+ {
+ case 0:
+ if (aud_playlist_entry_get_selected (active_playlist, position))
+ select_slide (data, FALSE, position);
+ else
+ select_single (data, FALSE, position);
+
+ data->drag = DRAG_MOVE;
+ break;
+ case GDK_SHIFT_MASK:
+ select_extend (data, FALSE, position);
+ data->drag = DRAG_SELECT;
+ break;
+ case GDK_CONTROL_MASK:
+ select_toggle (data, FALSE, position);
+ data->drag = DRAG_SELECT;
+ break;
+ default:
+ return TRUE;
+ }
+
+ break;
+ case 3:
+ if (state)
+ return TRUE;
+
+ if (position != -1 && position != active_length)
+ {
+ if (aud_playlist_entry_get_selected (active_playlist, position))
+ select_slide (data, FALSE, position);
+ else
+ select_single (data, FALSE, position);
+ }
+
+ menu_popup ((position == -1) ? UI_MENU_PLAYLIST :
+ UI_MENU_PLAYLIST_CONTEXT, event->x_root, event->y_root, FALSE,
+ FALSE, 3, event->time);
+ break;
+ default:
+ return FALSE;
+ }
+
+ break;
+ case GDK_2BUTTON_PRESS:
+ if (event->button != 1 || state || position == active_length)
+ return TRUE;
+
+ if (position != -1)
+ aud_playlist_set_position (active_playlist, position);
+
+ aud_playlist_play (active_playlist);
+ break;
+ default:
+ return TRUE;
+ }
+
+ playlistwin_update ();
+ return TRUE;
+}
+
+static gboolean playlist_button_release (GtkWidget * list, GdkEventButton *
+ event)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_val_if_fail (data, FALSE);
+
+ cancel_all (list, data);
+ return TRUE;
+}
+
+static gboolean scroll_cb (void * data_)
+{
+ auto data = (PlaylistData *) data_;
+ int position = adjust_position (data, TRUE, data->scroll);
+
+ if (position == -1)
+ return G_SOURCE_CONTINUE;
+
+ switch (data->drag)
+ {
+ case DRAG_SELECT:
+ select_extend (data, FALSE, position);
+ break;
+ case DRAG_MOVE:
+ select_move (data, FALSE, position);
+ break;
+ }
+
+ playlistwin_update ();
+ return G_SOURCE_CONTINUE;
+}
+
+static gboolean playlist_motion (GtkWidget * list, GdkEventMotion * event)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_val_if_fail (data, FALSE);
+
+ int position = calc_position (data, event->y);
+ int new_scroll;
+
+ if (data->drag)
+ {
+ if (position == -1 || position == active_length)
+ {
+ new_scroll = (position == -1 ? -1 : 1);
+
+ if (data->scroll != new_scroll)
+ {
+ if (data->scroll)
+ g_source_remove (data->scroll_source);
+
+ data->scroll = new_scroll;
+ data->scroll_source = g_timeout_add (100, scroll_cb, data);
+ }
+ }
+ else
+ {
+ if (data->scroll)
+ {
+ data->scroll = 0;
+ g_source_remove (data->scroll_source);
+ }
+
+ switch (data->drag)
+ {
+ case DRAG_SELECT:
+ select_extend (data, FALSE, position);
+ break;
+ case DRAG_MOVE:
+ select_move (data, FALSE, position);
+ break;
+ }
+
+ playlistwin_update ();
+ }
+ }
+ else
+ {
+ if (position == -1 || position == active_length)
+ cancel_all (list, data);
+ else if (aud_get_bool (nullptr, "show_filepopup_for_tuple") && data->popup_pos != position)
+ {
+ cancel_all (list, data);
+ popup_trigger (list, data, position);
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean playlist_leave (GtkWidget * list, GdkEventCrossing * event)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (! data->drag)
+ cancel_all (list, data);
+
+ return TRUE;
+}
+
+static gboolean popup_show (void * list)
+{
+ PlaylistData * data = (PlaylistData *) g_object_get_data ((GObject *) list, "playlistdata");
+ g_return_val_if_fail (data, FALSE);
+
+ audgui_infopopup_show (active_playlist, data->popup_pos);
+ data->popup_shown = TRUE;
+
+ g_source_remove (data->popup_source);
+ data->popup_source = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static void popup_trigger (GtkWidget * list, PlaylistData * data, int pos)
+{
+ popup_hide (list, data);
+
+ data->popup_pos = pos;
+ data->popup_source = g_timeout_add (aud_get_int (nullptr, "filepopup_delay") *
+ 100, popup_show, list);
+}
+
+static void popup_hide (GtkWidget * list, PlaylistData * data)
+{
+ if (data->popup_source)
+ {
+ g_source_remove (data->popup_source);
+ data->popup_source = 0;
+ }
+
+ if (data->popup_shown)
+ {
+ audgui_infopopup_hide ();
+ data->popup_shown = FALSE;
+ }
+
+ data->popup_pos = -1;
+}
diff --git a/src/skins/ui_skinned_playlist.h b/src/skins/ui_skinned_playlist.h
index bf1003669c74..ec919178e09e 100644
--- a/src/skins/ui_skinned_playlist.h
+++ b/src/skins/ui_skinned_playlist.h
@@ -30,16 +30,16 @@
#include <gtk/gtk.h>
-GtkWidget * ui_skinned_playlist_new (gint width, gint height, const gchar * font);
+GtkWidget * ui_skinned_playlist_new (int width, int height, const char * font);
void ui_skinned_playlist_set_slider (GtkWidget * list, GtkWidget * slider);
-void ui_skinned_playlist_resize (GtkWidget * list, gint w, gint h);
-void ui_skinned_playlist_set_font (GtkWidget * list, const gchar * font);
+void ui_skinned_playlist_resize (GtkWidget * list, int w, int h);
+void ui_skinned_playlist_set_font (GtkWidget * list, const char * font);
void ui_skinned_playlist_update (GtkWidget * list);
gboolean ui_skinned_playlist_key (GtkWidget * list, GdkEventKey * event);
-void ui_skinned_playlist_row_info (GtkWidget * list, gint * rows, gint * first);
-void ui_skinned_playlist_scroll_to (GtkWidget * list, gint row);
-void ui_skinned_playlist_set_focused (GtkWidget * list, gint row);
-void ui_skinned_playlist_hover (GtkWidget * list, gint x, gint y);
-gint ui_skinned_playlist_hover_end (GtkWidget * list);
+void ui_skinned_playlist_row_info (GtkWidget * list, int * rows, int * first);
+void ui_skinned_playlist_scroll_to (GtkWidget * list, int row);
+void ui_skinned_playlist_set_focused (GtkWidget * list, int row);
+void ui_skinned_playlist_hover (GtkWidget * list, int x, int y);
+int ui_skinned_playlist_hover_end (GtkWidget * list);
#endif
diff --git a/src/skins/ui_skinned_playlist_slider.c b/src/skins/ui_skinned_playlist_slider.c
deleted file mode 100644
index 0b4034c2ed5f..000000000000
--- a/src/skins/ui_skinned_playlist_slider.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz MoÅ
- * Copyright (c) 2011 John Lindgren
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "draw-compat.h"
-#include "ui_playlist.h"
-#include "ui_skin.h"
-#include "ui_skinned_playlist.h"
-#include "ui_skinned_playlist_slider.h"
-
-static GtkWidget * pl_slider_list;
-static gint pl_slider_height;
-static gboolean pl_slider_pressed;
-
-DRAW_FUNC_BEGIN (pl_slider_draw)
- gint rows, first;
- ui_skinned_playlist_row_info (pl_slider_list, & rows, & first);
-
- gint range = active_length - rows;
-
- gint y;
- if (active_length > rows)
- y = (first * (pl_slider_height - 19) + range / 2) / range;
- else
- y = 0;
-
- for (gint i = 0; i < pl_slider_height / 29; i ++)
- skin_draw_pixbuf (cr, SKIN_PLEDIT, 36, 42, 0, 29 * i, 8, 29);
-
- skin_draw_pixbuf (cr, SKIN_PLEDIT, pl_slider_pressed ? 61 : 52, 53, 0, y, 8,
- 18);
-DRAW_FUNC_END
-
-static void pl_slider_set_pos (gint y)
-{
- y = CLAMP (y, 0, pl_slider_height - 19);
-
- gint rows, first;
- ui_skinned_playlist_row_info (pl_slider_list, & rows, & first);
-
- gint range = pl_slider_height - 19;
-
- ui_skinned_playlist_scroll_to (pl_slider_list, (y * (active_length - rows) +
- range / 2) / range);
-}
-
-static gboolean pl_slider_button_press (GtkWidget * slider, GdkEventButton *
- event)
-{
- if (event->button != 1)
- return FALSE;
-
- pl_slider_pressed = TRUE;
- pl_slider_set_pos (event->y - 9);
-
- gtk_widget_queue_draw (slider);
- return TRUE;
-}
-
-static gboolean pl_slider_button_release (GtkWidget * slider, GdkEventButton *
- event)
-{
- if (event->button != 1)
- return FALSE;
-
- if (! pl_slider_pressed)
- return TRUE;
-
- pl_slider_pressed = FALSE;
- pl_slider_set_pos (event->y - 9);
-
- gtk_widget_queue_draw (slider);
- return TRUE;
-}
-
-static gboolean pl_slider_motion (GtkWidget * slider, GdkEventMotion * event)
-{
- if (! pl_slider_pressed)
- return TRUE;
-
- pl_slider_set_pos (event->y - 9);
-
- gtk_widget_queue_draw (slider);
- return TRUE;
-}
-
-GtkWidget * ui_skinned_playlist_slider_new (GtkWidget * list, gint height)
-{
- GtkWidget * slider = gtk_drawing_area_new ();
- gtk_widget_set_size_request (slider, 8, height);
- gtk_widget_add_events (slider, GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
-
- pl_slider_list = list;
- pl_slider_height = height;
-
- DRAW_CONNECT (slider, pl_slider_draw);
- g_signal_connect (slider, "button-press-event", (GCallback)
- pl_slider_button_press, NULL);
- g_signal_connect (slider, "button-release-event", (GCallback)
- pl_slider_button_release, NULL);
- g_signal_connect (slider, "motion-notify-event", (GCallback)
- pl_slider_motion, NULL);
-
- return slider;
-}
-
-void ui_skinned_playlist_slider_resize (GtkWidget * slider, gint height)
-{
- pl_slider_height = height;
- gtk_widget_set_size_request (slider, 8, height);
- gtk_widget_queue_draw (slider);
-}
-
-void ui_skinned_playlist_slider_update (GtkWidget * slider)
-{
- gtk_widget_queue_draw (slider);
-}
diff --git a/src/skins/ui_skinned_playlist_slider.cc b/src/skins/ui_skinned_playlist_slider.cc
new file mode 100644
index 000000000000..19a3cb879458
--- /dev/null
+++ b/src/skins/ui_skinned_playlist_slider.cc
@@ -0,0 +1,144 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz MoÅ
+ * Copyright (c) 2011 John Lindgren
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <libaudcore/objects.h>
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "ui_playlist.h"
+#include "ui_skin.h"
+#include "ui_skinned_playlist.h"
+#include "ui_skinned_playlist_slider.h"
+
+static GtkWidget * pl_slider_list;
+static int pl_slider_height;
+static gboolean pl_slider_pressed;
+
+DRAW_FUNC_BEGIN (pl_slider_draw)
+ int rows, first;
+ ui_skinned_playlist_row_info (pl_slider_list, & rows, & first);
+
+ int range = active_length - rows;
+
+ int y;
+ if (active_length > rows)
+ y = (first * (pl_slider_height - 19) + range / 2) / range;
+ else
+ y = 0;
+
+ for (int i = 0; i < pl_slider_height / 29; i ++)
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, 36, 42, 0, 29 * i, 8, 29);
+
+ skin_draw_pixbuf (cr, SKIN_PLEDIT, pl_slider_pressed ? 61 : 52, 53, 0, y, 8,
+ 18);
+DRAW_FUNC_END
+
+static void pl_slider_set_pos (int y)
+{
+ y = aud::clamp (y, 0, pl_slider_height - 19);
+
+ int rows, first;
+ ui_skinned_playlist_row_info (pl_slider_list, & rows, & first);
+
+ int range = pl_slider_height - 19;
+
+ ui_skinned_playlist_scroll_to (pl_slider_list, (y * (active_length - rows) +
+ range / 2) / range);
+}
+
+static gboolean pl_slider_button_press (GtkWidget * slider, GdkEventButton *
+ event)
+{
+ if (event->button != 1)
+ return FALSE;
+
+ pl_slider_pressed = TRUE;
+ pl_slider_set_pos (event->y / config.scale - 9);
+
+ gtk_widget_queue_draw (slider);
+ return TRUE;
+}
+
+static gboolean pl_slider_button_release (GtkWidget * slider, GdkEventButton *
+ event)
+{
+ if (event->button != 1)
+ return FALSE;
+
+ if (! pl_slider_pressed)
+ return TRUE;
+
+ pl_slider_pressed = FALSE;
+ pl_slider_set_pos (event->y / config.scale - 9);
+
+ gtk_widget_queue_draw (slider);
+ return TRUE;
+}
+
+static gboolean pl_slider_motion (GtkWidget * slider, GdkEventMotion * event)
+{
+ if (! pl_slider_pressed)
+ return TRUE;
+
+ pl_slider_set_pos (event->y / config.scale - 9);
+
+ gtk_widget_queue_draw (slider);
+ return TRUE;
+}
+
+GtkWidget * ui_skinned_playlist_slider_new (GtkWidget * list, int height)
+{
+ GtkWidget * slider = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (slider, 8 * config.scale, height * config.scale);
+ gtk_widget_add_events (slider, GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
+
+ pl_slider_list = list;
+ pl_slider_height = height;
+
+ DRAW_CONNECT (slider, pl_slider_draw);
+ g_signal_connect (slider, "button-press-event", (GCallback)
+ pl_slider_button_press, nullptr);
+ g_signal_connect (slider, "button-release-event", (GCallback)
+ pl_slider_button_release, nullptr);
+ g_signal_connect (slider, "motion-notify-event", (GCallback)
+ pl_slider_motion, nullptr);
+
+ return slider;
+}
+
+void ui_skinned_playlist_slider_resize (GtkWidget * slider, int height)
+{
+ pl_slider_height = height;
+ gtk_widget_set_size_request (slider, 8 * config.scale, height * config.scale);
+ gtk_widget_queue_draw (slider);
+}
+
+void ui_skinned_playlist_slider_update (GtkWidget * slider)
+{
+ gtk_widget_queue_draw (slider);
+}
diff --git a/src/skins/ui_skinned_playlist_slider.h b/src/skins/ui_skinned_playlist_slider.h
index 2bdb374f2511..8d28d3e7a5dc 100644
--- a/src/skins/ui_skinned_playlist_slider.h
+++ b/src/skins/ui_skinned_playlist_slider.h
@@ -30,8 +30,8 @@
#include <gtk/gtk.h>
-GtkWidget * ui_skinned_playlist_slider_new (GtkWidget * list, gint height);
-void ui_skinned_playlist_slider_resize (GtkWidget * slider, gint height);
+GtkWidget * ui_skinned_playlist_slider_new (GtkWidget * list, int height);
+void ui_skinned_playlist_slider_resize (GtkWidget * slider, int height);
void ui_skinned_playlist_slider_update (GtkWidget * slider);
#endif
diff --git a/src/skins/ui_skinned_playstatus.c b/src/skins/ui_skinned_playstatus.c
deleted file mode 100644
index 44d6f57e05c4..000000000000
--- a/src/skins/ui_skinned_playstatus.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz MoÅ
- * Copyright (c) 2011 John Lindgren
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "draw-compat.h"
-#include "ui_skin.h"
-#include "ui_skinned_playstatus.h"
-
-static gint playstatus_width, playstatus_height;
-static PStatus playstatus_status;
-
-DRAW_FUNC_BEGIN (playstatus_draw)
- if (! playstatus_width || ! playstatus_height)
- goto DONE;
-
- if (playstatus_status == STATUS_PLAY)
- skin_draw_pixbuf (cr, SKIN_PLAYPAUSE, 36, 0, 0, 0, 3, playstatus_height);
- else
- skin_draw_pixbuf (cr, SKIN_PLAYPAUSE, 27, 0, 0, 0, 2, playstatus_height);
-
- switch (playstatus_status)
- {
- case STATUS_STOP:
- skin_draw_pixbuf (cr, SKIN_PLAYPAUSE, 18, 0, 2, 0, 9, playstatus_height);
- break;
- case STATUS_PAUSE:
- skin_draw_pixbuf (cr, SKIN_PLAYPAUSE, 9, 0, 2, 0, 9, playstatus_height);
- break;
- case STATUS_PLAY:
- skin_draw_pixbuf (cr, SKIN_PLAYPAUSE, 1, 0, 3, 0, 8, playstatus_height);
- break;
- }
-
-DONE:
-DRAW_FUNC_END
-
-GtkWidget * ui_skinned_playstatus_new (void)
-{
- GtkWidget * playstatus = gtk_drawing_area_new ();
- DRAW_CONNECT (playstatus, playstatus_draw);
- return playstatus;
-}
-
-void ui_skinned_playstatus_set_status (GtkWidget * playstatus, PStatus status)
-{
- playstatus_status = status;
- gtk_widget_queue_draw (playstatus);
-}
-
-void ui_skinned_playstatus_set_size (GtkWidget * playstatus, gint width, gint
- height)
-{
- playstatus_width = width;
- playstatus_height = height;
-
- gtk_widget_set_size_request (playstatus, width, height);
- gtk_widget_queue_draw (playstatus);
-}
diff --git a/src/skins/ui_skinned_playstatus.cc b/src/skins/ui_skinned_playstatus.cc
new file mode 100644
index 000000000000..f4f51e39beb5
--- /dev/null
+++ b/src/skins/ui_skinned_playstatus.cc
@@ -0,0 +1,82 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz MoÅ
+ * Copyright (c) 2011 John Lindgren
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "ui_skin.h"
+#include "ui_skinned_playstatus.h"
+
+static int playstatus_width, playstatus_height;
+static PStatus playstatus_status;
+
+DRAW_FUNC_BEGIN (playstatus_draw)
+ if (! playstatus_width || ! playstatus_height)
+ goto DONE;
+
+ if (playstatus_status == STATUS_PLAY)
+ skin_draw_pixbuf (cr, SKIN_PLAYPAUSE, 36, 0, 0, 0, 3, playstatus_height);
+ else
+ skin_draw_pixbuf (cr, SKIN_PLAYPAUSE, 27, 0, 0, 0, 2, playstatus_height);
+
+ switch (playstatus_status)
+ {
+ case STATUS_STOP:
+ skin_draw_pixbuf (cr, SKIN_PLAYPAUSE, 18, 0, 2, 0, 9, playstatus_height);
+ break;
+ case STATUS_PAUSE:
+ skin_draw_pixbuf (cr, SKIN_PLAYPAUSE, 9, 0, 2, 0, 9, playstatus_height);
+ break;
+ case STATUS_PLAY:
+ skin_draw_pixbuf (cr, SKIN_PLAYPAUSE, 1, 0, 3, 0, 8, playstatus_height);
+ break;
+ }
+
+DONE:
+DRAW_FUNC_END
+
+GtkWidget * ui_skinned_playstatus_new (void)
+{
+ GtkWidget * playstatus = gtk_drawing_area_new ();
+ DRAW_CONNECT (playstatus, playstatus_draw);
+ return playstatus;
+}
+
+void ui_skinned_playstatus_set_status (GtkWidget * playstatus, PStatus status)
+{
+ playstatus_status = status;
+ gtk_widget_queue_draw (playstatus);
+}
+
+void ui_skinned_playstatus_set_size (GtkWidget * playstatus, int width, int
+ height)
+{
+ playstatus_width = width;
+ playstatus_height = height;
+
+ gtk_widget_set_size_request (playstatus, width * config.scale, height * config.scale);
+ gtk_widget_queue_draw (playstatus);
+}
diff --git a/src/skins/ui_skinned_playstatus.h b/src/skins/ui_skinned_playstatus.h
index efbddd6e566b..ffa8c4631887 100644
--- a/src/skins/ui_skinned_playstatus.h
+++ b/src/skins/ui_skinned_playstatus.h
@@ -36,6 +36,6 @@ typedef enum {
GtkWidget * ui_skinned_playstatus_new (void);
void ui_skinned_playstatus_set_status(GtkWidget *widget, PStatus status);
-void ui_skinned_playstatus_set_size(GtkWidget *widget, gint width, gint height);
+void ui_skinned_playstatus_set_size(GtkWidget *widget, int width, int height);
#endif
diff --git a/src/skins/ui_skinned_textbox.c b/src/skins/ui_skinned_textbox.c
deleted file mode 100644
index 54e8d94804df..000000000000
--- a/src/skins/ui_skinned_textbox.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz MoÅ
- * Copyright (c) 2011 John Lindgren
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <string.h>
-
-#include "draw-compat.h"
-#include "skins_cfg.h"
-#include "ui_skin.h"
-#include "ui_skinned_textbox.h"
-
-#define TIMEOUT 30
-#define DELAY 50
-
-typedef struct {
- gint width;
- gchar * text;
- PangoFontDescription * font;
- cairo_surface_t * buf;
- gint buf_width;
- gboolean may_scroll, scrolling, backward;
- gint scroll_source;
- gint offset, delay;
-} TextboxData;
-
-static GList * textboxes;
-
-DRAW_FUNC_BEGIN (textbox_draw)
- TextboxData * data = g_object_get_data ((GObject *) wid, "textboxdata");
- g_return_val_if_fail (data && data->buf, FALSE);
-
- if (data->scrolling)
- {
- cairo_set_source_surface (cr, data->buf, -data->offset, 0);
- cairo_paint (cr);
-
- if (-data->offset + data->buf_width < data->width)
- {
- cairo_set_source_surface (cr, data->buf, -data->offset +
- data->buf_width, 0);
- cairo_paint (cr);
- }
- }
- else
- {
- cairo_set_source_surface (cr, data->buf, 0, 0);
- cairo_paint (cr);
- }
-DRAW_FUNC_END
-
-static gboolean textbox_scroll (GtkWidget * textbox)
-{
- TextboxData * data = g_object_get_data ((GObject *) textbox, "textboxdata");
- g_return_val_if_fail (data, FALSE);
-
- if (data->delay < DELAY)
- {
- data->delay ++;
- return TRUE;
- }
-
- if (config.twoway_scroll && data->backward)
- data->offset --;
- else
- data->offset ++;
-
- if (config.twoway_scroll && (data->backward ? (data->offset <= 0) :
- (data->offset + data->width >= data->buf_width)))
- {
- data->backward = ! data->backward;
- data->delay = 0;
- }
-
- if (! config.twoway_scroll && data->offset >= data->buf_width)
- data->offset = 0;
-
- gtk_widget_queue_draw (textbox);
- return TRUE;
-}
-
-static void textbox_render_vector (GtkWidget * textbox, TextboxData * data,
- const gchar * text)
-{
- g_return_if_fail (data->font && ! data->buf && text);
-
- PangoLayout * layout = gtk_widget_create_pango_layout (textbox, text);
- pango_layout_set_font_description (layout, data->font);
-
- PangoRectangle rect;
- pango_layout_get_pixel_extents (layout, & rect, NULL);
-
- gtk_widget_set_size_request (textbox, data->width, rect.height);
-
- data->buf_width = MAX (rect.width, data->width);
- data->buf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- data->buf_width, rect.height);
-
- cairo_t * cr = cairo_create (data->buf);
-
- set_cairo_color (cr, active_skin->colors[SKIN_TEXTBG]);
- cairo_paint (cr);
-
- cairo_move_to (cr, -rect.x, -rect.y);
- set_cairo_color (cr, active_skin->colors[SKIN_TEXTFG]);
- pango_cairo_show_layout (cr, layout);
-
- cairo_destroy (cr);
- g_object_unref (layout);
-}
-
-static void lookup_char (const gchar c, gint * x, gint * y)
-{
- gint tx, ty;
-
- switch (c)
- {
- case '"': tx = 26; ty = 0; break;
- case '@': tx = 27; ty = 0; break;
- case ' ': tx = 29; ty = 0; break;
- case ':':
- case ';':
- case '|': tx = 12; ty = 1; break;
- case '(':
- case '{': tx = 13; ty = 1; break;
- case ')':
- case '}': tx = 14; ty = 1; break;
- case '-':
- case '~': tx = 15; ty = 1; break;
- case '`':
- case '\'': tx = 16; ty = 1; break;
- case '!': tx = 17; ty = 1; break;
- case '_': tx = 18; ty = 1; break;
- case '+': tx = 19; ty = 1; break;
- case '\\': tx = 20; ty = 1; break;
- case '/': tx = 21; ty = 1; break;
- case '[': tx = 22; ty = 1; break;
- case ']': tx = 23; ty = 1; break;
- case '^': tx = 24; ty = 1; break;
- case '&': tx = 25; ty = 1; break;
- case '%': tx = 26; ty = 1; break;
- case '.':
- case ',': tx = 27; ty = 1; break;
- case '=': tx = 28; ty = 1; break;
- case '$': tx = 29; ty = 1; break;
- case '#': tx = 30; ty = 1; break;
- case '?': tx = 3; ty = 2; break;
- case '*': tx = 4; ty = 2; break;
- default: tx = 3; ty = 2; break; /* '?' */
- }
-
- * x = tx * active_skin->properties.textbox_bitmap_font_width;
- * y = ty * active_skin->properties.textbox_bitmap_font_height;
-}
-
-static void textbox_render_bitmap (GtkWidget * textbox, TextboxData * data,
- const gchar * text)
-{
- g_return_if_fail (! data->font && ! data->buf && text);
-
- gint cw = active_skin->properties.textbox_bitmap_font_width;
- gint ch = active_skin->properties.textbox_bitmap_font_height;
-
- gtk_widget_set_size_request (textbox, data->width, ch);
-
- glong len;
- gunichar * utf32 = g_utf8_to_ucs4 (text, -1, NULL, & len, NULL);
- g_return_if_fail (utf32);
-
- data->buf_width = MAX (cw * len, data->width);
- data->buf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- data->buf_width, ch);
-
- cairo_t * cr = cairo_create (data->buf);
-
- gunichar * s = utf32;
- for (gint x = 0; x < data->buf_width; x += cw)
- {
- gunichar c = * s ? * s ++ : ' ';
- gint cx = 0, cy = 0;
-
- if (c >= 'A' && c <= 'Z')
- cx = cw * (c - 'A');
- else if (c >= 'a' && c <= 'z')
- cx = cw * (c - 'a');
- else if (c >= '0' && c <= '9')
- {
- cx = cw * (c - '0');
- cy = ch;
- }
- else
- lookup_char (c, & cx, & cy);
-
- skin_draw_pixbuf (cr, SKIN_TEXT, cx, cy, x, 0, cw, ch);
- }
-
- cairo_destroy (cr);
- g_free (utf32);
-}
-
-static void textbox_render (GtkWidget * textbox, TextboxData * data)
-{
- g_return_if_fail (data->text);
-
- if (data->buf)
- {
- cairo_surface_destroy (data->buf);
- data->buf = NULL;
- }
-
- data->scrolling = FALSE;
- data->backward = FALSE;
- data->offset = 0;
- data->delay = 0;
-
- if (data->font)
- textbox_render_vector (textbox, data, data->text);
- else
- textbox_render_bitmap (textbox, data, data->text);
-
- if (data->may_scroll && data->buf_width > data->width)
- {
- data->scrolling = TRUE;
-
- if (! config.twoway_scroll)
- {
- if (data->buf)
- {
- cairo_surface_destroy (data->buf);
- data->buf = NULL;
- }
-
- gchar * temp = g_strdup_printf ("%s --- ", data->text);
-
- if (data->font)
- textbox_render_vector (textbox, data, temp);
- else
- textbox_render_bitmap (textbox, data, temp);
-
- g_free (temp);
- }
- }
-
- gtk_widget_queue_draw (textbox);
-
- if (data->scrolling)
- {
- if (! data->scroll_source)
- data->scroll_source = g_timeout_add (TIMEOUT, (GSourceFunc)
- textbox_scroll, textbox);
- }
- else
- {
- if (data->scroll_source)
- {
- g_source_remove (data->scroll_source);
- data->scroll_source = 0;
- }
- }
-}
-
-void textbox_set_width (GtkWidget * textbox, gint width)
-{
- TextboxData * data = g_object_get_data ((GObject *) textbox, "textboxdata");
- g_return_if_fail (data);
-
- if (data->width == width)
- return;
-
- data->width = width;
- textbox_render (textbox, data);
-}
-
-const gchar * textbox_get_text (GtkWidget * textbox)
-{
- TextboxData * data = g_object_get_data ((GObject *) textbox, "textboxdata");
- g_return_val_if_fail (data, NULL);
-
- return data->text;
-}
-
-void textbox_set_text (GtkWidget * textbox, const gchar * text)
-{
- TextboxData * data = g_object_get_data ((GObject *) textbox, "textboxdata");
- g_return_if_fail (data);
-
- if (! text)
- text = "";
-
- if (data->text && ! strcmp (data->text, text))
- return;
-
- g_free (data->text);
- data->text = g_strdup (text);
- textbox_render (textbox, data);
-}
-
-void textbox_set_font (GtkWidget * textbox, const gchar * font)
-{
- TextboxData * data = g_object_get_data ((GObject *) textbox, "textboxdata");
- g_return_if_fail (data);
-
- if (data->font)
- {
- pango_font_description_free (data->font);
- data->font = NULL;
- }
-
- if (font)
- data->font = pango_font_description_from_string (font);
-
- textbox_render (textbox, data);
-}
-
-void textbox_set_scroll (GtkWidget * textbox, gboolean scroll)
-{
- TextboxData * data = g_object_get_data ((GObject *) textbox, "textboxdata");
- g_return_if_fail (data);
-
- if (data->may_scroll == scroll)
- return;
-
- data->may_scroll = scroll;
- textbox_render (textbox, data);
-}
-
-static void textbox_destroy (GtkWidget * textbox)
-{
- TextboxData * data = g_object_get_data ((GObject *) textbox, "textboxdata");
- g_return_if_fail (data);
-
- if (data->font)
- pango_font_description_free (data->font);
- if (data->buf)
- cairo_surface_destroy (data->buf);
- if (data->scroll_source)
- g_source_remove (data->scroll_source);
-
- g_free (data->text);
- g_free (data);
-
- textboxes = g_list_remove (textboxes, textbox);
-}
-
-GtkWidget * textbox_new (gint width, const gchar * text, const gchar * font,
- gboolean scroll)
-{
- GtkWidget * textbox = gtk_drawing_area_new ();
- gtk_widget_set_size_request (textbox, width, 0);
- gtk_widget_add_events (textbox, GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK);
-
- DRAW_CONNECT (textbox, textbox_draw);
- g_signal_connect (textbox, "destroy", (GCallback) textbox_destroy, NULL);
-
- TextboxData * data = g_malloc0 (sizeof (TextboxData));
- data->width = width;
- data->text = g_strdup (text);
- data->may_scroll = scroll;
- g_object_set_data ((GObject *) textbox, "textboxdata", data);
-
- if (font)
- data->font = pango_font_description_from_string (font);
-
- textboxes = g_list_prepend (textboxes, textbox);
-
- textbox_render (textbox, data);
- return textbox;
-}
-
-void textbox_update_all (void)
-{
- for (GList * node = textboxes; node; node = node->next)
- {
- GtkWidget * textbox = node->data;
- g_return_if_fail (textbox);
- TextboxData * data = g_object_get_data ((GObject *) textbox,
- "textboxdata");
- g_return_if_fail (data);
-
- textbox_render (textbox, data);
- }
-}
diff --git a/src/skins/ui_skinned_textbox.cc b/src/skins/ui_skinned_textbox.cc
new file mode 100644
index 000000000000..574b00387a1a
--- /dev/null
+++ b/src/skins/ui_skinned_textbox.cc
@@ -0,0 +1,412 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz MoÅ
+ * Copyright (c) 2011 John Lindgren
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <string.h>
+#include <libaudcore/objects.h>
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "ui_skin.h"
+#include "ui_skinned_textbox.h"
+
+#define TIMEOUT 30
+#define DELAY 50
+
+typedef struct {
+ int width;
+ char * text;
+ PangoFontDescription * font;
+ cairo_surface_t * buf;
+ int buf_width;
+ bool may_scroll, two_way;
+ bool scrolling, backward;
+ int scroll_source;
+ int offset, delay;
+} TextboxData;
+
+static GList * textboxes;
+
+DRAW_FUNC_BEGIN (textbox_draw)
+ TextboxData * data = (TextboxData *) g_object_get_data ((GObject *) wid, "textboxdata");
+ g_return_val_if_fail (data && data->buf, FALSE);
+
+ if (data->scrolling)
+ {
+ cairo_set_source_surface (cr, data->buf, -data->offset * config.scale, 0);
+ cairo_paint (cr);
+
+ if (-data->offset + data->buf_width < data->width)
+ {
+ cairo_set_source_surface (cr, data->buf, (-data->offset +
+ data->buf_width) * config.scale, 0);
+ cairo_paint (cr);
+ }
+ }
+ else
+ {
+ cairo_set_source_surface (cr, data->buf, 0, 0);
+ cairo_paint (cr);
+ }
+DRAW_FUNC_END
+
+static gboolean textbox_scroll (void * textbox)
+{
+ TextboxData * data = (TextboxData *) g_object_get_data ((GObject *) textbox, "textboxdata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (data->delay < DELAY)
+ {
+ data->delay ++;
+ return G_SOURCE_CONTINUE;
+ }
+
+ if (data->two_way && data->backward)
+ data->offset --;
+ else
+ data->offset ++;
+
+ if (data->two_way && (data->backward ? (data->offset <= 0) :
+ (data->offset + data->width >= data->buf_width)))
+ {
+ data->backward = ! data->backward;
+ data->delay = 0;
+ }
+
+ if (! data->two_way && data->offset >= data->buf_width)
+ data->offset = 0;
+
+ gtk_widget_queue_draw ((GtkWidget *) textbox);
+ return G_SOURCE_CONTINUE;
+}
+
+static void textbox_render_vector (GtkWidget * textbox, TextboxData * data,
+ const char * text)
+{
+ g_return_if_fail (data->font && ! data->buf && text);
+
+ PangoLayout * layout = gtk_widget_create_pango_layout (textbox, text);
+ pango_layout_set_font_description (layout, data->font);
+
+ PangoRectangle ink, logical;
+ pango_layout_get_pixel_extents (layout, & ink, & logical);
+
+ /* use logical width so as not to trim off the trailing space of the " --- " */
+ /* use ink height since vertical space is quite limited */
+ logical.width = aud::max (logical.width, 1);
+ ink.height = aud::max (ink.height, 1);
+
+ gtk_widget_set_size_request (textbox, data->width * config.scale, ink.height);
+
+ data->buf_width = aud::max ((logical.width + config.scale - 1) / config.scale, data->width);
+ data->buf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ data->buf_width * config.scale, ink.height);
+
+ cairo_t * cr = cairo_create (data->buf);
+
+ set_cairo_color (cr, active_skin->colors[SKIN_TEXTBG]);
+ cairo_paint (cr);
+
+ cairo_move_to (cr, -logical.x, -ink.y);
+ set_cairo_color (cr, active_skin->colors[SKIN_TEXTFG]);
+ pango_cairo_show_layout (cr, layout);
+
+ cairo_destroy (cr);
+ g_object_unref (layout);
+}
+
+static void lookup_char (const char c, int * x, int * y)
+{
+ int tx, ty;
+
+ switch (c)
+ {
+ case '"': tx = 26; ty = 0; break;
+ case '@': tx = 27; ty = 0; break;
+ case ' ': tx = 29; ty = 0; break;
+ case ':':
+ case ';':
+ case '|': tx = 12; ty = 1; break;
+ case '(':
+ case '{': tx = 13; ty = 1; break;
+ case ')':
+ case '}': tx = 14; ty = 1; break;
+ case '-':
+ case '~': tx = 15; ty = 1; break;
+ case '`':
+ case '\'': tx = 16; ty = 1; break;
+ case '!': tx = 17; ty = 1; break;
+ case '_': tx = 18; ty = 1; break;
+ case '+': tx = 19; ty = 1; break;
+ case '\\': tx = 20; ty = 1; break;
+ case '/': tx = 21; ty = 1; break;
+ case '[': tx = 22; ty = 1; break;
+ case ']': tx = 23; ty = 1; break;
+ case '^': tx = 24; ty = 1; break;
+ case '&': tx = 25; ty = 1; break;
+ case '%': tx = 26; ty = 1; break;
+ case '.':
+ case ',': tx = 27; ty = 1; break;
+ case '=': tx = 28; ty = 1; break;
+ case '$': tx = 29; ty = 1; break;
+ case '#': tx = 30; ty = 1; break;
+ case '?': tx = 3; ty = 2; break;
+ case '*': tx = 4; ty = 2; break;
+ default: tx = 3; ty = 2; break; /* '?' */
+ }
+
+ * x = tx * active_skin->properties.textbox_bitmap_font_width;
+ * y = ty * active_skin->properties.textbox_bitmap_font_height;
+}
+
+static void textbox_render_bitmap (GtkWidget * textbox, TextboxData * data,
+ const char * text)
+{
+ g_return_if_fail (! data->font && ! data->buf && text);
+
+ int cw = active_skin->properties.textbox_bitmap_font_width;
+ int ch = active_skin->properties.textbox_bitmap_font_height;
+
+ gtk_widget_set_size_request (textbox, data->width * config.scale, ch * config.scale);
+
+ long len;
+ gunichar * utf32 = g_utf8_to_ucs4 (text, -1, nullptr, & len, nullptr);
+ g_return_if_fail (utf32);
+
+ data->buf_width = aud::max (cw * (int) len, data->width);
+ data->buf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ data->buf_width * config.scale, ch * config.scale);
+
+ cairo_t * cr = cairo_create (data->buf);
+
+ gunichar * s = utf32;
+ for (int x = 0; x < data->buf_width; x += cw)
+ {
+ gunichar c = * s ? * s ++ : ' ';
+ int cx = 0, cy = 0;
+
+ if (c >= 'A' && c <= 'Z')
+ cx = cw * (c - 'A');
+ else if (c >= 'a' && c <= 'z')
+ cx = cw * (c - 'a');
+ else if (c >= '0' && c <= '9')
+ {
+ cx = cw * (c - '0');
+ cy = ch;
+ }
+ else
+ lookup_char (c, & cx, & cy);
+
+ skin_draw_pixbuf (cr, SKIN_TEXT, cx, cy, x, 0, cw, ch);
+ }
+
+ cairo_destroy (cr);
+ g_free (utf32);
+}
+
+static void textbox_render (GtkWidget * textbox, TextboxData * data)
+{
+ g_return_if_fail (data->text);
+
+ if (data->buf)
+ {
+ cairo_surface_destroy (data->buf);
+ data->buf = nullptr;
+ }
+
+ data->scrolling = FALSE;
+ data->backward = FALSE;
+ data->offset = 0;
+ data->delay = 0;
+
+ if (data->font)
+ textbox_render_vector (textbox, data, data->text);
+ else
+ textbox_render_bitmap (textbox, data, data->text);
+
+ if (data->may_scroll && data->buf_width > data->width)
+ {
+ data->scrolling = TRUE;
+
+ if (! data->two_way)
+ {
+ if (data->buf)
+ {
+ cairo_surface_destroy (data->buf);
+ data->buf = nullptr;
+ }
+
+ char * temp = g_strdup_printf ("%s --- ", data->text);
+
+ if (data->font)
+ textbox_render_vector (textbox, data, temp);
+ else
+ textbox_render_bitmap (textbox, data, temp);
+
+ g_free (temp);
+ }
+ }
+
+ gtk_widget_queue_draw (textbox);
+
+ if (data->scrolling)
+ {
+ if (! data->scroll_source)
+ data->scroll_source = g_timeout_add (TIMEOUT, textbox_scroll, textbox);
+ }
+ else
+ {
+ if (data->scroll_source)
+ {
+ g_source_remove (data->scroll_source);
+ data->scroll_source = 0;
+ }
+ }
+}
+
+void textbox_set_width (GtkWidget * textbox, int width)
+{
+ TextboxData * data = (TextboxData *) g_object_get_data ((GObject *) textbox, "textboxdata");
+ g_return_if_fail (data);
+
+ if (data->width == width)
+ return;
+
+ data->width = width;
+ textbox_render (textbox, data);
+}
+
+const char * textbox_get_text (GtkWidget * textbox)
+{
+ TextboxData * data = (TextboxData *) g_object_get_data ((GObject *) textbox, "textboxdata");
+ g_return_val_if_fail (data, nullptr);
+
+ return data->text;
+}
+
+void textbox_set_text (GtkWidget * textbox, const char * text)
+{
+ TextboxData * data = (TextboxData *) g_object_get_data ((GObject *) textbox, "textboxdata");
+ g_return_if_fail (data);
+
+ if (! text)
+ text = "";
+
+ if (data->text && ! strcmp (data->text, text))
+ return;
+
+ g_free (data->text);
+ data->text = g_strdup (text);
+ textbox_render (textbox, data);
+}
+
+void textbox_set_font (GtkWidget * textbox, const char * font)
+{
+ TextboxData * data = (TextboxData *) g_object_get_data ((GObject *) textbox, "textboxdata");
+ g_return_if_fail (data);
+
+ if (data->font)
+ {
+ pango_font_description_free (data->font);
+ data->font = nullptr;
+ }
+
+ if (font)
+ data->font = pango_font_description_from_string (font);
+
+ textbox_render (textbox, data);
+}
+
+void textbox_set_scroll (GtkWidget * textbox, gboolean scroll)
+{
+ TextboxData * data = (TextboxData *) g_object_get_data ((GObject *) textbox, "textboxdata");
+ g_return_if_fail (data);
+
+ if (data->may_scroll == scroll && data->two_way == config.twoway_scroll)
+ return;
+
+ data->may_scroll = scroll;
+ data->two_way = config.twoway_scroll;
+ textbox_render (textbox, data);
+}
+
+static void textbox_destroy (GtkWidget * textbox)
+{
+ TextboxData * data = (TextboxData *) g_object_get_data ((GObject *) textbox, "textboxdata");
+ g_return_if_fail (data);
+
+ if (data->font)
+ pango_font_description_free (data->font);
+ if (data->buf)
+ cairo_surface_destroy (data->buf);
+ if (data->scroll_source)
+ g_source_remove (data->scroll_source);
+
+ g_free (data->text);
+ g_free (data);
+
+ textboxes = g_list_remove (textboxes, textbox);
+}
+
+GtkWidget * textbox_new (int width, const char * text, const char * font,
+ gboolean scroll)
+{
+ GtkWidget * textbox = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (textbox, width, 0);
+ gtk_widget_add_events (textbox, GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK);
+
+ DRAW_CONNECT (textbox, textbox_draw);
+ g_signal_connect (textbox, "destroy", (GCallback) textbox_destroy, nullptr);
+
+ TextboxData * data = g_new0 (TextboxData, 1);
+ data->width = width;
+ data->text = g_strdup (text);
+ data->may_scroll = scroll;
+ data->two_way = config.twoway_scroll;
+ g_object_set_data ((GObject *) textbox, "textboxdata", data);
+
+ if (font)
+ data->font = pango_font_description_from_string (font);
+
+ textboxes = g_list_prepend (textboxes, textbox);
+
+ textbox_render (textbox, data);
+ return textbox;
+}
+
+void textbox_update_all (void)
+{
+ for (GList * node = textboxes; node; node = node->next)
+ {
+ GtkWidget * textbox = (GtkWidget *) node->data;
+ g_return_if_fail (textbox);
+ TextboxData * data = (TextboxData *) g_object_get_data ((GObject *) textbox, "textboxdata");
+ g_return_if_fail (data);
+
+ textbox_render (textbox, data);
+ }
+}
diff --git a/src/skins/ui_skinned_textbox.h b/src/skins/ui_skinned_textbox.h
index 4dfb9a0c3edb..9cadea5ea4cb 100644
--- a/src/skins/ui_skinned_textbox.h
+++ b/src/skins/ui_skinned_textbox.h
@@ -30,12 +30,12 @@
#include <gtk/gtk.h>
-GtkWidget * textbox_new (gint width, const gchar * text, const gchar * font,
+GtkWidget * textbox_new (int width, const char * text, const char * font,
gboolean scroll);
-void textbox_set_width (GtkWidget * textbox, gint width);
-const gchar * textbox_get_text (GtkWidget * textbox);
-void textbox_set_text (GtkWidget * textbox, const gchar * text);
-void textbox_set_font (GtkWidget * textbox, const gchar * font);
+void textbox_set_width (GtkWidget * textbox, int width);
+const char * textbox_get_text (GtkWidget * textbox);
+void textbox_set_text (GtkWidget * textbox, const char * text);
+void textbox_set_font (GtkWidget * textbox, const char * font);
void textbox_set_scroll (GtkWidget * textbox, gboolean scroll);
void textbox_update_all (void);
diff --git a/src/skins/ui_skinned_window.c b/src/skins/ui_skinned_window.c
deleted file mode 100644
index e791889e4507..000000000000
--- a/src/skins/ui_skinned_window.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * ui_skinned_window.c
- * Copyright 2011 John Lindgren
- *
- * This file is part of Audacious.
- *
- * Audacious 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, version 2 or version 3 of the License.
- *
- * Audacious 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
- * Audacious. If not, see <http://www.gnu.org/licenses/>.
- *
- * The Audacious team does not consider modular code linking to Audacious or
- * using our public API to be a derived work.
- */
-
-#include "draw-compat.h"
-#include "ui_dock.h"
-#include "ui_skinned_window.h"
-
-typedef struct {
- void (* draw) (GtkWidget * window, cairo_t * cr);
- GtkWidget * normal, * shaded;
- gboolean is_shaded, is_moving;
-} WindowData;
-
-DRAW_FUNC_BEGIN (window_draw)
- WindowData * data = g_object_get_data ((GObject *) wid, "windowdata");
- g_return_val_if_fail (data, FALSE);
-
- if (data->draw)
- data->draw (wid, cr);
-DRAW_FUNC_END
-
-static gboolean window_button_press (GtkWidget * window, GdkEventButton * event)
-{
- WindowData * data = g_object_get_data ((GObject *) window, "windowdata");
- g_return_val_if_fail (data, FALSE);
-
- /* pass double clicks through; they are handled elsewhere */
- if (event->button != 1 || event->type == GDK_2BUTTON_PRESS)
- return FALSE;
-
- if (data->is_moving)
- return TRUE;
-
- dock_move_start (window, event->x_root, event->y_root);
- data->is_moving = TRUE;
- return TRUE;
-}
-
-static gboolean window_button_release (GtkWidget * window, GdkEventButton *
- event)
-{
- WindowData * data = g_object_get_data ((GObject *) window, "windowdata");
- g_return_val_if_fail (data, FALSE);
-
- if (event->button != 1)
- return FALSE;
-
- data->is_moving = FALSE;
- return TRUE;
-}
-
-static gboolean window_motion (GtkWidget * window, GdkEventMotion * event)
-{
- WindowData * data = g_object_get_data ((GObject *) window, "windowdata");
- g_return_val_if_fail (data, FALSE);
-
- if (! data->is_moving)
- return TRUE;
-
- dock_move (event->x_root, event->y_root);
- return TRUE;
-}
-
-static void window_destroy (GtkWidget * window)
-{
- WindowData * data = g_object_get_data ((GObject *) window, "windowdata");
- g_return_if_fail (data);
-
- dock_remove_window (window);
-
- if (data->is_shaded)
- gtk_container_remove ((GtkContainer *) window, data->shaded);
- else
- gtk_container_remove ((GtkContainer *) window, data->normal);
-
- g_object_unref (data->normal);
- g_object_unref (data->shaded);
- g_free (data);
-}
-
-GtkWidget * window_new (gint * x, gint * y, gint w, gint h, gboolean main,
- gboolean shaded, void (* draw) (GtkWidget * window, cairo_t * cr))
-{
- GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_decorated ((GtkWindow *) window, FALSE);
- gtk_window_set_resizable ((GtkWindow *) window, FALSE);
- gtk_window_move ((GtkWindow *) window, * x, * y);
- gtk_widget_set_size_request (window, w, h);
- gtk_window_resize ((GtkWindow *) window, w, h);
-
- gtk_widget_set_app_paintable (window, TRUE);
- gtk_widget_add_events (window, GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK);
-
- DRAW_CONNECT (window, window_draw);
- g_signal_connect (window, "button-press-event", (GCallback) window_button_press, NULL);
- g_signal_connect (window, "button-release-event", (GCallback) window_button_release, NULL);
- g_signal_connect (window, "motion-notify-event", (GCallback) window_motion, NULL);
- g_signal_connect (window, "destroy", (GCallback) window_destroy, NULL);
-
- WindowData * data = g_malloc0 (sizeof (WindowData));
- g_object_set_data ((GObject *) window, "windowdata", data);
-
- data->normal = gtk_fixed_new ();
- g_object_ref (data->normal);
-
- data->shaded = gtk_fixed_new ();
- g_object_ref (data->shaded);
-
- if (shaded)
- gtk_container_add ((GtkContainer *) window, data->shaded);
- else
- gtk_container_add ((GtkContainer *) window, data->normal);
-
- data->is_shaded = shaded;
- data->draw = draw;
-
- dock_add_window (window, x, y, w, h, main);
- return window;
-}
-
-void window_set_size (GtkWidget * window, gint w, gint h)
-{
- gtk_widget_set_size_request (window, w, h);
- gtk_window_resize ((GtkWindow *) window, w, h);
- dock_set_size (window, w, h);
-}
-
-void window_set_shaded (GtkWidget * window, gboolean shaded)
-{
- WindowData * data = g_object_get_data ((GObject *) window, "windowdata");
- g_return_if_fail (data);
-
- if (data->is_shaded == shaded)
- return;
-
- if (shaded)
- {
- gtk_container_remove ((GtkContainer *) window, data->normal);
- gtk_container_add ((GtkContainer *) window, data->shaded);
- }
- else
- {
- gtk_container_remove ((GtkContainer *) window, data->shaded);
- gtk_container_add ((GtkContainer *) window, data->normal);
- }
-
- data->is_shaded = shaded;
-}
-
-void window_put_widget (GtkWidget * window, gboolean shaded, GtkWidget * widget,
- gint x, gint y)
-{
- WindowData * data = g_object_get_data ((GObject *) window, "windowdata");
- g_return_if_fail (data);
-
- GtkWidget * fixed = shaded ? data->shaded : data->normal;
- gtk_fixed_put ((GtkFixed *) fixed, widget, x, y);
-}
-
-void window_move_widget (GtkWidget * window, gboolean shaded, GtkWidget *
- widget, gint x, gint y)
-{
- WindowData * data = g_object_get_data ((GObject *) window, "windowdata");
- g_return_if_fail (data);
-
- GtkWidget * fixed = shaded ? data->shaded : data->normal;
- gtk_fixed_move ((GtkFixed *) fixed, widget, x, y);
-}
-
-void window_show_all (GtkWidget * window)
-{
- WindowData * data = g_object_get_data ((GObject *) window, "windowdata");
- g_return_if_fail (data);
-
- gtk_widget_show_all (data->normal);
- gtk_widget_show_all (data->shaded);
-}
diff --git a/src/skins/ui_skinned_window.cc b/src/skins/ui_skinned_window.cc
new file mode 100644
index 000000000000..e2875ea8cbb3
--- /dev/null
+++ b/src/skins/ui_skinned_window.cc
@@ -0,0 +1,246 @@
+/*
+ * ui_skinned_window.c
+ * Copyright 2011 John Lindgren
+ *
+ * This file is part of Audacious.
+ *
+ * Audacious 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, version 2 or version 3 of the License.
+ *
+ * Audacious 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
+ * Audacious. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The Audacious team does not consider modular code linking to Audacious or
+ * using our public API to be a derived work.
+ */
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "ui_dock.h"
+#include "ui_skinned_window.h"
+
+typedef struct {
+ void (* draw) (GtkWidget * window, cairo_t * cr);
+ GtkWidget * normal, * shaded;
+ GdkRegion * shape, * sshape;
+ gboolean is_shaded, is_moving;
+} WindowData;
+
+DRAW_FUNC_BEGIN (window_draw)
+ WindowData * data = (WindowData *) g_object_get_data ((GObject *) wid, "windowdata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (data->draw)
+ data->draw (wid, cr);
+DRAW_FUNC_END
+
+static void window_apply_shape (GtkWidget * window)
+{
+ WindowData * data = (WindowData *) g_object_get_data ((GObject *) window, "windowdata");
+ g_return_if_fail (data);
+
+ gdk_window_shape_combine_region (gtk_widget_get_window (window),
+ data->is_shaded ? data->sshape : data->shape, 0, 0);
+}
+
+static gboolean window_button_press (GtkWidget * window, GdkEventButton * event)
+{
+ WindowData * data = (WindowData *) g_object_get_data ((GObject *) window, "windowdata");
+ g_return_val_if_fail (data, FALSE);
+
+ /* pass double clicks through; they are handled elsewhere */
+ if (event->button != 1 || event->type == GDK_2BUTTON_PRESS)
+ return FALSE;
+
+ if (data->is_moving)
+ return TRUE;
+
+ dock_move_start (window, event->x_root, event->y_root);
+ data->is_moving = TRUE;
+ return TRUE;
+}
+
+static gboolean window_button_release (GtkWidget * window, GdkEventButton *
+ event)
+{
+ WindowData * data = (WindowData *) g_object_get_data ((GObject *) window, "windowdata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (event->button != 1)
+ return FALSE;
+
+ data->is_moving = FALSE;
+ return TRUE;
+}
+
+static gboolean window_motion (GtkWidget * window, GdkEventMotion * event)
+{
+ WindowData * data = (WindowData *) g_object_get_data ((GObject *) window, "windowdata");
+ g_return_val_if_fail (data, FALSE);
+
+ if (! data->is_moving)
+ return TRUE;
+
+ dock_move (event->x_root, event->y_root);
+ return TRUE;
+}
+
+static void window_destroy (GtkWidget * window)
+{
+ WindowData * data = (WindowData *) g_object_get_data ((GObject *) window, "windowdata");
+ g_return_if_fail (data);
+
+ dock_remove_window (window);
+
+ if (data->is_shaded)
+ gtk_container_remove ((GtkContainer *) window, data->shaded);
+ else
+ gtk_container_remove ((GtkContainer *) window, data->normal);
+
+ g_object_unref (data->normal);
+ g_object_unref (data->shaded);
+
+ if (data->shape)
+ gdk_region_destroy (data->shape);
+ if (data->sshape)
+ gdk_region_destroy (data->sshape);
+
+ g_free (data);
+}
+
+GtkWidget * window_new (int * x, int * y, int w, int h, gboolean main,
+ gboolean shaded, void (* draw) (GtkWidget * window, cairo_t * cr))
+{
+ w *= config.scale;
+ h *= config.scale;
+
+ GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_decorated ((GtkWindow *) window, FALSE);
+ gtk_window_set_resizable ((GtkWindow *) window, FALSE);
+ gtk_window_move ((GtkWindow *) window, * x, * y);
+ gtk_widget_set_size_request (window, w, h);
+ gtk_window_resize ((GtkWindow *) window, w, h);
+
+ gtk_widget_set_app_paintable (window, TRUE);
+ gtk_widget_add_events (window, GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK);
+
+ DRAW_CONNECT (window, window_draw);
+ g_signal_connect (window, "realize", (GCallback) window_apply_shape, nullptr);
+ g_signal_connect (window, "button-press-event", (GCallback) window_button_press, nullptr);
+ g_signal_connect (window, "button-release-event", (GCallback) window_button_release, nullptr);
+ g_signal_connect (window, "motion-notify-event", (GCallback) window_motion, nullptr);
+ g_signal_connect (window, "destroy", (GCallback) window_destroy, nullptr);
+
+ WindowData * data = g_new0 (WindowData, 1);
+ g_object_set_data ((GObject *) window, "windowdata", data);
+
+ data->normal = gtk_fixed_new ();
+ g_object_ref (data->normal);
+
+ data->shaded = gtk_fixed_new ();
+ g_object_ref (data->shaded);
+
+ if (shaded)
+ gtk_container_add ((GtkContainer *) window, data->shaded);
+ else
+ gtk_container_add ((GtkContainer *) window, data->normal);
+
+ data->is_shaded = shaded;
+ data->draw = draw;
+
+ dock_add_window (window, x, y, w, h, main);
+ return window;
+}
+
+void window_set_size (GtkWidget * window, int w, int h)
+{
+ w *= config.scale;
+ h *= config.scale;
+
+ gtk_widget_set_size_request (window, w, h);
+ gtk_window_resize ((GtkWindow *) window, w, h);
+ dock_set_size (window, w, h);
+}
+
+void window_set_shapes (GtkWidget * window, GdkRegion * shape, GdkRegion * sshape)
+{
+ WindowData * data = (WindowData *) g_object_get_data ((GObject *) window, "windowdata");
+ g_return_if_fail (data);
+
+ if (data->shape)
+ gdk_region_destroy (data->shape);
+ if (data->sshape)
+ gdk_region_destroy (data->sshape);
+
+ data->shape = shape;
+ data->sshape = sshape;
+
+ if (gtk_widget_get_realized (window))
+ window_apply_shape (window);
+}
+
+void window_set_shaded (GtkWidget * window, gboolean shaded)
+{
+ WindowData * data = (WindowData *) g_object_get_data ((GObject *) window, "windowdata");
+ g_return_if_fail (data);
+
+ if (data->is_shaded == shaded)
+ return;
+
+ if (shaded)
+ {
+ gtk_container_remove ((GtkContainer *) window, data->normal);
+ gtk_container_add ((GtkContainer *) window, data->shaded);
+ }
+ else
+ {
+ gtk_container_remove ((GtkContainer *) window, data->shaded);
+ gtk_container_add ((GtkContainer *) window, data->normal);
+ }
+
+ data->is_shaded = shaded;
+
+ if (gtk_widget_get_realized (window))
+ window_apply_shape (window);
+}
+
+void window_put_widget (GtkWidget * window, gboolean shaded, GtkWidget * widget,
+ int x, int y)
+{
+ x *= config.scale;
+ y *= config.scale;
+
+ WindowData * data = (WindowData *) g_object_get_data ((GObject *) window, "windowdata");
+ g_return_if_fail (data);
+
+ GtkWidget * fixed = shaded ? data->shaded : data->normal;
+ gtk_fixed_put ((GtkFixed *) fixed, widget, x, y);
+}
+
+void window_move_widget (GtkWidget * window, gboolean shaded, GtkWidget *
+ widget, int x, int y)
+{
+ x *= config.scale;
+ y *= config.scale;
+
+ WindowData * data = (WindowData *) g_object_get_data ((GObject *) window, "windowdata");
+ g_return_if_fail (data);
+
+ GtkWidget * fixed = shaded ? data->shaded : data->normal;
+ gtk_fixed_move ((GtkFixed *) fixed, widget, x, y);
+}
+
+void window_show_all (GtkWidget * window)
+{
+ WindowData * data = (WindowData *) g_object_get_data ((GObject *) window, "windowdata");
+ g_return_if_fail (data);
+
+ gtk_widget_show_all (data->normal);
+ gtk_widget_show_all (data->shaded);
+}
diff --git a/src/skins/ui_skinned_window.h b/src/skins/ui_skinned_window.h
index a6abf9b3ec31..eb73db677d95 100644
--- a/src/skins/ui_skinned_window.h
+++ b/src/skins/ui_skinned_window.h
@@ -24,14 +24,15 @@
#include <gtk/gtk.h>
-GtkWidget * window_new (gint * x, gint * y, gint w, gint h, gboolean main,
+GtkWidget * window_new (int * x, int * y, int w, int h, gboolean main,
gboolean shaded, void (* draw) (GtkWidget * window, cairo_t * cr));
-void window_set_size (GtkWidget * window, gint w, gint h);
+void window_set_size (GtkWidget * window, int w, int h);
+void window_set_shapes (GtkWidget * window, GdkRegion * shape, GdkRegion * sshape);
void window_set_shaded (GtkWidget * window, gboolean shaded);
void window_put_widget (GtkWidget * window, gboolean shaded, GtkWidget * widget,
- gint x, gint y);
+ int x, int y);
void window_move_widget (GtkWidget * window, gboolean shaded, GtkWidget *
- widget, gint x, gint y);
+ widget, int x, int y);
void window_show_all (GtkWidget * window);
#endif
diff --git a/src/skins/ui_skinselector.c b/src/skins/ui_skinselector.c
deleted file mode 100644
index 9898c9cf2484..000000000000
--- a/src/skins/ui_skinselector.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * ui_skinselector.c
- * Copyright 1998-2003 XMMS Development Team
- * Copyright 2003-2004 BMP Development Team
- * Copyright 2011 John Lindgren
- *
- * This file is part of Audacious.
- *
- * Audacious 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, version 2 or version 3 of the License.
- *
- * Audacious 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
- * Audacious. If not, see <http://www.gnu.org/licenses/>.
- *
- * The Audacious team does not consider modular code linking to Audacious or
- * using our public API to be a derived work.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "plugin.h"
-#include "ui_skin.h"
-#include "ui_skinselector.h"
-#include "util.h"
-
-#define EXTENSION_TARGETS 7
-
-static gchar *ext_targets[EXTENSION_TARGETS] = { "bmp", "xpm", "png", "svg",
- "gif", "jpg", "jpeg" };
-
-enum SkinViewCols {
- SKIN_VIEW_COL_PREVIEW,
- SKIN_VIEW_COL_FORMATTEDNAME,
- SKIN_VIEW_COL_NAME,
- SKIN_VIEW_N_COLS
-};
-
-typedef struct {
- gchar *name;
- gchar *desc;
- gchar *path;
- GTime *time;
-} SkinNode;
-
-static void skin_view_on_cursor_changed (GtkTreeView * treeview, void * data);
-
-static GList *skinlist = NULL;
-
-static gchar *
-get_thumbnail_filename(const gchar * path)
-{
- gchar *basename, *pngname, *thumbname;
-
- g_return_val_if_fail(path != NULL, NULL);
-
- basename = g_path_get_basename(path);
- pngname = g_strconcat(basename, ".png", NULL);
-
- thumbname = g_build_filename(skins_paths[SKINS_PATH_SKIN_THUMB_DIR],
- pngname, NULL);
-
- g_free(basename);
- g_free(pngname);
-
- return thumbname;
-}
-
-
-static GdkPixbuf *
-skin_get_preview(const gchar * path)
-{
- GdkPixbuf *preview = NULL;
- gchar *dec_path, *preview_path;
- gboolean is_archive = FALSE;
- gint i = 0;
- gchar buf[60]; /* gives us lots of room */
-
- if (file_is_archive(path))
- {
- if (!(dec_path = archive_decompress(path)))
- return NULL;
-
- is_archive = TRUE;
- }
- else
- {
- dec_path = g_strdup(path);
- }
-
- for (i = 0; i < EXTENSION_TARGETS; i++)
- {
- sprintf(buf, "main.%s", ext_targets[i]);
-
- if ((preview_path = find_file_case_path (dec_path, buf)) != NULL)
- break;
- }
-
- if (preview_path)
- {
- preview = gdk_pixbuf_new_from_file(preview_path, NULL);
- g_free(preview_path);
- }
-
- if (is_archive)
- del_directory(dec_path);
-
- g_free(dec_path);
-
- return preview;
-}
-
-static GdkPixbuf * skin_get_thumbnail (const gchar * path)
-{
- gchar * thumbname = get_thumbnail_filename (path);
- GdkPixbuf * thumb = NULL;
-
- if (g_file_test (thumbname, G_FILE_TEST_EXISTS))
- {
- thumb = gdk_pixbuf_new_from_file (thumbname, NULL);
- if (thumb)
- goto DONE;
- }
-
- thumb = skin_get_preview (path);
- if (! thumb)
- goto DONE;
-
- audgui_pixbuf_scale_within (& thumb, 128);
-
- if (thumb)
- gdk_pixbuf_save (thumb, thumbname, "png", NULL, NULL);
-
-DONE:
- g_free (thumbname);
- return thumb;
-}
-
-static void
-skinlist_add(const gchar * filename)
-{
- SkinNode *node;
- gchar *basename;
-
- g_return_if_fail(filename != NULL);
-
- node = g_slice_new0(SkinNode);
- node->path = g_strdup(filename);
-
- basename = g_path_get_basename(filename);
-
- if (file_is_archive(filename)) {
- node->name = archive_basename(basename);
- node->desc = _("Archived Winamp 2.x skin");
- g_free(basename);
- }
- else {
- node->name = basename;
- node->desc = _("Unarchived Winamp 2.x skin");
- }
-
- skinlist = g_list_prepend(skinlist, node);
-}
-
-static gboolean
-scan_skindir_func(const gchar * path, const gchar * basename, gpointer data)
-{
- if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) {
- if (file_is_archive(path)) {
- skinlist_add(path);
- }
- }
- else if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
- skinlist_add(path);
- }
-
- return FALSE;
-}
-
-static void
-scan_skindir(const gchar * path)
-{
- GError *error = NULL;
-
- g_return_if_fail(path != NULL);
-
- if (path[0] == '.')
- return;
-
- if (!dir_foreach(path, scan_skindir_func, NULL, &error)) {
- g_warning("Failed to open directory (%s): %s", path, error->message);
- g_error_free(error);
- return;
- }
-}
-
-static gint skinlist_compare_func (const void * _a, const void * _b)
-{
- const SkinNode * a = _a, * b = _b;
- g_return_val_if_fail (a && a->name, 1);
- g_return_val_if_fail (b && b->name, 1);
- return g_ascii_strcasecmp (a->name, b->name);
-}
-
-static void skin_free_func (void * _data)
-{
- SkinNode * data = _data;
- g_return_if_fail(data != NULL);
- g_free (data->name);
- g_free (data->path);
- g_slice_free(SkinNode, data);
-}
-
-
-static void
-skinlist_clear(void)
-{
- if (!skinlist)
- return;
-
- g_list_foreach(skinlist, (GFunc) skin_free_func, NULL);
- g_list_free(skinlist);
- skinlist = NULL;
-}
-
-static void
-skinlist_update(void)
-{
- gchar *skinsdir;
-
- skinlist_clear();
-
- if (g_file_test (skins_paths[SKINS_PATH_USER_SKIN_DIR], G_FILE_TEST_EXISTS))
- scan_skindir (skins_paths[SKINS_PATH_USER_SKIN_DIR]);
-
- gchar * path = g_strdup_printf ("%s/Skins", aud_get_path (AUD_PATH_DATA_DIR));
- scan_skindir (path);
- g_free (path);
-
- skinsdir = getenv("SKINSDIR");
- if (skinsdir) {
- gchar **dir_list = g_strsplit(skinsdir, ":", 0);
- gchar **dir;
-
- for (dir = dir_list; *dir; dir++)
- scan_skindir(*dir);
- g_strfreev(dir_list);
- }
-
- skinlist = g_list_sort(skinlist, skinlist_compare_func);
-
- g_assert(skinlist != NULL);
-}
-
-void skin_view_update (GtkTreeView * treeview)
-{
- GtkTreeSelection *selection = NULL;
- GtkListStore *store;
- GtkTreeIter iter, iter_current_skin;
- gboolean have_current_skin = FALSE;
- GtkTreePath *path;
-
- GdkPixbuf *thumbnail;
- gchar *formattedname;
- gchar *name;
- GList *entry;
-
- g_signal_handlers_block_by_func (treeview, (GCallback) skin_view_on_cursor_changed, NULL);
-
- store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
-
- gtk_list_store_clear(store);
-
- skinlist_update();
-
- for (entry = skinlist; entry; entry = entry->next)
- {
- SkinNode * node = entry->data;
-
- thumbnail = skin_get_thumbnail (node->path);
- formattedname = g_strdup_printf ("<big><b>%s</b></big>\n<i>%s</i>",
- node->name, node->desc);
- name = node->name;
-
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter,
- SKIN_VIEW_COL_PREVIEW, thumbnail,
- SKIN_VIEW_COL_FORMATTEDNAME, formattedname,
- SKIN_VIEW_COL_NAME, name, -1);
- if (thumbnail)
- g_object_unref(thumbnail);
- g_free(formattedname);
-
- if (g_strstr_len(active_skin->path,
- strlen(active_skin->path), name) ) {
- iter_current_skin = iter;
- have_current_skin = TRUE;
- }
- }
-
- if (have_current_skin) {
- selection = gtk_tree_view_get_selection(treeview);
- gtk_tree_selection_select_iter(selection, &iter_current_skin);
-
- path = gtk_tree_model_get_path(GTK_TREE_MODEL(store),
- &iter_current_skin);
- gtk_tree_view_scroll_to_cell(treeview, path, NULL, TRUE, 0.5, 0.5);
- gtk_tree_path_free(path);
- }
-
- g_signal_handlers_unblock_by_func (treeview, (GCallback) skin_view_on_cursor_changed, NULL);
-}
-
-
-static void
-skin_view_on_cursor_changed(GtkTreeView * treeview,
- gpointer data)
-{
- GtkTreeModel *model;
- GtkTreeSelection *selection;
- GtkTreeIter iter;
-
- GList *node;
- gchar *name;
- gchar *comp = NULL;
-
- selection = gtk_tree_view_get_selection(treeview);
-
- /* workaround for Gnome bug #679291 */
- if (! selection)
- return;
-
- if (!gtk_tree_selection_get_selected(selection, &model, &iter))
- return;
-
- gtk_tree_model_get(model, &iter, SKIN_VIEW_COL_NAME, &name, -1);
-
- for (node = skinlist; node; node = g_list_next(node)) {
- comp = ((SkinNode *) node->data)->path;
- if (g_strrstr(comp, name))
- break;
- }
-
- g_free(name);
-
- active_skin_load (comp);
-}
-
-
-void
-skin_view_realize(GtkTreeView * treeview)
-{
- GtkListStore *store;
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
- GtkTreeSelection *selection;
-
- gtk_widget_show_all(GTK_WIDGET(treeview));
-
- gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
- gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
-
- store = gtk_list_store_new(SKIN_VIEW_N_COLS, GDK_TYPE_PIXBUF,
- G_TYPE_STRING , G_TYPE_STRING);
- gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store));
- g_object_unref (store);
-
- column = gtk_tree_view_column_new();
- gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
- gtk_tree_view_column_set_spacing(column, 16);
- gtk_tree_view_append_column(GTK_TREE_VIEW(treeview),
- GTK_TREE_VIEW_COLUMN(column));
-
- renderer = gtk_cell_renderer_pixbuf_new();
- gtk_tree_view_column_pack_start(column, renderer, FALSE);
- gtk_tree_view_column_set_attributes(column, renderer, "pixbuf",
- SKIN_VIEW_COL_PREVIEW, NULL);
-
- renderer = gtk_cell_renderer_text_new();
- gtk_tree_view_column_pack_start(column, renderer, TRUE);
- gtk_tree_view_column_set_attributes(column, renderer, "markup",
- SKIN_VIEW_COL_FORMATTEDNAME, NULL);
-
- selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
- gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
-
- g_signal_connect(treeview, "cursor-changed",
- G_CALLBACK(skin_view_on_cursor_changed), NULL);
-}
diff --git a/src/skins/ui_skinselector.cc b/src/skins/ui_skinselector.cc
new file mode 100644
index 000000000000..71b0ae9248ef
--- /dev/null
+++ b/src/skins/ui_skinselector.cc
@@ -0,0 +1,398 @@
+/*
+ * ui_skinselector.c
+ * Copyright 1998-2003 XMMS Development Team
+ * Copyright 2003-2004 BMP Development Team
+ * Copyright 2011 John Lindgren
+ *
+ * This file is part of Audacious.
+ *
+ * Audacious 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, version 2 or version 3 of the License.
+ *
+ * Audacious 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
+ * Audacious. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The Audacious team does not consider modular code linking to Audacious or
+ * using our public API to be a derived work.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/runtime.h>
+#include <libaudgui/libaudgui-gtk.h>
+
+#include "plugin.h"
+#include "ui_skin.h"
+#include "ui_skinselector.h"
+#include "util.h"
+
+#define EXTENSION_TARGETS 7
+
+static const char *ext_targets[EXTENSION_TARGETS] = { "bmp", "xpm", "png", "svg",
+ "gif", "jpg", "jpeg" };
+
+enum SkinViewCols {
+ SKIN_VIEW_COL_PREVIEW,
+ SKIN_VIEW_COL_FORMATTEDNAME,
+ SKIN_VIEW_COL_NAME,
+ SKIN_VIEW_N_COLS
+};
+
+typedef struct {
+ char *name;
+ char *desc;
+ char *path;
+ GTime *time;
+} SkinNode;
+
+static void skin_view_on_cursor_changed (GtkTreeView * treeview, void * data);
+
+static GList *skinlist = nullptr;
+
+static char *
+get_thumbnail_filename(const char * path)
+{
+ char *basename, *pngname, *thumbname;
+
+ g_return_val_if_fail(path != nullptr, nullptr);
+
+ basename = g_path_get_basename(path);
+ pngname = g_strconcat(basename, ".png", nullptr);
+
+ thumbname = g_build_filename(skins_paths[SKINS_PATH_SKIN_THUMB_DIR],
+ pngname, nullptr);
+
+ g_free(basename);
+ g_free(pngname);
+
+ return thumbname;
+}
+
+
+static GdkPixbuf *
+skin_get_preview(const char * path)
+{
+ GdkPixbuf *preview = nullptr;
+ char *dec_path, *preview_path;
+ gboolean is_archive = FALSE;
+ int i = 0;
+ char buf[60]; /* gives us lots of room */
+
+ if (file_is_archive(path))
+ {
+ if (!(dec_path = archive_decompress(path)))
+ return nullptr;
+
+ is_archive = TRUE;
+ }
+ else
+ {
+ dec_path = g_strdup(path);
+ }
+
+ for (i = 0; i < EXTENSION_TARGETS; i++)
+ {
+ sprintf(buf, "main.%s", ext_targets[i]);
+
+ if ((preview_path = find_file_case_path (dec_path, buf)) != nullptr)
+ break;
+ }
+
+ if (preview_path)
+ {
+ preview = gdk_pixbuf_new_from_file(preview_path, nullptr);
+ g_free(preview_path);
+ }
+
+ if (is_archive)
+ del_directory(dec_path);
+
+ g_free(dec_path);
+
+ return preview;
+}
+
+static GdkPixbuf * skin_get_thumbnail (const char * path)
+{
+ char * thumbname = get_thumbnail_filename (path);
+ GdkPixbuf * thumb = nullptr;
+
+ if (g_file_test (thumbname, G_FILE_TEST_EXISTS))
+ {
+ thumb = gdk_pixbuf_new_from_file (thumbname, nullptr);
+ if (thumb)
+ goto DONE;
+ }
+
+ thumb = skin_get_preview (path);
+ if (! thumb)
+ goto DONE;
+
+ audgui_pixbuf_scale_within (& thumb, 128);
+
+ if (thumb)
+ {
+ make_directory (skins_paths[SKINS_PATH_SKIN_THUMB_DIR]);
+ gdk_pixbuf_save (thumb, thumbname, "png", nullptr, nullptr);
+ }
+
+DONE:
+ g_free (thumbname);
+ return thumb;
+}
+
+static void
+skinlist_add(const char * filename)
+{
+ SkinNode *node;
+ char *basename;
+
+ g_return_if_fail(filename != nullptr);
+
+ node = g_slice_new0(SkinNode);
+ node->path = g_strdup(filename);
+
+ basename = g_path_get_basename(filename);
+
+ if (file_is_archive(filename)) {
+ node->name = archive_basename(basename);
+ node->desc = _("Archived Winamp 2.x skin");
+ g_free(basename);
+ }
+ else {
+ node->name = basename;
+ node->desc = _("Unarchived Winamp 2.x skin");
+ }
+
+ skinlist = g_list_prepend(skinlist, node);
+}
+
+static gboolean
+scan_skindir_func(const char * path, const char * basename, void * data)
+{
+ if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) {
+ if (file_is_archive(path)) {
+ skinlist_add(path);
+ }
+ }
+ else if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
+ skinlist_add(path);
+ }
+
+ return FALSE;
+}
+
+static void
+scan_skindir(const char * path)
+{
+ GError *error = nullptr;
+
+ g_return_if_fail(path != nullptr);
+
+ if (path[0] == '.')
+ return;
+
+ if (!dir_foreach(path, scan_skindir_func, nullptr, &error)) {
+ g_warning("Failed to open directory (%s): %s", path, error->message);
+ g_error_free(error);
+ return;
+ }
+}
+
+static int skinlist_compare_func (const void * _a, const void * _b)
+{
+ const SkinNode * a = (SkinNode *) _a, * b = (SkinNode *) _b;
+ g_return_val_if_fail (a && a->name, 1);
+ g_return_val_if_fail (b && b->name, 1);
+ return g_ascii_strcasecmp (a->name, b->name);
+}
+
+static void skin_free_func (void * _data)
+{
+ SkinNode * data = (SkinNode *) _data;
+ g_return_if_fail(data != nullptr);
+ g_free (data->name);
+ g_free (data->path);
+ g_slice_free(SkinNode, data);
+}
+
+
+static void
+skinlist_clear(void)
+{
+ if (!skinlist)
+ return;
+
+ g_list_foreach(skinlist, (GFunc) skin_free_func, nullptr);
+ g_list_free(skinlist);
+ skinlist = nullptr;
+}
+
+static void
+skinlist_update(void)
+{
+ char *skinsdir;
+
+ skinlist_clear();
+
+ if (g_file_test (skins_paths[SKINS_PATH_USER_SKIN_DIR], G_FILE_TEST_EXISTS))
+ scan_skindir (skins_paths[SKINS_PATH_USER_SKIN_DIR]);
+
+ char * path = g_strdup_printf ("%s/Skins", aud_get_path (AudPath::DataDir));
+ scan_skindir (path);
+ g_free (path);
+
+ skinsdir = getenv("SKINSDIR");
+ if (skinsdir) {
+ char **dir_list = g_strsplit(skinsdir, ":", 0);
+ char **dir;
+
+ for (dir = dir_list; *dir; dir++)
+ scan_skindir(*dir);
+ g_strfreev(dir_list);
+ }
+
+ skinlist = g_list_sort(skinlist, skinlist_compare_func);
+
+ g_assert(skinlist != nullptr);
+}
+
+void skin_view_update (GtkTreeView * treeview)
+{
+ GtkTreeSelection *selection = nullptr;
+ GtkListStore *store;
+ GtkTreeIter iter, iter_current_skin;
+ gboolean have_current_skin = FALSE;
+ GtkTreePath *path;
+
+ GdkPixbuf *thumbnail;
+ char *formattedname;
+ char *name;
+ GList *entry;
+
+ g_signal_handlers_block_by_func (treeview, (void *) skin_view_on_cursor_changed, nullptr);
+
+ store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
+
+ gtk_list_store_clear(store);
+
+ skinlist_update();
+
+ for (entry = skinlist; entry; entry = entry->next)
+ {
+ SkinNode * node = (SkinNode *) entry->data;
+
+ thumbnail = skin_get_thumbnail (node->path);
+ formattedname = g_strdup_printf ("<big><b>%s</b></big>\n<i>%s</i>",
+ node->name, node->desc);
+ name = node->name;
+
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ SKIN_VIEW_COL_PREVIEW, thumbnail,
+ SKIN_VIEW_COL_FORMATTEDNAME, formattedname,
+ SKIN_VIEW_COL_NAME, name, -1);
+ if (thumbnail)
+ g_object_unref(thumbnail);
+ g_free(formattedname);
+
+ if (g_strstr_len(active_skin->path,
+ strlen(active_skin->path), name) ) {
+ iter_current_skin = iter;
+ have_current_skin = TRUE;
+ }
+ }
+
+ if (have_current_skin) {
+ selection = gtk_tree_view_get_selection(treeview);
+ gtk_tree_selection_select_iter(selection, &iter_current_skin);
+
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(store),
+ &iter_current_skin);
+ gtk_tree_view_scroll_to_cell(treeview, path, nullptr, TRUE, 0.5, 0.5);
+ gtk_tree_path_free(path);
+ }
+
+ g_signal_handlers_unblock_by_func (treeview, (void *) skin_view_on_cursor_changed, nullptr);
+}
+
+
+static void
+skin_view_on_cursor_changed(GtkTreeView * treeview,
+ void * data)
+{
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+
+ GList *node;
+ char *name;
+ char *comp = nullptr;
+
+ selection = gtk_tree_view_get_selection(treeview);
+
+ if (!gtk_tree_selection_get_selected(selection, &model, &iter))
+ return;
+
+ gtk_tree_model_get(model, &iter, SKIN_VIEW_COL_NAME, &name, -1);
+
+ for (node = skinlist; node; node = g_list_next(node)) {
+ comp = ((SkinNode *) node->data)->path;
+ if (g_strrstr(comp, name))
+ break;
+ }
+
+ g_free(name);
+
+ active_skin_load (comp);
+}
+
+
+void
+skin_view_realize(GtkTreeView * treeview)
+{
+ GtkListStore *store;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ GtkTreeSelection *selection;
+
+ gtk_widget_show_all(GTK_WIDGET(treeview));
+
+ gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
+
+ store = gtk_list_store_new(SKIN_VIEW_N_COLS, GDK_TYPE_PIXBUF,
+ G_TYPE_STRING , G_TYPE_STRING);
+ gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store));
+ g_object_unref (store);
+
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+ gtk_tree_view_column_set_spacing(column, 16);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview),
+ GTK_TREE_VIEW_COLUMN(column));
+
+ renderer = gtk_cell_renderer_pixbuf_new();
+ gtk_tree_view_column_pack_start(column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes(column, renderer, "pixbuf",
+ SKIN_VIEW_COL_PREVIEW, nullptr);
+
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(column, renderer, TRUE);
+ gtk_tree_view_column_set_attributes(column, renderer, "markup",
+ SKIN_VIEW_COL_FORMATTEDNAME, nullptr);
+
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
+
+ g_signal_connect(treeview, "cursor-changed",
+ G_CALLBACK(skin_view_on_cursor_changed), nullptr);
+}
diff --git a/src/skins/ui_svis.c b/src/skins/ui_svis.c
deleted file mode 100644
index 02a80f41805f..000000000000
--- a/src/skins/ui_svis.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007-2011 Audacious development team.
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <string.h>
-
-#include "draw-compat.h"
-#include "skins_cfg.h"
-#include "surface.h"
-#include "ui_skin.h"
-#include "ui_vis.h"
-
-static gint svis_analyzer_colors[] = {14, 11, 8, 5, 2};
-static gint svis_scope_colors[] = {20, 19, 18, 19, 20};
-static gint svis_vu_normal_colors[] = {16, 14, 12, 10, 8, 6, 4, 2};
-
-static struct {
- gboolean active;
- gint data[75];
-} svis;
-
-#define RGB_SEEK(x,y) (set = rgb + 38 * (y) + (x))
-#define RGB_SET(c) (* set ++ = (c))
-#define RGB_SET_Y(c) do {* set = (c); set += 38;} while (0)
-#define RGB_SET_INDEX(c) RGB_SET (active_skin->vis_colors[c])
-#define RGB_SET_INDEX_Y(c) RGB_SET_Y (active_skin->vis_colors[c])
-
-DRAW_FUNC_BEGIN (ui_svis_draw)
- guint32 rgb[38 * 5];
- guint32 * set;
-
- RGB_SEEK (0, 0);
- for (gint x = 0; x < 38 * 5; x ++)
- RGB_SET_INDEX (0);
-
- switch (config.vis_type)
- {
- case VIS_ANALYZER:;
- gboolean bars = (config.analyzer_type == ANALYZER_BARS);
-
- for (gint x = 0; x < 38; x ++)
- {
- if (bars && (x % 3) == 2)
- continue;
-
- gint h = svis.data[bars ? (x / 3) : x];
- h = CLAMP (h, 0, 5);
- RGB_SEEK (x, 5 - h);
-
- for (gint y = 0; y < h; y ++)
- RGB_SET_INDEX_Y (svis_analyzer_colors[h - 1 - y]);
- }
-
- break;
- case VIS_VOICEPRINT:
- switch (config.vu_mode)
- {
- case VU_NORMAL:
- for (gint y = 0; y < 5; y ++)
- {
- if (y == 2)
- continue;
-
- gint h = (svis.data[y / 3] * 8 + 19) / 38;
- h = CLAMP (h, 0, 8);
- RGB_SEEK (0, y);
-
- for (gint x = 0; x < h; x ++)
- {
- RGB_SET_INDEX (svis_vu_normal_colors[x]);
- RGB_SET_INDEX (svis_vu_normal_colors[x]);
- RGB_SET_INDEX (svis_vu_normal_colors[x]);
- set += 2;
- }
- }
- break;
- default: /* VU_SMOOTH */
- for (gint y = 0; y < 5; y ++)
- {
- if (y == 2)
- continue;
-
- gint h = svis.data[y / 3];
- h = CLAMP (h, 0, 38);
- RGB_SEEK (0, y);
-
- for (gint x = 0; x < h; x ++)
- RGB_SET_INDEX (17 - (x * 16) / 38);
- }
- break;
- }
- break;
- case VIS_SCOPE:;
- static const gint scale[17] = {0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 3, 4,
- 4, 4, 4, 4, 4};
-
- if (! svis.active)
- goto DRAW;
-
- switch (config.scope_mode)
- {
- case SCOPE_DOT:
- for (gint x = 0; x < 38; x ++)
- {
- gint h = scale[CLAMP (svis.data[2 * x], 0, 16)];
- RGB_SEEK (x, h);
- RGB_SET_INDEX (svis_scope_colors[h]);
- }
- break;
- case SCOPE_LINE:
- for (gint x = 0; x < 37; x++)
- {
- gint h = scale[CLAMP (svis.data[2 * x], 0, 16)];
- gint h2 = scale[CLAMP (svis.data[2 * (x + 1)], 0, 16)];
-
- if (h < h2) h2 --;
- else if (h > h2) {gint temp = h; h = h2 + 1; h2 = temp;}
-
- RGB_SEEK (x, h);
- for (gint y = h; y <= h2; y ++)
- RGB_SET_INDEX_Y (svis_scope_colors[y]);
- }
-
- gint h = scale[CLAMP (svis.data[74], 0, 16)];
- RGB_SEEK (37, h);
- RGB_SET_INDEX (svis_scope_colors[h]);
- break;
- default: /* SCOPE_SOLID */
- for (gint x = 0; x < 38; x++)
- {
- gint h = scale[CLAMP (svis.data[2 * x], 0, 16)];
- gint h2;
-
- if (h < 2) h2 = 2;
- else {h2 = h; h = 2;}
-
- RGB_SEEK (x, h);
- for (gint y = h; y <= h2; y ++)
- RGB_SET_INDEX_Y (svis_scope_colors[y]);
- }
- break;
- }
- break;
- }
-
-DRAW:;
- cairo_surface_t * surf = cairo_image_surface_create_for_data ((void *) rgb,
- CAIRO_FORMAT_RGB24, 38, 5, 4 * 38);
- cairo_set_source_surface (cr, surf, 0, 0);
- cairo_paint (cr);
- cairo_surface_destroy (surf);
-DRAW_FUNC_END
-
-GtkWidget * ui_svis_new (void)
-{
- GtkWidget * wid = gtk_drawing_area_new ();
- gtk_widget_set_size_request (wid, 38, 5);
- gtk_widget_add_events (wid, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
- DRAW_CONNECT (wid, ui_svis_draw);
- return wid;
-}
-
-void ui_svis_clear_data (GtkWidget * widget)
-{
- memset (& svis, 0, sizeof svis);
- gtk_widget_queue_draw (widget);
-}
-
-void ui_svis_timeout_func (GtkWidget * widget, guchar * data)
-{
- if (config.vis_type == VIS_VOICEPRINT)
- {
- for (gint i = 0; i < 2; i ++)
- svis.data[i] = data[i];
- }
- else
- {
- for (gint i = 0; i < 75; i ++)
- svis.data[i] = data[i];
- }
-
- svis.active = TRUE;
- gtk_widget_queue_draw (widget);
-}
diff --git a/src/skins/ui_svis.cc b/src/skins/ui_svis.cc
new file mode 100644
index 000000000000..a5af1ca219c8
--- /dev/null
+++ b/src/skins/ui_svis.cc
@@ -0,0 +1,215 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007-2011 Audacious development team.
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <string.h>
+#include <libaudcore/objects.h>
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "surface.h"
+#include "ui_skin.h"
+#include "ui_vis.h"
+
+static int svis_analyzer_colors[] = {14, 11, 8, 5, 2};
+static int svis_scope_colors[] = {20, 19, 18, 19, 20};
+static int svis_vu_normal_colors[] = {16, 14, 12, 10, 8, 6, 4, 2};
+
+static struct {
+ gboolean active;
+ int data[75];
+} svis;
+
+#define RGB_SEEK(x,y) (set = rgb + 38 * (y) + (x))
+#define RGB_SET(c) (* set ++ = (c))
+#define RGB_SET_Y(c) do {* set = (c); set += 38;} while (0)
+#define RGB_SET_INDEX(c) RGB_SET (active_skin->vis_colors[c])
+#define RGB_SET_INDEX_Y(c) RGB_SET_Y (active_skin->vis_colors[c])
+
+DRAW_FUNC_BEGIN (ui_svis_draw)
+ uint32_t rgb[38 * 5];
+ uint32_t * set;
+
+ RGB_SEEK (0, 0);
+ for (int x = 0; x < 38 * 5; x ++)
+ RGB_SET_INDEX (0);
+
+ switch (config.vis_type)
+ {
+ case VIS_ANALYZER:
+ {
+ gboolean bars = (config.analyzer_type == ANALYZER_BARS);
+
+ for (int x = 0; x < 38; x ++)
+ {
+ if (bars && (x % 3) == 2)
+ continue;
+
+ int h = svis.data[bars ? (x / 3) : x];
+ h = aud::clamp (h, 0, 5);
+ RGB_SEEK (x, 5 - h);
+
+ for (int y = 0; y < h; y ++)
+ RGB_SET_INDEX_Y (svis_analyzer_colors[h - 1 - y]);
+ }
+
+ break;
+ }
+ case VIS_VOICEPRINT:
+ switch (config.vu_mode)
+ {
+ case VU_NORMAL:
+ for (int y = 0; y < 5; y ++)
+ {
+ if (y == 2)
+ continue;
+
+ int h = (svis.data[y / 3] * 8 + 19) / 38;
+ h = aud::clamp (h, 0, 8);
+ RGB_SEEK (0, y);
+
+ for (int x = 0; x < h; x ++)
+ {
+ RGB_SET_INDEX (svis_vu_normal_colors[x]);
+ RGB_SET_INDEX (svis_vu_normal_colors[x]);
+ RGB_SET_INDEX (svis_vu_normal_colors[x]);
+ set += 2;
+ }
+ }
+ break;
+ default: /* VU_SMOOTH */
+ for (int y = 0; y < 5; y ++)
+ {
+ if (y == 2)
+ continue;
+
+ int h = svis.data[y / 3];
+ h = aud::clamp (h, 0, 38);
+ RGB_SEEK (0, y);
+
+ for (int x = 0; x < h; x ++)
+ RGB_SET_INDEX (17 - (x * 16) / 38);
+ }
+ break;
+ }
+ break;
+ case VIS_SCOPE:
+ {
+ static const int scale[17] = {0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 3, 4,
+ 4, 4, 4, 4, 4};
+
+ if (! svis.active)
+ goto DRAW;
+
+ switch (config.scope_mode)
+ {
+ case SCOPE_DOT:
+ for (int x = 0; x < 38; x ++)
+ {
+ int h = scale[aud::clamp (svis.data[2 * x], 0, 16)];
+ RGB_SEEK (x, h);
+ RGB_SET_INDEX (svis_scope_colors[h]);
+ }
+ break;
+ case SCOPE_LINE:
+ {
+ for (int x = 0; x < 37; x++)
+ {
+ int h = scale[aud::clamp (svis.data[2 * x], 0, 16)];
+ int h2 = scale[aud::clamp (svis.data[2 * (x + 1)], 0, 16)];
+
+ if (h < h2) h2 --;
+ else if (h > h2) {int temp = h; h = h2 + 1; h2 = temp;}
+
+ RGB_SEEK (x, h);
+ for (int y = h; y <= h2; y ++)
+ RGB_SET_INDEX_Y (svis_scope_colors[y]);
+ }
+
+ int h = scale[aud::clamp (svis.data[74], 0, 16)];
+ RGB_SEEK (37, h);
+ RGB_SET_INDEX (svis_scope_colors[h]);
+ break;
+ }
+ default: /* SCOPE_SOLID */
+ for (int x = 0; x < 38; x++)
+ {
+ int h = scale[aud::clamp (svis.data[2 * x], 0, 16)];
+ int h2;
+
+ if (h < 2) h2 = 2;
+ else {h2 = h; h = 2;}
+
+ RGB_SEEK (x, h);
+ for (int y = h; y <= h2; y ++)
+ RGB_SET_INDEX_Y (svis_scope_colors[y]);
+ }
+ break;
+ }
+ break;
+ }
+ }
+
+DRAW:;
+ cairo_surface_t * surf = cairo_image_surface_create_for_data
+ ((unsigned char *) rgb, CAIRO_FORMAT_RGB24, 38, 5, 4 * 38);
+ cairo_scale (cr, config.scale, config.scale);
+ cairo_set_source_surface (cr, surf, 0, 0);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint (cr);
+ cairo_surface_destroy (surf);
+DRAW_FUNC_END
+
+GtkWidget * ui_svis_new (void)
+{
+ GtkWidget * wid = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (wid, 38 * config.scale, 5 * config.scale);
+ gtk_widget_add_events (wid, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+ DRAW_CONNECT (wid, ui_svis_draw);
+ return wid;
+}
+
+void ui_svis_clear_data (GtkWidget * widget)
+{
+ memset (& svis, 0, sizeof svis);
+ gtk_widget_queue_draw (widget);
+}
+
+void ui_svis_timeout_func (GtkWidget * widget, unsigned char * data)
+{
+ if (config.vis_type == VIS_VOICEPRINT)
+ {
+ for (int i = 0; i < 2; i ++)
+ svis.data[i] = data[i];
+ }
+ else
+ {
+ for (int i = 0; i < 75; i ++)
+ svis.data[i] = data[i];
+ }
+
+ svis.active = TRUE;
+ gtk_widget_queue_draw (widget);
+}
diff --git a/src/skins/ui_vis.c b/src/skins/ui_vis.c
deleted file mode 100644
index d2138ac789ec..000000000000
--- a/src/skins/ui_vis.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007-2011 Audacious development team.
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004 BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <string.h>
-
-#include "draw-compat.h"
-#include "skins_cfg.h"
-#include "surface.h"
-#include "ui_skin.h"
-#include "ui_vis.h"
-
-static const gfloat vis_afalloff_speeds[] = {0.34, 0.5, 1.0, 1.3, 1.6};
-static const gfloat vis_pfalloff_speeds[] = {1.2, 1.3, 1.4, 1.5, 1.6};
-static const gint vis_scope_colors[16] = {22, 22, 21, 21, 20, 10, 19, 19, 18,
- 19, 19, 20, 20, 21, 21, 22};
-
-static guint32 vis_voice_color[256];
-static guint32 vis_voice_color_fire[256];
-static guint32 vis_voice_color_ice[256];
-static guint32 pattern_fill[76 * 2];
-
-static struct {
- gboolean active;
- gfloat data[75], peak[75], peak_speed[75];
- guchar voiceprint_data[76 * 16];
- gboolean voiceprint_advance;
-} vis;
-
-#define RGB_SEEK(x,y) (set = rgb + 76 * (y) + (x))
-#define RGB_SET(c) (* set ++ = (c))
-#define RGB_SET_Y(c) do {* set = (c); set += 76;} while (0)
-#define RGB_SET_INDEX(c) RGB_SET (active_skin->vis_colors[c])
-#define RGB_SET_INDEX_Y(c) RGB_SET_Y (active_skin->vis_colors[c])
-
-void ui_vis_set_colors (void)
-{
- g_return_if_fail (active_skin != NULL);
-
- guint32 fgc = active_skin->colors[SKIN_TEXTFG];
- guint32 bgc = active_skin->colors[SKIN_TEXTBG];
- gint fg[3] = {COLOR_R (fgc), COLOR_G (fgc), COLOR_B (fgc)};
- gint bg[3] = {COLOR_R (bgc), COLOR_G (bgc), COLOR_B (bgc)};
-
- for (gint x = 0; x < 256; x ++)
- {
- guchar c[3];
- for (gint n = 0; n < 3; n ++)
- c[n] = bg[n] + (fg[n] - bg[n]) * x / 255;
- vis_voice_color[x] = COLOR (c[0], c[1], c[2]);
- }
-
- for (gint x = 0; x < 256; x ++)
- {
- guchar r = MIN (x, 127) * 2;
- guchar g = CLAMP (x - 64, 0, 127) * 2;
- guchar b = MAX (x - 128, 0) * 2;
- vis_voice_color_fire[x] = COLOR (r, g, b);
- }
-
- for (gint x = 0; x < 256; x ++)
- vis_voice_color_ice[x] = COLOR (x / 2, x, MIN (x * 2, 255));
-
- guint32 * set = pattern_fill;
- guint32 * end = set + 76;
-
- while (set < end)
- RGB_SET_INDEX (0);
-
- end = set + 76;
-
- while (set < end)
- {
- RGB_SET_INDEX (1);
- RGB_SET_INDEX (0);
- }
-}
-
-DRAW_FUNC_BEGIN (ui_vis_draw)
- guint32 rgb[76 * 16];
- guint32 * set;
-
- if (config.vis_type != VIS_VOICEPRINT)
- {
- for (set = rgb; set < rgb + 76 * 16; set += 76 * 2)
- memcpy (set, pattern_fill, sizeof pattern_fill);
- }
-
- switch (config.vis_type)
- {
- case VIS_ANALYZER:;
- gboolean bars = (config.analyzer_type == ANALYZER_BARS);
-
- for (gint x = 0; x < 75; x ++)
- {
- if (bars && (x & 3) == 3)
- continue;
-
- gint h = vis.data[bars ? (x >> 2) : x];
- h = CLAMP (h, 0, 16);
- RGB_SEEK (x, 16 - h);
-
- switch (config.analyzer_mode)
- {
- case ANALYZER_NORMAL:
- for (gint y = 0; y < h; y ++)
- RGB_SET_INDEX_Y (18 - h + y);
- break;
- case ANALYZER_FIRE:
- for (gint y = 0; y < h; y ++)
- RGB_SET_INDEX_Y (2 + y);
- break;
- default: /* ANALYZER_VLINES */
- for (gint y = 0; y < h; y ++)
- RGB_SET_INDEX_Y (18 - h);
- break;
- }
-
- if (config.analyzer_peaks)
- {
- gint h = vis.peak[bars ? (x >> 2) : x];
- h = CLAMP (h, 0, 16);
-
- if (h)
- {
- RGB_SEEK (x, 16 - h);
- RGB_SET_INDEX (23);
- }
- }
- }
-
- break;
- case VIS_VOICEPRINT:
- if (vis.voiceprint_advance)
- {
- vis.voiceprint_advance = FALSE;
- memmove (vis.voiceprint_data, vis.voiceprint_data + 1, sizeof
- vis.voiceprint_data - 1);
-
- for (gint y = 0; y < 16; y ++)
- vis.voiceprint_data[76 * y + 75] = vis.data[y];
- }
-
- guchar * get = vis.voiceprint_data;
- guint32 * colors = (config.voiceprint_mode == VOICEPRINT_NORMAL) ?
- vis_voice_color : (config.voiceprint_mode == VOICEPRINT_FIRE) ?
- vis_voice_color_fire : /* VOICEPRINT_ICE */ vis_voice_color_ice;
- set = rgb;
-
- for (gint y = 0; y < 16; y ++)
- for (gint x = 0; x < 76; x ++)
- RGB_SET (colors[* get ++]);
- break;
- case VIS_SCOPE:
- if (! vis.active)
- goto DRAW;
-
- switch (config.scope_mode)
- {
- case SCOPE_DOT:
- for (gint x = 0; x < 75; x ++)
- {
- gint h = CLAMP (vis.data[x], 0, 15);
- RGB_SEEK (x, h);
- RGB_SET_INDEX (vis_scope_colors[h]);
- }
- break;
- case SCOPE_LINE:
- for (gint x = 0; x < 74; x++)
- {
- gint h = CLAMP (vis.data[x], 0, 15);
- gint h2 = CLAMP (vis.data[x + 1], 0, 15);
-
- if (h < h2) h2 --;
- else if (h > h2) {gint temp = h; h = h2 + 1; h2 = temp;}
-
- RGB_SEEK (x, h);
-
- for (gint y = h; y <= h2; y ++)
- RGB_SET_INDEX_Y (vis_scope_colors[y]);
- }
-
- gint h = CLAMP (vis.data[74], 0, 15);
- RGB_SEEK (74, h);
- RGB_SET_INDEX (vis_scope_colors[h]);
- break;
- default: /* SCOPE_SOLID */
- for (gint x = 0; x < 75; x++)
- {
- gint h = CLAMP (vis.data[x], 0, 15);
- gint h2;
-
- if (h < 8) h2 = 8;
- else {h2 = h; h = 8;}
-
- RGB_SEEK (x, h);
-
- for (gint y = h; y <= h2; y ++)
- RGB_SET_INDEX_Y (vis_scope_colors[y]);
- }
- break;
- }
- break;
- }
-
-DRAW:;
- cairo_surface_t * surf = cairo_image_surface_create_for_data ((void *) rgb,
- CAIRO_FORMAT_RGB24, 76, 16, 4 * 76);
- cairo_set_source_surface (cr, surf, 0, 0);
- cairo_paint (cr);
- cairo_surface_destroy (surf);
-DRAW_FUNC_END
-
-GtkWidget * ui_vis_new (void)
-{
- GtkWidget * wid = gtk_drawing_area_new ();
- gtk_widget_set_size_request (wid, 76, 16);
- gtk_widget_add_events (wid, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
- DRAW_CONNECT (wid, ui_vis_draw);
- return wid;
-}
-
-void ui_vis_clear_data (GtkWidget * wid)
-{
- memset (& vis, 0, sizeof vis);
- gtk_widget_queue_draw (wid);
-}
-
-void ui_vis_timeout_func (GtkWidget * widget, guchar * data)
-{
- if (config.vis_type == VIS_ANALYZER)
- {
- const gint n = (config.analyzer_type == ANALYZER_BARS) ? 19 : 75;
-
- for (gint i = 0; i < n; i++)
- {
- if (data[i] > vis.data[i])
- {
- vis.data[i] = data[i];
- if (vis.data[i] > vis.peak[i])
- {
- vis.peak[i] = vis.data[i];
- vis.peak_speed[i] = 0.01;
-
- }
- else if (vis.peak[i] > 0.0)
- {
- vis.peak[i] -= vis.peak_speed[i];
- vis.peak_speed[i] *=
- vis_pfalloff_speeds[config.peaks_falloff];
- if (vis.peak[i] < vis.data[i])
- vis.peak[i] = vis.data[i];
- if (vis.peak[i] < 0.0)
- vis.peak[i] = 0.0;
- }
- }
- else
- {
- if (vis.data[i] > 0.0)
- {
- vis.data[i] -=
- vis_afalloff_speeds[config.analyzer_falloff];
- if (vis.data[i] < 0.0)
- vis.data[i] = 0.0;
- }
- if (vis.peak[i] > 0.0)
- {
- vis.peak[i] -= vis.peak_speed[i];
- vis.peak_speed[i] *=
- vis_pfalloff_speeds[config.peaks_falloff];
- if (vis.peak[i] < vis.data[i])
- vis.peak[i] = vis.data[i];
- if (vis.peak[i] < 0.0)
- vis.peak[i] = 0.0;
- }
- }
- }
- }
- else if (config.vis_type == VIS_VOICEPRINT)
- {
- for (gint i = 0; i < 16; i++)
- vis.data[i] = data[15 - i];
-
- vis.voiceprint_advance = TRUE;
- }
- else
- {
- for (gint i = 0; i < 75; i++)
- vis.data[i] = data[i];
- }
-
- vis.active = TRUE;
- gtk_widget_queue_draw (widget);
-}
diff --git a/src/skins/ui_vis.cc b/src/skins/ui_vis.cc
new file mode 100644
index 000000000000..c5c3ee3b5109
--- /dev/null
+++ b/src/skins/ui_vis.cc
@@ -0,0 +1,325 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007-2011 Audacious development team.
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004 BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <string.h>
+#include <libaudcore/objects.h>
+
+#include "draw-compat.h"
+#include "skins_cfg.h"
+#include "surface.h"
+#include "ui_skin.h"
+#include "ui_vis.h"
+
+static const float vis_afalloff_speeds[] = {0.34, 0.5, 1.0, 1.3, 1.6};
+static const float vis_pfalloff_speeds[] = {1.2, 1.3, 1.4, 1.5, 1.6};
+static const int vis_scope_colors[16] = {22, 22, 21, 21, 20, 10, 19, 19, 18,
+ 19, 19, 20, 20, 21, 21, 22};
+
+static uint32_t vis_voice_color[256];
+static uint32_t vis_voice_color_fire[256];
+static uint32_t vis_voice_color_ice[256];
+static uint32_t pattern_fill[76 * 2];
+
+static struct {
+ gboolean active;
+ float data[75], peak[75], peak_speed[75];
+ unsigned char voiceprint_data[76 * 16];
+ gboolean voiceprint_advance;
+} vis;
+
+#define RGB_SEEK(x,y) (set = rgb + 76 * (y) + (x))
+#define RGB_SET(c) (* set ++ = (c))
+#define RGB_SET_Y(c) do {* set = (c); set += 76;} while (0)
+#define RGB_SET_INDEX(c) RGB_SET (active_skin->vis_colors[c])
+#define RGB_SET_INDEX_Y(c) RGB_SET_Y (active_skin->vis_colors[c])
+
+void ui_vis_set_colors (void)
+{
+ g_return_if_fail (active_skin != nullptr);
+
+ uint32_t fgc = active_skin->colors[SKIN_TEXTFG];
+ uint32_t bgc = active_skin->colors[SKIN_TEXTBG];
+ int fg[3] = {COLOR_R (fgc), COLOR_G (fgc), COLOR_B (fgc)};
+ int bg[3] = {COLOR_R (bgc), COLOR_G (bgc), COLOR_B (bgc)};
+
+ for (int x = 0; x < 256; x ++)
+ {
+ unsigned char c[3];
+ for (int n = 0; n < 3; n ++)
+ c[n] = bg[n] + (fg[n] - bg[n]) * x / 255;
+ vis_voice_color[x] = COLOR (c[0], c[1], c[2]);
+ }
+
+ for (int x = 0; x < 256; x ++)
+ {
+ unsigned char r = aud::min (x, 127) * 2;
+ unsigned char g = aud::clamp (x - 64, 0, 127) * 2;
+ unsigned char b = aud::max (x - 128, 0) * 2;
+ vis_voice_color_fire[x] = COLOR (r, g, b);
+ }
+
+ for (int x = 0; x < 256; x ++)
+ vis_voice_color_ice[x] = COLOR (x / 2, x, aud::min (x * 2, 255));
+
+ uint32_t * set = pattern_fill;
+ uint32_t * end = set + 76;
+
+ while (set < end)
+ RGB_SET_INDEX (0);
+
+ end = set + 76;
+
+ while (set < end)
+ {
+ RGB_SET_INDEX (1);
+ RGB_SET_INDEX (0);
+ }
+}
+
+DRAW_FUNC_BEGIN (ui_vis_draw)
+ uint32_t rgb[76 * 16];
+ uint32_t * set;
+
+ if (config.vis_type != VIS_VOICEPRINT)
+ {
+ for (set = rgb; set < rgb + 76 * 16; set += 76 * 2)
+ memcpy (set, pattern_fill, sizeof pattern_fill);
+ }
+
+ switch (config.vis_type)
+ {
+ case VIS_ANALYZER:
+ {
+ gboolean bars = (config.analyzer_type == ANALYZER_BARS);
+
+ for (int x = 0; x < 75; x ++)
+ {
+ if (bars && (x & 3) == 3)
+ continue;
+
+ int h = vis.data[bars ? (x >> 2) : x];
+ h = aud::clamp (h, 0, 16);
+ RGB_SEEK (x, 16 - h);
+
+ switch (config.analyzer_mode)
+ {
+ case ANALYZER_NORMAL:
+ for (int y = 0; y < h; y ++)
+ RGB_SET_INDEX_Y (18 - h + y);
+ break;
+ case ANALYZER_FIRE:
+ for (int y = 0; y < h; y ++)
+ RGB_SET_INDEX_Y (2 + y);
+ break;
+ default: /* ANALYZER_VLINES */
+ for (int y = 0; y < h; y ++)
+ RGB_SET_INDEX_Y (18 - h);
+ break;
+ }
+
+ if (config.analyzer_peaks)
+ {
+ int h = vis.peak[bars ? (x >> 2) : x];
+ h = aud::clamp (h, 0, 16);
+
+ if (h)
+ {
+ RGB_SEEK (x, 16 - h);
+ RGB_SET_INDEX (23);
+ }
+ }
+ }
+
+ break;
+ }
+ case VIS_VOICEPRINT:
+ {
+ if (vis.voiceprint_advance)
+ {
+ vis.voiceprint_advance = FALSE;
+ memmove (vis.voiceprint_data, vis.voiceprint_data + 1, sizeof
+ vis.voiceprint_data - 1);
+
+ for (int y = 0; y < 16; y ++)
+ vis.voiceprint_data[76 * y + 75] = vis.data[y];
+ }
+
+ unsigned char * get = vis.voiceprint_data;
+ uint32_t * colors = (config.voiceprint_mode == VOICEPRINT_NORMAL) ?
+ vis_voice_color : (config.voiceprint_mode == VOICEPRINT_FIRE) ?
+ vis_voice_color_fire : /* VOICEPRINT_ICE */ vis_voice_color_ice;
+ set = rgb;
+
+ for (int y = 0; y < 16; y ++)
+ for (int x = 0; x < 76; x ++)
+ RGB_SET (colors[* get ++]);
+ break;
+ }
+ case VIS_SCOPE:
+ if (! vis.active)
+ goto DRAW;
+
+ switch (config.scope_mode)
+ {
+ case SCOPE_DOT:
+ for (int x = 0; x < 75; x ++)
+ {
+ int h = aud::clamp ((int) vis.data[x], 0, 15);
+ RGB_SEEK (x, h);
+ RGB_SET_INDEX (vis_scope_colors[h]);
+ }
+ break;
+ case SCOPE_LINE:
+ {
+ for (int x = 0; x < 74; x++)
+ {
+ int h = aud::clamp ((int) vis.data[x], 0, 15);
+ int h2 = aud::clamp ((int) vis.data[x + 1], 0, 15);
+
+ if (h < h2) h2 --;
+ else if (h > h2) {int temp = h; h = h2 + 1; h2 = temp;}
+
+ RGB_SEEK (x, h);
+
+ for (int y = h; y <= h2; y ++)
+ RGB_SET_INDEX_Y (vis_scope_colors[y]);
+ }
+
+ int h = aud::clamp ((int) vis.data[74], 0, 15);
+ RGB_SEEK (74, h);
+ RGB_SET_INDEX (vis_scope_colors[h]);
+ break;
+ }
+ default: /* SCOPE_SOLID */
+ for (int x = 0; x < 75; x++)
+ {
+ int h = aud::clamp ((int) vis.data[x], 0, 15);
+ int h2;
+
+ if (h < 8) h2 = 8;
+ else {h2 = h; h = 8;}
+
+ RGB_SEEK (x, h);
+
+ for (int y = h; y <= h2; y ++)
+ RGB_SET_INDEX_Y (vis_scope_colors[y]);
+ }
+ break;
+ }
+ break;
+ }
+
+DRAW:;
+ cairo_surface_t * surf = cairo_image_surface_create_for_data
+ ((unsigned char *) rgb, CAIRO_FORMAT_RGB24, 76, 16, 4 * 76);
+ cairo_scale (cr, config.scale, config.scale);
+ cairo_set_source_surface (cr, surf, 0, 0);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint (cr);
+ cairo_surface_destroy (surf);
+DRAW_FUNC_END
+
+GtkWidget * ui_vis_new (void)
+{
+ GtkWidget * wid = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (wid, 76 * config.scale, 16 * config.scale);
+ gtk_widget_add_events (wid, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+ DRAW_CONNECT (wid, ui_vis_draw);
+ return wid;
+}
+
+void ui_vis_clear_data (GtkWidget * wid)
+{
+ memset (& vis, 0, sizeof vis);
+ gtk_widget_queue_draw (wid);
+}
+
+void ui_vis_timeout_func (GtkWidget * widget, unsigned char * data)
+{
+ if (config.vis_type == VIS_ANALYZER)
+ {
+ const int n = (config.analyzer_type == ANALYZER_BARS) ? 19 : 75;
+
+ for (int i = 0; i < n; i++)
+ {
+ if (data[i] > vis.data[i])
+ {
+ vis.data[i] = data[i];
+ if (vis.data[i] > vis.peak[i])
+ {
+ vis.peak[i] = vis.data[i];
+ vis.peak_speed[i] = 0.01;
+
+ }
+ else if (vis.peak[i] > 0.0)
+ {
+ vis.peak[i] -= vis.peak_speed[i];
+ vis.peak_speed[i] *=
+ vis_pfalloff_speeds[config.peaks_falloff];
+ if (vis.peak[i] < vis.data[i])
+ vis.peak[i] = vis.data[i];
+ if (vis.peak[i] < 0.0)
+ vis.peak[i] = 0.0;
+ }
+ }
+ else
+ {
+ if (vis.data[i] > 0.0)
+ {
+ vis.data[i] -=
+ vis_afalloff_speeds[config.analyzer_falloff];
+ if (vis.data[i] < 0.0)
+ vis.data[i] = 0.0;
+ }
+ if (vis.peak[i] > 0.0)
+ {
+ vis.peak[i] -= vis.peak_speed[i];
+ vis.peak_speed[i] *=
+ vis_pfalloff_speeds[config.peaks_falloff];
+ if (vis.peak[i] < vis.data[i])
+ vis.peak[i] = vis.data[i];
+ if (vis.peak[i] < 0.0)
+ vis.peak[i] = 0.0;
+ }
+ }
+ }
+ }
+ else if (config.vis_type == VIS_VOICEPRINT)
+ {
+ for (int i = 0; i < 16; i++)
+ vis.data[i] = data[15 - i];
+
+ vis.voiceprint_advance = TRUE;
+ }
+ else
+ {
+ for (int i = 0; i < 75; i++)
+ vis.data[i] = data[i];
+ }
+
+ vis.active = TRUE;
+ gtk_widget_queue_draw (widget);
+}
diff --git a/src/skins/ui_vis.h b/src/skins/ui_vis.h
index 6850071d9c33..e3d753af96ad 100644
--- a/src/skins/ui_vis.h
+++ b/src/skins/ui_vis.h
@@ -54,10 +54,10 @@ typedef enum {
GtkWidget * ui_vis_new (void);
void ui_vis_set_colors (void);
void ui_vis_clear_data (GtkWidget * widget);
-void ui_vis_timeout_func (GtkWidget * widget, guchar * data);
+void ui_vis_timeout_func (GtkWidget * widget, unsigned char * data);
GtkWidget * ui_svis_new (void);
void ui_svis_clear_data (GtkWidget * widget);
-void ui_svis_timeout_func (GtkWidget * widget, guchar * data);
+void ui_svis_timeout_func (GtkWidget * widget, unsigned char * data);
#endif
diff --git a/src/skins/util.c b/src/skins/util.c
deleted file mode 100644
index 3295c0b33139..000000000000
--- a/src/skins/util.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/* Audacious - Cross-platform multimedia player
- * Copyright (C) 2005-2009 Audacious development team
- *
- * Based on BMP:
- * Copyright (C) 2003-2004 BMP development team.
- *
- * Based on XMMS:
- * Copyright (C) 1998-2003 XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <glib/gstdio.h>
-
-#include <audacious/debug.h>
-#include <audacious/i18n.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudcore/vfs.h>
-
-#include "util.h"
-
-typedef struct
-{
- const gchar *to_match;
- gchar *match;
- gboolean found;
-} FindFileContext;
-
-#ifndef HAVE_MKDTEMP
-static void make_directory(const gchar *path, mode_t mode);
-#endif
-
-gchar * find_file_case (const gchar * folder, const gchar * basename)
-{
- static GHashTable * cache = NULL;
- GList * list = NULL;
- void * vlist;
-
- if (cache == NULL)
- cache = g_hash_table_new (g_str_hash, g_str_equal);
-
- if (g_hash_table_lookup_extended (cache, folder, NULL, & vlist))
- list = vlist;
- else
- {
- GDir * handle = g_dir_open (folder, 0, NULL);
- if (! handle)
- return NULL;
-
- const char * name;
- while ((name = g_dir_read_name (handle)))
- list = g_list_prepend (list, g_strdup (name));
-
- g_hash_table_insert (cache, g_strdup (folder), list);
- g_dir_close (handle);
- }
-
- for (; list != NULL; list = list->next)
- {
- if (! g_ascii_strcasecmp (list->data, basename))
- return g_strdup (list->data);
- }
-
- return NULL;
-}
-
-gchar * find_file_case_path (const gchar * folder, const gchar * basename)
-{
- gchar * found, * path;
-
- if ((found = find_file_case (folder, basename)) == NULL)
- return NULL;
-
- path = g_strdup_printf ("%s/%s", folder, found);
- g_free (found);
- return path;
-}
-
-VFSFile * open_local_file_nocase (const char * folder, const char * basename)
-{
- char * path = find_file_case_path (folder, basename);
- if (! path)
- return NULL;
-
- char * uri = filename_to_uri (path);
- g_free (path);
-
- if (! uri)
- return NULL;
-
- VFSFile * file = vfs_fopen (uri, "r");
- str_unref (uri);
- return file;
-}
-
-gchar * text_parse_line (gchar * text)
-{
- gchar * newline = strchr (text, '\n');
-
- if (newline == NULL)
- return NULL;
-
- * newline = 0;
- return newline + 1;
-}
-
-typedef enum
-{
- ARCHIVE_UNKNOWN = 0,
- ARCHIVE_DIR,
- ARCHIVE_TAR,
- ARCHIVE_TGZ,
- ARCHIVE_ZIP,
- ARCHIVE_TBZ2
-} ArchiveType;
-
-typedef gchar *(*ArchiveExtractFunc) (const gchar *, const gchar *);
-
-typedef struct
-{
- ArchiveType type;
- const gchar *ext;
-} ArchiveExtensionType;
-
-static ArchiveExtensionType archive_extensions[] = {
- {ARCHIVE_TAR, ".tar"},
- {ARCHIVE_ZIP, ".wsz"},
- {ARCHIVE_ZIP, ".zip"},
- {ARCHIVE_TGZ, ".tar.gz"},
- {ARCHIVE_TGZ, ".tgz"},
- {ARCHIVE_TBZ2, ".tar.bz2"},
- {ARCHIVE_TBZ2, ".bz2"},
- {ARCHIVE_UNKNOWN, NULL}
-};
-
-static gchar *archive_extract_tar(const gchar *archive, const gchar *dest);
-static gchar *archive_extract_zip(const gchar *archive, const gchar *dest);
-static gchar *archive_extract_tgz(const gchar *archive, const gchar *dest);
-static gchar *archive_extract_tbz2(const gchar *archive, const gchar *dest);
-
-static ArchiveExtractFunc archive_extract_funcs[] = {
- NULL,
- NULL,
- archive_extract_tar,
- archive_extract_tgz,
- archive_extract_zip,
- archive_extract_tbz2
-};
-
-
-/* FIXME: these functions can be generalised into a function using a
- * command lookup table */
-
-static const gchar *get_tar_command(void)
-{
- static const gchar *command = NULL;
-
- if (!command)
- {
- if (!(command = getenv("TARCMD")))
- command = "tar";
- }
-
- return command;
-}
-
-static const gchar *get_unzip_command(void)
-{
- static const gchar *command = NULL;
-
- if (!command)
- {
- if (!(command = getenv("UNZIPCMD")))
- command = "unzip";
- }
-
- return command;
-}
-
-
-static gchar *archive_extract_tar(const gchar *archive, const gchar *dest)
-{
- return g_strdup_printf("%s >/dev/null xf \"%s\" -C %s", get_tar_command(),
- archive, dest);
-}
-
-static gchar *archive_extract_zip(const gchar *archive, const gchar *dest)
-{
- return g_strdup_printf("%s >/dev/null -o -j \"%s\" -d %s",
- get_unzip_command(), archive, dest);
-}
-
-static gchar *archive_extract_tgz(const gchar *archive, const gchar *dest)
-{
- return g_strdup_printf("%s >/dev/null xzf \"%s\" -C %s", get_tar_command(),
- archive, dest);
-}
-
-static gchar *archive_extract_tbz2(const gchar *archive, const gchar *dest)
-{
- return g_strdup_printf("bzip2 -dc \"%s\" | %s >/dev/null xf - -C %s",
- archive, get_tar_command(), dest);
-}
-
-
-static ArchiveType archive_get_type(const gchar *filename)
-{
- gint i = 0;
-
- if (g_file_test(filename, G_FILE_TEST_IS_DIR))
- return ARCHIVE_DIR;
-
- while (archive_extensions[i].ext)
- {
- if (g_str_has_suffix(filename, archive_extensions[i].ext))
- {
- return archive_extensions[i].type;
- }
- i++;
- }
-
- return ARCHIVE_UNKNOWN;
-}
-
-gboolean file_is_archive(const gchar *filename)
-{
- return (archive_get_type(filename) > ARCHIVE_DIR);
-}
-
-gchar *archive_basename(const gchar *str)
-{
- gint i = 0;
-
- while (archive_extensions[i].ext)
- {
- if (str_has_suffix_nocase(str, archive_extensions[i].ext))
- {
- const gchar *end = g_strrstr(str, archive_extensions[i].ext);
- if (end)
- {
- return g_strndup(str, end - str);
- }
- break;
- }
- i++;
- }
-
- return NULL;
-}
-
-/**
- * Escapes characters that are special to the shell inside double quotes.
- *
- * @param string String to be escaped.
- * @return Given string with special characters escaped. Must be freed with g_free().
- */
-static gchar *
-escape_shell_chars(const gchar * string)
-{
- const gchar *special = "$`\"\\"; /* Characters to escape */
- const gchar *in = string;
- gchar *out, *escaped;
- gint num = 0;
-
- while (*in != '\0')
- if (strchr(special, *in++))
- num++;
-
- escaped = g_malloc(strlen(string) + num + 1);
-
- in = string;
- out = escaped;
-
- while (*in != '\0') {
- if (strchr(special, *in))
- *out++ = '\\';
- *out++ = *in++;
- }
- *out = '\0';
-
- return escaped;
-}
-
-/*
- decompress_archive
-
- Decompresses the archive "filename" to a temporary directory,
- returns the path to the temp dir, or NULL if failed,
- watch out tho, doesn't actually check if the system command succeeds :-|
-*/
-
-gchar *archive_decompress(const gchar *filename)
-{
- gchar *tmpdir, *cmd, *escaped_filename;
- ArchiveType type;
-#ifndef HAVE_MKDTEMP
-#ifdef S_IRGRP
- mode_t mode755 = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
-#else
- mode_t mode755 = S_IRWXU;
-#endif
-#endif
-
- if ((type = archive_get_type(filename)) <= ARCHIVE_DIR)
- return NULL;
-
-#ifdef HAVE_MKDTEMP
- tmpdir = g_build_filename(g_get_tmp_dir(), "audacious.XXXXXXXX", NULL);
- if (!mkdtemp(tmpdir))
- {
- g_free(tmpdir);
- AUDDBG("Unable to load skin: Failed to create temporary "
- "directory: %s\n", g_strerror(errno));
- return NULL;
- }
-#else
- tmpdir = g_strdup_printf("%s/audacious.%ld", g_get_tmp_dir(), (long)rand());
- make_directory(tmpdir, mode755);
-#endif
-
- escaped_filename = escape_shell_chars(filename);
- cmd = archive_extract_funcs[type] (escaped_filename, tmpdir);
- g_free(escaped_filename);
-
- if (!cmd)
- {
- AUDDBG("extraction function is NULL!\n");
- g_free(tmpdir);
- return NULL;
- }
-
- AUDDBG("Attempt to execute \"%s\"\n", cmd);
-
- if (system(cmd) != 0)
- {
- AUDDBG("could not execute cmd %s\n", cmd);
- g_free(cmd);
- return NULL;
- }
- g_free(cmd);
-
- return tmpdir;
-}
-
-static gboolean del_directory_func(const gchar *path, const gchar *basename,
- void *params)
-{
- if (!strcmp(basename, ".") || !strcmp(path, ".."))
- return FALSE;
-
- if (g_file_test(path, G_FILE_TEST_IS_DIR))
- {
- dir_foreach(path, del_directory_func, NULL, NULL);
- g_rmdir(path);
- return FALSE;
- }
-
- g_unlink(path);
-
- return FALSE;
-}
-
-void del_directory(const gchar *path)
-{
- dir_foreach(path, del_directory_func, NULL, NULL);
- g_rmdir(path);
-}
-
-GArray *string_to_garray(const gchar *str)
-{
- GArray *array;
- gint temp;
- const gchar *ptr = str;
- gchar *endptr;
-
- array = g_array_new(FALSE, TRUE, sizeof(gint));
- for (;;)
- {
- temp = strtol(ptr, &endptr, 10);
- if (ptr == endptr)
- break;
- g_array_append_val(array, temp);
- ptr = endptr;
- while (!g_ascii_isdigit((int)*ptr) && (*ptr) != '\0')
- ptr++;
- if (*ptr == '\0')
- break;
- }
- return (array);
-}
-
-gboolean dir_foreach(const gchar *path, DirForeachFunc function,
- gpointer user_data, GError **error)
-{
- GError *error_out = NULL;
- GDir *dir;
- const gchar *entry;
- gchar *entry_fullpath;
-
- if (!(dir = g_dir_open(path, 0, &error_out)))
- {
- g_propagate_error(error, error_out);
- return FALSE;
- }
-
- while ((entry = g_dir_read_name(dir)))
- {
- entry_fullpath = g_build_filename(path, entry, NULL);
-
- if ((*function) (entry_fullpath, entry, user_data))
- {
- g_free(entry_fullpath);
- break;
- }
-
- g_free(entry_fullpath);
- }
-
- g_dir_close(dir);
-
- return TRUE;
-}
-
-#ifndef HAVE_MKDTEMP
-static void make_directory(const gchar *path, mode_t mode)
-{
- if (g_mkdir_with_parents(path, mode) == 0)
- return;
-
- g_printerr(_("Could not create directory (%s): %s\n"), path,
- g_strerror(errno));
-}
-#endif
diff --git a/src/skins/util.cc b/src/skins/util.cc
new file mode 100644
index 000000000000..e93cdee5dd69
--- /dev/null
+++ b/src/skins/util.cc
@@ -0,0 +1,432 @@
+/* Audacious - Cross-platform multimedia player
+ * Copyright (C) 2005-2009 Audacious development team
+ *
+ * Based on BMP:
+ * Copyright (C) 2003-2004 BMP development team.
+ *
+ * Based on XMMS:
+ * Copyright (C) 1998-2003 XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <glib/gstdio.h>
+
+#include <libaudcore/runtime.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/vfs.h>
+
+#include "util.h"
+
+#ifdef S_IRGRP
+#define DIRMODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
+#else
+#define DIRMODE (S_IRWXU)
+#endif
+
+char * find_file_case (const char * folder, const char * basename)
+{
+ static GHashTable * cache = nullptr;
+ GList * list = nullptr;
+ void * vlist;
+
+ if (cache == nullptr)
+ cache = g_hash_table_new ((GHashFunc) str_calc_hash, g_str_equal);
+
+ if (g_hash_table_lookup_extended (cache, folder, nullptr, & vlist))
+ list = (GList *) vlist;
+ else
+ {
+ GDir * handle = g_dir_open (folder, 0, nullptr);
+ if (! handle)
+ return nullptr;
+
+ const char * name;
+ while ((name = g_dir_read_name (handle)))
+ list = g_list_prepend (list, g_strdup (name));
+
+ g_hash_table_insert (cache, g_strdup (folder), list);
+ g_dir_close (handle);
+ }
+
+ for (; list != nullptr; list = list->next)
+ {
+ if (! g_ascii_strcasecmp ((char *) list->data, basename))
+ return g_strdup ((char *) list->data);
+ }
+
+ return nullptr;
+}
+
+char * find_file_case_path (const char * folder, const char * basename)
+{
+ char * found, * path;
+
+ if ((found = find_file_case (folder, basename)) == nullptr)
+ return nullptr;
+
+ path = g_strdup_printf ("%s/%s", folder, found);
+ g_free (found);
+ return path;
+}
+
+VFSFile open_local_file_nocase (const char * folder, const char * basename)
+{
+ char * path = find_file_case_path (folder, basename);
+ if (! path)
+ return VFSFile ();
+
+ StringBuf uri = filename_to_uri (path);
+ g_free (path);
+
+ if (! uri)
+ return VFSFile ();
+
+ return VFSFile (uri, "r");
+}
+
+char * text_parse_line (char * text)
+{
+ char * newline = strchr (text, '\n');
+
+ if (newline == nullptr)
+ return nullptr;
+
+ * newline = 0;
+ return newline + 1;
+}
+
+typedef enum
+{
+ ARCHIVE_UNKNOWN = 0,
+ ARCHIVE_DIR,
+ ARCHIVE_TAR,
+ ARCHIVE_TGZ,
+ ARCHIVE_ZIP,
+ ARCHIVE_TBZ2
+} ArchiveType;
+
+typedef char *(*ArchiveExtractFunc) (const char *, const char *);
+
+typedef struct
+{
+ ArchiveType type;
+ const char *ext;
+} ArchiveExtensionType;
+
+static ArchiveExtensionType archive_extensions[] = {
+ {ARCHIVE_TAR, ".tar"},
+ {ARCHIVE_ZIP, ".wsz"},
+ {ARCHIVE_ZIP, ".zip"},
+ {ARCHIVE_TGZ, ".tar.gz"},
+ {ARCHIVE_TGZ, ".tgz"},
+ {ARCHIVE_TBZ2, ".tar.bz2"},
+ {ARCHIVE_TBZ2, ".bz2"},
+ {ARCHIVE_UNKNOWN, nullptr}
+};
+
+static char *archive_extract_tar(const char *archive, const char *dest);
+static char *archive_extract_zip(const char *archive, const char *dest);
+static char *archive_extract_tgz(const char *archive, const char *dest);
+static char *archive_extract_tbz2(const char *archive, const char *dest);
+
+static ArchiveExtractFunc archive_extract_funcs[] = {
+ nullptr,
+ nullptr,
+ archive_extract_tar,
+ archive_extract_tgz,
+ archive_extract_zip,
+ archive_extract_tbz2
+};
+
+
+/* FIXME: these functions can be generalised into a function using a
+ * command lookup table */
+
+static const char *get_tar_command(void)
+{
+ static const char *command = nullptr;
+
+ if (!command)
+ {
+ if (!(command = getenv("TARCMD")))
+ command = "tar";
+ }
+
+ return command;
+}
+
+static const char *get_unzip_command(void)
+{
+ static const char *command = nullptr;
+
+ if (!command)
+ {
+ if (!(command = getenv("UNZIPCMD")))
+ command = "unzip";
+ }
+
+ return command;
+}
+
+
+static char *archive_extract_tar(const char *archive, const char *dest)
+{
+ return g_strdup_printf("%s >/dev/null xf \"%s\" -C %s", get_tar_command(),
+ archive, dest);
+}
+
+static char *archive_extract_zip(const char *archive, const char *dest)
+{
+ return g_strdup_printf("%s >/dev/null -o -j \"%s\" -d %s",
+ get_unzip_command(), archive, dest);
+}
+
+static char *archive_extract_tgz(const char *archive, const char *dest)
+{
+ return g_strdup_printf("%s >/dev/null xzf \"%s\" -C %s", get_tar_command(),
+ archive, dest);
+}
+
+static char *archive_extract_tbz2(const char *archive, const char *dest)
+{
+ return g_strdup_printf("bzip2 -dc \"%s\" | %s >/dev/null xf - -C %s",
+ archive, get_tar_command(), dest);
+}
+
+
+static ArchiveType archive_get_type(const char *filename)
+{
+ int i = 0;
+
+ if (g_file_test(filename, G_FILE_TEST_IS_DIR))
+ return ARCHIVE_DIR;
+
+ while (archive_extensions[i].ext)
+ {
+ if (g_str_has_suffix(filename, archive_extensions[i].ext))
+ {
+ return archive_extensions[i].type;
+ }
+ i++;
+ }
+
+ return ARCHIVE_UNKNOWN;
+}
+
+gboolean file_is_archive(const char *filename)
+{
+ return (archive_get_type(filename) > ARCHIVE_DIR);
+}
+
+char *archive_basename(const char *str)
+{
+ int i = 0;
+
+ while (archive_extensions[i].ext)
+ {
+ if (str_has_suffix_nocase(str, archive_extensions[i].ext))
+ {
+ const char *end = g_strrstr(str, archive_extensions[i].ext);
+ if (end)
+ {
+ return g_strndup(str, end - str);
+ }
+ break;
+ }
+ i++;
+ }
+
+ return nullptr;
+}
+
+/**
+ * Escapes characters that are special to the shell inside double quotes.
+ *
+ * @param string String to be escaped.
+ * @return Given string with special characters escaped. Must be freed with g_free().
+ */
+static char *
+escape_shell_chars(const char * string)
+{
+ const char *special = "$`\"\\"; /* Characters to escape */
+ const char *in = string;
+ char *out, *escaped;
+ int num = 0;
+
+ while (*in != '\0')
+ if (strchr(special, *in++))
+ num++;
+
+ escaped = g_new (char, strlen(string) + num + 1);
+
+ in = string;
+ out = escaped;
+
+ while (*in != '\0') {
+ if (strchr(special, *in))
+ *out++ = '\\';
+ *out++ = *in++;
+ }
+ *out = '\0';
+
+ return escaped;
+}
+
+/*
+ decompress_archive
+
+ Decompresses the archive "filename" to a temporary directory,
+ returns the path to the temp dir, or nullptr if failed,
+ watch out tho, doesn't actually check if the system command succeeds :-|
+*/
+
+char *archive_decompress(const char *filename)
+{
+ char *tmpdir, *cmd, *escaped_filename;
+ ArchiveType type;
+
+ if ((type = archive_get_type(filename)) <= ARCHIVE_DIR)
+ return nullptr;
+
+ tmpdir = g_build_filename(g_get_tmp_dir(), "audacious.XXXXXX", nullptr);
+ if (!g_mkdtemp(tmpdir))
+ {
+ g_free(tmpdir);
+ AUDDBG("Unable to load skin: Failed to create temporary "
+ "directory: %s\n", g_strerror(errno));
+ return nullptr;
+ }
+
+ escaped_filename = escape_shell_chars(filename);
+ cmd = archive_extract_funcs[type] (escaped_filename, tmpdir);
+ g_free(escaped_filename);
+
+ if (!cmd)
+ {
+ AUDDBG("extraction function is nullptr!\n");
+ g_free(tmpdir);
+ return nullptr;
+ }
+
+ AUDDBG("Attempt to execute \"%s\"\n", cmd);
+
+ if (system(cmd) != 0)
+ {
+ AUDDBG("could not execute cmd %s\n", cmd);
+ g_free(cmd);
+ return nullptr;
+ }
+ g_free(cmd);
+
+ return tmpdir;
+}
+
+static gboolean del_directory_func(const char *path, const char *basename,
+ void *params)
+{
+ if (!strcmp(basename, ".") || !strcmp(path, ".."))
+ return FALSE;
+
+ if (g_file_test(path, G_FILE_TEST_IS_DIR))
+ {
+ dir_foreach(path, del_directory_func, nullptr, nullptr);
+ g_rmdir(path);
+ return FALSE;
+ }
+
+ g_unlink(path);
+
+ return FALSE;
+}
+
+void del_directory(const char *path)
+{
+ dir_foreach(path, del_directory_func, nullptr, nullptr);
+ g_rmdir(path);
+}
+
+GArray *string_to_garray(const char *str)
+{
+ GArray *array;
+ int temp;
+ const char *ptr = str;
+ char *endptr;
+
+ array = g_array_new(FALSE, TRUE, sizeof(int));
+ for (;;)
+ {
+ temp = strtol(ptr, &endptr, 10);
+ if (ptr == endptr)
+ break;
+ g_array_append_val(array, temp);
+ ptr = endptr;
+ while (!g_ascii_isdigit((int)*ptr) && (*ptr) != '\0')
+ ptr++;
+ if (*ptr == '\0')
+ break;
+ }
+ return (array);
+}
+
+gboolean dir_foreach(const char *path, DirForeachFunc function,
+ void * user_data, GError **error)
+{
+ GError *error_out = nullptr;
+ GDir *dir;
+ const char *entry;
+ char *entry_fullpath;
+
+ if (!(dir = g_dir_open(path, 0, &error_out)))
+ {
+ g_propagate_error(error, error_out);
+ return FALSE;
+ }
+
+ while ((entry = g_dir_read_name(dir)))
+ {
+ entry_fullpath = g_build_filename(path, entry, nullptr);
+
+ if ((*function) (entry_fullpath, entry, user_data))
+ {
+ g_free(entry_fullpath);
+ break;
+ }
+
+ g_free(entry_fullpath);
+ }
+
+ g_dir_close(dir);
+
+ return TRUE;
+}
+
+void make_directory(const char *path)
+{
+ if (g_mkdir_with_parents(path, DIRMODE) == 0)
+ return;
+
+ g_printerr(_("Could not create directory (%s): %s\n"), path,
+ g_strerror(errno));
+}
diff --git a/src/skins/util.h b/src/skins/util.h
index 87be2041f24c..6c041ae65e53 100644
--- a/src/skins/util.h
+++ b/src/skins/util.h
@@ -30,24 +30,26 @@
#include <libaudcore/vfs.h>
-typedef gboolean(*DirForeachFunc) (const gchar *path, const gchar *basename,
- gpointer user_data);
+typedef gboolean(*DirForeachFunc) (const char *path, const char *basename,
+ void * user_data);
-gchar * find_file_case (const gchar * folder, const gchar * basename);
-gchar * find_file_case_path (const gchar * folder, const gchar * basename);
+char * find_file_case (const char * folder, const char * basename);
+char * find_file_case_path (const char * folder, const char * basename);
-VFSFile * open_local_file_nocase (const char * folder, const char * basename);
+VFSFile open_local_file_nocase (const char * folder, const char * basename);
-gchar * text_parse_line (gchar * text);
+char * text_parse_line (char * text);
-void del_directory(const gchar *dirname);
-gboolean dir_foreach(const gchar *path, DirForeachFunc function,
- gpointer user_data, GError **error);
+void make_directory(const char *path);
+void del_directory(const char *path);
-GArray *string_to_garray(const gchar *str);
+gboolean dir_foreach(const char *path, DirForeachFunc function,
+ void * user_data, GError **error);
-gboolean file_is_archive(const gchar *filename);
-gchar *archive_decompress(const gchar *path);
-gchar *archive_basename(const gchar *path);
+GArray *string_to_garray(const char *str);
+
+gboolean file_is_archive(const char *filename);
+char *archive_decompress(const char *path);
+char *archive_basename(const char *path);
#endif
diff --git a/src/skins/view.c b/src/skins/view.c
deleted file mode 100644
index b1b69e750798..000000000000
--- a/src/skins/view.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * view.c
- * Copyright 2014 John Lindgren
- *
- * This file is part of Audacious.
- *
- * Audacious 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, version 2 or version 3 of the License.
- *
- * Audacious 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
- * Audacious. If not, see <http://www.gnu.org/licenses/>.
- *
- * The Audacious team does not consider modular code linking to Audacious or
- * using our public API to be a derived work.
- */
-
-#include "view.h"
-
-#include <audacious/misc.h>
-#include <libaudcore/hook.h>
-
-#include "skins_cfg.h"
-#include "ui_equalizer.h"
-#include "ui_main.h"
-#include "ui_main_evlisteners.h"
-#include "ui_playlist.h"
-#include "ui_skinned_button.h"
-#include "ui_skinned_menurow.h"
-#include "ui_skinned_window.h"
-
-void view_show_player (bool_t show)
-{
- if (show)
- gtk_window_present ((GtkWindow *) mainwin);
- else
- gtk_widget_hide (mainwin);
-
- view_apply_show_playlist ();
- view_apply_show_equalizer ();
-
- start_stop_visual (FALSE);
-}
-
-void view_set_show_playlist (bool_t show)
-{
- aud_set_bool ("skins", "playlist_visible", show);
- hook_call ("skins set playlist_visible", NULL);
-
- view_apply_show_playlist ();
-}
-
-void view_apply_show_playlist (void)
-{
- bool_t show = aud_get_bool ("skins", "playlist_visible");
-
- if (show && gtk_widget_get_visible (mainwin))
- gtk_window_present ((GtkWindow *) playlistwin);
- else
- gtk_widget_hide (playlistwin);
-
- button_set_active (mainwin_pl, show);
-}
-
-void view_set_show_equalizer (bool_t show)
-{
- aud_set_bool ("skins", "equalizer_visible", show);
- hook_call ("skins set equalizer_visible", NULL);
-
- view_apply_show_equalizer ();
-}
-
-void view_apply_show_equalizer (void)
-{
- bool_t show = aud_get_bool ("skins", "equalizer_visible");
-
- if (show && gtk_widget_get_visible (mainwin))
- gtk_window_present ((GtkWindow *) equalizerwin);
- else
- gtk_widget_hide (equalizerwin);
-
- button_set_active (mainwin_eq, show);
-}
-
-void view_set_player_shaded (bool_t shaded)
-{
- aud_set_bool ("skins", "player_shaded", shaded);
- hook_call ("skins set player_shaded", NULL);
-
- view_apply_player_shaded ();
-}
-
-void view_apply_player_shaded (void)
-{
- bool_t shaded = aud_get_bool ("skins", "player_shaded");
-
- window_set_shaded (mainwin, shaded);
-
- int width = shaded ? MAINWIN_SHADED_WIDTH : active_skin->properties.mainwin_width;
- int height = shaded ? MAINWIN_SHADED_HEIGHT : active_skin->properties.mainwin_height;
- window_set_size (mainwin, width, height);
-
- mainwin_set_shape ();
-}
-
-void view_set_playlist_shaded (bool_t shaded)
-{
- aud_set_bool ("skins", "playlist_shaded", shaded);
- hook_call ("skins set playlist_shaded", NULL);
-
- view_apply_playlist_shaded ();
-}
-
-void view_apply_playlist_shaded (void)
-{
- bool_t shaded = aud_get_bool ("skins", "playlist_shaded");
-
- window_set_shaded (playlistwin, shaded);
-
- int height = shaded ? MAINWIN_SHADED_HEIGHT : config.playlist_height;
- window_set_size (playlistwin, config.playlist_width, height);
-
- playlistwin_update ();
-}
-
-void view_set_equalizer_shaded (bool_t shaded)
-{
- aud_set_bool ("skins", "equalizer_shaded", shaded);
- hook_call ("skins set equalizer_shaded", NULL);
-
- view_apply_equalizer_shaded ();
-}
-
-void view_apply_equalizer_shaded (void)
-{
- bool_t shaded = aud_get_bool ("skins", "equalizer_shaded");
-
- window_set_shaded (equalizerwin, shaded);
- window_set_size (equalizerwin, 275, shaded ? 14 : 116);
-
- equalizerwin_set_shape ();
-}
-
-void view_set_on_top (bool_t on_top)
-{
- aud_set_bool ("skins", "always_on_top", on_top);
- hook_call ("skins set always_on_top", NULL);
-
- view_apply_on_top ();
-}
-
-void view_apply_on_top (void)
-{
- bool_t on_top = aud_get_bool ("skins", "always_on_top");
-
- gtk_window_set_keep_above ((GtkWindow *) mainwin, on_top);
- gtk_window_set_keep_above ((GtkWindow *) equalizerwin, on_top);
- gtk_window_set_keep_above ((GtkWindow *) playlistwin, on_top);
-
- ui_skinned_menurow_update (mainwin_menurow);
-}
-
-void view_set_sticky (bool_t sticky)
-{
- aud_set_bool ("skins", "sticky", sticky);
- hook_call ("skins set sticky", NULL);
-
- view_apply_sticky ();
-}
-
-void view_apply_sticky (void)
-{
- bool_t sticky = aud_get_bool ("skins", "sticky");
-
- if (sticky)
- {
- gtk_window_stick ((GtkWindow *) mainwin);
- gtk_window_stick ((GtkWindow *) equalizerwin);
- gtk_window_stick ((GtkWindow *) playlistwin);
- }
- else
- {
- gtk_window_unstick ((GtkWindow *) mainwin);
- gtk_window_unstick ((GtkWindow *) equalizerwin);
- gtk_window_unstick ((GtkWindow *) playlistwin);
- }
-}
-
-void view_set_show_remaining (bool_t remaining)
-{
- aud_set_bool ("skins", "show_remaining_time", remaining);
- hook_call ("skins set show_remaining_time", NULL);
-
- view_apply_show_remaining ();
-}
-
-void view_apply_show_remaining (void)
-{
- mainwin_update_song_info ();
-}
diff --git a/src/skins/view.cc b/src/skins/view.cc
new file mode 100644
index 000000000000..8baac93d9402
--- /dev/null
+++ b/src/skins/view.cc
@@ -0,0 +1,222 @@
+/*
+ * view.c
+ * Copyright 2014 John Lindgren
+ *
+ * This file is part of Audacious.
+ *
+ * Audacious 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, version 2 or version 3 of the License.
+ *
+ * Audacious 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
+ * Audacious. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The Audacious team does not consider modular code linking to Audacious or
+ * using our public API to be a derived work.
+ */
+
+#include "view.h"
+
+#include <libaudcore/runtime.h>
+#include <libaudcore/hook.h>
+
+#include "plugin.h"
+#include "plugin-window.h"
+#include "skins_cfg.h"
+#include "ui_equalizer.h"
+#include "ui_main.h"
+#include "ui_main_evlisteners.h"
+#include "ui_playlist.h"
+#include "ui_skinned_button.h"
+#include "ui_skinned_menurow.h"
+#include "ui_skinned_window.h"
+
+void view_show_player (bool show)
+{
+ if (show)
+ {
+ gtk_window_present ((GtkWindow *) mainwin);
+ show_plugin_windows ();
+ }
+ else
+ {
+ gtk_widget_hide (mainwin);
+ hide_plugin_windows ();
+ }
+
+ view_apply_show_playlist ();
+ view_apply_show_equalizer ();
+
+ start_stop_visual (FALSE);
+}
+
+void view_set_show_playlist (bool show)
+{
+ aud_set_bool ("skins", "playlist_visible", show);
+ hook_call ("skins set playlist_visible", nullptr);
+
+ view_apply_show_playlist ();
+}
+
+void view_apply_show_playlist (void)
+{
+ bool show = aud_get_bool ("skins", "playlist_visible");
+
+ if (show && gtk_widget_get_visible (mainwin))
+ gtk_window_present ((GtkWindow *) playlistwin);
+ else
+ gtk_widget_hide (playlistwin);
+
+ button_set_active (mainwin_pl, show);
+}
+
+void view_set_show_equalizer (bool show)
+{
+ aud_set_bool ("skins", "equalizer_visible", show);
+ hook_call ("skins set equalizer_visible", nullptr);
+
+ view_apply_show_equalizer ();
+}
+
+void view_apply_show_equalizer (void)
+{
+ bool show = aud_get_bool ("skins", "equalizer_visible");
+
+ if (show && gtk_widget_get_visible (mainwin))
+ gtk_window_present ((GtkWindow *) equalizerwin);
+ else
+ gtk_widget_hide (equalizerwin);
+
+ button_set_active (mainwin_eq, show);
+}
+
+void view_set_player_shaded (bool shaded)
+{
+ aud_set_bool ("skins", "player_shaded", shaded);
+ hook_call ("skins set player_shaded", nullptr);
+
+ view_apply_player_shaded ();
+}
+
+void view_apply_player_shaded (void)
+{
+ bool shaded = aud_get_bool ("skins", "player_shaded");
+
+ window_set_shaded (mainwin, shaded);
+
+ int width = shaded ? MAINWIN_SHADED_WIDTH : active_skin->properties.mainwin_width;
+ int height = shaded ? MAINWIN_SHADED_HEIGHT : active_skin->properties.mainwin_height;
+ window_set_size (mainwin, width, height);
+}
+
+void view_set_playlist_shaded (bool shaded)
+{
+ aud_set_bool ("skins", "playlist_shaded", shaded);
+ hook_call ("skins set playlist_shaded", nullptr);
+
+ view_apply_playlist_shaded ();
+}
+
+void view_apply_playlist_shaded (void)
+{
+ bool shaded = aud_get_bool ("skins", "playlist_shaded");
+
+ window_set_shaded (playlistwin, shaded);
+
+ int height = shaded ? MAINWIN_SHADED_HEIGHT : config.playlist_height;
+ window_set_size (playlistwin, config.playlist_width, height);
+
+ playlistwin_update ();
+}
+
+void view_set_equalizer_shaded (bool shaded)
+{
+ aud_set_bool ("skins", "equalizer_shaded", shaded);
+ hook_call ("skins set equalizer_shaded", nullptr);
+
+ view_apply_equalizer_shaded ();
+}
+
+void view_apply_equalizer_shaded (void)
+{
+ bool shaded = aud_get_bool ("skins", "equalizer_shaded");
+
+ window_set_shaded (equalizerwin, shaded);
+ window_set_size (equalizerwin, 275, shaded ? 14 : 116);
+}
+
+void view_set_double_size (bool double_size)
+{
+ aud_set_bool ("skins", "double_size", double_size);
+ hook_call ("skins set double_size", nullptr);
+
+ view_apply_double_size ();
+}
+
+void view_apply_double_size (void)
+{
+ config.scale = aud_get_bool ("skins", "double_size") ? 2 : 1;
+ skins_restart ();
+}
+
+void view_set_on_top (bool on_top)
+{
+ aud_set_bool ("skins", "always_on_top", on_top);
+ hook_call ("skins set always_on_top", nullptr);
+
+ view_apply_on_top ();
+}
+
+void view_apply_on_top (void)
+{
+ bool on_top = aud_get_bool ("skins", "always_on_top");
+
+ gtk_window_set_keep_above ((GtkWindow *) mainwin, on_top);
+ gtk_window_set_keep_above ((GtkWindow *) equalizerwin, on_top);
+ gtk_window_set_keep_above ((GtkWindow *) playlistwin, on_top);
+
+ ui_skinned_menurow_update (mainwin_menurow);
+}
+
+void view_set_sticky (bool sticky)
+{
+ aud_set_bool ("skins", "sticky", sticky);
+ hook_call ("skins set sticky", nullptr);
+
+ view_apply_sticky ();
+}
+
+void view_apply_sticky (void)
+{
+ bool sticky = aud_get_bool ("skins", "sticky");
+
+ if (sticky)
+ {
+ gtk_window_stick ((GtkWindow *) mainwin);
+ gtk_window_stick ((GtkWindow *) equalizerwin);
+ gtk_window_stick ((GtkWindow *) playlistwin);
+ }
+ else
+ {
+ gtk_window_unstick ((GtkWindow *) mainwin);
+ gtk_window_unstick ((GtkWindow *) equalizerwin);
+ gtk_window_unstick ((GtkWindow *) playlistwin);
+ }
+}
+
+void view_set_show_remaining (bool remaining)
+{
+ aud_set_bool ("skins", "show_remaining_time", remaining);
+ hook_call ("skins set show_remaining_time", nullptr);
+
+ view_apply_show_remaining ();
+}
+
+void view_apply_show_remaining (void)
+{
+ mainwin_update_song_info ();
+}
diff --git a/src/skins/view.h b/src/skins/view.h
index 8497c37b7de3..18de79c30f2f 100644
--- a/src/skins/view.h
+++ b/src/skins/view.h
@@ -22,32 +22,33 @@
#ifndef SKINS_VIEW_H
#define SKINS_VIEW_H
-#include <libaudcore/core.h>
+void view_show_player (bool show);
-void view_show_player (bool_t show);
-
-void view_set_show_playlist (bool_t show);
+void view_set_show_playlist (bool show);
void view_apply_show_playlist (void);
-void view_set_show_equalizer (bool_t show);
+void view_set_show_equalizer (bool show);
void view_apply_show_equalizer (void);
-void view_set_player_shaded (bool_t shaded);
+void view_set_player_shaded (bool shaded);
void view_apply_player_shaded (void);
-void view_set_playlist_shaded (bool_t shaded);
+void view_set_playlist_shaded (bool shaded);
void view_apply_playlist_shaded (void);
-void view_set_equalizer_shaded (bool_t shaded);
+void view_set_equalizer_shaded (bool shaded);
void view_apply_equalizer_shaded (void);
-void view_set_on_top (bool_t on_top);
+void view_set_double_size (bool double_size);
+void view_apply_double_size (void);
+
+void view_set_on_top (bool on_top);
void view_apply_on_top (void);
-void view_set_sticky (bool_t sticky);
+void view_set_sticky (bool sticky);
void view_apply_sticky (void);
-void view_set_show_remaining (bool_t remaining);
+void view_set_show_remaining (bool remaining);
void view_apply_show_remaining (void);
#endif /* SKINS_VIEW_H */
diff --git a/src/sndfile/Makefile b/src/sndfile/Makefile
index 6d0f4700f015..8f28aae08ae5 100644
--- a/src/sndfile/Makefile
+++ b/src/sndfile/Makefile
@@ -2,12 +2,14 @@ include ../../extra.mk
PLUGIN = sndfile${PLUGIN_SUFFIX}
-SRCS = plugin.c
+SRCS = plugin.cc
include ../../buildsys.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${SNDFILE_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS} ${SNDFILE_LIBS} -lm
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${SNDFILE_CFLAGS} -I../..
+LIBS += ${SNDFILE_LIBS} -lm
diff --git a/src/sndfile/plugin.c b/src/sndfile/plugin.c
deleted file mode 100644
index 468a7135b316..000000000000
--- a/src/sndfile/plugin.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/* Audacious - Cross-platform multimedia player
- * Copyright (C) 2005-2011 Audacious development team
- *
- * Based on the xmms_sndfile input plugin:
- * Copyright (C) 2000, 2002 Erik de Castro Lopo
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/*
- * Rewritten 17-Feb-2007 (nenolod):
- * - now uses conditional variables to ensure that sndfile mutex is
- * entirely protected.
- * - pausing works now
- * - fixed some potential race conditions when dealing with NFS.
- * - TITLE_LEN removed
- *
- * Re-cleaned up 09-Aug-2009 (ccr):
- * - removed threading madness.
- * - improved locking.
- * - misc. cleanups.
- *
- * Play loop rewritten 14-Nov-2009 (jlindgren):
- * - decode in floating point
- * - drain audio buffer before closing
- * - handle seeking/stopping while paused
- */
-
-#include <math.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include <sndfile.h>
-
-#include <audacious/input.h>
-#include <audacious/plugin.h>
-#include <audacious/i18n.h>
-#include <libaudcore/audstrings.h>
-
-/* Virtual file access wrappers for libsndfile
- */
-static sf_count_t
-sf_get_filelen (void *user_data)
-{
- return vfs_fsize (user_data);
-}
-
-static sf_count_t
-sf_vseek (sf_count_t offset, int whence, void *user_data)
-{
- return vfs_fseek(user_data, offset, whence);
-}
-
-static sf_count_t
-sf_vread (void *ptr, sf_count_t count, void *user_data)
-{
- return vfs_fread(ptr, 1, count, user_data);
-}
-
-static sf_count_t
-sf_vwrite (const void *ptr, sf_count_t count, void *user_data)
-{
- return vfs_fwrite(ptr, 1, count, user_data);
-}
-
-static sf_count_t
-sf_tell (void *user_data)
-{
- return vfs_ftell(user_data);
-}
-
-static SF_VIRTUAL_IO sf_virtual_io =
-{
- sf_get_filelen,
- sf_vseek,
- sf_vread,
- sf_vwrite,
- sf_tell
-};
-
-static void copy_string (SNDFILE * sf, int sf_id, Tuple * tup, int tup_id)
-{
- const char * str = sf_get_string (sf, sf_id);
- if (str)
- tuple_set_str (tup, tup_id, str);
-}
-
-static void copy_int (SNDFILE * sf, int sf_id, Tuple * tup, int tup_id)
-{
- const char * str = sf_get_string (sf, sf_id);
- if (str && atoi (str))
- tuple_set_int (tup, tup_id, atoi (str));
-}
-
-static Tuple * get_song_tuple (const char * filename, VFSFile * file)
-{
- SNDFILE *sndfile;
- SF_INFO sfinfo;
- const char *format, *subformat;
- Tuple * ti;
-
- sndfile = sf_open_virtual (& sf_virtual_io, SFM_READ, & sfinfo, file);
-
- if (sndfile == NULL)
- return NULL;
-
- ti = tuple_new_from_filename (filename);
-
- /* I have no idea version of sndfile ALBUM, GENRE, and TRACKNUMBER were
- * added in. -jlindgren */
- copy_string (sndfile, SF_STR_TITLE, ti, FIELD_TITLE);
- copy_string (sndfile, SF_STR_ARTIST, ti, FIELD_ARTIST);
-/* copy_string (sndfile, SF_STR_ALBUM, ti, FIELD_ALBUM); */
- copy_string (sndfile, SF_STR_COMMENT, ti, FIELD_COMMENT);
-/* copy_string (sndfile, SF_STR_GENRE, ti, FIELD_GENRE); */
- copy_int (sndfile, SF_STR_DATE, ti, FIELD_YEAR);
-/* copy_int (sndfile, SF_STR_TRACKNUMBER, ti, FIELD_TRACK_NUMBER); */
-
- sf_close (sndfile);
-
- if (sfinfo.samplerate > 0)
- {
- tuple_set_int(ti, FIELD_LENGTH,
- (int) ceil (1000.0 * sfinfo.frames / sfinfo.samplerate));
- }
-
- switch (sfinfo.format & SF_FORMAT_TYPEMASK)
- {
- case SF_FORMAT_WAV:
- case SF_FORMAT_WAVEX:
- format = "Microsoft WAV";
- break;
- case SF_FORMAT_AIFF:
- format = "Apple/SGI AIFF";
- break;
- case SF_FORMAT_AU:
- format = "Sun/NeXT AU";
- break;
- case SF_FORMAT_RAW:
- format = "Raw PCM data";
- break;
- case SF_FORMAT_PAF:
- format = "Ensoniq PARIS";
- break;
- case SF_FORMAT_SVX:
- format = "Amiga IFF / SVX8 / SV16";
- break;
- case SF_FORMAT_NIST:
- format = "Sphere NIST";
- break;
- case SF_FORMAT_VOC:
- format = "Creative VOC";
- break;
- case SF_FORMAT_IRCAM:
- format = "Berkeley/IRCAM/CARL";
- break;
- case SF_FORMAT_W64:
- format = "Sonic Foundry's 64 bit RIFF/WAV";
- break;
- case SF_FORMAT_MAT4:
- format = "Matlab (tm) V4.2 / GNU Octave 2.0";
- break;
- case SF_FORMAT_MAT5:
- format = "Matlab (tm) V5.0 / GNU Octave 2.1";
- break;
- case SF_FORMAT_PVF:
- format = "Portable Voice Format";
- break;
- case SF_FORMAT_XI:
- format = "Fasttracker 2 Extended Instrument";
- break;
- case SF_FORMAT_HTK:
- format = "HMM Tool Kit";
- break;
- case SF_FORMAT_SDS:
- format = "Midi Sample Dump Standard";
- break;
- case SF_FORMAT_AVR:
- format = "Audio Visual Research";
- break;
- case SF_FORMAT_SD2:
- format = "Sound Designer 2";
- break;
- case SF_FORMAT_FLAC:
- format = "Free Lossless Audio Codec";
- break;
- case SF_FORMAT_CAF:
- format = "Core Audio File";
- break;
- default:
- format = "Unknown sndfile";
- }
-
- switch (sfinfo.format & SF_FORMAT_SUBMASK)
- {
- case SF_FORMAT_PCM_S8:
- subformat = "signed 8 bit";
- break;
- case SF_FORMAT_PCM_16:
- subformat = "signed 16 bit";
- break;
- case SF_FORMAT_PCM_24:
- subformat = "signed 24 bit";
- break;
- case SF_FORMAT_PCM_32:
- subformat = "signed 32 bit";
- break;
- case SF_FORMAT_PCM_U8:
- subformat = "unsigned 8 bit";
- break;
- case SF_FORMAT_FLOAT:
- subformat = "32 bit float";
- break;
- case SF_FORMAT_DOUBLE:
- subformat = "64 bit float";
- break;
- case SF_FORMAT_ULAW:
- subformat = "U-Law";
- break;
- case SF_FORMAT_ALAW:
- subformat = "A-Law";
- break;
- case SF_FORMAT_IMA_ADPCM:
- subformat = "IMA ADPCM";
- break;
- case SF_FORMAT_MS_ADPCM:
- subformat = "MS ADPCM";
- break;
- case SF_FORMAT_GSM610:
- subformat = "GSM 6.10";
- break;
- case SF_FORMAT_VOX_ADPCM:
- subformat = "Oki Dialogic ADPCM";
- break;
- case SF_FORMAT_G721_32:
- subformat = "32kbs G721 ADPCM";
- break;
- case SF_FORMAT_G723_24:
- subformat = "24kbs G723 ADPCM";
- break;
- case SF_FORMAT_G723_40:
- subformat = "40kbs G723 ADPCM";
- break;
- case SF_FORMAT_DWVW_12:
- subformat = "12 bit Delta Width Variable Word";
- break;
- case SF_FORMAT_DWVW_16:
- subformat = "16 bit Delta Width Variable Word";
- break;
- case SF_FORMAT_DWVW_24:
- subformat = "24 bit Delta Width Variable Word";
- break;
- case SF_FORMAT_DWVW_N:
- subformat = "N bit Delta Width Variable Word";
- break;
- case SF_FORMAT_DPCM_8:
- subformat = "8 bit differential PCM";
- break;
- case SF_FORMAT_DPCM_16:
- subformat = "16 bit differential PCM";
- break;
- default:
- subformat = NULL;
- }
-
- if (subformat != NULL)
- {
- SPRINTF (codec, "%s (%s)", format, subformat);
- tuple_set_format (ti, codec, sfinfo.channels, sfinfo.samplerate, 0);
- }
- else
- tuple_set_format (ti, format, sfinfo.channels, sfinfo.samplerate, 0);
-
- return ti;
-}
-
-static bool_t play_start (const char * filename, VFSFile * file)
-{
- if (file == NULL)
- return FALSE;
-
- SF_INFO sfinfo;
- SNDFILE * sndfile = sf_open_virtual (& sf_virtual_io, SFM_READ, & sfinfo,
- file);
- if (sndfile == NULL)
- return FALSE;
-
- if (! aud_input_open_audio (FMT_FLOAT, sfinfo.samplerate,
- sfinfo.channels))
- {
- sf_close (sndfile);
- return FALSE;
- }
-
- int size = sfinfo.channels * (sfinfo.samplerate / 50);
- float * buffer = g_new (float, size);
-
- while (! aud_input_check_stop ())
- {
- int seek_value = aud_input_check_seek ();
- if (seek_value != -1)
- sf_seek (sndfile, (int64_t) seek_value * sfinfo.samplerate / 1000, SEEK_SET);
-
- int samples = sf_read_float (sndfile, buffer, size);
- if (! samples)
- break;
-
- aud_input_write_audio (buffer, sizeof (float) * samples);
- }
-
- sf_close (sndfile);
- g_free (buffer);
-
- return TRUE;
-}
-
-static int
-is_our_file_from_vfs(const char *filename, VFSFile *fin)
-{
- SNDFILE *tmp_sndfile;
- SF_INFO tmp_sfinfo;
-
- /* Have to open the file to see if libsndfile can handle it. */
- tmp_sndfile = sf_open_virtual (&sf_virtual_io, SFM_READ, &tmp_sfinfo, fin);
-
- if (!tmp_sndfile)
- return FALSE;
-
- /* It can so close file and return TRUE. */
- sf_close (tmp_sndfile);
- tmp_sndfile = NULL;
-
- return TRUE;
-}
-
-const char plugin_about[] =
- N_("Based on the xmms_sndfile plugin:\n"
- "Copyright (C) 2000, 2002 Erik de Castro Lopo\n\n"
- "Adapted for Audacious by Tony Vroon <chainsaw at gentoo.org>\n\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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.");
-
-static const char *sndfile_fmts[] = { "aiff", "au", "raw", "wav", NULL };
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("Sndfile Plugin"),
- .domain = PACKAGE,
- .about_text = plugin_about,
- .play = play_start,
- .probe_for_tuple = get_song_tuple,
- .is_our_file_from_vfs = is_our_file_from_vfs,
- .extensions = sndfile_fmts,
-
- /* low priority fallback (but before ffaudio) */
- .priority = 9,
-)
diff --git a/src/sndfile/plugin.cc b/src/sndfile/plugin.cc
new file mode 100644
index 000000000000..b050aa7d5707
--- /dev/null
+++ b/src/sndfile/plugin.cc
@@ -0,0 +1,351 @@
+/* Audacious - Cross-platform multimedia player
+ * Copyright (C) 2005-2011 Audacious development team
+ *
+ * Based on the xmms_sndfile input plugin:
+ * Copyright (C) 2000, 2002 Erik de Castro Lopo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+#include <stdlib.h>
+
+#include <sndfile.h>
+
+#define WANT_VFS_STDIO_COMPAT
+#include <libaudcore/plugin.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/audstrings.h>
+
+class SndfilePlugin : public InputPlugin
+{
+public:
+ static const char about[];
+ static const char * const exts[];
+
+ static constexpr PluginInfo info = {
+ N_("Sndfile Plugin"),
+ PACKAGE,
+ about
+ };
+
+ static constexpr auto iinfo = InputInfo ()
+ .with_priority (9) /* low priority fallback (but before ffaudio) */
+ .with_exts (exts);
+
+ constexpr SndfilePlugin () : InputPlugin (info, iinfo) {}
+
+ bool is_our_file (const char * filename, VFSFile & file);
+ Tuple read_tuple (const char * filename, VFSFile & file);
+ bool play (const char * filename, VFSFile & file);
+};
+
+EXPORT SndfilePlugin aud_plugin_instance;
+
+/* Virtual file access wrappers for libsndfile
+ */
+static sf_count_t
+sf_get_filelen (void *user_data)
+{
+ return ((VFSFile *) user_data)->fsize ();
+}
+
+static sf_count_t
+sf_vseek (sf_count_t offset, int whence, void *user_data)
+{
+ return ((VFSFile *) user_data)->fseek (offset, to_vfs_seek_type (whence));
+}
+
+static sf_count_t
+sf_vread (void *ptr, sf_count_t count, void *user_data)
+{
+ return ((VFSFile *) user_data)->fread (ptr, 1, count);
+}
+
+static sf_count_t
+sf_vwrite (const void *ptr, sf_count_t count, void *user_data)
+{
+ return ((VFSFile *) user_data)->fwrite (ptr, 1, count);
+}
+
+static sf_count_t
+sf_tell (void *user_data)
+{
+ return ((VFSFile *) user_data)->ftell ();
+}
+
+static SF_VIRTUAL_IO sf_virtual_io =
+{
+ sf_get_filelen,
+ sf_vseek,
+ sf_vread,
+ sf_vwrite,
+ sf_tell
+};
+
+static void copy_string (SNDFILE * sf, int sf_id, Tuple & tup, Tuple::Field field)
+{
+ const char * str = sf_get_string (sf, sf_id);
+ if (str)
+ tup.set_str (field, str);
+}
+
+static void copy_int (SNDFILE * sf, int sf_id, Tuple & tup, Tuple::Field field)
+{
+ const char * str = sf_get_string (sf, sf_id);
+ if (str && atoi (str))
+ tup.set_int (field, atoi (str));
+}
+
+Tuple SndfilePlugin::read_tuple (const char * filename, VFSFile & file)
+{
+ SNDFILE *sndfile;
+ SF_INFO sfinfo;
+ const char *format, *subformat;
+ Tuple ti;
+
+ sndfile = sf_open_virtual (& sf_virtual_io, SFM_READ, & sfinfo, & file);
+
+ if (sndfile == nullptr)
+ return ti;
+
+ ti.set_filename (filename);
+
+ copy_string (sndfile, SF_STR_TITLE, ti, Tuple::Title);
+ copy_string (sndfile, SF_STR_ARTIST, ti, Tuple::Artist);
+ copy_string (sndfile, SF_STR_ALBUM, ti, Tuple::Album);
+ copy_string (sndfile, SF_STR_COMMENT, ti, Tuple::Comment);
+ copy_string (sndfile, SF_STR_GENRE, ti, Tuple::Genre);
+ copy_int (sndfile, SF_STR_DATE, ti, Tuple::Year);
+ copy_int (sndfile, SF_STR_TRACKNUMBER, ti, Tuple::Track);
+
+ sf_close (sndfile);
+
+ if (sfinfo.samplerate > 0)
+ ti.set_int (Tuple::Length, ceil (1000.0 * sfinfo.frames / sfinfo.samplerate));
+
+ switch (sfinfo.format & SF_FORMAT_TYPEMASK)
+ {
+ case SF_FORMAT_WAV:
+ case SF_FORMAT_WAVEX:
+ format = "Microsoft WAV";
+ break;
+ case SF_FORMAT_AIFF:
+ format = "Apple/SGI AIFF";
+ break;
+ case SF_FORMAT_AU:
+ format = "Sun/NeXT AU";
+ break;
+ case SF_FORMAT_RAW:
+ format = "Raw PCM data";
+ break;
+ case SF_FORMAT_PAF:
+ format = "Ensoniq PARIS";
+ break;
+ case SF_FORMAT_SVX:
+ format = "Amiga IFF / SVX8 / SV16";
+ break;
+ case SF_FORMAT_NIST:
+ format = "Sphere NIST";
+ break;
+ case SF_FORMAT_VOC:
+ format = "Creative VOC";
+ break;
+ case SF_FORMAT_IRCAM:
+ format = "Berkeley/IRCAM/CARL";
+ break;
+ case SF_FORMAT_W64:
+ format = "Sonic Foundry's 64 bit RIFF/WAV";
+ break;
+ case SF_FORMAT_MAT4:
+ format = "Matlab (tm) V4.2 / GNU Octave 2.0";
+ break;
+ case SF_FORMAT_MAT5:
+ format = "Matlab (tm) V5.0 / GNU Octave 2.1";
+ break;
+ case SF_FORMAT_PVF:
+ format = "Portable Voice Format";
+ break;
+ case SF_FORMAT_XI:
+ format = "Fasttracker 2 Extended Instrument";
+ break;
+ case SF_FORMAT_HTK:
+ format = "HMM Tool Kit";
+ break;
+ case SF_FORMAT_SDS:
+ format = "Midi Sample Dump Standard";
+ break;
+ case SF_FORMAT_AVR:
+ format = "Audio Visual Research";
+ break;
+ case SF_FORMAT_SD2:
+ format = "Sound Designer 2";
+ break;
+ case SF_FORMAT_FLAC:
+ format = "Free Lossless Audio Codec";
+ break;
+ case SF_FORMAT_CAF:
+ format = "Core Audio File";
+ break;
+ default:
+ format = "Unknown sndfile";
+ }
+
+ switch (sfinfo.format & SF_FORMAT_SUBMASK)
+ {
+ case SF_FORMAT_PCM_S8:
+ subformat = "signed 8 bit";
+ break;
+ case SF_FORMAT_PCM_16:
+ subformat = "signed 16 bit";
+ break;
+ case SF_FORMAT_PCM_24:
+ subformat = "signed 24 bit";
+ break;
+ case SF_FORMAT_PCM_32:
+ subformat = "signed 32 bit";
+ break;
+ case SF_FORMAT_PCM_U8:
+ subformat = "unsigned 8 bit";
+ break;
+ case SF_FORMAT_FLOAT:
+ subformat = "32 bit float";
+ break;
+ case SF_FORMAT_DOUBLE:
+ subformat = "64 bit float";
+ break;
+ case SF_FORMAT_ULAW:
+ subformat = "U-Law";
+ break;
+ case SF_FORMAT_ALAW:
+ subformat = "A-Law";
+ break;
+ case SF_FORMAT_IMA_ADPCM:
+ subformat = "IMA ADPCM";
+ break;
+ case SF_FORMAT_MS_ADPCM:
+ subformat = "MS ADPCM";
+ break;
+ case SF_FORMAT_GSM610:
+ subformat = "GSM 6.10";
+ break;
+ case SF_FORMAT_VOX_ADPCM:
+ subformat = "Oki Dialogic ADPCM";
+ break;
+ case SF_FORMAT_G721_32:
+ subformat = "32kbs G721 ADPCM";
+ break;
+ case SF_FORMAT_G723_24:
+ subformat = "24kbs G723 ADPCM";
+ break;
+ case SF_FORMAT_G723_40:
+ subformat = "40kbs G723 ADPCM";
+ break;
+ case SF_FORMAT_DWVW_12:
+ subformat = "12 bit Delta Width Variable Word";
+ break;
+ case SF_FORMAT_DWVW_16:
+ subformat = "16 bit Delta Width Variable Word";
+ break;
+ case SF_FORMAT_DWVW_24:
+ subformat = "24 bit Delta Width Variable Word";
+ break;
+ case SF_FORMAT_DWVW_N:
+ subformat = "N bit Delta Width Variable Word";
+ break;
+ case SF_FORMAT_DPCM_8:
+ subformat = "8 bit differential PCM";
+ break;
+ case SF_FORMAT_DPCM_16:
+ subformat = "16 bit differential PCM";
+ break;
+ default:
+ subformat = nullptr;
+ }
+
+ if (subformat != nullptr)
+ ti.set_format (str_printf ("%s (%s)", format, subformat),
+ sfinfo.channels, sfinfo.samplerate, 0);
+ else
+ ti.set_format (format, sfinfo.channels, sfinfo.samplerate, 0);
+
+ return ti;
+}
+
+bool SndfilePlugin::play (const char * filename, VFSFile & file)
+{
+ SF_INFO sfinfo;
+ SNDFILE * sndfile = sf_open_virtual (& sf_virtual_io, SFM_READ, & sfinfo, & file);
+ if (sndfile == nullptr)
+ return false;
+
+ open_audio (FMT_FLOAT, sfinfo.samplerate, sfinfo.channels);
+
+ Index<float> buffer;
+ buffer.resize (sfinfo.channels * (sfinfo.samplerate / 50));
+
+ while (! check_stop ())
+ {
+ int seek_value = check_seek ();
+ if (seek_value != -1)
+ sf_seek (sndfile, (int64_t) seek_value * sfinfo.samplerate / 1000, SEEK_SET);
+
+ int samples = sf_read_float (sndfile, buffer.begin (), buffer.len ());
+ if (! samples)
+ break;
+
+ write_audio (buffer.begin (), sizeof (float) * samples);
+ }
+
+ sf_close (sndfile);
+
+ return true;
+}
+
+bool SndfilePlugin::is_our_file (const char * filename, VFSFile & file)
+{
+ SNDFILE *tmp_sndfile;
+ SF_INFO tmp_sfinfo;
+
+ /* Have to open the file to see if libsndfile can handle it. */
+ tmp_sndfile = sf_open_virtual (&sf_virtual_io, SFM_READ, &tmp_sfinfo, &file);
+
+ if (!tmp_sndfile)
+ return false;
+
+ /* It can so close file and return true. */
+ sf_close (tmp_sndfile);
+ tmp_sndfile = nullptr;
+
+ return true;
+}
+
+const char SndfilePlugin::about[] =
+ N_("Based on the xmms_sndfile plugin:\n"
+ "Copyright (C) 2000, 2002 Erik de Castro Lopo\n\n"
+ "Adapted for Audacious by Tony Vroon <chainsaw at gentoo.org>\n\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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.");
+
+const char * const SndfilePlugin::exts[] = { "aiff", "au", "raw", "wav", nullptr };
diff --git a/src/sndio-ng/Makefile b/src/sndio-ng/Makefile
new file mode 100644
index 000000000000..bc7bcd8396b6
--- /dev/null
+++ b/src/sndio-ng/Makefile
@@ -0,0 +1,13 @@
+PLUGIN = sndio-ng${PLUGIN_SUFFIX}
+
+SRCS = sndio.cc
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+plugindir := ${plugindir}/${OUTPUT_PLUGIN_DIR}
+
+LD = ${CXX}
+CFLAGS += ${PLUGIN_CFLAGS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
+LIBS += ${SNDIO_LIBS}
diff --git a/src/sndio-ng/sndio.cc b/src/sndio-ng/sndio.cc
new file mode 100644
index 000000000000..9b1d841d817f
--- /dev/null
+++ b/src/sndio-ng/sndio.cc
@@ -0,0 +1,376 @@
+/*
+ * Sndio Output Plugin for Audacious
+ * Copyright 2014 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/runtime.h>
+
+#include <errno.h>
+#include <poll.h>
+#include <pthread.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include <sndio.h>
+
+class SndioPlugin : public OutputPlugin
+{
+public:
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Sndio Output"),
+ PACKAGE,
+ nullptr,
+ & prefs
+ };
+
+ constexpr SndioPlugin () : OutputPlugin (info, 5) {}
+
+ bool init ();
+
+ StereoVolume get_volume ();
+ void set_volume (StereoVolume v);
+
+ bool open_audio (int format, int rate, int channels);
+ void close_audio ();
+
+ void period_wait ();
+ int write_audio (const void * data, int size);
+ void drain ();
+
+ int get_delay ();
+
+ void pause (bool pause);
+ void flush ();
+
+private:
+ bool poll_locked ();
+
+ static void volume_cb (void *, unsigned int vol);
+ static void move_cb (void * arg, int delta);
+
+ sio_hdl * m_handle = nullptr;
+
+ int m_rate = 0, m_channels = 0;
+ int m_bytes_per_frame = 0;
+
+ bool m_paused = false;
+ int m_frames_buffered = 0;
+ timeval m_last_write_time = timeval ();
+ int m_flush_count = 0;
+
+ pthread_mutex_t m_mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_cond_t m_cond = PTHREAD_COND_INITIALIZER;
+};
+
+EXPORT SndioPlugin aud_plugin_instance;
+
+const char * const SndioPlugin::defaults[] = {
+ "save_volume", "FALSE",
+ "volume", "100",
+ nullptr
+};
+
+const PreferencesWidget SndioPlugin::widgets[] = {
+ WidgetEntry (N_("Device (blank for default):"),
+ WidgetString ("sndio", "device")),
+ WidgetCheck (N_("Save and restore volume:"),
+ WidgetBool ("sndio", "save_volume"))
+};
+
+const PluginPreferences SndioPlugin::prefs = {{widgets}};
+
+bool SndioPlugin::init ()
+{
+ aud_config_set_defaults ("sndio", defaults);
+ return true;
+}
+
+void SndioPlugin::volume_cb (void *, unsigned int vol)
+{
+ aud_set_int ("sndio", "volume", aud::rescale ((int) vol, SIO_MAXVOL, 100));
+}
+
+void SndioPlugin::set_volume (StereoVolume v)
+{
+ int vol = aud::max (v.left, v.right);
+ aud_set_int ("sndio", "volume", vol);
+
+ pthread_mutex_lock (& m_mutex);
+
+ if (m_handle)
+ sio_setvol (m_handle, aud::rescale (vol, 100, SIO_MAXVOL));
+
+ pthread_mutex_unlock (& m_mutex);
+}
+
+StereoVolume SndioPlugin::get_volume ()
+{
+ int vol = aud_get_int ("sndio", "volume");
+ return {vol, vol};
+}
+
+void SndioPlugin::move_cb (void * arg, int delta)
+{
+ auto me = (SndioPlugin *) arg;
+
+ me->m_frames_buffered -= delta;
+ gettimeofday (& me->m_last_write_time, nullptr);
+
+ pthread_cond_broadcast (& me->m_cond);
+}
+
+struct FormatData {
+ int format;
+ int bits, bytes;
+ bool sign, le;
+};
+
+static const FormatData format_table[] = {
+ {FMT_S8, 8, 1, true, false},
+ {FMT_U8, 8, 1, false, false},
+ {FMT_S16_LE, 16, 2, true, true},
+ {FMT_S16_BE, 16, 2, true, false},
+ {FMT_U16_LE, 16, 2, false, true},
+ {FMT_U16_BE, 16, 2, false, false},
+ {FMT_S24_LE, 24, 4, true, true},
+ {FMT_S24_BE, 24, 4, true, false},
+ {FMT_U24_LE, 24, 4, false, true},
+ {FMT_U24_BE, 24, 4, false, false},
+ {FMT_S32_LE, 32, 4, true, true},
+ {FMT_S32_BE, 32, 4, true, false},
+ {FMT_U32_LE, 32, 4, false, true},
+ {FMT_U32_BE, 32, 4, false, false},
+};
+
+bool SndioPlugin::open_audio (int format, int rate, int channels)
+{
+ const FormatData * fdata = nullptr;
+
+ for (const FormatData & f : format_table)
+ {
+ if (f.format == format)
+ fdata = & f;
+ }
+
+ if (! fdata)
+ {
+ aud_ui_show_error (str_printf (_("Sndio error: Unsupported audio format (%d)"), format));
+ return false;
+ }
+
+ String device = aud_get_str ("sndio", "device");
+ const char * device2 = device[0] ? (const char *) device : SIO_DEVANY;
+
+ m_handle = sio_open (device2, SIO_PLAY, true);
+
+ if (! m_handle)
+ {
+ aud_ui_show_error (_("Sndio error: sio_open() failed"));
+ return false;
+ }
+
+ m_rate = rate;
+ m_channels = channels;
+ m_bytes_per_frame = FMT_SIZEOF (format) * channels;
+
+ m_paused = false;
+ m_frames_buffered = 0;
+ m_last_write_time = timeval ();
+ m_flush_count = 0;
+
+ int buffer_ms = aud_get_int (nullptr, "output_buffer_size");
+
+ sio_par par;
+ sio_initpar (& par);
+
+ par.bits = fdata->bits;
+ par.bps = fdata->bytes;
+ par.sig = fdata->sign;
+ par.le = fdata->le;
+ par.msb = false;
+ par.pchan = channels;
+ par.rate = rate;
+ par.bufsz = aud::rescale (buffer_ms, 1000, rate);
+ par.xrun = SIO_IGNORE;
+
+ if (! sio_setpar (m_handle, & par))
+ {
+ aud_ui_show_error (_("Sndio error: sio_setpar() failed"));
+ goto fail;
+ }
+
+ if (aud_get_bool ("sndio", "save_volume"))
+ set_volume (get_volume ());
+
+ sio_onvol (m_handle, volume_cb, nullptr);
+ sio_onmove (m_handle, move_cb, this);
+
+ if (! sio_start (m_handle))
+ {
+ aud_ui_show_error (_("Sndio error: sio_start() failed"));
+ goto fail;
+ }
+
+ return true;
+
+fail:
+ sio_close (m_handle);
+ m_handle = nullptr;
+ return false;
+}
+
+void SndioPlugin::close_audio ()
+{
+ sio_close (m_handle);
+ m_handle = nullptr;
+}
+
+bool SndioPlugin::poll_locked ()
+{
+ bool success = false;
+ pollfd * fds = nullptr;
+ int nfds, old_flush_count;
+
+ nfds = sio_nfds (m_handle);
+ if (nfds < 1)
+ goto fail;
+
+ fds = new pollfd[nfds];
+
+ nfds = sio_pollfd (m_handle, fds, POLLOUT);
+ if (nfds < 1)
+ goto fail;
+
+ old_flush_count = m_flush_count;
+
+ pthread_mutex_unlock (& m_mutex);
+
+ if (poll (fds, nfds, -1) < 0)
+ AUDERR ("poll() failed: %s\n", strerror (errno));
+ else
+ success = true;
+
+ pthread_mutex_lock (& m_mutex);
+
+ if (success && m_flush_count == old_flush_count)
+ sio_revents (m_handle, fds);
+
+fail:
+ delete[] fds;
+ return success;
+}
+
+void SndioPlugin::period_wait ()
+{
+ pthread_mutex_lock (& m_mutex);
+
+ if (m_paused || sio_eof (m_handle) || ! poll_locked ())
+ pthread_cond_wait (& m_cond, & m_mutex);
+
+ pthread_mutex_unlock (& m_mutex);
+}
+
+int SndioPlugin::write_audio (const void * data, int size)
+{
+ int len = 0;
+ pthread_mutex_lock (& m_mutex);
+
+ if (! m_paused)
+ {
+ len = sio_write (m_handle, data, size);
+ m_frames_buffered += len / m_bytes_per_frame;
+ }
+
+ pthread_mutex_unlock (& m_mutex);
+ return len;
+}
+
+void SndioPlugin::drain ()
+{
+ pthread_mutex_lock (& m_mutex);
+
+ if (! m_paused)
+ {
+ int d = aud::rescale (m_frames_buffered, m_rate, 1000);
+ timespec delay = {d / 1000, d % 1000 * 1000000};
+
+ pthread_mutex_unlock (& m_mutex);
+ nanosleep (& delay, nullptr);
+ pthread_mutex_lock (& m_mutex);
+
+ poll_locked ();
+ }
+
+ pthread_mutex_unlock (& m_mutex);
+}
+
+int SndioPlugin::get_delay ()
+{
+ auto timediff = [] (const timeval & a, const timeval & b) -> int64_t
+ { return 1000 * (int64_t) (b.tv_sec - a.tv_sec) + (b.tv_usec - a.tv_usec) / 1000; };
+
+ pthread_mutex_lock (& m_mutex);
+
+ int delay = aud::rescale (m_frames_buffered, m_rate, 1000);
+
+ if (m_last_write_time.tv_sec)
+ {
+ timeval now;
+ gettimeofday (& now, nullptr);
+ delay = aud::max (delay - timediff (m_last_write_time, now), (int64_t) 0);
+ }
+
+ pthread_mutex_unlock (& m_mutex);
+ return delay;
+}
+
+void SndioPlugin::pause (bool pause)
+{
+ pthread_mutex_lock (& m_mutex);
+
+ m_paused = pause;
+
+ pthread_cond_broadcast (& m_cond);
+ pthread_mutex_unlock (& m_mutex);
+}
+
+void SndioPlugin::flush ()
+{
+ pthread_mutex_lock (& m_mutex);
+
+ sio_stop (m_handle);
+
+ m_frames_buffered = 0;
+ m_last_write_time = timeval ();
+ m_flush_count ++;
+
+ if (! sio_start (m_handle))
+ AUDERR ("sio_start() failed\n");
+
+ pthread_cond_broadcast (& m_cond);
+ pthread_mutex_unlock (& m_mutex);
+}
diff --git a/src/sndio/Makefile b/src/sndio/Makefile
deleted file mode 100644
index 0623484b01e8..000000000000
--- a/src/sndio/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-PLUGIN = sndio${PLUGIN_SUFFIX}
-
-SRCS = sndio.c
-
-include ../../buildsys.mk
-include ../../extra.mk
-
-plugindir := ${plugindir}/${OUTPUT_PLUGIN_DIR}
-
-CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${SNDIO_LIBS}
diff --git a/src/sndio/sndio.c b/src/sndio/sndio.c
deleted file mode 100644
index 7246f26a1931..000000000000
--- a/src/sndio/sndio.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright (c) 2008, 2009 Thomas Pfaff <tpfaff at tp76.info>
- * Copyright (c) 2012 Alexandre Ratchov <alex at caoua.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <errno.h>
-#include <poll.h>
-#include <pthread.h>
-#include <sndio.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <gtk/gtk.h>
-#include <audacious/plugin.h>
-#include <audacious/misc.h>
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-#include <libaudgui/libaudgui.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-/*
- * minimum output buffer size in milliseconds
- */
-#define BUFFER_SIZE_MIN 250
-
-static int get_volume(void) { return aud_get_int("sndio", "volume"); }
-static void set_volume(int vol) { aud_set_int("sndio", "volume", vol); }
-
-bool_t sndio_init(void);
-void sndio_about(void);
-void sndio_configure(void);
-void sndio_get_volume(int *, int *);
-void sndio_set_volume(int, int);
-bool_t sndio_open(int, int, int);
-void sndio_close(void);
-int sndio_buffer_free(void);
-void sndio_period_wait(void);
-void sndio_write(void *, int);
-void sndio_pause(bool_t);
-void sndio_flush(int);
-int sndio_output_time(void);
-
-void onmove_cb(void *, int);
-void onvol_cb(void *, unsigned);
-
-void configure_win_ok_cb(GtkWidget *, gpointer);
-
-static struct sio_par par;
-static struct sio_hdl *hdl;
-static long long rdpos;
-static long long wrpos;
-static int paused, restarted;
-static int pause_pending, flush_pending, volume_pending;
-static int bytes_per_sec;
-static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
-
-static GtkWidget *configure_win;
-static GtkWidget *adevice_entry;
-
-AUD_OUTPUT_PLUGIN
-(
- .name = "sndio",
- .init = sndio_init,
- .about = sndio_about,
- .configure = sndio_configure,
- .probe_priority = 2,
- .get_volume = sndio_get_volume,
- .set_volume = sndio_set_volume,
- .open_audio = sndio_open,
- .write_audio = sndio_write,
- .close_audio = sndio_close,
- .buffer_free = sndio_buffer_free,
- .period_wait = sndio_period_wait,
- .flush = sndio_flush,
- .pause = sndio_pause,
- .output_time = sndio_output_time
-)
-
-static struct fmt_to_par {
- int fmt, bits, sig, le;
-} fmt_to_par[] = {
- {FMT_S8, 8, 1, 0}, {FMT_U8, 8, 0, 0},
- {FMT_S16_LE, 16, 1, 1}, {FMT_S16_BE, 16, 1, 0},
- {FMT_U16_LE, 16, 0, 1}, {FMT_U16_BE, 16, 0, 0},
- {FMT_S24_LE, 24, 1, 1}, {FMT_S24_BE, 24, 1, 0},
- {FMT_U24_LE, 24, 0, 1}, {FMT_U24_BE, 24, 0, 0},
- {FMT_S32_LE, 32, 1, 1}, {FMT_S32_BE, 32, 1, 0},
- {FMT_U32_LE, 32, 0, 1}, {FMT_U32_BE, 32, 0, 0}
-};
-
-static const gchar * const sndio_defaults[] = {
- "volume", "100",
- NULL,
-};
-
-static void
-reset(void)
-{
- if (!restarted) {
- restarted = 1;
- sio_stop(hdl);
- sio_start(hdl);
- rdpos = wrpos;
- }
-}
-
-static void
-wait_ready(void)
-{
- int n;
- struct pollfd pfds[16];
-
- if (volume_pending) {
- sio_setvol(hdl, get_volume() * SIO_MAXVOL / 100);
- volume_pending = 0;
- }
- if (flush_pending) {
- reset();
- flush_pending = 0;
- }
- if (pause_pending) {
- if (paused)
- reset();
- pause_pending = 0;
- }
- if (paused) {
- pthread_mutex_unlock(&mtx);
- usleep(20000);
- pthread_mutex_lock(&mtx);
- return;
- }
- n = sio_pollfd(hdl, pfds, POLLOUT);
- if (n != 0) {
- pthread_mutex_unlock(&mtx);
- while (poll(pfds, n, -1) < 0) {
- if (errno != EINTR) {
- perror("poll");
- exit(1);
- }
- }
- pthread_mutex_lock(&mtx);
- }
- (void)sio_revents(hdl, pfds);
-}
-
-bool_t
-sndio_init(void)
-{
- aud_config_set_defaults("sndio", sndio_defaults);
-
- return (1);
-}
-
-void
-sndio_about(void)
-{
- static GtkWidget *about = NULL;
-
- audgui_simple_message(&about, GTK_MESSAGE_INFO,
- _("About Sndio Output Plugin"),
- _("Sndio Output Plugin\n\n"
- "Written by Thomas Pfaff <tpfaff at tp76.info>\n"));
-}
-
-void
-sndio_get_volume(int *l, int *r)
-{
- *l = *r = get_volume();
-}
-
-void
-sndio_set_volume(int l, int r)
-{
- /* Ignore balance control, so use unattenuated channel. */
- pthread_mutex_lock(&mtx);
- set_volume(MAX(l, r));
- volume_pending = 1;
- pthread_mutex_unlock(&mtx);
-}
-
-bool_t
-sndio_open(int fmt, int rate, int nch)
-{
- int i;
- struct sio_par askpar;
- GtkWidget *dialog = NULL;
- unsigned buffer_size;
-
- char *audiodev = aud_get_str("sndio", "audiodev");
-
- hdl = sio_open(strlen(audiodev) > 0 ? audiodev : NULL, SIO_PLAY, 1);
- if (!hdl) {
- g_warning("failed to open audio device %s", audiodev);
- free(audiodev);
- return (0);
- }
-
- str_unref(audiodev);
-
- sio_initpar(&askpar);
- for (i = 0; ; i++) {
- if (i == ARRAY_LEN(fmt_to_par)) {
- g_warning("unknown format %d requested", fmt);
- sndio_close();
- return 0;
- }
- if (fmt_to_par[i].fmt == fmt)
- break;
- }
- askpar.bits = fmt_to_par[i].bits;
- askpar.bps = SIO_BPS(askpar.bits);
- askpar.sig = fmt_to_par[i].sig;
- if (askpar.bits > 8)
- askpar.le = fmt_to_par[i].le;
- if (askpar.bits < askpar.bps * 8)
- askpar.msb = 0;
- askpar.pchan = nch;
- askpar.rate = rate;
- buffer_size = aud_get_int(NULL, "output_buffer_size");
- if (buffer_size < BUFFER_SIZE_MIN)
- buffer_size = BUFFER_SIZE_MIN;
- askpar.appbufsz = buffer_size * rate / 1000;
- if (!sio_setpar(hdl, &askpar) || !sio_getpar(hdl, &par)) {
- g_warning("failed to set parameters");
- sndio_close();
- return (0);
- }
- if ((par.bps > 1 && par.le != askpar.le) ||
- (par.bits < par.bps * 8 && par.msb) ||
- par.bps != askpar.bps ||
- par.sig != askpar.sig ||
- par.pchan != askpar.pchan ||
- par.rate != askpar.rate) {
- g_warning("parameters not supported by the audio device");
- audgui_simple_message(&dialog, GTK_MESSAGE_INFO,
- _("Unsupported format"),
- _("A format not supported by the audio device "
- "was requested.\n\n"
- "Please try again with the sndiod(1) server running."));
- sndio_close();
- return (0);
- }
- rdpos = 0;
- wrpos = 0;
- sio_onmove(hdl, onmove_cb, NULL);
- sio_onvol(hdl, onvol_cb, NULL);
- sio_setvol(hdl, get_volume() * SIO_MAXVOL / 100);
- if (!sio_start(hdl)) {
- g_warning("failed to start audio device");
- sndio_close();
- return (0);
- }
- pause_pending = flush_pending = volume_pending = 0;
- bytes_per_sec = par.bps * par.pchan * par.rate;
- restarted = 1;
- paused = 0;
- return (1);
-}
-
-void
-sndio_write(void *ptr, int length)
-{
- unsigned n;
-
- pthread_mutex_lock(&mtx);
- for (;;) {
- if (paused)
- break;
- restarted = 0;
- n = sio_write(hdl, ptr, length);
- if (n == 0 && sio_eof(hdl))
- return;
- wrpos += n;
- length -= n;
- ptr = (char *)ptr + n;
- if (length == 0)
- break;
- wait_ready();
- }
- pthread_mutex_unlock(&mtx);
-}
-
-void
-sndio_close(void)
-{
- if (!hdl)
- return;
- sio_close(hdl);
- hdl = NULL;
-}
-
-int
-sndio_buffer_free(void)
-{
- return paused ? 0 : par.round * par.pchan * par.bps;
-}
-
-void
-sndio_period_wait(void)
-{
- pthread_mutex_lock(&mtx);
- wait_ready();
- pthread_mutex_unlock(&mtx);
-}
-
-void
-sndio_flush(int time)
-{
- pthread_mutex_lock(&mtx);
- rdpos = wrpos = (long long)time * bytes_per_sec / 1000;
- flush_pending = 1;
- pthread_mutex_unlock(&mtx);
-}
-
-void
-sndio_pause(bool_t flag)
-{
- pthread_mutex_lock(&mtx);
- paused = flag;
- pause_pending = 1;
- pthread_mutex_unlock(&mtx);
-}
-
-int
-sndio_output_time(void)
-{
- int time;
-
- pthread_mutex_lock(&mtx);
- time = rdpos * 1000 / bytes_per_sec;
- pthread_mutex_unlock(&mtx);
- return time;
-}
-
-void
-onmove_cb(void *addr, int delta)
-{
- rdpos += delta * (int)(par.bps * par.pchan);
-}
-
-void
-onvol_cb(void *addr, unsigned ctl)
-{
- /* Update volume only if it actually changed */
- if (ctl != get_volume() * SIO_MAXVOL / 100)
- set_volume(ctl * 100 / SIO_MAXVOL);
-}
-
-void
-configure_win_ok_cb(GtkWidget *w, gpointer data)
-{
- aud_set_str("sndio", "audiodev", gtk_entry_get_text(GTK_ENTRY(adevice_entry)));
- gtk_widget_destroy(configure_win);
-}
-
-void
-sndio_configure(void)
-{
- GtkWidget *vbox;
- GtkWidget *adevice_frame, *adevice_text, *adevice_vbox;
- GtkWidget *bbox, *ok, *cancel;
-
- if (configure_win) {
- gtk_window_present(GTK_WINDOW(configure_win));
- return;
- }
-
- configure_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- g_signal_connect(configure_win, "destroy",
- G_CALLBACK(gtk_widget_destroyed), &configure_win);
-
- gtk_window_set_title(GTK_WINDOW(configure_win), _("sndio device"));
- gtk_window_set_resizable(GTK_WINDOW(configure_win), FALSE);
- gtk_window_set_position(GTK_WINDOW(configure_win), GTK_WIN_POS_MOUSE);
- gtk_container_set_border_width(GTK_CONTAINER(configure_win), 10);
-
- vbox = gtk_vbox_new(FALSE, 5);
- gtk_container_add(GTK_CONTAINER(configure_win), vbox);
- gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
-
- adevice_frame = gtk_frame_new(_("Audio device:"));
- gtk_box_pack_start(GTK_BOX(vbox), adevice_frame, FALSE, FALSE, 0);
-
- adevice_vbox = gtk_vbox_new(FALSE, 5);
- gtk_container_set_border_width(GTK_CONTAINER(adevice_vbox), 5);
- gtk_container_add(GTK_CONTAINER(adevice_frame), adevice_vbox);
-
- adevice_text = gtk_label_new(_("(empty means default)"));
- gtk_box_pack_start(GTK_BOX(adevice_vbox), adevice_text, TRUE, TRUE, 0);
-
- char *audiodev = aud_get_str("sndio", "audiodev");
-
- adevice_entry = gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(adevice_entry), audiodev);
- gtk_box_pack_start(GTK_BOX(adevice_vbox), adevice_entry, TRUE, TRUE, 0);
-
- str_unref(audiodev);
-
- bbox = gtk_hbutton_box_new();
- gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
- gtk_box_set_spacing(GTK_BOX(bbox), 5);
- gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
-
- ok = gtk_button_new_with_label(_("OK"));
- g_signal_connect(ok, "clicked",
- G_CALLBACK(configure_win_ok_cb), NULL);
-
- gtk_widget_set_can_default(ok, TRUE);
- gtk_box_pack_start(GTK_BOX(bbox), ok, TRUE, TRUE, 0);
- gtk_widget_grab_default(ok);
-
- cancel = gtk_button_new_with_label(_("Cancel"));
- g_signal_connect(cancel, "clicked",
- G_CALLBACK(gtk_widget_destroy), &configure_win);
-
- gtk_widget_set_can_default(cancel, TRUE);
- gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0);
-
- gtk_widget_show_all(configure_win);
-}
diff --git a/src/song-info-qt/Makefile b/src/song-info-qt/Makefile
new file mode 100644
index 000000000000..415e32201e28
--- /dev/null
+++ b/src/song-info-qt/Makefile
@@ -0,0 +1,13 @@
+PLUGIN = song-info-qt${PLUGIN_SUFFIX}
+
+SRCS = song-info.cc
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+
+LD = ${CXX}
+CFLAGS += ${PLUGIN_CFLAGS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../.. ${QT_CFLAGS}
+LIBS += ${QT_LIBS} -laudqt
diff --git a/src/song-info-qt/song-info.cc b/src/song-info-qt/song-info.cc
new file mode 100644
index 000000000000..8b2693374ba5
--- /dev/null
+++ b/src/song-info-qt/song-info.cc
@@ -0,0 +1,99 @@
+/*
+ * song-info.cc
+ * Copyright 2014 William Pitcock
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <libaudcore/drct.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/plugin.h>
+
+#include <libaudqt/libaudqt.h>
+#include <libaudqt/info-widget.h>
+
+class SongInfo : public GeneralPlugin {
+public:
+ static constexpr PluginInfo info = {
+ N_("Song Info (Qt)"),
+ PACKAGE
+ };
+
+ constexpr SongInfo () : GeneralPlugin (info, false) {}
+ void * get_qt_widget ();
+
+private:
+ static void update (void * unused, audqt::InfoWidget * widget);
+ static void clear (void * unused, audqt::InfoWidget * widget);
+ static void widget_cleanup (QObject * widget);
+};
+
+void SongInfo::update (void * unused, audqt::InfoWidget * widget)
+{
+ if (! aud_drct_get_playing ())
+ return;
+
+ if (! widget)
+ return;
+
+ int playlist = aud_playlist_get_playing ();
+
+ if (playlist == -1)
+ playlist = aud_playlist_get_active ();
+
+ int position = aud_playlist_get_position (playlist);
+ if (position == -1)
+ return;
+
+ String filename = aud_playlist_entry_get_filename (playlist, position);
+ if (! filename)
+ return;
+
+ PluginHandle * decoder = aud_playlist_entry_get_decoder (playlist, position);
+ if (! decoder)
+ return;
+
+ Tuple tuple = aud_playlist_entry_get_tuple (playlist, position);
+ if (tuple)
+ widget->fillInfo (playlist, position, filename, tuple, decoder, false);
+}
+
+void SongInfo::clear (void * unused, audqt::InfoWidget * widget)
+{
+ if (! widget)
+ return;
+}
+
+void SongInfo::widget_cleanup (QObject * widget)
+{
+ hook_dissociate ("playback begin", (HookFunction) update, widget);
+ hook_dissociate ("playback stop", (HookFunction) clear, widget);
+}
+
+void * SongInfo::get_qt_widget ()
+{
+ audqt::InfoWidget * widget = new audqt::InfoWidget;
+
+ QObject::connect (widget, &QObject::destroyed, widget_cleanup);
+
+ hook_associate ("playback begin", (HookFunction) update, widget);
+ hook_associate ("playback stop", (HookFunction) clear, widget);
+
+ return widget;
+}
+
+EXPORT SongInfo aud_plugin_instance;
diff --git a/src/song_change/Makefile b/src/song_change/Makefile
index b151bdf51713..c3b3b3a28825 100644
--- a/src/song_change/Makefile
+++ b/src/song_change/Makefile
@@ -1,12 +1,14 @@
PLUGIN = song_change${PLUGIN_SUFFIX}
-SRCS = formatter.c song_change.c
+SRCS = formatter.cc song_change.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} -I../..
LIBS += ${GTK_LIBS} ${GLIB_LIBS}
diff --git a/src/song_change/formatter.c b/src/song_change/formatter.c
deleted file mode 100644
index c55d159954a8..000000000000
--- a/src/song_change/formatter.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Audacious
- * Copyright (C) 2005-2007 Audacious team
- *
- * XMMS - Cross-platform multimedia player
- * Copyright (C) 1998-2003 Peter Alm, Mikael Alm, Olle Hallnas,
- * Thomas Nilsson and 4Front Technologies
- * Copyright (C) 1999-2003 Haavard Kvaalen
- *
- * 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; under version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <glib.h>
-#include <string.h>
-#include "formatter.h"
-
-Formatter *
-formatter_new(void)
-{
- Formatter *formatter = g_slice_new0(Formatter);
-
- formatter_associate(formatter, '%', "%");
- return formatter;
-}
-
-void
-formatter_destroy(Formatter * formatter)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- if (formatter->values[i])
- g_free(formatter->values[i]);
-
- g_slice_free(Formatter, formatter);
-}
-
-void
-formatter_associate(Formatter * formatter, const guchar id, const gchar *value)
-{
- formatter_dissociate(formatter, id);
- formatter->values[id] = g_strdup(value);
-}
-
-void
-formatter_dissociate(Formatter * formatter, const guchar id)
-{
- if (formatter->values[id])
- g_free(formatter->values[id]);
- formatter->values[id] = 0;
-}
-
-gchar *
-formatter_format(Formatter * formatter, gchar *format)
-{
- gchar *p, *q, *buffer;
- gint len;
-
- for (p = format, len = 0; *p; p++)
- if (*p == '%') {
- if (formatter->values[(int) *++p])
- len += strlen(formatter->values[(int) *p]);
- else if (!*p) {
- len += 1;
- p--;
- }
- else
- len += 2;
- }
- else
- len++;
- buffer = g_malloc(len + 1);
- for (p = format, q = buffer; *p; p++)
- if (*p == '%') {
- if (formatter->values[(int) *++p]) {
- g_strlcpy(q, formatter->values[(int) *p], len - 1);
- q += strlen(q);
- }
- else {
- *q++ = '%';
- if (*p != '\0')
- *q++ = *p;
- else
- p--;
- }
- }
- else
- *q++ = *p;
- *q = 0;
- return buffer;
-}
diff --git a/src/song_change/formatter.cc b/src/song_change/formatter.cc
new file mode 100644
index 000000000000..c46c075e81d6
--- /dev/null
+++ b/src/song_change/formatter.cc
@@ -0,0 +1,104 @@
+/* Audacious
+ * Copyright (C) 2005-2007 Audacious team
+ *
+ * XMMS - Cross-platform multimedia player
+ * Copyright (C) 1998-2003 Peter Alm, Mikael Alm, Olle Hallnas,
+ * Thomas Nilsson and 4Front Technologies
+ * Copyright (C) 1999-2003 Haavard Kvaalen
+ *
+ * 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; under version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "formatter.h"
+
+Formatter *
+formatter_new(void)
+{
+ Formatter *formatter = g_slice_new0(Formatter);
+
+ formatter_associate(formatter, '%', "%");
+ return formatter;
+}
+
+void
+formatter_destroy(Formatter * formatter)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ if (formatter->values[i])
+ g_free(formatter->values[i]);
+
+ g_slice_free(Formatter, formatter);
+}
+
+void
+formatter_associate(Formatter * formatter, const unsigned char id, const char *value)
+{
+ formatter_dissociate(formatter, id);
+ formatter->values[id] = g_strdup(value);
+}
+
+void
+formatter_dissociate(Formatter * formatter, const unsigned char id)
+{
+ if (formatter->values[id])
+ g_free(formatter->values[id]);
+ formatter->values[id] = 0;
+}
+
+char *
+formatter_format(Formatter * formatter, const char *format)
+{
+ const char *p;
+ char *q, *buffer;
+ int len;
+
+ for (p = format, len = 0; *p; p++)
+ if (*p == '%') {
+ if (formatter->values[(int) *++p])
+ len += strlen(formatter->values[(int) *p]);
+ else if (!*p) {
+ len += 1;
+ p--;
+ }
+ else
+ len += 2;
+ }
+ else
+ len++;
+ buffer = g_new(char, len + 1);
+ for (p = format, q = buffer; *p; p++)
+ if (*p == '%') {
+ if (formatter->values[(int) *++p]) {
+ g_strlcpy(q, formatter->values[(int) *p], len - 1);
+ q += strlen(q);
+ }
+ else {
+ *q++ = '%';
+ if (*p != '\0')
+ *q++ = *p;
+ else
+ p--;
+ }
+ }
+ else
+ *q++ = *p;
+ *q = 0;
+ return buffer;
+}
diff --git a/src/song_change/formatter.h b/src/song_change/formatter.h
index b853bc5f790f..ec542e468f4c 100644
--- a/src/song_change/formatter.h
+++ b/src/song_change/formatter.h
@@ -4,13 +4,13 @@
#include <glib.h>
typedef struct {
- gchar *values[256];
+ char *values[256];
} Formatter;
Formatter *formatter_new(void);
void formatter_destroy(Formatter * formatter);
-void formatter_associate(Formatter * formatter, const guchar id, const gchar * value);
-void formatter_dissociate(Formatter * formatter, const guchar id);
-gchar *formatter_format(Formatter * formatter, gchar * format);
+void formatter_associate(Formatter * formatter, const unsigned char id, const char * value);
+void formatter_dissociate(Formatter * formatter, const unsigned char id);
+char *formatter_format(Formatter * formatter, const char * format);
#endif
diff --git a/src/song_change/song_change.c b/src/song_change/song_change.c
deleted file mode 100644
index bbda70756f41..000000000000
--- a/src/song_change/song_change.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Audacious: A cross-platform multimedia player.
- * Copyright (c) 2005 Audacious Team
- */
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include <signal.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include <string.h>
-
-#include <audacious/misc.h>
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-#include <audacious/playlist.h>
-#include <libaudcore/hook.h>
-#include <libaudcore/audstrings.h>
-#include <libaudcore/tuple.h>
-
-#include "formatter.h"
-
-static const PluginPreferences preferences;
-
-static gboolean init (void);
-static void cleanup(void);
-static void songchange_playback_begin(gpointer unused, gpointer unused2);
-static void songchange_playback_end(gpointer unused, gpointer unused2);
-static void songchange_playlist_eof(gpointer unused, gpointer unused2);
-//static void songchange_playback_ttc(gpointer, gpointer);
-
-typedef struct
-{
- gchar *title;
- gchar *filename;
-}
-songchange_playback_ttc_prevs_t;
-static songchange_playback_ttc_prevs_t *ttc_prevs = NULL;
-
-static char *cmd_line = NULL;
-static char *cmd_line_after = NULL;
-static char *cmd_line_end = NULL;
-static char *cmd_line_ttc = NULL;
-
-static GtkWidget *cmd_warn_label, *cmd_warn_img;
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("Song Change"),
- .domain = PACKAGE,
- .prefs = & preferences,
- .init = init,
- .cleanup = cleanup
-)
-
-/**
- * Escapes characters that are special to the shell inside double quotes.
- *
- * @param string String to be escaped.
- * @return Given string with special characters escaped. Must be freed with g_free().
- */
-static gchar *escape_shell_chars(const gchar * string)
-{
- const gchar *special = "$`\"\\"; /* Characters to escape */
- const gchar *in = string;
- gchar *out, *escaped;
- gint num = 0;
-
- while (*in != '\0')
- if (strchr(special, *in++))
- num++;
-
- escaped = g_malloc(strlen(string) + num + 1);
-
- in = string;
- out = escaped;
-
- while (*in != '\0') {
- if (strchr(special, *in))
- *out++ = '\\';
- *out++ = *in++;
- }
- *out = '\0';
-
- return escaped;
-}
-
-static void bury_child(int signal)
-{
- waitpid(-1, NULL, WNOHANG);
-}
-
-static void execute_command(char *cmd)
-{
- char *argv[4] = {"/bin/sh", "-c", NULL, NULL};
- int i;
- argv[2] = cmd;
- signal(SIGCHLD, bury_child);
- if (fork() == 0)
- {
- /* We don't want this process to hog the audio device etc */
- for (i = 3; i < 255; i++)
- close(i);
- execv("/bin/sh", argv);
- }
-}
-
-/* Format codes:
- *
- * F - frequency (in hertz)
- * c - number of channels
- * f - filename (full path)
- * l - length (in milliseconds)
- * n - name
- * r - rate (in bits per second)
- * s - name (since everyone's used to it)
- * t - playlist position (%02d)
- * p - currently playing (1 or 0)
- * a - artist
- * b - album
- * r - track title
- */
-/* do_command(): do @cmd after replacing the format codes
- @cmd: command to run */
-static void do_command (char * cmd)
-{
- int playlist = aud_playlist_get_playing ();
- int pos = aud_playlist_get_position (playlist);
-
- char *shstring = NULL, *temp, numbuf[32];
- gboolean playing;
- Formatter *formatter;
-
- if (cmd && strlen(cmd) > 0)
- {
- formatter = formatter_new();
-
- char * ctitle = aud_playlist_entry_get_title (playlist, pos, FALSE);
- if (ctitle)
- {
- temp = escape_shell_chars (ctitle);
- formatter_associate(formatter, 's', temp);
- formatter_associate(formatter, 'n', temp);
- g_free(temp);
- str_unref (ctitle);
- }
- else
- {
- formatter_associate(formatter, 's', "");
- formatter_associate(formatter, 'n', "");
- }
-
- char * filename = aud_playlist_entry_get_filename (playlist, pos);
- if (filename)
- {
- temp = escape_shell_chars (filename);
- formatter_associate(formatter, 'f', temp);
- g_free(temp);
- str_unref (filename);
- }
- else
- formatter_associate(formatter, 'f', "");
-
- g_snprintf(numbuf, sizeof(numbuf), "%02d", pos + 1);
- formatter_associate(formatter, 't', numbuf);
-
- int length = aud_playlist_entry_get_length (playlist, pos, FALSE);
- if (length > 0)
- {
- str_itoa (length, numbuf, sizeof numbuf);
- formatter_associate(formatter, 'l', numbuf);
- }
- else
- formatter_associate(formatter, 'l', "0");
-
- playing = aud_drct_get_playing();
- str_itoa (playing, numbuf, sizeof numbuf);
- formatter_associate(formatter, 'p', numbuf);
-
- if (playing)
- {
- int brate, srate, chans;
- aud_drct_get_info (& brate, & srate, & chans);
- str_itoa (brate, numbuf, sizeof numbuf);
- formatter_associate (formatter, 'r', numbuf);
- str_itoa (srate, numbuf, sizeof numbuf);
- formatter_associate (formatter, 'F', numbuf);
- str_itoa (chans, numbuf, sizeof numbuf);
- formatter_associate (formatter, 'c', numbuf);
- }
-
- Tuple * tuple = aud_playlist_entry_get_tuple
- (aud_playlist_get_active (), pos, 0);
-
- char * artist = tuple ? tuple_get_str (tuple, FIELD_ARTIST) : NULL;
- if (artist)
- {
- formatter_associate(formatter, 'a', artist);
- str_unref(artist);
- }
- else
- formatter_associate(formatter, 'a', "");
-
- char * album = tuple ? tuple_get_str (tuple, FIELD_ALBUM) : NULL;
- if (album)
- {
- formatter_associate(formatter, 'b', album);
- str_unref(album);
- }
- else
- formatter_associate(formatter, 'b', "");
-
- char * title = tuple ? tuple_get_str (tuple, FIELD_TITLE) : NULL;
- if (title)
- {
- formatter_associate(formatter, 'T', title);
- str_unref(title);
- }
- else
- formatter_associate(formatter, 'T', "");
-
- if (tuple)
- tuple_unref (tuple);
-
- shstring = formatter_format(formatter, cmd);
- formatter_destroy(formatter);
-
- if (shstring)
- {
- execute_command(shstring);
- /* FIXME: This can possibly be freed too early */
- g_free(shstring);
- }
- }
-}
-
-static void read_config(void)
-{
- cmd_line = aud_get_str("song_change", "cmd_line");
- cmd_line_after = aud_get_str("song_change", "cmd_line_after");
- cmd_line_end = aud_get_str("song_change", "cmd_line_end");
- cmd_line_ttc = aud_get_str("song_change", "cmd_line_ttc");
-}
-
-static void cleanup(void)
-{
- hook_dissociate("playback begin", songchange_playback_begin);
- hook_dissociate("playback end", songchange_playback_end);
- hook_dissociate("playlist end reached", songchange_playlist_eof);
- // hook_dissociate( "playlist set info" , songchange_playback_ttc);
-
- if ( ttc_prevs != NULL )
- {
- if ( ttc_prevs->title != NULL ) g_free( ttc_prevs->title );
- if ( ttc_prevs->filename != NULL ) g_free( ttc_prevs->filename );
- g_free( ttc_prevs );
- ttc_prevs = NULL;
- }
-
- str_unref(cmd_line);
- str_unref(cmd_line_after);
- str_unref(cmd_line_end);
- str_unref(cmd_line_ttc);
-
- cmd_line = NULL;
- cmd_line_after = NULL;
- cmd_line_end = NULL;
- cmd_line_ttc = NULL;
-
- signal(SIGCHLD, SIG_DFL);
-}
-
-static void save_and_close(gchar * cmd, gchar * cmd_after, gchar * cmd_end, gchar * cmd_ttc)
-{
- aud_set_str("song_change", "cmd_line", cmd);
- aud_set_str("song_change", "cmd_line_after", cmd_after);
- aud_set_str("song_change", "cmd_line_end", cmd_end);
- aud_set_str("song_change", "cmd_line_ttc", cmd_ttc);
-
- str_unref(cmd_line);
- str_unref(cmd_line_after);
- str_unref(cmd_line_end);
- str_unref(cmd_line_ttc);
-
- cmd_line = str_get(cmd);
- cmd_line_after = str_get(cmd_after);
- cmd_line_end = str_get(cmd_end);
- cmd_line_ttc = str_get(cmd_ttc);
-}
-
-static int check_command(char *command)
-{
- const char *dangerous = "fns";
- char *c;
- int qu = 0;
-
- for (c = command; *c != '\0'; c++)
- {
- if (*c == '"' && (c == command || *(c - 1) != '\\'))
- qu = !qu;
- else if (*c == '%' && !qu && strchr(dangerous, *(c + 1)))
- return -1;
- }
- return 0;
-}
-
-static gboolean init (void)
-{
- read_config();
-
- hook_associate("playback begin", songchange_playback_begin, NULL);
- hook_associate("playback end", songchange_playback_end, NULL);
- hook_associate("playlist end reached", songchange_playlist_eof, NULL);
-
- ttc_prevs = g_malloc0(sizeof(songchange_playback_ttc_prevs_t));
- ttc_prevs->title = NULL;
- ttc_prevs->filename = NULL;
- // hook_associate( "playlist set info" , songchange_playback_ttc , ttc_prevs );
-
- return TRUE;
-}
-
-static void songchange_playback_begin(gpointer unused, gpointer unused2)
-{
- do_command (cmd_line);
-}
-
-static void songchange_playback_end(gpointer unused, gpointer unused2)
-{
- do_command (cmd_line_after);
-}
-
-#if 0
- static void
-songchange_playback_ttc(gpointer plentry_gp, gpointer prevs_gp)
-{
- if ( ( aud_ip_state->playing ) && ( strcmp(cmd_line_ttc,"") ) )
- {
- songchange_playback_ttc_prevs_t *prevs = prevs_gp;
- PlaylistEntry *pl_entry = plentry_gp;
-
- /* same filename but title changed, useful to detect http stream song changes */
-
- if ( ( prevs->title != NULL ) && ( prevs->filename != NULL ) )
- {
- if ( ( pl_entry->filename != NULL ) && ( !strcmp(pl_entry->filename,prevs->filename) ) )
- {
- if ( ( pl_entry->title != NULL ) && ( strcmp(pl_entry->title,prevs->title) ) )
- {
- int pos = aud_drct_pl_get_pos();
- char *current_file = aud_drct_pl_get_file(pos);
- do_command(cmd_line_ttc, current_file, pos);
- g_free(current_file);
- g_free(prevs->title);
- prevs->title = g_strdup(pl_entry->title);
- }
- }
- else
- {
- g_free(prevs->filename);
- prevs->filename = g_strdup(pl_entry->filename);
- /* if filename changes, reset title as well */
- if ( prevs->title != NULL )
- g_free(prevs->title);
- prevs->title = g_strdup(pl_entry->title);
- }
- }
- else
- {
- if ( prevs->title != NULL )
- g_free(prevs->title);
- prevs->title = g_strdup(pl_entry->title);
- if ( prevs->filename != NULL )
- g_free(prevs->filename);
- prevs->filename = g_strdup(pl_entry->filename);
- }
- }
-}
-#endif
-
-static void songchange_playlist_eof(gpointer unused, gpointer unused2)
-{
- do_command (cmd_line_end);
-}
-
-typedef struct {
- gchar * cmd;
- gchar * cmd_after;
- gchar * cmd_end;
- gchar * cmd_ttc;
-} SongChangeConfig;
-
-static SongChangeConfig config = {NULL};
-
-static void configure_ok_cb()
-{
- char *cmd, *cmd_after, *cmd_end, *cmd_ttc;
- cmd = g_strdup(config.cmd);
- cmd_after = g_strdup(config.cmd_after);
- cmd_end = g_strdup(config.cmd_end);
- cmd_ttc = g_strdup(config.cmd_ttc);
-
- if (check_command(cmd) < 0 || check_command(cmd_after) < 0 ||
- check_command(cmd_end) < 0 || check_command(cmd_ttc) < 0)
- {
- gtk_widget_show(cmd_warn_img);
- gtk_widget_show(cmd_warn_label);
- }
- else
- {
- gtk_widget_hide(cmd_warn_img);
- gtk_widget_hide(cmd_warn_label);
- save_and_close(cmd, cmd_after, cmd_end, cmd_ttc);
- }
-
- g_free(cmd);
- g_free(cmd_after);
- g_free(cmd_end);
- g_free(cmd_ttc);
-}
-
-static const PreferencesWidget elements[] = {
- {WIDGET_LABEL, N_("Command to run when Audacious starts a new song."),
- .data = {.label = {.single_line = TRUE}}},
- {WIDGET_ENTRY, N_("Command:"), .cfg_type = VALUE_STRING,
- .cfg = & config.cmd, .callback = configure_ok_cb},
- {WIDGET_SEPARATOR, .data = {.separator = {TRUE}}},
-
- {WIDGET_LABEL, N_("Command to run toward the end of a song."),
- .data = {.label = {.single_line = TRUE}}},
- {WIDGET_ENTRY, N_("Command:"), .cfg_type = VALUE_STRING,
- .cfg = & config.cmd_after, .callback = configure_ok_cb},
- {WIDGET_SEPARATOR, .data = {.separator = {TRUE}}},
-
- {WIDGET_LABEL, N_("Command to run when Audacious reaches the end of the "
- "playlist."), .data = {.label = {.single_line = TRUE}}},
- {WIDGET_ENTRY, N_("Command:"), .cfg_type = VALUE_STRING,
- .cfg = & config.cmd_end, .callback = configure_ok_cb},
- {WIDGET_SEPARATOR, .data = {.separator = {TRUE}}},
-
- {WIDGET_LABEL, N_("Command to run when title changes for a song (i.e. "
- "network streams titles)."), .data = {.label = {.single_line = TRUE}}},
- {WIDGET_ENTRY, N_("Command:"), .cfg_type = VALUE_STRING,
- .cfg = & config.cmd_ttc, .callback = configure_ok_cb},
- {WIDGET_SEPARATOR, .data = {.separator = {TRUE}}},
-
- {WIDGET_LABEL, N_("You can use the following format strings which\n"
- "will be substituted before calling the command\n"
- "(not all are useful for the end-of-playlist command):\n\n"
- "%F: Frequency (in hertz)\n"
- "%c: Number of channels\n"
- "%f: File name (full path)\n"
- "%l: Length (in milliseconds)\n"
- "%n or %s: Song name\n"
- "%r: Rate (in bits per second)\n"
- "%t: Playlist position (%02d)\n"
- "%p: Currently playing (1 or 0)\n"
- "%a: Artist\n"
- "%b: Album\n"
- "%T: Track title")},
-};
-
-/* static GtkWidget * custom_warning (void) */
-static void * custom_warning (void)
-{
- GtkWidget *bbox_hbox;
- gchar * temp;
-
- bbox_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
-
- cmd_warn_img = gtk_image_new_from_icon_name("dialog-warning", GTK_ICON_SIZE_MENU);
- gtk_box_pack_start(GTK_BOX(bbox_hbox), cmd_warn_img, FALSE, FALSE, 0);
-
- temp = g_strdup_printf(_("<span size='small'>Parameters passed to the shell should be encapsulated in quotes. Doing otherwise is a security risk.</span>"));
- cmd_warn_label = gtk_label_new(temp);
- gtk_label_set_markup(GTK_LABEL(cmd_warn_label), temp);
- gtk_label_set_line_wrap(GTK_LABEL(cmd_warn_label), TRUE);
- gtk_box_pack_start(GTK_BOX(bbox_hbox), cmd_warn_label, FALSE, FALSE, 0);
- g_free(temp);
-
- return bbox_hbox;
-}
-
-static const PreferencesWidget settings[] = {
- {WIDGET_BOX, N_("Commands"), .data = {.box = {elements, ARRAY_LEN (elements), .frame = TRUE}}},
- {WIDGET_CUSTOM, .data = {.populate = custom_warning}}};
-
-static void configure_init(void)
-{
- read_config();
-
- config.cmd = g_strdup(cmd_line);
- config.cmd_after = g_strdup(cmd_line_after);
- config.cmd_end = g_strdup(cmd_line_end);
- config.cmd_ttc = g_strdup(cmd_line_ttc);
-}
-
-static void configure_cleanup(void)
-{
- g_free(config.cmd);
- config.cmd = NULL;
-
- g_free(config.cmd_after);
- config.cmd_after = NULL;
-
- g_free(config.cmd_end);
- config.cmd_end = NULL;
-
- g_free(config.cmd_ttc);
- config.cmd_ttc = NULL;
-}
-
-static const PluginPreferences preferences = {
- .widgets = settings,
- .n_widgets = ARRAY_LEN (settings),
- .init = configure_init,
- .cleanup = configure_cleanup,
-};
diff --git a/src/song_change/song_change.cc b/src/song_change/song_change.cc
new file mode 100644
index 000000000000..10a444bf0f16
--- /dev/null
+++ b/src/song_change/song_change.cc
@@ -0,0 +1,415 @@
+/*
+ * Audacious: A cross-platform multimedia player.
+ * Copyright (c) 2005 Audacious Team
+ */
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <signal.h>
+#include <unistd.h>
+
+#include <string.h>
+
+#include <libaudcore/runtime.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/tuple.h>
+
+#include "formatter.h"
+
+class SongChange : public GeneralPlugin
+{
+public:
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Song Change"),
+ PACKAGE,
+ nullptr,
+ & prefs
+ };
+
+ constexpr SongChange () : GeneralPlugin (info, false) {}
+
+ bool init ();
+ void cleanup ();
+};
+
+EXPORT SongChange aud_plugin_instance;
+
+static void songchange_playback_begin(void *, void *);
+static void songchange_playback_end(void *, void *);
+static void songchange_playlist_eof(void *, void *);
+static void songchange_playback_ttc(void *, void *);
+
+static String cmd_line;
+static String cmd_line_after;
+static String cmd_line_end;
+static String cmd_line_ttc;
+
+static GtkWidget *cmd_warn_label, *cmd_warn_img;
+
+/**
+ * Escapes characters that are special to the shell inside double quotes.
+ *
+ * @param string String to be escaped.
+ * @return Given string with special characters escaped. Must be freed with g_free().
+ */
+static char *escape_shell_chars(const char * string)
+{
+ const char *special = "$`\"\\"; /* Characters to escape */
+ const char *in = string;
+ char *out, *escaped;
+ int num = 0;
+
+ while (*in != '\0')
+ if (strchr(special, *in++))
+ num++;
+
+ escaped = g_new(char, strlen(string) + num + 1);
+
+ in = string;
+ out = escaped;
+
+ while (*in != '\0') {
+ if (strchr(special, *in))
+ *out++ = '\\';
+ *out++ = *in++;
+ }
+ *out = '\0';
+
+ return escaped;
+}
+
+static void bury_child(int signal)
+{
+ waitpid(-1, nullptr, WNOHANG);
+}
+
+static void execute_command(char *cmd)
+{
+ const char *argv[4] = {"/bin/sh", "-c", nullptr, nullptr};
+ int i;
+ argv[2] = cmd;
+ signal(SIGCHLD, bury_child);
+ if (fork() == 0)
+ {
+ /* We don't want this process to hog the audio device etc */
+ for (i = 3; i < 255; i++)
+ close(i);
+ execv("/bin/sh", (char **)argv);
+ }
+}
+
+/* Format codes:
+ *
+ * F - frequency (in hertz)
+ * c - number of channels
+ * f - filename (full path)
+ * l - length (in milliseconds)
+ * n - name
+ * r - rate (in bits per second)
+ * s - name (since everyone's used to it)
+ * t - playlist position (%02d)
+ * p - currently playing (1 or 0)
+ * a - artist
+ * b - album
+ * r - track title
+ */
+/* do_command(): do @cmd after replacing the format codes
+ @cmd: command to run */
+static void do_command (const char * cmd)
+{
+ char *shstring = nullptr, *temp;
+ gboolean playing;
+ Formatter *formatter;
+
+ if (cmd && strlen(cmd) > 0)
+ {
+ formatter = formatter_new();
+
+ playing = aud_drct_get_ready();
+
+ Tuple tuple;
+ if (playing)
+ tuple = aud_drct_get_tuple ();
+
+ String ctitle = tuple.get_str (Tuple::FormattedTitle);
+ if (ctitle)
+ {
+ temp = escape_shell_chars (ctitle);
+ formatter_associate(formatter, 's', temp);
+ formatter_associate(formatter, 'n', temp);
+ g_free(temp);
+ }
+ else
+ {
+ formatter_associate(formatter, 's', "");
+ formatter_associate(formatter, 'n', "");
+ }
+
+ String filename = aud_drct_get_filename ();
+ if (filename)
+ {
+ temp = escape_shell_chars (filename);
+ formatter_associate(formatter, 'f', temp);
+ g_free(temp);
+ }
+ else
+ formatter_associate(formatter, 'f', "");
+
+ if (playing)
+ {
+ int pos = aud_drct_get_position ();
+ formatter_associate (formatter, 't', str_printf ("%02d", pos + 1));
+ }
+ else
+ formatter_associate (formatter, 't', "");
+
+ int length = tuple.get_int (Tuple::Length);
+ if (length > 0)
+ formatter_associate(formatter, 'l', int_to_str (length));
+ else
+ formatter_associate(formatter, 'l', "0");
+
+ formatter_associate(formatter, 'p', int_to_str (playing));
+
+ if (playing)
+ {
+ int brate, srate, chans;
+ aud_drct_get_info (brate, srate, chans);
+ formatter_associate (formatter, 'r', int_to_str (brate));
+ formatter_associate (formatter, 'F', int_to_str (srate));
+ formatter_associate (formatter, 'c', int_to_str (chans));
+ }
+
+ String artist = tuple.get_str (Tuple::Artist);
+ if (artist)
+ formatter_associate(formatter, 'a', artist);
+ else
+ formatter_associate(formatter, 'a', "");
+
+ String album = tuple.get_str (Tuple::Album);
+ if (album)
+ formatter_associate(formatter, 'b', album);
+ else
+ formatter_associate(formatter, 'b', "");
+
+ String title = tuple.get_str (Tuple::Title);
+ if (title)
+ formatter_associate(formatter, 'T', title);
+ else
+ formatter_associate(formatter, 'T', "");
+
+ shstring = formatter_format(formatter, cmd);
+ formatter_destroy(formatter);
+
+ if (shstring)
+ {
+ execute_command(shstring);
+ /* FIXME: This can possibly be freed too early */
+ g_free(shstring);
+ }
+ }
+}
+
+static void read_config(void)
+{
+ cmd_line = aud_get_str("song_change", "cmd_line");
+ cmd_line_after = aud_get_str("song_change", "cmd_line_after");
+ cmd_line_end = aud_get_str("song_change", "cmd_line_end");
+ cmd_line_ttc = aud_get_str("song_change", "cmd_line_ttc");
+}
+
+void SongChange::cleanup ()
+{
+ hook_dissociate("playback ready", songchange_playback_begin);
+ hook_dissociate("playback end", songchange_playback_end);
+ hook_dissociate("playlist end reached", songchange_playlist_eof);
+ hook_dissociate("title change", songchange_playback_ttc);
+
+ cmd_line = String ();
+ cmd_line_after = String ();
+ cmd_line_end = String ();
+ cmd_line_ttc = String ();
+
+ signal(SIGCHLD, SIG_DFL);
+}
+
+static int check_command(const char *command)
+{
+ const char *dangerous = "fns";
+ const char *c;
+ int qu = 0;
+
+ for (c = command; *c != '\0'; c++)
+ {
+ if (*c == '"' && (c == command || *(c - 1) != '\\'))
+ qu = !qu;
+ else if (*c == '%' && !qu && strchr(dangerous, *(c + 1)))
+ return -1;
+ }
+ return 0;
+}
+
+bool SongChange::init ()
+{
+ read_config();
+
+ hook_associate("playback ready", songchange_playback_begin, nullptr);
+ hook_associate("playback end", songchange_playback_end, nullptr);
+ hook_associate("playlist end reached", songchange_playlist_eof, nullptr);
+ hook_associate("title change", songchange_playback_ttc, nullptr);
+
+ return TRUE;
+}
+
+static void songchange_playback_begin(void *, void *)
+{
+ do_command (cmd_line);
+}
+
+static void songchange_playback_end(void *, void *)
+{
+ do_command (cmd_line_after);
+}
+
+static void songchange_playback_ttc(void *, void *)
+{
+ do_command (cmd_line_ttc);
+}
+
+static void songchange_playlist_eof(void *, void *)
+{
+ do_command (cmd_line_end);
+}
+
+typedef struct {
+ String cmd;
+ String cmd_after;
+ String cmd_end;
+ String cmd_ttc;
+} SongChangeConfig;
+
+static SongChangeConfig config;
+
+static void edit_cb()
+{
+ if (check_command(config.cmd) < 0 || check_command(config.cmd_after) < 0 ||
+ check_command(config.cmd_end) < 0 || check_command(config.cmd_ttc) < 0)
+ {
+ gtk_widget_show(cmd_warn_img);
+ gtk_widget_show(cmd_warn_label);
+ }
+ else
+ {
+ gtk_widget_hide(cmd_warn_img);
+ gtk_widget_hide(cmd_warn_label);
+ }
+}
+
+static void configure_ok_cb()
+{
+ aud_set_str("song_change", "cmd_line", config.cmd);
+ aud_set_str("song_change", "cmd_line_after", config.cmd_after);
+ aud_set_str("song_change", "cmd_line_end", config.cmd_end);
+ aud_set_str("song_change", "cmd_line_ttc", config.cmd_ttc);
+
+ cmd_line = config.cmd;
+ cmd_line_after = config.cmd_after;
+ cmd_line_end = config.cmd_end;
+ cmd_line_ttc = config.cmd_ttc;
+}
+
+/* static GtkWidget * custom_warning (void) */
+static void * custom_warning (void)
+{
+ GtkWidget *bbox_hbox;
+ char * temp;
+
+ bbox_hbox = gtk_hbox_new (FALSE, 6);
+
+ cmd_warn_img = gtk_image_new_from_icon_name("dialog-warning", GTK_ICON_SIZE_MENU);
+ gtk_box_pack_start(GTK_BOX(bbox_hbox), cmd_warn_img, FALSE, FALSE, 0);
+
+ temp = g_strdup_printf(_("<span size='small'>Parameters passed to the shell should be encapsulated in quotes. Doing otherwise is a security risk.</span>"));
+ cmd_warn_label = gtk_label_new(temp);
+ gtk_label_set_markup(GTK_LABEL(cmd_warn_label), temp);
+ gtk_label_set_line_wrap(GTK_LABEL(cmd_warn_label), TRUE);
+ gtk_box_pack_start(GTK_BOX(bbox_hbox), cmd_warn_label, FALSE, FALSE, 0);
+ g_free(temp);
+
+ gtk_widget_set_no_show_all(cmd_warn_img, TRUE);
+ gtk_widget_set_no_show_all(cmd_warn_label, TRUE);
+
+ edit_cb();
+
+ return bbox_hbox;
+}
+
+const PreferencesWidget SongChange::widgets[] = {
+ WidgetLabel (N_("<b>Commands</b>")),
+
+ WidgetLabel (N_("Command to run when starting a new song:")),
+ WidgetEntry (0, WidgetString (config.cmd, edit_cb)),
+ WidgetSeparator ({true}),
+
+ WidgetLabel (N_("Command to run at the end of a song:")),
+ WidgetEntry (0, WidgetString (config.cmd_after, edit_cb)),
+ WidgetSeparator ({true}),
+
+ WidgetLabel (N_("Command to run at the end of the playlist:")),
+ WidgetEntry (0, WidgetString (config.cmd_end, edit_cb)),
+ WidgetSeparator ({true}),
+
+ WidgetLabel (N_("Command to run when song title changes (for network streams):")),
+ WidgetEntry (0, WidgetString (config.cmd_ttc, edit_cb)),
+ WidgetSeparator ({true}),
+
+ WidgetLabel (N_("You can use the following format strings which "
+ "will be substituted before calling the command "
+ "(not all are useful for the end-of-playlist command):\n\n"
+ "%F: Frequency (in hertz)\n"
+ "%c: Number of channels\n"
+ "%f: File name (full path)\n"
+ "%l: Length (in milliseconds)\n"
+ "%n or %s: Song name\n"
+ "%r: Rate (in bits per second)\n"
+ "%t: Playlist position (%02d)\n"
+ "%p: Currently playing (1 or 0)\n"
+ "%a: Artist\n"
+ "%b: Album\n"
+ "%T: Track title")),
+
+ WidgetCustomGTK (custom_warning)
+};
+
+static void configure_init(void)
+{
+ config.cmd = cmd_line;
+ config.cmd_after = cmd_line_after;
+ config.cmd_end = cmd_line_end;
+ config.cmd_ttc = cmd_line_ttc;
+}
+
+static void configure_cleanup(void)
+{
+ config.cmd = String ();
+ config.cmd_after = String ();
+ config.cmd_end = String ();
+ config.cmd_ttc = String ();
+}
+
+const PluginPreferences SongChange::prefs = {
+ {widgets},
+ configure_init,
+ configure_ok_cb,
+ configure_cleanup,
+};
diff --git a/src/sox-resampler/Makefile b/src/sox-resampler/Makefile
index 57154da70ed8..bc3bcd9a8cc0 100644
--- a/src/sox-resampler/Makefile
+++ b/src/sox-resampler/Makefile
@@ -1,12 +1,13 @@
PLUGIN = sox-resampler${PLUGIN_SUFFIX}
-SRCS = sox-resampler.c
+SRCS = sox-resampler.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS} -lsoxr
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
+LIBS += -lsoxr
diff --git a/src/sox-resampler/sox-resampler.c b/src/sox-resampler/sox-resampler.c
deleted file mode 100644
index d9c86d562a5e..000000000000
--- a/src/sox-resampler/sox-resampler.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * SoX Resampler Plugin for Audacious
- * Copyright 2013 MichaÅ Lipski
- *
- * Based on Sample Rate Converter Plugin:
- * Copyright 2010-2012 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include <soxr.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-#define MIN_RATE 8000
-#define MAX_RATE 192000
-#define RATE_STEP 50
-
-#define RESAMPLER_ERROR(e) fprintf (stderr, "sox-resampler: %s\n", e)
-
-static const char * const sox_resampler_defaults[] = {
- "quality", "4", /* SOXR_HQ */
- "rate", "44100",
- NULL};
-
-static soxr_t soxr;
-static soxr_error_t error;
-static int stored_channels;
-static double ratio;
-static float * buffer;
-static size_t buffer_samples;
-
-bool_t sox_resampler_init (void)
-{
- aud_config_set_defaults ("soxr", sox_resampler_defaults);
- return TRUE;
-}
-
-void sox_resampler_cleanup (void)
-{
- soxr_delete (soxr);
- soxr = 0;
- g_free (buffer);
- buffer = NULL;
- buffer_samples = 0;
-}
-
-void sox_resampler_start (int * channels, int * rate)
-{
- soxr_delete (soxr);
- soxr = 0;
-
- int new_rate = aud_get_int ("soxr", "rate");
- new_rate = CLAMP (new_rate, MIN_RATE, MAX_RATE);
-
- if (new_rate == * rate)
- return;
-
- soxr_quality_spec_t q = soxr_quality_spec(aud_get_int ("soxr", "quality"), 0);
-
- soxr = soxr_create((double) * rate, (double) new_rate, * channels, & error, NULL, & q, NULL);
-
- if (error)
- {
- RESAMPLER_ERROR (error);
- return;
- }
-
- stored_channels = * channels;
- ratio = (double) new_rate / * rate;
- * rate = new_rate;
-}
-
-void do_resample (float * * data, int * samples)
-{
- if (! soxr)
- return;
-
- if (buffer_samples < (int) (* samples * ratio) + 256)
- {
- buffer_samples = (int) (* samples * ratio) + 256;
- buffer = g_renew (float, buffer, buffer_samples);
- }
-
- size_t samples_done;
-
- error = soxr_process(soxr, * data, * samples / stored_channels, NULL,
- buffer, buffer_samples / stored_channels, & samples_done);
-
- if (error)
- {
- RESAMPLER_ERROR (error);
- return;
- }
-
- * data = buffer;
- * samples = samples_done * stored_channels;
-}
-
-void sox_resampler_process (float * * data, int * samples)
-{
- do_resample (data, samples);
-}
-
-void sox_resampler_flush (void)
-{
- if (soxr && (error = soxr_process(soxr, NULL, 0, NULL, NULL, 0, NULL)))
- RESAMPLER_ERROR (error);
-}
-
-void sox_resampler_finish (float * * data, int * samples)
-{
- do_resample (data, samples);
-}
-
-static const char sox_resampler_about[] =
- N_("SoX Resampler Plugin for Audacious\n"
- "Copyright 2013 MichaÅ Lipski\n\n"
- "Based on Sample Rate Converter Plugin:\n"
- "Copyright 2010-2012 John Lindgren");
-
-static const ComboBoxElements method_list[] = {
- {"0", N_("Quick")}, /* SOXR_QQ */
- {"1", N_("Low")}, /* SOXR_QL */
- {"2", N_("Medium")}, /* SOXR_QM */
- {"4", N_("High")}, /* SOXR_QH */
- {"6", N_("Very High")}}; /* SOXR_VHQ */
-
-static const PreferencesWidget sox_resampler_widgets[] = {
- {WIDGET_COMBO_BOX, N_("Quality:"),
- .cfg_type = VALUE_STRING, .csect = "soxr", .cname = "quality",
- .data = {.combo = {method_list, ARRAY_LEN (method_list)}}},
- {WIDGET_SPIN_BTN, N_("Rate:"),
- .cfg_type = VALUE_INT, .csect = "soxr", .cname = "rate",
- .data = {.spin_btn = {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")}}}
-};
-
-static const PluginPreferences sox_resampler_prefs = {
- .widgets = sox_resampler_widgets,
- .n_widgets = ARRAY_LEN (sox_resampler_widgets)};
-
-AUD_EFFECT_PLUGIN
-(
- .name = N_("SoX Resampler"),
- .domain = PACKAGE,
- .about_text = sox_resampler_about,
- .prefs = & sox_resampler_prefs,
- .init = sox_resampler_init,
- .cleanup = sox_resampler_cleanup,
- .start = sox_resampler_start,
- .process = sox_resampler_process,
- .flush = sox_resampler_flush,
- .finish = sox_resampler_finish,
- .order = 2 /* must be before crossfade */
-)
diff --git a/src/sox-resampler/sox-resampler.cc b/src/sox-resampler/sox-resampler.cc
new file mode 100644
index 000000000000..43cbe61a8924
--- /dev/null
+++ b/src/sox-resampler/sox-resampler.cc
@@ -0,0 +1,166 @@
+/*
+ * SoX Resampler Plugin for Audacious
+ * Copyright 2013 MichaÅ Lipski
+ *
+ * Based on Sample Rate Converter Plugin:
+ * Copyright 2010-2012 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <stdlib.h>
+#include <soxr.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+
+#define MIN_RATE 8000
+#define MAX_RATE 192000
+#define RATE_STEP 50
+
+class SoXResampler : public EffectPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("SoX Resampler"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ /* order #2: must be before crossfade */
+ constexpr SoXResampler () : EffectPlugin (info, 2, false) {}
+
+ bool init ();
+ void cleanup ();
+
+ void start (int & channels, int & rate);
+ Index<float> & process (Index<float> & data);
+ bool flush (bool force);
+};
+
+EXPORT SoXResampler aud_plugin_instance;
+
+const char * const SoXResampler::defaults[] = {
+ "quality", aud::numeric_string<SOXR_HQ>::str,
+ "rate", "44100",
+ nullptr};
+
+static soxr_t soxr;
+static soxr_error_t error;
+static int stored_channels;
+static double ratio;
+static Index<float> buffer;
+
+bool SoXResampler::init ()
+{
+ aud_config_set_defaults ("soxr", defaults);
+ return true;
+}
+
+void SoXResampler::cleanup ()
+{
+ soxr_delete (soxr);
+ soxr = 0;
+ buffer.clear ();
+}
+
+void SoXResampler::start (int & channels, int & rate)
+{
+ soxr_delete (soxr);
+ soxr = 0;
+
+ int new_rate = aud_get_int ("soxr", "rate");
+ new_rate = aud::clamp (new_rate, MIN_RATE, MAX_RATE);
+
+ if (new_rate == rate)
+ return;
+
+ soxr_quality_spec_t q = soxr_quality_spec(aud_get_int ("soxr", "quality"), 0);
+
+ soxr = soxr_create(rate, new_rate, channels, & error, nullptr, & q, nullptr);
+
+ if (error)
+ {
+ AUDERR (error);
+ return;
+ }
+
+ stored_channels = channels;
+ ratio = (double) new_rate / rate;
+ rate = new_rate;
+}
+
+Index<float> & SoXResampler::process (Index<float> & data)
+{
+ if (! soxr)
+ return data;
+
+ buffer.resize ((int) (data.len () * ratio) + 256);
+
+ size_t samples_done;
+ error = soxr_process (soxr, data.begin (), data.len () / stored_channels,
+ nullptr, buffer.begin (), buffer.len () / stored_channels, & samples_done);
+
+ if (error)
+ {
+ AUDERR (error);
+ return data;
+ }
+
+ buffer.resize (samples_done * stored_channels);
+
+ return buffer;
+}
+
+bool SoXResampler::flush (bool force)
+{
+ if (soxr && (error = soxr_process(soxr, nullptr, 0, nullptr, nullptr, 0, nullptr)))
+ AUDERR (error);
+
+ return true;
+}
+
+const char SoXResampler::about[] =
+ N_("SoX Resampler Plugin for Audacious\n"
+ "Copyright 2013 MichaÅ Lipski\n\n"
+ "Based on Sample Rate Converter Plugin:\n"
+ "Copyright 2010-2012 John Lindgren");
+
+static const ComboItem method_list[] = {
+ ComboItem (N_("Quick"), SOXR_QQ),
+ ComboItem (N_("Low"), SOXR_LQ),
+ ComboItem (N_("Medium"), SOXR_MQ),
+ ComboItem (N_("High"), SOXR_HQ),
+ ComboItem (N_("Very High"), SOXR_VHQ)
+};
+
+const PreferencesWidget SoXResampler::widgets[] = {
+ WidgetCombo (N_("Quality:"),
+ WidgetInt ("soxr", "quality"),
+ {{method_list}}),
+ WidgetSpin (N_("Rate:"),
+ WidgetInt ("soxr", "rate"),
+ {MIN_RATE, MAX_RATE, RATE_STEP, N_("Hz")})
+};
+
+const PluginPreferences SoXResampler::prefs = {{widgets}};
diff --git a/src/speed-pitch/Makefile b/src/speed-pitch/Makefile
index 635e22bcb110..41a00d5add83 100644
--- a/src/speed-pitch/Makefile
+++ b/src/speed-pitch/Makefile
@@ -1,12 +1,13 @@
PLUGIN = speed-pitch${PLUGIN_SUFFIX}
-SRCS = speed-pitch.c
+SRCS = speed-pitch.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
+LD = ${CXX}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
CFLAGS += ${PLUGIN_CFLAGS}
-LIBS += -lm ${GLIB_LIBS} -lsamplerate
+LIBS += -lm -lsamplerate
diff --git a/src/speed-pitch/speed-pitch.c b/src/speed-pitch/speed-pitch.c
deleted file mode 100644
index 94a996a3ae90..000000000000
--- a/src/speed-pitch/speed-pitch.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Speed and Pitch effect plugin for Audacious
- * Copyright 2012 John Lindgren
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions, and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions, and the following disclaimer in the documentation
- * provided with the distribution.
- *
- * This software is provided "as is" and without any warranty, express or
- * implied. In no event shall the authors be liable for any damages arising from
- * the use of this software.
- */
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <samplerate.h>
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-/* The general idea of the speed change algorithm is to divide the input signal
- * into pieces, spaced at a time interval A, using a cosine-shaped window
- * function. The pieces are then reassembled by adding them together again,
- * spaced at another time interval B. By varying the ratio A:B, we change the
- * speed of the audio. To get better results at the two ends of a song, we add
- * a short period of silence (half the width of the cosine window, to be exact)
- * to each end of the input signal beforehand and afterwards trim the same
- * amount from each end of the output signal. */
-
-#define FREQ 10
-#define OVERLAP 3
-
-#define CFGSECT "speed-pitch"
-#define MINSPEED 0.5
-#define MAXSPEED 2.0
-#define MINPITCH 0.5
-#define MAXPITCH 2.0
-
-#define BYTES(frames) ((frames) * curchans * sizeof (float))
-#define OFFSET(buf,frames) ((buf) + (frames) * curchans)
-
-typedef struct {
- float * mem;
- int size, len;
-} Buffer;
-
-static int curchans, currate;
-static SRC_STATE * srcstate;
-static int outstep, width;
-static double * cosine;
-static Buffer in, out;
-static int trim, written;
-static bool_t ending;
-
-static void bufgrow (Buffer * b, int len)
-{
- if (len > b->size)
- {
- b->mem = g_realloc (b->mem, BYTES (len));
- b->size = len;
- }
-
- if (len > b->len)
- {
- memset (OFFSET (b->mem, b->len), 0, BYTES (len - b->len));
- b->len = len;
- }
-}
-
-static void bufcut (Buffer * b, int len)
-{
- memmove (b->mem, OFFSET (b->mem, len), BYTES (b->len - len));
- b->len -= len;
-}
-
-static void bufadd (Buffer * b, float * data, int len, double ratio)
-{
- int oldlen = b->len;
- int max = len * ratio + 100;
- bufgrow (b, oldlen + max);
-
- SRC_DATA d = {
- .data_in = data,
- .input_frames = len,
- .data_out = OFFSET (b->mem, oldlen),
- .output_frames = max,
- .src_ratio = ratio};
-
- src_process (srcstate, & d);
- b->len = oldlen + d.output_frames_gen;
-}
-
-static void speed_flush (void)
-{
- src_reset (srcstate);
-
- in.len = 0;
- out.len = 0;
-
- /* Add silence to the beginning of the input signal. */
- bufgrow (& in, width / 2);
-
- trim = width / 2;
- written = 0;
- ending = FALSE;
-}
-
-static void speed_start (int * chans, int * rate)
-{
- curchans = * chans;
- currate = * rate;
-
- if (srcstate)
- src_delete (srcstate);
-
- srcstate = src_new (SRC_LINEAR, curchans, NULL);
-
- /* Calculate the width of the cosine window and the spacing interval for
- * output. */
- outstep = currate / FREQ;
- width = outstep * OVERLAP;
-
- /* Generate the cosine window, scaled vertically to compensate for the
- * overlap of the reassembled pieces of audio. */
- cosine = g_realloc (cosine, width * sizeof (double));
- for (int i = 0; i < width; i ++)
- cosine[i] = (1.0 - cos (2.0 * M_PI * i / width)) / OVERLAP;
-
- speed_flush ();
-}
-
-static void speed_process (float * * data, int * samples)
-{
- double pitch = aud_get_double (CFGSECT, "pitch");
- double speed = aud_get_double (CFGSECT, "speed");
-
- /* Remove audio that has already been played from the output buffer. */
- bufcut (& out, written);
-
- /* Copy the passed audio to the input buffer, scaled to adjust pitch. */
- bufadd (& in, * data, * samples / curchans, 1.0 / pitch);
-
- /* If we are ending, add silence to the end of the input signal. */
- if (ending)
- bufgrow (& in, in.len + width / 2);
-
- /* Calculate the spacing interval for input. */
- int instep = round (outstep * speed / pitch);
-
- /* Run the speed change algorithm. */
- int src = 0;
- int dst = 0;
-
- while (src + MAX (width, instep) <= in.len)
- {
- bufgrow (& out, dst + width);
- out.len = dst + width;
-
- for (int i = 0; i < width; i ++)
- for (int c = 0; c < curchans; c ++)
- OFFSET (out.mem, dst + i)[c] += OFFSET (in.mem, src + i)[c] * cosine[i];
-
- src += instep;
- dst += outstep;
- }
-
- /* Remove processed audio from the input buffer. */
- bufcut (& in, src);
-
- /* Trim silence from the beginning of the output buffer. */
- if (trim > 0)
- {
- int cut = MIN (trim, dst);
- bufcut (& out, cut);
- dst -= cut;
- trim -= cut;
- }
-
- /* If we are ending, return all of the output buffer except the silence that
- * we trim from the end of it. */
- if (ending)
- dst = out.len - width / 2;
-
- /* Return processed audio in the output buffer and mark it to be removed on
- * the next call. */
- * data = out.mem;
- * samples = dst * curchans;
- written = dst;
-}
-
-static void speed_finish (float * * data, int * samples)
-{
- /* Ignore the second "end of playlist" call since we are not in a state to
- * handle it properly. */
- if (! ending)
- {
- ending = TRUE;
- speed_process (data, samples);
- }
-}
-
-static int speed_adjust_delay (int delay)
-{
- /* Not sample-accurate, but should be a decent estimate. */
- double speed = aud_get_double (CFGSECT, "speed");
- return delay * speed + width * 1000 / currate;
-}
-
-static const char * const speed_defaults[] = {
- "speed", "1",
- "pitch", "1",
- NULL};
-
-static const PreferencesWidget speed_widgets[] = {
- {WIDGET_LABEL, N_("<b>Speed and Pitch</b>")},
- {WIDGET_SPIN_BTN, N_("Speed:"),
- .cfg_type = VALUE_FLOAT, .csect = CFGSECT, .cname = "speed",
- .data = {.spin_btn = {MINSPEED, MAXSPEED, 0.05}}},
- {WIDGET_SPIN_BTN, N_("Pitch:"),
- .cfg_type = VALUE_FLOAT, .csect = CFGSECT, .cname = "pitch",
- .data = {.spin_btn = {MINPITCH, MAXPITCH, 0.05}}}};
-
-static const PluginPreferences speed_prefs = {
- .widgets = speed_widgets,
- .n_widgets = ARRAY_LEN (speed_widgets)};
-
-static bool_t speed_init (void)
-{
- aud_config_set_defaults (CFGSECT, speed_defaults);
- return TRUE;
-}
-
-static void speed_cleanup (void)
-{
- if (srcstate)
- src_delete (srcstate);
-
- srcstate = NULL;
-
- g_free (cosine);
- cosine = NULL;
-
- g_free (in.mem);
- in.mem = NULL;
- in.size = 0;
-
- g_free (out.mem);
- out.mem = NULL;
- out.size = 0;
-}
-
-AUD_EFFECT_PLUGIN
-(
- .name = N_("Speed and Pitch"),
- .domain = PACKAGE,
- .prefs = & speed_prefs,
- .init = speed_init,
- .cleanup = speed_cleanup,
- .start = speed_start,
- .process = speed_process,
- .flush = speed_flush,
- .finish = speed_finish,
- .adjust_delay = speed_adjust_delay,
- .preserves_format = TRUE
-)
diff --git a/src/speed-pitch/speed-pitch.cc b/src/speed-pitch/speed-pitch.cc
new file mode 100644
index 000000000000..17acca47fdf9
--- /dev/null
+++ b/src/speed-pitch/speed-pitch.cc
@@ -0,0 +1,237 @@
+/*
+ * Speed and Pitch effect plugin for Audacious
+ * Copyright 2012 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include <math.h>
+#include <samplerate.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+
+/* The general idea of the speed change algorithm is to divide the input signal
+ * into pieces, spaced at a time interval A, using a cosine-shaped window
+ * function. The pieces are then reassembled by adding them together again,
+ * spaced at another time interval B. By varying the ratio A:B, we change the
+ * speed of the audio. */
+
+#define FREQ 10
+#define OVERLAP 3
+
+#define CFGSECT "speed-pitch"
+#define MINSPEED 0.5
+#define MAXSPEED 2.0
+#define MINPITCH 0.5
+#define MAXPITCH 2.0
+
+class SpeedPitch : public EffectPlugin
+{
+public:
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Speed and Pitch"),
+ PACKAGE,
+ nullptr,
+ & prefs
+ };
+
+ constexpr SpeedPitch () : EffectPlugin (info, 0, true) {}
+
+ bool init ();
+ void cleanup ();
+
+ void start (int & channels, int & rate);
+ bool flush (bool force);
+ int adjust_delay (int delay);
+
+ Index<float> & process (Index<float> & samples)
+ { return process (samples, false); }
+ Index<float> & finish (Index<float> & samples, bool end_of_playlist)
+ { return process (samples, true); }
+
+private:
+ Index<float> & process (Index<float> & samples, bool ending);
+};
+
+EXPORT SpeedPitch aud_plugin_instance;
+
+static int curchans, currate;
+static SRC_STATE * srcstate;
+static int outstep, width;
+static Index<float> cosine;
+static Index<float> in, out;
+static int src, dst;
+
+static void add_data (Index<float> & b, Index<float> & data, float ratio)
+{
+ int oldlen = b.len ();
+ int inframes = data.len () / curchans;
+ int maxframes = (int) (inframes * ratio) + 256;
+ b.resize (oldlen + maxframes * curchans);
+
+ SRC_DATA d = SRC_DATA ();
+
+ d.data_in = data.begin ();
+ d.input_frames = inframes;
+ d.data_out = & b[oldlen];
+ d.output_frames = maxframes;
+ d.src_ratio = ratio;
+
+ src_process (srcstate, & d);
+ b.resize (oldlen + d.output_frames_gen * curchans);
+}
+
+bool SpeedPitch::flush (bool force)
+{
+ src_reset (srcstate);
+
+ in.resize (0);
+ out.resize (0);
+
+ /* The source and destination pointers give the center of the next cosine
+ * window to be copied, relative to the current input and output buffers. */
+ src = dst = 0;
+
+ /* The output buffer always extends right of the destination pointer by half
+ * the width of a cosine window. */
+ out.insert (0, width / 2);
+
+ return true;
+}
+
+void SpeedPitch::start (int & chans, int & rate)
+{
+ curchans = chans;
+ currate = rate;
+
+ if (srcstate)
+ src_delete (srcstate);
+
+ srcstate = src_new (SRC_LINEAR, curchans, nullptr);
+
+ /* Calculate the width of the cosine window and the spacing interval for
+ * output. Make them both even numbers for convenience. Note that the
+ * cosine window is applied without deinterleaving the audio samples. */
+ outstep = ((currate / FREQ) & ~1) * curchans;
+ width = outstep * OVERLAP;
+
+ /* Generate the cosine window, scaled vertically to compensate for the
+ * overlap of the reassembled pieces of audio. */
+ cosine.resize (width);
+ for (int i = 0; i < width; i ++)
+ cosine[i] = (1.0 - cos (2.0 * M_PI * i / width)) / OVERLAP;
+
+ flush (true);
+}
+
+Index<float> & SpeedPitch::process (Index<float> & data, bool ending)
+{
+ const float * cosine_center = & cosine[width / 2];
+ float pitch = aud_get_double (CFGSECT, "pitch");
+ float speed = aud_get_double (CFGSECT, "speed");
+
+ /* Copy the passed audio to the input buffer, scaled to adjust pitch. */
+ add_data (in, data, 1.0 / pitch);
+
+ /* Calculate the spacing interval for input. */
+ int instep = (int) round ((outstep / curchans) * speed / pitch) * curchans;
+
+ /* Stop copying half a window's width before the end of the input buffer (or
+ * right up to the end of the buffer if the song is ending). */
+ int stop = in.len () - (ending ? 0 : width / 2);
+
+ while (src <= stop)
+ {
+ /* Truncate the window to avoid overflows if necessary. */
+ int begin = aud::max (-(width / 2), aud::max (-src, -dst));
+ int end = aud::min (width / 2, aud::min (in.len () - src, out.len () - dst));
+
+ for (int i = begin; i < end; i ++)
+ out[dst + i] += in[src + i] * cosine_center[i];
+
+ src += instep;
+ dst += outstep;
+
+ out.insert (-1, outstep);
+ }
+
+ /* Discard input up to half a window's width before the source pointer (or
+ * right up to the previous source pointer if the song is ending. */
+ int seek = aud::clamp (0, src - (ending ? instep : width / 2), in.len ());
+ in.remove (0, seek);
+ src -= seek;
+
+ data.resize (0);
+
+ /* Return output up to half a window's width before the destination pointer
+ * (or right up to the previous destination pointer if the song is ending). */
+ int ret = aud::clamp (0, dst - (ending ? outstep : width / 2), out.len ());
+ data.move_from (out, 0, 0, ret, true, true);
+ dst -= ret;
+
+ return data;
+}
+
+int SpeedPitch::adjust_delay (int delay)
+{
+ float samples_to_ms = 1000.0 / (curchans * currate);
+ float speed = aud_get_double (CFGSECT, "speed");
+ int in_samples = in.len () - src;
+ int out_samples = dst;
+
+ return (delay + in_samples * samples_to_ms) * speed + out_samples * samples_to_ms;
+}
+
+const char * const SpeedPitch::defaults[] = {
+ "speed", "1",
+ "pitch", "1",
+ nullptr};
+
+const PreferencesWidget SpeedPitch::widgets[] = {
+ WidgetLabel (N_("<b>Speed and Pitch</b>")),
+ WidgetSpin (N_("Speed:"),
+ WidgetFloat (CFGSECT, "speed"),
+ {MINSPEED, MAXSPEED, 0.05}),
+ WidgetSpin (N_("Pitch:"),
+ WidgetFloat (CFGSECT, "pitch"),
+ {MINPITCH, MAXPITCH, 0.05})
+};
+
+const PluginPreferences SpeedPitch::prefs = {{widgets}};
+
+bool SpeedPitch::init ()
+{
+ aud_config_set_defaults (CFGSECT, defaults);
+ return true;
+}
+
+void SpeedPitch::cleanup ()
+{
+ if (srcstate)
+ src_delete (srcstate);
+
+ srcstate = nullptr;
+
+ cosine.clear ();
+ in.clear ();
+ out.clear ();
+}
diff --git a/src/statusicon/Makefile b/src/statusicon/Makefile
index 13d5f6dbde92..a48f29b45acd 100644
--- a/src/statusicon/Makefile
+++ b/src/statusicon/Makefile
@@ -1,13 +1,13 @@
PLUGIN = statusicon${PLUGIN_SUFFIX}
-SRCS = statusicon.c \
- util.c
+SRCS = statusicon.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += ${GTK_LIBS} ${GLIB_LIBS} -laudgui
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} -I../..
+LIBS += ${GTK_LIBS} -laudgui
diff --git a/src/statusicon/statusicon.c b/src/statusicon/statusicon.c
deleted file mode 100644
index ffca3ac3ff16..000000000000
--- a/src/statusicon/statusicon.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
-* Status Icon Plugin for Audacious
-*
-* Copyright 2005-2007 Giacomo Lozito <james at develia.org>
-* Copyright 2010 MichaÅ Lipski <tallica at o2.pl>
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include "statusicon.h"
-
-#include <audacious/drct.h>
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/plugins.h>
-#include <audacious/preferences.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui.h>
-#include <libaudgui/libaudgui-gtk.h>
-#include <libaudgui/menu.h>
-
-#include <glib.h>
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-
-#define POPUP_IS_ACTIVE GPOINTER_TO_INT(g_object_get_data(G_OBJECT(icon), "popup_active"))
-#define TIMER_IS_ACTIVE GPOINTER_TO_INT(g_object_get_data(G_OBJECT(icon), "timer_active"))
-
-static void si_popup_timer_start(GtkStatusIcon *);
-static void si_popup_timer_stop(GtkStatusIcon *);
-static void si_smallmenu_show(gint x, gint y, guint button, guint32 time, gpointer);
-static void si_smallmenu_recreate(GtkStatusIcon *);
-static void si_popup_hide(gpointer icon);
-
-static const char * const si_defaults[] = {
- "scroll_action", "0", /* SI_CFG_SCROLL_ACTION_VOLUME */
- "volume_delta", "5",
- "disable_popup", "FALSE",
- "close_to_tray", "FALSE",
- "reverse_scroll", "FALSE",
- NULL};
-
-static gboolean plugin_active = FALSE;
-static gboolean recreate_smallmenu = FALSE;
-
-static GtkStatusIcon *si_create(void)
-{
- GtkStatusIcon *icon;
- GtkIconTheme *theme;
-
- theme = gtk_icon_theme_get_default();
-
- if (gtk_icon_theme_has_icon(theme, "audacious-panel"))
- icon = gtk_status_icon_new_from_icon_name("audacious-panel");
- else if (gtk_icon_theme_has_icon(theme, "audacious"))
- icon = gtk_status_icon_new_from_icon_name("audacious");
- else
- {
- gchar * path = g_strdup_printf ("%s/images/audacious.png",
- aud_get_path (AUD_PATH_DATA_DIR));
- icon = gtk_status_icon_new_from_file (path);
- g_free (path);
- }
-
- return icon;
-}
-
-static gboolean si_cb_btpress(GtkStatusIcon * icon, GdkEventButton * event, gpointer user_data)
-{
- if (event->type != GDK_BUTTON_PRESS)
- return FALSE;
-
- si_popup_timer_stop(icon);
- si_popup_hide(icon);
-
- switch (event->button)
- {
- case 1:
- {
- if (event->state & GDK_SHIFT_MASK)
- aud_drct_pl_next();
- else if (! aud_headless_mode ())
- aud_interface_show (! aud_interface_is_shown ());
- break;
- }
-
- case 2:
- {
- aud_drct_pause();
- break;
- }
-
- case 3:
- if (event->state & GDK_SHIFT_MASK)
- aud_drct_pl_prev();
- else
- {
- if (recreate_smallmenu == TRUE)
- si_smallmenu_recreate(icon);
- si_smallmenu_show(event->x_root, event->y_root, 3, event->time, icon);
- }
- break;
- }
-
- return TRUE;
-}
-
-static gboolean si_cb_btscroll(GtkStatusIcon * icon, GdkEventScroll * event, gpointer user_data)
-{
- switch (event->direction)
- {
- case GDK_SCROLL_UP:
- {
- switch (aud_get_int ("statusicon", "scroll_action"))
- {
- case SI_CFG_SCROLL_ACTION_VOLUME:
- si_volume_change (aud_get_int ("statusicon", "volume_delta"));
- break;
- case SI_CFG_SCROLL_ACTION_SKIP:
- if (aud_get_bool ("statusicon", "reverse_scroll"))
- aud_drct_pl_next ();
- else
- aud_drct_pl_prev ();
- break;
- }
- break;
- }
-
- case GDK_SCROLL_DOWN:
- {
- switch (aud_get_int ("statusicon", "scroll_action"))
- {
- case SI_CFG_SCROLL_ACTION_VOLUME:
- si_volume_change (-aud_get_int ("statusicon", "volume_delta"));
- break;
- case SI_CFG_SCROLL_ACTION_SKIP:
- if (aud_get_bool ("statusicon", "reverse_scroll"))
- aud_drct_pl_prev ();
- else
- aud_drct_pl_next ();
- break;
- }
- break;
- }
-
- default:;
- }
-
- return FALSE;
-}
-
-static gboolean si_popup_show(gpointer icon)
-{
- GdkRectangle area;
- gint x, y;
- static gint count = 0;
-
- audgui_get_mouse_coords (NULL, & x, & y);
- gtk_status_icon_get_geometry (icon, NULL, & area, NULL);
-
- if (x < area.x || x > area.x + area.width || y < area.y || y > area.y + area.width)
- {
- si_popup_timer_stop(icon);
- si_popup_hide(icon);
- count = 0;
-
- return TRUE;
- }
-
- if (!POPUP_IS_ACTIVE)
- {
- if (count < 10)
- {
- count++;
- return TRUE;
- }
- else
- count = 0;
-
- audgui_infopopup_show_current();
- g_object_set_data(G_OBJECT(icon), "popup_active", GINT_TO_POINTER(1));
- }
-
- return TRUE;
-}
-
-static void si_popup_hide(gpointer icon)
-{
- if (POPUP_IS_ACTIVE)
- {
- g_object_set_data(G_OBJECT(icon), "popup_active", GINT_TO_POINTER(0));
- audgui_infopopup_hide();
- }
-}
-
-static void si_popup_reshow(gpointer data, gpointer icon)
-{
- if (POPUP_IS_ACTIVE)
- {
- audgui_infopopup_hide();
- audgui_infopopup_show_current();
- }
-}
-
-static void si_popup_timer_start(GtkStatusIcon * icon)
-{
- gint timer_id = g_timeout_add(100, si_popup_show, icon);
- g_object_set_data(G_OBJECT(icon), "timer_id", GINT_TO_POINTER(timer_id));
- g_object_set_data(G_OBJECT(icon), "timer_active", GINT_TO_POINTER(1));
-}
-
-static void si_popup_timer_stop(GtkStatusIcon * icon)
-{
- if (TIMER_IS_ACTIVE)
- g_source_remove(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(icon), "timer_id")));
-
- g_object_set_data(G_OBJECT(icon), "timer_id", GINT_TO_POINTER(0));
- g_object_set_data(G_OBJECT(icon), "timer_active", GINT_TO_POINTER(0));
-}
-
-static gboolean si_cb_tooltip(GtkStatusIcon * icon, gint x, gint y, gboolean keyboard_mode, GtkTooltip * tooltip, gpointer user_data)
-{
- GtkWidget *menu = g_object_get_data(G_OBJECT(icon), "smenu");
-
- if (aud_get_bool("statusicon", "disable_popup") || gtk_widget_get_visible(menu))
- return FALSE;
-
- if (!POPUP_IS_ACTIVE && !TIMER_IS_ACTIVE)
- si_popup_timer_start(icon);
-
- return FALSE;
-}
-
-static void si_smallmenu_show(gint x, gint y, guint button, guint32 time, gpointer evbox)
-{
- GtkWidget *si_smenu = g_object_get_data(G_OBJECT(evbox), "smenu");
- gtk_menu_popup(GTK_MENU(si_smenu), NULL, NULL, NULL, NULL, button, time);
-}
-
-static void open_files (void)
-{
- audgui_run_filebrowser (TRUE);
-}
-
-static GtkWidget *si_smallmenu_create(void)
-{
- static const AudguiMenuItem items[] = {
- {N_("_Open Files ..."), "document-open", .func = open_files},
- {N_("Pre_vious"), "media-skip-backward", .func = aud_drct_pl_prev},
- {N_("_Play"), "media-playback-start", .func = aud_drct_play},
- {N_("Paus_e"), "media-playback-pause", .func = aud_drct_pause},
- {N_("_Stop"), "media-playback-stop", .func = aud_drct_stop},
- {N_("_Next"), "media-skip-forward", .func = aud_drct_pl_next},
- {.sep = TRUE},
- {N_("Se_ttings ..."), "preferences-system", .func = aud_show_prefs_window},
- {N_("_Quit"), "application-exit", .func = aud_drct_quit}
- };
-
- GtkWidget *si_smenu = gtk_menu_new();
- audgui_menu_init (si_smenu, items, ARRAY_LEN (items), NULL);
- return si_smenu;
-}
-
-static void si_smallmenu_recreate(GtkStatusIcon * icon)
-{
- GtkWidget *smenu = g_object_get_data(G_OBJECT(icon), "smenu");
- gtk_widget_destroy(GTK_WIDGET(smenu));
- smenu = si_smallmenu_create();
- g_object_set_data(G_OBJECT(icon), "smenu", smenu);
- recreate_smallmenu = FALSE;
-}
-
-static void si_window_close(gpointer data, gpointer user_data)
-{
- gboolean *handle = (gboolean*) data;
-
- if (aud_get_bool ("statusicon", "close_to_tray"))
- {
- *handle = TRUE;
- aud_interface_show (FALSE);
- }
-}
-
-static void si_enable(gboolean enable)
-{
- static GtkStatusIcon *si_applet = NULL;
-
- if (enable && ! si_applet)
- {
- GtkWidget *si_smenu;
-
- si_applet = si_create();
-
- if (si_applet == NULL)
- {
- g_warning("StatusIcon plugin: unable to create a status icon.\n");
- return;
- }
-
- g_object_set_data(G_OBJECT(si_applet), "timer_id", GINT_TO_POINTER(0));
- g_object_set_data(G_OBJECT(si_applet), "timer_active", GINT_TO_POINTER(0));
- g_object_set_data(G_OBJECT(si_applet), "popup_active", GINT_TO_POINTER(0));
-
- g_signal_connect(G_OBJECT(si_applet), "button-press-event", G_CALLBACK(si_cb_btpress), NULL);
- g_signal_connect(G_OBJECT(si_applet), "scroll-event", G_CALLBACK(si_cb_btscroll), NULL);
- g_signal_connect(G_OBJECT(si_applet), "query-tooltip", G_CALLBACK(si_cb_tooltip), NULL);
-
- gtk_status_icon_set_has_tooltip(si_applet, TRUE);
- gtk_status_icon_set_visible(si_applet, TRUE);
-
- /* small menu that can be used in place of the audacious standard one */
- si_smenu = si_smallmenu_create();
- g_object_set_data(G_OBJECT(si_applet), "smenu", si_smenu);
-
- hook_associate("title change", si_popup_reshow, si_applet);
- hook_associate("window close", si_window_close, NULL);
- }
-
- if (! enable && si_applet)
- {
- /* Prevent accidentally hiding of the interface
- * by disabling the plugin while Audacious is closed to the tray. */
- extern GeneralPlugin _aud_plugin_self;
- PluginHandle *si = aud_plugin_by_header(&_aud_plugin_self);
- if (! aud_plugin_get_enabled(si) && ! aud_headless_mode() && ! aud_interface_is_shown())
- aud_interface_show(TRUE);
-
- GtkWidget *si_smenu = g_object_get_data(G_OBJECT(si_applet), "smenu");
- si_popup_timer_stop(si_applet); /* just in case the timer is active */
- gtk_widget_destroy(si_smenu);
- g_object_unref(si_applet);
- si_applet = NULL;
-
- hook_dissociate("title change", si_popup_reshow);
- hook_dissociate("window close", si_window_close);
- }
-}
-
-static gboolean si_init (void)
-{
- aud_config_set_defaults ("statusicon", si_defaults);
- plugin_active = TRUE;
- si_enable(TRUE);
- return TRUE;
-}
-
-void si_cleanup(void)
-{
- if (!plugin_active)
- return;
-
- plugin_active = FALSE;
- si_enable(FALSE);
-}
-
-static const char si_about[] =
- N_("Status Icon Plugin\n\n"
- "Copyright 2005-2007 Giacomo Lozito <james at develia.org>\n"
- "Copyright 2010 MichaÅ Lipski <tallica at o2.pl>\n\n"
- "This plugin provides a status icon, placed in\n"
- "the system tray area of the window manager.");
-
-static const PreferencesWidget si_widgets[] = {
- {WIDGET_LABEL, N_("<b>Mouse Scroll Action</b>")},
- {WIDGET_RADIO_BTN, N_("Change volume"),
- .cfg_type = VALUE_INT, .csect = "statusicon", .cname = "scroll_action",
- .data = {.radio_btn = {SI_CFG_SCROLL_ACTION_VOLUME}}},
- {WIDGET_RADIO_BTN, N_("Change playing song"),
- .cfg_type = VALUE_INT, .csect = "statusicon", .cname = "scroll_action",
- .data = {.radio_btn = {SI_CFG_SCROLL_ACTION_SKIP}}},
- {WIDGET_LABEL, N_("<b>Other Settings</b>")},
- {WIDGET_CHK_BTN, N_("Disable the popup window"),
- .cfg_type = VALUE_BOOLEAN, .csect = "statusicon", .cname = "disable_popup"},
- {WIDGET_CHK_BTN, N_("Close to the system tray"),
- .cfg_type = VALUE_BOOLEAN, .csect = "statusicon", .cname = "close_to_tray"},
- {WIDGET_CHK_BTN, N_("Advance in playlist when scrolling upward"),
- .cfg_type = VALUE_BOOLEAN, .csect = "statusicon", .cname = "reverse_scroll"}};
-
-static const PluginPreferences si_prefs = {
- .widgets = si_widgets,
- .n_widgets = ARRAY_LEN (si_widgets)};
-
-AUD_GENERAL_PLUGIN
-(
- .name = N_("Status Icon"),
- .domain = PACKAGE,
- .about_text = si_about,
- .prefs = & si_prefs,
- .init = si_init,
- .cleanup = si_cleanup,
-)
diff --git a/src/statusicon/statusicon.cc b/src/statusicon/statusicon.cc
new file mode 100644
index 000000000000..5c5f38743cb2
--- /dev/null
+++ b/src/statusicon/statusicon.cc
@@ -0,0 +1,395 @@
+/*
+ * Status Icon Plugin for Audacious
+ *
+ * Copyright 2005-2007 Giacomo Lozito <james at develia.org>
+ * Copyright 2010 MichaÅ Lipski <tallica at o2.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/plugins.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/runtime.h>
+#include <libaudgui/libaudgui.h>
+#include <libaudgui/libaudgui-gtk.h>
+#include <libaudgui/menu.h>
+
+class StatusIcon : public GeneralPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Status Icon"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ constexpr StatusIcon () : GeneralPlugin (info, false) {}
+
+ bool init ();
+ void cleanup ();
+};
+
+EXPORT StatusIcon aud_plugin_instance;
+
+#define POPUP_IS_ACTIVE GPOINTER_TO_INT (g_object_get_data ((GObject *) icon, "popup_active"))
+#define TIMER_IS_ACTIVE GPOINTER_TO_INT (g_object_get_data ((GObject *) icon, "timer_active"))
+
+enum {
+ SI_CFG_SCROLL_ACTION_VOLUME,
+ SI_CFG_SCROLL_ACTION_SKIP
+};
+
+static void si_popup_timer_start (GtkStatusIcon * icon);
+static void si_popup_timer_stop (GtkStatusIcon * icon);
+static void si_menu_show (int x, int y, unsigned button, uint32_t time, void *);
+static void si_popup_hide (void * icon);
+
+const char * const StatusIcon::defaults[] = {
+ "scroll_action", "0", /* SI_CFG_SCROLL_ACTION_VOLUME */
+ "volume_delta", "5",
+ "disable_popup", "FALSE",
+ "close_to_tray", "FALSE",
+ "reverse_scroll", "FALSE",
+ nullptr
+};
+
+static GtkStatusIcon * si_create ()
+{
+ GtkStatusIcon * icon;
+ GtkIconTheme * theme = gtk_icon_theme_get_default ();
+
+ if (gtk_icon_theme_has_icon (theme, "audacious-panel"))
+ icon = gtk_status_icon_new_from_icon_name ("audacious-panel");
+ else if (gtk_icon_theme_has_icon (theme, "audacious"))
+ icon = gtk_status_icon_new_from_icon_name ("audacious");
+ else
+ icon = gtk_status_icon_new_from_file (aud_get_path (AudPath::IconFile));
+
+ return icon;
+}
+
+static void si_volume_change (int value)
+{
+ aud_drct_set_volume_main (aud_drct_get_volume_main () + value);
+}
+
+static gboolean si_cb_btpress (GtkStatusIcon * icon, GdkEventButton * event)
+{
+ if (event->type != GDK_BUTTON_PRESS)
+ return false;
+
+ si_popup_timer_stop (icon);
+ si_popup_hide (icon);
+
+ switch (event->button)
+ {
+ case 1:
+ if (event->state & GDK_SHIFT_MASK)
+ aud_drct_pl_next ();
+ else if (! aud_get_headless_mode ())
+ aud_ui_show (! aud_ui_is_shown ());
+ break;
+
+ case 2:
+ aud_drct_pause ();
+ break;
+
+ case 3:
+ if (event->state & GDK_SHIFT_MASK)
+ aud_drct_pl_prev ();
+ else
+ si_menu_show (event->x_root, event->y_root, event->button, event->time, icon);
+ break;
+ }
+
+ return true;
+}
+
+static gboolean si_cb_btscroll (GtkStatusIcon * icon, GdkEventScroll * event)
+{
+ switch (event->direction)
+ {
+ case GDK_SCROLL_UP:
+ {
+ switch (aud_get_int ("statusicon", "scroll_action"))
+ {
+ case SI_CFG_SCROLL_ACTION_VOLUME:
+ si_volume_change (aud_get_int ("statusicon", "volume_delta"));
+ break;
+ case SI_CFG_SCROLL_ACTION_SKIP:
+ if (aud_get_bool ("statusicon", "reverse_scroll"))
+ aud_drct_pl_next ();
+ else
+ aud_drct_pl_prev ();
+ break;
+ }
+ break;
+ }
+
+ case GDK_SCROLL_DOWN:
+ {
+ switch (aud_get_int ("statusicon", "scroll_action"))
+ {
+ case SI_CFG_SCROLL_ACTION_VOLUME:
+ si_volume_change (-aud_get_int ("statusicon", "volume_delta"));
+ break;
+ case SI_CFG_SCROLL_ACTION_SKIP:
+ if (aud_get_bool ("statusicon", "reverse_scroll"))
+ aud_drct_pl_prev ();
+ else
+ aud_drct_pl_next ();
+ break;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+static gboolean si_popup_show (void * icon)
+{
+ int x, y;
+ GdkRectangle area;
+ static int count = 0;
+
+ audgui_get_mouse_coords (gtk_status_icon_get_screen ((GtkStatusIcon *) icon), & x, & y);
+ gtk_status_icon_get_geometry ((GtkStatusIcon *) icon, nullptr, & area, nullptr);
+
+ if (x < area.x || x > area.x + area.width || y < area.y || y > area.y + area.width)
+ {
+ si_popup_timer_stop ((GtkStatusIcon *) icon);
+ si_popup_hide ((GtkStatusIcon *) icon);
+ count = 0;
+
+ return true;
+ }
+
+ if (! POPUP_IS_ACTIVE)
+ {
+ if (count < 10)
+ {
+ count ++;
+ return true;
+ }
+ else
+ count = 0;
+
+ audgui_infopopup_show_current ();
+ g_object_set_data ((GObject *) icon, "popup_active", GINT_TO_POINTER (1));
+ }
+
+ return true;
+}
+
+static void si_popup_hide (void * icon)
+{
+ if (POPUP_IS_ACTIVE)
+ {
+ g_object_set_data ((GObject *) icon, "popup_active", GINT_TO_POINTER (0));
+ audgui_infopopup_hide ();
+ }
+}
+
+static void si_popup_reshow (void * data, void * icon)
+{
+ if (POPUP_IS_ACTIVE)
+ {
+ audgui_infopopup_hide ();
+ audgui_infopopup_show_current ();
+ }
+}
+
+static void si_popup_timer_start (GtkStatusIcon * icon)
+{
+ int timer_id = g_timeout_add (100, si_popup_show, icon);
+ g_object_set_data ((GObject *) icon, "timer_id", GINT_TO_POINTER (timer_id));
+ g_object_set_data ((GObject *) icon, "timer_active", GINT_TO_POINTER (1));
+}
+
+static void si_popup_timer_stop (GtkStatusIcon * icon)
+{
+ if (TIMER_IS_ACTIVE)
+ g_source_remove (GPOINTER_TO_INT (g_object_get_data ((GObject *) icon, "timer_id")));
+
+ g_object_set_data ((GObject *) icon, "timer_id", GINT_TO_POINTER (0));
+ g_object_set_data ((GObject *) icon, "timer_active", GINT_TO_POINTER (0));
+}
+
+static gboolean si_cb_tooltip (GtkStatusIcon * icon, int x, int y, gboolean keyboard_mode, GtkTooltip * tooltip)
+{
+ GtkWidget * menu = (GtkWidget *) g_object_get_data ((GObject *) icon, "menu");
+
+ if (aud_get_bool ("statusicon", "disable_popup") || gtk_widget_get_visible (menu))
+ return false;
+
+ if (! POPUP_IS_ACTIVE && ! TIMER_IS_ACTIVE)
+ si_popup_timer_start (icon);
+
+ return false;
+}
+
+static void si_menu_show (int x, int y, unsigned button, uint32_t time, void * evbox)
+{
+ GtkWidget * si_menu = (GtkWidget *) g_object_get_data ((GObject *) evbox, "menu");
+ gtk_menu_popup ((GtkMenu *) si_menu, nullptr, nullptr, nullptr, nullptr, button, time);
+}
+
+static void open_files ()
+{
+ audgui_run_filebrowser (true);
+}
+
+static GtkWidget * si_menu_create ()
+{
+ static const AudguiMenuItem items[] = {
+ MenuCommand (N_("_Open Files ..."), "document-open", 0, (GdkModifierType) 0, open_files),
+ MenuCommand (N_("Pre_vious"), "media-skip-backward", 0, (GdkModifierType) 0, aud_drct_pl_prev),
+ MenuCommand (N_("_Play"), "media-playback-start", 0, (GdkModifierType) 0, aud_drct_play),
+ MenuCommand (N_("Paus_e"), "media-playback-pause", 0, (GdkModifierType) 0, aud_drct_pause),
+ MenuCommand (N_("_Stop"), "media-playback-stop", 0, (GdkModifierType) 0, aud_drct_stop),
+ MenuCommand (N_("_Next"), "media-skip-forward", 0, (GdkModifierType) 0, aud_drct_pl_next),
+ MenuSep (),
+ MenuCommand (N_("Se_ttings ..."), "preferences-system", 0, (GdkModifierType) 0, audgui_show_prefs_window),
+ MenuCommand (N_("_Quit"), "application-exit", 0, (GdkModifierType) 0, aud_quit)
+ };
+
+ GtkWidget * si_menu = gtk_menu_new ();
+ audgui_menu_init (si_menu, {items}, nullptr);
+ return si_menu;
+}
+
+static void si_window_close (void * data, void * user_data)
+{
+ bool * handle = (bool *) data;
+
+ if (aud_get_bool ("statusicon", "close_to_tray"))
+ {
+ * handle = true;
+ aud_ui_show (false);
+ }
+}
+
+static void si_enable (bool enable)
+{
+ static GtkStatusIcon * si_applet = nullptr;
+
+ if (enable && ! si_applet)
+ {
+ si_applet = si_create ();
+
+ if (! si_applet)
+ {
+ AUDWARN ("StatusIcon plugin: unable to create a status icon.\n");
+ return;
+ }
+
+ g_object_set_data ((GObject *) si_applet, "timer_id", GINT_TO_POINTER (0));
+ g_object_set_data ((GObject *) si_applet, "timer_active", GINT_TO_POINTER (0));
+ g_object_set_data ((GObject *) si_applet, "popup_active", GINT_TO_POINTER (0));
+
+ g_signal_connect (si_applet, "button-press-event", (GCallback) si_cb_btpress, nullptr);
+ g_signal_connect (si_applet, "scroll-event", (GCallback) si_cb_btscroll, nullptr);
+ g_signal_connect (si_applet, "query-tooltip", (GCallback) si_cb_tooltip, nullptr);
+
+ gtk_status_icon_set_has_tooltip (si_applet, true);
+ gtk_status_icon_set_visible (si_applet, true);
+
+ GtkWidget * si_menu = si_menu_create ();
+ g_object_set_data ((GObject *) si_applet, "menu", si_menu);
+
+ hook_associate ("title change", si_popup_reshow, si_applet);
+ hook_associate ("window close", si_window_close, nullptr);
+ }
+
+ if (! enable && si_applet)
+ {
+ /* Prevent accidentally hiding of the interface
+ * by disabling the plugin while Audacious is closed to the tray. */
+ PluginHandle * si = aud_plugin_by_header (& aud_plugin_instance);
+ if (! aud_plugin_get_enabled (si) && ! aud_get_headless_mode () && ! aud_ui_is_shown ())
+ aud_ui_show (true);
+
+ GtkWidget * si_menu = (GtkWidget *) g_object_get_data ((GObject *) si_applet, "menu");
+ si_popup_timer_stop (si_applet); /* just in case the timer is active */
+ gtk_widget_destroy (si_menu);
+ g_object_unref (si_applet);
+ si_applet = nullptr;
+
+ hook_dissociate ("title change", si_popup_reshow);
+ hook_dissociate ("window close", si_window_close);
+ }
+}
+
+bool StatusIcon::init ()
+{
+ if (aud_get_mainloop_type () != MainloopType::GLib)
+ return false;
+
+ aud_config_set_defaults ("statusicon", defaults);
+ audgui_init ();
+ si_enable (true);
+ return true;
+}
+
+void StatusIcon::cleanup ()
+{
+ si_enable (false);
+ audgui_cleanup ();
+}
+
+const char StatusIcon::about[] =
+ N_("Status Icon Plugin\n\n"
+ "Copyright 2005-2007 Giacomo Lozito <james at develia.org>\n"
+ "Copyright 2010 MichaÅ Lipski <tallica at o2.pl>\n\n"
+ "This plugin provides a status icon, placed in\n"
+ "the system tray area of the window manager.");
+
+const PreferencesWidget StatusIcon::widgets[] = {
+ WidgetLabel (N_("<b>Mouse Scroll Action</b>")),
+ WidgetRadio (N_("Change volume"),
+ WidgetInt ("statusicon", "scroll_action"),
+ {SI_CFG_SCROLL_ACTION_VOLUME}),
+ WidgetRadio (N_("Change playing song"),
+ WidgetInt ("statusicon", "scroll_action"),
+ {SI_CFG_SCROLL_ACTION_SKIP}),
+ WidgetLabel (N_("<b>Other Settings</b>")),
+ WidgetCheck (N_("Disable the popup window"),
+ WidgetBool ("statusicon", "disable_popup")),
+ WidgetCheck (N_("Close to the system tray"),
+ WidgetBool ("statusicon", "close_to_tray")),
+ WidgetCheck (N_("Advance in playlist when scrolling upward"),
+ WidgetBool ("statusicon", "reverse_scroll"))
+};
+
+const PluginPreferences StatusIcon::prefs = {{widgets}};
diff --git a/src/statusicon/statusicon.h b/src/statusicon/statusicon.h
deleted file mode 100644
index b8c2a19a4790..000000000000
--- a/src/statusicon/statusicon.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-* Status Icon Plugin for Audacious
-*
-* Copyright 2005-2007 Giacomo Lozito <james at develia.org>
-* Copyright 2010 MichaÅ Lipski <tallica at o2.pl>
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#ifndef STATUS_ICON_H
-#define STATUS_ICON_H
-
-enum {
- SI_CFG_SCROLL_ACTION_VOLUME,
- SI_CFG_SCROLL_ACTION_SKIP
-};
-
-/* util.c */
-void si_volume_change (int value);
-
-#endif
diff --git a/src/statusicon/util.c b/src/statusicon/util.c
deleted file mode 100644
index 5d2ec5e0f874..000000000000
--- a/src/statusicon/util.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-* Status Icon Plugin for Audacious
-*
-* Copyright 2005-2007 Giacomo Lozito <james at develia.org>
-* Copyright 2010 MichaÅ Lipski <tallica at o2.pl>
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-*/
-
-#include <glib.h>
-
-#include <audacious/drct.h>
-#include <libaudgui/libaudgui.h>
-
-#include "statusicon.h"
-
-void si_volume_change(gint value)
-{
- gint vl, vr;
- aud_drct_get_volume(&vl, &vr);
- aud_drct_set_volume(CLAMP(vl + value, 0, 100), CLAMP(vr + value, 0, 100));
-}
diff --git a/src/stereo_plugin/Makefile b/src/stereo_plugin/Makefile
index dcadd2d3c40f..f9e9d0c0515b 100644
--- a/src/stereo_plugin/Makefile
+++ b/src/stereo_plugin/Makefile
@@ -1,11 +1,12 @@
PLUGIN = stereo${PLUGIN_SUFFIX}
-SRCS = stereo.c
+SRCS = stereo.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
diff --git a/src/stereo_plugin/stereo.c b/src/stereo_plugin/stereo.c
deleted file mode 100644
index 3ec2cb8ba008..000000000000
--- a/src/stereo_plugin/stereo.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Extra Stereo Plugin for Audacious
- * Written by Johan Levin, 1999
- * Modified by John Lindgren, 2009-2012 */
-
-#include <audacious/i18n.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/preferences.h>
-
-static bool_t init (void);
-
-static void stereo_start (int * channels, int * rate);
-static void stereo_process (float * * data, int * samples);
-static void stereo_finish (float * * data, int * samples);
-
-static const char stereo_about[] =
- N_("Extra Stereo Plugin\n\n"
- "By Johan Levin, 1999");
-
-static const char * const stereo_defaults[] = {
- "intensity", "2.5",
- NULL};
-
-static const PreferencesWidget stereo_widgets[] = {
- {WIDGET_LABEL, N_("<b>Extra Stereo</b>")},
- {WIDGET_SPIN_BTN, N_("Intensity:"),
- .cfg_type = VALUE_FLOAT, .csect = "extra_stereo", .cname = "intensity",
- .data = {.spin_btn = {0, 10, 0.1}}}};
-
-static const PluginPreferences stereo_prefs = {
- .widgets = stereo_widgets,
- .n_widgets = ARRAY_LEN (stereo_widgets)};
-
-AUD_EFFECT_PLUGIN
-(
- .name = N_("Extra Stereo"),
- .domain = PACKAGE,
- .about_text = stereo_about,
- .prefs = & stereo_prefs,
- .init = init,
- .start = stereo_start,
- .process = stereo_process,
- .finish = stereo_finish,
- .preserves_format = TRUE
-)
-
-static bool_t init (void)
-{
- aud_config_set_defaults ("extra_stereo", stereo_defaults);
- return TRUE;
-}
-
-static int stereo_channels;
-
-static void stereo_start (int * channels, int * rate)
-{
- stereo_channels = * channels;
-}
-
-static void stereo_process (float * * data, int * samples)
-{
- float value = aud_get_double ("extra_stereo", "intensity");
- float * f, * end;
- float center;
-
- if (stereo_channels != 2 || samples == 0)
- return;
-
- end = (* data) + (* samples);
-
- for (f = * data; f < end; f += 2)
- {
- center = (f[0] + f[1]) / 2;
- f[0] = center + (f[0] - center) * value;
- f[1] = center + (f[1] - center) * value;
- }
-}
-
-static void stereo_finish (float * * data, int * samples)
-{
- stereo_process (data, samples);
-}
diff --git a/src/stereo_plugin/stereo.cc b/src/stereo_plugin/stereo.cc
new file mode 100644
index 000000000000..c6e875bfd39e
--- /dev/null
+++ b/src/stereo_plugin/stereo.cc
@@ -0,0 +1,84 @@
+/* Extra Stereo Plugin for Audacious
+ * Written by Johan Levin, 1999
+ * Modified by John Lindgren, 2009-2012 */
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+
+class ExtraStereo : public EffectPlugin
+{
+public:
+ static const char about[];
+ static const char * const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("Extra Stereo"),
+ PACKAGE,
+ about,
+ & prefs
+ };
+
+ constexpr ExtraStereo () : EffectPlugin (info, 0, true) {}
+
+ bool init ();
+
+ void start (int & channels, int & rate);
+ Index<float> & process (Index<float> & data);
+};
+
+EXPORT ExtraStereo aud_plugin_instance;
+
+const char ExtraStereo::about[] =
+ N_("Extra Stereo Plugin\n\n"
+ "By Johan Levin, 1999");
+
+const char * const ExtraStereo::defaults[] = {
+ "intensity", "2.5",
+ nullptr};
+
+const PreferencesWidget ExtraStereo::widgets[] = {
+ WidgetLabel (N_("<b>Extra Stereo</b>")),
+ WidgetSpin (N_("Intensity:"),
+ WidgetFloat ("extra_stereo", "intensity"),
+ {0, 10, 0.1})
+};
+
+const PluginPreferences ExtraStereo::prefs = {{widgets}};
+
+bool ExtraStereo::init ()
+{
+ aud_config_set_defaults ("extra_stereo", defaults);
+ return true;
+}
+
+static int stereo_channels;
+
+void ExtraStereo::start (int & channels, int & rate)
+{
+ stereo_channels = channels;
+}
+
+Index<float> & ExtraStereo::process(Index<float> & data)
+{
+ float value = aud_get_double ("extra_stereo", "intensity");
+ float * f, * end;
+ float center;
+
+ if (stereo_channels != 2)
+ return data;
+
+ end = data.end ();
+
+ for (f = data.begin (); f < end; f += 2)
+ {
+ center = (f[0] + f[1]) / 2;
+ f[0] = center + (f[0] - center) * value;
+ f[1] = center + (f[1] - center) * value;
+ }
+
+ return data;
+}
diff --git a/src/tonegen/Makefile b/src/tonegen/Makefile
index 4a0161f0e46d..ae998b0b6b59 100644
--- a/src/tonegen/Makefile
+++ b/src/tonegen/Makefile
@@ -1,12 +1,14 @@
PLUGIN = tonegen${PLUGIN_SUFFIX}
-SRCS = tonegen.c
+SRCS = tonegen.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS} -lm
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
+LIBS += -lm
diff --git a/src/tonegen/tonegen.c b/src/tonegen/tonegen.c
deleted file mode 100644
index 5143d6bc1ae6..000000000000
--- a/src/tonegen/tonegen.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright 2000, 2001 Håvard Kvålen <havardk at sol.no>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-
-#include <glib.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#define MIN_FREQ 10
-#define MAX_FREQ 20000
-#define OUTPUT_FREQ 44100
-#define BUF_SAMPLES 512
-#define BUF_BYTES (BUF_SAMPLES * sizeof(float))
-
-#ifndef PI
-#define PI 3.14159265358979323846
-#endif
-
-static gboolean tone_is_our_fd(const gchar *filename, VFSFile *fd)
-{
- if (!strncmp(filename, "tone://", 7))
- return TRUE;
- return FALSE;
-}
-
-static GArray *tone_filename_parse(const gchar * filename)
-{
- GArray *frequencies = g_array_new(FALSE, FALSE, sizeof(double));
- gchar **strings, **ptr;
-
- if (strncmp(filename, "tone://", 7))
- return NULL;
-
- strings = g_strsplit(filename + 7, ";", 100);
-
- for (ptr = strings; *ptr != NULL; ptr++)
- {
- gdouble freq = strtod(*ptr, NULL);
- if (freq >= MIN_FREQ && freq <= MAX_FREQ)
- g_array_append_val(frequencies, freq);
- }
- g_strfreev(strings);
-
- if (frequencies->len == 0)
- {
- g_array_free(frequencies, TRUE);
- frequencies = NULL;
- }
-
- return frequencies;
-}
-
-static gchar *tone_title(const gchar * filename)
-{
- GArray *freqs;
- gchar *title;
- gsize i;
-
- freqs = tone_filename_parse(filename);
- if (freqs == NULL)
- return NULL;
-
- title = g_strdup_printf(_("%s %.1f Hz"), _("Tone Generator: "), g_array_index(freqs, double, 0));
- for (i = 1; i < freqs->len; i++)
- {
- gchar *old_title = title;
- title = g_strdup_printf("%s;%.1f Hz", old_title, g_array_index(freqs, double, i));
- g_free(old_title);
- }
- g_array_free(freqs, TRUE);
-
- return title;
-}
-
-static gboolean tone_play(const gchar *filename, VFSFile *file)
-{
- GArray *frequencies;
- gfloat data[BUF_SAMPLES];
- gsize i;
- gboolean error = FALSE;
- struct
- {
- gdouble wd;
- guint period, t;
- } *tone = NULL;
-
- frequencies = tone_filename_parse(filename);
- if (frequencies == NULL)
- return FALSE;
-
- if (aud_input_open_audio(FMT_FLOAT, OUTPUT_FREQ, 1) == 0)
- {
- error = TRUE;
- goto error_exit;
- }
-
- aud_input_set_bitrate(16 * OUTPUT_FREQ);
-
- tone = g_malloc(frequencies->len * sizeof(*tone));
- for (i = 0; i < frequencies->len; i++)
- {
- gdouble f = g_array_index(frequencies, gdouble, i);
- tone[i].wd = 2 * PI * f / OUTPUT_FREQ;
- tone[i].period = (G_MAXINT * 2U / OUTPUT_FREQ) * (OUTPUT_FREQ / f);
- tone[i].t = 0;
- }
-
- while (!aud_input_check_stop())
- {
- for (i = 0; i < BUF_SAMPLES; i++)
- {
- gsize j;
- double sum_sines;
-
- for (sum_sines = 0, j = 0; j < frequencies->len; j++)
- {
- sum_sines += sin(tone[j].wd * tone[j].t);
- if (tone[j].t > tone[j].period)
- tone[j].t -= tone[j].period;
- tone[j].t++;
- }
- /* dithering can cause a little bit of clipping */
- data[i] = (sum_sines * 0.999 / (gdouble) frequencies->len);
- }
-
- aud_input_write_audio(data, BUF_BYTES);
- }
-
-error_exit:
- g_array_free(frequencies, TRUE);
- g_free(tone);
-
- return !error;
-}
-
-static Tuple *tone_probe_for_tuple(const gchar *filename, VFSFile *fd)
-{
- Tuple *tuple = tuple_new_from_filename(filename);
- gchar *tmp;
-
- if (tuple == NULL)
- return NULL;
-
- if ((tmp = tone_title(filename)) != NULL)
- {
- tuple_set_str(tuple, FIELD_TITLE, tmp);
- g_free(tmp);
- }
-
- return tuple;
-}
-
-static const char tone_about[] =
- N_("Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
- "Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n\n"
- "To use it, add a URL: tone://frequency1;frequency2;frequency3;...\n"
- "e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone");
-
-static const gchar * const schemes[] = {"tone", NULL};
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("Tone Generator"),
- .domain = PACKAGE,
- .about_text = tone_about,
- .schemes = schemes,
- .is_our_file_from_vfs = tone_is_our_fd,
- .play = tone_play,
- .probe_for_tuple = tone_probe_for_tuple
-)
diff --git a/src/tonegen/tonegen.cc b/src/tonegen/tonegen.cc
new file mode 100644
index 000000000000..9d9c9ef23e24
--- /dev/null
+++ b/src/tonegen/tonegen.cc
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2000, 2001 Håvard Kvålen <havardk at sol.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#define MIN_FREQ 10
+#define MAX_FREQ 20000
+#define OUTPUT_FREQ 44100
+#define BUF_SAMPLES 512
+#define BUF_BYTES (BUF_SAMPLES * sizeof(float))
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+
+class ToneGen : public InputPlugin
+{
+public:
+ static const char about[];
+ static const char *const schemes[];
+
+ static constexpr PluginInfo info = {
+ N_("Tone Generator"),
+ PACKAGE,
+ about
+ };
+
+ static constexpr auto iinfo = InputInfo()
+ .with_schemes(schemes);
+
+ constexpr ToneGen() : InputPlugin(info, iinfo) {}
+
+ bool is_our_file(const char *filename, VFSFile &file);
+ Tuple read_tuple(const char *filename, VFSFile &file);
+ bool play(const char *filename, VFSFile &file);
+};
+
+EXPORT ToneGen aud_plugin_instance;
+
+bool ToneGen::is_our_file(const char *filename, VFSFile &file)
+{
+ if (!strncmp(filename, "tone://", 7))
+ return true;
+ return false;
+}
+
+static Index<double> tone_filename_parse(const char *filename)
+{
+ Index<double> frequencies;
+
+ if (strncmp(filename, "tone://", 7))
+ return frequencies;
+
+ auto strings = str_list_to_index(filename + 7, ";");
+
+ for (const char *str : strings)
+ {
+ double freq = strtod(str, nullptr);
+ if (freq >= MIN_FREQ && freq <= MAX_FREQ)
+ frequencies.append(freq);
+ }
+
+ return frequencies;
+}
+
+static StringBuf tone_title(const char *filename)
+{
+ auto freqs = tone_filename_parse(filename);
+ if (!freqs.len())
+ return StringBuf();
+
+ auto title = str_printf(_("%s %.1f Hz"), _("Tone Generator: "), freqs[0]);
+ for (int i = 1; i < freqs.len(); i++)
+ title.combine(str_printf(";%.1f Hz", freqs[i]));
+
+ return title;
+}
+
+struct tone_t
+{
+ double wd;
+ unsigned period, t;
+};
+
+bool ToneGen::play(const char *filename, VFSFile &file)
+{
+ float data[BUF_SAMPLES];
+
+ auto frequencies = tone_filename_parse(filename);
+ if (!frequencies.len())
+ return false;
+
+ set_stream_bitrate(16 * OUTPUT_FREQ);
+ open_audio(FMT_FLOAT, OUTPUT_FREQ, 1);
+
+ Index<tone_t> tone;
+ tone.resize(frequencies.len());
+ for (int i = 0; i < frequencies.len(); i++)
+ {
+ double f = frequencies[i];
+ tone[i].wd = 2 * PI * f / OUTPUT_FREQ;
+ tone[i].period = (INT_MAX * 2U / OUTPUT_FREQ) * (OUTPUT_FREQ / f);
+ tone[i].t = 0;
+ }
+
+ while (!check_stop())
+ {
+ for (int i = 0; i < BUF_SAMPLES; i++)
+ {
+ double sum_sines = 0;
+
+ for (int j = 0; j < frequencies.len(); j++)
+ {
+ sum_sines += sin(tone[j].wd * tone[j].t);
+ if (tone[j].t > tone[j].period)
+ tone[j].t -= tone[j].period;
+ tone[j].t++;
+ }
+ /* dithering can cause a little bit of clipping */
+ data[i] = (sum_sines * 0.999 / (double)frequencies.len());
+ }
+
+ write_audio(data, BUF_BYTES);
+ }
+
+ return true;
+}
+
+Tuple ToneGen::read_tuple(const char *filename, VFSFile &file)
+{
+ Tuple tuple;
+ tuple.set_filename(filename);
+ tuple.set_str(Tuple::Title, tone_title(filename));
+ return tuple;
+}
+
+const char ToneGen::about[] =
+ N_("Sine tone generator by Håvard Kvålen <havardk at xmms.org>\n"
+ "Modified by Daniel J. Peng <danielpeng at bigfoot.com>\n\n"
+ "To use it, add a URL: tone://frequency1;frequency2;frequency3;...\n"
+ "e.g. tone://2000;2005 to play a 2000 Hz tone and a 2005 Hz tone");
+
+const char *const ToneGen::schemes[] = {"tone", nullptr};
diff --git a/src/voice_removal/Makefile b/src/voice_removal/Makefile
index 286924df390a..827b332329e9 100644
--- a/src/voice_removal/Makefile
+++ b/src/voice_removal/Makefile
@@ -1,11 +1,12 @@
PLUGIN = voice_removal${PLUGIN_SUFFIX}
-SRCS = voice_removal.c
+SRCS = voice_removal.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR}
+LD = ${CXX}
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../..
diff --git a/src/voice_removal/voice_removal.c b/src/voice_removal/voice_removal.c
deleted file mode 100644
index 979a1b3c1966..000000000000
--- a/src/voice_removal/voice_removal.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2010 William Pitcock <nenolod at dereferenced.org>.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-
-static int voice_channels;
-
-static void voice_start(int *channels, int *rate)
-{
- voice_channels = *channels;
-}
-
-static void voice_process(float **d, int *samples)
-{
- float *f = *d, *end;
- end = *d + *samples;
-
- if (voice_channels != 2)
- return;
-
- for (f = *d; f < end; f += 2)
- {
- f[0] -= f[1];
- f[1] = f[0];
- }
-}
-
-static void voice_finish(float **d, int *samples)
-{
- voice_process(d, samples);
-}
-
-AUD_EFFECT_PLUGIN
-(
- .name = N_("Voice Removal"),
- .domain = PACKAGE,
- .start = voice_start,
- .process = voice_process,
- .finish = voice_finish,
- .preserves_format = TRUE
-)
diff --git a/src/voice_removal/voice_removal.cc b/src/voice_removal/voice_removal.cc
new file mode 100644
index 000000000000..c86804e9c852
--- /dev/null
+++ b/src/voice_removal/voice_removal.cc
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010 William Pitcock <nenolod at dereferenced.org>.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+
+class VoiceRemoval : public EffectPlugin
+{
+public:
+ static constexpr PluginInfo info = {
+ N_("Voice Removal"),
+ PACKAGE
+ };
+
+ constexpr VoiceRemoval () : EffectPlugin (info, 0, true) {}
+
+ void start (int & channels, int & rate);
+ Index<float> & process (Index<float> & data);
+};
+
+EXPORT VoiceRemoval aud_plugin_instance;
+
+static int voice_channels;
+
+void VoiceRemoval::start (int & channels, int & rate)
+{
+ voice_channels = channels;
+}
+
+Index<float> & VoiceRemoval::process (Index<float> & data)
+{
+ if (voice_channels != 2)
+ return data;
+
+ float * end = data.end ();
+
+ for (float * f = data.begin (); f < end; f += 2)
+ {
+ f[0] -= f[1];
+ f[1] = f[0];
+ }
+
+ return data;
+}
diff --git a/src/vorbis/Makefile b/src/vorbis/Makefile
index 739f6c93bbed..98d8059d660f 100644
--- a/src/vorbis/Makefile
+++ b/src/vorbis/Makefile
@@ -1,14 +1,16 @@
PLUGIN = vorbis${PLUGIN_SUFFIX}
-SRCS = vcupdate.c \
- vcedit.c \
- vorbis.c
+SRCS = vcupdate.cc \
+ vcedit.cc \
+ vorbis.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${VORBIS_CFLAGS} ${GLIB_CFLAGS} -I../..
LIBS += ${VORBIS_LIBS} ${GLIB_LIBS}
diff --git a/src/vorbis/vcedit.c b/src/vorbis/vcedit.c
deleted file mode 100644
index dbc316c3ed1a..000000000000
--- a/src/vorbis/vcedit.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/* This program is licensed under the GNU Library General Public License, version 2,
- * a copy of which is included with this program (LICENCE.LGPL).
- *
- * (c) 2000-2001 Michael Smith <msmith at labyrinth.net.au>
- *
- *
- * Comment editing backend, suitable for use by nice frontend interfaces.
- *
- */
-#include <glib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ogg/ogg.h>
-#include <vorbis/codec.h>
-
-#include "vcedit.h"
-
-#define CHUNKSIZE 4096
-
-vcedit_state *
-vcedit_new_state(void)
-{
- return g_new0(vcedit_state, 1);
-}
-
-char *
-vcedit_error(vcedit_state * state)
-{
- return state->lasterror;
-}
-
-vorbis_comment *
-vcedit_comments(vcedit_state * state)
-{
- return state->vc;
-}
-
-static void
-vcedit_clear_internals(vcedit_state * state)
-{
- if (state->vc) {
- vorbis_comment_clear(state->vc);
- g_free(state->vc);
- state->vc = NULL;
- }
- if (state->os) {
- ogg_stream_clear(state->os);
- g_free(state->os);
- state->os = NULL;
- }
- if (state->oy) {
- ogg_sync_clear(state->oy);
- g_free(state->oy);
- state->oy = NULL;
- }
- if (state->vendor) {
- g_free(state->vendor);
- state->vendor = NULL;
- }
-}
-
-void
-vcedit_clear(vcedit_state * state)
-{
- if (state) {
- vcedit_clear_internals(state);
- g_free(state);
- }
-}
-
-/* Next two functions pulled straight from libvorbis, apart from one change
- * - we don't want to overwrite the vendor string.
- */
-static void
-_v_writestring(oggpack_buffer * o, char *s, int len)
-{
- while (len--) {
- oggpack_write(o, *s++, 8);
- }
-}
-
-static int
-_commentheader_out(vorbis_comment * vc, char *vendor, ogg_packet * op)
-{
- oggpack_buffer opb;
-
- oggpack_writeinit(&opb);
-
- /* preamble */
- oggpack_write(&opb, 0x03, 8);
- _v_writestring(&opb, "vorbis", 6);
-
- /* vendor */
- oggpack_write(&opb, strlen(vendor), 32);
- _v_writestring(&opb, vendor, strlen(vendor));
-
- /* comments */
- oggpack_write(&opb, vc->comments, 32);
- if (vc->comments) {
- int i;
- for (i = 0; i < vc->comments; i++) {
- if (vc->user_comments[i]) {
- oggpack_write(&opb, vc->comment_lengths[i], 32);
- _v_writestring(&opb, vc->user_comments[i],
- vc->comment_lengths[i]);
- }
- else {
- oggpack_write(&opb, 0, 32);
- }
- }
- }
- oggpack_write(&opb, 1, 1);
-
- op->packet = _ogg_malloc(oggpack_bytes(&opb));
- memcpy(op->packet, opb.buffer, oggpack_bytes(&opb));
-
- op->bytes = oggpack_bytes(&opb);
- op->b_o_s = 0;
- op->e_o_s = 0;
- op->granulepos = 0;
-
- return 0;
-}
-
-static int
-_blocksize(vcedit_state * s, ogg_packet * p)
-{
- int this = vorbis_packet_blocksize(&s->vi, p);
- int ret = (this + s->prevW) / 4;
-
- if (!s->prevW) {
- s->prevW = this;
- return 0;
- }
-
- s->prevW = this;
- return ret;
-}
-
-static int
-_fetch_next_packet(vcedit_state * s, ogg_packet * p, ogg_page * page)
-{
- int result;
- char *buffer;
- gint64 bytes;
-
- result = ogg_stream_packetout(s->os, p);
-
- if (result > 0)
- return 1;
- else {
- if (s->eosin)
- return 0;
- while (ogg_sync_pageout(s->oy, page) <= 0) {
- buffer = ogg_sync_buffer(s->oy, CHUNKSIZE);
- bytes = s->read(buffer, 1, CHUNKSIZE, s->in);
- ogg_sync_wrote(s->oy, bytes);
- if (bytes == 0)
- return 0;
- }
- if (ogg_page_eos(page))
- s->eosin = 1;
- else if (ogg_page_serialno(page) != s->serial) {
- s->eosin = 1;
- s->extrapage = 1;
- return 0;
- }
-
- ogg_stream_pagein(s->os, page);
- return _fetch_next_packet(s, p, page);
- }
-}
-
-
-int
-vcedit_open(vcedit_state * state, VFSFile * in)
-{
- return vcedit_open_callbacks(state, (void *) in,
- (vcedit_read_func) vfs_fread,
- (vcedit_write_func) vfs_fwrite);
-}
-
-int
-vcedit_open_callbacks(vcedit_state * state, void *in,
- vcedit_read_func read_func,
- vcedit_write_func write_func)
-{
- char *buffer;
- gint64 bytes, i;
- ogg_packet *header;
- ogg_packet header_main;
- ogg_packet header_comments;
- ogg_packet header_codebooks;
- ogg_page og;
-
- state->in = in;
- state->read = read_func;
- state->write = write_func;
-
- state->oy = g_new(ogg_sync_state, 1);
- ogg_sync_init(state->oy);
-
- buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
-
- bytes = state->read(buffer, 1, CHUNKSIZE, state->in);
-
- ogg_sync_wrote(state->oy, bytes);
-
- if (ogg_sync_pageout(state->oy, &og) != 1) {
- if (bytes < CHUNKSIZE)
- state->lasterror = "Input truncated or empty.";
- else
- state->lasterror = "Input is not an Ogg bitstream.";
- goto err;
- }
-
- state->serial = ogg_page_serialno(&og);
-
- state->os = g_new(ogg_stream_state, 1);
- ogg_stream_init(state->os, state->serial);
-
- vorbis_info_init(&state->vi);
-
- state->vc = g_new(vorbis_comment, 1);
- vorbis_comment_init(state->vc);
-
- if (ogg_stream_pagein(state->os, &og) < 0) {
- state->lasterror = "Error reading first page of Ogg bitstream.";
- goto err;
- }
-
- if (ogg_stream_packetout(state->os, &header_main) != 1) {
- state->lasterror = "Error reading initial header packet.";
- goto err;
- }
-
- if (vorbis_synthesis_headerin(&state->vi, state->vc, &header_main) < 0) {
- state->lasterror = "Ogg bitstream does not contain vorbis data.";
- goto err;
- }
-
- state->mainlen = header_main.bytes;
- state->mainbuf = g_malloc(state->mainlen);
- memcpy(state->mainbuf, header_main.packet, header_main.bytes);
-
- i = 0;
- header = &header_comments;
- while (i < 2) {
- while (i < 2) {
- int result = ogg_sync_pageout(state->oy, &og);
- if (result == 0)
- break; /* Too little data so far */
- else if (result == 1) {
- ogg_stream_pagein(state->os, &og);
- while (i < 2) {
- result = ogg_stream_packetout(state->os, header);
- if (result == 0)
- break;
- if (result == -1) {
- state->lasterror = "Corrupt secondary header.";
- goto err;
- }
- vorbis_synthesis_headerin(&state->vi, state->vc, header);
- if (i == 1) {
- state->booklen = header->bytes;
- state->bookbuf = g_malloc(state->booklen);
- memcpy(state->bookbuf, header->packet, header->bytes);
- }
- i++;
- header = &header_codebooks;
- }
- }
- }
-
- buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
- bytes = state->read(buffer, 1, CHUNKSIZE, state->in);
- if (bytes == 0 && i < 2) {
- state->lasterror = "EOF before end of vorbis headers.";
- goto err;
- }
- ogg_sync_wrote(state->oy, bytes);
- }
-
- /* Copy the vendor tag */
- state->vendor = g_malloc(strlen(state->vc->vendor) + 1);
- strcpy(state->vendor, state->vc->vendor);
-
- /* Headers are done! */
- return 0;
-
- err:
- vcedit_clear_internals(state);
- return -1;
-}
-
-#if 0
-static void
-dump_state(vcedit_state * state)
-{
-}
-#endif
-
-int
-vcedit_write(vcedit_state * state, void *out)
-{
-
- ogg_stream_state streamout;
- ogg_packet header_main;
- ogg_packet header_comments;
- ogg_packet header_codebooks;
-
- ogg_page ogout, ogin;
- ogg_packet op;
- ogg_int64_t granpos = 0;
- int result;
- char *buffer;
- gint64 bytes;
- int needflush = 0, needout = 0;
-
- state->eosin = 0;
- state->extrapage = 0;
-
- header_main.bytes = state->mainlen;
- header_main.packet = state->mainbuf;
- header_main.b_o_s = 1;
- header_main.e_o_s = 0;
- header_main.granulepos = 0;
-
- header_codebooks.bytes = state->booklen;
- header_codebooks.packet = state->bookbuf;
- header_codebooks.b_o_s = 0;
- header_codebooks.e_o_s = 0;
- header_codebooks.granulepos = 0;
-
- ogg_stream_init(&streamout, state->serial);
-
- _commentheader_out(state->vc, state->vendor, &header_comments);
-
- ogg_stream_packetin(&streamout, &header_main);
- ogg_stream_packetin(&streamout, &header_comments);
- ogg_stream_packetin(&streamout, &header_codebooks);
-
- while ((result = ogg_stream_flush(&streamout, &ogout))) {
- if (state->write(ogout.header, 1, ogout.header_len, out) !=
- (size_t) ogout.header_len)
- goto cleanup;
- if (state->write(ogout.body, 1, ogout.body_len, out) !=
- (size_t) ogout.body_len)
- goto cleanup;
- }
-
- while (_fetch_next_packet(state, &op, &ogin)) {
- int size;
- size = _blocksize(state, &op);
- granpos += size;
-
- if (needflush) {
- if (ogg_stream_flush(&streamout, &ogout)) {
- if (state->write(ogout.header, 1, ogout.header_len,
- out) != (size_t) ogout.header_len)
- goto cleanup;
- if (state->write(ogout.body, 1, ogout.body_len,
- out) != (size_t) ogout.body_len)
- goto cleanup;
- }
- }
- else if (needout) {
- if (ogg_stream_pageout(&streamout, &ogout)) {
- if (state->write(ogout.header, 1, ogout.header_len,
- out) != (size_t) ogout.header_len)
- goto cleanup;
- if (state->write(ogout.body, 1, ogout.body_len,
- out) != (size_t) ogout.body_len)
- goto cleanup;
- }
- }
-
- needflush = needout = 0;
-
- if (op.granulepos == -1) {
- op.granulepos = granpos;
- ogg_stream_packetin(&streamout, &op);
- }
- else { /* granulepos is set, validly. Use it, and force a flush to
- account for shortened blocks (vcut) when appropriate */
- if (granpos > op.granulepos) {
- granpos = op.granulepos;
- ogg_stream_packetin(&streamout, &op);
- needflush = 1;
- }
- else {
- ogg_stream_packetin(&streamout, &op);
- needout = 1;
- }
- }
- }
-
- streamout.e_o_s = 1;
- while (ogg_stream_flush(&streamout, &ogout)) {
- if (state->write(ogout.header, 1, ogout.header_len,
- out) != (size_t) ogout.header_len)
- goto cleanup;
- if (state->write(ogout.body, 1, ogout.body_len,
- out) != (size_t) ogout.body_len)
- goto cleanup;
- }
-
- /* FIXME: freeing this here probably leaks memory */
- /* Done with this, now */
- vorbis_info_clear(&state->vi);
-
- if (state->extrapage) {
- if (state->write(ogin.header, 1, ogin.header_len,
- out) != (size_t) ogin.header_len)
- goto cleanup;
- if (state->write(ogin.body, 1, ogin.body_len, out) !=
- (size_t) ogin.body_len)
- goto cleanup;
- }
-
- state->eosin = 0; /* clear it, because not all paths to here do */
- while (!state->eosin) { /* We reached eos, not eof */
- /* We copy the rest of the stream (other logical streams)
- * through, a page at a time. */
- while (1) {
- result = ogg_sync_pageout(state->oy, &ogout);
- if (result == 0)
- break;
- if (result < 0)
- state->lasterror = "Corrupt or missing data, continuing...";
- else {
- /* Don't bother going through the rest, we can just
- * write the page out now */
- if (state->write(ogout.header, 1, ogout.header_len,
- out) != (size_t) ogout.header_len)
- goto cleanup;
- if (state->write(ogout.body, 1, ogout.body_len, out) !=
- (size_t) ogout.body_len)
- goto cleanup;
- }
- }
- buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
- bytes = state->read(buffer, 1, CHUNKSIZE, state->in);
- ogg_sync_wrote(state->oy, bytes);
- if (bytes == 0) {
- state->eosin = 1;
- break;
- }
- }
-
-
- cleanup:
- ogg_stream_clear(&streamout);
- ogg_packet_clear(&header_comments);
-
- g_free(state->mainbuf);
- g_free(state->bookbuf);
-
- vcedit_clear_internals(state);
- if (!state->eosin) {
- state->lasterror =
- "Error writing stream to output. "
- "Output stream may be corrupted or truncated.";
- return -1;
- }
-
- return 0;
-}
diff --git a/src/vorbis/vcedit.cc b/src/vorbis/vcedit.cc
new file mode 100644
index 000000000000..6b650ae2be5c
--- /dev/null
+++ b/src/vorbis/vcedit.cc
@@ -0,0 +1,443 @@
+/* This program is licensed under the GNU Library General Public License, version 2,
+ * a copy of which is included with this program (LICENCE.LGPL).
+ *
+ * (c) 2000-2001 Michael Smith <msmith at labyrinth.net.au>
+ *
+ *
+ * Comment editing backend, suitable for use by nice frontend interfaces.
+ *
+ */
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ogg/ogg.h>
+#include <vorbis/codec.h>
+
+#include "vcedit.h"
+
+#define CHUNKSIZE 4096
+
+vcedit_state *
+vcedit_new_state(void)
+{
+ return g_new0(vcedit_state, 1);
+}
+
+const char *
+vcedit_error(vcedit_state * state)
+{
+ return state->lasterror;
+}
+
+vorbis_comment *
+vcedit_comments(vcedit_state * state)
+{
+ return state->vc;
+}
+
+static void
+vcedit_clear_internals(vcedit_state * state)
+{
+ if (state->vc) {
+ vorbis_comment_clear(state->vc);
+ g_free(state->vc);
+ state->vc = nullptr;
+ }
+ if (state->os) {
+ ogg_stream_clear(state->os);
+ g_free(state->os);
+ state->os = nullptr;
+ }
+ if (state->oy) {
+ ogg_sync_clear(state->oy);
+ g_free(state->oy);
+ state->oy = nullptr;
+ }
+ if (state->vendor) {
+ g_free(state->vendor);
+ state->vendor = nullptr;
+ }
+}
+
+void
+vcedit_clear(vcedit_state * state)
+{
+ if (state) {
+ vcedit_clear_internals(state);
+ g_free(state);
+ }
+}
+
+/* Next two functions pulled straight from libvorbis, apart from one change
+ * - we don't want to overwrite the vendor string.
+ */
+static void
+_v_writestring(oggpack_buffer * o, const char *s, int len)
+{
+ while (len--) {
+ oggpack_write(o, *s++, 8);
+ }
+}
+
+static int
+_commentheader_out(vorbis_comment * vc, char *vendor, ogg_packet * op)
+{
+ oggpack_buffer opb;
+
+ oggpack_writeinit(&opb);
+
+ /* preamble */
+ oggpack_write(&opb, 0x03, 8);
+ _v_writestring(&opb, "vorbis", 6);
+
+ /* vendor */
+ oggpack_write(&opb, strlen(vendor), 32);
+ _v_writestring(&opb, vendor, strlen(vendor));
+
+ /* comments */
+ oggpack_write(&opb, vc->comments, 32);
+ if (vc->comments) {
+ int i;
+ for (i = 0; i < vc->comments; i++) {
+ if (vc->user_comments[i]) {
+ oggpack_write(&opb, vc->comment_lengths[i], 32);
+ _v_writestring(&opb, vc->user_comments[i],
+ vc->comment_lengths[i]);
+ }
+ else {
+ oggpack_write(&opb, 0, 32);
+ }
+ }
+ }
+ oggpack_write(&opb, 1, 1);
+
+ op->packet = (unsigned char *) _ogg_malloc(oggpack_bytes(&opb));
+ memcpy(op->packet, opb.buffer, oggpack_bytes(&opb));
+
+ op->bytes = oggpack_bytes(&opb);
+ op->b_o_s = 0;
+ op->e_o_s = 0;
+ op->granulepos = 0;
+
+ return 0;
+}
+
+static int
+_blocksize(vcedit_state * s, ogg_packet * p)
+{
+ int size = vorbis_packet_blocksize(&s->vi, p);
+ int ret = (size + s->prevW) / 4;
+
+ if (!s->prevW) {
+ s->prevW = size;
+ return 0;
+ }
+
+ s->prevW = size;
+ return ret;
+}
+
+static int
+_fetch_next_packet(vcedit_state * s, ogg_packet * p, ogg_page * page)
+{
+ int result;
+ char *buffer;
+ int64_t bytes;
+
+ result = ogg_stream_packetout(s->os, p);
+
+ if (result > 0)
+ return 1;
+ else {
+ if (s->eosin)
+ return 0;
+ while (ogg_sync_pageout(s->oy, page) <= 0) {
+ buffer = ogg_sync_buffer(s->oy, CHUNKSIZE);
+ bytes = s->in->fread(buffer, 1, CHUNKSIZE);
+ ogg_sync_wrote(s->oy, bytes);
+ if (bytes == 0)
+ return 0;
+ }
+ if (ogg_page_eos(page))
+ s->eosin = 1;
+ else if (ogg_page_serialno(page) != s->serial) {
+ s->eosin = 1;
+ s->extrapage = 1;
+ return 0;
+ }
+
+ ogg_stream_pagein(s->os, page);
+ return _fetch_next_packet(s, p, page);
+ }
+}
+
+
+int
+vcedit_open(vcedit_state * state, VFSFile & in)
+{
+ char *buffer;
+ int64_t bytes, i;
+ ogg_packet *header;
+ ogg_packet header_main;
+ ogg_packet header_comments;
+ ogg_packet header_codebooks;
+ ogg_page og;
+
+ state->in = & in;
+
+ state->oy = g_new(ogg_sync_state, 1);
+ ogg_sync_init(state->oy);
+
+ buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
+
+ bytes = state->in->fread(buffer, 1, CHUNKSIZE);
+
+ ogg_sync_wrote(state->oy, bytes);
+
+ if (ogg_sync_pageout(state->oy, &og) != 1) {
+ if (bytes < CHUNKSIZE)
+ state->lasterror = "Input truncated or empty.";
+ else
+ state->lasterror = "Input is not an Ogg bitstream.";
+ goto err;
+ }
+
+ state->serial = ogg_page_serialno(&og);
+
+ state->os = g_new(ogg_stream_state, 1);
+ ogg_stream_init(state->os, state->serial);
+
+ vorbis_info_init(&state->vi);
+
+ state->vc = g_new(vorbis_comment, 1);
+ vorbis_comment_init(state->vc);
+
+ if (ogg_stream_pagein(state->os, &og) < 0) {
+ state->lasterror = "Error reading first page of Ogg bitstream.";
+ goto err;
+ }
+
+ if (ogg_stream_packetout(state->os, &header_main) != 1) {
+ state->lasterror = "Error reading initial header packet.";
+ goto err;
+ }
+
+ if (vorbis_synthesis_headerin(&state->vi, state->vc, &header_main) < 0) {
+ state->lasterror = "Ogg bitstream does not contain vorbis data.";
+ goto err;
+ }
+
+ state->mainlen = header_main.bytes;
+ state->mainbuf = g_new (unsigned char, state->mainlen);
+ memcpy(state->mainbuf, header_main.packet, header_main.bytes);
+
+ i = 0;
+ header = &header_comments;
+ while (i < 2) {
+ while (i < 2) {
+ int result = ogg_sync_pageout(state->oy, &og);
+ if (result == 0)
+ break; /* Too little data so far */
+ else if (result == 1) {
+ ogg_stream_pagein(state->os, &og);
+ while (i < 2) {
+ result = ogg_stream_packetout(state->os, header);
+ if (result == 0)
+ break;
+ if (result == -1) {
+ state->lasterror = "Corrupt secondary header.";
+ goto err;
+ }
+ vorbis_synthesis_headerin(&state->vi, state->vc, header);
+ if (i == 1) {
+ state->booklen = header->bytes;
+ state->bookbuf = g_new (unsigned char, state->booklen);
+ memcpy(state->bookbuf, header->packet, header->bytes);
+ }
+ i++;
+ header = &header_codebooks;
+ }
+ }
+ }
+
+ buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
+ bytes = state->in->fread(buffer, 1, CHUNKSIZE);
+ if (bytes == 0 && i < 2) {
+ state->lasterror = "EOF before end of vorbis headers.";
+ goto err;
+ }
+ ogg_sync_wrote(state->oy, bytes);
+ }
+
+ /* Copy the vendor tag */
+ state->vendor = g_strdup (state->vc->vendor);
+
+ /* Headers are done! */
+ return 0;
+
+ err:
+ vcedit_clear_internals(state);
+ return -1;
+}
+
+#if 0
+static void
+dump_state(vcedit_state * state)
+{
+}
+#endif
+
+int
+vcedit_write(vcedit_state * state, VFSFile & out)
+{
+
+ ogg_stream_state streamout;
+ ogg_packet header_main;
+ ogg_packet header_comments;
+ ogg_packet header_codebooks;
+
+ ogg_page ogout, ogin;
+ ogg_packet op;
+ ogg_int64_t granpos = 0;
+ int result;
+ char *buffer;
+ int64_t bytes;
+ int needflush = 0, needout = 0;
+
+ state->eosin = 0;
+ state->extrapage = 0;
+
+ header_main.bytes = state->mainlen;
+ header_main.packet = state->mainbuf;
+ header_main.b_o_s = 1;
+ header_main.e_o_s = 0;
+ header_main.granulepos = 0;
+
+ header_codebooks.bytes = state->booklen;
+ header_codebooks.packet = state->bookbuf;
+ header_codebooks.b_o_s = 0;
+ header_codebooks.e_o_s = 0;
+ header_codebooks.granulepos = 0;
+
+ ogg_stream_init(&streamout, state->serial);
+
+ _commentheader_out(state->vc, state->vendor, &header_comments);
+
+ ogg_stream_packetin(&streamout, &header_main);
+ ogg_stream_packetin(&streamout, &header_comments);
+ ogg_stream_packetin(&streamout, &header_codebooks);
+
+ while ((result = ogg_stream_flush(&streamout, &ogout))) {
+ if (out.fwrite(ogout.header, 1, ogout.header_len) != ogout.header_len)
+ goto cleanup;
+ if (out.fwrite(ogout.body, 1, ogout.body_len) != ogout.body_len)
+ goto cleanup;
+ }
+
+ while (_fetch_next_packet(state, &op, &ogin)) {
+ int size;
+ size = _blocksize(state, &op);
+ granpos += size;
+
+ if (needflush) {
+ if (ogg_stream_flush(&streamout, &ogout)) {
+ if (out.fwrite(ogout.header, 1, ogout.header_len) != ogout.header_len)
+ goto cleanup;
+ if (out.fwrite(ogout.body, 1, ogout.body_len) != ogout.body_len)
+ goto cleanup;
+ }
+ }
+ else if (needout) {
+ if (ogg_stream_pageout(&streamout, &ogout)) {
+ if (out.fwrite(ogout.header, 1, ogout.header_len) != ogout.header_len)
+ goto cleanup;
+ if (out.fwrite(ogout.body, 1, ogout.body_len) != ogout.body_len)
+ goto cleanup;
+ }
+ }
+
+ needflush = needout = 0;
+
+ if (op.granulepos == -1) {
+ op.granulepos = granpos;
+ ogg_stream_packetin(&streamout, &op);
+ }
+ else { /* granulepos is set, validly. Use it, and force a flush to
+ account for shortened blocks (vcut) when appropriate */
+ if (granpos > op.granulepos) {
+ granpos = op.granulepos;
+ ogg_stream_packetin(&streamout, &op);
+ needflush = 1;
+ }
+ else {
+ ogg_stream_packetin(&streamout, &op);
+ needout = 1;
+ }
+ }
+ }
+
+ streamout.e_o_s = 1;
+ while (ogg_stream_flush(&streamout, &ogout)) {
+ if (out.fwrite(ogout.header, 1, ogout.header_len) != ogout.header_len)
+ goto cleanup;
+ if (out.fwrite(ogout.body, 1, ogout.body_len) != ogout.body_len)
+ goto cleanup;
+ }
+
+ /* FIXME: freeing this here probably leaks memory */
+ /* Done with this, now */
+ vorbis_info_clear(&state->vi);
+
+ if (state->extrapage) {
+ if (out.fwrite(ogin.header, 1, ogin.header_len) != ogin.header_len)
+ goto cleanup;
+ if (out.fwrite(ogin.body, 1, ogin.body_len) != ogin.body_len)
+ goto cleanup;
+ }
+
+ state->eosin = 0; /* clear it, because not all paths to here do */
+ while (!state->eosin) { /* We reached eos, not eof */
+ /* We copy the rest of the stream (other logical streams)
+ * through, a page at a time. */
+ while (1) {
+ result = ogg_sync_pageout(state->oy, &ogout);
+ if (result == 0)
+ break;
+ if (result < 0)
+ state->lasterror = "Corrupt or missing data, continuing...";
+ else {
+ /* Don't bother going through the rest, we can just
+ * write the page out now */
+ if (out.fwrite(ogout.header, 1, ogout.header_len) != ogout.header_len)
+ goto cleanup;
+ if (out.fwrite(ogout.body, 1, ogout.body_len) != ogout.body_len)
+ goto cleanup;
+ }
+ }
+ buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
+ bytes = state->in->fread(buffer, 1, CHUNKSIZE);
+ ogg_sync_wrote(state->oy, bytes);
+ if (bytes == 0) {
+ state->eosin = 1;
+ break;
+ }
+ }
+
+
+ cleanup:
+ ogg_stream_clear(&streamout);
+ ogg_packet_clear(&header_comments);
+
+ g_free(state->mainbuf);
+ g_free(state->bookbuf);
+
+ vcedit_clear_internals(state);
+ if (!state->eosin) {
+ state->lasterror =
+ "Error writing stream to output. "
+ "Output stream may be corrupted or truncated.";
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/vorbis/vcedit.h b/src/vorbis/vcedit.h
index ea4432f8f298..a26239555101 100644
--- a/src/vorbis/vcedit.h
+++ b/src/vorbis/vcedit.h
@@ -10,17 +10,9 @@
#ifndef __VCEDIT_H
#define __VCEDIT_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
#include <ogg/ogg.h>
#include <vorbis/codec.h>
-#include <audacious/plugin.h>
-
-typedef gint64 (*vcedit_read_func)(void *, gint64, gint64, void *);
-typedef gint64 (*vcedit_write_func)(const void *, gint64, gint64, void *);
+#include <libaudcore/plugin.h>
typedef struct {
ogg_sync_state *oy;
@@ -29,16 +21,13 @@ typedef struct {
vorbis_comment *vc;
vorbis_info vi;
- vcedit_read_func read;
- vcedit_write_func write;
-
- void *in;
+ VFSFile *in;
long serial;
unsigned char *mainbuf;
unsigned char *bookbuf;
int mainlen;
int booklen;
- char *lasterror;
+ const char *lasterror;
char *vendor;
int prevW;
int extrapage;
@@ -48,16 +37,9 @@ typedef struct {
extern vcedit_state *vcedit_new_state(void);
extern void vcedit_clear(vcedit_state *state);
extern vorbis_comment *vcedit_comments(vcedit_state *state);
-extern int vcedit_open(vcedit_state *state, VFSFile *in);
-extern int vcedit_open_callbacks(vcedit_state *state, void *in,
- vcedit_read_func read_func,
- vcedit_write_func write_func);
-extern int vcedit_write(vcedit_state *state, void *out);
-extern char *vcedit_error(vcedit_state *state);
-
-#ifdef __cplusplus
-}
-#endif
+extern int vcedit_open(vcedit_state *state, VFSFile &in);
+extern int vcedit_write(vcedit_state *state, VFSFile &out);
+extern const char *vcedit_error(vcedit_state *state);
#endif /* __VCEDIT_H */
diff --git a/src/vorbis/vcupdate.c b/src/vorbis/vcupdate.c
deleted file mode 100644
index 7a65bd5fec2e..000000000000
--- a/src/vorbis/vcupdate.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/* Audacious - Cross-platform multimedia player
- * Copyright (C) 2005-2007 Audacious development team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- */
-
-#include <ogg/ogg.h>
-#include <vorbis/codec.h>
-#include <vorbis/vorbisfile.h>
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#include <audacious/debug.h>
-#include <audacious/plugin.h>
-#include <audacious/i18n.h>
-#include <libaudcore/audstrings.h>
-
-#include "vorbis.h"
-#include "vcedit.h"
-
-static gboolean write_and_pivot_files(vcedit_state * state);
-
-static GHashTable * dictionary_from_vorbis_comment (vorbis_comment * vc)
-{
- gint i;
-
- GHashTable * dict = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) str_unref, (GDestroyNotify) str_unref);
-
- for (i = 0; i < vc->comments; i++) {
- gchar **frags;
-
- AUDDBG("%s\n", vc->user_comments[i]);
- frags = g_strsplit(vc->user_comments[i], "=", 2);
-
- if (frags[0] && frags[1])
- {
- gchar * key = g_ascii_strdown (frags[0], -1);
- g_hash_table_insert (dict, str_get (key), str_get (frags[1]));
- g_free (key);
- }
-
- g_strfreev(frags); /* Don't use g_free() for string lists! --eugene */
- }
-
- return dict;
-}
-
-static void add_tag_cb (void * key, void * field, void * vc)
-{
- vorbis_comment_add_tag (vc, key, field);
-}
-
-static void dictionary_to_vorbis_comment (vorbis_comment * vc, GHashTable * dict)
-{
- vorbis_comment_clear(vc);
- g_hash_table_foreach (dict, add_tag_cb, vc);
-}
-
-static void insert_str_tuple_field_to_dictionary (const Tuple * tuple, int
- fieldn, GHashTable * dict, const char * key)
-{
- char * val = tuple_get_str (tuple, fieldn);
-
- if (val && val[0])
- g_hash_table_insert (dict, str_get (key), str_ref (val));
- else
- g_hash_table_remove (dict, key);
-
- str_unref(val);
-}
-
-static void insert_int_tuple_field_to_dictionary (const Tuple * tuple, int
- fieldn, GHashTable * dict, const char * key)
-{
- int val = tuple_get_int (tuple, fieldn);
-
- if (val > 0)
- g_hash_table_insert (dict, str_get (key), int_to_str (val));
- else
- g_hash_table_remove (dict, key);
-}
-
-gboolean vorbis_update_song_tuple (const char * filename, VFSFile * fd, const Tuple * tuple)
-{
-
- vcedit_state *state;
- vorbis_comment *comment;
- gboolean ret;
-
- if(!tuple || !fd) return FALSE;
-
- state = vcedit_new_state();
-
- if(vcedit_open(state, fd) < 0) {
- vcedit_clear(state);
- return FALSE;
- }
-
- comment = vcedit_comments(state);
- GHashTable * dict = dictionary_from_vorbis_comment (comment);
-
- insert_str_tuple_field_to_dictionary(tuple, FIELD_TITLE, dict, "title");
- insert_str_tuple_field_to_dictionary(tuple, FIELD_ARTIST, dict, "artist");
- insert_str_tuple_field_to_dictionary(tuple, FIELD_ALBUM, dict, "album");
- insert_str_tuple_field_to_dictionary(tuple, FIELD_COMMENT, dict, "comment");
- insert_str_tuple_field_to_dictionary(tuple, FIELD_GENRE, dict, "genre");
-
- insert_int_tuple_field_to_dictionary(tuple, FIELD_YEAR, dict, "date");
- insert_int_tuple_field_to_dictionary(tuple, FIELD_TRACK_NUMBER, dict, "tracknumber");
-
- dictionary_to_vorbis_comment(comment, dict);
- g_hash_table_destroy (dict);
-
- ret = write_and_pivot_files(state);
-
- vcedit_clear(state);
-
- return ret;
-}
-
-#define COPY_BUF 65536
-
-gboolean copy_vfs (VFSFile * in, VFSFile * out)
-{
- if (vfs_fseek (in, 0, SEEK_SET) < 0 || vfs_fseek (out, 0, SEEK_SET) < 0)
- return FALSE;
-
- gchar * buffer = g_malloc (COPY_BUF);
- gint64 size = 0, readed;
-
- while ((readed = vfs_fread (buffer, 1, COPY_BUF, in)) > 0)
- {
- if (vfs_fwrite (buffer, 1, readed, out) != readed)
- goto FAILED;
-
- size += readed;
- }
-
- if (vfs_ftruncate (out, size) < 0)
- goto FAILED;
-
- g_free (buffer);
- return TRUE;
-
-FAILED:
- g_free (buffer);
- return FALSE;
-}
-
-#undef COPY_BUF
-
-gboolean write_and_pivot_files (vcedit_state * state)
-{
- gchar * temp;
- GError * error;
- gint handle = g_file_open_tmp (NULL, & temp, & error);
-
- if (handle < 0)
- {
- fprintf (stderr, "Failed to create temp file: %s.\n", error->message);
- g_error_free (error);
- return FALSE;
- }
-
- close (handle);
-
- gchar * temp_uri = filename_to_uri (temp);
- g_return_val_if_fail (temp_uri, FALSE);
- VFSFile * temp_vfs = vfs_fopen (temp_uri, "r+");
- g_return_val_if_fail (temp_vfs, FALSE);
-
- str_unref (temp_uri);
-
- if (vcedit_write (state, temp_vfs) < 0)
- {
- fprintf (stderr, "Tag update failed: %s.\n", state->lasterror);
- vfs_fclose (temp_vfs);
- g_free (temp);
- return FALSE;
- }
-
- if (! copy_vfs (temp_vfs, state->in))
- {
- fprintf (stderr, "Failed to copy temp file. The temp file has not "
- "been deleted: %s.\n", temp);
- vfs_fclose (temp_vfs);
- g_free (temp);
- return FALSE;
- }
-
- vfs_fclose (temp_vfs);
-
- if (g_unlink (temp) < 0)
- fprintf (stderr, "Failed to delete temp file: %s.\n", temp);
-
- g_free (temp);
- return TRUE;
-}
diff --git a/src/vorbis/vcupdate.cc b/src/vorbis/vcupdate.cc
new file mode 100644
index 000000000000..096ff10f43b0
--- /dev/null
+++ b/src/vorbis/vcupdate.cc
@@ -0,0 +1,210 @@
+/* Audacious - Cross-platform multimedia player
+ * Copyright (C) 2005-2007 Audacious development team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <ogg/ogg.h>
+#include <vorbis/codec.h>
+#include <vorbis/vorbisfile.h>
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/multihash.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+#include "vorbis.h"
+#include "vcedit.h"
+
+static bool write_and_pivot_files(vcedit_state * state);
+
+typedef SimpleHash<String, String> Dictionary;
+
+static Dictionary dictionary_from_vorbis_comment (vorbis_comment * vc)
+{
+ Dictionary dict;
+
+ for (int i = 0; i < vc->comments; i ++)
+ {
+ char **frags;
+
+ AUDDBG("%s\n", vc->user_comments[i]);
+ frags = g_strsplit(vc->user_comments[i], "=", 2);
+
+ if (frags[0] && frags[1])
+ {
+ char * key = g_ascii_strdown (frags[0], -1);
+ dict.add (String (key), String (frags[1]));
+ g_free (key);
+ }
+
+ g_strfreev(frags); /* Don't use g_free() for string lists! --eugene */
+ }
+
+ return dict;
+}
+
+static void add_tag_cb (const String & key, String & field, void * vc)
+{
+ vorbis_comment_add_tag ((vorbis_comment *) vc, key, field);
+}
+
+static void dictionary_to_vorbis_comment (vorbis_comment * vc, Dictionary & dict)
+{
+ vorbis_comment_clear(vc);
+ dict.iterate (add_tag_cb, vc);
+}
+
+static void insert_str_tuple_field_to_dictionary (const Tuple & tuple,
+ Tuple::Field field, Dictionary & dict, const char * key)
+{
+ String val = tuple.get_str (field);
+
+ if (val && val[0])
+ dict.add (String (key), std::move (val));
+ else
+ dict.remove (String (key));
+}
+
+static void insert_int_tuple_field_to_dictionary (const Tuple & tuple,
+ Tuple::Field field, Dictionary & dict, const char * key)
+{
+ int val = tuple.get_int (field);
+
+ if (val > 0)
+ dict.add (String (key), String (int_to_str (val)));
+ else
+ dict.remove (String (key));
+}
+
+bool VorbisPlugin::write_tuple (const char * filename, VFSFile & file, const Tuple & tuple)
+{
+ vcedit_state *state;
+ vorbis_comment *comment;
+ bool ret;
+
+ state = vcedit_new_state();
+
+ if(vcedit_open(state, file) < 0) {
+ vcedit_clear(state);
+ return false;
+ }
+
+ comment = vcedit_comments(state);
+ Dictionary dict = dictionary_from_vorbis_comment (comment);
+
+ insert_str_tuple_field_to_dictionary(tuple, Tuple::Title, dict, "title");
+ insert_str_tuple_field_to_dictionary(tuple, Tuple::Artist, dict, "artist");
+ insert_str_tuple_field_to_dictionary(tuple, Tuple::Album, dict, "album");
+ insert_str_tuple_field_to_dictionary(tuple, Tuple::Comment, dict, "comment");
+ insert_str_tuple_field_to_dictionary(tuple, Tuple::Genre, dict, "genre");
+
+ insert_int_tuple_field_to_dictionary(tuple, Tuple::Year, dict, "date");
+ insert_int_tuple_field_to_dictionary(tuple, Tuple::Track, dict, "tracknumber");
+
+ dictionary_to_vorbis_comment(comment, dict);
+
+ ret = write_and_pivot_files(state);
+
+ vcedit_clear(state);
+
+ return ret;
+}
+
+#define COPY_BUF 65536
+
+bool copy_vfs (VFSFile & in, VFSFile & out)
+{
+ if (in.fseek (0, VFS_SEEK_SET) < 0 || out.fseek (0, VFS_SEEK_SET) < 0)
+ return false;
+
+ char * buffer = g_new (char, COPY_BUF);
+ int64_t size = 0, readed;
+
+ while ((readed = in.fread (buffer, 1, COPY_BUF)) > 0)
+ {
+ if (out.fwrite (buffer, 1, readed) != readed)
+ goto FAILED;
+
+ size += readed;
+ }
+
+ if (out.ftruncate (size) < 0)
+ goto FAILED;
+
+ g_free (buffer);
+ return true;
+
+FAILED:
+ g_free (buffer);
+ return false;
+}
+
+#undef COPY_BUF
+
+bool write_and_pivot_files (vcedit_state * state)
+{
+ char * temp;
+ GError * error;
+ int handle = g_file_open_tmp (nullptr, & temp, & error);
+
+ if (handle < 0)
+ {
+ AUDERR ("Failed to create temp file: %s.\n", error->message);
+ g_error_free (error);
+ return false;
+ }
+
+ close (handle);
+
+ StringBuf temp_uri = filename_to_uri (temp);
+ g_return_val_if_fail (temp_uri, false);
+ VFSFile temp_vfs (temp_uri, "r+");
+ g_return_val_if_fail (temp_vfs, false);
+
+ if (vcedit_write (state, temp_vfs) < 0)
+ {
+ AUDERR ("Tag update failed: %s.\n", state->lasterror);
+ g_free (temp);
+ return false;
+ }
+
+ if (! copy_vfs (temp_vfs, * state->in))
+ {
+ AUDERR ("Failed to copy temp file. The temp file has not "
+ "been deleted: %s.\n", temp);
+ g_free (temp);
+ return false;
+ }
+
+ temp_vfs = VFSFile ();
+
+ if (g_unlink (temp) < 0)
+ AUDERR ("Failed to delete temp file: %s.\n", temp);
+
+ g_free (temp);
+ return true;
+}
diff --git a/src/vorbis/vorbis.c b/src/vorbis/vorbis.c
deleted file mode 100644
index 868456e1a020..000000000000
--- a/src/vorbis/vorbis.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * Copyright (C) Tony Arcieri <bascule at inferno.tusculum.edu>
- * Copyright (C) 2001-2002 Håvard Kvålen <havardk at xmms.org>
- * Copyright (C) 2007 William Pitcock <nenolod at sacredspiral.co.uk>
- * Copyright (C) 2008 Cristi MÄgheruÈan <majeru at gentoo.ro>
- * Copyright (C) 2008 Eugene Zagidullin <e.asphyx at gmail.com>
- * Copyright (C) 2009-2011 Audacious Developers
- *
- * ReplayGain processing Copyright (C) 2002 Gian-Carlo Pascutto <gcp at sjeng.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- */
-
-/*#define AUD_DEBUG
-#define DEBUG*/
-
-#include <glib.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include <ogg/ogg.h>
-#include <vorbis/codec.h>
-#include <vorbis/vorbisfile.h>
-
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-#include "vorbis.h"
-
-static size_t ovcb_read (void * buffer, size_t size, size_t count, void * file)
-{
- return vfs_fread (buffer, size, count, file);
-}
-
-static int ovcb_seek (void * file, ogg_int64_t offset, int whence)
-{
- return vfs_fseek (file, offset, whence);
-}
-
-static int ovcb_close (void * file)
-{
- return 0;
-}
-
-static long ovcb_tell (void * file)
-{
- return vfs_ftell (file);
-}
-
-ov_callbacks vorbis_callbacks = {
- ovcb_read,
- ovcb_seek,
- ovcb_close,
- ovcb_tell
-};
-
-ov_callbacks vorbis_callbacks_stream = {
- ovcb_read,
- NULL,
- ovcb_close,
- NULL
-};
-
-static bool_t vorbis_check_fd (const char * filename, VFSFile * file)
-{
- ogg_sync_state oy = {0};
- ogg_stream_state os = {0};
- ogg_page og = {0};
- ogg_packet op = {0};
-
- bool_t result = FALSE;
-
- ogg_sync_init (& oy);
-
- while (1)
- {
- int64_t bytes = ogg_sync_pageseek (& oy, & og);
-
- if (bytes < 0) /* skipped some bytes */
- continue;
- if (bytes > 0) /* got a page */
- break;
-
- void * buffer = ogg_sync_buffer (& oy, 2048);
- bytes = vfs_fread (buffer, 1, 2048, file);
-
- if (bytes <= 0)
- goto end;
-
- ogg_sync_wrote (& oy, bytes);
- }
-
- if (! ogg_page_bos (& og))
- goto end;
-
- ogg_stream_init (& os, ogg_page_serialno (& og));
- ogg_stream_pagein (& os, & og);
-
- if (ogg_stream_packetout (& os, & op) > 0 && vorbis_synthesis_idheader (& op))
- result = TRUE;
-
-end:
- ogg_sync_clear (& oy);
- ogg_stream_clear (& os);
-
- return result;
-}
-
-static void
-set_tuple_str(Tuple *tuple, const gint nfield,
- vorbis_comment *comment, gchar *key)
-{
- tuple_set_str (tuple, nfield, vorbis_comment_query (comment, key, 0));
-}
-
-static Tuple *
-get_tuple_for_vorbisfile(OggVorbis_File * vorbisfile, const gchar *filename)
-{
- Tuple *tuple;
- gint length;
- vorbis_comment *comment = NULL;
-
- tuple = tuple_new_from_filename(filename);
-
- length = vfs_is_streaming (vorbisfile->datasource) ? -1 : ov_time_total
- (vorbisfile, -1) * 1000;
-
- /* associate with tuple */
- tuple_set_int(tuple, FIELD_LENGTH, length);
-
- if ((comment = ov_comment(vorbisfile, -1)) != NULL) {
- gchar *tmps;
- set_tuple_str(tuple, FIELD_TITLE, comment, "title");
- set_tuple_str(tuple, FIELD_ARTIST, comment, "artist");
- set_tuple_str(tuple, FIELD_ALBUM, comment, "album");
- set_tuple_str(tuple, FIELD_GENRE, comment, "genre");
- set_tuple_str(tuple, FIELD_COMMENT, comment, "comment");
-
- if ((tmps = vorbis_comment_query(comment, "tracknumber", 0)) != NULL)
- tuple_set_int(tuple, FIELD_TRACK_NUMBER, atoi(tmps));
-
- if ((tmps = vorbis_comment_query (comment, "date", 0)) != NULL)
- tuple_set_int (tuple, FIELD_YEAR, atoi (tmps));
- }
-
- vorbis_info * info = ov_info (vorbisfile, -1);
- tuple_set_format (tuple, "Ogg Vorbis", info->channels, info->rate,
- info->bitrate_nominal / 1000);
-
- tuple_set_str(tuple, FIELD_MIMETYPE, "application/ogg");
-
- return tuple;
-}
-
-static gfloat atof_no_locale (const gchar * string)
-{
- gfloat result = 0;
- gboolean negative = FALSE;
-
- if (* string == '+')
- string ++;
- else if (* string == '-')
- {
- negative = TRUE;
- string ++;
- }
-
- while (* string >= '0' && * string <= '9')
- result = 10 * result + (* string ++ - '0');
-
- if (* string == '.')
- {
- gfloat place = 0.1;
-
- string ++;
-
- while (* string >= '0' && * string <= '9')
- {
- result += (* string ++ - '0') * place;
- place *= 0.1;
- }
- }
-
- return negative ? -result : result;
-}
-
-static gboolean
-vorbis_update_replaygain(OggVorbis_File *vf, ReplayGainInfo *rg_info)
-{
- vorbis_comment *comment;
- gchar *rg_gain, *rg_peak;
-
- if (vf == NULL || rg_info == NULL || (comment = ov_comment(vf, -1)) == NULL)
- {
-#ifdef DEBUG
- printf ("No replay gain info.\n");
-#endif
- return FALSE;
- }
-
- rg_gain = vorbis_comment_query(comment, "replaygain_album_gain", 0);
- if (!rg_gain) rg_gain = vorbis_comment_query(comment, "rg_audiophile", 0); /* Old */
- rg_info->album_gain = (rg_gain != NULL) ? atof_no_locale (rg_gain) : 0.0;
-#ifdef DEBUG
- printf ("Album gain: %s (%f)\n", rg_gain, rg_info->album_gain);
-#endif
-
- rg_gain = vorbis_comment_query(comment, "replaygain_track_gain", 0);
- if (!rg_gain) rg_gain = vorbis_comment_query(comment, "rg_radio", 0); /* Old */
- rg_info->track_gain = (rg_gain != NULL) ? atof_no_locale (rg_gain) : 0.0;
-#ifdef DEBUG
- printf ("Track gain: %s (%f)\n", rg_gain, rg_info->track_gain);
-#endif
-
- rg_peak = vorbis_comment_query(comment, "replaygain_album_peak", 0);
- rg_info->album_peak = rg_peak != NULL ? atof_no_locale (rg_peak) : 0.0;
-#ifdef DEBUG
- printf ("Album peak: %s (%f)\n", rg_peak, rg_info->album_peak);
-#endif
-
- rg_peak = vorbis_comment_query(comment, "replaygain_track_peak", 0);
- if (!rg_peak) rg_peak = vorbis_comment_query(comment, "rg_peak", 0); /* Old */
- rg_info->track_peak = rg_peak != NULL ? atof_no_locale (rg_peak) : 0.0;
-#ifdef DEBUG
- printf ("Track peak: %s (%f)\n", rg_peak, rg_info->track_peak);
-#endif
-
- return TRUE;
-}
-
-static long
-vorbis_interleave_buffer(float **pcm, int samples, int ch, float *pcmout)
-{
- int i, j;
- for (i = 0; i < samples; i++)
- for (j = 0; j < ch; j++)
- *pcmout++ = pcm[j][i];
-
- return ch * samples * sizeof(float);
-}
-
-
-#define PCM_FRAMES 1024
-#define PCM_BUFSIZE (PCM_FRAMES * 2)
-
-static gboolean vorbis_play (const gchar * filename, VFSFile * file)
-{
- if (file == NULL)
- return FALSE;
-
- vorbis_info *vi;
- OggVorbis_File vf;
- gint last_section = -1;
- ReplayGainInfo rg_info;
- gfloat pcmout[PCM_BUFSIZE*sizeof(float)], **pcm;
- gint bytes, channels, samplerate, br;
- gchar * title = NULL;
-
- memset(&vf, 0, sizeof(vf));
-
- gboolean error = FALSE;
-
- if (ov_open_callbacks (file, & vf, NULL, 0, vfs_is_streaming (file) ?
- vorbis_callbacks_stream : vorbis_callbacks) < 0)
- {
- error = TRUE;
- goto play_cleanup;
- }
-
- vi = ov_info(&vf, -1);
-
- if (vi->channels > 2)
- goto play_cleanup;
-
- br = vi->bitrate_nominal;
- channels = vi->channels;
- samplerate = vi->rate;
-
- aud_input_set_bitrate (br);
-
- if (!aud_input_open_audio(FMT_FLOAT, samplerate, channels)) {
- error = TRUE;
- goto play_cleanup;
- }
-
- vorbis_update_replaygain(&vf, &rg_info);
- aud_input_set_gain (& rg_info);
-
- /*
- * Note that chaining changes things here; A vorbis file may
- * be a mix of different channels, bitrates and sample rates.
- * You can fetch the information for any section of the file
- * using the ov_ interface.
- */
-
- while (! aud_input_check_stop ())
- {
- int seek_value = aud_input_check_seek();
-
- if (seek_value >= 0 && ov_time_seek (& vf, (double) seek_value / 1000) < 0)
- {
- fprintf (stderr, "vorbis: seek failed\n");
- error = TRUE;
- break;
- }
-
- gint current_section = last_section;
- bytes = ov_read_float(&vf, &pcm, PCM_FRAMES, ¤t_section);
- if (bytes == OV_HOLE)
- continue;
-
- if (bytes <= 0)
- break;
-
- bytes = vorbis_interleave_buffer (pcm, bytes, channels, pcmout);
-
- { /* try to detect when metadata has changed */
- vorbis_comment * comment = ov_comment (& vf, -1);
- const gchar * new_title = (comment == NULL) ? NULL :
- vorbis_comment_query (comment, "title", 0);
-
- if (new_title != NULL && (title == NULL || strcmp (title, new_title)))
- {
- g_free (title);
- title = g_strdup (new_title);
-
- aud_input_set_tuple (get_tuple_for_vorbisfile (& vf,
- filename));
- }
- }
-
- if (current_section != last_section)
- {
- /*
- * The info struct is different in each section. vf
- * holds them all for the given bitstream. This
- * requests the current one
- */
- vi = ov_info(&vf, -1);
-
- if (vi->channels > 2)
- goto stop_processing;
-
- if (vi->rate != samplerate || vi->channels != channels)
- {
- samplerate = vi->rate;
- channels = vi->channels;
-
- if (!aud_input_open_audio(FMT_FLOAT, vi->rate, vi->channels)) {
- error = TRUE;
- goto stop_processing;
- }
-
- vorbis_update_replaygain(&vf, &rg_info);
- aud_input_set_gain (& rg_info); /* audio reopened */
- }
- }
-
- aud_input_write_audio (pcmout, bytes);
-
-stop_processing:
-
- if (current_section != last_section)
- {
- aud_input_set_bitrate (br);
- last_section = current_section;
- }
- } /* main loop */
-
-play_cleanup:
-
- ov_clear(&vf);
- g_free (title);
- return ! error;
-}
-
-static Tuple * get_song_tuple (const gchar * filename, VFSFile * file)
-{
- OggVorbis_File vfile; /* avoid thread interaction */
- Tuple *tuple = NULL;
-
- /*
- * The open function performs full stream detection and
- * machine initialization. If it returns zero, the stream
- * *is* Vorbis and we're fully ready to decode.
- */
- if (ov_open_callbacks (file, & vfile, NULL, 0, vfs_is_streaming (file) ?
- vorbis_callbacks_stream : vorbis_callbacks) < 0)
- return NULL;
-
- tuple = get_tuple_for_vorbisfile(&vfile, filename);
- ov_clear(&vfile);
- return tuple;
-}
-
-static gboolean get_song_image (const gchar * filename, VFSFile * file,
- void * * data, gint64 * size)
-{
- OggVorbis_File vfile;
-
- if (ov_open_callbacks (file, & vfile, NULL, 0, vfs_is_streaming (file) ?
- vorbis_callbacks_stream : vorbis_callbacks) < 0)
- return FALSE;
-
- vorbis_comment * comment = ov_comment (& vfile, -1);
- if (! comment)
- goto ERR;
-
- const gchar * s;
-
- if ((s = vorbis_comment_query (comment, "METADATA_BLOCK_PICTURE", 0)))
- {
- gsize length2;
- void * data2 = g_base64_decode (s, & length2);
- if (! data2 || length2 < 8)
- goto PARSE_ERR;
-
- gint mime_length = GUINT32_FROM_BE (* (guint32 *) (data2 + 4));
- if (length2 < 8 + mime_length + 4)
- goto PARSE_ERR;
-
- gint desc_length = GUINT32_FROM_BE (* (guint32 *) (data2 + 8 + mime_length));
- if (length2 < 8 + mime_length + 4 + desc_length + 20)
- goto PARSE_ERR;
-
- * size = GUINT32_FROM_BE (* (guint32 *) (data2 + 8 + mime_length + 4 + desc_length + 16));
- if (length2 < 8 + mime_length + 4 + desc_length + 20 + * size)
- goto PARSE_ERR;
-
- * data = g_memdup ((char *) data2 + 8 + mime_length + 4 + desc_length + 20, * size);
-
- g_free (data2);
- ov_clear (& vfile);
- return TRUE;
-
- PARSE_ERR:
- fprintf (stderr, "vorbis: Error parsing METADATA_BLOCK_PICTURE in %s.\n", filename);
- g_free (data2);
- }
-
- if ((s = vorbis_comment_query (comment, "COVERART", 0)))
- {
- gsize length2;
- void * data2 = g_base64_decode (s, & length2);
-
- if (! data2 || ! length2)
- {
- fprintf (stderr, "vorbis: Error parsing COVERART in %s.\n", filename);
- g_free (data2);
- goto ERR;
- }
-
- * data = data2;
- * size = length2;
-
- ov_clear (& vfile);
- return TRUE;
- }
-
-ERR:
- ov_clear (& vfile);
- return FALSE;
-}
-
-static const char vorbis_about[] =
- N_("Audacious Ogg Vorbis Decoder\n\n"
- "Based on the Xiph.org Foundation's Ogg Vorbis Plugin:\n"
- "http://www.xiph.org/\n\n"
- "Original code by:\n"
- "Tony Arcieri <bascule at inferno.tusculum.edu>\n\n"
- "Contributions from:\n"
- "Chris Montgomery <monty at xiph.org>\n"
- "Peter Alm <peter at xmms.org>\n"
- "Michael Smith <msmith at labyrinth.edu.au>\n"
- "Jack Moffitt <jack at icecast.org>\n"
- "Jorn Baayen <jorn at nl.linux.org>\n"
- "Håvard Kvålen <havardk at xmms.org>\n"
- "Gian-Carlo Pascutto <gcp at sjeng.org>\n"
- "Eugene Zagidullin <e.asphyx at gmail.com>");
-
-static const gchar *vorbis_fmts[] = { "ogg", "ogm", "oga", NULL };
-static const gchar * const mimes[] = {"application/ogg", NULL};
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("Ogg Vorbis Decoder"),
- .domain = PACKAGE,
- .about_text = vorbis_about,
- .play = vorbis_play,
- .probe_for_tuple = get_song_tuple,
- .get_song_image = get_song_image,
- .update_song_tuple = vorbis_update_song_tuple,
- .is_our_file_from_vfs = vorbis_check_fd,
- .extensions = vorbis_fmts,
- .mimes = mimes,
-
- /* medium-high priority (a little slow) */
- .priority = 2,
-)
diff --git a/src/vorbis/vorbis.cc b/src/vorbis/vorbis.cc
new file mode 100644
index 000000000000..531ec95fe082
--- /dev/null
+++ b/src/vorbis/vorbis.cc
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) Tony Arcieri <bascule at inferno.tusculum.edu>
+ * Copyright (C) 2001-2002 Håvard Kvålen <havardk at xmms.org>
+ * Copyright (C) 2007 William Pitcock <nenolod at sacredspiral.co.uk>
+ * Copyright (C) 2008 Cristi MÄgheruÈan <majeru at gentoo.ro>
+ * Copyright (C) 2008 Eugene Zagidullin <e.asphyx at gmail.com>
+ * Copyright (C) 2009-2011 Audacious Developers
+ *
+ * ReplayGain processing Copyright (C) 2002 Gian-Carlo Pascutto <gcp at sjeng.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <ogg/ogg.h>
+#include <vorbis/codec.h>
+#include <vorbis/vorbisfile.h>
+
+#define WANT_AUD_BSWAP
+#define WANT_VFS_STDIO_COMPAT
+#include <libaudcore/audstrings.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+#include "vorbis.h"
+
+EXPORT VorbisPlugin aud_plugin_instance;
+
+static size_t ovcb_read (void * buffer, size_t size, size_t count, void * file)
+{
+ return ((VFSFile *) file)->fread (buffer, size, count);
+}
+
+static int ovcb_seek (void * file, ogg_int64_t offset, int whence)
+{
+ return ((VFSFile *) file)->fseek (offset, to_vfs_seek_type (whence));
+}
+
+static int ovcb_close (void * file)
+{
+ return 0;
+}
+
+static long ovcb_tell (void * file)
+{
+ return ((VFSFile *) file)->ftell ();
+}
+
+ov_callbacks vorbis_callbacks = {
+ ovcb_read,
+ ovcb_seek,
+ ovcb_close,
+ ovcb_tell
+};
+
+ov_callbacks vorbis_callbacks_stream = {
+ ovcb_read,
+ nullptr,
+ ovcb_close,
+ nullptr
+};
+
+bool VorbisPlugin::is_our_file (const char * filename, VFSFile & file)
+{
+ ogg_sync_state oy = {0};
+ ogg_stream_state os = {0};
+ ogg_page og = {0};
+ ogg_packet op = {0};
+
+ bool result = false;
+
+ ogg_sync_init (& oy);
+
+ while (1)
+ {
+ int64_t bytes = ogg_sync_pageseek (& oy, & og);
+
+ if (bytes < 0) /* skipped some bytes */
+ continue;
+ if (bytes > 0) /* got a page */
+ break;
+
+ void * buffer = ogg_sync_buffer (& oy, 2048);
+ bytes = file.fread (buffer, 1, 2048);
+
+ if (bytes <= 0)
+ goto end;
+
+ ogg_sync_wrote (& oy, bytes);
+ }
+
+ if (! ogg_page_bos (& og))
+ goto end;
+
+ ogg_stream_init (& os, ogg_page_serialno (& og));
+ ogg_stream_pagein (& os, & og);
+
+ if (ogg_stream_packetout (& os, & op) > 0 && vorbis_synthesis_idheader (& op))
+ result = true;
+
+end:
+ ogg_sync_clear (& oy);
+ ogg_stream_clear (& os);
+
+ return result;
+}
+
+static void
+set_tuple_str(Tuple &tuple, Tuple::Field field,
+ vorbis_comment *comment, const char *key)
+{
+ tuple.set_str (field, vorbis_comment_query (comment, key, 0));
+}
+
+static Tuple
+get_tuple_for_vorbisfile(OggVorbis_File * vorbisfile, const char *filename, bool stream)
+{
+ Tuple tuple;
+ int length = -1;
+ vorbis_comment *comment = nullptr;
+
+ tuple.set_filename(filename);
+
+ if (! stream)
+ length = ov_time_total (vorbisfile, -1) * 1000;
+
+ /* associate with tuple */
+ tuple.set_int (Tuple::Length, length);
+
+ if ((comment = ov_comment(vorbisfile, -1)) != nullptr) {
+ char *tmps;
+ set_tuple_str(tuple, Tuple::Title, comment, "title");
+ set_tuple_str(tuple, Tuple::Artist, comment, "artist");
+ set_tuple_str(tuple, Tuple::Album, comment, "album");
+ set_tuple_str(tuple, Tuple::Genre, comment, "genre");
+ set_tuple_str(tuple, Tuple::Comment, comment, "comment");
+
+ if ((tmps = vorbis_comment_query(comment, "tracknumber", 0)) != nullptr)
+ tuple.set_int (Tuple::Track, atoi(tmps));
+
+ if ((tmps = vorbis_comment_query (comment, "date", 0)) != nullptr)
+ tuple.set_int (Tuple::Year, atoi (tmps));
+ }
+
+ vorbis_info * info = ov_info (vorbisfile, -1);
+ tuple.set_format ("Ogg Vorbis", info->channels, info->rate, info->bitrate_nominal / 1000);
+
+ tuple.set_str (Tuple::MIMEType, "application/ogg");
+
+ return tuple;
+}
+
+static float atof_no_locale (const char * string)
+{
+ float result = 0;
+ bool negative = false;
+
+ if (* string == '+')
+ string ++;
+ else if (* string == '-')
+ {
+ negative = true;
+ string ++;
+ }
+
+ while (* string >= '0' && * string <= '9')
+ result = 10 * result + (* string ++ - '0');
+
+ if (* string == '.')
+ {
+ float place = 0.1;
+
+ string ++;
+
+ while (* string >= '0' && * string <= '9')
+ {
+ result += (* string ++ - '0') * place;
+ place *= 0.1;
+ }
+ }
+
+ return negative ? -result : result;
+}
+
+/* try to detect when metadata has changed */
+static bool vorbis_fetch_tuple (OggVorbis_File * vf, const char * filename, bool stream, Tuple & tuple)
+{
+ String old_title = tuple.get_str (Tuple::Title);
+ vorbis_comment * comment = ov_comment (vf, -1);
+ const char * new_title = comment ? vorbis_comment_query (comment, "title", 0) : nullptr;
+
+ if (! new_title || (old_title && ! strcmp (old_title, new_title)))
+ return false;
+
+ tuple = get_tuple_for_vorbisfile (vf, filename, stream);
+ return true;
+}
+
+static bool vorbis_fetch_replaygain (OggVorbis_File * vf, ReplayGainInfo * rg_info)
+{
+ vorbis_comment *comment;
+ char *rg_gain, *rg_peak;
+
+ if (vf == nullptr || rg_info == nullptr || (comment = ov_comment(vf, -1)) == nullptr)
+ {
+ AUDDBG ("No replay gain info.\n");
+ return false;
+ }
+
+ rg_gain = vorbis_comment_query(comment, "replaygain_album_gain", 0);
+ if (!rg_gain) rg_gain = vorbis_comment_query(comment, "rg_audiophile", 0); /* Old */
+ rg_info->album_gain = (rg_gain != nullptr) ? atof_no_locale (rg_gain) : 0.0;
+ AUDDBG ("Album gain: %s (%f)\n", rg_gain, rg_info->album_gain);
+
+ rg_gain = vorbis_comment_query(comment, "replaygain_track_gain", 0);
+ if (!rg_gain) rg_gain = vorbis_comment_query(comment, "rg_radio", 0); /* Old */
+ rg_info->track_gain = (rg_gain != nullptr) ? atof_no_locale (rg_gain) : 0.0;
+ AUDDBG ("Track gain: %s (%f)\n", rg_gain, rg_info->track_gain);
+
+ rg_peak = vorbis_comment_query(comment, "replaygain_album_peak", 0);
+ rg_info->album_peak = rg_peak != nullptr ? atof_no_locale (rg_peak) : 0.0;
+ AUDDBG ("Album peak: %s (%f)\n", rg_peak, rg_info->album_peak);
+
+ rg_peak = vorbis_comment_query(comment, "replaygain_track_peak", 0);
+ if (!rg_peak) rg_peak = vorbis_comment_query(comment, "rg_peak", 0); /* Old */
+ rg_info->track_peak = rg_peak != nullptr ? atof_no_locale (rg_peak) : 0.0;
+ AUDDBG ("Track peak: %s (%f)\n", rg_peak, rg_info->track_peak);
+
+ return true;
+}
+
+static long
+vorbis_interleave_buffer(float **pcm, int samples, int ch, float *pcmout)
+{
+ int i, j;
+ for (i = 0; i < samples; i++)
+ for (j = 0; j < ch; j++)
+ *pcmout++ = pcm[j][i];
+
+ return ch * samples * sizeof(float);
+}
+
+
+#define PCM_FRAMES 1024
+#define PCM_BUFSIZE (PCM_FRAMES * 2)
+
+bool VorbisPlugin::play (const char * filename, VFSFile & file)
+{
+ vorbis_info *vi;
+ OggVorbis_File vf;
+ int last_section = -1;
+ Tuple tuple;
+ ReplayGainInfo rg_info;
+ float pcmout[PCM_BUFSIZE*sizeof(float)], **pcm;
+ int bytes, channels, samplerate, br;
+
+ memset(&vf, 0, sizeof(vf));
+
+ bool stream = (file.fsize () < 0);
+ bool error = false;
+
+ if (ov_open_callbacks (& file, & vf, nullptr, 0, stream ?
+ vorbis_callbacks_stream : vorbis_callbacks) < 0)
+ {
+ error = true;
+ goto play_cleanup;
+ }
+
+ vi = ov_info(&vf, -1);
+
+ br = vi->bitrate_nominal;
+ channels = vi->channels;
+ samplerate = vi->rate;
+
+ set_stream_bitrate (br);
+
+ if (vorbis_fetch_tuple (& vf, filename, stream, tuple))
+ set_playback_tuple (tuple.ref ());
+
+ if (vorbis_fetch_replaygain (& vf, & rg_info))
+ set_replay_gain (rg_info);
+
+ open_audio (FMT_FLOAT, samplerate, channels);
+
+ /*
+ * Note that chaining changes things here; A vorbis file may
+ * be a mix of different channels, bitrates and sample rates.
+ * You can fetch the information for any section of the file
+ * using the ov_ interface.
+ */
+
+ while (! check_stop ())
+ {
+ int seek_value = check_seek ();
+
+ if (seek_value >= 0 && ov_time_seek (& vf, (double) seek_value / 1000) < 0)
+ {
+ AUDERR ("seek failed\n");
+ error = true;
+ break;
+ }
+
+ int current_section = last_section;
+ bytes = ov_read_float(&vf, &pcm, PCM_FRAMES, ¤t_section);
+ if (bytes == OV_HOLE)
+ continue;
+
+ if (bytes <= 0)
+ break;
+
+ bytes = vorbis_interleave_buffer (pcm, bytes, channels, pcmout);
+
+ if (vorbis_fetch_tuple (& vf, filename, stream, tuple))
+ set_playback_tuple (tuple.ref ());
+
+ if (current_section != last_section)
+ {
+ /*
+ * The info struct is different in each section. vf
+ * holds them all for the given bitstream. This
+ * requests the current one
+ */
+ vi = ov_info(&vf, -1);
+
+ if (vi->rate != samplerate || vi->channels != channels)
+ {
+ samplerate = vi->rate;
+ channels = vi->channels;
+
+ if (vorbis_fetch_replaygain (& vf, & rg_info))
+ set_replay_gain (rg_info);
+
+ open_audio (FMT_FLOAT, vi->rate, vi->channels);
+ }
+ }
+
+ write_audio (pcmout, bytes);
+
+ if (current_section != last_section)
+ {
+ set_stream_bitrate (br);
+ last_section = current_section;
+ }
+ } /* main loop */
+
+play_cleanup:
+
+ ov_clear(&vf);
+ return ! error;
+}
+
+Tuple VorbisPlugin::read_tuple (const char * filename, VFSFile & file)
+{
+ OggVorbis_File vfile; /* avoid thread interaction */
+
+ bool stream = (file.fsize () < 0);
+
+ /*
+ * The open function performs full stream detection and
+ * machine initialization. If it returns zero, the stream
+ * *is* Vorbis and we're fully ready to decode.
+ */
+ if (ov_open_callbacks (& file, & vfile, nullptr, 0, stream ?
+ vorbis_callbacks_stream : vorbis_callbacks) < 0)
+ return Tuple ();
+
+ Tuple tuple = get_tuple_for_vorbisfile(&vfile, filename, stream);
+ ov_clear(&vfile);
+ return tuple;
+}
+
+Index<char> VorbisPlugin::read_image (const char * filename, VFSFile & file)
+{
+ Index<char> data;
+
+ OggVorbis_File vfile;
+
+ bool stream = (file.fsize () < 0);
+
+ if (ov_open_callbacks (& file, & vfile, nullptr, 0, stream ?
+ vorbis_callbacks_stream : vorbis_callbacks) < 0)
+ return data;
+
+ vorbis_comment * comment = ov_comment (& vfile, -1);
+ if (! comment)
+ goto ERR;
+
+ const char * s;
+
+ if ((s = vorbis_comment_query (comment, "METADATA_BLOCK_PICTURE", 0)))
+ {
+ unsigned mime_length, desc_length, length;
+
+ size_t length2;
+ unsigned char * data2 = g_base64_decode (s, & length2);
+ if (! data2 || length2 < 8)
+ goto PARSE_ERR;
+
+ mime_length = FROM_BE32 (* (uint32_t *) (data2 + 4));
+ if (length2 < 8 + mime_length + 4)
+ goto PARSE_ERR;
+
+ desc_length = FROM_BE32 (* (uint32_t *) (data2 + 8 + mime_length));
+ if (length2 < 8 + mime_length + 4 + desc_length + 20)
+ goto PARSE_ERR;
+
+ length = FROM_BE32 (* (uint32_t *) (data2 + 8 + mime_length + 4 + desc_length + 16));
+ if (length2 < 8 + mime_length + 4 + desc_length + 20 + length)
+ goto PARSE_ERR;
+
+ data.insert ((char *) data2 + 8 + mime_length + 4 + desc_length + 20, 0, length);
+
+ g_free (data2);
+ ov_clear (& vfile);
+ return data;
+
+ PARSE_ERR:
+ AUDERR ("Error parsing METADATA_BLOCK_PICTURE in %s.\n", filename);
+ g_free (data2);
+ }
+
+ if ((s = vorbis_comment_query (comment, "COVERART", 0)))
+ {
+ size_t length2;
+ void * data2 = g_base64_decode (s, & length2);
+
+ if (! data2 || ! length2)
+ {
+ AUDERR ("Error parsing COVERART in %s.\n", filename);
+ g_free (data2);
+ goto ERR;
+ }
+
+ data.insert ((const char *) data2, 0, length2);
+
+ g_free (data2);
+ ov_clear (& vfile);
+ return data;
+ }
+
+ERR:
+ ov_clear (& vfile);
+ return data;
+}
+
+const char VorbisPlugin::about[] =
+ N_("Audacious Ogg Vorbis Decoder\n\n"
+ "Based on the Xiph.org Foundation's Ogg Vorbis Plugin:\n"
+ "http://www.xiph.org/\n\n"
+ "Original code by:\n"
+ "Tony Arcieri <bascule at inferno.tusculum.edu>\n\n"
+ "Contributions from:\n"
+ "Chris Montgomery <monty at xiph.org>\n"
+ "Peter Alm <peter at xmms.org>\n"
+ "Michael Smith <msmith at labyrinth.edu.au>\n"
+ "Jack Moffitt <jack at icecast.org>\n"
+ "Jorn Baayen <jorn at nl.linux.org>\n"
+ "Håvard Kvålen <havardk at xmms.org>\n"
+ "Gian-Carlo Pascutto <gcp at sjeng.org>\n"
+ "Eugene Zagidullin <e.asphyx at gmail.com>");
+
+const char * const VorbisPlugin::exts[] = {"ogg", "ogm", "oga", nullptr};
+const char * const VorbisPlugin::mimes[] = {"application/ogg", nullptr};
diff --git a/src/vorbis/vorbis.h b/src/vorbis/vorbis.h
index 268c5112ef5b..28ab572decf5 100644
--- a/src/vorbis/vorbis.h
+++ b/src/vorbis/vorbis.h
@@ -3,10 +3,35 @@
#include <vorbis/vorbisfile.h>
-#include <audacious/plugin.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
extern ov_callbacks vorbis_callbacks;
-gboolean vorbis_update_song_tuple (const char * filename, VFSFile * fd, const Tuple * tuple);
+class VorbisPlugin : public InputPlugin
+{
+public:
+ static const char about[];
+ static const char * const exts[], * const mimes[];
+
+ static constexpr PluginInfo info = {
+ N_("Ogg Vorbis Decoder"),
+ PACKAGE,
+ about
+ };
+
+ static constexpr auto iinfo = InputInfo (FlagWritesTag)
+ .with_priority (2) /* medium-high priority (a little slow) */
+ .with_exts (exts)
+ .with_mimes (mimes);
+
+ constexpr VorbisPlugin () : InputPlugin (info, iinfo) {}
+
+ bool is_our_file (const char * filename, VFSFile & file);
+ Tuple read_tuple (const char * filename, VFSFile & file);
+ Index<char> read_image (const char * filename, VFSFile & file);
+ bool write_tuple (const char * filename, VFSFile & file, const Tuple & tuple);
+ bool play (const char * filename, VFSFile & file);
+};
#endif /* __VORBIS_H__ */
diff --git a/src/vtx/Makefile b/src/vtx/Makefile
index 0b8c1c4e3090..7fbab2f6aa5b 100644
--- a/src/vtx/Makefile
+++ b/src/vtx/Makefile
@@ -1,16 +1,18 @@
PLUGIN = vtx${PLUGIN_SUFFIX}
-SRCS = ay8912.c \
- info.c \
- lh5dec.c \
- vtx.c \
- vtxfile.c
+SRCS = ay8912.cc \
+ info.cc \
+ lh5dec.cc \
+ vtx.cc \
+ vtxfile.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} -I../.. -I.
-LIBS += ${GTK_LIBS} ${GLIB_LIBS}
+LIBS += ${GTK_LIBS} ${GLIB_LIBS} -laudgui
diff --git a/src/vtx/ay8912.c b/src/vtx/ay8912.c
deleted file mode 100644
index 7587418e63b9..000000000000
--- a/src/vtx/ay8912.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/* AY/YM emulator implementation. */
-
-#include <stdio.h>
-#include <inttypes.h>
-#include "ayemu.h"
-
-#define debuglog stderr;
-
-char *ayemu_err;
-
-/*static const char VERSION[] = "libayemu 0.9";*/
-
-const int MAGIC1 = 0xcdef; /* for check ayemu_t structure inited */
-
-enum {
-/* Max amplitude value for stereo signal for avoiding for possible
- folowwing SSRC for clipping */
- AYEMU_MAX_AMP = 24575,
- AYEMU_DEFAULT_CHIP_FREQ = 1773400
-};
-
-/* sound chip volume envelops (will calculated by gen_env()) */
-static int bEnvGenInit = 0;
-static int Envelope [16][128];
-
-
-/* AY volume table (c) by V_Soft and Lion 17 */
-static int Lion17_AY_table [16] =
- { 0, 513, 828, 1239, 1923, 3238, 4926, 9110,
- 10344, 17876, 24682, 30442, 38844, 47270, 56402, 65535};
-
-/* YM volume table (c) by V_Soft and Lion 17 */
-static int Lion17_YM_table [32] =
- { 0, 0, 190, 286, 375, 470, 560, 664,
- 866, 1130, 1515, 1803, 2253, 2848, 3351, 3862,
- 4844, 6058, 7290, 8559, 10474, 12878, 15297, 17787,
- 21500, 26172, 30866, 35676, 42664, 50986, 58842, 65535};
-
-/* AY volume table (c) by Hacker KAY */
-static int KAY_AY_table [16] =
- { 0, 836, 1212, 1773, 2619, 3875, 5397, 8823,
- 10392, 16706, 23339, 29292, 36969, 46421, 55195, 65535};
-
-/* YM volume table (c) by Hacker KAY */
-static int KAY_YM_table [32] =
- { 0, 0, 248, 450, 670, 826, 1010, 1239,
- 1552, 1919, 2314, 2626, 3131, 3778, 4407, 5031,
- 5968, 7161, 8415, 9622, 11421, 13689, 15957, 18280,
- 21759, 26148, 30523, 34879, 41434, 49404, 57492, 65535};
-
-/* default equlaizer (layout) settings for AY and YM, 7 stereo types */
-static const int default_layout [2][7][6] = {
- {
- /* A_l, A_r, B_l, B_r, C_l, C_r */
-
- /* for AY */
- {100, 100, 100, 100, 100, 100}, // _MONO
- {100, 33, 70, 70, 33, 100}, // _ABC
- {100, 33, 33, 100, 70, 70}, // _ACB
- {70, 70, 100, 33, 33, 100}, // _BAC
- {33, 100, 100, 33, 70, 70}, // _BCA
- {70, 70, 33, 100, 100, 33}, // _CAB
- {33, 100, 70, 70, 100, 33}}, // _CBA
- {
- /* for YM */
- {100, 100, 100, 100, 100, 100}, // _MONO
- {100, 5, 70, 70, 5, 100}, // _ABC
- {100, 5, 5, 100, 70, 70}, // _ACB
- {70, 70, 100, 5, 5, 100}, // _BAC
- {5, 100, 100, 5, 70, 70}, // _BCA
- {70, 70, 5, 100, 100, 5}, // _CAB
- {5, 100, 70, 70, 100, 5}} // _CBA
-};
-
-
-static int check_magic(ayemu_ay_t *ay)
-{
- if (ay->magic == MAGIC1)
- return 1;
- fprintf(stderr, "libayemu: passed pointer %p to uninitialized ayemu_ay_t structure\n", (void *) ay);
- return 0;
-}
-
-
-/* make chip hardware envelop tables.
- Will execute once before first use. */
-static void gen_env()
-{
- int env;
- int pos;
- int hold;
- int dir;
- int vol;
-
- for (env = 0; env < 16; env++) {
- hold = 0;
- dir = (env & 4)? 1 : -1;
- vol = (env & 4)? -1 : 32;
- for (pos = 0; pos < 128; pos++) {
- if (!hold) {
- vol += dir;
- if (vol < 0 || vol >= 32) {
- if ( env & 8 ) {
- if ( env & 2 ) dir = -dir;
- vol = (dir > 0 )? 0:31;
- if ( env & 1 ) {
- hold = 1;
- vol = ( dir > 0 )? 31:0;
- }
- } else {
- vol = 0;
- hold = 1;
- }
- }
- }
- Envelope[env][pos] = vol;
- }
- }
- bEnvGenInit = 1;
-}
-
-
-/**
- * \retval ayemu_init none.
- *
-*/
-void ayemu_init(ayemu_ay_t *ay)
-{
- ay->default_chip_flag = 1;
- ay->ChipFreq = AYEMU_DEFAULT_CHIP_FREQ;
- ay->default_stereo_flag = 1;
- ay->default_sound_format_flag = 1;
- ay->dirty = 1;
- ay->magic = MAGIC1;
-
- ayemu_reset(ay);
-}
-
-/** Reset AY/YM chip.
- *
- * \arg \c ay - pointer to ayemu_ay_t structure.
- * \return none.
- */
-void ayemu_reset(ayemu_ay_t *ay)
-{
- if (!check_magic(ay)) return;
-
- ay->cnt_a = ay->cnt_b = ay->cnt_c = ay->cnt_n = ay->cnt_e = 0;
- ay->bit_a = ay->bit_b = ay->bit_c = ay->bit_n = 0;
- ay->env_pos = ay->EnvNum = 0;
- ay->Cur_Seed = 0xffff;
-}
-
-
-static void set_table_ay (ayemu_ay_t *ay, int tbl[16])
-{
- int n;
- for (n = 0; n < 32; n++)
- ay->table[n] = tbl[n/2];
- ay->type = AYEMU_AY;
-}
-
-static void set_table_ym (ayemu_ay_t *ay, int tbl[32])
-{
- int n;
- for (n = 0; n < 32; n++)
- ay->table[n] = tbl[n];
- ay->type = AYEMU_YM;
-}
-
-
-/** Set chip type. */
-int ayemu_set_chip_type(ayemu_ay_t *ay, ayemu_chip_t type, int *custom_table)
-{
-if (!check_magic(ay))
- return 0;
-
- if (!(type == AYEMU_AY_CUSTOM || type == AYEMU_YM_CUSTOM) && custom_table != NULL) {
- ayemu_err = "For non-custom chip type 'custom_table' param must be NULL";
- return 0;
- }
-
- switch(type) {
- case AYEMU_AY:
- case AYEMU_AY_LION17:
- set_table_ay(ay, Lion17_AY_table);
- break;
- case AYEMU_YM:
- case AYEMU_YM_LION17:
- set_table_ym(ay, Lion17_YM_table);
- break;
- case AYEMU_AY_KAY:
- set_table_ay(ay, KAY_AY_table);
- break;
- case AYEMU_YM_KAY:
- set_table_ym(ay, KAY_YM_table);
- break;
- case AYEMU_AY_CUSTOM:
- set_table_ay(ay, custom_table);
- break;
- case AYEMU_YM_CUSTOM:
- set_table_ym(ay, custom_table);
- break;
- default:
- ayemu_err = "Incorrect chip type";
- return 0;
- }
-
- ay->default_chip_flag = 0;
- ay->dirty = 1;
- return 1;
-}
-
-
-/** Set chip frequency. */
-void ayemu_set_chip_freq(ayemu_ay_t *ay, int32_t chipfreq)
-{
- if (!check_magic(ay)) return;
-
- ay->ChipFreq = chipfreq;
- ay->dirty = 1;
-}
-
-/*! Set output sound format
- * \arg \c ay - pointer to ayemu_t structure
- * \arg \c freq - sound freq (44100 for example)
- * \arg \c chans - number of channels (1-mono, 2-stereo)
- * \arg \c bits - now supported only 16 and 8.
- * \retval \b 1 on success, \b 0 if error occure
- */
-int ayemu_set_sound_format (ayemu_ay_t *ay, int freq, int chans, int bits)
-{
- if (!check_magic(ay))
- return 0;
-
- if (!(bits == 16 || bits == 8)) {
- ayemu_err = "Incorrect bits value";
- return 0;
- }
- else if (!(chans == 1 || chans == 2)) {
- ayemu_err = "Incorrect number of channels";
- return 0;
- }
- else if (freq < 50) {
- ayemu_err = "Incorrect output sound freq";
- return 0;
- }
- else {
- ay->sndfmt.freq = freq;
- ay->sndfmt.channels = chans;
- ay->sndfmt.bpc = bits;
- }
-
- ay->default_sound_format_flag = 0;
- ay->dirty = 1;
- return 1;
-}
-
-
-/*! Set amplitude factor for each of channels (A,B anc C, tone and noise).
- * Factor's value must be from (-100) to 100.
- * \arg ay - pointer to ayemu_t structure
- * \arg stereo_type - type of stereo
- * \arg custom_eq - NULL or pointer to custom table of mixer layout.
- * \retval 1 if OK, 0 if error occures.
- */
-int ayemu_set_stereo(ayemu_ay_t *ay, ayemu_stereo_t stereo_type, int *custom_eq)
-{
- int i;
- int chip;
-
- if (!check_magic(ay))
- return 0;
-
- if (stereo_type != AYEMU_STEREO_CUSTOM && custom_eq != NULL) {
- ayemu_err = "Stereo type not custom, 'custom_eq' parametr must be NULL";
- return 0;
- }
-
- chip = (ay->type == AYEMU_AY)? 0 : 1;
-
- switch(stereo_type) {
- case AYEMU_MONO:
- case AYEMU_ABC:
- case AYEMU_ACB:
- case AYEMU_BAC:
- case AYEMU_BCA:
- case AYEMU_CAB:
- case AYEMU_CBA:
- for (i = 0 ; i < 6 ; i++)
- ay->eq[i] = default_layout[chip][stereo_type][i];
- break;
- case AYEMU_STEREO_CUSTOM:
- for (i = 0 ; i < 6 ; i++)
- ay->eq[i] = custom_eq[i];
- break;
- default:
- ayemu_err = "Incorrect stereo type";
- return 0;
- }
-
- ay->default_stereo_flag = 0;
- ay->dirty = 1;
- return 1;
-}
-
-
-#define WARN_IF_REGISTER_GREAT_THAN(r,m) \
-if (*(regs + r) > m) \
- fprintf(stderr, "ayemu_set_regs: warning: possible bad register data- R%d > %d\n", r, m)
-
-
-/** Assign values for AY registers.
- *
- * You must pass array of char [14] to this function
- */
-void ayemu_set_regs(ayemu_ay_t *ay, unsigned char *regs)
-{
- if (!check_magic(ay)) return;
-
- WARN_IF_REGISTER_GREAT_THAN(1,15);
- WARN_IF_REGISTER_GREAT_THAN(3,15);
- WARN_IF_REGISTER_GREAT_THAN(5,15);
- WARN_IF_REGISTER_GREAT_THAN(8,31);
- WARN_IF_REGISTER_GREAT_THAN(9,31);
- WARN_IF_REGISTER_GREAT_THAN(10,31);
-
- ay->regs.tone_a = regs[0] + ((regs[1]&0x0f) << 8);
- ay->regs.tone_b = regs[2] + ((regs[3]&0x0f) << 8);
- ay->regs.tone_c = regs[4] + ((regs[5]&0x0f) << 8);
-
- ay->regs.noise = regs[6] & 0x1f;
-
- ay->regs.R7_tone_a = ! (regs[7] & 0x01);
- ay->regs.R7_tone_b = ! (regs[7] & 0x02);
- ay->regs.R7_tone_c = ! (regs[7] & 0x04);
-
- ay->regs.R7_noise_a = ! (regs[7] & 0x08);
- ay->regs.R7_noise_b = ! (regs[7] & 0x10);
- ay->regs.R7_noise_c = ! (regs[7] & 0x20);
-
- ay->regs.vol_a = regs[8] & 0x0f;
- ay->regs.vol_b = regs[9] & 0x0f;
- ay->regs.vol_c = regs[10] & 0x0f;
- ay->regs.env_a = regs[8] & 0x10;
- ay->regs.env_b = regs[9] & 0x10;
- ay->regs.env_c = regs[10] & 0x10;
- ay->regs.env_freq = regs[11] + (regs[12] << 8);
-
- if (regs[13] != 0xff) { /* R13 = 255 means continue curent envelop */
- ay->regs.env_style = regs[13] & 0x0f;
- ay->env_pos = ay->cnt_e = 0;
- }
-}
-
-
-static void prepare_generation(ayemu_ay_t *ay)
-{
- int vol, max_l, max_r;
-
- if (!ay->dirty) return;
-
- if (!bEnvGenInit) gen_env ();
-
- if (ay->default_chip_flag) ayemu_set_chip_type(ay, AYEMU_AY, NULL);
-
- if (ay->default_stereo_flag) ayemu_set_stereo(ay, AYEMU_ABC, NULL);
-
- if (ay->default_sound_format_flag) ayemu_set_sound_format(ay, 44100, 2, 16);
-
- ay->ChipTacts_per_outcount = ay->ChipFreq / ay->sndfmt.freq / 8;
-
- { /* GenVols */
- int n, m;
- int vol;
- for (n = 0; n < 32; n++) {
- vol = ay->table[n];
- for (m=0; m < 6; m++)
- ay->vols[m][n] = (int) (((double) vol * ay->eq[m]) / 100);
- }
- }
-
- /* ������ ����������������� ����
- �������� ���vols [x][31] ��������������� TODO: �������� � ��;-)
- */
- max_l = ay->vols[0][31] + ay->vols[2][31] + ay->vols[3][31];
- max_r = ay->vols[1][31] + ay->vols[3][31] + ay->vols[5][31];
- vol = (max_l > max_r) ? max_l : max_r; // =157283 on all defaults
- ay->Amp_Global = ay->ChipTacts_per_outcount *vol / AYEMU_MAX_AMP;
-
- ay->dirty = 0;
-}
-
-
-/*! Generate sound.
- * Fill sound buffer with current register data
- * Return value: pointer to next data in output sound buffer
- * \retval \b 1 if OK, \b 0 if error occures.
- */
-void *ayemu_gen_sound(ayemu_ay_t *ay, void *buff, size_t sound_bufsize)
-{
- int mix_l, mix_r;
- int tmpvol;
- int m;
- int snd_numcount;
- unsigned char *sound_buf = buff;
-
- if (!check_magic(ay))
- return 0;
-
- prepare_generation(ay);
-
- snd_numcount = sound_bufsize / (ay->sndfmt.channels * (ay->sndfmt.bpc >> 3));
- while (snd_numcount-- > 0) {
- mix_l = mix_r = 0;
-
- for (m = 0 ; m < ay->ChipTacts_per_outcount ; m++) {
- if (++ay->cnt_a >= ay->regs.tone_a) {
- ay->cnt_a = 0;
- ay->bit_a = ! ay->bit_a;
- }
- if (++ay->cnt_b >= ay->regs.tone_b) {
- ay->cnt_b = 0;
- ay->bit_b = ! ay->bit_b;
- }
- if (++ay->cnt_c >= ay->regs.tone_c) {
- ay->cnt_c = 0;
- ay->bit_c = ! ay->bit_c;
- }
-
- /* GenNoise (c) Hacker KAY & Sergey Bulba */
- if (++ay->cnt_n >= (ay->regs.noise * 2)) {
- ay->cnt_n = 0;
- ay->Cur_Seed = (ay->Cur_Seed * 2 + 1) ^ \
- (((ay->Cur_Seed >> 16) ^ (ay->Cur_Seed >> 13)) & 1);
- ay->bit_n = ((ay->Cur_Seed >> 16) & 1);
- }
-
- if (++ay->cnt_e >= ay->regs.env_freq) {
- ay->cnt_e = 0;
- if (++ay->env_pos > 127)
- ay->env_pos = 64;
- }
-
-#define ENVVOL Envelope [ay->regs.env_style][ay->env_pos]
-
- if ((ay->bit_a | !ay->regs.R7_tone_a) & (ay->bit_n | !ay->regs.R7_noise_a)) {
- tmpvol = (ay->regs.env_a)? ENVVOL : ay->regs.vol_a * 2 + 1;
- mix_l += ay->vols[0][tmpvol];
- mix_r += ay->vols[1][tmpvol];
- }
-
- if ((ay->bit_b | !ay->regs.R7_tone_b) & (ay->bit_n | !ay->regs.R7_noise_b)) {
- tmpvol =(ay->regs.env_b)? ENVVOL : ay->regs.vol_b * 2 + 1;
- mix_l += ay->vols[2][tmpvol];
- mix_r += ay->vols[3][tmpvol];
- }
-
- if ((ay->bit_c | !ay->regs.R7_tone_c) & (ay->bit_n | !ay->regs.R7_noise_c)) {
- tmpvol = (ay->regs.env_c)? ENVVOL : ay->regs.vol_c * 2 + 1;
- mix_l += ay->vols[4][tmpvol];
- mix_r += ay->vols[5][tmpvol];
- }
- } /* end for (m=0; ...) */
-
- mix_l /= ay->Amp_Global;
- mix_r /= ay->Amp_Global;
-
- if (ay->sndfmt.bpc == 8) {
- mix_l = (mix_l >> 8) | 128; /* 8 bit sound */
- mix_r = (mix_r >> 8) | 128;
- *sound_buf++ = mix_l;
- if (ay->sndfmt.channels != 1)
- *sound_buf++ = mix_r;
- } else {
- *sound_buf++ = mix_l & 0x00FF; /* 16 bit sound */
- *sound_buf++ = (mix_l >> 8);
- if (ay->sndfmt.channels != 1) {
- *sound_buf++ = mix_r & 0x00FF;
- *sound_buf++ = (mix_r >> 8);
- }
- }
- }
- return sound_buf;
-}
-
-/** Free all data allocated by emulator
- *
- * For now it do nothing.
- */
-void ayemu_free (ayemu_ay_t *ay)
-{
- /* nothing to do here */
- return;
-}
diff --git a/src/vtx/ay8912.cc b/src/vtx/ay8912.cc
new file mode 100644
index 000000000000..8276cf0fd556
--- /dev/null
+++ b/src/vtx/ay8912.cc
@@ -0,0 +1,494 @@
+/* AY/YM emulator implementation. */
+
+#include <inttypes.h>
+#include "ayemu.h"
+
+#include <libaudcore/runtime.h>
+
+const char *ayemu_err;
+
+/*static const char VERSION[] = "libayemu 0.9";*/
+
+const int MAGIC1 = 0xcdef; /* for check ayemu_t structure inited */
+
+enum {
+/* Max amplitude value for stereo signal for avoiding for possible
+ folowwing SSRC for clipping */
+ AYEMU_MAX_AMP = 24575,
+ AYEMU_DEFAULT_CHIP_FREQ = 1773400
+};
+
+/* sound chip volume envelops (will calculated by gen_env()) */
+static int bEnvGenInit = 0;
+static int Envelope [16][128];
+
+
+/* AY volume table (c) by V_Soft and Lion 17 */
+static int Lion17_AY_table [16] =
+ { 0, 513, 828, 1239, 1923, 3238, 4926, 9110,
+ 10344, 17876, 24682, 30442, 38844, 47270, 56402, 65535};
+
+/* YM volume table (c) by V_Soft and Lion 17 */
+static int Lion17_YM_table [32] =
+ { 0, 0, 190, 286, 375, 470, 560, 664,
+ 866, 1130, 1515, 1803, 2253, 2848, 3351, 3862,
+ 4844, 6058, 7290, 8559, 10474, 12878, 15297, 17787,
+ 21500, 26172, 30866, 35676, 42664, 50986, 58842, 65535};
+
+/* AY volume table (c) by Hacker KAY */
+static int KAY_AY_table [16] =
+ { 0, 836, 1212, 1773, 2619, 3875, 5397, 8823,
+ 10392, 16706, 23339, 29292, 36969, 46421, 55195, 65535};
+
+/* YM volume table (c) by Hacker KAY */
+static int KAY_YM_table [32] =
+ { 0, 0, 248, 450, 670, 826, 1010, 1239,
+ 1552, 1919, 2314, 2626, 3131, 3778, 4407, 5031,
+ 5968, 7161, 8415, 9622, 11421, 13689, 15957, 18280,
+ 21759, 26148, 30523, 34879, 41434, 49404, 57492, 65535};
+
+/* default equlaizer (layout) settings for AY and YM, 7 stereo types */
+static const int default_layout [2][7][6] = {
+ {
+ /* A_l, A_r, B_l, B_r, C_l, C_r */
+
+ /* for AY */
+ {100, 100, 100, 100, 100, 100}, // _MONO
+ {100, 33, 70, 70, 33, 100}, // _ABC
+ {100, 33, 33, 100, 70, 70}, // _ACB
+ {70, 70, 100, 33, 33, 100}, // _BAC
+ {33, 100, 100, 33, 70, 70}, // _BCA
+ {70, 70, 33, 100, 100, 33}, // _CAB
+ {33, 100, 70, 70, 100, 33}}, // _CBA
+ {
+ /* for YM */
+ {100, 100, 100, 100, 100, 100}, // _MONO
+ {100, 5, 70, 70, 5, 100}, // _ABC
+ {100, 5, 5, 100, 70, 70}, // _ACB
+ {70, 70, 100, 5, 5, 100}, // _BAC
+ {5, 100, 100, 5, 70, 70}, // _BCA
+ {70, 70, 5, 100, 100, 5}, // _CAB
+ {5, 100, 70, 70, 100, 5}} // _CBA
+};
+
+
+static int check_magic(ayemu_ay_t *ay)
+{
+ if (ay->magic == MAGIC1)
+ return 1;
+ AUDERR("passed pointer %p to uninitialized ayemu_ay_t structure\n", (void *) ay);
+ return 0;
+}
+
+
+/* make chip hardware envelop tables.
+ Will execute once before first use. */
+static void gen_env()
+{
+ int env;
+ int pos;
+ int hold;
+ int dir;
+ int vol;
+
+ for (env = 0; env < 16; env++) {
+ hold = 0;
+ dir = (env & 4)? 1 : -1;
+ vol = (env & 4)? -1 : 32;
+ for (pos = 0; pos < 128; pos++) {
+ if (!hold) {
+ vol += dir;
+ if (vol < 0 || vol >= 32) {
+ if ( env & 8 ) {
+ if ( env & 2 ) dir = -dir;
+ vol = (dir > 0 )? 0:31;
+ if ( env & 1 ) {
+ hold = 1;
+ vol = ( dir > 0 )? 31:0;
+ }
+ } else {
+ vol = 0;
+ hold = 1;
+ }
+ }
+ }
+ Envelope[env][pos] = vol;
+ }
+ }
+ bEnvGenInit = 1;
+}
+
+
+/**
+ * \retval ayemu_init none.
+ *
+*/
+void ayemu_init(ayemu_ay_t *ay)
+{
+ ay->default_chip_flag = 1;
+ ay->ChipFreq = AYEMU_DEFAULT_CHIP_FREQ;
+ ay->default_stereo_flag = 1;
+ ay->default_sound_format_flag = 1;
+ ay->dirty = 1;
+ ay->magic = MAGIC1;
+
+ ayemu_reset(ay);
+}
+
+/** Reset AY/YM chip.
+ *
+ * \arg \c ay - pointer to ayemu_ay_t structure.
+ * \return none.
+ */
+void ayemu_reset(ayemu_ay_t *ay)
+{
+ if (!check_magic(ay)) return;
+
+ ay->cnt_a = ay->cnt_b = ay->cnt_c = ay->cnt_n = ay->cnt_e = 0;
+ ay->bit_a = ay->bit_b = ay->bit_c = ay->bit_n = 0;
+ ay->env_pos = ay->EnvNum = 0;
+ ay->Cur_Seed = 0xffff;
+}
+
+
+static void set_table_ay (ayemu_ay_t *ay, int tbl[16])
+{
+ int n;
+ for (n = 0; n < 32; n++)
+ ay->table[n] = tbl[n/2];
+ ay->type = AYEMU_AY;
+}
+
+static void set_table_ym (ayemu_ay_t *ay, int tbl[32])
+{
+ int n;
+ for (n = 0; n < 32; n++)
+ ay->table[n] = tbl[n];
+ ay->type = AYEMU_YM;
+}
+
+
+/** Set chip type. */
+int ayemu_set_chip_type(ayemu_ay_t *ay, ayemu_chip_t type, int *custom_table)
+{
+if (!check_magic(ay))
+ return 0;
+
+ if (!(type == AYEMU_AY_CUSTOM || type == AYEMU_YM_CUSTOM) && custom_table != nullptr) {
+ ayemu_err = "For non-custom chip type 'custom_table' param must be nullptr";
+ return 0;
+ }
+
+ switch(type) {
+ case AYEMU_AY:
+ case AYEMU_AY_LION17:
+ set_table_ay(ay, Lion17_AY_table);
+ break;
+ case AYEMU_YM:
+ case AYEMU_YM_LION17:
+ set_table_ym(ay, Lion17_YM_table);
+ break;
+ case AYEMU_AY_KAY:
+ set_table_ay(ay, KAY_AY_table);
+ break;
+ case AYEMU_YM_KAY:
+ set_table_ym(ay, KAY_YM_table);
+ break;
+ case AYEMU_AY_CUSTOM:
+ set_table_ay(ay, custom_table);
+ break;
+ case AYEMU_YM_CUSTOM:
+ set_table_ym(ay, custom_table);
+ break;
+ default:
+ ayemu_err = "Incorrect chip type";
+ return 0;
+ }
+
+ ay->default_chip_flag = 0;
+ ay->dirty = 1;
+ return 1;
+}
+
+
+/** Set chip frequency. */
+void ayemu_set_chip_freq(ayemu_ay_t *ay, int32_t chipfreq)
+{
+ if (!check_magic(ay)) return;
+
+ ay->ChipFreq = chipfreq;
+ ay->dirty = 1;
+}
+
+/*! Set output sound format
+ * \arg \c ay - pointer to ayemu_t structure
+ * \arg \c freq - sound freq (44100 for example)
+ * \arg \c chans - number of channels (1-mono, 2-stereo)
+ * \arg \c bits - now supported only 16 and 8.
+ * \retval \b 1 on success, \b 0 if error occure
+ */
+int ayemu_set_sound_format (ayemu_ay_t *ay, int freq, int chans, int bits)
+{
+ if (!check_magic(ay))
+ return 0;
+
+ if (!(bits == 16 || bits == 8)) {
+ ayemu_err = "Incorrect bits value";
+ return 0;
+ }
+ else if (!(chans == 1 || chans == 2)) {
+ ayemu_err = "Incorrect number of channels";
+ return 0;
+ }
+ else if (freq < 50) {
+ ayemu_err = "Incorrect output sound freq";
+ return 0;
+ }
+ else {
+ ay->sndfmt.freq = freq;
+ ay->sndfmt.channels = chans;
+ ay->sndfmt.bpc = bits;
+ }
+
+ ay->default_sound_format_flag = 0;
+ ay->dirty = 1;
+ return 1;
+}
+
+
+/*! Set amplitude factor for each of channels (A,B anc C, tone and noise).
+ * Factor's value must be from (-100) to 100.
+ * \arg ay - pointer to ayemu_t structure
+ * \arg stereo_type - type of stereo
+ * \arg custom_eq - nullptr or pointer to custom table of mixer layout.
+ * \retval 1 if OK, 0 if error occures.
+ */
+int ayemu_set_stereo(ayemu_ay_t *ay, ayemu_stereo_t stereo_type, int *custom_eq)
+{
+ int i;
+ int chip;
+
+ if (!check_magic(ay))
+ return 0;
+
+ if (stereo_type != AYEMU_STEREO_CUSTOM && custom_eq != nullptr) {
+ ayemu_err = "Stereo type not custom, 'custom_eq' parametr must be nullptr";
+ return 0;
+ }
+
+ chip = (ay->type == AYEMU_AY)? 0 : 1;
+
+ switch(stereo_type) {
+ case AYEMU_MONO:
+ case AYEMU_ABC:
+ case AYEMU_ACB:
+ case AYEMU_BAC:
+ case AYEMU_BCA:
+ case AYEMU_CAB:
+ case AYEMU_CBA:
+ for (i = 0 ; i < 6 ; i++)
+ ay->eq[i] = default_layout[chip][stereo_type][i];
+ break;
+ case AYEMU_STEREO_CUSTOM:
+ for (i = 0 ; i < 6 ; i++)
+ ay->eq[i] = custom_eq[i];
+ break;
+ default:
+ ayemu_err = "Incorrect stereo type";
+ return 0;
+ }
+
+ ay->default_stereo_flag = 0;
+ ay->dirty = 1;
+ return 1;
+}
+
+
+#define WARN_IF_REGISTER_GREAT_THAN(r,m) \
+if (*(regs + r) > m) \
+ AUDWARN("possible bad register data- R%d > %d\n", r, m)
+
+
+/** Assign values for AY registers.
+ *
+ * You must pass array of char [14] to this function
+ */
+void ayemu_set_regs(ayemu_ay_t *ay, unsigned char *regs)
+{
+ if (!check_magic(ay)) return;
+
+ WARN_IF_REGISTER_GREAT_THAN(1,15);
+ WARN_IF_REGISTER_GREAT_THAN(3,15);
+ WARN_IF_REGISTER_GREAT_THAN(5,15);
+ WARN_IF_REGISTER_GREAT_THAN(8,31);
+ WARN_IF_REGISTER_GREAT_THAN(9,31);
+ WARN_IF_REGISTER_GREAT_THAN(10,31);
+
+ ay->regs.tone_a = regs[0] + ((regs[1]&0x0f) << 8);
+ ay->regs.tone_b = regs[2] + ((regs[3]&0x0f) << 8);
+ ay->regs.tone_c = regs[4] + ((regs[5]&0x0f) << 8);
+
+ ay->regs.noise = regs[6] & 0x1f;
+
+ ay->regs.R7_tone_a = ! (regs[7] & 0x01);
+ ay->regs.R7_tone_b = ! (regs[7] & 0x02);
+ ay->regs.R7_tone_c = ! (regs[7] & 0x04);
+
+ ay->regs.R7_noise_a = ! (regs[7] & 0x08);
+ ay->regs.R7_noise_b = ! (regs[7] & 0x10);
+ ay->regs.R7_noise_c = ! (regs[7] & 0x20);
+
+ ay->regs.vol_a = regs[8] & 0x0f;
+ ay->regs.vol_b = regs[9] & 0x0f;
+ ay->regs.vol_c = regs[10] & 0x0f;
+ ay->regs.env_a = regs[8] & 0x10;
+ ay->regs.env_b = regs[9] & 0x10;
+ ay->regs.env_c = regs[10] & 0x10;
+ ay->regs.env_freq = regs[11] + (regs[12] << 8);
+
+ if (regs[13] != 0xff) { /* R13 = 255 means continue curent envelop */
+ ay->regs.env_style = regs[13] & 0x0f;
+ ay->env_pos = ay->cnt_e = 0;
+ }
+}
+
+
+static void prepare_generation(ayemu_ay_t *ay)
+{
+ int vol, max_l, max_r;
+
+ if (!ay->dirty) return;
+
+ if (!bEnvGenInit) gen_env ();
+
+ if (ay->default_chip_flag) ayemu_set_chip_type(ay, AYEMU_AY, nullptr);
+
+ if (ay->default_stereo_flag) ayemu_set_stereo(ay, AYEMU_ABC, nullptr);
+
+ if (ay->default_sound_format_flag) ayemu_set_sound_format(ay, 44100, 2, 16);
+
+ ay->ChipTacts_per_outcount = ay->ChipFreq / ay->sndfmt.freq / 8;
+
+ { /* GenVols */
+ int n, m;
+ int vol;
+ for (n = 0; n < 32; n++) {
+ vol = ay->table[n];
+ for (m=0; m < 6; m++)
+ ay->vols[m][n] = (int) (((double) vol * ay->eq[m]) / 100);
+ }
+ }
+
+ /* ������ ����������������� ����
+ �������� ���vols [x][31] ��������������� TODO: �������� � ��;-)
+ */
+ max_l = ay->vols[0][31] + ay->vols[2][31] + ay->vols[3][31];
+ max_r = ay->vols[1][31] + ay->vols[3][31] + ay->vols[5][31];
+ vol = (max_l > max_r) ? max_l : max_r; // =157283 on all defaults
+ ay->Amp_Global = ay->ChipTacts_per_outcount *vol / AYEMU_MAX_AMP;
+
+ ay->dirty = 0;
+}
+
+
+/*! Generate sound.
+ * Fill sound buffer with current register data
+ * Return value: pointer to next data in output sound buffer
+ * \retval \b 1 if OK, \b 0 if error occures.
+ */
+void *ayemu_gen_sound(ayemu_ay_t *ay, void *buff, size_t sound_bufsize)
+{
+ int mix_l, mix_r;
+ int tmpvol;
+ int m;
+ int snd_numcount;
+ unsigned char *sound_buf = (unsigned char *) buff;
+
+ if (!check_magic(ay))
+ return 0;
+
+ prepare_generation(ay);
+
+ snd_numcount = sound_bufsize / (ay->sndfmt.channels * (ay->sndfmt.bpc >> 3));
+ while (snd_numcount-- > 0) {
+ mix_l = mix_r = 0;
+
+ for (m = 0 ; m < ay->ChipTacts_per_outcount ; m++) {
+ if (++ay->cnt_a >= ay->regs.tone_a) {
+ ay->cnt_a = 0;
+ ay->bit_a = ! ay->bit_a;
+ }
+ if (++ay->cnt_b >= ay->regs.tone_b) {
+ ay->cnt_b = 0;
+ ay->bit_b = ! ay->bit_b;
+ }
+ if (++ay->cnt_c >= ay->regs.tone_c) {
+ ay->cnt_c = 0;
+ ay->bit_c = ! ay->bit_c;
+ }
+
+ /* GenNoise (c) Hacker KAY & Sergey Bulba */
+ if (++ay->cnt_n >= (ay->regs.noise * 2)) {
+ ay->cnt_n = 0;
+ ay->Cur_Seed = (ay->Cur_Seed * 2 + 1) ^ \
+ (((ay->Cur_Seed >> 16) ^ (ay->Cur_Seed >> 13)) & 1);
+ ay->bit_n = ((ay->Cur_Seed >> 16) & 1);
+ }
+
+ if (++ay->cnt_e >= ay->regs.env_freq) {
+ ay->cnt_e = 0;
+ if (++ay->env_pos > 127)
+ ay->env_pos = 64;
+ }
+
+#define ENVVOL Envelope [ay->regs.env_style][ay->env_pos]
+
+ if ((ay->bit_a | !ay->regs.R7_tone_a) & (ay->bit_n | !ay->regs.R7_noise_a)) {
+ tmpvol = (ay->regs.env_a)? ENVVOL : ay->regs.vol_a * 2 + 1;
+ mix_l += ay->vols[0][tmpvol];
+ mix_r += ay->vols[1][tmpvol];
+ }
+
+ if ((ay->bit_b | !ay->regs.R7_tone_b) & (ay->bit_n | !ay->regs.R7_noise_b)) {
+ tmpvol =(ay->regs.env_b)? ENVVOL : ay->regs.vol_b * 2 + 1;
+ mix_l += ay->vols[2][tmpvol];
+ mix_r += ay->vols[3][tmpvol];
+ }
+
+ if ((ay->bit_c | !ay->regs.R7_tone_c) & (ay->bit_n | !ay->regs.R7_noise_c)) {
+ tmpvol = (ay->regs.env_c)? ENVVOL : ay->regs.vol_c * 2 + 1;
+ mix_l += ay->vols[4][tmpvol];
+ mix_r += ay->vols[5][tmpvol];
+ }
+ } /* end for (m=0; ...) */
+
+ mix_l /= ay->Amp_Global;
+ mix_r /= ay->Amp_Global;
+
+ if (ay->sndfmt.bpc == 8) {
+ mix_l = (mix_l >> 8) | 128; /* 8 bit sound */
+ mix_r = (mix_r >> 8) | 128;
+ *sound_buf++ = mix_l;
+ if (ay->sndfmt.channels != 1)
+ *sound_buf++ = mix_r;
+ } else {
+ *sound_buf++ = mix_l & 0x00FF; /* 16 bit sound */
+ *sound_buf++ = (mix_l >> 8);
+ if (ay->sndfmt.channels != 1) {
+ *sound_buf++ = mix_r & 0x00FF;
+ *sound_buf++ = (mix_r >> 8);
+ }
+ }
+ }
+ return sound_buf;
+}
+
+/** Free all data allocated by emulator
+ *
+ * For now it do nothing.
+ */
+void ayemu_free (ayemu_ay_t *ay)
+{
+ /* nothing to do here */
+ return;
+}
diff --git a/src/vtx/ayemu.h b/src/vtx/ayemu.h
index 15ab7ac355bb..18195a5b42a9 100644
--- a/src/vtx/ayemu.h
+++ b/src/vtx/ayemu.h
@@ -16,20 +16,12 @@
License along with this library; if not, write to the Free
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- Alexander Sashnov
+ Alexander Sashnov
sashnov at ngs.ru
*/
#ifndef _AYEMU_H
#define _AYEMU_H
-#ifdef __cplusplus
-# define BEGIN_C_DECLS extern "C" {
-# define END_C_DECLS }
-#else /* !__cplusplus */
-# define BEGIN_C_DECLS
-# define END_C_DECLS
-#endif /* __cplusplus */
-
#define EXTERN extern
/* typedefs for 32-bit architecture */
diff --git a/src/vtx/ayemu_8912.h b/src/vtx/ayemu_8912.h
index a43a195f0b6a..2ffc5dc80008 100644
--- a/src/vtx/ayemu_8912.h
+++ b/src/vtx/ayemu_8912.h
@@ -8,8 +8,6 @@
#include <stddef.h>
#include <inttypes.h>
-BEGIN_C_DECLS
-
/** Types of stereo.
The codes of stereo types used for generage sound. */
typedef enum
@@ -43,7 +41,7 @@ typedef enum {
typedef struct
{
int tone_a; /**< R0, R1 */
- int tone_b; /**< R2, R3 */
+ int tone_b; /**< R2, R3 */
int tone_c; /**< R4, R5 */
int noise; /**< R6 */
int R7_tone_a; /**< R7 bit 0 */
@@ -79,7 +77,7 @@ ayemu_sndfmt_t;
/*@{*/
/** Data structure for sound chip emulation \internal
- *
+ *
*/
typedef struct
{
@@ -88,7 +86,7 @@ typedef struct
ayemu_chip_t type; /**< general chip type (\b AYEMU_AY or \b AYEMU_YM) */
int32_t ChipFreq; /**< chip emulator frequency */
int eq[6]; /**< volumes for channels.
- Array contains 6 elements:
+ Array contains 6 elements:
A left, A right, B left, B right, C left and C right;
range -100...100 */
ayemu_regdata_t regs; /**< parsed registers data */
@@ -126,7 +124,7 @@ ayemu_init(ayemu_ay_t *ay);
EXTERN void
ayemu_reset(ayemu_ay_t *ay);
-EXTERN int
+EXTERN int
ayemu_set_chip_type(ayemu_ay_t *ay, ayemu_chip_t chip, int *custom_table);
EXTERN void
@@ -138,7 +136,7 @@ ayemu_set_stereo(ayemu_ay_t *ay, ayemu_stereo_t stereo, int *custom_eq);
EXTERN int
ayemu_set_sound_format (ayemu_ay_t *ay, int freq, int chans, int bits);
-EXTERN void
+EXTERN void
ayemu_set_regs (ayemu_ay_t *ay, unsigned char *regs);
EXTERN void*
@@ -146,6 +144,4 @@ ayemu_gen_sound (ayemu_ay_t *ay, void *buf, size_t bufsize);
/*@}*/
-END_C_DECLS
-
#endif
diff --git a/src/vtx/ayemu_vtxfile.h b/src/vtx/ayemu_vtxfile.h
index b938d951fbe1..227945db24ec 100644
--- a/src/vtx/ayemu_vtxfile.h
+++ b/src/vtx/ayemu_vtxfile.h
@@ -1,9 +1,8 @@
#ifndef _AYEMU_vtxfile_h
#define _AYEMU_vtxfile_h
-#include <glib.h>
#include <inttypes.h>
-#include <audacious/plugin.h>
+#include <libaudcore/plugin.h>
#include "ayemu_8912.h"
/* The following constants and data structure comes from
@@ -15,8 +14,6 @@
typedef char NTstring[AYEMU_VTX_NTSTRING_MAX+1];
-BEGIN_C_DECLS
-
/** VTX file format header and status of open file
* \internal
*
@@ -50,44 +47,33 @@ struct VTXFileHeader
* It stores VTX file header and current state
* (open file pointer, extracted register data, etc).
*/
-typedef struct
+struct ayemu_vtx_t
{
- VFSFile *fp; /**< opening .vtx file pointer */
- struct VTXFileHeader hdr; /**< VTX header data */
- char *regdata; /**< unpacked song data */
- int pos; /**< current data frame offset */
-} ayemu_vtx_t;
+ VTXFileHeader hdr; /**< VTX header data */
+ Index<unsigned char> regdata; /**< unpacked song data */
+ int pos; /**< current data frame offset */
+ /** Read vtx file header
+ \return Return true if success, else false
+ */
+ bool read_header(VFSFile &file);
-/** Open vtx file and read vtx file header
- \arg \c vtx - pointer to ayemu_vtx_t structure
- \arg \c filename - filename for open vtx file
- \return Return true if success, else false
-*/
-EXTERN int ayemu_vtx_open (ayemu_vtx_t *vtx, const char *filename);
-
-/** Read and encode lha data from .vtx file.
- * \return Return pointer to unpacked data or NULL.
- */
-EXTERN char *ayemu_vtx_load_data (ayemu_vtx_t *vtx);
-
-/** Get next 14-bytes frame of AY register data.
- * \return Return value: true if sucess, false if not enought data.
- */
-EXTERN int ayemu_vtx_get_next_frame (ayemu_vtx_t *vtx, char *regs);
-
-/** Print formated file name. If fmt is NULL the default format %a - %t will used
- * \return none.
- */
-EXTERN void ayemu_vtx_sprintname (const ayemu_vtx_t *vtx, char *buf, const int sz, const char *fmt);
+ /** Read and encode lha data from .vtx file.
+ \return Return true if success, else false
+ */
+ bool load_data(VFSFile &file);
-/** Free all of allocaded resource for this file.
- * You must call this function on end work with vtx file
- */
-EXTERN void ayemu_vtx_free (ayemu_vtx_t *vtx);
+ /** Get next 14-bytes frame of AY register data.
+ * \return Return value: true if success, false if not enough data.
+ */
+ bool get_next_frame(unsigned char *regs);
-/*@}*/
+ /** Print formatted file name. If fmt is nullptr the default format %a - %t will be used
+ * \return none.
+ */
+ StringBuf sprintname(const char *fmt);
+};
-END_C_DECLS
+/*@}*/
#endif
diff --git a/src/vtx/info.c b/src/vtx/info.c
deleted file mode 100644
index ec54f39252f0..000000000000
--- a/src/vtx/info.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "ayemu.h"
-#include "vtx.h"
-
-#include <audacious/i18n.h>
-#include <libaudgui/libaudgui.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-void vtx_file_info(const gchar *filename)
-{
- static GtkWidget *box;
- ayemu_vtx_t vtx;
-
- if (!ayemu_vtx_open(&vtx, filename))
- {
- fprintf(stderr, "Can't open file %s\n", filename);
- return;
- }
- else
- {
- gchar head[1024];
- gchar body[8192];
-
- sprintf(head, "Details about %s", filename);
-
- ayemu_vtx_sprintname(&vtx, body, sizeof(body),
- "Title: %t\n"
- "Author: %a\n"
- "From : %f\n"
- "Tracker : %T\n"
- "Comment : %C\n"
- "Chip type: %c\n"
- "Stereo: %s\n"
- "Loop: %l\n"
- "Chip freq: %F\n"
- "Player Freq:%P\n"
- "Year: %y");
-
- audgui_simple_message (& box, GTK_MESSAGE_INFO, head, body);
- }
-}
diff --git a/src/vtx/info.cc b/src/vtx/info.cc
new file mode 100644
index 000000000000..8401982e70bd
--- /dev/null
+++ b/src/vtx/info.cc
@@ -0,0 +1,38 @@
+#include "ayemu.h"
+#include "vtx.h"
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/runtime.h>
+#include <libaudgui/libaudgui.h>
+#include <libaudgui/libaudgui-gtk.h>
+
+void vtx_file_info(const char *filename, VFSFile &file)
+{
+ static GtkWidget *box;
+ ayemu_vtx_t vtx;
+
+ if (!vtx.read_header(file))
+ {
+ AUDERR("Can't open file %s\n", filename);
+ return;
+ }
+ else
+ {
+ StringBuf head = str_printf(_("Details about %s"), filename);
+ StringBuf body = vtx.sprintname(_(
+ "Title: %t\n"
+ "Author: %a\n"
+ "From: %f\n"
+ "Tracker: %T\n"
+ "Comment: %C\n"
+ "Chip type: %c\n"
+ "Stereo: %s\n"
+ "Loop: %l\n"
+ "Chip freq: %F\n"
+ "Player Freq: %P\n"
+ "Year: %y"));
+
+ audgui_simple_message (& box, GTK_MESSAGE_INFO, head, body);
+ }
+}
diff --git a/src/vtx/lh5dec.c b/src/vtx/lh5dec.c
deleted file mode 100644
index 5c67fe4484b2..000000000000
--- a/src/vtx/lh5dec.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/* extractiong lh5 module
- (c) Haruhiko Okumura
- (m) Roman Scherbakov
-*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h> /* memmove */
-#include <limits.h>
-
-static unsigned short bitbuf;
-
-#define BITBUFSIZ (CHAR_BIT * sizeof bitbuf)
-
-#define DICBIT 13 /* 12(-lh4-) or 13(-lh5-) */
-#define DICSIZ (1L << DICBIT)
-#define MATCHBIT 8 /* bits for MAXMATCH - THRESHOLD */
-#define MAXMATCH 256 /* formerly F (not more than unsigned char_MAX + 1) */
-#define THRESHOLD 3 /* choose optimal value */
-#define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
-#define CBIT 9 /* $\lfloor \log_2 NC \rfloor + 1$ */
-#define CODE_BIT 16 /* codeword length */
-#define NP (DICBIT + 1)
-#define NT (CODE_BIT + 3)
-#define PBIT 4 /* smallest integer such that (1U << PBIT) > NP */
-#define TBIT 5 /* smallest integer such that (1U << TBIT) > NT */
-#if NT > NP
-#define NPT NT
-#else
-#define NPT NP
-#endif
-
-static unsigned long origsize, compsize;
-static unsigned char *in_buf;
-static unsigned char *out_buf;
-
-static unsigned short subbitbuf;
-static int bitcount;
-
-static unsigned short left[2 * NC - 1], right[2 * NC - 1];
-static unsigned char c_len[NC], pt_len[NPT];
-static unsigned short blocksize;
-
-static unsigned short c_table[4096], pt_table[256];
-
-static int j; /* remaining bytes to copy */
-
-
-static void error(char *msg)
-{
- fprintf(stderr, "libayemu: lh5dec.c: %s\n", msg);
- exit(EXIT_FAILURE);
-}
-
-static void fillbuf(int n) /* Shift bitbuf n bits left, read n bits */
-{
- bitbuf <<= n;
- while (n > bitcount) {
- bitbuf |= subbitbuf << (n -= bitcount);
- if (compsize != 0) {
- compsize--; subbitbuf = *in_buf++;
- } else subbitbuf = 0;
- bitcount = CHAR_BIT;
- }
- bitbuf |= subbitbuf >> (bitcount -= n);
-}
-
-static unsigned short getbits(int n)
-{
- unsigned short x;
-
- x = bitbuf >> (BITBUFSIZ - n); fillbuf(n);
- return x;
-}
-
-// make table for decoding
-
-static void make_table(int nchar, unsigned char bitlen[], int tablebits, unsigned short table[])
-{
- unsigned short count[17], weight[17], start[18], *p;
- unsigned short i, k, len, ch, jutbits, avail, nextcode, mask;
-
- for (i = 1; i <= 16; i++) count[i] = 0;
- for (i = 0; i < nchar; i++) count[bitlen[i]]++;
-
- start[1] = 0;
- for (i = 1; i <= 16; i++)
- start[i + 1] = start[i] + (count[i] << (16 - i));
- if (start[17] != (unsigned short)(1U << 16)) error("Bad table");
-
- jutbits = 16 - tablebits;
- for (i = 1; i <= tablebits; i++) {
- start[i] >>= jutbits;
- weight[i] = 1U << (tablebits - i);
- }
- while (i <= 16) {
- weight[i] = 1U << (16 - i);
- i++;
- }
-
- i = start[tablebits + 1] >> jutbits;
- if (i != (unsigned short)(1U << 16)) {
- k = 1U << tablebits;
- while (i != k) table[i++] = 0;
- }
-
- avail = nchar;
- mask = 1U << (15 - tablebits);
- for (ch = 0; ch < nchar; ch++) {
- if ((len = bitlen[ch]) == 0) continue;
- nextcode = start[len] + weight[len];
- if (len <= tablebits) {
- for (i = start[len]; i < nextcode; i++) table[i] = ch;
- } else {
- k = start[len];
- p = &table[k >> jutbits];
- i = len - tablebits;
- while (i != 0) {
- if (*p == 0) {
- right[avail] = left[avail] = 0;
- *p = avail++;
- }
- if (k & mask) p = &right[*p];
- else p = &left[*p];
- k <<= 1; i--;
- }
- *p = ch;
- }
- start[len] = nextcode;
- }
-}
-
-// static Huffman
-
-static void read_pt_len(int nn, int nbit, int i_special)
-{
- int i, c, n;
- unsigned short mask;
-
- n = getbits(nbit);
- if (n == 0) {
- c = getbits(nbit);
- for (i = 0; i < nn; i++) pt_len[i] = 0;
- for (i = 0; i < 256; i++) pt_table[i] = c;
- } else {
- i = 0;
- while (i < n) {
- c = bitbuf >> (BITBUFSIZ - 3);
- if (c == 7) {
- mask = 1U << (BITBUFSIZ - 1 - 3);
- while (mask & bitbuf) { mask >>= 1; c++; }
- }
- fillbuf((c < 7) ? 3 : c - 3);
- pt_len[i++] = c;
- if (i == i_special) {
- c = getbits(2);
- while (--c >= 0) pt_len[i++] = 0;
- }
- }
- while (i < nn) pt_len[i++] = 0;
- make_table(nn, pt_len, 8, pt_table);
- }
-}
-
-static void read_c_len(void)
-{
- int i, c, n;
- unsigned short mask;
-
- n = getbits(CBIT);
- if (n == 0) {
- c = getbits(CBIT);
- for (i = 0; i < NC; i++) c_len[i] = 0;
- for (i = 0; i < 4096; i++) c_table[i] = c;
- } else {
- i = 0;
- while (i < n) {
- c = pt_table[bitbuf >> (BITBUFSIZ - 8)];
- if (c >= NT) {
- mask = 1U << (BITBUFSIZ - 1 - 8);
- do {
- if (bitbuf & mask) c = right[c];
- else c = left [c];
- mask >>= 1;
- } while (c >= NT);
- }
- fillbuf(pt_len[c]);
- if (c <= 2) {
- if (c == 0) c = 1;
- else if (c == 1) c = getbits(4) + 3;
- else c = getbits(CBIT) + 20;
- while (--c >= 0) c_len[i++] = 0;
- } else c_len[i++] = c - 2;
- }
- while (i < NC) c_len[i++] = 0;
- make_table(NC, c_len, 12, c_table);
- }
-}
-
-
-static unsigned short decode_c(void)
-{
- unsigned short j, mask;
-
- if (blocksize == 0) {
- blocksize = getbits(16);
- read_pt_len(NT, TBIT, 3);
- read_c_len();
- read_pt_len(NP, PBIT, -1);
- }
- blocksize--;
- j = c_table[bitbuf >> (BITBUFSIZ - 12)];
- if (j >= NC) {
- mask = 1U << (BITBUFSIZ - 1 - 12);
- do {
- if (bitbuf & mask) j = right[j];
- else j = left [j];
- mask >>= 1;
- } while (j >= NC);
- }
- fillbuf(c_len[j]);
- return j;
-}
-
-
-static unsigned short decode_p(void)
-{
- unsigned short j, mask;
-
- j = pt_table[bitbuf >> (BITBUFSIZ - 8)];
- if (j >= NP) {
- mask = 1U << (BITBUFSIZ - 1 - 8);
- do {
- if (bitbuf & mask) j = right[j];
- else j = left [j];
- mask >>= 1;
- } while (j >= NP);
- }
- fillbuf(pt_len[j]);
- if (j != 0) j = (1U << (j - 1)) + getbits(j - 1);
- return j;
-}
-
-
-static void decode(unsigned short count, unsigned char buffer[])
-{
- static unsigned short i;
- unsigned short r, c;
-
- r = 0;
- while (--j >= 0) {
- buffer[r] = buffer[i];
- i = (i + 1) & (DICSIZ - 1);
- if (++r == count) return;
- }
- for ( ; ; ) {
- c = decode_c();
- if (c <= UCHAR_MAX) {
- buffer[r] = c & UCHAR_MAX;
- if (++r == count) return;
- } else {
- j = c - (UCHAR_MAX + 1 - THRESHOLD);
- i = (r - decode_p() - 1) & (DICSIZ - 1);
- while (--j >= 0) {
- buffer[r] = buffer[i];
- i = (i + 1) & (DICSIZ - 1);
- if (++r == count) return;
- }
- }
- }
-}
-
-void lh5_decode(unsigned char *inp, unsigned char *outp, unsigned long original_size, unsigned long packed_size)
-{
- unsigned short n;
- unsigned char *buffer;
-
- compsize = packed_size;
- origsize = original_size;
- in_buf = inp;
- out_buf = outp;
-
- buffer = (unsigned char *) malloc(DICSIZ);
- if (!buffer) error ("Out of memory");
-
- bitbuf = 0; subbitbuf = 0; bitcount = 0;
- fillbuf(BITBUFSIZ);
- blocksize = 0;
- j = 0;
-
- while (origsize != 0) {
- n = (origsize > DICSIZ) ? DICSIZ : (unsigned short)origsize;
- decode(n, buffer);
- memmove(out_buf, buffer, n);
- out_buf += n;
- origsize -= n;
- }
-
- if (buffer) free (buffer);
- buffer = NULL;
-}
diff --git a/src/vtx/lh5dec.cc b/src/vtx/lh5dec.cc
new file mode 100644
index 000000000000..b9cebc011cb7
--- /dev/null
+++ b/src/vtx/lh5dec.cc
@@ -0,0 +1,305 @@
+/* extractiong lh5 module
+ (c) Haruhiko Okumura
+ (m) Roman Scherbakov
+*/
+#include <string.h> /* memmove */
+#include <limits.h>
+
+#include <libaudcore/runtime.h>
+
+#include "vtx.h"
+
+static unsigned short bitbuf;
+
+#define BITBUFSIZ (CHAR_BIT * sizeof bitbuf)
+
+#define DICBIT 13 /* 12(-lh4-) or 13(-lh5-) */
+#define DICSIZ (1UL << DICBIT)
+#define MATCHBIT 8 /* bits for MAXMATCH - THRESHOLD */
+#define MAXMATCH 256 /* formerly F (not more than unsigned char_MAX + 1) */
+#define THRESHOLD 3 /* choose optimal value */
+#define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
+#define CBIT 9 /* $\lfloor \log_2 NC \rfloor + 1$ */
+#define CODE_BIT 16 /* codeword length */
+#define NP (DICBIT + 1)
+#define NT (CODE_BIT + 3)
+#define PBIT 4 /* smallest integer such that (1U << PBIT) > NP */
+#define TBIT 5 /* smallest integer such that (1U << TBIT) > NT */
+#if NT > NP
+#define NPT NT
+#else
+#define NPT NP
+#endif
+
+static unsigned long origsize, compsize;
+static const unsigned char *in_buf;
+static unsigned char *out_buf;
+
+static unsigned short subbitbuf;
+static int bitcount;
+
+static unsigned short left[2 * NC - 1], right[2 * NC - 1];
+static unsigned char c_len[NC], pt_len[NPT];
+static unsigned short blocksize;
+
+static unsigned short c_table[4096], pt_table[256];
+
+static int j; /* remaining bytes to copy */
+
+class DecodeError {}; // exception
+
+static void error(const char *msg)
+{
+ AUDERR("%s\n", msg);
+ throw DecodeError();
+}
+
+static void fillbuf(int n) /* Shift bitbuf n bits left, read n bits */
+{
+ bitbuf <<= n;
+ while (n > bitcount) {
+ bitbuf |= subbitbuf << (n -= bitcount);
+ if (compsize != 0) {
+ compsize--; subbitbuf = *in_buf++;
+ } else subbitbuf = 0;
+ bitcount = CHAR_BIT;
+ }
+ bitbuf |= subbitbuf >> (bitcount -= n);
+}
+
+static unsigned short getbits(int n)
+{
+ unsigned short x;
+
+ x = bitbuf >> (BITBUFSIZ - n); fillbuf(n);
+ return x;
+}
+
+// make table for decoding
+
+static void make_table(int nchar, unsigned char bitlen[], int tablebits, unsigned short table[])
+{
+ unsigned short count[17], weight[17], start[18], *p;
+ unsigned short i, k, len, ch, jutbits, avail, nextcode, mask;
+
+ for (i = 1; i <= 16; i++) count[i] = 0;
+ for (i = 0; i < nchar; i++) count[bitlen[i]]++;
+
+ start[1] = 0;
+ for (i = 1; i <= 16; i++)
+ start[i + 1] = start[i] + (count[i] << (16 - i));
+ if (start[17] != (unsigned short)(1U << 16)) error("Bad table");
+
+ jutbits = 16 - tablebits;
+ for (i = 1; i <= tablebits; i++) {
+ start[i] >>= jutbits;
+ weight[i] = 1U << (tablebits - i);
+ }
+ while (i <= 16) {
+ weight[i] = 1U << (16 - i);
+ i++;
+ }
+
+ i = start[tablebits + 1] >> jutbits;
+ if (i != (unsigned short)(1U << 16)) {
+ k = 1U << tablebits;
+ while (i != k) table[i++] = 0;
+ }
+
+ avail = nchar;
+ mask = 1U << (15 - tablebits);
+ for (ch = 0; ch < nchar; ch++) {
+ if ((len = bitlen[ch]) == 0) continue;
+ nextcode = start[len] + weight[len];
+ if (len <= tablebits) {
+ for (i = start[len]; i < nextcode; i++) table[i] = ch;
+ } else {
+ k = start[len];
+ p = &table[k >> jutbits];
+ i = len - tablebits;
+ while (i != 0) {
+ if (*p == 0) {
+ right[avail] = left[avail] = 0;
+ *p = avail++;
+ }
+ if (k & mask) p = &right[*p];
+ else p = &left[*p];
+ k <<= 1; i--;
+ }
+ *p = ch;
+ }
+ start[len] = nextcode;
+ }
+}
+
+// static Huffman
+
+static void read_pt_len(int nn, int nbit, int i_special)
+{
+ int i, c, n;
+ unsigned short mask;
+
+ n = getbits(nbit);
+ if (n == 0) {
+ c = getbits(nbit);
+ for (i = 0; i < nn; i++) pt_len[i] = 0;
+ for (i = 0; i < 256; i++) pt_table[i] = c;
+ } else {
+ i = 0;
+ while (i < n) {
+ c = bitbuf >> (BITBUFSIZ - 3);
+ if (c == 7) {
+ mask = 1U << (BITBUFSIZ - 1 - 3);
+ while (mask & bitbuf) { mask >>= 1; c++; }
+ }
+ fillbuf((c < 7) ? 3 : c - 3);
+ pt_len[i++] = c;
+ if (i == i_special) {
+ c = getbits(2);
+ while (--c >= 0) pt_len[i++] = 0;
+ }
+ }
+ while (i < nn) pt_len[i++] = 0;
+ make_table(nn, pt_len, 8, pt_table);
+ }
+}
+
+static void read_c_len(void)
+{
+ int i, c, n;
+ unsigned short mask;
+
+ n = getbits(CBIT);
+ if (n == 0) {
+ c = getbits(CBIT);
+ for (i = 0; i < NC; i++) c_len[i] = 0;
+ for (i = 0; i < 4096; i++) c_table[i] = c;
+ } else {
+ i = 0;
+ while (i < n) {
+ c = pt_table[bitbuf >> (BITBUFSIZ - 8)];
+ if (c >= NT) {
+ mask = 1U << (BITBUFSIZ - 1 - 8);
+ do {
+ if (bitbuf & mask) c = right[c];
+ else c = left [c];
+ mask >>= 1;
+ } while (c >= NT);
+ }
+ fillbuf(pt_len[c]);
+ if (c <= 2) {
+ if (c == 0) c = 1;
+ else if (c == 1) c = getbits(4) + 3;
+ else c = getbits(CBIT) + 20;
+ while (--c >= 0) c_len[i++] = 0;
+ } else c_len[i++] = c - 2;
+ }
+ while (i < NC) c_len[i++] = 0;
+ make_table(NC, c_len, 12, c_table);
+ }
+}
+
+
+static unsigned short decode_c(void)
+{
+ unsigned short j, mask;
+
+ if (blocksize == 0) {
+ blocksize = getbits(16);
+ read_pt_len(NT, TBIT, 3);
+ read_c_len();
+ read_pt_len(NP, PBIT, -1);
+ }
+ blocksize--;
+ j = c_table[bitbuf >> (BITBUFSIZ - 12)];
+ if (j >= NC) {
+ mask = 1U << (BITBUFSIZ - 1 - 12);
+ do {
+ if (bitbuf & mask) j = right[j];
+ else j = left [j];
+ mask >>= 1;
+ } while (j >= NC);
+ }
+ fillbuf(c_len[j]);
+ return j;
+}
+
+
+static unsigned short decode_p(void)
+{
+ unsigned short j, mask;
+
+ j = pt_table[bitbuf >> (BITBUFSIZ - 8)];
+ if (j >= NP) {
+ mask = 1U << (BITBUFSIZ - 1 - 8);
+ do {
+ if (bitbuf & mask) j = right[j];
+ else j = left [j];
+ mask >>= 1;
+ } while (j >= NP);
+ }
+ fillbuf(pt_len[j]);
+ if (j != 0) j = (1U << (j - 1)) + getbits(j - 1);
+ return j;
+}
+
+
+static void decode(unsigned short count, unsigned char buffer[])
+{
+ static unsigned short i;
+ unsigned short r, c;
+
+ r = 0;
+ while (--j >= 0) {
+ buffer[r] = buffer[i];
+ i = (i + 1) & (DICSIZ - 1);
+ if (++r == count) return;
+ }
+ for ( ; ; ) {
+ c = decode_c();
+ if (c <= UCHAR_MAX) {
+ buffer[r] = c & UCHAR_MAX;
+ if (++r == count) return;
+ } else {
+ j = c - (UCHAR_MAX + 1 - THRESHOLD);
+ i = (r - decode_p() - 1) & (DICSIZ - 1);
+ while (--j >= 0) {
+ buffer[r] = buffer[i];
+ i = (i + 1) & (DICSIZ - 1);
+ if (++r == count) return;
+ }
+ }
+ }
+}
+
+bool lh5_decode(const Index<char> &in, Index<unsigned char> &out)
+{
+ unsigned short n;
+ Index<unsigned char> buffer;
+
+ compsize = in.len();
+ origsize = out.len();
+ in_buf = (unsigned char *)in.begin();
+ out_buf = out.begin();
+
+ buffer.resize(DICSIZ);
+
+ bitbuf = 0; subbitbuf = 0; bitcount = 0;
+ fillbuf(BITBUFSIZ);
+ blocksize = 0;
+ j = 0;
+
+ try {
+ while (origsize != 0) {
+ n = aud::min(DICSIZ, origsize);
+ decode(n, buffer.begin());
+ memmove(out_buf, buffer.begin(), n);
+ out_buf += n;
+ origsize -= n;
+ }
+ } catch (DecodeError &) {
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/vtx/vtx.c b/src/vtx/vtx.c
deleted file mode 100644
index e88b482c1a8b..000000000000
--- a/src/vtx/vtx.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/* VTX Input Plugin for Audacious
- *
- * Copyright (C) 2002-2004 Sashnov Alexander
- * Copyright (C) 2010 MichaÅ Lipski <tallica at o2.pl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <audacious/debug.h>
-
-#include "vtx.h"
-#include "ayemu.h"
-
-#define SNDBUFSIZE 1024
-static gchar sndbuf[SNDBUFSIZE];
-static gint freq = 44100;
-static gint chans = 2;
-static gint bits = 16;
-
-ayemu_ay_t ay;
-ayemu_vtx_t vtx;
-
-static const gchar *vtx_fmts[] = { "vtx", NULL };
-
-gint vtx_is_our_fd(const gchar * filename, VFSFile * fp)
-{
- gchar buf[2];
- if (vfs_fread(buf, 1, 2, fp) < 2)
- return FALSE;
- return (!g_ascii_strncasecmp(buf, "ay", 2) || !g_ascii_strncasecmp(buf, "ym", 2));
-}
-
-Tuple *vtx_get_song_tuple_from_vtx(const gchar * filename, ayemu_vtx_t * in)
-{
- Tuple *out = tuple_new_from_filename(filename);
-
- tuple_set_str(out, FIELD_ARTIST, in->hdr.author);
- tuple_set_str(out, FIELD_TITLE, in->hdr.title);
-
- tuple_set_int(out, FIELD_LENGTH, in->hdr.regdata_size / 14 * 1000 / 50);
-
- tuple_set_str(out, FIELD_GENRE, (in->hdr.chiptype == AYEMU_AY) ? "AY chiptunes" : "YM chiptunes");
- tuple_set_str(out, FIELD_ALBUM, in->hdr.from);
-
- tuple_set_str(out, FIELD_QUALITY, _("sequenced"));
- tuple_set_str(out, FIELD_CODEC, in->hdr.tracker);
-
- tuple_set_int(out, FIELD_YEAR, in->hdr.year);
-
- return out;
-}
-
-Tuple *vtx_probe_for_tuple(const gchar *filename, VFSFile *fd)
-{
- ayemu_vtx_t tmp;
-
- if (ayemu_vtx_open(&tmp, filename))
- {
- Tuple *ti = vtx_get_song_tuple_from_vtx(filename, &tmp);
- ayemu_vtx_free(&tmp);
- return ti;
- }
-
- return NULL;
-}
-
-static gboolean vtx_play(const gchar * filename, VFSFile * file)
-{
- gboolean eof = FALSE;
- void *stream; /* pointer to current position in sound buffer */
- guchar regs[14];
- gint need;
- gint left; /* how many sound frames can play with current AY register frame */
- gint donow;
- gint rate;
-
- left = 0;
- rate = chans * (bits / 8);
-
- memset(&ay, 0, sizeof(ay));
-
- if (!ayemu_vtx_open(&vtx, filename))
- {
- g_print("libvtx: Error read vtx header from %s\n", filename);
- return FALSE;
- }
- else if (!ayemu_vtx_load_data(&vtx))
- {
- g_print("libvtx: Error read vtx data from %s\n", filename);
- return FALSE;
- }
-
- ayemu_init(&ay);
- ayemu_set_chip_type(&ay, vtx.hdr.chiptype, NULL);
- ayemu_set_chip_freq(&ay, vtx.hdr.chipFreq);
- ayemu_set_stereo(&ay, vtx.hdr.stereo, NULL);
-
- if (aud_input_open_audio(FMT_S16_NE, freq, chans) == 0)
- {
- g_print("libvtx: output audio error!\n");
- return FALSE;
- }
-
- aud_input_set_bitrate(14 * 50 * 8);
-
- while (!aud_input_check_stop() && !eof)
- {
- /* (time in sec) * 50 = offset in AY register data frames */
- int seek_value = aud_input_check_seek();
- if (seek_value >= 0)
- vtx.pos = seek_value / 20;
-
- /* fill sound buffer */
- stream = sndbuf;
-
- for (need = SNDBUFSIZE / rate; need > 0; need -= donow)
- {
- if (left > 0)
- { /* use current AY register frame */
- donow = (need > left) ? left : need;
- left -= donow;
- stream = ayemu_gen_sound(&ay, (char *)stream, donow * rate);
- }
- else
- { /* get next AY register frame */
- if (ayemu_vtx_get_next_frame(&vtx, (char *)regs) == 0)
- {
- donow = need;
- memset(stream, 0, donow * rate);
- eof = TRUE;
- }
- else
- {
- left = freq / vtx.hdr.playerFreq;
- ayemu_set_regs(&ay, regs);
- donow = 0;
- }
- }
- }
-
- aud_input_write_audio(sndbuf, SNDBUFSIZE);
- }
-
- ayemu_vtx_free(&vtx);
-
- return TRUE;
-}
-
-static const char vtx_about[] =
- N_("Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
- "Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
- "Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>");
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("VTX Decoder"),
- .domain = PACKAGE,
- .about_text = vtx_about,
- .play = vtx_play,
- .file_info_box = vtx_file_info,
- .probe_for_tuple = vtx_probe_for_tuple,
- .is_our_file_from_vfs = vtx_is_our_fd,
- .extensions = vtx_fmts
-)
diff --git a/src/vtx/vtx.cc b/src/vtx/vtx.cc
new file mode 100644
index 000000000000..d6709451a984
--- /dev/null
+++ b/src/vtx/vtx.cc
@@ -0,0 +1,186 @@
+/* VTX Input Plugin for Audacious
+ *
+ * Copyright (C) 2002-2004 Sashnov Alexander
+ * Copyright (C) 2010 MichaÅ Lipski <tallica at o2.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <string.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+#include "vtx.h"
+#include "ayemu.h"
+
+class VTXPlugin : public InputPlugin
+{
+public:
+ static const char about[];
+ static const char *const exts[];
+
+ static constexpr PluginInfo info = {
+ N_("VTX Decoder"),
+ PACKAGE,
+ about
+ };
+
+ static constexpr auto iinfo = InputInfo()
+ .with_exts(exts);
+
+ constexpr VTXPlugin() : InputPlugin(info, iinfo) {}
+
+ bool is_our_file(const char *filename, VFSFile &file);
+ Tuple read_tuple(const char *filename, VFSFile &file);
+ bool play(const char *filename, VFSFile &file);
+
+ bool file_info_box(const char *filename, VFSFile &file)
+ { vtx_file_info(filename, file); return true; }
+};
+
+EXPORT VTXPlugin aud_plugin_instance;
+
+#define SNDBUFSIZE 1024
+static char sndbuf[SNDBUFSIZE];
+static int freq = 44100;
+static int chans = 2;
+static int bits = 16;
+
+const char *const VTXPlugin::exts[] = { "vtx", nullptr };
+
+bool VTXPlugin::is_our_file(const char *filename, VFSFile &file)
+{
+ char buf[2];
+ if (file.fread (buf, 1, 2) < 2)
+ return false;
+ return (!strcmp_nocase(buf, "ay", 2) || !strcmp_nocase(buf, "ym", 2));
+}
+
+Tuple vtx_get_song_tuple_from_vtx(const char * filename, ayemu_vtx_t * in)
+{
+ Tuple tuple;
+ tuple.set_filename (filename);
+
+ tuple.set_str (Tuple::Artist, in->hdr.author);
+ tuple.set_str (Tuple::Title, in->hdr.title);
+
+ tuple.set_int (Tuple::Length, in->hdr.regdata_size / 14 * 1000 / 50);
+
+ tuple.set_str (Tuple::Genre, (in->hdr.chiptype == AYEMU_AY) ? "AY chiptunes" : "YM chiptunes");
+ tuple.set_str (Tuple::Album, in->hdr.from);
+
+ tuple.set_str (Tuple::Quality, _("sequenced"));
+ tuple.set_str (Tuple::Codec, in->hdr.tracker);
+
+ tuple.set_int (Tuple::Year, in->hdr.year);
+
+ return tuple;
+}
+
+Tuple VTXPlugin::read_tuple(const char *filename, VFSFile &file)
+{
+ ayemu_vtx_t tmp;
+
+ if (tmp.read_header(file))
+ return vtx_get_song_tuple_from_vtx(filename, &tmp);
+
+ return Tuple ();
+}
+
+bool VTXPlugin::play(const char *filename, VFSFile &file)
+{
+ ayemu_ay_t ay;
+ ayemu_vtx_t vtx;
+
+ bool eof = false;
+ void *stream; /* pointer to current position in sound buffer */
+ unsigned char regs[14];
+ int need;
+ int left; /* how many sound frames can play with current AY register frame */
+ int donow;
+ int rate;
+
+ left = 0;
+ rate = chans * (bits / 8);
+
+ memset(&ay, 0, sizeof(ay));
+
+ if (!vtx.read_header(file))
+ {
+ AUDERR("Error read vtx header from %s\n", filename);
+ return false;
+ }
+ else if (!vtx.load_data(file))
+ {
+ AUDERR("Error read vtx data from %s\n", filename);
+ return false;
+ }
+
+ ayemu_init(&ay);
+ ayemu_set_chip_type(&ay, vtx.hdr.chiptype, nullptr);
+ ayemu_set_chip_freq(&ay, vtx.hdr.chipFreq);
+ ayemu_set_stereo(&ay, (ayemu_stereo_t) vtx.hdr.stereo, nullptr);
+
+ set_stream_bitrate(14 * 50 * 8);
+ open_audio(FMT_S16_NE, freq, chans);
+
+ while (!check_stop() && !eof)
+ {
+ /* (time in sec) * 50 = offset in AY register data frames */
+ int seek_value = check_seek();
+ if (seek_value >= 0)
+ vtx.pos = seek_value / 20;
+
+ /* fill sound buffer */
+ stream = sndbuf;
+
+ for (need = SNDBUFSIZE / rate; need > 0; need -= donow)
+ {
+ if (left > 0)
+ { /* use current AY register frame */
+ donow = (need > left) ? left : need;
+ left -= donow;
+ stream = ayemu_gen_sound(&ay, (char *)stream, donow * rate);
+ }
+ else
+ { /* get next AY register frame */
+ if (!vtx.get_next_frame(regs))
+ {
+ donow = need;
+ memset(stream, 0, donow * rate);
+ eof = true;
+ }
+ else
+ {
+ left = freq / vtx.hdr.playerFreq;
+ ayemu_set_regs(&ay, regs);
+ donow = 0;
+ }
+ }
+ }
+
+ write_audio(sndbuf, SNDBUFSIZE);
+ }
+
+ return true;
+}
+
+const char VTXPlugin::about[] =
+ N_("Vortex file format player by Sashnov Alexander <sashnov at ngs.ru>\n"
+ "Based on in_vtx.dll by Roman Sherbakov <v_soft at microfor.ru>\n"
+ "Audacious plugin by Pavel Vymetalek <pvymetalek at seznam.cz>");
diff --git a/src/vtx/vtx.h b/src/vtx/vtx.h
index cae6bf830da6..1c96271b234a 100644
--- a/src/vtx/vtx.h
+++ b/src/vtx/vtx.h
@@ -1,12 +1,14 @@
#ifndef VTX_H
#define VTX_H
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
+#include <libaudcore/index.h>
-#include <audacious/plugin.h>
+class VFSFile;
-void vtx_file_info(const char *filename);
+/* info.cc */
+void vtx_file_info (const char *filename, VFSFile &file);
+
+/* lh5dec.cc */
+bool lh5_decode(const Index<char> &in, Index<unsigned char> &out);
#endif
diff --git a/src/vtx/vtxfile.c b/src/vtx/vtxfile.c
deleted file mode 100644
index b6f1376ba23c..000000000000
--- a/src/vtx/vtxfile.c
+++ /dev/null
@@ -1,331 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-#include <ctype.h>
-#include <inttypes.h>
-
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-#include "ayemu.h"
-
-/* defined in lh5dec.c */
-extern void lh5_decode(unsigned char *inp,unsigned char *outp,unsigned long original_size, unsigned long packed_size);
-
-
-/* Read 8-bit integer from file.
- * Return 1 if error occurs
- */
-static int read_byte(VFSFile *fp, int *p)
-{
- int c;
- if ((c = vfs_getc(fp)) == EOF) {
- perror("libayemu: read_byte()");
- return 1;
- }
- *p = c;
- return 0;
-}
-
-/* Read 16-bit integer from file.
- * Return 1 if error occurs
- */
-static int read_word16(VFSFile *fp, int *p)
-{
- int c;
- if ((c = vfs_getc(fp)) == EOF) {
- perror("libayemu: read_word16()");
- return 1;
- }
- *p = c;
-
- if ((c = vfs_getc(fp)) == EOF) {
- perror("libayemu: read_word16()");
- return 1;
- }
- *p += c << 8;
-
- return 0;
-}
-
-/* read 32-bit integer from file.
- * Returns 1 if error occurs
- */
-static int read_word32(VFSFile *fp, int32_t *p)
-{
- int c;
-
- if ((c = vfs_getc(fp)) == EOF) {
- perror("libayemu: read_word32()");
- return 1;
- }
- *p = c;
-
- if ((c = vfs_getc(fp)) == EOF) {
- perror("libayemu: read_word32()");
- return 1;
- }
- *p += c << 8;
-
- if ((c = vfs_getc(fp)) == EOF) {
- perror("libayemu: read_word32()");
- return 1;
- }
- *p += c << 16;
-
- if ((c = vfs_getc(fp)) == EOF) {
- perror("libayemu: read_word32()");
- return 1;
- }
- *p += c << 24;
-
- return 0;
-}
-
-/* read_NTstring: reads null-terminated string from file.
- * Return 1 if error occures.
- */
-static int read_NTstring(VFSFile *fp, char s[])
-{
- int i, c;
- for (i = 0 ; i < AYEMU_VTX_NTSTRING_MAX && (c = vfs_getc(fp)) != EOF && c ; i++)
- s[i] = c;
- s[i] = '\0';
- if (c == EOF) {
- fprintf(stderr, "libayemu: read_NTstring(): uninspected end of file!\n");
- return 1;
- }
- return 0;
-}
-
-/** Open specified .vtx file and read vtx file header
- *
- * Open specified .vtx file and read vtx file header in struct vtx
- * Return value: true if success, else false
- */
-int ayemu_vtx_open (ayemu_vtx_t *vtx, const char *filename)
-{
- char buf[2];
- int error = 0;
- int32_t int_regdata_size;
-
- vtx->regdata = NULL;
-
- if ((vtx->fp = vfs_fopen (filename, "rb")) == NULL) {
- fprintf(stderr, "ayemu_vtx_open: Cannot open file %s: %s\n", filename, strerror(errno));
- return 0;
- }
-
- if (vfs_fread(buf, 2, 1, vtx->fp) != 1) {
- fprintf(stderr,"ayemu_vtx_open: Can't read from %s: %s\n", filename, strerror(errno));
- error = 1;
- }
-
- buf[0] = tolower(buf[0]);
- buf[1] = tolower(buf[1]);
-
- if (strncmp(buf, "ay", 2) == 0)
- vtx->hdr.chiptype = AYEMU_AY;
- else if (strncmp (buf, "ym", 2) == 0)
- vtx->hdr.chiptype = AYEMU_YM;
- else {
- fprintf (stderr, "File %s is _not_ VORTEX format!\nIt not begins from AY or YM.\n", filename);
- error = 1;
- }
-
- /* read VTX header info in order format specified, see http:// ..... */
- if (!error) error = read_byte(vtx->fp, &vtx->hdr.stereo);
- if (!error) error = read_word16(vtx->fp, &vtx->hdr.loop);
- if (!error) error = read_word32(vtx->fp, &vtx->hdr.chipFreq);
- if (!error) error = read_byte(vtx->fp, &vtx->hdr.playerFreq);
- if (!error) error = read_word16(vtx->fp, &vtx->hdr.year);
- if (!error) {
- error = read_word32(vtx->fp, &int_regdata_size);
- vtx->hdr.regdata_size = (size_t) int_regdata_size;
- }
-
- if (!error) error = read_NTstring(vtx->fp, vtx->hdr.title);
- if (!error) error = read_NTstring(vtx->fp, vtx->hdr.author);
- if (!error) error = read_NTstring(vtx->fp, vtx->hdr.from);
- if (!error) error = read_NTstring(vtx->fp, vtx->hdr.tracker);
- if (!error) error = read_NTstring (vtx->fp, vtx->hdr.comment);
-
- if (error) {
- vfs_fclose(vtx->fp);
- vtx->fp = NULL;
- }
- return !error;
-}
-
-/** Read and encode lha data from .vtx file
- *
- * Return value: pointer to unpacked data or NULL
- * Note: you must call ayemu_vtx_open() first.
- */
-char *ayemu_vtx_load_data (ayemu_vtx_t *vtx)
-{
- char *packed_data;
- size_t packed_size;
- size_t buf_alloc;
- int c;
-
- if (vtx->fp == NULL) {
- fprintf(stderr, "ayemu_vtx_load_data: tune file not open yet (do you call ayemu_vtx_open first?)\n");
- return NULL;
- }
- packed_size = 0;
- buf_alloc = 4096;
- packed_data = (char *) malloc (buf_alloc);
- /* read packed AY register data to end of file. */
- while ((c = vfs_getc (vtx->fp)) != EOF) {
- if (buf_alloc < packed_size) {
- buf_alloc *= 2;
- packed_data = (char *) realloc (packed_data, buf_alloc);
- if (packed_data == NULL) {
- fprintf (stderr, "ayemu_vtx_load_data: Packed data out of memory!\n");
- vfs_fclose (vtx->fp);
- return NULL;
- }
- }
- packed_data[packed_size++] = c;
- }
- vfs_fclose (vtx->fp);
- vtx->fp = NULL;
- if ((vtx->regdata = (char *) malloc (vtx->hdr.regdata_size)) == NULL) {
- fprintf (stderr, "ayemu_vtx_load_data: Can allocate %d bytes for unpack register data\n", (int)(vtx->hdr.regdata_size));
- free (packed_data);
- return NULL;
- }
- lh5_decode ((unsigned char *)packed_data, (unsigned char *)(vtx->regdata), vtx->hdr.regdata_size, packed_size);
- free (packed_data);
- vtx->pos = 0;
- return vtx->regdata;
-}
-
-/** Get next 14-bytes frame of AY register data.
- *
- * Return value: 1 if sucess, 0 if no enought data.
- */
-int ayemu_vtx_get_next_frame (ayemu_vtx_t *vtx, char *regs)
-{
- int numframes = vtx->hdr.regdata_size / 14;
- if (vtx->pos++ >= numframes)
- return 0;
- else {
- int n;
- char *p = vtx->regdata + vtx->pos;
- for(n = 0 ; n < 14 ; n++, p+=numframes)
- regs[n] = *p;
- return 1;
- }
-}
-
-static void append_string(char *buf, const int sz, const char *str)
-{
- if (strlen(buf) + strlen(str) < sz - 1)
- strcat(buf, str);
-}
-
-static void append_number(char *buf, const int sz, const int num)
-{
- char s[32];
- str_itoa (num, s, sizeof s);
- append_string(buf, sz, s);
-}
-
-static void append_char(char *buf, const int sz, const char c)
-{
- int pos = strlen(buf);
- if (pos < sz - 1)
- buf[pos++] = c;
- buf[pos] = '\0';
-}
-
-/** Print formated file name. If fmt is NULL the default format %a - %t will used
- *
- * %% the % sign
- * %a author of song
- * %t song title
- * %y year
- * %f song from
- * %T Tracker
- * %C Comment
- * %s stereo type (ABC, BCA, ...)
- * %l 'looped' or 'non-looped'
- * %c chip type: 'AY' or 'YM'
- * %F chip Freq
- * %P player freq
- */
-void ayemu_vtx_sprintname (const ayemu_vtx_t *vtx, char *const buf, const int sz, const char *fmt)
-{
- static char *stereo_types[] = { "MONO", "ABC", "ACB", "BAC", "BCA", "CAB", "CBA" };
-
- if (fmt == NULL)
- fmt = "%a - %t";
-
- buf[0] = '\0';
-
- while (*fmt != '\0') {
- if (*fmt == '%') {
- switch(*++fmt) {
- case 'a':
- append_string(buf, sz, vtx->hdr.author);
- break;
- case 't':
- append_string(buf, sz, vtx->hdr.title);
- break;
- case 'y':
- append_number(buf, sz, vtx->hdr.year);
- break;
- case 'f':
- append_string(buf, sz, vtx->hdr.from);
- break;
- case 'T':
- append_string(buf, sz, vtx->hdr.tracker);
- break;
- case 'C':
- append_string(buf, sz, vtx->hdr.comment);
- break;
- case 's':
- append_string(buf, sz, stereo_types[vtx->hdr.stereo]);
- break;
- case 'l':
- append_string(buf, sz, (vtx->hdr.loop)? "looped" : "non-looped" );
- break;
- case 'c':
- append_string(buf, sz, (vtx->hdr.chiptype == AYEMU_AY)? "AY" : "YM" );
- break;
- case 'F':
- append_number(buf, sz, vtx->hdr.chipFreq);
- break;
- case 'P':
- append_number(buf, sz, vtx->hdr.playerFreq);
- break;
- default:
- append_char(buf, sz, *fmt);
- }
- fmt++;
- } else {
- append_char(buf, sz, *fmt++);
- }
- }
-}
-
-/** Free all of allocaded resource for this file.
- *
- * Free the unpacket register data if is and close file.
- */
-void ayemu_vtx_free (ayemu_vtx_t *vtx)
-{
- if (vtx->fp) {
- vfs_fclose(vtx->fp);
- vtx->fp = NULL;
- }
-
- if (vtx->regdata) {
- free(vtx->regdata);
- vtx->regdata = NULL;
- }
-}
diff --git a/src/vtx/vtxfile.cc b/src/vtx/vtxfile.cc
new file mode 100644
index 000000000000..ccf95d563a38
--- /dev/null
+++ b/src/vtx/vtxfile.cc
@@ -0,0 +1,229 @@
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/runtime.h>
+
+#include "ayemu.h"
+#include "vtx.h"
+
+/* Read 8-bit integer from file.
+ * Return 1 if error occurs
+ */
+static int read_byte(VFSFile &fp, int *p)
+{
+ unsigned char c;
+ if (fp.fread(&c, 1, 1) != 1) {
+ AUDERR("read_byte() error\n");
+ return 1;
+ }
+ *p = c;
+ return 0;
+}
+
+/* Read 16-bit integer from file.
+ * Return 1 if error occurs
+ */
+static int read_word16(VFSFile &fp, int *p)
+{
+ unsigned char c[2];
+ if (fp.fread(&c, 1, 2) != 2) {
+ AUDERR("read_word16() error\n");
+ return 1;
+ }
+ *p = c[0] | (c[1] << 8);
+ return 0;
+}
+
+/* read 32-bit integer from file.
+ * Returns 1 if error occurs
+ */
+static int read_word32(VFSFile &fp, int32_t *p)
+{
+ unsigned char c[4];
+ if (fp.fread(&c, 1, 4) != 4) {
+ AUDERR("read_word32() error\n");
+ return 1;
+ }
+ *p = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
+ return 0;
+}
+
+/* read_NTstring: reads null-terminated string from file.
+ * Return 1 if error occures.
+ */
+static int read_NTstring(VFSFile &fp, char s[])
+{
+ int i, n = 0;
+ unsigned char c;
+ for (i = 0 ; i < AYEMU_VTX_NTSTRING_MAX && (n = fp.fread(&c, 1, 1)) == 1 && c ; i++)
+ s[i] = c;
+ s[i] = '\0';
+ if (n != 1) {
+ AUDERR("unexpected end of file!\n");
+ return 1;
+ }
+ return 0;
+}
+
+/** Open specified .vtx file and read vtx file header
+ *
+ * Open specified .vtx file and read vtx file header in struct vtx
+ * Return value: true if success, else false
+ */
+bool ayemu_vtx_t::read_header(VFSFile &file)
+{
+ char buf[2];
+ int error = 0;
+ int32_t int_regdata_size;
+
+ if (file.fread(buf, 2, 1) != 1) {
+ AUDERR("Can't read from %s\n", file.filename());
+ error = 1;
+ }
+
+ if (!strcmp_nocase(buf, "ay", 2))
+ hdr.chiptype = AYEMU_AY;
+ else if (!strcmp_nocase(buf, "ym", 2))
+ hdr.chiptype = AYEMU_YM;
+ else {
+ AUDERR("File %s is _not_ VORTEX format!\nIt not begins from AY or YM.\n", file.filename());
+ error = 1;
+ }
+
+ /* read VTX header info in order format specified, see http:// ..... */
+ if (!error) error = read_byte(file, &hdr.stereo);
+ if (!error) error = read_word16(file, &hdr.loop);
+ if (!error) error = read_word32(file, &hdr.chipFreq);
+ if (!error) error = read_byte(file, &hdr.playerFreq);
+ if (!error) error = read_word16(file, &hdr.year);
+ if (!error) {
+ error = read_word32(file, &int_regdata_size);
+ hdr.regdata_size = int_regdata_size;
+ }
+
+ if (!error) error = read_NTstring(file, hdr.title);
+ if (!error) error = read_NTstring(file, hdr.author);
+ if (!error) error = read_NTstring(file, hdr.from);
+ if (!error) error = read_NTstring(file, hdr.tracker);
+ if (!error) error = read_NTstring(file, hdr.comment);
+
+ return !error;
+}
+
+/** Read and encode lha data from .vtx file
+ *
+ * Return value: pointer to unpacked data or nullptr
+ * Note: you must call ayemu_vtx_open() first.
+ */
+bool ayemu_vtx_t::load_data(VFSFile &file)
+{
+ /* read packed AY register data to end of file. */
+ Index<char> packed_data = file.read_all();
+
+ regdata.resize(hdr.regdata_size);
+ if (!lh5_decode(packed_data, regdata))
+ return false;
+
+ pos = 0;
+ return true;
+}
+
+/** Get next 14-bytes frame of AY register data.
+ *
+ * Return value: true if success, false if not enough data.
+ */
+bool ayemu_vtx_t::get_next_frame(unsigned char *regs)
+{
+ int numframes = hdr.regdata_size / 14;
+ if (pos++ >= numframes)
+ return 0;
+ else {
+ int n;
+ unsigned char *p = ®data[pos];
+ for(n = 0 ; n < 14 ; n++, p+=numframes)
+ regs[n] = *p;
+ return 1;
+ }
+}
+
+/** Print formatted file name. If fmt is nullptr the default format %a - %t will be used
+ *
+ * %% the % sign
+ * %a author of song
+ * %t song title
+ * %y year
+ * %f song from
+ * %T Tracker
+ * %C Comment
+ * %s stereo type (ABC, BCA, ...)
+ * %l 'looped' or 'non-looped'
+ * %c chip type: 'AY' or 'YM'
+ * %F chip Freq
+ * %P player freq
+ */
+StringBuf ayemu_vtx_t::sprintname (const char *fmt)
+{
+ static const char *stereo_types[] = { "MONO", "ABC", "ACB", "BAC", "BCA", "CAB", "CBA" };
+
+ if (!fmt)
+ fmt = "%a - %t";
+
+ StringBuf buf(0);
+
+ while (*fmt) {
+ if (*fmt == '%') {
+ switch(*++fmt) {
+ case 'a':
+ buf.insert(-1, hdr.author);
+ break;
+ case 't':
+ buf.insert(-1, hdr.title);
+ break;
+ case 'y':
+ buf.combine(int_to_str(hdr.year));
+ break;
+ case 'f':
+ buf.insert(-1, hdr.from);
+ break;
+ case 'T':
+ buf.insert(-1, hdr.tracker);
+ break;
+ case 'C':
+ buf.insert(-1, hdr.comment);
+ break;
+ case 's':
+ buf.insert(-1, stereo_types[hdr.stereo]);
+ break;
+ case 'l':
+ buf.insert(-1, (hdr.loop)? "looped" : "non-looped" );
+ break;
+ case 'c':
+ buf.insert(-1, (hdr.chiptype == AYEMU_AY)? "AY" : "YM" );
+ break;
+ case 'F':
+ buf.combine(int_to_str(hdr.chipFreq));
+ break;
+ case 'P':
+ buf.combine(int_to_str(hdr.playerFreq));
+ break;
+ default:
+ buf.insert(-1, fmt, 1);
+ }
+ fmt++;
+ } else {
+ const char *p = strchr(fmt, '%');
+ if (!p)
+ p = fmt + strlen(fmt);
+
+ buf.insert(-1, fmt, p - fmt);
+ fmt = p;
+ }
+ }
+
+ return buf;
+}
diff --git a/src/wavpack/Makefile b/src/wavpack/Makefile
index 56928003d11a..358f41178cc4 100644
--- a/src/wavpack/Makefile
+++ b/src/wavpack/Makefile
@@ -1,12 +1,14 @@
PLUGIN = wavpack${PLUGIN_SUFFIX}
-SRCS = wavpack.c
+SRCS = wavpack.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${WAVPACK_CFLAGS} -I../..
-LIBS += ${GLIB_LIBS} ${WAVPACK_LIBS} -laudtag
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${WAVPACK_CFLAGS} -I../..
+LIBS += ${WAVPACK_LIBS} -laudtag
diff --git a/src/wavpack/wavpack.c b/src/wavpack/wavpack.c
deleted file mode 100644
index b0130165430a..000000000000
--- a/src/wavpack/wavpack.c
+++ /dev/null
@@ -1,279 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <wavpack/wavpack.h>
-
-#include <audacious/audtag.h>
-#include <audacious/debug.h>
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-#define BUFFER_SIZE 256 /* read buffer size, in samples / frames */
-#define SAMPLE_SIZE(a) (a == 8 ? sizeof(uint8_t) : (a == 16 ? sizeof(uint16_t) : sizeof(uint32_t)))
-#define SAMPLE_FMT(a) (a == 8 ? FMT_S8 : (a == 16 ? FMT_S16_NE : (a == 24 ? FMT_S24_NE : FMT_S32_NE)))
-
-
-/* Audacious VFS wrappers for Wavpack stream reading
- */
-
-static int32_t
-wv_read_bytes(void *id, void *data, int32_t bcount)
-{
- return vfs_fread(data, 1, bcount, (VFSFile *) id);
-}
-
-static uint32_t
-wv_get_pos(void *id)
-{
- return vfs_ftell((VFSFile *) id);
-}
-
-static int
-wv_set_pos_abs(void *id, uint32_t pos)
-{
- return vfs_fseek((VFSFile *) id, pos, SEEK_SET);
-}
-
-static int
-wv_set_pos_rel(void *id, int32_t delta, int mode)
-{
- return vfs_fseek((VFSFile *) id, delta, mode);
-}
-
-static int
-wv_push_back_byte(void *id, int c)
-{
- return vfs_ungetc(c, (VFSFile *) id);
-}
-
-static uint32_t
-wv_get_length(void *id)
-{
- VFSFile *file = (VFSFile *) id;
-
- if (file == NULL)
- return 0;
-
- return vfs_fsize(file);
-}
-
-static int wv_can_seek(void *id)
-{
- return (vfs_is_streaming((VFSFile *) id) == FALSE);
-}
-
-static int32_t wv_write_bytes(void *id, void *data, int32_t bcount)
-{
- return vfs_fwrite(data, 1, bcount, (VFSFile *) id);
-}
-
-WavpackStreamReader wv_readers = {
- wv_read_bytes,
- wv_get_pos,
- wv_set_pos_abs,
- wv_set_pos_rel,
- wv_push_back_byte,
- wv_get_length,
- wv_can_seek,
- wv_write_bytes
-};
-
-static bool_t wv_attach (const char * filename, VFSFile * wv_input,
- VFSFile * * wvc_input, WavpackContext * * ctx, char * error, int flags)
-{
- if (flags & OPEN_WVC)
- {
- SPRINTF (corrFilename, "%sc", filename);
- if (vfs_file_test (corrFilename, VFS_IS_REGULAR))
- * wvc_input = vfs_fopen (corrFilename, "r");
- else
- * wvc_input = NULL;
- }
-
- * ctx = WavpackOpenFileInputEx (& wv_readers, wv_input, * wvc_input, error, flags, 0);
- return (* ctx != NULL);
-}
-
-static void wv_deattach (VFSFile * wvc_input, WavpackContext * ctx)
-{
- if (wvc_input != NULL)
- vfs_fclose(wvc_input);
- WavpackCloseFile(ctx);
-}
-
-static bool_t wv_play (const char * filename, VFSFile * file)
-{
- if (file == NULL)
- return FALSE;
-
- int32_t *input = NULL;
- void *output = NULL;
- int sample_rate, num_channels, bits_per_sample;
- unsigned num_samples;
- WavpackContext *ctx = NULL;
- VFSFile *wvc_input = NULL;
- bool_t error = FALSE;
-
- if (! wv_attach (filename, file, & wvc_input, & ctx, NULL, OPEN_TAGS |
- OPEN_WVC))
- {
- fprintf (stderr, "Error opening Wavpack file '%s'.", filename);
- error = TRUE;
- goto error_exit;
- }
-
- sample_rate = WavpackGetSampleRate(ctx);
- num_channels = WavpackGetNumChannels(ctx);
- bits_per_sample = WavpackGetBitsPerSample(ctx);
- num_samples = WavpackGetNumSamples(ctx);
-
- if (!aud_input_open_audio(SAMPLE_FMT(bits_per_sample), sample_rate, num_channels))
- {
- fprintf (stderr, "Error opening audio output.");
- error = TRUE;
- goto error_exit;
- }
-
- input = g_new(int32_t, BUFFER_SIZE * num_channels);
- output = g_malloc(BUFFER_SIZE * num_channels * SAMPLE_SIZE(bits_per_sample));
- if (input == NULL || output == NULL)
- goto error_exit;
-
- aud_input_set_bitrate(WavpackGetAverageBitrate(ctx, num_channels));
-
- while (! aud_input_check_stop ())
- {
- int seek_value = aud_input_check_seek ();
- if (seek_value >= 0)
- WavpackSeekSample (ctx, (int64_t) seek_value * sample_rate / 1000);
-
- /* Decode audio data */
- unsigned samples_left = num_samples - WavpackGetSampleIndex(ctx);
-
- if (samples_left == 0)
- break;
-
- int ret = WavpackUnpackSamples(ctx, input, BUFFER_SIZE);
-
- if (ret < 0)
- {
- fprintf (stderr, "Error decoding file.\n");
- break;
- }
- else
- {
- /* Perform audio data conversion and output */
- unsigned i;
- int32_t *rp = input;
- int8_t *wp = output;
- int16_t *wp2 = output;
- int32_t *wp4 = output;
-
- if (bits_per_sample == 8)
- {
- for (i = 0; i < ret * num_channels; i++, wp++, rp++)
- *wp = *rp & 0xff;
- }
- else if (bits_per_sample == 16)
- {
- for (i = 0; i < ret * num_channels; i++, wp2++, rp++)
- *wp2 = *rp & 0xffff;
- }
- else if (bits_per_sample == 24 || bits_per_sample == 32)
- {
- for (i = 0; i < ret * num_channels; i++, wp4++, rp++)
- *wp4 = *rp;
- }
-
- aud_input_write_audio(output, ret * num_channels * SAMPLE_SIZE(bits_per_sample));
- }
- }
-
-error_exit:
-
- g_free(input);
- g_free(output);
- wv_deattach (wvc_input, ctx);
-
- return ! error;
-}
-
-static char *
-wv_get_quality(WavpackContext *ctx)
-{
- int mode = WavpackGetMode(ctx);
- const char *quality;
-
- if (mode & MODE_LOSSLESS)
- quality = _("lossless");
- else if (mode & MODE_HYBRID)
- quality = _("lossy (hybrid)");
- else
- quality = _("lossy");
-
- return str_printf ("%s%s%s", quality,
- (mode & MODE_WVC) ? " (wvc corrected)" : "",
-#ifdef MODE_DNS /* WavPack 4.50 or later */
- (mode & MODE_DNS) ? " (dynamic noise shaped)" :
-#endif
- "");
-}
-
-static Tuple *
-wv_probe_for_tuple(const char * filename, VFSFile * fd)
-{
- WavpackContext *ctx;
- Tuple *tu;
- char error[1024];
-
- ctx = WavpackOpenFileInputEx(&wv_readers, fd, NULL, error, OPEN_TAGS, 0);
-
- if (ctx == NULL)
- return NULL;
-
- AUDDBG("starting probe of %p\n", (void *) fd);
-
- tu = tuple_new_from_filename(filename);
-
- tuple_set_int(tu, FIELD_LENGTH,
- ((uint64_t) WavpackGetNumSamples(ctx) * 1000) / (uint64_t) WavpackGetSampleRate(ctx));
- tuple_set_str(tu, FIELD_CODEC, "WavPack");
-
- char * quality = wv_get_quality (ctx);
- tuple_set_str (tu, FIELD_QUALITY, quality);
- str_unref (quality);
-
- WavpackCloseFile(ctx);
-
- if (! vfs_fseek (fd, 0, SEEK_SET))
- tag_tuple_read (tu, fd);
-
- AUDDBG("returning tuple %p for file %p\n", (void *) tu, (void *) fd);
- return tu;
-}
-
-static bool_t wv_write_tag (const char * filename, VFSFile * handle, const Tuple * tuple)
-{
- return tag_tuple_write(tuple, handle, TAG_TYPE_APE);
-}
-
-static const char wv_about[] =
- N_("Copyright 2006 William Pitcock <nenolod at nenolod.net>\n\n"
- "Some of the plugin code was by Miles Egan.");
-
-static const char *wv_fmts[] = { "wv", NULL };
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("WavPack Decoder"),
- .domain = PACKAGE,
- .about_text = wv_about,
- .play = wv_play,
- .extensions = wv_fmts,
- .probe_for_tuple = wv_probe_for_tuple,
- .update_song_tuple = wv_write_tag,
-)
diff --git a/src/wavpack/wavpack.cc b/src/wavpack/wavpack.cc
new file mode 100644
index 000000000000..f726702f6484
--- /dev/null
+++ b/src/wavpack/wavpack.cc
@@ -0,0 +1,258 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include <wavpack/wavpack.h>
+
+#define WANT_VFS_STDIO_COMPAT
+#include <audacious/audtag.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/audstrings.h>
+
+#define BUFFER_SIZE 256 /* read buffer size, in samples / frames */
+#define SAMPLE_SIZE(a) (a == 8 ? sizeof(uint8_t) : (a == 16 ? sizeof(uint16_t) : sizeof(uint32_t)))
+#define SAMPLE_FMT(a) (a == 8 ? FMT_S8 : (a == 16 ? FMT_S16_NE : (a == 24 ? FMT_S24_NE : FMT_S32_NE)))
+
+class WavpackPlugin : public InputPlugin
+{
+public:
+ static const char about[];
+ static const char * const exts[];
+
+ static constexpr PluginInfo info = {
+ N_("WavPack Decoder"),
+ PACKAGE,
+ about
+ };
+
+ static constexpr auto iinfo = InputInfo (FlagWritesTag)
+ .with_exts (exts);
+
+ constexpr WavpackPlugin() : InputPlugin (info, iinfo) {}
+
+ bool is_our_file (const char * filename, VFSFile & file)
+ { return false; }
+
+ Tuple read_tuple (const char * filename, VFSFile & file);
+ bool write_tuple (const char * filename, VFSFile & file, const Tuple & tuple);
+ bool play (const char * filename, VFSFile & file);
+};
+
+EXPORT WavpackPlugin aud_plugin_instance;
+
+/* Audacious VFS wrappers for Wavpack stream reading
+ */
+
+static int32_t
+wv_read_bytes(void *id, void *data, int32_t bcount)
+{
+ return ((VFSFile *) id)->fread (data, 1, bcount);
+}
+
+static uint32_t
+wv_get_pos(void *id)
+{
+ return aud::clamp (((VFSFile *) id)->ftell (), (int64_t) 0, (int64_t) 0xffffffff);
+}
+
+static int
+wv_set_pos_abs(void *id, uint32_t pos)
+{
+ return ((VFSFile *) id)->fseek (pos, VFS_SEEK_SET);
+}
+
+static int
+wv_set_pos_rel(void *id, int32_t delta, int mode)
+{
+ return ((VFSFile *) id)->fseek (delta, to_vfs_seek_type(mode));
+}
+
+static int
+wv_push_back_byte(void *id, int c)
+{
+ return (((VFSFile *) id)->fseek (-1, VFS_SEEK_CUR) == 0) ? c : -1;
+}
+
+static uint32_t
+wv_get_length(void *id)
+{
+ return aud::clamp (((VFSFile *) id)->fsize (), (int64_t) 0, (int64_t) 0xffffffff);
+}
+
+static int wv_can_seek(void *id)
+{
+ return (((VFSFile *) id)->fsize () >= 0);
+}
+
+static int32_t wv_write_bytes(void *id, void *data, int32_t bcount)
+{
+ return ((VFSFile *) id)->fwrite (data, 1, bcount);
+}
+
+WavpackStreamReader wv_readers = {
+ wv_read_bytes,
+ wv_get_pos,
+ wv_set_pos_abs,
+ wv_set_pos_rel,
+ wv_push_back_byte,
+ wv_get_length,
+ wv_can_seek,
+ wv_write_bytes
+};
+
+static bool wv_attach (const char * filename, VFSFile & wv_input,
+ VFSFile & wvc_input, WavpackContext * * ctx, char * error, int flags)
+{
+ if (flags & OPEN_WVC)
+ {
+ StringBuf corrFilename = str_concat ({filename, "c"});
+ if (VFSFile::test_file (corrFilename, VFS_IS_REGULAR))
+ wvc_input = VFSFile (corrFilename, "r");
+ }
+
+ * ctx = WavpackOpenFileInputEx (& wv_readers, & wv_input, & wvc_input, error, flags, 0);
+ return (* ctx != nullptr);
+}
+
+static void wv_deattach (WavpackContext * ctx)
+{
+ WavpackCloseFile(ctx);
+}
+
+bool WavpackPlugin::play (const char * filename, VFSFile & file)
+{
+ int sample_rate, num_channels, bits_per_sample;
+ unsigned num_samples;
+ WavpackContext *ctx = nullptr;
+ VFSFile wvc_input;
+
+ if (! wv_attach (filename, file, wvc_input, & ctx, nullptr, OPEN_TAGS | OPEN_WVC))
+ {
+ AUDERR ("Error opening Wavpack file '%s'.", filename);
+ return false;
+ }
+
+ sample_rate = WavpackGetSampleRate(ctx);
+ num_channels = WavpackGetNumChannels(ctx);
+ bits_per_sample = WavpackGetBitsPerSample(ctx);
+ num_samples = WavpackGetNumSamples(ctx);
+
+ set_stream_bitrate(WavpackGetAverageBitrate(ctx, num_channels));
+ open_audio(SAMPLE_FMT(bits_per_sample), sample_rate, num_channels);
+
+ Index<int32_t> input;
+ input.resize (BUFFER_SIZE * num_channels);
+
+ Index<char> output;
+ output.resize (BUFFER_SIZE * num_channels * SAMPLE_SIZE (bits_per_sample));
+
+ while (! check_stop ())
+ {
+ int seek_value = check_seek ();
+ if (seek_value >= 0)
+ WavpackSeekSample (ctx, (int64_t) seek_value * sample_rate / 1000);
+
+ /* Decode audio data */
+ unsigned samples_left = num_samples - WavpackGetSampleIndex(ctx);
+
+ if (samples_left == 0)
+ break;
+
+ int ret = WavpackUnpackSamples (ctx, input.begin (), BUFFER_SIZE);
+
+ if (ret < 0)
+ {
+ AUDERR ("Error decoding file.\n");
+ break;
+ }
+ else
+ {
+ /* Perform audio data conversion and output */
+ int32_t * rp = input.begin ();
+ int8_t * wp = (int8_t *) output.begin ();
+ int16_t * wp2 = (int16_t *) output.begin ();
+ int32_t * wp4 = (int32_t *) output.begin ();
+
+ if (bits_per_sample == 8)
+ {
+ for (int i = 0; i < ret * num_channels; i++, wp++, rp++)
+ *wp = *rp & 0xff;
+ }
+ else if (bits_per_sample == 16)
+ {
+ for (int i = 0; i < ret * num_channels; i++, wp2++, rp++)
+ *wp2 = *rp & 0xffff;
+ }
+ else if (bits_per_sample == 24 || bits_per_sample == 32)
+ {
+ for (int i = 0; i < ret * num_channels; i++, wp4++, rp++)
+ *wp4 = *rp;
+ }
+
+ write_audio (output.begin (),
+ ret * num_channels * SAMPLE_SIZE (bits_per_sample));
+ }
+ }
+
+ wv_deattach (ctx);
+ return true;
+}
+
+static StringBuf
+wv_get_quality(WavpackContext *ctx)
+{
+ int mode = WavpackGetMode(ctx);
+ const char *quality;
+
+ if (mode & MODE_LOSSLESS)
+ quality = _("lossless");
+ else if (mode & MODE_HYBRID)
+ quality = _("lossy (hybrid)");
+ else
+ quality = _("lossy");
+
+ return str_concat ({quality, (mode & MODE_WVC) ? " (wvc corrected)" : "",
+ (mode & MODE_DNS) ? " (dynamic noise shaped)" : ""});
+}
+
+Tuple WavpackPlugin::read_tuple (const char * filename, VFSFile & file)
+{
+ WavpackContext *ctx;
+ Tuple tuple;
+ char error[1024];
+
+ ctx = WavpackOpenFileInputEx(&wv_readers, &file, nullptr, error, OPEN_TAGS, 0);
+
+ if (ctx == nullptr)
+ return tuple;
+
+ AUDDBG("starting probe of %s\n", file.filename ());
+
+ tuple.set_filename (filename);
+
+ tuple.set_int (Tuple::Length,
+ ((uint64_t) WavpackGetNumSamples(ctx) * 1000) / (uint64_t) WavpackGetSampleRate(ctx));
+ tuple.set_str (Tuple::Codec, "WavPack");
+
+ tuple.set_str (Tuple::Quality, wv_get_quality (ctx));
+
+ WavpackCloseFile(ctx);
+
+ if (! file.fseek (0, VFS_SEEK_SET))
+ audtag::tuple_read (tuple, file);
+
+ AUDDBG("returning tuple for file %s\n", file.filename ());
+ return tuple;
+}
+
+bool WavpackPlugin::write_tuple (const char * filename, VFSFile & handle, const Tuple & tuple)
+{
+ return audtag::tuple_write(tuple, handle, audtag::TagType::APE);
+}
+
+const char WavpackPlugin::about[] =
+ N_("Copyright 2006 William Pitcock <nenolod at nenolod.net>\n\n"
+ "Some of the plugin code was by Miles Egan.");
+
+const char * const WavpackPlugin::exts[] = { "wv", nullptr };
diff --git a/src/xsf/Makefile b/src/xsf/Makefile
index a09708296df7..60b552370509 100644
--- a/src/xsf/Makefile
+++ b/src/xsf/Makefile
@@ -1,16 +1,18 @@
PLUGIN = xsf${PLUGIN_SUFFIX}
-SRCS = corlett.c \
- plugin.c \
- vio2sf.c \
- desmume/armcpu.c desmume/bios.c desmume/FIFO.c desmume/matrix.c desmume/MMU.c desmume/SPU.c \
- desmume/arm_instructions.c desmume/cp15.c desmume/GPU.c desmume/mc.c desmume/NDSSystem.c desmume/thumb_instructions.c \
+SRCS = corlett.cc \
+ plugin.cc \
+ vio2sf.cc \
+ desmume/armcpu.cc desmume/bios.cc desmume/FIFO.cc desmume/matrix.cc desmume/MMU.cc desmume/SPU.cc \
+ desmume/arm_instructions.cc desmume/cp15.cc desmume/GPU.cc desmume/mc.cc desmume/NDSSystem.cc desmume/thumb_instructions.cc \
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${INPUT_PLUGIN_DIR}
-CFLAGS += ${PLUGIN_CFLAGS} -O0
-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} -I../.. -Ispu/
-LIBS += -lm -lz ${GLIB_LIBS}
+LD = ${CXX}
+
+CXXFLAGS += ${PLUGIN_CFLAGS} -Wno-sign-compare
+CPPFLAGS += ${PLUGIN_CPPFLAGS} -I../.. -Ispu/
+LIBS += -lm -lz
diff --git a/src/xsf/corlett.c b/src/xsf/corlett.c
deleted file mode 100644
index 50ee0763e66f..000000000000
--- a/src/xsf/corlett.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
-
- Audio Overload SDK
-
- Copyright (c) 2007-2008, R. Belmont and Richard Bannister.
-
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-// corlett.c
-
-// Decodes file format designed by Neill Corlett (PSF, QSF, ...)
-
-/*
- - First 3 bytes: ASCII signature: "PSF" (case sensitive)
-
-- Next 1 byte: Version byte
- The version byte is used to determine the type of PSF file. It does NOT
- affect the basic structure of the file in any way.
-
- Currently accepted version bytes are:
- 0x01: Playstation (PSF1)
- 0x02: Playstation 2 (PSF2)
- 0x11: Saturn (SSF) [TENTATIVE]
- 0x12: Dreamcast (DSF) [TENTATIVE]
- 0x21: Nintendo 64 (USF) [RESERVED]
- 0x41: Capcom QSound (QSF)
-
-- Next 4 bytes: Size of reserved area (R), little-endian unsigned long
-
-- Next 4 bytes: Compressed program length (N), little-endian unsigned long
- This is the length of the program data _after_ compression.
-
-- Next 4 bytes: Compressed program CRC-32, little-endian unsigned long
- This is the CRC-32 of the program data _after_ compression. Filling in
- this value is mandatory, as a PSF file may be regarded as corrupt if it
- does not match.
-
-- Next R bytes: Reserved area.
- May be empty if R is 0 bytes.
-
-- Next N bytes: Compressed program, in zlib compress() format.
- May be empty if N is 0 bytes.
-
-The following data is optional and may be omitted:
-
-- Next 5 bytes: ASCII signature: "[TAG]" (case sensitive)
- If these 5 bytes do not match, then the remainder of the file may be
- regarded as invalid and discarded.
-
-- Remainder of file: Uncompressed ASCII tag data.
-*/
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-#include <zlib.h>
-
-#include "ao.h"
-#include "corlett.h"
-
-#define LE32(x) GUINT32_FROM_LE(x)
-
-#define DECOMP_MAX_SIZE ((32 * 1024 * 1024) + 12)
-
-int corlett_decode(uint8_t *input, uint32_t input_len, uint8_t **output, uint64_t *size, corlett_t **c)
-{
- uint32_t *buf;
- uint32_t res_area, comp_crc, actual_crc;
- uint8_t *decomp_dat, *tag_dec;
- uLongf decomp_length, comp_length;
-
- // 32-bit pointer to data
- buf = (uint32_t *)input;
-
- // Check we have a PSF format file.
- if ((input[0] != 'P') || (input[1] != 'S') || (input[2] != 'F'))
- {
- return AO_FAIL;
- }
-
- // Get our values
- res_area = LE32(buf[1]);
- comp_length = LE32(buf[2]);
- comp_crc = LE32(buf[3]);
-
- if (comp_length > 0)
- {
- // Check length
- if (input_len < comp_length + 16)
- return AO_FAIL;
-
- // Check CRC is correct
- actual_crc = crc32(0, (unsigned char *)&buf[4+(res_area/4)], comp_length);
- if (actual_crc != comp_crc)
- return AO_FAIL;
-
- // Decompress data if any
- decomp_dat = malloc(DECOMP_MAX_SIZE);
- decomp_length = DECOMP_MAX_SIZE;
- if (uncompress(decomp_dat, &decomp_length, (unsigned char *)&buf[4+(res_area/4)], comp_length) != Z_OK)
- {
- free(decomp_dat);
- return AO_FAIL;
- }
-
- // Resize memory buffer to what we actually need
- decomp_dat = realloc(decomp_dat, (size_t)decomp_length + 1);
- }
- else
- {
- decomp_dat = NULL;
- decomp_length = 0;
- }
-
- // Make structure
- *c = malloc(sizeof(corlett_t));
- if (!(*c))
- {
- free(decomp_dat);
- return AO_FAIL;
- }
- memset(*c, 0, sizeof(corlett_t));
- strcpy((*c)->inf_title, "n/a");
- strcpy((*c)->inf_copy, "n/a");
- strcpy((*c)->inf_artist, "n/a");
- strcpy((*c)->inf_game, "n/a");
- strcpy((*c)->inf_year, "n/a");
- strcpy((*c)->inf_length, "n/a");
- strcpy((*c)->inf_fade, "n/a");
-
- // set reserved section pointer
- (*c)->res_section = &buf[4];
- (*c)->res_size = res_area;
-
- // Return it
- if (output != NULL && size != NULL)
- {
- *output = decomp_dat;
- *size = decomp_length;
- }
- else
- free(decomp_dat);
-
- // Next check for tags
- input_len -= (comp_length + 16 + res_area);
- if (input_len < 5)
- return AO_SUCCESS;
-
-// printf("\n\nNew corlett: input len %d comp length %d res area %d\n", input_len, comp_length, res_area);
-
- tag_dec = input + (comp_length + res_area + 16);
- if ((tag_dec[0] == '[') && (tag_dec[1] == 'T') && (tag_dec[2] == 'A') && (tag_dec[3] == 'G') && (tag_dec[4] == ']'))
- {
- int l, num_tags, data;
-
- // Tags found!
- tag_dec += 5;
- input_len -= 5;
-
- data = FALSE;
- num_tags = 0;
- l = 0;
- while (input_len && (num_tags < MAX_UNKNOWN_TAGS))
- {
- if (data)
- {
- if ((*tag_dec == 0xA) || (*tag_dec == 0x00))
- {
- (*c)->tag_data[num_tags][l] = 0;
- data = FALSE;
- num_tags++;
- l = 0;
- }
- else
- {
- (*c)->tag_data[num_tags][l++] = *tag_dec;
- }
- }
- else
- {
- if (*tag_dec == '=')
- {
- (*c)->tag_name[num_tags][l] = 0;
- l = 0;
- data = TRUE;
- }
- else
- {
- (*c)->tag_name[num_tags][l++] = *tag_dec;
- }
- }
-
- tag_dec++;
- input_len--;
- }
-
-
- // Now, process that tag array into what we expect
- for (num_tags = 0; num_tags < MAX_UNKNOWN_TAGS; num_tags++)
- {
- // See if tag belongs in one of the special fields we have
- if (!g_ascii_strcasecmp((*c)->tag_name[num_tags], "_lib"))
- {
- strcpy((*c)->lib, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib2", 5))
- {
- strcpy((*c)->libaux[0], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib3", 5))
- {
- strcpy((*c)->libaux[1], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib4", 5))
- {
- strcpy((*c)->libaux[2], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib5", 5))
- {
- strcpy((*c)->libaux[3], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib6", 5))
- {
- strcpy((*c)->libaux[4], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib7", 5))
- {
- strcpy((*c)->libaux[5], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib8", 5))
- {
- strcpy((*c)->libaux[6], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_lib9", 5))
- {
- strcpy((*c)->libaux[7], (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "_refresh", 8))
- {
- strcpy((*c)->inf_refresh, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "title", 5))
- {
- strcpy((*c)->inf_title, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "copyright", 9))
- {
- strcpy((*c)->inf_copy, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "artist", 6))
- {
- strcpy((*c)->inf_artist, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "game", 4))
- {
- strcpy((*c)->inf_game, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "year", 4))
- {
- strcpy((*c)->inf_year, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "length", 6))
- {
- strcpy((*c)->inf_length, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- else if (!strncmp((*c)->tag_name[num_tags], "fade", 4))
- {
- strcpy((*c)->inf_fade, (*c)->tag_data[num_tags]);
- (*c)->tag_data[num_tags][0] = 0;
- (*c)->tag_name[num_tags][0] = 0;
- }
- }
- }
-
- // Bingo
- return AO_SUCCESS;
-}
-
-uint32_t psfTimeToMS(char *str)
-{
- int x, c=0;
- uint32_t acc=0;
- char s[100];
-
- strncpy(s,str,100);
- s[99]=0;
-
- for (x=strlen(s); x>=0; x--)
- {
- if (s[x]=='.' || s[x]==',')
- {
- acc=atoi(s+x+1);
- s[x]=0;
- }
- else if (s[x]==':')
- {
- if(c==0)
- {
- acc+=atoi(s+x+1)*10;
- }
- else if(c==1)
- {
- acc+=atoi(s+x+(x?1:0))*10*60;
- }
-
- c++;
- s[x]=0;
- }
- else if (x==0)
- {
- if(c==0)
- {
- acc+=atoi(s+x)*10;
- }
- else if(c==1)
- {
- acc+=atoi(s+x)*10*60;
- }
- else if(c==2)
- {
- acc+=atoi(s+x)*10*60*60;
- }
- }
- }
-
- acc*=100;
- return(acc);
-}
-
diff --git a/src/xsf/corlett.cc b/src/xsf/corlett.cc
new file mode 100644
index 000000000000..a7694d5ecdda
--- /dev/null
+++ b/src/xsf/corlett.cc
@@ -0,0 +1,385 @@
+/*
+
+ Audio Overload SDK
+
+ Copyright (c) 2007-2008, R. Belmont and Richard Bannister.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// corlett.c
+
+// Decodes file format designed by Neill Corlett (PSF, QSF, ...)
+
+/*
+ - First 3 bytes: ASCII signature: "PSF" (case sensitive)
+
+- Next 1 byte: Version byte
+ The version byte is used to determine the type of PSF file. It does NOT
+ affect the basic structure of the file in any way.
+
+ Currently accepted version bytes are:
+ 0x01: Playstation (PSF1)
+ 0x02: Playstation 2 (PSF2)
+ 0x11: Saturn (SSF) [TENTATIVE]
+ 0x12: Dreamcast (DSF) [TENTATIVE]
+ 0x21: Nintendo 64 (USF) [RESERVED]
+ 0x41: Capcom QSound (QSF)
+
+- Next 4 bytes: Size of reserved area (R), little-endian unsigned long
+
+- Next 4 bytes: Compressed program length (N), little-endian unsigned long
+ This is the length of the program data _after_ compression.
+
+- Next 4 bytes: Compressed program CRC-32, little-endian unsigned long
+ This is the CRC-32 of the program data _after_ compression. Filling in
+ this value is mandatory, as a PSF file may be regarded as corrupt if it
+ does not match.
+
+- Next R bytes: Reserved area.
+ May be empty if R is 0 bytes.
+
+- Next N bytes: Compressed program, in zlib compress() format.
+ May be empty if N is 0 bytes.
+
+The following data is optional and may be omitted:
+
+- Next 5 bytes: ASCII signature: "[TAG]" (case sensitive)
+ If these 5 bytes do not match, then the remainder of the file may be
+ regarded as invalid and discarded.
+
+- Remainder of file: Uncompressed ASCII tag data.
+*/
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <zlib.h>
+
+#define WANT_AUD_BSWAP
+#include <libaudcore/audio.h>
+#include <libaudcore/audstrings.h>
+
+#include "ao.h"
+#include "corlett.h"
+
+#define LE32(x) FROM_LE32(x)
+
+#define DECOMP_MAX_SIZE ((32 * 1024 * 1024) + 12)
+
+int corlett_decode(uint8_t *input, uint32_t input_len, uint8_t **output, uint64_t *size, corlett_t **c)
+{
+ uint32_t *buf;
+ uint32_t res_area, comp_crc, actual_crc;
+ uint8_t *decomp_dat, *tag_dec;
+ uLongf decomp_length, comp_length;
+
+ // 32-bit pointer to data
+ buf = (uint32_t *)input;
+
+ // Check we have a PSF format file.
+ if ((input[0] != 'P') || (input[1] != 'S') || (input[2] != 'F'))
+ {
+ return AO_FAIL;
+ }
+
+ // Get our values
+ res_area = LE32(buf[1]);
+ comp_length = LE32(buf[2]);
+ comp_crc = LE32(buf[3]);
+
+ if (comp_length > 0)
+ {
+ // Check length
+ if (input_len < comp_length + 16)
+ return AO_FAIL;
+
+ // Check CRC is correct
+ actual_crc = crc32(0, (unsigned char *)&buf[4+(res_area/4)], comp_length);
+ if (actual_crc != comp_crc)
+ return AO_FAIL;
+
+ // Decompress data if any
+ decomp_dat = (uint8_t *) malloc(DECOMP_MAX_SIZE);
+ decomp_length = DECOMP_MAX_SIZE;
+ if (uncompress(decomp_dat, &decomp_length, (unsigned char *)&buf[4+(res_area/4)], comp_length) != Z_OK)
+ {
+ free(decomp_dat);
+ return AO_FAIL;
+ }
+
+ // Resize memory buffer to what we actually need
+ decomp_dat = (uint8_t *) realloc(decomp_dat, (size_t)decomp_length + 1);
+ }
+ else
+ {
+ decomp_dat = nullptr;
+ decomp_length = 0;
+ }
+
+ // Make structure
+ *c = (corlett_t *) malloc(sizeof(corlett_t));
+ if (!(*c))
+ {
+ free(decomp_dat);
+ return AO_FAIL;
+ }
+ memset(*c, 0, sizeof(corlett_t));
+ strcpy((*c)->inf_title, "n/a");
+ strcpy((*c)->inf_copy, "n/a");
+ strcpy((*c)->inf_artist, "n/a");
+ strcpy((*c)->inf_game, "n/a");
+ strcpy((*c)->inf_year, "n/a");
+ strcpy((*c)->inf_length, "n/a");
+ strcpy((*c)->inf_fade, "n/a");
+
+ // set reserved section pointer
+ (*c)->res_section = &buf[4];
+ (*c)->res_size = res_area;
+
+ // Return it
+ if (output != nullptr && size != nullptr)
+ {
+ *output = decomp_dat;
+ *size = decomp_length;
+ }
+ else
+ free(decomp_dat);
+
+ // Next check for tags
+ input_len -= (comp_length + 16 + res_area);
+ if (input_len < 5)
+ return AO_SUCCESS;
+
+// printf("\n\nNew corlett: input len %d comp length %d res area %d\n", input_len, comp_length, res_area);
+
+ tag_dec = input + (comp_length + res_area + 16);
+ if ((tag_dec[0] == '[') && (tag_dec[1] == 'T') && (tag_dec[2] == 'A') && (tag_dec[3] == 'G') && (tag_dec[4] == ']'))
+ {
+ int l, num_tags, data;
+
+ // Tags found!
+ tag_dec += 5;
+ input_len -= 5;
+
+ data = false;
+ num_tags = 0;
+ l = 0;
+ while (input_len && (num_tags < MAX_UNKNOWN_TAGS))
+ {
+ if (data)
+ {
+ if ((*tag_dec == 0xA) || (*tag_dec == 0x00))
+ {
+ (*c)->tag_data[num_tags][l] = 0;
+ data = false;
+ num_tags++;
+ l = 0;
+ }
+ else
+ {
+ (*c)->tag_data[num_tags][l++] = *tag_dec;
+ }
+ }
+ else
+ {
+ if (*tag_dec == '=')
+ {
+ (*c)->tag_name[num_tags][l] = 0;
+ l = 0;
+ data = true;
+ }
+ else
+ {
+ (*c)->tag_name[num_tags][l++] = *tag_dec;
+ }
+ }
+
+ tag_dec++;
+ input_len--;
+ }
+
+
+ // Now, process that tag array into what we expect
+ for (num_tags = 0; num_tags < MAX_UNKNOWN_TAGS; num_tags++)
+ {
+ // See if tag belongs in one of the special fields we have
+ if (!strcmp_nocase((*c)->tag_name[num_tags], "_lib"))
+ {
+ strcpy((*c)->lib, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib2", 5))
+ {
+ strcpy((*c)->libaux[0], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib3", 5))
+ {
+ strcpy((*c)->libaux[1], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib4", 5))
+ {
+ strcpy((*c)->libaux[2], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib5", 5))
+ {
+ strcpy((*c)->libaux[3], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib6", 5))
+ {
+ strcpy((*c)->libaux[4], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib7", 5))
+ {
+ strcpy((*c)->libaux[5], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib8", 5))
+ {
+ strcpy((*c)->libaux[6], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_lib9", 5))
+ {
+ strcpy((*c)->libaux[7], (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "_refresh", 8))
+ {
+ strcpy((*c)->inf_refresh, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "title", 5))
+ {
+ strcpy((*c)->inf_title, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "copyright", 9))
+ {
+ strcpy((*c)->inf_copy, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "artist", 6))
+ {
+ strcpy((*c)->inf_artist, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "game", 4))
+ {
+ strcpy((*c)->inf_game, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "year", 4))
+ {
+ strcpy((*c)->inf_year, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "length", 6))
+ {
+ strcpy((*c)->inf_length, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ else if (!strncmp((*c)->tag_name[num_tags], "fade", 4))
+ {
+ strcpy((*c)->inf_fade, (*c)->tag_data[num_tags]);
+ (*c)->tag_data[num_tags][0] = 0;
+ (*c)->tag_name[num_tags][0] = 0;
+ }
+ }
+ }
+
+ // Bingo
+ return AO_SUCCESS;
+}
+
+uint32_t psfTimeToMS(char *str)
+{
+ int x, c=0;
+ uint32_t acc=0;
+ char s[100];
+
+ strncpy(s,str,100);
+ s[99]=0;
+
+ for (x=strlen(s); x>=0; x--)
+ {
+ if (s[x]=='.' || s[x]==',')
+ {
+ acc=atoi(s+x+1);
+ s[x]=0;
+ }
+ else if (s[x]==':')
+ {
+ if(c==0)
+ {
+ acc+=atoi(s+x+1)*10;
+ }
+ else if(c==1)
+ {
+ acc+=atoi(s+x+(x?1:0))*10*60;
+ }
+
+ c++;
+ s[x]=0;
+ }
+ else if (x==0)
+ {
+ if(c==0)
+ {
+ acc+=atoi(s+x)*10;
+ }
+ else if(c==1)
+ {
+ acc+=atoi(s+x)*10*60;
+ }
+ else if(c==2)
+ {
+ acc+=atoi(s+x)*10*60*60;
+ }
+ }
+ }
+
+ acc*=100;
+ return(acc);
+}
+
diff --git a/src/xsf/desmume/COPYING b/src/xsf/desmume/COPYING
index d60c31a97a54..623b6258a134 100644
--- a/src/xsf/desmume/COPYING
+++ b/src/xsf/desmume/COPYING
@@ -2,7 +2,7 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -305,7 +305,7 @@ the "copyright" line and a pointer to where the full notice is found.
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
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
diff --git a/src/xsf/desmume/FIFO.c b/src/xsf/desmume/FIFO.c
deleted file mode 100644
index c86017f711ef..000000000000
--- a/src/xsf/desmume/FIFO.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (C) 2006 yopyop
- yopyop156 at ifrance.com
- yopyop156.ifrance.com
-
- Copyright (C) 2007 shash
-
- This file is part of DeSmuME
-
- DeSmuME 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.
-
- DeSmuME 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 DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include "FIFO.h"
-
-void FIFOInit(FIFO * fifo)
-{
- u32 i;
-
- fifo->begin = 0;
- fifo->end = 0;
- for(i = 0; i<0x8000; ++i)
- fifo->data[i] = 0;
- fifo->full = FALSE;
- fifo->empty = TRUE;
- fifo->error = FALSE;
-}
-
-void FIFOAdd(FIFO * fifo, u32 v)
-{
- if(fifo->full)
- {
- fifo->error = TRUE;
- return;
- }
- fifo->data[fifo->end] = v;
- fifo->end = (fifo->end + 1)& 0x7FFF;
- fifo->full = (fifo->end == fifo->begin);
- fifo->empty = FALSE;
-}
-
-u32 FIFOValue(FIFO * fifo)
-{
- u32 v;
-
- if(fifo->empty)
- {
- fifo->error = TRUE;
- return 0;
- }
- v = fifo->data[fifo->begin];
- fifo->begin = (fifo->begin + 1)& 0x7FFF;
- fifo->empty = (fifo->begin == fifo->end);
- return v;
-}
diff --git a/src/xsf/desmume/FIFO.cc b/src/xsf/desmume/FIFO.cc
new file mode 100644
index 000000000000..09d6fb6e2462
--- /dev/null
+++ b/src/xsf/desmume/FIFO.cc
@@ -0,0 +1,65 @@
+/* Copyright (C) 2006 yopyop
+ yopyop156 at ifrance.com
+ yopyop156.ifrance.com
+
+ Copyright (C) 2007 shash
+
+ This file is part of DeSmuME
+
+ DeSmuME 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.
+
+ DeSmuME 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 DeSmuME; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "FIFO.h"
+
+void FIFOInit(FIFO * fifo)
+{
+ u32 i;
+
+ fifo->begin = 0;
+ fifo->end = 0;
+ for(i = 0; i<0x8000; ++i)
+ fifo->data[i] = 0;
+ fifo->full = false;
+ fifo->empty = true;
+ fifo->error = false;
+}
+
+void FIFOAdd(FIFO * fifo, u32 v)
+{
+ if(fifo->full)
+ {
+ fifo->error = true;
+ return;
+ }
+ fifo->data[fifo->end] = v;
+ fifo->end = (fifo->end + 1)& 0x7FFF;
+ fifo->full = (fifo->end == fifo->begin);
+ fifo->empty = false;
+}
+
+u32 FIFOValue(FIFO * fifo)
+{
+ u32 v;
+
+ if(fifo->empty)
+ {
+ fifo->error = true;
+ return 0;
+ }
+ v = fifo->data[fifo->begin];
+ fifo->begin = (fifo->begin + 1)& 0x7FFF;
+ fifo->empty = (fifo->begin == fifo->end);
+ return v;
+}
diff --git a/src/xsf/desmume/FIFO.h b/src/xsf/desmume/FIFO.h
index 86e282902260..c9ba28991e96 100644
--- a/src/xsf/desmume/FIFO.h
+++ b/src/xsf/desmume/FIFO.h
@@ -18,7 +18,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FIFO_H
@@ -26,10 +26,6 @@
#include "types.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef struct
{
u32 data[0x8000];
@@ -44,8 +40,4 @@ void FIFOInit(FIFO * fifo);
void FIFOAdd(FIFO * fifo, u32 v);
u32 FIFOValue(FIFO * fifo);
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/src/xsf/desmume/GPU.c b/src/xsf/desmume/GPU.c
deleted file mode 100644
index 4dcfe6c3996b..000000000000
--- a/src/xsf/desmume/GPU.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Copyright (C) 2006 yopyop
- yopyop156 at ifrance.com
- yopyop156.ifrance.com
-
- Copyright (C) 2006-2007 Theo Berkau
- Copyright (C) 2007 shash
-
- This file is part of DeSmuME
-
- DeSmuME 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.
-
- DeSmuME 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 DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-// CONTENTS
-// INITIALIZATION
-// ENABLING / DISABLING LAYERS
-// PARAMETERS OF BACKGROUNDS
-// PARAMETERS OF ROTOSCALE
-// PARAMETERS OF EFFECTS
-// PARAMETERS OF WINDOWS
-// ROUTINES FOR INSIDE / OUTSIDE WINDOW CHECKS
-// PIXEL RENDERING
-// BACKGROUND RENDERING -TEXT-
-// BACKGROUND RENDERING -ROTOSCALE-
-// BACKGROUND RENDERING -HELPER FUNCTIONS-
-// SPRITE RENDERING -HELPER FUNCTIONS-
-// SPRITE RENDERING
-// SCREEN FUNCTIONS
-// GRAPHICS CORE
-// GPU_ligne
-
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include "MMU.h"
-#include "GPU.h"
-
-ARM9_struct ARM9Mem;
-
-NDS_Screen MainScreen;
-NDS_Screen SubScreen;
-
-//#define DEBUG_TRI
-
-/*****************************************************************************/
-// INITIALIZATION
-/*****************************************************************************/
-
-GPU * GPU_Init(u8 l)
-{
- GPU * g;
-
- if ((g = (GPU *) malloc(sizeof(GPU))) == NULL)
- return NULL;
-
- GPU_Reset(g, l);
- return g;
-}
-
-void GPU_Reset(GPU *g, u8 l)
-{
- memset(g, 0, sizeof(GPU));
-}
-
-void GPU_DeInit(GPU * gpu)
-{
- if (gpu) free(gpu);
-}
-
-
-int Screen_Init(int coreid) {
- MainScreen.gpu = GPU_Init(0);
- SubScreen.gpu = GPU_Init(1);
-
- return 0;
-}
-
-void Screen_Reset(void) {
- GPU_Reset(MainScreen.gpu, 0);
- GPU_Reset(SubScreen.gpu, 1);
-}
-
-void Screen_DeInit(void) {
- GPU_DeInit(MainScreen.gpu);
- GPU_DeInit(SubScreen.gpu);
-
-}
diff --git a/src/xsf/desmume/GPU.cc b/src/xsf/desmume/GPU.cc
new file mode 100644
index 000000000000..4ab8f5907452
--- /dev/null
+++ b/src/xsf/desmume/GPU.cc
@@ -0,0 +1,98 @@
+/* Copyright (C) 2006 yopyop
+ yopyop156 at ifrance.com
+ yopyop156.ifrance.com
+
+ Copyright (C) 2006-2007 Theo Berkau
+ Copyright (C) 2007 shash
+
+ This file is part of DeSmuME
+
+ DeSmuME 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.
+
+ DeSmuME 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 DeSmuME; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+// CONTENTS
+// INITIALIZATION
+// ENABLING / DISABLING LAYERS
+// PARAMETERS OF BACKGROUNDS
+// PARAMETERS OF ROTOSCALE
+// PARAMETERS OF EFFECTS
+// PARAMETERS OF WINDOWS
+// ROUTINES FOR INSIDE / OUTSIDE WINDOW CHECKS
+// PIXEL RENDERING
+// BACKGROUND RENDERING -TEXT-
+// BACKGROUND RENDERING -ROTOSCALE-
+// BACKGROUND RENDERING -HELPER FUNCTIONS-
+// SPRITE RENDERING -HELPER FUNCTIONS-
+// SPRITE RENDERING
+// SCREEN FUNCTIONS
+// GRAPHICS CORE
+// GPU_ligne
+
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "MMU.h"
+#include "GPU.h"
+
+ARM9_struct ARM9Mem;
+
+NDS_Screen MainScreen;
+NDS_Screen SubScreen;
+
+//#define DEBUG_TRI
+
+/*****************************************************************************/
+// INITIALIZATION
+/*****************************************************************************/
+
+GPU * GPU_Init(u8 l)
+{
+ GPU * g;
+
+ if ((g = (GPU *) malloc(sizeof(GPU))) == nullptr)
+ return nullptr;
+
+ GPU_Reset(g, l);
+ return g;
+}
+
+void GPU_Reset(GPU *g, u8 l)
+{
+ memset(g, 0, sizeof(GPU));
+}
+
+void GPU_DeInit(GPU * gpu)
+{
+ if (gpu) free(gpu);
+}
+
+
+int Screen_Init(int coreid) {
+ MainScreen.gpu = GPU_Init(0);
+ SubScreen.gpu = GPU_Init(1);
+
+ return 0;
+}
+
+void Screen_Reset(void) {
+ GPU_Reset(MainScreen.gpu, 0);
+ GPU_Reset(SubScreen.gpu, 1);
+}
+
+void Screen_DeInit(void) {
+ GPU_DeInit(MainScreen.gpu);
+ GPU_DeInit(SubScreen.gpu);
+
+}
diff --git a/src/xsf/desmume/GPU.h b/src/xsf/desmume/GPU.h
index ac89d95434a5..423cf85dbe6f 100644
--- a/src/xsf/desmume/GPU.h
+++ b/src/xsf/desmume/GPU.h
@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef GPU_H
@@ -32,11 +32,6 @@
#include "FIFO.h"
#include "MMU.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
/*******************************************************************************
this structure is for display control,
it holds flags for general display
@@ -394,7 +389,7 @@ typedef struct _reg_dispx {
-
+#ifndef __cplusplus
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
@@ -402,6 +397,7 @@ typedef struct _reg_dispx {
#ifndef max
#define max(a,b) (((a)>(b))?(a):(b))
#endif
+#endif
typedef BOOL (*fun_gl_Begin) (int screen);
typedef void (*fun_gl_End) (int screen);
@@ -547,7 +543,7 @@ typedef struct
/*12*/ unsigned PaletteIndex:4;
/*10*/ unsigned Priority:2;
// attr3
-unsigned attr3:16;
+unsigned attr3:16;
#else
// attr0
/* 0*/ unsigned Y:8;
@@ -805,9 +801,5 @@ void GPU_setBLDALPHA_EVB(GPU *gpu, u8 val);
void GPU_setBLDY_EVY (GPU *gpu, u8 val);
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/src/xsf/desmume/MMU.c b/src/xsf/desmume/MMU.c
deleted file mode 100644
index 36677d774f68..000000000000
--- a/src/xsf/desmume/MMU.c
+++ /dev/null
@@ -1,3565 +0,0 @@
-/* Copyright (C) 2006 yopyop
- yopyop156 at ifrance.com
- yopyop156.ifrance.com
-
- Copyright (C) 2007 shash
-
- This file is part of DeSmuME
-
- DeSmuME 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.
-
- DeSmuME 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 DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-//#define RENDER3D
-
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-
-//#include "gl_vertex.h"
-
-#include "debug.h"
-#include "NDSSystem.h"
-//#include "cflash.h"
-#define cflash_read(a) 0
-#define cflash_write(a,d)
-#include "cp15.h"
-//#include "wifi.h"
-#include "registers.h"
-
-#if VIO2SF_GPU_ENABLE
-#include "render3D.h"
-#else
-#define GPU_setVideoProp(p1, p2)
-#define GPU_setBGProp(p1, p2, p3)
-
-#define GPU_setBLDCNT(p1, p2)
-#define GPU_setBLDALPHA(p1, p2)
-#define GPU_setBLDY(p1, p2)
-#define GPU_setMOSAIC(p1, p2)
-
-
-#define GPU_remove(p1,p2)
-#define GPU_addBack(p1,p2)
-
-#define GPU_ChangeGraphicsCore(p1) 0
-
-#define GPU_set_DISPCAPCNT(p1, p2)
-#define GPU_ligne(p1, p2)
-#define GPU_setMasterBrightness(p1, p2)
-
-#define GPU_setWIN0_H(p1, p2)
-#define GPU_setWIN0_H0(p1, p2)
-#define GPU_setWIN0_H1(p1, p2)
-
-#define GPU_setWIN0_V(p1, p2)
-#define GPU_setWIN0_V0(p1, p2)
-#define GPU_setWIN0_V1(p1, p2)
-
-#define GPU_setWIN1_H(p1, p2)
-#define GPU_setWIN1_H0(p1, p2)
-#define GPU_setWIN1_H1(p1, p2)
-
-#define GPU_setWIN1_V(p1, p2)
-#define GPU_setWIN1_V0(p1, p2)
-#define GPU_setWIN1_V1(p1, p2)
-
-#define GPU_setWININ(p1, p2)
-#define GPU_setWININ0(p1, p2)
-#define GPU_setWININ1(p1, p2)
-
-#define GPU_setWINOUT16(p1, p2)
-#define GPU_setWINOUT(p1, p2)
-#define GPU_setWINOBJ(p1, p2)
-
-#define GPU_setBLDCNT_LOW(p1, p2)
-#define GPU_setBLDCNT_HIGH(p1, p2)
-#define GPU_setBLDCNT(p1, p2)
-
-#define GPU_setBLDALPHA(p1, p2)
-#define GPU_setBLDALPHA_EVA(p1, p2)
-#define GPU_setBLDALPHA_EVB(p1, p2)
-
-#define GPU_setBLDY_EVY(p1, p2)
-#endif
-
-#define ROM_MASK 3
-
-/*
- *
- */
-//#define PROFILE_MEMORY_ACCESS 1
-#define EARLY_MEMORY_ACCESS 1
-
-#define INTERNAL_DTCM_READ 1
-#define INTERNAL_DTCM_WRITE 1
-
-//#define LOG_CARD
-//#define LOG_GPU
-//#define LOG_DMA
-//#define LOG_DMA2
-//#define LOG_DIV
-
-char szRomPath[512];
-char szRomBaseName[512];
-
-#define DUP2(x) x, x
-#define DUP4(x) x, x, x, x
-#define DUP8(x) x, x, x, x, x, x, x, x
-#define DUP16(x) x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x
-
-MMU_struct MMU;
-
-u8 * MMU_ARM9_MEM_MAP[256]={
-/* 0X*/ DUP16(ARM9Mem.ARM9_ITCM),
-/* 1X*/ //DUP16(ARM9Mem.ARM9_ITCM)
-/* 1X*/ DUP16(ARM9Mem.ARM9_WRAM),
-/* 2X*/ DUP16(ARM9Mem.MAIN_MEM),
-/* 3X*/ DUP16(MMU.SWIRAM),
-/* 4X*/ DUP16(ARM9Mem.ARM9_REG),
-/* 5X*/ DUP16(ARM9Mem.ARM9_VMEM),
-/* 6X*/ DUP2(ARM9Mem.ARM9_ABG),
- DUP2(ARM9Mem.ARM9_BBG),
- DUP2(ARM9Mem.ARM9_AOBJ),
- DUP2(ARM9Mem.ARM9_BOBJ),
- DUP8(ARM9Mem.ARM9_LCD),
-/* 7X*/ DUP16(ARM9Mem.ARM9_OAM),
-/* 8X*/ DUP16(NULL),
-/* 9X*/ DUP16(NULL),
-/* AX*/ DUP16(MMU.CART_RAM),
-/* BX*/ DUP16(MMU.UNUSED_RAM),
-/* CX*/ DUP16(MMU.UNUSED_RAM),
-/* DX*/ DUP16(MMU.UNUSED_RAM),
-/* EX*/ DUP16(MMU.UNUSED_RAM),
-/* FX*/ DUP16(ARM9Mem.ARM9_BIOS)
-};
-
-u32 MMU_ARM9_MEM_MASK[256]={
-/* 0X*/ DUP16(0x00007FFF),
-/* 1X*/ //DUP16(0x00007FFF)
-/* 1X*/ DUP16(0x00FFFFFF),
-/* 2X*/ DUP16(0x003FFFFF),
-/* 3X*/ DUP16(0x00007FFF),
-/* 4X*/ DUP16(0x00FFFFFF),
-/* 5X*/ DUP16(0x000007FF),
-/* 6X*/ DUP2(0x0007FFFF),
- DUP2(0x0001FFFF),
- DUP2(0x0003FFFF),
- DUP2(0x0001FFFF),
- DUP8(0x000FFFFF),
-/* 7X*/ DUP16(0x000007FF),
-/* 8X*/ DUP16(ROM_MASK),
-/* 9X*/ DUP16(ROM_MASK),
-/* AX*/ DUP16(0x0000FFFF),
-/* BX*/ DUP16(0x00000003),
-/* CX*/ DUP16(0x00000003),
-/* DX*/ DUP16(0x00000003),
-/* EX*/ DUP16(0x00000003),
-/* FX*/ DUP16(0x00007FFF)
-};
-
-u8 * MMU_ARM7_MEM_MAP[256]={
-/* 0X*/ DUP16(MMU.ARM7_BIOS),
-/* 1X*/ DUP16(MMU.UNUSED_RAM),
-/* 2X*/ DUP16(ARM9Mem.MAIN_MEM),
-/* 3X*/ DUP8(MMU.SWIRAM),
- DUP8(MMU.ARM7_ERAM),
-/* 4X*/ DUP8(MMU.ARM7_REG),
- DUP8(MMU.ARM7_WIRAM),
-/* 5X*/ DUP16(MMU.UNUSED_RAM),
-/* 6X*/ DUP16(ARM9Mem.ARM9_ABG),
-/* 7X*/ DUP16(MMU.UNUSED_RAM),
-/* 8X*/ DUP16(NULL),
-/* 9X*/ DUP16(NULL),
-/* AX*/ DUP16(MMU.CART_RAM),
-/* BX*/ DUP16(MMU.UNUSED_RAM),
-/* CX*/ DUP16(MMU.UNUSED_RAM),
-/* DX*/ DUP16(MMU.UNUSED_RAM),
-/* EX*/ DUP16(MMU.UNUSED_RAM),
-/* FX*/ DUP16(MMU.UNUSED_RAM)
-};
-
-u32 MMU_ARM7_MEM_MASK[256]={
-/* 0X*/ DUP16(0x00003FFF),
-/* 1X*/ DUP16(0x00000003),
-/* 2X*/ DUP16(0x003FFFFF),
-/* 3X*/ DUP8(0x00007FFF),
- DUP8(0x0000FFFF),
-/* 4X*/ DUP8(0x00FFFFFF),
- DUP8(0x0000FFFF),
-/* 5X*/ DUP16(0x00000003),
-/* 6X*/ DUP16(0x0003FFFF),
-/* 7X*/ DUP16(0x00000003),
-/* 8X*/ DUP16(ROM_MASK),
-/* 9X*/ DUP16(ROM_MASK),
-/* AX*/ DUP16(0x0000FFFF),
-/* BX*/ DUP16(0x00000003),
-/* CX*/ DUP16(0x00000003),
-/* DX*/ DUP16(0x00000003),
-/* EX*/ DUP16(0x00000003),
-/* FX*/ DUP16(0x00000003)
-};
-
-u32 MMU_ARM9_WAIT16[16]={
- 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1,
-};
-
-u32 MMU_ARM9_WAIT32[16]={
- 1, 1, 1, 1, 1, 2, 2, 1, 8, 8, 5, 1, 1, 1, 1, 1,
-};
-
-u32 MMU_ARM7_WAIT16[16]={
- 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1,
-};
-
-u32 MMU_ARM7_WAIT32[16]={
- 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 5, 1, 1, 1, 1, 1,
-};
-
-void MMU_Init(void) {
- int i;
-
- LOG("MMU init\n");
-
- memset(&MMU, 0, sizeof(MMU_struct));
-
- MMU.CART_ROM = MMU.UNUSED_RAM;
-
- for(i = 0x80; i<0xA0; ++i)
- {
- MMU_ARM9_MEM_MAP[i] = MMU.CART_ROM;
- MMU_ARM7_MEM_MAP[i] = MMU.CART_ROM;
- }
-
- MMU.MMU_MEM[0] = MMU_ARM9_MEM_MAP;
- MMU.MMU_MEM[1] = MMU_ARM7_MEM_MAP;
- MMU.MMU_MASK[0]= MMU_ARM9_MEM_MASK;
- MMU.MMU_MASK[1] = MMU_ARM7_MEM_MASK;
-
- MMU.ITCMRegion = 0x00800000;
-
- MMU.MMU_WAIT16[0] = MMU_ARM9_WAIT16;
- MMU.MMU_WAIT16[1] = MMU_ARM7_WAIT16;
- MMU.MMU_WAIT32[0] = MMU_ARM9_WAIT32;
- MMU.MMU_WAIT32[1] = MMU_ARM7_WAIT32;
-
- for(i = 0;i < 16;i++)
- FIFOInit(MMU.fifos + i);
-
- mc_init(&MMU.fw, MC_TYPE_FLASH); /* init fw device */
- mc_alloc(&MMU.fw, NDS_FW_SIZE_V1);
- MMU.fw.fp = NULL;
-
- // Init Backup Memory device, this should really be done when the rom is loaded
- mc_init(&MMU.bupmem, MC_TYPE_AUTODETECT);
- mc_alloc(&MMU.bupmem, 1);
- MMU.bupmem.fp = NULL;
-
-}
-
-void MMU_DeInit(void) {
- LOG("MMU deinit\n");
-// if (MMU.fw.fp)
-// fclose(MMU.fw.fp);
- mc_free(&MMU.fw);
-// if (MMU.bupmem.fp)
-// fclose(MMU.bupmem.fp);
- mc_free(&MMU.bupmem);
-}
-
-//Card rom & ram
-
-u16 SPI_CNT = 0;
-u16 SPI_CMD = 0;
-u16 AUX_SPI_CNT = 0;
-u16 AUX_SPI_CMD = 0;
-
-u32 rom_mask = 0;
-
-u32 DMASrc[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
-u32 DMADst[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
-
-void MMU_clearMem()
-{
- int i;
-
- memset(ARM9Mem.ARM9_ABG, 0, 0x080000);
- memset(ARM9Mem.ARM9_AOBJ, 0, 0x040000);
- memset(ARM9Mem.ARM9_BBG, 0, 0x020000);
- memset(ARM9Mem.ARM9_BOBJ, 0, 0x020000);
- memset(ARM9Mem.ARM9_DTCM, 0, 0x4000);
- memset(ARM9Mem.ARM9_ITCM, 0, 0x8000);
- memset(ARM9Mem.ARM9_LCD, 0, 0x0A4000);
- memset(ARM9Mem.ARM9_OAM, 0, 0x0800);
- memset(ARM9Mem.ARM9_REG, 0, 0x01000000);
- memset(ARM9Mem.ARM9_VMEM, 0, 0x0800);
- memset(ARM9Mem.ARM9_WRAM, 0, 0x01000000);
- memset(ARM9Mem.MAIN_MEM, 0, 0x400000);
-
- memset(ARM9Mem.blank_memory, 0, 0x020000);
-
- memset(MMU.ARM7_ERAM, 0, 0x010000);
- memset(MMU.ARM7_REG, 0, 0x010000);
-
- for(i = 0;i < 16;i++)
- FIFOInit(MMU.fifos + i);
-
- MMU.DTCMRegion = 0;
- MMU.ITCMRegion = 0x00800000;
-
- memset(MMU.timer, 0, sizeof(u16) * 2 * 4);
- memset(MMU.timerMODE, 0, sizeof(s32) * 2 * 4);
- memset(MMU.timerON, 0, sizeof(u32) * 2 * 4);
- memset(MMU.timerRUN, 0, sizeof(u32) * 2 * 4);
- memset(MMU.timerReload, 0, sizeof(u16) * 2 * 4);
-
- memset(MMU.reg_IME, 0, sizeof(u32) * 2);
- memset(MMU.reg_IE, 0, sizeof(u32) * 2);
- memset(MMU.reg_IF, 0, sizeof(u32) * 2);
-
- memset(MMU.DMAStartTime, 0, sizeof(u32) * 2 * 4);
- memset(MMU.DMACycle, 0, sizeof(s32) * 2 * 4);
- memset(MMU.DMACrt, 0, sizeof(u32) * 2 * 4);
- memset(MMU.DMAing, 0, sizeof(BOOL) * 2 * 4);
-
- memset(MMU.dscard, 0, sizeof(nds_dscard) * 2);
-
- MainScreen.offset = 192;
- SubScreen.offset = 0;
-
- /* setup the texture slot pointers */
-#if 0
- ARM9Mem.textureSlotAddr[0] = ARM9Mem.blank_memory;
- ARM9Mem.textureSlotAddr[1] = ARM9Mem.blank_memory;
- ARM9Mem.textureSlotAddr[2] = ARM9Mem.blank_memory;
- ARM9Mem.textureSlotAddr[3] = ARM9Mem.blank_memory;
-#else
- ARM9Mem.textureSlotAddr[0] = &ARM9Mem.ARM9_LCD[0x20000 * 0];
- ARM9Mem.textureSlotAddr[1] = &ARM9Mem.ARM9_LCD[0x20000 * 1];
- ARM9Mem.textureSlotAddr[2] = &ARM9Mem.ARM9_LCD[0x20000 * 2];
- ARM9Mem.textureSlotAddr[3] = &ARM9Mem.ARM9_LCD[0x20000 * 3];
-#endif
-}
-
-/* the VRAM blocks keep their content even when not blended in */
-/* to ensure that we write the content back to the LCD ram */
-/* FIXME: VRAM Bank E,F,G,H,I missing */
-void MMU_VRAMWriteBackToLCD(u8 block)
-{
- u8 *destination;
- u8 *source;
- u32 size ;
- u8 VRAMBankCnt;
- #if 1
- return ;
- #endif
- destination = 0 ;
- source = 0;
- VRAMBankCnt = MMU_read8(ARMCPU_ARM9,REG_VRAMCNTA+block) ;
- switch (block)
- {
- case 0: // Bank A
- destination = ARM9Mem.ARM9_LCD ;
- size = 0x20000 ;
- break ;
- case 1: // Bank B
- destination = ARM9Mem.ARM9_LCD + 0x20000 ;
- size = 0x20000 ;
- break ;
- case 2: // Bank C
- destination = ARM9Mem.ARM9_LCD + 0x40000 ;
- size = 0x20000 ;
- break ;
- case 3: // Bank D
- destination = ARM9Mem.ARM9_LCD + 0x60000 ;
- size = 0x20000 ;
- break ;
- case 4: // Bank E
- destination = ARM9Mem.ARM9_LCD + 0x80000 ;
- size = 0x10000 ;
- break ;
- case 5: // Bank F
- destination = ARM9Mem.ARM9_LCD + 0x90000 ;
- size = 0x4000 ;
- break ;
- case 6: // Bank G
- destination = ARM9Mem.ARM9_LCD + 0x94000 ;
- size = 0x4000 ;
- break ;
- case 8: // Bank H
- destination = ARM9Mem.ARM9_LCD + 0x98000 ;
- size = 0x8000 ;
- break ;
- case 9: // Bank I
- destination = ARM9Mem.ARM9_LCD + 0xA0000 ;
- size = 0x4000 ;
- break ;
- default:
- return ;
- }
- switch (VRAMBankCnt & 7) {
- case 0:
- /* vram is allready stored at LCD, we dont need to write it back */
- MMU.vScreen = 1;
- break ;
- case 1:
- switch(block){
- case 0:
- case 1:
- case 2:
- case 3:
- /* banks are in use for BG at ABG + ofs * 0x20000 */
- source = ARM9Mem.ARM9_ABG + ((VRAMBankCnt >> 3) & 3) * 0x20000 ;
- break ;
- case 4:
- /* bank E is in use at ABG */
- source = ARM9Mem.ARM9_ABG ;
- break;
- case 5:
- case 6:
- /* banks are in use for BG at ABG + (0x4000*OFS.0)+(0x10000*OFS.1)*/
- source = ARM9Mem.ARM9_ABG + (((VRAMBankCnt >> 3) & 1) * 0x4000) + (((VRAMBankCnt >> 2) & 1) * 0x10000) ;
- break;
- case 8:
- /* bank H is in use at BBG */
- source = ARM9Mem.ARM9_BBG ;
- break ;
- case 9:
- /* bank I is in use at BBG */
- source = ARM9Mem.ARM9_BBG + 0x8000 ;
- break;
- default: return ;
- }
- break ;
- case 2:
- if (block < 2)
- {
- /* banks A,B are in use for OBJ at AOBJ + ofs * 0x20000 */
- source = ARM9Mem.ARM9_AOBJ + ((VRAMBankCnt >> 3) & 1) * 0x20000 ;
- } else return ;
- break ;
- case 4:
- switch(block){
- case 2:
- /* bank C is in use at BBG */
- source = ARM9Mem.ARM9_BBG ;
- break ;
- case 3:
- /* bank D is in use at BOBJ */
- source = ARM9Mem.ARM9_BOBJ ;
- break ;
- default: return ;
- }
- break ;
- default:
- return ;
- }
- if (!destination) return ;
- if (!source) return ;
- memcpy(destination,source,size) ;
-}
-
-void MMU_VRAMReloadFromLCD(u8 block,u8 VRAMBankCnt)
-{
- u8 *destination;
- u8 *source;
- u32 size;
- #if 1
- return ;
- #endif
- destination = 0;
- source = 0;
- size = 0;
- switch (block)
- {
- case 0: // Bank A
- source = ARM9Mem.ARM9_LCD ;
- size = 0x20000 ;
- break ;
- case 1: // Bank B
- source = ARM9Mem.ARM9_LCD + 0x20000 ;
- size = 0x20000 ;
- break ;
- case 2: // Bank C
- source = ARM9Mem.ARM9_LCD + 0x40000 ;
- size = 0x20000 ;
- break ;
- case 3: // Bank D
- source = ARM9Mem.ARM9_LCD + 0x60000 ;
- size = 0x20000 ;
- break ;
- case 4: // Bank E
- source = ARM9Mem.ARM9_LCD + 0x80000 ;
- size = 0x10000 ;
- break ;
- case 5: // Bank F
- source = ARM9Mem.ARM9_LCD + 0x90000 ;
- size = 0x4000 ;
- break ;
- case 6: // Bank G
- source = ARM9Mem.ARM9_LCD + 0x94000 ;
- size = 0x4000 ;
- break ;
- case 8: // Bank H
- source = ARM9Mem.ARM9_LCD + 0x98000 ;
- size = 0x8000 ;
- break ;
- case 9: // Bank I
- source = ARM9Mem.ARM9_LCD + 0xA0000 ;
- size = 0x4000 ;
- break ;
- default:
- return ;
- }
- switch (VRAMBankCnt & 7) {
- case 0:
- /* vram is allready stored at LCD, we dont need to write it back */
- MMU.vScreen = 1;
- break ;
- case 1:
- if (block < 4)
- {
- /* banks are in use for BG at ABG + ofs * 0x20000 */
- destination = ARM9Mem.ARM9_ABG + ((VRAMBankCnt >> 3) & 3) * 0x20000 ;
- } else return ;
- break ;
- case 2:
- switch(block){
- case 0:
- case 1:
- case 2:
- case 3:
- /* banks are in use for BG at ABG + ofs * 0x20000 */
- destination = ARM9Mem.ARM9_ABG + ((VRAMBankCnt >> 3) & 3) * 0x20000 ;
- break ;
- case 4:
- /* bank E is in use at ABG */
- destination = ARM9Mem.ARM9_ABG ;
- break;
- case 5:
- case 6:
- /* banks are in use for BG at ABG + (0x4000*OFS.0)+(0x10000*OFS.1)*/
- destination = ARM9Mem.ARM9_ABG + (((VRAMBankCnt >> 3) & 1) * 0x4000) + (((VRAMBankCnt >> 2) & 1) * 0x10000) ;
- break;
- case 8:
- /* bank H is in use at BBG */
- destination = ARM9Mem.ARM9_BBG ;
- break ;
- case 9:
- /* bank I is in use at BBG */
- destination = ARM9Mem.ARM9_BBG + 0x8000 ;
- break;
- default: return ;
- }
- break ;
- case 4:
- switch(block){
- case 2:
- /* bank C is in use at BBG */
- destination = ARM9Mem.ARM9_BBG ;
- break ;
- case 3:
- /* bank D is in use at BOBJ */
- destination = ARM9Mem.ARM9_BOBJ ;
- break ;
- default: return ;
- }
- break ;
- default:
- return ;
- }
- if (!destination) return ;
- if (!source) return ;
- memcpy(destination,source,size) ;
-}
-
-void MMU_setRom(u8 * rom, u32 mask)
-{
- unsigned int i;
- MMU.CART_ROM = rom;
-
- for(i = 0x80; i<0xA0; ++i)
- {
- MMU_ARM9_MEM_MAP[i] = rom;
- MMU_ARM7_MEM_MAP[i] = rom;
- MMU_ARM9_MEM_MASK[i] = mask;
- MMU_ARM7_MEM_MASK[i] = mask;
- }
- rom_mask = mask;
-}
-
-void MMU_unsetRom()
-{
- unsigned int i;
- MMU.CART_ROM=MMU.UNUSED_RAM;
-
- for(i = 0x80; i<0xA0; ++i)
- {
- MMU_ARM9_MEM_MAP[i] = MMU.UNUSED_RAM;
- MMU_ARM7_MEM_MAP[i] = MMU.UNUSED_RAM;
- MMU_ARM9_MEM_MASK[i] = ROM_MASK;
- MMU_ARM7_MEM_MASK[i] = ROM_MASK;
- }
- rom_mask = ROM_MASK;
-}
-char txt[80];
-
-u8 FASTCALL MMU_read8(u32 proc, u32 adr)
-{
-#ifdef INTERNAL_DTCM_READ
- if((proc==ARMCPU_ARM9)&((adr&(~0x3FFF))==MMU.DTCMRegion))
- {
- return ARM9Mem.ARM9_DTCM[adr&0x3FFF];
- }
-#endif
-
- // CFlash reading, Mic
- if ((adr>=0x9000000)&&(adr<0x9900000))
- return (unsigned char)cflash_read(adr);
-
-#ifdef EXPERIMENTAL_WIFI
- /* wifi mac access */
- if ((proc==ARMCPU_ARM7) && (adr>=0x04800000)&&(adr<0x05000000))
- {
- if (adr & 1)
- return (WIFI_read16(&wifiMac,adr) >> 8) & 0xFF;
- else
- return WIFI_read16(&wifiMac,adr) & 0xFF;
- }
-#endif
-
- return MMU.MMU_MEM[proc][(adr>>20)&0xFF][adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF]];
-}
-
-
-
-u16 FASTCALL MMU_read16(u32 proc, u32 adr)
-{
-#ifdef INTERNAL_DTCM_READ
- if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion))
- {
- /* Returns data from DTCM (ARM9 only) */
- return T1ReadWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
- }
-#endif
-
- // CFlash reading, Mic
- if ((adr>=0x08800000)&&(adr<0x09900000))
- return (unsigned short)cflash_read(adr);
-
-#ifdef EXPERIMENTAL_WIFI
- /* wifi mac access */
- if ((proc==ARMCPU_ARM7) && (adr>=0x04800000)&&(adr<0x05000000))
- return WIFI_read16(&wifiMac,adr) ;
-#endif
-
- adr &= 0x0FFFFFFF;
-
- if(adr&0x04000000)
- {
- /* Adress is an IO register */
- switch(adr)
- {
-
-#if VIO2SF_GPU_ENABLE
- case 0x04000604:
- return (gpu3D->NDS_3D_GetNumPolys()&2047);
- case 0x04000606:
- return (gpu3D->NDS_3D_GetNumVertex()&8191);
-#endif
-
- case REG_IPCFIFORECV : /* TODO (clear): ??? */
- execute = FALSE;
- return 1;
-
- case REG_IME :
- return (u16)MMU.reg_IME[proc];
-
- case REG_IE :
- return (u16)MMU.reg_IE[proc];
- case REG_IE + 2 :
- return (u16)(MMU.reg_IE[proc]>>16);
-
- case REG_IF :
- return (u16)MMU.reg_IF[proc];
- case REG_IF + 2 :
- return (u16)(MMU.reg_IF[proc]>>16);
-
- case REG_TM0CNTL :
- case REG_TM1CNTL :
- case REG_TM2CNTL :
- case REG_TM3CNTL :
- return MMU.timer[proc][(adr&0xF)>>2];
-
- case 0x04000630 :
- LOG("vect res\r\n"); /* TODO (clear): ??? */
- //execute = FALSE;
- return 0;
- case REG_POSTFLG :
- return 1;
- default :
- break;
- }
- }
-
- /* Returns data from memory */
- return T1ReadWord(MMU.MMU_MEM[proc][(adr >> 20) & 0xFF], adr & MMU.MMU_MASK[proc][(adr >> 20) & 0xFF]);
-}
-
-u32 FASTCALL MMU_read32(u32 proc, u32 adr)
-{
-#ifdef INTERNAL_DTCM_READ
- if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion))
- {
- /* Returns data from DTCM (ARM9 only) */
- return T1ReadLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
- }
-#endif
-
- // CFlash reading, Mic
- if ((adr>=0x9000000)&&(adr<0x9900000))
- return (unsigned long)cflash_read(adr);
-
- adr &= 0x0FFFFFFF;
-
- if((adr >> 24) == 4)
- {
- /* Adress is an IO register */
- switch(adr)
- {
- // This is hacked due to the only current 3D core
- case 0x04000600:
- {
- u32 fifonum = IPCFIFO+proc;
-
- u32 gxstat = (MMU.fifos[fifonum].empty<<26) |
- (1<<25) |
- (MMU.fifos[fifonum].full<<24) |
- /*((NDS_nbpush[0]&1)<<13) | ((NDS_nbpush[2]&0x1F)<<8) |*/
- 2;
-
- LOG ("GXSTAT: 0x%X", gxstat);
-
- return gxstat;
- }
-
- case 0x04000640:
- case 0x04000644:
- case 0x04000648:
- case 0x0400064C:
- case 0x04000650:
- case 0x04000654:
- case 0x04000658:
- case 0x0400065C:
- case 0x04000660:
- case 0x04000664:
- case 0x04000668:
- case 0x0400066C:
- case 0x04000670:
- case 0x04000674:
- case 0x04000678:
- case 0x0400067C:
- {
- //LOG("4000640h..67Fh - CLIPMTX_RESULT - Read Current Clip Coordinates Matrix (R)");
-#if VIO2SF_GPU_ENABLE
- return gpu3D->NDS_3D_GetClipMatrix ((adr-0x04000640)/4);
-#else
- return 0;
-#endif
- }
- case 0x04000680:
- case 0x04000684:
- case 0x04000688:
- case 0x0400068C:
- case 0x04000690:
- case 0x04000694:
- case 0x04000698:
- case 0x0400069C:
- case 0x040006A0:
- {
-#if VIO2SF_GPU_ENABLE
- //LOG("4000680h..6A3h - VECMTX_RESULT - Read Current Directional Vector Matrix (R)");
- return gpu3D->NDS_3D_GetDirectionalMatrix ((adr-0x04000680)/4);
-#else
- return 0;
-#endif
- }
-
- case 0x4000604:
- {
-#if VIO2SF_GPU_ENABLE
- return (gpu3D->NDS_3D_GetNumPolys()&2047) & ((gpu3D->NDS_3D_GetNumVertex()&8191) << 16);
- //LOG ("read32 - RAM_COUNT -> 0x%X", ((u32 *)(MMU.MMU_MEM[proc][(adr>>20)&0xFF]))[(adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF])>>2]);
-#else
- return 0;
-#endif
- }
-
- case REG_IME :
- return MMU.reg_IME[proc];
- case REG_IE :
- return MMU.reg_IE[proc];
- case REG_IF :
- return MMU.reg_IF[proc];
- case REG_IPCFIFORECV :
- {
- u16 IPCFIFO_CNT = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184);
- if(IPCFIFO_CNT&0x8000)
- {
- //execute = FALSE;
- u32 fifonum = IPCFIFO+proc;
- u32 val = FIFOValue(MMU.fifos + fifonum);
- u32 remote = (proc+1) & 1;
- u16 IPCFIFO_CNT_remote = T1ReadWord(MMU.MMU_MEM[remote][0x40], 0x184);
- IPCFIFO_CNT |= (MMU.fifos[fifonum].empty<<8) | (MMU.fifos[fifonum].full<<9) | (MMU.fifos[fifonum].error<<14);
- IPCFIFO_CNT_remote |= (MMU.fifos[fifonum].empty) | (MMU.fifos[fifonum].full<<1);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, IPCFIFO_CNT);
- T1WriteWord(MMU.MMU_MEM[remote][0x40], 0x184, IPCFIFO_CNT_remote);
- if ((MMU.fifos[fifonum].empty) && (IPCFIFO_CNT & BIT(2)))
- NDS_makeInt(remote,17) ; /* remote: SEND FIFO EMPTY */
- return val;
- }
- }
- return 0;
- case REG_TM0CNTL :
- case REG_TM1CNTL :
- case REG_TM2CNTL :
- case REG_TM3CNTL :
- {
- u32 val = T1ReadWord(MMU.MMU_MEM[proc][0x40], (adr + 2) & 0xFFF);
- return MMU.timer[proc][(adr&0xF)>>2] | (val<<16);
- }
- /*
- case 0x04000640 : // TODO (clear): again, ???
- LOG("read proj\r\n");
- return 0;
- case 0x04000680 :
- LOG("read roat\r\n");
- return 0;
- case 0x04000620 :
- LOG("point res\r\n");
- return 0;
- */
- case REG_GCDATAIN:
- {
- u32 val;
-
- if(!MMU.dscard[proc].adress) return 0;
-
- val = T1ReadLong(MMU.CART_ROM, MMU.dscard[proc].adress);
-
- MMU.dscard[proc].adress += 4; /* increment adress */
-
- MMU.dscard[proc].transfer_count--; /* update transfer counter */
- if(MMU.dscard[proc].transfer_count) /* if transfer is not ended */
- {
- return val; /* return data */
- }
- else /* transfer is done */
- {
- T1WriteLong(MMU.MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, T1ReadLong(MMU.MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff) & ~(0x00800000 | 0x80000000));
- /* = 0x7f7fffff */
-
- /* if needed, throw irq for the end of transfer */
- if(T1ReadWord(MMU.MMU_MEM[proc][(REG_AUXSPICNT >> 20) & 0xff], REG_AUXSPICNT & 0xfff) & 0x4000)
- {
- if(proc == ARMCPU_ARM7) NDS_makeARM7Int(19);
- else NDS_makeARM9Int(19);
- }
-
- return val;
- }
- }
-
- default :
- break;
- }
- }
-
- /* Returns data from memory */
- return T1ReadLong(MMU.MMU_MEM[proc][(adr >> 20) & 0xFF], adr & MMU.MMU_MASK[proc][(adr >> 20) & 0xFF]);
-}
-
-void FASTCALL MMU_write8(u32 proc, u32 adr, u8 val)
-{
-#ifdef INTERNAL_DTCM_WRITE
- if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion))
- {
- /* Writes data in DTCM (ARM9 only) */
- ARM9Mem.ARM9_DTCM[adr&0x3FFF] = val;
- return ;
- }
-#endif
-
- // CFlash writing, Mic
- if ((adr>=0x9000000)&&(adr<0x9900000)) {
- cflash_write(adr,val);
- return;
- }
-
- adr &= 0x0FFFFFFF;
-
- // This is bad, remove it
- if(proc == ARMCPU_ARM7)
- {
- if ((adr>=0x04000400)&&(adr<0x0400051D))
- {
- SPU_WriteByte(adr, val);
- return;
- }
- }
-
- if ((adr & 0xFF800000) == 0x04800000)
- {
- /* is wifi hardware, dont intermix with regular hardware registers */
- /* FIXME handle 8 bit writes */
- return ;
- }
-
- switch(adr)
- {
- case REG_DISPA_WIN0H:
- if(proc == ARMCPU_ARM9) GPU_setWIN0_H1 (MainScreen.gpu, val);
- break ;
- case REG_DISPA_WIN0H+1:
- if(proc == ARMCPU_ARM9) GPU_setWIN0_H0 (MainScreen.gpu, val);
- break ;
- case REG_DISPA_WIN1H:
- if(proc == ARMCPU_ARM9) GPU_setWIN1_H1 (MainScreen.gpu,val);
- break ;
- case REG_DISPA_WIN1H+1:
- if(proc == ARMCPU_ARM9) GPU_setWIN1_H0 (MainScreen.gpu,val);
- break ;
-
- case REG_DISPB_WIN0H:
- if(proc == ARMCPU_ARM9) GPU_setWIN0_H1(SubScreen.gpu,val);
- break ;
- case REG_DISPB_WIN0H+1:
- if(proc == ARMCPU_ARM9) GPU_setWIN0_H0(SubScreen.gpu,val);
- break ;
- case REG_DISPB_WIN1H:
- if(proc == ARMCPU_ARM9) GPU_setWIN1_H1(SubScreen.gpu,val);
- break ;
- case REG_DISPB_WIN1H+1:
- if(proc == ARMCPU_ARM9) GPU_setWIN1_H0(SubScreen.gpu,val);
- break ;
-
- case REG_DISPA_WIN0V:
- if(proc == ARMCPU_ARM9) GPU_setWIN0_V1(MainScreen.gpu,val) ;
- break ;
- case REG_DISPA_WIN0V+1:
- if(proc == ARMCPU_ARM9) GPU_setWIN0_V0(MainScreen.gpu,val) ;
- break ;
- case REG_DISPA_WIN1V:
- if(proc == ARMCPU_ARM9) GPU_setWIN1_V1(MainScreen.gpu,val) ;
- break ;
- case REG_DISPA_WIN1V+1:
- if(proc == ARMCPU_ARM9) GPU_setWIN1_V0(MainScreen.gpu,val) ;
- break ;
-
- case REG_DISPB_WIN0V:
- if(proc == ARMCPU_ARM9) GPU_setWIN0_V1(SubScreen.gpu,val) ;
- break ;
- case REG_DISPB_WIN0V+1:
- if(proc == ARMCPU_ARM9) GPU_setWIN0_V0(SubScreen.gpu,val) ;
- break ;
- case REG_DISPB_WIN1V:
- if(proc == ARMCPU_ARM9) GPU_setWIN1_V1(SubScreen.gpu,val) ;
- break ;
- case REG_DISPB_WIN1V+1:
- if(proc == ARMCPU_ARM9) GPU_setWIN1_V0(SubScreen.gpu,val) ;
- break ;
-
- case REG_DISPA_WININ:
- if(proc == ARMCPU_ARM9) GPU_setWININ0(MainScreen.gpu,val) ;
- break ;
- case REG_DISPA_WININ+1:
- if(proc == ARMCPU_ARM9) GPU_setWININ1(MainScreen.gpu,val) ;
- break ;
- case REG_DISPA_WINOUT:
- if(proc == ARMCPU_ARM9) GPU_setWINOUT(MainScreen.gpu,val) ;
- break ;
- case REG_DISPA_WINOUT+1:
- if(proc == ARMCPU_ARM9) GPU_setWINOBJ(MainScreen.gpu,val);
- break ;
-
- case REG_DISPB_WININ:
- if(proc == ARMCPU_ARM9) GPU_setWININ0(SubScreen.gpu,val) ;
- break ;
- case REG_DISPB_WININ+1:
- if(proc == ARMCPU_ARM9) GPU_setWININ1(SubScreen.gpu,val) ;
- break ;
- case REG_DISPB_WINOUT:
- if(proc == ARMCPU_ARM9) GPU_setWINOUT(SubScreen.gpu,val) ;
- break ;
- case REG_DISPB_WINOUT+1:
- if(proc == ARMCPU_ARM9) GPU_setWINOBJ(SubScreen.gpu,val) ;
- break ;
-
-
- case REG_DISPA_BLDCNT:
- if(proc == ARMCPU_ARM9) GPU_setBLDCNT_HIGH(MainScreen.gpu,val);
- break;
- case REG_DISPA_BLDCNT+1:
- if(proc == ARMCPU_ARM9) GPU_setBLDCNT_LOW (MainScreen.gpu,val);
- break;
-
- case REG_DISPB_BLDCNT:
- if(proc == ARMCPU_ARM9) GPU_setBLDCNT_HIGH (SubScreen.gpu,val);
- break;
- case REG_DISPB_BLDCNT+1:
- if(proc == ARMCPU_ARM9) GPU_setBLDCNT_LOW (SubScreen.gpu,val);
- break;
-
- case REG_DISPA_BLDALPHA:
- if(proc == ARMCPU_ARM9) GPU_setBLDALPHA_EVB(MainScreen.gpu,val) ;
- break;
- case REG_DISPA_BLDALPHA+1:
- if(proc == ARMCPU_ARM9) GPU_setBLDALPHA_EVA(MainScreen.gpu,val) ;
- break;
-
- case REG_DISPB_BLDALPHA:
- if(proc == ARMCPU_ARM9) GPU_setBLDALPHA_EVB(SubScreen.gpu,val) ;
- break;
- case REG_DISPB_BLDALPHA+1:
- if(proc == ARMCPU_ARM9) GPU_setBLDALPHA_EVA(SubScreen.gpu,val);
- break;
-
- case REG_DISPA_BLDY:
- if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(MainScreen.gpu,val) ;
- break ;
- case REG_DISPB_BLDY:
- if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(SubScreen.gpu,val) ;
- break;
-
- /* TODO: EEEK ! Controls for VRAMs A, B, C, D are missing ! */
- /* TODO: Not all mappings of VRAMs are handled... (especially BG and OBJ modes) */
- case REG_VRAMCNTA:
- case REG_VRAMCNTB:
- case REG_VRAMCNTC:
- case REG_VRAMCNTD:
- if(proc == ARMCPU_ARM9)
- {
- MMU_VRAMWriteBackToLCD(0) ;
- MMU_VRAMWriteBackToLCD(1) ;
- MMU_VRAMWriteBackToLCD(2) ;
- MMU_VRAMWriteBackToLCD(3) ;
- switch(val & 0x1F)
- {
- case 1 :
- MMU.vram_mode[adr-REG_VRAMCNTA] = 0; // BG-VRAM
- //MMU.vram_offset[0] = ARM9Mem.ARM9_ABG+(0x20000*0); // BG-VRAM
- break;
- case 1 | (1 << 3) :
- MMU.vram_mode[adr-REG_VRAMCNTA] = 1; // BG-VRAM
- //MMU.vram_offset[0] = ARM9Mem.ARM9_ABG+(0x20000*1); // BG-VRAM
- break;
- case 1 | (2 << 3) :
- MMU.vram_mode[adr-REG_VRAMCNTA] = 2; // BG-VRAM
- //MMU.vram_offset[0] = ARM9Mem.ARM9_ABG+(0x20000*2); // BG-VRAM
- break;
- case 1 | (3 << 3) :
- MMU.vram_mode[adr-REG_VRAMCNTA] = 3; // BG-VRAM
- //MMU.vram_offset[0] = ARM9Mem.ARM9_ABG+(0x20000*3); // BG-VRAM
- break;
- case 0: /* mapped to lcd */
- MMU.vram_mode[adr-REG_VRAMCNTA] = 4 | (adr-REG_VRAMCNTA) ;
- break ;
- }
- /*
- * FIXME: simply texture slot handling
- * This is a first stab and is not correct. It does
- * not handle a VRAM texture slot becoming
- * unconfigured.
- * Revisit all of VRAM control handling for future
- * release?
- */
- if ( val & 0x80) {
- if ( (val & 0x7) == 3) {
- int slot_index = (val >> 3) & 0x3;
-
- ARM9Mem.textureSlotAddr[slot_index] =
- &ARM9Mem.ARM9_LCD[0x20000 * (adr - REG_VRAMCNTA)];
- }
- }
- MMU_VRAMReloadFromLCD(adr-REG_VRAMCNTA,val) ;
- }
- break;
- case REG_VRAMCNTE :
- if(proc == ARMCPU_ARM9)
- {
- MMU_VRAMWriteBackToLCD((u8)REG_VRAMCNTE) ;
- if((val & 7) == 5)
- {
- ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x80000;
- ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x82000;
- ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x84000;
- ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x86000;
- }
- else if((val & 7) == 3)
- {
- ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD + 0x80000;
- ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD + 0x82000;
- ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD + 0x84000;
- ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD + 0x86000;
- }
- else if((val & 7) == 4)
- {
- ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x80000;
- ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x82000;
- ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x84000;
- ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x86000;
- }
-
- MMU_VRAMReloadFromLCD(adr-REG_VRAMCNTE,val) ;
- }
- break;
-
- case REG_VRAMCNTF :
- if(proc == ARMCPU_ARM9)
- {
- switch(val & 0x1F)
- {
- case 4 :
- ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x90000;
- ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x92000;
- break;
-
- case 4 | (1 << 3) :
- ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x90000;
- ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x92000;
- break;
-
- case 3 :
- ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD + 0x90000;
- break;
-
- case 3 | (1 << 3) :
- ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD + 0x90000;
- break;
-
- case 3 | (2 << 3) :
- ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD + 0x90000;
- break;
-
- case 3 | (3 << 3) :
- ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD + 0x90000;
- break;
-
- case 5 :
- case 5 | (1 << 3) :
- case 5 | (2 << 3) :
- case 5 | (3 << 3) :
- ARM9Mem.ObjExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x90000;
- ARM9Mem.ObjExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x92000;
- break;
- }
- }
- break;
- case REG_VRAMCNTG :
- if(proc == ARMCPU_ARM9)
- {
- switch(val & 0x1F)
- {
- case 4 :
- ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x94000;
- ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x96000;
- break;
-
- case 4 | (1 << 3) :
- ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x94000;
- ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x96000;
- break;
-
- case 3 :
- ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD + 0x94000;
- break;
-
- case 3 | (1 << 3) :
- ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD + 0x94000;
- break;
-
- case 3 | (2 << 3) :
- ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD + 0x94000;
- break;
-
- case 3 | (3 << 3) :
- ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD + 0x94000;
- break;
-
- case 5 :
- case 5 | (1 << 3) :
- case 5 | (2 << 3) :
- case 5 | (3 << 3) :
- ARM9Mem.ObjExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x94000;
- ARM9Mem.ObjExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x96000;
- break;
- }
- }
- break;
-
- case REG_VRAMCNTH :
- if(proc == ARMCPU_ARM9)
- {
- MMU_VRAMWriteBackToLCD((u8)REG_VRAMCNTH) ;
-
- if((val & 7) == 2)
- {
- ARM9Mem.ExtPal[1][0] = ARM9Mem.ARM9_LCD + 0x98000;
- ARM9Mem.ExtPal[1][1] = ARM9Mem.ARM9_LCD + 0x9A000;
- ARM9Mem.ExtPal[1][2] = ARM9Mem.ARM9_LCD + 0x9C000;
- ARM9Mem.ExtPal[1][3] = ARM9Mem.ARM9_LCD + 0x9E000;
- }
-
- MMU_VRAMReloadFromLCD(adr-REG_VRAMCNTH,val) ;
- }
- break;
-
- case REG_VRAMCNTI :
- if(proc == ARMCPU_ARM9)
- {
- MMU_VRAMWriteBackToLCD((u8)REG_VRAMCNTI) ;
-
- if((val & 7) == 3)
- {
- ARM9Mem.ObjExtPal[1][0] = ARM9Mem.ARM9_LCD + 0xA0000;
- ARM9Mem.ObjExtPal[1][1] = ARM9Mem.ARM9_LCD + 0xA2000;
- }
-
- MMU_VRAMReloadFromLCD(adr-REG_VRAMCNTI,val) ;
- }
- break;
-
-#ifdef LOG_CARD
- case 0x040001A0 : /* TODO (clear): ??? */
- case 0x040001A1 :
- case 0x040001A2 :
- case 0x040001A8 :
- case 0x040001A9 :
- case 0x040001AA :
- case 0x040001AB :
- case 0x040001AC :
- case 0x040001AD :
- case 0x040001AE :
- case 0x040001AF :
- LOG("%08X : %02X\r\n", adr, val);
-#endif
-
- default :
- break;
- }
-
- MMU.MMU_MEM[proc][(adr>>20)&0xFF][adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF]]=val;
-}
-
-u16 partie = 1;
-
-void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val)
-{
-#ifdef INTERNAL_DTCM_WRITE
- if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion))
- {
- /* Writes in DTCM (ARM9 only) */
- T1WriteWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF, val);
- return;
- }
-#endif
-
- // CFlash writing, Mic
- if ((adr>=0x08800000)&&(adr<0x09900000))
- {
- cflash_write(adr,val);
- return;
- }
-
-#ifdef EXPERIMENTAL_WIFI
-
- /* wifi mac access */
- if ((proc==ARMCPU_ARM7) && (adr>=0x04800000)&&(adr<0x05000000))
- {
- WIFI_write16(&wifiMac,adr,val) ;
- return ;
- }
-#else
- if ((proc==ARMCPU_ARM7) && (adr>=0x04800000)&&(adr<0x05000000))
- return ;
-#endif
-
- adr &= 0x0FFFFFFF;
-
- // This is bad, remove it
- if(proc == ARMCPU_ARM7)
- {
- if ((adr>=0x04000400)&&(adr<0x0400051D))
- {
- SPU_WriteWord(adr, val);
- return;
- }
- }
-
- if((adr >> 24) == 4)
- {
- /* Adress is an IO register */
- switch(adr)
- {
-#if VIO2SF_GPU_ENABLE
- case 0x0400035C:
- {
- ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x35C>>1] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_FogOffset (val);
- }
- return;
- }
- case 0x04000340:
- {
- ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x340>>1] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_AlphaFunc(val);
- }
- return;
- }
- case 0x04000060:
- {
- ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x060>>1] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Control(val);
- }
- return;
- }
- case 0x04000354:
- {
- ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x354>>1] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_ClearDepth(val);
- }
- return;
- }
-#endif
-
- case REG_DISPA_BLDCNT:
- if(proc == ARMCPU_ARM9) GPU_setBLDCNT(MainScreen.gpu,val) ;
- break ;
- case REG_DISPB_BLDCNT:
- if(proc == ARMCPU_ARM9) GPU_setBLDCNT(SubScreen.gpu,val) ;
- break ;
- case REG_DISPA_BLDALPHA:
- if(proc == ARMCPU_ARM9) GPU_setBLDALPHA(MainScreen.gpu,val) ;
- break ;
- case REG_DISPB_BLDALPHA:
- if(proc == ARMCPU_ARM9) GPU_setBLDALPHA(SubScreen.gpu,val) ;
- break ;
- case REG_DISPA_BLDY:
- if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(MainScreen.gpu,val) ;
- break ;
- case REG_DISPB_BLDY:
- if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(SubScreen.gpu,val) ;
- break;
- case REG_DISPA_MASTERBRIGHT:
- GPU_setMasterBrightness (MainScreen.gpu, val);
- break;
- /*
- case REG_DISPA_MOSAIC:
- if(proc == ARMCPU_ARM9) GPU_setMOSAIC(MainScreen.gpu,val) ;
- break ;
- case REG_DISPB_MOSAIC:
- if(proc == ARMCPU_ARM9) GPU_setMOSAIC(SubScreen.gpu,val) ;
- break ;
- */
-
- case REG_DISPA_WIN0H:
- if(proc == ARMCPU_ARM9) GPU_setWIN0_H (MainScreen.gpu,val) ;
- break ;
- case REG_DISPA_WIN1H:
- if(proc == ARMCPU_ARM9) GPU_setWIN1_H(MainScreen.gpu,val) ;
- break ;
- case REG_DISPB_WIN0H:
- if(proc == ARMCPU_ARM9) GPU_setWIN0_H(SubScreen.gpu,val) ;
- break ;
- case REG_DISPB_WIN1H:
- if(proc == ARMCPU_ARM9) GPU_setWIN1_H(SubScreen.gpu,val) ;
- break ;
- case REG_DISPA_WIN0V:
- if(proc == ARMCPU_ARM9) GPU_setWIN0_V(MainScreen.gpu,val) ;
- break ;
- case REG_DISPA_WIN1V:
- if(proc == ARMCPU_ARM9) GPU_setWIN1_V(MainScreen.gpu,val) ;
- break ;
- case REG_DISPB_WIN0V:
- if(proc == ARMCPU_ARM9) GPU_setWIN0_V(SubScreen.gpu,val) ;
- break ;
- case REG_DISPB_WIN1V:
- if(proc == ARMCPU_ARM9) GPU_setWIN1_V(SubScreen.gpu,val) ;
- break ;
- case REG_DISPA_WININ:
- if(proc == ARMCPU_ARM9) GPU_setWININ(MainScreen.gpu, val) ;
- break ;
- case REG_DISPA_WINOUT:
- if(proc == ARMCPU_ARM9) GPU_setWINOUT16(MainScreen.gpu, val) ;
- break ;
- case REG_DISPB_WININ:
- if(proc == ARMCPU_ARM9) GPU_setWININ(SubScreen.gpu, val) ;
- break ;
- case REG_DISPB_WINOUT:
- if(proc == ARMCPU_ARM9) GPU_setWINOUT16(SubScreen.gpu, val) ;
- break ;
-
- case REG_DISPB_MASTERBRIGHT:
- GPU_setMasterBrightness (SubScreen.gpu, val);
- break;
-
- case REG_POWCNT1 :
- if(proc == ARMCPU_ARM9)
- {
- if(val & (1<<15))
- {
- LOG("Main core on top\n");
- MainScreen.offset = 0;
- SubScreen.offset = 192;
- //nds.swapScreen();
- }
- else
- {
- LOG("Main core on bottom (%04X)\n", val);
- MainScreen.offset = 192;
- SubScreen.offset = 0;
- }
- }
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x304, val);
- return;
-
- case REG_AUXSPICNT:
- T1WriteWord(MMU.MMU_MEM[proc][(REG_AUXSPICNT >> 20) & 0xff], REG_AUXSPICNT & 0xfff, val);
- AUX_SPI_CNT = val;
-
- if (val == 0)
- mc_reset_com(&MMU.bupmem); /* reset backup memory device communication */
- return;
-
- case REG_AUXSPIDATA:
- if(val!=0)
- {
- AUX_SPI_CMD = val & 0xFF;
- }
-
- T1WriteWord(MMU.MMU_MEM[proc][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, bm_transfer(&MMU.bupmem, val));
- return;
-
- case REG_SPICNT :
- if(proc == ARMCPU_ARM7)
- {
- int reset_firmware = 1;
-
- if ( ((SPI_CNT >> 8) & 0x3) == 1) {
- if ( ((val >> 8) & 0x3) == 1) {
- if ( BIT11(SPI_CNT)) {
- /* select held */
- reset_firmware = 0;
- }
- }
- }
-
- //MMU.fw.com == 0; /* reset fw device communication */
- if ( reset_firmware) {
- /* reset fw device communication */
- mc_reset_com(&MMU.fw);
- }
- SPI_CNT = val;
- }
-
- T1WriteWord(MMU.MMU_MEM[proc][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff, val);
- return;
-
- case REG_SPIDATA :
- if(proc==ARMCPU_ARM7)
- {
- u16 spicnt;
-
- if(val!=0)
- {
- SPI_CMD = val;
- }
-
- spicnt = T1ReadWord(MMU.MMU_MEM[proc][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff);
-
- switch((spicnt >> 8) & 0x3)
- {
- case 0 :
- break;
-
- case 1 : /* firmware memory device */
- if((spicnt & 0x3) != 0) /* check SPI baudrate (must be 4mhz) */
- {
- T1WriteWord(MMU.MMU_MEM[proc][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, 0);
- break;
- }
- T1WriteWord(MMU.MMU_MEM[proc][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, fw_transfer(&MMU.fw, val));
-
- return;
-
- case 2 :
- switch(SPI_CMD & 0x70)
- {
- case 0x00 :
- val = 0;
- break;
- case 0x10 :
- //execute = FALSE;
- if(SPI_CNT&(1<<11))
- {
- if(partie)
- {
- val = ((nds.touchY<<3)&0x7FF);
- partie = 0;
- //execute = FALSE;
- break;
- }
- val = (nds.touchY>>5);
- partie = 1;
- break;
- }
- val = ((nds.touchY<<3)&0x7FF);
- partie = 1;
- break;
- case 0x20 :
- val = 0;
- break;
- case 0x30 :
- val = 0;
- break;
- case 0x40 :
- val = 0;
- break;
- case 0x50 :
- if(spicnt & 0x800)
- {
- if(partie)
- {
- val = ((nds.touchX<<3)&0x7FF);
- partie = 0;
- break;
- }
- val = (nds.touchX>>5);
- partie = 1;
- break;
- }
- val = ((nds.touchX<<3)&0x7FF);
- partie = 1;
- break;
- case 0x60 :
- val = 0;
- break;
- case 0x70 :
- val = 0;
- break;
- }
- break;
-
- case 3 :
- /* NOTICE: Device 3 of SPI is reserved (unused and unusable) */
- break;
- }
- }
-
- T1WriteWord(MMU.MMU_MEM[proc][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, val);
- return;
-
- /* NOTICE: Perhaps we have to use gbatek-like reg names instead of libnds-like ones ...*/
-
- case REG_DISPA_BG0CNT :
- //GPULOG("MAIN BG0 SETPROP 16B %08X\r\n", val);
- if(proc == ARMCPU_ARM9) GPU_setBGProp(MainScreen.gpu, 0, val);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x8, val);
- return;
- case REG_DISPA_BG1CNT :
- //GPULOG("MAIN BG1 SETPROP 16B %08X\r\n", val);
- if(proc == ARMCPU_ARM9) GPU_setBGProp(MainScreen.gpu, 1, val);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xA, val);
- return;
- case REG_DISPA_BG2CNT :
- //GPULOG("MAIN BG2 SETPROP 16B %08X\r\n", val);
- if(proc == ARMCPU_ARM9) GPU_setBGProp(MainScreen.gpu, 2, val);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xC, val);
- return;
- case REG_DISPA_BG3CNT :
- //GPULOG("MAIN BG3 SETPROP 16B %08X\r\n", val);
- if(proc == ARMCPU_ARM9) GPU_setBGProp(MainScreen.gpu, 3, val);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xE, val);
- return;
- case REG_DISPB_BG0CNT :
- //GPULOG("SUB BG0 SETPROP 16B %08X\r\n", val);
- if(proc == ARMCPU_ARM9) GPU_setBGProp(SubScreen.gpu, 0, val);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x1008, val);
- return;
- case REG_DISPB_BG1CNT :
- //GPULOG("SUB BG1 SETPROP 16B %08X\r\n", val);
- if(proc == ARMCPU_ARM9) GPU_setBGProp(SubScreen.gpu, 1, val);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x100A, val);
- return;
- case REG_DISPB_BG2CNT :
- //GPULOG("SUB BG2 SETPROP 16B %08X\r\n", val);
- if(proc == ARMCPU_ARM9) GPU_setBGProp(SubScreen.gpu, 2, val);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x100C, val);
- return;
- case REG_DISPB_BG3CNT :
- //GPULOG("SUB BG3 SETPROP 16B %08X\r\n", val);
- if(proc == ARMCPU_ARM9) GPU_setBGProp(SubScreen.gpu, 3, val);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x100E, val);
- return;
- case REG_IME : {
- u32 old_val = MMU.reg_IME[proc];
- u32 new_val = val & 1;
- MMU.reg_IME[proc] = new_val;
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x208, val);
- if ( new_val && old_val != new_val) {
- /* raise an interrupt request to the CPU if needed */
- if ( MMU.reg_IE[proc] & MMU.reg_IF[proc]) {
- NDS_ARM7.wIRQ = TRUE;
- NDS_ARM7.waitIRQ = FALSE;
- }
- }
- return;
- }
- case REG_VRAMCNTA:
- MMU_write8(proc,adr,val & 0xFF) ;
- MMU_write8(proc,adr+1,val >> 8) ;
- return ;
- case REG_VRAMCNTC:
- MMU_write8(proc,adr,val & 0xFF) ;
- MMU_write8(proc,adr+1,val >> 8) ;
- return ;
- case REG_VRAMCNTE:
- MMU_write8(proc,adr,val & 0xFF) ;
- MMU_write8(proc,adr+1,val >> 8) ;
- return ;
- case REG_VRAMCNTG:
- MMU_write8(proc,adr,val & 0xFF) ;
- MMU_write8(proc,adr+1,val >> 8) ;
- return ;
- case REG_VRAMCNTI:
- MMU_write8(proc,adr,val & 0xFF) ;
- return ;
-
- case REG_IE :
- MMU.reg_IE[proc] = (MMU.reg_IE[proc]&0xFFFF0000) | val;
- if ( MMU.reg_IME[proc]) {
- /* raise an interrupt request to the CPU if needed */
- if ( MMU.reg_IE[proc] & MMU.reg_IF[proc]) {
- NDS_ARM7.wIRQ = TRUE;
- NDS_ARM7.waitIRQ = FALSE;
- }
- }
- return;
- case REG_IE + 2 :
- execute = FALSE;
- MMU.reg_IE[proc] = (MMU.reg_IE[proc]&0xFFFF) | (((u32)val)<<16);
- return;
-
- case REG_IF :
- execute = FALSE;
- MMU.reg_IF[proc] &= (~((u32)val));
- return;
- case REG_IF + 2 :
- execute = FALSE;
- MMU.reg_IF[proc] &= (~(((u32)val)<<16));
- return;
-
- case REG_IPCSYNC :
- {
- u32 remote = (proc+1)&1;
- u16 IPCSYNC_remote = T1ReadWord(MMU.MMU_MEM[remote][0x40], 0x180);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x180, (val&0xFFF0)|((IPCSYNC_remote>>8)&0xF));
- T1WriteWord(MMU.MMU_MEM[remote][0x40], 0x180, (IPCSYNC_remote&0xFFF0)|((val>>8)&0xF));
- MMU.reg_IF[remote] |= ((IPCSYNC_remote & (1<<14))<<2) & ((val & (1<<13))<<3);// & (MMU.reg_IME[remote] << 16);// & (MMU.reg_IE[remote] & (1<<16));//
- //execute = FALSE;
- }
- return;
- case REG_IPCFIFOCNT :
- {
- u32 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184) ;
- u32 cnt_r = T1ReadWord(MMU.MMU_MEM[(proc+1) & 1][0x40], 0x184) ;
- if ((val & 0x8000) && !(cnt_l & 0x8000))
- {
- /* this is the first init, the other side didnt init yet */
- /* so do a complete init */
- FIFOInit(MMU.fifos + (IPCFIFO+proc));
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184,0x8101) ;
- /* and then handle it as usual */
- }
-
- if(val & 0x4008)
- {
- FIFOInit(MMU.fifos + (IPCFIFO+((proc+1)&1)));
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, (cnt_l & 0x0301) | (val & 0x8404) | 1);
- T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, (cnt_r & 0xC507) | 0x100);
- MMU.reg_IF[proc] |= ((val & 4)<<15);// & (MMU.reg_IME[proc]<<17);// & (MMU.reg_IE[proc]&0x20000);//
- return;
- }
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184) | (val & 0xBFF4));
- }
- return;
- case REG_TM0CNTL :
- case REG_TM1CNTL :
- case REG_TM2CNTL :
- case REG_TM3CNTL :
- MMU.timerReload[proc][(adr>>2)&3] = val;
- return;
- case REG_TM0CNTH :
- case REG_TM1CNTH :
- case REG_TM2CNTH :
- case REG_TM3CNTH :
- if(val&0x80)
- {
- MMU.timer[proc][((adr-2)>>2)&0x3] = MMU.timerReload[proc][((adr-2)>>2)&0x3];
- }
- MMU.timerON[proc][((adr-2)>>2)&0x3] = val & 0x80;
- switch(val&7)
- {
- case 0 :
- MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 0+1;//proc;
- break;
- case 1 :
- MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 6+1;//proc;
- break;
- case 2 :
- MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 8+1;//proc;
- break;
- case 3 :
- MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 10+1;//proc;
- break;
- default :
- MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 0xFFFF;
- break;
- }
- if(!(val & 0x80))
- MMU.timerRUN[proc][((adr-2)>>2)&0x3] = FALSE;
- T1WriteWord(MMU.MMU_MEM[proc][0x40], adr & 0xFFF, val);
- return;
- case REG_DISPA_DISPCNT+2 :
- {
- //execute = FALSE;
- u32 v = (T1ReadLong(MMU.MMU_MEM[proc][0x40], 0) & 0xFFFF) | ((u32) val << 16);
- GPU_setVideoProp(MainScreen.gpu, v);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0, v);
- }
- return;
- case REG_DISPA_DISPCNT :
- if(proc == ARMCPU_ARM9)
- {
- u32 v = (T1ReadLong(MMU.MMU_MEM[proc][0x40], 0) & 0xFFFF0000) | val;
- GPU_setVideoProp(MainScreen.gpu, v);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0, v);
- }
- return;
- case REG_DISPA_DISPCAPCNT :
- if(proc == ARMCPU_ARM9)
- {
- GPU_set_DISPCAPCNT(MainScreen.gpu,val);
- }
- return;
- case REG_DISPB_DISPCNT+2 :
- if(proc == ARMCPU_ARM9)
- {
- //execute = FALSE;
- u32 v = (T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x1000) & 0xFFFF) | ((u32) val << 16);
- GPU_setVideoProp(SubScreen.gpu, v);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x1000, v);
- }
- return;
- case REG_DISPB_DISPCNT :
- {
- u32 v = (T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x1000) & 0xFFFF0000) | val;
- GPU_setVideoProp(SubScreen.gpu, v);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x1000, v);
- }
- return;
- //case 0x020D8460 :
- /*case 0x0235A904 :
- LOG("ECRIRE %d %04X\r\n", proc, val);
- execute = FALSE;*/
- case REG_DMA0CNTH :
- {
- u32 v;
-
- //if(val&0x8000) execute = FALSE;
- //LOG("16 bit dma0 %04X\r\n", val);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xBA, val);
- DMASrc[proc][0] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xB0);
- DMADst[proc][0] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xB4);
- v = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xB8);
- MMU.DMAStartTime[proc][0] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7);
- MMU.DMACrt[proc][0] = v;
- if(MMU.DMAStartTime[proc][0] == 0)
- MMU_doDMA(proc, 0);
- #ifdef LOG_DMA2
- //else
- {
- LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 0, DMASrc[proc][0], DMADst[proc][0], (val&(1<<25))?"ON":"OFF");
- }
- #endif
- }
- return;
- case REG_DMA1CNTH :
- {
- u32 v;
- //if(val&0x8000) execute = FALSE;
- //LOG("16 bit dma1 %04X\r\n", val);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xC6, val);
- DMASrc[proc][1] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xBC);
- DMASrc[proc][1] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xC0);
- v = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xC4);
- MMU.DMAStartTime[proc][1] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7);
- MMU.DMACrt[proc][1] = v;
- if(MMU.DMAStartTime[proc][1] == 0)
- MMU_doDMA(proc, 1);
- #ifdef LOG_DMA2
- //else
- {
- LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 1, DMASrc[proc][1], DMADst[proc][1], (val&(1<<25))?"ON":"OFF");
- }
- #endif
- }
- return;
- case REG_DMA2CNTH :
- {
- u32 v;
- //if(val&0x8000) execute = FALSE;
- //LOG("16 bit dma2 %04X\r\n", val);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xD2, val);
- DMASrc[proc][2] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xC8);
- DMASrc[proc][2] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xCC);
- v = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xD0);
- MMU.DMAStartTime[proc][2] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7);
- MMU.DMACrt[proc][2] = v;
- if(MMU.DMAStartTime[proc][2] == 0)
- MMU_doDMA(proc, 2);
- #ifdef LOG_DMA2
- //else
- {
- LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 2, DMASrc[proc][2], DMADst[proc][2], (val&(1<<25))?"ON":"OFF");
- }
- #endif
- }
- return;
- case REG_DMA3CNTH :
- {
- u32 v;
- //if(val&0x8000) execute = FALSE;
- //LOG("16 bit dma3 %04X\r\n", val);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xDE, val);
- DMASrc[proc][3] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xD4);
- DMASrc[proc][3] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xD8);
- v = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xDC);
- MMU.DMAStartTime[proc][3] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7);
- MMU.DMACrt[proc][3] = v;
-
- if(MMU.DMAStartTime[proc][3] == 0)
- MMU_doDMA(proc, 3);
- #ifdef LOG_DMA2
- //else
- {
- LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 3, DMASrc[proc][3], DMADst[proc][3], (val&(1<<25))?"ON":"OFF");
- }
- #endif
- }
- return;
- //case REG_AUXSPICNT : execute = FALSE;
- default :
- T1WriteWord(MMU.MMU_MEM[proc][0x40], adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF], val);
- return;
- }
- }
- T1WriteWord(MMU.MMU_MEM[proc][(adr>>20)&0xFF], adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF], val);
-}
-
-
-void FASTCALL MMU_write32(u32 proc, u32 adr, u32 val)
-{
-#ifdef INTERNAL_DTCM_WRITE
- if((proc==ARMCPU_ARM9)&((adr&(~0x3FFF))==MMU.DTCMRegion))
- {
- T1WriteLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF, val);
- return ;
- }
-#endif
-
- // CFlash writing, Mic
- if ((adr>=0x9000000)&&(adr<0x9900000)) {
- cflash_write(adr,val);
- return;
- }
-
- adr &= 0x0FFFFFFF;
-
- // This is bad, remove it
- if(proc == ARMCPU_ARM7)
- {
- if ((adr>=0x04000400)&&(adr<0x0400051D))
- {
- SPU_WriteLong(adr, val);
- return;
- }
- }
-
- if ((adr & 0xFF800000) == 0x04800000) {
- /* access to non regular hw registers */
- /* return to not overwrite valid data */
- return ;
- } ;
-
-
- if((adr>>24)==4)
- {
- if (adr >= 0x04000400 && adr < 0x04000440)
- {
- // Geometry commands (aka Dislay Lists) - Parameters:X
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x400>>2] = val;
-#if VIO2SF_GPU_ENABLE
- if(proc==ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_CallList(val);
- }
-#endif
- }
- else
- switch(adr)
- {
-#if VIO2SF_GPU_ENABLE
- // Alpha test reference value - Parameters:1
- case 0x04000340:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x340>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_AlphaFunc(val);
- }
- return;
- }
- // Clear background color setup - Parameters:2
- case 0x04000350:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x350>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_ClearColor(val);
- }
- return;
- }
- // Clear background depth setup - Parameters:2
- case 0x04000354:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x354>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_ClearDepth(val);
- }
- return;
- }
- // Fog Color - Parameters:4b
- case 0x04000358:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x358>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_FogColor(val);
- }
- return;
- }
- case 0x0400035C:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x35C>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_FogOffset(val);
- }
- return;
- }
- // Matrix mode - Parameters:1
- case 0x04000440:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x440>>2] = val;
-
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_MatrixMode(val);
- }
- return;
- }
- // Push matrix - Parameters:0
- case 0x04000444:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x444>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_PushMatrix();
- }
- return;
- }
- // Pop matrix/es - Parameters:1
- case 0x04000448:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x448>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_PopMatrix(val);
- }
- return;
- }
- // Store matrix in the stack - Parameters:1
- case 0x0400044C:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x44C>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_StoreMatrix(val);
- }
- return;
- }
- // Restore matrix from the stack - Parameters:1
- case 0x04000450:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x450>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_RestoreMatrix(val);
- }
- return;
- }
- // Load Identity matrix - Parameters:0
- case 0x04000454:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x454>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_LoadIdentity();
- }
- return;
- }
- // Load 4x4 matrix - Parameters:16
- case 0x04000458:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x458>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_LoadMatrix4x4(val);
- }
- return;
- }
- // Load 4x3 matrix - Parameters:12
- case 0x0400045C:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x45C>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_LoadMatrix4x3(val);
- }
- return;
- }
- // Multiply 4x4 matrix - Parameters:16
- case 0x04000460:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x460>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_MultMatrix4x4(val);
- }
- return;
- }
- // Multiply 4x4 matrix - Parameters:12
- case 0x04000464:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x464>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_MultMatrix4x3(val);
- }
- return;
- }
- // Multiply 3x3 matrix - Parameters:9
- case 0x04000468 :
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x468>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_MultMatrix3x3(val);
- }
- return;
- }
- // Multiply current matrix by scaling matrix - Parameters:3
- case 0x0400046C:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x46C>>2] = val;
- if(proc==ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Scale(val);
- }
- return;
- }
- // Multiply current matrix by translation matrix - Parameters:3
- case 0x04000470:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x470>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Translate(val);
- }
- return;
- }
- // Set vertex color - Parameters:1
- case 0x04000480:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x480>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Color3b(val);
- }
- return;
- }
- // Set vertex normal - Parameters:1
- case 0x04000484:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x484>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Normal(val);
- }
- return;
- }
- // Set vertex texture coordinate - Parameters:1
- case 0x04000488:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x488>>2] = val;
- if(proc==ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_TexCoord(val);
- }
- return;
- }
- // Set vertex position 16b/coordinate - Parameters:2
- case 0x0400048C:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x48C>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Vertex16b(val);
- }
- return;
- }
- // Set vertex position 10b/coordinate - Parameters:1
- case 0x04000490:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x490>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Vertex10b(val);
- }
- return;
- }
- // Set vertex XY position - Parameters:1
- case 0x04000494:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x494>>2] = val;
- if(proc==ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Vertex3_cord(0,1,val);
- }
- return;
- }
- // Set vertex XZ position - Parameters:1
- case 0x04000498:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x498>>2] = val;
- if(proc==ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Vertex3_cord(0,2,val);
- }
- return;
- }
- // Set vertex YZ position - Parameters:1
- case 0x0400049C:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x49C>>2] = val;
- if(proc==ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Vertex3_cord(1,2,val);
- }
- return;
- }
- // Set vertex difference position (offset from the last vertex) - Parameters:1
- case 0x040004A0:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4A0>>2] = val;
- if(proc==ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Vertex_rel (val);
- }
- return;
- }
- // Set polygon attributes - Parameters:1
- case 0x040004A4:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4A4>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_PolygonAttrib(val);
- }
- return;
- }
- // Set texture parameteres - Parameters:1
- case 0x040004A8:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4A8>>2] = val;
- if(proc==ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_TexImage(val);
- }
- return;
- }
- // Set palette base address - Parameters:1
- case 0x040004AC:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4AC>>2] = val&0x1FFF;
- if(proc==ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_TexPalette(val&0x1FFFF);
- }
- return;
- }
- // Set material diffuse/ambient parameters - Parameters:1
- case 0x040004C0:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4C0>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Material0 (val);
- }
- return;
- }
- // Set material reflection/emission parameters - Parameters:1
- case 0x040004C4:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4C4>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Material1 (val);
- }
- return;
- }
- // Light direction vector - Parameters:1
- case 0x040004C8:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4C8>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_LightDirection (val);
- }
- return;
- }
- // Light color - Parameters:1
- case 0x040004CC:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4CC>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_LightColor(val);
- }
- return;
- }
- // Material Shininess - Parameters:32
- case 0x040004D0:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4D0>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Shininess(val);
- }
- return;
- }
- // Begin vertex list - Parameters:1
- case 0x04000500:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x500>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Begin(val);
- }
- return;
- }
- // End vertex list - Parameters:0
- case 0x04000504:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x504>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_End();
- }
- return;
- }
- // Swap rendering engine buffers - Parameters:1
- case 0x04000540:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x540>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_Flush(val);
- }
- return;
- }
- // Set viewport coordinates - Parameters:1
- case 0x04000580:
- {
- ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x580>>2] = val;
- if(proc == ARMCPU_ARM9)
- {
- gpu3D->NDS_3D_ViewPort(val);
- }
- return;
- }
-#endif
-
- case REG_DISPA_WININ:
- {
- if(proc == ARMCPU_ARM9)
- {
- GPU_setWININ (MainScreen.gpu, val & 0xFFFF) ;
- GPU_setWINOUT16 (MainScreen.gpu, (val >> 16) & 0xFFFF) ;
- }
- break;
- }
- case REG_DISPB_WININ:
- {
- if(proc == ARMCPU_ARM9)
- {
- GPU_setWININ (SubScreen.gpu, val & 0xFFFF) ;
- GPU_setWINOUT16 (SubScreen.gpu, (val >> 16) & 0xFFFF) ;
- }
- break;
- }
-
- case REG_DISPA_BLDCNT:
- {
- if (proc == ARMCPU_ARM9)
- {
- GPU_setBLDCNT (MainScreen.gpu,val&0xffff);
- GPU_setBLDALPHA (MainScreen.gpu,val>>16);
- }
- break;
- }
- case REG_DISPB_BLDCNT:
- {
- if (proc == ARMCPU_ARM9)
- {
- GPU_setBLDCNT (SubScreen.gpu,val&0xffff);
- GPU_setBLDALPHA (SubScreen.gpu,val>>16);
- }
- break;
- }
-/*
- // Commented out, as this doesn't use the plug-in system, neither works
- case cmd_3D_MTX_MODE // 0x04000440 :
- if (proc == ARMCPU_ARM9) gl_MTX_MODE(val);
- return;
- case cmd_3D_MTX_PUSH // 0x04000444 :
- case cmd_3D_MTX_POP // 0x04000448 :
- case cmd_3D_MTX_STORE // 0x0400044C :
- case cmd_3D_MTX_RESTORE // 0x04000450 :
- if (proc == ARMCPU_ARM9) gl_print_cmd(adr);
- return;
- case cmd_3D_MTX_IDENTITY // 0x04000454 :
- if (proc == ARMCPU_ARM9) gl_MTX_IDENTITY();
- return;
- case cmd_3D_MTX_LOAD_4x4 // 0x04000458 :
- if (proc == ARMCPU_ARM9) gl_MTX_LOAD_4x4(val);
- return;
- case cmd_3D_MTX_LOAD_4x3 // 0x0400045C :
- if (proc == ARMCPU_ARM9) gl_MTX_LOAD_4x3(val);
- return;
- case cmd_3D_MTX_MULT_4x4 // 0x04000460 :
- if (proc == ARMCPU_ARM9) gl_MTX_MULT_4x4(val);
- return;
- case cmd_3D_MTX_MULT_4x3 // 0x04000464 :
- if (proc == ARMCPU_ARM9) gl_MTX_MULT_4x3(val);
- return;
- case cmd_3D_MTX_MULT_3x3 // 0x04000468 :
- if (proc == ARMCPU_ARM9) gl_MTX_MULT_3x3(val);
- return;
- case cmd_3D_MTX_SCALE // 0x0400046C :
- case cmd_3D_MTX_TRANS // 0x04000470 :
- case cmd_3D_COLOR // 0x04000480 :
- case cmd_3D_NORMA // 0x04000484 :
- if (proc == ARMCPU_ARM9) gl_print_cmd(adr);
- return;
- case cmd_3D_TEXCOORD // 0x04000488 :
- if (proc == ARMCPU_ARM9) gl_TEXCOORD(val);
- return;
- case cmd_3D_VTX_16 // 0x0400048C :
- if (proc == ARMCPU_ARM9) gl_VTX_16(val);
- return;
- case cmd_3D_VTX_10 // 0x04000490 :
- if (proc == ARMCPU_ARM9) gl_VTX_10(val);
- return;
- case cmd_3D_VTX_XY // 0x04000494 :
- if (proc == ARMCPU_ARM9) gl_VTX_XY(val);
- return;
- case cmd_3D_VTX_XZ // 0x04000498 :
- if (proc == ARMCPU_ARM9) gl_VTX_XZ(val);
- return;
- case cmd_3D_VTX_YZ // 0x0400049C :
- if (proc == ARMCPU_ARM9) gl_VTX_YZ(val);
- return;
- case cmd_3D_VTX_DIFF // 0x040004A0 :
- if (proc == ARMCPU_ARM9) gl_VTX_DIFF(val);
- return;
- case cmd_3D_POLYGON_ATTR // 0x040004A4 :
- case cmd_3D_TEXIMAGE_PARAM // 0x040004A8 :
- case cmd_3D_PLTT_BASE // 0x040004AC :
- case cmd_3D_DIF_AMB // 0x040004C0 :
- case cmd_3D_SPE_EMI // 0x040004C4 :
- case cmd_3D_LIGHT_VECTOR // 0x040004C8 :
- case cmd_3D_LIGHT_COLOR // 0x040004CC :
- case cmd_3D_SHININESS // 0x040004D0 :
- if (proc == ARMCPU_ARM9) gl_print_cmd(adr);
- return;
- case cmd_3D_BEGIN_VTXS // 0x04000500 :
- if (proc == ARMCPU_ARM9) gl_VTX_begin(val);
- return;
- case cmd_3D_END_VTXS // 0x04000504 :
- if (proc == ARMCPU_ARM9) gl_VTX_end();
- return;
- case cmd_3D_SWAP_BUFFERS // 0x04000540 :
- case cmd_3D_VIEWPORT // 0x04000580 :
- case cmd_3D_BOX_TEST // 0x040005C0 :
- case cmd_3D_POS_TEST // 0x040005C4 :
- case cmd_3D_VEC_TEST // 0x040005C8 :
- if (proc == ARMCPU_ARM9) gl_print_cmd(adr);
- return;
-*/
- case REG_DISPA_DISPCNT :
- if(proc == ARMCPU_ARM9) GPU_setVideoProp(MainScreen.gpu, val);
-
- //GPULOG("MAIN INIT 32B %08X\r\n", val);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0, val);
- return;
-
- case REG_DISPB_DISPCNT :
- if (proc == ARMCPU_ARM9) GPU_setVideoProp(SubScreen.gpu, val);
- //GPULOG("SUB INIT 32B %08X\r\n", val);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x1000, val);
- return;
- case REG_VRAMCNTA:
- case REG_VRAMCNTE:
- MMU_write8(proc,adr,val & 0xFF) ;
- MMU_write8(proc,adr+1,val >> 8) ;
- MMU_write8(proc,adr+2,val >> 16) ;
- MMU_write8(proc,adr+3,val >> 24) ;
- return ;
- case REG_VRAMCNTI:
- MMU_write8(proc,adr,val & 0xFF) ;
- return ;
-
- case REG_IME : {
- u32 old_val = MMU.reg_IME[proc];
- u32 new_val = val & 1;
- MMU.reg_IME[proc] = new_val;
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x208, val);
- if ( new_val && old_val != new_val) {
- /* raise an interrupt request to the CPU if needed */
- if ( MMU.reg_IE[proc] & MMU.reg_IF[proc]) {
- NDS_ARM7.wIRQ = TRUE;
- NDS_ARM7.waitIRQ = FALSE;
- }
- }
- return;
- }
-
- case REG_IE :
- MMU.reg_IE[proc] = val;
- if ( MMU.reg_IME[proc]) {
- /* raise an interrupt request to the CPU if needed */
- if ( MMU.reg_IE[proc] & MMU.reg_IF[proc]) {
- NDS_ARM7.wIRQ = TRUE;
- NDS_ARM7.waitIRQ = FALSE;
- }
- }
- return;
-
- case REG_IF :
- MMU.reg_IF[proc] &= (~val);
- return;
- case REG_TM0CNTL :
- case REG_TM1CNTL :
- case REG_TM2CNTL :
- case REG_TM3CNTL :
- MMU.timerReload[proc][(adr>>2)&0x3] = (u16)val;
- if(val&0x800000)
- {
- MMU.timer[proc][(adr>>2)&0x3] = MMU.timerReload[proc][(adr>>2)&0x3];
- }
- MMU.timerON[proc][(adr>>2)&0x3] = val & 0x800000;
- switch((val>>16)&7)
- {
- case 0 :
- MMU.timerMODE[proc][(adr>>2)&0x3] = 0+1;//proc;
- break;
- case 1 :
- MMU.timerMODE[proc][(adr>>2)&0x3] = 6+1;//proc;
- break;
- case 2 :
- MMU.timerMODE[proc][(adr>>2)&0x3] = 8+1;//proc;
- break;
- case 3 :
- MMU.timerMODE[proc][(adr>>2)&0x3] = 10+1;//proc;
- break;
- default :
- MMU.timerMODE[proc][(adr>>2)&0x3] = 0xFFFF;
- break;
- }
- if(!(val & 0x800000))
- {
- MMU.timerRUN[proc][(adr>>2)&0x3] = FALSE;
- }
- T1WriteLong(MMU.MMU_MEM[proc][0x40], adr & 0xFFF, val);
- return;
- case REG_DIVDENOM :
- {
- u16 cnt;
- s64 num = 0;
- s64 den = 1;
- s64 res;
- s64 mod;
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x298, val);
- cnt = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x280);
- switch(cnt&3)
- {
- case 0:
- {
- num = (s64) (s32) T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x290);
- den = (s64) (s32) T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x298);
- }
- break;
- case 1:
- {
- num = (s64) T1ReadQuad(MMU.MMU_MEM[proc][0x40], 0x290);
- den = (s64) (s32) T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x298);
- }
- break;
- case 2:
- {
- return;
- }
- break;
- default:
- break;
- }
- if(den==0)
- {
- res = 0;
- mod = 0;
- cnt |= 0x4000;
- cnt &= 0x7FFF;
- }
- else
- {
- res = num / den;
- mod = num % den;
- cnt &= 0x3FFF;
- }
- DIVLOG("BOUT1 %08X%08X / %08X%08X = %08X%08X\r\n", (u32)(num>>32), (u32)num,
- (u32)(den>>32), (u32)den,
- (u32)(res>>32), (u32)res);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2A0, (u32) res);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2A4, (u32) (res >> 32));
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2A8, (u32) mod);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2AC, (u32) (mod >> 32));
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x280, cnt);
- }
- return;
- case REG_DIVDENOM+4 :
- {
- u16 cnt;
- s64 num = 0;
- s64 den = 1;
- s64 res;
- s64 mod;
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x29C, val);
- cnt = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x280);
- switch(cnt&3)
- {
- case 0:
- {
- return;
- }
- break;
- case 1:
- {
- return;
- }
- break;
- case 2:
- {
- num = (s64) T1ReadQuad(MMU.MMU_MEM[proc][0x40], 0x290);
- den = (s64) T1ReadQuad(MMU.MMU_MEM[proc][0x40], 0x298);
- }
- break;
- default:
- break;
- }
- if(den==0)
- {
- res = 0;
- mod = 0;
- cnt |= 0x4000;
- cnt &= 0x7FFF;
- }
- else
- {
- res = num / den;
- mod = num % den;
- cnt &= 0x3FFF;
- }
- DIVLOG("BOUT2 %08X%08X / %08X%08X = %08X%08X\r\n", (u32)(num>>32), (u32)num,
- (u32)(den>>32), (u32)den,
- (u32)(res>>32), (u32)res);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2A0, (u32) res);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2A4, (u32) (res >> 32));
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2A8, (u32) mod);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2AC, (u32) (mod >> 32));
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x280, cnt);
- }
- return;
- case REG_SQRTPARAM :
- {
- u16 cnt;
- u64 v = 1;
- //execute = FALSE;
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2B8, val);
- cnt = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x2B0);
- switch(cnt&1)
- {
- case 0:
- v = (u64) T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x2B8);
- break;
- case 1:
- return;
- }
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2B4, (u32) sqrt((s64)v));
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2B0, cnt & 0x7FFF);
- SQRTLOG("BOUT1 sqrt(%08X%08X) = %08X\r\n", (u32)(v>>32), (u32)v,
- T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x2B4));
- }
- return;
- case REG_SQRTPARAM+4 :
- {
- u16 cnt;
- u64 v = 1;
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2BC, val);
- cnt = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x2B0);
- switch(cnt&1)
- {
- case 0:
- return;
- //break;
- case 1:
- v = T1ReadQuad(MMU.MMU_MEM[proc][0x40], 0x2B8);
- break;
- }
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2B4, (u32) sqrt((s64)v));
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2B0, cnt & 0x7FFF);
- SQRTLOG("BOUT2 sqrt(%08X%08X) = %08X\r\n", (u32)(v>>32), (u32)v,
- T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x2B4));
- }
- return;
- case REG_IPCSYNC :
- {
- //execute=FALSE;
- u32 remote = (proc+1)&1;
- u32 IPCSYNC_remote = T1ReadLong(MMU.MMU_MEM[remote][0x40], 0x180);
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x180, (val&0xFFF0)|((IPCSYNC_remote>>8)&0xF));
- T1WriteLong(MMU.MMU_MEM[remote][0x40], 0x180, (IPCSYNC_remote&0xFFF0)|((val>>8)&0xF));
- MMU.reg_IF[remote] |= ((IPCSYNC_remote & (1<<14))<<2) & ((val & (1<<13))<<3);// & (MMU.reg_IME[remote] << 16);// & (MMU.reg_IE[remote] & (1<<16));//
- }
- return;
- case REG_IPCFIFOCNT :
- {
- u32 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184) ;
- u32 cnt_r = T1ReadWord(MMU.MMU_MEM[(proc+1) & 1][0x40], 0x184) ;
- if ((val & 0x8000) && !(cnt_l & 0x8000))
- {
- /* this is the first init, the other side didnt init yet */
- /* so do a complete init */
- FIFOInit(MMU.fifos + (IPCFIFO+proc));
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184,0x8101) ;
- /* and then handle it as usual */
- }
- if(val & 0x4008)
- {
- FIFOInit(MMU.fifos + (IPCFIFO+((proc+1)&1)));
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, (cnt_l & 0x0301) | (val & 0x8404) | 1);
- T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, (cnt_r & 0xC507) | 0x100);
- MMU.reg_IF[proc] |= ((val & 4)<<15);// & (MMU.reg_IME[proc]<<17);// & (MMU.reg_IE[proc]&0x20000);//
- return;
- }
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, val & 0xBFF4);
- //execute = FALSE;
- return;
- }
- case REG_IPCFIFOSEND :
- {
- u16 IPCFIFO_CNT = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184);
- if(IPCFIFO_CNT&0x8000)
- {
- //if(val==43) execute = FALSE;
- u32 remote = (proc+1)&1;
- u32 fifonum = IPCFIFO+remote;
- u16 IPCFIFO_CNT_remote;
- FIFOAdd(MMU.fifos + fifonum, val);
- IPCFIFO_CNT = (IPCFIFO_CNT & 0xFFFC) | (MMU.fifos[fifonum].full<<1);
- IPCFIFO_CNT_remote = T1ReadWord(MMU.MMU_MEM[remote][0x40], 0x184);
- IPCFIFO_CNT_remote = (IPCFIFO_CNT_remote & 0xFCFF) | (MMU.fifos[fifonum].full<<10);
- T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, IPCFIFO_CNT);
- T1WriteWord(MMU.MMU_MEM[remote][0x40], 0x184, IPCFIFO_CNT_remote);
- MMU.reg_IF[remote] |= ((IPCFIFO_CNT_remote & (1<<10))<<8);// & (MMU.reg_IME[remote] << 18);// & (MMU.reg_IE[remote] & 0x40000);//
- //execute = FALSE;
- }
- }
- return;
- case REG_DMA0CNTL :
- //LOG("32 bit dma0 %04X\r\n", val);
- DMASrc[proc][0] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xB0);
- DMADst[proc][0] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xB4);
- MMU.DMAStartTime[proc][0] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7);
- MMU.DMACrt[proc][0] = val;
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0xB8, val);
- if( MMU.DMAStartTime[proc][0] == 0 ||
- MMU.DMAStartTime[proc][0] == 7) // Start Immediately
- MMU_doDMA(proc, 0);
- #ifdef LOG_DMA2
- else
- {
- LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 0, DMASrc[proc][0], DMADst[proc][0], 0, ((MMU.DMACrt[proc][0]>>27)&7));
- }
- #endif
- //execute = FALSE;
- return;
- case REG_DMA1CNTL:
- //LOG("32 bit dma1 %04X\r\n", val);
- DMASrc[proc][1] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xBC);
- DMADst[proc][1] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xC0);
- MMU.DMAStartTime[proc][1] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7);
- MMU.DMACrt[proc][1] = val;
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0xC4, val);
- if(MMU.DMAStartTime[proc][1] == 0 ||
- MMU.DMAStartTime[proc][1] == 7) // Start Immediately
- MMU_doDMA(proc, 1);
- #ifdef LOG_DMA2
- else
- {
- LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 1, DMASrc[proc][1], DMADst[proc][1], 0, ((MMU.DMACrt[proc][1]>>27)&7));
- }
- #endif
- return;
- case REG_DMA2CNTL :
- //LOG("32 bit dma2 %04X\r\n", val);
- DMASrc[proc][2] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xC8);
- DMADst[proc][2] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xCC);
- MMU.DMAStartTime[proc][2] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7);
- MMU.DMACrt[proc][2] = val;
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0xD0, val);
- if(MMU.DMAStartTime[proc][2] == 0 ||
- MMU.DMAStartTime[proc][2] == 7) // Start Immediately
- MMU_doDMA(proc, 2);
- #ifdef LOG_DMA2
- else
- {
- LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 2, DMASrc[proc][2], DMADst[proc][2], 0, ((MMU.DMACrt[proc][2]>>27)&7));
- }
- #endif
- return;
- case 0x040000DC :
- //LOG("32 bit dma3 %04X\r\n", val);
- DMASrc[proc][3] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xD4);
- DMADst[proc][3] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xD8);
- MMU.DMAStartTime[proc][3] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7);
- MMU.DMACrt[proc][3] = val;
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0xDC, val);
- if( MMU.DMAStartTime[proc][3] == 0 ||
- MMU.DMAStartTime[proc][3] == 7) // Start Immediately
- MMU_doDMA(proc, 3);
- #ifdef LOG_DMA2
- else
- {
- LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 3, DMASrc[proc][3], DMADst[proc][3], 0, ((MMU.DMACrt[proc][3]>>27)&7));
- }
- #endif
- return;
- case REG_GCROMCTRL :
- {
- int i;
-
- if(MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT) == 0xB7)
- {
- MMU.dscard[proc].adress = (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+1) << 24) | (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+2) << 16) | (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+3) << 8) | (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+4));
- MMU.dscard[proc].transfer_count = 0x80;// * ((val>>24)&7));
- }
- else if (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT) == 0xB8)
- {
- // Get ROM chip ID
- val |= 0x800000; // Data-Word Status
- T1WriteLong(MMU.MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val);
- MMU.dscard[proc].adress = 0;
- }
- else
- {
- LOG("CARD command: %02X\n", MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT));
- }
-
- //CARDLOG("%08X : %08X %08X\r\n", adr, val, adresse[proc]);
- val |= 0x00800000;
-
- if(MMU.dscard[proc].adress == 0)
- {
- val &= ~0x80000000;
- T1WriteLong(MMU.MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val);
- return;
- }
- T1WriteLong(MMU.MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val);
-
- /* launch DMA if start flag was set to "DS Cart" */
- if(proc == ARMCPU_ARM7) i = 2;
- else i = 5;
-
- if(proc == ARMCPU_ARM9 && MMU.DMAStartTime[proc][0] == i) /* dma0/1 on arm7 can't start on ds cart event */
- {
- MMU_doDMA(proc, 0);
- return;
- }
- else if(proc == ARMCPU_ARM9 && MMU.DMAStartTime[proc][1] == i)
- {
- MMU_doDMA(proc, 1);
- return;
- }
- else if(MMU.DMAStartTime[proc][2] == i)
- {
- MMU_doDMA(proc, 2);
- return;
- }
- else if(MMU.DMAStartTime[proc][3] == i)
- {
- MMU_doDMA(proc, 3);
- return;
- }
- return;
-
- }
- return;
- case REG_DISPA_DISPCAPCNT :
- if(proc == ARMCPU_ARM9)
- {
- GPU_set_DISPCAPCNT(MainScreen.gpu,val);
- T1WriteLong(ARM9Mem.ARM9_REG, 0x64, val);
- }
- return;
-
- case REG_DISPA_BG0CNT :
- if (proc == ARMCPU_ARM9)
- {
- GPU_setBGProp(MainScreen.gpu, 0, (val&0xFFFF));
- GPU_setBGProp(MainScreen.gpu, 1, (val>>16));
- }
- //if((val>>16)==0x400) execute = FALSE;
- T1WriteLong(ARM9Mem.ARM9_REG, 8, val);
- return;
- case REG_DISPA_BG2CNT :
- if (proc == ARMCPU_ARM9)
- {
- GPU_setBGProp(MainScreen.gpu, 2, (val&0xFFFF));
- GPU_setBGProp(MainScreen.gpu, 3, (val>>16));
- }
- T1WriteLong(ARM9Mem.ARM9_REG, 0xC, val);
- return;
- case REG_DISPB_BG0CNT :
- if (proc == ARMCPU_ARM9)
- {
- GPU_setBGProp(SubScreen.gpu, 0, (val&0xFFFF));
- GPU_setBGProp(SubScreen.gpu, 1, (val>>16));
- }
- T1WriteLong(ARM9Mem.ARM9_REG, 0x1008, val);
- return;
- case REG_DISPB_BG2CNT :
- if (proc == ARMCPU_ARM9)
- {
- GPU_setBGProp(SubScreen.gpu, 2, (val&0xFFFF));
- GPU_setBGProp(SubScreen.gpu, 3, (val>>16));
- }
- T1WriteLong(ARM9Mem.ARM9_REG, 0x100C, val);
- return;
- case REG_DISPA_DISPMMEMFIFO:
- {
- // NOTE: right now, the capture unit is not taken into account,
- // I don't know is it should be handled here or
-
- FIFOAdd(MMU.fifos + MAIN_MEMORY_DISP_FIFO, val);
- break;
- }
- //case 0x21FDFF0 : if(val==0) execute = FALSE;
- //case 0x21FDFB0 : if(val==0) execute = FALSE;
- default :
- T1WriteLong(MMU.MMU_MEM[proc][0x40], adr & MMU.MMU_MASK[proc][(adr>>20)&0xFF], val);
- return;
- }
- }
- T1WriteLong(MMU.MMU_MEM[proc][(adr>>20)&0xFF], adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF], val);
-}
-
-
-void FASTCALL MMU_doDMA(u32 proc, u32 num)
-{
- u32 src = DMASrc[proc][num];
- u32 dst = DMADst[proc][num];
- u32 taille;
-
- if(src==dst)
- {
- T1WriteLong(MMU.MMU_MEM[proc][0x40], 0xB8 + (0xC*num), T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xB8 + (0xC*num)) & 0x7FFFFFFF);
- return;
- }
-
- if((!(MMU.DMACrt[proc][num]&(1<<31)))&&(!(MMU.DMACrt[proc][num]&(1<<25))))
- { /* not enabled and not to be repeated */
- MMU.DMAStartTime[proc][num] = 0;
- MMU.DMACycle[proc][num] = 0;
- //MMU.DMAing[proc][num] = FALSE;
- return;
- }
-
-
- /* word count */
- taille = (MMU.DMACrt[proc][num]&0xFFFF);
-
- // If we are in "Main memory display" mode just copy an entire
- // screen (256x192 pixels).
- // Reference: http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode
- // (under DISP_MMEM_FIFO)
- if ((MMU.DMAStartTime[proc][num]==4) && // Must be in main memory display mode
- (taille==4) && // Word must be 4
- (((MMU.DMACrt[proc][num]>>26)&1) == 1)) // Transfer mode must be 32bit wide
- taille = 256*192/2;
-
- if(MMU.DMAStartTime[proc][num] == 5)
- taille *= 0x80;
-
- MMU.DMACycle[proc][num] = taille + nds.cycles;
- MMU.DMAing[proc][num] = TRUE;
-
- DMALOG("proc %d, dma %d src %08X dst %08X start %d taille %d repeat %s %08X\r\n",
- proc, num, src, dst, MMU.DMAStartTime[proc][num], taille,
- (MMU.DMACrt[proc][num]&(1<<25))?"on":"off",MMU.DMACrt[proc][num]);
-
- if(!(MMU.DMACrt[proc][num]&(1<<25)))
- MMU.DMAStartTime[proc][num] = 0;
-
- // transfer
- {
- u32 i=0;
- // 32 bit or 16 bit transfer ?
- int sz = ((MMU.DMACrt[proc][num]>>26)&1)? 4 : 2;
- int dstinc,srcinc;
- int u=(MMU.DMACrt[proc][num]>>21);
- switch(u & 0x3) {
- case 0 : dstinc = sz; break;
- case 1 : dstinc = -sz; break;
- case 2 : dstinc = 0; break;
- case 3 : dstinc = sz; break; //reload
- }
- switch((u >> 2)&0x3) {
- case 0 : srcinc = sz; break;
- case 1 : srcinc = -sz; break;
- case 2 : srcinc = 0; break;
- case 3 : // reserved
- return;
- }
- if ((MMU.DMACrt[proc][num]>>26)&1)
- for(; i < taille; ++i)
- {
- MMU_write32(proc, dst, MMU_read32(proc, src));
- dst += dstinc;
- src += srcinc;
- }
- else
- for(; i < taille; ++i)
- {
- MMU_write16(proc, dst, MMU_read16(proc, src));
- dst += dstinc;
- src += srcinc;
- }
- }
-}
-
-#ifdef MMU_ENABLE_ACL
-
-INLINE void check_access(u32 adr, u32 access) {
- /* every other mode: sys */
- access |= 1;
- if ((NDS_ARM9.CPSR.val & 0x1F) == 0x10) {
- /* is user mode access */
- access ^= 1 ;
- }
- if (armcp15_isAccessAllowed((armcp15_t *)NDS_ARM9.coproc[15],adr,access)==FALSE) {
- execute = FALSE ;
- }
-}
-INLINE void check_access_write(u32 adr) {
- u32 access = CP15_ACCESS_WRITE;
- check_access(adr, access)
-}
-
-u8 FASTCALL MMU_read8_acl(u32 proc, u32 adr, u32 access)
-{
- /* on arm9 we need to check the MPU regions */
- if (proc == ARMCPU_ARM9)
- check_access(u32 adr, u32 access);
- return MMU_read8(proc,adr);
-}
-u16 FASTCALL MMU_read16_acl(u32 proc, u32 adr, u32 access)
-{
- /* on arm9 we need to check the MPU regions */
- if (proc == ARMCPU_ARM9)
- check_access(u32 adr, u32 access);
- return MMU_read16(proc,adr);
-}
-u32 FASTCALL MMU_read32_acl(u32 proc, u32 adr, u32 access)
-{
- /* on arm9 we need to check the MPU regions */
- if (proc == ARMCPU_ARM9)
- check_access(u32 adr, u32 access);
- return MMU_read32(proc,adr);
-}
-
-void FASTCALL MMU_write8_acl(u32 proc, u32 adr, u8 val)
-{
- /* check MPU region on ARM9 */
- if (proc == ARMCPU_ARM9)
- check_access_write(adr);
- MMU_write8(proc,adr,val);
-}
-void FASTCALL MMU_write16_acl(u32 proc, u32 adr, u16 val)
-{
- /* check MPU region on ARM9 */
- if (proc == ARMCPU_ARM9)
- check_access_write(adr);
- MMU_write16(proc,adr,val) ;
-}
-void FASTCALL MMU_write32_acl(u32 proc, u32 adr, u32 val)
-{
- /* check MPU region on ARM9 */
- if (proc == ARMCPU_ARM9)
- check_access_write(adr);
- MMU_write32(proc,adr,val) ;
-}
-#endif
-
-
-
-#ifdef PROFILE_MEMORY_ACCESS
-
-#define PROFILE_PREFETCH 0
-#define PROFILE_READ 1
-#define PROFILE_WRITE 2
-
-struct mem_access_profile {
- u64 num_accesses;
- u32 address_mask;
- u32 masked_value;
-};
-
-#define PROFILE_NUM_MEM_ACCESS_PROFILES 4
-
-static u64 profile_num_accesses[2][3];
-static u64 profile_unknown_addresses[2][3];
-static struct mem_access_profile
-profile_memory_accesses[2][3][PROFILE_NUM_MEM_ACCESS_PROFILES];
-
-static void
-setup_profiling( void) {
- int i;
-
- for ( i = 0; i < 2; i++) {
- int access_type;
-
- for ( access_type = 0; access_type < 3; access_type++) {
- profile_num_accesses[i][access_type] = 0;
- profile_unknown_addresses[i][access_type] = 0;
-
- /*
- * Setup the access testing structures
- */
- profile_memory_accesses[i][access_type][0].address_mask = 0x0e000000;
- profile_memory_accesses[i][access_type][0].masked_value = 0x00000000;
- profile_memory_accesses[i][access_type][0].num_accesses = 0;
-
- /* main memory */
- profile_memory_accesses[i][access_type][1].address_mask = 0x0f000000;
- profile_memory_accesses[i][access_type][1].masked_value = 0x02000000;
- profile_memory_accesses[i][access_type][1].num_accesses = 0;
-
- /* shared memory */
- profile_memory_accesses[i][access_type][2].address_mask = 0x0f800000;
- profile_memory_accesses[i][access_type][2].masked_value = 0x03000000;
- profile_memory_accesses[i][access_type][2].num_accesses = 0;
-
- /* arm7 memory */
- profile_memory_accesses[i][access_type][3].address_mask = 0x0f800000;
- profile_memory_accesses[i][access_type][3].masked_value = 0x03800000;
- profile_memory_accesses[i][access_type][3].num_accesses = 0;
- }
- }
-}
-
-static void
-profile_memory_access( int arm9, u32 adr, int access_type) {
- static int first = 1;
- int mem_profile;
- int address_found = 0;
-
- if ( first) {
- setup_profiling();
- first = 0;
- }
-
- profile_num_accesses[arm9][access_type] += 1;
-
- for ( mem_profile = 0;
- mem_profile < PROFILE_NUM_MEM_ACCESS_PROFILES &&
- !address_found;
- mem_profile++) {
- if ( (adr & profile_memory_accesses[arm9][access_type][mem_profile].address_mask) ==
- profile_memory_accesses[arm9][access_type][mem_profile].masked_value) {
- /*printf( "adr %08x mask %08x res %08x expected %08x\n",
- adr,
- profile_memory_accesses[arm9][access_type][mem_profile].address_mask,
- adr & profile_memory_accesses[arm9][access_type][mem_profile].address_mask,
- profile_memory_accesses[arm9][access_type][mem_profile].masked_value);*/
- address_found = 1;
- profile_memory_accesses[arm9][access_type][mem_profile].num_accesses += 1;
- }
- }
-
- if ( !address_found) {
- profile_unknown_addresses[arm9][access_type] += 1;
- }
-}
-
-
-static const char *access_type_strings[] = {
- "prefetch",
- "read ",
- "write "
-};
-
-void
-print_memory_profiling( void) {
- int arm;
-
- printf("------ Memory access profile ------\n");
-
- for ( arm = 0; arm < 2; arm++) {
- int access_type;
-
- for ( access_type = 0; access_type < 3; access_type++) {
- int mem_profile;
- printf("ARM%c: num of %s %lld\n",
- arm ? '9' : '7',
- access_type_strings[access_type],
- profile_num_accesses[arm][access_type]);
-
- for ( mem_profile = 0;
- mem_profile < PROFILE_NUM_MEM_ACCESS_PROFILES;
- mem_profile++) {
- printf( "address %08lx: %llu\n",
- profile_memory_accesses[arm][access_type][mem_profile].masked_value,
- profile_memory_accesses[arm][access_type][mem_profile].num_accesses);
- }
-
- printf( "unknown addresses %lld\n",
- profile_unknown_addresses[arm][access_type]);
-
- printf( "\n");
- }
- }
-
- printf("------ End of Memory access profile ------\n\n");
-}
-#else
-void
-print_memory_profiling( void) {
-}
-#endif /* End of PROFILE_MEMORY_ACCESS area */
-
-static u16 FASTCALL
-arm9_prefetch16( void *data, u32 adr) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 1, adr, PROFILE_PREFETCH);
-#endif
-
-#ifdef EARLY_MEMORY_ACCESS
- if((adr & ~0x3FFF) == MMU.DTCMRegion)
- {
- /* Returns data from DTCM (ARM9 only) */
- return T1ReadWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
- }
- /* access to main memory */
- if ( (adr & 0x0f000000) == 0x02000000) {
- return T1ReadWord( MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF],
- adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
- }
-#endif
-
- return MMU_read16( ARMCPU_ARM9, adr);
-}
-static u32 FASTCALL
-arm9_prefetch32( void *data, u32 adr) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 1, adr, PROFILE_PREFETCH);
-#endif
-
-#ifdef EARLY_MEMORY_ACCESS
- if((adr & ~0x3FFF) == MMU.DTCMRegion)
- {
- /* Returns data from DTCM (ARM9 only) */
- return T1ReadLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
- }
- /* access to main memory */
- if ( (adr & 0x0f000000) == 0x02000000) {
- return T1ReadLong( MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF],
- adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
- }
-#endif
-
- return MMU_read32( ARMCPU_ARM9, adr);
-}
-
-static u8 FASTCALL
-arm9_read8( void *data, u32 adr) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 1, adr, PROFILE_READ);
-#endif
-
-#ifdef EARLY_MEMORY_ACCESS
- if( (adr&(~0x3FFF)) == MMU.DTCMRegion)
- {
- return ARM9Mem.ARM9_DTCM[adr&0x3FFF];
- }
- /* access to main memory */
- if ( (adr & 0x0f000000) == 0x02000000) {
- return MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF]
- [adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]];
- }
-#endif
-
- return MMU_read8( ARMCPU_ARM9, adr);
-}
-static u16 FASTCALL
-arm9_read16( void *data, u32 adr) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 1, adr, PROFILE_READ);
-#endif
-
-#ifdef EARLY_MEMORY_ACCESS
- if((adr & ~0x3FFF) == MMU.DTCMRegion)
- {
- /* Returns data from DTCM (ARM9 only) */
- return T1ReadWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
- }
-
- /* access to main memory */
- if ( (adr & 0x0f000000) == 0x02000000) {
- return T1ReadWord( MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF],
- adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
- }
-#endif
-
- return MMU_read16( ARMCPU_ARM9, adr);
-}
-static u32 FASTCALL
-arm9_read32( void *data, u32 adr) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 1, adr, PROFILE_READ);
-#endif
-
-#ifdef EARLY_MEMORY_ACCESS
- if((adr & ~0x3FFF) == MMU.DTCMRegion)
- {
- /* Returns data from DTCM (ARM9 only) */
- return T1ReadLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
- }
- /* access to main memory */
- if ( (adr & 0x0f000000) == 0x02000000) {
- return T1ReadLong( MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF],
- adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
- }
-#endif
-
- return MMU_read32( ARMCPU_ARM9, adr);
-}
-
-
-static void FASTCALL
-arm9_write8(void *data, u32 adr, u8 val) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 1, adr, PROFILE_WRITE);
-#endif
-
-#ifdef EARLY_MEMORY_ACCESS
- if( (adr & ~0x3FFF) == MMU.DTCMRegion)
- {
- /* Writes data in DTCM (ARM9 only) */
- ARM9Mem.ARM9_DTCM[adr&0x3FFF] = val;
- return ;
- }
- /* main memory */
- if ( (adr & 0x0f000000) == 0x02000000) {
- MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF]
- [adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF]] = val;
- return;
- }
-#endif
-
- MMU_write8( ARMCPU_ARM9, adr, val);
-}
-static void FASTCALL
-arm9_write16(void *data, u32 adr, u16 val) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 1, adr, PROFILE_WRITE);
-#endif
-
-#ifdef EARLY_MEMORY_ACCESS
- if((adr & ~0x3FFF) == MMU.DTCMRegion)
- {
- /* Writes in DTCM (ARM9 only) */
- T1WriteWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF, val);
- return;
- }
- /* main memory */
- if ( (adr & 0x0f000000) == 0x02000000) {
- T1WriteWord( MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF],
- adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF], val);
- return;
- }
-#endif
-
- MMU_write16( ARMCPU_ARM9, adr, val);
-}
-static void FASTCALL
-arm9_write32(void *data, u32 adr, u32 val) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 1, adr, PROFILE_WRITE);
-#endif
-
-#ifdef EARLY_MEMORY_ACCESS
- if((adr & ~0x3FFF) == MMU.DTCMRegion)
- {
- /* Writes in DTCM (ARM9 only) */
- T1WriteLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF, val);
- return;
- }
- /* main memory */
- if ( (adr & 0x0f000000) == 0x02000000) {
- T1WriteLong( MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF],
- adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF], val);
- return;
- }
-#endif
-
- MMU_write32( ARMCPU_ARM9, adr, val);
-}
-
-
-
-
-static u16 FASTCALL
-arm7_prefetch16( void *data, u32 adr) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 0, adr, PROFILE_PREFETCH);
-#endif
-
-#ifdef EARLY_MEMORY_ACCESS
- /* ARM7 private memory */
- if ( (adr & 0x0f800000) == 0x03800000) {
- T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][(adr >> 20) & 0xFF],
- adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr >> 20) & 0xFF]);
- }
-#endif
-
- return MMU_read16( ARMCPU_ARM7, adr);
-}
-static u32 FASTCALL
-arm7_prefetch32( void *data, u32 adr) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 0, adr, PROFILE_PREFETCH);
-#endif
-
-#ifdef EARLY_MEMORY_ACCESS
- /* ARM7 private memory */
- if ( (adr & 0x0f800000) == 0x03800000) {
- T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][(adr >> 20) & 0xFF],
- adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr >> 20) & 0xFF]);
- }
-#endif
-
- return MMU_read32( ARMCPU_ARM7, adr);
-}
-
-static u8 FASTCALL
-arm7_read8( void *data, u32 adr) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 0, adr, PROFILE_READ);
-#endif
-
- return MMU_read8( ARMCPU_ARM7, adr);
-}
-static u16 FASTCALL
-arm7_read16( void *data, u32 adr) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 0, adr, PROFILE_READ);
-#endif
-
- return MMU_read16( ARMCPU_ARM7, adr);
-}
-static u32 FASTCALL
-arm7_read32( void *data, u32 adr) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 0, adr, PROFILE_READ);
-#endif
-
- return MMU_read32( ARMCPU_ARM7, adr);
-}
-
-
-static void FASTCALL
-arm7_write8(void *data, u32 adr, u8 val) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 0, adr, PROFILE_WRITE);
-#endif
-
- MMU_write8( ARMCPU_ARM7, adr, val);
-}
-static void FASTCALL
-arm7_write16(void *data, u32 adr, u16 val) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 0, adr, PROFILE_WRITE);
-#endif
-
- MMU_write16( ARMCPU_ARM7, adr, val);
-}
-static void FASTCALL
-arm7_write32(void *data, u32 adr, u32 val) {
-#ifdef PROFILE_MEMORY_ACCESS
- profile_memory_access( 0, adr, PROFILE_WRITE);
-#endif
-
- MMU_write32( ARMCPU_ARM7, adr, val);
-}
-
-
-
-/*
- * the base memory interfaces
- */
-struct armcpu_memory_iface arm9_base_memory_iface = {
-#ifdef __GNUC__
- .prefetch32 = arm9_prefetch32,
- .prefetch16 = arm9_prefetch16,
-
- .read8 = arm9_read8,
- .read16 = arm9_read16,
- .read32 = arm9_read32,
-
- .write8 = arm9_write8,
- .write16 = arm9_write16,
- .write32 = arm9_write32
-#else
- arm9_prefetch32,
- arm9_prefetch16,
-
- arm9_read8,
- arm9_read16,
- arm9_read32,
-
- arm9_write8,
- arm9_write16,
- arm9_write32
-#endif
-};
-
-struct armcpu_memory_iface arm7_base_memory_iface = {
-#ifdef __GNUC__
- .prefetch32 = arm7_prefetch32,
- .prefetch16 = arm7_prefetch16,
-
- .read8 = arm7_read8,
- .read16 = arm7_read16,
- .read32 = arm7_read32,
-
- .write8 = arm7_write8,
- .write16 = arm7_write16,
- .write32 = arm7_write32
-#else
- arm7_prefetch32,
- arm7_prefetch16,
-
- arm7_read8,
- arm7_read16,
- arm7_read32,
-
- arm7_write8,
- arm7_write16,
- arm7_write32
-#endif
-};
-
-/*
- * The direct memory interface for the ARM9.
- * This avoids the ARM9 protection unit when accessing
- * memory.
- */
-struct armcpu_memory_iface arm9_direct_memory_iface = {
-#ifdef __GNUC__
- /* the prefetch is not used */
- .prefetch32 = NULL,
- .prefetch16 = NULL,
-
- .read8 = arm9_read8,
- .read16 = arm9_read16,
- .read32 = arm9_read32,
-
- .write8 = arm9_write8,
- .write16 = arm9_write16,
- .write32 = arm9_write32
-#else
- NULL,
- NULL,
-
- arm9_read8,
- arm9_read16,
- arm9_read32,
-
- arm9_write8,
- arm9_write16,
- arm9_write32
-#endif
-};
diff --git a/src/xsf/desmume/MMU.cc b/src/xsf/desmume/MMU.cc
new file mode 100644
index 000000000000..79e47ffb8521
--- /dev/null
+++ b/src/xsf/desmume/MMU.cc
@@ -0,0 +1,3526 @@
+/* Copyright (C) 2006 yopyop
+ yopyop156 at ifrance.com
+ yopyop156.ifrance.com
+
+ Copyright (C) 2007 shash
+
+ This file is part of DeSmuME
+
+ DeSmuME 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.
+
+ DeSmuME 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 DeSmuME; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+//#define RENDER3D
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+//#include "gl_vertex.h"
+
+#include "debug.h"
+#include "NDSSystem.h"
+//#include "cflash.h"
+#define cflash_read(a) 0
+#define cflash_write(a,d)
+#include "cp15.h"
+//#include "wifi.h"
+#include "registers.h"
+
+#if VIO2SF_GPU_ENABLE
+#include "render3D.h"
+#else
+#define GPU_setVideoProp(p1, p2)
+#define GPU_setBGProp(p1, p2, p3)
+
+#define GPU_setBLDCNT(p1, p2)
+#define GPU_setBLDALPHA(p1, p2)
+#define GPU_setBLDY(p1, p2)
+#define GPU_setMOSAIC(p1, p2)
+
+
+#define GPU_remove(p1,p2)
+#define GPU_addBack(p1,p2)
+
+#define GPU_ChangeGraphicsCore(p1) 0
+
+#define GPU_set_DISPCAPCNT(p1, p2)
+#define GPU_ligne(p1, p2)
+#define GPU_setMasterBrightness(p1, p2)
+
+#define GPU_setWIN0_H(p1, p2)
+#define GPU_setWIN0_H0(p1, p2)
+#define GPU_setWIN0_H1(p1, p2)
+
+#define GPU_setWIN0_V(p1, p2)
+#define GPU_setWIN0_V0(p1, p2)
+#define GPU_setWIN0_V1(p1, p2)
+
+#define GPU_setWIN1_H(p1, p2)
+#define GPU_setWIN1_H0(p1, p2)
+#define GPU_setWIN1_H1(p1, p2)
+
+#define GPU_setWIN1_V(p1, p2)
+#define GPU_setWIN1_V0(p1, p2)
+#define GPU_setWIN1_V1(p1, p2)
+
+#define GPU_setWININ(p1, p2)
+#define GPU_setWININ0(p1, p2)
+#define GPU_setWININ1(p1, p2)
+
+#define GPU_setWINOUT16(p1, p2)
+#define GPU_setWINOUT(p1, p2)
+#define GPU_setWINOBJ(p1, p2)
+
+#define GPU_setBLDCNT_LOW(p1, p2)
+#define GPU_setBLDCNT_HIGH(p1, p2)
+#define GPU_setBLDCNT(p1, p2)
+
+#define GPU_setBLDALPHA(p1, p2)
+#define GPU_setBLDALPHA_EVA(p1, p2)
+#define GPU_setBLDALPHA_EVB(p1, p2)
+
+#define GPU_setBLDY_EVY(p1, p2)
+#endif
+
+#define ROM_MASK 3
+
+/*
+ *
+ */
+//#define PROFILE_MEMORY_ACCESS 1
+#define EARLY_MEMORY_ACCESS 1
+
+#define INTERNAL_DTCM_READ 1
+#define INTERNAL_DTCM_WRITE 1
+
+//#define LOG_CARD
+//#define LOG_GPU
+//#define LOG_DMA
+//#define LOG_DMA2
+//#define LOG_DIV
+
+char szRomPath[512];
+char szRomBaseName[512];
+
+#define DUP2(x) x, x
+#define DUP4(x) x, x, x, x
+#define DUP8(x) x, x, x, x, x, x, x, x
+#define DUP16(x) x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x
+
+MMU_struct MMU;
+
+u8 * MMU_ARM9_MEM_MAP[256]={
+/* 0X*/ DUP16(ARM9Mem.ARM9_ITCM),
+/* 1X*/ //DUP16(ARM9Mem.ARM9_ITCM)
+/* 1X*/ DUP16(ARM9Mem.ARM9_WRAM),
+/* 2X*/ DUP16(ARM9Mem.MAIN_MEM),
+/* 3X*/ DUP16(MMU.SWIRAM),
+/* 4X*/ DUP16(ARM9Mem.ARM9_REG),
+/* 5X*/ DUP16(ARM9Mem.ARM9_VMEM),
+/* 6X*/ DUP2(ARM9Mem.ARM9_ABG),
+ DUP2(ARM9Mem.ARM9_BBG),
+ DUP2(ARM9Mem.ARM9_AOBJ),
+ DUP2(ARM9Mem.ARM9_BOBJ),
+ DUP8(ARM9Mem.ARM9_LCD),
+/* 7X*/ DUP16(ARM9Mem.ARM9_OAM),
+/* 8X*/ DUP16(nullptr),
+/* 9X*/ DUP16(nullptr),
+/* AX*/ DUP16(MMU.CART_RAM),
+/* BX*/ DUP16(MMU.UNUSED_RAM),
+/* CX*/ DUP16(MMU.UNUSED_RAM),
+/* DX*/ DUP16(MMU.UNUSED_RAM),
+/* EX*/ DUP16(MMU.UNUSED_RAM),
+/* FX*/ DUP16(ARM9Mem.ARM9_BIOS)
+};
+
+u32 MMU_ARM9_MEM_MASK[256]={
+/* 0X*/ DUP16(0x00007FFF),
+/* 1X*/ //DUP16(0x00007FFF)
+/* 1X*/ DUP16(0x00FFFFFF),
+/* 2X*/ DUP16(0x003FFFFF),
+/* 3X*/ DUP16(0x00007FFF),
+/* 4X*/ DUP16(0x00FFFFFF),
+/* 5X*/ DUP16(0x000007FF),
+/* 6X*/ DUP2(0x0007FFFF),
+ DUP2(0x0001FFFF),
+ DUP2(0x0003FFFF),
+ DUP2(0x0001FFFF),
+ DUP8(0x000FFFFF),
+/* 7X*/ DUP16(0x000007FF),
+/* 8X*/ DUP16(ROM_MASK),
+/* 9X*/ DUP16(ROM_MASK),
+/* AX*/ DUP16(0x0000FFFF),
+/* BX*/ DUP16(0x00000003),
+/* CX*/ DUP16(0x00000003),
+/* DX*/ DUP16(0x00000003),
+/* EX*/ DUP16(0x00000003),
+/* FX*/ DUP16(0x00007FFF)
+};
+
+u8 * MMU_ARM7_MEM_MAP[256]={
+/* 0X*/ DUP16(MMU.ARM7_BIOS),
+/* 1X*/ DUP16(MMU.UNUSED_RAM),
+/* 2X*/ DUP16(ARM9Mem.MAIN_MEM),
+/* 3X*/ DUP8(MMU.SWIRAM),
+ DUP8(MMU.ARM7_ERAM),
+/* 4X*/ DUP8(MMU.ARM7_REG),
+ DUP8(MMU.ARM7_WIRAM),
+/* 5X*/ DUP16(MMU.UNUSED_RAM),
+/* 6X*/ DUP16(ARM9Mem.ARM9_ABG),
+/* 7X*/ DUP16(MMU.UNUSED_RAM),
+/* 8X*/ DUP16(nullptr),
+/* 9X*/ DUP16(nullptr),
+/* AX*/ DUP16(MMU.CART_RAM),
+/* BX*/ DUP16(MMU.UNUSED_RAM),
+/* CX*/ DUP16(MMU.UNUSED_RAM),
+/* DX*/ DUP16(MMU.UNUSED_RAM),
+/* EX*/ DUP16(MMU.UNUSED_RAM),
+/* FX*/ DUP16(MMU.UNUSED_RAM)
+};
+
+u32 MMU_ARM7_MEM_MASK[256]={
+/* 0X*/ DUP16(0x00003FFF),
+/* 1X*/ DUP16(0x00000003),
+/* 2X*/ DUP16(0x003FFFFF),
+/* 3X*/ DUP8(0x00007FFF),
+ DUP8(0x0000FFFF),
+/* 4X*/ DUP8(0x00FFFFFF),
+ DUP8(0x0000FFFF),
+/* 5X*/ DUP16(0x00000003),
+/* 6X*/ DUP16(0x0003FFFF),
+/* 7X*/ DUP16(0x00000003),
+/* 8X*/ DUP16(ROM_MASK),
+/* 9X*/ DUP16(ROM_MASK),
+/* AX*/ DUP16(0x0000FFFF),
+/* BX*/ DUP16(0x00000003),
+/* CX*/ DUP16(0x00000003),
+/* DX*/ DUP16(0x00000003),
+/* EX*/ DUP16(0x00000003),
+/* FX*/ DUP16(0x00000003)
+};
+
+u32 MMU_ARM9_WAIT16[16]={
+ 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1,
+};
+
+u32 MMU_ARM9_WAIT32[16]={
+ 1, 1, 1, 1, 1, 2, 2, 1, 8, 8, 5, 1, 1, 1, 1, 1,
+};
+
+u32 MMU_ARM7_WAIT16[16]={
+ 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1,
+};
+
+u32 MMU_ARM7_WAIT32[16]={
+ 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 5, 1, 1, 1, 1, 1,
+};
+
+void MMU_Init(void) {
+ int i;
+
+ LOG("MMU init\n");
+
+ memset(&MMU, 0, sizeof(MMU_struct));
+
+ MMU.CART_ROM = MMU.UNUSED_RAM;
+
+ for(i = 0x80; i<0xA0; ++i)
+ {
+ MMU_ARM9_MEM_MAP[i] = MMU.CART_ROM;
+ MMU_ARM7_MEM_MAP[i] = MMU.CART_ROM;
+ }
+
+ MMU.MMU_MEM[0] = MMU_ARM9_MEM_MAP;
+ MMU.MMU_MEM[1] = MMU_ARM7_MEM_MAP;
+ MMU.MMU_MASK[0]= MMU_ARM9_MEM_MASK;
+ MMU.MMU_MASK[1] = MMU_ARM7_MEM_MASK;
+
+ MMU.ITCMRegion = 0x00800000;
+
+ MMU.MMU_WAIT16[0] = MMU_ARM9_WAIT16;
+ MMU.MMU_WAIT16[1] = MMU_ARM7_WAIT16;
+ MMU.MMU_WAIT32[0] = MMU_ARM9_WAIT32;
+ MMU.MMU_WAIT32[1] = MMU_ARM7_WAIT32;
+
+ for(i = 0;i < 16;i++)
+ FIFOInit(MMU.fifos + i);
+
+ mc_init(&MMU.fw, MC_TYPE_FLASH); /* init fw device */
+ mc_alloc(&MMU.fw, NDS_FW_SIZE_V1);
+ MMU.fw.fp = nullptr;
+
+ // Init Backup Memory device, this should really be done when the rom is loaded
+ mc_init(&MMU.bupmem, MC_TYPE_AUTODETECT);
+ mc_alloc(&MMU.bupmem, 1);
+ MMU.bupmem.fp = nullptr;
+
+}
+
+void MMU_DeInit(void) {
+ LOG("MMU deinit\n");
+// if (MMU.fw.fp)
+// fclose(MMU.fw.fp);
+ mc_free(&MMU.fw);
+// if (MMU.bupmem.fp)
+// fclose(MMU.bupmem.fp);
+ mc_free(&MMU.bupmem);
+}
+
+//Card rom & ram
+
+u16 SPI_CNT = 0;
+u16 SPI_CMD = 0;
+u16 AUX_SPI_CNT = 0;
+u16 AUX_SPI_CMD = 0;
+
+u32 rom_mask = 0;
+
+u32 DMASrc[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
+u32 DMADst[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
+
+void MMU_clearMem()
+{
+ int i;
+
+ memset(ARM9Mem.ARM9_ABG, 0, 0x080000);
+ memset(ARM9Mem.ARM9_AOBJ, 0, 0x040000);
+ memset(ARM9Mem.ARM9_BBG, 0, 0x020000);
+ memset(ARM9Mem.ARM9_BOBJ, 0, 0x020000);
+ memset(ARM9Mem.ARM9_DTCM, 0, 0x4000);
+ memset(ARM9Mem.ARM9_ITCM, 0, 0x8000);
+ memset(ARM9Mem.ARM9_LCD, 0, 0x0A4000);
+ memset(ARM9Mem.ARM9_OAM, 0, 0x0800);
+ memset(ARM9Mem.ARM9_REG, 0, 0x01000000);
+ memset(ARM9Mem.ARM9_VMEM, 0, 0x0800);
+ memset(ARM9Mem.ARM9_WRAM, 0, 0x01000000);
+ memset(ARM9Mem.MAIN_MEM, 0, 0x400000);
+
+ memset(ARM9Mem.blank_memory, 0, 0x020000);
+
+ memset(MMU.ARM7_ERAM, 0, 0x010000);
+ memset(MMU.ARM7_REG, 0, 0x010000);
+
+ for(i = 0;i < 16;i++)
+ FIFOInit(MMU.fifos + i);
+
+ MMU.DTCMRegion = 0;
+ MMU.ITCMRegion = 0x00800000;
+
+ memset(MMU.timer, 0, sizeof(u16) * 2 * 4);
+ memset(MMU.timerMODE, 0, sizeof(s32) * 2 * 4);
+ memset(MMU.timerON, 0, sizeof(u32) * 2 * 4);
+ memset(MMU.timerRUN, 0, sizeof(u32) * 2 * 4);
+ memset(MMU.timerReload, 0, sizeof(u16) * 2 * 4);
+
+ memset(MMU.reg_IME, 0, sizeof(u32) * 2);
+ memset(MMU.reg_IE, 0, sizeof(u32) * 2);
+ memset(MMU.reg_IF, 0, sizeof(u32) * 2);
+
+ memset(MMU.DMAStartTime, 0, sizeof(u32) * 2 * 4);
+ memset(MMU.DMACycle, 0, sizeof(s32) * 2 * 4);
+ memset(MMU.DMACrt, 0, sizeof(u32) * 2 * 4);
+ memset(MMU.DMAing, 0, sizeof(BOOL) * 2 * 4);
+
+ memset(MMU.dscard, 0, sizeof(nds_dscard) * 2);
+
+ MainScreen.offset = 192;
+ SubScreen.offset = 0;
+
+ /* setup the texture slot pointers */
+#if 0
+ ARM9Mem.textureSlotAddr[0] = ARM9Mem.blank_memory;
+ ARM9Mem.textureSlotAddr[1] = ARM9Mem.blank_memory;
+ ARM9Mem.textureSlotAddr[2] = ARM9Mem.blank_memory;
+ ARM9Mem.textureSlotAddr[3] = ARM9Mem.blank_memory;
+#else
+ ARM9Mem.textureSlotAddr[0] = &ARM9Mem.ARM9_LCD[0x20000 * 0];
+ ARM9Mem.textureSlotAddr[1] = &ARM9Mem.ARM9_LCD[0x20000 * 1];
+ ARM9Mem.textureSlotAddr[2] = &ARM9Mem.ARM9_LCD[0x20000 * 2];
+ ARM9Mem.textureSlotAddr[3] = &ARM9Mem.ARM9_LCD[0x20000 * 3];
+#endif
+}
+
+/* the VRAM blocks keep their content even when not blended in */
+/* to ensure that we write the content back to the LCD ram */
+/* FIXME: VRAM Bank E,F,G,H,I missing */
+void MMU_VRAMWriteBackToLCD(u8 block)
+{
+ u8 *destination;
+ u8 *source;
+ u32 size ;
+ u8 VRAMBankCnt;
+ #if 1
+ return ;
+ #endif
+ destination = 0 ;
+ source = 0;
+ VRAMBankCnt = MMU_read8(ARMCPU_ARM9,REG_VRAMCNTA+block) ;
+ switch (block)
+ {
+ case 0: // Bank A
+ destination = ARM9Mem.ARM9_LCD ;
+ size = 0x20000 ;
+ break ;
+ case 1: // Bank B
+ destination = ARM9Mem.ARM9_LCD + 0x20000 ;
+ size = 0x20000 ;
+ break ;
+ case 2: // Bank C
+ destination = ARM9Mem.ARM9_LCD + 0x40000 ;
+ size = 0x20000 ;
+ break ;
+ case 3: // Bank D
+ destination = ARM9Mem.ARM9_LCD + 0x60000 ;
+ size = 0x20000 ;
+ break ;
+ case 4: // Bank E
+ destination = ARM9Mem.ARM9_LCD + 0x80000 ;
+ size = 0x10000 ;
+ break ;
+ case 5: // Bank F
+ destination = ARM9Mem.ARM9_LCD + 0x90000 ;
+ size = 0x4000 ;
+ break ;
+ case 6: // Bank G
+ destination = ARM9Mem.ARM9_LCD + 0x94000 ;
+ size = 0x4000 ;
+ break ;
+ case 8: // Bank H
+ destination = ARM9Mem.ARM9_LCD + 0x98000 ;
+ size = 0x8000 ;
+ break ;
+ case 9: // Bank I
+ destination = ARM9Mem.ARM9_LCD + 0xA0000 ;
+ size = 0x4000 ;
+ break ;
+ default:
+ return ;
+ }
+ switch (VRAMBankCnt & 7) {
+ case 0:
+ /* vram is allready stored at LCD, we dont need to write it back */
+ MMU.vScreen = 1;
+ break ;
+ case 1:
+ switch(block){
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ /* banks are in use for BG at ABG + ofs * 0x20000 */
+ source = ARM9Mem.ARM9_ABG + ((VRAMBankCnt >> 3) & 3) * 0x20000 ;
+ break ;
+ case 4:
+ /* bank E is in use at ABG */
+ source = ARM9Mem.ARM9_ABG ;
+ break;
+ case 5:
+ case 6:
+ /* banks are in use for BG at ABG + (0x4000*OFS.0)+(0x10000*OFS.1)*/
+ source = ARM9Mem.ARM9_ABG + (((VRAMBankCnt >> 3) & 1) * 0x4000) + (((VRAMBankCnt >> 2) & 1) * 0x10000) ;
+ break;
+ case 8:
+ /* bank H is in use at BBG */
+ source = ARM9Mem.ARM9_BBG ;
+ break ;
+ case 9:
+ /* bank I is in use at BBG */
+ source = ARM9Mem.ARM9_BBG + 0x8000 ;
+ break;
+ default: return ;
+ }
+ break ;
+ case 2:
+ if (block < 2)
+ {
+ /* banks A,B are in use for OBJ at AOBJ + ofs * 0x20000 */
+ source = ARM9Mem.ARM9_AOBJ + ((VRAMBankCnt >> 3) & 1) * 0x20000 ;
+ } else return ;
+ break ;
+ case 4:
+ switch(block){
+ case 2:
+ /* bank C is in use at BBG */
+ source = ARM9Mem.ARM9_BBG ;
+ break ;
+ case 3:
+ /* bank D is in use at BOBJ */
+ source = ARM9Mem.ARM9_BOBJ ;
+ break ;
+ default: return ;
+ }
+ break ;
+ default:
+ return ;
+ }
+ if (!destination) return ;
+ if (!source) return ;
+ memcpy(destination,source,size) ;
+}
+
+void MMU_VRAMReloadFromLCD(u8 block,u8 VRAMBankCnt)
+{
+ u8 *destination;
+ u8 *source;
+ u32 size;
+ #if 1
+ return ;
+ #endif
+ destination = 0;
+ source = 0;
+ size = 0;
+ switch (block)
+ {
+ case 0: // Bank A
+ source = ARM9Mem.ARM9_LCD ;
+ size = 0x20000 ;
+ break ;
+ case 1: // Bank B
+ source = ARM9Mem.ARM9_LCD + 0x20000 ;
+ size = 0x20000 ;
+ break ;
+ case 2: // Bank C
+ source = ARM9Mem.ARM9_LCD + 0x40000 ;
+ size = 0x20000 ;
+ break ;
+ case 3: // Bank D
+ source = ARM9Mem.ARM9_LCD + 0x60000 ;
+ size = 0x20000 ;
+ break ;
+ case 4: // Bank E
+ source = ARM9Mem.ARM9_LCD + 0x80000 ;
+ size = 0x10000 ;
+ break ;
+ case 5: // Bank F
+ source = ARM9Mem.ARM9_LCD + 0x90000 ;
+ size = 0x4000 ;
+ break ;
+ case 6: // Bank G
+ source = ARM9Mem.ARM9_LCD + 0x94000 ;
+ size = 0x4000 ;
+ break ;
+ case 8: // Bank H
+ source = ARM9Mem.ARM9_LCD + 0x98000 ;
+ size = 0x8000 ;
+ break ;
+ case 9: // Bank I
+ source = ARM9Mem.ARM9_LCD + 0xA0000 ;
+ size = 0x4000 ;
+ break ;
+ default:
+ return ;
+ }
+ switch (VRAMBankCnt & 7) {
+ case 0:
+ /* vram is allready stored at LCD, we dont need to write it back */
+ MMU.vScreen = 1;
+ break ;
+ case 1:
+ if (block < 4)
+ {
+ /* banks are in use for BG at ABG + ofs * 0x20000 */
+ destination = ARM9Mem.ARM9_ABG + ((VRAMBankCnt >> 3) & 3) * 0x20000 ;
+ } else return ;
+ break ;
+ case 2:
+ switch(block){
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ /* banks are in use for BG at ABG + ofs * 0x20000 */
+ destination = ARM9Mem.ARM9_ABG + ((VRAMBankCnt >> 3) & 3) * 0x20000 ;
+ break ;
+ case 4:
+ /* bank E is in use at ABG */
+ destination = ARM9Mem.ARM9_ABG ;
+ break;
+ case 5:
+ case 6:
+ /* banks are in use for BG at ABG + (0x4000*OFS.0)+(0x10000*OFS.1)*/
+ destination = ARM9Mem.ARM9_ABG + (((VRAMBankCnt >> 3) & 1) * 0x4000) + (((VRAMBankCnt >> 2) & 1) * 0x10000) ;
+ break;
+ case 8:
+ /* bank H is in use at BBG */
+ destination = ARM9Mem.ARM9_BBG ;
+ break ;
+ case 9:
+ /* bank I is in use at BBG */
+ destination = ARM9Mem.ARM9_BBG + 0x8000 ;
+ break;
+ default: return ;
+ }
+ break ;
+ case 4:
+ switch(block){
+ case 2:
+ /* bank C is in use at BBG */
+ destination = ARM9Mem.ARM9_BBG ;
+ break ;
+ case 3:
+ /* bank D is in use at BOBJ */
+ destination = ARM9Mem.ARM9_BOBJ ;
+ break ;
+ default: return ;
+ }
+ break ;
+ default:
+ return ;
+ }
+ if (!destination) return ;
+ if (!source) return ;
+ memcpy(destination,source,size) ;
+}
+
+void MMU_setRom(u8 * rom, u32 mask)
+{
+ unsigned int i;
+ MMU.CART_ROM = rom;
+
+ for(i = 0x80; i<0xA0; ++i)
+ {
+ MMU_ARM9_MEM_MAP[i] = rom;
+ MMU_ARM7_MEM_MAP[i] = rom;
+ MMU_ARM9_MEM_MASK[i] = mask;
+ MMU_ARM7_MEM_MASK[i] = mask;
+ }
+ rom_mask = mask;
+}
+
+void MMU_unsetRom()
+{
+ unsigned int i;
+ MMU.CART_ROM=MMU.UNUSED_RAM;
+
+ for(i = 0x80; i<0xA0; ++i)
+ {
+ MMU_ARM9_MEM_MAP[i] = MMU.UNUSED_RAM;
+ MMU_ARM7_MEM_MAP[i] = MMU.UNUSED_RAM;
+ MMU_ARM9_MEM_MASK[i] = ROM_MASK;
+ MMU_ARM7_MEM_MASK[i] = ROM_MASK;
+ }
+ rom_mask = ROM_MASK;
+}
+char txt[80];
+
+u8 FASTCALL MMU_read8(u32 proc, u32 adr)
+{
+#ifdef INTERNAL_DTCM_READ
+ if((proc==ARMCPU_ARM9)&((adr&(~0x3FFF))==MMU.DTCMRegion))
+ {
+ return ARM9Mem.ARM9_DTCM[adr&0x3FFF];
+ }
+#endif
+
+ // CFlash reading, Mic
+ if ((adr>=0x9000000)&&(adr<0x9900000))
+ return (unsigned char)cflash_read(adr);
+
+#ifdef EXPERIMENTAL_WIFI
+ /* wifi mac access */
+ if ((proc==ARMCPU_ARM7) && (adr>=0x04800000)&&(adr<0x05000000))
+ {
+ if (adr & 1)
+ return (WIFI_read16(&wifiMac,adr) >> 8) & 0xFF;
+ else
+ return WIFI_read16(&wifiMac,adr) & 0xFF;
+ }
+#endif
+
+ return MMU.MMU_MEM[proc][(adr>>20)&0xFF][adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF]];
+}
+
+
+
+u16 FASTCALL MMU_read16(u32 proc, u32 adr)
+{
+#ifdef INTERNAL_DTCM_READ
+ if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion))
+ {
+ /* Returns data from DTCM (ARM9 only) */
+ return T1ReadWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
+ }
+#endif
+
+ // CFlash reading, Mic
+ if ((adr>=0x08800000)&&(adr<0x09900000))
+ return (unsigned short)cflash_read(adr);
+
+#ifdef EXPERIMENTAL_WIFI
+ /* wifi mac access */
+ if ((proc==ARMCPU_ARM7) && (adr>=0x04800000)&&(adr<0x05000000))
+ return WIFI_read16(&wifiMac,adr) ;
+#endif
+
+ adr &= 0x0FFFFFFF;
+
+ if(adr&0x04000000)
+ {
+ /* Adress is an IO register */
+ switch(adr)
+ {
+
+#if VIO2SF_GPU_ENABLE
+ case 0x04000604:
+ return (gpu3D->NDS_3D_GetNumPolys()&2047);
+ case 0x04000606:
+ return (gpu3D->NDS_3D_GetNumVertex()&8191);
+#endif
+
+ case REG_IPCFIFORECV : /* TODO (clear): ??? */
+ execute = false;
+ return 1;
+
+ case REG_IME :
+ return (u16)MMU.reg_IME[proc];
+
+ case REG_IE :
+ return (u16)MMU.reg_IE[proc];
+ case REG_IE + 2 :
+ return (u16)(MMU.reg_IE[proc]>>16);
+
+ case REG_IF :
+ return (u16)MMU.reg_IF[proc];
+ case REG_IF + 2 :
+ return (u16)(MMU.reg_IF[proc]>>16);
+
+ case REG_TM0CNTL :
+ case REG_TM1CNTL :
+ case REG_TM2CNTL :
+ case REG_TM3CNTL :
+ return MMU.timer[proc][(adr&0xF)>>2];
+
+ case 0x04000630 :
+ LOG("vect res\r\n"); /* TODO (clear): ??? */
+ //execute = false;
+ return 0;
+ case REG_POSTFLG :
+ return 1;
+ default :
+ break;
+ }
+ }
+
+ /* Returns data from memory */
+ return T1ReadWord(MMU.MMU_MEM[proc][(adr >> 20) & 0xFF], adr & MMU.MMU_MASK[proc][(adr >> 20) & 0xFF]);
+}
+
+u32 FASTCALL MMU_read32(u32 proc, u32 adr)
+{
+#ifdef INTERNAL_DTCM_READ
+ if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion))
+ {
+ /* Returns data from DTCM (ARM9 only) */
+ return T1ReadLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
+ }
+#endif
+
+ // CFlash reading, Mic
+ if ((adr>=0x9000000)&&(adr<0x9900000))
+ return (unsigned long)cflash_read(adr);
+
+ adr &= 0x0FFFFFFF;
+
+ if((adr >> 24) == 4)
+ {
+ /* Adress is an IO register */
+ switch(adr)
+ {
+ // This is hacked due to the only current 3D core
+ case 0x04000600:
+ {
+ u32 fifonum = IPCFIFO+proc;
+
+ u32 gxstat = (MMU.fifos[fifonum].empty<<26) |
+ (1<<25) |
+ (MMU.fifos[fifonum].full<<24) |
+ /*((NDS_nbpush[0]&1)<<13) | ((NDS_nbpush[2]&0x1F)<<8) |*/
+ 2;
+
+ LOG ("GXSTAT: 0x%X", gxstat);
+
+ return gxstat;
+ }
+
+ case 0x04000640:
+ case 0x04000644:
+ case 0x04000648:
+ case 0x0400064C:
+ case 0x04000650:
+ case 0x04000654:
+ case 0x04000658:
+ case 0x0400065C:
+ case 0x04000660:
+ case 0x04000664:
+ case 0x04000668:
+ case 0x0400066C:
+ case 0x04000670:
+ case 0x04000674:
+ case 0x04000678:
+ case 0x0400067C:
+ {
+ //LOG("4000640h..67Fh - CLIPMTX_RESULT - Read Current Clip Coordinates Matrix (R)");
+#if VIO2SF_GPU_ENABLE
+ return gpu3D->NDS_3D_GetClipMatrix ((adr-0x04000640)/4);
+#else
+ return 0;
+#endif
+ }
+ case 0x04000680:
+ case 0x04000684:
+ case 0x04000688:
+ case 0x0400068C:
+ case 0x04000690:
+ case 0x04000694:
+ case 0x04000698:
+ case 0x0400069C:
+ case 0x040006A0:
+ {
+#if VIO2SF_GPU_ENABLE
+ //LOG("4000680h..6A3h - VECMTX_RESULT - Read Current Directional Vector Matrix (R)");
+ return gpu3D->NDS_3D_GetDirectionalMatrix ((adr-0x04000680)/4);
+#else
+ return 0;
+#endif
+ }
+
+ case 0x4000604:
+ {
+#if VIO2SF_GPU_ENABLE
+ return (gpu3D->NDS_3D_GetNumPolys()&2047) & ((gpu3D->NDS_3D_GetNumVertex()&8191) << 16);
+ //LOG ("read32 - RAM_COUNT -> 0x%X", ((u32 *)(MMU.MMU_MEM[proc][(adr>>20)&0xFF]))[(adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF])>>2]);
+#else
+ return 0;
+#endif
+ }
+
+ case REG_IME :
+ return MMU.reg_IME[proc];
+ case REG_IE :
+ return MMU.reg_IE[proc];
+ case REG_IF :
+ return MMU.reg_IF[proc];
+ case REG_IPCFIFORECV :
+ {
+ u16 IPCFIFO_CNT = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184);
+ if(IPCFIFO_CNT&0x8000)
+ {
+ //execute = false;
+ u32 fifonum = IPCFIFO+proc;
+ u32 val = FIFOValue(MMU.fifos + fifonum);
+ u32 remote = (proc+1) & 1;
+ u16 IPCFIFO_CNT_remote = T1ReadWord(MMU.MMU_MEM[remote][0x40], 0x184);
+ IPCFIFO_CNT |= (MMU.fifos[fifonum].empty<<8) | (MMU.fifos[fifonum].full<<9) | (MMU.fifos[fifonum].error<<14);
+ IPCFIFO_CNT_remote |= (MMU.fifos[fifonum].empty) | (MMU.fifos[fifonum].full<<1);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, IPCFIFO_CNT);
+ T1WriteWord(MMU.MMU_MEM[remote][0x40], 0x184, IPCFIFO_CNT_remote);
+ if ((MMU.fifos[fifonum].empty) && (IPCFIFO_CNT & BIT(2)))
+ NDS_makeInt(remote,17) ; /* remote: SEND FIFO EMPTY */
+ return val;
+ }
+ }
+ return 0;
+ case REG_TM0CNTL :
+ case REG_TM1CNTL :
+ case REG_TM2CNTL :
+ case REG_TM3CNTL :
+ {
+ u32 val = T1ReadWord(MMU.MMU_MEM[proc][0x40], (adr + 2) & 0xFFF);
+ return MMU.timer[proc][(adr&0xF)>>2] | (val<<16);
+ }
+ /*
+ case 0x04000640 : // TODO (clear): again, ???
+ LOG("read proj\r\n");
+ return 0;
+ case 0x04000680 :
+ LOG("read roat\r\n");
+ return 0;
+ case 0x04000620 :
+ LOG("point res\r\n");
+ return 0;
+ */
+ case REG_GCDATAIN:
+ {
+ u32 val;
+
+ if(!MMU.dscard[proc].adress) return 0;
+
+ val = T1ReadLong(MMU.CART_ROM, MMU.dscard[proc].adress);
+
+ MMU.dscard[proc].adress += 4; /* increment adress */
+
+ MMU.dscard[proc].transfer_count--; /* update transfer counter */
+ if(MMU.dscard[proc].transfer_count) /* if transfer is not ended */
+ {
+ return val; /* return data */
+ }
+ else /* transfer is done */
+ {
+ T1WriteLong(MMU.MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, T1ReadLong(MMU.MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff) & ~(0x00800000 | 0x80000000));
+ /* = 0x7f7fffff */
+
+ /* if needed, throw irq for the end of transfer */
+ if(T1ReadWord(MMU.MMU_MEM[proc][(REG_AUXSPICNT >> 20) & 0xff], REG_AUXSPICNT & 0xfff) & 0x4000)
+ {
+ if(proc == ARMCPU_ARM7) NDS_makeARM7Int(19);
+ else NDS_makeARM9Int(19);
+ }
+
+ return val;
+ }
+ }
+
+ default :
+ break;
+ }
+ }
+
+ /* Returns data from memory */
+ return T1ReadLong(MMU.MMU_MEM[proc][(adr >> 20) & 0xFF], adr & MMU.MMU_MASK[proc][(adr >> 20) & 0xFF]);
+}
+
+void FASTCALL MMU_write8(u32 proc, u32 adr, u8 val)
+{
+#ifdef INTERNAL_DTCM_WRITE
+ if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion))
+ {
+ /* Writes data in DTCM (ARM9 only) */
+ ARM9Mem.ARM9_DTCM[adr&0x3FFF] = val;
+ return ;
+ }
+#endif
+
+ // CFlash writing, Mic
+ if ((adr>=0x9000000)&&(adr<0x9900000)) {
+ cflash_write(adr,val);
+ return;
+ }
+
+ adr &= 0x0FFFFFFF;
+
+ // This is bad, remove it
+ if(proc == ARMCPU_ARM7)
+ {
+ if ((adr>=0x04000400)&&(adr<0x0400051D))
+ {
+ SPU_WriteByte(adr, val);
+ return;
+ }
+ }
+
+ if ((adr & 0xFF800000) == 0x04800000)
+ {
+ /* is wifi hardware, dont intermix with regular hardware registers */
+ /* FIXME handle 8 bit writes */
+ return ;
+ }
+
+ switch(adr)
+ {
+ case REG_DISPA_WIN0H:
+ if(proc == ARMCPU_ARM9) GPU_setWIN0_H1 (MainScreen.gpu, val);
+ break ;
+ case REG_DISPA_WIN0H+1:
+ if(proc == ARMCPU_ARM9) GPU_setWIN0_H0 (MainScreen.gpu, val);
+ break ;
+ case REG_DISPA_WIN1H:
+ if(proc == ARMCPU_ARM9) GPU_setWIN1_H1 (MainScreen.gpu,val);
+ break ;
+ case REG_DISPA_WIN1H+1:
+ if(proc == ARMCPU_ARM9) GPU_setWIN1_H0 (MainScreen.gpu,val);
+ break ;
+
+ case REG_DISPB_WIN0H:
+ if(proc == ARMCPU_ARM9) GPU_setWIN0_H1(SubScreen.gpu,val);
+ break ;
+ case REG_DISPB_WIN0H+1:
+ if(proc == ARMCPU_ARM9) GPU_setWIN0_H0(SubScreen.gpu,val);
+ break ;
+ case REG_DISPB_WIN1H:
+ if(proc == ARMCPU_ARM9) GPU_setWIN1_H1(SubScreen.gpu,val);
+ break ;
+ case REG_DISPB_WIN1H+1:
+ if(proc == ARMCPU_ARM9) GPU_setWIN1_H0(SubScreen.gpu,val);
+ break ;
+
+ case REG_DISPA_WIN0V:
+ if(proc == ARMCPU_ARM9) GPU_setWIN0_V1(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPA_WIN0V+1:
+ if(proc == ARMCPU_ARM9) GPU_setWIN0_V0(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPA_WIN1V:
+ if(proc == ARMCPU_ARM9) GPU_setWIN1_V1(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPA_WIN1V+1:
+ if(proc == ARMCPU_ARM9) GPU_setWIN1_V0(MainScreen.gpu,val) ;
+ break ;
+
+ case REG_DISPB_WIN0V:
+ if(proc == ARMCPU_ARM9) GPU_setWIN0_V1(SubScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_WIN0V+1:
+ if(proc == ARMCPU_ARM9) GPU_setWIN0_V0(SubScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_WIN1V:
+ if(proc == ARMCPU_ARM9) GPU_setWIN1_V1(SubScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_WIN1V+1:
+ if(proc == ARMCPU_ARM9) GPU_setWIN1_V0(SubScreen.gpu,val) ;
+ break ;
+
+ case REG_DISPA_WININ:
+ if(proc == ARMCPU_ARM9) GPU_setWININ0(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPA_WININ+1:
+ if(proc == ARMCPU_ARM9) GPU_setWININ1(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPA_WINOUT:
+ if(proc == ARMCPU_ARM9) GPU_setWINOUT(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPA_WINOUT+1:
+ if(proc == ARMCPU_ARM9) GPU_setWINOBJ(MainScreen.gpu,val);
+ break ;
+
+ case REG_DISPB_WININ:
+ if(proc == ARMCPU_ARM9) GPU_setWININ0(SubScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_WININ+1:
+ if(proc == ARMCPU_ARM9) GPU_setWININ1(SubScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_WINOUT:
+ if(proc == ARMCPU_ARM9) GPU_setWINOUT(SubScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_WINOUT+1:
+ if(proc == ARMCPU_ARM9) GPU_setWINOBJ(SubScreen.gpu,val) ;
+ break ;
+
+
+ case REG_DISPA_BLDCNT:
+ if(proc == ARMCPU_ARM9) GPU_setBLDCNT_HIGH(MainScreen.gpu,val);
+ break;
+ case REG_DISPA_BLDCNT+1:
+ if(proc == ARMCPU_ARM9) GPU_setBLDCNT_LOW (MainScreen.gpu,val);
+ break;
+
+ case REG_DISPB_BLDCNT:
+ if(proc == ARMCPU_ARM9) GPU_setBLDCNT_HIGH (SubScreen.gpu,val);
+ break;
+ case REG_DISPB_BLDCNT+1:
+ if(proc == ARMCPU_ARM9) GPU_setBLDCNT_LOW (SubScreen.gpu,val);
+ break;
+
+ case REG_DISPA_BLDALPHA:
+ if(proc == ARMCPU_ARM9) GPU_setBLDALPHA_EVB(MainScreen.gpu,val) ;
+ break;
+ case REG_DISPA_BLDALPHA+1:
+ if(proc == ARMCPU_ARM9) GPU_setBLDALPHA_EVA(MainScreen.gpu,val) ;
+ break;
+
+ case REG_DISPB_BLDALPHA:
+ if(proc == ARMCPU_ARM9) GPU_setBLDALPHA_EVB(SubScreen.gpu,val) ;
+ break;
+ case REG_DISPB_BLDALPHA+1:
+ if(proc == ARMCPU_ARM9) GPU_setBLDALPHA_EVA(SubScreen.gpu,val);
+ break;
+
+ case REG_DISPA_BLDY:
+ if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_BLDY:
+ if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(SubScreen.gpu,val) ;
+ break;
+
+ /* TODO: EEEK ! Controls for VRAMs A, B, C, D are missing ! */
+ /* TODO: Not all mappings of VRAMs are handled... (especially BG and OBJ modes) */
+ case REG_VRAMCNTA:
+ case REG_VRAMCNTB:
+ case REG_VRAMCNTC:
+ case REG_VRAMCNTD:
+ if(proc == ARMCPU_ARM9)
+ {
+ MMU_VRAMWriteBackToLCD(0) ;
+ MMU_VRAMWriteBackToLCD(1) ;
+ MMU_VRAMWriteBackToLCD(2) ;
+ MMU_VRAMWriteBackToLCD(3) ;
+ switch(val & 0x1F)
+ {
+ case 1 :
+ MMU.vram_mode[adr-REG_VRAMCNTA] = 0; // BG-VRAM
+ //MMU.vram_offset[0] = ARM9Mem.ARM9_ABG+(0x20000*0); // BG-VRAM
+ break;
+ case 1 | (1 << 3) :
+ MMU.vram_mode[adr-REG_VRAMCNTA] = 1; // BG-VRAM
+ //MMU.vram_offset[0] = ARM9Mem.ARM9_ABG+(0x20000*1); // BG-VRAM
+ break;
+ case 1 | (2 << 3) :
+ MMU.vram_mode[adr-REG_VRAMCNTA] = 2; // BG-VRAM
+ //MMU.vram_offset[0] = ARM9Mem.ARM9_ABG+(0x20000*2); // BG-VRAM
+ break;
+ case 1 | (3 << 3) :
+ MMU.vram_mode[adr-REG_VRAMCNTA] = 3; // BG-VRAM
+ //MMU.vram_offset[0] = ARM9Mem.ARM9_ABG+(0x20000*3); // BG-VRAM
+ break;
+ case 0: /* mapped to lcd */
+ MMU.vram_mode[adr-REG_VRAMCNTA] = 4 | (adr-REG_VRAMCNTA) ;
+ break ;
+ }
+ /*
+ * FIXME: simply texture slot handling
+ * This is a first stab and is not correct. It does
+ * not handle a VRAM texture slot becoming
+ * unconfigured.
+ * Revisit all of VRAM control handling for future
+ * release?
+ */
+ if ( val & 0x80) {
+ if ( (val & 0x7) == 3) {
+ int slot_index = (val >> 3) & 0x3;
+
+ ARM9Mem.textureSlotAddr[slot_index] =
+ &ARM9Mem.ARM9_LCD[0x20000 * (adr - REG_VRAMCNTA)];
+ }
+ }
+ MMU_VRAMReloadFromLCD(adr-REG_VRAMCNTA,val) ;
+ }
+ break;
+ case REG_VRAMCNTE :
+ if(proc == ARMCPU_ARM9)
+ {
+ MMU_VRAMWriteBackToLCD((u8)REG_VRAMCNTE) ;
+ if((val & 7) == 5)
+ {
+ ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x80000;
+ ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x82000;
+ ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x84000;
+ ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x86000;
+ }
+ else if((val & 7) == 3)
+ {
+ ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD + 0x80000;
+ ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD + 0x82000;
+ ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD + 0x84000;
+ ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD + 0x86000;
+ }
+ else if((val & 7) == 4)
+ {
+ ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x80000;
+ ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x82000;
+ ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x84000;
+ ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x86000;
+ }
+
+ MMU_VRAMReloadFromLCD(adr-REG_VRAMCNTE,val) ;
+ }
+ break;
+
+ case REG_VRAMCNTF :
+ if(proc == ARMCPU_ARM9)
+ {
+ switch(val & 0x1F)
+ {
+ case 4 :
+ ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x90000;
+ ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x92000;
+ break;
+
+ case 4 | (1 << 3) :
+ ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x90000;
+ ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x92000;
+ break;
+
+ case 3 :
+ ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD + 0x90000;
+ break;
+
+ case 3 | (1 << 3) :
+ ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD + 0x90000;
+ break;
+
+ case 3 | (2 << 3) :
+ ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD + 0x90000;
+ break;
+
+ case 3 | (3 << 3) :
+ ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD + 0x90000;
+ break;
+
+ case 5 :
+ case 5 | (1 << 3) :
+ case 5 | (2 << 3) :
+ case 5 | (3 << 3) :
+ ARM9Mem.ObjExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x90000;
+ ARM9Mem.ObjExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x92000;
+ break;
+ }
+ }
+ break;
+ case REG_VRAMCNTG :
+ if(proc == ARMCPU_ARM9)
+ {
+ switch(val & 0x1F)
+ {
+ case 4 :
+ ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x94000;
+ ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x96000;
+ break;
+
+ case 4 | (1 << 3) :
+ ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x94000;
+ ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x96000;
+ break;
+
+ case 3 :
+ ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD + 0x94000;
+ break;
+
+ case 3 | (1 << 3) :
+ ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD + 0x94000;
+ break;
+
+ case 3 | (2 << 3) :
+ ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD + 0x94000;
+ break;
+
+ case 3 | (3 << 3) :
+ ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD + 0x94000;
+ break;
+
+ case 5 :
+ case 5 | (1 << 3) :
+ case 5 | (2 << 3) :
+ case 5 | (3 << 3) :
+ ARM9Mem.ObjExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x94000;
+ ARM9Mem.ObjExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x96000;
+ break;
+ }
+ }
+ break;
+
+ case REG_VRAMCNTH :
+ if(proc == ARMCPU_ARM9)
+ {
+ MMU_VRAMWriteBackToLCD((u8)REG_VRAMCNTH) ;
+
+ if((val & 7) == 2)
+ {
+ ARM9Mem.ExtPal[1][0] = ARM9Mem.ARM9_LCD + 0x98000;
+ ARM9Mem.ExtPal[1][1] = ARM9Mem.ARM9_LCD + 0x9A000;
+ ARM9Mem.ExtPal[1][2] = ARM9Mem.ARM9_LCD + 0x9C000;
+ ARM9Mem.ExtPal[1][3] = ARM9Mem.ARM9_LCD + 0x9E000;
+ }
+
+ MMU_VRAMReloadFromLCD(adr-REG_VRAMCNTH,val) ;
+ }
+ break;
+
+ case REG_VRAMCNTI :
+ if(proc == ARMCPU_ARM9)
+ {
+ MMU_VRAMWriteBackToLCD((u8)REG_VRAMCNTI) ;
+
+ if((val & 7) == 3)
+ {
+ ARM9Mem.ObjExtPal[1][0] = ARM9Mem.ARM9_LCD + 0xA0000;
+ ARM9Mem.ObjExtPal[1][1] = ARM9Mem.ARM9_LCD + 0xA2000;
+ }
+
+ MMU_VRAMReloadFromLCD(adr-REG_VRAMCNTI,val) ;
+ }
+ break;
+
+#ifdef LOG_CARD
+ case 0x040001A0 : /* TODO (clear): ??? */
+ case 0x040001A1 :
+ case 0x040001A2 :
+ case 0x040001A8 :
+ case 0x040001A9 :
+ case 0x040001AA :
+ case 0x040001AB :
+ case 0x040001AC :
+ case 0x040001AD :
+ case 0x040001AE :
+ case 0x040001AF :
+ LOG("%08X : %02X\r\n", adr, val);
+#endif
+
+ default :
+ break;
+ }
+
+ MMU.MMU_MEM[proc][(adr>>20)&0xFF][adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF]]=val;
+}
+
+u16 partie = 1;
+
+void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val)
+{
+#ifdef INTERNAL_DTCM_WRITE
+ if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion))
+ {
+ /* Writes in DTCM (ARM9 only) */
+ T1WriteWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF, val);
+ return;
+ }
+#endif
+
+ // CFlash writing, Mic
+ if ((adr>=0x08800000)&&(adr<0x09900000))
+ {
+ cflash_write(adr,val);
+ return;
+ }
+
+#ifdef EXPERIMENTAL_WIFI
+
+ /* wifi mac access */
+ if ((proc==ARMCPU_ARM7) && (adr>=0x04800000)&&(adr<0x05000000))
+ {
+ WIFI_write16(&wifiMac,adr,val) ;
+ return ;
+ }
+#else
+ if ((proc==ARMCPU_ARM7) && (adr>=0x04800000)&&(adr<0x05000000))
+ return ;
+#endif
+
+ adr &= 0x0FFFFFFF;
+
+ // This is bad, remove it
+ if(proc == ARMCPU_ARM7)
+ {
+ if ((adr>=0x04000400)&&(adr<0x0400051D))
+ {
+ SPU_WriteWord(adr, val);
+ return;
+ }
+ }
+
+ if((adr >> 24) == 4)
+ {
+ /* Adress is an IO register */
+ switch(adr)
+ {
+#if VIO2SF_GPU_ENABLE
+ case 0x0400035C:
+ {
+ ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x35C>>1] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_FogOffset (val);
+ }
+ return;
+ }
+ case 0x04000340:
+ {
+ ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x340>>1] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_AlphaFunc(val);
+ }
+ return;
+ }
+ case 0x04000060:
+ {
+ ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x060>>1] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Control(val);
+ }
+ return;
+ }
+ case 0x04000354:
+ {
+ ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x354>>1] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_ClearDepth(val);
+ }
+ return;
+ }
+#endif
+
+ case REG_DISPA_BLDCNT:
+ if(proc == ARMCPU_ARM9) GPU_setBLDCNT(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_BLDCNT:
+ if(proc == ARMCPU_ARM9) GPU_setBLDCNT(SubScreen.gpu,val) ;
+ break ;
+ case REG_DISPA_BLDALPHA:
+ if(proc == ARMCPU_ARM9) GPU_setBLDALPHA(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_BLDALPHA:
+ if(proc == ARMCPU_ARM9) GPU_setBLDALPHA(SubScreen.gpu,val) ;
+ break ;
+ case REG_DISPA_BLDY:
+ if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_BLDY:
+ if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(SubScreen.gpu,val) ;
+ break;
+ case REG_DISPA_MASTERBRIGHT:
+ GPU_setMasterBrightness (MainScreen.gpu, val);
+ break;
+ /*
+ case REG_DISPA_MOSAIC:
+ if(proc == ARMCPU_ARM9) GPU_setMOSAIC(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_MOSAIC:
+ if(proc == ARMCPU_ARM9) GPU_setMOSAIC(SubScreen.gpu,val) ;
+ break ;
+ */
+
+ case REG_DISPA_WIN0H:
+ if(proc == ARMCPU_ARM9) GPU_setWIN0_H (MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPA_WIN1H:
+ if(proc == ARMCPU_ARM9) GPU_setWIN1_H(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_WIN0H:
+ if(proc == ARMCPU_ARM9) GPU_setWIN0_H(SubScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_WIN1H:
+ if(proc == ARMCPU_ARM9) GPU_setWIN1_H(SubScreen.gpu,val) ;
+ break ;
+ case REG_DISPA_WIN0V:
+ if(proc == ARMCPU_ARM9) GPU_setWIN0_V(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPA_WIN1V:
+ if(proc == ARMCPU_ARM9) GPU_setWIN1_V(MainScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_WIN0V:
+ if(proc == ARMCPU_ARM9) GPU_setWIN0_V(SubScreen.gpu,val) ;
+ break ;
+ case REG_DISPB_WIN1V:
+ if(proc == ARMCPU_ARM9) GPU_setWIN1_V(SubScreen.gpu,val) ;
+ break ;
+ case REG_DISPA_WININ:
+ if(proc == ARMCPU_ARM9) GPU_setWININ(MainScreen.gpu, val) ;
+ break ;
+ case REG_DISPA_WINOUT:
+ if(proc == ARMCPU_ARM9) GPU_setWINOUT16(MainScreen.gpu, val) ;
+ break ;
+ case REG_DISPB_WININ:
+ if(proc == ARMCPU_ARM9) GPU_setWININ(SubScreen.gpu, val) ;
+ break ;
+ case REG_DISPB_WINOUT:
+ if(proc == ARMCPU_ARM9) GPU_setWINOUT16(SubScreen.gpu, val) ;
+ break ;
+
+ case REG_DISPB_MASTERBRIGHT:
+ GPU_setMasterBrightness (SubScreen.gpu, val);
+ break;
+
+ case REG_POWCNT1 :
+ if(proc == ARMCPU_ARM9)
+ {
+ if(val & (1<<15))
+ {
+ LOG("Main core on top\n");
+ MainScreen.offset = 0;
+ SubScreen.offset = 192;
+ //nds.swapScreen();
+ }
+ else
+ {
+ LOG("Main core on bottom (%04X)\n", val);
+ MainScreen.offset = 192;
+ SubScreen.offset = 0;
+ }
+ }
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x304, val);
+ return;
+
+ case REG_AUXSPICNT:
+ T1WriteWord(MMU.MMU_MEM[proc][(REG_AUXSPICNT >> 20) & 0xff], REG_AUXSPICNT & 0xfff, val);
+ AUX_SPI_CNT = val;
+
+ if (val == 0)
+ mc_reset_com(&MMU.bupmem); /* reset backup memory device communication */
+ return;
+
+ case REG_AUXSPIDATA:
+ if(val!=0)
+ {
+ AUX_SPI_CMD = val & 0xFF;
+ }
+
+ T1WriteWord(MMU.MMU_MEM[proc][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, bm_transfer(&MMU.bupmem, val));
+ return;
+
+ case REG_SPICNT :
+ if(proc == ARMCPU_ARM7)
+ {
+ int reset_firmware = 1;
+
+ if ( ((SPI_CNT >> 8) & 0x3) == 1) {
+ if ( ((val >> 8) & 0x3) == 1) {
+ if ( BIT11(SPI_CNT)) {
+ /* select held */
+ reset_firmware = 0;
+ }
+ }
+ }
+
+ //MMU.fw.com == 0; /* reset fw device communication */
+ if ( reset_firmware) {
+ /* reset fw device communication */
+ mc_reset_com(&MMU.fw);
+ }
+ SPI_CNT = val;
+ }
+
+ T1WriteWord(MMU.MMU_MEM[proc][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff, val);
+ return;
+
+ case REG_SPIDATA :
+ if(proc==ARMCPU_ARM7)
+ {
+ u16 spicnt;
+
+ if(val!=0)
+ {
+ SPI_CMD = val;
+ }
+
+ spicnt = T1ReadWord(MMU.MMU_MEM[proc][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff);
+
+ switch((spicnt >> 8) & 0x3)
+ {
+ case 0 :
+ break;
+
+ case 1 : /* firmware memory device */
+ if((spicnt & 0x3) != 0) /* check SPI baudrate (must be 4mhz) */
+ {
+ T1WriteWord(MMU.MMU_MEM[proc][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, 0);
+ break;
+ }
+ T1WriteWord(MMU.MMU_MEM[proc][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, fw_transfer(&MMU.fw, val));
+
+ return;
+
+ case 2 :
+ switch(SPI_CMD & 0x70)
+ {
+ case 0x00 :
+ val = 0;
+ break;
+ case 0x10 :
+ //execute = false;
+ if(SPI_CNT&(1<<11))
+ {
+ if(partie)
+ {
+ val = ((nds.touchY<<3)&0x7FF);
+ partie = 0;
+ //execute = false;
+ break;
+ }
+ val = (nds.touchY>>5);
+ partie = 1;
+ break;
+ }
+ val = ((nds.touchY<<3)&0x7FF);
+ partie = 1;
+ break;
+ case 0x20 :
+ val = 0;
+ break;
+ case 0x30 :
+ val = 0;
+ break;
+ case 0x40 :
+ val = 0;
+ break;
+ case 0x50 :
+ if(spicnt & 0x800)
+ {
+ if(partie)
+ {
+ val = ((nds.touchX<<3)&0x7FF);
+ partie = 0;
+ break;
+ }
+ val = (nds.touchX>>5);
+ partie = 1;
+ break;
+ }
+ val = ((nds.touchX<<3)&0x7FF);
+ partie = 1;
+ break;
+ case 0x60 :
+ val = 0;
+ break;
+ case 0x70 :
+ val = 0;
+ break;
+ }
+ break;
+
+ case 3 :
+ /* NOTICE: Device 3 of SPI is reserved (unused and unusable) */
+ break;
+ }
+ }
+
+ T1WriteWord(MMU.MMU_MEM[proc][(REG_SPIDATA >> 20) & 0xff], REG_SPIDATA & 0xfff, val);
+ return;
+
+ /* NOTICE: Perhaps we have to use gbatek-like reg names instead of libnds-like ones ...*/
+
+ case REG_DISPA_BG0CNT :
+ //GPULOG("MAIN BG0 SETPROP 16B %08X\r\n", val);
+ if(proc == ARMCPU_ARM9) GPU_setBGProp(MainScreen.gpu, 0, val);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x8, val);
+ return;
+ case REG_DISPA_BG1CNT :
+ //GPULOG("MAIN BG1 SETPROP 16B %08X\r\n", val);
+ if(proc == ARMCPU_ARM9) GPU_setBGProp(MainScreen.gpu, 1, val);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xA, val);
+ return;
+ case REG_DISPA_BG2CNT :
+ //GPULOG("MAIN BG2 SETPROP 16B %08X\r\n", val);
+ if(proc == ARMCPU_ARM9) GPU_setBGProp(MainScreen.gpu, 2, val);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xC, val);
+ return;
+ case REG_DISPA_BG3CNT :
+ //GPULOG("MAIN BG3 SETPROP 16B %08X\r\n", val);
+ if(proc == ARMCPU_ARM9) GPU_setBGProp(MainScreen.gpu, 3, val);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xE, val);
+ return;
+ case REG_DISPB_BG0CNT :
+ //GPULOG("SUB BG0 SETPROP 16B %08X\r\n", val);
+ if(proc == ARMCPU_ARM9) GPU_setBGProp(SubScreen.gpu, 0, val);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x1008, val);
+ return;
+ case REG_DISPB_BG1CNT :
+ //GPULOG("SUB BG1 SETPROP 16B %08X\r\n", val);
+ if(proc == ARMCPU_ARM9) GPU_setBGProp(SubScreen.gpu, 1, val);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x100A, val);
+ return;
+ case REG_DISPB_BG2CNT :
+ //GPULOG("SUB BG2 SETPROP 16B %08X\r\n", val);
+ if(proc == ARMCPU_ARM9) GPU_setBGProp(SubScreen.gpu, 2, val);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x100C, val);
+ return;
+ case REG_DISPB_BG3CNT :
+ //GPULOG("SUB BG3 SETPROP 16B %08X\r\n", val);
+ if(proc == ARMCPU_ARM9) GPU_setBGProp(SubScreen.gpu, 3, val);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x100E, val);
+ return;
+ case REG_IME : {
+ u32 old_val = MMU.reg_IME[proc];
+ u32 new_val = val & 1;
+ MMU.reg_IME[proc] = new_val;
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x208, val);
+ if ( new_val && old_val != new_val) {
+ /* raise an interrupt request to the CPU if needed */
+ if ( MMU.reg_IE[proc] & MMU.reg_IF[proc]) {
+ NDS_ARM7.wIRQ = true;
+ NDS_ARM7.waitIRQ = false;
+ }
+ }
+ return;
+ }
+ case REG_VRAMCNTA:
+ MMU_write8(proc,adr,val & 0xFF) ;
+ MMU_write8(proc,adr+1,val >> 8) ;
+ return ;
+ case REG_VRAMCNTC:
+ MMU_write8(proc,adr,val & 0xFF) ;
+ MMU_write8(proc,adr+1,val >> 8) ;
+ return ;
+ case REG_VRAMCNTE:
+ MMU_write8(proc,adr,val & 0xFF) ;
+ MMU_write8(proc,adr+1,val >> 8) ;
+ return ;
+ case REG_VRAMCNTG:
+ MMU_write8(proc,adr,val & 0xFF) ;
+ MMU_write8(proc,adr+1,val >> 8) ;
+ return ;
+ case REG_VRAMCNTI:
+ MMU_write8(proc,adr,val & 0xFF) ;
+ return ;
+
+ case REG_IE :
+ MMU.reg_IE[proc] = (MMU.reg_IE[proc]&0xFFFF0000) | val;
+ if ( MMU.reg_IME[proc]) {
+ /* raise an interrupt request to the CPU if needed */
+ if ( MMU.reg_IE[proc] & MMU.reg_IF[proc]) {
+ NDS_ARM7.wIRQ = true;
+ NDS_ARM7.waitIRQ = false;
+ }
+ }
+ return;
+ case REG_IE + 2 :
+ execute = false;
+ MMU.reg_IE[proc] = (MMU.reg_IE[proc]&0xFFFF) | (((u32)val)<<16);
+ return;
+
+ case REG_IF :
+ execute = false;
+ MMU.reg_IF[proc] &= (~((u32)val));
+ return;
+ case REG_IF + 2 :
+ execute = false;
+ MMU.reg_IF[proc] &= (~(((u32)val)<<16));
+ return;
+
+ case REG_IPCSYNC :
+ {
+ u32 remote = (proc+1)&1;
+ u16 IPCSYNC_remote = T1ReadWord(MMU.MMU_MEM[remote][0x40], 0x180);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x180, (val&0xFFF0)|((IPCSYNC_remote>>8)&0xF));
+ T1WriteWord(MMU.MMU_MEM[remote][0x40], 0x180, (IPCSYNC_remote&0xFFF0)|((val>>8)&0xF));
+ MMU.reg_IF[remote] |= ((IPCSYNC_remote & (1<<14))<<2) & ((val & (1<<13))<<3);// & (MMU.reg_IME[remote] << 16);// & (MMU.reg_IE[remote] & (1<<16));//
+ //execute = false;
+ }
+ return;
+ case REG_IPCFIFOCNT :
+ {
+ u32 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184) ;
+ u32 cnt_r = T1ReadWord(MMU.MMU_MEM[(proc+1) & 1][0x40], 0x184) ;
+ if ((val & 0x8000) && !(cnt_l & 0x8000))
+ {
+ /* this is the first init, the other side didnt init yet */
+ /* so do a complete init */
+ FIFOInit(MMU.fifos + (IPCFIFO+proc));
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184,0x8101) ;
+ /* and then handle it as usual */
+ }
+
+ if(val & 0x4008)
+ {
+ FIFOInit(MMU.fifos + (IPCFIFO+((proc+1)&1)));
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, (cnt_l & 0x0301) | (val & 0x8404) | 1);
+ T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, (cnt_r & 0xC507) | 0x100);
+ MMU.reg_IF[proc] |= ((val & 4)<<15);// & (MMU.reg_IME[proc]<<17);// & (MMU.reg_IE[proc]&0x20000);//
+ return;
+ }
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184) | (val & 0xBFF4));
+ }
+ return;
+ case REG_TM0CNTL :
+ case REG_TM1CNTL :
+ case REG_TM2CNTL :
+ case REG_TM3CNTL :
+ MMU.timerReload[proc][(adr>>2)&3] = val;
+ return;
+ case REG_TM0CNTH :
+ case REG_TM1CNTH :
+ case REG_TM2CNTH :
+ case REG_TM3CNTH :
+ if(val&0x80)
+ {
+ MMU.timer[proc][((adr-2)>>2)&0x3] = MMU.timerReload[proc][((adr-2)>>2)&0x3];
+ }
+ MMU.timerON[proc][((adr-2)>>2)&0x3] = val & 0x80;
+ switch(val&7)
+ {
+ case 0 :
+ MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 0+1;//proc;
+ break;
+ case 1 :
+ MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 6+1;//proc;
+ break;
+ case 2 :
+ MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 8+1;//proc;
+ break;
+ case 3 :
+ MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 10+1;//proc;
+ break;
+ default :
+ MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 0xFFFF;
+ break;
+ }
+ if(!(val & 0x80))
+ MMU.timerRUN[proc][((adr-2)>>2)&0x3] = false;
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], adr & 0xFFF, val);
+ return;
+ case REG_DISPA_DISPCNT+2 :
+ {
+ //execute = false;
+ u32 v = (T1ReadLong(MMU.MMU_MEM[proc][0x40], 0) & 0xFFFF) | ((u32) val << 16);
+ GPU_setVideoProp(MainScreen.gpu, v);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0, v);
+ }
+ return;
+ case REG_DISPA_DISPCNT :
+ if(proc == ARMCPU_ARM9)
+ {
+ u32 v = (T1ReadLong(MMU.MMU_MEM[proc][0x40], 0) & 0xFFFF0000) | val;
+ GPU_setVideoProp(MainScreen.gpu, v);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0, v);
+ }
+ return;
+ case REG_DISPA_DISPCAPCNT :
+ if(proc == ARMCPU_ARM9)
+ {
+ GPU_set_DISPCAPCNT(MainScreen.gpu,val);
+ }
+ return;
+ case REG_DISPB_DISPCNT+2 :
+ if(proc == ARMCPU_ARM9)
+ {
+ //execute = false;
+ u32 v = (T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x1000) & 0xFFFF) | ((u32) val << 16);
+ GPU_setVideoProp(SubScreen.gpu, v);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x1000, v);
+ }
+ return;
+ case REG_DISPB_DISPCNT :
+ {
+ u32 v = (T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x1000) & 0xFFFF0000) | val;
+ GPU_setVideoProp(SubScreen.gpu, v);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x1000, v);
+ }
+ return;
+ //case 0x020D8460 :
+ /*case 0x0235A904 :
+ LOG("ECRIRE %d %04X\r\n", proc, val);
+ execute = false;*/
+ case REG_DMA0CNTH :
+ {
+ u32 v;
+
+ //if(val&0x8000) execute = false;
+ //LOG("16 bit dma0 %04X\r\n", val);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xBA, val);
+ DMASrc[proc][0] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xB0);
+ DMADst[proc][0] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xB4);
+ v = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xB8);
+ MMU.DMAStartTime[proc][0] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7);
+ MMU.DMACrt[proc][0] = v;
+ if(MMU.DMAStartTime[proc][0] == 0)
+ MMU_doDMA(proc, 0);
+ #ifdef LOG_DMA2
+ //else
+ {
+ LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 0, DMASrc[proc][0], DMADst[proc][0], (val&(1<<25))?"ON":"OFF");
+ }
+ #endif
+ }
+ return;
+ case REG_DMA1CNTH :
+ {
+ u32 v;
+ //if(val&0x8000) execute = false;
+ //LOG("16 bit dma1 %04X\r\n", val);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xC6, val);
+ DMASrc[proc][1] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xBC);
+ DMASrc[proc][1] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xC0);
+ v = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xC4);
+ MMU.DMAStartTime[proc][1] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7);
+ MMU.DMACrt[proc][1] = v;
+ if(MMU.DMAStartTime[proc][1] == 0)
+ MMU_doDMA(proc, 1);
+ #ifdef LOG_DMA2
+ //else
+ {
+ LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 1, DMASrc[proc][1], DMADst[proc][1], (val&(1<<25))?"ON":"OFF");
+ }
+ #endif
+ }
+ return;
+ case REG_DMA2CNTH :
+ {
+ u32 v;
+ //if(val&0x8000) execute = false;
+ //LOG("16 bit dma2 %04X\r\n", val);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xD2, val);
+ DMASrc[proc][2] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xC8);
+ DMASrc[proc][2] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xCC);
+ v = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xD0);
+ MMU.DMAStartTime[proc][2] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7);
+ MMU.DMACrt[proc][2] = v;
+ if(MMU.DMAStartTime[proc][2] == 0)
+ MMU_doDMA(proc, 2);
+ #ifdef LOG_DMA2
+ //else
+ {
+ LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 2, DMASrc[proc][2], DMADst[proc][2], (val&(1<<25))?"ON":"OFF");
+ }
+ #endif
+ }
+ return;
+ case REG_DMA3CNTH :
+ {
+ u32 v;
+ //if(val&0x8000) execute = false;
+ //LOG("16 bit dma3 %04X\r\n", val);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0xDE, val);
+ DMASrc[proc][3] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xD4);
+ DMASrc[proc][3] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xD8);
+ v = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xDC);
+ MMU.DMAStartTime[proc][3] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7);
+ MMU.DMACrt[proc][3] = v;
+
+ if(MMU.DMAStartTime[proc][3] == 0)
+ MMU_doDMA(proc, 3);
+ #ifdef LOG_DMA2
+ //else
+ {
+ LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 3, DMASrc[proc][3], DMADst[proc][3], (val&(1<<25))?"ON":"OFF");
+ }
+ #endif
+ }
+ return;
+ //case REG_AUXSPICNT : execute = false;
+ default :
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF], val);
+ return;
+ }
+ }
+ T1WriteWord(MMU.MMU_MEM[proc][(adr>>20)&0xFF], adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF], val);
+}
+
+
+void FASTCALL MMU_write32(u32 proc, u32 adr, u32 val)
+{
+#ifdef INTERNAL_DTCM_WRITE
+ if((proc==ARMCPU_ARM9)&((adr&(~0x3FFF))==MMU.DTCMRegion))
+ {
+ T1WriteLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF, val);
+ return ;
+ }
+#endif
+
+ // CFlash writing, Mic
+ if ((adr>=0x9000000)&&(adr<0x9900000)) {
+ cflash_write(adr,val);
+ return;
+ }
+
+ adr &= 0x0FFFFFFF;
+
+ // This is bad, remove it
+ if(proc == ARMCPU_ARM7)
+ {
+ if ((adr>=0x04000400)&&(adr<0x0400051D))
+ {
+ SPU_WriteLong(adr, val);
+ return;
+ }
+ }
+
+ if ((adr & 0xFF800000) == 0x04800000) {
+ /* access to non regular hw registers */
+ /* return to not overwrite valid data */
+ return ;
+ } ;
+
+
+ if((adr>>24)==4)
+ {
+ if (adr >= 0x04000400 && adr < 0x04000440)
+ {
+ // Geometry commands (aka Dislay Lists) - Parameters:X
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x400>>2] = val;
+#if VIO2SF_GPU_ENABLE
+ if(proc==ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_CallList(val);
+ }
+#endif
+ }
+ else
+ switch(adr)
+ {
+#if VIO2SF_GPU_ENABLE
+ // Alpha test reference value - Parameters:1
+ case 0x04000340:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x340>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_AlphaFunc(val);
+ }
+ return;
+ }
+ // Clear background color setup - Parameters:2
+ case 0x04000350:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x350>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_ClearColor(val);
+ }
+ return;
+ }
+ // Clear background depth setup - Parameters:2
+ case 0x04000354:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x354>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_ClearDepth(val);
+ }
+ return;
+ }
+ // Fog Color - Parameters:4b
+ case 0x04000358:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x358>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_FogColor(val);
+ }
+ return;
+ }
+ case 0x0400035C:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x35C>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_FogOffset(val);
+ }
+ return;
+ }
+ // Matrix mode - Parameters:1
+ case 0x04000440:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x440>>2] = val;
+
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_MatrixMode(val);
+ }
+ return;
+ }
+ // Push matrix - Parameters:0
+ case 0x04000444:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x444>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_PushMatrix();
+ }
+ return;
+ }
+ // Pop matrix/es - Parameters:1
+ case 0x04000448:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x448>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_PopMatrix(val);
+ }
+ return;
+ }
+ // Store matrix in the stack - Parameters:1
+ case 0x0400044C:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x44C>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_StoreMatrix(val);
+ }
+ return;
+ }
+ // Restore matrix from the stack - Parameters:1
+ case 0x04000450:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x450>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_RestoreMatrix(val);
+ }
+ return;
+ }
+ // Load Identity matrix - Parameters:0
+ case 0x04000454:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x454>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_LoadIdentity();
+ }
+ return;
+ }
+ // Load 4x4 matrix - Parameters:16
+ case 0x04000458:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x458>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_LoadMatrix4x4(val);
+ }
+ return;
+ }
+ // Load 4x3 matrix - Parameters:12
+ case 0x0400045C:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x45C>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_LoadMatrix4x3(val);
+ }
+ return;
+ }
+ // Multiply 4x4 matrix - Parameters:16
+ case 0x04000460:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x460>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_MultMatrix4x4(val);
+ }
+ return;
+ }
+ // Multiply 4x4 matrix - Parameters:12
+ case 0x04000464:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x464>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_MultMatrix4x3(val);
+ }
+ return;
+ }
+ // Multiply 3x3 matrix - Parameters:9
+ case 0x04000468 :
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x468>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_MultMatrix3x3(val);
+ }
+ return;
+ }
+ // Multiply current matrix by scaling matrix - Parameters:3
+ case 0x0400046C:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x46C>>2] = val;
+ if(proc==ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Scale(val);
+ }
+ return;
+ }
+ // Multiply current matrix by translation matrix - Parameters:3
+ case 0x04000470:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x470>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Translate(val);
+ }
+ return;
+ }
+ // Set vertex color - Parameters:1
+ case 0x04000480:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x480>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Color3b(val);
+ }
+ return;
+ }
+ // Set vertex normal - Parameters:1
+ case 0x04000484:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x484>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Normal(val);
+ }
+ return;
+ }
+ // Set vertex texture coordinate - Parameters:1
+ case 0x04000488:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x488>>2] = val;
+ if(proc==ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_TexCoord(val);
+ }
+ return;
+ }
+ // Set vertex position 16b/coordinate - Parameters:2
+ case 0x0400048C:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x48C>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Vertex16b(val);
+ }
+ return;
+ }
+ // Set vertex position 10b/coordinate - Parameters:1
+ case 0x04000490:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x490>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Vertex10b(val);
+ }
+ return;
+ }
+ // Set vertex XY position - Parameters:1
+ case 0x04000494:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x494>>2] = val;
+ if(proc==ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Vertex3_cord(0,1,val);
+ }
+ return;
+ }
+ // Set vertex XZ position - Parameters:1
+ case 0x04000498:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x498>>2] = val;
+ if(proc==ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Vertex3_cord(0,2,val);
+ }
+ return;
+ }
+ // Set vertex YZ position - Parameters:1
+ case 0x0400049C:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x49C>>2] = val;
+ if(proc==ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Vertex3_cord(1,2,val);
+ }
+ return;
+ }
+ // Set vertex difference position (offset from the last vertex) - Parameters:1
+ case 0x040004A0:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4A0>>2] = val;
+ if(proc==ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Vertex_rel (val);
+ }
+ return;
+ }
+ // Set polygon attributes - Parameters:1
+ case 0x040004A4:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4A4>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_PolygonAttrib(val);
+ }
+ return;
+ }
+ // Set texture parameteres - Parameters:1
+ case 0x040004A8:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4A8>>2] = val;
+ if(proc==ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_TexImage(val);
+ }
+ return;
+ }
+ // Set palette base address - Parameters:1
+ case 0x040004AC:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4AC>>2] = val&0x1FFF;
+ if(proc==ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_TexPalette(val&0x1FFFF);
+ }
+ return;
+ }
+ // Set material diffuse/ambient parameters - Parameters:1
+ case 0x040004C0:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4C0>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Material0 (val);
+ }
+ return;
+ }
+ // Set material reflection/emission parameters - Parameters:1
+ case 0x040004C4:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4C4>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Material1 (val);
+ }
+ return;
+ }
+ // Light direction vector - Parameters:1
+ case 0x040004C8:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4C8>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_LightDirection (val);
+ }
+ return;
+ }
+ // Light color - Parameters:1
+ case 0x040004CC:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4CC>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_LightColor(val);
+ }
+ return;
+ }
+ // Material Shininess - Parameters:32
+ case 0x040004D0:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4D0>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Shininess(val);
+ }
+ return;
+ }
+ // Begin vertex list - Parameters:1
+ case 0x04000500:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x500>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Begin(val);
+ }
+ return;
+ }
+ // End vertex list - Parameters:0
+ case 0x04000504:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x504>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_End();
+ }
+ return;
+ }
+ // Swap rendering engine buffers - Parameters:1
+ case 0x04000540:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x540>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_Flush(val);
+ }
+ return;
+ }
+ // Set viewport coordinates - Parameters:1
+ case 0x04000580:
+ {
+ ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x580>>2] = val;
+ if(proc == ARMCPU_ARM9)
+ {
+ gpu3D->NDS_3D_ViewPort(val);
+ }
+ return;
+ }
+#endif
+
+ case REG_DISPA_WININ:
+ {
+ if(proc == ARMCPU_ARM9)
+ {
+ GPU_setWININ (MainScreen.gpu, val & 0xFFFF) ;
+ GPU_setWINOUT16 (MainScreen.gpu, (val >> 16) & 0xFFFF) ;
+ }
+ break;
+ }
+ case REG_DISPB_WININ:
+ {
+ if(proc == ARMCPU_ARM9)
+ {
+ GPU_setWININ (SubScreen.gpu, val & 0xFFFF) ;
+ GPU_setWINOUT16 (SubScreen.gpu, (val >> 16) & 0xFFFF) ;
+ }
+ break;
+ }
+
+ case REG_DISPA_BLDCNT:
+ {
+ if (proc == ARMCPU_ARM9)
+ {
+ GPU_setBLDCNT (MainScreen.gpu,val&0xffff);
+ GPU_setBLDALPHA (MainScreen.gpu,val>>16);
+ }
+ break;
+ }
+ case REG_DISPB_BLDCNT:
+ {
+ if (proc == ARMCPU_ARM9)
+ {
+ GPU_setBLDCNT (SubScreen.gpu,val&0xffff);
+ GPU_setBLDALPHA (SubScreen.gpu,val>>16);
+ }
+ break;
+ }
+/*
+ // Commented out, as this doesn't use the plug-in system, neither works
+ case cmd_3D_MTX_MODE // 0x04000440 :
+ if (proc == ARMCPU_ARM9) gl_MTX_MODE(val);
+ return;
+ case cmd_3D_MTX_PUSH // 0x04000444 :
+ case cmd_3D_MTX_POP // 0x04000448 :
+ case cmd_3D_MTX_STORE // 0x0400044C :
+ case cmd_3D_MTX_RESTORE // 0x04000450 :
+ if (proc == ARMCPU_ARM9) gl_print_cmd(adr);
+ return;
+ case cmd_3D_MTX_IDENTITY // 0x04000454 :
+ if (proc == ARMCPU_ARM9) gl_MTX_IDENTITY();
+ return;
+ case cmd_3D_MTX_LOAD_4x4 // 0x04000458 :
+ if (proc == ARMCPU_ARM9) gl_MTX_LOAD_4x4(val);
+ return;
+ case cmd_3D_MTX_LOAD_4x3 // 0x0400045C :
+ if (proc == ARMCPU_ARM9) gl_MTX_LOAD_4x3(val);
+ return;
+ case cmd_3D_MTX_MULT_4x4 // 0x04000460 :
+ if (proc == ARMCPU_ARM9) gl_MTX_MULT_4x4(val);
+ return;
+ case cmd_3D_MTX_MULT_4x3 // 0x04000464 :
+ if (proc == ARMCPU_ARM9) gl_MTX_MULT_4x3(val);
+ return;
+ case cmd_3D_MTX_MULT_3x3 // 0x04000468 :
+ if (proc == ARMCPU_ARM9) gl_MTX_MULT_3x3(val);
+ return;
+ case cmd_3D_MTX_SCALE // 0x0400046C :
+ case cmd_3D_MTX_TRANS // 0x04000470 :
+ case cmd_3D_COLOR // 0x04000480 :
+ case cmd_3D_NORMA // 0x04000484 :
+ if (proc == ARMCPU_ARM9) gl_print_cmd(adr);
+ return;
+ case cmd_3D_TEXCOORD // 0x04000488 :
+ if (proc == ARMCPU_ARM9) gl_TEXCOORD(val);
+ return;
+ case cmd_3D_VTX_16 // 0x0400048C :
+ if (proc == ARMCPU_ARM9) gl_VTX_16(val);
+ return;
+ case cmd_3D_VTX_10 // 0x04000490 :
+ if (proc == ARMCPU_ARM9) gl_VTX_10(val);
+ return;
+ case cmd_3D_VTX_XY // 0x04000494 :
+ if (proc == ARMCPU_ARM9) gl_VTX_XY(val);
+ return;
+ case cmd_3D_VTX_XZ // 0x04000498 :
+ if (proc == ARMCPU_ARM9) gl_VTX_XZ(val);
+ return;
+ case cmd_3D_VTX_YZ // 0x0400049C :
+ if (proc == ARMCPU_ARM9) gl_VTX_YZ(val);
+ return;
+ case cmd_3D_VTX_DIFF // 0x040004A0 :
+ if (proc == ARMCPU_ARM9) gl_VTX_DIFF(val);
+ return;
+ case cmd_3D_POLYGON_ATTR // 0x040004A4 :
+ case cmd_3D_TEXIMAGE_PARAM // 0x040004A8 :
+ case cmd_3D_PLTT_BASE // 0x040004AC :
+ case cmd_3D_DIF_AMB // 0x040004C0 :
+ case cmd_3D_SPE_EMI // 0x040004C4 :
+ case cmd_3D_LIGHT_VECTOR // 0x040004C8 :
+ case cmd_3D_LIGHT_COLOR // 0x040004CC :
+ case cmd_3D_SHININESS // 0x040004D0 :
+ if (proc == ARMCPU_ARM9) gl_print_cmd(adr);
+ return;
+ case cmd_3D_BEGIN_VTXS // 0x04000500 :
+ if (proc == ARMCPU_ARM9) gl_VTX_begin(val);
+ return;
+ case cmd_3D_END_VTXS // 0x04000504 :
+ if (proc == ARMCPU_ARM9) gl_VTX_end();
+ return;
+ case cmd_3D_SWAP_BUFFERS // 0x04000540 :
+ case cmd_3D_VIEWPORT // 0x04000580 :
+ case cmd_3D_BOX_TEST // 0x040005C0 :
+ case cmd_3D_POS_TEST // 0x040005C4 :
+ case cmd_3D_VEC_TEST // 0x040005C8 :
+ if (proc == ARMCPU_ARM9) gl_print_cmd(adr);
+ return;
+*/
+ case REG_DISPA_DISPCNT :
+ if(proc == ARMCPU_ARM9) GPU_setVideoProp(MainScreen.gpu, val);
+
+ //GPULOG("MAIN INIT 32B %08X\r\n", val);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0, val);
+ return;
+
+ case REG_DISPB_DISPCNT :
+ if (proc == ARMCPU_ARM9) GPU_setVideoProp(SubScreen.gpu, val);
+ //GPULOG("SUB INIT 32B %08X\r\n", val);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x1000, val);
+ return;
+ case REG_VRAMCNTA:
+ case REG_VRAMCNTE:
+ MMU_write8(proc,adr,val & 0xFF) ;
+ MMU_write8(proc,adr+1,val >> 8) ;
+ MMU_write8(proc,adr+2,val >> 16) ;
+ MMU_write8(proc,adr+3,val >> 24) ;
+ return ;
+ case REG_VRAMCNTI:
+ MMU_write8(proc,adr,val & 0xFF) ;
+ return ;
+
+ case REG_IME : {
+ u32 old_val = MMU.reg_IME[proc];
+ u32 new_val = val & 1;
+ MMU.reg_IME[proc] = new_val;
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x208, val);
+ if ( new_val && old_val != new_val) {
+ /* raise an interrupt request to the CPU if needed */
+ if ( MMU.reg_IE[proc] & MMU.reg_IF[proc]) {
+ NDS_ARM7.wIRQ = true;
+ NDS_ARM7.waitIRQ = false;
+ }
+ }
+ return;
+ }
+
+ case REG_IE :
+ MMU.reg_IE[proc] = val;
+ if ( MMU.reg_IME[proc]) {
+ /* raise an interrupt request to the CPU if needed */
+ if ( MMU.reg_IE[proc] & MMU.reg_IF[proc]) {
+ NDS_ARM7.wIRQ = true;
+ NDS_ARM7.waitIRQ = false;
+ }
+ }
+ return;
+
+ case REG_IF :
+ MMU.reg_IF[proc] &= (~val);
+ return;
+ case REG_TM0CNTL :
+ case REG_TM1CNTL :
+ case REG_TM2CNTL :
+ case REG_TM3CNTL :
+ MMU.timerReload[proc][(adr>>2)&0x3] = (u16)val;
+ if(val&0x800000)
+ {
+ MMU.timer[proc][(adr>>2)&0x3] = MMU.timerReload[proc][(adr>>2)&0x3];
+ }
+ MMU.timerON[proc][(adr>>2)&0x3] = val & 0x800000;
+ switch((val>>16)&7)
+ {
+ case 0 :
+ MMU.timerMODE[proc][(adr>>2)&0x3] = 0+1;//proc;
+ break;
+ case 1 :
+ MMU.timerMODE[proc][(adr>>2)&0x3] = 6+1;//proc;
+ break;
+ case 2 :
+ MMU.timerMODE[proc][(adr>>2)&0x3] = 8+1;//proc;
+ break;
+ case 3 :
+ MMU.timerMODE[proc][(adr>>2)&0x3] = 10+1;//proc;
+ break;
+ default :
+ MMU.timerMODE[proc][(adr>>2)&0x3] = 0xFFFF;
+ break;
+ }
+ if(!(val & 0x800000))
+ {
+ MMU.timerRUN[proc][(adr>>2)&0x3] = false;
+ }
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], adr & 0xFFF, val);
+ return;
+ case REG_DIVDENOM :
+ {
+ u16 cnt;
+ s64 num = 0;
+ s64 den = 1;
+ s64 res;
+ s64 mod;
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x298, val);
+ cnt = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x280);
+ switch(cnt&3)
+ {
+ case 0:
+ {
+ num = (s64) (s32) T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x290);
+ den = (s64) (s32) T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x298);
+ }
+ break;
+ case 1:
+ {
+ num = (s64) T1ReadQuad(MMU.MMU_MEM[proc][0x40], 0x290);
+ den = (s64) (s32) T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x298);
+ }
+ break;
+ case 2:
+ {
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+ if(den==0)
+ {
+ res = 0;
+ mod = 0;
+ cnt |= 0x4000;
+ cnt &= 0x7FFF;
+ }
+ else
+ {
+ res = num / den;
+ mod = num % den;
+ cnt &= 0x3FFF;
+ }
+ DIVLOG("BOUT1 %08X%08X / %08X%08X = %08X%08X\r\n", (u32)(num>>32), (u32)num,
+ (u32)(den>>32), (u32)den,
+ (u32)(res>>32), (u32)res);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2A0, (u32) res);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2A4, (u32) (res >> 32));
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2A8, (u32) mod);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2AC, (u32) (mod >> 32));
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x280, cnt);
+ }
+ return;
+ case REG_DIVDENOM+4 :
+ {
+ u16 cnt;
+ s64 num = 0;
+ s64 den = 1;
+ s64 res;
+ s64 mod;
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x29C, val);
+ cnt = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x280);
+ switch(cnt&3)
+ {
+ case 0:
+ {
+ return;
+ }
+ break;
+ case 1:
+ {
+ return;
+ }
+ break;
+ case 2:
+ {
+ num = (s64) T1ReadQuad(MMU.MMU_MEM[proc][0x40], 0x290);
+ den = (s64) T1ReadQuad(MMU.MMU_MEM[proc][0x40], 0x298);
+ }
+ break;
+ default:
+ break;
+ }
+ if(den==0)
+ {
+ res = 0;
+ mod = 0;
+ cnt |= 0x4000;
+ cnt &= 0x7FFF;
+ }
+ else
+ {
+ res = num / den;
+ mod = num % den;
+ cnt &= 0x3FFF;
+ }
+ DIVLOG("BOUT2 %08X%08X / %08X%08X = %08X%08X\r\n", (u32)(num>>32), (u32)num,
+ (u32)(den>>32), (u32)den,
+ (u32)(res>>32), (u32)res);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2A0, (u32) res);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2A4, (u32) (res >> 32));
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2A8, (u32) mod);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2AC, (u32) (mod >> 32));
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x280, cnt);
+ }
+ return;
+ case REG_SQRTPARAM :
+ {
+ u16 cnt;
+ u64 v = 1;
+ //execute = false;
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2B8, val);
+ cnt = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x2B0);
+ switch(cnt&1)
+ {
+ case 0:
+ v = (u64) T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x2B8);
+ break;
+ case 1:
+ return;
+ }
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2B4, (u32) sqrt((s64)v));
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2B0, cnt & 0x7FFF);
+ SQRTLOG("BOUT1 sqrt(%08X%08X) = %08X\r\n", (u32)(v>>32), (u32)v,
+ T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x2B4));
+ }
+ return;
+ case REG_SQRTPARAM+4 :
+ {
+ u16 cnt;
+ u64 v = 1;
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2BC, val);
+ cnt = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x2B0);
+ switch(cnt&1)
+ {
+ case 0:
+ return;
+ //break;
+ case 1:
+ v = T1ReadQuad(MMU.MMU_MEM[proc][0x40], 0x2B8);
+ break;
+ }
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2B4, (u32) sqrt((s64)v));
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x2B0, cnt & 0x7FFF);
+ SQRTLOG("BOUT2 sqrt(%08X%08X) = %08X\r\n", (u32)(v>>32), (u32)v,
+ T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x2B4));
+ }
+ return;
+ case REG_IPCSYNC :
+ {
+ //execute=false;
+ u32 remote = (proc+1)&1;
+ u32 IPCSYNC_remote = T1ReadLong(MMU.MMU_MEM[remote][0x40], 0x180);
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x180, (val&0xFFF0)|((IPCSYNC_remote>>8)&0xF));
+ T1WriteLong(MMU.MMU_MEM[remote][0x40], 0x180, (IPCSYNC_remote&0xFFF0)|((val>>8)&0xF));
+ MMU.reg_IF[remote] |= ((IPCSYNC_remote & (1<<14))<<2) & ((val & (1<<13))<<3);// & (MMU.reg_IME[remote] << 16);// & (MMU.reg_IE[remote] & (1<<16));//
+ }
+ return;
+ case REG_IPCFIFOCNT :
+ {
+ u32 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184) ;
+ u32 cnt_r = T1ReadWord(MMU.MMU_MEM[(proc+1) & 1][0x40], 0x184) ;
+ if ((val & 0x8000) && !(cnt_l & 0x8000))
+ {
+ /* this is the first init, the other side didnt init yet */
+ /* so do a complete init */
+ FIFOInit(MMU.fifos + (IPCFIFO+proc));
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184,0x8101) ;
+ /* and then handle it as usual */
+ }
+ if(val & 0x4008)
+ {
+ FIFOInit(MMU.fifos + (IPCFIFO+((proc+1)&1)));
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, (cnt_l & 0x0301) | (val & 0x8404) | 1);
+ T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, (cnt_r & 0xC507) | 0x100);
+ MMU.reg_IF[proc] |= ((val & 4)<<15);// & (MMU.reg_IME[proc]<<17);// & (MMU.reg_IE[proc]&0x20000);//
+ return;
+ }
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, val & 0xBFF4);
+ //execute = false;
+ return;
+ }
+ case REG_IPCFIFOSEND :
+ {
+ u16 IPCFIFO_CNT = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184);
+ if(IPCFIFO_CNT&0x8000)
+ {
+ //if(val==43) execute = false;
+ u32 remote = (proc+1)&1;
+ u32 fifonum = IPCFIFO+remote;
+ u16 IPCFIFO_CNT_remote;
+ FIFOAdd(MMU.fifos + fifonum, val);
+ IPCFIFO_CNT = (IPCFIFO_CNT & 0xFFFC) | (MMU.fifos[fifonum].full<<1);
+ IPCFIFO_CNT_remote = T1ReadWord(MMU.MMU_MEM[remote][0x40], 0x184);
+ IPCFIFO_CNT_remote = (IPCFIFO_CNT_remote & 0xFCFF) | (MMU.fifos[fifonum].full<<10);
+ T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, IPCFIFO_CNT);
+ T1WriteWord(MMU.MMU_MEM[remote][0x40], 0x184, IPCFIFO_CNT_remote);
+ MMU.reg_IF[remote] |= ((IPCFIFO_CNT_remote & (1<<10))<<8);// & (MMU.reg_IME[remote] << 18);// & (MMU.reg_IE[remote] & 0x40000);//
+ //execute = false;
+ }
+ }
+ return;
+ case REG_DMA0CNTL :
+ //LOG("32 bit dma0 %04X\r\n", val);
+ DMASrc[proc][0] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xB0);
+ DMADst[proc][0] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xB4);
+ MMU.DMAStartTime[proc][0] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7);
+ MMU.DMACrt[proc][0] = val;
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0xB8, val);
+ if( MMU.DMAStartTime[proc][0] == 0 ||
+ MMU.DMAStartTime[proc][0] == 7) // Start Immediately
+ MMU_doDMA(proc, 0);
+ #ifdef LOG_DMA2
+ else
+ {
+ LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 0, DMASrc[proc][0], DMADst[proc][0], 0, ((MMU.DMACrt[proc][0]>>27)&7));
+ }
+ #endif
+ //execute = false;
+ return;
+ case REG_DMA1CNTL:
+ //LOG("32 bit dma1 %04X\r\n", val);
+ DMASrc[proc][1] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xBC);
+ DMADst[proc][1] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xC0);
+ MMU.DMAStartTime[proc][1] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7);
+ MMU.DMACrt[proc][1] = val;
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0xC4, val);
+ if(MMU.DMAStartTime[proc][1] == 0 ||
+ MMU.DMAStartTime[proc][1] == 7) // Start Immediately
+ MMU_doDMA(proc, 1);
+ #ifdef LOG_DMA2
+ else
+ {
+ LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 1, DMASrc[proc][1], DMADst[proc][1], 0, ((MMU.DMACrt[proc][1]>>27)&7));
+ }
+ #endif
+ return;
+ case REG_DMA2CNTL :
+ //LOG("32 bit dma2 %04X\r\n", val);
+ DMASrc[proc][2] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xC8);
+ DMADst[proc][2] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xCC);
+ MMU.DMAStartTime[proc][2] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7);
+ MMU.DMACrt[proc][2] = val;
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0xD0, val);
+ if(MMU.DMAStartTime[proc][2] == 0 ||
+ MMU.DMAStartTime[proc][2] == 7) // Start Immediately
+ MMU_doDMA(proc, 2);
+ #ifdef LOG_DMA2
+ else
+ {
+ LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 2, DMASrc[proc][2], DMADst[proc][2], 0, ((MMU.DMACrt[proc][2]>>27)&7));
+ }
+ #endif
+ return;
+ case 0x040000DC :
+ //LOG("32 bit dma3 %04X\r\n", val);
+ DMASrc[proc][3] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xD4);
+ DMADst[proc][3] = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xD8);
+ MMU.DMAStartTime[proc][3] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7);
+ MMU.DMACrt[proc][3] = val;
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0xDC, val);
+ if( MMU.DMAStartTime[proc][3] == 0 ||
+ MMU.DMAStartTime[proc][3] == 7) // Start Immediately
+ MMU_doDMA(proc, 3);
+ #ifdef LOG_DMA2
+ else
+ {
+ LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 3, DMASrc[proc][3], DMADst[proc][3], 0, ((MMU.DMACrt[proc][3]>>27)&7));
+ }
+ #endif
+ return;
+ case REG_GCROMCTRL :
+ {
+ int i;
+
+ if(MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT) == 0xB7)
+ {
+ MMU.dscard[proc].adress = (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+1) << 24) | (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+2) << 16) | (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+3) << 8) | (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+4));
+ MMU.dscard[proc].transfer_count = 0x80;// * ((val>>24)&7));
+ }
+ else if (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT) == 0xB8)
+ {
+ // Get ROM chip ID
+ val |= 0x800000; // Data-Word Status
+ T1WriteLong(MMU.MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val);
+ MMU.dscard[proc].adress = 0;
+ }
+ else
+ {
+ LOG("CARD command: %02X\n", MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT));
+ }
+
+ //CARDLOG("%08X : %08X %08X\r\n", adr, val, adresse[proc]);
+ val |= 0x00800000;
+
+ if(MMU.dscard[proc].adress == 0)
+ {
+ val &= ~0x80000000;
+ T1WriteLong(MMU.MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val);
+ return;
+ }
+ T1WriteLong(MMU.MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val);
+
+ /* launch DMA if start flag was set to "DS Cart" */
+ if(proc == ARMCPU_ARM7) i = 2;
+ else i = 5;
+
+ if(proc == ARMCPU_ARM9 && MMU.DMAStartTime[proc][0] == i) /* dma0/1 on arm7 can't start on ds cart event */
+ {
+ MMU_doDMA(proc, 0);
+ return;
+ }
+ else if(proc == ARMCPU_ARM9 && MMU.DMAStartTime[proc][1] == i)
+ {
+ MMU_doDMA(proc, 1);
+ return;
+ }
+ else if(MMU.DMAStartTime[proc][2] == i)
+ {
+ MMU_doDMA(proc, 2);
+ return;
+ }
+ else if(MMU.DMAStartTime[proc][3] == i)
+ {
+ MMU_doDMA(proc, 3);
+ return;
+ }
+ return;
+
+ }
+ return;
+ case REG_DISPA_DISPCAPCNT :
+ if(proc == ARMCPU_ARM9)
+ {
+ GPU_set_DISPCAPCNT(MainScreen.gpu,val);
+ T1WriteLong(ARM9Mem.ARM9_REG, 0x64, val);
+ }
+ return;
+
+ case REG_DISPA_BG0CNT :
+ if (proc == ARMCPU_ARM9)
+ {
+ GPU_setBGProp(MainScreen.gpu, 0, (val&0xFFFF));
+ GPU_setBGProp(MainScreen.gpu, 1, (val>>16));
+ }
+ //if((val>>16)==0x400) execute = false;
+ T1WriteLong(ARM9Mem.ARM9_REG, 8, val);
+ return;
+ case REG_DISPA_BG2CNT :
+ if (proc == ARMCPU_ARM9)
+ {
+ GPU_setBGProp(MainScreen.gpu, 2, (val&0xFFFF));
+ GPU_setBGProp(MainScreen.gpu, 3, (val>>16));
+ }
+ T1WriteLong(ARM9Mem.ARM9_REG, 0xC, val);
+ return;
+ case REG_DISPB_BG0CNT :
+ if (proc == ARMCPU_ARM9)
+ {
+ GPU_setBGProp(SubScreen.gpu, 0, (val&0xFFFF));
+ GPU_setBGProp(SubScreen.gpu, 1, (val>>16));
+ }
+ T1WriteLong(ARM9Mem.ARM9_REG, 0x1008, val);
+ return;
+ case REG_DISPB_BG2CNT :
+ if (proc == ARMCPU_ARM9)
+ {
+ GPU_setBGProp(SubScreen.gpu, 2, (val&0xFFFF));
+ GPU_setBGProp(SubScreen.gpu, 3, (val>>16));
+ }
+ T1WriteLong(ARM9Mem.ARM9_REG, 0x100C, val);
+ return;
+ case REG_DISPA_DISPMMEMFIFO:
+ {
+ // NOTE: right now, the capture unit is not taken into account,
+ // I don't know is it should be handled here or
+
+ FIFOAdd(MMU.fifos + MAIN_MEMORY_DISP_FIFO, val);
+ break;
+ }
+ //case 0x21FDFF0 : if(val==0) execute = false;
+ //case 0x21FDFB0 : if(val==0) execute = false;
+ default :
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], adr & MMU.MMU_MASK[proc][(adr>>20)&0xFF], val);
+ return;
+ }
+ }
+ T1WriteLong(MMU.MMU_MEM[proc][(adr>>20)&0xFF], adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF], val);
+}
+
+
+void FASTCALL MMU_doDMA(u32 proc, u32 num)
+{
+ u32 src = DMASrc[proc][num];
+ u32 dst = DMADst[proc][num];
+ u32 taille;
+
+ if(src==dst)
+ {
+ T1WriteLong(MMU.MMU_MEM[proc][0x40], 0xB8 + (0xC*num), T1ReadLong(MMU.MMU_MEM[proc][0x40], 0xB8 + (0xC*num)) & 0x7FFFFFFF);
+ return;
+ }
+
+ if((!(MMU.DMACrt[proc][num]&(1<<31)))&&(!(MMU.DMACrt[proc][num]&(1<<25))))
+ { /* not enabled and not to be repeated */
+ MMU.DMAStartTime[proc][num] = 0;
+ MMU.DMACycle[proc][num] = 0;
+ //MMU.DMAing[proc][num] = false;
+ return;
+ }
+
+
+ /* word count */
+ taille = (MMU.DMACrt[proc][num]&0xFFFF);
+
+ // If we are in "Main memory display" mode just copy an entire
+ // screen (256x192 pixels).
+ // Reference: http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode
+ // (under DISP_MMEM_FIFO)
+ if ((MMU.DMAStartTime[proc][num]==4) && // Must be in main memory display mode
+ (taille==4) && // Word must be 4
+ (((MMU.DMACrt[proc][num]>>26)&1) == 1)) // Transfer mode must be 32bit wide
+ taille = 256*192/2;
+
+ if(MMU.DMAStartTime[proc][num] == 5)
+ taille *= 0x80;
+
+ MMU.DMACycle[proc][num] = taille + nds.cycles;
+ MMU.DMAing[proc][num] = true;
+
+ DMALOG("proc %d, dma %d src %08X dst %08X start %d taille %d repeat %s %08X\r\n",
+ proc, num, src, dst, MMU.DMAStartTime[proc][num], taille,
+ (MMU.DMACrt[proc][num]&(1<<25))?"on":"off",MMU.DMACrt[proc][num]);
+
+ if(!(MMU.DMACrt[proc][num]&(1<<25)))
+ MMU.DMAStartTime[proc][num] = 0;
+
+ // transfer
+ {
+ u32 i=0;
+ // 32 bit or 16 bit transfer ?
+ int sz = ((MMU.DMACrt[proc][num]>>26)&1)? 4 : 2;
+ int dstinc,srcinc;
+ int u=(MMU.DMACrt[proc][num]>>21);
+ switch(u & 0x3) {
+ case 0 : dstinc = sz; break;
+ case 1 : dstinc = -sz; break;
+ case 2 : dstinc = 0; break;
+ case 3 : dstinc = sz; break; //reload
+ }
+ switch((u >> 2)&0x3) {
+ case 0 : srcinc = sz; break;
+ case 1 : srcinc = -sz; break;
+ case 2 : srcinc = 0; break;
+ case 3 : // reserved
+ return;
+ }
+ if ((MMU.DMACrt[proc][num]>>26)&1)
+ for(; i < taille; ++i)
+ {
+ MMU_write32(proc, dst, MMU_read32(proc, src));
+ dst += dstinc;
+ src += srcinc;
+ }
+ else
+ for(; i < taille; ++i)
+ {
+ MMU_write16(proc, dst, MMU_read16(proc, src));
+ dst += dstinc;
+ src += srcinc;
+ }
+ }
+}
+
+#ifdef MMU_ENABLE_ACL
+
+INLINE void check_access(u32 adr, u32 access) {
+ /* every other mode: sys */
+ access |= 1;
+ if ((NDS_ARM9.CPSR.val & 0x1F) == 0x10) {
+ /* is user mode access */
+ access ^= 1 ;
+ }
+ if (armcp15_isAccessAllowed((armcp15_t *)NDS_ARM9.coproc[15],adr,access)==false) {
+ execute = false ;
+ }
+}
+INLINE void check_access_write(u32 adr) {
+ u32 access = CP15_ACCESS_WRITE;
+ check_access(adr, access)
+}
+
+u8 FASTCALL MMU_read8_acl(u32 proc, u32 adr, u32 access)
+{
+ /* on arm9 we need to check the MPU regions */
+ if (proc == ARMCPU_ARM9)
+ check_access(u32 adr, u32 access);
+ return MMU_read8(proc,adr);
+}
+u16 FASTCALL MMU_read16_acl(u32 proc, u32 adr, u32 access)
+{
+ /* on arm9 we need to check the MPU regions */
+ if (proc == ARMCPU_ARM9)
+ check_access(u32 adr, u32 access);
+ return MMU_read16(proc,adr);
+}
+u32 FASTCALL MMU_read32_acl(u32 proc, u32 adr, u32 access)
+{
+ /* on arm9 we need to check the MPU regions */
+ if (proc == ARMCPU_ARM9)
+ check_access(u32 adr, u32 access);
+ return MMU_read32(proc,adr);
+}
+
+void FASTCALL MMU_write8_acl(u32 proc, u32 adr, u8 val)
+{
+ /* check MPU region on ARM9 */
+ if (proc == ARMCPU_ARM9)
+ check_access_write(adr);
+ MMU_write8(proc,adr,val);
+}
+void FASTCALL MMU_write16_acl(u32 proc, u32 adr, u16 val)
+{
+ /* check MPU region on ARM9 */
+ if (proc == ARMCPU_ARM9)
+ check_access_write(adr);
+ MMU_write16(proc,adr,val) ;
+}
+void FASTCALL MMU_write32_acl(u32 proc, u32 adr, u32 val)
+{
+ /* check MPU region on ARM9 */
+ if (proc == ARMCPU_ARM9)
+ check_access_write(adr);
+ MMU_write32(proc,adr,val) ;
+}
+#endif
+
+
+
+#ifdef PROFILE_MEMORY_ACCESS
+
+#define PROFILE_PREFETCH 0
+#define PROFILE_READ 1
+#define PROFILE_WRITE 2
+
+struct mem_access_profile {
+ u64 num_accesses;
+ u32 address_mask;
+ u32 masked_value;
+};
+
+#define PROFILE_NUM_MEM_ACCESS_PROFILES 4
+
+static u64 profile_num_accesses[2][3];
+static u64 profile_unknown_addresses[2][3];
+static struct mem_access_profile
+profile_memory_accesses[2][3][PROFILE_NUM_MEM_ACCESS_PROFILES];
+
+static void
+setup_profiling( void) {
+ int i;
+
+ for ( i = 0; i < 2; i++) {
+ int access_type;
+
+ for ( access_type = 0; access_type < 3; access_type++) {
+ profile_num_accesses[i][access_type] = 0;
+ profile_unknown_addresses[i][access_type] = 0;
+
+ /*
+ * Setup the access testing structures
+ */
+ profile_memory_accesses[i][access_type][0].address_mask = 0x0e000000;
+ profile_memory_accesses[i][access_type][0].masked_value = 0x00000000;
+ profile_memory_accesses[i][access_type][0].num_accesses = 0;
+
+ /* main memory */
+ profile_memory_accesses[i][access_type][1].address_mask = 0x0f000000;
+ profile_memory_accesses[i][access_type][1].masked_value = 0x02000000;
+ profile_memory_accesses[i][access_type][1].num_accesses = 0;
+
+ /* shared memory */
+ profile_memory_accesses[i][access_type][2].address_mask = 0x0f800000;
+ profile_memory_accesses[i][access_type][2].masked_value = 0x03000000;
+ profile_memory_accesses[i][access_type][2].num_accesses = 0;
+
+ /* arm7 memory */
+ profile_memory_accesses[i][access_type][3].address_mask = 0x0f800000;
+ profile_memory_accesses[i][access_type][3].masked_value = 0x03800000;
+ profile_memory_accesses[i][access_type][3].num_accesses = 0;
+ }
+ }
+}
+
+static void
+profile_memory_access( int arm9, u32 adr, int access_type) {
+ static int first = 1;
+ int mem_profile;
+ int address_found = 0;
+
+ if ( first) {
+ setup_profiling();
+ first = 0;
+ }
+
+ profile_num_accesses[arm9][access_type] += 1;
+
+ for ( mem_profile = 0;
+ mem_profile < PROFILE_NUM_MEM_ACCESS_PROFILES &&
+ !address_found;
+ mem_profile++) {
+ if ( (adr & profile_memory_accesses[arm9][access_type][mem_profile].address_mask) ==
+ profile_memory_accesses[arm9][access_type][mem_profile].masked_value) {
+ /*printf( "adr %08x mask %08x res %08x expected %08x\n",
+ adr,
+ profile_memory_accesses[arm9][access_type][mem_profile].address_mask,
+ adr & profile_memory_accesses[arm9][access_type][mem_profile].address_mask,
+ profile_memory_accesses[arm9][access_type][mem_profile].masked_value);*/
+ address_found = 1;
+ profile_memory_accesses[arm9][access_type][mem_profile].num_accesses += 1;
+ }
+ }
+
+ if ( !address_found) {
+ profile_unknown_addresses[arm9][access_type] += 1;
+ }
+}
+
+
+static const char *access_type_strings[] = {
+ "prefetch",
+ "read ",
+ "write "
+};
+
+void
+print_memory_profiling( void) {
+ int arm;
+
+ printf("------ Memory access profile ------\n");
+
+ for ( arm = 0; arm < 2; arm++) {
+ int access_type;
+
+ for ( access_type = 0; access_type < 3; access_type++) {
+ int mem_profile;
+ printf("ARM%c: num of %s %lld\n",
+ arm ? '9' : '7',
+ access_type_strings[access_type],
+ profile_num_accesses[arm][access_type]);
+
+ for ( mem_profile = 0;
+ mem_profile < PROFILE_NUM_MEM_ACCESS_PROFILES;
+ mem_profile++) {
+ printf( "address %08lx: %llu\n",
+ profile_memory_accesses[arm][access_type][mem_profile].masked_value,
+ profile_memory_accesses[arm][access_type][mem_profile].num_accesses);
+ }
+
+ printf( "unknown addresses %lld\n",
+ profile_unknown_addresses[arm][access_type]);
+
+ printf( "\n");
+ }
+ }
+
+ printf("------ End of Memory access profile ------\n\n");
+}
+#else
+void
+print_memory_profiling( void) {
+}
+#endif /* End of PROFILE_MEMORY_ACCESS area */
+
+static u16 FASTCALL
+arm9_prefetch16( void *data, u32 adr) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 1, adr, PROFILE_PREFETCH);
+#endif
+
+#ifdef EARLY_MEMORY_ACCESS
+ if((adr & ~0x3FFF) == MMU.DTCMRegion)
+ {
+ /* Returns data from DTCM (ARM9 only) */
+ return T1ReadWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
+ }
+ /* access to main memory */
+ if ( (adr & 0x0f000000) == 0x02000000) {
+ return T1ReadWord( MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF],
+ adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
+ }
+#endif
+
+ return MMU_read16( ARMCPU_ARM9, adr);
+}
+static u32 FASTCALL
+arm9_prefetch32( void *data, u32 adr) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 1, adr, PROFILE_PREFETCH);
+#endif
+
+#ifdef EARLY_MEMORY_ACCESS
+ if((adr & ~0x3FFF) == MMU.DTCMRegion)
+ {
+ /* Returns data from DTCM (ARM9 only) */
+ return T1ReadLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
+ }
+ /* access to main memory */
+ if ( (adr & 0x0f000000) == 0x02000000) {
+ return T1ReadLong( MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF],
+ adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
+ }
+#endif
+
+ return MMU_read32( ARMCPU_ARM9, adr);
+}
+
+static u8 FASTCALL
+arm9_read8( void *data, u32 adr) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 1, adr, PROFILE_READ);
+#endif
+
+#ifdef EARLY_MEMORY_ACCESS
+ if( (adr&(~0x3FFF)) == MMU.DTCMRegion)
+ {
+ return ARM9Mem.ARM9_DTCM[adr&0x3FFF];
+ }
+ /* access to main memory */
+ if ( (adr & 0x0f000000) == 0x02000000) {
+ return MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF]
+ [adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]];
+ }
+#endif
+
+ return MMU_read8( ARMCPU_ARM9, adr);
+}
+static u16 FASTCALL
+arm9_read16( void *data, u32 adr) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 1, adr, PROFILE_READ);
+#endif
+
+#ifdef EARLY_MEMORY_ACCESS
+ if((adr & ~0x3FFF) == MMU.DTCMRegion)
+ {
+ /* Returns data from DTCM (ARM9 only) */
+ return T1ReadWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
+ }
+
+ /* access to main memory */
+ if ( (adr & 0x0f000000) == 0x02000000) {
+ return T1ReadWord( MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF],
+ adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
+ }
+#endif
+
+ return MMU_read16( ARMCPU_ARM9, adr);
+}
+static u32 FASTCALL
+arm9_read32( void *data, u32 adr) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 1, adr, PROFILE_READ);
+#endif
+
+#ifdef EARLY_MEMORY_ACCESS
+ if((adr & ~0x3FFF) == MMU.DTCMRegion)
+ {
+ /* Returns data from DTCM (ARM9 only) */
+ return T1ReadLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
+ }
+ /* access to main memory */
+ if ( (adr & 0x0f000000) == 0x02000000) {
+ return T1ReadLong( MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF],
+ adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
+ }
+#endif
+
+ return MMU_read32( ARMCPU_ARM9, adr);
+}
+
+
+static void FASTCALL
+arm9_write8(void *data, u32 adr, u8 val) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 1, adr, PROFILE_WRITE);
+#endif
+
+#ifdef EARLY_MEMORY_ACCESS
+ if( (adr & ~0x3FFF) == MMU.DTCMRegion)
+ {
+ /* Writes data in DTCM (ARM9 only) */
+ ARM9Mem.ARM9_DTCM[adr&0x3FFF] = val;
+ return ;
+ }
+ /* main memory */
+ if ( (adr & 0x0f000000) == 0x02000000) {
+ MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF]
+ [adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF]] = val;
+ return;
+ }
+#endif
+
+ MMU_write8( ARMCPU_ARM9, adr, val);
+}
+static void FASTCALL
+arm9_write16(void *data, u32 adr, u16 val) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 1, adr, PROFILE_WRITE);
+#endif
+
+#ifdef EARLY_MEMORY_ACCESS
+ if((adr & ~0x3FFF) == MMU.DTCMRegion)
+ {
+ /* Writes in DTCM (ARM9 only) */
+ T1WriteWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF, val);
+ return;
+ }
+ /* main memory */
+ if ( (adr & 0x0f000000) == 0x02000000) {
+ T1WriteWord( MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF],
+ adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF], val);
+ return;
+ }
+#endif
+
+ MMU_write16( ARMCPU_ARM9, adr, val);
+}
+static void FASTCALL
+arm9_write32(void *data, u32 adr, u32 val) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 1, adr, PROFILE_WRITE);
+#endif
+
+#ifdef EARLY_MEMORY_ACCESS
+ if((adr & ~0x3FFF) == MMU.DTCMRegion)
+ {
+ /* Writes in DTCM (ARM9 only) */
+ T1WriteLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF, val);
+ return;
+ }
+ /* main memory */
+ if ( (adr & 0x0f000000) == 0x02000000) {
+ T1WriteLong( MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF],
+ adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF], val);
+ return;
+ }
+#endif
+
+ MMU_write32( ARMCPU_ARM9, adr, val);
+}
+
+
+
+
+static u16 FASTCALL
+arm7_prefetch16( void *data, u32 adr) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 0, adr, PROFILE_PREFETCH);
+#endif
+
+#ifdef EARLY_MEMORY_ACCESS
+ /* ARM7 private memory */
+ if ( (adr & 0x0f800000) == 0x03800000) {
+ T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][(adr >> 20) & 0xFF],
+ adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr >> 20) & 0xFF]);
+ }
+#endif
+
+ return MMU_read16( ARMCPU_ARM7, adr);
+}
+static u32 FASTCALL
+arm7_prefetch32( void *data, u32 adr) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 0, adr, PROFILE_PREFETCH);
+#endif
+
+#ifdef EARLY_MEMORY_ACCESS
+ /* ARM7 private memory */
+ if ( (adr & 0x0f800000) == 0x03800000) {
+ T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][(adr >> 20) & 0xFF],
+ adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr >> 20) & 0xFF]);
+ }
+#endif
+
+ return MMU_read32( ARMCPU_ARM7, adr);
+}
+
+static u8 FASTCALL
+arm7_read8( void *data, u32 adr) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 0, adr, PROFILE_READ);
+#endif
+
+ return MMU_read8( ARMCPU_ARM7, adr);
+}
+static u16 FASTCALL
+arm7_read16( void *data, u32 adr) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 0, adr, PROFILE_READ);
+#endif
+
+ return MMU_read16( ARMCPU_ARM7, adr);
+}
+static u32 FASTCALL
+arm7_read32( void *data, u32 adr) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 0, adr, PROFILE_READ);
+#endif
+
+ return MMU_read32( ARMCPU_ARM7, adr);
+}
+
+
+static void FASTCALL
+arm7_write8(void *data, u32 adr, u8 val) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 0, adr, PROFILE_WRITE);
+#endif
+
+ MMU_write8( ARMCPU_ARM7, adr, val);
+}
+static void FASTCALL
+arm7_write16(void *data, u32 adr, u16 val) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 0, adr, PROFILE_WRITE);
+#endif
+
+ MMU_write16( ARMCPU_ARM7, adr, val);
+}
+static void FASTCALL
+arm7_write32(void *data, u32 adr, u32 val) {
+#ifdef PROFILE_MEMORY_ACCESS
+ profile_memory_access( 0, adr, PROFILE_WRITE);
+#endif
+
+ MMU_write32( ARMCPU_ARM7, adr, val);
+}
+
+
+
+/*
+ * the base memory interfaces
+ */
+struct armcpu_memory_iface arm9_base_memory_iface = {
+ arm9_prefetch32,
+ arm9_prefetch16,
+
+ arm9_read8,
+ arm9_read16,
+ arm9_read32,
+
+ arm9_write8,
+ arm9_write16,
+ arm9_write32
+};
+
+struct armcpu_memory_iface arm7_base_memory_iface = {
+ arm7_prefetch32,
+ arm7_prefetch16,
+
+ arm7_read8,
+ arm7_read16,
+ arm7_read32,
+
+ arm7_write8,
+ arm7_write16,
+ arm7_write32
+};
+
+/*
+ * The direct memory interface for the ARM9.
+ * This avoids the ARM9 protection unit when accessing
+ * memory.
+ */
+struct armcpu_memory_iface arm9_direct_memory_iface = {
+ /* the prefetch is not used */
+ nullptr,
+ nullptr,
+
+ arm9_read8,
+ arm9_read16,
+ arm9_read32,
+
+ arm9_write8,
+ arm9_write16,
+ arm9_write32
+};
diff --git a/src/xsf/desmume/MMU.h b/src/xsf/desmume/MMU.h
index 75c46c844ed5..e9b7263a7ea1 100644
--- a/src/xsf/desmume/MMU.h
+++ b/src/xsf/desmume/MMU.h
@@ -18,7 +18,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MMU_H
@@ -30,10 +30,6 @@
#include "ARM9.h"
#include "mc.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
extern char szRomPath[512];
extern char szRomBaseName[512];
@@ -42,35 +38,35 @@ extern char szRomBaseName[512];
/* theses ones for reading in rom data */
#define ROM_8(m, a) (((u8*)(m))[(a)])
-
+
#define IPCFIFO 0
#define MAIN_MEMORY_DISP_FIFO 2
-
+
typedef struct {
//ARM7 mem
u8 ARM7_BIOS[0x4000];
u8 ARM7_ERAM[0x10000];
u8 ARM7_REG[0x10000];
u8 ARM7_WIRAM[0x10000];
-
+
u8 vram_mode[9];
u8 vScreen;
//Shared ram
u8 SWIRAM[0x8000];
-
+
//Card rom & ram
u8 * CART_ROM;
u8 CART_RAM[0x10000];
//Unused ram
u8 UNUSED_RAM[4];
-
+
u8 * * MMU_MEM[2];
u32 * MMU_MASK[2];
-
+
u8 ARM9_RW_MODE;
-
+
FIFO fifos[16];
u32 * MMU_WAIT16[2];
@@ -78,27 +74,27 @@ typedef struct {
u32 DTCMRegion;
u32 ITCMRegion;
-
+
u16 timer[2][4];
s32 timerMODE[2][4];
u32 timerON[2][4];
u32 timerRUN[2][4];
u16 timerReload[2][4];
-
+
u32 reg_IME[2];
u32 reg_IE[2];
u32 reg_IF[2];
-
+
u32 DMAStartTime[2][4];
s32 DMACycle[2][4];
u32 DMACrt[2][4];
BOOL DMAing[2][4];
-
+
memory_chip_t fw;
memory_chip_t bupmem;
-
+
nds_dscard dscard[2];
-
+
} MMU_struct;
extern MMU_struct MMU;
@@ -171,7 +167,7 @@ void FASTCALL MMU_write32(u32 proc, u32 adr, u32 val);
#define MMU_write16_acl MMU_write16
#define MMU_write32_acl MMU_write32
#endif
-
+
void FASTCALL MMU_doDMA(u32 proc, u32 num);
@@ -180,11 +176,6 @@ void FASTCALL MMU_doDMA(u32 proc, u32 num);
*/
extern struct armcpu_memory_iface arm9_base_memory_iface;
extern struct armcpu_memory_iface arm7_base_memory_iface;
-extern struct armcpu_memory_iface arm9_direct_memory_iface;
-
-
-#ifdef __cplusplus
-}
-#endif
+extern struct armcpu_memory_iface arm9_direct_memory_iface;
#endif
diff --git a/src/xsf/desmume/NDSSystem.c b/src/xsf/desmume/NDSSystem.c
deleted file mode 100644
index cb656c4e41f3..000000000000
--- a/src/xsf/desmume/NDSSystem.c
+++ /dev/null
@@ -1,748 +0,0 @@
-/* Copyright (C) 2006 yopyop
- yopyop156 at ifrance.com
- yopyop156.ifrance.com
-
- This file is part of DeSmuME
-
- DeSmuME 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.
-
- DeSmuME 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 DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "NDSSystem.h"
-#include "MMU.h"
-//#include "cflash.h"
-
-//#include "ROMReader.h"
-
-/* the count of bytes copied from the firmware into memory */
-#define NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT 0x70
-
-NDSSystem nds;
-
-static u32
-calc_CRC16( u32 start, const u8 *data, int count) {
- int i,j;
- u32 crc = start & 0xffff;
- static u16 val[] = { 0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001 };
- for(i = 0; i < count; i++)
- {
- crc = crc ^ data[i];
-
- for(j = 0; j < 8; j++) {
- int do_bit = 0;
-
- if ( crc & 0x1)
- do_bit = 1;
-
- crc = crc >> 1;
-
- if ( do_bit) {
- crc = crc ^ (val[j] << (7-j));
- }
- }
- }
- return crc;
-}
-
-static int
-copy_firmware_user_data( u8 *dest_buffer, const u8 *fw_data) {
- /*
- * Determine which of the two user settings in the firmware is the current
- * and valid one and then copy this into the destination buffer.
- *
- * The current setting will have a greater count.
- * Settings are only valid if its CRC16 is correct.
- */
- int user1_valid = 0;
- int user2_valid = 0;
- u32 user_settings_offset;
- u32 fw_crc;
- u32 crc;
- int copy_good = 0;
-
- user_settings_offset = fw_data[0x20];
- user_settings_offset |= fw_data[0x21] << 8;
- user_settings_offset <<= 3;
-
- if ( user_settings_offset <= 0x3FE00) {
- s32 copy_settings_offset = -1;
-
- crc = calc_CRC16( 0xffff, &fw_data[user_settings_offset],
- NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT);
- fw_crc = fw_data[user_settings_offset + 0x72];
- fw_crc |= fw_data[user_settings_offset + 0x73] << 8;
- if ( crc == fw_crc) {
- user1_valid = 1;
- }
-
- crc = calc_CRC16( 0xffff, &fw_data[user_settings_offset + 0x100],
- NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT);
- fw_crc = fw_data[user_settings_offset + 0x100 + 0x72];
- fw_crc |= fw_data[user_settings_offset + 0x100 + 0x73] << 8;
- if ( crc == fw_crc) {
- user2_valid = 1;
- }
-
- if ( user1_valid) {
- if ( user2_valid) {
- u16 count1, count2;
-
- count1 = fw_data[user_settings_offset + 0x70];
- count1 |= fw_data[user_settings_offset + 0x71] << 8;
-
- count2 = fw_data[user_settings_offset + 0x100 + 0x70];
- count2 |= fw_data[user_settings_offset + 0x100 + 0x71] << 8;
-
- if ( count2 > count1) {
- copy_settings_offset = user_settings_offset + 0x100;
- }
- else {
- copy_settings_offset = user_settings_offset;
- }
- }
- else {
- copy_settings_offset = user_settings_offset;
- }
- }
- else if ( user2_valid) {
- /* copy the second user settings */
- copy_settings_offset = user_settings_offset + 0x100;
- }
-
- if ( copy_settings_offset > 0) {
- memcpy( dest_buffer, &fw_data[copy_settings_offset],
- NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT);
- copy_good = 1;
- }
- }
-
- return copy_good;
-}
-
-
-#ifdef GDB_STUB
-int NDS_Init( struct armcpu_memory_iface *arm9_mem_if,
- struct armcpu_ctrl_iface **arm9_ctrl_iface,
- struct armcpu_memory_iface *arm7_mem_if,
- struct armcpu_ctrl_iface **arm7_ctrl_iface) {
-#else
-int NDS_Init( void) {
-#endif
- nds.ARM9Cycle = 0;
- nds.ARM7Cycle = 0;
- nds.cycles = 0;
- MMU_Init();
- nds.nextHBlank = 3168;
- nds.VCount = 0;
- nds.lignerendu = FALSE;
-
- if (Screen_Init(GFXCORE_DUMMY) != 0)
- return -1;
-
- #ifdef GDB_STUB
- armcpu_new(&NDS_ARM7,1, arm7_mem_if, arm7_ctrl_iface);
- armcpu_new(&NDS_ARM9,0, arm9_mem_if, arm9_ctrl_iface);
-#else
- armcpu_new(&NDS_ARM7,1);
- armcpu_new(&NDS_ARM9,0);
-#endif
-
- if (SPU_Init(SNDCORE_DUMMY, 735) != 0)
- return -1;
-
-#ifdef EXPERIMENTAL_WIFI
- WIFI_Init(&wifiMac) ;
-#endif
-
- return 0;
-}
-
-static void armcpu_deinit(armcpu_t *armcpu)
-{
- if(armcpu->coproc[15])
- {
- free(armcpu->coproc[15]);
- armcpu->coproc[15] = 0;
- }
-}
-
-void NDS_DeInit(void) {
- if(MMU.CART_ROM != MMU.UNUSED_RAM)
- NDS_FreeROM();
-
- armcpu_deinit(&NDS_ARM7);
- armcpu_deinit(&NDS_ARM9);
-
- nds.nextHBlank = 3168;
- SPU_DeInit();
- Screen_DeInit();
- MMU_DeInit();
-}
-
-BOOL NDS_SetROM(u8 * rom, u32 mask)
-{
- MMU_setRom(rom, mask);
-
- return TRUE;
-}
-
-NDS_header * NDS_getROMHeader(void)
-{
- NDS_header * header = malloc(sizeof(NDS_header));
-
- memcpy(header->gameTile, MMU.CART_ROM, 12);
- memcpy(header->gameCode, MMU.CART_ROM + 12, 4);
- header->makerCode = T1ReadWord(MMU.CART_ROM, 16);
- header->unitCode = MMU.CART_ROM[18];
- header->deviceCode = MMU.CART_ROM[19];
- header->cardSize = MMU.CART_ROM[20];
- memcpy(header->cardInfo, MMU.CART_ROM + 21, 8);
- header->flags = MMU.CART_ROM[29];
- header->ARM9src = T1ReadLong(MMU.CART_ROM, 32);
- header->ARM9exe = T1ReadLong(MMU.CART_ROM, 36);
- header->ARM9cpy = T1ReadLong(MMU.CART_ROM, 40);
- header->ARM9binSize = T1ReadLong(MMU.CART_ROM, 44);
- header->ARM7src = T1ReadLong(MMU.CART_ROM, 48);
- header->ARM7exe = T1ReadLong(MMU.CART_ROM, 52);
- header->ARM7cpy = T1ReadLong(MMU.CART_ROM, 56);
- header->ARM7binSize = T1ReadLong(MMU.CART_ROM, 60);
- header->FNameTblOff = T1ReadLong(MMU.CART_ROM, 64);
- header->FNameTblSize = T1ReadLong(MMU.CART_ROM, 68);
- header->FATOff = T1ReadLong(MMU.CART_ROM, 72);
- header->FATSize = T1ReadLong(MMU.CART_ROM, 76);
- header->ARM9OverlayOff = T1ReadLong(MMU.CART_ROM, 80);
- header->ARM9OverlaySize = T1ReadLong(MMU.CART_ROM, 84);
- header->ARM7OverlayOff = T1ReadLong(MMU.CART_ROM, 88);
- header->ARM7OverlaySize = T1ReadLong(MMU.CART_ROM, 92);
- header->unknown2a = T1ReadLong(MMU.CART_ROM, 96);
- header->unknown2b = T1ReadLong(MMU.CART_ROM, 100);
- header->IconOff = T1ReadLong(MMU.CART_ROM, 104);
- header->CRC16 = T1ReadWord(MMU.CART_ROM, 108);
- header->ROMtimeout = T1ReadWord(MMU.CART_ROM, 110);
- header->ARM9unk = T1ReadLong(MMU.CART_ROM, 112);
- header->ARM7unk = T1ReadLong(MMU.CART_ROM, 116);
- memcpy(header->unknown3c, MMU.CART_ROM + 120, 8);
- header->ROMSize = T1ReadLong(MMU.CART_ROM, 128);
- header->HeaderSize = T1ReadLong(MMU.CART_ROM, 132);
- memcpy(header->unknown5, MMU.CART_ROM + 136, 56);
- memcpy(header->logo, MMU.CART_ROM + 192, 156);
- header->logoCRC16 = T1ReadWord(MMU.CART_ROM, 348);
- header->headerCRC16 = T1ReadWord(MMU.CART_ROM, 350);
- memcpy(header->reserved, MMU.CART_ROM + 352, 160);
-
- return header;
-
- //return (NDS_header *)MMU.CART_ROM;
-}
-
-
-
-void NDS_FreeROM(void)
-{
- if (MMU.CART_ROM != MMU.UNUSED_RAM)
- free(MMU.CART_ROM);
- MMU_unsetRom();
-// if (MMU.bupmem.fp)
-// fclose(MMU.bupmem.fp);
-// MMU.bupmem.fp = NULL;
-}
-
-
-
-void NDS_Reset( void)
-{
- BOOL oldexecute=execute;
- int i;
- u32 src;
- u32 dst;
- NDS_header * header = NDS_getROMHeader();
-
- if (!header) return ;
-
- execute = FALSE;
-
- MMU_clearMem();
-
- src = header->ARM9src;
- dst = header->ARM9cpy;
-
- for(i = 0; i < (header->ARM9binSize>>2); ++i)
- {
- MMU_write32(0, dst, T1ReadLong(MMU.CART_ROM, src));
- dst += 4;
- src += 4;
- }
-
- src = header->ARM7src;
- dst = header->ARM7cpy;
-
- for(i = 0; i < (header->ARM7binSize>>2); ++i)
- {
- MMU_write32(1, dst, T1ReadLong(MMU.CART_ROM, src));
- dst += 4;
- src += 4;
- }
-
- armcpu_init(&NDS_ARM7, header->ARM7exe);
- armcpu_init(&NDS_ARM9, header->ARM9exe);
-
- nds.ARM9Cycle = 0;
- nds.ARM7Cycle = 0;
- nds.cycles = 0;
- memset(nds.timerCycle, 0, sizeof(s32) * 2 * 4);
- memset(nds.timerOver, 0, sizeof(BOOL) * 2 * 4);
- nds.nextHBlank = 3168;
- nds.VCount = 0;
- nds.old = 0;
- nds.diff = 0;
- nds.lignerendu = FALSE;
- nds.touchX = nds.touchY = 0;
-
- MMU_write16(0, 0x04000130, 0x3FF);
- MMU_write16(1, 0x04000130, 0x3FF);
- MMU_write8(1, 0x04000136, 0x43);
-
- /*
- * Setup a copy of the firmware user settings in memory.
- * (this is what the DS firmware would do).
- */
- {
- u8 temp_buffer[NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT];
- int fw_index;
-
- if ( copy_firmware_user_data( temp_buffer, MMU.fw.data)) {
- for ( fw_index = 0; fw_index < NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT; fw_index++) {
- MMU_write8( 0, 0x027FFC80 + fw_index, temp_buffer[fw_index]);
- }
- }
- }
-
- // Copy the whole header to Main RAM 0x27FFE00 on startup.
- // Reference: http://nocash.emubase.de/gbatek.htm#dscartridgeheader
- for (i = 0; i < ((0x170+0x90)/4); i++)
- {
- MMU_write32 (0, 0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i]));
- }
-
- MainScreen.offset = 0;
- SubScreen.offset = 192;
-
- //MMU_write32(0, 0x02007FFC, 0xE92D4030);
-
- //ARM7 BIOS IRQ HANDLER
- MMU_write32(1, 0x00, 0xE25EF002);
- MMU_write32(1, 0x04, 0xEAFFFFFE);
- MMU_write32(1, 0x18, 0xEA000000);
- MMU_write32(1, 0x20, 0xE92D500F);
- MMU_write32(1, 0x24, 0xE3A00301);
- MMU_write32(1, 0x28, 0xE28FE000);
- MMU_write32(1, 0x2C, 0xE510F004);
- MMU_write32(1, 0x30, 0xE8BD500F);
- MMU_write32(1, 0x34, 0xE25EF004);
-
- //ARM9 BIOS IRQ HANDLER
- MMU_write32(0, 0xFFFF0018, 0xEA000000);
- MMU_write32(0, 0xFFFF0020, 0xE92D500F);
- MMU_write32(0, 0xFFFF0024, 0xEE190F11);
- MMU_write32(0, 0xFFFF0028, 0xE1A00620);
- MMU_write32(0, 0xFFFF002C, 0xE1A00600);
- MMU_write32(0, 0xFFFF0030, 0xE2800C40);
- MMU_write32(0, 0xFFFF0034, 0xE28FE000);
- MMU_write32(0, 0xFFFF0038, 0xE510F004);
- MMU_write32(0, 0xFFFF003C, 0xE8BD500F);
- MMU_write32(0, 0xFFFF0040, 0xE25EF004);
-
- MMU_write32(0, 0x0000004, 0xE3A0010E);
- MMU_write32(0, 0x0000008, 0xE3A01020);
-// MMU_write32(0, 0x000000C, 0xE1B02110);
- MMU_write32(0, 0x000000C, 0xE1B02040);
- MMU_write32(0, 0x0000010, 0xE3B02020);
-// MMU_write32(0, 0x0000010, 0xE2100202);
-
- free(header);
-
- GPU_Reset(MainScreen.gpu, 0);
- GPU_Reset(SubScreen.gpu, 1);
- SPU_Reset();
-
- execute = oldexecute;
-}
-
-static void dma_check(void)
-{
- if((MMU.DMAing[0][0])&&(MMU.DMACycle[0][0]<=nds.cycles))
- {
- T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*0), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*0)) & 0x7FFFFFFF);
- if((MMU.DMACrt[0][0])&(1<<30)) NDS_makeARM9Int(8);
- MMU.DMAing[0][0] = FALSE;
- }
-
- if((MMU.DMAing[0][1])&&(MMU.DMACycle[0][1]<=nds.cycles))
- {
- T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*1), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*1)) & 0x7FFFFFFF);
- if((MMU.DMACrt[0][1])&(1<<30)) NDS_makeARM9Int(9);
- MMU.DMAing[0][1] = FALSE;
- }
-
- if((MMU.DMAing[0][2])&&(MMU.DMACycle[0][2]<=nds.cycles))
- {
- T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*2), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*2)) & 0x7FFFFFFF);
- if((MMU.DMACrt[0][2])&(1<<30)) NDS_makeARM9Int(10);
- MMU.DMAing[0][2] = FALSE;
- }
-
- if((MMU.DMAing[0][3])&&(MMU.DMACycle[0][3]<=nds.cycles))
- {
- T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*3), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*3)) & 0x7FFFFFFF);
- if((MMU.DMACrt[0][3])&(1<<30)) NDS_makeARM9Int(11);
- MMU.DMAing[0][3] = FALSE;
- }
-
- if((MMU.DMAing[1][0])&&(MMU.DMACycle[1][0]<=nds.cycles))
- {
- T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*0), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*0)) & 0x7FFFFFFF);
- if((MMU.DMACrt[1][0])&(1<<30)) NDS_makeARM7Int(8);
- MMU.DMAing[1][0] = FALSE;
- }
-
- if((MMU.DMAing[1][1])&&(MMU.DMACycle[1][1]<=nds.cycles))
- {
- T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*1), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*1)) & 0x7FFFFFFF);
- if((MMU.DMACrt[1][1])&(1<<30)) NDS_makeARM7Int(9);
- MMU.DMAing[1][1] = FALSE;
- }
-
- if((MMU.DMAing[1][2])&&(MMU.DMACycle[1][2]<=nds.cycles))
- {
- T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*2), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*2)) & 0x7FFFFFFF);
- if((MMU.DMACrt[1][2])&(1<<30)) NDS_makeARM7Int(10);
- MMU.DMAing[1][2] = FALSE;
- }
-
- if((MMU.DMAing[1][3])&&(MMU.DMACycle[1][3]<=nds.cycles))
- {
- T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*3), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*3)) & 0x7FFFFFFF);
- if((MMU.DMACrt[1][3])&(1<<30)) NDS_makeARM7Int(11);
- MMU.DMAing[1][3] = FALSE;
- }
-
- if((MMU.reg_IF[0]&MMU.reg_IE[0]) && (MMU.reg_IME[0]))
- {
-#ifdef GDB_STUB
- if ( armcpu_flagIrq( &NDS_ARM9))
-#else
- if ( armcpu_irqExeption(&NDS_ARM9))
-#endif
- {
- nds.ARM9Cycle = nds.cycles;
- }
- }
-
- if((MMU.reg_IF[1]&MMU.reg_IE[1]) && (MMU.reg_IME[1]))
- {
-#ifdef GDB_STUB
- if ( armcpu_flagIrq( &NDS_ARM7))
-#else
- if ( armcpu_irqExeption(&NDS_ARM7))
-#endif
- {
- nds.ARM7Cycle = nds.cycles;
- }
- }
-
-}
-
-static void timer_check(void)
-{
- int p, t;
- for (p = 0; p < 2; p++)
- {
- for (t = 0; t < 4; t++)
- {
- nds.timerOver[p][t] = 0;
- if(MMU.timerON[p][t])
- {
- if(MMU.timerRUN[p][t])
- {
- switch(MMU.timerMODE[p][t])
- {
- case 0xFFFF :
- if(t > 0 && nds.timerOver[p][t - 1])
- {
- ++(MMU.timer[p][t]);
- nds.timerOver[p][t] = !MMU.timer[p][t];
- if (nds.timerOver[p][t])
- {
- if (p == 0)
- {
- if(T1ReadWord(ARM9Mem.ARM9_REG, 0x102 + (t << 2)) & 0x40)
- NDS_makeARM9Int(3 + t);
- }
- else
- {
- if(T1ReadWord(MMU.ARM7_REG, 0x102 + (t << 2)) & 0x40)
- NDS_makeARM7Int(3 + t);
- }
- MMU.timer[p][t] = MMU.timerReload[p][t];
- }
- }
- break;
- default :
- {
- nds.diff = (nds.cycles >> MMU.timerMODE[p][t]) - (nds.timerCycle[p][t] >> MMU.timerMODE[p][t]);
- nds.old = MMU.timer[p][t];
- MMU.timer[p][t] += nds.diff;
- nds.timerCycle[p][t] += nds.diff << MMU.timerMODE[p][t];
- nds.timerOver[p][t] = nds.old >= MMU.timer[p][t];
- if(nds.timerOver[p][t])
- {
- if (p == 0)
- {
- if(T1ReadWord(ARM9Mem.ARM9_REG, 0x102 + (t << 2)) & 0x40)
- NDS_makeARM9Int(3 + t);
- }
- else
- {
- if(T1ReadWord(MMU.ARM7_REG, 0x102 + (t << 2)) & 0x40)
- NDS_makeARM7Int(3 + t);
- }
- MMU.timer[p][t] = MMU.timerReload[p][t] + MMU.timer[p][t] - nds.old;
- }
- }
- break;
- }
- }
- else
- {
- MMU.timerRUN[p][t] = TRUE;
- nds.timerCycle[p][t] = nds.cycles;
- }
- }
- }
- }
-}
-
-void NDS_exec_hframe(int cpu_clockdown_level_arm9, int cpu_clockdown_level_arm7)
-{
- int h;
- for (h = 0; h < 2; h++)
- {
- s32 nb = nds.cycles + (h ? (99 * 12) : (256 * 12));
-
- while (nb > nds.ARM9Cycle && !NDS_ARM9.waitIRQ)
- nds.ARM9Cycle += armcpu_exec(&NDS_ARM9) << (cpu_clockdown_level_arm9);
- if (NDS_ARM9.waitIRQ) nds.ARM9Cycle = nb;
- while (nb > nds.ARM7Cycle && !NDS_ARM7.waitIRQ)
- nds.ARM7Cycle += armcpu_exec(&NDS_ARM7) << (1 + (cpu_clockdown_level_arm7));
- if (NDS_ARM7.waitIRQ) nds.ARM7Cycle = nb;
- nds.cycles = (nds.ARM9Cycle<nds.ARM7Cycle)?nds.ARM9Cycle : nds.ARM7Cycle;
-
- /* HBLANK */
- if (h)
- {
- T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 2);
- T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 2);
- NDS_ARM9HBlankInt();
- NDS_ARM7HBlankInt();
-
- if(nds.VCount<192)
- {
- if(MMU.DMAStartTime[0][0] == 2)
- MMU_doDMA(0, 0);
- if(MMU.DMAStartTime[0][1] == 2)
- MMU_doDMA(0, 1);
- if(MMU.DMAStartTime[0][2] == 2)
- MMU_doDMA(0, 2);
- if(MMU.DMAStartTime[0][3] == 2)
- MMU_doDMA(0, 3);
- }
- }
- else
- {
- /* HDISP */
- u32 vmatch;
-
- nds.nextHBlank += 4260;
- ++nds.VCount;
- T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFD);
- T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFD);
-
- if(MMU.DMAStartTime[0][0] == 3)
- MMU_doDMA(0, 0);
- if(MMU.DMAStartTime[0][1] == 3)
- MMU_doDMA(0, 1);
- if(MMU.DMAStartTime[0][2] == 3)
- MMU_doDMA(0, 2);
- if(MMU.DMAStartTime[0][3] == 3)
- MMU_doDMA(0, 3);
-
- // Main memory display
- if(MMU.DMAStartTime[0][0] == 4)
- {
- MMU_doDMA(0, 0);
- MMU.DMAStartTime[0][0] = 0;
- }
- if(MMU.DMAStartTime[0][1] == 4)
- {
- MMU_doDMA(0, 1);
- MMU.DMAStartTime[0][1] = 0;
- }
- if(MMU.DMAStartTime[0][2] == 4)
- {
- MMU_doDMA(0, 2);
- MMU.DMAStartTime[0][2] = 0;
- }
- if(MMU.DMAStartTime[0][3] == 4)
- {
- MMU_doDMA(0, 3);
- MMU.DMAStartTime[0][3] = 0;
- }
-
- if(MMU.DMAStartTime[1][0] == 4)
- {
- MMU_doDMA(1, 0);
- MMU.DMAStartTime[1][0] = 0;
- }
- if(MMU.DMAStartTime[1][1] == 4)
- {
- MMU_doDMA(1, 1);
- MMU.DMAStartTime[0][1] = 0;
- }
- if(MMU.DMAStartTime[1][2] == 4)
- {
- MMU_doDMA(1, 2);
- MMU.DMAStartTime[1][2] = 0;
- }
- if(MMU.DMAStartTime[1][3] == 4)
- {
- MMU_doDMA(1, 3);
- MMU.DMAStartTime[1][3] = 0;
- }
-
- if(nds.VCount == 192)
- {
- /* VBLANK */
- T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 1);
- T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 1);
- NDS_ARM9VBlankInt();
- NDS_ARM7VBlankInt();
-
- if(MMU.DMAStartTime[0][0] == 1)
- MMU_doDMA(0, 0);
- if(MMU.DMAStartTime[0][1] == 1)
- MMU_doDMA(0, 1);
- if(MMU.DMAStartTime[0][2] == 1)
- MMU_doDMA(0, 2);
- if(MMU.DMAStartTime[0][3] == 1)
- MMU_doDMA(0, 3);
-
- if(MMU.DMAStartTime[1][0] == 1)
- MMU_doDMA(1, 0);
- if(MMU.DMAStartTime[1][1] == 1)
- MMU_doDMA(1, 1);
- if(MMU.DMAStartTime[1][2] == 1)
- MMU_doDMA(1, 2);
- if(MMU.DMAStartTime[1][3] == 1)
- MMU_doDMA(1, 3);
- }
- else if(nds.VCount == 263)
- {
- const int cycles_per_frame = (263 * (99 * 12 + 256 * 12));
- /* VDISP */
- nds.nextHBlank = 3168;
- nds.VCount = 0;
- T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFE);
- T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFE);
-
- nds.cycles -= cycles_per_frame;
- nds.ARM9Cycle -= cycles_per_frame;
- nds.ARM7Cycle -= cycles_per_frame;
- nb -= cycles_per_frame;
- if(MMU.timerON[0][0])
- nds.timerCycle[0][0] -= cycles_per_frame;
- if(MMU.timerON[0][1])
- nds.timerCycle[0][1] -= cycles_per_frame;
- if(MMU.timerON[0][2])
- nds.timerCycle[0][2] -= cycles_per_frame;
- if(MMU.timerON[0][3])
- nds.timerCycle[0][3] -= cycles_per_frame;
-
- if(MMU.timerON[1][0])
- nds.timerCycle[1][0] -= cycles_per_frame;
- if(MMU.timerON[1][1])
- nds.timerCycle[1][1] -= cycles_per_frame;
- if(MMU.timerON[1][2])
- nds.timerCycle[1][2] -= cycles_per_frame;
- if(MMU.timerON[1][3])
- nds.timerCycle[1][3] -= cycles_per_frame;
- if(MMU.DMAing[0][0])
- MMU.DMACycle[0][0] -= cycles_per_frame;
- if(MMU.DMAing[0][1])
- MMU.DMACycle[0][1] -= cycles_per_frame;
- if(MMU.DMAing[0][2])
- MMU.DMACycle[0][2] -= cycles_per_frame;
- if(MMU.DMAing[0][3])
- MMU.DMACycle[0][3] -= cycles_per_frame;
- if(MMU.DMAing[1][0])
- MMU.DMACycle[1][0] -= cycles_per_frame;
- if(MMU.DMAing[1][1])
- MMU.DMACycle[1][1] -= cycles_per_frame;
- if(MMU.DMAing[1][2])
- MMU.DMACycle[1][2] -= cycles_per_frame;
- if(MMU.DMAing[1][3])
- MMU.DMACycle[1][3] -= cycles_per_frame;
-
- }
-
- T1WriteWord(ARM9Mem.ARM9_REG, 6, nds.VCount);
- T1WriteWord(MMU.ARM7_REG, 6, nds.VCount);
-
- vmatch = T1ReadWord(ARM9Mem.ARM9_REG, 4);
- if(nds.VCount== ((vmatch >> 8) | ((vmatch << 1) & 256)))
- {
- T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 4);
- if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 32)
- NDS_makeARM9Int(2);
- }
- else
- T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFB);
-
- vmatch = T1ReadWord(MMU.ARM7_REG, 4);
- if(nds.VCount== ((vmatch >> 8) | ((vmatch <<1 ) & 256)))
- {
- T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 4);
- if(T1ReadWord(MMU.ARM7_REG, 4) & 32)
- NDS_makeARM7Int(2);
- }
- else
- T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFB);
-
- timer_check();
- dma_check();
- }
- }
-}
-
-void NDS_exec_frame(int cpu_clockdown_level_arm9, int cpu_clockdown_level_arm7)
-{
- int v;
- for (v = 0; v < 263; v++)
- {
- NDS_exec_hframe(cpu_clockdown_level_arm9, cpu_clockdown_level_arm7);
- }
-}
-
diff --git a/src/xsf/desmume/NDSSystem.cc b/src/xsf/desmume/NDSSystem.cc
new file mode 100644
index 000000000000..ee02bc938d5e
--- /dev/null
+++ b/src/xsf/desmume/NDSSystem.cc
@@ -0,0 +1,748 @@
+/* Copyright (C) 2006 yopyop
+ yopyop156 at ifrance.com
+ yopyop156.ifrance.com
+
+ This file is part of DeSmuME
+
+ DeSmuME 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.
+
+ DeSmuME 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 DeSmuME; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "NDSSystem.h"
+#include "MMU.h"
+//#include "cflash.h"
+
+//#include "ROMReader.h"
+
+/* the count of bytes copied from the firmware into memory */
+#define NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT 0x70
+
+NDSSystem nds;
+
+static u32
+calc_CRC16( u32 start, const u8 *data, int count) {
+ int i,j;
+ u32 crc = start & 0xffff;
+ static u16 val[] = { 0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001 };
+ for(i = 0; i < count; i++)
+ {
+ crc = crc ^ data[i];
+
+ for(j = 0; j < 8; j++) {
+ int do_bit = 0;
+
+ if ( crc & 0x1)
+ do_bit = 1;
+
+ crc = crc >> 1;
+
+ if ( do_bit) {
+ crc = crc ^ (val[j] << (7-j));
+ }
+ }
+ }
+ return crc;
+}
+
+static int
+copy_firmware_user_data( u8 *dest_buffer, const u8 *fw_data) {
+ /*
+ * Determine which of the two user settings in the firmware is the current
+ * and valid one and then copy this into the destination buffer.
+ *
+ * The current setting will have a greater count.
+ * Settings are only valid if its CRC16 is correct.
+ */
+ int user1_valid = 0;
+ int user2_valid = 0;
+ u32 user_settings_offset;
+ u32 fw_crc;
+ u32 crc;
+ int copy_good = 0;
+
+ user_settings_offset = fw_data[0x20];
+ user_settings_offset |= fw_data[0x21] << 8;
+ user_settings_offset <<= 3;
+
+ if ( user_settings_offset <= 0x3FE00) {
+ s32 copy_settings_offset = -1;
+
+ crc = calc_CRC16( 0xffff, &fw_data[user_settings_offset],
+ NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT);
+ fw_crc = fw_data[user_settings_offset + 0x72];
+ fw_crc |= fw_data[user_settings_offset + 0x73] << 8;
+ if ( crc == fw_crc) {
+ user1_valid = 1;
+ }
+
+ crc = calc_CRC16( 0xffff, &fw_data[user_settings_offset + 0x100],
+ NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT);
+ fw_crc = fw_data[user_settings_offset + 0x100 + 0x72];
+ fw_crc |= fw_data[user_settings_offset + 0x100 + 0x73] << 8;
+ if ( crc == fw_crc) {
+ user2_valid = 1;
+ }
+
+ if ( user1_valid) {
+ if ( user2_valid) {
+ u16 count1, count2;
+
+ count1 = fw_data[user_settings_offset + 0x70];
+ count1 |= fw_data[user_settings_offset + 0x71] << 8;
+
+ count2 = fw_data[user_settings_offset + 0x100 + 0x70];
+ count2 |= fw_data[user_settings_offset + 0x100 + 0x71] << 8;
+
+ if ( count2 > count1) {
+ copy_settings_offset = user_settings_offset + 0x100;
+ }
+ else {
+ copy_settings_offset = user_settings_offset;
+ }
+ }
+ else {
+ copy_settings_offset = user_settings_offset;
+ }
+ }
+ else if ( user2_valid) {
+ /* copy the second user settings */
+ copy_settings_offset = user_settings_offset + 0x100;
+ }
+
+ if ( copy_settings_offset > 0) {
+ memcpy( dest_buffer, &fw_data[copy_settings_offset],
+ NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT);
+ copy_good = 1;
+ }
+ }
+
+ return copy_good;
+}
+
+
+#ifdef GDB_STUB
+int NDS_Init( struct armcpu_memory_iface *arm9_mem_if,
+ struct armcpu_ctrl_iface **arm9_ctrl_iface,
+ struct armcpu_memory_iface *arm7_mem_if,
+ struct armcpu_ctrl_iface **arm7_ctrl_iface) {
+#else
+int NDS_Init( void) {
+#endif
+ nds.ARM9Cycle = 0;
+ nds.ARM7Cycle = 0;
+ nds.cycles = 0;
+ MMU_Init();
+ nds.nextHBlank = 3168;
+ nds.VCount = 0;
+ nds.lignerendu = false;
+
+ if (Screen_Init(GFXCORE_DUMMY) != 0)
+ return -1;
+
+ #ifdef GDB_STUB
+ armcpu_new(&NDS_ARM7,1, arm7_mem_if, arm7_ctrl_iface);
+ armcpu_new(&NDS_ARM9,0, arm9_mem_if, arm9_ctrl_iface);
+#else
+ armcpu_new(&NDS_ARM7,1);
+ armcpu_new(&NDS_ARM9,0);
+#endif
+
+ if (SPU_Init(SNDCORE_DUMMY, 735) != 0)
+ return -1;
+
+#ifdef EXPERIMENTAL_WIFI
+ WIFI_Init(&wifiMac) ;
+#endif
+
+ return 0;
+}
+
+static void armcpu_deinit(armcpu_t *armcpu)
+{
+ if(armcpu->coproc[15])
+ {
+ free(armcpu->coproc[15]);
+ armcpu->coproc[15] = 0;
+ }
+}
+
+void NDS_DeInit(void) {
+ if(MMU.CART_ROM != MMU.UNUSED_RAM)
+ NDS_FreeROM();
+
+ armcpu_deinit(&NDS_ARM7);
+ armcpu_deinit(&NDS_ARM9);
+
+ nds.nextHBlank = 3168;
+ SPU_DeInit();
+ Screen_DeInit();
+ MMU_DeInit();
+}
+
+BOOL NDS_SetROM(u8 * rom, u32 mask)
+{
+ MMU_setRom(rom, mask);
+
+ return true;
+}
+
+NDS_header * NDS_getROMHeader(void)
+{
+ NDS_header * header = (NDS_header *) malloc(sizeof(NDS_header));
+
+ memcpy(header->gameTile, MMU.CART_ROM, 12);
+ memcpy(header->gameCode, MMU.CART_ROM + 12, 4);
+ header->makerCode = T1ReadWord(MMU.CART_ROM, 16);
+ header->unitCode = MMU.CART_ROM[18];
+ header->deviceCode = MMU.CART_ROM[19];
+ header->cardSize = MMU.CART_ROM[20];
+ memcpy(header->cardInfo, MMU.CART_ROM + 21, 8);
+ header->flags = MMU.CART_ROM[29];
+ header->ARM9src = T1ReadLong(MMU.CART_ROM, 32);
+ header->ARM9exe = T1ReadLong(MMU.CART_ROM, 36);
+ header->ARM9cpy = T1ReadLong(MMU.CART_ROM, 40);
+ header->ARM9binSize = T1ReadLong(MMU.CART_ROM, 44);
+ header->ARM7src = T1ReadLong(MMU.CART_ROM, 48);
+ header->ARM7exe = T1ReadLong(MMU.CART_ROM, 52);
+ header->ARM7cpy = T1ReadLong(MMU.CART_ROM, 56);
+ header->ARM7binSize = T1ReadLong(MMU.CART_ROM, 60);
+ header->FNameTblOff = T1ReadLong(MMU.CART_ROM, 64);
+ header->FNameTblSize = T1ReadLong(MMU.CART_ROM, 68);
+ header->FATOff = T1ReadLong(MMU.CART_ROM, 72);
+ header->FATSize = T1ReadLong(MMU.CART_ROM, 76);
+ header->ARM9OverlayOff = T1ReadLong(MMU.CART_ROM, 80);
+ header->ARM9OverlaySize = T1ReadLong(MMU.CART_ROM, 84);
+ header->ARM7OverlayOff = T1ReadLong(MMU.CART_ROM, 88);
+ header->ARM7OverlaySize = T1ReadLong(MMU.CART_ROM, 92);
+ header->unknown2a = T1ReadLong(MMU.CART_ROM, 96);
+ header->unknown2b = T1ReadLong(MMU.CART_ROM, 100);
+ header->IconOff = T1ReadLong(MMU.CART_ROM, 104);
+ header->CRC16 = T1ReadWord(MMU.CART_ROM, 108);
+ header->ROMtimeout = T1ReadWord(MMU.CART_ROM, 110);
+ header->ARM9unk = T1ReadLong(MMU.CART_ROM, 112);
+ header->ARM7unk = T1ReadLong(MMU.CART_ROM, 116);
+ memcpy(header->unknown3c, MMU.CART_ROM + 120, 8);
+ header->ROMSize = T1ReadLong(MMU.CART_ROM, 128);
+ header->HeaderSize = T1ReadLong(MMU.CART_ROM, 132);
+ memcpy(header->unknown5, MMU.CART_ROM + 136, 56);
+ memcpy(header->logo, MMU.CART_ROM + 192, 156);
+ header->logoCRC16 = T1ReadWord(MMU.CART_ROM, 348);
+ header->headerCRC16 = T1ReadWord(MMU.CART_ROM, 350);
+ memcpy(header->reserved, MMU.CART_ROM + 352, 160);
+
+ return header;
+
+ //return (NDS_header *)MMU.CART_ROM;
+}
+
+
+
+void NDS_FreeROM(void)
+{
+ if (MMU.CART_ROM != MMU.UNUSED_RAM)
+ free(MMU.CART_ROM);
+ MMU_unsetRom();
+// if (MMU.bupmem.fp)
+// fclose(MMU.bupmem.fp);
+// MMU.bupmem.fp = nullptr;
+}
+
+
+
+void NDS_Reset( void)
+{
+ BOOL oldexecute=execute;
+ int i;
+ u32 src;
+ u32 dst;
+ NDS_header * header = NDS_getROMHeader();
+
+ if (!header) return ;
+
+ execute = false;
+
+ MMU_clearMem();
+
+ src = header->ARM9src;
+ dst = header->ARM9cpy;
+
+ for(i = 0; i < (header->ARM9binSize>>2); ++i)
+ {
+ MMU_write32(0, dst, T1ReadLong(MMU.CART_ROM, src));
+ dst += 4;
+ src += 4;
+ }
+
+ src = header->ARM7src;
+ dst = header->ARM7cpy;
+
+ for(i = 0; i < (header->ARM7binSize>>2); ++i)
+ {
+ MMU_write32(1, dst, T1ReadLong(MMU.CART_ROM, src));
+ dst += 4;
+ src += 4;
+ }
+
+ armcpu_init(&NDS_ARM7, header->ARM7exe);
+ armcpu_init(&NDS_ARM9, header->ARM9exe);
+
+ nds.ARM9Cycle = 0;
+ nds.ARM7Cycle = 0;
+ nds.cycles = 0;
+ memset(nds.timerCycle, 0, sizeof(s32) * 2 * 4);
+ memset(nds.timerOver, 0, sizeof(BOOL) * 2 * 4);
+ nds.nextHBlank = 3168;
+ nds.VCount = 0;
+ nds.old = 0;
+ nds.diff = 0;
+ nds.lignerendu = false;
+ nds.touchX = nds.touchY = 0;
+
+ MMU_write16(0, 0x04000130, 0x3FF);
+ MMU_write16(1, 0x04000130, 0x3FF);
+ MMU_write8(1, 0x04000136, 0x43);
+
+ /*
+ * Setup a copy of the firmware user settings in memory.
+ * (this is what the DS firmware would do).
+ */
+ {
+ u8 temp_buffer[NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT];
+ int fw_index;
+
+ if ( copy_firmware_user_data( temp_buffer, MMU.fw.data)) {
+ for ( fw_index = 0; fw_index < NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT; fw_index++) {
+ MMU_write8( 0, 0x027FFC80 + fw_index, temp_buffer[fw_index]);
+ }
+ }
+ }
+
+ // Copy the whole header to Main RAM 0x27FFE00 on startup.
+ // Reference: http://nocash.emubase.de/gbatek.htm#dscartridgeheader
+ for (i = 0; i < ((0x170+0x90)/4); i++)
+ {
+ MMU_write32 (0, 0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i]));
+ }
+
+ MainScreen.offset = 0;
+ SubScreen.offset = 192;
+
+ //MMU_write32(0, 0x02007FFC, 0xE92D4030);
+
+ //ARM7 BIOS IRQ HANDLER
+ MMU_write32(1, 0x00, 0xE25EF002);
+ MMU_write32(1, 0x04, 0xEAFFFFFE);
+ MMU_write32(1, 0x18, 0xEA000000);
+ MMU_write32(1, 0x20, 0xE92D500F);
+ MMU_write32(1, 0x24, 0xE3A00301);
+ MMU_write32(1, 0x28, 0xE28FE000);
+ MMU_write32(1, 0x2C, 0xE510F004);
+ MMU_write32(1, 0x30, 0xE8BD500F);
+ MMU_write32(1, 0x34, 0xE25EF004);
+
+ //ARM9 BIOS IRQ HANDLER
+ MMU_write32(0, 0xFFFF0018, 0xEA000000);
+ MMU_write32(0, 0xFFFF0020, 0xE92D500F);
+ MMU_write32(0, 0xFFFF0024, 0xEE190F11);
+ MMU_write32(0, 0xFFFF0028, 0xE1A00620);
+ MMU_write32(0, 0xFFFF002C, 0xE1A00600);
+ MMU_write32(0, 0xFFFF0030, 0xE2800C40);
+ MMU_write32(0, 0xFFFF0034, 0xE28FE000);
+ MMU_write32(0, 0xFFFF0038, 0xE510F004);
+ MMU_write32(0, 0xFFFF003C, 0xE8BD500F);
+ MMU_write32(0, 0xFFFF0040, 0xE25EF004);
+
+ MMU_write32(0, 0x0000004, 0xE3A0010E);
+ MMU_write32(0, 0x0000008, 0xE3A01020);
+// MMU_write32(0, 0x000000C, 0xE1B02110);
+ MMU_write32(0, 0x000000C, 0xE1B02040);
+ MMU_write32(0, 0x0000010, 0xE3B02020);
+// MMU_write32(0, 0x0000010, 0xE2100202);
+
+ free(header);
+
+ GPU_Reset(MainScreen.gpu, 0);
+ GPU_Reset(SubScreen.gpu, 1);
+ SPU_Reset();
+
+ execute = oldexecute;
+}
+
+static void dma_check(void)
+{
+ if((MMU.DMAing[0][0])&&(MMU.DMACycle[0][0]<=nds.cycles))
+ {
+ T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*0), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*0)) & 0x7FFFFFFF);
+ if((MMU.DMACrt[0][0])&(1<<30)) NDS_makeARM9Int(8);
+ MMU.DMAing[0][0] = false;
+ }
+
+ if((MMU.DMAing[0][1])&&(MMU.DMACycle[0][1]<=nds.cycles))
+ {
+ T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*1), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*1)) & 0x7FFFFFFF);
+ if((MMU.DMACrt[0][1])&(1<<30)) NDS_makeARM9Int(9);
+ MMU.DMAing[0][1] = false;
+ }
+
+ if((MMU.DMAing[0][2])&&(MMU.DMACycle[0][2]<=nds.cycles))
+ {
+ T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*2), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*2)) & 0x7FFFFFFF);
+ if((MMU.DMACrt[0][2])&(1<<30)) NDS_makeARM9Int(10);
+ MMU.DMAing[0][2] = false;
+ }
+
+ if((MMU.DMAing[0][3])&&(MMU.DMACycle[0][3]<=nds.cycles))
+ {
+ T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*3), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*3)) & 0x7FFFFFFF);
+ if((MMU.DMACrt[0][3])&(1<<30)) NDS_makeARM9Int(11);
+ MMU.DMAing[0][3] = false;
+ }
+
+ if((MMU.DMAing[1][0])&&(MMU.DMACycle[1][0]<=nds.cycles))
+ {
+ T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*0), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*0)) & 0x7FFFFFFF);
+ if((MMU.DMACrt[1][0])&(1<<30)) NDS_makeARM7Int(8);
+ MMU.DMAing[1][0] = false;
+ }
+
+ if((MMU.DMAing[1][1])&&(MMU.DMACycle[1][1]<=nds.cycles))
+ {
+ T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*1), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*1)) & 0x7FFFFFFF);
+ if((MMU.DMACrt[1][1])&(1<<30)) NDS_makeARM7Int(9);
+ MMU.DMAing[1][1] = false;
+ }
+
+ if((MMU.DMAing[1][2])&&(MMU.DMACycle[1][2]<=nds.cycles))
+ {
+ T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*2), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*2)) & 0x7FFFFFFF);
+ if((MMU.DMACrt[1][2])&(1<<30)) NDS_makeARM7Int(10);
+ MMU.DMAing[1][2] = false;
+ }
+
+ if((MMU.DMAing[1][3])&&(MMU.DMACycle[1][3]<=nds.cycles))
+ {
+ T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*3), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*3)) & 0x7FFFFFFF);
+ if((MMU.DMACrt[1][3])&(1<<30)) NDS_makeARM7Int(11);
+ MMU.DMAing[1][3] = false;
+ }
+
+ if((MMU.reg_IF[0]&MMU.reg_IE[0]) && (MMU.reg_IME[0]))
+ {
+#ifdef GDB_STUB
+ if ( armcpu_flagIrq( &NDS_ARM9))
+#else
+ if ( armcpu_irqExeption(&NDS_ARM9))
+#endif
+ {
+ nds.ARM9Cycle = nds.cycles;
+ }
+ }
+
+ if((MMU.reg_IF[1]&MMU.reg_IE[1]) && (MMU.reg_IME[1]))
+ {
+#ifdef GDB_STUB
+ if ( armcpu_flagIrq( &NDS_ARM7))
+#else
+ if ( armcpu_irqExeption(&NDS_ARM7))
+#endif
+ {
+ nds.ARM7Cycle = nds.cycles;
+ }
+ }
+
+}
+
+static void timer_check(void)
+{
+ int p, t;
+ for (p = 0; p < 2; p++)
+ {
+ for (t = 0; t < 4; t++)
+ {
+ nds.timerOver[p][t] = 0;
+ if(MMU.timerON[p][t])
+ {
+ if(MMU.timerRUN[p][t])
+ {
+ switch(MMU.timerMODE[p][t])
+ {
+ case 0xFFFF :
+ if(t > 0 && nds.timerOver[p][t - 1])
+ {
+ ++(MMU.timer[p][t]);
+ nds.timerOver[p][t] = !MMU.timer[p][t];
+ if (nds.timerOver[p][t])
+ {
+ if (p == 0)
+ {
+ if(T1ReadWord(ARM9Mem.ARM9_REG, 0x102 + (t << 2)) & 0x40)
+ NDS_makeARM9Int(3 + t);
+ }
+ else
+ {
+ if(T1ReadWord(MMU.ARM7_REG, 0x102 + (t << 2)) & 0x40)
+ NDS_makeARM7Int(3 + t);
+ }
+ MMU.timer[p][t] = MMU.timerReload[p][t];
+ }
+ }
+ break;
+ default :
+ {
+ nds.diff = (nds.cycles >> MMU.timerMODE[p][t]) - (nds.timerCycle[p][t] >> MMU.timerMODE[p][t]);
+ nds.old = MMU.timer[p][t];
+ MMU.timer[p][t] += nds.diff;
+ nds.timerCycle[p][t] += nds.diff << MMU.timerMODE[p][t];
+ nds.timerOver[p][t] = nds.old >= MMU.timer[p][t];
+ if(nds.timerOver[p][t])
+ {
+ if (p == 0)
+ {
+ if(T1ReadWord(ARM9Mem.ARM9_REG, 0x102 + (t << 2)) & 0x40)
+ NDS_makeARM9Int(3 + t);
+ }
+ else
+ {
+ if(T1ReadWord(MMU.ARM7_REG, 0x102 + (t << 2)) & 0x40)
+ NDS_makeARM7Int(3 + t);
+ }
+ MMU.timer[p][t] = MMU.timerReload[p][t] + MMU.timer[p][t] - nds.old;
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ MMU.timerRUN[p][t] = true;
+ nds.timerCycle[p][t] = nds.cycles;
+ }
+ }
+ }
+ }
+}
+
+void NDS_exec_hframe(int cpu_clockdown_level_arm9, int cpu_clockdown_level_arm7)
+{
+ int h;
+ for (h = 0; h < 2; h++)
+ {
+ s32 nb = nds.cycles + (h ? (99 * 12) : (256 * 12));
+
+ while (nb > nds.ARM9Cycle && !NDS_ARM9.waitIRQ)
+ nds.ARM9Cycle += armcpu_exec(&NDS_ARM9) << (cpu_clockdown_level_arm9);
+ if (NDS_ARM9.waitIRQ) nds.ARM9Cycle = nb;
+ while (nb > nds.ARM7Cycle && !NDS_ARM7.waitIRQ)
+ nds.ARM7Cycle += armcpu_exec(&NDS_ARM7) << (1 + (cpu_clockdown_level_arm7));
+ if (NDS_ARM7.waitIRQ) nds.ARM7Cycle = nb;
+ nds.cycles = (nds.ARM9Cycle<nds.ARM7Cycle)?nds.ARM9Cycle : nds.ARM7Cycle;
+
+ /* HBLANK */
+ if (h)
+ {
+ T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 2);
+ T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 2);
+ NDS_ARM9HBlankInt();
+ NDS_ARM7HBlankInt();
+
+ if(nds.VCount<192)
+ {
+ if(MMU.DMAStartTime[0][0] == 2)
+ MMU_doDMA(0, 0);
+ if(MMU.DMAStartTime[0][1] == 2)
+ MMU_doDMA(0, 1);
+ if(MMU.DMAStartTime[0][2] == 2)
+ MMU_doDMA(0, 2);
+ if(MMU.DMAStartTime[0][3] == 2)
+ MMU_doDMA(0, 3);
+ }
+ }
+ else
+ {
+ /* HDISP */
+ u32 vmatch;
+
+ nds.nextHBlank += 4260;
+ ++nds.VCount;
+ T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFD);
+ T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFD);
+
+ if(MMU.DMAStartTime[0][0] == 3)
+ MMU_doDMA(0, 0);
+ if(MMU.DMAStartTime[0][1] == 3)
+ MMU_doDMA(0, 1);
+ if(MMU.DMAStartTime[0][2] == 3)
+ MMU_doDMA(0, 2);
+ if(MMU.DMAStartTime[0][3] == 3)
+ MMU_doDMA(0, 3);
+
+ // Main memory display
+ if(MMU.DMAStartTime[0][0] == 4)
+ {
+ MMU_doDMA(0, 0);
+ MMU.DMAStartTime[0][0] = 0;
+ }
+ if(MMU.DMAStartTime[0][1] == 4)
+ {
+ MMU_doDMA(0, 1);
+ MMU.DMAStartTime[0][1] = 0;
+ }
+ if(MMU.DMAStartTime[0][2] == 4)
+ {
+ MMU_doDMA(0, 2);
+ MMU.DMAStartTime[0][2] = 0;
+ }
+ if(MMU.DMAStartTime[0][3] == 4)
+ {
+ MMU_doDMA(0, 3);
+ MMU.DMAStartTime[0][3] = 0;
+ }
+
+ if(MMU.DMAStartTime[1][0] == 4)
+ {
+ MMU_doDMA(1, 0);
+ MMU.DMAStartTime[1][0] = 0;
+ }
+ if(MMU.DMAStartTime[1][1] == 4)
+ {
+ MMU_doDMA(1, 1);
+ MMU.DMAStartTime[0][1] = 0;
+ }
+ if(MMU.DMAStartTime[1][2] == 4)
+ {
+ MMU_doDMA(1, 2);
+ MMU.DMAStartTime[1][2] = 0;
+ }
+ if(MMU.DMAStartTime[1][3] == 4)
+ {
+ MMU_doDMA(1, 3);
+ MMU.DMAStartTime[1][3] = 0;
+ }
+
+ if(nds.VCount == 192)
+ {
+ /* VBLANK */
+ T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 1);
+ T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 1);
+ NDS_ARM9VBlankInt();
+ NDS_ARM7VBlankInt();
+
+ if(MMU.DMAStartTime[0][0] == 1)
+ MMU_doDMA(0, 0);
+ if(MMU.DMAStartTime[0][1] == 1)
+ MMU_doDMA(0, 1);
+ if(MMU.DMAStartTime[0][2] == 1)
+ MMU_doDMA(0, 2);
+ if(MMU.DMAStartTime[0][3] == 1)
+ MMU_doDMA(0, 3);
+
+ if(MMU.DMAStartTime[1][0] == 1)
+ MMU_doDMA(1, 0);
+ if(MMU.DMAStartTime[1][1] == 1)
+ MMU_doDMA(1, 1);
+ if(MMU.DMAStartTime[1][2] == 1)
+ MMU_doDMA(1, 2);
+ if(MMU.DMAStartTime[1][3] == 1)
+ MMU_doDMA(1, 3);
+ }
+ else if(nds.VCount == 263)
+ {
+ const int cycles_per_frame = (263 * (99 * 12 + 256 * 12));
+ /* VDISP */
+ nds.nextHBlank = 3168;
+ nds.VCount = 0;
+ T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFE);
+ T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFE);
+
+ nds.cycles -= cycles_per_frame;
+ nds.ARM9Cycle -= cycles_per_frame;
+ nds.ARM7Cycle -= cycles_per_frame;
+ nb -= cycles_per_frame;
+ if(MMU.timerON[0][0])
+ nds.timerCycle[0][0] -= cycles_per_frame;
+ if(MMU.timerON[0][1])
+ nds.timerCycle[0][1] -= cycles_per_frame;
+ if(MMU.timerON[0][2])
+ nds.timerCycle[0][2] -= cycles_per_frame;
+ if(MMU.timerON[0][3])
+ nds.timerCycle[0][3] -= cycles_per_frame;
+
+ if(MMU.timerON[1][0])
+ nds.timerCycle[1][0] -= cycles_per_frame;
+ if(MMU.timerON[1][1])
+ nds.timerCycle[1][1] -= cycles_per_frame;
+ if(MMU.timerON[1][2])
+ nds.timerCycle[1][2] -= cycles_per_frame;
+ if(MMU.timerON[1][3])
+ nds.timerCycle[1][3] -= cycles_per_frame;
+ if(MMU.DMAing[0][0])
+ MMU.DMACycle[0][0] -= cycles_per_frame;
+ if(MMU.DMAing[0][1])
+ MMU.DMACycle[0][1] -= cycles_per_frame;
+ if(MMU.DMAing[0][2])
+ MMU.DMACycle[0][2] -= cycles_per_frame;
+ if(MMU.DMAing[0][3])
+ MMU.DMACycle[0][3] -= cycles_per_frame;
+ if(MMU.DMAing[1][0])
+ MMU.DMACycle[1][0] -= cycles_per_frame;
+ if(MMU.DMAing[1][1])
+ MMU.DMACycle[1][1] -= cycles_per_frame;
+ if(MMU.DMAing[1][2])
+ MMU.DMACycle[1][2] -= cycles_per_frame;
+ if(MMU.DMAing[1][3])
+ MMU.DMACycle[1][3] -= cycles_per_frame;
+
+ }
+
+ T1WriteWord(ARM9Mem.ARM9_REG, 6, nds.VCount);
+ T1WriteWord(MMU.ARM7_REG, 6, nds.VCount);
+
+ vmatch = T1ReadWord(ARM9Mem.ARM9_REG, 4);
+ if(nds.VCount== ((vmatch >> 8) | ((vmatch << 1) & 256)))
+ {
+ T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 4);
+ if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 32)
+ NDS_makeARM9Int(2);
+ }
+ else
+ T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFB);
+
+ vmatch = T1ReadWord(MMU.ARM7_REG, 4);
+ if(nds.VCount== ((vmatch >> 8) | ((vmatch <<1 ) & 256)))
+ {
+ T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 4);
+ if(T1ReadWord(MMU.ARM7_REG, 4) & 32)
+ NDS_makeARM7Int(2);
+ }
+ else
+ T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFB);
+
+ timer_check();
+ dma_check();
+ }
+ }
+}
+
+void NDS_exec_frame(int cpu_clockdown_level_arm9, int cpu_clockdown_level_arm7)
+{
+ int v;
+ for (v = 0; v < 263; v++)
+ {
+ NDS_exec_hframe(cpu_clockdown_level_arm9, cpu_clockdown_level_arm7);
+ }
+}
+
diff --git a/src/xsf/desmume/NDSSystem.h b/src/xsf/desmume/NDSSystem.h
index f55e12ee8606..2417f6135db4 100644
--- a/src/xsf/desmume/NDSSystem.h
+++ b/src/xsf/desmume/NDSSystem.h
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef NDSSYSTEM_H
@@ -31,11 +31,6 @@
#include "mem.h"
//#include "wifi.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
extern volatile BOOL execute;
extern BOOL click;
@@ -65,37 +60,37 @@ typedef struct
u8 cardSize;
u8 cardInfo[8];
u8 flags;
-
+
u32 ARM9src;
u32 ARM9exe;
u32 ARM9cpy;
u32 ARM9binSize;
-
+
u32 ARM7src;
u32 ARM7exe;
u32 ARM7cpy;
u32 ARM7binSize;
-
+
u32 FNameTblOff;
u32 FNameTblSize;
-
+
u32 FATOff;
u32 FATSize;
-
+
u32 ARM9OverlayOff;
u32 ARM9OverlaySize;
u32 ARM7OverlayOff;
u32 ARM7OverlaySize;
-
+
u32 unknown2a;
u32 unknown2b;
-
+
u32 IconOff;
u16 CRC16;
u16 ROMtimeout;
u32 ARM9unk;
u32 ARM7unk;
-
+
u8 unknown3c[8];
u32 ROMSize;
u32 HeaderSize;
@@ -120,7 +115,7 @@ typedef struct
u32 old;
s32 diff;
BOOL lignerendu;
-
+
u16 touchX;
u16 touchY;
} NDSSystem;
@@ -181,7 +176,7 @@ NDS_FillDefaultFirmwareConfigData( struct NDS_fw_config_data *fw_config);
BOOL NDS_SetROM(u8 * rom, u32 mask);
NDS_header * NDS_getROMHeader(void);
-
+
void NDS_setTouchPos(u16 x, u16 y);
void NDS_releasTouch(void);
@@ -202,54 +197,50 @@ NDS_exec(s32 nb, BOOL force);
if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0x10)
{
MMU.reg_IF[0] |= 2;// & (MMU.reg_IME[0] << 1);// (MMU.reg_IE[0] & (1<<1));
- NDS_ARM9.wIRQ = TRUE;
+ NDS_ARM9.wIRQ = true;
}
}
-
+
static INLINE void NDS_ARM7HBlankInt(void)
{
if(T1ReadWord(MMU.ARM7_REG, 4) & 0x10)
{
MMU.reg_IF[1] |= 2;// & (MMU.reg_IME[1] << 1);// (MMU.reg_IE[1] & (1<<1));
- NDS_ARM7.wIRQ = TRUE;
+ NDS_ARM7.wIRQ = true;
}
}
-
+
static INLINE void NDS_ARM9VBlankInt(void)
{
if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0x8)
{
MMU.reg_IF[0] |= 1;// & (MMU.reg_IME[0]);// (MMU.reg_IE[0] & 1);
- NDS_ARM9.wIRQ = TRUE;
- //execute = FALSE;
+ NDS_ARM9.wIRQ = true;
+ //execute = false;
/*logcount++;*/
}
}
-
+
static INLINE void NDS_ARM7VBlankInt(void)
{
if(T1ReadWord(MMU.ARM7_REG, 4) & 0x8)
MMU.reg_IF[1] |= 1;// & (MMU.reg_IME[1]);// (MMU.reg_IE[1] & 1);
- NDS_ARM7.wIRQ = TRUE;
- //execute = FALSE;
+ NDS_ARM7.wIRQ = true;
+ //execute = false;
}
-
+
static INLINE void NDS_swapScreen(void)
{
u16 tmp = MainScreen.offset;
MainScreen.offset = SubScreen.offset;
SubScreen.offset = tmp;
}
-
-
+
+
void NDS_exec_frame(int cpu_clockdown_level_arm9, int cpu_clockdown_level_arm7);
void NDS_exec_hframe(int cpu_clockdown_level_arm9, int cpu_clockdown_level_arm7);
-#ifdef __cplusplus
-}
#endif
-#endif
-
diff --git a/src/xsf/desmume/SPU.c b/src/xsf/desmume/SPU.c
deleted file mode 100644
index 26cd603f7f30..000000000000
--- a/src/xsf/desmume/SPU.c
+++ /dev/null
@@ -1,961 +0,0 @@
-/* Copyright (C) 2006 Theo Berkau
-
- Ideas borrowed from Stephane Dallongeville's SCSP core
-
- This file is part of DeSmuME
-
- DeSmuME 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.
-
- DeSmuME 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 DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "ARM9.h"
-#include "MMU.h"
-#include "SPU.h"
-#include "mem.h"
-
-#include "armcpu.h"
-
-enum
-{
- FORMAT_PCM8 = 0,
- FORMAT_PCM16 = 1,
- FORMAT_ADPCM = 2,
- FORMAT_PSG = 3
-};
-
-#define VOL_SHIFT 10
-
-typedef struct
-{
- int id;
- int status;
- int format;
- u8 *buf8; s16 *buf16;
- double pos, inc;
- int loopend, looppos;
- int loop, length;
- s32 adpcm;
- int adpcm_pos, adpcm_index;
- s32 adpcm_loop;
- int adpcm_loop_pos, adpcm_loop_index;
- int psg_duty;
- int timer;
- int volume;
- int pan;
- int shift;
- int repeat, hold;
- u32 addr;
- s32 volumel;
- s32 volumer;
- s16 output;
-} SChannel;
-
-typedef struct
-{
- s32 *pmixbuf;
- s16 *pclipingbuf;
- u32 buflen;
- SChannel ch[16];
-} SPU_struct;
-
-static SPU_struct spu = { 0, 0, 0 };
-
-static SoundInterface_struct *SNDCore=NULL;
-extern SoundInterface_struct *SNDCoreList[];
-
-int SPU_ChangeSoundCore(int coreid, int buffersize)
-{
- int i;
- SPU_DeInit();
-
- // Allocate memory for sound buffer
- spu.buflen = buffersize * 2; /* stereo */
- spu.pmixbuf = malloc(spu.buflen * sizeof(s32));
- if (!spu.pmixbuf)
- {
- SPU_DeInit();
- return -1;
- }
-
- spu.pclipingbuf = malloc(spu.buflen * sizeof(s16));
- if (!spu.pclipingbuf)
- {
- SPU_DeInit();
- return -1;
- }
-
- // So which core do we want?
- if (coreid == SNDCORE_DEFAULT)
- coreid = 0; // Assume we want the first one
-
- // Go through core list and find the id
- for (i = 0; SNDCoreList[i] != NULL; i++)
- {
- if (SNDCoreList[i]->id == coreid)
- {
- // Set to current core
- SNDCore = SNDCoreList[i];
- break;
- }
- }
-
- if (SNDCore == NULL)
- {
- SPU_DeInit();
- return -1;
- }
-
- if (SNDCore->Init(spu.buflen) == -1)
- {
- // Since it failed, instead of it being fatal, we'll just use the dummy
- // core instead
- SNDCore = &SNDDummy;
- }
-
- return 0;
-}
-int SPU_Init(int coreid, int buffersize)
-{
- SPU_DeInit();
- SPU_Reset();
- return SPU_ChangeSoundCore(coreid, buffersize);
-}
-void SPU_Pause(int pause)
-{
- if(pause)
- SNDCore->MuteAudio();
- else
- SNDCore->UnMuteAudio();
-}
-void SPU_SetVolume(int volume)
-{
- if (SNDCore)
- SNDCore->SetVolume(volume);
-}
-void SPU_DeInit(void)
-{
- spu.buflen = 0;
- if (spu.pmixbuf)
- {
- free(spu.pmixbuf);
- spu.pmixbuf = 0;
- }
- if (spu.pclipingbuf)
- {
- free(spu.pclipingbuf);
- spu.pclipingbuf = 0;
- }
- if (SNDCore)
- {
- SNDCore->DeInit();
- }
- SNDCore = &SNDDummy;
-}
-
-static const short g_adpcm_index[16] = { -1, -1, -1, -1, -1, -1, -1, -1, 2, 2, 4, 4, 6, 6, 8, 8 };
-
-static const int g_adpcm_mult[89] =
-{
- 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x0010, 0x0011,
- 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F, 0x0022, 0x0025, 0x0029, 0x002D,
- 0x0032, 0x0037, 0x003C, 0x0042, 0x0049, 0x0050, 0x0058, 0x0061, 0x006B, 0x0076,
- 0x0082, 0x008F, 0x009D, 0x00AD, 0x00BE, 0x00D1, 0x00E6, 0x00FD, 0x0117, 0x0133,
- 0x0151, 0x0173, 0x0198, 0x01C1, 0x01EE, 0x0220, 0x0256, 0x0292, 0x02D4, 0x031C,
- 0x036C, 0x03C3, 0x0424, 0x048E, 0x0502, 0x0583, 0x0610, 0x06AB, 0x0756, 0x0812,
- 0x08E0, 0x09C3, 0x0ABD, 0x0BD0, 0x0CFF, 0x0E4C, 0x0FBA, 0x114C, 0x1307, 0x14EE,
- 0x1706, 0x1954, 0x1BDC, 0x1EA5, 0x21B6, 0x2515, 0x28CA, 0x2CDF, 0x315B, 0x364B,
- 0x3BB9, 0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF,
-};
-
-static const s16 g_psg_duty[8][8] = {
- { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, +0x7FFF },
- { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, +0x7FFF, +0x7FFF },
- { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF },
- { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF },
- { -0x7FFF, -0x7FFF, -0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF },
- { -0x7FFF, -0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF },
- { -0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF },
- { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF },
-};
-
-
-static void reset_channel(SChannel *ch, int id)
-{
- ch->status = 0;
- ch->id = id;
-}
-
-void SPU_Reset(void)
-{
- int i;
- for (i = 0;i < 16; i++)
- reset_channel(&spu.ch[i], i);
-
- for (i = 0x400; i < 0x51D; i++)
- T1WriteByte(MMU.ARM7_REG, i, 0);
-}
-void SPU_KeyOn(int channel)
-{
-}
-
-static INLINE void adjust_channel_timer(SChannel *ch)
-{
- ch->inc = (((double)33512000) / (44100 * 2)) / (double)(0x10000 - ch->timer);
-}
-
-static int check_valid(u32 addr, u32 size)
-{
- u32 t1, t2;
-
- if(size > MMU.MMU_MASK[1][(addr >> 20) & 0xff]) return 0;
-
- t1 = addr;
- t2 = (addr + size);
- t1 &= MMU.MMU_MASK[1][(addr >> 20) & 0xff];
- t2 &= MMU.MMU_MASK[1][(addr >> 20) & 0xff];
-
- if(t2 < t1) return 0;
-
- return 1;
-}
-
-static void start_channel(SChannel *ch)
-{
-
- switch(ch->format)
- {
- case FORMAT_PCM8:
- {
- u8 *p = MMU.MMU_MEM[1][(ch->addr >> 20) & 0xff];
- u32 ofs = MMU.MMU_MASK[1][(ch->addr >> 20) & 0xff] & ch->addr;
- u32 size = ((ch->length + ch->loop) << 2);
- if((p != NULL) && check_valid(ch->addr, size))
- {
- ch->buf8 = p + ofs;
- ch->looppos = ch->loop << 2;
- ch->loopend = size;
- ch->pos = 0;
- ch->status = 1;
- }
- }
- break;
- case FORMAT_PCM16:
- {
- u8 *p = MMU.MMU_MEM[1][(ch->addr >> 20) & 0xff];
- u32 ofs = MMU.MMU_MASK[1][(ch->addr >> 20) & 0xff] & ch->addr;
- u32 size = ((ch->length + ch->loop) << 1);
- if((p != NULL) && check_valid(ch->addr, size << 1))
- {
- ch->buf16 = (s16 *)(p + ofs - (ofs & 1));
- ch->looppos = ch->loop << 1;
- ch->loopend = size;
- ch->pos = 0;
- ch->status = 1;
- }
- }
- break;
- case FORMAT_ADPCM:
- {
- u8 *p = MMU.MMU_MEM[1][(ch->addr >> 20) & 0xff];
- u32 ofs = MMU.MMU_MASK[1][(ch->addr >> 20) & 0xff] & ch->addr;
- u32 size = ((ch->length + ch->loop) << 3);
- if((p != NULL) && check_valid(ch->addr, size >> 1))
- {
- ch->buf8 = p + ofs;
-#ifdef WORDS_BIGENDIAN
- ch->adpcm = ((s32)(s16)T1ReadWord((u8 *)ch->buf8, 0)) << 3;
-#else
- ch->adpcm = ((s32)*(s16 *)ch->buf8) << 3;
-#endif
- ch->adpcm_index = (ch->buf8[2] & 0x7F);
- ch->adpcm_pos = 8;
- ch->pos = 9;
- ch->looppos = ch->loop << 3;
- ch->loopend = size;
- ch->adpcm_loop_index = -1;
- ch->status = 1;
- }
- }
- break;
- case FORMAT_PSG:
- ch->status = 1;
- if(ch->id < 14)
- {
- ch->pos = 0;
- }
- else
- {
- ch->pos = 0x7FFF;
- }
- break;
- }
-}
-
-static void stop_channel(SChannel *ch)
-{
- u32 addr = 0x400 + (ch->id << 4) + 3;
- ch->status = 0;
- T1WriteByte(MMU.ARM7_REG, addr, (u8)(T1ReadByte(MMU.ARM7_REG, addr) & ~0x80));
-}
-static void set_channel_volume(SChannel *ch)
-{
- s32 vol1 = (T1ReadByte(MMU.ARM7_REG, 0x500) & 0x7F) * ch->volume;
- s32 vol2;
- vol2 = vol1 * ch->pan;
- vol1 = vol1 * (127-ch->pan);
- ch->volumel = vol1 >> (21 - VOL_SHIFT + ch->shift);
- ch->volumer = vol2 >> (21 - VOL_SHIFT + ch->shift);
-}
-
-void SPU_WriteByte(u32 addr, u8 x)
-{
- addr &= 0x00000FFF;
- T1WriteByte(MMU.ARM7_REG, addr, x);
-
- if(addr < 0x500)
- {
- SChannel *ch;
- switch(addr & 0x0F)
- {
- case 0x0:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->volume = (x & 0x7F);
- set_channel_volume(ch);
- break;
- case 0x1:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->shift = (x & 0x03);
- ch->hold = (x >> 7 & 0x01);
- set_channel_volume(ch);
- break;
- case 0x2:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->pan = (x & 0x7F);
- set_channel_volume(ch);
- break;
- case 0x3:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->psg_duty = (x & 0x07);
- ch->repeat = (x >> 3 & 0x03);
- ch->format = (x >> 5 & 0x03);
- if(x & 0x80) start_channel(ch); else stop_channel(ch);
- break;
-#if !DISABLE_XSF_TESTS
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x07:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->addr = (T1ReadLong(MMU.ARM7_REG, addr & ~3) & 0x07FFFFFF);
- break;
- case 0x08:
- case 0x09:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->timer = T1ReadWord(MMU.ARM7_REG, addr & ~1);
- adjust_channel_timer(ch);
- break;
- case 0x0a:
- case 0x0b:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->loop = T1ReadWord(MMU.ARM7_REG, addr & ~1);
- break;
- case 0x0c:
- case 0x0e:
- case 0x0d:
- case 0x0f:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->length = (T1ReadLong(MMU.ARM7_REG, addr & ~3) & 0x003FFFFF);
- break;
-#endif
- }
- }
-
-}
-
-
-void SPU_WriteWord(u32 addr, u16 x)
-{
- addr &= 0x00000FFF;
- T1WriteWord(MMU.ARM7_REG, addr, x);
-
- if(addr < 0x500)
- {
- SChannel *ch;
- switch(addr & 0x00F)
- {
- case 0x0:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->volume = (x & 0x007F);
- ch->shift = (x >> 8 & 0x0003);
- ch->hold = (x >> 15 & 0x0001);
- set_channel_volume(ch);
- break;
- case 0x2:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->pan = (x & 0x007F);
- ch->psg_duty = (x >> 8 & 0x0007);
- ch->repeat = (x >> 11 & 0x0003);
- ch->format = (x >> 13 & 0x0003);
- set_channel_volume(ch);
- if(x & 0x8000) start_channel(ch); else stop_channel(ch);
- break;
- case 0x08:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->timer = x;
- adjust_channel_timer(ch);
- break;
- case 0x0a:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->loop = x;
- break;
-#if !DISABLE_XSF_TESTS
- case 0x04:
- case 0x06:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->addr = (T1ReadLong(MMU.ARM7_REG, addr & ~3) & 0x07FFFFFF);
- break;
- case 0x0c:
- case 0x0e:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->length = (T1ReadLong(MMU.ARM7_REG, addr & ~3) & 0x003FFFFF);
- break;
-#endif
- }
- }
-}
-
-
-void SPU_WriteLong(u32 addr, u32 x)
-{
- addr &= 0x00000FFF;
- T1WriteLong(MMU.ARM7_REG, addr, x);
-
- if(addr < 0x500)
- {
- SChannel *ch;
- switch(addr & 0x00F)
- {
- case 0x0:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->volume = (x & 0x7F);
- ch->shift = (x >> 8 & 0x00000003);
- ch->hold = (x >> 15 & 0x00000001);
- ch->pan = (x >> 16 & 0x0000007F);
- ch->psg_duty = (x >> 24 & 0x00000007);
- ch->repeat = (x >> 27 & 0x00000003);
- ch->format = (x >> 29 & 0x00000003);
- set_channel_volume(ch);
- if(x & 0x80000000) start_channel(ch); else stop_channel(ch);
- break;
- case 0x04:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->addr = (x & 0x07FFFFFF);
- break;
- case 0x08:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->timer = (x & 0x0000FFFF);
- ch->loop = (x >> 16 & 0x0000FFFF);
- adjust_channel_timer(ch);
- break;
- case 0x0C:
- ch = spu.ch + (addr >> 4 & 0xF);
- ch->length = (x & 0x003FFFFF);
- break;
- }
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-u32 SPU_ReadLong(u32 addr)
-{
- addr &= 0xFFF;
- return T1ReadLong(MMU.ARM7_REG, addr);
-}
-
-static INLINE s32 clipping(s32 x, s32 min, s32 max) {
-#if 1 || defined(SIGNED_IS_NOT_2S_COMPLEMENT)
- if (x < min)
- {
- return (min);
- }
- else if (x > max)
- {
- return (max);
- }
- return (x);
-#else
- return x ^ ((-(x < min)) & (x ^ min)) ^ ((-(x > max)) & (x ^ max));
-#endif
-}
-
-extern unsigned long dwChannelMute;
-
-static void decode_pcm8(SChannel *ch, s32 *out, int length)
-{
- int oi;
- double pos, inc, len;
- if (!ch->buf8) return;
-
- pos = ch->pos; inc = ch->inc; len = ch->loopend;
-
- for(oi = 0; oi < length; oi++)
- {
- ch->output = ((s16)(s8)ch->buf8[(int)pos]) << 8;
-#if 0
- if (dwChannelMute & (1 << ch->id))
- {
- out++;
- out++;
- }
- else
-#endif
- {
- *(out++) += (ch->output * ch->volumel) >> VOL_SHIFT;
- *(out++) += (ch->output * ch->volumer) >> VOL_SHIFT;
- }
- pos += inc;
- if(pos >= len)
- {
- switch(ch->repeat)
- {
-#if !DISABLE_XSF_TESTS
- case 0:
-#endif
- case 1:
- pos += ch->looppos - len;
- break;
- default:
- stop_channel(ch);
- oi = length;
- break;
- }
- }
- }
-
- ch->pos = pos;
- return;
-}
-
-static void decode_pcm16(SChannel *ch, s32 *out, int length)
-{
- int oi;
- double pos, inc, len;
-
- if (!ch->buf16) return;
-
- pos = ch->pos; inc = ch->inc; len = ch->loopend;
-
- for(oi = 0; oi < length; oi++)
- {
-#ifdef WORDS_BIGENDIAN
- ch->output = (s16)T1ReadWord((u8 *)ch->buf16, (int)pos << 1);
-#else
- ch->output = (s16)ch->buf16[(int)pos];
-#endif
-#if 0
- if (dwChannelMute & (1 << ch->id))
- {
- out++;
- out++;
- }
- else
-#endif
- {
- *(out++) += (ch->output * ch->volumel) >> VOL_SHIFT;
- *(out++) += (ch->output * ch->volumer) >> VOL_SHIFT;
- }
- pos += inc;
- if(pos >= len)
- {
- switch(ch->repeat)
- {
-#if !DISABLE_XSF_TESTS
- case 0:
-#endif
- case 1:
- pos += ch->looppos - len;
- break;
- default:
- stop_channel(ch);
- oi = length;
- break;
- }
- }
- }
-
- ch->pos = pos;
-}
-
-static INLINE void decode_adpcmone_P4(SChannel *ch, int m)
-{
- int i, ci0;
- u8 *p;
- s32 s;
- int N;
-
- i = ch->adpcm_pos;
- p = (ch->buf8 + (i >> 1));
- ci0 = ch->adpcm_index;
- s = ch->adpcm;
-
- if (ch->adpcm_loop_index < 0 && m >= ch->looppos)
- {
- ch->adpcm_loop_index = ci0;
- ch->adpcm_loop = s;
- ch->adpcm_loop_pos = i;
- }
-
- if(i++ & 1)
- {
- s32 x1, d1;
- x1 = ((*(p++) >> 3) & 0x1F) | 1;
- d1 = ((x1 & 0xF) * g_adpcm_mult[ci0] & ~7);
- ci0 = clipping((ci0 + g_adpcm_index[x1 & 0xE]), 0, 88);
-#if 1 || defined(SIGNED_IS_NOT_2S_COMPLEMENT)
- if(x1 & 0x10) d1 = -d1;
-#else
- d1 -= (d1 + d1) & (-(((x1 >> 4) & 1)));
-#endif
-
- s = clipping((s + d1), (-32768 << 3), (32767 << 3));
- }
-
- N = (((m & ~1) - (i & ~1)) >> 1);
- for(i = 0; i < N; i++)
- {
- s32 x0, d0;
- s32 x1, d1;
- int ci1;
- x0 = ((*p << 1) & 0x1F) | 1;
- x1 = ((*p >> 3) & 0x1F) | 1;
- ci1 = clipping((ci0 + g_adpcm_index[x0 & 0xE]), 0, 88);
- d0 = ((x0 & 0xF) * g_adpcm_mult[ci0] & ~7);
- ci0 = clipping((ci1 + g_adpcm_index[x1 & 0xE]), 0, 88);
- d1 = ((x1 & 0xF) * g_adpcm_mult[ci1] & ~7);
-#if 1 || defined(SIGNED_IS_NOT_2S_COMPLEMENT)
- if(x0 & 0x10) d0 = -d0;
- if(x1 & 0x10) d1 = -d1;
-#else
- d0 -= (d0 + d0) & (-(((x0 >> 4) & 1)));
- d1 -= (d1 + d1) & (-(((x1 >> 4) & 1)));
-#endif
- s = clipping((s + d0), (-32768 << 3), (32767 << 3));
- s = clipping((s + d1), (-32768 << 3), (32767 << 3));
- p++;
- }
- if(m & 1)
- {
- s32 x0, d0;
- x0 = ((*p << 1) & 0x1F) | 1;
- d0 = ((x0 & 0xF) * g_adpcm_mult[ci0] & ~7);
- ci0 = clipping((ci0 + g_adpcm_index[x0 & 0xE]), 0, 88);
-#if 1 || defined(SIGNED_IS_NOT_2S_COMPLEMENT)
- if(x0 & 0x10) d0 = -d0;
-#else
- d0 -= (d0 + d0) & (-(((x0 >> 4) & 1)));
-#endif
- s = clipping((s + d0), (-32768 << 3), (32767 << 3));
- }
-
- ch->output = (s16)(s >> 3);
-
- ch->adpcm = s;
- ch->adpcm_index = ci0;
- ch->adpcm_pos = m;
-}
-
-static INLINE void decode_adpcmone_XX(SChannel *ch, int m)
-{
- int i, ci0;
- u8 *p;
- s32 s;
-
- i = ch->adpcm_pos;
- p = (ch->buf8 + (i >> 1));
- ci0 = ch->adpcm_index;
- s = ch->adpcm;
-
- if (ch->adpcm_loop_index < 0 && m >= ch->looppos)
- {
- ch->adpcm_loop_index = ci0;
- ch->adpcm_loop = s;
- ch->adpcm_loop_pos = i;
- }
-
- while (i < m)
- {
- s32 x1, d1;
- x1 = ((s32)*p) >> ((i & 1) << 2) & 0xf;
- x1 = x1 + x1 + 1;
- d1 = ((x1 & 0xF) * g_adpcm_mult[ci0] & ~7);
- ci0 = clipping((ci0 + g_adpcm_index[x1 & 0xE]), 0, 88);
-#if 1 || defined(SIGNED_IS_NOT_2S_COMPLEMENT)
- if(x1 & 0x10) d1 = -d1;
-#else
- d1 -= (d1 + d1) & (-(((x1 >> 4) & 1)));
-#endif
-
- s = clipping((s + d1), (-32768 << 3), (32767 << 3));
- p += (i & 1);
- i++;
- }
-
- ch->output = (s16)(s >> 3);
-
- ch->adpcm = s;
- ch->adpcm_index = ci0;
- ch->adpcm_pos = m;
-}
-
-#define decode_adpcmone decode_adpcmone_P4
-
-static void decode_adpcm(SChannel *ch, s32 *out, int length)
-{
- int oi;
- double pos, inc, len;
- if (!ch->buf8) return;
-
- pos = ch->pos; inc = ch->inc; len = ch->loopend;
-
- for(oi = 0; oi < length; oi++)
- {
- int m = (int)pos;
- int i = ch->adpcm_pos;
- if(i < m)
- decode_adpcmone(ch, m);
-
-#if 0
- if (dwChannelMute & (1 << ch->id))
- {
- out++;
- out++;
- }
- else
-#endif
- {
- *(out++) += (ch->output * ch->volumel) >> VOL_SHIFT;
- *(out++) += (ch->output * ch->volumer) >> VOL_SHIFT;
- }
- pos += inc;
- if(pos >= len)
- {
- switch(ch->repeat)
- {
- case 1:
- if (ch->adpcm_loop_index >= 0)
- {
- pos += ch->looppos - len;
- ch->adpcm_pos = ch->adpcm_loop_pos;
- ch->adpcm_index = ch->adpcm_loop_index;
- ch->adpcm = ch->adpcm_loop;
- break;
- }
-#if !DISABLE_XSF_TESTS
- case 0:
- pos = 9 - len;
-#ifdef WORDS_BIGENDIAN
- ch->adpcm = ((s32)(s16)T1ReadWord((u8 *)ch->buf8, 0)) << 3;
-#else
- ch->adpcm = ((s32)*(s16 *)ch->buf8) << 3;
-#endif
- ch->adpcm_index = (ch->buf8[2] & 0x7F);
- ch->adpcm_pos = 8;
- break;
-#endif
- default:
- stop_channel(ch);
- oi = length;
- break;
- }
- }
- }
- ch->pos = pos;
-}
-
-static void decode_psg(SChannel *ch, s32 *out, int length)
-{
- int oi;
-
- if(ch->id < 14)
- {
- // NOTE: square wave.
- double pos, inc;
- pos = ch->pos; inc = ch->inc;
- for(oi = 0; oi < length; oi++)
- {
- ch->output = (s16)g_psg_duty[ch->psg_duty][(int)pos & 0x00000007];
-#if 0
- if (dwChannelMute & (1 << ch->id))
- {
- out++;
- out++;
- }
- else
-#endif
- {
- *(out++) += (ch->output * ch->volumel) >> VOL_SHIFT;
- *(out++) += (ch->output * ch->volumer) >> VOL_SHIFT;
- }
- pos += inc;
- }
- ch->pos = pos;
- }
- else
- {
- // NOTE: noise.
- u16 X;
- X = (u16)ch->pos;
- for(oi = 0; oi < length; oi++)
- {
- if(X & 1)
- {
- X >>= 1;
- X ^= 0x6000;
- ch->output = -0x8000;
- }
- else
- {
- X >>= 1;
- ch->output = +0x7FFF;
- }
- }
-#if 0
- if (dwChannelMute & (1 << ch->id))
- {
- out++;
- out++;
- }
- else
-#endif
- {
- *(out++) += (ch->output * ch->volumel) >> VOL_SHIFT;
- *(out++) += (ch->output * ch->volumer) >> VOL_SHIFT;
- }
- ch->pos = X;
- }
-}
-
-
-
-void SPU_EmulateSamples(u32 numsamples)
-{
- u32 sizesmp = numsamples;
- u32 sizebyte = sizesmp << 2;
- if (sizebyte > spu.buflen * sizeof(s16)) sizebyte = spu.buflen * sizeof(s16);
- sizesmp = sizebyte >> 2;
- sizebyte = sizesmp << 2;
- if (sizesmp > 0)
- {
- unsigned i;
- SChannel *ch = spu.ch;
- memset(spu.pmixbuf, 0, spu.buflen * sizeof(s32));
- for (i = 0; i < 16; i++)
- {
- if (ch->status)
- {
- switch (ch->format)
- {
- case 0:
- decode_pcm8(ch, spu.pmixbuf, sizesmp);
- break;
- case 1:
- decode_pcm16(ch, spu.pmixbuf, sizesmp);
- break;
- case 2:
- decode_adpcm(ch, spu.pmixbuf, sizesmp);
- break;
- case 3:
- decode_psg(ch, spu.pmixbuf, sizesmp);
- break;
- }
- }
- ch++;
- }
- for (i = 0; i < sizesmp * 2; i++)
- spu.pclipingbuf[i] = (s16)clipping(spu.pmixbuf[i], -0x8000, 0x7fff);
- SNDCore->UpdateAudio(spu.pclipingbuf, sizesmp);
- }
-}
-
-void SPU_Emulate(void)
-{
- SPU_EmulateSamples(SNDCore->GetAudioSpace());
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-// Dummy Sound Interface
-//////////////////////////////////////////////////////////////////////////////
-
-static int SNDDummyInit(int buffersize)
-{
- return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-static void SNDDummyDeInit()
-{
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-static void SNDDummyUpdateAudio(s16 *buffer, u32 num_samples)
-{
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-static u32 SNDDummyGetAudioSpace()
-{
- return 735;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-static void SNDDummyMuteAudio()
-{
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-static void SNDDummyUnMuteAudio()
-{
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-static void SNDDummySetVolume(int volume)
-{
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-SoundInterface_struct SNDDummy =
-{
- SNDCORE_DUMMY,
- "Dummy Sound Interface",
- SNDDummyInit,
- SNDDummyDeInit,
- SNDDummyUpdateAudio,
- SNDDummyGetAudioSpace,
- SNDDummyMuteAudio,
- SNDDummyUnMuteAudio,
- SNDDummySetVolume
-};
-
diff --git a/src/xsf/desmume/SPU.cc b/src/xsf/desmume/SPU.cc
new file mode 100644
index 000000000000..eca09e9aaf35
--- /dev/null
+++ b/src/xsf/desmume/SPU.cc
@@ -0,0 +1,963 @@
+/* Copyright (C) 2006 Theo Berkau
+
+ Ideas borrowed from Stephane Dallongeville's SCSP core
+
+ This file is part of DeSmuME
+
+ DeSmuME 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.
+
+ DeSmuME 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 DeSmuME; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "ARM9.h"
+#include "MMU.h"
+#include "SPU.h"
+#include "mem.h"
+
+#include "armcpu.h"
+
+enum
+{
+ FORMAT_PCM8 = 0,
+ FORMAT_PCM16 = 1,
+ FORMAT_ADPCM = 2,
+ FORMAT_PSG = 3
+};
+
+#define VOL_SHIFT 10
+
+typedef struct
+{
+ int id;
+ int status;
+ int format;
+ u8 *buf8; s16 *buf16;
+ double pos, inc;
+ int loopend, looppos;
+ int loop, length;
+ s32 adpcm;
+ int adpcm_pos, adpcm_index;
+ s32 adpcm_loop;
+ int adpcm_loop_pos, adpcm_loop_index;
+ int psg_duty;
+ int timer;
+ int volume;
+ int pan;
+ int shift;
+ int repeat, hold;
+ u32 addr;
+ s32 volumel;
+ s32 volumer;
+ s16 output;
+} SChannel;
+
+typedef struct
+{
+ s32 *pmixbuf;
+ s16 *pclipingbuf;
+ u32 buflen;
+ SChannel ch[16];
+} SPU_struct;
+
+static SPU_struct spu = { 0, 0, 0 };
+
+static SoundInterface_struct *SNDCore=nullptr;
+extern SoundInterface_struct *SNDCoreList[];
+
+int SPU_ChangeSoundCore(int coreid, int buffersize)
+{
+ int i;
+ SPU_DeInit();
+
+ // Allocate memory for sound buffer
+ spu.buflen = buffersize * 2; /* stereo */
+ spu.pmixbuf = (s32 *) malloc(spu.buflen * sizeof(s32));
+ if (!spu.pmixbuf)
+ {
+ SPU_DeInit();
+ return -1;
+ }
+
+ spu.pclipingbuf = (s16 *) malloc(spu.buflen * sizeof(s16));
+ if (!spu.pclipingbuf)
+ {
+ SPU_DeInit();
+ return -1;
+ }
+
+ // So which core do we want?
+ if (coreid == SNDCORE_DEFAULT)
+ coreid = 0; // Assume we want the first one
+
+ // Go through core list and find the id
+ for (i = 0; SNDCoreList[i] != nullptr; i++)
+ {
+ if (SNDCoreList[i]->id == coreid)
+ {
+ // Set to current core
+ SNDCore = SNDCoreList[i];
+ break;
+ }
+ }
+
+ if (SNDCore == nullptr)
+ {
+ SPU_DeInit();
+ return -1;
+ }
+
+ if (SNDCore->Init(spu.buflen) == -1)
+ {
+ // Since it failed, instead of it being fatal, we'll just use the dummy
+ // core instead
+ SNDCore = &SNDDummy;
+ }
+
+ return 0;
+}
+int SPU_Init(int coreid, int buffersize)
+{
+ SPU_DeInit();
+ SPU_Reset();
+ return SPU_ChangeSoundCore(coreid, buffersize);
+}
+void SPU_Pause(int pause)
+{
+ if(pause)
+ SNDCore->MuteAudio();
+ else
+ SNDCore->UnMuteAudio();
+}
+void SPU_SetVolume(int volume)
+{
+ if (SNDCore)
+ SNDCore->SetVolume(volume);
+}
+void SPU_DeInit(void)
+{
+ spu.buflen = 0;
+ if (spu.pmixbuf)
+ {
+ free(spu.pmixbuf);
+ spu.pmixbuf = 0;
+ }
+ if (spu.pclipingbuf)
+ {
+ free(spu.pclipingbuf);
+ spu.pclipingbuf = 0;
+ }
+ if (SNDCore)
+ {
+ SNDCore->DeInit();
+ }
+ SNDCore = &SNDDummy;
+}
+
+static const short g_adpcm_index[16] = { -1, -1, -1, -1, -1, -1, -1, -1, 2, 2, 4, 4, 6, 6, 8, 8 };
+
+static const int g_adpcm_mult[89] =
+{
+ 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x0010, 0x0011,
+ 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F, 0x0022, 0x0025, 0x0029, 0x002D,
+ 0x0032, 0x0037, 0x003C, 0x0042, 0x0049, 0x0050, 0x0058, 0x0061, 0x006B, 0x0076,
+ 0x0082, 0x008F, 0x009D, 0x00AD, 0x00BE, 0x00D1, 0x00E6, 0x00FD, 0x0117, 0x0133,
+ 0x0151, 0x0173, 0x0198, 0x01C1, 0x01EE, 0x0220, 0x0256, 0x0292, 0x02D4, 0x031C,
+ 0x036C, 0x03C3, 0x0424, 0x048E, 0x0502, 0x0583, 0x0610, 0x06AB, 0x0756, 0x0812,
+ 0x08E0, 0x09C3, 0x0ABD, 0x0BD0, 0x0CFF, 0x0E4C, 0x0FBA, 0x114C, 0x1307, 0x14EE,
+ 0x1706, 0x1954, 0x1BDC, 0x1EA5, 0x21B6, 0x2515, 0x28CA, 0x2CDF, 0x315B, 0x364B,
+ 0x3BB9, 0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF,
+};
+
+static const s16 g_psg_duty[8][8] = {
+ { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, +0x7FFF },
+ { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, +0x7FFF, +0x7FFF },
+ { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF },
+ { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF },
+ { -0x7FFF, -0x7FFF, -0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF },
+ { -0x7FFF, -0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF },
+ { -0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF, +0x7FFF },
+ { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF },
+};
+
+
+static void reset_channel(SChannel *ch, int id)
+{
+ ch->status = 0;
+ ch->id = id;
+}
+
+void SPU_Reset(void)
+{
+ int i;
+ for (i = 0;i < 16; i++)
+ reset_channel(&spu.ch[i], i);
+
+ for (i = 0x400; i < 0x51D; i++)
+ T1WriteByte(MMU.ARM7_REG, i, 0);
+}
+void SPU_KeyOn(int channel)
+{
+}
+
+static INLINE void adjust_channel_timer(SChannel *ch)
+{
+ ch->inc = (((double)33512000) / (44100 * 2)) / (double)(0x10000 - ch->timer);
+}
+
+static int check_valid(u32 addr, u32 size)
+{
+ u32 t1, t2;
+
+ if(size > MMU.MMU_MASK[1][(addr >> 20) & 0xff]) return 0;
+
+ t1 = addr;
+ t2 = (addr + size);
+ t1 &= MMU.MMU_MASK[1][(addr >> 20) & 0xff];
+ t2 &= MMU.MMU_MASK[1][(addr >> 20) & 0xff];
+
+ if(t2 < t1) return 0;
+
+ return 1;
+}
+
+static void start_channel(SChannel *ch)
+{
+
+ switch(ch->format)
+ {
+ case FORMAT_PCM8:
+ {
+ u8 *p = MMU.MMU_MEM[1][(ch->addr >> 20) & 0xff];
+ u32 ofs = MMU.MMU_MASK[1][(ch->addr >> 20) & 0xff] & ch->addr;
+ u32 size = ((ch->length + ch->loop) << 2);
+ if((p != nullptr) && check_valid(ch->addr, size))
+ {
+ ch->buf8 = p + ofs;
+ ch->looppos = ch->loop << 2;
+ ch->loopend = size;
+ ch->pos = 0;
+ ch->status = 1;
+ }
+ }
+ break;
+ case FORMAT_PCM16:
+ {
+ u8 *p = MMU.MMU_MEM[1][(ch->addr >> 20) & 0xff];
+ u32 ofs = MMU.MMU_MASK[1][(ch->addr >> 20) & 0xff] & ch->addr;
+ u32 size = ((ch->length + ch->loop) << 1);
+ if((p != nullptr) && check_valid(ch->addr, size << 1))
+ {
+ ch->buf16 = (s16 *)(p + ofs - (ofs & 1));
+ ch->looppos = ch->loop << 1;
+ ch->loopend = size;
+ ch->pos = 0;
+ ch->status = 1;
+ }
+ }
+ break;
+ case FORMAT_ADPCM:
+ {
+ u8 *p = MMU.MMU_MEM[1][(ch->addr >> 20) & 0xff];
+ u32 ofs = MMU.MMU_MASK[1][(ch->addr >> 20) & 0xff] & ch->addr;
+ u32 size = ((ch->length + ch->loop) << 3);
+ if((p != nullptr) && check_valid(ch->addr, size >> 1))
+ {
+ ch->buf8 = p + ofs;
+#ifdef WORDS_BIGENDIAN
+ ch->adpcm = ((s32)(s16)T1ReadWord((u8 *)ch->buf8, 0)) << 3;
+#else
+ ch->adpcm = ((s32)*(s16 *)ch->buf8) << 3;
+#endif
+ ch->adpcm_index = (ch->buf8[2] & 0x7F);
+ ch->adpcm_pos = 8;
+ ch->pos = 9;
+ ch->looppos = ch->loop << 3;
+ ch->loopend = size;
+ ch->adpcm_loop_index = -1;
+ ch->status = 1;
+ }
+ }
+ break;
+ case FORMAT_PSG:
+ ch->status = 1;
+ if(ch->id < 14)
+ {
+ ch->pos = 0;
+ }
+ else
+ {
+ ch->pos = 0x7FFF;
+ }
+ break;
+ }
+}
+
+static void stop_channel(SChannel *ch)
+{
+ u32 addr = 0x400 + (ch->id << 4) + 3;
+ ch->status = 0;
+ T1WriteByte(MMU.ARM7_REG, addr, (u8)(T1ReadByte(MMU.ARM7_REG, addr) & ~0x80));
+}
+static void set_channel_volume(SChannel *ch)
+{
+ s32 vol1 = (T1ReadByte(MMU.ARM7_REG, 0x500) & 0x7F) * ch->volume;
+ s32 vol2;
+ vol2 = vol1 * ch->pan;
+ vol1 = vol1 * (127-ch->pan);
+ ch->volumel = vol1 >> (21 - VOL_SHIFT + ch->shift);
+ ch->volumer = vol2 >> (21 - VOL_SHIFT + ch->shift);
+}
+
+void SPU_WriteByte(u32 addr, u8 x)
+{
+ addr &= 0x00000FFF;
+ T1WriteByte(MMU.ARM7_REG, addr, x);
+
+ if(addr < 0x500)
+ {
+ SChannel *ch;
+ switch(addr & 0x0F)
+ {
+ case 0x0:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->volume = (x & 0x7F);
+ set_channel_volume(ch);
+ break;
+ case 0x1:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->shift = (x & 0x03);
+ ch->hold = (x >> 7 & 0x01);
+ set_channel_volume(ch);
+ break;
+ case 0x2:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->pan = (x & 0x7F);
+ set_channel_volume(ch);
+ break;
+ case 0x3:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->psg_duty = (x & 0x07);
+ ch->repeat = (x >> 3 & 0x03);
+ ch->format = (x >> 5 & 0x03);
+ if(x & 0x80) start_channel(ch); else stop_channel(ch);
+ break;
+#if !DISABLE_XSF_TESTS
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->addr = (T1ReadLong(MMU.ARM7_REG, addr & ~3) & 0x07FFFFFF);
+ break;
+ case 0x08:
+ case 0x09:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->timer = T1ReadWord(MMU.ARM7_REG, addr & ~1);
+ adjust_channel_timer(ch);
+ break;
+ case 0x0a:
+ case 0x0b:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->loop = T1ReadWord(MMU.ARM7_REG, addr & ~1);
+ break;
+ case 0x0c:
+ case 0x0e:
+ case 0x0d:
+ case 0x0f:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->length = (T1ReadLong(MMU.ARM7_REG, addr & ~3) & 0x003FFFFF);
+ break;
+#endif
+ }
+ }
+
+}
+
+
+void SPU_WriteWord(u32 addr, u16 x)
+{
+ addr &= 0x00000FFF;
+ T1WriteWord(MMU.ARM7_REG, addr, x);
+
+ if(addr < 0x500)
+ {
+ SChannel *ch;
+ switch(addr & 0x00F)
+ {
+ case 0x0:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->volume = (x & 0x007F);
+ ch->shift = (x >> 8 & 0x0003);
+ ch->hold = (x >> 15 & 0x0001);
+ set_channel_volume(ch);
+ break;
+ case 0x2:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->pan = (x & 0x007F);
+ ch->psg_duty = (x >> 8 & 0x0007);
+ ch->repeat = (x >> 11 & 0x0003);
+ ch->format = (x >> 13 & 0x0003);
+ set_channel_volume(ch);
+ if(x & 0x8000) start_channel(ch); else stop_channel(ch);
+ break;
+ case 0x08:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->timer = x;
+ adjust_channel_timer(ch);
+ break;
+ case 0x0a:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->loop = x;
+ break;
+#if !DISABLE_XSF_TESTS
+ case 0x04:
+ case 0x06:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->addr = (T1ReadLong(MMU.ARM7_REG, addr & ~3) & 0x07FFFFFF);
+ break;
+ case 0x0c:
+ case 0x0e:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->length = (T1ReadLong(MMU.ARM7_REG, addr & ~3) & 0x003FFFFF);
+ break;
+#endif
+ }
+ }
+}
+
+
+void SPU_WriteLong(u32 addr, u32 x)
+{
+ addr &= 0x00000FFF;
+ T1WriteLong(MMU.ARM7_REG, addr, x);
+
+ if(addr < 0x500)
+ {
+ SChannel *ch;
+ switch(addr & 0x00F)
+ {
+ case 0x0:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->volume = (x & 0x7F);
+ ch->shift = (x >> 8 & 0x00000003);
+ ch->hold = (x >> 15 & 0x00000001);
+ ch->pan = (x >> 16 & 0x0000007F);
+ ch->psg_duty = (x >> 24 & 0x00000007);
+ ch->repeat = (x >> 27 & 0x00000003);
+ ch->format = (x >> 29 & 0x00000003);
+ set_channel_volume(ch);
+ if(x & 0x80000000) start_channel(ch); else stop_channel(ch);
+ break;
+ case 0x04:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->addr = (x & 0x07FFFFFF);
+ break;
+ case 0x08:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->timer = (x & 0x0000FFFF);
+ ch->loop = (x >> 16 & 0x0000FFFF);
+ adjust_channel_timer(ch);
+ break;
+ case 0x0C:
+ ch = spu.ch + (addr >> 4 & 0xF);
+ ch->length = (x & 0x003FFFFF);
+ break;
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+u32 SPU_ReadLong(u32 addr)
+{
+ addr &= 0xFFF;
+ return T1ReadLong(MMU.ARM7_REG, addr);
+}
+
+static INLINE s32 clipping(s32 x, s32 min, s32 max) {
+#if 1 || defined(SIGNED_IS_NOT_2S_COMPLEMENT)
+ if (x < min)
+ {
+ return (min);
+ }
+ else if (x > max)
+ {
+ return (max);
+ }
+ return (x);
+#else
+ return x ^ ((-(x < min)) & (x ^ min)) ^ ((-(x > max)) & (x ^ max));
+#endif
+}
+
+extern unsigned long dwChannelMute;
+
+static void decode_pcm8(SChannel *ch, s32 *out, int length)
+{
+ int oi;
+ double pos, inc, len;
+ if (!ch->buf8) return;
+
+ pos = ch->pos; inc = ch->inc; len = ch->loopend;
+
+ for(oi = 0; oi < length; oi++)
+ {
+ ch->output = ((s16)(s8)ch->buf8[(int)pos]) << 8;
+#if 0
+ if (dwChannelMute & (1 << ch->id))
+ {
+ out++;
+ out++;
+ }
+ else
+#endif
+ {
+ *(out++) += (ch->output * ch->volumel) >> VOL_SHIFT;
+ *(out++) += (ch->output * ch->volumer) >> VOL_SHIFT;
+ }
+ pos += inc;
+ if(pos >= len)
+ {
+ switch(ch->repeat)
+ {
+#if !DISABLE_XSF_TESTS
+ case 0:
+#endif
+ case 1:
+ pos += ch->looppos - len;
+ break;
+ default:
+ stop_channel(ch);
+ oi = length;
+ break;
+ }
+ }
+ }
+
+ ch->pos = pos;
+ return;
+}
+
+static void decode_pcm16(SChannel *ch, s32 *out, int length)
+{
+ int oi;
+ double pos, inc, len;
+
+ if (!ch->buf16) return;
+
+ pos = ch->pos; inc = ch->inc; len = ch->loopend;
+
+ for(oi = 0; oi < length; oi++)
+ {
+#ifdef WORDS_BIGENDIAN
+ ch->output = (s16)T1ReadWord((u8 *)ch->buf16, (int)pos << 1);
+#else
+ ch->output = (s16)ch->buf16[(int)pos];
+#endif
+#if 0
+ if (dwChannelMute & (1 << ch->id))
+ {
+ out++;
+ out++;
+ }
+ else
+#endif
+ {
+ *(out++) += (ch->output * ch->volumel) >> VOL_SHIFT;
+ *(out++) += (ch->output * ch->volumer) >> VOL_SHIFT;
+ }
+ pos += inc;
+ if(pos >= len)
+ {
+ switch(ch->repeat)
+ {
+#if !DISABLE_XSF_TESTS
+ case 0:
+#endif
+ case 1:
+ pos += ch->looppos - len;
+ break;
+ default:
+ stop_channel(ch);
+ oi = length;
+ break;
+ }
+ }
+ }
+
+ ch->pos = pos;
+}
+
+static INLINE void decode_adpcmone_P4(SChannel *ch, int m)
+{
+ int i, ci0;
+ u8 *p;
+ s32 s;
+ int N;
+
+ i = ch->adpcm_pos;
+ p = (ch->buf8 + (i >> 1));
+ ci0 = ch->adpcm_index;
+ s = ch->adpcm;
+
+ if (ch->adpcm_loop_index < 0 && m >= ch->looppos)
+ {
+ ch->adpcm_loop_index = ci0;
+ ch->adpcm_loop = s;
+ ch->adpcm_loop_pos = i;
+ }
+
+ if(i++ & 1)
+ {
+ s32 x1, d1;
+ x1 = ((*(p++) >> 3) & 0x1F) | 1;
+ d1 = ((x1 & 0xF) * g_adpcm_mult[ci0] & ~7);
+ ci0 = clipping((ci0 + g_adpcm_index[x1 & 0xE]), 0, 88);
+#if 1 || defined(SIGNED_IS_NOT_2S_COMPLEMENT)
+ if(x1 & 0x10) d1 = -d1;
+#else
+ d1 -= (d1 + d1) & (-(((x1 >> 4) & 1)));
+#endif
+
+ s = clipping((s + d1), (-32768 << 3), (32767 << 3));
+ }
+
+ N = (((m & ~1) - (i & ~1)) >> 1);
+ for(i = 0; i < N; i++)
+ {
+ s32 x0, d0;
+ s32 x1, d1;
+ int ci1;
+ x0 = ((*p << 1) & 0x1F) | 1;
+ x1 = ((*p >> 3) & 0x1F) | 1;
+ ci1 = clipping((ci0 + g_adpcm_index[x0 & 0xE]), 0, 88);
+ d0 = ((x0 & 0xF) * g_adpcm_mult[ci0] & ~7);
+ ci0 = clipping((ci1 + g_adpcm_index[x1 & 0xE]), 0, 88);
+ d1 = ((x1 & 0xF) * g_adpcm_mult[ci1] & ~7);
+#if 1 || defined(SIGNED_IS_NOT_2S_COMPLEMENT)
+ if(x0 & 0x10) d0 = -d0;
+ if(x1 & 0x10) d1 = -d1;
+#else
+ d0 -= (d0 + d0) & (-(((x0 >> 4) & 1)));
+ d1 -= (d1 + d1) & (-(((x1 >> 4) & 1)));
+#endif
+ s = clipping((s + d0), (-32768 << 3), (32767 << 3));
+ s = clipping((s + d1), (-32768 << 3), (32767 << 3));
+ p++;
+ }
+ if(m & 1)
+ {
+ s32 x0, d0;
+ x0 = ((*p << 1) & 0x1F) | 1;
+ d0 = ((x0 & 0xF) * g_adpcm_mult[ci0] & ~7);
+ ci0 = clipping((ci0 + g_adpcm_index[x0 & 0xE]), 0, 88);
+#if 1 || defined(SIGNED_IS_NOT_2S_COMPLEMENT)
+ if(x0 & 0x10) d0 = -d0;
+#else
+ d0 -= (d0 + d0) & (-(((x0 >> 4) & 1)));
+#endif
+ s = clipping((s + d0), (-32768 << 3), (32767 << 3));
+ }
+
+ ch->output = (s16)(s >> 3);
+
+ ch->adpcm = s;
+ ch->adpcm_index = ci0;
+ ch->adpcm_pos = m;
+}
+
+#if 0 // not used
+static INLINE void decode_adpcmone_XX(SChannel *ch, int m)
+{
+ int i, ci0;
+ u8 *p;
+ s32 s;
+
+ i = ch->adpcm_pos;
+ p = (ch->buf8 + (i >> 1));
+ ci0 = ch->adpcm_index;
+ s = ch->adpcm;
+
+ if (ch->adpcm_loop_index < 0 && m >= ch->looppos)
+ {
+ ch->adpcm_loop_index = ci0;
+ ch->adpcm_loop = s;
+ ch->adpcm_loop_pos = i;
+ }
+
+ while (i < m)
+ {
+ s32 x1, d1;
+ x1 = ((s32)*p) >> ((i & 1) << 2) & 0xf;
+ x1 = x1 + x1 + 1;
+ d1 = ((x1 & 0xF) * g_adpcm_mult[ci0] & ~7);
+ ci0 = clipping((ci0 + g_adpcm_index[x1 & 0xE]), 0, 88);
+#if 1 || defined(SIGNED_IS_NOT_2S_COMPLEMENT)
+ if(x1 & 0x10) d1 = -d1;
+#else
+ d1 -= (d1 + d1) & (-(((x1 >> 4) & 1)));
+#endif
+
+ s = clipping((s + d1), (-32768 << 3), (32767 << 3));
+ p += (i & 1);
+ i++;
+ }
+
+ ch->output = (s16)(s >> 3);
+
+ ch->adpcm = s;
+ ch->adpcm_index = ci0;
+ ch->adpcm_pos = m;
+}
+#endif
+
+#define decode_adpcmone decode_adpcmone_P4
+
+static void decode_adpcm(SChannel *ch, s32 *out, int length)
+{
+ int oi;
+ double pos, inc, len;
+ if (!ch->buf8) return;
+
+ pos = ch->pos; inc = ch->inc; len = ch->loopend;
+
+ for(oi = 0; oi < length; oi++)
+ {
+ int m = (int)pos;
+ int i = ch->adpcm_pos;
+ if(i < m)
+ decode_adpcmone(ch, m);
+
+#if 0
+ if (dwChannelMute & (1 << ch->id))
+ {
+ out++;
+ out++;
+ }
+ else
+#endif
+ {
+ *(out++) += (ch->output * ch->volumel) >> VOL_SHIFT;
+ *(out++) += (ch->output * ch->volumer) >> VOL_SHIFT;
+ }
+ pos += inc;
+ if(pos >= len)
+ {
+ switch(ch->repeat)
+ {
+ case 1:
+ if (ch->adpcm_loop_index >= 0)
+ {
+ pos += ch->looppos - len;
+ ch->adpcm_pos = ch->adpcm_loop_pos;
+ ch->adpcm_index = ch->adpcm_loop_index;
+ ch->adpcm = ch->adpcm_loop;
+ break;
+ }
+#if !DISABLE_XSF_TESTS
+ case 0:
+ pos = 9 - len;
+#ifdef WORDS_BIGENDIAN
+ ch->adpcm = ((s32)(s16)T1ReadWord((u8 *)ch->buf8, 0)) << 3;
+#else
+ ch->adpcm = ((s32)*(s16 *)ch->buf8) << 3;
+#endif
+ ch->adpcm_index = (ch->buf8[2] & 0x7F);
+ ch->adpcm_pos = 8;
+ break;
+#endif
+ default:
+ stop_channel(ch);
+ oi = length;
+ break;
+ }
+ }
+ }
+ ch->pos = pos;
+}
+
+static void decode_psg(SChannel *ch, s32 *out, int length)
+{
+ int oi;
+
+ if(ch->id < 14)
+ {
+ // NOTE: square wave.
+ double pos, inc;
+ pos = ch->pos; inc = ch->inc;
+ for(oi = 0; oi < length; oi++)
+ {
+ ch->output = (s16)g_psg_duty[ch->psg_duty][(int)pos & 0x00000007];
+#if 0
+ if (dwChannelMute & (1 << ch->id))
+ {
+ out++;
+ out++;
+ }
+ else
+#endif
+ {
+ *(out++) += (ch->output * ch->volumel) >> VOL_SHIFT;
+ *(out++) += (ch->output * ch->volumer) >> VOL_SHIFT;
+ }
+ pos += inc;
+ }
+ ch->pos = pos;
+ }
+ else
+ {
+ // NOTE: noise.
+ u16 X;
+ X = (u16)ch->pos;
+ for(oi = 0; oi < length; oi++)
+ {
+ if(X & 1)
+ {
+ X >>= 1;
+ X ^= 0x6000;
+ ch->output = -0x8000;
+ }
+ else
+ {
+ X >>= 1;
+ ch->output = +0x7FFF;
+ }
+ }
+#if 0
+ if (dwChannelMute & (1 << ch->id))
+ {
+ out++;
+ out++;
+ }
+ else
+#endif
+ {
+ *(out++) += (ch->output * ch->volumel) >> VOL_SHIFT;
+ *(out++) += (ch->output * ch->volumer) >> VOL_SHIFT;
+ }
+ ch->pos = X;
+ }
+}
+
+
+
+void SPU_EmulateSamples(u32 numsamples)
+{
+ u32 sizesmp = numsamples;
+ u32 sizebyte = sizesmp << 2;
+ if (sizebyte > spu.buflen * sizeof(s16)) sizebyte = spu.buflen * sizeof(s16);
+ sizesmp = sizebyte >> 2;
+ sizebyte = sizesmp << 2;
+ if (sizesmp > 0)
+ {
+ unsigned i;
+ SChannel *ch = spu.ch;
+ memset(spu.pmixbuf, 0, spu.buflen * sizeof(s32));
+ for (i = 0; i < 16; i++)
+ {
+ if (ch->status)
+ {
+ switch (ch->format)
+ {
+ case 0:
+ decode_pcm8(ch, spu.pmixbuf, sizesmp);
+ break;
+ case 1:
+ decode_pcm16(ch, spu.pmixbuf, sizesmp);
+ break;
+ case 2:
+ decode_adpcm(ch, spu.pmixbuf, sizesmp);
+ break;
+ case 3:
+ decode_psg(ch, spu.pmixbuf, sizesmp);
+ break;
+ }
+ }
+ ch++;
+ }
+ for (i = 0; i < sizesmp * 2; i++)
+ spu.pclipingbuf[i] = (s16)clipping(spu.pmixbuf[i], -0x8000, 0x7fff);
+ SNDCore->UpdateAudio(spu.pclipingbuf, sizesmp);
+ }
+}
+
+void SPU_Emulate(void)
+{
+ SPU_EmulateSamples(SNDCore->GetAudioSpace());
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Dummy Sound Interface
+//////////////////////////////////////////////////////////////////////////////
+
+static int SNDDummyInit(int buffersize)
+{
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static void SNDDummyDeInit()
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static void SNDDummyUpdateAudio(s16 *buffer, u32 num_samples)
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static u32 SNDDummyGetAudioSpace()
+{
+ return 735;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static void SNDDummyMuteAudio()
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static void SNDDummyUnMuteAudio()
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static void SNDDummySetVolume(int volume)
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+SoundInterface_struct SNDDummy =
+{
+ SNDCORE_DUMMY,
+ "Dummy Sound Interface",
+ SNDDummyInit,
+ SNDDummyDeInit,
+ SNDDummyUpdateAudio,
+ SNDDummyGetAudioSpace,
+ SNDDummyMuteAudio,
+ SNDDummyUnMuteAudio,
+ SNDDummySetVolume
+};
+
diff --git a/src/xsf/desmume/SPU.h b/src/xsf/desmume/SPU.h
index 2f39b9e674ab..9752a424964f 100644
--- a/src/xsf/desmume/SPU.h
+++ b/src/xsf/desmume/SPU.h
@@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef SPU_H
diff --git a/src/xsf/desmume/arm_instructions.c b/src/xsf/desmume/arm_instructions.c
deleted file mode 100644
index 4bbf42ce99eb..000000000000
--- a/src/xsf/desmume/arm_instructions.c
+++ /dev/null
@@ -1,7857 +0,0 @@
-/* Copyright (C) 2006 yopyop
- Copyright (C) 2006 shash
- yopyop156 at ifrance.com
- yopyop156.ifrance.com
-
- Copyright (C) 2006-2007 shash
-
- This file is part of DeSmuME
-
- DeSmuME 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.
-
- DeSmuME 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 DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include "cp15.h"
-#include "debug.h"
-#include "MMU.h"
-
-
-// Use this macros for reading/writing, so the GDB stub isn't broken
-#ifdef GDB_STUB
- #define READ32(a,b) cpu->mem_if->read32(a,b)
- #define WRITE32(a,b,c) cpu->mem_if->write32(a,b,c)
- #define READ16(a,b) cpu->mem_if->read16(a,b)
- #define WRITE16(a,b,c) cpu->mem_if->write16(a,b,c)
- #define READ8(a,b) cpu->mem_if->read8(a,b)
- #define WRITE8(a,b,c) cpu->mem_if->write8(a,b,c)
-#else
- #define READ32(a,b) MMU_read32(cpu->proc_ID, b)
- #define WRITE32(a,b,c) MMU_write32(cpu->proc_ID,b,c)
- #define READ16(a,b) MMU_read16(cpu->proc_ID, b)
- #define WRITE16(a,b,c) MMU_write16(cpu->proc_ID,b,c)
- #define READ8(a,b) MMU_read8(cpu->proc_ID, b)
- #define WRITE8(a,b,c) MMU_write8(cpu->proc_ID,b,c)
-#endif
-
-
-
-#define LSL_IMM shift_op = cpu->R[REG_POS(i,0)]<<((i>>7)&0x1F);
-
-#define S_LSL_IMM u32 shift_op = ((i>>7)&0x1F);\
- u32 c = cpu->CPSR.bits.C;\
- if(shift_op==0)\
- shift_op=cpu->R[REG_POS(i,0)];\
- else\
- {\
- c = BIT_N(cpu->R[REG_POS(i,0)], 32-shift_op);\
- shift_op = cpu->R[REG_POS(i,0)]<<((i>>7)&0x1F);\
- }
-
-#define LSL_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
- if(shift_op>=32)\
- shift_op=0;\
- else\
- shift_op=cpu->R[REG_POS(i,0)]<<shift_op;
-
-#define S_LSL_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
- u32 c = cpu->CPSR.bits.C;\
- if(shift_op==0)\
- shift_op=cpu->R[REG_POS(i,0)];\
- else\
- if(shift_op<32)\
- {\
- c = BIT_N(cpu->R[REG_POS(i,0)], 32-shift_op);\
- shift_op = cpu->R[REG_POS(i,0)]<<shift_op;\
- }\
- else\
- if(shift_op==32)\
- {\
- shift_op = 0;\
- c = BIT0(cpu->R[REG_POS(i,0)]);\
- }\
- else\
- {\
- shift_op = 0;\
- c = 0;\
- }
-
-#define LSR_IMM shift_op = ((i>>7)&0x1F);\
- if(shift_op!=0)\
- shift_op = cpu->R[REG_POS(i,0)]>>shift_op;
-
-#define S_LSR_IMM u32 shift_op = ((i>>7)&0x1F);\
- u32 c = cpu->CPSR.bits.C;\
- if(shift_op==0)\
- {\
- c = BIT31(cpu->R[REG_POS(i,0)]);\
- }\
- else\
- {\
- c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\
- shift_op = cpu->R[REG_POS(i,0)]>>shift_op;\
- }
-
-#define LSR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
- if(shift_op>=32)\
- shift_op = 0;\
- else\
- shift_op = cpu->R[REG_POS(i,0)]>>shift_op;
-
-#define S_LSR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
- u32 c = cpu->CPSR.bits.C;\
- if(shift_op==0)\
- {\
- shift_op = cpu->R[REG_POS(i,0)];\
- }\
- else\
- if(shift_op<32)\
- {\
- c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\
- shift_op = cpu->R[REG_POS(i,0)]>>shift_op;\
- }\
- else\
- if(shift_op==32)\
- {\
- c = BIT31(cpu->R[REG_POS(i,0)]);\
- shift_op = 0;\
- }\
- else\
- {\
- c = 0;\
- shift_op = 0;\
- }
-
-#define ASR_IMM shift_op = ((i>>7)&0x1F);\
- if(shift_op==0)\
- shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;\
- else\
- shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);
-
-#define S_ASR_IMM u32 shift_op = ((i>>7)&0x1F);\
- u32 c = cpu->CPSR.bits.C;\
- if(shift_op==0)\
- {\
- shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;\
- c = BIT31(cpu->R[REG_POS(i,0)]);\
- }\
- else\
- {\
- c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\
- shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);\
- }
-
-#define ASR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
- if(shift_op==0)\
- shift_op=cpu->R[REG_POS(i,0)];\
- else\
- if(shift_op<32)\
- shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);\
- else\
- shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;
-
-#define S_ASR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
- u32 c = cpu->CPSR.bits.C;\
- if(shift_op==0)\
- shift_op=cpu->R[REG_POS(i,0)];\
- else\
- if(shift_op<32)\
- {\
- c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\
- shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);\
- }\
- else\
- {\
- c = BIT31(cpu->R[REG_POS(i,0)]);\
- shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;\
- }
-
-#define ROR_IMM shift_op = ((i>>7)&0x1F);\
- if(shift_op==0)\
- {\
- u32 tmp = cpu->CPSR.bits.C;\
- shift_op = (tmp<<31)|(cpu->R[REG_POS(i,0)]>>1);\
- }\
- else\
- shift_op = ROR(cpu->R[REG_POS(i,0)],shift_op);
-
-#define S_ROR_IMM u32 shift_op = ((i>>7)&0x1F);\
- u32 c = cpu->CPSR.bits.C;\
- if(shift_op==0)\
- {\
- u32 tmp = cpu->CPSR.bits.C;\
- shift_op = (tmp<<31)|(cpu->R[REG_POS(i,0)]>>1);\
- c = BIT0(cpu->R[REG_POS(i,0)]);\
- }\
- else\
- {\
- c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\
- shift_op = ROR(cpu->R[REG_POS(i,0)],shift_op);\
- }
-
-#define ROR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
- if((shift_op==0)||((shift_op&0xF)==0))\
- shift_op=cpu->R[REG_POS(i,0)];\
- else\
- shift_op = ROR(cpu->R[REG_POS(i,0)],(shift_op&0xF));
-
-#define S_ROR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
- u32 c = cpu->CPSR.bits.C;\
- if(shift_op==0)\
- shift_op=cpu->R[REG_POS(i,0)];\
- else\
- {\
- shift_op&=0xF;\
- if(shift_op==0)\
- {\
- shift_op=cpu->R[REG_POS(i,0)];\
- c = BIT31(cpu->R[REG_POS(i,0)]);\
- }\
- else\
- {\
- c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\
- shift_op = ROR(cpu->R[REG_POS(i,0)],(shift_op&0xF));\
- }\
- }
-
-#define IMM_VALUE u32 shift_op = ROR((i&0xFF), (i>>7)&0x1E);
-
-#define S_IMM_VALUE u32 shift_op = ROR((i&0xFF), (i>>7)&0x1E);\
- u32 c = cpu->CPSR.bits.C;\
- if((i>>8)&0xF)\
- c = BIT31(shift_op);
-
-#define IMM_OFF (((i>>4)&0xF0)+(i&0xF))
-
-#define IMM_OFF_12 ((i)&0xFFF)
-
-extern BOOL execute;
-
-static u32 FASTCALL OP_UND(armcpu_t *cpu)
-{
- LOG("Undefined instruction: %08X\n", cpu->instruction);
- execute = FALSE;
- return 1;
-}
-
-//-----------------------AND------------------------------------
-
-#define OP_AND(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & shift_op;\
- if(REG_POS(i,12)==15)\
- {\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- return a;
-
-#define OP_ANDS(a, b)\
- if(REG_POS(i,12)==15)\
- {\
- Status_Reg SPSR;\
- cpu->R[15] = cpu->R[REG_POS(i,16)] & shift_op;\
- SPSR = cpu->SPSR;\
- armcpu_switchMode(cpu, SPSR.bits.mode);\
- cpu->CPSR=SPSR;\
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & shift_op;\
- cpu->CPSR.bits.C = c;\
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
- return a;
-
-static u32 FASTCALL OP_AND_LSL_IMM(register armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OP_AND(1, 3);
-}
-
-static u32 FASTCALL OP_AND_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OP_AND(2, 4);
-}
-
-static u32 FASTCALL OP_AND_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OP_AND(1, 3);
-}
-
-static u32 FASTCALL OP_AND_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OP_AND(2, 4);
-}
-
-static u32 FASTCALL OP_AND_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OP_AND(1, 3);
-}
-
-static u32 FASTCALL OP_AND_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OP_AND(2, 4);
-}
-
-static u32 FASTCALL OP_AND_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OP_AND(1, 3);
-}
-
-static u32 FASTCALL OP_AND_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OP_AND(2, 4);
-}
-
-static u32 FASTCALL OP_AND_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OP_AND(1, 3);
-}
-
-static u32 FASTCALL OP_AND_S_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_IMM;
- OP_ANDS(2, 4);
-}
-
-static u32 FASTCALL OP_AND_S_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_REG;
- OP_ANDS(3, 5);
-}
-
-static u32 FASTCALL OP_AND_S_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_IMM;
- OP_ANDS(2, 4);
-}
-
-static u32 FASTCALL OP_AND_S_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_REG;
- OP_ANDS(3, 5);
-}
-
-static u32 FASTCALL OP_AND_S_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_IMM;
- OP_ANDS(2, 4);
-}
-
-static u32 FASTCALL OP_AND_S_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_REG;
- OP_ANDS(3, 5);
-}
-
-static u32 FASTCALL OP_AND_S_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_IMM;
- OP_ANDS(2, 4);
-}
-
-static u32 FASTCALL OP_AND_S_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_REG;
- OP_ANDS(3, 5);
-}
-
-static u32 FASTCALL OP_AND_S_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_IMM_VALUE;
- OP_ANDS(2, 4);
-}
-
-//--------------EOR------------------------------
-
-#define OP_EOR(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] ^ shift_op;\
- if(REG_POS(i,12)==15)\
- {\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- return a;
-
-#define OP_EORS(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] ^ shift_op;\
- if(REG_POS(i,12)==15)\
- {\
- Status_Reg SPSR = cpu->SPSR;\
- armcpu_switchMode(cpu, SPSR.bits.mode);\
- cpu->CPSR=SPSR;\
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- cpu->CPSR.bits.C = c;\
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
- return a;
-
-static u32 FASTCALL OP_EOR_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OP_EOR(1, 3);
-}
-
-static u32 FASTCALL OP_EOR_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OP_EOR(2, 4);
-}
-
-static u32 FASTCALL OP_EOR_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OP_EOR(1, 3);
-}
-
-static u32 FASTCALL OP_EOR_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OP_EOR(2, 4);
-}
-
-static u32 FASTCALL OP_EOR_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OP_EOR(1, 3);
-}
-
-static u32 FASTCALL OP_EOR_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OP_EOR(2, 4);
-}
-
-static u32 FASTCALL OP_EOR_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OP_EOR(1, 3);
-}
-
-static u32 FASTCALL OP_EOR_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OP_EOR(2, 4);
-}
-
-static u32 FASTCALL OP_EOR_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OP_EOR(1, 3);
-}
-
-static u32 FASTCALL OP_EOR_S_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_IMM;
- OP_EORS(2, 4);
-}
-
-static u32 FASTCALL OP_EOR_S_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_REG;
- OP_EORS(3, 5);
-}
-
-static u32 FASTCALL OP_EOR_S_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_IMM;
- OP_EORS(2, 4);
-}
-
-static u32 FASTCALL OP_EOR_S_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_REG;
- OP_EORS(3, 5);
-}
-
-static u32 FASTCALL OP_EOR_S_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_IMM;
- OP_EORS(2, 4);
-}
-
-static u32 FASTCALL OP_EOR_S_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_REG;
- OP_EORS(3, 5);
-}
-
-static u32 FASTCALL OP_EOR_S_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_IMM;
- OP_EORS(2, 4);
-}
-
-static u32 FASTCALL OP_EOR_S_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_REG;
- OP_EORS(3, 5);
-}
-
-static u32 FASTCALL OP_EOR_S_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_IMM_VALUE;
- OP_EORS(2, 4);
-}
-
-//-------------SUB-------------------------------------
-
-#define OP_SUB(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] - shift_op;\
- if(REG_POS(i,12)==15)\
- {\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- return a;
-
-#define OPSUBS(a, b) cpu->R[REG_POS(i,12)] = v - shift_op;\
- if(REG_POS(i,12)==15)\
- {\
- Status_Reg SPSR = cpu->SPSR;\
- armcpu_switchMode(cpu, SPSR.bits.mode);\
- cpu->CPSR=SPSR;\
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
- cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\
- return a;
-
-static u32 FASTCALL OP_SUB_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OP_SUB(1, 3);
-}
-
-static u32 FASTCALL OP_SUB_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OP_SUB(2, 4);
-}
-
-static u32 FASTCALL OP_SUB_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OP_SUB(1, 3);
-}
-
-static u32 FASTCALL OP_SUB_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OP_SUB(2, 4);
-}
-
-static u32 FASTCALL OP_SUB_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OP_SUB(1, 3);
-}
-
-static u32 FASTCALL OP_SUB_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OP_SUB(2, 4);
-}
-
-static u32 FASTCALL OP_SUB_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OP_SUB(1, 3);
-}
-
-static u32 FASTCALL OP_SUB_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OP_SUB(2, 4);
-}
-
-static u32 FASTCALL OP_SUB_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OP_SUB(1, 3);
-}
-
-static u32 FASTCALL OP_SUB_S_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- LSL_IMM;
- OPSUBS(2, 4);
-}
-
-static u32 FASTCALL OP_SUB_S_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- LSL_REG;
- OPSUBS(3, 5);
-}
-
-static u32 FASTCALL OP_SUB_S_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- LSR_IMM;
- OPSUBS(2, 4);
-}
-
-static u32 FASTCALL OP_SUB_S_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- LSR_REG;
- OPSUBS(3, 5);
-}
-
-static u32 FASTCALL OP_SUB_S_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- ASR_IMM;
- OPSUBS(2, 4);
-}
-
-static u32 FASTCALL OP_SUB_S_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- ASR_REG;
- OPSUBS(3, 5);
-}
-
-static u32 FASTCALL OP_SUB_S_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- ROR_IMM;
- OPSUBS(2, 4);
-}
-
-static u32 FASTCALL OP_SUB_S_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- ROR_REG;
- OPSUBS(3, 5);
-}
-
-static u32 FASTCALL OP_SUB_S_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- IMM_VALUE;
- OPSUBS(2, 4);
-}
-
-//------------------RSB------------------------
-
-#define OP_RSB(a, b) cpu->R[REG_POS(i,12)] = shift_op - cpu->R[REG_POS(i,16)];\
- if(REG_POS(i,12)==15)\
- {\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- return a;
-
-#define OP_RSBS(a, b) cpu->R[REG_POS(i,12)] = shift_op - v;\
- if(REG_POS(i,12)==15)\
- {\
- Status_Reg SPSR = cpu->SPSR;\
- armcpu_switchMode(cpu, SPSR.bits.mode);\
- cpu->CPSR=SPSR;\
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
- cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(shift_op, v, cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(shift_op, v, cpu->R[REG_POS(i,12)]);\
- return a;
-
-static u32 FASTCALL OP_RSB_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OP_RSB(1, 3);
-}
-
-static u32 FASTCALL OP_RSB_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OP_RSB(2, 4);
-}
-
-static u32 FASTCALL OP_RSB_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OP_RSB(1, 3);
-}
-
-static u32 FASTCALL OP_RSB_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OP_RSB(2, 4);
-}
-
-static u32 FASTCALL OP_RSB_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OP_RSB(1, 3);
-}
-
-static u32 FASTCALL OP_RSB_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OP_RSB(2, 4);
-}
-
-static u32 FASTCALL OP_RSB_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OP_RSB(1, 3);
-}
-
-static u32 FASTCALL OP_RSB_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OP_RSB(2, 4);
-}
-
-static u32 FASTCALL OP_RSB_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OP_RSB(1, 3);
-}
-
-static u32 FASTCALL OP_RSB_S_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- LSL_IMM;
- OP_RSBS(2, 4);
-}
-
-static u32 FASTCALL OP_RSB_S_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- LSL_REG;
- OP_RSBS(3, 5);
-}
-
-static u32 FASTCALL OP_RSB_S_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- LSR_IMM;
- OP_RSBS(2, 4);
-}
-
-static u32 FASTCALL OP_RSB_S_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- LSR_REG;
- OP_RSBS(3, 5);
-}
-
-static u32 FASTCALL OP_RSB_S_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- ASR_IMM;
- OP_RSBS(2, 4);
-}
-
-static u32 FASTCALL OP_RSB_S_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- ASR_REG;
- OP_RSBS(3, 5);
-}
-
-static u32 FASTCALL OP_RSB_S_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- ROR_IMM;
- OP_RSBS(2, 4);
-}
-
-static u32 FASTCALL OP_RSB_S_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- ROR_REG;
- OP_RSBS(3, 5);
-}
-
-static u32 FASTCALL OP_RSB_S_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- IMM_VALUE;
- OP_RSBS(2, 4);
-}
-
-//------------------ADD-----------------------------------
-
-#define OP_ADD(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] + shift_op;\
- if(REG_POS(i,12)==15)\
- {\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- return a;
-
-static u32 FASTCALL OP_ADD_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OP_ADD(1, 3);
-}
-
-static u32 FASTCALL OP_ADD_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OP_ADD(2, 4);
-}
-
-static u32 FASTCALL OP_ADD_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OP_ADD(1, 3);
-}
-
-static u32 FASTCALL OP_ADD_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OP_ADD(2, 4);
-}
-
-static u32 FASTCALL OP_ADD_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OP_ADD(1, 3);
-}
-
-static u32 FASTCALL OP_ADD_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OP_ADD(2, 4);
-}
-
-static u32 FASTCALL OP_ADD_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OP_ADD(1, 3);
-}
-
-static u32 FASTCALL OP_ADD_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OP_ADD(2, 4);
-}
-
-static u32 FASTCALL OP_ADD_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OP_ADD(1, 3);
-}
-
-#define OP_ADDS(a, b) cpu->R[REG_POS(i,12)] = v + shift_op;\
- if(REG_POS(i,12)==15)\
- {\
- Status_Reg SPSR = cpu->SPSR;\
- armcpu_switchMode(cpu, SPSR.bits.mode);\
- cpu->CPSR=SPSR;\
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
- cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.V = SIGNED_OVERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\
- return a;
-
-static u32 FASTCALL OP_ADD_S_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- LSL_IMM;
- OP_ADDS(2, 4);
-}
-
-static u32 FASTCALL OP_ADD_S_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- LSL_REG;
- OP_ADDS(3, 5);
-}
-
-static u32 FASTCALL OP_ADD_S_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- LSR_IMM;
- OP_ADDS(2, 4);
-}
-
-static u32 FASTCALL OP_ADD_S_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- LSR_REG;
- OP_ADDS(3, 5);
-}
-
-static u32 FASTCALL OP_ADD_S_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- ASR_IMM;
- OP_ADDS(2, 4);
-}
-
-static u32 FASTCALL OP_ADD_S_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- ASR_REG;
- OP_ADDS(3, 5);
-}
-
-static u32 FASTCALL OP_ADD_S_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- ROR_IMM;
- OP_ADDS(2, 4);
-}
-
-static u32 FASTCALL OP_ADD_S_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- ROR_REG;
- OP_ADDS(3, 5);
-}
-
-static u32 FASTCALL OP_ADD_S_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- IMM_VALUE;
- OP_ADDS(2, 4);
-}
-
-//------------------ADC-----------------------------------
-
-#define OP_ADC(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] + shift_op + cpu->CPSR.bits.C;\
- if(REG_POS(i,12)==15)\
- {\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- return a;
-
-static u32 FASTCALL OP_ADC_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OP_ADC(1, 3);
-}
-
-static u32 FASTCALL OP_ADC_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OP_ADC(2, 4);
-}
-
-static u32 FASTCALL OP_ADC_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OP_ADC(1, 3);
-}
-
-static u32 FASTCALL OP_ADC_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OP_ADC(2, 4);
-}
-
-static u32 FASTCALL OP_ADC_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OP_ADC(1, 3);
-}
-
-static u32 FASTCALL OP_ADC_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OP_ADC(2, 4);
-}
-
-static u32 FASTCALL OP_ADC_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OP_ADC(1, 3);
-}
-
-static u32 FASTCALL OP_ADC_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OP_ADC(2, 4);
-}
-
-static u32 FASTCALL OP_ADC_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OP_ADC(1, 3);
-}
-
-#define OP_ADCS(a, b) \
- { \
- u32 tmp = shift_op + cpu->CPSR.bits.C;\
- cpu->R[REG_POS(i,12)] = v + tmp;\
- if(REG_POS(i,12)==15)\
- {\
- Status_Reg SPSR = cpu->SPSR;\
- armcpu_switchMode(cpu, SPSR.bits.mode);\
- cpu->CPSR=SPSR;\
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
- cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(shift_op, cpu->CPSR.bits.C, tmp) | UNSIGNED_OVERFLOW(v, tmp, cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.V = SIGNED_OVERFLOW(shift_op, cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(v, tmp, cpu->R[REG_POS(i,12)]);\
- return a; \
- }
-
-static u32 FASTCALL OP_ADC_S_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- LSL_IMM;
- OP_ADCS(2, 4);
-}
-
-static u32 FASTCALL OP_ADC_S_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- LSL_REG;
- OP_ADCS(3, 5);
-}
-
-static u32 FASTCALL OP_ADC_S_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- LSR_IMM;
- OP_ADCS(2, 4);
-}
-
-static u32 FASTCALL OP_ADC_S_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- LSR_REG;
- OP_ADCS(3, 5);
-}
-
-static u32 FASTCALL OP_ADC_S_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- ASR_IMM;
- OP_ADCS(2, 4);
-}
-
-static u32 FASTCALL OP_ADC_S_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- ASR_REG;
- OP_ADCS(3, 5);
-}
-
-static u32 FASTCALL OP_ADC_S_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- ROR_IMM;
- OP_ADCS(2, 4);
-}
-
-static u32 FASTCALL OP_ADC_S_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- ROR_REG;
- OP_ADCS(3, 5);
-}
-
-static u32 FASTCALL OP_ADC_S_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- IMM_VALUE;
- OP_ADCS(2, 4);
-}
-
-//-------------SBC-------------------------------------
-
-#define OP_SBC(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] - shift_op - (!cpu->CPSR.bits.C);\
- if(REG_POS(i,12)==15)\
- {\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- return a;
-
-static u32 FASTCALL OP_SBC_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OP_SBC(1, 3);
-}
-
-static u32 FASTCALL OP_SBC_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OP_SBC(2, 4);
-}
-
-static u32 FASTCALL OP_SBC_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OP_SBC(1, 3);
-}
-
-static u32 FASTCALL OP_SBC_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OP_SBC(2, 4);
-}
-
-static u32 FASTCALL OP_SBC_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OP_SBC(1, 3);
-}
-
-static u32 FASTCALL OP_SBC_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OP_SBC(2, 4);
-}
-
-static u32 FASTCALL OP_SBC_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OP_SBC(1, 3);
-}
-
-static u32 FASTCALL OP_SBC_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OP_SBC(2, 4);
-}
-
-static u32 FASTCALL OP_SBC_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OP_SBC(1, 3);
-}
-
-#define OP_SBCS(a, b) \
- { \
- u32 tmp = v - (!cpu->CPSR.bits.C);\
- cpu->R[REG_POS(i,12)] = tmp - shift_op;\
- if(REG_POS(i,12)==15)\
- {\
- Status_Reg SPSR = cpu->SPSR;\
- armcpu_switchMode(cpu, SPSR.bits.mode);\
- cpu->CPSR=SPSR;\
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
- cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(v, (!cpu->CPSR.bits.C), tmp)) & (!UNSIGNED_UNDERFLOW(tmp, shift_op, cpu->R[REG_POS(i,12)]));\
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(v, (!cpu->CPSR.bits.C), tmp) | SIGNED_UNDERFLOW(tmp, shift_op, cpu->R[REG_POS(i,12)]);\
- return a; \
- }
-
-static u32 FASTCALL OP_SBC_S_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- LSL_IMM;
- OP_SBCS(2, 4);
-}
-
-static u32 FASTCALL OP_SBC_S_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- LSL_REG;
- OP_SBCS(3, 5);
-}
-
-static u32 FASTCALL OP_SBC_S_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- LSR_IMM;
- OP_SBCS(2, 4);
-}
-
-static u32 FASTCALL OP_SBC_S_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- LSR_REG;
- OP_SBCS(3, 5);
-}
-
-static u32 FASTCALL OP_SBC_S_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- ASR_IMM;
- OP_SBCS(2, 4);
-}
-
-static u32 FASTCALL OP_SBC_S_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- ASR_REG;
- OP_SBCS(3, 5);
-}
-
-static u32 FASTCALL OP_SBC_S_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- ROR_IMM;
- OP_SBCS(2, 4);
-}
-
-static u32 FASTCALL OP_SBC_S_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- ROR_REG;
- OP_SBCS(3, 5);
-}
-
-static u32 FASTCALL OP_SBC_S_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- IMM_VALUE;
- OP_SBCS(2, 4);
-}
-
-//---------------RSC----------------------------------
-
-#define OP_RSC(a, b) cpu->R[REG_POS(i,12)] = shift_op - cpu->R[REG_POS(i,16)] - (!cpu->CPSR.bits.C);\
- if(REG_POS(i,12)==15)\
- {\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- return a;
-
-static u32 FASTCALL OP_RSC_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OP_RSC(1, 3);
-}
-
-static u32 FASTCALL OP_RSC_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OP_RSC(2, 4);
-}
-
-static u32 FASTCALL OP_RSC_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OP_RSC(1, 3);
-}
-
-static u32 FASTCALL OP_RSC_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OP_RSC(2, 4);
-}
-
-static u32 FASTCALL OP_RSC_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OP_RSC(1, 3);
-}
-
-static u32 FASTCALL OP_RSC_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OP_RSC(2, 4);
-}
-
-static u32 FASTCALL OP_RSC_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OP_RSC(1, 3);
-}
-
-static u32 FASTCALL OP_RSC_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OP_RSC(2, 4);
-}
-
-static u32 FASTCALL OP_RSC_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OP_RSC(1, 3);
-}
-
-#define OP_RSCS(a,b) \
- { \
- u32 tmp = shift_op - (!cpu->CPSR.bits.C);\
- cpu->R[REG_POS(i,12)] = tmp - v;\
- if(REG_POS(i,12)==15)\
- {\
- Status_Reg SPSR = cpu->SPSR;\
- armcpu_switchMode(cpu, SPSR.bits.mode);\
- cpu->CPSR=SPSR;\
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
- cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(shift_op, (!cpu->CPSR.bits.C), tmp)) & (!UNSIGNED_UNDERFLOW(tmp, v, cpu->R[REG_POS(i,12)]));\
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(shift_op, (!cpu->CPSR.bits.C), tmp) | SIGNED_UNDERFLOW(tmp, v, cpu->R[REG_POS(i,12)]);\
- return a; \
- }
-
-static u32 FASTCALL OP_RSC_S_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- LSL_IMM;
- OP_RSCS(2,4);
-}
-
-static u32 FASTCALL OP_RSC_S_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- LSL_REG;
- OP_RSCS(3,5);
-}
-
-static u32 FASTCALL OP_RSC_S_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- LSR_IMM;
- OP_RSCS(2,4);
-}
-
-static u32 FASTCALL OP_RSC_S_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- LSR_REG;
- OP_RSCS(3,5);
-}
-
-static u32 FASTCALL OP_RSC_S_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- ASR_IMM;
- OP_RSCS(2,4);
-}
-
-static u32 FASTCALL OP_RSC_S_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- ASR_REG;
- OP_RSCS(3,5);
-}
-
-static u32 FASTCALL OP_RSC_S_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- u32 shift_op;
- ROR_IMM;
- OP_RSCS(2,4);
-}
-
-static u32 FASTCALL OP_RSC_S_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- ROR_REG;
- OP_RSCS(3,5);
-}
-
-static u32 FASTCALL OP_RSC_S_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,16)];
- IMM_VALUE;
- OP_RSCS(2,4);
-}
-
-//-------------------TST----------------------------
-
-#define OP_TST(a) \
- { \
- unsigned tmp = cpu->R[REG_POS(i,16)] & shift_op;\
- cpu->CPSR.bits.C = c;\
- cpu->CPSR.bits.N = BIT31(tmp);\
- cpu->CPSR.bits.Z = (tmp==0);\
- return a; \
- }
-
-static u32 FASTCALL OP_TST_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_IMM;
- OP_TST(1);
-}
-
-static u32 FASTCALL OP_TST_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_REG;
- OP_TST(2);
-}
-
-static u32 FASTCALL OP_TST_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_IMM;
- OP_TST(1);
-}
-
-static u32 FASTCALL OP_TST_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_REG;
- OP_TST(2);
-}
-
-static u32 FASTCALL OP_TST_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_IMM;
- OP_TST(1);
-}
-
-static u32 FASTCALL OP_TST_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_REG;
- OP_TST(2);
-}
-
-static u32 FASTCALL OP_TST_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_IMM;
- OP_TST(1);
-}
-
-static u32 FASTCALL OP_TST_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_REG;
- OP_TST(2);
-}
-
-static u32 FASTCALL OP_TST_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_IMM_VALUE;
- OP_TST(1);
-}
-
-//-------------------TEQ----------------------------
-
-#define OP_TEQ(a) \
- { \
- unsigned tmp = cpu->R[REG_POS(i,16)] ^ shift_op;\
- cpu->CPSR.bits.C = c;\
- cpu->CPSR.bits.N = BIT31(tmp);\
- cpu->CPSR.bits.Z = (tmp==0);\
- return a; \
- }
-
-static u32 FASTCALL OP_TEQ_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_IMM;
- OP_TEQ(1);
-}
-
-static u32 FASTCALL OP_TEQ_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_REG;
- OP_TEQ(2);
-}
-
-static u32 FASTCALL OP_TEQ_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_IMM;
- OP_TEQ(1);
-}
-
-static u32 FASTCALL OP_TEQ_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_REG;
- OP_TEQ(2);
-}
-
-static u32 FASTCALL OP_TEQ_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_IMM;
- OP_TEQ(1);
-}
-
-static u32 FASTCALL OP_TEQ_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_REG;
- OP_TEQ(2);
-}
-
-static u32 FASTCALL OP_TEQ_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_IMM;
- OP_TEQ(1);
-}
-
-static u32 FASTCALL OP_TEQ_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_REG;
- OP_TEQ(2);
-}
-
-static u32 FASTCALL OP_TEQ_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_IMM_VALUE;
- OP_TEQ(1);
-}
-
-//-------------CMP-------------------------------------
-
-#define OP_CMP(a) \
- { \
- u32 tmp = cpu->R[REG_POS(i,16)] - shift_op;\
- cpu->CPSR.bits.N = BIT31(tmp);\
- cpu->CPSR.bits.Z = (tmp==0);\
- cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\
- return a; \
- }
-
-static u32 FASTCALL OP_CMP_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OP_CMP(1);
-}
-
-static u32 FASTCALL OP_CMP_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OP_CMP(2);
-}
-
-static u32 FASTCALL OP_CMP_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OP_CMP(1);
-}
-
-static u32 FASTCALL OP_CMP_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OP_CMP(2);
-}
-
-static u32 FASTCALL OP_CMP_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OP_CMP(1);
-}
-
-static u32 FASTCALL OP_CMP_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OP_CMP(2);
-}
-
-static u32 FASTCALL OP_CMP_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OP_CMP(1);
-}
-
-static u32 FASTCALL OP_CMP_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OP_CMP(2);
-}
-
-static u32 FASTCALL OP_CMP_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OP_CMP(1);
-}
-
-//---------------CMN---------------------------
-
-#define OP_CMN(a) \
- { \
- u32 tmp = cpu->R[REG_POS(i,16)] + shift_op;\
- cpu->CPSR.bits.N = BIT31(tmp);\
- cpu->CPSR.bits.Z = (tmp==0);\
- cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\
- cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\
- return a; \
- }
-
-static u32 FASTCALL OP_CMN_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OP_CMN(1);
-}
-
-static u32 FASTCALL OP_CMN_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OP_CMN(2);
-}
-
-static u32 FASTCALL OP_CMN_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OP_CMN(1);
-}
-
-static u32 FASTCALL OP_CMN_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OP_CMN(2);
-}
-
-static u32 FASTCALL OP_CMN_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OP_CMN(1);
-}
-
-static u32 FASTCALL OP_CMN_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OP_CMN(2);
-}
-
-static u32 FASTCALL OP_CMN_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OP_CMN(1);
-}
-
-static u32 FASTCALL OP_CMN_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OP_CMN(2);
-}
-
-static u32 FASTCALL OP_CMN_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OP_CMN(1);
-}
-
-//------------------ORR-------------------
-
-#define OP_ORR(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;\
- if(REG_POS(i,12)==15)\
- {\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- return a;
-
-static u32 FASTCALL OP_ORR_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OP_ORR(1, 3);
-}
-
-static u32 FASTCALL OP_ORR_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OP_ORR(2, 4);
-}
-
-static u32 FASTCALL OP_ORR_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OP_ORR(1, 3);
-}
-
-static u32 FASTCALL OP_ORR_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OP_ORR(2, 4);
-}
-
-static u32 FASTCALL OP_ORR_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OP_ORR(1, 3);
-}
-
-static u32 FASTCALL OP_ORR_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OP_ORR(2, 4);
-}
-
-static u32 FASTCALL OP_ORR_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OP_ORR(1, 3);
-}
-
-static u32 FASTCALL OP_ORR_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OP_ORR(2, 4);
-}
-
-static u32 FASTCALL OP_ORR_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OP_ORR(1, 3);
-}
-
-static u32 FASTCALL OP_ORR_S_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_IMM;
- cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
- if(REG_POS(i,12)==15)
- {
- Status_Reg SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
- cpu->next_instruction = cpu->R[15];
- return 4;
- }
- cpu->CPSR.bits.C = c;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
- return 2;
-}
-
-static u32 FASTCALL OP_ORR_S_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_REG;
- cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
- if(REG_POS(i,12)==15)
- {
- Status_Reg SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
- cpu->next_instruction = cpu->R[15];
- return 5;
- }
- cpu->CPSR.bits.C = c;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
- return 3;
-}
-
-static u32 FASTCALL OP_ORR_S_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_IMM;
- cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
- if(REG_POS(i,12)==15)
- {
- Status_Reg SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
- cpu->next_instruction = cpu->R[15];
- return 4;
- }
- cpu->CPSR.bits.C = c;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
- return 2;
-}
-
-static u32 FASTCALL OP_ORR_S_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_REG;
- cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
- if(REG_POS(i,12)==15)
- {
- Status_Reg SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
- cpu->next_instruction = cpu->R[15];
- return 5;
- }
- cpu->CPSR.bits.C = c;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
- return 3;
-}
-
-static u32 FASTCALL OP_ORR_S_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_IMM;
- cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
- if(REG_POS(i,12)==15)
- {
- Status_Reg SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
- cpu->next_instruction = cpu->R[15];
- return 4;
- }
- cpu->CPSR.bits.C = c;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
- return 2;
-}
-
-static u32 FASTCALL OP_ORR_S_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_REG;
- cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
- if(REG_POS(i,12)==15)
- {
- Status_Reg SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
- cpu->next_instruction = cpu->R[15];
- return 5;
- }
- cpu->CPSR.bits.C = c;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
- return 3;
-}
-
-static u32 FASTCALL OP_ORR_S_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_IMM;
- cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
- if(REG_POS(i,12)==15)
- {
- Status_Reg SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
- cpu->next_instruction = cpu->R[15];
- return 4;
- }
- cpu->CPSR.bits.C = c;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
- return 2;
-}
-
-static u32 FASTCALL OP_ORR_S_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_REG;
- cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
- if(REG_POS(i,12)==15)
- {
- Status_Reg SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
- cpu->next_instruction = cpu->R[15];
- return 5;
- }
- cpu->CPSR.bits.C = c;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
- return 3;
-}
-
-static u32 FASTCALL OP_ORR_S_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_IMM_VALUE;
- cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
- if(REG_POS(i,12)==15)
- {
- Status_Reg SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
- cpu->next_instruction = cpu->R[15];
- return 4;
- }
- cpu->CPSR.bits.C = c;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
- return 2;
-}
-
-//------------------MOV-------------------
-
-#define OP_MOV(a, b) cpu->R[REG_POS(i,12)] = shift_op;\
- if(REG_POS(i,12)==15)\
- {\
- cpu->next_instruction = shift_op;\
- return b;\
- }\
- return a;
-
-#define OP_MOV_S(a, b) cpu->R[REG_POS(i,12)] = shift_op;\
- if(BIT20(i) && REG_POS(i,12)==15)\
- {\
- Status_Reg SPSR = cpu->SPSR;\
- armcpu_switchMode(cpu, SPSR.bits.mode);\
- cpu->CPSR=SPSR;\
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- cpu->CPSR.bits.C = c;\
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
- return a;\
-
-static u32 FASTCALL OP_MOV_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OP_MOV(1,3);
-}
-
-static u32 FASTCALL OP_MOV_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- if (REG_POS(i,0) == 15) shift_op += 4;
- OP_MOV(2,4);
-}
-
-static u32 FASTCALL OP_MOV_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OP_MOV(1,3);
-}
-
-static u32 FASTCALL OP_MOV_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- if (REG_POS(i,0) == 15) shift_op += 4;
- OP_MOV(2,4);
-}
-
-static u32 FASTCALL OP_MOV_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OP_MOV(1,3);
-}
-
-static u32 FASTCALL OP_MOV_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OP_MOV(2,4);
-}
-
-static u32 FASTCALL OP_MOV_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OP_MOV(2,4);
-}
-
-static u32 FASTCALL OP_MOV_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OP_MOV(2,4);
-}
-
-static u32 FASTCALL OP_MOV_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OP_MOV(1,3);
-}
-
-static u32 FASTCALL OP_MOV_S_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_IMM;
- OP_MOV_S(2,4);
-}
-
-static u32 FASTCALL OP_MOV_S_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_REG;
- if (REG_POS(i,0) == 15) shift_op += 4;
- OP_MOV_S(3,5);
-}
-
-static u32 FASTCALL OP_MOV_S_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_IMM;
- OP_MOV_S(2,4);
-}
-
-static u32 FASTCALL OP_MOV_S_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_REG;
- if (REG_POS(i,0) == 15) shift_op += 4;
- OP_MOV_S(3,5);
-}
-
-static u32 FASTCALL OP_MOV_S_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_IMM;
- OP_MOV_S(2,4);
-}
-
-static u32 FASTCALL OP_MOV_S_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_REG;
- OP_MOV_S(3,5);
-}
-
-static u32 FASTCALL OP_MOV_S_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_IMM;
- OP_MOV_S(2,4);
-}
-
-static u32 FASTCALL OP_MOV_S_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_REG;
- OP_MOV_S(3,5);
-}
-
-static u32 FASTCALL OP_MOV_S_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_IMM_VALUE;
- OP_MOV_S(2,4);
-}
-
-//------------------BIC-------------------
-#define OPP_BIC(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & (~shift_op);\
- if(REG_POS(i,12)==15)\
- {\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- return a;
-
-#define OPP_BIC_S(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & (~shift_op);\
- if(REG_POS(i,12)==15)\
- {\
- Status_Reg SPSR = cpu->SPSR;\
- armcpu_switchMode(cpu, SPSR.bits.mode);\
- cpu->CPSR=SPSR;\
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- cpu->CPSR.bits.C = c;\
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
- return a;
-
-static u32 FASTCALL OP_BIC_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OPP_BIC(1,3);
-}
-
-static u32 FASTCALL OP_BIC_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OPP_BIC(2,4);
-}
-
-static u32 FASTCALL OP_BIC_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OPP_BIC(1,3);
-}
-
-static u32 FASTCALL OP_BIC_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OPP_BIC(2,4);
-}
-
-static u32 FASTCALL OP_BIC_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OPP_BIC(1,3);
-}
-
-static u32 FASTCALL OP_BIC_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OPP_BIC(2,4);
-}
-
-static u32 FASTCALL OP_BIC_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OPP_BIC(1,3);
-}
-
-static u32 FASTCALL OP_BIC_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OPP_BIC(2,4);
-}
-
-static u32 FASTCALL OP_BIC_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OPP_BIC(1,3);
-}
-
-static u32 FASTCALL OP_BIC_S_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_IMM;
- OPP_BIC_S(2,4);
-}
-
-static u32 FASTCALL OP_BIC_S_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_REG;
- OPP_BIC_S(3,5);
-}
-
-static u32 FASTCALL OP_BIC_S_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_IMM;
- OPP_BIC_S(2,4);
-}
-
-static u32 FASTCALL OP_BIC_S_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_REG;
- OPP_BIC_S(3,5);
-}
-
-static u32 FASTCALL OP_BIC_S_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_IMM;
- OPP_BIC_S(2,4);
-}
-
-static u32 FASTCALL OP_BIC_S_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_REG;
- OPP_BIC_S(3,5);
-}
-
-static u32 FASTCALL OP_BIC_S_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_IMM;
- OPP_BIC_S(2,4);
-}
-
-static u32 FASTCALL OP_BIC_S_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_REG;
- OPP_BIC_S(3,5);
-}
-
-static u32 FASTCALL OP_BIC_S_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_IMM_VALUE;
- OPP_BIC_S(2,4);
-}
-
-//------------------MVN-------------------
-#define OPP_MVN(a, b) cpu->R[REG_POS(i,12)] = ~shift_op;\
- if(REG_POS(i,12)==15)\
- {\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- return a;
-
-#define OPP_MVN_S(a, b) cpu->R[REG_POS(i,12)] = ~shift_op;\
- if(REG_POS(i,12)==15)\
- {\
- Status_Reg SPSR = cpu->SPSR;\
- armcpu_switchMode(cpu, SPSR.bits.mode);\
- cpu->CPSR=SPSR;\
- cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
- cpu->next_instruction = cpu->R[15];\
- return b;\
- }\
- cpu->CPSR.bits.C = c;\
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
- return a;
-
-static u32 FASTCALL OP_MVN_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSL_IMM;
- OPP_MVN(1,3);
-}
-
-static u32 FASTCALL OP_MVN_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSL_REG;
- OPP_MVN(2,4);
-}
-
-static u32 FASTCALL OP_MVN_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- LSR_IMM;
- OPP_MVN(1,3);
-}
-
-static u32 FASTCALL OP_MVN_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- LSR_REG;
- OPP_MVN(2,4);
-}
-
-static u32 FASTCALL OP_MVN_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ASR_IMM;
- OPP_MVN(1,3);
-}
-
-static u32 FASTCALL OP_MVN_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ASR_REG;
- OPP_MVN(2,4);
-}
-
-static u32 FASTCALL OP_MVN_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 shift_op;
- ROR_IMM;
- OPP_MVN(1,3);
-}
-
-static u32 FASTCALL OP_MVN_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- ROR_REG;
- OPP_MVN(2,4);
-}
-
-static u32 FASTCALL OP_MVN_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
- OPP_MVN(1,3);
-}
-
-static u32 FASTCALL OP_MVN_S_LSL_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_IMM;
- OPP_MVN_S(2,4);
-}
-
-static u32 FASTCALL OP_MVN_S_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSL_REG;
- OPP_MVN_S(3,5);
-}
-
-static u32 FASTCALL OP_MVN_S_LSR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_IMM;
- OPP_MVN_S(2,4);
-}
-
-static u32 FASTCALL OP_MVN_S_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_LSR_REG;
- OPP_MVN_S(3,5);
-}
-
-static u32 FASTCALL OP_MVN_S_ASR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_IMM;
- OPP_MVN_S(2,4);
-}
-
-static u32 FASTCALL OP_MVN_S_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ASR_REG;
- OPP_MVN_S(3,5);
-}
-
-static u32 FASTCALL OP_MVN_S_ROR_IMM(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_IMM;
- OPP_MVN_S(2,4);
-}
-
-static u32 FASTCALL OP_MVN_S_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_ROR_REG;
- OPP_MVN_S(3,5);
-}
-
-static u32 FASTCALL OP_MVN_S_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- S_IMM_VALUE;
- OPP_MVN_S(2,4);
-}
-
-//-------------MUL------------------------
-#define OPP_M(a,b) v >>= 8;\
- if((v==0)||(v==0xFFFFFF))\
- return b;\
- v >>= 8;\
- if((v==0)||(v==0xFFFF))\
- return b+1;\
- v >>= 8;\
- if((v==0)||(v==0xFF))\
- return b+2;\
- return a;\
-
-static u32 FASTCALL OP_MUL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,16)] = cpu->R[REG_POS(i,8)] * v;
- OPP_M(5,2);
-}
-
-static u32 FASTCALL OP_MLA(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,0)];
- u32 a = cpu->R[REG_POS(i,8)];
- u32 b = cpu->R[REG_POS(i,12)];
- cpu->R[REG_POS(i,16)] = a * v + b;
-
- OPP_M(6,3);
-}
-
-static u32 FASTCALL OP_MUL_S(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,16)] = cpu->R[REG_POS(i,8)] * v;
-
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0);
-
- OPP_M(6,3);
-}
-
-static u32 FASTCALL OP_MLA_S(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,16)] = cpu->R[REG_POS(i,8)] * v + cpu->R[REG_POS(i,12)];
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0);
- OPP_M(7,4);
-}
-
-//----------UMUL--------------------------
-
-static u32 FASTCALL OP_UMULL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,0)];
- u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)];
-
- cpu->R[REG_POS(i,12)] = (u32)res;
- cpu->R[REG_POS(i,16)] = (u32)(res>>32);
-
- OPP_M(6,3);
-}
-
-static u32 FASTCALL OP_UMLAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,0)];
- u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)] + (u64)cpu->R[REG_POS(i,12)];
-
- cpu->R[REG_POS(i,12)] = (u32)res;
- cpu->R[REG_POS(i,16)] += (u32)(res>>32);
-
- OPP_M(7,4);
-}
-
-static u32 FASTCALL OP_UMULL_S(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,0)];
- u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)];
-
- cpu->R[REG_POS(i,12)] = (u32)res;
- cpu->R[REG_POS(i,16)] = (u32)(res>>32);
-
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0);
-
- OPP_M(7,4);
-}
-
-static u32 FASTCALL OP_UMLAL_S(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_POS(i,0)];
- u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)] + (u64)cpu->R[REG_POS(i,12)];
-
- cpu->R[REG_POS(i,12)] = (u32)res;
- cpu->R[REG_POS(i,16)] += (u32)(res>>32);
-
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0);
-
- OPP_M(8,5);
-}
-
-//----------SMUL--------------------------
-
-static u32 FASTCALL OP_SMULL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- s64 v = (s32)cpu->R[REG_POS(i,0)];
- s64 b = (s32)cpu->R[REG_POS(i,8)];
- s64 res = v * b;
-
- cpu->R[REG_POS(i,12)] = (u32)(res&0xFFFFFFFF);
- cpu->R[REG_POS(i,16)] = (u32)(res>>32);
-
- v &= 0xFFFFFFFF;
-
- OPP_M(6,3);
-}
-
-static u32 FASTCALL OP_SMLAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
-
- s64 v = (s32)cpu->R[REG_POS(i,0)];
- s64 b = (s32)cpu->R[REG_POS(i,8)];
- s64 res = v * b + (u64)cpu->R[REG_POS(i,12)];
-
- //LOG("%08X * %08X + %08X%08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], cpu->R[REG_POS(i,16)], cpu->R[REG_POS(i,12)]);
-
- cpu->R[REG_POS(i,12)] = (u32)res;
- cpu->R[REG_POS(i,16)] += (u32)(res>>32);
-
- //LOG("= %08X%08X %08X%08X\r\n", cpu->R[REG_POS(i,16)], cpu->R[REG_POS(i,12)], res);
-
- v &= 0xFFFFFFFF;
-
- OPP_M(7,4);
-}
-
-static u32 FASTCALL OP_SMULL_S(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- s64 v = (s32)cpu->R[REG_POS(i,0)];
- s64 b = (s32)cpu->R[REG_POS(i,8)];
- s64 res = v * b;
-
- cpu->R[REG_POS(i,12)] = (u32)res;
- cpu->R[REG_POS(i,16)] = (u32)(res>>32);
-
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0);
-
- v &= 0xFFFFFFFF;
-
- OPP_M(7,4);
-}
-
-static u32 FASTCALL OP_SMLAL_S(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- s64 v = (s32)cpu->R[REG_POS(i,0)];
- s64 b = (s32)cpu->R[REG_POS(i,8)];
- s64 res = v * b + (u64)cpu->R[REG_POS(i,12)];
-
- cpu->R[REG_POS(i,12)] = (u32)res;
- cpu->R[REG_POS(i,16)] += (u32)(res>>32);
-
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]);
- cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0);
-
- v &= 0xFFFFFFFF;
-
- OPP_M(8,5);
-}
-
-//---------------SWP------------------------------
-
-static u32 FASTCALL OP_SWP(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- u32 tmp = ROR(READ32(cpu->mem_if->data, adr), ((cpu->R[REG_POS(i,16)]&3)<<3));
-
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,0)]);
- cpu->R[REG_POS(i,12)] = tmp;
-
- return 4 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]*2;
-}
-
-static u32 FASTCALL OP_SWPB(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- u8 tmp = READ8(cpu->mem_if->data, adr);
- WRITE8(cpu->mem_if->data, adr, (u8)(cpu->R[REG_POS(i,0)]&0xFF));
- cpu->R[REG_POS(i,12)] = tmp;
-
- return 4 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]*2;
-}
-
-//------------LDRH-----------------------------
-
-static u32 FASTCALL OP_LDRH_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
- cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
- cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_P_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_M_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_PRE_INDE_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_PRE_INDE_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
-
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_PRE_INDE_P_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] =(u32)READ16(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_PRE_INDE_M_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_POS_INDE_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] += IMM_OFF;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_POS_INDE_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] -= IMM_OFF;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_POS_INDE_P_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)];
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_POS_INDE_M_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)];
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-//------------STRH-----------------------------
-
-static u32 FASTCALL OP_STRH_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_P_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_M_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_PRE_INDE_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
- cpu->R[REG_POS(i,16)] = adr;
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_PRE_INDE_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_PRE_INDE_P_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_PRE_INDE_M_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_POS_INDE_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] += IMM_OFF;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_POS_INDE_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] -= IMM_OFF;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_POS_INDE_P_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)];
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_POS_INDE_M_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)];
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-//----------------LDRSH--------------------------
-
-static u32 FASTCALL OP_LDRSH_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
- cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSH_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
- cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSH_P_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSH_M_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSH_PRE_INDE_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
- cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] = adr;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSH_PRE_INDE_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
- cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] = adr;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSH_PRE_INDE_P_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] = adr;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSH_PRE_INDE_M_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] = adr;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSH_POS_INDE_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] += IMM_OFF;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSH_POS_INDE_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] -= IMM_OFF;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSH_POS_INDE_P_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)];
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSH_POS_INDE_M_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)];
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-//----------------------LDRSB----------------------
-
-static u32 FASTCALL OP_LDRSB_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
- cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSB_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
- cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSB_P_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSB_M_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSB_PRE_INDE_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
- cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] = adr;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSB_PRE_INDE_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
- cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] = adr;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSB_PRE_INDE_P_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] = adr;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSB_PRE_INDE_M_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
- cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] = adr;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSB_POS_INDE_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] += IMM_OFF;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSB_POS_INDE_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] -= IMM_OFF;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSB_POS_INDE_P_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)];
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSB_POS_INDE_M_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
- cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)];
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-//--------------MRS--------------------------------
-
-static u32 FASTCALL OP_MRS_CPSR(armcpu_t *cpu)
-{
- cpu->R[REG_POS(cpu->instruction,12)] = cpu->CPSR.val;
-
- return 1;
-}
-
-static u32 FASTCALL OP_MRS_SPSR(armcpu_t *cpu)
-{
- cpu->R[REG_POS(cpu->instruction,12)] = cpu->SPSR.val;
-
- return 1;
-}
-
-//--------------MSR--------------------------------
-
-static u32 FASTCALL OP_MSR_CPSR(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 operand = cpu->R[REG_POS(i,0)];
-
- if(cpu->CPSR.bits.mode!=USR)
- {
- if(BIT16(i))
- {
- armcpu_switchMode(cpu, operand & 0x1F);
- cpu->CPSR.val = (cpu->CPSR.val & 0xFFFFFF00) | (operand & 0xFF);
- }
- if(BIT17(i))
- cpu->CPSR.val = (cpu->CPSR.val & 0xFFFF00FF) | (operand & 0xFF00);
- if(BIT18(i))
- cpu->CPSR.val = (cpu->CPSR.val & 0xFF00FFFF) | (operand & 0xFF0000);
- }
- if(BIT19(i))
- cpu->CPSR.val = (cpu->CPSR.val & 0x00FFFFFF) | (operand & 0xFF000000);
-
- return 1;
-}
-
-static u32 FASTCALL OP_MSR_SPSR(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 operand = cpu->R[REG_POS(i,0)];
-
- if(cpu->CPSR.bits.mode!=USR)
- {
- if(BIT16(i))
- {
- cpu->SPSR.val = (cpu->SPSR.val & 0xFFFFFF00) | (operand & 0XFF);
- }
- if(BIT17(i))
- cpu->SPSR.val = (cpu->SPSR.val & 0xFFFF00FF) | (operand & 0XFF00);
- if(BIT18(i))
- cpu->SPSR.val = (cpu->SPSR.val & 0xFF00FFFF) | (operand & 0XFF0000);
- }
- if(BIT19(i))
- cpu->SPSR.val = (cpu->SPSR.val & 0x00FFFFFF) | (operand & 0XFF000000);
-
- return 1;
-}
-
-static u32 FASTCALL OP_MSR_CPSR_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
-
- if(cpu->CPSR.bits.mode!=USR)
- {
- if(BIT16(i))
- {
- armcpu_switchMode(cpu, shift_op & 0x1F);
- cpu->CPSR.val = (cpu->CPSR.val & 0xFFFFFF00) | (shift_op & 0XFF);
- }
- if(BIT17(i))
- cpu->CPSR.val = (cpu->CPSR.val & 0xFFFF00FF) | (shift_op & 0XFF00);
- if(BIT18(i))
- cpu->CPSR.val = (cpu->CPSR.val & 0xFF00FFFF) | (shift_op & 0XFF0000);
- }
- if(BIT19(i))
- {
- //cpu->CPSR.val = (cpu->CPSR.val & 0xFF000000) | (shift_op & 0XFF000000);
- cpu->CPSR.val = (cpu->CPSR.val & 0x00FFFFFF) | (shift_op & 0xFF000000);
- }
-
- return 1;
-}
-
-static u32 FASTCALL OP_MSR_SPSR_IMM_VAL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- IMM_VALUE;
-
- if(cpu->CPSR.bits.mode!=USR)
- {
- if(BIT16(i))
- {
- cpu->SPSR.val = (cpu->SPSR.val & 0xFFFFFF00) | (shift_op & 0XFF);
- }
- if(BIT17(i))
- cpu->SPSR.val = (cpu->SPSR.val & 0xFFFF00FF) | (shift_op & 0XFF00);
- if(BIT18(i))
- cpu->SPSR.val = (cpu->SPSR.val & 0xFF00FFFF) | (shift_op & 0XFF0000);
- }
- if(BIT19(i))
- cpu->SPSR.val = (cpu->SPSR.val & 0xFF000000) | (shift_op & 0XFF000000);
-
- return 1;
-}
-
-//-----------------BRANCH--------------------------
-
-static u32 FASTCALL OP_BX(armcpu_t *cpu)
-{
- u32 tmp = cpu->R[REG_POS(cpu->instruction, 0)];
-
- cpu->CPSR.bits.T = BIT0(tmp);
- cpu->R[15] = tmp & 0xFFFFFFFE;
- cpu->next_instruction = cpu->R[15];
- return 3;
-}
-
-static u32 FASTCALL OP_BLX_REG(armcpu_t *cpu)
-{
- u32 tmp = cpu->R[REG_POS(cpu->instruction, 0)];
-
- cpu->R[14] = cpu->next_instruction;
- cpu->CPSR.bits.T = BIT0(tmp);
- cpu->R[15] = tmp & 0xFFFFFFFE;
- cpu->next_instruction = cpu->R[15];
- return 3;
-}
-
-#define SIGNEXTEND_24(i) (((s32)((i)<<8))>>8)
-
-static u32 FASTCALL OP_B(armcpu_t *cpu)
-{
- u32 off = SIGNEXTEND_24(cpu->instruction);
- if(CONDITION(cpu->instruction)==0xF)
- {
- cpu->R[14] = cpu->next_instruction;
- cpu->CPSR.bits.T = 1;
- }
- cpu->R[15] += (off<<2);
- cpu->next_instruction = cpu->R[15];
-
- return 3;
-}
-
-static u32 FASTCALL OP_BL(armcpu_t *cpu)
-{
- u32 off = SIGNEXTEND_24(cpu->instruction);
- if(CONDITION(cpu->instruction)==0xF)
- {
- cpu->CPSR.bits.T = 1;
- cpu->R[15] += 2;
- }
- cpu->R[14] = cpu->next_instruction;
- cpu->R[15] += (off<<2);
- cpu->next_instruction = cpu->R[15];
-
- return 3;
-}
-
-//----------------CLZ-------------------------------
-
-u8 CLZ_TAB[16]=
-{
- 0, // 0000
- 1, // 0001
- 2, 2, // 001X
- 3, 3, 3, 3, // 01XX
- 4, 4, 4, 4, 4, 4, 4, 4 // 1XXX
-};
-
-static u32 FASTCALL OP_CLZ(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 Rm = cpu->R[REG_POS(i,0)];
- u32 pos;
-
- if(Rm==0)
- {
- cpu->R[REG_POS(i,12)]=32;
- return 2;
- }
-
- Rm |= (Rm >>1);
- Rm |= (Rm >>2);
- Rm |= (Rm >>4);
- Rm |= (Rm >>8);
- Rm |= (Rm >>16);
-
- pos =
- CLZ_TAB[Rm&0xF] +
- CLZ_TAB[(Rm>>4)&0xF] +
- CLZ_TAB[(Rm>>8)&0xF] +
- CLZ_TAB[(Rm>>12)&0xF] +
- CLZ_TAB[(Rm>>16)&0xF] +
- CLZ_TAB[(Rm>>20)&0xF] +
- CLZ_TAB[(Rm>>24)&0xF] +
- CLZ_TAB[(Rm>>28)&0xF];
-
- cpu->R[REG_POS(i,12)]=32 - pos;
-
- return 2;
-}
-
-//--------------------QADD--QSUB------------------------------
-
-static u32 FASTCALL OP_QADD(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 res = cpu->R[REG_POS(i,16)]+cpu->R[REG_POS(i,0)];
-
- LOG("spe add\r\n");
- if(SIGNED_OVERFLOW(cpu->R[REG_POS(i,16)],cpu->R[REG_POS(i,0)], res))
- {
- cpu->CPSR.bits.Q=1;
- cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res);
- return 2;
- }
- cpu->R[REG_POS(i,12)]=res;
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] &= 0XFFFFFFFC;
- cpu->next_instruction = cpu->R[15];
- return 3;
- }
- return 2;
-}
-
-static u32 FASTCALL OP_QSUB(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 res = cpu->R[REG_POS(i,0)]-cpu->R[REG_POS(i,16)];
-
- LOG("spe add\r\n");
- if(SIGNED_UNDERFLOW(cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,16)], res))
- {
- cpu->CPSR.bits.Q=1;
- cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res);
- return 2;
- }
- cpu->R[REG_POS(i,12)]=res;
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] &= 0XFFFFFFFC;
- cpu->next_instruction = cpu->R[15];
- return 3;
- }
- return 2;
-}
-
-static u32 FASTCALL OP_QDADD(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 mul = cpu->R[REG_POS(i,16)]<<1;
- u32 res;
-
-
- LOG("spe add\r\n");
- if(BIT31(cpu->R[REG_POS(i,16)])!=BIT31(mul))
- {
- cpu->CPSR.bits.Q=1;
- mul = 0x80000000-BIT31(mul);
- }
-
- res = mul + cpu->R[REG_POS(i,0)];
- if(SIGNED_OVERFLOW(cpu->R[REG_POS(i,0)],mul, res))
- {
- cpu->CPSR.bits.Q=1;
- cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res);
- return 2;
- }
- cpu->R[REG_POS(i,12)]=res;
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] &= 0XFFFFFFFC;
- cpu->next_instruction = cpu->R[15];
- return 3;
- }
- return 2;
-}
-
-static u32 FASTCALL OP_QDSUB(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 mul = cpu->R[REG_POS(i,16)]<<1;
- u32 res;
-
-
- LOG("spe add\r\n");
- if(BIT31(cpu->R[REG_POS(i,16)])!=BIT31(mul))
- {
- cpu->CPSR.bits.Q=1;
- mul = 0x80000000-BIT31(mul);
- }
-
- res = cpu->R[REG_POS(i,0)] - mul;
- if(SIGNED_UNDERFLOW(cpu->R[REG_POS(i,0)], mul, res))
- {
- cpu->CPSR.bits.Q=1;
- cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res);
- return 2;
- }
- cpu->R[REG_POS(i,12)]=res;
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] &= 0XFFFFFFFC;
- cpu->next_instruction = cpu->R[15];
- return 3;
- }
- return 2;
-}
-
-//-----------------SMUL-------------------------------
-
-#define HWORD(i) ((s32)(((s32)(i))>>16))
-#define LWORD(i) (s32)(((s32)((i)<<16))>>16)
-
-static u32 FASTCALL OP_SMUL_B_B(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
-
- cpu->R[REG_POS(i,16)] = (u32)(LWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)]));
-
- return 2;
-}
-
-static u32 FASTCALL OP_SMUL_B_T(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
-
- cpu->R[REG_POS(i,16)] = (u32)(LWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)]));
-
- return 2;
-}
-
-static u32 FASTCALL OP_SMUL_T_B(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
-
- cpu->R[REG_POS(i,16)] = (u32)(HWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)]));
-
- return 2;
-}
-
-static u32 FASTCALL OP_SMUL_T_T(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
-
- cpu->R[REG_POS(i,16)] = (u32)(HWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)]));
-
- return 2;
-}
-
-//-----------SMLA----------------------------
-
-static u32 FASTCALL OP_SMLA_B_B(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 tmp = (u32)(LWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)]));
- u32 a = cpu->R[REG_POS(i,12)];
-
- //LOG("SMLABB %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a);
- cpu->R[REG_POS(i,16)] = tmp + a;
-
- if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)]))
- cpu->CPSR.bits.Q = 1;
-
- return 2;
-}
-
-static u32 FASTCALL OP_SMLA_B_T(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 tmp = (u32)(LWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)]));
- u32 a = cpu->R[REG_POS(i,12)];
-
- //LOG("SMLABT %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a);
- cpu->R[REG_POS(i,16)] = tmp + a;
-
- if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)]))
- cpu->CPSR.bits.Q = 1;
-
- return 2;
-}
-
-static u32 FASTCALL OP_SMLA_T_B(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 tmp = (u32)(HWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)]));
- u32 a = cpu->R[REG_POS(i,12)];
-
- //LOG("SMLATB %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a);
- cpu->R[REG_POS(i,16)] = tmp + a;
-
- if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)]))
- cpu->CPSR.bits.Q = 1;
-
- return 2;
-}
-
-static u32 FASTCALL OP_SMLA_T_T(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 tmp = (u32)(HWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)]));
- u32 a = cpu->R[REG_POS(i,12)];
-
- //LOG("SMLATT %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a);
- cpu->R[REG_POS(i,16)] = tmp + a;
-
- if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)]))
- cpu->CPSR.bits.Q = 1;
-
- return 2;
-}
-
-//--------------SMLAL---------------------------------------
-
-static u32 FASTCALL OP_SMLAL_B_B(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- s64 tmp = (s64)(LWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)]));
- u64 res = (u64)tmp + cpu->R[REG_POS(i,12)];
-
- LOG("SMLALBB %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + (res + ((tmp<0)*0xFFFFFFFF))), (int)(u32) res);
-
- cpu->R[REG_POS(i,12)] = (u32) res;
- cpu->R[REG_POS(i,16)] += (res + ((tmp<0)*0xFFFFFFFF));
-
- return 2;
-}
-
-static u32 FASTCALL OP_SMLAL_B_T(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- s64 tmp = (s64)(LWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)]));
- u64 res = (u64)tmp + cpu->R[REG_POS(i,12)];
-
- LOG("SMLALBT %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + res + ((tmp<0)*0xFFFFFFFF)), (int)(u32) res);
-
- cpu->R[REG_POS(i,12)] = (u32) res;
- cpu->R[REG_POS(i,16)] += res + ((tmp<0)*0xFFFFFFFF);
-
- return 2;
-}
-
-static u32 FASTCALL OP_SMLAL_T_B(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- s64 tmp = (s64)(HWORD(cpu->R[REG_POS(i,0)])* (s64)LWORD(cpu->R[REG_POS(i,8)]));
- u64 res = (u64)tmp + cpu->R[REG_POS(i,12)];
-
- LOG("SMLALTB %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + res + ((tmp<0)*0xFFFFFFFF)), (int)(u32) res);
-
- cpu->R[REG_POS(i,12)] = (u32) res;
- cpu->R[REG_POS(i,16)] += res + ((tmp<0)*0xFFFFFFFF);
-
- return 2;
-}
-
-static u32 FASTCALL OP_SMLAL_T_T(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- s64 tmp = (s64)(HWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)]));
- u64 res = (u64)tmp + cpu->R[REG_POS(i,12)];
-
- LOG("SMLALTT %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + res + ((tmp<0)*0xFFFFFFFF)), (int)(u32) res);
-
- cpu->R[REG_POS(i,12)] = (u32) res;
- cpu->R[REG_POS(i,16)] += res + ((tmp<0)*0xFFFFFFFF);
-
- return 2;
-}
-
-//--------------SMULW--------------------
-
-static u32 FASTCALL OP_SMULW_B(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- s64 tmp = (s64)LWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]);
-
- //LOG("SMULWB %08X * %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], ((tmp>>16)&0xFFFFFFFF);
-
- cpu->R[REG_POS(i,16)] = ((tmp>>16)&0xFFFFFFFF);
-
- return 2;
-}
-
-static u32 FASTCALL OP_SMULW_T(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- s64 tmp = (s64)HWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]);
-
- //LOG("SMULWT %08X * %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], ((tmp>>16)&0xFFFFFFFF));
-
- cpu->R[REG_POS(i,16)] = ((tmp>>16)&0xFFFFFFFF);
-
- return 2;
-}
-
-//--------------SMLAW-------------------
-static u32 FASTCALL OP_SMLAW_B(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- s64 tmp = (s64)LWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]);
- u32 a = cpu->R[REG_POS(i,12)];
-
- //LOG("SMLAWB %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, (tmp>>16) + a);
-
- tmp = (tmp>>16);
-
- cpu->R[REG_POS(i,16)] = tmp + a;
-
- if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)]))
- cpu->CPSR.bits.Q = 1;
-
- return 2;
-}
-
-static u32 FASTCALL OP_SMLAW_T(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- s64 tmp = (s64)HWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]);
- u32 a = cpu->R[REG_POS(i,12)];
-
- //LOG("SMLAWT %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, ((tmp>>16)&0xFFFFFFFF) + a);
-
- tmp = ((tmp>>16)&0xFFFFFFFF);
- cpu->R[REG_POS(i,16)] = tmp + a;
-
- if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)]))
- cpu->CPSR.bits.Q = 1;
-
- return 2;
-}
-
-//------------LDR---------------------------
-
-static u32 FASTCALL OP_LDR_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
- u32 val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,12)] = val;
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
- u32 val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_LSL_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_LSL_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_LSR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_LSR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_ASR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_ASR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_ROR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_ROR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,12)] = val;
- cpu->R[REG_POS(i,16)] = adr;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
- u32 val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
- u32 val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- u32 val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-//------------------------------------------------------------
-static u32 FASTCALL OP_LDR_P_IMM_OFF_POSTIND2(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
-
- u32 adr = cpu->R[REG_POS(i,16)];
- u32 val = READ32(cpu->mem_if->data, adr);
- u32 old;
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- old = armcpu_switchMode(cpu, USR);
- cpu->R[REG_POS(i,12)] = val;
- armcpu_switchMode(cpu, old);
-
- cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-//------------------------------------------------------------
-
-static u32 FASTCALL OP_LDR_M_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- u32 val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr + shift_op;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr + shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr - shift_op;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr - shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr + shift_op;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr + shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr - shift_op;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr - shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr + shift_op;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr + shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr - shift_op;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr - shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr + shift_op;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr + shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ32(cpu->mem_if->data, adr);
-
- if(adr&3)
- val = ROR(val, 8*(adr&3));
-
- if(REG_POS(i,12)==15)
- {
- cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
- cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
- cpu->next_instruction = cpu->R[15];
- cpu->R[REG_POS(i,16)] = adr - shift_op;
- return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- }
-
- cpu->R[REG_POS(i,16)] = adr - shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-//-----------------LDRB-------------------------------------------
-
-static u32 FASTCALL OP_LDRB_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
- u32 val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
- u32 val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_LSL_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_LSL_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_LSR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_LSR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_ASR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_ASR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_ROR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_ROR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
- cpu->R[REG_POS(i,16)] = adr;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
- u32 val = READ8(cpu->mem_if->data, adr);
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
- u32 val = READ8(cpu->mem_if->data, adr);
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ8(cpu->mem_if->data, adr);
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ8(cpu->mem_if->data, adr);
-
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- u32 val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- u32 val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 val;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
- cpu->R[REG_POS(i,12)] = val;
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-//----------------------STR--------------------------------
-
-static u32 FASTCALL OP_STR_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
-
-// execute = false;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_LSL_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_LSL_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_LSR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_LSR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_ASR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_ASR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_ROR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_ROR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-//-----------------------STRB-------------------------------------
-
-static u32 FASTCALL OP_STRB_P_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_LSL_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_LSL_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_LSR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_LSR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_ASR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_ASR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_ROR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_ROR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
- WRITE8(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] + shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)] - shift_op;
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr;
- u32 shift_op;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-//-----------------------LDRBT-------------------------------------
-
-static u32 FASTCALL OP_LDRBT_P_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 val;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
- oldmode = armcpu_switchMode(cpu, SYS);
-
- i = cpu->instruction;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
- cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRBT_M_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 val;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
- oldmode = armcpu_switchMode(cpu, SYS);
-
- //execute = FALSE;
- LOG("Untested opcode: OP_LDRBT_M_IMM_OFF_POSTIND\n");
-
-
- i = cpu->instruction;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
- cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRBT_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 val;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
- oldmode = armcpu_switchMode(cpu, SYS);
- //execute = FALSE;
- LOG("Untested opcode: OP_LDRBT_P_LSL_IMM_OFF_POSTIND");
-
-
- i = cpu->instruction;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRBT_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 val;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
- //execute = FALSE;
- LOG("Untested opcode: OP_LDRBT_M_LSL_IMM_OFF_POSTIND");
-
-
- i = cpu->instruction;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRBT_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 val;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
- //execute = FALSE;
- LOG("Untested opcode: OP_LDRBT_P_LSR_IMM_OFF_POSTIND");
-
-
- i = cpu->instruction;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRBT_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 val;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
- //execute = FALSE;
- LOG("Untested opcode: OP_LDRBT_M_LSR_IMM_OFF_POSTIND");
-
-
- i = cpu->instruction;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRBT_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 val;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
- //execute = FALSE;
- LOG("Untested opcode: OP_LDRBT_P_ASR_IMM_OFF_POSTIND");
-
-
- i = cpu->instruction;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRBT_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 val;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
- //execute = FALSE;
- LOG("Untested opcode: OP_LDRBT_M_ASR_IMM_OFF_POSTIND");
-
-
- i = cpu->instruction;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRBT_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 val;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
- //execute = FALSE;
- LOG("Untested opcode: OP_LDRBT_P_ROR_IMM_OFF_POSTIND");
-
-
- i = cpu->instruction;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRBT_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 val;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
- //execute = FALSE;
- LOG("Untested opcode: OP_LDRBT_M_ROR_IMM_OFF_POSTIND");
-
-
- i = cpu->instruction;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- val = READ8(cpu->mem_if->data, adr);
- cpu->R[REG_POS(i,12)] = val;
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-//----------------------STRBT----------------------------
-
-static u32 FASTCALL OP_STRBT_P_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
-
-
- i = cpu->instruction;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRBT_M_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
-
-
- i = cpu->instruction;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRBT_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
-
-
- i = cpu->instruction;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRBT_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
-
-
- i = cpu->instruction;
- LSL_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRBT_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
-
-
- i = cpu->instruction;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRBT_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
-
-
- i = cpu->instruction;
- LSR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRBT_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
-
-
- i = cpu->instruction;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRBT_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
-
-
- i = cpu->instruction;
- ASR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRBT_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
-
-
- i = cpu->instruction;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr + shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRBT_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
-{
- u32 oldmode;
- u32 i;
- u32 adr;
- u32 shift_op;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- oldmode = armcpu_switchMode(cpu, SYS);
-
-
- i = cpu->instruction;
- ROR_IMM;
- adr = cpu->R[REG_POS(i,16)];
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
- cpu->R[REG_POS(i,16)] = adr - shift_op;
-
- armcpu_switchMode(cpu, oldmode);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-//---------------------LDM-----------------------------
-
-#define OP_L_IA(reg, adr) if(BIT##reg(i))\
- {\
- registres[reg] = READ32(cpu->mem_if->data, start);\
- c += waitState[(start>>24)&0xF];\
- adr += 4;\
- }
-
-#define OP_L_IB(reg, adr) if(BIT##reg(i))\
- {\
- adr += 4;\
- registres[reg] = READ32(cpu->mem_if->data, start);\
- c += waitState[(start>>24)&0xF];\
- }
-
-#define OP_L_DA(reg, adr) if(BIT##reg(i))\
- {\
- registres[reg] = READ32(cpu->mem_if->data, start);\
- c += waitState[(start>>24)&0xF];\
- adr -= 4;\
- }
-
-#define OP_L_DB(reg, adr) if(BIT##reg(i))\
- {\
- adr -= 4;\
- registres[reg] = READ32(cpu->mem_if->data, start);\
- c += waitState[(start>>24)&0xF];\
- }
-
-static u32 FASTCALL OP_LDMIA(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 c = 0;
- u32 start = cpu->R[REG_POS(i,16)];
-
- u32 * registres = cpu->R;
- u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- OP_L_IA(0, start);
- OP_L_IA(1, start);
- OP_L_IA(2, start);
- OP_L_IA(3, start);
- OP_L_IA(4, start);
- OP_L_IA(5, start);
- OP_L_IA(6, start);
- OP_L_IA(7, start);
- OP_L_IA(8, start);
- OP_L_IA(9, start);
- OP_L_IA(10, start);
- OP_L_IA(11, start);
- OP_L_IA(12, start);
- OP_L_IA(13, start);
- OP_L_IA(14, start);
-
- if(BIT15(i))
- {
- u32 tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- cpu->CPSR.bits.T = BIT0(tmp);
- //start += 4;
- cpu->next_instruction = registres[15];
- c += waitState[(start>>24)&0xF];
- }
-
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMIB(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 c = 0;
- u32 start = cpu->R[REG_POS(i,16)];
-
- u32 * registres = cpu->R;
- u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- OP_L_IB(0, start);
- OP_L_IB(1, start);
- OP_L_IB(2, start);
- OP_L_IB(3, start);
- OP_L_IB(4, start);
- OP_L_IB(5, start);
- OP_L_IB(6, start);
- OP_L_IB(7, start);
- OP_L_IB(8, start);
- OP_L_IB(9, start);
- OP_L_IB(10, start);
- OP_L_IB(11, start);
- OP_L_IB(12, start);
- OP_L_IB(13, start);
- OP_L_IB(14, start);
-
- if(BIT15(i))
- {
- u32 tmp;
- start += 4;
- c += waitState[(start>>24)&0xF];
- tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- cpu->CPSR.bits.T = BIT0(tmp);
- cpu->next_instruction = registres[15];
- c += 2 + (c==0);
- }
-
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMDA(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 c = 0;
- u32 start = cpu->R[REG_POS(i,16)];
-
- u32 * registres = cpu->R;
- u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- if(BIT15(i))
- {
- u32 tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- cpu->CPSR.bits.T = BIT0(tmp);
- c += waitState[(start>>24)&0xF];
- start -= 4;
- cpu->next_instruction = registres[15];
- }
-
- OP_L_DA(14, start);
- OP_L_DA(13, start);
- OP_L_DA(12, start);
- OP_L_DA(11, start);
- OP_L_DA(10, start);
- OP_L_DA(9, start);
- OP_L_DA(8, start);
- OP_L_DA(7, start);
- OP_L_DA(6, start);
- OP_L_DA(5, start);
- OP_L_DA(4, start);
- OP_L_DA(3, start);
- OP_L_DA(2, start);
- OP_L_DA(1, start);
- OP_L_DA(0, start);
-
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMDB(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 c = 0;
- u32 start = cpu->R[REG_POS(i,16)];
-
- u32 * registres = cpu->R;
- u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- if(BIT15(i))
- {
- u32 tmp;
- start -= 4;
- tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- cpu->CPSR.bits.T = BIT0(tmp);
- cpu->next_instruction = registres[15];
- c += waitState[(start>>24)&0xF];
- }
-
- OP_L_DB(14, start);
- OP_L_DB(13, start);
- OP_L_DB(12, start);
- OP_L_DB(11, start);
- OP_L_DB(10, start);
- OP_L_DB(9, start);
- OP_L_DB(8, start);
- OP_L_DB(7, start);
- OP_L_DB(6, start);
- OP_L_DB(5, start);
- OP_L_DB(4, start);
- OP_L_DB(3, start);
- OP_L_DB(2, start);
- OP_L_DB(1, start);
- OP_L_DB(0, start);
-
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMIA_W(armcpu_t *cpu)
-{
- u32 i = cpu->instruction, c = 0;
- u32 start = cpu->R[REG_POS(i,16)];
- u32 bitList = (~((2 << REG_POS(i,16))-1)) & 0xFFFF;
-
- u32 * registres = cpu->R;
- u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- OP_L_IA(0, start);
- OP_L_IA(1, start);
- OP_L_IA(2, start);
- OP_L_IA(3, start);
- OP_L_IA(4, start);
- OP_L_IA(5, start);
- OP_L_IA(6, start);
- OP_L_IA(7, start);
- OP_L_IA(8, start);
- OP_L_IA(9, start);
- OP_L_IA(10, start);
- OP_L_IA(11, start);
- OP_L_IA(12, start);
- OP_L_IA(13, start);
- OP_L_IA(14, start);
-
- if(BIT15(i))
- {
- u32 tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- cpu->CPSR.bits.T = BIT0(tmp);
- c += waitState[(start>>24)&0xF];
- start += 4;
- cpu->next_instruction = registres[15];
- }
-
- if(i & (1 << REG_POS(i,16))) {
- if(i & bitList)
- cpu->R[REG_POS(i,16)] = start;
- }
- else
- cpu->R[REG_POS(i,16)] = start;
-
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMIB_W(armcpu_t *cpu)
-{
- u32 i = cpu->instruction, c = 0;
- u32 start = cpu->R[REG_POS(i,16)];
- u32 bitList = (~((2 << REG_POS(i,16))-1)) & 0xFFFF;
-
- u32 * registres = cpu->R;
- u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- OP_L_IB(0, start);
- OP_L_IB(1, start);
- OP_L_IB(2, start);
- OP_L_IB(3, start);
- OP_L_IB(4, start);
- OP_L_IB(5, start);
- OP_L_IB(6, start);
- OP_L_IB(7, start);
- OP_L_IB(8, start);
- OP_L_IB(9, start);
- OP_L_IB(10, start);
- OP_L_IB(11, start);
- OP_L_IB(12, start);
- OP_L_IB(13, start);
- OP_L_IB(14, start);
-
- if(BIT15(i))
- {
- u32 tmp;
- start += 4;
- c += waitState[(start>>24)&0xF];
- tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- cpu->CPSR.bits.T = BIT0(tmp);
- cpu->next_instruction = registres[15];
- c += 2 + (c==0);
- }
-
- if(i & (1 << REG_POS(i,16))) {
- if(i & bitList)
- cpu->R[REG_POS(i,16)] = start;
- }
- else
- cpu->R[REG_POS(i,16)] = start;
-
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMDA_W(armcpu_t *cpu)
-{
- u32 i = cpu->instruction, c = 0;
- u32 start = cpu->R[REG_POS(i,16)];
- u32 bitList = (~((2 << REG_POS(i,16))-1)) & 0xFFFF;
-
- u32 * registres = cpu->R;
- u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- if(BIT15(i))
- {
- u32 tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- cpu->CPSR.bits.T = BIT0(tmp);
- c += waitState[(start>>24)&0xF];
- start -= 4;
- cpu->next_instruction = registres[15];
- }
-
- OP_L_DA(14, start);
- OP_L_DA(13, start);
- OP_L_DA(12, start);
- OP_L_DA(11, start);
- OP_L_DA(10, start);
- OP_L_DA(9, start);
- OP_L_DA(8, start);
- OP_L_DA(7, start);
- OP_L_DA(6, start);
- OP_L_DA(5, start);
- OP_L_DA(4, start);
- OP_L_DA(3, start);
- OP_L_DA(2, start);
- OP_L_DA(1, start);
- OP_L_DA(0, start);
-
- if(i & (1 << REG_POS(i,16))) {
- if(i & bitList)
- cpu->R[REG_POS(i,16)] = start;
- }
- else
- cpu->R[REG_POS(i,16)] = start;
-
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMDB_W(armcpu_t *cpu)
-{
- u32 i = cpu->instruction, c = 0;
- u32 start = cpu->R[REG_POS(i,16)];
- u32 bitList = (~((2 << REG_POS(i,16))-1)) & 0xFFFF;
- u32 * registres = cpu->R;
- u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- if(BIT15(i))
- {
- u32 tmp;
- start -= 4;
- tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- cpu->CPSR.bits.T = BIT0(tmp);
- cpu->next_instruction = registres[15];
- c += waitState[(start>>24)&0xF];
- }
-
- OP_L_DB(14, start);
- OP_L_DB(13, start);
- OP_L_DB(12, start);
- OP_L_DB(11, start);
- OP_L_DB(10, start);
- OP_L_DB(9, start);
- OP_L_DB(8, start);
- OP_L_DB(7, start);
- OP_L_DB(6, start);
- OP_L_DB(5, start);
- OP_L_DB(4, start);
- OP_L_DB(3, start);
- OP_L_DB(2, start);
- OP_L_DB(1, start);
- OP_L_DB(0, start);
-
- if(i & (1 << REG_POS(i,16))) {
- if(i & bitList)
- cpu->R[REG_POS(i,16)] = start;
- }
- else
- cpu->R[REG_POS(i,16)] = start;
-
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMIA2(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 oldmode;
-
- u32 c = 0;
-
- u32 start = cpu->R[REG_POS(i,16)];
- u32 * registres;
- u32 * waitState;
-
- if(BIT15(i)==0)
- {
- if(cpu->CPSR.bits.mode==USR)
- return 1;
- oldmode = armcpu_switchMode(cpu, SYS);
- }
-
- registres = cpu->R;
- waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- OP_L_IA(0, start);
- OP_L_IA(1, start);
- OP_L_IA(2, start);
- OP_L_IA(3, start);
- OP_L_IA(4, start);
- OP_L_IA(5, start);
- OP_L_IA(6, start);
- OP_L_IA(7, start);
- OP_L_IA(8, start);
- OP_L_IA(9, start);
- OP_L_IA(10, start);
- OP_L_IA(11, start);
- OP_L_IA(12, start);
- OP_L_IA(13, start);
- OP_L_IA(14, start);
-
- if(BIT15(i))
- {
- u32 tmp = READ32(cpu->mem_if->data, start);
- Status_Reg SPSR;
- cpu->R[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- //start += 4;
- cpu->next_instruction = cpu->R[15];
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- }
- else
- {
- armcpu_switchMode(cpu, oldmode);
- }
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMIB2(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 oldmode;
- u32 c = 0;
-
- u32 start = cpu->R[REG_POS(i,16)];
- u32 * registres;
- u32 * waitState;
- //execute = FALSE;
- LOG("Untested opcode: OP_LDMIB2");
-
- if(BIT15(i)==0)
- {
- if(cpu->CPSR.bits.mode==USR)
- return 2;
- oldmode = armcpu_switchMode(cpu, SYS);
- }
-
- registres = cpu->R;
- waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- OP_L_IB(0, start);
- OP_L_IB(1, start);
- OP_L_IB(2, start);
- OP_L_IB(3, start);
- OP_L_IB(4, start);
- OP_L_IB(5, start);
- OP_L_IB(6, start);
- OP_L_IB(7, start);
- OP_L_IB(8, start);
- OP_L_IB(9, start);
- OP_L_IB(10, start);
- OP_L_IB(11, start);
- OP_L_IB(12, start);
- OP_L_IB(13, start);
- OP_L_IB(14, start);
-
- if(BIT15(i))
- {
- u32 tmp;
- Status_Reg SPSR;
- start += 4;
- tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- cpu->next_instruction = registres[15];
- c += waitState[(start>>24)&0xF];
- }
- else
- {
- armcpu_switchMode(cpu, oldmode);
- }
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMDA2(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
-
- u32 oldmode;
- u32 c = 0;
- u32 * registres;
- u32 * waitState;
-
- u32 start = cpu->R[REG_POS(i,16)];
- //execute = FALSE;
- LOG("Untested opcode: OP_LDMDA2");
-
- if(BIT15(i)==0)
- {
- if(cpu->CPSR.bits.mode==USR)
- return 2;
- oldmode = armcpu_switchMode(cpu, SYS);
- }
-
- registres = cpu->R;
- waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- if(BIT15(i))
- {
- u32 tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- cpu->CPSR = cpu->SPSR;
- c += waitState[(start>>24)&0xF];
- start -= 4;
- cpu->next_instruction = registres[15];
- }
-
- OP_L_DA(14, start);
- OP_L_DA(13, start);
- OP_L_DA(12, start);
- OP_L_DA(11, start);
- OP_L_DA(10, start);
- OP_L_DA(9, start);
- OP_L_DA(8, start);
- OP_L_DA(7, start);
- OP_L_DA(6, start);
- OP_L_DA(5, start);
- OP_L_DA(4, start);
- OP_L_DA(3, start);
- OP_L_DA(2, start);
- OP_L_DA(1, start);
- OP_L_DA(0, start);
-
- if(BIT15(i)==0)
- {
- armcpu_switchMode(cpu, oldmode);
- }
- else
- {
- Status_Reg SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- }
-
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMDB2(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
-
- u32 oldmode;
- u32 c = 0;
- u32 * registres;
- u32 * waitState;
-
- u32 start = cpu->R[REG_POS(i,16)];
- if(BIT15(i)==0)
- {
- if(cpu->CPSR.bits.mode==USR)
- return 2;
- oldmode = armcpu_switchMode(cpu, SYS);
- }
-
- registres = cpu->R;
- waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- if(BIT15(i))
- {
- u32 tmp;
- start -= 4;
- tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- cpu->CPSR = cpu->SPSR;
- cpu->next_instruction = registres[15];
- c += waitState[(start>>24)&0xF];
- }
-
- OP_L_DB(14, start);
- OP_L_DB(13, start);
- OP_L_DB(12, start);
- OP_L_DB(11, start);
- OP_L_DB(10, start);
- OP_L_DB(9, start);
- OP_L_DB(8, start);
- OP_L_DB(7, start);
- OP_L_DB(6, start);
- OP_L_DB(5, start);
- OP_L_DB(4, start);
- OP_L_DB(3, start);
- OP_L_DB(2, start);
- OP_L_DB(1, start);
- OP_L_DB(0, start);
-
- if(BIT15(i)==0)
- {
- armcpu_switchMode(cpu, oldmode);
- }
- else
- {
- Status_Reg SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- }
-
- return 2 + c;
-}
-
-static u32 FASTCALL OP_LDMIA2_W(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 c = 0;
-
- u32 oldmode;
- u32 start = cpu->R[REG_POS(i,16)];
- u32 * registres;
- u32 * waitState;
- u32 tmp;
- Status_Reg SPSR;
-// execute = FALSE;
- if(BIT15(i)==0)
- {
- if(cpu->CPSR.bits.mode==USR)
- return 2;
- oldmode = armcpu_switchMode(cpu, SYS);
- }
-
- registres = cpu->R;
- waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- OP_L_IA(0, start);
- OP_L_IA(1, start);
- OP_L_IA(2, start);
- OP_L_IA(3, start);
- OP_L_IA(4, start);
- OP_L_IA(5, start);
- OP_L_IA(6, start);
- OP_L_IA(7, start);
- OP_L_IA(8, start);
- OP_L_IA(9, start);
- OP_L_IA(10, start);
- OP_L_IA(11, start);
- OP_L_IA(12, start);
- OP_L_IA(13, start);
- OP_L_IA(14, start);
-
- if(BIT15(i)==0)
- {
- registres[REG_POS(i,16)] = start;
- armcpu_switchMode(cpu, oldmode);
- return c + 2;
- }
-
- registres[REG_POS(i,16)] = start + 4;
- tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- cpu->next_instruction = registres[15];
- c += waitState[(start>>24)&0xF];
-
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMIB2_W(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 c = 0;
-
- u32 oldmode;
- u32 start = cpu->R[REG_POS(i,16)];
- u32 * registres;
- u32 * waitState;
- u32 tmp;
- Status_Reg SPSR;
-
- if(BIT15(i)==0)
- {
- if(cpu->CPSR.bits.mode==USR)
- return 2;
- oldmode = armcpu_switchMode(cpu, SYS);
- }
-
- registres = cpu->R;
- waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- OP_L_IB(0, start);
- OP_L_IB(1, start);
- OP_L_IB(2, start);
- OP_L_IB(3, start);
- OP_L_IB(4, start);
- OP_L_IB(5, start);
- OP_L_IB(6, start);
- OP_L_IB(7, start);
- OP_L_IB(8, start);
- OP_L_IB(9, start);
- OP_L_IB(10, start);
- OP_L_IB(11, start);
- OP_L_IB(12, start);
- OP_L_IB(13, start);
- OP_L_IB(14, start);
-
- if(BIT15(i)==0)
- {
- armcpu_switchMode(cpu, oldmode);
- registres[REG_POS(i,16)] = start;
-
- return c + 2;
- }
-
- registres[REG_POS(i,16)] = start + 4;
- tmp = READ32(cpu->mem_if->data, start + 4);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- cpu->CPSR = cpu->SPSR;
- cpu->next_instruction = registres[15];
- SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- c += waitState[(start>>24)&0xF];
-
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMDA2_W(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 c = 0;
-
- u32 oldmode;
- u32 start = cpu->R[REG_POS(i,16)];
- u32 * registres;
- u32 * waitState;
- Status_Reg SPSR;
-// execute = FALSE;
- if(BIT15(i)==0)
- {
- if(cpu->CPSR.bits.mode==USR)
- return 2;
- oldmode = armcpu_switchMode(cpu, SYS);
- }
-
- registres = cpu->R;
- waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- if(BIT15(i))
- {
- u32 tmp = READ32(cpu->mem_if->data, start);
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- c += waitState[(start>>24)&0xF];
- start -= 4;
- cpu->next_instruction = registres[15];
- }
-
- OP_L_DA(14, start);
- OP_L_DA(13, start);
- OP_L_DA(12, start);
- OP_L_DA(11, start);
- OP_L_DA(10, start);
- OP_L_DA(9, start);
- OP_L_DA(8, start);
- OP_L_DA(7, start);
- OP_L_DA(6, start);
- OP_L_DA(5, start);
- OP_L_DA(4, start);
- OP_L_DA(3, start);
- OP_L_DA(2, start);
- OP_L_DA(1, start);
- OP_L_DA(0, start);
-
- registres[REG_POS(i,16)] = start;
-
- if(BIT15(i)==0)
- {
- armcpu_switchMode(cpu, oldmode);
- return c + 2;
- }
-
- SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMDB2_W(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 c = 0;
-
- u32 oldmode;
- u32 start = cpu->R[REG_POS(i,16)];
- u32 * registres;
- u32 * waitState;
- Status_Reg SPSR;
-// execute = FALSE;
- if(BIT15(i)==0)
- {
- if(cpu->CPSR.bits.mode==USR)
- return 2;
- oldmode = armcpu_switchMode(cpu, SYS);
- }
-
- registres = cpu->R;
- waitState = MMU.MMU_WAIT32[cpu->proc_ID];
-
- if(BIT15(i))
- {
- u32 tmp;
- start -= 4;
- tmp = READ32(cpu->mem_if->data, start);
- c += waitState[(start>>24)&0xF];
- registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
- cpu->CPSR = cpu->SPSR;
- cpu->next_instruction = registres[15];
- }
-
- OP_L_DB(14, start);
- OP_L_DB(13, start);
- OP_L_DB(12, start);
- OP_L_DB(11, start);
- OP_L_DB(10, start);
- OP_L_DB(9, start);
- OP_L_DB(8, start);
- OP_L_DB(7, start);
- OP_L_DB(6, start);
- OP_L_DB(5, start);
- OP_L_DB(4, start);
- OP_L_DB(3, start);
- OP_L_DB(2, start);
- OP_L_DB(1, start);
- OP_L_DB(0, start);
-
- registres[REG_POS(i,16)] = start;
-
- if(BIT15(i)==0)
- {
- armcpu_switchMode(cpu, oldmode);
- return c + 2;
- }
-
- SPSR = cpu->SPSR;
- armcpu_switchMode(cpu, SPSR.bits.mode);
- cpu->CPSR=SPSR;
- return c + 2;
-}
-
-//------------------------------STM----------------------------------
-
-static u32 FASTCALL OP_STMIA(armcpu_t *cpu)
-{
- u32 i = cpu->instruction, c = 0, b;
- u32 start = cpu->R[REG_POS(i,16)];
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, b))
- {
- WRITE32(cpu->mem_if->data, start, cpu->R[b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- start += 4;
- }
- }
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMIB(armcpu_t *cpu)
-{
- u32 i = cpu->instruction, c = 0, b;
- u32 start = cpu->R[REG_POS(i,16)];
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, b))
- {
- start += 4;
- WRITE32(cpu->mem_if->data, start, cpu->R[b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- }
- }
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMDA(armcpu_t *cpu)
-{
- u32 i = cpu->instruction, c = 0, b;
- u32 start = cpu->R[REG_POS(i,16)];
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, 15-b))
- {
- WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- start -= 4;
- }
- }
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMDB(armcpu_t *cpu)
-{
- u32 i = cpu->instruction, c = 0, b;
- u32 start = cpu->R[REG_POS(i,16)];
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, 15-b))
- {
- start -= 4;
- WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- }
- }
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMIA_W(armcpu_t *cpu)
-{
- u32 i = cpu->instruction, c = 0, b;
- u32 start = cpu->R[REG_POS(i,16)];
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, b))
- {
- WRITE32(cpu->mem_if->data, start, cpu->R[b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- start += 4;
- }
- }
-
- cpu->R[REG_POS(i,16)] = start;
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMIB_W(armcpu_t *cpu)
-{
- u32 i = cpu->instruction, c = 0, b;
- u32 start = cpu->R[REG_POS(i,16)];
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, b))
- {
- start += 4;
- WRITE32(cpu->mem_if->data, start, cpu->R[b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- }
- }
- cpu->R[REG_POS(i,16)] = start;
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMDA_W(armcpu_t *cpu)
-{
- u32 i = cpu->instruction, c = 0, b;
- u32 start = cpu->R[REG_POS(i,16)];
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, 15-b))
- {
- WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- start -= 4;
- }
- }
-
- cpu->R[REG_POS(i,16)] = start;
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMDB_W(armcpu_t *cpu)
-{
- u32 i = cpu->instruction, c = 0, b;
- u32 start = cpu->R[REG_POS(i,16)];
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, 15-b))
- {
- start -= 4;
- WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- }
- }
-
- cpu->R[REG_POS(i,16)] = start;
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMIA2(armcpu_t *cpu)
-{
- u32 i, c, b;
- u32 start;
- u32 oldmode;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- i = cpu->instruction;
- c = 0;
- start = cpu->R[REG_POS(i,16)];
- oldmode = armcpu_switchMode(cpu, SYS);
-
- //execute = FALSE;
- LOG("Untested opcode: OP_STMIA2");
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, b))
- {
- WRITE32(cpu->mem_if->data, start, cpu->R[b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- start += 4;
- }
- }
-
- armcpu_switchMode(cpu, oldmode);
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMIB2(armcpu_t *cpu)
-{
- u32 i, c, b;
- u32 start;
- u32 oldmode;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- i = cpu->instruction;
- c = 0;
- start = cpu->R[REG_POS(i,16)];
- oldmode = armcpu_switchMode(cpu, SYS);
-
- //execute = FALSE;
- LOG("Untested opcode: OP_STMIB2");
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, b))
- {
- start += 4;
- WRITE32(cpu->mem_if->data, start, cpu->R[b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- }
- }
-
- armcpu_switchMode(cpu, oldmode);
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMDA2(armcpu_t *cpu)
-{
- u32 i, c, b;
- u32 start;
- u32 oldmode;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- i = cpu->instruction;
- c = 0;
- start = cpu->R[REG_POS(i,16)];
- oldmode = armcpu_switchMode(cpu, SYS);
-
- //execute = FALSE;
- LOG("Untested opcode: OP_STMDA2");
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, 15-b))
- {
- WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- start -= 4;
- }
- }
-
- armcpu_switchMode(cpu, oldmode);
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMDB2(armcpu_t *cpu)
-{
- u32 i, c, b;
- u32 start;
- u32 oldmode;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
- i = cpu->instruction;
- c=0;
- start = cpu->R[REG_POS(i,16)];
- oldmode = armcpu_switchMode(cpu, SYS);
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, 15-b))
- {
- start -= 4;
- WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- }
- }
-
- armcpu_switchMode(cpu, oldmode);
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMIA2_W(armcpu_t *cpu)
-{
- u32 i, c, b;
- u32 start;
- u32 oldmode;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- i = cpu->instruction;
- c=0;
- start = cpu->R[REG_POS(i,16)];
- oldmode = armcpu_switchMode(cpu, SYS);
-
- //execute = FALSE;
- LOG("Untested opcode: OP_STMIA2_W");
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, b))
- {
- WRITE32(cpu->mem_if->data, start, cpu->R[b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- start += 4;
- }
- }
-
- cpu->R[REG_POS(i,16)] = start;
-
- armcpu_switchMode(cpu, oldmode);
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMIB2_W(armcpu_t *cpu)
-{
- u32 i, c, b;
- u32 start;
- u32 oldmode;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
- i = cpu->instruction;
- c=0;
- start = cpu->R[REG_POS(i,16)];
- oldmode = armcpu_switchMode(cpu, SYS);
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, b))
- {
- start += 4;
- WRITE32(cpu->mem_if->data, start, cpu->R[b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- }
- }
- armcpu_switchMode(cpu, oldmode);
- cpu->R[REG_POS(i,16)] = start;
-
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMDA2_W(armcpu_t *cpu)
-{
- u32 i, c, b;
- u32 start;
- u32 oldmode;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- i = cpu->instruction;
- c = 0;
- start = cpu->R[REG_POS(i,16)];
- oldmode = armcpu_switchMode(cpu, SYS);
- //execute = FALSE;
- LOG("Untested opcode: OP_STMDA2_W");
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, 15-b))
- {
- WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- start -= 4;
- }
- }
-
- cpu->R[REG_POS(i,16)] = start;
-
- armcpu_switchMode(cpu, oldmode);
- return c + 1;
-}
-
-static u32 FASTCALL OP_STMDB2_W(armcpu_t *cpu)
-{
- u32 i, c, b;
- u32 start;
- u32 oldmode;
-
- if(cpu->CPSR.bits.mode==USR)
- return 2;
-
- i = cpu->instruction;
- c = 0;
-
- start = cpu->R[REG_POS(i,16)];
- oldmode = armcpu_switchMode(cpu, SYS);
-
- //execute = FALSE;
- LOG("Untested opcode: OP_STMDB2_W");
-
- for(b=0; b<16; ++b)
- {
- if(BIT_N(i, 15-b))
- {
- start -= 4;
- WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
- }
- }
-
- cpu->R[REG_POS(i,16)] = start;
-
- armcpu_switchMode(cpu, oldmode);
- return c + 1;
-}
-
-/*
- *
- * The Enhanced DSP Extension LDRD and STRD instructions.
- *
- */
-static u32 FASTCALL
-OP_LDRD_STRD_POST_INDEX( armcpu_t *cpu) {
- u32 i = cpu->instruction;
- u32 Rd_num = REG_POS( i, 12);
- u32 addr = cpu->R[REG_POS(i,16)];
- u32 index;
-
- /* I bit - immediate or register */
- if ( BIT22(i))
- index = IMM_OFF;
- else
- index = cpu->R[REG_POS(i,0)];
-
- /* U bit - add or subtract */
- if ( BIT23(i))
- cpu->R[REG_POS(i,16)] += index;
- else
- cpu->R[REG_POS(i,16)] -= index;
-
- if ( !(Rd_num & 0x1)) {
- /* Store/Load */
- if ( BIT5(i)) {
- WRITE32(cpu->mem_if->data, addr, cpu->R[Rd_num]);
- WRITE32(cpu->mem_if->data, addr + 4, cpu->R[Rd_num + 1]);
- }
- else {
- cpu->R[Rd_num] = READ32(cpu->mem_if->data, addr);
- cpu->R[Rd_num + 1] = READ32(cpu->mem_if->data, addr + 4);
- }
- }
-
- return 3 + (MMU.MMU_WAIT32[cpu->proc_ID][(addr>>24)&0xF] * 2);
-}
-
-static u32 FASTCALL
-OP_LDRD_STRD_OFFSET_PRE_INDEX( armcpu_t *cpu) {
- u32 i = cpu->instruction;
- u32 Rd_num = REG_POS( i, 12);
- u32 addr = cpu->R[REG_POS(i,16)];
- u32 index;
-
- /* I bit - immediate or register */
- if ( BIT22(i))
- index = IMM_OFF;
- else
- index = cpu->R[REG_POS(i,0)];
-
- /* U bit - add or subtract */
- if ( BIT23(i)) {
- addr += index;
-
- /* W bit - writeback */
- if ( BIT21(i))
- cpu->R[REG_POS(i,16)] = addr;
- }
- else {
- addr -= index;
-
- /* W bit - writeback */
- if ( BIT21(i))
- cpu->R[REG_POS(i,16)] = addr;
- }
-
- if ( !(Rd_num & 0x1)) {
- /* Store/Load */
- if ( BIT5(i)) {
- WRITE32(cpu->mem_if->data, addr, cpu->R[Rd_num]);
- WRITE32(cpu->mem_if->data, addr + 4, cpu->R[Rd_num + 1]);
- }
- else {
- cpu->R[Rd_num] = READ32(cpu->mem_if->data, addr);
- cpu->R[Rd_num + 1] = READ32(cpu->mem_if->data, addr + 4);
- }
- }
-
- return 3 + (MMU.MMU_WAIT32[cpu->proc_ID][(addr>>24)&0xF] * 2);
-}
-
-
-
-//---------------------STC----------------------------------
-
-static u32 FASTCALL OP_STC_P_IMM_OFF(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
- return 2;
- }
-}
-
-static u32 FASTCALL OP_STC_M_IMM_OFF(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
- return 2;
- }
-}
-
-static u32 FASTCALL OP_STC_P_PREIND(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
- return 2;
- }
-}
-
-static u32 FASTCALL OP_STC_M_PREIND(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
- return 2;
- }
-}
-
-static u32 FASTCALL OP_STC_P_POSTIND(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
- return 2;
- }
-}
-
-static u32 FASTCALL OP_STC_M_POSTIND(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
- return 2;
- }
-}
-
-static u32 FASTCALL OP_STC_OPTION(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
- return 2;
- }
-}
-
-//---------------------LDC----------------------------------
-
-static u32 FASTCALL OP_LDC_P_IMM_OFF(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
- return 2;
- }
-}
-
-static u32 FASTCALL OP_LDC_M_IMM_OFF(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
- return 2;
- }
-}
-
-static u32 FASTCALL OP_LDC_P_PREIND(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
- return 2;
- }
-}
-
-static u32 FASTCALL OP_LDC_M_PREIND(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
- return 2;
- }
-}
-
-static u32 FASTCALL OP_LDC_P_POSTIND(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
- return 2;
- }
-}
-
-static u32 FASTCALL OP_LDC_M_POSTIND(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
- return 2;
- }
-}
-
-static u32 FASTCALL OP_LDC_OPTION(armcpu_t *cpu)
-{
- {
- /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
- return 2;
- }
-}
-
-//----------------MCR-----------------------
-
-static u32 FASTCALL OP_MCR(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 cpnum = REG_POS(i, 8);
-
- if(!cpu->coproc[cpnum])
- {
- execute = FALSE;
- return 2;
- }
-
- armcp15_moveARM2CP((armcp15_t*)cpu->coproc[cpnum], cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7);
- //cpu->coproc[cpnum]->moveARM2CP(cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7);
- return 2;
-}
-
-//----------------MRC-----------------------
-
-static u32 FASTCALL OP_MRC(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 cpnum = REG_POS(i, 8);
-
- if(!cpu->coproc[cpnum])
- {
- execute = FALSE;
- return 2;
- }
-
- armcp15_moveCP2ARM((armcp15_t*)cpu->coproc[cpnum], &cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7);
- //cpu->coproc[cpnum]->moveCP2ARM(&cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7);
- return 4;
-}
-
-//--------------SWI-------------------------------
-static u32 FASTCALL OP_SWI(armcpu_t *cpu)
-{
- if (((cpu->intVector != 0) ^ (cpu->proc_ID == ARMCPU_ARM9)))
- {
- /* TODO (#1#): translocated SWI vectors */
- /* we use an irq thats not in the irq tab, as
- it was replaced duie to a changed intVector */
- Status_Reg tmp = cpu->CPSR;
- armcpu_switchMode(cpu, SVC); /* enter svc mode */
- cpu->R[14] = cpu->R[15] - 4; /* jump to swi Vector */
- cpu->SPSR = tmp; /* save old CPSR as new SPSR */
- cpu->CPSR.bits.T = 0; /* handle as ARM32 code */
- cpu->CPSR.bits.I = cpu->SPSR.bits.I; /* keep int disable flag */
- cpu->R[15] = cpu->intVector + 0x08;
- cpu->next_instruction = cpu->R[15];
- return 4;
- }
- else
- {
- u32 swinum = (cpu->instruction>>16)&0x1F;
- return cpu->swi_tab[swinum](cpu) + 3;
- }
-}
-
-//----------------BKPT-------------------------
-static u32 FASTCALL OP_BKPT(armcpu_t *cpu)
-{
- execute = FALSE;
- return 4;
-}
-
-//----------------CDP-----------------------
-
-static u32 FASTCALL OP_CDP(armcpu_t *cpu)
-{
- execute = FALSE;
- return 4;
-}
-
-#define TYPE_RETOUR u32
-#define PARAMETRES armcpu_t *cpu
-#define CALLTYPE FASTCALL
-#define NOM_TAB arm_instructions_set
-
-#include "instruction_tabdef.inc"
diff --git a/src/xsf/desmume/arm_instructions.cc b/src/xsf/desmume/arm_instructions.cc
new file mode 100644
index 000000000000..b246a974c947
--- /dev/null
+++ b/src/xsf/desmume/arm_instructions.cc
@@ -0,0 +1,7857 @@
+/* Copyright (C) 2006 yopyop
+ Copyright (C) 2006 shash
+ yopyop156 at ifrance.com
+ yopyop156.ifrance.com
+
+ Copyright (C) 2006-2007 shash
+
+ This file is part of DeSmuME
+
+ DeSmuME 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.
+
+ DeSmuME 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 DeSmuME; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "cp15.h"
+#include "debug.h"
+#include "MMU.h"
+
+
+// Use this macros for reading/writing, so the GDB stub isn't broken
+#ifdef GDB_STUB
+ #define READ32(a,b) cpu->mem_if->read32(a,b)
+ #define WRITE32(a,b,c) cpu->mem_if->write32(a,b,c)
+ #define READ16(a,b) cpu->mem_if->read16(a,b)
+ #define WRITE16(a,b,c) cpu->mem_if->write16(a,b,c)
+ #define READ8(a,b) cpu->mem_if->read8(a,b)
+ #define WRITE8(a,b,c) cpu->mem_if->write8(a,b,c)
+#else
+ #define READ32(a,b) MMU_read32(cpu->proc_ID, b)
+ #define WRITE32(a,b,c) MMU_write32(cpu->proc_ID,b,c)
+ #define READ16(a,b) MMU_read16(cpu->proc_ID, b)
+ #define WRITE16(a,b,c) MMU_write16(cpu->proc_ID,b,c)
+ #define READ8(a,b) MMU_read8(cpu->proc_ID, b)
+ #define WRITE8(a,b,c) MMU_write8(cpu->proc_ID,b,c)
+#endif
+
+
+
+#define LSL_IMM shift_op = cpu->R[REG_POS(i,0)]<<((i>>7)&0x1F);
+
+#define S_LSL_IMM u32 shift_op = ((i>>7)&0x1F);\
+ u32 c = cpu->CPSR.bits.C;\
+ if(shift_op==0)\
+ shift_op=cpu->R[REG_POS(i,0)];\
+ else\
+ {\
+ c = BIT_N(cpu->R[REG_POS(i,0)], 32-shift_op);\
+ shift_op = cpu->R[REG_POS(i,0)]<<((i>>7)&0x1F);\
+ }
+
+#define LSL_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
+ if(shift_op>=32)\
+ shift_op=0;\
+ else\
+ shift_op=cpu->R[REG_POS(i,0)]<<shift_op;
+
+#define S_LSL_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
+ u32 c = cpu->CPSR.bits.C;\
+ if(shift_op==0)\
+ shift_op=cpu->R[REG_POS(i,0)];\
+ else\
+ if(shift_op<32)\
+ {\
+ c = BIT_N(cpu->R[REG_POS(i,0)], 32-shift_op);\
+ shift_op = cpu->R[REG_POS(i,0)]<<shift_op;\
+ }\
+ else\
+ if(shift_op==32)\
+ {\
+ shift_op = 0;\
+ c = BIT0(cpu->R[REG_POS(i,0)]);\
+ }\
+ else\
+ {\
+ shift_op = 0;\
+ c = 0;\
+ }
+
+#define LSR_IMM shift_op = ((i>>7)&0x1F);\
+ if(shift_op!=0)\
+ shift_op = cpu->R[REG_POS(i,0)]>>shift_op;
+
+#define S_LSR_IMM u32 shift_op = ((i>>7)&0x1F);\
+ u32 c = cpu->CPSR.bits.C;\
+ if(shift_op==0)\
+ {\
+ c = BIT31(cpu->R[REG_POS(i,0)]);\
+ }\
+ else\
+ {\
+ c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\
+ shift_op = cpu->R[REG_POS(i,0)]>>shift_op;\
+ }
+
+#define LSR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
+ if(shift_op>=32)\
+ shift_op = 0;\
+ else\
+ shift_op = cpu->R[REG_POS(i,0)]>>shift_op;
+
+#define S_LSR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
+ u32 c = cpu->CPSR.bits.C;\
+ if(shift_op==0)\
+ {\
+ shift_op = cpu->R[REG_POS(i,0)];\
+ }\
+ else\
+ if(shift_op<32)\
+ {\
+ c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\
+ shift_op = cpu->R[REG_POS(i,0)]>>shift_op;\
+ }\
+ else\
+ if(shift_op==32)\
+ {\
+ c = BIT31(cpu->R[REG_POS(i,0)]);\
+ shift_op = 0;\
+ }\
+ else\
+ {\
+ c = 0;\
+ shift_op = 0;\
+ }
+
+#define ASR_IMM shift_op = ((i>>7)&0x1F);\
+ if(shift_op==0)\
+ shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;\
+ else\
+ shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);
+
+#define S_ASR_IMM u32 shift_op = ((i>>7)&0x1F);\
+ u32 c = cpu->CPSR.bits.C;\
+ if(shift_op==0)\
+ {\
+ shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;\
+ c = BIT31(cpu->R[REG_POS(i,0)]);\
+ }\
+ else\
+ {\
+ c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\
+ shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);\
+ }
+
+#define ASR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
+ if(shift_op==0)\
+ shift_op=cpu->R[REG_POS(i,0)];\
+ else\
+ if(shift_op<32)\
+ shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);\
+ else\
+ shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;
+
+#define S_ASR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
+ u32 c = cpu->CPSR.bits.C;\
+ if(shift_op==0)\
+ shift_op=cpu->R[REG_POS(i,0)];\
+ else\
+ if(shift_op<32)\
+ {\
+ c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\
+ shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);\
+ }\
+ else\
+ {\
+ c = BIT31(cpu->R[REG_POS(i,0)]);\
+ shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;\
+ }
+
+#define ROR_IMM shift_op = ((i>>7)&0x1F);\
+ if(shift_op==0)\
+ {\
+ u32 tmp = cpu->CPSR.bits.C;\
+ shift_op = (tmp<<31)|(cpu->R[REG_POS(i,0)]>>1);\
+ }\
+ else\
+ shift_op = ROR(cpu->R[REG_POS(i,0)],shift_op);
+
+#define S_ROR_IMM u32 shift_op = ((i>>7)&0x1F);\
+ u32 c = cpu->CPSR.bits.C;\
+ if(shift_op==0)\
+ {\
+ u32 tmp = cpu->CPSR.bits.C;\
+ shift_op = (tmp<<31)|(cpu->R[REG_POS(i,0)]>>1);\
+ c = BIT0(cpu->R[REG_POS(i,0)]);\
+ }\
+ else\
+ {\
+ c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\
+ shift_op = ROR(cpu->R[REG_POS(i,0)],shift_op);\
+ }
+
+#define ROR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
+ if((shift_op==0)||((shift_op&0xF)==0))\
+ shift_op=cpu->R[REG_POS(i,0)];\
+ else\
+ shift_op = ROR(cpu->R[REG_POS(i,0)],(shift_op&0xF));
+
+#define S_ROR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\
+ u32 c = cpu->CPSR.bits.C;\
+ if(shift_op==0)\
+ shift_op=cpu->R[REG_POS(i,0)];\
+ else\
+ {\
+ shift_op&=0xF;\
+ if(shift_op==0)\
+ {\
+ shift_op=cpu->R[REG_POS(i,0)];\
+ c = BIT31(cpu->R[REG_POS(i,0)]);\
+ }\
+ else\
+ {\
+ c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\
+ shift_op = ROR(cpu->R[REG_POS(i,0)],(shift_op&0xF));\
+ }\
+ }
+
+#define IMM_VALUE u32 shift_op = ROR((i&0xFF), (i>>7)&0x1E);
+
+#define S_IMM_VALUE u32 shift_op = ROR((i&0xFF), (i>>7)&0x1E);\
+ u32 c = cpu->CPSR.bits.C;\
+ if((i>>8)&0xF)\
+ c = BIT31(shift_op);
+
+#define IMM_OFF (((i>>4)&0xF0)+(i&0xF))
+
+#define IMM_OFF_12 ((i)&0xFFF)
+
+extern BOOL execute;
+
+static u32 FASTCALL OP_UND(armcpu_t *cpu)
+{
+ LOG("Undefined instruction: %08X\n", cpu->instruction);
+ execute = false;
+ return 1;
+}
+
+//-----------------------AND------------------------------------
+
+#define OP_AND(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & shift_op;\
+ if(REG_POS(i,12)==15)\
+ {\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ return a;
+
+#define OP_ANDS(a, b)\
+ if(REG_POS(i,12)==15)\
+ {\
+ Status_Reg SPSR;\
+ cpu->R[15] = cpu->R[REG_POS(i,16)] & shift_op;\
+ SPSR = cpu->SPSR;\
+ armcpu_switchMode(cpu, SPSR.bits.mode);\
+ cpu->CPSR=SPSR;\
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & shift_op;\
+ cpu->CPSR.bits.C = c;\
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
+ return a;
+
+static u32 FASTCALL OP_AND_LSL_IMM(register armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OP_AND(1, 3);
+}
+
+static u32 FASTCALL OP_AND_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OP_AND(2, 4);
+}
+
+static u32 FASTCALL OP_AND_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OP_AND(1, 3);
+}
+
+static u32 FASTCALL OP_AND_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OP_AND(2, 4);
+}
+
+static u32 FASTCALL OP_AND_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OP_AND(1, 3);
+}
+
+static u32 FASTCALL OP_AND_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OP_AND(2, 4);
+}
+
+static u32 FASTCALL OP_AND_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OP_AND(1, 3);
+}
+
+static u32 FASTCALL OP_AND_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OP_AND(2, 4);
+}
+
+static u32 FASTCALL OP_AND_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OP_AND(1, 3);
+}
+
+static u32 FASTCALL OP_AND_S_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_IMM;
+ OP_ANDS(2, 4);
+}
+
+static u32 FASTCALL OP_AND_S_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_REG;
+ OP_ANDS(3, 5);
+}
+
+static u32 FASTCALL OP_AND_S_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_IMM;
+ OP_ANDS(2, 4);
+}
+
+static u32 FASTCALL OP_AND_S_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_REG;
+ OP_ANDS(3, 5);
+}
+
+static u32 FASTCALL OP_AND_S_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_IMM;
+ OP_ANDS(2, 4);
+}
+
+static u32 FASTCALL OP_AND_S_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_REG;
+ OP_ANDS(3, 5);
+}
+
+static u32 FASTCALL OP_AND_S_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_IMM;
+ OP_ANDS(2, 4);
+}
+
+static u32 FASTCALL OP_AND_S_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_REG;
+ OP_ANDS(3, 5);
+}
+
+static u32 FASTCALL OP_AND_S_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_IMM_VALUE;
+ OP_ANDS(2, 4);
+}
+
+//--------------EOR------------------------------
+
+#define OP_EOR(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] ^ shift_op;\
+ if(REG_POS(i,12)==15)\
+ {\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ return a;
+
+#define OP_EORS(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] ^ shift_op;\
+ if(REG_POS(i,12)==15)\
+ {\
+ Status_Reg SPSR = cpu->SPSR;\
+ armcpu_switchMode(cpu, SPSR.bits.mode);\
+ cpu->CPSR=SPSR;\
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ cpu->CPSR.bits.C = c;\
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
+ return a;
+
+static u32 FASTCALL OP_EOR_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OP_EOR(1, 3);
+}
+
+static u32 FASTCALL OP_EOR_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OP_EOR(2, 4);
+}
+
+static u32 FASTCALL OP_EOR_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OP_EOR(1, 3);
+}
+
+static u32 FASTCALL OP_EOR_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OP_EOR(2, 4);
+}
+
+static u32 FASTCALL OP_EOR_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OP_EOR(1, 3);
+}
+
+static u32 FASTCALL OP_EOR_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OP_EOR(2, 4);
+}
+
+static u32 FASTCALL OP_EOR_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OP_EOR(1, 3);
+}
+
+static u32 FASTCALL OP_EOR_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OP_EOR(2, 4);
+}
+
+static u32 FASTCALL OP_EOR_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OP_EOR(1, 3);
+}
+
+static u32 FASTCALL OP_EOR_S_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_IMM;
+ OP_EORS(2, 4);
+}
+
+static u32 FASTCALL OP_EOR_S_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_REG;
+ OP_EORS(3, 5);
+}
+
+static u32 FASTCALL OP_EOR_S_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_IMM;
+ OP_EORS(2, 4);
+}
+
+static u32 FASTCALL OP_EOR_S_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_REG;
+ OP_EORS(3, 5);
+}
+
+static u32 FASTCALL OP_EOR_S_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_IMM;
+ OP_EORS(2, 4);
+}
+
+static u32 FASTCALL OP_EOR_S_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_REG;
+ OP_EORS(3, 5);
+}
+
+static u32 FASTCALL OP_EOR_S_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_IMM;
+ OP_EORS(2, 4);
+}
+
+static u32 FASTCALL OP_EOR_S_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_REG;
+ OP_EORS(3, 5);
+}
+
+static u32 FASTCALL OP_EOR_S_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_IMM_VALUE;
+ OP_EORS(2, 4);
+}
+
+//-------------SUB-------------------------------------
+
+#define OP_SUB(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] - shift_op;\
+ if(REG_POS(i,12)==15)\
+ {\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ return a;
+
+#define OPSUBS(a, b) cpu->R[REG_POS(i,12)] = v - shift_op;\
+ if(REG_POS(i,12)==15)\
+ {\
+ Status_Reg SPSR = cpu->SPSR;\
+ armcpu_switchMode(cpu, SPSR.bits.mode);\
+ cpu->CPSR=SPSR;\
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
+ cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\
+ return a;
+
+static u32 FASTCALL OP_SUB_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OP_SUB(1, 3);
+}
+
+static u32 FASTCALL OP_SUB_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OP_SUB(2, 4);
+}
+
+static u32 FASTCALL OP_SUB_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OP_SUB(1, 3);
+}
+
+static u32 FASTCALL OP_SUB_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OP_SUB(2, 4);
+}
+
+static u32 FASTCALL OP_SUB_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OP_SUB(1, 3);
+}
+
+static u32 FASTCALL OP_SUB_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OP_SUB(2, 4);
+}
+
+static u32 FASTCALL OP_SUB_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OP_SUB(1, 3);
+}
+
+static u32 FASTCALL OP_SUB_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OP_SUB(2, 4);
+}
+
+static u32 FASTCALL OP_SUB_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OP_SUB(1, 3);
+}
+
+static u32 FASTCALL OP_SUB_S_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ LSL_IMM;
+ OPSUBS(2, 4);
+}
+
+static u32 FASTCALL OP_SUB_S_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ LSL_REG;
+ OPSUBS(3, 5);
+}
+
+static u32 FASTCALL OP_SUB_S_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ LSR_IMM;
+ OPSUBS(2, 4);
+}
+
+static u32 FASTCALL OP_SUB_S_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ LSR_REG;
+ OPSUBS(3, 5);
+}
+
+static u32 FASTCALL OP_SUB_S_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ ASR_IMM;
+ OPSUBS(2, 4);
+}
+
+static u32 FASTCALL OP_SUB_S_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ ASR_REG;
+ OPSUBS(3, 5);
+}
+
+static u32 FASTCALL OP_SUB_S_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ ROR_IMM;
+ OPSUBS(2, 4);
+}
+
+static u32 FASTCALL OP_SUB_S_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ ROR_REG;
+ OPSUBS(3, 5);
+}
+
+static u32 FASTCALL OP_SUB_S_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ IMM_VALUE;
+ OPSUBS(2, 4);
+}
+
+//------------------RSB------------------------
+
+#define OP_RSB(a, b) cpu->R[REG_POS(i,12)] = shift_op - cpu->R[REG_POS(i,16)];\
+ if(REG_POS(i,12)==15)\
+ {\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ return a;
+
+#define OP_RSBS(a, b) cpu->R[REG_POS(i,12)] = shift_op - v;\
+ if(REG_POS(i,12)==15)\
+ {\
+ Status_Reg SPSR = cpu->SPSR;\
+ armcpu_switchMode(cpu, SPSR.bits.mode);\
+ cpu->CPSR=SPSR;\
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
+ cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(shift_op, v, cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(shift_op, v, cpu->R[REG_POS(i,12)]);\
+ return a;
+
+static u32 FASTCALL OP_RSB_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OP_RSB(1, 3);
+}
+
+static u32 FASTCALL OP_RSB_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OP_RSB(2, 4);
+}
+
+static u32 FASTCALL OP_RSB_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OP_RSB(1, 3);
+}
+
+static u32 FASTCALL OP_RSB_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OP_RSB(2, 4);
+}
+
+static u32 FASTCALL OP_RSB_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OP_RSB(1, 3);
+}
+
+static u32 FASTCALL OP_RSB_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OP_RSB(2, 4);
+}
+
+static u32 FASTCALL OP_RSB_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OP_RSB(1, 3);
+}
+
+static u32 FASTCALL OP_RSB_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OP_RSB(2, 4);
+}
+
+static u32 FASTCALL OP_RSB_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OP_RSB(1, 3);
+}
+
+static u32 FASTCALL OP_RSB_S_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ LSL_IMM;
+ OP_RSBS(2, 4);
+}
+
+static u32 FASTCALL OP_RSB_S_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ LSL_REG;
+ OP_RSBS(3, 5);
+}
+
+static u32 FASTCALL OP_RSB_S_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ LSR_IMM;
+ OP_RSBS(2, 4);
+}
+
+static u32 FASTCALL OP_RSB_S_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ LSR_REG;
+ OP_RSBS(3, 5);
+}
+
+static u32 FASTCALL OP_RSB_S_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ ASR_IMM;
+ OP_RSBS(2, 4);
+}
+
+static u32 FASTCALL OP_RSB_S_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ ASR_REG;
+ OP_RSBS(3, 5);
+}
+
+static u32 FASTCALL OP_RSB_S_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ ROR_IMM;
+ OP_RSBS(2, 4);
+}
+
+static u32 FASTCALL OP_RSB_S_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ ROR_REG;
+ OP_RSBS(3, 5);
+}
+
+static u32 FASTCALL OP_RSB_S_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ IMM_VALUE;
+ OP_RSBS(2, 4);
+}
+
+//------------------ADD-----------------------------------
+
+#define OP_ADD(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] + shift_op;\
+ if(REG_POS(i,12)==15)\
+ {\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ return a;
+
+static u32 FASTCALL OP_ADD_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OP_ADD(1, 3);
+}
+
+static u32 FASTCALL OP_ADD_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OP_ADD(2, 4);
+}
+
+static u32 FASTCALL OP_ADD_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OP_ADD(1, 3);
+}
+
+static u32 FASTCALL OP_ADD_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OP_ADD(2, 4);
+}
+
+static u32 FASTCALL OP_ADD_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OP_ADD(1, 3);
+}
+
+static u32 FASTCALL OP_ADD_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OP_ADD(2, 4);
+}
+
+static u32 FASTCALL OP_ADD_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OP_ADD(1, 3);
+}
+
+static u32 FASTCALL OP_ADD_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OP_ADD(2, 4);
+}
+
+static u32 FASTCALL OP_ADD_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OP_ADD(1, 3);
+}
+
+#define OP_ADDS(a, b) cpu->R[REG_POS(i,12)] = v + shift_op;\
+ if(REG_POS(i,12)==15)\
+ {\
+ Status_Reg SPSR = cpu->SPSR;\
+ armcpu_switchMode(cpu, SPSR.bits.mode);\
+ cpu->CPSR=SPSR;\
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
+ cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.V = SIGNED_OVERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\
+ return a;
+
+static u32 FASTCALL OP_ADD_S_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ LSL_IMM;
+ OP_ADDS(2, 4);
+}
+
+static u32 FASTCALL OP_ADD_S_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ LSL_REG;
+ OP_ADDS(3, 5);
+}
+
+static u32 FASTCALL OP_ADD_S_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ LSR_IMM;
+ OP_ADDS(2, 4);
+}
+
+static u32 FASTCALL OP_ADD_S_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ LSR_REG;
+ OP_ADDS(3, 5);
+}
+
+static u32 FASTCALL OP_ADD_S_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ ASR_IMM;
+ OP_ADDS(2, 4);
+}
+
+static u32 FASTCALL OP_ADD_S_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ ASR_REG;
+ OP_ADDS(3, 5);
+}
+
+static u32 FASTCALL OP_ADD_S_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ ROR_IMM;
+ OP_ADDS(2, 4);
+}
+
+static u32 FASTCALL OP_ADD_S_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ ROR_REG;
+ OP_ADDS(3, 5);
+}
+
+static u32 FASTCALL OP_ADD_S_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ IMM_VALUE;
+ OP_ADDS(2, 4);
+}
+
+//------------------ADC-----------------------------------
+
+#define OP_ADC(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] + shift_op + cpu->CPSR.bits.C;\
+ if(REG_POS(i,12)==15)\
+ {\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ return a;
+
+static u32 FASTCALL OP_ADC_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OP_ADC(1, 3);
+}
+
+static u32 FASTCALL OP_ADC_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OP_ADC(2, 4);
+}
+
+static u32 FASTCALL OP_ADC_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OP_ADC(1, 3);
+}
+
+static u32 FASTCALL OP_ADC_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OP_ADC(2, 4);
+}
+
+static u32 FASTCALL OP_ADC_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OP_ADC(1, 3);
+}
+
+static u32 FASTCALL OP_ADC_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OP_ADC(2, 4);
+}
+
+static u32 FASTCALL OP_ADC_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OP_ADC(1, 3);
+}
+
+static u32 FASTCALL OP_ADC_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OP_ADC(2, 4);
+}
+
+static u32 FASTCALL OP_ADC_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OP_ADC(1, 3);
+}
+
+#define OP_ADCS(a, b) \
+ { \
+ u32 tmp = shift_op + cpu->CPSR.bits.C;\
+ cpu->R[REG_POS(i,12)] = v + tmp;\
+ if(REG_POS(i,12)==15)\
+ {\
+ Status_Reg SPSR = cpu->SPSR;\
+ armcpu_switchMode(cpu, SPSR.bits.mode);\
+ cpu->CPSR=SPSR;\
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
+ cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(shift_op, cpu->CPSR.bits.C, tmp) | UNSIGNED_OVERFLOW(v, tmp, cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.V = SIGNED_OVERFLOW(shift_op, cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(v, tmp, cpu->R[REG_POS(i,12)]);\
+ return a; \
+ }
+
+static u32 FASTCALL OP_ADC_S_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ LSL_IMM;
+ OP_ADCS(2, 4);
+}
+
+static u32 FASTCALL OP_ADC_S_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ LSL_REG;
+ OP_ADCS(3, 5);
+}
+
+static u32 FASTCALL OP_ADC_S_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ LSR_IMM;
+ OP_ADCS(2, 4);
+}
+
+static u32 FASTCALL OP_ADC_S_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ LSR_REG;
+ OP_ADCS(3, 5);
+}
+
+static u32 FASTCALL OP_ADC_S_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ ASR_IMM;
+ OP_ADCS(2, 4);
+}
+
+static u32 FASTCALL OP_ADC_S_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ ASR_REG;
+ OP_ADCS(3, 5);
+}
+
+static u32 FASTCALL OP_ADC_S_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ ROR_IMM;
+ OP_ADCS(2, 4);
+}
+
+static u32 FASTCALL OP_ADC_S_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ ROR_REG;
+ OP_ADCS(3, 5);
+}
+
+static u32 FASTCALL OP_ADC_S_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ IMM_VALUE;
+ OP_ADCS(2, 4);
+}
+
+//-------------SBC-------------------------------------
+
+#define OP_SBC(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] - shift_op - (!cpu->CPSR.bits.C);\
+ if(REG_POS(i,12)==15)\
+ {\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ return a;
+
+static u32 FASTCALL OP_SBC_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OP_SBC(1, 3);
+}
+
+static u32 FASTCALL OP_SBC_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OP_SBC(2, 4);
+}
+
+static u32 FASTCALL OP_SBC_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OP_SBC(1, 3);
+}
+
+static u32 FASTCALL OP_SBC_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OP_SBC(2, 4);
+}
+
+static u32 FASTCALL OP_SBC_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OP_SBC(1, 3);
+}
+
+static u32 FASTCALL OP_SBC_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OP_SBC(2, 4);
+}
+
+static u32 FASTCALL OP_SBC_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OP_SBC(1, 3);
+}
+
+static u32 FASTCALL OP_SBC_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OP_SBC(2, 4);
+}
+
+static u32 FASTCALL OP_SBC_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OP_SBC(1, 3);
+}
+
+#define OP_SBCS(a, b) \
+ { \
+ u32 tmp = v - (!cpu->CPSR.bits.C);\
+ cpu->R[REG_POS(i,12)] = tmp - shift_op;\
+ if(REG_POS(i,12)==15)\
+ {\
+ Status_Reg SPSR = cpu->SPSR;\
+ armcpu_switchMode(cpu, SPSR.bits.mode);\
+ cpu->CPSR=SPSR;\
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
+ cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(v, (!cpu->CPSR.bits.C), tmp)) & (!UNSIGNED_UNDERFLOW(tmp, shift_op, cpu->R[REG_POS(i,12)]));\
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(v, (!cpu->CPSR.bits.C), tmp) | SIGNED_UNDERFLOW(tmp, shift_op, cpu->R[REG_POS(i,12)]);\
+ return a; \
+ }
+
+static u32 FASTCALL OP_SBC_S_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ LSL_IMM;
+ OP_SBCS(2, 4);
+}
+
+static u32 FASTCALL OP_SBC_S_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ LSL_REG;
+ OP_SBCS(3, 5);
+}
+
+static u32 FASTCALL OP_SBC_S_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ LSR_IMM;
+ OP_SBCS(2, 4);
+}
+
+static u32 FASTCALL OP_SBC_S_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ LSR_REG;
+ OP_SBCS(3, 5);
+}
+
+static u32 FASTCALL OP_SBC_S_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ ASR_IMM;
+ OP_SBCS(2, 4);
+}
+
+static u32 FASTCALL OP_SBC_S_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ ASR_REG;
+ OP_SBCS(3, 5);
+}
+
+static u32 FASTCALL OP_SBC_S_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ ROR_IMM;
+ OP_SBCS(2, 4);
+}
+
+static u32 FASTCALL OP_SBC_S_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ ROR_REG;
+ OP_SBCS(3, 5);
+}
+
+static u32 FASTCALL OP_SBC_S_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ IMM_VALUE;
+ OP_SBCS(2, 4);
+}
+
+//---------------RSC----------------------------------
+
+#define OP_RSC(a, b) cpu->R[REG_POS(i,12)] = shift_op - cpu->R[REG_POS(i,16)] - (!cpu->CPSR.bits.C);\
+ if(REG_POS(i,12)==15)\
+ {\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ return a;
+
+static u32 FASTCALL OP_RSC_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OP_RSC(1, 3);
+}
+
+static u32 FASTCALL OP_RSC_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OP_RSC(2, 4);
+}
+
+static u32 FASTCALL OP_RSC_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OP_RSC(1, 3);
+}
+
+static u32 FASTCALL OP_RSC_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OP_RSC(2, 4);
+}
+
+static u32 FASTCALL OP_RSC_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OP_RSC(1, 3);
+}
+
+static u32 FASTCALL OP_RSC_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OP_RSC(2, 4);
+}
+
+static u32 FASTCALL OP_RSC_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OP_RSC(1, 3);
+}
+
+static u32 FASTCALL OP_RSC_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OP_RSC(2, 4);
+}
+
+static u32 FASTCALL OP_RSC_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OP_RSC(1, 3);
+}
+
+#define OP_RSCS(a,b) \
+ { \
+ u32 tmp = shift_op - (!cpu->CPSR.bits.C);\
+ cpu->R[REG_POS(i,12)] = tmp - v;\
+ if(REG_POS(i,12)==15)\
+ {\
+ Status_Reg SPSR = cpu->SPSR;\
+ armcpu_switchMode(cpu, SPSR.bits.mode);\
+ cpu->CPSR=SPSR;\
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
+ cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(shift_op, (!cpu->CPSR.bits.C), tmp)) & (!UNSIGNED_UNDERFLOW(tmp, v, cpu->R[REG_POS(i,12)]));\
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(shift_op, (!cpu->CPSR.bits.C), tmp) | SIGNED_UNDERFLOW(tmp, v, cpu->R[REG_POS(i,12)]);\
+ return a; \
+ }
+
+static u32 FASTCALL OP_RSC_S_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ LSL_IMM;
+ OP_RSCS(2,4);
+}
+
+static u32 FASTCALL OP_RSC_S_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ LSL_REG;
+ OP_RSCS(3,5);
+}
+
+static u32 FASTCALL OP_RSC_S_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ LSR_IMM;
+ OP_RSCS(2,4);
+}
+
+static u32 FASTCALL OP_RSC_S_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ LSR_REG;
+ OP_RSCS(3,5);
+}
+
+static u32 FASTCALL OP_RSC_S_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ ASR_IMM;
+ OP_RSCS(2,4);
+}
+
+static u32 FASTCALL OP_RSC_S_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ ASR_REG;
+ OP_RSCS(3,5);
+}
+
+static u32 FASTCALL OP_RSC_S_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ u32 shift_op;
+ ROR_IMM;
+ OP_RSCS(2,4);
+}
+
+static u32 FASTCALL OP_RSC_S_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ ROR_REG;
+ OP_RSCS(3,5);
+}
+
+static u32 FASTCALL OP_RSC_S_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,16)];
+ IMM_VALUE;
+ OP_RSCS(2,4);
+}
+
+//-------------------TST----------------------------
+
+#define OP_TST(a) \
+ { \
+ unsigned tmp = cpu->R[REG_POS(i,16)] & shift_op;\
+ cpu->CPSR.bits.C = c;\
+ cpu->CPSR.bits.N = BIT31(tmp);\
+ cpu->CPSR.bits.Z = (tmp==0);\
+ return a; \
+ }
+
+static u32 FASTCALL OP_TST_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_IMM;
+ OP_TST(1);
+}
+
+static u32 FASTCALL OP_TST_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_REG;
+ OP_TST(2);
+}
+
+static u32 FASTCALL OP_TST_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_IMM;
+ OP_TST(1);
+}
+
+static u32 FASTCALL OP_TST_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_REG;
+ OP_TST(2);
+}
+
+static u32 FASTCALL OP_TST_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_IMM;
+ OP_TST(1);
+}
+
+static u32 FASTCALL OP_TST_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_REG;
+ OP_TST(2);
+}
+
+static u32 FASTCALL OP_TST_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_IMM;
+ OP_TST(1);
+}
+
+static u32 FASTCALL OP_TST_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_REG;
+ OP_TST(2);
+}
+
+static u32 FASTCALL OP_TST_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_IMM_VALUE;
+ OP_TST(1);
+}
+
+//-------------------TEQ----------------------------
+
+#define OP_TEQ(a) \
+ { \
+ unsigned tmp = cpu->R[REG_POS(i,16)] ^ shift_op;\
+ cpu->CPSR.bits.C = c;\
+ cpu->CPSR.bits.N = BIT31(tmp);\
+ cpu->CPSR.bits.Z = (tmp==0);\
+ return a; \
+ }
+
+static u32 FASTCALL OP_TEQ_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_IMM;
+ OP_TEQ(1);
+}
+
+static u32 FASTCALL OP_TEQ_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_REG;
+ OP_TEQ(2);
+}
+
+static u32 FASTCALL OP_TEQ_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_IMM;
+ OP_TEQ(1);
+}
+
+static u32 FASTCALL OP_TEQ_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_REG;
+ OP_TEQ(2);
+}
+
+static u32 FASTCALL OP_TEQ_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_IMM;
+ OP_TEQ(1);
+}
+
+static u32 FASTCALL OP_TEQ_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_REG;
+ OP_TEQ(2);
+}
+
+static u32 FASTCALL OP_TEQ_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_IMM;
+ OP_TEQ(1);
+}
+
+static u32 FASTCALL OP_TEQ_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_REG;
+ OP_TEQ(2);
+}
+
+static u32 FASTCALL OP_TEQ_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_IMM_VALUE;
+ OP_TEQ(1);
+}
+
+//-------------CMP-------------------------------------
+
+#define OP_CMP(a) \
+ { \
+ u32 tmp = cpu->R[REG_POS(i,16)] - shift_op;\
+ cpu->CPSR.bits.N = BIT31(tmp);\
+ cpu->CPSR.bits.Z = (tmp==0);\
+ cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\
+ return a; \
+ }
+
+static u32 FASTCALL OP_CMP_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OP_CMP(1);
+}
+
+static u32 FASTCALL OP_CMP_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OP_CMP(2);
+}
+
+static u32 FASTCALL OP_CMP_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OP_CMP(1);
+}
+
+static u32 FASTCALL OP_CMP_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OP_CMP(2);
+}
+
+static u32 FASTCALL OP_CMP_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OP_CMP(1);
+}
+
+static u32 FASTCALL OP_CMP_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OP_CMP(2);
+}
+
+static u32 FASTCALL OP_CMP_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OP_CMP(1);
+}
+
+static u32 FASTCALL OP_CMP_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OP_CMP(2);
+}
+
+static u32 FASTCALL OP_CMP_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OP_CMP(1);
+}
+
+//---------------CMN---------------------------
+
+#define OP_CMN(a) \
+ { \
+ u32 tmp = cpu->R[REG_POS(i,16)] + shift_op;\
+ cpu->CPSR.bits.N = BIT31(tmp);\
+ cpu->CPSR.bits.Z = (tmp==0);\
+ cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\
+ cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\
+ return a; \
+ }
+
+static u32 FASTCALL OP_CMN_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OP_CMN(1);
+}
+
+static u32 FASTCALL OP_CMN_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OP_CMN(2);
+}
+
+static u32 FASTCALL OP_CMN_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OP_CMN(1);
+}
+
+static u32 FASTCALL OP_CMN_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OP_CMN(2);
+}
+
+static u32 FASTCALL OP_CMN_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OP_CMN(1);
+}
+
+static u32 FASTCALL OP_CMN_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OP_CMN(2);
+}
+
+static u32 FASTCALL OP_CMN_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OP_CMN(1);
+}
+
+static u32 FASTCALL OP_CMN_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OP_CMN(2);
+}
+
+static u32 FASTCALL OP_CMN_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OP_CMN(1);
+}
+
+//------------------ORR-------------------
+
+#define OP_ORR(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;\
+ if(REG_POS(i,12)==15)\
+ {\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ return a;
+
+static u32 FASTCALL OP_ORR_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OP_ORR(1, 3);
+}
+
+static u32 FASTCALL OP_ORR_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OP_ORR(2, 4);
+}
+
+static u32 FASTCALL OP_ORR_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OP_ORR(1, 3);
+}
+
+static u32 FASTCALL OP_ORR_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OP_ORR(2, 4);
+}
+
+static u32 FASTCALL OP_ORR_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OP_ORR(1, 3);
+}
+
+static u32 FASTCALL OP_ORR_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OP_ORR(2, 4);
+}
+
+static u32 FASTCALL OP_ORR_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OP_ORR(1, 3);
+}
+
+static u32 FASTCALL OP_ORR_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OP_ORR(2, 4);
+}
+
+static u32 FASTCALL OP_ORR_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OP_ORR(1, 3);
+}
+
+static u32 FASTCALL OP_ORR_S_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_IMM;
+ cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
+ if(REG_POS(i,12)==15)
+ {
+ Status_Reg SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
+ cpu->next_instruction = cpu->R[15];
+ return 4;
+ }
+ cpu->CPSR.bits.C = c;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
+ return 2;
+}
+
+static u32 FASTCALL OP_ORR_S_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_REG;
+ cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
+ if(REG_POS(i,12)==15)
+ {
+ Status_Reg SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
+ cpu->next_instruction = cpu->R[15];
+ return 5;
+ }
+ cpu->CPSR.bits.C = c;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
+ return 3;
+}
+
+static u32 FASTCALL OP_ORR_S_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_IMM;
+ cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
+ if(REG_POS(i,12)==15)
+ {
+ Status_Reg SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
+ cpu->next_instruction = cpu->R[15];
+ return 4;
+ }
+ cpu->CPSR.bits.C = c;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
+ return 2;
+}
+
+static u32 FASTCALL OP_ORR_S_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_REG;
+ cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
+ if(REG_POS(i,12)==15)
+ {
+ Status_Reg SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
+ cpu->next_instruction = cpu->R[15];
+ return 5;
+ }
+ cpu->CPSR.bits.C = c;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
+ return 3;
+}
+
+static u32 FASTCALL OP_ORR_S_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_IMM;
+ cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
+ if(REG_POS(i,12)==15)
+ {
+ Status_Reg SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
+ cpu->next_instruction = cpu->R[15];
+ return 4;
+ }
+ cpu->CPSR.bits.C = c;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
+ return 2;
+}
+
+static u32 FASTCALL OP_ORR_S_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_REG;
+ cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
+ if(REG_POS(i,12)==15)
+ {
+ Status_Reg SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
+ cpu->next_instruction = cpu->R[15];
+ return 5;
+ }
+ cpu->CPSR.bits.C = c;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
+ return 3;
+}
+
+static u32 FASTCALL OP_ORR_S_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_IMM;
+ cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
+ if(REG_POS(i,12)==15)
+ {
+ Status_Reg SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
+ cpu->next_instruction = cpu->R[15];
+ return 4;
+ }
+ cpu->CPSR.bits.C = c;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
+ return 2;
+}
+
+static u32 FASTCALL OP_ORR_S_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_REG;
+ cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
+ if(REG_POS(i,12)==15)
+ {
+ Status_Reg SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
+ cpu->next_instruction = cpu->R[15];
+ return 5;
+ }
+ cpu->CPSR.bits.C = c;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
+ return 3;
+}
+
+static u32 FASTCALL OP_ORR_S_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_IMM_VALUE;
+ cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;
+ if(REG_POS(i,12)==15)
+ {
+ Status_Reg SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));
+ cpu->next_instruction = cpu->R[15];
+ return 4;
+ }
+ cpu->CPSR.bits.C = c;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);
+ return 2;
+}
+
+//------------------MOV-------------------
+
+#define OP_MOV(a, b) cpu->R[REG_POS(i,12)] = shift_op;\
+ if(REG_POS(i,12)==15)\
+ {\
+ cpu->next_instruction = shift_op;\
+ return b;\
+ }\
+ return a;
+
+#define OP_MOV_S(a, b) cpu->R[REG_POS(i,12)] = shift_op;\
+ if(BIT20(i) && REG_POS(i,12)==15)\
+ {\
+ Status_Reg SPSR = cpu->SPSR;\
+ armcpu_switchMode(cpu, SPSR.bits.mode);\
+ cpu->CPSR=SPSR;\
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ cpu->CPSR.bits.C = c;\
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
+ return a;\
+
+static u32 FASTCALL OP_MOV_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OP_MOV(1,3);
+}
+
+static u32 FASTCALL OP_MOV_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ if (REG_POS(i,0) == 15) shift_op += 4;
+ OP_MOV(2,4);
+}
+
+static u32 FASTCALL OP_MOV_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OP_MOV(1,3);
+}
+
+static u32 FASTCALL OP_MOV_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ if (REG_POS(i,0) == 15) shift_op += 4;
+ OP_MOV(2,4);
+}
+
+static u32 FASTCALL OP_MOV_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OP_MOV(1,3);
+}
+
+static u32 FASTCALL OP_MOV_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OP_MOV(2,4);
+}
+
+static u32 FASTCALL OP_MOV_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OP_MOV(2,4);
+}
+
+static u32 FASTCALL OP_MOV_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OP_MOV(2,4);
+}
+
+static u32 FASTCALL OP_MOV_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OP_MOV(1,3);
+}
+
+static u32 FASTCALL OP_MOV_S_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_IMM;
+ OP_MOV_S(2,4);
+}
+
+static u32 FASTCALL OP_MOV_S_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_REG;
+ if (REG_POS(i,0) == 15) shift_op += 4;
+ OP_MOV_S(3,5);
+}
+
+static u32 FASTCALL OP_MOV_S_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_IMM;
+ OP_MOV_S(2,4);
+}
+
+static u32 FASTCALL OP_MOV_S_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_REG;
+ if (REG_POS(i,0) == 15) shift_op += 4;
+ OP_MOV_S(3,5);
+}
+
+static u32 FASTCALL OP_MOV_S_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_IMM;
+ OP_MOV_S(2,4);
+}
+
+static u32 FASTCALL OP_MOV_S_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_REG;
+ OP_MOV_S(3,5);
+}
+
+static u32 FASTCALL OP_MOV_S_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_IMM;
+ OP_MOV_S(2,4);
+}
+
+static u32 FASTCALL OP_MOV_S_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_REG;
+ OP_MOV_S(3,5);
+}
+
+static u32 FASTCALL OP_MOV_S_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_IMM_VALUE;
+ OP_MOV_S(2,4);
+}
+
+//------------------BIC-------------------
+#define OPP_BIC(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & (~shift_op);\
+ if(REG_POS(i,12)==15)\
+ {\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ return a;
+
+#define OPP_BIC_S(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & (~shift_op);\
+ if(REG_POS(i,12)==15)\
+ {\
+ Status_Reg SPSR = cpu->SPSR;\
+ armcpu_switchMode(cpu, SPSR.bits.mode);\
+ cpu->CPSR=SPSR;\
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ cpu->CPSR.bits.C = c;\
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
+ return a;
+
+static u32 FASTCALL OP_BIC_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OPP_BIC(1,3);
+}
+
+static u32 FASTCALL OP_BIC_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OPP_BIC(2,4);
+}
+
+static u32 FASTCALL OP_BIC_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OPP_BIC(1,3);
+}
+
+static u32 FASTCALL OP_BIC_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OPP_BIC(2,4);
+}
+
+static u32 FASTCALL OP_BIC_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OPP_BIC(1,3);
+}
+
+static u32 FASTCALL OP_BIC_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OPP_BIC(2,4);
+}
+
+static u32 FASTCALL OP_BIC_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OPP_BIC(1,3);
+}
+
+static u32 FASTCALL OP_BIC_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OPP_BIC(2,4);
+}
+
+static u32 FASTCALL OP_BIC_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OPP_BIC(1,3);
+}
+
+static u32 FASTCALL OP_BIC_S_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_IMM;
+ OPP_BIC_S(2,4);
+}
+
+static u32 FASTCALL OP_BIC_S_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_REG;
+ OPP_BIC_S(3,5);
+}
+
+static u32 FASTCALL OP_BIC_S_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_IMM;
+ OPP_BIC_S(2,4);
+}
+
+static u32 FASTCALL OP_BIC_S_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_REG;
+ OPP_BIC_S(3,5);
+}
+
+static u32 FASTCALL OP_BIC_S_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_IMM;
+ OPP_BIC_S(2,4);
+}
+
+static u32 FASTCALL OP_BIC_S_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_REG;
+ OPP_BIC_S(3,5);
+}
+
+static u32 FASTCALL OP_BIC_S_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_IMM;
+ OPP_BIC_S(2,4);
+}
+
+static u32 FASTCALL OP_BIC_S_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_REG;
+ OPP_BIC_S(3,5);
+}
+
+static u32 FASTCALL OP_BIC_S_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_IMM_VALUE;
+ OPP_BIC_S(2,4);
+}
+
+//------------------MVN-------------------
+#define OPP_MVN(a, b) cpu->R[REG_POS(i,12)] = ~shift_op;\
+ if(REG_POS(i,12)==15)\
+ {\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ return a;
+
+#define OPP_MVN_S(a, b) cpu->R[REG_POS(i,12)] = ~shift_op;\
+ if(REG_POS(i,12)==15)\
+ {\
+ Status_Reg SPSR = cpu->SPSR;\
+ armcpu_switchMode(cpu, SPSR.bits.mode);\
+ cpu->CPSR=SPSR;\
+ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1));\
+ cpu->next_instruction = cpu->R[15];\
+ return b;\
+ }\
+ cpu->CPSR.bits.C = c;\
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\
+ return a;
+
+static u32 FASTCALL OP_MVN_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSL_IMM;
+ OPP_MVN(1,3);
+}
+
+static u32 FASTCALL OP_MVN_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSL_REG;
+ OPP_MVN(2,4);
+}
+
+static u32 FASTCALL OP_MVN_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ LSR_IMM;
+ OPP_MVN(1,3);
+}
+
+static u32 FASTCALL OP_MVN_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ LSR_REG;
+ OPP_MVN(2,4);
+}
+
+static u32 FASTCALL OP_MVN_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ASR_IMM;
+ OPP_MVN(1,3);
+}
+
+static u32 FASTCALL OP_MVN_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ASR_REG;
+ OPP_MVN(2,4);
+}
+
+static u32 FASTCALL OP_MVN_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 shift_op;
+ ROR_IMM;
+ OPP_MVN(1,3);
+}
+
+static u32 FASTCALL OP_MVN_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ ROR_REG;
+ OPP_MVN(2,4);
+}
+
+static u32 FASTCALL OP_MVN_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+ OPP_MVN(1,3);
+}
+
+static u32 FASTCALL OP_MVN_S_LSL_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_IMM;
+ OPP_MVN_S(2,4);
+}
+
+static u32 FASTCALL OP_MVN_S_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSL_REG;
+ OPP_MVN_S(3,5);
+}
+
+static u32 FASTCALL OP_MVN_S_LSR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_IMM;
+ OPP_MVN_S(2,4);
+}
+
+static u32 FASTCALL OP_MVN_S_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_LSR_REG;
+ OPP_MVN_S(3,5);
+}
+
+static u32 FASTCALL OP_MVN_S_ASR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_IMM;
+ OPP_MVN_S(2,4);
+}
+
+static u32 FASTCALL OP_MVN_S_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ASR_REG;
+ OPP_MVN_S(3,5);
+}
+
+static u32 FASTCALL OP_MVN_S_ROR_IMM(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_IMM;
+ OPP_MVN_S(2,4);
+}
+
+static u32 FASTCALL OP_MVN_S_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_ROR_REG;
+ OPP_MVN_S(3,5);
+}
+
+static u32 FASTCALL OP_MVN_S_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ S_IMM_VALUE;
+ OPP_MVN_S(2,4);
+}
+
+//-------------MUL------------------------
+#define OPP_M(a,b) v >>= 8;\
+ if((v==0)||(v==0xFFFFFF))\
+ return b;\
+ v >>= 8;\
+ if((v==0)||(v==0xFFFF))\
+ return b+1;\
+ v >>= 8;\
+ if((v==0)||(v==0xFF))\
+ return b+2;\
+ return a;\
+
+static u32 FASTCALL OP_MUL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,16)] = cpu->R[REG_POS(i,8)] * v;
+ OPP_M(5,2);
+}
+
+static u32 FASTCALL OP_MLA(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,0)];
+ u32 a = cpu->R[REG_POS(i,8)];
+ u32 b = cpu->R[REG_POS(i,12)];
+ cpu->R[REG_POS(i,16)] = a * v + b;
+
+ OPP_M(6,3);
+}
+
+static u32 FASTCALL OP_MUL_S(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,16)] = cpu->R[REG_POS(i,8)] * v;
+
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0);
+
+ OPP_M(6,3);
+}
+
+static u32 FASTCALL OP_MLA_S(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,16)] = cpu->R[REG_POS(i,8)] * v + cpu->R[REG_POS(i,12)];
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0);
+ OPP_M(7,4);
+}
+
+//----------UMUL--------------------------
+
+static u32 FASTCALL OP_UMULL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,0)];
+ u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)];
+
+ cpu->R[REG_POS(i,12)] = (u32)res;
+ cpu->R[REG_POS(i,16)] = (u32)(res>>32);
+
+ OPP_M(6,3);
+}
+
+static u32 FASTCALL OP_UMLAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,0)];
+ u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)] + (u64)cpu->R[REG_POS(i,12)];
+
+ cpu->R[REG_POS(i,12)] = (u32)res;
+ cpu->R[REG_POS(i,16)] += (u32)(res>>32);
+
+ OPP_M(7,4);
+}
+
+static u32 FASTCALL OP_UMULL_S(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,0)];
+ u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)];
+
+ cpu->R[REG_POS(i,12)] = (u32)res;
+ cpu->R[REG_POS(i,16)] = (u32)(res>>32);
+
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0);
+
+ OPP_M(7,4);
+}
+
+static u32 FASTCALL OP_UMLAL_S(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_POS(i,0)];
+ u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)] + (u64)cpu->R[REG_POS(i,12)];
+
+ cpu->R[REG_POS(i,12)] = (u32)res;
+ cpu->R[REG_POS(i,16)] += (u32)(res>>32);
+
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0);
+
+ OPP_M(8,5);
+}
+
+//----------SMUL--------------------------
+
+static u32 FASTCALL OP_SMULL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ s64 v = (s32)cpu->R[REG_POS(i,0)];
+ s64 b = (s32)cpu->R[REG_POS(i,8)];
+ s64 res = v * b;
+
+ cpu->R[REG_POS(i,12)] = (u32)(res&0xFFFFFFFF);
+ cpu->R[REG_POS(i,16)] = (u32)(res>>32);
+
+ v &= 0xFFFFFFFF;
+
+ OPP_M(6,3);
+}
+
+static u32 FASTCALL OP_SMLAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+
+ s64 v = (s32)cpu->R[REG_POS(i,0)];
+ s64 b = (s32)cpu->R[REG_POS(i,8)];
+ s64 res = v * b + (u64)cpu->R[REG_POS(i,12)];
+
+ //LOG("%08X * %08X + %08X%08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], cpu->R[REG_POS(i,16)], cpu->R[REG_POS(i,12)]);
+
+ cpu->R[REG_POS(i,12)] = (u32)res;
+ cpu->R[REG_POS(i,16)] += (u32)(res>>32);
+
+ //LOG("= %08X%08X %08X%08X\r\n", cpu->R[REG_POS(i,16)], cpu->R[REG_POS(i,12)], res);
+
+ v &= 0xFFFFFFFF;
+
+ OPP_M(7,4);
+}
+
+static u32 FASTCALL OP_SMULL_S(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ s64 v = (s32)cpu->R[REG_POS(i,0)];
+ s64 b = (s32)cpu->R[REG_POS(i,8)];
+ s64 res = v * b;
+
+ cpu->R[REG_POS(i,12)] = (u32)res;
+ cpu->R[REG_POS(i,16)] = (u32)(res>>32);
+
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0);
+
+ v &= 0xFFFFFFFF;
+
+ OPP_M(7,4);
+}
+
+static u32 FASTCALL OP_SMLAL_S(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ s64 v = (s32)cpu->R[REG_POS(i,0)];
+ s64 b = (s32)cpu->R[REG_POS(i,8)];
+ s64 res = v * b + (u64)cpu->R[REG_POS(i,12)];
+
+ cpu->R[REG_POS(i,12)] = (u32)res;
+ cpu->R[REG_POS(i,16)] += (u32)(res>>32);
+
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]);
+ cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0);
+
+ v &= 0xFFFFFFFF;
+
+ OPP_M(8,5);
+}
+
+//---------------SWP------------------------------
+
+static u32 FASTCALL OP_SWP(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ u32 tmp = ROR(READ32(cpu->mem_if->data, adr), ((cpu->R[REG_POS(i,16)]&3)<<3));
+
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,0)]);
+ cpu->R[REG_POS(i,12)] = tmp;
+
+ return 4 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]*2;
+}
+
+static u32 FASTCALL OP_SWPB(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ u8 tmp = READ8(cpu->mem_if->data, adr);
+ WRITE8(cpu->mem_if->data, adr, (u8)(cpu->R[REG_POS(i,0)]&0xFF));
+ cpu->R[REG_POS(i,12)] = tmp;
+
+ return 4 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]*2;
+}
+
+//------------LDRH-----------------------------
+
+static u32 FASTCALL OP_LDRH_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
+ cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
+ cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_P_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_M_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_PRE_INDE_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_PRE_INDE_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
+
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_PRE_INDE_P_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] =(u32)READ16(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_PRE_INDE_M_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_POS_INDE_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] += IMM_OFF;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_POS_INDE_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] -= IMM_OFF;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_POS_INDE_P_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)];
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_POS_INDE_M_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ cpu->R[REG_POS(i,12)] = (u32)READ16(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)];
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+//------------STRH-----------------------------
+
+static u32 FASTCALL OP_STRH_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_P_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_M_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_PRE_INDE_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
+ cpu->R[REG_POS(i,16)] = adr;
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_PRE_INDE_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_PRE_INDE_P_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_PRE_INDE_M_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_POS_INDE_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] += IMM_OFF;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_POS_INDE_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] -= IMM_OFF;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_POS_INDE_P_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)];
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_POS_INDE_M_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)];
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+//----------------LDRSH--------------------------
+
+static u32 FASTCALL OP_LDRSH_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
+ cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSH_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
+ cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSH_P_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSH_M_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSH_PRE_INDE_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
+ cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSH_PRE_INDE_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
+ cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSH_PRE_INDE_P_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSH_PRE_INDE_M_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSH_POS_INDE_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] += IMM_OFF;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSH_POS_INDE_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] -= IMM_OFF;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSH_POS_INDE_P_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)];
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSH_POS_INDE_M_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ cpu->R[REG_POS(i,12)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)];
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+//----------------------LDRSB----------------------
+
+static u32 FASTCALL OP_LDRSB_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
+ cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSB_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
+ cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSB_P_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSB_M_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSB_PRE_INDE_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF;
+ cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSB_PRE_INDE_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF;
+ cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSB_PRE_INDE_P_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSB_PRE_INDE_M_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)];
+ cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSB_POS_INDE_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] += IMM_OFF;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSB_POS_INDE_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] -= IMM_OFF;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSB_POS_INDE_P_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)];
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSB_POS_INDE_M_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ cpu->R[REG_POS(i,12)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+ cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)];
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+//--------------MRS--------------------------------
+
+static u32 FASTCALL OP_MRS_CPSR(armcpu_t *cpu)
+{
+ cpu->R[REG_POS(cpu->instruction,12)] = cpu->CPSR.val;
+
+ return 1;
+}
+
+static u32 FASTCALL OP_MRS_SPSR(armcpu_t *cpu)
+{
+ cpu->R[REG_POS(cpu->instruction,12)] = cpu->SPSR.val;
+
+ return 1;
+}
+
+//--------------MSR--------------------------------
+
+static u32 FASTCALL OP_MSR_CPSR(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 operand = cpu->R[REG_POS(i,0)];
+
+ if(cpu->CPSR.bits.mode!=USR)
+ {
+ if(BIT16(i))
+ {
+ armcpu_switchMode(cpu, operand & 0x1F);
+ cpu->CPSR.val = (cpu->CPSR.val & 0xFFFFFF00) | (operand & 0xFF);
+ }
+ if(BIT17(i))
+ cpu->CPSR.val = (cpu->CPSR.val & 0xFFFF00FF) | (operand & 0xFF00);
+ if(BIT18(i))
+ cpu->CPSR.val = (cpu->CPSR.val & 0xFF00FFFF) | (operand & 0xFF0000);
+ }
+ if(BIT19(i))
+ cpu->CPSR.val = (cpu->CPSR.val & 0x00FFFFFF) | (operand & 0xFF000000);
+
+ return 1;
+}
+
+static u32 FASTCALL OP_MSR_SPSR(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 operand = cpu->R[REG_POS(i,0)];
+
+ if(cpu->CPSR.bits.mode!=USR)
+ {
+ if(BIT16(i))
+ {
+ cpu->SPSR.val = (cpu->SPSR.val & 0xFFFFFF00) | (operand & 0XFF);
+ }
+ if(BIT17(i))
+ cpu->SPSR.val = (cpu->SPSR.val & 0xFFFF00FF) | (operand & 0XFF00);
+ if(BIT18(i))
+ cpu->SPSR.val = (cpu->SPSR.val & 0xFF00FFFF) | (operand & 0XFF0000);
+ }
+ if(BIT19(i))
+ cpu->SPSR.val = (cpu->SPSR.val & 0x00FFFFFF) | (operand & 0XFF000000);
+
+ return 1;
+}
+
+static u32 FASTCALL OP_MSR_CPSR_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+
+ if(cpu->CPSR.bits.mode!=USR)
+ {
+ if(BIT16(i))
+ {
+ armcpu_switchMode(cpu, shift_op & 0x1F);
+ cpu->CPSR.val = (cpu->CPSR.val & 0xFFFFFF00) | (shift_op & 0XFF);
+ }
+ if(BIT17(i))
+ cpu->CPSR.val = (cpu->CPSR.val & 0xFFFF00FF) | (shift_op & 0XFF00);
+ if(BIT18(i))
+ cpu->CPSR.val = (cpu->CPSR.val & 0xFF00FFFF) | (shift_op & 0XFF0000);
+ }
+ if(BIT19(i))
+ {
+ //cpu->CPSR.val = (cpu->CPSR.val & 0xFF000000) | (shift_op & 0XFF000000);
+ cpu->CPSR.val = (cpu->CPSR.val & 0x00FFFFFF) | (shift_op & 0xFF000000);
+ }
+
+ return 1;
+}
+
+static u32 FASTCALL OP_MSR_SPSR_IMM_VAL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ IMM_VALUE;
+
+ if(cpu->CPSR.bits.mode!=USR)
+ {
+ if(BIT16(i))
+ {
+ cpu->SPSR.val = (cpu->SPSR.val & 0xFFFFFF00) | (shift_op & 0XFF);
+ }
+ if(BIT17(i))
+ cpu->SPSR.val = (cpu->SPSR.val & 0xFFFF00FF) | (shift_op & 0XFF00);
+ if(BIT18(i))
+ cpu->SPSR.val = (cpu->SPSR.val & 0xFF00FFFF) | (shift_op & 0XFF0000);
+ }
+ if(BIT19(i))
+ cpu->SPSR.val = (cpu->SPSR.val & 0xFF000000) | (shift_op & 0XFF000000);
+
+ return 1;
+}
+
+//-----------------BRANCH--------------------------
+
+static u32 FASTCALL OP_BX(armcpu_t *cpu)
+{
+ u32 tmp = cpu->R[REG_POS(cpu->instruction, 0)];
+
+ cpu->CPSR.bits.T = BIT0(tmp);
+ cpu->R[15] = tmp & 0xFFFFFFFE;
+ cpu->next_instruction = cpu->R[15];
+ return 3;
+}
+
+static u32 FASTCALL OP_BLX_REG(armcpu_t *cpu)
+{
+ u32 tmp = cpu->R[REG_POS(cpu->instruction, 0)];
+
+ cpu->R[14] = cpu->next_instruction;
+ cpu->CPSR.bits.T = BIT0(tmp);
+ cpu->R[15] = tmp & 0xFFFFFFFE;
+ cpu->next_instruction = cpu->R[15];
+ return 3;
+}
+
+#define SIGNEXTEND_24(i) (((s32)((i)<<8))>>8)
+
+static u32 FASTCALL OP_B(armcpu_t *cpu)
+{
+ u32 off = SIGNEXTEND_24(cpu->instruction);
+ if(CONDITION(cpu->instruction)==0xF)
+ {
+ cpu->R[14] = cpu->next_instruction;
+ cpu->CPSR.bits.T = 1;
+ }
+ cpu->R[15] += (off<<2);
+ cpu->next_instruction = cpu->R[15];
+
+ return 3;
+}
+
+static u32 FASTCALL OP_BL(armcpu_t *cpu)
+{
+ u32 off = SIGNEXTEND_24(cpu->instruction);
+ if(CONDITION(cpu->instruction)==0xF)
+ {
+ cpu->CPSR.bits.T = 1;
+ cpu->R[15] += 2;
+ }
+ cpu->R[14] = cpu->next_instruction;
+ cpu->R[15] += (off<<2);
+ cpu->next_instruction = cpu->R[15];
+
+ return 3;
+}
+
+//----------------CLZ-------------------------------
+
+u8 CLZ_TAB[16]=
+{
+ 0, // 0000
+ 1, // 0001
+ 2, 2, // 001X
+ 3, 3, 3, 3, // 01XX
+ 4, 4, 4, 4, 4, 4, 4, 4 // 1XXX
+};
+
+static u32 FASTCALL OP_CLZ(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 Rm = cpu->R[REG_POS(i,0)];
+ u32 pos;
+
+ if(Rm==0)
+ {
+ cpu->R[REG_POS(i,12)]=32;
+ return 2;
+ }
+
+ Rm |= (Rm >>1);
+ Rm |= (Rm >>2);
+ Rm |= (Rm >>4);
+ Rm |= (Rm >>8);
+ Rm |= (Rm >>16);
+
+ pos =
+ CLZ_TAB[Rm&0xF] +
+ CLZ_TAB[(Rm>>4)&0xF] +
+ CLZ_TAB[(Rm>>8)&0xF] +
+ CLZ_TAB[(Rm>>12)&0xF] +
+ CLZ_TAB[(Rm>>16)&0xF] +
+ CLZ_TAB[(Rm>>20)&0xF] +
+ CLZ_TAB[(Rm>>24)&0xF] +
+ CLZ_TAB[(Rm>>28)&0xF];
+
+ cpu->R[REG_POS(i,12)]=32 - pos;
+
+ return 2;
+}
+
+//--------------------QADD--QSUB------------------------------
+
+static u32 FASTCALL OP_QADD(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 res = cpu->R[REG_POS(i,16)]+cpu->R[REG_POS(i,0)];
+
+ LOG("spe add\r\n");
+ if(SIGNED_OVERFLOW(cpu->R[REG_POS(i,16)],cpu->R[REG_POS(i,0)], res))
+ {
+ cpu->CPSR.bits.Q=1;
+ cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res);
+ return 2;
+ }
+ cpu->R[REG_POS(i,12)]=res;
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] &= 0XFFFFFFFC;
+ cpu->next_instruction = cpu->R[15];
+ return 3;
+ }
+ return 2;
+}
+
+static u32 FASTCALL OP_QSUB(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 res = cpu->R[REG_POS(i,0)]-cpu->R[REG_POS(i,16)];
+
+ LOG("spe add\r\n");
+ if(SIGNED_UNDERFLOW(cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,16)], res))
+ {
+ cpu->CPSR.bits.Q=1;
+ cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res);
+ return 2;
+ }
+ cpu->R[REG_POS(i,12)]=res;
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] &= 0XFFFFFFFC;
+ cpu->next_instruction = cpu->R[15];
+ return 3;
+ }
+ return 2;
+}
+
+static u32 FASTCALL OP_QDADD(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 mul = cpu->R[REG_POS(i,16)]<<1;
+ u32 res;
+
+
+ LOG("spe add\r\n");
+ if(BIT31(cpu->R[REG_POS(i,16)])!=BIT31(mul))
+ {
+ cpu->CPSR.bits.Q=1;
+ mul = 0x80000000-BIT31(mul);
+ }
+
+ res = mul + cpu->R[REG_POS(i,0)];
+ if(SIGNED_OVERFLOW(cpu->R[REG_POS(i,0)],mul, res))
+ {
+ cpu->CPSR.bits.Q=1;
+ cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res);
+ return 2;
+ }
+ cpu->R[REG_POS(i,12)]=res;
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] &= 0XFFFFFFFC;
+ cpu->next_instruction = cpu->R[15];
+ return 3;
+ }
+ return 2;
+}
+
+static u32 FASTCALL OP_QDSUB(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 mul = cpu->R[REG_POS(i,16)]<<1;
+ u32 res;
+
+
+ LOG("spe add\r\n");
+ if(BIT31(cpu->R[REG_POS(i,16)])!=BIT31(mul))
+ {
+ cpu->CPSR.bits.Q=1;
+ mul = 0x80000000-BIT31(mul);
+ }
+
+ res = cpu->R[REG_POS(i,0)] - mul;
+ if(SIGNED_UNDERFLOW(cpu->R[REG_POS(i,0)], mul, res))
+ {
+ cpu->CPSR.bits.Q=1;
+ cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res);
+ return 2;
+ }
+ cpu->R[REG_POS(i,12)]=res;
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] &= 0XFFFFFFFC;
+ cpu->next_instruction = cpu->R[15];
+ return 3;
+ }
+ return 2;
+}
+
+//-----------------SMUL-------------------------------
+
+#define HWORD(i) ((s32)(((s32)(i))>>16))
+#define LWORD(i) (s32)(((s32)((i)<<16))>>16)
+
+static u32 FASTCALL OP_SMUL_B_B(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+
+ cpu->R[REG_POS(i,16)] = (u32)(LWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)]));
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SMUL_B_T(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+
+ cpu->R[REG_POS(i,16)] = (u32)(LWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)]));
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SMUL_T_B(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+
+ cpu->R[REG_POS(i,16)] = (u32)(HWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)]));
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SMUL_T_T(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+
+ cpu->R[REG_POS(i,16)] = (u32)(HWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)]));
+
+ return 2;
+}
+
+//-----------SMLA----------------------------
+
+static u32 FASTCALL OP_SMLA_B_B(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 tmp = (u32)(LWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)]));
+ u32 a = cpu->R[REG_POS(i,12)];
+
+ //LOG("SMLABB %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a);
+ cpu->R[REG_POS(i,16)] = tmp + a;
+
+ if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)]))
+ cpu->CPSR.bits.Q = 1;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SMLA_B_T(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 tmp = (u32)(LWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)]));
+ u32 a = cpu->R[REG_POS(i,12)];
+
+ //LOG("SMLABT %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a);
+ cpu->R[REG_POS(i,16)] = tmp + a;
+
+ if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)]))
+ cpu->CPSR.bits.Q = 1;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SMLA_T_B(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 tmp = (u32)(HWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)]));
+ u32 a = cpu->R[REG_POS(i,12)];
+
+ //LOG("SMLATB %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a);
+ cpu->R[REG_POS(i,16)] = tmp + a;
+
+ if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)]))
+ cpu->CPSR.bits.Q = 1;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SMLA_T_T(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 tmp = (u32)(HWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)]));
+ u32 a = cpu->R[REG_POS(i,12)];
+
+ //LOG("SMLATT %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a);
+ cpu->R[REG_POS(i,16)] = tmp + a;
+
+ if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)]))
+ cpu->CPSR.bits.Q = 1;
+
+ return 2;
+}
+
+//--------------SMLAL---------------------------------------
+
+static u32 FASTCALL OP_SMLAL_B_B(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ s64 tmp = (s64)(LWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)]));
+ u64 res = (u64)tmp + cpu->R[REG_POS(i,12)];
+
+ LOG("SMLALBB %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + (res + ((tmp<0)*0xFFFFFFFF))), (int)(u32) res);
+
+ cpu->R[REG_POS(i,12)] = (u32) res;
+ cpu->R[REG_POS(i,16)] += (res + ((tmp<0)*0xFFFFFFFF));
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SMLAL_B_T(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ s64 tmp = (s64)(LWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)]));
+ u64 res = (u64)tmp + cpu->R[REG_POS(i,12)];
+
+ LOG("SMLALBT %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + res + ((tmp<0)*0xFFFFFFFF)), (int)(u32) res);
+
+ cpu->R[REG_POS(i,12)] = (u32) res;
+ cpu->R[REG_POS(i,16)] += res + ((tmp<0)*0xFFFFFFFF);
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SMLAL_T_B(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ s64 tmp = (s64)(HWORD(cpu->R[REG_POS(i,0)])* (s64)LWORD(cpu->R[REG_POS(i,8)]));
+ u64 res = (u64)tmp + cpu->R[REG_POS(i,12)];
+
+ LOG("SMLALTB %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + res + ((tmp<0)*0xFFFFFFFF)), (int)(u32) res);
+
+ cpu->R[REG_POS(i,12)] = (u32) res;
+ cpu->R[REG_POS(i,16)] += res + ((tmp<0)*0xFFFFFFFF);
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SMLAL_T_T(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ s64 tmp = (s64)(HWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)]));
+ u64 res = (u64)tmp + cpu->R[REG_POS(i,12)];
+
+ LOG("SMLALTT %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + res + ((tmp<0)*0xFFFFFFFF)), (int)(u32) res);
+
+ cpu->R[REG_POS(i,12)] = (u32) res;
+ cpu->R[REG_POS(i,16)] += res + ((tmp<0)*0xFFFFFFFF);
+
+ return 2;
+}
+
+//--------------SMULW--------------------
+
+static u32 FASTCALL OP_SMULW_B(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ s64 tmp = (s64)LWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]);
+
+ //LOG("SMULWB %08X * %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], ((tmp>>16)&0xFFFFFFFF);
+
+ cpu->R[REG_POS(i,16)] = ((tmp>>16)&0xFFFFFFFF);
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SMULW_T(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ s64 tmp = (s64)HWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]);
+
+ //LOG("SMULWT %08X * %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], ((tmp>>16)&0xFFFFFFFF));
+
+ cpu->R[REG_POS(i,16)] = ((tmp>>16)&0xFFFFFFFF);
+
+ return 2;
+}
+
+//--------------SMLAW-------------------
+static u32 FASTCALL OP_SMLAW_B(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ s64 tmp = (s64)LWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]);
+ u32 a = cpu->R[REG_POS(i,12)];
+
+ //LOG("SMLAWB %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, (tmp>>16) + a);
+
+ tmp = (tmp>>16);
+
+ cpu->R[REG_POS(i,16)] = tmp + a;
+
+ if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)]))
+ cpu->CPSR.bits.Q = 1;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SMLAW_T(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ s64 tmp = (s64)HWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]);
+ u32 a = cpu->R[REG_POS(i,12)];
+
+ //LOG("SMLAWT %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, ((tmp>>16)&0xFFFFFFFF) + a);
+
+ tmp = ((tmp>>16)&0xFFFFFFFF);
+ cpu->R[REG_POS(i,16)] = tmp + a;
+
+ if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)]))
+ cpu->CPSR.bits.Q = 1;
+
+ return 2;
+}
+
+//------------LDR---------------------------
+
+static u32 FASTCALL OP_LDR_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
+ u32 val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,12)] = val;
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
+ u32 val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_LSL_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_LSL_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_LSR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_LSR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_ASR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_ASR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_ROR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_ROR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,12)] = val;
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
+ u32 val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
+ u32 val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ u32 val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+//------------------------------------------------------------
+static u32 FASTCALL OP_LDR_P_IMM_OFF_POSTIND2(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+
+ u32 adr = cpu->R[REG_POS(i,16)];
+ u32 val = READ32(cpu->mem_if->data, adr);
+ u32 old;
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ old = armcpu_switchMode(cpu, USR);
+ cpu->R[REG_POS(i,12)] = val;
+ armcpu_switchMode(cpu, old);
+
+ cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+//------------------------------------------------------------
+
+static u32 FASTCALL OP_LDR_M_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ u32 val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ32(cpu->mem_if->data, adr);
+
+ if(adr&3)
+ val = ROR(val, 8*(adr&3));
+
+ if(REG_POS(i,12)==15)
+ {
+ cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1));
+ cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit;
+ cpu->next_instruction = cpu->R[15];
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+ return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ }
+
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+//-----------------LDRB-------------------------------------------
+
+static u32 FASTCALL OP_LDRB_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
+ u32 val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
+ u32 val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_LSL_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_LSL_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_LSR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_LSR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_ASR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_ASR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_ROR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_ROR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
+ u32 val = READ8(cpu->mem_if->data, adr);
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
+ u32 val = READ8(cpu->mem_if->data, adr);
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ u32 val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ u32 val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+ cpu->R[REG_POS(i,12)] = val;
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+//----------------------STR--------------------------------
+
+static u32 FASTCALL OP_STR_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+
+// execute = false;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_LSL_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_LSL_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_LSR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_LSR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_ASR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_ASR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_ROR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_ROR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+//-----------------------STRB-------------------------------------
+
+static u32 FASTCALL OP_STRB_P_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_LSL_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_LSL_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_LSR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_LSR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_ASR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_ASR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_ROR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_ROR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12;
+ WRITE8(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] + shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)] - shift_op;
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr;
+ u32 shift_op;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+//-----------------------LDRBT-------------------------------------
+
+static u32 FASTCALL OP_LDRBT_P_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 val;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+ i = cpu->instruction;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+ cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRBT_M_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 val;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+ //execute = false;
+ LOG("Untested opcode: OP_LDRBT_M_IMM_OFF_POSTIND\n");
+
+
+ i = cpu->instruction;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+ cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRBT_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+ oldmode = armcpu_switchMode(cpu, SYS);
+ //execute = false;
+ LOG("Untested opcode: OP_LDRBT_P_LSL_IMM_OFF_POSTIND");
+
+
+ i = cpu->instruction;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRBT_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+ //execute = false;
+ LOG("Untested opcode: OP_LDRBT_M_LSL_IMM_OFF_POSTIND");
+
+
+ i = cpu->instruction;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRBT_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+ //execute = false;
+ LOG("Untested opcode: OP_LDRBT_P_LSR_IMM_OFF_POSTIND");
+
+
+ i = cpu->instruction;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRBT_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+ //execute = false;
+ LOG("Untested opcode: OP_LDRBT_M_LSR_IMM_OFF_POSTIND");
+
+
+ i = cpu->instruction;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRBT_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+ //execute = false;
+ LOG("Untested opcode: OP_LDRBT_P_ASR_IMM_OFF_POSTIND");
+
+
+ i = cpu->instruction;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRBT_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+ //execute = false;
+ LOG("Untested opcode: OP_LDRBT_M_ASR_IMM_OFF_POSTIND");
+
+
+ i = cpu->instruction;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRBT_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+ //execute = false;
+ LOG("Untested opcode: OP_LDRBT_P_ROR_IMM_OFF_POSTIND");
+
+
+ i = cpu->instruction;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRBT_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 val;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+ //execute = false;
+ LOG("Untested opcode: OP_LDRBT_M_ROR_IMM_OFF_POSTIND");
+
+
+ i = cpu->instruction;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ val = READ8(cpu->mem_if->data, adr);
+ cpu->R[REG_POS(i,12)] = val;
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+//----------------------STRBT----------------------------
+
+static u32 FASTCALL OP_STRBT_P_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+
+ i = cpu->instruction;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRBT_M_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+
+ i = cpu->instruction;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRBT_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+
+ i = cpu->instruction;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRBT_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+
+ i = cpu->instruction;
+ LSL_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRBT_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+
+ i = cpu->instruction;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRBT_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+
+ i = cpu->instruction;
+ LSR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRBT_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+
+ i = cpu->instruction;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRBT_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+
+ i = cpu->instruction;
+ ASR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRBT_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+
+ i = cpu->instruction;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr + shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRBT_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu)
+{
+ u32 oldmode;
+ u32 i;
+ u32 adr;
+ u32 shift_op;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+
+ i = cpu->instruction;
+ ROR_IMM;
+ adr = cpu->R[REG_POS(i,16)];
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_POS(i,12)]);
+ cpu->R[REG_POS(i,16)] = adr - shift_op;
+
+ armcpu_switchMode(cpu, oldmode);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+//---------------------LDM-----------------------------
+
+#define OP_L_IA(reg, adr) if(BIT##reg(i))\
+ {\
+ registres[reg] = READ32(cpu->mem_if->data, start);\
+ c += waitState[(start>>24)&0xF];\
+ adr += 4;\
+ }
+
+#define OP_L_IB(reg, adr) if(BIT##reg(i))\
+ {\
+ adr += 4;\
+ registres[reg] = READ32(cpu->mem_if->data, start);\
+ c += waitState[(start>>24)&0xF];\
+ }
+
+#define OP_L_DA(reg, adr) if(BIT##reg(i))\
+ {\
+ registres[reg] = READ32(cpu->mem_if->data, start);\
+ c += waitState[(start>>24)&0xF];\
+ adr -= 4;\
+ }
+
+#define OP_L_DB(reg, adr) if(BIT##reg(i))\
+ {\
+ adr -= 4;\
+ registres[reg] = READ32(cpu->mem_if->data, start);\
+ c += waitState[(start>>24)&0xF];\
+ }
+
+static u32 FASTCALL OP_LDMIA(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 c = 0;
+ u32 start = cpu->R[REG_POS(i,16)];
+
+ u32 * registres = cpu->R;
+ u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ OP_L_IA(0, start);
+ OP_L_IA(1, start);
+ OP_L_IA(2, start);
+ OP_L_IA(3, start);
+ OP_L_IA(4, start);
+ OP_L_IA(5, start);
+ OP_L_IA(6, start);
+ OP_L_IA(7, start);
+ OP_L_IA(8, start);
+ OP_L_IA(9, start);
+ OP_L_IA(10, start);
+ OP_L_IA(11, start);
+ OP_L_IA(12, start);
+ OP_L_IA(13, start);
+ OP_L_IA(14, start);
+
+ if(BIT15(i))
+ {
+ u32 tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ cpu->CPSR.bits.T = BIT0(tmp);
+ //start += 4;
+ cpu->next_instruction = registres[15];
+ c += waitState[(start>>24)&0xF];
+ }
+
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMIB(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 c = 0;
+ u32 start = cpu->R[REG_POS(i,16)];
+
+ u32 * registres = cpu->R;
+ u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ OP_L_IB(0, start);
+ OP_L_IB(1, start);
+ OP_L_IB(2, start);
+ OP_L_IB(3, start);
+ OP_L_IB(4, start);
+ OP_L_IB(5, start);
+ OP_L_IB(6, start);
+ OP_L_IB(7, start);
+ OP_L_IB(8, start);
+ OP_L_IB(9, start);
+ OP_L_IB(10, start);
+ OP_L_IB(11, start);
+ OP_L_IB(12, start);
+ OP_L_IB(13, start);
+ OP_L_IB(14, start);
+
+ if(BIT15(i))
+ {
+ u32 tmp;
+ start += 4;
+ c += waitState[(start>>24)&0xF];
+ tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ cpu->CPSR.bits.T = BIT0(tmp);
+ cpu->next_instruction = registres[15];
+ c += 2 + (c==0);
+ }
+
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMDA(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 c = 0;
+ u32 start = cpu->R[REG_POS(i,16)];
+
+ u32 * registres = cpu->R;
+ u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ if(BIT15(i))
+ {
+ u32 tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ cpu->CPSR.bits.T = BIT0(tmp);
+ c += waitState[(start>>24)&0xF];
+ start -= 4;
+ cpu->next_instruction = registres[15];
+ }
+
+ OP_L_DA(14, start);
+ OP_L_DA(13, start);
+ OP_L_DA(12, start);
+ OP_L_DA(11, start);
+ OP_L_DA(10, start);
+ OP_L_DA(9, start);
+ OP_L_DA(8, start);
+ OP_L_DA(7, start);
+ OP_L_DA(6, start);
+ OP_L_DA(5, start);
+ OP_L_DA(4, start);
+ OP_L_DA(3, start);
+ OP_L_DA(2, start);
+ OP_L_DA(1, start);
+ OP_L_DA(0, start);
+
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMDB(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 c = 0;
+ u32 start = cpu->R[REG_POS(i,16)];
+
+ u32 * registres = cpu->R;
+ u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ if(BIT15(i))
+ {
+ u32 tmp;
+ start -= 4;
+ tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ cpu->CPSR.bits.T = BIT0(tmp);
+ cpu->next_instruction = registres[15];
+ c += waitState[(start>>24)&0xF];
+ }
+
+ OP_L_DB(14, start);
+ OP_L_DB(13, start);
+ OP_L_DB(12, start);
+ OP_L_DB(11, start);
+ OP_L_DB(10, start);
+ OP_L_DB(9, start);
+ OP_L_DB(8, start);
+ OP_L_DB(7, start);
+ OP_L_DB(6, start);
+ OP_L_DB(5, start);
+ OP_L_DB(4, start);
+ OP_L_DB(3, start);
+ OP_L_DB(2, start);
+ OP_L_DB(1, start);
+ OP_L_DB(0, start);
+
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMIA_W(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction, c = 0;
+ u32 start = cpu->R[REG_POS(i,16)];
+ u32 bitList = (~((2 << REG_POS(i,16))-1)) & 0xFFFF;
+
+ u32 * registres = cpu->R;
+ u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ OP_L_IA(0, start);
+ OP_L_IA(1, start);
+ OP_L_IA(2, start);
+ OP_L_IA(3, start);
+ OP_L_IA(4, start);
+ OP_L_IA(5, start);
+ OP_L_IA(6, start);
+ OP_L_IA(7, start);
+ OP_L_IA(8, start);
+ OP_L_IA(9, start);
+ OP_L_IA(10, start);
+ OP_L_IA(11, start);
+ OP_L_IA(12, start);
+ OP_L_IA(13, start);
+ OP_L_IA(14, start);
+
+ if(BIT15(i))
+ {
+ u32 tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ cpu->CPSR.bits.T = BIT0(tmp);
+ c += waitState[(start>>24)&0xF];
+ start += 4;
+ cpu->next_instruction = registres[15];
+ }
+
+ if(i & (1 << REG_POS(i,16))) {
+ if(i & bitList)
+ cpu->R[REG_POS(i,16)] = start;
+ }
+ else
+ cpu->R[REG_POS(i,16)] = start;
+
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMIB_W(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction, c = 0;
+ u32 start = cpu->R[REG_POS(i,16)];
+ u32 bitList = (~((2 << REG_POS(i,16))-1)) & 0xFFFF;
+
+ u32 * registres = cpu->R;
+ u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ OP_L_IB(0, start);
+ OP_L_IB(1, start);
+ OP_L_IB(2, start);
+ OP_L_IB(3, start);
+ OP_L_IB(4, start);
+ OP_L_IB(5, start);
+ OP_L_IB(6, start);
+ OP_L_IB(7, start);
+ OP_L_IB(8, start);
+ OP_L_IB(9, start);
+ OP_L_IB(10, start);
+ OP_L_IB(11, start);
+ OP_L_IB(12, start);
+ OP_L_IB(13, start);
+ OP_L_IB(14, start);
+
+ if(BIT15(i))
+ {
+ u32 tmp;
+ start += 4;
+ c += waitState[(start>>24)&0xF];
+ tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ cpu->CPSR.bits.T = BIT0(tmp);
+ cpu->next_instruction = registres[15];
+ c += 2 + (c==0);
+ }
+
+ if(i & (1 << REG_POS(i,16))) {
+ if(i & bitList)
+ cpu->R[REG_POS(i,16)] = start;
+ }
+ else
+ cpu->R[REG_POS(i,16)] = start;
+
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMDA_W(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction, c = 0;
+ u32 start = cpu->R[REG_POS(i,16)];
+ u32 bitList = (~((2 << REG_POS(i,16))-1)) & 0xFFFF;
+
+ u32 * registres = cpu->R;
+ u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ if(BIT15(i))
+ {
+ u32 tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ cpu->CPSR.bits.T = BIT0(tmp);
+ c += waitState[(start>>24)&0xF];
+ start -= 4;
+ cpu->next_instruction = registres[15];
+ }
+
+ OP_L_DA(14, start);
+ OP_L_DA(13, start);
+ OP_L_DA(12, start);
+ OP_L_DA(11, start);
+ OP_L_DA(10, start);
+ OP_L_DA(9, start);
+ OP_L_DA(8, start);
+ OP_L_DA(7, start);
+ OP_L_DA(6, start);
+ OP_L_DA(5, start);
+ OP_L_DA(4, start);
+ OP_L_DA(3, start);
+ OP_L_DA(2, start);
+ OP_L_DA(1, start);
+ OP_L_DA(0, start);
+
+ if(i & (1 << REG_POS(i,16))) {
+ if(i & bitList)
+ cpu->R[REG_POS(i,16)] = start;
+ }
+ else
+ cpu->R[REG_POS(i,16)] = start;
+
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMDB_W(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction, c = 0;
+ u32 start = cpu->R[REG_POS(i,16)];
+ u32 bitList = (~((2 << REG_POS(i,16))-1)) & 0xFFFF;
+ u32 * registres = cpu->R;
+ u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ if(BIT15(i))
+ {
+ u32 tmp;
+ start -= 4;
+ tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ cpu->CPSR.bits.T = BIT0(tmp);
+ cpu->next_instruction = registres[15];
+ c += waitState[(start>>24)&0xF];
+ }
+
+ OP_L_DB(14, start);
+ OP_L_DB(13, start);
+ OP_L_DB(12, start);
+ OP_L_DB(11, start);
+ OP_L_DB(10, start);
+ OP_L_DB(9, start);
+ OP_L_DB(8, start);
+ OP_L_DB(7, start);
+ OP_L_DB(6, start);
+ OP_L_DB(5, start);
+ OP_L_DB(4, start);
+ OP_L_DB(3, start);
+ OP_L_DB(2, start);
+ OP_L_DB(1, start);
+ OP_L_DB(0, start);
+
+ if(i & (1 << REG_POS(i,16))) {
+ if(i & bitList)
+ cpu->R[REG_POS(i,16)] = start;
+ }
+ else
+ cpu->R[REG_POS(i,16)] = start;
+
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMIA2(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 oldmode = 0;
+
+ u32 c = 0;
+
+ u32 start = cpu->R[REG_POS(i,16)];
+ u32 * registres;
+ u32 * waitState;
+
+ if(BIT15(i)==0)
+ {
+ if(cpu->CPSR.bits.mode==USR)
+ return 1;
+ oldmode = armcpu_switchMode(cpu, SYS);
+ }
+
+ registres = cpu->R;
+ waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ OP_L_IA(0, start);
+ OP_L_IA(1, start);
+ OP_L_IA(2, start);
+ OP_L_IA(3, start);
+ OP_L_IA(4, start);
+ OP_L_IA(5, start);
+ OP_L_IA(6, start);
+ OP_L_IA(7, start);
+ OP_L_IA(8, start);
+ OP_L_IA(9, start);
+ OP_L_IA(10, start);
+ OP_L_IA(11, start);
+ OP_L_IA(12, start);
+ OP_L_IA(13, start);
+ OP_L_IA(14, start);
+
+ if(BIT15(i))
+ {
+ u32 tmp = READ32(cpu->mem_if->data, start);
+ Status_Reg SPSR;
+ cpu->R[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ //start += 4;
+ cpu->next_instruction = cpu->R[15];
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ }
+ else
+ {
+ armcpu_switchMode(cpu, oldmode);
+ }
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMIB2(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 oldmode = 0;
+ u32 c = 0;
+
+ u32 start = cpu->R[REG_POS(i,16)];
+ u32 * registres;
+ u32 * waitState;
+ //execute = false;
+ LOG("Untested opcode: OP_LDMIB2");
+
+ if(BIT15(i)==0)
+ {
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+ oldmode = armcpu_switchMode(cpu, SYS);
+ }
+
+ registres = cpu->R;
+ waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ OP_L_IB(0, start);
+ OP_L_IB(1, start);
+ OP_L_IB(2, start);
+ OP_L_IB(3, start);
+ OP_L_IB(4, start);
+ OP_L_IB(5, start);
+ OP_L_IB(6, start);
+ OP_L_IB(7, start);
+ OP_L_IB(8, start);
+ OP_L_IB(9, start);
+ OP_L_IB(10, start);
+ OP_L_IB(11, start);
+ OP_L_IB(12, start);
+ OP_L_IB(13, start);
+ OP_L_IB(14, start);
+
+ if(BIT15(i))
+ {
+ u32 tmp;
+ Status_Reg SPSR;
+ start += 4;
+ tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ cpu->next_instruction = registres[15];
+ c += waitState[(start>>24)&0xF];
+ }
+ else
+ {
+ armcpu_switchMode(cpu, oldmode);
+ }
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMDA2(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+
+ u32 oldmode = 0;
+ u32 c = 0;
+ u32 * registres;
+ u32 * waitState;
+
+ u32 start = cpu->R[REG_POS(i,16)];
+ //execute = false;
+ LOG("Untested opcode: OP_LDMDA2");
+
+ if(BIT15(i)==0)
+ {
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+ oldmode = armcpu_switchMode(cpu, SYS);
+ }
+
+ registres = cpu->R;
+ waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ if(BIT15(i))
+ {
+ u32 tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ cpu->CPSR = cpu->SPSR;
+ c += waitState[(start>>24)&0xF];
+ start -= 4;
+ cpu->next_instruction = registres[15];
+ }
+
+ OP_L_DA(14, start);
+ OP_L_DA(13, start);
+ OP_L_DA(12, start);
+ OP_L_DA(11, start);
+ OP_L_DA(10, start);
+ OP_L_DA(9, start);
+ OP_L_DA(8, start);
+ OP_L_DA(7, start);
+ OP_L_DA(6, start);
+ OP_L_DA(5, start);
+ OP_L_DA(4, start);
+ OP_L_DA(3, start);
+ OP_L_DA(2, start);
+ OP_L_DA(1, start);
+ OP_L_DA(0, start);
+
+ if(BIT15(i)==0)
+ {
+ armcpu_switchMode(cpu, oldmode);
+ }
+ else
+ {
+ Status_Reg SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ }
+
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMDB2(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+
+ u32 oldmode = 0;
+ u32 c = 0;
+ u32 * registres;
+ u32 * waitState;
+
+ u32 start = cpu->R[REG_POS(i,16)];
+ if(BIT15(i)==0)
+ {
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+ oldmode = armcpu_switchMode(cpu, SYS);
+ }
+
+ registres = cpu->R;
+ waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ if(BIT15(i))
+ {
+ u32 tmp;
+ start -= 4;
+ tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ cpu->CPSR = cpu->SPSR;
+ cpu->next_instruction = registres[15];
+ c += waitState[(start>>24)&0xF];
+ }
+
+ OP_L_DB(14, start);
+ OP_L_DB(13, start);
+ OP_L_DB(12, start);
+ OP_L_DB(11, start);
+ OP_L_DB(10, start);
+ OP_L_DB(9, start);
+ OP_L_DB(8, start);
+ OP_L_DB(7, start);
+ OP_L_DB(6, start);
+ OP_L_DB(5, start);
+ OP_L_DB(4, start);
+ OP_L_DB(3, start);
+ OP_L_DB(2, start);
+ OP_L_DB(1, start);
+ OP_L_DB(0, start);
+
+ if(BIT15(i)==0)
+ {
+ armcpu_switchMode(cpu, oldmode);
+ }
+ else
+ {
+ Status_Reg SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ }
+
+ return 2 + c;
+}
+
+static u32 FASTCALL OP_LDMIA2_W(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 c = 0;
+
+ u32 oldmode = 0;
+ u32 start = cpu->R[REG_POS(i,16)];
+ u32 * registres;
+ u32 * waitState;
+ u32 tmp;
+ Status_Reg SPSR;
+// execute = false;
+ if(BIT15(i)==0)
+ {
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+ oldmode = armcpu_switchMode(cpu, SYS);
+ }
+
+ registres = cpu->R;
+ waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ OP_L_IA(0, start);
+ OP_L_IA(1, start);
+ OP_L_IA(2, start);
+ OP_L_IA(3, start);
+ OP_L_IA(4, start);
+ OP_L_IA(5, start);
+ OP_L_IA(6, start);
+ OP_L_IA(7, start);
+ OP_L_IA(8, start);
+ OP_L_IA(9, start);
+ OP_L_IA(10, start);
+ OP_L_IA(11, start);
+ OP_L_IA(12, start);
+ OP_L_IA(13, start);
+ OP_L_IA(14, start);
+
+ if(BIT15(i)==0)
+ {
+ registres[REG_POS(i,16)] = start;
+ armcpu_switchMode(cpu, oldmode);
+ return c + 2;
+ }
+
+ registres[REG_POS(i,16)] = start + 4;
+ tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ cpu->next_instruction = registres[15];
+ c += waitState[(start>>24)&0xF];
+
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMIB2_W(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 c = 0;
+
+ u32 oldmode = 0;
+ u32 start = cpu->R[REG_POS(i,16)];
+ u32 * registres;
+ u32 * waitState;
+ u32 tmp;
+ Status_Reg SPSR;
+
+ if(BIT15(i)==0)
+ {
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+ oldmode = armcpu_switchMode(cpu, SYS);
+ }
+
+ registres = cpu->R;
+ waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ OP_L_IB(0, start);
+ OP_L_IB(1, start);
+ OP_L_IB(2, start);
+ OP_L_IB(3, start);
+ OP_L_IB(4, start);
+ OP_L_IB(5, start);
+ OP_L_IB(6, start);
+ OP_L_IB(7, start);
+ OP_L_IB(8, start);
+ OP_L_IB(9, start);
+ OP_L_IB(10, start);
+ OP_L_IB(11, start);
+ OP_L_IB(12, start);
+ OP_L_IB(13, start);
+ OP_L_IB(14, start);
+
+ if(BIT15(i)==0)
+ {
+ armcpu_switchMode(cpu, oldmode);
+ registres[REG_POS(i,16)] = start;
+
+ return c + 2;
+ }
+
+ registres[REG_POS(i,16)] = start + 4;
+ tmp = READ32(cpu->mem_if->data, start + 4);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ cpu->CPSR = cpu->SPSR;
+ cpu->next_instruction = registres[15];
+ SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ c += waitState[(start>>24)&0xF];
+
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMDA2_W(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 c = 0;
+
+ u32 oldmode = 0;
+ u32 start = cpu->R[REG_POS(i,16)];
+ u32 * registres;
+ u32 * waitState;
+ Status_Reg SPSR;
+// execute = false;
+ if(BIT15(i)==0)
+ {
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+ oldmode = armcpu_switchMode(cpu, SYS);
+ }
+
+ registres = cpu->R;
+ waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ if(BIT15(i))
+ {
+ u32 tmp = READ32(cpu->mem_if->data, start);
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ c += waitState[(start>>24)&0xF];
+ start -= 4;
+ cpu->next_instruction = registres[15];
+ }
+
+ OP_L_DA(14, start);
+ OP_L_DA(13, start);
+ OP_L_DA(12, start);
+ OP_L_DA(11, start);
+ OP_L_DA(10, start);
+ OP_L_DA(9, start);
+ OP_L_DA(8, start);
+ OP_L_DA(7, start);
+ OP_L_DA(6, start);
+ OP_L_DA(5, start);
+ OP_L_DA(4, start);
+ OP_L_DA(3, start);
+ OP_L_DA(2, start);
+ OP_L_DA(1, start);
+ OP_L_DA(0, start);
+
+ registres[REG_POS(i,16)] = start;
+
+ if(BIT15(i)==0)
+ {
+ armcpu_switchMode(cpu, oldmode);
+ return c + 2;
+ }
+
+ SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMDB2_W(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 c = 0;
+
+ u32 oldmode = 0;
+ u32 start = cpu->R[REG_POS(i,16)];
+ u32 * registres;
+ u32 * waitState;
+ Status_Reg SPSR;
+// execute = false;
+ if(BIT15(i)==0)
+ {
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+ oldmode = armcpu_switchMode(cpu, SYS);
+ }
+
+ registres = cpu->R;
+ waitState = MMU.MMU_WAIT32[cpu->proc_ID];
+
+ if(BIT15(i))
+ {
+ u32 tmp;
+ start -= 4;
+ tmp = READ32(cpu->mem_if->data, start);
+ c += waitState[(start>>24)&0xF];
+ registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1));
+ cpu->CPSR = cpu->SPSR;
+ cpu->next_instruction = registres[15];
+ }
+
+ OP_L_DB(14, start);
+ OP_L_DB(13, start);
+ OP_L_DB(12, start);
+ OP_L_DB(11, start);
+ OP_L_DB(10, start);
+ OP_L_DB(9, start);
+ OP_L_DB(8, start);
+ OP_L_DB(7, start);
+ OP_L_DB(6, start);
+ OP_L_DB(5, start);
+ OP_L_DB(4, start);
+ OP_L_DB(3, start);
+ OP_L_DB(2, start);
+ OP_L_DB(1, start);
+ OP_L_DB(0, start);
+
+ registres[REG_POS(i,16)] = start;
+
+ if(BIT15(i)==0)
+ {
+ armcpu_switchMode(cpu, oldmode);
+ return c + 2;
+ }
+
+ SPSR = cpu->SPSR;
+ armcpu_switchMode(cpu, SPSR.bits.mode);
+ cpu->CPSR=SPSR;
+ return c + 2;
+}
+
+//------------------------------STM----------------------------------
+
+static u32 FASTCALL OP_STMIA(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction, c = 0, b;
+ u32 start = cpu->R[REG_POS(i,16)];
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, b))
+ {
+ WRITE32(cpu->mem_if->data, start, cpu->R[b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ start += 4;
+ }
+ }
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMIB(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction, c = 0, b;
+ u32 start = cpu->R[REG_POS(i,16)];
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, b))
+ {
+ start += 4;
+ WRITE32(cpu->mem_if->data, start, cpu->R[b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ }
+ }
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMDA(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction, c = 0, b;
+ u32 start = cpu->R[REG_POS(i,16)];
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, 15-b))
+ {
+ WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ start -= 4;
+ }
+ }
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMDB(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction, c = 0, b;
+ u32 start = cpu->R[REG_POS(i,16)];
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, 15-b))
+ {
+ start -= 4;
+ WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ }
+ }
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMIA_W(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction, c = 0, b;
+ u32 start = cpu->R[REG_POS(i,16)];
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, b))
+ {
+ WRITE32(cpu->mem_if->data, start, cpu->R[b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ start += 4;
+ }
+ }
+
+ cpu->R[REG_POS(i,16)] = start;
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMIB_W(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction, c = 0, b;
+ u32 start = cpu->R[REG_POS(i,16)];
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, b))
+ {
+ start += 4;
+ WRITE32(cpu->mem_if->data, start, cpu->R[b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ }
+ }
+ cpu->R[REG_POS(i,16)] = start;
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMDA_W(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction, c = 0, b;
+ u32 start = cpu->R[REG_POS(i,16)];
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, 15-b))
+ {
+ WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ start -= 4;
+ }
+ }
+
+ cpu->R[REG_POS(i,16)] = start;
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMDB_W(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction, c = 0, b;
+ u32 start = cpu->R[REG_POS(i,16)];
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, 15-b))
+ {
+ start -= 4;
+ WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ }
+ }
+
+ cpu->R[REG_POS(i,16)] = start;
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMIA2(armcpu_t *cpu)
+{
+ u32 i, c, b;
+ u32 start;
+ u32 oldmode;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ i = cpu->instruction;
+ c = 0;
+ start = cpu->R[REG_POS(i,16)];
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+ //execute = false;
+ LOG("Untested opcode: OP_STMIA2");
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, b))
+ {
+ WRITE32(cpu->mem_if->data, start, cpu->R[b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ start += 4;
+ }
+ }
+
+ armcpu_switchMode(cpu, oldmode);
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMIB2(armcpu_t *cpu)
+{
+ u32 i, c, b;
+ u32 start;
+ u32 oldmode;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ i = cpu->instruction;
+ c = 0;
+ start = cpu->R[REG_POS(i,16)];
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+ //execute = false;
+ LOG("Untested opcode: OP_STMIB2");
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, b))
+ {
+ start += 4;
+ WRITE32(cpu->mem_if->data, start, cpu->R[b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ }
+ }
+
+ armcpu_switchMode(cpu, oldmode);
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMDA2(armcpu_t *cpu)
+{
+ u32 i, c, b;
+ u32 start;
+ u32 oldmode;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ i = cpu->instruction;
+ c = 0;
+ start = cpu->R[REG_POS(i,16)];
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+ //execute = false;
+ LOG("Untested opcode: OP_STMDA2");
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, 15-b))
+ {
+ WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ start -= 4;
+ }
+ }
+
+ armcpu_switchMode(cpu, oldmode);
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMDB2(armcpu_t *cpu)
+{
+ u32 i, c, b;
+ u32 start;
+ u32 oldmode;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+ i = cpu->instruction;
+ c=0;
+ start = cpu->R[REG_POS(i,16)];
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, 15-b))
+ {
+ start -= 4;
+ WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ }
+ }
+
+ armcpu_switchMode(cpu, oldmode);
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMIA2_W(armcpu_t *cpu)
+{
+ u32 i, c, b;
+ u32 start;
+ u32 oldmode;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ i = cpu->instruction;
+ c=0;
+ start = cpu->R[REG_POS(i,16)];
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+ //execute = false;
+ LOG("Untested opcode: OP_STMIA2_W");
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, b))
+ {
+ WRITE32(cpu->mem_if->data, start, cpu->R[b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ start += 4;
+ }
+ }
+
+ cpu->R[REG_POS(i,16)] = start;
+
+ armcpu_switchMode(cpu, oldmode);
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMIB2_W(armcpu_t *cpu)
+{
+ u32 i, c, b;
+ u32 start;
+ u32 oldmode;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+ i = cpu->instruction;
+ c=0;
+ start = cpu->R[REG_POS(i,16)];
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, b))
+ {
+ start += 4;
+ WRITE32(cpu->mem_if->data, start, cpu->R[b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ }
+ }
+ armcpu_switchMode(cpu, oldmode);
+ cpu->R[REG_POS(i,16)] = start;
+
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMDA2_W(armcpu_t *cpu)
+{
+ u32 i, c, b;
+ u32 start;
+ u32 oldmode;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ i = cpu->instruction;
+ c = 0;
+ start = cpu->R[REG_POS(i,16)];
+ oldmode = armcpu_switchMode(cpu, SYS);
+ //execute = false;
+ LOG("Untested opcode: OP_STMDA2_W");
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, 15-b))
+ {
+ WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ start -= 4;
+ }
+ }
+
+ cpu->R[REG_POS(i,16)] = start;
+
+ armcpu_switchMode(cpu, oldmode);
+ return c + 1;
+}
+
+static u32 FASTCALL OP_STMDB2_W(armcpu_t *cpu)
+{
+ u32 i, c, b;
+ u32 start;
+ u32 oldmode;
+
+ if(cpu->CPSR.bits.mode==USR)
+ return 2;
+
+ i = cpu->instruction;
+ c = 0;
+
+ start = cpu->R[REG_POS(i,16)];
+ oldmode = armcpu_switchMode(cpu, SYS);
+
+ //execute = false;
+ LOG("Untested opcode: OP_STMDB2_W");
+
+ for(b=0; b<16; ++b)
+ {
+ if(BIT_N(i, 15-b))
+ {
+ start -= 4;
+ WRITE32(cpu->mem_if->data, start, cpu->R[15-b]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF];
+ }
+ }
+
+ cpu->R[REG_POS(i,16)] = start;
+
+ armcpu_switchMode(cpu, oldmode);
+ return c + 1;
+}
+
+/*
+ *
+ * The Enhanced DSP Extension LDRD and STRD instructions.
+ *
+ */
+static u32 FASTCALL
+OP_LDRD_STRD_POST_INDEX( armcpu_t *cpu) {
+ u32 i = cpu->instruction;
+ u32 Rd_num = REG_POS( i, 12);
+ u32 addr = cpu->R[REG_POS(i,16)];
+ u32 index;
+
+ /* I bit - immediate or register */
+ if ( BIT22(i))
+ index = IMM_OFF;
+ else
+ index = cpu->R[REG_POS(i,0)];
+
+ /* U bit - add or subtract */
+ if ( BIT23(i))
+ cpu->R[REG_POS(i,16)] += index;
+ else
+ cpu->R[REG_POS(i,16)] -= index;
+
+ if ( !(Rd_num & 0x1)) {
+ /* Store/Load */
+ if ( BIT5(i)) {
+ WRITE32(cpu->mem_if->data, addr, cpu->R[Rd_num]);
+ WRITE32(cpu->mem_if->data, addr + 4, cpu->R[Rd_num + 1]);
+ }
+ else {
+ cpu->R[Rd_num] = READ32(cpu->mem_if->data, addr);
+ cpu->R[Rd_num + 1] = READ32(cpu->mem_if->data, addr + 4);
+ }
+ }
+
+ return 3 + (MMU.MMU_WAIT32[cpu->proc_ID][(addr>>24)&0xF] * 2);
+}
+
+static u32 FASTCALL
+OP_LDRD_STRD_OFFSET_PRE_INDEX( armcpu_t *cpu) {
+ u32 i = cpu->instruction;
+ u32 Rd_num = REG_POS( i, 12);
+ u32 addr = cpu->R[REG_POS(i,16)];
+ u32 index;
+
+ /* I bit - immediate or register */
+ if ( BIT22(i))
+ index = IMM_OFF;
+ else
+ index = cpu->R[REG_POS(i,0)];
+
+ /* U bit - add or subtract */
+ if ( BIT23(i)) {
+ addr += index;
+
+ /* W bit - writeback */
+ if ( BIT21(i))
+ cpu->R[REG_POS(i,16)] = addr;
+ }
+ else {
+ addr -= index;
+
+ /* W bit - writeback */
+ if ( BIT21(i))
+ cpu->R[REG_POS(i,16)] = addr;
+ }
+
+ if ( !(Rd_num & 0x1)) {
+ /* Store/Load */
+ if ( BIT5(i)) {
+ WRITE32(cpu->mem_if->data, addr, cpu->R[Rd_num]);
+ WRITE32(cpu->mem_if->data, addr + 4, cpu->R[Rd_num + 1]);
+ }
+ else {
+ cpu->R[Rd_num] = READ32(cpu->mem_if->data, addr);
+ cpu->R[Rd_num + 1] = READ32(cpu->mem_if->data, addr + 4);
+ }
+ }
+
+ return 3 + (MMU.MMU_WAIT32[cpu->proc_ID][(addr>>24)&0xF] * 2);
+}
+
+
+
+//---------------------STC----------------------------------
+
+static u32 FASTCALL OP_STC_P_IMM_OFF(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+static u32 FASTCALL OP_STC_M_IMM_OFF(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+static u32 FASTCALL OP_STC_P_PREIND(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+static u32 FASTCALL OP_STC_M_PREIND(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+static u32 FASTCALL OP_STC_P_POSTIND(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+static u32 FASTCALL OP_STC_M_POSTIND(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+static u32 FASTCALL OP_STC_OPTION(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a STC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+//---------------------LDC----------------------------------
+
+static u32 FASTCALL OP_LDC_P_IMM_OFF(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+static u32 FASTCALL OP_LDC_M_IMM_OFF(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+static u32 FASTCALL OP_LDC_P_PREIND(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+static u32 FASTCALL OP_LDC_M_PREIND(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+static u32 FASTCALL OP_LDC_P_POSTIND(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+static u32 FASTCALL OP_LDC_M_POSTIND(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+static u32 FASTCALL OP_LDC_OPTION(armcpu_t *cpu)
+{
+ {
+ /* the NDS has no coproc that responses to a LDC, no feedback is given to the arm */
+ return 2;
+ }
+}
+
+//----------------MCR-----------------------
+
+static u32 FASTCALL OP_MCR(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 cpnum = REG_POS(i, 8);
+
+ if(!cpu->coproc[cpnum])
+ {
+ execute = false;
+ return 2;
+ }
+
+ armcp15_moveARM2CP((armcp15_t*)cpu->coproc[cpnum], cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7);
+ //cpu->coproc[cpnum]->moveARM2CP(cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7);
+ return 2;
+}
+
+//----------------MRC-----------------------
+
+static u32 FASTCALL OP_MRC(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 cpnum = REG_POS(i, 8);
+
+ if(!cpu->coproc[cpnum])
+ {
+ execute = false;
+ return 2;
+ }
+
+ armcp15_moveCP2ARM((armcp15_t*)cpu->coproc[cpnum], &cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7);
+ //cpu->coproc[cpnum]->moveCP2ARM(&cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7);
+ return 4;
+}
+
+//--------------SWI-------------------------------
+static u32 FASTCALL OP_SWI(armcpu_t *cpu)
+{
+ if (((cpu->intVector != 0) ^ (cpu->proc_ID == ARMCPU_ARM9)))
+ {
+ /* TODO (#1#): translocated SWI vectors */
+ /* we use an irq thats not in the irq tab, as
+ it was replaced duie to a changed intVector */
+ Status_Reg tmp = cpu->CPSR;
+ armcpu_switchMode(cpu, SVC); /* enter svc mode */
+ cpu->R[14] = cpu->R[15] - 4; /* jump to swi Vector */
+ cpu->SPSR = tmp; /* save old CPSR as new SPSR */
+ cpu->CPSR.bits.T = 0; /* handle as ARM32 code */
+ cpu->CPSR.bits.I = cpu->SPSR.bits.I; /* keep int disable flag */
+ cpu->R[15] = cpu->intVector + 0x08;
+ cpu->next_instruction = cpu->R[15];
+ return 4;
+ }
+ else
+ {
+ u32 swinum = (cpu->instruction>>16)&0x1F;
+ return cpu->swi_tab[swinum](cpu) + 3;
+ }
+}
+
+//----------------BKPT-------------------------
+static u32 FASTCALL OP_BKPT(armcpu_t *cpu)
+{
+ execute = false;
+ return 4;
+}
+
+//----------------CDP-----------------------
+
+static u32 FASTCALL OP_CDP(armcpu_t *cpu)
+{
+ execute = false;
+ return 4;
+}
+
+#define TYPE_RETOUR u32
+#define PARAMETRES armcpu_t *cpu
+#define CALLTYPE FASTCALL
+#define NOM_TAB arm_instructions_set
+
+#include "instruction_tabdef.inc"
diff --git a/src/xsf/desmume/arm_instructions.h b/src/xsf/desmume/arm_instructions.h
index 350680aafc44..2d6461b675d7 100644
--- a/src/xsf/desmume/arm_instructions.h
+++ b/src/xsf/desmume/arm_instructions.h
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ARMINSTRUCTION_H
diff --git a/src/xsf/desmume/armcpu.c b/src/xsf/desmume/armcpu.c
deleted file mode 100644
index a1760934a5c5..000000000000
--- a/src/xsf/desmume/armcpu.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/* Copyright (C) 2006 yopyop
- yopyop156 at ifrance.com
- yopyop156.ifrance.com
-
- This file is part of DeSmuME
-
- DeSmuME 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.
-
- DeSmuME 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 DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include "arm_instructions.h"
-#include "thumb_instructions.h"
-#include "cp15.h"
-#include "bios.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-const unsigned char arm_cond_table[16*16] = {
- /* N=0, Z=0, C=0, V=0 */
- 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
- 0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
- /* N=0, Z=0, C=0, V=1 */
- 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x00,
- 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
- /* N=0, Z=0, C=1, V=0 */
- 0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,
- 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
- /* N=0, Z=0, C=1, V=1 */
- 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,
- 0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
- /* N=0, Z=1, C=0, V=0 */
- 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,
- 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
- /* N=0, Z=1, C=0, V=1 */
- 0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00,
- 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
- /* N=0, Z=1, C=1, V=0 */
- 0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF,
- 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
- /* N=0, Z=1, C=1, V=1 */
- 0xFF,0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00,
- 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
- /* N=1, Z=0, C=0, V=0 */
- 0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00,0xFF,
- 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
- /* N=1, Z=0, C=0, V=1 */
- 0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x00,
- 0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
- /* N=1, Z=0, C=1, V=0 */
- 0x00,0xFF,0xFF,0x00,0xFF,0x00,0x00,0xFF,
- 0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
- /* N=1, Z=0, C=1, V=1 */
- 0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x00,
- 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
- /* N=1, Z=1, C=0, V=0 */
- 0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,
- 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
- /* N=1, Z=1, C=0, V=1 */
- 0xFF,0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00,
- 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
- /* N=1, Z=1, C=1, V=0 */
- 0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF,
- 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
- /* N=1, Z=1, C=1, V=1 */
- 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
- 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
-};
-
-armcpu_t NDS_ARM7;
-armcpu_t NDS_ARM9;
-
-#define SWAP(a, b, c) do \
- { \
- c=a; \
- a=b; \
- b=c; \
- } \
- while(0)
-
-#ifdef GDB_STUB
-
-#define STALLED_CYCLE_COUNT 10
-
-static void
-stall_cpu( void *instance) {
- armcpu_t *armcpu = (armcpu_t *)instance;
-
- armcpu->stalled = 1;
-}
-
-static void
-unstall_cpu( void *instance) {
- armcpu_t *armcpu = (armcpu_t *)instance;
-
- armcpu->stalled = 0;
-}
-
-static void
-install_post_exec_fn( void *instance,
- void (*ex_fn)( void *, u32 adr, int thumb),
- void *fn_data) {
- armcpu_t *armcpu = (armcpu_t *)instance;
-
- armcpu->post_ex_fn = ex_fn;
- armcpu->post_ex_fn_data = fn_data;
-}
-
-static void
-remove_post_exec_fn( void *instance) {
- armcpu_t *armcpu = (armcpu_t *)instance;
-
- armcpu->post_ex_fn = NULL;
-}
-#endif
-
-#ifdef GDB_STUB
-int armcpu_new( armcpu_t *armcpu, u32 id,
- struct armcpu_memory_iface *mem_if,
- struct armcpu_ctrl_iface **ctrl_iface_ret)
-#else
-int armcpu_new( armcpu_t *armcpu, u32 id)
-#endif
-{
- armcpu->proc_ID = id;
-
- if(id==0)
- armcpu->swi_tab = ARM9_swi_tab;
- else
- armcpu->swi_tab = ARM7_swi_tab;
-
-#ifdef GDB_STUB
- armcpu->mem_if = mem_if;
-
- /* populate the control interface */
- armcpu->ctrl_iface.stall = stall_cpu;
- armcpu->ctrl_iface.unstall = unstall_cpu;
- armcpu->ctrl_iface.read_reg = read_cpu_reg;
- armcpu->ctrl_iface.set_reg = set_cpu_reg;
- armcpu->ctrl_iface.install_post_ex_fn = install_post_exec_fn;
- armcpu->ctrl_iface.remove_post_ex_fn = remove_post_exec_fn;
- armcpu->ctrl_iface.data = armcpu;
-
- *ctrl_iface_ret = &armcpu->ctrl_iface;
-
- armcpu->stalled = 0;
- armcpu->post_ex_fn = NULL;
-#endif
-
- armcpu_init(armcpu, 0);
-
- return 0;
-}
-
-void armcpu_init(armcpu_t *armcpu, u32 adr)
-{
- u32 i;
-
- armcpu->LDTBit = (armcpu->proc_ID==0); //Si ARM9 utiliser le syte v5 pour le load
- armcpu->intVector = 0xFFFF0000 * (armcpu->proc_ID==0);
- armcpu->waitIRQ = FALSE;
- armcpu->wirq = FALSE;
-
-#ifdef GDB_STUB
- armcpu->irq_flag = 0;
-#endif
-
- if(armcpu->coproc[15]) free(armcpu->coproc[15]);
-
- for(i = 0; i < 15; ++i)
- {
- armcpu->R[i] = 0;
- armcpu->coproc[i] = NULL;
- }
-
- armcpu->CPSR.val = armcpu->SPSR.val = SYS;
-
- armcpu->R13_usr = armcpu->R14_usr = 0;
- armcpu->R13_svc = armcpu->R14_svc = 0;
- armcpu->R13_abt = armcpu->R14_abt = 0;
- armcpu->R13_und = armcpu->R14_und = 0;
- armcpu->R13_irq = armcpu->R14_irq = 0;
- armcpu->R8_fiq = armcpu->R9_fiq = armcpu->R10_fiq = armcpu->R11_fiq = armcpu->R12_fiq = armcpu->R13_fiq = armcpu->R14_fiq = 0;
-
- armcpu->SPSR_svc.val = armcpu->SPSR_abt.val = armcpu->SPSR_und.val = armcpu->SPSR_irq.val = armcpu->SPSR_fiq.val = 0;
-
-#ifdef GDB_STUB
- armcpu->instruct_adr = adr;
- armcpu->R[15] = adr + 8;
-#else
- armcpu->R[15] = adr;
-#endif
-
- armcpu->next_instruction = adr;
-
- armcpu->coproc[15] = (armcp_t*)armcp15_new(armcpu);
-
-#ifndef GDB_STUB
- armcpu_prefetch(armcpu);
-#endif
-}
-
-u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode)
-{
- u32 oldmode = armcpu->CPSR.bits.mode;
-
- switch(oldmode)
- {
- case USR :
- case SYS :
- armcpu->R13_usr = armcpu->R[13];
- armcpu->R14_usr = armcpu->R[14];
- break;
-
- case FIQ :
- {
- u32 tmp;
- SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
- SWAP(armcpu->R[9], armcpu->R9_fiq, tmp);
- SWAP(armcpu->R[10], armcpu->R10_fiq, tmp);
- SWAP(armcpu->R[11], armcpu->R11_fiq, tmp);
- SWAP(armcpu->R[12], armcpu->R12_fiq, tmp);
- armcpu->R13_fiq = armcpu->R[13];
- armcpu->R14_fiq = armcpu->R[14];
- armcpu->SPSR_fiq = armcpu->SPSR;
- break;
- }
- case IRQ :
- armcpu->R13_irq = armcpu->R[13];
- armcpu->R14_irq = armcpu->R[14];
- armcpu->SPSR_irq = armcpu->SPSR;
- break;
-
- case SVC :
- armcpu->R13_svc = armcpu->R[13];
- armcpu->R14_svc = armcpu->R[14];
- armcpu->SPSR_svc = armcpu->SPSR;
- break;
-
- case ABT :
- armcpu->R13_abt = armcpu->R[13];
- armcpu->R14_abt = armcpu->R[14];
- armcpu->SPSR_abt = armcpu->SPSR;
- break;
-
- case UND :
- armcpu->R13_und = armcpu->R[13];
- armcpu->R14_und = armcpu->R[14];
- armcpu->SPSR_und = armcpu->SPSR;
- break;
- default :
- break;
- }
-
- switch(mode)
- {
- case USR :
- case SYS :
- armcpu->R[13] = armcpu->R13_usr;
- armcpu->R[14] = armcpu->R14_usr;
- //SPSR = CPSR;
- break;
-
- case FIQ :
- {
- u32 tmp;
- SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
- SWAP(armcpu->R[9], armcpu->R9_fiq, tmp);
- SWAP(armcpu->R[10], armcpu->R10_fiq, tmp);
- SWAP(armcpu->R[11], armcpu->R11_fiq, tmp);
- SWAP(armcpu->R[12], armcpu->R12_fiq, tmp);
- armcpu->R[13] = armcpu->R13_fiq;
- armcpu->R[14] = armcpu->R14_fiq;
- armcpu->SPSR = armcpu->SPSR_fiq;
- break;
- }
-
- case IRQ :
- armcpu->R[13] = armcpu->R13_irq;
- armcpu->R[14] = armcpu->R14_irq;
- armcpu->SPSR = armcpu->SPSR_irq;
- break;
-
- case SVC :
- armcpu->R[13] = armcpu->R13_svc;
- armcpu->R[14] = armcpu->R14_svc;
- armcpu->SPSR = armcpu->SPSR_svc;
- break;
-
- case ABT :
- armcpu->R[13] = armcpu->R13_abt;
- armcpu->R[14] = armcpu->R14_abt;
- armcpu->SPSR = armcpu->SPSR_abt;
- break;
-
- case UND :
- armcpu->R[13] = armcpu->R13_und;
- armcpu->R[14] = armcpu->R14_und;
- armcpu->SPSR = armcpu->SPSR_und;
- break;
-
- default :
- break;
- }
-
- armcpu->CPSR.bits.mode = mode & 0x1F;
- return oldmode;
-}
-
-u32 armcpu_prefetch(armcpu_t *armcpu)
-{
-#ifdef GDB_STUB
- u32 temp_instruction;
-#endif
-
- if(armcpu->CPSR.bits.T == 0)
- {
-#ifdef GDB_STUB
- temp_instruction =
- armcpu->mem_if->prefetch32( armcpu->mem_if->data,
- armcpu->next_instruction);
-
- if ( !armcpu->stalled) {
- armcpu->instruction = temp_instruction;
- armcpu->instruct_adr = armcpu->next_instruction;
- armcpu->next_instruction += 4;
- armcpu->R[15] = armcpu->next_instruction + 4;
- }
-#else
- armcpu->instruction = MMU_read32_acl(armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
-
- armcpu->instruct_adr = armcpu->next_instruction;
- armcpu->next_instruction += 4;
- armcpu->R[15] = armcpu->next_instruction + 4;
-#endif
-
- return MMU.MMU_WAIT32[armcpu->proc_ID][(armcpu->instruct_adr>>24)&0xF];
- }
-
-#ifdef GDB_STUB
- temp_instruction =
- armcpu->mem_if->prefetch16( armcpu->mem_if->data,
- armcpu->next_instruction);
-
- if ( !armcpu->stalled) {
- armcpu->instruction = temp_instruction;
- armcpu->instruct_adr = armcpu->next_instruction;
- armcpu->next_instruction = armcpu->next_instruction + 2;
- armcpu->R[15] = armcpu->next_instruction + 2;
- }
-#else
- armcpu->instruction = MMU_read16_acl(armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
-
- armcpu->instruct_adr = armcpu->next_instruction;
- armcpu->next_instruction += 2;
- armcpu->R[15] = armcpu->next_instruction + 2;
-#endif
-
- return MMU.MMU_WAIT16[armcpu->proc_ID][(armcpu->instruct_adr>>24)&0xF];
-}
-
-
-BOOL armcpu_irqExeption(armcpu_t *armcpu)
-{
- Status_Reg tmp;
-
- if(armcpu->CPSR.bits.I) return FALSE;
-
-#ifdef GDB_STUB
- armcpu->irq_flag = 0;
-#endif
-
- tmp = armcpu->CPSR;
- armcpu_switchMode(armcpu, IRQ);
-
-#ifdef GDB_STUB
- armcpu->R[14] = armcpu->next_instruction + 4;
-#else
- armcpu->R[14] = armcpu->instruct_adr + 4;
-#endif
- armcpu->SPSR = tmp;
- armcpu->CPSR.bits.T = 0;
- armcpu->CPSR.bits.I = 1;
- armcpu->next_instruction = armcpu->intVector + 0x18;
- armcpu->waitIRQ = 0;
-
-#ifndef GDB_STUB
- armcpu->R[15] = armcpu->next_instruction + 8;
- armcpu_prefetch(armcpu);
-#endif
-
- return TRUE;
-}
-/*
-static BOOL armcpu_prefetchExeption(armcpu_t *armcpu)
-{
- Status_Reg tmp;
- if(armcpu->CPSR.bits.I) return FALSE;
- tmp = armcpu->CPSR;
- armcpu_switchMode(armcpu, ABT);
- armcpu->R[14] = armcpu->next_instruction + 4;
- armcpu->SPSR = tmp;
- armcpu->CPSR.bits.T = 0;
- armcpu->CPSR.bits.I = 1;
- armcpu->next_instruction = armcpu->intVector + 0xC;
- armcpu->R[15] = armcpu->next_instruction + 8;
- armcpu->waitIRQ = 0;
- return TRUE;
-}
-*/
-
-BOOL
-armcpu_flagIrq( armcpu_t *armcpu) {
- if(armcpu->CPSR.bits.I) return FALSE;
-
- armcpu->waitIRQ = 0;
-
-#ifdef GDB_STUB
- armcpu->irq_flag = 1;
-#endif
-
- return TRUE;
-}
-
-
-u32 armcpu_exec(armcpu_t *armcpu)
-{
- u32 c = 1;
-
-#ifdef GDB_STUB
- if ( armcpu->stalled)
- return STALLED_CYCLE_COUNT;
-
- /* check for interrupts */
- if ( armcpu->irq_flag) {
- armcpu_irqExeption( armcpu);
- }
-
- c = armcpu_prefetch(armcpu);
-
- if ( armcpu->stalled) {
- return c;
- }
-#endif
-
- if(armcpu->CPSR.bits.T == 0)
- {
-/* if((TEST_COND(CONDITION(armcpu->instruction), armcpu->CPSR)) || ((CONDITION(armcpu->instruction)==0xF)&&(CODE(armcpu->instruction)==0x5)))*/
- if((TEST_COND(CONDITION(armcpu->instruction), CODE(armcpu->instruction), armcpu->CPSR)))
- {
- c += arm_instructions_set[INSTRUCTION_INDEX(armcpu->instruction)](armcpu);
- }
-#ifdef GDB_STUB
- if ( armcpu->post_ex_fn != NULL) {
- /* call the external post execute function */
- armcpu->post_ex_fn( armcpu->post_ex_fn_data,
- armcpu->instruct_adr, 0);
- }
-#else
- c += armcpu_prefetch(armcpu);
-#endif
- return c;
- }
-
- c += thumb_instructions_set[armcpu->instruction>>6](armcpu);
-
-#ifdef GDB_STUB
- if ( armcpu->post_ex_fn != NULL) {
- /* call the external post execute function */
- armcpu->post_ex_fn( armcpu->post_ex_fn_data, armcpu->instruct_adr, 1);
- }
-#else
- c += armcpu_prefetch(armcpu);
-#endif
- return c;
-}
-
diff --git a/src/xsf/desmume/armcpu.cc b/src/xsf/desmume/armcpu.cc
new file mode 100644
index 000000000000..09356fea0598
--- /dev/null
+++ b/src/xsf/desmume/armcpu.cc
@@ -0,0 +1,487 @@
+/* Copyright (C) 2006 yopyop
+ yopyop156 at ifrance.com
+ yopyop156.ifrance.com
+
+ This file is part of DeSmuME
+
+ DeSmuME 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.
+
+ DeSmuME 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 DeSmuME; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "arm_instructions.h"
+#include "thumb_instructions.h"
+#include "cp15.h"
+#include "bios.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+const unsigned char arm_cond_table[16*16] = {
+ /* N=0, Z=0, C=0, V=0 */
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
+ 0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
+ /* N=0, Z=0, C=0, V=1 */
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x00,
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
+ /* N=0, Z=0, C=1, V=0 */
+ 0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,
+ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
+ /* N=0, Z=0, C=1, V=1 */
+ 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,
+ 0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
+ /* N=0, Z=1, C=0, V=0 */
+ 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,
+ 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
+ /* N=0, Z=1, C=0, V=1 */
+ 0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00,
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
+ /* N=0, Z=1, C=1, V=0 */
+ 0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF,
+ 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
+ /* N=0, Z=1, C=1, V=1 */
+ 0xFF,0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00,
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
+ /* N=1, Z=0, C=0, V=0 */
+ 0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00,0xFF,
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
+ /* N=1, Z=0, C=0, V=1 */
+ 0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x00,
+ 0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
+ /* N=1, Z=0, C=1, V=0 */
+ 0x00,0xFF,0xFF,0x00,0xFF,0x00,0x00,0xFF,
+ 0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
+ /* N=1, Z=0, C=1, V=1 */
+ 0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x00,
+ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
+ /* N=1, Z=1, C=0, V=0 */
+ 0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
+ /* N=1, Z=1, C=0, V=1 */
+ 0xFF,0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00,
+ 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
+ /* N=1, Z=1, C=1, V=0 */
+ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF,
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
+ /* N=1, Z=1, C=1, V=1 */
+ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
+ 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
+};
+
+armcpu_t NDS_ARM7;
+armcpu_t NDS_ARM9;
+
+#define SWAP(a, b, c) do \
+ { \
+ c=a; \
+ a=b; \
+ b=c; \
+ } \
+ while(0)
+
+#ifdef GDB_STUB
+
+#define STALLED_CYCLE_COUNT 10
+
+static void
+stall_cpu( void *instance) {
+ armcpu_t *armcpu = (armcpu_t *)instance;
+
+ armcpu->stalled = 1;
+}
+
+static void
+unstall_cpu( void *instance) {
+ armcpu_t *armcpu = (armcpu_t *)instance;
+
+ armcpu->stalled = 0;
+}
+
+static void
+install_post_exec_fn( void *instance,
+ void (*ex_fn)( void *, u32 adr, int thumb),
+ void *fn_data) {
+ armcpu_t *armcpu = (armcpu_t *)instance;
+
+ armcpu->post_ex_fn = ex_fn;
+ armcpu->post_ex_fn_data = fn_data;
+}
+
+static void
+remove_post_exec_fn( void *instance) {
+ armcpu_t *armcpu = (armcpu_t *)instance;
+
+ armcpu->post_ex_fn = nullptr;
+}
+#endif
+
+#ifdef GDB_STUB
+int armcpu_new( armcpu_t *armcpu, u32 id,
+ struct armcpu_memory_iface *mem_if,
+ struct armcpu_ctrl_iface **ctrl_iface_ret)
+#else
+int armcpu_new( armcpu_t *armcpu, u32 id)
+#endif
+{
+ armcpu->proc_ID = id;
+
+ if(id==0)
+ armcpu->swi_tab = ARM9_swi_tab;
+ else
+ armcpu->swi_tab = ARM7_swi_tab;
+
+#ifdef GDB_STUB
+ armcpu->mem_if = mem_if;
+
+ /* populate the control interface */
+ armcpu->ctrl_iface.stall = stall_cpu;
+ armcpu->ctrl_iface.unstall = unstall_cpu;
+ armcpu->ctrl_iface.read_reg = read_cpu_reg;
+ armcpu->ctrl_iface.set_reg = set_cpu_reg;
+ armcpu->ctrl_iface.install_post_ex_fn = install_post_exec_fn;
+ armcpu->ctrl_iface.remove_post_ex_fn = remove_post_exec_fn;
+ armcpu->ctrl_iface.data = armcpu;
+
+ *ctrl_iface_ret = &armcpu->ctrl_iface;
+
+ armcpu->stalled = 0;
+ armcpu->post_ex_fn = nullptr;
+#endif
+
+ armcpu_init(armcpu, 0);
+
+ return 0;
+}
+
+void armcpu_init(armcpu_t *armcpu, u32 adr)
+{
+ u32 i;
+
+ armcpu->LDTBit = (armcpu->proc_ID==0); //Si ARM9 utiliser le syte v5 pour le load
+ armcpu->intVector = 0xFFFF0000 * (armcpu->proc_ID==0);
+ armcpu->waitIRQ = false;
+ armcpu->wirq = false;
+
+#ifdef GDB_STUB
+ armcpu->irq_flag = 0;
+#endif
+
+ if(armcpu->coproc[15]) free(armcpu->coproc[15]);
+
+ for(i = 0; i < 15; ++i)
+ {
+ armcpu->R[i] = 0;
+ armcpu->coproc[i] = nullptr;
+ }
+
+ armcpu->CPSR.val = armcpu->SPSR.val = SYS;
+
+ armcpu->R13_usr = armcpu->R14_usr = 0;
+ armcpu->R13_svc = armcpu->R14_svc = 0;
+ armcpu->R13_abt = armcpu->R14_abt = 0;
+ armcpu->R13_und = armcpu->R14_und = 0;
+ armcpu->R13_irq = armcpu->R14_irq = 0;
+ armcpu->R8_fiq = armcpu->R9_fiq = armcpu->R10_fiq = armcpu->R11_fiq = armcpu->R12_fiq = armcpu->R13_fiq = armcpu->R14_fiq = 0;
+
+ armcpu->SPSR_svc.val = armcpu->SPSR_abt.val = armcpu->SPSR_und.val = armcpu->SPSR_irq.val = armcpu->SPSR_fiq.val = 0;
+
+#ifdef GDB_STUB
+ armcpu->instruct_adr = adr;
+ armcpu->R[15] = adr + 8;
+#else
+ armcpu->R[15] = adr;
+#endif
+
+ armcpu->next_instruction = adr;
+
+ armcpu->coproc[15] = (armcp_t*)armcp15_new(armcpu);
+
+#ifndef GDB_STUB
+ armcpu_prefetch(armcpu);
+#endif
+}
+
+u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode)
+{
+ u32 oldmode = armcpu->CPSR.bits.mode;
+
+ switch(oldmode)
+ {
+ case USR :
+ case SYS :
+ armcpu->R13_usr = armcpu->R[13];
+ armcpu->R14_usr = armcpu->R[14];
+ break;
+
+ case FIQ :
+ {
+ u32 tmp;
+ SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
+ SWAP(armcpu->R[9], armcpu->R9_fiq, tmp);
+ SWAP(armcpu->R[10], armcpu->R10_fiq, tmp);
+ SWAP(armcpu->R[11], armcpu->R11_fiq, tmp);
+ SWAP(armcpu->R[12], armcpu->R12_fiq, tmp);
+ armcpu->R13_fiq = armcpu->R[13];
+ armcpu->R14_fiq = armcpu->R[14];
+ armcpu->SPSR_fiq = armcpu->SPSR;
+ break;
+ }
+ case IRQ :
+ armcpu->R13_irq = armcpu->R[13];
+ armcpu->R14_irq = armcpu->R[14];
+ armcpu->SPSR_irq = armcpu->SPSR;
+ break;
+
+ case SVC :
+ armcpu->R13_svc = armcpu->R[13];
+ armcpu->R14_svc = armcpu->R[14];
+ armcpu->SPSR_svc = armcpu->SPSR;
+ break;
+
+ case ABT :
+ armcpu->R13_abt = armcpu->R[13];
+ armcpu->R14_abt = armcpu->R[14];
+ armcpu->SPSR_abt = armcpu->SPSR;
+ break;
+
+ case UND :
+ armcpu->R13_und = armcpu->R[13];
+ armcpu->R14_und = armcpu->R[14];
+ armcpu->SPSR_und = armcpu->SPSR;
+ break;
+ default :
+ break;
+ }
+
+ switch(mode)
+ {
+ case USR :
+ case SYS :
+ armcpu->R[13] = armcpu->R13_usr;
+ armcpu->R[14] = armcpu->R14_usr;
+ //SPSR = CPSR;
+ break;
+
+ case FIQ :
+ {
+ u32 tmp;
+ SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
+ SWAP(armcpu->R[9], armcpu->R9_fiq, tmp);
+ SWAP(armcpu->R[10], armcpu->R10_fiq, tmp);
+ SWAP(armcpu->R[11], armcpu->R11_fiq, tmp);
+ SWAP(armcpu->R[12], armcpu->R12_fiq, tmp);
+ armcpu->R[13] = armcpu->R13_fiq;
+ armcpu->R[14] = armcpu->R14_fiq;
+ armcpu->SPSR = armcpu->SPSR_fiq;
+ break;
+ }
+
+ case IRQ :
+ armcpu->R[13] = armcpu->R13_irq;
+ armcpu->R[14] = armcpu->R14_irq;
+ armcpu->SPSR = armcpu->SPSR_irq;
+ break;
+
+ case SVC :
+ armcpu->R[13] = armcpu->R13_svc;
+ armcpu->R[14] = armcpu->R14_svc;
+ armcpu->SPSR = armcpu->SPSR_svc;
+ break;
+
+ case ABT :
+ armcpu->R[13] = armcpu->R13_abt;
+ armcpu->R[14] = armcpu->R14_abt;
+ armcpu->SPSR = armcpu->SPSR_abt;
+ break;
+
+ case UND :
+ armcpu->R[13] = armcpu->R13_und;
+ armcpu->R[14] = armcpu->R14_und;
+ armcpu->SPSR = armcpu->SPSR_und;
+ break;
+
+ default :
+ break;
+ }
+
+ armcpu->CPSR.bits.mode = mode & 0x1F;
+ return oldmode;
+}
+
+u32 armcpu_prefetch(armcpu_t *armcpu)
+{
+#ifdef GDB_STUB
+ u32 temp_instruction;
+#endif
+
+ if(armcpu->CPSR.bits.T == 0)
+ {
+#ifdef GDB_STUB
+ temp_instruction =
+ armcpu->mem_if->prefetch32( armcpu->mem_if->data,
+ armcpu->next_instruction);
+
+ if ( !armcpu->stalled) {
+ armcpu->instruction = temp_instruction;
+ armcpu->instruct_adr = armcpu->next_instruction;
+ armcpu->next_instruction += 4;
+ armcpu->R[15] = armcpu->next_instruction + 4;
+ }
+#else
+ armcpu->instruction = MMU_read32_acl(armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
+
+ armcpu->instruct_adr = armcpu->next_instruction;
+ armcpu->next_instruction += 4;
+ armcpu->R[15] = armcpu->next_instruction + 4;
+#endif
+
+ return MMU.MMU_WAIT32[armcpu->proc_ID][(armcpu->instruct_adr>>24)&0xF];
+ }
+
+#ifdef GDB_STUB
+ temp_instruction =
+ armcpu->mem_if->prefetch16( armcpu->mem_if->data,
+ armcpu->next_instruction);
+
+ if ( !armcpu->stalled) {
+ armcpu->instruction = temp_instruction;
+ armcpu->instruct_adr = armcpu->next_instruction;
+ armcpu->next_instruction = armcpu->next_instruction + 2;
+ armcpu->R[15] = armcpu->next_instruction + 2;
+ }
+#else
+ armcpu->instruction = MMU_read16_acl(armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
+
+ armcpu->instruct_adr = armcpu->next_instruction;
+ armcpu->next_instruction += 2;
+ armcpu->R[15] = armcpu->next_instruction + 2;
+#endif
+
+ return MMU.MMU_WAIT16[armcpu->proc_ID][(armcpu->instruct_adr>>24)&0xF];
+}
+
+
+BOOL armcpu_irqExeption(armcpu_t *armcpu)
+{
+ Status_Reg tmp;
+
+ if(armcpu->CPSR.bits.I) return false;
+
+#ifdef GDB_STUB
+ armcpu->irq_flag = 0;
+#endif
+
+ tmp = armcpu->CPSR;
+ armcpu_switchMode(armcpu, IRQ);
+
+#ifdef GDB_STUB
+ armcpu->R[14] = armcpu->next_instruction + 4;
+#else
+ armcpu->R[14] = armcpu->instruct_adr + 4;
+#endif
+ armcpu->SPSR = tmp;
+ armcpu->CPSR.bits.T = 0;
+ armcpu->CPSR.bits.I = 1;
+ armcpu->next_instruction = armcpu->intVector + 0x18;
+ armcpu->waitIRQ = 0;
+
+#ifndef GDB_STUB
+ armcpu->R[15] = armcpu->next_instruction + 8;
+ armcpu_prefetch(armcpu);
+#endif
+
+ return true;
+}
+/*
+static BOOL armcpu_prefetchExeption(armcpu_t *armcpu)
+{
+ Status_Reg tmp;
+ if(armcpu->CPSR.bits.I) return false;
+ tmp = armcpu->CPSR;
+ armcpu_switchMode(armcpu, ABT);
+ armcpu->R[14] = armcpu->next_instruction + 4;
+ armcpu->SPSR = tmp;
+ armcpu->CPSR.bits.T = 0;
+ armcpu->CPSR.bits.I = 1;
+ armcpu->next_instruction = armcpu->intVector + 0xC;
+ armcpu->R[15] = armcpu->next_instruction + 8;
+ armcpu->waitIRQ = 0;
+ return true;
+}
+*/
+
+BOOL
+armcpu_flagIrq( armcpu_t *armcpu) {
+ if(armcpu->CPSR.bits.I) return false;
+
+ armcpu->waitIRQ = 0;
+
+#ifdef GDB_STUB
+ armcpu->irq_flag = 1;
+#endif
+
+ return true;
+}
+
+
+u32 armcpu_exec(armcpu_t *armcpu)
+{
+ u32 c = 1;
+
+#ifdef GDB_STUB
+ if ( armcpu->stalled)
+ return STALLED_CYCLE_COUNT;
+
+ /* check for interrupts */
+ if ( armcpu->irq_flag) {
+ armcpu_irqExeption( armcpu);
+ }
+
+ c = armcpu_prefetch(armcpu);
+
+ if ( armcpu->stalled) {
+ return c;
+ }
+#endif
+
+ if(armcpu->CPSR.bits.T == 0)
+ {
+/* if((TEST_COND(CONDITION(armcpu->instruction), armcpu->CPSR)) || ((CONDITION(armcpu->instruction)==0xF)&&(CODE(armcpu->instruction)==0x5)))*/
+ if((TEST_COND(CONDITION(armcpu->instruction), CODE(armcpu->instruction), armcpu->CPSR)))
+ {
+ c += arm_instructions_set[INSTRUCTION_INDEX(armcpu->instruction)](armcpu);
+ }
+#ifdef GDB_STUB
+ if ( armcpu->post_ex_fn != nullptr) {
+ /* call the external post execute function */
+ armcpu->post_ex_fn( armcpu->post_ex_fn_data,
+ armcpu->instruct_adr, 0);
+ }
+#else
+ c += armcpu_prefetch(armcpu);
+#endif
+ return c;
+ }
+
+ c += thumb_instructions_set[armcpu->instruction>>6](armcpu);
+
+#ifdef GDB_STUB
+ if ( armcpu->post_ex_fn != nullptr) {
+ /* call the external post execute function */
+ armcpu->post_ex_fn( armcpu->post_ex_fn_data, armcpu->instruct_adr, 1);
+ }
+#else
+ c += armcpu_prefetch(armcpu);
+#endif
+ return c;
+}
+
diff --git a/src/xsf/desmume/armcpu.h b/src/xsf/desmume/armcpu.h
index 7fa3ef9b4fbd..4b91f9d62de9 100644
--- a/src/xsf/desmume/armcpu.h
+++ b/src/xsf/desmume/armcpu.h
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ARM_CPU
@@ -26,10 +26,6 @@
#include "bits.h"
#include "MMU.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define ARMCPU_ARM7 1
#define ARMCPU_ARM9 0
@@ -249,8 +245,8 @@ static INLINE void NDS_makeARM9Int(u32 num)
/* generate the interrupt if enabled */
if ((MMU.reg_IE[0] & (1 << num)) && MMU.reg_IME[0])
{
- NDS_ARM9.wIRQ = TRUE;
- NDS_ARM9.waitIRQ = FALSE;
+ NDS_ARM9.wIRQ = true;
+ NDS_ARM9.waitIRQ = false;
}
}
@@ -262,8 +258,8 @@ static INLINE void NDS_makeARM7Int(u32 num)
/* generate the interrupt if enabled */
if ((MMU.reg_IE[1] & (1 << num)) && MMU.reg_IME[1])
{
- NDS_ARM7.wIRQ = TRUE;
- NDS_ARM7.waitIRQ = FALSE;
+ NDS_ARM7.wIRQ = true;
+ NDS_ARM7.waitIRQ = false;
}
}
@@ -280,9 +276,4 @@ static INLINE void NDS_makeInt(u8 proc_ID,u32 num)
}
}
-
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/src/xsf/desmume/bios.c b/src/xsf/desmume/bios.c
deleted file mode 100644
index 87114043877e..000000000000
--- a/src/xsf/desmume/bios.c
+++ /dev/null
@@ -1,1073 +0,0 @@
-/* Copyright (C) 2006 yopyop
- yopyop156 at ifrance.com
- yopyop156.ifrance.com
-
- This file is part of DeSmuME
-
- DeSmuME 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.
-
- DeSmuME 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 DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include "cp15.h"
-#include <math.h>
-#include "MMU.h"
-#include "SPU.h"
-#include "debug.h"
-
-extern BOOL execute;
-
-static u16 getsinetbl[] = {
-0x0000, 0x0324, 0x0648, 0x096A, 0x0C8C, 0x0FAB, 0x12C8, 0x15E2,
-0x18F9, 0x1C0B, 0x1F1A, 0x2223, 0x2528, 0x2826, 0x2B1F, 0x2E11,
-0x30FB, 0x33DF, 0x36BA, 0x398C, 0x3C56, 0x3F17, 0x41CE, 0x447A,
-0x471C, 0x49B4, 0x4C3F, 0x4EBF, 0x5133, 0x539B, 0x55F5, 0x5842,
-0x5A82, 0x5CB3, 0x5ED7, 0x60EB, 0x62F1, 0x64E8, 0x66CF, 0x68A6,
-0x6A6D, 0x6C23, 0x6DC9, 0x6F5E, 0x70E2, 0x7254, 0x73B5, 0x7504,
-0x7641, 0x776B, 0x7884, 0x7989, 0x7A7C, 0x7B5C, 0x7C29, 0x7CE3,
-0x7D89, 0x7E1D, 0x7E9C, 0x7F09, 0x7F61, 0x7FA6, 0x7FD8, 0x7FF5
-};
-
-static u16 getpitchtbl[] = {
-0x0000, 0x003B, 0x0076, 0x00B2, 0x00ED, 0x0128, 0x0164, 0x019F,
-0x01DB, 0x0217, 0x0252, 0x028E, 0x02CA, 0x0305, 0x0341, 0x037D,
-0x03B9, 0x03F5, 0x0431, 0x046E, 0x04AA, 0x04E6, 0x0522, 0x055F,
-0x059B, 0x05D8, 0x0614, 0x0651, 0x068D, 0x06CA, 0x0707, 0x0743,
-0x0780, 0x07BD, 0x07FA, 0x0837, 0x0874, 0x08B1, 0x08EF, 0x092C,
-0x0969, 0x09A7, 0x09E4, 0x0A21, 0x0A5F, 0x0A9C, 0x0ADA, 0x0B18,
-0x0B56, 0x0B93, 0x0BD1, 0x0C0F, 0x0C4D, 0x0C8B, 0x0CC9, 0x0D07,
-0x0D45, 0x0D84, 0x0DC2, 0x0E00, 0x0E3F, 0x0E7D, 0x0EBC, 0x0EFA,
-0x0F39, 0x0F78, 0x0FB6, 0x0FF5, 0x1034, 0x1073, 0x10B2, 0x10F1,
-0x1130, 0x116F, 0x11AE, 0x11EE, 0x122D, 0x126C, 0x12AC, 0x12EB,
-0x132B, 0x136B, 0x13AA, 0x13EA, 0x142A, 0x146A, 0x14A9, 0x14E9,
-0x1529, 0x1569, 0x15AA, 0x15EA, 0x162A, 0x166A, 0x16AB, 0x16EB,
-0x172C, 0x176C, 0x17AD, 0x17ED, 0x182E, 0x186F, 0x18B0, 0x18F0,
-0x1931, 0x1972, 0x19B3, 0x19F5, 0x1A36, 0x1A77, 0x1AB8, 0x1AFA,
-0x1B3B, 0x1B7D, 0x1BBE, 0x1C00, 0x1C41, 0x1C83, 0x1CC5, 0x1D07,
-0x1D48, 0x1D8A, 0x1DCC, 0x1E0E, 0x1E51, 0x1E93, 0x1ED5, 0x1F17,
-0x1F5A, 0x1F9C, 0x1FDF, 0x2021, 0x2064, 0x20A6, 0x20E9, 0x212C,
-0x216F, 0x21B2, 0x21F5, 0x2238, 0x227B, 0x22BE, 0x2301, 0x2344,
-0x2388, 0x23CB, 0x240E, 0x2452, 0x2496, 0x24D9, 0x251D, 0x2561,
-0x25A4, 0x25E8, 0x262C, 0x2670, 0x26B4, 0x26F8, 0x273D, 0x2781,
-0x27C5, 0x280A, 0x284E, 0x2892, 0x28D7, 0x291C, 0x2960, 0x29A5,
-0x29EA, 0x2A2F, 0x2A74, 0x2AB9, 0x2AFE, 0x2B43, 0x2B88, 0x2BCD,
-0x2C13, 0x2C58, 0x2C9D, 0x2CE3, 0x2D28, 0x2D6E, 0x2DB4, 0x2DF9,
-0x2E3F, 0x2E85, 0x2ECB, 0x2F11, 0x2F57, 0x2F9D, 0x2FE3, 0x302A,
-0x3070, 0x30B6, 0x30FD, 0x3143, 0x318A, 0x31D0, 0x3217, 0x325E,
-0x32A5, 0x32EC, 0x3332, 0x3379, 0x33C1, 0x3408, 0x344F, 0x3496,
-0x34DD, 0x3525, 0x356C, 0x35B4, 0x35FB, 0x3643, 0x368B, 0x36D3,
-0x371A, 0x3762, 0x37AA, 0x37F2, 0x383A, 0x3883, 0x38CB, 0x3913,
-0x395C, 0x39A4, 0x39ED, 0x3A35, 0x3A7E, 0x3AC6, 0x3B0F, 0x3B58,
-0x3BA1, 0x3BEA, 0x3C33, 0x3C7C, 0x3CC5, 0x3D0E, 0x3D58, 0x3DA1,
-0x3DEA, 0x3E34, 0x3E7D, 0x3EC7, 0x3F11, 0x3F5A, 0x3FA4, 0x3FEE,
-0x4038, 0x4082, 0x40CC, 0x4116, 0x4161, 0x41AB, 0x41F5, 0x4240,
-0x428A, 0x42D5, 0x431F, 0x436A, 0x43B5, 0x4400, 0x444B, 0x4495,
-0x44E1, 0x452C, 0x4577, 0x45C2, 0x460D, 0x4659, 0x46A4, 0x46F0,
-0x473B, 0x4787, 0x47D3, 0x481E, 0x486A, 0x48B6, 0x4902, 0x494E,
-0x499A, 0x49E6, 0x4A33, 0x4A7F, 0x4ACB, 0x4B18, 0x4B64, 0x4BB1,
-0x4BFE, 0x4C4A, 0x4C97, 0x4CE4, 0x4D31, 0x4D7E, 0x4DCB, 0x4E18,
-0x4E66, 0x4EB3, 0x4F00, 0x4F4E, 0x4F9B, 0x4FE9, 0x5036, 0x5084,
-0x50D2, 0x5120, 0x516E, 0x51BC, 0x520A, 0x5258, 0x52A6, 0x52F4,
-0x5343, 0x5391, 0x53E0, 0x542E, 0x547D, 0x54CC, 0x551A, 0x5569,
-0x55B8, 0x5607, 0x5656, 0x56A5, 0x56F4, 0x5744, 0x5793, 0x57E2,
-0x5832, 0x5882, 0x58D1, 0x5921, 0x5971, 0x59C1, 0x5A10, 0x5A60,
-0x5AB0, 0x5B01, 0x5B51, 0x5BA1, 0x5BF1, 0x5C42, 0x5C92, 0x5CE3,
-0x5D34, 0x5D84, 0x5DD5, 0x5E26, 0x5E77, 0x5EC8, 0x5F19, 0x5F6A,
-0x5FBB, 0x600D, 0x605E, 0x60B0, 0x6101, 0x6153, 0x61A4, 0x61F6,
-0x6248, 0x629A, 0x62EC, 0x633E, 0x6390, 0x63E2, 0x6434, 0x6487,
-0x64D9, 0x652C, 0x657E, 0x65D1, 0x6624, 0x6676, 0x66C9, 0x671C,
-0x676F, 0x67C2, 0x6815, 0x6869, 0x68BC, 0x690F, 0x6963, 0x69B6,
-0x6A0A, 0x6A5E, 0x6AB1, 0x6B05, 0x6B59, 0x6BAD, 0x6C01, 0x6C55,
-0x6CAA, 0x6CFE, 0x6D52, 0x6DA7, 0x6DFB, 0x6E50, 0x6EA4, 0x6EF9,
-0x6F4E, 0x6FA3, 0x6FF8, 0x704D, 0x70A2, 0x70F7, 0x714D, 0x71A2,
-0x71F7, 0x724D, 0x72A2, 0x72F8, 0x734E, 0x73A4, 0x73FA, 0x7450,
-0x74A6, 0x74FC, 0x7552, 0x75A8, 0x75FF, 0x7655, 0x76AC, 0x7702,
-0x7759, 0x77B0, 0x7807, 0x785E, 0x78B4, 0x790C, 0x7963, 0x79BA,
-0x7A11, 0x7A69, 0x7AC0, 0x7B18, 0x7B6F, 0x7BC7, 0x7C1F, 0x7C77,
-0x7CCF, 0x7D27, 0x7D7F, 0x7DD7, 0x7E2F, 0x7E88, 0x7EE0, 0x7F38,
-0x7F91, 0x7FEA, 0x8042, 0x809B, 0x80F4, 0x814D, 0x81A6, 0x81FF,
-0x8259, 0x82B2, 0x830B, 0x8365, 0x83BE, 0x8418, 0x8472, 0x84CB,
-0x8525, 0x857F, 0x85D9, 0x8633, 0x868E, 0x86E8, 0x8742, 0x879D,
-0x87F7, 0x8852, 0x88AC, 0x8907, 0x8962, 0x89BD, 0x8A18, 0x8A73,
-0x8ACE, 0x8B2A, 0x8B85, 0x8BE0, 0x8C3C, 0x8C97, 0x8CF3, 0x8D4F,
-0x8DAB, 0x8E07, 0x8E63, 0x8EBF, 0x8F1B, 0x8F77, 0x8FD4, 0x9030,
-0x908C, 0x90E9, 0x9146, 0x91A2, 0x91FF, 0x925C, 0x92B9, 0x9316,
-0x9373, 0x93D1, 0x942E, 0x948C, 0x94E9, 0x9547, 0x95A4, 0x9602,
-0x9660, 0x96BE, 0x971C, 0x977A, 0x97D8, 0x9836, 0x9895, 0x98F3,
-0x9952, 0x99B0, 0x9A0F, 0x9A6E, 0x9ACD, 0x9B2C, 0x9B8B, 0x9BEA,
-0x9C49, 0x9CA8, 0x9D08, 0x9D67, 0x9DC7, 0x9E26, 0x9E86, 0x9EE6,
-0x9F46, 0x9FA6, 0xA006, 0xA066, 0xA0C6, 0xA127, 0xA187, 0xA1E8,
-0xA248, 0xA2A9, 0xA30A, 0xA36B, 0xA3CC, 0xA42D, 0xA48E, 0xA4EF,
-0xA550, 0xA5B2, 0xA613, 0xA675, 0xA6D6, 0xA738, 0xA79A, 0xA7FC,
-0xA85E, 0xA8C0, 0xA922, 0xA984, 0xA9E7, 0xAA49, 0xAAAC, 0xAB0E,
-0xAB71, 0xABD4, 0xAC37, 0xAC9A, 0xACFD, 0xAD60, 0xADC3, 0xAE27,
-0xAE8A, 0xAEED, 0xAF51, 0xAFB5, 0xB019, 0xB07C, 0xB0E0, 0xB145,
-0xB1A9, 0xB20D, 0xB271, 0xB2D6, 0xB33A, 0xB39F, 0xB403, 0xB468,
-0xB4CD, 0xB532, 0xB597, 0xB5FC, 0xB662, 0xB6C7, 0xB72C, 0xB792,
-0xB7F7, 0xB85D, 0xB8C3, 0xB929, 0xB98F, 0xB9F5, 0xBA5B, 0xBAC1,
-0xBB28, 0xBB8E, 0xBBF5, 0xBC5B, 0xBCC2, 0xBD29, 0xBD90, 0xBDF7,
-0xBE5E, 0xBEC5, 0xBF2C, 0xBF94, 0xBFFB, 0xC063, 0xC0CA, 0xC132,
-0xC19A, 0xC202, 0xC26A, 0xC2D2, 0xC33A, 0xC3A2, 0xC40B, 0xC473,
-0xC4DC, 0xC544, 0xC5AD, 0xC616, 0xC67F, 0xC6E8, 0xC751, 0xC7BB,
-0xC824, 0xC88D, 0xC8F7, 0xC960, 0xC9CA, 0xCA34, 0xCA9E, 0xCB08,
-0xCB72, 0xCBDC, 0xCC47, 0xCCB1, 0xCD1B, 0xCD86, 0xCDF1, 0xCE5B,
-0xCEC6, 0xCF31, 0xCF9C, 0xD008, 0xD073, 0xD0DE, 0xD14A, 0xD1B5,
-0xD221, 0xD28D, 0xD2F8, 0xD364, 0xD3D0, 0xD43D, 0xD4A9, 0xD515,
-0xD582, 0xD5EE, 0xD65B, 0xD6C7, 0xD734, 0xD7A1, 0xD80E, 0xD87B,
-0xD8E9, 0xD956, 0xD9C3, 0xDA31, 0xDA9E, 0xDB0C, 0xDB7A, 0xDBE8,
-0xDC56, 0xDCC4, 0xDD32, 0xDDA0, 0xDE0F, 0xDE7D, 0xDEEC, 0xDF5B,
-0xDFC9, 0xE038, 0xE0A7, 0xE116, 0xE186, 0xE1F5, 0xE264, 0xE2D4,
-0xE343, 0xE3B3, 0xE423, 0xE493, 0xE503, 0xE573, 0xE5E3, 0xE654,
-0xE6C4, 0xE735, 0xE7A5, 0xE816, 0xE887, 0xE8F8, 0xE969, 0xE9DA,
-0xEA4B, 0xEABC, 0xEB2E, 0xEB9F, 0xEC11, 0xEC83, 0xECF5, 0xED66,
-0xEDD9, 0xEE4B, 0xEEBD, 0xEF2F, 0xEFA2, 0xF014, 0xF087, 0xF0FA,
-0xF16D, 0xF1E0, 0xF253, 0xF2C6, 0xF339, 0xF3AD, 0xF420, 0xF494,
-0xF507, 0xF57B, 0xF5EF, 0xF663, 0xF6D7, 0xF74C, 0xF7C0, 0xF834,
-0xF8A9, 0xF91E, 0xF992, 0xFA07, 0xFA7C, 0xFAF1, 0xFB66, 0xFBDC,
-0xFC51, 0xFCC7, 0xFD3C, 0xFDB2, 0xFE28, 0xFE9E, 0xFF14, 0xFF8A
-};
-
-static u8 getvoltbl[] = {
-0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
-0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08,
-0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
-0x09, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
-0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E,
-0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10,
-0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14,
-0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x18,
-0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1C,
-0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
-0x22, 0x23, 0x23, 0x24, 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x27, 0x28, 0x28, 0x29,
-0x29, 0x2A, 0x2A, 0x2B, 0x2B, 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, 0x30, 0x31, 0x31,
-0x32, 0x32, 0x33, 0x33, 0x34, 0x35, 0x35, 0x36, 0x36, 0x37, 0x38, 0x38, 0x39, 0x3A, 0x3A, 0x3B,
-0x3C, 0x3C, 0x3D, 0x3E, 0x3F, 0x3F, 0x40, 0x41, 0x42, 0x42, 0x43, 0x44, 0x45, 0x45, 0x46, 0x47,
-0x48, 0x49, 0x4A, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x52, 0x53, 0x54, 0x55,
-0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67,
-0x68, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x6F, 0x71, 0x72, 0x73, 0x75, 0x76, 0x77, 0x79, 0x7A, 0x7B,
-0x7D, 0x7E, 0x7F, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25,
-0x26, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, 0x2C, 0x2C, 0x2D,
-0x2D, 0x2E, 0x2E, 0x2F, 0x2F, 0x30, 0x30, 0x31, 0x31, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x36,
-0x36, 0x37, 0x37, 0x38, 0x39, 0x39, 0x3A, 0x3B, 0x3B, 0x3C, 0x3D, 0x3E, 0x3E, 0x3F, 0x40, 0x40,
-0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x47, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4D,
-0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D,
-0x5E, 0x5F, 0x60, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6F, 0x70,
-0x71, 0x73, 0x74, 0x75, 0x77, 0x78, 0x79, 0x7B, 0x7C, 0x7E, 0x7E, 0x40, 0x41, 0x42, 0x43, 0x43,
-0x44, 0x45, 0x46, 0x47, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
-0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61,
-0x62, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D, 0x6E, 0x70, 0x71, 0x72, 0x74, 0x75,
-0x76, 0x78, 0x79, 0x7B, 0x7C, 0x7D, 0x7E, 0x40, 0x41, 0x42, 0x42, 0x43, 0x44, 0x45, 0x46, 0x46,
-0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55,
-0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x65, 0x66,
-0x67, 0x68, 0x69, 0x6A, 0x6C, 0x6D, 0x6E, 0x6F, 0x71, 0x72, 0x73, 0x75, 0x76, 0x77, 0x79, 0x7A,
-0x7C, 0x7D, 0x7E, 0x7F
-};
-
-u32 bios_nop(armcpu_t * cpu)
-{
- if (cpu->proc_ID == ARMCPU_ARM9)
- {
- LOG("Unimplemented bios function %02X(ARM9) was used. R0:%08X\n", (cpu->instruction)&0x1F, cpu->R[0]);
- }
- else
- {
- LOG("Unimplemented bios function %02X(ARM7) was used. R0:%08X\n", (cpu->instruction)&0x1F, cpu->R[0]);
- }
- return 3;
-}
-
-u32 delayLoop(armcpu_t * cpu)
-{
- return cpu->R[0] * 4;
-}
-
-//u32 oldmode[2];
-
-u32 intrWaitARM(armcpu_t * cpu)
-{
- u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8;
- u32 intr;
- u32 intrFlag = 0;
-
- //execute = FALSE;
- if(cpu->proc_ID)
- {
- intrFlagAdr = 0x380FFF8;
- } else {
- intrFlagAdr = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8;
- }
- intr = MMU_read32(cpu->proc_ID, intrFlagAdr);
- intrFlag = cpu->R[1] & intr;
-
- if(intrFlag)
- {
- // si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s)
- // on efface son(les) occurence(s).
- intr ^= intrFlag;
- MMU_write32(cpu->proc_ID, intrFlagAdr, intr);
- //cpu->switchMode(oldmode[cpu->proc_ID]);
- return 1;
- }
-
- cpu->R[15] = cpu->instruct_adr;
- cpu->next_instruction = cpu->R[15];
- cpu->waitIRQ = 1;
- //oldmode[cpu->proc_ID] = cpu->switchMode(SVC);
-
- return 1;
-}
-
-u32 waitVBlankARM(armcpu_t * cpu)
-{
- u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8;
- u32 intr;
- u32 intrFlag = 0;
-
- //execute = FALSE;
- if(cpu->proc_ID)
- {
- intrFlagAdr = 0x380FFF8;
- } else {
- intrFlagAdr = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8;
- }
- intr = MMU_read32(cpu->proc_ID, intrFlagAdr);
- intrFlag = 1 & intr;
-
- if(intrFlag)
- {
- // si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s)
- // on efface son(les) occurence(s).
- intr ^= intrFlag;
- MMU_write32(cpu->proc_ID, intrFlagAdr, intr);
- //cpu->switchMode(oldmode[cpu->proc_ID]);
- return 1;
- }
-
- cpu->R[15] = cpu->instruct_adr;
- cpu->next_instruction = cpu->R[15];
- cpu->waitIRQ = 1;
- //oldmode[cpu->proc_ID] = cpu->switchMode(SVC);
-
- return 1;
-}
-
-u32 wait4IRQ(armcpu_t* cpu)
-{
- //execute= FALSE;
- if(cpu->wirq)
- {
- if(!cpu->waitIRQ)
- {
- cpu->waitIRQ = 0;
- cpu->wirq = 0;
- //cpu->switchMode(oldmode[cpu->proc_ID]);
- return 1;
- }
- cpu->R[15] = cpu->instruct_adr;
- cpu->next_instruction = cpu->R[15];
- return 1;
- }
- cpu->waitIRQ = 1;
- cpu->wirq = 1;
- cpu->R[15] = cpu->instruct_adr;
- cpu->next_instruction = cpu->R[15];
- //oldmode[cpu->proc_ID] = cpu->switchMode(SVC);
- return 1;
-}
-
-u32 devide(armcpu_t* cpu)
-{
- s32 num = (s32)cpu->R[0];
- s32 dnum = (s32)cpu->R[1];
-
- if(dnum==0) return 0;
-
- cpu->R[0] = (u32)(num / dnum);
- cpu->R[1] = (u32)(num % dnum);
- cpu->R[3] = (u32) (((s32)cpu->R[0])<0 ? -cpu->R[0] : cpu->R[0]);
-
- return 6;
-}
-
-u32 copy(armcpu_t* cpu)
-{
- u32 src = cpu->R[0];
- u32 dst = cpu->R[1];
- u32 cnt = cpu->R[2];
-
- switch(BIT26(cnt))
- {
- case 0:
- src &= 0xFFFFFFFE;
- dst &= 0xFFFFFFFE;
- switch(BIT24(cnt))
- {
- case 0:
- cnt &= 0x1FFFFF;
- while(cnt)
- {
- MMU_write16(cpu->proc_ID, dst, MMU_read16(cpu->proc_ID, src));
- cnt--;
- dst+=2;
- src+=2;
- }
- break;
- case 1:
- {
- u32 val = MMU_read16(cpu->proc_ID, src);
- cnt &= 0x1FFFFF;
- while(cnt)
- {
- MMU_write16(cpu->proc_ID, dst, val);
- cnt--;
- dst+=2;
- }
- }
- break;
- }
- break;
- case 1:
- src &= 0xFFFFFFFC;
- dst &= 0xFFFFFFFC;
- switch(BIT24(cnt))
- {
- case 0:
- cnt &= 0x1FFFFF;
- while(cnt)
- {
- MMU_write32(cpu->proc_ID, dst, MMU_read32(cpu->proc_ID, src));
- cnt--;
- dst+=4;
- src+=4;
- }
- break;
- case 1:
- {
- u32 val = MMU_read32(cpu->proc_ID, src);
- cnt &= 0x1FFFFF;
- while(cnt)
- {
- MMU_write32(cpu->proc_ID, dst, val);
- cnt--;
- dst+=4;
- }
- }
- break;
- }
- break;
- }
- return 1;
-}
-
-u32 fastCopy(armcpu_t* cpu)
-{
- u32 src = cpu->R[0] & 0xFFFFFFFC;
- u32 dst = cpu->R[1] & 0xFFFFFFFC;
- u32 cnt = cpu->R[2];
-
- switch(BIT24(cnt))
- {
- case 0:
- cnt &= 0x1FFFFF;
- while(cnt)
- {
- MMU_write32(cpu->proc_ID, dst, MMU_read32(cpu->proc_ID, src));
- cnt--;
- dst+=4;
- src+=4;
- }
- break;
- case 1:
- {
- u32 val = MMU_read32(cpu->proc_ID, src);
- cnt &= 0x1FFFFF;
- while(cnt)
- {
- MMU_write32(cpu->proc_ID, dst, val);
- cnt--;
- dst+=4;
- }
- }
- break;
- }
- return 1;
-}
-
-u32 LZ77UnCompVram(armcpu_t* cpu)
-{
- int i1, i2;
- int byteCount;
- int byteShift;
- u32 writeValue;
- int len;
- u32 source = cpu->R[0];
- u32 dest = cpu->R[1];
- u32 header = MMU_read32(cpu->proc_ID, source);
- source += 4;
-
- if(((source & 0xe000000) == 0) ||
- ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)
- return 0;
-
- byteCount = 0;
- byteShift = 0;
- writeValue = 0;
-
- len = header >> 8;
-
- while(len > 0) {
- u8 d = MMU_read8(cpu->proc_ID, source++);
-
- if(d) {
- for(i1 = 0; i1 < 8; i1++) {
- if(d & 0x80) {
- int length;
- int offset;
- u32 windowOffset;
- u16 data = MMU_read8(cpu->proc_ID, source++) << 8;
- data |= MMU_read8(cpu->proc_ID, source++);
- length = (data >> 12) + 3;
- offset = (data & 0x0FFF);
- windowOffset = dest + byteCount - offset - 1;
- for(i2 = 0; i2 < length; i2++) {
- writeValue |= (MMU_read8(cpu->proc_ID, windowOffset++) << byteShift);
- byteShift += 8;
- byteCount++;
-
- if(byteCount == 2) {
- MMU_write16(cpu->proc_ID, dest, writeValue);
- dest += 2;
- byteCount = 0;
- byteShift = 0;
- writeValue = 0;
- }
- len--;
- if(len == 0)
- return 0;
- }
- } else {
- writeValue |= (MMU_read8(cpu->proc_ID, source++) << byteShift);
- byteShift += 8;
- byteCount++;
- if(byteCount == 2) {
- MMU_write16(cpu->proc_ID, dest, writeValue);
- dest += 2;
- byteCount = 0;
- byteShift = 0;
- writeValue = 0;
- }
- len--;
- if(len == 0)
- return 0;
- }
- d <<= 1;
- }
- } else {
- for(i1 = 0; i1 < 8; i1++) {
- writeValue |= (MMU_read8(cpu->proc_ID, source++) << byteShift);
- byteShift += 8;
- byteCount++;
- if(byteCount == 2) {
- MMU_write16(cpu->proc_ID, dest, writeValue);
- dest += 2;
- byteShift = 0;
- byteCount = 0;
- writeValue = 0;
- }
- len--;
- if(len == 0)
- return 0;
- }
- }
- }
- return 1;
-}
-
-u32 LZ77UnCompWram(armcpu_t* cpu)
-{
- int i1, i2;
- int len;
- u32 source = cpu->R[0];
- u32 dest = cpu->R[1];
-
- u32 header = MMU_read32(cpu->proc_ID, source);
- source += 4;
-
- if(((source & 0xe000000) == 0) ||
- ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)
- return 0;
-
- len = header >> 8;
-
- while(len > 0) {
- u8 d = MMU_read8(cpu->proc_ID, source++);
-
- if(d) {
- for(i1 = 0; i1 < 8; i1++) {
- if(d & 0x80) {
- int length;
- int offset;
- u32 windowOffset;
- u16 data = MMU_read8(cpu->proc_ID, source++) << 8;
- data |= MMU_read8(cpu->proc_ID, source++);
- length = (data >> 12) + 3;
- offset = (data & 0x0FFF);
- windowOffset = dest - offset - 1;
- for(i2 = 0; i2 < length; i2++) {
- MMU_write8(cpu->proc_ID, dest++, MMU_read8(cpu->proc_ID, windowOffset++));
- len--;
- if(len == 0)
- return 0;
- }
- } else {
- MMU_write8(cpu->proc_ID, dest++, MMU_read8(cpu->proc_ID, source++));
- len--;
- if(len == 0)
- return 0;
- }
- d <<= 1;
- }
- } else {
- for(i1 = 0; i1 < 8; i1++) {
- MMU_write8(cpu->proc_ID, dest++, MMU_read8(cpu->proc_ID, source++));
- len--;
- if(len == 0)
- return 0;
- }
- }
- }
- return 1;
-}
-
-u32 RLUnCompVram(armcpu_t* cpu)
-{
- int i;
- int len;
- int byteCount;
- int byteShift;
- u32 writeValue;
- u32 source = cpu->R[0];
- u32 dest = cpu->R[1];
-
- u32 header = MMU_read32(cpu->proc_ID, source);
- source += 4;
-
- if(((source & 0xe000000) == 0) ||
- ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)
- return 0;
-
- len = header >> 8;
- byteCount = 0;
- byteShift = 0;
- writeValue = 0;
-
- while(len > 0) {
- u8 d = MMU_read8(cpu->proc_ID, source++);
- int l = d & 0x7F;
- if(d & 0x80) {
- u8 data = MMU_read8(cpu->proc_ID, source++);
- l += 3;
- for(i = 0;i < l; i++) {
- writeValue |= (data << byteShift);
- byteShift += 8;
- byteCount++;
-
- if(byteCount == 2) {
- MMU_write16(cpu->proc_ID, dest, writeValue);
- dest += 2;
- byteCount = 0;
- byteShift = 0;
- writeValue = 0;
- }
- len--;
- if(len == 0)
- return 0;
- }
- } else {
- l++;
- for(i = 0; i < l; i++) {
- writeValue |= (MMU_read8(cpu->proc_ID, source++) << byteShift);
- byteShift += 8;
- byteCount++;
- if(byteCount == 2) {
- MMU_write16(cpu->proc_ID, dest, writeValue);
- dest += 2;
- byteCount = 0;
- byteShift = 0;
- writeValue = 0;
- }
- len--;
- if(len == 0)
- return 0;
- }
- }
- }
- return 1;
-}
-
-u32 RLUnCompWram(armcpu_t* cpu)
-{
- int i;
- int len;
- u32 source = cpu->R[0];
- u32 dest = cpu->R[1];
-
- u32 header = MMU_read32(cpu->proc_ID, source);
- source += 4;
-
- if(((source & 0xe000000) == 0) ||
- ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)
- return 0;
-
- len = header >> 8;
-
- while(len > 0) {
- u8 d = MMU_read8(cpu->proc_ID, source++);
- int l = d & 0x7F;
- if(d & 0x80) {
- u8 data = MMU_read8(cpu->proc_ID, source++);
- l += 3;
- for(i = 0;i < l; i++) {
- MMU_write8(cpu->proc_ID, dest++, data);
- len--;
- if(len == 0)
- return 0;
- }
- } else {
- l++;
- for(i = 0; i < l; i++) {
- MMU_write8(cpu->proc_ID, dest++, MMU_read8(cpu->proc_ID, source++));
- len--;
- if(len == 0)
- return 0;
- }
- }
- }
- return 1;
-}
-
-u32 UnCompHuffman(armcpu_t* cpu)
-{
- u32 source, dest, writeValue, header, treeStart, mask;
- u32 data;
- u8 treeSize, currentNode, rootNode;
- int byteCount, byteShift, len, pos;
- int writeData;
-
- source = cpu->R[0];
- dest = cpu->R[1];
-
- header = MMU_read8(cpu->proc_ID, source);
- source += 4;
-
- if(((source & 0xe000000) == 0) ||
- ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)
- return 0;
-
- treeSize = MMU_read8(cpu->proc_ID, source++);
-
- treeStart = source;
-
- source += ((treeSize+1)<<1)-1; // minus because we already skipped one byte
-
- len = header >> 8;
-
- mask = 0x80000000;
- data = MMU_read8(cpu->proc_ID, source);
- source += 4;
-
- pos = 0;
- rootNode = MMU_read8(cpu->proc_ID, treeStart);
- currentNode = rootNode;
- writeData = 0;
- byteShift = 0;
- byteCount = 0;
- writeValue = 0;
-
- if((header & 0x0F) == 8) {
- while(len > 0) {
- // take left
- if(pos == 0)
- pos++;
- else
- pos += (((currentNode & 0x3F)+1)<<1);
-
- if(data & mask) {
- // right
- if(currentNode & 0x40)
- writeData = 1;
- currentNode = MMU_read8(cpu->proc_ID, treeStart+pos+1);
- } else {
- // left
- if(currentNode & 0x80)
- writeData = 1;
- currentNode = MMU_read8(cpu->proc_ID, treeStart+pos);
- }
-
- if(writeData) {
- writeValue |= (currentNode << byteShift);
- byteCount++;
- byteShift += 8;
-
- pos = 0;
- currentNode = rootNode;
- writeData = 0;
-
- if(byteCount == 4) {
- byteCount = 0;
- byteShift = 0;
- MMU_write8(cpu->proc_ID, dest, writeValue);
- writeValue = 0;
- dest += 4;
- len -= 4;
- }
- }
- mask >>= 1;
- if(mask == 0) {
- mask = 0x80000000;
- data = MMU_read8(cpu->proc_ID, source);
- source += 4;
- }
- }
- } else {
- int halfLen = 0;
- int value = 0;
- while(len > 0) {
- // take left
- if(pos == 0)
- pos++;
- else
- pos += (((currentNode & 0x3F)+1)<<1);
-
- if((data & mask)) {
- // right
- if(currentNode & 0x40)
- writeData = 1;
- currentNode = MMU_read8(cpu->proc_ID, treeStart+pos+1);
- } else {
- // left
- if(currentNode & 0x80)
- writeData = 1;
- currentNode = MMU_read8(cpu->proc_ID, treeStart+pos);
- }
-
- if(writeData) {
- if(halfLen == 0)
- value |= currentNode;
- else
- value |= (currentNode<<4);
-
- halfLen += 4;
- if(halfLen == 8) {
- writeValue |= (value << byteShift);
- byteCount++;
- byteShift += 8;
-
- halfLen = 0;
- value = 0;
-
- if(byteCount == 4) {
- byteCount = 0;
- byteShift = 0;
- MMU_write8(cpu->proc_ID, dest, writeValue);
- dest += 4;
- writeValue = 0;
- len -= 4;
- }
- }
- pos = 0;
- currentNode = rootNode;
- writeData = 0;
- }
- mask >>= 1;
- if(mask == 0) {
- mask = 0x80000000;
- data = MMU_read8(cpu->proc_ID, source);
- source += 4;
- }
- }
- }
- return 1;
-}
-
-u32 BitUnPack(armcpu_t* cpu)
-{
- u32 source,dest,header,base,d,temp;
- int len,bits,revbits,dataSize,data,bitwritecount,mask,bitcount,addBase;
- u8 b;
-
- source = cpu->R[0];
- dest = cpu->R[1];
- header = cpu->R[2];
-
- len = MMU_read16(cpu->proc_ID, header);
- // check address
- bits = MMU_read8(cpu->proc_ID, header+2);
- revbits = 8 - bits;
- // u32 value = 0;
- base = MMU_read8(cpu->proc_ID, header+4);
- addBase = (base & 0x80000000) ? 1 : 0;
- base &= 0x7fffffff;
- dataSize = MMU_read8(cpu->proc_ID, header+3);
-
- data = 0;
- bitwritecount = 0;
- while(1) {
- len -= 1;
- if(len < 0)
- break;
- mask = 0xff >> revbits;
- b = MMU_read8(cpu->proc_ID, source);
- source++;
- bitcount = 0;
- while(1) {
- if(bitcount >= 8)
- break;
- d = b & mask;
- temp = d >> bitcount;
- if(!temp && addBase) {
- temp += base;
- }
- data |= temp << bitwritecount;
- bitwritecount += dataSize;
- if(bitwritecount >= 32) {
- MMU_write8(cpu->proc_ID, dest, data);
- dest += 4;
- data = 0;
- bitwritecount = 0;
- }
- mask <<= bits;
- bitcount += bits;
- }
- }
- return 1;
-}
-
-u32 Diff8bitUnFilterWram(armcpu_t* cpu)
-{
- u32 source,dest,header;
- u8 data,diff;
- int len;
-
- source = cpu->R[0];
- dest = cpu->R[1];
-
- header = MMU_read8(cpu->proc_ID, source);
- source += 4;
-
- if(((source & 0xe000000) == 0) ||
- (( (source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0))
- return 0;
-
- len = header >> 8;
-
- data = MMU_read8(cpu->proc_ID, source++);
- MMU_write8(cpu->proc_ID, dest++, data);
- len--;
-
- while(len > 0) {
- diff = MMU_read8(cpu->proc_ID, source++);
- data += diff;
- MMU_write8(cpu->proc_ID, dest++, data);
- len--;
- }
- return 1;
-}
-
-u32 Diff16bitUnFilter(armcpu_t* cpu)
-{
- u32 source,dest,header;
- u16 data;
- int len;
-
- source = cpu->R[0];
- dest = cpu->R[1];
-
- header = MMU_read8(cpu->proc_ID, source);
- source += 4;
-
- if(((source & 0xe000000) == 0) ||
- ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)
- return 0;
-
- len = header >> 8;
-
- data = MMU_read16(cpu->proc_ID, source);
- source += 2;
- MMU_write16(cpu->proc_ID, dest, data);
- dest += 2;
- len -= 2;
-
- while(len >= 2) {
- u16 diff = MMU_read16(cpu->proc_ID, source);
- source += 2;
- data += diff;
- MMU_write16(cpu->proc_ID, dest, data);
- dest += 2;
- len -= 2;
- }
- return 1;
-}
-
-u32 bios_sqrt(armcpu_t* cpu)
-{
- cpu->R[0] = (u32)sqrt((double)(cpu->R[0]));
- return 1;
-}
-
-u32 setHaltCR(armcpu_t* cpu)
-{
- MMU_write8(cpu->proc_ID, 0x4000300+cpu->proc_ID, cpu->R[0]);
- return 1;
-}
-
-u32 getSineTab(armcpu_t* cpu)
-{
- cpu->R[0] = getsinetbl[cpu->R[0]];
- return 1;
-}
-
-u32 getPitchTab(armcpu_t* cpu)
-{
- cpu->R[0] = getpitchtbl[cpu->R[0]];
- return 1;
-}
-
-u32 getVolumeTab(armcpu_t* cpu)
-{
- cpu->R[0] = getvoltbl[cpu->R[0]];
- return 1;
-}
-
-u32 getCRC16(armcpu_t* cpu)
-{
- unsigned int i,j;
-
- u32 crc = cpu->R[0];
- u32 datap = cpu->R[1];
- u32 size = cpu->R[2];
-
- static u16 val[] = { 0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001 };
- for(i = 0; i < size; i++)
- {
- crc = crc ^ MMU_read8( cpu->proc_ID, datap + i);
-
- for(j = 0; j < 8; j++) {
- int do_bit = 0;
-
- if ( crc & 0x1)
- do_bit = 1;
-
- crc = crc >> 1;
-
- if ( do_bit) {
- crc = crc ^ (val[j] << (7-j));
- }
- }
- }
- cpu->R[0] = crc;
- return 1;
-}
-
-u32 SoundBias(armcpu_t* cpu)
-{
- u32 current = SPU_ReadLong(0x4000504);
- if (cpu->R[0] > current)
- SPU_WriteLong(0x4000504, current + 0x1);
- else
- SPU_WriteLong(0x4000504, current - 0x1);
- return cpu->R[1];
-}
-
-u32 (* ARM9_swi_tab[32])(armcpu_t* cpu)={
- bios_nop, // 0x00
- bios_nop, // 0x01
- bios_nop, // 0x02
- delayLoop, // 0x03
- intrWaitARM, // 0x04
- waitVBlankARM, // 0x05
- wait4IRQ, // 0x06
- bios_nop, // 0x07
- bios_nop, // 0x08
- devide, // 0x09
- bios_nop, // 0x0A
- copy, // 0x0B
- fastCopy, // 0x0C
- bios_sqrt, // 0x0D
- getCRC16, // 0x0E
- bios_nop, // 0x0F
- BitUnPack, // 0x10
- LZ77UnCompWram, // 0x11
- LZ77UnCompVram, // 0x12
- UnCompHuffman, // 0x13
- RLUnCompWram, // 0x14
- RLUnCompVram, // 0x15
- Diff8bitUnFilterWram, // 0x16
- bios_nop, // 0x17
- Diff16bitUnFilter, // 0x18
- bios_nop, // 0x19
- bios_nop, // 0x1A
- bios_nop, // 0x1B
- bios_nop, // 0x1C
- bios_nop, // 0x1D
- bios_nop, // 0x1E
- setHaltCR, // 0x1F
-};
-
-u32 (* ARM7_swi_tab[32])(armcpu_t* cpu)={
- bios_nop, // 0x00
- bios_nop, // 0x01
- bios_nop, // 0x02
- delayLoop, // 0x03
- intrWaitARM, // 0x04
- waitVBlankARM, // 0x05
- wait4IRQ, // 0x06
- wait4IRQ, // 0x07
- SoundBias, // 0x08
- devide, // 0x09
- bios_nop, // 0x0A
- copy, // 0x0B
- fastCopy, // 0x0C
- bios_sqrt, // 0x0D
- getCRC16, // 0x0E
- bios_nop, // 0x0F
- BitUnPack, // 0x10
- LZ77UnCompWram, // 0x11
- LZ77UnCompVram, // 0x12
- UnCompHuffman, // 0x13
- RLUnCompWram, // 0x14
- RLUnCompVram, // 0x15
- Diff8bitUnFilterWram, // 0x16
- bios_nop, // 0x17
- bios_nop, // 0x18
- bios_nop, // 0x19
- getSineTab, // 0x1A
- getPitchTab, // 0x1B
- getVolumeTab, // 0x1C
- bios_nop, // 0x1D
- bios_nop, // 0x1E
- setHaltCR, // 0x1F
-};
diff --git a/src/xsf/desmume/bios.cc b/src/xsf/desmume/bios.cc
new file mode 100644
index 000000000000..2a0c7727c19d
--- /dev/null
+++ b/src/xsf/desmume/bios.cc
@@ -0,0 +1,1073 @@
+/* Copyright (C) 2006 yopyop
+ yopyop156 at ifrance.com
+ yopyop156.ifrance.com
+
+ This file is part of DeSmuME
+
+ DeSmuME 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.
+
+ DeSmuME 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 DeSmuME; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "cp15.h"
+#include <math.h>
+#include "MMU.h"
+#include "SPU.h"
+#include "debug.h"
+
+extern BOOL execute;
+
+static u16 getsinetbl[] = {
+0x0000, 0x0324, 0x0648, 0x096A, 0x0C8C, 0x0FAB, 0x12C8, 0x15E2,
+0x18F9, 0x1C0B, 0x1F1A, 0x2223, 0x2528, 0x2826, 0x2B1F, 0x2E11,
+0x30FB, 0x33DF, 0x36BA, 0x398C, 0x3C56, 0x3F17, 0x41CE, 0x447A,
+0x471C, 0x49B4, 0x4C3F, 0x4EBF, 0x5133, 0x539B, 0x55F5, 0x5842,
+0x5A82, 0x5CB3, 0x5ED7, 0x60EB, 0x62F1, 0x64E8, 0x66CF, 0x68A6,
+0x6A6D, 0x6C23, 0x6DC9, 0x6F5E, 0x70E2, 0x7254, 0x73B5, 0x7504,
+0x7641, 0x776B, 0x7884, 0x7989, 0x7A7C, 0x7B5C, 0x7C29, 0x7CE3,
+0x7D89, 0x7E1D, 0x7E9C, 0x7F09, 0x7F61, 0x7FA6, 0x7FD8, 0x7FF5
+};
+
+static u16 getpitchtbl[] = {
+0x0000, 0x003B, 0x0076, 0x00B2, 0x00ED, 0x0128, 0x0164, 0x019F,
+0x01DB, 0x0217, 0x0252, 0x028E, 0x02CA, 0x0305, 0x0341, 0x037D,
+0x03B9, 0x03F5, 0x0431, 0x046E, 0x04AA, 0x04E6, 0x0522, 0x055F,
+0x059B, 0x05D8, 0x0614, 0x0651, 0x068D, 0x06CA, 0x0707, 0x0743,
+0x0780, 0x07BD, 0x07FA, 0x0837, 0x0874, 0x08B1, 0x08EF, 0x092C,
+0x0969, 0x09A7, 0x09E4, 0x0A21, 0x0A5F, 0x0A9C, 0x0ADA, 0x0B18,
+0x0B56, 0x0B93, 0x0BD1, 0x0C0F, 0x0C4D, 0x0C8B, 0x0CC9, 0x0D07,
+0x0D45, 0x0D84, 0x0DC2, 0x0E00, 0x0E3F, 0x0E7D, 0x0EBC, 0x0EFA,
+0x0F39, 0x0F78, 0x0FB6, 0x0FF5, 0x1034, 0x1073, 0x10B2, 0x10F1,
+0x1130, 0x116F, 0x11AE, 0x11EE, 0x122D, 0x126C, 0x12AC, 0x12EB,
+0x132B, 0x136B, 0x13AA, 0x13EA, 0x142A, 0x146A, 0x14A9, 0x14E9,
+0x1529, 0x1569, 0x15AA, 0x15EA, 0x162A, 0x166A, 0x16AB, 0x16EB,
+0x172C, 0x176C, 0x17AD, 0x17ED, 0x182E, 0x186F, 0x18B0, 0x18F0,
+0x1931, 0x1972, 0x19B3, 0x19F5, 0x1A36, 0x1A77, 0x1AB8, 0x1AFA,
+0x1B3B, 0x1B7D, 0x1BBE, 0x1C00, 0x1C41, 0x1C83, 0x1CC5, 0x1D07,
+0x1D48, 0x1D8A, 0x1DCC, 0x1E0E, 0x1E51, 0x1E93, 0x1ED5, 0x1F17,
+0x1F5A, 0x1F9C, 0x1FDF, 0x2021, 0x2064, 0x20A6, 0x20E9, 0x212C,
+0x216F, 0x21B2, 0x21F5, 0x2238, 0x227B, 0x22BE, 0x2301, 0x2344,
+0x2388, 0x23CB, 0x240E, 0x2452, 0x2496, 0x24D9, 0x251D, 0x2561,
+0x25A4, 0x25E8, 0x262C, 0x2670, 0x26B4, 0x26F8, 0x273D, 0x2781,
+0x27C5, 0x280A, 0x284E, 0x2892, 0x28D7, 0x291C, 0x2960, 0x29A5,
+0x29EA, 0x2A2F, 0x2A74, 0x2AB9, 0x2AFE, 0x2B43, 0x2B88, 0x2BCD,
+0x2C13, 0x2C58, 0x2C9D, 0x2CE3, 0x2D28, 0x2D6E, 0x2DB4, 0x2DF9,
+0x2E3F, 0x2E85, 0x2ECB, 0x2F11, 0x2F57, 0x2F9D, 0x2FE3, 0x302A,
+0x3070, 0x30B6, 0x30FD, 0x3143, 0x318A, 0x31D0, 0x3217, 0x325E,
+0x32A5, 0x32EC, 0x3332, 0x3379, 0x33C1, 0x3408, 0x344F, 0x3496,
+0x34DD, 0x3525, 0x356C, 0x35B4, 0x35FB, 0x3643, 0x368B, 0x36D3,
+0x371A, 0x3762, 0x37AA, 0x37F2, 0x383A, 0x3883, 0x38CB, 0x3913,
+0x395C, 0x39A4, 0x39ED, 0x3A35, 0x3A7E, 0x3AC6, 0x3B0F, 0x3B58,
+0x3BA1, 0x3BEA, 0x3C33, 0x3C7C, 0x3CC5, 0x3D0E, 0x3D58, 0x3DA1,
+0x3DEA, 0x3E34, 0x3E7D, 0x3EC7, 0x3F11, 0x3F5A, 0x3FA4, 0x3FEE,
+0x4038, 0x4082, 0x40CC, 0x4116, 0x4161, 0x41AB, 0x41F5, 0x4240,
+0x428A, 0x42D5, 0x431F, 0x436A, 0x43B5, 0x4400, 0x444B, 0x4495,
+0x44E1, 0x452C, 0x4577, 0x45C2, 0x460D, 0x4659, 0x46A4, 0x46F0,
+0x473B, 0x4787, 0x47D3, 0x481E, 0x486A, 0x48B6, 0x4902, 0x494E,
+0x499A, 0x49E6, 0x4A33, 0x4A7F, 0x4ACB, 0x4B18, 0x4B64, 0x4BB1,
+0x4BFE, 0x4C4A, 0x4C97, 0x4CE4, 0x4D31, 0x4D7E, 0x4DCB, 0x4E18,
+0x4E66, 0x4EB3, 0x4F00, 0x4F4E, 0x4F9B, 0x4FE9, 0x5036, 0x5084,
+0x50D2, 0x5120, 0x516E, 0x51BC, 0x520A, 0x5258, 0x52A6, 0x52F4,
+0x5343, 0x5391, 0x53E0, 0x542E, 0x547D, 0x54CC, 0x551A, 0x5569,
+0x55B8, 0x5607, 0x5656, 0x56A5, 0x56F4, 0x5744, 0x5793, 0x57E2,
+0x5832, 0x5882, 0x58D1, 0x5921, 0x5971, 0x59C1, 0x5A10, 0x5A60,
+0x5AB0, 0x5B01, 0x5B51, 0x5BA1, 0x5BF1, 0x5C42, 0x5C92, 0x5CE3,
+0x5D34, 0x5D84, 0x5DD5, 0x5E26, 0x5E77, 0x5EC8, 0x5F19, 0x5F6A,
+0x5FBB, 0x600D, 0x605E, 0x60B0, 0x6101, 0x6153, 0x61A4, 0x61F6,
+0x6248, 0x629A, 0x62EC, 0x633E, 0x6390, 0x63E2, 0x6434, 0x6487,
+0x64D9, 0x652C, 0x657E, 0x65D1, 0x6624, 0x6676, 0x66C9, 0x671C,
+0x676F, 0x67C2, 0x6815, 0x6869, 0x68BC, 0x690F, 0x6963, 0x69B6,
+0x6A0A, 0x6A5E, 0x6AB1, 0x6B05, 0x6B59, 0x6BAD, 0x6C01, 0x6C55,
+0x6CAA, 0x6CFE, 0x6D52, 0x6DA7, 0x6DFB, 0x6E50, 0x6EA4, 0x6EF9,
+0x6F4E, 0x6FA3, 0x6FF8, 0x704D, 0x70A2, 0x70F7, 0x714D, 0x71A2,
+0x71F7, 0x724D, 0x72A2, 0x72F8, 0x734E, 0x73A4, 0x73FA, 0x7450,
+0x74A6, 0x74FC, 0x7552, 0x75A8, 0x75FF, 0x7655, 0x76AC, 0x7702,
+0x7759, 0x77B0, 0x7807, 0x785E, 0x78B4, 0x790C, 0x7963, 0x79BA,
+0x7A11, 0x7A69, 0x7AC0, 0x7B18, 0x7B6F, 0x7BC7, 0x7C1F, 0x7C77,
+0x7CCF, 0x7D27, 0x7D7F, 0x7DD7, 0x7E2F, 0x7E88, 0x7EE0, 0x7F38,
+0x7F91, 0x7FEA, 0x8042, 0x809B, 0x80F4, 0x814D, 0x81A6, 0x81FF,
+0x8259, 0x82B2, 0x830B, 0x8365, 0x83BE, 0x8418, 0x8472, 0x84CB,
+0x8525, 0x857F, 0x85D9, 0x8633, 0x868E, 0x86E8, 0x8742, 0x879D,
+0x87F7, 0x8852, 0x88AC, 0x8907, 0x8962, 0x89BD, 0x8A18, 0x8A73,
+0x8ACE, 0x8B2A, 0x8B85, 0x8BE0, 0x8C3C, 0x8C97, 0x8CF3, 0x8D4F,
+0x8DAB, 0x8E07, 0x8E63, 0x8EBF, 0x8F1B, 0x8F77, 0x8FD4, 0x9030,
+0x908C, 0x90E9, 0x9146, 0x91A2, 0x91FF, 0x925C, 0x92B9, 0x9316,
+0x9373, 0x93D1, 0x942E, 0x948C, 0x94E9, 0x9547, 0x95A4, 0x9602,
+0x9660, 0x96BE, 0x971C, 0x977A, 0x97D8, 0x9836, 0x9895, 0x98F3,
+0x9952, 0x99B0, 0x9A0F, 0x9A6E, 0x9ACD, 0x9B2C, 0x9B8B, 0x9BEA,
+0x9C49, 0x9CA8, 0x9D08, 0x9D67, 0x9DC7, 0x9E26, 0x9E86, 0x9EE6,
+0x9F46, 0x9FA6, 0xA006, 0xA066, 0xA0C6, 0xA127, 0xA187, 0xA1E8,
+0xA248, 0xA2A9, 0xA30A, 0xA36B, 0xA3CC, 0xA42D, 0xA48E, 0xA4EF,
+0xA550, 0xA5B2, 0xA613, 0xA675, 0xA6D6, 0xA738, 0xA79A, 0xA7FC,
+0xA85E, 0xA8C0, 0xA922, 0xA984, 0xA9E7, 0xAA49, 0xAAAC, 0xAB0E,
+0xAB71, 0xABD4, 0xAC37, 0xAC9A, 0xACFD, 0xAD60, 0xADC3, 0xAE27,
+0xAE8A, 0xAEED, 0xAF51, 0xAFB5, 0xB019, 0xB07C, 0xB0E0, 0xB145,
+0xB1A9, 0xB20D, 0xB271, 0xB2D6, 0xB33A, 0xB39F, 0xB403, 0xB468,
+0xB4CD, 0xB532, 0xB597, 0xB5FC, 0xB662, 0xB6C7, 0xB72C, 0xB792,
+0xB7F7, 0xB85D, 0xB8C3, 0xB929, 0xB98F, 0xB9F5, 0xBA5B, 0xBAC1,
+0xBB28, 0xBB8E, 0xBBF5, 0xBC5B, 0xBCC2, 0xBD29, 0xBD90, 0xBDF7,
+0xBE5E, 0xBEC5, 0xBF2C, 0xBF94, 0xBFFB, 0xC063, 0xC0CA, 0xC132,
+0xC19A, 0xC202, 0xC26A, 0xC2D2, 0xC33A, 0xC3A2, 0xC40B, 0xC473,
+0xC4DC, 0xC544, 0xC5AD, 0xC616, 0xC67F, 0xC6E8, 0xC751, 0xC7BB,
+0xC824, 0xC88D, 0xC8F7, 0xC960, 0xC9CA, 0xCA34, 0xCA9E, 0xCB08,
+0xCB72, 0xCBDC, 0xCC47, 0xCCB1, 0xCD1B, 0xCD86, 0xCDF1, 0xCE5B,
+0xCEC6, 0xCF31, 0xCF9C, 0xD008, 0xD073, 0xD0DE, 0xD14A, 0xD1B5,
+0xD221, 0xD28D, 0xD2F8, 0xD364, 0xD3D0, 0xD43D, 0xD4A9, 0xD515,
+0xD582, 0xD5EE, 0xD65B, 0xD6C7, 0xD734, 0xD7A1, 0xD80E, 0xD87B,
+0xD8E9, 0xD956, 0xD9C3, 0xDA31, 0xDA9E, 0xDB0C, 0xDB7A, 0xDBE8,
+0xDC56, 0xDCC4, 0xDD32, 0xDDA0, 0xDE0F, 0xDE7D, 0xDEEC, 0xDF5B,
+0xDFC9, 0xE038, 0xE0A7, 0xE116, 0xE186, 0xE1F5, 0xE264, 0xE2D4,
+0xE343, 0xE3B3, 0xE423, 0xE493, 0xE503, 0xE573, 0xE5E3, 0xE654,
+0xE6C4, 0xE735, 0xE7A5, 0xE816, 0xE887, 0xE8F8, 0xE969, 0xE9DA,
+0xEA4B, 0xEABC, 0xEB2E, 0xEB9F, 0xEC11, 0xEC83, 0xECF5, 0xED66,
+0xEDD9, 0xEE4B, 0xEEBD, 0xEF2F, 0xEFA2, 0xF014, 0xF087, 0xF0FA,
+0xF16D, 0xF1E0, 0xF253, 0xF2C6, 0xF339, 0xF3AD, 0xF420, 0xF494,
+0xF507, 0xF57B, 0xF5EF, 0xF663, 0xF6D7, 0xF74C, 0xF7C0, 0xF834,
+0xF8A9, 0xF91E, 0xF992, 0xFA07, 0xFA7C, 0xFAF1, 0xFB66, 0xFBDC,
+0xFC51, 0xFCC7, 0xFD3C, 0xFDB2, 0xFE28, 0xFE9E, 0xFF14, 0xFF8A
+};
+
+static u8 getvoltbl[] = {
+0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
+0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+0x09, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
+0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E,
+0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10,
+0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14,
+0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x18,
+0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1C,
+0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
+0x22, 0x23, 0x23, 0x24, 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x27, 0x28, 0x28, 0x29,
+0x29, 0x2A, 0x2A, 0x2B, 0x2B, 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, 0x30, 0x31, 0x31,
+0x32, 0x32, 0x33, 0x33, 0x34, 0x35, 0x35, 0x36, 0x36, 0x37, 0x38, 0x38, 0x39, 0x3A, 0x3A, 0x3B,
+0x3C, 0x3C, 0x3D, 0x3E, 0x3F, 0x3F, 0x40, 0x41, 0x42, 0x42, 0x43, 0x44, 0x45, 0x45, 0x46, 0x47,
+0x48, 0x49, 0x4A, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x52, 0x53, 0x54, 0x55,
+0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67,
+0x68, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x6F, 0x71, 0x72, 0x73, 0x75, 0x76, 0x77, 0x79, 0x7A, 0x7B,
+0x7D, 0x7E, 0x7F, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25,
+0x26, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, 0x2C, 0x2C, 0x2D,
+0x2D, 0x2E, 0x2E, 0x2F, 0x2F, 0x30, 0x30, 0x31, 0x31, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x36,
+0x36, 0x37, 0x37, 0x38, 0x39, 0x39, 0x3A, 0x3B, 0x3B, 0x3C, 0x3D, 0x3E, 0x3E, 0x3F, 0x40, 0x40,
+0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x47, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4D,
+0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D,
+0x5E, 0x5F, 0x60, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6F, 0x70,
+0x71, 0x73, 0x74, 0x75, 0x77, 0x78, 0x79, 0x7B, 0x7C, 0x7E, 0x7E, 0x40, 0x41, 0x42, 0x43, 0x43,
+0x44, 0x45, 0x46, 0x47, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
+0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61,
+0x62, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D, 0x6E, 0x70, 0x71, 0x72, 0x74, 0x75,
+0x76, 0x78, 0x79, 0x7B, 0x7C, 0x7D, 0x7E, 0x40, 0x41, 0x42, 0x42, 0x43, 0x44, 0x45, 0x46, 0x46,
+0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55,
+0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x65, 0x66,
+0x67, 0x68, 0x69, 0x6A, 0x6C, 0x6D, 0x6E, 0x6F, 0x71, 0x72, 0x73, 0x75, 0x76, 0x77, 0x79, 0x7A,
+0x7C, 0x7D, 0x7E, 0x7F
+};
+
+u32 bios_nop(armcpu_t * cpu)
+{
+ if (cpu->proc_ID == ARMCPU_ARM9)
+ {
+ LOG("Unimplemented bios function %02X(ARM9) was used. R0:%08X\n", (cpu->instruction)&0x1F, cpu->R[0]);
+ }
+ else
+ {
+ LOG("Unimplemented bios function %02X(ARM7) was used. R0:%08X\n", (cpu->instruction)&0x1F, cpu->R[0]);
+ }
+ return 3;
+}
+
+u32 delayLoop(armcpu_t * cpu)
+{
+ return cpu->R[0] * 4;
+}
+
+//u32 oldmode[2];
+
+u32 intrWaitARM(armcpu_t * cpu)
+{
+ u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8;
+ u32 intr;
+ u32 intrFlag = 0;
+
+ //execute = false;
+ if(cpu->proc_ID)
+ {
+ intrFlagAdr = 0x380FFF8;
+ } else {
+ intrFlagAdr = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8;
+ }
+ intr = MMU_read32(cpu->proc_ID, intrFlagAdr);
+ intrFlag = cpu->R[1] & intr;
+
+ if(intrFlag)
+ {
+ // si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s)
+ // on efface son(les) occurence(s).
+ intr ^= intrFlag;
+ MMU_write32(cpu->proc_ID, intrFlagAdr, intr);
+ //cpu->switchMode(oldmode[cpu->proc_ID]);
+ return 1;
+ }
+
+ cpu->R[15] = cpu->instruct_adr;
+ cpu->next_instruction = cpu->R[15];
+ cpu->waitIRQ = 1;
+ //oldmode[cpu->proc_ID] = cpu->switchMode(SVC);
+
+ return 1;
+}
+
+u32 waitVBlankARM(armcpu_t * cpu)
+{
+ u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8;
+ u32 intr;
+ u32 intrFlag = 0;
+
+ //execute = false;
+ if(cpu->proc_ID)
+ {
+ intrFlagAdr = 0x380FFF8;
+ } else {
+ intrFlagAdr = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8;
+ }
+ intr = MMU_read32(cpu->proc_ID, intrFlagAdr);
+ intrFlag = 1 & intr;
+
+ if(intrFlag)
+ {
+ // si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s)
+ // on efface son(les) occurence(s).
+ intr ^= intrFlag;
+ MMU_write32(cpu->proc_ID, intrFlagAdr, intr);
+ //cpu->switchMode(oldmode[cpu->proc_ID]);
+ return 1;
+ }
+
+ cpu->R[15] = cpu->instruct_adr;
+ cpu->next_instruction = cpu->R[15];
+ cpu->waitIRQ = 1;
+ //oldmode[cpu->proc_ID] = cpu->switchMode(SVC);
+
+ return 1;
+}
+
+u32 wait4IRQ(armcpu_t* cpu)
+{
+ //execute= false;
+ if(cpu->wirq)
+ {
+ if(!cpu->waitIRQ)
+ {
+ cpu->waitIRQ = 0;
+ cpu->wirq = 0;
+ //cpu->switchMode(oldmode[cpu->proc_ID]);
+ return 1;
+ }
+ cpu->R[15] = cpu->instruct_adr;
+ cpu->next_instruction = cpu->R[15];
+ return 1;
+ }
+ cpu->waitIRQ = 1;
+ cpu->wirq = 1;
+ cpu->R[15] = cpu->instruct_adr;
+ cpu->next_instruction = cpu->R[15];
+ //oldmode[cpu->proc_ID] = cpu->switchMode(SVC);
+ return 1;
+}
+
+u32 devide(armcpu_t* cpu)
+{
+ s32 num = (s32)cpu->R[0];
+ s32 dnum = (s32)cpu->R[1];
+
+ if(dnum==0) return 0;
+
+ cpu->R[0] = (u32)(num / dnum);
+ cpu->R[1] = (u32)(num % dnum);
+ cpu->R[3] = (u32) (((s32)cpu->R[0])<0 ? -cpu->R[0] : cpu->R[0]);
+
+ return 6;
+}
+
+u32 copy(armcpu_t* cpu)
+{
+ u32 src = cpu->R[0];
+ u32 dst = cpu->R[1];
+ u32 cnt = cpu->R[2];
+
+ switch(BIT26(cnt))
+ {
+ case 0:
+ src &= 0xFFFFFFFE;
+ dst &= 0xFFFFFFFE;
+ switch(BIT24(cnt))
+ {
+ case 0:
+ cnt &= 0x1FFFFF;
+ while(cnt)
+ {
+ MMU_write16(cpu->proc_ID, dst, MMU_read16(cpu->proc_ID, src));
+ cnt--;
+ dst+=2;
+ src+=2;
+ }
+ break;
+ case 1:
+ {
+ u32 val = MMU_read16(cpu->proc_ID, src);
+ cnt &= 0x1FFFFF;
+ while(cnt)
+ {
+ MMU_write16(cpu->proc_ID, dst, val);
+ cnt--;
+ dst+=2;
+ }
+ }
+ break;
+ }
+ break;
+ case 1:
+ src &= 0xFFFFFFFC;
+ dst &= 0xFFFFFFFC;
+ switch(BIT24(cnt))
+ {
+ case 0:
+ cnt &= 0x1FFFFF;
+ while(cnt)
+ {
+ MMU_write32(cpu->proc_ID, dst, MMU_read32(cpu->proc_ID, src));
+ cnt--;
+ dst+=4;
+ src+=4;
+ }
+ break;
+ case 1:
+ {
+ u32 val = MMU_read32(cpu->proc_ID, src);
+ cnt &= 0x1FFFFF;
+ while(cnt)
+ {
+ MMU_write32(cpu->proc_ID, dst, val);
+ cnt--;
+ dst+=4;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ return 1;
+}
+
+u32 fastCopy(armcpu_t* cpu)
+{
+ u32 src = cpu->R[0] & 0xFFFFFFFC;
+ u32 dst = cpu->R[1] & 0xFFFFFFFC;
+ u32 cnt = cpu->R[2];
+
+ switch(BIT24(cnt))
+ {
+ case 0:
+ cnt &= 0x1FFFFF;
+ while(cnt)
+ {
+ MMU_write32(cpu->proc_ID, dst, MMU_read32(cpu->proc_ID, src));
+ cnt--;
+ dst+=4;
+ src+=4;
+ }
+ break;
+ case 1:
+ {
+ u32 val = MMU_read32(cpu->proc_ID, src);
+ cnt &= 0x1FFFFF;
+ while(cnt)
+ {
+ MMU_write32(cpu->proc_ID, dst, val);
+ cnt--;
+ dst+=4;
+ }
+ }
+ break;
+ }
+ return 1;
+}
+
+u32 LZ77UnCompVram(armcpu_t* cpu)
+{
+ int i1, i2;
+ int byteCount;
+ int byteShift;
+ u32 writeValue;
+ int len;
+ u32 source = cpu->R[0];
+ u32 dest = cpu->R[1];
+ u32 header = MMU_read32(cpu->proc_ID, source);
+ source += 4;
+
+ if(((source & 0xe000000) == 0) ||
+ ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)
+ return 0;
+
+ byteCount = 0;
+ byteShift = 0;
+ writeValue = 0;
+
+ len = header >> 8;
+
+ while(len > 0) {
+ u8 d = MMU_read8(cpu->proc_ID, source++);
+
+ if(d) {
+ for(i1 = 0; i1 < 8; i1++) {
+ if(d & 0x80) {
+ int length;
+ int offset;
+ u32 windowOffset;
+ u16 data = MMU_read8(cpu->proc_ID, source++) << 8;
+ data |= MMU_read8(cpu->proc_ID, source++);
+ length = (data >> 12) + 3;
+ offset = (data & 0x0FFF);
+ windowOffset = dest + byteCount - offset - 1;
+ for(i2 = 0; i2 < length; i2++) {
+ writeValue |= (MMU_read8(cpu->proc_ID, windowOffset++) << byteShift);
+ byteShift += 8;
+ byteCount++;
+
+ if(byteCount == 2) {
+ MMU_write16(cpu->proc_ID, dest, writeValue);
+ dest += 2;
+ byteCount = 0;
+ byteShift = 0;
+ writeValue = 0;
+ }
+ len--;
+ if(len == 0)
+ return 0;
+ }
+ } else {
+ writeValue |= (MMU_read8(cpu->proc_ID, source++) << byteShift);
+ byteShift += 8;
+ byteCount++;
+ if(byteCount == 2) {
+ MMU_write16(cpu->proc_ID, dest, writeValue);
+ dest += 2;
+ byteCount = 0;
+ byteShift = 0;
+ writeValue = 0;
+ }
+ len--;
+ if(len == 0)
+ return 0;
+ }
+ d <<= 1;
+ }
+ } else {
+ for(i1 = 0; i1 < 8; i1++) {
+ writeValue |= (MMU_read8(cpu->proc_ID, source++) << byteShift);
+ byteShift += 8;
+ byteCount++;
+ if(byteCount == 2) {
+ MMU_write16(cpu->proc_ID, dest, writeValue);
+ dest += 2;
+ byteShift = 0;
+ byteCount = 0;
+ writeValue = 0;
+ }
+ len--;
+ if(len == 0)
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+u32 LZ77UnCompWram(armcpu_t* cpu)
+{
+ int i1, i2;
+ int len;
+ u32 source = cpu->R[0];
+ u32 dest = cpu->R[1];
+
+ u32 header = MMU_read32(cpu->proc_ID, source);
+ source += 4;
+
+ if(((source & 0xe000000) == 0) ||
+ ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)
+ return 0;
+
+ len = header >> 8;
+
+ while(len > 0) {
+ u8 d = MMU_read8(cpu->proc_ID, source++);
+
+ if(d) {
+ for(i1 = 0; i1 < 8; i1++) {
+ if(d & 0x80) {
+ int length;
+ int offset;
+ u32 windowOffset;
+ u16 data = MMU_read8(cpu->proc_ID, source++) << 8;
+ data |= MMU_read8(cpu->proc_ID, source++);
+ length = (data >> 12) + 3;
+ offset = (data & 0x0FFF);
+ windowOffset = dest - offset - 1;
+ for(i2 = 0; i2 < length; i2++) {
+ MMU_write8(cpu->proc_ID, dest++, MMU_read8(cpu->proc_ID, windowOffset++));
+ len--;
+ if(len == 0)
+ return 0;
+ }
+ } else {
+ MMU_write8(cpu->proc_ID, dest++, MMU_read8(cpu->proc_ID, source++));
+ len--;
+ if(len == 0)
+ return 0;
+ }
+ d <<= 1;
+ }
+ } else {
+ for(i1 = 0; i1 < 8; i1++) {
+ MMU_write8(cpu->proc_ID, dest++, MMU_read8(cpu->proc_ID, source++));
+ len--;
+ if(len == 0)
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+u32 RLUnCompVram(armcpu_t* cpu)
+{
+ int i;
+ int len;
+ int byteCount;
+ int byteShift;
+ u32 writeValue;
+ u32 source = cpu->R[0];
+ u32 dest = cpu->R[1];
+
+ u32 header = MMU_read32(cpu->proc_ID, source);
+ source += 4;
+
+ if(((source & 0xe000000) == 0) ||
+ ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)
+ return 0;
+
+ len = header >> 8;
+ byteCount = 0;
+ byteShift = 0;
+ writeValue = 0;
+
+ while(len > 0) {
+ u8 d = MMU_read8(cpu->proc_ID, source++);
+ int l = d & 0x7F;
+ if(d & 0x80) {
+ u8 data = MMU_read8(cpu->proc_ID, source++);
+ l += 3;
+ for(i = 0;i < l; i++) {
+ writeValue |= (data << byteShift);
+ byteShift += 8;
+ byteCount++;
+
+ if(byteCount == 2) {
+ MMU_write16(cpu->proc_ID, dest, writeValue);
+ dest += 2;
+ byteCount = 0;
+ byteShift = 0;
+ writeValue = 0;
+ }
+ len--;
+ if(len == 0)
+ return 0;
+ }
+ } else {
+ l++;
+ for(i = 0; i < l; i++) {
+ writeValue |= (MMU_read8(cpu->proc_ID, source++) << byteShift);
+ byteShift += 8;
+ byteCount++;
+ if(byteCount == 2) {
+ MMU_write16(cpu->proc_ID, dest, writeValue);
+ dest += 2;
+ byteCount = 0;
+ byteShift = 0;
+ writeValue = 0;
+ }
+ len--;
+ if(len == 0)
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+u32 RLUnCompWram(armcpu_t* cpu)
+{
+ int i;
+ int len;
+ u32 source = cpu->R[0];
+ u32 dest = cpu->R[1];
+
+ u32 header = MMU_read32(cpu->proc_ID, source);
+ source += 4;
+
+ if(((source & 0xe000000) == 0) ||
+ ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)
+ return 0;
+
+ len = header >> 8;
+
+ while(len > 0) {
+ u8 d = MMU_read8(cpu->proc_ID, source++);
+ int l = d & 0x7F;
+ if(d & 0x80) {
+ u8 data = MMU_read8(cpu->proc_ID, source++);
+ l += 3;
+ for(i = 0;i < l; i++) {
+ MMU_write8(cpu->proc_ID, dest++, data);
+ len--;
+ if(len == 0)
+ return 0;
+ }
+ } else {
+ l++;
+ for(i = 0; i < l; i++) {
+ MMU_write8(cpu->proc_ID, dest++, MMU_read8(cpu->proc_ID, source++));
+ len--;
+ if(len == 0)
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+u32 UnCompHuffman(armcpu_t* cpu)
+{
+ u32 source, dest, writeValue, header, treeStart, mask;
+ u32 data;
+ u8 treeSize, currentNode, rootNode;
+ int byteCount, byteShift, len, pos;
+ int writeData;
+
+ source = cpu->R[0];
+ dest = cpu->R[1];
+
+ header = MMU_read8(cpu->proc_ID, source);
+ source += 4;
+
+ if(((source & 0xe000000) == 0) ||
+ ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)
+ return 0;
+
+ treeSize = MMU_read8(cpu->proc_ID, source++);
+
+ treeStart = source;
+
+ source += ((treeSize+1)<<1)-1; // minus because we already skipped one byte
+
+ len = header >> 8;
+
+ mask = 0x80000000;
+ data = MMU_read8(cpu->proc_ID, source);
+ source += 4;
+
+ pos = 0;
+ rootNode = MMU_read8(cpu->proc_ID, treeStart);
+ currentNode = rootNode;
+ writeData = 0;
+ byteShift = 0;
+ byteCount = 0;
+ writeValue = 0;
+
+ if((header & 0x0F) == 8) {
+ while(len > 0) {
+ // take left
+ if(pos == 0)
+ pos++;
+ else
+ pos += (((currentNode & 0x3F)+1)<<1);
+
+ if(data & mask) {
+ // right
+ if(currentNode & 0x40)
+ writeData = 1;
+ currentNode = MMU_read8(cpu->proc_ID, treeStart+pos+1);
+ } else {
+ // left
+ if(currentNode & 0x80)
+ writeData = 1;
+ currentNode = MMU_read8(cpu->proc_ID, treeStart+pos);
+ }
+
+ if(writeData) {
+ writeValue |= (currentNode << byteShift);
+ byteCount++;
+ byteShift += 8;
+
+ pos = 0;
+ currentNode = rootNode;
+ writeData = 0;
+
+ if(byteCount == 4) {
+ byteCount = 0;
+ byteShift = 0;
+ MMU_write8(cpu->proc_ID, dest, writeValue);
+ writeValue = 0;
+ dest += 4;
+ len -= 4;
+ }
+ }
+ mask >>= 1;
+ if(mask == 0) {
+ mask = 0x80000000;
+ data = MMU_read8(cpu->proc_ID, source);
+ source += 4;
+ }
+ }
+ } else {
+ int halfLen = 0;
+ int value = 0;
+ while(len > 0) {
+ // take left
+ if(pos == 0)
+ pos++;
+ else
+ pos += (((currentNode & 0x3F)+1)<<1);
+
+ if((data & mask)) {
+ // right
+ if(currentNode & 0x40)
+ writeData = 1;
+ currentNode = MMU_read8(cpu->proc_ID, treeStart+pos+1);
+ } else {
+ // left
+ if(currentNode & 0x80)
+ writeData = 1;
+ currentNode = MMU_read8(cpu->proc_ID, treeStart+pos);
+ }
+
+ if(writeData) {
+ if(halfLen == 0)
+ value |= currentNode;
+ else
+ value |= (currentNode<<4);
+
+ halfLen += 4;
+ if(halfLen == 8) {
+ writeValue |= (value << byteShift);
+ byteCount++;
+ byteShift += 8;
+
+ halfLen = 0;
+ value = 0;
+
+ if(byteCount == 4) {
+ byteCount = 0;
+ byteShift = 0;
+ MMU_write8(cpu->proc_ID, dest, writeValue);
+ dest += 4;
+ writeValue = 0;
+ len -= 4;
+ }
+ }
+ pos = 0;
+ currentNode = rootNode;
+ writeData = 0;
+ }
+ mask >>= 1;
+ if(mask == 0) {
+ mask = 0x80000000;
+ data = MMU_read8(cpu->proc_ID, source);
+ source += 4;
+ }
+ }
+ }
+ return 1;
+}
+
+u32 BitUnPack(armcpu_t* cpu)
+{
+ u32 source,dest,header,base,d,temp;
+ int len,bits,revbits,dataSize,data,bitwritecount,mask,bitcount,addBase;
+ u8 b;
+
+ source = cpu->R[0];
+ dest = cpu->R[1];
+ header = cpu->R[2];
+
+ len = MMU_read16(cpu->proc_ID, header);
+ // check address
+ bits = MMU_read8(cpu->proc_ID, header+2);
+ revbits = 8 - bits;
+ // u32 value = 0;
+ base = MMU_read8(cpu->proc_ID, header+4);
+ addBase = (base & 0x80000000) ? 1 : 0;
+ base &= 0x7fffffff;
+ dataSize = MMU_read8(cpu->proc_ID, header+3);
+
+ data = 0;
+ bitwritecount = 0;
+ while(1) {
+ len -= 1;
+ if(len < 0)
+ break;
+ mask = 0xff >> revbits;
+ b = MMU_read8(cpu->proc_ID, source);
+ source++;
+ bitcount = 0;
+ while(1) {
+ if(bitcount >= 8)
+ break;
+ d = b & mask;
+ temp = d >> bitcount;
+ if(!temp && addBase) {
+ temp += base;
+ }
+ data |= temp << bitwritecount;
+ bitwritecount += dataSize;
+ if(bitwritecount >= 32) {
+ MMU_write8(cpu->proc_ID, dest, data);
+ dest += 4;
+ data = 0;
+ bitwritecount = 0;
+ }
+ mask <<= bits;
+ bitcount += bits;
+ }
+ }
+ return 1;
+}
+
+u32 Diff8bitUnFilterWram(armcpu_t* cpu)
+{
+ u32 source,dest,header;
+ u8 data,diff;
+ int len;
+
+ source = cpu->R[0];
+ dest = cpu->R[1];
+
+ header = MMU_read8(cpu->proc_ID, source);
+ source += 4;
+
+ if(((source & 0xe000000) == 0) ||
+ (( (source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0))
+ return 0;
+
+ len = header >> 8;
+
+ data = MMU_read8(cpu->proc_ID, source++);
+ MMU_write8(cpu->proc_ID, dest++, data);
+ len--;
+
+ while(len > 0) {
+ diff = MMU_read8(cpu->proc_ID, source++);
+ data += diff;
+ MMU_write8(cpu->proc_ID, dest++, data);
+ len--;
+ }
+ return 1;
+}
+
+u32 Diff16bitUnFilter(armcpu_t* cpu)
+{
+ u32 source,dest,header;
+ u16 data;
+ int len;
+
+ source = cpu->R[0];
+ dest = cpu->R[1];
+
+ header = MMU_read8(cpu->proc_ID, source);
+ source += 4;
+
+ if(((source & 0xe000000) == 0) ||
+ ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)
+ return 0;
+
+ len = header >> 8;
+
+ data = MMU_read16(cpu->proc_ID, source);
+ source += 2;
+ MMU_write16(cpu->proc_ID, dest, data);
+ dest += 2;
+ len -= 2;
+
+ while(len >= 2) {
+ u16 diff = MMU_read16(cpu->proc_ID, source);
+ source += 2;
+ data += diff;
+ MMU_write16(cpu->proc_ID, dest, data);
+ dest += 2;
+ len -= 2;
+ }
+ return 1;
+}
+
+u32 bios_sqrt(armcpu_t* cpu)
+{
+ cpu->R[0] = (u32)sqrt((double)(cpu->R[0]));
+ return 1;
+}
+
+u32 setHaltCR(armcpu_t* cpu)
+{
+ MMU_write8(cpu->proc_ID, 0x4000300+cpu->proc_ID, cpu->R[0]);
+ return 1;
+}
+
+u32 getSineTab(armcpu_t* cpu)
+{
+ cpu->R[0] = getsinetbl[cpu->R[0]];
+ return 1;
+}
+
+u32 getPitchTab(armcpu_t* cpu)
+{
+ cpu->R[0] = getpitchtbl[cpu->R[0]];
+ return 1;
+}
+
+u32 getVolumeTab(armcpu_t* cpu)
+{
+ cpu->R[0] = getvoltbl[cpu->R[0]];
+ return 1;
+}
+
+u32 getCRC16(armcpu_t* cpu)
+{
+ unsigned int i,j;
+
+ u32 crc = cpu->R[0];
+ u32 datap = cpu->R[1];
+ u32 size = cpu->R[2];
+
+ static u16 val[] = { 0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001 };
+ for(i = 0; i < size; i++)
+ {
+ crc = crc ^ MMU_read8( cpu->proc_ID, datap + i);
+
+ for(j = 0; j < 8; j++) {
+ int do_bit = 0;
+
+ if ( crc & 0x1)
+ do_bit = 1;
+
+ crc = crc >> 1;
+
+ if ( do_bit) {
+ crc = crc ^ (val[j] << (7-j));
+ }
+ }
+ }
+ cpu->R[0] = crc;
+ return 1;
+}
+
+u32 SoundBias(armcpu_t* cpu)
+{
+ u32 current = SPU_ReadLong(0x4000504);
+ if (cpu->R[0] > current)
+ SPU_WriteLong(0x4000504, current + 0x1);
+ else
+ SPU_WriteLong(0x4000504, current - 0x1);
+ return cpu->R[1];
+}
+
+u32 (* ARM9_swi_tab[32])(armcpu_t* cpu)={
+ bios_nop, // 0x00
+ bios_nop, // 0x01
+ bios_nop, // 0x02
+ delayLoop, // 0x03
+ intrWaitARM, // 0x04
+ waitVBlankARM, // 0x05
+ wait4IRQ, // 0x06
+ bios_nop, // 0x07
+ bios_nop, // 0x08
+ devide, // 0x09
+ bios_nop, // 0x0A
+ copy, // 0x0B
+ fastCopy, // 0x0C
+ bios_sqrt, // 0x0D
+ getCRC16, // 0x0E
+ bios_nop, // 0x0F
+ BitUnPack, // 0x10
+ LZ77UnCompWram, // 0x11
+ LZ77UnCompVram, // 0x12
+ UnCompHuffman, // 0x13
+ RLUnCompWram, // 0x14
+ RLUnCompVram, // 0x15
+ Diff8bitUnFilterWram, // 0x16
+ bios_nop, // 0x17
+ Diff16bitUnFilter, // 0x18
+ bios_nop, // 0x19
+ bios_nop, // 0x1A
+ bios_nop, // 0x1B
+ bios_nop, // 0x1C
+ bios_nop, // 0x1D
+ bios_nop, // 0x1E
+ setHaltCR, // 0x1F
+};
+
+u32 (* ARM7_swi_tab[32])(armcpu_t* cpu)={
+ bios_nop, // 0x00
+ bios_nop, // 0x01
+ bios_nop, // 0x02
+ delayLoop, // 0x03
+ intrWaitARM, // 0x04
+ waitVBlankARM, // 0x05
+ wait4IRQ, // 0x06
+ wait4IRQ, // 0x07
+ SoundBias, // 0x08
+ devide, // 0x09
+ bios_nop, // 0x0A
+ copy, // 0x0B
+ fastCopy, // 0x0C
+ bios_sqrt, // 0x0D
+ getCRC16, // 0x0E
+ bios_nop, // 0x0F
+ BitUnPack, // 0x10
+ LZ77UnCompWram, // 0x11
+ LZ77UnCompVram, // 0x12
+ UnCompHuffman, // 0x13
+ RLUnCompWram, // 0x14
+ RLUnCompVram, // 0x15
+ Diff8bitUnFilterWram, // 0x16
+ bios_nop, // 0x17
+ bios_nop, // 0x18
+ bios_nop, // 0x19
+ getSineTab, // 0x1A
+ getPitchTab, // 0x1B
+ getVolumeTab, // 0x1C
+ bios_nop, // 0x1D
+ bios_nop, // 0x1E
+ setHaltCR, // 0x1F
+};
diff --git a/src/xsf/desmume/bios.h b/src/xsf/desmume/bios.h
index 7f717cb8cfdc..ad41d6a0b6c8 100644
--- a/src/xsf/desmume/bios.h
+++ b/src/xsf/desmume/bios.h
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef BIOS_H
diff --git a/src/xsf/desmume/config.h b/src/xsf/desmume/config.h
index 2f2f707ee041..53a2a936b7ac 100644
--- a/src/xsf/desmume/config.h
+++ b/src/xsf/desmume/config.h
@@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __CONFIG_H__
diff --git a/src/xsf/desmume/cp15.c b/src/xsf/desmume/cp15.c
deleted file mode 100644
index 3a54a2654662..000000000000
--- a/src/xsf/desmume/cp15.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/* Copyright (C) 2006 yopyop
- yopyop156 at ifrance.com
- yopyop156.ifrance.com
-
- This file is part of DeSmuME
-
- DeSmuME 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.
-
- DeSmuME 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 DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <stdlib.h>
-
-#include "cp15.h"
-#include "debug.h"
-#include "MMU.h"
-
-armcp15_t *armcp15_new(armcpu_t * c)
-{
- int i;
- armcp15_t *armcp15 = (armcp15_t*)malloc(sizeof(armcp15_t));
- if(!armcp15) return NULL;
-
- armcp15->cpu = c;
- armcp15->IDCode = 0x41049460;
- armcp15->cacheType = 0x0F0D2112;
- armcp15->TCMSize = 0x00140140;
- armcp15->ctrl = 0x00000000;
- armcp15->DCConfig = 0x0;
- armcp15->ICConfig = 0x0;
- armcp15->writeBuffCtrl = 0x0;
- armcp15->und = 0x0;
- armcp15->DaccessPerm = 0x22222222;
- armcp15->IaccessPerm = 0x22222222;
- armcp15->protectBaseSize0 = 0x0;
- armcp15->protectBaseSize1 = 0x0;
- armcp15->protectBaseSize2 = 0x0;
- armcp15->protectBaseSize3 = 0x0;
- armcp15->protectBaseSize4 = 0x0;
- armcp15->protectBaseSize5 = 0x0;
- armcp15->protectBaseSize6 = 0x0;
- armcp15->protectBaseSize7 = 0x0;
- armcp15->cacheOp = 0x0;
- armcp15->DcacheLock = 0x0;
- armcp15->IcacheLock = 0x0;
- armcp15->ITCMRegion = 0x0C;
- armcp15->DTCMRegion = 0x0080000A;
- armcp15->processID = 0;
-
- /* preset calculated regionmasks */
- for (i=0;i<8;i++) {
- armcp15->regionWriteMask_USR[i] = 0 ;
- armcp15->regionWriteMask_SYS[i] = 0 ;
- armcp15->regionReadMask_USR[i] = 0 ;
- armcp15->regionReadMask_SYS[i] = 0 ;
- armcp15->regionExecuteMask_USR[i] = 0 ;
- armcp15->regionExecuteMask_SYS[i] = 0 ;
- armcp15->regionWriteSet_USR[i] = 0 ;
- armcp15->regionWriteSet_SYS[i] = 0 ;
- armcp15->regionReadSet_USR[i] = 0 ;
- armcp15->regionReadSet_SYS[i] = 0 ;
- armcp15->regionExecuteSet_USR[i] = 0 ;
- armcp15->regionExecuteSet_SYS[i] = 0 ;
- } ;
-
- return armcp15;
-}
-
-#define ACCESSTYPE(val,n) (((val) >> (4*n)) & 0x0F)
-#define SIZEIDENTIFIER(val) ((((val) >> 1) & 0x1F))
-#define SIZEBINARY(val) (1 << (SIZEIDENTIFIER(val)+1))
-#define MASKFROMREG(val) (~((SIZEBINARY(val)-1) | 0x3F))
-#define SETFROMREG(val) ((val) & MASKFROMREG(val))
-/* sets the precalculated regions to mask,set for the affected accesstypes */
-void armcp15_setSingleRegionAccess(armcp15_t *armcp15,unsigned long dAccess,unsigned long iAccess,unsigned char num, unsigned long mask,unsigned long set) {
-
- switch (ACCESSTYPE(dAccess,num)) {
- case 4: /* UNP */
- case 7: /* UNP */
- case 8: /* UNP */
- case 9: /* UNP */
- case 10: /* UNP */
- case 11: /* UNP */
- case 12: /* UNP */
- case 13: /* UNP */
- case 14: /* UNP */
- case 15: /* UNP */
- case 0: /* no access at all */
- armcp15->regionWriteMask_USR[num] = 0 ;
- armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
- armcp15->regionReadMask_USR[num] = 0 ;
- armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
- armcp15->regionWriteMask_SYS[num] = 0 ;
- armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
- armcp15->regionReadMask_SYS[num] = 0 ;
- armcp15->regionReadSet_SYS[num] = 0xFFFFFFFF ;
- break ;
- case 1: /* no access at USR, all to sys */
- armcp15->regionWriteMask_USR[num] = 0 ;
- armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
- armcp15->regionReadMask_USR[num] = 0 ;
- armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
- armcp15->regionWriteMask_SYS[num] = mask ;
- armcp15->regionWriteSet_SYS[num] = set ;
- armcp15->regionReadMask_SYS[num] = mask ;
- armcp15->regionReadSet_SYS[num] = set ;
- break ;
- case 2: /* read at USR, all to sys */
- armcp15->regionWriteMask_USR[num] = 0 ;
- armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
- armcp15->regionReadMask_USR[num] = mask ;
- armcp15->regionReadSet_USR[num] = set ;
- armcp15->regionWriteMask_SYS[num] = mask ;
- armcp15->regionWriteSet_SYS[num] = set ;
- armcp15->regionReadMask_SYS[num] = mask ;
- armcp15->regionReadSet_SYS[num] = set ;
- break ;
- case 3: /* all to USR, all to sys */
- armcp15->regionWriteMask_USR[num] = mask ;
- armcp15->regionWriteSet_USR[num] = set ;
- armcp15->regionReadMask_USR[num] = mask ;
- armcp15->regionReadSet_USR[num] = set ;
- armcp15->regionWriteMask_SYS[num] = mask ;
- armcp15->regionWriteSet_SYS[num] = set ;
- armcp15->regionReadMask_SYS[num] = mask ;
- armcp15->regionReadSet_SYS[num] = set ;
- break ;
- case 5: /* no access at USR, read to sys */
- armcp15->regionWriteMask_USR[num] = 0 ;
- armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
- armcp15->regionReadMask_USR[num] = 0 ;
- armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
- armcp15->regionWriteMask_SYS[num] = 0 ;
- armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
- armcp15->regionReadMask_SYS[num] = mask ;
- armcp15->regionReadSet_SYS[num] = set ;
- break ;
- case 6: /* read at USR, read to sys */
- armcp15->regionWriteMask_USR[num] = 0 ;
- armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
- armcp15->regionReadMask_USR[num] = mask ;
- armcp15->regionReadSet_USR[num] = set ;
- armcp15->regionWriteMask_SYS[num] = 0 ;
- armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
- armcp15->regionReadMask_SYS[num] = mask ;
- armcp15->regionReadSet_SYS[num] = set ;
- break ;
- }
- switch (ACCESSTYPE(iAccess,num)) {
- case 4: /* UNP */
- case 7: /* UNP */
- case 8: /* UNP */
- case 9: /* UNP */
- case 10: /* UNP */
- case 11: /* UNP */
- case 12: /* UNP */
- case 13: /* UNP */
- case 14: /* UNP */
- case 15: /* UNP */
- case 0: /* no access at all */
- armcp15->regionExecuteMask_USR[num] = 0 ;
- armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ;
- armcp15->regionExecuteMask_SYS[num] = 0 ;
- armcp15->regionExecuteSet_SYS[num] = 0xFFFFFFFF ;
- break ;
- case 1:
- armcp15->regionExecuteMask_USR[num] = 0 ;
- armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ;
- armcp15->regionExecuteMask_SYS[num] = mask ;
- armcp15->regionExecuteSet_SYS[num] = set ;
- break ;
- case 2:
- case 3:
- case 6:
- armcp15->regionExecuteMask_USR[num] = mask ;
- armcp15->regionExecuteSet_USR[num] = set ;
- armcp15->regionExecuteMask_SYS[num] = mask ;
- armcp15->regionExecuteSet_SYS[num] = set ;
- break ;
- }
-}
-
-/* precalculate region masks/sets from cp15 register */
-void armcp15_maskPrecalc(armcp15_t *armcp15)
-{
- #define precalc(num) { \
- u32 mask = 0, set = 0xFFFFFFFF ; /* (x & 0) == 0xFF..FF is allways false (disabled) */ \
- if (BIT_N(armcp15->protectBaseSize##num,0)) /* if region is enabled */ \
- { /* reason for this define: naming includes var */ \
- mask = MASKFROMREG(armcp15->protectBaseSize##num) ; \
- set = SETFROMREG(armcp15->protectBaseSize##num) ; \
- if (SIZEIDENTIFIER(armcp15->protectBaseSize##num)==0x1F) \
- { /* for the 4GB region, u32 suffers wraparound */ \
- mask = 0 ; set = 0 ; /* (x & 0) == 0 is allways true (enabled) */ \
- } \
- } \
- armcp15_setSingleRegionAccess(armcp15,armcp15->DaccessPerm,armcp15->IaccessPerm,num,mask,set) ; \
- }
- precalc(0) ;
- precalc(1) ;
- precalc(2) ;
- precalc(3) ;
- precalc(4) ;
- precalc(5) ;
- precalc(6) ;
- precalc(7) ;
-}
-
-INLINE BOOL armcp15_isAccessAllowed(armcp15_t *armcp15,u32 address,u32 access)
-{
- int i ;
- if (!(armcp15->ctrl & 1)) return TRUE ; /* protection checking is not enabled */
- for (i=0;i<8;i++) {
- switch (access) {
- case CP15_ACCESS_WRITEUSR:
- if ((address & armcp15->regionWriteMask_USR[i]) == armcp15->regionWriteSet_USR[i]) return TRUE ;
- break ;
- case CP15_ACCESS_WRITESYS:
- if ((address & armcp15->regionWriteMask_SYS[i]) == armcp15->regionWriteSet_SYS[i]) return TRUE ;
- break ;
- case CP15_ACCESS_READUSR:
- if ((address & armcp15->regionReadMask_USR[i]) == armcp15->regionReadSet_USR[i]) return TRUE ;
- break ;
- case CP15_ACCESS_READSYS:
- if ((address & armcp15->regionReadMask_SYS[i]) == armcp15->regionReadSet_SYS[i]) return TRUE ;
- break ;
- case CP15_ACCESS_EXECUSR:
- if ((address & armcp15->regionExecuteMask_USR[i]) == armcp15->regionExecuteSet_USR[i]) return TRUE ;
- break ;
- case CP15_ACCESS_EXECSYS:
- if ((address & armcp15->regionExecuteMask_SYS[i]) == armcp15->regionExecuteSet_SYS[i]) return TRUE ;
- break ;
- }
- }
- /* when protections are enabled, but no region allows access, deny access */
- return FALSE ;
-}
-
-BOOL armcp15_dataProcess(armcp15_t *armcp15, u8 CRd, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2)
-{
- return FALSE;
-}
-
-BOOL armcp15_load(armcp15_t *armcp15, u8 CRd, u8 adr)
-{
- return FALSE;
-}
-
-BOOL armcp15_store(armcp15_t *armcp15, u8 CRd, u8 adr)
-{
- return FALSE;
-}
-
-BOOL armcp15_moveCP2ARM(armcp15_t *armcp15, u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2)
-{
- if(armcp15->cpu->CPSR.bits.mode == USR) return FALSE;
-
- switch(CRn)
- {
- case 0 :
- if((opcode1 == 0)&&(CRm==0))
- {
- switch(opcode2)
- {
- case 1 :
- *R = armcp15->cacheType;
- return TRUE;
- case 2 :
- *R = armcp15->TCMSize;
- return TRUE;
- default :
- *R = armcp15->IDCode;
- return TRUE;
- }
- }
- return FALSE;
- case 1 :
- if((opcode1==0) && (opcode2==0) && (CRm==0))
- {
- *R = armcp15->ctrl;
- return TRUE;
- }
- return FALSE;
-
- case 2 :
- if((opcode1==0) && (CRm==0))
- {
- switch(opcode2)
- {
- case 0 :
- *R = armcp15->DCConfig;
- return TRUE;
- case 1 :
- *R = armcp15->ICConfig;
- return TRUE;
- default :
- return FALSE;
- }
- }
- return FALSE;
- case 3 :
- if((opcode1==0) && (opcode2==0) && (CRm==0))
- {
- *R = armcp15->writeBuffCtrl;
- return TRUE;
- }
- return FALSE;
- case 5 :
- if((opcode1==0) && (CRm==0))
- {
- switch(opcode2)
- {
- case 2 :
- *R = armcp15->DaccessPerm;
- return TRUE;
- case 3 :
- *R = armcp15->IaccessPerm;
- return TRUE;
- default :
- return FALSE;
- }
- }
- return FALSE;
- case 6 :
- if((opcode1==0) && (opcode2==0))
- {
- switch(CRm)
- {
- case 0 :
- *R = armcp15->protectBaseSize0;
- return TRUE;
- case 1 :
- *R = armcp15->protectBaseSize1;
- return TRUE;
- case 2 :
- *R = armcp15->protectBaseSize2;
- return TRUE;
- case 3 :
- *R = armcp15->protectBaseSize3;
- return TRUE;
- case 4 :
- *R = armcp15->protectBaseSize4;
- return TRUE;
- case 5 :
- *R = armcp15->protectBaseSize5;
- return TRUE;
- case 6 :
- *R = armcp15->protectBaseSize6;
- return TRUE;
- case 7 :
- *R = armcp15->protectBaseSize7;
- return TRUE;
- default :
- return FALSE;
- }
- }
- return FALSE;
- case 9 :
- if(opcode1==0)
- {
- switch(CRm)
- {
- case 0 :
- switch(opcode2)
- {
- case 0 :
- *R = armcp15->DcacheLock;
- return TRUE;
- case 1 :
- *R = armcp15->IcacheLock;
- return TRUE;
- default :
- return FALSE;
- }
- case 1 :
- switch(opcode2)
- {
- case 0 :
- *R = armcp15->DTCMRegion;
- return TRUE;
- case 1 :
- *R = armcp15->ITCMRegion;
- return TRUE;
- default :
- return FALSE;
- }
- }
- }
- return FALSE;
- default :
- return FALSE;
- }
-}
-
-
-u32 CP15wait4IRQ(armcpu_t *cpu)
-{
- /* on the first call, wirq is not set */
- if(cpu->wirq)
- {
- /* check wether an irq was issued */
- if(!cpu->waitIRQ)
- {
- cpu->waitIRQ = 0;
- cpu->wirq = 0;
- return 1; /* return execution */
- }
- /* otherwise, repeat this instruction */
- cpu->R[15] = cpu->instruct_adr;
- cpu->next_instruction = cpu->R[15];
- return 1;
- }
- /* first run, set us into waiting state */
- cpu->waitIRQ = 1;
- cpu->wirq = 1;
- /* and set next instruction to repeat this */
- cpu->R[15] = cpu->instruct_adr;
- cpu->next_instruction = cpu->R[15];
- /* CHECKME: IME shouldn't be modified (?) */
- MMU.reg_IME[0] = 1;
- return 1;
-}
-
-BOOL armcp15_moveARM2CP(armcp15_t *armcp15, u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2)
-{
- if(armcp15->cpu->CPSR.bits.mode == USR) return FALSE;
-
- switch(CRn)
- {
- case 1 :
- if((opcode1==0) && (opcode2==0) && (CRm==0))
- {
- armcp15->ctrl = val;
- MMU.ARM9_RW_MODE = BIT7(val);
- armcp15->cpu->intVector = 0x0FFF0000 * (BIT13(val));
- armcp15->cpu->LDTBit = !BIT15(val); //TBit
- /*if(BIT17(val))
- {
- log::ajouter("outch !!!!!!!");
- }
- if(BIT19(val))
- {
- log::ajouter("outch !!!!!!!");
- }*/
- return TRUE;
- }
- return FALSE;
- case 2 :
- if((opcode1==0) && (CRm==0))
- {
- switch(opcode2)
- {
- case 0 :
- armcp15->DCConfig = val;
- return TRUE;
- case 1 :
- armcp15->ICConfig = val;
- return TRUE;
- default :
- return FALSE;
- }
- }
- return FALSE;
- case 3 :
- if((opcode1==0) && (opcode2==0) && (CRm==0))
- {
- armcp15->writeBuffCtrl = val;
- return TRUE;
- }
- return FALSE;
- if((opcode1==0) && (CRm==0))
- {
- switch(opcode2)
- {
- case 2 :
- armcp15->DaccessPerm = val;
- armcp15_maskPrecalc(armcp15);
- return TRUE;
- case 3 :
- armcp15->IaccessPerm = val;
- armcp15_maskPrecalc(armcp15);
- return TRUE;
- default :
- return FALSE;
- }
- }
- return FALSE;
- case 6 :
- if((opcode1==0) && (opcode2==0))
- {
- switch(CRm)
- {
- case 0 :
- armcp15->protectBaseSize0 = val;
- armcp15_maskPrecalc(armcp15) ;
- return TRUE;
- case 1 :
- armcp15->protectBaseSize1 = val;
- armcp15_maskPrecalc(armcp15) ;
- return TRUE;
- case 2 :
- armcp15->protectBaseSize2 = val;
- armcp15_maskPrecalc(armcp15) ;
- return TRUE;
- case 3 :
- armcp15->protectBaseSize3 = val;
- armcp15_maskPrecalc(armcp15) ;
- return TRUE;
- case 4 :
- armcp15->protectBaseSize4 = val;
- armcp15_maskPrecalc(armcp15) ;
- return TRUE;
- case 5 :
- armcp15->protectBaseSize5 = val;
- armcp15_maskPrecalc(armcp15) ;
- return TRUE;
- case 6 :
- armcp15->protectBaseSize6 = val;
- armcp15_maskPrecalc(armcp15) ;
- return TRUE;
- case 7 :
- armcp15->protectBaseSize7 = val;
- armcp15_maskPrecalc(armcp15) ;
- return TRUE;
- default :
- return FALSE;
- }
- }
- return FALSE;
- case 7 :
- if((CRm==0)&&(opcode1==0)&&((opcode2==4)))
- {
- CP15wait4IRQ(armcp15->cpu);
- return TRUE;
- }
- return FALSE;
- case 9 :
- if(opcode1==0)
- {
- switch(CRm)
- {
- case 0 :
- switch(opcode2)
- {
- case 0 :
- armcp15->DcacheLock = val;
- return TRUE;
- case 1 :
- armcp15->IcacheLock = val;
- return TRUE;
- default :
- return FALSE;
- }
- case 1 :
- switch(opcode2)
- {
- case 0 :
- armcp15->DTCMRegion = val;
- MMU.DTCMRegion = val & 0x0FFFFFFC0;
- /*sprintf(logbuf, "%08X", val);
- log::ajouter(logbuf);*/
- return TRUE;
- case 1 :
- armcp15->ITCMRegion = val;
- /* ITCM base is not writeable! */
- MMU.ITCMRegion = 0;
- return TRUE;
- default :
- return FALSE;
- }
- }
- }
- return FALSE;
- default :
- return FALSE;
- }
-}
-
-
-
diff --git a/src/xsf/desmume/cp15.cc b/src/xsf/desmume/cp15.cc
new file mode 100644
index 000000000000..1c07c550c301
--- /dev/null
+++ b/src/xsf/desmume/cp15.cc
@@ -0,0 +1,590 @@
+/* Copyright (C) 2006 yopyop
+ yopyop156 at ifrance.com
+ yopyop156.ifrance.com
+
+ This file is part of DeSmuME
+
+ DeSmuME 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.
+
+ DeSmuME 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 DeSmuME; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <stdlib.h>
+
+#include "cp15.h"
+#include "debug.h"
+#include "MMU.h"
+
+armcp15_t *armcp15_new(armcpu_t * c)
+{
+ int i;
+ armcp15_t *armcp15 = (armcp15_t*)malloc(sizeof(armcp15_t));
+ if(!armcp15) return nullptr;
+
+ armcp15->cpu = c;
+ armcp15->IDCode = 0x41049460;
+ armcp15->cacheType = 0x0F0D2112;
+ armcp15->TCMSize = 0x00140140;
+ armcp15->ctrl = 0x00000000;
+ armcp15->DCConfig = 0x0;
+ armcp15->ICConfig = 0x0;
+ armcp15->writeBuffCtrl = 0x0;
+ armcp15->und = 0x0;
+ armcp15->DaccessPerm = 0x22222222;
+ armcp15->IaccessPerm = 0x22222222;
+ armcp15->protectBaseSize0 = 0x0;
+ armcp15->protectBaseSize1 = 0x0;
+ armcp15->protectBaseSize2 = 0x0;
+ armcp15->protectBaseSize3 = 0x0;
+ armcp15->protectBaseSize4 = 0x0;
+ armcp15->protectBaseSize5 = 0x0;
+ armcp15->protectBaseSize6 = 0x0;
+ armcp15->protectBaseSize7 = 0x0;
+ armcp15->cacheOp = 0x0;
+ armcp15->DcacheLock = 0x0;
+ armcp15->IcacheLock = 0x0;
+ armcp15->ITCMRegion = 0x0C;
+ armcp15->DTCMRegion = 0x0080000A;
+ armcp15->processID = 0;
+
+ /* preset calculated regionmasks */
+ for (i=0;i<8;i++) {
+ armcp15->regionWriteMask_USR[i] = 0 ;
+ armcp15->regionWriteMask_SYS[i] = 0 ;
+ armcp15->regionReadMask_USR[i] = 0 ;
+ armcp15->regionReadMask_SYS[i] = 0 ;
+ armcp15->regionExecuteMask_USR[i] = 0 ;
+ armcp15->regionExecuteMask_SYS[i] = 0 ;
+ armcp15->regionWriteSet_USR[i] = 0 ;
+ armcp15->regionWriteSet_SYS[i] = 0 ;
+ armcp15->regionReadSet_USR[i] = 0 ;
+ armcp15->regionReadSet_SYS[i] = 0 ;
+ armcp15->regionExecuteSet_USR[i] = 0 ;
+ armcp15->regionExecuteSet_SYS[i] = 0 ;
+ } ;
+
+ return armcp15;
+}
+
+#define ACCESSTYPE(val,n) (((val) >> (4*n)) & 0x0F)
+#define SIZEIDENTIFIER(val) ((((val) >> 1) & 0x1F))
+#define SIZEBINARY(val) (1 << (SIZEIDENTIFIER(val)+1))
+#define MASKFROMREG(val) (~((SIZEBINARY(val)-1) | 0x3F))
+#define SETFROMREG(val) ((val) & MASKFROMREG(val))
+/* sets the precalculated regions to mask,set for the affected accesstypes */
+void armcp15_setSingleRegionAccess(armcp15_t *armcp15,unsigned long dAccess,unsigned long iAccess,unsigned char num, unsigned long mask,unsigned long set) {
+
+ switch (ACCESSTYPE(dAccess,num)) {
+ case 4: /* UNP */
+ case 7: /* UNP */
+ case 8: /* UNP */
+ case 9: /* UNP */
+ case 10: /* UNP */
+ case 11: /* UNP */
+ case 12: /* UNP */
+ case 13: /* UNP */
+ case 14: /* UNP */
+ case 15: /* UNP */
+ case 0: /* no access at all */
+ armcp15->regionWriteMask_USR[num] = 0 ;
+ armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
+ armcp15->regionReadMask_USR[num] = 0 ;
+ armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
+ armcp15->regionWriteMask_SYS[num] = 0 ;
+ armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
+ armcp15->regionReadMask_SYS[num] = 0 ;
+ armcp15->regionReadSet_SYS[num] = 0xFFFFFFFF ;
+ break ;
+ case 1: /* no access at USR, all to sys */
+ armcp15->regionWriteMask_USR[num] = 0 ;
+ armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
+ armcp15->regionReadMask_USR[num] = 0 ;
+ armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
+ armcp15->regionWriteMask_SYS[num] = mask ;
+ armcp15->regionWriteSet_SYS[num] = set ;
+ armcp15->regionReadMask_SYS[num] = mask ;
+ armcp15->regionReadSet_SYS[num] = set ;
+ break ;
+ case 2: /* read at USR, all to sys */
+ armcp15->regionWriteMask_USR[num] = 0 ;
+ armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
+ armcp15->regionReadMask_USR[num] = mask ;
+ armcp15->regionReadSet_USR[num] = set ;
+ armcp15->regionWriteMask_SYS[num] = mask ;
+ armcp15->regionWriteSet_SYS[num] = set ;
+ armcp15->regionReadMask_SYS[num] = mask ;
+ armcp15->regionReadSet_SYS[num] = set ;
+ break ;
+ case 3: /* all to USR, all to sys */
+ armcp15->regionWriteMask_USR[num] = mask ;
+ armcp15->regionWriteSet_USR[num] = set ;
+ armcp15->regionReadMask_USR[num] = mask ;
+ armcp15->regionReadSet_USR[num] = set ;
+ armcp15->regionWriteMask_SYS[num] = mask ;
+ armcp15->regionWriteSet_SYS[num] = set ;
+ armcp15->regionReadMask_SYS[num] = mask ;
+ armcp15->regionReadSet_SYS[num] = set ;
+ break ;
+ case 5: /* no access at USR, read to sys */
+ armcp15->regionWriteMask_USR[num] = 0 ;
+ armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
+ armcp15->regionReadMask_USR[num] = 0 ;
+ armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
+ armcp15->regionWriteMask_SYS[num] = 0 ;
+ armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
+ armcp15->regionReadMask_SYS[num] = mask ;
+ armcp15->regionReadSet_SYS[num] = set ;
+ break ;
+ case 6: /* read at USR, read to sys */
+ armcp15->regionWriteMask_USR[num] = 0 ;
+ armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
+ armcp15->regionReadMask_USR[num] = mask ;
+ armcp15->regionReadSet_USR[num] = set ;
+ armcp15->regionWriteMask_SYS[num] = 0 ;
+ armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
+ armcp15->regionReadMask_SYS[num] = mask ;
+ armcp15->regionReadSet_SYS[num] = set ;
+ break ;
+ }
+ switch (ACCESSTYPE(iAccess,num)) {
+ case 4: /* UNP */
+ case 7: /* UNP */
+ case 8: /* UNP */
+ case 9: /* UNP */
+ case 10: /* UNP */
+ case 11: /* UNP */
+ case 12: /* UNP */
+ case 13: /* UNP */
+ case 14: /* UNP */
+ case 15: /* UNP */
+ case 0: /* no access at all */
+ armcp15->regionExecuteMask_USR[num] = 0 ;
+ armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ;
+ armcp15->regionExecuteMask_SYS[num] = 0 ;
+ armcp15->regionExecuteSet_SYS[num] = 0xFFFFFFFF ;
+ break ;
+ case 1:
+ armcp15->regionExecuteMask_USR[num] = 0 ;
+ armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ;
+ armcp15->regionExecuteMask_SYS[num] = mask ;
+ armcp15->regionExecuteSet_SYS[num] = set ;
+ break ;
+ case 2:
+ case 3:
+ case 6:
+ armcp15->regionExecuteMask_USR[num] = mask ;
+ armcp15->regionExecuteSet_USR[num] = set ;
+ armcp15->regionExecuteMask_SYS[num] = mask ;
+ armcp15->regionExecuteSet_SYS[num] = set ;
+ break ;
+ }
+}
+
+/* precalculate region masks/sets from cp15 register */
+void armcp15_maskPrecalc(armcp15_t *armcp15)
+{
+ #define precalc(num) { \
+ u32 mask = 0, set = 0xFFFFFFFF ; /* (x & 0) == 0xFF..FF is allways false (disabled) */ \
+ if (BIT_N(armcp15->protectBaseSize##num,0)) /* if region is enabled */ \
+ { /* reason for this define: naming includes var */ \
+ mask = MASKFROMREG(armcp15->protectBaseSize##num) ; \
+ set = SETFROMREG(armcp15->protectBaseSize##num) ; \
+ if (SIZEIDENTIFIER(armcp15->protectBaseSize##num)==0x1F) \
+ { /* for the 4GB region, u32 suffers wraparound */ \
+ mask = 0 ; set = 0 ; /* (x & 0) == 0 is allways true (enabled) */ \
+ } \
+ } \
+ armcp15_setSingleRegionAccess(armcp15,armcp15->DaccessPerm,armcp15->IaccessPerm,num,mask,set) ; \
+ }
+ precalc(0) ;
+ precalc(1) ;
+ precalc(2) ;
+ precalc(3) ;
+ precalc(4) ;
+ precalc(5) ;
+ precalc(6) ;
+ precalc(7) ;
+}
+
+INLINE BOOL armcp15_isAccessAllowed(armcp15_t *armcp15,u32 address,u32 access)
+{
+ int i ;
+ if (!(armcp15->ctrl & 1)) return true ; /* protection checking is not enabled */
+ for (i=0;i<8;i++) {
+ switch (access) {
+ case CP15_ACCESS_WRITEUSR:
+ if ((address & armcp15->regionWriteMask_USR[i]) == armcp15->regionWriteSet_USR[i]) return true ;
+ break ;
+ case CP15_ACCESS_WRITESYS:
+ if ((address & armcp15->regionWriteMask_SYS[i]) == armcp15->regionWriteSet_SYS[i]) return true ;
+ break ;
+ case CP15_ACCESS_READUSR:
+ if ((address & armcp15->regionReadMask_USR[i]) == armcp15->regionReadSet_USR[i]) return true ;
+ break ;
+ case CP15_ACCESS_READSYS:
+ if ((address & armcp15->regionReadMask_SYS[i]) == armcp15->regionReadSet_SYS[i]) return true ;
+ break ;
+ case CP15_ACCESS_EXECUSR:
+ if ((address & armcp15->regionExecuteMask_USR[i]) == armcp15->regionExecuteSet_USR[i]) return true ;
+ break ;
+ case CP15_ACCESS_EXECSYS:
+ if ((address & armcp15->regionExecuteMask_SYS[i]) == armcp15->regionExecuteSet_SYS[i]) return true ;
+ break ;
+ }
+ }
+ /* when protections are enabled, but no region allows access, deny access */
+ return false ;
+}
+
+BOOL armcp15_dataProcess(armcp15_t *armcp15, u8 CRd, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2)
+{
+ return false;
+}
+
+BOOL armcp15_load(armcp15_t *armcp15, u8 CRd, u8 adr)
+{
+ return false;
+}
+
+BOOL armcp15_store(armcp15_t *armcp15, u8 CRd, u8 adr)
+{
+ return false;
+}
+
+BOOL armcp15_moveCP2ARM(armcp15_t *armcp15, u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2)
+{
+ if(armcp15->cpu->CPSR.bits.mode == USR) return false;
+
+ switch(CRn)
+ {
+ case 0 :
+ if((opcode1 == 0)&&(CRm==0))
+ {
+ switch(opcode2)
+ {
+ case 1 :
+ *R = armcp15->cacheType;
+ return true;
+ case 2 :
+ *R = armcp15->TCMSize;
+ return true;
+ default :
+ *R = armcp15->IDCode;
+ return true;
+ }
+ }
+ return false;
+ case 1 :
+ if((opcode1==0) && (opcode2==0) && (CRm==0))
+ {
+ *R = armcp15->ctrl;
+ return true;
+ }
+ return false;
+
+ case 2 :
+ if((opcode1==0) && (CRm==0))
+ {
+ switch(opcode2)
+ {
+ case 0 :
+ *R = armcp15->DCConfig;
+ return true;
+ case 1 :
+ *R = armcp15->ICConfig;
+ return true;
+ default :
+ return false;
+ }
+ }
+ return false;
+ case 3 :
+ if((opcode1==0) && (opcode2==0) && (CRm==0))
+ {
+ *R = armcp15->writeBuffCtrl;
+ return true;
+ }
+ return false;
+ case 5 :
+ if((opcode1==0) && (CRm==0))
+ {
+ switch(opcode2)
+ {
+ case 2 :
+ *R = armcp15->DaccessPerm;
+ return true;
+ case 3 :
+ *R = armcp15->IaccessPerm;
+ return true;
+ default :
+ return false;
+ }
+ }
+ return false;
+ case 6 :
+ if((opcode1==0) && (opcode2==0))
+ {
+ switch(CRm)
+ {
+ case 0 :
+ *R = armcp15->protectBaseSize0;
+ return true;
+ case 1 :
+ *R = armcp15->protectBaseSize1;
+ return true;
+ case 2 :
+ *R = armcp15->protectBaseSize2;
+ return true;
+ case 3 :
+ *R = armcp15->protectBaseSize3;
+ return true;
+ case 4 :
+ *R = armcp15->protectBaseSize4;
+ return true;
+ case 5 :
+ *R = armcp15->protectBaseSize5;
+ return true;
+ case 6 :
+ *R = armcp15->protectBaseSize6;
+ return true;
+ case 7 :
+ *R = armcp15->protectBaseSize7;
+ return true;
+ default :
+ return false;
+ }
+ }
+ return false;
+ case 9 :
+ if(opcode1==0)
+ {
+ switch(CRm)
+ {
+ case 0 :
+ switch(opcode2)
+ {
+ case 0 :
+ *R = armcp15->DcacheLock;
+ return true;
+ case 1 :
+ *R = armcp15->IcacheLock;
+ return true;
+ default :
+ return false;
+ }
+ case 1 :
+ switch(opcode2)
+ {
+ case 0 :
+ *R = armcp15->DTCMRegion;
+ return true;
+ case 1 :
+ *R = armcp15->ITCMRegion;
+ return true;
+ default :
+ return false;
+ }
+ }
+ }
+ return false;
+ default :
+ return false;
+ }
+}
+
+
+u32 CP15wait4IRQ(armcpu_t *cpu)
+{
+ /* on the first call, wirq is not set */
+ if(cpu->wirq)
+ {
+ /* check wether an irq was issued */
+ if(!cpu->waitIRQ)
+ {
+ cpu->waitIRQ = 0;
+ cpu->wirq = 0;
+ return 1; /* return execution */
+ }
+ /* otherwise, repeat this instruction */
+ cpu->R[15] = cpu->instruct_adr;
+ cpu->next_instruction = cpu->R[15];
+ return 1;
+ }
+ /* first run, set us into waiting state */
+ cpu->waitIRQ = 1;
+ cpu->wirq = 1;
+ /* and set next instruction to repeat this */
+ cpu->R[15] = cpu->instruct_adr;
+ cpu->next_instruction = cpu->R[15];
+ /* CHECKME: IME shouldn't be modified (?) */
+ MMU.reg_IME[0] = 1;
+ return 1;
+}
+
+BOOL armcp15_moveARM2CP(armcp15_t *armcp15, u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2)
+{
+ if(armcp15->cpu->CPSR.bits.mode == USR) return false;
+
+ switch(CRn)
+ {
+ case 1 :
+ if((opcode1==0) && (opcode2==0) && (CRm==0))
+ {
+ armcp15->ctrl = val;
+ MMU.ARM9_RW_MODE = BIT7(val);
+ armcp15->cpu->intVector = 0x0FFF0000 * (BIT13(val));
+ armcp15->cpu->LDTBit = !BIT15(val); //TBit
+ /*if(BIT17(val))
+ {
+ log::ajouter("outch !!!!!!!");
+ }
+ if(BIT19(val))
+ {
+ log::ajouter("outch !!!!!!!");
+ }*/
+ return true;
+ }
+ return false;
+ case 2 :
+ if((opcode1==0) && (CRm==0))
+ {
+ switch(opcode2)
+ {
+ case 0 :
+ armcp15->DCConfig = val;
+ return true;
+ case 1 :
+ armcp15->ICConfig = val;
+ return true;
+ default :
+ return false;
+ }
+ }
+ return false;
+ case 3 :
+ if((opcode1==0) && (opcode2==0) && (CRm==0))
+ {
+ armcp15->writeBuffCtrl = val;
+ return true;
+ }
+ return false;
+ if((opcode1==0) && (CRm==0))
+ {
+ switch(opcode2)
+ {
+ case 2 :
+ armcp15->DaccessPerm = val;
+ armcp15_maskPrecalc(armcp15);
+ return true;
+ case 3 :
+ armcp15->IaccessPerm = val;
+ armcp15_maskPrecalc(armcp15);
+ return true;
+ default :
+ return false;
+ }
+ }
+ return false;
+ case 6 :
+ if((opcode1==0) && (opcode2==0))
+ {
+ switch(CRm)
+ {
+ case 0 :
+ armcp15->protectBaseSize0 = val;
+ armcp15_maskPrecalc(armcp15) ;
+ return true;
+ case 1 :
+ armcp15->protectBaseSize1 = val;
+ armcp15_maskPrecalc(armcp15) ;
+ return true;
+ case 2 :
+ armcp15->protectBaseSize2 = val;
+ armcp15_maskPrecalc(armcp15) ;
+ return true;
+ case 3 :
+ armcp15->protectBaseSize3 = val;
+ armcp15_maskPrecalc(armcp15) ;
+ return true;
+ case 4 :
+ armcp15->protectBaseSize4 = val;
+ armcp15_maskPrecalc(armcp15) ;
+ return true;
+ case 5 :
+ armcp15->protectBaseSize5 = val;
+ armcp15_maskPrecalc(armcp15) ;
+ return true;
+ case 6 :
+ armcp15->protectBaseSize6 = val;
+ armcp15_maskPrecalc(armcp15) ;
+ return true;
+ case 7 :
+ armcp15->protectBaseSize7 = val;
+ armcp15_maskPrecalc(armcp15) ;
+ return true;
+ default :
+ return false;
+ }
+ }
+ return false;
+ case 7 :
+ if((CRm==0)&&(opcode1==0)&&((opcode2==4)))
+ {
+ CP15wait4IRQ(armcp15->cpu);
+ return true;
+ }
+ return false;
+ case 9 :
+ if(opcode1==0)
+ {
+ switch(CRm)
+ {
+ case 0 :
+ switch(opcode2)
+ {
+ case 0 :
+ armcp15->DcacheLock = val;
+ return true;
+ case 1 :
+ armcp15->IcacheLock = val;
+ return true;
+ default :
+ return false;
+ }
+ case 1 :
+ switch(opcode2)
+ {
+ case 0 :
+ armcp15->DTCMRegion = val;
+ MMU.DTCMRegion = val & 0x0FFFFFFC0;
+ /*sprintf(logbuf, "%08X", val);
+ log::ajouter(logbuf);*/
+ return true;
+ case 1 :
+ armcp15->ITCMRegion = val;
+ /* ITCM base is not writeable! */
+ MMU.ITCMRegion = 0;
+ return true;
+ default :
+ return false;
+ }
+ }
+ }
+ return false;
+ default :
+ return false;
+ }
+}
+
+
+
diff --git a/src/xsf/desmume/cp15.h b/src/xsf/desmume/cp15.h
index 83122516bce5..4735a9668311 100644
--- a/src/xsf/desmume/cp15.h
+++ b/src/xsf/desmume/cp15.h
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __CP15_H__
diff --git a/src/xsf/desmume/dscard.h b/src/xsf/desmume/dscard.h
index 9b002e3479c3..dc185e1c36b4 100644
--- a/src/xsf/desmume/dscard.h
+++ b/src/xsf/desmume/dscard.h
@@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __DSCARD_H__
diff --git a/src/xsf/desmume/instruction_tabdef.inc b/src/xsf/desmume/instruction_tabdef.inc
index f63763a732a7..cc7d9416ca37 100644
--- a/src/xsf/desmume/instruction_tabdef.inc
+++ b/src/xsf/desmume/instruction_tabdef.inc
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
TYPE_RETOUR (*CALLTYPE NOM_TAB[4096])(PARAMETRES)={
diff --git a/src/xsf/desmume/matrix.c b/src/xsf/desmume/matrix.c
deleted file mode 100644
index 555d62b1532d..000000000000
--- a/src/xsf/desmume/matrix.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- Copyright (C) 2006-2007 shash
-
- This file is part of DeSmuME
-
- DeSmuME 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.
-
- DeSmuME 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 DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "matrix.h"
-
-void MatrixInit (float *matrix)
-{
- memset (matrix, 0, sizeof(float)*16);
-
- matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.f;
-}
-
-void MatrixMultVec4x4 (float *matrix, float *vecPtr)
-{
- float x = vecPtr[0];
- float y = vecPtr[1];
- float z = vecPtr[2];
-
- vecPtr[0] = x * matrix[0] + y * matrix[4] + z * matrix[ 8] + matrix[12];
- vecPtr[1] = x * matrix[1] + y * matrix[5] + z * matrix[ 9] + matrix[13];
- vecPtr[2] = x * matrix[2] + y * matrix[6] + z * matrix[10] + matrix[14];
-}
-
-void MatrixMultVec3x3 (float *matrix, float *vecPtr)
-{
- float x = vecPtr[0];
- float y = vecPtr[1];
- float z = vecPtr[2];
-
- vecPtr[0] = x * matrix[0] + y * matrix[4] + z * matrix[ 8];
- vecPtr[1] = x * matrix[1] + y * matrix[5] + z * matrix[ 9];
- vecPtr[2] = x * matrix[2] + y * matrix[6] + z * matrix[10];
-}
-
-void MatrixIdentity (float *matrix)
-{
- memset (matrix, 0, sizeof(float)*16);
-
- matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.f;
-}
-
-void MatrixMultiply (float *matrix, float *rightMatrix)
-{
- float tmpMatrix[16];
-
- tmpMatrix[0] = (matrix[0]*rightMatrix[0])+(matrix[4]*rightMatrix[1])+(matrix[8]*rightMatrix[2])+(matrix[12]*rightMatrix[3]);
- tmpMatrix[1] = (matrix[1]*rightMatrix[0])+(matrix[5]*rightMatrix[1])+(matrix[9]*rightMatrix[2])+(matrix[13]*rightMatrix[3]);
- tmpMatrix[2] = (matrix[2]*rightMatrix[0])+(matrix[6]*rightMatrix[1])+(matrix[10]*rightMatrix[2])+(matrix[14]*rightMatrix[3]);
- tmpMatrix[3] = (matrix[3]*rightMatrix[0])+(matrix[7]*rightMatrix[1])+(matrix[11]*rightMatrix[2])+(matrix[15]*rightMatrix[3]);
-
- tmpMatrix[4] = (matrix[0]*rightMatrix[4])+(matrix[4]*rightMatrix[5])+(matrix[8]*rightMatrix[6])+(matrix[12]*rightMatrix[7]);
- tmpMatrix[5] = (matrix[1]*rightMatrix[4])+(matrix[5]*rightMatrix[5])+(matrix[9]*rightMatrix[6])+(matrix[13]*rightMatrix[7]);
- tmpMatrix[6] = (matrix[2]*rightMatrix[4])+(matrix[6]*rightMatrix[5])+(matrix[10]*rightMatrix[6])+(matrix[14]*rightMatrix[7]);
- tmpMatrix[7] = (matrix[3]*rightMatrix[4])+(matrix[7]*rightMatrix[5])+(matrix[11]*rightMatrix[6])+(matrix[15]*rightMatrix[7]);
-
- tmpMatrix[8] = (matrix[0]*rightMatrix[8])+(matrix[4]*rightMatrix[9])+(matrix[8]*rightMatrix[10])+(matrix[12]*rightMatrix[11]);
- tmpMatrix[9] = (matrix[1]*rightMatrix[8])+(matrix[5]*rightMatrix[9])+(matrix[9]*rightMatrix[10])+(matrix[13]*rightMatrix[11]);
- tmpMatrix[10] = (matrix[2]*rightMatrix[8])+(matrix[6]*rightMatrix[9])+(matrix[10]*rightMatrix[10])+(matrix[14]*rightMatrix[11]);
- tmpMatrix[11] = (matrix[3]*rightMatrix[8])+(matrix[7]*rightMatrix[9])+(matrix[11]*rightMatrix[10])+(matrix[15]*rightMatrix[11]);
-
- tmpMatrix[12] = (matrix[0]*rightMatrix[12])+(matrix[4]*rightMatrix[13])+(matrix[8]*rightMatrix[14])+(matrix[12]*rightMatrix[15]);
- tmpMatrix[13] = (matrix[1]*rightMatrix[12])+(matrix[5]*rightMatrix[13])+(matrix[9]*rightMatrix[14])+(matrix[13]*rightMatrix[15]);
- tmpMatrix[14] = (matrix[2]*rightMatrix[12])+(matrix[6]*rightMatrix[13])+(matrix[10]*rightMatrix[14])+(matrix[14]*rightMatrix[15]);
- tmpMatrix[15] = (matrix[3]*rightMatrix[12])+(matrix[7]*rightMatrix[13])+(matrix[11]*rightMatrix[14])+(matrix[15]*rightMatrix[15]);
-
- memcpy (matrix, tmpMatrix, sizeof(float)*16);
-}
-/*
-void MatrixMulti (float* right)
-{
- float tmpMatrix[16];
-
- tmpMatrix[0] = (matrix[0]*right[0])+(matrix[4]*right[1])+(matrix[8]*right[2])+(matrix[12]*right[3]);
- tmpMatrix[1] = (matrix[1]*right[0])+(matrix[5]*right[1])+(matrix[9]*right[2])+(matrix[13]*right[3]);
- tmpMatrix[2] = (matrix[2]*right[0])+(matrix[6]*right[1])+(matrix[10]*right[2])+(matrix[14]*right[3]);
- tmpMatrix[3] = (matrix[3]*right[0])+(matrix[7]*right[1])+(matrix[11]*right[2])+(matrix[15]*right[3]);
-
- tmpMatrix[4] = (matrix[0]*right[4])+(matrix[4]*right[5])+(matrix[8]*right[6])+(matrix[12]*right[7]);
- tmpMatrix[5] = (matrix[1]*right[4])+(matrix[5]*right[5])+(matrix[9]*right[6])+(matrix[13]*right[7]);
- tmpMatrix[6] = (matrix[2]*right[4])+(matrix[6]*right[5])+(matrix[10]*right[6])+(matrix[14]*right[7]);
- tmpMatrix[7] = (matrix[3]*right[4])+(matrix[7]*right[5])+(matrix[11]*right[6])+(matrix[15]*right[7]);
-
- tmpMatrix[8] = (matrix[0]*right[8])+(matrix[4]*right[9])+(matrix[8]*right[10])+(matrix[12]*right[11]);
- tmpMatrix[9] = (matrix[1]*right[8])+(matrix[5]*right[9])+(matrix[9]*right[10])+(matrix[13]*right[11]);
- tmpMatrix[10] = (matrix[2]*right[8])+(matrix[6]*right[9])+(matrix[10]*right[10])+(matrix[14]*right[11]);
- tmpMatrix[11] = (matrix[3]*right[8])+(matrix[7]*right[9])+(matrix[11]*right[10])+(matrix[15]*right[11]);
-
- tmpMatrix[12] = (matrix[0]*right[12])+(matrix[4]*right[13])+(matrix[8]*right[14])+(matrix[12]*right[15]);
- tmpMatrix[13] = (matrix[1]*right[12])+(matrix[5]*right[13])+(matrix[9]*right[14])+(matrix[13]*right[15]);
- tmpMatrix[14] = (matrix[2]*right[12])+(matrix[6]*right[13])+(matrix[10]*right[14])+(matrix[14]*right[15]);
- tmpMatrix[15] = (matrix[3]*right[12])+(matrix[7]*right[13])+(matrix[11]*right[14])+(matrix[15]*right[15]);
-
- memcpy (matrix, tmpMatrix, sizeof(float)*16);
-}
-
-
-float* Matrix::Get (void)
-{
- return matrix;
-}
-
-float MatrixGet (float *matrix, int index)
-{
- return matrix[index];
-}
-*/
-
-float MatrixGetMultipliedIndex (int index, float *matrix, float *rightMatrix)
-{
- int iMod = index%4, iDiv = (index>>2)<<2;
-
- return (matrix[iMod ]*rightMatrix[iDiv ])+(matrix[iMod+ 4]*rightMatrix[iDiv+1])+
- (matrix[iMod+8]*rightMatrix[iDiv+2])+(matrix[iMod+12]*rightMatrix[iDiv+3]);
-}
-
-void MatrixSet (float *matrix, int x, int y, float value)
-{
- matrix [x+(y<<2)] = value;
-}
-/*
-void Matrix::Set (int pos, float value)
-{
- matrix [pos] = value;
-}
-*/
-void MatrixCopy (float *matrixDST, float *matrixSRC)
-{
- memcpy (matrixDST, matrixSRC, sizeof(float)*16);
-}
-
-void MatrixTranslate (float *matrix, float *ptr)
-{
- matrix[12] += (matrix[0]*ptr[0])+(matrix[4]*ptr[1])+(matrix[ 8]*ptr[2]);
- matrix[13] += (matrix[1]*ptr[0])+(matrix[5]*ptr[1])+(matrix[ 9]*ptr[2]);
- matrix[14] += (matrix[2]*ptr[0])+(matrix[6]*ptr[1])+(matrix[10]*ptr[2]);
- matrix[15] += (matrix[3]*ptr[0])+(matrix[7]*ptr[1])+(matrix[11]*ptr[2]);
-}
-
-void MatrixScale (float *matrix, float *ptr)
-{
- matrix[0] *= ptr[0];
- matrix[1] *= ptr[0];
- matrix[2] *= ptr[0];
- matrix[3] *= ptr[0];
-
- matrix[4] *= ptr[1];
- matrix[5] *= ptr[1];
- matrix[6] *= ptr[1];
- matrix[7] *= ptr[1];
-
- matrix[8] *= ptr[2];
- matrix[9] *= ptr[2];
- matrix[10] *= ptr[2];
- matrix[11] *= ptr[2];
-}
-/*
-void Matrix::Set (float a11, float a21, float a31, float a41,
- float a12, float a22, float a32, float a42,
- float a13, float a23, float a33, float a43,
- float a14, float a24, float a34, float a44)
-{
-}
-*/
-
-
-//-----------------------------------------
-
-void MatrixStackInit (MatrixStack *stack)
-{
- stack->matrix = NULL;
- stack->position = 0;
- stack->size = 0;
-}
-
-void MatrixStackSetMaxSize (MatrixStack *stack, int size)
-{
- int i = 0;
-
- stack->size = size;
-
- if (stack->matrix == NULL)
- {
- stack->matrix = (float*) malloc (stack->size*16*sizeof(float));
- }
- else
- {
- free (stack->matrix);
- stack->matrix = (float*) malloc (stack->size*16*sizeof(float));
- }
-
- for (i = 0; i < stack->size; i++)
- {
- MatrixInit (&stack->matrix[i*16]);
- }
-
- stack->size--;
-}
-
-
-void MatrixStackSetStackPosition (MatrixStack *stack, int pos)
-{
- stack->position += pos;
-
- if (stack->position < 0)
- stack->position = 0;
- else if (stack->position > stack->size)
- stack->position = stack->size;
-}
-
-void MatrixStackPushMatrix (MatrixStack *stack, float *ptr)
-{
- MatrixCopy (&stack->matrix[stack->position*16], ptr);
-
- MatrixStackSetStackPosition (stack, 1);
-}
-
-float * MatrixStackPopMatrix (MatrixStack *stack, int size)
-{
- MatrixStackSetStackPosition(stack, -size);
-
- return &stack->matrix[stack->position*16];
-}
-
-float * MatrixStackGetPos (MatrixStack *stack, int pos)
-{
- return &stack->matrix[pos*16];
-}
-
-float * MatrixStackGet (MatrixStack *stack)
-{
- return &stack->matrix[stack->position*16];
-}
-
-void MatrixStackLoadMatrix (MatrixStack *stack, int pos, float *ptr)
-{
- MatrixCopy (&stack->matrix[pos*16], ptr);
-}
diff --git a/src/xsf/desmume/matrix.cc b/src/xsf/desmume/matrix.cc
new file mode 100644
index 000000000000..217ad316b83e
--- /dev/null
+++ b/src/xsf/desmume/matrix.cc
@@ -0,0 +1,257 @@
+/*
+ Copyright (C) 2006-2007 shash
+
+ This file is part of DeSmuME
+
+ DeSmuME 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.
+
+ DeSmuME 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 DeSmuME; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "matrix.h"
+
+void MatrixInit (float *matrix)
+{
+ memset (matrix, 0, sizeof(float)*16);
+
+ matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.f;
+}
+
+void MatrixMultVec4x4 (float *matrix, float *vecPtr)
+{
+ float x = vecPtr[0];
+ float y = vecPtr[1];
+ float z = vecPtr[2];
+
+ vecPtr[0] = x * matrix[0] + y * matrix[4] + z * matrix[ 8] + matrix[12];
+ vecPtr[1] = x * matrix[1] + y * matrix[5] + z * matrix[ 9] + matrix[13];
+ vecPtr[2] = x * matrix[2] + y * matrix[6] + z * matrix[10] + matrix[14];
+}
+
+void MatrixMultVec3x3 (float *matrix, float *vecPtr)
+{
+ float x = vecPtr[0];
+ float y = vecPtr[1];
+ float z = vecPtr[2];
+
+ vecPtr[0] = x * matrix[0] + y * matrix[4] + z * matrix[ 8];
+ vecPtr[1] = x * matrix[1] + y * matrix[5] + z * matrix[ 9];
+ vecPtr[2] = x * matrix[2] + y * matrix[6] + z * matrix[10];
+}
+
+void MatrixIdentity (float *matrix)
+{
+ memset (matrix, 0, sizeof(float)*16);
+
+ matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.f;
+}
+
+void MatrixMultiply (float *matrix, float *rightMatrix)
+{
+ float tmpMatrix[16];
+
+ tmpMatrix[0] = (matrix[0]*rightMatrix[0])+(matrix[4]*rightMatrix[1])+(matrix[8]*rightMatrix[2])+(matrix[12]*rightMatrix[3]);
+ tmpMatrix[1] = (matrix[1]*rightMatrix[0])+(matrix[5]*rightMatrix[1])+(matrix[9]*rightMatrix[2])+(matrix[13]*rightMatrix[3]);
+ tmpMatrix[2] = (matrix[2]*rightMatrix[0])+(matrix[6]*rightMatrix[1])+(matrix[10]*rightMatrix[2])+(matrix[14]*rightMatrix[3]);
+ tmpMatrix[3] = (matrix[3]*rightMatrix[0])+(matrix[7]*rightMatrix[1])+(matrix[11]*rightMatrix[2])+(matrix[15]*rightMatrix[3]);
+
+ tmpMatrix[4] = (matrix[0]*rightMatrix[4])+(matrix[4]*rightMatrix[5])+(matrix[8]*rightMatrix[6])+(matrix[12]*rightMatrix[7]);
+ tmpMatrix[5] = (matrix[1]*rightMatrix[4])+(matrix[5]*rightMatrix[5])+(matrix[9]*rightMatrix[6])+(matrix[13]*rightMatrix[7]);
+ tmpMatrix[6] = (matrix[2]*rightMatrix[4])+(matrix[6]*rightMatrix[5])+(matrix[10]*rightMatrix[6])+(matrix[14]*rightMatrix[7]);
+ tmpMatrix[7] = (matrix[3]*rightMatrix[4])+(matrix[7]*rightMatrix[5])+(matrix[11]*rightMatrix[6])+(matrix[15]*rightMatrix[7]);
+
+ tmpMatrix[8] = (matrix[0]*rightMatrix[8])+(matrix[4]*rightMatrix[9])+(matrix[8]*rightMatrix[10])+(matrix[12]*rightMatrix[11]);
+ tmpMatrix[9] = (matrix[1]*rightMatrix[8])+(matrix[5]*rightMatrix[9])+(matrix[9]*rightMatrix[10])+(matrix[13]*rightMatrix[11]);
+ tmpMatrix[10] = (matrix[2]*rightMatrix[8])+(matrix[6]*rightMatrix[9])+(matrix[10]*rightMatrix[10])+(matrix[14]*rightMatrix[11]);
+ tmpMatrix[11] = (matrix[3]*rightMatrix[8])+(matrix[7]*rightMatrix[9])+(matrix[11]*rightMatrix[10])+(matrix[15]*rightMatrix[11]);
+
+ tmpMatrix[12] = (matrix[0]*rightMatrix[12])+(matrix[4]*rightMatrix[13])+(matrix[8]*rightMatrix[14])+(matrix[12]*rightMatrix[15]);
+ tmpMatrix[13] = (matrix[1]*rightMatrix[12])+(matrix[5]*rightMatrix[13])+(matrix[9]*rightMatrix[14])+(matrix[13]*rightMatrix[15]);
+ tmpMatrix[14] = (matrix[2]*rightMatrix[12])+(matrix[6]*rightMatrix[13])+(matrix[10]*rightMatrix[14])+(matrix[14]*rightMatrix[15]);
+ tmpMatrix[15] = (matrix[3]*rightMatrix[12])+(matrix[7]*rightMatrix[13])+(matrix[11]*rightMatrix[14])+(matrix[15]*rightMatrix[15]);
+
+ memcpy (matrix, tmpMatrix, sizeof(float)*16);
+}
+/*
+void MatrixMulti (float* right)
+{
+ float tmpMatrix[16];
+
+ tmpMatrix[0] = (matrix[0]*right[0])+(matrix[4]*right[1])+(matrix[8]*right[2])+(matrix[12]*right[3]);
+ tmpMatrix[1] = (matrix[1]*right[0])+(matrix[5]*right[1])+(matrix[9]*right[2])+(matrix[13]*right[3]);
+ tmpMatrix[2] = (matrix[2]*right[0])+(matrix[6]*right[1])+(matrix[10]*right[2])+(matrix[14]*right[3]);
+ tmpMatrix[3] = (matrix[3]*right[0])+(matrix[7]*right[1])+(matrix[11]*right[2])+(matrix[15]*right[3]);
+
+ tmpMatrix[4] = (matrix[0]*right[4])+(matrix[4]*right[5])+(matrix[8]*right[6])+(matrix[12]*right[7]);
+ tmpMatrix[5] = (matrix[1]*right[4])+(matrix[5]*right[5])+(matrix[9]*right[6])+(matrix[13]*right[7]);
+ tmpMatrix[6] = (matrix[2]*right[4])+(matrix[6]*right[5])+(matrix[10]*right[6])+(matrix[14]*right[7]);
+ tmpMatrix[7] = (matrix[3]*right[4])+(matrix[7]*right[5])+(matrix[11]*right[6])+(matrix[15]*right[7]);
+
+ tmpMatrix[8] = (matrix[0]*right[8])+(matrix[4]*right[9])+(matrix[8]*right[10])+(matrix[12]*right[11]);
+ tmpMatrix[9] = (matrix[1]*right[8])+(matrix[5]*right[9])+(matrix[9]*right[10])+(matrix[13]*right[11]);
+ tmpMatrix[10] = (matrix[2]*right[8])+(matrix[6]*right[9])+(matrix[10]*right[10])+(matrix[14]*right[11]);
+ tmpMatrix[11] = (matrix[3]*right[8])+(matrix[7]*right[9])+(matrix[11]*right[10])+(matrix[15]*right[11]);
+
+ tmpMatrix[12] = (matrix[0]*right[12])+(matrix[4]*right[13])+(matrix[8]*right[14])+(matrix[12]*right[15]);
+ tmpMatrix[13] = (matrix[1]*right[12])+(matrix[5]*right[13])+(matrix[9]*right[14])+(matrix[13]*right[15]);
+ tmpMatrix[14] = (matrix[2]*right[12])+(matrix[6]*right[13])+(matrix[10]*right[14])+(matrix[14]*right[15]);
+ tmpMatrix[15] = (matrix[3]*right[12])+(matrix[7]*right[13])+(matrix[11]*right[14])+(matrix[15]*right[15]);
+
+ memcpy (matrix, tmpMatrix, sizeof(float)*16);
+}
+
+
+float* Matrix::Get (void)
+{
+ return matrix;
+}
+
+float MatrixGet (float *matrix, int index)
+{
+ return matrix[index];
+}
+*/
+
+float MatrixGetMultipliedIndex (int index, float *matrix, float *rightMatrix)
+{
+ int iMod = index%4, iDiv = (index>>2)<<2;
+
+ return (matrix[iMod ]*rightMatrix[iDiv ])+(matrix[iMod+ 4]*rightMatrix[iDiv+1])+
+ (matrix[iMod+8]*rightMatrix[iDiv+2])+(matrix[iMod+12]*rightMatrix[iDiv+3]);
+}
+
+void MatrixSet (float *matrix, int x, int y, float value)
+{
+ matrix [x+(y<<2)] = value;
+}
+/*
+void Matrix::Set (int pos, float value)
+{
+ matrix [pos] = value;
+}
+*/
+void MatrixCopy (float *matrixDST, float *matrixSRC)
+{
+ memcpy (matrixDST, matrixSRC, sizeof(float)*16);
+}
+
+void MatrixTranslate (float *matrix, float *ptr)
+{
+ matrix[12] += (matrix[0]*ptr[0])+(matrix[4]*ptr[1])+(matrix[ 8]*ptr[2]);
+ matrix[13] += (matrix[1]*ptr[0])+(matrix[5]*ptr[1])+(matrix[ 9]*ptr[2]);
+ matrix[14] += (matrix[2]*ptr[0])+(matrix[6]*ptr[1])+(matrix[10]*ptr[2]);
+ matrix[15] += (matrix[3]*ptr[0])+(matrix[7]*ptr[1])+(matrix[11]*ptr[2]);
+}
+
+void MatrixScale (float *matrix, float *ptr)
+{
+ matrix[0] *= ptr[0];
+ matrix[1] *= ptr[0];
+ matrix[2] *= ptr[0];
+ matrix[3] *= ptr[0];
+
+ matrix[4] *= ptr[1];
+ matrix[5] *= ptr[1];
+ matrix[6] *= ptr[1];
+ matrix[7] *= ptr[1];
+
+ matrix[8] *= ptr[2];
+ matrix[9] *= ptr[2];
+ matrix[10] *= ptr[2];
+ matrix[11] *= ptr[2];
+}
+/*
+void Matrix::Set (float a11, float a21, float a31, float a41,
+ float a12, float a22, float a32, float a42,
+ float a13, float a23, float a33, float a43,
+ float a14, float a24, float a34, float a44)
+{
+}
+*/
+
+
+//-----------------------------------------
+
+void MatrixStackInit (MatrixStack *stack)
+{
+ stack->matrix = nullptr;
+ stack->position = 0;
+ stack->size = 0;
+}
+
+void MatrixStackSetMaxSize (MatrixStack *stack, int size)
+{
+ int i = 0;
+
+ stack->size = size;
+
+ if (stack->matrix == nullptr)
+ {
+ stack->matrix = (float*) malloc (stack->size*16*sizeof(float));
+ }
+ else
+ {
+ free (stack->matrix);
+ stack->matrix = (float*) malloc (stack->size*16*sizeof(float));
+ }
+
+ for (i = 0; i < stack->size; i++)
+ {
+ MatrixInit (&stack->matrix[i*16]);
+ }
+
+ stack->size--;
+}
+
+
+void MatrixStackSetStackPosition (MatrixStack *stack, int pos)
+{
+ stack->position += pos;
+
+ if (stack->position < 0)
+ stack->position = 0;
+ else if (stack->position > stack->size)
+ stack->position = stack->size;
+}
+
+void MatrixStackPushMatrix (MatrixStack *stack, float *ptr)
+{
+ MatrixCopy (&stack->matrix[stack->position*16], ptr);
+
+ MatrixStackSetStackPosition (stack, 1);
+}
+
+float * MatrixStackPopMatrix (MatrixStack *stack, int size)
+{
+ MatrixStackSetStackPosition(stack, -size);
+
+ return &stack->matrix[stack->position*16];
+}
+
+float * MatrixStackGetPos (MatrixStack *stack, int pos)
+{
+ return &stack->matrix[pos*16];
+}
+
+float * MatrixStackGet (MatrixStack *stack)
+{
+ return &stack->matrix[stack->position*16];
+}
+
+void MatrixStackLoadMatrix (MatrixStack *stack, int pos, float *ptr)
+{
+ MatrixCopy (&stack->matrix[pos*16], ptr);
+}
diff --git a/src/xsf/desmume/matrix.h b/src/xsf/desmume/matrix.h
index 05c0786e2b94..d9aa8cb1d8ff 100644
--- a/src/xsf/desmume/matrix.h
+++ b/src/xsf/desmume/matrix.h
@@ -15,7 +15,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MATRIX_H
diff --git a/src/xsf/desmume/mc.c b/src/xsf/desmume/mc.c
deleted file mode 100644
index 756a92c8d9de..000000000000
--- a/src/xsf/desmume/mc.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* Copyright (C) 2006 thoduv
- Copyright (C) 2006-2007 Theo Berkau
-
- This file is part of DeSmuME
-
- DeSmuME 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.
-
- DeSmuME 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 DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <stdlib.h>
-#include "debug.h"
-#include "types.h"
-#include "mc.h"
-
-#define FW_CMD_READ 0x3
-#define FW_CMD_WRITEDISABLE 0x4
-#define FW_CMD_READSTATUS 0x5
-#define FW_CMD_WRITEENABLE 0x6
-#define FW_CMD_PAGEWRITE 0xA
-
-#define BM_CMD_AUTODETECT 0xFF
-#define BM_CMD_WRITESTATUS 0x1
-#define BM_CMD_WRITELOW 0x2
-#define BM_CMD_READLOW 0x3
-#define BM_CMD_WRITEDISABLE 0x4
-#define BM_CMD_READSTATUS 0x5
-#define BM_CMD_WRITEENABLE 0x6
-#define BM_CMD_WRITEHIGH 0xA
-#define BM_CMD_READHIGH 0xB
-
-/* FLASH*/
-#define COMM_PAGE_WRITE 0x0A
-#define COMM_PAGE_ERASE 0xDB
-#define COMM_SECTOR_ERASE 0xD8
-#define COMM_CHIP_ERASE 0xC7
-#define CARDFLASH_READ_BYTES_FAST 0x0B /* Not used*/
-#define CARDFLASH_DEEP_POWDOWN 0xB9 /* Not used*/
-#define CARDFLASH_WAKEUP 0xAB /* Not used*/
-
-void mc_init(memory_chip_t *mc, int type)
-{
- mc->com = 0;
- mc->addr = 0;
- mc->addr_shift = 0;
- mc->data = NULL;
- mc->size = 0;
- mc->write_enable = FALSE;
- mc->writeable_buffer = FALSE;
- mc->type = type;
- mc->autodetectsize = 0;
-
- switch(mc->type)
- {
- case MC_TYPE_EEPROM1:
- mc->addr_size = 1;
- break;
- case MC_TYPE_EEPROM2:
- case MC_TYPE_FRAM:
- mc->addr_size = 2;
- break;
- case MC_TYPE_FLASH:
- mc->addr_size = 3;
- break;
- default: break;
- }
-}
-
-u8 *mc_alloc(memory_chip_t *mc, u32 size)
-{
- u8 *buffer;
- buffer = malloc(size);
-
- mc->data = buffer;
- if(!buffer) { return NULL; }
- mc->size = size;
- mc->writeable_buffer = TRUE;
-
- return buffer;
-}
-
-void mc_free(memory_chip_t *mc)
-{
- if(mc->data)
- {
- free(mc->data);
- mc->data = 0;
- }
- mc_init(mc, 0);
-}
-
-void mc_realloc(memory_chip_t *mc, int type, u32 size)
-{
- mc_free(mc);
- mc_init(mc, type);
- mc_alloc(mc, size);
-}
-
-
-void mc_reset_com(memory_chip_t *mc)
-{
-}
-u8 fw_transfer(memory_chip_t *mc, u8 data)
-{
- return 0;
-}
-u8 bm_transfer(memory_chip_t *mc, u8 data)
-{
- return 0;
-}
-
diff --git a/src/xsf/desmume/mc.cc b/src/xsf/desmume/mc.cc
new file mode 100644
index 000000000000..4f7dd706644f
--- /dev/null
+++ b/src/xsf/desmume/mc.cc
@@ -0,0 +1,121 @@
+/* Copyright (C) 2006 thoduv
+ Copyright (C) 2006-2007 Theo Berkau
+
+ This file is part of DeSmuME
+
+ DeSmuME 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.
+
+ DeSmuME 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 DeSmuME; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <stdlib.h>
+#include "debug.h"
+#include "types.h"
+#include "mc.h"
+
+#define FW_CMD_READ 0x3
+#define FW_CMD_WRITEDISABLE 0x4
+#define FW_CMD_READSTATUS 0x5
+#define FW_CMD_WRITEENABLE 0x6
+#define FW_CMD_PAGEWRITE 0xA
+
+#define BM_CMD_AUTODETECT 0xFF
+#define BM_CMD_WRITESTATUS 0x1
+#define BM_CMD_WRITELOW 0x2
+#define BM_CMD_READLOW 0x3
+#define BM_CMD_WRITEDISABLE 0x4
+#define BM_CMD_READSTATUS 0x5
+#define BM_CMD_WRITEENABLE 0x6
+#define BM_CMD_WRITEHIGH 0xA
+#define BM_CMD_READHIGH 0xB
+
+/* FLASH*/
+#define COMM_PAGE_WRITE 0x0A
+#define COMM_PAGE_ERASE 0xDB
+#define COMM_SECTOR_ERASE 0xD8
+#define COMM_CHIP_ERASE 0xC7
+#define CARDFLASH_READ_BYTES_FAST 0x0B /* Not used*/
+#define CARDFLASH_DEEP_POWDOWN 0xB9 /* Not used*/
+#define CARDFLASH_WAKEUP 0xAB /* Not used*/
+
+void mc_init(memory_chip_t *mc, int type)
+{
+ mc->com = 0;
+ mc->addr = 0;
+ mc->addr_shift = 0;
+ mc->data = nullptr;
+ mc->size = 0;
+ mc->write_enable = false;
+ mc->writeable_buffer = false;
+ mc->type = type;
+ mc->autodetectsize = 0;
+
+ switch(mc->type)
+ {
+ case MC_TYPE_EEPROM1:
+ mc->addr_size = 1;
+ break;
+ case MC_TYPE_EEPROM2:
+ case MC_TYPE_FRAM:
+ mc->addr_size = 2;
+ break;
+ case MC_TYPE_FLASH:
+ mc->addr_size = 3;
+ break;
+ default: break;
+ }
+}
+
+u8 *mc_alloc(memory_chip_t *mc, u32 size)
+{
+ u8 *buffer;
+ buffer = (u8 *) malloc(size);
+
+ mc->data = buffer;
+ if(!buffer) { return nullptr; }
+ mc->size = size;
+ mc->writeable_buffer = true;
+
+ return buffer;
+}
+
+void mc_free(memory_chip_t *mc)
+{
+ if(mc->data)
+ {
+ free(mc->data);
+ mc->data = 0;
+ }
+ mc_init(mc, 0);
+}
+
+void mc_realloc(memory_chip_t *mc, int type, u32 size)
+{
+ mc_free(mc);
+ mc_init(mc, type);
+ mc_alloc(mc, size);
+}
+
+
+void mc_reset_com(memory_chip_t *mc)
+{
+}
+u8 fw_transfer(memory_chip_t *mc, u8 data)
+{
+ return 0;
+}
+u8 bm_transfer(memory_chip_t *mc, u8 data)
+{
+ return 0;
+}
+
diff --git a/src/xsf/desmume/mc.h b/src/xsf/desmume/mc.h
index dd567c9d0280..3e9f4e298ee2 100644
--- a/src/xsf/desmume/mc.h
+++ b/src/xsf/desmume/mc.h
@@ -15,16 +15,12 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __FW_H__
#define __FW_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include <stdio.h>
#include "types.h"
@@ -51,9 +47,9 @@ typedef struct
u32 addr; /* current address for reading/writing */
u8 addr_shift; /* shift for address (since addresses are transfered by 3 bytes units) */
u8 addr_size; /* size of addr when writing/reading */
-
+
BOOL write_enable; /* is write enabled ? */
-
+
u8 *data; /* memory data */
u32 size; /* memory size */
BOOL writeable_buffer; /* is "data" writeable ? */
@@ -77,9 +73,5 @@ void mc_reset_com(memory_chip_t *mc); /* reset communication with mc */
u8 fw_transfer(memory_chip_t *mc, u8 data); /* transfer to, then receive data from firmware */
u8 bm_transfer(memory_chip_t *mc, u8 data); /* transfer to, then receive data from backup memory */
-#ifdef __cplusplus
-}
-#endif
-
#endif /*__FW_H__*/
diff --git a/src/xsf/desmume/mem.h b/src/xsf/desmume/mem.h
index 72060f1f5531..5d48c2b9d50c 100644
--- a/src/xsf/desmume/mem.h
+++ b/src/xsf/desmume/mem.h
@@ -15,7 +15,7 @@
You should have received a copy of the GNU General Public License
along with Yabause; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MEM_H
diff --git a/src/xsf/desmume/registers.h b/src/xsf/desmume/registers.h
index f9060214d916..3371b4c257ff 100644
--- a/src/xsf/desmume/registers.h
+++ b/src/xsf/desmume/registers.h
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef REGISTERS_H
diff --git a/src/xsf/desmume/thumb_instructions.c b/src/xsf/desmume/thumb_instructions.c
deleted file mode 100644
index fbe5e31c8dbe..000000000000
--- a/src/xsf/desmume/thumb_instructions.c
+++ /dev/null
@@ -1,944 +0,0 @@
-/*
- Copyright (C) 2006 yopyop
- yopyop156 at ifrance.com
- yopyop156.ifrance.com
-
- Code added on 18/08/2006 by shash
- - Missing missaligned addresses correction
- (reference in http://nocash.emubase.de/gbatek.htm#cpumemoryalignments)
-
- This file is part of DeSmuME
-
- DeSmuME 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.
-
- DeSmuME 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 DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include "bios.h"
-#include "debug.h"
-#include "MMU.h"
-
-#define REG_NUM(i, n) (((i)>>n)&0x7)
-
-extern BOOL execute;
-
-// Use this macros for reading/writing, so the GDB stub isn't broken
-#ifdef GDB_STUB
- #define READ32(a,b) cpu->mem_if->read32(a,b)
- #define WRITE32(a,b,c) cpu->mem_if->write32(a,b,c)
- #define READ16(a,b) cpu->mem_if->read16(a,b)
- #define WRITE16(a,b,c) cpu->mem_if->write16(a,b,c)
- #define READ8(a,b) cpu->mem_if->read8(a,b)
- #define WRITE8(a,b,c) cpu->mem_if->write8(a,b,c)
-#else
- #define READ32(a,b) MMU_read32(cpu->proc_ID, b)
- #define WRITE32(a,b,c) MMU_write32(cpu->proc_ID,b,c)
- #define READ16(a,b) MMU_read16(cpu->proc_ID, b)
- #define WRITE16(a,b,c) MMU_write16(cpu->proc_ID,b,c)
- #define READ8(a,b) MMU_read8(cpu->proc_ID, b)
- #define WRITE8(a,b,c) MMU_write8(cpu->proc_ID,b,c)
-#endif
-
-static u32 FASTCALL OP_UND_THUMB(armcpu_t *cpu)
-{
- execute = FALSE;
- return 1;
-}
-
-static u32 FASTCALL OP_LSL_0(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)];
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 2;
-}
-
-static u32 FASTCALL OP_LSL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = (i>>6) & 0x1F;
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], 32-v);
- cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] << v);
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 2;
-}
-
-static u32 FASTCALL OP_LSR_0(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- // cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]);
- cpu->R[REG_NUM(i, 0)] = 0;
- cpu->CPSR.bits.N = 0;
- cpu->CPSR.bits.Z = 1;
-
- return 2;
-}
-
-static u32 FASTCALL OP_LSR(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = (i>>6) & 0x1F;
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
- cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] >> v);
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 2;
-}
-
-static u32 FASTCALL OP_ASR_0(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]);
- cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 3)])*0xFFFFFFFF;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 2;
-}
-
-static u32 FASTCALL OP_ASR(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = (i>>6) & 0x1F;
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], v-1);
- cpu->R[REG_NUM(i, 0)] = (((s32)cpu->R[REG_NUM(i, 3)]) >> v);
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 2;
-}
-
-static u32 FASTCALL OP_ADD_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 a = cpu->R[REG_NUM(i, 3)];
- u32 b = cpu->R[REG_NUM(i, 6)];
- cpu->R[REG_NUM(i, 0)] = a + b;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
-
- return 3;
-}
-
-static u32 FASTCALL OP_SUB_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 a = cpu->R[REG_NUM(i, 3)];
- u32 b = cpu->R[REG_NUM(i, 6)];
- cpu->R[REG_NUM(i, 0)] = a - b;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
-
- return 3;
-}
-
-static u32 FASTCALL OP_ADD_IMM3(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 a = cpu->R[REG_NUM(i, 3)];
- cpu->R[REG_NUM(i, 0)] = a + REG_NUM(i, 6);
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
-
- return 2;
-}
-
-static u32 FASTCALL OP_SUB_IMM3(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 a = cpu->R[REG_NUM(i, 3)];
- cpu->R[REG_NUM(i, 0)] = a - REG_NUM(i, 6);
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
-
- return 2;
-}
-
-static u32 FASTCALL OP_MOV_IMM8(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[REG_NUM(i, 8)] = i & 0xFF;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 8)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 8)] == 0;
-
- return 2;
-}
-
-static u32 FASTCALL OP_CMP_IMM8(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF);
- cpu->CPSR.bits.N = BIT31(tmp);
- cpu->CPSR.bits.Z = tmp == 0;
- cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
-
- return 2;
-}
-
-static u32 FASTCALL OP_ADD_IMM8(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 tmp = cpu->R[REG_NUM(i, 8)] + (i & 0xFF);
- cpu->CPSR.bits.N = BIT31(tmp);
- cpu->CPSR.bits.Z = tmp == 0;
- cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
- cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
- cpu->R[REG_NUM(i, 8)] = tmp;
-
- return 2;
-}
-
-static u32 FASTCALL OP_SUB_IMM8(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF);
- cpu->CPSR.bits.N = BIT31(tmp);
- cpu->CPSR.bits.Z = tmp == 0;
- cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
- cpu->R[REG_NUM(i, 8)] = tmp;
-
- return 2;
-}
-
-static u32 FASTCALL OP_AND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[REG_NUM(i, 0)] &= cpu->R[REG_NUM(i, 3)];
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 3;
-}
-
-static u32 FASTCALL OP_EOR(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[REG_NUM(i, 0)] ^= cpu->R[REG_NUM(i, 3)];
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 3;
-}
-
-static u32 FASTCALL OP_LSL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
-
- if(!v)
- {
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- return 3;
- }
- if(v<32)
- {
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], 32-v);
- cpu->R[REG_NUM(i, 0)] <<= v;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- return 3;
- }
- if(v==32)
- cpu->CPSR.bits.C = BIT0(cpu->R[REG_NUM(i, 0)]);
- else
- cpu->CPSR.bits.C = 0;
- cpu->R[REG_NUM(i, 0)] = 0;
- cpu->CPSR.bits.N = 0;
- cpu->CPSR.bits.Z = 1;
-
- return 3;
-}
-
-static u32 FASTCALL OP_LSR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
-
- if(!v)
- {
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- return 3;
- }
- if(v<32)
- {
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
- cpu->R[REG_NUM(i, 0)] >>= v;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- return 3;
- }
- if(v==32)
- cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
- else
- cpu->CPSR.bits.C = 0;
- cpu->R[REG_NUM(i, 0)] = 0;
- cpu->CPSR.bits.N = 0;
- cpu->CPSR.bits.Z = 1;
-
- return 3;
-}
-
-static u32 FASTCALL OP_ASR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
-
- if(!v)
- {
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- return 3;
- }
- if(v<32)
- {
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
- cpu->R[REG_NUM(i, 0)] = (u32)(((s32)cpu->R[REG_NUM(i, 0)]) >> v);
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- return 3;
- }
-
- cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 0)])*0xFFFFFFFF;
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 3;
-}
-
-static u32 FASTCALL OP_ADC_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 a = cpu->R[REG_NUM(i, 0)];
- u32 b = cpu->R[REG_NUM(i, 3)];
- u32 tmp = b + cpu->CPSR.bits.C;
- u32 res = a + tmp;
-
- cpu->R[REG_NUM(i, 0)] = res;
-
- cpu->CPSR.bits.N = BIT31(res);
- cpu->CPSR.bits.Z = res == 0;
-
- cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(b, cpu->CPSR.bits.C, tmp) | UNSIGNED_OVERFLOW(tmp, a, res);
- cpu->CPSR.bits.V = SIGNED_OVERFLOW(b, cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(tmp, a, res);
-
- return 3;
-}
-
-static u32 FASTCALL OP_SBC_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 a = cpu->R[REG_NUM(i, 0)];
- u32 b = cpu->R[REG_NUM(i, 3)];
- u32 tmp = a - (!cpu->CPSR.bits.C);
- u32 res = tmp - b;
- cpu->R[REG_NUM(i, 0)] = res;
-
- cpu->CPSR.bits.N = BIT31(res);
- cpu->CPSR.bits.Z = res == 0;
-
- cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(a, !cpu->CPSR.bits.C, tmp)) & (!UNSIGNED_OVERFLOW(tmp, b, res));
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, !cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(tmp, b, res);
-
- return 3;
-}
-
-static u32 FASTCALL OP_ROR_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
-
- if(v == 0)
- {
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- return 3;
- }
- v &= 0xF;
- if(v == 0)
- {
- cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- return 3;
- }
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
- cpu->R[REG_NUM(i, 0)] = ROR(cpu->R[REG_NUM(i, 0)], v);
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 3;
-}
-
-static u32 FASTCALL OP_TST(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 tmp = cpu->R[REG_NUM(i, 0)] & cpu->R[REG_NUM(i, 3)];
- cpu->CPSR.bits.N = BIT31(tmp);
- cpu->CPSR.bits.Z = tmp == 0;
-
- return 3;
-}
-
-static u32 FASTCALL OP_NEG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 a = cpu->R[REG_NUM(i, 3)];
- cpu->R[REG_NUM(i, 0)] = -((signed int)a);
-
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
- cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(0, a, cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(0, a, cpu->R[REG_NUM(i, 0)]);
-
- return 3;
-}
-
-static u32 FASTCALL OP_CMP(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 tmp = cpu->R[REG_NUM(i, 0)] -cpu->R[REG_NUM(i, 3)];
-
- cpu->CPSR.bits.N = BIT31(tmp);
- cpu->CPSR.bits.Z = tmp == 0;
- cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
-
- return 3;
-}
-
-static u32 FASTCALL OP_CMN(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 tmp = cpu->R[REG_NUM(i, 0)] + cpu->R[REG_NUM(i, 3)];
-
- //execute = FALSE;
- //log::ajouter("OP_CMN THUMB");
- cpu->CPSR.bits.N = BIT31(tmp);
- cpu->CPSR.bits.Z = tmp == 0;
- cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
- cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
-
- return 3;
-}
-
-static u32 FASTCALL OP_ORR(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[REG_NUM(i, 0)] |= cpu->R[REG_NUM(i, 3)];
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 3;
-}
-
-static u32 FASTCALL OP_MUL_REG(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[REG_NUM(i, 0)] *= cpu->R[REG_NUM(i, 3)];
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 3;
-}
-
-static u32 FASTCALL OP_BIC(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[REG_NUM(i, 0)] &= (~cpu->R[REG_NUM(i, 3)]);
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 3;
-}
-
-static u32 FASTCALL OP_MVN(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[REG_NUM(i, 0)] = (~cpu->R[REG_NUM(i, 3)]);
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
-
- return 3;
-}
-
-static u32 FASTCALL OP_ADD_SPE(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 Rd = (i&7) | ((i>>4)&8);
- cpu->R[Rd] += cpu->R[REG_POS(i, 3)];
-
- if(Rd==15)
- cpu->next_instruction = cpu->R[15];
-
- return 2;
-}
-
-static u32 FASTCALL OP_CMP_SPE(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 Rn = (i&7) | ((i>>4)&8);
- u32 tmp = cpu->R[Rn] -cpu->R[REG_POS(i, 3)];
-
- cpu->CPSR.bits.N = BIT31(tmp);
- cpu->CPSR.bits.Z = tmp == 0;
- cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp);
- cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp);
-
- return 3;
-}
-
-static u32 FASTCALL OP_MOV_SPE(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 Rd = (i&7) | ((i>>4)&8);
- cpu->R[Rd] = cpu->R[REG_POS(i, 3)];
-
- if(Rd==15)
- cpu->next_instruction = cpu->R[15];
-
- return 2;
-}
-
-static u32 FASTCALL OP_BX_THUMB(armcpu_t *cpu)
-{
- u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)];
-
- cpu->CPSR.bits.T = BIT0(Rm);
- cpu->R[15] = (Rm & 0xFFFFFFFE);
- cpu->next_instruction = cpu->R[15];
-
- return 3;
-}
-
-static u32 FASTCALL OP_BLX_THUMB(armcpu_t *cpu)
-{
- u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)];
-
- cpu->CPSR.bits.T = BIT0(Rm);
- cpu->R[14] = cpu->next_instruction | 1;
- cpu->R[15] = (Rm & 0xFFFFFFFE);
- cpu->next_instruction = cpu->R[15];
-
- return 3;
-}
-
-static u32 FASTCALL OP_LDR_PCREL(armcpu_t *cpu)
-{
- u32 adr = (cpu->R[15]&0xFFFFFFFC) + ((cpu->instruction&0xFF)<<2);
-
- cpu->R[REG_NUM(cpu->instruction, 8)] = READ32(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 6)] + cpu->R[REG_NUM(i, 3)];
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]);
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
- WRITE16(cpu->mem_if->data, adr, ((u16)cpu->R[REG_NUM(i, 0)]));
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
- WRITE8(cpu->mem_if->data, adr, ((u8)cpu->R[REG_NUM(i, 0)]));
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSB_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
- cpu->R[REG_NUM(i, 0)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = (cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]);
- u32 tempValue = READ32(cpu->mem_if->data, adr&0xFFFFFFFC);
-
- adr = (adr&3)*8;
- tempValue = (tempValue>>adr) | (tempValue<<(32-adr));
- cpu->R[REG_NUM(i, 0)] = tempValue;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
- cpu->R[REG_NUM(i, 0)] = (u32)READ16(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
- cpu->R[REG_NUM(i, 0)] = (u32)READ8(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRSH_REG_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
- cpu->R[REG_NUM(i, 0)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C);
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]);
-
- return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C);
- u32 tempValue = READ32(cpu->mem_if->data, adr&0xFFFFFFFC);
- adr = (adr&3)*8;
- tempValue = (tempValue>>adr) | (tempValue<<(32-adr));
- cpu->R[REG_NUM(i, 0)] = tempValue;
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRB_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F);
- WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_NUM(i, 0)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRB_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F);
- cpu->R[REG_NUM(i, 0)] = READ8(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STRH_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E);
- WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_NUM(i, 0)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDRH_IMM_OFF(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E);
- cpu->R[REG_NUM(i, 0)] = READ16(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_STR_SPREL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[13] + ((i&0xFF)<<2);
- WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 8)]);
-
- return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_LDR_SPREL(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[13] + ((i&0xFF)<<2);
- cpu->R[REG_NUM(i, 8)] = READ32(cpu->mem_if->data, adr);
-
- return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
-}
-
-static u32 FASTCALL OP_ADD_2PC(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[REG_NUM(i, 8)] = (cpu->R[15]&0xFFFFFFFC) + ((i&0xFF)<<2);
-
- return 5;
-}
-
-static u32 FASTCALL OP_ADD_2SP(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[REG_NUM(i, 8)] = cpu->R[13] + ((i&0xFF)<<2);
-
- return 2;
-}
-
-static u32 FASTCALL OP_ADJUST_P_SP(armcpu_t *cpu)
-{
- cpu->R[13] += ((cpu->instruction&0x7F)<<2);
-
- return 1;
-}
-
-static u32 FASTCALL OP_ADJUST_M_SP(armcpu_t *cpu)
-{
- cpu->R[13] -= ((cpu->instruction&0x7F)<<2);
-
- return 1;
-}
-
-static u32 FASTCALL OP_PUSH(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[13] - 4;
- u32 c = 0, j;
-
- for(j = 0; j<8; ++j)
- if(BIT_N(i, 7-j))
- {
- WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- adr -= 4;
- }
- cpu->R[13] = adr + 4;
-
- return c + 3;
-}
-
-static u32 FASTCALL OP_PUSH_LR(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[13] - 4;
- u32 c = 0, j;
-
- WRITE32(cpu->mem_if->data, adr, cpu->R[14]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- adr -= 4;
-
- for(j = 0; j<8; ++j)
- if(BIT_N(i, 7-j))
- {
- WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- adr -= 4;
- }
- cpu->R[13] = adr + 4;
-
- return c + 4;
-}
-
-static u32 FASTCALL OP_POP(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[13];
- u32 c = 0, j;
-
- for(j = 0; j<8; ++j)
- if(BIT_N(i, j))
- {
- cpu->R[j] = READ32(cpu->mem_if->data, adr);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- adr += 4;
- }
- cpu->R[13] = adr;
-
- return c + 2;
-}
-
-static u32 FASTCALL OP_POP_PC(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[13];
- u32 c = 0, j;
- u32 v;
-
- for(j = 0; j<8; ++j)
- if(BIT_N(i, j))
- {
- cpu->R[j] = READ32(cpu->mem_if->data, adr);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- adr += 4;
- }
-
- v = READ32(cpu->mem_if->data, adr);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- cpu->R[15] = v & 0xFFFFFFFE;
- cpu->next_instruction = v & 0xFFFFFFFE;
- if(cpu->proc_ID==0)
- cpu->CPSR.bits.T = BIT0(v);
- adr += 4;
-
- cpu->R[13] = adr;
- return c + 5;
-}
-
-static u32 FASTCALL OP_BKPT_THUMB(armcpu_t *cpu)
-{
- return 1;
-}
-
-static u32 FASTCALL OP_STMIA_THUMB(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 8)];
- u32 c = 0, j;
-
- for(j = 0; j<8; ++j)
- if(BIT_N(i, j))
- {
- WRITE32(cpu->mem_if->data, adr, cpu->R[j]);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- adr += 4;
- }
- cpu->R[REG_NUM(i, 8)] = adr;
- return c + 2;
-}
-
-static u32 FASTCALL OP_LDMIA_THUMB(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- u32 adr = cpu->R[REG_NUM(i, 8)];
- u32 c = 0, j;
-
- for(j = 0; j<8; ++j)
- if(BIT_N(i, j))
- {
- cpu->R[j] = READ32(cpu->mem_if->data, adr);
- c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
- adr += 4;
- }
- cpu->R[REG_NUM(i, 8)] = adr;
- return c + 3;
-}
-
-static u32 FASTCALL OP_B_COND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- if(!TEST_COND((i>>8)&0xF, 0, cpu->CPSR))
- return 1;
-
- cpu->R[15] += ((s32)((s8)(i&0xFF)))<<1;
- cpu->next_instruction = cpu->R[15];
- return 3;
-}
-
-static u32 FASTCALL OP_SWI_THUMB(armcpu_t *cpu)
-{
- if (((cpu->intVector != 0) ^ (cpu->proc_ID == ARMCPU_ARM9)))
- {
- /* we use an irq thats not in the irq tab, as
- it was replaced duie to a changed intVector */
- Status_Reg tmp = cpu->CPSR;
- armcpu_switchMode(cpu, SVC); /* enter svc mode */
- cpu->R[14] = cpu->R[15] - 4; /* jump to swi Vector */
- cpu->SPSR = tmp; /* save old CPSR as new SPSR */
- cpu->CPSR.bits.T = 0; /* handle as ARM32 code */
- cpu->CPSR.bits.I = cpu->SPSR.bits.I; /* keep int disable flag */
- cpu->R[15] = cpu->intVector + 0x08;
- cpu->next_instruction = cpu->R[15];
- return 3;
- }
- else
- {
- u32 swinum = cpu->instruction & 0xFF;
- return cpu->swi_tab[swinum](cpu) + 3;
- }
- //return 3;
-}
-
-#define SIGNEEXT_IMM11(i) (((i)&0x7FF) | (BIT10(i) * 0xFFFFF800))
-
-static u32 FASTCALL OP_B_UNCOND(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[15] += (SIGNEEXT_IMM11(i)<<1);
- cpu->next_instruction = cpu->R[15];
- return 3;
-}
-
-static u32 FASTCALL OP_BLX(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1))&0xFFFFFFFC;
- cpu->R[14] = cpu->next_instruction | 1;
- cpu->next_instruction = cpu->R[15];
- cpu->CPSR.bits.T = 0;
- return 3;
-}
-
-static u32 FASTCALL OP_BL_10(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[14] = cpu->R[15] + (SIGNEEXT_IMM11(i)<<12);
- return 1;
-}
-
-static u32 FASTCALL OP_BL_THUMB(armcpu_t *cpu)
-{
- u32 i = cpu->instruction;
- cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1));
- cpu->R[14] = cpu->next_instruction | 1;
- cpu->next_instruction = cpu->R[15];
- return 3;
-}
-
-#define TYPE_RETOUR u32
-#define CALLTYPE FASTCALL
-#define PARAMETRES armcpu_t *cpu
-#define NOM_THUMB_TAB thumb_instructions_set
-
-#include "thumb_tabdef.inc"
diff --git a/src/xsf/desmume/thumb_instructions.cc b/src/xsf/desmume/thumb_instructions.cc
new file mode 100644
index 000000000000..fedf03b900ff
--- /dev/null
+++ b/src/xsf/desmume/thumb_instructions.cc
@@ -0,0 +1,944 @@
+/*
+ Copyright (C) 2006 yopyop
+ yopyop156 at ifrance.com
+ yopyop156.ifrance.com
+
+ Code added on 18/08/2006 by shash
+ - Missing missaligned addresses correction
+ (reference in http://nocash.emubase.de/gbatek.htm#cpumemoryalignments)
+
+ This file is part of DeSmuME
+
+ DeSmuME 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.
+
+ DeSmuME 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 DeSmuME; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "bios.h"
+#include "debug.h"
+#include "MMU.h"
+
+#define REG_NUM(i, n) (((i)>>n)&0x7)
+
+extern BOOL execute;
+
+// Use this macros for reading/writing, so the GDB stub isn't broken
+#ifdef GDB_STUB
+ #define READ32(a,b) cpu->mem_if->read32(a,b)
+ #define WRITE32(a,b,c) cpu->mem_if->write32(a,b,c)
+ #define READ16(a,b) cpu->mem_if->read16(a,b)
+ #define WRITE16(a,b,c) cpu->mem_if->write16(a,b,c)
+ #define READ8(a,b) cpu->mem_if->read8(a,b)
+ #define WRITE8(a,b,c) cpu->mem_if->write8(a,b,c)
+#else
+ #define READ32(a,b) MMU_read32(cpu->proc_ID, b)
+ #define WRITE32(a,b,c) MMU_write32(cpu->proc_ID,b,c)
+ #define READ16(a,b) MMU_read16(cpu->proc_ID, b)
+ #define WRITE16(a,b,c) MMU_write16(cpu->proc_ID,b,c)
+ #define READ8(a,b) MMU_read8(cpu->proc_ID, b)
+ #define WRITE8(a,b,c) MMU_write8(cpu->proc_ID,b,c)
+#endif
+
+static u32 FASTCALL OP_UND_THUMB(armcpu_t *cpu)
+{
+ execute = false;
+ return 1;
+}
+
+static u32 FASTCALL OP_LSL_0(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)];
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_LSL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = (i>>6) & 0x1F;
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], 32-v);
+ cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] << v);
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_LSR_0(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ // cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]);
+ cpu->R[REG_NUM(i, 0)] = 0;
+ cpu->CPSR.bits.N = 0;
+ cpu->CPSR.bits.Z = 1;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_LSR(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = (i>>6) & 0x1F;
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
+ cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] >> v);
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_ASR_0(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]);
+ cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 3)])*0xFFFFFFFF;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_ASR(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = (i>>6) & 0x1F;
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], v-1);
+ cpu->R[REG_NUM(i, 0)] = (((s32)cpu->R[REG_NUM(i, 3)]) >> v);
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_ADD_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 a = cpu->R[REG_NUM(i, 3)];
+ u32 b = cpu->R[REG_NUM(i, 6)];
+ cpu->R[REG_NUM(i, 0)] = a + b;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
+
+ return 3;
+}
+
+static u32 FASTCALL OP_SUB_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 a = cpu->R[REG_NUM(i, 3)];
+ u32 b = cpu->R[REG_NUM(i, 6)];
+ cpu->R[REG_NUM(i, 0)] = a - b;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
+
+ return 3;
+}
+
+static u32 FASTCALL OP_ADD_IMM3(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 a = cpu->R[REG_NUM(i, 3)];
+ cpu->R[REG_NUM(i, 0)] = a + REG_NUM(i, 6);
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SUB_IMM3(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 a = cpu->R[REG_NUM(i, 3)];
+ cpu->R[REG_NUM(i, 0)] = a - REG_NUM(i, 6);
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
+
+ return 2;
+}
+
+static u32 FASTCALL OP_MOV_IMM8(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[REG_NUM(i, 8)] = i & 0xFF;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 8)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 8)] == 0;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_CMP_IMM8(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF);
+ cpu->CPSR.bits.N = BIT31(tmp);
+ cpu->CPSR.bits.Z = tmp == 0;
+ cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
+
+ return 2;
+}
+
+static u32 FASTCALL OP_ADD_IMM8(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 tmp = cpu->R[REG_NUM(i, 8)] + (i & 0xFF);
+ cpu->CPSR.bits.N = BIT31(tmp);
+ cpu->CPSR.bits.Z = tmp == 0;
+ cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
+ cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
+ cpu->R[REG_NUM(i, 8)] = tmp;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_SUB_IMM8(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF);
+ cpu->CPSR.bits.N = BIT31(tmp);
+ cpu->CPSR.bits.Z = tmp == 0;
+ cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
+ cpu->R[REG_NUM(i, 8)] = tmp;
+
+ return 2;
+}
+
+static u32 FASTCALL OP_AND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[REG_NUM(i, 0)] &= cpu->R[REG_NUM(i, 3)];
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 3;
+}
+
+static u32 FASTCALL OP_EOR(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[REG_NUM(i, 0)] ^= cpu->R[REG_NUM(i, 3)];
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 3;
+}
+
+static u32 FASTCALL OP_LSL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
+
+ if(!v)
+ {
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ return 3;
+ }
+ if(v<32)
+ {
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], 32-v);
+ cpu->R[REG_NUM(i, 0)] <<= v;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ return 3;
+ }
+ if(v==32)
+ cpu->CPSR.bits.C = BIT0(cpu->R[REG_NUM(i, 0)]);
+ else
+ cpu->CPSR.bits.C = 0;
+ cpu->R[REG_NUM(i, 0)] = 0;
+ cpu->CPSR.bits.N = 0;
+ cpu->CPSR.bits.Z = 1;
+
+ return 3;
+}
+
+static u32 FASTCALL OP_LSR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
+
+ if(!v)
+ {
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ return 3;
+ }
+ if(v<32)
+ {
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
+ cpu->R[REG_NUM(i, 0)] >>= v;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ return 3;
+ }
+ if(v==32)
+ cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
+ else
+ cpu->CPSR.bits.C = 0;
+ cpu->R[REG_NUM(i, 0)] = 0;
+ cpu->CPSR.bits.N = 0;
+ cpu->CPSR.bits.Z = 1;
+
+ return 3;
+}
+
+static u32 FASTCALL OP_ASR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
+
+ if(!v)
+ {
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ return 3;
+ }
+ if(v<32)
+ {
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
+ cpu->R[REG_NUM(i, 0)] = (u32)(((s32)cpu->R[REG_NUM(i, 0)]) >> v);
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ return 3;
+ }
+
+ cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 0)])*0xFFFFFFFF;
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 3;
+}
+
+static u32 FASTCALL OP_ADC_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 a = cpu->R[REG_NUM(i, 0)];
+ u32 b = cpu->R[REG_NUM(i, 3)];
+ u32 tmp = b + cpu->CPSR.bits.C;
+ u32 res = a + tmp;
+
+ cpu->R[REG_NUM(i, 0)] = res;
+
+ cpu->CPSR.bits.N = BIT31(res);
+ cpu->CPSR.bits.Z = res == 0;
+
+ cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(b, cpu->CPSR.bits.C, tmp) | UNSIGNED_OVERFLOW(tmp, a, res);
+ cpu->CPSR.bits.V = SIGNED_OVERFLOW(b, cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(tmp, a, res);
+
+ return 3;
+}
+
+static u32 FASTCALL OP_SBC_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 a = cpu->R[REG_NUM(i, 0)];
+ u32 b = cpu->R[REG_NUM(i, 3)];
+ u32 tmp = a - (!cpu->CPSR.bits.C);
+ u32 res = tmp - b;
+ cpu->R[REG_NUM(i, 0)] = res;
+
+ cpu->CPSR.bits.N = BIT31(res);
+ cpu->CPSR.bits.Z = res == 0;
+
+ cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(a, !cpu->CPSR.bits.C, tmp)) & (!UNSIGNED_OVERFLOW(tmp, b, res));
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, !cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(tmp, b, res);
+
+ return 3;
+}
+
+static u32 FASTCALL OP_ROR_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
+
+ if(v == 0)
+ {
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ return 3;
+ }
+ v &= 0xF;
+ if(v == 0)
+ {
+ cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ return 3;
+ }
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
+ cpu->R[REG_NUM(i, 0)] = ROR(cpu->R[REG_NUM(i, 0)], v);
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 3;
+}
+
+static u32 FASTCALL OP_TST(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 tmp = cpu->R[REG_NUM(i, 0)] & cpu->R[REG_NUM(i, 3)];
+ cpu->CPSR.bits.N = BIT31(tmp);
+ cpu->CPSR.bits.Z = tmp == 0;
+
+ return 3;
+}
+
+static u32 FASTCALL OP_NEG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 a = cpu->R[REG_NUM(i, 3)];
+ cpu->R[REG_NUM(i, 0)] = -((signed int)a);
+
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+ cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(0, a, cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(0, a, cpu->R[REG_NUM(i, 0)]);
+
+ return 3;
+}
+
+static u32 FASTCALL OP_CMP(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 tmp = cpu->R[REG_NUM(i, 0)] -cpu->R[REG_NUM(i, 3)];
+
+ cpu->CPSR.bits.N = BIT31(tmp);
+ cpu->CPSR.bits.Z = tmp == 0;
+ cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
+
+ return 3;
+}
+
+static u32 FASTCALL OP_CMN(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 tmp = cpu->R[REG_NUM(i, 0)] + cpu->R[REG_NUM(i, 3)];
+
+ //execute = false;
+ //log::ajouter("OP_CMN THUMB");
+ cpu->CPSR.bits.N = BIT31(tmp);
+ cpu->CPSR.bits.Z = tmp == 0;
+ cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
+ cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
+
+ return 3;
+}
+
+static u32 FASTCALL OP_ORR(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[REG_NUM(i, 0)] |= cpu->R[REG_NUM(i, 3)];
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 3;
+}
+
+static u32 FASTCALL OP_MUL_REG(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[REG_NUM(i, 0)] *= cpu->R[REG_NUM(i, 3)];
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 3;
+}
+
+static u32 FASTCALL OP_BIC(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[REG_NUM(i, 0)] &= (~cpu->R[REG_NUM(i, 3)]);
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 3;
+}
+
+static u32 FASTCALL OP_MVN(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[REG_NUM(i, 0)] = (~cpu->R[REG_NUM(i, 3)]);
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
+
+ return 3;
+}
+
+static u32 FASTCALL OP_ADD_SPE(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 Rd = (i&7) | ((i>>4)&8);
+ cpu->R[Rd] += cpu->R[REG_POS(i, 3)];
+
+ if(Rd==15)
+ cpu->next_instruction = cpu->R[15];
+
+ return 2;
+}
+
+static u32 FASTCALL OP_CMP_SPE(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 Rn = (i&7) | ((i>>4)&8);
+ u32 tmp = cpu->R[Rn] -cpu->R[REG_POS(i, 3)];
+
+ cpu->CPSR.bits.N = BIT31(tmp);
+ cpu->CPSR.bits.Z = tmp == 0;
+ cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp);
+ cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp);
+
+ return 3;
+}
+
+static u32 FASTCALL OP_MOV_SPE(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 Rd = (i&7) | ((i>>4)&8);
+ cpu->R[Rd] = cpu->R[REG_POS(i, 3)];
+
+ if(Rd==15)
+ cpu->next_instruction = cpu->R[15];
+
+ return 2;
+}
+
+static u32 FASTCALL OP_BX_THUMB(armcpu_t *cpu)
+{
+ u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)];
+
+ cpu->CPSR.bits.T = BIT0(Rm);
+ cpu->R[15] = (Rm & 0xFFFFFFFE);
+ cpu->next_instruction = cpu->R[15];
+
+ return 3;
+}
+
+static u32 FASTCALL OP_BLX_THUMB(armcpu_t *cpu)
+{
+ u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)];
+
+ cpu->CPSR.bits.T = BIT0(Rm);
+ cpu->R[14] = cpu->next_instruction | 1;
+ cpu->R[15] = (Rm & 0xFFFFFFFE);
+ cpu->next_instruction = cpu->R[15];
+
+ return 3;
+}
+
+static u32 FASTCALL OP_LDR_PCREL(armcpu_t *cpu)
+{
+ u32 adr = (cpu->R[15]&0xFFFFFFFC) + ((cpu->instruction&0xFF)<<2);
+
+ cpu->R[REG_NUM(cpu->instruction, 8)] = READ32(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 6)] + cpu->R[REG_NUM(i, 3)];
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]);
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
+ WRITE16(cpu->mem_if->data, adr, ((u16)cpu->R[REG_NUM(i, 0)]));
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
+ WRITE8(cpu->mem_if->data, adr, ((u8)cpu->R[REG_NUM(i, 0)]));
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSB_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
+ cpu->R[REG_NUM(i, 0)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = (cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]);
+ u32 tempValue = READ32(cpu->mem_if->data, adr&0xFFFFFFFC);
+
+ adr = (adr&3)*8;
+ tempValue = (tempValue>>adr) | (tempValue<<(32-adr));
+ cpu->R[REG_NUM(i, 0)] = tempValue;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
+ cpu->R[REG_NUM(i, 0)] = (u32)READ16(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
+ cpu->R[REG_NUM(i, 0)] = (u32)READ8(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRSH_REG_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
+ cpu->R[REG_NUM(i, 0)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C);
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]);
+
+ return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C);
+ u32 tempValue = READ32(cpu->mem_if->data, adr&0xFFFFFFFC);
+ adr = (adr&3)*8;
+ tempValue = (tempValue>>adr) | (tempValue<<(32-adr));
+ cpu->R[REG_NUM(i, 0)] = tempValue;
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRB_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F);
+ WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_NUM(i, 0)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRB_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F);
+ cpu->R[REG_NUM(i, 0)] = READ8(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STRH_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E);
+ WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_NUM(i, 0)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDRH_IMM_OFF(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E);
+ cpu->R[REG_NUM(i, 0)] = READ16(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_STR_SPREL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[13] + ((i&0xFF)<<2);
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 8)]);
+
+ return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_LDR_SPREL(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[13] + ((i&0xFF)<<2);
+ cpu->R[REG_NUM(i, 8)] = READ32(cpu->mem_if->data, adr);
+
+ return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+}
+
+static u32 FASTCALL OP_ADD_2PC(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[REG_NUM(i, 8)] = (cpu->R[15]&0xFFFFFFFC) + ((i&0xFF)<<2);
+
+ return 5;
+}
+
+static u32 FASTCALL OP_ADD_2SP(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[REG_NUM(i, 8)] = cpu->R[13] + ((i&0xFF)<<2);
+
+ return 2;
+}
+
+static u32 FASTCALL OP_ADJUST_P_SP(armcpu_t *cpu)
+{
+ cpu->R[13] += ((cpu->instruction&0x7F)<<2);
+
+ return 1;
+}
+
+static u32 FASTCALL OP_ADJUST_M_SP(armcpu_t *cpu)
+{
+ cpu->R[13] -= ((cpu->instruction&0x7F)<<2);
+
+ return 1;
+}
+
+static u32 FASTCALL OP_PUSH(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[13] - 4;
+ u32 c = 0, j;
+
+ for(j = 0; j<8; ++j)
+ if(BIT_N(i, 7-j))
+ {
+ WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ adr -= 4;
+ }
+ cpu->R[13] = adr + 4;
+
+ return c + 3;
+}
+
+static u32 FASTCALL OP_PUSH_LR(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[13] - 4;
+ u32 c = 0, j;
+
+ WRITE32(cpu->mem_if->data, adr, cpu->R[14]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ adr -= 4;
+
+ for(j = 0; j<8; ++j)
+ if(BIT_N(i, 7-j))
+ {
+ WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ adr -= 4;
+ }
+ cpu->R[13] = adr + 4;
+
+ return c + 4;
+}
+
+static u32 FASTCALL OP_POP(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[13];
+ u32 c = 0, j;
+
+ for(j = 0; j<8; ++j)
+ if(BIT_N(i, j))
+ {
+ cpu->R[j] = READ32(cpu->mem_if->data, adr);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ adr += 4;
+ }
+ cpu->R[13] = adr;
+
+ return c + 2;
+}
+
+static u32 FASTCALL OP_POP_PC(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[13];
+ u32 c = 0, j;
+ u32 v;
+
+ for(j = 0; j<8; ++j)
+ if(BIT_N(i, j))
+ {
+ cpu->R[j] = READ32(cpu->mem_if->data, adr);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ adr += 4;
+ }
+
+ v = READ32(cpu->mem_if->data, adr);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ cpu->R[15] = v & 0xFFFFFFFE;
+ cpu->next_instruction = v & 0xFFFFFFFE;
+ if(cpu->proc_ID==0)
+ cpu->CPSR.bits.T = BIT0(v);
+ adr += 4;
+
+ cpu->R[13] = adr;
+ return c + 5;
+}
+
+static u32 FASTCALL OP_BKPT_THUMB(armcpu_t *cpu)
+{
+ return 1;
+}
+
+static u32 FASTCALL OP_STMIA_THUMB(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 8)];
+ u32 c = 0, j;
+
+ for(j = 0; j<8; ++j)
+ if(BIT_N(i, j))
+ {
+ WRITE32(cpu->mem_if->data, adr, cpu->R[j]);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ adr += 4;
+ }
+ cpu->R[REG_NUM(i, 8)] = adr;
+ return c + 2;
+}
+
+static u32 FASTCALL OP_LDMIA_THUMB(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ u32 adr = cpu->R[REG_NUM(i, 8)];
+ u32 c = 0, j;
+
+ for(j = 0; j<8; ++j)
+ if(BIT_N(i, j))
+ {
+ cpu->R[j] = READ32(cpu->mem_if->data, adr);
+ c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
+ adr += 4;
+ }
+ cpu->R[REG_NUM(i, 8)] = adr;
+ return c + 3;
+}
+
+static u32 FASTCALL OP_B_COND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ if(!TEST_COND((i>>8)&0xF, 0, cpu->CPSR))
+ return 1;
+
+ cpu->R[15] += ((s32)((s8)(i&0xFF)))<<1;
+ cpu->next_instruction = cpu->R[15];
+ return 3;
+}
+
+static u32 FASTCALL OP_SWI_THUMB(armcpu_t *cpu)
+{
+ if (((cpu->intVector != 0) ^ (cpu->proc_ID == ARMCPU_ARM9)))
+ {
+ /* we use an irq thats not in the irq tab, as
+ it was replaced duie to a changed intVector */
+ Status_Reg tmp = cpu->CPSR;
+ armcpu_switchMode(cpu, SVC); /* enter svc mode */
+ cpu->R[14] = cpu->R[15] - 4; /* jump to swi Vector */
+ cpu->SPSR = tmp; /* save old CPSR as new SPSR */
+ cpu->CPSR.bits.T = 0; /* handle as ARM32 code */
+ cpu->CPSR.bits.I = cpu->SPSR.bits.I; /* keep int disable flag */
+ cpu->R[15] = cpu->intVector + 0x08;
+ cpu->next_instruction = cpu->R[15];
+ return 3;
+ }
+ else
+ {
+ u32 swinum = cpu->instruction & 0xFF;
+ return cpu->swi_tab[swinum](cpu) + 3;
+ }
+ //return 3;
+}
+
+#define SIGNEEXT_IMM11(i) (((i)&0x7FF) | (BIT10(i) * 0xFFFFF800))
+
+static u32 FASTCALL OP_B_UNCOND(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[15] += (SIGNEEXT_IMM11(i)<<1);
+ cpu->next_instruction = cpu->R[15];
+ return 3;
+}
+
+static u32 FASTCALL OP_BLX(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1))&0xFFFFFFFC;
+ cpu->R[14] = cpu->next_instruction | 1;
+ cpu->next_instruction = cpu->R[15];
+ cpu->CPSR.bits.T = 0;
+ return 3;
+}
+
+static u32 FASTCALL OP_BL_10(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[14] = cpu->R[15] + (SIGNEEXT_IMM11(i)<<12);
+ return 1;
+}
+
+static u32 FASTCALL OP_BL_THUMB(armcpu_t *cpu)
+{
+ u32 i = cpu->instruction;
+ cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1));
+ cpu->R[14] = cpu->next_instruction | 1;
+ cpu->next_instruction = cpu->R[15];
+ return 3;
+}
+
+#define TYPE_RETOUR u32
+#define CALLTYPE FASTCALL
+#define PARAMETRES armcpu_t *cpu
+#define NOM_THUMB_TAB thumb_instructions_set
+
+#include "thumb_tabdef.inc"
diff --git a/src/xsf/desmume/thumb_instructions.h b/src/xsf/desmume/thumb_instructions.h
index 27088a6e33eb..7795d2868f80 100644
--- a/src/xsf/desmume/thumb_instructions.h
+++ b/src/xsf/desmume/thumb_instructions.h
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef THUMB_INSTRUCTIONS_H
diff --git a/src/xsf/desmume/thumb_tabdef.inc b/src/xsf/desmume/thumb_tabdef.inc
index 1a9c53b03475..37c0dcaf34ac 100644
--- a/src/xsf/desmume/thumb_tabdef.inc
+++ b/src/xsf/desmume/thumb_tabdef.inc
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
TYPE_RETOUR (* CALLTYPE NOM_THUMB_TAB[1024])(PARAMETRES)={
diff --git a/src/xsf/desmume/types.h b/src/xsf/desmume/types.h
index ed4f210762bd..42c005bb55cd 100644
--- a/src/xsf/desmume/types.h
+++ b/src/xsf/desmume/types.h
@@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef TYPES_HPP
@@ -124,12 +124,12 @@ typedef int desmume_BOOL;
#define BOOL desmume_BOOL
#endif
-#ifndef TRUE
-#define TRUE 1
+#ifndef true
+#define true 1
#endif
-#ifndef FALSE
-#define FALSE 0
+#ifndef false
+#define false 0
#endif
#ifdef __GNUC__
diff --git a/src/xsf/plugin.c b/src/xsf/plugin.c
deleted file mode 100644
index c7e32831b27d..000000000000
--- a/src/xsf/plugin.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- Audio Overload SDK - main driver. for demonstration only, not user friendly!
-
- Copyright (c) 2007-2008 R. Belmont and Richard Bannister.
-
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <audacious/i18n.h>
-#include <audacious/input.h>
-#include <audacious/misc.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-#include "ao.h"
-#include "corlett.h"
-#include "vio2sf.h"
-
-/* xsf_get_lib: called to load secondary files */
-static const char *dirpath;
-
-int xsf_get_lib(char *filename, void **buffer, unsigned int *length)
-{
- void *filebuf;
- int64_t size;
-
- SPRINTF(path2, "%s/%s", dirpath, filename);
- vfs_file_get_contents(path2, &filebuf, &size);
-
- *buffer = filebuf;
- *length = (uint64_t)size;
-
- return AO_SUCCESS;
-}
-
-Tuple *xsf_tuple(const char *filename, VFSFile *fd)
-{
- Tuple *t;
- corlett_t *c;
- void *buf;
- int64_t sz;
-
- vfs_file_get_contents (filename, & buf, & sz);
-
- if (!buf)
- return NULL;
-
- if (corlett_decode(buf, sz, NULL, NULL, &c) != AO_SUCCESS)
- return NULL;
-
- t = tuple_new_from_filename(filename);
-
- tuple_set_int(t, FIELD_LENGTH, c->inf_length ? psfTimeToMS(c->inf_length) + psfTimeToMS(c->inf_fade) : -1);
- tuple_set_str(t, FIELD_ARTIST, c->inf_artist);
- tuple_set_str(t, FIELD_ALBUM, c->inf_game);
- tuple_set_str(t, FIELD_TITLE, c->inf_title);
- tuple_set_str(t, FIELD_COPYRIGHT, c->inf_copy);
- tuple_set_str(t, FIELD_QUALITY, _("sequenced"));
- tuple_set_str(t, FIELD_CODEC, "GBA/Nintendo DS Audio");
-
- free(c);
- free(buf);
-
- return t;
-}
-
-static int xsf_get_length(const char *filename)
-{
- corlett_t *c;
- void *buf;
- int64_t size;
-
- vfs_file_get_contents(filename, &buf, &size);
-
- if (!buf)
- return -1;
-
- if (corlett_decode(buf, size, NULL, NULL, &c) != AO_SUCCESS)
- {
- free(buf);
- return -1;
- }
-
- int length = c->inf_length ? psfTimeToMS(c->inf_length) + psfTimeToMS(c->inf_fade) : -1;
-
- free(c);
- free(buf);
-
- return length;
-}
-
-static bool_t xsf_play(const char * filename, VFSFile * file)
-{
- void *buffer;
- int64_t size;
- int length = xsf_get_length(filename);
- int16_t samples[44100*2];
- int seglen = 44100 / 60;
- float pos;
- bool_t error = FALSE;
-
- const char * slash = strrchr (filename, '/');
- if (! slash)
- return FALSE;
-
- SNCOPY (dirbuf, filename, slash + 1 - filename);
- dirpath = dirbuf;
-
- vfs_file_get_contents (filename, & buffer, & size);
-
- if (xsf_start(buffer, size) != AO_SUCCESS)
- {
- error = TRUE;
- goto ERR_NO_CLOSE;
- }
-
- if (!aud_input_open_audio(FMT_S16_NE, 44100, 2))
- {
- error = TRUE;
- goto ERR_NO_CLOSE;
- }
-
- aud_input_set_bitrate(44100*2*2*8);
-
- while (! aud_input_check_stop ())
- {
- int seek_value = aud_input_check_seek ();
-
- if (seek_value >= 0)
- {
- if (seek_value > aud_input_written_time ())
- {
- pos = aud_input_written_time ();
-
- while (pos < seek_value)
- {
- xsf_gen(samples, seglen);
- pos += 16.666;
- }
- }
- else if (seek_value < aud_input_written_time ())
- {
- xsf_term();
-
- if (xsf_start(buffer, size) == AO_SUCCESS)
- {
- pos = 0;
- while (pos < seek_value)
- {
- xsf_gen(samples, seglen);
- pos += 16.666; /* each segment is 16.666ms */
- }
- }
- else
- {
- error = TRUE;
- goto CLEANUP;
- }
- }
- }
-
- xsf_gen(samples, seglen);
- aud_input_write_audio((uint8_t *)samples, seglen * 4);
-
- if (aud_input_written_time() >= length)
- goto CLEANUP;
- }
-
-CLEANUP:
- xsf_term();
-
-ERR_NO_CLOSE:
- dirpath = NULL;
- free(buffer);
-
- return !error;
-}
-
-int xsf_is_our_fd(const char *filename, VFSFile *file)
-{
- char magic[4];
- if (vfs_fread(magic, 1, 4, file) < 4)
- return FALSE;
-
- if (!memcmp(magic, "PSF$", 4))
- return 1;
-
- return 0;
-}
-
-static const char *xsf_fmts[] = { "2sf", "mini2sf", NULL };
-
-AUD_INPUT_PLUGIN
-(
- .name = N_("2SF Decoder"),
- .domain = PACKAGE,
- .play = xsf_play,
- .probe_for_tuple = xsf_tuple,
- .is_our_file_from_vfs = xsf_is_our_fd,
- .extensions = xsf_fmts,
-)
diff --git a/src/xsf/plugin.cc b/src/xsf/plugin.cc
new file mode 100644
index 000000000000..3f38f8593229
--- /dev/null
+++ b/src/xsf/plugin.cc
@@ -0,0 +1,242 @@
+/*
+ Audio Overload SDK - main driver. for demonstration only, not user friendly!
+
+ Copyright (c) 2007-2008 R. Belmont and Richard Bannister.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/preferences.h>
+#include <libaudcore/audstrings.h>
+#include <libaudcore/runtime.h>
+
+#include "ao.h"
+#include "corlett.h"
+#include "vio2sf.h"
+
+class XSFPlugin : public InputPlugin
+{
+public:
+ static const char *const exts[];
+ static const char *const defaults[];
+ static const PreferencesWidget widgets[];
+ static const PluginPreferences prefs;
+
+ static constexpr PluginInfo info = {
+ N_("2SF Decoder"),
+ PACKAGE,
+ nullptr,
+ & prefs
+ };
+
+ static constexpr auto iinfo = InputInfo()
+ .with_exts(exts);
+
+ constexpr XSFPlugin() : InputPlugin(info, iinfo) {}
+
+ bool init();
+
+ bool is_our_file(const char *filename, VFSFile &file);
+ Tuple read_tuple(const char *filename, VFSFile &file);
+ bool play(const char *filename, VFSFile &file);
+};
+
+EXPORT XSFPlugin aud_plugin_instance;
+
+/* xsf_get_lib: called to load secondary files */
+static String dirpath;
+
+#define CFG_ID "xsf"
+
+const char* const XSFPlugin::defaults[] =
+{
+ "ignore_length", "FALSE",
+ NULL
+};
+
+bool XSFPlugin::init()
+{
+ aud_config_set_defaults(CFG_ID, defaults);
+ return true;
+}
+
+Index<char> xsf_get_lib(char *filename)
+{
+ VFSFile file(filename_build({dirpath, filename}), "r");
+ return file ? file.read_all() : Index<char>();
+}
+
+Tuple XSFPlugin::read_tuple(const char *filename, VFSFile &fd)
+{
+ Tuple t;
+ corlett_t *c;
+
+ Index<char> buf = fd.read_all ();
+
+ if (!buf.len())
+ return t;
+
+ if (corlett_decode((uint8_t *)buf.begin(), buf.len(), nullptr, nullptr, &c) != AO_SUCCESS)
+ return t;
+
+ t.set_filename (filename);
+
+ t.set_int (Tuple::Length, psfTimeToMS(c->inf_length) + psfTimeToMS(c->inf_fade));
+ t.set_str (Tuple::Artist, c->inf_artist);
+ t.set_str (Tuple::Album, c->inf_game);
+ t.set_str (Tuple::Title, c->inf_title);
+ t.set_str (Tuple::Copyright, c->inf_copy);
+ t.set_str (Tuple::Quality, _("sequenced"));
+ t.set_str (Tuple::Codec, "GBA/Nintendo DS Audio");
+
+ free(c);
+
+ return t;
+}
+
+static int xsf_get_length(const Index<char> &buf)
+{
+ corlett_t *c;
+
+ if (corlett_decode((uint8_t *)buf.begin(), buf.len(), nullptr, nullptr, &c) != AO_SUCCESS)
+ return -1;
+
+ bool ignore_length = aud_get_bool(CFG_ID, "ignore_length");
+ int length = (!ignore_length) ? psfTimeToMS(c->inf_length) + psfTimeToMS(c->inf_fade) : -1;
+
+ free(c);
+
+ return length;
+}
+
+bool XSFPlugin::play(const char *filename, VFSFile &file)
+{
+ int length = -1;
+ int16_t samples[44100*2];
+ int seglen = 44100 / 60;
+ float pos = 0.0;
+ bool error = false;
+
+ const char * slash = strrchr (filename, '/');
+ if (! slash)
+ return false;
+
+ dirpath = String (str_copy (filename, slash + 1 - filename));
+
+ Index<char> buf = file.read_all ();
+
+ if (!buf.len())
+ {
+ error = true;
+ goto ERR_NO_CLOSE;
+ }
+
+ length = xsf_get_length(buf);
+
+ if (xsf_start(buf.begin(), buf.len()) != AO_SUCCESS)
+ {
+ error = true;
+ goto ERR_NO_CLOSE;
+ }
+
+ set_stream_bitrate(44100*2*2*8);
+ open_audio(FMT_S16_NE, 44100, 2);
+
+ while (! check_stop ())
+ {
+ int seek_value = check_seek ();
+
+ if (seek_value >= 0)
+ {
+ if (seek_value > pos)
+ {
+ while (pos < seek_value)
+ {
+ xsf_gen(samples, seglen);
+ pos += 16.666;
+ }
+ }
+ else if (seek_value < pos)
+ {
+ xsf_term();
+
+ if (xsf_start(buf.begin(), buf.len()) == AO_SUCCESS)
+ {
+ pos = 0.0;
+ while (pos < seek_value)
+ {
+ xsf_gen(samples, seglen);
+ pos += 16.666; /* each segment is 16.666ms */
+ }
+ }
+ else
+ {
+ error = true;
+ goto CLEANUP;
+ }
+ }
+ }
+
+ xsf_gen(samples, seglen);
+ pos += 16.666;
+
+ write_audio(samples, seglen * 4);
+
+ bool ignore_length = aud_get_bool(CFG_ID, "ignore_length");
+ if (pos >= length && !ignore_length)
+ goto CLEANUP;
+ }
+
+CLEANUP:
+ xsf_term();
+
+ERR_NO_CLOSE:
+ dirpath = String ();
+
+ return !error;
+}
+
+bool XSFPlugin::is_our_file(const char *filename, VFSFile &file)
+{
+ char magic[4];
+ if (file.fread (magic, 1, 4) < 4)
+ return false;
+
+ if (!memcmp(magic, "PSF$", 4))
+ return 1;
+
+ return 0;
+}
+
+const char *const XSFPlugin::exts[] = { "2sf", "mini2sf", nullptr };
+
+const PreferencesWidget XSFPlugin::widgets[] = {
+ WidgetLabel(N_("<b>XSF Configuration</b>")),
+ WidgetCheck(N_("Ignore length from file"), WidgetBool(CFG_ID, "ignore_length")),
+};
+
+const PluginPreferences XSFPlugin::prefs = {{widgets}};
diff --git a/src/xsf/tagget.h b/src/xsf/tagget.h
index 4ba361bba8d9..07a58fe0af08 100644
--- a/src/xsf/tagget.h
+++ b/src/xsf/tagget.h
@@ -92,7 +92,7 @@ typedef struct
static int xsf_tagenum_callback_tagget(void *pWork, const char *pNameTop, const char *pNameEnd, const char *pValueTop, const char *pValueEnd)
{
xsf_tagget_work_t *pwork = (xsf_tagget_work_t *)pWork;
- if (pwork->taglen == pNameEnd - pNameTop && !g_ascii_strncasecmp(pNameTop, pwork->tag, pwork->taglen))
+ if (pwork->taglen == pNameEnd - pNameTop && !strcmp_nocase(pNameTop, pwork->tag, pwork->taglen))
{
char *ret = (char *)malloc(pValueEnd - pValueTop + 1);
if (!ret) return xsf_tagenum_callback_returnvaluecontinue;
diff --git a/src/xsf/vio2sf.c b/src/xsf/vio2sf.c
deleted file mode 100644
index 0a53c602be9c..000000000000
--- a/src/xsf/vio2sf.c
+++ /dev/null
@@ -1,841 +0,0 @@
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "desmume/MMU.h"
-#include "desmume/armcpu.h"
-#include "desmume/NDSSystem.h"
-#include "desmume/SPU.h"
-#include "desmume/cp15.h"
-
-#include <glib.h>
-#include <zlib.h>
-#include "tagget.h"
-#include "vio2sf.h"
-
-volatile BOOL execute = FALSE;
-
-static struct
-{
- unsigned char *rom;
- unsigned char *state;
- unsigned romsize;
- unsigned statesize;
- unsigned stateptr;
-} loaderwork = {0, 0, 0, 0, 0};
-
-static void load_term(void)
-{
- if (loaderwork.rom)
- {
- free(loaderwork.rom);
- loaderwork.rom = 0;
- }
- loaderwork.romsize = 0;
- if (loaderwork.state)
- {
- free(loaderwork.state);
- loaderwork.state = 0;
- }
- loaderwork.statesize = 0;
-}
-
-static int load_map(int issave, unsigned char *udata, unsigned usize)
-{
- unsigned char *iptr;
- unsigned isize;
- unsigned char *xptr;
- unsigned xsize = getdwordle(udata + 4);
- unsigned xofs = getdwordle(udata + 0);
- if (issave)
- {
- iptr = loaderwork.state;
- isize = loaderwork.statesize;
- loaderwork.state = 0;
- loaderwork.statesize = 0;
- }
- else
- {
- iptr = loaderwork.rom;
- isize = loaderwork.romsize;
- loaderwork.rom = 0;
- loaderwork.romsize = 0;
- }
- if (!iptr)
- {
- iptr = malloc(xofs + xsize + 10);
- if (!iptr)
- return XSF_FALSE;
- memset(iptr, 0, xofs + xsize + 10);
- isize = xofs + xsize;
- }
- else if (isize < xofs + xsize)
- {
- unsigned rsize = xofs + xsize;
- if (!issave)
- {
- rsize -= 1;
- rsize |= rsize >> 1;
- rsize |= rsize >> 2;
- rsize |= rsize >> 4;
- rsize |= rsize >> 8;
- rsize |= rsize >> 16;
- rsize += 1;
- }
- xptr = realloc(iptr, xofs + rsize + 10);
- if (!xptr)
- {
- free(iptr);
- return XSF_FALSE;
- }
- iptr = xptr;
- isize = rsize;
- }
- memcpy(iptr + xofs, udata + 8, xsize);
- if (issave)
- {
- loaderwork.state = iptr;
- loaderwork.statesize = isize;
- }
- else
- {
- loaderwork.rom = iptr;
- loaderwork.romsize = isize;
- }
- return XSF_TRUE;
-}
-
-static int load_mapz(int issave, unsigned char *zdata, unsigned zsize, unsigned zcrc)
-{
- int ret;
- int zerr;
- uLongf usize = 8;
- uLongf rsize = usize;
- unsigned char *udata;
- unsigned char *rdata;
-
- udata = malloc(usize);
- if (!udata)
- return XSF_FALSE;
-
- while (Z_OK != (zerr = uncompress(udata, &usize, zdata, zsize)))
- {
- if (Z_MEM_ERROR != zerr && Z_BUF_ERROR != zerr)
- {
- free(udata);
- return XSF_FALSE;
- }
- if (usize >= 8)
- {
- usize = getdwordle(udata + 4) + 8;
- if (usize < rsize)
- {
- rsize += rsize;
- usize = rsize;
- }
- else
- rsize = usize;
- }
- else
- {
- rsize += rsize;
- usize = rsize;
- }
- free(udata);
- udata = malloc(usize);
- if (!udata)
- return XSF_FALSE;
- }
-
- rdata = realloc(udata, usize);
- if (!rdata)
- {
- free(udata);
- return XSF_FALSE;
- }
-
- if (0)
- {
- unsigned ccrc = crc32(crc32(0L, Z_NULL, 0), rdata, usize);
- if (ccrc != zcrc)
- return XSF_FALSE;
- }
-
- ret = load_map(issave, rdata, usize);
- free(rdata);
- return ret;
-}
-
-static int load_psf_one(unsigned char *pfile, unsigned bytes)
-{
- unsigned char *ptr = pfile;
- unsigned code_size;
- unsigned resv_size;
- unsigned code_crc;
- if (bytes < 16 || getdwordle(ptr) != 0x24465350)
- return XSF_FALSE;
-
- resv_size = getdwordle(ptr + 4);
- code_size = getdwordle(ptr + 8);
- code_crc = getdwordle(ptr + 12);
-
- if (resv_size)
- {
- unsigned resv_pos = 0;
- ptr = pfile + 16;
- if (16+ resv_size > bytes)
- return XSF_FALSE;
- while (resv_pos + 12 < resv_size)
- {
- unsigned save_size = getdwordle(ptr + resv_pos + 4);
- unsigned save_crc = getdwordle(ptr + resv_pos + 8);
- if (getdwordle(ptr + resv_pos + 0) == 0x45564153)
- {
- if (resv_pos + 12 + save_size > resv_size)
- return XSF_FALSE;
- if (!load_mapz(1, ptr + resv_pos + 12, save_size, save_crc))
- return XSF_FALSE;
- }
- resv_pos += 12 + save_size;
- }
- }
-
- if (code_size)
- {
- ptr = pfile + 16 + resv_size;
- if (16 + resv_size + code_size > bytes)
- return XSF_FALSE;
- if (!load_mapz(0, ptr, code_size, code_crc))
- return XSF_FALSE;
- }
-
- return XSF_TRUE;
-}
-
-typedef struct
-{
- const char *tag;
- int taglen;
- int level;
- int found;
-} loadlibwork_t;
-
-static int load_libs(int level, void *pfile, unsigned bytes);
-
-static int load_psfcb(void *pWork, const char *pNameTop, const char *pNameEnd, const char *pValueTop, const char *pValueEnd)
-{
- loadlibwork_t *pwork = (loadlibwork_t *)pWork;
- int ret = xsf_tagenum_callback_returnvaluecontinue;
- if (pNameEnd - pNameTop == pwork->taglen && !g_ascii_strncasecmp(pNameTop, pwork->tag , pwork->taglen))
- {
- unsigned l = pValueEnd - pValueTop;
- char *lib = malloc(l + 1);
- if (!lib)
- {
- ret = xsf_tagenum_callback_returnvaluebreak;
- }
- else
- {
- void *libbuf;
- unsigned libsize;
- memcpy(lib, pValueTop, l);
- lib[l] = '\0';
- if (!xsf_get_lib(lib, &libbuf, &libsize))
- {
- ret = xsf_tagenum_callback_returnvaluebreak;
- }
- else
- {
- if (!load_libs(pwork->level + 1, libbuf, libsize) || !load_psf_one(libbuf, libsize))
- ret = xsf_tagenum_callback_returnvaluebreak;
- else
- {
- pwork->found++;
- free(libbuf);
- }
- }
- free(lib);
- }
- }
- return ret;
-}
-
-static int load_libs(int level, void *pfile, unsigned bytes)
-{
- char tbuf[16];
- loadlibwork_t work;
- int n = 1;
-
- if (level > 10)
- return XSF_TRUE;
-
- work.level = level;
- work.tag = "_lib";
-
- do
- {
- work.taglen = strlen(work.tag);
- work.found = 0;
-
- if (xsf_tagenum(load_psfcb, &work, pfile, bytes) < 0)
- return XSF_FALSE;
-
-#ifdef HAVE_SPRINTF_S
- sprintf_s(tbuf, sizeof(tbuf), "_lib%10d", ++n);
-#else
- sprintf(tbuf, "_lib%10d", ++n);
-#endif
- work.tag = tbuf;
- }
- while (work.found);
-
- return XSF_TRUE;
-}
-
-static int load_psf(void *pfile, unsigned bytes)
-{
- load_term();
-
- if (!load_libs(1, pfile, bytes) || !load_psf_one(pfile, bytes))
- return XSF_FALSE;
-
- return XSF_TRUE;
-}
-
-static void load_getstateinit(unsigned ptr)
-{
- loaderwork.stateptr = ptr;
-}
-
-static u16 getwordle(const unsigned char *pData)
-{
- return pData[0] | (((u16)pData[1]) << 8);
-}
-
-static void load_getsta(Status_Reg *ptr, unsigned l)
-{
- unsigned s = l << 2;
- unsigned i;
- if ((loaderwork.stateptr > loaderwork.statesize) || ((loaderwork.stateptr + s) > loaderwork.statesize))
- return;
- for (i = 0; i < l; i++)
- {
- u32 st = getdwordle(loaderwork.state + loaderwork.stateptr + (i << 2));
- ptr[i].bits.N = (st >> 31) & 1;
- ptr[i].bits.Z = (st >> 30) & 1;
- ptr[i].bits.C = (st >> 29) & 1;
- ptr[i].bits.V = (st >> 28) & 1;
- ptr[i].bits.Q = (st >> 27) & 1;
- ptr[i].bits.RAZ = (st >> 8) & ((1 << 19) - 1);
- ptr[i].bits.I = (st >> 7) & 1;
- ptr[i].bits.F = (st >> 6) & 1;
- ptr[i].bits.T = (st >> 5) & 1;
- ptr[i].bits.mode = (st >> 0) & 0x1f;
- }
- loaderwork.stateptr += s;
-}
-
-static void load_getbool(BOOL *ptr, unsigned l)
-{
- unsigned s = l << 2;
- unsigned i;
- if ((loaderwork.stateptr > loaderwork.statesize) || ((loaderwork.stateptr + s) > loaderwork.statesize))
- return;
- for (i = 0; i < l; i++)
- ptr[i] = (BOOL)getdwordle(loaderwork.state + loaderwork.stateptr + (i << 2));
- loaderwork.stateptr += s;
-}
-
-#if defined(SIGNED_IS_NOT_2S_COMPLEMENT)
-/* 2's complement */
-#define u32tos32(v) ((s32)((((s64)(v)) ^ 0x8000) - 0x8000))
-#else
-/* 2's complement */
-#define u32tos32(v) ((s32)v)
-#endif
-
-static void load_gets32(s32 *ptr, unsigned l)
-{
- unsigned s = l << 2;
- unsigned i;
- if ((loaderwork.stateptr > loaderwork.statesize) || ((loaderwork.stateptr + s) > loaderwork.statesize))
- return;
- for (i = 0; i < l; i++)
- ptr[i] = u32tos32(getdwordle(loaderwork.state + loaderwork.stateptr + (i << 2)));
- loaderwork.stateptr += s;
-}
-
-static void load_getu32(u32 *ptr, unsigned l)
-{
- unsigned s = l << 2;
- unsigned i;
- if ((loaderwork.stateptr > loaderwork.statesize) || ((loaderwork.stateptr + s) > loaderwork.statesize))
- return;
- for (i = 0; i < l; i++)
- ptr[i] = getdwordle(loaderwork.state + loaderwork.stateptr + (i << 2));
- loaderwork.stateptr += s;
-}
-
-static void load_getu16(u16 *ptr, unsigned l)
-{
- unsigned s = l << 1;
- unsigned i;
- if ((loaderwork.stateptr > loaderwork.statesize) || ((loaderwork.stateptr + s) > loaderwork.statesize))
- return;
- for (i = 0; i < l; i++)
- ptr[i] = getwordle(loaderwork.state + loaderwork.stateptr + (i << 1));
- loaderwork.stateptr += s;
-}
-
-static void load_getu8(u8 *ptr, unsigned l)
-{
- unsigned s = l;
- unsigned i;
- if ((loaderwork.stateptr > loaderwork.statesize) || ((loaderwork.stateptr + s) > loaderwork.statesize))
- return;
- for (i = 0; i < l; i++)
- ptr[i] = loaderwork.state[loaderwork.stateptr + i];
- loaderwork.stateptr += s;
-}
-
-void gdb_stub_fix(armcpu_t *armcpu)
-{
- /* armcpu->R[15] = armcpu->instruct_adr; */
- armcpu->next_instruction = armcpu->instruct_adr;
- if(armcpu->CPSR.bits.T == 0)
- {
- armcpu->instruction = MMU_read32_acl(armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
- armcpu->instruct_adr = armcpu->next_instruction;
- armcpu->next_instruction += 4;
- armcpu->R[15] = armcpu->next_instruction + 4;
- }
- else
- {
- armcpu->instruction = MMU_read16_acl(armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
- armcpu->instruct_adr = armcpu->next_instruction;
- armcpu->next_instruction += 2;
- armcpu->R[15] = armcpu->next_instruction + 2;
- }
-}
-
-static void load_setstate(void)
-{
- if (!loaderwork.statesize)
- return;
-
- /* Skip over "Desmume Save File" crap */
- load_getstateinit(0x17);
-
- /* Read ARM7 cpu registers */
- load_getu32(&NDS_ARM7.proc_ID, 1);
- load_getu32(&NDS_ARM7.instruction, 1);
- load_getu32(&NDS_ARM7.instruct_adr, 1);
- load_getu32(&NDS_ARM7.next_instruction, 1);
- load_getu32(NDS_ARM7.R, 16);
- load_getsta(&NDS_ARM7.CPSR, 1);
- load_getsta(&NDS_ARM7.SPSR, 1);
- load_getu32(&NDS_ARM7.R13_usr, 1);
- load_getu32(&NDS_ARM7.R14_usr, 1);
- load_getu32(&NDS_ARM7.R13_svc, 1);
- load_getu32(&NDS_ARM7.R14_svc, 1);
- load_getu32(&NDS_ARM7.R13_abt, 1);
- load_getu32(&NDS_ARM7.R14_abt, 1);
- load_getu32(&NDS_ARM7.R13_und, 1);
- load_getu32(&NDS_ARM7.R14_und, 1);
- load_getu32(&NDS_ARM7.R13_irq, 1);
- load_getu32(&NDS_ARM7.R14_irq, 1);
- load_getu32(&NDS_ARM7.R8_fiq, 1);
- load_getu32(&NDS_ARM7.R9_fiq, 1);
- load_getu32(&NDS_ARM7.R10_fiq, 1);
- load_getu32(&NDS_ARM7.R11_fiq, 1);
- load_getu32(&NDS_ARM7.R12_fiq, 1);
- load_getu32(&NDS_ARM7.R13_fiq, 1);
- load_getu32(&NDS_ARM7.R14_fiq, 1);
- load_getsta(&NDS_ARM7.SPSR_svc, 1);
- load_getsta(&NDS_ARM7.SPSR_abt, 1);
- load_getsta(&NDS_ARM7.SPSR_und, 1);
- load_getsta(&NDS_ARM7.SPSR_irq, 1);
- load_getsta(&NDS_ARM7.SPSR_fiq, 1);
- load_getu32(&NDS_ARM7.intVector, 1);
- load_getu8(&NDS_ARM7.LDTBit, 1);
- load_getbool(&NDS_ARM7.waitIRQ, 1);
- load_getbool(&NDS_ARM7.wIRQ, 1);
- load_getbool(&NDS_ARM7.wirq, 1);
-
- /* Read ARM9 cpu registers */
- load_getu32(&NDS_ARM9.proc_ID, 1);
- load_getu32(&NDS_ARM9.instruction, 1);
- load_getu32(&NDS_ARM9.instruct_adr, 1);
- load_getu32(&NDS_ARM9.next_instruction, 1);
- load_getu32(NDS_ARM9.R, 16);
- load_getsta(&NDS_ARM9.CPSR, 1);
- load_getsta(&NDS_ARM9.SPSR, 1);
- load_getu32(&NDS_ARM9.R13_usr, 1);
- load_getu32(&NDS_ARM9.R14_usr, 1);
- load_getu32(&NDS_ARM9.R13_svc, 1);
- load_getu32(&NDS_ARM9.R14_svc, 1);
- load_getu32(&NDS_ARM9.R13_abt, 1);
- load_getu32(&NDS_ARM9.R14_abt, 1);
- load_getu32(&NDS_ARM9.R13_und, 1);
- load_getu32(&NDS_ARM9.R14_und, 1);
- load_getu32(&NDS_ARM9.R13_irq, 1);
- load_getu32(&NDS_ARM9.R14_irq, 1);
- load_getu32(&NDS_ARM9.R8_fiq, 1);
- load_getu32(&NDS_ARM9.R9_fiq, 1);
- load_getu32(&NDS_ARM9.R10_fiq, 1);
- load_getu32(&NDS_ARM9.R11_fiq, 1);
- load_getu32(&NDS_ARM9.R12_fiq, 1);
- load_getu32(&NDS_ARM9.R13_fiq, 1);
- load_getu32(&NDS_ARM9.R14_fiq, 1);
- load_getsta(&NDS_ARM9.SPSR_svc, 1);
- load_getsta(&NDS_ARM9.SPSR_abt, 1);
- load_getsta(&NDS_ARM9.SPSR_und, 1);
- load_getsta(&NDS_ARM9.SPSR_irq, 1);
- load_getsta(&NDS_ARM9.SPSR_fiq, 1);
- load_getu32(&NDS_ARM9.intVector, 1);
- load_getu8(&NDS_ARM9.LDTBit, 1);
- load_getbool(&NDS_ARM9.waitIRQ, 1);
- load_getbool(&NDS_ARM9.wIRQ, 1);
- load_getbool(&NDS_ARM9.wirq, 1);
-
- /* Read in other internal variables that are important */
- load_gets32(&nds.ARM9Cycle, 1);
- load_gets32(&nds.ARM7Cycle, 1);
- load_gets32(&nds.cycles, 1);
- load_gets32(nds.timerCycle[0], 4);
- load_gets32(nds.timerCycle[1], 4);
- load_getbool(nds.timerOver[0], 4);
- load_getbool(nds.timerOver[1], 4);
- load_gets32(&nds.nextHBlank, 1);
- load_getu32(&nds.VCount, 1);
- load_getu32(&nds.old, 1);
- load_gets32(&nds.diff, 1);
- load_getbool(&nds.lignerendu, 1);
- load_getu16(&nds.touchX, 1);
- load_getu16(&nds.touchY, 1);
-
- /* Read in memory/registers specific to the ARM9 */
- load_getu8 (ARM9Mem.ARM9_ITCM, 0x8000);
- load_getu8 (ARM9Mem.ARM9_DTCM, 0x4000);
- load_getu8 (ARM9Mem.ARM9_WRAM, 0x1000000);
- load_getu8 (ARM9Mem.MAIN_MEM, 0x400000);
- load_getu8 (ARM9Mem.ARM9_REG, 0x10000);
- load_getu8 (ARM9Mem.ARM9_VMEM, 0x800);
- load_getu8 (ARM9Mem.ARM9_OAM, 0x800);
- load_getu8 (ARM9Mem.ARM9_ABG, 0x80000);
- load_getu8 (ARM9Mem.ARM9_BBG, 0x20000);
- load_getu8 (ARM9Mem.ARM9_AOBJ, 0x40000);
- load_getu8 (ARM9Mem.ARM9_BOBJ, 0x20000);
- load_getu8 (ARM9Mem.ARM9_LCD, 0xA4000);
-
- /* Read in memory/registers specific to the ARM7 */
- load_getu8 (MMU.ARM7_ERAM, 0x10000);
- load_getu8 (MMU.ARM7_REG, 0x10000);
- load_getu8 (MMU.ARM7_WIRAM, 0x10000);
-
- /* Read in shared memory */
- load_getu8 (MMU.SWIRAM, 0x8000);
-
-#ifdef GDB_STUB
-#else
- gdb_stub_fix(&NDS_ARM9);
- gdb_stub_fix(&NDS_ARM7);
-#endif
-}
-
-static struct
-{
- unsigned char *pcmbufalloc;
- unsigned char *pcmbuftop;
- unsigned filled;
- unsigned used;
- u32 bufferbytes;
- u32 cycles;
- int xfs_load;
- int sync_type;
- int arm7_clockdown_level;
- int arm9_clockdown_level;
-} sndifwork = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
-static void SNDIFDeInit(void)
-{
- if (sndifwork.pcmbufalloc)
- {
- free(sndifwork.pcmbufalloc);
- sndifwork.pcmbufalloc = 0;
- sndifwork.pcmbuftop = 0;
- sndifwork.bufferbytes = 0;
- }
-}
-static int SNDIFInit(int buffersize)
-{
- u32 bufferbytes = buffersize * sizeof(s16);
- SNDIFDeInit();
- sndifwork.pcmbufalloc = malloc(bufferbytes + 3);
- if (!sndifwork.pcmbufalloc)
- return -1;
- sndifwork.pcmbuftop = (void *) (((uintptr_t) sndifwork.pcmbufalloc + 3) & ~3);
- sndifwork.bufferbytes = bufferbytes;
- sndifwork.filled = 0;
- sndifwork.used = 0;
- sndifwork.cycles = 0;
- return 0;
-}
-static void SNDIFMuteAudio(void)
-{
-}
-static void SNDIFUnMuteAudio(void)
-{
-}
-static void SNDIFSetVolume(int volume)
-{
-}
-static u32 SNDIFGetAudioSpace(void)
-{
- return sndifwork.bufferbytes >> 2; // bytes to samples
-}
-static void SNDIFUpdateAudio(s16 * buffer, u32 num_samples)
-{
- u32 num_bytes = num_samples << 2;
- if (num_bytes > sndifwork.bufferbytes) num_bytes = sndifwork.bufferbytes;
- memcpy(sndifwork.pcmbuftop, buffer, num_bytes);
- sndifwork.filled = num_bytes;
- sndifwork.used = 0;
-}
-#define VIO2SFSNDIFID 2
-static SoundInterface_struct VIO2SFSNDIF =
-{
- VIO2SFSNDIFID,
- "vio2sf Sound Interface",
- SNDIFInit,
- SNDIFDeInit,
- SNDIFUpdateAudio,
- SNDIFGetAudioSpace,
- SNDIFMuteAudio,
- SNDIFUnMuteAudio,
- SNDIFSetVolume
-};
-
-SoundInterface_struct *SNDCoreList[] = {
- &VIO2SFSNDIF,
- &SNDDummy,
- NULL
-};
-
-#ifdef GDB_STUB
-static struct armcpu_ctrl_iface *arm9_ctrl_iface = 0;
-static struct armcpu_ctrl_iface *arm7_ctrl_iface = 0;
-#endif
-
-int xsf_start(void *pfile, unsigned bytes)
-{
- int frames = xsf_tagget_int("_frames", pfile, bytes, -1);
- int clockdown = xsf_tagget_int("_clockdown", pfile, bytes, 0);
- sndifwork.sync_type = xsf_tagget_int("_vio2sf_sync_type", pfile, bytes, 0);
- sndifwork.arm9_clockdown_level = xsf_tagget_int("_vio2sf_arm9_clockdown_level", pfile, bytes, clockdown);
- sndifwork.arm7_clockdown_level = xsf_tagget_int("_vio2sf_arm7_clockdown_level", pfile, bytes, clockdown);
-
- sndifwork.xfs_load = 0;
- printf("load_psf... ");
- if (!load_psf(pfile, bytes))
- return XSF_FALSE;
- printf("ok!\n");
-
-#ifdef GDB_STUB
- if (NDS_Init(&arm9_base_memory_iface, &arm9_ctrl_iface, &arm7_base_memory_iface, &arm7_ctrl_iface))
-#else
- if (NDS_Init())
-#endif
- return XSF_FALSE;
-
- SPU_ChangeSoundCore(VIO2SFSNDIFID, 737);
-
- execute = FALSE;
-
- MMU_unsetRom();
- if (loaderwork.rom)
- {
- NDS_SetROM(loaderwork.rom, loaderwork.romsize - 1);
- }
-
- NDS_Reset();
-
- execute = TRUE;
-
- if (loaderwork.state)
- {
- armcp15_t *c9 = (armcp15_t *)NDS_ARM9.coproc[15];
- int proc;
- if (frames == -1)
- {
-
- /* set initial ARM9 coprocessor state */
-
- armcp15_moveARM2CP(c9, 0x00000000, 0x01, 0x00, 0, 0);
- armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x05, 0, 0);
- armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x06, 0, 0);
- armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x0a, 0, 4);
- armcp15_moveARM2CP(c9, 0x04000033, 0x06, 0x00, 0, 4);
- armcp15_moveARM2CP(c9, 0x0200002d, 0x06, 0x01, 0, 0);
- armcp15_moveARM2CP(c9, 0x027e0021, 0x06, 0x02, 0, 0);
- armcp15_moveARM2CP(c9, 0x08000035, 0x06, 0x03, 0, 0);
- armcp15_moveARM2CP(c9, 0x027e001b, 0x06, 0x04, 0, 0);
- armcp15_moveARM2CP(c9, 0x0100002f, 0x06, 0x05, 0, 0);
- armcp15_moveARM2CP(c9, 0xffff001d, 0x06, 0x06, 0, 0);
- armcp15_moveARM2CP(c9, 0x027ff017, 0x06, 0x07, 0, 0);
- armcp15_moveARM2CP(c9, 0x00000020, 0x09, 0x01, 0, 1);
-
- armcp15_moveARM2CP(c9, 0x027e000a, 0x09, 0x01, 0, 0);
-
- armcp15_moveARM2CP(c9, 0x00000042, 0x02, 0x00, 0, 1);
- armcp15_moveARM2CP(c9, 0x00000042, 0x02, 0x00, 0, 0);
- armcp15_moveARM2CP(c9, 0x00000002, 0x03, 0x00, 0, 0);
- armcp15_moveARM2CP(c9, 0x05100011, 0x05, 0x00, 0, 3);
- armcp15_moveARM2CP(c9, 0x15111011, 0x05, 0x00, 0, 2);
- armcp15_moveARM2CP(c9, 0x07dd1e10, 0x01, 0x00, 0, 0);
- armcp15_moveARM2CP(c9, 0x0005707d, 0x01, 0x00, 0, 0);
-
- armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x0a, 0, 4);
- armcp15_moveARM2CP(c9, 0x02004000, 0x07, 0x05, 0, 1);
- armcp15_moveARM2CP(c9, 0x02004000, 0x07, 0x0e, 0, 1);
-
- /* set initial timer state */
-
- MMU_write16(0, REG_TM0CNTL, 0x0000);
- MMU_write16(0, REG_TM0CNTH, 0x00C1);
- MMU_write16(1, REG_TM0CNTL, 0x0000);
- MMU_write16(1, REG_TM0CNTH, 0x00C1);
- MMU_write16(1, REG_TM1CNTL, 0xf7e7);
- MMU_write16(1, REG_TM1CNTH, 0x00C1);
-
- /* set initial interrupt state */
-
- MMU.reg_IME[0] = 0x00000001;
- MMU.reg_IE[0] = 0x00042001;
- MMU.reg_IME[1] = 0x00000001;
- MMU.reg_IE[1] = 0x0104009d;
- }
- else if (frames > 0)
- {
- /* execute boot code */
- int i;
- for (i=0; i<frames; i++)
- NDS_exec_frame(0, 0);
- i = 0;
- }
-
- /* load state */
-
- load_setstate();
- free(loaderwork.state);
- loaderwork.state = 0;
-
- if (frames == -1)
- {
- armcp15_moveARM2CP(c9, (NDS_ARM9.R13_irq & 0x0fff0000) | 0x0a, 0x09, 0x01, 0, 0);
- }
-
- /* restore timer state */
-
- for (proc = 0; proc < 2; proc++)
- {
- MMU_write16(proc, REG_TM0CNTH, T1ReadWord(MMU.MMU_MEM[proc][0x40], REG_TM0CNTH & 0xFFF));
- MMU_write16(proc, REG_TM1CNTH, T1ReadWord(MMU.MMU_MEM[proc][0x40], REG_TM1CNTH & 0xFFF));
- MMU_write16(proc, REG_TM2CNTH, T1ReadWord(MMU.MMU_MEM[proc][0x40], REG_TM2CNTH & 0xFFF));
- MMU_write16(proc, REG_TM3CNTH, T1ReadWord(MMU.MMU_MEM[proc][0x40], REG_TM3CNTH & 0xFFF));
- }
- }
- else if (frames > 0)
- {
- /* skip 1 sec */
- int i;
- for (i=0; i<frames; i++)
- NDS_exec_frame(0, 0);
- }
- execute = TRUE;
- sndifwork.xfs_load = 1;
- return XSF_TRUE;
-}
-
-int xsf_gen(void *pbuffer, unsigned samples)
-{
- unsigned char *ptr = pbuffer;
- unsigned bytes = samples <<= 2;
- if (!sndifwork.xfs_load) return 0;
- while (bytes)
- {
- unsigned remainbytes = sndifwork.filled - sndifwork.used;
- if (remainbytes > 0)
- {
- if (remainbytes > bytes)
- {
- memcpy(ptr, sndifwork.pcmbuftop + sndifwork.used, bytes);
- sndifwork.used += bytes;
- ptr += bytes;
- remainbytes -= bytes; /**/
- bytes = 0; /**/
- break;
- }
- else
- {
- memcpy(ptr, sndifwork.pcmbuftop + sndifwork.used, remainbytes);
- sndifwork.used += remainbytes;
- ptr += remainbytes;
- bytes -= remainbytes;
- remainbytes = 0;
- }
- }
- if (remainbytes == 0)
- {
-
-#define HBASE_CYCLES 33509300.322234
-#define VBASE_CYCLES (((double)HBASE_CYCLES) / 100)
-#define HSAMPLES ((u32)((44100.0 * 6 * (99 + 256)) / HBASE_CYCLES))
-#define VSAMPLES ((u32)((44100.0 * 6 * (99 + 256) * 263) / HBASE_CYCLES))
-
- int numsamples;
- if (sndifwork.sync_type == 1)
- {
- /* vsync */
- sndifwork.cycles += (441 * 6 * (99 + 256) * 263);
- if (sndifwork.cycles >= (u32)(VBASE_CYCLES * (VSAMPLES + 1)))
- {
- numsamples = (VSAMPLES + 1);
- sndifwork.cycles -= (u32)(VBASE_CYCLES * (VSAMPLES + 1));
- }
- else
- {
- numsamples = (VSAMPLES + 0);
- sndifwork.cycles -= (u32)(VBASE_CYCLES * (VSAMPLES + 0));
- }
- NDS_exec_frame(sndifwork.arm9_clockdown_level, sndifwork.arm7_clockdown_level);
- }
- else
- {
- /* hsync */
- sndifwork.cycles += (44100 * 6 * (99 + 256));
- if (sndifwork.cycles >= (u32)(HBASE_CYCLES * (HSAMPLES + 1)))
- {
- numsamples = (HSAMPLES + 1);
- sndifwork.cycles -= (u32)(HBASE_CYCLES * (HSAMPLES + 1));
- }
- else
- {
- numsamples = (HSAMPLES + 0);
- sndifwork.cycles -= (u32)(HBASE_CYCLES * (HSAMPLES + 0));
- }
- NDS_exec_hframe(sndifwork.arm9_clockdown_level, sndifwork.arm7_clockdown_level);
- }
- SPU_EmulateSamples(numsamples);
- }
- }
- return ptr - (unsigned char *)pbuffer;
-}
-
-void xsf_term(void)
-{
- MMU_unsetRom();
- NDS_DeInit();
- load_term();
-}
diff --git a/src/xsf/vio2sf.cc b/src/xsf/vio2sf.cc
new file mode 100644
index 000000000000..6359fb08ab83
--- /dev/null
+++ b/src/xsf/vio2sf.cc
@@ -0,0 +1,828 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "desmume/MMU.h"
+#include "desmume/armcpu.h"
+#include "desmume/NDSSystem.h"
+#include "desmume/SPU.h"
+#include "desmume/cp15.h"
+
+#include <zlib.h>
+
+#include <libaudcore/audstrings.h>
+
+#include "tagget.h"
+#include "vio2sf.h"
+
+volatile BOOL execute = false;
+
+static struct
+{
+ unsigned char *rom;
+ unsigned char *state;
+ unsigned romsize;
+ unsigned statesize;
+ unsigned stateptr;
+} loaderwork = {0, 0, 0, 0, 0};
+
+static void load_term(void)
+{
+ if (loaderwork.rom)
+ {
+ free(loaderwork.rom);
+ loaderwork.rom = 0;
+ }
+ loaderwork.romsize = 0;
+ if (loaderwork.state)
+ {
+ free(loaderwork.state);
+ loaderwork.state = 0;
+ }
+ loaderwork.statesize = 0;
+}
+
+static int load_map(int issave, unsigned char *udata, unsigned usize)
+{
+ unsigned char *iptr;
+ unsigned isize;
+ unsigned char *xptr;
+ unsigned xsize = getdwordle(udata + 4);
+ unsigned xofs = getdwordle(udata + 0);
+ if (issave)
+ {
+ iptr = loaderwork.state;
+ isize = loaderwork.statesize;
+ loaderwork.state = 0;
+ loaderwork.statesize = 0;
+ }
+ else
+ {
+ iptr = loaderwork.rom;
+ isize = loaderwork.romsize;
+ loaderwork.rom = 0;
+ loaderwork.romsize = 0;
+ }
+ if (!iptr)
+ {
+ iptr = (unsigned char *) malloc(xofs + xsize + 10);
+ if (!iptr)
+ return false;
+ memset(iptr, 0, xofs + xsize + 10);
+ isize = xofs + xsize;
+ }
+ else if (isize < xofs + xsize)
+ {
+ unsigned rsize = xofs + xsize;
+ if (!issave)
+ {
+ rsize -= 1;
+ rsize |= rsize >> 1;
+ rsize |= rsize >> 2;
+ rsize |= rsize >> 4;
+ rsize |= rsize >> 8;
+ rsize |= rsize >> 16;
+ rsize += 1;
+ }
+ xptr = (unsigned char *) realloc(iptr, xofs + rsize + 10);
+ if (!xptr)
+ {
+ free(iptr);
+ return false;
+ }
+ iptr = xptr;
+ isize = rsize;
+ }
+ memcpy(iptr + xofs, udata + 8, xsize);
+ if (issave)
+ {
+ loaderwork.state = iptr;
+ loaderwork.statesize = isize;
+ }
+ else
+ {
+ loaderwork.rom = iptr;
+ loaderwork.romsize = isize;
+ }
+ return true;
+}
+
+static int load_mapz(int issave, unsigned char *zdata, unsigned zsize, unsigned zcrc)
+{
+ int ret;
+ int zerr;
+ uLongf usize = 8;
+ uLongf rsize = usize;
+ unsigned char *udata;
+ unsigned char *rdata;
+
+ udata = (unsigned char *) malloc(usize);
+ if (!udata)
+ return false;
+
+ while (Z_OK != (zerr = uncompress(udata, &usize, zdata, zsize)))
+ {
+ if (Z_MEM_ERROR != zerr && Z_BUF_ERROR != zerr)
+ {
+ free(udata);
+ return false;
+ }
+ if (usize >= 8)
+ {
+ usize = getdwordle(udata + 4) + 8;
+ if (usize < rsize)
+ {
+ rsize += rsize;
+ usize = rsize;
+ }
+ else
+ rsize = usize;
+ }
+ else
+ {
+ rsize += rsize;
+ usize = rsize;
+ }
+ free(udata);
+ udata = (unsigned char *) malloc(usize);
+ if (!udata)
+ return false;
+ }
+
+ rdata = (unsigned char *) realloc(udata, usize);
+ if (!rdata)
+ {
+ free(udata);
+ return false;
+ }
+
+ if (0)
+ {
+ unsigned ccrc = crc32(crc32(0L, Z_NULL, 0), rdata, usize);
+ if (ccrc != zcrc)
+ return false;
+ }
+
+ ret = load_map(issave, rdata, usize);
+ free(rdata);
+ return ret;
+}
+
+static int load_psf_one(unsigned char *pfile, unsigned bytes)
+{
+ unsigned char *ptr = pfile;
+ unsigned code_size;
+ unsigned resv_size;
+ unsigned code_crc;
+ if (bytes < 16 || getdwordle(ptr) != 0x24465350)
+ return false;
+
+ resv_size = getdwordle(ptr + 4);
+ code_size = getdwordle(ptr + 8);
+ code_crc = getdwordle(ptr + 12);
+
+ if (resv_size)
+ {
+ unsigned resv_pos = 0;
+ ptr = pfile + 16;
+ if (16+ resv_size > bytes)
+ return false;
+ while (resv_pos + 12 < resv_size)
+ {
+ unsigned save_size = getdwordle(ptr + resv_pos + 4);
+ unsigned save_crc = getdwordle(ptr + resv_pos + 8);
+ if (getdwordle(ptr + resv_pos + 0) == 0x45564153)
+ {
+ if (resv_pos + 12 + save_size > resv_size)
+ return false;
+ if (!load_mapz(1, ptr + resv_pos + 12, save_size, save_crc))
+ return false;
+ }
+ resv_pos += 12 + save_size;
+ }
+ }
+
+ if (code_size)
+ {
+ ptr = pfile + 16 + resv_size;
+ if (16 + resv_size + code_size > bytes)
+ return false;
+ if (!load_mapz(0, ptr, code_size, code_crc))
+ return false;
+ }
+
+ return true;
+}
+
+typedef struct
+{
+ const char *tag;
+ int taglen;
+ int level;
+ int found;
+} loadlibwork_t;
+
+static int load_libs(int level, void *pfile, unsigned bytes);
+
+static int load_psfcb(void *pWork, const char *pNameTop, const char *pNameEnd, const char *pValueTop, const char *pValueEnd)
+{
+ loadlibwork_t *pwork = (loadlibwork_t *)pWork;
+ int ret = xsf_tagenum_callback_returnvaluecontinue;
+ if (pNameEnd - pNameTop == pwork->taglen && !strcmp_nocase(pNameTop, pwork->tag, pwork->taglen))
+ {
+ StringBuf lib = str_copy(pValueTop, pValueEnd - pValueTop);
+ Index<char> buf = xsf_get_lib(lib);
+
+ if (buf.len() &&
+ load_libs(pwork->level + 1, buf.begin(), buf.len()) &&
+ load_psf_one((unsigned char *) buf.begin(), buf.len()))
+ {
+ pwork->found++;
+ }
+ else
+ {
+ ret = xsf_tagenum_callback_returnvaluebreak;
+ }
+ }
+ return ret;
+}
+
+static int load_libs(int level, void *pfile, unsigned bytes)
+{
+ char tbuf[16];
+ loadlibwork_t work;
+ int n = 1;
+
+ if (level > 10)
+ return true;
+
+ work.level = level;
+ work.tag = "_lib";
+
+ do
+ {
+ work.taglen = strlen(work.tag);
+ work.found = 0;
+
+ if (xsf_tagenum(load_psfcb, &work, (unsigned char *) pfile, bytes) < 0)
+ return false;
+
+#ifdef HAVE_SPRINTF_S
+ sprintf_s(tbuf, sizeof(tbuf), "_lib%10d", ++n);
+#else
+ sprintf(tbuf, "_lib%10d", ++n);
+#endif
+ work.tag = tbuf;
+ }
+ while (work.found);
+
+ return true;
+}
+
+static int load_psf(void *pfile, unsigned bytes)
+{
+ load_term();
+
+ if (!load_libs(1, pfile, bytes) || !load_psf_one((unsigned char *) pfile, bytes))
+ return false;
+
+ return true;
+}
+
+static void load_getstateinit(unsigned ptr)
+{
+ loaderwork.stateptr = ptr;
+}
+
+static u16 getwordle(const unsigned char *pData)
+{
+ return pData[0] | (((u16)pData[1]) << 8);
+}
+
+static void load_getsta(Status_Reg *ptr, unsigned l)
+{
+ unsigned s = l << 2;
+ unsigned i;
+ if ((loaderwork.stateptr > loaderwork.statesize) || ((loaderwork.stateptr + s) > loaderwork.statesize))
+ return;
+ for (i = 0; i < l; i++)
+ {
+ u32 st = getdwordle(loaderwork.state + loaderwork.stateptr + (i << 2));
+ ptr[i].bits.N = (st >> 31) & 1;
+ ptr[i].bits.Z = (st >> 30) & 1;
+ ptr[i].bits.C = (st >> 29) & 1;
+ ptr[i].bits.V = (st >> 28) & 1;
+ ptr[i].bits.Q = (st >> 27) & 1;
+ ptr[i].bits.RAZ = (st >> 8) & ((1 << 19) - 1);
+ ptr[i].bits.I = (st >> 7) & 1;
+ ptr[i].bits.F = (st >> 6) & 1;
+ ptr[i].bits.T = (st >> 5) & 1;
+ ptr[i].bits.mode = (st >> 0) & 0x1f;
+ }
+ loaderwork.stateptr += s;
+}
+
+static void load_getbool(BOOL *ptr, unsigned l)
+{
+ unsigned s = l << 2;
+ unsigned i;
+ if ((loaderwork.stateptr > loaderwork.statesize) || ((loaderwork.stateptr + s) > loaderwork.statesize))
+ return;
+ for (i = 0; i < l; i++)
+ ptr[i] = (BOOL)getdwordle(loaderwork.state + loaderwork.stateptr + (i << 2));
+ loaderwork.stateptr += s;
+}
+
+#if defined(SIGNED_IS_NOT_2S_COMPLEMENT)
+/* 2's complement */
+#define u32tos32(v) ((s32)((((s64)(v)) ^ 0x8000) - 0x8000))
+#else
+/* 2's complement */
+#define u32tos32(v) ((s32)v)
+#endif
+
+static void load_gets32(s32 *ptr, unsigned l)
+{
+ unsigned s = l << 2;
+ unsigned i;
+ if ((loaderwork.stateptr > loaderwork.statesize) || ((loaderwork.stateptr + s) > loaderwork.statesize))
+ return;
+ for (i = 0; i < l; i++)
+ ptr[i] = u32tos32(getdwordle(loaderwork.state + loaderwork.stateptr + (i << 2)));
+ loaderwork.stateptr += s;
+}
+
+static void load_getu32(u32 *ptr, unsigned l)
+{
+ unsigned s = l << 2;
+ unsigned i;
+ if ((loaderwork.stateptr > loaderwork.statesize) || ((loaderwork.stateptr + s) > loaderwork.statesize))
+ return;
+ for (i = 0; i < l; i++)
+ ptr[i] = getdwordle(loaderwork.state + loaderwork.stateptr + (i << 2));
+ loaderwork.stateptr += s;
+}
+
+static void load_getu16(u16 *ptr, unsigned l)
+{
+ unsigned s = l << 1;
+ unsigned i;
+ if ((loaderwork.stateptr > loaderwork.statesize) || ((loaderwork.stateptr + s) > loaderwork.statesize))
+ return;
+ for (i = 0; i < l; i++)
+ ptr[i] = getwordle(loaderwork.state + loaderwork.stateptr + (i << 1));
+ loaderwork.stateptr += s;
+}
+
+static void load_getu8(u8 *ptr, unsigned l)
+{
+ unsigned s = l;
+ unsigned i;
+ if ((loaderwork.stateptr > loaderwork.statesize) || ((loaderwork.stateptr + s) > loaderwork.statesize))
+ return;
+ for (i = 0; i < l; i++)
+ ptr[i] = loaderwork.state[loaderwork.stateptr + i];
+ loaderwork.stateptr += s;
+}
+
+void gdb_stub_fix(armcpu_t *armcpu)
+{
+ /* armcpu->R[15] = armcpu->instruct_adr; */
+ armcpu->next_instruction = armcpu->instruct_adr;
+ if(armcpu->CPSR.bits.T == 0)
+ {
+ armcpu->instruction = MMU_read32_acl(armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
+ armcpu->instruct_adr = armcpu->next_instruction;
+ armcpu->next_instruction += 4;
+ armcpu->R[15] = armcpu->next_instruction + 4;
+ }
+ else
+ {
+ armcpu->instruction = MMU_read16_acl(armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
+ armcpu->instruct_adr = armcpu->next_instruction;
+ armcpu->next_instruction += 2;
+ armcpu->R[15] = armcpu->next_instruction + 2;
+ }
+}
+
+static void load_setstate(void)
+{
+ if (!loaderwork.statesize)
+ return;
+
+ /* Skip over "Desmume Save File" crap */
+ load_getstateinit(0x17);
+
+ /* Read ARM7 cpu registers */
+ load_getu32(&NDS_ARM7.proc_ID, 1);
+ load_getu32(&NDS_ARM7.instruction, 1);
+ load_getu32(&NDS_ARM7.instruct_adr, 1);
+ load_getu32(&NDS_ARM7.next_instruction, 1);
+ load_getu32(NDS_ARM7.R, 16);
+ load_getsta(&NDS_ARM7.CPSR, 1);
+ load_getsta(&NDS_ARM7.SPSR, 1);
+ load_getu32(&NDS_ARM7.R13_usr, 1);
+ load_getu32(&NDS_ARM7.R14_usr, 1);
+ load_getu32(&NDS_ARM7.R13_svc, 1);
+ load_getu32(&NDS_ARM7.R14_svc, 1);
+ load_getu32(&NDS_ARM7.R13_abt, 1);
+ load_getu32(&NDS_ARM7.R14_abt, 1);
+ load_getu32(&NDS_ARM7.R13_und, 1);
+ load_getu32(&NDS_ARM7.R14_und, 1);
+ load_getu32(&NDS_ARM7.R13_irq, 1);
+ load_getu32(&NDS_ARM7.R14_irq, 1);
+ load_getu32(&NDS_ARM7.R8_fiq, 1);
+ load_getu32(&NDS_ARM7.R9_fiq, 1);
+ load_getu32(&NDS_ARM7.R10_fiq, 1);
+ load_getu32(&NDS_ARM7.R11_fiq, 1);
+ load_getu32(&NDS_ARM7.R12_fiq, 1);
+ load_getu32(&NDS_ARM7.R13_fiq, 1);
+ load_getu32(&NDS_ARM7.R14_fiq, 1);
+ load_getsta(&NDS_ARM7.SPSR_svc, 1);
+ load_getsta(&NDS_ARM7.SPSR_abt, 1);
+ load_getsta(&NDS_ARM7.SPSR_und, 1);
+ load_getsta(&NDS_ARM7.SPSR_irq, 1);
+ load_getsta(&NDS_ARM7.SPSR_fiq, 1);
+ load_getu32(&NDS_ARM7.intVector, 1);
+ load_getu8(&NDS_ARM7.LDTBit, 1);
+ load_getbool(&NDS_ARM7.waitIRQ, 1);
+ load_getbool(&NDS_ARM7.wIRQ, 1);
+ load_getbool(&NDS_ARM7.wirq, 1);
+
+ /* Read ARM9 cpu registers */
+ load_getu32(&NDS_ARM9.proc_ID, 1);
+ load_getu32(&NDS_ARM9.instruction, 1);
+ load_getu32(&NDS_ARM9.instruct_adr, 1);
+ load_getu32(&NDS_ARM9.next_instruction, 1);
+ load_getu32(NDS_ARM9.R, 16);
+ load_getsta(&NDS_ARM9.CPSR, 1);
+ load_getsta(&NDS_ARM9.SPSR, 1);
+ load_getu32(&NDS_ARM9.R13_usr, 1);
+ load_getu32(&NDS_ARM9.R14_usr, 1);
+ load_getu32(&NDS_ARM9.R13_svc, 1);
+ load_getu32(&NDS_ARM9.R14_svc, 1);
+ load_getu32(&NDS_ARM9.R13_abt, 1);
+ load_getu32(&NDS_ARM9.R14_abt, 1);
+ load_getu32(&NDS_ARM9.R13_und, 1);
+ load_getu32(&NDS_ARM9.R14_und, 1);
+ load_getu32(&NDS_ARM9.R13_irq, 1);
+ load_getu32(&NDS_ARM9.R14_irq, 1);
+ load_getu32(&NDS_ARM9.R8_fiq, 1);
+ load_getu32(&NDS_ARM9.R9_fiq, 1);
+ load_getu32(&NDS_ARM9.R10_fiq, 1);
+ load_getu32(&NDS_ARM9.R11_fiq, 1);
+ load_getu32(&NDS_ARM9.R12_fiq, 1);
+ load_getu32(&NDS_ARM9.R13_fiq, 1);
+ load_getu32(&NDS_ARM9.R14_fiq, 1);
+ load_getsta(&NDS_ARM9.SPSR_svc, 1);
+ load_getsta(&NDS_ARM9.SPSR_abt, 1);
+ load_getsta(&NDS_ARM9.SPSR_und, 1);
+ load_getsta(&NDS_ARM9.SPSR_irq, 1);
+ load_getsta(&NDS_ARM9.SPSR_fiq, 1);
+ load_getu32(&NDS_ARM9.intVector, 1);
+ load_getu8(&NDS_ARM9.LDTBit, 1);
+ load_getbool(&NDS_ARM9.waitIRQ, 1);
+ load_getbool(&NDS_ARM9.wIRQ, 1);
+ load_getbool(&NDS_ARM9.wirq, 1);
+
+ /* Read in other internal variables that are important */
+ load_gets32(&nds.ARM9Cycle, 1);
+ load_gets32(&nds.ARM7Cycle, 1);
+ load_gets32(&nds.cycles, 1);
+ load_gets32(nds.timerCycle[0], 4);
+ load_gets32(nds.timerCycle[1], 4);
+ load_getbool(nds.timerOver[0], 4);
+ load_getbool(nds.timerOver[1], 4);
+ load_gets32(&nds.nextHBlank, 1);
+ load_getu32(&nds.VCount, 1);
+ load_getu32(&nds.old, 1);
+ load_gets32(&nds.diff, 1);
+ load_getbool(&nds.lignerendu, 1);
+ load_getu16(&nds.touchX, 1);
+ load_getu16(&nds.touchY, 1);
+
+ /* Read in memory/registers specific to the ARM9 */
+ load_getu8 (ARM9Mem.ARM9_ITCM, 0x8000);
+ load_getu8 (ARM9Mem.ARM9_DTCM, 0x4000);
+ load_getu8 (ARM9Mem.ARM9_WRAM, 0x1000000);
+ load_getu8 (ARM9Mem.MAIN_MEM, 0x400000);
+ load_getu8 (ARM9Mem.ARM9_REG, 0x10000);
+ load_getu8 (ARM9Mem.ARM9_VMEM, 0x800);
+ load_getu8 (ARM9Mem.ARM9_OAM, 0x800);
+ load_getu8 (ARM9Mem.ARM9_ABG, 0x80000);
+ load_getu8 (ARM9Mem.ARM9_BBG, 0x20000);
+ load_getu8 (ARM9Mem.ARM9_AOBJ, 0x40000);
+ load_getu8 (ARM9Mem.ARM9_BOBJ, 0x20000);
+ load_getu8 (ARM9Mem.ARM9_LCD, 0xA4000);
+
+ /* Read in memory/registers specific to the ARM7 */
+ load_getu8 (MMU.ARM7_ERAM, 0x10000);
+ load_getu8 (MMU.ARM7_REG, 0x10000);
+ load_getu8 (MMU.ARM7_WIRAM, 0x10000);
+
+ /* Read in shared memory */
+ load_getu8 (MMU.SWIRAM, 0x8000);
+
+#ifdef GDB_STUB
+#else
+ gdb_stub_fix(&NDS_ARM9);
+ gdb_stub_fix(&NDS_ARM7);
+#endif
+}
+
+static struct
+{
+ unsigned char *pcmbufalloc;
+ unsigned char *pcmbuftop;
+ unsigned filled;
+ unsigned used;
+ u32 bufferbytes;
+ u32 cycles;
+ int xfs_load;
+ int sync_type;
+ int arm7_clockdown_level;
+ int arm9_clockdown_level;
+} sndifwork = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+static void SNDIFDeInit(void)
+{
+ if (sndifwork.pcmbufalloc)
+ {
+ free(sndifwork.pcmbufalloc);
+ sndifwork.pcmbufalloc = 0;
+ sndifwork.pcmbuftop = 0;
+ sndifwork.bufferbytes = 0;
+ }
+}
+static int SNDIFInit(int buffersize)
+{
+ u32 bufferbytes = buffersize * sizeof(s16);
+ SNDIFDeInit();
+ sndifwork.pcmbufalloc = (unsigned char *) malloc(bufferbytes + 3);
+ if (!sndifwork.pcmbufalloc)
+ return -1;
+ sndifwork.pcmbuftop = (unsigned char *) (((uintptr_t) sndifwork.pcmbufalloc + 3) & ~3);
+ sndifwork.bufferbytes = bufferbytes;
+ sndifwork.filled = 0;
+ sndifwork.used = 0;
+ sndifwork.cycles = 0;
+ return 0;
+}
+static void SNDIFMuteAudio(void)
+{
+}
+static void SNDIFUnMuteAudio(void)
+{
+}
+static void SNDIFSetVolume(int volume)
+{
+}
+static u32 SNDIFGetAudioSpace(void)
+{
+ return sndifwork.bufferbytes >> 2; // bytes to samples
+}
+static void SNDIFUpdateAudio(s16 * buffer, u32 num_samples)
+{
+ u32 num_bytes = num_samples << 2;
+ if (num_bytes > sndifwork.bufferbytes) num_bytes = sndifwork.bufferbytes;
+ memcpy(sndifwork.pcmbuftop, buffer, num_bytes);
+ sndifwork.filled = num_bytes;
+ sndifwork.used = 0;
+}
+#define VIO2SFSNDIFID 2
+static SoundInterface_struct VIO2SFSNDIF =
+{
+ VIO2SFSNDIFID,
+ "vio2sf Sound Interface",
+ SNDIFInit,
+ SNDIFDeInit,
+ SNDIFUpdateAudio,
+ SNDIFGetAudioSpace,
+ SNDIFMuteAudio,
+ SNDIFUnMuteAudio,
+ SNDIFSetVolume
+};
+
+SoundInterface_struct *SNDCoreList[] = {
+ &VIO2SFSNDIF,
+ &SNDDummy,
+ nullptr
+};
+
+#ifdef GDB_STUB
+static struct armcpu_ctrl_iface *arm9_ctrl_iface = 0;
+static struct armcpu_ctrl_iface *arm7_ctrl_iface = 0;
+#endif
+
+int xsf_start(void *pfile, unsigned bytes)
+{
+ int frames = xsf_tagget_int("_frames", (unsigned char *) pfile, bytes, -1);
+ int clockdown = xsf_tagget_int("_clockdown", (unsigned char *) pfile, bytes, 0);
+ sndifwork.sync_type = xsf_tagget_int("_vio2sf_sync_type", (unsigned char *) pfile, bytes, 0);
+ sndifwork.arm9_clockdown_level = xsf_tagget_int("_vio2sf_arm9_clockdown_level", (unsigned char *) pfile, bytes, clockdown);
+ sndifwork.arm7_clockdown_level = xsf_tagget_int("_vio2sf_arm7_clockdown_level", (unsigned char *) pfile, bytes, clockdown);
+
+ sndifwork.xfs_load = 0;
+ printf("load_psf... ");
+ if (!load_psf(pfile, bytes))
+ return false;
+ printf("ok!\n");
+
+#ifdef GDB_STUB
+ if (NDS_Init(&arm9_base_memory_iface, &arm9_ctrl_iface, &arm7_base_memory_iface, &arm7_ctrl_iface))
+#else
+ if (NDS_Init())
+#endif
+ return false;
+
+ SPU_ChangeSoundCore(VIO2SFSNDIFID, 737);
+
+ execute = false;
+
+ MMU_unsetRom();
+ if (loaderwork.rom)
+ {
+ NDS_SetROM(loaderwork.rom, loaderwork.romsize - 1);
+ }
+
+ NDS_Reset();
+
+ execute = true;
+
+ if (loaderwork.state)
+ {
+ armcp15_t *c9 = (armcp15_t *)NDS_ARM9.coproc[15];
+ int proc;
+ if (frames == -1)
+ {
+
+ /* set initial ARM9 coprocessor state */
+
+ armcp15_moveARM2CP(c9, 0x00000000, 0x01, 0x00, 0, 0);
+ armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x05, 0, 0);
+ armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x06, 0, 0);
+ armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x0a, 0, 4);
+ armcp15_moveARM2CP(c9, 0x04000033, 0x06, 0x00, 0, 4);
+ armcp15_moveARM2CP(c9, 0x0200002d, 0x06, 0x01, 0, 0);
+ armcp15_moveARM2CP(c9, 0x027e0021, 0x06, 0x02, 0, 0);
+ armcp15_moveARM2CP(c9, 0x08000035, 0x06, 0x03, 0, 0);
+ armcp15_moveARM2CP(c9, 0x027e001b, 0x06, 0x04, 0, 0);
+ armcp15_moveARM2CP(c9, 0x0100002f, 0x06, 0x05, 0, 0);
+ armcp15_moveARM2CP(c9, 0xffff001d, 0x06, 0x06, 0, 0);
+ armcp15_moveARM2CP(c9, 0x027ff017, 0x06, 0x07, 0, 0);
+ armcp15_moveARM2CP(c9, 0x00000020, 0x09, 0x01, 0, 1);
+
+ armcp15_moveARM2CP(c9, 0x027e000a, 0x09, 0x01, 0, 0);
+
+ armcp15_moveARM2CP(c9, 0x00000042, 0x02, 0x00, 0, 1);
+ armcp15_moveARM2CP(c9, 0x00000042, 0x02, 0x00, 0, 0);
+ armcp15_moveARM2CP(c9, 0x00000002, 0x03, 0x00, 0, 0);
+ armcp15_moveARM2CP(c9, 0x05100011, 0x05, 0x00, 0, 3);
+ armcp15_moveARM2CP(c9, 0x15111011, 0x05, 0x00, 0, 2);
+ armcp15_moveARM2CP(c9, 0x07dd1e10, 0x01, 0x00, 0, 0);
+ armcp15_moveARM2CP(c9, 0x0005707d, 0x01, 0x00, 0, 0);
+
+ armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x0a, 0, 4);
+ armcp15_moveARM2CP(c9, 0x02004000, 0x07, 0x05, 0, 1);
+ armcp15_moveARM2CP(c9, 0x02004000, 0x07, 0x0e, 0, 1);
+
+ /* set initial timer state */
+
+ MMU_write16(0, REG_TM0CNTL, 0x0000);
+ MMU_write16(0, REG_TM0CNTH, 0x00C1);
+ MMU_write16(1, REG_TM0CNTL, 0x0000);
+ MMU_write16(1, REG_TM0CNTH, 0x00C1);
+ MMU_write16(1, REG_TM1CNTL, 0xf7e7);
+ MMU_write16(1, REG_TM1CNTH, 0x00C1);
+
+ /* set initial interrupt state */
+
+ MMU.reg_IME[0] = 0x00000001;
+ MMU.reg_IE[0] = 0x00042001;
+ MMU.reg_IME[1] = 0x00000001;
+ MMU.reg_IE[1] = 0x0104009d;
+ }
+ else if (frames > 0)
+ {
+ /* execute boot code */
+ int i;
+ for (i=0; i<frames; i++)
+ NDS_exec_frame(0, 0);
+ i = 0;
+ }
+
+ /* load state */
+
+ load_setstate();
+ free(loaderwork.state);
+ loaderwork.state = 0;
+
+ if (frames == -1)
+ {
+ armcp15_moveARM2CP(c9, (NDS_ARM9.R13_irq & 0x0fff0000) | 0x0a, 0x09, 0x01, 0, 0);
+ }
+
+ /* restore timer state */
+
+ for (proc = 0; proc < 2; proc++)
+ {
+ MMU_write16(proc, REG_TM0CNTH, T1ReadWord(MMU.MMU_MEM[proc][0x40], REG_TM0CNTH & 0xFFF));
+ MMU_write16(proc, REG_TM1CNTH, T1ReadWord(MMU.MMU_MEM[proc][0x40], REG_TM1CNTH & 0xFFF));
+ MMU_write16(proc, REG_TM2CNTH, T1ReadWord(MMU.MMU_MEM[proc][0x40], REG_TM2CNTH & 0xFFF));
+ MMU_write16(proc, REG_TM3CNTH, T1ReadWord(MMU.MMU_MEM[proc][0x40], REG_TM3CNTH & 0xFFF));
+ }
+ }
+ else if (frames > 0)
+ {
+ /* skip 1 sec */
+ int i;
+ for (i=0; i<frames; i++)
+ NDS_exec_frame(0, 0);
+ }
+ execute = true;
+ sndifwork.xfs_load = 1;
+ return true;
+}
+
+int xsf_gen(void *pbuffer, unsigned samples)
+{
+ unsigned char *ptr = (unsigned char *) pbuffer;
+ unsigned bytes = samples <<= 2;
+ if (!sndifwork.xfs_load) return 0;
+ while (bytes)
+ {
+ unsigned remainbytes = sndifwork.filled - sndifwork.used;
+ if (remainbytes > 0)
+ {
+ if (remainbytes > bytes)
+ {
+ memcpy(ptr, sndifwork.pcmbuftop + sndifwork.used, bytes);
+ sndifwork.used += bytes;
+ ptr += bytes;
+ remainbytes -= bytes; /**/
+ bytes = 0; /**/
+ break;
+ }
+ else
+ {
+ memcpy(ptr, sndifwork.pcmbuftop + sndifwork.used, remainbytes);
+ sndifwork.used += remainbytes;
+ ptr += remainbytes;
+ bytes -= remainbytes;
+ remainbytes = 0;
+ }
+ }
+ if (remainbytes == 0)
+ {
+
+#define HBASE_CYCLES 33509300.322234
+#define VBASE_CYCLES (((double)HBASE_CYCLES) / 100)
+#define HSAMPLES ((u32)((44100.0 * 6 * (99 + 256)) / HBASE_CYCLES))
+#define VSAMPLES ((u32)((44100.0 * 6 * (99 + 256) * 263) / HBASE_CYCLES))
+
+ int numsamples;
+ if (sndifwork.sync_type == 1)
+ {
+ /* vsync */
+ sndifwork.cycles += (441 * 6 * (99 + 256) * 263);
+ if (sndifwork.cycles >= (u32)(VBASE_CYCLES * (VSAMPLES + 1)))
+ {
+ numsamples = (VSAMPLES + 1);
+ sndifwork.cycles -= (u32)(VBASE_CYCLES * (VSAMPLES + 1));
+ }
+ else
+ {
+ numsamples = (VSAMPLES + 0);
+ sndifwork.cycles -= (u32)(VBASE_CYCLES * (VSAMPLES + 0));
+ }
+ NDS_exec_frame(sndifwork.arm9_clockdown_level, sndifwork.arm7_clockdown_level);
+ }
+ else
+ {
+ /* hsync */
+ sndifwork.cycles += (44100 * 6 * (99 + 256));
+ if (sndifwork.cycles >= (u32)(HBASE_CYCLES * (HSAMPLES + 1)))
+ {
+ numsamples = (HSAMPLES + 1);
+ sndifwork.cycles -= (u32)(HBASE_CYCLES * (HSAMPLES + 1));
+ }
+ else
+ {
+ numsamples = (HSAMPLES + 0);
+ sndifwork.cycles -= (u32)(HBASE_CYCLES * (HSAMPLES + 0));
+ }
+ NDS_exec_hframe(sndifwork.arm9_clockdown_level, sndifwork.arm7_clockdown_level);
+ }
+ SPU_EmulateSamples(numsamples);
+ }
+ }
+ return ptr - (unsigned char *)pbuffer;
+}
+
+void xsf_term(void)
+{
+ MMU_unsetRom();
+ NDS_DeInit();
+ load_term();
+}
diff --git a/src/xsf/vio2sf.h b/src/xsf/vio2sf.h
index 1415436311fc..542f7160e603 100644
--- a/src/xsf/vio2sf.h
+++ b/src/xsf/vio2sf.h
@@ -1,7 +1,6 @@
-#define XSF_FALSE (0)
-#define XSF_TRUE (!XSF_FALSE)
+#include <libaudcore/index.h>
int xsf_start(void *pfile, unsigned bytes);
int xsf_gen(void *pbuffer, unsigned samples);
-int xsf_get_lib(char *pfilename, void **ppbuffer, unsigned int *plength);
+Index<char> xsf_get_lib(char *pfilename);
void xsf_term(void);
diff --git a/src/xsf/xsfdrv.h b/src/xsf/xsfdrv.h
index a1c7300c01ab..afcb17adba73 100644
--- a/src/xsf/xsfdrv.h
+++ b/src/xsf/xsfdrv.h
@@ -1,7 +1,3 @@
-#ifdef __cplusplus
-extern "C" {
-#endif
-
typedef int (PASCAL * LPFNGETLIB_XSFDRV)(void *lpWork, LPSTR lpszFilename, void **ppBuffer, DWORD *pdwSize);
typedef struct
{
@@ -14,8 +10,3 @@ typedef struct
typedef IXSFDRV * (PASCAL * LPFNXSFDRVSETUP)(LPFNGETLIB_XSFDRV lpfn, void *lpWork);
/* IXSFDRV * PASCAL XSFDRVSetup(LPFNGETLIB_XSFDRV lpfn, void *lpWork); */
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/src/xspf/Makefile b/src/xspf/Makefile
index 4443d5014e05..9a1771ae84bb 100644
--- a/src/xspf/Makefile
+++ b/src/xspf/Makefile
@@ -1,12 +1,14 @@
PLUGIN = xspf${PLUGIN_SUFFIX}
-SRCS = xspf.c
+SRCS = xspf.cc
include ../../buildsys.mk
include ../../extra.mk
plugindir := ${plugindir}/${CONTAINER_PLUGIN_DIR}
+LD = ${CXX}
+
CFLAGS += ${PLUGIN_CFLAGS}
CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${XML_CFLAGS} -I../..
LIBS += ${GLIB_LIBS} ${XML_LIBS}
diff --git a/src/xspf/xspf.c b/src/xspf/xspf.c
deleted file mode 100644
index e513a029a1a2..000000000000
--- a/src/xspf/xspf.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Audacious: A cross-platform multimedia player
- * Copyright (c) 2006 William Pitcock, Tony Vroon, George Averill,
- * Giacomo Lozito, Derek Pomery, Yoshiki Yazawa
- * and Matti Hämäläinen.
- * Copyright (c) 2011 John Lindgren
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <glib.h>
-#include <string.h>
-
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/xmlreader.h>
-#include <libxml/xmlsave.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-#include <libxml/uri.h>
-
-#include <audacious/i18n.h>
-#include <audacious/plugin.h>
-#include <libaudcore/audstrings.h>
-
-#define XSPF_ROOT_NODE_NAME "playlist"
-#define XSPF_XMLNS "http://xspf.org/ns/0/"
-
-typedef struct {
- gint tupleField;
- gchar *xspfName;
- TupleValueType type;
- gboolean isMeta;
-} xspf_entry_t;
-
-
-static const xspf_entry_t xspf_entries[] = {
- { FIELD_ARTIST, "creator", TUPLE_STRING, FALSE},
- { FIELD_TITLE, "title", TUPLE_STRING, FALSE},
- { FIELD_ALBUM, "album", TUPLE_STRING, FALSE},
- { FIELD_COMMENT, "annotation", TUPLE_STRING, FALSE},
- { FIELD_GENRE, "genre", TUPLE_STRING, TRUE},
-
- { FIELD_TRACK_NUMBER, "trackNum", TUPLE_INT, FALSE},
- { FIELD_LENGTH, "duration", TUPLE_INT, FALSE},
- { FIELD_YEAR, "year", TUPLE_INT, TRUE},
- { FIELD_QUALITY, "quality", TUPLE_STRING, TRUE},
-
- { FIELD_CODEC, "codec", TUPLE_STRING, TRUE},
-
- { FIELD_SONG_ARTIST, "song-artist", TUPLE_STRING, TRUE},
- { FIELD_COMPOSER, "composer", TUPLE_STRING, TRUE},
- { FIELD_PERFORMER, "performer", TUPLE_STRING, TRUE},
- { FIELD_COPYRIGHT, "copyright", TUPLE_STRING, TRUE},
- { FIELD_DATE, "date", TUPLE_STRING, TRUE},
-
- { FIELD_SUBSONG_ID, "subsong-id", TUPLE_INT, TRUE},
- { FIELD_SUBSONG_NUM, "subsong-num", TUPLE_INT, TRUE},
- { FIELD_MIMETYPE, "mime-type", TUPLE_STRING, TRUE},
- { FIELD_BITRATE, "bitrate", TUPLE_INT, TRUE},
- { FIELD_SEGMENT_START,"seg-start", TUPLE_INT, TRUE},
- { FIELD_SEGMENT_END, "seg-end", TUPLE_INT, TRUE},
-
- { FIELD_GAIN_ALBUM_GAIN, "gain-album-gain", TUPLE_INT, TRUE},
- { FIELD_GAIN_ALBUM_PEAK, "gain-album-peak", TUPLE_INT, TRUE},
- { FIELD_GAIN_TRACK_GAIN, "gain-track-gain", TUPLE_INT, TRUE},
- { FIELD_GAIN_TRACK_PEAK, "gain-track-peak", TUPLE_INT, TRUE},
- { FIELD_GAIN_GAIN_UNIT, "gain-gain-unit", TUPLE_INT, TRUE},
- { FIELD_GAIN_PEAK_UNIT, "gain-peak-unit", TUPLE_INT, TRUE},
-};
-
-static void xspf_add_file (xmlNode * track, const gchar * filename, const gchar
- * base, Index * filenames, Index * tuples)
-{
- xmlNode *nptr;
- gchar *location = NULL;
- Tuple * tuple = NULL;
-
- for (nptr = track->children; nptr != NULL; nptr = nptr->next) {
- if (nptr->type == XML_ELEMENT_NODE) {
- if (!xmlStrcmp(nptr->name, (xmlChar *)"location")) {
- /* Location is a special case */
- gchar *str = (gchar *)xmlNodeGetContent(nptr);
-
- if (strstr (str, "://") != NULL)
- location = str_get (str);
- else if (str[0] == '/' && base != NULL)
- {
- const gchar * colon = strstr (base, "://");
-
- if (colon != NULL)
- location = str_printf ("%.*s%s", (gint) (colon + 3 -
- base), base, str);
- }
- else if (base != NULL)
- {
- const gchar * slash = strrchr (base, '/');
-
- if (slash != NULL)
- location = str_printf ("%.*s%s", (gint) (slash + 1 -
- base), base, str);
- }
-
- xmlFree(str);
- } else {
- /* Rest of the nodes are handled here */
- gint i;
- gboolean isMeta;
- xmlChar *findName;
-
- if (!xmlStrcmp(nptr->name, (xmlChar *)"meta")) {
- isMeta = TRUE;
- findName = xmlGetProp(nptr, (xmlChar *)"rel");
- } else {
- isMeta = FALSE;
- findName = xmlStrdup(nptr->name);
- }
-
- for (i = 0; i < ARRAY_LEN (xspf_entries); i++)
- if ((xspf_entries[i].isMeta == isMeta) &&
- !xmlStrcmp(findName, (xmlChar *)xspf_entries[i].xspfName)) {
- xmlChar *str = xmlNodeGetContent(nptr);
- switch (xspf_entries[i].type) {
- case TUPLE_STRING:
- if (! tuple)
- tuple = tuple_new ();
- tuple_set_str(tuple, xspf_entries[i].tupleField, (gchar *)str);
- break;
-
- case TUPLE_INT:
- if (! tuple)
- tuple = tuple_new ();
- tuple_set_int(tuple, xspf_entries[i].tupleField, atol((char *)str));
- break;
-
- default:
- break;
- }
- xmlFree(str);
- break;
- }
-
- xmlFree(findName);
- }
- }
- }
-
- if (location != NULL)
- {
- if (tuple)
- tuple_set_filename (tuple, location);
-
- index_insert (filenames, -1, location);
- index_insert (tuples, -1, tuple);
- }
- else if (tuple)
- tuple_unref (tuple);
-}
-
-
-static void xspf_find_track (xmlNode * tracklist, const gchar * filename, const
- gchar * base, Index * filenames, Index * tuples)
-{
- xmlNode *nptr;
-
- for (nptr = tracklist->children; nptr != NULL; nptr = nptr->next) {
- if (nptr->type == XML_ELEMENT_NODE &&
- ! xmlStrcmp (nptr->name, (xmlChar *) "track"))
- xspf_add_file (nptr, filename, base, filenames, tuples);
- }
-}
-
-static gint read_cb (void * file, gchar * buf, gint len)
-{
- return vfs_fread (buf, 1, len, file);
-}
-
-static gint write_cb (void * file, const gchar * buf, gint len)
-{
- return vfs_fwrite (buf, 1, len, file);
-}
-
-static gint close_cb (void * file)
-{
- return 0;
-}
-
-static gboolean xspf_playlist_load (const gchar * filename, VFSFile * file,
- gchar * * title, Index * filenames, Index * tuples)
-{
- xmlDoc * doc = xmlReadIO (read_cb, close_cb, file, filename, NULL,
- XML_PARSE_RECOVER);
- if (! doc)
- return FALSE;
-
- * title = NULL;
-
- xmlNode *nptr, *nptr2;
-
- // find trackList
- for (nptr = doc->children; nptr != NULL; nptr = nptr->next) {
- if (nptr->type == XML_ELEMENT_NODE &&
- !xmlStrcmp(nptr->name, (xmlChar *)"playlist")) {
- gchar * base;
-
- base = (gchar *)xmlNodeGetBase(doc, nptr);
-
- for (nptr2 = nptr->children; nptr2; nptr2 = nptr2->next)
- {
- if (nptr2->type != XML_ELEMENT_NODE)
- continue;
-
- if (! xmlStrcmp (nptr2->name, (xmlChar *) "title"))
- {
- xmlChar * xml_title = xmlNodeGetContent (nptr2);
- if (xml_title && xml_title[0])
- {
- str_unref (* title);
- * title = str_get ((gchar *) xml_title);
- }
- xmlFree (xml_title);
- }
- else if (! xmlStrcmp (nptr2->name, (xmlChar *) "trackList"))
- xspf_find_track (nptr2, filename, base, filenames, tuples);
- }
-
- xmlFree (base);
- }
- }
-
- xmlFreeDoc(doc);
- return TRUE;
-}
-
-
-#define IS_VALID_CHAR(c) (((c) >= 0x20 && (c) <= 0xd7ff) || \
- ((c) == 0x9) || \
- ((c) == 0xa) || \
- ((c) == 0xd) || \
- ((c) >= 0xe000 && (c) <= 0xfffd) || \
- ((c) >= 0x10000 && (c) <= 0x10ffff))
-
-/* check for characters that are invalid in XML */
-static gboolean is_valid_string (const gchar * s, gchar * * subst)
-{
- if (! g_utf8_validate (s, -1, NULL))
- goto NOT_VALID;
-
- const gchar * p = s;
- while (* p)
- {
- gunichar c = g_utf8_get_char (p);
-
- if (IS_VALID_CHAR (c))
- p = g_utf8_next_char (p);
- else
- goto NOT_VALID;
- }
-
- return TRUE;
-
-NOT_VALID:;
- gint len = 0;
-
- p = s;
- while (* p)
- {
- gunichar c = g_utf8_get_char_validated (p, -1);
-
- if (IS_VALID_CHAR (c))
- {
- len += g_unichar_to_utf8 (c, NULL);
- p = g_utf8_next_char (p);
- }
- else
- p ++;
- }
-
- * subst = g_malloc (len + 1);
- gchar * w = * subst;
-
- p = s;
- while (* p)
- {
- gunichar c = g_utf8_get_char_validated (p, -1);
-
- if (IS_VALID_CHAR (c))
- {
- w += g_unichar_to_utf8 (c, w);
- p = g_utf8_next_char (p);
- }
- else
- p ++;
- }
-
- * w = 0;
- return FALSE;
-}
-
-
-static void xspf_add_node(xmlNodePtr node, TupleValueType type,
- gboolean isMeta, const gchar *xspfName, const gchar *strVal,
- const gint intVal)
-{
- gchar tmps[64];
- xmlNodePtr tmp;
-
- if (isMeta) {
- tmp = xmlNewNode(NULL, (xmlChar *) "meta");
- xmlSetProp(tmp, (xmlChar *) "rel", (xmlChar *) xspfName);
- } else
- tmp = xmlNewNode(NULL, (xmlChar *) xspfName);
-
- switch (type) {
- case TUPLE_STRING:;
- gchar * subst;
- if (is_valid_string (strVal, & subst))
- xmlAddChild (tmp, xmlNewText ((xmlChar *) strVal));
- else
- {
- xmlAddChild (tmp, xmlNewText ((xmlChar *) subst));
- g_free (subst);
- }
- break;
-
- case TUPLE_INT:
- str_itoa (intVal, tmps, sizeof tmps);
- xmlAddChild(tmp, xmlNewText((xmlChar *) tmps));
- break;
-
- default:
- break;
- }
-
- xmlAddChild(node, tmp);
-}
-
-
-static gboolean xspf_playlist_save (const gchar * filename, VFSFile * file,
- const gchar * title, Index * filenames, Index * tuples)
-{
- gint entries = index_count (filenames);
- xmlDocPtr doc;
- xmlNodePtr rootnode, tracklist;
- gint count;
-
- doc = xmlNewDoc((xmlChar *)"1.0");
- doc->charset = XML_CHAR_ENCODING_UTF8;
- doc->encoding = xmlStrdup((xmlChar *)"UTF-8");
-
- rootnode = xmlNewNode(NULL, (xmlChar *)XSPF_ROOT_NODE_NAME);
- xmlSetProp(rootnode, (xmlChar *)"version", (xmlChar *)"1");
- xmlSetProp(rootnode, (xmlChar *)"xmlns", (xmlChar *)XSPF_XMLNS);
-
- /* common */
- xmlDocSetRootElement(doc, rootnode);
-
- if (title)
- xspf_add_node (rootnode, TUPLE_STRING, FALSE, "title", title, 0);
-
- tracklist = xmlNewNode(NULL, (xmlChar *)"trackList");
- xmlAddChild(rootnode, tracklist);
-
- for (count = 0; count < entries; count ++)
- {
- const gchar * filename = index_get (filenames, count);
- const Tuple * tuple = index_get (tuples, count);
- xmlNodePtr track, location;
- gchar *scratch = NULL;
- gint scratchi = 0;
-
- track = xmlNewNode(NULL, (xmlChar *)"track");
- location = xmlNewNode(NULL, (xmlChar *)"location");
-
- xmlAddChild(location, xmlNewText((xmlChar *)filename));
- xmlAddChild(track, location);
- xmlAddChild(tracklist, track);
-
- if (tuple != NULL)
- {
- gint i;
- for (i = 0; i < ARRAY_LEN (xspf_entries); i++) {
- const xspf_entry_t *xs = &xspf_entries[i];
- gboolean isOK = (tuple_get_value_type (tuple, xs->tupleField) == xs->type);
-
- switch (xs->type) {
- case TUPLE_STRING:
- scratch = tuple_get_str (tuple, xs->tupleField);
- if (! scratch)
- isOK = FALSE;
- str_unref(scratch);
- break;
- case TUPLE_INT:
- scratchi = tuple_get_int (tuple, xs->tupleField);
- break;
- default:
- break;
- }
-
- if (isOK)
- xspf_add_node(track, xs->type, xs->isMeta, xs->xspfName, scratch, scratchi);
- }
- }
- }
-
- xmlSaveCtxt * save = xmlSaveToIO (write_cb, close_cb, file, NULL,
- XML_SAVE_FORMAT);
- if (! save)
- goto ERR;
-
- if (xmlSaveDoc (save, doc) < 0 || xmlSaveClose (save) < 0)
- goto ERR;
-
- xmlFreeDoc(doc);
- return TRUE;
-
-ERR:
- xmlFreeDoc (doc);
- return FALSE;
-}
-
-static const gchar * const xspf_exts[] = {"xspf", NULL};
-
-AUD_PLAYLIST_PLUGIN
-(
- .name = N_("XML Shareable Playlists (XSPF)"),
- .domain = PACKAGE,
- .extensions = xspf_exts,
- .load = xspf_playlist_load,
- .save = xspf_playlist_save
-)
diff --git a/src/xspf/xspf.cc b/src/xspf/xspf.cc
new file mode 100644
index 000000000000..67b71b7c279e
--- /dev/null
+++ b/src/xspf/xspf.cc
@@ -0,0 +1,429 @@
+/*
+ * Audacious: A cross-platform multimedia player
+ * Copyright (c) 2006 William Pitcock, Tony Vroon, George Averill,
+ * Giacomo Lozito, Derek Pomery, Yoshiki Yazawa
+ * and Matti Hämäläinen.
+ * Copyright (c) 2011 John Lindgren
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <string.h>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xmlreader.h>
+#include <libxml/xmlsave.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/uri.h>
+
+#include <libaudcore/i18n.h>
+#include <libaudcore/plugin.h>
+#include <libaudcore/audstrings.h>
+
+#define XSPF_ROOT_NODE_NAME "playlist"
+#define XSPF_XMLNS "http://xspf.org/ns/0/"
+
+typedef struct {
+ Tuple::Field tupleField;
+ const char *xspfName;
+ Tuple::ValueType type;
+ bool isMeta;
+} xspf_entry_t;
+
+
+static const xspf_entry_t xspf_entries[] = {
+ {Tuple::Artist, "creator", Tuple::String, false},
+ {Tuple::Title, "title", Tuple::String, false},
+ {Tuple::Album, "album", Tuple::String, false},
+ {Tuple::Comment, "annotation", Tuple::String, false},
+ {Tuple::Genre, "genre", Tuple::String, true},
+
+ {Tuple::Track, "trackNum", Tuple::Int, false},
+ {Tuple::Length, "duration", Tuple::Int, false},
+ {Tuple::Year, "year", Tuple::Int, true},
+ {Tuple::Quality, "quality", Tuple::String, true},
+
+ {Tuple::Codec, "codec", Tuple::String, true},
+
+ {Tuple::AlbumArtist, "album-artist", Tuple::String, true},
+ {Tuple::Composer, "composer", Tuple::String, true},
+ {Tuple::Performer, "performer", Tuple::String, true},
+ {Tuple::Copyright, "copyright", Tuple::String, true},
+ {Tuple::Date, "date", Tuple::String, true},
+
+ {Tuple::Subtune, "subsong-id", Tuple::Int, true},
+ {Tuple::NumSubtunes, "subsong-num", Tuple::Int, true},
+ {Tuple::MIMEType, "mime-type", Tuple::String, true},
+ {Tuple::Bitrate, "bitrate", Tuple::Int, true},
+ {Tuple::StartTime, "seg-start", Tuple::Int, true},
+ {Tuple::EndTime, "seg-end", Tuple::Int, true},
+
+ {Tuple::AlbumGain, "gain-album-gain", Tuple::Int, true},
+ {Tuple::AlbumPeak, "gain-album-peak", Tuple::Int, true},
+ {Tuple::TrackGain, "gain-track-gain", Tuple::Int, true},
+ {Tuple::TrackPeak, "gain-track-peak", Tuple::Int, true},
+ {Tuple::GainDivisor, "gain-gain-unit", Tuple::Int, true},
+ {Tuple::PeakDivisor, "gain-peak-unit", Tuple::Int, true},
+};
+
+static const char * const xspf_exts[] = {"xspf"};
+
+class XSPFLoader : public PlaylistPlugin
+{
+public:
+ static constexpr PluginInfo info = {N_("XML Shareable Playlists (XSPF)"), PACKAGE};
+
+ constexpr XSPFLoader () : PlaylistPlugin (info, xspf_exts, true) {}
+
+ bool load (const char * filename, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items);
+ bool save (const char * filename, VFSFile & file, const char * title,
+ const Index<PlaylistAddItem> & items);
+};
+
+EXPORT XSPFLoader aud_plugin_instance;
+
+static void xspf_add_file (xmlNode * track, const char * filename,
+ const char * base, Index<PlaylistAddItem> & items)
+{
+ xmlNode *nptr;
+ String location;
+ Tuple tuple;
+
+ for (nptr = track->children; nptr != nullptr; nptr = nptr->next) {
+ if (nptr->type == XML_ELEMENT_NODE) {
+ if (!xmlStrcmp(nptr->name, (xmlChar *)"location")) {
+ /* Location is a special case */
+ char *str = (char *)xmlNodeGetContent(nptr);
+
+ if (strstr (str, "://") != nullptr)
+ location = String (str);
+ else if (str[0] == '/' && base != nullptr)
+ {
+ const char * colon = strstr (base, "://");
+
+ if (colon != nullptr)
+ location = String (str_printf ("%.*s%s",
+ (int) (colon + 3 - base), base, str));
+ }
+ else if (base != nullptr)
+ {
+ const char * slash = strrchr (base, '/');
+
+ if (slash != nullptr)
+ location = String (str_printf ("%.*s%s",
+ (int) (slash + 1 - base), base, str));
+ }
+
+ xmlFree(str);
+ } else {
+ /* Rest of the nodes are handled here */
+ bool isMeta;
+ xmlChar *findName;
+
+ if (!xmlStrcmp(nptr->name, (xmlChar *)"meta")) {
+ isMeta = true;
+ findName = xmlGetProp(nptr, (xmlChar *)"rel");
+ } else {
+ isMeta = false;
+ findName = xmlStrdup(nptr->name);
+ }
+
+ for (const xspf_entry_t & entry : xspf_entries)
+ if ((entry.isMeta == isMeta) &&
+ !xmlStrcmp(findName, (xmlChar *)entry.xspfName)) {
+ xmlChar *str = xmlNodeGetContent(nptr);
+ switch (entry.type) {
+ case Tuple::String:
+ tuple.set_str (entry.tupleField, (char *)str);
+ break;
+
+ case Tuple::Int:
+ tuple.set_int (entry.tupleField, atol((char *)str));
+ break;
+
+ default:
+ break;
+ }
+ xmlFree(str);
+ break;
+ }
+
+ xmlFree(findName);
+ }
+ }
+ }
+
+ if (location != nullptr)
+ {
+ if (tuple)
+ tuple.set_filename (location);
+
+ items.append (location, std::move (tuple));
+ }
+}
+
+
+static void xspf_find_track (xmlNode * tracklist, const char * filename,
+ const char * base, Index<PlaylistAddItem> & items)
+{
+ xmlNode *nptr;
+
+ for (nptr = tracklist->children; nptr != nullptr; nptr = nptr->next) {
+ if (nptr->type == XML_ELEMENT_NODE &&
+ ! xmlStrcmp (nptr->name, (xmlChar *) "track"))
+ xspf_add_file (nptr, filename, base, items);
+ }
+}
+
+static int read_cb (void * file, char * buf, int len)
+{
+ return ((VFSFile *) file)->fread (buf, 1, len);
+}
+
+static int write_cb (void * file, const char * buf, int len)
+{
+ return ((VFSFile *) file)->fwrite (buf, 1, len);
+}
+
+static int close_cb (void * file)
+{
+ return 0;
+}
+
+bool XSPFLoader::load (const char * filename, VFSFile & file, String & title,
+ Index<PlaylistAddItem> & items)
+{
+ xmlDoc * doc = xmlReadIO (read_cb, close_cb, & file, filename, nullptr, XML_PARSE_RECOVER);
+ if (! doc)
+ return false;
+
+ xmlNode *nptr, *nptr2;
+
+ // find trackList
+ for (nptr = doc->children; nptr != nullptr; nptr = nptr->next) {
+ if (nptr->type == XML_ELEMENT_NODE &&
+ !xmlStrcmp(nptr->name, (xmlChar *)"playlist")) {
+ char * base;
+
+ base = (char *)xmlNodeGetBase(doc, nptr);
+
+ for (nptr2 = nptr->children; nptr2; nptr2 = nptr2->next)
+ {
+ if (nptr2->type != XML_ELEMENT_NODE)
+ continue;
+
+ if (! xmlStrcmp (nptr2->name, (xmlChar *) "title"))
+ {
+ xmlChar * xml_title = xmlNodeGetContent (nptr2);
+ if (xml_title && xml_title[0])
+ title = String ((char *) xml_title);
+ xmlFree (xml_title);
+ }
+ else if (! xmlStrcmp (nptr2->name, (xmlChar *) "trackList"))
+ xspf_find_track (nptr2, filename, base, items);
+ }
+
+ xmlFree (base);
+ }
+ }
+
+ xmlFreeDoc(doc);
+ return true;
+}
+
+
+#define IS_VALID_CHAR(c) (((c) >= 0x20 && (c) <= 0xd7ff) || \
+ ((c) == 0x9) || \
+ ((c) == 0xa) || \
+ ((c) == 0xd) || \
+ ((c) >= 0xe000 && (c) <= 0xfffd) || \
+ ((c) >= 0x10000 && (c) <= 0x10ffff))
+
+/* check for characters that are invalid in XML */
+static bool is_valid_string (const char * s, char * * subst)
+{
+ bool valid = g_utf8_validate (s, -1, nullptr);
+
+ if (valid)
+ {
+ for (const char * p = s; * p; p = g_utf8_next_char (p))
+ {
+ if (! IS_VALID_CHAR (g_utf8_get_char (p)))
+ {
+ valid = false;
+ break;
+ }
+ }
+
+ if (valid)
+ return true;
+ }
+
+ int len = 0;
+
+ const char * p = s;
+ while (* p)
+ {
+ gunichar c = g_utf8_get_char_validated (p, -1);
+
+ if (IS_VALID_CHAR (c))
+ {
+ len += g_unichar_to_utf8 (c, nullptr);
+ p = g_utf8_next_char (p);
+ }
+ else
+ p ++;
+ }
+
+ * subst = g_new (char, len + 1);
+ char * w = * subst;
+
+ p = s;
+ while (* p)
+ {
+ gunichar c = g_utf8_get_char_validated (p, -1);
+
+ if (IS_VALID_CHAR (c))
+ {
+ w += g_unichar_to_utf8 (c, w);
+ p = g_utf8_next_char (p);
+ }
+ else
+ p ++;
+ }
+
+ * w = 0;
+ return false;
+}
+
+
+static void xspf_add_node(xmlNodePtr node, Tuple::ValueType type,
+ bool isMeta, const char *xspfName, const char *strVal,
+ const int intVal)
+{
+ xmlNodePtr tmp;
+
+ if (isMeta) {
+ tmp = xmlNewNode(nullptr, (xmlChar *) "meta");
+ xmlSetProp(tmp, (xmlChar *) "rel", (xmlChar *) xspfName);
+ } else
+ tmp = xmlNewNode(nullptr, (xmlChar *) xspfName);
+
+ switch (type) {
+ case Tuple::String:;
+ char * subst;
+ if (is_valid_string (strVal, & subst))
+ xmlAddChild (tmp, xmlNewText ((xmlChar *) strVal));
+ else
+ {
+ xmlAddChild (tmp, xmlNewText ((xmlChar *) subst));
+ g_free (subst);
+ }
+ break;
+
+ case Tuple::Int:
+ xmlAddChild (tmp, xmlNewText ((xmlChar *) (char *) int_to_str (intVal)));
+ break;
+
+ default:
+ break;
+ }
+
+ xmlAddChild(node, tmp);
+}
+
+
+bool XSPFLoader::save (const char * filename, VFSFile & file,
+ const char * title, const Index<PlaylistAddItem> & items)
+{
+ xmlDocPtr doc;
+ xmlNodePtr rootnode, tracklist;
+
+ doc = xmlNewDoc((xmlChar *)"1.0");
+ doc->charset = XML_CHAR_ENCODING_UTF8;
+ doc->encoding = xmlStrdup((xmlChar *)"UTF-8");
+
+ rootnode = xmlNewNode(nullptr, (xmlChar *)XSPF_ROOT_NODE_NAME);
+ xmlSetProp(rootnode, (xmlChar *)"version", (xmlChar *)"1");
+ xmlSetProp(rootnode, (xmlChar *)"xmlns", (xmlChar *)XSPF_XMLNS);
+
+ /* common */
+ xmlDocSetRootElement(doc, rootnode);
+
+ if (title)
+ xspf_add_node (rootnode, Tuple::String, false, "title", title, 0);
+
+ tracklist = xmlNewNode(nullptr, (xmlChar *)"trackList");
+ xmlAddChild(rootnode, tracklist);
+
+ for (auto & item : items)
+ {
+ const char * filename = item.filename;
+ const Tuple & tuple = item.tuple;
+ xmlNodePtr track, location;
+ String scratch;
+ int scratchi = 0;
+
+ track = xmlNewNode(nullptr, (xmlChar *)"track");
+ location = xmlNewNode(nullptr, (xmlChar *)"location");
+
+ xmlAddChild(location, xmlNewText((xmlChar *)filename));
+ xmlAddChild(track, location);
+ xmlAddChild(tracklist, track);
+
+ if (tuple)
+ {
+ for (const xspf_entry_t & entry : xspf_entries)
+ {
+ bool isOK = (tuple.get_value_type (entry.tupleField) == entry.type);
+
+ switch (entry.type) {
+ case Tuple::String:
+ scratch = tuple.get_str (entry.tupleField);
+ if (! scratch)
+ isOK = false;
+ break;
+ case Tuple::Int:
+ scratchi = tuple.get_int (entry.tupleField);
+ break;
+ default:
+ break;
+ }
+
+ if (isOK)
+ xspf_add_node (track, entry.type, entry.isMeta,
+ entry.xspfName, scratch, scratchi);
+ }
+ }
+ }
+
+ xmlSaveCtxt * save = xmlSaveToIO (write_cb, close_cb, & file, nullptr, XML_SAVE_FORMAT);
+ if (! save)
+ goto ERR;
+
+ if (xmlSaveDoc (save, doc) < 0 || xmlSaveClose (save) < 0)
+ goto ERR;
+
+ xmlFreeDoc(doc);
+ return true;
+
+ERR:
+ xmlFreeDoc (doc);
+ return false;
+}
--
2.1.4
More information about the pkg-multimedia-maintainers
mailing list